@dbx-tools/appkit-model-gateway 0.9.175 → 0.9.177

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.
@@ -0,0 +1,700 @@
1
+ /**
2
+ * Databricks Smart Router transport, context construction, probing, and turn pinning.
3
+ *
4
+ * @module
5
+ */
6
+ import { createHash } from "node:crypto";
7
+ import { CacheManager, getExecutionContext } from "@databricks/appkit";
8
+ import { closeCache, createCache, getOrSet } from "@dbx-tools/cache";
9
+ import { refreshWorkspaceClientAuthentication } from "@dbx-tools/databricks";
10
+ import { isRecord, log, toError } from "@dbx-tools/shared-core";
11
+ import { ReasoningEffortSchema } from "@dbx-tools/shared-model";
12
+ import { SMART_ROUTER_NAME, SmartRouterObservationSchema, SmartRouterRequestSchema, SmartRouterResponseSchema, } from "@dbx-tools/shared-model-gateway";
13
+ import { Tiktoken } from "js-tiktoken/lite";
14
+ import o200kBase from "js-tiktoken/ranks/o200k_base";
15
+ import { z } from "zod";
16
+ import { resolveRoute } from "./router.js";
17
+ const logger = log.logger("appkit/model-gateway/smart-router");
18
+ const ROUTE_CACHE_NAMESPACE = "model-gateway-smart-router";
19
+ const ROUTE_POLICY_VERSION = 1;
20
+ const PROBE_CACHE_NAMESPACE = "model-gateway-smart-router-probe";
21
+ const PROBE_CACHE_VERSION = 1;
22
+ const PROBE_TASK = "Check whether Smart Router can select an available model.";
23
+ const NEGATIVE_PROBE_TTL_MS = 30_000;
24
+ const CONTEXT_ENCODING = new Tiktoken(o200kBase);
25
+ /** Defaults shared by gateway, Mastra, and CLI Smart Router callers. */
26
+ export const SMART_ROUTER_DEFAULT_SETTINGS = Object.freeze({
27
+ contextTokenBudget: 4_096,
28
+ probeRefreshIntervalMs: 3_600_000,
29
+ probeTtlMs: 300_000,
30
+ routeTtlSeconds: 21_600,
31
+ routerName: SMART_ROUTER_NAME,
32
+ timeoutMs: 10_000,
33
+ });
34
+ export const SmartRouterProbeRecordSchema = z
35
+ .object({
36
+ enabled: z.boolean().describe("Whether the live Smart Router probe succeeded."),
37
+ expiresAt: z.number().int().describe("Epoch milliseconds when this probe becomes stale."),
38
+ })
39
+ .describe("Persisted Smart Router capability probe result.");
40
+ /** Error carrying an HTTP status for Smart Router validation or availability failures. */
41
+ export class SmartRouterError extends Error {
42
+ status;
43
+ constructor(status, message) {
44
+ super(message);
45
+ this.status = status;
46
+ this.name = "SmartRouterError";
47
+ }
48
+ }
49
+ /** AppKit cache adapter; configured Lakebase/Postgres storage remains AppKit-owned. */
50
+ export class AppKitSmartRouterStore {
51
+ async get(key) {
52
+ const cache = await CacheManager.getInstance();
53
+ return cache.get(cache.generateKey([ROUTE_CACHE_NAMESPACE, ROUTE_POLICY_VERSION], key));
54
+ }
55
+ async set(key, value, ttlSeconds) {
56
+ const cache = await CacheManager.getInstance();
57
+ await cache.set(cache.generateKey([ROUTE_CACHE_NAMESPACE, ROUTE_POLICY_VERSION], key), value, {
58
+ ttl: ttlSeconds,
59
+ });
60
+ }
61
+ }
62
+ /** AppKit cache adapter for process- and persistence-backed capability probes. */
63
+ export class AppKitSmartRouterProbeStore {
64
+ async get(key, client) {
65
+ const cache = appKitCacheManager();
66
+ if (!cache)
67
+ return undefined;
68
+ const identity = await smartRouterProbeIdentity(client);
69
+ return cache.get(cache.generateKey([PROBE_CACHE_NAMESPACE, PROBE_CACHE_VERSION], `${identity}:${key}`));
70
+ }
71
+ async set(key, value, ttlSeconds, client) {
72
+ const cache = appKitCacheManager();
73
+ if (!cache)
74
+ return;
75
+ const identity = await smartRouterProbeIdentity(client);
76
+ await cache.set(cache.generateKey([PROBE_CACHE_NAMESPACE, PROBE_CACHE_VERSION], `${identity}:${key}`), value, { ttl: ttlSeconds });
77
+ }
78
+ }
79
+ /**
80
+ * Dedicated Smart Router service for strings, request objects, message arrays,
81
+ * and generic JSON-like inputs.
82
+ */
83
+ export class SmartRouterService {
84
+ invoke;
85
+ probeStore;
86
+ context;
87
+ settings;
88
+ probes = new WeakMap();
89
+ probeKeys = new WeakMap();
90
+ probeCaches = new Set();
91
+ constructor(settings = {}, invoke = invokeSmartRouter, probeStore = new AppKitSmartRouterProbeStore()) {
92
+ this.invoke = invoke;
93
+ this.probeStore = probeStore;
94
+ this.settings = { ...SMART_ROUTER_DEFAULT_SETTINGS, ...settings };
95
+ this.context = new SmartRouterContextBuilder(this.settings.contextTokenBudget);
96
+ }
97
+ /** Select one offered route for arbitrary input content. */
98
+ async select(input, candidates, options = {}) {
99
+ const task = this.context.build(input);
100
+ if (!task)
101
+ throw new SmartRouterError(400, "Smart Router input contains no routable text");
102
+ const client = options.client ?? getExecutionContext().client;
103
+ try {
104
+ const selection = await this.selectTask(task, candidates, { ...options, client });
105
+ this.setProbeValue(candidates, client, true);
106
+ return selection;
107
+ }
108
+ catch (error) {
109
+ this.setProbeUnavailable(candidates, client);
110
+ throw error;
111
+ }
112
+ }
113
+ /** Return a memoized live capability probe for the active identity and candidate menu. */
114
+ async isEnabled(candidates, client = getExecutionContext().client) {
115
+ const offered = uniqueCandidates(candidates);
116
+ if (offered.length === 0)
117
+ return false;
118
+ const cache = this.probeCache(client);
119
+ const key = probeKey(offered, this.settings.routerName);
120
+ this.rememberProbeKey(client, key);
121
+ const probe = await getOrSet(cache, key, () => this.loadProbe(key, offered, client), {
122
+ ttl: this.probeCacheTtlMs(),
123
+ refreshAfterWrite: (value) => this.probeRefreshAfterWrite(value.enabled),
124
+ });
125
+ return probe?.enabled ?? false;
126
+ }
127
+ /** Stop process-local probe caches after their active refreshes settle. */
128
+ dispose() {
129
+ for (const cache of this.probeCaches)
130
+ void closeCache(cache);
131
+ this.probeCaches.clear();
132
+ }
133
+ async loadProbe(key, candidates, client) {
134
+ const stored = await this.readStoredProbe(key, client);
135
+ if (stored && stored.expiresAt > Date.now())
136
+ return stored;
137
+ return this.executeProbe(key, candidates, client);
138
+ }
139
+ async executeProbe(key, candidates, client) {
140
+ const enabled = await this.selectTask(PROBE_TASK, candidates, { client })
141
+ .then(() => true)
142
+ .catch((error) => {
143
+ logger.debug("Smart Router capability probe unavailable", { error: toError(error) });
144
+ return false;
145
+ });
146
+ const probe = this.probeRecord(enabled);
147
+ void this.writeStoredProbe(key, probe, client);
148
+ return probe;
149
+ }
150
+ setProbeValue(candidates, client, enabled) {
151
+ const offered = uniqueCandidates(candidates);
152
+ if (offered.length === 0)
153
+ return;
154
+ const cache = this.probeCache(client);
155
+ const key = probeKey(offered, this.settings.routerName);
156
+ this.rememberProbeKey(client, key);
157
+ const probe = this.probeRecord(enabled);
158
+ void this.writeProcessProbe(cache, key, probe);
159
+ void this.writeStoredProbe(key, probe, client);
160
+ }
161
+ setProbeUnavailable(candidates, client) {
162
+ const cache = this.probeCache(client);
163
+ const offered = uniqueCandidates(candidates);
164
+ const requestedKey = probeKey(offered, this.settings.routerName);
165
+ this.rememberProbeKey(client, requestedKey);
166
+ const keys = this.probeKeys.get(client.config) ?? new Set([requestedKey]);
167
+ for (const key of keys) {
168
+ const probe = this.probeRecord(false);
169
+ void this.writeProcessProbe(cache, key, probe);
170
+ void this.writeStoredProbe(key, probe, client);
171
+ }
172
+ }
173
+ probeRecord(enabled) {
174
+ return { enabled, expiresAt: Date.now() + this.probeTtl(enabled) };
175
+ }
176
+ async readStoredProbe(key, client) {
177
+ try {
178
+ const parsed = SmartRouterProbeRecordSchema.safeParse(await this.probeStore.get(key, client));
179
+ return parsed.success ? parsed.data : undefined;
180
+ }
181
+ catch (error) {
182
+ logger.debug("Smart Router probe cache read failed", { error: toError(error) });
183
+ return undefined;
184
+ }
185
+ }
186
+ async writeProcessProbe(cache, key, probe) {
187
+ try {
188
+ await cache.set(key, probe, { ttl: this.probeCacheTtlMs() });
189
+ }
190
+ catch (error) {
191
+ logger.debug("Smart Router process probe cache write failed", { error: toError(error) });
192
+ }
193
+ }
194
+ async writeStoredProbe(key, probe, client) {
195
+ try {
196
+ await this.probeStore.set(key, probe, Math.max(1, Math.ceil(this.probeCacheTtlMs() / 1_000)), client);
197
+ }
198
+ catch (error) {
199
+ logger.debug("Smart Router probe cache write failed", { error: toError(error) });
200
+ }
201
+ }
202
+ probeCache(client) {
203
+ const owner = client.config;
204
+ let cache = this.probes.get(owner);
205
+ if (!cache) {
206
+ cache = createCache({ maxEntries: 32, useClone: false });
207
+ this.probes.set(owner, cache);
208
+ this.probeCaches.add(cache);
209
+ }
210
+ return cache;
211
+ }
212
+ rememberProbeKey(client, key) {
213
+ const owner = client.config;
214
+ let keys = this.probeKeys.get(owner);
215
+ if (!keys) {
216
+ keys = new Set();
217
+ this.probeKeys.set(owner, keys);
218
+ }
219
+ keys.add(key);
220
+ }
221
+ probeCacheTtlMs() {
222
+ return Math.max(this.settings.probeRefreshIntervalMs, this.settings.probeTtlMs) * 2;
223
+ }
224
+ probeTtl(enabled) {
225
+ return enabled
226
+ ? this.settings.probeTtlMs
227
+ : Math.min(this.settings.probeTtlMs, NEGATIVE_PROBE_TTL_MS);
228
+ }
229
+ probeRefreshAfterWrite(enabled) {
230
+ return Math.min(this.settings.probeRefreshIntervalMs, this.probeTtl(enabled));
231
+ }
232
+ async selectTask(task, candidates, options) {
233
+ const offered = uniqueCandidates(candidates);
234
+ if (offered.length === 0) {
235
+ throw new SmartRouterError(400, "No compatible system models are available to Smart Router");
236
+ }
237
+ const request = SmartRouterRequestSchema.parse({
238
+ route_options: offered.map(({ model, harness }) => ({ model, harness })),
239
+ task: { prompt: task },
240
+ route_selector: { router_name: this.settings.routerName },
241
+ });
242
+ const client = options.client ?? getExecutionContext().client;
243
+ const signal = options.signal ?? new AbortController().signal;
244
+ const startedAt = Date.now();
245
+ const response = SmartRouterResponseSchema.parse(await this.invoke(client, request, signal, this.settings.timeoutMs));
246
+ const selection = response.route_selection[0];
247
+ const selected = offered.find((candidate) => normalizeRouteModel(candidate.model) ===
248
+ normalizeRouteModel(selection.route_option.model) &&
249
+ (!selection.route_option.harness || candidate.harness === selection.route_option.harness));
250
+ if (!selected) {
251
+ throw new SmartRouterError(502, `Smart Router selected an unsupported model: ${selection.route_option.model}`);
252
+ }
253
+ return {
254
+ value: selected.value,
255
+ routeModel: selection.route_option.model,
256
+ harness: selected.harness,
257
+ routerName: this.settings.routerName,
258
+ latencyMs: Date.now() - startedAt,
259
+ ...(response.rationale ? { rationale: response.rationale } : {}),
260
+ ...(selection.params ? { params: selection.params } : {}),
261
+ };
262
+ }
263
+ }
264
+ /** Build a Smart Router candidate menu from values carrying modelServiceName. */
265
+ export function smartRouterCandidates(values, harness) {
266
+ return values.flatMap((value) => {
267
+ const model = value.modelServiceName?.trim();
268
+ if (!model || !model.toLowerCase().startsWith("system.ai."))
269
+ return [];
270
+ return [{ model, harness, value }];
271
+ });
272
+ }
273
+ /**
274
+ * Context extractor shared by the gateway, Mastra, and the file/stdin CLI.
275
+ * It favors conversation/task fields and ignores credentials, tool schemas,
276
+ * and tool arguments.
277
+ */
278
+ export class SmartRouterContextBuilder {
279
+ tokenBudget;
280
+ constructor(tokenBudget = 4_096) {
281
+ this.tokenBudget = tokenBudget;
282
+ }
283
+ /** Return only the bounded task prompt required by routes:select. */
284
+ build(input) {
285
+ return this.analyze(input).task;
286
+ }
287
+ /** Return bounded task text plus logical-turn metadata used for pinning. */
288
+ analyze(input) {
289
+ const normalized = parseJsonString(input);
290
+ const events = conversationEvents(normalized);
291
+ if (events.length > 0)
292
+ return contextFromEvents(events, this.tokenBudget);
293
+ const values = collectTaskStrings(normalized);
294
+ const task = truncateText(values.join("\n"), this.tokenBudget, "start");
295
+ return { task, logicalTurn: task, continuation: false };
296
+ }
297
+ }
298
+ /** Smart Router orchestration shared by Responses, Chat Completions, and Messages. */
299
+ export class SmartModelRouter {
300
+ store;
301
+ client;
302
+ service;
303
+ settings;
304
+ constructor(settings = {}, service = undefined, store = new AppKitSmartRouterStore(), client) {
305
+ this.store = store;
306
+ this.client = client;
307
+ this.settings = { ...SMART_ROUTER_DEFAULT_SETTINGS, ...settings };
308
+ this.service = service ?? new SmartRouterService(this.settings);
309
+ }
310
+ /** Probe whether Smart Router is usable for the current model catalogue. */
311
+ isEnabled(targets) {
312
+ const candidates = smartRouterCandidates(targets.filter((target) => target.capabilities.chat && target.capabilities.aiGatewayCodex), "codex");
313
+ return this.client
314
+ ? this.service.isEnabled(candidates, this.client)
315
+ : this.service.isEnabled(candidates);
316
+ }
317
+ /** Resolve one virtual smart-router request to a concrete compatible target. */
318
+ async resolve(input) {
319
+ const harness = input.protocol === "anthropic-messages" ? "claude" : "codex";
320
+ const explicitReasoningEffort = requestedReasoningEffort(input.body);
321
+ const eligibleTargets = input.targets.filter((target) => isEligibleTarget(target, { ...input, originator: input.headers.get("originator") ?? undefined }, explicitReasoningEffort, harness));
322
+ const candidates = smartRouterCandidates(eligibleTargets, harness);
323
+ if (candidates.length === 0) {
324
+ throw new SmartRouterError(400, "No compatible system models are available to Databricks Smart Router");
325
+ }
326
+ const context = this.service.context.analyze(input.body);
327
+ if (!context.task) {
328
+ throw new SmartRouterError(400, "Smart Router request contains no task text");
329
+ }
330
+ const key = smartRouterTurnKey(context.logicalTurn, candidates, {
331
+ harness,
332
+ protocol: input.protocol,
333
+ features: input.features,
334
+ ...(explicitReasoningEffort ? { explicitReasoningEffort } : {}),
335
+ });
336
+ const cached = context.continuation ? await this.readCached(key, eligibleTargets) : undefined;
337
+ if (cached) {
338
+ return {
339
+ target: eligibleTargets.find((target) => target.id === cached.selectedModel),
340
+ body: input.body,
341
+ observation: { ...cached, source: "cache" },
342
+ };
343
+ }
344
+ const selected = await this.service.select(context.task, candidates, {
345
+ signal: input.signal,
346
+ ...(this.client ? { client: this.client } : {}),
347
+ });
348
+ const target = selected.value;
349
+ const observation = SmartRouterObservationSchema.parse({
350
+ selectedModel: target.id,
351
+ routeModel: selected.routeModel,
352
+ harness: selected.harness,
353
+ routerName: selected.routerName,
354
+ source: "router",
355
+ latencyMs: selected.latencyMs,
356
+ ...(selected.rationale ? { rationale: selected.rationale } : {}),
357
+ ...(selected.params ? { params: selected.params } : {}),
358
+ });
359
+ await this.writeCached(key, observation);
360
+ logger.debug("selected Smart Router model", {
361
+ candidateCount: candidates.length,
362
+ harness,
363
+ latencyMs: observation.latencyMs,
364
+ model: observation.selectedModel,
365
+ routeModel: observation.routeModel,
366
+ routerName: observation.routerName,
367
+ });
368
+ return { target, body: input.body, observation };
369
+ }
370
+ async readCached(key, targets) {
371
+ try {
372
+ const parsed = SmartRouterObservationSchema.safeParse(await this.store.get(key));
373
+ if (!parsed.success)
374
+ return undefined;
375
+ return targets.some((target) => target.id === parsed.data.selectedModel)
376
+ ? parsed.data
377
+ : undefined;
378
+ }
379
+ catch (error) {
380
+ logger.debug("Smart Router cache read failed", { error: toError(error) });
381
+ return undefined;
382
+ }
383
+ }
384
+ async writeCached(key, observation) {
385
+ try {
386
+ await this.store.set(key, observation, this.settings.routeTtlSeconds);
387
+ }
388
+ catch (error) {
389
+ logger.debug("Smart Router cache write failed", { error: toError(error) });
390
+ }
391
+ }
392
+ }
393
+ /** Stable logical-turn key shared by initial requests and tool continuations. */
394
+ export function smartRouterTurnKey(logicalTurn, candidates, context) {
395
+ return createHash("sha256")
396
+ .update(JSON.stringify({
397
+ logicalTurn,
398
+ candidates: candidates.map(({ model, harness }) => ({ model, harness })),
399
+ context,
400
+ }))
401
+ .digest("hex");
402
+ }
403
+ function isEligibleTarget(target, input, explicitReasoningEffort, harness) {
404
+ if (!target.endpoint || target.endpoint.status?.deprecated === true)
405
+ return false;
406
+ if (!target.modelServiceName?.toLowerCase().startsWith("system.ai."))
407
+ return false;
408
+ if (!target.capabilities.chat)
409
+ return false;
410
+ if (harness === "codex" && !target.capabilities.aiGatewayCodex)
411
+ return false;
412
+ if (harness === "claude" && !target.capabilities.anthropic)
413
+ return false;
414
+ if (input.features.tools && !target.capabilities.tools)
415
+ return false;
416
+ if (input.features.parallelTools && !target.capabilities.parallelTools)
417
+ return false;
418
+ if (input.features.customTools && !target.capabilities.customTools)
419
+ return false;
420
+ if (input.features.structuredOutput && !target.capabilities.structuredOutput)
421
+ return false;
422
+ if (input.features.webSearch && !target.capabilities.webSearch)
423
+ return false;
424
+ if (input.features.imageInput && !target.capabilities.imageInput)
425
+ return false;
426
+ if (input.features.applyPatch && !target.capabilities.applyPatch)
427
+ return false;
428
+ if (input.features.reasoning && !target.capabilities.reasoning)
429
+ return false;
430
+ if (explicitReasoningEffort &&
431
+ explicitReasoningEffort !== "none" &&
432
+ !target.reasoningEfforts.includes(explicitReasoningEffort)) {
433
+ return false;
434
+ }
435
+ try {
436
+ resolveRoute({
437
+ clientProtocol: input.protocol,
438
+ ...(input.originator ? { originator: input.originator } : {}),
439
+ preferSystemModels: input.preferSystemModels,
440
+ features: input.features,
441
+ target,
442
+ });
443
+ return true;
444
+ }
445
+ catch {
446
+ return false;
447
+ }
448
+ }
449
+ function requestedReasoningEffort(body) {
450
+ const reasoning = isRecord(body.reasoning) ? body.reasoning : undefined;
451
+ const outputConfig = isRecord(body.output_config) ? body.output_config : undefined;
452
+ const raw = body.reasoning_effort ?? reasoning?.effort ?? outputConfig?.effort;
453
+ if (raw === undefined || raw === null)
454
+ return undefined;
455
+ const normalized = String(raw).trim().toLowerCase().replaceAll("_", "-");
456
+ const parsed = ReasoningEffortSchema.safeParse(normalized === "extra-high" ? "xhigh" : normalized);
457
+ if (!parsed.success) {
458
+ throw new SmartRouterError(400, `Unsupported Smart Router reasoning effort: ${String(raw)}`);
459
+ }
460
+ return parsed.data;
461
+ }
462
+ function contextFromEvents(events, tokenBudget) {
463
+ const latestUserIndex = lastEventIndex(events, "user");
464
+ const taskEvent = latestUserIndex >= 0 ? events[latestUserIndex] : events.at(-1);
465
+ const task = truncateText(taskEvent?.text ?? "", tokenBudget, "start");
466
+ let remaining = Math.max(0, tokenBudget - countTokens(task));
467
+ const context = [];
468
+ for (let index = (taskEvent ? events.indexOf(taskEvent) : events.length) - 1; index >= 0; index -= 1) {
469
+ const event = events[index];
470
+ if (!event || !event.text || event.role === "tool")
471
+ continue;
472
+ const value = `${event.role}: ${event.text}`;
473
+ const retained = truncateText(value, remaining, "end");
474
+ if (!retained)
475
+ break;
476
+ context.unshift(retained);
477
+ remaining -= countTokens(retained);
478
+ }
479
+ const combined = [...context, task].filter(Boolean).join("\n");
480
+ const logicalEvents = latestUserIndex >= 0 ? events.slice(0, latestUserIndex + 1) : events;
481
+ return {
482
+ task: combined,
483
+ logicalTurn: logicalEvents.map((event) => `${event.role}:${event.text}`).join("\n"),
484
+ continuation: latestUserIndex >= 0 &&
485
+ events.slice(latestUserIndex + 1).some((event) => event.role !== "system"),
486
+ };
487
+ }
488
+ function conversationEvents(input) {
489
+ if (typeof input === "string")
490
+ return input.trim() ? [{ role: "user", text: input.trim() }] : [];
491
+ if (Array.isArray(input))
492
+ return input.flatMap(messageEvent);
493
+ if (!isRecord(input))
494
+ return [];
495
+ for (const key of ["messages", "input"]) {
496
+ const value = input[key];
497
+ if (typeof value === "string" && value.trim())
498
+ return [{ role: "user", text: value.trim() }];
499
+ if (Array.isArray(value)) {
500
+ const events = value.flatMap(messageEvent);
501
+ if (events.length > 0)
502
+ return events;
503
+ }
504
+ }
505
+ return [];
506
+ }
507
+ function messageEvent(value) {
508
+ if (typeof value === "string")
509
+ return value.trim() ? [{ role: "user", text: value.trim() }] : [];
510
+ if (!isRecord(value))
511
+ return [];
512
+ const role = messageRole(value);
513
+ if (!role)
514
+ return [];
515
+ const text = contentText(value.content ?? value.text ?? value.input_text ?? value.output_text);
516
+ return text ? [{ role, text }] : [];
517
+ }
518
+ function messageRole(value) {
519
+ if (value.role === "user" || value.role === "assistant" || value.role === "system") {
520
+ return value.role;
521
+ }
522
+ if (value.role === "tool" ||
523
+ value.type === "function_call_output" ||
524
+ value.type === "tool_result") {
525
+ return "tool";
526
+ }
527
+ if (value.type === "function_call" || value.type === "reasoning")
528
+ return "assistant";
529
+ if (value.type === "message" && value.role === undefined)
530
+ return "user";
531
+ return undefined;
532
+ }
533
+ function contentText(value) {
534
+ if (typeof value === "string")
535
+ return value.trim();
536
+ if (Array.isArray(value))
537
+ return value.map(contentText).filter(Boolean).join("\n");
538
+ if (!isRecord(value))
539
+ return "";
540
+ for (const key of ["text", "input_text", "output_text", "content"]) {
541
+ const text = contentText(value[key]);
542
+ if (text)
543
+ return text;
544
+ }
545
+ return "";
546
+ }
547
+ const TASK_KEYS = [
548
+ "prompt",
549
+ "task",
550
+ "query",
551
+ "question",
552
+ "request",
553
+ "description",
554
+ "message",
555
+ "text",
556
+ "input",
557
+ ];
558
+ const IGNORED_KEYS = new Set([
559
+ "api_key",
560
+ "authorization",
561
+ "arguments",
562
+ "credentials",
563
+ "headers",
564
+ "metadata",
565
+ "password",
566
+ "secret",
567
+ "token",
568
+ "tools",
569
+ ]);
570
+ function collectTaskStrings(input) {
571
+ if (typeof input === "string")
572
+ return input.trim() ? [input.trim()] : [];
573
+ const preferred = [];
574
+ if (isRecord(input)) {
575
+ for (const key of TASK_KEYS)
576
+ preferred.push(...stringLeaves(input[key], key, 0));
577
+ }
578
+ return preferred.length > 0 ? preferred.slice(0, 32) : stringLeaves(input, "", 0).slice(0, 32);
579
+ }
580
+ function stringLeaves(value, key, depth) {
581
+ if (depth > 6 || IGNORED_KEYS.has(key.toLowerCase()))
582
+ return [];
583
+ if (typeof value === "string")
584
+ return value.trim() ? [value.trim()] : [];
585
+ if (Array.isArray(value))
586
+ return value.flatMap((item) => stringLeaves(item, key, depth + 1));
587
+ if (!isRecord(value))
588
+ return [];
589
+ return Object.entries(value).flatMap(([childKey, child]) => stringLeaves(child, childKey, depth + 1));
590
+ }
591
+ function parseJsonString(input) {
592
+ if (typeof input !== "string")
593
+ return input;
594
+ const trimmed = input.trim();
595
+ if (!trimmed || (!trimmed.startsWith("{") && !trimmed.startsWith("[")))
596
+ return input;
597
+ try {
598
+ return JSON.parse(trimmed);
599
+ }
600
+ catch {
601
+ return input;
602
+ }
603
+ }
604
+ function countTokens(text) {
605
+ return CONTEXT_ENCODING.encode(text, [], []).length;
606
+ }
607
+ function truncateText(text, tokenBudget, edge) {
608
+ if (tokenBudget <= 0 || !text)
609
+ return "";
610
+ const tokens = CONTEXT_ENCODING.encode(text, [], []);
611
+ if (tokens.length <= tokenBudget)
612
+ return text;
613
+ return CONTEXT_ENCODING.decode(edge === "start" ? tokens.slice(0, tokenBudget) : tokens.slice(-tokenBudget));
614
+ }
615
+ function lastEventIndex(events, role) {
616
+ for (let index = events.length - 1; index >= 0; index -= 1) {
617
+ if (events[index]?.role === role)
618
+ return index;
619
+ }
620
+ return -1;
621
+ }
622
+ function uniqueCandidates(candidates) {
623
+ const seen = new Set();
624
+ return candidates.filter((candidate) => {
625
+ const key = `${candidate.harness}:${normalizeRouteModel(candidate.model)}`;
626
+ if (seen.has(key))
627
+ return false;
628
+ seen.add(key);
629
+ return true;
630
+ });
631
+ }
632
+ function normalizeRouteModel(model) {
633
+ let normalized = model.trim().toLowerCase().split("/").at(-1) ?? "";
634
+ for (const prefix of ["databricks-", "system.ai."]) {
635
+ if (normalized.startsWith(prefix)) {
636
+ normalized = normalized.slice(prefix.length);
637
+ break;
638
+ }
639
+ }
640
+ return normalized;
641
+ }
642
+ function probeKey(candidates, routerName) {
643
+ return JSON.stringify({
644
+ routerName,
645
+ candidates: candidates
646
+ .map(({ model, harness }) => ({ model: normalizeRouteModel(model), harness }))
647
+ .sort((left, right) => `${left.harness}:${left.model}`.localeCompare(`${right.harness}:${right.model}`)),
648
+ });
649
+ }
650
+ function appKitCacheManager() {
651
+ try {
652
+ return CacheManager.getInstanceSync();
653
+ }
654
+ catch {
655
+ return undefined;
656
+ }
657
+ }
658
+ async function smartRouterProbeIdentity(client) {
659
+ const headers = new Headers();
660
+ const host = (await client.config.getHost()).toString();
661
+ await client.config.authenticate(headers);
662
+ return createHash("sha256")
663
+ .update(host)
664
+ .update("\0")
665
+ .update(headers.get("authorization") ?? "")
666
+ .update("\0")
667
+ .update(headers.get("x-databricks-workspace-id") ?? "")
668
+ .digest("hex");
669
+ }
670
+ async function invokeSmartRouter(client, body, signal, timeoutMs) {
671
+ const host = (await client.config.getHost()).toString();
672
+ const url = new URL("/ai-gateway/routing/v1/routes:select", host);
673
+ const headers = new Headers({ "content-type": "application/json" });
674
+ await client.config.authenticate(headers);
675
+ const combinedSignal = AbortSignal.any([signal, AbortSignal.timeout(timeoutMs)]);
676
+ let response = await fetch(url, {
677
+ method: "POST",
678
+ headers,
679
+ body: JSON.stringify(body),
680
+ signal: combinedSignal,
681
+ });
682
+ if (response.status === 401 && (await refreshWorkspaceClientAuthentication(client))) {
683
+ await response.body?.cancel();
684
+ headers.delete("authorization");
685
+ headers.delete("x-databricks-workspace-id");
686
+ await client.config.authenticate(headers);
687
+ response = await fetch(url, {
688
+ method: "POST",
689
+ headers,
690
+ body: JSON.stringify(body),
691
+ signal: combinedSignal,
692
+ });
693
+ }
694
+ if (!response.ok) {
695
+ const detail = (await response.text().catch(() => "")).trim().slice(0, 500);
696
+ throw new SmartRouterError(response.status === 404 ? 404 : 503, `Databricks Smart Router failed with HTTP ${response.status}${detail ? `: ${detail}` : ""}`);
697
+ }
698
+ return response.json();
699
+ }
700
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnQtcm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NtYXJ0LXJvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUgsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN6QyxPQUFPLEVBQUUsWUFBWSxFQUFFLG1CQUFtQixFQUF3QixNQUFNLG9CQUFvQixDQUFDO0FBQzdGLE9BQU8sRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxvQ0FBb0MsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzdFLE9BQU8sRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxxQkFBcUIsRUFBd0IsTUFBTSx5QkFBeUIsQ0FBQztBQUN0RixPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLDRCQUE0QixFQUM1Qix3QkFBd0IsRUFDeEIseUJBQXlCLEdBTzFCLE1BQU0saUNBQWlDLENBQUM7QUFDekMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sU0FBUyxNQUFNLDhCQUE4QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFFeEIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUUzQyxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLG1DQUFtQyxDQUFDLENBQUM7QUFDL0QsTUFBTSxxQkFBcUIsR0FBRyw0QkFBNEIsQ0FBQztBQUMzRCxNQUFNLG9CQUFvQixHQUFHLENBQUMsQ0FBQztBQUMvQixNQUFNLHFCQUFxQixHQUFHLGtDQUFrQyxDQUFDO0FBQ2pFLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxDQUFDO0FBQzlCLE1BQU0sVUFBVSxHQUFHLDJEQUEyRCxDQUFDO0FBQy9FLE1BQU0scUJBQXFCLEdBQUcsTUFBTSxDQUFDO0FBQ3JDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7QUFZakQsd0VBQXdFO0FBQ3hFLE1BQU0sQ0FBQyxNQUFNLDZCQUE2QixHQUF3QixNQUFNLENBQUMsTUFBTSxDQUFDO0lBQzlFLGtCQUFrQixFQUFFLEtBQUs7SUFDekIsc0JBQXNCLEVBQUUsU0FBUztJQUNqQyxVQUFVLEVBQUUsT0FBTztJQUNuQixlQUFlLEVBQUUsTUFBTTtJQUN2QixVQUFVLEVBQUUsaUJBQWlCO0lBQzdCLFNBQVMsRUFBRSxNQUFNO0NBQ2xCLENBQUMsQ0FBQztBQTBCSCxNQUFNLENBQUMsTUFBTSw0QkFBNEIsR0FBRyxDQUFDO0tBQzFDLE1BQU0sQ0FBQztJQUNOLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDLGdEQUFnRCxDQUFDO0lBQy9FLFNBQVMsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLG1EQUFtRCxDQUFDO0NBQzFGLENBQUM7S0FDRCxRQUFRLENBQUMsaURBQWlELENBQUMsQ0FBQztBQTZCL0QsMEZBQTBGO0FBQzFGLE1BQU0sT0FBTyxnQkFBaUIsU0FBUSxLQUFLO0lBRTlCO0lBRFgsWUFDVyxNQUFjLEVBQ3ZCLE9BQWU7UUFFZixLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFITixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBSXZCLElBQUksQ0FBQyxJQUFJLEdBQUcsa0JBQWtCLENBQUM7SUFDakMsQ0FBQztDQUNGO0FBRUQsdUZBQXVGO0FBQ3ZGLE1BQU0sT0FBTyxzQkFBc0I7SUFDakMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFXO1FBQ25CLE1BQU0sS0FBSyxHQUFHLE1BQU0sWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQy9DLE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUMscUJBQXFCLEVBQUUsb0JBQW9CLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzFGLENBQUM7SUFFRCxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQVcsRUFBRSxLQUE2QixFQUFFLFVBQWtCO1FBQ3RFLE1BQU0sS0FBSyxHQUFHLE1BQU0sWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQy9DLE1BQU0sS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUMscUJBQXFCLEVBQUUsb0JBQW9CLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUU7WUFDNUYsR0FBRyxFQUFFLFVBQVU7U0FDaEIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBRUQsa0ZBQWtGO0FBQ2xGLE1BQU0sT0FBTywyQkFBMkI7SUFDdEMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFXLEVBQUUsTUFBdUI7UUFDNUMsTUFBTSxLQUFLLEdBQUcsa0JBQWtCLEVBQUUsQ0FBQztRQUNuQyxJQUFJLENBQUMsS0FBSztZQUFFLE9BQU8sU0FBUyxDQUFDO1FBQzdCLE1BQU0sUUFBUSxHQUFHLE1BQU0sd0JBQXdCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDeEQsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUNkLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQyxxQkFBcUIsRUFBRSxtQkFBbUIsQ0FBQyxFQUFFLEdBQUcsUUFBUSxJQUFJLEdBQUcsRUFBRSxDQUFDLENBQ3RGLENBQUM7SUFDSixDQUFDO0lBRUQsS0FBSyxDQUFDLEdBQUcsQ0FDUCxHQUFXLEVBQ1gsS0FBNkIsRUFDN0IsVUFBa0IsRUFDbEIsTUFBdUI7UUFFdkIsTUFBTSxLQUFLLEdBQUcsa0JBQWtCLEVBQUUsQ0FBQztRQUNuQyxJQUFJLENBQUMsS0FBSztZQUFFLE9BQU87UUFDbkIsTUFBTSxRQUFRLEdBQUcsTUFBTSx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4RCxNQUFNLEtBQUssQ0FBQyxHQUFHLENBQ2IsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLHFCQUFxQixFQUFFLG1CQUFtQixDQUFDLEVBQUUsR0FBRyxRQUFRLElBQUksR0FBRyxFQUFFLENBQUMsRUFDckYsS0FBSyxFQUNMLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxDQUNwQixDQUFDO0lBQ0osQ0FBQztDQUNGO0FBaUJEOzs7R0FHRztBQUNILE1BQU0sT0FBTyxrQkFBa0I7SUFTVjtJQUNBO0lBVFYsT0FBTyxDQUE0QjtJQUMzQixRQUFRLENBQXNCO0lBQzlCLE1BQU0sR0FBRyxJQUFJLE9BQU8sRUFBaUMsQ0FBQztJQUN0RCxTQUFTLEdBQUcsSUFBSSxPQUFPLEVBQXVCLENBQUM7SUFDL0MsV0FBVyxHQUFHLElBQUksR0FBRyxFQUF5QixDQUFDO0lBRWhFLFlBQ0UsV0FBeUMsRUFBRSxFQUMxQixTQUE2QixpQkFBaUIsRUFDOUMsYUFBb0MsSUFBSSwyQkFBMkIsRUFBRTtRQURyRSxXQUFNLEdBQU4sTUFBTSxDQUF3QztRQUM5QyxlQUFVLEdBQVYsVUFBVSxDQUEyRDtRQUV0RixJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsR0FBRyw2QkFBNkIsRUFBRSxHQUFHLFFBQVEsRUFBRSxDQUFDO1FBQ2xFLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDakYsQ0FBQztJQUVELDREQUE0RDtJQUM1RCxLQUFLLENBQUMsTUFBTSxDQUNWLEtBQWMsRUFDZCxVQUE4QyxFQUM5QyxVQUFvQyxFQUFFO1FBRXRDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxJQUFJO1lBQUUsTUFBTSxJQUFJLGdCQUFnQixDQUFDLEdBQUcsRUFBRSw4Q0FBOEMsQ0FBQyxDQUFDO1FBQzNGLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksbUJBQW1CLEVBQUUsQ0FBQyxNQUFNLENBQUM7UUFDOUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsRUFBRSxHQUFHLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQ2xGLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztZQUM3QyxPQUFPLFNBQVMsQ0FBQztRQUNuQixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDN0MsTUFBTSxLQUFLLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUVELDBGQUEwRjtJQUMxRixLQUFLLENBQUMsU0FBUyxDQUNiLFVBQThDLEVBQzlDLE1BQU0sR0FBRyxtQkFBbUIsRUFBRSxDQUFDLE1BQU07UUFFckMsTUFBTSxPQUFPLEdBQUcsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDN0MsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUN2QyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN4RCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ25DLE1BQU0sS0FBSyxHQUFHLE1BQU0sUUFBUSxDQUMxQixLQUFLLEVBQ0wsR0FBRyxFQUNILEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsRUFDMUM7WUFDRSxHQUFHLEVBQUUsSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUMzQixpQkFBaUIsRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7U0FDekUsQ0FDRixDQUFDO1FBQ0YsT0FBTyxLQUFLLEVBQUUsT0FBTyxJQUFJLEtBQUssQ0FBQztJQUNqQyxDQUFDO0lBRUQsMkVBQTJFO0lBQzNFLE9BQU87UUFDTCxLQUFLLE1BQU0sS0FBSyxJQUFJLElBQUksQ0FBQyxXQUFXO1lBQUUsS0FBSyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRU8sS0FBSyxDQUFDLFNBQVMsQ0FDckIsR0FBVyxFQUNYLFVBQThDLEVBQzlDLE1BQXVCO1FBRXZCLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDdkQsSUFBSSxNQUFNLElBQUksTUFBTSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFO1lBQUUsT0FBTyxNQUFNLENBQUM7UUFDM0QsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVPLEtBQUssQ0FBQyxZQUFZLENBQ3hCLEdBQVcsRUFDWCxVQUE4QyxFQUM5QyxNQUF1QjtRQUV2QixNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLFVBQVUsRUFBRSxFQUFFLE1BQU0sRUFBRSxDQUFDO2FBQ3RFLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7YUFDaEIsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDZixNQUFNLENBQUMsS0FBSyxDQUFDLDJDQUEyQyxFQUFFLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDckYsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDLENBQUMsQ0FBQztRQUNMLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDeEMsS0FBSyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMvQyxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFTyxhQUFhLENBQ25CLFVBQThDLEVBQzlDLE1BQXVCLEVBQ3ZCLE9BQWdCO1FBRWhCLE1BQU0sT0FBTyxHQUFHLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzdDLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDO1lBQUUsT0FBTztRQUNqQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN4RCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ25DLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDeEMsS0FBSyxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMvQyxLQUFLLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFTyxtQkFBbUIsQ0FDekIsVUFBOEMsRUFDOUMsTUFBdUI7UUFFdkIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN0QyxNQUFNLE9BQU8sR0FBRyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUM3QyxNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDakUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxZQUFZLENBQUMsQ0FBQztRQUM1QyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBZ0IsQ0FBQyxJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztRQUNwRixLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdEMsS0FBSyxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMvQyxLQUFLLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2pELENBQUM7SUFDSCxDQUFDO0lBRU8sV0FBVyxDQUFDLE9BQWdCO1FBQ2xDLE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7SUFDckUsQ0FBQztJQUVPLEtBQUssQ0FBQyxlQUFlLENBQzNCLEdBQVcsRUFDWCxNQUF1QjtRQUV2QixJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyw0QkFBNEIsQ0FBQyxTQUFTLENBQUMsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUM5RixPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUNsRCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sQ0FBQyxLQUFLLENBQUMsc0NBQXNDLEVBQUUsRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNoRixPQUFPLFNBQVMsQ0FBQztRQUNuQixDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQyxpQkFBaUIsQ0FDN0IsS0FBNEIsRUFDNUIsR0FBVyxFQUNYLEtBQTZCO1FBRTdCLElBQUksQ0FBQztZQUNILE1BQU0sS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDL0QsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLENBQUMsS0FBSyxDQUFDLCtDQUErQyxFQUFFLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDM0YsQ0FBQztJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsZ0JBQWdCLENBQzVCLEdBQVcsRUFDWCxLQUE2QixFQUM3QixNQUF1QjtRQUV2QixJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUN2QixHQUFHLEVBQ0gsS0FBSyxFQUNMLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxHQUFHLEtBQUssQ0FBQyxDQUFDLEVBQ3RELE1BQU0sQ0FDUCxDQUFDO1FBQ0osQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLENBQUMsS0FBSyxDQUFDLHVDQUF1QyxFQUFFLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDbkYsQ0FBQztJQUNILENBQUM7SUFFTyxVQUFVLENBQUMsTUFBdUI7UUFDeEMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLE1BQWdCLENBQUM7UUFDdEMsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsS0FBSyxHQUFHLFdBQVcsQ0FBQyxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDekQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzlCLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzlCLENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFTyxnQkFBZ0IsQ0FBQyxNQUF1QixFQUFFLEdBQVc7UUFDM0QsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLE1BQWdCLENBQUM7UUFDdEMsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDckMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ1YsSUFBSSxHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2xDLENBQUM7UUFDRCxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2hCLENBQUM7SUFFTyxlQUFlO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLHNCQUFzQixFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3RGLENBQUM7SUFFTyxRQUFRLENBQUMsT0FBZ0I7UUFDL0IsT0FBTyxPQUFPO1lBQ1osQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVTtZQUMxQixDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFFTyxzQkFBc0IsQ0FBQyxPQUFnQjtRQUM3QyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxzQkFBc0IsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDaEYsQ0FBQztJQUVPLEtBQUssQ0FBQyxVQUFVLENBQ3RCLElBQVksRUFDWixVQUE4QyxFQUM5QyxPQUFpQztRQUVqQyxNQUFNLE9BQU8sR0FBRyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUM3QyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDekIsTUFBTSxJQUFJLGdCQUFnQixDQUFDLEdBQUcsRUFBRSwyREFBMkQsQ0FBQyxDQUFDO1FBQy9GLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyx3QkFBd0IsQ0FBQyxLQUFLLENBQUM7WUFDN0MsYUFBYSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1lBQ3hFLElBQUksRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7WUFDdEIsY0FBYyxFQUFFLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFO1NBQzFELENBQUMsQ0FBQztRQUNILE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksbUJBQW1CLEVBQUUsQ0FBQyxNQUFNLENBQUM7UUFDOUQsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sSUFBSSxJQUFJLGVBQWUsRUFBRSxDQUFDLE1BQU0sQ0FBQztRQUM5RCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDN0IsTUFBTSxRQUFRLEdBQUcseUJBQXlCLENBQUMsS0FBSyxDQUM5QyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FDcEUsQ0FBQztRQUNGLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFFLENBQUM7UUFDL0MsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FDM0IsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUNaLG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUM7WUFDbEMsbUJBQW1CLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUM7WUFDbkQsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsT0FBTyxJQUFJLFNBQVMsQ0FBQyxPQUFPLEtBQUssU0FBUyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FDNUYsQ0FBQztRQUNGLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNkLE1BQU0sSUFBSSxnQkFBZ0IsQ0FDeEIsR0FBRyxFQUNILCtDQUErQyxTQUFTLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxDQUM5RSxDQUFDO1FBQ0osQ0FBQztRQUNELE9BQU87WUFDTCxLQUFLLEVBQUUsUUFBUSxDQUFDLEtBQUs7WUFDckIsVUFBVSxFQUFFLFNBQVMsQ0FBQyxZQUFZLENBQUMsS0FBSztZQUN4QyxPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU87WUFDekIsVUFBVSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVTtZQUNwQyxTQUFTLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLFNBQVM7WUFDakMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLFFBQVEsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ2hFLEdBQUcsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztTQUMxRCxDQUFDO0lBQ0osQ0FBQztDQUNGO0FBRUQsaUZBQWlGO0FBQ2pGLE1BQU0sVUFBVSxxQkFBcUIsQ0FDbkMsTUFBb0IsRUFDcEIsT0FBMkI7SUFFM0IsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7UUFDOUIsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLGdCQUFnQixFQUFFLElBQUksRUFBRSxDQUFDO1FBQzdDLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQztZQUFFLE9BQU8sRUFBRSxDQUFDO1FBQ3ZFLE9BQU8sQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUNyQyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLHlCQUF5QjtJQUNQO0lBQTdCLFlBQTZCLGNBQWMsS0FBSztRQUFuQixnQkFBVyxHQUFYLFdBQVcsQ0FBUTtJQUFHLENBQUM7SUFFcEQscUVBQXFFO0lBQ3JFLEtBQUssQ0FBQyxLQUFjO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDbEMsQ0FBQztJQUVELDRFQUE0RTtJQUM1RSxPQUFPLENBQUMsS0FBYztRQUNwQixNQUFNLFVBQVUsR0FBRyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUMsTUFBTSxNQUFNLEdBQUcsa0JBQWtCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDOUMsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUM7WUFBRSxPQUFPLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDMUUsTUFBTSxNQUFNLEdBQUcsa0JBQWtCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDOUMsTUFBTSxJQUFJLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN4RSxPQUFPLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxDQUFDO0lBQzFELENBQUM7Q0FDRjtBQUVELHNGQUFzRjtBQUN0RixNQUFNLE9BQU8sZ0JBQWdCO0lBT1I7SUFDQTtJQVBWLE9BQU8sQ0FBcUI7SUFDcEIsUUFBUSxDQUFzQjtJQUUvQyxZQUNFLFdBQXlDLEVBQUUsRUFDM0MsVUFBMEMsU0FBUyxFQUNsQyxRQUEwQixJQUFJLHNCQUFzQixFQUFFLEVBQ3RELE1BQXdCO1FBRHhCLFVBQUssR0FBTCxLQUFLLENBQWlEO1FBQ3RELFdBQU0sR0FBTixNQUFNLENBQWtCO1FBRXpDLElBQUksQ0FBQyxRQUFRLEdBQUcsRUFBRSxHQUFHLDZCQUE2QixFQUFFLEdBQUcsUUFBUSxFQUFFLENBQUM7UUFDbEUsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLElBQUksSUFBSSxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUVELDRFQUE0RTtJQUM1RSxTQUFTLENBQUMsT0FBK0I7UUFDdkMsTUFBTSxVQUFVLEdBQUcscUJBQXFCLENBQ3RDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDLEVBQzFGLE9BQU8sQ0FDUixDQUFDO1FBQ0YsT0FBTyxJQUFJLENBQUMsTUFBTTtZQUNoQixDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUM7WUFDakQsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRCxnRkFBZ0Y7SUFDaEYsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQVFiO1FBQ0MsTUFBTSxPQUFPLEdBQ1gsS0FBSyxDQUFDLFFBQVEsS0FBSyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7UUFDL0QsTUFBTSx1QkFBdUIsR0FBRyx3QkFBd0IsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckUsTUFBTSxlQUFlLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUN0RCxnQkFBZ0IsQ0FDZCxNQUFNLEVBQ04sRUFBRSxHQUFHLEtBQUssRUFBRSxVQUFVLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLElBQUksU0FBUyxFQUFFLEVBQ3RFLHVCQUF1QixFQUN2QixPQUFPLENBQ1IsQ0FDRixDQUFDO1FBQ0YsTUFBTSxVQUFVLEdBQUcscUJBQXFCLENBQUMsZUFBZSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ25FLElBQUksVUFBVSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM1QixNQUFNLElBQUksZ0JBQWdCLENBQ3hCLEdBQUcsRUFDSCxzRUFBc0UsQ0FDdkUsQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3pELElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDbEIsTUFBTSxJQUFJLGdCQUFnQixDQUFDLEdBQUcsRUFBRSw0Q0FBNEMsQ0FBQyxDQUFDO1FBQ2hGLENBQUM7UUFDRCxNQUFNLEdBQUcsR0FBRyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLFVBQVUsRUFBRTtZQUM5RCxPQUFPO1lBQ1AsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO1lBQ3hCLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUTtZQUN4QixHQUFHLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLEVBQUUsdUJBQXVCLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQ2hFLENBQUMsQ0FBQztRQUNILE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUM5RixJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsT0FBTztnQkFDTCxNQUFNLEVBQUUsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsS0FBSyxNQUFNLENBQUMsYUFBYSxDQUFFO2dCQUM3RSxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7Z0JBQ2hCLFdBQVcsRUFBRSxFQUFFLEdBQUcsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUU7YUFDNUMsQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFO1lBQ25FLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtZQUNwQixHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7U0FDaEQsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQztRQUM5QixNQUFNLFdBQVcsR0FBRyw0QkFBNEIsQ0FBQyxLQUFLLENBQUM7WUFDckQsYUFBYSxFQUFFLE1BQU0sQ0FBQyxFQUFFO1lBQ3hCLFVBQVUsRUFBRSxRQUFRLENBQUMsVUFBVTtZQUMvQixPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU87WUFDekIsVUFBVSxFQUFFLFFBQVEsQ0FBQyxVQUFVO1lBQy9CLE1BQU0sRUFBRSxRQUFRO1lBQ2hCLFNBQVMsRUFBRSxRQUFRLENBQUMsU0FBUztZQUM3QixHQUFHLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUUsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDaEUsR0FBRyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQ3hELENBQUMsQ0FBQztRQUNILE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDekMsTUFBTSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsRUFBRTtZQUMxQyxjQUFjLEVBQUUsVUFBVSxDQUFDLE1BQU07WUFDakMsT0FBTztZQUNQLFNBQVMsRUFBRSxXQUFXLENBQUMsU0FBUztZQUNoQyxLQUFLLEVBQUUsV0FBVyxDQUFDLGFBQWE7WUFDaEMsVUFBVSxFQUFFLFdBQVcsQ0FBQyxVQUFVO1lBQ2xDLFVBQVUsRUFBRSxXQUFXLENBQUMsVUFBVTtTQUNuQyxDQUFDLENBQUM7UUFDSCxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRSxDQUFDO0lBQ25ELENBQUM7SUFFTyxLQUFLLENBQUMsVUFBVSxDQUN0QixHQUFXLEVBQ1gsT0FBK0I7UUFFL0IsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsNEJBQTRCLENBQUMsU0FBUyxDQUFDLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNqRixJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU87Z0JBQUUsT0FBTyxTQUFTLENBQUM7WUFDdEMsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxLQUFLLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDO2dCQUN0RSxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUk7Z0JBQ2IsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUNoQixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sQ0FBQyxLQUFLLENBQUMsZ0NBQWdDLEVBQUUsRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMxRSxPQUFPLFNBQVMsQ0FBQztRQUNuQixDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQyxXQUFXLENBQUMsR0FBVyxFQUFFLFdBQW1DO1FBQ3hFLElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsRUFBRSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzdFLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUFFRCxpRkFBaUY7QUFDakYsTUFBTSxVQUFVLGtCQUFrQixDQUNoQyxXQUFtQixFQUNuQixVQUFvRCxFQUNwRCxPQUEwQztJQUUxQyxPQUFPLFVBQVUsQ0FBQyxRQUFRLENBQUM7U0FDeEIsTUFBTSxDQUNMLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDYixXQUFXO1FBQ1gsVUFBVSxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ3hFLE9BQU87S0FDUixDQUFDLENBQ0g7U0FDQSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDbkIsQ0FBQztBQUVELFNBQVMsZ0JBQWdCLENBQ3ZCLE1BQW1CLEVBQ25CLEtBS0MsRUFDRCx1QkFBb0QsRUFDcEQsT0FBMkI7SUFFM0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsVUFBVSxLQUFLLElBQUk7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUNsRixJQUFJLENBQUMsTUFBTSxDQUFDLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUNuRixJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxJQUFJO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDNUMsSUFBSSxPQUFPLEtBQUssT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxjQUFjO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDN0UsSUFBSSxPQUFPLEtBQUssUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxTQUFTO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDekUsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsS0FBSztRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3JFLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxhQUFhLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLGFBQWE7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUNyRixJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsV0FBVyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxXQUFXO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDakYsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLGdCQUFnQixJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxnQkFBZ0I7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUMzRixJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsU0FBUyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxTQUFTO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDN0UsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLFVBQVUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsVUFBVTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQy9FLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxVQUFVLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLFVBQVU7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUMvRSxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsU0FBUyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxTQUFTO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDN0UsSUFDRSx1QkFBdUI7UUFDdkIsdUJBQXVCLEtBQUssTUFBTTtRQUNsQyxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsdUJBQXVCLENBQUMsRUFDMUQsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELElBQUksQ0FBQztRQUNILFlBQVksQ0FBQztZQUNYLGNBQWMsRUFBRSxLQUFLLENBQUMsUUFBUTtZQUM5QixHQUFHLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDN0Qsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLGtCQUFrQjtZQUM1QyxRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVE7WUFDeEIsTUFBTTtTQUNQLENBQUMsQ0FBQztRQUNILE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztBQUNILENBQUM7QUFFRCxTQUFTLHdCQUF3QixDQUMvQixJQUF1QztJQUV2QyxNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDeEUsTUFBTSxZQUFZLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ25GLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxTQUFTLEVBQUUsTUFBTSxJQUFJLFlBQVksRUFBRSxNQUFNLENBQUM7SUFDL0UsSUFBSSxHQUFHLEtBQUssU0FBUyxJQUFJLEdBQUcsS0FBSyxJQUFJO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDeEQsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDekUsTUFBTSxNQUFNLEdBQUcscUJBQXFCLENBQUMsU0FBUyxDQUM1QyxVQUFVLEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FDbkQsQ0FBQztJQUNGLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDcEIsTUFBTSxJQUFJLGdCQUFnQixDQUFDLEdBQUcsRUFBRSw4Q0FBOEMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUMvRixDQUFDO0lBQ0QsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDO0FBQ3JCLENBQUM7QUFPRCxTQUFTLGlCQUFpQixDQUN4QixNQUFvQyxFQUNwQyxXQUFtQjtJQUVuQixNQUFNLGVBQWUsR0FBRyxjQUFjLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3ZELE1BQU0sU0FBUyxHQUFHLGVBQWUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2pGLE1BQU0sSUFBSSxHQUFHLFlBQVksQ0FBQyxTQUFTLEVBQUUsSUFBSSxJQUFJLEVBQUUsRUFBRSxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDdkUsSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsV0FBVyxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzdELE1BQU0sT0FBTyxHQUFhLEVBQUUsQ0FBQztJQUM3QixLQUNFLElBQUksS0FBSyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUN2RSxLQUFLLElBQUksQ0FBQyxFQUNWLEtBQUssSUFBSSxDQUFDLEVBQ1YsQ0FBQztRQUNELE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QixJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLE1BQU07WUFBRSxTQUFTO1FBQzdELE1BQU0sS0FBSyxHQUFHLEdBQUcsS0FBSyxDQUFDLElBQUksS0FBSyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDN0MsTUFBTSxRQUFRLEdBQUcsWUFBWSxDQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLFFBQVE7WUFBRSxNQUFNO1FBQ3JCLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDMUIsU0FBUyxJQUFJLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBQ0QsTUFBTSxRQUFRLEdBQUcsQ0FBQyxHQUFHLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQy9ELE1BQU0sYUFBYSxHQUFHLGVBQWUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLGVBQWUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQzNGLE9BQU87UUFDTCxJQUFJLEVBQUUsUUFBUTtRQUNkLFdBQVcsRUFBRSxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxJQUFJLElBQUksS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztRQUNuRixZQUFZLEVBQ1YsZUFBZSxJQUFJLENBQUM7WUFDcEIsTUFBTSxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQztLQUM3RSxDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsa0JBQWtCLENBQUMsS0FBYztJQUN4QyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7UUFBRSxPQUFPLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUNqRyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQzdELElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDaEMsS0FBSyxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQVUsRUFBRSxDQUFDO1FBQ2pELE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QixJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsSUFBSSxFQUFFO1lBQUUsT0FBTyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztRQUM3RixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN6QixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzNDLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDO2dCQUFFLE9BQU8sTUFBTSxDQUFDO1FBQ3ZDLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxFQUFFLENBQUM7QUFDWixDQUFDO0FBRUQsU0FBUyxZQUFZLENBQUMsS0FBYztJQUNsQyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7UUFBRSxPQUFPLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUNqRyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ2hDLE1BQU0sSUFBSSxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoQyxJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ3JCLE1BQU0sSUFBSSxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsT0FBTyxJQUFJLEtBQUssQ0FBQyxJQUFJLElBQUksS0FBSyxDQUFDLFVBQVUsSUFBSSxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDL0YsT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQ3RDLENBQUM7QUFFRCxTQUFTLFdBQVcsQ0FDbEIsS0FBd0M7SUFFeEMsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLE1BQU0sSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLFdBQVcsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ25GLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQztJQUNwQixDQUFDO0lBQ0QsSUFDRSxLQUFLLENBQUMsSUFBSSxLQUFLLE1BQU07UUFDckIsS0FBSyxDQUFDLElBQUksS0FBSyxzQkFBc0I7UUFDckMsS0FBSyxDQUFDLElBQUksS0FBSyxhQUFhLEVBQzVCLENBQUM7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBQ0QsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLGVBQWUsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLFdBQVc7UUFBRSxPQUFPLFdBQVcsQ0FBQztJQUNyRixJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssU0FBUyxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssU0FBUztRQUFFLE9BQU8sTUFBTSxDQUFDO0lBQ3hFLE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRCxTQUFTLFdBQVcsQ0FBQyxLQUFjO0lBQ2pDLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUTtRQUFFLE9BQU8sS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ25ELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuRixJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ2hDLEtBQUssTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxTQUFTLENBQVUsRUFBRSxDQUFDO1FBQzVFLE1BQU0sSUFBSSxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNyQyxJQUFJLElBQUk7WUFBRSxPQUFPLElBQUksQ0FBQztJQUN4QixDQUFDO0lBQ0QsT0FBTyxFQUFFLENBQUM7QUFDWixDQUFDO0FBRUQsTUFBTSxTQUFTLEdBQUc7SUFDaEIsUUFBUTtJQUNSLE1BQU07SUFDTixPQUFPO0lBQ1AsVUFBVTtJQUNWLFNBQVM7SUFDVCxhQUFhO0lBQ2IsU0FBUztJQUNULE1BQU07SUFDTixPQUFPO0NBQ0MsQ0FBQztBQUNYLE1BQU0sWUFBWSxHQUFHLElBQUksR0FBRyxDQUFDO0lBQzNCLFNBQVM7SUFDVCxlQUFlO0lBQ2YsV0FBVztJQUNYLGFBQWE7SUFDYixTQUFTO0lBQ1QsVUFBVTtJQUNWLFVBQVU7SUFDVixRQUFRO0lBQ1IsT0FBTztJQUNQLE9BQU87Q0FDUixDQUFDLENBQUM7QUFFSCxTQUFTLGtCQUFrQixDQUFDLEtBQWM7SUFDeEMsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUN6RSxNQUFNLFNBQVMsR0FBYSxFQUFFLENBQUM7SUFDL0IsSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNwQixLQUFLLE1BQU0sR0FBRyxJQUFJLFNBQVM7WUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsWUFBWSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuRixDQUFDO0lBQ0QsT0FBTyxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDakcsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFDLEtBQWMsRUFBRSxHQUFXLEVBQUUsS0FBYTtJQUM5RCxJQUFJLEtBQUssR0FBRyxDQUFDLElBQUksWUFBWSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUNoRSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7UUFBRSxPQUFPLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ3pFLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdGLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDaEMsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FDekQsWUFBWSxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUN6QyxDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLEtBQWM7SUFDckMsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDNUMsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzdCLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDckYsSUFBSSxDQUFDO1FBQ0gsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBWSxDQUFDO0lBQ3hDLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxXQUFXLENBQUMsSUFBWTtJQUMvQixPQUFPLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQztBQUN0RCxDQUFDO0FBRUQsU0FBUyxZQUFZLENBQUMsSUFBWSxFQUFFLFdBQW1CLEVBQUUsSUFBcUI7SUFDNUUsSUFBSSxXQUFXLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ3pDLE1BQU0sTUFBTSxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3JELElBQUksTUFBTSxDQUFDLE1BQU0sSUFBSSxXQUFXO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDOUMsT0FBTyxnQkFBZ0IsQ0FBQyxNQUFNLENBQzVCLElBQUksS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQzdFLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxjQUFjLENBQ3JCLE1BQW9DLEVBQ3BDLElBQStCO0lBRS9CLEtBQUssSUFBSSxLQUFLLEdBQUcsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsRUFBRSxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDM0QsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxLQUFLLElBQUk7WUFBRSxPQUFPLEtBQUssQ0FBQztJQUNqRCxDQUFDO0lBQ0QsT0FBTyxDQUFDLENBQUMsQ0FBQztBQUNaLENBQUM7QUFFRCxTQUFTLGdCQUFnQixDQUN2QixVQUE4QztJQUU5QyxNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0lBQy9CLE9BQU8sVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFO1FBQ3JDLE1BQU0sR0FBRyxHQUFHLEdBQUcsU0FBUyxDQUFDLE9BQU8sSUFBSSxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUMzRSxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFDaEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNkLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsU0FBUyxtQkFBbUIsQ0FBQyxLQUFhO0lBQ3hDLElBQUksVUFBVSxHQUFHLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3BFLEtBQUssTUFBTSxNQUFNLElBQUksQ0FBQyxhQUFhLEVBQUUsWUFBWSxDQUFVLEVBQUUsQ0FBQztRQUM1RCxJQUFJLFVBQVUsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUNsQyxVQUFVLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDN0MsTUFBTTtRQUNSLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxVQUFVLENBQUM7QUFDcEIsQ0FBQztBQUVELFNBQVMsUUFBUSxDQUFJLFVBQThDLEVBQUUsVUFBa0I7SUFDckYsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQ3BCLFVBQVU7UUFDVixVQUFVLEVBQUUsVUFBVTthQUNuQixHQUFHLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO2FBQzdFLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUNwQixHQUFHLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEtBQUssQ0FBQyxPQUFPLElBQUksS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQ2pGO0tBQ0osQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQVMsa0JBQWtCO0lBQ3pCLElBQUksQ0FBQztRQUNILE9BQU8sWUFBWSxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBQ3hDLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0FBQ0gsQ0FBQztBQUVELEtBQUssVUFBVSx3QkFBd0IsQ0FBQyxNQUF1QjtJQUM3RCxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0lBQzlCLE1BQU0sSUFBSSxHQUFHLENBQUMsTUFBTSxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDeEQsTUFBTSxNQUFNLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMxQyxPQUFPLFVBQVUsQ0FBQyxRQUFRLENBQUM7U0FDeEIsTUFBTSxDQUFDLElBQUksQ0FBQztTQUNaLE1BQU0sQ0FBQyxJQUFJLENBQUM7U0FDWixNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLENBQUM7U0FDMUMsTUFBTSxDQUFDLElBQUksQ0FBQztTQUNaLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLDJCQUEyQixDQUFDLElBQUksRUFBRSxDQUFDO1NBQ3RELE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNuQixDQUFDO0FBRUQsS0FBSyxVQUFVLGlCQUFpQixDQUM5QixNQUF1QixFQUN2QixJQUF3QixFQUN4QixNQUFtQixFQUNuQixTQUFpQjtJQUVqQixNQUFNLElBQUksR0FBRyxDQUFDLE1BQU0sTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ3hELE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLHNDQUFzQyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2xFLE1BQU0sT0FBTyxHQUFHLElBQUksT0FBTyxDQUFDLEVBQUUsY0FBYyxFQUFFLGtCQUFrQixFQUFFLENBQUMsQ0FBQztJQUNwRSxNQUFNLE1BQU0sQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzFDLE1BQU0sY0FBYyxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakYsSUFBSSxRQUFRLEdBQUcsTUFBTSxLQUFLLENBQUMsR0FBRyxFQUFFO1FBQzlCLE1BQU0sRUFBRSxNQUFNO1FBQ2QsT0FBTztRQUNQLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQztRQUMxQixNQUFNLEVBQUUsY0FBYztLQUN2QixDQUFDLENBQUM7SUFDSCxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxvQ0FBb0MsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDcEYsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDO1FBQzlCLE9BQU8sQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDaEMsT0FBTyxDQUFDLE1BQU0sQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO1FBQzVDLE1BQU0sTUFBTSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDMUMsUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLEdBQUcsRUFBRTtZQUMxQixNQUFNLEVBQUUsTUFBTTtZQUNkLE9BQU87WUFDUCxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUM7WUFDMUIsTUFBTSxFQUFFLGNBQWM7U0FDdkIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUNELElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDakIsTUFBTSxNQUFNLEdBQUcsQ0FBQyxNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzVFLE1BQU0sSUFBSSxnQkFBZ0IsQ0FDeEIsUUFBUSxDQUFDLE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUNuQyw0Q0FBNEMsUUFBUSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUM1RixDQUFDO0lBQ0osQ0FBQztJQUNELE9BQU8sUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ3pCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIERhdGFicmlja3MgU21hcnQgUm91dGVyIHRyYW5zcG9ydCwgY29udGV4dCBjb25zdHJ1Y3Rpb24sIHByb2JpbmcsIGFuZCB0dXJuIHBpbm5pbmcuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGNyZWF0ZUhhc2ggfSBmcm9tIFwibm9kZTpjcnlwdG9cIjtcbmltcG9ydCB7IENhY2hlTWFuYWdlciwgZ2V0RXhlY3V0aW9uQ29udGV4dCwgdHlwZSBXb3Jrc3BhY2VDbGllbnQgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBjbG9zZUNhY2hlLCBjcmVhdGVDYWNoZSwgZ2V0T3JTZXQgfSBmcm9tIFwiQGRieC10b29scy9jYWNoZVwiO1xuaW1wb3J0IHsgcmVmcmVzaFdvcmtzcGFjZUNsaWVudEF1dGhlbnRpY2F0aW9uIH0gZnJvbSBcIkBkYngtdG9vbHMvZGF0YWJyaWNrc1wiO1xuaW1wb3J0IHsgaXNSZWNvcmQsIGxvZywgdG9FcnJvciB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBSZWFzb25pbmdFZmZvcnRTY2hlbWEsIHR5cGUgUmVhc29uaW5nRWZmb3J0IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLW1vZGVsXCI7XG5pbXBvcnQge1xuICBTTUFSVF9ST1VURVJfTkFNRSxcbiAgU21hcnRSb3V0ZXJPYnNlcnZhdGlvblNjaGVtYSxcbiAgU21hcnRSb3V0ZXJSZXF1ZXN0U2NoZW1hLFxuICBTbWFydFJvdXRlclJlc3BvbnNlU2NoZW1hLFxuICB0eXBlIENsaWVudFByb3RvY29sLFxuICB0eXBlIE1vZGVsVGFyZ2V0LFxuICB0eXBlIFJlcXVlc3RlZEZlYXR1cmVzLFxuICB0eXBlIFNtYXJ0Um91dGVySGFybmVzcyxcbiAgdHlwZSBTbWFydFJvdXRlck9ic2VydmF0aW9uLFxuICB0eXBlIFNtYXJ0Um91dGVyUmVxdWVzdCxcbn0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLW1vZGVsLWdhdGV3YXlcIjtcbmltcG9ydCB7IFRpa3Rva2VuIH0gZnJvbSBcImpzLXRpa3Rva2VuL2xpdGVcIjtcbmltcG9ydCBvMjAwa0Jhc2UgZnJvbSBcImpzLXRpa3Rva2VuL3JhbmtzL28yMDBrX2Jhc2VcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmltcG9ydCB7IHJlc29sdmVSb3V0ZSB9IGZyb20gXCIuL3JvdXRlci50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwiYXBwa2l0L21vZGVsLWdhdGV3YXkvc21hcnQtcm91dGVyXCIpO1xuY29uc3QgUk9VVEVfQ0FDSEVfTkFNRVNQQUNFID0gXCJtb2RlbC1nYXRld2F5LXNtYXJ0LXJvdXRlclwiO1xuY29uc3QgUk9VVEVfUE9MSUNZX1ZFUlNJT04gPSAxO1xuY29uc3QgUFJPQkVfQ0FDSEVfTkFNRVNQQUNFID0gXCJtb2RlbC1nYXRld2F5LXNtYXJ0LXJvdXRlci1wcm9iZVwiO1xuY29uc3QgUFJPQkVfQ0FDSEVfVkVSU0lPTiA9IDE7XG5jb25zdCBQUk9CRV9UQVNLID0gXCJDaGVjayB3aGV0aGVyIFNtYXJ0IFJvdXRlciBjYW4gc2VsZWN0IGFuIGF2YWlsYWJsZSBtb2RlbC5cIjtcbmNvbnN0IE5FR0FUSVZFX1BST0JFX1RUTF9NUyA9IDMwXzAwMDtcbmNvbnN0IENPTlRFWFRfRU5DT0RJTkcgPSBuZXcgVGlrdG9rZW4obzIwMGtCYXNlKTtcblxuLyoqIFJ1bnRpbWUgc2V0dGluZ3MgZm9yIFNtYXJ0IFJvdXRlci4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU21hcnRSb3V0ZXJTZXR0aW5ncyB7XG4gIHJlYWRvbmx5IGNvbnRleHRUb2tlbkJ1ZGdldDogbnVtYmVyO1xuICByZWFkb25seSBwcm9iZVJlZnJlc2hJbnRlcnZhbE1zOiBudW1iZXI7XG4gIHJlYWRvbmx5IHByb2JlVHRsTXM6IG51bWJlcjtcbiAgcmVhZG9ubHkgcm91dGVUdGxTZWNvbmRzOiBudW1iZXI7XG4gIHJlYWRvbmx5IHJvdXRlck5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgdGltZW91dE1zOiBudW1iZXI7XG59XG5cbi8qKiBEZWZhdWx0cyBzaGFyZWQgYnkgZ2F0ZXdheSwgTWFzdHJhLCBhbmQgQ0xJIFNtYXJ0IFJvdXRlciBjYWxsZXJzLiAqL1xuZXhwb3J0IGNvbnN0IFNNQVJUX1JPVVRFUl9ERUZBVUxUX1NFVFRJTkdTOiBTbWFydFJvdXRlclNldHRpbmdzID0gT2JqZWN0LmZyZWV6ZSh7XG4gIGNvbnRleHRUb2tlbkJ1ZGdldDogNF8wOTYsXG4gIHByb2JlUmVmcmVzaEludGVydmFsTXM6IDNfNjAwXzAwMCxcbiAgcHJvYmVUdGxNczogMzAwXzAwMCxcbiAgcm91dGVUdGxTZWNvbmRzOiAyMV82MDAsXG4gIHJvdXRlck5hbWU6IFNNQVJUX1JPVVRFUl9OQU1FLFxuICB0aW1lb3V0TXM6IDEwXzAwMCxcbn0pO1xuXG4vKiogT25lIHJvdXRlIG9wdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhlIGNhbGxlci1vd25lZCB2YWx1ZSBpdCByZXByZXNlbnRzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTbWFydFJvdXRlckNhbmRpZGF0ZTxUPiB7XG4gIHJlYWRvbmx5IGhhcm5lc3M6IFNtYXJ0Um91dGVySGFybmVzcztcbiAgcmVhZG9ubHkgbW9kZWw6IHN0cmluZztcbiAgcmVhZG9ubHkgdmFsdWU6IFQ7XG59XG5cbi8qKiBSZXN1bHQgcmV0dXJuZWQgYWZ0ZXIgbWFwcGluZyBhIERhdGFicmlja3Mgcm91dGUgYmFjayB0byBhIGNhbGxlci1vd25lZCB2YWx1ZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU21hcnRSb3V0ZXJTZWxlY3Rpb248VD4ge1xuICByZWFkb25seSBoYXJuZXNzOiBTbWFydFJvdXRlckhhcm5lc3M7XG4gIHJlYWRvbmx5IGxhdGVuY3lNczogbnVtYmVyO1xuICByZWFkb25seSBwYXJhbXM/OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj47XG4gIHJlYWRvbmx5IHJhdGlvbmFsZT86IHN0cmluZztcbiAgcmVhZG9ubHkgcm91dGVNb2RlbDogc3RyaW5nO1xuICByZWFkb25seSByb3V0ZXJOYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHZhbHVlOiBUO1xufVxuXG4vKiogUG9ydGFibGUgcGVyc2lzdGVuY2Ugc3VyZmFjZSBmb3IgYSBwaW5uZWQgU21hcnQgUm91dGVyIHR1cm4uICovXG5leHBvcnQgaW50ZXJmYWNlIFNtYXJ0Um91dGVyU3RvcmUge1xuICBnZXQoa2V5OiBzdHJpbmcpOiBQcm9taXNlPHVua25vd24+O1xuICBzZXQoa2V5OiBzdHJpbmcsIHZhbHVlOiBTbWFydFJvdXRlck9ic2VydmF0aW9uLCB0dGxTZWNvbmRzOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+O1xufVxuXG5leHBvcnQgY29uc3QgU21hcnRSb3V0ZXJQcm9iZVJlY29yZFNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgZW5hYmxlZDogei5ib29sZWFuKCkuZGVzY3JpYmUoXCJXaGV0aGVyIHRoZSBsaXZlIFNtYXJ0IFJvdXRlciBwcm9iZSBzdWNjZWVkZWQuXCIpLFxuICAgIGV4cGlyZXNBdDogei5udW1iZXIoKS5pbnQoKS5kZXNjcmliZShcIkVwb2NoIG1pbGxpc2Vjb25kcyB3aGVuIHRoaXMgcHJvYmUgYmVjb21lcyBzdGFsZS5cIiksXG4gIH0pXG4gIC5kZXNjcmliZShcIlBlcnNpc3RlZCBTbWFydCBSb3V0ZXIgY2FwYWJpbGl0eSBwcm9iZSByZXN1bHQuXCIpO1xuXG5leHBvcnQgdHlwZSBTbWFydFJvdXRlclByb2JlUmVjb3JkID0gei5pbmZlcjx0eXBlb2YgU21hcnRSb3V0ZXJQcm9iZVJlY29yZFNjaGVtYT47XG5cbi8qKiBPcHRpb25hbCBwZXJzaXN0ZW50IGNhY2hlIGZvciBjYXBhYmlsaXR5IHByb2Jlcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU21hcnRSb3V0ZXJQcm9iZVN0b3JlIHtcbiAgZ2V0KGtleTogc3RyaW5nLCBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudCk6IFByb21pc2U8dW5rbm93bj47XG4gIHNldChcbiAgICBrZXk6IHN0cmluZyxcbiAgICB2YWx1ZTogU21hcnRSb3V0ZXJQcm9iZVJlY29yZCxcbiAgICB0dGxTZWNvbmRzOiBudW1iZXIsXG4gICAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnQsXG4gICk6IFByb21pc2U8dm9pZD47XG59XG5cbi8qKiBSZXN1bHQgYXBwbGllZCB0byBvbmUgY29uY3JldGUgZ2F0ZXdheSByZXF1ZXN0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBTbWFydFJvdXRlclJlc3VsdCB7XG4gIHJlYWRvbmx5IGJvZHk6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PjtcbiAgcmVhZG9ubHkgb2JzZXJ2YXRpb246IFNtYXJ0Um91dGVyT2JzZXJ2YXRpb247XG4gIHJlYWRvbmx5IHRhcmdldDogTW9kZWxUYXJnZXQ7XG59XG5cbi8qKiBCb3VuZGVkIHRhc2sgY29udGV4dCBleHRyYWN0ZWQgZnJvbSBhbiBhcmJpdHJhcnkgc3VwcG9ydGVkIGlucHV0IHNoYXBlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTbWFydFJvdXRlckNvbnRleHQge1xuICByZWFkb25seSBjb250aW51YXRpb246IGJvb2xlYW47XG4gIHJlYWRvbmx5IGxvZ2ljYWxUdXJuOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHRhc2s6IHN0cmluZztcbn1cblxuLyoqIEVycm9yIGNhcnJ5aW5nIGFuIEhUVFAgc3RhdHVzIGZvciBTbWFydCBSb3V0ZXIgdmFsaWRhdGlvbiBvciBhdmFpbGFiaWxpdHkgZmFpbHVyZXMuICovXG5leHBvcnQgY2xhc3MgU21hcnRSb3V0ZXJFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcmVhZG9ubHkgc3RhdHVzOiBudW1iZXIsXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICApIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLm5hbWUgPSBcIlNtYXJ0Um91dGVyRXJyb3JcIjtcbiAgfVxufVxuXG4vKiogQXBwS2l0IGNhY2hlIGFkYXB0ZXI7IGNvbmZpZ3VyZWQgTGFrZWJhc2UvUG9zdGdyZXMgc3RvcmFnZSByZW1haW5zIEFwcEtpdC1vd25lZC4gKi9cbmV4cG9ydCBjbGFzcyBBcHBLaXRTbWFydFJvdXRlclN0b3JlIGltcGxlbWVudHMgU21hcnRSb3V0ZXJTdG9yZSB7XG4gIGFzeW5jIGdldChrZXk6IHN0cmluZyk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgIGNvbnN0IGNhY2hlID0gYXdhaXQgQ2FjaGVNYW5hZ2VyLmdldEluc3RhbmNlKCk7XG4gICAgcmV0dXJuIGNhY2hlLmdldChjYWNoZS5nZW5lcmF0ZUtleShbUk9VVEVfQ0FDSEVfTkFNRVNQQUNFLCBST1VURV9QT0xJQ1lfVkVSU0lPTl0sIGtleSkpO1xuICB9XG5cbiAgYXN5bmMgc2V0KGtleTogc3RyaW5nLCB2YWx1ZTogU21hcnRSb3V0ZXJPYnNlcnZhdGlvbiwgdHRsU2Vjb25kczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY2FjaGUgPSBhd2FpdCBDYWNoZU1hbmFnZXIuZ2V0SW5zdGFuY2UoKTtcbiAgICBhd2FpdCBjYWNoZS5zZXQoY2FjaGUuZ2VuZXJhdGVLZXkoW1JPVVRFX0NBQ0hFX05BTUVTUEFDRSwgUk9VVEVfUE9MSUNZX1ZFUlNJT05dLCBrZXkpLCB2YWx1ZSwge1xuICAgICAgdHRsOiB0dGxTZWNvbmRzLFxuICAgIH0pO1xuICB9XG59XG5cbi8qKiBBcHBLaXQgY2FjaGUgYWRhcHRlciBmb3IgcHJvY2Vzcy0gYW5kIHBlcnNpc3RlbmNlLWJhY2tlZCBjYXBhYmlsaXR5IHByb2Jlcy4gKi9cbmV4cG9ydCBjbGFzcyBBcHBLaXRTbWFydFJvdXRlclByb2JlU3RvcmUgaW1wbGVtZW50cyBTbWFydFJvdXRlclByb2JlU3RvcmUge1xuICBhc3luYyBnZXQoa2V5OiBzdHJpbmcsIGNsaWVudDogV29ya3NwYWNlQ2xpZW50KTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgY29uc3QgY2FjaGUgPSBhcHBLaXRDYWNoZU1hbmFnZXIoKTtcbiAgICBpZiAoIWNhY2hlKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGNvbnN0IGlkZW50aXR5ID0gYXdhaXQgc21hcnRSb3V0ZXJQcm9iZUlkZW50aXR5KGNsaWVudCk7XG4gICAgcmV0dXJuIGNhY2hlLmdldChcbiAgICAgIGNhY2hlLmdlbmVyYXRlS2V5KFtQUk9CRV9DQUNIRV9OQU1FU1BBQ0UsIFBST0JFX0NBQ0hFX1ZFUlNJT05dLCBgJHtpZGVudGl0eX06JHtrZXl9YCksXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIHNldChcbiAgICBrZXk6IHN0cmluZyxcbiAgICB2YWx1ZTogU21hcnRSb3V0ZXJQcm9iZVJlY29yZCxcbiAgICB0dGxTZWNvbmRzOiBudW1iZXIsXG4gICAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnQsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNhY2hlID0gYXBwS2l0Q2FjaGVNYW5hZ2VyKCk7XG4gICAgaWYgKCFjYWNoZSkgcmV0dXJuO1xuICAgIGNvbnN0IGlkZW50aXR5ID0gYXdhaXQgc21hcnRSb3V0ZXJQcm9iZUlkZW50aXR5KGNsaWVudCk7XG4gICAgYXdhaXQgY2FjaGUuc2V0KFxuICAgICAgY2FjaGUuZ2VuZXJhdGVLZXkoW1BST0JFX0NBQ0hFX05BTUVTUEFDRSwgUFJPQkVfQ0FDSEVfVkVSU0lPTl0sIGAke2lkZW50aXR5fToke2tleX1gKSxcbiAgICAgIHZhbHVlLFxuICAgICAgeyB0dGw6IHR0bFNlY29uZHMgfSxcbiAgICApO1xuICB9XG59XG5cbnR5cGUgU21hcnRSb3V0ZXJQcm9iZUNhY2hlID0gUmV0dXJuVHlwZTx0eXBlb2YgY3JlYXRlQ2FjaGU+O1xuXG4vKiogT3B0aW9uYWwgaWRlbnRpdHkgYW5kIGNhbmNlbGxhdGlvbiBpbnB1dHMgZm9yIG9uZSBTbWFydCBSb3V0ZXIgY2FsbC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU21hcnRSb3V0ZXJTZWxlY3RPcHRpb25zIHtcbiAgcmVhZG9ubHkgY2xpZW50PzogV29ya3NwYWNlQ2xpZW50O1xuICByZWFkb25seSBzaWduYWw/OiBBYm9ydFNpZ25hbDtcbn1cblxudHlwZSBTbWFydFJvdXRlckludm9rZXIgPSAoXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50LFxuICByZXF1ZXN0OiBTbWFydFJvdXRlclJlcXVlc3QsXG4gIHNpZ25hbDogQWJvcnRTaWduYWwsXG4gIHRpbWVvdXRNczogbnVtYmVyLFxuKSA9PiBQcm9taXNlPHVua25vd24+O1xuXG4vKipcbiAqIERlZGljYXRlZCBTbWFydCBSb3V0ZXIgc2VydmljZSBmb3Igc3RyaW5ncywgcmVxdWVzdCBvYmplY3RzLCBtZXNzYWdlIGFycmF5cyxcbiAqIGFuZCBnZW5lcmljIEpTT04tbGlrZSBpbnB1dHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBTbWFydFJvdXRlclNlcnZpY2Uge1xuICByZWFkb25seSBjb250ZXh0OiBTbWFydFJvdXRlckNvbnRleHRCdWlsZGVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHNldHRpbmdzOiBTbWFydFJvdXRlclNldHRpbmdzO1xuICBwcml2YXRlIHJlYWRvbmx5IHByb2JlcyA9IG5ldyBXZWFrTWFwPG9iamVjdCwgU21hcnRSb3V0ZXJQcm9iZUNhY2hlPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHByb2JlS2V5cyA9IG5ldyBXZWFrTWFwPG9iamVjdCwgU2V0PHN0cmluZz4+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcHJvYmVDYWNoZXMgPSBuZXcgU2V0PFNtYXJ0Um91dGVyUHJvYmVDYWNoZT4oKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBzZXR0aW5nczogUGFydGlhbDxTbWFydFJvdXRlclNldHRpbmdzPiA9IHt9LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgaW52b2tlOiBTbWFydFJvdXRlckludm9rZXIgPSBpbnZva2VTbWFydFJvdXRlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHByb2JlU3RvcmU6IFNtYXJ0Um91dGVyUHJvYmVTdG9yZSA9IG5ldyBBcHBLaXRTbWFydFJvdXRlclByb2JlU3RvcmUoKSxcbiAgKSB7XG4gICAgdGhpcy5zZXR0aW5ncyA9IHsgLi4uU01BUlRfUk9VVEVSX0RFRkFVTFRfU0VUVElOR1MsIC4uLnNldHRpbmdzIH07XG4gICAgdGhpcy5jb250ZXh0ID0gbmV3IFNtYXJ0Um91dGVyQ29udGV4dEJ1aWxkZXIodGhpcy5zZXR0aW5ncy5jb250ZXh0VG9rZW5CdWRnZXQpO1xuICB9XG5cbiAgLyoqIFNlbGVjdCBvbmUgb2ZmZXJlZCByb3V0ZSBmb3IgYXJiaXRyYXJ5IGlucHV0IGNvbnRlbnQuICovXG4gIGFzeW5jIHNlbGVjdDxUPihcbiAgICBpbnB1dDogdW5rbm93bixcbiAgICBjYW5kaWRhdGVzOiByZWFkb25seSBTbWFydFJvdXRlckNhbmRpZGF0ZTxUPltdLFxuICAgIG9wdGlvbnM6IFNtYXJ0Um91dGVyU2VsZWN0T3B0aW9ucyA9IHt9LFxuICApOiBQcm9taXNlPFNtYXJ0Um91dGVyU2VsZWN0aW9uPFQ+PiB7XG4gICAgY29uc3QgdGFzayA9IHRoaXMuY29udGV4dC5idWlsZChpbnB1dCk7XG4gICAgaWYgKCF0YXNrKSB0aHJvdyBuZXcgU21hcnRSb3V0ZXJFcnJvcig0MDAsIFwiU21hcnQgUm91dGVyIGlucHV0IGNvbnRhaW5zIG5vIHJvdXRhYmxlIHRleHRcIik7XG4gICAgY29uc3QgY2xpZW50ID0gb3B0aW9ucy5jbGllbnQgPz8gZ2V0RXhlY3V0aW9uQ29udGV4dCgpLmNsaWVudDtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc2VsZWN0aW9uID0gYXdhaXQgdGhpcy5zZWxlY3RUYXNrKHRhc2ssIGNhbmRpZGF0ZXMsIHsgLi4ub3B0aW9ucywgY2xpZW50IH0pO1xuICAgICAgdGhpcy5zZXRQcm9iZVZhbHVlKGNhbmRpZGF0ZXMsIGNsaWVudCwgdHJ1ZSk7XG4gICAgICByZXR1cm4gc2VsZWN0aW9uO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLnNldFByb2JlVW5hdmFpbGFibGUoY2FuZGlkYXRlcywgY2xpZW50KTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBSZXR1cm4gYSBtZW1vaXplZCBsaXZlIGNhcGFiaWxpdHkgcHJvYmUgZm9yIHRoZSBhY3RpdmUgaWRlbnRpdHkgYW5kIGNhbmRpZGF0ZSBtZW51LiAqL1xuICBhc3luYyBpc0VuYWJsZWQ8VD4oXG4gICAgY2FuZGlkYXRlczogcmVhZG9ubHkgU21hcnRSb3V0ZXJDYW5kaWRhdGU8VD5bXSxcbiAgICBjbGllbnQgPSBnZXRFeGVjdXRpb25Db250ZXh0KCkuY2xpZW50LFxuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBvZmZlcmVkID0gdW5pcXVlQ2FuZGlkYXRlcyhjYW5kaWRhdGVzKTtcbiAgICBpZiAob2ZmZXJlZC5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcbiAgICBjb25zdCBjYWNoZSA9IHRoaXMucHJvYmVDYWNoZShjbGllbnQpO1xuICAgIGNvbnN0IGtleSA9IHByb2JlS2V5KG9mZmVyZWQsIHRoaXMuc2V0dGluZ3Mucm91dGVyTmFtZSk7XG4gICAgdGhpcy5yZW1lbWJlclByb2JlS2V5KGNsaWVudCwga2V5KTtcbiAgICBjb25zdCBwcm9iZSA9IGF3YWl0IGdldE9yU2V0KFxuICAgICAgY2FjaGUsXG4gICAgICBrZXksXG4gICAgICAoKSA9PiB0aGlzLmxvYWRQcm9iZShrZXksIG9mZmVyZWQsIGNsaWVudCksXG4gICAgICB7XG4gICAgICAgIHR0bDogdGhpcy5wcm9iZUNhY2hlVHRsTXMoKSxcbiAgICAgICAgcmVmcmVzaEFmdGVyV3JpdGU6ICh2YWx1ZSkgPT4gdGhpcy5wcm9iZVJlZnJlc2hBZnRlcldyaXRlKHZhbHVlLmVuYWJsZWQpLFxuICAgICAgfSxcbiAgICApO1xuICAgIHJldHVybiBwcm9iZT8uZW5hYmxlZCA/PyBmYWxzZTtcbiAgfVxuXG4gIC8qKiBTdG9wIHByb2Nlc3MtbG9jYWwgcHJvYmUgY2FjaGVzIGFmdGVyIHRoZWlyIGFjdGl2ZSByZWZyZXNoZXMgc2V0dGxlLiAqL1xuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIGZvciAoY29uc3QgY2FjaGUgb2YgdGhpcy5wcm9iZUNhY2hlcykgdm9pZCBjbG9zZUNhY2hlKGNhY2hlKTtcbiAgICB0aGlzLnByb2JlQ2FjaGVzLmNsZWFyKCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxvYWRQcm9iZTxUPihcbiAgICBrZXk6IHN0cmluZyxcbiAgICBjYW5kaWRhdGVzOiByZWFkb25seSBTbWFydFJvdXRlckNhbmRpZGF0ZTxUPltdLFxuICAgIGNsaWVudDogV29ya3NwYWNlQ2xpZW50LFxuICApOiBQcm9taXNlPFNtYXJ0Um91dGVyUHJvYmVSZWNvcmQ+IHtcbiAgICBjb25zdCBzdG9yZWQgPSBhd2FpdCB0aGlzLnJlYWRTdG9yZWRQcm9iZShrZXksIGNsaWVudCk7XG4gICAgaWYgKHN0b3JlZCAmJiBzdG9yZWQuZXhwaXJlc0F0ID4gRGF0ZS5ub3coKSkgcmV0dXJuIHN0b3JlZDtcbiAgICByZXR1cm4gdGhpcy5leGVjdXRlUHJvYmUoa2V5LCBjYW5kaWRhdGVzLCBjbGllbnQpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBleGVjdXRlUHJvYmU8VD4oXG4gICAga2V5OiBzdHJpbmcsXG4gICAgY2FuZGlkYXRlczogcmVhZG9ubHkgU21hcnRSb3V0ZXJDYW5kaWRhdGU8VD5bXSxcbiAgICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudCxcbiAgKTogUHJvbWlzZTxTbWFydFJvdXRlclByb2JlUmVjb3JkPiB7XG4gICAgY29uc3QgZW5hYmxlZCA9IGF3YWl0IHRoaXMuc2VsZWN0VGFzayhQUk9CRV9UQVNLLCBjYW5kaWRhdGVzLCB7IGNsaWVudCB9KVxuICAgICAgLnRoZW4oKCkgPT4gdHJ1ZSlcbiAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKFwiU21hcnQgUm91dGVyIGNhcGFiaWxpdHkgcHJvYmUgdW5hdmFpbGFibGVcIiwgeyBlcnJvcjogdG9FcnJvcihlcnJvcikgfSk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0pO1xuICAgIGNvbnN0IHByb2JlID0gdGhpcy5wcm9iZVJlY29yZChlbmFibGVkKTtcbiAgICB2b2lkIHRoaXMud3JpdGVTdG9yZWRQcm9iZShrZXksIHByb2JlLCBjbGllbnQpO1xuICAgIHJldHVybiBwcm9iZTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0UHJvYmVWYWx1ZTxUPihcbiAgICBjYW5kaWRhdGVzOiByZWFkb25seSBTbWFydFJvdXRlckNhbmRpZGF0ZTxUPltdLFxuICAgIGNsaWVudDogV29ya3NwYWNlQ2xpZW50LFxuICAgIGVuYWJsZWQ6IGJvb2xlYW4sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IG9mZmVyZWQgPSB1bmlxdWVDYW5kaWRhdGVzKGNhbmRpZGF0ZXMpO1xuICAgIGlmIChvZmZlcmVkLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgIGNvbnN0IGNhY2hlID0gdGhpcy5wcm9iZUNhY2hlKGNsaWVudCk7XG4gICAgY29uc3Qga2V5ID0gcHJvYmVLZXkob2ZmZXJlZCwgdGhpcy5zZXR0aW5ncy5yb3V0ZXJOYW1lKTtcbiAgICB0aGlzLnJlbWVtYmVyUHJvYmVLZXkoY2xpZW50LCBrZXkpO1xuICAgIGNvbnN0IHByb2JlID0gdGhpcy5wcm9iZVJlY29yZChlbmFibGVkKTtcbiAgICB2b2lkIHRoaXMud3JpdGVQcm9jZXNzUHJvYmUoY2FjaGUsIGtleSwgcHJvYmUpO1xuICAgIHZvaWQgdGhpcy53cml0ZVN0b3JlZFByb2JlKGtleSwgcHJvYmUsIGNsaWVudCk7XG4gIH1cblxuICBwcml2YXRlIHNldFByb2JlVW5hdmFpbGFibGU8VD4oXG4gICAgY2FuZGlkYXRlczogcmVhZG9ubHkgU21hcnRSb3V0ZXJDYW5kaWRhdGU8VD5bXSxcbiAgICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudCxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgY2FjaGUgPSB0aGlzLnByb2JlQ2FjaGUoY2xpZW50KTtcbiAgICBjb25zdCBvZmZlcmVkID0gdW5pcXVlQ2FuZGlkYXRlcyhjYW5kaWRhdGVzKTtcbiAgICBjb25zdCByZXF1ZXN0ZWRLZXkgPSBwcm9iZUtleShvZmZlcmVkLCB0aGlzLnNldHRpbmdzLnJvdXRlck5hbWUpO1xuICAgIHRoaXMucmVtZW1iZXJQcm9iZUtleShjbGllbnQsIHJlcXVlc3RlZEtleSk7XG4gICAgY29uc3Qga2V5cyA9IHRoaXMucHJvYmVLZXlzLmdldChjbGllbnQuY29uZmlnIGFzIG9iamVjdCkgPz8gbmV3IFNldChbcmVxdWVzdGVkS2V5XSk7XG4gICAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgICAgY29uc3QgcHJvYmUgPSB0aGlzLnByb2JlUmVjb3JkKGZhbHNlKTtcbiAgICAgIHZvaWQgdGhpcy53cml0ZVByb2Nlc3NQcm9iZShjYWNoZSwga2V5LCBwcm9iZSk7XG4gICAgICB2b2lkIHRoaXMud3JpdGVTdG9yZWRQcm9iZShrZXksIHByb2JlLCBjbGllbnQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcHJvYmVSZWNvcmQoZW5hYmxlZDogYm9vbGVhbik6IFNtYXJ0Um91dGVyUHJvYmVSZWNvcmQge1xuICAgIHJldHVybiB7IGVuYWJsZWQsIGV4cGlyZXNBdDogRGF0ZS5ub3coKSArIHRoaXMucHJvYmVUdGwoZW5hYmxlZCkgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVhZFN0b3JlZFByb2JlKFxuICAgIGtleTogc3RyaW5nLFxuICAgIGNsaWVudDogV29ya3NwYWNlQ2xpZW50LFxuICApOiBQcm9taXNlPFNtYXJ0Um91dGVyUHJvYmVSZWNvcmQgfCB1bmRlZmluZWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFyc2VkID0gU21hcnRSb3V0ZXJQcm9iZVJlY29yZFNjaGVtYS5zYWZlUGFyc2UoYXdhaXQgdGhpcy5wcm9iZVN0b3JlLmdldChrZXksIGNsaWVudCkpO1xuICAgICAgcmV0dXJuIHBhcnNlZC5zdWNjZXNzID8gcGFyc2VkLmRhdGEgOiB1bmRlZmluZWQ7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcIlNtYXJ0IFJvdXRlciBwcm9iZSBjYWNoZSByZWFkIGZhaWxlZFwiLCB7IGVycm9yOiB0b0Vycm9yKGVycm9yKSB9KTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB3cml0ZVByb2Nlc3NQcm9iZShcbiAgICBjYWNoZTogU21hcnRSb3V0ZXJQcm9iZUNhY2hlLFxuICAgIGtleTogc3RyaW5nLFxuICAgIHByb2JlOiBTbWFydFJvdXRlclByb2JlUmVjb3JkLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY2FjaGUuc2V0KGtleSwgcHJvYmUsIHsgdHRsOiB0aGlzLnByb2JlQ2FjaGVUdGxNcygpIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZGVidWcoXCJTbWFydCBSb3V0ZXIgcHJvY2VzcyBwcm9iZSBjYWNoZSB3cml0ZSBmYWlsZWRcIiwgeyBlcnJvcjogdG9FcnJvcihlcnJvcikgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB3cml0ZVN0b3JlZFByb2JlKFxuICAgIGtleTogc3RyaW5nLFxuICAgIHByb2JlOiBTbWFydFJvdXRlclByb2JlUmVjb3JkLFxuICAgIGNsaWVudDogV29ya3NwYWNlQ2xpZW50LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wcm9iZVN0b3JlLnNldChcbiAgICAgICAga2V5LFxuICAgICAgICBwcm9iZSxcbiAgICAgICAgTWF0aC5tYXgoMSwgTWF0aC5jZWlsKHRoaXMucHJvYmVDYWNoZVR0bE1zKCkgLyAxXzAwMCkpLFxuICAgICAgICBjbGllbnQsXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZGVidWcoXCJTbWFydCBSb3V0ZXIgcHJvYmUgY2FjaGUgd3JpdGUgZmFpbGVkXCIsIHsgZXJyb3I6IHRvRXJyb3IoZXJyb3IpIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcHJvYmVDYWNoZShjbGllbnQ6IFdvcmtzcGFjZUNsaWVudCk6IFNtYXJ0Um91dGVyUHJvYmVDYWNoZSB7XG4gICAgY29uc3Qgb3duZXIgPSBjbGllbnQuY29uZmlnIGFzIG9iamVjdDtcbiAgICBsZXQgY2FjaGUgPSB0aGlzLnByb2Jlcy5nZXQob3duZXIpO1xuICAgIGlmICghY2FjaGUpIHtcbiAgICAgIGNhY2hlID0gY3JlYXRlQ2FjaGUoeyBtYXhFbnRyaWVzOiAzMiwgdXNlQ2xvbmU6IGZhbHNlIH0pO1xuICAgICAgdGhpcy5wcm9iZXMuc2V0KG93bmVyLCBjYWNoZSk7XG4gICAgICB0aGlzLnByb2JlQ2FjaGVzLmFkZChjYWNoZSk7XG4gICAgfVxuICAgIHJldHVybiBjYWNoZTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtZW1iZXJQcm9iZUtleShjbGllbnQ6IFdvcmtzcGFjZUNsaWVudCwga2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBvd25lciA9IGNsaWVudC5jb25maWcgYXMgb2JqZWN0O1xuICAgIGxldCBrZXlzID0gdGhpcy5wcm9iZUtleXMuZ2V0KG93bmVyKTtcbiAgICBpZiAoIWtleXMpIHtcbiAgICAgIGtleXMgPSBuZXcgU2V0KCk7XG4gICAgICB0aGlzLnByb2JlS2V5cy5zZXQob3duZXIsIGtleXMpO1xuICAgIH1cbiAgICBrZXlzLmFkZChrZXkpO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9iZUNhY2hlVHRsTXMoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTWF0aC5tYXgodGhpcy5zZXR0aW5ncy5wcm9iZVJlZnJlc2hJbnRlcnZhbE1zLCB0aGlzLnNldHRpbmdzLnByb2JlVHRsTXMpICogMjtcbiAgfVxuXG4gIHByaXZhdGUgcHJvYmVUdGwoZW5hYmxlZDogYm9vbGVhbik6IG51bWJlciB7XG4gICAgcmV0dXJuIGVuYWJsZWRcbiAgICAgID8gdGhpcy5zZXR0aW5ncy5wcm9iZVR0bE1zXG4gICAgICA6IE1hdGgubWluKHRoaXMuc2V0dGluZ3MucHJvYmVUdGxNcywgTkVHQVRJVkVfUFJPQkVfVFRMX01TKTtcbiAgfVxuXG4gIHByaXZhdGUgcHJvYmVSZWZyZXNoQWZ0ZXJXcml0ZShlbmFibGVkOiBib29sZWFuKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTWF0aC5taW4odGhpcy5zZXR0aW5ncy5wcm9iZVJlZnJlc2hJbnRlcnZhbE1zLCB0aGlzLnByb2JlVHRsKGVuYWJsZWQpKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VsZWN0VGFzazxUPihcbiAgICB0YXNrOiBzdHJpbmcsXG4gICAgY2FuZGlkYXRlczogcmVhZG9ubHkgU21hcnRSb3V0ZXJDYW5kaWRhdGU8VD5bXSxcbiAgICBvcHRpb25zOiBTbWFydFJvdXRlclNlbGVjdE9wdGlvbnMsXG4gICk6IFByb21pc2U8U21hcnRSb3V0ZXJTZWxlY3Rpb248VD4+IHtcbiAgICBjb25zdCBvZmZlcmVkID0gdW5pcXVlQ2FuZGlkYXRlcyhjYW5kaWRhdGVzKTtcbiAgICBpZiAob2ZmZXJlZC5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBTbWFydFJvdXRlckVycm9yKDQwMCwgXCJObyBjb21wYXRpYmxlIHN5c3RlbSBtb2RlbHMgYXJlIGF2YWlsYWJsZSB0byBTbWFydCBSb3V0ZXJcIik7XG4gICAgfVxuICAgIGNvbnN0IHJlcXVlc3QgPSBTbWFydFJvdXRlclJlcXVlc3RTY2hlbWEucGFyc2Uoe1xuICAgICAgcm91dGVfb3B0aW9uczogb2ZmZXJlZC5tYXAoKHsgbW9kZWwsIGhhcm5lc3MgfSkgPT4gKHsgbW9kZWwsIGhhcm5lc3MgfSkpLFxuICAgICAgdGFzazogeyBwcm9tcHQ6IHRhc2sgfSxcbiAgICAgIHJvdXRlX3NlbGVjdG9yOiB7IHJvdXRlcl9uYW1lOiB0aGlzLnNldHRpbmdzLnJvdXRlck5hbWUgfSxcbiAgICB9KTtcbiAgICBjb25zdCBjbGllbnQgPSBvcHRpb25zLmNsaWVudCA/PyBnZXRFeGVjdXRpb25Db250ZXh0KCkuY2xpZW50O1xuICAgIGNvbnN0IHNpZ25hbCA9IG9wdGlvbnMuc2lnbmFsID8/IG5ldyBBYm9ydENvbnRyb2xsZXIoKS5zaWduYWw7XG4gICAgY29uc3Qgc3RhcnRlZEF0ID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCByZXNwb25zZSA9IFNtYXJ0Um91dGVyUmVzcG9uc2VTY2hlbWEucGFyc2UoXG4gICAgICBhd2FpdCB0aGlzLmludm9rZShjbGllbnQsIHJlcXVlc3QsIHNpZ25hbCwgdGhpcy5zZXR0aW5ncy50aW1lb3V0TXMpLFxuICAgICk7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gcmVzcG9uc2Uucm91dGVfc2VsZWN0aW9uWzBdITtcbiAgICBjb25zdCBzZWxlY3RlZCA9IG9mZmVyZWQuZmluZChcbiAgICAgIChjYW5kaWRhdGUpID0+XG4gICAgICAgIG5vcm1hbGl6ZVJvdXRlTW9kZWwoY2FuZGlkYXRlLm1vZGVsKSA9PT1cbiAgICAgICAgICBub3JtYWxpemVSb3V0ZU1vZGVsKHNlbGVjdGlvbi5yb3V0ZV9vcHRpb24ubW9kZWwpICYmXG4gICAgICAgICghc2VsZWN0aW9uLnJvdXRlX29wdGlvbi5oYXJuZXNzIHx8IGNhbmRpZGF0ZS5oYXJuZXNzID09PSBzZWxlY3Rpb24ucm91dGVfb3B0aW9uLmhhcm5lc3MpLFxuICAgICk7XG4gICAgaWYgKCFzZWxlY3RlZCkge1xuICAgICAgdGhyb3cgbmV3IFNtYXJ0Um91dGVyRXJyb3IoXG4gICAgICAgIDUwMixcbiAgICAgICAgYFNtYXJ0IFJvdXRlciBzZWxlY3RlZCBhbiB1bnN1cHBvcnRlZCBtb2RlbDogJHtzZWxlY3Rpb24ucm91dGVfb3B0aW9uLm1vZGVsfWAsXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgdmFsdWU6IHNlbGVjdGVkLnZhbHVlLFxuICAgICAgcm91dGVNb2RlbDogc2VsZWN0aW9uLnJvdXRlX29wdGlvbi5tb2RlbCxcbiAgICAgIGhhcm5lc3M6IHNlbGVjdGVkLmhhcm5lc3MsXG4gICAgICByb3V0ZXJOYW1lOiB0aGlzLnNldHRpbmdzLnJvdXRlck5hbWUsXG4gICAgICBsYXRlbmN5TXM6IERhdGUubm93KCkgLSBzdGFydGVkQXQsXG4gICAgICAuLi4ocmVzcG9uc2UucmF0aW9uYWxlID8geyByYXRpb25hbGU6IHJlc3BvbnNlLnJhdGlvbmFsZSB9IDoge30pLFxuICAgICAgLi4uKHNlbGVjdGlvbi5wYXJhbXMgPyB7IHBhcmFtczogc2VsZWN0aW9uLnBhcmFtcyB9IDoge30pLFxuICAgIH07XG4gIH1cbn1cblxuLyoqIEJ1aWxkIGEgU21hcnQgUm91dGVyIGNhbmRpZGF0ZSBtZW51IGZyb20gdmFsdWVzIGNhcnJ5aW5nIG1vZGVsU2VydmljZU5hbWUuICovXG5leHBvcnQgZnVuY3Rpb24gc21hcnRSb3V0ZXJDYW5kaWRhdGVzPFQgZXh0ZW5kcyB7IHJlYWRvbmx5IG1vZGVsU2VydmljZU5hbWU/OiBzdHJpbmcgfT4oXG4gIHZhbHVlczogcmVhZG9ubHkgVFtdLFxuICBoYXJuZXNzOiBTbWFydFJvdXRlckhhcm5lc3MsXG4pOiBTbWFydFJvdXRlckNhbmRpZGF0ZTxUPltdIHtcbiAgcmV0dXJuIHZhbHVlcy5mbGF0TWFwKCh2YWx1ZSkgPT4ge1xuICAgIGNvbnN0IG1vZGVsID0gdmFsdWUubW9kZWxTZXJ2aWNlTmFtZT8udHJpbSgpO1xuICAgIGlmICghbW9kZWwgfHwgIW1vZGVsLnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aChcInN5c3RlbS5haS5cIikpIHJldHVybiBbXTtcbiAgICByZXR1cm4gW3sgbW9kZWwsIGhhcm5lc3MsIHZhbHVlIH1dO1xuICB9KTtcbn1cblxuLyoqXG4gKiBDb250ZXh0IGV4dHJhY3RvciBzaGFyZWQgYnkgdGhlIGdhdGV3YXksIE1hc3RyYSwgYW5kIHRoZSBmaWxlL3N0ZGluIENMSS5cbiAqIEl0IGZhdm9ycyBjb252ZXJzYXRpb24vdGFzayBmaWVsZHMgYW5kIGlnbm9yZXMgY3JlZGVudGlhbHMsIHRvb2wgc2NoZW1hcyxcbiAqIGFuZCB0b29sIGFyZ3VtZW50cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFNtYXJ0Um91dGVyQ29udGV4dEJ1aWxkZXIge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHRva2VuQnVkZ2V0ID0gNF8wOTYpIHt9XG5cbiAgLyoqIFJldHVybiBvbmx5IHRoZSBib3VuZGVkIHRhc2sgcHJvbXB0IHJlcXVpcmVkIGJ5IHJvdXRlczpzZWxlY3QuICovXG4gIGJ1aWxkKGlucHV0OiB1bmtub3duKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5hbmFseXplKGlucHV0KS50YXNrO1xuICB9XG5cbiAgLyoqIFJldHVybiBib3VuZGVkIHRhc2sgdGV4dCBwbHVzIGxvZ2ljYWwtdHVybiBtZXRhZGF0YSB1c2VkIGZvciBwaW5uaW5nLiAqL1xuICBhbmFseXplKGlucHV0OiB1bmtub3duKTogU21hcnRSb3V0ZXJDb250ZXh0IHtcbiAgICBjb25zdCBub3JtYWxpemVkID0gcGFyc2VKc29uU3RyaW5nKGlucHV0KTtcbiAgICBjb25zdCBldmVudHMgPSBjb252ZXJzYXRpb25FdmVudHMobm9ybWFsaXplZCk7XG4gICAgaWYgKGV2ZW50cy5sZW5ndGggPiAwKSByZXR1cm4gY29udGV4dEZyb21FdmVudHMoZXZlbnRzLCB0aGlzLnRva2VuQnVkZ2V0KTtcbiAgICBjb25zdCB2YWx1ZXMgPSBjb2xsZWN0VGFza1N0cmluZ3Mobm9ybWFsaXplZCk7XG4gICAgY29uc3QgdGFzayA9IHRydW5jYXRlVGV4dCh2YWx1ZXMuam9pbihcIlxcblwiKSwgdGhpcy50b2tlbkJ1ZGdldCwgXCJzdGFydFwiKTtcbiAgICByZXR1cm4geyB0YXNrLCBsb2dpY2FsVHVybjogdGFzaywgY29udGludWF0aW9uOiBmYWxzZSB9O1xuICB9XG59XG5cbi8qKiBTbWFydCBSb3V0ZXIgb3JjaGVzdHJhdGlvbiBzaGFyZWQgYnkgUmVzcG9uc2VzLCBDaGF0IENvbXBsZXRpb25zLCBhbmQgTWVzc2FnZXMuICovXG5leHBvcnQgY2xhc3MgU21hcnRNb2RlbFJvdXRlciB7XG4gIHJlYWRvbmx5IHNlcnZpY2U6IFNtYXJ0Um91dGVyU2VydmljZTtcbiAgcHJpdmF0ZSByZWFkb25seSBzZXR0aW5nczogU21hcnRSb3V0ZXJTZXR0aW5ncztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBzZXR0aW5nczogUGFydGlhbDxTbWFydFJvdXRlclNldHRpbmdzPiA9IHt9LFxuICAgIHNlcnZpY2U6IFNtYXJ0Um91dGVyU2VydmljZSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHN0b3JlOiBTbWFydFJvdXRlclN0b3JlID0gbmV3IEFwcEtpdFNtYXJ0Um91dGVyU3RvcmUoKSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudD86IFdvcmtzcGFjZUNsaWVudCxcbiAgKSB7XG4gICAgdGhpcy5zZXR0aW5ncyA9IHsgLi4uU01BUlRfUk9VVEVSX0RFRkFVTFRfU0VUVElOR1MsIC4uLnNldHRpbmdzIH07XG4gICAgdGhpcy5zZXJ2aWNlID0gc2VydmljZSA/PyBuZXcgU21hcnRSb3V0ZXJTZXJ2aWNlKHRoaXMuc2V0dGluZ3MpO1xuICB9XG5cbiAgLyoqIFByb2JlIHdoZXRoZXIgU21hcnQgUm91dGVyIGlzIHVzYWJsZSBmb3IgdGhlIGN1cnJlbnQgbW9kZWwgY2F0YWxvZ3VlLiAqL1xuICBpc0VuYWJsZWQodGFyZ2V0czogcmVhZG9ubHkgTW9kZWxUYXJnZXRbXSk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGNhbmRpZGF0ZXMgPSBzbWFydFJvdXRlckNhbmRpZGF0ZXMoXG4gICAgICB0YXJnZXRzLmZpbHRlcigodGFyZ2V0KSA9PiB0YXJnZXQuY2FwYWJpbGl0aWVzLmNoYXQgJiYgdGFyZ2V0LmNhcGFiaWxpdGllcy5haUdhdGV3YXlDb2RleCksXG4gICAgICBcImNvZGV4XCIsXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5jbGllbnRcbiAgICAgID8gdGhpcy5zZXJ2aWNlLmlzRW5hYmxlZChjYW5kaWRhdGVzLCB0aGlzLmNsaWVudClcbiAgICAgIDogdGhpcy5zZXJ2aWNlLmlzRW5hYmxlZChjYW5kaWRhdGVzKTtcbiAgfVxuXG4gIC8qKiBSZXNvbHZlIG9uZSB2aXJ0dWFsIHNtYXJ0LXJvdXRlciByZXF1ZXN0IHRvIGEgY29uY3JldGUgY29tcGF0aWJsZSB0YXJnZXQuICovXG4gIGFzeW5jIHJlc29sdmUoaW5wdXQ6IHtcbiAgICByZWFkb25seSBib2R5OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj47XG4gICAgcmVhZG9ubHkgZmVhdHVyZXM6IFJlcXVlc3RlZEZlYXR1cmVzO1xuICAgIHJlYWRvbmx5IGhlYWRlcnM6IEhlYWRlcnM7XG4gICAgcmVhZG9ubHkgcHJlZmVyU3lzdGVtTW9kZWxzOiBib29sZWFuO1xuICAgIHJlYWRvbmx5IHByb3RvY29sOiBFeGNsdWRlPENsaWVudFByb3RvY29sLCBcIm9wZW5haS1lbWJlZGRpbmdzXCI+O1xuICAgIHJlYWRvbmx5IHNpZ25hbDogQWJvcnRTaWduYWw7XG4gICAgcmVhZG9ubHkgdGFyZ2V0czogcmVhZG9ubHkgTW9kZWxUYXJnZXRbXTtcbiAgfSk6IFByb21pc2U8U21hcnRSb3V0ZXJSZXN1bHQ+IHtcbiAgICBjb25zdCBoYXJuZXNzOiBTbWFydFJvdXRlckhhcm5lc3MgPVxuICAgICAgaW5wdXQucHJvdG9jb2wgPT09IFwiYW50aHJvcGljLW1lc3NhZ2VzXCIgPyBcImNsYXVkZVwiIDogXCJjb2RleFwiO1xuICAgIGNvbnN0IGV4cGxpY2l0UmVhc29uaW5nRWZmb3J0ID0gcmVxdWVzdGVkUmVhc29uaW5nRWZmb3J0KGlucHV0LmJvZHkpO1xuICAgIGNvbnN0IGVsaWdpYmxlVGFyZ2V0cyA9IGlucHV0LnRhcmdldHMuZmlsdGVyKCh0YXJnZXQpID0+XG4gICAgICBpc0VsaWdpYmxlVGFyZ2V0KFxuICAgICAgICB0YXJnZXQsXG4gICAgICAgIHsgLi4uaW5wdXQsIG9yaWdpbmF0b3I6IGlucHV0LmhlYWRlcnMuZ2V0KFwib3JpZ2luYXRvclwiKSA/PyB1bmRlZmluZWQgfSxcbiAgICAgICAgZXhwbGljaXRSZWFzb25pbmdFZmZvcnQsXG4gICAgICAgIGhhcm5lc3MsXG4gICAgICApLFxuICAgICk7XG4gICAgY29uc3QgY2FuZGlkYXRlcyA9IHNtYXJ0Um91dGVyQ2FuZGlkYXRlcyhlbGlnaWJsZVRhcmdldHMsIGhhcm5lc3MpO1xuICAgIGlmIChjYW5kaWRhdGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IFNtYXJ0Um91dGVyRXJyb3IoXG4gICAgICAgIDQwMCxcbiAgICAgICAgXCJObyBjb21wYXRpYmxlIHN5c3RlbSBtb2RlbHMgYXJlIGF2YWlsYWJsZSB0byBEYXRhYnJpY2tzIFNtYXJ0IFJvdXRlclwiLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5zZXJ2aWNlLmNvbnRleHQuYW5hbHl6ZShpbnB1dC5ib2R5KTtcbiAgICBpZiAoIWNvbnRleHQudGFzaykge1xuICAgICAgdGhyb3cgbmV3IFNtYXJ0Um91dGVyRXJyb3IoNDAwLCBcIlNtYXJ0IFJvdXRlciByZXF1ZXN0IGNvbnRhaW5zIG5vIHRhc2sgdGV4dFwiKTtcbiAgICB9XG4gICAgY29uc3Qga2V5ID0gc21hcnRSb3V0ZXJUdXJuS2V5KGNvbnRleHQubG9naWNhbFR1cm4sIGNhbmRpZGF0ZXMsIHtcbiAgICAgIGhhcm5lc3MsXG4gICAgICBwcm90b2NvbDogaW5wdXQucHJvdG9jb2wsXG4gICAgICBmZWF0dXJlczogaW5wdXQuZmVhdHVyZXMsXG4gICAgICAuLi4oZXhwbGljaXRSZWFzb25pbmdFZmZvcnQgPyB7IGV4cGxpY2l0UmVhc29uaW5nRWZmb3J0IH0gOiB7fSksXG4gICAgfSk7XG4gICAgY29uc3QgY2FjaGVkID0gY29udGV4dC5jb250aW51YXRpb24gPyBhd2FpdCB0aGlzLnJlYWRDYWNoZWQoa2V5LCBlbGlnaWJsZVRhcmdldHMpIDogdW5kZWZpbmVkO1xuICAgIGlmIChjYWNoZWQpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRhcmdldDogZWxpZ2libGVUYXJnZXRzLmZpbmQoKHRhcmdldCkgPT4gdGFyZ2V0LmlkID09PSBjYWNoZWQuc2VsZWN0ZWRNb2RlbCkhLFxuICAgICAgICBib2R5OiBpbnB1dC5ib2R5LFxuICAgICAgICBvYnNlcnZhdGlvbjogeyAuLi5jYWNoZWQsIHNvdXJjZTogXCJjYWNoZVwiIH0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IHNlbGVjdGVkID0gYXdhaXQgdGhpcy5zZXJ2aWNlLnNlbGVjdChjb250ZXh0LnRhc2ssIGNhbmRpZGF0ZXMsIHtcbiAgICAgIHNpZ25hbDogaW5wdXQuc2lnbmFsLFxuICAgICAgLi4uKHRoaXMuY2xpZW50ID8geyBjbGllbnQ6IHRoaXMuY2xpZW50IH0gOiB7fSksXG4gICAgfSk7XG4gICAgY29uc3QgdGFyZ2V0ID0gc2VsZWN0ZWQudmFsdWU7XG4gICAgY29uc3Qgb2JzZXJ2YXRpb24gPSBTbWFydFJvdXRlck9ic2VydmF0aW9uU2NoZW1hLnBhcnNlKHtcbiAgICAgIHNlbGVjdGVkTW9kZWw6IHRhcmdldC5pZCxcbiAgICAgIHJvdXRlTW9kZWw6IHNlbGVjdGVkLnJvdXRlTW9kZWwsXG4gICAgICBoYXJuZXNzOiBzZWxlY3RlZC5oYXJuZXNzLFxuICAgICAgcm91dGVyTmFtZTogc2VsZWN0ZWQucm91dGVyTmFtZSxcbiAgICAgIHNvdXJjZTogXCJyb3V0ZXJcIixcbiAgICAgIGxhdGVuY3lNczogc2VsZWN0ZWQubGF0ZW5jeU1zLFxuICAgICAgLi4uKHNlbGVjdGVkLnJhdGlvbmFsZSA/IHsgcmF0aW9uYWxlOiBzZWxlY3RlZC5yYXRpb25hbGUgfSA6IHt9KSxcbiAgICAgIC4uLihzZWxlY3RlZC5wYXJhbXMgPyB7IHBhcmFtczogc2VsZWN0ZWQucGFyYW1zIH0gOiB7fSksXG4gICAgfSk7XG4gICAgYXdhaXQgdGhpcy53cml0ZUNhY2hlZChrZXksIG9ic2VydmF0aW9uKTtcbiAgICBsb2dnZXIuZGVidWcoXCJzZWxlY3RlZCBTbWFydCBSb3V0ZXIgbW9kZWxcIiwge1xuICAgICAgY2FuZGlkYXRlQ291bnQ6IGNhbmRpZGF0ZXMubGVuZ3RoLFxuICAgICAgaGFybmVzcyxcbiAgICAgIGxhdGVuY3lNczogb2JzZXJ2YXRpb24ubGF0ZW5jeU1zLFxuICAgICAgbW9kZWw6IG9ic2VydmF0aW9uLnNlbGVjdGVkTW9kZWwsXG4gICAgICByb3V0ZU1vZGVsOiBvYnNlcnZhdGlvbi5yb3V0ZU1vZGVsLFxuICAgICAgcm91dGVyTmFtZTogb2JzZXJ2YXRpb24ucm91dGVyTmFtZSxcbiAgICB9KTtcbiAgICByZXR1cm4geyB0YXJnZXQsIGJvZHk6IGlucHV0LmJvZHksIG9ic2VydmF0aW9uIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlYWRDYWNoZWQoXG4gICAga2V5OiBzdHJpbmcsXG4gICAgdGFyZ2V0czogcmVhZG9ubHkgTW9kZWxUYXJnZXRbXSxcbiAgKTogUHJvbWlzZTxTbWFydFJvdXRlck9ic2VydmF0aW9uIHwgdW5kZWZpbmVkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhcnNlZCA9IFNtYXJ0Um91dGVyT2JzZXJ2YXRpb25TY2hlbWEuc2FmZVBhcnNlKGF3YWl0IHRoaXMuc3RvcmUuZ2V0KGtleSkpO1xuICAgICAgaWYgKCFwYXJzZWQuc3VjY2VzcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiB0YXJnZXRzLnNvbWUoKHRhcmdldCkgPT4gdGFyZ2V0LmlkID09PSBwYXJzZWQuZGF0YS5zZWxlY3RlZE1vZGVsKVxuICAgICAgICA/IHBhcnNlZC5kYXRhXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZGVidWcoXCJTbWFydCBSb3V0ZXIgY2FjaGUgcmVhZCBmYWlsZWRcIiwgeyBlcnJvcjogdG9FcnJvcihlcnJvcikgfSk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgd3JpdGVDYWNoZWQoa2V5OiBzdHJpbmcsIG9ic2VydmF0aW9uOiBTbWFydFJvdXRlck9ic2VydmF0aW9uKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuc3RvcmUuc2V0KGtleSwgb2JzZXJ2YXRpb24sIHRoaXMuc2V0dGluZ3Mucm91dGVUdGxTZWNvbmRzKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmRlYnVnKFwiU21hcnQgUm91dGVyIGNhY2hlIHdyaXRlIGZhaWxlZFwiLCB7IGVycm9yOiB0b0Vycm9yKGVycm9yKSB9KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqIFN0YWJsZSBsb2dpY2FsLXR1cm4ga2V5IHNoYXJlZCBieSBpbml0aWFsIHJlcXVlc3RzIGFuZCB0b29sIGNvbnRpbnVhdGlvbnMuICovXG5leHBvcnQgZnVuY3Rpb24gc21hcnRSb3V0ZXJUdXJuS2V5KFxuICBsb2dpY2FsVHVybjogc3RyaW5nLFxuICBjYW5kaWRhdGVzOiByZWFkb25seSBTbWFydFJvdXRlckNhbmRpZGF0ZTx1bmtub3duPltdLFxuICBjb250ZXh0OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4sXG4pOiBzdHJpbmcge1xuICByZXR1cm4gY3JlYXRlSGFzaChcInNoYTI1NlwiKVxuICAgIC51cGRhdGUoXG4gICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIGxvZ2ljYWxUdXJuLFxuICAgICAgICBjYW5kaWRhdGVzOiBjYW5kaWRhdGVzLm1hcCgoeyBtb2RlbCwgaGFybmVzcyB9KSA9PiAoeyBtb2RlbCwgaGFybmVzcyB9KSksXG4gICAgICAgIGNvbnRleHQsXG4gICAgICB9KSxcbiAgICApXG4gICAgLmRpZ2VzdChcImhleFwiKTtcbn1cblxuZnVuY3Rpb24gaXNFbGlnaWJsZVRhcmdldChcbiAgdGFyZ2V0OiBNb2RlbFRhcmdldCxcbiAgaW5wdXQ6IHtcbiAgICByZWFkb25seSBmZWF0dXJlczogUmVxdWVzdGVkRmVhdHVyZXM7XG4gICAgcmVhZG9ubHkgb3JpZ2luYXRvcj86IHN0cmluZztcbiAgICByZWFkb25seSBwcmVmZXJTeXN0ZW1Nb2RlbHM6IGJvb2xlYW47XG4gICAgcmVhZG9ubHkgcHJvdG9jb2w6IEV4Y2x1ZGU8Q2xpZW50UHJvdG9jb2wsIFwib3BlbmFpLWVtYmVkZGluZ3NcIj47XG4gIH0sXG4gIGV4cGxpY2l0UmVhc29uaW5nRWZmb3J0OiBSZWFzb25pbmdFZmZvcnQgfCB1bmRlZmluZWQsXG4gIGhhcm5lc3M6IFNtYXJ0Um91dGVySGFybmVzcyxcbik6IGJvb2xlYW4ge1xuICBpZiAoIXRhcmdldC5lbmRwb2ludCB8fCB0YXJnZXQuZW5kcG9pbnQuc3RhdHVzPy5kZXByZWNhdGVkID09PSB0cnVlKSByZXR1cm4gZmFsc2U7XG4gIGlmICghdGFyZ2V0Lm1vZGVsU2VydmljZU5hbWU/LnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aChcInN5c3RlbS5haS5cIikpIHJldHVybiBmYWxzZTtcbiAgaWYgKCF0YXJnZXQuY2FwYWJpbGl0aWVzLmNoYXQpIHJldHVybiBmYWxzZTtcbiAgaWYgKGhhcm5lc3MgPT09IFwiY29kZXhcIiAmJiAhdGFyZ2V0LmNhcGFiaWxpdGllcy5haUdhdGV3YXlDb2RleCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoaGFybmVzcyA9PT0gXCJjbGF1ZGVcIiAmJiAhdGFyZ2V0LmNhcGFiaWxpdGllcy5hbnRocm9waWMpIHJldHVybiBmYWxzZTtcbiAgaWYgKGlucHV0LmZlYXR1cmVzLnRvb2xzICYmICF0YXJnZXQuY2FwYWJpbGl0aWVzLnRvb2xzKSByZXR1cm4gZmFsc2U7XG4gIGlmIChpbnB1dC5mZWF0dXJlcy5wYXJhbGxlbFRvb2xzICYmICF0YXJnZXQuY2FwYWJpbGl0aWVzLnBhcmFsbGVsVG9vbHMpIHJldHVybiBmYWxzZTtcbiAgaWYgKGlucHV0LmZlYXR1cmVzLmN1c3RvbVRvb2xzICYmICF0YXJnZXQuY2FwYWJpbGl0aWVzLmN1c3RvbVRvb2xzKSByZXR1cm4gZmFsc2U7XG4gIGlmIChpbnB1dC5mZWF0dXJlcy5zdHJ1Y3R1cmVkT3V0cHV0ICYmICF0YXJnZXQuY2FwYWJpbGl0aWVzLnN0cnVjdHVyZWRPdXRwdXQpIHJldHVybiBmYWxzZTtcbiAgaWYgKGlucHV0LmZlYXR1cmVzLndlYlNlYXJjaCAmJiAhdGFyZ2V0LmNhcGFiaWxpdGllcy53ZWJTZWFyY2gpIHJldHVybiBmYWxzZTtcbiAgaWYgKGlucHV0LmZlYXR1cmVzLmltYWdlSW5wdXQgJiYgIXRhcmdldC5jYXBhYmlsaXRpZXMuaW1hZ2VJbnB1dCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoaW5wdXQuZmVhdHVyZXMuYXBwbHlQYXRjaCAmJiAhdGFyZ2V0LmNhcGFiaWxpdGllcy5hcHBseVBhdGNoKSByZXR1cm4gZmFsc2U7XG4gIGlmIChpbnB1dC5mZWF0dXJlcy5yZWFzb25pbmcgJiYgIXRhcmdldC5jYXBhYmlsaXRpZXMucmVhc29uaW5nKSByZXR1cm4gZmFsc2U7XG4gIGlmIChcbiAgICBleHBsaWNpdFJlYXNvbmluZ0VmZm9ydCAmJlxuICAgIGV4cGxpY2l0UmVhc29uaW5nRWZmb3J0ICE9PSBcIm5vbmVcIiAmJlxuICAgICF0YXJnZXQucmVhc29uaW5nRWZmb3J0cy5pbmNsdWRlcyhleHBsaWNpdFJlYXNvbmluZ0VmZm9ydClcbiAgKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHRyeSB7XG4gICAgcmVzb2x2ZVJvdXRlKHtcbiAgICAgIGNsaWVudFByb3RvY29sOiBpbnB1dC5wcm90b2NvbCxcbiAgICAgIC4uLihpbnB1dC5vcmlnaW5hdG9yID8geyBvcmlnaW5hdG9yOiBpbnB1dC5vcmlnaW5hdG9yIH0gOiB7fSksXG4gICAgICBwcmVmZXJTeXN0ZW1Nb2RlbHM6IGlucHV0LnByZWZlclN5c3RlbU1vZGVscyxcbiAgICAgIGZlYXR1cmVzOiBpbnB1dC5mZWF0dXJlcyxcbiAgICAgIHRhcmdldCxcbiAgICB9KTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlcXVlc3RlZFJlYXNvbmluZ0VmZm9ydChcbiAgYm9keTogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+LFxuKTogUmVhc29uaW5nRWZmb3J0IHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcmVhc29uaW5nID0gaXNSZWNvcmQoYm9keS5yZWFzb25pbmcpID8gYm9keS5yZWFzb25pbmcgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IG91dHB1dENvbmZpZyA9IGlzUmVjb3JkKGJvZHkub3V0cHV0X2NvbmZpZykgPyBib2R5Lm91dHB1dF9jb25maWcgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IHJhdyA9IGJvZHkucmVhc29uaW5nX2VmZm9ydCA/PyByZWFzb25pbmc/LmVmZm9ydCA/PyBvdXRwdXRDb25maWc/LmVmZm9ydDtcbiAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gbnVsbCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IFN0cmluZyhyYXcpLnRyaW0oKS50b0xvd2VyQ2FzZSgpLnJlcGxhY2VBbGwoXCJfXCIsIFwiLVwiKTtcbiAgY29uc3QgcGFyc2VkID0gUmVhc29uaW5nRWZmb3J0U2NoZW1hLnNhZmVQYXJzZShcbiAgICBub3JtYWxpemVkID09PSBcImV4dHJhLWhpZ2hcIiA/IFwieGhpZ2hcIiA6IG5vcm1hbGl6ZWQsXG4gICk7XG4gIGlmICghcGFyc2VkLnN1Y2Nlc3MpIHtcbiAgICB0aHJvdyBuZXcgU21hcnRSb3V0ZXJFcnJvcig0MDAsIGBVbnN1cHBvcnRlZCBTbWFydCBSb3V0ZXIgcmVhc29uaW5nIGVmZm9ydDogJHtTdHJpbmcocmF3KX1gKTtcbiAgfVxuICByZXR1cm4gcGFyc2VkLmRhdGE7XG59XG5cbmludGVyZmFjZSBDb252ZXJzYXRpb25FdmVudCB7XG4gIHJlYWRvbmx5IHJvbGU6IFwiYXNzaXN0YW50XCIgfCBcInN5c3RlbVwiIHwgXCJ0b29sXCIgfCBcInVzZXJcIjtcbiAgcmVhZG9ubHkgdGV4dDogc3RyaW5nO1xufVxuXG5mdW5jdGlvbiBjb250ZXh0RnJvbUV2ZW50cyhcbiAgZXZlbnRzOiByZWFkb25seSBDb252ZXJzYXRpb25FdmVudFtdLFxuICB0b2tlbkJ1ZGdldDogbnVtYmVyLFxuKTogU21hcnRSb3V0ZXJDb250ZXh0IHtcbiAgY29uc3QgbGF0ZXN0VXNlckluZGV4ID0gbGFzdEV2ZW50SW5kZXgoZXZlbnRzLCBcInVzZXJcIik7XG4gIGNvbnN0IHRhc2tFdmVudCA9IGxhdGVzdFVzZXJJbmRleCA+PSAwID8gZXZlbnRzW2xhdGVzdFVzZXJJbmRleF0gOiBldmVudHMuYXQoLTEpO1xuICBjb25zdCB0YXNrID0gdHJ1bmNhdGVUZXh0KHRhc2tFdmVudD8udGV4dCA/PyBcIlwiLCB0b2tlbkJ1ZGdldCwgXCJzdGFydFwiKTtcbiAgbGV0IHJlbWFpbmluZyA9IE1hdGgubWF4KDAsIHRva2VuQnVkZ2V0IC0gY291bnRUb2tlbnModGFzaykpO1xuICBjb25zdCBjb250ZXh0OiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKFxuICAgIGxldCBpbmRleCA9ICh0YXNrRXZlbnQgPyBldmVudHMuaW5kZXhPZih0YXNrRXZlbnQpIDogZXZlbnRzLmxlbmd0aCkgLSAxO1xuICAgIGluZGV4ID49IDA7XG4gICAgaW5kZXggLT0gMVxuICApIHtcbiAgICBjb25zdCBldmVudCA9IGV2ZW50c1tpbmRleF07XG4gICAgaWYgKCFldmVudCB8fCAhZXZlbnQudGV4dCB8fCBldmVudC5yb2xlID09PSBcInRvb2xcIikgY29udGludWU7XG4gICAgY29uc3QgdmFsdWUgPSBgJHtldmVudC5yb2xlfTogJHtldmVudC50ZXh0fWA7XG4gICAgY29uc3QgcmV0YWluZWQgPSB0cnVuY2F0ZVRleHQodmFsdWUsIHJlbWFpbmluZywgXCJlbmRcIik7XG4gICAgaWYgKCFyZXRhaW5lZCkgYnJlYWs7XG4gICAgY29udGV4dC51bnNoaWZ0KHJldGFpbmVkKTtcbiAgICByZW1haW5pbmcgLT0gY291bnRUb2tlbnMocmV0YWluZWQpO1xuICB9XG4gIGNvbnN0IGNvbWJpbmVkID0gWy4uLmNvbnRleHQsIHRhc2tdLmZpbHRlcihCb29sZWFuKS5qb2luKFwiXFxuXCIpO1xuICBjb25zdCBsb2dpY2FsRXZlbnRzID0gbGF0ZXN0VXNlckluZGV4ID49IDAgPyBldmVudHMuc2xpY2UoMCwgbGF0ZXN0VXNlckluZGV4ICsgMSkgOiBldmVudHM7XG4gIHJldHVybiB7XG4gICAgdGFzazogY29tYmluZWQsXG4gICAgbG9naWNhbFR1cm46IGxvZ2ljYWxFdmVudHMubWFwKChldmVudCkgPT4gYCR7ZXZlbnQucm9sZX06JHtldmVudC50ZXh0fWApLmpvaW4oXCJcXG5cIiksXG4gICAgY29udGludWF0aW9uOlxuICAgICAgbGF0ZXN0VXNlckluZGV4ID49IDAgJiZcbiAgICAgIGV2ZW50cy5zbGljZShsYXRlc3RVc2VySW5kZXggKyAxKS5zb21lKChldmVudCkgPT4gZXZlbnQucm9sZSAhPT0gXCJzeXN0ZW1cIiksXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnNhdGlvbkV2ZW50cyhpbnB1dDogdW5rbm93bik6IENvbnZlcnNhdGlvbkV2ZW50W10ge1xuICBpZiAodHlwZW9mIGlucHV0ID09PSBcInN0cmluZ1wiKSByZXR1cm4gaW5wdXQudHJpbSgpID8gW3sgcm9sZTogXCJ1c2VyXCIsIHRleHQ6IGlucHV0LnRyaW0oKSB9XSA6IFtdO1xuICBpZiAoQXJyYXkuaXNBcnJheShpbnB1dCkpIHJldHVybiBpbnB1dC5mbGF0TWFwKG1lc3NhZ2VFdmVudCk7XG4gIGlmICghaXNSZWNvcmQoaW5wdXQpKSByZXR1cm4gW107XG4gIGZvciAoY29uc3Qga2V5IG9mIFtcIm1lc3NhZ2VzXCIsIFwiaW5wdXRcIl0gYXMgY29uc3QpIHtcbiAgICBjb25zdCB2YWx1ZSA9IGlucHV0W2tleV07XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiB2YWx1ZS50cmltKCkpIHJldHVybiBbeyByb2xlOiBcInVzZXJcIiwgdGV4dDogdmFsdWUudHJpbSgpIH1dO1xuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgY29uc3QgZXZlbnRzID0gdmFsdWUuZmxhdE1hcChtZXNzYWdlRXZlbnQpO1xuICAgICAgaWYgKGV2ZW50cy5sZW5ndGggPiAwKSByZXR1cm4gZXZlbnRzO1xuICAgIH1cbiAgfVxuICByZXR1cm4gW107XG59XG5cbmZ1bmN0aW9uIG1lc3NhZ2VFdmVudCh2YWx1ZTogdW5rbm93bik6IENvbnZlcnNhdGlvbkV2ZW50W10ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSByZXR1cm4gdmFsdWUudHJpbSgpID8gW3sgcm9sZTogXCJ1c2VyXCIsIHRleHQ6IHZhbHVlLnRyaW0oKSB9XSA6IFtdO1xuICBpZiAoIWlzUmVjb3JkKHZhbHVlKSkgcmV0dXJuIFtdO1xuICBjb25zdCByb2xlID0gbWVzc2FnZVJvbGUodmFsdWUpO1xuICBpZiAoIXJvbGUpIHJldHVybiBbXTtcbiAgY29uc3QgdGV4dCA9IGNvbnRlbnRUZXh0KHZhbHVlLmNvbnRlbnQgPz8gdmFsdWUudGV4dCA/PyB2YWx1ZS5pbnB1dF90ZXh0ID8/IHZhbHVlLm91dHB1dF90ZXh0KTtcbiAgcmV0dXJuIHRleHQgPyBbeyByb2xlLCB0ZXh0IH1dIDogW107XG59XG5cbmZ1bmN0aW9uIG1lc3NhZ2VSb2xlKFxuICB2YWx1ZTogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+LFxuKTogQ29udmVyc2F0aW9uRXZlbnRbXCJyb2xlXCJdIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHZhbHVlLnJvbGUgPT09IFwidXNlclwiIHx8IHZhbHVlLnJvbGUgPT09IFwiYXNzaXN0YW50XCIgfHwgdmFsdWUucm9sZSA9PT0gXCJzeXN0ZW1cIikge1xuICAgIHJldHVybiB2YWx1ZS5yb2xlO1xuICB9XG4gIGlmIChcbiAgICB2YWx1ZS5yb2xlID09PSBcInRvb2xcIiB8fFxuICAgIHZhbHVlLnR5cGUgPT09IFwiZnVuY3Rpb25fY2FsbF9vdXRwdXRcIiB8fFxuICAgIHZhbHVlLnR5cGUgPT09IFwidG9vbF9yZXN1bHRcIlxuICApIHtcbiAgICByZXR1cm4gXCJ0b29sXCI7XG4gIH1cbiAgaWYgKHZhbHVlLnR5cGUgPT09IFwiZnVuY3Rpb25fY2FsbFwiIHx8IHZhbHVlLnR5cGUgPT09IFwicmVhc29uaW5nXCIpIHJldHVybiBcImFzc2lzdGFudFwiO1xuICBpZiAodmFsdWUudHlwZSA9PT0gXCJtZXNzYWdlXCIgJiYgdmFsdWUucm9sZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gXCJ1c2VyXCI7XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGNvbnRlbnRUZXh0KHZhbHVlOiB1bmtub3duKTogc3RyaW5nIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIHZhbHVlLnRyaW0oKTtcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSByZXR1cm4gdmFsdWUubWFwKGNvbnRlbnRUZXh0KS5maWx0ZXIoQm9vbGVhbikuam9pbihcIlxcblwiKTtcbiAgaWYgKCFpc1JlY29yZCh2YWx1ZSkpIHJldHVybiBcIlwiO1xuICBmb3IgKGNvbnN0IGtleSBvZiBbXCJ0ZXh0XCIsIFwiaW5wdXRfdGV4dFwiLCBcIm91dHB1dF90ZXh0XCIsIFwiY29udGVudFwiXSBhcyBjb25zdCkge1xuICAgIGNvbnN0IHRleHQgPSBjb250ZW50VGV4dCh2YWx1ZVtrZXldKTtcbiAgICBpZiAodGV4dCkgcmV0dXJuIHRleHQ7XG4gIH1cbiAgcmV0dXJuIFwiXCI7XG59XG5cbmNvbnN0IFRBU0tfS0VZUyA9IFtcbiAgXCJwcm9tcHRcIixcbiAgXCJ0YXNrXCIsXG4gIFwicXVlcnlcIixcbiAgXCJxdWVzdGlvblwiLFxuICBcInJlcXVlc3RcIixcbiAgXCJkZXNjcmlwdGlvblwiLFxuICBcIm1lc3NhZ2VcIixcbiAgXCJ0ZXh0XCIsXG4gIFwiaW5wdXRcIixcbl0gYXMgY29uc3Q7XG5jb25zdCBJR05PUkVEX0tFWVMgPSBuZXcgU2V0KFtcbiAgXCJhcGlfa2V5XCIsXG4gIFwiYXV0aG9yaXphdGlvblwiLFxuICBcImFyZ3VtZW50c1wiLFxuICBcImNyZWRlbnRpYWxzXCIsXG4gIFwiaGVhZGVyc1wiLFxuICBcIm1ldGFkYXRhXCIsXG4gIFwicGFzc3dvcmRcIixcbiAgXCJzZWNyZXRcIixcbiAgXCJ0b2tlblwiLFxuICBcInRvb2xzXCIsXG5dKTtcblxuZnVuY3Rpb24gY29sbGVjdFRhc2tTdHJpbmdzKGlucHV0OiB1bmtub3duKTogc3RyaW5nW10ge1xuICBpZiAodHlwZW9mIGlucHV0ID09PSBcInN0cmluZ1wiKSByZXR1cm4gaW5wdXQudHJpbSgpID8gW2lucHV0LnRyaW0oKV0gOiBbXTtcbiAgY29uc3QgcHJlZmVycmVkOiBzdHJpbmdbXSA9IFtdO1xuICBpZiAoaXNSZWNvcmQoaW5wdXQpKSB7XG4gICAgZm9yIChjb25zdCBrZXkgb2YgVEFTS19LRVlTKSBwcmVmZXJyZWQucHVzaCguLi5zdHJpbmdMZWF2ZXMoaW5wdXRba2V5XSwga2V5LCAwKSk7XG4gIH1cbiAgcmV0dXJuIHByZWZlcnJlZC5sZW5ndGggPiAwID8gcHJlZmVycmVkLnNsaWNlKDAsIDMyKSA6IHN0cmluZ0xlYXZlcyhpbnB1dCwgXCJcIiwgMCkuc2xpY2UoMCwgMzIpO1xufVxuXG5mdW5jdGlvbiBzdHJpbmdMZWF2ZXModmFsdWU6IHVua25vd24sIGtleTogc3RyaW5nLCBkZXB0aDogbnVtYmVyKTogc3RyaW5nW10ge1xuICBpZiAoZGVwdGggPiA2IHx8IElHTk9SRURfS0VZUy5oYXMoa2V5LnRvTG93ZXJDYXNlKCkpKSByZXR1cm4gW107XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHJldHVybiB2YWx1ZS50cmltKCkgPyBbdmFsdWUudHJpbSgpXSA6IFtdO1xuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiB2YWx1ZS5mbGF0TWFwKChpdGVtKSA9PiBzdHJpbmdMZWF2ZXMoaXRlbSwga2V5LCBkZXB0aCArIDEpKTtcbiAgaWYgKCFpc1JlY29yZCh2YWx1ZSkpIHJldHVybiBbXTtcbiAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKHZhbHVlKS5mbGF0TWFwKChbY2hpbGRLZXksIGNoaWxkXSkgPT5cbiAgICBzdHJpbmdMZWF2ZXMoY2hpbGQsIGNoaWxkS2V5LCBkZXB0aCArIDEpLFxuICApO1xufVxuXG5mdW5jdGlvbiBwYXJzZUpzb25TdHJpbmcoaW5wdXQ6IHVua25vd24pOiB1bmtub3duIHtcbiAgaWYgKHR5cGVvZiBpbnB1dCAhPT0gXCJzdHJpbmdcIikgcmV0dXJuIGlucHV0O1xuICBjb25zdCB0cmltbWVkID0gaW5wdXQudHJpbSgpO1xuICBpZiAoIXRyaW1tZWQgfHwgKCF0cmltbWVkLnN0YXJ0c1dpdGgoXCJ7XCIpICYmICF0cmltbWVkLnN0YXJ0c1dpdGgoXCJbXCIpKSkgcmV0dXJuIGlucHV0O1xuICB0cnkge1xuICAgIHJldHVybiBKU09OLnBhcnNlKHRyaW1tZWQpIGFzIHVua25vd247XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBpbnB1dDtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb3VudFRva2Vucyh0ZXh0OiBzdHJpbmcpOiBudW1iZXIge1xuICByZXR1cm4gQ09OVEVYVF9FTkNPRElORy5lbmNvZGUodGV4dCwgW10sIFtdKS5sZW5ndGg7XG59XG5cbmZ1bmN0aW9uIHRydW5jYXRlVGV4dCh0ZXh0OiBzdHJpbmcsIHRva2VuQnVkZ2V0OiBudW1iZXIsIGVkZ2U6IFwic3RhcnRcIiB8IFwiZW5kXCIpOiBzdHJpbmcge1xuICBpZiAodG9rZW5CdWRnZXQgPD0gMCB8fCAhdGV4dCkgcmV0dXJuIFwiXCI7XG4gIGNvbnN0IHRva2VucyA9IENPTlRFWFRfRU5DT0RJTkcuZW5jb2RlKHRleHQsIFtdLCBbXSk7XG4gIGlmICh0b2tlbnMubGVuZ3RoIDw9IHRva2VuQnVkZ2V0KSByZXR1cm4gdGV4dDtcbiAgcmV0dXJuIENPTlRFWFRfRU5DT0RJTkcuZGVjb2RlKFxuICAgIGVkZ2UgPT09IFwic3RhcnRcIiA/IHRva2Vucy5zbGljZSgwLCB0b2tlbkJ1ZGdldCkgOiB0b2tlbnMuc2xpY2UoLXRva2VuQnVkZ2V0KSxcbiAgKTtcbn1cblxuZnVuY3Rpb24gbGFzdEV2ZW50SW5kZXgoXG4gIGV2ZW50czogcmVhZG9ubHkgQ29udmVyc2F0aW9uRXZlbnRbXSxcbiAgcm9sZTogQ29udmVyc2F0aW9uRXZlbnRbXCJyb2xlXCJdLFxuKTogbnVtYmVyIHtcbiAgZm9yIChsZXQgaW5kZXggPSBldmVudHMubGVuZ3RoIC0gMTsgaW5kZXggPj0gMDsgaW5kZXggLT0gMSkge1xuICAgIGlmIChldmVudHNbaW5kZXhdPy5yb2xlID09PSByb2xlKSByZXR1cm4gaW5kZXg7XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG5mdW5jdGlvbiB1bmlxdWVDYW5kaWRhdGVzPFQ+KFxuICBjYW5kaWRhdGVzOiByZWFkb25seSBTbWFydFJvdXRlckNhbmRpZGF0ZTxUPltdLFxuKTogU21hcnRSb3V0ZXJDYW5kaWRhdGU8VD5bXSB7XG4gIGNvbnN0IHNlZW4gPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgcmV0dXJuIGNhbmRpZGF0ZXMuZmlsdGVyKChjYW5kaWRhdGUpID0+IHtcbiAgICBjb25zdCBrZXkgPSBgJHtjYW5kaWRhdGUuaGFybmVzc306JHtub3JtYWxpemVSb3V0ZU1vZGVsKGNhbmRpZGF0ZS5tb2RlbCl9YDtcbiAgICBpZiAoc2Vlbi5oYXMoa2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgIHNlZW4uYWRkKGtleSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBub3JtYWxpemVSb3V0ZU1vZGVsKG1vZGVsOiBzdHJpbmcpOiBzdHJpbmcge1xuICBsZXQgbm9ybWFsaXplZCA9IG1vZGVsLnRyaW0oKS50b0xvd2VyQ2FzZSgpLnNwbGl0KFwiL1wiKS5hdCgtMSkgPz8gXCJcIjtcbiAgZm9yIChjb25zdCBwcmVmaXggb2YgW1wiZGF0YWJyaWNrcy1cIiwgXCJzeXN0ZW0uYWkuXCJdIGFzIGNvbnN0KSB7XG4gICAgaWYgKG5vcm1hbGl6ZWQuc3RhcnRzV2l0aChwcmVmaXgpKSB7XG4gICAgICBub3JtYWxpemVkID0gbm9ybWFsaXplZC5zbGljZShwcmVmaXgubGVuZ3RoKTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbm9ybWFsaXplZDtcbn1cblxuZnVuY3Rpb24gcHJvYmVLZXk8VD4oY2FuZGlkYXRlczogcmVhZG9ubHkgU21hcnRSb3V0ZXJDYW5kaWRhdGU8VD5bXSwgcm91dGVyTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHtcbiAgICByb3V0ZXJOYW1lLFxuICAgIGNhbmRpZGF0ZXM6IGNhbmRpZGF0ZXNcbiAgICAgIC5tYXAoKHsgbW9kZWwsIGhhcm5lc3MgfSkgPT4gKHsgbW9kZWw6IG5vcm1hbGl6ZVJvdXRlTW9kZWwobW9kZWwpLCBoYXJuZXNzIH0pKVxuICAgICAgLnNvcnQoKGxlZnQsIHJpZ2h0KSA9PlxuICAgICAgICBgJHtsZWZ0Lmhhcm5lc3N9OiR7bGVmdC5tb2RlbH1gLmxvY2FsZUNvbXBhcmUoYCR7cmlnaHQuaGFybmVzc306JHtyaWdodC5tb2RlbH1gKSxcbiAgICAgICksXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBhcHBLaXRDYWNoZU1hbmFnZXIoKTogQ2FjaGVNYW5hZ2VyIHwgdW5kZWZpbmVkIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gQ2FjaGVNYW5hZ2VyLmdldEluc3RhbmNlU3luYygpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNtYXJ0Um91dGVyUHJvYmVJZGVudGl0eShjbGllbnQ6IFdvcmtzcGFjZUNsaWVudCk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycygpO1xuICBjb25zdCBob3N0ID0gKGF3YWl0IGNsaWVudC5jb25maWcuZ2V0SG9zdCgpKS50b1N0cmluZygpO1xuICBhd2FpdCBjbGllbnQuY29uZmlnLmF1dGhlbnRpY2F0ZShoZWFkZXJzKTtcbiAgcmV0dXJuIGNyZWF0ZUhhc2goXCJzaGEyNTZcIilcbiAgICAudXBkYXRlKGhvc3QpXG4gICAgLnVwZGF0ZShcIlxcMFwiKVxuICAgIC51cGRhdGUoaGVhZGVycy5nZXQoXCJhdXRob3JpemF0aW9uXCIpID8/IFwiXCIpXG4gICAgLnVwZGF0ZShcIlxcMFwiKVxuICAgIC51cGRhdGUoaGVhZGVycy5nZXQoXCJ4LWRhdGFicmlja3Mtd29ya3NwYWNlLWlkXCIpID8/IFwiXCIpXG4gICAgLmRpZ2VzdChcImhleFwiKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gaW52b2tlU21hcnRSb3V0ZXIoXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50LFxuICBib2R5OiBTbWFydFJvdXRlclJlcXVlc3QsXG4gIHNpZ25hbDogQWJvcnRTaWduYWwsXG4gIHRpbWVvdXRNczogbnVtYmVyLFxuKTogUHJvbWlzZTx1bmtub3duPiB7XG4gIGNvbnN0IGhvc3QgPSAoYXdhaXQgY2xpZW50LmNvbmZpZy5nZXRIb3N0KCkpLnRvU3RyaW5nKCk7XG4gIGNvbnN0IHVybCA9IG5ldyBVUkwoXCIvYWktZ2F0ZXdheS9yb3V0aW5nL3YxL3JvdXRlczpzZWxlY3RcIiwgaG9zdCk7XG4gIGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycyh7IFwiY29udGVudC10eXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiIH0pO1xuICBhd2FpdCBjbGllbnQuY29uZmlnLmF1dGhlbnRpY2F0ZShoZWFkZXJzKTtcbiAgY29uc3QgY29tYmluZWRTaWduYWwgPSBBYm9ydFNpZ25hbC5hbnkoW3NpZ25hbCwgQWJvcnRTaWduYWwudGltZW91dCh0aW1lb3V0TXMpXSk7XG4gIGxldCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCwge1xuICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgaGVhZGVycyxcbiAgICBib2R5OiBKU09OLnN0cmluZ2lmeShib2R5KSxcbiAgICBzaWduYWw6IGNvbWJpbmVkU2lnbmFsLFxuICB9KTtcbiAgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gNDAxICYmIChhd2FpdCByZWZyZXNoV29ya3NwYWNlQ2xpZW50QXV0aGVudGljYXRpb24oY2xpZW50KSkpIHtcbiAgICBhd2FpdCByZXNwb25zZS5ib2R5Py5jYW5jZWwoKTtcbiAgICBoZWFkZXJzLmRlbGV0ZShcImF1dGhvcml6YXRpb25cIik7XG4gICAgaGVhZGVycy5kZWxldGUoXCJ4LWRhdGFicmlja3Mtd29ya3NwYWNlLWlkXCIpO1xuICAgIGF3YWl0IGNsaWVudC5jb25maWcuYXV0aGVudGljYXRlKGhlYWRlcnMpO1xuICAgIHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsLCB7XG4gICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgaGVhZGVycyxcbiAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGJvZHkpLFxuICAgICAgc2lnbmFsOiBjb21iaW5lZFNpZ25hbCxcbiAgICB9KTtcbiAgfVxuICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgY29uc3QgZGV0YWlsID0gKGF3YWl0IHJlc3BvbnNlLnRleHQoKS5jYXRjaCgoKSA9PiBcIlwiKSkudHJpbSgpLnNsaWNlKDAsIDUwMCk7XG4gICAgdGhyb3cgbmV3IFNtYXJ0Um91dGVyRXJyb3IoXG4gICAgICByZXNwb25zZS5zdGF0dXMgPT09IDQwNCA/IDQwNCA6IDUwMyxcbiAgICAgIGBEYXRhYnJpY2tzIFNtYXJ0IFJvdXRlciBmYWlsZWQgd2l0aCBIVFRQICR7cmVzcG9uc2Uuc3RhdHVzfSR7ZGV0YWlsID8gYDogJHtkZXRhaWx9YCA6IFwiXCJ9YCxcbiAgICApO1xuICB9XG4gIHJldHVybiByZXNwb25zZS5qc29uKCk7XG59XG4iXX0=