@workflow/core 5.0.0-beta.41 → 5.0.0-beta.42

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.
Files changed (47) hide show
  1. package/dist/events-consumer.d.ts +97 -0
  2. package/dist/events-consumer.d.ts.map +1 -1
  3. package/dist/events-consumer.js +147 -14
  4. package/dist/private.d.ts.map +1 -1
  5. package/dist/private.js +3 -4
  6. package/dist/runtime/constants.d.ts +35 -0
  7. package/dist/runtime/constants.d.ts.map +1 -1
  8. package/dist/runtime/constants.js +38 -1
  9. package/dist/runtime/helpers.d.ts +127 -93
  10. package/dist/runtime/helpers.d.ts.map +1 -1
  11. package/dist/runtime/helpers.js +149 -132
  12. package/dist/runtime/quickjs-entrypoint.d.ts +8 -9
  13. package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -1
  14. package/dist/runtime/quickjs-entrypoint.js +160 -37
  15. package/dist/runtime/replay-budget.d.ts +8 -0
  16. package/dist/runtime/replay-budget.d.ts.map +1 -1
  17. package/dist/runtime/replay-budget.js +3 -3
  18. package/dist/runtime/resume-hook.d.ts.map +1 -1
  19. package/dist/runtime/resume-hook.js +53 -13
  20. package/dist/runtime/resume-latency.d.ts +143 -0
  21. package/dist/runtime/resume-latency.d.ts.map +1 -0
  22. package/dist/runtime/resume-latency.js +153 -0
  23. package/dist/runtime/step-executor.d.ts +27 -12
  24. package/dist/runtime/step-executor.d.ts.map +1 -1
  25. package/dist/runtime/step-executor.js +105 -12
  26. package/dist/runtime/suspension-handler.d.ts +39 -8
  27. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  28. package/dist/runtime/suspension-handler.js +147 -36
  29. package/dist/runtime/world-compatibility.d.ts +6 -5
  30. package/dist/runtime/world-compatibility.d.ts.map +1 -1
  31. package/dist/runtime/world-compatibility.js +7 -6
  32. package/dist/runtime.d.ts.map +1 -1
  33. package/dist/runtime.js +459 -128
  34. package/dist/serialization/codec-devalue.d.ts.map +1 -1
  35. package/dist/serialization/codec-devalue.js +15 -4
  36. package/dist/serialization.d.ts.map +1 -1
  37. package/dist/serialization.js +8 -3
  38. package/dist/telemetry/semantic-conventions.d.ts +81 -0
  39. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  40. package/dist/telemetry/semantic-conventions.js +67 -1
  41. package/dist/test-support/orchestrator-context.d.ts +25 -0
  42. package/dist/test-support/orchestrator-context.d.ts.map +1 -0
  43. package/dist/test-support/orchestrator-context.js +91 -0
  44. package/dist/version.d.ts +1 -1
  45. package/dist/version.js +2 -2
  46. package/dist/workflow.js +35 -2
  47. package/package.json +5 -5
