@workflow/core 5.0.0-beta.44 → 5.0.0-beta.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attribute-changes.d.ts +3 -5
- package/dist/attribute-changes.d.ts.map +1 -1
- package/dist/attribute-changes.js +2 -2
- package/dist/capabilities.d.ts +6 -5
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +14 -12
- package/dist/events-consumer.d.ts +30 -7
- package/dist/events-consumer.d.ts.map +1 -1
- package/dist/events-consumer.js +67 -11
- package/dist/flushable-stream.js +2 -2
- package/dist/global.d.ts +3 -1
- package/dist/global.d.ts.map +1 -1
- package/dist/global.js +8 -5
- package/dist/private.d.ts +20 -14
- package/dist/private.d.ts.map +1 -1
- package/dist/private.js +67 -29
- package/dist/replay-payload-cache.d.ts +13 -17
- package/dist/replay-payload-cache.d.ts.map +1 -1
- package/dist/replay-payload-cache.js +55 -57
- package/dist/runtime/constants.d.ts +3 -3
- package/dist/runtime/constants.d.ts.map +1 -1
- package/dist/runtime/constants.js +4 -4
- package/dist/runtime/helpers.d.ts +15 -34
- package/dist/runtime/helpers.d.ts.map +1 -1
- package/dist/runtime/helpers.js +18 -43
- package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -1
- package/dist/runtime/quickjs-entrypoint.js +8 -1
- package/dist/runtime/quickjs-runtime.js +7 -1
- package/dist/runtime/resume-hook.d.ts +20 -12
- package/dist/runtime/resume-hook.d.ts.map +1 -1
- package/dist/runtime/resume-hook.js +195 -249
- package/dist/runtime/resume-latency.d.ts +13 -6
- package/dist/runtime/resume-latency.d.ts.map +1 -1
- package/dist/runtime/resume-latency.js +4 -2
- package/dist/runtime/run.d.ts +1 -1
- package/dist/runtime/run.d.ts.map +1 -1
- package/dist/runtime/run.js +3 -2
- package/dist/runtime/start.js +12 -10
- package/dist/runtime/step-latency.d.ts +31 -14
- package/dist/runtime/step-latency.d.ts.map +1 -1
- package/dist/runtime/step-latency.js +19 -13
- package/dist/runtime/suspension-handler.d.ts +9 -7
- package/dist/runtime/suspension-handler.d.ts.map +1 -1
- package/dist/runtime/suspension-handler.js +41 -41
- package/dist/runtime/vm-mode.d.ts +1 -1
- package/dist/runtime/vm-mode.d.ts.map +1 -1
- package/dist/runtime/vm-mode.js +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +278 -125
- package/dist/serialization/hardened.d.ts +5 -4
- package/dist/serialization/hardened.d.ts.map +1 -1
- package/dist/serialization/hardened.js +7 -1
- package/dist/serialization-format.js +2 -2
- package/dist/serialization.d.ts +8 -9
- package/dist/serialization.d.ts.map +1 -1
- package/dist/serialization.js +32 -25
- package/dist/step.d.ts.map +1 -1
- package/dist/step.js +3 -11
- package/dist/telemetry/semantic-conventions.d.ts +51 -8
- package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
- package/dist/telemetry/semantic-conventions.js +38 -5
- package/dist/telemetry.d.ts +12 -0
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +62 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +2 -2
- package/dist/vm/script-cache.d.ts +9 -11
- package/dist/vm/script-cache.d.ts.map +1 -1
- package/dist/vm/script-cache.js +25 -40
- package/dist/workflow/attribute-dispatcher.d.ts.map +1 -1
- package/dist/workflow/attribute-dispatcher.js +3 -6
- package/dist/workflow/hook.d.ts.map +1 -1
- package/dist/workflow/hook.js +6 -15
- package/dist/workflow.d.ts +16 -0
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +73 -29
- package/docs/foundations/errors-and-retries.mdx +1 -1
- package/package.json +6 -6
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { HOOK_RESUME_DEDUP_VERSION,
|
|
1
|
+
import { ERROR_SLUGS, HookNotFoundError, RunExpiredError, WorkflowRuntimeError, } from '@workflow/errors';
|
|
2
|
+
import { HOOK_RESUME_DEDUP_VERSION, isLegacySpecVersion, isTerminalWorkflowRunStatus, SPEC_VERSION_CURRENT, SPEC_VERSION_LEGACY, SPEC_VERSION_SUPPORTS_COMPRESSION, } from '@workflow/world';
|
|
3
3
|
import { monotonicFactory } from 'ulid';
|
|
4
4
|
import { getRunCapabilities } from '../capabilities.js';
|
|
5
|
-
import { isRetryableWorldError } from '../classify-error.js';
|
|
6
5
|
import { importKey } from '../encryption.js';
|
|
7
6
|
import { runtimeLogger } from '../logger.js';
|
|
8
7
|
import { decodeRunPublicKey } from '../sealed-box.js';
|
|
@@ -16,24 +15,10 @@ import { getWorkflowQueueName } from './helpers.js';
|
|
|
16
15
|
import { safeWaitUntil, waitedUntil } from './wait-until.js';
|
|
17
16
|
/** Monotonic ULID factory for per-call resume idempotency keys. */
|
|
18
17
|
const generateResumeId = monotonicFactory();
|
|
19
|
-
/**
|
|
20
|
-
* Upper bound on the serialized hook payload that the parallel fast path will
|
|
21
|
-
* inline into the queue message's `hookInput`. Vercel Queues caps a single
|
|
22
|
-
* message at ~256 KiB, and the message also carries the runId, hookId, token,
|
|
23
|
-
* resumeId, digest, and trace carrier alongside CBOR framing overhead. Staying
|
|
24
|
-
* well under that ceiling keeps the queue publish from rejecting an oversized
|
|
25
|
-
* message, which, on the parallel path, would persist `hook_received` but never
|
|
26
|
-
* re-trigger the run. Above this size we fall back to the sequential path, whose
|
|
27
|
-
* queue message carries only the run ID (the payload lives in the event log).
|
|
28
|
-
*/
|
|
29
|
-
const MAX_INLINE_RESUME_PAYLOAD_BYTES = 128 * 1024;
|
|
30
18
|
/**
|
|
31
19
|
* Hex SHA-256 of the serialized resume payload bytes. Computed once by the
|
|
32
|
-
* producer and
|
|
33
|
-
*
|
|
34
|
-
* identical digest on the server's `(runId, resumeId)` constraint. Hashing the
|
|
35
|
-
* already-serialized bytes (not the raw value) keeps producer and consumer in
|
|
36
|
-
* lockstep: the consumer forwards this string without recomputing.
|
|
20
|
+
* producer and sent with its durable `hook_received` write so transport and
|
|
21
|
+
* slot retries converge through the server's `(runId, resumeId)` constraint.
|
|
37
22
|
*/
|
|
38
23
|
async function computeResumePayloadDigest(bytes) {
|
|
39
24
|
const digest = await crypto.subtle.digest('SHA-256', bytes);
|
|
@@ -44,6 +29,62 @@ async function computeResumePayloadDigest(bytes) {
|
|
|
44
29
|
}
|
|
45
30
|
return hex;
|
|
46
31
|
}
|
|
32
|
+
const HOOK_WAKE_RETRY_DELAYS_MS = [25, 100];
|
|
33
|
+
/**
|
|
34
|
+
* A wake failure worth retrying is transport-shaped (network error, 5xx,
|
|
35
|
+
* throttle). A definitive rejection will not change on a 25ms retry, so
|
|
36
|
+
* spending the budget on it only delays the caller's error.
|
|
37
|
+
*
|
|
38
|
+
* `@vercel/queue` errors carry no `status` field — they are bare `Error`
|
|
39
|
+
* subclasses distinguished by `name` — so classification checks the World's
|
|
40
|
+
* deployment-unavailable hook first (a deployment the queue cannot discover
|
|
41
|
+
* will not come back within this function's ~125ms budget), then a numeric
|
|
42
|
+
* status when one exists (non-Vercel queue implementations), then the queue
|
|
43
|
+
* client's definitive-4xx error names.
|
|
44
|
+
*/
|
|
45
|
+
function isRetryableWakeError(error, isDeploymentUnavailableError) {
|
|
46
|
+
if (isDeploymentUnavailableError?.(error))
|
|
47
|
+
return false;
|
|
48
|
+
const status = error ?? {};
|
|
49
|
+
const code = status.status ?? status.statusCode;
|
|
50
|
+
if (typeof code === 'number') {
|
|
51
|
+
return code >= 500 || code === 408 || code === 429;
|
|
52
|
+
}
|
|
53
|
+
const name = error?.name;
|
|
54
|
+
return (name !== 'BadRequestError' &&
|
|
55
|
+
name !== 'UnauthorizedError' &&
|
|
56
|
+
name !== 'ForbiddenError');
|
|
57
|
+
}
|
|
58
|
+
// A publish may succeed even when its response is lost, so a retry can
|
|
59
|
+
// enqueue a duplicate wake. That is harmless: the event is already durable,
|
|
60
|
+
// and deterministic replay makes a second delivery of the same run a no-op.
|
|
61
|
+
async function publishHookWakeWithRetry(publish, isDeploymentUnavailableError) {
|
|
62
|
+
let lastError;
|
|
63
|
+
for (let attempt = 0; attempt <= HOOK_WAKE_RETRY_DELAYS_MS.length; attempt++) {
|
|
64
|
+
try {
|
|
65
|
+
await publish();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
lastError = error;
|
|
70
|
+
if (!isRetryableWakeError(error, isDeploymentUnavailableError))
|
|
71
|
+
break;
|
|
72
|
+
const delayMs = HOOK_WAKE_RETRY_DELAYS_MS[attempt];
|
|
73
|
+
if (delayMs !== undefined) {
|
|
74
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// The wake only runs after the hook_received write committed, so a wake
|
|
79
|
+
// failure here is necessarily "durable but not yet dispatched": the event
|
|
80
|
+
// survives, and any later wake of the run delivers it. Do not let a queue
|
|
81
|
+
// implementation reuse HookNotFoundError and accidentally imply that no
|
|
82
|
+
// hook_received exists.
|
|
83
|
+
if (HookNotFoundError.is(lastError)) {
|
|
84
|
+
throw new WorkflowRuntimeError('The hook resume was committed, but its workflow wake could not be published', { cause: lastError });
|
|
85
|
+
}
|
|
86
|
+
throw lastError;
|
|
87
|
+
}
|
|
47
88
|
/** Derive a resume context from a full run (fallback for pre-`resumeContext` hooks). */
|
|
48
89
|
function resumeContextFromRun(run) {
|
|
49
90
|
const coreVersion = run.executionContext?.workflowCoreVersion;
|
|
@@ -145,6 +186,22 @@ export async function getHookByToken(token) {
|
|
|
145
186
|
* This function is called externally (e.g., from an API route or server action)
|
|
146
187
|
* to send data to a hook and resume the associated workflow run.
|
|
147
188
|
*
|
|
189
|
+
* Resolving means BOTH that the `hook_received` event is durably recorded in
|
|
190
|
+
* the run's event log and that the workflow wake was accepted by the queue, in
|
|
191
|
+
* that order. A {@link HookNotFoundError} means this invocation committed no
|
|
192
|
+
* event. Any other error after the write is ambiguous only in dispatch, never
|
|
193
|
+
* in durability: the event may already be committed, and a later wake of the
|
|
194
|
+
* run (from any source) will deliver it.
|
|
195
|
+
*
|
|
196
|
+
* Prefer passing the token string over a cached {@link Hook} object. A token
|
|
197
|
+
* is looked up fresh, so the live backend can attest its atomic resume claim
|
|
198
|
+
* and the durable write becomes idempotent-on-retry (transport retries of the
|
|
199
|
+
* same write converge on one event). A supplied Hook object may carry a stale
|
|
200
|
+
* attestation, so it is deliberately ignored and the write is claim-less —
|
|
201
|
+
* meaning a lost response cannot be retried safely: retrying at the
|
|
202
|
+
* application level mints a fresh claim and can commit a second
|
|
203
|
+
* `hook_received`.
|
|
204
|
+
*
|
|
148
205
|
* @param tokenOrHook - The unique token identifying the hook, or the hook object itself
|
|
149
206
|
* @param payload - The data payload to send to the hook
|
|
150
207
|
* @returns Promise resolving to the {@link ResumedHook}
|
|
@@ -172,11 +229,12 @@ export async function resumeHook(tokenOrHook, payload, encryptionKeyOverride) {
|
|
|
172
229
|
// Public entry point. It never attests hook freshness, so a Hook object
|
|
173
230
|
// supplied here (which may carry a `resumeCapabilities` cached before a
|
|
174
231
|
// server rollback or kill switch) is ignored by the dynamic-dedup gate and
|
|
175
|
-
// fails closed to
|
|
176
|
-
// the hook by token in-line during the same resume, reaches the
|
|
177
|
-
// implementation with the fresh attestation set. Keeping the
|
|
178
|
-
// off the exported signature prevents a caller from passing a
|
|
179
|
-
// `true` and reactivating dynamic dedup against a
|
|
232
|
+
// fails closed to a plain, claim-less write. Only `resumeWebhook`, which
|
|
233
|
+
// fetches the hook by token in-line during the same resume, reaches the
|
|
234
|
+
// internal implementation with the fresh attestation set. Keeping the
|
|
235
|
+
// freshness flag off the exported signature prevents a caller from passing a
|
|
236
|
+
// stale Hook plus `true` and reactivating dynamic dedup against a
|
|
237
|
+
// rolled-back backend.
|
|
180
238
|
//
|
|
181
239
|
// T0 of the hook-resume TTR window is taken HERE, at the public entry point,
|
|
182
240
|
// rather than inside the implementation; see the parameter's doc comment.
|
|
@@ -282,18 +340,31 @@ async function resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, hookF
|
|
|
282
340
|
capabilities.supportedFormats.has(SerializationFormat.GZIP);
|
|
283
341
|
// Dehydrate the payload for storage
|
|
284
342
|
const ops = [];
|
|
343
|
+
const readbackOps = [];
|
|
285
344
|
const v1Compat = isLegacySpecVersion(hook.specVersion);
|
|
286
|
-
const dehydratedPayload = await dehydrateStepReturnValue(payload, hook.runId, payloadKey, ops, globalThis, v1Compat, capabilities.framedByteStreams, compression);
|
|
287
|
-
//
|
|
288
|
-
//
|
|
289
|
-
//
|
|
290
|
-
//
|
|
291
|
-
//
|
|
292
|
-
// webhook
|
|
293
|
-
|
|
345
|
+
const dehydratedPayload = await dehydrateStepReturnValue(payload, hook.runId, payloadKey, ops, globalThis, v1Compat, capabilities.framedByteStreams, compression, undefined, readbackOps);
|
|
346
|
+
// A hook_received event is not durable while its payload still points
|
|
347
|
+
// at stream uploads in flight. Finish those before committing the
|
|
348
|
+
// event — but ONLY the producer-push ops in `ops`. A dehydrated
|
|
349
|
+
// WritableStream lands in `readbackOps` instead: it is a server-stream
|
|
350
|
+
// READER that resolves only once the woken workflow writes into it (a
|
|
351
|
+
// manual webhook's `responseWritable` is the canonical case), so
|
|
352
|
+
// awaiting it here would deadlock the resume against its own wake.
|
|
353
|
+
//
|
|
354
|
+
// A rejection with `undefined` is an expected artifact of the webhook
|
|
355
|
+
// bundle and was historically ignored by the background flush. Keep
|
|
356
|
+
// that tolerance now that the flush is awaited inline.
|
|
357
|
+
await Promise.all(ops.map((op) => op.catch((error) => {
|
|
358
|
+
if (error !== undefined)
|
|
359
|
+
throw error;
|
|
360
|
+
})));
|
|
361
|
+
// Readback pipes (notably a manual webhook response writable) can only
|
|
362
|
+
// finish after the workflow wakes and writes to them. Keep them alive,
|
|
363
|
+
// but never place them in the durability barrier above.
|
|
364
|
+
safeWaitUntil(Promise.all(readbackOps), (err) => {
|
|
294
365
|
if (err === undefined)
|
|
295
366
|
return;
|
|
296
|
-
runtimeLogger.warn('Background
|
|
367
|
+
runtimeLogger.warn('Background readback of hook payload failed', {
|
|
297
368
|
workflowRunId: hook.runId,
|
|
298
369
|
hookId: hook.hookId,
|
|
299
370
|
error: err instanceof Error ? err.message : String(err),
|
|
@@ -303,251 +374,126 @@ async function resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, hookF
|
|
|
303
374
|
...Attribute.WorkflowName(resumeContext.workflowName),
|
|
304
375
|
});
|
|
305
376
|
// Link to the run-origin context from the stored trace carrier
|
|
306
|
-
// (skipped when absent or invalid). Resolved before dispatch so
|
|
307
|
-
// the
|
|
377
|
+
// (skipped when absent or invalid). Resolved before dispatch so the
|
|
378
|
+
// write and the wake both sit under a span that carries it.
|
|
308
379
|
const originLink = await linkToTraceCarrier(resumeContext.traceCarrier);
|
|
309
380
|
if (originLink) {
|
|
310
381
|
span?.addLink?.(originLink);
|
|
311
382
|
}
|
|
312
|
-
const eventData = {
|
|
313
|
-
...(v1Compat ? {} : { token: hook.token }),
|
|
314
|
-
payload: dehydratedPayload,
|
|
315
|
-
};
|
|
316
383
|
const queueName = getWorkflowQueueName(resumeContext.workflowName);
|
|
317
384
|
const queueOptions = {
|
|
318
385
|
deploymentId: resumeContext.deploymentId,
|
|
319
386
|
specVersion: resumeContext.runSpecVersion ?? SPEC_VERSION_LEGACY,
|
|
320
387
|
};
|
|
321
|
-
//
|
|
322
|
-
//
|
|
323
|
-
//
|
|
324
|
-
//
|
|
325
|
-
//
|
|
388
|
+
// The dispatch is strictly serial: the hook_received event is made
|
|
389
|
+
// durable FIRST, and the workflow wake is published only after the
|
|
390
|
+
// write is acknowledged. This is what lets `resumeHook()` resolving
|
|
391
|
+
// mean "the resume survives anything that happens next" — a disposal
|
|
392
|
+
// or run completion racing the queue delivery cannot erase a committed
|
|
393
|
+
// event, and the wake itself carries no payload, so nothing rides on
|
|
394
|
+
// the message but the trigger.
|
|
326
395
|
//
|
|
327
|
-
//
|
|
328
|
-
// if the fast path ever misbehaves. It is an SDK-deployment env var,
|
|
329
|
-
// so changing it generally requires redeploying the workflow
|
|
330
|
-
// deployment. (The backend can independently drop new resumes to the
|
|
331
|
-
// sequential path fleet-wide by ceasing to attest dedup support on
|
|
332
|
-
// the by-token lookup; see the backend-dedup condition below.)
|
|
333
|
-
// - backend dedup: the live backend must enforce the
|
|
334
|
-
// `(runId, resumeId)` constraint, or the two writers would commit two
|
|
335
|
-
// `hook_received` events. Fail closed. Attested by EITHER a fresh,
|
|
336
|
-
// response-only `hook.resumeCapabilities.hookResumeDedupVersion` from
|
|
337
|
-
// the by-token lookup (world-vercel: recomputed every read, so a
|
|
338
|
-
// server rollback or kill switch drops to sequential immediately) OR
|
|
339
|
-
// the static `world.capabilities.hookResumeDedup` (world-local, whose
|
|
340
|
-
// adapter and backend ship together). The response-only capability is
|
|
341
|
-
// trusted ONLY when the hook was looked up by token during this
|
|
342
|
-
// resume (`hookResumeCapabilitiesAreFresh`); a Hook object handed in
|
|
343
|
-
// by a public caller may carry a capability cached before a rollback,
|
|
344
|
-
// so it is ignored and the path falls back to sequential.
|
|
345
|
-
// - consumer support: the target run's deployment must re-ensure the
|
|
346
|
-
// event from `hookInput` on replay. Attested by the run's explicit
|
|
347
|
-
// `hookResumeInputVersion` execution-context marker (mirrored onto
|
|
348
|
-
// resumeContext), NOT a version-compare against a predicted release
|
|
349
|
-
// cutoff. Absent → a lost producer write would be a lost resume.
|
|
350
|
-
// - not legacy: v1Compat runs omit `token` from the producer's event
|
|
351
|
-
// body but the consumer's re-ensure always includes it, so the two
|
|
352
|
-
// writers would disagree on the event body. Legacy stays sequential.
|
|
353
|
-
// - CBOR transport: the run must use CBOR queue transport so the binary
|
|
354
|
-
// payload survives the queue message.
|
|
355
|
-
// - raw bytes: the dehydrated payload must be a `Uint8Array` (the
|
|
356
|
-
// content digest that keys the dedup constraint is over these bytes).
|
|
357
|
-
// - size: a payload above the queue's message ceiling would fail the
|
|
358
|
-
// publish (which, on the parallel path, would persist the event but
|
|
359
|
-
// never re-trigger the run), so oversized payloads stay sequential
|
|
360
|
-
// (their queue message carries only the run ID).
|
|
361
|
-
const parallelResumeDisabled = process.env.WORKFLOW_DISABLE_LAZY_HOOK_RESUME === '1';
|
|
362
|
-
// Backend dedup is supported when EITHER the live server attests it
|
|
396
|
+
// Backend dedup is attested when EITHER the live server attests it
|
|
363
397
|
// fresh on this by-token hook (world-vercel: response-only, recomputed
|
|
364
398
|
// every read, so rollback/kill-switch take effect immediately) OR the
|
|
365
399
|
// static world capability is set (world-local: adapter + backend ship
|
|
366
|
-
// together).
|
|
367
|
-
//
|
|
400
|
+
// together). When attested, the write carries a per-call resumeId +
|
|
401
|
+
// payload digest so transport-level retries of the SAME write converge
|
|
402
|
+
// on exactly one committed event via the backend's (runId, resumeId)
|
|
403
|
+
// constraint. Without it the write is a plain single-shot create,
|
|
404
|
+
// exactly as before dedup existed.
|
|
368
405
|
const backendDedupSupported = (hookResumeCapabilitiesAreFresh
|
|
369
406
|
? (hook.resumeCapabilities?.hookResumeDedupVersion ?? 0)
|
|
370
407
|
: 0) >= HOOK_RESUME_DEDUP_VERSION ||
|
|
371
408
|
world.capabilities?.hookResumeDedup === true;
|
|
372
|
-
const
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
? 'backend_unsupported'
|
|
376
|
-
: (resumeContext.hookResumeInputVersion ?? 0) <
|
|
377
|
-
HOOK_RESUME_INPUT_VERSION
|
|
378
|
-
? 'consumer_unsupported'
|
|
379
|
-
: v1Compat
|
|
380
|
-
? 'legacy'
|
|
381
|
-
: (resumeContext.runSpecVersion ?? 0) <
|
|
382
|
-
SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT
|
|
383
|
-
? 'non_cbor_transport'
|
|
384
|
-
: !(dehydratedPayload instanceof Uint8Array)
|
|
385
|
-
? 'non_bytes'
|
|
386
|
-
: dehydratedPayload.byteLength >
|
|
387
|
-
MAX_INLINE_RESUME_PAYLOAD_BYTES
|
|
388
|
-
? 'oversized'
|
|
389
|
-
: null;
|
|
390
|
-
const useParallelResume = fallbackReason === null;
|
|
409
|
+
const canClaimResume = backendDedupSupported &&
|
|
410
|
+
!v1Compat &&
|
|
411
|
+
dehydratedPayload instanceof Uint8Array;
|
|
391
412
|
span?.setAttributes({
|
|
392
|
-
'workflow.hook.resume_strategy':
|
|
393
|
-
? 'parallel'
|
|
394
|
-
: 'sequential',
|
|
395
|
-
...(fallbackReason
|
|
396
|
-
? { 'workflow.hook.resume_fallback_reason': fallbackReason }
|
|
397
|
-
: {}),
|
|
413
|
+
'workflow.hook.resume_strategy': 'sequential',
|
|
398
414
|
});
|
|
415
|
+
const resumeId = canClaimResume ? generateResumeId() : undefined;
|
|
416
|
+
const payloadDigest = canClaimResume
|
|
417
|
+
? await computeResumePayloadDigest(dehydratedPayload)
|
|
418
|
+
: undefined;
|
|
419
|
+
if (resumeId) {
|
|
420
|
+
span?.setAttributes({ 'workflow.hook.resume_id': resumeId });
|
|
421
|
+
}
|
|
399
422
|
// Re-key any "hook can no longer be received" rejection to
|
|
400
|
-
// HookNotFoundError(hook.token) so `.token` matches the
|
|
401
|
-
// contract
|
|
402
|
-
//
|
|
403
|
-
//
|
|
404
|
-
// - a genuinely missing hook maps to HookNotFoundError (keyed on the
|
|
405
|
-
// event correlationId / hook ID);
|
|
423
|
+
// HookNotFoundError(hook.token) so `.token` matches the historical
|
|
424
|
+
// contract. The specific error depends on the World:
|
|
425
|
+
// - a genuinely missing hook maps to HookNotFoundError (keyed on
|
|
426
|
+
// the event correlationId / hook ID);
|
|
406
427
|
// - a terminal run on Vercel rejects hook_received with 404, which
|
|
407
428
|
// world-vercel maps to HookNotFoundError;
|
|
408
429
|
// - a terminal run on world-local / world-postgres rejects with
|
|
409
430
|
// RunExpiredError.
|
|
410
431
|
//
|
|
411
|
-
//
|
|
412
|
-
//
|
|
413
|
-
//
|
|
414
|
-
//
|
|
415
|
-
//
|
|
416
|
-
//
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
specVersion: SPEC_VERSION_CURRENT,
|
|
426
|
-
correlationId: hook.hookId,
|
|
427
|
-
eventData,
|
|
428
|
-
}, { v1Compat });
|
|
429
|
-
}
|
|
430
|
-
catch (err) {
|
|
431
|
-
if (isHookGoneError(err)) {
|
|
432
|
-
throw new HookNotFoundError(hook.token);
|
|
433
|
-
}
|
|
434
|
-
throw err;
|
|
435
|
-
}
|
|
436
|
-
// T1 of the TTR window. Stamped immediately before the publish so
|
|
437
|
-
// `producer_prep` covers exactly the work above it (hook lookup,
|
|
438
|
-
// key resolution, serialization, and, on this path, the awaited
|
|
439
|
-
// `hook_received` write, which is genuinely serial here).
|
|
440
|
-
const queuePublishRequestedAtMs = Date.now();
|
|
441
|
-
await world.queue(queueName, {
|
|
442
|
-
runId: hook.runId,
|
|
443
|
-
traceCarrier: resumeContext.traceCarrier ?? undefined,
|
|
444
|
-
hookResumeTiming: {
|
|
445
|
-
resumeRequestedAtMs,
|
|
446
|
-
queuePublishRequestedAtMs,
|
|
447
|
-
strategy: 'sequential',
|
|
448
|
-
},
|
|
449
|
-
}, queueOptions);
|
|
450
|
-
return hook;
|
|
451
|
-
}
|
|
452
|
-
// Parallel fast path. A stable idempotency key ties the direct write to
|
|
453
|
-
// the queue consumer's re-ensure; the payload digest lets the server
|
|
454
|
-
// detect key reuse across byte-identical payloads.
|
|
455
|
-
const resumeId = generateResumeId();
|
|
456
|
-
const payloadDigest = await computeResumePayloadDigest(dehydratedPayload);
|
|
457
|
-
span?.setAttributes({ 'workflow.hook.resume_id': resumeId });
|
|
458
|
-
// Wrapped in a thunk purely so T1 of the TTR window is stamped at the
|
|
459
|
-
// exact instant the publish is requested, after the racing
|
|
460
|
-
// `hook_received` write has been kicked off, which is where the
|
|
461
|
-
// additive `producer_prep` phase must end. The two calls still start
|
|
462
|
-
// in the same turn and race exactly as before.
|
|
463
|
-
const publishInvocation = () => {
|
|
464
|
-
const queuePublishRequestedAtMs = Date.now();
|
|
465
|
-
return world.queue(queueName, {
|
|
466
|
-
runId: hook.runId,
|
|
467
|
-
traceCarrier: resumeContext.traceCarrier ?? undefined,
|
|
468
|
-
hookInput: {
|
|
469
|
-
resumeId,
|
|
470
|
-
hookId: hook.hookId,
|
|
471
|
-
token: hook.token,
|
|
472
|
-
payload: dehydratedPayload,
|
|
473
|
-
payloadDigest,
|
|
474
|
-
// Deployment affinity for the consumer's cheap pre-write
|
|
475
|
-
// check: lets a misrouted delivery re-route before its
|
|
476
|
-
// hoisted hook_received write instead of after.
|
|
477
|
-
deploymentId: resumeContext.deploymentId,
|
|
478
|
-
},
|
|
479
|
-
hookResumeTiming: {
|
|
480
|
-
resumeRequestedAtMs,
|
|
481
|
-
queuePublishRequestedAtMs,
|
|
482
|
-
strategy: 'parallel',
|
|
483
|
-
},
|
|
484
|
-
}, queueOptions);
|
|
485
|
-
};
|
|
486
|
-
const [eventResult, queueResult] = await Promise.allSettled([
|
|
487
|
-
world.events.create(hook.runId, {
|
|
432
|
+
// An EntityConflictError (HTTP 409) is deliberately NOT re-keyed,
|
|
433
|
+
// breaking with the historical mapping: every 409 the backend emits
|
|
434
|
+
// on this write today is TRANSIENT — a slot conflict that escaped the
|
|
435
|
+
// server's own retry budget under contention, or a resume-claim race
|
|
436
|
+
// mid-resolution — and its transaction committed nothing. Re-keying
|
|
437
|
+
// it to HookNotFoundError told the caller (and a webhook sender, via
|
|
438
|
+
// 404) that a retryable failure was permanent, silently dropping the
|
|
439
|
+
// resume. It now surfaces as-is: retryable, with nothing committed.
|
|
440
|
+
// (A 422 resumeId-reuse error likewise passes through unmapped — it
|
|
441
|
+
// means the caller replayed a resumeId with a different payload, and
|
|
442
|
+
// hiding that behind "not found" would mask the bug.)
|
|
443
|
+
const isHookGoneError = (err) => HookNotFoundError.is(err) || RunExpiredError.is(err);
|
|
444
|
+
try {
|
|
445
|
+
await world.events.create(hook.runId, {
|
|
488
446
|
eventType: 'hook_received',
|
|
489
447
|
specVersion: SPEC_VERSION_CURRENT,
|
|
490
448
|
correlationId: hook.hookId,
|
|
491
|
-
eventData
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
449
|
+
eventData: {
|
|
450
|
+
...(v1Compat ? {} : { token: hook.token }),
|
|
451
|
+
payload: dehydratedPayload,
|
|
452
|
+
},
|
|
453
|
+
}, {
|
|
454
|
+
v1Compat,
|
|
455
|
+
...(resumeId && payloadDigest
|
|
456
|
+
? { resumeId, resumePayloadDigest: payloadDigest }
|
|
457
|
+
: {}),
|
|
458
|
+
});
|
|
499
459
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
// caller as `ResumedHook.resilientResume` and on the span.
|
|
503
|
-
let resilientResume = false;
|
|
504
|
-
if (eventResult.status === 'rejected') {
|
|
505
|
-
const err = eventResult.reason;
|
|
506
|
-
if (HookNotFoundError.is(err) || RunExpiredError.is(err)) {
|
|
507
|
-
// The hook's run has genuinely ended: surface the same contract as
|
|
508
|
-
// the sequential path. The queue message already went out, but the
|
|
509
|
-
// consumer's re-ensure will also reject against the terminal run
|
|
510
|
-
// and no-op, so the workflow does not resume.
|
|
460
|
+
catch (err) {
|
|
461
|
+
if (isHookGoneError(err)) {
|
|
511
462
|
throw new HookNotFoundError(hook.token);
|
|
512
463
|
}
|
|
513
|
-
|
|
514
|
-
// Resilient. Two shapes reach here, both non-terminal:
|
|
515
|
-
// - EntityConflict (409): this write raced its own re-ensuring
|
|
516
|
-
// consumer (or a redrive) on the shared `resumeId`; the run is
|
|
517
|
-
// NOT gone, and the consumer converges on the one committed
|
|
518
|
-
// event. Unlike the sequential path, a 409 here is expected
|
|
519
|
-
// concurrency, not a vanished hook.
|
|
520
|
-
// - 429 / 5xx / transport: a transient backend failure.
|
|
521
|
-
// In both cases the run WAS re-triggered via the queue and the
|
|
522
|
-
// consumer idempotently ensures the hook_received before replay, so
|
|
523
|
-
// swallow rather than failing the caller.
|
|
524
|
-
//
|
|
525
|
-
// Producer telemetry: record that the direct write did not land but
|
|
526
|
-
// the resume is still guaranteed via queue-delivered `hookInput`.
|
|
527
|
-
// This is the operational signal that the recovery path fired,
|
|
528
|
-
// surfaced both on the span and as the public `resilientResume`
|
|
529
|
-
// flag on the returned hook (the resume outcome is otherwise
|
|
530
|
-
// identical to the happy path from the caller's perspective).
|
|
531
|
-
resilientResume = true;
|
|
532
|
-
span?.setAttributes({
|
|
533
|
-
...Attribute.HookResilientResume(true),
|
|
534
|
-
'workflow.hook.resume_event_write_recovered': true,
|
|
535
|
-
'workflow.hook.resume_event_write_error': err instanceof Error ? err.name : 'unknown',
|
|
536
|
-
});
|
|
537
|
-
runtimeLogger.warn('Hook resume event write failed, but the run was re-triggered via ' +
|
|
538
|
-
'the queue. The hook_received event will be ensured by the ' +
|
|
539
|
-
'queue consumer.', {
|
|
540
|
-
workflowRunId: hook.runId,
|
|
541
|
-
hookId: hook.hookId,
|
|
542
|
-
resumeId,
|
|
543
|
-
error: err instanceof Error ? err.message : String(err),
|
|
544
|
-
});
|
|
545
|
-
}
|
|
546
|
-
else {
|
|
547
|
-
throw err;
|
|
548
|
-
}
|
|
464
|
+
throw err;
|
|
549
465
|
}
|
|
550
|
-
|
|
466
|
+
// Stamped AFTER the write resolves (entry-time attributes cannot tell
|
|
467
|
+
// an attempted resume from a committed one): together with
|
|
468
|
+
// HookWakePublished below, this is what makes a stranded resume — a
|
|
469
|
+
// committed event whose wake never went out or was never delivered —
|
|
470
|
+
// queryable from traces. See the alerting note on HookWakePublished.
|
|
471
|
+
span?.setAttributes(Attribute.HookResumeCommitted(true));
|
|
472
|
+
// T1 of the TTR window. Stamped immediately before the publish so
|
|
473
|
+
// `producer_prep` covers exactly the work above it (hook lookup, key
|
|
474
|
+
// resolution, serialization, and the awaited hook_received write,
|
|
475
|
+
// which is genuinely serial here).
|
|
476
|
+
const queuePublishRequestedAtMs = Date.now();
|
|
477
|
+
await publishHookWakeWithRetry(() => world.queue(queueName, {
|
|
478
|
+
runId: hook.runId,
|
|
479
|
+
traceCarrier: resumeContext.traceCarrier ?? undefined,
|
|
480
|
+
hookResumeTiming: {
|
|
481
|
+
resumeRequestedAtMs,
|
|
482
|
+
queuePublishRequestedAtMs,
|
|
483
|
+
strategy: 'sequential',
|
|
484
|
+
},
|
|
485
|
+
}, {
|
|
486
|
+
...queueOptions,
|
|
487
|
+
// Dedup retried publishes whose response was lost: a
|
|
488
|
+
// duplicate wake is harmless for correctness (deterministic
|
|
489
|
+
// replay) but costs a full replay of the run, and the queue
|
|
490
|
+
// accepts a repeated idempotency key by delivering only one
|
|
491
|
+
// of the messages. Claim-less writes have no resumeId and
|
|
492
|
+
// keep the previous behavior.
|
|
493
|
+
...(resumeId ? { idempotencyKey: `hook-${resumeId}` } : {}),
|
|
494
|
+
}), world.isDeploymentUnavailableError?.bind(world));
|
|
495
|
+
span?.setAttributes(Attribute.HookWakePublished(true));
|
|
496
|
+
return hook;
|
|
551
497
|
}
|
|
552
498
|
catch (err) {
|
|
553
499
|
span?.setAttributes({
|
|
@@ -635,8 +581,8 @@ export async function resumeWebhook(token, request) {
|
|
|
635
581
|
// `hook` was just fetched via `getHookByTokenWithKey` (a fresh by-token
|
|
636
582
|
// lookup) above, so its response-only `resumeCapabilities` reflects the live
|
|
637
583
|
// backend. Call the internal implementation with the fresh attestation so
|
|
638
|
-
// the
|
|
639
|
-
// `resumeHook` never sets this, so a caller cannot forge it.)
|
|
584
|
+
// the write's idempotency claim stays available without a second GET. (The
|
|
585
|
+
// public `resumeHook` never sets this, so a caller cannot forge it.)
|
|
640
586
|
await resumeHookImpl(hook, request, encryptionKey, true, resumeRequestedAtMs);
|
|
641
587
|
if (responseReadable) {
|
|
642
588
|
// Wait for the readable stream to emit one chunk,
|
|
@@ -655,4 +601,4 @@ export async function resumeWebhook(token, request) {
|
|
|
655
601
|
}
|
|
656
602
|
return response;
|
|
657
603
|
}
|
|
658
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdW1lLWhvb2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVudGltZS9yZXN1bWUtaG9vay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLFdBQVcsRUFDWCxpQkFBaUIsRUFDakIsZUFBZSxFQUNmLG9CQUFvQixHQUNyQixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFDTCx5QkFBeUIsRUFDekIseUJBQXlCLEVBR3pCLG1CQUFtQixFQUNuQiwyQkFBMkIsRUFDM0Isb0JBQW9CLEVBQ3BCLG1CQUFtQixFQUNuQiwwQ0FBMEMsRUFDMUMsaUNBQWlDLEdBR2xDLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzdELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3RFLE9BQU8sRUFDTCx3QkFBd0IsRUFDeEIsb0JBQW9CLEVBRXBCLG1CQUFtQixFQUNuQixNQUFNLEdBQ1AsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDMUQsT0FBTyxLQUFLLFNBQVMsTUFBTSxzQ0FBc0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsS0FBSyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDNUQsT0FBTyxFQUFFLFlBQVksRUFB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SUFBSSxvQkFBb0IsQ0FDNUIsa0NBQWtDLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLEVBQzdELEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxrQ0FBa0MsRUFBRSxDQUN6RCxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7U0FBTSxDQUFDO1FBQ04seUVBQXlFO1FBQ3pFLFFBQVEsR0FBRyxJQUFJLFFBQVEsQ0FBQyxJQUFJLEVBQUUsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRUQsd0VBQXdFO0lBQ3hFLDZFQUE2RTtJQUM3RSwwRUFBMEU7SUFDMUUsMkVBQTJFO0lBQzNFLDhEQUE4RDtJQUM5RCxNQUFNLGNBQWMsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztJQUU5RSxJQUFJLGdCQUFnQixFQUFFLENBQUM7UUFDckIsa0RBQWtEO1FBQ2xELGlDQUFpQztRQUNqQyxNQUFNLE1BQU0sR0FBRyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUM1QyxNQUFNLEtBQUssR0FBRyxNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNsQyxJQUFJLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNoQixRQUFRLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQztRQUN6QixDQUFDO1FBQ0QsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDZCxNQUFNLElBQUksb0JBQW9CLENBQUMsc0NBQXNDLEVBQUU7WUFDckUsSUFBSSxFQUFFLFdBQVcsQ0FBQyx5QkFBeUI7U0FDNUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELE9BQU8sUUFBUSxDQUFDO0FBQ2xCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBFbnRpdHlDb25mbGljdEVycm9yLFxuICBFUlJPUl9TTFVHUyxcbiAgSG9va05vdEZvdW5kRXJyb3IsXG4gIFJ1bkV4cGlyZWRFcnJvcixcbiAgV29ya2Zsb3dSdW50aW1lRXJyb3IsXG59IGZyb20gJ0B3b3JrZmxvdy9lcnJvcnMnO1xuaW1wb3J0IHtcbiAgSE9PS19SRVNVTUVfREVEVVBfVkVSU0lPTixcbiAgSE9PS19SRVNVTUVfSU5QVVRfVkVSU0lPTixcbiAgdHlwZSBIb29rLFxuICB0eXBlIEhvb2tSZXN1bWVDb250ZXh0LFxuICBpc0xlZ2FjeVNwZWNWZXJzaW9uLFxuICBpc1Rlcm1pbmFsV29ya2Zsb3dSdW5TdGF0dXMsXG4gIFNQRUNfVkVSU0lPTl9DVVJSRU5ULFxuICBTUEVDX1ZFUlNJT05fTEVHQUNZLFxuICBTUEVDX1ZFUlNJT05fU1VQUE9SVFNfQ0JPUl9RVUVVRV9UUkFOU1BPUlQsXG4gIFNQRUNfVkVSU0lPTl9TVVBQT1JUU19DT01QUkVTU0lPTixcbiAgdHlwZSBXb3JrZmxvd0ludm9rZVBheWxvYWQsXG4gIHR5cGUgV29ya2Zsb3dSdW4sXG59IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgeyBtb25vdG9uaWNGYWN0b3J5IH0gZnJvbSAndWxpZCc7XG5pbXBvcnQgeyBnZXRSdW5DYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9jYXBhYmlsaXRpZXMuanMnO1xuaW1wb3J0IHsgaXNSZXRyeWFibGVXb3JsZEVycm9yIH0gZnJvbSAnLi4vY2xhc3NpZnktZXJyb3IuanMnO1xuaW1wb3J0IHsgaW1wb3J0S2V5IH0gZnJvbSAnLi4vZW5jcnlwdGlvbi5qcyc7XG5pbXBvcnQgeyBydW50aW1lTG9nZ2VyIH0gZnJvbSAnLi4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IGRlY29kZVJ1blB1YmxpY0tleSB9IGZyb20gJy4uL3NlYWxlZC1ib3guanMnO1xuaW1wb3J0IHsgZGVyaXZlUnVuUGF5bG9hZEtleXMgfSBmcm9tICcuLi9zZXJpYWxpemF0aW9uL2VuY3J5cHRpb24uanMnO1xuaW1wb3J0IHtcbiAgZGVoeWRyYXRlU3RlcFJldHVyblZhbHVlLFxuICBoeWRyYXRlU3RlcEFyZ3VtZW50cyxcbiAgdHlwZSBQYXlsb2FkS2V5LFxuICBTZXJpYWxpemF0aW9uRm9ybWF0LFxuICBzZWFsVG8sXG59IGZyb20gJy4uL3NlcmlhbGl6YXRpb24uanMnO1xuaW1wb3J0IHsgV0VCSE9PS19SRVNQT05TRV9XUklUQUJMRSB9IGZyb20gJy4uL3N5bWJvbHMuanMnO1xuaW1wb3J0ICogYXMgQXR0cmlidXRlIGZyb20gJy4uL3RlbGVtZXRyeS9zZW1hbnRpYy1jb252ZW50aW9ucy5qcyc7XG5pbXBvcnQgeyBsaW5rVG9UcmFjZUNhcnJpZXIsIHRyYWNlIH0gZnJvbSAnLi4vdGVsZW1ldHJ5LmpzJztcbmltcG9ydCB7IGdldFdvcmxkTGF6eSB9IGZyb20gJy4vZ2V0LXdvcmxkLWxhenkuanMnO1xuaW1wb3J0IHsgZ2V0V29ya2Zsb3dRdWV1ZU5hbWUgfSBmcm9tICcuL2hlbHBlcnMuanMnO1xuaW1wb3J0IHsgc2FmZVdhaXRVbnRpbCwgd2FpdGVkVW50aWwgfSBmcm9tICcuL3dhaXQtdW50aWwuanMnO1xuXG4vKiogTW9ub3RvbmljIFVMSUQgZmFjdG9yeSBmb3IgcGVyLWNhbGwgcmVzdW1lIGlkZW1wb3RlbmN5IGtleXMuICovXG5jb25zdCBnZW5lcmF0ZVJlc3VtZUlkID0gbW9ub3RvbmljRmFjdG9yeSgpO1xuXG4vKipcbiAqIFVwcGVyIGJvdW5kIG9uIHRoZSBzZXJpYWxpemVkIGhvb2sgcGF5bG9hZCB0aGF0IHRoZSBwYXJhbGxlbCBmYXN0IHBhdGggd2lsbFxuICogaW5saW5lIGludG8gdGhlIHF1ZXVlIG1lc3NhZ2UncyBgaG9va0lucHV0YC4gVmVyY2VsIFF1ZXVlcyBjYXBzIGEgc2luZ2xlXG4gKiBtZXNzYWdlIGF0IH4yNTYgS2lCLCBhbmQgdGhlIG1lc3NhZ2UgYWxzbyBjYXJyaWVzIHRoZSBydW5JZCwgaG9va0lkLCB0b2tlbixcbiAqIHJlc3VtZUlkLCBkaWdlc3QsIGFuZCB0cmFjZSBjYXJyaWVyIGFsb25nc2lkZSBDQk9SIGZyYW1pbmcgb3ZlcmhlYWQuIFN0YXlpbmdcbiAqIHdlbGwgdW5kZXIgdGhhdCBjZWlsaW5nIGtlZXBzIHRoZSBxdWV1ZSBwdWJsaXNoIGZyb20gcmVqZWN0aW5nIGFuIG92ZXJzaXplZFxuICogbWVzc2FnZSwgd2hpY2gsIG9uIHRoZSBwYXJhbGxlbCBwYXRoLCB3b3VsZCBwZXJzaXN0IGBob29rX3JlY2VpdmVkYCBidXQgbmV2ZXJcbiAqIHJlLXRyaWdnZXIgdGhlIHJ1bi4gQWJvdmUgdGhpcyBzaXplIHdlIGZhbGwgYmFjayB0byB0aGUgc2VxdWVudGlhbCBwYXRoLCB3aG9zZVxuICogcXVldWUgbWVzc2FnZSBjYXJyaWVzIG9ubHkgdGhlIHJ1biBJRCAodGhlIHBheWxvYWQgbGl2ZXMgaW4gdGhlIGV2ZW50IGxvZykuXG4gKi9cbmNvbnN0IE1BWF9JTkxJTkVfUkVTVU1FX1BBWUxPQURfQllURVMgPSAxMjggKiAxMDI0O1xuXG4vKipcbiAqIEhleCBTSEEtMjU2IG9mIHRoZSBzZXJpYWxpemVkIHJlc3VtZSBwYXlsb2FkIGJ5dGVzLiBDb21wdXRlZCBvbmNlIGJ5IHRoZVxuICogcHJvZHVjZXIgYW5kIGZvcndhcmRlZCB2ZXJiYXRpbSBvbiBib3RoIHRoZSBkaXJlY3QgYGhvb2tfcmVjZWl2ZWRgIHdyaXRlIGFuZFxuICogdGhlIHF1ZXVlIGBob29rSW5wdXRgLCBzbyBib3RoIHdyaXRlcnMgb2YgdGhlIHNhbWUgYHJlc3VtZUlkYCByZWNvcmQgYW5cbiAqIGlkZW50aWNhbCBkaWdlc3Qgb24gdGhlIHNlcnZlcidzIGAocnVuSWQsIHJlc3VtZUlkKWAgY29uc3RyYWludC4gSGFzaGluZyB0aGVcbiAqIGFscmVhZHktc2VyaWFsaXplZCBieXRlcyAobm90IHRoZSByYXcgdmFsdWUpIGtlZXBzIHByb2R1Y2VyIGFuZCBjb25zdW1lciBpblxuICogbG9ja3N0ZXA6IHRoZSBjb25zdW1lciBmb3J3YXJkcyB0aGlzIHN0cmluZyB3aXRob3V0IHJlY29tcHV0aW5nLlxuICovXG5hc3luYyBmdW5jdGlvbiBjb21wdXRlUmVzdW1lUGF5bG9hZERpZ2VzdChieXRlczogVWludDhBcnJheSk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGRpZ2VzdCA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGlnZXN0KCdTSEEtMjU2JywgYnl0ZXMpO1xuICBjb25zdCB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkoZGlnZXN0KTtcbiAgbGV0IGhleCA9ICcnO1xuICBmb3IgKGNvbnN0IGIgb2Ygdmlldykge1xuICAgIGhleCArPSBiLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCAnMCcpO1xuICB9XG4gIHJldHVybiBoZXg7XG59XG5cbi8qKlxuICogVGhlIHJlc3VtZSBjb250ZXh0IGZvciBhIGhvb2sgcGx1cyB3aGVyZSBpdCBjYW1lIGZyb20uIGBydW5gIGlzIHByZXNlbnQgb25seVxuICogb24gdGhlIGZhbGxiYWNrIHBhdGggKHByZS1gcmVzdW1lQ29udGV4dGAgaG9va3MpLCB3aGVyZSBpdCBhbHNvIGNhcnJpZXMgdGhlXG4gKiBydW4ncyBtdXRhYmxlIHN0YXR1cyBmb3IgdGhlIHRlcm1pbmFsLXJ1biBjaGVjay4gS2V5IHJlc29sdXRpb24gaXMga2VwdFxuICogc2VwYXJhdGUgc28gY2FsbGVycyBjYW4gZ2F0ZSBpdCBiZWhpbmQgdGhhdCBjaGVjay5cbiAqL1xuaW50ZXJmYWNlIEhvb2tSZXN1bWVJbmZvIHtcbiAgcmVzdW1lQ29udGV4dDogSG9va1Jlc3VtZUNvbnRleHQ7XG4gIHNvdXJjZTogJ2hvb2snIHwgJ3J1bl9mYWxsYmFjayc7XG4gIHJ1bj86IFdvcmtmbG93UnVuO1xufVxuXG4vKiogRGVyaXZlIGEgcmVzdW1lIGNvbnRleHQgZnJvbSBhIGZ1bGwgcnVuIChmYWxsYmFjayBmb3IgcHJlLWByZXN1bWVDb250ZXh0YCBob29rcykuICovXG5mdW5jdGlvbiByZXN1bWVDb250ZXh0RnJvbVJ1bihydW46IFdvcmtmbG93UnVuKTogSG9va1Jlc3VtZUNvbnRleHQge1xuICBjb25zdCBjb3JlVmVyc2lvbiA9IHJ1bi5leGVjdXRpb25Db250ZXh0Py53b3JrZmxvd0NvcmVWZXJzaW9uO1xuICBjb25zdCB0cmFjZUNhcnJpZXIgPSBydW4uZXhlY3V0aW9uQ29udGV4dD8udHJhY2VDYXJyaWVyO1xuICBjb25zdCBob29rUmVzdW1lSW5wdXRWZXJzaW9uID0gcnVuLmV4ZWN1dGlvbkNvbnRleHQ/Lmhvb2tSZXN1bWVJbnB1dFZlcnNpb247XG4gIHJldHVybiB7XG4gICAgZGVwbG95bWVudElkOiBydW4uZGVwbG95bWVudElkLFxuICAgIHdvcmtmbG93TmFtZTogcnVuLndvcmtmbG93TmFtZSxcbiAgICBydW5TcGVjVmVyc2lvbjogcnVuLnNwZWNWZXJzaW9uLFxuICAgIHdvcmtmbG93Q29yZVZlcnNpb246XG4gICAgICB0eXBlb2YgY29yZVZlcnNpb24gPT09ICdzdHJpbmcnID8gY29yZVZlcnNpb24gOiB1bmRlZmluZWQsXG4gICAgdHJhY2VDYXJyaWVyOlxuICAgICAgdHJhY2VDYXJyaWVyICYmIHR5cGVvZiB0cmFjZUNhcnJpZXIgPT09ICdvYmplY3QnXG4gICAgICAgID8gKHRyYWNlQ2FycmllciBhcyBIb29rUmVzdW1lQ29udGV4dFsndHJhY2VDYXJyaWVyJ10pXG4gICAgICAgIDogdW5kZWZpbmVkLFxuICAgIGVuY3J5cHRpb25QdWJsaWNLZXk6IHJ1bi5lbmNyeXB0aW9uUHVibGljS2V5LFxuICAgIGhvb2tSZXN1bWVJbnB1dFZlcnNpb246XG4gICAgICB0eXBlb2YgaG9va1Jlc3VtZUlucHV0VmVyc2lvbiA9PT0gJ251bWJlcidcbiAgICAgICAgPyBob29rUmVzdW1lSW5wdXRWZXJzaW9uXG4gICAgICAgIDogdW5kZWZpbmVkLFxuICB9O1xufVxuXG4vKipcbiAqIFJlc29sdmUgcmVzdW1lIGNvbnRleHQgZm9yIGEgaG9vay4gVXNlcyB0aGUgc3RvcmVkIGByZXN1bWVDb250ZXh0YCB3aGVuXG4gKiBwcmVzZW50IChmYXN0IHBhdGgsIG5vIHJ1biByZWFkKTsgb3RoZXJ3aXNlIGZldGNoZXMgdGhlIHJ1biBhbmQgc3ludGhlc2l6ZXNcbiAqIGl0LiBEb2VzIE5PVCByZXNvbHZlIHRoZSBlbmNyeXB0aW9uIGtleTsgY2FsbGVycyBkbyB0aGF0IHNlcGFyYXRlbHkuIE9ubHlcbiAqIHRoZSBmYWxsYmFjayBwYXRoIGNhbiBnYXRlIGtleSB3b3JrIGJlaGluZCBhIGxvY2FsIHRlcm1pbmFsLXJ1biBjaGVjayAoaXRcbiAqIGhhcyB0aGUgZmV0Y2hlZCBydW4pOyB0aGUgZmFzdCBwYXRoJ3Mgc3RvcmVkIGNvbnRleHQgY2FycmllcyBubyBzdGF0dXMsIHNvXG4gKiBzZWFsL3NlcmlhbGl6YXRpb24gd29yayBtYXkgcnVuIGJlZm9yZSB0aGUgcmVjZWl2aW5nIHNpZGUgcmVqZWN0c1xuICogYGhvb2tfcmVjZWl2ZWRgIGZvciBhbiBlbmRlZCBydW4uXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVIb29rUmVzdW1lSW5mbyhob29rOiBIb29rKTogUHJvbWlzZTxIb29rUmVzdW1lSW5mbz4ge1xuICBpZiAoaG9vay5yZXN1bWVDb250ZXh0KSB7XG4gICAgcmV0dXJuIHsgcmVzdW1lQ29udGV4dDogaG9vay5yZXN1bWVDb250ZXh0LCBzb3VyY2U6ICdob29rJyB9O1xuICB9XG4gIGNvbnN0IHJ1biA9IGF3YWl0IChhd2FpdCBnZXRXb3JsZExhenkoKSkucnVucy5nZXQoaG9vay5ydW5JZCk7XG4gIHJldHVybiB7XG4gICAgcmVzdW1lQ29udGV4dDogcmVzdW1lQ29udGV4dEZyb21SdW4ocnVuKSxcbiAgICBzb3VyY2U6ICdydW5fZmFsbGJhY2snLFxuICAgIHJ1bixcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIHRoZSBydW4ncyBzeW1tZXRyaWMga2V5IGZvciBhIHBheWxvYWQgV1JJVEUsIGFzIGEgYmFyZSBgQ3J5cHRvS2V5YFxuICogKGBpbXBvcnRLZXlgKTogdGhlIGBlbmNyYCB3cml0ZSBmYWxsYmFjayB1c2VkIHdoZW4gdGhlIHJ1biBwdWJsaXNoZWQgbm9cbiAqIHB1YmxpYyBrZXkgdG8gc2VhbCB0by4gV3JpdGluZyBuZWVkcyBvbmx5IHRoZSBBRVMga2V5LCBub3QgdGhlIHJlYWQtc2lkZVxuICoga2V5cGFpci4gT24gdGhlIGZhc3QgcGF0aCB0aGlzIG5lZWRzIG9ubHkgYHJ1bklkYCArIGBkZXBsb3ltZW50SWRgIChubyBydW5cbiAqIGVudGl0eSk7IG9uIHRoZSBmYWxsYmFjayBwYXRoIHRoZSBhbHJlYWR5IGZldGNoZWQgcnVuIGlzIHJldXNlZC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUhvb2tFbmNyeXB0aW9uS2V5KFxuICBob29rOiBIb29rLFxuICBpbmZvOiBIb29rUmVzdW1lSW5mb1xuKTogUHJvbWlzZTxBd2FpdGVkPFJldHVyblR5cGU8dHlwZW9mIGltcG9ydEtleT4+IHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IHdvcmxkID0gYXdhaXQgZ2V0V29ybGRMYXp5KCk7XG4gIGNvbnN0IHJhd0tleSA9IGluZm8ucnVuXG4gICAgPyBhd2FpdCB3b3JsZC5nZXRFbmNyeXB0aW9uS2V5Rm9yUnVuPy4oaW5mby5ydW4pXG4gICAgOiBhd2FpdCB3b3JsZC5nZXRFbmNyeXB0aW9uS2V5Rm9yUnVuPy4oaG9vay5ydW5JZCwge1xuICAgICAgICBkZXBsb3ltZW50SWQ6IGluZm8ucmVzdW1lQ29udGV4dC5kZXBsb3ltZW50SWQsXG4gICAgICB9KTtcbiAgcmV0dXJuIHJhd0tleSA/IGF3YWl0IGltcG9ydEtleShyYXdLZXkpIDogdW5kZWZpbmVkO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRIb29rQnlUb2tlbldpdGhLZXkodG9rZW46IHN0cmluZyk6IFByb21pc2U8e1xuICBob29rOiBIb29rO1xuICBlbmNyeXB0aW9uS2V5OiBQYXlsb2FkS2V5IHwgdW5kZWZpbmVkO1xufT4ge1xuICBjb25zdCB3b3JsZCA9IGF3YWl0IGdldFdvcmxkTGF6eSgpO1xuICBjb25zdCBob29rID0gYXdhaXQgd29ybGQuaG9va3MuZ2V0QnlUb2tlbih0b2tlbik7XG5cbiAgLy8gT25seSBhIGhvb2sgdGhhdCBhY3R1YWxseSBjYXJyaWVzIG1ldGFkYXRhIG5lZWRzIHRoZSBydW4ncyBrZXkgcmVzb2x2ZWRcbiAgLy8gaGVyZTogaHlkcmF0aW5nIHRoYXQgbWV0YWRhdGEgaXMgYSBSRUFELCBzbyBkZXJpdmUgdGhlIGZ1bGwgUnVuUGF5bG9hZEtleXNcbiAgLy8gKHdoaWNoIG9wZW5zIHNlYWxlZCBgZW5jcGAgbWV0YWRhdGEsIG5vdCBqdXN0IHN5bW1ldHJpYyBgZW5jcmApLiBUaGUgY29tbW9uXG4gIC8vIGRlZmF1bHQgd2ViaG9vayAoY3JlYXRlV2ViaG9vaygpIHdpdGggbm8gYHJlc3BvbmRXaXRoYCkgc3RvcmVzIG5vXG4gIC8vIG1ldGFkYXRhLCBzbyBpdCBza2lwcyB0aGlzIGVudGlyZWx5OiBubyB+MzUwbXMgYHJ1bi1rZXlgIEFQSSByb3VuZCB0cmlwLFxuICAvLyBhbmQsIGNydWNpYWxseSwgbm8gcmVzb2x2ZWQga2V5IGhhbmRlZCB0byBgcmVzdW1lSG9va2AsIGxlYXZpbmcgaXQgZnJlZSB0b1xuICAvLyBzZWFsIHRoZSBwYXlsb2FkIHRvIHRoZSBydW4ncyBwdWJsaXNoZWQgcHVibGljIGtleSBpbnN0ZWFkLiBNZXRhZGF0YS1cbiAgLy8gYmVhcmluZyB3ZWJob29rcyBzdGlsbCBsZWdpdGltYXRlbHkgcGF5IG9uZSBsb29rdXAgdG8gaHlkcmF0ZS5cbiAgbGV0IGVuY3J5cHRpb25LZXk6IFBheWxvYWRLZXkgfCB1bmRlZmluZWQ7XG4gIGlmICh0eXBlb2YgaG9vay5tZXRhZGF0YSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBjb25zdCBpbmZvID0gYXdhaXQgcmVzb2x2ZUhvb2tSZXN1bWVJbmZvKGhvb2spO1xuICAgIC8vIE9uIHRoZSBmYXN0IHBhdGggdGhpcyByZXNvbHZlcyB0aGUga2V5IGJ5IHJ1bklkICsgZGVwbG95bWVudElkIChubyBydW5cbiAgICAvLyByZWFkKTsgb24gdGhlIGZhbGxiYWNrIHBhdGggaXQgcmV1c2VzIHRoZSBhbHJlYWR5LWZldGNoZWQgcnVuLlxuICAgIGNvbnN0IHJhd0tleSA9IGluZm8ucnVuXG4gICAgICA/IGF3YWl0IHdvcmxkLmdldEVuY3J5cHRpb25LZXlGb3JSdW4/LihpbmZvLnJ1bilcbiAgICAgIDogYXdhaXQgd29ybGQuZ2V0RW5jcnlwdGlvbktleUZvclJ1bj8uKGhvb2sucnVuSWQsIHtcbiAgICAgICAgICBkZXBsb3ltZW50SWQ6IGluZm8ucmVzdW1lQ29udGV4dC5kZXBsb3ltZW50SWQsXG4gICAgICAgIH0pO1xuICAgIGVuY3J5cHRpb25LZXkgPSByYXdLZXkgPyBhd2FpdCBkZXJpdmVSdW5QYXlsb2FkS2V5cyhyYXdLZXkpIDogdW5kZWZpbmVkO1xuICAgIGhvb2subWV0YWRhdGEgPSBhd2FpdCBoeWRyYXRlU3RlcEFyZ3VtZW50cyhcbiAgICAgIGhvb2subWV0YWRhdGEgYXMgYW55LFxuICAgICAgaG9vay5ydW5JZCxcbiAgICAgIGVuY3J5cHRpb25LZXlcbiAgICApO1xuICB9XG4gIHJldHVybiB7IGhvb2ssIGVuY3J5cHRpb25LZXkgfTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIGhvb2sgYnkgdG9rZW4gdG8gZmluZCB0aGUgYXNzb2NpYXRlZCB3b3JrZmxvdyBydW4sXG4gKiBhbmQgaHlkcmF0ZSB0aGUgYG1ldGFkYXRhYCBwcm9wZXJ0eSBpZiBpdCB3YXMgc2V0IGZyb20gd2l0aGluXG4gKiB0aGUgd29ya2Zsb3cgcnVuLlxuICpcbiAqIEEgSG9vayBrZXB0IGJ5IG1pbmltdW0gcmV0ZW50aW9uIHJlbWFpbnMgYXZhaWxhYmxlIGhlcmUgYWZ0ZXIgaXRzIHJ1biBlbmRzLFxuICogYnV0IGNhbm5vdCBiZSByZXN1bWVkLlxuICpcbiAqIEBwYXJhbSB0b2tlbiAtIFRoZSB1bmlxdWUgdG9rZW4gaWRlbnRpZnlpbmcgdGhlIGhvb2tcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldEhvb2tCeVRva2VuKHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPEhvb2s+IHtcbiAgY29uc3QgeyBob29rIH0gPSBhd2FpdCBnZXRIb29rQnlUb2tlbldpdGhLZXkodG9rZW4pO1xuICByZXR1cm4gaG9vaztcbn1cblxuLyoqXG4gKiBUaGUgcmVzdWx0IG9mIHtAbGluayByZXN1bWVIb29rfTogYSB7QGxpbmsgSG9va30gYXVnbWVudGVkIHdpdGggYW4gb3B0aW9uYWxcbiAqIHJlc2lsaWVuY2Ugc2lnbmFsLlxuICpcbiAqIE9uIHRoZSBwYXJhbGxlbCBmYXN0IHBhdGgsIGByZXN1bWVIb29rKClgIHdyaXRlcyB0aGUgYGhvb2tfcmVjZWl2ZWRgIGV2ZW50IGFuZFxuICogZGlzcGF0Y2hlcyB0aGUgd29ya2Zsb3cgcXVldWUgbWVzc2FnZSBjb25jdXJyZW50bHkuIFdoZW4gdGhlIGRpcmVjdCBldmVudFxuICogd3JpdGUgZmFpbHMgKnRyYW5zaWVudGx5KiAoYSA0MjkvNXh4LCBhIHRyYW5zcG9ydCBlcnJvciwgb3IgYW4gZXhwZWN0ZWRcbiAqIGAocnVuSWQsIHJlc3VtZUlkKWAgY29uZmxpY3Qgd2l0aCBpdHMgb3duIHJlLWVuc3VyaW5nIGNvbnN1bWVyKSBidXQgdGhlIHF1ZXVlXG4gKiBkaXNwYXRjaCBzdWNjZWVkcywgdGhlIHJlc3VtZSBpcyBzdGlsbCBndWFyYW50ZWVkOiB0aGUgcXVldWUgY29uc3VtZXJcbiAqIGlkZW1wb3RlbnRseSBtYXRlcmlhbGl6ZXMgdGhlIGBob29rX3JlY2VpdmVkYCBldmVudCBmcm9tIHRoZSBwYXlsb2FkIGNhcnJpZWRcbiAqIG9uIHRoZSBtZXNzYWdlIGJlZm9yZSByZXBsYXkuIEluIHRoYXQgcmVjb3ZlcmVkIGNhc2UgdGhlIHJldHVybmVkIGhvb2sgY2Fycmllc1xuICogYHJlc2lsaWVudFJlc3VtZTogdHJ1ZWAuXG4gKlxuICogT24gdGhlIGhhcHB5IHBhdGggKHRoZSBkaXJlY3Qgd3JpdGUgbGFuZGVkKSBhbmQgb24gdGhlIHNlcXVlbnRpYWwgZmFsbGJhY2tcbiAqIHBhdGgsIHRoZSBmbGFnIGlzIGFic2VudCAoYHVuZGVmaW5lZGApLiBDYWxsZXJzIHRoYXQgZG9uJ3QgY2FyZSBhYm91dCB0aGVcbiAqIGRpc3RpbmN0aW9uIGNhbiB0cmVhdCB0aGUgcmVzdWx0IGFzIGEgcGxhaW4ge0BsaW5rIEhvb2t9LlxuICovXG5leHBvcnQgdHlwZSBSZXN1bWVkSG9vayA9IEhvb2sgJiB7IHJlc2lsaWVudFJlc3VtZT86IGJvb2xlYW4gfTtcblxuLyoqXG4gKiBSZXN1bWVzIGEgd29ya2Zsb3cgcnVuIGJ5IHNlbmRpbmcgYSBwYXlsb2FkIHRvIGEgaG9vayBpZGVudGlmaWVkIGJ5IGl0cyB0b2tlbi5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBleHRlcm5hbGx5IChlLmcuLCBmcm9tIGFuIEFQSSByb3V0ZSBvciBzZXJ2ZXIgYWN0aW9uKVxuICogdG8gc2VuZCBkYXRhIHRvIGEgaG9vayBhbmQgcmVzdW1lIHRoZSBhc3NvY2lhdGVkIHdvcmtmbG93IHJ1bi5cbiAqXG4gKiBAcGFyYW0gdG9rZW5Pckhvb2sgLSBUaGUgdW5pcXVlIHRva2VuIGlkZW50aWZ5aW5nIHRoZSBob29rLCBvciB0aGUgaG9vayBvYmplY3QgaXRzZWxmXG4gKiBAcGFyYW0gcGF5bG9hZCAtIFRoZSBkYXRhIHBheWxvYWQgdG8gc2VuZCB0byB0aGUgaG9va1xuICogQHJldHVybnMgUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIHtAbGluayBSZXN1bWVkSG9va31cbiAqIEB0aHJvd3Mge0hvb2tOb3RGb3VuZEVycm9yfSBJZiB0aGUgSG9vayBkb2VzIG5vdCBleGlzdCBvciBpdHMgcnVuIGhhcyBlbmRlZFxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogYGBgdHNcbiAqIC8vIEluIGFuIEFQSSByb3V0ZVxuICogaW1wb3J0IHsgcmVzdW1lSG9vayB9IGZyb20gJ0B3b3JrZmxvdy9jb3JlL3J1bnRpbWUnO1xuICpcbiAqIGV4cG9ydCBhc3luYyBmdW5jdGlvbiBQT1NUKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAqICAgY29uc3QgeyB0b2tlbiwgZGF0YSB9ID0gYXdhaXQgcmVxdWVzdC5qc29uKCk7XG4gKlxuICogICB0cnkge1xuICogICAgIGNvbnN0IGhvb2sgPSBhd2FpdCByZXN1bWVIb29rKHRva2VuLCBkYXRhKTtcbiAqICAgICByZXR1cm4gUmVzcG9uc2UuanNvbih7IHJ1bklkOiBob29rLnJ1bklkIH0pO1xuICogICB9IGNhdGNoIChlcnJvcikge1xuICogICAgIHJldHVybiBuZXcgUmVzcG9uc2UoJ0hvb2sgbm90IGZvdW5kJywgeyBzdGF0dXM6IDQwNCB9KTtcbiAqICAgfVxuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXN1bWVIb29rPFQgPSBhbnk+KFxuICB0b2tlbk9ySG9vazogc3RyaW5nIHwgSG9vayxcbiAgcGF5bG9hZDogVCxcbiAgZW5jcnlwdGlvbktleU92ZXJyaWRlPzogUGF5bG9hZEtleVxuKTogUHJvbWlzZTxSZXN1bWVkSG9vaz4ge1xuICAvLyBQdWJsaWMgZW50cnkgcG9pbnQuIEl0IG5ldmVyIGF0dGVzdHMgaG9vayBmcmVzaG5lc3MsIHNvIGEgSG9vayBvYmplY3RcbiAgLy8gc3VwcGxpZWQgaGVyZSAod2hpY2ggbWF5IGNhcnJ5IGEgYHJlc3VtZUNhcGFiaWxpdGllc2AgY2FjaGVkIGJlZm9yZSBhXG4gIC8vIHNlcnZlciByb2xsYmFjayBvciBraWxsIHN3aXRjaCkgaXMgaWdub3JlZCBieSB0aGUgZHluYW1pYy1kZWR1cCBnYXRlIGFuZFxuICAvLyBmYWlscyBjbG9zZWQgdG8gdGhlIHNlcXVlbnRpYWwgcGF0aC4gT25seSBgcmVzdW1lV2ViaG9va2AsIHdoaWNoIGZldGNoZXNcbiAgLy8gdGhlIGhvb2sgYnkgdG9rZW4gaW4tbGluZSBkdXJpbmcgdGhlIHNhbWUgcmVzdW1lLCByZWFjaGVzIHRoZSBpbnRlcm5hbFxuICAvLyBpbXBsZW1lbnRhdGlvbiB3aXRoIHRoZSBmcmVzaCBhdHRlc3RhdGlvbiBzZXQuIEtlZXBpbmcgdGhlIGZyZXNobmVzcyBmbGFnXG4gIC8vIG9mZiB0aGUgZXhwb3J0ZWQgc2lnbmF0dXJlIHByZXZlbnRzIGEgY2FsbGVyIGZyb20gcGFzc2luZyBhIHN0YWxlIEhvb2sgcGx1c1xuICAvLyBgdHJ1ZWAgYW5kIHJlYWN0aXZhdGluZyBkeW5hbWljIGRlZHVwIGFnYWluc3QgYSByb2xsZWQtYmFjayBiYWNrZW5kLlxuICAvL1xuICAvLyBUMCBvZiB0aGUgaG9vay1yZXN1bWUgVFRSIHdpbmRvdyBpcyB0YWtlbiBIRVJFLCBhdCB0aGUgcHVibGljIGVudHJ5IHBvaW50LFxuICAvLyByYXRoZXIgdGhhbiBpbnNpZGUgdGhlIGltcGxlbWVudGF0aW9uOyBzZWUgdGhlIHBhcmFtZXRlcidzIGRvYyBjb21tZW50LlxuICByZXR1cm4gcmVzdW1lSG9va0ltcGwoXG4gICAgdG9rZW5Pckhvb2ssXG4gICAgcGF5bG9hZCxcbiAgICBlbmNyeXB0aW9uS2V5T3ZlcnJpZGUsXG4gICAgZmFsc2UsXG4gICAgRGF0ZS5ub3coKVxuICApO1xufVxuXG4vKipcbiAqIEludGVybmFsIGltcGxlbWVudGF0aW9uIG9mIHtAbGluayByZXN1bWVIb29rfS4gTk9UIGV4cG9ydGVkOiB0aGVcbiAqIGBob29rRnJlc2hseUxvb2tlZFVwYCBhdHRlc3RhdGlvbiBtdXN0IG5ldmVyIGJlIHJlYWNoYWJsZSBieSBwdWJsaWMgY2FsbGVyc1xuICogKHNlZSB0aGUgd3JhcHBlciBhYm92ZSkuXG4gKlxuICogQHBhcmFtIGhvb2tGcmVzaGx5TG9va2VkVXAgLSBBdHRlc3RzIHRoYXQgYSBzdXBwbGllZCBIb29rIG9iamVjdCB3YXMgZmV0Y2hlZFxuICogICBieSB0b2tlbiBkdXJpbmcgVEhJUyByZXN1bWUsIHNvIGl0cyByZXNwb25zZS1vbmx5IGByZXN1bWVDYXBhYmlsaXRpZXNgXG4gKiAgIHJlZmxlY3RzIHRoZSBsaXZlIGJhY2tlbmQgYW5kIG1heSBiZSB0cnVzdGVkIGZvciB0aGUgZHluYW1pYy1kZWR1cCBnYXRlLlxuICogICBBIHRva2VuIHN0cmluZyBpcyBhbHdheXMgZmV0Y2hlZCBmcmVzaCBoZXJlLCBzbyBpdCBpcyBpbXBsaWNpdGx5IGZyZXNoLlxuICogQHBhcmFtIHJlc3VtZVJlcXVlc3RlZEF0TXMgLSBUMCBvZiB0aGUgaG9vay1yZXN1bWUgVFRSIHdpbmRvdyAoc2VlXG4gKiAgIHJ1bnRpbWUvcmVzdW1lLWxhdGVuY3kudHMpLCBzdGFtcGVkIGJ5IHRoZSBQVUJMSUMgZW50cnkgcG9pbnQgdGhlIGNhbGxlclxuICogICB1c2VkLiBJdCBpcyBhIHBhcmFtZXRlciByYXRoZXIgdGhhbiBhIGxvY2FsIGJlY2F1c2UgYHJlc3VtZVdlYmhvb2tgIGRvZXNcbiAqICAgcmVhbCB3b3JrIGJlZm9yZSBpdCBnZXRzIGhlcmUgKHRoZSBieS10b2tlbiBsb29rdXAsIHRoZSBydW4ta2V5XG4gKiAgIHJlc29sdXRpb24gdGhhdCBoeWRyYXRlcyBob29rIG1ldGFkYXRhLCBhbmQgdGhlIGByZXNwb25kV2l0aGAgc2V0dXApIGFuZFxuICogICBzdGFtcGluZyBsb2NhbGx5IHdvdWxkIHNpbGVudGx5IGV4Y2x1ZGUgYWxsIG9mIGl0LCBzbyB0aGUgdHdvIGVudHJ5IHBvaW50c1xuICogICB3b3VsZCByZXBvcnQgdGhlIHNhbWUgbWV0cmljIG92ZXIgZGlmZmVyZW50IHdpbmRvd3MuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc3VtZUhvb2tJbXBsPFQgPSBhbnk+KFxuICB0b2tlbk9ySG9vazogc3RyaW5nIHwgSG9vayxcbiAgcGF5bG9hZDogVCxcbiAgZW5jcnlwdGlvbktleU92ZXJyaWRlOiBQYXlsb2FkS2V5IHwgdW5kZWZpbmVkLFxuICBob29rRnJlc2hseUxvb2tlZFVwOiBib29sZWFuLFxuICByZXN1bWVSZXF1ZXN0ZWRBdE1zOiBudW1iZXJcbik6IFByb21pc2U8UmVzdW1lZEhvb2s+IHtcbiAgcmV0dXJuIGF3YWl0IHdhaXRlZFVudGlsKCgpID0+IHtcbiAgICByZXR1cm4gdHJhY2UoJ2hvb2sucmVzdW1lJywgYXN5bmMgKHNwYW4pID0+IHtcbiAgICAgIGNvbnN0IHdvcmxkID0gYXdhaXQgZ2V0V29ybGRMYXp5KCk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHN1cHBsaWVkVG9rZW4gPSB0eXBlb2YgdG9rZW5Pckhvb2sgPT09ICdzdHJpbmcnO1xuICAgICAgICBjb25zdCBob29rOiBIb29rID0gc3VwcGxpZWRUb2tlblxuICAgICAgICAgID8gYXdhaXQgd29ybGQuaG9va3MuZ2V0QnlUb2tlbih0b2tlbk9ySG9vaylcbiAgICAgICAgICA6IHRva2VuT3JIb29rO1xuICAgICAgICAvLyBUaGUgZHluYW1pYywgcmVzcG9uc2Utb25seSBgcmVzdW1lQ2FwYWJpbGl0aWVzYCBtYXkgb25seSBiZSB0cnVzdGVkXG4gICAgICAgIC8vIHdoZW4gaXQgY2FtZSBmcm9tIGEgYnktdG9rZW4gbG9va3VwIHBlcmZvcm1lZCBkdXJpbmcgdGhpcyByZXN1bWUuXG4gICAgICAgIGNvbnN0IGhvb2tSZXN1bWVDYXBhYmlsaXRpZXNBcmVGcmVzaCA9XG4gICAgICAgICAgc3VwcGxpZWRUb2tlbiB8fCBob29rRnJlc2hseUxvb2tlZFVwO1xuXG4gICAgICAgIGNvbnN0IGluZm8gPSBhd2FpdCByZXNvbHZlSG9va1Jlc3VtZUluZm8oaG9vayk7XG4gICAgICAgIGNvbnN0IHsgcmVzdW1lQ29udGV4dCB9ID0gaW5mbztcblxuICAgICAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgICAgICAuLi5BdHRyaWJ1dGUuSG9va1Rva2VuKGhvb2sudG9rZW4pLFxuICAgICAgICAgIC4uLkF0dHJpYnV0ZS5Ib29rSWQoaG9vay5ob29rSWQpLFxuICAgICAgICAgIC4uLkF0dHJpYnV0ZS5Xb3JrZmxvd1J1bklkKGhvb2sucnVuSWQpLFxuICAgICAgICAgICd3b3JrZmxvdy5ob29rLnJlc3VtZV9jb250ZXh0X3NvdXJjZSc6IGluZm8uc291cmNlLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBUaGUgc3RvcmVkIGByZXN1bWVDb250ZXh0YCBpbnRlbnRpb25hbGx5IG9taXRzIHRoZSBydW4ncyBtdXRhYmxlXG4gICAgICAgIC8vIHN0YXR1cywgc28gdGhpcyBlYXJseSBjbGllbnQtc2lkZSByZWplY3Rpb24gb25seSBydW5zIG9uIHRoZVxuICAgICAgICAvLyBmYWxsYmFjayBwYXRoICh3aGljaCBmZXRjaGVkIHRoZSBydW4pLiBPbiB0aGUgZmFzdCBwYXRoIHRoZSB0ZXJtaW5hbFxuICAgICAgICAvLyBjaGVjayBoYXBwZW5zIHNlcnZlci1zaWRlOiBgaG9va19yZWNlaXZlZGAgYWdhaW5zdCBhbiBlbmRlZCBydW4gaXNcbiAgICAgICAgLy8gcmVqZWN0ZWQsIHdoaWNoIHRoZSBjYXRjaCBhcm91bmQgYHdvcmxkLmV2ZW50cy5jcmVhdGVgIGJlbG93IHJlLWtleXNcbiAgICAgICAgLy8gdG8gSG9va05vdEZvdW5kRXJyb3I6IHNhbWUgcHVibGljIGNvbnRyYWN0LCBubyBydW4gcHJlLWZldGNoLlxuICAgICAgICBpZiAoaW5mby5ydW4gJiYgaXNUZXJtaW5hbFdvcmtmbG93UnVuU3RhdHVzKGluZm8ucnVuLnN0YXR1cykpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgSG9va05vdEZvdW5kRXJyb3IoaG9vay50b2tlbik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDaGVjayB0aGUgdGFyZ2V0IHJ1bidzIGNhcGFiaWxpdGllcyB0byBlbnN1cmUgd2UgZW5jb2RlIHRoZVxuICAgICAgICAvLyBwYXlsb2FkIGluIGEgZm9ybWF0IHRoZSBydW4ncyBkZXBsb3ltZW50IGNhbiBkZWNvZGUuIEZvciBleGFtcGxlLFxuICAgICAgICAvLyBydW5zIGNyZWF0ZWQgYmVmb3JlIGVuY3J5cHRpb24gc3VwcG9ydCB3YXMgYWRkZWQgY2Fubm90IGRlY29kZVxuICAgICAgICAvLyB0aGUgJ2VuY3InIHNlcmlhbGl6YXRpb24gZm9ybWF0LCBhbmQgcnVucyBjcmVhdGVkIGJlZm9yZVxuICAgICAgICAvLyBieXRlLXN0cmVhbSBmcmFtaW5nIHN1cHBvcnQgY2Fubm90IGRlY29kZSBmcmFtZWQgYnl0ZSBzdHJlYW1zLlxuICAgICAgICBjb25zdCBjYXBhYmlsaXRpZXMgPSBnZXRSdW5DYXBhYmlsaXRpZXMoXG4gICAgICAgICAgcmVzdW1lQ29udGV4dC53b3JrZmxvd0NvcmVWZXJzaW9uXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gUmVzb2x2ZSBob3cgdG8gZW5jcnlwdCB0aGUgcGF5bG9hZCBmb3IgdGhlIHRhcmdldCBydW4gKGEgV1JJVEUpLlxuICAgICAgICAvL1xuICAgICAgICAvLyBQcmVmZXJyZWQgcGF0aDogc2VhbCB0byB0aGUgcnVuJ3MgcHVibGlzaGVkIFgyNTUxOSBwdWJsaWMga2V5LCB3aGljaFxuICAgICAgICAvLyB0aGUgc3RvcmVkIGByZXN1bWVDb250ZXh0YCBjYXJyaWVzIGlubGluZS4gT24gdGhlIGZhc3QgcGF0aCB0aGlzIGlzXG4gICAgICAgIC8vIHRoZSB3aG9sZSB3aW46IG5vIHJ1biByZWFkIEFORCBubyBgZ2V0RW5jcnlwdGlvbktleUZvclJ1bmAsIHdob3NlXG4gICAgICAgIC8vIH4zNTBtcyBgcnVuLWtleWAgQVBJIHJvdW5kIHRyaXAgZG9taW5hdGVzIGNyb3NzLWRlcGxveW1lbnQgaG9va1xuICAgICAgICAvLyByZXN1bXB0aW9uIGxhdGVuY3kuIChPbiB0aGUgZmFsbGJhY2sgcGF0aCB0aGUga2V5IGlzIHN5bnRoZXNpemVkXG4gICAgICAgIC8vIGZyb20gdGhlIGZldGNoZWQgcnVuLCB3aGljaCBhbHNvIGNhcnJpZXMgaXQuKVxuICAgICAgICAvL1xuICAgICAgICAvLyBTZWFsaW5nIGFsc28gZHJvcHMgcHJpdmlsZWdlOiB0aGUgcmVzdW1lciBlbmRzIHVwIGFibGUgdG8gd3JpdGUgYVxuICAgICAgICAvLyBwYXlsb2FkIGZvciB0aGUgcnVuIHdpdGhvdXQgYmVpbmcgYWJsZSB0byByZWFkIGFueXRoaW5nIG9mIHRoZVxuICAgICAgICAvLyBydW4ncywgd2hlcmUgZmV0Y2hpbmcgdGhlIHN5bW1ldHJpYyBrZXkgZ3JhbnRzIGJvdGguXG4gICAgICAgIC8vXG4gICAgICAgIC8vIERlbGliZXJhdGVseSBOT1QgZ2F0ZWQgb24gYGNhcGFiaWxpdGllcy5zdXBwb3J0ZWRGb3JtYXRzYCB0aGUgd2F5XG4gICAgICAgIC8vIHRoZSBzeW1tZXRyaWMgZmFsbGJhY2sgYmVsb3cgZ2F0ZXMgYGVuY3JgOiBwcmVzZW5jZSBvZiB0aGUgcHVibGljIGtleVxuICAgICAgICAvLyBpcyBpdHNlbGYgdGhlIGdhdGUuIEEgcnVuIG9ubHkgY2FycmllcyBvbmUgaWYgdGhlIHJ1bnRpbWUgdGhhdFxuICAgICAgICAvLyBjcmVhdGVkIGl0IGNvdWxkIGFsc28gb3BlbiBhIHNlYWxlZCBwYXlsb2FkLCBhbmQgcnVucyBhcmUgcGlubmVkIHRvXG4gICAgICAgIC8vIHRoZWlyIGNyZWF0aW5nIGRlcGxveW1lbnQsIHNvIHByZXNlbmNlIGlzIGEgbW9yZSByZWxpYWJsZSBhdHRlc3RhdGlvblxuICAgICAgICAvLyB0aGFuIGEgdmVyc2lvbiBjb21wYXJlLCBhbmQgaXQgc3RheXMgY29ycmVjdCBldmVuIHdoZW4gcGFja2FnZVxuICAgICAgICAvLyB2ZXJzaW9ucyBkcmlmdC5cbiAgICAgICAgbGV0IHBheWxvYWRLZXk6IFBheWxvYWRLZXkgfCB1bmRlZmluZWQ7XG4gICAgICAgIGNvbnN0IHJ1blB1YmxpY0tleSA9IGVuY3J5cHRpb25LZXlPdmVycmlkZVxuICAgICAgICAgID8gLy8gVGhlIGNhbGxlciBhbHJlYWR5IGhvbGRzIGEga2V5IChyZXN1bWVXZWJob29rIHJlc29sdmVkIG9uZSB0b1xuICAgICAgICAgICAgLy8gaHlkcmF0ZSBob29rIG1ldGFkYXRhKSwgc28gc2VhbGluZyB3b3VsZCBhZGQgYW4gRUNESCBmb3Igbm9cbiAgICAgICAgICAgIC8vIHNhdmVkIHJvdW5kIHRyaXAuIFJldXNlIHdoYXQgaXQgcmVzb2x2ZWQuXG4gICAgICAgICAgICB1bmRlZmluZWRcbiAgICAgICAgICA6IGRlY29kZVJ1blB1YmxpY0tleShyZXN1bWVDb250ZXh0LmVuY3J5cHRpb25QdWJsaWNLZXkpO1xuXG4gICAgICAgIGlmIChydW5QdWJsaWNLZXkpIHtcbiAgICAgICAgICBwYXlsb2FkS2V5ID0gc2VhbFRvKHJ1blB1YmxpY0tleSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gU3ltbWV0cmljIGBlbmNyYCB3cml0ZSBmYWxsYmFjazogbmVlZHMgb25seSB0aGUgQUVTIGtleVxuICAgICAgICAgIC8vIChhIGJhcmUgQ3J5cHRvS2V5IHZpYSBgcmVzb2x2ZUhvb2tFbmNyeXB0aW9uS2V5YCksIG5vdCB0aGVcbiAgICAgICAgICAvLyByZWFkLXNpZGUgUnVuUGF5bG9hZEtleXMuXG4gICAgICAgICAgbGV0IGVuY3J5cHRpb25LZXkgPVxuICAgICAgICAgICAgZW5jcnlwdGlvbktleU92ZXJyaWRlID8/XG4gICAgICAgICAgICAoYXdhaXQgcmVzb2x2ZUhvb2tFbmNyeXB0aW9uS2V5KGhvb2ssIGluZm8pKTtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhY2FwYWJpbGl0aWVzLnN1cHBvcnRlZEZvcm1hdHMuaGFzKFNlcmlhbGl6YXRpb25Gb3JtYXQuRU5DUllQVEVEKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgZW5jcnlwdGlvbktleSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcGF5bG9hZEtleSA9IGVuY3J5cHRpb25LZXk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDb21wcmVzcyBvbmx5IHdoZW4gdGhlIHRhcmdldCBydW4gYW5kIGl0cyBkZXBsb3ltZW50IHN1cHBvcnQgdGhlXG4gICAgICAgIC8vIGNvbXByZXNzaW9uIGZvcm1hdHMgaW50cm9kdWNlZCB3aXRoIHNwZWMgdmVyc2lvbiA1LlxuICAgICAgICBjb25zdCBjb21wcmVzc2lvbiA9XG4gICAgICAgICAgKHJlc3VtZUNvbnRleHQucnVuU3BlY1ZlcnNpb24gPz8gMCkgPj1cbiAgICAgICAgICAgIFNQRUNfVkVSU0lPTl9TVVBQT1JUU19DT01QUkVTU0lPTiAmJlxuICAgICAgICAgIGNhcGFiaWxpdGllcy5zdXBwb3J0ZWRGb3JtYXRzLmhhcyhTZXJpYWxpemF0aW9uRm9ybWF0LkdaSVApO1xuXG4gICAgICAgIC8vIERlaHlkcmF0ZSB0aGUgcGF5bG9hZCBmb3Igc3RvcmFnZVxuICAgICAgICBjb25zdCBvcHM6IFByb21pc2U8YW55PltdID0gW107XG4gICAgICAgIGNvbnN0IHYxQ29tcGF0ID0gaXNMZWdhY3lTcGVjVmVyc2lvbihob29rLnNwZWNWZXJzaW9uKTtcbiAgICAgICAgY29uc3QgZGVoeWRyYXRlZFBheWxvYWQgPSBhd2FpdCBkZWh5ZHJhdGVTdGVwUmV0dXJuVmFsdWUoXG4gICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgICBob29rLnJ1bklkLFxuICAgICAgICAgIHBheWxvYWRLZXksXG4gICAgICAgICAgb3BzLFxuICAgICAgICAgIGdsb2JhbFRoaXMsXG4gICAgICAgICAgdjFDb21wYXQsXG4gICAgICAgICAgY2FwYWJpbGl0aWVzLmZyYW1lZEJ5dGVTdHJlYW1zLFxuICAgICAgICAgIGNvbXByZXNzaW9uXG4gICAgICAgICk7XG4gICAgICAgIC8vIFRoZXNlIHBheWxvYWQtc3RyZWFtIG9wcyBhcmUgZmx1c2hlZCBpbiB0aGUgYmFja2dyb3VuZDsgdGhlXG4gICAgICAgIC8vIHByb21pc2UgaGFuZGVkIHRvIHdhaXRVbnRpbCBtdXN0IG5ldmVyIHJlamVjdCAoYW4gdW5jb25zdW1lZFxuICAgICAgICAvLyB3YWl0VW50aWwgcmVqZWN0aW9uIGNyYXNoZXMgdGhlIHByb2Nlc3MgYXMgdW5oYW5kbGVkUmVqZWN0aW9uKSxcbiAgICAgICAgLy8gc28gdW5leHBlY3RlZCBmYWlsdXJlcyBhcmUgbG9nZ2VkIGluc3RlYWQuXG4gICAgICAgIC8vIE5PVEU6IHJlamVjdGlvbnMgd2l0aCBgdW5kZWZpbmVkYCBhcmUgYW4gZXhwZWN0ZWQgYXJ0aWZhY3Qgb2YgdGhlXG4gICAgICAgIC8vIHdlYmhvb2sgYnVuZGxlIGFuZCBhcmUgaWdub3JlZCBlbnRpcmVseS5cbiAgICAgICAgc2FmZVdhaXRVbnRpbChQcm9taXNlLmFsbChvcHMpLCAoZXJyKSA9PiB7XG4gICAgICAgICAgaWYgKGVyciA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgICAgICAgcnVudGltZUxvZ2dlci53YXJuKCdCYWNrZ3JvdW5kIGZsdXNoIG9mIGhvb2sgcGF5bG9hZCBvcHMgZmFpbGVkJywge1xuICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogaG9vay5ydW5JZCxcbiAgICAgICAgICAgIGhvb2tJZDogaG9vay5ob29rSWQsXG4gICAgICAgICAgICBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dOYW1lKHJlc3VtZUNvbnRleHQud29ya2Zsb3dOYW1lKSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTGluayB0byB0aGUgcnVuLW9yaWdpbiBjb250ZXh0IGZyb20gdGhlIHN0b3JlZCB0cmFjZSBjYXJyaWVyXG4gICAgICAgIC8vIChza2lwcGVkIHdoZW4gYWJzZW50IG9yIGludmFsaWQpLiBSZXNvbHZlZCBiZWZvcmUgZGlzcGF0Y2ggc28gYm90aFxuICAgICAgICAvLyB0aGUgc2VxdWVudGlhbCBhbmQgcGFyYWxsZWwgcGF0aHMgYXR0YWNoIGl0LlxuICAgICAgICBjb25zdCBvcmlnaW5MaW5rID0gYXdhaXQgbGlua1RvVHJhY2VDYXJyaWVyKHJlc3VtZUNvbnRleHQudHJhY2VDYXJyaWVyKTtcbiAgICAgICAgaWYgKG9yaWdpbkxpbmspIHtcbiAgICAgICAgICBzcGFuPy5hZGRMaW5rPy4ob3JpZ2luTGluayk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBldmVudERhdGEgPSB7XG4gICAgICAgICAgLi4uKHYxQ29tcGF0ID8ge30gOiB7IHRva2VuOiBob29rLnRva2VuIH0pLFxuICAgICAgICAgIHBheWxvYWQ6IGRlaHlkcmF0ZWRQYXlsb2FkLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHF1ZXVlTmFtZSA9IGdldFdvcmtmbG93UXVldWVOYW1lKHJlc3VtZUNvbnRleHQud29ya2Zsb3dOYW1lKTtcbiAgICAgICAgY29uc3QgcXVldWVPcHRpb25zID0ge1xuICAgICAgICAgIGRlcGxveW1lbnRJZDogcmVzdW1lQ29udGV4dC5kZXBsb3ltZW50SWQsXG4gICAgICAgICAgc3BlY1ZlcnNpb246IHJlc3VtZUNvbnRleHQucnVuU3BlY1ZlcnNpb24gPz8gU1BFQ19WRVJTSU9OX0xFR0FDWSxcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBEZWNpZGUgd2hldGhlciB0byBwYXJhbGxlbGl6ZSB0aGUgYGhvb2tfcmVjZWl2ZWRgIHdyaXRlIGFuZCB0aGUgcXVldWVcbiAgICAgICAgLy8gcHVibGlzaC4gVGhlIGZhc3QgcGF0aCBpcyBvbmx5IHNhZmUgd2hlbiBFVkVSWSBwcmVjb25kaXRpb24gaG9sZHM7IHRoZVxuICAgICAgICAvLyBmaXJzdCB0aGF0IGZhaWxzIG5hbWVzIHRoZSBmYWxsYmFjayByZWFzb24gKGVtaXR0ZWQgYXMgYSBzcGFuXG4gICAgICAgIC8vIGF0dHJpYnV0ZSBmb3Igb2JzZXJ2YWJpbGl0eSwgYW5kIHRvIG1ha2UgXCJ3aHkgZGlkIHRoaXMgcnVuIHNlcXVlbnRpYWxcIlxuICAgICAgICAvLyBhbnN3ZXJhYmxlIGluIHByb2R1Y3Rpb24pLiBBbGwgY29uZGl0aW9uczpcbiAgICAgICAgLy9cbiAgICAgICAgLy8gIC0ga2lsbCBzd2l0Y2g6IGBXT1JLRkxPV19ESVNBQkxFX0xBWllfSE9PS19SRVNVTUVgIGZvcmNlcyBzZXF1ZW50aWFsXG4gICAgICAgIC8vICAgIGlmIHRoZSBmYXN0IHBhdGggZXZlciBtaXNiZWhhdmVzLiBJdCBpcyBhbiBTREstZGVwbG95bWVudCBlbnYgdmFyLFxuICAgICAgICAvLyAgICBzbyBjaGFuZ2luZyBpdCBnZW5lcmFsbHkgcmVxdWlyZXMgcmVkZXBsb3lpbmcgdGhlIHdvcmtmbG93XG4gICAgICAgIC8vICAgIGRlcGxveW1lbnQuIChUaGUgYmFja2VuZCBjYW4gaW5kZXBlbmRlbnRseSBkcm9wIG5ldyByZXN1bWVzIHRvIHRoZVxuICAgICAgICAvLyAgICBzZXF1ZW50aWFsIHBhdGggZmxlZXQtd2lkZSBieSBjZWFzaW5nIHRvIGF0dGVzdCBkZWR1cCBzdXBwb3J0IG9uXG4gICAgICAgIC8vICAgIHRoZSBieS10b2tlbiBsb29rdXA7IHNlZSB0aGUgYmFja2VuZC1kZWR1cCBjb25kaXRpb24gYmVsb3cuKVxuICAgICAgICAvLyAgLSBiYWNrZW5kIGRlZHVwOiB0aGUgbGl2ZSBiYWNrZW5kIG11c3QgZW5mb3JjZSB0aGVcbiAgICAgICAgLy8gICAgYChydW5JZCwgcmVzdW1lSWQpYCBjb25zdHJhaW50LCBvciB0aGUgdHdvIHdyaXRlcnMgd291bGQgY29tbWl0IHR3b1xuICAgICAgICAvLyAgICBgaG9va19yZWNlaXZlZGAgZXZlbnRzLiBGYWlsIGNsb3NlZC4gQXR0ZXN0ZWQgYnkgRUlUSEVSIGEgZnJlc2gsXG4gICAgICAgIC8vICAgIHJlc3BvbnNlLW9ubHkgYGhvb2sucmVzdW1lQ2FwYWJpbGl0aWVzLmhvb2tSZXN1bWVEZWR1cFZlcnNpb25gIGZyb21cbiAgICAgICAgLy8gICAgdGhlIGJ5LXRva2VuIGxvb2t1cCAod29ybGQtdmVyY2VsOiByZWNvbXB1dGVkIGV2ZXJ5IHJlYWQsIHNvIGFcbiAgICAgICAgLy8gICAgc2VydmVyIHJvbGxiYWNrIG9yIGtpbGwgc3dpdGNoIGRyb3BzIHRvIHNlcXVlbnRpYWwgaW1tZWRpYXRlbHkpIE9SXG4gICAgICAgIC8vICAgIHRoZSBzdGF0aWMgYHdvcmxkLmNhcGFiaWxpdGllcy5ob29rUmVzdW1lRGVkdXBgICh3b3JsZC1sb2NhbCwgd2hvc2VcbiAgICAgICAgLy8gICAgYWRhcHRlciBhbmQgYmFja2VuZCBzaGlwIHRvZ2V0aGVyKS4gVGhlIHJlc3BvbnNlLW9ubHkgY2FwYWJpbGl0eSBpc1xuICAgICAgICAvLyAgICB0cnVzdGVkIE9OTFkgd2hlbiB0aGUgaG9vayB3YXMgbG9va2VkIHVwIGJ5IHRva2VuIGR1cmluZyB0aGlzXG4gICAgICAgIC8vICAgIHJlc3VtZSAoYGhvb2tSZXN1bWVDYXBhYmlsaXRpZXNBcmVGcmVzaGApOyBhIEhvb2sgb2JqZWN0IGhhbmRlZCBpblxuICAgICAgICAvLyAgICBieSBhIHB1YmxpYyBjYWxsZXIgbWF5IGNhcnJ5IGEgY2FwYWJpbGl0eSBjYWNoZWQgYmVmb3JlIGEgcm9sbGJhY2ssXG4gICAgICAgIC8vICAgIHNvIGl0IGlzIGlnbm9yZWQgYW5kIHRoZSBwYXRoIGZhbGxzIGJhY2sgdG8gc2VxdWVudGlhbC5cbiAgICAgICAgLy8gIC0gY29uc3VtZXIgc3VwcG9ydDogdGhlIHRhcmdldCBydW4ncyBkZXBsb3ltZW50IG11c3QgcmUtZW5zdXJlIHRoZVxuICAgICAgICAvLyAgICBldmVudCBmcm9tIGBob29rSW5wdXRgIG9uIHJlcGxheS4gQXR0ZXN0ZWQgYnkgdGhlIHJ1bidzIGV4cGxpY2l0XG4gICAgICAgIC8vICAgIGBob29rUmVzdW1lSW5wdXRWZXJzaW9uYCBleGVjdXRpb24tY29udGV4dCBtYXJrZXIgKG1pcnJvcmVkIG9udG9cbiAgICAgICAgLy8gICAgcmVzdW1lQ29udGV4dCksIE5PVCBhIHZlcnNpb24tY29tcGFyZSBhZ2FpbnN0IGEgcHJlZGljdGVkIHJlbGVhc2VcbiAgICAgICAgLy8gICAgY3V0b2ZmLiBBYnNlbnQg4oaSIGEgbG9zdCBwcm9kdWNlciB3cml0ZSB3b3VsZCBiZSBhIGxvc3QgcmVzdW1lLlxuICAgICAgICAvLyAgLSBub3QgbGVnYWN5OiB2MUNvbXBhdCBydW5zIG9taXQgYHRva2VuYCBmcm9tIHRoZSBwcm9kdWNlcidzIGV2ZW50XG4gICAgICAgIC8vICAgIGJvZHkgYnV0IHRoZSBjb25zdW1lcidzIHJlLWVuc3VyZSBhbHdheXMgaW5jbHVkZXMgaXQsIHNvIHRoZSB0d29cbiAgICAgICAgLy8gICAgd3JpdGVycyB3b3VsZCBkaXNhZ3JlZSBvbiB0aGUgZXZlbnQgYm9keS4gTGVnYWN5IHN0YXlzIHNlcXVlbnRpYWwuXG4gICAgICAgIC8vICAtIENCT1IgdHJhbnNwb3J0OiB0aGUgcnVuIG11c3QgdXNlIENCT1IgcXVldWUgdHJhbnNwb3J0IHNvIHRoZSBiaW5hcnlcbiAgICAgICAgLy8gICAgcGF5bG9hZCBzdXJ2aXZlcyB0aGUgcXVldWUgbWVzc2FnZS5cbiAgICAgICAgLy8gIC0gcmF3IGJ5dGVzOiB0aGUgZGVoeWRyYXRlZCBwYXlsb2FkIG11c3QgYmUgYSBgVWludDhBcnJheWAgKHRoZVxuICAgICAgICAvLyAgICBjb250ZW50IGRpZ2VzdCB0aGF0IGtleXMgdGhlIGRlZHVwIGNvbnN0cmFpbnQgaXMgb3ZlciB0aGVzZSBieXRlcykuXG4gICAgICAgIC8vICAtIHNpemU6IGEgcGF5bG9hZCBhYm92ZSB0aGUgcXVldWUncyBtZXNzYWdlIGNlaWxpbmcgd291bGQgZmFpbCB0aGVcbiAgICAgICAgLy8gICAgcHVibGlzaCAod2hpY2gsIG9uIHRoZSBwYXJhbGxlbCBwYXRoLCB3b3VsZCBwZXJzaXN0IHRoZSBldmVudCBidXRcbiAgICAgICAgLy8gICAgbmV2ZXIgcmUtdHJpZ2dlciB0aGUgcnVuKSwgc28gb3ZlcnNpemVkIHBheWxvYWRzIHN0YXkgc2VxdWVudGlhbFxuICAgICAgICAvLyAgICAodGhlaXIgcXVldWUgbWVzc2FnZSBjYXJyaWVzIG9ubHkgdGhlIHJ1biBJRCkuXG4gICAgICAgIGNvbnN0IHBhcmFsbGVsUmVzdW1lRGlzYWJsZWQgPVxuICAgICAgICAgIHByb2Nlc3MuZW52LldPUktGTE9XX0RJU0FCTEVfTEFaWV9IT09LX1JFU1VNRSA9PT0gJzEnO1xuICAgICAgICAvLyBCYWNrZW5kIGRlZHVwIGlzIHN1cHBvcnRlZCB3aGVuIEVJVEhFUiB0aGUgbGl2ZSBzZXJ2ZXIgYXR0ZXN0cyBpdFxuICAgICAgICAvLyBmcmVzaCBvbiB0aGlzIGJ5LXRva2VuIGhvb2sgKHdvcmxkLXZlcmNlbDogcmVzcG9uc2Utb25seSwgcmVjb21wdXRlZFxuICAgICAgICAvLyBldmVyeSByZWFkLCBzbyByb2xsYmFjay9raWxsLXN3aXRjaCB0YWtlIGVmZmVjdCBpbW1lZGlhdGVseSkgT1IgdGhlXG4gICAgICAgIC8vIHN0YXRpYyB3b3JsZCBjYXBhYmlsaXR5IGlzIHNldCAod29ybGQtbG9jYWw6IGFkYXB0ZXIgKyBiYWNrZW5kIHNoaXBcbiAgICAgICAgLy8gdG9nZXRoZXIpLiBCb3RoIGFyZSByZS1ldmFsdWF0ZWQgcGVyIHJlc3VtZSwgc28gZXZlcnkgcm9sbG91dCBhbmRcbiAgICAgICAgLy8gcm9sbGJhY2sgZGlyZWN0aW9uIGRlZ3JhZGVzIHNhZmVseSB0byB0aGUgc2VxdWVudGlhbCBwYXRoLlxuICAgICAgICBjb25zdCBiYWNrZW5kRGVkdXBTdXBwb3J0ZWQgPVxuICAgICAgICAgIChob29rUmVzdW1lQ2FwYWJpbGl0aWVzQXJlRnJlc2hcbiAgICAgICAgICAgID8gKGhvb2sucmVzdW1lQ2FwYWJpbGl0aWVzPy5ob29rUmVzdW1lRGVkdXBWZXJzaW9uID8/IDApXG4gICAgICAgICAgICA6IDApID49IEhPT0tfUkVTVU1FX0RFRFVQX1ZFUlNJT04gfHxcbiAgICAgICAgICB3b3JsZC5jYXBhYmlsaXRpZXM/Lmhvb2tSZXN1bWVEZWR1cCA9PT0gdHJ1ZTtcbiAgICAgICAgY29uc3QgZmFsbGJhY2tSZWFzb246IHN0cmluZyB8IG51bGwgPSBwYXJhbGxlbFJlc3VtZURpc2FibGVkXG4gICAgICAgICAgPyAnZGlzYWJsZWQnXG4gICAgICAgICAgOiAhYmFja2VuZERlZHVwU3VwcG9ydGVkXG4gICAgICAgICAgICA/ICdiYWNrZW5kX3Vuc3VwcG9ydGVkJ1xuICAgICAgICAgICAgOiAocmVzdW1lQ29udGV4dC5ob29rUmVzdW1lSW5wdXRWZXJzaW9uID8/IDApIDxcbiAgICAgICAgICAgICAgICBIT09LX1JFU1VNRV9JTlBVVF9WRVJTSU9OXG4gICAgICAgICAgICAgID8gJ2NvbnN1bWVyX3Vuc3VwcG9ydGVkJ1xuICAgICAgICAgICAgICA6IHYxQ29tcGF0XG4gICAgICAgICAgICAgICAgPyAnbGVnYWN5J1xuICAgICAgICAgICAgICAgIDogKHJlc3VtZUNvbnRleHQucnVuU3BlY1ZlcnNpb24gPz8gMCkgPFxuICAgICAgICAgICAgICAgICAgICBTUEVDX1ZFUlNJT05fU1VQUE9SVFNfQ0JPUl9RVUVVRV9UUkFOU1BPUlRcbiAgICAgICAgICAgICAgICAgID8gJ25vbl9jYm9yX3RyYW5zcG9ydCdcbiAgICAgICAgICAgICAgICAgIDogIShkZWh5ZHJhdGVkUGF5bG9hZCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpXG4gICAgICAgICAgICAgICAgICAgID8gJ25vbl9ieXRlcydcbiAgICAgICAgICAgICAgICAgICAgOiBkZWh5ZHJhdGVkUGF5bG9hZC5ieXRlTGVuZ3RoID5cbiAgICAgICAgICAgICAgICAgICAgICAgIE1BWF9JTkxJTkVfUkVTVU1FX1BBWUxPQURfQllURVNcbiAgICAgICAgICAgICAgICAgICAgICA/ICdvdmVyc2l6ZWQnXG4gICAgICAgICAgICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICBjb25zdCB1c2VQYXJhbGxlbFJlc3VtZSA9IGZhbGxiYWNrUmVhc29uID09PSBudWxsO1xuXG4gICAgICAgIHNwYW4/LnNldEF0dHJpYnV0ZXMoe1xuICAgICAgICAgICd3b3JrZmxvdy5ob29rLnJlc3VtZV9zdHJhdGVneSc6IHVzZVBhcmFsbGVsUmVzdW1lXG4gICAgICAgICAgICA/ICdwYXJhbGxlbCdcbiAgICAgICAgICAgIDogJ3NlcXVlbnRpYWwnLFxuICAgICAgICAgIC4uLihmYWxsYmFja1JlYXNvblxuICAgICAgICAgICAgPyB7ICd3b3JrZmxvdy5ob29rLnJlc3VtZV9mYWxsYmFja19yZWFzb24nOiBmYWxsYmFja1JlYXNvbiB9XG4gICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUmUta2V5IGFueSBcImhvb2sgY2FuIG5vIGxvbmdlciBiZSByZWNlaXZlZFwiIHJlamVjdGlvbiB0b1xuICAgICAgICAvLyBIb29rTm90Rm91bmRFcnJvcihob29rLnRva2VuKSBzbyBgLnRva2VuYCBtYXRjaGVzIHRoZSBwcmUtZmFzdC1wYXRoXG4gICAgICAgIC8vIGNvbnRyYWN0LCB3aGVyZSByZXN1bWVIb29rIHRocmV3IGBIb29rTm90Rm91bmRFcnJvcihob29rLnRva2VuKWBcbiAgICAgICAgLy8gYWZ0ZXIgaXRzIG93biB0ZXJtaW5hbCBjaGVjay4gVGhlIHNwZWNpZmljIGVycm9yIGRlcGVuZHMgb24gdGhlXG4gICAgICAgIC8vIFdvcmxkOlxuICAgICAgICAvLyAgIC0gYSBnZW51aW5lbHkgbWlzc2luZyBob29rIG1hcHMgdG8gSG9va05vdEZvdW5kRXJyb3IgKGtleWVkIG9uIHRoZVxuICAgICAgICAvLyAgICAgZXZlbnQgY29ycmVsYXRpb25JZCAvIGhvb2sgSUQpO1xuICAgICAgICAvLyAgIC0gYSB0ZXJtaW5hbCBydW4gb24gVmVyY2VsIHJlamVjdHMgaG9va19yZWNlaXZlZCB3aXRoIDQwNCwgd2hpY2hcbiAgICAgICAgLy8gICAgIHdvcmxkLXZlcmNlbCBtYXBzIHRvIEhvb2tOb3RGb3VuZEVycm9yO1xuICAgICAgICAvLyAgIC0gYSB0ZXJtaW5hbCBydW4gb24gd29ybGQtbG9jYWwgLyB3b3JsZC1wb3N0Z3JlcyByZWplY3RzIHdpdGhcbiAgICAgICAgLy8gICAgIFJ1bkV4cGlyZWRFcnJvci5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gT24gdGhlIFNFUVVFTlRJQUwgcGF0aCBhbiBFbnRpdHlDb25mbGljdEVycm9yIChIVFRQIDQwOSkgaXMgYWxzb1xuICAgICAgICAvLyB0cmVhdGVkIGFzIFwiaG9vayBnb25lXCIgZm9yIGhpc3RvcmljYWwgLyBjb25mbGljdC1zaGFwZWQtcmVqZWN0aW9uXG4gICAgICAgIC8vIGNvbXBhdGliaWxpdHk6IHRoZXJlIGlzIG5vIHF1ZXVlIG1lc3NhZ2UgaW4gZmxpZ2h0LCBzbyBhIGNvbmZsaWN0IGhhc1xuICAgICAgICAvLyBubyByZS1lbnN1cmluZyBjb25zdW1lciB0byBjb252ZXJnZSBvbi4gVGhlIFBBUkFMTEVMIHBhdGggaGFuZGxlcyA0MDlcbiAgICAgICAgLy8gZGlmZmVyZW50bHkgKHNlZSBiZWxvdyk6IGl0IHB1Ymxpc2hlZCB0aGUgcXVldWUgbWVzc2FnZSBiZWZvcmUgdGhlXG4gICAgICAgIC8vIGNvbmZsaWN0LCBzbyB0aGUgY29uc3VtZXIgd2lsbCBjb252ZXJnZSB0aGUgZXZlbnQuXG4gICAgICAgIGNvbnN0IGlzSG9va0dvbmVFcnJvciA9IChlcnI6IHVua25vd24pOiBib29sZWFuID0+XG4gICAgICAgICAgSG9va05vdEZvdW5kRXJyb3IuaXMoZXJyKSB8fFxuICAgICAgICAgIEVudGl0eUNvbmZsaWN0RXJyb3IuaXMoZXJyKSB8fFxuICAgICAgICAgIFJ1bkV4cGlyZWRFcnJvci5pcyhlcnIpO1xuXG4gICAgICAgIGlmICghdXNlUGFyYWxsZWxSZXN1bWUpIHtcbiAgICAgICAgICAvLyBTZXF1ZW50aWFsIHBhdGg6IGNyZWF0ZSBhIGhvb2tfcmVjZWl2ZWQgZXZlbnQsIHRoZW4gcmUtdHJpZ2dlci5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgd29ybGQuZXZlbnRzLmNyZWF0ZShcbiAgICAgICAgICAgICAgaG9vay5ydW5JZCxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGV2ZW50VHlwZTogJ2hvb2tfcmVjZWl2ZWQnLFxuICAgICAgICAgICAgICAgIHNwZWNWZXJzaW9uOiBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBob29rLmhvb2tJZCxcbiAgICAgICAgICAgICAgICBldmVudERhdGEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHsgdjFDb21wYXQgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGlmIChpc0hvb2tHb25lRXJyb3IoZXJyKSkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgSG9va05vdEZvdW5kRXJyb3IoaG9vay50b2tlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gVDEgb2YgdGhlIFRUUiB3aW5kb3cuIFN0YW1wZWQgaW1tZWRpYXRlbHkgYmVmb3JlIHRoZSBwdWJsaXNoIHNvXG4gICAgICAgICAgLy8gYHByb2R1Y2VyX3ByZXBgIGNvdmVycyBleGFjdGx5IHRoZSB3b3JrIGFib3ZlIGl0IChob29rIGxvb2t1cCxcbiAgICAgICAgICAvLyBrZXkgcmVzb2x1dGlvbiwgc2VyaWFsaXphdGlvbiwgYW5kLCBvbiB0aGlzIHBhdGgsIHRoZSBhd2FpdGVkXG4gICAgICAgICAgLy8gYGhvb2tfcmVjZWl2ZWRgIHdyaXRlLCB3aGljaCBpcyBnZW51aW5lbHkgc2VyaWFsIGhlcmUpLlxuICAgICAgICAgIGNvbnN0IHF1ZXVlUHVibGlzaFJlcXVlc3RlZEF0TXMgPSBEYXRlLm5vdygpO1xuICAgICAgICAgIGF3YWl0IHdvcmxkLnF1ZXVlKFxuICAgICAgICAgICAgcXVldWVOYW1lLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBydW5JZDogaG9vay5ydW5JZCxcbiAgICAgICAgICAgICAgdHJhY2VDYXJyaWVyOiByZXN1bWVDb250ZXh0LnRyYWNlQ2FycmllciA/PyB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIGhvb2tSZXN1bWVUaW1pbmc6IHtcbiAgICAgICAgICAgICAgICByZXN1bWVSZXF1ZXN0ZWRBdE1zLFxuICAgICAgICAgICAgICAgIHF1ZXVlUHVibGlzaFJlcXVlc3RlZEF0TXMsXG4gICAgICAgICAgICAgICAgc3RyYXRlZ3k6ICdzZXF1ZW50aWFsJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0gc2F0aXNmaWVzIFdvcmtmbG93SW52b2tlUGF5bG9hZCxcbiAgICAgICAgICAgIHF1ZXVlT3B0aW9uc1xuICAgICAgICAgICk7XG5cbiAgICAgICAgICByZXR1cm4gaG9vaztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFBhcmFsbGVsIGZhc3QgcGF0aC4gQSBzdGFibGUgaWRlbXBvdGVuY3kga2V5IHRpZXMgdGhlIGRpcmVjdCB3cml0ZSB0b1xuICAgICAgICAvLyB0aGUgcXVldWUgY29uc3VtZXIncyByZS1lbnN1cmU7IHRoZSBwYXlsb2FkIGRpZ2VzdCBsZXRzIHRoZSBzZXJ2ZXJcbiAgICAgICAgLy8gZGV0ZWN0IGtleSByZXVzZSBhY3Jvc3MgYnl0ZS1pZGVudGljYWwgcGF5bG9hZHMuXG4gICAgICAgIGNvbnN0IHJlc3VtZUlkID0gZ2VuZXJhdGVSZXN1bWVJZCgpO1xuICAgICAgICBjb25zdCBwYXlsb2FkRGlnZXN0ID0gYXdhaXQgY29tcHV0ZVJlc3VtZVBheWxvYWREaWdlc3QoXG4gICAgICAgICAgZGVoeWRyYXRlZFBheWxvYWQgYXMgVWludDhBcnJheVxuICAgICAgICApO1xuICAgICAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHsgJ3dvcmtmbG93Lmhvb2sucmVzdW1lX2lkJzogcmVzdW1lSWQgfSk7XG5cbiAgICAgICAgLy8gV3JhcHBlZCBpbiBhIHRodW5rIHB1cmVseSBzbyBUMSBvZiB0aGUgVFRSIHdpbmRvdyBpcyBzdGFtcGVkIGF0IHRoZVxuICAgICAgICAvLyBleGFjdCBpbnN0YW50IHRoZSBwdWJsaXNoIGlzIHJlcXVlc3RlZCwgYWZ0ZXIgdGhlIHJhY2luZ1xuICAgICAgICAvLyBgaG9va19yZWNlaXZlZGAgd3JpdGUgaGFzIGJlZW4ga2lja2VkIG9mZiwgd2hpY2ggaXMgd2hlcmUgdGhlXG4gICAgICAgIC8vIGFkZGl0aXZlIGBwcm9kdWNlcl9wcmVwYCBwaGFzZSBtdXN0IGVuZC4gVGhlIHR3byBjYWxscyBzdGlsbCBzdGFydFxuICAgICAgICAvLyBpbiB0aGUgc2FtZSB0dXJuIGFuZCByYWNlIGV4YWN0bHkgYXMgYmVmb3JlLlxuICAgICAgICBjb25zdCBwdWJsaXNoSW52b2NhdGlvbiA9ICgpID0+IHtcbiAgICAgICAgICBjb25zdCBxdWV1ZVB1Ymxpc2hSZXF1ZXN0ZWRBdE1zID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICByZXR1cm4gd29ybGQucXVldWUoXG4gICAgICAgICAgICBxdWV1ZU5hbWUsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHJ1bklkOiBob29rLnJ1bklkLFxuICAgICAgICAgICAgICB0cmFjZUNhcnJpZXI6IHJlc3VtZUNvbnRleHQudHJhY2VDYXJyaWVyID8/IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgaG9va0lucHV0OiB7XG4gICAgICAgICAgICAgICAgcmVzdW1lSWQsXG4gICAgICAgICAgICAgICAgaG9va0lkOiBob29rLmhvb2tJZCxcbiAgICAgICAgICAgICAgICB0b2tlbjogaG9vay50b2tlbixcbiAgICAgICAgICAgICAgICBwYXlsb2FkOiBkZWh5ZHJhdGVkUGF5bG9hZCxcbiAgICAgICAgICAgICAgICBwYXlsb2FkRGlnZXN0LFxuICAgICAgICAgICAgICAgIC8vIERlcGxveW1lbnQgYWZmaW5pdHkgZm9yIHRoZSBjb25zdW1lcidzIGNoZWFwIHByZS13cml0ZVxuICAgICAgICAgICAgICAgIC8vIGNoZWNrOiBsZXRzIGEgbWlzcm91dGVkIGRlbGl2ZXJ5IHJlLXJvdXRlIGJlZm9yZSBpdHNcbiAgICAgICAgICAgICAgICAvLyBob2lzdGVkIGhvb2tfcmVjZWl2ZWQgd3JpdGUgaW5zdGVhZCBvZiBhZnRlci5cbiAgICAgICAgICAgICAgICBkZXBsb3ltZW50SWQ6IHJlc3VtZUNvbnRleHQuZGVwbG95bWVudElkLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBob29rUmVzdW1lVGltaW5nOiB7XG4gICAgICAgICAgICAgICAgcmVzdW1lUmVxdWVzdGVkQXRNcyxcbiAgICAgICAgICAgICAgICBxdWV1ZVB1Ymxpc2hSZXF1ZXN0ZWRBdE1zLFxuICAgICAgICAgICAgICAgIHN0cmF0ZWd5OiAncGFyYWxsZWwnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSBzYXRpc2ZpZXMgV29ya2Zsb3dJbnZva2VQYXlsb2FkLFxuICAgICAgICAgICAgcXVldWVPcHRpb25zXG4gICAgICAgICAgKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgW2V2ZW50UmVzdWx0LCBxdWV1ZVJlc3VsdF0gPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoW1xuICAgICAgICAgIHdvcmxkLmV2ZW50cy5jcmVhdGUoXG4gICAgICAgICAgICBob29rLnJ1bklkLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBldmVudFR5cGU6ICdob29rX3JlY2VpdmVkJyxcbiAgICAgICAgICAgICAgc3BlY1ZlcnNpb246IFNQRUNfVkVSU0lPTl9DVVJSRU5ULFxuICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBob29rLmhvb2tJZCxcbiAgICAgICAgICAgICAgZXZlbnREYXRhLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHsgdjFDb21wYXQsIHJlc3VtZUlkLCByZXN1bWVQYXlsb2FkRGlnZXN0OiBwYXlsb2FkRGlnZXN0IH1cbiAgICAgICAgICApLFxuICAgICAgICAgIHB1Ymxpc2hJbnZvY2F0aW9uKCksXG4gICAgICAgIF0pO1xuXG4gICAgICAgIC8vIFF1ZXVlIGZhaWx1cmUgaXMgYWx3YXlzIGZhdGFsOiB0aGUgcnVuIHdhcyBub3QgcmUtdHJpZ2dlcmVkLCBzbyBub1xuICAgICAgICAvLyBjb25zdW1lciB3aWxsIHJlLWVuc3VyZSB0aGUgZXZlbnQuXG4gICAgICAgIGlmIChxdWV1ZVJlc3VsdC5zdGF0dXMgPT09ICdyZWplY3RlZCcpIHtcbiAgICAgICAgICB0aHJvdyBxdWV1ZVJlc3VsdC5yZWFzb247XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgd2hlbiB0aGUgZGlyZWN0IHdyaXRlIGRpZCBub3QgbGFuZCBidXQgdGhlIHF1ZXVlIGRpc3BhdGNoIGRpZCwgc29cbiAgICAgICAgLy8gdGhlIGNvbnN1bWVyIG1hdGVyaWFsaXplcyB0aGUgZXZlbnQgYmVmb3JlIHJlcGxheS4gU3VyZmFjZWQgdG8gdGhlXG4gICAgICAgIC8vIGNhbGxlciBhcyBgUmVzdW1lZEhvb2sucmVzaWxpZW50UmVzdW1lYCBhbmQgb24gdGhlIHNwYW4uXG4gICAgICAgIGxldCByZXNpbGllbnRSZXN1bWUgPSBmYWxzZTtcbiAgICAgICAgaWYgKGV2ZW50UmVzdWx0LnN0YXR1cyA9PT0gJ3JlamVjdGVkJykge1xuICAgICAgICAgIGNvbnN0IGVyciA9IGV2ZW50UmVzdWx0LnJlYXNvbjtcbiAgICAgICAgICBpZiAoSG9va05vdEZvdW5kRXJyb3IuaXMoZXJyKSB8fCBSdW5FeHBpcmVkRXJyb3IuaXMoZXJyKSkge1xuICAgICAgICAgICAgLy8gVGhlIGhvb2sncyBydW4gaGFzIGdlbnVpbmVseSBlbmRlZDogc3VyZmFjZSB0aGUgc2FtZSBjb250cmFjdCBhc1xuICAgICAgICAgICAgLy8gdGhlIHNlcXVlbnRpYWwgcGF0aC4gVGhlIHF1ZXVlIG1lc3NhZ2UgYWxyZWFkeSB3ZW50IG91dCwgYnV0IHRoZVxuICAgICAgICAgICAgLy8gY29uc3VtZXIncyByZS1lbnN1cmUgd2lsbCBhbHNvIHJlamVjdCBhZ2FpbnN0IHRoZSB0ZXJtaW5hbCBydW5cbiAgICAgICAgICAgIC8vIGFuZCBuby1vcCwgc28gdGhlIHdvcmtmbG93IGRvZXMgbm90IHJlc3VtZS5cbiAgICAgICAgICAgIHRocm93IG5ldyBIb29rTm90Rm91bmRFcnJvcihob29rLnRva2VuKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKEVudGl0eUNvbmZsaWN0RXJyb3IuaXMoZXJyKSB8fCBpc1JldHJ5YWJsZVdvcmxkRXJyb3IoZXJyKSkge1xuICAgICAgICAgICAgLy8gUmVzaWxpZW50LiBUd28gc2hhcGVzIHJlYWNoIGhlcmUsIGJvdGggbm9uLXRlcm1pbmFsOlxuICAgICAgICAgICAgLy8gICAtIEVudGl0eUNvbmZsaWN0ICg0MDkpOiB0aGlzIHdyaXRlIHJhY2VkIGl0cyBvd24gcmUtZW5zdXJpbmdcbiAgICAgICAgICAgIC8vICAgICBjb25zdW1lciAob3IgYSByZWRyaXZlKSBvbiB0aGUgc2hhcmVkIGByZXN1bWVJZGA7IHRoZSBydW4gaXNcbiAgICAgICAgICAgIC8vICAgICBOT1QgZ29uZSwgYW5kIHRoZSBjb25zdW1lciBjb252ZXJnZXMgb24gdGhlIG9uZSBjb21taXR0ZWRcbiAgICAgICAgICAgIC8vICAgICBldmVudC4gVW5saWtlIHRoZSBzZXF1ZW50aWFsIHBhdGgsIGEgNDA5IGhlcmUgaXMgZXhwZWN0ZWRcbiAgICAgICAgICAgIC8vICAgICBjb25jdXJyZW5jeSwgbm90IGEgdmFuaXNoZWQgaG9vay5cbiAgICAgICAgICAgIC8vICAgLSA0MjkgLyA1eHggLyB0cmFuc3BvcnQ6IGEgdHJhbnNpZW50IGJhY2tlbmQgZmFpbHVyZS5cbiAgICAgICAgICAgIC8vIEluIGJvdGggY2FzZXMgdGhlIHJ1biBXQVMgcmUtdHJpZ2dlcmVkIHZpYSB0aGUgcXVldWUgYW5kIHRoZVxuICAgICAgICAgICAgLy8gY29uc3VtZXIgaWRlbXBvdGVudGx5IGVuc3VyZXMgdGhlIGhvb2tfcmVjZWl2ZWQgYmVmb3JlIHJlcGxheSwgc29cbiAgICAgICAgICAgIC8vIHN3YWxsb3cgcmF0aGVyIHRoYW4gZmFpbGluZyB0aGUgY2FsbGVyLlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIFByb2R1Y2VyIHRlbGVtZXRyeTogcmVjb3JkIHRoYXQgdGhlIGRpcmVjdCB3cml0ZSBkaWQgbm90IGxhbmQgYnV0XG4gICAgICAgICAgICAvLyB0aGUgcmVzdW1lIGlzIHN0aWxsIGd1YXJhbnRlZWQgdmlhIHF1ZXVlLWRlbGl2ZXJlZCBgaG9va0lucHV0YC5cbiAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIG9wZXJhdGlvbmFsIHNpZ25hbCB0aGF0IHRoZSByZWNvdmVyeSBwYXRoIGZpcmVkLFxuICAgICAgICAgICAgLy8gc3VyZmFjZWQgYm90aCBvbiB0aGUgc3BhbiBhbmQgYXMgdGhlIHB1YmxpYyBgcmVzaWxpZW50UmVzdW1lYFxuICAgICAgICAgICAgLy8gZmxhZyBvbiB0aGUgcmV0dXJuZWQgaG9vayAodGhlIHJlc3VtZSBvdXRjb21lIGlzIG90aGVyd2lzZVxuICAgICAgICAgICAgLy8gaWRlbnRpY2FsIHRvIHRoZSBoYXBweSBwYXRoIGZyb20gdGhlIGNhbGxlcidzIHBlcnNwZWN0aXZlKS5cbiAgICAgICAgICAgIHJlc2lsaWVudFJlc3VtZSA9IHRydWU7XG4gICAgICAgICAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgICAgICAgICAgLi4uQXR0cmlidXRlLkhvb2tSZXNpbGllbnRSZXN1bWUodHJ1ZSksXG4gICAgICAgICAgICAgICd3b3JrZmxvdy5ob29rLnJlc3VtZV9ldmVudF93cml0ZV9yZWNvdmVyZWQnOiB0cnVlLFxuICAgICAgICAgICAgICAnd29ya2Zsb3cuaG9vay5yZXN1bWVfZXZlbnRfd3JpdGVfZXJyb3InOlxuICAgICAgICAgICAgICAgIGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm5hbWUgOiAndW5rbm93bicsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIud2FybihcbiAgICAgICAgICAgICAgJ0hvb2sgcmVzdW1lIGV2ZW50IHdyaXRlIGZhaWxlZCwgYnV0IHRoZSBydW4gd2FzIHJlLXRyaWdnZXJlZCB2aWEgJyArXG4gICAgICAgICAgICAgICAgJ3RoZSBxdWV1ZS4gVGhlIGhvb2tfcmVjZWl2ZWQgZXZlbnQgd2lsbCBiZSBlbnN1cmVkIGJ5IHRoZSAnICtcbiAgICAgICAgICAgICAgICAncXVldWUgY29uc3VtZXIuJyxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IGhvb2sucnVuSWQsXG4gICAgICAgICAgICAgICAgaG9va0lkOiBob29rLmhvb2tJZCxcbiAgICAgICAgICAgICAgICByZXN1bWVJZCxcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICByZXNpbGllbnRSZXN1bWUgPyB7IC4uLmhvb2ssIHJlc2lsaWVudFJlc3VtZTogdHJ1ZSB9IDogaG9va1xuICAgICAgICApIHNhdGlzZmllcyBSZXN1bWVkSG9vaztcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgICAgICAuLi5BdHRyaWJ1dGUuSG9va1Rva2VuKFxuICAgICAgICAgICAgdHlwZW9mIHRva2VuT3JIb29rID09PSAnc3RyaW5nJyA/IHRva2VuT3JIb29rIDogdG9rZW5Pckhvb2sudG9rZW5cbiAgICAgICAgICApLFxuICAgICAgICAgIC4uLkF0dHJpYnV0ZS5Ib29rRm91bmQoZmFsc2UpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZXN1bWVzIGEgd2ViaG9vayBieSBzZW5kaW5nIGEge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9SZXF1ZXN0IHwgUmVxdWVzdH1cbiAqIG9iamVjdCB0byBhIGhvb2sgaWRlbnRpZmllZCBieSBpdHMgdG9rZW4uXG4gKlxuICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgZXh0ZXJuYWxseSAoZS5nLiwgZnJvbSBhbiBBUEkgcm91dGUgb3Igc2VydmVyIGFjdGlvbilcbiAqIHRvIHNlbmQgYSByZXF1ZXN0IHRvIGEgd2ViaG9vayBhbmQgcmVzdW1lIHRoZSBhc3NvY2lhdGVkIHdvcmtmbG93IHJ1bi5cbiAqXG4gKiBAcGFyYW0gdG9rZW4gLSBUaGUgdW5pcXVlIHRva2VuIGlkZW50aWZ5aW5nIHRoZSBob29rXG4gKiBAcGFyYW0gcmVxdWVzdCAtIFRoZSByZXF1ZXN0IHRvIHNlbmQgdG8gdGhlIGhvb2tcbiAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSByZXNwb25zZVxuICogQHRocm93cyBFcnJvciBpZiB0aGUgaG9vayBpcyBub3QgZm91bmQgb3IgaWYgdGhlcmUncyBhbiBlcnJvciBkdXJpbmcgdGhlIHByb2Nlc3NcbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqIGBgYHRzXG4gKiAvLyBJbiBhbiBBUEkgcm91dGVcbiAqIGltcG9ydCB7IHJlc3VtZVdlYmhvb2sgfSBmcm9tICdAd29ya2Zsb3cvY29yZS9ydW50aW1lJztcbiAqXG4gKiBleHBvcnQgYXN5bmMgZnVuY3Rpb24gUE9TVChyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gKiAgIGNvbnN0IHVybCA9IG5ldyBVUkwocmVxdWVzdC51cmwpO1xuICogICBjb25zdCB0b2tlbiA9IHVybC5zZWFyY2hQYXJhbXMuZ2V0KCd0b2tlbicpO1xuICpcbiAqICAgaWYgKCF0b2tlbikge1xuICogICAgIHJldHVybiBuZXcgUmVzcG9uc2UoJ01pc3NpbmcgdG9rZW4nLCB7IHN0YXR1czogNDAwIH0pO1xuICogICB9XG4gKlxuICogICB0cnkge1xuICogICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgcmVzdW1lV2ViaG9vayh0b2tlbiwgcmVxdWVzdCk7XG4gKiAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICogICB9IGNhdGNoIChlcnJvcikge1xuICogICAgIHJldHVybiBuZXcgUmVzcG9uc2UoJ1dlYmhvb2sgbm90IGZvdW5kJywgeyBzdGF0dXM6IDQwNCB9KTtcbiAqICAgfVxuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXN1bWVXZWJob29rKFxuICB0b2tlbjogc3RyaW5nLFxuICByZXF1ZXN0OiBSZXF1ZXN0XG4pOiBQcm9taXNlPFJlc3BvbnNlPiB7XG4gIC8vIFQwIG9mIHRoZSBob29rLXJlc3VtZSBUVFIgd2luZG93LiBFdmVyeXRoaW5nIGJlbG93ICh0aGUgYnktdG9rZW4gbG9va3VwLFxuICAvLyB0aGUgcnVuLWtleSByZXNvbHV0aW9uIGl0IG1heSB0cmlnZ2VyLCBhbmQgdGhlIGByZXNwb25kV2l0aGAgc2V0dXApIGlzXG4gIC8vIHJlYWwgcHJvZHVjZXItc2lkZSBsYXRlbmN5IG9uIHRoaXMgcGF0aCwgc28gdGhlIHdpbmRvdyBoYXMgdG8gb3BlbiBoZXJlXG4gIC8vIGFuZCBub3QgaW5zaWRlIGByZXN1bWVIb29rSW1wbGA7IG90aGVyd2lzZSB3ZWJob29rIHJlc3VtZXMgd291bGQgcmVwb3J0IGFcbiAgLy8gc3lzdGVtYXRpY2FsbHkgc2hvcnRlciB0b3RhbCB0aGFuIGByZXN1bWVIb29rYCBvbmVzIGludG8gdGhlIHNhbWUgbWV0cmljLlxuICBjb25zdCByZXN1bWVSZXF1ZXN0ZWRBdE1zID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgeyBob29rLCBlbmNyeXB0aW9uS2V5IH0gPSBhd2FpdCBnZXRIb29rQnlUb2tlbldpdGhLZXkodG9rZW4pO1xuXG4gIC8vIE9ubHkgd2ViaG9va3MgY2FuIGJlIHJlc3VtZWQgdmlhIHRoZSBwdWJsaWMgZW5kcG9pbnQuXG4gIC8vIElmIHRoZSBob29rIHdhcyBjcmVhdGVkIHZpYSBjcmVhdGVIb29rKCkgKGlzV2ViaG9vayAhPT0gdHJ1ZSksXG4gIC8vIHRocm93IHRoZSBzYW1lIFwibm90IGZvdW5kXCIgZXJyb3IgdGhlIHdvcmxkIHdvdWxkIHRocm93IGZvciBhIG1pc3NpbmdcbiAgLy8gdG9rZW4uIFRoaXMgcHJldmVudHMgbGVha2luZyB0aGF0IHRoZSB0b2tlbiBpcyB2YWxpZC5cbiAgaWYgKGhvb2suaXNXZWJob29rID09PSBmYWxzZSkge1xuICAgIHRocm93IG5ldyBIb29rTm90Rm91bmRFcnJvcih0b2tlbik7XG4gIH1cblxuICBsZXQgcmVzcG9uc2U6IFJlc3BvbnNlIHwgdW5kZWZpbmVkO1xuICBsZXQgcmVzcG9uc2VSZWFkYWJsZTogUmVhZGFibGVTdHJlYW08UmVzcG9uc2U+IHwgdW5kZWZpbmVkO1xuICBpZiAoXG4gICAgaG9vay5tZXRhZGF0YSAmJlxuICAgIHR5cGVvZiBob29rLm1ldGFkYXRhID09PSAnb2JqZWN0JyAmJlxuICAgICdyZXNwb25kV2l0aCcgaW4gaG9vay5tZXRhZGF0YVxuICApIHtcbiAgICBpZiAoaG9vay5tZXRhZGF0YS5yZXNwb25kV2l0aCA9PT0gJ21hbnVhbCcpIHtcbiAgICAgIGNvbnN0IHsgcmVhZGFibGUsIHdyaXRhYmxlIH0gPSBuZXcgVHJhbnNmb3JtU3RyZWFtPFJlc3BvbnNlLCBSZXNwb25zZT4oKTtcbiAgICAgIHJlc3BvbnNlUmVhZGFibGUgPSByZWFkYWJsZTtcblxuICAgICAgLy8gVGhlIHJlcXVlc3QgaW5zdGFuY2UgaW5jbHVkZXMgdGhlIHdyaXRhYmxlIHN0cmVhbSB3aGljaCB3aWxsIGJlIHVzZWRcbiAgICAgIC8vIHRvIHdyaXRlIHRoZSByZXNwb25zZSB0byB0aGUgY2xpZW50IGZyb20gd2l0aGluIHRoZSB3b3JrZmxvdyBydW5cbiAgICAgIChyZXF1ZXN0IGFzIGFueSlbV0VCSE9PS19SRVNQT05TRV9XUklUQUJMRV0gPSB3cml0YWJsZTtcbiAgICB9IGVsc2UgaWYgKGhvb2subWV0YWRhdGEucmVzcG9uZFdpdGggaW5zdGFuY2VvZiBSZXNwb25zZSkge1xuICAgICAgcmVzcG9uc2UgPSBob29rLm1ldGFkYXRhLnJlc3BvbmRXaXRoO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIFxcYHJlc3BvbmRXaXRoXFxgIHZhbHVlOiAke2hvb2subWV0YWRhdGEucmVzcG9uZFdpdGh9YCxcbiAgICAgICAgeyBzbHVnOiBFUlJPUl9TTFVHUy5XRUJIT09LX0lOVkFMSURfUkVTUE9ORF9XSVRIX1ZBTFVFIH1cbiAgICAgICk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIE5vIGByZXNwb25kV2l0aGAgdmFsdWUgaW1wbGllcyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiByZXR1cm5pbmcgYSAyMDJcbiAgICByZXNwb25zZSA9IG5ldyBSZXNwb25zZShudWxsLCB7IHN0YXR1czogMjAyIH0pO1xuICB9XG5cbiAgLy8gYGhvb2tgIHdhcyBqdXN0IGZldGNoZWQgdmlhIGBnZXRIb29rQnlUb2tlbldpdGhLZXlgIChhIGZyZXNoIGJ5LXRva2VuXG4gIC8vIGxvb2t1cCkgYWJvdmUsIHNvIGl0cyByZXNwb25zZS1vbmx5IGByZXN1bWVDYXBhYmlsaXRpZXNgIHJlZmxlY3RzIHRoZSBsaXZlXG4gIC8vIGJhY2tlbmQuIENhbGwgdGhlIGludGVybmFsIGltcGxlbWVudGF0aW9uIHdpdGggdGhlIGZyZXNoIGF0dGVzdGF0aW9uIHNvXG4gIC8vIHRoZSBwYXJhbGxlbCBmYXN0IHBhdGggc3RheXMgYXZhaWxhYmxlIHdpdGhvdXQgYSBzZWNvbmQgR0VULiAoVGhlIHB1YmxpY1xuICAvLyBgcmVzdW1lSG9va2AgbmV2ZXIgc2V0cyB0aGlzLCBzbyBhIGNhbGxlciBjYW5ub3QgZm9yZ2UgaXQuKVxuICBhd2FpdCByZXN1bWVIb29rSW1wbChob29rLCByZXF1ZXN0LCBlbmNyeXB0aW9uS2V5LCB0cnVlLCByZXN1bWVSZXF1ZXN0ZWRBdE1zKTtcblxuICBpZiAocmVzcG9uc2VSZWFkYWJsZSkge1xuICAgIC8vIFdhaXQgZm9yIHRoZSByZWFkYWJsZSBzdHJlYW0gdG8gZW1pdCBvbmUgY2h1bmssXG4gICAgLy8gd2hpY2ggaXMgdGhlIGBSZXNwb25zZWAgb2JqZWN0XG4gICAgY29uc3QgcmVhZGVyID0gcmVzcG9uc2VSZWFkYWJsZS5nZXRSZWFkZXIoKTtcbiAgICBjb25zdCBjaHVuayA9IGF3YWl0IHJlYWRlci5yZWFkKCk7XG4gICAgaWYgKGNodW5rLnZhbHVlKSB7XG4gICAgICByZXNwb25zZSA9IGNodW5rLnZhbHVlO1xuICAgIH1cbiAgICByZWFkZXIuY2FuY2VsKCk7XG4gIH1cblxuICBpZiAoIXJlc3BvbnNlKSB7XG4gICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKCdXb3JrZmxvdyBydW4gZGlkIG5vdCBzZW5kIGEgcmVzcG9uc2UnLCB7XG4gICAgICBzbHVnOiBFUlJPUl9TTFVHUy5XRUJIT09LX1JFU1BPTlNFX05PVF9TRU5ULFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHJlc3BvbnNlO1xufVxuIl19
|
|
604
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdW1lLWhvb2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVudGltZS9yZXN1bWUtaG9vay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsV0FBVyxFQUNYLGlCQUFpQixFQUNqQixlQUFlLEVBQ2Ysb0JBQW9CLEdBQ3JCLE1BQU0sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxFQUNMLHlCQUF5QixFQUd6QixtQkFBbUIsRUFDbkIsMkJBQTJCLEVBQzNCLG9CQUFvQixFQUNwQixtQkFBbUIsRUFDbkIsaUNBQWlDLEdBR2xDLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3RFLE9BQU8sRUFDTCx3QkFBd0IsRUFDeEIsb0JBQW9CLEVBRXBCLG1CQUFtQixFQUNuQixNQUFNLEdBQ1AsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDMUQsT0FBTyxLQUFLLFNBQVMsTUFBTSxzQ0FBc0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsS0FBSyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDNUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNwRCxPQUFPLEVBQUUsYUFBYSxF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LEVBQUUsSUFBSSxFQUFFLG1CQUFtQixDQUFDLENBQUM7SUFFOUUsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3JCLGtEQUFrRDtRQUNsRCxpQ0FBaUM7UUFDakMsTUFBTSxNQUFNLEdBQUcsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDNUMsTUFBTSxLQUFLLEdBQUcsTUFBTSxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDbEMsSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDaEIsUUFBUSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDekIsQ0FBQztRQUNELE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNsQixDQUFDO0lBRUQsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2QsTUFBTSxJQUFJLG9CQUFvQixDQUFDLHNDQUFzQyxFQUFFO1lBQ3JFLElBQUksRUFBRSxXQUFXLENBQUMseUJBQXlCO1NBQzVDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxPQUFPLFFBQVEsQ0FBQztBQUNsQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgRVJST1JfU0xVR1MsXG4gIEhvb2tOb3RGb3VuZEVycm9yLFxuICBSdW5FeHBpcmVkRXJyb3IsXG4gIFdvcmtmbG93UnVudGltZUVycm9yLFxufSBmcm9tICdAd29ya2Zsb3cvZXJyb3JzJztcbmltcG9ydCB7XG4gIEhPT0tfUkVTVU1FX0RFRFVQX1ZFUlNJT04sXG4gIHR5cGUgSG9vayxcbiAgdHlwZSBIb29rUmVzdW1lQ29udGV4dCxcbiAgaXNMZWdhY3lTcGVjVmVyc2lvbixcbiAgaXNUZXJtaW5hbFdvcmtmbG93UnVuU3RhdHVzLFxuICBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgU1BFQ19WRVJTSU9OX0xFR0FDWSxcbiAgU1BFQ19WRVJTSU9OX1NVUFBPUlRTX0NPTVBSRVNTSU9OLFxuICB0eXBlIFdvcmtmbG93SW52b2tlUGF5bG9hZCxcbiAgdHlwZSBXb3JrZmxvd1J1bixcbn0gZnJvbSAnQHdvcmtmbG93L3dvcmxkJztcbmltcG9ydCB7IG1vbm90b25pY0ZhY3RvcnkgfSBmcm9tICd1bGlkJztcbmltcG9ydCB7IGdldFJ1bkNhcGFiaWxpdGllcyB9IGZyb20gJy4uL2NhcGFiaWxpdGllcy5qcyc7XG5pbXBvcnQgeyBpbXBvcnRLZXkgfSBmcm9tICcuLi9lbmNyeXB0aW9uLmpzJztcbmltcG9ydCB7IHJ1bnRpbWVMb2dnZXIgfSBmcm9tICcuLi9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZGVjb2RlUnVuUHVibGljS2V5IH0gZnJvbSAnLi4vc2VhbGVkLWJveC5qcyc7XG5pbXBvcnQgeyBkZXJpdmVSdW5QYXlsb2FkS2V5cyB9IGZyb20gJy4uL3NlcmlhbGl6YXRpb24vZW5jcnlwdGlvbi5qcyc7XG5pbXBvcnQge1xuICBkZWh5ZHJhdGVTdGVwUmV0dXJuVmFsdWUsXG4gIGh5ZHJhdGVTdGVwQXJndW1lbnRzLFxuICB0eXBlIFBheWxvYWRLZXksXG4gIFNlcmlhbGl6YXRpb25Gb3JtYXQsXG4gIHNlYWxUbyxcbn0gZnJvbSAnLi4vc2VyaWFsaXphdGlvbi5qcyc7XG5pbXBvcnQgeyBXRUJIT09LX1JFU1BPTlNFX1dSSVRBQkxFIH0gZnJvbSAnLi4vc3ltYm9scy5qcyc7XG5pbXBvcnQgKiBhcyBBdHRyaWJ1dGUgZnJvbSAnLi4vdGVsZW1ldHJ5L3NlbWFudGljLWNvbnZlbnRpb25zLmpzJztcbmltcG9ydCB7IGxpbmtUb1RyYWNlQ2FycmllciwgdHJhY2UgfSBmcm9tICcuLi90ZWxlbWV0cnkuanMnO1xuaW1wb3J0IHsgZ2V0V29ybGRMYXp5IH0gZnJvbSAnLi9nZXQtd29ybGQtbGF6eS5qcyc7XG5pbXBvcnQgeyBnZXRXb3JrZmxvd1F1ZXVlTmFtZSB9IGZyb20gJy4vaGVscGVycy5qcyc7XG5pbXBvcnQgeyBzYWZlV2FpdFVudGlsLCB3YWl0ZWRVbnRpbCB9IGZyb20gJy4vd2FpdC11bnRpbC5qcyc7XG5cbi8qKiBNb25vdG9uaWMgVUxJRCBmYWN0b3J5IGZvciBwZXItY2FsbCByZXN1bWUgaWRlbXBvdGVuY3kga2V5cy4gKi9cbmNvbnN0IGdlbmVyYXRlUmVzdW1lSWQgPSBtb25vdG9uaWNGYWN0b3J5KCk7XG5cbi8qKlxuICogSGV4IFNIQS0yNTYgb2YgdGhlIHNlcmlhbGl6ZWQgcmVzdW1lIHBheWxvYWQgYnl0ZXMuIENvbXB1dGVkIG9uY2UgYnkgdGhlXG4gKiBwcm9kdWNlciBhbmQgc2VudCB3aXRoIGl0cyBkdXJhYmxlIGBob29rX3JlY2VpdmVkYCB3cml0ZSBzbyB0cmFuc3BvcnQgYW5kXG4gKiBzbG90IHJldHJpZXMgY29udmVyZ2UgdGhyb3VnaCB0aGUgc2VydmVyJ3MgYChydW5JZCwgcmVzdW1lSWQpYCBjb25zdHJhaW50LlxuICovXG5hc3luYyBmdW5jdGlvbiBjb21wdXRlUmVzdW1lUGF5bG9hZERpZ2VzdChieXRlczogVWludDhBcnJheSk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGRpZ2VzdCA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGlnZXN0KCdTSEEtMjU2JywgYnl0ZXMpO1xuICBjb25zdCB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkoZGlnZXN0KTtcbiAgbGV0IGhleCA9ICcnO1xuICBmb3IgKGNvbnN0IGIgb2Ygdmlldykge1xuICAgIGhleCArPSBiLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCAnMCcpO1xuICB9XG4gIHJldHVybiBoZXg7XG59XG5cbmNvbnN0IEhPT0tfV0FLRV9SRVRSWV9ERUxBWVNfTVMgPSBbMjUsIDEwMF0gYXMgY29uc3Q7XG5cbi8qKlxuICogQSB3YWtlIGZhaWx1cmUgd29ydGggcmV0cnlpbmcgaXMgdHJhbnNwb3J0LXNoYXBlZCAobmV0d29yayBlcnJvciwgNXh4LFxuICogdGhyb3R0bGUpLiBBIGRlZmluaXRpdmUgcmVqZWN0aW9uIHdpbGwgbm90IGNoYW5nZSBvbiBhIDI1bXMgcmV0cnksIHNvXG4gKiBzcGVuZGluZyB0aGUgYnVkZ2V0IG9uIGl0IG9ubHkgZGVsYXlzIHRoZSBjYWxsZXIncyBlcnJvci5cbiAqXG4gKiBgQHZlcmNlbC9xdWV1ZWAgZXJyb3JzIGNhcnJ5IG5vIGBzdGF0dXNgIGZpZWxkIOKAlCB0aGV5IGFyZSBiYXJlIGBFcnJvcmBcbiAqIHN1YmNsYXNzZXMgZGlzdGluZ3Vpc2hlZCBieSBgbmFtZWAg4oCUIHNvIGNsYXNzaWZpY2F0aW9uIGNoZWNrcyB0aGUgV29ybGQnc1xuICogZGVwbG95bWVudC11bmF2YWlsYWJsZSBob29rIGZpcnN0IChhIGRlcGxveW1lbnQgdGhlIHF1ZXVlIGNhbm5vdCBkaXNjb3ZlclxuICogd2lsbCBub3QgY29tZSBiYWNrIHdpdGhpbiB0aGlzIGZ1bmN0aW9uJ3MgfjEyNW1zIGJ1ZGdldCksIHRoZW4gYSBudW1lcmljXG4gKiBzdGF0dXMgd2hlbiBvbmUgZXhpc3RzIChub24tVmVyY2VsIHF1ZXVlIGltcGxlbWVudGF0aW9ucyksIHRoZW4gdGhlIHF1ZXVlXG4gKiBjbGllbnQncyBkZWZpbml0aXZlLTR4eCBlcnJvciBuYW1lcy5cbiAqL1xuZnVuY3Rpb24gaXNSZXRyeWFibGVXYWtlRXJyb3IoXG4gIGVycm9yOiB1bmtub3duLFxuICBpc0RlcGxveW1lbnRVbmF2YWlsYWJsZUVycm9yPzogKGVycm9yOiB1bmtub3duKSA9PiBib29sZWFuXG4pOiBib29sZWFuIHtcbiAgaWYgKGlzRGVwbG95bWVudFVuYXZhaWxhYmxlRXJyb3I/LihlcnJvcikpIHJldHVybiBmYWxzZTtcbiAgY29uc3Qgc3RhdHVzID0gKGVycm9yIGFzIHsgc3RhdHVzPzogdW5rbm93bjsgc3RhdHVzQ29kZT86IHVua25vd24gfSkgPz8ge307XG4gIGNvbnN0IGNvZGUgPSBzdGF0dXMuc3RhdHVzID8/IHN0YXR1cy5zdGF0dXNDb2RlO1xuICBpZiAodHlwZW9mIGNvZGUgPT09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIGNvZGUgPj0gNTAwIHx8IGNvZGUgPT09IDQwOCB8fCBjb2RlID09PSA0Mjk7XG4gIH1cbiAgY29uc3QgbmFtZSA9IChlcnJvciBhcyBFcnJvciB8IG51bGwpPy5uYW1lO1xuICByZXR1cm4gKFxuICAgIG5hbWUgIT09ICdCYWRSZXF1ZXN0RXJyb3InICYmXG4gICAgbmFtZSAhPT0gJ1VuYXV0aG9yaXplZEVycm9yJyAmJlxuICAgIG5hbWUgIT09ICdGb3JiaWRkZW5FcnJvcidcbiAgKTtcbn1cblxuLy8gQSBwdWJsaXNoIG1heSBzdWNjZWVkIGV2ZW4gd2hlbiBpdHMgcmVzcG9uc2UgaXMgbG9zdCwgc28gYSByZXRyeSBjYW5cbi8vIGVucXVldWUgYSBkdXBsaWNhdGUgd2FrZS4gVGhhdCBpcyBoYXJtbGVzczogdGhlIGV2ZW50IGlzIGFscmVhZHkgZHVyYWJsZSxcbi8vIGFuZCBkZXRlcm1pbmlzdGljIHJlcGxheSBtYWtlcyBhIHNlY29uZCBkZWxpdmVyeSBvZiB0aGUgc2FtZSBydW4gYSBuby1vcC5cbmFzeW5jIGZ1bmN0aW9uIHB1Ymxpc2hIb29rV2FrZVdpdGhSZXRyeShcbiAgcHVibGlzaDogKCkgPT4gUHJvbWlzZTx1bmtub3duPixcbiAgaXNEZXBsb3ltZW50VW5hdmFpbGFibGVFcnJvcj86IChlcnJvcjogdW5rbm93bikgPT4gYm9vbGVhblxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGxldCBsYXN0RXJyb3I6IHVua25vd247XG4gIGZvciAoXG4gICAgbGV0IGF0dGVtcHQgPSAwO1xuICAgIGF0dGVtcHQgPD0gSE9PS19XQUtFX1JFVFJZX0RFTEFZU19NUy5sZW5ndGg7XG4gICAgYXR0ZW1wdCsrXG4gICkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBwdWJsaXNoKCk7XG4gICAgICByZXR1cm47XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxhc3RFcnJvciA9IGVycm9yO1xuICAgICAgaWYgKCFpc1JldHJ5YWJsZVdha2VFcnJvcihlcnJvciwgaXNEZXBsb3ltZW50VW5hdmFpbGFibGVFcnJvcikpIGJyZWFrO1xuICAgICAgY29uc3QgZGVsYXlNcyA9IEhPT0tfV0FLRV9SRVRSWV9ERUxBWVNfTVNbYXR0ZW1wdF07XG4gICAgICBpZiAoZGVsYXlNcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIGRlbGF5TXMpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBUaGUgd2FrZSBvbmx5IHJ1bnMgYWZ0ZXIgdGhlIGhvb2tfcmVjZWl2ZWQgd3JpdGUgY29tbWl0dGVkLCBzbyBhIHdha2VcbiAgLy8gZmFpbHVyZSBoZXJlIGlzIG5lY2Vzc2FyaWx5IFwiZHVyYWJsZSBidXQgbm90IHlldCBkaXNwYXRjaGVkXCI6IHRoZSBldmVudFxuICAvLyBzdXJ2aXZlcywgYW5kIGFueSBsYXRlciB3YWtlIG9mIHRoZSBydW4gZGVsaXZlcnMgaXQuIERvIG5vdCBsZXQgYSBxdWV1ZVxuICAvLyBpbXBsZW1lbnRhdGlvbiByZXVzZSBIb29rTm90Rm91bmRFcnJvciBhbmQgYWNjaWRlbnRhbGx5IGltcGx5IHRoYXQgbm9cbiAgLy8gaG9va19yZWNlaXZlZCBleGlzdHMuXG4gIGlmIChIb29rTm90Rm91bmRFcnJvci5pcyhsYXN0RXJyb3IpKSB7XG4gICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKFxuICAgICAgJ1RoZSBob29rIHJlc3VtZSB3YXMgY29tbWl0dGVkLCBidXQgaXRzIHdvcmtmbG93IHdha2UgY291bGQgbm90IGJlIHB1Ymxpc2hlZCcsXG4gICAgICB7IGNhdXNlOiBsYXN0RXJyb3IgfVxuICAgICk7XG4gIH1cbiAgdGhyb3cgbGFzdEVycm9yO1xufVxuXG4vKipcbiAqIFRoZSByZXN1bWUgY29udGV4dCBmb3IgYSBob29rIHBsdXMgd2hlcmUgaXQgY2FtZSBmcm9tLiBgcnVuYCBpcyBwcmVzZW50IG9ubHlcbiAqIG9uIHRoZSBmYWxsYmFjayBwYXRoIChwcmUtYHJlc3VtZUNvbnRleHRgIGhvb2tzKSwgd2hlcmUgaXQgYWxzbyBjYXJyaWVzIHRoZVxuICogcnVuJ3MgbXV0YWJsZSBzdGF0dXMgZm9yIHRoZSB0ZXJtaW5hbC1ydW4gY2hlY2suIEtleSByZXNvbHV0aW9uIGlzIGtlcHRcbiAqIHNlcGFyYXRlIHNvIGNhbGxlcnMgY2FuIGdhdGUgaXQgYmVoaW5kIHRoYXQgY2hlY2suXG4gKi9cbmludGVyZmFjZSBIb29rUmVzdW1lSW5mbyB7XG4gIHJlc3VtZUNvbnRleHQ6IEhvb2tSZXN1bWVDb250ZXh0O1xuICBzb3VyY2U6ICdob29rJyB8ICdydW5fZmFsbGJhY2snO1xuICBydW4/OiBXb3JrZmxvd1J1bjtcbn1cblxuLyoqIERlcml2ZSBhIHJlc3VtZSBjb250ZXh0IGZyb20gYSBmdWxsIHJ1biAoZmFsbGJhY2sgZm9yIHByZS1gcmVzdW1lQ29udGV4dGAgaG9va3MpLiAqL1xuZnVuY3Rpb24gcmVzdW1lQ29udGV4dEZyb21SdW4ocnVuOiBXb3JrZmxvd1J1bik6IEhvb2tSZXN1bWVDb250ZXh0IHtcbiAgY29uc3QgY29yZVZlcnNpb24gPSBydW4uZXhlY3V0aW9uQ29udGV4dD8ud29ya2Zsb3dDb3JlVmVyc2lvbjtcbiAgY29uc3QgdHJhY2VDYXJyaWVyID0gcnVuLmV4ZWN1dGlvbkNvbnRleHQ/LnRyYWNlQ2FycmllcjtcbiAgY29uc3QgaG9va1Jlc3VtZUlucHV0VmVyc2lvbiA9IHJ1bi5leGVjdXRpb25Db250ZXh0Py5ob29rUmVzdW1lSW5wdXRWZXJzaW9uO1xuICByZXR1cm4ge1xuICAgIGRlcGxveW1lbnRJZDogcnVuLmRlcGxveW1lbnRJZCxcbiAgICB3b3JrZmxvd05hbWU6IHJ1bi53b3JrZmxvd05hbWUsXG4gICAgcnVuU3BlY1ZlcnNpb246IHJ1bi5zcGVjVmVyc2lvbixcbiAgICB3b3JrZmxvd0NvcmVWZXJzaW9uOlxuICAgICAgdHlwZW9mIGNvcmVWZXJzaW9uID09PSAnc3RyaW5nJyA/IGNvcmVWZXJzaW9uIDogdW5kZWZpbmVkLFxuICAgIHRyYWNlQ2FycmllcjpcbiAgICAgIHRyYWNlQ2FycmllciAmJiB0eXBlb2YgdHJhY2VDYXJyaWVyID09PSAnb2JqZWN0J1xuICAgICAgICA/ICh0cmFjZUNhcnJpZXIgYXMgSG9va1Jlc3VtZUNvbnRleHRbJ3RyYWNlQ2FycmllciddKVxuICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICBlbmNyeXB0aW9uUHVibGljS2V5OiBydW4uZW5jcnlwdGlvblB1YmxpY0tleSxcbiAgICBob29rUmVzdW1lSW5wdXRWZXJzaW9uOlxuICAgICAgdHlwZW9mIGhvb2tSZXN1bWVJbnB1dFZlcnNpb24gPT09ICdudW1iZXInXG4gICAgICAgID8gaG9va1Jlc3VtZUlucHV0VmVyc2lvblxuICAgICAgICA6IHVuZGVmaW5lZCxcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIHJlc3VtZSBjb250ZXh0IGZvciBhIGhvb2suIFVzZXMgdGhlIHN0b3JlZCBgcmVzdW1lQ29udGV4dGAgd2hlblxuICogcHJlc2VudCAoZmFzdCBwYXRoLCBubyBydW4gcmVhZCk7IG90aGVyd2lzZSBmZXRjaGVzIHRoZSBydW4gYW5kIHN5bnRoZXNpemVzXG4gKiBpdC4gRG9lcyBOT1QgcmVzb2x2ZSB0aGUgZW5jcnlwdGlvbiBrZXk7IGNhbGxlcnMgZG8gdGhhdCBzZXBhcmF0ZWx5LiBPbmx5XG4gKiB0aGUgZmFsbGJhY2sgcGF0aCBjYW4gZ2F0ZSBrZXkgd29yayBiZWhpbmQgYSBsb2NhbCB0ZXJtaW5hbC1ydW4gY2hlY2sgKGl0XG4gKiBoYXMgdGhlIGZldGNoZWQgcnVuKTsgdGhlIGZhc3QgcGF0aCdzIHN0b3JlZCBjb250ZXh0IGNhcnJpZXMgbm8gc3RhdHVzLCBzb1xuICogc2VhbC9zZXJpYWxpemF0aW9uIHdvcmsgbWF5IHJ1biBiZWZvcmUgdGhlIHJlY2VpdmluZyBzaWRlIHJlamVjdHNcbiAqIGBob29rX3JlY2VpdmVkYCBmb3IgYW4gZW5kZWQgcnVuLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlSG9va1Jlc3VtZUluZm8oaG9vazogSG9vayk6IFByb21pc2U8SG9va1Jlc3VtZUluZm8+IHtcbiAgaWYgKGhvb2sucmVzdW1lQ29udGV4dCkge1xuICAgIHJldHVybiB7IHJlc3VtZUNvbnRleHQ6IGhvb2sucmVzdW1lQ29udGV4dCwgc291cmNlOiAnaG9vaycgfTtcbiAgfVxuICBjb25zdCBydW4gPSBhd2FpdCAoYXdhaXQgZ2V0V29ybGRMYXp5KCkpLnJ1bnMuZ2V0KGhvb2sucnVuSWQpO1xuICByZXR1cm4ge1xuICAgIHJlc3VtZUNvbnRleHQ6IHJlc3VtZUNvbnRleHRGcm9tUnVuKHJ1biksXG4gICAgc291cmNlOiAncnVuX2ZhbGxiYWNrJyxcbiAgICBydW4sXG4gIH07XG59XG5cbi8qKlxuICogUmVzb2x2ZSB0aGUgcnVuJ3Mgc3ltbWV0cmljIGtleSBmb3IgYSBwYXlsb2FkIFdSSVRFLCBhcyBhIGJhcmUgYENyeXB0b0tleWBcbiAqIChgaW1wb3J0S2V5YCk6IHRoZSBgZW5jcmAgd3JpdGUgZmFsbGJhY2sgdXNlZCB3aGVuIHRoZSBydW4gcHVibGlzaGVkIG5vXG4gKiBwdWJsaWMga2V5IHRvIHNlYWwgdG8uIFdyaXRpbmcgbmVlZHMgb25seSB0aGUgQUVTIGtleSwgbm90IHRoZSByZWFkLXNpZGVcbiAqIGtleXBhaXIuIE9uIHRoZSBmYXN0IHBhdGggdGhpcyBuZWVkcyBvbmx5IGBydW5JZGAgKyBgZGVwbG95bWVudElkYCAobm8gcnVuXG4gKiBlbnRpdHkpOyBvbiB0aGUgZmFsbGJhY2sgcGF0aCB0aGUgYWxyZWFkeSBmZXRjaGVkIHJ1biBpcyByZXVzZWQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVIb29rRW5jcnlwdGlvbktleShcbiAgaG9vazogSG9vayxcbiAgaW5mbzogSG9va1Jlc3VtZUluZm9cbik6IFByb21pc2U8QXdhaXRlZDxSZXR1cm5UeXBlPHR5cGVvZiBpbXBvcnRLZXk+PiB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCB3b3JsZCA9IGF3YWl0IGdldFdvcmxkTGF6eSgpO1xuICBjb25zdCByYXdLZXkgPSBpbmZvLnJ1blxuICAgID8gYXdhaXQgd29ybGQuZ2V0RW5jcnlwdGlvbktleUZvclJ1bj8uKGluZm8ucnVuKVxuICAgIDogYXdhaXQgd29ybGQuZ2V0RW5jcnlwdGlvbktleUZvclJ1bj8uKGhvb2sucnVuSWQsIHtcbiAgICAgICAgZGVwbG95bWVudElkOiBpbmZvLnJlc3VtZUNvbnRleHQuZGVwbG95bWVudElkLFxuICAgICAgfSk7XG4gIHJldHVybiByYXdLZXkgPyBhd2FpdCBpbXBvcnRLZXkocmF3S2V5KSA6IHVuZGVmaW5lZDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0SG9va0J5VG9rZW5XaXRoS2V5KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPHtcbiAgaG9vazogSG9vaztcbiAgZW5jcnlwdGlvbktleTogUGF5bG9hZEtleSB8IHVuZGVmaW5lZDtcbn0+IHtcbiAgY29uc3Qgd29ybGQgPSBhd2FpdCBnZXRXb3JsZExhenkoKTtcbiAgY29uc3QgaG9vayA9IGF3YWl0IHdvcmxkLmhvb2tzLmdldEJ5VG9rZW4odG9rZW4pO1xuXG4gIC8vIE9ubHkgYSBob29rIHRoYXQgYWN0dWFsbHkgY2FycmllcyBtZXRhZGF0YSBuZWVkcyB0aGUgcnVuJ3Mga2V5IHJlc29sdmVkXG4gIC8vIGhlcmU6IGh5ZHJhdGluZyB0aGF0IG1ldGFkYXRhIGlzIGEgUkVBRCwgc28gZGVyaXZlIHRoZSBmdWxsIFJ1blBheWxvYWRLZXlzXG4gIC8vICh3aGljaCBvcGVucyBzZWFsZWQgYGVuY3BgIG1ldGFkYXRhLCBub3QganVzdCBzeW1tZXRyaWMgYGVuY3JgKS4gVGhlIGNvbW1vblxuICAvLyBkZWZhdWx0IHdlYmhvb2sgKGNyZWF0ZVdlYmhvb2soKSB3aXRoIG5vIGByZXNwb25kV2l0aGApIHN0b3JlcyBub1xuICAvLyBtZXRhZGF0YSwgc28gaXQgc2tpcHMgdGhpcyBlbnRpcmVseTogbm8gfjM1MG1zIGBydW4ta2V5YCBBUEkgcm91bmQgdHJpcCxcbiAgLy8gYW5kLCBjcnVjaWFsbHksIG5vIHJlc29sdmVkIGtleSBoYW5kZWQgdG8gYHJlc3VtZUhvb2tgLCBsZWF2aW5nIGl0IGZyZWUgdG9cbiAgLy8gc2VhbCB0aGUgcGF5bG9hZCB0byB0aGUgcnVuJ3MgcHVibGlzaGVkIHB1YmxpYyBrZXkgaW5zdGVhZC4gTWV0YWRhdGEtXG4gIC8vIGJlYXJpbmcgd2ViaG9va3Mgc3RpbGwgbGVnaXRpbWF0ZWx5IHBheSBvbmUgbG9va3VwIHRvIGh5ZHJhdGUuXG4gIGxldCBlbmNyeXB0aW9uS2V5OiBQYXlsb2FkS2V5IHwgdW5kZWZpbmVkO1xuICBpZiAodHlwZW9mIGhvb2subWV0YWRhdGEgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgY29uc3QgaW5mbyA9IGF3YWl0IHJlc29sdmVIb29rUmVzdW1lSW5mbyhob29rKTtcbiAgICAvLyBPbiB0aGUgZmFzdCBwYXRoIHRoaXMgcmVzb2x2ZXMgdGhlIGtleSBieSBydW5JZCArIGRlcGxveW1lbnRJZCAobm8gcnVuXG4gICAgLy8gcmVhZCk7IG9uIHRoZSBmYWxsYmFjayBwYXRoIGl0IHJldXNlcyB0aGUgYWxyZWFkeS1mZXRjaGVkIHJ1bi5cbiAgICBjb25zdCByYXdLZXkgPSBpbmZvLnJ1blxuICAgICAgPyBhd2FpdCB3b3JsZC5nZXRFbmNyeXB0aW9uS2V5Rm9yUnVuPy4oaW5mby5ydW4pXG4gICAgICA6IGF3YWl0IHdvcmxkLmdldEVuY3J5cHRpb25LZXlGb3JSdW4/Lihob29rLnJ1bklkLCB7XG4gICAgICAgICAgZGVwbG95bWVudElkOiBpbmZvLnJlc3VtZUNvbnRleHQuZGVwbG95bWVudElkLFxuICAgICAgICB9KTtcbiAgICBlbmNyeXB0aW9uS2V5ID0gcmF3S2V5ID8gYXdhaXQgZGVyaXZlUnVuUGF5bG9hZEtleXMocmF3S2V5KSA6IHVuZGVmaW5lZDtcbiAgICBob29rLm1ldGFkYXRhID0gYXdhaXQgaHlkcmF0ZVN0ZXBBcmd1bWVudHMoXG4gICAgICBob29rLm1ldGFkYXRhIGFzIGFueSxcbiAgICAgIGhvb2sucnVuSWQsXG4gICAgICBlbmNyeXB0aW9uS2V5XG4gICAgKTtcbiAgfVxuICByZXR1cm4geyBob29rLCBlbmNyeXB0aW9uS2V5IH07XG59XG5cbi8qKlxuICogR2V0IHRoZSBob29rIGJ5IHRva2VuIHRvIGZpbmQgdGhlIGFzc29jaWF0ZWQgd29ya2Zsb3cgcnVuLFxuICogYW5kIGh5ZHJhdGUgdGhlIGBtZXRhZGF0YWAgcHJvcGVydHkgaWYgaXQgd2FzIHNldCBmcm9tIHdpdGhpblxuICogdGhlIHdvcmtmbG93IHJ1bi5cbiAqXG4gKiBBIEhvb2sga2VwdCBieSBtaW5pbXVtIHJldGVudGlvbiByZW1haW5zIGF2YWlsYWJsZSBoZXJlIGFmdGVyIGl0cyBydW4gZW5kcyxcbiAqIGJ1dCBjYW5ub3QgYmUgcmVzdW1lZC5cbiAqXG4gKiBAcGFyYW0gdG9rZW4gLSBUaGUgdW5pcXVlIHRva2VuIGlkZW50aWZ5aW5nIHRoZSBob29rXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRIb29rQnlUb2tlbih0b2tlbjogc3RyaW5nKTogUHJvbWlzZTxIb29rPiB7XG4gIGNvbnN0IHsgaG9vayB9ID0gYXdhaXQgZ2V0SG9va0J5VG9rZW5XaXRoS2V5KHRva2VuKTtcbiAgcmV0dXJuIGhvb2s7XG59XG5cbi8qKlxuICogVGhlIHJlc3VsdCBvZiB7QGxpbmsgcmVzdW1lSG9va306IGEge0BsaW5rIEhvb2t9IGF1Z21lbnRlZCB3aXRoIGFuIG9wdGlvbmFsXG4gKiByZXNpbGllbmNlIHNpZ25hbC5cbiAqXG4gKiBgcmVzaWxpZW50UmVzdW1lYCBpcyByZXRhaW5lZCBmb3Igc291cmNlIGNvbXBhdGliaWxpdHkgYW5kIGlzIG5ldmVyIHNldC5cbiAqIGByZXN1bWVIb29rKClgIG5vdyByZXF1aXJlcyB0aGUgZHVyYWJsZSBgaG9va19yZWNlaXZlZGAgd3JpdGUgYW5kIHdvcmtmbG93XG4gKiB3YWtlIHRvIGJvdGggc3VjY2VlZCBiZWZvcmUgaXQgcmVzb2x2ZXMuIFRyZWF0IHRoZSByZXN1bHQgYXMgYSBwbGFpblxuICoge0BsaW5rIEhvb2t9LlxuICovXG5leHBvcnQgdHlwZSBSZXN1bWVkSG9vayA9IEhvb2sgJiB7IHJlc2lsaWVudFJlc3VtZT86IGJvb2xlYW4gfTtcblxuLyoqXG4gKiBSZXN1bWVzIGEgd29ya2Zsb3cgcnVuIGJ5IHNlbmRpbmcgYSBwYXlsb2FkIHRvIGEgaG9vayBpZGVudGlmaWVkIGJ5IGl0cyB0b2tlbi5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBleHRlcm5hbGx5IChlLmcuLCBmcm9tIGFuIEFQSSByb3V0ZSBvciBzZXJ2ZXIgYWN0aW9uKVxuICogdG8gc2VuZCBkYXRhIHRvIGEgaG9vayBhbmQgcmVzdW1lIHRoZSBhc3NvY2lhdGVkIHdvcmtmbG93IHJ1bi5cbiAqXG4gKiBSZXNvbHZpbmcgbWVhbnMgQk9USCB0aGF0IHRoZSBgaG9va19yZWNlaXZlZGAgZXZlbnQgaXMgZHVyYWJseSByZWNvcmRlZCBpblxuICogdGhlIHJ1bidzIGV2ZW50IGxvZyBhbmQgdGhhdCB0aGUgd29ya2Zsb3cgd2FrZSB3YXMgYWNjZXB0ZWQgYnkgdGhlIHF1ZXVlLCBpblxuICogdGhhdCBvcmRlci4gQSB7QGxpbmsgSG9va05vdEZvdW5kRXJyb3J9IG1lYW5zIHRoaXMgaW52b2NhdGlvbiBjb21taXR0ZWQgbm9cbiAqIGV2ZW50LiBBbnkgb3RoZXIgZXJyb3IgYWZ0ZXIgdGhlIHdyaXRlIGlzIGFtYmlndW91cyBvbmx5IGluIGRpc3BhdGNoLCBuZXZlclxuICogaW4gZHVyYWJpbGl0eTogdGhlIGV2ZW50IG1heSBhbHJlYWR5IGJlIGNvbW1pdHRlZCwgYW5kIGEgbGF0ZXIgd2FrZSBvZiB0aGVcbiAqIHJ1biAoZnJvbSBhbnkgc291cmNlKSB3aWxsIGRlbGl2ZXIgaXQuXG4gKlxuICogUHJlZmVyIHBhc3NpbmcgdGhlIHRva2VuIHN0cmluZyBvdmVyIGEgY2FjaGVkIHtAbGluayBIb29rfSBvYmplY3QuIEEgdG9rZW5cbiAqIGlzIGxvb2tlZCB1cCBmcmVzaCwgc28gdGhlIGxpdmUgYmFja2VuZCBjYW4gYXR0ZXN0IGl0cyBhdG9taWMgcmVzdW1lIGNsYWltXG4gKiBhbmQgdGhlIGR1cmFibGUgd3JpdGUgYmVjb21lcyBpZGVtcG90ZW50LW9uLXJldHJ5ICh0cmFuc3BvcnQgcmV0cmllcyBvZiB0aGVcbiAqIHNhbWUgd3JpdGUgY29udmVyZ2Ugb24gb25lIGV2ZW50KS4gQSBzdXBwbGllZCBIb29rIG9iamVjdCBtYXkgY2FycnkgYSBzdGFsZVxuICogYXR0ZXN0YXRpb24sIHNvIGl0IGlzIGRlbGliZXJhdGVseSBpZ25vcmVkIGFuZCB0aGUgd3JpdGUgaXMgY2xhaW0tbGVzcyDigJRcbiAqIG1lYW5pbmcgYSBsb3N0IHJlc3BvbnNlIGNhbm5vdCBiZSByZXRyaWVkIHNhZmVseTogcmV0cnlpbmcgYXQgdGhlXG4gKiBhcHBsaWNhdGlvbiBsZXZlbCBtaW50cyBhIGZyZXNoIGNsYWltIGFuZCBjYW4gY29tbWl0IGEgc2Vjb25kXG4gKiBgaG9va19yZWNlaXZlZGAuXG4gKlxuICogQHBhcmFtIHRva2VuT3JIb29rIC0gVGhlIHVuaXF1ZSB0b2tlbiBpZGVudGlmeWluZyB0aGUgaG9vaywgb3IgdGhlIGhvb2sgb2JqZWN0IGl0c2VsZlxuICogQHBhcmFtIHBheWxvYWQgLSBUaGUgZGF0YSBwYXlsb2FkIHRvIHNlbmQgdG8gdGhlIGhvb2tcbiAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSB7QGxpbmsgUmVzdW1lZEhvb2t9XG4gKiBAdGhyb3dzIHtIb29rTm90Rm91bmRFcnJvcn0gSWYgdGhlIEhvb2sgZG9lcyBub3QgZXhpc3Qgb3IgaXRzIHJ1biBoYXMgZW5kZWRcbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqIGBgYHRzXG4gKiAvLyBJbiBhbiBBUEkgcm91dGVcbiAqIGltcG9ydCB7IHJlc3VtZUhvb2sgfSBmcm9tICdAd29ya2Zsb3cvY29yZS9ydW50aW1lJztcbiAqXG4gKiBleHBvcnQgYXN5bmMgZnVuY3Rpb24gUE9TVChyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gKiAgIGNvbnN0IHsgdG9rZW4sIGRhdGEgfSA9IGF3YWl0IHJlcXVlc3QuanNvbigpO1xuICpcbiAqICAgdHJ5IHtcbiAqICAgICBjb25zdCBob29rID0gYXdhaXQgcmVzdW1lSG9vayh0b2tlbiwgZGF0YSk7XG4gKiAgICAgcmV0dXJuIFJlc3BvbnNlLmpzb24oeyBydW5JZDogaG9vay5ydW5JZCB9KTtcbiAqICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAqICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKCdIb29rIG5vdCBmb3VuZCcsIHsgc3RhdHVzOiA0MDQgfSk7XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzdW1lSG9vazxUID0gYW55PihcbiAgdG9rZW5Pckhvb2s6IHN0cmluZyB8IEhvb2ssXG4gIHBheWxvYWQ6IFQsXG4gIGVuY3J5cHRpb25LZXlPdmVycmlkZT86IFBheWxvYWRLZXlcbik6IFByb21pc2U8UmVzdW1lZEhvb2s+IHtcbiAgLy8gUHVibGljIGVudHJ5IHBvaW50LiBJdCBuZXZlciBhdHRlc3RzIGhvb2sgZnJlc2huZXNzLCBzbyBhIEhvb2sgb2JqZWN0XG4gIC8vIHN1cHBsaWVkIGhlcmUgKHdoaWNoIG1heSBjYXJyeSBhIGByZXN1bWVDYXBhYmlsaXRpZXNgIGNhY2hlZCBiZWZvcmUgYVxuICAvLyBzZXJ2ZXIgcm9sbGJhY2sgb3Iga2lsbCBzd2l0Y2gpIGlzIGlnbm9yZWQgYnkgdGhlIGR5bmFtaWMtZGVkdXAgZ2F0ZSBhbmRcbiAgLy8gZmFpbHMgY2xvc2VkIHRvIGEgcGxhaW4sIGNsYWltLWxlc3Mgd3JpdGUuIE9ubHkgYHJlc3VtZVdlYmhvb2tgLCB3aGljaFxuICAvLyBmZXRjaGVzIHRoZSBob29rIGJ5IHRva2VuIGluLWxpbmUgZHVyaW5nIHRoZSBzYW1lIHJlc3VtZSwgcmVhY2hlcyB0aGVcbiAgLy8gaW50ZXJuYWwgaW1wbGVtZW50YXRpb24gd2l0aCB0aGUgZnJlc2ggYXR0ZXN0YXRpb24gc2V0LiBLZWVwaW5nIHRoZVxuICAvLyBmcmVzaG5lc3MgZmxhZyBvZmYgdGhlIGV4cG9ydGVkIHNpZ25hdHVyZSBwcmV2ZW50cyBhIGNhbGxlciBmcm9tIHBhc3NpbmcgYVxuICAvLyBzdGFsZSBIb29rIHBsdXMgYHRydWVgIGFuZCByZWFjdGl2YXRpbmcgZHluYW1pYyBkZWR1cCBhZ2FpbnN0IGFcbiAgLy8gcm9sbGVkLWJhY2sgYmFja2VuZC5cbiAgLy9cbiAgLy8gVDAgb2YgdGhlIGhvb2stcmVzdW1lIFRUUiB3aW5kb3cgaXMgdGFrZW4gSEVSRSwgYXQgdGhlIHB1YmxpYyBlbnRyeSBwb2ludCxcbiAgLy8gcmF0aGVyIHRoYW4gaW5zaWRlIHRoZSBpbXBsZW1lbnRhdGlvbjsgc2VlIHRoZSBwYXJhbWV0ZXIncyBkb2MgY29tbWVudC5cbiAgcmV0dXJuIHJlc3VtZUhvb2tJbXBsKFxuICAgIHRva2VuT3JIb29rLFxuICAgIHBheWxvYWQsXG4gICAgZW5jcnlwdGlvbktleU92ZXJyaWRlLFxuICAgIGZhbHNlLFxuICAgIERhdGUubm93KClcbiAgKTtcbn1cblxuLyoqXG4gKiBJbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgcmVzdW1lSG9va30uIE5PVCBleHBvcnRlZDogdGhlXG4gKiBgaG9va0ZyZXNobHlMb29rZWRVcGAgYXR0ZXN0YXRpb24gbXVzdCBuZXZlciBiZSByZWFjaGFibGUgYnkgcHVibGljIGNhbGxlcnNcbiAqIChzZWUgdGhlIHdyYXBwZXIgYWJvdmUpLlxuICpcbiAqIEBwYXJhbSBob29rRnJlc2hseUxvb2tlZFVwIC0gQXR0ZXN0cyB0aGF0IGEgc3VwcGxpZWQgSG9vayBvYmplY3Qgd2FzIGZldGNoZWRcbiAqICAgYnkgdG9rZW4gZHVyaW5nIFRISVMgcmVzdW1lLCBzbyBpdHMgcmVzcG9uc2Utb25seSBgcmVzdW1lQ2FwYWJpbGl0aWVzYFxuICogICByZWZsZWN0cyB0aGUgbGl2ZSBiYWNrZW5kIGFuZCBtYXkgYmUgdHJ1c3RlZCBmb3IgdGhlIGR5bmFtaWMtZGVkdXAgZ2F0ZS5cbiAqICAgQSB0b2tlbiBzdHJpbmcgaXMgYWx3YXlzIGZldGNoZWQgZnJlc2ggaGVyZSwgc28gaXQgaXMgaW1wbGljaXRseSBmcmVzaC5cbiAqIEBwYXJhbSByZXN1bWVSZXF1ZXN0ZWRBdE1zIC0gVDAgb2YgdGhlIGhvb2stcmVzdW1lIFRUUiB3aW5kb3cgKHNlZVxuICogICBydW50aW1lL3Jlc3VtZS1sYXRlbmN5LnRzKSwgc3RhbXBlZCBieSB0aGUgUFVCTElDIGVudHJ5IHBvaW50IHRoZSBjYWxsZXJcbiAqICAgdXNlZC4gSXQgaXMgYSBwYXJhbWV0ZXIgcmF0aGVyIHRoYW4gYSBsb2NhbCBiZWNhdXNlIGByZXN1bWVXZWJob29rYCBkb2VzXG4gKiAgIHJlYWwgd29yayBiZWZvcmUgaXQgZ2V0cyBoZXJlICh0aGUgYnktdG9rZW4gbG9va3VwLCB0aGUgcnVuLWtleVxuICogICByZXNvbHV0aW9uIHRoYXQgaHlkcmF0ZXMgaG9vayBtZXRhZGF0YSwgYW5kIHRoZSBgcmVzcG9uZFdpdGhgIHNldHVwKSBhbmRcbiAqICAgc3RhbXBpbmcgbG9jYWxseSB3b3VsZCBzaWxlbnRseSBleGNsdWRlIGFsbCBvZiBpdCwgc28gdGhlIHR3byBlbnRyeSBwb2ludHNcbiAqICAgd291bGQgcmVwb3J0IHRoZSBzYW1lIG1ldHJpYyBvdmVyIGRpZmZlcmVudCB3aW5kb3dzLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXN1bWVIb29rSW1wbDxUID0gYW55PihcbiAgdG9rZW5Pckhvb2s6IHN0cmluZyB8IEhvb2ssXG4gIHBheWxvYWQ6IFQsXG4gIGVuY3J5cHRpb25LZXlPdmVycmlkZTogUGF5bG9hZEtleSB8IHVuZGVmaW5lZCxcbiAgaG9va0ZyZXNobHlMb29rZWRVcDogYm9vbGVhbixcbiAgcmVzdW1lUmVxdWVzdGVkQXRNczogbnVtYmVyXG4pOiBQcm9taXNlPFJlc3VtZWRIb29rPiB7XG4gIHJldHVybiBhd2FpdCB3YWl0ZWRVbnRpbCgoKSA9PiB7XG4gICAgcmV0dXJuIHRyYWNlKCdob29rLnJlc3VtZScsIGFzeW5jIChzcGFuKSA9PiB7XG4gICAgICBjb25zdCB3b3JsZCA9IGF3YWl0IGdldFdvcmxkTGF6eSgpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBzdXBwbGllZFRva2VuID0gdHlwZW9mIHRva2VuT3JIb29rID09PSAnc3RyaW5nJztcbiAgICAgICAgY29uc3QgaG9vazogSG9vayA9IHN1cHBsaWVkVG9rZW5cbiAgICAgICAgICA/IGF3YWl0IHdvcmxkLmhvb2tzLmdldEJ5VG9rZW4odG9rZW5Pckhvb2spXG4gICAgICAgICAgOiB0b2tlbk9ySG9vaztcbiAgICAgICAgLy8gVGhlIGR5bmFtaWMsIHJlc3BvbnNlLW9ubHkgYHJlc3VtZUNhcGFiaWxpdGllc2AgbWF5IG9ubHkgYmUgdHJ1c3RlZFxuICAgICAgICAvLyB3aGVuIGl0IGNhbWUgZnJvbSBhIGJ5LXRva2VuIGxvb2t1cCBwZXJmb3JtZWQgZHVyaW5nIHRoaXMgcmVzdW1lLlxuICAgICAgICBjb25zdCBob29rUmVzdW1lQ2FwYWJpbGl0aWVzQXJlRnJlc2ggPVxuICAgICAgICAgIHN1cHBsaWVkVG9rZW4gfHwgaG9va0ZyZXNobHlMb29rZWRVcDtcblxuICAgICAgICBjb25zdCBpbmZvID0gYXdhaXQgcmVzb2x2ZUhvb2tSZXN1bWVJbmZvKGhvb2spO1xuICAgICAgICBjb25zdCB7IHJlc3VtZUNvbnRleHQgfSA9IGluZm87XG5cbiAgICAgICAgc3Bhbj8uc2V0QXR0cmlidXRlcyh7XG4gICAgICAgICAgLi4uQXR0cmlidXRlLkhvb2tUb2tlbihob29rLnRva2VuKSxcbiAgICAgICAgICAuLi5BdHRyaWJ1dGUuSG9va0lkKGhvb2suaG9va0lkKSxcbiAgICAgICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dSdW5JZChob29rLnJ1bklkKSxcbiAgICAgICAgICAnd29ya2Zsb3cuaG9vay5yZXN1bWVfY29udGV4dF9zb3VyY2UnOiBpbmZvLnNvdXJjZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVGhlIHN0b3JlZCBgcmVzdW1lQ29udGV4dGAgaW50ZW50aW9uYWxseSBvbWl0cyB0aGUgcnVuJ3MgbXV0YWJsZVxuICAgICAgICAvLyBzdGF0dXMsIHNvIHRoaXMgZWFybHkgY2xpZW50LXNpZGUgcmVqZWN0aW9uIG9ubHkgcnVucyBvbiB0aGVcbiAgICAgICAgLy8gZmFsbGJhY2sgcGF0aCAod2hpY2ggZmV0Y2hlZCB0aGUgcnVuKS4gT24gdGhlIGZhc3QgcGF0aCB0aGUgdGVybWluYWxcbiAgICAgICAgLy8gY2hlY2sgaGFwcGVucyBzZXJ2ZXItc2lkZTogYGhvb2tfcmVjZWl2ZWRgIGFnYWluc3QgYW4gZW5kZWQgcnVuIGlzXG4gICAgICAgIC8vIHJlamVjdGVkLCB3aGljaCB0aGUgY2F0Y2ggYXJvdW5kIGB3b3JsZC5ldmVudHMuY3JlYXRlYCBiZWxvdyByZS1rZXlzXG4gICAgICAgIC8vIHRvIEhvb2tOb3RGb3VuZEVycm9yOiBzYW1lIHB1YmxpYyBjb250cmFjdCwgbm8gcnVuIHByZS1mZXRjaC5cbiAgICAgICAgaWYgKGluZm8ucnVuICYmIGlzVGVybWluYWxXb3JrZmxvd1J1blN0YXR1cyhpbmZvLnJ1bi5zdGF0dXMpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEhvb2tOb3RGb3VuZEVycm9yKGhvb2sudG9rZW4pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgdGhlIHRhcmdldCBydW4ncyBjYXBhYmlsaXRpZXMgdG8gZW5zdXJlIHdlIGVuY29kZSB0aGVcbiAgICAgICAgLy8gcGF5bG9hZCBpbiBhIGZvcm1hdCB0aGUgcnVuJ3MgZGVwbG95bWVudCBjYW4gZGVjb2RlLiBGb3IgZXhhbXBsZSxcbiAgICAgICAgLy8gcnVucyBjcmVhdGVkIGJlZm9yZSBlbmNyeXB0aW9uIHN1cHBvcnQgd2FzIGFkZGVkIGNhbm5vdCBkZWNvZGVcbiAgICAgICAgLy8gdGhlICdlbmNyJyBzZXJpYWxpemF0aW9uIGZvcm1hdCwgYW5kIHJ1bnMgY3JlYXRlZCBiZWZvcmVcbiAgICAgICAgLy8gYnl0ZS1zdHJlYW0gZnJhbWluZyBzdXBwb3J0IGNhbm5vdCBkZWNvZGUgZnJhbWVkIGJ5dGUgc3RyZWFtcy5cbiAgICAgICAgY29uc3QgY2FwYWJpbGl0aWVzID0gZ2V0UnVuQ2FwYWJpbGl0aWVzKFxuICAgICAgICAgIHJlc3VtZUNvbnRleHQud29ya2Zsb3dDb3JlVmVyc2lvblxuICAgICAgICApO1xuXG4gICAgICAgIC8vIFJlc29sdmUgaG93IHRvIGVuY3J5cHQgdGhlIHBheWxvYWQgZm9yIHRoZSB0YXJnZXQgcnVuIChhIFdSSVRFKS5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gUHJlZmVycmVkIHBhdGg6IHNlYWwgdG8gdGhlIHJ1bidzIHB1Ymxpc2hlZCBYMjU1MTkgcHVibGljIGtleSwgd2hpY2hcbiAgICAgICAgLy8gdGhlIHN0b3JlZCBgcmVzdW1lQ29udGV4dGAgY2FycmllcyBpbmxpbmUuIE9uIHRoZSBmYXN0IHBhdGggdGhpcyBpc1xuICAgICAgICAvLyB0aGUgd2hvbGUgd2luOiBubyBydW4gcmVhZCBBTkQgbm8gYGdldEVuY3J5cHRpb25LZXlGb3JSdW5gLCB3aG9zZVxuICAgICAgICAvLyB+MzUwbXMgYHJ1bi1rZXlgIEFQSSByb3VuZCB0cmlwIGRvbWluYXRlcyBjcm9zcy1kZXBsb3ltZW50IGhvb2tcbiAgICAgICAgLy8gcmVzdW1wdGlvbiBsYXRlbmN5LiAoT24gdGhlIGZhbGxiYWNrIHBhdGggdGhlIGtleSBpcyBzeW50aGVzaXplZFxuICAgICAgICAvLyBmcm9tIHRoZSBmZXRjaGVkIHJ1biwgd2hpY2ggYWxzbyBjYXJyaWVzIGl0LilcbiAgICAgICAgLy9cbiAgICAgICAgLy8gU2VhbGluZyBhbHNvIGRyb3BzIHByaXZpbGVnZTogdGhlIHJlc3VtZXIgZW5kcyB1cCBhYmxlIHRvIHdyaXRlIGFcbiAgICAgICAgLy8gcGF5bG9hZCBmb3IgdGhlIHJ1biB3aXRob3V0IGJlaW5nIGFibGUgdG8gcmVhZCBhbnl0aGluZyBvZiB0aGVcbiAgICAgICAgLy8gcnVuJ3MsIHdoZXJlIGZldGNoaW5nIHRoZSBzeW1tZXRyaWMga2V5IGdyYW50cyBib3RoLlxuICAgICAgICAvL1xuICAgICAgICAvLyBEZWxpYmVyYXRlbHkgTk9UIGdhdGVkIG9uIGBjYXBhYmlsaXRpZXMuc3VwcG9ydGVkRm9ybWF0c2AgdGhlIHdheVxuICAgICAgICAvLyB0aGUgc3ltbWV0cmljIGZhbGxiYWNrIGJlbG93IGdhdGVzIGBlbmNyYDogcHJlc2VuY2Ugb2YgdGhlIHB1YmxpYyBrZXlcbiAgICAgICAgLy8gaXMgaXRzZWxmIHRoZSBnYXRlLiBBIHJ1biBvbmx5IGNhcnJpZXMgb25lIGlmIHRoZSBydW50aW1lIHRoYXRcbiAgICAgICAgLy8gY3JlYXRlZCBpdCBjb3VsZCBhbHNvIG9wZW4gYSBzZWFsZWQgcGF5bG9hZCwgYW5kIHJ1bnMgYXJlIHBpbm5lZCB0b1xuICAgICAgICAvLyB0aGVpciBjcmVhdGluZyBkZXBsb3ltZW50LCBzbyBwcmVzZW5jZSBpcyBhIG1vcmUgcmVsaWFibGUgYXR0ZXN0YXRpb25cbiAgICAgICAgLy8gdGhhbiBhIHZlcnNpb24gY29tcGFyZSwgYW5kIGl0IHN0YXlzIGNvcnJlY3QgZXZlbiB3aGVuIHBhY2thZ2VcbiAgICAgICAgLy8gdmVyc2lvbnMgZHJpZnQuXG4gICAgICAgIGxldCBwYXlsb2FkS2V5OiBQYXlsb2FkS2V5IHwgdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBydW5QdWJsaWNLZXkgPSBlbmNyeXB0aW9uS2V5T3ZlcnJpZGVcbiAgICAgICAgICA/IC8vIFRoZSBjYWxsZXIgYWxyZWFkeSBob2xkcyBhIGtleSAocmVzdW1lV2ViaG9vayByZXNvbHZlZCBvbmUgdG9cbiAgICAgICAgICAgIC8vIGh5ZHJhdGUgaG9vayBtZXRhZGF0YSksIHNvIHNlYWxpbmcgd291bGQgYWRkIGFuIEVDREggZm9yIG5vXG4gICAgICAgICAgICAvLyBzYXZlZCByb3VuZCB0cmlwLiBSZXVzZSB3aGF0IGl0IHJlc29sdmVkLlxuICAgICAgICAgICAgdW5kZWZpbmVkXG4gICAgICAgICAgOiBkZWNvZGVSdW5QdWJsaWNLZXkocmVzdW1lQ29udGV4dC5lbmNyeXB0aW9uUHVibGljS2V5KTtcblxuICAgICAgICBpZiAocnVuUHVibGljS2V5KSB7XG4gICAgICAgICAgcGF5bG9hZEtleSA9IHNlYWxUbyhydW5QdWJsaWNLZXkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFN5bW1ldHJpYyBgZW5jcmAgd3JpdGUgZmFsbGJhY2s6IG5lZWRzIG9ubHkgdGhlIEFFUyBrZXlcbiAgICAgICAgICAvLyAoYSBiYXJlIENyeXB0b0tleSB2aWEgYHJlc29sdmVIb29rRW5jcnlwdGlvbktleWApLCBub3QgdGhlXG4gICAgICAgICAgLy8gcmVhZC1zaWRlIFJ1blBheWxvYWRLZXlzLlxuICAgICAgICAgIGxldCBlbmNyeXB0aW9uS2V5ID1cbiAgICAgICAgICAgIGVuY3J5cHRpb25LZXlPdmVycmlkZSA/P1xuICAgICAgICAgICAgKGF3YWl0IHJlc29sdmVIb29rRW5jcnlwdGlvbktleShob29rLCBpbmZvKSk7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIWNhcGFiaWxpdGllcy5zdXBwb3J0ZWRGb3JtYXRzLmhhcyhTZXJpYWxpemF0aW9uRm9ybWF0LkVOQ1JZUFRFRClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGVuY3J5cHRpb25LZXkgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIHBheWxvYWRLZXkgPSBlbmNyeXB0aW9uS2V5O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ29tcHJlc3Mgb25seSB3aGVuIHRoZSB0YXJnZXQgcnVuIGFuZCBpdHMgZGVwbG95bWVudCBzdXBwb3J0IHRoZVxuICAgICAgICAvLyBjb21wcmVzc2lvbiBmb3JtYXRzIGludHJvZHVjZWQgd2l0aCBzcGVjIHZlcnNpb24gNS5cbiAgICAgICAgY29uc3QgY29tcHJlc3Npb24gPVxuICAgICAgICAgIChyZXN1bWVDb250ZXh0LnJ1blNwZWNWZXJzaW9uID8/IDApID49XG4gICAgICAgICAgICBTUEVDX1ZFUlNJT05fU1VQUE9SVFNfQ09NUFJFU1NJT04gJiZcbiAgICAgICAgICBjYXBhYmlsaXRpZXMuc3VwcG9ydGVkRm9ybWF0cy5oYXMoU2VyaWFsaXphdGlvbkZvcm1hdC5HWklQKTtcblxuICAgICAgICAvLyBEZWh5ZHJhdGUgdGhlIHBheWxvYWQgZm9yIHN0b3JhZ2VcbiAgICAgICAgY29uc3Qgb3BzOiBQcm9taXNlPGFueT5bXSA9IFtdO1xuICAgICAgICBjb25zdCByZWFkYmFja09wczogUHJvbWlzZTxhbnk+W10gPSBbXTtcbiAgICAgICAgY29uc3QgdjFDb21wYXQgPSBpc0xlZ2FjeVNwZWNWZXJzaW9uKGhvb2suc3BlY1ZlcnNpb24pO1xuICAgICAgICBjb25zdCBkZWh5ZHJhdGVkUGF5bG9hZCA9IGF3YWl0IGRlaHlkcmF0ZVN0ZXBSZXR1cm5WYWx1ZShcbiAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICAgIGhvb2sucnVuSWQsXG4gICAgICAgICAgcGF5bG9hZEtleSxcbiAgICAgICAgICBvcHMsXG4gICAgICAgICAgZ2xvYmFsVGhpcyxcbiAgICAgICAgICB2MUNvbXBhdCxcbiAgICAgICAgICBjYXBhYmlsaXRpZXMuZnJhbWVkQnl0ZVN0cmVhbXMsXG4gICAgICAgICAgY29tcHJlc3Npb24sXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIHJlYWRiYWNrT3BzXG4gICAgICAgICk7XG4gICAgICAgIC8vIEEgaG9va19yZWNlaXZlZCBldmVudCBpcyBub3QgZHVyYWJsZSB3aGlsZSBpdHMgcGF5bG9hZCBzdGlsbCBwb2ludHNcbiAgICAgICAgLy8gYXQgc3RyZWFtIHVwbG9hZHMgaW4gZmxpZ2h0LiBGaW5pc2ggdGhvc2UgYmVmb3JlIGNvbW1pdHRpbmcgdGhlXG4gICAgICAgIC8vIGV2ZW50IOKAlCBidXQgT05MWSB0aGUgcHJvZHVjZXItcHVzaCBvcHMgaW4gYG9wc2AuIEEgZGVoeWRyYXRlZFxuICAgICAgICAvLyBXcml0YWJsZVN0cmVhbSBsYW5kcyBpbiBgcmVhZGJhY2tPcHNgIGluc3RlYWQ6IGl0IGlzIGEgc2VydmVyLXN0cmVhbVxuICAgICAgICAvLyBSRUFERVIgdGhhdCByZXNvbHZlcyBvbmx5IG9uY2UgdGhlIHdva2VuIHdvcmtmbG93IHdyaXRlcyBpbnRvIGl0IChhXG4gICAgICAgIC8vIG1hbnVhbCB3ZWJob29rJ3MgYHJlc3BvbnNlV3JpdGFibGVgIGlzIHRoZSBjYW5vbmljYWwgY2FzZSksIHNvXG4gICAgICAgIC8vIGF3YWl0aW5nIGl0IGhlcmUgd291bGQgZGVhZGxvY2sgdGhlIHJlc3VtZSBhZ2FpbnN0IGl0cyBvd24gd2FrZS5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gQSByZWplY3Rpb24gd2l0aCBgdW5kZWZpbmVkYCBpcyBhbiBleHBlY3RlZCBhcnRpZmFjdCBvZiB0aGUgd2ViaG9va1xuICAgICAgICAvLyBidW5kbGUgYW5kIHdhcyBoaXN0b3JpY2FsbHkgaWdub3JlZCBieSB0aGUgYmFja2dyb3VuZCBmbHVzaC4gS2VlcFxuICAgICAgICAvLyB0aGF0IHRvbGVyYW5jZSBub3cgdGhhdCB0aGUgZmx1c2ggaXMgYXdhaXRlZCBpbmxpbmUuXG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgIG9wcy5tYXAoKG9wKSA9PlxuICAgICAgICAgICAgb3AuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChlcnJvciAhPT0gdW5kZWZpbmVkKSB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgICAvLyBSZWFkYmFjayBwaXBlcyAobm90YWJseSBhIG1hbnVhbCB3ZWJob29rIHJlc3BvbnNlIHdyaXRhYmxlKSBjYW4gb25seVxuICAgICAgICAvLyBmaW5pc2ggYWZ0ZXIgdGhlIHdvcmtmbG93IHdha2VzIGFuZCB3cml0ZXMgdG8gdGhlbS4gS2VlcCB0aGVtIGFsaXZlLFxuICAgICAgICAvLyBidXQgbmV2ZXIgcGxhY2UgdGhlbSBpbiB0aGUgZHVyYWJpbGl0eSBiYXJyaWVyIGFib3ZlLlxuICAgICAgICBzYWZlV2FpdFVudGlsKFByb21pc2UuYWxsKHJlYWRiYWNrT3BzKSwgKGVycikgPT4ge1xuICAgICAgICAgIGlmIChlcnIgPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICAgICAgICAgIHJ1bnRpbWVMb2dnZXIud2FybignQmFja2dyb3VuZCByZWFkYmFjayBvZiBob29rIHBheWxvYWQgZmFpbGVkJywge1xuICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogaG9vay5ydW5JZCxcbiAgICAgICAgICAgIGhvb2tJZDogaG9vay5ob29rSWQsXG4gICAgICAgICAgICBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dOYW1lKHJlc3VtZUNvbnRleHQud29ya2Zsb3dOYW1lKSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTGluayB0byB0aGUgcnVuLW9yaWdpbiBjb250ZXh0IGZyb20gdGhlIHN0b3JlZCB0cmFjZSBjYXJyaWVyXG4gICAgICAgIC8vIChza2lwcGVkIHdoZW4gYWJzZW50IG9yIGludmFsaWQpLiBSZXNvbHZlZCBiZWZvcmUgZGlzcGF0Y2ggc28gdGhlXG4gICAgICAgIC8vIHdyaXRlIGFuZCB0aGUgd2FrZSBib3RoIHNpdCB1bmRlciBhIHNwYW4gdGhhdCBjYXJyaWVzIGl0LlxuICAgICAgICBjb25zdCBvcmlnaW5MaW5rID0gYXdhaXQgbGlua1RvVHJhY2VDYXJyaWVyKHJlc3VtZUNvbnRleHQudHJhY2VDYXJyaWVyKTtcbiAgICAgICAgaWYgKG9yaWdpbkxpbmspIHtcbiAgICAgICAgICBzcGFuPy5hZGRMaW5rPy4ob3JpZ2luTGluayk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBxdWV1ZU5hbWUgPSBnZXRXb3JrZmxvd1F1ZXVlTmFtZShyZXN1bWVDb250ZXh0LndvcmtmbG93TmFtZSk7XG4gICAgICAgIGNvbnN0IHF1ZXVlT3B0aW9ucyA9IHtcbiAgICAgICAgICBkZXBsb3ltZW50SWQ6IHJlc3VtZUNvbnRleHQuZGVwbG95bWVudElkLFxuICAgICAgICAgIHNwZWNWZXJzaW9uOiByZXN1bWVDb250ZXh0LnJ1blNwZWNWZXJzaW9uID8/IFNQRUNfVkVSU0lPTl9MRUdBQ1ksXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gVGhlIGRpc3BhdGNoIGlzIHN0cmljdGx5IHNlcmlhbDogdGhlIGhvb2tfcmVjZWl2ZWQgZXZlbnQgaXMgbWFkZVxuICAgICAgICAvLyBkdXJhYmxlIEZJUlNULCBhbmQgdGhlIHdvcmtmbG93IHdha2UgaXMgcHVibGlzaGVkIG9ubHkgYWZ0ZXIgdGhlXG4gICAgICAgIC8vIHdyaXRlIGlzIGFja25vd2xlZGdlZC4gVGhpcyBpcyB3aGF0IGxldHMgYHJlc3VtZUhvb2soKWAgcmVzb2x2aW5nXG4gICAgICAgIC8vIG1lYW4gXCJ0aGUgcmVzdW1lIHN1cnZpdmVzIGFueXRoaW5nIHRoYXQgaGFwcGVucyBuZXh0XCIg4oCUIGEgZGlzcG9zYWxcbiAgICAgICAgLy8gb3IgcnVuIGNvbXBsZXRpb24gcmFjaW5nIHRoZSBxdWV1ZSBkZWxpdmVyeSBjYW5ub3QgZXJhc2UgYSBjb21taXR0ZWRcbiAgICAgICAgLy8gZXZlbnQsIGFuZCB0aGUgd2FrZSBpdHNlbGYgY2FycmllcyBubyBwYXlsb2FkLCBzbyBub3RoaW5nIHJpZGVzIG9uXG4gICAgICAgIC8vIHRoZSBtZXNzYWdlIGJ1dCB0aGUgdHJpZ2dlci5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gQmFja2VuZCBkZWR1cCBpcyBhdHRlc3RlZCB3aGVuIEVJVEhFUiB0aGUgbGl2ZSBzZXJ2ZXIgYXR0ZXN0cyBpdFxuICAgICAgICAvLyBmcmVzaCBvbiB0aGlzIGJ5LXRva2VuIGhvb2sgKHdvcmxkLXZlcmNlbDogcmVzcG9uc2Utb25seSwgcmVjb21wdXRlZFxuICAgICAgICAvLyBldmVyeSByZWFkLCBzbyByb2xsYmFjay9raWxsLXN3aXRjaCB0YWtlIGVmZmVjdCBpbW1lZGlhdGVseSkgT1IgdGhlXG4gICAgICAgIC8vIHN0YXRpYyB3b3JsZCBjYXBhYmlsaXR5IGlzIHNldCAod29ybGQtbG9jYWw6IGFkYXB0ZXIgKyBiYWNrZW5kIHNoaXBcbiAgICAgICAgLy8gdG9nZXRoZXIpLiBXaGVuIGF0dGVzdGVkLCB0aGUgd3JpdGUgY2FycmllcyBhIHBlci1jYWxsIHJlc3VtZUlkICtcbiAgICAgICAgLy8gcGF5bG9hZCBkaWdlc3Qgc28gdHJhbnNwb3J0LWxldmVsIHJldHJpZXMgb2YgdGhlIFNBTUUgd3JpdGUgY29udmVyZ2VcbiAgICAgICAgLy8gb24gZXhhY3RseSBvbmUgY29tbWl0dGVkIGV2ZW50IHZpYSB0aGUgYmFja2VuZCdzIChydW5JZCwgcmVzdW1lSWQpXG4gICAgICAgIC8vIGNvbnN0cmFpbnQuIFdpdGhvdXQgaXQgdGhlIHdyaXRlIGlzIGEgcGxhaW4gc2luZ2xlLXNob3QgY3JlYXRlLFxuICAgICAgICAvLyBleGFjdGx5IGFzIGJlZm9yZSBkZWR1cCBleGlzdGVkLlxuICAgICAgICBjb25zdCBiYWNrZW5kRGVkdXBTdXBwb3J0ZWQgPVxuICAgICAgICAgIChob29rUmVzdW1lQ2FwYWJpbGl0aWVzQXJlRnJlc2hcbiAgICAgICAgICAgID8gKGhvb2sucmVzdW1lQ2FwYWJpbGl0aWVzPy5ob29rUmVzdW1lRGVkdXBWZXJzaW9uID8/IDApXG4gICAgICAgICAgICA6IDApID49IEhPT0tfUkVTVU1FX0RFRFVQX1ZFUlNJT04gfHxcbiAgICAgICAgICB3b3JsZC5jYXBhYmlsaXRpZXM/Lmhvb2tSZXN1bWVEZWR1cCA9PT0gdHJ1ZTtcbiAgICAgICAgY29uc3QgY2FuQ2xhaW1SZXN1bWUgPVxuICAgICAgICAgIGJhY2tlbmREZWR1cFN1cHBvcnRlZCAmJlxuICAgICAgICAgICF2MUNvbXBhdCAmJlxuICAgICAgICAgIGRlaHlkcmF0ZWRQYXlsb2FkIGluc3RhbmNlb2YgVWludDhBcnJheTtcblxuICAgICAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgICAgICAnd29ya2Zsb3cuaG9vay5yZXN1bWVfc3RyYXRlZ3knOiAnc2VxdWVudGlhbCcsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VtZUlkID0gY2FuQ2xhaW1SZXN1bWUgPyBnZW5lcmF0ZVJlc3VtZUlkKCkgOiB1bmRlZmluZWQ7XG4gICAgICAgIGNvbnN0IHBheWxvYWREaWdlc3QgPSBjYW5DbGFpbVJlc3VtZVxuICAgICAgICAgID8gYXdhaXQgY29tcHV0ZVJlc3VtZVBheWxvYWREaWdlc3QoZGVoeWRyYXRlZFBheWxvYWQpXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChyZXN1bWVJZCkge1xuICAgICAgICAgIHNwYW4/LnNldEF0dHJpYnV0ZXMoeyAnd29ya2Zsb3cuaG9vay5yZXN1bWVfaWQnOiByZXN1bWVJZCB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlLWtleSBhbnkgXCJob29rIGNhbiBubyBsb25nZXIgYmUgcmVjZWl2ZWRcIiByZWplY3Rpb24gdG9cbiAgICAgICAgLy8gSG9va05vdEZvdW5kRXJyb3IoaG9vay50b2tlbikgc28gYC50b2tlbmAgbWF0Y2hlcyB0aGUgaGlzdG9yaWNhbFxuICAgICAgICAvLyBjb250cmFjdC4gVGhlIHNwZWNpZmljIGVycm9yIGRlcGVuZHMgb24gdGhlIFdvcmxkOlxuICAgICAgICAvLyAgIC0gYSBnZW51aW5lbHkgbWlzc2luZyBob29rIG1hcHMgdG8gSG9va05vdEZvdW5kRXJyb3IgKGtleWVkIG9uXG4gICAgICAgIC8vICAgICB0aGUgZXZlbnQgY29ycmVsYXRpb25JZCAvIGhvb2sgSUQpO1xuICAgICAgICAvLyAgIC0gYSB0ZXJtaW5hbCBydW4gb24gVmVyY2VsIHJlamVjdHMgaG9va19yZWNlaXZlZCB3aXRoIDQwNCwgd2hpY2hcbiAgICAgICAgLy8gICAgIHdvcmxkLXZlcmNlbCBtYXBzIHRvIEhvb2tOb3RGb3VuZEVycm9yO1xuICAgICAgICAvLyAgIC0gYSB0ZXJtaW5hbCBydW4gb24gd29ybGQtbG9jYWwgLyB3b3JsZC1wb3N0Z3JlcyByZWplY3RzIHdpdGhcbiAgICAgICAgLy8gICAgIFJ1bkV4cGlyZWRFcnJvci5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gQW4gRW50aXR5Q29uZmxpY3RFcnJvciAoSFRUUCA0MDkpIGlzIGRlbGliZXJhdGVseSBOT1QgcmUta2V5ZWQsXG4gICAgICAgIC8vIGJyZWFraW5nIHdpdGggdGhlIGhpc3RvcmljYWwgbWFwcGluZzogZXZlcnkgNDA5IHRoZSBiYWNrZW5kIGVtaXRzXG4gICAgICAgIC8vIG9uIHRoaXMgd3JpdGUgdG9kYXkgaXMgVFJBTlNJRU5UIOKAlCBhIHNsb3QgY29uZmxpY3QgdGhhdCBlc2NhcGVkIHRoZVxuICAgICAgICAvLyBzZXJ2ZXIncyBvd24gcmV0cnkgYnVkZ2V0IHVuZGVyIGNvbnRlbnRpb24sIG9yIGEgcmVzdW1lLWNsYWltIHJhY2VcbiAgICAgICAgLy8gbWlkLXJlc29sdXRpb24g4oCUIGFuZCBpdHMgdHJhbnNhY3Rpb24gY29tbWl0dGVkIG5vdGhpbmcuIFJlLWtleWluZ1xuICAgICAgICAvLyBpdCB0byBIb29rTm90Rm91bmRFcnJvciB0b2xkIHRoZSBjYWxsZXIgKGFuZCBhIHdlYmhvb2sgc2VuZGVyLCB2aWFcbiAgICAgICAgLy8gNDA0KSB0aGF0IGEgcmV0cnlhYmxlIGZhaWx1cmUgd2FzIHBlcm1hbmVudCwgc2lsZW50bHkgZHJvcHBpbmcgdGhlXG4gICAgICAgIC8vIHJlc3VtZS4gSXQgbm93IHN1cmZhY2VzIGFzLWlzOiByZXRyeWFibGUsIHdpdGggbm90aGluZyBjb21taXR0ZWQuXG4gICAgICAgIC8vIChBIDQyMiByZXN1bWVJZC1yZXVzZSBlcnJvciBsaWtld2lzZSBwYXNzZXMgdGhyb3VnaCB1bm1hcHBlZCDigJQgaXRcbiAgICAgICAgLy8gbWVhbnMgdGhlIGNhbGxlciByZXBsYXllZCBhIHJlc3VtZUlkIHdpdGggYSBkaWZmZXJlbnQgcGF5bG9hZCwgYW5kXG4gICAgICAgIC8vIGhpZGluZyB0aGF0IGJlaGluZCBcIm5vdCBmb3VuZFwiIHdvdWxkIG1hc2sgdGhlIGJ1Zy4pXG4gICAgICAgIGNvbnN0IGlzSG9va0dvbmVFcnJvciA9IChlcnI6IHVua25vd24pOiBib29sZWFuID0+XG4gICAgICAgICAgSG9va05vdEZvdW5kRXJyb3IuaXMoZXJyKSB8fCBSdW5FeHBpcmVkRXJyb3IuaXMoZXJyKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCB3b3JsZC5ldmVudHMuY3JlYXRlKFxuICAgICAgICAgICAgaG9vay5ydW5JZCxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZXZlbnRUeXBlOiAnaG9va19yZWNlaXZlZCcsXG4gICAgICAgICAgICAgIHNwZWNWZXJzaW9uOiBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICAgICAgICAgICAgY29ycmVsYXRpb25JZDogaG9vay5ob29rSWQsXG4gICAgICAgICAgICAgIGV2ZW50RGF0YToge1xuICAgICAgICAgICAgICAgIC4uLih2MUNvbXBhdCA/IHt9IDogeyB0b2tlbjogaG9vay50b2tlbiB9KSxcbiAgICAgICAgICAgICAgICBwYXlsb2FkOiBkZWh5ZHJhdGVkUGF5bG9hZCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHYxQ29tcGF0LFxuICAgICAgICAgICAgICAuLi4ocmVzdW1lSWQgJiYgcGF5bG9hZERpZ2VzdFxuICAgICAgICAgICAgICAgID8geyByZXN1bWVJZCwgcmVzdW1lUGF5bG9hZERpZ2VzdDogcGF5bG9hZERpZ2VzdCB9XG4gICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgaWYgKGlzSG9va0dvbmVFcnJvcihlcnIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgSG9va05vdEZvdW5kRXJyb3IoaG9vay50b2tlbik7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgICAvLyBTdGFtcGVkIEFGVEVSIHRoZSB3cml0ZSByZXNvbHZlcyAoZW50cnktdGltZSBhdHRyaWJ1dGVzIGNhbm5vdCB0ZWxsXG4gICAgICAgIC8vIGFuIGF0dGVtcHRlZCByZXN1bWUgZnJvbSBhIGNvbW1pdHRlZCBvbmUpOiB0b2dldGhlciB3aXRoXG4gICAgICAgIC8vIEhvb2tXYWtlUHVibGlzaGVkIGJlbG93LCB0aGlzIGlzIHdoYXQgbWFrZXMgYSBzdHJhbmRlZCByZXN1bWUg4oCUIGFcbiAgICAgICAgLy8gY29tbWl0dGVkIGV2ZW50IHdob3NlIHdha2UgbmV2ZXIgd2VudCBvdXQgb3Igd2FzIG5ldmVyIGRlbGl2ZXJlZCDigJRcbiAgICAgICAgLy8gcXVlcnlhYmxlIGZyb20gdHJhY2VzLiBTZWUgdGhlIGFsZXJ0aW5nIG5vdGUgb24gSG9va1dha2VQdWJsaXNoZWQuXG4gICAgICAgIHNwYW4/LnNldEF0dHJpYnV0ZXMoQXR0cmlidXRlLkhvb2tSZXN1bWVDb21taXR0ZWQodHJ1ZSkpO1xuXG4gICAgICAgIC8vIFQxIG9mIHRoZSBUVFIgd2luZG93LiBTdGFtcGVkIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgcHVibGlzaCBzb1xuICAgICAgICAvLyBgcHJvZHVjZXJfcHJlcGAgY292ZXJzIGV4YWN0bHkgdGhlIHdvcmsgYWJvdmUgaXQgKGhvb2sgbG9va3VwLCBrZXlcbiAgICAgICAgLy8gcmVzb2x1dGlvbiwgc2VyaWFsaXphdGlvbiwgYW5kIHRoZSBhd2FpdGVkIGhvb2tfcmVjZWl2ZWQgd3JpdGUsXG4gICAgICAgIC8vIHdoaWNoIGlzIGdlbnVpbmVseSBzZXJpYWwgaGVyZSkuXG4gICAgICAgIGNvbnN0IHF1ZXVlUHVibGlzaFJlcXVlc3RlZEF0TXMgPSBEYXRlLm5vdygpO1xuICAgICAgICBhd2FpdCBwdWJsaXNoSG9va1dha2VXaXRoUmV0cnkoXG4gICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgIHdvcmxkLnF1ZXVlKFxuICAgICAgICAgICAgICBxdWV1ZU5hbWUsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBydW5JZDogaG9vay5ydW5JZCxcbiAgICAgICAgICAgICAgICB0cmFjZUNhcnJpZXI6IHJlc3VtZUNvbnRleHQudHJhY2VDYXJyaWVyID8/IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBob29rUmVzdW1lVGltaW5nOiB7XG4gICAgICAgICAgICAgICAgICByZXN1bWVSZXF1ZXN0ZWRBdE1zLFxuICAgICAgICAgICAgICAgICAgcXVldWVQdWJsaXNoUmVxdWVzdGVkQXRNcyxcbiAgICAgICAgICAgICAgICAgIHN0cmF0ZWd5OiAnc2VxdWVudGlhbCcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSBzYXRpc2ZpZXMgV29ya2Zsb3dJbnZva2VQYXlsb2FkLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgLi4ucXVldWVPcHRpb25zLFxuICAgICAgICAgICAgICAgIC8vIERlZHVwIHJldHJpZWQgcHVibGlzaGVzIHdob3NlIHJlc3BvbnNlIHdhcyBsb3N0OiBhXG4gICAgICAgICAgICAgICAgLy8gZHVwbGljYXRlIHdha2UgaXMgaGFybWxlc3MgZm9yIGNvcnJlY3RuZXNzIChkZXRlcm1pbmlzdGljXG4gICAgICAgICAgICAgICAgLy8gcmVwbGF5KSBidXQgY29zdHMgYSBmdWxsIHJlcGxheSBvZiB0aGUgcnVuLCBhbmQgdGhlIHF1ZXVlXG4gICAgICAgICAgICAgICAgLy8gYWNjZXB0cyBhIHJlcGVhdGVkIGlkZW1wb3RlbmN5IGtleSBieSBkZWxpdmVyaW5nIG9ubHkgb25lXG4gICAgICAgICAgICAgICAgLy8gb2YgdGhlIG1lc3NhZ2VzLiBDbGFpbS1sZXNzIHdyaXRlcyBoYXZlIG5vIHJlc3VtZUlkIGFuZFxuICAgICAgICAgICAgICAgIC8vIGtlZXAgdGhlIHByZXZpb3VzIGJlaGF2aW9yLlxuICAgICAgICAgICAgICAgIC4uLihyZXN1bWVJZCA/IHsgaWRlbXBvdGVuY3lLZXk6IGBob29rLSR7cmVzdW1lSWR9YCB9IDoge30pLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApLFxuICAgICAgICAgIHdvcmxkLmlzRGVwbG95bWVudFVuYXZhaWxhYmxlRXJyb3I/LmJpbmQod29ybGQpXG4gICAgICAgICk7XG4gICAgICAgIHNwYW4/LnNldEF0dHJpYnV0ZXMoQXR0cmlidXRlLkhvb2tXYWtlUHVibGlzaGVkKHRydWUpKTtcblxuICAgICAgICByZXR1cm4gaG9vayBzYXRpc2ZpZXMgUmVzdW1lZEhvb2s7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgc3Bhbj8uc2V0QXR0cmlidXRlcyh7XG4gICAgICAgICAgLi4uQXR0cmlidXRlLkhvb2tUb2tlbihcbiAgICAgICAgICAgIHR5cGVvZiB0b2tlbk9ySG9vayA9PT0gJ3N0cmluZycgPyB0b2tlbk9ySG9vayA6IHRva2VuT3JIb29rLnRva2VuXG4gICAgICAgICAgKSxcbiAgICAgICAgICAuLi5BdHRyaWJ1dGUuSG9va0ZvdW5kKGZhbHNlKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmVzdW1lcyBhIHdlYmhvb2sgYnkgc2VuZGluZyBhIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUmVxdWVzdCB8IFJlcXVlc3R9XG4gKiBvYmplY3QgdG8gYSBob29rIGlkZW50aWZpZWQgYnkgaXRzIHRva2VuLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGV4dGVybmFsbHkgKGUuZy4sIGZyb20gYW4gQVBJIHJvdXRlIG9yIHNlcnZlciBhY3Rpb24pXG4gKiB0byBzZW5kIGEgcmVxdWVzdCB0byBhIHdlYmhvb2sgYW5kIHJlc3VtZSB0aGUgYXNzb2NpYXRlZCB3b3JrZmxvdyBydW4uXG4gKlxuICogQHBhcmFtIHRva2VuIC0gVGhlIHVuaXF1ZSB0b2tlbiBpZGVudGlmeWluZyB0aGUgaG9va1xuICogQHBhcmFtIHJlcXVlc3QgLSBUaGUgcmVxdWVzdCB0byBzZW5kIHRvIHRoZSBob29rXG4gKiBAcmV0dXJucyBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgcmVzcG9uc2VcbiAqIEB0aHJvd3MgRXJyb3IgaWYgdGhlIGhvb2sgaXMgbm90IGZvdW5kIG9yIGlmIHRoZXJlJ3MgYW4gZXJyb3IgZHVyaW5nIHRoZSBwcm9jZXNzXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiBgYGB0c1xuICogLy8gSW4gYW4gQVBJIHJvdXRlXG4gKiBpbXBvcnQgeyByZXN1bWVXZWJob29rIH0gZnJvbSAnQHdvcmtmbG93L2NvcmUvcnVudGltZSc7XG4gKlxuICogZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIFBPU1QocmVxdWVzdDogUmVxdWVzdCkge1xuICogICBjb25zdCB1cmwgPSBuZXcgVVJMKHJlcXVlc3QudXJsKTtcbiAqICAgY29uc3QgdG9rZW4gPSB1cmwuc2VhcmNoUGFyYW1zLmdldCgndG9rZW4nKTtcbiAqXG4gKiAgIGlmICghdG9rZW4pIHtcbiAqICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKCdNaXNzaW5nIHRva2VuJywgeyBzdGF0dXM6IDQwMCB9KTtcbiAqICAgfVxuICpcbiAqICAgdHJ5IHtcbiAqICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHJlc3VtZVdlYmhvb2sodG9rZW4sIHJlcXVlc3QpO1xuICogICAgIHJldHVybiByZXNwb25zZTtcbiAqICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAqICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKCdXZWJob29rIG5vdCBmb3VuZCcsIHsgc3RhdHVzOiA0MDQgfSk7XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzdW1lV2ViaG9vayhcbiAgdG9rZW46IHN0cmluZyxcbiAgcmVxdWVzdDogUmVxdWVzdFxuKTogUHJvbWlzZTxSZXNwb25zZT4ge1xuICAvLyBUMCBvZiB0aGUgaG9vay1yZXN1bWUgVFRSIHdpbmRvdy4gRXZlcnl0aGluZyBiZWxvdyAodGhlIGJ5LXRva2VuIGxvb2t1cCxcbiAgLy8gdGhlIHJ1bi1rZXkgcmVzb2x1dGlvbiBpdCBtYXkgdHJpZ2dlciwgYW5kIHRoZSBgcmVzcG9uZFdpdGhgIHNldHVwKSBpc1xuICAvLyByZWFsIHByb2R1Y2VyLXNpZGUgbGF0ZW5jeSBvbiB0aGlzIHBhdGgsIHNvIHRoZSB3aW5kb3cgaGFzIHRvIG9wZW4gaGVyZVxuICAvLyBhbmQgbm90IGluc2lkZSBgcmVzdW1lSG9va0ltcGxgOyBvdGhlcndpc2Ugd2ViaG9vayByZXN1bWVzIHdvdWxkIHJlcG9ydCBhXG4gIC8vIHN5c3RlbWF0aWNhbGx5IHNob3J0ZXIgdG90YWwgdGhhbiBgcmVzdW1lSG9va2Agb25lcyBpbnRvIHRoZSBzYW1lIG1ldHJpYy5cbiAgY29uc3QgcmVzdW1lUmVxdWVzdGVkQXRNcyA9IERhdGUubm93KCk7XG4gIGNvbnN0IHsgaG9vaywgZW5jcnlwdGlvbktleSB9ID0gYXdhaXQgZ2V0SG9va0J5VG9rZW5XaXRoS2V5KHRva2VuKTtcblxuICAvLyBPbmx5IHdlYmhvb2tzIGNhbiBiZSByZXN1bWVkIHZpYSB0aGUgcHVibGljIGVuZHBvaW50LlxuICAvLyBJZiB0aGUgaG9vayB3YXMgY3JlYXRlZCB2aWEgY3JlYXRlSG9vaygpIChpc1dlYmhvb2sgIT09IHRydWUpLFxuICAvLyB0aHJvdyB0aGUgc2FtZSBcIm5vdCBmb3VuZFwiIGVycm9yIHRoZSB3b3JsZCB3b3VsZCB0aHJvdyBmb3IgYSBtaXNzaW5nXG4gIC8vIHRva2VuLiBUaGlzIHByZXZlbnRzIGxlYWtpbmcgdGhhdCB0aGUgdG9rZW4gaXMgdmFsaWQuXG4gIGlmIChob29rLmlzV2ViaG9vayA9PT0gZmFsc2UpIHtcbiAgICB0aHJvdyBuZXcgSG9va05vdEZvdW5kRXJyb3IodG9rZW4pO1xuICB9XG5cbiAgbGV0IHJlc3BvbnNlOiBSZXNwb25zZSB8IHVuZGVmaW5lZDtcbiAgbGV0IHJlc3BvbnNlUmVhZGFibGU6IFJlYWRhYmxlU3RyZWFtPFJlc3BvbnNlPiB8IHVuZGVmaW5lZDtcbiAgaWYgKFxuICAgIGhvb2subWV0YWRhdGEgJiZcbiAgICB0eXBlb2YgaG9vay5tZXRhZGF0YSA9PT0gJ29iamVjdCcgJiZcbiAgICAncmVzcG9uZFdpdGgnIGluIGhvb2subWV0YWRhdGFcbiAgKSB7XG4gICAgaWYgKGhvb2subWV0YWRhdGEucmVzcG9uZFdpdGggPT09ICdtYW51YWwnKSB7XG4gICAgICBjb25zdCB7IHJlYWRhYmxlLCB3cml0YWJsZSB9ID0gbmV3IFRyYW5zZm9ybVN0cmVhbTxSZXNwb25zZSwgUmVzcG9uc2U+KCk7XG4gICAgICByZXNwb25zZVJlYWRhYmxlID0gcmVhZGFibGU7XG5cbiAgICAgIC8vIFRoZSByZXF1ZXN0IGluc3RhbmNlIGluY2x1ZGVzIHRoZSB3cml0YWJsZSBzdHJlYW0gd2hpY2ggd2lsbCBiZSB1c2VkXG4gICAgICAvLyB0byB3cml0ZSB0aGUgcmVzcG9uc2UgdG8gdGhlIGNsaWVudCBmcm9tIHdpdGhpbiB0aGUgd29ya2Zsb3cgcnVuXG4gICAgICAocmVxdWVzdCBhcyBhbnkpW1dFQkhPT0tfUkVTUE9OU0VfV1JJVEFCTEVdID0gd3JpdGFibGU7XG4gICAgfSBlbHNlIGlmIChob29rLm1ldGFkYXRhLnJlc3BvbmRXaXRoIGluc3RhbmNlb2YgUmVzcG9uc2UpIHtcbiAgICAgIHJlc3BvbnNlID0gaG9vay5tZXRhZGF0YS5yZXNwb25kV2l0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKFxuICAgICAgICBgSW52YWxpZCBcXGByZXNwb25kV2l0aFxcYCB2YWx1ZTogJHtob29rLm1ldGFkYXRhLnJlc3BvbmRXaXRofWAsXG4gICAgICAgIHsgc2x1ZzogRVJST1JfU0xVR1MuV0VCSE9PS19JTlZBTElEX1JFU1BPTkRfV0lUSF9WQUxVRSB9XG4gICAgICApO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBObyBgcmVzcG9uZFdpdGhgIHZhbHVlIGltcGxpZXMgdGhlIGRlZmF1bHQgYmVoYXZpb3Igb2YgcmV0dXJuaW5nIGEgMjAyXG4gICAgcmVzcG9uc2UgPSBuZXcgUmVzcG9uc2UobnVsbCwgeyBzdGF0dXM6IDIwMiB9KTtcbiAgfVxuXG4gIC8vIGBob29rYCB3YXMganVzdCBmZXRjaGVkIHZpYSBgZ2V0SG9va0J5VG9rZW5XaXRoS2V5YCAoYSBmcmVzaCBieS10b2tlblxuICAvLyBsb29rdXApIGFib3ZlLCBzbyBpdHMgcmVzcG9uc2Utb25seSBgcmVzdW1lQ2FwYWJpbGl0aWVzYCByZWZsZWN0cyB0aGUgbGl2ZVxuICAvLyBiYWNrZW5kLiBDYWxsIHRoZSBpbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiB3aXRoIHRoZSBmcmVzaCBhdHRlc3RhdGlvbiBzb1xuICAvLyB0aGUgd3JpdGUncyBpZGVtcG90ZW5jeSBjbGFpbSBzdGF5cyBhdmFpbGFibGUgd2l0aG91dCBhIHNlY29uZCBHRVQuIChUaGVcbiAgLy8gcHVibGljIGByZXN1bWVIb29rYCBuZXZlciBzZXRzIHRoaXMsIHNvIGEgY2FsbGVyIGNhbm5vdCBmb3JnZSBpdC4pXG4gIGF3YWl0IHJlc3VtZUhvb2tJbXBsKGhvb2ssIHJlcXVlc3QsIGVuY3J5cHRpb25LZXksIHRydWUsIHJlc3VtZVJlcXVlc3RlZEF0TXMpO1xuXG4gIGlmIChyZXNwb25zZVJlYWRhYmxlKSB7XG4gICAgLy8gV2FpdCBmb3IgdGhlIHJlYWRhYmxlIHN0cmVhbSB0byBlbWl0IG9uZSBjaHVuayxcbiAgICAvLyB3aGljaCBpcyB0aGUgYFJlc3BvbnNlYCBvYmplY3RcbiAgICBjb25zdCByZWFkZXIgPSByZXNwb25zZVJlYWRhYmxlLmdldFJlYWRlcigpO1xuICAgIGNvbnN0IGNodW5rID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcbiAgICBpZiAoY2h1bmsudmFsdWUpIHtcbiAgICAgIHJlc3BvbnNlID0gY2h1bmsudmFsdWU7XG4gICAgfVxuICAgIHJlYWRlci5jYW5jZWwoKTtcbiAgfVxuXG4gIGlmICghcmVzcG9uc2UpIHtcbiAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IoJ1dvcmtmbG93IHJ1biBkaWQgbm90IHNlbmQgYSByZXNwb25zZScsIHtcbiAgICAgIHNsdWc6IEVSUk9SX1NMVUdTLldFQkhPT0tfUkVTUE9OU0VfTk9UX1NFTlQsXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gcmVzcG9uc2U7XG59XG4iXX0=
|