@workflow/core 5.0.0-beta.5 → 5.0.0-beta.51
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/README.md +5 -0
- package/dist/attribute-changes.d.ts +5 -0
- package/dist/attribute-changes.d.ts.map +1 -0
- package/dist/attribute-changes.js +25 -0
- package/dist/capabilities.d.ts +35 -2
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +74 -5
- package/dist/capture-stack.d.ts +1 -1
- package/dist/capture-stack.js +2 -2
- 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/classify-error.d.ts +19 -3
- package/dist/classify-error.d.ts.map +1 -1
- package/dist/classify-error.js +98 -6
- package/dist/context-violation-error.d.ts +5 -5
- package/dist/context-violation-error.d.ts.map +1 -1
- package/dist/context-violation-error.js +8 -6
- package/dist/create-hook.d.ts +72 -7
- package/dist/create-hook.d.ts.map +1 -1
- package/dist/create-hook.js +1 -1
- package/dist/define-hook.js +2 -2
- package/dist/describe-error.d.ts +7 -7
- package/dist/describe-error.d.ts.map +1 -1
- package/dist/describe-error.js +97 -12
- package/dist/encryption.d.ts +38 -4
- package/dist/encryption.d.ts.map +1 -1
- package/dist/encryption.js +96 -14
- package/dist/events-consumer.d.ts +297 -0
- package/dist/events-consumer.d.ts.map +1 -1
- package/dist/events-consumer.js +673 -42
- package/dist/flushable-stream.d.ts +97 -1
- package/dist/flushable-stream.d.ts.map +1 -1
- package/dist/flushable-stream.js +291 -11
- package/dist/global.d.ts +36 -2
- package/dist/global.d.ts.map +1 -1
- package/dist/global.js +21 -6
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/log-format.d.ts +2 -2
- package/dist/log-format.js +19 -12
- package/dist/logger.d.ts +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +10 -6
- package/dist/private.d.ts +226 -9
- package/dist/private.d.ts.map +1 -1
- package/dist/private.js +626 -7
- package/dist/replay-divergence.d.ts +25 -0
- package/dist/replay-divergence.d.ts.map +1 -0
- package/dist/replay-divergence.js +61 -0
- package/dist/replay-payload-cache.d.ts +64 -0
- package/dist/replay-payload-cache.d.ts.map +1 -0
- package/dist/replay-payload-cache.js +158 -0
- package/dist/runtime/compute-instance.d.ts +13 -0
- package/dist/runtime/compute-instance.d.ts.map +1 -0
- package/dist/runtime/compute-instance.js +14 -0
- package/dist/runtime/constants.d.ts +315 -0
- package/dist/runtime/constants.d.ts.map +1 -1
- package/dist/runtime/constants.js +502 -16
- package/dist/runtime/count-step-started-events.d.ts +52 -0
- package/dist/runtime/count-step-started-events.d.ts.map +1 -0
- package/dist/runtime/count-step-started-events.js +72 -0
- package/dist/runtime/deployment-guard.d.ts +99 -0
- package/dist/runtime/deployment-guard.d.ts.map +1 -0
- package/dist/runtime/deployment-guard.js +154 -0
- package/dist/runtime/get-port-lazy.d.ts +15 -0
- package/dist/runtime/get-port-lazy.d.ts.map +1 -1
- package/dist/runtime/get-port-lazy.js +75 -6
- package/dist/runtime/get-world-lazy.d.ts +5 -14
- package/dist/runtime/get-world-lazy.d.ts.map +1 -1
- package/dist/runtime/get-world-lazy.js +19 -29
- package/dist/runtime/helpers.d.ts +415 -29
- package/dist/runtime/helpers.d.ts.map +1 -1
- package/dist/runtime/helpers.js +686 -57
- package/dist/runtime/quickjs-assets.generated.d.ts +14 -0
- package/dist/runtime/quickjs-assets.generated.d.ts.map +1 -0
- package/dist/runtime/quickjs-assets.generated.js +30 -0
- package/dist/runtime/quickjs-entrypoint.d.ts +158 -0
- package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -0
- package/dist/runtime/quickjs-entrypoint.js +1863 -0
- package/dist/runtime/quickjs-log-view.d.ts +129 -0
- package/dist/runtime/quickjs-log-view.d.ts.map +1 -0
- package/dist/runtime/quickjs-log-view.js +229 -0
- package/dist/runtime/quickjs-runtime.d.ts +244 -0
- package/dist/runtime/quickjs-runtime.d.ts.map +1 -0
- package/dist/runtime/quickjs-runtime.js +2427 -0
- package/dist/runtime/quickjs-serde.d.ts +107 -0
- package/dist/runtime/quickjs-serde.d.ts.map +1 -0
- package/dist/runtime/quickjs-serde.js +2159 -0
- package/dist/runtime/replay-budget.d.ts +97 -0
- package/dist/runtime/replay-budget.d.ts.map +1 -0
- package/dist/runtime/replay-budget.js +139 -0
- package/dist/runtime/replay-recovery-reporter.d.ts +36 -0
- package/dist/runtime/replay-recovery-reporter.d.ts.map +1 -0
- package/dist/runtime/replay-recovery-reporter.js +64 -0
- package/dist/runtime/resume-hook.d.ts +91 -8
- package/dist/runtime/resume-hook.d.ts.map +1 -1
- package/dist/runtime/resume-hook.js +512 -89
- package/dist/runtime/resume-latency.d.ts +150 -0
- package/dist/runtime/resume-latency.d.ts.map +1 -0
- package/dist/runtime/resume-latency.js +155 -0
- package/dist/runtime/run-id-time.d.ts +19 -0
- package/dist/runtime/run-id-time.d.ts.map +1 -0
- package/dist/runtime/run-id-time.js +42 -0
- package/dist/runtime/run.d.ts +72 -7
- package/dist/runtime/run.d.ts.map +1 -1
- package/dist/runtime/run.js +280 -53
- package/dist/runtime/runs.d.ts +54 -3
- package/dist/runtime/runs.d.ts.map +1 -1
- package/dist/runtime/runs.js +126 -16
- package/dist/runtime/start.d.ts +101 -2
- package/dist/runtime/start.d.ts.map +1 -1
- package/dist/runtime/start.js +352 -61
- package/dist/runtime/step-executor.d.ts +186 -5
- package/dist/runtime/step-executor.d.ts.map +1 -1
- package/dist/runtime/step-executor.js +768 -130
- package/dist/runtime/step-latency.d.ts +220 -0
- package/dist/runtime/step-latency.d.ts.map +1 -0
- package/dist/runtime/step-latency.js +215 -0
- package/dist/runtime/step-ownership.d.ts +72 -0
- package/dist/runtime/step-ownership.d.ts.map +1 -0
- package/dist/runtime/step-ownership.js +114 -0
- package/dist/runtime/step-single-flight.d.ts +12 -0
- package/dist/runtime/step-single-flight.d.ts.map +1 -0
- package/dist/runtime/step-single-flight.js +75 -0
- package/dist/runtime/suspension-handler.d.ts +247 -7
- package/dist/runtime/suspension-handler.d.ts.map +1 -1
- package/dist/runtime/suspension-handler.js +1304 -125
- package/dist/runtime/unserializable-step.d.ts +34 -0
- package/dist/runtime/unserializable-step.d.ts.map +1 -0
- package/dist/runtime/unserializable-step.js +52 -0
- package/dist/runtime/vm-mode.d.ts +44 -0
- package/dist/runtime/vm-mode.d.ts.map +1 -0
- package/dist/runtime/vm-mode.js +62 -0
- package/dist/runtime/vm-serde-bundle.generated.d.ts +14 -0
- package/dist/runtime/vm-serde-bundle.generated.d.ts.map +1 -0
- package/dist/runtime/vm-serde-bundle.generated.js +16 -0
- package/dist/runtime/wait-continuation.d.ts +106 -0
- package/dist/runtime/wait-continuation.d.ts.map +1 -0
- package/dist/runtime/wait-continuation.js +136 -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/world-compatibility.d.ts +32 -0
- package/dist/runtime/world-compatibility.d.ts.map +1 -0
- package/dist/runtime/world-compatibility.js +44 -0
- package/dist/runtime/world-init.d.ts +17 -42
- package/dist/runtime/world-init.d.ts.map +1 -1
- package/dist/runtime/world-init.js +18 -43
- package/dist/runtime/world.d.ts +14 -2
- package/dist/runtime/world.d.ts.map +1 -1
- package/dist/runtime/world.js +75 -19
- package/dist/runtime.d.ts +10 -6
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +3911 -489
- package/dist/sealed-box.d.ts +167 -0
- package/dist/sealed-box.d.ts.map +1 -0
- package/dist/sealed-box.js +571 -0
- package/dist/serialization/client.d.ts +3 -3
- package/dist/serialization/client.d.ts.map +1 -1
- package/dist/serialization/client.js +8 -4
- package/dist/serialization/codec-devalue-vm.d.ts +16 -0
- package/dist/serialization/codec-devalue-vm.d.ts.map +1 -0
- package/dist/serialization/codec-devalue-vm.js +148 -0
- package/dist/serialization/codec-devalue.d.ts +1 -1
- package/dist/serialization/codec-devalue.d.ts.map +1 -1
- package/dist/serialization/codec-devalue.js +24 -6
- package/dist/serialization/codec.d.ts +37 -2
- package/dist/serialization/codec.d.ts.map +1 -1
- package/dist/serialization/codec.js +2 -2
- package/dist/serialization/compression.d.ts +105 -0
- package/dist/serialization/compression.d.ts.map +1 -0
- package/dist/serialization/compression.js +261 -0
- package/dist/serialization/encryption.d.ts +119 -17
- package/dist/serialization/encryption.d.ts.map +1 -1
- package/dist/serialization/encryption.js +152 -17
- package/dist/serialization/errors.d.ts +13 -0
- package/dist/serialization/errors.d.ts.map +1 -1
- package/dist/serialization/errors.js +20 -2
- package/dist/serialization/format.d.ts +6 -6
- package/dist/serialization/format.js +7 -7
- package/dist/serialization/hardened.d.ts +156 -0
- package/dist/serialization/hardened.d.ts.map +1 -0
- package/dist/serialization/hardened.js +538 -0
- package/dist/serialization/index.d.ts +10 -8
- package/dist/serialization/index.d.ts.map +1 -1
- package/dist/serialization/index.js +10 -8
- package/dist/serialization/reducers/class-vm.d.ts +20 -0
- package/dist/serialization/reducers/class-vm.d.ts.map +1 -0
- package/dist/serialization/reducers/class-vm.js +77 -0
- package/dist/serialization/reducers/class.d.ts.map +1 -1
- package/dist/serialization/reducers/class.js +11 -6
- package/dist/serialization/reducers/common-vm.d.ts +15 -0
- package/dist/serialization/reducers/common-vm.d.ts.map +1 -0
- package/dist/serialization/reducers/common-vm.js +616 -0
- package/dist/serialization/reducers/common.d.ts +1 -1
- package/dist/serialization/reducers/common.d.ts.map +1 -1
- package/dist/serialization/reducers/common.js +202 -62
- package/dist/serialization/reducers/step-function-vm.d.ts +44 -0
- package/dist/serialization/reducers/step-function-vm.d.ts.map +1 -0
- package/dist/serialization/reducers/step-function-vm.js +97 -0
- package/dist/serialization/reducers/step-function.d.ts.map +1 -1
- package/dist/serialization/reducers/step-function.js +25 -9
- package/dist/serialization/step.d.ts +4 -4
- package/dist/serialization/step.d.ts.map +1 -1
- package/dist/serialization/step.js +9 -5
- package/dist/serialization/types.d.ts +80 -1
- package/dist/serialization/types.d.ts.map +1 -1
- package/dist/serialization/types.js +15 -1
- package/dist/serialization/workflow-vm.d.ts +29 -0
- package/dist/serialization/workflow-vm.d.ts.map +1 -0
- package/dist/serialization/workflow-vm.js +74 -0
- package/dist/serialization-format.d.ts +64 -8
- package/dist/serialization-format.d.ts.map +1 -1
- package/dist/serialization-format.js +225 -73
- package/dist/serialization.d.ts +262 -34
- package/dist/serialization.d.ts.map +1 -1
- package/dist/serialization.js +1885 -277
- package/dist/set-attributes.d.ts +13 -0
- package/dist/set-attributes.d.ts.map +1 -0
- package/dist/set-attributes.js +60 -0
- package/dist/source-map.d.ts +25 -0
- package/dist/source-map.d.ts.map +1 -1
- package/dist/source-map.js +154 -10
- package/dist/step/context-storage.d.ts +63 -2
- package/dist/step/context-storage.d.ts.map +1 -1
- package/dist/step/context-storage.js +7 -5
- package/dist/step/writable-stream.d.ts +3 -3
- package/dist/step/writable-stream.d.ts.map +1 -1
- package/dist/step/writable-stream.js +80 -13
- package/dist/step.d.ts.map +1 -1
- package/dist/step.js +148 -27
- package/dist/symbols.d.ts +50 -0
- package/dist/symbols.d.ts.map +1 -1
- package/dist/symbols.js +51 -1
- package/dist/telemetry/semantic-conventions.d.ts +433 -2
- package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
- package/dist/telemetry/semantic-conventions.js +319 -3
- package/dist/telemetry.d.ts +91 -0
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +244 -17
- package/dist/test-support/orchestrator-context.d.ts +25 -0
- package/dist/test-support/orchestrator-context.d.ts.map +1 -0
- package/dist/test-support/orchestrator-context.js +107 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +23 -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.d.ts.map +1 -1
- package/dist/version.js +2 -2
- package/dist/vm/index.d.ts.map +1 -1
- package/dist/vm/index.js +84 -14
- package/dist/vm/script-cache.d.ts +26 -0
- package/dist/vm/script-cache.d.ts.map +1 -0
- package/dist/vm/script-cache.js +131 -0
- package/dist/vm/uint8array-base64.js +1 -1
- package/dist/workflow/abort-controller.d.ts +2 -2
- package/dist/workflow/abort-controller.d.ts.map +1 -1
- package/dist/workflow/abort-controller.js +88 -21
- 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 +45 -0
- package/dist/workflow/create-hook.d.ts.map +1 -1
- package/dist/workflow/create-hook.js +24 -3
- package/dist/workflow/get-workflow-metadata.js +2 -2
- package/dist/workflow/hook.d.ts.map +1 -1
- package/dist/workflow/hook.js +304 -47
- package/dist/workflow/index.d.ts +1 -0
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js +2 -1
- package/dist/workflow/set-attributes.d.ts +68 -0
- package/dist/workflow/set-attributes.d.ts.map +1 -0
- package/dist/workflow/set-attributes.js +60 -0
- package/dist/workflow/sleep.d.ts.map +1 -1
- package/dist/workflow/sleep.js +58 -12
- package/dist/workflow/world-init-stub.d.ts +3 -3
- package/dist/workflow/world-init-stub.js +4 -4
- package/dist/workflow.d.ts +95 -3
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +900 -561
- package/docs/api-reference/create-hook.mdx +89 -10
- package/docs/api-reference/create-webhook.mdx +16 -15
- package/docs/api-reference/define-hook.mdx +35 -33
- package/docs/api-reference/fatal-error.mdx +30 -8
- package/docs/api-reference/fetch.mdx +14 -10
- package/docs/api-reference/get-step-metadata.mdx +2 -2
- package/docs/api-reference/get-workflow-metadata.mdx +3 -3
- package/docs/api-reference/get-writable.mdx +7 -7
- package/docs/api-reference/index.mdx +4 -1
- package/docs/api-reference/retryable-error.mdx +1 -1
- package/docs/api-reference/set-attributes.mdx +61 -0
- package/docs/api-reference/sleep.mdx +4 -4
- package/docs/foundations/cancellation.mdx +31 -32
- package/docs/foundations/errors-and-retries.mdx +42 -11
- package/docs/foundations/hooks.mdx +64 -35
- package/docs/foundations/idempotency.mdx +244 -12
- package/docs/foundations/index.mdx +1 -23
- package/docs/foundations/meta.json +2 -1
- package/docs/foundations/serialization.mdx +21 -22
- package/docs/foundations/starting-workflows.mdx +106 -30
- package/docs/foundations/streaming.mdx +108 -60
- package/docs/foundations/versioning.mdx +263 -0
- package/docs/foundations/workflows-and-steps.mdx +9 -9
- package/docs/how-it-works/cancellation.mdx +63 -63
- package/docs/how-it-works/code-transform.mdx +83 -67
- package/docs/how-it-works/encryption.mdx +30 -26
- package/docs/how-it-works/event-sourcing.mdx +125 -34
- package/docs/how-it-works/framework-integrations.mdx +96 -337
- package/docs/how-it-works/understanding-directives.mdx +22 -22
- package/package.json +24 -15
- package/dist/runtime/step-handler.d.ts +0 -2
- package/dist/runtime/step-handler.d.ts.map +0 -1
- package/dist/runtime/step-handler.js +0 -776
package/dist/runtime/run.js
CHANGED
|
@@ -1,11 +1,81 @@
|
|
|
1
|
-
import { WorkflowRunCancelledError, WorkflowRunFailedError, WorkflowRunNotCompletedError, WorkflowRunNotFoundError, } from '@workflow/errors';
|
|
1
|
+
import { RunExpiredError, WorkflowRunCancelledError, WorkflowRunFailedError, WorkflowRunNotCompletedError, WorkflowRunNotFoundError, } from '@workflow/errors';
|
|
2
2
|
import { WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE } from '@workflow/serde';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { envNumber } from '@workflow/world/env-config';
|
|
4
|
+
import { SPEC_VERSION_CURRENT } from '@workflow/world/spec-version';
|
|
5
|
+
import { deriveRunPayloadKeys, } from '../serialization/encryption.js';
|
|
6
|
+
import { createForwardedWritable, getForwardedWritableEncryptionKey, getRunReadableStream, hydrateRunError, hydrateWorkflowReturnValue, tagForwardedWritableTarget, } from '../serialization.js';
|
|
6
7
|
import { getWorkflowRunStreamId } from '../util.js';
|
|
7
|
-
import { wakeUpRun, } from './runs.js';
|
|
8
8
|
import { getWorldLazy } from './get-world-lazy.js';
|
|
9
|
+
import { wakeUpRun, } from './runs.js';
|
|
10
|
+
const RETURN_VALUE_POLL_INTERVAL_MS = 1_000;
|
|
11
|
+
const PAYLOAD_TERMINAL_RUN_STATUSES = new Set([
|
|
12
|
+
'completed',
|
|
13
|
+
'failed',
|
|
14
|
+
]);
|
|
15
|
+
// Give resilient starts up to 10 seconds to create the run.
|
|
16
|
+
const NOT_FOUND_RETRY_DELAYS = [1_000, 3_000, 6_000];
|
|
17
|
+
/** @internal */
|
|
18
|
+
export function getReturnValuePollIntervalMs() {
|
|
19
|
+
return envNumber('WORKFLOW_RETURN_VALUE_POLL_INTERVAL_MS', RETURN_VALUE_POLL_INTERVAL_MS, { integer: true, min: 1 });
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* How long a single `runs.waitForTerminalStatus` call may block while waiting
|
|
23
|
+
* for a run to finish. The wait is re-issued until the run is terminal, so
|
|
24
|
+
* this is a per-call budget rather than a limit on total wait time: its only
|
|
25
|
+
* job is to bound one request so a stalled connection cannot hold the awaiting
|
|
26
|
+
* side forever.
|
|
27
|
+
*
|
|
28
|
+
* 50s is the largest budget `world-vercel` can actually request: it clamps to
|
|
29
|
+
* `REQUEST_TIMEOUT_MS` (60s) minus 10s of headroom, so the budget is always
|
|
30
|
+
* observed as a *response* (a non-terminal snapshot) rather than as a
|
|
31
|
+
* client-side timeout. Asking for more is silently reduced to that, so raising
|
|
32
|
+
* this without also raising `WORKFLOW_REQUEST_TIMEOUT_MS` has no effect.
|
|
33
|
+
*/
|
|
34
|
+
const RETURN_VALUE_WAIT_TIMEOUT_MS = 50_000;
|
|
35
|
+
/** @internal */
|
|
36
|
+
export function getReturnValueWaitTimeoutMs() {
|
|
37
|
+
return envNumber('WORKFLOW_RETURN_VALUE_WAIT_MS', RETURN_VALUE_WAIT_TIMEOUT_MS, { integer: true, min: 1 });
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* How many consecutive long-poll calls `await run.returnValue` will make
|
|
41
|
+
* before falling back to interval polling for the rest of the wait.
|
|
42
|
+
*
|
|
43
|
+
* A cap is worth having because a wait that keeps returning non-terminal is
|
|
44
|
+
* indistinguishable from one that is not working, and interval polling is the
|
|
45
|
+
* behavior we know is correct. It does **not** end the await: a run legitimately
|
|
46
|
+
* lasts hours or days, so exhausting the cap switches strategy and keeps
|
|
47
|
+
* waiting rather than throwing.
|
|
48
|
+
*
|
|
49
|
+
* Note the consequence, since it cuts against the reason the long poll exists:
|
|
50
|
+
* a run still going after `MAX x budget` (~8 minutes at the defaults) spends
|
|
51
|
+
* the remainder of its life polling once per
|
|
52
|
+
* `WORKFLOW_RETURN_VALUE_POLL_INTERVAL_MS`, which is more requests than
|
|
53
|
+
* continuing to long poll would have cost. Runs that outlive the cap are
|
|
54
|
+
* exactly the ones the request reduction helped most.
|
|
55
|
+
*/
|
|
56
|
+
const RETURN_VALUE_MAX_LONG_POLLS = 10;
|
|
57
|
+
/** @internal */
|
|
58
|
+
export function getReturnValueMaxLongPolls() {
|
|
59
|
+
return envNumber('WORKFLOW_RETURN_VALUE_MAX_LONG_POLLS', RETURN_VALUE_MAX_LONG_POLLS, { integer: true, min: 1 });
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Whether `await run.returnValue` may use the World's long poll
|
|
63
|
+
* (`runs.waitForTerminalStatus`) instead of interval-polling `runs.get`.
|
|
64
|
+
*
|
|
65
|
+
* Default **ON** wherever the World implements the method; a World that does
|
|
66
|
+
* not is already on the interval path with nothing to switch off. Reads
|
|
67
|
+
* `process.env.WORKFLOW_RETURN_VALUE_LONG_POLL` lazily; an explicit `'0'` /
|
|
68
|
+
* `'false'` is the kill switch, restoring the fixed-interval poll exactly as
|
|
69
|
+
* it behaved before the fast path existed.
|
|
70
|
+
*
|
|
71
|
+
* @internal
|
|
72
|
+
*/
|
|
73
|
+
export function isReturnValueLongPollEnabled() {
|
|
74
|
+
const raw = process.env.WORKFLOW_RETURN_VALUE_LONG_POLL;
|
|
75
|
+
if (raw === undefined || raw === '')
|
|
76
|
+
return true;
|
|
77
|
+
return !(raw === '0' || raw.toLowerCase() === 'false');
|
|
78
|
+
}
|
|
9
79
|
/**
|
|
10
80
|
* A handler class for a workflow run.
|
|
11
81
|
*/
|
|
@@ -54,17 +124,26 @@ export class Run {
|
|
|
54
124
|
* to be resolved once.
|
|
55
125
|
* @internal
|
|
56
126
|
*/
|
|
57
|
-
#getEncryptionKey() {
|
|
127
|
+
#getEncryptionKey(run) {
|
|
58
128
|
if (!this.#encryptionKeyPromise) {
|
|
59
129
|
this.#encryptionKeyPromise = (async () => {
|
|
60
130
|
const world = await this.#lazyWorldPromise;
|
|
61
|
-
const
|
|
62
|
-
const rawKey = await world.getEncryptionKeyForRun?.(
|
|
63
|
-
return rawKey ? await
|
|
131
|
+
const runData = run ?? (await world.runs.get(this.runId));
|
|
132
|
+
const rawKey = await world.getEncryptionKeyForRun?.(runData);
|
|
133
|
+
return rawKey ? await deriveRunPayloadKeys(rawKey) : undefined;
|
|
64
134
|
})();
|
|
65
135
|
}
|
|
66
136
|
return this.#encryptionKeyPromise;
|
|
67
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Defers fetching the run and its encryption key until a readable is first
|
|
140
|
+
* consumed. The first pull prefetches it so an encrypted first frame can join
|
|
141
|
+
* the lookup; this also applies to an empty consumed stream.
|
|
142
|
+
* @internal
|
|
143
|
+
*/
|
|
144
|
+
#getEncryptionKeyLazily() {
|
|
145
|
+
return () => this.#getEncryptionKey();
|
|
146
|
+
}
|
|
68
147
|
/**
|
|
69
148
|
* Interrupts pending `sleep()` calls, resuming the workflow early.
|
|
70
149
|
*
|
|
@@ -78,13 +157,20 @@ export class Run {
|
|
|
78
157
|
}
|
|
79
158
|
/**
|
|
80
159
|
* Cancels the workflow run.
|
|
160
|
+
*
|
|
161
|
+
* @param options - Optional cancellation settings. `cancelReason` records a
|
|
162
|
+
* free-text reason (max 512 chars) on the run_cancelled event, surfaced in
|
|
163
|
+
* the run detail view.
|
|
81
164
|
*/
|
|
82
|
-
async cancel() {
|
|
165
|
+
async cancel(options) {
|
|
83
166
|
'use step';
|
|
84
167
|
const world = await this.#lazyWorldPromise;
|
|
85
168
|
await world.events.create(this.runId, {
|
|
86
169
|
eventType: 'run_cancelled',
|
|
87
170
|
specVersion: SPEC_VERSION_CURRENT,
|
|
171
|
+
...(options?.cancelReason !== undefined
|
|
172
|
+
? { eventData: { cancelReason: options.cancelReason } }
|
|
173
|
+
: {}),
|
|
88
174
|
});
|
|
89
175
|
}
|
|
90
176
|
/**
|
|
@@ -107,11 +193,13 @@ export class Run {
|
|
|
107
193
|
*/
|
|
108
194
|
get status() {
|
|
109
195
|
'use step';
|
|
110
|
-
return this.#lazyWorldPromise.then((world) => world.runs
|
|
196
|
+
return this.#lazyWorldPromise.then((world) => world.runs
|
|
197
|
+
.get(this.runId, { resolveData: 'none' })
|
|
198
|
+
.then((run) => run.status));
|
|
111
199
|
}
|
|
112
200
|
/**
|
|
113
201
|
* The return value of the workflow run.
|
|
114
|
-
* Polls the workflow return value until
|
|
202
|
+
* Polls the workflow return value until the workflow run completes.
|
|
115
203
|
*/
|
|
116
204
|
get returnValue() {
|
|
117
205
|
'use step';
|
|
@@ -169,14 +257,11 @@ export class Run {
|
|
|
169
257
|
'use step';
|
|
170
258
|
const { ops = [], global = globalThis, startIndex, namespace } = options;
|
|
171
259
|
const name = getWorkflowRunStreamId(this.runId, namespace);
|
|
172
|
-
//
|
|
173
|
-
//
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
name,
|
|
178
|
-
startIndex,
|
|
179
|
-
});
|
|
260
|
+
// The resolver starts only on the readable's first pull, so construction
|
|
261
|
+
// is inert. A consumed empty stream still performs the speculative lookup
|
|
262
|
+
// to keep the first encrypted-frame path concurrent.
|
|
263
|
+
const encryptionKey = this.#getEncryptionKeyLazily();
|
|
264
|
+
const stream = getRunReadableStream(global, ops, this.runId, name, startIndex, encryptionKey);
|
|
180
265
|
const worldPromise = this.#lazyWorldPromise;
|
|
181
266
|
const runId = this.runId;
|
|
182
267
|
return Object.assign(stream, {
|
|
@@ -187,8 +272,126 @@ export class Run {
|
|
|
187
272
|
},
|
|
188
273
|
});
|
|
189
274
|
}
|
|
275
|
+
/** The writable stream of the workflow run. */
|
|
276
|
+
get writable() {
|
|
277
|
+
return this.getWritable();
|
|
278
|
+
}
|
|
190
279
|
/**
|
|
191
|
-
*
|
|
280
|
+
* Returns a writable that appends to this run's stream.
|
|
281
|
+
*
|
|
282
|
+
* Initialization is deferred until the first write. The run must already
|
|
283
|
+
* exist. The writable may be forwarded through `start()` and into steps, but
|
|
284
|
+
* grants no read access or additional authorization.
|
|
285
|
+
*
|
|
286
|
+
* @remarks
|
|
287
|
+
* `writer.close()` closes the shared stream. Contributors should call
|
|
288
|
+
* `releaseLock()`, which also drains pending writes.
|
|
289
|
+
*
|
|
290
|
+
* @param options - The writable stream options.
|
|
291
|
+
*/
|
|
292
|
+
getWritable(options = {}) {
|
|
293
|
+
'use step';
|
|
294
|
+
const { ops = [], global = globalThis, namespace } = options;
|
|
295
|
+
const name = getWorkflowRunStreamId(this.runId, namespace);
|
|
296
|
+
let targetPromise;
|
|
297
|
+
let writable;
|
|
298
|
+
const resolveTarget = () => {
|
|
299
|
+
targetPromise ??= this.#getMetadata().then(async (run) => {
|
|
300
|
+
const target = {
|
|
301
|
+
key: await getForwardedWritableEncryptionKey(this.runId, run.deploymentId, run.encryptionPublicKey),
|
|
302
|
+
deploymentId: run.deploymentId,
|
|
303
|
+
encryptionPublicKey: run.encryptionPublicKey,
|
|
304
|
+
};
|
|
305
|
+
tagForwardedWritableTarget(writable, target);
|
|
306
|
+
return target;
|
|
307
|
+
});
|
|
308
|
+
return targetPromise;
|
|
309
|
+
};
|
|
310
|
+
writable = createForwardedWritable({
|
|
311
|
+
global,
|
|
312
|
+
ops,
|
|
313
|
+
runId: this.runId,
|
|
314
|
+
name,
|
|
315
|
+
key: () => resolveTarget().then(({ key }) => key),
|
|
316
|
+
});
|
|
317
|
+
return writable;
|
|
318
|
+
}
|
|
319
|
+
/** Reads metadata, briefly retrying resilient starts. @internal */
|
|
320
|
+
async #getMetadata() {
|
|
321
|
+
const world = await this.#lazyWorldPromise;
|
|
322
|
+
const maxRetries = this.#resilientStart ? NOT_FOUND_RETRY_DELAYS.length : 0;
|
|
323
|
+
let attempt = 0;
|
|
324
|
+
while (true) {
|
|
325
|
+
try {
|
|
326
|
+
return await world.runs.get(this.runId, { resolveData: 'none' });
|
|
327
|
+
}
|
|
328
|
+
catch (error) {
|
|
329
|
+
if (!WorkflowRunNotFoundError.is(error) || attempt >= maxRetries) {
|
|
330
|
+
throw error;
|
|
331
|
+
}
|
|
332
|
+
const delay = NOT_FOUND_RETRY_DELAYS[attempt];
|
|
333
|
+
attempt++;
|
|
334
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
/** @internal */
|
|
339
|
+
async #resolveTerminalReturnValue(run) {
|
|
340
|
+
// Expiry is checked before the status branches, and deliberately so.
|
|
341
|
+
//
|
|
342
|
+
// Past its retention boundary a run's payloads are gone but its metadata
|
|
343
|
+
// usually is not, so `run.output` and `run.error` hydrate to an
|
|
344
|
+
// expired-data placeholder rather than to anything the caller asked for.
|
|
345
|
+
// Handing that back as if it were the return value — or wrapping it as
|
|
346
|
+
// the `cause` of a WorkflowRunFailedError — is worse than failing: it is
|
|
347
|
+
// indistinguishable from the workflow having genuinely returned it.
|
|
348
|
+
//
|
|
349
|
+
// A run started with `experimental_retention: 0` reaches this almost
|
|
350
|
+
// immediately (its purge races, and usually beats, the caller's own read
|
|
351
|
+
// of the result). An ordinary run reaches it whenever it is read after
|
|
352
|
+
// the World's default window. Both are the same condition and get the
|
|
353
|
+
// same terminal, non-retryable error, carrying whatever metadata
|
|
354
|
+
// survived so the caller can still tell success from failure.
|
|
355
|
+
//
|
|
356
|
+
// When even the metadata is gone the World reports the run as missing and
|
|
357
|
+
// the caller gets WorkflowRunNotFoundError from the read above instead —
|
|
358
|
+
// there is nothing left here to describe.
|
|
359
|
+
const expiredAt = run.expiredAt;
|
|
360
|
+
if (expiredAt != null && expiredAt <= new Date()) {
|
|
361
|
+
throw new RunExpiredError(`Run "${this.runId}" ${run.status === 'completed' ? 'completed' : `is ${run.status}`}, but its data expired at ${expiredAt.toISOString()} and is no longer readable.`, this.runId, run.status, expiredAt);
|
|
362
|
+
}
|
|
363
|
+
if (run.status === 'completed') {
|
|
364
|
+
const encryptionKey = await this.#getEncryptionKey(run);
|
|
365
|
+
return await hydrateWorkflowReturnValue(run.output, this.runId, encryptionKey);
|
|
366
|
+
}
|
|
367
|
+
if (run.status === 'cancelled') {
|
|
368
|
+
throw new WorkflowRunCancelledError(this.runId);
|
|
369
|
+
}
|
|
370
|
+
if (run.status === 'failed') {
|
|
371
|
+
// Hydrate the serialized run error so the original thrown value
|
|
372
|
+
// (with its type identity, cause chain, etc.) is set as the
|
|
373
|
+
// `cause` on WorkflowRunFailedError.
|
|
374
|
+
const encryptionKey = await this.#getEncryptionKey(run);
|
|
375
|
+
let hydratedError;
|
|
376
|
+
try {
|
|
377
|
+
hydratedError = await hydrateRunError(run.error, this.runId, encryptionKey);
|
|
378
|
+
}
|
|
379
|
+
catch {
|
|
380
|
+
// If hydration fails, surface a generic fallback rather than
|
|
381
|
+
// leaving the user with a raw Uint8Array. The run's errorCode
|
|
382
|
+
// is still preserved on the thrown WorkflowRunFailedError.
|
|
383
|
+
hydratedError = new Error('Failed to hydrate workflow run error');
|
|
384
|
+
}
|
|
385
|
+
throw new WorkflowRunFailedError(this.runId, hydratedError, {
|
|
386
|
+
errorCode: run.errorCode,
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
// Terminal statuses are immutable, but if an inconsistent world returns
|
|
390
|
+
// a non-terminal full record, resume polling safely.
|
|
391
|
+
throw new WorkflowRunNotCompletedError(this.runId, run.status);
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Polls the workflow return value until the workflow run completes.
|
|
192
395
|
* @internal
|
|
193
396
|
* @returns The workflow return value.
|
|
194
397
|
*/
|
|
@@ -198,57 +401,81 @@ export class Run {
|
|
|
198
401
|
// not exist yet. Retry on WorkflowRunNotFoundError up to 3 times
|
|
199
402
|
// (1s + 3s + 6s = 10s total) to give the queue time to deliver
|
|
200
403
|
// and the runtime to create the run via run_started.
|
|
201
|
-
// When resilientStart is false, 404 is a real error
|
|
404
|
+
// When resilientStart is false, 404 is a real error: fail fast.
|
|
202
405
|
let notFoundRetries = 0;
|
|
203
|
-
const NOT_FOUND_MAX_RETRIES = this.#resilientStart
|
|
204
|
-
|
|
406
|
+
const NOT_FOUND_MAX_RETRIES = this.#resilientStart
|
|
407
|
+
? NOT_FOUND_RETRY_DELAYS.length
|
|
408
|
+
: 0;
|
|
409
|
+
// Prefer the World's long poll: one read that the backend holds open
|
|
410
|
+
// until the run finishes, instead of asking again every second and
|
|
411
|
+
// paying up to a full interval of quantization on a run that already
|
|
412
|
+
// ended. Worlds that cannot wait do not implement it (see
|
|
413
|
+
// `Storage['runs'].waitForTerminalStatus`) and this stays the exact
|
|
414
|
+
// fixed-interval poll it has always been, as does an operator who
|
|
415
|
+
// throws the `WORKFLOW_RETURN_VALUE_LONG_POLL=0` kill switch.
|
|
416
|
+
const waitForTerminalStatus = isReturnValueLongPollEnabled()
|
|
417
|
+
? world.runs.waitForTerminalStatus?.bind(world.runs)
|
|
418
|
+
: undefined;
|
|
419
|
+
// Long polls spent so far. Once the cap is reached the loop keeps waiting
|
|
420
|
+
// but on the interval path, which is the strategy we know is correct; see
|
|
421
|
+
// `RETURN_VALUE_MAX_LONG_POLLS`. Never a reason to stop awaiting.
|
|
422
|
+
let longPolls = 0;
|
|
423
|
+
const maxLongPolls = getReturnValueMaxLongPolls();
|
|
205
424
|
// NOTE: when this poll runs inside a step (e.g. the step that a parent
|
|
206
425
|
// workflow uses to await a child workflow's `returnValue`), it blocks
|
|
207
426
|
// a queue worker slot for as long as the child run takes to finish.
|
|
208
427
|
// Worker-based worlds like `world-postgres` must be sized to cover the
|
|
209
|
-
// peak number of such polls in flight
|
|
428
|
+
// peak number of such polls in flight; see the `queueConcurrency`
|
|
210
429
|
// default on the Postgres world and the notes in the eager-processing
|
|
211
430
|
// changelog for details.
|
|
212
431
|
while (true) {
|
|
432
|
+
const iterationStartedAt = Date.now();
|
|
213
433
|
try {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
434
|
+
// Metadata only, either way: the status is all this iteration needs,
|
|
435
|
+
// and payload refs are resolved once below, after a terminal status is
|
|
436
|
+
// observed.
|
|
437
|
+
const useLongPoll = waitForTerminalStatus && longPolls < maxLongPolls;
|
|
438
|
+
if (useLongPoll)
|
|
439
|
+
longPolls++;
|
|
440
|
+
const runMetadata = useLongPoll
|
|
441
|
+
? await waitForTerminalStatus(this.runId, {
|
|
442
|
+
timeoutMs: getReturnValueWaitTimeoutMs(),
|
|
443
|
+
resolveData: 'none',
|
|
444
|
+
})
|
|
445
|
+
: await world.runs.get(this.runId, {
|
|
446
|
+
resolveData: 'none',
|
|
447
|
+
});
|
|
448
|
+
if (runMetadata.status === 'cancelled') {
|
|
220
449
|
throw new WorkflowRunCancelledError(this.runId);
|
|
221
450
|
}
|
|
222
|
-
if (
|
|
223
|
-
//
|
|
224
|
-
//
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
let hydratedError;
|
|
228
|
-
try {
|
|
229
|
-
hydratedError = await hydrateRunError(run.error, this.runId, encryptionKey);
|
|
230
|
-
}
|
|
231
|
-
catch {
|
|
232
|
-
// If hydration fails, surface a generic fallback rather than
|
|
233
|
-
// leaving the user with a raw Uint8Array. The run's errorCode
|
|
234
|
-
// is still preserved on the thrown WorkflowRunFailedError.
|
|
235
|
-
hydratedError = new Error('Failed to hydrate workflow run error');
|
|
236
|
-
}
|
|
237
|
-
throw new WorkflowRunFailedError(this.runId, hydratedError, {
|
|
238
|
-
errorCode: run.errorCode,
|
|
451
|
+
if (PAYLOAD_TERMINAL_RUN_STATUSES.has(runMetadata.status)) {
|
|
452
|
+
// The polling read above deliberately skips input/output/error refs.
|
|
453
|
+
// Resolve payloads only once the run reaches a terminal state.
|
|
454
|
+
const run = await world.runs.get(this.runId, {
|
|
455
|
+
resolveData: 'all',
|
|
239
456
|
});
|
|
457
|
+
return await this.#resolveTerminalReturnValue(run);
|
|
240
458
|
}
|
|
241
|
-
// Run not completed yet
|
|
242
|
-
throw new WorkflowRunNotCompletedError(this.runId,
|
|
459
|
+
// Run not completed yet: sleep and poll again.
|
|
460
|
+
throw new WorkflowRunNotCompletedError(this.runId, runMetadata.status);
|
|
243
461
|
}
|
|
244
462
|
catch (error) {
|
|
245
463
|
if (WorkflowRunNotCompletedError.is(error)) {
|
|
246
|
-
|
|
464
|
+
// Space consecutive non-terminal observations at least one poll
|
|
465
|
+
// interval apart. On the plain-poll path that is the familiar fixed
|
|
466
|
+
// sleep; on the long-poll path the wait has usually already
|
|
467
|
+
// outlasted the interval and this is a no-op, but it also means a
|
|
468
|
+
// World whose wait returns early (a backend with no long poll, a
|
|
469
|
+
// clamped budget) degrades to interval polling instead of spinning.
|
|
470
|
+
const remainingIntervalMs = getReturnValuePollIntervalMs() - (Date.now() - iterationStartedAt);
|
|
471
|
+
if (remainingIntervalMs > 0) {
|
|
472
|
+
await new Promise((resolve) => setTimeout(resolve, remainingIntervalMs));
|
|
473
|
+
}
|
|
247
474
|
continue;
|
|
248
475
|
}
|
|
249
476
|
if (WorkflowRunNotFoundError.is(error) &&
|
|
250
477
|
notFoundRetries < NOT_FOUND_MAX_RETRIES) {
|
|
251
|
-
const delay =
|
|
478
|
+
const delay = NOT_FOUND_RETRY_DELAYS[notFoundRetries];
|
|
252
479
|
notFoundRetries++;
|
|
253
480
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
254
481
|
continue;
|
|
@@ -268,4 +495,4 @@ export class Run {
|
|
|
268
495
|
export function getRun(runId) {
|
|
269
496
|
return new Run(runId);
|
|
270
497
|
}
|
|
271
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvcnVuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx5QkFBeUIsRUFDekIsc0JBQXNCLEVBQ3RCLDRCQUE0QixFQUM1Qix3QkFBd0IsR0FDekIsTUFBTSxrQkFBa0IsQ0FBQztBQUMxQixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzRSxPQUFPLEVBQ0wsb0JBQW9CLEdBR3JCLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFrQixTQUFTLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM3RCxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLGVBQWUsRUFDZiwwQkFBMEIsR0FDM0IsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDcEQsT0FBTyxFQUdMLFNBQVMsR0FDVixNQUFNLFdBQVcsQ0FBQztBQUNuQixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUE2Q25EOztHQUVHO0FBQ0gsTUFBTSxPQUFPLEdBQUc7SUFDZCxNQUFNLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLFFBQXNCO1FBQ2hELE9BQU8sRUFBRSxLQUFLLEVBQUUsUUFBUSxDQUFDLEtBQUssRUFBRSxjQUFjLEVBQUUsUUFBUSxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBQzdFLENBQUM7SUFFRCxNQUFNLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLElBRzdCO1FBQ0MsT0FBTyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsY0FBYyxFQUFFLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBUztJQUVkOzs7T0FHRztJQUNILGFBQWEsQ0FBNkI7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RCxJQUNFLHdCQUF3QixDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUM7b0JBQ2xDLGVBQWUsR0FBRyxxQkFBcUIsRUFDdkMsQ0FBQztvQkFDRCxNQUFNLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxlQUFlLENBQUUsQ0FBQztvQkFDakQsZUFBZSxFQUFFLENBQUM7b0JBQ2xCLE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztvQkFDM0QsU0FBUztnQkFDWCxDQUFDO2dCQUNELE1BQU0sS0FBSyxDQUFDO1lBQ2QsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUFFRDs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsTUFBTSxDQUFVLEtBQWE7SUFDM0MsT0FBTyxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN4QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgV29ya2Zsb3dSdW5DYW5jZWxsZWRFcnJvcixcbiAgV29ya2Zsb3dSdW5GYWlsZWRFcnJvcixcbiAgV29ya2Zsb3dSdW5Ob3RDb21wbGV0ZWRFcnJvcixcbiAgV29ya2Zsb3dSdW5Ob3RGb3VuZEVycm9yLFxufSBmcm9tICdAd29ya2Zsb3cvZXJyb3JzJztcbmltcG9ydCB7IFdPUktGTE9XX0RFU0VSSUFMSVpFLCBXT1JLRkxPV19TRVJJQUxJWkUgfSBmcm9tICdAd29ya2Zsb3cvc2VyZGUnO1xuaW1wb3J0IHtcbiAgU1BFQ19WRVJTSU9OX0NVUlJFTlQsXG4gIHR5cGUgV29ya2Zsb3dSdW5TdGF0dXMsXG4gIHR5cGUgV29ybGQsXG59IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgeyB0eXBlIENyeXB0b0tleSwgaW1wb3J0S2V5IH0gZnJvbSAnLi4vZW5jcnlwdGlvbi5qcyc7XG5pbXBvcnQge1xuICBnZXRFeHRlcm5hbFJldml2ZXJzLFxuICBoeWRyYXRlUnVuRXJyb3IsXG4gIGh5ZHJhdGVXb3JrZmxvd1JldHVyblZhbHVlLFxufSBmcm9tICcuLi9zZXJpYWxpemF0aW9uLmpzJztcbmltcG9ydCB7IGdldFdvcmtmbG93UnVuU3RyZWFtSWQgfSBmcm9tICcuLi91dGlsLmpzJztcbmltcG9ydCB7XG4gIHR5cGUgU3RvcFNsZWVwT3B0aW9ucyxcbiAgdHlwZSBTdG9wU2xlZXBSZXN1bHQsXG4gIHdha2VVcFJ1bixcbn0gZnJvbSAnLi9ydW5zLmpzJztcbmltcG9ydCB7IGdldFdvcmxkTGF6eSB9IGZyb20gJy4vZ2V0LXdvcmxkLWxhenkuanMnO1xuXG4vKipcbiAqIEEgYFJlYWRhYmxlU3RyZWFtYCBleHRlbmRlZCB3aXRoIHdvcmtmbG93LXNwZWNpZmljIGhlbHBlcnMuXG4gKi9cbmV4cG9ydCB0eXBlIFdvcmtmbG93UmVhZGFibGVTdHJlYW08UiA9IGFueT4gPSBSZWFkYWJsZVN0cmVhbTxSPiAmIHtcbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHRhaWwgaW5kZXggKGluZGV4IG9mIHRoZSBsYXN0IGtub3duIGNodW5rLCAwLWJhc2VkKSBvZiB0aGVcbiAgICogdW5kZXJseWluZyB3b3JrZmxvdyBzdHJlYW0uIFVzZWZ1bCBmb3IgcmVzb2x2aW5nIGEgbmVnYXRpdmUgYHN0YXJ0SW5kZXhgXG4gICAqIGludG8gYW4gYWJzb2x1dGUgcG9zaXRpb24g4oCUIGZvciBleGFtcGxlLCB3aGVuIGJ1aWxkaW5nIHJlY29ubmVjdGlvblxuICAgKiBlbmRwb2ludHMgdGhhdCBuZWVkIHRvIGluZm9ybSB0aGUgY2xpZW50IHdoZXJlIHRoZSBzdHJlYW0gc3RhcnRzLlxuICAgKlxuICAgKiBSZXR1cm5zIGAtMWAgd2hlbiBubyBjaHVua3MgaGF2ZSBiZWVuIHdyaXR0ZW4geWV0LlxuICAgKi9cbiAgZ2V0VGFpbEluZGV4KCk6IFByb21pc2U8bnVtYmVyPjtcbn07XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgY29uZmlndXJpbmcgYSB3b3JrZmxvdydzIHJlYWRhYmxlIHN0cmVhbS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBXb3JrZmxvd1JlYWRhYmxlU3RyZWFtT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBBbiBvcHRpb25hbCBuYW1lc3BhY2UgdG8gZGlzdGluZ3Vpc2ggYmV0d2VlbiBtdWx0aXBsZSBzdHJlYW1zIGFzc29jaWF0ZWRcbiAgICogd2l0aCB0aGUgc2FtZSB3b3JrZmxvdyBydW4uXG4gICAqL1xuICBuYW1lc3BhY2U/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgaW5kZXggbnVtYmVyIG9mIHRoZSBzdGFydGluZyBjaHVuayB0byBiZWdpbiByZWFkaW5nIHRoZSBzdHJlYW0gZnJvbS5cbiAgICogTmVnYXRpdmUgdmFsdWVzIHN0YXJ0IGZyb20gdGhlIGVuZCAoZS5nLiAtMyByZWFkcyB0aGUgbGFzdCAzIGNodW5rcykuXG4gICAqL1xuICBzdGFydEluZGV4PzogbnVtYmVyO1xuICAvKipcbiAgICogQW55IGFzeW5jaHJvbm91cyBvcGVyYXRpb25zIHRoYXQgbmVlZCB0byBiZSBwZXJmb3JtZWQgYmVmb3JlIHRoZSBleGVjdXRpb25cbiAgICogZW52aXJvbm1lbnQgaXMgcGF1c2VkIC8gdGVybWluYXRlZFxuICAgKiAoaS5lLiB1c2luZyBbYHdhaXRVbnRpbCgpYF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZG9jcy9XZWIvQVBJL0V4dGVuZGFibGVFdmVudC93YWl0VW50aWwpIG9yIHNpbWlsYXIpLlxuICAgKi9cbiAgb3BzPzogUHJvbWlzZTxhbnk+W107XG4gIC8qKlxuICAgKiBUaGUgZ2xvYmFsIG9iamVjdCB0byB1c2UgZm9yIGh5ZHJhdGluZyB0eXBlcyBmcm9tIHRoZSBnbG9iYWwgc2NvcGUuXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIHtAbGluayBbYGdsb2JhbFRoaXNgXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9nbG9iYWxUaGlzKX0uXG4gICAqL1xuICBnbG9iYWw/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xufVxuXG4vKipcbiAqIEEgaGFuZGxlciBjbGFzcyBmb3IgYSB3b3JrZmxvdyBydW4uXG4gKi9cbmV4cG9ydCBjbGFzcyBSdW48VFJlc3VsdD4ge1xuICBzdGF0aWMgW1dPUktGTE9XX1NFUklBTElaRV0oaW5zdGFuY2U6IFJ1bjx1bmtub3duPikge1xuICAgIHJldHVybiB7IHJ1bklkOiBpbnN0YW5jZS5ydW5JZCwgcmVzaWxpZW50U3RhcnQ6IGluc3RhbmNlLiNyZXNpbGllbnRTdGFydCB9O1xuICB9XG5cbiAgc3RhdGljIFtXT1JLRkxPV19ERVNFUklBTElaRV0oZGF0YToge1xuICAgIHJ1bklkOiBzdHJpbmc7XG4gICAgcmVzaWxpZW50U3RhcnQ/OiBib29sZWFuO1xuICB9KSB7XG4gICAgcmV0dXJuIG5ldyBSdW4oZGF0YS5ydW5JZCwgeyByZXNpbGllbnRTdGFydDogZGF0YS5yZXNpbGllbnRTdGFydCB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgSUQgb2YgdGhlIHdvcmtmbG93IHJ1bi5cbiAgICovXG4gIHJ1bklkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB3b3JsZCBvYmplY3QuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgI3dvcmxkUHJvbWlzZTogUHJvbWlzZTxXb3JsZD4gfCB1bmRlZmluZWQ7XG4gIGdldCAjbGF6eVdvcmxkUHJvbWlzZSgpIHtcbiAgICBpZiAoIXRoaXMuI3dvcmxkUHJvbWlzZSkgdGhpcy4jd29ybGRQcm9taXNlID0gZ2V0V29ybGRMYXp5KCk7XG4gICAgcmV0dXJuIHRoaXMuI3dvcmxkUHJvbWlzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWNoZWQgZW5jcnlwdGlvbiBrZXkgcmVzb2x1dGlvbi4gUmVzb2x2ZWQgb25jZSBvbiBmaXJzdCB1c2UgYW5kXG4gICAqIHJldXNlZCBmb3IgcmV0dXJuVmFsdWUsIGdldFJlYWRhYmxlKCksIGV0Yy5cbiAgICogQGludGVybmFsXG4gICAqL1xuICAjZW5jcnlwdGlvbktleVByb21pc2U6IFByb21pc2U8Q3J5cHRvS2V5IHwgdW5kZWZpbmVkPiB8IG51bGwgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBXaGVuIHRydWUsIHJ1bl9jcmVhdGVkIGZhaWxlZCBhbmQgdGhlIHJ1biBtYXkgbm90IGV4aXN0IHlldCAodGhlXG4gICAqIHJlc2lsaWVudCBzdGFydCBwYXRoIHdpbGwgY3JlYXRlIGl0IHZpYSBydW5fc3RhcnRlZCkuIHBvbGxSZXR1cm5WYWx1ZVxuICAgKiByZXRyaWVzIG9uIFdvcmtmbG93UnVuTm90Rm91bmRFcnJvciBvbmx5IHdoZW4gdGhpcyBmbGFnIGlzIHNldCBzb1xuICAgKiB0aGF0IG5vcm1hbCBydW5zIGZhaWwgZmFzdCBvbiA0MDQuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgI3Jlc2lsaWVudFN0YXJ0ID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IocnVuSWQ6IHN0cmluZywgb3B0cz86IHsgcmVzaWxpZW50U3RhcnQ/OiBib29sZWFuIH0pIHtcbiAgICB0aGlzLnJ1bklkID0gcnVuSWQ7XG4gICAgdGhpcy4jcmVzaWxpZW50U3RhcnQgPSBvcHRzPy5yZXNpbGllbnRTdGFydCA/PyBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyBhbmQgY2FjaGVzIHRoZSBlbmNyeXB0aW9uIGtleSBmb3IgdGhpcyBydW4uXG4gICAqIFRoZSBrZXkgaXMgdGhlIHNhbWUgZm9yIHRoZSBsaWZldGltZSBvZiBhIHJ1biwgc28gaXQgb25seSBuZWVkc1xuICAgKiB0byBiZSByZXNvbHZlZCBvbmNlLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gICNnZXRFbmNyeXB0aW9uS2V5KCk6IFByb21pc2U8Q3J5cHRvS2V5IHwgdW5kZWZpbmVkPiB7XG4gICAgaWYgKCF0aGlzLiNlbmNyeXB0aW9uS2V5UHJvbWlzZSkge1xuICAgICAgdGhpcy4jZW5jcnlwdGlvbktleVByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3b3JsZCA9IGF3YWl0IHRoaXMuI2xhenlXb3JsZFByb21pc2U7XG4gICAgICAgIGNvbnN0IHJ1biA9IGF3YWl0IHdvcmxkLnJ1bnMuZ2V0KHRoaXMucnVuSWQpO1xuICAgICAgICBjb25zdCByYXdLZXkgPSBhd2FpdCB3b3JsZC5nZXRFbmNyeXB0aW9uS2V5Rm9yUnVuPy4ocnVuKTtcbiAgICAgICAgcmV0dXJuIHJhd0tleSA/IGF3YWl0IGltcG9ydEtleShyYXdLZXkpIDogdW5kZWZpbmVkO1xuICAgICAgfSkoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuI2VuY3J5cHRpb25LZXlQcm9taXNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEludGVycnVwdHMgcGVuZGluZyBgc2xlZXAoKWAgY2FsbHMsIHJlc3VtaW5nIHRoZSB3b3JrZmxvdyBlYXJseS5cbiAgICpcbiAgICogQHBhcmFtIG9wdGlvbnMgLSBPcHRpb25hbCBzZXR0aW5ncyB0byB0YXJnZXQgc3BlY2lmaWMgc2xlZXAgY2FsbHMgYnkgY29ycmVsYXRpb24gSUQuXG4gICAqICAgSWYgbm90IHByb3ZpZGVkLCBhbGwgcGVuZGluZyBzbGVlcCBjYWxscyB3aWxsIGJlIGludGVycnVwdGVkLlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBTdG9wU2xlZXBSZXN1bHR9IG9iamVjdCBjb250YWluaW5nIHRoZSBudW1iZXIgb2Ygc2xlZXAgY2FsbHMgdGhhdCB3ZXJlIGludGVycnVwdGVkLlxuICAgKi9cbiAgYXN5bmMgd2FrZVVwKG9wdGlvbnM/OiBTdG9wU2xlZXBPcHRpb25zKTogUHJvbWlzZTxTdG9wU2xlZXBSZXN1bHQ+IHtcbiAgICAndXNlIHN0ZXAnO1xuICAgIHJldHVybiB3YWtlVXBSdW4oYXdhaXQgdGhpcy4jbGF6eVdvcmxkUHJvbWlzZSwgdGhpcy5ydW5JZCwgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogQ2FuY2VscyB0aGUgd29ya2Zsb3cgcnVuLlxuICAgKi9cbiAgYXN5bmMgY2FuY2VsKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICd1c2Ugc3RlcCc7XG4gICAgY29uc3Qgd29ybGQgPSBhd2FpdCB0aGlzLiNsYXp5V29ybGRQcm9taXNlO1xuICAgIGF3YWl0IHdvcmxkLmV2ZW50cy5jcmVhdGUodGhpcy5ydW5JZCwge1xuICAgICAgZXZlbnRUeXBlOiAncnVuX2NhbmNlbGxlZCcsXG4gICAgICBzcGVjVmVyc2lvbjogU1BFQ19WRVJTSU9OX0NVUlJFTlQsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogV2hldGhlciB0aGUgd29ya2Zsb3cgcnVuIGV4aXN0cy5cbiAgICovXG4gIGdldCBleGlzdHMoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgJ3VzZSBzdGVwJztcbiAgICByZXR1cm4gdGhpcy4jbGF6eVdvcmxkUHJvbWlzZS50aGVuKCh3b3JsZCkgPT5cbiAgICAgIHdvcmxkLnJ1bnNcbiAgICAgICAgLmdldCh0aGlzLnJ1bklkLCB7IHJlc29sdmVEYXRhOiAnbm9uZScgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4gdHJ1ZSlcbiAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgIGlmIChXb3JrZmxvd1J1bk5vdEZvdW5kRXJyb3IuaXMoZXJyb3IpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHN0YXR1cyBvZiB0aGUgd29ya2Zsb3cgcnVuLlxuICAgKi9cbiAgZ2V0IHN0YXR1cygpOiBQcm9taXNlPFdvcmtmbG93UnVuU3RhdHVzPiB7XG4gICAgJ3VzZSBzdGVwJztcbiAgICByZXR1cm4gdGhpcy4jbGF6eVdvcmxkUHJvbWlzZS50aGVuKCh3b3JsZCkgPT5cbiAgICAgIHdvcmxkLnJ1bnMuZ2V0KHRoaXMucnVuSWQpLnRoZW4oKHJ1bikgPT4gcnVuLnN0YXR1cylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIHdvcmtmbG93IHJ1bi5cbiAgICogUG9sbHMgdGhlIHdvcmtmbG93IHJldHVybiB2YWx1ZSB1bnRpbCBpdCBpcyBjb21wbGV0ZWQuXG4gICAqL1xuICBnZXQgcmV0dXJuVmFsdWUoKTogUHJvbWlzZTxUUmVzdWx0PiB7XG4gICAgJ3VzZSBzdGVwJztcbiAgICByZXR1cm4gdGhpcy4jcG9sbFJldHVyblZhbHVlKCk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIHdvcmtmbG93LlxuICAgKi9cbiAgZ2V0IHdvcmtmbG93TmFtZSgpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICd1c2Ugc3RlcCc7XG4gICAgcmV0dXJuIHRoaXMuI2xhenlXb3JsZFByb21pc2UudGhlbigod29ybGQpID0+XG4gICAgICB3b3JsZC5ydW5zLmdldCh0aGlzLnJ1bklkKS50aGVuKChydW4pID0+IHJ1bi53b3JrZmxvd05hbWUpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgdGltZXN0YW1wIHdoZW4gdGhlIHdvcmtmbG93IHJ1biB3YXMgY3JlYXRlZC5cbiAgICovXG4gIGdldCBjcmVhdGVkQXQoKTogUHJvbWlzZTxEYXRlPiB7XG4gICAgJ3VzZSBzdGVwJztcbiAgICByZXR1cm4gdGhpcy4jbGF6eVdvcmxkUHJvbWlzZS50aGVuKCh3b3JsZCkgPT5cbiAgICAgIHdvcmxkLnJ1bnMuZ2V0KHRoaXMucnVuSWQpLnRoZW4oKHJ1bikgPT4gcnVuLmNyZWF0ZWRBdClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB0aW1lc3RhbXAgd2hlbiB0aGUgd29ya2Zsb3cgcnVuIHN0YXJ0ZWQgZXhlY3V0aW9uLlxuICAgKiBSZXR1cm5zIHVuZGVmaW5lZCBpZiB0aGUgd29ya2Zsb3cgaGFzIG5vdCBzdGFydGVkIHlldC5cbiAgICovXG4gIGdldCBzdGFydGVkQXQoKTogUHJvbWlzZTxEYXRlIHwgdW5kZWZpbmVkPiB7XG4gICAgJ3VzZSBzdGVwJztcbiAgICByZXR1cm4gdGhpcy4jbGF6eVdvcmxkUHJvbWlzZS50aGVuKCh3b3JsZCkgPT5cbiAgICAgIHdvcmxkLnJ1bnMuZ2V0KHRoaXMucnVuSWQpLnRoZW4oKHJ1bikgPT4gcnVuLnN0YXJ0ZWRBdClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB0aW1lc3RhbXAgd2hlbiB0aGUgd29ya2Zsb3cgcnVuIGNvbXBsZXRlZC5cbiAgICogUmV0dXJucyB1bmRlZmluZWQgaWYgdGhlIHdvcmtmbG93IGhhcyBub3QgY29tcGxldGVkIHlldC5cbiAgICovXG4gIGdldCBjb21wbGV0ZWRBdCgpOiBQcm9taXNlPERhdGUgfCB1bmRlZmluZWQ+IHtcbiAgICAndXNlIHN0ZXAnO1xuICAgIHJldHVybiB0aGlzLiNsYXp5V29ybGRQcm9taXNlLnRoZW4oKHdvcmxkKSA9PlxuICAgICAgd29ybGQucnVucy5nZXQodGhpcy5ydW5JZCkudGhlbigocnVuKSA9PiBydW4uY29tcGxldGVkQXQpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcmVhZGFibGUgc3RyZWFtIG9mIHRoZSB3b3JrZmxvdyBydW4uXG4gICAqL1xuICBnZXQgcmVhZGFibGUoKTogV29ya2Zsb3dSZWFkYWJsZVN0cmVhbSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UmVhZGFibGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgdGhlIHdvcmtmbG93IHJ1bidzIGRlZmF1bHQgcmVhZGFibGUgc3RyZWFtLCB3aGljaCByZWFkcyBjaHVua3NcbiAgICogd3JpdHRlbiB0byB0aGUgY29ycmVzcG9uZGluZyB3cml0YWJsZSBzdHJlYW0ge0BsaW5rIGdldFdyaXRhYmxlfS5cbiAgICpcbiAgICogVGhlIHJldHVybmVkIHN0cmVhbSBoYXMgYW4gYWRkaXRpb25hbCB7QGxpbmsgV29ya2Zsb3dSZWFkYWJsZVN0cmVhbS5nZXRUYWlsSW5kZXggfCBnZXRUYWlsSW5kZXgoKX1cbiAgICogaGVscGVyIHRoYXQgcmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGxhc3Qga25vd24gY2h1bmsuIFRoaXMgaXMgdXNlZnVsIHdoZW5cbiAgICogYnVpbGRpbmcgcmVjb25uZWN0aW9uIGVuZHBvaW50cyB0aGF0IG5lZWQgdG8gaW5mb3JtIGNsaWVudHMgd2hlcmUgdGhlXG4gICAqIHN0cmVhbSBzdGFydHMuXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgZm9yIHRoZSByZWFkYWJsZSBzdHJlYW0uXG4gICAqIEByZXR1cm5zIEEgYFdvcmtmbG93UmVhZGFibGVTdHJlYW1gIGZvciB0aGUgd29ya2Zsb3cgcnVuLlxuICAgKi9cbiAgZ2V0UmVhZGFibGU8UiA9IGFueT4oXG4gICAgb3B0aW9uczogV29ya2Zsb3dSZWFkYWJsZVN0cmVhbU9wdGlvbnMgPSB7fVxuICApOiBXb3JrZmxvd1JlYWRhYmxlU3RyZWFtPFI+IHtcbiAgICAndXNlIHN0ZXAnO1xuICAgIGNvbnN0IHsgb3BzID0gW10sIGdsb2JhbCA9IGdsb2JhbFRoaXMsIHN0YXJ0SW5kZXgsIG5hbWVzcGFjZSB9ID0gb3B0aW9ucztcbiAgICBjb25zdCBuYW1lID0gZ2V0V29ya2Zsb3dSdW5TdHJlYW1JZCh0aGlzLnJ1bklkLCBuYW1lc3BhY2UpO1xuICAgIC8vIFBhc3MgdGhlIGtleSBhcyBhIHByb21pc2Ug4oCUIGl0IHdpbGwgYmUgcmVzb2x2ZWQgbGF6aWx5IGluc2lkZVxuICAgIC8vIHRoZSBmaXJzdCBhc3luYyB0cmFuc2Zvcm0oKSBjYWxsIG9mIHRoZSBkZXNlcmlhbGl6ZSBzdHJlYW0uXG4gICAgY29uc3QgZW5jcnlwdGlvbktleSA9IHRoaXMuI2dldEVuY3J5cHRpb25LZXkoKTtcbiAgICBjb25zdCBzdHJlYW0gPSBnZXRFeHRlcm5hbFJldml2ZXJzKGdsb2JhbCwgb3BzLCB0aGlzLnJ1bklkLCBlbmNyeXB0aW9uS2V5KVxuICAgICAgLlJlYWRhYmxlU3RyZWFtISh7XG4gICAgICBuYW1lLFxuICAgICAgc3RhcnRJbmRleCxcbiAgICB9KSBhcyBSZWFkYWJsZVN0cmVhbTxSPjtcblxuICAgIGNvbnN0IHdvcmxkUHJvbWlzZSA9IHRoaXMuI2xhenlXb3JsZFByb21pc2U7XG4gICAgY29uc3QgcnVuSWQgPSB0aGlzLnJ1bklkO1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHN0cmVhbSwge1xuICAgICAgZ2V0VGFpbEluZGV4OiBhc3luYyAoKTogUHJvbWlzZTxudW1iZXI+ID0+IHtcbiAgICAgICAgY29uc3Qgd29ybGQgPSBhd2FpdCB3b3JsZFByb21pc2U7XG4gICAgICAgIGNvbnN0IGluZm8gPSBhd2FpdCB3b3JsZC5zdHJlYW1zLmdldEluZm8ocnVuSWQsIG5hbWUpO1xuICAgICAgICByZXR1cm4gaW5mby50YWlsSW5kZXg7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFBvbGxzIHRoZSB3b3JrZmxvdyByZXR1cm4gdmFsdWUgZXZlcnkgMSBzZWNvbmQgdW50aWwgaXQgaXMgY29tcGxldGVkLlxuICAgKiBAaW50ZXJuYWxcbiAgICogQHJldHVybnMgVGhlIHdvcmtmbG93IHJldHVybiB2YWx1ZS5cbiAgICovXG4gIGFzeW5jICNwb2xsUmV0dXJuVmFsdWUoKTogUHJvbWlzZTxUUmVzdWx0PiB7XG4gICAgY29uc3Qgd29ybGQgPSBhd2FpdCB0aGlzLiNsYXp5V29ybGRQcm9taXNlO1xuXG4gICAgLy8gV2hlbiByZXNpbGllbnRTdGFydCBpcyB0cnVlLCBydW5fY3JlYXRlZCBmYWlsZWQgYW5kIHRoZSBydW4gbWF5XG4gICAgLy8gbm90IGV4aXN0IHlldC4gUmV0cnkgb24gV29ya2Zsb3dSdW5Ob3RGb3VuZEVycm9yIHVwIHRvIDMgdGltZXNcbiAgICAvLyAoMXMgKyAzcyArIDZzID0gMTBzIHRvdGFsKSB0byBnaXZlIHRoZSBxdWV1ZSB0aW1lIHRvIGRlbGl2ZXJcbiAgICAvLyBhbmQgdGhlIHJ1bnRpbWUgdG8gY3JlYXRlIHRoZSBydW4gdmlhIHJ1bl9zdGFydGVkLlxuICAgIC8vIFdoZW4gcmVzaWxpZW50U3RhcnQgaXMgZmFsc2UsIDQwNCBpcyBhIHJlYWwgZXJyb3Ig4oCUIGZhaWwgZmFzdC5cbiAgICBsZXQgbm90Rm91bmRSZXRyaWVzID0gMDtcbiAgICBjb25zdCBOT1RfRk9VTkRfTUFYX1JFVFJJRVMgPSB0aGlzLiNyZXNpbGllbnRTdGFydCA/IDMgOiAwO1xuICAgIGNvbnN0IE5PVF9GT1VORF9ERUxBWVMgPSBbMV8wMDAsIDNfMDAwLCA2XzAwMF07XG5cbiAgICAvLyBOT1RFOiB3aGVuIHRoaXMgcG9sbCBydW5zIGluc2lkZSBhIHN0ZXAgKGUuZy4gdGhlIHN0ZXAgdGhhdCBhIHBhcmVudFxuICAgIC8vIHdvcmtmbG93IHVzZXMgdG8gYXdhaXQgYSBjaGlsZCB3b3JrZmxvdydzIGByZXR1cm5WYWx1ZWApLCBpdCBibG9ja3NcbiAgICAvLyBhIHF1ZXVlIHdvcmtlciBzbG90IGZvciBhcyBsb25nIGFzIHRoZSBjaGlsZCBydW4gdGFrZXMgdG8gZmluaXNoLlxuICAgIC8vIFdvcmtlci1iYXNlZCB3b3JsZHMgbGlrZSBgd29ybGQtcG9zdGdyZXNgIG11c3QgYmUgc2l6ZWQgdG8gY292ZXIgdGhlXG4gICAgLy8gcGVhayBudW1iZXIgb2Ygc3VjaCBwb2xscyBpbiBmbGlnaHQg4oCUIHNlZSB0aGUgYHF1ZXVlQ29uY3VycmVuY3lgXG4gICAgLy8gZGVmYXVsdCBvbiB0aGUgUG9zdGdyZXMgd29ybGQgYW5kIHRoZSBub3RlcyBpbiB0aGUgZWFnZXItcHJvY2Vzc2luZ1xuICAgIC8vIGNoYW5nZWxvZyBmb3IgZGV0YWlscy5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcnVuID0gYXdhaXQgd29ybGQucnVucy5nZXQodGhpcy5ydW5JZCk7XG5cbiAgICAgICAgaWYgKHJ1bi5zdGF0dXMgPT09ICdjb21wbGV0ZWQnKSB7XG4gICAgICAgICAgY29uc3QgZW5jcnlwdGlvbktleSA9IGF3YWl0IHRoaXMuI2dldEVuY3J5cHRpb25LZXkoKTtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgaHlkcmF0ZVdvcmtmbG93UmV0dXJuVmFsdWUoXG4gICAgICAgICAgICBydW4ub3V0cHV0LFxuICAgICAgICAgICAgdGhpcy5ydW5JZCxcbiAgICAgICAgICAgIGVuY3J5cHRpb25LZXlcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJ1bi5zdGF0dXMgPT09ICdjYW5jZWxsZWQnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVuQ2FuY2VsbGVkRXJyb3IodGhpcy5ydW5JZCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocnVuLnN0YXR1cyA9PT0gJ2ZhaWxlZCcpIHtcbiAgICAgICAgICAvLyBIeWRyYXRlIHRoZSBzZXJpYWxpemVkIHJ1biBlcnJvciBzbyB0aGUgb3JpZ2luYWwgdGhyb3duIHZhbHVlXG4gICAgICAgICAgLy8gKHdpdGggaXRzIHR5cGUgaWRlbnRpdHksIGNhdXNlIGNoYWluLCBldGMuKSBpcyBzZXQgYXMgdGhlXG4gICAgICAgICAgLy8gYGNhdXNlYCBvbiBXb3JrZmxvd1J1bkZhaWxlZEVycm9yLlxuICAgICAgICAgIGNvbnN0IGVuY3J5cHRpb25LZXkgPSBhd2FpdCB0aGlzLiNnZXRFbmNyeXB0aW9uS2V5KCk7XG4gICAgICAgICAgbGV0IGh5ZHJhdGVkRXJyb3I6IHVua25vd247XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGh5ZHJhdGVkRXJyb3IgPSBhd2FpdCBoeWRyYXRlUnVuRXJyb3IoXG4gICAgICAgICAgICAgIHJ1bi5lcnJvcixcbiAgICAgICAgICAgICAgdGhpcy5ydW5JZCxcbiAgICAgICAgICAgICAgZW5jcnlwdGlvbktleVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIElmIGh5ZHJhdGlvbiBmYWlscywgc3VyZmFjZSBhIGdlbmVyaWMgZmFsbGJhY2sgcmF0aGVyIHRoYW5cbiAgICAgICAgICAgIC8vIGxlYXZpbmcgdGhlIHVzZXIgd2l0aCBhIHJhdyBVaW50OEFycmF5LiBUaGUgcnVuJ3MgZXJyb3JDb2RlXG4gICAgICAgICAgICAvLyBpcyBzdGlsbCBwcmVzZXJ2ZWQgb24gdGhlIHRocm93biBXb3JrZmxvd1J1bkZhaWxlZEVycm9yLlxuICAgICAgICAgICAgaHlkcmF0ZWRFcnJvciA9IG5ldyBFcnJvcignRmFpbGVkIHRvIGh5ZHJhdGUgd29ya2Zsb3cgcnVuIGVycm9yJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bkZhaWxlZEVycm9yKHRoaXMucnVuSWQsIGh5ZHJhdGVkRXJyb3IsIHtcbiAgICAgICAgICAgIGVycm9yQ29kZTogcnVuLmVycm9yQ29kZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJ1biBub3QgY29tcGxldGVkIHlldCDigJQgc2xlZXAgYW5kIHBvbGwgYWdhaW4uXG4gICAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bk5vdENvbXBsZXRlZEVycm9yKHRoaXMucnVuSWQsIHJ1bi5zdGF0dXMpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKFdvcmtmbG93UnVuTm90Q29tcGxldGVkRXJyb3IuaXMoZXJyb3IpKSB7XG4gICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgMV8wMDApKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXG4gICAgICAgICAgV29ya2Zsb3dSdW5Ob3RGb3VuZEVycm9yLmlzKGVycm9yKSAmJlxuICAgICAgICAgIG5vdEZvdW5kUmV0cmllcyA8IE5PVF9GT1VORF9NQVhfUkVUUklFU1xuICAgICAgICApIHtcbiAgICAgICAgICBjb25zdCBkZWxheSA9IE5PVF9GT1VORF9ERUxBWVNbbm90Rm91bmRSZXRyaWVzXSE7XG4gICAgICAgICAgbm90Rm91bmRSZXRyaWVzKys7XG4gICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgZGVsYXkpKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZXRyaWV2ZXMgYSBgUnVuYCBvYmplY3QgZm9yIGEgZ2l2ZW4gcnVuIElELlxuICpcbiAqIEBwYXJhbSBydW5JZCAtIFRoZSB3b3JrZmxvdyBydW4gSUQgb2J0YWluZWQgZnJvbSB7QGxpbmsgc3RhcnR9LlxuICogQHJldHVybnMgQSBgUnVuYCBvYmplY3QuXG4gKiBAdGhyb3dzIFdvcmtmbG93UnVuTm90Rm91bmRFcnJvciBpZiB0aGUgcnVuIElEIGlzIG5vdCBmb3VuZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJ1bjxUUmVzdWx0PihydW5JZDogc3RyaW5nKTogUnVuPFRSZXN1bHQ+IHtcbiAgcmV0dXJuIG5ldyBSdW4ocnVuSWQpO1xufVxuIl19
|
|
498
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvcnVuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxlQUFlLEVBQ2YseUJBQXlCLEVBQ3pCLHNCQUFzQixFQUN0Qiw0QkFBNEIsRUFDNUIsd0JBQXdCLEdBQ3pCLE1BQU0sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxFQUFFLG9CQUFvQixFQUFFLGtCQUFrQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFM0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3BFLE9BQU8sRUFDTCxvQkFBb0IsR0FFckIsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN4QyxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlDQUFpQyxFQUNqQyxvQkFBb0IsRUFDcEIsZUFBZSxFQUNmLDBCQUEwQixFQUMxQiwwQkFBMEIsR0FDM0IsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDcEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ25ELE9BQU8sRUFJTCxTQUFTLEdBQ1YsTUFBTSxXQUFXLENBQUM7QUFFbkIsTUFBTSw2QkFBNkIsR0FBRyxLQUFLLENBQUM7QUFDNUMsTUFBTSw2QkFBNkIsR0FBRyxJQUFJLEdBQUcsQ0FBb0I7SUFDL0QsV0FBVztJQUNYLFFBQVE7Q0FDVCxDQUFDLENBQUM7QUFFSCw0REFBNEQ7QUFDNUQsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFFckQsZ0JBQWdCO0FBQ2hCLE1BQU0sVUFBVSw0QkFBNEI7SUFDMUMsT0FBTyxTQUFTLENBQ2Qsd0NBQXdDLEVBQ3hDLDZCQUE2QixFQUM3QixFQUFFLE9B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VSxLQUFhO0lBQzNDLE9BQU8sSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDeEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIFJ1bkV4cGlyZWRFcnJvcixcbiAgV29ya2Zsb3dSdW5DYW5jZWxsZWRFcnJvcixcbiAgV29ya2Zsb3dSdW5GYWlsZWRFcnJvcixcbiAgV29ya2Zsb3dSdW5Ob3RDb21wbGV0ZWRFcnJvcixcbiAgV29ya2Zsb3dSdW5Ob3RGb3VuZEVycm9yLFxufSBmcm9tICdAd29ya2Zsb3cvZXJyb3JzJztcbmltcG9ydCB7IFdPUktGTE9XX0RFU0VSSUFMSVpFLCBXT1JLRkxPV19TRVJJQUxJWkUgfSBmcm9tICdAd29ya2Zsb3cvc2VyZGUnO1xuaW1wb3J0IHR5cGUgeyBXb3JrZmxvd1J1biwgV29ya2Zsb3dSdW5TdGF0dXMsIFdvcmxkIH0gZnJvbSAnQHdvcmtmbG93L3dvcmxkJztcbmltcG9ydCB7IGVudk51bWJlciB9IGZyb20gJ0B3b3JrZmxvdy93b3JsZC9lbnYtY29uZmlnJztcbmltcG9ydCB7IFNQRUNfVkVSU0lPTl9DVVJSRU5UIH0gZnJvbSAnQHdvcmtmbG93L3dvcmxkL3NwZWMtdmVyc2lvbic7XG5pbXBvcnQge1xuICBkZXJpdmVSdW5QYXlsb2FkS2V5cyxcbiAgdHlwZSBQYXlsb2FkS2V5LFxufSBmcm9tICcuLi9zZXJpYWxpemF0aW9uL2VuY3J5cHRpb24uanMnO1xuaW1wb3J0IHtcbiAgY3JlYXRlRm9yd2FyZGVkV3JpdGFibGUsXG4gIGdldEZvcndhcmRlZFdyaXRhYmxlRW5jcnlwdGlvbktleSxcbiAgZ2V0UnVuUmVhZGFibGVTdHJlYW0sXG4gIGh5ZHJhdGVSdW5FcnJvcixcbiAgaHlkcmF0ZVdvcmtmbG93UmV0dXJuVmFsdWUsXG4gIHRhZ0ZvcndhcmRlZFdyaXRhYmxlVGFyZ2V0LFxufSBmcm9tICcuLi9zZXJpYWxpemF0aW9uLmpzJztcbmltcG9ydCB7IGdldFdvcmtmbG93UnVuU3RyZWFtSWQgfSBmcm9tICcuLi91dGlsLmpzJztcbmltcG9ydCB7IGdldFdvcmxkTGF6eSB9IGZyb20gJy4vZ2V0LXdvcmxkLWxhenkuanMnO1xuaW1wb3J0IHtcbiAgdHlwZSBDYW5jZWxSdW5PcHRpb25zLFxuICB0eXBlIFN0b3BTbGVlcE9wdGlvbnMsXG4gIHR5cGUgU3RvcFNsZWVwUmVzdWx0LFxuICB3YWtlVXBSdW4sXG59IGZyb20gJy4vcnVucy5qcyc7XG5cbmNvbnN0IFJFVFVSTl9WQUxVRV9QT0xMX0lOVEVSVkFMX01TID0gMV8wMDA7XG5jb25zdCBQQVlMT0FEX1RFUk1JTkFMX1JVTl9TVEFUVVNFUyA9IG5ldyBTZXQ8V29ya2Zsb3dSdW5TdGF0dXM+KFtcbiAgJ2NvbXBsZXRlZCcsXG4gICdmYWlsZWQnLFxuXSk7XG5cbi8vIEdpdmUgcmVzaWxpZW50IHN0YXJ0cyB1cCB0byAxMCBzZWNvbmRzIHRvIGNyZWF0ZSB0aGUgcnVuLlxuY29uc3QgTk9UX0ZPVU5EX1JFVFJZX0RFTEFZUyA9IFsxXzAwMCwgM18wMDAsIDZfMDAwXTtcblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJldHVyblZhbHVlUG9sbEludGVydmFsTXMoKTogbnVtYmVyIHtcbiAgcmV0dXJuIGVudk51bWJlcihcbiAgICAnV09SS0ZMT1dfUkVUVVJOX1ZBTFVFX1BPTExfSU5URVJWQUxfTVMnLFxuICAgIFJFVFVSTl9WQUxVRV9QT0xMX0lOVEVSVkFMX01TLFxuICAgIHsgaW50ZWdlcjogdHJ1ZSwgbWluOiAxIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBIb3cgbG9uZyBhIHNpbmdsZSBgcnVucy53YWl0Rm9yVGVybWluYWxTdGF0dXNgIGNhbGwgbWF5IGJsb2NrIHdoaWxlIHdhaXRpbmdcbiAqIGZvciBhIHJ1biB0byBmaW5pc2guIFRoZSB3YWl0IGlzIHJlLWlzc3VlZCB1bnRpbCB0aGUgcnVuIGlzIHRlcm1pbmFsLCBzb1xuICogdGhpcyBpcyBhIHBlci1jYWxsIGJ1ZGdldCByYXRoZXIgdGhhbiBhIGxpbWl0IG9uIHRvdGFsIHdhaXQgdGltZTogaXRzIG9ubHlcbiAqIGpvYiBpcyB0byBib3VuZCBvbmUgcmVxdWVzdCBzbyBhIHN0YWxsZWQgY29ubmVjdGlvbiBjYW5ub3QgaG9sZCB0aGUgYXdhaXRpbmdcbiAqIHNpZGUgZm9yZXZlci5cbiAqXG4gKiA1MHMgaXMgdGhlIGxhcmdlc3QgYnVkZ2V0IGB3b3JsZC12ZXJjZWxgIGNhbiBhY3R1YWxseSByZXF1ZXN0OiBpdCBjbGFtcHMgdG9cbiAqIGBSRVFVRVNUX1RJTUVPVVRfTVNgICg2MHMpIG1pbnVzIDEwcyBvZiBoZWFkcm9vbSwgc28gdGhlIGJ1ZGdldCBpcyBhbHdheXNcbiAqIG9ic2VydmVkIGFzIGEgKnJlc3BvbnNlKiAoYSBub24tdGVybWluYWwgc25hcHNob3QpIHJhdGhlciB0aGFuIGFzIGFcbiAqIGNsaWVudC1zaWRlIHRpbWVvdXQuIEFza2luZyBmb3IgbW9yZSBpcyBzaWxlbnRseSByZWR1Y2VkIHRvIHRoYXQsIHNvIHJhaXNpbmdcbiAqIHRoaXMgd2l0aG91dCBhbHNvIHJhaXNpbmcgYFdPUktGTE9XX1JFUVVFU1RfVElNRU9VVF9NU2AgaGFzIG5vIGVmZmVjdC5cbiAqL1xuY29uc3QgUkVUVVJOX1ZBTFVFX1dBSVRfVElNRU9VVF9NUyA9IDUwXzAwMDtcblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJldHVyblZhbHVlV2FpdFRpbWVvdXRNcygpOiBudW1iZXIge1xuICByZXR1cm4gZW52TnVtYmVyKFxuICAgICdXT1JLRkxPV19SRVRVUk5fVkFMVUVfV0FJVF9NUycsXG4gICAgUkVUVVJOX1ZBTFVFX1dBSVRfVElNRU9VVF9NUyxcbiAgICB7IGludGVnZXI6IHRydWUsIG1pbjogMSB9XG4gICk7XG59XG5cbi8qKlxuICogSG93IG1hbnkgY29uc2VjdXRpdmUgbG9uZy1wb2xsIGNhbGxzIGBhd2FpdCBydW4ucmV0dXJuVmFsdWVgIHdpbGwgbWFrZVxuICogYmVmb3JlIGZhbGxpbmcgYmFjayB0byBpbnRlcnZhbCBwb2xsaW5nIGZvciB0aGUgcmVzdCBvZiB0aGUgd2FpdC5cbiAqXG4gKiBBIGNhcCBpcyB3b3J0aCBoYXZpbmcgYmVjYXVzZSBhIHdhaXQgdGhhdCBrZWVwcyByZXR1cm5pbmcgbm9uLXRlcm1pbmFsIGlzXG4gKiBpbmRpc3Rpbmd1aXNoYWJsZSBmcm9tIG9uZSB0aGF0IGlzIG5vdCB3b3JraW5nLCBhbmQgaW50ZXJ2YWwgcG9sbGluZyBpcyB0aGVcbiAqIGJlaGF2aW9yIHdlIGtub3cgaXMgY29ycmVjdC4gSXQgZG9lcyAqKm5vdCoqIGVuZCB0aGUgYXdhaXQ6IGEgcnVuIGxlZ2l0aW1hdGVseVxuICogbGFzdHMgaG91cnMgb3IgZGF5cywgc28gZXhoYXVzdGluZyB0aGUgY2FwIHN3aXRjaGVzIHN0cmF0ZWd5IGFuZCBrZWVwc1xuICogd2FpdGluZyByYXRoZXIgdGhhbiB0aHJvd2luZy5cbiAqXG4gKiBOb3RlIHRoZSBjb25zZXF1ZW5jZSwgc2luY2UgaXQgY3V0cyBhZ2FpbnN0IHRoZSByZWFzb24gdGhlIGxvbmcgcG9sbCBleGlzdHM6XG4gKiBhIHJ1biBzdGlsbCBnb2luZyBhZnRlciBgTUFYIHggYnVkZ2V0YCAofjggbWludXRlcyBhdCB0aGUgZGVmYXVsdHMpIHNwZW5kc1xuICogdGhlIHJlbWFpbmRlciBvZiBpdHMgbGlmZSBwb2xsaW5nIG9uY2UgcGVyXG4gKiBgV09SS0ZMT1dfUkVUVVJOX1ZBTFVFX1BPTExfSU5URVJWQUxfTVNgLCB3aGljaCBpcyBtb3JlIHJlcXVlc3RzIHRoYW5cbiAqIGNvbnRpbnVpbmcgdG8gbG9uZyBwb2xsIHdvdWxkIGhhdmUgY29zdC4gUnVucyB0aGF0IG91dGxpdmUgdGhlIGNhcCBhcmVcbiAqIGV4YWN0bHkgdGhlIG9uZXMgdGhlIHJlcXVlc3QgcmVkdWN0aW9uIGhlbHBlZCBtb3N0LlxuICovXG5jb25zdCBSRVRVUk5fVkFMVUVfTUFYX0xPTkdfUE9MTFMgPSAxMDtcblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJldHVyblZhbHVlTWF4TG9uZ1BvbGxzKCk6IG51bWJlciB7XG4gIHJldHVybiBlbnZOdW1iZXIoXG4gICAgJ1dPUktGTE9XX1JFVFVSTl9WQUxVRV9NQVhfTE9OR19QT0xMUycsXG4gICAgUkVUVVJOX1ZBTFVFX01BWF9MT05HX1BPTExTLFxuICAgIHsgaW50ZWdlcjogdHJ1ZSwgbWluOiAxIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIGBhd2FpdCBydW4ucmV0dXJuVmFsdWVgIG1heSB1c2UgdGhlIFdvcmxkJ3MgbG9uZyBwb2xsXG4gKiAoYHJ1bnMud2FpdEZvclRlcm1pbmFsU3RhdHVzYCkgaW5zdGVhZCBvZiBpbnRlcnZhbC1wb2xsaW5nIGBydW5zLmdldGAuXG4gKlxuICogRGVmYXVsdCAqKk9OKiogd2hlcmV2ZXIgdGhlIFdvcmxkIGltcGxlbWVudHMgdGhlIG1ldGhvZDsgYSBXb3JsZCB0aGF0IGRvZXNcbiAqIG5vdCBpcyBhbHJlYWR5IG9uIHRoZSBpbnRlcnZhbCBwYXRoIHdpdGggbm90aGluZyB0byBzd2l0Y2ggb2ZmLiBSZWFkc1xuICogYHByb2Nlc3MuZW52LldPUktGTE9XX1JFVFVSTl9WQUxVRV9MT05HX1BPTExgIGxhemlseTsgYW4gZXhwbGljaXQgYCcwJ2AgL1xuICogYCdmYWxzZSdgIGlzIHRoZSBraWxsIHN3aXRjaCwgcmVzdG9yaW5nIHRoZSBmaXhlZC1pbnRlcnZhbCBwb2xsIGV4YWN0bHkgYXNcbiAqIGl0IGJlaGF2ZWQgYmVmb3JlIHRoZSBmYXN0IHBhdGggZXhpc3RlZC5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUmV0dXJuVmFsdWVMb25nUG9sbEVuYWJsZWQoKTogYm9vbGVhbiB7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LldPUktGTE9XX1JFVFVSTl9WQUxVRV9MT05HX1BPTEw7XG4gIGlmIChyYXcgPT09IHVuZGVmaW5lZCB8fCByYXcgPT09ICcnKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuICEocmF3ID09PSAnMCcgfHwgcmF3LnRvTG93ZXJDYXNlKCkgPT09ICdmYWxzZScpO1xufVxuXG4vKipcbiAqIEEgYFJlYWRhYmxlU3RyZWFtYCBleHRlbmRlZCB3aXRoIHdvcmtmbG93LXNwZWNpZmljIGhlbHBlcnMuXG4gKi9cbmV4cG9ydCB0eXBlIFdvcmtmbG93UmVhZGFibGVTdHJlYW08UiA9IGFueT4gPSBSZWFkYWJsZVN0cmVhbTxSPiAmIHtcbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHRhaWwgaW5kZXggKGluZGV4IG9mIHRoZSBsYXN0IGtub3duIGNodW5rLCAwLWJhc2VkKSBvZiB0aGVcbiAgICogdW5kZXJseWluZyB3b3JrZmxvdyBzdHJlYW0uIFVzZWZ1bCBmb3IgcmVzb2x2aW5nIGEgbmVnYXRpdmUgYHN0YXJ0SW5kZXhgXG4gICAqIGludG8gYW4gYWJzb2x1dGUgcG9zaXRpb24sIGZvciBleGFtcGxlLCB3aGVuIGJ1aWxkaW5nIHJlY29ubmVjdGlvblxuICAgKiBlbmRwb2ludHMgdGhhdCBuZWVkIHRvIGluZm9ybSB0aGUgY2xpZW50IHdoZXJlIHRoZSBzdHJlYW0gc3RhcnRzLlxuICAgKlxuICAgKiBSZXR1cm5zIGAtMWAgd2hlbiBubyBjaHVua3MgaGF2ZSBiZWVuIHdyaXR0ZW4geWV0LlxuICAgKi9cbiAgZ2V0VGFpbEluZGV4KCk6IFByb21pc2U8bnVtYmVyPjtcbn07XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgY29uZmlndXJpbmcgYSB3b3JrZmxvdydzIHJlYWRhYmxlIHN0cmVhbS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBXb3JrZmxvd1JlYWRhYmxlU3RyZWFtT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBBbiBvcHRpb25hbCBuYW1lc3BhY2UgdG8gZGlzdGluZ3Vpc2ggYmV0d2VlbiBtdWx0aXBsZSBzdHJlYW1zIGFzc29jaWF0ZWRcbiAgICogd2l0aCB0aGUgc2FtZSB3b3JrZmxvdyBydW4uXG4gICAqL1xuICBuYW1lc3BhY2U/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgaW5kZXggbnVtYmVyIG9mIHRoZSBzdGFydGluZyBjaHVuayB0byBiZWdpbiByZWFkaW5nIHRoZSBzdHJlYW0gZnJvbS5cbiAgICogTmVnYXRpdmUgdmFsdWVzIHN0YXJ0IGZyb20gdGhlIGVuZCAoZS5nLiAtMyByZWFkcyB0aGUgbGFzdCAzIGNodW5rcykuXG4gICAqL1xuICBzdGFydEluZGV4PzogbnVtYmVyO1xuICAvKipcbiAgICogQW55IGFzeW5jaHJvbm91cyBvcGVyYXRpb25zIHRvIGNvbXBsZXRlIGJlZm9yZSBwYXVzaW5nIG9yIHRlcm1pbmF0aW5nIHRoZVxuICAgKiBleGVjdXRpb24gZW52aXJvbm1lbnRcbiAgICogKGkuZS4gdXNpbmcgW2B3YWl0VW50aWwoKWBdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2RvY3MvV2ViL0FQSS9FeHRlbmRhYmxlRXZlbnQvd2FpdFVudGlsKSBvciBzaW1pbGFyKS5cbiAgICovXG4gIG9wcz86IFByb21pc2U8YW55PltdO1xuICAvKipcbiAgICogVGhlIGdsb2JhbCBvYmplY3QgdG8gdXNlIGZvciBoeWRyYXRpbmcgdHlwZXMgZnJvbSB0aGUgZ2xvYmFsIHNjb3BlLlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byB7QGxpbmsgW2BnbG9iYWxUaGlzYF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvZ2xvYmFsVGhpcyl9LlxuICAgKi9cbiAgZ2xvYmFsPzogUmVjb3JkPHN0cmluZywgYW55Pjtcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBjb25maWd1cmluZyBhIHdyaXRhYmxlIG9udG8gYSB3b3JrZmxvdyBydW4ncyBzdHJlYW0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV29ya2Zsb3dSdW5Xcml0YWJsZVN0cmVhbU9wdGlvbnMge1xuICAvKipcbiAgICogQW4gb3B0aW9uYWwgbmFtZXNwYWNlIHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gbXVsdGlwbGUgc3RyZWFtcyBhc3NvY2lhdGVkXG4gICAqIHdpdGggdGhlIHNhbWUgd29ya2Zsb3cgcnVuLlxuICAgKi9cbiAgbmFtZXNwYWNlPzogc3RyaW5nO1xuICAvKipcbiAgICogQW55IGFzeW5jaHJvbm91cyBvcGVyYXRpb25zIHRvIGNvbXBsZXRlIGJlZm9yZSBwYXVzaW5nIG9yIHRlcm1pbmF0aW5nIHRoZVxuICAgKiBleGVjdXRpb24gZW52aXJvbm1lbnRcbiAgICogKGkuZS4gdXNpbmcgW2B3YWl0VW50aWwoKWBdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2RvY3MvV2ViL0FQSS9FeHRlbmRhYmxlRXZlbnQvd2FpdFVudGlsKSBvciBzaW1pbGFyKS5cbiAgICpcbiAgICogV3JpdGVzIGFyZSBhY2tub3dsZWRnZWQgb24gYnVmZmVyIGVudHJ5LCBzbyBhIGNhbGxlciB0aGF0IG5lZWRzIHRoZW1cbiAgICogZHVyYWJsZSBiZWZvcmUgdGhlIGVudmlyb25tZW50IGdvZXMgYXdheSBzaG91bGQgcGFzcyBhbiBhcnJheSBoZXJlIGFuZFxuICAgKiBhd2FpdCBpdCBhZnRlciByZWxlYXNpbmcgdGhlIHdyaXRlciBsb2NrLlxuICAgKi9cbiAgb3BzPzogUHJvbWlzZTxhbnk+W107XG4gIC8qKlxuICAgKiBUaGUgZ2xvYmFsIG9iamVjdCB0byB1c2UgZm9yIHJlZHVjaW5nIHR5cGVzIGZyb20gdGhlIGdsb2JhbCBzY29wZS5cbiAgICpcbiAgICogRGVmYXVsdHMgdG8ge0BsaW5rIFtgZ2xvYmFsVGhpc2BdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL2dsb2JhbFRoaXMpfS5cbiAgICovXG4gIGdsb2JhbD86IFJlY29yZDxzdHJpbmcsIGFueT47XG59XG5cbi8qKlxuICogQSBoYW5kbGVyIGNsYXNzIGZvciBhIHdvcmtmbG93IHJ1bi5cbiAqL1xuZXhwb3J0IGNsYXNzIFJ1bjxUUmVzdWx0PiB7XG4gIHN0YXRpYyBbV09SS0ZMT1dfU0VSSUFMSVpFXShpbnN0YW5jZTogUnVuPHVua25vd24+KSB7XG4gICAgcmV0dXJuIHsgcnVuSWQ6IGluc3RhbmNlLnJ1bklkLCByZXNpbGllbnRTdGFydDogaW5zdGFuY2UuI3Jlc2lsaWVudFN0YXJ0IH07XG4gIH1cblxuICBzdGF0aWMgW1dPUktGTE9XX0RFU0VSSUFMSVpFXShkYXRhOiB7XG4gICAgcnVuSWQ6IHN0cmluZztcbiAgICByZXNpbGllbnRTdGFydD86IGJvb2xlYW47XG4gIH0pIHtcbiAgICByZXR1cm4gbmV3IFJ1bihkYXRhLnJ1bklkLCB7IHJlc2lsaWVudFN0YXJ0OiBkYXRhLnJlc2lsaWVudFN0YXJ0IH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBJRCBvZiB0aGUgd29ya2Zsb3cgcnVuLlxuICAgKi9cbiAgcnVuSWQ6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHdvcmxkIG9iamVjdC5cbiAgICogQGludGVybmFsXG4gICAqL1xuICAjd29ybGRQcm9taXNlOiBQcm9taXNlPFdvcmxkPiB8IHVuZGVmaW5lZDtcbiAgZ2V0ICNsYXp5V29ybGRQcm9taXNlKCkge1xuICAgIGlmICghdGhpcy4jd29ybGRQcm9taXNlKSB0aGlzLiN3b3JsZFByb21pc2UgPSBnZXRXb3JsZExhenkoKTtcbiAgICByZXR1cm4gdGhpcy4jd29ybGRQcm9taXNlO1xuICB9XG5cbiAgLyoqXG4gICAqIENhY2hlZCBlbmNyeXB0aW9uIGtleSByZXNvbHV0aW9uLiBSZXNvbHZlZCBvbmNlIG9uIGZpcnN0IHVzZSBhbmRcbiAgICogcmV1c2VkIGZvciByZXR1cm5WYWx1ZSwgZ2V0UmVhZGFibGUoKSwgZXRjLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gICNlbmNyeXB0aW9uS2V5UHJvbWlzZTogUHJvbWlzZTxQYXlsb2FkS2V5IHwgdW5kZWZpbmVkPiB8IG51bGwgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBXaGVuIHRydWUsIHJ1bl9jcmVhdGVkIGZhaWxlZCBhbmQgdGhlIHJ1biBtYXkgbm90IGV4aXN0IHlldCAodGhlXG4gICAqIHJlc2lsaWVudCBzdGFydCBwYXRoIHdpbGwgY3JlYXRlIGl0IHZpYSBydW5fc3RhcnRlZCkuIHBvbGxSZXR1cm5WYWx1ZVxuICAgKiByZXRyaWVzIG9uIFdvcmtmbG93UnVuTm90Rm91bmRFcnJvciBvbmx5IHdoZW4gdGhpcyBmbGFnIGlzIHNldCBzb1xuICAgKiB0aGF0IG5vcm1hbCBydW5zIGZhaWwgZmFzdCBvbiA0MDQuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgI3Jlc2lsaWVudFN0YXJ0ID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IocnVuSWQ6IHN0cmluZywgb3B0cz86IHsgcmVzaWxpZW50U3RhcnQ/OiBib29sZWFuIH0pIHtcbiAgICB0aGlzLnJ1bklkID0gcnVuSWQ7XG4gICAgdGhpcy4jcmVzaWxpZW50U3RhcnQgPSBvcHRzPy5yZXNpbGllbnRTdGFydCA/PyBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyBhbmQgY2FjaGVzIHRoZSBlbmNyeXB0aW9uIGtleSBmb3IgdGhpcyBydW4uXG4gICAqIFRoZSBrZXkgaXMgdGhlIHNhbWUgZm9yIHRoZSBsaWZldGltZSBvZiBhIHJ1biwgc28gaXQgb25seSBuZWVkc1xuICAgKiB0byBiZSByZXNvbHZlZCBvbmNlLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gICNnZXRFbmNyeXB0aW9uS2V5KHJ1bj86IFdvcmtmbG93UnVuKTogUHJvbWlzZTxQYXlsb2FkS2V5IHwgdW5kZWZpbmVkPiB7XG4gICAgaWYgKCF0aGlzLiNlbmNyeXB0aW9uS2V5UHJvbWlzZSkge1xuICAgICAgdGhpcy4jZW5jcnlwdGlvbktleVByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3b3JsZCA9IGF3YWl0IHRoaXMuI2xhenlXb3JsZFByb21pc2U7XG4gICAgICAgIGNvbnN0IHJ1bkRhdGEgPSBydW4gPz8gKGF3YWl0IHdvcmxkLnJ1bnMuZ2V0KHRoaXMucnVuSWQpKTtcbiAgICAgICAgY29uc3QgcmF3S2V5ID0gYXdhaXQgd29ybGQuZ2V0RW5jcnlwdGlvbktleUZvclJ1bj8uKHJ1bkRhdGEpO1xuICAgICAgICByZXR1cm4gcmF3S2V5ID8gYXdhaXQgZGVyaXZlUnVuUGF5bG9hZEtleXMocmF3S2V5KSA6IHVuZGVmaW5lZDtcbiAgICAgIH0pKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLiNlbmNyeXB0aW9uS2V5UHJvbWlzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWZlcnMgZmV0Y2hpbmcgdGhlIHJ1biBhbmQgaXRzIGVuY3J5cHRpb24ga2V5IHVudGlsIGEgcmVhZGFibGUgaXMgZmlyc3RcbiAgICogY29uc3VtZWQuIFRoZSBmaXJzdCBwdWxsIHByZWZldGNoZXMgaXQgc28gYW4gZW5jcnlwdGVkIGZpcnN0IGZyYW1lIGNhbiBqb2luXG4gICAqIHRoZSBsb29rdXA7IHRoaXMgYWxzbyBhcHBsaWVzIHRvIGFuIGVtcHR5IGNvbnN1bWVkIHN0cmVhbS5cbiAgICogQGludGVybmFsXG4gICAqL1xuICAjZ2V0RW5jcnlwdGlvbktleUxhemlseSgpOiAoKSA9PiBQcm9taXNlPFBheWxvYWRLZXkgfCB1bmRlZmluZWQ+IHtcbiAgICByZXR1cm4gKCkgPT4gdGhpcy4jZ2V0RW5jcnlwdGlvbktleSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEludGVycnVwdHMgcGVuZGluZyBgc2xlZXAoKWAgY2FsbHMsIHJlc3VtaW5nIHRoZSB3b3JrZmxvdyBlYXJseS5cbiAgICpcbiAgICogQHBhcmFtIG9wdGlvbnMgLSBPcHRpb25hbCBzZXR0aW5ncyB0byB0YXJnZXQgc3BlY2lmaWMgc2xlZXAgY2FsbHMgYnkgY29ycmVsYXRpb24gSUQuXG4gICAqICAgSWYgbm90IHByb3ZpZGVkLCBhbGwgcGVuZGluZyBzbGVlcCBjYWxscyB3aWxsIGJlIGludGVycnVwdGVkLlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBTdG9wU2xlZXBSZXN1bHR9IG9iamVjdCBjb250YWluaW5nIHRoZSBudW1iZXIgb2Ygc2xlZXAgY2FsbHMgdGhhdCB3ZXJlIGludGVycnVwdGVkLlxuICAgKi9cbiAgYXN5bmMgd2FrZVVwKG9wdGlvbnM/OiBTdG9wU2xlZXBPcHRpb25zKTogUHJvbWlzZTxTdG9wU2xlZXBSZXN1bHQ+IHtcbiAgICAndXNlIHN0ZXAnO1xuICAgIHJldHVybiB3YWtlVXBSdW4oYXdhaXQgdGhpcy4jbGF6eVdvcmxkUHJvbWlzZSwgdGhpcy5ydW5JZCwgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogQ2FuY2VscyB0aGUgd29ya2Zsb3cgcnVuLlxuICAgKlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIGNhbmNlbGxhdGlvbiBzZXR0aW5ncy4gYGNhbmNlbFJlYXNvbmAgcmVjb3JkcyBhXG4gICAqICAgZnJlZS10ZXh0IHJlYXNvbiAobWF4IDUxMiBjaGFycykgb24gdGhlIHJ1bl9jYW5jZWxsZWQgZXZlbnQsIHN1cmZhY2VkIGluXG4gICAqICAgdGhlIHJ1biBkZXRhaWwgdmlldy5cbiAgICovXG4gIGFzeW5jIGNhbmNlbChvcHRpb25zPzogQ2FuY2VsUnVuT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgICd1c2Ugc3RlcCc7XG4gICAgY29uc3Qgd29ybGQgPSBhd2FpdCB0aGlzLiNsYXp5V29ybGRQcm9taXNlO1xuICAgIGF3YWl0IHdvcmxkLmV2ZW50cy5jcmVhdGUodGhpcy5ydW5JZCwge1xuICAgICAgZXZlbnRUeXBlOiAncnVuX2NhbmNlbGxlZCcsXG4gICAgICBzcGVjVmVyc2lvbjogU1BFQ19WRVJTSU9OX0NVUlJFTlQsXG4gICAgICAuLi4ob3B0aW9ucz8uY2FuY2VsUmVhc29uICE9PSB1bmRlZmluZWRcbiAgICAgICAgPyB7IGV2ZW50RGF0YTogeyBjYW5jZWxSZWFzb246IG9wdGlvbnMuY2FuY2VsUmVhc29uIH0gfVxuICAgICAgICA6IHt9KSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSB3b3JrZmxvdyBydW4gZXhpc3RzLlxuICAgKi9cbiAgZ2V0IGV4aXN0cygpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAndXNlIHN0ZXAnO1xuICAgIHJldHVybiB0aGlzLiNsYXp5V29ybGRQcm9taXNlLnRoZW4oKHdvcmxkKSA9PlxuICAgICAgd29ybGQucnVuc1xuICAgICAgICAuZ2V0KHRoaXMucnVuSWQsIHsgcmVzb2x2ZURhdGE6ICdub25lJyB9KVxuICAgICAgICAudGhlbigoKSA9PiB0cnVlKVxuICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgaWYgKFdvcmtmbG93UnVuTm90Rm91bmRFcnJvci5pcyhlcnJvcikpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgc3RhdHVzIG9mIHRoZSB3b3JrZmxvdyBydW4uXG4gICAqL1xuICBnZXQgc3RhdHVzKCk6IFByb21pc2U8V29ya2Zsb3dSdW5TdGF0dXM+IHtcbiAgICAndXNlIHN0ZXAnO1xuICAgIHJldHVybiB0aGlzLiNsYXp5V29ybGRQcm9taXNlLnRoZW4oKHdvcmxkKSA9PlxuICAgICAgd29ybGQucnVuc1xuICAgICAgICAuZ2V0KHRoaXMucnVuSWQsIHsgcmVzb2x2ZURhdGE6ICdub25lJyB9KVxuICAgICAgICAudGhlbigocnVuKSA9PiBydW4uc3RhdHVzKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgd29ya2Zsb3cgcnVuLlxuICAgKiBQb2xscyB0aGUgd29ya2Zsb3cgcmV0dXJuIHZhbHVlIHVudGlsIHRoZSB3b3JrZmxvdyBydW4gY29tcGxldGVzLlxuICAgKi9cbiAgZ2V0IHJldHVyblZhbHVlKCk6IFByb21pc2U8VFJlc3VsdD4ge1xuICAgICd1c2Ugc3RlcCc7XG4gICAgcmV0dXJuIHRoaXMuI3BvbGxSZXR1cm5WYWx1ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSB3b3JrZmxvdy5cbiAgICovXG4gIGdldCB3b3JrZmxvd05hbWUoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAndXNlIHN0ZXAnO1xuICAgIHJldHVybiB0aGlzLiNsYXp5V29ybGRQcm9taXNlLnRoZW4oKHdvcmxkKSA9PlxuICAgICAgd29ybGQucnVucy5nZXQodGhpcy5ydW5JZCkudGhlbigocnVuKSA9PiBydW4ud29ya2Zsb3dOYW1lKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHRpbWVzdGFtcCB3aGVuIHRoZSB3b3JrZmxvdyBydW4gd2FzIGNyZWF0ZWQuXG4gICAqL1xuICBnZXQgY3JlYXRlZEF0KCk6IFByb21pc2U8RGF0ZT4ge1xuICAgICd1c2Ugc3RlcCc7XG4gICAgcmV0dXJuIHRoaXMuI2xhenlXb3JsZFByb21pc2UudGhlbigod29ybGQpID0+XG4gICAgICB3b3JsZC5ydW5zLmdldCh0aGlzLnJ1bklkKS50aGVuKChydW4pID0+IHJ1bi5jcmVhdGVkQXQpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgdGltZXN0YW1wIHdoZW4gdGhlIHdvcmtmbG93IHJ1biBzdGFydGVkIGV4ZWN1dGlvbi5cbiAgICogUmV0dXJucyB1bmRlZmluZWQgaWYgdGhlIHdvcmtmbG93IGhhcyBub3Qgc3RhcnRlZCB5ZXQuXG4gICAqL1xuICBnZXQgc3RhcnRlZEF0KCk6IFByb21pc2U8RGF0ZSB8IHVuZGVmaW5lZD4ge1xuICAgICd1c2Ugc3RlcCc7XG4gICAgcmV0dXJuIHRoaXMuI2xhenlXb3JsZFByb21pc2UudGhlbigod29ybGQpID0+XG4gICAgICB3b3JsZC5ydW5zLmdldCh0aGlzLnJ1bklkKS50aGVuKChydW4pID0+IHJ1bi5zdGFydGVkQXQpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgdGltZXN0YW1wIHdoZW4gdGhlIHdvcmtmbG93IHJ1biBjb21wbGV0ZWQuXG4gICAqIFJldHVybnMgdW5kZWZpbmVkIGlmIHRoZSB3b3JrZmxvdyBoYXMgbm90IGNvbXBsZXRlZCB5ZXQuXG4gICAqL1xuICBnZXQgY29tcGxldGVkQXQoKTogUHJvbWlzZTxEYXRlIHwgdW5kZWZpbmVkPiB7XG4gICAgJ3VzZSBzdGVwJztcbiAgICByZXR1cm4gdGhpcy4jbGF6eVdvcmxkUHJvbWlzZS50aGVuKCh3b3JsZCkgPT5cbiAgICAgIHdvcmxkLnJ1bnMuZ2V0KHRoaXMucnVuSWQpLnRoZW4oKHJ1bikgPT4gcnVuLmNvbXBsZXRlZEF0KVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHJlYWRhYmxlIHN0cmVhbSBvZiB0aGUgd29ya2Zsb3cgcnVuLlxuICAgKi9cbiAgZ2V0IHJlYWRhYmxlKCk6IFdvcmtmbG93UmVhZGFibGVTdHJlYW0ge1xuICAgIHJldHVybiB0aGlzLmdldFJlYWRhYmxlKCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIHRoZSB3b3JrZmxvdyBydW4ncyBkZWZhdWx0IHJlYWRhYmxlIHN0cmVhbSwgd2hpY2ggcmVhZHMgY2h1bmtzXG4gICAqIHdyaXR0ZW4gdG8gdGhlIGNvcnJlc3BvbmRpbmcgd3JpdGFibGUgc3RyZWFtIHtAbGluayBnZXRXcml0YWJsZX0uXG4gICAqXG4gICAqIFRoZSByZXR1cm5lZCBzdHJlYW0gaGFzIGFuIGFkZGl0aW9uYWwge0BsaW5rIFdvcmtmbG93UmVhZGFibGVTdHJlYW0uZ2V0VGFpbEluZGV4IHwgZ2V0VGFpbEluZGV4KCl9XG4gICAqIGhlbHBlciB0aGF0IHJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBsYXN0IGtub3duIGNodW5rLiBUaGlzIGlzIHVzZWZ1bCB3aGVuXG4gICAqIGJ1aWxkaW5nIHJlY29ubmVjdGlvbiBlbmRwb2ludHMgdGhhdCBuZWVkIHRvIGluZm9ybSBjbGllbnRzIHdoZXJlIHRoZVxuICAgKiBzdHJlYW0gc3RhcnRzLlxuICAgKlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIGZvciB0aGUgcmVhZGFibGUgc3RyZWFtLlxuICAgKiBAcmV0dXJucyBBIGBXb3JrZmxvd1JlYWRhYmxlU3RyZWFtYCBmb3IgdGhlIHdvcmtmbG93IHJ1bi5cbiAgICovXG4gIGdldFJlYWRhYmxlPFIgPSBhbnk+KFxuICAgIG9wdGlvbnM6IFdvcmtmbG93UmVhZGFibGVTdHJlYW1PcHRpb25zID0ge31cbiAgKTogV29ya2Zsb3dSZWFkYWJsZVN0cmVhbTxSPiB7XG4gICAgJ3VzZSBzdGVwJztcbiAgICBjb25zdCB7IG9wcyA9IFtdLCBnbG9iYWwgPSBnbG9iYWxUaGlzLCBzdGFydEluZGV4LCBuYW1lc3BhY2UgfSA9IG9wdGlvbnM7XG4gICAgY29uc3QgbmFtZSA9IGdldFdvcmtmbG93UnVuU3RyZWFtSWQodGhpcy5ydW5JZCwgbmFtZXNwYWNlKTtcbiAgICAvLyBUaGUgcmVzb2x2ZXIgc3RhcnRzIG9ubHkgb24gdGhlIHJlYWRhYmxlJ3MgZmlyc3QgcHVsbCwgc28gY29uc3RydWN0aW9uXG4gICAgLy8gaXMgaW5lcnQuIEEgY29uc3VtZWQgZW1wdHkgc3RyZWFtIHN0aWxsIHBlcmZvcm1zIHRoZSBzcGVjdWxhdGl2ZSBsb29rdXBcbiAgICAvLyB0byBrZWVwIHRoZSBmaXJzdCBlbmNyeXB0ZWQtZnJhbWUgcGF0aCBjb25jdXJyZW50LlxuICAgIGNvbnN0IGVuY3J5cHRpb25LZXkgPSB0aGlzLiNnZXRFbmNyeXB0aW9uS2V5TGF6aWx5KCk7XG4gICAgY29uc3Qgc3RyZWFtID0gZ2V0UnVuUmVhZGFibGVTdHJlYW08Uj4oXG4gICAgICBnbG9iYWwsXG4gICAgICBvcHMsXG4gICAgICB0aGlzLnJ1bklkLFxuICAgICAgbmFtZSxcbiAgICAgIHN0YXJ0SW5kZXgsXG4gICAgICBlbmNyeXB0aW9uS2V5XG4gICAgKTtcblxuICAgIGNvbnN0IHdvcmxkUHJvbWlzZSA9IHRoaXMuI2xhenlXb3JsZFByb21pc2U7XG4gICAgY29uc3QgcnVuSWQgPSB0aGlzLnJ1bklkO1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHN0cmVhbSwge1xuICAgICAgZ2V0VGFpbEluZGV4OiBhc3luYyAoKTogUHJvbWlzZTxudW1iZXI+ID0+IHtcbiAgICAgICAgY29uc3Qgd29ybGQgPSBhd2FpdCB3b3JsZFByb21pc2U7XG4gICAgICAgIGNvbnN0IGluZm8gPSBhd2FpdCB3b3JsZC5zdHJlYW1zLmdldEluZm8ocnVuSWQsIG5hbWUpO1xuICAgICAgICByZXR1cm4gaW5mby50YWlsSW5kZXg7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqIFRoZSB3cml0YWJsZSBzdHJlYW0gb2YgdGhlIHdvcmtmbG93IHJ1bi4gKi9cbiAgZ2V0IHdyaXRhYmxlKCk6IFdyaXRhYmxlU3RyZWFtIHtcbiAgICByZXR1cm4gdGhpcy5nZXRXcml0YWJsZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSB3cml0YWJsZSB0aGF0IGFwcGVuZHMgdG8gdGhpcyBydW4ncyBzdHJlYW0uXG4gICAqXG4gICAqIEluaXRpYWxpemF0aW9uIGlzIGRlZmVycmVkIHVudGlsIHRoZSBmaXJzdCB3cml0ZS4gVGhlIHJ1biBtdXN0IGFscmVhZHlcbiAgICogZXhpc3QuIFRoZSB3cml0YWJsZSBtYXkgYmUgZm9yd2FyZGVkIHRocm91Z2ggYHN0YXJ0KClgIGFuZCBpbnRvIHN0ZXBzLCBidXRcbiAgICogZ3JhbnRzIG5vIHJlYWQgYWNjZXNzIG9yIGFkZGl0aW9uYWwgYXV0aG9yaXphdGlvbi5cbiAgICpcbiAgICogQHJlbWFya3NcbiAgICogYHdyaXRlci5jbG9zZSgpYCBjbG9zZXMgdGhlIHNoYXJlZCBzdHJlYW0uIENvbnRyaWJ1dG9ycyBzaG91bGQgY2FsbFxuICAgKiBgcmVsZWFzZUxvY2soKWAsIHdoaWNoIGFsc28gZHJhaW5zIHBlbmRpbmcgd3JpdGVzLlxuICAgKlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSB3cml0YWJsZSBzdHJlYW0gb3B0aW9ucy5cbiAgICovXG4gIGdldFdyaXRhYmxlPFcgPSBhbnk+KFxuICAgIG9wdGlvbnM6IFdvcmtmbG93UnVuV3JpdGFibGVTdHJlYW1PcHRpb25zID0ge31cbiAgKTogV3JpdGFibGVTdHJlYW08Vz4ge1xuICAgICd1c2Ugc3RlcCc7XG4gICAgY29uc3QgeyBvcHMgPSBbXSwgZ2xvYmFsID0gZ2xvYmFsVGhpcywgbmFtZXNwYWNlIH0gPSBvcHRpb25zO1xuICAgIGNvbnN0IG5hbWUgPSBnZXRXb3JrZmxvd1J1blN0cmVhbUlkKHRoaXMucnVuSWQsIG5hbWVzcGFjZSk7XG4gICAgbGV0IHRhcmdldFByb21pc2U6XG4gICAgICB8IFByb21pc2U8e1xuICAgICAgICAgIGtleTogUGF5bG9hZEtleSB8IHVuZGVmaW5lZDtcbiAgICAgICAgICBkZXBsb3ltZW50SWQ/OiBzdHJpbmc7XG4gICAgICAgICAgZW5jcnlwdGlvblB1YmxpY0tleT86IHN0cmluZztcbiAgICAgICAgfT5cbiAgICAgIHwgdW5kZWZpbmVkO1xuICAgIGxldCB3cml0YWJsZTogV3JpdGFibGVTdHJlYW08Vz47XG5cbiAgICBjb25zdCByZXNvbHZlVGFyZ2V0ID0gKCkgPT4ge1xuICAgICAgdGFyZ2V0UHJvbWlzZSA/Pz0gdGhpcy4jZ2V0TWV0YWRhdGEoKS50aGVuKGFzeW5jIChydW4pID0+IHtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0ge1xuICAgICAgICAgIGtleTogYXdhaXQgZ2V0Rm9yd2FyZGVkV3JpdGFibGVFbmNyeXB0aW9uS2V5KFxuICAgICAgICAgICAgdGhpcy5ydW5JZCxcbiAgICAgICAgICAgIHJ1bi5kZXBsb3ltZW50SWQsXG4gICAgICAgICAgICBydW4uZW5jcnlwdGlvblB1YmxpY0tleVxuICAgICAgICAgICksXG4gICAgICAgICAgZGVwbG95bWVudElkOiBydW4uZGVwbG95bWVudElkLFxuICAgICAgICAgIGVuY3J5cHRpb25QdWJsaWNLZXk6IHJ1bi5lbmNyeXB0aW9uUHVibGljS2V5LFxuICAgICAgICB9O1xuICAgICAgICB0YWdGb3J3YXJkZWRXcml0YWJsZVRhcmdldCh3cml0YWJsZSwgdGFyZ2V0KTtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRhcmdldFByb21pc2U7XG4gICAgfTtcblxuICAgIHdyaXRhYmxlID0gY3JlYXRlRm9yd2FyZGVkV3JpdGFibGU8Vz4oe1xuICAgICAgZ2xvYmFsLFxuICAgICAgb3BzLFxuICAgICAgcnVuSWQ6IHRoaXMucnVuSWQsXG4gICAgICBuYW1lLFxuICAgICAga2V5OiAoKSA9PiByZXNvbHZlVGFyZ2V0KCkudGhlbigoeyBrZXkgfSkgPT4ga2V5KSxcbiAgICB9KTtcbiAgICByZXR1cm4gd3JpdGFibGU7XG4gIH1cblxuICAvKiogUmVhZHMgbWV0YWRhdGEsIGJyaWVmbHkgcmV0cnlpbmcgcmVzaWxpZW50IHN0YXJ0cy4gQGludGVybmFsICovXG4gIGFzeW5jICNnZXRNZXRhZGF0YSgpIHtcbiAgICBjb25zdCB3b3JsZCA9IGF3YWl0IHRoaXMuI2xhenlXb3JsZFByb21pc2U7XG4gICAgY29uc3QgbWF4UmV0cmllcyA9IHRoaXMuI3Jlc2lsaWVudFN0YXJ0ID8gTk9UX0ZPVU5EX1JFVFJZX0RFTEFZUy5sZW5ndGggOiAwO1xuICAgIGxldCBhdHRlbXB0ID0gMDtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdvcmxkLnJ1bnMuZ2V0KHRoaXMucnVuSWQsIHsgcmVzb2x2ZURhdGE6ICdub25lJyB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmICghV29ya2Zsb3dSdW5Ob3RGb3VuZEVycm9yLmlzKGVycm9yKSB8fCBhdHRlbXB0ID49IG1heFJldHJpZXMpIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkZWxheSA9IE5PVF9GT1VORF9SRVRSWV9ERUxBWVNbYXR0ZW1wdF0hO1xuICAgICAgICBhdHRlbXB0Kys7XG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIGRlbGF5KSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBhc3luYyAjcmVzb2x2ZVRlcm1pbmFsUmV0dXJuVmFsdWUocnVuOiBXb3JrZmxvd1J1bik6IFByb21pc2U8VFJlc3VsdD4ge1xuICAgIC8vIEV4cGlyeSBpcyBjaGVja2VkIGJlZm9yZSB0aGUgc3RhdHVzIGJyYW5jaGVzLCBhbmQgZGVsaWJlcmF0ZWx5IHNvLlxuICAgIC8vXG4gICAgLy8gUGFzdCBpdHMgcmV0ZW50aW9uIGJvdW5kYXJ5IGEgcnVuJ3MgcGF5bG9hZHMgYXJlIGdvbmUgYnV0IGl0cyBtZXRhZGF0YVxuICAgIC8vIHVzdWFsbHkgaXMgbm90LCBzbyBgcnVuLm91dHB1dGAgYW5kIGBydW4uZXJyb3JgIGh5ZHJhdGUgdG8gYW5cbiAgICAvLyBleHBpcmVkLWRhdGEgcGxhY2Vob2xkZXIgcmF0aGVyIHRoYW4gdG8gYW55dGhpbmcgdGhlIGNhbGxlciBhc2tlZCBmb3IuXG4gICAgLy8gSGFuZGluZyB0aGF0IGJhY2sgYXMgaWYgaXQgd2VyZSB0aGUgcmV0dXJuIHZhbHVlIOKAlCBvciB3cmFwcGluZyBpdCBhc1xuICAgIC8vIHRoZSBgY2F1c2VgIG9mIGEgV29ya2Zsb3dSdW5GYWlsZWRFcnJvciDigJQgaXMgd29yc2UgdGhhbiBmYWlsaW5nOiBpdCBpc1xuICAgIC8vIGluZGlzdGluZ3Vpc2hhYmxlIGZyb20gdGhlIHdvcmtmbG93IGhhdmluZyBnZW51aW5lbHkgcmV0dXJuZWQgaXQuXG4gICAgLy9cbiAgICAvLyBBIHJ1biBzdGFydGVkIHdpdGggYGV4cGVyaW1lbnRhbF9yZXRlbnRpb246IDBgIHJlYWNoZXMgdGhpcyBhbG1vc3RcbiAgICAvLyBpbW1lZGlhdGVseSAoaXRzIHB1cmdlIHJhY2VzLCBhbmQgdXN1YWxseSBiZWF0cywgdGhlIGNhbGxlcidzIG93biByZWFkXG4gICAgLy8gb2YgdGhlIHJlc3VsdCkuIEFuIG9yZGluYXJ5IHJ1biByZWFjaGVzIGl0IHdoZW5ldmVyIGl0IGlzIHJlYWQgYWZ0ZXJcbiAgICAvLyB0aGUgV29ybGQncyBkZWZhdWx0IHdpbmRvdy4gQm90aCBhcmUgdGhlIHNhbWUgY29uZGl0aW9uIGFuZCBnZXQgdGhlXG4gICAgLy8gc2FtZSB0ZXJtaW5hbCwgbm9uLXJldHJ5YWJsZSBlcnJvciwgY2Fycnlpbmcgd2hhdGV2ZXIgbWV0YWRhdGFcbiAgICAvLyBzdXJ2aXZlZCBzbyB0aGUgY2FsbGVyIGNhbiBzdGlsbCB0ZWxsIHN1Y2Nlc3MgZnJvbSBmYWlsdXJlLlxuICAgIC8vXG4gICAgLy8gV2hlbiBldmVuIHRoZSBtZXRhZGF0YSBpcyBnb25lIHRoZSBXb3JsZCByZXBvcnRzIHRoZSBydW4gYXMgbWlzc2luZyBhbmRcbiAgICAvLyB0aGUgY2FsbGVyIGdldHMgV29ya2Zsb3dSdW5Ob3RGb3VuZEVycm9yIGZyb20gdGhlIHJlYWQgYWJvdmUgaW5zdGVhZCDigJRcbiAgICAvLyB0aGVyZSBpcyBub3RoaW5nIGxlZnQgaGVyZSB0byBkZXNjcmliZS5cbiAgICBjb25zdCBleHBpcmVkQXQgPSBydW4uZXhwaXJlZEF0O1xuICAgIGlmIChleHBpcmVkQXQgIT0gbnVsbCAmJiBleHBpcmVkQXQgPD0gbmV3IERhdGUoKSkge1xuICAgICAgdGhyb3cgbmV3IFJ1bkV4cGlyZWRFcnJvcihcbiAgICAgICAgYFJ1biBcIiR7dGhpcy5ydW5JZH1cIiAke3J1bi5zdGF0dXMgPT09ICdjb21wbGV0ZWQnID8gJ2NvbXBsZXRlZCcgOiBgaXMgJHtydW4uc3RhdHVzfWB9LCBidXQgaXRzIGRhdGEgZXhwaXJlZCBhdCAke2V4cGlyZWRBdC50b0lTT1N0cmluZygpfSBhbmQgaXMgbm8gbG9uZ2VyIHJlYWRhYmxlLmAsXG4gICAgICAgIHRoaXMucnVuSWQsXG4gICAgICAgIHJ1bi5zdGF0dXMsXG4gICAgICAgIGV4cGlyZWRBdFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAocnVuLnN0YXR1cyA9PT0gJ2NvbXBsZXRlZCcpIHtcbiAgICAgIGNvbnN0IGVuY3J5cHRpb25LZXkgPSBhd2FpdCB0aGlzLiNnZXRFbmNyeXB0aW9uS2V5KHJ1bik7XG4gICAgICByZXR1cm4gYXdhaXQgaHlkcmF0ZVdvcmtmbG93UmV0dXJuVmFsdWUoXG4gICAgICAgIHJ1bi5vdXRwdXQsXG4gICAgICAgIHRoaXMucnVuSWQsXG4gICAgICAgIGVuY3J5cHRpb25LZXlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKHJ1bi5zdGF0dXMgPT09ICdjYW5jZWxsZWQnKSB7XG4gICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW5DYW5jZWxsZWRFcnJvcih0aGlzLnJ1bklkKTtcbiAgICB9XG5cbiAgICBpZiAocnVuLnN0YXR1cyA9PT0gJ2ZhaWxlZCcpIHtcbiAgICAgIC8vIEh5ZHJhdGUgdGhlIHNlcmlhbGl6ZWQgcnVuIGVycm9yIHNvIHRoZSBvcmlnaW5hbCB0aHJvd24gdmFsdWVcbiAgICAgIC8vICh3aXRoIGl0cyB0eXBlIGlkZW50aXR5LCBjYXVzZSBjaGFpbiwgZXRjLikgaXMgc2V0IGFzIHRoZVxuICAgICAgLy8gYGNhdXNlYCBvbiBXb3JrZmxvd1J1bkZhaWxlZEVycm9yLlxuICAgICAgY29uc3QgZW5jcnlwdGlvbktleSA9IGF3YWl0IHRoaXMuI2dldEVuY3J5cHRpb25LZXkocnVuKTtcbiAgICAgIGxldCBoeWRyYXRlZEVycm9yOiB1bmtub3duO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaHlkcmF0ZWRFcnJvciA9IGF3YWl0IGh5ZHJhdGVSdW5FcnJvcihcbiAgICAgICAgICBydW4uZXJyb3IsXG4gICAgICAgICAgdGhpcy5ydW5JZCxcbiAgICAgICAgICBlbmNyeXB0aW9uS2V5XG4gICAgICAgICk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gSWYgaHlkcmF0aW9uIGZhaWxzLCBzdXJmYWNlIGEgZ2VuZXJpYyBmYWxsYmFjayByYXRoZXIgdGhhblxuICAgICAgICAvLyBsZWF2aW5nIHRoZSB1c2VyIHdpdGggYSByYXcgVWludDhBcnJheS4gVGhlIHJ1bidzIGVycm9yQ29kZVxuICAgICAgICAvLyBpcyBzdGlsbCBwcmVzZXJ2ZWQgb24gdGhlIHRocm93biBXb3JrZmxvd1J1bkZhaWxlZEVycm9yLlxuICAgICAgICBoeWRyYXRlZEVycm9yID0gbmV3IEVycm9yKCdGYWlsZWQgdG8gaHlkcmF0ZSB3b3JrZmxvdyBydW4gZXJyb3InKTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bkZhaWxlZEVycm9yKHRoaXMucnVuSWQsIGh5ZHJhdGVkRXJyb3IsIHtcbiAgICAgICAgZXJyb3JDb2RlOiBydW4uZXJyb3JDb2RlLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gVGVybWluYWwgc3RhdHVzZXMgYXJlIGltbXV0YWJsZSwgYnV0IGlmIGFuIGluY29uc2lzdGVudCB3b3JsZCByZXR1cm5zXG4gICAgLy8gYSBub24tdGVybWluYWwgZnVsbCByZWNvcmQsIHJlc3VtZSBwb2xsaW5nIHNhZmVseS5cbiAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW5Ob3RDb21wbGV0ZWRFcnJvcih0aGlzLnJ1bklkLCBydW4uc3RhdHVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQb2xscyB0aGUgd29ya2Zsb3cgcmV0dXJuIHZhbHVlIHVudGlsIHRoZSB3b3JrZmxvdyBydW4gY29tcGxldGVzLlxuICAgKiBAaW50ZXJuYWxcbiAgICogQHJldHVybnMgVGhlIHdvcmtmbG93IHJldHVybiB2YWx1ZS5cbiAgICovXG4gIGFzeW5jICNwb2xsUmV0dXJuVmFsdWUoKTogUHJvbWlzZTxUUmVzdWx0PiB7XG4gICAgY29uc3Qgd29ybGQgPSBhd2FpdCB0aGlzLiNsYXp5V29ybGRQcm9taXNlO1xuXG4gICAgLy8gV2hlbiByZXNpbGllbnRTdGFydCBpcyB0cnVlLCBydW5fY3JlYXRlZCBmYWlsZWQgYW5kIHRoZSBydW4gbWF5XG4gICAgLy8gbm90IGV4aXN0IHlldC4gUmV0cnkgb24gV29ya2Zsb3dSdW5Ob3RGb3VuZEVycm9yIHVwIHRvIDMgdGltZXNcbiAgICAvLyAoMXMgKyAzcyArIDZzID0gMTBzIHRvdGFsKSB0byBnaXZlIHRoZSBxdWV1ZSB0aW1lIHRvIGRlbGl2ZXJcbiAgICAvLyBhbmQgdGhlIHJ1bnRpbWUgdG8gY3JlYXRlIHRoZSBydW4gdmlhIHJ1bl9zdGFydGVkLlxuICAgIC8vIFdoZW4gcmVzaWxpZW50U3RhcnQgaXMgZmFsc2UsIDQwNCBpcyBhIHJlYWwgZXJyb3I6IGZhaWwgZmFzdC5cbiAgICBsZXQgbm90Rm91bmRSZXRyaWVzID0gMDtcbiAgICBjb25zdCBOT1RfRk9VTkRfTUFYX1JFVFJJRVMgPSB0aGlzLiNyZXNpbGllbnRTdGFydFxuICAgICAgPyBOT1RfRk9VTkRfUkVUUllfREVMQVlTLmxlbmd0aFxuICAgICAgOiAwO1xuXG4gICAgLy8gUHJlZmVyIHRoZSBXb3JsZCdzIGxvbmcgcG9sbDogb25lIHJlYWQgdGhhdCB0aGUgYmFja2VuZCBob2xkcyBvcGVuXG4gICAgLy8gdW50aWwgdGhlIHJ1biBmaW5pc2hlcywgaW5zdGVhZCBvZiBhc2tpbmcgYWdhaW4gZXZlcnkgc2Vjb25kIGFuZFxuICAgIC8vIHBheWluZyB1cCB0byBhIGZ1bGwgaW50ZXJ2YWwgb2YgcXVhbnRpemF0aW9uIG9uIGEgcnVuIHRoYXQgYWxyZWFkeVxuICAgIC8vIGVuZGVkLiBXb3JsZHMgdGhhdCBjYW5ub3Qgd2FpdCBkbyBub3QgaW1wbGVtZW50IGl0IChzZWVcbiAgICAvLyBgU3RvcmFnZVsncnVucyddLndhaXRGb3JUZXJtaW5hbFN0YXR1c2ApIGFuZCB0aGlzIHN0YXlzIHRoZSBleGFjdFxuICAgIC8vIGZpeGVkLWludGVydmFsIHBvbGwgaXQgaGFzIGFsd2F5cyBiZWVuLCBhcyBkb2VzIGFuIG9wZXJhdG9yIHdob1xuICAgIC8vIHRocm93cyB0aGUgYFdPUktGTE9XX1JFVFVSTl9WQUxVRV9MT05HX1BPTEw9MGAga2lsbCBzd2l0Y2guXG4gICAgY29uc3Qgd2FpdEZvclRlcm1pbmFsU3RhdHVzID0gaXNSZXR1cm5WYWx1ZUxvbmdQb2xsRW5hYmxlZCgpXG4gICAgICA/IHdvcmxkLnJ1bnMud2FpdEZvclRlcm1pbmFsU3RhdHVzPy5iaW5kKHdvcmxkLnJ1bnMpXG4gICAgICA6IHVuZGVmaW5lZDtcblxuICAgIC8vIExvbmcgcG9sbHMgc3BlbnQgc28gZmFyLiBPbmNlIHRoZSBjYXAgaXMgcmVhY2hlZCB0aGUgbG9vcCBrZWVwcyB3YWl0aW5nXG4gICAgLy8gYnV0IG9uIHRoZSBpbnRlcnZhbCBwYXRoLCB3aGljaCBpcyB0aGUgc3RyYXRlZ3kgd2Uga25vdyBpcyBjb3JyZWN0OyBzZWVcbiAgICAvLyBgUkVUVVJOX1ZBTFVFX01BWF9MT05HX1BPTExTYC4gTmV2ZXIgYSByZWFzb24gdG8gc3RvcCBhd2FpdGluZy5cbiAgICBsZXQgbG9uZ1BvbGxzID0gMDtcbiAgICBjb25zdCBtYXhMb25nUG9sbHMgPSBnZXRSZXR1cm5WYWx1ZU1heExvbmdQb2xscygpO1xuXG4gICAgLy8gTk9URTogd2hlbiB0aGlzIHBvbGwgcnVucyBpbnNpZGUgYSBzdGVwIChlLmcuIHRoZSBzdGVwIHRoYXQgYSBwYXJlbnRcbiAgICAvLyB3b3JrZmxvdyB1c2VzIHRvIGF3YWl0IGEgY2hpbGQgd29ya2Zsb3cncyBgcmV0dXJuVmFsdWVgKSwgaXQgYmxvY2tzXG4gICAgLy8gYSBxdWV1ZSB3b3JrZXIgc2xvdCBmb3IgYXMgbG9uZyBhcyB0aGUgY2hpbGQgcnVuIHRha2VzIHRvIGZpbmlzaC5cbiAgICAvLyBXb3JrZXItYmFzZWQgd29ybGRzIGxpa2UgYHdvcmxkLXBvc3RncmVzYCBtdXN0IGJlIHNpemVkIHRvIGNvdmVyIHRoZVxuICAgIC8vIHBlYWsgbnVtYmVyIG9mIHN1Y2ggcG9sbHMgaW4gZmxpZ2h0OyBzZWUgdGhlIGBxdWV1ZUNvbmN1cnJlbmN5YFxuICAgIC8vIGRlZmF1bHQgb24gdGhlIFBvc3RncmVzIHdvcmxkIGFuZCB0aGUgbm90ZXMgaW4gdGhlIGVhZ2VyLXByb2Nlc3NpbmdcbiAgICAvLyBjaGFuZ2Vsb2cgZm9yIGRldGFpbHMuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGNvbnN0IGl0ZXJhdGlvblN0YXJ0ZWRBdCA9IERhdGUubm93KCk7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBNZXRhZGF0YSBvbmx5LCBlaXRoZXIgd2F5OiB0aGUgc3RhdHVzIGlzIGFsbCB0aGlzIGl0ZXJhdGlvbiBuZWVkcyxcbiAgICAgICAgLy8gYW5kIHBheWxvYWQgcmVmcyBhcmUgcmVzb2x2ZWQgb25jZSBiZWxvdywgYWZ0ZXIgYSB0ZXJtaW5hbCBzdGF0dXMgaXNcbiAgICAgICAgLy8gb2JzZXJ2ZWQuXG4gICAgICAgIGNvbnN0IHVzZUxvbmdQb2xsID0gd2FpdEZvclRlcm1pbmFsU3RhdHVzICYmIGxvbmdQb2xscyA8IG1heExvbmdQb2xscztcbiAgICAgICAgaWYgKHVzZUxvbmdQb2xsKSBsb25nUG9sbHMrKztcbiAgICAgICAgY29uc3QgcnVuTWV0YWRhdGEgPSB1c2VMb25nUG9sbFxuICAgICAgICAgID8gYXdhaXQgd2FpdEZvclRlcm1pbmFsU3RhdHVzKHRoaXMucnVuSWQsIHtcbiAgICAgICAgICAgICAgdGltZW91dE1zOiBnZXRSZXR1cm5WYWx1ZVdhaXRUaW1lb3V0TXMoKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZURhdGE6ICdub25lJyxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgOiBhd2FpdCB3b3JsZC5ydW5zLmdldCh0aGlzLnJ1bklkLCB7XG4gICAgICAgICAgICAgIHJlc29sdmVEYXRhOiAnbm9uZScsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICBpZiAocnVuTWV0YWRhdGEuc3RhdHVzID09PSAnY2FuY2VsbGVkJykge1xuICAgICAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bkNhbmNlbGxlZEVycm9yKHRoaXMucnVuSWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKFBBWUxPQURfVEVSTUlOQUxfUlVOX1NUQVRVU0VTLmhhcyhydW5NZXRhZGF0YS5zdGF0dXMpKSB7XG4gICAgICAgICAgLy8gVGhlIHBvbGxpbmcgcmVhZCBhYm92ZSBkZWxpYmVyYXRlbHkgc2tpcHMgaW5wdXQvb3V0cHV0L2Vycm9yIHJlZnMuXG4gICAgICAgICAgLy8gUmVzb2x2ZSBwYXlsb2FkcyBvbmx5IG9uY2UgdGhlIHJ1biByZWFjaGVzIGEgdGVybWluYWwgc3RhdGUuXG4gICAgICAgICAgY29uc3QgcnVuID0gYXdhaXQgd29ybGQucnVucy5nZXQodGhpcy5ydW5JZCwge1xuICAgICAgICAgICAgcmVzb2x2ZURhdGE6ICdhbGwnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLiNyZXNvbHZlVGVybWluYWxSZXR1cm5WYWx1ZShydW4pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUnVuIG5vdCBjb21wbGV0ZWQgeWV0OiBzbGVlcCBhbmQgcG9sbCBhZ2Fpbi5cbiAgICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVuTm90Q29tcGxldGVkRXJyb3IodGhpcy5ydW5JZCwgcnVuTWV0YWRhdGEuc3RhdHVzKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChXb3JrZmxvd1J1bk5vdENvbXBsZXRlZEVycm9yLmlzKGVycm9yKSkge1xuICAgICAgICAgIC8vIFNwYWNlIGNvbnNlY3V0aXZlIG5vbi10ZXJtaW5hbCBvYnNlcnZhdGlvbnMgYXQgbGVhc3Qgb25lIHBvbGxcbiAgICAgICAgICAvLyBpbnRlcnZhbCBhcGFydC4gT24gdGhlIHBsYWluLXBvbGwgcGF0aCB0aGF0IGlzIHRoZSBmYW1pbGlhciBmaXhlZFxuICAgICAgICAgIC8vIHNsZWVwOyBvbiB0aGUgbG9uZy1wb2xsIHBhdGggdGhlIHdhaXQgaGFzIHVzdWFsbHkgYWxyZWFkeVxuICAgICAgICAgIC8vIG91dGxhc3RlZCB0aGUgaW50ZXJ2YWwgYW5kIHRoaXMgaXMgYSBuby1vcCwgYnV0IGl0IGFsc28gbWVhbnMgYVxuICAgICAgICAgIC8vIFdvcmxkIHdob3NlIHdhaXQgcmV0dXJucyBlYXJseSAoYSBiYWNrZW5kIHdpdGggbm8gbG9uZyBwb2xsLCBhXG4gICAgICAgICAgLy8gY2xhbXBlZCBidWRnZXQpIGRlZ3JhZGVzIHRvIGludGVydmFsIHBvbGxpbmcgaW5zdGVhZCBvZiBzcGlubmluZy5cbiAgICAgICAgICBjb25zdCByZW1haW5pbmdJbnRlcnZhbE1zID1cbiAgICAgICAgICAgIGdldFJldHVyblZhbHVlUG9sbEludGVydmFsTXMoKSAtIChEYXRlLm5vdygpIC0gaXRlcmF0aW9uU3RhcnRlZEF0KTtcbiAgICAgICAgICBpZiAocmVtYWluaW5nSW50ZXJ2YWxNcyA+IDApIHtcbiAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PlxuICAgICAgICAgICAgICBzZXRUaW1lb3V0KHJlc29sdmUsIHJlbWFpbmluZ0ludGVydmFsTXMpXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXG4gICAgICAgICAgV29ya2Zsb3dSdW5Ob3RGb3VuZEVycm9yLmlzKGVycm9yKSAmJlxuICAgICAgICAgIG5vdEZvdW5kUmV0cmllcyA8IE5PVF9GT1VORF9NQVhfUkVUUklFU1xuICAgICAgICApIHtcbiAgICAgICAgICBjb25zdCBkZWxheSA9IE5PVF9GT1VORF9SRVRSWV9ERUxBWVNbbm90Rm91bmRSZXRyaWVzXSE7XG4gICAgICAgICAgbm90Rm91bmRSZXRyaWVzKys7XG4gICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgZGVsYXkpKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZXRyaWV2ZXMgYSBgUnVuYCBvYmplY3QgZm9yIGEgZ2l2ZW4gcnVuIElELlxuICpcbiAqIEBwYXJhbSBydW5JZCAtIFRoZSB3b3JrZmxvdyBydW4gSUQgb2J0YWluZWQgZnJvbSB7QGxpbmsgc3RhcnR9LlxuICogQHJldHVybnMgQSBgUnVuYCBvYmplY3QuXG4gKiBAdGhyb3dzIFdvcmtmbG93UnVuTm90Rm91bmRFcnJvciBpZiB0aGUgcnVuIElEIGlzIG5vdCBmb3VuZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJ1bjxUUmVzdWx0PihydW5JZDogc3RyaW5nKTogUnVuPFRSZXN1bHQ+IHtcbiAgcmV0dXJuIG5ldyBSdW4ocnVuSWQpO1xufVxuIl19
|