@@ -0,0 +1,143 @@
1
+ import type { HookResumeTiming } from '@workflow/world';
2
+ /**
3
+ * Hook-triggered time-to-resume (TTR): wall-clock from entry into
4
+ * `resumeHook()` (T0) to the first line of the next durable step (T7), plus a
5
+ * decomposition into non-overlapping phases that sum exactly to it.
6
+ *
7
+ * ```text
8
+ * T0 resumeHook() entered
9
+ * producer_prep — hook lookup, serialization, encryption
10
+ * T1 queue publish requested
11
+ * queue_delivery — network + VQS delivery (incl. any affinity re-route)
12
+ * T2 final consumer's queue handler entered
13
+ * resume_setup — affinity check, hook_received re-ensure, replay preload
14
+ * T3 replay begins
15
+ * replay — VM/session creation and workflow replay
16
+ * T4 next durable step encountered
17
+ * step_dispatch — suspension handling, inline batch or queue dispatch
18
+ * T5 step_started request begins
19
+ * step_claim — the claim round trip
20
+ * T6 step_started response returned
21
+ * step_prepare — key resolution, argument hydration, context setup
22
+ * T7 immediately before stepFn.apply()
23
+ * ```
24
+ *
25
+ * The producer's direct `hook_received` POST races the queue publish on the
26
+ * parallel fast path, so it deliberately has no phase of its own — the two
27
+ * overlap, and representing both as additive phases would double-count. It
28
+ * remains visible as a contextual span (`hook.resume`).
29
+ *
30
+ * T0/T1 are stamped on the producer's machine and T2..T7 on the consumer's, so
31
+ * the measurement is subject to cross-machine clock skew. Rather than clamp
32
+ * (which would break the sum-equals-total property this decomposition exists
33
+ * for), a non-monotonic boundary set drops the whole sample — see
34
+ * {@link computeResumeTtrAttributes}.
35
+ */
36
+ /** What caused the resumption being measured. Only hooks are measured today. */
37
+ export type ResumeTrigger = 'hook';
38
+ /** Which `resumeHook()` dispatch path produced this resume. */
39
+ export type ResumeStrategy = 'parallel' | 'sequential';
40
+ /**
41
+ * How the consuming invocation initialized its replay state:
42
+ *
43
+ * - `hook_preload` — the hoisted `hook_received` write returned a usable
44
+ * replay preload, so neither `run_started` nor the initial `events.list` ran.
45
+ * - `run_started` — the generic `run_started` setup ran (including the fast
46
+ * path's fallback, where the hoisted write succeeded but returned no usable
47
+ * preload).
48
+ * - `event_load` — neither setup ran because the run arrived already loaded,
49
+ * so setup was a plain event load. No current path produces it (the one
50
+ * preloaded-run path, the background-step fall-through, consumes the
51
+ * tracking on its own step first); it is the honest default rather than a
52
+ * live value, and keeps the dimension total if such a path is added.
53
+ */
54
+ export type ResumeSetupSource = 'hook_preload' | 'run_started' | 'event_load';
55
+ /** Whether the measured step ran in the resuming invocation or a queued one. */
56
+ export type ResumeStepExecution = 'inline' | 'dispatched';
57
+ /**
58
+ * The resume boundaries observed so far, threaded from the queue handler into
59
+ * `executeStep`. Producer fields arrive on the queue message
60
+ * ({@link HookResumeTiming}); consumer fields are stamped by the invocation
61
+ * that replays the resume.
62
+ *
63
+ * The runtime holds at most one of these per invocation and CONSUMES it when
64
+ * it hands it to the execution that will attempt the next durable step, so a
65
+ * later step in the same invocation — or a retry of the same step — never
66
+ * re-reports the same resumption. Within one inline batch the object is
67
+ * shared by every step and the {@link ResumeTtrTracking.reported} latch picks
68
+ * the single reporter.
69
+ */
70
+ export interface ResumeTtrTracking {
71
+ trigger: ResumeTrigger;
72
+ /** Absent only if an older producer omitted it from the queue message. */
73
+ strategy?: ResumeStrategy;
74
+ /** T0 — entry into `resumeHook()`. */
75
+ resumeRequestedAtMs: number;
76
+ /** T1 — immediately before the queue publish was requested. */
77
+ queuePublishRequestedAtMs: number;
78
+ /**
79
+ * T2 — entry into the FINAL consumer's queue handler. A delivery that
80
+ * re-routes for deployment affinity never stamps this, so the re-routed hop
81
+ * stays inside `queue_delivery` where it belongs.
82
+ */
83
+ consumerStartedAtMs: number;
84
+ /** T3 — this invocation's first replay pass. */
85
+ replayStartedAtMs?: number;
86
+ /** T4 — replay first encountered a durable step after the resume. */
87
+ nextStepEncounteredAtMs?: number;
88
+ setupSource?: ResumeSetupSource;
89
+ stepExecution: ResumeStepExecution;
90
+ /**
91
+ * One-shot latch, set by the step executor once this resumption has been
92
+ * reported. Every step of an inline batch is handed the SAME tracking
93
+ * object, so the first one to reach user code takes the measurement and the
94
+ * rest see this and skip — one resumption, one sample, without pinning the
95
+ * sample to a step that may lose its create-claim and never run.
96
+ *
97
+ * Deliberately not part of {@link HookResumeTiming}: it is invocation-local
98
+ * state, and a queue message carries the boundaries, not the claim.
99
+ */
100
+ reported?: boolean;
101
+ }
102
+ /**
103
+ * Rebuild tracking from a queue message's timing object. Returns undefined for
104
+ * a message that carries none (an older producer, or any non-hook delivery) —
105
+ * the caller then simply reports no TTR.
106
+ */
107
+ export declare function resumeTrackingFromMessage(timing: HookResumeTiming | undefined, stepExecution: ResumeStepExecution): ResumeTtrTracking | undefined;
108
+ /**
109
+ * Serialize tracking back onto a queue message, for the case where the
110
+ * resuming invocation dispatches the next durable step to another invocation
111
+ * instead of running it inline. Returns undefined when the tracking is not
112
+ * complete enough to be worth forwarding.
113
+ */
114
+ export declare function resumeTimingForMessage(tracking: ResumeTtrTracking | undefined): HookResumeTiming | undefined;
115
+ /**
116
+ * Compute the TTR span attributes for a step that is the first durable step
117
+ * following a hook resume. Returns undefined — emitting nothing at all — when
118
+ * any of these hold:
119
+ *
120
+ * - the invocation carries no resume tracking (not a hook resume, or an older
121
+ * queue message with no timing);
122
+ * - this is a retry (`attempt !== 1`), which measures a re-execution rather
123
+ * than the resumption;
124
+ * - a required boundary is missing, non-finite, or out of order.
125
+ *
126
+ * `step_claim_ms` is the one phase that may be individually omitted. Under
127
+ * optimistic inline start the `step_started` claim is deliberately NOT awaited
128
+ * before the body runs, so its completion instant does not exist yet at T7;
129
+ * rather than invent one, the claim phase is dropped and `step_prepare_ms`
130
+ * spans T5→T7. The sum-equals-total property holds either way.
131
+ */
132
+ export declare function computeResumeTtrAttributes(params: {
133
+ tracking: ResumeTtrTracking | undefined;
134
+ /** The attempt number of the execution about to run. */
135
+ attempt: number;
136
+ /** T5 — `Date.now()` immediately before the `step_started` request. */
137
+ stepClaimStartedAtMs: number | undefined;
138
+ /** T6 — `Date.now()` once the `step_started` response returned. */
139
+ stepClaimCompletedAtMs: number | undefined;
140
+ /** T7 — `Date.now()` immediately before `stepFn.apply()`. */
141
+ stepCodeStartedAtMs: number;
142
+ }): Record<string, string | number> | undefined;
143
+ //# sourceMappingURL=resume-latency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume-latency.d.ts","sourceRoot":"","sources":["../../src/runtime/resume-latency.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,gFAAgF;AAChF,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC;AAEnC,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC;AAEvD;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,aAAa,GAAG,YAAY,CAAC;AAE9E,gFAAgF;AAChF,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,YAAY,CAAC;AAE1D;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,aAAa,CAAC;IACvB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,sCAAsC;IACtC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,+DAA+D;IAC/D,yBAAyB,EAAE,MAAM,CAAC;IAClC;;;;OAIG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gDAAgD;IAChD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qEAAqE;IACrE,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,aAAa,EAAE,mBAAmB,CAAC;IACnC;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,gBAAgB,GAAG,SAAS,EACpC,aAAa,EAAE,mBAAmB,GACjC,iBAAiB,GAAG,SAAS,CAgC/B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,iBAAiB,GAAG,SAAS,GACtC,gBAAgB,GAAG,SAAS,CAkB9B;AA6CD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,QAAQ,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACxC,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,mEAAmE;IACnE,sBAAsB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,6DAA6D;IAC7D,mBAAmB,EAAE,MAAM,CAAC;CAC7B,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,SAAS,CAoD9C"}
@@ -0,0 +1,153 @@
1
+ import * as Attribute from '../telemetry/semantic-conventions.js';
2
+ /**
3
+ * Rebuild tracking from a queue message's timing object. Returns undefined for
4
+ * a message that carries none (an older producer, or any non-hook delivery) —
5
+ * the caller then simply reports no TTR.
6
+ */
7
+ export function resumeTrackingFromMessage(timing, stepExecution) {
8
+ if (!timing)
9
+ return undefined;
10
+ if (!Number.isFinite(timing.resumeRequestedAtMs) ||
11
+ !Number.isFinite(timing.queuePublishRequestedAtMs)) {
12
+ return undefined;
13
+ }
14
+ return {
15
+ trigger: 'hook',
16
+ ...(timing.strategy === 'parallel' || timing.strategy === 'sequential'
17
+ ? { strategy: timing.strategy }
18
+ : {}),
19
+ resumeRequestedAtMs: timing.resumeRequestedAtMs,
20
+ queuePublishRequestedAtMs: timing.queuePublishRequestedAtMs,
21
+ // A dispatched step reads the resuming invocation's boundaries off the
22
+ // message; an inline one has them stamped locally by the caller, which
23
+ // overwrites this placeholder immediately after construction.
24
+ consumerStartedAtMs: timing.consumerStartedAtMs ?? Number.NaN,
25
+ ...(timing.replayStartedAtMs !== undefined
26
+ ? { replayStartedAtMs: timing.replayStartedAtMs }
27
+ : {}),
28
+ ...(timing.nextStepEncounteredAtMs !== undefined
29
+ ? { nextStepEncounteredAtMs: timing.nextStepEncounteredAtMs }
30
+ : {}),
31
+ ...(timing.setupSource === 'hook_preload' ||
32
+ timing.setupSource === 'run_started' ||
33
+ timing.setupSource === 'event_load'
34
+ ? { setupSource: timing.setupSource }
35
+ : {}),
36
+ stepExecution,
37
+ };
38
+ }
39
+ /**
40
+ * Serialize tracking back onto a queue message, for the case where the
41
+ * resuming invocation dispatches the next durable step to another invocation
42
+ * instead of running it inline. Returns undefined when the tracking is not
43
+ * complete enough to be worth forwarding.
44
+ */
45
+ export function resumeTimingForMessage(tracking) {
46
+ if (!tracking)
47
+ return undefined;
48
+ if (!Number.isFinite(tracking.consumerStartedAtMs))
49
+ return undefined;
50
+ return {
51
+ resumeRequestedAtMs: tracking.resumeRequestedAtMs,
52
+ queuePublishRequestedAtMs: tracking.queuePublishRequestedAtMs,
53
+ ...(tracking.strategy !== undefined ? { strategy: tracking.strategy } : {}),
54
+ consumerStartedAtMs: tracking.consumerStartedAtMs,
55
+ ...(tracking.replayStartedAtMs !== undefined
56
+ ? { replayStartedAtMs: tracking.replayStartedAtMs }
57
+ : {}),
58
+ ...(tracking.nextStepEncounteredAtMs !== undefined
59
+ ? { nextStepEncounteredAtMs: tracking.nextStepEncounteredAtMs }
60
+ : {}),
61
+ ...(tracking.setupSource !== undefined
62
+ ? { setupSource: tracking.setupSource }
63
+ : {}),
64
+ };
65
+ }
66
+ /**
67
+ * Validate that every required boundary is a finite epoch-ms value and that
68
+ * the whole sequence is non-decreasing. Returns undefined otherwise, which
69
+ * suppresses the metric entirely rather than reporting a phase that never
70
+ * happened or a negative duration.
71
+ */
72
+ function validateBoundaries(b) {
73
+ const ordered = [
74
+ b.resumeRequestedAtMs,
75
+ b.queuePublishRequestedAtMs,
76
+ b.consumerStartedAtMs,
77
+ b.replayStartedAtMs,
78
+ b.nextStepEncounteredAtMs,
79
+ b.stepClaimStartedAtMs,
80
+ ...(b.stepClaimCompletedAtMs !== undefined
81
+ ? [b.stepClaimCompletedAtMs]
82
+ : []),
83
+ b.stepCodeStartedAtMs,
84
+ ];
85
+ for (const value of ordered) {
86
+ if (typeof value !== 'number' || !Number.isFinite(value))
87
+ return undefined;
88
+ }
89
+ for (let i = 1; i < ordered.length; i++) {
90
+ if (ordered[i] < ordered[i - 1])
91
+ return undefined;
92
+ }
93
+ return ordered;
94
+ }
95
+ /**
96
+ * Compute the TTR span attributes for a step that is the first durable step
97
+ * following a hook resume. Returns undefined — emitting nothing at all — when
98
+ * any of these hold:
99
+ *
100
+ * - the invocation carries no resume tracking (not a hook resume, or an older
101
+ * queue message with no timing);
102
+ * - this is a retry (`attempt !== 1`), which measures a re-execution rather
103
+ * than the resumption;
104
+ * - a required boundary is missing, non-finite, or out of order.
105
+ *
106
+ * `step_claim_ms` is the one phase that may be individually omitted. Under
107
+ * optimistic inline start the `step_started` claim is deliberately NOT awaited
108
+ * before the body runs, so its completion instant does not exist yet at T7;
109
+ * rather than invent one, the claim phase is dropped and `step_prepare_ms`
110
+ * spans T5→T7. The sum-equals-total property holds either way.
111
+ */
112
+ export function computeResumeTtrAttributes(params) {
113
+ const { tracking } = params;
114
+ if (!tracking || params.attempt !== 1)
115
+ return undefined;
116
+ if (tracking.replayStartedAtMs === undefined ||
117
+ tracking.nextStepEncounteredAtMs === undefined ||
118
+ params.stepClaimStartedAtMs === undefined) {
119
+ return undefined;
120
+ }
121
+ const boundaries = {
122
+ resumeRequestedAtMs: tracking.resumeRequestedAtMs,
123
+ queuePublishRequestedAtMs: tracking.queuePublishRequestedAtMs,
124
+ consumerStartedAtMs: tracking.consumerStartedAtMs,
125
+ replayStartedAtMs: tracking.replayStartedAtMs,
126
+ nextStepEncounteredAtMs: tracking.nextStepEncounteredAtMs,
127
+ stepClaimStartedAtMs: params.stepClaimStartedAtMs,
128
+ stepClaimCompletedAtMs: params.stepClaimCompletedAtMs,
129
+ stepCodeStartedAtMs: params.stepCodeStartedAtMs,
130
+ };
131
+ if (!validateBoundaries(boundaries))
132
+ return undefined;
133
+ const { resumeRequestedAtMs: t0, queuePublishRequestedAtMs: t1, consumerStartedAtMs: t2, replayStartedAtMs: t3, nextStepEncounteredAtMs: t4, stepClaimStartedAtMs: t5, stepClaimCompletedAtMs: t6, stepCodeStartedAtMs: t7, } = boundaries;
134
+ return {
135
+ ...Attribute.ResumeTotalMs(t7 - t0),
136
+ ...Attribute.ResumeProducerPrepMs(t1 - t0),
137
+ ...Attribute.ResumeQueueDeliveryMs(t2 - t1),
138
+ ...Attribute.ResumeSetupMs(t3 - t2),
139
+ ...Attribute.ResumeReplayMs(t4 - t3),
140
+ ...Attribute.ResumeStepDispatchMs(t5 - t4),
141
+ ...(t6 !== undefined ? Attribute.ResumeStepClaimMs(t6 - t5) : {}),
142
+ ...Attribute.ResumeStepPrepareMs(t7 - (t6 ?? t5)),
143
+ ...Attribute.ResumeTrigger(tracking.trigger),
144
+ ...(tracking.strategy !== undefined
145
+ ? Attribute.ResumeStrategy(tracking.strategy)
146
+ : {}),
147
+ ...(tracking.setupSource !== undefined
148
+ ? Attribute.ResumeSetupSource(tracking.setupSource)
149
+ : {}),
150
+ ...Attribute.ResumeStepExecution(tracking.stepExecution),
151
+ };
152
+ }
153
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdW1lLWxhdGVuY3kuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVudGltZS9yZXN1bWUtbGF0ZW5jeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEtBQUssU0FBUyxNQUFNLHNDQUFzQyxDQUFDO0FBNEdsRTs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLHlCQUF5QixDQUN2QyxNQUFvQyxFQUNwQyxhQUFrQztJQUVsQyxJQUFJLENBQUMsTUFBTTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQzlCLElBQ0UsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQztRQUM1QyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLHlCQUF5QixDQUFDLEVBQ2xELENBQUM7UUFDRCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBQ0QsT0FBTztRQUNMLE9BQU8sRUFBRSxNQUFNO1FBQ2YsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEtBQUssVUFBVSxJQUFJLE1BQU0sQ0FBQyxRQUFRLEtBQUssWUFBWTtZQUNwRSxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVEsRUFBRTtZQUMvQixDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ1AsbUJBQW1CLEVBQUUsTUFBTSxDQUFDLG1CQUFtQjtRQUMvQyx5QkFBeUIsRUFBRSxNQUFNLENBQUMseUJBQXlCO1FBQzNELHVFQUF1RTtRQUN2RSx1RUFBdUU7UUFDdkUsOERBQThEO1FBQzlELG1CQUFtQixFQUFFLE1BQU0sQ0FBQyxtQkFBbUIsSUFBSSxNQUFNLENBQUMsR0FBRztRQUM3RCxHQUFHLENBQUMsTUFBTSxDQUFDLGlCQUFpQixLQUFLLFNBQVM7WUFDeEMsQ0FBQyxDQUFDLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxDQUFDLGlCQUFpQixFQUFFO1lBQ2pELENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDUCxHQUFHLENBQUMs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cG9ydCB0eXBlIHsgSG9va1Jlc3VtZVRpbWluZyB9IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgKiBhcyBBdHRyaWJ1dGUgZnJvbSAnLi4vdGVsZW1ldHJ5L3NlbWFudGljLWNvbnZlbnRpb25zLmpzJztcblxuLyoqXG4gKiBIb29rLXRyaWdnZXJlZCB0aW1lLXRvLXJlc3VtZSAoVFRSKTogd2FsbC1jbG9jayBmcm9tIGVudHJ5IGludG9cbiAqIGByZXN1bWVIb29rKClgIChUMCkgdG8gdGhlIGZpcnN0IGxpbmUgb2YgdGhlIG5leHQgZHVyYWJsZSBzdGVwIChUNyksIHBsdXMgYVxuICogZGVjb21wb3NpdGlvbiBpbnRvIG5vbi1vdmVybGFwcGluZyBwaGFzZXMgdGhhdCBzdW0gZXhhY3RseSB0byBpdC5cbiAqXG4gKiBgYGB0ZXh0XG4gKiBUMCByZXN1bWVIb29rKCkgZW50ZXJlZFxuICogICAgICBwcm9kdWNlcl9wcmVwICAg4oCUIGhvb2sgbG9va3VwLCBzZXJpYWxpemF0aW9uLCBlbmNyeXB0aW9uXG4gKiBUMSBxdWV1ZSBwdWJsaXNoIHJlcXVlc3RlZFxuICogICAgICBxdWV1ZV9kZWxpdmVyeSAg4oCUIG5ldHdvcmsgKyBWUVMgZGVsaXZlcnkgKGluY2wuIGFueSBhZmZpbml0eSByZS1yb3V0ZSlcbiAqIFQyIGZpbmFsIGNvbnN1bWVyJ3MgcXVldWUgaGFuZGxlciBlbnRlcmVkXG4gKiAgICAgIHJlc3VtZV9zZXR1cCAgICDigJQgYWZmaW5pdHkgY2hlY2ssIGhvb2tfcmVjZWl2ZWQgcmUtZW5zdXJlLCByZXBsYXkgcHJlbG9hZFxuICogVDMgcmVwbGF5IGJlZ2luc1xuICogICAgICByZXBsYXkgICAgICAgICAg4oCUIFZNL3Nlc3Npb24gY3JlYXRpb24gYW5kIHdvcmtmbG93IHJlcGxheVxuICogVDQgbmV4dCBkdXJhYmxlIHN0ZXAgZW5jb3VudGVyZWRcbiAqICAgICAgc3RlcF9kaXNwYXRjaCAgIOKAlCBzdXNwZW5zaW9uIGhhbmRsaW5nLCBpbmxpbmUgYmF0Y2ggb3IgcXVldWUgZGlzcGF0Y2hcbiAqIFQ1IHN0ZXBfc3RhcnRlZCByZXF1ZXN0IGJlZ2luc1xuICogICAgICBzdGVwX2NsYWltICAgICAg4oCUIHRoZSBjbGFpbSByb3VuZCB0cmlwXG4gKiBUNiBzdGVwX3N0YXJ0ZWQgcmVzcG9uc2UgcmV0dXJuZWRcbiAqICAgICAgc3RlcF9wcmVwYXJlICAgIOKAlCBrZXkgcmVzb2x1dGlvbiwgYXJndW1lbnQgaHlkcmF0aW9uLCBjb250ZXh0IHNldHVwXG4gKiBUNyBpbW1lZGlhdGVseSBiZWZvcmUgc3RlcEZuLmFwcGx5KClcbiAqIGBgYFxuICpcbiAqIFRoZSBwcm9kdWNlcidzIGRpcmVjdCBgaG9va19yZWNlaXZlZGAgUE9TVCByYWNlcyB0aGUgcXVldWUgcHVibGlzaCBvbiB0aGVcbiAqIHBhcmFsbGVsIGZhc3QgcGF0aCwgc28gaXQgZGVsaWJlcmF0ZWx5IGhhcyBubyBwaGFzZSBvZiBpdHMgb3duIOKAlCB0aGUgdHdvXG4gKiBvdmVybGFwLCBhbmQgcmVwcmVzZW50aW5nIGJvdGggYXMgYWRkaXRpdmUgcGhhc2VzIHdvdWxkIGRvdWJsZS1jb3VudC4gSXRcbiAqIHJlbWFpbnMgdmlzaWJsZSBhcyBhIGNvbnRleHR1YWwgc3BhbiAoYGhvb2sucmVzdW1lYCkuXG4gKlxuICogVDAvVDEgYXJlIHN0YW1wZWQgb24gdGhlIHByb2R1Y2VyJ3MgbWFjaGluZSBhbmQgVDIuLlQ3IG9uIHRoZSBjb25zdW1lcidzLCBzb1xuICogdGhlIG1lYXN1cmVtZW50IGlzIHN1YmplY3QgdG8gY3Jvc3MtbWFjaGluZSBjbG9jayBza2V3LiBSYXRoZXIgdGhhbiBjbGFtcFxuICogKHdoaWNoIHdvdWxkIGJyZWFrIHRoZSBzdW0tZXF1YWxzLXRvdGFsIHByb3BlcnR5IHRoaXMgZGVjb21wb3NpdGlvbiBleGlzdHNcbiAqIGZvciksIGEgbm9uLW1vbm90b25pYyBib3VuZGFyeSBzZXQgZHJvcHMgdGhlIHdob2xlIHNhbXBsZSDigJQgc2VlXG4gKiB7QGxpbmsgY29tcHV0ZVJlc3VtZVR0ckF0dHJpYnV0ZXN9LlxuICovXG5cbi8qKiBXaGF0IGNhdXNlZCB0aGUgcmVzdW1wdGlvbiBiZWluZyBtZWFzdXJlZC4gT25seSBob29rcyBhcmUgbWVhc3VyZWQgdG9kYXkuICovXG5leHBvcnQgdHlwZSBSZXN1bWVUcmlnZ2VyID0gJ2hvb2snO1xuXG4vKiogV2hpY2ggYHJlc3VtZUhvb2soKWAgZGlzcGF0Y2ggcGF0aCBwcm9kdWNlZCB0aGlzIHJlc3VtZS4gKi9cbmV4cG9ydCB0eXBlIFJlc3VtZVN0cmF0ZWd5ID0gJ3BhcmFsbGVsJyB8ICdzZXF1ZW50aWFsJztcblxuLyoqXG4gKiBIb3cgdGhlIGNvbnN1bWluZyBpbnZvY2F0aW9uIGluaXRpYWxpemVkIGl0cyByZXBsYXkgc3RhdGU6XG4gKlxuICogLSBgaG9va19wcmVsb2FkYCDigJQgdGhlIGhvaXN0ZWQgYGhvb2tfcmVjZWl2ZWRgIHdyaXRlIHJldHVybmVkIGEgdXNhYmxlXG4gKiAgIHJlcGxheSBwcmVsb2FkLCBzbyBuZWl0aGVyIGBydW5fc3RhcnRlZGAgbm9yIHRoZSBpbml0aWFsIGBldmVudHMubGlzdGAgcmFuLlxuICogLSBgcnVuX3N0YXJ0ZWRgIOKAlCB0aGUgZ2VuZXJpYyBgcnVuX3N0YXJ0ZWRgIHNldHVwIHJhbiAoaW5jbHVkaW5nIHRoZSBmYXN0XG4gKiAgIHBhdGgncyBmYWxsYmFjaywgd2hlcmUgdGhlIGhvaXN0ZWQgd3JpdGUgc3VjY2VlZGVkIGJ1dCByZXR1cm5lZCBubyB1c2FibGVcbiAqICAgcHJlbG9hZCkuXG4gKiAtIGBldmVudF9sb2FkYCDigJQgbmVpdGhlciBzZXR1cCByYW4gYmVjYXVzZSB0aGUgcnVuIGFycml2ZWQgYWxyZWFkeSBsb2FkZWQsXG4gKiAgIHNvIHNldHVwIHdhcyBhIHBsYWluIGV2ZW50IGxvYWQuIE5vIGN1cnJlbnQgcGF0aCBwcm9kdWNlcyBpdCAodGhlIG9uZVxuICogICBwcmVsb2FkZWQtcnVuIHBhdGgsIHRoZSBiYWNrZ3JvdW5kLXN0ZXAgZmFsbC10aHJvdWdoLCBjb25zdW1lcyB0aGVcbiAqICAgdHJhY2tpbmcgb24gaXRzIG93biBzdGVwIGZpcnN0KTsgaXQgaXMgdGhlIGhvbmVzdCBkZWZhdWx0IHJhdGhlciB0aGFuIGFcbiAqICAgbGl2ZSB2YWx1ZSwgYW5kIGtlZXBzIHRoZSBkaW1lbnNpb24gdG90YWwgaWYgc3VjaCBhIHBhdGggaXMgYWRkZWQuXG4gKi9cbmV4cG9ydCB0eXBlIFJlc3VtZVNldHVwU291cmNlID0gJ2hvb2tfcHJlbG9hZCcgfCAncnVuX3N0YXJ0ZWQnIHwgJ2V2ZW50X2xvYWQnO1xuXG4vKiogV2hldGhlciB0aGUgbWVhc3VyZWQgc3RlcCByYW4gaW4gdGhlIHJlc3VtaW5nIGludm9jYXRpb24gb3IgYSBxdWV1ZWQgb25lLiAqL1xuZXhwb3J0IHR5cGUgUmVzdW1lU3RlcEV4ZWN1dGlvbiA9ICdpbmxpbmUnIHwgJ2Rpc3BhdGNoZWQnO1xuXG4vKipcbiAqIFRoZSByZXN1bWUgYm91bmRhcmllcyBvYnNlcnZlZCBzbyBmYXIsIHRocmVhZGVkIGZyb20gdGhlIHF1ZXVlIGhhbmRsZXIgaW50b1xuICogYGV4ZWN1dGVTdGVwYC4gUHJvZHVjZXIgZmllbGRzIGFycml2ZSBvbiB0aGUgcXVldWUgbWVzc2FnZVxuICogKHtAbGluayBIb29rUmVzdW1lVGltaW5nfSk7IGNvbnN1bWVyIGZpZWxkcyBhcmUgc3RhbXBlZCBieSB0aGUgaW52b2NhdGlvblxuICogdGhhdCByZXBsYXlzIHRoZSByZXN1bWUuXG4gKlxuICogVGhlIHJ1bnRpbWUgaG9sZHMgYXQgbW9zdCBvbmUgb2YgdGhlc2UgcGVyIGludm9jYXRpb24gYW5kIENPTlNVTUVTIGl0IHdoZW5cbiAqIGl0IGhhbmRzIGl0IHRvIHRoZSBleGVjdXRpb24gdGhhdCB3aWxsIGF0dGVtcHQgdGhlIG5leHQgZHVyYWJsZSBzdGVwLCBzbyBhXG4gKiBsYXRlciBzdGVwIGluIHRoZSBzYW1lIGludm9jYXRpb24g4oCUIG9yIGEgcmV0cnkgb2YgdGhlIHNhbWUgc3RlcCDigJQgbmV2ZXJcbiAqIHJlLXJlcG9ydHMgdGhlIHNhbWUgcmVzdW1wdGlvbi4gV2l0aGluIG9uZSBpbmxpbmUgYmF0Y2ggdGhlIG9iamVjdCBpc1xuICogc2hhcmVkIGJ5IGV2ZXJ5IHN0ZXAgYW5kIHRoZSB7QGxpbmsgUmVzdW1lVHRyVHJhY2tpbmcucmVwb3J0ZWR9IGxhdGNoIHBpY2tzXG4gKiB0aGUgc2luZ2xlIHJlcG9ydGVyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc3VtZVR0clRyYWNraW5nIHtcbiAgdHJpZ2dlcjogUmVzdW1lVHJpZ2dlcjtcbiAgLyoqIEFic2VudCBvbmx5IGlmIGFuIG9sZGVyIHByb2R1Y2VyIG9taXR0ZWQgaXQgZnJvbSB0aGUgcXVldWUgbWVzc2FnZS4gKi9cbiAgc3RyYXRlZ3k/OiBSZXN1bWVTdHJhdGVneTtcbiAgLyoqIFQwIOKAlCBlbnRyeSBpbnRvIGByZXN1bWVIb29rKClgLiAqL1xuICByZXN1bWVSZXF1ZXN0ZWRBdE1zOiBudW1iZXI7XG4gIC8qKiBUMSDigJQgaW1tZWRpYXRlbHkgYmVmb3JlIHRoZSBxdWV1ZSBwdWJsaXNoIHdhcyByZXF1ZXN0ZWQuICovXG4gIHF1ZXVlUHVibGlzaFJlcXVlc3RlZEF0TXM6IG51bWJlcjtcbiAgLyoqXG4gICAqIFQyIOKAlCBlbnRyeSBpbnRvIHRoZSBGSU5BTCBjb25zdW1lcidzIHF1ZXVlIGhhbmRsZXIuIEEgZGVsaXZlcnkgdGhhdFxuICAgKiByZS1yb3V0ZXMgZm9yIGRlcGxveW1lbnQgYWZmaW5pdHkgbmV2ZXIgc3RhbXBzIHRoaXMsIHNvIHRoZSByZS1yb3V0ZWQgaG9wXG4gICAqIHN0YXlzIGluc2lkZSBgcXVldWVfZGVsaXZlcnlgIHdoZXJlIGl0IGJlbG9uZ3MuXG4gICAqL1xuICBjb25zdW1lclN0YXJ0ZWRBdE1zOiBudW1iZXI7XG4gIC8qKiBUMyDigJQgdGhpcyBpbnZvY2F0aW9uJ3MgZmlyc3QgcmVwbGF5IHBhc3MuICovXG4gIHJlcGxheVN0YXJ0ZWRBdE1zPzogbnVtYmVyO1xuICAvKiogVDQg4oCUIHJlcGxheSBmaXJzdCBlbmNvdW50ZXJlZCBhIGR1cmFibGUgc3RlcCBhZnRlciB0aGUgcmVzdW1lLiAqL1xuICBuZXh0U3RlcEVuY291bnRlcmVkQXRNcz86IG51bWJlcjtcbiAgc2V0dXBTb3VyY2U/OiBSZXN1bWVTZXR1cFNvdXJjZTtcbiAgc3RlcEV4ZWN1dGlvbjogUmVzdW1lU3RlcEV4ZWN1dGlvbjtcbiAgLyoqXG4gICAqIE9uZS1zaG90IGxhdGNoLCBzZXQgYnkgdGhlIHN0ZXAgZXhlY3V0b3Igb25jZSB0aGlzIHJlc3VtcHRpb24gaGFzIGJlZW5cbiAgICogcmVwb3J0ZWQuIEV2ZXJ5IHN0ZXAgb2YgYW4gaW5saW5lIGJhdGNoIGlzIGhhbmRlZCB0aGUgU0FNRSB0cmFja2luZ1xuICAgKiBvYmplY3QsIHNvIHRoZSBmaXJzdCBvbmUgdG8gcmVhY2ggdXNlciBjb2RlIHRha2VzIHRoZSBtZWFzdXJlbWVudCBhbmQgdGhlXG4gICAqIHJlc3Qgc2VlIHRoaXMgYW5kIHNraXAg4oCUIG9uZSByZXN1bXB0aW9uLCBvbmUgc2FtcGxlLCB3aXRob3V0IHBpbm5pbmcgdGhlXG4gICAqIHNhbXBsZSB0byBhIHN0ZXAgdGhhdCBtYXkgbG9zZSBpdHMgY3JlYXRlLWNsYWltIGFuZCBuZXZlciBydW4uXG4gICAqXG4gICAqIERlbGliZXJhdGVseSBub3QgcGFydCBvZiB7QGxpbmsgSG9va1Jlc3VtZVRpbWluZ306IGl0IGlzIGludm9jYXRpb24tbG9jYWxcbiAgICogc3RhdGUsIGFuZCBhIHF1ZXVlIG1lc3NhZ2UgY2FycmllcyB0aGUgYm91bmRhcmllcywgbm90IHRoZSBjbGFpbS5cbiAgICovXG4gIHJlcG9ydGVkPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBSZWJ1aWxkIHRyYWNraW5nIGZyb20gYSBxdWV1ZSBtZXNzYWdlJ3MgdGltaW5nIG9iamVjdC4gUmV0dXJucyB1bmRlZmluZWQgZm9yXG4gKiBhIG1lc3NhZ2UgdGhhdCBjYXJyaWVzIG5vbmUgKGFuIG9sZGVyIHByb2R1Y2VyLCBvciBhbnkgbm9uLWhvb2sgZGVsaXZlcnkpIOKAlFxuICogdGhlIGNhbGxlciB0aGVuIHNpbXBseSByZXBvcnRzIG5vIFRUUi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc3VtZVRyYWNraW5nRnJvbU1lc3NhZ2UoXG4gIHRpbWluZzogSG9va1Jlc3VtZVRpbWluZyB8IHVuZGVmaW5lZCxcbiAgc3RlcEV4ZWN1dGlvbjogUmVzdW1lU3RlcEV4ZWN1dGlvblxuKTogUmVzdW1lVHRyVHJhY2tpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoIXRpbWluZykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgaWYgKFxuICAgICFOdW1iZXIuaXNGaW5pdGUodGltaW5nLnJlc3VtZVJlcXVlc3RlZEF0TXMpIHx8XG4gICAgIU51bWJlci5pc0Zpbml0ZSh0aW1pbmcucXVldWVQdWJsaXNoUmVxdWVzdGVkQXRNcylcbiAgKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICByZXR1cm4ge1xuICAgIHRyaWdnZXI6ICdob29rJyxcbiAgICAuLi4odGltaW5nLnN0cmF0ZWd5ID09PSAncGFyYWxsZWwnIHx8IHRpbWluZy5zdHJhdGVneSA9PT0gJ3NlcXVlbnRpYWwnXG4gICAgICA/IHsgc3RyYXRlZ3k6IHRpbWluZy5zdHJhdGVneSB9XG4gICAgICA6IHt9KSxcbiAgICByZXN1bWVSZXF1ZXN0ZWRBdE1zOiB0aW1pbmcucmVzdW1lUmVxdWVzdGVkQXRNcyxcbiAgICBxdWV1ZVB1Ymxpc2hSZXF1ZXN0ZWRBdE1zOiB0aW1pbmcucXVldWVQdWJsaXNoUmVxdWVzdGVkQXRNcyxcbiAgICAvLyBBIGRpc3BhdGNoZWQgc3RlcCByZWFkcyB0aGUgcmVzdW1pbmcgaW52b2NhdGlvbidzIGJvdW5kYXJpZXMgb2ZmIHRoZVxuICAgIC8vIG1lc3NhZ2U7IGFuIGlubGluZSBvbmUgaGFzIHRoZW0gc3RhbXBlZCBsb2NhbGx5IGJ5IHRoZSBjYWxsZXIsIHdoaWNoXG4gICAgLy8gb3ZlcndyaXRlcyB0aGlzIHBsYWNlaG9sZGVyIGltbWVkaWF0ZWx5IGFmdGVyIGNvbnN0cnVjdGlvbi5cbiAgICBjb25zdW1lclN0YXJ0ZWRBdE1zOiB0aW1pbmcuY29uc3VtZXJTdGFydGVkQXRNcyA/PyBOdW1iZXIuTmFOLFxuICAgIC4uLih0aW1pbmcucmVwbGF5U3RhcnRlZEF0TXMgIT09IHVuZGVmaW5lZFxuICAgICAgPyB7IHJlcGxheVN0YXJ0ZWRBdE1zOiB0aW1pbmcucmVwbGF5U3RhcnRlZEF0TXMgfVxuICAgICAgOiB7fSksXG4gICAgLi4uKHRpbWluZy5uZXh0U3RlcEVuY291bnRlcmVkQXRNcyAhPT0gdW5kZWZpbmVkXG4gICAgICA/IHsgbmV4dFN0ZXBFbmNvdW50ZXJlZEF0TXM6IHRpbWluZy5uZXh0U3RlcEVuY291bnRlcmVkQXRNcyB9XG4gICAgICA6IHt9KSxcbiAgICAuLi4odGltaW5nLnNldHVwU291cmNlID09PSAnaG9va19wcmVsb2FkJyB8fFxuICAgIHRpbWluZy5zZXR1cFNvdXJjZSA9PT0gJ3J1bl9zdGFydGVkJyB8fFxuICAgIHRpbWluZy5zZXR1cFNvdXJjZSA9PT0gJ2V2ZW50X2xvYWQnXG4gICAgICA/IHsgc2V0dXBTb3VyY2U6IHRpbWluZy5zZXR1cFNvdXJjZSB9XG4gICAgICA6IHt9KSxcbiAgICBzdGVwRXhlY3V0aW9uLFxuICB9O1xufVxuXG4vKipcbiAqIFNlcmlhbGl6ZSB0cmFja2luZyBiYWNrIG9udG8gYSBxdWV1ZSBtZXNzYWdlLCBmb3IgdGhlIGNhc2Ugd2hlcmUgdGhlXG4gKiByZXN1bWluZyBpbnZvY2F0aW9uIGRpc3BhdGNoZXMgdGhlIG5leHQgZHVyYWJsZSBzdGVwIHRvIGFub3RoZXIgaW52b2NhdGlvblxuICogaW5zdGVhZCBvZiBydW5uaW5nIGl0IGlubGluZS4gUmV0dXJucyB1bmRlZmluZWQgd2hlbiB0aGUgdHJhY2tpbmcgaXMgbm90XG4gKiBjb21wbGV0ZSBlbm91Z2ggdG8gYmUgd29ydGggZm9yd2FyZGluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc3VtZVRpbWluZ0Zvck1lc3NhZ2UoXG4gIHRyYWNraW5nOiBSZXN1bWVUdHJUcmFja2luZyB8IHVuZGVmaW5lZFxuKTogSG9va1Jlc3VtZVRpbWluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghdHJhY2tpbmcpIHJldHVybiB1bmRlZmluZWQ7XG4gIGlmICghTnVtYmVyLmlzRmluaXRlKHRyYWNraW5nLmNvbnN1bWVyU3RhcnRlZEF0TXMpKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4ge1xuICAgIHJlc3VtZVJlcXVlc3RlZEF0TXM6IHRyYWNraW5nLnJlc3VtZVJlcXVlc3RlZEF0TXMsXG4gICAgcXVldWVQdWJsaXNoUmVxdWVzdGVkQXRNczogdHJhY2tpbmcucXVldWVQdWJsaXNoUmVxdWVzdGVkQXRNcyxcbiAgICAuLi4odHJhY2tpbmcuc3RyYXRlZ3kgIT09IHVuZGVmaW5lZCA/IHsgc3RyYXRlZ3k6IHRyYWNraW5nLnN0cmF0ZWd5IH0gOiB7fSksXG4gICAgY29uc3VtZXJTdGFydGVkQXRNczogdHJhY2tpbmcuY29uc3VtZXJTdGFydGVkQXRNcyxcbiAgICAuLi4odHJhY2tpbmcucmVwbGF5U3RhcnRlZEF0TXMgIT09IHVuZGVmaW5lZFxuICAgICAgPyB7IHJlcGxheVN0YXJ0ZWRBdE1zOiB0cmFja2luZy5yZXBsYXlTdGFydGVkQXRNcyB9XG4gICAgICA6IHt9KSxcbiAgICAuLi4odHJhY2tpbmcubmV4dFN0ZXBFbmNvdW50ZXJlZEF0TXMgIT09IHVuZGVmaW5lZFxuICAgICAgPyB7IG5leHRTdGVwRW5jb3VudGVyZWRBdE1zOiB0cmFja2luZy5uZXh0U3RlcEVuY291bnRlcmVkQXRNcyB9XG4gICAgICA6IHt9KSxcbiAgICAuLi4odHJhY2tpbmcuc2V0dXBTb3VyY2UgIT09IHVuZGVmaW5lZFxuICAgICAgPyB7IHNldHVwU291cmNlOiB0cmFja2luZy5zZXR1cFNvdXJjZSB9XG4gICAgICA6IHt9KSxcbiAgfTtcbn1cblxuLyoqIEV2ZXJ5IGJvdW5kYXJ5IHRoZSBlbWlzc2lvbiBnYXRlIHJlcXVpcmVzLCBwbHVzIHRoZSBvcHRpb25hbCBjbGFpbSBlbmQuICovXG5pbnRlcmZhY2UgUmVzdW1lQm91bmRhcmllcyB7XG4gIC8qKiBUMCAqLyByZXN1bWVSZXF1ZXN0ZWRBdE1zOiBudW1iZXI7XG4gIC8qKiBUMSAqLyBxdWV1ZVB1Ymxpc2hSZXF1ZXN0ZWRBdE1zOiBudW1iZXI7XG4gIC8qKiBUMiAqLyBjb25zdW1lclN0YXJ0ZWRBdE1zOiBudW1iZXI7XG4gIC8qKiBUMyAqLyByZXBsYXlTdGFydGVkQXRNczogbnVtYmVyO1xuICAvKiogVDQgKi8gbmV4dFN0ZXBFbmNvdW50ZXJlZEF0TXM6IG51bWJlcjtcbiAgLyoqIFQ1ICovIHN0ZXBDbGFpbVN0YXJ0ZWRBdE1zOiBudW1iZXI7XG4gIC8qKiBUNiDigJQgYWJzZW50IG9uIHRoZSBvcHRpbWlzdGljLXN0YXJ0IHBhdGg7IHNlZSBiZWxvdy4gKi9cbiAgc3RlcENsYWltQ29tcGxldGVkQXRNczogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAvKiogVDcgKi8gc3RlcENvZGVTdGFydGVkQXRNczogbnVtYmVyO1xufVxuXG4vKipcbiAqIFZhbGlkYXRlIHRoYXQgZXZlcnkgcmVxdWlyZWQgYm91bmRhcnkgaXMgYSBmaW5pdGUgZXBvY2gtbXMgdmFsdWUgYW5kIHRoYXRcbiAqIHRoZSB3aG9sZSBzZXF1ZW5jZSBpcyBub24tZGVjcmVhc2luZy4gUmV0dXJucyB1bmRlZmluZWQgb3RoZXJ3aXNlLCB3aGljaFxuICogc3VwcHJlc3NlcyB0aGUgbWV0cmljIGVudGlyZWx5IHJhdGhlciB0aGFuIHJlcG9ydGluZyBhIHBoYXNlIHRoYXQgbmV2ZXJcbiAqIGhhcHBlbmVkIG9yIGEgbmVnYXRpdmUgZHVyYXRpb24uXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlQm91bmRhcmllcyhcbiAgYjogUmVzdW1lQm91bmRhcmllc1xuKTogcmVhZG9ubHkgbnVtYmVyW10gfCB1bmRlZmluZWQge1xuICBjb25zdCBvcmRlcmVkID0gW1xuICAgIGIucmVzdW1lUmVxdWVzdGVkQXRNcyxcbiAgICBiLnF1ZXVlUHVibGlzaFJlcXVlc3RlZEF0TXMsXG4gICAgYi5jb25zdW1lclN0YXJ0ZWRBdE1zLFxuICAgIGIucmVwbGF5U3RhcnRlZEF0TXMsXG4gICAgYi5uZXh0U3RlcEVuY291bnRlcmVkQXRNcyxcbiAgICBiLnN0ZXBDbGFpbVN0YXJ0ZWRBdE1zLFxuICAgIC4uLihiLnN0ZXBDbGFpbUNvbXBsZXRlZEF0TXMgIT09IHVuZGVmaW5lZFxuICAgICAgPyBbYi5zdGVwQ2xhaW1Db21wbGV0ZWRBdE1zXVxuICAgICAgOiBbXSksXG4gICAgYi5zdGVwQ29kZVN0YXJ0ZWRBdE1zLFxuICBdO1xuICBmb3IgKGNvbnN0IHZhbHVlIG9mIG9yZGVyZWQpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCAhTnVtYmVyLmlzRmluaXRlKHZhbHVlKSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBmb3IgKGxldCBpID0gMTsgaSA8IG9yZGVyZWQubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAob3JkZXJlZFtpXSA8IG9yZGVyZWRbaSAtIDFdKSByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIHJldHVybiBvcmRlcmVkO1xufVxuXG4vKipcbiAqIENvbXB1dGUgdGhlIFRUUiBzcGFuIGF0dHJpYnV0ZXMgZm9yIGEgc3RlcCB0aGF0IGlzIHRoZSBmaXJzdCBkdXJhYmxlIHN0ZXBcbiAqIGZvbGxvd2luZyBhIGhvb2sgcmVzdW1lLiBSZXR1cm5zIHVuZGVmaW5lZCDigJQgZW1pdHRpbmcgbm90aGluZyBhdCBhbGwg4oCUIHdoZW5cbiAqIGFueSBvZiB0aGVzZSBob2xkOlxuICpcbiAqIC0gdGhlIGludm9jYXRpb24gY2FycmllcyBubyByZXN1bWUgdHJhY2tpbmcgKG5vdCBhIGhvb2sgcmVzdW1lLCBvciBhbiBvbGRlclxuICogICBxdWV1ZSBtZXNzYWdlIHdpdGggbm8gdGltaW5nKTtcbiAqIC0gdGhpcyBpcyBhIHJldHJ5IChgYXR0ZW1wdCAhPT0gMWApLCB3aGljaCBtZWFzdXJlcyBhIHJlLWV4ZWN1dGlvbiByYXRoZXJcbiAqICAgdGhhbiB0aGUgcmVzdW1wdGlvbjtcbiAqIC0gYSByZXF1aXJlZCBib3VuZGFyeSBpcyBtaXNzaW5nLCBub24tZmluaXRlLCBvciBvdXQgb2Ygb3JkZXIuXG4gKlxuICogYHN0ZXBfY2xhaW1fbXNgIGlzIHRoZSBvbmUgcGhhc2UgdGhhdCBtYXkgYmUgaW5kaXZpZHVhbGx5IG9taXR0ZWQuIFVuZGVyXG4gKiBvcHRpbWlzdGljIGlubGluZSBzdGFydCB0aGUgYHN0ZXBfc3RhcnRlZGAgY2xhaW0gaXMgZGVsaWJlcmF0ZWx5IE5PVCBhd2FpdGVkXG4gKiBiZWZvcmUgdGhlIGJvZHkgcnVucywgc28gaXRzIGNvbXBsZXRpb24gaW5zdGFudCBkb2VzIG5vdCBleGlzdCB5ZXQgYXQgVDc7XG4gKiByYXRoZXIgdGhhbiBpbnZlbnQgb25lLCB0aGUgY2xhaW0gcGhhc2UgaXMgZHJvcHBlZCBhbmQgYHN0ZXBfcHJlcGFyZV9tc2BcbiAqIHNwYW5zIFQ14oaSVDcuIFRoZSBzdW0tZXF1YWxzLXRvdGFsIHByb3BlcnR5IGhvbGRzIGVpdGhlciB3YXkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlUmVzdW1lVHRyQXR0cmlidXRlcyhwYXJhbXM6IHtcbiAgdHJhY2tpbmc6IFJlc3VtZVR0clRyYWNraW5nIHwgdW5kZWZpbmVkO1xuICAvKiogVGhlIGF0dGVtcHQgbnVtYmVyIG9mIHRoZSBleGVjdXRpb24gYWJvdXQgdG8gcnVuLiAqL1xuICBhdHRlbXB0OiBudW1iZXI7XG4gIC8qKiBUNSDigJQgYERhdGUubm93KClgIGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgYHN0ZXBfc3RhcnRlZGAgcmVxdWVzdC4gKi9cbiAgc3RlcENsYWltU3RhcnRlZEF0TXM6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgLyoqIFQ2IOKAlCBgRGF0ZS5ub3coKWAgb25jZSB0aGUgYHN0ZXBfc3RhcnRlZGAgcmVzcG9uc2UgcmV0dXJuZWQuICovXG4gIHN0ZXBDbGFpbUNvbXBsZXRlZEF0TXM6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgLyoqIFQ3IOKAlCBgRGF0ZS5ub3coKWAgaW1tZWRpYXRlbHkgYmVmb3JlIGBzdGVwRm4uYXBwbHkoKWAuICovXG4gIHN0ZXBDb2RlU3RhcnRlZEF0TXM6IG51bWJlcjtcbn0pOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBudW1iZXI+IHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgeyB0cmFja2luZyB9ID0gcGFyYW1zO1xuICBpZiAoIXRyYWNraW5nIHx8IHBhcmFtcy5hdHRlbXB0ICE9PSAxKSByZXR1cm4gdW5kZWZpbmVkO1xuICBpZiAoXG4gICAgdHJhY2tpbmcucmVwbGF5U3RhcnRlZEF0TXMgPT09IHVuZGVmaW5lZCB8fFxuICAgIHRyYWNraW5nLm5leHRTdGVwRW5jb3VudGVyZWRBdE1zID09PSB1bmRlZmluZWQgfHxcbiAgICBwYXJhbXMuc3RlcENsYWltU3RhcnRlZEF0TXMgPT09IHVuZGVmaW5lZFxuICApIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgYm91bmRhcmllczogUmVzdW1lQm91bmRhcmllcyA9IHtcbiAgICByZXN1bWVSZXF1ZXN0ZWRBdE1zOiB0cmFja2luZy5yZXN1bWVSZXF1ZXN0ZWRBdE1zLFxuICAgIHF1ZXVlUHVibGlzaFJlcXVlc3RlZEF0TXM6IHRyYWNraW5nLnF1ZXVlUHVibGlzaFJlcXVlc3RlZEF0TXMsXG4gICAgY29uc3VtZXJTdGFydGVkQXRNczogdHJhY2tpbmcuY29uc3VtZXJTdGFydGVkQXRNcyxcbiAgICByZXBsYXlTdGFydGVkQXRNczogdHJhY2tpbmcucmVwbGF5U3RhcnRlZEF0TXMsXG4gICAgbmV4dFN0ZXBFbmNvdW50ZXJlZEF0TXM6IHRyYWNraW5nLm5leHRTdGVwRW5jb3VudGVyZWRBdE1zLFxuICAgIHN0ZXBDbGFpbVN0YXJ0ZWRBdE1zOiBwYXJhbXMuc3RlcENsYWltU3RhcnRlZEF0TXMsXG4gICAgc3RlcENsYWltQ29tcGxldGVkQXRNczogcGFyYW1zLnN0ZXBDbGFpbUNvbXBsZXRlZEF0TXMsXG4gICAgc3RlcENvZGVTdGFydGVkQXRNczogcGFyYW1zLnN0ZXBDb2RlU3RhcnRlZEF0TXMsXG4gIH07XG4gIGlmICghdmFsaWRhdGVCb3VuZGFyaWVzKGJvdW5kYXJpZXMpKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gIGNvbnN0IHtcbiAgICByZXN1bWVSZXF1ZXN0ZWRBdE1zOiB0MCxcbiAgICBxdWV1ZVB1Ymxpc2hSZXF1ZXN0ZWRBdE1zOiB0MSxcbiAgICBjb25zdW1lclN0YXJ0ZWRBdE1zOiB0MixcbiAgICByZXBsYXlTdGFydGVkQXRNczogdDMsXG4gICAgbmV4dFN0ZXBFbmNvdW50ZXJlZEF0TXM6IHQ0LFxuICAgIHN0ZXBDbGFpbVN0YXJ0ZWRBdE1zOiB0NSxcbiAgICBzdGVwQ2xhaW1Db21wbGV0ZWRBdE1zOiB0NixcbiAgICBzdGVwQ29kZVN0YXJ0ZWRBdE1zOiB0NyxcbiAgfSA9IGJvdW5kYXJpZXM7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5BdHRyaWJ1dGUuUmVzdW1lVG90YWxNcyh0NyAtIHQwKSxcbiAgICAuLi5BdHRyaWJ1dGUuUmVzdW1lUHJvZHVjZXJQcmVwTXModDEgLSB0MCksXG4gICAgLi4uQXR0cmlidXRlLlJlc3VtZVF1ZXVlRGVsaXZlcnlNcyh0MiAtIHQxKSxcbiAgICAuLi5BdHRyaWJ1dGUuUmVzdW1lU2V0dXBNcyh0MyAtIHQyKSxcbiAgICAuLi5BdHRyaWJ1dGUuUmVzdW1lUmVwbGF5TXModDQgLSB0MyksXG4gICAgLi4uQXR0cmlidXRlLlJlc3VtZVN0ZXBEaXNwYXRjaE1zKHQ1IC0gdDQpLFxuICAgIC4uLih0NiAhPT0gdW5kZWZpbmVkID8gQXR0cmlidXRlLlJlc3VtZVN0ZXBDbGFpbU1zKHQ2IC0gdDUpIDoge30pLFxuICAgIC4uLkF0dHJpYnV0ZS5SZXN1bWVTdGVwUHJlcGFyZU1zKHQ3IC0gKHQ2ID8/IHQ1KSksXG4gICAgLi4uQXR0cmlidXRlLlJlc3VtZVRyaWdnZXIodHJhY2tpbmcudHJpZ2dlciksXG4gICAgLi4uKHRyYWNraW5nLnN0cmF0ZWd5ICE9PSB1bmRlZmluZWRcbiAgICAgID8gQXR0cmlidXRlLlJlc3VtZVN0cmF0ZWd5KHRyYWNraW5nLnN0cmF0ZWd5KVxuICAgICAgOiB7fSksXG4gICAgLi4uKHRyYWNraW5nLnNldHVwU291cmNlICE9PSB1bmRlZmluZWRcbiAgICAgID8gQXR0cmlidXRlLlJlc3VtZVNldHVwU291cmNlKHRyYWNraW5nLnNldHVwU291cmNlKVxuICAgICAgOiB7fSksXG4gICAgLi4uQXR0cmlidXRlLlJlc3VtZVN0ZXBFeGVjdXRpb24odHJhY2tpbmcuc3RlcEV4ZWN1dGlvbiksXG4gIH07XG59XG4iXX0=
@@ -1,7 +1,8 @@
1
1
  import type { Event, SerializedData, World } from '@workflow/world';
