pulse-ui-client 0.1.32 → 0.1.37

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.
@@ -1,2138 +0,0 @@
1
- // src/channel.ts
2
- class PulseChannelResetError extends Error {
3
- constructor(message) {
4
- super(message);
5
- this.name = "PulseChannelResetError";
6
- }
7
- }
8
- function randomId() {
9
- if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
10
- return crypto.randomUUID().replace(/-/g, "");
11
- }
12
- return Math.random().toString(16).slice(2) + Math.random().toString(16).slice(2);
13
- }
14
- function formatError(error) {
15
- if (error instanceof Error)
16
- return error.message;
17
- if (typeof error === "string")
18
- return error;
19
- try {
20
- return JSON.stringify(error);
21
- } catch {
22
- return String(error);
23
- }
24
- }
25
- function isServerResponseMessage(message) {
26
- return typeof message.responseTo === "string";
27
- }
28
- function isServerRequestMessage(message) {
29
- return typeof message.event === "string";
30
- }
31
-
32
- class ChannelBridge {
33
- client;
34
- id;
35
- handlers = new Map;
36
- pending = new Map;
37
- backlog = [];
38
- closed = false;
39
- constructor(client, id) {
40
- this.client = client;
41
- this.id = id;
42
- }
43
- emit(event, payload) {
44
- this.ensureOpen();
45
- this.client.sendMessage({
46
- type: "channel_message",
47
- channel: this.id,
48
- event,
49
- payload
50
- });
51
- }
52
- request(event, payload) {
53
- this.ensureOpen();
54
- const requestId = randomId();
55
- return new Promise((resolve, reject) => {
56
- this.pending.set(requestId, { resolve, reject });
57
- this.client.sendMessage({
58
- type: "channel_message",
59
- channel: this.id,
60
- event,
61
- payload,
62
- requestId
63
- });
64
- });
65
- }
66
- on(event, handler) {
67
- this.ensureOpen();
68
- let bucket = this.handlers.get(event);
69
- if (!bucket) {
70
- bucket = new Set;
71
- this.handlers.set(event, bucket);
72
- }
73
- bucket.add(handler);
74
- this.flushBacklog(event);
75
- return () => {
76
- const set = this.handlers.get(event);
77
- if (!set)
78
- return;
79
- set.delete(handler);
80
- if (set.size === 0) {
81
- this.handlers.delete(event);
82
- }
83
- };
84
- }
85
- handleServerMessage(message) {
86
- if (isServerResponseMessage(message)) {
87
- this.resolvePending(message);
88
- return this.closed;
89
- }
90
- if (this.closed) {
91
- return true;
92
- }
93
- if (!isServerRequestMessage(message)) {
94
- return this.closed;
95
- }
96
- if (message.event === "__close__") {
97
- this.close(new PulseChannelResetError("Channel closed by server"));
98
- return true;
99
- }
100
- if (message.requestId) {
101
- this.dispatchRequest(message);
102
- } else {
103
- this.dispatchEvent(message);
104
- }
105
- return this.closed;
106
- }
107
- handleDisconnect(reason) {
108
- this.close(reason);
109
- }
110
- dispose(reason) {
111
- this.close(reason);
112
- }
113
- ensureOpen() {
114
- if (this.closed) {
115
- throw new PulseChannelResetError("Channel is closed");
116
- }
117
- }
118
- flushBacklog(event) {
119
- if (this.backlog.length === 0)
120
- return;
121
- const remaining = [];
122
- for (const item of this.backlog) {
123
- if (item.event === event) {
124
- this.dispatchEvent(item);
125
- } else {
126
- remaining.push(item);
127
- }
128
- }
129
- this.backlog = remaining;
130
- }
131
- dispatchEvent(message) {
132
- const handlers = this.handlers.get(message.event);
133
- if (!handlers || handlers.size === 0) {
134
- this.backlog.push(message);
135
- return;
136
- }
137
- for (const handler of handlers) {
138
- try {
139
- const result = handler(message.payload);
140
- if (result && typeof result.then === "function") {
141
- result.catch((err) => {
142
- console.error("Pulse channel handler error", err);
143
- });
144
- }
145
- } catch (err) {
146
- console.error("Pulse channel handler error", err);
147
- }
148
- }
149
- }
150
- async dispatchRequest(message) {
151
- const handlers = this.handlers.get(message.event);
152
- let response;
153
- let error;
154
- if (handlers && handlers.size > 0) {
155
- for (const handler of handlers) {
156
- try {
157
- const result = handler(message.payload);
158
- response = await Promise.resolve(result);
159
- if (response !== undefined) {
160
- break;
161
- }
162
- } catch (err) {
163
- error = err;
164
- break;
165
- }
166
- }
167
- }
168
- if (error) {
169
- this.client.sendMessage({
170
- type: "channel_message",
171
- channel: this.id,
172
- event: undefined,
173
- responseTo: message.requestId,
174
- error: formatError(error)
175
- });
176
- return;
177
- }
178
- this.client.sendMessage({
179
- type: "channel_message",
180
- channel: this.id,
181
- event: undefined,
182
- responseTo: message.requestId,
183
- payload: response
184
- });
185
- }
186
- resolvePending(message) {
187
- const entry = message.responseTo ? this.pending.get(message.responseTo) : undefined;
188
- if (!entry) {
189
- return;
190
- }
191
- this.pending.delete(message.responseTo);
192
- if (message.error !== undefined && message.error !== null) {
193
- entry.reject(new PulseChannelResetError(String(message.error)));
194
- } else {
195
- entry.resolve(message.payload);
196
- }
197
- }
198
- close(reason) {
199
- if (this.closed) {
200
- return;
201
- }
202
- this.closed = true;
203
- for (const request of this.pending.values()) {
204
- request.reject(reason);
205
- }
206
- this.pending.clear();
207
- this.handlers.clear();
208
- this.backlog = [];
209
- }
210
- }
211
- function createChannelBridge(client, id) {
212
- return new ChannelBridge(client, id);
213
- }
214
- // src/form.tsx
215
- import { forwardRef, useCallback } from "react";
216
- import { jsxDEV } from "react/jsx-dev-runtime";
217
- var PulseForm = forwardRef(function PulseForm2({ onSubmit, action, ...rest }, ref) {
218
- return /* @__PURE__ */ jsxDEV("form", {
219
- ...rest,
220
- action,
221
- ref,
222
- onSubmit: useCallback((event) => submitForm({ event, action, onSubmit }), [action, onSubmit])
223
- }, undefined, false, undefined, this);
224
- });
225
- async function submitForm({ event, action, onSubmit, formData, force }) {
226
- onSubmit?.(event);
227
- if (!force && event.defaultPrevented) {
228
- return;
229
- }
230
- const form = event.currentTarget;
231
- event.preventDefault();
232
- const nativeEvent = event.nativeEvent;
233
- if (!formData) {
234
- formData = new FormData(form, nativeEvent.submitter);
235
- }
236
- const url = new URL(action, window.location.href);
237
- try {
238
- await fetch(url, {
239
- method: "POST",
240
- credentials: "include",
241
- body: formData
242
- });
243
- } catch (err) {
244
- if (true) {
245
- console.error("[Pulse] Form submission failed", err);
246
- } else {}
247
- }
248
- }
249
- // src/helpers.ts
250
- function extractServerRouteInfo({ params, request }) {
251
- const { "*": catchall = "", ...pathParams } = params;
252
- const parsedUrl = new URL(request.url);
253
- return {
254
- hash: parsedUrl.hash,
255
- pathname: parsedUrl.pathname,
256
- query: parsedUrl.search,
257
- queryParams: Object.fromEntries(parsedUrl.searchParams.entries()),
258
- pathParams,
259
- catchall: catchall.length > 1 ? catchall.split("/") : []
260
- };
261
- }
262
- // src/pulse.tsx
263
- import { createContext, useContext, useEffect, useMemo, useState } from "react";
264
- import { useLocation, useNavigate, useParams } from "react-router";
265
-
266
- // src/client.tsx
267
- import { io } from "socket.io-client";
268
-
269
- // src/serialize/extractor.ts
270
- function createExtractor() {
271
- function _createExtractor(keys, computed) {
272
- return (src) => {
273
- const out = {};
274
- for (const key of keys) {
275
- out[key] = src[key];
276
- }
277
- if (computed) {
278
- for (const key in computed) {
279
- const fn = computed[key];
280
- out[key] = fn(src);
281
- }
282
- }
283
- return out;
284
- };
285
- }
286
- return _createExtractor;
287
- }
288
-
289
- // src/serialize/elements.ts
290
- var lowerTagName = (e) => e.tagName.toLowerCase();
291
- var ELEMENT_KEYS = [
292
- "id",
293
- "className",
294
- "tagName",
295
- "localName",
296
- "clientHeight",
297
- "clientLeft",
298
- "clientTop",
299
- "clientWidth",
300
- "scrollHeight",
301
- "scrollLeft",
302
- "scrollTop",
303
- "scrollWidth",
304
- "slot"
305
- ];
306
- var HTML_OR_SVG_KEYS = [
307
- "autofocus",
308
- "tabIndex",
309
- "nonce"
310
- ];
311
- var HTML_ELEMENT_BASE_KEYS = [
312
- "accessKey",
313
- "accessKeyLabel",
314
- "autocapitalize",
315
- "dir",
316
- "draggable",
317
- "hidden",
318
- "inert",
319
- "lang",
320
- "offsetHeight",
321
- "offsetLeft",
322
- "offsetTop",
323
- "offsetWidth",
324
- "popover",
325
- "spellcheck",
326
- "title",
327
- "translate",
328
- "writingSuggestions",
329
- "contentEditable",
330
- "enterKeyHint",
331
- "isContentEditable",
332
- "inputMode"
333
- ];
334
- var extractElement = createExtractor()(ELEMENT_KEYS, {
335
- tagName: lowerTagName
336
- });
337
- var extractHTMLOrSVGElement = createExtractor()(HTML_OR_SVG_KEYS);
338
- var extractHTMLElementBaseOnly = createExtractor()(HTML_ELEMENT_BASE_KEYS);
339
- function extractHTMLElementBase(elt) {
340
- return {
341
- ...extractElement(elt),
342
- ...extractHTMLOrSVGElement(elt),
343
- ...extractHTMLElementBaseOnly(elt)
344
- };
345
- }
346
- function withBase(keys, computed) {
347
- const only = createExtractor()(keys, computed);
348
- return (elt) => ({ ...extractHTMLElementBase(elt), ...only(elt) });
349
- }
350
- var HTML_ANCHOR_KEYS = [
351
- "hash",
352
- "host",
353
- "hostname",
354
- "href",
355
- "origin",
356
- "password",
357
- "pathname",
358
- "port",
359
- "protocol",
360
- "search",
361
- "target",
362
- "download",
363
- "rel",
364
- "hreflang",
365
- "type",
366
- "username",
367
- "ping",
368
- "referrerPolicy",
369
- "text"
370
- ];
371
- var anchorExtractor = withBase(HTML_ANCHOR_KEYS);
372
- var HTML_AREA_KEYS = [
373
- "alt",
374
- "coords",
375
- "download",
376
- "hash",
377
- "host",
378
- "hostname",
379
- "href",
380
- "origin",
381
- "password",
382
- "pathname",
383
- "port",
384
- "protocol",
385
- "rel",
386
- "search",
387
- "shape",
388
- "target",
389
- "username",
390
- "ping",
391
- "referrerPolicy"
392
- ];
393
- var areaExtractor = withBase(HTML_AREA_KEYS);
394
- var HTML_MEDIA_KEYS = [
395
- "autoplay",
396
- "controls",
397
- "crossOrigin",
398
- "currentSrc",
399
- "currentTime",
400
- "defaultMuted",
401
- "defaultPlaybackRate",
402
- "duration",
403
- "ended",
404
- "loop",
405
- "muted",
406
- "networkState",
407
- "paused",
408
- "playbackRate",
409
- "preload",
410
- "readyState",
411
- "seeking",
412
- "src",
413
- "volume",
414
- "preservesPitch"
415
- ];
416
- var mediaExtractor = withBase(HTML_MEDIA_KEYS);
417
- var audioExtractor = (elt) => mediaExtractor(elt);
418
- var HTML_BUTTON_KEYS = [
419
- "disabled",
420
- "name",
421
- "type",
422
- "value",
423
- "formAction",
424
- "formEnctype",
425
- "formMethod",
426
- "formNoValidate",
427
- "formTarget",
428
- "popoverTargetAction"
429
- ];
430
- var buttonExtractor = withBase(HTML_BUTTON_KEYS);
431
- var HTML_DATA_KEYS = ["value"];
432
- var dataExtractor = withBase(HTML_DATA_KEYS);
433
- var HTML_EMBED_KEYS = [
434
- "height",
435
- "src",
436
- "type",
437
- "width",
438
- "align",
439
- "name"
440
- ];
441
- var embedExtractor = withBase(HTML_EMBED_KEYS);
442
- var HTML_FIELDSET_KEYS = [
443
- "disabled",
444
- "name",
445
- "type",
446
- "validationMessage",
447
- "willValidate"
448
- ];
449
- var fieldsetExtractor = withBase(HTML_FIELDSET_KEYS);
450
- var HTML_FORM_KEYS = [
451
- "acceptCharset",
452
- "action",
453
- "autocomplete",
454
- "encoding",
455
- "enctype",
456
- "length",
457
- "method",
458
- "name",
459
- "noValidate",
460
- "target",
461
- "rel"
462
- ];
463
- var formExtractor = withBase(HTML_FORM_KEYS);
464
- var HTML_IFRAME_KEYS = [
465
- "allow",
466
- "allowFullscreen",
467
- "height",
468
- "name",
469
- "referrerPolicy",
470
- "src",
471
- "srcdoc",
472
- "width",
473
- "align",
474
- "frameBorder",
475
- "longDesc",
476
- "marginHeight",
477
- "marginWidth",
478
- "scrolling",
479
- "sandbox"
480
- ];
481
- var iframeExtractor = withBase(HTML_IFRAME_KEYS);
482
- var HTML_IMAGE_KEYS = [
483
- "alt",
484
- "crossOrigin",
485
- "decoding",
486
- "height",
487
- "isMap",
488
- "loading",
489
- "naturalHeight",
490
- "naturalWidth",
491
- "referrerPolicy",
492
- "sizes",
493
- "src",
494
- "srcset",
495
- "useMap",
496
- "width",
497
- "align",
498
- "border",
499
- "complete",
500
- "hspace",
501
- "longDesc",
502
- "lowsrc",
503
- "name",
504
- "vspace",
505
- "x",
506
- "y",
507
- "fetchPriority"
508
- ];
509
- var imageExtractor = withBase(HTML_IMAGE_KEYS);
510
- var HTML_INPUT_KEYS = [
511
- "accept",
512
- "alt",
513
- "autocomplete",
514
- "checked",
515
- "defaultChecked",
516
- "defaultValue",
517
- "dirName",
518
- "disabled",
519
- "height",
520
- "indeterminate",
521
- "max",
522
- "maxLength",
523
- "min",
524
- "minLength",
525
- "multiple",
526
- "name",
527
- "pattern",
528
- "placeholder",
529
- "readOnly",
530
- "required",
531
- "selectionDirection",
532
- "selectionEnd",
533
- "selectionStart",
534
- "size",
535
- "src",
536
- "step",
537
- "type",
538
- "value",
539
- "valueAsNumber",
540
- "width",
541
- "align",
542
- "capture",
543
- "formAction",
544
- "formEnctype",
545
- "formMethod",
546
- "formNoValidate",
547
- "formTarget",
548
- "useMap",
549
- "validationMessage",
550
- "willValidate",
551
- "popoverTargetAction"
552
- ];
553
- var inputExtractor = withBase(HTML_INPUT_KEYS);
554
- var HTML_LABEL_KEYS = ["htmlFor"];
555
- var labelExtractor = withBase(HTML_LABEL_KEYS);
556
- var HTML_LI_KEYS = ["value", "type"];
557
- var liExtractor = withBase(HTML_LI_KEYS);
558
- var HTML_LINK_KEYS = [
559
- "as",
560
- "crossOrigin",
561
- "disabled",
562
- "fetchPriority",
563
- "href",
564
- "hreflang",
565
- "imageSizes",
566
- "imageSrcset",
567
- "integrity",
568
- "media",
569
- "referrerPolicy",
570
- "rel",
571
- "type",
572
- "charset",
573
- "rev",
574
- "target",
575
- "sizes"
576
- ];
577
- var linkExtractor = withBase(HTML_LINK_KEYS);
578
- var HTML_MAP_KEYS = ["name"];
579
- var mapExtractor = withBase(HTML_MAP_KEYS);
580
- var HTML_METER_KEYS = [
581
- "high",
582
- "low",
583
- "max",
584
- "min",
585
- "optimum",
586
- "value"
587
- ];
588
- var meterExtractor = withBase(HTML_METER_KEYS);
589
- var HTML_MOD_KEYS = ["cite", "dateTime"];
590
- var modExtractor = withBase(HTML_MOD_KEYS);
591
- var HTML_OL_KEYS = [
592
- "reversed",
593
- "start",
594
- "type",
595
- "compact"
596
- ];
597
- var olistExtractor = withBase(HTML_OL_KEYS);
598
- var HTML_OBJECT_KEYS = [
599
- "data",
600
- "height",
601
- "name",
602
- "type",
603
- "useMap",
604
- "width",
605
- "validationMessage",
606
- "willValidate",
607
- "align",
608
- "archive",
609
- "border",
610
- "code",
611
- "codeBase",
612
- "codeType",
613
- "declare",
614
- "hspace",
615
- "standby",
616
- "vspace"
617
- ];
618
- var objectExtractor = withBase(HTML_OBJECT_KEYS);
619
- var HTML_OPTGROUP_KEYS = [
620
- "disabled",
621
- "label"
622
- ];
623
- var optgroupExtractor = withBase(HTML_OPTGROUP_KEYS);
624
- var HTML_OPTION_KEYS = [
625
- "defaultSelected",
626
- "disabled",
627
- "index",
628
- "label",
629
- "selected",
630
- "text",
631
- "value"
632
- ];
633
- var optionExtractor = withBase(HTML_OPTION_KEYS);
634
- var HTML_OUTPUT_KEYS = [
635
- "defaultValue",
636
- "name",
637
- "type",
638
- "value",
639
- "htmlFor",
640
- "validationMessage",
641
- "willValidate"
642
- ];
643
- var outputExtractor = withBase(HTML_OUTPUT_KEYS);
644
- var HTML_PROGRESS_KEYS = [
645
- "max",
646
- "position",
647
- "value"
648
- ];
649
- var progressExtractor = withBase(HTML_PROGRESS_KEYS);
650
- var HTML_QUOTE_KEYS = ["cite"];
651
- var quoteExtractor = withBase(HTML_QUOTE_KEYS);
652
- var citeExtractor = (elt) => extractHTMLElementBase(elt);
653
- var HTML_SCRIPT_KEYS = [
654
- "async",
655
- "crossOrigin",
656
- "defer",
657
- "fetchPriority",
658
- "integrity",
659
- "noModule",
660
- "referrerPolicy",
661
- "src",
662
- "text",
663
- "type",
664
- "charset"
665
- ];
666
- var extractHTMLScriptOnly = createExtractor()(HTML_SCRIPT_KEYS, {
667
- event: (s) => s.event,
668
- htmlFor: (s) => s.htmlFor
669
- });
670
- var scriptExtractor = (elt) => ({
671
- ...extractHTMLElementBase(elt),
672
- ...extractHTMLScriptOnly(elt)
673
- });
674
- var HTML_SELECT_KEYS = [
675
- "autocomplete",
676
- "disabled",
677
- "length",
678
- "multiple",
679
- "name",
680
- "required",
681
- "selectedIndex",
682
- "size",
683
- "type",
684
- "value",
685
- "validationMessage",
686
- "willValidate"
687
- ];
688
- var selectExtractor = withBase(HTML_SELECT_KEYS);
689
- var HTML_SLOT_KEYS = ["name"];
690
- var slotExtractor = withBase(HTML_SLOT_KEYS);
691
- var HTML_SOURCE_KEYS = [
692
- "height",
693
- "media",
694
- "sizes",
695
- "src",
696
- "srcset",
697
- "type",
698
- "width"
699
- ];
700
- var sourceExtractor = withBase(HTML_SOURCE_KEYS);
701
- var HTML_TABLE_CAPTION_KEYS = [
702
- "align"
703
- ];
704
- var tableCaptionExtractor = withBase(HTML_TABLE_CAPTION_KEYS);
705
- var HTML_TABLE_CELL_KEYS = [
706
- "abbr",
707
- "cellIndex",
708
- "colSpan",
709
- "headers",
710
- "rowSpan",
711
- "scope",
712
- "align",
713
- "axis",
714
- "bgColor",
715
- "ch",
716
- "chOff",
717
- "height",
718
- "noWrap",
719
- "vAlign",
720
- "width"
721
- ];
722
- var tableCellExtractor = withBase(HTML_TABLE_CELL_KEYS);
723
- var HTML_TABLE_COL_KEYS = [
724
- "span",
725
- "align",
726
- "ch",
727
- "chOff",
728
- "vAlign",
729
- "width"
730
- ];
731
- var tableColExtractor = withBase(HTML_TABLE_COL_KEYS);
732
- var HTML_TABLE_KEYS = [
733
- "align",
734
- "bgColor",
735
- "border",
736
- "cellPadding",
737
- "cellSpacing",
738
- "frame",
739
- "rules",
740
- "summary",
741
- "width"
742
- ];
743
- var tableExtractor = withBase(HTML_TABLE_KEYS);
744
- var HTML_TR_KEYS = [
745
- "rowIndex",
746
- "sectionRowIndex",
747
- "align",
748
- "bgColor",
749
- "ch",
750
- "chOff",
751
- "vAlign"
752
- ];
753
- var tableRowExtractor = withBase(HTML_TR_KEYS);
754
- var HTML_TSECTION_KEYS = [
755
- "align",
756
- "ch",
757
- "chOff",
758
- "vAlign"
759
- ];
760
- var tableSectionExtractor = withBase(HTML_TSECTION_KEYS);
761
- var templateExtractor = (elt) => extractHTMLElementBase(elt);
762
- var HTML_TEXTAREA_KEYS = [
763
- "autocomplete",
764
- "cols",
765
- "defaultValue",
766
- "dirName",
767
- "disabled",
768
- "maxLength",
769
- "minLength",
770
- "name",
771
- "placeholder",
772
- "readOnly",
773
- "required",
774
- "rows",
775
- "selectionDirection",
776
- "selectionEnd",
777
- "selectionStart",
778
- "value",
779
- "wrap",
780
- "textLength",
781
- "validationMessage",
782
- "willValidate"
783
- ];
784
- var textareaExtractor = withBase(HTML_TEXTAREA_KEYS);
785
- var HTML_TIME_KEYS = ["dateTime"];
786
- var timeExtractor = withBase(HTML_TIME_KEYS);
787
- var HTML_TRACK_KEYS = [
788
- "default",
789
- "kind",
790
- "label",
791
- "readyState",
792
- "src",
793
- "srclang"
794
- ];
795
- var trackExtractor = withBase(HTML_TRACK_KEYS);
796
- var HTML_VIDEO_KEYS = [
797
- "height",
798
- "poster",
799
- "videoHeight",
800
- "videoWidth",
801
- "width",
802
- "playsInline"
803
- ];
804
- var extractHTMLVideoOnly = createExtractor()(HTML_VIDEO_KEYS);
805
- var videoExtractor = (elt) => ({
806
- ...mediaExtractor(elt),
807
- ...extractHTMLVideoOnly(elt)
808
- });
809
- var HTML_BR_KEYS = ["clear"];
810
- var brExtractor = withBase(HTML_BR_KEYS);
811
- var HTML_BASE_KEYS = ["href", "target"];
812
- var baseExtractor = withBase(HTML_BASE_KEYS);
813
- var HTML_BODY_KEYS = [
814
- "aLink",
815
- "background",
816
- "bgColor",
817
- "link",
818
- "text",
819
- "vLink"
820
- ];
821
- var bodyExtractor = withBase(HTML_BODY_KEYS);
822
- var HTML_DLIST_KEYS = ["compact"];
823
- var dlistExtractor = withBase(HTML_DLIST_KEYS);
824
- var HTML_DETAILS_KEYS = ["open"];
825
- var detailsExtractor = withBase(HTML_DETAILS_KEYS);
826
- var HTML_DIALOG_KEYS = [
827
- "open",
828
- "returnValue"
829
- ];
830
- var dialogExtractor = withBase(HTML_DIALOG_KEYS);
831
- var HTML_DIV_KEYS = ["align"];
832
- var divExtractor = withBase(HTML_DIV_KEYS);
833
- var headExtractor = (elt) => extractHTMLElementBase(elt);
834
- var HTML_HEADING_KEYS = ["align"];
835
- var headingExtractor = withBase(HTML_HEADING_KEYS);
836
- var HTML_HR_KEYS = [
837
- "align",
838
- "color",
839
- "noShade",
840
- "size",
841
- "width"
842
- ];
843
- var hrExtractor = withBase(HTML_HR_KEYS);
844
- var HTML_HTML_KEYS = ["version"];
845
- var htmlExtractor = withBase(HTML_HTML_KEYS);
846
- var menuExtractor = (elt) => extractHTMLElementBase(elt);
847
- var HTML_META_KEYS = [
848
- "content",
849
- "httpEquiv",
850
- "name",
851
- "scheme"
852
- ];
853
- var metaExtractor = withBase(HTML_META_KEYS);
854
- var HTML_P_KEYS = ["align"];
855
- var paragraphExtractor = withBase(HTML_P_KEYS);
856
- var pictureExtractor = (elt) => extractHTMLElementBase(elt);
857
- var HTML_PRE_KEYS = ["width"];
858
- var preExtractor = withBase(HTML_PRE_KEYS);
859
- var spanExtractor = (elt) => extractHTMLElementBase(elt);
860
- var HTML_STYLE_KEYS = [
861
- "media",
862
- "type",
863
- "disabled"
864
- ];
865
- var styleExtractor = withBase(HTML_STYLE_KEYS);
866
- var HTML_TITLE_KEYS = ["text"];
867
- var titleExtractor = withBase(HTML_TITLE_KEYS);
868
- var HTML_UL_KEYS = ["compact", "type"];
869
- var ulistExtractor = withBase(HTML_UL_KEYS);
870
- var elementExtractors = {
871
- A: anchorExtractor,
872
- AREA: areaExtractor,
873
- AUDIO: audioExtractor,
874
- BASE: baseExtractor,
875
- BLOCKQUOTE: quoteExtractor,
876
- Q: quoteExtractor,
877
- BODY: bodyExtractor,
878
- BR: brExtractor,
879
- BUTTON: buttonExtractor,
880
- CANVAS: extractHTMLElementBase,
881
- CAPTION: tableCaptionExtractor,
882
- CITE: citeExtractor,
883
- COL: tableColExtractor,
884
- COLGROUP: tableColExtractor,
885
- DATA: dataExtractor,
886
- DETAILS: detailsExtractor,
887
- DIALOG: dialogExtractor,
888
- DIV: divExtractor,
889
- DL: dlistExtractor,
890
- EMBED: embedExtractor,
891
- FIELDSET: fieldsetExtractor,
892
- FORM: formExtractor,
893
- H1: headingExtractor,
894
- H2: headingExtractor,
895
- H3: headingExtractor,
896
- H4: headingExtractor,
897
- H5: headingExtractor,
898
- H6: headingExtractor,
899
- HEAD: headExtractor,
900
- HR: hrExtractor,
901
- HTML: htmlExtractor,
902
- IFRAME: iframeExtractor,
903
- IMG: imageExtractor,
904
- INPUT: inputExtractor,
905
- LABEL: labelExtractor,
906
- LI: liExtractor,
907
- LINK: linkExtractor,
908
- MAP: mapExtractor,
909
- MENU: menuExtractor,
910
- META: metaExtractor,
911
- METER: meterExtractor,
912
- INS: modExtractor,
913
- DEL: modExtractor,
914
- OBJECT: objectExtractor,
915
- OL: olistExtractor,
916
- OPTGROUP: optgroupExtractor,
917
- OPTION: optionExtractor,
918
- OUTPUT: outputExtractor,
919
- P: paragraphExtractor,
920
- PICTURE: pictureExtractor,
921
- PRE: preExtractor,
922
- PROGRESS: progressExtractor,
923
- SCRIPT: scriptExtractor,
924
- SELECT: selectExtractor,
925
- SLOT: slotExtractor,
926
- SOURCE: sourceExtractor,
927
- SPAN: spanExtractor,
928
- STYLE: styleExtractor,
929
- TABLE: tableExtractor,
930
- TBODY: tableSectionExtractor,
931
- THEAD: tableSectionExtractor,
932
- TFOOT: tableSectionExtractor,
933
- TD: tableCellExtractor,
934
- TH: tableCellExtractor,
935
- TEMPLATE: templateExtractor,
936
- TEXTAREA: textareaExtractor,
937
- TIME: timeExtractor,
938
- TITLE: titleExtractor,
939
- TR: tableRowExtractor,
940
- TRACK: trackExtractor,
941
- UL: ulistExtractor,
942
- VIDEO: videoExtractor
943
- };
944
- function extractHTMLElement(elt) {
945
- const tagName = elt.tagName.toUpperCase();
946
- const extractor = elementExtractors[tagName];
947
- if (extractor) {
948
- return extractor(elt);
949
- }
950
- throw new Error(`Unexpected HTML element tag: ${elt.tagName} (update .web/custom/serialize.ts)`);
951
- }
952
-
953
- // src/serialize/events.ts
954
- var mapTarget = (e) => extractHTMLElement(e.target);
955
- var mapRelated = (e) => e.relatedTarget ? extractHTMLElement(e.relatedTarget) : null;
956
- function makeExtractor(keys, computed) {
957
- return createExtractor()(keys, {
958
- target: mapTarget,
959
- ...computed || {}
960
- });
961
- }
962
- var SYNTHETIC_KEYS = [
963
- "target",
964
- "bubbles",
965
- "cancelable",
966
- "defaultPrevented",
967
- "eventPhase",
968
- "isTrusted",
969
- "timeStamp",
970
- "type"
971
- ];
972
- var UI_KEYS = [...SYNTHETIC_KEYS, "detail"];
973
- var MOUSE_KEYS = [
974
- ...UI_KEYS,
975
- "altKey",
976
- "button",
977
- "buttons",
978
- "clientX",
979
- "clientY",
980
- "ctrlKey",
981
- "metaKey",
982
- "movementX",
983
- "movementY",
984
- "pageX",
985
- "pageY",
986
- "screenX",
987
- "screenY",
988
- "shiftKey"
989
- ];
990
- var POINTER_KEYS = [
991
- ...MOUSE_KEYS,
992
- "pointerId",
993
- "pressure",
994
- "tangentialPressure",
995
- "tiltX",
996
- "tiltY",
997
- "twist",
998
- "width",
999
- "height",
1000
- "pointerType",
1001
- "isPrimary"
1002
- ];
1003
- var syntheticExtractor = makeExtractor(SYNTHETIC_KEYS);
1004
- var uiExtractor = makeExtractor(UI_KEYS);
1005
- var mouseExtractor = makeExtractor(MOUSE_KEYS, { relatedTarget: mapRelated });
1006
- var clipboardExtractor = makeExtractor(SYNTHETIC_KEYS, {
1007
- clipboardData: (e) => extractDataTransfer(e.clipboardData)
1008
- });
1009
- var compositionExtractor = makeExtractor([...SYNTHETIC_KEYS, "data"]);
1010
- var dragExtractor = makeExtractor(MOUSE_KEYS, {
1011
- relatedTarget: mapRelated,
1012
- dataTransfer: (e) => extractDataTransfer(e.dataTransfer)
1013
- });
1014
- var pointerExtractor = makeExtractor(POINTER_KEYS, {
1015
- relatedTarget: mapRelated
1016
- });
1017
- var focusExtractor = makeExtractor(SYNTHETIC_KEYS, {
1018
- relatedTarget: mapRelated
1019
- });
1020
- var formExtractor2 = makeExtractor(SYNTHETIC_KEYS);
1021
- var invalidExtractor = makeExtractor(SYNTHETIC_KEYS);
1022
- var changeExtractor = makeExtractor(SYNTHETIC_KEYS);
1023
- var keyboardExtractor = makeExtractor([
1024
- ...UI_KEYS,
1025
- "altKey",
1026
- "ctrlKey",
1027
- "code",
1028
- "key",
1029
- "locale",
1030
- "location",
1031
- "metaKey",
1032
- "repeat",
1033
- "shiftKey"
1034
- ]);
1035
- var touchExtractor = makeExtractor([
1036
- ...UI_KEYS,
1037
- "altKey",
1038
- "ctrlKey",
1039
- "metaKey",
1040
- "shiftKey",
1041
- "changedTouches",
1042
- "targetTouches",
1043
- "touches"
1044
- ], {
1045
- changedTouches: (e) => mapTouchList(e.changedTouches),
1046
- targetTouches: (e) => mapTouchList(e.targetTouches),
1047
- touches: (e) => mapTouchList(e.touches)
1048
- });
1049
- var wheelExtractor = makeExtractor([...MOUSE_KEYS, "deltaMode", "deltaX", "deltaY", "deltaZ"], {
1050
- relatedTarget: mapRelated
1051
- });
1052
- var animationExtractor = makeExtractor([
1053
- ...SYNTHETIC_KEYS,
1054
- "animationName",
1055
- "elapsedTime",
1056
- "pseudoElement"
1057
- ]);
1058
- var toggleExtractor = makeExtractor([...SYNTHETIC_KEYS, "oldState", "newState"]);
1059
- var transitionExtractor = makeExtractor([
1060
- ...SYNTHETIC_KEYS,
1061
- "elapsedTime",
1062
- "propertyName",
1063
- "pseudoElement"
1064
- ]);
1065
- function mapTouchList(list) {
1066
- return Array.from(list).map((touch) => ({
1067
- target: extractHTMLElement(touch.target),
1068
- identifier: touch.identifier,
1069
- screenX: touch.screenX,
1070
- screenY: touch.screenY,
1071
- clientX: touch.clientX,
1072
- clientY: touch.clientY,
1073
- pageX: touch.pageX,
1074
- pageY: touch.pageY
1075
- }));
1076
- }
1077
- function extractDataTransfer(dt) {
1078
- if (!dt) {
1079
- return null;
1080
- }
1081
- const items = [];
1082
- if (dt.items) {
1083
- for (let i = 0;i < dt.items.length; i++) {
1084
- const item = dt.items[i];
1085
- items.push({
1086
- kind: item.kind,
1087
- type: item.type
1088
- });
1089
- }
1090
- }
1091
- return {
1092
- drop_effect: dt.dropEffect,
1093
- effect_allowed: dt.effectAllowed,
1094
- items,
1095
- types: Array.from(dt.types || [])
1096
- };
1097
- }
1098
- var eventExtractorMap = {};
1099
- function add(map, names, fn) {
1100
- for (const n of names)
1101
- map[n] = fn;
1102
- }
1103
- add(eventExtractorMap, [
1104
- "pointerdown",
1105
- "pointermove",
1106
- "pointerup",
1107
- "pointercancel",
1108
- "gotpointercapture",
1109
- "lostpointercapture",
1110
- "pointerenter",
1111
- "pointerleave",
1112
- "pointerover",
1113
- "pointerout"
1114
- ], pointerExtractor);
1115
- add(eventExtractorMap, [
1116
- "click",
1117
- "contextmenu",
1118
- "dblclick",
1119
- "mousedown",
1120
- "mouseenter",
1121
- "mouseleave",
1122
- "mousemove",
1123
- "mouseout",
1124
- "mouseover",
1125
- "mouseup"
1126
- ], mouseExtractor);
1127
- add(eventExtractorMap, ["drag", "dragend", "dragenter", "dragexit", "dragleave", "dragover", "dragstart", "drop"], dragExtractor);
1128
- add(eventExtractorMap, ["keydown", "keypress", "keyup"], keyboardExtractor);
1129
- add(eventExtractorMap, ["focus", "blur"], focusExtractor);
1130
- add(eventExtractorMap, ["change", "input"], changeExtractor);
1131
- add(eventExtractorMap, ["invalid"], invalidExtractor);
1132
- add(eventExtractorMap, ["reset", "submit"], formExtractor2);
1133
- add(eventExtractorMap, ["copy", "cut", "paste"], clipboardExtractor);
1134
- add(eventExtractorMap, ["compositionend", "compositionstart", "compositionupdate"], compositionExtractor);
1135
- add(eventExtractorMap, ["touchcancel", "touchend", "touchmove", "touchstart"], touchExtractor);
1136
- add(eventExtractorMap, ["scroll"], uiExtractor);
1137
- add(eventExtractorMap, ["wheel"], wheelExtractor);
1138
- add(eventExtractorMap, ["animationstart", "animationend", "animationiteration"], animationExtractor);
1139
- add(eventExtractorMap, ["transitionend"], transitionExtractor);
1140
- add(eventExtractorMap, ["toggle"], toggleExtractor);
1141
- function extractEvent(value) {
1142
- if (value && typeof value === "object" && "nativeEvent" in value && typeof value.isDefaultPrevented === "function") {
1143
- const evt = value;
1144
- if (typeof evt.type !== "string") {
1145
- return value;
1146
- }
1147
- const extractor = eventExtractorMap[evt.type.toLowerCase()];
1148
- if (extractor) {
1149
- return extractor(evt);
1150
- }
1151
- return syntheticExtractor(evt);
1152
- }
1153
- return value;
1154
- }
1155
-
1156
- // src/serialize/serializer.ts
1157
- function serialize(data) {
1158
- const seen = new Map;
1159
- const refs = [];
1160
- const dates = [];
1161
- const sets = [];
1162
- const maps = [];
1163
- let globalIndex = 0;
1164
- function process(value) {
1165
- if (value == null || typeof value === "number" || typeof value === "string" || typeof value === "boolean") {
1166
- return value;
1167
- }
1168
- const idx = globalIndex++;
1169
- const prevRef = seen.get(value);
1170
- if (prevRef !== undefined) {
1171
- refs.push(idx);
1172
- return prevRef;
1173
- }
1174
- seen.set(value, idx);
1175
- if (value instanceof Date) {
1176
- dates.push(idx);
1177
- return value.getTime();
1178
- }
1179
- if (Array.isArray(value)) {
1180
- const length = value.length;
1181
- const result = new Array(length);
1182
- for (let i = 0;i < length; i++) {
1183
- result[i] = process(value[i]);
1184
- }
1185
- return result;
1186
- }
1187
- if (value instanceof Map) {
1188
- maps.push(idx);
1189
- const rec = {};
1190
- for (const [key, entry] of value.entries()) {
1191
- rec[String(key)] = process(entry);
1192
- }
1193
- return rec;
1194
- }
1195
- if (value instanceof Set) {
1196
- sets.push(idx);
1197
- const size = value.size;
1198
- const result = new Array(size);
1199
- let i = 0;
1200
- for (const entry of value) {
1201
- result[i] = process(entry);
1202
- i += 1;
1203
- }
1204
- return result;
1205
- }
1206
- if (typeof value === "object") {
1207
- const rec = {};
1208
- const keys = Object.keys(value);
1209
- for (let i = 0;i < keys.length; i++) {
1210
- const key = keys[i];
1211
- rec[key] = process(value[key]);
1212
- }
1213
- return rec;
1214
- }
1215
- throw new Error(`Unsupported value in serialization: ${value}`);
1216
- }
1217
- const payload = process(data);
1218
- return [[refs, dates, sets, maps], payload];
1219
- }
1220
- function deserialize(payload, options) {
1221
- const [[refsA, datesA, setsA, mapsA], data] = payload;
1222
- const refs = new Set(refsA);
1223
- const dates = new Set(datesA);
1224
- const sets = new Set(setsA);
1225
- const maps = new Set(mapsA);
1226
- const objects = [];
1227
- function reconstruct(value) {
1228
- const idx = objects.length;
1229
- if (refs.has(idx)) {
1230
- objects.push(null);
1231
- return objects[value];
1232
- }
1233
- if (dates.has(idx)) {
1234
- const dt = new Date(value);
1235
- objects.push(dt);
1236
- return dt;
1237
- }
1238
- if (value == null || typeof value === "number" || typeof value === "string" || typeof value === "boolean") {
1239
- if (options?.coerceNullsToUndefined) {
1240
- return value ?? undefined;
1241
- }
1242
- return value;
1243
- }
1244
- if (Array.isArray(value)) {
1245
- if (sets.has(idx)) {
1246
- const result = new Set;
1247
- objects.push(result);
1248
- for (let i = 0;i < value.length; i++) {
1249
- result.add(reconstruct(value[i]));
1250
- }
1251
- return result;
1252
- }
1253
- const length = value.length;
1254
- const arr = new Array(length);
1255
- objects.push(arr);
1256
- for (let i = 0;i < length; i++) {
1257
- arr[i] = reconstruct(value[i]);
1258
- }
1259
- return arr;
1260
- }
1261
- if (typeof value === "object") {
1262
- if (maps.has(idx)) {
1263
- const result2 = new Map;
1264
- objects.push(result2);
1265
- const keys2 = Object.keys(value);
1266
- for (let i = 0;i < keys2.length; i++) {
1267
- const key = keys2[i];
1268
- result2.set(key, reconstruct(value[key]));
1269
- }
1270
- return result2;
1271
- }
1272
- const result = {};
1273
- objects.push(result);
1274
- const keys = Object.keys(value);
1275
- for (let i = 0;i < keys.length; i++) {
1276
- const key = keys[i];
1277
- result[key] = reconstruct(value[key]);
1278
- }
1279
- return result;
1280
- }
1281
- throw new Error(`Unsupported value in deserialization: ${value}`);
1282
- }
1283
- return reconstruct(data);
1284
- }
1285
-
1286
- // src/client.tsx
1287
- class PulseSocketIOClient {
1288
- #activeViews;
1289
- #socket = null;
1290
- #messageQueue;
1291
- #connectionListeners = new Set;
1292
- #serverErrors = new Map;
1293
- #serverErrorListeners = new Set;
1294
- #channels = new Map;
1295
- #url;
1296
- #renderId;
1297
- #frameworkNavigate;
1298
- constructor(url, renderId, frameworkNavigate) {
1299
- this.#url = url;
1300
- this.#renderId = renderId;
1301
- this.#frameworkNavigate = frameworkNavigate;
1302
- this.#socket = null;
1303
- this.#activeViews = new Map;
1304
- this.#messageQueue = [];
1305
- }
1306
- isConnected() {
1307
- return this.#socket?.connected ?? false;
1308
- }
1309
- async connect() {
1310
- if (this.#socket) {
1311
- return;
1312
- }
1313
- return new Promise((resolve, reject) => {
1314
- const socket = io(this.#url, {
1315
- transports: ["websocket", "webtransport"],
1316
- auth: { renderId: this.#renderId }
1317
- });
1318
- this.#socket = socket;
1319
- socket.on("connect", () => {
1320
- console.log("[SocketIOTransport] Connected:", this.#socket?.id);
1321
- for (const [path, route] of this.#activeViews) {
1322
- socket.emit("message", serialize({
1323
- type: "mount",
1324
- path,
1325
- routeInfo: route.routeInfo
1326
- }));
1327
- }
1328
- for (const payload of this.#messageQueue) {
1329
- if (payload.type === "mount" && this.#activeViews.has(payload.path)) {
1330
- continue;
1331
- }
1332
- if (payload.type === "navigate") {
1333
- continue;
1334
- }
1335
- socket.emit("message", serialize(payload));
1336
- }
1337
- this.#messageQueue = [];
1338
- this.notifyConnectionListeners(true);
1339
- resolve();
1340
- });
1341
- socket.on("connect_error", (err) => {
1342
- console.error("[SocketIOTransport] Connection failed:", err);
1343
- this.notifyConnectionListeners(false);
1344
- reject(err);
1345
- });
1346
- socket.on("disconnect", () => {
1347
- console.log("[SocketIOTransport] Disconnected");
1348
- this.#handleTransportDisconnect();
1349
- this.notifyConnectionListeners(false);
1350
- });
1351
- socket.on("message", (data) => this.#handleServerMessage(deserialize(data, { coerceNullsToUndefined: true })));
1352
- });
1353
- }
1354
- onConnectionChange(listener) {
1355
- this.#connectionListeners.add(listener);
1356
- listener(this.isConnected());
1357
- return () => {
1358
- this.#connectionListeners.delete(listener);
1359
- };
1360
- }
1361
- notifyConnectionListeners(connected) {
1362
- for (const listener of this.#connectionListeners) {
1363
- listener(connected);
1364
- }
1365
- }
1366
- onServerError(listener) {
1367
- this.#serverErrorListeners.add(listener);
1368
- for (const [path, err] of this.#serverErrors)
1369
- listener(path, err);
1370
- return () => {
1371
- this.#serverErrorListeners.delete(listener);
1372
- };
1373
- }
1374
- notifyServerError(path, error) {
1375
- for (const listener of this.#serverErrorListeners)
1376
- listener(path, error);
1377
- }
1378
- sendMessage(payload) {
1379
- if (this.isConnected()) {
1380
- this.#socket.emit("message", serialize(payload));
1381
- } else {
1382
- this.#messageQueue.push(payload);
1383
- }
1384
- }
1385
- mountView(path, view) {
1386
- if (this.#activeViews.has(path)) {
1387
- throw new Error(`Path ${path} is already mounted`);
1388
- }
1389
- this.#activeViews.set(path, view);
1390
- this.sendMessage({
1391
- type: "mount",
1392
- path,
1393
- routeInfo: view.routeInfo
1394
- });
1395
- }
1396
- async navigate(path, routeInfo) {
1397
- await this.sendMessage({
1398
- type: "navigate",
1399
- path,
1400
- routeInfo
1401
- });
1402
- }
1403
- unmount(path) {
1404
- this.sendMessage({ type: "unmount", path });
1405
- this.#activeViews.delete(path);
1406
- }
1407
- disconnect() {
1408
- this.#socket?.disconnect();
1409
- this.#socket = null;
1410
- this.#messageQueue = [];
1411
- this.#connectionListeners.clear();
1412
- this.#activeViews.clear();
1413
- this.#serverErrors.clear();
1414
- this.#serverErrorListeners.clear();
1415
- for (const { bridge } of this.#channels.values()) {
1416
- bridge.dispose(new PulseChannelResetError("Client disconnected"));
1417
- }
1418
- this.#channels.clear();
1419
- }
1420
- #handleServerMessage(message) {
1421
- switch (message.type) {
1422
- case "vdom_init": {
1423
- const route = this.#activeViews.get(message.path);
1424
- if (!route)
1425
- return;
1426
- if (route) {
1427
- route.onInit(message.vdom, message.callbacks, message.render_props, message.css_refs);
1428
- }
1429
- if (this.#serverErrors.has(message.path)) {
1430
- this.#serverErrors.delete(message.path);
1431
- this.notifyServerError(message.path, null);
1432
- }
1433
- break;
1434
- }
1435
- case "vdom_update": {
1436
- const route = this.#activeViews.get(message.path);
1437
- if (!route)
1438
- return;
1439
- route.onUpdate(message.ops);
1440
- if (this.#serverErrors.has(message.path)) {
1441
- this.#serverErrors.delete(message.path);
1442
- this.notifyServerError(message.path, null);
1443
- }
1444
- break;
1445
- }
1446
- case "server_error": {
1447
- if (!this.#activeViews.has(message.path))
1448
- return;
1449
- this.#serverErrors.set(message.path, message.error);
1450
- this.notifyServerError(message.path, message.error);
1451
- break;
1452
- }
1453
- case "api_call": {
1454
- this.#performApiCall(message);
1455
- break;
1456
- }
1457
- case "navigate_to": {
1458
- const replace = !!message.replace;
1459
- let dest = message.path || "";
1460
- if (dest.startsWith("//"))
1461
- dest = `${window.location.protocol}${dest}`;
1462
- const hasScheme = /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(dest);
1463
- if (hasScheme) {
1464
- if (dest.startsWith("http://") || dest.startsWith("https://")) {
1465
- try {
1466
- const url = new URL(dest);
1467
- if (url.origin === window.location.origin) {
1468
- const internal = `${url.pathname}${url.search}${url.hash}`;
1469
- this.#frameworkNavigate(internal, { replace });
1470
- } else {
1471
- if (replace)
1472
- window.location.replace(dest);
1473
- else
1474
- window.location.assign(dest);
1475
- }
1476
- } catch {
1477
- if (replace)
1478
- window.location.replace(dest);
1479
- else
1480
- window.location.assign(dest);
1481
- }
1482
- } else {
1483
- if (replace)
1484
- window.location.replace(dest);
1485
- else
1486
- window.location.assign(dest);
1487
- }
1488
- } else {
1489
- this.#frameworkNavigate(dest, { replace });
1490
- }
1491
- break;
1492
- }
1493
- case "channel_message": {
1494
- this.#routeChannelMessage(message);
1495
- break;
1496
- }
1497
- default: {
1498
- console.error("Unexpected message:", message);
1499
- }
1500
- }
1501
- }
1502
- async#performApiCall(msg) {
1503
- try {
1504
- const res = await fetch(msg.url, {
1505
- method: msg.method || "GET",
1506
- headers: {
1507
- ...msg.headers || {},
1508
- ...msg.body != null && !("content-type" in (msg.headers || {})) ? { "content-type": "application/json" } : {}
1509
- },
1510
- body: msg.body != null ? typeof msg.body === "string" ? msg.body : JSON.stringify(msg.body) : undefined,
1511
- credentials: msg.credentials || "include"
1512
- });
1513
- const headersObj = {};
1514
- res.headers.forEach((v, k) => {
1515
- headersObj[k] = v;
1516
- });
1517
- let body = null;
1518
- const ct = res.headers.get("content-type") || "";
1519
- if (ct.includes("application/json")) {
1520
- body = await res.json().catch(() => null);
1521
- } else {
1522
- body = await res.text().catch(() => null);
1523
- }
1524
- const reply = {
1525
- type: "api_result",
1526
- id: msg.id,
1527
- ok: res.ok,
1528
- status: res.status,
1529
- headers: headersObj,
1530
- body
1531
- };
1532
- this.sendMessage(reply);
1533
- } catch (err) {
1534
- const reply = {
1535
- type: "api_result",
1536
- id: msg.id,
1537
- ok: false,
1538
- status: 0,
1539
- headers: {},
1540
- body: { error: String(err) }
1541
- };
1542
- this.sendMessage(reply);
1543
- }
1544
- }
1545
- invokeCallback(path, callback, args) {
1546
- this.sendMessage({
1547
- type: "callback",
1548
- path,
1549
- callback,
1550
- args: args.map(extractEvent)
1551
- });
1552
- }
1553
- acquireChannel(id) {
1554
- const entry = this.#ensureChannelEntry(id);
1555
- entry.refCount += 1;
1556
- return entry.bridge;
1557
- }
1558
- releaseChannel(id) {
1559
- const entry = this.#channels.get(id);
1560
- if (!entry) {
1561
- return;
1562
- }
1563
- entry.refCount = Math.max(0, entry.refCount - 1);
1564
- if (entry.refCount === 0) {
1565
- entry.bridge.dispose(new PulseChannelResetError("Channel released"));
1566
- this.#channels.delete(id);
1567
- }
1568
- }
1569
- #ensureChannelEntry(id) {
1570
- let entry = this.#channels.get(id);
1571
- if (!entry) {
1572
- entry = {
1573
- bridge: createChannelBridge(this, id),
1574
- refCount: 0
1575
- };
1576
- this.#channels.set(id, entry);
1577
- }
1578
- return entry;
1579
- }
1580
- #routeChannelMessage(message) {
1581
- const entry = this.#ensureChannelEntry(message.channel);
1582
- const closed = entry.bridge.handleServerMessage(message);
1583
- if (closed && entry.refCount === 0) {
1584
- this.#channels.delete(message.channel);
1585
- }
1586
- }
1587
- #handleTransportDisconnect() {
1588
- for (const entry of this.#channels.values()) {
1589
- entry.bridge.handleDisconnect(new PulseChannelResetError("Connection lost"));
1590
- }
1591
- }
1592
- }
1593
-
1594
- // src/renderer.tsx
1595
- import {
1596
- cloneElement,
1597
- createElement,
1598
- Fragment,
1599
- isValidElement,
1600
- lazy,
1601
- Suspense
1602
- } from "react";
1603
-
1604
- // src/vdom.ts
1605
- var FRAGMENT_TAG = "$$fragment";
1606
- var MOUNT_POINT_PREFIX = "$$";
1607
- function isElementNode(node) {
1608
- return typeof node === "object" && node !== null;
1609
- }
1610
- function isMountPointNode(node) {
1611
- return typeof node === "object" && node !== null && node.tag.startsWith(MOUNT_POINT_PREFIX) && node.tag !== FRAGMENT_TAG;
1612
- }
1613
-
1614
- // src/renderer.tsx
1615
- import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
1616
-
1617
- class VDOMRenderer {
1618
- #callbacks;
1619
- #callbackCache;
1620
- #renderPropKeys;
1621
- #cssProps;
1622
- #callbackList;
1623
- #client;
1624
- #path;
1625
- #components;
1626
- #cssModules;
1627
- constructor(client, path, components, cssModules, initialCallbacks = [], initialRenderProps = [], initialCssRefs = []) {
1628
- this.#client = client;
1629
- this.#path = path;
1630
- this.#components = components;
1631
- this.#cssModules = cssModules;
1632
- this.#callbacks = new Set(initialCallbacks);
1633
- this.#callbackCache = new Map;
1634
- this.#renderPropKeys = new Set(initialRenderProps);
1635
- this.#cssProps = new Set(initialCssRefs);
1636
- this.#callbackList = [...this.#callbacks].sort();
1637
- }
1638
- hasCallbackPath(path) {
1639
- return this.#callbacks.has(path);
1640
- }
1641
- hasRenderPropPath(path) {
1642
- return this.#renderPropKeys.has(path);
1643
- }
1644
- hasAnyCallbackUnder(prefix) {
1645
- if (prefix === "")
1646
- return this.#callbackList.length > 0;
1647
- const i = this.#lowerBound(this.#callbackList, prefix);
1648
- return i < this.#callbackList.length && this.#callbackList[i].startsWith(prefix);
1649
- }
1650
- applyCallbackDelta(delta) {
1651
- if (delta.remove) {
1652
- for (const key of delta.remove) {
1653
- this.#callbacks.delete(key);
1654
- this.#callbackCache.delete(key);
1655
- }
1656
- }
1657
- if (delta.add) {
1658
- for (const key of delta.add) {
1659
- this.#callbacks.add(key);
1660
- }
1661
- }
1662
- this.#callbackList = [...this.#callbacks].sort();
1663
- }
1664
- applyRenderPropsDelta(delta) {
1665
- if (delta.remove) {
1666
- for (const key of delta.remove) {
1667
- this.#renderPropKeys.delete(key);
1668
- }
1669
- }
1670
- if (delta.add) {
1671
- for (const key of delta.add) {
1672
- this.#renderPropKeys.add(key);
1673
- }
1674
- }
1675
- }
1676
- applyCssRefsDelta(delta) {
1677
- if (delta.remove) {
1678
- for (const prop of delta.remove) {
1679
- this.#cssProps.delete(prop);
1680
- }
1681
- }
1682
- if (delta.add) {
1683
- for (const prop of delta.add) {
1684
- this.#cssProps.add(prop);
1685
- }
1686
- }
1687
- }
1688
- getCallback(path, prop) {
1689
- const key = this.#propPath(path, prop);
1690
- let fn = this.#callbackCache.get(key);
1691
- if (!fn) {
1692
- fn = (...args) => this.#client.invokeCallback(this.#path, key, args);
1693
- this.#callbackCache.set(key, fn);
1694
- }
1695
- return fn;
1696
- }
1697
- renderNode(node, currentPath = "") {
1698
- if (node == null || typeof node === "boolean" || typeof node === "number" || typeof node === "string") {
1699
- return node;
1700
- }
1701
- if (isElementNode(node)) {
1702
- const { tag, props = {}, children = [] } = node;
1703
- const newProps = {};
1704
- for (const [propName, propValue] of Object.entries(props)) {
1705
- newProps[propName] = this.transformValue(currentPath, propName, propValue);
1706
- }
1707
- if (node.key) {
1708
- newProps.key = node.key;
1709
- }
1710
- const renderedChildren = [];
1711
- for (let index = 0;index < children.length; index += 1) {
1712
- const child = children[index];
1713
- const childPath = currentPath ? `${currentPath}.${index}` : String(index);
1714
- renderedChildren.push(this.renderNode(child, childPath));
1715
- }
1716
- if (isMountPointNode(node)) {
1717
- const componentKey = node.tag.slice(MOUNT_POINT_PREFIX.length);
1718
- const Component = this.#components[componentKey];
1719
- if (!Component) {
1720
- throw new Error(`Could not find component ${componentKey}. This is a Pulse internal error.`);
1721
- }
1722
- return createElement(Component, newProps, ...renderedChildren);
1723
- }
1724
- return createElement(tag === FRAGMENT_TAG ? Fragment : tag, newProps, ...renderedChildren);
1725
- }
1726
- if (true) {
1727
- console.error("Unknown VDOM node type:", node);
1728
- }
1729
- return null;
1730
- }
1731
- #propPath(path, prop) {
1732
- return path ? `${path}.${prop}` : prop;
1733
- }
1734
- transformValue(path, key, value) {
1735
- const propPath = this.#propPath(path, key);
1736
- if (this.#callbacks.has(propPath)) {
1737
- return this.getCallback(path, key);
1738
- }
1739
- if (this.#renderPropKeys.has(propPath)) {
1740
- return this.renderNode(value, propPath);
1741
- }
1742
- if (this.#cssProps.has(propPath)) {
1743
- return this.#resolveCssToken(value);
1744
- }
1745
- return value;
1746
- }
1747
- #resolveCssToken(token) {
1748
- const idx = token.indexOf(":");
1749
- if (idx === -1) {
1750
- return token;
1751
- }
1752
- const moduleId = token.slice(0, idx);
1753
- const className = token.slice(idx + 1);
1754
- if (!moduleId || !className) {
1755
- return token;
1756
- }
1757
- const mod = this.#cssModules[moduleId];
1758
- if (!mod) {
1759
- throw new Error(`Received CSS reference for unknown module '${moduleId}'`);
1760
- }
1761
- const resolved = mod[className];
1762
- if (typeof resolved !== "string") {
1763
- throw new Error(`Received CSS reference for missing class '${className}' in module '${moduleId}'`);
1764
- }
1765
- return resolved;
1766
- }
1767
- init(vdom, callbacks, renderProps, cssRefs) {
1768
- this.#callbacks = new Set(callbacks);
1769
- for (const k of Array.from(this.#callbackCache.keys())) {
1770
- if (!this.#callbacks.has(k))
1771
- this.#callbackCache.delete(k);
1772
- }
1773
- this.#callbackList = [...this.#callbacks].sort();
1774
- this.#renderPropKeys = new Set(renderProps);
1775
- this.#cssProps = new Set(cssRefs);
1776
- return this.renderNode(vdom);
1777
- }
1778
- #ensureChildrenArray(el) {
1779
- const children = el.props?.children;
1780
- if (children == null)
1781
- return [];
1782
- return Array.isArray(children) ? children.slice() : [children];
1783
- }
1784
- applyUpdates(initialTree, updates) {
1785
- let newTree = initialTree;
1786
- for (const update of updates) {
1787
- if (update.type === "update_callbacks") {
1788
- this.applyCallbackDelta(update.data);
1789
- continue;
1790
- }
1791
- if (update.type === "update_css_refs") {
1792
- this.applyCssRefsDelta(update.data);
1793
- continue;
1794
- }
1795
- if (update.type === "update_render_props") {
1796
- this.applyRenderPropsDelta(update.data);
1797
- continue;
1798
- }
1799
- const parts = update.path.split(".").filter((s) => s.length > 0);
1800
- const descend = (node, depth, path) => {
1801
- if (depth < parts.length) {
1802
- this.#assertIsElement(node, parts, depth);
1803
- const element = node;
1804
- const childKey = parts[depth];
1805
- const childIdx = +childKey;
1806
- const childPath = path ? `${path}.${childKey}` : childKey;
1807
- if (!Number.isNaN(childIdx)) {
1808
- const childrenArr = this.#ensureChildrenArray(element);
1809
- const child = childrenArr[childIdx];
1810
- childrenArr[childIdx] = descend(child, depth + 1, childPath);
1811
- return cloneElement(element, undefined, ...childrenArr);
1812
- } else {
1813
- const baseProps = element.props ?? {};
1814
- const child = baseProps[childKey];
1815
- const props = {
1816
- ...baseProps,
1817
- [childKey]: descend(child, depth + 1, childPath)
1818
- };
1819
- return cloneElement(element, props);
1820
- }
1821
- }
1822
- switch (update.type) {
1823
- case "replace": {
1824
- return this.renderNode(update.data, update.path);
1825
- }
1826
- case "update_props": {
1827
- this.#assertIsElement(node, parts, depth);
1828
- const element = node;
1829
- const currentProps = element.props ?? {};
1830
- const nextProps = { ...currentProps };
1831
- const delta = update.data;
1832
- if (delta.remove && delta.remove.length > 0) {
1833
- for (const key of delta.remove) {
1834
- if (key in nextProps) {
1835
- delete nextProps[key];
1836
- }
1837
- }
1838
- }
1839
- if (delta.set) {
1840
- for (const [k, v] of Object.entries(delta.set)) {
1841
- nextProps[k] = this.transformValue(path, k, v);
1842
- }
1843
- }
1844
- const removedSomething = (delta.remove?.length ?? 0) > 0;
1845
- if (removedSomething) {
1846
- nextProps.key = element.key;
1847
- nextProps.ref = element.ref;
1848
- return createElement(element.type, nextProps, ...this.#ensureChildrenArray(element));
1849
- } else {
1850
- return cloneElement(element, nextProps);
1851
- }
1852
- }
1853
- case "reconciliation": {
1854
- this.#assertIsElement(node, parts, depth);
1855
- const element = node;
1856
- const prevChildren = this.#ensureChildrenArray(element);
1857
- const nextChildren = [];
1858
- const [newIndices, newContents] = update.new;
1859
- const [reuseIndices, reuseSources] = update.reuse;
1860
- let nextNew = -1, nextReuse = -1, newIdx = -1, reuseIdx = -1;
1861
- if (newIndices.length > 0) {
1862
- nextNew = newIndices[0];
1863
- newIdx = 0;
1864
- }
1865
- if (reuseIndices.length > 0) {
1866
- nextReuse = reuseIndices[0];
1867
- reuseIdx = 0;
1868
- }
1869
- for (let i = 0;i < update.N; ++i) {
1870
- if (i === nextNew) {
1871
- const contents = newContents[newIdx];
1872
- const childPath = path ? `${path}.${i}` : String(i);
1873
- nextChildren.push(this.renderNode(contents, childPath));
1874
- nextNew = newIdx < newIndices.length - 1 ? newIndices[++newIdx] : -1;
1875
- } else if (i === nextReuse) {
1876
- const srcIdx = reuseSources[reuseIdx];
1877
- let src = prevChildren[srcIdx];
1878
- const childPath = path ? `${path}.${i}` : String(i);
1879
- if (this.hasAnyCallbackUnder(childPath)) {
1880
- src = this.#rebindCallbacksInSubtree(src, childPath);
1881
- }
1882
- nextChildren.push(src);
1883
- nextReuse = reuseIdx < reuseIndices.length - 1 ? reuseIndices[++reuseIdx] : -1;
1884
- } else {
1885
- nextChildren.push(prevChildren[i]);
1886
- }
1887
- }
1888
- return cloneElement(element, null, ...nextChildren);
1889
- }
1890
- default:
1891
- throw new Error(`[Pulse renderer] Unknown update type: ${update?.type}`);
1892
- }
1893
- };
1894
- newTree = descend(newTree, 0, "");
1895
- }
1896
- return newTree;
1897
- }
1898
- #assertIsElement(node, parts, depth) {
1899
- if (!isValidElement(node)) {
1900
- console.error("Invalid node:", node);
1901
- throw new Error(`Invalid node at path ${parts.slice(0, depth).join(".")}`);
1902
- }
1903
- return true;
1904
- }
1905
- #rebindCallbacksInSubtree(node, path) {
1906
- if (!isValidElement(node))
1907
- return node;
1908
- const element = node;
1909
- const baseProps = element.props ?? {};
1910
- const nextProps = { ...baseProps };
1911
- for (const key of Object.keys(baseProps)) {
1912
- const propPath = path ? `${path}.${key}` : key;
1913
- if (this.hasCallbackPath(propPath)) {
1914
- nextProps[key] = this.getCallback(path, key);
1915
- }
1916
- if (this.hasRenderPropPath(propPath) && this.hasAnyCallbackUnder(propPath)) {
1917
- nextProps[key] = this.#rebindCallbacksInSubtree(baseProps[key], propPath);
1918
- }
1919
- }
1920
- const children = this.#ensureChildrenArray(element).map((child, idx) => {
1921
- const childPath = path ? `${path}.${idx}` : String(idx);
1922
- if (this.hasAnyCallbackUnder(childPath)) {
1923
- return this.#rebindCallbacksInSubtree(child, childPath);
1924
- } else {
1925
- return child;
1926
- }
1927
- });
1928
- return cloneElement(element, nextProps, ...children);
1929
- }
1930
- #lowerBound(arr, target) {
1931
- let lo = 0;
1932
- let hi = arr.length;
1933
- while (lo < hi) {
1934
- const mid = lo + hi >>> 1;
1935
- if (arr[mid] < target) {
1936
- lo = mid + 1;
1937
- } else {
1938
- hi = mid;
1939
- }
1940
- }
1941
- return lo;
1942
- }
1943
- }
1944
- function RenderLazy(component, fallback) {
1945
- const Component = lazy(component);
1946
- return ({ children, ...props }) => {
1947
- return /* @__PURE__ */ jsxDEV2(Suspense, {
1948
- fallback,
1949
- children: /* @__PURE__ */ jsxDEV2(Component, {
1950
- ...props,
1951
- children
1952
- }, undefined, false, undefined, this)
1953
- }, undefined, false, undefined, this);
1954
- };
1955
- }
1956
-
1957
- // src/pulse.tsx
1958
- import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
1959
- var PulseClientContext = createContext(null);
1960
- var PulsePrerenderContext = createContext(null);
1961
- var usePulseClient = () => {
1962
- const client = useContext(PulseClientContext);
1963
- if (!client) {
1964
- throw new Error("usePulseClient must be used within a PulseProvider");
1965
- }
1966
- return client;
1967
- };
1968
- var usePulsePrerender = (path) => {
1969
- const ctx = useContext(PulsePrerenderContext);
1970
- if (!ctx) {
1971
- throw new Error("usePulsePrerender must be used within a PulseProvider");
1972
- }
1973
- const view = ctx.views[path];
1974
- if (!view) {
1975
- throw new Error(`No prerender found for '${path}'`);
1976
- }
1977
- return view;
1978
- };
1979
- var inBrowser = typeof window !== "undefined";
1980
- function PulseProvider({ children, config, prerender }) {
1981
- const [connected, setConnected] = useState(true);
1982
- const rrNavigate = useNavigate();
1983
- const { renderId } = prerender;
1984
- const client = useMemo(() => new PulseSocketIOClient(config.serverAddress, renderId, rrNavigate), [config.serverAddress, rrNavigate, renderId]);
1985
- useEffect(() => client.onConnectionChange(setConnected), [client]);
1986
- useEffect(() => {
1987
- if (inBrowser) {
1988
- client.connect();
1989
- return () => client.disconnect();
1990
- }
1991
- }, [client]);
1992
- return /* @__PURE__ */ jsxDEV3(PulseClientContext.Provider, {
1993
- value: client,
1994
- children: /* @__PURE__ */ jsxDEV3(PulsePrerenderContext.Provider, {
1995
- value: prerender,
1996
- children: [
1997
- !connected && /* @__PURE__ */ jsxDEV3("div", {
1998
- style: {
1999
- position: "fixed",
2000
- bottom: "20px",
2001
- right: "20px",
2002
- backgroundColor: "red",
2003
- color: "white",
2004
- padding: "10px",
2005
- borderRadius: "5px",
2006
- zIndex: 1000
2007
- },
2008
- children: "Failed to connect to the server."
2009
- }, undefined, false, undefined, this),
2010
- children
2011
- ]
2012
- }, undefined, true, undefined, this)
2013
- }, undefined, false, undefined, this);
2014
- }
2015
- function PulseView({ externalComponents, path, cssModules }) {
2016
- const client = usePulseClient();
2017
- const initialView = usePulsePrerender(path);
2018
- const initialVDOM = initialView.vdom;
2019
- const renderer = useMemo(() => new VDOMRenderer(client, path, externalComponents, cssModules, initialView.callbacks, initialView.render_props, initialView.css_refs), [client, path, externalComponents, cssModules, initialView]);
2020
- const [tree, setTree] = useState(() => renderer.init(initialVDOM, initialView.callbacks, initialView.render_props, initialView.css_refs));
2021
- const [serverError, setServerError] = useState(null);
2022
- const location = useLocation();
2023
- const params = useParams();
2024
- const routeInfo = useMemo(() => {
2025
- const { "*": catchall = "", ...pathParams } = params;
2026
- const queryParams = new URLSearchParams(location.search);
2027
- return {
2028
- hash: location.hash,
2029
- pathname: location.pathname,
2030
- query: location.search,
2031
- queryParams: Object.fromEntries(queryParams.entries()),
2032
- pathParams,
2033
- catchall: catchall.length > 0 ? catchall.split("/") : []
2034
- };
2035
- }, [location.hash, location.pathname, location.search, JSON.stringify(params)]);
2036
- useEffect(() => {
2037
- if (inBrowser) {
2038
- client.mountView(path, {
2039
- routeInfo,
2040
- onInit: (vdom, callbacks, renderProps, cssRefs) => {
2041
- setTree(renderer.init(vdom, callbacks, renderProps, cssRefs));
2042
- },
2043
- onUpdate: (ops) => {
2044
- setTree((prev) => prev == null ? prev : renderer.applyUpdates(prev, ops));
2045
- }
2046
- });
2047
- const offErr = client.onServerError((p, err) => {
2048
- if (p === path)
2049
- setServerError(err);
2050
- });
2051
- return () => {
2052
- offErr();
2053
- client.unmount(path);
2054
- };
2055
- }
2056
- }, [client, renderer, path, routeInfo]);
2057
- useEffect(() => {
2058
- if (inBrowser) {
2059
- client.navigate(path, routeInfo);
2060
- }
2061
- }, [client, path, routeInfo]);
2062
- if (serverError) {
2063
- return /* @__PURE__ */ jsxDEV3(ServerError, {
2064
- error: serverError
2065
- }, undefined, false, undefined, this);
2066
- }
2067
- return tree;
2068
- }
2069
- function ServerError({ error }) {
2070
- return /* @__PURE__ */ jsxDEV3("div", {
2071
- style: {
2072
- padding: 16,
2073
- border: "1px solid #e00",
2074
- background: "#fff5f5",
2075
- color: "#900",
2076
- fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
2077
- whiteSpace: "pre-wrap"
2078
- },
2079
- children: [
2080
- /* @__PURE__ */ jsxDEV3("div", {
2081
- style: { fontWeight: 700, marginBottom: 8 },
2082
- children: [
2083
- "Server Error during ",
2084
- error.phase
2085
- ]
2086
- }, undefined, true, undefined, this),
2087
- error.message && /* @__PURE__ */ jsxDEV3("div", {
2088
- children: error.message
2089
- }, undefined, false, undefined, this),
2090
- error.stack && /* @__PURE__ */ jsxDEV3("details", {
2091
- open: true,
2092
- style: { marginTop: 8 },
2093
- children: [
2094
- /* @__PURE__ */ jsxDEV3("summary", {
2095
- children: "Stack trace"
2096
- }, undefined, false, undefined, this),
2097
- /* @__PURE__ */ jsxDEV3("pre", {
2098
- style: { margin: 0 },
2099
- children: error.stack
2100
- }, undefined, false, undefined, this)
2101
- ]
2102
- }, undefined, true, undefined, this)
2103
- ]
2104
- }, undefined, true, undefined, this);
2105
- }
2106
- // src/usePulseChannel.ts
2107
- import { useEffect as useEffect2, useMemo as useMemo2 } from "react";
2108
- function usePulseChannel(channelId) {
2109
- const client = usePulseClient();
2110
- const bridge = useMemo2(() => {
2111
- if (!channelId) {
2112
- throw new Error("usePulseChannel requires a non-empty channelId");
2113
- }
2114
- return client.acquireChannel(channelId);
2115
- }, [client, channelId]);
2116
- useEffect2(() => {
2117
- return () => {
2118
- client.releaseChannel(channelId);
2119
- };
2120
- }, [client, channelId]);
2121
- return bridge;
2122
- }
2123
- export {
2124
- usePulseClient,
2125
- usePulseChannel,
2126
- submitForm,
2127
- serialize,
2128
- extractServerRouteInfo,
2129
- deserialize,
2130
- RenderLazy,
2131
- PulseView,
2132
- PulseProvider,
2133
- PulseForm,
2134
- PulseChannelResetError
2135
- };
2136
-
2137
- //# debugId=E3FD7CD6C93459F364756E2164756E21
2138
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2NoYW5uZWwudHMiLCAiLi4vc3JjL2Zvcm0udHN4IiwgIi4uL3NyYy9oZWxwZXJzLnRzIiwgIi4uL3NyYy9wdWxzZS50c3giLCAiLi4vc3JjL2NsaWVudC50c3giLCAiLi4vc3JjL3NlcmlhbGl6ZS9leHRyYWN0b3IudHMiLCAiLi4vc3JjL3NlcmlhbGl6ZS9lbGVtZW50cy50cyIsICIuLi9zcmMvc2VyaWFsaXplL2V2ZW50cy50cyIsICIuLi9zcmMvc2VyaWFsaXplL3NlcmlhbGl6ZXIudHMiLCAiLi4vc3JjL3JlbmRlcmVyLnRzeCIsICIuLi9zcmMvdmRvbS50cyIsICIuLi9zcmMvdXNlUHVsc2VDaGFubmVsLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWwogICAgImltcG9ydCB0eXBlIHsgUHVsc2VTb2NrZXRJT0NsaWVudCB9IGZyb20gXCIuL2NsaWVudFwiO1xuaW1wb3J0IHR5cGUge1xuXHRTZXJ2ZXJDaGFubmVsTWVzc2FnZSxcblx0U2VydmVyQ2hhbm5lbFJlcXVlc3RNZXNzYWdlLFxuXHRTZXJ2ZXJDaGFubmVsUmVzcG9uc2VNZXNzYWdlLFxufSBmcm9tIFwiLi9tZXNzYWdlc1wiO1xuXG5leHBvcnQgY2xhc3MgUHVsc2VDaGFubmVsUmVzZXRFcnJvciBleHRlbmRzIEVycm9yIHtcblx0Y29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG5cdFx0c3VwZXIobWVzc2FnZSk7XG5cdFx0dGhpcy5uYW1lID0gXCJQdWxzZUNoYW5uZWxSZXNldEVycm9yXCI7XG5cdH1cbn1cblxuZXhwb3J0IHR5cGUgQ2hhbm5lbEV2ZW50SGFuZGxlciA9IChwYXlsb2FkOiBhbnkpID0+IGFueSB8IFByb21pc2U8YW55PjtcblxuaW50ZXJmYWNlIFBlbmRpbmdSZXF1ZXN0IHtcblx0cmVzb2x2ZTogKHZhbHVlOiBhbnkpID0+IHZvaWQ7XG5cdHJlamVjdDogKGVycm9yOiBhbnkpID0+IHZvaWQ7XG59XG5cbmZ1bmN0aW9uIHJhbmRvbUlkKCk6IHN0cmluZyB7XG5cdGlmICh0eXBlb2YgY3J5cHRvICE9PSBcInVuZGVmaW5lZFwiICYmIHR5cGVvZiBjcnlwdG8ucmFuZG9tVVVJRCA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0cmV0dXJuIGNyeXB0by5yYW5kb21VVUlEKCkucmVwbGFjZSgvLS9nLCBcIlwiKTtcblx0fVxuXHRyZXR1cm4gTWF0aC5yYW5kb20oKS50b1N0cmluZygxNikuc2xpY2UoMikgKyBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDE2KS5zbGljZSgyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0RXJyb3IoZXJyb3I6IHVua25vd24pOiBzdHJpbmcge1xuXHRpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikgcmV0dXJuIGVycm9yLm1lc3NhZ2U7XG5cdGlmICh0eXBlb2YgZXJyb3IgPT09IFwic3RyaW5nXCIpIHJldHVybiBlcnJvcjtcblx0dHJ5IHtcblx0XHRyZXR1cm4gSlNPTi5zdHJpbmdpZnkoZXJyb3IpO1xuXHR9IGNhdGNoIHtcblx0XHRyZXR1cm4gU3RyaW5nKGVycm9yKTtcblx0fVxufVxuXG5mdW5jdGlvbiBpc1NlcnZlclJlc3BvbnNlTWVzc2FnZShcblx0bWVzc2FnZTogU2VydmVyQ2hhbm5lbE1lc3NhZ2UsXG4pOiBtZXNzYWdlIGlzIFNlcnZlckNoYW5uZWxSZXNwb25zZU1lc3NhZ2Uge1xuXHRyZXR1cm4gdHlwZW9mIChtZXNzYWdlIGFzIFNlcnZlckNoYW5uZWxSZXNwb25zZU1lc3NhZ2UpLnJlc3BvbnNlVG8gPT09IFwic3RyaW5nXCI7XG59XG5cbmZ1bmN0aW9uIGlzU2VydmVyUmVxdWVzdE1lc3NhZ2UoXG5cdG1lc3NhZ2U6IFNlcnZlckNoYW5uZWxNZXNzYWdlLFxuKTogbWVzc2FnZSBpcyBTZXJ2ZXJDaGFubmVsUmVxdWVzdE1lc3NhZ2Uge1xuXHRyZXR1cm4gdHlwZW9mIChtZXNzYWdlIGFzIFNlcnZlckNoYW5uZWxSZXF1ZXN0TWVzc2FnZSkuZXZlbnQgPT09IFwic3RyaW5nXCI7XG59XG5cbmV4cG9ydCBjbGFzcyBDaGFubmVsQnJpZGdlIHtcblx0cHJpdmF0ZSBoYW5kbGVycyA9IG5ldyBNYXA8c3RyaW5nLCBTZXQ8Q2hhbm5lbEV2ZW50SGFuZGxlcj4+KCk7XG5cdHByaXZhdGUgcGVuZGluZyA9IG5ldyBNYXA8c3RyaW5nLCBQZW5kaW5nUmVxdWVzdD4oKTtcblx0cHJpdmF0ZSBiYWNrbG9nOiBTZXJ2ZXJDaGFubmVsUmVxdWVzdE1lc3NhZ2VbXSA9IFtdO1xuXHRwcml2YXRlIGNsb3NlZCA9IGZhbHNlO1xuXG5cdGNvbnN0cnVjdG9yKFxuXHRcdHByaXZhdGUgY2xpZW50OiBQdWxzZVNvY2tldElPQ2xpZW50LFxuXHRcdHB1YmxpYyByZWFkb25seSBpZDogc3RyaW5nLFxuXHQpIHt9XG5cblx0ZW1pdChldmVudDogc3RyaW5nLCBwYXlsb2FkPzogYW55KTogdm9pZCB7XG5cdFx0dGhpcy5lbnN1cmVPcGVuKCk7XG5cdFx0dGhpcy5jbGllbnQuc2VuZE1lc3NhZ2Uoe1xuXHRcdFx0dHlwZTogXCJjaGFubmVsX21lc3NhZ2VcIixcblx0XHRcdGNoYW5uZWw6IHRoaXMuaWQsXG5cdFx0XHRldmVudCxcblx0XHRcdHBheWxvYWQsXG5cdFx0fSk7XG5cdH1cblxuXHRyZXF1ZXN0KGV2ZW50OiBzdHJpbmcsIHBheWxvYWQ/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuXHRcdHRoaXMuZW5zdXJlT3BlbigpO1xuXHRcdGNvbnN0IHJlcXVlc3RJZCA9IHJhbmRvbUlkKCk7XG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0XHRcdHRoaXMucGVuZGluZy5zZXQocmVxdWVzdElkLCB7IHJlc29sdmUsIHJlamVjdCB9KTtcblx0XHRcdHRoaXMuY2xpZW50LnNlbmRNZXNzYWdlKHtcblx0XHRcdFx0dHlwZTogXCJjaGFubmVsX21lc3NhZ2VcIixcblx0XHRcdFx0Y2hhbm5lbDogdGhpcy5pZCxcblx0XHRcdFx0ZXZlbnQsXG5cdFx0XHRcdHBheWxvYWQsXG5cdFx0XHRcdHJlcXVlc3RJZCxcblx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9XG5cblx0b24oZXZlbnQ6IHN0cmluZywgaGFuZGxlcjogQ2hhbm5lbEV2ZW50SGFuZGxlcik6ICgpID0+IHZvaWQge1xuXHRcdHRoaXMuZW5zdXJlT3BlbigpO1xuXHRcdGxldCBidWNrZXQgPSB0aGlzLmhhbmRsZXJzLmdldChldmVudCk7XG5cdFx0aWYgKCFidWNrZXQpIHtcblx0XHRcdGJ1Y2tldCA9IG5ldyBTZXQoKTtcblx0XHRcdHRoaXMuaGFuZGxlcnMuc2V0KGV2ZW50LCBidWNrZXQpO1xuXHRcdH1cblx0XHRidWNrZXQuYWRkKGhhbmRsZXIpO1xuXHRcdHRoaXMuZmx1c2hCYWNrbG9nKGV2ZW50KTtcblx0XHRyZXR1cm4gKCkgPT4ge1xuXHRcdFx0Y29uc3Qgc2V0ID0gdGhpcy5oYW5kbGVycy5nZXQoZXZlbnQpO1xuXHRcdFx0aWYgKCFzZXQpIHJldHVybjtcblx0XHRcdHNldC5kZWxldGUoaGFuZGxlcik7XG5cdFx0XHRpZiAoc2V0LnNpemUgPT09IDApIHtcblx0XHRcdFx0dGhpcy5oYW5kbGVycy5kZWxldGUoZXZlbnQpO1xuXHRcdFx0fVxuXHRcdH07XG5cdH1cblxuXHRoYW5kbGVTZXJ2ZXJNZXNzYWdlKG1lc3NhZ2U6IFNlcnZlckNoYW5uZWxNZXNzYWdlKTogYm9vbGVhbiB7XG5cdFx0aWYgKGlzU2VydmVyUmVzcG9uc2VNZXNzYWdlKG1lc3NhZ2UpKSB7XG5cdFx0XHR0aGlzLnJlc29sdmVQZW5kaW5nKG1lc3NhZ2UpO1xuXHRcdFx0cmV0dXJuIHRoaXMuY2xvc2VkO1xuXHRcdH1cblx0XHRpZiAodGhpcy5jbG9zZWQpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0XHRpZiAoIWlzU2VydmVyUmVxdWVzdE1lc3NhZ2UobWVzc2FnZSkpIHtcblx0XHRcdHJldHVybiB0aGlzLmNsb3NlZDtcblx0XHR9XG5cblx0XHRpZiAobWVzc2FnZS5ldmVudCA9PT0gXCJfX2Nsb3NlX19cIikge1xuXHRcdFx0dGhpcy5jbG9zZShuZXcgUHVsc2VDaGFubmVsUmVzZXRFcnJvcihcIkNoYW5uZWwgY2xvc2VkIGJ5IHNlcnZlclwiKSk7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cdFx0aWYgKG1lc3NhZ2UucmVxdWVzdElkKSB7XG5cdFx0XHR2b2lkIHRoaXMuZGlzcGF0Y2hSZXF1ZXN0KFxuXHRcdFx0XHRtZXNzYWdlIGFzIFNlcnZlckNoYW5uZWxSZXF1ZXN0TWVzc2FnZSAmIHtcblx0XHRcdFx0XHRyZXF1ZXN0SWQ6IHN0cmluZztcblx0XHRcdFx0fSxcblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuZGlzcGF0Y2hFdmVudChtZXNzYWdlKTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuY2xvc2VkO1xuXHR9XG5cblx0aGFuZGxlRGlzY29ubmVjdChyZWFzb246IFB1bHNlQ2hhbm5lbFJlc2V0RXJyb3IpOiB2b2lkIHtcblx0XHR0aGlzLmNsb3NlKHJlYXNvbik7XG5cdH1cblxuXHRkaXNwb3NlKHJlYXNvbjogUHVsc2VDaGFubmVsUmVzZXRFcnJvcik6IHZvaWQge1xuXHRcdHRoaXMuY2xvc2UocmVhc29uKTtcblx0fVxuXG5cdHByaXZhdGUgZW5zdXJlT3BlbigpOiB2b2lkIHtcblx0XHRpZiAodGhpcy5jbG9zZWQpIHtcblx0XHRcdHRocm93IG5ldyBQdWxzZUNoYW5uZWxSZXNldEVycm9yKFwiQ2hhbm5lbCBpcyBjbG9zZWRcIik7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBmbHVzaEJhY2tsb2coZXZlbnQ6IHN0cmluZyk6IHZvaWQge1xuXHRcdGlmICh0aGlzLmJhY2tsb2cubGVuZ3RoID09PSAwKSByZXR1cm47XG5cdFx0Y29uc3QgcmVtYWluaW5nOiBTZXJ2ZXJDaGFubmVsUmVxdWVzdE1lc3NhZ2VbXSA9IFtdO1xuXHRcdGZvciAoY29uc3QgaXRlbSBvZiB0aGlzLmJhY2tsb2cpIHtcblx0XHRcdGlmIChpdGVtLmV2ZW50ID09PSBldmVudCkge1xuXHRcdFx0XHR0aGlzLmRpc3BhdGNoRXZlbnQoaXRlbSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZW1haW5pbmcucHVzaChpdGVtKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0dGhpcy5iYWNrbG9nID0gcmVtYWluaW5nO1xuXHR9XG5cblx0cHJpdmF0ZSBkaXNwYXRjaEV2ZW50KG1lc3NhZ2U6IFNlcnZlckNoYW5uZWxSZXF1ZXN0TWVzc2FnZSk6IHZvaWQge1xuXHRcdGNvbnN0IGhhbmRsZXJzID0gdGhpcy5oYW5kbGVycy5nZXQobWVzc2FnZS5ldmVudCk7XG5cdFx0aWYgKCFoYW5kbGVycyB8fCBoYW5kbGVycy5zaXplID09PSAwKSB7XG5cdFx0XHR0aGlzLmJhY2tsb2cucHVzaChtZXNzYWdlKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0Zm9yIChjb25zdCBoYW5kbGVyIG9mIGhhbmRsZXJzKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRjb25zdCByZXN1bHQgPSBoYW5kbGVyKG1lc3NhZ2UucGF5bG9hZCk7XG5cdFx0XHRcdGlmIChyZXN1bHQgJiYgdHlwZW9mIChyZXN1bHQgYXMgUHJvbWlzZTxhbnk+KS50aGVuID09PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdFx0XHR2b2lkIChyZXN1bHQgYXMgUHJvbWlzZTxhbnk+KS5jYXRjaCgoZXJyKSA9PiB7XG5cdFx0XHRcdFx0XHRjb25zb2xlLmVycm9yKFwiUHVsc2UgY2hhbm5lbCBoYW5kbGVyIGVycm9yXCIsIGVycik7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gY2F0Y2ggKGVycikge1xuXHRcdFx0XHRjb25zb2xlLmVycm9yKFwiUHVsc2UgY2hhbm5lbCBoYW5kbGVyIGVycm9yXCIsIGVycik7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBhc3luYyBkaXNwYXRjaFJlcXVlc3QoXG5cdFx0bWVzc2FnZTogU2VydmVyQ2hhbm5lbFJlcXVlc3RNZXNzYWdlICYgeyByZXF1ZXN0SWQ6IHN0cmluZyB9LFxuXHQpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRjb25zdCBoYW5kbGVycyA9IHRoaXMuaGFuZGxlcnMuZ2V0KG1lc3NhZ2UuZXZlbnQpO1xuXHRcdGxldCByZXNwb25zZTogYW55O1xuXHRcdGxldCBlcnJvcjogYW55O1xuXHRcdGlmIChoYW5kbGVycyAmJiBoYW5kbGVycy5zaXplID4gMCkge1xuXHRcdFx0Zm9yIChjb25zdCBoYW5kbGVyIG9mIGhhbmRsZXJzKSB7XG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0Y29uc3QgcmVzdWx0ID0gaGFuZGxlcihtZXNzYWdlLnBheWxvYWQpO1xuXHRcdFx0XHRcdHJlc3BvbnNlID0gYXdhaXQgUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCk7XG5cdFx0XHRcdFx0aWYgKHJlc3BvbnNlICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0XHRcdFx0ZXJyb3IgPSBlcnI7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0aWYgKGVycm9yKSB7XG5cdFx0XHR0aGlzLmNsaWVudC5zZW5kTWVzc2FnZSh7XG5cdFx0XHRcdHR5cGU6IFwiY2hhbm5lbF9tZXNzYWdlXCIsXG5cdFx0XHRcdGNoYW5uZWw6IHRoaXMuaWQsXG5cdFx0XHRcdGV2ZW50OiB1bmRlZmluZWQsXG5cdFx0XHRcdHJlc3BvbnNlVG86IG1lc3NhZ2UucmVxdWVzdElkLFxuXHRcdFx0XHRlcnJvcjogZm9ybWF0RXJyb3IoZXJyb3IpLFxuXHRcdFx0fSk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMuY2xpZW50LnNlbmRNZXNzYWdlKHtcblx0XHRcdHR5cGU6IFwiY2hhbm5lbF9tZXNzYWdlXCIsXG5cdFx0XHRjaGFubmVsOiB0aGlzLmlkLFxuXHRcdFx0ZXZlbnQ6IHVuZGVmaW5lZCxcblx0XHRcdHJlc3BvbnNlVG86IG1lc3NhZ2UucmVxdWVzdElkLFxuXHRcdFx0cGF5bG9hZDogcmVzcG9uc2UsXG5cdFx0fSk7XG5cdH1cblxuXHRwcml2YXRlIHJlc29sdmVQZW5kaW5nKG1lc3NhZ2U6IFNlcnZlckNoYW5uZWxSZXNwb25zZU1lc3NhZ2UpOiB2b2lkIHtcblx0XHRjb25zdCBlbnRyeSA9IG1lc3NhZ2UucmVzcG9uc2VUbyA/IHRoaXMucGVuZGluZy5nZXQobWVzc2FnZS5yZXNwb25zZVRvKSA6IHVuZGVmaW5lZDtcblx0XHRpZiAoIWVudHJ5KSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMucGVuZGluZy5kZWxldGUobWVzc2FnZS5yZXNwb25zZVRvISk7XG5cdFx0aWYgKG1lc3NhZ2UuZXJyb3IgIT09IHVuZGVmaW5lZCAmJiBtZXNzYWdlLmVycm9yICE9PSBudWxsKSB7XG5cdFx0XHRlbnRyeS5yZWplY3QobmV3IFB1bHNlQ2hhbm5lbFJlc2V0RXJyb3IoU3RyaW5nKG1lc3NhZ2UuZXJyb3IpKSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGVudHJ5LnJlc29sdmUobWVzc2FnZS5wYXlsb2FkKTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGNsb3NlKHJlYXNvbjogUHVsc2VDaGFubmVsUmVzZXRFcnJvcik6IHZvaWQge1xuXHRcdGlmICh0aGlzLmNsb3NlZCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHR0aGlzLmNsb3NlZCA9IHRydWU7XG5cdFx0Zm9yIChjb25zdCByZXF1ZXN0IG9mIHRoaXMucGVuZGluZy52YWx1ZXMoKSkge1xuXHRcdFx0cmVxdWVzdC5yZWplY3QocmVhc29uKTtcblx0XHR9XG5cdFx0dGhpcy5wZW5kaW5nLmNsZWFyKCk7XG5cdFx0dGhpcy5oYW5kbGVycy5jbGVhcigpO1xuXHRcdHRoaXMuYmFja2xvZyA9IFtdO1xuXHRcdC8vIE5vLW9wOiBvd25pbmcgY2xpZW50IG1hbmFnZXMgcmVnaXN0cnkgbGlmZWN5Y2xlLlxuXHR9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDaGFubmVsQnJpZGdlKGNsaWVudDogUHVsc2VTb2NrZXRJT0NsaWVudCwgaWQ6IHN0cmluZyk6IENoYW5uZWxCcmlkZ2Uge1xuXHRyZXR1cm4gbmV3IENoYW5uZWxCcmlkZ2UoY2xpZW50LCBpZCk7XG59XG4iLAogICAgImltcG9ydCBSZWFjdCwgeyB0eXBlIEZvcm1FdmVudCwgZm9yd2FyZFJlZiwgdXNlQ2FsbGJhY2sgfSBmcm9tIFwicmVhY3RcIjtcblxuZXhwb3J0IHR5cGUgUHVsc2VGb3JtUHJvcHMgPSBSZWFjdC5Db21wb25lbnRQcm9wc1dpdGhvdXRSZWY8XCJmb3JtXCI+ICYge1xuXHRhY3Rpb246IHN0cmluZztcbn07XG5cbi8qKlxuICogUHVsc2VGb3JtIGludGVyY2VwdHMgbmF0aXZlIGZvcm0gc3VibWlzc2lvbnMgYW5kIHNlbmRzIHRoZW0gdGhyb3VnaCBmZXRjaCBzbyB0aGVcbiAqIHN1cnJvdW5kaW5nIFB1bHNlIHZpZXcgc3RheXMgbW91bnRlZC4gU2VydmVyLXNpZGUgaGFuZGxlcnMgYXJlIHN0aWxsIGludm9rZWQgdmlhXG4gKiB0aGUgZm9ybSBhY3Rpb24gZW5kcG9pbnQgYW5kIHJlYWN0aXZlIHVwZGF0ZXMgcHJvcGFnYXRlIG92ZXIgdGhlIHNvY2tldC5cbiAqL1xuZXhwb3J0IGNvbnN0IFB1bHNlRm9ybSA9IGZvcndhcmRSZWY8SFRNTEZvcm1FbGVtZW50LCBQdWxzZUZvcm1Qcm9wcz4oZnVuY3Rpb24gUHVsc2VGb3JtKFxuXHR7IG9uU3VibWl0LCBhY3Rpb24sIC4uLnJlc3QgfSxcblx0cmVmLFxuKSB7XG5cdHJldHVybiAoXG5cdFx0PGZvcm1cblx0XHRcdHsuLi5yZXN0fVxuXHRcdFx0YWN0aW9uPXthY3Rpb259XG5cdFx0XHRyZWY9e3JlZn1cblx0XHRcdG9uU3VibWl0PXt1c2VDYWxsYmFjayhcblx0XHRcdFx0KGV2ZW50OiBGb3JtRXZlbnQ8SFRNTEZvcm1FbGVtZW50PikgPT4gc3VibWl0Rm9ybSh7IGV2ZW50LCBhY3Rpb24sIG9uU3VibWl0IH0pLFxuXHRcdFx0XHRbYWN0aW9uLCBvblN1Ym1pdF0sXG5cdFx0XHQpfVxuXHRcdC8+XG5cdCk7XG59KTtcblxuaW50ZXJmYWNlIFN1Ym1pdEZvcm0ge1xuXHRldmVudDogUmVhY3QuRm9ybUV2ZW50PEhUTUxGb3JtRWxlbWVudD47XG5cdGFjdGlvbjogc3RyaW5nO1xuXHRvblN1Ym1pdD86IFB1bHNlRm9ybVByb3BzW1wib25TdWJtaXRcIl07XG5cdGZvcm1EYXRhPzogRm9ybURhdGE7XG5cdGZvcmNlPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN1Ym1pdEZvcm0oeyBldmVudCwgYWN0aW9uLCBvblN1Ym1pdCwgZm9ybURhdGEsIGZvcmNlIH06IFN1Ym1pdEZvcm0pIHtcblx0b25TdWJtaXQ/LihldmVudCk7XG5cdGlmICghZm9yY2UgJiYgZXZlbnQuZGVmYXVsdFByZXZlbnRlZCkge1xuXHRcdHJldHVybjtcblx0fVxuXHRjb25zdCBmb3JtID0gZXZlbnQuY3VycmVudFRhcmdldDtcblx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0Y29uc3QgbmF0aXZlRXZlbnQgPSBldmVudC5uYXRpdmVFdmVudCBhcyBTdWJtaXRFdmVudDtcblx0aWYgKCFmb3JtRGF0YSkge1xuXHRcdGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKGZvcm0sIG5hdGl2ZUV2ZW50LnN1Ym1pdHRlcik7XG5cdH1cblx0Y29uc3QgdXJsID0gbmV3IFVSTChhY3Rpb24sIHdpbmRvdy5sb2NhdGlvbi5ocmVmKTtcblx0dHJ5IHtcblx0XHRhd2FpdCBmZXRjaCh1cmwsIHtcblx0XHRcdG1ldGhvZDogXCJQT1NUXCIsXG5cdFx0XHQvLyBSZXF1aXJlZCBmb3Igb3VyIGhvc3Rpbmcgc2NlbmFyaW9zIG9mIHNhbWUgaG9zdCArIGRpZmZlcmVudCBwb3J0cyBvciAyIHN1YmRvbWFpbnNcblx0XHRcdGNyZWRlbnRpYWxzOiBcImluY2x1ZGVcIixcblx0XHRcdGJvZHk6IGZvcm1EYXRhLFxuXHRcdH0pO1xuXHR9IGNhdGNoIChlcnIpIHtcblx0XHRpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG5cdFx0XHRjb25zb2xlLmVycm9yKFwiW1B1bHNlXSBGb3JtIHN1Ym1pc3Npb24gZmFpbGVkXCIsIGVycik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRocm93IGVycjtcblx0XHR9XG5cdH1cbn1cbiIsCiAgICAiaW1wb3J0IHR5cGUgeyBMb2FkZXJGdW5jdGlvbkFyZ3MgfSBmcm9tIFwicmVhY3Qtcm91dGVyXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUm91dGVJbmZvIHtcblx0cGF0aG5hbWU6IHN0cmluZztcblx0aGFzaDogc3RyaW5nO1xuXHRxdWVyeTogc3RyaW5nO1xuXHRxdWVyeVBhcmFtczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcblx0cGF0aFBhcmFtczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPjtcblx0Y2F0Y2hhbGw6IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdFNlcnZlclJvdXRlSW5mbyh7IHBhcmFtcywgcmVxdWVzdCB9OiBMb2FkZXJGdW5jdGlvbkFyZ3MpIHtcblx0Y29uc3QgeyBcIipcIjogY2F0Y2hhbGwgPSBcIlwiLCAuLi5wYXRoUGFyYW1zIH0gPSBwYXJhbXM7XG5cdGNvbnN0IHBhcnNlZFVybCA9IG5ldyBVUkwocmVxdWVzdC51cmwpO1xuXG5cdHJldHVybiB7XG5cdFx0aGFzaDogcGFyc2VkVXJsLmhhc2gsXG5cdFx0cGF0aG5hbWU6IHBhcnNlZFVybC5wYXRobmFtZSxcblx0XHRxdWVyeTogcGFyc2VkVXJsLnNlYXJjaCxcblx0XHRxdWVyeVBhcmFtczogT2JqZWN0LmZyb21FbnRyaWVzKHBhcnNlZFVybC5zZWFyY2hQYXJhbXMuZW50cmllcygpKSxcblx0XHRwYXRoUGFyYW1zLFxuXHRcdGNhdGNoYWxsOiBjYXRjaGFsbC5sZW5ndGggPiAxID8gY2F0Y2hhbGwuc3BsaXQoXCIvXCIpIDogW10sXG5cdH0gc2F0aXNmaWVzIFJvdXRlSW5mbztcbn1cbiIsCiAgICAiaW1wb3J0IHsgY3JlYXRlQ29udGV4dCwgdHlwZSBSZWFjdE5vZGUsIHVzZUNvbnRleHQsIHVzZUVmZmVjdCwgdXNlTWVtbywgdXNlU3RhdGUgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IHVzZUxvY2F0aW9uLCB1c2VOYXZpZ2F0ZSwgdXNlUGFyYW1zIH0gZnJvbSBcInJlYWN0LXJvdXRlclwiO1xuaW1wb3J0IHsgUHVsc2VTb2NrZXRJT0NsaWVudCB9IGZyb20gXCIuL2NsaWVudFwiO1xuaW1wb3J0IHR5cGUgeyBSb3V0ZUluZm8gfSBmcm9tIFwiLi9oZWxwZXJzXCI7XG5pbXBvcnQgdHlwZSB7IFNlcnZlckVycm9ySW5mbyB9IGZyb20gXCIuL21lc3NhZ2VzXCI7XG5pbXBvcnQgeyBWRE9NUmVuZGVyZXIgfSBmcm9tIFwiLi9yZW5kZXJlclwiO1xuaW1wb3J0IHR5cGUgeyBDb21wb25lbnRSZWdpc3RyeSwgVkRPTSB9IGZyb20gXCIuL3Zkb21cIjtcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFR5cGVzXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5leHBvcnQgaW50ZXJmYWNlIFB1bHNlQ29uZmlnIHtcblx0c2VydmVyQWRkcmVzczogc3RyaW5nO1xufVxuXG5leHBvcnQgdHlwZSBQdWxzZVByZXJlbmRlclZpZXcgPSB7XG5cdHZkb206IFZET007XG5cdGNhbGxiYWNrczogc3RyaW5nW107XG5cdHJlbmRlcl9wcm9wczogc3RyaW5nW107XG5cdGNzc19yZWZzOiBzdHJpbmdbXTtcbn07XG5cbmV4cG9ydCB0eXBlIFB1bHNlUHJlcmVuZGVyID0ge1xuXHRyZW5kZXJJZDogc3RyaW5nO1xuXHR2aWV3czogUmVjb3JkPHN0cmluZywgUHVsc2VQcmVyZW5kZXJWaWV3Pjtcbn07XG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gQ29udGV4dCBhbmQgSG9va3Ncbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8vIENvbnRleHQgZm9yIHRoZSBjbGllbnQsIHByb3ZpZGVkIGJ5IFB1bHNlUHJvdmlkZXJcbmNvbnN0IFB1bHNlQ2xpZW50Q29udGV4dCA9IGNyZWF0ZUNvbnRleHQ8UHVsc2VTb2NrZXRJT0NsaWVudCB8IG51bGw+KG51bGwpO1xuY29uc3QgUHVsc2VQcmVyZW5kZXJDb250ZXh0ID0gY3JlYXRlQ29udGV4dDxQdWxzZVByZXJlbmRlciB8IG51bGw+KG51bGwpO1xuXG5leHBvcnQgY29uc3QgdXNlUHVsc2VDbGllbnQgPSAoKSA9PiB7XG5cdGNvbnN0IGNsaWVudCA9IHVzZUNvbnRleHQoUHVsc2VDbGllbnRDb250ZXh0KTtcblx0aWYgKCFjbGllbnQpIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoXCJ1c2VQdWxzZUNsaWVudCBtdXN0IGJlIHVzZWQgd2l0aGluIGEgUHVsc2VQcm92aWRlclwiKTtcblx0fVxuXHRyZXR1cm4gY2xpZW50O1xufTtcblxuZXhwb3J0IGNvbnN0IHVzZVB1bHNlUHJlcmVuZGVyID0gKHBhdGg6IHN0cmluZykgPT4ge1xuXHRjb25zdCBjdHggPSB1c2VDb250ZXh0KFB1bHNlUHJlcmVuZGVyQ29udGV4dCk7XG5cdGlmICghY3R4KSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKFwidXNlUHVsc2VQcmVyZW5kZXIgbXVzdCBiZSB1c2VkIHdpdGhpbiBhIFB1bHNlUHJvdmlkZXJcIik7XG5cdH1cblx0Y29uc3QgdmlldyA9IGN0eC52aWV3c1twYXRoXTtcblx0aWYgKCF2aWV3KSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKGBObyBwcmVyZW5kZXIgZm91bmQgZm9yICcke3BhdGh9J2ApO1xuXHR9XG5cdHJldHVybiB2aWV3O1xufTtcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFByb3ZpZGVyXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5leHBvcnQgaW50ZXJmYWNlIFB1bHNlUHJvdmlkZXJQcm9wcyB7XG5cdGNoaWxkcmVuOiBSZWFjdE5vZGU7XG5cdGNvbmZpZzogUHVsc2VDb25maWc7XG5cdHByZXJlbmRlcjogUHVsc2VQcmVyZW5kZXI7XG59XG5cbmNvbnN0IGluQnJvd3NlciA9IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBQdWxzZVByb3ZpZGVyKHsgY2hpbGRyZW4sIGNvbmZpZywgcHJlcmVuZGVyIH06IFB1bHNlUHJvdmlkZXJQcm9wcykge1xuXHRjb25zdCBbY29ubmVjdGVkLCBzZXRDb25uZWN0ZWRdID0gdXNlU3RhdGUodHJ1ZSk7XG5cdGNvbnN0IHJyTmF2aWdhdGUgPSB1c2VOYXZpZ2F0ZSgpO1xuXHRjb25zdCB7IHJlbmRlcklkIH0gPSBwcmVyZW5kZXI7XG5cblx0Y29uc3QgY2xpZW50ID0gdXNlTWVtbyhcblx0XHQoKSA9PiBuZXcgUHVsc2VTb2NrZXRJT0NsaWVudChjb25maWcuc2VydmVyQWRkcmVzcywgcmVuZGVySWQsIHJyTmF2aWdhdGUpLFxuXHRcdFtjb25maWcuc2VydmVyQWRkcmVzcywgcnJOYXZpZ2F0ZSwgcmVuZGVySWRdLFxuXHQpO1xuXG5cdHVzZUVmZmVjdCgoKSA9PiBjbGllbnQub25Db25uZWN0aW9uQ2hhbmdlKHNldENvbm5lY3RlZCksIFtjbGllbnRdKTtcblxuXHR1c2VFZmZlY3QoKCkgPT4ge1xuXHRcdGlmIChpbkJyb3dzZXIpIHtcblx0XHRcdGNsaWVudC5jb25uZWN0KCk7XG5cdFx0XHRyZXR1cm4gKCkgPT4gY2xpZW50LmRpc2Nvbm5lY3QoKTtcblx0XHR9XG5cdH0sIFtjbGllbnRdKTtcblxuXHRyZXR1cm4gKFxuXHRcdDxQdWxzZUNsaWVudENvbnRleHQuUHJvdmlkZXIgdmFsdWU9e2NsaWVudH0+XG5cdFx0XHQ8UHVsc2VQcmVyZW5kZXJDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXtwcmVyZW5kZXJ9PlxuXHRcdFx0XHR7IWNvbm5lY3RlZCAmJiAoXG5cdFx0XHRcdFx0PGRpdlxuXHRcdFx0XHRcdFx0c3R5bGU9e3tcblx0XHRcdFx0XHRcdFx0cG9zaXRpb246IFwiZml4ZWRcIixcblx0XHRcdFx0XHRcdFx0Ym90dG9tOiBcIjIwcHhcIixcblx0XHRcdFx0XHRcdFx0cmlnaHQ6IFwiMjBweFwiLFxuXHRcdFx0XHRcdFx0XHRiYWNrZ3JvdW5kQ29sb3I6IFwicmVkXCIsXG5cdFx0XHRcdFx0XHRcdGNvbG9yOiBcIndoaXRlXCIsXG5cdFx0XHRcdFx0XHRcdHBhZGRpbmc6IFwiMTBweFwiLFxuXHRcdFx0XHRcdFx0XHRib3JkZXJSYWRpdXM6IFwiNXB4XCIsXG5cdFx0XHRcdFx0XHRcdHpJbmRleDogMTAwMCxcblx0XHRcdFx0XHRcdH19XG5cdFx0XHRcdFx0PlxuXHRcdFx0XHRcdFx0RmFpbGVkIHRvIGNvbm5lY3QgdG8gdGhlIHNlcnZlci5cblx0XHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0KX1cblx0XHRcdFx0e2NoaWxkcmVufVxuXHRcdFx0PC9QdWxzZVByZXJlbmRlckNvbnRleHQuUHJvdmlkZXI+XG5cdFx0PC9QdWxzZUNsaWVudENvbnRleHQuUHJvdmlkZXI+XG5cdCk7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBWaWV3XG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5leHBvcnQgaW50ZXJmYWNlIFB1bHNlVmlld1Byb3BzIHtcblx0ZXh0ZXJuYWxDb21wb25lbnRzOiBDb21wb25lbnRSZWdpc3RyeTtcblx0cGF0aDogc3RyaW5nO1xuXHRjc3NNb2R1bGVzOiBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+Pjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFB1bHNlVmlldyh7IGV4dGVybmFsQ29tcG9uZW50cywgcGF0aCwgY3NzTW9kdWxlcyB9OiBQdWxzZVZpZXdQcm9wcykge1xuXHRjb25zdCBjbGllbnQgPSB1c2VQdWxzZUNsaWVudCgpO1xuXHRjb25zdCBpbml0aWFsVmlldyA9IHVzZVB1bHNlUHJlcmVuZGVyKHBhdGgpO1xuXHRjb25zdCBpbml0aWFsVkRPTSA9IGluaXRpYWxWaWV3LnZkb207XG5cdGNvbnN0IHJlbmRlcmVyID0gdXNlTWVtbyhcblx0XHQoKSA9PlxuXHRcdFx0bmV3IFZET01SZW5kZXJlcihcblx0XHRcdFx0Y2xpZW50LFxuXHRcdFx0XHRwYXRoLFxuXHRcdFx0XHRleHRlcm5hbENvbXBvbmVudHMsXG5cdFx0XHRcdGNzc01vZHVsZXMsXG5cdFx0XHRcdGluaXRpYWxWaWV3LmNhbGxiYWNrcyxcblx0XHRcdFx0aW5pdGlhbFZpZXcucmVuZGVyX3Byb3BzLFxuXHRcdFx0XHRpbml0aWFsVmlldy5jc3NfcmVmcyxcblx0XHRcdCksXG5cdFx0W2NsaWVudCwgcGF0aCwgZXh0ZXJuYWxDb21wb25lbnRzLCBjc3NNb2R1bGVzLCBpbml0aWFsVmlld10sXG5cdCk7XG5cdGNvbnN0IFt0cmVlLCBzZXRUcmVlXSA9IHVzZVN0YXRlPFJlYWN0Tm9kZT4oKCkgPT5cblx0XHRyZW5kZXJlci5pbml0KFxuXHRcdFx0aW5pdGlhbFZET00sXG5cdFx0XHRpbml0aWFsVmlldy5jYWxsYmFja3MsXG5cdFx0XHRpbml0aWFsVmlldy5yZW5kZXJfcHJvcHMsXG5cdFx0XHRpbml0aWFsVmlldy5jc3NfcmVmcyxcblx0XHQpLFxuXHQpO1xuXHRjb25zdCBbc2VydmVyRXJyb3IsIHNldFNlcnZlckVycm9yXSA9IHVzZVN0YXRlPFNlcnZlckVycm9ySW5mbyB8IG51bGw+KG51bGwpO1xuXG5cdGNvbnN0IGxvY2F0aW9uID0gdXNlTG9jYXRpb24oKTtcblx0Y29uc3QgcGFyYW1zID0gdXNlUGFyYW1zKCk7XG5cblx0Ly8gYmlvbWUtaWdub3JlIGxpbnQvY29ycmVjdG5lc3MvdXNlRXhoYXVzdGl2ZURlcGVuZGVuY2llczogdXNpbmcgaGFja3kgZGVlcCBlcXVhbGl0eSBmb3IgcGFyYW1zXG5cdGNvbnN0IHJvdXRlSW5mbyA9IHVzZU1lbW8oKCkgPT4ge1xuXHRcdGNvbnN0IHsgXCIqXCI6IGNhdGNoYWxsID0gXCJcIiwgLi4ucGF0aFBhcmFtcyB9ID0gcGFyYW1zO1xuXHRcdGNvbnN0IHF1ZXJ5UGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyhsb2NhdGlvbi5zZWFyY2gpO1xuXHRcdHJldHVybiB7XG5cdFx0XHRoYXNoOiBsb2NhdGlvbi5oYXNoLFxuXHRcdFx0cGF0aG5hbWU6IGxvY2F0aW9uLnBhdGhuYW1lLFxuXHRcdFx0cXVlcnk6IGxvY2F0aW9uLnNlYXJjaCxcblx0XHRcdHF1ZXJ5UGFyYW1zOiBPYmplY3QuZnJvbUVudHJpZXMocXVlcnlQYXJhbXMuZW50cmllcygpKSxcblx0XHRcdHBhdGhQYXJhbXMsXG5cdFx0XHRjYXRjaGFsbDogY2F0Y2hhbGwubGVuZ3RoID4gMCA/IGNhdGNoYWxsLnNwbGl0KFwiL1wiKSA6IFtdLFxuXHRcdH0gc2F0aXNmaWVzIFJvdXRlSW5mbztcblx0fSwgW2xvY2F0aW9uLmhhc2gsIGxvY2F0aW9uLnBhdGhuYW1lLCBsb2NhdGlvbi5zZWFyY2gsIEpTT04uc3RyaW5naWZ5KHBhcmFtcyldKTtcblxuXHR1c2VFZmZlY3QoKCkgPT4ge1xuXHRcdGlmIChpbkJyb3dzZXIpIHtcblx0XHRcdGNsaWVudC5tb3VudFZpZXcocGF0aCwge1xuXHRcdFx0XHRyb3V0ZUluZm8sXG5cdFx0XHRcdG9uSW5pdDogKHZkb20sIGNhbGxiYWNrcywgcmVuZGVyUHJvcHMsIGNzc1JlZnMpID0+IHtcblx0XHRcdFx0XHRzZXRUcmVlKHJlbmRlcmVyLmluaXQodmRvbSwgY2FsbGJhY2tzLCByZW5kZXJQcm9wcywgY3NzUmVmcykpO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRvblVwZGF0ZTogKG9wcykgPT4ge1xuXHRcdFx0XHRcdHNldFRyZWUoKHByZXYpID0+IChwcmV2ID09IG51bGwgPyBwcmV2IDogcmVuZGVyZXIuYXBwbHlVcGRhdGVzKHByZXYsIG9wcykpKTtcblx0XHRcdFx0fSxcblx0XHRcdH0pO1xuXHRcdFx0Y29uc3Qgb2ZmRXJyID0gY2xpZW50Lm9uU2VydmVyRXJyb3IoKHAsIGVycikgPT4ge1xuXHRcdFx0XHRpZiAocCA9PT0gcGF0aCkgc2V0U2VydmVyRXJyb3IoZXJyKTtcblx0XHRcdH0pO1xuXHRcdFx0cmV0dXJuICgpID0+IHtcblx0XHRcdFx0b2ZmRXJyKCk7XG5cdFx0XHRcdGNsaWVudC51bm1vdW50KHBhdGgpO1xuXHRcdFx0fTtcblx0XHR9XG5cdFx0Ly8gcm91dGVJbmZvIGlzIE5PVCBpbmNsdWRlZCBoZXJlIG9uIHB1cnBvc2Vcblx0fSwgW2NsaWVudCwgcmVuZGVyZXIsIHBhdGgsIHJvdXRlSW5mb10pO1xuXG5cdHVzZUVmZmVjdCgoKSA9PiB7XG5cdFx0aWYgKGluQnJvd3Nlcikge1xuXHRcdFx0Y2xpZW50Lm5hdmlnYXRlKHBhdGgsIHJvdXRlSW5mbyk7XG5cdFx0fVxuXHR9LCBbY2xpZW50LCBwYXRoLCByb3V0ZUluZm9dKTtcblxuXHRpZiAoc2VydmVyRXJyb3IpIHtcblx0XHRyZXR1cm4gPFNlcnZlckVycm9yIGVycm9yPXtzZXJ2ZXJFcnJvcn0gLz47XG5cdH1cblxuXHRyZXR1cm4gdHJlZTtcbn1cblxuZnVuY3Rpb24gU2VydmVyRXJyb3IoeyBlcnJvciB9OiB7IGVycm9yOiBTZXJ2ZXJFcnJvckluZm8gfSkge1xuXHRyZXR1cm4gKFxuXHRcdDxkaXZcblx0XHRcdHN0eWxlPXt7XG5cdFx0XHRcdHBhZGRpbmc6IDE2LFxuXHRcdFx0XHRib3JkZXI6IFwiMXB4IHNvbGlkICNlMDBcIixcblx0XHRcdFx0YmFja2dyb3VuZDogXCIjZmZmNWY1XCIsXG5cdFx0XHRcdGNvbG9yOiBcIiM5MDBcIixcblx0XHRcdFx0Zm9udEZhbWlseTpcblx0XHRcdFx0XHQndWktbW9ub3NwYWNlLCBTRk1vbm8tUmVndWxhciwgTWVubG8sIE1vbmFjbywgQ29uc29sYXMsIFwiTGliZXJhdGlvbiBNb25vXCIsIFwiQ291cmllciBOZXdcIiwgbW9ub3NwYWNlJyxcblx0XHRcdFx0d2hpdGVTcGFjZTogXCJwcmUtd3JhcFwiLFxuXHRcdFx0fX1cblx0XHQ+XG5cdFx0XHQ8ZGl2IHN0eWxlPXt7IGZvbnRXZWlnaHQ6IDcwMCwgbWFyZ2luQm90dG9tOiA4IH19PlNlcnZlciBFcnJvciBkdXJpbmcge2Vycm9yLnBoYXNlfTwvZGl2PlxuXHRcdFx0e2Vycm9yLm1lc3NhZ2UgJiYgPGRpdj57ZXJyb3IubWVzc2FnZX08L2Rpdj59XG5cdFx0XHR7ZXJyb3Iuc3RhY2sgJiYgKFxuXHRcdFx0XHQ8ZGV0YWlscyBvcGVuIHN0eWxlPXt7IG1hcmdpblRvcDogOCB9fT5cblx0XHRcdFx0XHQ8c3VtbWFyeT5TdGFjayB0cmFjZTwvc3VtbWFyeT5cblx0XHRcdFx0XHQ8cHJlIHN0eWxlPXt7IG1hcmdpbjogMCB9fT57ZXJyb3Iuc3RhY2t9PC9wcmU+XG5cdFx0XHRcdDwvZGV0YWlscz5cblx0XHRcdCl9XG5cdFx0PC9kaXY+XG5cdCk7XG59XG4iLAogICAgImltcG9ydCB0eXBlIHsgTmF2aWdhdGVGdW5jdGlvbiB9IGZyb20gXCJyZWFjdC1yb3V0ZXJcIjtcbmltcG9ydCB7IGlvLCB0eXBlIFNvY2tldCB9IGZyb20gXCJzb2NrZXQuaW8tY2xpZW50XCI7XG5pbXBvcnQgdHlwZSB7IENoYW5uZWxCcmlkZ2UgfSBmcm9tIFwiLi9jaGFubmVsXCI7XG5pbXBvcnQgeyBjcmVhdGVDaGFubmVsQnJpZGdlLCBQdWxzZUNoYW5uZWxSZXNldEVycm9yIH0gZnJvbSBcIi4vY2hhbm5lbFwiO1xuaW1wb3J0IHR5cGUgeyBSb3V0ZUluZm8gfSBmcm9tIFwiLi9oZWxwZXJzXCI7XG5pbXBvcnQgdHlwZSB7XG5cdENsaWVudEFwaVJlc3VsdE1lc3NhZ2UsXG5cdENsaWVudE1lc3NhZ2UsXG5cdFNlcnZlckFwaUNhbGxNZXNzYWdlLFxuXHRTZXJ2ZXJDaGFubmVsTWVzc2FnZSxcblx0U2VydmVyRXJyb3JJbmZvLFxuXHRTZXJ2ZXJNZXNzYWdlLFxufSBmcm9tIFwiLi9tZXNzYWdlc1wiO1xuaW1wb3J0IHsgZXh0cmFjdEV2ZW50IH0gZnJvbSBcIi4vc2VyaWFsaXplL2V2ZW50c1wiO1xuaW1wb3J0IHsgZGVzZXJpYWxpemUsIHNlcmlhbGl6ZSB9IGZyb20gXCIuL3NlcmlhbGl6ZS9zZXJpYWxpemVyXCI7XG5pbXBvcnQgdHlwZSB7IFZET00sIFZET01VcGRhdGUgfSBmcm9tIFwiLi92ZG9tXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTW91bnRlZFZpZXcge1xuXHRyb3V0ZUluZm86IFJvdXRlSW5mbztcblx0b25Jbml0OiAodmRvbTogVkRPTSwgY2FsbGJhY2tzOiBzdHJpbmdbXSwgcmVuZGVyUHJvcHM6IHN0cmluZ1tdLCBjc3NSZWZzOiBzdHJpbmdbXSkgPT4gdm9pZDtcblx0b25VcGRhdGU6IChvcHM6IFZET01VcGRhdGVbXSkgPT4gdm9pZDtcbn1cbmV4cG9ydCB0eXBlIENvbm5lY3Rpb25TdGF0dXNMaXN0ZW5lciA9IChjb25uZWN0ZWQ6IGJvb2xlYW4pID0+IHZvaWQ7XG5leHBvcnQgdHlwZSBTZXJ2ZXJFcnJvckxpc3RlbmVyID0gKHBhdGg6IHN0cmluZywgZXJyb3I6IFNlcnZlckVycm9ySW5mbyB8IG51bGwpID0+IHZvaWQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHVsc2VDbGllbnQge1xuXHQvLyBDb25uZWN0aW9uIG1hbmFnZW1lbnRcblx0Y29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+O1xuXHRkaXNjb25uZWN0KCk6IHZvaWQ7XG5cdGlzQ29ubmVjdGVkKCk6IGJvb2xlYW47XG5cdG9uQ29ubmVjdGlvbkNoYW5nZShsaXN0ZW5lcjogQ29ubmVjdGlvblN0YXR1c0xpc3RlbmVyKTogKCkgPT4gdm9pZDtcblx0Ly8gTWVzc2FnZXNcblx0bmF2aWdhdGUocGF0aDogc3RyaW5nLCByb3V0ZUluZm86IFJvdXRlSW5mbyk6IFByb21pc2U8dm9pZD47XG5cdGxlYXZlKHBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG5cdGludm9rZUNhbGxiYWNrKHBhdGg6IHN0cmluZywgY2FsbGJhY2s6IHN0cmluZywgYXJnczogYW55W10pOiBQcm9taXNlPHZvaWQ+O1xuXHQvLyBWRE9NIHN1YnNjcmlwdGlvblxuXHRtb3VudFZpZXcocGF0aDogc3RyaW5nLCB2aWV3OiBNb3VudGVkVmlldyk6ICgpID0+IHZvaWQ7XG59XG5cbmV4cG9ydCBjbGFzcyBQdWxzZVNvY2tldElPQ2xpZW50IHtcblx0I2FjdGl2ZVZpZXdzOiBNYXA8c3RyaW5nLCBNb3VudGVkVmlldz47XG5cdCNzb2NrZXQ6IFNvY2tldCB8IG51bGwgPSBudWxsO1xuXHQjbWVzc2FnZVF1ZXVlOiBDbGllbnRNZXNzYWdlW107XG5cdCNjb25uZWN0aW9uTGlzdGVuZXJzOiBTZXQ8Q29ubmVjdGlvblN0YXR1c0xpc3RlbmVyPiA9IG5ldyBTZXQoKTtcblx0I3NlcnZlckVycm9yczogTWFwPHN0cmluZywgU2VydmVyRXJyb3JJbmZvPiA9IG5ldyBNYXAoKTtcblx0I3NlcnZlckVycm9yTGlzdGVuZXJzOiBTZXQ8U2VydmVyRXJyb3JMaXN0ZW5lcj4gPSBuZXcgU2V0KCk7XG5cdCNjaGFubmVsczogTWFwPHN0cmluZywgeyBicmlkZ2U6IENoYW5uZWxCcmlkZ2U7IHJlZkNvdW50OiBudW1iZXIgfT4gPSBuZXcgTWFwKCk7XG5cdCN1cmw6IHN0cmluZztcblx0I3JlbmRlcklkOiBzdHJpbmc7XG5cdCNmcmFtZXdvcmtOYXZpZ2F0ZTogTmF2aWdhdGVGdW5jdGlvbjtcblxuXHRjb25zdHJ1Y3Rvcih1cmw6IHN0cmluZywgcmVuZGVySWQ6IHN0cmluZywgZnJhbWV3b3JrTmF2aWdhdGU6IE5hdmlnYXRlRnVuY3Rpb24pIHtcblx0XHR0aGlzLiN1cmwgPSB1cmw7XG5cdFx0dGhpcy4jcmVuZGVySWQgPSByZW5kZXJJZDtcblx0XHR0aGlzLiNmcmFtZXdvcmtOYXZpZ2F0ZSA9IGZyYW1ld29ya05hdmlnYXRlO1xuXHRcdHRoaXMuI3NvY2tldCA9IG51bGw7XG5cdFx0dGhpcy4jYWN0aXZlVmlld3MgPSBuZXcgTWFwKCk7XG5cdFx0dGhpcy4jbWVzc2FnZVF1ZXVlID0gW107XG5cdH1cblx0cHVibGljIGlzQ29ubmVjdGVkKCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiB0aGlzLiNzb2NrZXQ/LmNvbm5lY3RlZCA/PyBmYWxzZTtcblx0fVxuXG5cdHB1YmxpYyBhc3luYyBjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGlmICh0aGlzLiNzb2NrZXQpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0XHRcdGNvbnN0IHNvY2tldCA9IGlvKHRoaXMuI3VybCwge1xuXHRcdFx0XHR0cmFuc3BvcnRzOiBbXCJ3ZWJzb2NrZXRcIiwgXCJ3ZWJ0cmFuc3BvcnRcIl0sXG5cdFx0XHRcdGF1dGg6IHsgcmVuZGVySWQ6IHRoaXMuI3JlbmRlcklkIH0sXG5cdFx0XHR9KTtcblx0XHRcdHRoaXMuI3NvY2tldCA9IHNvY2tldDtcblxuXHRcdFx0c29ja2V0Lm9uKFwiY29ubmVjdFwiLCAoKSA9PiB7XG5cdFx0XHRcdGNvbnNvbGUubG9nKFwiW1NvY2tldElPVHJhbnNwb3J0XSBDb25uZWN0ZWQ6XCIsIHRoaXMuI3NvY2tldD8uaWQpO1xuXHRcdFx0XHQvLyBNYWtlIHN1cmUgdG8gc2VuZCBhIG5hdmlnYXRlIHBheWxvYWQgZm9yIGFsbCB0aGUgcm91dGVzXG5cdFx0XHRcdGZvciAoY29uc3QgW3BhdGgsIHJvdXRlXSBvZiB0aGlzLiNhY3RpdmVWaWV3cykge1xuXHRcdFx0XHRcdHNvY2tldC5lbWl0KFxuXHRcdFx0XHRcdFx0XCJtZXNzYWdlXCIsXG5cdFx0XHRcdFx0XHRzZXJpYWxpemUoe1xuXHRcdFx0XHRcdFx0XHR0eXBlOiBcIm1vdW50XCIsXG5cdFx0XHRcdFx0XHRcdHBhdGg6IHBhdGgsXG5cdFx0XHRcdFx0XHRcdHJvdXRlSW5mbzogcm91dGUucm91dGVJbmZvLFxuXHRcdFx0XHRcdFx0fSksXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGZvciAoY29uc3QgcGF5bG9hZCBvZiB0aGlzLiNtZXNzYWdlUXVldWUpIHtcblx0XHRcdFx0XHQvLyBBbHJlYWR5IHNlbnQgYWJvdmVcblx0XHRcdFx0XHRpZiAocGF5bG9hZC50eXBlID09PSBcIm1vdW50XCIgJiYgdGhpcy4jYWN0aXZlVmlld3MuaGFzKHBheWxvYWQucGF0aCkpIHtcblx0XHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHQvLyBXZSdyZSByZW1vdW50aW5nIGFsbCB0aGUgcm91dGVzLCBzbyBubyBuZWVkIHRvIG5hdmlnYXRlXG5cdFx0XHRcdFx0aWYgKHBheWxvYWQudHlwZSA9PT0gXCJuYXZpZ2F0ZVwiKSB7XG5cdFx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0c29ja2V0LmVtaXQoXCJtZXNzYWdlXCIsIHNlcmlhbGl6ZShwYXlsb2FkKSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy4jbWVzc2FnZVF1ZXVlID0gW107XG5cblx0XHRcdFx0dGhpcy5ub3RpZnlDb25uZWN0aW9uTGlzdGVuZXJzKHRydWUpO1xuXHRcdFx0XHRyZXNvbHZlKCk7XG5cdFx0XHR9KTtcblxuXHRcdFx0c29ja2V0Lm9uKFwiY29ubmVjdF9lcnJvclwiLCAoZXJyKSA9PiB7XG5cdFx0XHRcdGNvbnNvbGUuZXJyb3IoXCJbU29ja2V0SU9UcmFuc3BvcnRdIENvbm5lY3Rpb24gZmFpbGVkOlwiLCBlcnIpO1xuXHRcdFx0XHR0aGlzLm5vdGlmeUNvbm5lY3Rpb25MaXN0ZW5lcnMoZmFsc2UpO1xuXHRcdFx0XHRyZWplY3QoZXJyKTtcblx0XHRcdH0pO1xuXG5cdFx0XHRzb2NrZXQub24oXCJkaXNjb25uZWN0XCIsICgpID0+IHtcblx0XHRcdFx0Y29uc29sZS5sb2coXCJbU29ja2V0SU9UcmFuc3BvcnRdIERpc2Nvbm5lY3RlZFwiKTtcblx0XHRcdFx0dGhpcy4jaGFuZGxlVHJhbnNwb3J0RGlzY29ubmVjdCgpO1xuXHRcdFx0XHR0aGlzLm5vdGlmeUNvbm5lY3Rpb25MaXN0ZW5lcnMoZmFsc2UpO1xuXHRcdFx0fSk7XG5cblx0XHRcdC8vIFdyYXAgaW4gYW4gYXJyb3cgZnVuY3Rpb24gdG8gYXZvaWQgbG9zaW5nIHRoZSBgdGhpc2AgcmVmZXJlbmNlXG5cdFx0XHRzb2NrZXQub24oXCJtZXNzYWdlXCIsIChkYXRhKSA9PlxuXHRcdFx0XHR0aGlzLiNoYW5kbGVTZXJ2ZXJNZXNzYWdlKGRlc2VyaWFsaXplKGRhdGEsIHsgY29lcmNlTnVsbHNUb1VuZGVmaW5lZDogdHJ1ZSB9KSksXG5cdFx0XHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0b25Db25uZWN0aW9uQ2hhbmdlKGxpc3RlbmVyOiBDb25uZWN0aW9uU3RhdHVzTGlzdGVuZXIpOiAoKSA9PiB2b2lkIHtcblx0XHR0aGlzLiNjb25uZWN0aW9uTGlzdGVuZXJzLmFkZChsaXN0ZW5lcik7XG5cdFx0bGlzdGVuZXIodGhpcy5pc0Nvbm5lY3RlZCgpKTtcblx0XHRyZXR1cm4gKCkgPT4ge1xuXHRcdFx0dGhpcy4jY29ubmVjdGlvbkxpc3RlbmVycy5kZWxldGUobGlzdGVuZXIpO1xuXHRcdH07XG5cdH1cblxuXHRwcml2YXRlIG5vdGlmeUNvbm5lY3Rpb25MaXN0ZW5lcnMoY29ubmVjdGVkOiBib29sZWFuKTogdm9pZCB7XG5cdFx0Zm9yIChjb25zdCBsaXN0ZW5lciBvZiB0aGlzLiNjb25uZWN0aW9uTGlzdGVuZXJzKSB7XG5cdFx0XHRsaXN0ZW5lcihjb25uZWN0ZWQpO1xuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBvblNlcnZlckVycm9yKGxpc3RlbmVyOiBTZXJ2ZXJFcnJvckxpc3RlbmVyKTogKCkgPT4gdm9pZCB7XG5cdFx0dGhpcy4jc2VydmVyRXJyb3JMaXN0ZW5lcnMuYWRkKGxpc3RlbmVyKTtcblx0XHQvLyBFbWl0IGN1cnJlbnQgZXJyb3JzIHRvIG5ldyBsaXN0ZW5lclxuXHRcdGZvciAoY29uc3QgW3BhdGgsIGVycl0gb2YgdGhpcy4jc2VydmVyRXJyb3JzKSBsaXN0ZW5lcihwYXRoLCBlcnIpO1xuXHRcdHJldHVybiAoKSA9PiB7XG5cdFx0XHR0aGlzLiNzZXJ2ZXJFcnJvckxpc3RlbmVycy5kZWxldGUobGlzdGVuZXIpO1xuXHRcdH07XG5cdH1cblxuXHRwcml2YXRlIG5vdGlmeVNlcnZlckVycm9yKHBhdGg6IHN0cmluZywgZXJyb3I6IFNlcnZlckVycm9ySW5mbyB8IG51bGwpIHtcblx0XHRmb3IgKGNvbnN0IGxpc3RlbmVyIG9mIHRoaXMuI3NlcnZlckVycm9yTGlzdGVuZXJzKSBsaXN0ZW5lcihwYXRoLCBlcnJvcik7XG5cdH1cblxuXHRwdWJsaWMgc2VuZE1lc3NhZ2UocGF5bG9hZDogQ2xpZW50TWVzc2FnZSkge1xuXHRcdGlmICh0aGlzLmlzQ29ubmVjdGVkKCkpIHtcblx0XHRcdC8vIGNvbnNvbGUubG9nKFwiW1NvY2tldElPVHJhbnNwb3J0XSBTZW5kaW5nOlwiLCBwYXlsb2FkKTtcblx0XHRcdHRoaXMuI3NvY2tldCEuZW1pdChcIm1lc3NhZ2VcIiwgc2VyaWFsaXplKHBheWxvYWQgYXMgYW55KSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIGNvbnNvbGUubG9nKFwiW1NvY2tldElPVHJhbnNwb3J0XSBRdWV1aW5nIG1lc3NhZ2U6XCIsIHBheWxvYWQpO1xuXHRcdFx0dGhpcy4jbWVzc2FnZVF1ZXVlLnB1c2gocGF5bG9hZCk7XG5cdFx0fVxuXHR9XG5cblx0cHVibGljIG1vdW50VmlldyhwYXRoOiBzdHJpbmcsIHZpZXc6IE1vdW50ZWRWaWV3KSB7XG5cdFx0aWYgKHRoaXMuI2FjdGl2ZVZpZXdzLmhhcyhwYXRoKSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKGBQYXRoICR7cGF0aH0gaXMgYWxyZWFkeSBtb3VudGVkYCk7XG5cdFx0fVxuXHRcdHRoaXMuI2FjdGl2ZVZpZXdzLnNldChwYXRoLCB2aWV3KTtcblx0XHR2b2lkIHRoaXMuc2VuZE1lc3NhZ2Uoe1xuXHRcdFx0dHlwZTogXCJtb3VudFwiLFxuXHRcdFx0cGF0aCxcblx0XHRcdHJvdXRlSW5mbzogdmlldy5yb3V0ZUluZm8sXG5cdFx0fSk7XG5cdH1cblxuXHRwdWJsaWMgYXN5bmMgbmF2aWdhdGUocGF0aDogc3RyaW5nLCByb3V0ZUluZm86IFJvdXRlSW5mbykge1xuXHRcdGF3YWl0IHRoaXMuc2VuZE1lc3NhZ2Uoe1xuXHRcdFx0dHlwZTogXCJuYXZpZ2F0ZVwiLFxuXHRcdFx0cGF0aCxcblx0XHRcdHJvdXRlSW5mbyxcblx0XHR9KTtcblx0fVxuXG5cdHB1YmxpYyB1bm1vdW50KHBhdGg6IHN0cmluZykge1xuXHRcdHZvaWQgdGhpcy5zZW5kTWVzc2FnZSh7IHR5cGU6IFwidW5tb3VudFwiLCBwYXRoIH0pO1xuXHRcdHRoaXMuI2FjdGl2ZVZpZXdzLmRlbGV0ZShwYXRoKTtcblx0fVxuXG5cdHB1YmxpYyBkaXNjb25uZWN0KCkge1xuXHRcdHRoaXMuI3NvY2tldD8uZGlzY29ubmVjdCgpO1xuXHRcdHRoaXMuI3NvY2tldCA9IG51bGw7XG5cdFx0dGhpcy4jbWVzc2FnZVF1ZXVlID0gW107XG5cdFx0dGhpcy4jY29ubmVjdGlvbkxpc3RlbmVycy5jbGVhcigpO1xuXHRcdHRoaXMuI2FjdGl2ZVZpZXdzLmNsZWFyKCk7XG5cdFx0dGhpcy4jc2VydmVyRXJyb3JzLmNsZWFyKCk7XG5cdFx0dGhpcy4jc2VydmVyRXJyb3JMaXN0ZW5lcnMuY2xlYXIoKTtcblx0XHRmb3IgKGNvbnN0IHsgYnJpZGdlIH0gb2YgdGhpcy4jY2hhbm5lbHMudmFsdWVzKCkpIHtcblx0XHRcdGJyaWRnZS5kaXNwb3NlKG5ldyBQdWxzZUNoYW5uZWxSZXNldEVycm9yKFwiQ2xpZW50IGRpc2Nvbm5lY3RlZFwiKSk7XG5cdFx0fVxuXHRcdHRoaXMuI2NoYW5uZWxzLmNsZWFyKCk7XG5cdH1cblxuXHQjaGFuZGxlU2VydmVyTWVzc2FnZShtZXNzYWdlOiBTZXJ2ZXJNZXNzYWdlKSB7XG5cdFx0Ly8gY29uc29sZS5sb2coXCJbUHVsc2VDbGllbnRdIFJlY2VpdmVkIG1lc3NhZ2U6XCIsIG1lc3NhZ2UpO1xuXHRcdHN3aXRjaCAobWVzc2FnZS50eXBlKSB7XG5cdFx0XHRjYXNlIFwidmRvbV9pbml0XCI6IHtcblx0XHRcdFx0Y29uc3Qgcm91dGUgPSB0aGlzLiNhY3RpdmVWaWV3cy5nZXQobWVzc2FnZS5wYXRoKTtcblx0XHRcdFx0Ly8gSWdub3JlIG1lc3NhZ2VzIGZvciBwYXRocyB0aGF0IGFyZSBub3QgbW91bnRlZFxuXHRcdFx0XHRpZiAoIXJvdXRlKSByZXR1cm47XG5cdFx0XHRcdGlmIChyb3V0ZSkge1xuXHRcdFx0XHRcdHJvdXRlLm9uSW5pdChtZXNzYWdlLnZkb20sIG1lc3NhZ2UuY2FsbGJhY2tzLCBtZXNzYWdlLnJlbmRlcl9wcm9wcywgbWVzc2FnZS5jc3NfcmVmcyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Ly8gQ2xlYXIgYW55IHByaW9yIGVycm9yIGZvciB0aGlzIHBhdGggb24gc3VjY2Vzc2Z1bCBpbml0XG5cdFx0XHRcdGlmICh0aGlzLiNzZXJ2ZXJFcnJvcnMuaGFzKG1lc3NhZ2UucGF0aCkpIHtcblx0XHRcdFx0XHR0aGlzLiNzZXJ2ZXJFcnJvcnMuZGVsZXRlKG1lc3NhZ2UucGF0aCk7XG5cdFx0XHRcdFx0dGhpcy5ub3RpZnlTZXJ2ZXJFcnJvcihtZXNzYWdlLnBhdGgsIG51bGwpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0Y2FzZSBcInZkb21fdXBkYXRlXCI6IHtcblx0XHRcdFx0Y29uc3Qgcm91dGUgPSB0aGlzLiNhY3RpdmVWaWV3cy5nZXQobWVzc2FnZS5wYXRoKTtcblx0XHRcdFx0aWYgKCFyb3V0ZSkgcmV0dXJuOyAvLyBOb3QgYW4gYWN0aXZlIHBhdGg7IGRpc2NhcmRcblx0XHRcdFx0cm91dGUub25VcGRhdGUobWVzc2FnZS5vcHMpO1xuXHRcdFx0XHQvLyBDbGVhciBhbnkgcHJpb3IgZXJyb3IgZm9yIHRoaXMgcGF0aCBvbiBzdWNjZXNzZnVsIHVwZGF0ZVxuXHRcdFx0XHRpZiAodGhpcy4jc2VydmVyRXJyb3JzLmhhcyhtZXNzYWdlLnBhdGgpKSB7XG5cdFx0XHRcdFx0dGhpcy4jc2VydmVyRXJyb3JzLmRlbGV0ZShtZXNzYWdlLnBhdGgpO1xuXHRcdFx0XHRcdHRoaXMubm90aWZ5U2VydmVyRXJyb3IobWVzc2FnZS5wYXRoLCBudWxsKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGNhc2UgXCJzZXJ2ZXJfZXJyb3JcIjoge1xuXHRcdFx0XHRpZiAoIXRoaXMuI2FjdGl2ZVZpZXdzLmhhcyhtZXNzYWdlLnBhdGgpKSByZXR1cm47IC8vIGRpc2NhcmQgZm9yIGluYWN0aXZlIHBhdGhzXG5cdFx0XHRcdHRoaXMuI3NlcnZlckVycm9ycy5zZXQobWVzc2FnZS5wYXRoLCBtZXNzYWdlLmVycm9yKTtcblx0XHRcdFx0dGhpcy5ub3RpZnlTZXJ2ZXJFcnJvcihtZXNzYWdlLnBhdGgsIG1lc3NhZ2UuZXJyb3IpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGNhc2UgXCJhcGlfY2FsbFwiOiB7XG5cdFx0XHRcdHZvaWQgdGhpcy4jcGVyZm9ybUFwaUNhbGwobWVzc2FnZSk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0Y2FzZSBcIm5hdmlnYXRlX3RvXCI6IHtcblx0XHRcdFx0Ly8gYG5hdmlnYXRlX3RvYCBpcyBuYXZpZ2F0aW9uYWw7IGFsbG93IHJlZ2FyZGxlc3Mgb2YgYWN0aXZlVmlld3MgbWVtYmVyc2hpcFxuXHRcdFx0XHRjb25zdCByZXBsYWNlID0gISFtZXNzYWdlLnJlcGxhY2U7XG5cdFx0XHRcdGxldCBkZXN0ID0gbWVzc2FnZS5wYXRoIHx8IFwiXCI7XG5cdFx0XHRcdC8vIE5vcm1hbGl6ZSBwcm90b2NvbC1yZWxhdGl2ZSBVUkxzIHRvIGFic29sdXRlXG5cdFx0XHRcdGlmIChkZXN0LnN0YXJ0c1dpdGgoXCIvL1wiKSkgZGVzdCA9IGAke3dpbmRvdy5sb2NhdGlvbi5wcm90b2NvbH0ke2Rlc3R9YDtcblx0XHRcdFx0Y29uc3QgaGFzU2NoZW1lID0gL15bYS16QS1aXVthLXpBLVowLTkrLi1dKjovLnRlc3QoZGVzdCk7XG5cdFx0XHRcdGlmIChoYXNTY2hlbWUpIHtcblx0XHRcdFx0XHRpZiAoZGVzdC5zdGFydHNXaXRoKFwiaHR0cDovL1wiKSB8fCBkZXN0LnN0YXJ0c1dpdGgoXCJodHRwczovL1wiKSkge1xuXHRcdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdFx0Y29uc3QgdXJsID0gbmV3IFVSTChkZXN0KTtcblx0XHRcdFx0XHRcdFx0aWYgKHVybC5vcmlnaW4gPT09IHdpbmRvdy5sb2NhdGlvbi5vcmlnaW4pIHtcblx0XHRcdFx0XHRcdFx0XHRjb25zdCBpbnRlcm5hbCA9IGAke3VybC5wYXRobmFtZX0ke3VybC5zZWFyY2h9JHt1cmwuaGFzaH1gO1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuI2ZyYW1ld29ya05hdmlnYXRlKGludGVybmFsLCB7IHJlcGxhY2UgfSk7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKHJlcGxhY2UpIHdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKGRlc3QpO1xuXHRcdFx0XHRcdFx0XHRcdGVsc2Ugd2luZG93LmxvY2F0aW9uLmFzc2lnbihkZXN0KTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSBjYXRjaCB7XG5cdFx0XHRcdFx0XHRcdGlmIChyZXBsYWNlKSB3aW5kb3cubG9jYXRpb24ucmVwbGFjZShkZXN0KTtcblx0XHRcdFx0XHRcdFx0ZWxzZSB3aW5kb3cubG9jYXRpb24uYXNzaWduKGRlc3QpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHQvLyBtYWlsdG86LCB0ZWw6LCBkYXRhOiwgZXRjLlxuXHRcdFx0XHRcdFx0aWYgKHJlcGxhY2UpIHdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKGRlc3QpO1xuXHRcdFx0XHRcdFx0ZWxzZSB3aW5kb3cubG9jYXRpb24uYXNzaWduKGRlc3QpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQvLyBSZWxhdGl2ZSBvciByb290LXJlbGF0aXZlIHBhdGgg4oaSIFNQQSBuYXZpZ2F0ZVxuXHRcdFx0XHRcdHRoaXMuI2ZyYW1ld29ya05hdmlnYXRlKGRlc3QsIHsgcmVwbGFjZSB9KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGNhc2UgXCJjaGFubmVsX21lc3NhZ2VcIjoge1xuXHRcdFx0XHR0aGlzLiNyb3V0ZUNoYW5uZWxNZXNzYWdlKG1lc3NhZ2UpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGRlZmF1bHQ6IHtcblx0XHRcdFx0Y29uc29sZS5lcnJvcihcIlVuZXhwZWN0ZWQgbWVzc2FnZTpcIiwgbWVzc2FnZSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0YXN5bmMgI3BlcmZvcm1BcGlDYWxsKG1zZzogU2VydmVyQXBpQ2FsbE1lc3NhZ2UpIHtcblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgcmVzID0gYXdhaXQgZmV0Y2gobXNnLnVybCwge1xuXHRcdFx0XHRtZXRob2Q6IG1zZy5tZXRob2QgfHwgXCJHRVRcIixcblx0XHRcdFx0aGVhZGVyczoge1xuXHRcdFx0XHRcdC4uLihtc2cuaGVhZGVycyB8fCB7fSksXG5cdFx0XHRcdFx0Li4uKG1zZy5ib2R5ICE9IG51bGwgJiYgIShcImNvbnRlbnQtdHlwZVwiIGluIChtc2cuaGVhZGVycyB8fCB7fSkpXG5cdFx0XHRcdFx0XHQ/IHsgXCJjb250ZW50LXR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIgfVxuXHRcdFx0XHRcdFx0OiB7fSksXG5cdFx0XHRcdH0sXG5cdFx0XHRcdGJvZHk6XG5cdFx0XHRcdFx0bXNnLmJvZHkgIT0gbnVsbFxuXHRcdFx0XHRcdFx0PyB0eXBlb2YgbXNnLmJvZHkgPT09IFwic3RyaW5nXCJcblx0XHRcdFx0XHRcdFx0PyBtc2cuYm9keVxuXHRcdFx0XHRcdFx0XHQ6IEpTT04uc3RyaW5naWZ5KG1zZy5ib2R5KVxuXHRcdFx0XHRcdFx0OiB1bmRlZmluZWQsXG5cdFx0XHRcdGNyZWRlbnRpYWxzOiBtc2cuY3JlZGVudGlhbHMgfHwgXCJpbmNsdWRlXCIsXG5cdFx0XHR9KTtcblx0XHRcdGNvbnN0IGhlYWRlcnNPYmo6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblx0XHRcdHJlcy5oZWFkZXJzLmZvckVhY2goKHYsIGspID0+IHtcblx0XHRcdFx0aGVhZGVyc09ialtrXSA9IHY7XG5cdFx0XHR9KTtcblx0XHRcdGxldCBib2R5OiBhbnkgPSBudWxsO1xuXHRcdFx0Y29uc3QgY3QgPSByZXMuaGVhZGVycy5nZXQoXCJjb250ZW50LXR5cGVcIikgfHwgXCJcIjtcblx0XHRcdGlmIChjdC5pbmNsdWRlcyhcImFwcGxpY2F0aW9uL2pzb25cIikpIHtcblx0XHRcdFx0Ym9keSA9IGF3YWl0IHJlcy5qc29uKCkuY2F0Y2goKCkgPT4gbnVsbCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRib2R5ID0gYXdhaXQgcmVzLnRleHQoKS5jYXRjaCgoKSA9PiBudWxsKTtcblx0XHRcdH1cblx0XHRcdGNvbnN0IHJlcGx5OiBDbGllbnRBcGlSZXN1bHRNZXNzYWdlID0ge1xuXHRcdFx0XHR0eXBlOiBcImFwaV9yZXN1bHRcIixcblx0XHRcdFx0aWQ6IG1zZy5pZCxcblx0XHRcdFx0b2s6IHJlcy5vayxcblx0XHRcdFx0c3RhdHVzOiByZXMuc3RhdHVzLFxuXHRcdFx0XHRoZWFkZXJzOiBoZWFkZXJzT2JqLFxuXHRcdFx0XHRib2R5LFxuXHRcdFx0fTtcblx0XHRcdHRoaXMuc2VuZE1lc3NhZ2UocmVwbHkpO1xuXHRcdH0gY2F0Y2ggKGVycikge1xuXHRcdFx0Y29uc3QgcmVwbHk6IENsaWVudEFwaVJlc3VsdE1lc3NhZ2UgPSB7XG5cdFx0XHRcdHR5cGU6IFwiYXBpX3Jlc3VsdFwiLFxuXHRcdFx0XHRpZDogbXNnLmlkLFxuXHRcdFx0XHRvazogZmFsc2UsXG5cdFx0XHRcdHN0YXR1czogMCxcblx0XHRcdFx0aGVhZGVyczoge30sXG5cdFx0XHRcdGJvZHk6IHsgZXJyb3I6IFN0cmluZyhlcnIpIH0sXG5cdFx0XHR9O1xuXHRcdFx0dGhpcy5zZW5kTWVzc2FnZShyZXBseSk7XG5cdFx0fVxuXHR9XG5cblx0cHVibGljIGludm9rZUNhbGxiYWNrKHBhdGg6IHN0cmluZywgY2FsbGJhY2s6IHN0cmluZywgYXJnczogYW55W10pIHtcblx0XHR0aGlzLnNlbmRNZXNzYWdlKHtcblx0XHRcdHR5cGU6IFwiY2FsbGJhY2tcIixcblx0XHRcdHBhdGgsXG5cdFx0XHRjYWxsYmFjayxcblx0XHRcdGFyZ3M6IGFyZ3MubWFwKGV4dHJhY3RFdmVudCksXG5cdFx0fSk7XG5cdH1cblxuXHRwdWJsaWMgYWNxdWlyZUNoYW5uZWwoaWQ6IHN0cmluZyk6IENoYW5uZWxCcmlkZ2Uge1xuXHRcdGNvbnN0IGVudHJ5ID0gdGhpcy4jZW5zdXJlQ2hhbm5lbEVudHJ5KGlkKTtcblx0XHRlbnRyeS5yZWZDb3VudCArPSAxO1xuXHRcdHJldHVybiBlbnRyeS5icmlkZ2U7XG5cdH1cblxuXHRwdWJsaWMgcmVsZWFzZUNoYW5uZWwoaWQ6IHN0cmluZyk6IHZvaWQge1xuXHRcdGNvbnN0IGVudHJ5ID0gdGhpcy4jY2hhbm5lbHMuZ2V0KGlkKTtcblx0XHRpZiAoIWVudHJ5KSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGVudHJ5LnJlZkNvdW50ID0gTWF0aC5tYXgoMCwgZW50cnkucmVmQ291bnQgLSAxKTtcblx0XHRpZiAoZW50cnkucmVmQ291bnQgPT09IDApIHtcblx0XHRcdGVudHJ5LmJyaWRnZS5kaXNwb3NlKG5ldyBQdWxzZUNoYW5uZWxSZXNldEVycm9yKFwiQ2hhbm5lbCByZWxlYXNlZFwiKSk7XG5cdFx0XHR0aGlzLiNjaGFubmVscy5kZWxldGUoaWQpO1xuXHRcdH1cblx0fVxuXG5cdCNlbnN1cmVDaGFubmVsRW50cnkoaWQ6IHN0cmluZyk6IHtcblx0XHRicmlkZ2U6IENoYW5uZWxCcmlkZ2U7XG5cdFx0cmVmQ291bnQ6IG51bWJlcjtcblx0fSB7XG5cdFx0bGV0IGVudHJ5ID0gdGhpcy4jY2hhbm5lbHMuZ2V0KGlkKTtcblx0XHRpZiAoIWVudHJ5KSB7XG5cdFx0XHRlbnRyeSA9IHtcblx0XHRcdFx0YnJpZGdlOiBjcmVhdGVDaGFubmVsQnJpZGdlKHRoaXMsIGlkKSxcblx0XHRcdFx0cmVmQ291bnQ6IDAsXG5cdFx0XHR9O1xuXHRcdFx0dGhpcy4jY2hhbm5lbHMuc2V0KGlkLCBlbnRyeSk7XG5cdFx0fVxuXHRcdHJldHVybiBlbnRyeTtcblx0fVxuXG5cdCNyb3V0ZUNoYW5uZWxNZXNzYWdlKG1lc3NhZ2U6IFNlcnZlckNoYW5uZWxNZXNzYWdlKTogdm9pZCB7XG5cdFx0Y29uc3QgZW50cnkgPSB0aGlzLiNlbnN1cmVDaGFubmVsRW50cnkobWVzc2FnZS5jaGFubmVsKTtcblx0XHRjb25zdCBjbG9zZWQgPSBlbnRyeS5icmlkZ2UuaGFuZGxlU2VydmVyTWVzc2FnZShtZXNzYWdlKTtcblx0XHRpZiAoY2xvc2VkICYmIGVudHJ5LnJlZkNvdW50ID09PSAwKSB7XG5cdFx0XHR0aGlzLiNjaGFubmVscy5kZWxldGUobWVzc2FnZS5jaGFubmVsKTtcblx0XHR9XG5cdH1cblxuXHQjaGFuZGxlVHJhbnNwb3J0RGlzY29ubmVjdCgpOiB2b2lkIHtcblx0XHRmb3IgKGNvbnN0IGVudHJ5IG9mIHRoaXMuI2NoYW5uZWxzLnZhbHVlcygpKSB7XG5cdFx0XHRlbnRyeS5icmlkZ2UuaGFuZGxlRGlzY29ubmVjdChuZXcgUHVsc2VDaGFubmVsUmVzZXRFcnJvcihcIkNvbm5lY3Rpb24gbG9zdFwiKSk7XG5cdFx0fVxuXHR9XG59XG4iLAogICAgInR5cGUgU2ltcGxpZnk8VD4gPSB7IFtLIGluIGtleW9mIFRdOiBUW0tdIH0gJiB7fTtcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUV4dHJhY3RvcjxUIGV4dGVuZHMgb2JqZWN0PigpIHtcblx0ZnVuY3Rpb24gX2NyZWF0ZUV4dHJhY3Rvcjxcblx0XHRjb25zdCBLIGV4dGVuZHMgcmVhZG9ubHkgKGtleW9mIFQpW10sXG5cdFx0QyBleHRlbmRzIFBhcnRpYWw8UmVjb3JkPEtbbnVtYmVyXSB8IHN0cmluZywgKHNyYzogVCkgPT4gYW55Pj4sXG5cdD4oa2V5czogSywgY29tcHV0ZWQ/OiBDKSB7XG5cdFx0cmV0dXJuIChcblx0XHRcdHNyYzogVCxcblx0XHQpOiBTaW1wbGlmeTxcblx0XHRcdFBpY2s8VCwgS1tudW1iZXJdPiAmIHtcblx0XHRcdFx0W1AgaW4ga2V5b2YgQ10tPzogQ1tQXSBleHRlbmRzICguLi5hcmdzOiBhbnkpID0+IGluZmVyIFIgPyBSIDogbmV2ZXI7XG5cdFx0XHR9XG5cdFx0PiA9PiB7XG5cdFx0XHRjb25zdCBvdXQ6IGFueSA9IHt9O1xuXHRcdFx0Zm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuXHRcdFx0XHRvdXRba2V5IGFzIHN0cmluZ10gPSAoc3JjIGFzIGFueSlba2V5IGFzIHN0cmluZ107XG5cdFx0XHR9XG5cdFx0XHRpZiAoY29tcHV0ZWQpIHtcblx0XHRcdFx0Zm9yIChjb25zdCBrZXkgaW4gY29tcHV0ZWQpIHtcblx0XHRcdFx0XHRjb25zdCBmbiA9IGNvbXB1dGVkW2tleV0hO1xuXHRcdFx0XHRcdG91dFtrZXldID0gZm4oc3JjKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG91dDtcblx0XHR9O1xuXHR9XG5cdHJldHVybiBfY3JlYXRlRXh0cmFjdG9yO1xufVxuIiwKICAgICJpbXBvcnQgeyBjcmVhdGVFeHRyYWN0b3IgfSBmcm9tIFwiLi9leHRyYWN0b3JcIjtcblxuLy8gQmFzZSBleHRyYWN0b3JzIChjYW1lbENhc2UpIHNpbWlsYXIgdG8gZXZlbnRzLnRzIHN0eWxlXG5jb25zdCBsb3dlclRhZ05hbWUgPSAoZTogRWxlbWVudCkgPT4gZS50YWdOYW1lLnRvTG93ZXJDYXNlKCk7XG5cbmNvbnN0IEVMRU1FTlRfS0VZUyA9IFtcblx0XCJpZFwiLFxuXHRcImNsYXNzTmFtZVwiLFxuXHRcInRhZ05hbWVcIixcblx0XCJsb2NhbE5hbWVcIixcblx0XCJjbGllbnRIZWlnaHRcIixcblx0XCJjbGllbnRMZWZ0XCIsXG5cdFwiY2xpZW50VG9wXCIsXG5cdFwiY2xpZW50V2lkdGhcIixcblx0XCJzY3JvbGxIZWlnaHRcIixcblx0XCJzY3JvbGxMZWZ0XCIsXG5cdFwic2Nyb2xsVG9wXCIsXG5cdFwic2Nyb2xsV2lkdGhcIixcblx0XCJzbG90XCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgRWxlbWVudClbXTtcblxuY29uc3QgSFRNTF9PUl9TVkdfS0VZUyA9IFtcblx0XCJhdXRvZm9jdXNcIixcblx0XCJ0YWJJbmRleFwiLFxuXHRcIm5vbmNlXCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTE9yU1ZHRWxlbWVudClbXTtcblxuY29uc3QgSFRNTF9FTEVNRU5UX0JBU0VfS0VZUyA9IFtcblx0XCJhY2Nlc3NLZXlcIixcblx0XCJhY2Nlc3NLZXlMYWJlbFwiLFxuXHRcImF1dG9jYXBpdGFsaXplXCIsXG5cdFwiZGlyXCIsXG5cdFwiZHJhZ2dhYmxlXCIsXG5cdFwiaGlkZGVuXCIsXG5cdFwiaW5lcnRcIixcblx0XCJsYW5nXCIsXG5cdFwib2Zmc2V0SGVpZ2h0XCIsXG5cdFwib2Zmc2V0TGVmdFwiLFxuXHRcIm9mZnNldFRvcFwiLFxuXHRcIm9mZnNldFdpZHRoXCIsXG5cdFwicG9wb3ZlclwiLFxuXHRcInNwZWxsY2hlY2tcIixcblx0XCJ0aXRsZVwiLFxuXHRcInRyYW5zbGF0ZVwiLFxuXHRcIndyaXRpbmdTdWdnZXN0aW9uc1wiLFxuXHRcImNvbnRlbnRFZGl0YWJsZVwiLFxuXHRcImVudGVyS2V5SGludFwiLFxuXHRcImlzQ29udGVudEVkaXRhYmxlXCIsXG5cdFwiaW5wdXRNb2RlXCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTEVsZW1lbnQpW107XG5cbmNvbnN0IGV4dHJhY3RFbGVtZW50ID0gY3JlYXRlRXh0cmFjdG9yPEVsZW1lbnQ+KCkoRUxFTUVOVF9LRVlTLCB7XG5cdHRhZ05hbWU6IGxvd2VyVGFnTmFtZSxcbn0pO1xuXG5jb25zdCBleHRyYWN0SFRNTE9yU1ZHRWxlbWVudCA9IGNyZWF0ZUV4dHJhY3RvcjxIVE1MT3JTVkdFbGVtZW50PigpKEhUTUxfT1JfU1ZHX0tFWVMpO1xuXG5jb25zdCBleHRyYWN0SFRNTEVsZW1lbnRCYXNlT25seSA9IGNyZWF0ZUV4dHJhY3RvcjxIVE1MRWxlbWVudD4oKShIVE1MX0VMRU1FTlRfQkFTRV9LRVlTKTtcblxuZnVuY3Rpb24gZXh0cmFjdEhUTUxFbGVtZW50QmFzZShlbHQ6IEhUTUxFbGVtZW50KSB7XG5cdHJldHVybiB7XG5cdFx0Li4uZXh0cmFjdEVsZW1lbnQoZWx0KSxcblx0XHQuLi5leHRyYWN0SFRNTE9yU1ZHRWxlbWVudChlbHQgYXMgSFRNTE9yU1ZHRWxlbWVudCksXG5cdFx0Li4uZXh0cmFjdEhUTUxFbGVtZW50QmFzZU9ubHkoZWx0KSxcblx0fTtcbn1cblxuLy8gSGVscGVyIHRvIGNvbXBvc2UgcGVyLWVsZW1lbnQgZXh0cmFjdG9ycyB3aXRoIHRoZSBzaGFyZWQgYmFzZVxuZnVuY3Rpb24gd2l0aEJhc2U8VCBleHRlbmRzIEhUTUxFbGVtZW50Pihcblx0a2V5czogcmVhZG9ubHkgKGtleW9mIFQpW10sXG5cdGNvbXB1dGVkPzogUGFydGlhbDxSZWNvcmQ8c3RyaW5nLCAoc3JjOiBUKSA9PiBhbnk+Pixcbikge1xuXHRjb25zdCBvbmx5ID0gY3JlYXRlRXh0cmFjdG9yPFQ+KCkoa2V5cywgY29tcHV0ZWQgYXMgYW55KTtcblx0cmV0dXJuIChlbHQ6IFQpID0+ICh7IC4uLmV4dHJhY3RIVE1MRWxlbWVudEJhc2UoZWx0KSwgLi4ub25seShlbHQpIH0pO1xufVxuXG5jb25zdCBIVE1MX0FOQ0hPUl9LRVlTID0gW1xuXHRcImhhc2hcIixcblx0XCJob3N0XCIsXG5cdFwiaG9zdG5hbWVcIixcblx0XCJocmVmXCIsXG5cdFwib3JpZ2luXCIsXG5cdFwicGFzc3dvcmRcIixcblx0XCJwYXRobmFtZVwiLFxuXHRcInBvcnRcIixcblx0XCJwcm90b2NvbFwiLFxuXHRcInNlYXJjaFwiLFxuXHRcInRhcmdldFwiLFxuXHRcImRvd25sb2FkXCIsXG5cdFwicmVsXCIsXG5cdFwiaHJlZmxhbmdcIixcblx0XCJ0eXBlXCIsXG5cdFwidXNlcm5hbWVcIixcblx0XCJwaW5nXCIsXG5cdFwicmVmZXJyZXJQb2xpY3lcIixcblx0XCJ0ZXh0XCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTEFuY2hvckVsZW1lbnQpW107XG5jb25zdCBhbmNob3JFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MQW5jaG9yRWxlbWVudD4oSFRNTF9BTkNIT1JfS0VZUyk7XG5cbmNvbnN0IEhUTUxfQVJFQV9LRVlTID0gW1xuXHRcImFsdFwiLFxuXHRcImNvb3Jkc1wiLFxuXHRcImRvd25sb2FkXCIsXG5cdFwiaGFzaFwiLFxuXHRcImhvc3RcIixcblx0XCJob3N0bmFtZVwiLFxuXHRcImhyZWZcIixcblx0XCJvcmlnaW5cIixcblx0XCJwYXNzd29yZFwiLFxuXHRcInBhdGhuYW1lXCIsXG5cdFwicG9ydFwiLFxuXHRcInByb3RvY29sXCIsXG5cdFwicmVsXCIsXG5cdFwic2VhcmNoXCIsXG5cdFwic2hhcGVcIixcblx0XCJ0YXJnZXRcIixcblx0XCJ1c2VybmFtZVwiLFxuXHRcInBpbmdcIixcblx0XCJyZWZlcnJlclBvbGljeVwiLFxuXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxBcmVhRWxlbWVudClbXTtcbmNvbnN0IGFyZWFFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MQXJlYUVsZW1lbnQ+KEhUTUxfQVJFQV9LRVlTKTtcblxuY29uc3QgSFRNTF9NRURJQV9LRVlTID0gW1xuXHRcImF1dG9wbGF5XCIsXG5cdFwiY29udHJvbHNcIixcblx0XCJjcm9zc09yaWdpblwiLFxuXHRcImN1cnJlbnRTcmNcIixcblx0XCJjdXJyZW50VGltZVwiLFxuXHRcImRlZmF1bHRNdXRlZFwiLFxuXHRcImRlZmF1bHRQbGF5YmFja1JhdGVcIixcblx0XCJkdXJhdGlvblwiLFxuXHRcImVuZGVkXCIsXG5cdFwibG9vcFwiLFxuXHRcIm11dGVkXCIsXG5cdFwibmV0d29ya1N0YXRlXCIsXG5cdFwicGF1c2VkXCIsXG5cdFwicGxheWJhY2tSYXRlXCIsXG5cdFwicHJlbG9hZFwiLFxuXHRcInJlYWR5U3RhdGVcIixcblx0XCJzZWVraW5nXCIsXG5cdFwic3JjXCIsXG5cdFwidm9sdW1lXCIsXG5cdFwicHJlc2VydmVzUGl0Y2hcIixcbl0gYXMgY29uc3Qgc2F0aXNmaWVzIHJlYWRvbmx5IChrZXlvZiBIVE1MTWVkaWFFbGVtZW50KVtdO1xuY29uc3QgbWVkaWFFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MTWVkaWFFbGVtZW50PihIVE1MX01FRElBX0tFWVMpO1xuXG5jb25zdCBhdWRpb0V4dHJhY3RvciA9IChlbHQ6IEhUTUxBdWRpb0VsZW1lbnQpID0+IG1lZGlhRXh0cmFjdG9yKGVsdCk7XG5cbmNvbnN0IEhUTUxfQlVUVE9OX0tFWVMgPSBbXG5cdFwiZGlzYWJsZWRcIixcblx0XCJuYW1lXCIsXG5cdFwidHlwZVwiLFxuXHRcInZhbHVlXCIsXG5cdFwiZm9ybUFjdGlvblwiLFxuXHRcImZvcm1FbmN0eXBlXCIsXG5cdFwiZm9ybU1ldGhvZFwiLFxuXHRcImZvcm1Ob1ZhbGlkYXRlXCIsXG5cdFwiZm9ybVRhcmdldFwiLFxuXHRcInBvcG92ZXJUYXJnZXRBY3Rpb25cIixcbl0gYXMgY29uc3Qgc2F0aXNmaWVzIHJlYWRvbmx5IChrZXlvZiBIVE1MQnV0dG9uRWxlbWVudClbXTtcbmNvbnN0IGJ1dHRvbkV4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxCdXR0b25FbGVtZW50PihIVE1MX0JVVFRPTl9LRVlTKTtcblxuY29uc3QgSFRNTF9EQVRBX0tFWVMgPSBbXCJ2YWx1ZVwiXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxEYXRhRWxlbWVudClbXTtcbmNvbnN0IGRhdGFFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MRGF0YUVsZW1lbnQ+KEhUTUxfREFUQV9LRVlTKTtcblxuY29uc3QgSFRNTF9FTUJFRF9LRVlTID0gW1xuXHRcImhlaWdodFwiLFxuXHRcInNyY1wiLFxuXHRcInR5cGVcIixcblx0XCJ3aWR0aFwiLFxuXHRcImFsaWduXCIsXG5cdFwibmFtZVwiLFxuXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxFbWJlZEVsZW1lbnQpW107XG5jb25zdCBlbWJlZEV4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxFbWJlZEVsZW1lbnQ+KEhUTUxfRU1CRURfS0VZUyk7XG5cbmNvbnN0IEhUTUxfRklFTERTRVRfS0VZUyA9IFtcblx0XCJkaXNhYmxlZFwiLFxuXHRcIm5hbWVcIixcblx0XCJ0eXBlXCIsXG5cdFwidmFsaWRhdGlvbk1lc3NhZ2VcIixcblx0XCJ3aWxsVmFsaWRhdGVcIixcbl0gYXMgY29uc3Qgc2F0aXNmaWVzIHJlYWRvbmx5IChrZXlvZiBIVE1MRmllbGRTZXRFbGVtZW50KVtdO1xuY29uc3QgZmllbGRzZXRFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MRmllbGRTZXRFbGVtZW50PihIVE1MX0ZJRUxEU0VUX0tFWVMpO1xuXG5jb25zdCBIVE1MX0ZPUk1fS0VZUyA9IFtcblx0XCJhY2NlcHRDaGFyc2V0XCIsXG5cdFwiYWN0aW9uXCIsXG5cdFwiYXV0b2NvbXBsZXRlXCIsXG5cdFwiZW5jb2RpbmdcIixcblx0XCJlbmN0eXBlXCIsXG5cdFwibGVuZ3RoXCIsXG5cdFwibWV0aG9kXCIsXG5cdFwibmFtZVwiLFxuXHRcIm5vVmFsaWRhdGVcIixcblx0XCJ0YXJnZXRcIixcblx0XCJyZWxcIixcbl0gYXMgY29uc3Qgc2F0aXNmaWVzIHJlYWRvbmx5IChrZXlvZiBIVE1MRm9ybUVsZW1lbnQpW107XG5jb25zdCBmb3JtRXh0cmFjdG9yID0gd2l0aEJhc2U8SFRNTEZvcm1FbGVtZW50PihIVE1MX0ZPUk1fS0VZUyk7XG5cbmNvbnN0IEhUTUxfSUZSQU1FX0tFWVMgPSBbXG5cdFwiYWxsb3dcIixcblx0XCJhbGxvd0Z1bGxzY3JlZW5cIixcblx0XCJoZWlnaHRcIixcblx0XCJuYW1lXCIsXG5cdFwicmVmZXJyZXJQb2xpY3lcIixcblx0XCJzcmNcIixcblx0XCJzcmNkb2NcIixcblx0XCJ3aWR0aFwiLFxuXHRcImFsaWduXCIsXG5cdFwiZnJhbWVCb3JkZXJcIixcblx0XCJsb25nRGVzY1wiLFxuXHRcIm1hcmdpbkhlaWdodFwiLFxuXHRcIm1hcmdpbldpZHRoXCIsXG5cdFwic2Nyb2xsaW5nXCIsXG5cdFwic2FuZGJveFwiLFxuXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxJRnJhbWVFbGVtZW50KVtdO1xuY29uc3QgaWZyYW1lRXh0cmFjdG9yID0gd2l0aEJhc2U8SFRNTElGcmFtZUVsZW1lbnQ+KEhUTUxfSUZSQU1FX0tFWVMpO1xuXG5jb25zdCBIVE1MX0lNQUdFX0tFWVMgPSBbXG5cdFwiYWx0XCIsXG5cdFwiY3Jvc3NPcmlnaW5cIixcblx0XCJkZWNvZGluZ1wiLFxuXHRcImhlaWdodFwiLFxuXHRcImlzTWFwXCIsXG5cdFwibG9hZGluZ1wiLFxuXHRcIm5hdHVyYWxIZWlnaHRcIixcblx0XCJuYXR1cmFsV2lkdGhcIixcblx0XCJyZWZlcnJlclBvbGljeVwiLFxuXHRcInNpemVzXCIsXG5cdFwic3JjXCIsXG5cdFwic3Jjc2V0XCIsXG5cdFwidXNlTWFwXCIsXG5cdFwid2lkdGhcIixcblx0XCJhbGlnblwiLFxuXHRcImJvcmRlclwiLFxuXHRcImNvbXBsZXRlXCIsXG5cdFwiaHNwYWNlXCIsXG5cdFwibG9uZ0Rlc2NcIixcblx0XCJsb3dzcmNcIixcblx0XCJuYW1lXCIsXG5cdFwidnNwYWNlXCIsXG5cdFwieFwiLFxuXHRcInlcIixcblx0XCJmZXRjaFByaW9yaXR5XCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTEltYWdlRWxlbWVudClbXTtcbmNvbnN0IGltYWdlRXh0cmFjdG9yID0gd2l0aEJhc2U8SFRNTEltYWdlRWxlbWVudD4oSFRNTF9JTUFHRV9LRVlTKTtcblxuY29uc3QgSFRNTF9JTlBVVF9LRVlTID0gW1xuXHRcImFjY2VwdFwiLFxuXHRcImFsdFwiLFxuXHRcImF1dG9jb21wbGV0ZVwiLFxuXHRcImNoZWNrZWRcIixcblx0XCJkZWZhdWx0Q2hlY2tlZFwiLFxuXHRcImRlZmF1bHRWYWx1ZVwiLFxuXHRcImRpck5hbWVcIixcblx0XCJkaXNhYmxlZFwiLFxuXHRcImhlaWdodFwiLFxuXHRcImluZGV0ZXJtaW5hdGVcIixcblx0XCJtYXhcIixcblx0XCJtYXhMZW5ndGhcIixcblx0XCJtaW5cIixcblx0XCJtaW5MZW5ndGhcIixcblx0XCJtdWx0aXBsZVwiLFxuXHRcIm5hbWVcIixcblx0XCJwYXR0ZXJuXCIsXG5cdFwicGxhY2Vob2xkZXJcIixcblx0XCJyZWFkT25seVwiLFxuXHRcInJlcXVpcmVkXCIsXG5cdFwic2VsZWN0aW9uRGlyZWN0aW9uXCIsXG5cdFwic2VsZWN0aW9uRW5kXCIsXG5cdFwic2VsZWN0aW9uU3RhcnRcIixcblx0XCJzaXplXCIsXG5cdFwic3JjXCIsXG5cdFwic3RlcFwiLFxuXHRcInR5cGVcIixcblx0XCJ2YWx1ZVwiLFxuXHRcInZhbHVlQXNOdW1iZXJcIixcblx0XCJ3aWR0aFwiLFxuXHRcImFsaWduXCIsXG5cdFwiY2FwdHVyZVwiLFxuXHRcImZvcm1BY3Rpb25cIixcblx0XCJmb3JtRW5jdHlwZVwiLFxuXHRcImZvcm1NZXRob2RcIixcblx0XCJmb3JtTm9WYWxpZGF0ZVwiLFxuXHRcImZvcm1UYXJnZXRcIixcblx0XCJ1c2VNYXBcIixcblx0XCJ2YWxpZGF0aW9uTWVzc2FnZVwiLFxuXHRcIndpbGxWYWxpZGF0ZVwiLFxuXHRcInBvcG92ZXJUYXJnZXRBY3Rpb25cIixcbl0gYXMgY29uc3Qgc2F0aXNmaWVzIHJlYWRvbmx5IChrZXlvZiBIVE1MSW5wdXRFbGVtZW50KVtdO1xuY29uc3QgaW5wdXRFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MSW5wdXRFbGVtZW50PihIVE1MX0lOUFVUX0tFWVMpO1xuXG5jb25zdCBIVE1MX0xBQkVMX0tFWVMgPSBbXCJodG1sRm9yXCJdIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTExhYmVsRWxlbWVudClbXTtcbmNvbnN0IGxhYmVsRXh0cmFjdG9yID0gd2l0aEJhc2U8SFRNTExhYmVsRWxlbWVudD4oSFRNTF9MQUJFTF9LRVlTKTtcblxuY29uc3QgSFRNTF9MSV9LRVlTID0gW1widmFsdWVcIiwgXCJ0eXBlXCJdIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTExJRWxlbWVudClbXTtcbmNvbnN0IGxpRXh0cmFjdG9yID0gd2l0aEJhc2U8SFRNTExJRWxlbWVudD4oSFRNTF9MSV9LRVlTKTtcblxuY29uc3QgSFRNTF9MSU5LX0tFWVMgPSBbXG5cdFwiYXNcIixcblx0XCJjcm9zc09yaWdpblwiLFxuXHRcImRpc2FibGVkXCIsXG5cdFwiZmV0Y2hQcmlvcml0eVwiLFxuXHRcImhyZWZcIixcblx0XCJocmVmbGFuZ1wiLFxuXHRcImltYWdlU2l6ZXNcIixcblx0XCJpbWFnZVNyY3NldFwiLFxuXHRcImludGVncml0eVwiLFxuXHRcIm1lZGlhXCIsXG5cdFwicmVmZXJyZXJQb2xpY3lcIixcblx0XCJyZWxcIixcblx0XCJ0eXBlXCIsXG5cdFwiY2hhcnNldFwiLFxuXHRcInJldlwiLFxuXHRcInRhcmdldFwiLFxuXHRcInNpemVzXCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTExpbmtFbGVtZW50KVtdO1xuY29uc3QgbGlua0V4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxMaW5rRWxlbWVudD4oSFRNTF9MSU5LX0tFWVMpO1xuXG5jb25zdCBIVE1MX01BUF9LRVlTID0gW1wibmFtZVwiXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxNYXBFbGVtZW50KVtdO1xuY29uc3QgbWFwRXh0cmFjdG9yID0gd2l0aEJhc2U8SFRNTE1hcEVsZW1lbnQ+KEhUTUxfTUFQX0tFWVMpO1xuXG5jb25zdCBIVE1MX01FVEVSX0tFWVMgPSBbXG5cdFwiaGlnaFwiLFxuXHRcImxvd1wiLFxuXHRcIm1heFwiLFxuXHRcIm1pblwiLFxuXHRcIm9wdGltdW1cIixcblx0XCJ2YWx1ZVwiLFxuXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxNZXRlckVsZW1lbnQpW107XG5jb25zdCBtZXRlckV4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxNZXRlckVsZW1lbnQ+KEhUTUxfTUVURVJfS0VZUyk7XG5cbmNvbnN0IEhUTUxfTU9EX0tFWVMgPSBbXCJjaXRlXCIsIFwiZGF0ZVRpbWVcIl0gYXMgY29uc3Qgc2F0aXNmaWVzIHJlYWRvbmx5IChrZXlvZiBIVE1MTW9kRWxlbWVudClbXTtcbmNvbnN0IG1vZEV4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxNb2RFbGVtZW50PihIVE1MX01PRF9LRVlTKTtcblxuY29uc3QgSFRNTF9PTF9LRVlTID0gW1xuXHRcInJldmVyc2VkXCIsXG5cdFwic3RhcnRcIixcblx0XCJ0eXBlXCIsXG5cdFwiY29tcGFjdFwiLFxuXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxPTGlzdEVsZW1lbnQpW107XG5jb25zdCBvbGlzdEV4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxPTGlzdEVsZW1lbnQ+KEhUTUxfT0xfS0VZUyk7XG5cbmNvbnN0IEhUTUxfT0JKRUNUX0tFWVMgPSBbXG5cdFwiZGF0YVwiLFxuXHRcImhlaWdodFwiLFxuXHRcIm5hbWVcIixcblx0XCJ0eXBlXCIsXG5cdFwidXNlTWFwXCIsXG5cdFwid2lkdGhcIixcblx0XCJ2YWxpZGF0aW9uTWVzc2FnZVwiLFxuXHRcIndpbGxWYWxpZGF0ZVwiLFxuXHRcImFsaWduXCIsXG5cdFwiYXJjaGl2ZVwiLFxuXHRcImJvcmRlclwiLFxuXHRcImNvZGVcIixcblx0XCJjb2RlQmFzZVwiLFxuXHRcImNvZGVUeXBlXCIsXG5cdFwiZGVjbGFyZVwiLFxuXHRcImhzcGFjZVwiLFxuXHRcInN0YW5kYnlcIixcblx0XCJ2c3BhY2VcIixcbl0gYXMgY29uc3Qgc2F0aXNmaWVzIHJlYWRvbmx5IChrZXlvZiBIVE1MT2JqZWN0RWxlbWVudClbXTtcbmNvbnN0IG9iamVjdEV4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxPYmplY3RFbGVtZW50PihIVE1MX09CSkVDVF9LRVlTKTtcblxuY29uc3QgSFRNTF9PUFRHUk9VUF9LRVlTID0gW1xuXHRcImRpc2FibGVkXCIsXG5cdFwibGFiZWxcIixcbl0gYXMgY29uc3Qgc2F0aXNmaWVzIHJlYWRvbmx5IChrZXlvZiBIVE1MT3B0R3JvdXBFbGVtZW50KVtdO1xuY29uc3Qgb3B0Z3JvdXBFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MT3B0R3JvdXBFbGVtZW50PihIVE1MX09QVEdST1VQX0tFWVMpO1xuXG5jb25zdCBIVE1MX09QVElPTl9LRVlTID0gW1xuXHRcImRlZmF1bHRTZWxlY3RlZFwiLFxuXHRcImRpc2FibGVkXCIsXG5cdFwiaW5kZXhcIixcblx0XCJsYWJlbFwiLFxuXHRcInNlbGVjdGVkXCIsXG5cdFwidGV4dFwiLFxuXHRcInZhbHVlXCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTE9wdGlvbkVsZW1lbnQpW107XG5jb25zdCBvcHRpb25FeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MT3B0aW9uRWxlbWVudD4oSFRNTF9PUFRJT05fS0VZUyk7XG5cbmNvbnN0IEhUTUxfT1VUUFVUX0tFWVMgPSBbXG5cdFwiZGVmYXVsdFZhbHVlXCIsXG5cdFwibmFtZVwiLFxuXHRcInR5cGVcIixcblx0XCJ2YWx1ZVwiLFxuXHRcImh0bWxGb3JcIixcblx0XCJ2YWxpZGF0aW9uTWVzc2FnZVwiLFxuXHRcIndpbGxWYWxpZGF0ZVwiLFxuXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxPdXRwdXRFbGVtZW50KVtdO1xuY29uc3Qgb3V0cHV0RXh0cmFjdG9yID0gd2l0aEJhc2U8SFRNTE91dHB1dEVsZW1lbnQ+KEhUTUxfT1VUUFVUX0tFWVMpO1xuXG5jb25zdCBIVE1MX1BST0dSRVNTX0tFWVMgPSBbXG5cdFwibWF4XCIsXG5cdFwicG9zaXRpb25cIixcblx0XCJ2YWx1ZVwiLFxuXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxQcm9ncmVzc0VsZW1lbnQpW107XG5jb25zdCBwcm9ncmVzc0V4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxQcm9ncmVzc0VsZW1lbnQ+KEhUTUxfUFJPR1JFU1NfS0VZUyk7XG5cbmNvbnN0IEhUTUxfUVVPVEVfS0VZUyA9IFtcImNpdGVcIl0gYXMgY29uc3Qgc2F0aXNmaWVzIHJlYWRvbmx5IChrZXlvZiBIVE1MUXVvdGVFbGVtZW50KVtdO1xuY29uc3QgcXVvdGVFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MUXVvdGVFbGVtZW50PihIVE1MX1FVT1RFX0tFWVMpO1xuXG5jb25zdCBjaXRlRXh0cmFjdG9yID0gKGVsdDogSFRNTEVsZW1lbnQpID0+IGV4dHJhY3RIVE1MRWxlbWVudEJhc2UoZWx0KTtcblxuY29uc3QgSFRNTF9TQ1JJUFRfS0VZUyA9IFtcblx0XCJhc3luY1wiLFxuXHRcImNyb3NzT3JpZ2luXCIsXG5cdFwiZGVmZXJcIixcblx0XCJmZXRjaFByaW9yaXR5XCIsXG5cdFwiaW50ZWdyaXR5XCIsXG5cdFwibm9Nb2R1bGVcIixcblx0XCJyZWZlcnJlclBvbGljeVwiLFxuXHRcInNyY1wiLFxuXHRcInRleHRcIixcblx0XCJ0eXBlXCIsXG5cdFwiY2hhcnNldFwiLFxuXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxTY3JpcHRFbGVtZW50KVtdO1xuY29uc3QgZXh0cmFjdEhUTUxTY3JpcHRPbmx5ID0gY3JlYXRlRXh0cmFjdG9yPEhUTUxTY3JpcHRFbGVtZW50PigpKEhUTUxfU0NSSVBUX0tFWVMsIHtcblx0ZXZlbnQ6IChzKSA9PiAocyBhcyBhbnkpLmV2ZW50LFxuXHRodG1sRm9yOiAocykgPT4gKHMgYXMgYW55KS5odG1sRm9yLFxufSk7XG5jb25zdCBzY3JpcHRFeHRyYWN0b3IgPSAoZWx0OiBIVE1MU2NyaXB0RWxlbWVudCkgPT4gKHtcblx0Li4uZXh0cmFjdEhUTUxFbGVtZW50QmFzZShlbHQpLFxuXHQuLi5leHRyYWN0SFRNTFNjcmlwdE9ubHkoZWx0KSxcbn0pO1xuXG5jb25zdCBIVE1MX1NFTEVDVF9LRVlTID0gW1xuXHRcImF1dG9jb21wbGV0ZVwiLFxuXHRcImRpc2FibGVkXCIsXG5cdFwibGVuZ3RoXCIsXG5cdFwibXVsdGlwbGVcIixcblx0XCJuYW1lXCIsXG5cdFwicmVxdWlyZWRcIixcblx0XCJzZWxlY3RlZEluZGV4XCIsXG5cdFwic2l6ZVwiLFxuXHRcInR5cGVcIixcblx0XCJ2YWx1ZVwiLFxuXHRcInZhbGlkYXRpb25NZXNzYWdlXCIsXG5cdFwid2lsbFZhbGlkYXRlXCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTFNlbGVjdEVsZW1lbnQpW107XG5jb25zdCBzZWxlY3RFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MU2VsZWN0RWxlbWVudD4oSFRNTF9TRUxFQ1RfS0VZUyk7XG5cbmNvbnN0IEhUTUxfU0xPVF9LRVlTID0gW1wibmFtZVwiXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxTbG90RWxlbWVudClbXTtcbmNvbnN0IHNsb3RFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MU2xvdEVsZW1lbnQ+KEhUTUxfU0xPVF9LRVlTKTtcblxuY29uc3QgSFRNTF9TT1VSQ0VfS0VZUyA9IFtcblx0XCJoZWlnaHRcIixcblx0XCJtZWRpYVwiLFxuXHRcInNpemVzXCIsXG5cdFwic3JjXCIsXG5cdFwic3Jjc2V0XCIsXG5cdFwidHlwZVwiLFxuXHRcIndpZHRoXCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTFNvdXJjZUVsZW1lbnQpW107XG5jb25zdCBzb3VyY2VFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MU291cmNlRWxlbWVudD4oSFRNTF9TT1VSQ0VfS0VZUyk7XG5cbmNvbnN0IEhUTUxfVEFCTEVfQ0FQVElPTl9LRVlTID0gW1xuXHRcImFsaWduXCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQpW107XG5jb25zdCB0YWJsZUNhcHRpb25FeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MVGFibGVDYXB0aW9uRWxlbWVudD4oSFRNTF9UQUJMRV9DQVBUSU9OX0tFWVMpO1xuXG5jb25zdCBIVE1MX1RBQkxFX0NFTExfS0VZUyA9IFtcblx0XCJhYmJyXCIsXG5cdFwiY2VsbEluZGV4XCIsXG5cdFwiY29sU3BhblwiLFxuXHRcImhlYWRlcnNcIixcblx0XCJyb3dTcGFuXCIsXG5cdFwic2NvcGVcIixcblx0XCJhbGlnblwiLFxuXHRcImF4aXNcIixcblx0XCJiZ0NvbG9yXCIsXG5cdFwiY2hcIixcblx0XCJjaE9mZlwiLFxuXHRcImhlaWdodFwiLFxuXHRcIm5vV3JhcFwiLFxuXHRcInZBbGlnblwiLFxuXHRcIndpZHRoXCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTFRhYmxlQ2VsbEVsZW1lbnQpW107XG5jb25zdCB0YWJsZUNlbGxFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MVGFibGVDZWxsRWxlbWVudD4oSFRNTF9UQUJMRV9DRUxMX0tFWVMpO1xuXG5jb25zdCBIVE1MX1RBQkxFX0NPTF9LRVlTID0gW1xuXHRcInNwYW5cIixcblx0XCJhbGlnblwiLFxuXHRcImNoXCIsXG5cdFwiY2hPZmZcIixcblx0XCJ2QWxpZ25cIixcblx0XCJ3aWR0aFwiLFxuXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxUYWJsZUNvbEVsZW1lbnQpW107XG5jb25zdCB0YWJsZUNvbEV4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxUYWJsZUNvbEVsZW1lbnQ+KEhUTUxfVEFCTEVfQ09MX0tFWVMpO1xuXG5jb25zdCBIVE1MX1RBQkxFX0tFWVMgPSBbXG5cdFwiYWxpZ25cIixcblx0XCJiZ0NvbG9yXCIsXG5cdFwiYm9yZGVyXCIsXG5cdFwiY2VsbFBhZGRpbmdcIixcblx0XCJjZWxsU3BhY2luZ1wiLFxuXHRcImZyYW1lXCIsXG5cdFwicnVsZXNcIixcblx0XCJzdW1tYXJ5XCIsXG5cdFwid2lkdGhcIixcbl0gYXMgY29uc3Qgc2F0aXNmaWVzIHJlYWRvbmx5IChrZXlvZiBIVE1MVGFibGVFbGVtZW50KVtdO1xuY29uc3QgdGFibGVFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MVGFibGVFbGVtZW50PihIVE1MX1RBQkxFX0tFWVMpO1xuXG5jb25zdCBIVE1MX1RSX0tFWVMgPSBbXG5cdFwicm93SW5kZXhcIixcblx0XCJzZWN0aW9uUm93SW5kZXhcIixcblx0XCJhbGlnblwiLFxuXHRcImJnQ29sb3JcIixcblx0XCJjaFwiLFxuXHRcImNoT2ZmXCIsXG5cdFwidkFsaWduXCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTFRhYmxlUm93RWxlbWVudClbXTtcbmNvbnN0IHRhYmxlUm93RXh0cmFjdG9yID0gd2l0aEJhc2U8SFRNTFRhYmxlUm93RWxlbWVudD4oSFRNTF9UUl9LRVlTKTtcblxuY29uc3QgSFRNTF9UU0VDVElPTl9LRVlTID0gW1xuXHRcImFsaWduXCIsXG5cdFwiY2hcIixcblx0XCJjaE9mZlwiLFxuXHRcInZBbGlnblwiLFxuXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50KVtdO1xuY29uc3QgdGFibGVTZWN0aW9uRXh0cmFjdG9yID0gd2l0aEJhc2U8SFRNTFRhYmxlU2VjdGlvbkVsZW1lbnQ+KEhUTUxfVFNFQ1RJT05fS0VZUyk7XG5cbmNvbnN0IHRlbXBsYXRlRXh0cmFjdG9yID0gKGVsdDogSFRNTFRlbXBsYXRlRWxlbWVudCkgPT4gZXh0cmFjdEhUTUxFbGVtZW50QmFzZShlbHQpO1xuXG5jb25zdCBIVE1MX1RFWFRBUkVBX0tFWVMgPSBbXG5cdFwiYXV0b2NvbXBsZXRlXCIsXG5cdFwiY29sc1wiLFxuXHRcImRlZmF1bHRWYWx1ZVwiLFxuXHRcImRpck5hbWVcIixcblx0XCJkaXNhYmxlZFwiLFxuXHRcIm1heExlbmd0aFwiLFxuXHRcIm1pbkxlbmd0aFwiLFxuXHRcIm5hbWVcIixcblx0XCJwbGFjZWhvbGRlclwiLFxuXHRcInJlYWRPbmx5XCIsXG5cdFwicmVxdWlyZWRcIixcblx0XCJyb3dzXCIsXG5cdFwic2VsZWN0aW9uRGlyZWN0aW9uXCIsXG5cdFwic2VsZWN0aW9uRW5kXCIsXG5cdFwic2VsZWN0aW9uU3RhcnRcIixcblx0XCJ2YWx1ZVwiLFxuXHRcIndyYXBcIixcblx0XCJ0ZXh0TGVuZ3RoXCIsXG5cdFwidmFsaWRhdGlvbk1lc3NhZ2VcIixcblx0XCJ3aWxsVmFsaWRhdGVcIixcbl0gYXMgY29uc3Qgc2F0aXNmaWVzIHJlYWRvbmx5IChrZXlvZiBIVE1MVGV4dEFyZWFFbGVtZW50KVtdO1xuY29uc3QgdGV4dGFyZWFFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MVGV4dEFyZWFFbGVtZW50PihIVE1MX1RFWFRBUkVBX0tFWVMpO1xuXG5jb25zdCBIVE1MX1RJTUVfS0VZUyA9IFtcImRhdGVUaW1lXCJdIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTFRpbWVFbGVtZW50KVtdO1xuY29uc3QgdGltZUV4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxUaW1lRWxlbWVudD4oSFRNTF9USU1FX0tFWVMpO1xuXG5jb25zdCBIVE1MX1RSQUNLX0tFWVMgPSBbXG5cdFwiZGVmYXVsdFwiLFxuXHRcImtpbmRcIixcblx0XCJsYWJlbFwiLFxuXHRcInJlYWR5U3RhdGVcIixcblx0XCJzcmNcIixcblx0XCJzcmNsYW5nXCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTFRyYWNrRWxlbWVudClbXTtcbmNvbnN0IHRyYWNrRXh0cmFjdG9yID0gd2l0aEJhc2U8SFRNTFRyYWNrRWxlbWVudD4oSFRNTF9UUkFDS19LRVlTKTtcblxuY29uc3QgSFRNTF9WSURFT19LRVlTID0gW1xuXHRcImhlaWdodFwiLFxuXHRcInBvc3RlclwiLFxuXHRcInZpZGVvSGVpZ2h0XCIsXG5cdFwidmlkZW9XaWR0aFwiLFxuXHRcIndpZHRoXCIsXG5cdFwicGxheXNJbmxpbmVcIixcbl0gYXMgY29uc3Qgc2F0aXNmaWVzIHJlYWRvbmx5IChrZXlvZiBIVE1MVmlkZW9FbGVtZW50KVtdO1xuY29uc3QgZXh0cmFjdEhUTUxWaWRlb09ubHkgPSBjcmVhdGVFeHRyYWN0b3I8SFRNTFZpZGVvRWxlbWVudD4oKShIVE1MX1ZJREVPX0tFWVMpO1xuY29uc3QgdmlkZW9FeHRyYWN0b3IgPSAoZWx0OiBIVE1MVmlkZW9FbGVtZW50KSA9PiAoe1xuXHQuLi5tZWRpYUV4dHJhY3RvcihlbHQpLFxuXHQuLi5leHRyYWN0SFRNTFZpZGVvT25seShlbHQpLFxufSk7XG5cbmNvbnN0IEhUTUxfQlJfS0VZUyA9IFtcImNsZWFyXCJdIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTEJSRWxlbWVudClbXTtcbmNvbnN0IGJyRXh0cmFjdG9yID0gd2l0aEJhc2U8SFRNTEJSRWxlbWVudD4oSFRNTF9CUl9LRVlTKTtcblxuY29uc3QgSFRNTF9CQVNFX0tFWVMgPSBbXCJocmVmXCIsIFwidGFyZ2V0XCJdIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTEJhc2VFbGVtZW50KVtdO1xuY29uc3QgYmFzZUV4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxCYXNlRWxlbWVudD4oSFRNTF9CQVNFX0tFWVMpO1xuXG5jb25zdCBIVE1MX0JPRFlfS0VZUyA9IFtcblx0XCJhTGlua1wiLFxuXHRcImJhY2tncm91bmRcIixcblx0XCJiZ0NvbG9yXCIsXG5cdFwibGlua1wiLFxuXHRcInRleHRcIixcblx0XCJ2TGlua1wiLFxuXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxCb2R5RWxlbWVudClbXTtcbmNvbnN0IGJvZHlFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MQm9keUVsZW1lbnQ+KEhUTUxfQk9EWV9LRVlTKTtcblxuY29uc3QgSFRNTF9ETElTVF9LRVlTID0gW1wiY29tcGFjdFwiXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxETGlzdEVsZW1lbnQpW107XG5jb25zdCBkbGlzdEV4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxETGlzdEVsZW1lbnQ+KEhUTUxfRExJU1RfS0VZUyk7XG5cbmNvbnN0IEhUTUxfREVUQUlMU19LRVlTID0gW1wib3BlblwiXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxEZXRhaWxzRWxlbWVudClbXTtcbmNvbnN0IGRldGFpbHNFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MRGV0YWlsc0VsZW1lbnQ+KEhUTUxfREVUQUlMU19LRVlTKTtcblxuY29uc3QgSFRNTF9ESUFMT0dfS0VZUyA9IFtcblx0XCJvcGVuXCIsXG5cdFwicmV0dXJuVmFsdWVcIixcbl0gYXMgY29uc3Qgc2F0aXNmaWVzIHJlYWRvbmx5IChrZXlvZiBIVE1MRGlhbG9nRWxlbWVudClbXTtcbmNvbnN0IGRpYWxvZ0V4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxEaWFsb2dFbGVtZW50PihIVE1MX0RJQUxPR19LRVlTKTtcblxuY29uc3QgSFRNTF9ESVZfS0VZUyA9IFtcImFsaWduXCJdIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTERpdkVsZW1lbnQpW107XG5jb25zdCBkaXZFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MRGl2RWxlbWVudD4oSFRNTF9ESVZfS0VZUyk7XG5cbmNvbnN0IGhlYWRFeHRyYWN0b3IgPSAoZWx0OiBIVE1MSGVhZEVsZW1lbnQpID0+IGV4dHJhY3RIVE1MRWxlbWVudEJhc2UoZWx0KTtcblxuY29uc3QgSFRNTF9IRUFESU5HX0tFWVMgPSBbXCJhbGlnblwiXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxIZWFkaW5nRWxlbWVudClbXTtcbmNvbnN0IGhlYWRpbmdFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MSGVhZGluZ0VsZW1lbnQ+KEhUTUxfSEVBRElOR19LRVlTKTtcblxuY29uc3QgSFRNTF9IUl9LRVlTID0gW1xuXHRcImFsaWduXCIsXG5cdFwiY29sb3JcIixcblx0XCJub1NoYWRlXCIsXG5cdFwic2l6ZVwiLFxuXHRcIndpZHRoXCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTEhSRWxlbWVudClbXTtcbmNvbnN0IGhyRXh0cmFjdG9yID0gd2l0aEJhc2U8SFRNTEhSRWxlbWVudD4oSFRNTF9IUl9LRVlTKTtcblxuY29uc3QgSFRNTF9IVE1MX0tFWVMgPSBbXCJ2ZXJzaW9uXCJdIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTEh0bWxFbGVtZW50KVtdO1xuY29uc3QgaHRtbEV4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxIdG1sRWxlbWVudD4oSFRNTF9IVE1MX0tFWVMpO1xuXG5jb25zdCBtZW51RXh0cmFjdG9yID0gKGVsdDogSFRNTE1lbnVFbGVtZW50KSA9PiBleHRyYWN0SFRNTEVsZW1lbnRCYXNlKGVsdCk7XG5cbmNvbnN0IEhUTUxfTUVUQV9LRVlTID0gW1xuXHRcImNvbnRlbnRcIixcblx0XCJodHRwRXF1aXZcIixcblx0XCJuYW1lXCIsXG5cdFwic2NoZW1lXCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTE1ldGFFbGVtZW50KVtdO1xuY29uc3QgbWV0YUV4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxNZXRhRWxlbWVudD4oSFRNTF9NRVRBX0tFWVMpO1xuXG5jb25zdCBIVE1MX1BfS0VZUyA9IFtcImFsaWduXCJdIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgSFRNTFBhcmFncmFwaEVsZW1lbnQpW107XG5jb25zdCBwYXJhZ3JhcGhFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MUGFyYWdyYXBoRWxlbWVudD4oSFRNTF9QX0tFWVMpO1xuXG5jb25zdCBwaWN0dXJlRXh0cmFjdG9yID0gKGVsdDogSFRNTFBpY3R1cmVFbGVtZW50KSA9PiBleHRyYWN0SFRNTEVsZW1lbnRCYXNlKGVsdCk7XG5cbmNvbnN0IEhUTUxfUFJFX0tFWVMgPSBbXCJ3aWR0aFwiXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxQcmVFbGVtZW50KVtdO1xuY29uc3QgcHJlRXh0cmFjdG9yID0gd2l0aEJhc2U8SFRNTFByZUVsZW1lbnQ+KEhUTUxfUFJFX0tFWVMpO1xuXG5jb25zdCBzcGFuRXh0cmFjdG9yID0gKGVsdDogSFRNTFNwYW5FbGVtZW50KSA9PiBleHRyYWN0SFRNTEVsZW1lbnRCYXNlKGVsdCk7XG5cbmNvbnN0IEhUTUxfU1RZTEVfS0VZUyA9IFtcblx0XCJtZWRpYVwiLFxuXHRcInR5cGVcIixcblx0XCJkaXNhYmxlZFwiLFxuXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxTdHlsZUVsZW1lbnQpW107XG5jb25zdCBzdHlsZUV4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxTdHlsZUVsZW1lbnQ+KEhUTUxfU1RZTEVfS0VZUyk7XG5cbmNvbnN0IEhUTUxfVElUTEVfS0VZUyA9IFtcInRleHRcIl0gYXMgY29uc3Qgc2F0aXNmaWVzIHJlYWRvbmx5IChrZXlvZiBIVE1MVGl0bGVFbGVtZW50KVtdO1xuY29uc3QgdGl0bGVFeHRyYWN0b3IgPSB3aXRoQmFzZTxIVE1MVGl0bGVFbGVtZW50PihIVE1MX1RJVExFX0tFWVMpO1xuXG5jb25zdCBIVE1MX1VMX0tFWVMgPSBbXCJjb21wYWN0XCIsIFwidHlwZVwiXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIEhUTUxVTGlzdEVsZW1lbnQpW107XG5jb25zdCB1bGlzdEV4dHJhY3RvciA9IHdpdGhCYXNlPEhUTUxVTGlzdEVsZW1lbnQ+KEhUTUxfVUxfS0VZUyk7XG5cbi8vIE1hcCBvZiB0YWdOYW1lIC0+IGV4dHJhY3RvciAoY29uY2lzZSwgbGlrZSBldmVudHMudHMpXG5jb25zdCBlbGVtZW50RXh0cmFjdG9yczogUmVjb3JkPHN0cmluZywgKGVsdDogYW55KSA9PiBvYmplY3Q+ID0ge1xuXHRBOiBhbmNob3JFeHRyYWN0b3IsXG5cdEFSRUE6IGFyZWFFeHRyYWN0b3IsXG5cdEFVRElPOiBhdWRpb0V4dHJhY3Rvcixcblx0QkFTRTogYmFzZUV4dHJhY3Rvcixcblx0QkxPQ0tRVU9URTogcXVvdGVFeHRyYWN0b3IsXG5cdFE6IHF1b3RlRXh0cmFjdG9yLFxuXHRCT0RZOiBib2R5RXh0cmFjdG9yLFxuXHRCUjogYnJFeHRyYWN0b3IsXG5cdEJVVFRPTjogYnV0dG9uRXh0cmFjdG9yLFxuXHRDQU5WQVM6IGV4dHJhY3RIVE1MRWxlbWVudEJhc2UsXG5cdENBUFRJT046IHRhYmxlQ2FwdGlvbkV4dHJhY3Rvcixcblx0Q0lURTogY2l0ZUV4dHJhY3Rvcixcblx0Q09MOiB0YWJsZUNvbEV4dHJhY3Rvcixcblx0Q09MR1JPVVA6IHRhYmxlQ29sRXh0cmFjdG9yLFxuXHREQVRBOiBkYXRhRXh0cmFjdG9yLFxuXHRERVRBSUxTOiBkZXRhaWxzRXh0cmFjdG9yLFxuXHRESUFMT0c6IGRpYWxvZ0V4dHJhY3Rvcixcblx0RElWOiBkaXZFeHRyYWN0b3IsXG5cdERMOiBkbGlzdEV4dHJhY3Rvcixcblx0RU1CRUQ6IGVtYmVkRXh0cmFjdG9yLFxuXHRGSUVMRFNFVDogZmllbGRzZXRFeHRyYWN0b3IsXG5cdEZPUk06IGZvcm1FeHRyYWN0b3IsXG5cdEgxOiBoZWFkaW5nRXh0cmFjdG9yLFxuXHRIMjogaGVhZGluZ0V4dHJhY3Rvcixcblx0SDM6IGhlYWRpbmdFeHRyYWN0b3IsXG5cdEg0OiBoZWFkaW5nRXh0cmFjdG9yLFxuXHRINTogaGVhZGluZ0V4dHJhY3Rvcixcblx0SDY6IGhlYWRpbmdFeHRyYWN0b3IsXG5cdEhFQUQ6IGhlYWRFeHRyYWN0b3IsXG5cdEhSOiBockV4dHJhY3Rvcixcblx0SFRNTDogaHRtbEV4dHJhY3Rvcixcblx0SUZSQU1FOiBpZnJhbWVFeHRyYWN0b3IsXG5cdElNRzogaW1hZ2VFeHRyYWN0b3IsXG5cdElOUFVUOiBpbnB1dEV4dHJhY3Rvcixcblx0TEFCRUw6IGxhYmVsRXh0cmFjdG9yLFxuXHRMSTogbGlFeHRyYWN0b3IsXG5cdExJTks6IGxpbmtFeHRyYWN0b3IsXG5cdE1BUDogbWFwRXh0cmFjdG9yLFxuXHRNRU5VOiBtZW51RXh0cmFjdG9yLFxuXHRNRVRBOiBtZXRhRXh0cmFjdG9yLFxuXHRNRVRFUjogbWV0ZXJFeHRyYWN0b3IsXG5cdElOUzogbW9kRXh0cmFjdG9yLFxuXHRERUw6IG1vZEV4dHJhY3Rvcixcblx0T0JKRUNUOiBvYmplY3RFeHRyYWN0b3IsXG5cdE9MOiBvbGlzdEV4dHJhY3Rvcixcblx0T1BUR1JPVVA6IG9wdGdyb3VwRXh0cmFjdG9yLFxuXHRPUFRJT046IG9wdGlvbkV4dHJhY3Rvcixcblx0T1VUUFVUOiBvdXRwdXRFeHRyYWN0b3IsXG5cdFA6IHBhcmFncmFwaEV4dHJhY3Rvcixcblx0UElDVFVSRTogcGljdHVyZUV4dHJhY3Rvcixcblx0UFJFOiBwcmVFeHRyYWN0b3IsXG5cdFBST0dSRVNTOiBwcm9ncmVzc0V4dHJhY3Rvcixcblx0U0NSSVBUOiBzY3JpcHRFeHRyYWN0b3IsXG5cdFNFTEVDVDogc2VsZWN0RXh0cmFjdG9yLFxuXHRTTE9UOiBzbG90RXh0cmFjdG9yLFxuXHRTT1VSQ0U6IHNvdXJjZUV4dHJhY3Rvcixcblx0U1BBTjogc3BhbkV4dHJhY3Rvcixcblx0U1RZTEU6IHN0eWxlRXh0cmFjdG9yLFxuXHRUQUJMRTogdGFibGVFeHRyYWN0b3IsXG5cdFRCT0RZOiB0YWJsZVNlY3Rpb25FeHRyYWN0b3IsXG5cdFRIRUFEOiB0YWJsZVNlY3Rpb25FeHRyYWN0b3IsXG5cdFRGT09UOiB0YWJsZVNlY3Rpb25FeHRyYWN0b3IsXG5cdFREOiB0YWJsZUNlbGxFeHRyYWN0b3IsXG5cdFRIOiB0YWJsZUNlbGxFeHRyYWN0b3IsXG5cdFRFTVBMQVRFOiB0ZW1wbGF0ZUV4dHJhY3Rvcixcblx0VEVYVEFSRUE6IHRleHRhcmVhRXh0cmFjdG9yLFxuXHRUSU1FOiB0aW1lRXh0cmFjdG9yLFxuXHRUSVRMRTogdGl0bGVFeHRyYWN0b3IsXG5cdFRSOiB0YWJsZVJvd0V4dHJhY3Rvcixcblx0VFJBQ0s6IHRyYWNrRXh0cmFjdG9yLFxuXHRVTDogdWxpc3RFeHRyYWN0b3IsXG5cdFZJREVPOiB2aWRlb0V4dHJhY3Rvcixcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0SFRNTEVsZW1lbnQoZWx0OiBIVE1MRWxlbWVudCk6IG9iamVjdCB7XG5cdGNvbnN0IHRhZ05hbWUgPSBlbHQudGFnTmFtZS50b1VwcGVyQ2FzZSgpO1xuXG5cdGNvbnN0IGV4dHJhY3RvciA9IGVsZW1lbnRFeHRyYWN0b3JzW3RhZ05hbWVdO1xuXHRpZiAoZXh0cmFjdG9yKSB7XG5cdFx0cmV0dXJuIGV4dHJhY3RvcihlbHQpO1xuXHR9XG5cdHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCBIVE1MIGVsZW1lbnQgdGFnOiAke2VsdC50YWdOYW1lfSAodXBkYXRlIC53ZWIvY3VzdG9tL3NlcmlhbGl6ZS50cylgKTtcbn1cbiIsCiAgICAiLyogPT09IElNUE9SVEFOVCA9PT0gKi9cblxuaW1wb3J0IHsgZXh0cmFjdEhUTUxFbGVtZW50IH0gZnJvbSBcIi4vZWxlbWVudHNcIjtcbmltcG9ydCB7IGNyZWF0ZUV4dHJhY3RvciB9IGZyb20gXCIuL2V4dHJhY3RvclwiO1xuXG4vLyBSZXVzYWJsZSBjb21wdXRlZCBtYXBwZXJzIChoZWxwcyBidW5kbGVycy9taW5pZmllcnMgc2hhcmUgcmVmZXJlbmNlcylcbmNvbnN0IG1hcFRhcmdldCA9IChlOiB7IHRhcmdldDogRXZlbnRUYXJnZXQgfCBudWxsIH0pID0+XG5cdGV4dHJhY3RIVE1MRWxlbWVudChlLnRhcmdldCBhcyBIVE1MRWxlbWVudCk7XG5jb25zdCBtYXBSZWxhdGVkID0gKGU6IHsgcmVsYXRlZFRhcmdldDogRXZlbnRUYXJnZXQgfCBudWxsIH0pID0+XG5cdGUucmVsYXRlZFRhcmdldCA/IGV4dHJhY3RIVE1MRWxlbWVudChlLnJlbGF0ZWRUYXJnZXQgYXMgSFRNTEVsZW1lbnQpIDogbnVsbDtcblxuZnVuY3Rpb24gbWFrZUV4dHJhY3RvcjxLIGV4dGVuZHMgcmVhZG9ubHkgYW55W10+KFxuXHRrZXlzOiBLLFxuXHRjb21wdXRlZD86IFJlY29yZDxzdHJpbmcsIChldnQ6IGFueSkgPT4gYW55Pixcbikge1xuXHRyZXR1cm4gY3JlYXRlRXh0cmFjdG9yPGFueT4oKShcblx0XHRrZXlzIGFzIGFueSxcblx0XHR7XG5cdFx0XHR0YXJnZXQ6IG1hcFRhcmdldCxcblx0XHRcdC4uLihjb21wdXRlZCB8fCB7fSksXG5cdFx0fSBhcyBhbnksXG5cdCk7XG59XG5cbmNvbnN0IFNZTlRIRVRJQ19LRVlTID0gW1xuXHRcInRhcmdldFwiLFxuXHRcImJ1YmJsZXNcIixcblx0XCJjYW5jZWxhYmxlXCIsXG5cdFwiZGVmYXVsdFByZXZlbnRlZFwiLFxuXHRcImV2ZW50UGhhc2VcIixcblx0XCJpc1RydXN0ZWRcIixcblx0XCJ0aW1lU3RhbXBcIixcblx0XCJ0eXBlXCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgUmVhY3QuU3ludGhldGljRXZlbnQpW107XG5cbmNvbnN0IFVJX0tFWVMgPSBbLi4uU1lOVEhFVElDX0tFWVMsIFwiZGV0YWlsXCJdIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgUmVhY3QuVUlFdmVudClbXTtcblxuY29uc3QgTU9VU0VfS0VZUyA9IFtcblx0Li4uVUlfS0VZUyxcblx0XCJhbHRLZXlcIixcblx0XCJidXR0b25cIixcblx0XCJidXR0b25zXCIsXG5cdFwiY2xpZW50WFwiLFxuXHRcImNsaWVudFlcIixcblx0XCJjdHJsS2V5XCIsXG5cdFwibWV0YUtleVwiLFxuXHRcIm1vdmVtZW50WFwiLFxuXHRcIm1vdmVtZW50WVwiLFxuXHRcInBhZ2VYXCIsXG5cdFwicGFnZVlcIixcblx0XCJzY3JlZW5YXCIsXG5cdFwic2NyZWVuWVwiLFxuXHRcInNoaWZ0S2V5XCIsXG5dIGFzIGNvbnN0IHNhdGlzZmllcyByZWFkb25seSAoa2V5b2YgUmVhY3QuTW91c2VFdmVudClbXTtcblxuY29uc3QgUE9JTlRFUl9LRVlTID0gW1xuXHQuLi5NT1VTRV9LRVlTLFxuXHRcInBvaW50ZXJJZFwiLFxuXHRcInByZXNzdXJlXCIsXG5cdFwidGFuZ2VudGlhbFByZXNzdXJlXCIsXG5cdFwidGlsdFhcIixcblx0XCJ0aWx0WVwiLFxuXHRcInR3aXN0XCIsXG5cdFwid2lkdGhcIixcblx0XCJoZWlnaHRcIixcblx0XCJwb2ludGVyVHlwZVwiLFxuXHRcImlzUHJpbWFyeVwiLFxuXSBhcyBjb25zdCBzYXRpc2ZpZXMgcmVhZG9ubHkgKGtleW9mIFJlYWN0LlBvaW50ZXJFdmVudClbXTtcblxuY29uc3Qgc3ludGhldGljRXh0cmFjdG9yID0gbWFrZUV4dHJhY3RvcihTWU5USEVUSUNfS0VZUyk7XG5cbmNvbnN0IHVpRXh0cmFjdG9yID0gbWFrZUV4dHJhY3RvcihVSV9LRVlTKTtcblxuY29uc3QgbW91c2VFeHRyYWN0b3IgPSBtYWtlRXh0cmFjdG9yKE1PVVNFX0tFWVMsIHsgcmVsYXRlZFRhcmdldDogbWFwUmVsYXRlZCB9KTtcblxuY29uc3QgY2xpcGJvYXJkRXh0cmFjdG9yID0gbWFrZUV4dHJhY3RvcihTWU5USEVUSUNfS0VZUywge1xuXHRjbGlwYm9hcmREYXRhOiAoZSkgPT4gZXh0cmFjdERhdGFUcmFuc2ZlcihlLmNsaXBib2FyZERhdGEpLFxufSk7XG5cbmNvbnN0IGNvbXBvc2l0aW9uRXh0cmFjdG9yID0gbWFrZUV4dHJhY3RvcihbLi4uU1lOVEhFVElDX0tFWVMsIFwiZGF0YVwiXSBhcyBjb25zdCk7XG5cbmNvbnN0IGRyYWdFeHRyYWN0b3IgPSBtYWtlRXh0cmFjdG9yKE1PVVNFX0tFWVMsIHtcblx0cmVsYXRlZFRhcmdldDogbWFwUmVsYXRlZCxcblx0ZGF0YVRyYW5zZmVyOiAoZSkgPT4gZXh0cmFjdERhdGFUcmFuc2ZlcihlLmRhdGFUcmFuc2ZlciksXG59KTtcblxuY29uc3QgcG9pbnRlckV4dHJhY3RvciA9IG1ha2VFeHRyYWN0b3IoUE9JTlRFUl9LRVlTLCB7XG5cdHJlbGF0ZWRUYXJnZXQ6IG1hcFJlbGF0ZWQsXG59KTtcblxuY29uc3QgZm9jdXNFeHRyYWN0b3IgPSBtYWtlRXh0cmFjdG9yKFNZTlRIRVRJQ19LRVlTLCB7XG5cdHJlbGF0ZWRUYXJnZXQ6IG1hcFJlbGF0ZWQsXG59KTtcblxuY29uc3QgZm9ybUV4dHJhY3RvciA9IG1ha2VFeHRyYWN0b3IoU1lOVEhFVElDX0tFWVMpO1xuXG5jb25zdCBpbnZhbGlkRXh0cmFjdG9yID0gbWFrZUV4dHJhY3RvcihTWU5USEVUSUNfS0VZUyk7XG5cbmNvbnN0IGNoYW5nZUV4dHJhY3RvciA9IG1ha2VFeHRyYWN0b3IoU1lOVEhFVElDX0tFWVMpO1xuXG5jb25zdCBrZXlib2FyZEV4dHJhY3RvciA9IG1ha2VFeHRyYWN0b3IoW1xuXHQuLi5VSV9LRVlTLFxuXHRcImFsdEtleVwiLFxuXHRcImN0cmxLZXlcIixcblx0XCJjb2RlXCIsXG5cdFwia2V5XCIsXG5cdFwibG9jYWxlXCIsXG5cdFwibG9jYXRpb25cIixcblx0XCJtZXRhS2V5XCIsXG5cdFwicmVwZWF0XCIsXG5cdFwic2hpZnRLZXlcIixcbl0gYXMgY29uc3QpO1xuXG5jb25zdCB0b3VjaEV4dHJhY3RvciA9IG1ha2VFeHRyYWN0b3IoXG5cdFtcblx0XHQuLi5VSV9LRVlTLFxuXHRcdFwiYWx0S2V5XCIsXG5cdFx0XCJjdHJsS2V5XCIsXG5cdFx0XCJtZXRhS2V5XCIsXG5cdFx0XCJzaGlmdEtleVwiLFxuXHRcdFwiY2hhbmdlZFRvdWNoZXNcIixcblx0XHRcInRhcmdldFRvdWNoZXNcIixcblx0XHRcInRvdWNoZXNcIixcblx0XSBhcyBjb25zdCxcblx0e1xuXHRcdGNoYW5nZWRUb3VjaGVzOiAoZSkgPT4gbWFwVG91Y2hMaXN0KGUuY2hhbmdlZFRvdWNoZXMpLFxuXHRcdHRhcmdldFRvdWNoZXM6IChlKSA9PiBtYXBUb3VjaExpc3QoZS50YXJnZXRUb3VjaGVzKSxcblx0XHR0b3VjaGVzOiAoZSkgPT4gbWFwVG91Y2hMaXN0KGUudG91Y2hlcyksXG5cdH0sXG4pO1xuXG5jb25zdCB3aGVlbEV4dHJhY3RvciA9IG1ha2VFeHRyYWN0b3IoXG5cdFsuLi5NT1VTRV9LRVlTLCBcImRlbHRhTW9kZVwiLCBcImRlbHRhWFwiLCBcImRlbHRhWVwiLCBcImRlbHRhWlwiXSBhcyBjb25zdCxcblx0e1xuXHRcdHJlbGF0ZWRUYXJnZXQ6IG1hcFJlbGF0ZWQsXG5cdH0sXG4pO1xuXG5jb25zdCBhbmltYXRpb25FeHRyYWN0b3IgPSBtYWtlRXh0cmFjdG9yKFtcblx0Li4uU1lOVEhFVElDX0tFWVMsXG5cdFwiYW5pbWF0aW9uTmFtZVwiLFxuXHRcImVsYXBzZWRUaW1lXCIsXG5cdFwicHNldWRvRWxlbWVudFwiLFxuXSBhcyBjb25zdCk7XG5cbmNvbnN0IHRvZ2dsZUV4dHJhY3RvciA9IG1ha2VFeHRyYWN0b3IoWy4uLlNZTlRIRVRJQ19LRVlTLCBcIm9sZFN0YXRlXCIsIFwibmV3U3RhdGVcIl0gYXMgY29uc3QpO1xuXG5jb25zdCB0cmFuc2l0aW9uRXh0cmFjdG9yID0gbWFrZUV4dHJhY3RvcihbXG5cdC4uLlNZTlRIRVRJQ19LRVlTLFxuXHRcImVsYXBzZWRUaW1lXCIsXG5cdFwicHJvcGVydHlOYW1lXCIsXG5cdFwicHNldWRvRWxlbWVudFwiLFxuXSBhcyBjb25zdCk7XG5cbmZ1bmN0aW9uIG1hcFRvdWNoTGlzdChsaXN0OiBhbnkpOiBhbnlbXSB7XG5cdHJldHVybiBBcnJheS5mcm9tKGxpc3QgYXMgQXJyYXlMaWtlPGFueT4pLm1hcCgodG91Y2g6IGFueSkgPT4gKHtcblx0XHR0YXJnZXQ6IGV4dHJhY3RIVE1MRWxlbWVudCh0b3VjaC50YXJnZXQgYXMgSFRNTEVsZW1lbnQpLFxuXHRcdGlkZW50aWZpZXI6IHRvdWNoLmlkZW50aWZpZXIsXG5cdFx0c2NyZWVuWDogdG91Y2guc2NyZWVuWCxcblx0XHRzY3JlZW5ZOiB0b3VjaC5zY3JlZW5ZLFxuXHRcdGNsaWVudFg6IHRvdWNoLmNsaWVudFgsXG5cdFx0Y2xpZW50WTogdG91Y2guY2xpZW50WSxcblx0XHRwYWdlWDogdG91Y2gucGFnZVgsXG5cdFx0cGFnZVk6IHRvdWNoLnBhZ2VZLFxuXHR9KSk7XG59XG5cbi8vIEhlbHBlciBmdW5jdGlvbiB0byBleHRyYWN0IERhdGFUcmFuc2ZlciBwcm9wZXJ0aWVzXG5mdW5jdGlvbiBleHRyYWN0RGF0YVRyYW5zZmVyKGR0OiBEYXRhVHJhbnNmZXIgfCBudWxsKTogb2JqZWN0IHwgbnVsbCB7XG5cdGlmICghZHQpIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXHRjb25zdCBpdGVtcyA9IFtdO1xuXHRpZiAoZHQuaXRlbXMpIHtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGR0Lml0ZW1zLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRjb25zdCBpdGVtID0gZHQuaXRlbXNbaV0hO1xuXHRcdFx0aXRlbXMucHVzaCh7XG5cdFx0XHRcdGtpbmQ6IGl0ZW0ua2luZCxcblx0XHRcdFx0dHlwZTogaXRlbS50eXBlLFxuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiB7XG5cdFx0ZHJvcF9lZmZlY3Q6IGR0LmRyb3BFZmZlY3QsXG5cdFx0ZWZmZWN0X2FsbG93ZWQ6IGR0LmVmZmVjdEFsbG93ZWQsXG5cdFx0aXRlbXM6IGl0ZW1zLFxuXHRcdHR5cGVzOiBBcnJheS5mcm9tKGR0LnR5cGVzIHx8IFtdKSxcblx0fTtcbn1cblxuY29uc3QgZXZlbnRFeHRyYWN0b3JNYXA6IHsgW2tleTogc3RyaW5nXTogKGV2dDogYW55KSA9PiBvYmplY3QgfSA9IHt9O1xuXG5mdW5jdGlvbiBhZGQobWFwOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10sIGZuOiBhbnkpIHtcblx0Zm9yIChjb25zdCBuIG9mIG5hbWVzKSBtYXBbbl0gPSBmbjtcbn1cblxuYWRkKFxuXHRldmVudEV4dHJhY3Rvck1hcCxcblx0W1xuXHRcdFwicG9pbnRlcmRvd25cIixcblx0XHRcInBvaW50ZXJtb3ZlXCIsXG5cdFx0XCJwb2ludGVydXBcIixcblx0XHRcInBvaW50ZXJjYW5jZWxcIixcblx0XHRcImdvdHBvaW50ZXJjYXB0dXJlXCIsXG5cdFx0XCJsb3N0cG9pbnRlcmNhcHR1cmVcIixcblx0XHRcInBvaW50ZXJlbnRlclwiLFxuXHRcdFwicG9pbnRlcmxlYXZlXCIsXG5cdFx0XCJwb2ludGVyb3ZlclwiLFxuXHRcdFwicG9pbnRlcm91dFwiLFxuXHRdLFxuXHRwb2ludGVyRXh0cmFjdG9yLFxuKTtcblxuYWRkKFxuXHRldmVudEV4dHJhY3Rvck1hcCxcblx0W1xuXHRcdFwiY2xpY2tcIixcblx0XHRcImNvbnRleHRtZW51XCIsXG5cdFx0XCJkYmxjbGlja1wiLFxuXHRcdFwibW91c2Vkb3duXCIsXG5cdFx0XCJtb3VzZWVudGVyXCIsXG5cdFx0XCJtb3VzZWxlYXZlXCIsXG5cdFx0XCJtb3VzZW1vdmVcIixcblx0XHRcIm1vdXNlb3V0XCIsXG5cdFx0XCJtb3VzZW92ZXJcIixcblx0XHRcIm1vdXNldXBcIixcblx0XSxcblx0bW91c2VFeHRyYWN0b3IsXG4pO1xuXG5hZGQoXG5cdGV2ZW50RXh0cmFjdG9yTWFwLFxuXHRbXCJkcmFnXCIsIFwiZHJhZ2VuZFwiLCBcImRyYWdlbnRlclwiLCBcImRyYWdleGl0XCIsIFwiZHJhZ2xlYXZlXCIsIFwiZHJhZ292ZXJcIiwgXCJkcmFnc3RhcnRcIiwgXCJkcm9wXCJdLFxuXHRkcmFnRXh0cmFjdG9yLFxuKTtcblxuYWRkKGV2ZW50RXh0cmFjdG9yTWFwLCBbXCJrZXlkb3duXCIsIFwia2V5cHJlc3NcIiwgXCJrZXl1cFwiXSwga2V5Ym9hcmRFeHRyYWN0b3IpO1xuYWRkKGV2ZW50RXh0cmFjdG9yTWFwLCBbXCJmb2N1c1wiLCBcImJsdXJcIl0sIGZvY3VzRXh0cmFjdG9yKTtcbmFkZChldmVudEV4dHJhY3Rvck1hcCwgW1wiY2hhbmdlXCIsIFwiaW5wdXRcIl0sIGNoYW5nZUV4dHJhY3Rvcik7XG5hZGQoZXZlbnRFeHRyYWN0b3JNYXAsIFtcImludmFsaWRcIl0sIGludmFsaWRFeHRyYWN0b3IpO1xuYWRkKGV2ZW50RXh0cmFjdG9yTWFwLCBbXCJyZXNldFwiLCBcInN1Ym1pdFwiXSwgZm9ybUV4dHJhY3Rvcik7XG5hZGQoZXZlbnRFeHRyYWN0b3JNYXAsIFtcImNvcHlcIiwgXCJjdXRcIiwgXCJwYXN0ZVwiXSwgY2xpcGJvYXJkRXh0cmFjdG9yKTtcbmFkZChcblx0ZXZlbnRFeHRyYWN0b3JNYXAsXG5cdFtcImNvbXBvc2l0aW9uZW5kXCIsIFwiY29tcG9zaXRpb25zdGFydFwiLCBcImNvbXBvc2l0aW9udXBkYXRlXCJdLFxuXHRjb21wb3NpdGlvbkV4dHJhY3Rvcixcbik7XG5hZGQoZXZlbnRFeHRyYWN0b3JNYXAsIFtcInRvdWNoY2FuY2VsXCIsIFwidG91Y2hlbmRcIiwgXCJ0b3VjaG1vdmVcIiwgXCJ0b3VjaHN0YXJ0XCJdLCB0b3VjaEV4dHJhY3Rvcik7XG5hZGQoZXZlbnRFeHRyYWN0b3JNYXAsIFtcInNjcm9sbFwiXSwgdWlFeHRyYWN0b3IpO1xuYWRkKGV2ZW50RXh0cmFjdG9yTWFwLCBbXCJ3aGVlbFwiXSwgd2hlZWxFeHRyYWN0b3IpO1xuYWRkKFxuXHRldmVudEV4dHJhY3Rvck1hcCxcblx0W1wiYW5pbWF0aW9uc3RhcnRcIiwgXCJhbmltYXRpb25lbmRcIiwgXCJhbmltYXRpb25pdGVyYXRpb25cIl0sXG5cdGFuaW1hdGlvbkV4dHJhY3Rvcixcbik7XG5hZGQoZXZlbnRFeHRyYWN0b3JNYXAsIFtcInRyYW5zaXRpb25lbmRcIl0sIHRyYW5zaXRpb25FeHRyYWN0b3IpO1xuYWRkKGV2ZW50RXh0cmFjdG9yTWFwLCBbXCJ0b2dnbGVcIl0sIHRvZ2dsZUV4dHJhY3Rvcik7XG5cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0RXZlbnQodmFsdWU6IGFueSk6IGFueSB7XG5cdC8vIER1Y2stdHlwaW5nIGZvciBSZWFjdCdzIFN5bnRoZXRpY0V2ZW50LlxuXHQvLyBXZSBjaGVjayBmb3IgcHJvcGVydGllcyB0aGF0IGFyZSB1bmlxdWUgdG8gc3ludGhldGljIGV2ZW50cy5cblx0aWYgKFxuXHRcdHZhbHVlICYmXG5cdFx0dHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmXG5cdFx0XCJuYXRpdmVFdmVudFwiIGluIHZhbHVlICYmXG5cdFx0dHlwZW9mIHZhbHVlLmlzRGVmYXVsdFByZXZlbnRlZCA9PT0gXCJmdW5jdGlvblwiXG5cdCkge1xuXHRcdGNvbnN0IGV2dCA9IHZhbHVlIGFzIFJlYWN0LlN5bnRoZXRpY0V2ZW50O1xuXHRcdC8vIFRoZSBgdHlwZWAgcHJvcGVydHkgaXMgY3J1Y2lhbCBmb3IgdGhlIGxvb2t1cC5cblx0XHRpZiAodHlwZW9mIGV2dC50eXBlICE9PSBcInN0cmluZ1wiKSB7XG5cdFx0XHRyZXR1cm4gdmFsdWU7XG5cdFx0fVxuXG5cdFx0Y29uc3QgZXh0cmFjdG9yID0gZXZlbnRFeHRyYWN0b3JNYXBbZXZ0LnR5cGUudG9Mb3dlckNhc2UoKV07XG5cdFx0aWYgKGV4dHJhY3Rvcikge1xuXHRcdFx0cmV0dXJuIGV4dHJhY3RvcihldnQpO1xuXHRcdH1cblxuXHRcdC8vIEZhbGxiYWNrIGZvciB1bmtub3duIGV2ZW50IHR5cGVzOiBtaW5pbWFsIHN5bnRoZXRpYyBleHRyYWN0b3Jcblx0XHRyZXR1cm4gc3ludGhldGljRXh0cmFjdG9yKGV2dCk7XG5cdH1cblxuXHQvLyBJZiBpdCdzIG5vdCBhIGR1Y2stdHlwZWQgZXZlbnQsIHJldHVybiBpdCBhcyBpcy5cblx0cmV0dXJuIHZhbHVlO1xufVxuIiwKICAgICJleHBvcnQgdHlwZSBQcmltaXRpdmUgPSBudW1iZXIgfCBzdHJpbmcgfCBib29sZWFuIHwgbnVsbCB8IHVuZGVmaW5lZDtcbmV4cG9ydCB0eXBlIEpTT048VD4gPSBUIHwgQXJyYXk8SlNPTjxUPj4gfCB7IFtLOiBzdHJpbmddOiBKU09OPFQ+IH07XG5leHBvcnQgdHlwZSBQbGFpbkpTT04gPSBKU09OPFByaW1pdGl2ZT47XG5leHBvcnQgdHlwZSBTZXJpYWxpemFibGUgPSBhbnk7XG5cbmV4cG9ydCB0eXBlIFNlcmlhbGl6ZWQgPSBbW251bWJlcltdLCBudW1iZXJbXSwgbnVtYmVyW10sIG51bWJlcltdXSwgUGxhaW5KU09OXTtcblxuZXhwb3J0IGZ1bmN0aW9uIHNlcmlhbGl6ZShkYXRhOiBTZXJpYWxpemFibGUpOiBTZXJpYWxpemVkIHtcblx0Y29uc3Qgc2VlbiA9IG5ldyBNYXA8YW55LCBudW1iZXI+KCk7XG5cdGNvbnN0IHJlZnM6IG51bWJlcltdID0gW107XG5cdGNvbnN0IGRhdGVzOiBudW1iZXJbXSA9IFtdO1xuXHRjb25zdCBzZXRzOiBudW1iZXJbXSA9IFtdO1xuXHRjb25zdCBtYXBzOiBudW1iZXJbXSA9IFtdO1xuXG5cdC8vIFNpbmdsZSBnbG9iYWwgY291bnRlciAtIGluY3JlbWVudHMgb25jZSBwZXIgbm9kZSB2aXNpdFxuXHRsZXQgZ2xvYmFsSW5kZXggPSAwO1xuXG5cdGZ1bmN0aW9uIHByb2Nlc3ModmFsdWU6IFNlcmlhbGl6YWJsZSk6IFBsYWluSlNPTiB7XG5cdFx0aWYgKFxuXHRcdFx0dmFsdWUgPT0gbnVsbCB8fFxuXHRcdFx0dHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiIHx8XG5cdFx0XHR0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgfHxcblx0XHRcdHR5cGVvZiB2YWx1ZSA9PT0gXCJib29sZWFuXCJcblx0XHQpIHtcblx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHR9XG5cblx0XHRjb25zdCBpZHggPSBnbG9iYWxJbmRleCsrO1xuXHRcdGNvbnN0IHByZXZSZWYgPSBzZWVuLmdldCh2YWx1ZSk7XG5cdFx0aWYgKHByZXZSZWYgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0Ly8gTWFrZSBzdXJlIHRvIHB1c2ggdGhlIGN1cnJlbnQgaW5kZXgsIGJ1dCB1c2UgdGhlIHJlZidzIGluZGV4IGFzIHRoZSB2YWx1ZSFcblx0XHRcdHJlZnMucHVzaChpZHgpO1xuXHRcdFx0cmV0dXJuIHByZXZSZWY7XG5cdFx0fVxuXG5cdFx0c2Vlbi5zZXQodmFsdWUsIGlkeCk7XG5cblx0XHRpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG5cdFx0XHRkYXRlcy5wdXNoKGlkeCk7XG5cdFx0XHRyZXR1cm4gdmFsdWUuZ2V0VGltZSgpO1xuXHRcdH1cblxuXHRcdGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuXHRcdFx0Y29uc3QgbGVuZ3RoID0gdmFsdWUubGVuZ3RoO1xuXHRcdFx0Y29uc3QgcmVzdWx0ID0gbmV3IEFycmF5KGxlbmd0aCk7XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdHJlc3VsdFtpXSA9IHByb2Nlc3ModmFsdWVbaV0pO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cblx0XHRpZiAodmFsdWUgaW5zdGFuY2VvZiBNYXApIHtcblx0XHRcdG1hcHMucHVzaChpZHgpO1xuXHRcdFx0Y29uc3QgcmVjOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG5cdFx0XHRmb3IgKGNvbnN0IFtrZXksIGVudHJ5XSBvZiB2YWx1ZS5lbnRyaWVzKCkpIHtcblx0XHRcdFx0cmVjW1N0cmluZyhrZXkpXSA9IHByb2Nlc3MoZW50cnkpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlYztcblx0XHR9XG5cblx0XHRpZiAodmFsdWUgaW5zdGFuY2VvZiBTZXQpIHtcblx0XHRcdHNldHMucHVzaChpZHgpO1xuXHRcdFx0Y29uc3Qgc2l6ZSA9IHZhbHVlLnNpemU7XG5cdFx0XHRjb25zdCByZXN1bHQgPSBuZXcgQXJyYXkoc2l6ZSk7XG5cdFx0XHRsZXQgaSA9IDA7XG5cdFx0XHRmb3IgKGNvbnN0IGVudHJ5IG9mIHZhbHVlKSB7XG5cdFx0XHRcdHJlc3VsdFtpXSA9IHByb2Nlc3MoZW50cnkpO1xuXHRcdFx0XHRpICs9IDE7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdH1cblxuXHRcdGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIpIHtcblx0XHRcdGNvbnN0IHJlYzogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuXHRcdFx0Y29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHZhbHVlKTtcblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRjb25zdCBrZXkgPSBrZXlzW2ldO1xuXHRcdFx0XHRyZWNba2V5XSA9IHByb2Nlc3ModmFsdWVba2V5XSk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmVjO1xuXHRcdH1cblxuXHRcdHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgdmFsdWUgaW4gc2VyaWFsaXphdGlvbjogJHt2YWx1ZX1gKTtcblx0fVxuXG5cdGNvbnN0IHBheWxvYWQgPSBwcm9jZXNzKGRhdGEpO1xuXHRyZXR1cm4gW1tyZWZzLCBkYXRlcywgc2V0cywgbWFwc10sIHBheWxvYWRdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERlc2VyaWFsaXphdGlvbk9wdGlvbnMge1xuXHRjb2VyY2VOdWxsc1RvVW5kZWZpbmVkPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlc2VyaWFsaXplPERhdGEgZXh0ZW5kcyBTZXJpYWxpemFibGUgPSBTZXJpYWxpemFibGU+KFxuXHRwYXlsb2FkOiBTZXJpYWxpemVkLFxuXHRvcHRpb25zPzogRGVzZXJpYWxpemF0aW9uT3B0aW9ucyxcbik6IERhdGEge1xuXHRjb25zdCBbW3JlZnNBLCBkYXRlc0EsIHNldHNBLCBtYXBzQV0sIGRhdGFdID0gcGF5bG9hZDtcblxuXHRjb25zdCByZWZzID0gbmV3IFNldChyZWZzQSk7XG5cdGNvbnN0IGRhdGVzID0gbmV3IFNldChkYXRlc0EpO1xuXHRjb25zdCBzZXRzID0gbmV3IFNldChzZXRzQSk7XG5cdGNvbnN0IG1hcHMgPSBuZXcgU2V0KG1hcHNBKTtcblxuXHRjb25zdCBvYmplY3RzOiBBcnJheTxhbnk+ID0gW107XG5cblx0ZnVuY3Rpb24gcmVjb25zdHJ1Y3QodmFsdWU6IFBsYWluSlNPTik6IGFueSB7XG5cdFx0Y29uc3QgaWR4ID0gb2JqZWN0cy5sZW5ndGg7XG5cdFx0aWYgKHJlZnMuaGFzKGlkeCkpIHtcblx0XHRcdC8vIFdlIGluY3JlbWVudCB0aGUgY291bnRlciBvbiByZWZzIGR1cmluZyBzZXJpYWxpemF0aW9uLiBXZSdyZSBuZXZlclxuXHRcdFx0Ly8gZ29pbmcgdG8gdXNlIHRoaXMgZW50cnksIHNvIHdlIGNhbiBqdXN0IHB1c2ggbnVsbC5cblx0XHRcdG9iamVjdHMucHVzaChudWxsKTtcblx0XHRcdHJldHVybiBvYmplY3RzW3ZhbHVlIGFzIG51bWJlcl07XG5cdFx0fVxuXG5cdFx0aWYgKGRhdGVzLmhhcyhpZHgpKSB7XG5cdFx0XHRjb25zdCBkdCA9IG5ldyBEYXRlKHZhbHVlIGFzIG51bWJlcik7XG5cdFx0XHRvYmplY3RzLnB1c2goZHQpO1xuXHRcdFx0cmV0dXJuIGR0O1xuXHRcdH1cblxuXHRcdGlmIChcblx0XHRcdHZhbHVlID09IG51bGwgfHxcblx0XHRcdHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIiB8fFxuXHRcdFx0dHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiIHx8XG5cdFx0XHR0eXBlb2YgdmFsdWUgPT09IFwiYm9vbGVhblwiXG5cdFx0KSB7XG5cdFx0XHRpZiAob3B0aW9ucz8uY29lcmNlTnVsbHNUb1VuZGVmaW5lZCkge1xuXHRcdFx0XHRyZXR1cm4gdmFsdWUgPz8gdW5kZWZpbmVkO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdH1cblxuXHRcdGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuXHRcdFx0aWYgKHNldHMuaGFzKGlkeCkpIHtcblx0XHRcdFx0Y29uc3QgcmVzdWx0ID0gbmV3IFNldCgpO1xuXHRcdFx0XHRvYmplY3RzLnB1c2gocmVzdWx0KTtcblx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdHJlc3VsdC5hZGQocmVjb25zdHJ1Y3QodmFsdWVbaV0pKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdFx0fVxuXG5cdFx0XHRjb25zdCBsZW5ndGggPSB2YWx1ZS5sZW5ndGg7XG5cdFx0XHRjb25zdCBhcnIgPSBuZXcgQXJyYXkobGVuZ3RoKTtcblx0XHRcdG9iamVjdHMucHVzaChhcnIpO1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuXHRcdFx0XHRhcnJbaV0gPSByZWNvbnN0cnVjdCh2YWx1ZVtpXSk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gYXJyO1xuXHRcdH1cblxuXHRcdGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIpIHtcblx0XHRcdGlmIChtYXBzLmhhcyhpZHgpKSB7XG5cdFx0XHRcdGNvbnN0IHJlc3VsdCA9IG5ldyBNYXA8c3RyaW5nLCBhbnk+KCk7XG5cdFx0XHRcdG9iamVjdHMucHVzaChyZXN1bHQpO1xuXHRcdFx0XHRjb25zdCBrZXlzID0gT2JqZWN0LmtleXModmFsdWUpO1xuXHRcdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRjb25zdCBrZXkgPSBrZXlzW2ldO1xuXHRcdFx0XHRcdHJlc3VsdC5zZXQoa2V5LCByZWNvbnN0cnVjdCh2YWx1ZVtrZXldKSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdH1cblxuXHRcdFx0Y29uc3QgcmVzdWx0OiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG5cdFx0XHRvYmplY3RzLnB1c2gocmVzdWx0KTtcblx0XHRcdGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZSk7XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0Y29uc3Qga2V5ID0ga2V5c1tpXTtcblx0XHRcdFx0cmVzdWx0W2tleV0gPSByZWNvbnN0cnVjdCh2YWx1ZVtrZXldKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fVxuXG5cdFx0dGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCB2YWx1ZSBpbiBkZXNlcmlhbGl6YXRpb246ICR7dmFsdWV9YCk7XG5cdH1cblxuXHRyZXR1cm4gcmVjb25zdHJ1Y3QoZGF0YSk7XG59XG4iLAogICAgImltcG9ydCB7XG5cdHR5cGUgQ29tcG9uZW50VHlwZSxcblx0Y2xvbmVFbGVtZW50LFxuXHRjcmVhdGVFbGVtZW50LFxuXHR0eXBlIEZDLFxuXHRGcmFnbWVudCxcblx0aXNWYWxpZEVsZW1lbnQsXG5cdGxhenksXG5cdHR5cGUgUHJvcHNXaXRoQ2hpbGRyZW4sXG5cdHR5cGUgUmVhY3RFbGVtZW50LFxuXHR0eXBlIFJlYWN0Tm9kZSxcblx0U3VzcGVuc2UsXG59IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHR5cGUgeyBQdWxzZVNvY2tldElPQ2xpZW50IH0gZnJvbSBcIi4vY2xpZW50XCI7XG5pbXBvcnQgdHlwZSB7IENvbXBvbmVudFJlZ2lzdHJ5LCBQYXRoRGVsdGEsIFZET00sIFZET01Ob2RlLCBWRE9NVXBkYXRlIH0gZnJvbSBcIi4vdmRvbVwiO1xuaW1wb3J0IHsgRlJBR01FTlRfVEFHLCBpc0VsZW1lbnROb2RlLCBpc01vdW50UG9pbnROb2RlLCBNT1VOVF9QT0lOVF9QUkVGSVggfSBmcm9tIFwiLi92ZG9tXCI7XG5cbmV4cG9ydCBjbGFzcyBWRE9NUmVuZGVyZXIge1xuXHQjY2FsbGJhY2tzOiBTZXQ8c3RyaW5nPjtcblx0I2NhbGxiYWNrQ2FjaGU6IE1hcDxzdHJpbmcsICguLi5hcmdzOiBhbnkpID0+IHZvaWQ+O1xuXHQjcmVuZGVyUHJvcEtleXM6IFNldDxzdHJpbmc+O1xuXHQjY3NzUHJvcHM6IFNldDxzdHJpbmc+O1xuXHQjY2FsbGJhY2tMaXN0OiBzdHJpbmdbXTtcblx0I2NsaWVudDogUHVsc2VTb2NrZXRJT0NsaWVudDtcblx0I3BhdGg6IHN0cmluZztcblx0I2NvbXBvbmVudHM6IENvbXBvbmVudFJlZ2lzdHJ5O1xuXHQjY3NzTW9kdWxlczogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgc3RyaW5nPj47XG5cblx0Y29uc3RydWN0b3IoXG5cdFx0Y2xpZW50OiBQdWxzZVNvY2tldElPQ2xpZW50LFxuXHRcdHBhdGg6IHN0cmluZyxcblx0XHRjb21wb25lbnRzOiBDb21wb25lbnRSZWdpc3RyeSxcblx0XHRjc3NNb2R1bGVzOiBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+Pixcblx0XHRpbml0aWFsQ2FsbGJhY2tzOiBzdHJpbmdbXSA9IFtdLFxuXHRcdGluaXRpYWxSZW5kZXJQcm9wczogc3RyaW5nW10gPSBbXSxcblx0XHRpbml0aWFsQ3NzUmVmczogc3RyaW5nW10gPSBbXSxcblx0KSB7XG5cdFx0dGhpcy4jY2xpZW50ID0gY2xpZW50O1xuXHRcdHRoaXMuI3BhdGggPSBwYXRoO1xuXHRcdHRoaXMuI2NvbXBvbmVudHMgPSBjb21wb25lbnRzO1xuXHRcdHRoaXMuI2Nzc01vZHVsZXMgPSBjc3NNb2R1bGVzO1xuXHRcdHRoaXMuI2NhbGxiYWNrcyA9IG5ldyBTZXQoaW5pdGlhbENhbGxiYWNrcyk7XG5cdFx0dGhpcy4jY2FsbGJhY2tDYWNoZSA9IG5ldyBNYXAoKTtcblx0XHR0aGlzLiNyZW5kZXJQcm9wS2V5cyA9IG5ldyBTZXQoaW5pdGlhbFJlbmRlclByb3BzKTtcblx0XHR0aGlzLiNjc3NQcm9wcyA9IG5ldyBTZXQoaW5pdGlhbENzc1JlZnMpO1xuXHRcdHRoaXMuI2NhbGxiYWNrTGlzdCA9IFsuLi50aGlzLiNjYWxsYmFja3NdLnNvcnQoKTtcblx0fVxuXG5cdC8vIEFjY2Vzc29ycyB1c2VkIGJ5IHVwZGF0ZSBsb2dpYyB0byBkZXRlcm1pbmUgd2hpY2ggcHJvcHMgbmVlZCByZWJpbmRpbmdcblx0aGFzQ2FsbGJhY2tQYXRoKHBhdGg6IHN0cmluZykge1xuXHRcdHJldHVybiB0aGlzLiNjYWxsYmFja3MuaGFzKHBhdGgpO1xuXHR9XG5cblx0aGFzUmVuZGVyUHJvcFBhdGgocGF0aDogc3RyaW5nKSB7XG5cdFx0cmV0dXJuIHRoaXMuI3JlbmRlclByb3BLZXlzLmhhcyhwYXRoKTtcblx0fVxuXG5cdGhhc0FueUNhbGxiYWNrVW5kZXIocHJlZml4OiBzdHJpbmcpOiBib29sZWFuIHtcblx0XHRpZiAocHJlZml4ID09PSBcIlwiKSByZXR1cm4gdGhpcy4jY2FsbGJhY2tMaXN0Lmxlbmd0aCA+IDA7XG5cdFx0Y29uc3QgaSA9IHRoaXMuI2xvd2VyQm91bmQodGhpcy4jY2FsbGJhY2tMaXN0LCBwcmVmaXgpO1xuXHRcdHJldHVybiBpIDwgdGhpcy4jY2FsbGJhY2tMaXN0Lmxlbmd0aCAmJiB0aGlzLiNjYWxsYmFja0xpc3RbaV0hLnN0YXJ0c1dpdGgocHJlZml4KTtcblx0fVxuXG5cdGFwcGx5Q2FsbGJhY2tEZWx0YShkZWx0YTogUGF0aERlbHRhKSB7XG5cdFx0Ly8gT25seSB1cGRhdGUgdGhlIGludGVybmFsIGNhbGxiYWNrIHBhdGggcmVnaXN0cnkgYW5kIGNhY2hlLiBXZSByZWx5IG9uXG5cdFx0Ly8gYWNjb21wYW55aW5nIHVwZGF0ZV9wcm9wcyBvcGVyYXRpb25zIHRoYXQgY29udGFpbiB0aGUgXCIkY2JcIiBwbGFjZWhvbGRlclxuXHRcdC8vIHRvIHRyaWdnZXIgcHJvcCB1cGRhdGVzOyB0cmFuc2Zvcm1WYWx1ZSB3aWxsIHJlc29sdmUgdG8gZnVuY3Rpb25zLlxuXHRcdGlmIChkZWx0YS5yZW1vdmUpIHtcblx0XHRcdGZvciAoY29uc3Qga2V5IG9mIGRlbHRhLnJlbW92ZSkge1xuXHRcdFx0XHR0aGlzLiNjYWxsYmFja3MuZGVsZXRlKGtleSk7XG5cdFx0XHRcdHRoaXMuI2NhbGxiYWNrQ2FjaGUuZGVsZXRlKGtleSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmIChkZWx0YS5hZGQpIHtcblx0XHRcdGZvciAoY29uc3Qga2V5IG9mIGRlbHRhLmFkZCkge1xuXHRcdFx0XHR0aGlzLiNjYWxsYmFja3MuYWRkKGtleSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRoaXMuI2NhbGxiYWNrTGlzdCA9IFsuLi50aGlzLiNjYWxsYmFja3NdLnNvcnQoKTtcblx0fVxuXG5cdGFwcGx5UmVuZGVyUHJvcHNEZWx0YShkZWx0YTogUGF0aERlbHRhKSB7XG5cdFx0aWYgKGRlbHRhLnJlbW92ZSkge1xuXHRcdFx0Zm9yIChjb25zdCBrZXkgb2YgZGVsdGEucmVtb3ZlKSB7XG5cdFx0XHRcdHRoaXMuI3JlbmRlclByb3BLZXlzLmRlbGV0ZShrZXkpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRpZiAoZGVsdGEuYWRkKSB7XG5cdFx0XHRmb3IgKGNvbnN0IGtleSBvZiBkZWx0YS5hZGQpIHtcblx0XHRcdFx0dGhpcy4jcmVuZGVyUHJvcEtleXMuYWRkKGtleSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0YXBwbHlDc3NSZWZzRGVsdGEoZGVsdGE6IFBhdGhEZWx0YSkge1xuXHRcdGlmIChkZWx0YS5yZW1vdmUpIHtcblx0XHRcdGZvciAoY29uc3QgcHJvcCBvZiBkZWx0YS5yZW1vdmUpIHtcblx0XHRcdFx0dGhpcy4jY3NzUHJvcHMuZGVsZXRlKHByb3ApO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRpZiAoZGVsdGEuYWRkKSB7XG5cdFx0XHRmb3IgKGNvbnN0IHByb3Agb2YgZGVsdGEuYWRkKSB7XG5cdFx0XHRcdHRoaXMuI2Nzc1Byb3BzLmFkZChwcm9wKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRnZXRDYWxsYmFjayhwYXRoOiBzdHJpbmcsIHByb3A6IHN0cmluZykge1xuXHRcdGNvbnN0IGtleSA9IHRoaXMuI3Byb3BQYXRoKHBhdGgsIHByb3ApO1xuXHRcdGxldCBmbiA9IHRoaXMuI2NhbGxiYWNrQ2FjaGUuZ2V0KGtleSk7XG5cdFx0aWYgKCFmbikge1xuXHRcdFx0Zm4gPSAoLi4uYXJnczogYW55W10pID0+IHRoaXMuI2NsaWVudC5pbnZva2VDYWxsYmFjayh0aGlzLiNwYXRoLCBrZXksIGFyZ3MpO1xuXHRcdFx0dGhpcy4jY2FsbGJhY2tDYWNoZS5zZXQoa2V5LCBmbik7XG5cdFx0fVxuXHRcdHJldHVybiBmbjtcblx0fVxuXG5cdHJlbmRlck5vZGUobm9kZTogVkRPTU5vZGUsIGN1cnJlbnRQYXRoID0gXCJcIik6IFJlYWN0Tm9kZSB7XG5cdFx0Ly8gSGFuZGxlIHByaW1pdGl2ZXMgZWFybHlcblx0XHRpZiAoXG5cdFx0XHRub2RlID09IG51bGwgfHwgLy8gY2F0Y2hlcyBib3RoIG51bGwgYW5kIHVuZGVmaW5lZFxuXHRcdFx0dHlwZW9mIG5vZGUgPT09IFwiYm9vbGVhblwiIHx8XG5cdFx0XHR0eXBlb2Ygbm9kZSA9PT0gXCJudW1iZXJcIiB8fFxuXHRcdFx0dHlwZW9mIG5vZGUgPT09IFwic3RyaW5nXCJcblx0XHQpIHtcblx0XHRcdHJldHVybiBub2RlO1xuXHRcdH1cblxuXHRcdC8vIEVsZW1lbnQgbm9kZXNcblx0XHRpZiAoaXNFbGVtZW50Tm9kZShub2RlKSkge1xuXHRcdFx0Y29uc3QgeyB0YWcsIHByb3BzID0ge30sIGNoaWxkcmVuID0gW10gfSA9IG5vZGU7XG5cblx0XHRcdGNvbnN0IG5ld1Byb3BzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG5cdFx0XHRmb3IgKGNvbnN0IFtwcm9wTmFtZSwgcHJvcFZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhwcm9wcykpIHtcblx0XHRcdFx0bmV3UHJvcHNbcHJvcE5hbWVdID0gdGhpcy50cmFuc2Zvcm1WYWx1ZShjdXJyZW50UGF0aCwgcHJvcE5hbWUsIHByb3BWYWx1ZSk7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChub2RlLmtleSkge1xuXHRcdFx0XHRuZXdQcm9wcy5rZXkgPSBub2RlLmtleTtcblx0XHRcdH1cblxuXHRcdFx0Y29uc3QgcmVuZGVyZWRDaGlsZHJlbiA9IFtdO1xuXHRcdFx0Zm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGNoaWxkcmVuLmxlbmd0aDsgaW5kZXggKz0gMSkge1xuXHRcdFx0XHRjb25zdCBjaGlsZCA9IGNoaWxkcmVuW2luZGV4XSE7XG5cdFx0XHRcdGNvbnN0IGNoaWxkUGF0aCA9IGN1cnJlbnRQYXRoID8gYCR7Y3VycmVudFBhdGh9LiR7aW5kZXh9YCA6IFN0cmluZyhpbmRleCk7XG5cdFx0XHRcdHJlbmRlcmVkQ2hpbGRyZW4ucHVzaCh0aGlzLnJlbmRlck5vZGUoY2hpbGQsIGNoaWxkUGF0aCkpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoaXNNb3VudFBvaW50Tm9kZShub2RlKSkge1xuXHRcdFx0XHRjb25zdCBjb21wb25lbnRLZXkgPSBub2RlLnRhZy5zbGljZShNT1VOVF9QT0lOVF9QUkVGSVgubGVuZ3RoKTtcblx0XHRcdFx0Y29uc3QgQ29tcG9uZW50ID0gdGhpcy4jY29tcG9uZW50c1tjb21wb25lbnRLZXldITtcblx0XHRcdFx0aWYgKCFDb21wb25lbnQpIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoXG5cdFx0XHRcdFx0XHRgQ291bGQgbm90IGZpbmQgY29tcG9uZW50ICR7Y29tcG9uZW50S2V5fS4gVGhpcyBpcyBhIFB1bHNlIGludGVybmFsIGVycm9yLmAsXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gY3JlYXRlRWxlbWVudChDb21wb25lbnQsIG5ld1Byb3BzLCAuLi5yZW5kZXJlZENoaWxkcmVuKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGNyZWF0ZUVsZW1lbnQodGFnID09PSBGUkFHTUVOVF9UQUcgPyBGcmFnbWVudCA6IHRhZywgbmV3UHJvcHMsIC4uLnJlbmRlcmVkQ2hpbGRyZW4pO1xuXHRcdH1cblxuXHRcdC8vIEZhbGxiYWNrIGZvciB1bmtub3duIG5vZGUgdHlwZXNcblx0XHRpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwicHJvZHVjdGlvblwiKSB7XG5cdFx0XHRjb25zb2xlLmVycm9yKFwiVW5rbm93biBWRE9NIG5vZGUgdHlwZTpcIiwgbm9kZSk7XG5cdFx0fVxuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0I3Byb3BQYXRoKHBhdGg6IHN0cmluZywgcHJvcDogc3RyaW5nKSB7XG5cdFx0cmV0dXJuIHBhdGggPyBgJHtwYXRofS4ke3Byb3B9YCA6IHByb3A7XG5cdH1cblxuXHR0cmFuc2Zvcm1WYWx1ZShwYXRoOiBzdHJpbmcsIGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSB7XG5cdFx0Y29uc3QgcHJvcFBhdGggPSB0aGlzLiNwcm9wUGF0aChwYXRoLCBrZXkpO1xuXHRcdGlmICh0aGlzLiNjYWxsYmFja3MuaGFzKHByb3BQYXRoKSkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZ2V0Q2FsbGJhY2socGF0aCwga2V5KTtcblx0XHR9XG5cdFx0aWYgKHRoaXMuI3JlbmRlclByb3BLZXlzLmhhcyhwcm9wUGF0aCkpIHtcblx0XHRcdHJldHVybiB0aGlzLnJlbmRlck5vZGUodmFsdWUsIHByb3BQYXRoKTtcblx0XHR9XG5cdFx0aWYgKHRoaXMuI2Nzc1Byb3BzLmhhcyhwcm9wUGF0aCkpIHtcblx0XHRcdHJldHVybiB0aGlzLiNyZXNvbHZlQ3NzVG9rZW4odmFsdWUpO1xuXHRcdH1cblx0XHRyZXR1cm4gdmFsdWU7XG5cdH1cblxuXHQjcmVzb2x2ZUNzc1Rva2VuKHRva2VuOiBzdHJpbmcpOiBzdHJpbmcge1xuXHRcdGNvbnN0IGlkeCA9IHRva2VuLmluZGV4T2YoXCI6XCIpO1xuXHRcdGlmIChpZHggPT09IC0xKSB7XG5cdFx0XHRyZXR1cm4gdG9rZW47XG5cdFx0fVxuXHRcdGNvbnN0IG1vZHVsZUlkID0gdG9rZW4uc2xpY2UoMCwgaWR4KTtcblx0XHRjb25zdCBjbGFzc05hbWUgPSB0b2tlbi5zbGljZShpZHggKyAxKTtcblx0XHRpZiAoIW1vZHVsZUlkIHx8ICFjbGFzc05hbWUpIHtcblx0XHRcdHJldHVybiB0b2tlbjtcblx0XHR9XG5cdFx0Y29uc3QgbW9kID0gdGhpcy4jY3NzTW9kdWxlc1ttb2R1bGVJZF07XG5cdFx0aWYgKCFtb2QpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihgUmVjZWl2ZWQgQ1NTIHJlZmVyZW5jZSBmb3IgdW5rbm93biBtb2R1bGUgJyR7bW9kdWxlSWR9J2ApO1xuXHRcdH1cblx0XHRjb25zdCByZXNvbHZlZCA9IG1vZFtjbGFzc05hbWVdO1xuXHRcdGlmICh0eXBlb2YgcmVzb2x2ZWQgIT09IFwic3RyaW5nXCIpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihcblx0XHRcdFx0YFJlY2VpdmVkIENTUyByZWZlcmVuY2UgZm9yIG1pc3NpbmcgY2xhc3MgJyR7Y2xhc3NOYW1lfScgaW4gbW9kdWxlICcke21vZHVsZUlkfSdgLFxuXHRcdFx0KTtcblx0XHR9XG5cdFx0cmV0dXJuIHJlc29sdmVkO1xuXHR9XG5cblx0aW5pdCh2ZG9tOiBWRE9NLCBjYWxsYmFja3M6IHN0cmluZ1tdLCByZW5kZXJQcm9wczogc3RyaW5nW10sIGNzc1JlZnM6IHN0cmluZ1tdKTogUmVhY3ROb2RlIHtcblx0XHQvLyBTZXQgY2FsbGJhY2tzXG5cdFx0dGhpcy4jY2FsbGJhY2tzID0gbmV3IFNldChjYWxsYmFja3MpO1xuXHRcdC8vIHBydW5lIHN0YWxlIGNhY2hlZCBjYWxsYmFja3Ncblx0XHRmb3IgKGNvbnN0IGsgb2YgQXJyYXkuZnJvbSh0aGlzLiNjYWxsYmFja0NhY2hlLmtleXMoKSkpIHtcblx0XHRcdGlmICghdGhpcy4jY2FsbGJhY2tzLmhhcyhrKSkgdGhpcy4jY2FsbGJhY2tDYWNoZS5kZWxldGUoayk7XG5cdFx0fVxuXHRcdHRoaXMuI2NhbGxiYWNrTGlzdCA9IFsuLi50aGlzLiNjYWxsYmFja3NdLnNvcnQoKTtcblxuXHRcdC8vIFNldCByZW5kZXIgcHJvcHNcblx0XHR0aGlzLiNyZW5kZXJQcm9wS2V5cyA9IG5ldyBTZXQocmVuZGVyUHJvcHMpO1xuXG5cdFx0Ly8gU2V0IENTUyByZWZzXG5cdFx0dGhpcy4jY3NzUHJvcHMgPSBuZXcgU2V0KGNzc1JlZnMpO1xuXG5cdFx0cmV0dXJuIHRoaXMucmVuZGVyTm9kZSh2ZG9tKTtcblx0fVxuXG5cdCNlbnN1cmVDaGlsZHJlbkFycmF5KGVsOiBSZWFjdEVsZW1lbnQpOiBSZWFjdE5vZGVbXSB7XG5cdFx0Y29uc3QgY2hpbGRyZW4gPSAoZWwucHJvcHMgYXMgYW55KT8uY2hpbGRyZW4gYXMgUmVhY3ROb2RlIHwgdW5kZWZpbmVkO1xuXHRcdGlmIChjaGlsZHJlbiA9PSBudWxsKSByZXR1cm4gW107XG5cdFx0cmV0dXJuIEFycmF5LmlzQXJyYXkoY2hpbGRyZW4pID8gY2hpbGRyZW4uc2xpY2UoKSA6IFtjaGlsZHJlbl07XG5cdH1cblxuXHRhcHBseVVwZGF0ZXMoaW5pdGlhbFRyZWU6IFJlYWN0Tm9kZSwgdXBkYXRlczogVkRPTVVwZGF0ZVtdKTogUmVhY3ROb2RlIHtcblx0XHRsZXQgbmV3VHJlZTogUmVhY3ROb2RlID0gaW5pdGlhbFRyZWU7XG5cdFx0Zm9yIChjb25zdCB1cGRhdGUgb2YgdXBkYXRlcykge1xuXHRcdFx0aWYgKHVwZGF0ZS50eXBlID09PSBcInVwZGF0ZV9jYWxsYmFja3NcIikge1xuXHRcdFx0XHR0aGlzLmFwcGx5Q2FsbGJhY2tEZWx0YSh1cGRhdGUuZGF0YSk7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXHRcdFx0aWYgKHVwZGF0ZS50eXBlID09PSBcInVwZGF0ZV9jc3NfcmVmc1wiKSB7XG5cdFx0XHRcdHRoaXMuYXBwbHlDc3NSZWZzRGVsdGEodXBkYXRlLmRhdGEpO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblx0XHRcdGlmICh1cGRhdGUudHlwZSA9PT0gXCJ1cGRhdGVfcmVuZGVyX3Byb3BzXCIpIHtcblx0XHRcdFx0dGhpcy5hcHBseVJlbmRlclByb3BzRGVsdGEodXBkYXRlLmRhdGEpO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0Y29uc3QgcGFydHMgPSB1cGRhdGUucGF0aC5zcGxpdChcIi5cIikuZmlsdGVyKChzKSA9PiBzLmxlbmd0aCA+IDApO1xuXG5cdFx0XHRjb25zdCBkZXNjZW5kID0gKG5vZGU6IFJlYWN0Tm9kZSwgZGVwdGg6IG51bWJlciwgcGF0aDogc3RyaW5nKTogUmVhY3ROb2RlID0+IHtcblx0XHRcdFx0aWYgKGRlcHRoIDwgcGFydHMubGVuZ3RoKSB7XG5cdFx0XHRcdFx0dGhpcy4jYXNzZXJ0SXNFbGVtZW50KG5vZGUsIHBhcnRzLCBkZXB0aCk7XG5cdFx0XHRcdFx0Y29uc3QgZWxlbWVudCA9IG5vZGUgYXMgUmVhY3RFbGVtZW50PFJlY29yZDxzdHJpbmcsIGFueT4gfCBudWxsPjtcblx0XHRcdFx0XHRjb25zdCBjaGlsZEtleSA9IHBhcnRzW2RlcHRoXSE7XG5cdFx0XHRcdFx0Y29uc3QgY2hpbGRJZHggPSArY2hpbGRLZXk7XG5cdFx0XHRcdFx0Y29uc3QgY2hpbGRQYXRoID0gcGF0aCA/IGAke3BhdGh9LiR7Y2hpbGRLZXl9YCA6IGNoaWxkS2V5O1xuXHRcdFx0XHRcdGlmICghTnVtYmVyLmlzTmFOKGNoaWxkSWR4KSkge1xuXHRcdFx0XHRcdFx0Ly8gUmVndWxhciBjaGlsZCB0cmF2ZXJzYWxcblx0XHRcdFx0XHRcdGNvbnN0IGNoaWxkcmVuQXJyID0gdGhpcy4jZW5zdXJlQ2hpbGRyZW5BcnJheShlbGVtZW50KTtcblx0XHRcdFx0XHRcdGNvbnN0IGNoaWxkID0gY2hpbGRyZW5BcnJbY2hpbGRJZHhdO1xuXHRcdFx0XHRcdFx0Y2hpbGRyZW5BcnJbY2hpbGRJZHhdID0gZGVzY2VuZChjaGlsZCwgZGVwdGggKyAxLCBjaGlsZFBhdGgpIGFzIGFueTtcblx0XHRcdFx0XHRcdHJldHVybiBjbG9uZUVsZW1lbnQoZWxlbWVudCwgdW5kZWZpbmVkLCAuLi5jaGlsZHJlbkFycik7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdC8vIFJlbmRlciBwcm9wIHRyYXZlcnNhbFxuXHRcdFx0XHRcdFx0Y29uc3QgYmFzZVByb3BzID0gKGVsZW1lbnQucHJvcHMgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIGFueT47XG5cdFx0XHRcdFx0XHRjb25zdCBjaGlsZCA9IGJhc2VQcm9wc1tjaGlsZEtleV07XG5cdFx0XHRcdFx0XHRjb25zdCBwcm9wcyA9IHtcblx0XHRcdFx0XHRcdFx0Li4uYmFzZVByb3BzLFxuXHRcdFx0XHRcdFx0XHRbY2hpbGRLZXldOiBkZXNjZW5kKGNoaWxkLCBkZXB0aCArIDEsIGNoaWxkUGF0aCksXG5cdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0cmV0dXJuIGNsb25lRWxlbWVudChlbGVtZW50LCBwcm9wcyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHN3aXRjaCAodXBkYXRlLnR5cGUpIHtcblx0XHRcdFx0XHRjYXNlIFwicmVwbGFjZVwiOiB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdGhpcy5yZW5kZXJOb2RlKHVwZGF0ZS5kYXRhLCB1cGRhdGUucGF0aCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNhc2UgXCJ1cGRhdGVfcHJvcHNcIjoge1xuXHRcdFx0XHRcdFx0dGhpcy4jYXNzZXJ0SXNFbGVtZW50KG5vZGUsIHBhcnRzLCBkZXB0aCk7XG5cdFx0XHRcdFx0XHRjb25zdCBlbGVtZW50ID0gbm9kZSBhcyBSZWFjdEVsZW1lbnQ7XG5cdFx0XHRcdFx0XHRjb25zdCBjdXJyZW50UHJvcHMgPSAoZWxlbWVudC5wcm9wcyA/PyB7fSkgYXMgUmVjb3JkPHN0cmluZywgYW55Pjtcblx0XHRcdFx0XHRcdGNvbnN0IG5leHRQcm9wczogUmVjb3JkPHN0cmluZywgYW55PiA9IHsgLi4uY3VycmVudFByb3BzIH07XG5cdFx0XHRcdFx0XHRjb25zdCBkZWx0YSA9IHVwZGF0ZS5kYXRhO1xuXHRcdFx0XHRcdFx0aWYgKGRlbHRhLnJlbW92ZSAmJiBkZWx0YS5yZW1vdmUubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRcdFx0XHRmb3IgKGNvbnN0IGtleSBvZiBkZWx0YS5yZW1vdmUpIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoa2V5IGluIG5leHRQcm9wcykge1xuXHRcdFx0XHRcdFx0XHRcdFx0ZGVsZXRlIG5leHRQcm9wc1trZXldO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYgKGRlbHRhLnNldCkge1xuXHRcdFx0XHRcdFx0XHRmb3IgKGNvbnN0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyhkZWx0YS5zZXQpKSB7XG5cdFx0XHRcdFx0XHRcdFx0bmV4dFByb3BzW2tdID0gdGhpcy50cmFuc2Zvcm1WYWx1ZShwYXRoLCBrLCB2KTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBJZiBzb21lIHByb3BzIHdlcmUgcmVtb3ZlZCwgdXNlIGBjcmVhdGVFbGVtZW50YCB0byBmdWxseSBvdmVycmlkZVxuXHRcdFx0XHRcdFx0Ly8gdGhlIHByb3BzLCBhcyBgY2xvbmVFbGVtZW50YCBzaGFsbG93bHkgbWVyZ2VzIHRoZSBuZXcgcHJvcHMgd2l0aFxuXHRcdFx0XHRcdFx0Ly8gdGhlIG9sZCBvbmVzLlxuXHRcdFx0XHRcdFx0Y29uc3QgcmVtb3ZlZFNvbWV0aGluZyA9IChkZWx0YS5yZW1vdmU/Lmxlbmd0aCA/PyAwKSA+IDA7XG5cdFx0XHRcdFx0XHRpZiAocmVtb3ZlZFNvbWV0aGluZykge1xuXHRcdFx0XHRcdFx0XHQvLyBQcmVzZXJ2ZSBrZXkgKyByZWZcblx0XHRcdFx0XHRcdFx0bmV4dFByb3BzLmtleSA9IGVsZW1lbnQua2V5O1xuXHRcdFx0XHRcdFx0XHRuZXh0UHJvcHMucmVmID0gKGVsZW1lbnQgYXMgYW55KS5yZWY7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBjcmVhdGVFbGVtZW50KGVsZW1lbnQudHlwZSwgbmV4dFByb3BzLCAuLi50aGlzLiNlbnN1cmVDaGlsZHJlbkFycmF5KGVsZW1lbnQpKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdC8vIERvbid0IHRvdWNoIGNoaWxkcmVuLiBLZXkgYW5kIHJlZiBhcmUgdHJhbnNmZXJyZWQgYnkgY2xvbmVFbGVtZW50LlxuXHRcdFx0XHRcdFx0XHRyZXR1cm4gY2xvbmVFbGVtZW50KGVsZW1lbnQsIG5leHRQcm9wcyk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNhc2UgXCJyZWNvbmNpbGlhdGlvblwiOiB7XG5cdFx0XHRcdFx0XHR0aGlzLiNhc3NlcnRJc0VsZW1lbnQobm9kZSwgcGFydHMsIGRlcHRoKTtcblx0XHRcdFx0XHRcdGNvbnN0IGVsZW1lbnQgPSBub2RlIGFzIFJlYWN0RWxlbWVudDtcblx0XHRcdFx0XHRcdGNvbnN0IHByZXZDaGlsZHJlbiA9IHRoaXMuI2Vuc3VyZUNoaWxkcmVuQXJyYXkoZWxlbWVudCk7XG5cdFx0XHRcdFx0XHRjb25zdCBuZXh0Q2hpbGRyZW4gPSBbXTtcblxuXHRcdFx0XHRcdFx0Y29uc3QgW25ld0luZGljZXMsIG5ld0NvbnRlbnRzXSA9IHVwZGF0ZS5uZXc7XG5cdFx0XHRcdFx0XHRjb25zdCBbcmV1c2VJbmRpY2VzLCByZXVzZVNvdXJjZXNdID0gdXBkYXRlLnJldXNlO1xuXG5cdFx0XHRcdFx0XHRsZXQgbmV4dE5ldyA9IC0xLFxuXHRcdFx0XHRcdFx0XHRuZXh0UmV1c2UgPSAtMSxcblx0XHRcdFx0XHRcdFx0bmV3SWR4ID0gLTEsXG5cdFx0XHRcdFx0XHRcdHJldXNlSWR4ID0gLTE7XG5cdFx0XHRcdFx0XHRpZiAobmV3SW5kaWNlcy5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdFx0XHRcdG5leHROZXcgPSBuZXdJbmRpY2VzWzBdO1xuXHRcdFx0XHRcdFx0XHRuZXdJZHggPSAwO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYgKHJldXNlSW5kaWNlcy5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdFx0XHRcdG5leHRSZXVzZSA9IHJldXNlSW5kaWNlc1swXTtcblx0XHRcdFx0XHRcdFx0cmV1c2VJZHggPSAwO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB1cGRhdGUuTjsgKytpKSB7XG5cdFx0XHRcdFx0XHRcdGlmIChpID09PSBuZXh0TmV3KSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgY29udGVudHMgPSBuZXdDb250ZW50c1tuZXdJZHhdO1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IGNoaWxkUGF0aCA9IHBhdGggPyBgJHtwYXRofS4ke2l9YCA6IFN0cmluZyhpKTtcblx0XHRcdFx0XHRcdFx0XHRuZXh0Q2hpbGRyZW4ucHVzaCh0aGlzLnJlbmRlck5vZGUoY29udGVudHMsIGNoaWxkUGF0aCkpO1xuXHRcdFx0XHRcdFx0XHRcdG5leHROZXcgPSBuZXdJZHggPCBuZXdJbmRpY2VzLmxlbmd0aCAtIDEgPyBuZXdJbmRpY2VzWysrbmV3SWR4XSA6IC0xO1xuXHRcdFx0XHRcdFx0XHR9IGVsc2UgaWYgKGkgPT09IG5leHRSZXVzZSkge1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IHNyY0lkeCA9IHJldXNlU291cmNlc1tyZXVzZUlkeF07XG5cdFx0XHRcdFx0XHRcdFx0bGV0IHNyYyA9IHByZXZDaGlsZHJlbltzcmNJZHhdO1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IGNoaWxkUGF0aCA9IHBhdGggPyBgJHtwYXRofS4ke2l9YCA6IFN0cmluZyhpKTtcblx0XHRcdFx0XHRcdFx0XHQvLyBUaGUgbm9kZSBtYXkgaGF2ZSBjYWxsYmFja3MgdGhhdCBuZWVkIHRvIGJlIHVwZGF0ZWQgZm9yIHRoaXMgbmV3IHBhdGhcblx0XHRcdFx0XHRcdFx0XHRpZiAodGhpcy5oYXNBbnlDYWxsYmFja1VuZGVyKGNoaWxkUGF0aCkpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHNyYyA9IHRoaXMuI3JlYmluZENhbGxiYWNrc0luU3VidHJlZShzcmMsIGNoaWxkUGF0aCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdG5leHRDaGlsZHJlbi5wdXNoKHNyYyk7XG5cdFx0XHRcdFx0XHRcdFx0bmV4dFJldXNlID0gcmV1c2VJZHggPCByZXVzZUluZGljZXMubGVuZ3RoIC0gMSA/IHJldXNlSW5kaWNlc1srK3JldXNlSWR4XSA6IC0xO1xuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdC8vIE5vIG5lZWQgdG8gcmViaW5kIGNhbGxiYWNrcywgdGhlIG5vZGUgaGFzbid0IG1vdmVkXG5cdFx0XHRcdFx0XHRcdFx0bmV4dENoaWxkcmVuLnB1c2gocHJldkNoaWxkcmVuW2ldKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0Ly8gUGFzcyBudWxsIHRvIHJldXNlIHByZXZpb3VzIHByb3BzXG5cdFx0XHRcdFx0XHRyZXR1cm4gY2xvbmVFbGVtZW50KGVsZW1lbnQsIG51bGwhLCAuLi5uZXh0Q2hpbGRyZW4pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKGBbUHVsc2UgcmVuZGVyZXJdIFVua25vd24gdXBkYXRlIHR5cGU6ICR7KHVwZGF0ZSBhcyBhbnkpPy50eXBlfWApO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0XHRuZXdUcmVlID0gZGVzY2VuZChuZXdUcmVlLCAwLCBcIlwiKTtcblx0XHR9XG5cdFx0cmV0dXJuIG5ld1RyZWU7XG5cdH1cblxuXHQjYXNzZXJ0SXNFbGVtZW50KG5vZGU6IFJlYWN0Tm9kZSwgcGFydHM6IHN0cmluZ1tdLCBkZXB0aDogbnVtYmVyKTogbm9kZSBpcyBSZWFjdEVsZW1lbnQge1xuXHRcdGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIgJiYgIWlzVmFsaWRFbGVtZW50KG5vZGUpKSB7XG5cdFx0XHRjb25zb2xlLmVycm9yKFwiSW52YWxpZCBub2RlOlwiLCBub2RlKTtcblx0XHRcdHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBub2RlIGF0IHBhdGggJHtwYXJ0cy5zbGljZSgwLCBkZXB0aCkuam9pbihcIi5cIil9YCk7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0Ly8gUmViaW5kIGNhbGxiYWNrIGZ1bmN0aW9uIHByb3BzIHdpdGhpbiBhIHN1YnRyZWUgYWZ0ZXIgYSBwYXRoLWNoYW5naW5nIG1vdmVcblx0I3JlYmluZENhbGxiYWNrc0luU3VidHJlZShub2RlOiBSZWFjdE5vZGUsIHBhdGg6IHN0cmluZyk6IFJlYWN0Tm9kZSB7XG5cdFx0aWYgKCFpc1ZhbGlkRWxlbWVudChub2RlKSkgcmV0dXJuIG5vZGU7XG5cdFx0Y29uc3QgZWxlbWVudCA9IG5vZGUgYXMgUmVhY3RFbGVtZW50PFJlY29yZDxzdHJpbmcsIGFueT4gfCBudWxsPjtcblx0XHRjb25zdCBiYXNlUHJvcHMgPSAoZWxlbWVudC5wcm9wcyA/PyB7fSkgYXMgUmVjb3JkPHN0cmluZywgYW55Pjtcblx0XHRjb25zdCBuZXh0UHJvcHM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7IC4uLmJhc2VQcm9wcyB9O1xuXG5cdFx0Ly8gUmViaW5kIG9ubHkgY2FsbGJhY2sgcHJvcHM7IENTUyByZWZzIGFyZSBwYXRoLWFnbm9zdGljIGFuZCByZW5kZXItcHJvcHNcblx0XHQvLyBhcmUgaGFuZGxlZCBieSB0aGUgc2VydmVyLXNpZGUgcmVuZGVyZXIgdmlhIGV4cGxpY2l0IHVwZGF0ZXNcblx0XHRmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhiYXNlUHJvcHMpKSB7XG5cdFx0XHRjb25zdCBwcm9wUGF0aCA9IHBhdGggPyBgJHtwYXRofS4ke2tleX1gIDoga2V5O1xuXHRcdFx0aWYgKHRoaXMuaGFzQ2FsbGJhY2tQYXRoKHByb3BQYXRoKSkge1xuXHRcdFx0XHRuZXh0UHJvcHNba2V5XSA9IHRoaXMuZ2V0Q2FsbGJhY2socGF0aCwga2V5KTtcblx0XHRcdH1cblx0XHRcdGlmICh0aGlzLmhhc1JlbmRlclByb3BQYXRoKHByb3BQYXRoKSAmJiB0aGlzLmhhc0FueUNhbGxiYWNrVW5kZXIocHJvcFBhdGgpKSB7XG5cdFx0XHRcdG5leHRQcm9wc1trZXldID0gdGhpcy4jcmViaW5kQ2FsbGJhY2tzSW5TdWJ0cmVlKGJhc2VQcm9wc1trZXldLCBwcm9wUGF0aCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Y29uc3QgY2hpbGRyZW4gPSB0aGlzLiNlbnN1cmVDaGlsZHJlbkFycmF5KGVsZW1lbnQpLm1hcCgoY2hpbGQsIGlkeCkgPT4ge1xuXHRcdFx0Y29uc3QgY2hpbGRQYXRoID0gcGF0aCA/IGAke3BhdGh9LiR7aWR4fWAgOiBTdHJpbmcoaWR4KTtcblx0XHRcdGlmICh0aGlzLmhhc0FueUNhbGxiYWNrVW5kZXIoY2hpbGRQYXRoKSkge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy4jcmViaW5kQ2FsbGJhY2tzSW5TdWJ0cmVlKGNoaWxkLCBjaGlsZFBhdGgpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuIGNoaWxkO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIGNsb25lRWxlbWVudChlbGVtZW50LCBuZXh0UHJvcHMsIC4uLmNoaWxkcmVuKTtcblx0fVxuXG5cdC8vIEJpbmFyeS1zZWFyY2ggbG93ZXIgYm91bmQgZm9yIHByZWZpeCBtYXRjaGluZyBvbiBzb3J0ZWQgY2FsbGJhY2sgcGF0aHNcblx0I2xvd2VyQm91bmQoYXJyOiBzdHJpbmdbXSwgdGFyZ2V0OiBzdHJpbmcpOiBudW1iZXIge1xuXHRcdGxldCBsbyA9IDA7XG5cdFx0bGV0IGhpID0gYXJyLmxlbmd0aDtcblx0XHR3aGlsZSAobG8gPCBoaSkge1xuXHRcdFx0Y29uc3QgbWlkID0gKGxvICsgaGkpID4+PiAxO1xuXHRcdFx0aWYgKGFyclttaWRdISA8IHRhcmdldCkge1xuXHRcdFx0XHRsbyA9IG1pZCArIDE7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRoaSA9IG1pZDtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGxvO1xuXHR9XG59XG5cbi8vIFRoZSBgY29tcG9uZW50YCBwcm9wIHNob3VsZCBiZSBzb21ldGhpbmcgbGlrZSBgKCkgPT5cbi8vIGltcG9ydCgnfi9wYXRoL3RvL2NvbXBvbmVudCcpICh3ZSdsbCBuZWVkIHRvIHJlbWFwIGlmIHdlJ3JlIGltcG9ydGluZyBhIG5hbWVkIGV4cG9ydCBhbmQgbm90IHRoZSBkZWZhdWx0KVxuZXhwb3J0IGZ1bmN0aW9uIFJlbmRlckxhenkoXG5cdGNvbXBvbmVudDogKCkgPT4gUHJvbWlzZTx7IGRlZmF1bHQ6IENvbXBvbmVudFR5cGU8YW55PiB9Pixcblx0ZmFsbGJhY2s/OiBSZWFjdE5vZGUsXG4pOiBGQzxQcm9wc1dpdGhDaGlsZHJlbjx1bmtub3duPj4ge1xuXHRjb25zdCBDb21wb25lbnQgPSBsYXp5KGNvbXBvbmVudCk7XG5cdHJldHVybiAoeyBjaGlsZHJlbiwgLi4ucHJvcHMgfTogUHJvcHNXaXRoQ2hpbGRyZW48dW5rbm93bj4pID0+IHtcblx0XHRyZXR1cm4gKFxuXHRcdFx0PFN1c3BlbnNlIGZhbGxiYWNrPXtmYWxsYmFja30+XG5cdFx0XHRcdDxDb21wb25lbnQgey4uLnByb3BzfT57Y2hpbGRyZW59PC9Db21wb25lbnQ+XG5cdFx0XHQ8L1N1c3BlbnNlPlxuXHRcdCk7XG5cdH07XG59XG4iLAogICAgImltcG9ydCB0eXBlIHsgQ29tcG9uZW50VHlwZSB9IGZyb20gXCJyZWFjdFwiO1xuXG4vLyBTcGVjaWFsIHByZWZpeGVzIGZvciByZXNlcnZlZCBub2RlIHR5cGVzXG5leHBvcnQgY29uc3QgRlJBR01FTlRfVEFHID0gXCIkJGZyYWdtZW50XCI7XG5leHBvcnQgY29uc3QgTU9VTlRfUE9JTlRfUFJFRklYID0gXCIkJFwiO1xuXG4vLyBleHBvcnQgdHlwZSBMYXp5Q29tcG9uZW50ID0gKCkgPT4gUHJvbWlzZTx7IGRlZmF1bHQ6IENvbXBvbmVudFR5cGU8YW55PiB9PjtcbmV4cG9ydCB0eXBlIFJlZ2lzdHJ5RW50cnkgPSBDb21wb25lbnRUeXBlPGFueT47XG5leHBvcnQgdHlwZSBDb21wb25lbnRSZWdpc3RyeSA9IFJlY29yZDxzdHJpbmcsIENvbXBvbmVudFR5cGU8YW55Pj47XG5cbmV4cG9ydCBpbnRlcmZhY2UgVkRPTUVsZW1lbnQge1xuXHR0YWc6IHN0cmluZztcblx0cHJvcHM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuXHRjaGlsZHJlbj86IFZET01Ob2RlW107XG5cdGtleT86IHN0cmluZztcblx0bGF6eT86IGJvb2xlYW47XG59XG5cbi8vIFByaW1pdGl2ZSBub2RlcyB0aGF0IGNhbiBiZSByZW5kZXJlZFxuZXhwb3J0IHR5cGUgUHJpbWl0aXZlTm9kZSA9IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW47XG5cbi8vIFZET01Ob2RlIGlzIGVpdGhlciBhIHByaW1pdGl2ZSAoc3RyaW5nLCBudW1iZXIsIGJvb2xlYW4pIG9yIGFuIGVsZW1lbnQgbm9kZS5cbi8vIEJvb2xlYW5zIGFyZSB2YWxpZCBjaGlsZHJlbiBpbiBSZWFjdCBidXQgZG8gbm90IHJlbmRlciBhbnl0aGluZy5cbi8vIE1vdW50IHBvaW50cyBhcmUganVzdCBVSUVsZW1lbnROb2RlcyB3aXRoIHRhZ3Mgc3RhcnRpbmcgd2l0aCAkJENvbXBvbmVudEtleVxuZXhwb3J0IHR5cGUgVkRPTU5vZGUgPSBQcmltaXRpdmVOb2RlIHwgVkRPTUVsZW1lbnQ7XG5cbmV4cG9ydCB0eXBlIFZET00gPSBWRE9NTm9kZTtcblxuZXhwb3J0IGludGVyZmFjZSBWRE9NVXBkYXRlQmFzZSB7XG5cdHR5cGU6IHN0cmluZztcblx0cGF0aDogc3RyaW5nOyAvLyBEb3Qtc2VwYXJhdGVkIHBhdGggdG8gdGhlIG5vZGVcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXBsYWNlVXBkYXRlIGV4dGVuZHMgVkRPTVVwZGF0ZUJhc2Uge1xuXHR0eXBlOiBcInJlcGxhY2VcIjtcblx0ZGF0YTogVkRPTU5vZGU7IC8vIFRoZSBuZXcgbm9kZVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVwZGF0ZVByb3BzVXBkYXRlIGV4dGVuZHMgVkRPTVVwZGF0ZUJhc2Uge1xuXHR0eXBlOiBcInVwZGF0ZV9wcm9wc1wiO1xuXHRkYXRhOiB7XG5cdFx0c2V0PzogUmVjb3JkPHN0cmluZywgYW55Pjtcblx0XHRyZW1vdmU/OiBzdHJpbmdbXTtcblx0fTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWNvbmNpbGlhdGlvblVwZGF0ZSB7XG5cdHR5cGU6IFwicmVjb25jaWxpYXRpb25cIjtcblx0cGF0aDogc3RyaW5nO1xuXHROOiBudW1iZXI7XG5cdG5ldzogW251bWJlcltdLCBWRE9NW11dO1xuXHRyZXVzZTogW251bWJlcltdLCBudW1iZXJbXV07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGF0aERlbHRhIHtcblx0YWRkPzogc3RyaW5nW107XG5cdHJlbW92ZT86IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVwZGF0ZUNhbGxiYWNrc1VwZGF0ZSBleHRlbmRzIFZET01VcGRhdGVCYXNlIHtcblx0dHlwZTogXCJ1cGRhdGVfY2FsbGJhY2tzXCI7XG5cdGRhdGE6IFBhdGhEZWx0YTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVcGRhdGVSZW5kZXJQcm9wc1VwZGF0ZSBleHRlbmRzIFZET01VcGRhdGVCYXNlIHtcblx0dHlwZTogXCJ1cGRhdGVfcmVuZGVyX3Byb3BzXCI7XG5cdGRhdGE6IFBhdGhEZWx0YTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVcGRhdGVDc3NSZWZzVXBkYXRlIGV4dGVuZHMgVkRPTVVwZGF0ZUJhc2Uge1xuXHR0eXBlOiBcInVwZGF0ZV9jc3NfcmVmc1wiO1xuXHRkYXRhOiBQYXRoRGVsdGE7XG59XG5cbmV4cG9ydCB0eXBlIFZET01VcGRhdGUgPVxuXHR8IFJlcGxhY2VVcGRhdGVcblx0fCBVcGRhdGVQcm9wc1VwZGF0ZVxuXHR8IFJlY29uY2lsaWF0aW9uVXBkYXRlXG5cdHwgVXBkYXRlQ2FsbGJhY2tzVXBkYXRlXG5cdHwgVXBkYXRlUmVuZGVyUHJvcHNVcGRhdGVcblx0fCBVcGRhdGVDc3NSZWZzVXBkYXRlO1xuXG5leHBvcnQgdHlwZSBVcGRhdGVUeXBlID0gVkRPTVVwZGF0ZVtcInR5cGVcIl07XG5cbi8vIFV0aWxpdHkgZnVuY3Rpb25zIGZvciB3b3JraW5nIHdpdGggdGhlIFVJIHRyZWUgc3RydWN0dXJlXG5leHBvcnQgZnVuY3Rpb24gaXNFbGVtZW50Tm9kZShub2RlOiBWRE9NTm9kZSk6IG5vZGUgaXMgVkRPTUVsZW1lbnQge1xuXHQvLyBNYXRjaGVzIGFsbCBub24tdGV4dCBub2Rlc1xuXHRyZXR1cm4gdHlwZW9mIG5vZGUgPT09IFwib2JqZWN0XCIgJiYgbm9kZSAhPT0gbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTW91bnRQb2ludE5vZGUobm9kZTogVkRPTU5vZGUpOiBub2RlIGlzIFZET01FbGVtZW50IHtcblx0cmV0dXJuIChcblx0XHR0eXBlb2Ygbm9kZSA9PT0gXCJvYmplY3RcIiAmJlxuXHRcdG5vZGUgIT09IG51bGwgJiZcblx0XHRub2RlLnRhZy5zdGFydHNXaXRoKE1PVU5UX1BPSU5UX1BSRUZJWCkgJiZcblx0XHRub2RlLnRhZyAhPT0gRlJBR01FTlRfVEFHXG5cdCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1RleHROb2RlKG5vZGU6IFZET01Ob2RlKTogbm9kZSBpcyBzdHJpbmcge1xuXHRyZXR1cm4gdHlwZW9mIG5vZGUgPT09IFwic3RyaW5nXCI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0ZyYWdtZW50KG5vZGU6IFZET01Ob2RlKTogYm9vbGVhbiB7XG5cdHJldHVybiB0eXBlb2Ygbm9kZSA9PT0gXCJvYmplY3RcIiAmJiBub2RlICE9PSBudWxsICYmIG5vZGUudGFnID09PSBGUkFHTUVOVF9UQUc7XG59XG4iLAogICAgImltcG9ydCB7IHVzZUVmZmVjdCwgdXNlTWVtbyB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHR5cGUgeyBDaGFubmVsQnJpZGdlIH0gZnJvbSBcIi4vY2hhbm5lbFwiO1xuaW1wb3J0IHsgdXNlUHVsc2VDbGllbnQgfSBmcm9tIFwiLi9wdWxzZVwiO1xuXG5leHBvcnQgZnVuY3Rpb24gdXNlUHVsc2VDaGFubmVsKGNoYW5uZWxJZDogc3RyaW5nKTogQ2hhbm5lbEJyaWRnZSB7XG5cdGNvbnN0IGNsaWVudCA9IHVzZVB1bHNlQ2xpZW50KCk7XG5cdGNvbnN0IGJyaWRnZSA9IHVzZU1lbW8oKCkgPT4ge1xuXHRcdGlmICghY2hhbm5lbElkKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJ1c2VQdWxzZUNoYW5uZWwgcmVxdWlyZXMgYSBub24tZW1wdHkgY2hhbm5lbElkXCIpO1xuXHRcdH1cblx0XHRyZXR1cm4gY2xpZW50LmFjcXVpcmVDaGFubmVsKGNoYW5uZWxJZCk7XG5cdH0sIFtjbGllbnQsIGNoYW5uZWxJZF0pO1xuXG5cdHVzZUVmZmVjdCgoKSA9PiB7XG5cdFx0cmV0dXJuICgpID0+IHtcblx0XHRcdGNsaWVudC5yZWxlYXNlQ2hhbm5lbChjaGFubmVsSWQpO1xuXHRcdH07XG5cdH0sIFtjbGllbnQsIGNoYW5uZWxJZF0pO1xuXG5cdHJldHVybiBicmlkZ2U7XG59XG4iCiAgXSwKICAibWFwcGluZ3MiOiAiO0FBT08sTUFBTSwrQkFBK0IsTUFBTTtBQUFBLEVBQ2pELFdBQVcsQ0FBQyxTQUFpQjtBQUFBLElBQzVCLE1BQU0sT0FBTztBQUFBLElBQ2IsS0FBSyxPQUFPO0FBQUE7QUFFZDtBQVNBLFNBQVMsUUFBUSxHQUFXO0FBQUEsRUFDM0IsSUFBSSxPQUFPLFdBQVcsZUFBZSxPQUFPLE9BQU8sZUFBZSxZQUFZO0FBQUEsSUFDN0UsT0FBTyxPQUFPLFdBQVcsRUFBRSxRQUFRLE1BQU0sRUFBRTtBQUFBLEVBQzVDO0FBQUEsRUFDQSxPQUFPLEtBQUssT0FBTyxFQUFFLFNBQVMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEtBQUssT0FBTyxFQUFFLFNBQVMsRUFBRSxFQUFFLE1BQU0sQ0FBQztBQUFBO0FBR2hGLFNBQVMsV0FBVyxDQUFDLE9BQXdCO0FBQUEsRUFD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QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQ0Q7QUFDQSxJQUFNLGlCQUFpQixTQUEyQixlQUFlO0FBRWpFLElBQU0sa0JBQWtCO0FBQUEsRUFDdkI7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQ0Q7QUFDQSxJQUFNLGlCQUFpQixTQUEyQixlQUFlO0FBRWpFLElBQU0sa0JBQWtCLENBQUMsU0FBUztBQUNsQyxJQUFNLGlCQUFpQixTQUEyQixlQUFlO0FBRWpFLElBQU0sZUFBZSxDQUFDLFNBQVMsTUFBTTtBQUNyQyxJQUFNLGNBQWMsU0FBd0IsWUFBWTtBQUV4RCxJQUFNLGlCQUFpQjtBQUFBLEVBQ3RCO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtB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RCxHQUFHO0FBQUEsRUFDSCxNQUFNO0FBQUEsRUFDTixPQUFPO0FBQUEsRUFDUCxNQUFNO0FBQUEsRUFDTixZQUFZO0FBQUEsRUFDWixHQUFHO0FBQUEsRUFDSCxNQUFNO0FBQUEsRUFDTixJQUFJO0FBQUEsRUFDSixRQUFRO0FBQUEsRUFDUixRQUFRO0FBQUEsRUFDUixTQUFTO0FBQUEsRUFDVCxNQUFNO0FBQUEsRUFDTixLQUFLO0FBQUEsRUFDTCxVQUFVO0FBQUEsRUFDVixNQUFNO0FBQUEsRUFDTixTQUFTO0FBQUEsRUFDVCxRQUFRO0FBQUEsRUFDUixLQUFLO0FBQUEsRUFDTCxJQUFJO0FBQUEsRUFDSixPQUFPO0FBQUEsRUFDUCxVQUFVO0FBQUEsRUFDVixNQUFNO0FBQUEsRUFDTixJQUFJO0FBQUEsRUFDSixJQUFJO0FBQUEsRUFDSixJQUFJO0FBQUEsRUFDSixJQUFJO0FBQUEsRUFDSixJQUFJO0FBQUEsRUFDSixJQUFJO0FBQUEsRUFDSixNQUFNO0FBQUEsRUFDTixJQUFJO0FBQUEsRUFDSixNQUFNO0FBQUEsRUFDTixRQUFRO0FBQUEsRUFDUixLQUFLO0FBQUEsRUFDTCxPQUFPO0FBQUEsRUFDUCxPQUFPO0FBQUEsRUFDUCxJQUFJO0FBQUEsRUFDSixNQUFNO0FBQUEsRUFDTixLQUFLO0FBQUEsRUFDTCxNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsRUFDTixPQUFPO0FBQUEsRUFDUCxLQUFLO0FBQUEsRUFDTCxLQUFLO0FBQUEsRUFDTCxRQUFRO0FBQUEsRUFDUixJQUFJO0FBQUEsRUFDSixVQUFVO0FBQUEsRUFDVixRQUFRO0FBQUEsRUFDUixRQUFRO0FBQUEsRUFDUixHQUFHO0FBQUEsRUFDSCxTQUFTO0FBQUEsRUFDVCxLQUFLO0FBQUEsRUFDTCxVQUFVO0FBQUEsRUFDVixRQUFRO0FBQUEsRUFDUixRQUFRO0FBQUEsRUFDUixNQUFNO0FBQUEsRUFDTixRQUFRO0FBQUEsRUFDUixNQUFNO0FBQUEsRUFDTixPQUFPO0FBQUEsRUFDUCxPQUFPO0FBQUEsRUFDUCxPQUFPO0FBQUEsRUFD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QU07QUFBQTtBQUFBLFNBQTdFLGdDQUFxRjtBQUFBLE1BQ3BGLE1BQU0sMkJBQVcsUUFBc0IsT0FBdEI7QUFBQSxrQkFBTSxNQUFNO0FBQUEsU0FBWixpQ0FBc0I7QUFBQSxNQUN2QyxNQUFNLHlCQUNOLFFBR0UsV0FIRjtBQUFBLFFBQVMsTUFBSTtBQUFBLFFBQUMsT0FBTyxFQUFFLFdBQVcsRUFBRTtBQUFBLFFBQXBDLFVBR0U7QUFBQSwwQkFGRCxRQUFzQixXQUF0QjtBQUFBO0FBQUEsOENBQXNCO0FBQUEsMEJBQ3RCLFFBQTBDLE9BQTFDO0FBQUEsWUFBSyxPQUFPLEVBQUUsUUFBUSxFQUFFO0FBQUEsWUFBeEIsVUFBNEIsTUFBTTtBQUFBLGFBQWxDLGlDQUEwQztBQUFBO0FBQUEsU0FGM0MsZ0NBR0U7QUFBQTtBQUFBLEtBakJKLGdDQW1CRTtBQUFBOztBUTdOSixzQkFBUyx1QkFBVztBQUliLFNBQVMsZUFBZSxDQUFDLFdBQWtDO0FBQUEsRUFDakUsTUFBTSxTQUFTLGVBQWU7QUFBQSxFQUM5QixNQUFNLFNBQVMsU0FBUSxNQUFNO0FBQUEsSUFDNUIsSUFBSSxDQUFDLFdBQVc7QUFBQSxNQUNmLE1BQU0sSUFBSSxNQUFNLGdEQUFnRDtBQUFBLElBQ2pFO0FBQUEsSUFDQSxPQUFPLE9BQU8sZUFBZSxTQUFTO0FBQUEsS0FDcEMsQ0FBQyxRQUFRLFNBQVMsQ0FBQztBQUFBLEVBRXRCLFdBQVUsTUFBTTtBQUFBLElBQ2YsT0FBTyxNQUFNO0FBQUEsTUFDWixPQUFPLGVBQWUsU0FBUztBQUFBO0FBQUEsS0FFOUIsQ0FBQyxRQUFRLFNBQVMsQ0FBQztBQUFBLEVBRXRCLE9BQU87QUFBQTsiLAogICJkZWJ1Z0lkIjogIkUzRkQ3Q0Q2QzkzNDU5RjM2NDc1NkUyMTY0NzU2RTIxIiwKICAibmFtZXMiOiBbXQp9