@workflow/core 5.0.0-beta.3 → 5.0.0-beta.30

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 (268) hide show
  1. package/dist/attribute-changes.d.ts +7 -0
  2. package/dist/attribute-changes.d.ts.map +1 -0
  3. package/dist/attribute-changes.js +25 -0
  4. package/dist/capabilities.d.ts +22 -1
  5. package/dist/capabilities.d.ts.map +1 -1
  6. package/dist/capabilities.js +41 -4
  7. package/dist/capture-stack.d.ts +16 -0
  8. package/dist/capture-stack.d.ts.map +1 -0
  9. package/dist/capture-stack.js +21 -0
  10. package/dist/class-serialization.d.ts +32 -0
  11. package/dist/class-serialization.d.ts.map +1 -1
  12. package/dist/class-serialization.js +37 -1
  13. package/dist/classify-error.d.ts +26 -3
  14. package/dist/classify-error.d.ts.map +1 -1
  15. package/dist/classify-error.js +103 -6
  16. package/dist/context-errors.d.ts +27 -0
  17. package/dist/context-errors.d.ts.map +1 -0
  18. package/dist/context-errors.js +101 -0
  19. package/dist/context-violation-error.d.ts +97 -0
  20. package/dist/context-violation-error.d.ts.map +1 -0
  21. package/dist/context-violation-error.js +147 -0
  22. package/dist/create-hook.d.ts +42 -3
  23. package/dist/create-hook.d.ts.map +1 -1
  24. package/dist/create-hook.js +4 -3
  25. package/dist/define-hook.d.ts.map +1 -1
  26. package/dist/define-hook.js +20 -5
  27. package/dist/describe-error.d.ts +70 -0
  28. package/dist/describe-error.d.ts.map +1 -0
  29. package/dist/describe-error.js +165 -0
  30. package/dist/encryption.d.ts +22 -1
  31. package/dist/encryption.d.ts.map +1 -1
  32. package/dist/encryption.js +72 -27
  33. package/dist/events-consumer.d.ts +25 -1
  34. package/dist/events-consumer.d.ts.map +1 -1
  35. package/dist/events-consumer.js +95 -16
  36. package/dist/flushable-stream.d.ts +10 -10
  37. package/dist/flushable-stream.d.ts.map +1 -1
  38. package/dist/flushable-stream.js +26 -15
  39. package/dist/global.d.ts +35 -1
  40. package/dist/global.d.ts.map +1 -1
  41. package/dist/global.js +21 -3
  42. package/dist/index.d.ts +1 -0
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +2 -1
  45. package/dist/log-format.d.ts +25 -0
  46. package/dist/log-format.d.ts.map +1 -0
  47. package/dist/log-format.js +250 -0
  48. package/dist/logger.d.ts +29 -30
  49. package/dist/logger.d.ts.map +1 -1
  50. package/dist/logger.js +82 -32
  51. package/dist/private.d.ts +107 -2
  52. package/dist/private.d.ts.map +1 -1
  53. package/dist/private.js +80 -3
  54. package/dist/runtime/constants.d.ts +189 -0
  55. package/dist/runtime/constants.d.ts.map +1 -1
  56. package/dist/runtime/constants.js +310 -15
  57. package/dist/runtime/get-port-lazy.d.ts +25 -0
  58. package/dist/runtime/get-port-lazy.d.ts.map +1 -0
  59. package/dist/runtime/get-port-lazy.js +92 -0
  60. package/dist/runtime/get-world-lazy.d.ts +23 -0
  61. package/dist/runtime/get-world-lazy.d.ts.map +1 -0
  62. package/dist/runtime/get-world-lazy.js +46 -0
  63. package/dist/runtime/helpers.d.ts +57 -6
  64. package/dist/runtime/helpers.d.ts.map +1 -1
  65. package/dist/runtime/helpers.js +169 -32
  66. package/dist/runtime/replay-budget.d.ts +98 -0
  67. package/dist/runtime/replay-budget.d.ts.map +1 -0
  68. package/dist/runtime/replay-budget.js +192 -0
  69. package/dist/runtime/resume-hook.d.ts.map +1 -1
  70. package/dist/runtime/resume-hook.js +39 -23
  71. package/dist/runtime/run-id-time.d.ts +10 -0
  72. package/dist/runtime/run-id-time.d.ts.map +1 -0
  73. package/dist/runtime/run-id-time.js +31 -0
  74. package/dist/runtime/run.d.ts +6 -2
  75. package/dist/runtime/run.d.ts.map +1 -1
  76. package/dist/runtime/run.js +52 -10
  77. package/dist/runtime/runs.d.ts +36 -2
  78. package/dist/runtime/runs.d.ts.map +1 -1
  79. package/dist/runtime/runs.js +18 -7
  80. package/dist/runtime/start.d.ts +58 -1
  81. package/dist/runtime/start.d.ts.map +1 -1
  82. package/dist/runtime/start.js +160 -46
  83. package/dist/runtime/step-executor.d.ts +131 -0
  84. package/dist/runtime/step-executor.d.ts.map +1 -0
  85. package/dist/runtime/step-executor.js +818 -0
  86. package/dist/runtime/step-handler.d.ts.map +1 -1
  87. package/dist/runtime/step-handler.js +718 -557
  88. package/dist/runtime/step-latency.d.ts +131 -0
  89. package/dist/runtime/step-latency.d.ts.map +1 -0
  90. package/dist/runtime/step-latency.js +155 -0
  91. package/dist/runtime/step-ownership.d.ts +72 -0
  92. package/dist/runtime/step-ownership.d.ts.map +1 -0
  93. package/dist/runtime/step-ownership.js +114 -0
  94. package/dist/runtime/step-single-flight.d.ts +12 -0
  95. package/dist/runtime/step-single-flight.d.ts.map +1 -0
  96. package/dist/runtime/step-single-flight.js +69 -0
  97. package/dist/runtime/suspension-handler.d.ts +81 -7
  98. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  99. package/dist/runtime/suspension-handler.js +355 -137
  100. package/dist/runtime/wait-continuation.d.ts +84 -0
  101. package/dist/runtime/wait-continuation.d.ts.map +1 -0
  102. package/dist/runtime/wait-continuation.js +105 -0
  103. package/dist/runtime/wait-until.d.ts +18 -0
  104. package/dist/runtime/wait-until.d.ts.map +1 -0
  105. package/dist/runtime/wait-until.js +42 -0
  106. package/dist/runtime/world-compatibility.d.ts +5 -0
  107. package/dist/runtime/world-compatibility.d.ts.map +1 -0
  108. package/dist/runtime/world-compatibility.js +12 -0
  109. package/dist/runtime/world-init.d.ts +50 -0
  110. package/dist/runtime/world-init.d.ts.map +1 -0
  111. package/dist/runtime/world-init.js +50 -0
  112. package/dist/runtime/world-target.d.ts +11 -0
  113. package/dist/runtime/world-target.d.ts.map +1 -0
  114. package/dist/runtime/world-target.js +15 -0
  115. package/dist/runtime/world.d.ts +21 -9
  116. package/dist/runtime/world.d.ts.map +1 -1
  117. package/dist/runtime/world.js +58 -83
  118. package/dist/runtime.d.ts +15 -10
  119. package/dist/runtime.d.ts.map +1 -1
  120. package/dist/runtime.js +1757 -326
  121. package/dist/schemas.d.ts +1 -1
  122. package/dist/schemas.d.ts.map +1 -1
  123. package/dist/schemas.js +1 -1
  124. package/dist/serialization/client.d.ts +17 -0
  125. package/dist/serialization/client.d.ts.map +1 -0
  126. package/dist/serialization/client.js +48 -0
  127. package/dist/serialization/codec-devalue.d.ts +14 -0
  128. package/dist/serialization/codec-devalue.d.ts.map +1 -0
  129. package/dist/serialization/codec-devalue.js +98 -0
  130. package/dist/serialization/codec.d.ts +106 -0
  131. package/dist/serialization/codec.d.ts.map +1 -0
  132. package/dist/serialization/codec.js +17 -0
  133. package/dist/serialization/compression.d.ts +104 -0
  134. package/dist/serialization/compression.d.ts.map +1 -0
  135. package/dist/serialization/compression.js +260 -0
  136. package/dist/serialization/encryption.d.ts +33 -0
  137. package/dist/serialization/encryption.d.ts.map +1 -0
  138. package/dist/serialization/encryption.js +70 -0
  139. package/dist/serialization/errors.d.ts +34 -0
  140. package/dist/serialization/errors.d.ts.map +1 -0
  141. package/dist/serialization/errors.js +59 -0
  142. package/dist/serialization/format.d.ts +60 -0
  143. package/dist/serialization/format.d.ts.map +1 -0
  144. package/dist/serialization/format.js +97 -0
  145. package/dist/serialization/index.d.ts +19 -0
  146. package/dist/serialization/index.d.ts.map +1 -0
  147. package/dist/serialization/index.js +22 -0
  148. package/dist/serialization/reducers/class.d.ts +11 -0
  149. package/dist/serialization/reducers/class.d.ts.map +1 -0
  150. package/dist/serialization/reducers/class.js +68 -0
  151. package/dist/serialization/reducers/common.d.ts +16 -0
  152. package/dist/serialization/reducers/common.d.ts.map +1 -0
  153. package/dist/serialization/reducers/common.js +417 -0
  154. package/dist/serialization/reducers/step-function.d.ts +35 -0
  155. package/dist/serialization/reducers/step-function.d.ts.map +1 -0
  156. package/dist/serialization/reducers/step-function.js +88 -0
  157. package/dist/serialization/step.d.ts +17 -0
  158. package/dist/serialization/step.d.ts.map +1 -0
  159. package/dist/serialization/step.js +48 -0
  160. package/dist/serialization/types.d.ts +253 -0
  161. package/dist/serialization/types.d.ts.map +1 -0
  162. package/dist/serialization/types.js +25 -0
  163. package/dist/serialization/workflow.d.ts +29 -0
  164. package/dist/serialization/workflow.d.ts.map +1 -0
  165. package/dist/serialization/workflow.js +54 -0
  166. package/dist/serialization-format.d.ts +16 -0
  167. package/dist/serialization-format.d.ts.map +1 -1
  168. package/dist/serialization-format.js +213 -50
  169. package/dist/serialization.d.ts +322 -214
  170. package/dist/serialization.d.ts.map +1 -1
  171. package/dist/serialization.js +1575 -664
  172. package/dist/set-attributes.d.ts +13 -0
  173. package/dist/set-attributes.d.ts.map +1 -0
  174. package/dist/set-attributes.js +56 -0
  175. package/dist/sleep.d.ts.map +1 -1
  176. package/dist/sleep.js +3 -2
  177. package/dist/source-map.d.ts +5 -0
  178. package/dist/source-map.d.ts.map +1 -1
  179. package/dist/source-map.js +102 -10
  180. package/dist/step/context-storage.d.ts +53 -0
  181. package/dist/step/context-storage.d.ts.map +1 -1
  182. package/dist/step/context-storage.js +1 -1
  183. package/dist/step/get-closure-vars.d.ts.map +1 -1
  184. package/dist/step/get-closure-vars.js +3 -2
  185. package/dist/step/get-step-metadata.d.ts.map +1 -1
  186. package/dist/step/get-step-metadata.js +3 -2
  187. package/dist/step/get-workflow-metadata.d.ts.map +1 -1
  188. package/dist/step/get-workflow-metadata.js +3 -2
  189. package/dist/step/writable-stream.d.ts.map +1 -1
  190. package/dist/step/writable-stream.js +58 -6
  191. package/dist/step-hydration-cache.d.ts +148 -0
  192. package/dist/step-hydration-cache.d.ts.map +1 -0
  193. package/dist/step-hydration-cache.js +171 -0
  194. package/dist/step.d.ts.map +1 -1
  195. package/dist/step.js +144 -25
  196. package/dist/symbols.d.ts +28 -0
  197. package/dist/symbols.d.ts.map +1 -1
  198. package/dist/symbols.js +29 -1
  199. package/dist/telemetry/semantic-conventions.d.ts +98 -2
  200. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  201. package/dist/telemetry/semantic-conventions.js +66 -1
  202. package/dist/telemetry.d.ts +68 -0
  203. package/dist/telemetry.d.ts.map +1 -1
  204. package/dist/telemetry.js +106 -4
  205. package/dist/types.d.ts +6 -0
  206. package/dist/types.d.ts.map +1 -1
  207. package/dist/types.js +23 -1
  208. package/dist/util.d.ts +16 -6
  209. package/dist/util.d.ts.map +1 -1
  210. package/dist/util.js +25 -16
  211. package/dist/version.d.ts +1 -1
  212. package/dist/version.d.ts.map +1 -1
  213. package/dist/version.js +2 -2
  214. package/dist/vm/index.d.ts.map +1 -1
  215. package/dist/vm/index.js +3 -2
  216. package/dist/vm/script-cache.d.ts +28 -0
  217. package/dist/vm/script-cache.d.ts.map +1 -0
  218. package/dist/vm/script-cache.js +140 -0
  219. package/dist/workflow/abort-controller.d.ts +65 -0
  220. package/dist/workflow/abort-controller.d.ts.map +1 -0
  221. package/dist/workflow/abort-controller.js +277 -0
  222. package/dist/workflow/attribute-dispatcher.d.ts +6 -0
  223. package/dist/workflow/attribute-dispatcher.d.ts.map +1 -0
  224. package/dist/workflow/attribute-dispatcher.js +48 -0
  225. package/dist/workflow/create-hook.d.ts.map +1 -1
  226. package/dist/workflow/create-hook.js +25 -3
  227. package/dist/workflow/define-hook.d.ts +1 -1
  228. package/dist/workflow/define-hook.d.ts.map +1 -1
  229. package/dist/workflow/define-hook.js +8 -4
  230. package/dist/workflow/get-workflow-metadata.d.ts.map +1 -1
  231. package/dist/workflow/get-workflow-metadata.js +14 -3
  232. package/dist/workflow/hook.d.ts.map +1 -1
  233. package/dist/workflow/hook.js +207 -33
  234. package/dist/workflow/index.d.ts +1 -0
  235. package/dist/workflow/index.d.ts.map +1 -1
  236. package/dist/workflow/index.js +5 -3
  237. package/dist/workflow/set-attributes.d.ts +73 -0
  238. package/dist/workflow/set-attributes.d.ts.map +1 -0
  239. package/dist/workflow/set-attributes.js +65 -0
  240. package/dist/workflow/sleep.d.ts.map +1 -1
  241. package/dist/workflow/sleep.js +45 -8
  242. package/dist/workflow/world-init-stub.d.ts +15 -0
  243. package/dist/workflow/world-init-stub.d.ts.map +1 -0
  244. package/dist/workflow/world-init-stub.js +15 -0
  245. package/dist/workflow.d.ts +17 -1
  246. package/dist/workflow.d.ts.map +1 -1
  247. package/dist/workflow.js +190 -56
  248. package/docs/api-reference/create-hook.mdx +38 -0
  249. package/docs/api-reference/create-webhook.mdx +1 -0
  250. package/docs/api-reference/experimental-set-attributes.mdx +65 -0
  251. package/docs/api-reference/fetch.mdx +5 -0
  252. package/docs/api-reference/index.mdx +3 -0
  253. package/docs/foundations/cancellation.mdx +459 -0
  254. package/docs/foundations/errors-and-retries.mdx +7 -3
  255. package/docs/foundations/hooks.mdx +29 -0
  256. package/docs/foundations/idempotency.mdx +236 -11
  257. package/docs/foundations/index.mdx +1 -23
  258. package/docs/foundations/meta.json +3 -1
  259. package/docs/foundations/serialization.mdx +77 -41
  260. package/docs/foundations/starting-workflows.mdx +5 -1
  261. package/docs/foundations/streaming.mdx +14 -23
  262. package/docs/foundations/versioning.mdx +263 -0
  263. package/docs/how-it-works/cancellation.mdx +287 -0
  264. package/docs/how-it-works/code-transform.mdx +2 -2
  265. package/docs/how-it-works/encryption.mdx +2 -2
  266. package/docs/how-it-works/event-sourcing.mdx +2 -2
  267. package/docs/how-it-works/meta.json +2 -1
  268. package/package.json +32 -11
@@ -1,10 +1,12 @@
1
- import { HealthCheckPayloadSchema, SPEC_VERSION_CURRENT, SPEC_VERSION_LEGACY, } from '@workflow/world';
1
+ import { RUN_ERROR_CODES, WorkflowWorldError } from '@workflow/errors';
2
+ import { getQueueTopicPrefix, HealthCheckPayloadSchema, resolveQueueNamespace, SPEC_VERSION_CURRENT, SPEC_VERSION_LEGACY, } from '@workflow/world';
2
3
  import { monotonicFactory } from 'ulid';
4
+ import { importKey } from '../encryption.js';
3
5
  import { runtimeLogger } from '../logger.js';
4
6
  import * as Attribute from '../telemetry/semantic-conventions.js';
5
7
  import { getSpanKind, trace } from '../telemetry.js';
6
8
  import { version as workflowCoreVersion } from '../version.js';
7
- import { getWorld } from './world.js';
9
+ import { getWorldLazy } from './get-world-lazy.js';
8
10
  /** Default timeout for health checks in milliseconds */
9
11
  const DEFAULT_HEALTH_CHECK_TIMEOUT = 30_000;
