@workflow/core 5.0.0-beta.5 → 5.0.0-beta.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attribute-changes.d.ts +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 +271 -0
- package/dist/events-consumer.d.ts.map +1 -1
- package/dist/events-consumer.js +646 -42
- package/dist/flushable-stream.d.ts +56 -1
- package/dist/flushable-stream.d.ts.map +1 -1
- package/dist/flushable-stream.js +123 -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 +7 -7
- 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-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 +341 -29
- package/dist/runtime/helpers.d.ts.map +1 -1
- package/dist/runtime/helpers.js +559 -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 +136 -0
- package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -0
- package/dist/runtime/quickjs-entrypoint.js +1686 -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 +205 -5
- package/dist/runtime/step-executor.d.ts.map +1 -1
- package/dist/runtime/step-executor.js +760 -127
- 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 +269 -7
- package/dist/runtime/suspension-handler.d.ts.map +1 -1
- package/dist/runtime/suspension-handler.js +1253 -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 +3741 -490
- 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 +1879 -274
- 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 +61 -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 +72 -9
- 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 +397 -2
- package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
- package/dist/telemetry/semantic-conventions.js +297 -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 +101 -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 +895 -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 +107 -59
- 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 +98 -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
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared shape for finalizing a step whose arguments failed to serialize
|
|
3
|
+
* (used by both the node:vm suspension handler and the QuickJS entrypoint).
|
|
4
|
+
*
|
|
5
|
+
* The world requires a `step_created` before any terminal step event, and
|
|
6
|
+
* the step's real input is precisely what refused to serialize, so the
|
|
7
|
+
* finalization writes a placeholder input. The marker string makes the
|
|
8
|
+
* placeholder distinguishable from a genuine zero-argument step in
|
|
9
|
+
* `workflow inspect steps` and the observability UI: a reader sees
|
|
10
|
+
* "input unavailable" instead of "no arguments".
|
|
11
|
+
*/
|
|
12
|
+
export declare const UNSERIALIZABLE_STEP_INPUT_MARKER = "[input unavailable: step argument serialization failed]";
|
|
13
|
+
/**
|
|
14
|
+
* The placeholder value serialized into the failed step's `step_created`
|
|
15
|
+
* input. Matches the `{ args, closureVars, thisVal }` triple
|
|
16
|
+
* `dehydrateStepArguments` / the QuickJS bootstrap produce for real steps,
|
|
17
|
+
* so every consumer hydrates it uniformly, plus the structural flag the
|
|
18
|
+
* step executor checks before running user code (see
|
|
19
|
+
* {@link isUnserializableStepInputPlaceholder}).
|
|
20
|
+
*/
|
|
21
|
+
export declare function unserializableStepInputPlaceholder(): Record<string, unknown>;
|
|
22
|
+
/**
|
|
23
|
+
* Whether a hydrated step input is the finalization placeholder.
|
|
24
|
+
*
|
|
25
|
+
* Finalization writes `step_created` (placeholder) and `step_failed` as two
|
|
26
|
+
* separate durable writes; a crash or transient failure between them leaves
|
|
27
|
+
* a pending step whose stored input is the placeholder. Redelivery then
|
|
28
|
+
* dispatches that step through normal crash recovery: the executor calls
|
|
29
|
+
* this before running user code and completes the intended failure (a fatal
|
|
30
|
+
* SerializationError → `step_failed`) instead of silently invoking the step
|
|
31
|
+
* body with placeholder arguments.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isUnserializableStepInputPlaceholder(hydratedInput: unknown): boolean;
|
|
34
|
+
//# sourceMappingURL=unserializable-step.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unserializable-step.d.ts","sourceRoot":"","sources":["../../src/runtime/unserializable-step.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gCAAgC,4DACc,CAAC;AAU5D;;;;;;;GAOG;AACH,wBAAgB,kCAAkC,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAO5E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oCAAoC,CAClD,aAAa,EAAE,OAAO,GACrB,OAAO,CAMT"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared shape for finalizing a step whose arguments failed to serialize
|
|
3
|
+
* (used by both the node:vm suspension handler and the QuickJS entrypoint).
|
|
4
|
+
*
|
|
5
|
+
* The world requires a `step_created` before any terminal step event, and
|
|
6
|
+
* the step's real input is precisely what refused to serialize, so the
|
|
7
|
+
* finalization writes a placeholder input. The marker string makes the
|
|
8
|
+
* placeholder distinguishable from a genuine zero-argument step in
|
|
9
|
+
* `workflow inspect steps` and the observability UI: a reader sees
|
|
10
|
+
* "input unavailable" instead of "no arguments".
|
|
11
|
+
*/
|
|
12
|
+
export const UNSERIALIZABLE_STEP_INPUT_MARKER = '[input unavailable: step argument serialization failed]';
|
|
13
|
+
/**
|
|
14
|
+
* Structural discriminator on the placeholder's top level. The
|
|
15
|
+
* `{ args, closureVars, thisVal }` triple is built by the SDK (user code
|
|
16
|
+
* never controls its top-level keys), so this flag cannot false-positive on
|
|
17
|
+
* a legitimate input, unlike the display marker inside `args`.
|
|
18
|
+
*/
|
|
19
|
+
const UNSERIALIZABLE_FLAG = '__workflowUnserializableStepInput';
|
|
20
|
+
/**
|
|
21
|
+
* The placeholder value serialized into the failed step's `step_created`
|
|
22
|
+
* input. Matches the `{ args, closureVars, thisVal }` triple
|
|
23
|
+
* `dehydrateStepArguments` / the QuickJS bootstrap produce for real steps,
|
|
24
|
+
* so every consumer hydrates it uniformly, plus the structural flag the
|
|
25
|
+
* step executor checks before running user code (see
|
|
26
|
+
* {@link isUnserializableStepInputPlaceholder}).
|
|
27
|
+
*/
|
|
28
|
+
export function unserializableStepInputPlaceholder() {
|
|
29
|
+
return {
|
|
30
|
+
args: [UNSERIALIZABLE_STEP_INPUT_MARKER],
|
|
31
|
+
closureVars: [],
|
|
32
|
+
thisVal: undefined,
|
|
33
|
+
[UNSERIALIZABLE_FLAG]: true,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Whether a hydrated step input is the finalization placeholder.
|
|
38
|
+
*
|
|
39
|
+
* Finalization writes `step_created` (placeholder) and `step_failed` as two
|
|
40
|
+
* separate durable writes; a crash or transient failure between them leaves
|
|
41
|
+
* a pending step whose stored input is the placeholder. Redelivery then
|
|
42
|
+
* dispatches that step through normal crash recovery: the executor calls
|
|
43
|
+
* this before running user code and completes the intended failure (a fatal
|
|
44
|
+
* SerializationError → `step_failed`) instead of silently invoking the step
|
|
45
|
+
* body with placeholder arguments.
|
|
46
|
+
*/
|
|
47
|
+
export function isUnserializableStepInputPlaceholder(hydratedInput) {
|
|
48
|
+
return (typeof hydratedInput === 'object' &&
|
|
49
|
+
hydratedInput !== null &&
|
|
50
|
+
hydratedInput[UNSERIALIZABLE_FLAG] === true);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5zZXJpYWxpemFibGUtc3RlcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW50aW1lL3Vuc2VyaWFsaXphYmxlLXN0ZXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sQ0FBQyxNQUFNLGdDQUFnQyxHQUMzQyx5REFBeUQsQ0FBQztBQUU1RDs7Ozs7R0FLRztBQUNILE1BQU0sbUJBQW1CLEdBQUcsbUNBQW1DLENBQUM7QUFFaEU7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxrQ0FBa0M7SUFDaEQsT0FBTztRQUNMLElBQUksRUFBRSxDQUFDLGdDQUFnQyxDQUFDO1FBQ3hDLFdBQVcsRUFBRSxFQUFFO1FBQ2YsT0FBTyxFQUFFLFNBQVM7UUFDbEIsQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLElBQUk7S0FDNUIsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxVQUFVLG9DQUFvQyxDQUNsRCxhQUFzQjtJQUV0QixPQUFPLENBQ0wsT0FBTyxhQUFhLEtBQUssUUFBUTtRQUNqQyxhQUFhLEtBQUssSUFBSTtRQUNyQixhQUF5QyxDQUFDLG1CQUFtQixDQUFDLEtBQUssSUFBSSxDQUN6RSxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU2hhcmVkIHNoYXBlIGZvciBmaW5hbGl6aW5nIGEgc3RlcCB3aG9zZSBhcmd1bWVudHMgZmFpbGVkIHRvIHNlcmlhbGl6ZVxuICogKHVzZWQgYnkgYm90aCB0aGUgbm9kZTp2bSBzdXNwZW5zaW9uIGhhbmRsZXIgYW5kIHRoZSBRdWlja0pTIGVudHJ5cG9pbnQpLlxuICpcbiAqIFRoZSB3b3JsZCByZXF1aXJlcyBhIGBzdGVwX2NyZWF0ZWRgIGJlZm9yZSBhbnkgdGVybWluYWwgc3RlcCBldmVudCwgYW5kXG4gKiB0aGUgc3RlcCdzIHJlYWwgaW5wdXQgaXMgcHJlY2lzZWx5IHdoYXQgcmVmdXNlZCB0byBzZXJpYWxpemUsIHNvIHRoZVxuICogZmluYWxpemF0aW9uIHdyaXRlcyBhIHBsYWNlaG9sZGVyIGlucHV0LiBUaGUgbWFya2VyIHN0cmluZyBtYWtlcyB0aGVcbiAqIHBsYWNlaG9sZGVyIGRpc3Rpbmd1aXNoYWJsZSBmcm9tIGEgZ2VudWluZSB6ZXJvLWFyZ3VtZW50IHN0ZXAgaW5cbiAqIGB3b3JrZmxvdyBpbnNwZWN0IHN0ZXBzYCBhbmQgdGhlIG9ic2VydmFiaWxpdHkgVUk6IGEgcmVhZGVyIHNlZXNcbiAqIFwiaW5wdXQgdW5hdmFpbGFibGVcIiBpbnN0ZWFkIG9mIFwibm8gYXJndW1lbnRzXCIuXG4gKi9cbmV4cG9ydCBjb25zdCBVTlNFUklBTElaQUJMRV9TVEVQX0lOUFVUX01BUktFUiA9XG4gICdbaW5wdXQgdW5hdmFpbGFibGU6IHN0ZXAgYXJndW1lbnQgc2VyaWFsaXphdGlvbiBmYWlsZWRdJztcblxuLyoqXG4gKiBTdHJ1Y3R1cmFsIGRpc2NyaW1pbmF0b3Igb24gdGhlIHBsYWNlaG9sZGVyJ3MgdG9wIGxldmVsLiBUaGVcbiAqIGB7IGFyZ3MsIGNsb3N1cmVWYXJzLCB0aGlzVmFsIH1gIHRyaXBsZSBpcyBidWlsdCBieSB0aGUgU0RLICh1c2VyIGNvZGVcbiAqIG5ldmVyIGNvbnRyb2xzIGl0cyB0b3AtbGV2ZWwga2V5cyksIHNvIHRoaXMgZmxhZyBjYW5ub3QgZmFsc2UtcG9zaXRpdmUgb25cbiAqIGEgbGVnaXRpbWF0ZSBpbnB1dCwgdW5saWtlIHRoZSBkaXNwbGF5IG1hcmtlciBpbnNpZGUgYGFyZ3NgLlxuICovXG5jb25zdCBVTlNFUklBTElaQUJMRV9GTEFHID0gJ19fd29ya2Zsb3dVbnNlcmlhbGl6YWJsZVN0ZXBJbnB1dCc7XG5cbi8qKlxuICogVGhlIHBsYWNlaG9sZGVyIHZhbHVlIHNlcmlhbGl6ZWQgaW50byB0aGUgZmFpbGVkIHN0ZXAncyBgc3RlcF9jcmVhdGVkYFxuICogaW5wdXQuIE1hdGNoZXMgdGhlIGB7IGFyZ3MsIGNsb3N1cmVWYXJzLCB0aGlzVmFsIH1gIHRyaXBsZVxuICogYGRlaHlkcmF0ZVN0ZXBBcmd1bWVudHNgIC8gdGhlIFF1aWNrSlMgYm9vdHN0cmFwIHByb2R1Y2UgZm9yIHJlYWwgc3RlcHMsXG4gKiBzbyBldmVyeSBjb25zdW1lciBoeWRyYXRlcyBpdCB1bmlmb3JtbHksIHBsdXMgdGhlIHN0cnVjdHVyYWwgZmxhZyB0aGVcbiAqIHN0ZXAgZXhlY3V0b3IgY2hlY2tzIGJlZm9yZSBydW5uaW5nIHVzZXIgY29kZSAoc2VlXG4gKiB7QGxpbmsgaXNVbnNlcmlhbGl6YWJsZVN0ZXBJbnB1dFBsYWNlaG9sZGVyfSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1bnNlcmlhbGl6YWJsZVN0ZXBJbnB1dFBsYWNlaG9sZGVyKCk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgcmV0dXJuIHtcbiAgICBhcmdzOiBbVU5TRVJJQUxJWkFCTEVfU1RFUF9JTlBVVF9NQVJLRVJdLFxuICAgIGNsb3N1cmVWYXJzOiBbXSxcbiAgICB0aGlzVmFsOiB1bmRlZmluZWQsXG4gICAgW1VOU0VSSUFMSVpBQkxFX0ZMQUddOiB0cnVlLFxuICB9O1xufVxuXG4vKipcbiAqIFdoZXRoZXIgYSBoeWRyYXRlZCBzdGVwIGlucHV0IGlzIHRoZSBmaW5hbGl6YXRpb24gcGxhY2Vob2xkZXIuXG4gKlxuICogRmluYWxpemF0aW9uIHdyaXRlcyBgc3RlcF9jcmVhdGVkYCAocGxhY2Vob2xkZXIpIGFuZCBgc3RlcF9mYWlsZWRgIGFzIHR3b1xuICogc2VwYXJhdGUgZHVyYWJsZSB3cml0ZXM7IGEgY3Jhc2ggb3IgdHJhbnNpZW50IGZhaWx1cmUgYmV0d2VlbiB0aGVtIGxlYXZlc1xuICogYSBwZW5kaW5nIHN0ZXAgd2hvc2Ugc3RvcmVkIGlucHV0IGlzIHRoZSBwbGFjZWhvbGRlci4gUmVkZWxpdmVyeSB0aGVuXG4gKiBkaXNwYXRjaGVzIHRoYXQgc3RlcCB0aHJvdWdoIG5vcm1hbCBjcmFzaCByZWNvdmVyeTogdGhlIGV4ZWN1dG9yIGNhbGxzXG4gKiB0aGlzIGJlZm9yZSBydW5uaW5nIHVzZXIgY29kZSBhbmQgY29tcGxldGVzIHRoZSBpbnRlbmRlZCBmYWlsdXJlIChhIGZhdGFsXG4gKiBTZXJpYWxpemF0aW9uRXJyb3Ig4oaSIGBzdGVwX2ZhaWxlZGApIGluc3RlYWQgb2Ygc2lsZW50bHkgaW52b2tpbmcgdGhlIHN0ZXBcbiAqIGJvZHkgd2l0aCBwbGFjZWhvbGRlciBhcmd1bWVudHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1Vuc2VyaWFsaXphYmxlU3RlcElucHV0UGxhY2Vob2xkZXIoXG4gIGh5ZHJhdGVkSW5wdXQ6IHVua25vd25cbik6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIHR5cGVvZiBoeWRyYXRlZElucHV0ID09PSAnb2JqZWN0JyAmJlxuICAgIGh5ZHJhdGVkSW5wdXQgIT09IG51bGwgJiZcbiAgICAoaHlkcmF0ZWRJbnB1dCBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilbVU5TRVJJQUxJWkFCTEVfRkxBR10gPT09IHRydWVcbiAgKTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VM engine selection for workflow execution.
|
|
3
|
+
*
|
|
4
|
+
* The Node.js `node:vm` engine is the default. The QuickJS WASM engine is
|
|
5
|
+
* opt-in via the `WORKFLOW_VM` env var or `executionContext.workflowVm`.
|
|
6
|
+
*
|
|
7
|
+
* Both engines implement the same event-replay execution model: on every
|
|
8
|
+
* workflow handler invocation the workflow function is re-executed from the
|
|
9
|
+
* top and the recorded event log resolves awaited primitives. The QuickJS
|
|
10
|
+
* engine runs the workflow code in a QuickJS WASM VM (via quickjs-wasi)
|
|
11
|
+
* instead of a `node:vm` context, which makes it usable on platforms that
|
|
12
|
+
* do not implement `node:vm` (e.g. Cloudflare Workers) and is the
|
|
13
|
+
* foundation for VM-memory snapshotting.
|
|
14
|
+
*/
|
|
15
|
+
import type { WorkflowRun } from '@workflow/world';
|
|
16
|
+
/**
|
|
17
|
+
* Known workflow VM engines. Any other `WORKFLOW_VM` value is treated as
|
|
18
|
+
* a misconfiguration and rejected at startup.
|
|
19
|
+
*/
|
|
20
|
+
export declare const WORKFLOW_VMS: readonly ["node", "quickjs"];
|
|
21
|
+
export type WorkflowVmMode = (typeof WORKFLOW_VMS)[number];
|
|
22
|
+
/**
|
|
23
|
+
* Read and validate the `WORKFLOW_VM` env var.
|
|
24
|
+
*
|
|
25
|
+
* Returns the configured engine, or `undefined` if unset/empty.
|
|
26
|
+
* Throws {@link WorkflowRuntimeError} if the value is set but not one of
|
|
27
|
+
* the known engines, since catching misconfiguration early is better than
|
|
28
|
+
* silently falling back to the default.
|
|
29
|
+
*/
|
|
30
|
+
export declare function getWorkflowVmFromEnv(env?: NodeJS.ProcessEnv): WorkflowVmMode | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Whether to use the QuickJS WASM VM for a given run.
|
|
33
|
+
*
|
|
34
|
+
* The run's `executionContext.workflowVm` (stamped by the SDK at `start()`
|
|
35
|
+
* when `WORKFLOW_VM` is set on the client) takes precedence so a run keeps
|
|
36
|
+
* executing on the engine it started on. When the run doesn't specify an
|
|
37
|
+
* engine, the `WORKFLOW_VM` env var on the workflow handler decides.
|
|
38
|
+
* The default is the `node:vm` engine.
|
|
39
|
+
*
|
|
40
|
+
* Throws if `WORKFLOW_VM` or `executionContext.workflowVm` is set to an
|
|
41
|
+
* unknown value.
|
|
42
|
+
*/
|
|
43
|
+
export declare function useQuickJSVm(workflowRun: Pick<WorkflowRun, 'executionContext'>): boolean;
|
|
44
|
+
//# sourceMappingURL=vm-mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vm-mode.d.ts","sourceRoot":"","sources":["../../src/runtime/vm-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD;;;GAGG;AACH,eAAO,MAAM,YAAY,8BAA+B,CAAC;AAEzD,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,cAAc,GAAG,SAAS,CAU5B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,GACjD,OAAO,CAcT"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VM engine selection for workflow execution.
|
|
3
|
+
*
|
|
4
|
+
* The Node.js `node:vm` engine is the default. The QuickJS WASM engine is
|
|
5
|
+
* opt-in via the `WORKFLOW_VM` env var or `executionContext.workflowVm`.
|
|
6
|
+
*
|
|
7
|
+
* Both engines implement the same event-replay execution model: on every
|
|
8
|
+
* workflow handler invocation the workflow function is re-executed from the
|
|
9
|
+
* top and the recorded event log resolves awaited primitives. The QuickJS
|
|
10
|
+
* engine runs the workflow code in a QuickJS WASM VM (via quickjs-wasi)
|
|
11
|
+
* instead of a `node:vm` context, which makes it usable on platforms that
|
|
12
|
+
* do not implement `node:vm` (e.g. Cloudflare Workers) and is the
|
|
13
|
+
* foundation for VM-memory snapshotting.
|
|
14
|
+
*/
|
|
15
|
+
import { WorkflowRuntimeError } from '@workflow/errors';
|
|
16
|
+
/**
|
|
17
|
+
* Known workflow VM engines. Any other `WORKFLOW_VM` value is treated as
|
|
18
|
+
* a misconfiguration and rejected at startup.
|
|
19
|
+
*/
|
|
20
|
+
export const WORKFLOW_VMS = ['node', 'quickjs'];
|
|
21
|
+
/**
|
|
22
|
+
* Read and validate the `WORKFLOW_VM` env var.
|
|
23
|
+
*
|
|
24
|
+
* Returns the configured engine, or `undefined` if unset/empty.
|
|
25
|
+
* Throws {@link WorkflowRuntimeError} if the value is set but not one of
|
|
26
|
+
* the known engines, since catching misconfiguration early is better than
|
|
27
|
+
* silently falling back to the default.
|
|
28
|
+
*/
|
|
29
|
+
export function getWorkflowVmFromEnv(env = process.env) {
|
|
30
|
+
const raw = env.WORKFLOW_VM;
|
|
31
|
+
if (raw === undefined || raw === '')
|
|
32
|
+
return undefined;
|
|
33
|
+
if (WORKFLOW_VMS.includes(raw)) {
|
|
34
|
+
return raw;
|
|
35
|
+
}
|
|
36
|
+
throw new WorkflowRuntimeError(`Invalid WORKFLOW_VM value: "${raw}". ` +
|
|
37
|
+
`Expected one of: ${WORKFLOW_VMS.join(', ')}.`);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Whether to use the QuickJS WASM VM for a given run.
|
|
41
|
+
*
|
|
42
|
+
* The run's `executionContext.workflowVm` (stamped by the SDK at `start()`
|
|
43
|
+
* when `WORKFLOW_VM` is set on the client) takes precedence so a run keeps
|
|
44
|
+
* executing on the engine it started on. When the run doesn't specify an
|
|
45
|
+
* engine, the `WORKFLOW_VM` env var on the workflow handler decides.
|
|
46
|
+
* The default is the `node:vm` engine.
|
|
47
|
+
*
|
|
48
|
+
* Throws if `WORKFLOW_VM` or `executionContext.workflowVm` is set to an
|
|
49
|
+
* unknown value.
|
|
50
|
+
*/
|
|
51
|
+
export function useQuickJSVm(workflowRun) {
|
|
52
|
+
const vmFromRun = workflowRun.executionContext?.workflowVm;
|
|
53
|
+
if (vmFromRun !== undefined) {
|
|
54
|
+
if (!WORKFLOW_VMS.includes(vmFromRun)) {
|
|
55
|
+
throw new WorkflowRuntimeError(`Invalid executionContext.workflowVm value: "${vmFromRun}". ` +
|
|
56
|
+
`Expected one of: ${WORKFLOW_VMS.join(', ')}.`);
|
|
57
|
+
}
|
|
58
|
+
return vmFromRun === 'quickjs';
|
|
59
|
+
}
|
|
60
|
+
return getWorkflowVmFromEnv() === 'quickjs';
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm0tbW9kZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW50aW1lL3ZtLW1vZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUVILE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBR3hEOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQVUsQ0FBQztBQUl6RDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUNsQyxNQUF5QixPQUFPLENBQUMsR0FBRztJQUVwQyxNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsV0FBVyxDQUFDO0lBQzVCLElBQUksR0FBRyxLQUFLLFNBQVMsSUFBSSxHQUFHLEtBQUssRUFBRTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQ3RELElBQUssWUFBa0MsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN0RCxPQUFPLEdBQXFCLENBQUM7SUFDL0IsQ0FBQztJQUNELE1BQU0sSUFBSSxvQkFBb0IsQ0FDNUIsK0JBQStCLEdBQUcsS0FBSztRQUNyQyxvQkFBb0IsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUNqRCxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxVQUFVLFlBQVksQ0FDMUIsV0FBa0Q7SUFFbEQsTUFBTSxTQUFTLEdBQ2IsV0FBVyxDQUFDLGdCQUNiLEVBQUUsVUFBVSxDQUFDO0lBQ2QsSUFBSSxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFFLFlBQWtDLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDN0QsTUFBTSxJQUFJLG9CQUFvQixDQUM1QiwrQ0FBK0MsU0FBUyxLQUFLO2dCQUMzRCxvQkFBb0IsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUNqRCxDQUFDO1FBQ0osQ0FBQztRQUNELE9BQU8sU0FBUyxLQUFLLFNBQVMsQ0FBQztJQUNqQyxDQUFDO0lBQ0QsT0FBTyxvQkFBb0IsRUFBRSxLQUFLLFNBQVMsQ0FBQztBQUM5QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBWTSBlbmdpbmUgc2VsZWN0aW9uIGZvciB3b3JrZmxvdyBleGVjdXRpb24uXG4gKlxuICogVGhlIE5vZGUuanMgYG5vZGU6dm1gIGVuZ2luZSBpcyB0aGUgZGVmYXVsdC4gVGhlIFF1aWNrSlMgV0FTTSBlbmdpbmUgaXNcbiAqIG9wdC1pbiB2aWEgdGhlIGBXT1JLRkxPV19WTWAgZW52IHZhciBvciBgZXhlY3V0aW9uQ29udGV4dC53b3JrZmxvd1ZtYC5cbiAqXG4gKiBCb3RoIGVuZ2luZXMgaW1wbGVtZW50IHRoZSBzYW1lIGV2ZW50LXJlcGxheSBleGVjdXRpb24gbW9kZWw6IG9uIGV2ZXJ5XG4gKiB3b3JrZmxvdyBoYW5kbGVyIGludm9jYXRpb24gdGhlIHdvcmtmbG93IGZ1bmN0aW9uIGlzIHJlLWV4ZWN1dGVkIGZyb20gdGhlXG4gKiB0b3AgYW5kIHRoZSByZWNvcmRlZCBldmVudCBsb2cgcmVzb2x2ZXMgYXdhaXRlZCBwcmltaXRpdmVzLiBUaGUgUXVpY2tKU1xuICogZW5naW5lIHJ1bnMgdGhlIHdvcmtmbG93IGNvZGUgaW4gYSBRdWlja0pTIFdBU00gVk0gKHZpYSBxdWlja2pzLXdhc2kpXG4gKiBpbnN0ZWFkIG9mIGEgYG5vZGU6dm1gIGNvbnRleHQsIHdoaWNoIG1ha2VzIGl0IHVzYWJsZSBvbiBwbGF0Zm9ybXMgdGhhdFxuICogZG8gbm90IGltcGxlbWVudCBgbm9kZTp2bWAgKGUuZy4gQ2xvdWRmbGFyZSBXb3JrZXJzKSBhbmQgaXMgdGhlXG4gKiBmb3VuZGF0aW9uIGZvciBWTS1tZW1vcnkgc25hcHNob3R0aW5nLlxuICovXG5cbmltcG9ydCB7IFdvcmtmbG93UnVudGltZUVycm9yIH0gZnJvbSAnQHdvcmtmbG93L2Vycm9ycyc7XG5pbXBvcnQgdHlwZSB7IFdvcmtmbG93UnVuIH0gZnJvbSAnQHdvcmtmbG93L3dvcmxkJztcblxuLyoqXG4gKiBLbm93biB3b3JrZmxvdyBWTSBlbmdpbmVzLiBBbnkgb3RoZXIgYFdPUktGTE9XX1ZNYCB2YWx1ZSBpcyB0cmVhdGVkIGFzXG4gKiBhIG1pc2NvbmZpZ3VyYXRpb24gYW5kIHJlamVjdGVkIGF0IHN0YXJ0dXAuXG4gKi9cbmV4cG9ydCBjb25zdCBXT1JLRkxPV19WTVMgPSBbJ25vZGUnLCAncXVpY2tqcyddIGFzIGNvbnN0O1xuXG5leHBvcnQgdHlwZSBXb3JrZmxvd1ZtTW9kZSA9ICh0eXBlb2YgV09SS0ZMT1dfVk1TKVtudW1iZXJdO1xuXG4vKipcbiAqIFJlYWQgYW5kIHZhbGlkYXRlIHRoZSBgV09SS0ZMT1dfVk1gIGVudiB2YXIuXG4gKlxuICogUmV0dXJucyB0aGUgY29uZmlndXJlZCBlbmdpbmUsIG9yIGB1bmRlZmluZWRgIGlmIHVuc2V0L2VtcHR5LlxuICogVGhyb3dzIHtAbGluayBXb3JrZmxvd1J1bnRpbWVFcnJvcn0gaWYgdGhlIHZhbHVlIGlzIHNldCBidXQgbm90IG9uZSBvZlxuICogdGhlIGtub3duIGVuZ2luZXMsIHNpbmNlIGNhdGNoaW5nIG1pc2NvbmZpZ3VyYXRpb24gZWFybHkgaXMgYmV0dGVyIHRoYW5cbiAqIHNpbGVudGx5IGZhbGxpbmcgYmFjayB0byB0aGUgZGVmYXVsdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmtmbG93Vm1Gcm9tRW52KFxuICBlbnY6IE5vZGVKUy5Qcm9jZXNzRW52ID0gcHJvY2Vzcy5lbnZcbik6IFdvcmtmbG93Vm1Nb2RlIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcmF3ID0gZW52LldPUktGTE9XX1ZNO1xuICBpZiAocmF3ID09PSB1bmRlZmluZWQgfHwgcmF3ID09PSAnJykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgaWYgKChXT1JLRkxPV19WTVMgYXMgcmVhZG9ubHkgc3RyaW5nW10pLmluY2x1ZGVzKHJhdykpIHtcbiAgICByZXR1cm4gcmF3IGFzIFdvcmtmbG93Vm1Nb2RlO1xuICB9XG4gIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcihcbiAgICBgSW52YWxpZCBXT1JLRkxPV19WTSB2YWx1ZTogXCIke3Jhd31cIi4gYCArXG4gICAgICBgRXhwZWN0ZWQgb25lIG9mOiAke1dPUktGTE9XX1ZNUy5qb2luKCcsICcpfS5gXG4gICk7XG59XG5cbi8qKlxuICogV2hldGhlciB0byB1c2UgdGhlIFF1aWNrSlMgV0FTTSBWTSBmb3IgYSBnaXZlbiBydW4uXG4gKlxuICogVGhlIHJ1bidzIGBleGVjdXRpb25Db250ZXh0LndvcmtmbG93Vm1gIChzdGFtcGVkIGJ5IHRoZSBTREsgYXQgYHN0YXJ0KClgXG4gKiB3aGVuIGBXT1JLRkxPV19WTWAgaXMgc2V0IG9uIHRoZSBjbGllbnQpIHRha2VzIHByZWNlZGVuY2Ugc28gYSBydW4ga2VlcHNcbiAqIGV4ZWN1dGluZyBvbiB0aGUgZW5naW5lIGl0IHN0YXJ0ZWQgb24uIFdoZW4gdGhlIHJ1biBkb2Vzbid0IHNwZWNpZnkgYW5cbiAqIGVuZ2luZSwgdGhlIGBXT1JLRkxPV19WTWAgZW52IHZhciBvbiB0aGUgd29ya2Zsb3cgaGFuZGxlciBkZWNpZGVzLlxuICogVGhlIGRlZmF1bHQgaXMgdGhlIGBub2RlOnZtYCBlbmdpbmUuXG4gKlxuICogVGhyb3dzIGlmIGBXT1JLRkxPV19WTWAgb3IgYGV4ZWN1dGlvbkNvbnRleHQud29ya2Zsb3dWbWAgaXMgc2V0IHRvIGFuXG4gKiB1bmtub3duIHZhbHVlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlUXVpY2tKU1ZtKFxuICB3b3JrZmxvd1J1bjogUGljazxXb3JrZmxvd1J1biwgJ2V4ZWN1dGlvbkNvbnRleHQnPlxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IHZtRnJvbVJ1biA9IChcbiAgICB3b3JrZmxvd1J1bi5leGVjdXRpb25Db250ZXh0IGFzIHsgd29ya2Zsb3dWbT86IHN0cmluZyB9IHwgdW5kZWZpbmVkXG4gICk/LndvcmtmbG93Vm07XG4gIGlmICh2bUZyb21SdW4gIT09IHVuZGVmaW5lZCkge1xuICAgIGlmICghKFdPUktGTE9XX1ZNUyBhcyByZWFkb25seSBzdHJpbmdbXSkuaW5jbHVkZXModm1Gcm9tUnVuKSkge1xuICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKFxuICAgICAgICBgSW52YWxpZCBleGVjdXRpb25Db250ZXh0LndvcmtmbG93Vm0gdmFsdWU6IFwiJHt2bUZyb21SdW59XCIuIGAgK1xuICAgICAgICAgIGBFeHBlY3RlZCBvbmUgb2Y6ICR7V09SS0ZMT1dfVk1TLmpvaW4oJywgJyl9LmBcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB2bUZyb21SdW4gPT09ICdxdWlja2pzJztcbiAgfVxuICByZXR1cm4gZ2V0V29ya2Zsb3dWbUZyb21FbnYoKSA9PT0gJ3F1aWNranMnO1xufVxuIl19
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-generated by scripts/build-vm-serde-bundle.js
|
|
3
|
+
* Do not edit manually.
|
|
4
|
+
*
|
|
5
|
+
* This is the VM serialization bundle — a self-contained IIFE that sets up
|
|
6
|
+
* the serialize/deserialize functions inside the QuickJS WASM VM. It
|
|
7
|
+
* includes devalue and all workflow-mode reducers/revivers. (TextEncoder,
|
|
8
|
+
* TextDecoder, and Headers are provided by quickjs-wasi's native C
|
|
9
|
+
* extensions — no JS polyfills are bundled.)
|
|
10
|
+
*
|
|
11
|
+
* Size: 25.6 KB minified
|
|
12
|
+
*/
|
|
13
|
+
export declare const VM_SERDE_BUNDLE: string;
|
|
14
|
+
//# sourceMappingURL=vm-serde-bundle.generated.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vm-serde-bundle.generated.d.ts","sourceRoot":"","sources":["../../src/runtime/vm-serde-bundle.generated.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,EAAE,MAE7B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-generated by scripts/build-vm-serde-bundle.js
|
|
3
|
+
* Do not edit manually.
|
|
4
|
+
*
|
|
5
|
+
* This is the VM serialization bundle — a self-contained IIFE that sets up
|
|
6
|
+
* the serialize/deserialize functions inside the QuickJS WASM VM. It
|
|
7
|
+
* includes devalue and all workflow-mode reducers/revivers. (TextEncoder,
|
|
8
|
+
* TextDecoder, and Headers are provided by quickjs-wasi's native C
|
|
9
|
+
* extensions — no JS polyfills are bundled.)
|
|
10
|
+
*
|
|
11
|
+
* Size: 25.6 KB minified
|
|
12
|
+
*/
|
|
13
|
+
export const VM_SERDE_BUNDLE = `"use strict";(()=>{var D="0123456789ABCDEFGHJKMNPQRSTVWXYZ";var w;(function(r){r.Base32IncorrectEncoding="B32_ENC_INVALID",r.DecodeTimeInvalidCharacter="DEC_TIME_CHAR",r.DecodeTimeValueMalformed="DEC_TIME_MALFORMED",r.EncodeTimeNegative="ENC_TIME_NEG",r.EncodeTimeSizeExceeded="ENC_TIME_SIZE_EXCEED",r.EncodeTimeValueMalformed="ENC_TIME_MALFORMED",r.PRNGDetectFailure="PRNG_DETECT",r.ULIDInvalid="ULID_INVALID",r.Unexpected="UNEXPECTED",r.UUIDInvalid="UUID_INVALID"})(w||(w={}));var O=class extends Error{constructor(e,t){super(\`\${t} (\${e})\`),this.name="ULIDError",this.code=e}};function Fr(r){let e=Math.floor(r()*32)%32;return D.charAt(e)}function sr(r,e,t){return e>r.length-1?r:r.substr(0,e)+t+r.substr(e+1)}function Wr(r){let e,t=r.length,n,o,s=r,p=31;for(;!e&&t-->=0;){if(n=s[t],o=D.indexOf(n),o===-1)throw new O(w.Base32IncorrectEncoding,"Incorrectly encoded string");if(o===p){s=sr(s,t,D[0]);continue}e=sr(s,t,D[o+1])}if(typeof e=="string")return e;throw new O(w.Base32IncorrectEncoding,"Failed incrementing string")}function Cr(r){let e=Pr(),t=e&&(e.crypto||e.msCrypto)||null;if(typeof t?.getRandomValues=="function")return()=>{let n=new Uint8Array(1);return t.getRandomValues(n),n[0]/255};if(typeof t?.randomBytes=="function")return()=>t.randomBytes(1).readUInt8()/255;throw new O(w.PRNGDetectFailure,"Failed to find a reliable PRNG")}function Pr(){return jr()?self:typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:null}function Br(r,e){let t="";for(;r>0;r--)t=Fr(e)+t;return t}function ar(r,e=10){if(isNaN(r))throw new O(w.EncodeTimeValueMalformed,\`Time must be a number: \${r}\`);if(r>0xffffffffffff)throw new O(w.EncodeTimeSizeExceeded,\`Cannot encode a time larger than \${0xffffffffffff}: \${r}\`);if(r<0)throw new O(w.EncodeTimeNegative,\`Time must be positive: \${r}\`);if(Number.isInteger(r)===!1)throw new O(w.EncodeTimeValueMalformed,\`Time must be an integer: \${r}\`);let t,n="";for(let o=e;o>0;o--)t=r%32,n=D.charAt(t)+n,r=(r-t)/32;return n}function jr(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}function ir(r){let e=r||Cr(),t=0,n;return function(s){let p=!s||isNaN(s)?Date.now():s;if(p<=t){let c=n=Wr(n);return ar(t,10)+c}t=p;let g=n=Br(16,e);return ar(p,10)+g}}var S=class extends Error{constructor(e,t,n,o){super(e),this.name="DevalueError",this.path=t.join(""),this.value=n,this.root=o}};var Kr=Object.getOwnPropertyNames(Object.prototype).sort().join("\\0");function fr(r){let e=Object.getPrototypeOf(r);return e===Object.prototype||e===null||Object.getPrototypeOf(e)===null||Object.getOwnPropertyNames(e).sort().join("\\0")===Kr}function yr(r){return Object.prototype.toString.call(r).slice(8,-1)}function Vr(r){switch(r){case'"':return'\\\\"';case"<":return"\\\\u003C";case"\\\\":return"\\\\\\\\";case\`
|
|
14
|
+
\`:return"\\\\n";case"\\r":return"\\\\r";case" ":return"\\\\t";case"\\b":return"\\\\b";case"\\f":return"\\\\f";case"\\u2028":return"\\\\u2028";case"\\u2029":return"\\\\u2029";default:return r<" "?\`\\\\u\${r.charCodeAt(0).toString(16).padStart(4,"0")}\`:""}}function I(r){let e="",t=0,n=r.length;for(let o=0;o<n;o+=1){let s=r[o],p=Vr(s);p&&(e+=r.slice(t,o)+p,t=o+1)}return\`"\${t===0?r:e+r.slice(t)}"\`}function lr(r){return Object.getOwnPropertySymbols(r).filter(e=>Object.getOwnPropertyDescriptor(r,e).enumerable)}var zr=/^[a-zA-Z_$][a-zA-Z_$0-9]*$/;function Z(r){return zr.test(r)?"."+r:"["+JSON.stringify(r)+"]"}function Y(r){return!(!Number.isInteger(r)||r<0||r>4294967294)}function ur(r){return!(!Number.isInteger(r)||r<0||r>4294967295)}function $r(r){if(r.length===0||r.length>1&&r.charCodeAt(0)===48)return!1;for(let e=0;e<r.length;e++){let t=r.charCodeAt(e);if(t<48||t>57)return!1}return Y(+r)}function Zr(r){for(var e=r.length-1;e>=0&&!$r(r[e]);e--);return e+1}function pr(r){let e=Object.keys(r);return e.length=Zr(e),e}function Yr(r){return new Uint8Array(r).toBase64()}function Gr(r){return Uint8Array.fromBase64(r).buffer}function Hr(r){return Buffer.from(r).toString("base64")}function Xr(r){return Uint8Array.from(Buffer.from(r,"base64")).buffer}function qr(r){let e=new Uint8Array(r),t="",n=32768;for(let o=0;o<e.length;o+=n){let s=e.subarray(o,o+n);t+=String.fromCharCode.apply(null,s)}return btoa(t)}function Jr(r){let e=atob(r),t=e.length,n=new Uint8Array(t);for(let o=0;o<t;o++)n[o]=e.charCodeAt(o);return n.buffer}var gr=typeof Uint8Array.fromBase64=="function",dr=typeof process=="object"&&process.versions?.node!==void 0,mr=gr?Yr:dr?Hr:qr,br=gr?Gr:dr?Xr:Jr;function W(r,e){if(!e)return r;let t={};for(let n of Object.keys(r))t[n]=e[n]??r[n];return t}var Qr=Object.freeze({kind:"not-plain"}),vr=Object.freeze({kind:"symbol-keys"}),re={identify:r=>r,typeOf:r=>r===null?"null":typeof r,toPrimitive:r=>r,tagOf:r=>yr(r),isThenable:r=>typeof r.then=="function",toPromise:r=>Promise.resolve(r),unbox:r=>r.valueOf(),toISOString:r=>isNaN(r.getDate())?"":r.toISOString(),toStringValue:r=>r.toString(),regExpInfo:r=>({source:r.source,flags:r.flags}),valuesOf:r=>r,entriesOf:r=>r,viewInfo:r=>({buffer:r.buffer,byteOffset:r.byteOffset,byteLength:r.byteLength,length:r.length,bufferByteLength:r.buffer.byteLength}),toArrayBuffer:r=>r,lengthOf:r=>r.length,hasOwn:(r,e)=>Object.hasOwn(r,e),indicesOf:r=>pr(r),shapeOf:r=>fr(r)?lr(r).length>0?vr:{kind:Object.getPrototypeOf(r)===null?"null-proto":"plain",keys:Object.keys(r)}:Qr,get:(r,e)=>r[e]},Er=Object.freeze(re),ee={fromPrimitive:r=>r,fromISOString:r=>new Date(r),fromStringValue:(r,e)=>r==="URL"?new URL(e):r==="URLSearchParams"?new URLSearchParams(e):Temporal[r.slice(9)].from(e),fromArrayBuffer:r=>r,fromRegExpInfo:(r,e)=>new RegExp(r,e),fromViewInfo:(r,e,t,n)=>{let o=globalThis[r];return t!==void 0?new o(e,t,n):new o(e)},box:r=>Object(r),createArray:r=>new Array(r),createSparseArray:r=>{let e=[];return e[4294967294]=void 0,delete e[4294967294],e.length=r,e},createObject:()=>({}),createNullPrototypeObject:()=>Object.create(null),createSet:()=>new Set,createMap:()=>new Map,set:(r,e,t)=>{r[e]=t},addValue:(r,e)=>{r.add(e)},addEntry:(r,e,t)=>{r.set(e,t)}},_r=Object.freeze(ee);function G(r,e,t){return C(JSON.parse(r),e,t)}function C(r,e,t){let n=W(_r,t?.operations);if(typeof r=="number")return g(r,!0);if(!Array.isArray(r)||r.length===0)throw new Error("Invalid input");let o=r,s=Array(o.length),p=null;function g(c,V=!1){if(c===-1)return n.fromPrimitive(void 0);if(c===-3)return n.fromPrimitive(NaN);if(c===-4)return n.fromPrimitive(1/0);if(c===-5)return n.fromPrimitive(-1/0);if(c===-6)return n.fromPrimitive(-0);if(V||typeof c!="number")throw new Error("Invalid input");if(c in s)return s[c];let i=o[c];if(!i||typeof i!="object")s[c]=n.fromPrimitive(i);else if(Array.isArray(i))if(typeof i[0]=="string"){let d=i[0],a=e&&Object.hasOwn(e,d)?e[d]:void 0;if(a){let y=i[1];if(typeof y!="number"&&(y=o.push(i[1])-1),Object.hasOwn(s,y))return s[c]=a(s[y]);if(p??(p=new Set),p.has(y))throw new Error("Invalid circular reference");return p.add(y),s[c]=a(g(y)),p.delete(y),s[c]}switch(d){case"Date":s[c]=n.fromISOString(i[1]);break;case"Set":let y=n.createSet();s[c]=y;for(let l=1;l<i.length;l+=1)n.addValue(y,g(i[l]));break;case"Map":let E=n.createMap();s[c]=E;for(let l=1;l<i.length;l+=2)n.addEntry(E,g(i[l]),g(i[l+1]));break;case"RegExp":s[c]=n.fromRegExpInfo(i[1],i[2]);break;case"Object":{let l=i[1];if(typeof o[l]=="object"&&o[l][0]!=="BigInt")throw new Error("Invalid input");s[c]=n.box(g(l));break}case"BigInt":s[c]=n.fromPrimitive(BigInt(i[1]));break;case"null":let A=n.createNullPrototypeObject();s[c]=A;for(let l=1;l<i.length;l+=2){if(i[l]==="__proto__")throw new Error("Cannot parse an object with a \`__proto__\` property");n.set(A,i[l],g(i[l+1]))}break;case"Int8Array":case"Uint8Array":case"Uint8ClampedArray":case"Int16Array":case"Uint16Array":case"Float16Array":case"Int32Array":case"Uint32Array":case"Float32Array":case"Float64Array":case"BigInt64Array":case"BigUint64Array":case"DataView":{if(o[i[1]][0]!=="ArrayBuffer")throw new Error("Invalid data");let l=g(i[1]);s[c]=n.fromViewInfo(d,l,i[2],i[3]);break}case"ArrayBuffer":{let l=i[1];if(typeof l!="string")throw new Error("Invalid ArrayBuffer encoding");s[c]=n.fromArrayBuffer(br(l));break}case"URL":case"URLSearchParams":case"Temporal.Duration":case"Temporal.Instant":case"Temporal.PlainDate":case"Temporal.PlainTime":case"Temporal.PlainDateTime":case"Temporal.PlainMonthDay":case"Temporal.PlainYearMonth":case"Temporal.ZonedDateTime":{s[c]=n.fromStringValue(d,i[1]);break}default:throw new Error(\`Unknown type \${d}\`)}}else if(i[0]===-7){let d=i[1];if(!ur(d))throw new Error("Invalid input");let a=n.createSparseArray(d);s[c]=a;for(let y=2;y<i.length;y+=2){let E=i[y];if(!Y(E)||E>=d)throw new Error("Invalid input");n.set(a,E,g(i[y+1]))}}else{let d=n.createArray(i.length);s[c]=d;for(let a=0;a<i.length;a+=1){let y=i[a];y!==-2&&n.set(d,a,g(y))}}else{let d=n.createObject();s[c]=d;for(let a of Object.keys(i)){if(a==="__proto__")throw new Error("Cannot parse an object with a \`__proto__\` property");n.set(d,a,g(i[a]))}}return s[c]}return g(0)}function H(r,e,t){let n=ae(!1,r,e,t);return typeof n=="string"?n:\`[\${n.join(",")}]\`}function ae(r,e,t,n){let o=W(Er,n?.operations),s=[],p=new Map,g=[];if(t)for(let a of Object.getOwnPropertyNames(t))g.push({key:a,fn:t[a]});let c=[],V=0;function i(a,y){let E=o.typeOf(a);if(E==="undefined")return-1;let A;if(E==="number"){if(A=o.toPrimitive(a),Number.isNaN(A))return-3;if(A===1/0)return-4;if(A===-1/0)return-5;if(A===0&&1/A<0)return-6}let l=o.identify(a);if(p.has(l))return p.get(l);y??(y=V++),p.set(l,y);for(let{key:T,fn:k}of g){let M=k(a);if(M)return s[y]=\`["\${T}",\${i(M)}]\`,y}if(E==="function")throw new S("Cannot stringify a function",c,a,e);if(E==="symbol")throw new S("Cannot stringify a Symbol primitive",c,a,e);let f="";if(E!=="object")f=wr(E==="number"?A:o.toPrimitive(a));else if(o.isThenable(a)){if(!r)throw new S("Cannot stringify a Promise or thenable \\u2014 use stringifyAsync instead",c,a,e);f=o.toPromise(a).then(T=>{let k=i(T,y);k<0&&(s[y]=k)})}else{let T=o.tagOf(a);switch(T){case"Number":case"String":case"Boolean":case"BigInt":f=\`["Object",\${i(o.unbox(a))}]\`;break;case"Date":f=\`["Date","\${o.toISOString(a)}"]\`;break;case"URL":f=\`["URL",\${I(o.toStringValue(a))}]\`;break;case"URLSearchParams":f=\`["URLSearchParams",\${I(o.toStringValue(a))}]\`;break;case"RegExp":let{source:k,flags:M}=o.regExpInfo(a);f=M?\`["RegExp",\${I(k)},"\${M}"]\`:\`["RegExp",\${I(k)}]\`;break;case"Array":{let u=!1,b=o.lengthOf(a);f="[";for(let m=0;m<b;m+=1)if(m>0&&(f+=","),o.hasOwn(a,m))c.push(\`[\${m}]\`),f+=i(o.get(a,m)),c.pop();else if(u)f+=-2;else{let x=o.indicesOf(a),nr=x.length,or=String(b).length,Dr=(b-nr)*3,Ur=4+or+nr*(or+1);if(Dr>Ur){f="["+-7+","+b;for(let z=0;z<x.length;z++){let $=x[z];c.push(\`[\${$}]\`),f+=","+$+","+i(o.get(a,$)),c.pop()}break}else u=!0,f+=-2}f+="]";break}case"Set":f='["Set"';for(let u of o.valuesOf(a))f+=\`,\${i(u)}\`;f+="]";break;case"Map":f='["Map"';for(let[u,b]of o.entriesOf(a)){let m=o.typeOf(u),x=m!=="object"&&m!=="function"&&m!=="symbol";c.push(\`.get(\${x?wr(o.toPrimitive(u)):"..."})\`),f+=\`,\${i(u)},\${i(b)}\`,c.pop()}f+="]";break;case"Int8Array":case"Uint8Array":case"Uint8ClampedArray":case"Int16Array":case"Uint16Array":case"Float16Array":case"Int32Array":case"Uint32Array":case"Float32Array":case"Float64Array":case"BigInt64Array":case"BigUint64Array":{let u=o.viewInfo(a);f='["'+T+'",'+i(u.buffer),u.byteLength!==u.bufferByteLength&&(f+=\`,\${u.byteOffset},\${u.length}\`),f+="]";break}case"DataView":{let u=o.viewInfo(a);f='["'+T+'",'+i(u.buffer),u.byteLength!==u.bufferByteLength&&(f+=\`,\${u.byteOffset},\${u.byteLength}\`),f+="]";break}case"ArrayBuffer":{f=\`["ArrayBuffer","\${mr(o.toArrayBuffer(a))}"]\`;break}case"Temporal.Duration":case"Temporal.Instant":case"Temporal.PlainDate":case"Temporal.PlainTime":case"Temporal.PlainDateTime":case"Temporal.PlainMonthDay":case"Temporal.PlainYearMonth":case"Temporal.ZonedDateTime":f=\`["\${T}",\${I(o.toStringValue(a))}]\`;break;default:{let u=o.shapeOf(a);if(u.kind==="not-plain")throw new S("Cannot stringify arbitrary non-POJOs",c,a,e);if(u.kind==="symbol-keys")throw new S("Cannot stringify POJOs with symbolic keys",c,a,e);if(u.kind==="null-proto"){f='["null"';for(let b of u.keys){if(b==="__proto__")throw new S("Cannot stringify objects with __proto__ keys",c,a,e);c.push(Z(b)),f+=\`,\${I(b)},\${i(o.get(a,b))}\`,c.pop()}f+="]"}else{f="{";let b=!1;for(let m of u.keys){if(m==="__proto__")throw new S("Cannot stringify objects with __proto__ keys",c,a,e);b&&(f+=","),b=!0,c.push(Z(m)),f+=\`\${I(m)}:\${i(o.get(a,m))}\`,c.pop()}f+="}"}}}}return s[y]=f,y}let d=i(e);return d<0?\`\${d}\`:s}function wr(r){let e=typeof r;return e==="string"?I(r):r===void 0?(-1).toString():r===0&&1/r<0?(-6).toString():e==="bigint"?\`["BigInt","\${r}"]\`:String(r)}var X=Symbol.for("workflow-serialize"),q=Symbol.for("workflow-deserialize");var J=Symbol.for("workflow-class-registry");function ie(r=globalThis){let e=r,t=e[J];return t||(t=new Map,e[J]=t),t}function Q(r,e){return ie(e).get(r)}function P(){return{Class:r=>{if(typeof r!="function")return!1;let e=r.classId;return typeof e!="string"?!1:{classId:e}},Instance:r=>{if(r===null||typeof r!="object")return!1;let e=r.constructor;if(!e||typeof e!="function")return!1;let t=e[X];if(typeof t!="function")return!1;let n=e.classId;if(typeof n!="string")throw new Error(\`Class "\${e.name}" with \${String(X)} must have a static "classId" property.\`);let o=t.call(e,r);return{classId:n,data:o}}}}function B(r=globalThis){return{Class:e=>{let t=e.classId,n=Q(t,r);if(!n)throw new Error(\`Class "\${t}" not found. Make sure the class is registered with registerSerializationClass.\`);return n},Instance:e=>{let t=e.classId,n=e.data,o=Q(t,r);if(!o)throw new Error(\`Class "\${t}" not found. Make sure the class is registered with registerSerializationClass.\`);let s=o[q];if(typeof s!="function")throw new Error(\`Class "\${t}" does not have a static \${String(q)} method.\`);return s.call(o,n)}}}function Or(r,e,t){if(t===0)return".";let n=new Uint8Array(r,e,t),o="";for(let s=0;s<n.length;s++)o+=String.fromCharCode(n[s]);return btoa(o)}function R(r){return Or(r.buffer,r.byteOffset,r.byteLength)}function _(r){if(r===".")return new ArrayBuffer(0);let e=atob(r),t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n);return t.buffer}function h(r){return e=>{if(!(e instanceof Error)||e.name!==r)return!1;let t={message:e.message,stack:e.stack};return"cause"in e&&(t.cause=e.cause),t}}function N(r){return e=>{let t=globalThis[r],n;return typeof t=="function"?n=new t(e.message):(n=new Error(e.message),n.name=r),e.stack!==void 0&&(n.stack=e.stack),"cause"in e&&(n.cause=e.cause),n}}function j(){return{ArrayBuffer:r=>r instanceof ArrayBuffer&&Or(r,0,r.byteLength),BigInt:r=>typeof r=="bigint"&&r.toString(),BigInt64Array:r=>r instanceof BigInt64Array&&R(r),BigUint64Array:r=>r instanceof BigUint64Array&&R(r),Date:r=>r instanceof Date?!Number.isNaN(r.getDate())?r.toISOString():".":!1,DOMException:r=>{if(!(r instanceof DOMException))return!1;let e={message:r.message,name:r.name,stack:r.stack};return"cause"in r&&(e.cause=r.cause),e},AggregateError:r=>{if(!(r instanceof Error)||r.name!=="AggregateError")return!1;let e={message:r.message,stack:r.stack,errors:r.errors};return"cause"in r&&(e.cause=r.cause),e},EvalError:h("EvalError"),FatalError:h("FatalError"),HookConflictError:r=>{if(!(r instanceof Error)||r.name!=="HookConflictError")return!1;let e={message:r.message,stack:r.stack,token:r.token};return r.conflictingRunId!==void 0&&(e.conflictingRunId=r.conflictingRunId),"cause"in r&&(e.cause=r.cause),e},RangeError:h("RangeError"),ReferenceError:h("ReferenceError"),RetryableError:r=>{if(!(r instanceof Error)||r.name!=="RetryableError")return!1;let e=r.retryAfter,t;if(e&&typeof e=="object"&&typeof e.getTime=="function"){let o=e.getTime();t=Number.isNaN(o)?Date.now()+1e3:o}else if(typeof e=="string"||typeof e=="number"){let o=new Date(e).getTime();t=Number.isNaN(o)?Date.now()+1e3:o}else t=Date.now()+1e3;let n={message:r.message,stack:r.stack,retryAfter:t};return"cause"in r&&(n.cause=r.cause),n},RuntimeDecryptionError:r=>{if(!(r instanceof Error)||r.name!=="RuntimeDecryptionError")return!1;let e={message:r.message,stack:r.stack},t=r.context;return t!==void 0&&(e.context=t),"cause"in r&&(e.cause=r.cause),e},SyntaxError:h("SyntaxError"),TypeError:h("TypeError"),URIError:h("URIError"),Error:r=>{if(!(r instanceof Error))return!1;let e={name:r.name,message:r.message,stack:r.stack};return"cause"in r&&(e.cause=r.cause),e},Float32Array:r=>r instanceof Float32Array&&R(r),Float64Array:r=>r instanceof Float64Array&&R(r),Int8Array:r=>r instanceof Int8Array&&R(r),Int16Array:r=>r instanceof Int16Array&&R(r),Int32Array:r=>r instanceof Int32Array&&R(r),Map:r=>r instanceof Map&&Array.from(r),RegExp:r=>r instanceof RegExp&&{source:r.source,flags:r.flags},Headers:r=>{let e=globalThis.Headers;return!e||!(r instanceof e)?!1:Array.from(r)},Request:r=>{let e=globalThis.Request;if(!e||!(r instanceof e)&&typeof r?.json!="function"||typeof r?.method!="string")return!1;let t={method:r.method,url:r.url,headers:r.headers,body:r.body,duplex:r.duplex},n=r[Symbol.for("WEBHOOK_RESPONSE_WRITABLE")];return n&&(t.responseWritable=n),t},Response:r=>{let e=globalThis.Response;return!e||!(r instanceof e)&&typeof r?.clone!="function"||typeof r?.status!="number"?!1:{type:r.type,url:r.url,status:r.status,statusText:r.statusText,headers:r.headers,body:r.body,redirected:r.redirected}},ReadableStream:(r=>{if(r==null)return!1;let e=globalThis.ReadableStream;if(!e||!(r instanceof e||Object.getPrototypeOf(r)===e.prototype))return!1;let t=r[Symbol.for("BODY_INIT")];if(t!==void 0)return{bodyInit:t};let n=r[Symbol.for("WORKFLOW_STREAM_NAME")];if(n){let o={name:n},s=r[Symbol.for("WORKFLOW_STREAM_TYPE")];s&&(o.type=s);let p=r[Symbol.for("WORKFLOW_STREAM_FRAMING")];return p&&(o.framing=p),o}return{name:"__empty"}}),WritableStream:(r=>{if(r==null)return!1;let e=globalThis.WritableStream;if(!e||!(r instanceof e||Object.getPrototypeOf(r)===e.prototype))return!1;let n={name:r[Symbol.for("WORKFLOW_STREAM_NAME")]||"__empty"},o=r[Symbol.for("WORKFLOW_STREAM_SERVER_RUN_ID")];typeof o=="string"&&(n.runId=o);let s=r[Symbol.for("WORKFLOW_STREAM_SERVER_DEPLOYMENT_ID")];return typeof s=="string"&&(n.deploymentId=s),n}),Set:r=>r instanceof Set&&Array.from(r),URL:r=>r instanceof URL&&r.href,WorkflowFunction:r=>{if(typeof r!="function")return!1;let e=r.workflowId;return typeof e!="string"?!1:{workflowId:e}},URLSearchParams:r=>r instanceof URLSearchParams?r.size===0?".":String(r):!1,Uint8Array:r=>r instanceof Uint8Array&&R(r),Uint8ClampedArray:r=>r instanceof Uint8ClampedArray&&R(r),Uint16Array:r=>r instanceof Uint16Array&&R(r),Uint32Array:r=>r instanceof Uint32Array&&R(r)}}function K(){return{ArrayBuffer:r=>_(r),BigInt:r=>BigInt(r),BigInt64Array:r=>new BigInt64Array(_(r)),BigUint64Array:r=>new BigUint64Array(_(r)),Date:r=>new Date(r),DOMException:r=>{let e=new DOMException(r.message,r.name);return r.stack!==void 0&&(e.stack=r.stack),"cause"in r&&(e.cause=r.cause),e},AggregateError:r=>{let e=new AggregateError(r.errors??[],r.message);return r.stack!==void 0&&(e.stack=r.stack),"cause"in r&&(e.cause=r.cause),e},EvalError:N("EvalError"),FatalError:r=>{let e=globalThis[Symbol.for("@workflow/errors//FatalError")],t;return typeof e=="function"?t=new e(r.message):(t=new Error(r.message),t.name="FatalError"),r.stack!==void 0&&(t.stack=r.stack),"cause"in r&&(t.cause=r.cause),t},HookConflictError:r=>{let e=globalThis[Symbol.for("@workflow/errors//HookConflictError")],t;return typeof e=="function"?t=new e(r.token,r.conflictingRunId):(t=new Error(r.message),t.name="HookConflictError",t.token=r.token,r.conflictingRunId!==void 0&&(t.conflictingRunId=r.conflictingRunId)),r.stack!==void 0&&(t.stack=r.stack),"cause"in r&&(t.cause=r.cause),t},RangeError:N("RangeError"),ReferenceError:N("ReferenceError"),RetryableError:r=>{let e=globalThis[Symbol.for("@workflow/errors//RetryableError")],t=new Date(r.retryAfter),n;return typeof e=="function"?n=new e(r.message,{retryAfter:t}):(n=new Error(r.message),n.name="RetryableError",n.retryAfter=t),r.stack!==void 0&&(n.stack=r.stack),"cause"in r&&(n.cause=r.cause),n},RuntimeDecryptionError:r=>{let e=globalThis[Symbol.for("@workflow/errors//RuntimeDecryptionError")],t;if(typeof e=="function"){let n={};"cause"in r&&(n.cause=r.cause),r.context!==void 0&&(n.context=r.context),t=new e(r.message,n)}else t=new Error(r.message),t.name="RuntimeDecryptionError",r.context!==void 0&&(t.context=r.context),"cause"in r&&(t.cause=r.cause);return r.stack!==void 0&&(t.stack=r.stack),t},SyntaxError:N("SyntaxError"),TypeError:N("TypeError"),URIError:N("URIError"),Error:r=>{let e=new Error(r.message);return e.name=r.name,r.stack!==void 0&&(e.stack=r.stack),"cause"in r&&(e.cause=r.cause),e},Float32Array:r=>new Float32Array(_(r)),Float64Array:r=>new Float64Array(_(r)),Int8Array:r=>new Int8Array(_(r)),Int16Array:r=>new Int16Array(_(r)),Int32Array:r=>new Int32Array(_(r)),Map:r=>new Map(r),RegExp:r=>new RegExp(r.source,r.flags),Set:r=>new Set(r),URL:r=>new URL(r),WorkflowFunction:r=>Object.assign(()=>{throw new Error("Workflow functions cannot be called directly. Use start() to invoke them.")},{workflowId:r.workflowId}),URLSearchParams:r=>new URLSearchParams(r==="."?"":r),Uint8Array:r=>new Uint8Array(_(r)),Uint8ClampedArray:r=>new Uint8ClampedArray(_(r)),Uint16Array:r=>new Uint16Array(_(r)),Uint32Array:r=>new Uint32Array(_(r)),Headers:r=>new globalThis.Headers(r),Request:r=>{let e=globalThis.Request;return e&&(r.json=e.prototype.json,r.text=e.prototype.text,r.arrayBuffer=e.prototype.arrayBuffer),r.responseWritable&&(r[Symbol.for("WEBHOOK_RESPONSE_WRITABLE")]=r.responseWritable),r},Response:r=>{let e=globalThis.Response;return e&&(r.json=e.prototype.json,r.text=e.prototype.text,r.arrayBuffer=e.prototype.arrayBuffer,e.prototype.bytes&&(r.bytes=e.prototype.bytes),e.prototype.clone&&(r.clone=e.prototype.clone)),r._body=r.body,r.ok=r.status>=200&&r.status<300,r.bodyUsed=!1,r},ReadableStream:r=>{let e=globalThis.ReadableStream,t=Object.create(e?e.prototype:{});return r&&"bodyInit"in r?t[Symbol.for("BODY_INIT")]=r.bodyInit:r&&"name"in r&&(t[Symbol.for("WORKFLOW_STREAM_NAME")]=r.name,r.type&&(t[Symbol.for("WORKFLOW_STREAM_TYPE")]=r.type),r.framing&&(t[Symbol.for("WORKFLOW_STREAM_FRAMING")]=r.framing)),t},WritableStream:r=>{let e=globalThis.WritableStream,t=Object.create(e?e.prototype:{});return r&&"name"in r&&(t[Symbol.for("WORKFLOW_STREAM_NAME")]=r.name),r&&typeof r.runId=="string"&&(t[Symbol.for("WORKFLOW_STREAM_SERVER_RUN_ID")]=r.runId),r&&typeof r.deploymentId=="string"&&(t[Symbol.for("WORKFLOW_STREAM_SERVER_DEPLOYMENT_ID")]=r.deploymentId),t}}}function Ir(){return{StepFunction:r=>{if(typeof r!="function")return!1;let e=r.stepId;if(typeof e!="string")return!1;let t=r.__closureVarsFn,n=t&&typeof t=="function"?t():void 0,o="__boundThis"in r,s=o?r.__boundThis:void 0,p=r.__boundArgs,g={stepId:e};return n!==void 0&&(g.closureVars=n),o&&(g.boundThis=s),Array.isArray(p)&&p.length>0&&(g.boundArgs=p),g}}}function Tr(r=globalThis){let e=r[Symbol.for("WORKFLOW_USE_STEP")];return{StepFunction:t=>{let n=t.stepId,o=t.closureVars;if(!e)throw new Error("WORKFLOW_USE_STEP not found on global object. Step functions cannot be deserialized outside workflow context.");let s=o?e(n,()=>o):e(n);if("boundThis"in t){let p=Array.isArray(t.boundArgs)?t.boundArgs:[];return s.bind(t.boundThis,...p)}return s}}}function kr(r){return r.length===4&&/^[a-z0-9]{4}$/.test(r)}var U={DEVALUE_V1:"devl",ENCRYPTED:"encr",SEALED:"encp",GZIP:"gzip",ZSTD:"zstd"};var ce=new TextEncoder,fe=new TextDecoder,L=Symbol.for("WORKFLOW_ABORT_STREAM_NAME"),v=Symbol.for("WORKFLOW_ABORT_HOOK_TOKEN");function hr(r,e){let t=e[L]??e.signal?.[L],n=e[v]??e.signal?.[v];if(!t)throw new Error("AbortController/AbortSignal stream name is not set");return{streamName:t,hookToken:n,aborted:r.aborted,reason:r.aborted?r.reason:void 0}}function Nr(r){let e=globalThis.__WorkflowAbortSignal;if(typeof e!="function")throw new Error("WorkflowAbortSignal is not registered in the VM (bootstrap not evaluated)");let t=new e(r.streamName,r.hookToken);return r.aborted&&t._setAborted(r.reason),t}function ye(){return{AbortController:r=>!r||typeof r!="object"||!r.signal||(r[L]??r.signal?.[L])===void 0?!1:hr(r.signal,r),AbortSignal:r=>!r||typeof r!="object"||r[L]===void 0?!1:hr(r,r)}}function le(){return{AbortController:r=>({[L]:r.streamName,[v]:r.hookToken,signal:Nr(r),abort:()=>{}}),AbortSignal:r=>Nr(r)}}function ue(r){switch(r){case"workflow":return{...ye(),...P(),...Ir(),...j()};case"step":return{...P(),...j()};case"client":return{...P(),...j()}}}function Lr(r){switch(r){case"workflow":return{...le(),...B(),...Tr(),...K()};case"step":return{...B(),...K()};case"client":return{...B(),...K(),StepFunction:()=>{throw new Error("Step functions cannot be deserialized in client context.")}}}}var F={formatPrefix:U.DEVALUE_V1,serialize(r,e){let t=ue(e),n=H(r,t);return ce.encode(n)},deserialize(r,e){let t=Lr(e),n=fe.decode(r);return G(n,t)},deserializeLegacy(r,e){let t=Lr(e);return C(r,t)}};var rr=4,er,tr;function pe(){return er||(er=new globalThis.TextEncoder),er}function ge(){return tr||(tr=new globalThis.TextDecoder),tr}function Mr(r){let e=F.serialize(r,"workflow"),t=pe().encode(U.DEVALUE_V1),n=new Uint8Array(t.length+e.length);return n.set(t,0),n.set(e,t.length),n}function xr(r){if(!(r instanceof Uint8Array)){if(F.deserializeLegacy)return F.deserializeLegacy(r,"workflow");throw new Error("Cannot deserialize non-binary data without legacy support")}if(r.length<rr)throw new Error("Data too short to contain format prefix");let e=ge().decode(r.subarray(0,rr));if(!kr(e))throw new Error(\`Invalid format prefix: "\${e}"\`);if(e===U.DEVALUE_V1){let t=r.subarray(rr);return F.deserialize(t,"workflow")}throw new Error(\`Unsupported serialization format: \${e}\`)}globalThis[Symbol.for("workflow-serialize")]=Mr;globalThis[Symbol.for("workflow-deserialize")]=xr;var de=ir(()=>Math.random());globalThis.__generateUlid=()=>{let r=globalThis.__ulidTimestamp;if(typeof r!="number")throw new Error("__generateUlid: globalThis.__ulidTimestamp must be a number set by the host before the serde bundle is evaluated. Without it, ULIDs would fall back to Date.now() and concurrent workflow invocations of the same resumption would produce divergent correlationIds.");return de(r)};})();
|
|
15
|
+
`;
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm0tc2VyZGUtYnVuZGxlLmdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW50aW1lL3ZtLXNlcmRlLWJ1bmRsZS5nZW5lcmF0ZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQVc7O0NBRXRDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEF1dG8tZ2VuZXJhdGVkIGJ5IHNjcmlwdHMvYnVpbGQtdm0tc2VyZGUtYnVuZGxlLmpzXG4gKiBEbyBub3QgZWRpdCBtYW51YWxseS5cbiAqXG4gKiBUaGlzIGlzIHRoZSBWTSBzZXJpYWxpemF0aW9uIGJ1bmRsZSDigJQgYSBzZWxmLWNvbnRhaW5lZCBJSUZFIHRoYXQgc2V0cyB1cFxuICogdGhlIHNlcmlhbGl6ZS9kZXNlcmlhbGl6ZSBmdW5jdGlvbnMgaW5zaWRlIHRoZSBRdWlja0pTIFdBU00gVk0uIEl0XG4gKiBpbmNsdWRlcyBkZXZhbHVlIGFuZCBhbGwgd29ya2Zsb3ctbW9kZSByZWR1Y2Vycy9yZXZpdmVycy4gKFRleHRFbmNvZGVyLFxuICogVGV4dERlY29kZXIsIGFuZCBIZWFkZXJzIGFyZSBwcm92aWRlZCBieSBxdWlja2pzLXdhc2kncyBuYXRpdmUgQ1xuICogZXh0ZW5zaW9ucyDigJQgbm8gSlMgcG9seWZpbGxzIGFyZSBidW5kbGVkLilcbiAqXG4gKiBTaXplOiAyNS42IEtCIG1pbmlmaWVkXG4gKi9cbmV4cG9ydCBjb25zdCBWTV9TRVJERV9CVU5ETEU6IHN0cmluZyA9IGBcInVzZSBzdHJpY3RcIjsoKCk9Pnt2YXIgRD1cIjAxMjM0NTY3ODlBQkNERUZHSEpLTU5QUVJTVFZXWFlaXCI7dmFyIHc7KGZ1bmN0aW9uKHIpe3IuQmFzZTMySW5jb3JyZWN0RW5jb2Rpbmc9XCJCMzJfRU5DX0lOVkFMSURcIixyLkRlY29kZVRpbWVJbnZhbGlkQ2hhcmFjdGVyPVwiREVDX1RJTUVfQ0hBUlwiLHIuRGVjb2RlVGltZVZhbHVlTWFsZm9ybWVkPVwiREVDX1RJTUVfTUFMRk9STUVEXCIsci5FbmNvZGVUaW1lTmVnYXRpdmU9XCJFTkNfVElNRV9ORUdcIixyLkVuY29kZVRpbWVTaXplRXhjZWVkZWQ9XCJFTkNfVElNRV9TSVpFX0VYQ0VFRFwiLHIuRW5jb2RlVGltZVZhbHVlTWFsZm9ybWVkPVwiRU5DX1RJTUVfTUFMRk9STUVEXCIsci5QUk5HRGV0ZWN0RmFpbHVyZT1cIlBSTkdfREVURUNUXCIsci5VTElESW52YWxpZD1cIlVMSURfSU5WQUxJRFwiLHIuVW5leHBlY3RlZD1cIlVORVhQRUNURURcIixyLlVVSURJbnZhbGlkPVwiVVVJRF9JTlZBTElEXCJ9KSh3fHwodz17fSkpO3ZhciBPPWNsYXNzIGV4dGVuZHMgRXJyb3J7Y29uc3RydWN0b3IoZSx0KXtzdXBlcihcXGBcXCR7dH0gKFxcJHtlfSlcXGApLHRoaXMubmFtZT1cIlVMSURFcnJvclwiLHRoaXMuY29kZT1lfX07ZnVuY3Rpb24gRnIocil7bGV0IGU9TWF0aC5mbG9vcihyKCkqMzIpJTMyO3JldHVybiBELmNoYXJBdChlKX1mdW5jdGlvbiBzcihyLGUsdCl7cmV0dXJuIGU+ci5sZW5ndGgtMT9yOnIuc3Vic3RyKDAsZSkrdCtyLnN1YnN0cihlKzEpfWZ1bmN0aW9uIFdyKHIpe2xldCBlLHQ9ci5sZW5ndGgsbixvLHM9cixwPTMxO2Zvcig7IWUmJnQtLT49MDspe2lmKG49c1t0XSxvPUQuaW5kZXhPZihuKSxvPT09LTEpdGhyb3cgbmV3IE8ody5CYXNlMzJJbmNvcnJlY3RFbmNvZGluZyxcIkluY29ycmVjdGx5IGVuY29kZWQgc3RyaW5nXCIpO2lmKG89PT1wKXtzPXNyKHMsdCxEWzBdKTtjb250aW51ZX1lPXNyKHMsdCxEW28rMV0pfWlmKHR5cGVvZiBlPT1cInN0cmluZ1wiKXJldHVybiBlO3Rocm93IG5ldyBPKHcuQmFzZTMySW5jb3JyZWN0RW5jb2RpbmcsXCJGYWlsZWQgaW5jcmVtZW50aW5nIHN0cmluZ1wiKX1mdW5jdGlvbiBDcihyKXtsZXQgZT1QcigpLHQ9ZSYmKGUuY3J5cHRvfHxlLm1zQ3J5cHRvKXx8bnVsbDtpZih0eXBlb2YgdD8uZ2V0UmFuZG9tVmFsdWVzPT1cImZ1bmN0aW9uXCIpcmV0dXJuKCk9PntsZXQgbj1uZXcgVWludDhBcnJheSgxKTtyZXR1cm4gdC5nZXRSYW5kb21WYWx1ZXMobiksblswXS8yNTV9O2lmKHR5cGVvZiB0Py5yYW5kb21CeXRlcz09XCJmdW5jdGlvblwiKXJldHVybigpPT50LnJhbmRvbUJ5dGVzKDEpLnJlYWRVSW50OCgpLzI1NTt0aHJvdyBuZXcgTyh3LlBSTkdEZXRlY3RGYWlsdXJlLFwiRmFpbGVkIHRvIGZpbmQgYSByZWxpYWJsZSBQUk5HXCIpfWZ1bmN0aW9uIFByKCl7cmV0dXJuIGpyKCk/c2VsZjp0eXBlb2Ygd2luZG93PFwidVwiP3dpbmRvdzp0eXBlb2YgZ2xvYmFsPFwidVwiP2dsb2JhbDp0eXBlb2YgZ2xvYmFsVGhpczxcInVcIj9nbG9iYWxUaGlzOm51bGx9ZnVuY3Rpb24gQnIocixlKXtsZXQgdD1cIlwiO2Zvcig7cj4wO3ItLSl0PUZyKGUpK3Q7cmV0dXJuIHR9ZnVuY3Rpb24gYXIocixlPTEwKXtpZihpc05hTihyKSl0aHJvdyBuZXcgTyh3LkVuY29kZVRpbWVWYWx1ZU1hbGZvcm1lZCxcXGBUaW1lIG11c3QgYmUgYSBudW1iZXI6IFxcJHtyfVxcYCk7aWYocj4weGZmZmZmZmZmZmZmZil0aHJvdyBuZXcgTyh3LkVuY29kZVRpbWVTaXplRXhjZWVkZWQsXFxgQ2Fubm90IGVuY29kZSBhIHRpbWUgbGFyZ2VyIHRoYW4gXFwkezB4ZmZmZmZmZmZmZmZmfTogXFwke3J9XFxgKTtpZihyPDApdGhyb3cgbmV3IE8ody5FbmNvZGVUaW1lTmVnYXRpdmUsXFxgVGltZSBtdXN0IGJlIHBvc2l0aXZlOiBcXCR7cn1cXGApO2lmKE51bWJlci5pc0ludGVnZXIocik9PT0hMSl0aHJvdyBuZXcgTyh3LkVuY29kZVRpbWVWYWx1ZU1hbGZvcm1lZCxcXGBUaW1lIG11c3QgYmUgYW4gaW50ZWdlcjogXFwke3J9XFxgKTtsZXQgdCxuPVwiXCI7Zm9yKGxldCBvPWU7bz4wO28tLSl0PXIlMzIsbj1ELmNoYXJBdCh0KStuLHI9KHItdCkvMzI7cmV0dXJuIG59ZnVuY3Rpb24ganIoKXtyZXR1cm4gdHlwZW9mIFdvcmtlckdsb2JhbFNjb3BlPFwidVwiJiZzZWxmIGluc3RhbmNlb2YgV29ya2VyR2xvYmFsU2NvcGV9ZnVuY3Rpb24gaXIocil7bGV0IGU9cnx8Q3IoKSx0PTAsbjtyZXR1cm4gZnVuY3Rpb24ocyl7bGV0IHA9IXN8fGlzTmFOKHMpP0RhdGUubm93KCk6cztpZihwPD10KXtsZXQgYz1uPVdyKG4pO3JldHVybiBhcih0LDEwKStjfXQ9cDtsZXQgZz1uPUJyKDE2LGUpO3JldHVybiBhcihwLDEwKStnfX12YXIgUz1jbGFzcyBleHRlbmRzIEVycm9ye2NvbnN0cnVjdG9yKGUsdCxuLG8pe3N1cGVyKGUpLHRoaXMubmFtZT1cIkRldmFsdWVFcnJvclwiLHRoaXMucGF0aD10LmpvaW4oXCJcIiksdGhpcy52YWx1ZT1uLHRoaXMucm9vdD1vfX07dmFyIEtyPU9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKE9iamVjdC5wcm90b3R5cGUpLnNvcnQoKS5qb2luKFwiXFxcXDBcIik7ZnVuY3Rpb24gZnIocil7bGV0IGU9T2JqZWN0LmdldFByb3RvdHlwZU9mKHIpO3JldHVybiBlPT09T2JqZWN0LnByb3RvdHlwZXx8ZT09PW51bGx8fE9iamVjdC5nZXRQcm90b3R5cGVPZihlKT09PW51bGx8fE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGUpLnNvcnQoKS5qb2luKFwiXFxcXDBcIik9PT1Lcn1mdW5jdGlvbiB5cihyKXtyZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHIpLnNsaWNlKDgsLTEpfWZ1bmN0aW9uIFZyKHIpe3N3aXRjaChyKXtjYXNlJ1wiJzpyZXR1cm4nXFxcXFxcXFxcIic7Y2FzZVwiPFwiOnJldHVyblwiXFxcXFxcXFx1MDAzQ1wiO2Nhc2VcIlxcXFxcXFxcXCI6cmV0dXJuXCJcXFxcXFxcXFxcXFxcXFxcXCI7Y2FzZVxcYFxuXFxgOnJldHVyblwiXFxcXFxcXFxuXCI7Y2FzZVwiXFxcXHJcIjpyZXR1cm5cIlxcXFxcXFxcclwiO2Nhc2VcIlx0XCI6cmV0dXJuXCJcXFxcXFxcXHRcIjtjYXNlXCJcXFxcYlwiOnJldHVyblwiXFxcXFxcXFxiXCI7Y2FzZVwiXFxcXGZcIjpyZXR1cm5cIlxcXFxcXFxcZlwiO2Nhc2VcIlxcXFx1MjAyOFwiOnJldHVyblwiXFxcXFxcXFx1MjAyOFwiO2Nhc2VcIlxcXFx1MjAyOVwiOnJldHVyblwiXFxcXFxcXFx1MjAyOVwiO2RlZmF1bHQ6cmV0dXJuIHI8XCIgXCI/XFxgXFxcXFxcXFx1XFwke3IuY2hhckNvZGVBdCgwKS50b1N0cmluZygxNikucGFkU3RhcnQoNCxcIjBcIil9XFxgOlwiXCJ9fWZ1bmN0aW9uIEkocil7bGV0IGU9XCJcIix0PTAsbj1yLmxlbmd0aDtmb3IobGV0IG89MDtvPG47bys9MSl7bGV0IHM9cltvXSxwPVZyKHMpO3AmJihlKz1yLnNsaWNlKHQsbykrcCx0PW8rMSl9cmV0dXJuXFxgXCJcXCR7dD09PTA/cjplK3Iuc2xpY2UodCl9XCJcXGB9ZnVuY3Rpb24gbHIocil7cmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocikuZmlsdGVyKGU9Pk9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IocixlKS5lbnVtZXJhYmxlKX12YXIgenI9L15bYS16QS1aXyRdW2EtekEtWl8kMC05XSokLztmdW5jdGlvbiBaKHIpe3JldHVybiB6ci50ZXN0KHIpP1wiLlwiK3I6XCJbXCIrSlNPTi5zdHJpbmdpZnkocikrXCJdXCJ9ZnVuY3Rpb24gWShyKXtyZXR1cm4hKCFOdW1iZXIuaXNJbnRlZ2VyKHIpfHxyPDB8fHI+NDI5NDk2NzI5NCl9ZnVuY3Rpb24gdXIocil7cmV0dXJuISghTnVtYmVyLmlzSW50ZWdlcihyKXx8cjwwfHxyPjQyOTQ5NjcyOTUpfWZ1bmN0aW9uICRyKHIpe2lmKHIubGVuZ3RoPT09MHx8ci5sZW5ndGg+MSYmci5jaGFyQ29kZUF0KDApPT09NDgpcmV0dXJuITE7Zm9yKGxldCBlPTA7ZTxyLmxlbmd0aDtlKyspe2xldCB0PXIuY2hhckNvZGVBdChlKTtpZih0PDQ4fHx0PjU3KXJldHVybiExfXJldHVybiBZKCtyKX1mdW5jdGlvbiBacihyKXtmb3IodmFyIGU9ci5sZW5ndGgtMTtlPj0wJiYhJHIocltlXSk7ZS0tKTtyZXR1cm4gZSsxfWZ1bmN0aW9uIHByKHIpe2xldCBlPU9iamVjdC5rZXlzKHIpO3JldHVybiBlLmxlbmd0aD1acihlKSxlfWZ1bmN0aW9uIFlyKHIpe3JldHVybiBuZXcgVWludDhBcnJheShyKS50b0Jhc2U2NCgpfWZ1bmN0aW9uIEdyKHIpe3JldHVybiBVaW50OEFycmF5LmZyb21CYXNlNjQocikuYnVmZmVyfWZ1bmN0aW9uIEhyKHIpe3JldHVybiBCdWZmZXIuZnJvbShyKS50b1N0cmluZyhcImJhc2U2NFwiKX1mdW5jdGlvbiBYcihyKXtyZXR1cm4gVWludDhBcnJheS5mcm9tKEJ1ZmZlci5mcm9tKHIsXCJiYXNlNjRcIikpLmJ1ZmZlcn1mdW5jdGlvbiBxcihyKXtsZXQgZT1uZXcgVWludDhBcnJheShyKSx0PVwiXCIsbj0zMjc2ODtmb3IobGV0IG89MDtvPGUubGVuZ3RoO28rPW4pe2xldCBzPWUuc3ViYXJyYXkobyxvK24pO3QrPVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxzKX1yZXR1cm4gYnRvYSh0KX1mdW5jdGlvbiBKcihyKXtsZXQgZT1hdG9iKHIpLHQ9ZS5sZW5ndGgsbj1uZXcgVWludDhBcnJheSh0KTtmb3IobGV0IG89MDtvPHQ7bysrKW5bb109ZS5jaGFyQ29kZUF0KG8pO3JldHVybiBuLmJ1ZmZlcn12YXIgZ3I9dHlwZW9mIFVpbnQ4QXJyYXkuZnJvbUJhc2U2ND09XCJmdW5jdGlvblwiLGRyPXR5cGVvZiBwcm9jZXNzPT1cIm9iamVjdFwiJiZwcm9jZXNzLnZlcnNpb25zPy5ub2RlIT09dm9pZCAwLG1yPWdyP1lyOmRyP0hyOnFyLGJyPWdyP0dyOmRyP1hyOkpyO2Z1bmN0aW9uIFcocixlKXtpZighZSlyZXR1cm4gcjtsZXQgdD17fTtmb3IobGV0IG4gb2YgT2JqZWN0LmtleXMocikpdFtuXT1lW25dPz9yW25dO3JldHVybiB0fXZhciBRcj1PYmplY3QuZnJlZXplKHtraW5kOlwibm90LXBsYWluXCJ9KSx2cj1PYmplY3QuZnJlZXplKHtraW5kOlwic3ltYm9sLWtleXNcIn0pLHJlPXtpZGVudGlmeTpyPT5yLHR5cGVPZjpyPT5yPT09bnVsbD9cIm51bGxcIjp0eXBlb2Ygcix0b1ByaW1pdGl2ZTpyPT5yLHRhZ09mOnI9PnlyKHIpLGlzVGhlbmFibGU6cj0+dHlwZW9mIHIudGhlbj09XCJmdW5jdGlvblwiLHRvUHJvbWlzZTpyPT5Qcm9taXNlLnJlc29sdmUociksdW5ib3g6cj0+ci52YWx1ZU9mKCksdG9JU09TdHJpbmc6cj0+aXNOYU4oci5nZXREYXRlKCkpP1wiXCI6ci50b0lTT1N0cmluZygpLHRvU3RyaW5nVmFsdWU6cj0+ci50b1N0cmluZygpLHJlZ0V4cEluZm86cj0+KHtzb3VyY2U6ci5zb3VyY2UsZmxhZ3M6ci5mbGFnc30pLHZhbHVlc09mOnI9PnIsZW50cmllc09mOnI9PnIsdmlld0luZm86cj0+KHtidWZmZXI6ci5idWZmZXIsYnl0ZU9mZnNldDpyLmJ5dGVPZmZzZXQsYnl0ZUxlbmd0aDpyLmJ5dGVMZW5ndGgsbGVuZ3RoOnIubGVuZ3RoLGJ1ZmZlckJ5dGVMZW5ndGg6ci5idWZmZXIuYnl0ZUxlbmd0aH0pLHRvQXJyYXlCdWZmZXI6cj0+cixsZW5ndGhPZjpyPT5yLmxlbmd0aCxoYXNPd246KHIsZSk9Pk9iamVjdC5oYXNPd24ocixlKSxpbmRpY2VzT2Y6cj0+cHIociksc2hhcGVPZjpyPT5mcihyKT9scihyKS5sZW5ndGg+MD92cjp7a2luZDpPYmplY3QuZ2V0UHJvdG90eXBlT2Yocik9PT1udWxsP1wibnVsbC1wcm90b1wiOlwicGxhaW5cIixrZXlzOk9iamVjdC5rZXlzKHIpfTpRcixnZXQ6KHIsZSk9PnJbZV19LEVyPU9iamVjdC5mcmVlemUocmUpLGVlPXtmcm9tUHJpbWl0aXZlOnI9PnIsZnJvbUlTT1N0cmluZzpyPT5uZXcgRGF0ZShyKSxmcm9tU3RyaW5nVmFsdWU6KHIsZSk9PnI9PT1cIlVSTFwiP25ldyBVUkwoZSk6cj09PVwiVVJMU2VhcmNoUGFyYW1zXCI/bmV3IFVSTFNlYXJjaFBhcmFtcyhlKTpUZW1wb3JhbFtyLnNsaWNlKDkpXS5mcm9tKGUpLGZyb21BcnJheUJ1ZmZlcjpyPT5yLGZyb21SZWdFeHBJbmZvOihyLGUpPT5uZXcgUmVnRXhwKHIsZSksZnJvbVZpZXdJbmZvOihyLGUsdCxuKT0+e2xldCBvPWdsb2JhbFRoaXNbcl07cmV0dXJuIHQhPT12b2lkIDA/bmV3IG8oZSx0LG4pOm5ldyBvKGUpfSxib3g6cj0+T2JqZWN0KHIpLGNyZWF0ZUFycmF5OnI9Pm5ldyBBcnJheShyKSxjcmVhdGVTcGFyc2VBcnJheTpyPT57bGV0IGU9W107cmV0dXJuIGVbNDI5NDk2NzI5NF09dm9pZCAwLGRlbGV0ZSBlWzQyOTQ5NjcyOTRdLGUubGVuZ3RoPXIsZX0sY3JlYXRlT2JqZWN0OigpPT4oe30pLGNyZWF0ZU51bGxQcm90b3R5cGVPYmplY3Q6KCk9Pk9iamVjdC5jcmVhdGUobnVsbCksY3JlYXRlU2V0OigpPT5uZXcgU2V0LGNyZWF0ZU1hcDooKT0+bmV3IE1hcCxzZXQ6KHIsZSx0KT0+e3JbZV09dH0sYWRkVmFsdWU6KHIsZSk9PntyLmFkZChlKX0sYWRkRW50cnk6KHIsZSx0KT0+e3Iuc2V0KGUsdCl9fSxfcj1PYmplY3QuZnJlZXplKGVlKTtmdW5jdGlvbiBHKHIsZSx0KXtyZXR1cm4gQyhKU09OLnBhcnNlKHIpLGUsdCl9ZnVuY3Rpb24gQyhyLGUsdCl7bGV0IG49Vyhfcix0Py5vcGVyYXRpb25zKTtpZih0eXBlb2Ygcj09XCJudW1iZXJcIilyZXR1cm4gZyhyLCEwKTtpZighQXJyYXkuaXNBcnJheShyKXx8ci5sZW5ndGg9PT0wKXRocm93IG5ldyBFcnJvcihcIkludmFsaWQgaW5wdXRcIik7bGV0IG89cixzPUFycmF5KG8ubGVuZ3RoKSxwPW51bGw7ZnVuY3Rpb24gZyhjLFY9ITEpe2lmKGM9PT0tMSlyZXR1cm4gbi5mcm9tUHJpbWl0aXZlKHZvaWQgMCk7aWYoYz09PS0zKXJldHVybiBuLmZyb21QcmltaXRpdmUoTmFOKTtpZihjPT09LTQpcmV0dXJuIG4uZnJvbVByaW1pdGl2ZSgxLzApO2lmKGM9PT0tNSlyZXR1cm4gbi5mcm9tUHJpbWl0aXZlKC0xLzApO2lmKGM9PT0tNilyZXR1cm4gbi5mcm9tUHJpbWl0aXZlKC0wKTtpZihWfHx0eXBlb2YgYyE9XCJudW1iZXJcIil0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGlucHV0XCIpO2lmKGMgaW4gcylyZXR1cm4gc1tjXTtsZXQgaT1vW2NdO2lmKCFpfHx0eXBlb2YgaSE9XCJvYmplY3RcIilzW2NdPW4uZnJvbVByaW1pdGl2ZShpKTtlbHNlIGlmKEFycmF5LmlzQXJyYXkoaSkpaWYodHlwZW9mIGlbMF09PVwic3RyaW5nXCIpe2xldCBkPWlbMF0sYT1lJiZPYmplY3QuaGFzT3duKGUsZCk/ZVtkXTp2b2lkIDA7aWYoYSl7bGV0IHk9aVsxXTtpZih0eXBlb2YgeSE9XCJudW1iZXJcIiYmKHk9by5wdXNoKGlbMV0pLTEpLE9iamVjdC5oYXNPd24ocyx5KSlyZXR1cm4gc1tjXT1hKHNbeV0pO2lmKHA/PyhwPW5ldyBTZXQpLHAuaGFzKHkpKXRocm93IG5ldyBFcnJvcihcIkludmFsaWQgY2lyY3VsYXIgcmVmZXJlbmNlXCIpO3JldHVybiBwLmFkZCh5KSxzW2NdPWEoZyh5KSkscC5kZWxldGUoeSksc1tjXX1zd2l0Y2goZCl7Y2FzZVwiRGF0ZVwiOnNbY109bi5mcm9tSVNPU3RyaW5nKGlbMV0pO2JyZWFrO2Nhc2VcIlNldFwiOmxldCB5PW4uY3JlYXRlU2V0KCk7c1tjXT15O2ZvcihsZXQgbD0xO2w8aS5sZW5ndGg7bCs9MSluLmFkZFZhbHVlKHksZyhpW2xdKSk7YnJlYWs7Y2FzZVwiTWFwXCI6bGV0IEU9bi5jcmVhdGVNYXAoKTtzW2NdPUU7Zm9yKGxldCBsPTE7bDxpLmxlbmd0aDtsKz0yKW4uYWRkRW50cnkoRSxnKGlbbF0pLGcoaVtsKzFdKSk7YnJlYWs7Y2FzZVwiUmVnRXhwXCI6c1tjXT1uLmZyb21SZWdFeHBJbmZvKGlbMV0saVsyXSk7YnJlYWs7Y2FzZVwiT2JqZWN0XCI6e2xldCBsPWlbMV07aWYodHlwZW9mIG9bbF09PVwib2JqZWN0XCImJm9bbF1bMF0hPT1cIkJpZ0ludFwiKXRocm93IG5ldyBFcnJvcihcIkludmFsaWQgaW5wdXRcIik7c1tjXT1uLmJveChnKGwpKTticmVha31jYXNlXCJCaWdJbnRcIjpzW2NdPW4uZnJvbVByaW1pdGl2ZShCaWdJbnQoaVsxXSkpO2JyZWFrO2Nhc2VcIm51bGxcIjpsZXQgQT1uLmNyZWF0ZU51bGxQcm90b3R5cGVPYmplY3QoKTtzW2NdPUE7Zm9yKGxldCBsPTE7bDxpLmxlbmd0aDtsKz0yKXtpZihpW2xdPT09XCJfX3Byb3RvX19cIil0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgcGFyc2UgYW4gb2JqZWN0IHdpdGggYSBcXGBfX3Byb3RvX19cXGAgcHJvcGVydHlcIik7bi5zZXQoQSxpW2xdLGcoaVtsKzFdKSl9YnJlYWs7Y2FzZVwiSW50OEFycmF5XCI6Y2FzZVwiVWludDhBcnJheVwiOmNhc2VcIlVpbnQ4Q2xhbXBlZEFycmF5XCI6Y2FzZVwiSW50MTZBcnJheVwiOmNhc2VcIlVpbnQxNkFycmF5XCI6Y2FzZVwiRmxvYXQxNkFycmF5XCI6Y2FzZVwiSW50MzJBcnJheVwiOmNhc2VcIlVpbnQzMkFycmF5XCI6Y2FzZVwiRmxvYXQzMkFycmF5XCI6Y2FzZVwiRmxvYXQ2NEFycmF5XCI6Y2FzZVwiQmlnSW50NjRBcnJheVwiOmNhc2VcIkJpZ1VpbnQ2NEFycmF5XCI6Y2FzZVwiRGF0YVZpZXdcIjp7aWYob1tpWzFdXVswXSE9PVwiQXJyYXlCdWZmZXJcIil0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGRhdGFcIik7bGV0IGw9ZyhpWzFdKTtzW2NdPW4uZnJvbVZpZXdJbmZvKGQsbCxpWzJdLGlbM10pO2JyZWFrfWNhc2VcIkFycmF5QnVmZmVyXCI6e2xldCBsPWlbMV07aWYodHlwZW9mIGwhPVwic3RyaW5nXCIpdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBBcnJheUJ1ZmZlciBlbmNvZGluZ1wiKTtzW2NdPW4uZnJvbUFycmF5QnVmZmVyKGJyKGwpKTticmVha31jYXNlXCJVUkxcIjpjYXNlXCJVUkxTZWFyY2hQYXJhbXNcIjpjYXNlXCJUZW1wb3JhbC5EdXJhdGlvblwiOmNhc2VcIlRlbXBvcmFsLkluc3RhbnRcIjpjYXNlXCJUZW1wb3JhbC5QbGFpbkRhdGVcIjpjYXNlXCJUZW1wb3JhbC5QbGFpblRpbWVcIjpjYXNlXCJUZW1wb3JhbC5QbGFpbkRhdGVUaW1lXCI6Y2FzZVwiVGVtcG9yYWwuUGxhaW5Nb250aERheVwiOmNhc2VcIlRlbXBvcmFsLlBsYWluWWVhck1vbnRoXCI6Y2FzZVwiVGVtcG9yYWwuWm9uZWREYXRlVGltZVwiOntzW2NdPW4uZnJvbVN0cmluZ1ZhbHVlKGQsaVsxXSk7YnJlYWt9ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoXFxgVW5rbm93biB0eXBlIFxcJHtkfVxcYCl9fWVsc2UgaWYoaVswXT09PS03KXtsZXQgZD1pWzFdO2lmKCF1cihkKSl0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGlucHV0XCIpO2xldCBhPW4uY3JlYXRlU3BhcnNlQXJyYXkoZCk7c1tjXT1hO2ZvcihsZXQgeT0yO3k8aS5sZW5ndGg7eSs9Mil7bGV0IEU9aVt5XTtpZighWShFKXx8RT49ZCl0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGlucHV0XCIpO24uc2V0KGEsRSxnKGlbeSsxXSkpfX1lbHNle2xldCBkPW4uY3JlYXRlQXJyYXkoaS5sZW5ndGgpO3NbY109ZDtmb3IobGV0IGE9MDthPGkubGVuZ3RoO2ErPTEpe2xldCB5PWlbYV07eSE9PS0yJiZuLnNldChkLGEsZyh5KSl9fWVsc2V7bGV0IGQ9bi5jcmVhdGVPYmplY3QoKTtzW2NdPWQ7Zm9yKGxldCBhIG9mIE9iamVjdC5rZXlzKGkpKXtpZihhPT09XCJfX3Byb3RvX19cIil0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgcGFyc2UgYW4gb2JqZWN0IHdpdGggYSBcXGBfX3Byb3RvX19cXGAgcHJvcGVydHlcIik7bi5zZXQoZCxhLGcoaVthXSkpfX1yZXR1cm4gc1tjXX1yZXR1cm4gZygwKX1mdW5jdGlvbiBIKHIsZSx0KXtsZXQgbj1hZSghMSxyLGUsdCk7cmV0dXJuIHR5cGVvZiBuPT1cInN0cmluZ1wiP246XFxgW1xcJHtuLmpvaW4oXCIsXCIpfV1cXGB9ZnVuY3Rpb24gYWUocixlLHQsbil7bGV0IG89VyhFcixuPy5vcGVyYXRpb25zKSxzPVtdLHA9bmV3IE1hcCxnPVtdO2lmKHQpZm9yKGxldCBhIG9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHQpKWcucHVzaCh7a2V5OmEsZm46dFthXX0pO2xldCBjPVtdLFY9MDtmdW5jdGlvbiBpKGEseSl7bGV0IEU9by50eXBlT2YoYSk7aWYoRT09PVwidW5kZWZpbmVkXCIpcmV0dXJuLTE7bGV0IEE7aWYoRT09PVwibnVtYmVyXCIpe2lmKEE9by50b1ByaW1pdGl2ZShhKSxOdW1iZXIuaXNOYU4oQSkpcmV0dXJuLTM7aWYoQT09PTEvMClyZXR1cm4tNDtpZihBPT09LTEvMClyZXR1cm4tNTtpZihBPT09MCYmMS9BPDApcmV0dXJuLTZ9bGV0IGw9by5pZGVudGlmeShhKTtpZihwLmhhcyhsKSlyZXR1cm4gcC5nZXQobCk7eT8/KHk9VisrKSxwLnNldChsLHkpO2ZvcihsZXR7a2V5OlQsZm46a31vZiBnKXtsZXQgTT1rKGEpO2lmKE0pcmV0dXJuIHNbeV09XFxgW1wiXFwke1R9XCIsXFwke2koTSl9XVxcYCx5fWlmKEU9PT1cImZ1bmN0aW9uXCIpdGhyb3cgbmV3IFMoXCJDYW5ub3Qgc3RyaW5naWZ5IGEgZnVuY3Rpb25cIixjLGEsZSk7aWYoRT09PVwic3ltYm9sXCIpdGhyb3cgbmV3IFMoXCJDYW5ub3Qgc3RyaW5naWZ5IGEgU3ltYm9sIHByaW1pdGl2ZVwiLGMsYSxlKTtsZXQgZj1cIlwiO2lmKEUhPT1cIm9iamVjdFwiKWY9d3IoRT09PVwibnVtYmVyXCI/QTpvLnRvUHJpbWl0aXZlKGEpKTtlbHNlIGlmKG8uaXNUaGVuYWJsZShhKSl7aWYoIXIpdGhyb3cgbmV3IFMoXCJDYW5ub3Qgc3RyaW5naWZ5IGEgUHJvbWlzZSBvciB0aGVuYWJsZSBcXFxcdTIwMTQgdXNlIHN0cmluZ2lmeUFzeW5jIGluc3RlYWRcIixjLGEsZSk7Zj1vLnRvUHJvbWlzZShhKS50aGVuKFQ9PntsZXQgaz1pKFQseSk7azwwJiYoc1t5XT1rKX0pfWVsc2V7bGV0IFQ9by50YWdPZihhKTtzd2l0Y2goVCl7Y2FzZVwiTnVtYmVyXCI6Y2FzZVwiU3RyaW5nXCI6Y2FzZVwiQm9vbGVhblwiOmNhc2VcIkJpZ0ludFwiOmY9XFxgW1wiT2JqZWN0XCIsXFwke2koby51bmJveChhKSl9XVxcYDticmVhaztjYXNlXCJEYXRlXCI6Zj1cXGBbXCJEYXRlXCIsXCJcXCR7by50b0lTT1N0cmluZyhhKX1cIl1cXGA7YnJlYWs7Y2FzZVwiVVJMXCI6Zj1cXGBbXCJVUkxcIixcXCR7SShvLnRvU3RyaW5nVmFsdWUoYSkpfV1cXGA7YnJlYWs7Y2FzZVwiVVJMU2VhcmNoUGFyYW1zXCI6Zj1cXGBbXCJVUkxTZWFyY2hQYXJhbXNcIixcXCR7SShvLnRvU3RyaW5nVmFsdWUoYSkpfV1cXGA7YnJlYWs7Y2FzZVwiUmVnRXhwXCI6bGV0e3NvdXJjZTprLGZsYWdzOk19PW8ucmVnRXhwSW5mbyhhKTtmPU0/XFxgW1wiUmVnRXhwXCIsXFwke0koayl9LFwiXFwke019XCJdXFxgOlxcYFtcIlJlZ0V4cFwiLFxcJHtJKGspfV1cXGA7YnJlYWs7Y2FzZVwiQXJyYXlcIjp7bGV0IHU9ITEsYj1vLmxlbmd0aE9mKGEpO2Y9XCJbXCI7Zm9yKGxldCBtPTA7bTxiO20rPTEpaWYobT4wJiYoZis9XCIsXCIpLG8uaGFzT3duKGEsbSkpYy5wdXNoKFxcYFtcXCR7bX1dXFxgKSxmKz1pKG8uZ2V0KGEsbSkpLGMucG9wKCk7ZWxzZSBpZih1KWYrPS0yO2Vsc2V7bGV0IHg9by5pbmRpY2VzT2YoYSksbnI9eC5sZW5ndGgsb3I9U3RyaW5nKGIpLmxlbmd0aCxEcj0oYi1ucikqMyxVcj00K29yK25yKihvcisxKTtpZihEcj5Vcil7Zj1cIltcIistNytcIixcIitiO2ZvcihsZXQgej0wO3o8eC5sZW5ndGg7eisrKXtsZXQgJD14W3pdO2MucHVzaChcXGBbXFwkeyR9XVxcYCksZis9XCIsXCIrJCtcIixcIitpKG8uZ2V0KGEsJCkpLGMucG9wKCl9YnJlYWt9ZWxzZSB1PSEwLGYrPS0yfWYrPVwiXVwiO2JyZWFrfWNhc2VcIlNldFwiOmY9J1tcIlNldFwiJztmb3IobGV0IHUgb2Ygby52YWx1ZXNPZihhKSlmKz1cXGAsXFwke2kodSl9XFxgO2YrPVwiXVwiO2JyZWFrO2Nhc2VcIk1hcFwiOmY9J1tcIk1hcFwiJztmb3IobGV0W3UsYl1vZiBvLmVudHJpZXNPZihhKSl7bGV0IG09by50eXBlT2YodSkseD1tIT09XCJvYmplY3RcIiYmbSE9PVwiZnVuY3Rpb25cIiYmbSE9PVwic3ltYm9sXCI7Yy5wdXNoKFxcYC5nZXQoXFwke3g/d3Ioby50b1ByaW1pdGl2ZSh1KSk6XCIuLi5cIn0pXFxgKSxmKz1cXGAsXFwke2kodSl9LFxcJHtpKGIpfVxcYCxjLnBvcCgpfWYrPVwiXVwiO2JyZWFrO2Nhc2VcIkludDhBcnJheVwiOmNhc2VcIlVpbnQ4QXJyYXlcIjpjYXNlXCJVaW50OENsYW1wZWRBcnJheVwiOmNhc2VcIkludDE2QXJyYXlcIjpjYXNlXCJVaW50MTZBcnJheVwiOmNhc2VcIkZsb2F0MTZBcnJheVwiOmNhc2VcIkludDMyQXJyYXlcIjpjYXNlXCJVaW50MzJBcnJheVwiOmNhc2VcIkZsb2F0MzJBcnJheVwiOmNhc2VcIkZsb2F0NjRBcnJheVwiOmNhc2VcIkJpZ0ludDY0QXJyYXlcIjpjYXNlXCJCaWdVaW50NjRBcnJheVwiOntsZXQgdT1vLnZpZXdJbmZvKGEpO2Y9J1tcIicrVCsnXCIsJytpKHUuYnVmZmVyKSx1LmJ5dGVMZW5ndGghPT11LmJ1ZmZlckJ5dGVMZW5ndGgmJihmKz1cXGAsXFwke3UuYnl0ZU9mZnNldH0sXFwke3UubGVuZ3RofVxcYCksZis9XCJdXCI7YnJlYWt9Y2FzZVwiRGF0YVZpZXdcIjp7bGV0IHU9by52aWV3SW5mbyhhKTtmPSdbXCInK1QrJ1wiLCcraSh1LmJ1ZmZlciksdS5ieXRlTGVuZ3RoIT09dS5idWZmZXJCeXRlTGVuZ3RoJiYoZis9XFxgLFxcJHt1LmJ5dGVPZmZzZXR9LFxcJHt1LmJ5dGVMZW5ndGh9XFxgKSxmKz1cIl1cIjticmVha31jYXNlXCJBcnJheUJ1ZmZlclwiOntmPVxcYFtcIkFycmF5QnVmZmVyXCIsXCJcXCR7bXIoby50b0FycmF5QnVmZmVyKGEpKX1cIl1cXGA7YnJlYWt9Y2FzZVwiVGVtcG9yYWwuRHVyYXRpb25cIjpjYXNlXCJUZW1wb3JhbC5JbnN0YW50XCI6Y2FzZVwiVGVtcG9yYWwuUGxhaW5EYXRlXCI6Y2FzZVwiVGVtcG9yYWwuUGxhaW5UaW1lXCI6Y2FzZVwiVGVtcG9yYWwuUGxhaW5EYXRlVGltZVwiOmNhc2VcIlRlbXBvcmFsLlBsYWluTW9udGhEYXlcIjpjYXNlXCJUZW1wb3JhbC5QbGFpblllYXJNb250aFwiOmNhc2VcIlRlbXBvcmFsLlpvbmVkRGF0ZVRpbWVcIjpmPVxcYFtcIlxcJHtUfVwiLFxcJHtJKG8udG9TdHJpbmdWYWx1ZShhKSl9XVxcYDticmVhaztkZWZhdWx0OntsZXQgdT1vLnNoYXBlT2YoYSk7aWYodS5raW5kPT09XCJub3QtcGxhaW5cIil0aHJvdyBuZXcgUyhcIkNhbm5vdCBzdHJpbmdpZnkgYXJiaXRyYXJ5IG5vbi1QT0pPc1wiLGMsYSxlKTtpZih1LmtpbmQ9PT1cInN5bWJvbC1rZXlzXCIpdGhyb3cgbmV3IFMoXCJDYW5ub3Qgc3RyaW5naWZ5IFBPSk9zIHdpdGggc3ltYm9saWMga2V5c1wiLGMsYSxlKTtpZih1LmtpbmQ9PT1cIm51bGwtcHJvdG9cIil7Zj0nW1wibnVsbFwiJztmb3IobGV0IGIgb2YgdS5rZXlzKXtpZihiPT09XCJfX3Byb3RvX19cIil0aHJvdyBuZXcgUyhcIkNhbm5vdCBzdHJpbmdpZnkgb2JqZWN0cyB3aXRoIF9fcHJvdG9fXyBrZXlzXCIsYyxhLGUpO2MucHVzaChaKGIpKSxmKz1cXGAsXFwke0koYil9LFxcJHtpKG8uZ2V0KGEsYikpfVxcYCxjLnBvcCgpfWYrPVwiXVwifWVsc2V7Zj1cIntcIjtsZXQgYj0hMTtmb3IobGV0IG0gb2YgdS5rZXlzKXtpZihtPT09XCJfX3Byb3RvX19cIil0aHJvdyBuZXcgUyhcIkNhbm5vdCBzdHJpbmdpZnkgb2JqZWN0cyB3aXRoIF9fcHJvdG9fXyBrZXlzXCIsYyxhLGUpO2ImJihmKz1cIixcIiksYj0hMCxjLnB1c2goWihtKSksZis9XFxgXFwke0kobSl9OlxcJHtpKG8uZ2V0KGEsbSkpfVxcYCxjLnBvcCgpfWYrPVwifVwifX19fXJldHVybiBzW3ldPWYseX1sZXQgZD1pKGUpO3JldHVybiBkPDA/XFxgXFwke2R9XFxgOnN9ZnVuY3Rpb24gd3Iocil7bGV0IGU9dHlwZW9mIHI7cmV0dXJuIGU9PT1cInN0cmluZ1wiP0kocik6cj09PXZvaWQgMD8oLTEpLnRvU3RyaW5nKCk6cj09PTAmJjEvcjwwPygtNikudG9TdHJpbmcoKTplPT09XCJiaWdpbnRcIj9cXGBbXCJCaWdJbnRcIixcIlxcJHtyfVwiXVxcYDpTdHJpbmcocil9dmFyIFg9U3ltYm9sLmZvcihcIndvcmtmbG93LXNlcmlhbGl6ZVwiKSxxPVN5bWJvbC5mb3IoXCJ3b3JrZmxvdy1kZXNlcmlhbGl6ZVwiKTt2YXIgSj1TeW1ib2wuZm9yKFwid29ya2Zsb3ctY2xhc3MtcmVnaXN0cnlcIik7ZnVuY3Rpb24gaWUocj1nbG9iYWxUaGlzKXtsZXQgZT1yLHQ9ZVtKXTtyZXR1cm4gdHx8KHQ9bmV3IE1hcCxlW0pdPXQpLHR9ZnVuY3Rpb24gUShyLGUpe3JldHVybiBpZShlKS5nZXQocil9ZnVuY3Rpb24gUCgpe3JldHVybntDbGFzczpyPT57aWYodHlwZW9mIHIhPVwiZnVuY3Rpb25cIilyZXR1cm4hMTtsZXQgZT1yLmNsYXNzSWQ7cmV0dXJuIHR5cGVvZiBlIT1cInN0cmluZ1wiPyExOntjbGFzc0lkOmV9fSxJbnN0YW5jZTpyPT57aWYocj09PW51bGx8fHR5cGVvZiByIT1cIm9iamVjdFwiKXJldHVybiExO2xldCBlPXIuY29uc3RydWN0b3I7aWYoIWV8fHR5cGVvZiBlIT1cImZ1bmN0aW9uXCIpcmV0dXJuITE7bGV0IHQ9ZVtYXTtpZih0eXBlb2YgdCE9XCJmdW5jdGlvblwiKXJldHVybiExO2xldCBuPWUuY2xhc3NJZDtpZih0eXBlb2YgbiE9XCJzdHJpbmdcIil0aHJvdyBuZXcgRXJyb3IoXFxgQ2xhc3MgXCJcXCR7ZS5uYW1lfVwiIHdpdGggXFwke1N0cmluZyhYKX0gbXVzdCBoYXZlIGEgc3RhdGljIFwiY2xhc3NJZFwiIHByb3BlcnR5LlxcYCk7bGV0IG89dC5jYWxsKGUscik7cmV0dXJue2NsYXNzSWQ6bixkYXRhOm99fX19ZnVuY3Rpb24gQihyPWdsb2JhbFRoaXMpe3JldHVybntDbGFzczplPT57bGV0IHQ9ZS5jbGFzc0lkLG49USh0LHIpO2lmKCFuKXRocm93IG5ldyBFcnJvcihcXGBDbGFzcyBcIlxcJHt0fVwiIG5vdCBmb3VuZC4gTWFrZSBzdXJlIHRoZSBjbGFzcyBpcyByZWdpc3RlcmVkIHdpdGggcmVnaXN0ZXJTZXJpYWxpemF0aW9uQ2xhc3MuXFxgKTtyZXR1cm4gbn0sSW5zdGFuY2U6ZT0+e2xldCB0PWUuY2xhc3NJZCxuPWUuZGF0YSxvPVEodCxyKTtpZighbyl0aHJvdyBuZXcgRXJyb3IoXFxgQ2xhc3MgXCJcXCR7dH1cIiBub3QgZm91bmQuIE1ha2Ugc3VyZSB0aGUgY2xhc3MgaXMgcmVnaXN0ZXJlZCB3aXRoIHJlZ2lzdGVyU2VyaWFsaXphdGlvbkNsYXNzLlxcYCk7bGV0IHM9b1txXTtpZih0eXBlb2YgcyE9XCJmdW5jdGlvblwiKXRocm93IG5ldyBFcnJvcihcXGBDbGFzcyBcIlxcJHt0fVwiIGRvZXMgbm90IGhhdmUgYSBzdGF0aWMgXFwke1N0cmluZyhxKX0gbWV0aG9kLlxcYCk7cmV0dXJuIHMuY2FsbChvLG4pfX19ZnVuY3Rpb24gT3IocixlLHQpe2lmKHQ9PT0wKXJldHVyblwiLlwiO2xldCBuPW5ldyBVaW50OEFycmF5KHIsZSx0KSxvPVwiXCI7Zm9yKGxldCBzPTA7czxuLmxlbmd0aDtzKyspbys9U3RyaW5nLmZyb21DaGFyQ29kZShuW3NdKTtyZXR1cm4gYnRvYShvKX1mdW5jdGlvbiBSKHIpe3JldHVybiBPcihyLmJ1ZmZlcixyLmJ5dGVPZmZzZXQsci5ieXRlTGVuZ3RoKX1mdW5jdGlvbiBfKHIpe2lmKHI9PT1cIi5cIilyZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO2xldCBlPWF0b2IociksdD1uZXcgVWludDhBcnJheShlLmxlbmd0aCk7Zm9yKGxldCBuPTA7bjxlLmxlbmd0aDtuKyspdFtuXT1lLmNoYXJDb2RlQXQobik7cmV0dXJuIHQuYnVmZmVyfWZ1bmN0aW9uIGgocil7cmV0dXJuIGU9PntpZighKGUgaW5zdGFuY2VvZiBFcnJvcil8fGUubmFtZSE9PXIpcmV0dXJuITE7bGV0IHQ9e21lc3NhZ2U6ZS5tZXNzYWdlLHN0YWNrOmUuc3RhY2t9O3JldHVyblwiY2F1c2VcImluIGUmJih0LmNhdXNlPWUuY2F1c2UpLHR9fWZ1bmN0aW9uIE4ocil7cmV0dXJuIGU9PntsZXQgdD1nbG9iYWxUaGlzW3JdLG47cmV0dXJuIHR5cGVvZiB0PT1cImZ1bmN0aW9uXCI/bj1uZXcgdChlLm1lc3NhZ2UpOihuPW5ldyBFcnJvcihlLm1lc3NhZ2UpLG4ubmFtZT1yKSxlLnN0YWNrIT09dm9pZCAwJiYobi5zdGFjaz1lLnN0YWNrKSxcImNhdXNlXCJpbiBlJiYobi5jYXVzZT1lLmNhdXNlKSxufX1mdW5jdGlvbiBqKCl7cmV0dXJue0FycmF5QnVmZmVyOnI9PnIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlciYmT3IociwwLHIuYnl0ZUxlbmd0aCksQmlnSW50OnI9PnR5cGVvZiByPT1cImJpZ2ludFwiJiZyLnRvU3RyaW5nKCksQmlnSW50NjRBcnJheTpyPT5yIGluc3RhbmNlb2YgQmlnSW50NjRBcnJheSYmUihyKSxCaWdVaW50NjRBcnJheTpyPT5yIGluc3RhbmNlb2YgQmlnVWludDY0QXJyYXkmJlIociksRGF0ZTpyPT5yIGluc3RhbmNlb2YgRGF0ZT8hTnVtYmVyLmlzTmFOKHIuZ2V0RGF0ZSgpKT9yLnRvSVNPU3RyaW5nKCk6XCIuXCI6ITEsRE9NRXhjZXB0aW9uOnI9PntpZighKHIgaW5zdGFuY2VvZiBET01FeGNlcHRpb24pKXJldHVybiExO2xldCBlPXttZXNzYWdlOnIubWVzc2FnZSxuYW1lOnIubmFtZSxzdGFjazpyLnN0YWNrfTtyZXR1cm5cImNhdXNlXCJpbiByJiYoZS5jYXVzZT1yLmNhdXNlKSxlfSxBZ2dyZWdhdGVFcnJvcjpyPT57aWYoIShyIGluc3RhbmNlb2YgRXJyb3IpfHxyLm5hbWUhPT1cIkFnZ3JlZ2F0ZUVycm9yXCIpcmV0dXJuITE7bGV0IGU9e21lc3NhZ2U6ci5tZXNzYWdlLHN0YWNrOnIuc3RhY2ssZXJyb3JzOnIuZXJyb3JzfTtyZXR1cm5cImNhdXNlXCJpbiByJiYoZS5jYXVzZT1yLmNhdXNlKSxlfSxFdmFsRXJyb3I6aChcIkV2YWxFcnJvclwiKSxGYXRhbEVycm9yOmgoXCJGYXRhbEVycm9yXCIpLEhvb2tDb25mbGljdEVycm9yOnI9PntpZighKHIgaW5zdGFuY2VvZiBFcnJvcil8fHIubmFtZSE9PVwiSG9va0NvbmZsaWN0RXJyb3JcIilyZXR1cm4hMTtsZXQgZT17bWVzc2FnZTpyLm1lc3NhZ2Usc3RhY2s6ci5zdGFjayx0b2tlbjpyLnRva2VufTtyZXR1cm4gci5jb25mbGljdGluZ1J1bklkIT09dm9pZCAwJiYoZS5jb25mbGljdGluZ1J1bklkPXIuY29uZmxpY3RpbmdSdW5JZCksXCJjYXVzZVwiaW4gciYmKGUuY2F1c2U9ci5jYXVzZSksZX0sUmFuZ2VFcnJvcjpoKFwiUmFuZ2VFcnJvclwiKSxSZWZlcmVuY2VFcnJvcjpoKFwiUmVmZXJlbmNlRXJyb3JcIiksUmV0cnlhYmxlRXJyb3I6cj0+e2lmKCEociBpbnN0YW5jZW9mIEVycm9yKXx8ci5uYW1lIT09XCJSZXRyeWFibGVFcnJvclwiKXJldHVybiExO2xldCBlPXIucmV0cnlBZnRlcix0O2lmKGUmJnR5cGVvZiBlPT1cIm9iamVjdFwiJiZ0eXBlb2YgZS5nZXRUaW1lPT1cImZ1bmN0aW9uXCIpe2xldCBvPWUuZ2V0VGltZSgpO3Q9TnVtYmVyLmlzTmFOKG8pP0RhdGUubm93KCkrMWUzOm99ZWxzZSBpZih0eXBlb2YgZT09XCJzdHJpbmdcInx8dHlwZW9mIGU9PVwibnVtYmVyXCIpe2xldCBvPW5ldyBEYXRlKGUpLmdldFRpbWUoKTt0PU51bWJlci5pc05hTihvKT9EYXRlLm5vdygpKzFlMzpvfWVsc2UgdD1EYXRlLm5vdygpKzFlMztsZXQgbj17bWVzc2FnZTpyLm1lc3NhZ2Usc3RhY2s6ci5zdGFjayxyZXRyeUFmdGVyOnR9O3JldHVyblwiY2F1c2VcImluIHImJihuLmNhdXNlPXIuY2F1c2UpLG59LFJ1bnRpbWVEZWNyeXB0aW9uRXJyb3I6cj0+e2lmKCEociBpbnN0YW5jZW9mIEVycm9yKXx8ci5uYW1lIT09XCJSdW50aW1lRGVjcnlwdGlvbkVycm9yXCIpcmV0dXJuITE7bGV0IGU9e21lc3NhZ2U6ci5tZXNzYWdlLHN0YWNrOnIuc3RhY2t9LHQ9ci5jb250ZXh0O3JldHVybiB0IT09dm9pZCAwJiYoZS5jb250ZXh0PXQpLFwiY2F1c2VcImluIHImJihlLmNhdXNlPXIuY2F1c2UpLGV9LFN5bnRheEVycm9yOmgoXCJTeW50YXhFcnJvclwiKSxUeXBlRXJyb3I6aChcIlR5cGVFcnJvclwiKSxVUklFcnJvcjpoKFwiVVJJRXJyb3JcIiksRXJyb3I6cj0+e2lmKCEociBpbnN0YW5jZW9mIEVycm9yKSlyZXR1cm4hMTtsZXQgZT17bmFtZTpyLm5hbWUsbWVzc2FnZTpyLm1lc3NhZ2Usc3RhY2s6ci5zdGFja307cmV0dXJuXCJjYXVzZVwiaW4gciYmKGUuY2F1c2U9ci5jYXVzZSksZX0sRmxvYXQzMkFycmF5OnI9PnIgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkmJlIociksRmxvYXQ2NEFycmF5OnI9PnIgaW5zdGFuY2VvZiBGbG9hdDY0QXJyYXkmJlIociksSW50OEFycmF5OnI9PnIgaW5zdGFuY2VvZiBJbnQ4QXJyYXkmJlIociksSW50MTZBcnJheTpyPT5yIGluc3RhbmNlb2YgSW50MTZBcnJheSYmUihyKSxJbnQzMkFycmF5OnI9PnIgaW5zdGFuY2VvZiBJbnQzMkFycmF5JiZSKHIpLE1hcDpyPT5yIGluc3RhbmNlb2YgTWFwJiZBcnJheS5mcm9tKHIpLFJlZ0V4cDpyPT5yIGluc3RhbmNlb2YgUmVnRXhwJiZ7c291cmNlOnIuc291cmNlLGZsYWdzOnIuZmxhZ3N9LEhlYWRlcnM6cj0+e2xldCBlPWdsb2JhbFRoaXMuSGVhZGVycztyZXR1cm4hZXx8IShyIGluc3RhbmNlb2YgZSk/ITE6QXJyYXkuZnJvbShyKX0sUmVxdWVzdDpyPT57bGV0IGU9Z2xvYmFsVGhpcy5SZXF1ZXN0O2lmKCFlfHwhKHIgaW5zdGFuY2VvZiBlKSYmdHlwZW9mIHI/Lmpzb24hPVwiZnVuY3Rpb25cInx8dHlwZW9mIHI/Lm1ldGhvZCE9XCJzdHJpbmdcIilyZXR1cm4hMTtsZXQgdD17bWV0aG9kOnIubWV0aG9kLHVybDpyLnVybCxoZWFkZXJzOnIuaGVhZGVycyxib2R5OnIuYm9keSxkdXBsZXg6ci5kdXBsZXh9LG49cltTeW1ib2wuZm9yKFwiV0VCSE9PS19SRVNQT05TRV9XUklUQUJMRVwiKV07cmV0dXJuIG4mJih0LnJlc3BvbnNlV3JpdGFibGU9biksdH0sUmVzcG9uc2U6cj0+e2xldCBlPWdsb2JhbFRoaXMuUmVzcG9uc2U7cmV0dXJuIWV8fCEociBpbnN0YW5jZW9mIGUpJiZ0eXBlb2Ygcj8uY2xvbmUhPVwiZnVuY3Rpb25cInx8dHlwZW9mIHI/LnN0YXR1cyE9XCJudW1iZXJcIj8hMTp7dHlwZTpyLnR5cGUsdXJsOnIudXJsLHN0YXR1czpyLnN0YXR1cyxzdGF0dXNUZXh0OnIuc3RhdHVzVGV4dCxoZWFkZXJzOnIuaGVhZGVycyxib2R5OnIuYm9keSxyZWRpcmVjdGVkOnIucmVkaXJlY3RlZH19LFJlYWRhYmxlU3RyZWFtOihyPT57aWYocj09bnVsbClyZXR1cm4hMTtsZXQgZT1nbG9iYWxUaGlzLlJlYWRhYmxlU3RyZWFtO2lmKCFlfHwhKHIgaW5zdGFuY2VvZiBlfHxPYmplY3QuZ2V0UHJvdG90eXBlT2Yocik9PT1lLnByb3RvdHlwZSkpcmV0dXJuITE7bGV0IHQ9cltTeW1ib2wuZm9yKFwiQk9EWV9JTklUXCIpXTtpZih0IT09dm9pZCAwKXJldHVybntib2R5SW5pdDp0fTtsZXQgbj1yW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19TVFJFQU1fTkFNRVwiKV07aWYobil7bGV0IG89e25hbWU6bn0scz1yW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19TVFJFQU1fVFlQRVwiKV07cyYmKG8udHlwZT1zKTtsZXQgcD1yW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19TVFJFQU1fRlJBTUlOR1wiKV07cmV0dXJuIHAmJihvLmZyYW1pbmc9cCksb31yZXR1cm57bmFtZTpcIl9fZW1wdHlcIn19KSxXcml0YWJsZVN0cmVhbToocj0+e2lmKHI9PW51bGwpcmV0dXJuITE7bGV0IGU9Z2xvYmFsVGhpcy5Xcml0YWJsZVN0cmVhbTtpZighZXx8IShyIGluc3RhbmNlb2YgZXx8T2JqZWN0LmdldFByb3RvdHlwZU9mKHIpPT09ZS5wcm90b3R5cGUpKXJldHVybiExO2xldCBuPXtuYW1lOnJbU3ltYm9sLmZvcihcIldPUktGTE9XX1NUUkVBTV9OQU1FXCIpXXx8XCJfX2VtcHR5XCJ9LG89cltTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RSRUFNX1NFUlZFUl9SVU5fSURcIildO3R5cGVvZiBvPT1cInN0cmluZ1wiJiYobi5ydW5JZD1vKTtsZXQgcz1yW1N5bWJvbC5mb3IoXCJXT1JLRkxPV19TVFJFQU1fU0VSVkVSX0RFUExPWU1FTlRfSURcIildO3JldHVybiB0eXBlb2Ygcz09XCJzdHJpbmdcIiYmKG4uZGVwbG95bWVudElkPXMpLG59KSxTZXQ6cj0+ciBpbnN0YW5jZW9mIFNldCYmQXJyYXkuZnJvbShyKSxVUkw6cj0+ciBpbnN0YW5jZW9mIFVSTCYmci5ocmVmLFdvcmtmbG93RnVuY3Rpb246cj0+e2lmKHR5cGVvZiByIT1cImZ1bmN0aW9uXCIpcmV0dXJuITE7bGV0IGU9ci53b3JrZmxvd0lkO3JldHVybiB0eXBlb2YgZSE9XCJzdHJpbmdcIj8hMTp7d29ya2Zsb3dJZDplfX0sVVJMU2VhcmNoUGFyYW1zOnI9PnIgaW5zdGFuY2VvZiBVUkxTZWFyY2hQYXJhbXM/ci5zaXplPT09MD9cIi5cIjpTdHJpbmcocik6ITEsVWludDhBcnJheTpyPT5yIGluc3RhbmNlb2YgVWludDhBcnJheSYmUihyKSxVaW50OENsYW1wZWRBcnJheTpyPT5yIGluc3RhbmNlb2YgVWludDhDbGFtcGVkQXJyYXkmJlIociksVWludDE2QXJyYXk6cj0+ciBpbnN0YW5jZW9mIFVpbnQxNkFycmF5JiZSKHIpLFVpbnQzMkFycmF5OnI9PnIgaW5zdGFuY2VvZiBVaW50MzJBcnJheSYmUihyKX19ZnVuY3Rpb24gSygpe3JldHVybntBcnJheUJ1ZmZlcjpyPT5fKHIpLEJpZ0ludDpyPT5CaWdJbnQociksQmlnSW50NjRBcnJheTpyPT5uZXcgQmlnSW50NjRBcnJheShfKHIpKSxCaWdVaW50NjRBcnJheTpyPT5uZXcgQmlnVWludDY0QXJyYXkoXyhyKSksRGF0ZTpyPT5uZXcgRGF0ZShyKSxET01FeGNlcHRpb246cj0+e2xldCBlPW5ldyBET01FeGNlcHRpb24oci5tZXNzYWdlLHIubmFtZSk7cmV0dXJuIHIuc3RhY2shPT12b2lkIDAmJihlLnN0YWNrPXIuc3RhY2spLFwiY2F1c2VcImluIHImJihlLmNhdXNlPXIuY2F1c2UpLGV9LEFnZ3JlZ2F0ZUVycm9yOnI9PntsZXQgZT1uZXcgQWdncmVnYXRlRXJyb3Ioci5lcnJvcnM/P1tdLHIubWVzc2FnZSk7cmV0dXJuIHIuc3RhY2shPT12b2lkIDAmJihlLnN0YWNrPXIuc3RhY2spLFwiY2F1c2VcImluIHImJihlLmNhdXNlPXIuY2F1c2UpLGV9LEV2YWxFcnJvcjpOKFwiRXZhbEVycm9yXCIpLEZhdGFsRXJyb3I6cj0+e2xldCBlPWdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIkB3b3JrZmxvdy9lcnJvcnMvL0ZhdGFsRXJyb3JcIildLHQ7cmV0dXJuIHR5cGVvZiBlPT1cImZ1bmN0aW9uXCI/dD1uZXcgZShyLm1lc3NhZ2UpOih0PW5ldyBFcnJvcihyLm1lc3NhZ2UpLHQubmFtZT1cIkZhdGFsRXJyb3JcIiksci5zdGFjayE9PXZvaWQgMCYmKHQuc3RhY2s9ci5zdGFjayksXCJjYXVzZVwiaW4gciYmKHQuY2F1c2U9ci5jYXVzZSksdH0sSG9va0NvbmZsaWN0RXJyb3I6cj0+e2xldCBlPWdsb2JhbFRoaXNbU3ltYm9sLmZvcihcIkB3b3JrZmxvdy9lcnJvcnMvL0hvb2tDb25mbGljdEVycm9yXCIpXSx0O3JldHVybiB0eXBlb2YgZT09XCJmdW5jdGlvblwiP3Q9bmV3IGUoci50b2tlbixyLmNvbmZsaWN0aW5nUnVuSWQpOih0PW5ldyBFcnJvcihyLm1lc3NhZ2UpLHQubmFtZT1cIkhvb2tDb25mbGljdEVycm9yXCIsdC50b2tlbj1yLnRva2VuLHIuY29uZmxpY3RpbmdSdW5JZCE9PXZvaWQgMCYmKHQuY29uZmxpY3RpbmdSdW5JZD1yLmNvbmZsaWN0aW5nUnVuSWQpKSxyLnN0YWNrIT09dm9pZCAwJiYodC5zdGFjaz1yLnN0YWNrKSxcImNhdXNlXCJpbiByJiYodC5jYXVzZT1yLmNhdXNlKSx0fSxSYW5nZUVycm9yOk4oXCJSYW5nZUVycm9yXCIpLFJlZmVyZW5jZUVycm9yOk4oXCJSZWZlcmVuY2VFcnJvclwiKSxSZXRyeWFibGVFcnJvcjpyPT57bGV0IGU9Z2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwiQHdvcmtmbG93L2Vycm9ycy8vUmV0cnlhYmxlRXJyb3JcIildLHQ9bmV3IERhdGUoci5yZXRyeUFmdGVyKSxuO3JldHVybiB0eXBlb2YgZT09XCJmdW5jdGlvblwiP249bmV3IGUoci5tZXNzYWdlLHtyZXRyeUFmdGVyOnR9KToobj1uZXcgRXJyb3Ioci5tZXNzYWdlKSxuLm5hbWU9XCJSZXRyeWFibGVFcnJvclwiLG4ucmV0cnlBZnRlcj10KSxyLnN0YWNrIT09dm9pZCAwJiYobi5zdGFjaz1yLnN0YWNrKSxcImNhdXNlXCJpbiByJiYobi5jYXVzZT1yLmNhdXNlKSxufSxSdW50aW1lRGVjcnlwdGlvbkVycm9yOnI9PntsZXQgZT1nbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJAd29ya2Zsb3cvZXJyb3JzLy9SdW50aW1lRGVjcnlwdGlvbkVycm9yXCIpXSx0O2lmKHR5cGVvZiBlPT1cImZ1bmN0aW9uXCIpe2xldCBuPXt9O1wiY2F1c2VcImluIHImJihuLmNhdXNlPXIuY2F1c2UpLHIuY29udGV4dCE9PXZvaWQgMCYmKG4uY29udGV4dD1yLmNvbnRleHQpLHQ9bmV3IGUoci5tZXNzYWdlLG4pfWVsc2UgdD1uZXcgRXJyb3Ioci5tZXNzYWdlKSx0Lm5hbWU9XCJSdW50aW1lRGVjcnlwdGlvbkVycm9yXCIsci5jb250ZXh0IT09dm9pZCAwJiYodC5jb250ZXh0PXIuY29udGV4dCksXCJjYXVzZVwiaW4gciYmKHQuY2F1c2U9ci5jYXVzZSk7cmV0dXJuIHIuc3RhY2shPT12b2lkIDAmJih0LnN0YWNrPXIuc3RhY2spLHR9LFN5bnRheEVycm9yOk4oXCJTeW50YXhFcnJvclwiKSxUeXBlRXJyb3I6TihcIlR5cGVFcnJvclwiKSxVUklFcnJvcjpOKFwiVVJJRXJyb3JcIiksRXJyb3I6cj0+e2xldCBlPW5ldyBFcnJvcihyLm1lc3NhZ2UpO3JldHVybiBlLm5hbWU9ci5uYW1lLHIuc3RhY2shPT12b2lkIDAmJihlLnN0YWNrPXIuc3RhY2spLFwiY2F1c2VcImluIHImJihlLmNhdXNlPXIuY2F1c2UpLGV9LEZsb2F0MzJBcnJheTpyPT5uZXcgRmxvYXQzMkFycmF5KF8ocikpLEZsb2F0NjRBcnJheTpyPT5uZXcgRmxvYXQ2NEFycmF5KF8ocikpLEludDhBcnJheTpyPT5uZXcgSW50OEFycmF5KF8ocikpLEludDE2QXJyYXk6cj0+bmV3IEludDE2QXJyYXkoXyhyKSksSW50MzJBcnJheTpyPT5uZXcgSW50MzJBcnJheShfKHIpKSxNYXA6cj0+bmV3IE1hcChyKSxSZWdFeHA6cj0+bmV3IFJlZ0V4cChyLnNvdXJjZSxyLmZsYWdzKSxTZXQ6cj0+bmV3IFNldChyKSxVUkw6cj0+bmV3IFVSTChyKSxXb3JrZmxvd0Z1bmN0aW9uOnI9Pk9iamVjdC5hc3NpZ24oKCk9Pnt0aHJvdyBuZXcgRXJyb3IoXCJXb3JrZmxvdyBmdW5jdGlvbnMgY2Fubm90IGJlIGNhbGxlZCBkaXJlY3RseS4gVXNlIHN0YXJ0KCkgdG8gaW52b2tlIHRoZW0uXCIpfSx7d29ya2Zsb3dJZDpyLndvcmtmbG93SWR9KSxVUkxTZWFyY2hQYXJhbXM6cj0+bmV3IFVSTFNlYXJjaFBhcmFtcyhyPT09XCIuXCI/XCJcIjpyKSxVaW50OEFycmF5OnI9Pm5ldyBVaW50OEFycmF5KF8ocikpLFVpbnQ4Q2xhbXBlZEFycmF5OnI9Pm5ldyBVaW50OENsYW1wZWRBcnJheShfKHIpKSxVaW50MTZBcnJheTpyPT5uZXcgVWludDE2QXJyYXkoXyhyKSksVWludDMyQXJyYXk6cj0+bmV3IFVpbnQzMkFycmF5KF8ocikpLEhlYWRlcnM6cj0+bmV3IGdsb2JhbFRoaXMuSGVhZGVycyhyKSxSZXF1ZXN0OnI9PntsZXQgZT1nbG9iYWxUaGlzLlJlcXVlc3Q7cmV0dXJuIGUmJihyLmpzb249ZS5wcm90b3R5cGUuanNvbixyLnRleHQ9ZS5wcm90b3R5cGUudGV4dCxyLmFycmF5QnVmZmVyPWUucHJvdG90eXBlLmFycmF5QnVmZmVyKSxyLnJlc3BvbnNlV3JpdGFibGUmJihyW1N5bWJvbC5mb3IoXCJXRUJIT09LX1JFU1BPTlNFX1dSSVRBQkxFXCIpXT1yLnJlc3BvbnNlV3JpdGFibGUpLHJ9LFJlc3BvbnNlOnI9PntsZXQgZT1nbG9iYWxUaGlzLlJlc3BvbnNlO3JldHVybiBlJiYoci5qc29uPWUucHJvdG90eXBlLmpzb24sci50ZXh0PWUucHJvdG90eXBlLnRleHQsci5hcnJheUJ1ZmZlcj1lLnByb3RvdHlwZS5hcnJheUJ1ZmZlcixlLnByb3RvdHlwZS5ieXRlcyYmKHIuYnl0ZXM9ZS5wcm90b3R5cGUuYnl0ZXMpLGUucHJvdG90eXBlLmNsb25lJiYoci5jbG9uZT1lLnByb3RvdHlwZS5jbG9uZSkpLHIuX2JvZHk9ci5ib2R5LHIub2s9ci5zdGF0dXM+PTIwMCYmci5zdGF0dXM8MzAwLHIuYm9keVVzZWQ9ITEscn0sUmVhZGFibGVTdHJlYW06cj0+e2xldCBlPWdsb2JhbFRoaXMuUmVhZGFibGVTdHJlYW0sdD1PYmplY3QuY3JlYXRlKGU/ZS5wcm90b3R5cGU6e30pO3JldHVybiByJiZcImJvZHlJbml0XCJpbiByP3RbU3ltYm9sLmZvcihcIkJPRFlfSU5JVFwiKV09ci5ib2R5SW5pdDpyJiZcIm5hbWVcImluIHImJih0W1N5bWJvbC5mb3IoXCJXT1JLRkxPV19TVFJFQU1fTkFNRVwiKV09ci5uYW1lLHIudHlwZSYmKHRbU3ltYm9sLmZvcihcIldPUktGTE9XX1NUUkVBTV9UWVBFXCIpXT1yLnR5cGUpLHIuZnJhbWluZyYmKHRbU3ltYm9sLmZvcihcIldPUktGTE9XX1NUUkVBTV9GUkFNSU5HXCIpXT1yLmZyYW1pbmcpKSx0fSxXcml0YWJsZVN0cmVhbTpyPT57bGV0IGU9Z2xvYmFsVGhpcy5Xcml0YWJsZVN0cmVhbSx0PU9iamVjdC5jcmVhdGUoZT9lLnByb3RvdHlwZTp7fSk7cmV0dXJuIHImJlwibmFtZVwiaW4gciYmKHRbU3ltYm9sLmZvcihcIldPUktGTE9XX1NUUkVBTV9OQU1FXCIpXT1yLm5hbWUpLHImJnR5cGVvZiByLnJ1bklkPT1cInN0cmluZ1wiJiYodFtTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RSRUFNX1NFUlZFUl9SVU5fSURcIildPXIucnVuSWQpLHImJnR5cGVvZiByLmRlcGxveW1lbnRJZD09XCJzdHJpbmdcIiYmKHRbU3ltYm9sLmZvcihcIldPUktGTE9XX1NUUkVBTV9TRVJWRVJfREVQTE9ZTUVOVF9JRFwiKV09ci5kZXBsb3ltZW50SWQpLHR9fX1mdW5jdGlvbiBJcigpe3JldHVybntTdGVwRnVuY3Rpb246cj0+e2lmKHR5cGVvZiByIT1cImZ1bmN0aW9uXCIpcmV0dXJuITE7bGV0IGU9ci5zdGVwSWQ7aWYodHlwZW9mIGUhPVwic3RyaW5nXCIpcmV0dXJuITE7bGV0IHQ9ci5fX2Nsb3N1cmVWYXJzRm4sbj10JiZ0eXBlb2YgdD09XCJmdW5jdGlvblwiP3QoKTp2b2lkIDAsbz1cIl9fYm91bmRUaGlzXCJpbiByLHM9bz9yLl9fYm91bmRUaGlzOnZvaWQgMCxwPXIuX19ib3VuZEFyZ3MsZz17c3RlcElkOmV9O3JldHVybiBuIT09dm9pZCAwJiYoZy5jbG9zdXJlVmFycz1uKSxvJiYoZy5ib3VuZFRoaXM9cyksQXJyYXkuaXNBcnJheShwKSYmcC5sZW5ndGg+MCYmKGcuYm91bmRBcmdzPXApLGd9fX1mdW5jdGlvbiBUcihyPWdsb2JhbFRoaXMpe2xldCBlPXJbU3ltYm9sLmZvcihcIldPUktGTE9XX1VTRV9TVEVQXCIpXTtyZXR1cm57U3RlcEZ1bmN0aW9uOnQ9PntsZXQgbj10LnN0ZXBJZCxvPXQuY2xvc3VyZVZhcnM7aWYoIWUpdGhyb3cgbmV3IEVycm9yKFwiV09SS0ZMT1dfVVNFX1NURVAgbm90IGZvdW5kIG9uIGdsb2JhbCBvYmplY3QuIFN0ZXAgZnVuY3Rpb25zIGNhbm5vdCBiZSBkZXNlcmlhbGl6ZWQgb3V0c2lkZSB3b3JrZmxvdyBjb250ZXh0LlwiKTtsZXQgcz1vP2UobiwoKT0+byk6ZShuKTtpZihcImJvdW5kVGhpc1wiaW4gdCl7bGV0IHA9QXJyYXkuaXNBcnJheSh0LmJvdW5kQXJncyk/dC5ib3VuZEFyZ3M6W107cmV0dXJuIHMuYmluZCh0LmJvdW5kVGhpcywuLi5wKX1yZXR1cm4gc319fWZ1bmN0aW9uIGtyKHIpe3JldHVybiByLmxlbmd0aD09PTQmJi9eW2EtejAtOV17NH0kLy50ZXN0KHIpfXZhciBVPXtERVZBTFVFX1YxOlwiZGV2bFwiLEVOQ1JZUFRFRDpcImVuY3JcIixTRUFMRUQ6XCJlbmNwXCIsR1pJUDpcImd6aXBcIixaU1REOlwienN0ZFwifTt2YXIgY2U9bmV3IFRleHRFbmNvZGVyLGZlPW5ldyBUZXh0RGVjb2RlcixMPVN5bWJvbC5mb3IoXCJXT1JLRkxPV19BQk9SVF9TVFJFQU1fTkFNRVwiKSx2PVN5bWJvbC5mb3IoXCJXT1JLRkxPV19BQk9SVF9IT09LX1RPS0VOXCIpO2Z1bmN0aW9uIGhyKHIsZSl7bGV0IHQ9ZVtMXT8/ZS5zaWduYWw/LltMXSxuPWVbdl0/P2Uuc2lnbmFsPy5bdl07aWYoIXQpdGhyb3cgbmV3IEVycm9yKFwiQWJvcnRDb250cm9sbGVyL0Fib3J0U2lnbmFsIHN0cmVhbSBuYW1lIGlzIG5vdCBzZXRcIik7cmV0dXJue3N0cmVhbU5hbWU6dCxob29rVG9rZW46bixhYm9ydGVkOnIuYWJvcnRlZCxyZWFzb246ci5hYm9ydGVkP3IucmVhc29uOnZvaWQgMH19ZnVuY3Rpb24gTnIocil7bGV0IGU9Z2xvYmFsVGhpcy5fX1dvcmtmbG93QWJvcnRTaWduYWw7aWYodHlwZW9mIGUhPVwiZnVuY3Rpb25cIil0aHJvdyBuZXcgRXJyb3IoXCJXb3JrZmxvd0Fib3J0U2lnbmFsIGlzIG5vdCByZWdpc3RlcmVkIGluIHRoZSBWTSAoYm9vdHN0cmFwIG5vdCBldmFsdWF0ZWQpXCIpO2xldCB0PW5ldyBlKHIuc3RyZWFtTmFtZSxyLmhvb2tUb2tlbik7cmV0dXJuIHIuYWJvcnRlZCYmdC5fc2V0QWJvcnRlZChyLnJlYXNvbiksdH1mdW5jdGlvbiB5ZSgpe3JldHVybntBYm9ydENvbnRyb2xsZXI6cj0+IXJ8fHR5cGVvZiByIT1cIm9iamVjdFwifHwhci5zaWduYWx8fChyW0xdPz9yLnNpZ25hbD8uW0xdKT09PXZvaWQgMD8hMTpocihyLnNpZ25hbCxyKSxBYm9ydFNpZ25hbDpyPT4hcnx8dHlwZW9mIHIhPVwib2JqZWN0XCJ8fHJbTF09PT12b2lkIDA/ITE6aHIocixyKX19ZnVuY3Rpb24gbGUoKXtyZXR1cm57QWJvcnRDb250cm9sbGVyOnI9Pih7W0xdOnIuc3RyZWFtTmFtZSxbdl06ci5ob29rVG9rZW4sc2lnbmFsOk5yKHIpLGFib3J0OigpPT57fX0pLEFib3J0U2lnbmFsOnI9Pk5yKHIpfX1mdW5jdGlvbiB1ZShyKXtzd2l0Y2gocil7Y2FzZVwid29ya2Zsb3dcIjpyZXR1cm57Li4ueWUoKSwuLi5QKCksLi4uSXIoKSwuLi5qKCl9O2Nhc2VcInN0ZXBcIjpyZXR1cm57Li4uUCgpLC4uLmooKX07Y2FzZVwiY2xpZW50XCI6cmV0dXJuey4uLlAoKSwuLi5qKCl9fX1mdW5jdGlvbiBMcihyKXtzd2l0Y2gocil7Y2FzZVwid29ya2Zsb3dcIjpyZXR1cm57Li4ubGUoKSwuLi5CKCksLi4uVHIoKSwuLi5LKCl9O2Nhc2VcInN0ZXBcIjpyZXR1cm57Li4uQigpLC4uLksoKX07Y2FzZVwiY2xpZW50XCI6cmV0dXJuey4uLkIoKSwuLi5LKCksU3RlcEZ1bmN0aW9uOigpPT57dGhyb3cgbmV3IEVycm9yKFwiU3RlcCBmdW5jdGlvbnMgY2Fubm90IGJlIGRlc2VyaWFsaXplZCBpbiBjbGllbnQgY29udGV4dC5cIil9fX19dmFyIEY9e2Zvcm1hdFByZWZpeDpVLkRFVkFMVUVfVjEsc2VyaWFsaXplKHIsZSl7bGV0IHQ9dWUoZSksbj1IKHIsdCk7cmV0dXJuIGNlLmVuY29kZShuKX0sZGVzZXJpYWxpemUocixlKXtsZXQgdD1McihlKSxuPWZlLmRlY29kZShyKTtyZXR1cm4gRyhuLHQpfSxkZXNlcmlhbGl6ZUxlZ2FjeShyLGUpe2xldCB0PUxyKGUpO3JldHVybiBDKHIsdCl9fTt2YXIgcnI9NCxlcix0cjtmdW5jdGlvbiBwZSgpe3JldHVybiBlcnx8KGVyPW5ldyBnbG9iYWxUaGlzLlRleHRFbmNvZGVyKSxlcn1mdW5jdGlvbiBnZSgpe3JldHVybiB0cnx8KHRyPW5ldyBnbG9iYWxUaGlzLlRleHREZWNvZGVyKSx0cn1mdW5jdGlvbiBNcihyKXtsZXQgZT1GLnNlcmlhbGl6ZShyLFwid29ya2Zsb3dcIiksdD1wZSgpLmVuY29kZShVLkRFVkFMVUVfVjEpLG49bmV3IFVpbnQ4QXJyYXkodC5sZW5ndGgrZS5sZW5ndGgpO3JldHVybiBuLnNldCh0LDApLG4uc2V0KGUsdC5sZW5ndGgpLG59ZnVuY3Rpb24geHIocil7aWYoIShyIGluc3RhbmNlb2YgVWludDhBcnJheSkpe2lmKEYuZGVzZXJpYWxpemVMZWdhY3kpcmV0dXJuIEYuZGVzZXJpYWxpemVMZWdhY3kocixcIndvcmtmbG93XCIpO3Rocm93IG5ldyBFcnJvcihcIkNhbm5vdCBkZXNlcmlhbGl6ZSBub24tYmluYXJ5IGRhdGEgd2l0aG91dCBsZWdhY3kgc3VwcG9ydFwiKX1pZihyLmxlbmd0aDxycil0aHJvdyBuZXcgRXJyb3IoXCJEYXRhIHRvbyBzaG9ydCB0byBjb250YWluIGZvcm1hdCBwcmVmaXhcIik7bGV0IGU9Z2UoKS5kZWNvZGUoci5zdWJhcnJheSgwLHJyKSk7aWYoIWtyKGUpKXRocm93IG5ldyBFcnJvcihcXGBJbnZhbGlkIGZvcm1hdCBwcmVmaXg6IFwiXFwke2V9XCJcXGApO2lmKGU9PT1VLkRFVkFMVUVfVjEpe2xldCB0PXIuc3ViYXJyYXkocnIpO3JldHVybiBGLmRlc2VyaWFsaXplKHQsXCJ3b3JrZmxvd1wiKX10aHJvdyBuZXcgRXJyb3IoXFxgVW5zdXBwb3J0ZWQgc2VyaWFsaXphdGlvbiBmb3JtYXQ6IFxcJHtlfVxcYCl9Z2xvYmFsVGhpc1tTeW1ib2wuZm9yKFwid29ya2Zsb3ctc2VyaWFsaXplXCIpXT1NcjtnbG9iYWxUaGlzW1N5bWJvbC5mb3IoXCJ3b3JrZmxvdy1kZXNlcmlhbGl6ZVwiKV09eHI7dmFyIGRlPWlyKCgpPT5NYXRoLnJhbmRvbSgpKTtnbG9iYWxUaGlzLl9fZ2VuZXJhdGVVbGlkPSgpPT57bGV0IHI9Z2xvYmFsVGhpcy5fX3VsaWRUaW1lc3RhbXA7aWYodHlwZW9mIHIhPVwibnVtYmVyXCIpdGhyb3cgbmV3IEVycm9yKFwiX19nZW5lcmF0ZVVsaWQ6IGdsb2JhbFRoaXMuX191bGlkVGltZXN0YW1wIG11c3QgYmUgYSBudW1iZXIgc2V0IGJ5IHRoZSBob3N0IGJlZm9yZSB0aGUgc2VyZGUgYnVuZGxlIGlzIGV2YWx1YXRlZC4gV2l0aG91dCBpdCwgVUxJRHMgd291bGQgZmFsbCBiYWNrIHRvIERhdGUubm93KCkgYW5kIGNvbmN1cnJlbnQgd29ya2Zsb3cgaW52b2NhdGlvbnMgb2YgdGhlIHNhbWUgcmVzdW1wdGlvbiB3b3VsZCBwcm9kdWNlIGRpdmVyZ2VudCBjb3JyZWxhdGlvbklkcy5cIik7cmV0dXJuIGRlKHIpfTt9KSgpO1xuYDtcbiJdfQ==
|
|
@@ -0,0 +1,106 @@
|
|
|
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) 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
|
+
*
|
|
54
|
+
* That last case used to be the one hole in the scheme, and it was not
|
|
55
|
+
* theoretical. Any delivery early enough to re-observe its own wait as
|
|
56
|
+
* pending burns the bare key on the way in: the re-enqueue is dropped by
|
|
57
|
+
* the dedupe window, nothing else is scheduled to wake the run, and no
|
|
58
|
+
* backstop exists for a wait the way inline step ownership provides one
|
|
59
|
+
* for a step. The run sleeps forever. Waits over the threshold have zero
|
|
60
|
+
* tolerance for it, which is why an infrastructure change in delivery
|
|
61
|
+
* timing was able to strand runs across every published SDK version at
|
|
62
|
+
* once, all of them keyed this way.
|
|
63
|
+
*
|
|
64
|
+
* So the key is no longer derived from the wait alone. A continuation
|
|
65
|
+
* carries the wait it was armed for and its attempt number
|
|
66
|
+
* ({@link WorkflowInvokePayload.waitContinuation}), and an invocation
|
|
67
|
+
* that recognizes itself as the continuation for a wait that is still
|
|
68
|
+
* pending arms the next one at `attempt + 1`. Attempts advance ONLY when
|
|
69
|
+
* an early delivery actually happens, so the normal path is untouched:
|
|
70
|
+
* attempt 0 keys exactly as before, and every re-observation within one
|
|
71
|
+
* attempt still collapses to a single message.
|
|
72
|
+
*/
|
|
73
|
+
/**
|
|
74
|
+
* Maximum `delaySeconds` for a single wait-continuation message. Waits
|
|
75
|
+
* longer than this are chained across multiple hops. 23 hours leaves a 1h
|
|
76
|
+
* buffer under Vercel Queues' default 24h message TTL and mirrors
|
|
77
|
+
* world-vercel's `MAX_DELAY_SECONDS`.
|
|
78
|
+
*/
|
|
79
|
+
export declare const WAIT_CONTINUATION_MAX_DELAY_SECONDS = 82800;
|
|
80
|
+
/**
|
|
81
|
+
* Waits with at most this many seconds remaining use a second-bucketed
|
|
82
|
+
* idempotency key so an early-delivered continuation can re-enqueue its
|
|
83
|
+
* short-delay retry. This is also the host clock-skew tolerance for
|
|
84
|
+
* mid-range waits keyed on the bare correlationId.
|
|
85
|
+
*/
|
|
86
|
+
export declare const NEAR_ELAPSED_WAIT_THRESHOLD_SECONDS = 2;
|
|
87
|
+
export interface WaitContinuationDispatch {
|
|
88
|
+
delaySeconds: number;
|
|
89
|
+
idempotencyKey: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Computes the queue delay and idempotency key for a wait-continuation
|
|
93
|
+
* message. `timeoutSeconds` is the time until the wait's `resumeAt`
|
|
94
|
+
* (floored at 1s by the suspension handler); `waitCorrelationId`
|
|
95
|
+
* identifies the wait so repeated suspension passes dedupe.
|
|
96
|
+
*
|
|
97
|
+
* `attempt` is the number of continuations already spent on this wait, taken
|
|
98
|
+
* from the incoming message when this invocation IS one of them (see
|
|
99
|
+
* {@link WorkflowInvokePayload.waitContinuation}). It only ever moves when a
|
|
100
|
+
* continuation arrived before its wait elapsed, which is exactly when the
|
|
101
|
+
* previous key is spent and re-using it would drop the message. Attempt 0
|
|
102
|
+
* keys identically to the scheme before attempts existed, so the ordinary
|
|
103
|
+
* path — arm once, deliver once, complete — is byte-for-byte unchanged.
|
|
104
|
+
*/
|
|
105
|
+
export declare function getWaitContinuationDispatch(timeoutSeconds: number, waitCorrelationId: string, now?: number, attempt?: number): WaitContinuationDispatch;
|
|
106
|
+
//# 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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AAIH;;;;;GAKG;AACH,eAAO,MAAM,mCAAmC,QAAS,CAAC;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,mCAAmC,IAAI,CAAC;AAiBrD,MAAM,WAAW,wBAAwB;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,2BAA2B,CACzC,cAAc,EAAE,MAAM,EACtB,iBAAiB,EAAE,MAAM,EACzB,GAAG,GAAE,MAAmB,EACxB,OAAO,SAAI,GACV,wBAAwB,CAW1B"}
|