pulse-ui-client 0.1.28 → 0.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/channel.d.ts +1 -1
- package/dist/client.d.ts +6 -21
- package/dist/helpers.d.ts +1 -1
- package/dist/index.bun.js +3 -3
- package/dist/index.d.ts +12 -16
- package/dist/index.development.js +2138 -0
- package/dist/index.js +2 -2
- package/dist/index.js.map +15 -17
- package/dist/index.node.js +3 -3
- package/dist/messages.d.ts +1 -1
- package/dist/pulse.d.ts +5 -5
- package/dist/renderer.d.ts +8 -20
- package/dist/transport.d.ts +1 -1
- package/package.json +45 -45
- package/dist/channel.test.d.ts +0 -1
- package/dist/renderer.test.d.ts +0 -1
- package/dist/serialize/clean.test.d.ts +0 -1
- package/dist/serialize/serializer.test.d.ts +0 -1
|
@@ -0,0 +1,2138 @@
|
|
|
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+IHtcblx0XHRcdGNsaWVudC5yZWxlYXNlQ2hhbm5lbChjaGFubmVsSWQpO1xuXHRcdH07XG5cdH0sIFtjbGllbnQsIGNoYW5uZWxJZF0pO1xuXG5cdHJldHVybiBicmlkZ2U7XG59XG4iCiAgXSwKICAibWFwcGluZ3MiOiAiO0FBT08sTUFBTSwrQkFBK0IsTUFBTTtBQUFBLEVBQ2pELFdBQVcsQ0FBQyxTQUFpQjtBQUFBLElBQzVCLE1BQU0sT0FBTztBQUFBLElBQ2IsS0FBSyxPQUFPO0FBQUE7QUFFZDtBQVNBLFNBQVMsUUFBUSxHQUFXO0FBQUEsRUFDM0IsSUFBSSxPQUFPLFdBQVcsZUFBZSxPQUFPLE9BQU8sZUFBZSxZQUFZO0FBQUEsSUFDN0UsT0FBTyxPQUFPLFdBQVcsRUFBRSxRQUFRLE1BQU0sRUFBRTtBQUFBLEVBQzVDO0FBQUEsRUFDQSxPQUFPLEtBQUssT0FBTyxFQUFFLFNBQVMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEtBQUssT0FBTyxFQUFFLFNBQVMsRUFBRSxFQUFFLE1BQU0sQ0FBQztBQUFBO0FBR2hGLFNBQVMsV0FBVyxDQUFDLE9BQXdCO0FBQUEsRUFDNUMsSUFBSSxpQkFBaUI7QUFBQSxJQUFPLE9BQU8sTUFBTTtBQUFBLEVBQ3pDLElBQUksT0FBTyxVQUFVO0FBQUEsSUFBVSxPQUFPO0FBQUEsRUFDdEMsSUFBSTtBQUFBLElBQ0gsT0FBTyxLQUFLLFVBQVUsS0FBSztBQUFBLElBQzFCLE1BQU07QUFBQSxJQUNQLE9BQU8sT0FBTyxLQUFLO0FBQUE7QUFBQTtBQUlyQixTQUFTLHVCQUF1QixDQUMvQixTQUMwQztBQUFBLEVBQzFDLE9BQU8sT0FBUSxRQUF5QyxlQUFlO0FBQUE7QUFHeEUsU0FBUyxzQkFBc0IsQ0FDOUIsU0FDeUM7QUFBQSxFQUN6QyxPQUFPLE9BQVEsUUFBd0MsVUFBVTtBQUFBO0FBQUE7QUFHM0QsTUFBTSxjQUFjO0FBQUEsRUFPakI7QUFBQSxFQUNRO0FBQUEsRUFQVCxXQUFXLElBQUk7QUFBQSxFQUNmLFVBQVUsSUFBSTtBQUFBLEVBQ2QsVUFBeUMsQ0FBQztBQUFBLEVBQzFDLFNBQVM7QUFBQSxFQUVqQixXQUFXLENBQ0YsUUFDUSxJQUNmO0FBQUEsSUFGTztBQUFBLElBQ1E7QUFBQTtBQUFBLEVBR2pCLElBQUksQ0FBQyxPQUFlLFNBQXFCO0FBQUEsSUFDeEMsS0FBSyxXQUFXO0FBQUEsSUFDaEIsS0FBSyxPQUFPLFlBQVk7QUFBQSxNQUN2QixNQUFNO0FBQUEsTUFDTixTQUFTLEtBQUs7QUFBQSxNQUNkO0FBQUEsTUFDQTtBQUFBLElBQ0QsQ0FBQztBQUFBO0FBQUEsRUFHRixPQUFPLENBQUMsT0FBZSxTQUE2QjtBQUFBLElBQ25ELEtBQUssV0FBVztBQUFBLElBQ2hCLE1BQU0sWUFBWSxTQUFTO0FBQUEsSUFDM0IsT0FBTyxJQUFJLFFBQVEsQ0FBQyxTQUFTLFdBQVc7QUFBQSxNQUN2QyxLQUFLLFFBQVEsSUFBSSxXQUFXLEVBQUUsU0FBUyxPQUFPLENBQUM7QUFBQSxNQUMvQyxLQUFLLE9BQU8sWUFBWTtBQUFBLFFBQ3ZCLE1BQU07QUFBQSxRQUNOLFNBQVMsS0FBSztBQUFBLFFBQ2Q7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLE1BQ0QsQ0FBQztBQUFBLEtBQ0Q7QUFBQTtBQUFBLEVBR0YsRUFBRSxDQUFDLE9BQWUsU0FBMEM7QUFBQSxJQUMzRCxLQUFLLFdBQVc7QUFBQSxJQUNoQixJQUFJLFNBQVMsS0FBSyxTQUFTLElBQUksS0FBSztBQUFBLElBQ3BDLElBQUksQ0FBQyxRQUFRO0FBQUEsTUFDWixTQUFTLElBQUk7QUFBQSxNQUNiLEtBQUssU0FBUyxJQUFJLE9BQU8sTUFBTTtBQUFBLElBQ2hDO0FBQUEsSUFDQSxPQUFPLElBQUksT0FBTztBQUFBLElBQ2xCLEtBQUssYUFBYSxLQUFLO0FBQUEsSUFDdkIsT0FBTyxNQUFNO0FBQUEsTUFDWixNQUFNLE1BQU0sS0FBSyxTQUFTLElBQUksS0FBSztBQUFBLE1BQ25DLElBQUksQ0FBQztBQUFBLFFBQUs7QUFBQSxNQUNWLElBQUksT0FBTyxPQUFPO0FBQUEsTUFDbEIsSUFBSSxJQUFJLFNBQVMsR0FBRztBQUFBLFFBQ25CLEtBQUssU0FBUyxPQUFPLEtBQUs7QUFBQSxNQUMzQjtBQUFBO0FBQUE7QUFBQSxFQUlGLG1CQUFtQixDQUFDLFNBQXdDO0FBQUEsSUFDM0QsSUFBSSx3QkFBd0IsT0FBTyxHQUFHO0FBQUEsTUFDckMsS0FBSyxlQUFlLE9BQU87QUFBQSxNQUMzQixPQUFPLEtBQUs7QUFBQSxJQUNiO0FBQUEsSUFDQSxJQUFJLEtBQUssUUFBUTtBQUFBLE1BQ2hCLE9BQU87QUFBQSxJQUNSO0FBQUEsSUFDQSxJQUFJLENBQUMsdUJBQXVCLE9BQU8sR0FBRztBQUFBLE1BQ3JDLE9BQU8sS0FBSztBQUFBLElBQ2I7QUFBQSxJQUVBLElBQUksUUFBUSxVQUFVLGFBQWE7QUFBQSxNQUNsQyxLQUFLLE1BQU0sSUFBSSx1QkFBdUIsMEJBQTBCLENBQUM7QUFBQSxNQUNqRSxPQUFPO0FBQUEsSUFDUjtBQUFBLElBQ0EsSUFBSSxRQUFRLFdBQVc7QUFBQSxNQUNqQixLQUFLLGdCQUNULE9BR0Q7QUFBQSxJQUNELEVBQU87QUFBQSxNQUNOLEtBQUssY0FBYyxPQUFPO0FBQUE7QUFBQSxJQUUzQixPQUFPLEtBQUs7QUFBQTtBQUFBLEVBR2IsZ0JBQWdCLENBQUMsUUFBc0M7QUFBQSxJQUN0RCxLQUFLLE1BQU0sTUFBTTtBQUFBO0FBQUEsRUFHbEIsT0FBTyxDQUFDLFFBQXNDO0FBQUEsSUFDN0MsS0FBSyxNQUFNLE1BQU07QUFBQTtBQUFBLEVBR1YsVUFBVSxHQUFTO0FBQUEsSUFDMUIsSUFBSSxLQUFLLFFBQVE7QUFBQSxNQUNoQixNQUFNLElBQUksdUJBQXVCLG1CQUFtQjtBQUFBLElBQ3JEO0FBQUE7QUFBQSxFQUdPLFlBQVksQ0FBQyxPQUFxQjtBQUFBLElBQ3pDLElBQUksS0FBSyxRQUFRLFdBQVc7QUFBQSxNQUFHO0FBQUEsSUFDL0IsTUFBTSxZQUEyQyxDQUFDO0FBQUEsSUFDbEQsV0FBVyxRQUFRLEtBQUssU0FBUztBQUFBLE1BQ2hDLElBQUksS0FBSyxVQUFVLE9BQU87QUFBQSxRQUN6QixLQUFLLGNBQWMsSUFBSTtBQUFBLE1BQ3hCLEVBQU87QUFBQSxRQUNOLFVBQVUsS0FBSyxJQUFJO0FBQUE7QUFBQSxJQUVyQjtBQUFBLElBQ0EsS0FBSyxVQUFVO0FBQUE7QUFBQSxFQUdSLGFBQWEsQ0FBQyxTQUE0QztBQUFBLElBQ2pFLE1BQU0sV0FBVyxLQUFLLFNBQVMsSUFBSSxRQUFRLEtBQUs7QUFBQSxJQUNoRCxJQUFJLENBQUMsWUFBWSxTQUFTLFNBQVMsR0FBRztBQUFBLE1BQ3JDLEtBQUssUUFBUSxLQUFLLE9BQU87QUFBQSxNQUN6QjtBQUFBLElBQ0Q7QUFBQSxJQUNBLFdBQVcsV0FBVyxVQUFVO0FBQUEsTUFDL0IsSUFBSTtBQUFBLFFBQ0gsTUFBTSxTQUFTLFFBQVEsUUFBUSxPQUFPO0FBQUEsUUFDdEMsSUFBSSxVQUFVLE9BQVEsT0FBd0IsU0FBUyxZQUFZO0FBQUEsVUFDNUQsT0FBd0IsTUFBTSxDQUFDLFFBQVE7QUFBQSxZQUM1QyxRQUFRLE1BQU0sK0JBQStCLEdBQUc7QUFBQSxXQUNoRDtBQUFBLFFBQ0Y7QUFBQSxRQUNDLE9BQU8sS0FBSztBQUFBLFFBQ2IsUUFBUSxNQUFNLCtCQUErQixHQUFHO0FBQUE7QUFBQSxJQUVsRDtBQUFBO0FBQUEsT0FHYSxnQkFBZSxDQUM1QixTQUNnQjtBQUFBLElBQ2hCLE1BQU0sV0FBVyxLQUFLLFNBQVMsSUFBSSxRQUFRLEtBQUs7QUFBQSxJQUNoRCxJQUFJO0FBQUEsSUFDSixJQUFJO0FBQUEsSUFDSixJQUFJLFlBQVksU0FBUyxPQUFPLEdBQUc7QUFBQSxNQUNsQyxXQUFXLFdBQVcsVUFBVTtBQUFBLFFBQy9CLElBQUk7QUFBQSxVQUNILE1BQU0sU0FBUyxRQUFRLFFBQVEsT0FBTztBQUFBLFVBQ3RDLFdBQVcsTUFBTSxRQUFRLFFBQVEsTUFBTTtBQUFBLFVBQ3ZDLElBQUksYUFBYSxXQUFXO0FBQUEsWUFDM0I7QUFBQSxVQUNEO0FBQUEsVUFDQyxPQUFPLEtBQUs7QUFBQSxVQUNiLFFBQVE7QUFBQSxVQUNSO0FBQUE7QUFBQSxNQUVGO0FBQUEsSUFDRDtBQUFBLElBQ0EsSUFBSSxPQUFPO0FBQUEsTUFDVixLQUFLLE9BQU8sWUFBWTtBQUFBLFFBQ3ZCLE1BQU07QUFBQSxRQUNOLFNBQVMsS0FBSztBQUFBLFFBQ2QsT0FBTztBQUFBLFFBQ1AsWUFBWSxRQUFRO0FBQUEsUUFDcEIsT0FBTyxZQUFZLEtBQUs7QUFBQSxNQUN6QixDQUFDO0FBQUEsTUFDRDtBQUFBLElBQ0Q7QUFBQSxJQUNBLEtBQUssT0FBTyxZQUFZO0FBQUEsTUFDdkIsTUFBTTtBQUFBLE1BQ04sU0FBUyxLQUFLO0FBQUEsTUFDZCxPQUFPO0FBQUEsTUFDUCxZQUFZLFFBQVE7QUFBQSxNQUNwQixTQUFTO0FBQUEsSUFDVixDQUFDO0FBQUE7QUFBQSxFQUdNLGNBQWMsQ0FBQyxTQUE2QztBQUFBLElBQ25FLE1BQU0sUUFBUSxRQUFRLGFBQWEsS0FBSyxRQUFRLElBQUksUUFBUSxVQUFVLElBQUk7QUFBQSxJQUMxRSxJQUFJLENBQUMsT0FBTztBQUFBLE1BQ1g7QUFBQSxJQUNEO0FBQUEsSUFDQSxLQUFLLFFBQVEsT0FBTyxRQUFRLFVBQVc7QUFBQSxJQUN2QyxJQUFJLFFBQVEsVUFBVSxhQUFhLFFBQVEsVUFBVSxNQUFNO0FBQUEsTUFDMUQsTUFBTSxPQUFPLElBQUksdUJBQXVCLE9BQU8sUUFBUSxLQUFLLENBQUMsQ0FBQztBQUFBLElBQy9ELEVBQU87QUFBQSxNQUNOLE1BQU0sUUFBUSxRQUFRLE9BQU87QUFBQTtBQUFBO0FBQUEsRUFJdkIsS0FBSyxDQUFDLFFBQXNDO0FBQUEsSUFDbkQsSUFBSSxLQUFLLFFBQVE7QUFBQSxNQUNoQjtBQUFBLElBQ0Q7QUFBQSxJQUNBLEtBQUssU0FBUztBQUFBLElBQ2QsV0FBVyxXQUFXLEtBQUssUUFBUSxPQUFPLEdBQUc7QUFBQSxNQUM1QyxRQUFRLE9BQU8sTUFBTTtBQUFBLElBQ3RCO0FBQUEsSUFDQSxLQUFLLFFBQVEsTUFBTTtBQUFBLElBQ25CLEtBQUssU0FBUyxNQUFNO0FBQUEsSUFDcEIsS0FBSyxVQUFVLENBQUM7QUFBQTtBQUdsQjtBQUVPLFNBQVMsbUJBQW1CLENBQUMsUUFBNkIsSUFBMkI7QUFBQSxFQUMzRixPQUFPLElBQUksY0FBYyxRQUFRLEVBQUU7QUFBQTs7QUN4UHBDO0FBQUE7QUFXTyxJQUFNLFlBQVksV0FBNEMsU0FBUyxVQUFTLEdBQ3BGLFVBQVUsV0FBVyxRQUN2QixLQUNDO0FBQUEsRUFDRCx1QkFDQyxPQUFDLFFBQUQ7QUFBQSxPQUNLO0FBQUEsSUFDSjtBQUFBLElBQ0E7QUFBQSxJQUNBLFVBQVUsWUFDVCxDQUFDLFVBQXNDLFdBQVcsRUFBRSxPQUFPLFFBQVEsU0FBUyxDQUFDLEdBQzdFLENBQUMsUUFBUSxRQUFRLENBQ2xCO0FBQUEsS0FQRCxpQ0FRQTtBQUFBLENBRUQ7QUFVRCxlQUFzQixVQUFVLEdBQUcsT0FBTyxRQUFRLFVBQVUsVUFBVSxTQUFxQjtBQUFBLEVBQzFGLFdBQVcsS0FBSztBQUFBLEVBQ2hCLElBQUksQ0FBQyxTQUFTLE1BQU0sa0JBQWtCO0FBQUEsSUFDckM7QUFBQSxFQUNEO0FBQUEsRUFDQSxNQUFNLE9BQU8sTUFBTTtBQUFBLEVBQ25CLE1BQU0sZUFBZTtBQUFBLEVBQ3JCLE1BQU0sY0FBYyxNQUFNO0FBQUEsRUFDMUIsSUFBSSxDQUFDLFVBQVU7QUFBQSxJQUNkLFdBQVcsSUFBSSxTQUFTLE1BQU0sWUFBWSxTQUFTO0FBQUEsRUFDcEQ7QUFBQSxFQUNBLE1BQU0sTUFBTSxJQUFJLElBQUksUUFBUSxPQUFPLFNBQVMsSUFBSTtBQUFBLEVBQ2hELElBQUk7QUFBQSxJQUNILE1BQU0sTUFBTSxLQUFLO0FBQUEsTUFDaEIsUUFBUTtBQUFBLE1BRVIsYUFBYTtBQUFBLE1BQ2IsTUFBTTtBQUFBLElBQ1AsQ0FBQztBQUFBLElBQ0EsT0FBTyxLQUFLO0FBQUEsSUFDYixJQUFJLE1BQXVDO0FBQUEsTUFDMUMsUUFBUSxNQUFNLGtDQUFrQyxHQUFHO0FBQUEsSUFDcEQsRUFBTztBQUFBO0FBQUE7O0FDL0NGLFNBQVMsc0JBQXNCLEdBQUcsUUFBUSxXQUErQjtBQUFBLEVBQy9FLFFBQVEsS0FBSyxXQUFXLE9BQU8sZUFBZTtBQUFBLEVBQzlDLE1BQU0sWUFBWSxJQUFJLElBQUksUUFBUSxHQUFHO0FBQUEsRUFFckMsT0FBTztBQUFBLElBQ04sTUFBTSxVQUFVO0FBQUEsSUFDaEIsVUFBVSxVQUFVO0FBQUEsSUFDcEIsT0FBTyxVQUFVO0FBQUEsSUFDakIsYUFBYSxPQUFPLFlBQVksVUFBVSxhQUFhLFFBQVEsQ0FBQztBQUFBLElBQ2hFO0FBQUEsSUFDQSxVQUFVLFNBQVMsU0FBUyxJQUFJLFNBQVMsTUFBTSxHQUFHLElBQUksQ0FBQztBQUFBLEVBQ3hEO0FBQUE7O0FDdEJEO0FBQ0E7OztBQ0FBOzs7QUNDTyxTQUFTLGVBQWlDLEdBQUc7QUFBQSxFQUNuRCxTQUFTLGdCQUdSLENBQUMsTUFBUyxVQUFjO0FBQUEsSUFDeEIsT0FBTyxDQUNOLFFBS0k7QUFBQSxNQUNKLE1BQU0sTUFBVyxDQUFDO0FBQUEsTUFDbEIsV0FBVyxPQUFPLE1BQU07QUFBQSxRQUN2QixJQUFJLE9BQWtCLElBQVk7QUFBQSxNQUNuQztBQUFBLE1BQ0EsSUFBSSxVQUFVO0FBQUEsUUFDYixXQUFXLE9BQU8sVUFBVTtBQUFBLFVBQzNCLE1BQU0sS0FBSyxTQUFTO0FBQUEsVUFDcEIsSUFBSSxPQUFPLEdBQUcsR0FBRztBQUFBLFFBQ2xCO0FBQUEsTUFDRDtBQUFBLE1BQ0EsT0FBTztBQUFBO0FBQUE7QUFBQSxFQUdULE9BQU87QUFBQTs7O0FDeEJSLElBQU0sZUFBZSxDQUFDLE1BQWUsRUFBRSxRQUFRLFlBQVk7QUFFM0QsSUFBTSxlQUFlO0FBQUEsRUFDcEI7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFDRDtBQUVBLElBQU0sbUJBQW1CO0FBQUEsRUFDeEI7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUNEO0FBRUEsSUFBTSx5QkFBeUI7QUFBQSxFQUM5QjtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQ0Q7QUFFQSxJQUFNLGlCQUFpQixnQkFBeUIsRUFBRSxjQUFjO0FBQUEsRUFDL0QsU0FBUztBQUNWLENBQUM7QUFFRCxJQUFNLDBCQUEwQixnQkFBa0MsRUFBRSxnQkFBZ0I7QUFFcEYsSUFBTSw2QkFBNkIsZ0JBQTZCLEVBQUUsc0JBQXNCO0FBRXhGLFNBQVMsc0JBQXNCLENBQUMsS0FBa0I7QUFBQSxFQUNqRCxPQUFPO0FBQUEsT0FDSCxlQUFlLEdBQUc7QUFBQSxPQUNsQix3QkFBd0IsR0FBdUI7QUFBQSxPQUMvQywyQkFBMkIsR0FBRztBQUFBLEVBQ2xDO0FBQUE7QUFJRCxTQUFTLFFBQStCLENBQ3ZDLE1BQ0EsVUFDQztBQUFBLEVBQ0QsTUFBTSxPQUFPLGdCQUFtQixFQUFFLE1BQU0sUUFBZTtBQUFBLEVBQ3ZELE9BQU8sQ0FBQyxTQUFZLEtBQUssdUJBQXVCLEdBQUcsTUFBTSxLQUFLLEdBQUcsRUFBRTtBQUFBO0FBR3BFLElBQU0sbUJBQW1CO0FBQUEsRUFDeEI7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFDRDtBQUNBLElBQU0sa0JBQWtCLFNBQTRCLGdCQUFnQjtBQUVwRSxJQUFNLGlCQUFpQjtBQUFBLEVBQ3RCO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQ0Q7QUFDQSxJQUFNLGdCQUFnQixTQUEwQixjQUFjO0FBRTlELElBQU0sa0JBQWtCO0FBQUEsRUFDdkI7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQ0Q7QUFDQSxJQUFNLGlCQUFpQixTQUEyQixlQUFlO0FBRWpFLElBQU0saUJBQWlCLENBQUMsUUFBMEIsZUFBZSxHQUFHO0FBRXBFLElBQU0sbUJBQW1CO0FBQUEsRUFDeEI7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFDRDtBQUNBLElBQU0sa0JBQWtCLFNBQTRCLGdCQUFnQjtBQUVwRSxJQUFNLGlCQUFpQixDQUFDLE9BQU87QUFDL0IsSUFBTSxnQkFBZ0IsU0FBMEIsY0FBYztBQUU5RCxJQUFNLGtCQUFrQjtBQUFBLEVBQ3ZCO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFDRDtBQUNBLElBQU0saUJBQWlCLFNBQTJCLGVBQWU7QUFFakUsSUFBTSxxQkFBcUI7QUFBQSxFQUMxQjtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFDRDtBQUNBLElBQU0sb0JBQW9CLFNBQThCLGtCQUFrQjtBQUUxRSxJQUFNLGlCQUFpQjtBQUFBLEVBQ3RCO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUNEO0FBQ0EsSUFBTSxnQkFBZ0IsU0FBMEIsY0FBYztBQUU5RCxJQUFNLG1CQUFtQjtBQUFBLEVBQ3hCO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFDRDtBQUNBLElBQU0sa0JBQWtCLFNBQTRCLGdCQUFnQjtBQUVwRSxJQUFNLGtCQUFrQjtBQUFBLEVBQ3ZCO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQ0Q7QUFDQSxJQUFNLGlCQUFpQixTQUEyQixlQUFlO0FBRWpFLElBQU0sa0JBQWtCO0FBQUEsRUFDdkI7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQ0Q7QUFDQSxJQUFNLGlCQUFpQixTQUEyQixlQUFlO0FBRWpFLElBQU0sa0JBQWtCLENBQUMsU0FBUztBQUNsQyxJQUFNLGlCQUFpQixTQUEyQixlQUFlO0FBRWpFLElBQU0sZUFBZSxDQUFDLFNBQVMsTUFBTTtBQUNyQyxJQUFNLGNBQWMsU0FBd0IsWUFBWTtBQUV4RCxJQUFNLGlCQUFpQjtBQUFBLEVBQ3RCO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtB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RCxHQUFHO0FBQUEsRUFDSCxNQUFNO0FBQUEsRUFDTixPQUFPO0FBQUEsRUFDUCxNQUFNO0FBQUEsRUFDTixZQUFZO0FBQUEsRUFDWixHQUFHO0FBQUEsRUFDSCxNQUFNO0FBQUEsRUFDTixJQUFJO0FBQUEsRUFDSixRQUFRO0FBQUEsRUFDUixRQUFRO0FBQUEsRUFDUixTQUFTO0FBQUEsRUFDVCxNQUFNO0FBQUEsRUFDTixLQUFLO0FBQUEsRUFDTCxVQUFVO0FBQUEsRUFDVixNQUFNO0FBQUEsRUFDTixTQUFTO0FBQUEsRUFDVCxRQUFRO0FBQUEsRUFDUixLQUFLO0FBQUEsRUFDTCxJQUFJO0FBQUEsRUFDSixPQUFPO0FBQUEsRUFDUCxVQUFVO0FBQUEsRUFDVixNQUFNO0FBQUEsRUFDTixJQUFJO0FBQUEsRUFDSixJQUFJO0FBQUEsRUFDSixJQUFJO0FBQUEsRUFDSixJQUFJO0FBQUEsRUFDSixJQUFJO0FBQUEsRUFDSixJQUFJO0FBQUEsRUFDSixNQUFNO0FBQUEsRUFDTixJQUFJO0FBQUEsRUFDSixNQUFNO0FBQUEsRUFDTixRQUFRO0FBQUEsRUFDUixLQUFLO0FBQUEsRUFDTCxPQUFPO0FBQUEsRUFDUCxPQUFPO0FBQUEsRUFDUCxJQUFJO0FBQUEsRUFDSixNQUFNO0FBQUEsRUFDTixLQUFLO0FBQUEsRUFDTCxNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsRUFDTixPQUFPO0FBQUEsRUFDUCxLQUFLO0FBQUEsRUFDTCxLQUFLO0FBQUEsRUFDTCxRQUFRO0FBQUEsRUFDUixJQUFJO0FBQUEsRUFDSixVQUFVO0FBQUEsRUFDVixRQUFRO0FBQUEsRUFDUixRQUFRO0FBQUEsRUFDUixHQUFHO0FBQUEsRUFDSCxTQUFTO0FBQUEsRUFDVCxLQUFLO0FBQUEsRUFDTCxVQUFVO0FBQUEsRUFDVixRQUFRO0FBQUEsRUFDUixRQUFRO0FBQUEsRUFDUixNQUFNO0FBQUEsRUFDTixRQUFRO0FBQUEsRUFDUixNQUFNO0FBQUEsRUFDTixPQUFPO0FBQUEsRUFDUCxPQUFPO0FBQUEsRUFDUCxPQUFPO0FBQUEsRUFD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QU07QUFBQTtBQUFBLFNBQTdFLGdDQUFxRjtBQUFBLE1BQ3BGLE1BQU0sMkJBQVcsUUFBc0IsT0FBdEI7QUFBQSxrQkFBTSxNQUFNO0FBQUEsU0FBWixpQ0FBc0I7QUFBQSxNQUN2QyxNQUFNLHlCQUNOLFFBR0UsV0FIRjtBQUFBLFFBQVMsTUFBSTtBQUFBLFFBQUMsT0FBTyxFQUFFLFdBQVcsRUFBRTtBQUFBLFFBQXBDLFVBR0U7QUFBQSwwQkFGRCxRQUFzQixXQUF0QjtBQUFBO0FBQUEsOENBQXNCO0FBQUEsMEJBQ3RCLFFBQTBDLE9BQTFDO0FBQUEsWUFBSyxPQUFPLEVBQUUsUUFBUSxFQUFFO0FBQUEsWUFBeEIsVUFBNEIsTUFBTTtBQUFBLGFBQWxDLGlDQUEwQztBQUFBO0FBQUEsU0FGM0MsZ0NBR0U7QUFBQTtBQUFBLEtBakJKLGdDQW1CRTtBQUFBOztBUTdOSixzQkFBUyx1QkFBVztBQUliLFNBQVMsZUFBZSxDQUFDLFdBQWtDO0FBQUEsRUFDakUsTUFBTSxTQUFTLGVBQWU7QUFBQSxFQUM5QixNQUFNLFNBQVMsU0FBUSxNQUFNO0FBQUEsSUFDNUIsSUFBSSxDQUFDLFdBQVc7QUFBQSxNQUNmLE1BQU0sSUFBSSxNQUFNLGdEQUFnRDtBQUFBLElBQ2pFO0FBQUEsSUFDQSxPQUFPLE9BQU8sZUFBZSxTQUFTO0FBQUEsS0FDcEMsQ0FBQyxRQUFRLFNBQVMsQ0FBQztBQUFBLEVBRXRCLFdBQVUsTUFBTTtBQUFBLElBQ2YsT0FBTyxNQUFNO0FBQUEsTUFDWixPQUFPLGVBQWUsU0FBUztBQUFBO0FBQUEsS0FFOUIsQ0FBQyxRQUFRLFNBQVMsQ0FBQztBQUFBLEVBRXRCLE9BQU87QUFBQTsiLAogICJkZWJ1Z0lkIjogIkUzRkQ3Q0Q2QzkzNDU5RjM2NDc1NkUyMTY0NzU2RTIxIiwKICAibmFtZXMiOiBbXQp9
|