@workflow/core 5.0.0-beta.13 → 5.0.0-beta.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/capabilities.d.ts +19 -1
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +30 -4
- package/dist/class-serialization.d.ts +32 -0
- package/dist/class-serialization.d.ts.map +1 -1
- package/dist/class-serialization.js +37 -1
- package/dist/create-hook.d.ts +37 -0
- package/dist/create-hook.d.ts.map +1 -1
- package/dist/create-hook.js +1 -1
- package/dist/global.d.ts +11 -1
- package/dist/global.d.ts.map +1 -1
- package/dist/global.js +14 -2
- package/dist/runtime/helpers.d.ts +4 -2
- package/dist/runtime/helpers.d.ts.map +1 -1
- package/dist/runtime/helpers.js +6 -7
- package/dist/runtime/resume-hook.d.ts.map +1 -1
- package/dist/runtime/resume-hook.js +23 -12
- package/dist/runtime/start.d.ts +6 -0
- package/dist/runtime/start.d.ts.map +1 -1
- package/dist/runtime/start.js +74 -14
- package/dist/runtime/step-executor.d.ts.map +1 -1
- package/dist/runtime/step-executor.js +22 -8
- package/dist/runtime/step-handler.d.ts.map +1 -1
- package/dist/runtime/step-handler.js +640 -630
- package/dist/runtime/suspension-handler.d.ts +15 -2
- package/dist/runtime/suspension-handler.d.ts.map +1 -1
- package/dist/runtime/suspension-handler.js +150 -49
- package/dist/runtime/wait-continuation.d.ts +84 -0
- package/dist/runtime/wait-continuation.d.ts.map +1 -0
- package/dist/runtime/wait-continuation.js +92 -0
- package/dist/runtime/wait-until.d.ts +18 -0
- package/dist/runtime/wait-until.d.ts.map +1 -0
- package/dist/runtime/wait-until.js +42 -0
- package/dist/runtime.d.ts +3 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +166 -80
- package/dist/serialization/types.d.ts +21 -0
- package/dist/serialization/types.d.ts.map +1 -1
- package/dist/serialization/types.js +1 -1
- package/dist/serialization.d.ts +113 -6
- package/dist/serialization.d.ts.map +1 -1
- package/dist/serialization.js +384 -22
- package/dist/set-attributes.d.ts.map +1 -1
- package/dist/set-attributes.js +17 -15
- package/dist/step/writable-stream.d.ts.map +1 -1
- package/dist/step/writable-stream.js +6 -2
- package/dist/symbols.d.ts +2 -0
- package/dist/symbols.d.ts.map +1 -1
- package/dist/symbols.js +3 -1
- package/dist/util.d.ts +0 -5
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +1 -15
- package/dist/version.d.ts +1 -1
- package/dist/version.js +2 -2
- package/dist/workflow/attribute-dispatcher.d.ts +6 -0
- package/dist/workflow/attribute-dispatcher.d.ts.map +1 -0
- package/dist/workflow/attribute-dispatcher.js +48 -0
- package/dist/workflow/create-hook.d.ts.map +1 -1
- package/dist/workflow/create-hook.js +21 -1
- package/dist/workflow/hook.d.ts.map +1 -1
- package/dist/workflow/hook.js +110 -3
- package/dist/workflow/set-attributes.d.ts +3 -4
- package/dist/workflow/set-attributes.d.ts.map +1 -1
- package/dist/workflow/set-attributes.js +8 -9
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +17 -5
- package/docs/api-reference/create-hook.mdx +32 -0
- package/docs/api-reference/create-webhook.mdx +1 -0
- package/docs/api-reference/experimental-set-attributes.mdx +3 -1
- package/docs/foundations/hooks.mdx +29 -0
- package/docs/foundations/streaming.mdx +1 -1
- package/docs/foundations/versioning.mdx +1 -1
- package/docs/how-it-works/encryption.mdx +2 -2
- package/docs/how-it-works/event-sourcing.mdx +2 -2
- package/package.json +4 -4
|
@@ -24,10 +24,23 @@ export interface SuspensionHandlerResult {
|
|
|
24
24
|
* into the same batch boundary.
|
|
25
25
|
*/
|
|
26
26
|
createdStepCorrelationIds: Set<string>;
|
|
27
|
-
/**
|
|
28
|
-
|
|
27
|
+
/**
|
|
28
|
+
* The soonest pending wait, if any: seconds until it elapses and the
|
|
29
|
+
* correlationId of the wait that produced that timeout. The
|
|
30
|
+
* correlationId seeds the idempotency key for the wait-continuation
|
|
31
|
+
* queue message so that repeated suspension passes over the same
|
|
32
|
+
* pending wait collapse into a single delayed continuation.
|
|
33
|
+
*/
|
|
34
|
+
waitTimeout?: {
|
|
35
|
+
seconds: number;
|
|
36
|
+
correlationId: string;
|
|
37
|
+
};
|
|
29
38
|
/** Whether a hook conflict was detected (should re-invoke immediately) */
|
|
30
39
|
hasHookConflict: boolean;
|
|
40
|
+
/** Whether a `hook.getConflict()` awaiter needs the workflow to continue immediately */
|
|
41
|
+
hasAwaitedHookCreation: boolean;
|
|
42
|
+
/** Whether native workflow attribute events were written for replay. */
|
|
43
|
+
hasAttributeEvents: boolean;
|
|
31
44
|
}
|
|
32
45
|
/**
|
|
33
46
|
* Handles a workflow suspension by processing all pending operations (hooks, steps, waits).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suspension-handler.d.ts","sourceRoot":"","sources":["../../src/runtime/suspension-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"suspension-handler.d.ts","sourceRoot":"","sources":["../../src/runtime/suspension-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAQ/C,OAAO,EAKL,KAAK,WAAW,EAChB,KAAK,KAAK,EACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAGV,uBAAuB,EAEvB,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAMtB,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,WAAW,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,4DAA4D;IAC5D,YAAY,EAAE,uBAAuB,EAAE,CAAC;IACxC;;;;;;;OAOG;IACH,yBAAyB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC;;;;;;OAMG;IACH,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,0EAA0E;IAC1E,eAAe,EAAE,OAAO,CAAC;IACzB,wFAAwF;IACxF,sBAAsB,EAAE,OAAO,CAAC;IAChC,wEAAwE;IACxE,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAgED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,UAAU,EACV,KAAK,EACL,GAAG,EACH,IAAI,EACJ,SAAS,GACV,EAAE,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAmY5D"}
|
|
@@ -1,11 +1,53 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { SPEC_VERSION_CURRENT, } from '@workflow/world';
|
|
1
|
+
import { EntityConflictError, FatalError, HookNotFoundError, RunExpiredError, WorkflowWorldError, } from '@workflow/errors';
|
|
2
|
+
import { AttributeValidationError, SPEC_VERSION_CURRENT, } from '@workflow/world';
|
|
4
3
|
import { importKey } from '../encryption.js';
|
|
5
4
|
import { runtimeLogger } from '../logger.js';
|
|
6
5
|
import { dehydrateStepArguments } from '../serialization.js';
|
|
7
6
|
import * as Attribute from '../telemetry/semantic-conventions.js';
|
|
8
7
|
import { getAbortStreamIdFromToken } from '../util.js';
|
|
8
|
+
async function createHookEvent({ world, runId, hookEvent, queueItem, requestId, }) {
|
|
9
|
+
try {
|
|
10
|
+
const result = await world.events.create(runId, hookEvent, {
|
|
11
|
+
requestId,
|
|
12
|
+
});
|
|
13
|
+
// Check if the world returned a hook_conflict event instead of hook_created.
|
|
14
|
+
// The hook_conflict event is stored in the event log and will be replayed
|
|
15
|
+
// on the next workflow invocation, causing the hook's promise to reject.
|
|
16
|
+
if (result.event?.eventType === 'hook_conflict') {
|
|
17
|
+
return {
|
|
18
|
+
hasHookConflict: true,
|
|
19
|
+
hasAwaitedHookCreation: false,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
hasHookConflict: false,
|
|
24
|
+
hasAwaitedHookCreation: queueItem.hasConflictAwaiter === true,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
if (EntityConflictError.is(err)) {
|
|
29
|
+
runtimeLogger.info('Hook already exists, continuing', {
|
|
30
|
+
workflowRunId: runId,
|
|
31
|
+
message: err.message,
|
|
32
|
+
});
|
|
33
|
+
return {
|
|
34
|
+
hasHookConflict: false,
|
|
35
|
+
hasAwaitedHookCreation: queueItem.hasConflictAwaiter === true,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (RunExpiredError.is(err)) {
|
|
39
|
+
runtimeLogger.info('Workflow run already completed, skipping hook', {
|
|
40
|
+
workflowRunId: runId,
|
|
41
|
+
message: err.message,
|
|
42
|
+
});
|
|
43
|
+
return {
|
|
44
|
+
hasHookConflict: false,
|
|
45
|
+
hasAwaitedHookCreation: false,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
throw err;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
9
51
|
/**
|
|
10
52
|
* Handles a workflow suspension by processing all pending operations (hooks, steps, waits).
|
|
11
53
|
* Creates events for all operations but does NOT queue step messages — returns the pending
|
|
@@ -21,6 +63,7 @@ export async function handleSuspension({ suspension, world, run, span, requestId
|
|
|
21
63
|
const stepItems = suspension.steps.filter((item) => item.type === 'step');
|
|
22
64
|
const allHookItems = suspension.steps.filter((item) => item.type === 'hook');
|
|
23
65
|
const waitItems = suspension.steps.filter((item) => item.type === 'wait');
|
|
66
|
+
const attributeItems = suspension.steps.filter((item) => item.type === 'attribute');
|
|
24
67
|
// Split hooks by what actions they need
|
|
25
68
|
const hooksNeedingCreation = allHookItems.filter((item) => !item.hasCreatedEvent);
|
|
26
69
|
const hooksNeedingDisposal = allHookItems.filter((item) => item.disposed);
|
|
@@ -33,14 +76,17 @@ export async function handleSuspension({ suspension, world, run, span, requestId
|
|
|
33
76
|
? undefined
|
|
34
77
|
: (await dehydrateStepArguments(queueItem.metadata, runId, encryptionKey, suspension.globalThis));
|
|
35
78
|
return {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
79
|
+
queueItem,
|
|
80
|
+
hookEvent: {
|
|
81
|
+
eventType: 'hook_created',
|
|
82
|
+
specVersion: SPEC_VERSION_CURRENT,
|
|
83
|
+
correlationId: queueItem.correlationId,
|
|
84
|
+
eventData: {
|
|
85
|
+
token: queueItem.token,
|
|
86
|
+
metadata: hookMetadata,
|
|
87
|
+
isWebhook: queueItem.isWebhook ?? false,
|
|
88
|
+
...(queueItem.isSystem && { isSystem: true }),
|
|
89
|
+
},
|
|
44
90
|
},
|
|
45
91
|
};
|
|
46
92
|
}));
|
|
@@ -49,32 +95,17 @@ export async function handleSuspension({ suspension, world, run, span, requestId
|
|
|
49
95
|
// Track any hook conflicts that occur — these are returned to the caller
|
|
50
96
|
// so the V2 handler can re-invoke immediately.
|
|
51
97
|
let hasHookConflict = false;
|
|
98
|
+
let hasAwaitedHookCreation = false;
|
|
52
99
|
if (hookEvents.length > 0) {
|
|
53
|
-
await Promise.all(hookEvents.map(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (result.event.eventType === 'hook_conflict') {
|
|
63
|
-
hasHookConflict = true;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
catch (err) {
|
|
67
|
-
if (EntityConflictError.is(err) || RunExpiredError.is(err)) {
|
|
68
|
-
runtimeLogger.info('Workflow run already completed, skipping hook', {
|
|
69
|
-
workflowRunId: runId,
|
|
70
|
-
message: err.message,
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
throw err;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}));
|
|
100
|
+
const results = await Promise.all(hookEvents.map(({ hookEvent, queueItem }) => createHookEvent({
|
|
101
|
+
world,
|
|
102
|
+
runId,
|
|
103
|
+
hookEvent,
|
|
104
|
+
queueItem,
|
|
105
|
+
requestId,
|
|
106
|
+
})));
|
|
107
|
+
hasHookConflict = results.some((result) => result.hasHookConflict);
|
|
108
|
+
hasAwaitedHookCreation = results.some((result) => result.hasAwaitedHookCreation);
|
|
78
109
|
}
|
|
79
110
|
// Process hook disposals — these release hook tokens for reuse by other workflows.
|
|
80
111
|
if (hooksNeedingDisposal.length > 0) {
|
|
@@ -251,22 +282,71 @@ export async function handleSuspension({ suspension, world, run, span, requestId
|
|
|
251
282
|
})());
|
|
252
283
|
}
|
|
253
284
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
285
|
+
for (const queueItem of attributeItems) {
|
|
286
|
+
ops.push((async () => {
|
|
287
|
+
try {
|
|
288
|
+
await world.events.create(runId, {
|
|
289
|
+
eventType: 'attr_set',
|
|
290
|
+
specVersion: SPEC_VERSION_CURRENT,
|
|
291
|
+
correlationId: queueItem.correlationId,
|
|
292
|
+
eventData: {
|
|
293
|
+
changes: queueItem.changes,
|
|
294
|
+
writer: { type: 'workflow' },
|
|
295
|
+
...(queueItem.allowReservedAttributes
|
|
296
|
+
? { allowReservedAttributes: true }
|
|
297
|
+
: {}),
|
|
298
|
+
},
|
|
299
|
+
}, { requestId });
|
|
300
|
+
}
|
|
301
|
+
catch (err) {
|
|
302
|
+
if (EntityConflictError.is(err)) {
|
|
303
|
+
runtimeLogger.info('Workflow attribute event already exists, continuing', {
|
|
304
|
+
workflowRunId: runId,
|
|
305
|
+
correlationId: queueItem.correlationId,
|
|
306
|
+
message: err.message,
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
else if (isAttributeValidationFailure(err)) {
|
|
310
|
+
// Deterministic validation rejection from the World — e.g. the
|
|
311
|
+
// cumulative per-run attribute cap, which only the World can
|
|
312
|
+
// check against the run's existing attributes. Redelivering the
|
|
313
|
+
// orchestrator message replays the workflow into the exact same
|
|
314
|
+
// write and the exact same rejection, so retrying can never
|
|
315
|
+
// succeed. Surface it as a FatalError so the caller fails the
|
|
316
|
+
// run with a clear error instead of wedging it in redelivery.
|
|
317
|
+
const fatal = new FatalError(`experimental_setAttributes failed World validation: ${err instanceof Error ? err.message : String(err)}`);
|
|
318
|
+
fatal.cause = err;
|
|
319
|
+
throw fatal;
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
throw err;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
})());
|
|
326
|
+
}
|
|
327
|
+
// Await the step_created / wait_created event creates before returning.
|
|
328
|
+
// The caller (workflowEntrypoint) only enqueues the step-dispatch queue
|
|
329
|
+
// messages AFTER handleSuspension resolves, and the queue handler acks
|
|
330
|
+
// the orchestrator message only after the caller resolves. So the step_created
|
|
331
|
+
// events must be durable here, and the dispatch sends must complete in the caller,
|
|
332
|
+
// all before ack. If the process crashes before this resolves, the orchestrator
|
|
333
|
+
// message is not acked and VQS redelivers, re-creates the (idempotent)
|
|
334
|
+
// step_created and re-dispatches, and recovers the run instead of orphaning it.
|
|
259
335
|
await Promise.all(ops);
|
|
260
|
-
//
|
|
336
|
+
// Find the soonest pending wait (minimum timeout)
|
|
261
337
|
const now = Date.now();
|
|
262
|
-
|
|
338
|
+
let soonestWait;
|
|
339
|
+
for (const queueItem of waitItems) {
|
|
263
340
|
const resumeAtMs = queueItem.resumeAt.getTime();
|
|
264
341
|
const delayMs = Math.max(1000, resumeAtMs - now);
|
|
265
342
|
const timeoutSeconds = Math.ceil(delayMs / 1000);
|
|
266
|
-
if (
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
343
|
+
if (!soonestWait || timeoutSeconds < soonestWait.seconds) {
|
|
344
|
+
soonestWait = {
|
|
345
|
+
seconds: timeoutSeconds,
|
|
346
|
+
correlationId: queueItem.correlationId,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
}
|
|
270
350
|
span?.setAttributes({
|
|
271
351
|
...Attribute.WorkflowRunStatus('workflow_suspended'),
|
|
272
352
|
...Attribute.WorkflowStepsCreated(stepItems.length),
|
|
@@ -276,8 +356,29 @@ export async function handleSuspension({ suspension, world, run, span, requestId
|
|
|
276
356
|
return {
|
|
277
357
|
pendingSteps: stepItems,
|
|
278
358
|
createdStepCorrelationIds,
|
|
279
|
-
|
|
359
|
+
// On hook conflict the caller re-invokes immediately and never reads
|
|
360
|
+
// the wait timeout, so don't report one.
|
|
361
|
+
waitTimeout: hasHookConflict ? undefined : soonestWait,
|
|
280
362
|
hasHookConflict,
|
|
363
|
+
hasAwaitedHookCreation,
|
|
364
|
+
hasAttributeEvents: attributeItems.length > 0,
|
|
281
365
|
};
|
|
282
366
|
}
|
|
283
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VzcGVuc2lvbi1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvc3VzcGVuc2lvbi1oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM5QyxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLGlCQUFpQixFQUNqQixlQUFlLEdBQ2hCLE1BQU0sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxFQUdMLG9CQUFvQixHQUdyQixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQU83QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzdELE9BQU8sS0FBSyxTQUFTLE1BQU0sc0NBQXNDLENBQUM7QUFDbEUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBZ0N2RDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsZ0JBQWdCLENBQUMsRUFDckMsVUFBVSxFQUNWLEtBQUssRUFDTCxHQUFHLEVBQ0gsSUFBSSxFQUNKLFNBQVMsR0FDZTtJQUN4QixNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDO0lBQ3hCLCtCQUErQjtJQUMvQixNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FDdkMsQ0FBQyxJQUFJLEVBQW1DLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLE1BQU0sQ0FDaEUsQ0FBQztJQUNGLE1BQU0sWUFBWSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUMxQyxDQUFDLElBQUksRUFBbUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUNoRSxDQUFDO0lB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LE9BQU8sRUFBRSxDQUFDO1FBQ2hELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFVBQVUsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNqRCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsQ0FBQztRQUNqRCxJQUFJLEdBQUcsS0FBSyxJQUFJO1lBQUUsT0FBTyxjQUFjLENBQUM7UUFDeEMsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxjQUFjLENBQUMsQ0FBQztJQUN2QyxDQUFDLEVBQ0QsSUFBSSxDQUNMLENBQUM7SUFFRixJQUFJLEVBQUUsYUFBYSxDQUFDO1FBQ2xCLEdBQUcsU0FBUyxDQUFDLGlCQUFpQixDQUFDLG9CQUFvQixDQUFDO1FBQ3BELEdBQUcsU0FBUyxDQUFDLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7UUFDbkQsR0FBRyxTQUFTLENBQUMsb0JBQW9CLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDO1FBQzlELEdBQUcsU0FBUyxDQUFDLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7S0FDcEQsQ0FBQyxDQUFDO0lBRUgsT0FBTztRQUNMLFlBQVksRUFBRSxTQUFTO1FBQ3ZCLHlCQUF5QjtRQUN6QixjQUFjLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLElBQUksU0FBUyxDQUFDO1FBQ3RFLGVBQWU7S0FDaEIsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFNwYW4gfSBmcm9tICdAb3BlbnRlbGVtZXRyeS9hcGknO1xuaW1wb3J0IHsgd2FpdFVudGlsIH0gZnJvbSAnQHZlcmNlbC9mdW5jdGlvbnMnO1xuaW1wb3J0IHtcbiAgRW50aXR5Q29uZmxpY3RFcnJvcixcbiAgSG9va05vdEZvdW5kRXJyb3IsXG4gIFJ1bkV4cGlyZWRFcnJvcixcbn0gZnJvbSAnQHdvcmtmbG93L2Vycm9ycyc7XG5pbXBvcnQge1xuICB0eXBlIENyZWF0ZUV2ZW50UmVxdWVzdCxcbiAgdHlwZSBTZXJpYWxpemVkRGF0YSxcbiAgU1BFQ19WRVJTSU9OX0NVUlJFTlQsXG4gIHR5cGUgV29ya2Zsb3dSdW4sXG4gIHR5cGUgV29ybGQsXG59IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgeyBpbXBvcnRLZXkgfSBmcm9tICcuLi9lbmNyeXB0aW9uLmpzJztcbmltcG9ydCB0eXBlIHtcbiAgSG9va0ludm9jYXRpb25RdWV1ZUl0ZW0sXG4gIFN0ZXBJbnZvY2F0aW9uUXVldWVJdGVtLFxuICBXYWl0SW52b2NhdGlvblF1ZXVlSXRlbSxcbiAgV29ya2Zsb3dTdXNwZW5zaW9uLFxufSBmcm9tICcuLi9nbG9iYWwuanMnO1xuaW1wb3J0IHsgcnVudGltZUxvZ2dlciB9IGZyb20gJy4uL2xvZ2dlci5qcyc7XG5pbXBvcnQgeyBkZWh5ZHJhdGVTdGVwQXJndW1lbnRzIH0gZnJvbSAnLi4vc2VyaWFsaXphdGlvbi5qcyc7XG5pbXBvcnQgKiBhcyBBdHRyaWJ1dGUgZnJvbSAnLi4vdGVsZW1ldHJ5L3NlbWFudGljLWNvbnZlbnRpb25zLmpzJztcbmltcG9ydCB7IGdldEFib3J0U3RyZWFtSWRGcm9tVG9rZW4gfSBmcm9tICcuLi91dGlsLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBTdXNwZW5zaW9uSGFuZGxlclBhcmFtcyB7XG4gIHN1c3BlbnNpb246IFdvcmtmbG93U3VzcGVuc2lvbjtcbiAgd29ybGQ6IFdvcmxkO1xuICBydW46IFdvcmtmbG93UnVuO1xuICBzcGFuPzogU3BhbjtcbiAgcmVxdWVzdElkPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFJlc3VsdCBvZiBoYW5kbGluZyBhIHN1c3BlbnNpb24uIFJldHVybnMgcGVuZGluZyBzdGVwIGl0ZW1zIHNvIHRoZSBjYWxsZXJcbiAqIGNhbiBkZWNpZGUgd2hpY2ggdG8gZXhlY3V0ZSBpbmxpbmUgdnMgcXVldWUgdG8gYmFja2dyb3VuZC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdXNwZW5zaW9uSGFuZGxlclJlc3VsdCB7XG4gIC8qKiBQZW5kaW5nIHN0ZXAgaXRlbXMgd2l0aCBldmVudHMgY3JlYXRlZCBidXQgTk9UIHF1ZXVlZCAqL1xuICBwZW5kaW5nU3RlcHM6IFN0ZXBJbnZvY2F0aW9uUXVldWVJdGVtW107XG4gIC8qKlxuICAgKiBDb3JyZWxhdGlvbiBJRHMgZm9yIHdoaWNoIHRoaXMgc3VzcGVuc2lvbiBjYWxsIGFjdHVhbGx5IHdyb3RlIHRoZVxuICAgKiBzdGVwX2NyZWF0ZWQgZXZlbnQgKGFzIG9wcG9zZWQgdG8gY2F0Y2hpbmcgRW50aXR5Q29uZmxpY3RFcnJvciBiZWNhdXNlXG4gICAqIGEgY29uY3VycmVudCBoYW5kbGVyIHdyb3RlIGl0IGZpcnN0KS4gT25seSB0aGUgaGFuZGxlciB0aGF0IHdyb3RlIHRoZVxuICAgKiBzdGVwX2NyZWF0ZWQgZXZlbnQgc2hvdWxkIHF1ZXVlIC8gaW5saW5lLWV4ZWN1dGUgdGhlIHN0ZXAg4oCUIHRoaXNcbiAgICogZ3VhcmFudGVlcyBhIHNpbmdsZSBvd25lciBwZXIgc3RlcCwgZXZlbiB3aGVuIG11bHRpcGxlIGhhbmRsZXJzIHJhY2VcbiAgICogaW50byB0aGUgc2FtZSBiYXRjaCBib3VuZGFyeS5cbiAgICovXG4gIGNyZWF0ZWRTdGVwQ29ycmVsYXRpb25JZHM6IFNldDxzdHJpbmc+O1xuICAvKiogVGltZW91dCBmcm9tIHdhaXRzLCBpZiBhbnkgKi9cbiAgdGltZW91dFNlY29uZHM/OiBudW1iZXI7XG4gIC8qKiBXaGV0aGVyIGEgaG9vayBjb25mbGljdCB3YXMgZGV0ZWN0ZWQgKHNob3VsZCByZS1pbnZva2UgaW1tZWRpYXRlbHkpICovXG4gIGhhc0hvb2tDb25mbGljdDogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBIYW5kbGVzIGEgd29ya2Zsb3cgc3VzcGVuc2lvbiBieSBwcm9jZXNzaW5nIGFsbCBwZW5kaW5nIG9wZXJhdGlvbnMgKGhvb2tzLCBzdGVwcywgd2FpdHMpLlxuICogQ3JlYXRlcyBldmVudHMgZm9yIGFsbCBvcGVyYXRpb25zIGJ1dCBkb2VzIE5PVCBxdWV1ZSBzdGVwIG1lc3NhZ2VzIOKAlCByZXR1cm5zIHRoZSBwZW5kaW5nXG4gKiBzdGVwcyBzbyB0aGUgY2FsbGVyIGNhbiBkZWNpZGUgd2hpY2ggdG8gZXhlY3V0ZSBpbmxpbmUgdnMgcXVldWUgdG8gYmFja2dyb3VuZC5cbiAqXG4gKiBQcm9jZXNzaW5nIG9yZGVyOlxuICogMS4gSG9va3MgYXJlIHByb2Nlc3NlZCBmaXJzdCB0byBwcmV2ZW50IHJhY2UgY29uZGl0aW9ucyB3aXRoIHdlYmhvb2sgcmVjZWl2ZXJzXG4gKiAyLiBTdGVwIGV2ZW50cyBhbmQgd2FpdCBldmVudHMgYXJlIGNyZWF0ZWQgaW4gcGFyYWxsZWxcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZVN1c3BlbnNpb24oe1xuICBzdXNwZW5zaW9uLFxuICB3b3JsZCxcbiAgcnVuLFxuICBzcGFuLFxuICByZXF1ZXN0SWQsXG59OiBTdXNwZW5zaW9uSGFuZGxlclBhcmFtcyk6IFByb21pc2U8U3VzcGVuc2lvbkhhbmRsZXJSZXN1bHQ+IHtcbiAgY29uc3QgcnVuSWQgPSBydW4ucnVuSWQ7XG4gIC8vIFNlcGFyYXRlIHF1ZXVlIGl0ZW1zIGJ5IHR5cGVcbiAgY29uc3Qgc3RlcEl0ZW1zID0gc3VzcGVuc2lvbi5zdGVwcy5maWx0ZXIoXG4gICAgKGl0ZW0pOiBpdGVtIGlzIFN0ZXBJbnZvY2F0aW9uUXVldWVJdGVtID0+IGl0ZW0udHlwZSA9PT0gJ3N0ZXAnXG4gICk7XG4gIGNvbnN0IGFsbEhvb2tJdGVtcyA9IHN1c3BlbnNpb24uc3RlcHMuZmlsdGVyKFxuICAgIChpdGVtKTogaXRlbSBpcyBIb29rSW52b2NhdGlvblF1ZXVlSXRlbSA9PiBpdGVtLnR5cGUgPT09ICdob29rJ1xuICApO1xuICBjb25zdCB3YWl0SXRlbXMgPSBzdXNwZW5zaW9uLnN0ZXBzLmZpbHRlcihcbiAgICAoaXRlbSk6IGl0ZW0gaXMgV2FpdEludm9jYXRpb25RdWV1ZUl0ZW0gPT4gaXRlbS50eXBlID09PSAnd2FpdCdcbiAgKTtcblxuICAvLyBTcGxpdCBob29rcyBieSB3aGF0IGFjdGlvbnMgdGhleSBuZWVkXG4gIGNvbnN0IGhvb2tzTmVlZGluZ0NyZWF0aW9uID0gYWxsSG9va0l0ZW1zLmZpbHRlcihcbiAgICAoaXRlbSkgPT4gIWl0ZW0uaGFzQ3JlYXRlZEV2ZW50XG4gICk7XG4gIGNvbnN0IGhvb2tzTmVlZGluZ0Rpc3Bvc2FsID0gYWxsSG9va0l0ZW1zLmZpbHRlcigoaXRlbSkgPT4gaXRlbS5kaXNwb3NlZCk7XG5cbiAgLy8gUmVzb2x2ZSBlbmNyeXB0aW9uIGtleSBmb3IgdGhpcyBydW5cbiAgY29uc3QgcmF3S2V5ID0gYXdhaXQgd29ybGQuZ2V0RW5jcnlwdGlvbktleUZvclJ1bj8uKHJ1bik7XG4gIGNvbnN0IGVuY3J5cHRpb25LZXkgPSByYXdLZXkgPyBhd2FpdCBpbXBvcnRLZXkocmF3S2V5KSA6IHVuZGVmaW5lZDtcblxuICAvLyBCdWlsZCBhbmQgcHJvY2VzcyBob29rX2NyZWF0ZWQgZXZlbnRzIChzYW1lIGFzIFYxKVxuICBjb25zdCBob29rRXZlbnRzOiBDcmVhdGVFdmVudFJlcXVlc3RbXSA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgIGhvb2tzTmVlZGluZ0NyZWF0aW9uLm1hcChhc3luYyAocXVldWVJdGVtKSA9PiB7XG4gICAgICBjb25zdCBob29rTWV0YWRhdGE6IFNlcmlhbGl6ZWREYXRhIHwgdW5kZWZpbmVkID1cbiAgICAgICAgdHlwZW9mIHF1ZXVlSXRlbS5tZXRhZGF0YSA9PT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgIDogKChhd2FpdCBkZWh5ZHJhdGVTdGVwQXJndW1lbnRzKFxuICAgICAgICAgICAgICBxdWV1ZUl0ZW0ubWV0YWRhdGEsXG4gICAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgICBlbmNyeXB0aW9uS2V5LFxuICAgICAgICAgICAgICBzdXNwZW5zaW9uLmdsb2JhbFRoaXNcbiAgICAgICAgICAgICkpIGFzIFNlcmlhbGl6ZWREYXRhKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGV2ZW50VHlwZTogJ2hvb2tfY3JlYXRlZCcgYXMgY29uc3QsXG4gICAgICAgIHNwZWNWZXJzaW9uOiBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICAgIGV2ZW50RGF0YToge1xuICAgICAgICAgIHRva2VuOiBxdWV1ZUl0ZW0udG9rZW4sXG4gICAgICAgICAgbWV0YWRhdGE6IGhvb2tNZXRhZGF0YSxcbiAgICAgICAgICBpc1dlYmhvb2s6IHF1ZXVlSXRlbS5pc1dlYmhvb2sgPz8gZmFsc2UsXG4gICAgICAgICAgLi4uKHF1ZXVlSXRlbS5pc1N5c3RlbSAmJiB7IGlzU3lzdGVtOiB0cnVlIH0pLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9KVxuICApO1xuXG4gIC8vIFByb2Nlc3MgaG9va3MgZmlyc3QgdG8gcHJldmVudCByYWNlIGNvbmRpdGlvbnMgd2l0aCB3ZWJob29rIHJlY2VpdmVycy5cbiAgLy8gQWxsIGhvb2sgY3JlYXRpb25zIHJ1biBpbiBwYXJhbGxlbC5cbiAgLy8gVHJhY2sgYW55IGhvb2sgY29uZmxpY3RzIHRoYXQgb2NjdXIg4oCUIHRoZXNlIGFyZSByZXR1cm5lZCB0byB0aGUgY2FsbGVyXG4gIC8vIHNvIHRoZSBWMiBoYW5kbGVyIGNhbiByZS1pbnZva2UgaW1tZWRpYXRlbHkuXG4gIGxldCBoYXNIb29rQ29uZmxpY3QgPSBmYWxzZTtcblxuICBpZiAoaG9va0V2ZW50cy5sZW5ndGggPiAwKSB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBob29rRXZlbnRzLm1hcChhc3luYyAoaG9va0V2ZW50KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd29ybGQuZXZlbnRzLmNyZWF0ZShydW5JZCwgaG9va0V2ZW50LCB7XG4gICAgICAgICAgICByZXF1ZXN0SWQsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHdvcmxkIHJldHVybmVkIGEgaG9va19jb25mbGljdCBldmVudCBpbnN0ZWFkIG9mIGhvb2tfY3JlYXRlZC5cbiAgICAgICAgICAvLyBUaGUgaG9va19jb25mbGljdCBldmVudCBpcyBzdG9yZWQgaW4gdGhlIGV2ZW50IGxvZyBhbmQgd2lsbCBiZSByZXBsYXllZFxuICAgICAgICAgIC8vIG9uIHRoZSBuZXh0IHdvcmtmbG93IGludm9jYXRpb24sIGNhdXNpbmcgdGhlIGhvb2sncyBwcm9taXNlIHRvIHJlamVjdC5cbiAgICAgICAgICAvLyBOb3RlOiBob29rIGV2ZW50cyBhbHdheXMgY3JlYXRlIGFuIGV2ZW50IChsZWdhY3kgcnVucyB0aHJvdywgbm90IHJldHVybiB1bmRlZmluZWQpXG4gICAgICAgICAgaWYgKHJlc3VsdC5ldmVudCEuZXZlbnRUeXBlID09PSAnaG9va19jb25mbGljdCcpIHtcbiAgICAgICAgICAgIGhhc0hvb2tDb25mbGljdCA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBpZiAoRW50aXR5Q29uZmxpY3RFcnJvci5pcyhlcnIpIHx8IFJ1bkV4cGlyZWRFcnJvci5pcyhlcnIpKSB7XG4gICAgICAgICAgICBydW50aW1lTG9nZ2VyLmluZm8oXG4gICAgICAgICAgICAgICdXb3JrZmxvdyBydW4gYWxyZWFkeSBjb21wbGV0ZWQsIHNraXBwaW5nIGhvb2snLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8vIFByb2Nlc3MgaG9vayBkaXNwb3NhbHMg4oCUIHRoZXNlIHJlbGVhc2UgaG9vayB0b2tlbnMgZm9yIHJldXNlIGJ5IG90aGVyIHdvcmtmbG93cy5cbiAgaWYgKGhvb2tzTmVlZGluZ0Rpc3Bvc2FsLmxlbmd0aCA+IDApIHtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGhvb2tzTmVlZGluZ0Rpc3Bvc2FsLm1hcChhc3luYyAocXVldWVJdGVtKSA9PiB7XG4gICAgICAgIGNvbnN0IGhvb2tEaXNwb3NlZEV2ZW50OiBDcmVhdGVFdmVudFJlcXVlc3QgPSB7XG4gICAgICAgICAgZXZlbnRUeXBlOiAnaG9va19kaXNwb3NlZCcgYXMgY29uc3QsXG4gICAgICAgICAgc3BlY1ZlcnNpb246IFNQRUNfVkVSU0lPTl9DVVJSRU5ULFxuICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgIGV2ZW50RGF0YToge1xuICAgICAgICAgICAgdG9rZW46IHF1ZXVlSXRlbS50b2tlbixcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHdvcmxkLmV2ZW50cy5jcmVhdGUocnVuSWQsIGhvb2tEaXNwb3NlZEV2ZW50LCB7IHJlcXVlc3RJZCB9KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgaWYgKEVudGl0eUNvbmZsaWN0RXJyb3IuaXMoZXJyKSkge1xuICAgICAgICAgICAgLy8gSG9vayB3YXMgYWxyZWFkeSBkaXNwb3NlZCBieSBhIGNvbmN1cnJlbnQgaW52b2NhdGlvbiDigJQgc2FmZSB0byBza2lwXG4gICAgICAgICAgICBydW50aW1lTG9nZ2VyLmluZm8oXG4gICAgICAgICAgICAgICdIb29rIGFscmVhZHkgZGlzcG9zZWQsIHNraXBwaW5nIGR1cGxpY2F0ZSBkaXNwb3NhbCcsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKFJ1bkV4cGlyZWRFcnJvci5pcyhlcnIpKSB7XG4gICAgICAgICAgICBydW50aW1lTG9nZ2VyLmluZm8oXG4gICAgICAgICAgICAgICdXb3JrZmxvdyBydW4gYWxyZWFkeSBjb21wbGV0ZWQsIHNraXBwaW5nIGhvb2sgZGlzcG9zYWwnLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgICAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIGlmIChIb29rTm90Rm91bmRFcnJvci5pcyhlcnIpKSB7XG4gICAgICAgICAgICAvLyBIb29rIG1heSBoYXZlIGFscmVhZHkgYmVlbiBkaXNwb3NlZCBvciBuZXZlciBjcmVhdGVkXG4gICAgICAgICAgICBydW50aW1lTG9nZ2VyLmluZm8oJ0hvb2sgbm90IGZvdW5kIGZvciBkaXNwb3NhbCwgY29udGludWluZycsIHtcbiAgICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvLyBQcm9jZXNzIGFib3J0IHJlcXVlc3RzIOKAlCByZXN1bWUgdGhlIGhvb2sgd2l0aCBhYm9ydCBwYXlsb2FkIGFuZCB3cml0ZSBzdHJlYW0gcGFja2V0XG4gIGNvbnN0IGhvb2tzTmVlZGluZ0Fib3J0ID0gYWxsSG9va0l0ZW1zLmZpbHRlcihcbiAgICAoaXRlbSkgPT4gaXRlbS5hYm9ydFJlcXVlc3RlZCAmJiAhaXRlbS5kaXNwb3NlZFxuICApO1xuXG4gIGlmIChob29rc05lZWRpbmdBYm9ydC5sZW5ndGggPiAwKSB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBob29rc05lZWRpbmdBYm9ydC5tYXAoYXN5bmMgKHF1ZXVlSXRlbSkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIERlaHlkcmF0ZSB0aGUgYWJvcnQgcGF5bG9hZCBmb3Igc3RvcmFnZVxuICAgICAgICAgIGNvbnN0IGFib3J0UGF5bG9hZCA9IGF3YWl0IGRlaHlkcmF0ZVN0ZXBBcmd1bWVudHMoXG4gICAgICAgICAgICB7IGFib3J0ZWQ6IHRydWUsIHJlYXNvbjogcXVldWVJdGVtLmFib3J0UmVhc29uIH0sXG4gICAgICAgICAgICBydW5JZCxcbiAgICAgICAgICAgIGVuY3J5cHRpb25LZXksXG4gICAgICAgICAgICBzdXNwZW5zaW9uLmdsb2JhbFRoaXNcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgLy8gQ3JlYXRlIGhvb2tfcmVjZWl2ZWQgZXZlbnQgd2l0aCBhYm9ydCBwYXlsb2FkXG4gICAgICAgICAgYXdhaXQgd29ybGQuZXZlbnRzLmNyZWF0ZShydW5JZCwge1xuICAgICAgICAgICAgZXZlbnRUeXBlOiAnaG9va19yZWNlaXZlZCcgYXMgY29uc3QsXG4gICAgICAgICAgICBzcGVjVmVyc2lvbjogU1BFQ19WRVJTSU9OX0NVUlJFTlQsXG4gICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgIGV2ZW50RGF0YToge1xuICAgICAgICAgICAgICB0b2tlbjogcXVldWVJdGVtLnRva2VuLFxuICAgICAgICAgICAgICBwYXlsb2FkOiBhYm9ydFBheWxvYWQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8gV3JpdGUgc3RyZWFtIGNhbmNlbGxhdGlvbiBwYWNrZXQgZm9yIHJlYWwtdGltZSBzdGVwIHByb3BhZ2F0aW9uLlxuICAgICAgICAgIC8vIFJldXNlIHRoZSBzYW1lIGRlaHlkcmF0ZWQgcGF5bG9hZCBhcyB0aGUgaG9vayBldmVudCBzbyB0aGUgcmVhc29uXG4gICAgICAgICAgLy8gcm91bmQtdHJpcHMgdGhyb3VnaCBgZGVoeWRyYXRlU3RlcEFyZ3VtZW50c2AgLyBgaHlkcmF0ZVN0ZXBBcmd1bWVudHNgXG4gICAgICAgICAgLy8gKGhhbmRsZXMgRE9NRXhjZXB0aW9uLCBjdXN0b20gZXJyb3JzLCBlbmNyeXB0aW9uLCBldGMuKSBpbnN0ZWFkIG9mXG4gICAgICAgICAgLy8gYmFyZSBKU09OLnN0cmluZ2lmeSB3aGljaCBsb3NlcyB0eXBlIGluZm9ybWF0aW9uIGFuZCBkcm9wcyB1bmRlZmluZWQuXG4gICAgICAgICAgLy8gc3RyZWFtTmFtZSBpcyBzZXQgb24gdGhlIHF1ZXVlIGl0ZW0gYXQgY29udHJvbGxlciBjb25zdHJ1Y3Rpb24gdGltZVxuICAgICAgICAgIC8vIChzZWUgd29ya2Zsb3cvYWJvcnQtY29udHJvbGxlci50cykuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbU5hbWUgPSBnZXRBYm9ydFN0cmVhbUlkRnJvbVRva2VuKHF1ZXVlSXRlbS50b2tlbik7XG4gICAgICAgICAgICBhd2FpdCB3b3JsZC5zdHJlYW1zLndyaXRlKFxuICAgICAgICAgICAgICBydW5JZCxcbiAgICAgICAgICAgICAgc3RyZWFtTmFtZSxcbiAgICAgICAgICAgICAgYWJvcnRQYXlsb2FkIGFzIFVpbnQ4QXJyYXlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBhd2FpdCB3b3JsZC5zdHJlYW1zLmNsb3NlKHJ1bklkLCBzdHJlYW1OYW1lKTtcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIEJlc3QtZWZmb3J0IHN0cmVhbSB3cml0ZSDigJQgaG9vayBldmVudCBwcm92aWRlcyB0aGUgZHVyYWJsZSBmYWxsYmFja1xuICAgICAgICAgICAgcnVudGltZUxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICAgICAgJ0ZhaWxlZCB0byB3cml0ZSBhYm9ydCBzdHJlYW0gcGFja2V0LCBob29rIGV2ZW50IHdpbGwgcHJvdmlkZSBmYWxsYmFjaycsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIGlmIChFbnRpdHlDb25mbGljdEVycm9yLmlzKGVycikgfHwgUnVuRXhwaXJlZEVycm9yLmlzKGVycikpIHtcbiAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgJ1dvcmtmbG93IHJ1biBhbHJlYWR5IGNvbXBsZXRlZCwgc2tpcHBpbmcgYWJvcnQnLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgICAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8vIENyZWF0ZSBzdGVwIGV2ZW50cyBmb3Igc3RlcHMgdGhhdCBkb24ndCBoYXZlIHRoZW0geWV0LlxuICAvLyBVbmxpa2UgVjEsIHdlIGRvIE5PVCBxdWV1ZSBzdGVwIG1lc3NhZ2VzIGZyb20gaGVyZSDigJQgdGhlIGNhbGxlclxuICAvLyBkZWNpZGVzIHdoaWNoIHN0ZXBzIHRvIGV4ZWN1dGUgaW5saW5lIHZzLiBxdWV1ZSB0byBiYWNrZ3JvdW5kLlxuICAvLyBXYWl0IGV2ZW50cyBhcmUgYWxzbyBjcmVhdGVkIGluIHBhcmFsbGVsIGJlbG93LlxuICBjb25zdCBzdGVwc05lZWRpbmdDcmVhdGlvbiA9IG5ldyBTZXQoXG4gICAgc3RlcEl0ZW1zXG4gICAgICAuZmlsdGVyKChxdWV1ZUl0ZW0pID0+ICFxdWV1ZUl0ZW0uaGFzQ3JlYXRlZEV2ZW50KVxuICAgICAgLm1hcCgocXVldWVJdGVtKSA9PiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZClcbiAgKTtcblxuICAvLyBDb3JyZWxhdGlvbiBJRHMgZm9yIHdoaWNoIFRISVMgc3VzcGVuc2lvbiBjYWxsIGFjdHVhbGx5IHdyb3RlIHRoZVxuICAvLyBzdGVwX2NyZWF0ZWQgZXZlbnQuIFBvcHVsYXRlZCBieSB0aGUgb3BzIGJlbG93IGFmdGVyIGEgc3VjY2Vzc2Z1bFxuICAvLyBldmVudHMuY3JlYXRlIOKAlCB1c2VkIGJ5IHRoZSBjYWxsZXIgdG8gY2xhaW0gb3duZXJzaGlwIGFuZCBhdm9pZFxuICAvLyByYWNpbmcgd2l0aCBjb25jdXJyZW50IGhhbmRsZXJzIG9uIHN0ZXAgZXhlY3V0aW9uLlxuICBjb25zdCBjcmVhdGVkU3RlcENvcnJlbGF0aW9uSWRzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgY29uc3Qgb3BzOiBQcm9taXNlPHZvaWQ+W10gPSBbXTtcblxuICAvLyBTdGVwczogY3JlYXRlIHN0ZXBfY3JlYXRlZCBldmVudHMgKG5vIHF1ZXVpbmcg4oCUIFYyIHJldHVybnMgcGVuZGluZyBzdGVwcyB0byBjYWxsZXIpXG4gIGZvciAoY29uc3QgcXVldWVJdGVtIG9mIHN0ZXBJdGVtcykge1xuICAgIGlmIChzdGVwc05lZWRpbmdDcmVhdGlvbi5oYXMocXVldWVJdGVtLmNvcnJlbGF0aW9uSWQpKSB7XG4gICAgICBvcHMucHVzaChcbiAgICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCBkZWh5ZHJhdGVkSW5wdXQgPSBhd2FpdCBkZWh5ZHJhdGVTdGVwQXJndW1lbnRzKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhcmdzOiBxdWV1ZUl0ZW0uYXJncyxcbiAgICAgICAgICAgICAgY2xvc3VyZVZhcnM6IHF1ZXVlSXRlbS5jbG9zdXJlVmFycyxcbiAgICAgICAgICAgICAgdGhpc1ZhbDogcXVldWVJdGVtLnRoaXNWYWwsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICBlbmNyeXB0aW9uS2V5LFxuICAgICAgICAgICAgc3VzcGVuc2lvbi5nbG9iYWxUaGlzXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zdCBzdGVwRXZlbnQ6IENyZWF0ZUV2ZW50UmVxdWVzdCA9IHtcbiAgICAgICAgICAgIGV2ZW50VHlwZTogJ3N0ZXBfY3JlYXRlZCcgYXMgY29uc3QsXG4gICAgICAgICAgICBzcGVjVmVyc2lvbjogU1BFQ19WRVJTSU9OX0NVUlJFTlQsXG4gICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgIGV2ZW50RGF0YToge1xuICAgICAgICAgICAgICBzdGVwTmFtZTogcXVldWVJdGVtLnN0ZXBOYW1lLFxuICAgICAgICAgICAgICBpbnB1dDogZGVoeWRyYXRlZElucHV0IGFzIFNlcmlhbGl6ZWREYXRhLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB3b3JsZC5ldmVudHMuY3JlYXRlKHJ1bklkLCBzdGVwRXZlbnQsIHsgcmVxdWVzdElkIH0pO1xuICAgICAgICAgICAgY3JlYXRlZFN0ZXBDb3JyZWxhdGlvbklkcy5hZGQocXVldWVJdGVtLmNvcnJlbGF0aW9uSWQpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgaWYgKEVudGl0eUNvbmZsaWN0RXJyb3IuaXMoZXJyKSkge1xuICAgICAgICAgICAgICBydW50aW1lTG9nZ2VyLmluZm8oJ1N0ZXAgYWxyZWFkeSBleGlzdHMsIGNvbnRpbnVpbmcnLCB7XG4gICAgICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgICAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSkoKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvLyBDcmVhdGUgd2FpdCBldmVudHMgKHNhbWUgYXMgVjEpXG4gIGZvciAoY29uc3QgcXVldWVJdGVtIG9mIHdhaXRJdGVtcykge1xuICAgIGlmICghcXVldWVJdGVtLmhhc0NyZWF0ZWRFdmVudCkge1xuICAgICAgb3BzLnB1c2goXG4gICAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3Qgd2FpdEV2ZW50OiBDcmVhdGVFdmVudFJlcXVlc3QgPSB7XG4gICAgICAgICAgICBldmVudFR5cGU6ICd3YWl0X2NyZWF0ZWQnIGFzIGNvbnN0LFxuICAgICAgICAgICAgc3BlY1ZlcnNpb246IFNQRUNfVkVSU0lPTl9DVVJSRU5ULFxuICAgICAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICAgICAgICBldmVudERhdGE6IHtcbiAgICAgICAgICAgICAgcmVzdW1lQXQ6IHF1ZXVlSXRlbS5yZXN1bWVBdCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgd29ybGQuZXZlbnRzLmNyZWF0ZShydW5JZCwgd2FpdEV2ZW50LCB7IHJlcXVlc3RJZCB9KTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGlmIChFbnRpdHlDb25mbGljdEVycm9yLmlzKGVycikpIHtcbiAgICAgICAgICAgICAgcnVudGltZUxvZ2dlci5pbmZvKCdXYWl0IGFscmVhZHkgZXhpc3RzLCBjb250aW51aW5nJywge1xuICAgICAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVyci5tZXNzYWdlLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pKClcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgd2FpdFVudGlsKFxuICAgIFByb21pc2UuYWxsKG9wcykuY2F0Y2goKG9wRXJyKSA9PiB7XG4gICAgICBjb25zdCBpc0Fib3J0RXJyb3IgPVxuICAgICAgICBvcEVycj8ubmFtZSA9PT0gJ0Fib3J0RXJyb3InIHx8IG9wRXJyPy5uYW1lID09PSAnUmVzcG9uc2VBYm9ydGVkJztcbiAgICAgIGlmICghaXNBYm9ydEVycm9yKSB0aHJvdyBvcEVycjtcbiAgICB9KVxuICApO1xuICBhd2FpdCBQcm9taXNlLmFsbChvcHMpO1xuXG4gIC8vIENhbGN1bGF0ZSBtaW5pbXVtIHRpbWVvdXQgZnJvbSB3YWl0c1xuICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICBjb25zdCBtaW5UaW1lb3V0U2Vjb25kcyA9IHdhaXRJdGVtcy5yZWR1Y2U8bnVtYmVyIHwgbnVsbD4oXG4gICAgKG1pbiwgcXVldWVJdGVtKSA9PiB7XG4gICAgICBjb25zdCByZXN1bWVBdE1zID0gcXVldWVJdGVtLnJlc3VtZUF0LmdldFRpbWUoKTtcbiAgICAgIGNvbnN0IGRlbGF5TXMgPSBNYXRoLm1heCgxMDAwLCByZXN1bWVBdE1zIC0gbm93KTtcbiAgICAgIGNvbnN0IHRpbWVvdXRTZWNvbmRzID0gTWF0aC5jZWlsKGRlbGF5TXMgLyAxMDAwKTtcbiAgICAgIGlmIChtaW4gPT09IG51bGwpIHJldHVybiB0aW1lb3V0U2Vjb25kcztcbiAgICAgIHJldHVybiBNYXRoLm1pbihtaW4sIHRpbWVvdXRTZWNvbmRzKTtcbiAgICB9LFxuICAgIG51bGxcbiAgKTtcblxuICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHtcbiAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dSdW5TdGF0dXMoJ3dvcmtmbG93X3N1c3BlbmRlZCcpLFxuICAgIC4uLkF0dHJpYnV0ZS5Xb3JrZmxvd1N0ZXBzQ3JlYXRlZChzdGVwSXRlbXMubGVuZ3RoKSxcbiAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dIb29rc0NyZWF0ZWQoaG9va3NOZWVkaW5nQ3JlYXRpb24ubGVuZ3RoKSxcbiAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dXYWl0c0NyZWF0ZWQod2FpdEl0ZW1zLmxlbmd0aCksXG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgcGVuZGluZ1N0ZXBzOiBzdGVwSXRlbXMsXG4gICAgY3JlYXRlZFN0ZXBDb3JyZWxhdGlvbklkcyxcbiAgICB0aW1lb3V0U2Vjb25kczogaGFzSG9va0NvbmZsaWN0ID8gMCA6IChtaW5UaW1lb3V0U2Vjb25kcyA/PyB1bmRlZmluZWQpLFxuICAgIGhhc0hvb2tDb25mbGljdCxcbiAgfTtcbn1cbiJdfQ==
|
|
367
|
+
/**
|
|
368
|
+
* Whether an `events.create` rejection is a deterministic attribute
|
|
369
|
+
* validation failure rather than a transient/storage error. Local Worlds
|
|
370
|
+
* (world-local, world-postgres) throw `AttributeValidationError` directly;
|
|
371
|
+
* remote Worlds surface the equivalent server-side rejection as a
|
|
372
|
+
* `WorkflowWorldError` with HTTP status 400. The name check covers
|
|
373
|
+
* `AttributeValidationError` instances from a different copy of
|
|
374
|
+
* `@workflow/world` than the one this package resolved.
|
|
375
|
+
*/
|
|
376
|
+
function isAttributeValidationFailure(err) {
|
|
377
|
+
if (err instanceof AttributeValidationError)
|
|
378
|
+
return true;
|
|
379
|
+
if (err instanceof Error && err.name === 'AttributeValidationError') {
|
|
380
|
+
return true;
|
|
381
|
+
}
|
|
382
|
+
return WorkflowWorldError.is(err) && err.status === 400;
|
|
383
|
+
}
|
|
384
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VzcGVuc2lvbi1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvc3VzcGVuc2lvbi1oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsVUFBVSxFQUNWLGlCQUFpQixFQUNqQixlQUFlLEVBQ2Ysa0JBQWtCLEdBQ25CLE1BQU0sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxFQUNMLHdCQUF3QixFQUd4QixvQkFBb0IsR0FHckIsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFRN0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUM3QyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM3RCxPQUFPLEtBQUssU0FBUyxNQUFNLHNDQUFzQyxDQUFDO0FBQ2xFLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLFlBQVksQ0FBQztBQTBDdkQsS0FBSyxVQUFVLGVBQWUsQ0FBQyxFQUM3QixLQUFLLEVBQ0wsS0FBSyxFQUNMLFNBQVMsRUFDVCxTQUFTLEVBQ1QsU0FBUyxHQU9WO0lBSUMsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFO1lBQ3pELFNBQVM7U0FDVixDQUFDLENBQUM7UUFFSCw2RUFBNkU7UUFDN0UsMEVBQTBFO1FBQzFFLHlFQUF5RTtRQUN6RSxJQUFJLE1BQU0sQ0FBQyxLQUFLLEVBQUUsU0FBUyxLQUFLLGVBQWUsRUFBRSxDQUFDO1lBQ2hELE9BQU87Z0JBQ0wsZUFBZSxFQUFFLElBQUk7Z0JBQ3JCLHNCQUFzQixFQUFFLEtBQUs7YUFDOUIsQ0FBQztRQUNKLENBQUM7UUFFRCxPQUFPO1lBQ0wsZUFBZSxFQUFFLEtBQUs7WUFDdEIsc0JBQXNCLEVBQUUsU0FBUyxDQUFDLGtCQUFrQixLQUFLLElBQUk7U0FDOUQsQ0FBQztJQUNKLENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsSUFBSSxtQkFBbUIsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNoQyxhQUFhLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxFQUFFO2dCQUNwRCxhQUFhLEVBQUUsS0FBSztnQkFDcEIsT0FBTyxFQUFFLEdBQUcsQ0FBQyxPQUFPO2FBQ3JCLENBQUMsQ0FBQztZQUNILE9BQU87Z0JBQ0wsZUFBZSxFQUFFLEtBQUs7Z0JBQ3RCLHNCQUFzQixFQUFFLFNBQVMsQ0FBQyxrQkFBa0IsS0FBSyxJQUFJO2FBQzlELENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxlQUFlLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDNUIsYUFBYSxDQUFDLElBQUksQ0FBQywrQ0FBK0MsRUFBRTtnQkFDbEUsYUFBYSxFQUFFLEtBQUs7Z0JBQ3BCLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTzthQUNyQixDQUFDLENBQUM7WUFDSCxPQUFPO2dCQUNMLGVBQWUsRUFBRSxLQUFLO2dCQUN0QixzQkFBc0IsRUFBRSxLQUFLO2FBQzlCLENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxHQUFHLENBQUM7SUFDWixDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxnQkFBZ0IsQ0FBQyxFQUNyQyxVQUFVLEVBQ1YsS0FBSyxFQUNMLEdBQUcsRUFDSCxJQUFJLEVBQ0osU0FBUyxHQUNlO0lBQ3hCLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUM7SUFDeEIsK0JBQStCO0lBQy9CLE1BQU0sU0FBUyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUN2QyxDQUFDLElBQUksRUFBbUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUNoRSxDQUFDO0lBQ0YsTUFBTSxZQUFZLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQzFDLENBQUMsSUFBSSxFQUFtQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxNQUFNLENBQ2hFLENBQUM7SUFDRixNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FDdkMsQ0FBQyxJQUFJLEVBQW1DLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLE1BQU0sQ0FDaEUsQ0FBQztJQUNGLE1BQU0sY0FBYyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUM1QyxDQUFDLElBQUksRUFBd0MsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssV0FBVyxDQUMxRSxDQUFDO0lBRUYsd0NBQXdDO0lBQ3hDLE1BQU0sb0JBQW9CLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FDOUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FDaEMsQ0FBQztJQUNGLE1BQU0sb0JBQW9CLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRTFFLHNDQUFzQztJQUN0QyxNQUFNLE1BQU0sR0FBRyxNQUFNLEtBQUssQ0FBQyxzQkFBc0IsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3pELE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUVuRSxxREFBcUQ7SUFDckQsTUFBTSxVQUFVLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUNsQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxFQUFFO1FBQzNDLE1BQU0sWUFBWSxHQUNoQixPQUFPLFNBQVMsQ0FBQyxRQUFRLEtBQUssV0FBVztZQUN2QyxDQUFDLENBQUMsU0FBUztZQUNYLENBQUMsQ0FBRSxDQUFDLE1BQU0sc0JBQXNCLENBQzVCLFNBQVMsQ0FBQyxRQUFRLEVBQ2xCLEtBQUssRUFDTCxhQUFhLEVBQ2IsVUFBVSxDQUFDLFVBQVUsQ0FDdEIsQ0FBb0IsQ0FBQztRQUM1QixPQUFPO1lBQ0wsU0FBUztZQUNULFNBQVMsRUFBRTtnQkFDVCxTQUFTLEVBQUUsY0FBdUI7Z0JBQ2xDLFdBQVcsRUFBRSxvQkFBb0I7Z0JBQ2pDLGFBQWEsRUFBRSxTQUFTLENBQUMsYUFBYTtnQkFDdEMsU0FBUyxFQUFFO29CQUNULEtBQUssRUFBRSxTQUFTLENBQUMsS0FBSztvQkFDdEIsUUFBUSxFQUFFLFlBQVk7b0JBQ3RCLFNBQVMsRUFBRSxTQUFTLENBQUMsU0FBUyxJQUFJLEtBQUs7b0JBQ3ZDLEdBQUcsQ0FBQyxTQUFTLENBQUMsUUFBUSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDO2lCQUM5QzthQUNGO1NBQ0YsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUNILENBQUM7SUFFRix5RUFBeUU7SUFDekUsc0NBQXNDO0lBQ3RDLHlFQUF5RTtJQUN6RSwrQ0FBK0M7SUFDL0MsSUFBSSxlQUFlLEdBQUcsS0FBSyxDQUFDO0lBQzVCLElBQUksc0JBQXNCLEdBQUcsS0FBSyxDQUFDO0lBRW5DLElBQUksVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUMxQixNQUFNLE9BQU8sR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQy9CLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLENBQzFDLGVBQWUsQ0FBQztZQUNkLEtBQUs7WUFDTCxLQUFLO1lBQ0wsU0FBUztZQUNULFNBQVM7WUFDVCxTQUFTO1NBQ1YsQ0FBQyxDQUNILENBQ0YsQ0FBQztRQUNGLGVBQWUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDbkUsc0JBQXNCLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FDbkMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FDMUMsQ0FBQztJQUNKLENBQUM7SUFFRCxtRkFBbUY7SUFDbkYsSUFBSSxvQkFBb0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDcEMsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUNmLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLEVBQUU7WUFDM0MsTUFBTSxpQkFBaUIsR0FBdUI7Z0JBQzVDLFNBQVMsRUFBRSxlQUF3QjtnQkFDbkMsV0FBVyxFQUFFLG9CQUFvQjtnQkFDakMsYUFBYSxFQUFFLFNBQVMsQ0FBQyxhQUFhO2dCQUN0QyxTQUFTLEVBQUU7b0JBQ1QsS0FBSyxFQUFFLFNBQVMsQ0FBQyxLQUFLO2lCQUN2QjthQUNGLENBQUM7WUFDRixJQUFJLENBQUM7Z0JBQ0gsTUFBTSxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1lBQ3JFLENBQUM7WUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNiLElBQUksbUJBQW1CLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7b0JBQ2hDLHNFQUFzRTtvQkFDdEUsYUFBYSxDQUFDLElBQUksQ0FDaEIsb0RBQW9ELEVBQ3BEO3dCQUNFLGFBQWEsRUFBRSxLQUFLO3dCQUNwQixhQUFhLEVBQUUsU0FBUyxDQUFDLGFBQWE7d0JBQ3RDLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTztxQkFDckIsQ0FDRixDQUFDO2dCQUNKLENBQUM7cUJBQU0sSUFBSSxlQUFlLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7b0JBQ25DLGFBQWEsQ0FBQyxJQUFJLENBQ2hCLHdEQUF3RCxFQUN4RDt3QkFDRSxhQUFhLEVBQUUsS0FBSzt3QkFDcEIsYUFBYSxFQUFFLFNBQVMsQ0FBQyxhQUFhO3dCQUN0QyxPQUFPLEVBQUUsR0FBRyxDQUFDLE9BQU87cUJBQ3JCLENBQ0YsQ0FBQztnQkFDSixDQUFDO3FCQUFNLElBQUksaUJBQWlCLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7b0JBQ3JDLHVEQUF1RDtvQkFDdkQsYUFBYSxDQUFDLElBQUksQ0FBQyx5Q0FBeUMsRUFBRTt3QkFDNUQsYUFBYSxFQUFFLEtBQUs7d0JBQ3BCLGFBQWEsRUFBRSxTQUFTLENBQUMsYUFBYTt3QkFDdEMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxPQUFPO3FCQUNyQixDQUFDLENBQUM7Z0JBQ0wsQ0FBQztxQkFBTSxDQUFDO29CQUNOLE1BQU0sR0FBRyxDQUFDO2dCQUNaLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFRCxzRkFBc0Y7SUFDdEYsTUFBTSxpQkFBaUIsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUMzQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQ2hELENBQUM7SUFFRixJQUFJLGlCQUFpQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNqQyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQ2YsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsRUFBRTtZQUN4QyxJQUFJLENBQUM7Z0JBQ0gsMENBQTBDO2dCQUMxQyxNQUFNLFlBQVksR0FBRyxNQUFNLHNCQUFzQixDQUMvQyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQyxXQUFXLEVBQUUsRUFDaEQsS0FBSyxFQUNMLGFBQWEsRUFDYixVQUFVLENBQUMsVUFBVSxDQUN0QixDQUFDO2dCQUVGLGdEQUFnRDtnQkFDaEQsTUFBTSxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUU7b0JBQy9CLFNBQVMsRUFBRSxlQUF3QjtvQkFDbkMsV0FBVyxFQUFFLG9CQUFvQjtvQkFDakMsYUFBYSxFQUFFLFNBQVMsQ0FBQyxhQUFhO29CQUN0QyxTQUFTLEVBQUU7d0JBQ1QsS0FBSyxFQUFFLFNBQVMsQ0FBQyxLQUFLO3dCQUN0QixPQUFPLEVBQUUsWUFBWTtxQkFDdEI7aUJBQ0YsQ0FBQyxDQUFDO2dCQUVILG1FQUFtRTtnQkFDbkUsb0VBQW9FO2dCQUNwRSx3RUFBd0U7Z0JBQ3hFLHFFQUFxRTtnQkFDckUsd0VBQXdFO2dCQUN4RSxzRUFBc0U7Z0JBQ3RFLHNDQUFzQztnQkFDdEMsSUFBSSxDQUFDO29CQUNILE1BQU0sVUFBVSxHQUFHLHlCQUF5QixDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDOUQsTUFBTSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FDdkIsS0FBSyxFQUNMLFVBQVUsRUFDVixZQUEwQixDQUMzQixDQUFDO29CQUNGLE1BQU0sS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dCQUMvQyxDQUFDO2dCQUFDLE1BQU0sQ0FBQztvQkFDUCxzRUFBc0U7b0JBQ3RFLGFBQWEsQ0FBQyxLQUFLLENBQ2pCLHVFQUF1RSxFQUN2RTt3QkFDRSxhQUFhLEVBQUUsS0FBSzt3QkFDcEIsYUFBYSxFQUFFLFNBQVMsQ0FBQyxhQUFhO3FCQUN2QyxDQUNGLENBQUM7Z0JBQ0osQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNiLElBQUksbUJBQW1CLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLGVBQWUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDM0QsYUFBYSxDQUFDLElBQUksQ0FDaEIsZ0RBQWdELEVBQ2hEO3dCQUNFLGFBQWEsRUFBRSxLQUFLO3dCQUNwQixhQUFhLEVBQUUsU0FBUyxDQUFDLGFBQWE7d0JBQ3RDLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTztxQkFDckIsQ0FDRixDQUFDO2dCQUNKLENBQUM7cUJBQU0sQ0FBQztvQkFDTixNQUFNLEdBQUcsQ0FBQztnQkFDWixDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0lBRUQseURBQXlEO0lBQ3pELGtFQUFrRTtJQUNsRSxpRUFBaUU7SUFDakUsa0RBQWtEO0lBQ2xELE1BQU0sb0JBQW9CLEdBQUcsSUFBSSxHQUFHLENBQ2xDLFNBQVM7U0FDTixNQUFNLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQztTQUNqRCxHQUFHLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FDL0MsQ0FBQztJQUVGLG9FQUFvRTtJQUNwRSxvRUFBb0U7SUFDcEUsa0VBQWtFO0lBQ2xFLHFEQUFxRDtJQUNyRCxNQUFNLHlCQUF5QixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFFcEQsTUFBTSxHQUFHLEdBQW9CLEVBQUUsQ0FBQztJQUVoQyxzRkFBc0Y7SUFDdEYsS0FBSyxNQUFNLFNBQVMsSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUNsQyxJQUFJLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQztZQUN0RCxHQUFHLENBQUMsSUFBSSxDQUNOLENBQUMsS0FBSyxJQUFJLEVBQUU7Z0JBQ1YsTUFBTSxlQUFlLEdBQUcsTUFBTSxzQkFBc0IsQ0FDbEQ7b0JBQ0UsSUFBSSxFQUFFLFNBQVMsQ0FBQyxJQUFJO29CQUNwQixXQUFXLEVBQUUsU0FBUyxDQUFDLFdBQVc7b0JBQ2xDLE9BQU8sRUFBRSxTQUFTLENBQUMsT0FBTztpQkFDM0IsRUFDRCxLQUFLLEVBQ0wsYUFBYSxFQUNiLFVBQVUsQ0FBQyxVQUFVLENBQ3RCLENBQUM7Z0JBQ0YsTUFBTSxTQUFTLEdBQXVCO29CQUNwQyxTQUFTLEVBQUUsY0FBdUI7b0JBQ2xDLFdBQVcsRUFBRSxvQkFBb0I7b0JBQ2pDLGFBQWEsRUFBRSxTQUFTLENBQUMsYUFBYTtvQkFDdEMsU0FBUyxFQUFFO3dCQUNULFFBQVEsRUFBRSxTQUFTLENBQUMsUUFBUTt3QkFDNUIsS0FBSyxFQUFFLGVBQWlDO3FCQUN6QztpQkFDRixDQUFDO2dCQUNGLElBQUksQ0FBQztvQkFDSCxNQUFNLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO29CQUMzRCx5QkFBeUIsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxDQUFDO2dCQUN6RCxDQUFDO2dCQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7b0JBQ2IsSUFBSSxtQkFBbUIsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQzt3QkFDaEMsYUFBYSxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsRUFBRTs0QkFDcEQsYUFBYSxFQUFFLEtBQUs7NEJBQ3BCLGFBQWEsRUFBRSxTQUFTLENBQUMsYUFBYTs0QkFDdEMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxPQUFPO3lCQUNyQixDQUFDLENBQUM7b0JBQ0wsQ0FBQzt5QkFBTSxDQUFDO3dCQUNOLE1BQU0sR0FBRyxDQUFDO29CQUNaLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUMsQ0FBQyxFQUFFLENBQ0wsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQsa0NBQWtDO0lBQ2xDLEtBQUssTUFBTSxTQUFTLElBQUksU0FBUyxFQUFFLENBQUM7UUFDbEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUMvQixHQUFHLENBQUMsSUFBSSxDQUNOLENBQUMsS0FBSyxJQUFJLEVBQUU7Z0JBQ1YsTUFBTSxTQUFTLEdBQXVCO29CQUNwQyxTQUFTLEVBQUUsY0FBdUI7b0JBQ2xDLFdBQVcsRUFBRSxvQkFBb0I7b0JBQ2pDLGFBQWEsRUFBRSxTQUFTLENBQUMsYUFBYTtvQkFDdEMsU0FBUyxFQUFFO3dCQUNULFFBQVEsRUFBRSxTQUFTLENBQUMsUUFBUTtxQkFDN0I7aUJBQ0YsQ0FBQztnQkFDRixJQUFJLENBQUM7b0JBQ0gsTUFBTSxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQztnQkFDN0QsQ0FBQztnQkFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO29CQUNiLElBQUksbUJBQW1CLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7d0JBQ2hDLGFBQWEsQ0FBQyxJQUFJLENBQUMsaUNBQWlDLEVBQUU7NEJBQ3BELGFBQWEsRUFBRSxLQUFLOzRCQUNwQixhQUFhLEVBQUUsU0FBUyxDQUFDLGFBQWE7NEJBQ3RDLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTzt5QkFDckIsQ0FBQyxDQUFDO29CQUNMLENBQUM7eUJBQU0sQ0FBQzt3QkFDTixNQUFNLEdBQUcsQ0FBQztvQkFDWixDQUFDO2dCQUNILENBQUM7WUFDSCxDQUFDLENBQUMsRUFBRSxDQUNMLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssTUFBTSxTQUFTLElBQUksY0FBYyxFQUFFLENBQUM7UUFDdkMsR0FBRyxDQUFDLElBQUksQ0FDTixDQUFDLEtBQUssSUFBSSxFQUFFO1lBQ1YsSUFBSSxDQUFDO2dCQUNILE1BQU0sS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQ3ZCLEtBQUssRUFDTDtvQkFDRSxTQUFTLEVBQUUsVUFBVTtvQkFDckIsV0FBVyxFQUFFLG9CQUFvQjtvQkFDakMsYUFBYSxFQUFFLFNBQVMsQ0FBQyxhQUFhO29CQUN0QyxTQUFTLEVBQUU7d0JBQ1QsT0FBTyxFQUFFLFNBQVMsQ0FBQyxPQUFPO3dCQUMxQixNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO3dCQUM1QixHQUFHLENBQUMsU0FBUyxDQUFDLHVCQUF1Qjs0QkFDbkMsQ0FBQyxDQUFDLEVBQUUsdUJBQXVCLEVBQUUsSUFBSSxFQUFFOzRCQUNuQyxDQUFDLENBQUMsRUFBRSxDQUFDO3FCQUNSO2lCQUNGLEVBQ0QsRUFBRSxTQUFTLEVBQUUsQ0FDZCxDQUFDO1lBQ0osQ0FBQztZQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7Z0JBQ2IsSUFBSSxtQkFBbUIsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDaEMsYUFBYSxDQUFDLElBQUksQ0FDaEIscURBQXFELEVBQ3JEO3dCQUNFLGFBQWEsRUFBRSxLQUFLO3dCQUNwQixhQUFhLEVBQUUsU0FBUyxDQUFDLGFBQWE7d0JBQ3RDLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTztxQkFDckIsQ0FDRixDQUFDO2dCQUNKLENBQUM7cUJBQU0sSUFBSSw0QkFBNEIsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUM3QywrREFBK0Q7b0JBQy9ELDZEQUE2RDtvQkFDN0QsZ0VBQWdFO29CQUNoRSxnRUFBZ0U7b0JBQ2hFLDREQUE0RDtvQkFDNUQsOERBQThEO29CQUM5RCw4REFBOEQ7b0JBQzlELE1BQU0sS0FBSyxHQUFHLElBQUksVUFBVSxDQUMxQix1REFDRSxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUNqRCxFQUFFLENBQ0gsQ0FBQztvQkFDRixLQUFLLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQztvQkFDbEIsTUFBTSxLQUFLLENBQUM7Z0JBQ2QsQ0FBQztxQkFBTSxDQUFDO29CQUNOLE1BQU0sR0FBRyxDQUFDO2dCQUNaLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FDTCxDQUFDO0lBQ0osQ0FBQztJQUVELHdFQUF3RTtJQUN4RSx3RUFBd0U7SUFDeEUsdUVBQXVFO0lBQ3ZFLCtFQUErRTtJQUMvRSxtRkFBbUY7SUFDbkYsZ0ZBQWdGO0lBQ2hGLHVFQUF1RTtJQUN2RSxnRkFBZ0Y7SUFDaEYsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRXZCLGtEQUFrRDtJQUNsRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDdkIsSUFBSSxXQUFtRSxDQUFDO0lBQ3hFLEtBQUssTUFBTSxTQUFTLElBQUksU0FBUyxFQUFFLENBQUM7UUFDbEMsTUFBTSxVQUFVLEdBQUcsU0FBUyxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNoRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxVQUFVLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDakQsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLFdBQVcsSUFBSSxjQUFjLEdBQUcsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3pELFdBQVcsR0FBRztnQkFDWixPQUFPLEVBQUUsY0FBYztnQkFDdkIsYUFBYSxFQUFFLFNBQVMsQ0FBQyxhQUFhO2FBQ3ZDLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUksRUFBRSxhQUFhLENBQUM7UUFDbEIsR0FBRyxTQUFTLENBQUMsaUJBQWlCLENBQUMsb0JBQW9CLENBQUM7UUFDcEQsR0FBRyxTQUFTLENBQUMsb0JBQW9CLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztRQUNuRCxHQUFHLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUM7UUFDOUQsR0FBRyxTQUFTLENBQUMsb0JBQW9CLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztLQUNwRCxDQUFDLENBQUM7SUFFSCxPQUFPO1FBQ0wsWUFBWSxFQUFFLFNBQVM7UUFDdkIseUJBQXlCO1FBQ3pCLHFFQUFxRTtRQUNyRSx5Q0FBeUM7UUFDekMsV0FBVyxFQUFFLGVBQWUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxXQUFXO1FBQ3RELGVBQWU7UUFDZixzQkFBc0I7UUFDdEIsa0JBQWtCLEVBQUUsY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDO0tBQzlDLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxTQUFTLDRCQUE0QixDQUFDLEdBQVk7SUFDaEQsSUFBSSxHQUFHLFlBQVksd0JBQXdCO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDekQsSUFBSSxHQUFHLFlBQVksS0FBSyxJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssMEJBQTBCLEVBQUUsQ0FBQztRQUNwRSxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxPQUFPLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLEdBQUcsQ0FBQztBQUMxRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBTcGFuIH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvYXBpJztcbmltcG9ydCB7XG4gIEVudGl0eUNvbmZsaWN0RXJyb3IsXG4gIEZhdGFsRXJyb3IsXG4gIEhvb2tOb3RGb3VuZEVycm9yLFxuICBSdW5FeHBpcmVkRXJyb3IsXG4gIFdvcmtmbG93V29ybGRFcnJvcixcbn0gZnJvbSAnQHdvcmtmbG93L2Vycm9ycyc7XG5pbXBvcnQge1xuICBBdHRyaWJ1dGVWYWxpZGF0aW9uRXJyb3IsXG4gIHR5cGUgQ3JlYXRlRXZlbnRSZXF1ZXN0LFxuICB0eXBlIFNlcmlhbGl6ZWREYXRhLFxuICBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgdHlwZSBXb3JrZmxvd1J1bixcbiAgdHlwZSBXb3JsZCxcbn0gZnJvbSAnQHdvcmtmbG93L3dvcmxkJztcbmltcG9ydCB7IGltcG9ydEtleSB9IGZyb20gJy4uL2VuY3J5cHRpb24uanMnO1xuaW1wb3J0IHR5cGUge1xuICBBdHRyaWJ1dGVJbnZvY2F0aW9uUXVldWVJdGVtLFxuICBIb29rSW52b2NhdGlvblF1ZXVlSXRlbSxcbiAgU3RlcEludm9jYXRpb25RdWV1ZUl0ZW0sXG4gIFdhaXRJbnZvY2F0aW9uUXVldWVJdGVtLFxuICBXb3JrZmxvd1N1c3BlbnNpb24sXG59IGZyb20gJy4uL2dsb2JhbC5qcyc7XG5pbXBvcnQgeyBydW50aW1lTG9nZ2VyIH0gZnJvbSAnLi4vbG9nZ2VyLmpzJztcbmltcG9ydCB7IGRlaHlkcmF0ZVN0ZXBBcmd1bWVudHMgfSBmcm9tICcuLi9zZXJpYWxpemF0aW9uLmpzJztcbmltcG9ydCAqIGFzIEF0dHJpYnV0ZSBmcm9tICcuLi90ZWxlbWV0cnkvc2VtYW50aWMtY29udmVudGlvbnMuanMnO1xuaW1wb3J0IHsgZ2V0QWJvcnRTdHJlYW1JZEZyb21Ub2tlbiB9IGZyb20gJy4uL3V0aWwuanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN1c3BlbnNpb25IYW5kbGVyUGFyYW1zIHtcbiAgc3VzcGVuc2lvbjogV29ya2Zsb3dTdXNwZW5zaW9uO1xuICB3b3JsZDogV29ybGQ7XG4gIHJ1bjogV29ya2Zsb3dSdW47XG4gIHNwYW4/OiBTcGFuO1xuICByZXF1ZXN0SWQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogUmVzdWx0IG9mIGhhbmRsaW5nIGEgc3VzcGVuc2lvbi4gUmV0dXJucyBwZW5kaW5nIHN0ZXAgaXRlbXMgc28gdGhlIGNhbGxlclxuICogY2FuIGRlY2lkZSB3aGljaCB0byBleGVjdXRlIGlubGluZSB2cyBxdWV1ZSB0byBiYWNrZ3JvdW5kLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN1c3BlbnNpb25IYW5kbGVyUmVzdWx0IHtcbiAgLyoqIFBlbmRpbmcgc3RlcCBpdGVtcyB3aXRoIGV2ZW50cyBjcmVhdGVkIGJ1dCBOT1QgcXVldWVkICovXG4gIHBlbmRpbmdTdGVwczogU3RlcEludm9jYXRpb25RdWV1ZUl0ZW1bXTtcbiAgLyoqXG4gICAqIENvcnJlbGF0aW9uIElEcyBmb3Igd2hpY2ggdGhpcyBzdXNwZW5zaW9uIGNhbGwgYWN0dWFsbHkgd3JvdGUgdGhlXG4gICAqIHN0ZXBfY3JlYXRlZCBldmVudCAoYXMgb3Bwb3NlZCB0byBjYXRjaGluZyBFbnRpdHlDb25mbGljdEVycm9yIGJlY2F1c2VcbiAgICogYSBjb25jdXJyZW50IGhhbmRsZXIgd3JvdGUgaXQgZmlyc3QpLiBPbmx5IHRoZSBoYW5kbGVyIHRoYXQgd3JvdGUgdGhlXG4gICAqIHN0ZXBfY3JlYXRlZCBldmVudCBzaG91bGQgcXVldWUgLyBpbmxpbmUtZXhlY3V0ZSB0aGUgc3RlcCDigJQgdGhpc1xuICAgKiBndWFyYW50ZWVzIGEgc2luZ2xlIG93bmVyIHBlciBzdGVwLCBldmVuIHdoZW4gbXVsdGlwbGUgaGFuZGxlcnMgcmFjZVxuICAgKiBpbnRvIHRoZSBzYW1lIGJhdGNoIGJvdW5kYXJ5LlxuICAgKi9cbiAgY3JlYXRlZFN0ZXBDb3JyZWxhdGlvbklkczogU2V0PHN0cmluZz47XG4gIC8qKlxuICAgKiBUaGUgc29vbmVzdCBwZW5kaW5nIHdhaXQsIGlmIGFueTogc2Vjb25kcyB1bnRpbCBpdCBlbGFwc2VzIGFuZCB0aGVcbiAgICogY29ycmVsYXRpb25JZCBvZiB0aGUgd2FpdCB0aGF0IHByb2R1Y2VkIHRoYXQgdGltZW91dC4gVGhlXG4gICAqIGNvcnJlbGF0aW9uSWQgc2VlZHMgdGhlIGlkZW1wb3RlbmN5IGtleSBmb3IgdGhlIHdhaXQtY29udGludWF0aW9uXG4gICAqIHF1ZXVlIG1lc3NhZ2Ugc28gdGhhdCByZXBlYXRlZCBzdXNwZW5zaW9uIHBhc3NlcyBvdmVyIHRoZSBzYW1lXG4gICAqIHBlbmRpbmcgd2FpdCBjb2xsYXBzZSBpbnRvIGEgc2luZ2xlIGRlbGF5ZWQgY29udGludWF0aW9uLlxuICAgKi9cbiAgd2FpdFRpbWVvdXQ/OiB7IHNlY29uZHM6IG51bWJlcjsgY29ycmVsYXRpb25JZDogc3RyaW5nIH07XG4gIC8qKiBXaGV0aGVyIGEgaG9vayBjb25mbGljdCB3YXMgZGV0ZWN0ZWQgKHNob3VsZCByZS1pbnZva2UgaW1tZWRpYXRlbHkpICovXG4gIGhhc0hvb2tDb25mbGljdDogYm9vbGVhbjtcbiAgLyoqIFdoZXRoZXIgYSBgaG9vay5nZXRDb25mbGljdCgpYCBhd2FpdGVyIG5lZWRzIHRoZSB3b3JrZmxvdyB0byBjb250aW51ZSBpbW1lZGlhdGVseSAqL1xuICBoYXNBd2FpdGVkSG9va0NyZWF0aW9uOiBib29sZWFuO1xuICAvKiogV2hldGhlciBuYXRpdmUgd29ya2Zsb3cgYXR0cmlidXRlIGV2ZW50cyB3ZXJlIHdyaXR0ZW4gZm9yIHJlcGxheS4gKi9cbiAgaGFzQXR0cmlidXRlRXZlbnRzOiBib29sZWFuO1xufVxuXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVIb29rRXZlbnQoe1xuICB3b3JsZCxcbiAgcnVuSWQsXG4gIGhvb2tFdmVudCxcbiAgcXVldWVJdGVtLFxuICByZXF1ZXN0SWQsXG59OiB7XG4gIHdvcmxkOiBXb3JsZDtcbiAgcnVuSWQ6IHN0cmluZztcbiAgaG9va0V2ZW50OiBDcmVhdGVFdmVudFJlcXVlc3Q7XG4gIHF1ZXVlSXRlbTogSG9va0ludm9jYXRpb25RdWV1ZUl0ZW07XG4gIHJlcXVlc3RJZD86IHN0cmluZztcbn0pOiBQcm9taXNlPHtcbiAgaGFzSG9va0NvbmZsaWN0OiBib29sZWFuO1xuICBoYXNBd2FpdGVkSG9va0NyZWF0aW9uOiBib29sZWFuO1xufT4ge1xuICB0cnkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdvcmxkLmV2ZW50cy5jcmVhdGUocnVuSWQsIGhvb2tFdmVudCwge1xuICAgICAgcmVxdWVzdElkLFxuICAgIH0pO1xuXG4gICAgLy8gQ2hlY2sgaWYgdGhlIHdvcmxkIHJldHVybmVkIGEgaG9va19jb25mbGljdCBldmVudCBpbnN0ZWFkIG9mIGhvb2tfY3JlYXRlZC5cbiAgICAvLyBUaGUgaG9va19jb25mbGljdCBldmVudCBpcyBzdG9yZWQgaW4gdGhlIGV2ZW50IGxvZyBhbmQgd2lsbCBiZSByZXBsYXllZFxuICAgIC8vIG9uIHRoZSBuZXh0IHdvcmtmbG93IGludm9jYXRpb24sIGNhdXNpbmcgdGhlIGhvb2sncyBwcm9taXNlIHRvIHJlamVjdC5cbiAgICBpZiAocmVzdWx0LmV2ZW50Py5ldmVudFR5cGUgPT09ICdob29rX2NvbmZsaWN0Jykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaGFzSG9va0NvbmZsaWN0OiB0cnVlLFxuICAgICAgICBoYXNBd2FpdGVkSG9va0NyZWF0aW9uOiBmYWxzZSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGhhc0hvb2tDb25mbGljdDogZmFsc2UsXG4gICAgICBoYXNBd2FpdGVkSG9va0NyZWF0aW9uOiBxdWV1ZUl0ZW0uaGFzQ29uZmxpY3RBd2FpdGVyID09PSB0cnVlLFxuICAgIH07XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGlmIChFbnRpdHlDb25mbGljdEVycm9yLmlzKGVycikpIHtcbiAgICAgIHJ1bnRpbWVMb2dnZXIuaW5mbygnSG9vayBhbHJlYWR5IGV4aXN0cywgY29udGludWluZycsIHtcbiAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgIG1lc3NhZ2U6IGVyci5tZXNzYWdlLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBoYXNIb29rQ29uZmxpY3Q6IGZhbHNlLFxuICAgICAgICBoYXNBd2FpdGVkSG9va0NyZWF0aW9uOiBxdWV1ZUl0ZW0uaGFzQ29uZmxpY3RBd2FpdGVyID09PSB0cnVlLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoUnVuRXhwaXJlZEVycm9yLmlzKGVycikpIHtcbiAgICAgIHJ1bnRpbWVMb2dnZXIuaW5mbygnV29ya2Zsb3cgcnVuIGFscmVhZHkgY29tcGxldGVkLCBza2lwcGluZyBob29rJywge1xuICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgbWVzc2FnZTogZXJyLm1lc3NhZ2UsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGhhc0hvb2tDb25mbGljdDogZmFsc2UsXG4gICAgICAgIGhhc0F3YWl0ZWRIb29rQ3JlYXRpb246IGZhbHNlLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aHJvdyBlcnI7XG4gIH1cbn1cblxuLyoqXG4gKiBIYW5kbGVzIGEgd29ya2Zsb3cgc3VzcGVuc2lvbiBieSBwcm9jZXNzaW5nIGFsbCBwZW5kaW5nIG9wZXJhdGlvbnMgKGhvb2tzLCBzdGVwcywgd2FpdHMpLlxuICogQ3JlYXRlcyBldmVudHMgZm9yIGFsbCBvcGVyYXRpb25zIGJ1dCBkb2VzIE5PVCBxdWV1ZSBzdGVwIG1lc3NhZ2VzIOKAlCByZXR1cm5zIHRoZSBwZW5kaW5nXG4gKiBzdGVwcyBzbyB0aGUgY2FsbGVyIGNhbiBkZWNpZGUgd2hpY2ggdG8gZXhlY3V0ZSBpbmxpbmUgdnMgcXVldWUgdG8gYmFja2dyb3VuZC5cbiAqXG4gKiBQcm9jZXNzaW5nIG9yZGVyOlxuICogMS4gSG9va3MgYXJlIHByb2Nlc3NlZCBmaXJzdCB0byBwcmV2ZW50IHJhY2UgY29uZGl0aW9ucyB3aXRoIHdlYmhvb2sgcmVjZWl2ZXJzXG4gKiAyLiBTdGVwIGV2ZW50cyBhbmQgd2FpdCBldmVudHMgYXJlIGNyZWF0ZWQgaW4gcGFyYWxsZWxcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZVN1c3BlbnNpb24oe1xuICBzdXNwZW5zaW9uLFxuICB3b3JsZCxcbiAgcnVuLFxuICBzcGFuLFxuICByZXF1ZXN0SWQsXG59OiBTdXNwZW5zaW9uSGFuZGxlclBhcmFtcyk6IFByb21pc2U8U3VzcGVuc2lvbkhhbmRsZXJSZXN1bHQ+IHtcbiAgY29uc3QgcnVuSWQgPSBydW4ucnVuSWQ7XG4gIC8vIFNlcGFyYXRlIHF1ZXVlIGl0ZW1zIGJ5IHR5cGVcbiAgY29uc3Qgc3RlcEl0ZW1zID0gc3VzcGVuc2lvbi5zdGVwcy5maWx0ZXIoXG4gICAgKGl0ZW0pOiBpdGVtIGlzIFN0ZXBJbnZvY2F0aW9uUXVldWVJdGVtID0+IGl0ZW0udHlwZSA9PT0gJ3N0ZXAnXG4gICk7XG4gIGNvbnN0IGFsbEhvb2tJdGVtcyA9IHN1c3BlbnNpb24uc3RlcHMuZmlsdGVyKFxuICAgIChpdGVtKTogaXRlbSBpcyBIb29rSW52b2NhdGlvblF1ZXVlSXRlbSA9PiBpdGVtLnR5cGUgPT09ICdob29rJ1xuICApO1xuICBjb25zdCB3YWl0SXRlbXMgPSBzdXNwZW5zaW9uLnN0ZXBzLmZpbHRlcihcbiAgICAoaXRlbSk6IGl0ZW0gaXMgV2FpdEludm9jYXRpb25RdWV1ZUl0ZW0gPT4gaXRlbS50eXBlID09PSAnd2FpdCdcbiAgKTtcbiAgY29uc3QgYXR0cmlidXRlSXRlbXMgPSBzdXNwZW5zaW9uLnN0ZXBzLmZpbHRlcihcbiAgICAoaXRlbSk6IGl0ZW0gaXMgQXR0cmlidXRlSW52b2NhdGlvblF1ZXVlSXRlbSA9PiBpdGVtLnR5cGUgPT09ICdhdHRyaWJ1dGUnXG4gICk7XG5cbiAgLy8gU3BsaXQgaG9va3MgYnkgd2hhdCBhY3Rpb25zIHRoZXkgbmVlZFxuICBjb25zdCBob29rc05lZWRpbmdDcmVhdGlvbiA9IGFsbEhvb2tJdGVtcy5maWx0ZXIoXG4gICAgKGl0ZW0pID0+ICFpdGVtLmhhc0NyZWF0ZWRFdmVudFxuICApO1xuICBjb25zdCBob29rc05lZWRpbmdEaXNwb3NhbCA9IGFsbEhvb2tJdGVtcy5maWx0ZXIoKGl0ZW0pID0+IGl0ZW0uZGlzcG9zZWQpO1xuXG4gIC8vIFJlc29sdmUgZW5jcnlwdGlvbiBrZXkgZm9yIHRoaXMgcnVuXG4gIGNvbnN0IHJhd0tleSA9IGF3YWl0IHdvcmxkLmdldEVuY3J5cHRpb25LZXlGb3JSdW4/LihydW4pO1xuICBjb25zdCBlbmNyeXB0aW9uS2V5ID0gcmF3S2V5ID8gYXdhaXQgaW1wb3J0S2V5KHJhd0tleSkgOiB1bmRlZmluZWQ7XG5cbiAgLy8gQnVpbGQgYW5kIHByb2Nlc3MgaG9va19jcmVhdGVkIGV2ZW50cyAoc2FtZSBhcyBWMSlcbiAgY29uc3QgaG9va0V2ZW50cyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgIGhvb2tzTmVlZGluZ0NyZWF0aW9uLm1hcChhc3luYyAocXVldWVJdGVtKSA9PiB7XG4gICAgICBjb25zdCBob29rTWV0YWRhdGE6IFNlcmlhbGl6ZWREYXRhIHwgdW5kZWZpbmVkID1cbiAgICAgICAgdHlwZW9mIHF1ZXVlSXRlbS5tZXRhZGF0YSA9PT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgIDogKChhd2FpdCBkZWh5ZHJhdGVTdGVwQXJndW1lbnRzKFxuICAgICAgICAgICAgICBxdWV1ZUl0ZW0ubWV0YWRhdGEsXG4gICAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgICBlbmNyeXB0aW9uS2V5LFxuICAgICAgICAgICAgICBzdXNwZW5zaW9uLmdsb2JhbFRoaXNcbiAgICAgICAgICAgICkpIGFzIFNlcmlhbGl6ZWREYXRhKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHF1ZXVlSXRlbSxcbiAgICAgICAgaG9va0V2ZW50OiB7XG4gICAgICAgICAgZXZlbnRUeXBlOiAnaG9va19jcmVhdGVkJyBhcyBjb25zdCxcbiAgICAgICAgICBzcGVjVmVyc2lvbjogU1BFQ19WRVJTSU9OX0NVUlJFTlQsXG4gICAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICAgICAgZXZlbnREYXRhOiB7XG4gICAgICAgICAgICB0b2tlbjogcXVldWVJdGVtLnRva2VuLFxuICAgICAgICAgICAgbWV0YWRhdGE6IGhvb2tNZXRhZGF0YSxcbiAgICAgICAgICAgIGlzV2ViaG9vazogcXVldWVJdGVtLmlzV2ViaG9vayA/PyBmYWxzZSxcbiAgICAgICAgICAgIC4uLihxdWV1ZUl0ZW0uaXNTeXN0ZW0gJiYgeyBpc1N5c3RlbTogdHJ1ZSB9KSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9KVxuICApO1xuXG4gIC8vIFByb2Nlc3MgaG9va3MgZmlyc3QgdG8gcHJldmVudCByYWNlIGNvbmRpdGlvbnMgd2l0aCB3ZWJob29rIHJlY2VpdmVycy5cbiAgLy8gQWxsIGhvb2sgY3JlYXRpb25zIHJ1biBpbiBwYXJhbGxlbC5cbiAgLy8gVHJhY2sgYW55IGhvb2sgY29uZmxpY3RzIHRoYXQgb2NjdXIg4oCUIHRoZXNlIGFyZSByZXR1cm5lZCB0byB0aGUgY2FsbGVyXG4gIC8vIHNvIHRoZSBWMiBoYW5kbGVyIGNhbiByZS1pbnZva2UgaW1tZWRpYXRlbHkuXG4gIGxldCBoYXNIb29rQ29uZmxpY3QgPSBmYWxzZTtcbiAgbGV0IGhhc0F3YWl0ZWRIb29rQ3JlYXRpb24gPSBmYWxzZTtcblxuICBpZiAoaG9va0V2ZW50cy5sZW5ndGggPiAwKSB7XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgaG9va0V2ZW50cy5tYXAoKHsgaG9va0V2ZW50LCBxdWV1ZUl0ZW0gfSkgPT5cbiAgICAgICAgY3JlYXRlSG9va0V2ZW50KHtcbiAgICAgICAgICB3b3JsZCxcbiAgICAgICAgICBydW5JZCxcbiAgICAgICAgICBob29rRXZlbnQsXG4gICAgICAgICAgcXVldWVJdGVtLFxuICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICApO1xuICAgIGhhc0hvb2tDb25mbGljdCA9IHJlc3VsdHMuc29tZSgocmVzdWx0KSA9PiByZXN1bHQuaGFzSG9va0NvbmZsaWN0KTtcbiAgICBoYXNBd2FpdGVkSG9va0NyZWF0aW9uID0gcmVzdWx0cy5zb21lKFxuICAgICAgKHJlc3VsdCkgPT4gcmVzdWx0Lmhhc0F3YWl0ZWRIb29rQ3JlYXRpb25cbiAgICApO1xuICB9XG5cbiAgLy8gUHJvY2VzcyBob29rIGRpc3Bvc2FscyDigJQgdGhlc2UgcmVsZWFzZSBob29rIHRva2VucyBmb3IgcmV1c2UgYnkgb3RoZXIgd29ya2Zsb3dzLlxuICBpZiAoaG9va3NOZWVkaW5nRGlzcG9zYWwubGVuZ3RoID4gMCkge1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgaG9va3NOZWVkaW5nRGlzcG9zYWwubWFwKGFzeW5jIChxdWV1ZUl0ZW0pID0+IHtcbiAgICAgICAgY29uc3QgaG9va0Rpc3Bvc2VkRXZlbnQ6IENyZWF0ZUV2ZW50UmVxdWVzdCA9IHtcbiAgICAgICAgICBldmVudFR5cGU6ICdob29rX2Rpc3Bvc2VkJyBhcyBjb25zdCxcbiAgICAgICAgICBzcGVjVmVyc2lvbjogU1BFQ19WRVJTSU9OX0NVUlJFTlQsXG4gICAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICAgICAgZXZlbnREYXRhOiB7XG4gICAgICAgICAgICB0b2tlbjogcXVldWVJdGVtLnRva2VuLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgd29ybGQuZXZlbnRzLmNyZWF0ZShydW5JZCwgaG9va0Rpc3Bvc2VkRXZlbnQsIHsgcmVxdWVzdElkIH0pO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBpZiAoRW50aXR5Q29uZmxpY3RFcnJvci5pcyhlcnIpKSB7XG4gICAgICAgICAgICAvLyBIb29rIHdhcyBhbHJlYWR5IGRpc3Bvc2VkIGJ5IGEgY29uY3VycmVudCBpbnZvY2F0aW9uIOKAlCBzYWZlIHRvIHNraXBcbiAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgJ0hvb2sgYWxyZWFkeSBkaXNwb3NlZCwgc2tpcHBpbmcgZHVwbGljYXRlIGRpc3Bvc2FsJyxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVyci5tZXNzYWdlLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSBpZiAoUnVuRXhwaXJlZEVycm9yLmlzKGVycikpIHtcbiAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgJ1dvcmtmbG93IHJ1biBhbHJlYWR5IGNvbXBsZXRlZCwgc2tpcHBpbmcgaG9vayBkaXNwb3NhbCcsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKEhvb2tOb3RGb3VuZEVycm9yLmlzKGVycikpIHtcbiAgICAgICAgICAgIC8vIEhvb2sgbWF5IGhhdmUgYWxyZWFkeSBiZWVuIGRpc3Bvc2VkIG9yIG5ldmVyIGNyZWF0ZWRcbiAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIuaW5mbygnSG9vayBub3QgZm91bmQgZm9yIGRpc3Bvc2FsLCBjb250aW51aW5nJywge1xuICAgICAgICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICAgICAgICAgIG1lc3NhZ2U6IGVyci5tZXNzYWdlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8vIFByb2Nlc3MgYWJvcnQgcmVxdWVzdHMg4oCUIHJlc3VtZSB0aGUgaG9vayB3aXRoIGFib3J0IHBheWxvYWQgYW5kIHdyaXRlIHN0cmVhbSBwYWNrZXRcbiAgY29uc3QgaG9va3NOZWVkaW5nQWJvcnQgPSBhbGxIb29rSXRlbXMuZmlsdGVyKFxuICAgIChpdGVtKSA9PiBpdGVtLmFib3J0UmVxdWVzdGVkICYmICFpdGVtLmRpc3Bvc2VkXG4gICk7XG5cbiAgaWYgKGhvb2tzTmVlZGluZ0Fib3J0Lmxlbmd0aCA+IDApIHtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGhvb2tzTmVlZGluZ0Fib3J0Lm1hcChhc3luYyAocXVldWVJdGVtKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gRGVoeWRyYXRlIHRoZSBhYm9ydCBwYXlsb2FkIGZvciBzdG9yYWdlXG4gICAgICAgICAgY29uc3QgYWJvcnRQYXlsb2FkID0gYXdhaXQgZGVoeWRyYXRlU3RlcEFyZ3VtZW50cyhcbiAgICAgICAgICAgIHsgYWJvcnRlZDogdHJ1ZSwgcmVhc29uOiBxdWV1ZUl0ZW0uYWJvcnRSZWFzb24gfSxcbiAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgZW5jcnlwdGlvbktleSxcbiAgICAgICAgICAgIHN1c3BlbnNpb24uZ2xvYmFsVGhpc1xuICAgICAgICAgICk7XG5cbiAgICAgICAgICAvLyBDcmVhdGUgaG9va19yZWNlaXZlZCBldmVudCB3aXRoIGFib3J0IHBheWxvYWRcbiAgICAgICAgICBhd2FpdCB3b3JsZC5ldmVudHMuY3JlYXRlKHJ1bklkLCB7XG4gICAgICAgICAgICBldmVudFR5cGU6ICdob29rX3JlY2VpdmVkJyBhcyBjb25zdCxcbiAgICAgICAgICAgIHNwZWNWZXJzaW9uOiBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgZXZlbnREYXRhOiB7XG4gICAgICAgICAgICAgIHRva2VuOiBxdWV1ZUl0ZW0udG9rZW4sXG4gICAgICAgICAgICAgIHBheWxvYWQ6IGFib3J0UGF5bG9hZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyBXcml0ZSBzdHJlYW0gY2FuY2VsbGF0aW9uIHBhY2tldCBmb3IgcmVhbC10aW1lIHN0ZXAgcHJvcGFnYXRpb24uXG4gICAgICAgICAgLy8gUmV1c2UgdGhlIHNhbWUgZGVoeWRyYXRlZCBwYXlsb2FkIGFzIHRoZSBob29rIGV2ZW50IHNvIHRoZSByZWFzb25cbiAgICAgICAgICAvLyByb3VuZC10cmlwcyB0aHJvdWdoIGBkZWh5ZHJhdGVTdGVwQXJndW1lbnRzYCAvIGBoeWRyYXRlU3RlcEFyZ3VtZW50c2BcbiAgICAgICAgICAvLyAoaGFuZGxlcyBET01FeGNlcHRpb24sIGN1c3RvbSBlcnJvcnMsIGVuY3J5cHRpb24sIGV0Yy4pIGluc3RlYWQgb2ZcbiAgICAgICAgICAvLyBiYXJlIEpTT04uc3RyaW5naWZ5IHdoaWNoIGxvc2VzIHR5cGUgaW5mb3JtYXRpb24gYW5kIGRyb3BzIHVuZGVmaW5lZC5cbiAgICAgICAgICAvLyBzdHJlYW1OYW1lIGlzIHNldCBvbiB0aGUgcXVldWUgaXRlbSBhdCBjb250cm9sbGVyIGNvbnN0cnVjdGlvbiB0aW1lXG4gICAgICAgICAgLy8gKHNlZSB3b3JrZmxvdy9hYm9ydC1jb250cm9sbGVyLnRzKS5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtTmFtZSA9IGdldEFib3J0U3RyZWFtSWRGcm9tVG9rZW4ocXVldWVJdGVtLnRva2VuKTtcbiAgICAgICAgICAgIGF3YWl0IHdvcmxkLnN0cmVhbXMud3JpdGUoXG4gICAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgICBzdHJlYW1OYW1lLFxuICAgICAgICAgICAgICBhYm9ydFBheWxvYWQgYXMgVWludDhBcnJheVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGF3YWl0IHdvcmxkLnN0cmVhbXMuY2xvc2UocnVuSWQsIHN0cmVhbU5hbWUpO1xuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLy8gQmVzdC1lZmZvcnQgc3RyZWFtIHdyaXRlIOKAlCBob29rIGV2ZW50IHByb3ZpZGVzIHRoZSBkdXJhYmxlIGZhbGxiYWNrXG4gICAgICAgICAgICBydW50aW1lTG9nZ2VyLmRlYnVnKFxuICAgICAgICAgICAgICAnRmFpbGVkIHRvIHdyaXRlIGFib3J0IHN0cmVhbSBwYWNrZXQsIGhvb2sgZXZlbnQgd2lsbCBwcm92aWRlIGZhbGxiYWNrJyxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgaWYgKEVudGl0eUNvbmZsaWN0RXJyb3IuaXMoZXJyKSB8fCBSdW5FeHBpcmVkRXJyb3IuaXMoZXJyKSkge1xuICAgICAgICAgICAgcnVudGltZUxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICAnV29ya2Zsb3cgcnVuIGFscmVhZHkgY29tcGxldGVkLCBza2lwcGluZyBhYm9ydCcsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLy8gQ3JlYXRlIHN0ZXAgZXZlbnRzIGZvciBzdGVwcyB0aGF0IGRvbid0IGhhdmUgdGhlbSB5ZXQuXG4gIC8vIFVubGlrZSBWMSwgd2UgZG8gTk9UIHF1ZXVlIHN0ZXAgbWVzc2FnZXMgZnJvbSBoZXJlIOKAlCB0aGUgY2FsbGVyXG4gIC8vIGRlY2lkZXMgd2hpY2ggc3RlcHMgdG8gZXhlY3V0ZSBpbmxpbmUgdnMuIHF1ZXVlIHRvIGJhY2tncm91bmQuXG4gIC8vIFdhaXQgZXZlbnRzIGFyZSBhbHNvIGNyZWF0ZWQgaW4gcGFyYWxsZWwgYmVsb3cuXG4gIGNvbnN0IHN0ZXBzTmVlZGluZ0NyZWF0aW9uID0gbmV3IFNldChcbiAgICBzdGVwSXRlbXNcbiAgICAgIC5maWx0ZXIoKHF1ZXVlSXRlbSkgPT4gIXF1ZXVlSXRlbS5oYXNDcmVhdGVkRXZlbnQpXG4gICAgICAubWFwKChxdWV1ZUl0ZW0pID0+IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkKVxuICApO1xuXG4gIC8vIENvcnJlbGF0aW9uIElEcyBmb3Igd2hpY2ggVEhJUyBzdXNwZW5zaW9uIGNhbGwgYWN0dWFsbHkgd3JvdGUgdGhlXG4gIC8vIHN0ZXBfY3JlYXRlZCBldmVudC4gUG9wdWxhdGVkIGJ5IHRoZSBvcHMgYmVsb3cgYWZ0ZXIgYSBzdWNjZXNzZnVsXG4gIC8vIGV2ZW50cy5jcmVhdGUg4oCUIHVzZWQgYnkgdGhlIGNhbGxlciB0byBjbGFpbSBvd25lcnNoaXAgYW5kIGF2b2lkXG4gIC8vIHJhY2luZyB3aXRoIGNvbmN1cnJlbnQgaGFuZGxlcnMgb24gc3RlcCBleGVjdXRpb24uXG4gIGNvbnN0IGNyZWF0ZWRTdGVwQ29ycmVsYXRpb25JZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICBjb25zdCBvcHM6IFByb21pc2U8dm9pZD5bXSA9IFtdO1xuXG4gIC8vIFN0ZXBzOiBjcmVhdGUgc3RlcF9jcmVhdGVkIGV2ZW50cyAobm8gcXVldWluZyDigJQgVjIgcmV0dXJucyBwZW5kaW5nIHN0ZXBzIHRvIGNhbGxlcilcbiAgZm9yIChjb25zdCBxdWV1ZUl0ZW0gb2Ygc3RlcEl0ZW1zKSB7XG4gICAgaWYgKHN0ZXBzTmVlZGluZ0NyZWF0aW9uLmhhcyhxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCkpIHtcbiAgICAgIG9wcy5wdXNoKFxuICAgICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGRlaHlkcmF0ZWRJbnB1dCA9IGF3YWl0IGRlaHlkcmF0ZVN0ZXBBcmd1bWVudHMoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFyZ3M6IHF1ZXVlSXRlbS5hcmdzLFxuICAgICAgICAgICAgICBjbG9zdXJlVmFyczogcXVldWVJdGVtLmNsb3N1cmVWYXJzLFxuICAgICAgICAgICAgICB0aGlzVmFsOiBxdWV1ZUl0ZW0udGhpc1ZhbCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBydW5JZCxcbiAgICAgICAgICAgIGVuY3J5cHRpb25LZXksXG4gICAgICAgICAgICBzdXNwZW5zaW9uLmdsb2JhbFRoaXNcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IHN0ZXBFdmVudDogQ3JlYXRlRXZlbnRSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgZXZlbnRUeXBlOiAnc3RlcF9jcmVhdGVkJyBhcyBjb25zdCxcbiAgICAgICAgICAgIHNwZWNWZXJzaW9uOiBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgZXZlbnREYXRhOiB7XG4gICAgICAgICAgICAgIHN0ZXBOYW1lOiBxdWV1ZUl0ZW0uc3RlcE5hbWUsXG4gICAgICAgICAgICAgIGlucHV0OiBkZWh5ZHJhdGVkSW5wdXQgYXMgU2VyaWFsaXplZERhdGEsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IHdvcmxkLmV2ZW50cy5jcmVhdGUocnVuSWQsIHN0ZXBFdmVudCwgeyByZXF1ZXN0SWQgfSk7XG4gICAgICAgICAgICBjcmVhdGVkU3RlcENvcnJlbGF0aW9uSWRzLmFkZChxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBpZiAoRW50aXR5Q29uZmxpY3RFcnJvci5pcyhlcnIpKSB7XG4gICAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIuaW5mbygnU3RlcCBhbHJlYWR5IGV4aXN0cywgY29udGludWluZycsIHtcbiAgICAgICAgICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KSgpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIENyZWF0ZSB3YWl0IGV2ZW50cyAoc2FtZSBhcyBWMSlcbiAgZm9yIChjb25zdCBxdWV1ZUl0ZW0gb2Ygd2FpdEl0ZW1zKSB7XG4gICAgaWYgKCFxdWV1ZUl0ZW0uaGFzQ3JlYXRlZEV2ZW50KSB7XG4gICAgICBvcHMucHVzaChcbiAgICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB3YWl0RXZlbnQ6IENyZWF0ZUV2ZW50UmVxdWVzdCA9IHtcbiAgICAgICAgICAgIGV2ZW50VHlwZTogJ3dhaXRfY3JlYXRlZCcgYXMgY29uc3QsXG4gICAgICAgICAgICBzcGVjVmVyc2lvbjogU1BFQ19WRVJTSU9OX0NVUlJFTlQsXG4gICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgIGV2ZW50RGF0YToge1xuICAgICAgICAgICAgICByZXN1bWVBdDogcXVldWVJdGVtLnJlc3VtZUF0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB3b3JsZC5ldmVudHMuY3JlYXRlKHJ1bklkLCB3YWl0RXZlbnQsIHsgcmVxdWVzdElkIH0pO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgaWYgKEVudGl0eUNvbmZsaWN0RXJyb3IuaXMoZXJyKSkge1xuICAgICAgICAgICAgICBydW50aW1lTG9nZ2VyLmluZm8oJ1dhaXQgYWxyZWFkeSBleGlzdHMsIGNvbnRpbnVpbmcnLCB7XG4gICAgICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgICAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSkoKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBmb3IgKGNvbnN0IHF1ZXVlSXRlbSBvZiBhdHRyaWJ1dGVJdGVtcykge1xuICAgIG9wcy5wdXNoKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCB3b3JsZC5ldmVudHMuY3JlYXRlKFxuICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGV2ZW50VHlwZTogJ2F0dHJfc2V0JyxcbiAgICAgICAgICAgICAgc3BlY1ZlcnNpb246IFNQRUNfVkVSU0lPTl9DVVJSRU5ULFxuICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgZXZlbnREYXRhOiB7XG4gICAgICAgICAgICAgICAgY2hhbmdlczogcXVldWVJdGVtLmNoYW5nZXMsXG4gICAgICAgICAgICAgICAgd3JpdGVyOiB7IHR5cGU6ICd3b3JrZmxvdycgfSxcbiAgICAgICAgICAgICAgICAuLi4ocXVldWVJdGVtLmFsbG93UmVzZXJ2ZWRBdHRyaWJ1dGVzXG4gICAgICAgICAgICAgICAgICA/IHsgYWxsb3dSZXNlcnZlZEF0dHJpYnV0ZXM6IHRydWUgfVxuICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeyByZXF1ZXN0SWQgfVxuICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIGlmIChFbnRpdHlDb25mbGljdEVycm9yLmlzKGVycikpIHtcbiAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgJ1dvcmtmbG93IGF0dHJpYnV0ZSBldmVudCBhbHJlYWR5IGV4aXN0cywgY29udGludWluZycsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzQXR0cmlidXRlVmFsaWRhdGlvbkZhaWx1cmUoZXJyKSkge1xuICAgICAgICAgICAgLy8gRGV0ZXJtaW5pc3RpYyB2YWxpZGF0aW9uIHJlamVjdGlvbiBmcm9tIHRoZSBXb3JsZCDigJQgZS5nLiB0aGVcbiAgICAgICAgICAgIC8vIGN1bXVsYXRpdmUgcGVyLXJ1biBhdHRyaWJ1dGUgY2FwLCB3aGljaCBvbmx5IHRoZSBXb3JsZCBjYW5cbiAgICAgICAgICAgIC8vIGNoZWNrIGFnYWluc3QgdGhlIHJ1bidzIGV4aXN0aW5nIGF0dHJpYnV0ZXMuIFJlZGVsaXZlcmluZyB0aGVcbiAgICAgICAgICAgIC8vIG9yY2hlc3RyYXRvciBtZXNzYWdlIHJlcGxheXMgdGhlIHdvcmtmbG93IGludG8gdGhlIGV4YWN0IHNhbWVcbiAgICAgICAgICAgIC8vIHdyaXRlIGFuZCB0aGUgZXhhY3Qgc2FtZSByZWplY3Rpb24sIHNvIHJldHJ5aW5nIGNhbiBuZXZlclxuICAgICAgICAgICAgLy8gc3VjY2VlZC4gU3VyZmFjZSBpdCBhcyBhIEZhdGFsRXJyb3Igc28gdGhlIGNhbGxlciBmYWlscyB0aGVcbiAgICAgICAgICAgIC8vIHJ1biB3aXRoIGEgY2xlYXIgZXJyb3IgaW5zdGVhZCBvZiB3ZWRnaW5nIGl0IGluIHJlZGVsaXZlcnkuXG4gICAgICAgICAgICBjb25zdCBmYXRhbCA9IG5ldyBGYXRhbEVycm9yKFxuICAgICAgICAgICAgICBgZXhwZXJpbWVudGFsX3NldEF0dHJpYnV0ZXMgZmFpbGVkIFdvcmxkIHZhbGlkYXRpb246ICR7XG4gICAgICAgICAgICAgICAgZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpXG4gICAgICAgICAgICAgIH1gXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgZmF0YWwuY2F1c2UgPSBlcnI7XG4gICAgICAgICAgICB0aHJvdyBmYXRhbDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSkoKVxuICAgICk7XG4gIH1cblxuICAvLyBBd2FpdCB0aGUgc3RlcF9jcmVhdGVkIC8gd2FpdF9jcmVhdGVkIGV2ZW50IGNyZWF0ZXMgYmVmb3JlIHJldHVybmluZy5cbiAgLy8gVGhlIGNhbGxlciAod29ya2Zsb3dFbnRyeXBvaW50KSBvbmx5IGVucXVldWVzIHRoZSBzdGVwLWRpc3BhdGNoIHF1ZXVlXG4gIC8vIG1lc3NhZ2VzIEFGVEVSIGhhbmRsZVN1c3BlbnNpb24gcmVzb2x2ZXMsIGFuZCB0aGUgcXVldWUgaGFuZGxlciBhY2tzXG4gIC8vIHRoZSBvcmNoZXN0cmF0b3IgbWVzc2FnZSBvbmx5IGFmdGVyIHRoZSBjYWxsZXIgcmVzb2x2ZXMuIFNvIHRoZSBzdGVwX2NyZWF0ZWRcbiAgLy8gZXZlbnRzIG11c3QgYmUgZHVyYWJsZSBoZXJlLCBhbmQgdGhlIGRpc3BhdGNoIHNlbmRzIG11c3QgY29tcGxldGUgaW4gdGhlIGNhbGxlcixcbiAgLy8gYWxsIGJlZm9yZSBhY2suIElmIHRoZSBwcm9jZXNzIGNyYXNoZXMgYmVmb3JlIHRoaXMgcmVzb2x2ZXMsIHRoZSBvcmNoZXN0cmF0b3JcbiAgLy8gbWVzc2FnZSBpcyBub3QgYWNrZWQgYW5kIFZRUyByZWRlbGl2ZXJzLCByZS1jcmVhdGVzIHRoZSAoaWRlbXBvdGVudClcbiAgLy8gc3RlcF9jcmVhdGVkIGFuZCByZS1kaXNwYXRjaGVzLCBhbmQgcmVjb3ZlcnMgdGhlIHJ1biBpbnN0ZWFkIG9mIG9ycGhhbmluZyBpdC5cbiAgYXdhaXQgUHJvbWlzZS5hbGwob3BzKTtcblxuICAvLyBGaW5kIHRoZSBzb29uZXN0IHBlbmRpbmcgd2FpdCAobWluaW11bSB0aW1lb3V0KVxuICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICBsZXQgc29vbmVzdFdhaXQ6IHsgc2Vjb25kczogbnVtYmVyOyBjb3JyZWxhdGlvbklkOiBzdHJpbmcgfSB8IHVuZGVmaW5lZDtcbiAgZm9yIChjb25zdCBxdWV1ZUl0ZW0gb2Ygd2FpdEl0ZW1zKSB7XG4gICAgY29uc3QgcmVzdW1lQXRNcyA9IHF1ZXVlSXRlbS5yZXN1bWVBdC5nZXRUaW1lKCk7XG4gICAgY29uc3QgZGVsYXlNcyA9IE1hdGgubWF4KDEwMDAsIHJlc3VtZUF0TXMgLSBub3cpO1xuICAgIGNvbnN0IHRpbWVvdXRTZWNvbmRzID0gTWF0aC5jZWlsKGRlbGF5TXMgLyAxMDAwKTtcbiAgICBpZiAoIXNvb25lc3RXYWl0IHx8IHRpbWVvdXRTZWNvbmRzIDwgc29vbmVzdFdhaXQuc2Vjb25kcykge1xuICAgICAgc29vbmVzdFdhaXQgPSB7XG4gICAgICAgIHNlY29uZHM6IHRpbWVvdXRTZWNvbmRzLFxuICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgc3Bhbj8uc2V0QXR0cmlidXRlcyh7XG4gICAgLi4uQXR0cmlidXRlLldvcmtmbG93UnVuU3RhdHVzKCd3b3JrZmxvd19zdXNwZW5kZWQnKSxcbiAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dTdGVwc0NyZWF0ZWQoc3RlcEl0ZW1zLmxlbmd0aCksXG4gICAgLi4uQXR0cmlidXRlLldvcmtmbG93SG9va3NDcmVhdGVkKGhvb2tzTmVlZGluZ0NyZWF0aW9uLmxlbmd0aCksXG4gICAgLi4uQXR0cmlidXRlLldvcmtmbG93V2FpdHNDcmVhdGVkKHdhaXRJdGVtcy5sZW5ndGgpLFxuICB9KTtcblxuICByZXR1cm4ge1xuICAgIHBlbmRpbmdTdGVwczogc3RlcEl0ZW1zLFxuICAgIGNyZWF0ZWRTdGVwQ29ycmVsYXRpb25JZHMsXG4gICAgLy8gT24gaG9vayBjb25mbGljdCB0aGUgY2FsbGVyIHJlLWludm9rZXMgaW1tZWRpYXRlbHkgYW5kIG5ldmVyIHJlYWRzXG4gICAgLy8gdGhlIHdhaXQgdGltZW91dCwgc28gZG9uJ3QgcmVwb3J0IG9uZS5cbiAgICB3YWl0VGltZW91dDogaGFzSG9va0NvbmZsaWN0ID8gdW5kZWZpbmVkIDogc29vbmVzdFdhaXQsXG4gICAgaGFzSG9va0NvbmZsaWN0LFxuICAgIGhhc0F3YWl0ZWRIb29rQ3JlYXRpb24sXG4gICAgaGFzQXR0cmlidXRlRXZlbnRzOiBhdHRyaWJ1dGVJdGVtcy5sZW5ndGggPiAwLFxuICB9O1xufVxuXG4vKipcbiAqIFdoZXRoZXIgYW4gYGV2ZW50cy5jcmVhdGVgIHJlamVjdGlvbiBpcyBhIGRldGVybWluaXN0aWMgYXR0cmlidXRlXG4gKiB2YWxpZGF0aW9uIGZhaWx1cmUgcmF0aGVyIHRoYW4gYSB0cmFuc2llbnQvc3RvcmFnZSBlcnJvci4gTG9jYWwgV29ybGRzXG4gKiAod29ybGQtbG9jYWwsIHdvcmxkLXBvc3RncmVzKSB0aHJvdyBgQXR0cmlidXRlVmFsaWRhdGlvbkVycm9yYCBkaXJlY3RseTtcbiAqIHJlbW90ZSBXb3JsZHMgc3VyZmFjZSB0aGUgZXF1aXZhbGVudCBzZXJ2ZXItc2lkZSByZWplY3Rpb24gYXMgYVxuICogYFdvcmtmbG93V29ybGRFcnJvcmAgd2l0aCBIVFRQIHN0YXR1cyA0MDAuIFRoZSBuYW1lIGNoZWNrIGNvdmVyc1xuICogYEF0dHJpYnV0ZVZhbGlkYXRpb25FcnJvcmAgaW5zdGFuY2VzIGZyb20gYSBkaWZmZXJlbnQgY29weSBvZlxuICogYEB3b3JrZmxvdy93b3JsZGAgdGhhbiB0aGUgb25lIHRoaXMgcGFja2FnZSByZXNvbHZlZC5cbiAqL1xuZnVuY3Rpb24gaXNBdHRyaWJ1dGVWYWxpZGF0aW9uRmFpbHVyZShlcnI6IHVua25vd24pOiBib29sZWFuIHtcbiAgaWYgKGVyciBpbnN0YW5jZW9mIEF0dHJpYnV0ZVZhbGlkYXRpb25FcnJvcikgcmV0dXJuIHRydWU7XG4gIGlmIChlcnIgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnIubmFtZSA9PT0gJ0F0dHJpYnV0ZVZhbGlkYXRpb25FcnJvcicpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gV29ya2Zsb3dXb3JsZEVycm9yLmlzKGVycikgJiYgZXJyLnN0YXR1cyA9PT0gNDAwO1xufVxuIl19
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wait-continuation dispatch: delay + idempotency-key selection.
|
|
3
|
+
*
|
|
4
|
+
* When V2 suspension processing observes a pending wait, it enqueues a
|
|
5
|
+
* delayed "continuation" message that fires once the wait elapses and
|
|
6
|
+
* drives the next replay (which completes the wait via the "complete
|
|
7
|
+
* elapsed waits" pass). This module decides the message's `delaySeconds`
|
|
8
|
+
* and `idempotencyKey`.
|
|
9
|
+
*
|
|
10
|
+
* The continuation is keyed on the wait's correlationId: while a wait is
|
|
11
|
+
* pending, every replay pass over the run re-observes it (e.g., once per
|
|
12
|
+
* step completion in `Promise.all([steps..., sleep()])`), and without
|
|
13
|
+
* dedupe each pass would enqueue another delayed continuation — each one
|
|
14
|
+
* a spurious full replay when the wait elapses, and each a fresh message
|
|
15
|
+
* that resets the delivery-attempt runaway guard. A key is attached in
|
|
16
|
+
* all cases: some worlds (e.g. world-postgres) serialize key-less
|
|
17
|
+
* workflow messages per run, which would park the continuation behind
|
|
18
|
+
* the handler's own inline step execution and defeat the race semantics
|
|
19
|
+
* the continuation exists to provide.
|
|
20
|
+
*
|
|
21
|
+
* The bare correlationId cannot be the key in every case, though: world
|
|
22
|
+
* dedupe windows outlive the first delivery (VQS keeps idempotency
|
|
23
|
+
* records until message-retention TTL; world-postgres keeps a
|
|
24
|
+
* completed-keys cache), so once a key has been used, a later enqueue
|
|
25
|
+
* under the same key is silently dropped. Any situation where a
|
|
26
|
+
* continuation is delivered while its wait is still pending therefore
|
|
27
|
+
* needs a fresh key for the re-enqueue, or the wait's timer is lost and
|
|
28
|
+
* the run stalls until unrelated traffic happens to wake it. Two such
|
|
29
|
+
* situations exist, each with its own key variation:
|
|
30
|
+
*
|
|
31
|
+
* - Waits longer than the maximum queue delay are chained: the delay is
|
|
32
|
+
* clamped to `WAIT_CONTINUATION_MAX_DELAY_SECONDS` (23h — VQS messages
|
|
33
|
+
* have a 24h retention limit, and one hour of buffer matches
|
|
34
|
+
* world-vercel's own clamp for delayed re-enqueues), so the
|
|
35
|
+
* continuation intentionally fires early, re-observes the wait, and
|
|
36
|
+
* must enqueue the next hop. The key is suffixed with the hop index
|
|
37
|
+
* (`ceil(timeoutSeconds / maxDelay)`): stable for every re-observation
|
|
38
|
+
* within the same hop window (so passes dedupe), decremented at each
|
|
39
|
+
* hop delivery (so the chain always advances). Worlds without a delay
|
|
40
|
+
* limit (world-postgres, world-local) simply take the same ≤23h hops.
|
|
41
|
+
*
|
|
42
|
+
* - Near-elapsed waits (≤2s remaining) get a second-bucketed suffix. A
|
|
43
|
+
* continuation delivered marginally early (clock skew between the
|
|
44
|
+
* enqueuing and handling hosts; the ceil() on the delay can leave a ~0
|
|
45
|
+
* margin) re-observes the wait as pending with ~1s remaining and must
|
|
46
|
+
* be able to enqueue a fresh short-delay retry. The bucket suffix
|
|
47
|
+
* keeps that retry enqueueable (its ≥1s delay guarantees a later
|
|
48
|
+
* bucket) while still collapsing same-instant duplicates.
|
|
49
|
+
*
|
|
50
|
+
* Mid-range waits (more than the near-elapsed threshold, at most one
|
|
51
|
+
* hop) use the bare correlationId: every re-observation targets the same
|
|
52
|
+
* deadline, so deduping to the first message is semantically lossless.
|
|
53
|
+
* Host clock skew beyond the near-elapsed threshold could in principle
|
|
54
|
+
* deliver such a continuation early enough to re-observe its wait and
|
|
55
|
+
* lose the re-enqueue to the burnt key; the threshold is the skew
|
|
56
|
+
* tolerance we accept for the benefit of exactly-one continuation per
|
|
57
|
+
* wait.
|
|
58
|
+
*/
|
|
59
|
+
/**
|
|
60
|
+
* Maximum `delaySeconds` for a single wait-continuation message. Waits
|
|
61
|
+
* longer than this are chained across multiple hops. 23 hours: VQS
|
|
62
|
+
* messages have a 24h retention limit; the 1h buffer mirrors
|
|
63
|
+
* world-vercel's `MAX_DELAY_SECONDS`.
|
|
64
|
+
*/
|
|
65
|
+
export declare const WAIT_CONTINUATION_MAX_DELAY_SECONDS = 82800;
|
|
66
|
+
/**
|
|
67
|
+
* Waits with at most this many seconds remaining use a second-bucketed
|
|
68
|
+
* idempotency key so an early-delivered continuation can re-enqueue its
|
|
69
|
+
* short-delay retry. This is also the host clock-skew tolerance for
|
|
70
|
+
* mid-range waits keyed on the bare correlationId.
|
|
71
|
+
*/
|
|
72
|
+
export declare const NEAR_ELAPSED_WAIT_THRESHOLD_SECONDS = 2;
|
|
73
|
+
export interface WaitContinuationDispatch {
|
|
74
|
+
delaySeconds: number;
|
|
75
|
+
idempotencyKey: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Computes the queue delay and idempotency key for a wait-continuation
|
|
79
|
+
* message. `timeoutSeconds` is the time until the wait's `resumeAt`
|
|
80
|
+
* (floored at 1s by the suspension handler); `waitCorrelationId`
|
|
81
|
+
* identifies the wait so repeated suspension passes dedupe.
|
|
82
|
+
*/
|
|
83
|
+
export declare function getWaitContinuationDispatch(timeoutSeconds: number, waitCorrelationId: string, now?: number): WaitContinuationDispatch;
|
|
84
|
+
//# sourceMappingURL=wait-continuation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait-continuation.d.ts","sourceRoot":"","sources":["../../src/runtime/wait-continuation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,mCAAmC,QAAS,CAAC;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,mCAAmC,IAAI,CAAC;AAErD,MAAM,WAAW,wBAAwB;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,cAAc,EAAE,MAAM,EACtB,iBAAiB,EAAE,MAAM,EACzB,GAAG,GAAE,MAAmB,GACvB,wBAAwB,CAc1B"}
|