10
12
  /**
@@ -18,11 +20,12 @@ const SAFE_WORKFLOW_NAME_PATTERN = /^[a-zA-Z0-9_\-./@]+$/;
18
20
  * Ensures the workflow name only contains safe characters before
19
21
  * interpolating it into the queue name string.
20
22
  */
21
- export function getWorkflowQueueName(workflowName) {
23
+ export function getWorkflowQueueName(workflowName, namespace) {
22
24
  if (!SAFE_WORKFLOW_NAME_PATTERN.test(workflowName)) {
23
25
  throw new Error(`Invalid workflow name "${workflowName}": must only contain alphanumeric characters, underscores, hyphens, dots, forward slashes, or at signs`);
24
26
  }
25
- return `__wkf_workflow_${workflowName}`;
27
+ const prefix = getQueueTopicPrefix('workflow', resolveQueueNamespace(namespace));
28
+ return `${prefix}${workflowName}`;
26
29
  }
27
30
  const generateId = monotonicFactory();
28
31
  /**
@@ -59,7 +62,7 @@ function generateHealthCheckRunId(correlationId) {
59
62
  * @param endpoint - Which endpoint is responding ('workflow' or 'step')
60
63
  */
61
64
  export async function handleHealthCheckMessage(healthCheck, endpoint, worldSpecVersion) {
62
- const world = await getWorld();
65
+ const world = await getWorldLazy();
63
66
  const streamName = getHealthCheckStreamName(healthCheck.correlationId);
64
67
  const response = JSON.stringify({
65
68
  healthy: true,
@@ -96,6 +99,24 @@ const HEALTH_CHECK_READ_TIMEOUT = 500;
96
99
  * Read chunks from a stream with a timeout per read operation.
97
100
  * Returns { chunks, timedOut } where timedOut indicates if a read timed out.
98
101
  */
102
+ /**
103
+ * Race a promise against a deadline. Rejects with a timeout error when the
104
+ * deadline elapses first. Used to bound `world.streams.get()` inside the
105
+ * health-check poll loop: some worlds hold that request open until the
106
+ * stream has data (e.g. workflow-server holds unwritten streams open for
107
+ * ~2 minutes), which would otherwise blow through the configured health
108
+ * check timeout — the `while` condition is only re-checked between
109
+ * iterations.
110
+ */
111
+ function withDeadline(promise, ms) {
112
+ let timer;
113
+ return Promise.race([
114
+ promise,
115
+ new Promise((_, reject) => {
116
+ timer = setTimeout(() => reject(new Error(`Operation timed out after ${ms}ms`)), ms);
117
+ }),
118
+ ]).finally(() => clearTimeout(timer));
119
+ }
99
120
  async function readStreamWithTimeout(reader, readTimeout) {
100
121
  const chunks = [];
101
122
  let done = false;
@@ -154,15 +175,16 @@ function parseHealthCheckResponse(chunks) {
154
175
  if (typeof r.specVersion === 'number') {
155
176
  parsed.specVersion = r.specVersion;
156
177
  }
178
+ if (typeof r.workflowCoreVersion === 'string') {
179
+ parsed.workflowCoreVersion = r.workflowCoreVersion;
180
+ }
157
181
  return parsed;
158
182
  }
159
183
  export async function healthCheck(world, endpoint, options) {
160
184
  const timeout = options?.timeout ?? DEFAULT_HEALTH_CHECK_TIMEOUT;
161
185
  const correlationId = generateId();
162
186
  const streamName = getHealthCheckStreamName(correlationId);
163
- const queueName = endpoint === 'workflow'
164
- ? '__wkf_workflow_health_check'
165
- : '__wkf_step_health_check';
187
+ const queueName = `${getQueueTopicPrefix(endpoint, resolveQueueNamespace(options?.namespace))}health_check`;
166
188
  const startTime = Date.now();
167
189
  try {
168
190
  await world.queue(queueName, { __healthCheck: true, correlationId }, {
@@ -173,7 +195,8 @@ export async function healthCheck(world, endpoint, options) {
173
195
  });
174
196
  while (Date.now() - startTime < timeout) {
175
197
  try {
176
- const stream = await world.streams.get(generateHealthCheckRunId(correlationId), streamName);
198
+ const remainingMs = timeout - (Date.now() - startTime);
199
+ const stream = await withDeadline(world.streams.get(generateHealthCheckRunId(correlationId), streamName), remainingMs);
177
200
  const reader = stream.getReader();
178
201
  const { chunks, timedOut } = await readStreamWithTimeout(reader, HEALTH_CHECK_READ_TIMEOUT);
179
202
  if (timedOut) {
@@ -211,58 +234,133 @@ export async function healthCheck(world, endpoint, options) {
211
234
  };
212
235
  }
213
236
  }
237
+ function eventPaginationContractError(runId, message) {
238
+ return new WorkflowWorldError(`Event pagination ${message} for workflow run "${runId}".`, { code: RUN_ERROR_CODES.WORLD_CONTRACT_ERROR });
239
+ }
240
+ function recordRequestedEventCursor(runId, cursor, requestedCursors) {
241
+ if (!cursor) {
242
+ return;
243
+ }
244
+ if (requestedCursors.has(cursor)) {
245
+ throw eventPaginationContractError(runId, 'did not advance');
246
+ }
247
+ requestedCursors.add(cursor);
248
+ }
249
+ function appendUniqueEvents(target, targetIds, events) {
250
+ for (const event of events) {
251
+ if (!targetIds.has(event.eventId)) {
252
+ targetIds.add(event.eventId);
253
+ target.push(event);
254
+ }
255
+ }
256
+ }
257
+ function assertEventPaginationProgress(runId, hasMore, cursor, requestedCursors) {
258
+ if (!hasMore) {
259
+ return;
260
+ }
261
+ if (cursor === null) {
262
+ throw eventPaginationContractError(runId, 'returned more pages without a cursor');
263
+ }
264
+ if (requestedCursors.has(cursor)) {
265
+ throw eventPaginationContractError(runId, 'repeated a cursor');
266
+ }
267
+ }
268
+ function shouldRetryWithoutEventCursor(error, cursor, alreadyRetried) {
269
+ return (cursor !== null &&
270
+ !alreadyRetried &&
271
+ WorkflowWorldError.is(error) &&
272
+ error.status === 400);
273
+ }
214
274
  /**
215
- * Loads all workflow run events by iterating through all pages of paginated results.
216
- * This ensures that *all* events are loaded into memory before running the workflow.
217
- * Events must be in chronological order (ascending) for proper workflow replay.
275
+ * Loads workflow run events by iterating through all pages of paginated
276
+ * results. Events are returned in chronological (ascending) order for
277
+ * deterministic workflow replay.
278
+ *
279
+ * @param runId - The workflow run ID.
280
+ * @param afterCursor - If provided, only events after this cursor are
281
+ * returned (incremental load). If omitted, all events are returned.
282
+ * The returned cursor can be passed back in on a subsequent call for
283
+ * incremental loading.
218
284
  */
219
- export async function getAllWorkflowRunEvents(runId) {
220
- return trace('workflow.loadEvents', async (span) => {
285
+ export async function loadWorkflowRunEvents(runId, afterCursor) {
286
+ const incremental = afterCursor !== undefined;
287
+ return trace(incremental ? 'workflow.loadNewEvents' : 'workflow.loadEvents', async (span) => {
221
288
  span?.setAttributes({
222
289
  ...Attribute.WorkflowRunId(runId),
223
290
  });
224
- const allEvents = [];
225
- let cursor = null;
291
+ const loadedEvents = [];
292
+ const loadedEventIds = new Set();
293
+ const requestedCursors = new Set();
294
+ let cursor = afterCursor ?? null;
226
295
  let hasMore = true;
227
296
  let pagesLoaded = 0;
228
- const world = await getWorld();
297
+ let retriedWithoutCursor = false;
298
+ const world = await getWorldLazy();
229
299
  const loadStart = Date.now();
230
300
  while (hasMore) {
231
301
  // TODO: we're currently loading all the data with resolveRef behaviour. We need to update this
232
302
  // to lazyload the data from the world instead so that we can optimize and make the event log loading
233
303
  // much faster and memory efficient
234
304
  const pageStart = Date.now();
235
- const response = await world.events.list({
236
- runId,
237
- pagination: {
238
- sortOrder: 'asc', // Required: events must be in chronological order for replay
239
- cursor: cursor ?? undefined,
240
- },
241
- });
242
- allEvents.push(...response.data);
305
+ const requestedCursor = cursor;
306
+ recordRequestedEventCursor(runId, requestedCursor, requestedCursors);
307
+ let response;
308
+ try {
309
+ response = await world.events.list({
310
+ runId,
311
+ pagination: {
312
+ sortOrder: 'asc',
313
+ cursor: requestedCursor ?? undefined,
314
+ },
315
+ });
316
+ }
317
+ catch (error) {
318
+ if (shouldRetryWithoutEventCursor(error, requestedCursor, retriedWithoutCursor)) {
319
+ runtimeLogger.warn('Event cursor was rejected; retrying with a full event reload.', { workflowRunId: runId });
320
+ loadedEvents.length = 0;
321
+ loadedEventIds.clear();
322
+ requestedCursors.clear();
323
+ cursor = null;
324
+ retriedWithoutCursor = true;
325
+ continue;
326
+ }
327
+ throw error;
328
+ }
329
+ appendUniqueEvents(loadedEvents, loadedEventIds, response.data);
243
330
  hasMore = response.hasMore;
244
- cursor = response.cursor;
331
+ assertEventPaginationProgress(runId, hasMore, response.cursor, requestedCursors);
332
+ // Preserve the last non-null cursor across pages. A World may
333
+ // legitimately return `{ data: [], cursor: null, hasMore: false }`
334
+ // on a trailing empty page — for example when the previous page's
335
+ // underlying DB query hit the limit exactly and returned a
336
+ // `LastEvaluatedKey` "just in case". Overwriting with that null
337
+ // would lose the position past the last real event we loaded and
338
+ // force the runtime into the "no cursor after initial load" full-
339
+ // reload fallback on every subsequent replay iteration.
340
+ cursor = response.cursor ?? cursor;
245
341
  pagesLoaded++;
246
342
  runtimeLogger.debug('Loaded event page', {
247
343
  workflowRunId: runId,
344
+ incremental,
248
345
  page: pagesLoaded,
249
346
  pageEvents: response.data.length,
250
- totalEvents: allEvents.length,
347
+ totalEvents: loadedEvents.length,
251
348
  hasMore,
252
349
  pageMs: Date.now() - pageStart,
253
350
  });
254
351
  }
255
- runtimeLogger.debug('Event loading complete', {
352
+ runtimeLogger.debug('Event load complete', {
256
353
  workflowRunId: runId,
257
- totalEvents: allEvents.length,
354
+ incremental,
355
+ totalEvents: loadedEvents.length,
258
356
  pagesLoaded,
259
357
  totalMs: Date.now() - loadStart,
260
358
  });
261
359
  span?.setAttributes({
262
- ...Attribute.WorkflowEventsCount(allEvents.length),
360
+ ...Attribute.WorkflowEventsCount(loadedEvents.length),
263
361
  ...Attribute.WorkflowEventsPagesLoaded(pagesLoaded),
264
362
  });
265
- return allEvents;
363
+ return { events: loadedEvents, cursor };
266
364
  });
267
365
  }
268
366
  /**
@@ -344,4 +442,43 @@ export function getQueueOverhead(message) {
344
442
  return;
345
443
  }
346
444
  }
347
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW50aW1lL2hlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTUEsT0FBTyxFQUNMLHdCQUF3QixFQUN4QixvQkFBb0IsRUFDcEIsbUJBQW1CLEdBQ3BCLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXhDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDN0MsT0FBTyxLQUFLLFNBQVMsTUFBTSxzQ0FBc0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxPQUFPLElBQUksbUJBQW1CLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUV0Qyx3REFBd0Q7QUFDeEQsTUFBTSw0QkFBNEIsR0FBRyxNQUFNLENBQUM7QUFFNUM7Ozs7R0FJRztBQUNILE1BQU0sMEJBQTBCLEdBQUcsc0JBQXNCLENBQUM7QUFFMUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxZQUFvQjtJQUN2RCxJQUFJLENBQUMsMEJBQTBCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7UUFDbkQsTUFBTSxJQUFJLEtBQUssQ0FDYiwwQkFBMEIsWUFBWSx3R0FBd0csQ0FDL0ksQ0FBQztJQUNKLENBQUM7SUFDRCxPQUFPLGtCQUFrQixZQUFZLEVBQW9CLENBQUM7QUFDNUQsQ0FBQztBQUVELE1BQU0sVUFBVSxHQUFHLGdCQUFnQixFQUFFLENBQUM7QUFFdEM7O0dBRUc7QUFDSCxTQUFTLHdCQUF3QixDQUFDLGFBQXFCO0lBQ3JELE9BQU8sbUJBQW1CLGFBQWEsRUFBRSxDQUFDO0FBQzVDLENBQUM7QUFlRDs7O0dBR0c7QUFD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LHdCQUF3QixDQUFDLFNBQVMsQ0FBQztZQUNoRCxHQUFHLFNBQVMsQ0FBQyxzQkFBc0IsQ0FBQyxTQUFTLENBQUM7WUFDOUMsd0NBQXdDO1lBQ3hDLEdBQUcsU0FBUyxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUM7WUFDeEMsR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQztZQUN0QyxHQUFHLFNBQVMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDO1lBQzlCLEdBQUcsU0FBUyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUM7U0FDbEM7UUFDRCxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUMsVUFBVSxDQUFDO0tBQ3BDLEVBQ0QsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFO1FBQ2IsTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQ2pELElBQUksU0FBUyxFQUFFLENBQUM7WUFDZCxJQUFJLEVBQUUsYUFBYSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQy9ELENBQUM7SUFDSCxDQUFDLENBQ0YsQ0FBQztBQUNKLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxPQUErQjtJQUM5RCxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVc7UUFBRSxPQUFPO0lBQ2pDLElBQUksQ0FBQztRQUNILE9BQU8sU0FBUyxDQUFDLGVBQWUsQ0FDOUIsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLENBQzNDLENBQUM7SUFDSixDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTztJQUNULENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUge1xuICBFdmVudCxcbiAgSGVhbHRoQ2hlY2tQYXlsb2FkLFxuICBWYWxpZFF1ZXVlTmFtZSxcbiAgV29ybGQsXG59IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQge1xuICBIZWFsdGhDaGVja1BheWxvYWRTY2hlbWEsXG4gIFNQRUNfVkVSU0lPTl9DVVJSRU5ULFxuICBTUEVDX1ZFUlNJT05fTEVHQUNZLFxufSBmcm9tICdAd29ya2Zsb3cvd29ybGQnO1xuaW1wb3J0IHsgbW9ub3RvbmljRmFjdG9yeSB9IGZyb20gJ3VsaWQnO1xuXG5pbXBvcnQgeyBydW50aW1lTG9nZ2VyIH0gZnJvbSAnLi4vbG9nZ2VyLmpzJztcbmltcG9ydCAqIGFzIEF0dHJpYnV0ZSBmcm9tICcuLi90ZWxlbWV0cnkvc2VtYW50aWMtY29udmVudGlvbnMuanMnO1xuaW1wb3J0IHsgZ2V0U3BhbktpbmQsIHRyYWNlIH0gZnJvbSAnLi4vdGVsZW1ldHJ5LmpzJztcbmltcG9ydCB7IHZlcnNpb24gYXMgd29ya2Zsb3dDb3JlVmVyc2lvbiB9IGZyb20gJy4uL3ZlcnNpb24uanMnO1xuaW1wb3J0IHsgZ2V0V29ybGQgfSBmcm9tICcuL3dvcmxkLmpzJztcblxuLyoqIERlZmF1bHQgdGltZW91dCBmb3IgaGVhbHRoIGNoZWNrcyBpbiBtaWxsaXNlY29uZHMgKi9cbmNvbnN0IERFRkFVTFRfSEVBTFRIX0NIRUNLX1RJTUVPVVQgPSAzMF8wMDA7XG5cbi8qKlxuICogUGF0dGVybiBmb3Igc2FmZSB3b3JrZmxvdyBuYW1lcy4gT25seSBhbGxvd3MgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMsXG4gKiB1bmRlcnNjb3JlcywgaHlwaGVucywgZG90cywgZm9yd2FyZCBzbGFzaGVzIChmb3IgbmFtZXNwYWNlZCB3b3JrZmxvd3MpLFxuICogYW5kIGF0IHNpZ25zIChmb3Igc2NvcGVkIHBhY2thZ2VzKS5cbiAqL1xuY29uc3QgU0FGRV9XT1JLRkxPV19OQU1FX1BBVFRFUk4gPSAvXlthLXpBLVowLTlfXFwtLi9AXSskLztcblxuLyoqXG4gKiBWYWxpZGF0ZXMgYSB3b3JrZmxvdyBuYW1lIGFuZCByZXR1cm5zIHRoZSBjb3JyZXNwb25kaW5nIHF1ZXVlIG5hbWUuXG4gKiBFbnN1cmVzIHRoZSB3b3JrZmxvdyBuYW1lIG9ubHkgY29udGFpbnMgc2FmZSBjaGFyYWN0ZXJzIGJlZm9yZVxuICogaW50ZXJwb2xhdGluZyBpdCBpbnRvIHRoZSBxdWV1ZSBuYW1lIHN0cmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmtmbG93UXVldWVOYW1lKHdvcmtmbG93TmFtZTogc3RyaW5nKTogVmFsaWRRdWV1ZU5hbWUge1xuICBpZiAoIVNBRkVfV09SS0ZMT1dfTkFNRV9QQVRURVJOLnRlc3Qod29ya2Zsb3dOYW1lKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBJbnZhbGlkIHdvcmtmbG93IG5hbWUgXCIke3dvcmtmbG93TmFtZX1cIjogbXVzdCBvbmx5IGNvbnRhaW4gYWxwaGFudW1lcmljIGNoYXJhY3RlcnMsIHVuZGVyc2NvcmVzLCBoeXBoZW5zLCBkb3RzLCBmb3J3YXJkIHNsYXNoZXMsIG9yIGF0IHNpZ25zYFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGBfX3drZl93b3JrZmxvd18ke3dvcmtmbG93TmFtZX1gIGFzIFZhbGlkUXVldWVOYW1lO1xufVxuXG5jb25zdCBnZW5lcmF0ZUlkID0gbW9ub3RvbmljRmFjdG9yeSgpO1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHN0cmVhbSBuYW1lIGZvciBhIGhlYWx0aCBjaGVjayB3aXRoIHRoZSBnaXZlbiBjb3JyZWxhdGlvbiBJRC5cbiAqL1xuZnVuY3Rpb24gZ2V0SGVhbHRoQ2hlY2tTdHJlYW1OYW1lKGNvcnJlbGF0aW9uSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgX19oZWFsdGhfY2hlY2tfXyR7Y29ycmVsYXRpb25JZH1gO1xufVxuXG4vKipcbiAqIFJlc3VsdCBvZiBhIGhlYWx0aCBjaGVjayBvcGVyYXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSGVhbHRoQ2hlY2tSZXN1bHQge1xuICBoZWFsdGh5OiBib29sZWFuO1xuICAvKiogRXJyb3IgbWVzc2FnZSBpZiBoZWFsdGggY2hlY2sgZmFpbGVkICovXG4gIGVycm9yPzogc3RyaW5nO1xuICAvKiogTGF0ZW5jeSBpZiB0aGUgaGVhbHRoIGNoZWNrIHdhcyBzdWNjZXNzZnVsICovXG4gIGxhdGVuY3lNcz86IG51bWJlcjtcbiAgLyoqIFNwZWMgdmVyc2lvbiBvZiB0aGUgcmVzcG9uZGluZyBkZXBsb3ltZW50ICovXG4gIHNwZWNWZXJzaW9uPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gbWVzc2FnZSBpcyBhIGhlYWx0aCBjaGVjayBwYXlsb2FkLlxuICogSWYgc28sIHJldHVybnMgdGhlIHBhcnNlZCBwYXlsb2FkLiBPdGhlcndpc2UgcmV0dXJucyB1bmRlZmluZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUhlYWx0aENoZWNrUGF5bG9hZChcbiAgbWVzc2FnZTogdW5rbm93blxuKTogSGVhbHRoQ2hlY2tQYXlsb2FkIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcmVzdWx0ID0gSGVhbHRoQ2hlY2tQYXlsb2FkU2NoZW1hLnNhZmVQYXJzZShtZXNzYWdlKTtcbiAgaWYgKHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgcmV0dXJuIHJlc3VsdC5kYXRhO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgZGV0ZXJtaW5pc3RpYyBmYWtlIHJ1bklkIGZvciBoZWFsdGggY2hlY2sgc3RyZWFtcy5cbiAqIEJvdGggdGhlIHdyaXRlciAoaGFuZGxlSGVhbHRoQ2hlY2tNZXNzYWdlKSBhbmQgcmVhZGVyIChoZWFsdGhDaGVjaykgZGVyaXZlXG4gKiB0aGUgc2FtZSBydW5JZCBmcm9tIHRoZSBjb3JyZWxhdGlvbklkIHNvIHRoYXQgaW1wbGVtZW50YXRpb25zIHRoYXQgc2NvcGVcbiAqIHN0cmVhbSByZWFkcyBieSBydW5JZCBzdGlsbCB3b3JrIGNvcnJlY3RseS5cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVIZWFsdGhDaGVja1J1bklkKGNvcnJlbGF0aW9uSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgd3J1bl9oY18ke2NvcnJlbGF0aW9uSWR9YDtcbn1cblxuLyoqXG4gKiBIYW5kbGVzIGEgaGVhbHRoIGNoZWNrIG1lc3NhZ2UgYnkgd3JpdGluZyB0aGUgcmVzdWx0IHRvIHRoZSB3b3JsZCdzIHN0cmVhbS5cbiAqIFRoZSBjYWxsZXIgY2FuIGxpc3RlbiB0byB0aGlzIHN0cmVhbSB0byBnZXQgdGhlIGhlYWx0aCBjaGVjayByZXNwb25zZS5cbiAqXG4gKiBAcGFyYW0gaGVhbHRoQ2hlY2sgLSBUaGUgcGFyc2VkIGhlYWx0aCBjaGVjayBwYXlsb2FkXG4gKiBAcGFyYW0gZW5kcG9pbnQgLSBXaGljaCBlbmRwb2ludCBpcyByZXNwb25kaW5nICgnd29ya2Zsb3cnIG9yICdzdGVwJylcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZUhlYWx0aENoZWNrTWVzc2FnZShcbiAgaGVhbHRoQ2hlY2s6IEhlYWx0aENoZWNrUGF5bG9hZCxcbiAgZW5kcG9pbnQ6ICd3b3JrZmxvdycgfCAnc3RlcCcsXG4gIHdvcmxkU3BlY1ZlcnNpb24/OiBudW1iZXJcbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB3b3JsZCA9IGF3YWl0IGdldFdvcmxkKCk7XG4gIGNvbnN0IHN0cmVhbU5hbWUgPSBnZXRIZWFsdGhDaGVja1N0cmVhbU5hbWUoaGVhbHRoQ2hlY2suY29ycmVsYXRpb25JZCk7XG4gIGNvbnN0IHJlc3BvbnNlID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgIGhlYWx0aHk6IHRydWUsXG4gICAgZW5kcG9pbnQsXG4gICAgY29ycmVsYXRpb25JZDogaGVhbHRoQ2hlY2suY29ycmVsYXRpb25JZCxcbiAgICBzcGVjVmVyc2lvbjogd29ybGRTcGVjVmVyc2lvbiA/PyBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICB3b3JrZmxvd0NvcmVWZXJzaW9uLFxuICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgfSk7XG4gIC8vIFVzZSBhIGRldGVybWluaXN0aWMgZmFrZSBydW5JZCBkZXJpdmVkIGZyb20gdGhlIGNvcnJlbGF0aW9uSWQgc28gdGhhdFxuICAvLyB0aGUgcmVhZGVyIHNpZGUgcHJvZHVjZXMgdGhlIHNhbWUgdmFsdWUuXG4gIGNvbnN0IGZha2VSdW5JZCA9IGdlbmVyYXRlSGVhbHRoQ2hlY2tSdW5JZChoZWFsdGhDaGVjay5jb3JyZWxhdGlvbklkKTtcbiAgYXdhaXQgd29ybGQuc3RyZWFtcy53cml0ZShmYWtlUnVuSWQsIHN0cmVhbU5hbWUsIHJlc3BvbnNlKTtcbiAgYXdhaXQgd29ybGQuc3RyZWFtcy5jbG9zZShmYWtlUnVuSWQsIHN0cmVhbU5hbWUpO1xufVxuXG5leHBvcnQgdHlwZSBIZWFsdGhDaGVja0VuZHBvaW50ID0gJ3dvcmtmbG93JyB8ICdzdGVwJztcblxuZXhwb3J0IGludGVyZmFjZSBIZWFsdGhDaGVja09wdGlvbnMge1xuICAvKiogVGltZW91dCBpbiBtaWxsaXNlY29uZHMgdG8gd2FpdCBmb3IgaGVhbHRoIGNoZWNrIHJlc3BvbnNlLiBEZWZhdWx0OiAzMDAwMCAoMzBzKSAqL1xuICB0aW1lb3V0PzogbnVtYmVyO1xuICAvKiogRGVwbG95bWVudCBJRCB0byBzZW5kIHRoZSBoZWFsdGggY2hlY2sgdG8uIEZhbGxzIGJhY2sgdG8gcHJvY2Vzcy5lbnYuVkVSQ0VMX0RFUExPWU1FTlRfSUQuICovXG4gIGRlcGxveW1lbnRJZD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBQZXJmb3JtcyBhIGhlYWx0aCBjaGVjayBieSBzZW5kaW5nIGEgbWVzc2FnZSB0aHJvdWdoIHRoZSBxdWV1ZSBwaXBlbGluZVxuICogYW5kIHZlcmlmeWluZyBpdCBpcyBwcm9jZXNzZWQgYnkgdGhlIHNwZWNpZmllZCBlbmRwb2ludC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGJ5cGFzc2VzIERlcGxveW1lbnQgUHJvdGVjdGlvbiBvbiBWZXJjZWwgYmVjYXVzZSBpdCBnb2VzXG4gKiB0aHJvdWdoIHRoZSBxdWV1ZSBpbmZyYXN0cnVjdHVyZSByYXRoZXIgdGhhbiBkaXJlY3QgSFRUUC5cbiAqXG4gKiBAcGFyYW0gd29ybGQgLSBUaGUgV29ybGQgaW5zdGFuY2UgdG8gdXNlIGZvciB0aGUgaGVhbHRoIGNoZWNrXG4gKiBAcGFyYW0gZW5kcG9pbnQgLSBXaGljaCBlbmRwb2ludCB0byBoZWFsdGggY2hlY2s6ICd3b3JrZmxvdycgb3IgJ3N0ZXAnXG4gKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBoZWFsdGggY2hlY2tcbiAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIGhlYWx0aCBjaGVjayByZXN1bHRcbiAqL1xuLy8gUG9sbCBpbnRlcnZhbCBmb3IgaGVhbHRoIGNoZWNrIHJldHJpZXMgKG1zKVxuY29uc3QgSEVBTFRIX0NIRUNLX1BPTExfSU5URVJWQUwgPSAxMDA7XG4vLyBQZXItcmVhZCB0aW1lb3V0IHRvIHByZXZlbnQgYmxvY2tpbmcgZm9yZXZlciBvbiBsb2NhbCB3b3JsZCdzIEV2ZW50RW1pdHRlclxuLy8gKHdoaWNoIGRvZXNuJ3Qgd29yayBhY3Jvc3MgcHJvY2Vzc2VzKVxuY29uc3QgSEVBTFRIX0NIRUNLX1JFQURfVElNRU9VVCA9IDUwMDtcblxuLyoqXG4gKiBSZWFkIGNodW5rcyBmcm9tIGEgc3RyZWFtIHdpdGggYSB0aW1lb3V0IHBlciByZWFkIG9wZXJhdGlvbi5cbiAqIFJldHVybnMgeyBjaHVua3MsIHRpbWVkT3V0IH0gd2hlcmUgdGltZWRPdXQgaW5kaWNhdGVzIGlmIGEgcmVhZCB0aW1lZCBvdXQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlYWRTdHJlYW1XaXRoVGltZW91dChcbiAgcmVhZGVyOiBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXI8VWludDhBcnJheT4sXG4gIHJlYWRUaW1lb3V0OiBudW1iZXJcbik6IFByb21pc2U8eyBjaHVua3M6IFVpbnQ4QXJyYXlbXTsgdGltZWRPdXQ6IGJvb2xlYW4gfT4ge1xuICBjb25zdCBjaHVua3M6IFVpbnQ4QXJyYXlbXSA9IFtdO1xuICBsZXQgZG9uZSA9IGZhbHNlO1xuICBsZXQgdGltZWRPdXQgPSBmYWxzZTtcblxuICB3aGlsZSAoIWRvbmUgJiYgIXRpbWVkT3V0KSB7XG4gICAgY29uc3QgcmVhZFByb21pc2UgPSByZWFkZXIucmVhZCgpO1xuICAgIGNvbnN0IHRpbWVvdXRQcm9taXNlID0gbmV3IFByb21pc2U8eyBkb25lOiB0cnVlOyB2YWx1ZTogdW5kZWZpbmVkIH0+KFxuICAgICAgKHJlc29sdmUpID0+XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHRpbWVkT3V0ID0gdHJ1ZTtcbiAgICAgICAgICByZXNvbHZlKHsgZG9uZTogdHJ1ZSwgdmFsdWU6IHVuZGVmaW5lZCB9KTtcbiAgICAgICAgfSwgcmVhZFRpbWVvdXQpXG4gICAgKTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IFByb21pc2UucmFjZShbcmVhZFByb21pc2UsIHRpbWVvdXRQcm9taXNlXSk7XG4gICAgZG9uZSA9IHJlc3VsdC5kb25lO1xuICAgIGlmIChyZXN1bHQudmFsdWUpIGNodW5rcy5wdXNoKHJlc3VsdC52YWx1ZSk7XG4gIH1cblxuICByZXR1cm4geyBjaHVua3MsIHRpbWVkT3V0IH07XG59XG5cbi8qKlxuICogUGFyc2UgYW5kIHZhbGlkYXRlIGEgaGVhbHRoIGNoZWNrIHJlc3BvbnNlIGZyb20gc3RyZWFtIGNodW5rcy5cbiAqIFJldHVybnMgdGhlIHBhcnNlZCByZXNwb25zZSBvciBudWxsIGlmIGludmFsaWQuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlSGVhbHRoQ2hlY2tSZXNwb25zZShcbiAgY2h1bmtzOiBVaW50OEFycmF5W11cbik6IHsgaGVhbHRoeTogYm9vbGVhbiB9IHwgbnVsbCB7XG4gIGlmIChjaHVua3MubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcblxuICBjb25zdCB0b3RhbExlbmd0aCA9IGNodW5rcy5yZWR1Y2UoKHN1bSwgY2h1bmspID0+IHN1bSArIGNodW5rLmxlbmd0aCwgMCk7XG4gIGNvbnN0IGNvbWJpbmVkID0gbmV3IFVpbnQ4QXJyYXkodG90YWxMZW5ndGgpO1xuICBsZXQgb2Zmc2V0ID0gMDtcbiAgZm9yIChjb25zdCBjaHVuayBvZiBjaHVua3MpIHtcbiAgICBjb21iaW5lZC5zZXQoY2h1bmssIG9mZnNldCk7XG4gICAgb2Zmc2V0ICs9IGNodW5rLmxlbmd0aDtcbiAgfVxuICBjb25zdCByZXNwb25zZVRleHQgPSBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoY29tYmluZWQpO1xuXG4gIGxldCByZXNwb25zZTogdW5rbm93bjtcbiAgdHJ5IHtcbiAgICByZXNwb25zZSA9IEpTT04ucGFyc2UocmVzcG9uc2VUZXh0KTtcbiAgfSBjYXRjaCB7XG4gICAgLy8gT2xkIGRlcGxveW1lbnRzIChzcGVjVmVyc2lvbiA8IDMpIHJldHVybiBwbGFpbiB0ZXh0IGxpa2VcbiAgICAvLyAnV29ya2Zsb3cgU0RLIFwiLi4uXCIgZW5kcG9pbnQgaXMgaGVhbHRoeScuIFRyZWF0IGFueSBub24tZW1wdHlcbiAgICAvLyB0ZXh0IHJlc3BvbnNlIGFzIGEgaGVhbHRoeSBkZXBsb3ltZW50IHdpdGggdW5rbm93biBzcGVjVmVyc2lvbi5cbiAgICBpZiAocmVzcG9uc2VUZXh0Lmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiB7IGhlYWx0aHk6IHRydWUgfTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoXG4gICAgdHlwZW9mIHJlc3BvbnNlICE9PSAnb2JqZWN0JyB8fFxuICAgIHJlc3BvbnNlID09PSBudWxsIHx8XG4gICAgISgnaGVhbHRoeScgaW4gcmVzcG9uc2UpIHx8XG4gICAgdHlwZW9mIChyZXNwb25zZSBhcyB7IGhlYWx0aHk6IHVua25vd24gfSkuaGVhbHRoeSAhPT0gJ2Jvb2xlYW4nXG4gICkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgciA9IHJlc3BvbnNlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBjb25zdCBwYXJzZWQ6IHsgaGVhbHRoeTogYm9vbGVhbjsgc3BlY1ZlcnNpb24/OiBudW1iZXIgfSA9IHtcbiAgICBoZWFsdGh5OiByLmhlYWx0aHkgYXMgYm9vbGVhbixcbiAgfTtcbiAgaWYgKHR5cGVvZiByLnNwZWNWZXJzaW9uID09PSAnbnVtYmVyJykge1xuICAgIHBhcnNlZC5zcGVjVmVyc2lvbiA9IHIuc3BlY1ZlcnNpb247XG4gIH1cbiAgcmV0dXJuIHBhcnNlZDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhlYWx0aENoZWNrKFxuICB3b3JsZDogV29ybGQsXG4gIGVuZHBvaW50OiBIZWFsdGhDaGVja0VuZHBvaW50LFxuICBvcHRpb25zPzogSGVhbHRoQ2hlY2tPcHRpb25zXG4pOiBQcm9taXNlPEhlYWx0aENoZWNrUmVzdWx0PiB7XG4gIGNvbnN0IHRpbWVvdXQgPSBvcHRpb25zPy50aW1lb3V0ID8/IERFRkFVTFRfSEVBTFRIX0NIRUNLX1RJTUVPVVQ7XG4gIGNvbnN0IGNvcnJlbGF0aW9uSWQgPSBnZW5lcmF0ZUlkKCk7XG4gIGNvbnN0IHN0cmVhbU5hbWUgPSBnZXRIZWFsdGhDaGVja1N0cmVhbU5hbWUoY29ycmVsYXRpb25JZCk7XG5cbiAgY29uc3QgcXVldWVOYW1lOiBWYWxpZFF1ZXVlTmFtZSA9XG4gICAgZW5kcG9pbnQgPT09ICd3b3JrZmxvdydcbiAgICAgID8gJ19fd2tmX3dvcmtmbG93X2hlYWx0aF9jaGVjaydcbiAgICAgIDogJ19fd2tmX3N0ZXBfaGVhbHRoX2NoZWNrJztcblxuICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgd29ybGQucXVldWUoXG4gICAgICBxdWV1ZU5hbWUsXG4gICAgICB7IF9faGVhbHRoQ2hlY2s6IHRydWUsIGNvcnJlbGF0aW9uSWQgfSxcbiAgICAgIHtcbiAgICAgICAgLy8gVXNlIEpTT04gdHJhbnNwb3J0IHNvIHRoZSBoZWFsdGggY2hlY2sgd29ya3MgYWdhaW5zdCBib3RoXG4gICAgICAgIC8vIG9sZCAoSlNPTi1vbmx5KSBhbmQgbmV3IChkdWFsKSBkZXBsb3ltZW50cy5cbiAgICAgICAgc3BlY1ZlcnNpb246IFNQRUNfVkVSU0lPTl9MRUdBQ1ksXG4gICAgICAgIGRlcGxveW1lbnRJZDogb3B0aW9ucz8uZGVwbG95bWVudElkLFxuICAgICAgfVxuICAgICk7XG5cbiAgICB3aGlsZSAoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSA8IHRpbWVvdXQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHN0cmVhbSA9IGF3YWl0IHdvcmxkLnN0cmVhbXMuZ2V0KFxuICAgICAgICAgIGdlbmVyYXRlSGVhbHRoQ2hlY2tSdW5JZChjb3JyZWxhdGlvbklkKSxcbiAgICAgICAgICBzdHJlYW1OYW1lXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5nZXRSZWFkZXIoKTtcbiAgICAgICAgY29uc3QgeyBjaHVua3MsIHRpbWVkT3V0IH0gPSBhd2FpdCByZWFkU3RyZWFtV2l0aFRpbWVvdXQoXG4gICAgICAgICAgcmVhZGVyLFxuICAgICAgICAgIEhFQUxUSF9DSEVDS19SRUFEX1RJTUVPVVRcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAodGltZWRPdXQpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmVhZGVyLmNhbmNlbCgpO1xuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLy8gSWdub3JlIGNhbmNlbCBlcnJvcnNcbiAgICAgICAgICB9XG4gICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+XG4gICAgICAgICAgICBzZXRUaW1lb3V0KHJlc29sdmUsIEhFQUxUSF9DSEVDS19QT0xMX0lOVEVSVkFMKVxuICAgICAgICAgICk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IHBhcnNlSGVhbHRoQ2hlY2tSZXNwb25zZShjaHVua3MpO1xuICAgICAgICBpZiAocmVzcG9uc2UpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4ucmVzcG9uc2UsXG4gICAgICAgICAgICBsYXRlbmN5TXM6IERhdGUubm93KCkgLSBzdGFydFRpbWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PlxuICAgICAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgSEVBTFRIX0NIRUNLX1BPTExfSU5URVJWQUwpXG4gICAgICAgICk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+XG4gICAgICAgICAgc2V0VGltZW91dChyZXNvbHZlLCBIRUFMVEhfQ0hFQ0tfUE9MTF9JTlRFUlZBTClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGhlYWx0aHk6IGZhbHNlLFxuICAgICAgZXJyb3I6IGBIZWFsdGggY2hlY2sgdGltZWQgb3V0IGFmdGVyICR7dGltZW91dH1tc2AsXG4gICAgfTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaGVhbHRoeTogZmFsc2UsXG4gICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBMb2FkcyBhbGwgd29ya2Zsb3cgcnVuIGV2ZW50cyBieSBpdGVyYXRpbmcgdGhyb3VnaCBhbGwgcGFnZXMgb2YgcGFnaW5hdGVkIHJlc3VsdHMuXG4gKiBUaGlzIGVuc3VyZXMgdGhhdCAqYWxsKiBldmVudHMgYXJlIGxvYWRlZCBpbnRvIG1lbW9yeSBiZWZvcmUgcnVubmluZyB0aGUgd29ya2Zsb3cuXG4gKiBFdmVudHMgbXVzdCBiZSBpbiBjaHJvbm9sb2dpY2FsIG9yZGVyIChhc2NlbmRpbmcpIGZvciBwcm9wZXIgd29ya2Zsb3cgcmVwbGF5LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0QWxsV29ya2Zsb3dSdW5FdmVudHMocnVuSWQ6IHN0cmluZyk6IFByb21pc2U8RXZlbnRbXT4ge1xuICByZXR1cm4gdHJhY2UoJ3dvcmtmbG93LmxvYWRFdmVudHMnLCBhc3luYyAoc3BhbikgPT4ge1xuICAgIHNwYW4/LnNldEF0dHJpYnV0ZXMoe1xuICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93UnVuSWQocnVuSWQpLFxuICAgIH0pO1xuXG4gICAgY29uc3QgYWxsRXZlbnRzOiBFdmVudFtdID0gW107XG4gICAgbGV0IGN1cnNvcjogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gICAgbGV0IGhhc01vcmUgPSB0cnVlO1xuICAgIGxldCBwYWdlc0xvYWRlZCA9IDA7XG5cbiAgICBjb25zdCB3b3JsZCA9IGF3YWl0IGdldFdvcmxkKCk7XG4gICAgY29uc3QgbG9hZFN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICB3aGlsZSAoaGFzTW9yZSkge1xuICAgICAgLy8gVE9ETzogd2UncmUgY3VycmVudGx5IGxvYWRpbmcgYWxsIHRoZSBkYXRhIHdpdGggcmVzb2x2ZVJlZiBiZWhhdmlvdXIuIFdlIG5lZWQgdG8gdXBkYXRlIHRoaXNcbiAgICAgIC8vIHRvIGxhenlsb2FkIHRoZSBkYXRhIGZyb20gdGhlIHdvcmxkIGluc3RlYWQgc28gdGhhdCB3ZSBjYW4gb3B0aW1pemUgYW5kIG1ha2UgdGhlIGV2ZW50IGxvZyBsb2FkaW5nXG4gICAgICAvLyBtdWNoIGZhc3RlciBhbmQgbWVtb3J5IGVmZmljaWVudFxuICAgICAgY29uc3QgcGFnZVN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd29ybGQuZXZlbnRzLmxpc3Qoe1xuICAgICAgICBydW5JZCxcbiAgICAgICAgcGFnaW5hdGlvbjoge1xuICAgICAgICAgIHNvcnRPcmRlcjogJ2FzYycsIC8vIFJlcXVpcmVkOiBldmVudHMgbXVzdCBiZSBpbiBjaHJvbm9sb2dpY2FsIG9yZGVyIGZvciByZXBsYXlcbiAgICAgICAgICBjdXJzb3I6IGN1cnNvciA/PyB1bmRlZmluZWQsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgYWxsRXZlbnRzLnB1c2goLi4ucmVzcG9uc2UuZGF0YSk7XG4gICAgICBoYXNNb3JlID0gcmVzcG9uc2UuaGFzTW9yZTtcbiAgICAgIGN1cnNvciA9IHJlc3BvbnNlLmN1cnNvcjtcbiAgICAgIHBhZ2VzTG9hZGVkKys7XG5cbiAgICAgIHJ1bnRpbWVMb2dnZXIuZGVidWcoJ0xvYWRlZCBldmVudCBwYWdlJywge1xuICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgcGFnZTogcGFnZXNMb2FkZWQsXG4gICAgICAgIHBhZ2VFdmVudHM6IHJlc3BvbnNlLmRhdGEubGVuZ3RoLFxuICAgICAgICB0b3RhbEV2ZW50czogYWxsRXZlbnRzLmxlbmd0aCxcbiAgICAgICAgaGFzTW9yZSxcbiAgICAgICAgcGFnZU1zOiBEYXRlLm5vdygpIC0gcGFnZVN0YXJ0LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcnVudGltZUxvZ2dlci5kZWJ1ZygnRXZlbnQgbG9hZGluZyBjb21wbGV0ZScsIHtcbiAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgdG90YWxFdmVudHM6IGFsbEV2ZW50cy5sZW5ndGgsXG4gICAgICBwYWdlc0xvYWRlZCxcbiAgICAgIHRvdGFsTXM6IERhdGUubm93KCkgLSBsb2FkU3RhcnQsXG4gICAgfSk7XG5cbiAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgIC4uLkF0dHJpYnV0ZS5Xb3JrZmxvd0V2ZW50c0NvdW50KGFsbEV2ZW50cy5sZW5ndGgpLFxuICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93RXZlbnRzUGFnZXNMb2FkZWQocGFnZXNMb2FkZWQpLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGFsbEV2ZW50cztcbiAgfSk7XG59XG5cbi8qKlxuICogQ09SUyBoZWFkZXJzIGZvciBoZWFsdGggY2hlY2sgcmVzcG9uc2VzLlxuICogQWxsb3dzIHRoZSBvYnNlcnZhYmlsaXR5IFVJIHRvIGNoZWNrIGVuZHBvaW50IGhlYWx0aCBmcm9tIGEgZGlmZmVyZW50IG9yaWdpbi5cbiAqL1xuY29uc3QgSEVBTFRIX0NIRUNLX0NPUlNfSEVBREVSUyA9IHtcbiAgJ0FjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbic6ICcqJyxcbiAgJ0FjY2Vzcy1Db250cm9sLUFsbG93LU1ldGhvZHMnOiAnUE9TVCwgT1BUSU9OUywgR0VULCBIRUFEJyxcbiAgJ0FjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnMnOiAnQ29udGVudC1UeXBlJyxcbn07XG5cbi8qKlxuICogV3JhcHMgYSByZXF1ZXN0L3Jlc3BvbnNlIGhhbmRsZXIgYW5kIGFkZHMgYSBoZWFsdGggY2hlY2sgXCJtb2RlXCJcbiAqIGJhc2VkIG9uIHRoZSBwcmVzZW5jZSBvZiBhIGBfX2hlYWx0aGAgcXVlcnkgcGFyYW1ldGVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2l0aEhlYWx0aENoZWNrKFxuICBoYW5kbGVyOiAocmVxOiBSZXF1ZXN0KSA9PiBQcm9taXNlPFJlc3BvbnNlPixcbiAgd29ybGRTcGVjVmVyc2lvbj86IG51bWJlclxuKTogKHJlcTogUmVxdWVzdCkgPT4gUHJvbWlzZTxSZXNwb25zZT4ge1xuICByZXR1cm4gYXN5bmMgKHJlcTogUmVxdWVzdCkgPT4ge1xuICAgIGNvbnN0IHVybCA9IG5ldyBVUkwocmVxLnVybCk7XG4gICAgY29uc3QgaXNIZWFsdGhDaGVjayA9IHVybC5zZWFyY2hQYXJhbXMuaGFzKCdfX2hlYWx0aCcpO1xuICAgIGlmIChpc0hlYWx0aENoZWNrKSB7XG4gICAgICAvLyBIYW5kbGUgQ09SUyBwcmVmbGlnaHQgZm9yIGhlYWx0aCBjaGVja1xuICAgICAgaWYgKHJlcS5tZXRob2QgPT09ICdPUFRJT05TJykge1xuICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKG51bGwsIHtcbiAgICAgICAgICBzdGF0dXM6IDIwNCxcbiAgICAgICAgICBoZWFkZXJzOiBIRUFMVEhfQ0hFQ0tfQ09SU19IRUFERVJTLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UoXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBoZWFsdGh5OiB0cnVlLFxuICAgICAgICAgIGVuZHBvaW50OiB1cmwucGF0aG5hbWUsXG4gICAgICAgICAgc3BlY1ZlcnNpb246IHdvcmxkU3BlY1ZlcnNpb24gPz8gU1BFQ19WRVJTSU9OX0NVUlJFTlQsXG4gICAgICAgICAgd29ya2Zsb3dDb3JlVmVyc2lvbixcbiAgICAgICAgfSksXG4gICAgICAgIHtcbiAgICAgICAgICBzdGF0dXM6IDIwMCxcbiAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgLi4uSEVBTFRIX0NIRUNLX0NPUlNfSEVBREVSUyxcbiAgICAgICAgICB9LFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gYXdhaXQgaGFuZGxlcihyZXEpO1xuICB9O1xufVxuXG4vKipcbiAqIFF1ZXVlcyBhIG1lc3NhZ2UgdG8gdGhlIHNwZWNpZmllZCBxdWV1ZSB3aXRoIHRyYWNpbmcuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBxdWV1ZU1lc3NhZ2UoXG4gIHdvcmxkOiBXb3JsZCxcbiAgLi4uYXJnczogUGFyYW1ldGVyczx0eXBlb2Ygd29ybGQucXVldWU+XG4pIHtcbiAgY29uc3QgcXVldWVOYW1lID0gYXJnc1swXTtcbiAgYXdhaXQgdHJhY2UoXG4gICAgJ3F1ZXVlLnB1Ymxpc2gnLFxuICAgIHtcbiAgICAgIC8vIFN0YW5kYXJkIE9URUwgbWVzc2FnaW5nIGNvbnZlbnRpb25zXG4gICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgIC4uLkF0dHJpYnV0ZS5NZXNzYWdpbmdTeXN0ZW0oJ3ZlcmNlbC1xdWV1ZScpLFxuICAgICAgICAuLi5BdHRyaWJ1dGUuTWVzc2FnaW5nRGVzdGluYXRpb25OYW1lKHF1ZXVlTmFtZSksXG4gICAgICAgIC4uLkF0dHJpYnV0ZS5NZXNzYWdpbmdPcGVyYXRpb25UeXBlKCdwdWJsaXNoJyksXG4gICAgICAgIC8vIFBlZXIgc2VydmljZSBmb3IgRGF0YWRvZyBzZXJ2aWNlIG1hcHNcbiAgICAgICAgLi4uQXR0cmlidXRlLlBlZXJTZXJ2aWNlKCd2ZXJjZWwtcXVldWUnKSxcbiAgICAgICAgLi4uQXR0cmlidXRlLlJwY1N5c3RlbSgndmVyY2VsLXF1ZXVlJyksXG4gICAgICAgIC4uLkF0dHJpYnV0ZS5ScGNTZXJ2aWNlKCd2cXMnKSxcbiAgICAgICAgLi4uQXR0cmlidXRlLlJwY01ldGhvZCgncHVibGlzaCcpLFxuICAgICAgfSxcbiAgICAgIGtpbmQ6IGF3YWl0IGdldFNwYW5LaW5kKCdQUk9EVUNFUicpLFxuICAgIH0sXG4gICAgYXN5bmMgKHNwYW4pID0+IHtcbiAgICAgIGNvbnN0IHsgbWVzc2FnZUlkIH0gPSBhd2FpdCB3b3JsZC5xdWV1ZSguLi5hcmdzKTtcbiAgICAgIGlmIChtZXNzYWdlSWQpIHtcbiAgICAgICAgc3Bhbj8uc2V0QXR0cmlidXRlcyhBdHRyaWJ1dGUuTWVzc2FnaW5nTWVzc2FnZUlkKG1lc3NhZ2VJZCkpO1xuICAgICAgfVxuICAgIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBxdWV1ZSBvdmVyaGVhZCB0aW1lIGluIG1pbGxpc2Vjb25kcyBmb3IgYSBnaXZlbiBtZXNzYWdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UXVldWVPdmVyaGVhZChtZXNzYWdlOiB7IHJlcXVlc3RlZEF0PzogRGF0ZSB9KSB7XG4gIGlmICghbWVzc2FnZS5yZXF1ZXN0ZWRBdCkgcmV0dXJuO1xuICB0cnkge1xuICAgIHJldHVybiBBdHRyaWJ1dGUuUXVldWVPdmVyaGVhZE1zKFxuICAgICAgRGF0ZS5ub3coKSAtIG1lc3NhZ2UucmVxdWVzdGVkQXQuZ2V0VGltZSgpXG4gICAgKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuO1xuICB9XG59XG4iXX0=
445
+ /**
446
+ * Returns a memoized accessor for the per-run AES-256 encryption key.
447
+ *
448
+ * The first call resolves the key via `world.getEncryptionKeyForRun` (which
449
+ * may do HKDF derivation locally on Vercel, or a network fetch from
450
+ * external contexts) and imports it as a `CryptoKey`; subsequent calls
451
+ * await the same cached promise. If the world doesn't support encryption
452
+ * or the run has no key configured, the cached value is `undefined`.
453
+ *
454
+ * Used by step / workflow handlers to defer the (potentially expensive)
455
+ * key fetch until the first code path that actually needs it — typically
456
+ * input hydration on the success path, or error dehydration on a failure
457
+ * path. Both paths can race-call the accessor without triggering duplicate
458
+ * fetches.
459
+ *
460
+ * Errors thrown by `getEncryptionKeyForRun` propagate to every caller
461
+ * (the cached promise rejects). This is intentional: when encryption is
462
+ * configured, we never want to silently fall back to plaintext
463
+ * serialization. A propagated error in an event-emission path leaves the
464
+ * outer try/catch to log and surface the issue; the queue's redelivery
465
+ * semantics will retry the key fetch on the next attempt.
466
+ */
467
+ export function memoizeEncryptionKey(world, runOrId) {
468
+ let cached;
469
+ return () => {
470
+ if (!cached) {
471
+ cached = (async () => {
472
+ // The `getEncryptionKeyForRun` overload set takes either a
473
+ // `WorkflowRun` or a `runId: string` (with optional context). Branch
474
+ // here so TypeScript picks the right overload for each shape.
475
+ const rawKey = typeof runOrId === 'string'
476
+ ? await world.getEncryptionKeyForRun?.(runOrId)
477
+ : await world.getEncryptionKeyForRun?.(runOrId);
478
+ return rawKey ? await importKey(rawKey) : undefined;
479
+ })();
480
+ }
481
+ return cached;
482
+ };
483
+ }
484
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW50aW1lL2hlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGVBQWUsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBUXZFLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsd0JBQXdCLEVBQ3hCLHFCQUFxQixFQUNyQixvQkFBb0IsRUFDcEIsbUJBQW1CLEdBQ3BCLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXhDLE9BQU8sRUFBa0IsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUM3QyxPQUFPLEtBQUssU0FBUyxNQUFNLHNDQUFzQyxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDckQsT0FBTyxFQUFFLE9BQU8sSUFBSSxtQkFBbUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFbkQsd0RBQXdEO0FBQ3hELE1BQU0sNEJBQTRCLEdBQUcsTUFBTSxDQUFDO0FBRTVDOzs7O0dBSUc7QUFDSCxNQUFNLDBCQUEwQixHQUFHLHNCQUFzQixDQUFDO0FBRTFEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsb0JBQW9CLENBQ2xDLFlBQW9CLEVBQ3BCLFNBQWtCO0lBRWxCLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztRQUNuRCxNQUFNLElBQUksS0FBSyxDQUNiLDBCQUEwQixZQUFZLHdHQUF3RyxDQUMvSSxDQUFDO0lBQ0osQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLG1CQUFtQixDQUNoQyxVQUFVLEVB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QStCO0lBQzlELElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVztRQUFFLE9BQU87SUFDakMsSUFBSSxDQUFDO1FBQ0gsT0FBTyxTQUFTLENBQUMsZUFBZSxDQUM5QixJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FDM0MsQ0FBQztJQUNKLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPO0lBQ1QsQ0FBQztBQUNILENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUNsQyxLQUFZLEVBQ1osT0FBNkI7SUFFN0IsSUFBSSxNQUFrRCxDQUFDO0lBQ3ZELE9BQU8sR0FBRyxFQUFFO1FBQ1YsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ1osTUFBTSxHQUFHLENBQUMsS0FBSyxJQUFJLEVBQUU7Z0JBQ25CLDJEQUEyRDtnQkFDM0QscUVBQXFFO2dCQUNyRSw4REFBOEQ7Z0JBQzlELE1BQU0sTUFBTSxHQUNWLE9BQU8sT0FBTyxLQUFLLFFBQVE7b0JBQ3pCLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxzQkFBc0IsRUFBRSxDQUFDLE9BQU8sQ0FBQztvQkFDL0MsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLHNCQUFzQixFQUFFLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ3BELE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ3RELENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDUCxDQUFDO1FBQ0QsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJVTl9FUlJPUl9DT0RFUywgV29ya2Zsb3dXb3JsZEVycm9yIH0gZnJvbSAnQHdvcmtmbG93L2Vycm9ycyc7XG5pbXBvcnQgdHlwZSB7XG4gIEV2ZW50LFxuICBIZWFsdGhDaGVja1BheWxvYWQsXG4gIFZhbGlkUXVldWVOYW1lLFxuICBXb3JrZmxvd1J1bixcbiAgV29ybGQsXG59IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQge1xuICBnZXRRdWV1ZVRvcGljUHJlZml4LFxuICBIZWFsdGhDaGVja1BheWxvYWRTY2hlbWEsXG4gIHJlc29sdmVRdWV1ZU5hbWVzcGFjZSxcbiAgU1BFQ19WRVJTSU9OX0NVUlJFTlQsXG4gIFNQRUNfVkVSU0lPTl9MRUdBQ1ksXG59IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgeyBtb25vdG9uaWNGYWN0b3J5IH0gZnJvbSAndWxpZCc7XG5cbmltcG9ydCB7IHR5cGUgQ3J5cHRvS2V5LCBpbXBvcnRLZXkgfSBmcm9tICcuLi9lbmNyeXB0aW9uLmpzJztcbmltcG9ydCB7IHJ1bnRpbWVMb2dnZXIgfSBmcm9tICcuLi9sb2dnZXIuanMnO1xuaW1wb3J0ICogYXMgQXR0cmlidXRlIGZyb20gJy4uL3RlbGVtZXRyeS9zZW1hbnRpYy1jb252ZW50aW9ucy5qcyc7XG5pbXBvcnQgeyBnZXRTcGFuS2luZCwgdHJhY2UgfSBmcm9tICcuLi90ZWxlbWV0cnkuanMnO1xuaW1wb3J0IHsgdmVyc2lvbiBhcyB3b3JrZmxvd0NvcmVWZXJzaW9uIH0gZnJvbSAnLi4vdmVyc2lvbi5qcyc7XG5pbXBvcnQgeyBnZXRXb3JsZExhenkgfSBmcm9tICcuL2dldC13b3JsZC1sYXp5LmpzJztcblxuLyoqIERlZmF1bHQgdGltZW91dCBmb3IgaGVhbHRoIGNoZWNrcyBpbiBtaWxsaXNlY29uZHMgKi9cbmNvbnN0IERFRkFVTFRfSEVBTFRIX0NIRUNLX1RJTUVPVVQgPSAzMF8wMDA7XG5cbi8qKlxuICogUGF0dGVybiBmb3Igc2FmZSB3b3JrZmxvdyBuYW1lcy4gT25seSBhbGxvd3MgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMsXG4gKiB1bmRlcnNjb3JlcywgaHlwaGVucywgZG90cywgZm9yd2FyZCBzbGFzaGVzIChmb3IgbmFtZXNwYWNlZCB3b3JrZmxvd3MpLFxuICogYW5kIGF0IHNpZ25zIChmb3Igc2NvcGVkIHBhY2thZ2VzKS5cbiAqL1xuY29uc3QgU0FGRV9XT1JLRkxPV19OQU1FX1BBVFRFUk4gPSAvXlthLXpBLVowLTlfXFwtLi9AXSskLztcblxuLyoqXG4gKiBWYWxpZGF0ZXMgYSB3b3JrZmxvdyBuYW1lIGFuZCByZXR1cm5zIHRoZSBjb3JyZXNwb25kaW5nIHF1ZXVlIG5hbWUuXG4gKiBFbnN1cmVzIHRoZSB3b3JrZmxvdyBuYW1lIG9ubHkgY29udGFpbnMgc2FmZSBjaGFyYWN0ZXJzIGJlZm9yZVxuICogaW50ZXJwb2xhdGluZyBpdCBpbnRvIHRoZSBxdWV1ZSBuYW1lIHN0cmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmtmbG93UXVldWVOYW1lKFxuICB3b3JrZmxvd05hbWU6IHN0cmluZyxcbiAgbmFtZXNwYWNlPzogc3RyaW5nXG4pOiBWYWxpZFF1ZXVlTmFtZSB7XG4gIGlmICghU0FGRV9XT1JLRkxPV19OQU1FX1BBVFRFUk4udGVzdCh3b3JrZmxvd05hbWUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYEludmFsaWQgd29ya2Zsb3cgbmFtZSBcIiR7d29ya2Zsb3dOYW1lfVwiOiBtdXN0IG9ubHkgY29udGFpbiBhbHBoYW51bWVyaWMgY2hhcmFjdGVycywgdW5kZXJzY29yZXMsIGh5cGhlbnMsIGRvdHMsIGZvcndhcmQgc2xhc2hlcywgb3IgYXQgc2lnbnNgXG4gICAgKTtcbiAgfVxuICBjb25zdCBwcmVmaXggPSBnZXRRdWV1ZVRvcGljUHJlZml4KFxuICAgICd3b3JrZmxvdycsXG4gICAgcmVzb2x2ZVF1ZXVlTmFtZXNwYWNlKG5hbWVzcGFjZSlcbiAgKTtcbiAgcmV0dXJuIGAke3ByZWZpeH0ke3dvcmtmbG93TmFtZX1gIGFzIFZhbGlkUXVldWVOYW1lO1xufVxuXG5jb25zdCBnZW5lcmF0ZUlkID0gbW9ub3RvbmljRmFjdG9yeSgpO1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHN0cmVhbSBuYW1lIGZvciBhIGhlYWx0aCBjaGVjayB3aXRoIHRoZSBnaXZlbiBjb3JyZWxhdGlvbiBJRC5cbiAqL1xuZnVuY3Rpb24gZ2V0SGVhbHRoQ2hlY2tTdHJlYW1OYW1lKGNvcnJlbGF0aW9uSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgX19oZWFsdGhfY2hlY2tfXyR7Y29ycmVsYXRpb25JZH1gO1xufVxuXG4vKipcbiAqIFJlc3VsdCBvZiBhIGhlYWx0aCBjaGVjayBvcGVyYXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSGVhbHRoQ2hlY2tSZXN1bHQge1xuICBoZWFsdGh5OiBib29sZWFuO1xuICAvKiogRXJyb3IgbWVzc2FnZSBpZiBoZWFsdGggY2hlY2sgZmFpbGVkICovXG4gIGVycm9yPzogc3RyaW5nO1xuICAvKiogTGF0ZW5jeSBpZiB0aGUgaGVhbHRoIGNoZWNrIHdhcyBzdWNjZXNzZnVsICovXG4gIGxhdGVuY3lNcz86IG51bWJlcjtcbiAgLyoqIFNwZWMgdmVyc2lvbiBvZiB0aGUgcmVzcG9uZGluZyBkZXBsb3ltZW50ICovXG4gIHNwZWNWZXJzaW9uPzogbnVtYmVyO1xuICAvKipcbiAgICogYEB3b3JrZmxvdy9jb3JlYCB2ZXJzaW9uIG9mIHRoZSByZXNwb25kaW5nIGRlcGxveW1lbnQsIHVzZWQgZm9yXG4gICAqIGNhcGFiaWxpdHkgZGV0ZWN0aW9uIChzZWUgYGdldFJ1bkNhcGFiaWxpdGllc2ApLiBPbWl0dGVkIHdoZW4gdGhlXG4gICAqIHJlc3BvbmRpbmcgZGVwbG95bWVudCBkaWQgbm90IHByb3ZpZGUgdGhlIGZpZWxkIGFzIGEgc3RyaW5nIOKAlFxuICAgKiBmb3IgZXhhbXBsZSwgYW4gb2xkZXIgYEB3b3JrZmxvdy9jb3JlYCB0aGF0IHByZWRhdGVzIHRoaXMgZmllbGQsXG4gICAqIG9yIGEgbm9uLUpTT04gcGxhaW4tdGV4dCBoZWFsdGggcmVzcG9uc2UuXG4gICAqL1xuICB3b3JrZmxvd0NvcmVWZXJzaW9uPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gbWVzc2FnZSBpcyBhIGhlYWx0aCBjaGVjayBwYXlsb2FkLlxuICogSWYgc28sIHJldHVybnMgdGhlIHBhcnNlZCBwYXlsb2FkLiBPdGhlcndpc2UgcmV0dXJucyB1bmRlZmluZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUhlYWx0aENoZWNrUGF5bG9hZChcbiAgbWVzc2FnZTogdW5rbm93blxuKTogSGVhbHRoQ2hlY2tQYXlsb2FkIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcmVzdWx0ID0gSGVhbHRoQ2hlY2tQYXlsb2FkU2NoZW1hLnNhZmVQYXJzZShtZXNzYWdlKTtcbiAgaWYgKHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgcmV0dXJuIHJlc3VsdC5kYXRhO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgZGV0ZXJtaW5pc3RpYyBmYWtlIHJ1bklkIGZvciBoZWFsdGggY2hlY2sgc3RyZWFtcy5cbiAqIEJvdGggdGhlIHdyaXRlciAoaGFuZGxlSGVhbHRoQ2hlY2tNZXNzYWdlKSBhbmQgcmVhZGVyIChoZWFsdGhDaGVjaykgZGVyaXZlXG4gKiB0aGUgc2FtZSBydW5JZCBmcm9tIHRoZSBjb3JyZWxhdGlvbklkIHNvIHRoYXQgaW1wbGVtZW50YXRpb25zIHRoYXQgc2NvcGVcbiAqIHN0cmVhbSByZWFkcyBieSBydW5JZCBzdGlsbCB3b3JrIGNvcnJlY3RseS5cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVIZWFsdGhDaGVja1J1bklkKGNvcnJlbGF0aW9uSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgd3J1bl9oY18ke2NvcnJlbGF0aW9uSWR9YDtcbn1cblxuLyoqXG4gKiBIYW5kbGVzIGEgaGVhbHRoIGNoZWNrIG1lc3NhZ2UgYnkgd3JpdGluZyB0aGUgcmVzdWx0IHRvIHRoZSB3b3JsZCdzIHN0cmVhbS5cbiAqIFRoZSBjYWxsZXIgY2FuIGxpc3RlbiB0byB0aGlzIHN0cmVhbSB0byBnZXQgdGhlIGhlYWx0aCBjaGVjayByZXNwb25zZS5cbiAqXG4gKiBAcGFyYW0gaGVhbHRoQ2hlY2sgLSBUaGUgcGFyc2VkIGhlYWx0aCBjaGVjayBwYXlsb2FkXG4gKiBAcGFyYW0gZW5kcG9pbnQgLSBXaGljaCBlbmRwb2ludCBpcyByZXNwb25kaW5nICgnd29ya2Zsb3cnIG9yICdzdGVwJylcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZUhlYWx0aENoZWNrTWVzc2FnZShcbiAgaGVhbHRoQ2hlY2s6IEhlYWx0aENoZWNrUGF5bG9hZCxcbiAgZW5kcG9pbnQ6ICd3b3JrZmxvdycgfCAnc3RlcCcsXG4gIHdvcmxkU3BlY1ZlcnNpb24/OiBudW1iZXJcbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB3b3JsZCA9IGF3YWl0IGdldFdvcmxkTGF6eSgpO1xuICBjb25zdCBzdHJlYW1OYW1lID0gZ2V0SGVhbHRoQ2hlY2tTdHJlYW1OYW1lKGhlYWx0aENoZWNrLmNvcnJlbGF0aW9uSWQpO1xuICBjb25zdCByZXNwb25zZSA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICBoZWFsdGh5OiB0cnVlLFxuICAgIGVuZHBvaW50LFxuICAgIGNvcnJlbGF0aW9uSWQ6IGhlYWx0aENoZWNrLmNvcnJlbGF0aW9uSWQsXG4gICAgc3BlY1ZlcnNpb246IHdvcmxkU3BlY1ZlcnNpb24gPz8gU1BFQ19WRVJTSU9OX0NVUlJFTlQsXG4gICAgd29ya2Zsb3dDb3JlVmVyc2lvbixcbiAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gIH0pO1xuICAvLyBVc2UgYSBkZXRlcm1pbmlzdGljIGZha2UgcnVuSWQgZGVyaXZlZCBmcm9tIHRoZSBjb3JyZWxhdGlvbklkIHNvIHRoYXRcbiAgLy8gdGhlIHJlYWRlciBzaWRlIHByb2R1Y2VzIHRoZSBzYW1lIHZhbHVlLlxuICBjb25zdCBmYWtlUnVuSWQgPSBnZW5lcmF0ZUhlYWx0aENoZWNrUnVuSWQoaGVhbHRoQ2hlY2suY29ycmVsYXRpb25JZCk7XG4gIGF3YWl0IHdvcmxkLnN0cmVhbXMud3JpdGUoZmFrZVJ1bklkLCBzdHJlYW1OYW1lLCByZXNwb25zZSk7XG4gIGF3YWl0IHdvcmxkLnN0cmVhbXMuY2xvc2UoZmFrZVJ1bklkLCBzdHJlYW1OYW1lKTtcbn1cblxuZXhwb3J0IHR5cGUgSGVhbHRoQ2hlY2tFbmRwb2ludCA9ICd3b3JrZmxvdycgfCAnc3RlcCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSGVhbHRoQ2hlY2tPcHRpb25zIHtcbiAgLyoqIFRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIHRvIHdhaXQgZm9yIGhlYWx0aCBjaGVjayByZXNwb25zZS4gRGVmYXVsdDogMzAwMDAgKDMwcykgKi9cbiAgdGltZW91dD86IG51bWJlcjtcbiAgLyoqIERlcGxveW1lbnQgSUQgdG8gc2VuZCB0aGUgaGVhbHRoIGNoZWNrIHRvLiBGYWxscyBiYWNrIHRvIHByb2Nlc3MuZW52LlZFUkNFTF9ERVBMT1lNRU5UX0lELiAqL1xuICBkZXBsb3ltZW50SWQ/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBRdWV1ZSBuYW1lc3BhY2Ugb2YgdGhlIHRhcmdldCBkZXBsb3ltZW50IChlLmcuIGAnZXZlJ2AgZm9yIHRvcGljcyBsaWtlXG4gICAqIGBfX2V2ZV93a2Zfd29ya2Zsb3dfKmApLiBGYWxscyBiYWNrIHRvIGBXT1JLRkxPV19RVUVVRV9OQU1FU1BBQ0VgIGluIHRoZVxuICAgKiBjYWxsaW5nIHByb2Nlc3MuIENyb3NzLWNvbnRleHQgY2FsbGVycyAoZS5nLiB0aGUgb2JzZXJ2YWJpbGl0eVxuICAgKiBkYXNoYm9hcmQpIG11c3QgcGFzcyB0aGUgdGFyZ2V0IGRlcGxveW1lbnQncyBuYW1lc3BhY2UgZXhwbGljaXRseSDigJRcbiAgICogdGhlIGVudiBmYWxsYmFjayByZXNvbHZlcyBpbiB0aGUgY2FsbGVyJ3MgcHJvY2VzcywgYW5kIGEgbWVzc2FnZVxuICAgKiBwdWJsaXNoZWQgdG8gYSBtaXNtYXRjaGVkIHRvcGljIGhhcyBubyBjb25zdW1lciwgc28gdGhlIGNoZWNrIHdvdWxkXG4gICAqIGFsd2F5cyB0aW1lIG91dC5cbiAgICovXG4gIG5hbWVzcGFjZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBQZXJmb3JtcyBhIGhlYWx0aCBjaGVjayBieSBzZW5kaW5nIGEgbWVzc2FnZSB0aHJvdWdoIHRoZSBxdWV1ZSBwaXBlbGluZVxuICogYW5kIHZlcmlmeWluZyBpdCBpcyBwcm9jZXNzZWQgYnkgdGhlIHNwZWNpZmllZCBlbmRwb2ludC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGJ5cGFzc2VzIERlcGxveW1lbnQgUHJvdGVjdGlvbiBvbiBWZXJjZWwgYmVjYXVzZSBpdCBnb2VzXG4gKiB0aHJvdWdoIHRoZSBxdWV1ZSBpbmZyYXN0cnVjdHVyZSByYXRoZXIgdGhhbiBkaXJlY3QgSFRUUC5cbiAqXG4gKiBAcGFyYW0gd29ybGQgLSBUaGUgV29ybGQgaW5zdGFuY2UgdG8gdXNlIGZvciB0aGUgaGVhbHRoIGNoZWNrXG4gKiBAcGFyYW0gZW5kcG9pbnQgLSBXaGljaCBlbmRwb2ludCB0byBoZWFsdGggY2hlY2s6ICd3b3JrZmxvdycgb3IgJ3N0ZXAnXG4gKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBoZWFsdGggY2hlY2tcbiAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIGhlYWx0aCBjaGVjayByZXN1bHRcbiAqL1xuLy8gUG9sbCBpbnRlcnZhbCBmb3IgaGVhbHRoIGNoZWNrIHJldHJpZXMgKG1zKVxuY29uc3QgSEVBTFRIX0NIRUNLX1BPTExfSU5URVJWQUwgPSAxMDA7XG4vLyBQZXItcmVhZCB0aW1lb3V0IHRvIHByZXZlbnQgYmxvY2tpbmcgZm9yZXZlciBvbiBsb2NhbCB3b3JsZCdzIEV2ZW50RW1pdHRlclxuLy8gKHdoaWNoIGRvZXNuJ3Qgd29yayBhY3Jvc3MgcHJvY2Vzc2VzKVxuY29uc3QgSEVBTFRIX0NIRUNLX1JFQURfVElNRU9VVCA9IDUwMDtcblxuLyoqXG4gKiBSZWFkIGNodW5rcyBmcm9tIGEgc3RyZWFtIHdpdGggYSB0aW1lb3V0IHBlciByZWFkIG9wZXJhdGlvbi5cbiAqIFJldHVybnMgeyBjaHVua3MsIHRpbWVkT3V0IH0gd2hlcmUgdGltZWRPdXQgaW5kaWNhdGVzIGlmIGEgcmVhZCB0aW1lZCBvdXQuXG4gKi9cbi8qKlxuICogUmFjZSBhIHByb21pc2UgYWdhaW5zdCBhIGRlYWRsaW5lLiBSZWplY3RzIHdpdGggYSB0aW1lb3V0IGVycm9yIHdoZW4gdGhlXG4gKiBkZWFkbGluZSBlbGFwc2VzIGZpcnN0LiBVc2VkIHRvIGJvdW5kIGB3b3JsZC5zdHJlYW1zLmdldCgpYCBpbnNpZGUgdGhlXG4gKiBoZWFsdGgtY2hlY2sgcG9sbCBsb29wOiBzb21lIHdvcmxkcyBob2xkIHRoYXQgcmVxdWVzdCBvcGVuIHVudGlsIHRoZVxuICogc3RyZWFtIGhhcyBkYXRhIChlLmcuIHdvcmtmbG93LXNlcnZlciBob2xkcyB1bndyaXR0ZW4gc3RyZWFtcyBvcGVuIGZvclxuICogfjIgbWludXRlcyksIHdoaWNoIHdvdWxkIG90aGVyd2lzZSBibG93IHRocm91Z2ggdGhlIGNvbmZpZ3VyZWQgaGVhbHRoXG4gKiBjaGVjayB0aW1lb3V0IOKAlCB0aGUgYHdoaWxlYCBjb25kaXRpb24gaXMgb25seSByZS1jaGVja2VkIGJldHdlZW5cbiAqIGl0ZXJhdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIHdpdGhEZWFkbGluZTxUPihwcm9taXNlOiBQcm9taXNlPFQ+LCBtczogbnVtYmVyKTogUHJvbWlzZTxUPiB7XG4gIGxldCB0aW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCB1bmRlZmluZWQ7XG4gIHJldHVybiBQcm9taXNlLnJhY2UoW1xuICAgIHByb21pc2UsXG4gICAgbmV3IFByb21pc2U8bmV2ZXI+KChfLCByZWplY3QpID0+IHtcbiAgICAgIHRpbWVyID0gc2V0VGltZW91dChcbiAgICAgICAgKCkgPT4gcmVqZWN0KG5ldyBFcnJvcihgT3BlcmF0aW9uIHRpbWVkIG91dCBhZnRlciAke21zfW1zYCkpLFxuICAgICAgICBtc1xuICAgICAgKTtcbiAgICB9KSxcbiAgXSkuZmluYWxseSgoKSA9PiBjbGVhclRpbWVvdXQodGltZXIpKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVhZFN0cmVhbVdpdGhUaW1lb3V0KFxuICByZWFkZXI6IFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcjxVaW50OEFycmF5PixcbiAgcmVhZFRpbWVvdXQ6IG51bWJlclxuKTogUHJvbWlzZTx7IGNodW5rczogVWludDhBcnJheVtdOyB0aW1lZE91dDogYm9vbGVhbiB9PiB7XG4gIGNvbnN0IGNodW5rczogVWludDhBcnJheVtdID0gW107XG4gIGxldCBkb25lID0gZmFsc2U7XG4gIGxldCB0aW1lZE91dCA9IGZhbHNlO1xuXG4gIHdoaWxlICghZG9uZSAmJiAhdGltZWRPdXQpIHtcbiAgICBjb25zdCByZWFkUHJvbWlzZSA9IHJlYWRlci5yZWFkKCk7XG4gICAgY29uc3QgdGltZW91dFByb21pc2UgPSBuZXcgUHJvbWlzZTx7IGRvbmU6IHRydWU7IHZhbHVlOiB1bmRlZmluZWQgfT4oXG4gICAgICAocmVzb2x2ZSkgPT5cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGltZWRPdXQgPSB0cnVlO1xuICAgICAgICAgIHJlc29sdmUoeyBkb25lOiB0cnVlLCB2YWx1ZTogdW5kZWZpbmVkIH0pO1xuICAgICAgICB9LCByZWFkVGltZW91dClcbiAgICApO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgUHJvbWlzZS5yYWNlKFtyZWFkUHJvbWlzZSwgdGltZW91dFByb21pc2VdKTtcbiAgICBkb25lID0gcmVzdWx0LmRvbmU7XG4gICAgaWYgKHJlc3VsdC52YWx1ZSkgY2h1bmtzLnB1c2gocmVzdWx0LnZhbHVlKTtcbiAgfVxuXG4gIHJldHVybiB7IGNodW5rcywgdGltZWRPdXQgfTtcbn1cblxuLyoqXG4gKiBQYXJzZSBhbmQgdmFsaWRhdGUgYSBoZWFsdGggY2hlY2sgcmVzcG9uc2UgZnJvbSBzdHJlYW0gY2h1bmtzLlxuICogUmV0dXJucyB0aGUgcGFyc2VkIHJlc3BvbnNlIG9yIG51bGwgaWYgaW52YWxpZC5cbiAqL1xuZnVuY3Rpb24gcGFyc2VIZWFsdGhDaGVja1Jlc3BvbnNlKGNodW5rczogVWludDhBcnJheVtdKToge1xuICBoZWFsdGh5OiBib29sZWFuO1xuICBzcGVjVmVyc2lvbj86IG51bWJlcjtcbiAgd29ya2Zsb3dDb3JlVmVyc2lvbj86IHN0cmluZztcbn0gfCBudWxsIHtcbiAgaWYgKGNodW5rcy5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuXG4gIGNvbnN0IHRvdGFsTGVuZ3RoID0gY2h1bmtzLnJlZHVjZSgoc3VtLCBjaHVuaykgPT4gc3VtICsgY2h1bmsubGVuZ3RoLCAwKTtcbiAgY29uc3QgY29tYmluZWQgPSBuZXcgVWludDhBcnJheSh0b3RhbExlbmd0aCk7XG4gIGxldCBvZmZzZXQgPSAwO1xuICBmb3IgKGNvbnN0IGNodW5rIG9mIGNodW5rcykge1xuICAgIGNvbWJpbmVkLnNldChjaHVuaywgb2Zmc2V0KTtcbiAgICBvZmZzZXQgKz0gY2h1bmsubGVuZ3RoO1xuICB9XG4gIGNvbnN0IHJlc3BvbnNlVGV4dCA9IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShjb21iaW5lZCk7XG5cbiAgbGV0IHJlc3BvbnNlOiB1bmtub3duO1xuICB0cnkge1xuICAgIHJlc3BvbnNlID0gSlNPTi5wYXJzZShyZXNwb25zZVRleHQpO1xuICB9IGNhdGNoIHtcbiAgICAvLyBPbGQgZGVwbG95bWVudHMgKHNwZWNWZXJzaW9uIDwgMykgcmV0dXJuIHBsYWluIHRleHQgbGlrZVxuICAgIC8vICdXb3JrZmxvdyBTREsgXCIuLi5cIiBlbmRwb2ludCBpcyBoZWFsdGh5Jy4gVHJlYXQgYW55IG5vbi1lbXB0eVxuICAgIC8vIHRleHQgcmVzcG9uc2UgYXMgYSBoZWFsdGh5IGRlcGxveW1lbnQgd2l0aCB1bmtub3duIHNwZWNWZXJzaW9uLlxuICAgIGlmIChyZXNwb25zZVRleHQubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIHsgaGVhbHRoeTogdHJ1ZSB9O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmIChcbiAgICB0eXBlb2YgcmVzcG9uc2UgIT09ICdvYmplY3QnIHx8XG4gICAgcmVzcG9uc2UgPT09IG51bGwgfHxcbiAgICAhKCdoZWFsdGh5JyBpbiByZXNwb25zZSkgfHxcbiAgICB0eXBlb2YgKHJlc3BvbnNlIGFzIHsgaGVhbHRoeTogdW5rbm93biB9KS5oZWFsdGh5ICE9PSAnYm9vbGVhbidcbiAgKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCByID0gcmVzcG9uc2UgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGNvbnN0IHBhcnNlZDoge1xuICAgIGhlYWx0aHk6IGJvb2xlYW47XG4gICAgc3BlY1ZlcnNpb24/OiBudW1iZXI7XG4gICAgd29ya2Zsb3dDb3JlVmVyc2lvbj86IHN0cmluZztcbiAgfSA9IHtcbiAgICBoZWFsdGh5OiByLmhlYWx0aHkgYXMgYm9vbGVhbixcbiAgfTtcbiAgaWYgKHR5cGVvZiByLnNwZWNWZXJzaW9uID09PSAnbnVtYmVyJykge1xuICAgIHBhcnNlZC5zcGVjVmVyc2lvbiA9IHIuc3BlY1ZlcnNpb247XG4gIH1cbiAgaWYgKHR5cGVvZiByLndvcmtmbG93Q29yZVZlcnNpb24gPT09ICdzdHJpbmcnKSB7XG4gICAgcGFyc2VkLndvcmtmbG93Q29yZVZlcnNpb24gPSByLndvcmtmbG93Q29yZVZlcnNpb247XG4gIH1cbiAgcmV0dXJuIHBhcnNlZDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhlYWx0aENoZWNrKFxuICB3b3JsZDogV29ybGQsXG4gIGVuZHBvaW50OiBIZWFsdGhDaGVja0VuZHBvaW50LFxuICBvcHRpb25zPzogSGVhbHRoQ2hlY2tPcHRpb25zXG4pOiBQcm9taXNlPEhlYWx0aENoZWNrUmVzdWx0PiB7XG4gIGNvbnN0IHRpbWVvdXQgPSBvcHRpb25zPy50aW1lb3V0ID8/IERFRkFVTFRfSEVBTFRIX0NIRUNLX1RJTUVPVVQ7XG4gIGNvbnN0IGNvcnJlbGF0aW9uSWQgPSBnZW5lcmF0ZUlkKCk7XG4gIGNvbnN0IHN0cmVhbU5hbWUgPSBnZXRIZWFsdGhDaGVja1N0cmVhbU5hbWUoY29ycmVsYXRpb25JZCk7XG5cbiAgY29uc3QgcXVldWVOYW1lID1cbiAgICBgJHtnZXRRdWV1ZVRvcGljUHJlZml4KGVuZHBvaW50LCByZXNvbHZlUXVldWVOYW1lc3BhY2Uob3B0aW9ucz8ubmFtZXNwYWNlKSl9aGVhbHRoX2NoZWNrYCBhcyBWYWxpZFF1ZXVlTmFtZTtcblxuICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgd29ybGQucXVldWUoXG4gICAgICBxdWV1ZU5hbWUsXG4gICAgICB7IF9faGVhbHRoQ2hlY2s6IHRydWUsIGNvcnJlbGF0aW9uSWQgfSxcbiAgICAgIHtcbiAgICAgICAgLy8gVXNlIEpTT04gdHJhbnNwb3J0IHNvIHRoZSBoZWFsdGggY2hlY2sgd29ya3MgYWdhaW5zdCBib3RoXG4gICAgICAgIC8vIG9sZCAoSlNPTi1vbmx5KSBhbmQgbmV3IChkdWFsKSBkZXBsb3ltZW50cy5cbiAgICAgICAgc3BlY1ZlcnNpb246IFNQRUNfVkVSU0lPTl9MRUdBQ1ksXG4gICAgICAgIGRlcGxveW1lbnRJZDogb3B0aW9ucz8uZGVwbG95bWVudElkLFxuICAgICAgfVxuICAgICk7XG5cbiAgICB3aGlsZSAoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSA8IHRpbWVvdXQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlbWFpbmluZ01zID0gdGltZW91dCAtIChEYXRlLm5vdygpIC0gc3RhcnRUaW1lKTtcbiAgICAgICAgY29uc3Qgc3RyZWFtID0gYXdhaXQgd2l0aERlYWRsaW5lKFxuICAgICAgICAgIHdvcmxkLnN0cmVhbXMuZ2V0KFxuICAgICAgICAgICAgZ2VuZXJhdGVIZWFsdGhDaGVja1J1bklkKGNvcnJlbGF0aW9uSWQpLFxuICAgICAgICAgICAgc3RyZWFtTmFtZVxuICAgICAgICAgICksXG4gICAgICAgICAgcmVtYWluaW5nTXNcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLmdldFJlYWRlcigpO1xuICAgICAgICBjb25zdCB7IGNodW5rcywgdGltZWRPdXQgfSA9IGF3YWl0IHJlYWRTdHJlYW1XaXRoVGltZW91dChcbiAgICAgICAgICByZWFkZXIsXG4gICAgICAgICAgSEVBTFRIX0NIRUNLX1JFQURfVElNRU9VVFxuICAgICAgICApO1xuXG4gICAgICAgIGlmICh0aW1lZE91dCkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZWFkZXIuY2FuY2VsKCk7XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgY2FuY2VsIGVycm9yc1xuICAgICAgICAgIH1cbiAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT5cbiAgICAgICAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgSEVBTFRIX0NIRUNLX1BPTExfSU5URVJWQUwpXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gcGFyc2VIZWFsdGhDaGVja1Jlc3BvbnNlKGNodW5rcyk7XG4gICAgICAgIGlmIChyZXNwb25zZSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5yZXNwb25zZSxcbiAgICAgICAgICAgIGxhdGVuY3lNczogRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+XG4gICAgICAgICAgc2V0VGltZW91dChyZXNvbHZlLCBIRUFMVEhfQ0hFQ0tfUE9MTF9JTlRFUlZBTClcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT5cbiAgICAgICAgICBzZXRUaW1lb3V0KHJlc29sdmUsIEhFQUxUSF9DSEVDS19QT0xMX0lOVEVSVkFMKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgaGVhbHRoeTogZmFsc2UsXG4gICAgICBlcnJvcjogYEhlYWx0aCBjaGVjayB0aW1lZCBvdXQgYWZ0ZXIgJHt0aW1lb3V0fW1zYCxcbiAgICB9O1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB7XG4gICAgICBoZWFsdGh5OiBmYWxzZSxcbiAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvciksXG4gICAgfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBldmVudFBhZ2luYXRpb25Db250cmFjdEVycm9yKFxuICBydW5JZDogc3RyaW5nLFxuICBtZXNzYWdlOiBzdHJpbmdcbik6IFdvcmtmbG93V29ybGRFcnJvciB7XG4gIHJldHVybiBuZXcgV29ya2Zsb3dXb3JsZEVycm9yKFxuICAgIGBFdmVudCBwYWdpbmF0aW9uICR7bWVzc2FnZX0gZm9yIHdvcmtmbG93IHJ1biBcIiR7cnVuSWR9XCIuYCxcbiAgICB7IGNvZGU6IFJVTl9FUlJPUl9DT0RFUy5XT1JMRF9DT05UUkFDVF9FUlJPUiB9XG4gICk7XG59XG5cbmZ1bmN0aW9uIHJlY29yZFJlcXVlc3RlZEV2ZW50Q3Vyc29yKFxuICBydW5JZDogc3RyaW5nLFxuICBjdXJzb3I6IHN0cmluZyB8IG51bGwsXG4gIHJlcXVlc3RlZEN1cnNvcnM6IFNldDxzdHJpbmc+XG4pOiB2b2lkIHtcbiAgaWYgKCFjdXJzb3IpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHJlcXVlc3RlZEN1cnNvcnMuaGFzKGN1cnNvcikpIHtcbiAgICB0aHJvdyBldmVudFBhZ2luYXRpb25Db250cmFjdEVycm9yKHJ1bklkLCAnZGlkIG5vdCBhZHZhbmNlJyk7XG4gIH1cbiAgcmVxdWVzdGVkQ3Vyc29ycy5hZGQoY3Vyc29yKTtcbn1cblxuZnVuY3Rpb24gYXBwZW5kVW5pcXVlRXZlbnRzKFxuICB0YXJnZXQ6IEV2ZW50W10sXG4gIHRhcmdldElkczogU2V0PHN0cmluZz4sXG4gIGV2ZW50czogRXZlbnRbXVxuKTogdm9pZCB7XG4gIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgaWYgKCF0YXJnZXRJZHMuaGFzKGV2ZW50LmV2ZW50SWQpKSB7XG4gICAgICB0YXJnZXRJZHMuYWRkKGV2ZW50LmV2ZW50SWQpO1xuICAgICAgdGFyZ2V0LnB1c2goZXZlbnQpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhc3NlcnRFdmVudFBhZ2luYXRpb25Qcm9ncmVzcyhcbiAgcnVuSWQ6IHN0cmluZyxcbiAgaGFzTW9yZTogYm9vbGVhbixcbiAgY3Vyc29yOiBzdHJpbmcgfCBudWxsLFxuICByZXF1ZXN0ZWRDdXJzb3JzOiBTZXQ8c3RyaW5nPlxuKTogdm9pZCB7XG4gIGlmICghaGFzTW9yZSkge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoY3Vyc29yID09PSBudWxsKSB7XG4gICAgdGhyb3cgZXZlbnRQYWdpbmF0aW9uQ29udHJhY3RFcnJvcihcbiAgICAgIHJ1bklkLFxuICAgICAgJ3JldHVybmVkIG1vcmUgcGFnZXMgd2l0aG91dCBhIGN1cnNvcidcbiAgICApO1xuICB9XG4gIGlmIChyZXF1ZXN0ZWRDdXJzb3JzLmhhcyhjdXJzb3IpKSB7XG4gICAgdGhyb3cgZXZlbnRQYWdpbmF0aW9uQ29udHJhY3RFcnJvcihydW5JZCwgJ3JlcGVhdGVkIGEgY3Vyc29yJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2hvdWxkUmV0cnlXaXRob3V0RXZlbnRDdXJzb3IoXG4gIGVycm9yOiB1bmtub3duLFxuICBjdXJzb3I6IHN0cmluZyB8IG51bGwsXG4gIGFscmVhZHlSZXRyaWVkOiBib29sZWFuXG4pOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBjdXJzb3IgIT09IG51bGwgJiZcbiAgICAhYWxyZWFkeVJldHJpZWQgJiZcbiAgICBXb3JrZmxvd1dvcmxkRXJyb3IuaXMoZXJyb3IpICYmXG4gICAgZXJyb3Iuc3RhdHVzID09PSA0MDBcbiAgKTtcbn1cblxuLyoqXG4gKiBMb2FkcyB3b3JrZmxvdyBydW4gZXZlbnRzIGJ5IGl0ZXJhdGluZyB0aHJvdWdoIGFsbCBwYWdlcyBvZiBwYWdpbmF0ZWRcbiAqIHJlc3VsdHMuIEV2ZW50cyBhcmUgcmV0dXJuZWQgaW4gY2hyb25vbG9naWNhbCAoYXNjZW5kaW5nKSBvcmRlciBmb3JcbiAqIGRldGVybWluaXN0aWMgd29ya2Zsb3cgcmVwbGF5LlxuICpcbiAqIEBwYXJhbSBydW5JZCAtIFRoZSB3b3JrZmxvdyBydW4gSUQuXG4gKiBAcGFyYW0gYWZ0ZXJDdXJzb3IgLSBJZiBwcm92aWRlZCwgb25seSBldmVudHMgYWZ0ZXIgdGhpcyBjdXJzb3IgYXJlXG4gKiAgIHJldHVybmVkIChpbmNyZW1lbnRhbCBsb2FkKS4gSWYgb21pdHRlZCwgYWxsIGV2ZW50cyBhcmUgcmV0dXJuZWQuXG4gKiAgIFRoZSByZXR1cm5lZCBjdXJzb3IgY2FuIGJlIHBhc3NlZCBiYWNrIGluIG9uIGEgc3Vic2VxdWVudCBjYWxsIGZvclxuICogICBpbmNyZW1lbnRhbCBsb2FkaW5nLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9hZFdvcmtmbG93UnVuRXZlbnRzKFxuICBydW5JZDogc3RyaW5nLFxuICBhZnRlckN1cnNvcj86IHN0cmluZ1xuKTogUHJvbWlzZTx7IGV2ZW50czogRXZlbnRbXTsgY3Vyc29yOiBzdHJpbmcgfCBudWxsIH0+IHtcbiAgY29uc3QgaW5jcmVtZW50YWwgPSBhZnRlckN1cnNvciAhPT0gdW5kZWZpbmVkO1xuICByZXR1cm4gdHJhY2UoXG4gICAgaW5jcmVtZW50YWwgPyAnd29ya2Zsb3cubG9hZE5ld0V2ZW50cycgOiAnd29ya2Zsb3cubG9hZEV2ZW50cycsXG4gICAgYXN5bmMgKHNwYW4pID0+IHtcbiAgICAgIHNwYW4/LnNldEF0dHJpYnV0ZXMoe1xuICAgICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dSdW5JZChydW5JZCksXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgbG9hZGVkRXZlbnRzOiBFdmVudFtdID0gW107XG4gICAgICBjb25zdCBsb2FkZWRFdmVudElkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgY29uc3QgcmVxdWVzdGVkQ3Vyc29ycyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgbGV0IGN1cnNvcjogc3RyaW5nIHwgbnVsbCA9IGFmdGVyQ3Vyc29yID8/IG51bGw7XG4gICAgICBsZXQgaGFzTW9yZSA9IHRydWU7XG4gICAgICBsZXQgcGFnZXNMb2FkZWQgPSAwO1xuICAgICAgbGV0IHJldHJpZWRXaXRob3V0Q3Vyc29yID0gZmFsc2U7XG5cbiAgICAgIGNvbnN0IHdvcmxkID0gYXdhaXQgZ2V0V29ybGRMYXp5KCk7XG4gICAgICBjb25zdCBsb2FkU3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgd2hpbGUgKGhhc01vcmUpIHtcbiAgICAgICAgLy8gVE9ETzogd2UncmUgY3VycmVudGx5IGxvYWRpbmcgYWxsIHRoZSBkYXRhIHdpdGggcmVzb2x2ZVJlZiBiZWhhdmlvdXIuIFdlIG5lZWQgdG8gdXBkYXRlIHRoaXNcbiAgICAgICAgLy8gdG8gbGF6eWxvYWQgdGhlIGRhdGEgZnJvbSB0aGUgd29ybGQgaW5zdGVhZCBzbyB0aGF0IHdlIGNhbiBvcHRpbWl6ZSBhbmQgbWFrZSB0aGUgZXZlbnQgbG9nIGxvYWRpbmdcbiAgICAgICAgLy8gbXVjaCBmYXN0ZXIgYW5kIG1lbW9yeSBlZmZpY2llbnRcbiAgICAgICAgY29uc3QgcGFnZVN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgY29uc3QgcmVxdWVzdGVkQ3Vyc29yID0gY3Vyc29yO1xuICAgICAgICByZWNvcmRSZXF1ZXN0ZWRFdmVudEN1cnNvcihydW5JZCwgcmVxdWVzdGVkQ3Vyc29yLCByZXF1ZXN0ZWRDdXJzb3JzKTtcblxuICAgICAgICBsZXQgcmVzcG9uc2U6IEF3YWl0ZWQ8UmV0dXJuVHlwZTx0eXBlb2Ygd29ybGQuZXZlbnRzLmxpc3Q+PjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXNwb25zZSA9IGF3YWl0IHdvcmxkLmV2ZW50cy5saXN0KHtcbiAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgcGFnaW5hdGlvbjoge1xuICAgICAgICAgICAgICBzb3J0T3JkZXI6ICdhc2MnLFxuICAgICAgICAgICAgICBjdXJzb3I6IHJlcXVlc3RlZEN1cnNvciA/PyB1bmRlZmluZWQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHNob3VsZFJldHJ5V2l0aG91dEV2ZW50Q3Vyc29yKFxuICAgICAgICAgICAgICBlcnJvcixcbiAgICAgICAgICAgICAgcmVxdWVzdGVkQ3Vyc29yLFxuICAgICAgICAgICAgICByZXRyaWVkV2l0aG91dEN1cnNvclxuICAgICAgICAgICAgKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcnVudGltZUxvZ2dlci53YXJuKFxuICAgICAgICAgICAgICAnRXZlbnQgY3Vyc29yIHdhcyByZWplY3RlZDsgcmV0cnlpbmcgd2l0aCBhIGZ1bGwgZXZlbnQgcmVsb2FkLicsXG4gICAgICAgICAgICAgIHsgd29ya2Zsb3dSdW5JZDogcnVuSWQgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGxvYWRlZEV2ZW50cy5sZW5ndGggPSAwO1xuICAgICAgICAgICAgbG9hZGVkRXZlbnRJZHMuY2xlYXIoKTtcbiAgICAgICAgICAgIHJlcXVlc3RlZEN1cnNvcnMuY2xlYXIoKTtcbiAgICAgICAgICAgIGN1cnNvciA9IG51bGw7XG4gICAgICAgICAgICByZXRyaWVkV2l0aG91dEN1cnNvciA9IHRydWU7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICBhcHBlbmRVbmlxdWVFdmVudHMobG9hZGVkRXZlbnRzLCBsb2FkZWRFdmVudElkcywgcmVzcG9uc2UuZGF0YSk7XG4gICAgICAgIGhhc01vcmUgPSByZXNwb25zZS5oYXNNb3JlO1xuICAgICAgICBhc3NlcnRFdmVudFBhZ2luYXRpb25Qcm9ncmVzcyhcbiAgICAgICAgICBydW5JZCxcbiAgICAgICAgICBoYXNNb3JlLFxuICAgICAgICAgIHJlc3BvbnNlLmN1cnNvcixcbiAgICAgICAgICByZXF1ZXN0ZWRDdXJzb3JzXG4gICAgICAgICk7XG4gICAgICAgIC8vIFByZXNlcnZlIHRoZSBsYXN0IG5vbi1udWxsIGN1cnNvciBhY3Jvc3MgcGFnZXMuIEEgV29ybGQgbWF5XG4gICAgICAgIC8vIGxlZ2l0aW1hdGVseSByZXR1cm4gYHsgZGF0YTogW10sIGN1cnNvcjogbnVsbCwgaGFzTW9yZTogZmFsc2UgfWBcbiAgICAgICAgLy8gb24gYSB0cmFpbGluZyBlbXB0eSBwYWdlIOKAlCBmb3IgZXhhbXBsZSB3aGVuIHRoZSBwcmV2aW91cyBwYWdlJ3NcbiAgICAgICAgLy8gdW5kZXJseWluZyBEQiBxdWVyeSBoaXQgdGhlIGxpbWl0IGV4YWN0bHkgYW5kIHJldHVybmVkIGFcbiAgICAgICAgLy8gYExhc3RFdmFsdWF0ZWRLZXlgIFwianVzdCBpbiBjYXNlXCIuIE92ZXJ3cml0aW5nIHdpdGggdGhhdCBudWxsXG4gICAgICAgIC8vIHdvdWxkIGxvc2UgdGhlIHBvc2l0aW9uIHBhc3QgdGhlIGxhc3QgcmVhbCBldmVudCB3ZSBsb2FkZWQgYW5kXG4gICAgICAgIC8vIGZvcmNlIHRoZSBydW50aW1lIGludG8gdGhlIFwibm8gY3Vyc29yIGFmdGVyIGluaXRpYWwgbG9hZFwiIGZ1bGwtXG4gICAgICAgIC8vIHJlbG9hZCBmYWxsYmFjayBvbiBldmVyeSBzdWJzZXF1ZW50IHJlcGxheSBpdGVyYXRpb24uXG4gICAgICAgIGN1cnNvciA9IHJlc3BvbnNlLmN1cnNvciA/PyBjdXJzb3I7XG4gICAgICAgIHBhZ2VzTG9hZGVkKys7XG5cbiAgICAgICAgcnVudGltZUxvZ2dlci5kZWJ1ZygnTG9hZGVkIGV2ZW50IHBhZ2UnLCB7XG4gICAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgICAgaW5jcmVtZW50YWwsXG4gICAgICAgICAgcGFnZTogcGFnZXNMb2FkZWQsXG4gICAgICAgICAgcGFnZUV2ZW50czogcmVzcG9uc2UuZGF0YS5sZW5ndGgsXG4gICAgICAgICAgdG90YWxFdmVudHM6IGxvYWRlZEV2ZW50cy5sZW5ndGgsXG4gICAgICAgICAgaGFzTW9yZSxcbiAgICAgICAgICBwYWdlTXM6IERhdGUubm93KCkgLSBwYWdlU3RhcnQsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBydW50aW1lTG9nZ2VyLmRlYnVnKCdFdmVudCBsb2FkIGNvbXBsZXRlJywge1xuICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgaW5jcmVtZW50YWwsXG4gICAgICAgIHRvdGFsRXZlbnRzOiBsb2FkZWRFdmVudHMubGVuZ3RoLFxuICAgICAgICBwYWdlc0xvYWRlZCxcbiAgICAgICAgdG90YWxNczogRGF0ZS5ub3coKSAtIGxvYWRTdGFydCxcbiAgICAgIH0pO1xuXG4gICAgICBzcGFuPy5zZXRBdHRyaWJ1dGVzKHtcbiAgICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93RXZlbnRzQ291bnQobG9hZGVkRXZlbnRzLmxlbmd0aCksXG4gICAgICAgIC4uLkF0dHJpYnV0ZS5Xb3JrZmxvd0V2ZW50c1BhZ2VzTG9hZGVkKHBhZ2VzTG9hZGVkKSxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4geyBldmVudHM6IGxvYWRlZEV2ZW50cywgY3Vyc29yIH07XG4gICAgfVxuICApO1xufVxuXG4vKipcbiAqIENPUlMgaGVhZGVycyBmb3IgaGVhbHRoIGNoZWNrIHJlc3BvbnNlcy5cbiAqIEFsbG93cyB0aGUgb2JzZXJ2YWJpbGl0eSBVSSB0byBjaGVjayBlbmRwb2ludCBoZWFsdGggZnJvbSBhIGRpZmZlcmVudCBvcmlnaW4uXG4gKi9cbmNvbnN0IEhFQUxUSF9DSEVDS19DT1JTX0hFQURFUlMgPSB7XG4gICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW4nOiAnKicsXG4gICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJzogJ1BPU1QsIE9QVElPTlMsIEdFVCwgSEVBRCcsXG4gICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1IZWFkZXJzJzogJ0NvbnRlbnQtVHlwZScsXG59O1xuXG4vKipcbiAqIFdyYXBzIGEgcmVxdWVzdC9yZXNwb25zZSBoYW5kbGVyIGFuZCBhZGRzIGEgaGVhbHRoIGNoZWNrIFwibW9kZVwiXG4gKiBiYXNlZCBvbiB0aGUgcHJlc2VuY2Ugb2YgYSBgX19oZWFsdGhgIHF1ZXJ5IHBhcmFtZXRlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdpdGhIZWFsdGhDaGVjayhcbiAgaGFuZGxlcjogKHJlcTogUmVxdWVzdCkgPT4gUHJvbWlzZTxSZXNwb25zZT4sXG4gIHdvcmxkU3BlY1ZlcnNpb24/OiBudW1iZXJcbik6IChyZXE6IFJlcXVlc3QpID0+IFByb21pc2U8UmVzcG9uc2U+IHtcbiAgcmV0dXJuIGFzeW5jIChyZXE6IFJlcXVlc3QpID0+IHtcbiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHJlcS51cmwpO1xuICAgIGNvbnN0IGlzSGVhbHRoQ2hlY2sgPSB1cmwuc2VhcmNoUGFyYW1zLmhhcygnX19oZWFsdGgnKTtcbiAgICBpZiAoaXNIZWFsdGhDaGVjaykge1xuICAgICAgLy8gSGFuZGxlIENPUlMgcHJlZmxpZ2h0IGZvciBoZWFsdGggY2hlY2tcbiAgICAgIGlmIChyZXEubWV0aG9kID09PSAnT1BUSU9OUycpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShudWxsLCB7XG4gICAgICAgICAgc3RhdHVzOiAyMDQsXG4gICAgICAgICAgaGVhZGVyczogSEVBTFRIX0NIRUNLX0NPUlNfSEVBREVSUyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKFxuICAgICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgaGVhbHRoeTogdHJ1ZSxcbiAgICAgICAgICBlbmRwb2ludDogdXJsLnBhdGhuYW1lLFxuICAgICAgICAgIHNwZWNWZXJzaW9uOiB3b3JsZFNwZWNWZXJzaW9uID8/IFNQRUNfVkVSU0lPTl9DVVJSRU5ULFxuICAgICAgICAgIHdvcmtmbG93Q29yZVZlcnNpb24sXG4gICAgICAgIH0pLFxuICAgICAgICB7XG4gICAgICAgICAgc3RhdHVzOiAyMDAsXG4gICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgIC4uLkhFQUxUSF9DSEVDS19DT1JTX0hFQURFUlMsXG4gICAgICAgICAgfSxcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIGF3YWl0IGhhbmRsZXIocmVxKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBRdWV1ZXMgYSBtZXNzYWdlIHRvIHRoZSBzcGVjaWZpZWQgcXVldWUgd2l0aCB0cmFjaW5nLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcXVldWVNZXNzYWdlKFxuICB3b3JsZDogV29ybGQsXG4gIC4uLmFyZ3M6IFBhcmFtZXRlcnM8dHlwZW9mIHdvcmxkLnF1ZXVlPlxuKSB7XG4gIGNvbnN0IHF1ZXVlTmFtZSA9IGFyZ3NbMF07XG4gIGF3YWl0IHRyYWNlKFxuICAgICdxdWV1ZS5wdWJsaXNoJyxcbiAgICB7XG4gICAgICAvLyBTdGFuZGFyZCBPVEVMIG1lc3NhZ2luZyBjb252ZW50aW9uc1xuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAuLi5BdHRyaWJ1dGUuTWVzc2FnaW5nU3lzdGVtKCd2ZXJjZWwtcXVldWUnKSxcbiAgICAgICAgLi4uQXR0cmlidXRlLk1lc3NhZ2luZ0Rlc3RpbmF0aW9uTmFtZShxdWV1ZU5hbWUpLFxuICAgICAgICAuLi5BdHRyaWJ1dGUuTWVzc2FnaW5nT3BlcmF0aW9uVHlwZSgncHVibGlzaCcpLFxuICAgICAgICAvLyBQZWVyIHNlcnZpY2UgZm9yIERhdGFkb2cgc2VydmljZSBtYXBzXG4gICAgICAgIC4uLkF0dHJpYnV0ZS5QZWVyU2VydmljZSgndmVyY2VsLXF1ZXVlJyksXG4gICAgICAgIC4uLkF0dHJpYnV0ZS5ScGNTeXN0ZW0oJ3ZlcmNlbC1xdWV1ZScpLFxuICAgICAgICAuLi5BdHRyaWJ1dGUuUnBjU2VydmljZSgndnFzJyksXG4gICAgICAgIC4uLkF0dHJpYnV0ZS5ScGNNZXRob2QoJ3B1Ymxpc2gnKSxcbiAgICAgIH0sXG4gICAgICBraW5kOiBhd2FpdCBnZXRTcGFuS2luZCgnUFJPRFVDRVInKSxcbiAgICB9LFxuICAgIGFzeW5jIChzcGFuKSA9PiB7XG4gICAgICBjb25zdCB7IG1lc3NhZ2VJZCB9ID0gYXdhaXQgd29ybGQucXVldWUoLi4uYXJncyk7XG4gICAgICBpZiAobWVzc2FnZUlkKSB7XG4gICAgICAgIHNwYW4/LnNldEF0dHJpYnV0ZXMoQXR0cmlidXRlLk1lc3NhZ2luZ01lc3NhZ2VJZChtZXNzYWdlSWQpKTtcbiAgICAgIH1cbiAgICB9XG4gICk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgcXVldWUgb3ZlcmhlYWQgdGltZSBpbiBtaWxsaXNlY29uZHMgZm9yIGEgZ2l2ZW4gbWVzc2FnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFF1ZXVlT3ZlcmhlYWQobWVzc2FnZTogeyByZXF1ZXN0ZWRBdD86IERhdGUgfSkge1xuICBpZiAoIW1lc3NhZ2UucmVxdWVzdGVkQXQpIHJldHVybjtcbiAgdHJ5IHtcbiAgICByZXR1cm4gQXR0cmlidXRlLlF1ZXVlT3ZlcmhlYWRNcyhcbiAgICAgIERhdGUubm93KCkgLSBtZXNzYWdlLnJlcXVlc3RlZEF0LmdldFRpbWUoKVxuICAgICk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybjtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgYSBtZW1vaXplZCBhY2Nlc3NvciBmb3IgdGhlIHBlci1ydW4gQUVTLTI1NiBlbmNyeXB0aW9uIGtleS5cbiAqXG4gKiBUaGUgZmlyc3QgY2FsbCByZXNvbHZlcyB0aGUga2V5IHZpYSBgd29ybGQuZ2V0RW5jcnlwdGlvbktleUZvclJ1bmAgKHdoaWNoXG4gKiBtYXkgZG8gSEtERiBkZXJpdmF0aW9uIGxvY2FsbHkgb24gVmVyY2VsLCBvciBhIG5ldHdvcmsgZmV0Y2ggZnJvbVxuICogZXh0ZXJuYWwgY29udGV4dHMpIGFuZCBpbXBvcnRzIGl0IGFzIGEgYENyeXB0b0tleWA7IHN1YnNlcXVlbnQgY2FsbHNcbiAqIGF3YWl0IHRoZSBzYW1lIGNhY2hlZCBwcm9taXNlLiBJZiB0aGUgd29ybGQgZG9lc24ndCBzdXBwb3J0IGVuY3J5cHRpb25cbiAqIG9yIHRoZSBydW4gaGFzIG5vIGtleSBjb25maWd1cmVkLCB0aGUgY2FjaGVkIHZhbHVlIGlzIGB1bmRlZmluZWRgLlxuICpcbiAqIFVzZWQgYnkgc3RlcCAvIHdvcmtmbG93IGhhbmRsZXJzIHRvIGRlZmVyIHRoZSAocG90ZW50aWFsbHkgZXhwZW5zaXZlKVxuICoga2V5IGZldGNoIHVudGlsIHRoZSBmaXJzdCBjb2RlIHBhdGggdGhhdCBhY3R1YWxseSBuZWVkcyBpdCDigJQgdHlwaWNhbGx5XG4gKiBpbnB1dCBoeWRyYXRpb24gb24gdGhlIHN1Y2Nlc3MgcGF0aCwgb3IgZXJyb3IgZGVoeWRyYXRpb24gb24gYSBmYWlsdXJlXG4gKiBwYXRoLiBCb3RoIHBhdGhzIGNhbiByYWNlLWNhbGwgdGhlIGFjY2Vzc29yIHdpdGhvdXQgdHJpZ2dlcmluZyBkdXBsaWNhdGVcbiAqIGZldGNoZXMuXG4gKlxuICogRXJyb3JzIHRocm93biBieSBgZ2V0RW5jcnlwdGlvbktleUZvclJ1bmAgcHJvcGFnYXRlIHRvIGV2ZXJ5IGNhbGxlclxuICogKHRoZSBjYWNoZWQgcHJvbWlzZSByZWplY3RzKS4gVGhpcyBpcyBpbnRlbnRpb25hbDogd2hlbiBlbmNyeXB0aW9uIGlzXG4gKiBjb25maWd1cmVkLCB3ZSBuZXZlciB3YW50IHRvIHNpbGVudGx5IGZhbGwgYmFjayB0byBwbGFpbnRleHRcbiAqIHNlcmlhbGl6YXRpb24uIEEgcHJvcGFnYXRlZCBlcnJvciBpbiBhbiBldmVudC1lbWlzc2lvbiBwYXRoIGxlYXZlcyB0aGVcbiAqIG91dGVyIHRyeS9jYXRjaCB0byBsb2cgYW5kIHN1cmZhY2UgdGhlIGlzc3VlOyB0aGUgcXVldWUncyByZWRlbGl2ZXJ5XG4gKiBzZW1hbnRpY3Mgd2lsbCByZXRyeSB0aGUga2V5IGZldGNoIG9uIHRoZSBuZXh0IGF0dGVtcHQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZW1vaXplRW5jcnlwdGlvbktleShcbiAgd29ybGQ6IFdvcmxkLFxuICBydW5PcklkOiBXb3JrZmxvd1J1biB8IHN0cmluZ1xuKTogKCkgPT4gUHJvbWlzZTxDcnlwdG9LZXkgfCB1bmRlZmluZWQ+IHtcbiAgbGV0IGNhY2hlZDogUHJvbWlzZTxDcnlwdG9LZXkgfCB1bmRlZmluZWQ+IHwgdW5kZWZpbmVkO1xuICByZXR1cm4gKCkgPT4ge1xuICAgIGlmICghY2FjaGVkKSB7XG4gICAgICBjYWNoZWQgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAvLyBUaGUgYGdldEVuY3J5cHRpb25LZXlGb3JSdW5gIG92ZXJsb2FkIHNldCB0YWtlcyBlaXRoZXIgYVxuICAgICAgICAvLyBgV29ya2Zsb3dSdW5gIG9yIGEgYHJ1bklkOiBzdHJpbmdgICh3aXRoIG9wdGlvbmFsIGNvbnRleHQpLiBCcmFuY2hcbiAgICAgICAgLy8gaGVyZSBzbyBUeXBlU2NyaXB0IHBpY2tzIHRoZSByaWdodCBvdmVybG9hZCBmb3IgZWFjaCBzaGFwZS5cbiAgICAgICAgY29uc3QgcmF3S2V5ID1cbiAgICAgICAgICB0eXBlb2YgcnVuT3JJZCA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgID8gYXdhaXQgd29ybGQuZ2V0RW5jcnlwdGlvbktleUZvclJ1bj8uKHJ1bk9ySWQpXG4gICAgICAgICAgICA6IGF3YWl0IHdvcmxkLmdldEVuY3J5cHRpb25LZXlGb3JSdW4/LihydW5PcklkKTtcbiAgICAgICAgcmV0dXJuIHJhd0tleSA/IGF3YWl0IGltcG9ydEtleShyYXdLZXkpIDogdW5kZWZpbmVkO1xuICAgICAgfSkoKTtcbiAgICB9XG4gICAgcmV0dXJuIGNhY2hlZDtcbiAgfTtcbn1cbiJdfQ==
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Per-invocation accounting of the *non-step* portion of a workflow
3
+ * handler run: deterministic event-log replay, workflow-VM execution
4
+ * between step boundaries, suspension handling, queue round-trips, etc.
5
+ * Inline step bodies (`"use step"` functions invoked via `executeStep`)
6
+ * are intentionally excluded — they are bounded by the platform's
7
+ * function `maxDuration` and the `NO_INLINE_REPLAY_AFTER_MS` early-return
8
+ * guard.
9
+ *
10
+ * Usage:
11
+ *
12
+ * ```ts
13
+ * const budget = new ReplayBudget();
14
+ * // …non-step work happens here, accumulates against the budget…
15
+ * budget.pause();
16
+ * try {
17
+ * await executeStep(...); // not charged
18
+ * } finally {
19
+ * budget.resume();
20
+ * }
21
+ * // back to charging
22
+ * if (budget.isExhausted()) { ... }
23
+ * ```
24
+ *
25
+ * Implementation notes:
26
+ *
27
+ * - `pause()` and `resume()` are idempotent: calling `pause()` while
28
+ * already paused (or `resume()` while already resumed) is a no-op.
29
+ * This protects against double-counting in future refactors that nest
30
+ * step execution or take an early-return path between a `pause()` and
31
+ * the matching `resume()`.
32
+ * - `isExhausted()` is checked at loop boundaries by the caller — the
33
+ * budget itself does not arm any timers. This means an in-flight
34
+ * pathological `runWorkflow` call (e.g. a huge event-log replay) can
35
+ * overshoot the budget by up to one iteration's worth of work before
36
+ * the next check fires. In practice the 20s headroom built into
37
+ * `MAX_REPLAY_TIMEOUT_MS` (and the function `maxDuration` ceiling)
38
+ * gives us slack; the old `setTimeout`-based approach also ultimately
39
+ * relied on the platform SIGTERM as the hard backstop.
40
+ */
41
+ export declare class ReplayBudget {
42
+ private readonly limitMs;
43
+ private elapsedMs;
44
+ private intervalStart;
45
+ constructor(limitMs?: number);
46
+ /**
47
+ * The configured replay-timeout limit, in ms. Useful for log messages.
48
+ */
49
+ get configuredLimitMs(): number;
50
+ /**
51
+ * Total non-step time accumulated so far, in ms. Includes the
52
+ * currently-active interval if the budget is not paused.
53
+ */
54
+ elapsed(): number;
55
+ /**
56
+ * Stop counting elapsed time toward the budget. Idempotent — safe to
57
+ * call multiple times in a row; subsequent calls are no-ops until
58
+ * `resume()` reopens an interval.
59
+ */
60
+ pause(): void;
61
+ /**
62
+ * Resume counting elapsed time toward the budget. Idempotent — safe to
63
+ * call multiple times in a row; subsequent calls re-anchor the
64
+ * interval start to `now()`, which is fine because no time accrues
65
+ * between back-to-back `resume()` calls.
66
+ */
67
+ resume(): void;
68
+ /**
69
+ * True if the budget has been exhausted (`elapsed() >= limitMs`).
70
+ * Callers should invoke `handleExhausted(...)` afterward and return
71
+ * from the handler.
72
+ */
73
+ isExhausted(): boolean;
74
+ }
75
+ /**
76
+ * Fail the run (or retry, on early attempts) when the replay budget is
77
+ * exhausted. The handling depends on whether the underlying World
78
+ * supports `process.exit(1)` as a queue redelivery signal (see
79
+ * `World.processExitTriggersQueueRedelivery`):
80
+ *
81
+ * - **Managed-platform Worlds** (`world-vercel`): on attempts <=
82
+ * `REPLAY_TIMEOUT_MAX_RETRIES` exit the process so the platform fails
83
+ * the invocation and the queue redelivers; on the next attempt write
84
+ * `run_failed` with `RUN_ERROR_CODES.REPLAY_TIMEOUT` and exit.
85
+ *
86
+ * - **In-process Worlds** (`world-local`, dev servers): calling
87
+ * `process.exit()` would terminate the host (e.g. `pnpm dev`), so
88
+ * instead log a warning, write `run_failed` best-effort, and return.
89
+ * The framework completes the request normally.
90
+ */
91
+ export declare function handleReplayBudgetExhausted(args: {
92
+ runId: string;
93
+ workflowName: string;
94
+ requestId: string | undefined;
95
+ attempt: number;
96
+ limitMs: number;
97
+ }): Promise<void>;
98
+ //# sourceMappingURL=replay-budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay-budget.d.ts","sourceRoot":"","sources":["../../src/runtime/replay-budget.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,aAAa,CAAgB;gBAEzB,OAAO,GAAE,MAA6B;IAKlD;;OAEG;IACH,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED;;;OAGG;IACH,OAAO,IAAI,MAAM;IAMjB;;;;OAIG;IACH,KAAK,IAAI,IAAI;IAMb;;;;;OAKG;IACH,MAAM,IAAI,IAAI;IAId;;;;OAIG;IACH,WAAW,IAAI,OAAO;CAGvB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,2BAA2B,CAAC,IAAI,EAAE;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkHhB"}