2
2
  import type { PayloadKey } from '../serialization/encryption.js';
3
- import { type PreconditionSnapshotParams } from './helpers.js';
3
+ import { type SlotSnapshotParams } from './helpers.js';
4
4
  import { ReplayRecoveryReporter } from './replay-recovery-reporter.js';
5
+ import { type ResumeTtrTracking } from './resume-latency.js';
5
6
  import { type StepLatencyTracking } from './step-latency.js';
6
7
  export declare const DEFAULT_STEP_MAX_RETRIES = 3;
7
8
  export interface StepExecutorParams {
@@ -59,20 +60,25 @@ export interface StepExecutorParams {
59
60
  */
60
61
  inlineDeltaSinceCursor?: string;
61
62
  /**
62
- * Precondition-guard snapshot of the event log the caller's replay loaded, to
63
- * attach to this step's `step_started` claim. On the lazy inline path the
64
- * claim is the step's FIRST durable write (its `step_created` is deferred),
65
- * so without this the claim would bypass the optimistic-concurrency guard
66
- * entirely: a replay working from a stale view could claim — and then commit
67
- * — a step scheduled without observing an event it never loaded. A
68
- * guard-enforcing World rejects a stale claim with `PreconditionFailedError`
63
+ * How much of the run's log the caller's replay had loaded when it scheduled
64
+ * this step, as the highest slot that log occupies. Seeds the snapshot every
65
+ * write this executor makes carries; each committed event advances it to its
66
+ * own slot, so a later write never names a position that predates an earlier
67
+ * one from the same step.
68
+ *
69
+ * It matters most on the lazy inline path, where the `step_started` claim is
70
+ * the step's FIRST durable write (its `step_created` is deferred): without a
71
+ * seed the claim would name no position at all, and a replay working from a
72
+ * stale view could claim — and then commit — a step scheduled without
73
+ * observing an event it never loaded.
74
+ *
75
+ * A World that fences rejects a stale claim with `PreconditionFailedError`
69
76
  * (412); executeStep does NOT translate that rejection (re-claiming in place
70
77
  * would still commit the stale schedule), so it propagates for the caller to
71
- * abandon the batch and restart its replay. Undefined when the guard is
72
- * disabled or the caller has no snapshot; Worlds that don't enforce the guard
73
- * ignore it.
78
+ * abandon the batch and restart its replay. Undefined for a caller with
79
+ * nothing loaded.
74
80
  */
75
- preconditionSnapshot?: PreconditionSnapshotParams;
81
+ slotSnapshot?: SlotSnapshotParams;
76
82
  /**
77
83
  * Suppress optimistic inline start for this step regardless of
78
84
  * `WORKFLOW_OPTIMISTIC_INLINE_START` / `forceOptimisticStart`: take the
@@ -111,6 +117,15 @@ export interface StepExecutorParams {
111
117
  * runtime/step-latency.ts.
112
118
  */
113
119
  latencyTracking?: StepLatencyTracking;
120
+ /**
121
+ * Hook-resume TTR telemetry: the boundaries of a hook resumption whose next
122
+ * durable step is the one this call is about to execute. When set, the
123
+ * executor closes the measurement against the `step_started` claim and the
124
+ * wall clock taken immediately before user code, and attaches the total plus
125
+ * its phase breakdown to this step's `step.execute` span. Set by the runtime
126
+ * for exactly one step per resumption — see runtime/resume-latency.ts.
127
+ */
128
+ resumeTracking?: ResumeTtrTracking;
114
129
  /**
115
130
  * Authoritative attempt number for this execution, used to bound retries
116
131
  * against `maxRetries` BEFORE the body runs. In order to also catch
@@ -1 +1 @@
1
- {"version":3,"file":"step-executor.d.ts","sourceRoot":"","sources":["../../src/runtime/step-executor.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAGV,KAAK,EAEL,cAAc,EAEd,KAAK,EACN,MAAM,iBAAiB,CAAC;AAOzB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAuBjE,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,mBAAmB,CAAC;AAG3B,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAuB1C,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,KAAK,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,UAAU,CAAC;IAC3B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,cAAc,CAAC;IAC/B;;;;;;;;;;;;OAYG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;OAQG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;;;;;;;;;OAaG;IACH,oBAAoB,CAAC,EAAE,0BAA0B,CAAC;IAClD;;;;;;;;;;OAUG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC;;;;;;;;;OASG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,wEAAwE;IACxE,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;CACjD;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC,GACD;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,mBAAmB,CAAC,CA8jC9B"}
1
+ {"version":3,"file":"step-executor.d.ts","sourceRoot":"","sources":["../../src/runtime/step-executor.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAGV,KAAK,EAEL,cAAc,EAEd,KAAK,EACN,MAAM,iBAAiB,CAAC;AAQzB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAuBjE,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,mBAAmB,CAAC;AAG3B,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAuB1C,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,KAAK,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,UAAU,CAAC;IAC3B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,cAAc,CAAC;IAC/B;;;;;;;;;;;;OAYG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;OAQG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;;;;;;;;;;;;;;OAkBG;IACH,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC;;;;;;;;;;OAUG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,iBAAiB,CAAC;IACnC;;;;;;;;;OASG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,wEAAwE;IACxE,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;CACjD;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC,GACD;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,mBAAmB,CAAC,CAypC9B"}