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

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 (322) 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 +33 -1
  5. package/dist/capabilities.d.ts.map +1 -1
  6. package/dist/capabilities.js +71 -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 +109 -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 +149 -0
  22. package/dist/create-hook.d.ts +62 -4
  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 +189 -0
  30. package/dist/encryption.d.ts +37 -3
  31. package/dist/encryption.d.ts.map +1 -1
  32. package/dist/encryption.js +97 -31
  33. package/dist/events-consumer.d.ts +147 -1
  34. package/dist/events-consumer.d.ts.map +1 -1
  35. package/dist/events-consumer.js +444 -43
  36. package/dist/flushable-stream.d.ts +65 -10
  37. package/dist/flushable-stream.d.ts.map +1 -1
  38. package/dist/flushable-stream.js +131 -18
  39. package/dist/global.d.ts +37 -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 +246 -8
  52. package/dist/private.d.ts.map +1 -1
  53. package/dist/private.js +345 -9
  54. package/dist/replay-payload-cache.d.ts +68 -0
  55. package/dist/replay-payload-cache.d.ts.map +1 -0
  56. package/dist/replay-payload-cache.js +160 -0
  57. package/dist/runtime/compute-instance.d.ts +12 -0
  58. package/dist/runtime/compute-instance.d.ts.map +1 -0
  59. package/dist/runtime/compute-instance.js +13 -0
  60. package/dist/runtime/constants.d.ts +251 -0
  61. package/dist/runtime/constants.d.ts.map +1 -1
  62. package/dist/runtime/constants.js +425 -16
  63. package/dist/runtime/count-step-started-events.d.ts +52 -0
  64. package/dist/runtime/count-step-started-events.d.ts.map +1 -0
  65. package/dist/runtime/count-step-started-events.js +72 -0
  66. package/dist/runtime/deployment-guard.d.ts +99 -0
  67. package/dist/runtime/deployment-guard.d.ts.map +1 -0
  68. package/dist/runtime/deployment-guard.js +154 -0
  69. package/dist/runtime/get-port-lazy.d.ts +25 -0
  70. package/dist/runtime/get-port-lazy.d.ts.map +1 -0
  71. package/dist/runtime/get-port-lazy.js +92 -0
  72. package/dist/runtime/get-world-lazy.d.ts +23 -0
  73. package/dist/runtime/get-world-lazy.d.ts.map +1 -0
  74. package/dist/runtime/get-world-lazy.js +46 -0
  75. package/dist/runtime/helpers.d.ts +327 -10
  76. package/dist/runtime/helpers.d.ts.map +1 -1
  77. package/dist/runtime/helpers.js +586 -40
  78. package/dist/runtime/quickjs-assets.generated.d.ts +14 -0
  79. package/dist/runtime/quickjs-assets.generated.d.ts.map +1 -0
  80. package/dist/runtime/quickjs-assets.generated.js +30 -0
  81. package/dist/runtime/quickjs-entrypoint.d.ts +124 -0
  82. package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -0
  83. package/dist/runtime/quickjs-entrypoint.js +1437 -0
  84. package/dist/runtime/quickjs-runtime.d.ts +228 -0
  85. package/dist/runtime/quickjs-runtime.d.ts.map +1 -0
  86. package/dist/runtime/quickjs-runtime.js +2372 -0
  87. package/dist/runtime/quickjs-serde.d.ts +107 -0
  88. package/dist/runtime/quickjs-serde.d.ts.map +1 -0
  89. package/dist/runtime/quickjs-serde.js +2098 -0
  90. package/dist/runtime/replay-budget.d.ts +89 -0
  91. package/dist/runtime/replay-budget.d.ts.map +1 -0
  92. package/dist/runtime/replay-budget.js +139 -0
  93. package/dist/runtime/replay-recovery-reporter.d.ts +36 -0
  94. package/dist/runtime/replay-recovery-reporter.d.ts.map +1 -0
  95. package/dist/runtime/replay-recovery-reporter.js +64 -0
  96. package/dist/runtime/resume-hook.d.ts +27 -4
  97. package/dist/runtime/resume-hook.d.ts.map +1 -1
  98. package/dist/runtime/resume-hook.js +452 -76
  99. package/dist/runtime/run-id-time.d.ts +19 -0
  100. package/dist/runtime/run-id-time.d.ts.map +1 -0
  101. package/dist/runtime/run-id-time.js +42 -0
  102. package/dist/runtime/run.d.ts +8 -2
  103. package/dist/runtime/run.d.ts.map +1 -1
  104. package/dist/runtime/run.js +62 -15
  105. package/dist/runtime/runs.d.ts +54 -3
  106. package/dist/runtime/runs.d.ts.map +1 -1
  107. package/dist/runtime/runs.js +119 -13
  108. package/dist/runtime/start.d.ts +70 -1
  109. package/dist/runtime/start.d.ts.map +1 -1
  110. package/dist/runtime/start.js +313 -60
  111. package/dist/runtime/step-executor.d.ts +177 -0
  112. package/dist/runtime/step-executor.d.ts.map +1 -0
  113. package/dist/runtime/step-executor.js +946 -0
  114. package/dist/runtime/step-latency.d.ts +197 -0
  115. package/dist/runtime/step-latency.d.ts.map +1 -0
  116. package/dist/runtime/step-latency.js +207 -0
  117. package/dist/runtime/step-ownership.d.ts +72 -0
  118. package/dist/runtime/step-ownership.d.ts.map +1 -0
  119. package/dist/runtime/step-ownership.js +114 -0
  120. package/dist/runtime/step-single-flight.d.ts +12 -0
  121. package/dist/runtime/step-single-flight.d.ts.map +1 -0
  122. package/dist/runtime/step-single-flight.js +69 -0
  123. package/dist/runtime/suspension-handler.d.ts +109 -7
  124. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  125. package/dist/runtime/suspension-handler.js +486 -140
  126. package/dist/runtime/vm-mode.d.ts +44 -0
  127. package/dist/runtime/vm-mode.d.ts.map +1 -0
  128. package/dist/runtime/vm-mode.js +62 -0
  129. package/dist/runtime/vm-serde-bundle.generated.d.ts +14 -0
  130. package/dist/runtime/vm-serde-bundle.generated.d.ts.map +1 -0
  131. package/dist/runtime/vm-serde-bundle.generated.js +16 -0
  132. package/dist/runtime/wait-continuation.d.ts +84 -0
  133. package/dist/runtime/wait-continuation.d.ts.map +1 -0
  134. package/dist/runtime/wait-continuation.js +105 -0
  135. package/dist/runtime/wait-until.d.ts +18 -0
  136. package/dist/runtime/wait-until.d.ts.map +1 -0
  137. package/dist/runtime/wait-until.js +42 -0
  138. package/dist/runtime/world-compatibility.d.ts +20 -0
  139. package/dist/runtime/world-compatibility.d.ts.map +1 -0
  140. package/dist/runtime/world-compatibility.js +32 -0
  141. package/dist/runtime/world-init.d.ts +50 -0
  142. package/dist/runtime/world-init.d.ts.map +1 -0
  143. package/dist/runtime/world-init.js +50 -0
  144. package/dist/runtime/world.d.ts +14 -2
  145. package/dist/runtime/world.d.ts.map +1 -1
  146. package/dist/runtime/world.js +101 -26
  147. package/dist/runtime.d.ts +17 -12
  148. package/dist/runtime.d.ts.map +1 -1
  149. package/dist/runtime.js +3135 -328
  150. package/dist/schemas.d.ts +1 -1
  151. package/dist/schemas.d.ts.map +1 -1
  152. package/dist/schemas.js +1 -1
  153. package/dist/sealed-box.d.ts +167 -0
  154. package/dist/sealed-box.d.ts.map +1 -0
  155. package/dist/sealed-box.js +571 -0
  156. package/dist/serialization/client.d.ts +17 -0
  157. package/dist/serialization/client.d.ts.map +1 -0
  158. package/dist/serialization/client.js +48 -0
  159. package/dist/serialization/codec-devalue-vm.d.ts +16 -0
  160. package/dist/serialization/codec-devalue-vm.d.ts.map +1 -0
  161. package/dist/serialization/codec-devalue-vm.js +148 -0
  162. package/dist/serialization/codec-devalue.d.ts +14 -0
  163. package/dist/serialization/codec-devalue.d.ts.map +1 -0
  164. package/dist/serialization/codec-devalue.js +105 -0
  165. package/dist/serialization/codec.d.ts +125 -0
  166. package/dist/serialization/codec.d.ts.map +1 -0
  167. package/dist/serialization/codec.js +17 -0
  168. package/dist/serialization/compression.d.ts +104 -0
  169. package/dist/serialization/compression.d.ts.map +1 -0
  170. package/dist/serialization/compression.js +260 -0
  171. package/dist/serialization/encryption.d.ts +134 -0
  172. package/dist/serialization/encryption.d.ts.map +1 -0
  173. package/dist/serialization/encryption.js +186 -0
  174. package/dist/serialization/errors.d.ts +34 -0
  175. package/dist/serialization/errors.d.ts.map +1 -0
  176. package/dist/serialization/errors.js +59 -0
  177. package/dist/serialization/format.d.ts +60 -0
  178. package/dist/serialization/format.d.ts.map +1 -0
  179. package/dist/serialization/format.js +97 -0
  180. package/dist/serialization/hardened.d.ts +155 -0
  181. package/dist/serialization/hardened.d.ts.map +1 -0
  182. package/dist/serialization/hardened.js +523 -0
  183. package/dist/serialization/index.d.ts +20 -0
  184. package/dist/serialization/index.d.ts.map +1 -0
  185. package/dist/serialization/index.js +22 -0
  186. package/dist/serialization/reducers/class-vm.d.ts +20 -0
  187. package/dist/serialization/reducers/class-vm.d.ts.map +1 -0
  188. package/dist/serialization/reducers/class-vm.js +77 -0
  189. package/dist/serialization/reducers/class.d.ts +11 -0
  190. package/dist/serialization/reducers/class.d.ts.map +1 -0
  191. package/dist/serialization/reducers/class.js +73 -0
  192. package/dist/serialization/reducers/common-vm.d.ts +15 -0
  193. package/dist/serialization/reducers/common-vm.d.ts.map +1 -0
  194. package/dist/serialization/reducers/common-vm.js +579 -0
  195. package/dist/serialization/reducers/common.d.ts +16 -0
  196. package/dist/serialization/reducers/common.d.ts.map +1 -0
  197. package/dist/serialization/reducers/common.js +478 -0
  198. package/dist/serialization/reducers/step-function-vm.d.ts +44 -0
  199. package/dist/serialization/reducers/step-function-vm.d.ts.map +1 -0
  200. package/dist/serialization/reducers/step-function-vm.js +97 -0
  201. package/dist/serialization/reducers/step-function.d.ts +35 -0
  202. package/dist/serialization/reducers/step-function.d.ts.map +1 -0
  203. package/dist/serialization/reducers/step-function.js +104 -0
  204. package/dist/serialization/step.d.ts +17 -0
  205. package/dist/serialization/step.d.ts.map +1 -0
  206. package/dist/serialization/step.js +48 -0
  207. package/dist/serialization/types.d.ts +273 -0
  208. package/dist/serialization/types.d.ts.map +1 -0
  209. package/dist/serialization/types.js +35 -0
  210. package/dist/serialization/workflow-vm.d.ts +29 -0
  211. package/dist/serialization/workflow-vm.d.ts.map +1 -0
  212. package/dist/serialization/workflow-vm.js +71 -0
  213. package/dist/serialization/workflow.d.ts +29 -0
  214. package/dist/serialization/workflow.d.ts.map +1 -0
  215. package/dist/serialization/workflow.js +54 -0
  216. package/dist/serialization-format.d.ts +60 -4
  217. package/dist/serialization-format.d.ts.map +1 -1
  218. package/dist/serialization-format.js +276 -56
  219. package/dist/serialization.d.ts +374 -221
  220. package/dist/serialization.d.ts.map +1 -1
  221. package/dist/serialization.js +2300 -783
  222. package/dist/set-attributes.d.ts +13 -0
  223. package/dist/set-attributes.d.ts.map +1 -0
  224. package/dist/set-attributes.js +60 -0
  225. package/dist/sleep.d.ts.map +1 -1
  226. package/dist/sleep.js +3 -2
  227. package/dist/source-map.d.ts +25 -0
  228. package/dist/source-map.d.ts.map +1 -1
  229. package/dist/source-map.js +148 -10
  230. package/dist/step/context-storage.d.ts +61 -2
  231. package/dist/step/context-storage.d.ts.map +1 -1
  232. package/dist/step/context-storage.js +7 -5
  233. package/dist/step/get-closure-vars.d.ts.map +1 -1
  234. package/dist/step/get-closure-vars.js +3 -2
  235. package/dist/step/get-step-metadata.d.ts.map +1 -1
  236. package/dist/step/get-step-metadata.js +3 -2
  237. package/dist/step/get-workflow-metadata.d.ts.map +1 -1
  238. package/dist/step/get-workflow-metadata.js +3 -2
  239. package/dist/step/writable-stream.d.ts.map +1 -1
  240. package/dist/step/writable-stream.js +71 -7
  241. package/dist/step.d.ts.map +1 -1
  242. package/dist/step.js +225 -29
  243. package/dist/symbols.d.ts +54 -0
  244. package/dist/symbols.d.ts.map +1 -1
  245. package/dist/symbols.js +55 -1
  246. package/dist/telemetry/semantic-conventions.d.ts +265 -2
  247. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  248. package/dist/telemetry/semantic-conventions.js +190 -1
  249. package/dist/telemetry.d.ts +73 -0
  250. package/dist/telemetry.d.ts.map +1 -1
  251. package/dist/telemetry.js +153 -16
  252. package/dist/types.d.ts +6 -0
  253. package/dist/types.d.ts.map +1 -1
  254. package/dist/types.js +23 -1
  255. package/dist/util.d.ts +16 -6
  256. package/dist/util.d.ts.map +1 -1
  257. package/dist/util.js +25 -16
  258. package/dist/version.d.ts +1 -1
  259. package/dist/version.d.ts.map +1 -1
  260. package/dist/version.js +2 -2
  261. package/dist/vm/index.d.ts.map +1 -1
  262. package/dist/vm/index.js +85 -14
  263. package/dist/vm/script-cache.d.ts +28 -0
  264. package/dist/vm/script-cache.d.ts.map +1 -0
  265. package/dist/vm/script-cache.js +140 -0
  266. package/dist/workflow/abort-controller.d.ts +65 -0
  267. package/dist/workflow/abort-controller.d.ts.map +1 -0
  268. package/dist/workflow/abort-controller.js +312 -0
  269. package/dist/workflow/attribute-dispatcher.d.ts +6 -0
  270. package/dist/workflow/attribute-dispatcher.d.ts.map +1 -0
  271. package/dist/workflow/attribute-dispatcher.js +48 -0
  272. package/dist/workflow/create-hook.d.ts.map +1 -1
  273. package/dist/workflow/create-hook.js +25 -3
  274. package/dist/workflow/define-hook.d.ts +1 -1
  275. package/dist/workflow/define-hook.d.ts.map +1 -1
  276. package/dist/workflow/define-hook.js +8 -4
  277. package/dist/workflow/get-workflow-metadata.d.ts.map +1 -1
  278. package/dist/workflow/get-workflow-metadata.js +14 -3
  279. package/dist/workflow/hook.d.ts.map +1 -1
  280. package/dist/workflow/hook.js +302 -36
  281. package/dist/workflow/index.d.ts +1 -0
  282. package/dist/workflow/index.d.ts.map +1 -1
  283. package/dist/workflow/index.js +5 -3
  284. package/dist/workflow/set-attributes.d.ts +68 -0
  285. package/dist/workflow/set-attributes.d.ts.map +1 -0
  286. package/dist/workflow/set-attributes.js +60 -0
  287. package/dist/workflow/sleep.d.ts.map +1 -1
  288. package/dist/workflow/sleep.js +57 -8
  289. package/dist/workflow/world-init-stub.d.ts +15 -0
  290. package/dist/workflow/world-init-stub.d.ts.map +1 -0
  291. package/dist/workflow/world-init-stub.js +15 -0
  292. package/dist/workflow.d.ts +79 -3
  293. package/dist/workflow.d.ts.map +1 -1
  294. package/dist/workflow.js +831 -553
  295. package/docs/api-reference/create-hook.mdx +79 -0
  296. package/docs/api-reference/create-webhook.mdx +1 -0
  297. package/docs/api-reference/define-hook.mdx +26 -24
  298. package/docs/api-reference/fatal-error.mdx +29 -7
  299. package/docs/api-reference/fetch.mdx +8 -4
  300. package/docs/api-reference/index.mdx +3 -0
  301. package/docs/api-reference/set-attributes.mdx +61 -0
  302. package/docs/api-reference/sleep.mdx +1 -1
  303. package/docs/foundations/cancellation.mdx +459 -0
  304. package/docs/foundations/errors-and-retries.mdx +7 -3
  305. package/docs/foundations/hooks.mdx +29 -0
  306. package/docs/foundations/idempotency.mdx +243 -11
  307. package/docs/foundations/index.mdx +1 -23
  308. package/docs/foundations/meta.json +3 -1
  309. package/docs/foundations/serialization.mdx +77 -41
  310. package/docs/foundations/starting-workflows.mdx +79 -2
  311. package/docs/foundations/streaming.mdx +14 -23
  312. package/docs/foundations/versioning.mdx +263 -0
  313. package/docs/how-it-works/cancellation.mdx +287 -0
  314. package/docs/how-it-works/code-transform.mdx +21 -17
  315. package/docs/how-it-works/encryption.mdx +5 -5
  316. package/docs/how-it-works/event-sourcing.mdx +17 -9
  317. package/docs/how-it-works/framework-integrations.mdx +96 -337
  318. package/docs/how-it-works/meta.json +2 -1
  319. package/package.json +31 -13
  320. package/dist/runtime/step-handler.d.ts +0 -2
  321. package/dist/runtime/step-handler.d.ts.map +0 -1
  322. package/dist/runtime/step-handler.js +0 -678
package/dist/private.js CHANGED
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * Utils used by the bundler when transforming code
3
3
  */
4
+ import { withResolvers } from '@workflow/utils';
4
5
  const RegisteredStepsKey = Symbol.for('@workflow/core//registeredSteps');
5
6
  const globalSymbols = globalThis;
6
7
  // biome-ignore lint/suspicious/noAssignInExpressions: /
7
8
  const registeredSteps = (globalSymbols[RegisteredStepsKey] ??= new Map());
8
- const BUILTIN_STEP_NAMES = new Set([
9
+ const BUILTIN_RESPONSE_STEP_NAMES = new Set([
9
10
  '__builtin_response_array_buffer',
10
11
  '__builtin_response_json',
11
12
  '__builtin_response_text',
@@ -41,7 +42,7 @@ function getStepIdAliasCandidates(stepId) {
41
42
  return Array.from(modulePathAliases, (aliasModulePath) => `step//${aliasModulePath}//${fnName}`);
42
43
  }
43
44
  function getBuiltinResponseStepAlias(stepId) {
44
- if (!BUILTIN_STEP_NAMES.has(stepId)) {
45
+ if (!BUILTIN_RESPONSE_STEP_NAMES.has(stepId)) {
45
46
  return undefined;
46
47
  }
47
48
  for (const [registeredStepId, stepFn] of registeredSteps.entries()) {
@@ -85,18 +86,353 @@ export function getStepFunction(stepId) {
85
86
  }
86
87
  return undefined;
87
88
  }
89
+ /**
90
+ * Which earlier kinds each delivery kind defers behind. Chosen so that no kind
91
+ * blocks on a peer it does not need to:
92
+ *
93
+ * - a hook defers behind earlier WAITS and STEPS — not earlier hooks, which
94
+ * are sequential same-entity payloads and must not block one another;
95
+ * - a wait defers behind earlier HOOKS and STEPS — not earlier waits, since a
96
+ * wait never needs to queue behind another wait;
97
+ * - a step defers behind earlier WAITS, HOOKS and STEPS.
98
+ *
99
+ * The step-behind-step edge is not redundant with the serial `promiseQueue`.
100
+ * The queue fixes the order in which step results are HYDRATED, but a step no
101
+ * longer resolves inside its queue slot — it captures the outcome there and
102
+ * resolves from a detached continuation once its barrier clears. Two steps
103
+ * agree on that continuation's ordering only while they defer behind the same
104
+ * set, which holds when they are consumed in the same drain window but not
105
+ * across windows: a step consumed later can miss a wait/hook barrier that an
106
+ * earlier step is still parked on, because the barrier retired in between. The
107
+ * earlier step is then waiting out the macrotask yield below while the later
108
+ * one resolves on microtasks, and overtakes it — see
109
+ * `delivery-barrier-coverage.test.ts`. Deferring behind earlier steps
110
+ * closes that window structurally: the earlier step's barrier is still
111
+ * registered precisely because it has not delivered yet.
112
+ *
113
+ * Every edge points from a later log index to a strictly earlier one, so the
114
+ * wait-for graph can never contain a cycle.
115
+ */
116
+ const DEFER_BEHIND = {
117
+ hook: ['wait', 'step'],
118
+ wait: ['hook', 'step'],
119
+ step: ['wait', 'hook', 'step'],
120
+ };
121
+ /**
122
+ * Whether a delivery of `kind` at log index `index` gates on the earlier
123
+ * registry entry `other` (at `otherIndex`).
124
+ *
125
+ * Single source of truth for that question, called by both
126
+ * {@link awaitEarlierDeliveries} (which awaits what it gates on) and
127
+ * {@link computeResolvesOnItsOwn} (which recurses into what it gates on).
128
+ * Those two MUST agree exactly, and the doc block on
129
+ * {@link awaitEarlierDeliveries} stakes deadlock-freedom on it, so the
130
+ * condition lives here rather than being spelled out twice.
131
+ */
132
+ function gatesOn(kind, index, otherIndex, other) {
133
+ if (otherIndex >= index || !DEFER_BEHIND[kind].includes(other.kind)) {
134
+ return false;
135
+ }
136
+ // A step skips an UNARMED earlier entry (an unclaimed buffered hook
137
+ // payload) — see the asymmetry described on `awaitEarlierDeliveries`. The
138
+ // skip is direct, never transitive: armed entries are still gated on, even
139
+ // when they are themselves parked behind such a payload.
140
+ return !(kind === 'step' && !other.armed);
141
+ }
142
+ /**
143
+ * Whether `entry` will resolve on its own — it is armed, and every earlier
144
+ * delivery it actually gates on ({@link gatesOn}) will likewise resolve on its
145
+ * own.
146
+ *
147
+ * A step does not gate on an unclaimed buffered payload, so such a payload
148
+ * cannot keep it from resolving. A step DOES gate on earlier armed waits and
149
+ * hooks, so one parked behind an unclaimed payload makes the step
150
+ * non-self-resolving in turn. Disagreeing with {@link awaitEarlierDeliveries}
151
+ * here would not be a cosmetic problem: this predicate is what
152
+ * {@link hasParkedCommittedDelivery} uses to decide whether idle is reachable,
153
+ * and an entry reported self-resolving while it is in fact parked behind a
154
+ * payload that only the idle safety net can retire would gate its own
155
+ * retirement.
156
+ *
157
+ * Recursion terminates because every edge points to a strictly smaller index.
158
+ * `memo` keeps the walk linear in registry size, and the registry is not small
159
+ * by construction — `EventsConsumer` drains consecutively consumable events
160
+ * synchronously while barriers only retire on microtask-driven deliveries, so
161
+ * a fan-out of `Promise.race([hook, sleep])` branches accumulates one barrier
162
+ * per branch per kind. The memo MUST be per-call: `armed` mutates between
163
+ * calls as buffered payloads are claimed.
164
+ *
165
+ * The memo is an optimization, not a correctness requirement. It once was one:
166
+ * `awaitEarlierDeliveries` used to run this walk for every earlier entry of a
167
+ * step delivery, with no early exit, which unmemoized is T(n) = Σ T(j) —
168
+ * measured at 4.3e8 recursive calls (84s) for 40 alternating armed hook/wait
169
+ * barriers. That call site is gone; a step now tests `armed` directly. The one
170
+ * surviving caller, {@link hasParkedCommittedDelivery}, cannot reach that
171
+ * shape: it returns at the FIRST self-resolving entry, so it only ever
172
+ * advances past entries that are non-self-resolving, and those short-circuit
173
+ * on their first false child. Every entry it evaluates therefore has
174
+ * all-false predecessors and returns after one child, degenerating the walk to
175
+ * a chain (measured: 98 calls unmemoized for the worst 40-barrier shape, 1
176
+ * call for the registry above). Do not restore an exponential claim here
177
+ * without restoring a caller that can produce it.
178
+ */
179
+ function resolvesOnItsOwn(barriers, index, entry, memo) {
180
+ const cached = memo.get(index);
181
+ if (cached !== undefined) {
182
+ return cached;
183
+ }
184
+ const result = computeResolvesOnItsOwn(barriers, index, entry, memo);
185
+ memo.set(index, result);
186
+ return result;
187
+ }
188
+ function computeResolvesOnItsOwn(barriers, index, entry, memo) {
189
+ if (!entry.armed) {
190
+ return false;
191
+ }
192
+ for (const [otherIndex, other] of barriers) {
193
+ if (!gatesOn(entry.kind, index, otherIndex, other)) {
194
+ continue;
195
+ }
196
+ if (!resolvesOnItsOwn(barriers, otherIndex, other, memo)) {
197
+ return false;
198
+ }
199
+ }
200
+ return true;
201
+ }
202
+ /**
203
+ * Awaits, in strict event-log order, every still-registered delivery that is
204
+ * earlier in the log than `eventIndex` and that a delivery of `kind` defers
205
+ * behind (see {@link DEFER_BEHIND}), so that this resolution is handed to the
206
+ * workflow only after all relevant earlier-in-log deliveries have been. This
207
+ * is what keeps a `Promise.race` — or the ULID a follow-up `useStep` draws on
208
+ * a concurrent branch — deterministic and aligned with the committed event
209
+ * log, independent of microtask-hop counts, hydration time, or race-argument
210
+ * order. When this delivery does have to wait, it also yields a macrotask
211
+ * afterwards so the earlier delivery's consumer can run to its own next
212
+ * suspension point first; see the comment at that `await` for why ordering the
213
+ * `resolve()` calls alone is not enough.
214
+ *
215
+ * What counts as "defers behind" is {@link gatesOn}, shared with
216
+ * {@link computeResolvesOnItsOwn} so the two cannot drift.
217
+ *
218
+ * One asymmetry: a STEP result skips any earlier delivery that is UNARMED,
219
+ * i.e. a buffered hook payload no consumer has claimed. Such a payload is
220
+ * delivered only when the workflow next reads the hook, and reaching that read
221
+ * very commonly requires the step result itself (`await stepX()` before the
222
+ * read). Gating the step on it would stall the workflow until the barrier's
223
+ * idle safety net fires, which then releases every delivery queued behind that
224
+ * payload at once — losing exactly the race this ordering exists to protect.
225
+ * Waits and hooks keep gating on unclaimed payloads: for them, waiting for the
226
+ * claim IS the ordering guarantee (a `wait_completed` must not preempt a
227
+ * payload the log ordered first).
228
+ *
229
+ * The skip is direct, never transitive. A step still gates on an earlier ARMED
230
+ * wait or hook, including one that is itself parked behind an unclaimed
231
+ * payload. Skipping those too would invert log order for the commonest shape
232
+ * there is: a workflow that creates a hook it does not read on this branch,
233
+ * races `step` against `sleep`, and has the log say the sleep won. The step
234
+ * would then overtake the wait, both branches would swap the correlation ids
235
+ * they draw next, and replay would diverge — see
236
+ * `step-delivery-ordering.test.ts`. Waiting instead is safe because the
237
+ * payload's own idle safety net retires it and the whole chain then delivers
238
+ * in log order; {@link hasParkedCommittedDelivery} deliberately reports such a
239
+ * step as not self-resolving so that idle stays reachable.
240
+ *
241
+ * "The whole chain then delivers in log order" rests on the PAYLOAD's safety
242
+ * net observing idle before the net of the wait parked behind it. If the
243
+ * wait's net fired first, the step's gate would open while the wait was still
244
+ * parked on the payload barrier and the inversion above would reappear. Within
245
+ * one drain window that order is structural, and carried by FIFO of the
246
+ * safety-net polls: nets arm via `setTimeout` in log order during synchronous
247
+ * consumption, each polling round re-arms through `promiseQueue.then(...)` in
248
+ * the order the checks ran, and each net that fires flips
249
+ * {@link hasParkedCommittedDelivery} back to true, re-blocking the rest until
250
+ * the released delivery completes. Replay — where divergence manifests —
251
+ * always consumes the log in one window. Do not "optimize" the net scheduling
252
+ * in a way that breaks that per-window FIFO.
253
+ */
254
+ export async function awaitEarlierDeliveries(ctx, eventIndex, kind) {
255
+ // Defensive: tolerate contexts that predate this field (test harnesses).
256
+ if (eventIndex === undefined ||
257
+ !ctx.pendingDeliveryBarriers ||
258
+ ctx.pendingDeliveryBarriers.size === 0) {
259
+ return;
260
+ }
261
+ const barriers = ctx.pendingDeliveryBarriers;
262
+ const earlier = [];
263
+ for (const [index, entry] of barriers) {
264
+ if (!gatesOn(kind, eventIndex, index, entry)) {
265
+ continue;
266
+ }
267
+ earlier.push(entry.delivered);
268
+ }
269
+ if (earlier.length > 0) {
270
+ await Promise.all(earlier);
271
+ // An earlier delivery being "delivered" only means its `resolve()` ran.
272
+ // The branch it woke may need an arbitrary number of further microtask
273
+ // hops before it reaches its next `useStep` call and draws a ULID — a
274
+ // `for await` over a hook, for instance, resumes the generator, settles
275
+ // the promise from `next()`, and only then runs the loop body. Resolving
276
+ // this delivery on a microtask would let it overtake that branch and
277
+ // reorder the ULID allocation anyway, turning the guarantee below into a
278
+ // hop-count race that holds only for the shortest consumers.
279
+ //
280
+ // Yielding a macrotask lets the earlier branch's entire microtask chain
281
+ // drain first, whatever its length, so log order survives regardless of
282
+ // how the workflow consumes the earlier delivery. Only deliveries that
283
+ // actually had to defer pay this, so the common single-delivery drain is
284
+ // unaffected.
285
+ await new Promise((resolve) => setTimeout(resolve, 0));
286
+ }
287
+ }
288
+ /**
289
+ * Register a branch-deciding delivery at its event-log index so that later
290
+ * deliveries can be ordered strictly after it. Returns an inert handle when
291
+ * `pendingDeliveryBarriers` is not initialized.
292
+ *
293
+ * Pass `armed: false` for a delivery whose resolution waits on workflow code
294
+ * asking for it (a buffered hook payload); call `arm()` when it does.
295
+ *
296
+ * To guarantee a later delivery gated on this one can never hang when this
297
+ * delivery is abandoned (the workflow took a different branch or is
298
+ * suspending and never observes it), the barrier auto-resolves at idle.
299
+ *
300
+ * INVARIANT required of every call site: a barrier that is ever `armed` must
301
+ * be paired with a delivery chain that runs unconditionally — attached when
302
+ * the event is consumed (waits, step results, waiting-consumer hook payloads,
303
+ * aborts), or by the `claim()` whose invocation is what arms it (buffered
304
+ * hook payloads). The idle check ({@link scheduleWhenIdle}) refuses to
305
+ * observe idle while an armed, self-resolving barrier is undelivered, and the
306
+ * safety net below is itself idle-gated — so an armed barrier with no
307
+ * unconditional chain would livelock every idle check in the run, including
308
+ * its own retirement.
309
+ */
310
+ export function registerDeliveryBarrier(ctx, eventIndex, kind, options = {}) {
311
+ const barriers = ctx.pendingDeliveryBarriers;
312
+ if (!barriers || eventIndex === undefined) {
313
+ return { markDelivered: () => { }, arm: () => { } };
314
+ }
315
+ let done = false;
316
+ const { promise, resolve } = withResolvers();
317
+ const entry = {
318
+ kind,
319
+ delivered: promise,
320
+ armed: options.armed ?? true,
321
+ };
322
+ barriers.set(eventIndex, entry);
323
+ const finish = () => {
324
+ if (done) {
325
+ return;
326
+ }
327
+ done = true;
328
+ if (barriers.get(eventIndex) === entry) {
329
+ barriers.delete(eventIndex);
330
+ }
331
+ resolve();
332
+ };
333
+ // Safety net: if this delivery is never delivered to the workflow (its
334
+ // branch was not taken / the run is suspending, or a buffered hook payload
335
+ // is only claimed after a later delivery the workflow is still waiting on),
336
+ // resolve at idle so a later delivery gated on it cannot deadlock and the
337
+ // registry cannot leak an entry per abandoned delivery.
338
+ scheduleWhenIdle(ctx, finish);
339
+ return {
340
+ markDelivered: finish,
341
+ arm: () => {
342
+ entry.armed = true;
343
+ },
344
+ };
345
+ }
346
+ /**
347
+ * Whether some registered branch-deciding delivery is going to reach the
348
+ * workflow without any further help (it is armed and not transitively parked
349
+ * behind an unclaimed buffered payload — see {@link resolvesOnItsOwn}) but
350
+ * has not been handed over yet.
351
+ *
352
+ * This is the delivery state `pendingDeliveries` cannot see. That counter
353
+ * covers the hydration window inside a serial `promiseQueue` slot and is
354
+ * released there, while the delivery's `resolve()` runs later, from a
355
+ * detached continuation behind {@link awaitEarlierDeliveries} — including its
356
+ * macrotask yield whenever the delivery had to defer. Replaying a batch of N
357
+ * parallel step results consumed in one drain window leaves N-1 of them
358
+ * parked on that yield with `pendingDeliveries` already at 0. An idle check
359
+ * armed during the same window (a pending `sleep()` arms one on every replay)
360
+ * could then observe "idle" mid-deferral and raise a `WorkflowSuspension`
361
+ * BEFORE the workflow's own continuations ran — a suspension carrying none of
362
+ * the follow-up work the batch was about to create, which the runtime
363
+ * dutifully schedules as nothing, leaving the run dormant until an unrelated
364
+ * timer fires (vercel/workflow#3183).
365
+ *
366
+ * Deliveries that do NOT resolve on their own must be excluded, not for
367
+ * accuracy but for termination: an unclaimed buffered hook payload is retired
368
+ * BY the idle safety net in {@link registerDeliveryBarrier}, so counting it
369
+ * here would gate its own retirement. That reasoning extends to whatever is
370
+ * parked behind such a payload — a wait, and a step gating on that wait — for
371
+ * the same reason: the whole chain moves only once the net fires, and it
372
+ * cannot fire while the chain is counted. Self-resolving deliveries always
373
+ * deliver from their own chains (see the INVARIANT on
374
+ * {@link registerDeliveryBarrier}) and never need that net, so waiting on
375
+ * them is deadlock-free.
376
+ */
377
+ export function hasParkedCommittedDelivery(ctx) {
378
+ const barriers = ctx.pendingDeliveryBarriers;
379
+ if (!barriers || barriers.size === 0) {
380
+ return false;
381
+ }
382
+ // Shared across this call only — see `resolvesOnItsOwn`.
383
+ const selfResolving = new Map();
384
+ for (const [index, entry] of barriers) {
385
+ if (resolvesOnItsOwn(barriers, index, entry, selfResolving)) {
386
+ return true;
387
+ }
388
+ }
389
+ return false;
390
+ }
391
+ /**
392
+ * Whether no data delivery (step result, hook payload) is in flight right now.
393
+ *
394
+ * "In flight" is two distinct windows, each with its own guard:
395
+ * `pendingDeliveries > 0` covers hydration inside the serial queue slots, and
396
+ * {@link hasParkedCommittedDelivery} covers the detached gap between a slot
397
+ * releasing that counter and the delivery's `resolve()` actually running —
398
+ * deliberately outside `pendingDeliveries` (see step.ts), and invisible to it.
399
+ *
400
+ * Anything that decides a replay is over, or that a replay went wrong, has to
401
+ * consult this first: while it is false the workflow VM is mid-reaction, so
402
+ * what it has and has not done yet says nothing about the run. Two callers
403
+ * read it, for the two such decisions: {@link scheduleWhenIdle} for the
404
+ * suspension, and the events consumer's unconsumed-event check for divergence.
405
+ */
406
+ export function isDeliveryIdle(ctx) {
407
+ return ctx.pendingDeliveries === 0 && !hasParkedCommittedDelivery(ctx);
408
+ }
88
409
  /**
89
410
  * Schedule a callback to fire only after all pending data deliveries
90
411
  * (step results, hook payloads) and async deserialization have completed.
91
- * Uses a polling loop: setTimeout(0) → check pendingDeliveries
92
- * if > 0, wait for promiseQueue → repeat. This handles the multi-round
93
- * delivery pattern where each hook payload delivery cycle appends new
94
- * async work to the promiseQueue.
412
+ * Uses a polling loop: setTimeout(0) → check pendingDeliveries and the
413
+ * barrier registry → if anything is still in flight, wait for promiseQueue →
414
+ * repeat. This handles the multi-round delivery pattern where each hook
415
+ * payload delivery cycle appends new async work to the promiseQueue. What
416
+ * counts as in flight is {@link isDeliveryIdle}.
417
+ *
418
+ * The initial `setTimeout(0)` macrotask is load-bearing and must NOT be
419
+ * downgraded to a microtask (`queueMicrotask`/`Promise.resolve().then`).
420
+ * `pendingDeliveries` only guards the host-side hydration window; between a
421
+ * delivery's `resolve()` and the workflow VM body running its continuation to
422
+ * register the next subscriber, `pendingDeliveries` is already 0 even though
423
+ * the VM is mid-reaction. Node does not guarantee a microtask scheduled in
424
+ * the host context settles after the cross-VM promise chain (resolve in host
425
+ * → workflow code in VM → subscribe back in host); the macrotask boundary
426
+ * gives that chain time to run, so the suspension does not preempt a sibling
427
+ * delivery still in flight. Empirically, replacing it with `queueMicrotask`
428
+ * breaks hook/sleep `Promise.race` ordering (CorruptedEventLogError).
95
429
  */
96
430
  export function scheduleWhenIdle(ctx, fn) {
97
431
  const check = () => {
98
- if (ctx.pendingDeliveries > 0) {
99
- // Still delivering data wait for queue to drain, then re-check
432
+ if (!isDeliveryIdle(ctx)) {
433
+ // A delivery is still hydrating, or is committed but parked behind its
434
+ // deferral (whose resolve runs on a detached timer, not this queue).
435
+ // Either way: let the queue drain, then re-check a timer tick later.
100
436
  ctx.promiseQueue.then(() => {
101
437
  setTimeout(check, 0);
102
438
  });
@@ -107,4 +443,4 @@ export function scheduleWhenIdle(ctx, fn) {
107
443
  };
108
444
  setTimeout(check, 0);
109
445
  }
110
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpdmF0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9wcml2YXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBZUgsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7QUFFekUsTUFBTSxhQUFhLEdBRWYsVUFBVSxDQUFDO0FBRWYsd0RBQXdEO0FBQ3hELE1BQU0sZUFBZSxHQUFHLENBQUMsYUFBYSxDQUFDLGtCQUFrQixDQUFDLEtBQUssSUFBSSxHQUFHLEVBR25FLENBQUMsQ0FBQztBQUVMLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDakMsaUNBQWlDO0lBQ2pDLHlCQUF5QjtJQUN6Qix5QkFBeUI7Q0FDMUIsQ0FBQyxDQUFDO0FBRUgsU0FBUyx3QkFBd0IsQ0FBQyxNQUFjO0lBQzlDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakMsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssTUFBTSxFQUFFLENBQUM7UUFDOUMsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN4QixNQUFNLGlCQUFpQixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFFNUMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxlQUF1QixFQUFFLEVBQUU7UUFDM0MsSUFBSSxlQUFlLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDbkMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ3pDLENBQUM7SUFDSCxDQUFDLENBQUM7SUFFRixJQUFJLFVBQVUsQ0FBQyxVQUFVLENBQUMsY0FBYyxD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akIsSUFBSSxHQUFHLENBQUMsaUJBQWlCLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDOUIsaUVBQWlFO1lBQ2pFLEdBQUcsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtnQkFDekIsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztZQUN2QixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7YUFBTSxDQUFDO1lBQ04sRUFBRSxFQUFFLENBQUM7UUFDUCxDQUFDO0lBQ0gsQ0FBQyxDQUFDO0lBQ0YsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN2QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBVdGlscyB1c2VkIGJ5IHRoZSBidW5kbGVyIHdoZW4gdHJhbnNmb3JtaW5nIGNvZGVcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IENyeXB0b0tleSB9IGZyb20gJy4vZW5jcnlwdGlvbi5qcyc7XG5pbXBvcnQgdHlwZSB7IEV2ZW50c0NvbnN1bWVyIH0gZnJvbSAnLi9ldmVudHMtY29uc3VtZXIuanMnO1xuaW1wb3J0IHR5cGUgeyBRdWV1ZUl0ZW0gfSBmcm9tICcuL2dsb2JhbC5qcyc7XG5pbXBvcnQgdHlwZSB7IFNlcmlhbGl6YWJsZSB9IGZyb20gJy4vc2NoZW1hcy5qcyc7XG5cbmV4cG9ydCB0eXBlIFN0ZXBGdW5jdGlvbjxcbiAgQXJncyBleHRlbmRzIFNlcmlhbGl6YWJsZVtdID0gYW55W10sXG4gIFJlc3VsdCBleHRlbmRzIFNlcmlhbGl6YWJsZSB8IHVua25vd24gPSB1bmtub3duLFxuPiA9ICgoLi4uYXJnczogQXJncykgPT4gUHJvbWlzZTxSZXN1bHQ+KSAmIHtcbiAgbWF4UmV0cmllcz86IG51bWJlcjtcbiAgc3RlcElkPzogc3RyaW5nO1xufTtcblxuY29uc3QgUmVnaXN0ZXJlZFN0ZXBzS2V5ID0gU3ltYm9sLmZvcignQHdvcmtmbG93L2NvcmUvL3JlZ2lzdGVyZWRTdGVwcycpO1xuXG5jb25zdCBnbG9iYWxTeW1ib2xzOiB0eXBlb2YgZ2xvYmFsVGhpcyAmIHtcbiAgW1JlZ2lzdGVyZWRTdGVwc0tleV0/OiBNYXA8c3RyaW5nLCBTdGVwRnVuY3Rpb24+O1xufSA9IGdsb2JhbFRoaXM7XG5cbi8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9Bc3NpZ25JbkV4cHJlc3Npb25zOiAvXG5jb25zdCByZWdpc3RlcmVkU3RlcHMgPSAoZ2xvYmFsU3ltYm9sc1tSZWdpc3RlcmVkU3RlcHNLZXldID8/PSBuZXcgTWFwPFxuICBzdHJpbmcsXG4gIFN0ZXBGdW5jdGlvblxuPigpKTtcblxuY29uc3QgQlVJTFRJTl9TVEVQX05BTUVTID0gbmV3IFNldChbXG4gICdfX2J1aWx0aW5fcmVzcG9uc2VfYXJyYXlfYnVmZmVyJyxcbiAgJ19fYnVpbHRpbl9yZXNwb25zZV9qc29uJyxcbiAgJ19fYnVpbHRpbl9yZXNwb25zZV90ZXh0Jyxcbl0pO1xuXG5mdW5jdGlvbiBnZXRTdGVwSWRBbGlhc0NhbmRpZGF0ZXMoc3RlcElkOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHBhcnRzID0gc3RlcElkLnNwbGl0KCcvLycpO1xuICBpZiAocGFydHMubGVuZ3RoICE9PSAzIHx8IHBhcnRzWzBdICE9PSAnc3RlcCcpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBtb2R1bGVQYXRoID0gcGFydHNbMV07XG4gIGNvbnN0IGZuTmFtZSA9IHBhcnRzWzJdO1xuICBjb25zdCBtb2R1bGVQYXRoQWxpYXNlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gIGNvbnN0IGFkZEFsaWFzID0gKGFsaWFzTW9kdWxlUGF0aDogc3RyaW5nKSA9PiB7XG4gICAgaWYgKGFsaWFzTW9kdWxlUGF0aCAhPT0gbW9kdWxlUGF0aCkge1xuICAgICAgbW9kdWxlUGF0aEFsaWFzZXMuYWRkKGFsaWFzTW9kdWxlUGF0aCk7XG4gICAgfVxuICB9O1xuXG4gIGlmIChtb2R1bGVQYXRoLnN0YXJ0c1dpdGgoJy4vd29ya2Zsb3dzLycpKSB7XG4gICAgY29uc3Qgd29ya2Zsb3dSZWxhdGl2ZVBhdGggPSBtb2R1bGVQYXRoLnNsaWNlKCcuLycubGVuZ3RoKTtcbiAgICBhZGRBbGlhcyhgLi9leGFtcGxlLyR7d29ya2Zsb3dSZWxhdGl2ZVBhdGh9YCk7XG4gICAgYWRkQWxpYXMoYC4vc3JjLyR7d29ya2Zsb3dSZWxhdGl2ZVBhdGh9YCk7XG4gIH0gZWxzZSBpZiAobW9kdWxlUGF0aC5zdGFydHNXaXRoKCcuL2V4YW1wbGUvd29ya2Zsb3dzLycpKSB7XG4gICAgY29uc3Qgd29ya2Zsb3dSZWxhdGl2ZVBhdGggPSBtb2R1bGVQYXRoLnNsaWNlKCcuL2V4YW1wbGUvJy5sZW5ndGgpO1xuICAgIGFkZEFsaWFzKGAuLyR7d29ya2Zsb3dSZWxhdGl2ZVBhdGh9YCk7XG4gICAgYWRkQWxpYXMoYC4vc3JjLyR7d29ya2Zsb3dSZWxhdGl2ZVBhdGh9YCk7XG4gIH0gZWxzZSBpZiAobW9kdWxlUGF0aC5zdGFydHNXaXRoKCcuL3NyYy93b3JrZmxvd3MvJykpIHtcbiAgICBjb25zdCB3b3JrZmxvd1JlbGF0aXZlUGF0aCA9IG1vZHVsZVBhdGguc2xpY2UoJy4vc3JjLycubGVuZ3RoKTtcbiAgICBhZGRBbGlhcyhgLi8ke3dvcmtmbG93UmVsYXRpdmVQYXRofWApO1xuICAgIGFkZEFsaWFzKGAuL2V4YW1wbGUvJHt3b3JrZmxvd1JlbGF0aXZlUGF0aH1gKTtcbiAgfVxuXG4gIHJldHVybiBBcnJheS5mcm9tKFxuICAgIG1vZHVsZVBhdGhBbGlhc2VzLFxuICAgIChhbGlhc01vZHVsZVBhdGgpID0+IGBzdGVwLy8ke2FsaWFzTW9kdWxlUGF0aH0vLyR7Zm5OYW1lfWBcbiAgKTtcbn1cblxuZnVuY3Rpb24gZ2V0QnVpbHRpblJlc3BvbnNlU3RlcEFsaWFzKHN0ZXBJZDogc3RyaW5nKTogU3RlcEZ1bmN0aW9uIHwgdW5kZWZpbmVkIHtcbiAgaWYgKCFCVUlMVElOX1NURVBfTkFNRVMuaGFzKHN0ZXBJZCkpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgZm9yIChjb25zdCBbcmVnaXN0ZXJlZFN0ZXBJZCwgc3RlcEZuXSBvZiByZWdpc3RlcmVkU3RlcHMuZW50cmllcygpKSB7XG4gICAgaWYgKHJlZ2lzdGVyZWRTdGVwSWQuZW5kc1dpdGgoYC8vJHtzdGVwSWR9YCkpIHtcbiAgICAgIHJldHVybiBzdGVwRm47XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZWdpc3RlciBhIHN0ZXAgZnVuY3Rpb24gdG8gYmUgc2VydmVkIGluIHRoZSBzZXJ2ZXIgYnVuZGxlLlxuICogQWxzbyBzZXRzIHRoZSBzdGVwSWQgcHJvcGVydHkgb24gdGhlIGZ1bmN0aW9uIGZvciBzZXJpYWxpemF0aW9uIHN1cHBvcnQuXG4gKlxuICogTm90ZTogVGhlIFNXQyBjb21waWxlciBwbHVnaW4gbm8gbG9uZ2VyIGdlbmVyYXRlcyBjYWxscyB0byB0aGlzIGZ1bmN0aW9uLlxuICogU3RlcCByZWdpc3RyYXRpb24gaXMgbm93IGlubGluZWQgYXMgYSBzZWxmLWNvbnRhaW5lZCBJSUZFIHRoYXQgd3JpdGVzXG4gKiBkaXJlY3RseSB0byB0aGUgZ2xvYmFsIE1hcCBhdCBTeW1ib2wuZm9yKFwiQHdvcmtmbG93L2NvcmUvL3JlZ2lzdGVyZWRTdGVwc1wiKS5cbiAqIFRoaXMgZnVuY3Rpb24gaXMga2VwdCBmb3IgaW50ZXJuYWwvdGVzdCB1c2Ugb25seS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyU3RlcEZ1bmN0aW9uKHN0ZXBJZDogc3RyaW5nLCBzdGVwRm46IFN0ZXBGdW5jdGlvbikge1xuICByZWdpc3RlcmVkU3RlcHMuc2V0KHN0ZXBJZCwgc3RlcEZuKTtcbiAgc3RlcEZuLnN0ZXBJZCA9IHN0ZXBJZDtcbn1cblxuLyoqXG4gKiBGaW5kIGEgcmVnaXN0ZXJlZCBzdGVwIGZ1bmN0aW9uIGJ5IG5hbWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFN0ZXBGdW5jdGlvbihzdGVwSWQ6IHN0cmluZyk6IFN0ZXBGdW5jdGlvbiB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGRpcmVjdE1hdGNoID0gcmVnaXN0ZXJlZFN0ZXBzLmdldChzdGVwSWQpO1xuICBpZiAoZGlyZWN0TWF0Y2gpIHtcbiAgICByZXR1cm4gZGlyZWN0TWF0Y2g7XG4gIH1cblxuICAvLyBTdXBwb3J0IGVxdWl2YWxlbnQgd29ya2Zsb3cgcGF0aCBhbGlhc2VzIGluIG1peGVkIHN5bWxpbmsgZW52aXJvbm1lbnRzLlxuICBmb3IgKGNvbnN0IGFsaWFzU3RlcElkIG9mIGdldFN0ZXBJZEFsaWFzQ2FuZGlkYXRlcyhzdGVwSWQpKSB7XG4gICAgY29uc3QgYWxpYXNNYXRjaCA9IHJlZ2lzdGVyZWRTdGVwcy5nZXQoYWxpYXNTdGVwSWQpO1xuICAgIGlmIChhbGlhc01hdGNoKSB7XG4gICAgICByZXR1cm4gYWxpYXNNYXRjaDtcbiAgICB9XG4gIH1cblxuICBjb25zdCBidWlsdGluQWxpYXNNYXRjaCA9IGdldEJ1aWx0aW5SZXNwb25zZVN0ZXBBbGlhcyhzdGVwSWQpO1xuICBpZiAoYnVpbHRpbkFsaWFzTWF0Y2gpIHtcbiAgICByZXR1cm4gYnVpbHRpbkFsaWFzTWF0Y2g7XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vLyBOb3RlOiBfX3ByaXZhdGVfZ2V0Q2xvc3VyZVZhcnMgaXMgbm8gbG9uZ2VyIHJlLWV4cG9ydGVkIGhlcmUuXG4vLyBUaGUgU1dDIGNvbXBpbGVyIHBsdWdpbiBub3cgaW5saW5lcyBjbG9zdXJlIHZhcmlhYmxlIGFjY2VzcyBhcyBhXG4vLyBzZWxmLWNvbnRhaW5lZCBJSUZFIHRoYXQgcmVhZHMgZGlyZWN0bHkgZnJvbSB0aGUgZ2xvYmFsIEFzeW5jTG9jYWxTdG9yYWdlXG4vLyBhdCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9DT05URVhUX1NUT1JBR0VcIikuXG5cbmV4cG9ydCBpbnRlcmZhY2UgV29ya2Zsb3dPcmNoZXN0cmF0b3JDb250ZXh0IHtcbiAgcnVuSWQ6IHN0cmluZztcbiAgZW5jcnlwdGlvbktleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkO1xuICBnbG9iYWxUaGlzOiB0eXBlb2YgZ2xvYmFsVGhpcztcbiAgZXZlbnRzQ29uc3VtZXI6IEV2ZW50c0NvbnN1bWVyO1xuICAvKipcbiAgICogTWFwIG9mIHBlbmRpbmcgaW52b2NhdGlvbnMga2V5ZWQgYnkgY29ycmVsYXRpb25JZC5cbiAgICogVXNpbmcgTWFwIGluc3RlYWQgb2YgQXJyYXkgZm9yIE8oMSkgbG9va3VwL2RlbGV0ZSBvcGVyYXRpb25zLlxuICAgKi9cbiAgaW52b2NhdGlvbnNRdWV1ZTogTWFwPHN0cmluZywgUXVldWVJdGVtPjtcbiAgb25Xb3JrZmxvd0Vycm9yOiAoZXJyb3I6IEVycm9yKSA9PiB2b2lkO1xuICBnZW5lcmF0ZVVsaWQ6ICgpID0+IHN0cmluZztcbiAgZ2VuZXJhdGVOYW5vaWQ6ICgpID0+IHN0cmluZztcbiAgLyoqXG4gICAqIFNlcXVlbnRpYWwgcHJvbWlzZSBxdWV1ZSB0aGF0IGVuc3VyZXMgYWxsIGV2ZW50LWRyaXZlbiBwcm9taXNlIHJlc29sdXRpb25zXG4gICAqIChzdGVwIHJlc3VsdHMsIGhvb2sgcGF5bG9hZHMsIGZhaWx1cmVzLCBzdXNwZW5zaW9ucykgaGFwcGVuIGluIGV2ZW50IGxvZ1xuICAgKiBvcmRlci4gRXZlcnkgcmVzb2x2ZSwgcmVqZWN0LCBvciB3b3JrZmxvdyBlcnJvciBpcyBjaGFpbmVkIHRocm91Z2ggdGhpc1xuICAgKiBxdWV1ZSBzbyB0aGF0IGV2ZW4gaWYgaW5kaXZpZHVhbCBvcGVyYXRpb25zIHRha2UgdmFyaWFibGUgdGltZSAoZS5nLixcbiAgICogYXN5bmMgZGVjcnlwdGlvbiksIHByb21pc2VzIHJlc29sdmUgZGV0ZXJtaW5pc3RpY2FsbHkuXG4gICAqL1xuICBwcm9taXNlUXVldWU6IFByb21pc2U8dm9pZD47XG4gIC8qKlxuICAgKiBDb3VudGVyIG9mIGluLWZsaWdodCBhc3luYyBkYXRhIGRlbGl2ZXJ5IG9wZXJhdGlvbnMgKHN0ZXAgcmVzdWx0XG4gICAqIGh5ZHJhdGlvbiwgaG9vayBwYXlsb2FkIGh5ZHJhdGlvbikuIFN1c3BlbnNpb25zIG11c3Qgd2FpdCBmb3IgdGhpc1xuICAgKiB0byByZWFjaCAwIGJlZm9yZSBmaXJpbmcsIHRvIGF2b2lkIHByZWVtcHRpbmcgZGF0YSBkZWxpdmVyeS5cbiAgICovXG4gIHBlbmRpbmdEZWxpdmVyaWVzOiBudW1iZXI7XG59XG5cbi8qKlxuICogU2NoZWR1bGUgYSBjYWxsYmFjayB0byBmaXJlIG9ubHkgYWZ0ZXIgYWxsIHBlbmRpbmcgZGF0YSBkZWxpdmVyaWVzXG4gKiAoc3RlcCByZXN1bHRzLCBob29rIHBheWxvYWRzKSBhbmQgYXN5bmMgZGVzZXJpYWxpemF0aW9uIGhhdmUgY29tcGxldGVkLlxuICogVXNlcyBhIHBvbGxpbmcgbG9vcDogc2V0VGltZW91dCgwKSDihpIgY2hlY2sgcGVuZGluZ0RlbGl2ZXJpZXMg4oaSXG4gKiBpZiA+IDAsIHdhaXQgZm9yIHByb21pc2VRdWV1ZSDihpIgcmVwZWF0LiBUaGlzIGhhbmRsZXMgdGhlIG11bHRpLXJvdW5kXG4gKiBkZWxpdmVyeSBwYXR0ZXJuIHdoZXJlIGVhY2ggaG9vayBwYXlsb2FkIGRlbGl2ZXJ5IGN5Y2xlIGFwcGVuZHMgbmV3XG4gKiBhc3luYyB3b3JrIHRvIHRoZSBwcm9taXNlUXVldWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzY2hlZHVsZVdoZW5JZGxlKFxuICBjdHg6IFdvcmtmbG93T3JjaGVzdHJhdG9yQ29udGV4dCxcbiAgZm46ICgpID0+IHZvaWRcbik6IHZvaWQge1xuICBjb25zdCBjaGVjayA9ICgpID0+IHtcbiAgICBpZiAoY3R4LnBlbmRpbmdEZWxpdmVyaWVzID4gMCkge1xuICAgICAgLy8gU3RpbGwgZGVsaXZlcmluZyBkYXRhIOKAlCB3YWl0IGZvciBxdWV1ZSB0byBkcmFpbiwgdGhlbiByZS1jaGVja1xuICAgICAgY3R4LnByb21pc2VRdWV1ZS50aGVuKCgpID0+IHtcbiAgICAgICAgc2V0VGltZW91dChjaGVjaywgMCk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm4oKTtcbiAgICB9XG4gIH07XG4gIHNldFRpbWVvdXQoY2hlY2ssIDApO1xufVxuIl19
446
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpdmF0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9wcml2YXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBZ0JoRCxNQUFNLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsaUNBQWlDLENBQUMsQ0FBQztBQUV6RSxNQUFNLGFBQWEsR0FFZixVQUFVLENBQUM7QUFFZix3REFBd0Q7QUFDeEQsTUFBTSxlQUFlLEdBQUcsQ0FBQyxhQUFhLENBQUMsa0JBQWtCLENBQUMsS0FBSyxJQUFJLEdBQUcsRUFHbkUsQ0FBQyxDQUFDO0FBRUwsTUFBTSwyQkFBMkIsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUMxQyxpQ0FBaUM7SUFDakMseUJBQXlCO0lBQ3pCLHlCQUF5QjtDQUMxQixDQUFDLENBQUM7QUFFSCxTQUFTLHdCQUF3QixDQUFDLE1BQWM7SUFDOUMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNqQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxNQUFNLEVBQUUsQ0FBQztRQUM5QyxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFRCxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDNUIsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hCLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztJQUU1QyxNQUFNLFFBQVEsR0FBRyxDQUFDLGVBQXVCLEVBQUUsRUFBRTtRQUMzQyxJQUFJLGVBQWUsS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUNuQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDekMsQ0FBQztJQUNILENBQUMsQ0FBQztJQUVGLElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO1FBQzFDLE1BQU0sb0JBQW9CLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDM0QsUUFBUSxDQUFDLGFBQWEsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO1FBQzlDLFFBQVEsQ0FBQyxTQUFTLG9CQUFvQixFQUFFLENBQUMsQ0FBQztJQUM1QyxDQUFDO1NBQU0sSUFBSSxVQUFVLENBQUMsVUFBVSxDQUFDLHNCQUFzQixDQUFDLEVBQUUsQ0FBQztRQUN6RCxNQUFNLG9CQUFvQixHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ25FLFFBQVEsQ0FBQyxLQUFLLG9CQUFvQixFQUFFLENBQUMsQ0FBQztRQUN0QyxRQUFRLENBQUMsU0FBUyxvQkFBb0IsRUFBRSxDQUFDLENBQUM7SUFDNUMsQ0FBQztTQUFNLElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUM7UUFDckQsTUFBTSxvQkFBb0IsR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvRCxRQUFRLENBQUMsS0FBSyxvQkFBb0IsRUFBRSxDQUFDLENBQUM7UUFDdEMsUUFBUSxDQUFDLGFBQWEsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQ2YsaUJBQWlCLEVBQ2pCLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxTQUFTLGVBQWUsS0FBSyxNQUFNLEVBQUUsQ0FDM0QsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLDJCQUEyQixDQUFDLE1BQWM7SUFDakQsSUFBSSxDQUFDLDJCQUEyQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQzdDLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFRCxLQUFLLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxNQUFNLENBQUMsSUFBSSxlQUFlLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztRQUNuRSxJQUFJLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxLQUFLLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUM3QyxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxNQUFjLEVBQUUsTUFBb0I7SUFDdkUsZUFBZSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDcEMsTUFBTSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7QUFDekIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FBQyxNQUFjO0lBQzVDLE1BQU0sV0FBVyxHQUFHLGVBQWUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDaEQsSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUNoQixPQUFPLFdBQVcsQ0FBQztJQUNyQixDQUFDO0lBRUQsMEVBQTBFO0lBQzFFLEtBQUssTUFBTSxXQUFXLElBQUksd0JBQXdCLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUMzRCxNQUFNLFVBQVUsR0FBRyxlQUFlLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3BELElBQUksVUFBVSxFQUFFLENBQUM7WUFDZixPQUFPLFVBQVUsQ0FBQztRQUNwQixDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0saUJBQWlCLEdBQUcsMkJBQTJCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDOUQsSUFBSSxpQkFBaUIsRUFBRSxDQUFDO1FBQ3RCLE9BQU8saUJBQWlCLENBQUM7SUFDM0IsQ0FBQztJQUVELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFzSEQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMEJHO0FBQ0gsTUFBTSxZQUFZLEdBQWtEO0lBQ2xFLElBQUksRUFBRSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUM7SUFDdEIsSUFBSSxFQUFFLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUN0QixJQUFJLEVBQUUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQztDQUMvQixDQUFDO0FBRUY7Ozs7Ozs7Ozs7R0FVRztBQUNILFNBQVMsT0FBTyxDQUNkLElBQWtCLEVBQ2xCLEtBQWEsRUFDYixVQUFrQixFQUNsQixLQUEyQjtJQUUzQixJQUFJLFVBQVUsSUFBSSxLQUFLLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ3BFLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELG9FQUFvRTtJQUNwRSwwRUFBMEU7SUFDMUUsMkVBQTJFO0lBQzNFLHlEQUF5RDtJQUN6RCxPQUFPLENBQUMsQ0FBQyxJQUFJLEtBQUssTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzVDLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0NHO0FBQ0gsU0FBUyxnQkFBZ0IsQ0FDdkIsUUFBMkMsRUFDM0MsS0FBYSxFQUNiLEtBQTJCLEVBQzNCLElBQTBCO0lBRTFCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0IsSUFBSSxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDekIsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLHVCQUF1QixDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3JFLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3hCLE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRCxTQUFTLHVCQUF1QixDQUM5QixRQUEyQyxFQUMzQyxLQUFhLEVBQ2IsS0FBMkIsRUFDM0IsSUFBMEI7SUFFMUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNqQixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFDRCxLQUFLLE1BQU0sQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLElBQUksUUFBUSxFQUFFLENBQUM7UUFDM0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNuRCxTQUFTO1FBQ1gsQ0FBQztRQUNELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3pELE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbURHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxzQkFBc0IsQ0FDMUMsR0FBZ0MsRUFDaEMsVUFBOEIsRUFDOUIsSUFBa0I7SUFFbEIseUVBQXlFO0lBQ3pFLElBQ0UsVUFBVSxLQUFLLFNBQVM7UUFDeEIsQ0FBQyxHQUFHLENBQUMsdUJBQXVCO1FBQzVCLEdBQUcsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLEtBQUssQ0FBQyxFQUN0QyxDQUFDO1FBQ0QsT0FBTztJQUNULENBQUM7SUFDRCxNQUFNLFFBQVEsR0FBRyxHQUFHLENBQUMsdUJBQXVCLENBQUM7SUFDN0MsTUFBTSxPQUFPLEdBQW9CLEVBQUUsQ0FBQztJQUNwQyxLQUFLLE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLElBQUksUUFBUSxFQUFFLENBQUM7UUFDdEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzdDLFNBQVM7UUFDWCxDQUFDO1FBQ0QsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUNELElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN2QixNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDM0Isd0VBQXdFO1FBQ3hFLHVFQUF1RTtRQUN2RSxzRUFBc0U7UUFDdEUsd0VBQXdFO1FBQ3hFLHlFQUF5RTtRQUN6RSxxRUFBcUU7UUFDckUseUVBQXlFO1FBQ3pFLDZEQUE2RDtRQUM3RCxFQUFFO1FBQ0Ysd0VBQXdFO1FBQ3hFLHdFQUF3RTtRQUN4RSx1RUFBdUU7UUFDdkUseUVBQXlFO1FBQ3pFLGNBQWM7UUFDZCxNQUFNLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDL0QsQ0FBQztBQUNILENBQUM7QUFtQkQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILE1BQU0sVUFBVSx1QkFBdUIsQ0FDckMsR0FBZ0MsRUFDaEMsVUFBOEIsRUFDOUIsSUFBa0IsRUFDbEIsVUFBK0IsRUFBRTtJQUVqQyxNQUFNLFFBQVEsR0FBRyxHQUFHLENBQUMsdUJBQXVCLENBQUM7SUFDN0MsSUFBSSxDQUFDLFFBQVEsSUFBSSxVQUFVLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDMUMsT0FBTyxFQUFFLGFBQWEsRUFBRSxHQUFHLEVBQUUsR0FBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFFLENBQUMsRUFBRSxDQUFDO0lBQ3BELENBQUM7SUFFRCxJQUFJLElBQUksR0FBRyxLQUFLLENBQUM7SUFDakIsTUFBTSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsR0FBRyxhQUFhLEVBQVEsQ0FBQztJQUNuRCxNQUFNLEtBQUssR0FBeUI7UUFDbEMsSUFBSTtRQUNKLFNBQVMsRUFBRSxPQUFPO1FBQ2xCLEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSyxJQUFJLElBQUk7S0FDN0IsQ0FBQztJQUNGLFFBQVEsQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBRWhDLE1BQU0sTUFBTSxHQUFHLEdBQUcsRUFBRTtRQUNsQixJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1QsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ1osSUFBSSxRQUFRLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEtBQUssRUFBRSxDQUFDO1lBQ3ZDLFFBQVEsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDOUIsQ0FBQztRQUNELE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQyxDQUFDO0lBRUYsdUVBQXVFO0lBQ3ZFLDJFQUEyRTtJQUMzRSw0RUFBNEU7SUFDNUUsMEVBQTBFO0lBQzFFLHdEQUF3RDtJQUN4RCxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFFOUIsT0FBTztRQUNMLGFBQWEsRUFBRSxNQUFNO1FBQ3JCLEdBQUcsRUFBRSxHQUFHLEVBQUU7WUFDUixLQUFLLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztRQUNyQixDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBOEJHO0FBQ0gsTUFBTSxVQUFVLDBCQUEwQixDQUN4QyxHQUFnQztJQUVoQyxNQUFNLFFBQVEsR0FBRyxHQUFHLENBQUMsdUJBQXVCLENBQUM7SUFDN0MsSUFBSSxDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsSUFBSSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3JDLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELHlEQUF5RDtJQUN6RCxNQUFNLGFBQWEsR0FBRyxJQUFJLEdBQUcsRUFBbUIsQ0FBQztJQUNqRCxLQUFLLE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLElBQUksUUFBUSxFQUFFLENBQUM7UUFDdEMsSUFBSSxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxhQUFhLENBQUMsRUFBRSxDQUFDO1lBQzVELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsR0FBZ0M7SUFDN0QsT0FBTyxHQUFHLENBQUMsaUJBQWlCLEtBQUssQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDekUsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FDOUIsR0FBZ0MsRUFDaEMsRUFBYztJQUVkLE1BQU0sS0FBSyxHQUFHLEdBQUcsRUFBRTtRQUNqQixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDekIsdUVBQXVFO1lBQ3ZFLHFFQUFxRTtZQUNyRSxxRUFBcUU7WUFDckUsR0FBRyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFO2dCQUN6QixVQUFVLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3ZCLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQzthQUFNLENBQUM7WUFDTixFQUFFLEVBQUUsQ0FBQztRQUNQLENBQUM7SUFDSCxDQUFDLENBQUM7SUFDRixVQUFVLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFV0aWxzIHVzZWQgYnkgdGhlIGJ1bmRsZXIgd2hlbiB0cmFuc2Zvcm1pbmcgY29kZVxuICovXG5cbmltcG9ydCB7IHdpdGhSZXNvbHZlcnMgfSBmcm9tICdAd29ya2Zsb3cvdXRpbHMnO1xuaW1wb3J0IHR5cGUgeyBXb3JsZENhcGFiaWxpdGllcyB9IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgdHlwZSB7IEV2ZW50c0NvbnN1bWVyIH0gZnJvbSAnLi9ldmVudHMtY29uc3VtZXIuanMnO1xuaW1wb3J0IHR5cGUgeyBRdWV1ZUl0ZW0gfSBmcm9tICcuL2dsb2JhbC5qcyc7XG5pbXBvcnQgdHlwZSB7IFJlcGxheVBheWxvYWRDYWNoZSB9IGZyb20gJy4vcmVwbGF5LXBheWxvYWQtY2FjaGUuanMnO1xuaW1wb3J0IHR5cGUgeyBTZXJpYWxpemFibGUgfSBmcm9tICcuL3NjaGVtYXMuanMnO1xuaW1wb3J0IHR5cGUgeyBQYXlsb2FkS2V5IH0gZnJvbSAnLi9zZXJpYWxpemF0aW9uL2VuY3J5cHRpb24uanMnO1xuXG5leHBvcnQgdHlwZSBTdGVwRnVuY3Rpb248XG4gIEFyZ3MgZXh0ZW5kcyBTZXJpYWxpemFibGVbXSA9IGFueVtdLFxuICBSZXN1bHQgZXh0ZW5kcyBTZXJpYWxpemFibGUgfCB1bmtub3duID0gdW5rbm93bixcbj4gPSAoKC4uLmFyZ3M6IEFyZ3MpID0+IFByb21pc2U8UmVzdWx0PikgJiB7XG4gIG1heFJldHJpZXM/OiBudW1iZXI7XG4gIHN0ZXBJZD86IHN0cmluZztcbn07XG5cbmNvbnN0IFJlZ2lzdGVyZWRTdGVwc0tleSA9IFN5bWJvbC5mb3IoJ0B3b3JrZmxvdy9jb3JlLy9yZWdpc3RlcmVkU3RlcHMnKTtcblxuY29uc3QgZ2xvYmFsU3ltYm9sczogdHlwZW9mIGdsb2JhbFRoaXMgJiB7XG4gIFtSZWdpc3RlcmVkU3RlcHNLZXldPzogTWFwPHN0cmluZywgU3RlcEZ1bmN0aW9uPjtcbn0gPSBnbG9iYWxUaGlzO1xuXG4vLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vQXNzaWduSW5FeHByZXNzaW9uczogL1xuY29uc3QgcmVnaXN0ZXJlZFN0ZXBzID0gKGdsb2JhbFN5bWJvbHNbUmVnaXN0ZXJlZFN0ZXBzS2V5XSA/Pz0gbmV3IE1hcDxcbiAgc3RyaW5nLFxuICBTdGVwRnVuY3Rpb25cbj4oKSk7XG5cbmNvbnN0IEJVSUxUSU5fUkVTUE9OU0VfU1RFUF9OQU1FUyA9IG5ldyBTZXQoW1xuICAnX19idWlsdGluX3Jlc3BvbnNlX2FycmF5X2J1ZmZlcicsXG4gICdfX2J1aWx0aW5fcmVzcG9uc2VfanNvbicsXG4gICdfX2J1aWx0aW5fcmVzcG9uc2VfdGV4dCcsXG5dKTtcblxuZnVuY3Rpb24gZ2V0U3RlcElkQWxpYXNDYW5kaWRhdGVzKHN0ZXBJZDogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCBwYXJ0cyA9IHN0ZXBJZC5zcGxpdCgnLy8nKTtcbiAgaWYgKHBhcnRzLmxlbmd0aCAhPT0gMyB8fCBwYXJ0c1swXSAhPT0gJ3N0ZXAnKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgY29uc3QgbW9kdWxlUGF0aCA9IHBhcnRzWzFdO1xuICBjb25zdCBmbk5hbWUgPSBwYXJ0c1syXTtcbiAgY29uc3QgbW9kdWxlUGF0aEFsaWFzZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICBjb25zdCBhZGRBbGlhcyA9IChhbGlhc01vZHVsZVBhdGg6IHN0cmluZykgPT4ge1xuICAgIGlmIChhbGlhc01vZHVsZVBhdGggIT09IG1vZHVsZVBhdGgpIHtcbiAgICAgIG1vZHVsZVBhdGhBbGlhc2VzLmFkZChhbGlhc01vZHVsZVBhdGgpO1xuICAgIH1cbiAgfTtcblxuICBpZiAobW9kdWxlUGF0aC5zdGFydHNXaXRoKCcuL3dvcmtmbG93cy8nKSkge1xuICAgIGNvbnN0IHdvcmtmbG93UmVsYXRpdmVQYXRoID0gbW9kdWxlUGF0aC5zbGljZSgnLi8nLmxlbmd0aCk7XG4gICAgYWRkQWxpYXMoYC4vZXhhbXBsZS8ke3dvcmtmbG93UmVsYXRpdmVQYXRofWApO1xuICAgIGFkZEFsaWFzKGAuL3NyYy8ke3dvcmtmbG93UmVsYXRpdmVQYXRofWApO1xuICB9IGVsc2UgaWYgKG1vZHVsZVBhdGguc3RhcnRzV2l0aCgnLi9leGFtcGxlL3dvcmtmbG93cy8nKSkge1xuICAgIGNvbnN0IHdvcmtmbG93UmVsYXRpdmVQYXRoID0gbW9kdWxlUGF0aC5zbGljZSgnLi9leGFtcGxlLycubGVuZ3RoKTtcbiAgICBhZGRBbGlhcyhgLi8ke3dvcmtmbG93UmVsYXRpdmVQYXRofWApO1xuICAgIGFkZEFsaWFzKGAuL3NyYy8ke3dvcmtmbG93UmVsYXRpdmVQYXRofWApO1xuICB9IGVsc2UgaWYgKG1vZHVsZVBhdGguc3RhcnRzV2l0aCgnLi9zcmMvd29ya2Zsb3dzLycpKSB7XG4gICAgY29uc3Qgd29ya2Zsb3dSZWxhdGl2ZVBhdGggPSBtb2R1bGVQYXRoLnNsaWNlKCcuL3NyYy8nLmxlbmd0aCk7XG4gICAgYWRkQWxpYXMoYC4vJHt3b3JrZmxvd1JlbGF0aXZlUGF0aH1gKTtcbiAgICBhZGRBbGlhcyhgLi9leGFtcGxlLyR7d29ya2Zsb3dSZWxhdGl2ZVBhdGh9YCk7XG4gIH1cblxuICByZXR1cm4gQXJyYXkuZnJvbShcbiAgICBtb2R1bGVQYXRoQWxpYXNlcyxcbiAgICAoYWxpYXNNb2R1bGVQYXRoKSA9PiBgc3RlcC8vJHthbGlhc01vZHVsZVBhdGh9Ly8ke2ZuTmFtZX1gXG4gICk7XG59XG5cbmZ1bmN0aW9uIGdldEJ1aWx0aW5SZXNwb25zZVN0ZXBBbGlhcyhzdGVwSWQ6IHN0cmluZyk6IFN0ZXBGdW5jdGlvbiB8IHVuZGVmaW5lZCB7XG4gIGlmICghQlVJTFRJTl9SRVNQT05TRV9TVEVQX05BTUVTLmhhcyhzdGVwSWQpKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGZvciAoY29uc3QgW3JlZ2lzdGVyZWRTdGVwSWQsIHN0ZXBGbl0gb2YgcmVnaXN0ZXJlZFN0ZXBzLmVudHJpZXMoKSkge1xuICAgIGlmIChyZWdpc3RlcmVkU3RlcElkLmVuZHNXaXRoKGAvLyR7c3RlcElkfWApKSB7XG4gICAgICByZXR1cm4gc3RlcEZuO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmVnaXN0ZXIgYSBzdGVwIGZ1bmN0aW9uIHRvIGJlIHNlcnZlZCBpbiB0aGUgc2VydmVyIGJ1bmRsZS5cbiAqIEFsc28gc2V0cyB0aGUgc3RlcElkIHByb3BlcnR5IG9uIHRoZSBmdW5jdGlvbiBmb3Igc2VyaWFsaXphdGlvbiBzdXBwb3J0LlxuICpcbiAqIE5vdGU6IFRoZSBTV0MgY29tcGlsZXIgcGx1Z2luIG5vIGxvbmdlciBnZW5lcmF0ZXMgY2FsbHMgdG8gdGhpcyBmdW5jdGlvbi5cbiAqIFN0ZXAgcmVnaXN0cmF0aW9uIGlzIG5vdyBpbmxpbmVkIGFzIGEgc2VsZi1jb250YWluZWQgSUlGRSB0aGF0IHdyaXRlc1xuICogZGlyZWN0bHkgdG8gdGhlIGdsb2JhbCBNYXAgYXQgU3ltYm9sLmZvcihcIkB3b3JrZmxvdy9jb3JlLy9yZWdpc3RlcmVkU3RlcHNcIikuXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGtlcHQgZm9yIGludGVybmFsL3Rlc3QgdXNlIG9ubHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlclN0ZXBGdW5jdGlvbihzdGVwSWQ6IHN0cmluZywgc3RlcEZuOiBTdGVwRnVuY3Rpb24pIHtcbiAgcmVnaXN0ZXJlZFN0ZXBzLnNldChzdGVwSWQsIHN0ZXBGbik7XG4gIHN0ZXBGbi5zdGVwSWQgPSBzdGVwSWQ7XG59XG5cbi8qKlxuICogRmluZCBhIHJlZ2lzdGVyZWQgc3RlcCBmdW5jdGlvbiBieSBuYW1lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTdGVwRnVuY3Rpb24oc3RlcElkOiBzdHJpbmcpOiBTdGVwRnVuY3Rpb24gfCB1bmRlZmluZWQge1xuICBjb25zdCBkaXJlY3RNYXRjaCA9IHJlZ2lzdGVyZWRTdGVwcy5nZXQoc3RlcElkKTtcbiAgaWYgKGRpcmVjdE1hdGNoKSB7XG4gICAgcmV0dXJuIGRpcmVjdE1hdGNoO1xuICB9XG5cbiAgLy8gU3VwcG9ydCBlcXVpdmFsZW50IHdvcmtmbG93IHBhdGggYWxpYXNlcyBpbiBtaXhlZCBzeW1saW5rIGVudmlyb25tZW50cy5cbiAgZm9yIChjb25zdCBhbGlhc1N0ZXBJZCBvZiBnZXRTdGVwSWRBbGlhc0NhbmRpZGF0ZXMoc3RlcElkKSkge1xuICAgIGNvbnN0IGFsaWFzTWF0Y2ggPSByZWdpc3RlcmVkU3RlcHMuZ2V0KGFsaWFzU3RlcElkKTtcbiAgICBpZiAoYWxpYXNNYXRjaCkge1xuICAgICAgcmV0dXJuIGFsaWFzTWF0Y2g7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgYnVpbHRpbkFsaWFzTWF0Y2ggPSBnZXRCdWlsdGluUmVzcG9uc2VTdGVwQWxpYXMoc3RlcElkKTtcbiAgaWYgKGJ1aWx0aW5BbGlhc01hdGNoKSB7XG4gICAgcmV0dXJuIGJ1aWx0aW5BbGlhc01hdGNoO1xuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLy8gTm90ZTogX19wcml2YXRlX2dldENsb3N1cmVWYXJzIGlzIG5vIGxvbmdlciByZS1leHBvcnRlZCBoZXJlLlxuLy8gVGhlIFNXQyBjb21waWxlciBwbHVnaW4gbm93IGlubGluZXMgY2xvc3VyZSB2YXJpYWJsZSBhY2Nlc3MgYXMgYVxuLy8gc2VsZi1jb250YWluZWQgSUlGRSB0aGF0IHJlYWRzIGRpcmVjdGx5IGZyb20gdGhlIGdsb2JhbCBBc3luY0xvY2FsU3RvcmFnZVxuLy8gYXQgU3ltYm9sLmZvcihcIldPUktGTE9XX1NURVBfQ09OVEVYVF9TVE9SQUdFXCIpLlxuXG5leHBvcnQgaW50ZXJmYWNlIFdvcmtmbG93T3JjaGVzdHJhdG9yQ29udGV4dCB7XG4gIHJ1bklkOiBzdHJpbmc7XG4gIGVuY3J5cHRpb25LZXk6IFBheWxvYWRLZXkgfCB1bmRlZmluZWQ7XG4gIHdvcmxkQ2FwYWJpbGl0aWVzPzogV29ybGRDYXBhYmlsaXRpZXM7XG4gIGdsb2JhbFRoaXM6IHR5cGVvZiBnbG9iYWxUaGlzO1xuICAvKipcbiAgICogSW5jcmVtZW50cyB3aGVuIGEgc3VzcGVuc2lvbiBpcyBhY2NlcHRlZCBhbmQgb24gZXZlcnkgcmV0YWluZWQtc2Vzc2lvblxuICAgKiByZXN1bWUuIFNURVAgc3VzcGVuc2lvbiBzaWduYWxzIGNhcHR1cmUgaXQgd2hlbiBzY2hlZHVsZWQgYW5kIG5vLW9wIGlmXG4gICAqIGl0IG1vdmVkIChzZWUgc3RlcC50cykg4oCUIHRoaXMgZHJvcHMgc2FtZS1ib3VuZGFyeSBzaWJsaW5nIHNpZ25hbHMgYW5kXG4gICAqIHRpbWVycyBxdWV1ZWQgYXQgYm91bmRhcnkgTiB0aGF0IHdvdWxkIGZpcmUgYWZ0ZXIgdGhlIHNlc3Npb24gcmVzdW1lZFxuICAgKiBpbnRvIGJvdW5kYXJ5IE4rMS4gU2xlZXAvaG9vay9hdHRyaWJ1dGUgc2lnbmFscyBhcmUgaW50ZW50aW9uYWxseVxuICAgKiB1bmd1YXJkZWQ6IHRoZWlyIHByZXNlbmNlIG1ha2VzIHRoZSBib3VuZGFyeSB1bnJldGFpbmFibGUsIHNvIGEgbGF0ZVxuICAgKiBzaWduYWwgY29ycmVjdGx5IGRlbW90ZXMgdGhlIHNlc3Npb24gKHdvcmtmbG93LnRzIGBvbldvcmtmbG93RXJyb3JgKS5cbiAgICovXG4gIHN1c3BlbnNpb25HZW5lcmF0aW9uOiBudW1iZXI7XG4gIGV2ZW50c0NvbnN1bWVyOiBFdmVudHNDb25zdW1lcjtcbiAgLyoqXG4gICAqIE1hcCBvZiBwZW5kaW5nIGludm9jYXRpb25zIGtleWVkIGJ5IGNvcnJlbGF0aW9uSWQuXG4gICAqIFVzaW5nIE1hcCBpbnN0ZWFkIG9mIEFycmF5IGZvciBPKDEpIGxvb2t1cC9kZWxldGUgb3BlcmF0aW9ucy5cbiAgICovXG4gIGludm9jYXRpb25zUXVldWU6IE1hcDxzdHJpbmcsIFF1ZXVlSXRlbT47XG4gIG9uV29ya2Zsb3dFcnJvcjogKGVycm9yOiBFcnJvcikgPT4gdm9pZDtcbiAgLyoqXG4gICAqIE1pbnRzIHRoZSBVTElEIGJvZHkgb2YgYSBjb3JyZWxhdGlvbiBpZC4gRXZlcnkgZW50aXR5IGEgcmVwbGF5IGNyZWF0ZXNcbiAgICogZHJhd3MgZnJvbSB0aGlzIG9uZSBtb25vdG9uaWMgc2VxdWVuY2UsIHNvIGFuIGlkIGlzIGFuIG9yZGluYWwgb3ZlciB0aGVcbiAgICogd2hvbGUgcnVuIGFuZCBib3RoIHJlcGxheXMgb2YgYSBydW4gbXVzdCBkcmF3IGluIHRoZSBzYW1lIG9yZGVyLlxuICAgKi9cbiAgZ2VuZXJhdGVVbGlkOiAoKSA9PiBzdHJpbmc7XG4gIGdlbmVyYXRlTmFub2lkOiAoKSA9PiBzdHJpbmc7XG4gIC8qKlxuICAgKiBTZXF1ZW50aWFsIHByb21pc2UgcXVldWUgdGhhdCBlbnN1cmVzIGFsbCBldmVudC1kcml2ZW4gcHJvbWlzZSByZXNvbHV0aW9uc1xuICAgKiAoc3RlcCByZXN1bHRzLCBob29rIHBheWxvYWRzLCBmYWlsdXJlcywgc3VzcGVuc2lvbnMpIGhhcHBlbiBpbiBldmVudCBsb2dcbiAgICogb3JkZXIuIEV2ZXJ5IHJlc29sdmUsIHJlamVjdCwgb3Igd29ya2Zsb3cgZXJyb3IgaXMgY2hhaW5lZCB0aHJvdWdoIHRoaXNcbiAgICogcXVldWUgc28gdGhhdCBldmVuIGlmIGluZGl2aWR1YWwgb3BlcmF0aW9ucyB0YWtlIHZhcmlhYmxlIHRpbWUgKGUuZy4sXG4gICAqIGFzeW5jIGRlY3J5cHRpb24pLCBwcm9taXNlcyByZXNvbHZlIGRldGVybWluaXN0aWNhbGx5LlxuICAgKi9cbiAgcHJvbWlzZVF1ZXVlOiBQcm9taXNlPHZvaWQ+O1xuICAvKipcbiAgICogQ291bnRlciBvZiBpbi1mbGlnaHQgYXN5bmMgZGF0YSBkZWxpdmVyeSBvcGVyYXRpb25zIChzdGVwIHJlc3VsdFxuICAgKiBoeWRyYXRpb24sIGhvb2sgcGF5bG9hZCBoeWRyYXRpb24sIGFib3J0IHNpZ25hbCBoeWRyYXRpb24pLiBTdXNwZW5zaW9uc1xuICAgKiBtdXN0IHdhaXQgZm9yIHRoaXMgdG8gcmVhY2ggMCBiZWZvcmUgZmlyaW5nLCB0byBhdm9pZCBwcmVlbXB0aW5nIGRhdGFcbiAgICogZGVsaXZlcnkg4oCUIGUuZy4gZGVoeWRyYXRpbmcgYSBzdGVwJ3MgYXJndW1lbnRzIHdoaWxlIGFuIGFib3J0IHRoYXQgc2hvdWxkXG4gICAqIGJlIHJlZmxlY3RlZCBpbiB0aG9zZSBhcmd1bWVudHMgaXMgc3RpbGwgaHlkcmF0aW5nIGl0cyByZWFzb24uXG4gICAqL1xuICBwZW5kaW5nRGVsaXZlcmllczogbnVtYmVyO1xuICAvKipcbiAgICogT3JkZXJlZCByZWdpc3RyeSBvZiBpbi1mbGlnaHQgXCJicmFuY2gtZGVjaWRpbmdcIiBkZWxpdmVyaWVzIOKAlCB0aGVcbiAgICogcmVzb2x1dGlvbnMgYSB3b3JrZmxvdyB0eXBpY2FsbHkgYFByb21pc2UucmFjZWBzIG9uLCBvciBhd2FpdHMgZnJvbVxuICAgKiBpbmRlcGVuZGVudCBjb25jdXJyZW50IGJyYW5jaGVzOiBob29rIHBheWxvYWRzIChgaG9va19yZWNlaXZlZGApLCB3YWl0XG4gICAqIGNvbXBsZXRpb25zIChgd2FpdF9jb21wbGV0ZWRgKSwgYW5kIHN0ZXAgcmVzdWx0cyAoYHN0ZXBfY29tcGxldGVkYCAvXG4gICAqIGBzdGVwX2ZhaWxlZGApLiBLZXllZCBieSB0aGUgZGVsaXZlcnkncyBwb3NpdGlvbiAoaW5kZXgpIGluIHRoZSBjb25zdW1lZFxuICAgKiBldmVudCBsb2cuXG4gICAqXG4gICAqIFRoZSBwcm9ibGVtOiBlYWNoIG9mIHRoZXNlIHJlc29sdXRpb25zIHJlYWNoZXMgd29ya2Zsb3cgY29kZSBhZnRlciBhXG4gICAqIGRpZmZlcmVudCwgd29ya2xvYWQtZGVwZW5kZW50IG51bWJlciBvZiBtaWNyb3Rhc2sgaG9wcy4gQSBidWZmZXJlZCBob29rXG4gICAqIHBheWxvYWQgaXMgb2JzZXJ2ZWQgdmlhIHRoZSBhc3luYyBob29rIGl0ZXJhdG9yIChgeWllbGQgYXdhaXQgdGhpc2ApLFxuICAgKiBjb3N0aW5nIGV4dHJhIGhvcHM7IGEgYHdhaXRfY29tcGxldGVkYCByZXNvbHZlcyB3aXRoIGZld2VyLCBhbmQgYSByZXVzZWRcbiAgICogc2xlZXAgY2FuIHJlc29sdmUgaW4gYW4gZW50aXJlbHkgZWFybGllciBsb29wIGl0ZXJhdGlvbjsgYSBzdGVwIHJlc3VsdCBpc1xuICAgKiBnYXRlZCBvbiBoeWRyYXRpb24gd2hvc2UgY29zdCB2YXJpZXMgYmV0d2VlbiByZXBsYXlzIG9mIHRoZSBTQU1FXG4gICAqIGludm9jYXRpb24g4oCUIHRoZSBmaXJzdCByZXBsYXkgcGF5cyB0aGUgZnVsbCBkZWNyeXB0L2RlY29tcHJlc3MvcmV2aXZlLFxuICAgKiB3aGlsZSBsYXRlciByZXBsYXlzIHNoYXJpbmcgdGhlIGludm9jYXRpb24ncyBgUmVwbGF5UGF5bG9hZENhY2hlYFxuICAgKiBtZW1vLWhpdCBzbWFsbCBwcmltaXRpdmUgcmVzdWx0cyBhbmQgcmVzb2x2ZSBpbiBvbmUgb3IgdHdvIGhvcHMuIEVpdGhlclxuICAgKiB3YXksIHRoZSByZXNvbHV0aW9uIHRoYXQgdGhlIGNvbW1pdHRlZCBldmVudCBsb2cgb3JkZXJlZCBmaXJzdCBjYW4gbG9zZSBhXG4gICAqIGBQcm9taXNlLnJhY2VgIChvciBhIGB1c2VTdGVwYCBVTElEIGFsbG9jYXRpb24pIHRvIGEgZmFzdGVyLSBvclxuICAgKiBhbHJlYWR5LXJlc29sdmVkIGNvbXBldGl0b3IsIGRpdmVyZ2luZyBmcm9tIHRoZSBsb2cgYW5kIHN1cmZhY2luZyBhc1xuICAgKiBgQ29ycnVwdGVkRXZlbnRMb2dFcnJvcmAuXG4gICAqXG4gICAqIFRoZSBmaXggaXMgYSBzdHJpY3QsIGRldGVybWluaXN0aWMgZGVsaXZlcnkgb3JkZXIgYW5jaG9yZWQgb25cbiAgICogZXZlbnQtbG9nIHBvc2l0aW9uOiBhIGRlbGl2ZXJ5IGRvZXMgbm90IHJlc29sdmUgdG8gdGhlIHdvcmtmbG93IHVudGlsXG4gICAqIGV2ZXJ5IHJlbGV2YW50IGVhcmxpZXItaW4tbG9nIGRlbGl2ZXJ5IGhhcyBiZWVuIGRlbGl2ZXJlZC4gQmVjYXVzZSB0aGVcbiAgICogZ2F0ZSBpcyBcInRoZSBlYXJsaWVyIGRlbGl2ZXJ5IHJlc29sdmVkXCIsIG5vdCBcIndvbiBhIHRpbWluZyByYWNlXCIsIHRoZVxuICAgKiBvdXRjb21lIGlzIGluZGVwZW5kZW50IG9mIG1pY3JvdGFzayBob3BzLCBoeWRyYXRpb24vZGVjcnlwdGlvbiB0aW1lLFxuICAgKiBhbmQgYFByb21pc2UucmFjZWAgYXJndW1lbnQgb3JkZXIuIFdoaWNoIGVhcmxpZXIga2luZHMgYSBkZWxpdmVyeSBkZWZlcnNcbiAgICogYmVoaW5kIGlzIHNwZWxsZWQgb3V0IG9uIHtAbGluayBhd2FpdEVhcmxpZXJEZWxpdmVyaWVzfS5cbiAgICpcbiAgICogSW5kZXggaXMgdXNlZCByYXRoZXIgdGhhbiB0aGUgYGV2ZW50SWRgIHN0cmluZyBiZWNhdXNlIGBldmVudElkYCBpcyBhblxuICAgKiBvcGFxdWUsIHdvcmxkLWFzc2lnbmVkIHZhbHVlIG5vdCBndWFyYW50ZWVkIHRvIHNvcnQgaW4gY3JlYXRpb24gb3JkZXJcbiAgICogKG9ubHkgdGhlIGJ1bmRsZWQgVUxJRCB3b3JsZHMgaGFwcGVuIHRvKS5cbiAgICpcbiAgICogT3B0aW9uYWwgc28gb2xkZXIvb3V0LW9mLXRyZWUgY29udGV4dHMgKGFuZCBsaWdodHdlaWdodCB0ZXN0IGhhcm5lc3NlcylcbiAgICogdGhhdCBkbyBub3QgaW5pdGlhbGl6ZSBpdCBkZWdyYWRlIGdyYWNlZnVsbHkgdG8gdGhlIHByZXZpb3VzIGJlaGF2aW9yLlxuICAgKi9cbiAgcGVuZGluZ0RlbGl2ZXJ5QmFycmllcnM/OiBNYXA8bnVtYmVyLCBEZWxpdmVyeUJhcnJpZXJFbnRyeT47XG4gIC8qKlxuICAgKiBJbnZvY2F0aW9uLXNjb3BlZCBjYWNoZSBvZiBwcmVwYXJlZCBzZXJpYWxpemVkIHBheWxvYWRzIGFuZCBpbW11dGFibGUgZmluYWxcbiAgICogdmFsdWVzLiBQcmVwYXJlZCBieXRlcyBzdXJ2aXZlIGZyZXNoIHJlcGxheSBWTXM7IG9iamVjdCBncmFwaHMgZG8gbm90LlxuICAgKi9cbiAgcmVwbGF5UGF5bG9hZENhY2hlOiBSZXBsYXlQYXlsb2FkQ2FjaGU7XG59XG5cbi8qKiBUaGUga2luZCBvZiBicmFuY2gtZGVjaWRpbmcgZGVsaXZlcnkgYSBiYXJyaWVyIHJlcHJlc2VudHMuICovXG5leHBvcnQgdHlwZSBEZWxpdmVyeUtpbmQgPSAnaG9vaycgfCAnd2FpdCcgfCAnc3RlcCc7XG5cbmludGVyZmFjZSBEZWxpdmVyeUJhcnJpZXJFbnRyeSB7XG4gIGtpbmQ6IERlbGl2ZXJ5S2luZDtcbiAgLyoqIFJlc29sdmVzIG9uY2UgdGhpcyBkZWxpdmVyeSBoYXMgcmVzb2x2ZWQgdG8gdGhlIHdvcmtmbG93LiAqL1xuICBkZWxpdmVyZWQ6IFByb21pc2U8dm9pZD47XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoaXMgZGVsaXZlcnkgaXMgY29tbWl0dGVkIHRvIHJlYWNoaW5nIHRoZSB3b3JrZmxvdyB3aXRob3V0IGFueVxuICAgKiBmdXJ0aGVyIGFjdGlvbiBieSB3b3JrZmxvdyBjb2RlLiBUcnVlIGZvciB3YWl0IGNvbXBsZXRpb25zIGFuZCBzdGVwXG4gICAqIHJlc3VsdHMsIHdoaWNoIGFsd2F5cyByZXNvbHZlIGZyb20gdGhlaXIgb3duIGNoYWluLCBhbmQgZm9yIGEgaG9vayBwYXlsb2FkXG4gICAqIHRoYXQgYWxyZWFkeSBoYWQgYSB3YWl0aW5nIGNvbnN1bWVyIHdoZW4gaXQgd2FzIGNvbnN1bWVkLlxuICAgKlxuICAgKiBGYWxzZSBmb3IgYSBCVUZGRVJFRCBob29rIHBheWxvYWQgbm8gY29uc3VtZXIgaGFzIGNsYWltZWQgeWV0OiBpdCBpc1xuICAgKiBkZWxpdmVyZWQgYnkgYGNsYWltKClgLCBpLmUuIHdoZW5ldmVyIHRoZSB3b3JrZmxvdyBuZXh0IHJlYWRzIHRoZSBob29rIOKAlFxuICAgKiB3aGljaCBtYXkgYmUgY2F1c2FsbHkgKmFmdGVyKiBhIGxhdGVyLWluLWxvZyBkZWxpdmVyeS4gYGFybSgpYCBmbGlwcyBpdFxuICAgKiBvbmNlIGEgY29uc3VtZXIgdGFrZXMgdGhlIHBheWxvYWQuXG4gICAqL1xuICBhcm1lZDogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBXaGljaCBlYXJsaWVyIGtpbmRzIGVhY2ggZGVsaXZlcnkga2luZCBkZWZlcnMgYmVoaW5kLiBDaG9zZW4gc28gdGhhdCBubyBraW5kXG4gKiBibG9ja3Mgb24gYSBwZWVyIGl0IGRvZXMgbm90IG5lZWQgdG86XG4gKlxuICogIC0gYSBob29rIGRlZmVycyBiZWhpbmQgZWFybGllciBXQUlUUyBhbmQgU1RFUFMg4oCUIG5vdCBlYXJsaWVyIGhvb2tzLCB3aGljaFxuICogICAgYXJlIHNlcXVlbnRpYWwgc2FtZS1lbnRpdHkgcGF5bG9hZHMgYW5kIG11c3Qgbm90IGJsb2NrIG9uZSBhbm90aGVyO1xuICogIC0gYSB3YWl0IGRlZmVycyBiZWhpbmQgZWFybGllciBIT09LUyBhbmQgU1RFUFMg4oCUIG5vdCBlYXJsaWVyIHdhaXRzLCBzaW5jZSBhXG4gKiAgICB3YWl0IG5ldmVyIG5lZWRzIHRvIHF1ZXVlIGJlaGluZCBhbm90aGVyIHdhaXQ7XG4gKiAgLSBhIHN0ZXAgZGVmZXJzIGJlaGluZCBlYXJsaWVyIFdBSVRTLCBIT09LUyBhbmQgU1RFUFMuXG4gKlxuICogVGhlIHN0ZXAtYmVoaW5kLXN0ZXAgZWRnZSBpcyBub3QgcmVkdW5kYW50IHdpdGggdGhlIHNlcmlhbCBgcHJvbWlzZVF1ZXVlYC5cbiAqIFRoZSBxdWV1ZSBmaXhlcyB0aGUgb3JkZXIgaW4gd2hpY2ggc3RlcCByZXN1bHRzIGFyZSBIWURSQVRFRCwgYnV0IGEgc3RlcCBub1xuICogbG9uZ2VyIHJlc29sdmVzIGluc2lkZSBpdHMgcXVldWUgc2xvdCDigJQgaXQgY2FwdHVyZXMgdGhlIG91dGNvbWUgdGhlcmUgYW5kXG4gKiByZXNvbHZlcyBmcm9tIGEgZGV0YWNoZWQgY29udGludWF0aW9uIG9uY2UgaXRzIGJhcnJpZXIgY2xlYXJzLiBUd28gc3RlcHNcbiAqIGFncmVlIG9uIHRoYXQgY29udGludWF0aW9uJ3Mgb3JkZXJpbmcgb25seSB3aGlsZSB0aGV5IGRlZmVyIGJlaGluZCB0aGUgc2FtZVxuICogc2V0LCB3aGljaCBob2xkcyB3aGVuIHRoZXkgYXJlIGNvbnN1bWVkIGluIHRoZSBzYW1lIGRyYWluIHdpbmRvdyBidXQgbm90XG4gKiBhY3Jvc3Mgd2luZG93czogYSBzdGVwIGNvbnN1bWVkIGxhdGVyIGNhbiBtaXNzIGEgd2FpdC9ob29rIGJhcnJpZXIgdGhhdCBhblxuICogZWFybGllciBzdGVwIGlzIHN0aWxsIHBhcmtlZCBvbiwgYmVjYXVzZSB0aGUgYmFycmllciByZXRpcmVkIGluIGJldHdlZW4uIFRoZVxuICogZWFybGllciBzdGVwIGlzIHRoZW4gd2FpdGluZyBvdXQgdGhlIG1hY3JvdGFzayB5aWVsZCBiZWxvdyB3aGlsZSB0aGUgbGF0ZXJcbiAqIG9uZSByZXNvbHZlcyBvbiBtaWNyb3Rhc2tzLCBhbmQgb3ZlcnRha2VzIGl0IOKAlCBzZWVcbiAqIGBkZWxpdmVyeS1iYXJyaWVyLWNvdmVyYWdlLnRlc3QudHNgLiBEZWZlcnJpbmcgYmVoaW5kIGVhcmxpZXIgc3RlcHNcbiAqIGNsb3NlcyB0aGF0IHdpbmRvdyBzdHJ1Y3R1cmFsbHk6IHRoZSBlYXJsaWVyIHN0ZXAncyBiYXJyaWVyIGlzIHN0aWxsXG4gKiByZWdpc3RlcmVkIHByZWNpc2VseSBiZWNhdXNlIGl0IGhhcyBub3QgZGVsaXZlcmVkIHlldC5cbiAqXG4gKiBFdmVyeSBlZGdlIHBvaW50cyBmcm9tIGEgbGF0ZXIgbG9nIGluZGV4IHRvIGEgc3RyaWN0bHkgZWFybGllciBvbmUsIHNvIHRoZVxuICogd2FpdC1mb3IgZ3JhcGggY2FuIG5ldmVyIGNvbnRhaW4gYSBjeWNsZS5cbiAqL1xuY29uc3QgREVGRVJfQkVISU5EOiBSZWNvcmQ8RGVsaXZlcnlLaW5kLCByZWFkb25seSBEZWxpdmVyeUtpbmRbXT4gPSB7XG4gIGhvb2s6IFsnd2FpdCcsICdzdGVwJ10sXG4gIHdhaXQ6IFsnaG9vaycsICdzdGVwJ10sXG4gIHN0ZXA6IFsnd2FpdCcsICdob29rJywgJ3N0ZXAnXSxcbn07XG5cbi8qKlxuICogV2hldGhlciBhIGRlbGl2ZXJ5IG9mIGBraW5kYCBhdCBsb2cgaW5kZXggYGluZGV4YCBnYXRlcyBvbiB0aGUgZWFybGllclxuICogcmVnaXN0cnkgZW50cnkgYG90aGVyYCAoYXQgYG90aGVySW5kZXhgKS5cbiAqXG4gKiBTaW5nbGUgc291cmNlIG9mIHRydXRoIGZvciB0aGF0IHF1ZXN0aW9uLCBjYWxsZWQgYnkgYm90aFxuICoge0BsaW5rIGF3YWl0RWFybGllckRlbGl2ZXJpZXN9ICh3aGljaCBhd2FpdHMgd2hhdCBpdCBnYXRlcyBvbikgYW5kXG4gKiB7QGxpbmsgY29tcHV0ZVJlc29sdmVzT25JdHNPd259ICh3aGljaCByZWN1cnNlcyBpbnRvIHdoYXQgaXQgZ2F0ZXMgb24pLlxuICogVGhvc2UgdHdvIE1VU1QgYWdyZWUgZXhhY3RseSwgYW5kIHRoZSBkb2MgYmxvY2sgb25cbiAqIHtAbGluayBhd2FpdEVhcmxpZXJEZWxpdmVyaWVzfSBzdGFrZXMgZGVhZGxvY2stZnJlZWRvbSBvbiBpdCwgc28gdGhlXG4gKiBjb25kaXRpb24gbGl2ZXMgaGVyZSByYXRoZXIgdGhhbiBiZWluZyBzcGVsbGVkIG91dCB0d2ljZS5cbiAqL1xuZnVuY3Rpb24gZ2F0ZXNPbihcbiAga2luZDogRGVsaXZlcnlLaW5kLFxuICBpbmRleDogbnVtYmVyLFxuICBvdGhlckluZGV4OiBudW1iZXIsXG4gIG90aGVyOiBEZWxpdmVyeUJhcnJpZXJFbnRyeVxuKTogYm9vbGVhbiB7XG4gIGlmIChvdGhlckluZGV4ID49IGluZGV4IHx8ICFERUZFUl9CRUhJTkRba2luZF0uaW5jbHVkZXMob3RoZXIua2luZCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gQSBzdGVwIHNraXBzIGFuIFVOQVJNRUQgZWFybGllciBlbnRyeSAoYW4gdW5jbGFpbWVkIGJ1ZmZlcmVkIGhvb2tcbiAgLy8gcGF5bG9hZCkg4oCUIHNlZSB0aGUgYXN5bW1ldHJ5IGRlc2NyaWJlZCBvbiBgYXdhaXRFYXJsaWVyRGVsaXZlcmllc2AuIFRoZVxuICAvLyBza2lwIGlzIGRpcmVjdCwgbmV2ZXIgdHJhbnNpdGl2ZTogYXJtZWQgZW50cmllcyBhcmUgc3RpbGwgZ2F0ZWQgb24sIGV2ZW5cbiAgLy8gd2hlbiB0aGV5IGFyZSB0aGVtc2VsdmVzIHBhcmtlZCBiZWhpbmQgc3VjaCBhIHBheWxvYWQuXG4gIHJldHVybiAhKGtpbmQgPT09ICdzdGVwJyAmJiAhb3RoZXIuYXJtZWQpO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgYGVudHJ5YCB3aWxsIHJlc29sdmUgb24gaXRzIG93biDigJQgaXQgaXMgYXJtZWQsIGFuZCBldmVyeSBlYXJsaWVyXG4gKiBkZWxpdmVyeSBpdCBhY3R1YWxseSBnYXRlcyBvbiAoe0BsaW5rIGdhdGVzT259KSB3aWxsIGxpa2V3aXNlIHJlc29sdmUgb24gaXRzXG4gKiBvd24uXG4gKlxuICogQSBzdGVwIGRvZXMgbm90IGdhdGUgb24gYW4gdW5jbGFpbWVkIGJ1ZmZlcmVkIHBheWxvYWQsIHNvIHN1Y2ggYSBwYXlsb2FkXG4gKiBjYW5ub3Qga2VlcCBpdCBmcm9tIHJlc29sdmluZy4gQSBzdGVwIERPRVMgZ2F0ZSBvbiBlYXJsaWVyIGFybWVkIHdhaXRzIGFuZFxuICogaG9va3MsIHNvIG9uZSBwYXJrZWQgYmVoaW5kIGFuIHVuY2xhaW1lZCBwYXlsb2FkIG1ha2VzIHRoZSBzdGVwXG4gKiBub24tc2VsZi1yZXNvbHZpbmcgaW4gdHVybi4gRGlzYWdyZWVpbmcgd2l0aCB7QGxpbmsgYXdhaXRFYXJsaWVyRGVsaXZlcmllc31cbiAqIGhlcmUgd291bGQgbm90IGJlIGEgY29zbWV0aWMgcHJvYmxlbTogdGhpcyBwcmVkaWNhdGUgaXMgd2hhdFxuICoge0BsaW5rIGhhc1BhcmtlZENvbW1pdHRlZERlbGl2ZXJ5fSB1c2VzIHRvIGRlY2lkZSB3aGV0aGVyIGlkbGUgaXMgcmVhY2hhYmxlLFxuICogYW5kIGFuIGVudHJ5IHJlcG9ydGVkIHNlbGYtcmVzb2x2aW5nIHdoaWxlIGl0IGlzIGluIGZhY3QgcGFya2VkIGJlaGluZCBhXG4gKiBwYXlsb2FkIHRoYXQgb25seSB0aGUgaWRsZSBzYWZldHkgbmV0IGNhbiByZXRpcmUgd291bGQgZ2F0ZSBpdHMgb3duXG4gKiByZXRpcmVtZW50LlxuICpcbiAqIFJlY3Vyc2lvbiB0ZXJtaW5hdGVzIGJlY2F1c2UgZXZlcnkgZWRnZSBwb2ludHMgdG8gYSBzdHJpY3RseSBzbWFsbGVyIGluZGV4LlxuICogYG1lbW9gIGtlZXBzIHRoZSB3YWxrIGxpbmVhciBpbiByZWdpc3RyeSBzaXplLCBhbmQgdGhlIHJlZ2lzdHJ5IGlzIG5vdCBzbWFsbFxuICogYnkgY29uc3RydWN0aW9uIOKAlCBgRXZlbnRzQ29uc3VtZXJgIGRyYWlucyBjb25zZWN1dGl2ZWx5IGNvbnN1bWFibGUgZXZlbnRzXG4gKiBzeW5jaHJvbm91c2x5IHdoaWxlIGJhcnJpZXJzIG9ubHkgcmV0aXJlIG9uIG1pY3JvdGFzay1kcml2ZW4gZGVsaXZlcmllcywgc29cbiAqIGEgZmFuLW91dCBvZiBgUHJvbWlzZS5yYWNlKFtob29rLCBzbGVlcF0pYCBicmFuY2hlcyBhY2N1bXVsYXRlcyBvbmUgYmFycmllclxuICogcGVyIGJyYW5jaCBwZXIga2luZC4gVGhlIG1lbW8gTVVTVCBiZSBwZXItY2FsbDogYGFybWVkYCBtdXRhdGVzIGJldHdlZW5cbiAqIGNhbGxzIGFzIGJ1ZmZlcmVkIHBheWxvYWRzIGFyZSBjbGFpbWVkLlxuICpcbiAqIFRoZSBtZW1vIGlzIGFuIG9wdGltaXphdGlvbiwgbm90IGEgY29ycmVjdG5lc3MgcmVxdWlyZW1lbnQuIEl0IG9uY2Ugd2FzIG9uZTpcbiAqIGBhd2FpdEVhcmxpZXJEZWxpdmVyaWVzYCB1c2VkIHRvIHJ1biB0aGlzIHdhbGsgZm9yIGV2ZXJ5IGVhcmxpZXIgZW50cnkgb2YgYVxuICogc3RlcCBkZWxpdmVyeSwgd2l0aCBubyBlYXJseSBleGl0LCB3aGljaCB1bm1lbW9pemVkIGlzIFQobikgPSDOoyBUKGopIOKAlFxuICogbWVhc3VyZWQgYXQgNC4zZTggcmVjdXJzaXZlIGNhbGxzICg4NHMpIGZvciA0MCBhbHRlcm5hdGluZyBhcm1lZCBob29rL3dhaXRcbiAqIGJhcnJpZXJzLiBUaGF0IGNhbGwgc2l0ZSBpcyBnb25lOyBhIHN0ZXAgbm93IHRlc3RzIGBhcm1lZGAgZGlyZWN0bHkuIFRoZSBvbmVcbiAqIHN1cnZpdmluZyBjYWxsZXIsIHtAbGluayBoYXNQYXJrZWRDb21taXR0ZWREZWxpdmVyeX0sIGNhbm5vdCByZWFjaCB0aGF0XG4gKiBzaGFwZTogaXQgcmV0dXJucyBhdCB0aGUgRklSU1Qgc2VsZi1yZXNvbHZpbmcgZW50cnksIHNvIGl0IG9ubHkgZXZlclxuICogYWR2YW5jZXMgcGFzdCBlbnRyaWVzIHRoYXQgYXJlIG5vbi1zZWxmLXJlc29sdmluZywgYW5kIHRob3NlIHNob3J0LWNpcmN1aXRcbiAqIG9uIHRoZWlyIGZpcnN0IGZhbHNlIGNoaWxkLiBFdmVyeSBlbnRyeSBpdCBldmFsdWF0ZXMgdGhlcmVmb3JlIGhhc1xuICogYWxsLWZhbHNlIHByZWRlY2Vzc29ycyBhbmQgcmV0dXJucyBhZnRlciBvbmUgY2hpbGQsIGRlZ2VuZXJhdGluZyB0aGUgd2FsayB0b1xuICogYSBjaGFpbiAobWVhc3VyZWQ6IDk4IGNhbGxzIHVubWVtb2l6ZWQgZm9yIHRoZSB3b3JzdCA0MC1iYXJyaWVyIHNoYXBlLCAxXG4gKiBjYWxsIGZvciB0aGUgcmVnaXN0cnkgYWJvdmUpLiBEbyBub3QgcmVzdG9yZSBhbiBleHBvbmVudGlhbCBjbGFpbSBoZXJlXG4gKiB3aXRob3V0IHJlc3RvcmluZyBhIGNhbGxlciB0aGF0IGNhbiBwcm9kdWNlIGl0LlxuICovXG5mdW5jdGlvbiByZXNvbHZlc09uSXRzT3duKFxuICBiYXJyaWVyczogTWFwPG51bWJlciwgRGVsaXZlcnlCYXJyaWVyRW50cnk+LFxuICBpbmRleDogbnVtYmVyLFxuICBlbnRyeTogRGVsaXZlcnlCYXJyaWVyRW50cnksXG4gIG1lbW86IE1hcDxudW1iZXIsIGJvb2xlYW4+XG4pOiBib29sZWFuIHtcbiAgY29uc3QgY2FjaGVkID0gbWVtby5nZXQoaW5kZXgpO1xuICBpZiAoY2FjaGVkICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gY2FjaGVkO1xuICB9XG4gIGNvbnN0IHJlc3VsdCA9IGNvbXB1dGVSZXNvbHZlc09uSXRzT3duKGJhcnJpZXJzLCBpbmRleCwgZW50cnksIG1lbW8pO1xuICBtZW1vLnNldChpbmRleCwgcmVzdWx0KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gY29tcHV0ZVJlc29sdmVzT25JdHNPd24oXG4gIGJhcnJpZXJzOiBNYXA8bnVtYmVyLCBEZWxpdmVyeUJhcnJpZXJFbnRyeT4sXG4gIGluZGV4OiBudW1iZXIsXG4gIGVudHJ5OiBEZWxpdmVyeUJhcnJpZXJFbnRyeSxcbiAgbWVtbzogTWFwPG51bWJlciwgYm9vbGVhbj5cbik6IGJvb2xlYW4ge1xuICBpZiAoIWVudHJ5LmFybWVkKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGZvciAoY29uc3QgW290aGVySW5kZXgsIG90aGVyXSBvZiBiYXJyaWVycykge1xuICAgIGlmICghZ2F0ZXNPbihlbnRyeS5raW5kLCBpbmRleCwgb3RoZXJJbmRleCwgb3RoZXIpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKCFyZXNvbHZlc09uSXRzT3duKGJhcnJpZXJzLCBvdGhlckluZGV4LCBvdGhlciwgbWVtbykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogQXdhaXRzLCBpbiBzdHJpY3QgZXZlbnQtbG9nIG9yZGVyLCBldmVyeSBzdGlsbC1yZWdpc3RlcmVkIGRlbGl2ZXJ5IHRoYXQgaXNcbiAqIGVhcmxpZXIgaW4gdGhlIGxvZyB0aGFuIGBldmVudEluZGV4YCBhbmQgdGhhdCBhIGRlbGl2ZXJ5IG9mIGBraW5kYCBkZWZlcnNcbiAqIGJlaGluZCAoc2VlIHtAbGluayBERUZFUl9CRUhJTkR9KSwgc28gdGhhdCB0aGlzIHJlc29sdXRpb24gaXMgaGFuZGVkIHRvIHRoZVxuICogd29ya2Zsb3cgb25seSBhZnRlciBhbGwgcmVsZXZhbnQgZWFybGllci1pbi1sb2cgZGVsaXZlcmllcyBoYXZlIGJlZW4uIFRoaXNcbiAqIGlzIHdoYXQga2VlcHMgYSBgUHJvbWlzZS5yYWNlYCDigJQgb3IgdGhlIFVMSUQgYSBmb2xsb3ctdXAgYHVzZVN0ZXBgIGRyYXdzIG9uXG4gKiBhIGNvbmN1cnJlbnQgYnJhbmNoIOKAlCBkZXRlcm1pbmlzdGljIGFuZCBhbGlnbmVkIHdpdGggdGhlIGNvbW1pdHRlZCBldmVudFxuICogbG9nLCBpbmRlcGVuZGVudCBvZiBtaWNyb3Rhc2staG9wIGNvdW50cywgaHlkcmF0aW9uIHRpbWUsIG9yIHJhY2UtYXJndW1lbnRcbiAqIG9yZGVyLiBXaGVuIHRoaXMgZGVsaXZlcnkgZG9lcyBoYXZlIHRvIHdhaXQsIGl0IGFsc28geWllbGRzIGEgbWFjcm90YXNrXG4gKiBhZnRlcndhcmRzIHNvIHRoZSBlYXJsaWVyIGRlbGl2ZXJ5J3MgY29uc3VtZXIgY2FuIHJ1biB0byBpdHMgb3duIG5leHRcbiAqIHN1c3BlbnNpb24gcG9pbnQgZmlyc3Q7IHNlZSB0aGUgY29tbWVudCBhdCB0aGF0IGBhd2FpdGAgZm9yIHdoeSBvcmRlcmluZyB0aGVcbiAqIGByZXNvbHZlKClgIGNhbGxzIGFsb25lIGlzIG5vdCBlbm91Z2guXG4gKlxuICogV2hhdCBjb3VudHMgYXMgXCJkZWZlcnMgYmVoaW5kXCIgaXMge0BsaW5rIGdhdGVzT259LCBzaGFyZWQgd2l0aFxuICoge0BsaW5rIGNvbXB1dGVSZXNvbHZlc09uSXRzT3dufSBzbyB0aGUgdHdvIGNhbm5vdCBkcmlmdC5cbiAqXG4gKiBPbmUgYXN5bW1ldHJ5OiBhIFNURVAgcmVzdWx0IHNraXBzIGFueSBlYXJsaWVyIGRlbGl2ZXJ5IHRoYXQgaXMgVU5BUk1FRCxcbiAqIGkuZS4gYSBidWZmZXJlZCBob29rIHBheWxvYWQgbm8gY29uc3VtZXIgaGFzIGNsYWltZWQuIFN1Y2ggYSBwYXlsb2FkIGlzXG4gKiBkZWxpdmVyZWQgb25seSB3aGVuIHRoZSB3b3JrZmxvdyBuZXh0IHJlYWRzIHRoZSBob29rLCBhbmQgcmVhY2hpbmcgdGhhdCByZWFkXG4gKiB2ZXJ5IGNvbW1vbmx5IHJlcXVpcmVzIHRoZSBzdGVwIHJlc3VsdCBpdHNlbGYgKGBhd2FpdCBzdGVwWCgpYCBiZWZvcmUgdGhlXG4gKiByZWFkKS4gR2F0aW5nIHRoZSBzdGVwIG9uIGl0IHdvdWxkIHN0YWxsIHRoZSB3b3JrZmxvdyB1bnRpbCB0aGUgYmFycmllcidzXG4gKiBpZGxlIHNhZmV0eSBuZXQgZmlyZXMsIHdoaWNoIHRoZW4gcmVsZWFzZXMgZXZlcnkgZGVsaXZlcnkgcXVldWVkIGJlaGluZCB0aGF0XG4gKiBwYXlsb2FkIGF0IG9uY2Ug4oCUIGxvc2luZyBleGFjdGx5IHRoZSByYWNlIHRoaXMgb3JkZXJpbmcgZXhpc3RzIHRvIHByb3RlY3QuXG4gKiBXYWl0cyBhbmQgaG9va3Mga2VlcCBnYXRpbmcgb24gdW5jbGFpbWVkIHBheWxvYWRzOiBmb3IgdGhlbSwgd2FpdGluZyBmb3IgdGhlXG4gKiBjbGFpbSBJUyB0aGUgb3JkZXJpbmcgZ3VhcmFudGVlIChhIGB3YWl0X2NvbXBsZXRlZGAgbXVzdCBub3QgcHJlZW1wdCBhXG4gKiBwYXlsb2FkIHRoZSBsb2cgb3JkZXJlZCBmaXJzdCkuXG4gKlxuICogVGhlIHNraXAgaXMgZGlyZWN0LCBuZXZlciB0cmFuc2l0aXZlLiBBIHN0ZXAgc3RpbGwgZ2F0ZXMgb24gYW4gZWFybGllciBBUk1FRFxuICogd2FpdCBvciBob29rLCBpbmNsdWRpbmcgb25lIHRoYXQgaXMgaXRzZWxmIHBhcmtlZCBiZWhpbmQgYW4gdW5jbGFpbWVkXG4gKiBwYXlsb2FkLiBTa2lwcGluZyB0aG9zZSB0b28gd291bGQgaW52ZXJ0IGxvZyBvcmRlciBmb3IgdGhlIGNvbW1vbmVzdCBzaGFwZVxuICogdGhlcmUgaXM6IGEgd29ya2Zsb3cgdGhhdCBjcmVhdGVzIGEgaG9vayBpdCBkb2VzIG5vdCByZWFkIG9uIHRoaXMgYnJhbmNoLFxuICogcmFjZXMgYHN0ZXBgIGFnYWluc3QgYHNsZWVwYCwgYW5kIGhhcyB0aGUgbG9nIHNheSB0aGUgc2xlZXAgd29uLiBUaGUgc3RlcFxuICogd291bGQgdGhlbiBvdmVydGFrZSB0aGUgd2FpdCwgYm90aCBicmFuY2hlcyB3b3VsZCBzd2FwIHRoZSBjb3JyZWxhdGlvbiBpZHNcbiAqIHRoZXkgZHJhdyBuZXh0LCBhbmQgcmVwbGF5IHdvdWxkIGRpdmVyZ2Ug4oCUIHNlZVxuICogYHN0ZXAtZGVsaXZlcnktb3JkZXJpbmcudGVzdC50c2AuIFdhaXRpbmcgaW5zdGVhZCBpcyBzYWZlIGJlY2F1c2UgdGhlXG4gKiBwYXlsb2FkJ3Mgb3duIGlkbGUgc2FmZXR5IG5ldCByZXRpcmVzIGl0IGFuZCB0aGUgd2hvbGUgY2hhaW4gdGhlbiBkZWxpdmVyc1xuICogaW4gbG9nIG9yZGVyOyB7QGxpbmsgaGFzUGFya2VkQ29tbWl0dGVkRGVsaXZlcnl9IGRlbGliZXJhdGVseSByZXBvcnRzIHN1Y2ggYVxuICogc3RlcCBhcyBub3Qgc2VsZi1yZXNvbHZpbmcgc28gdGhhdCBpZGxlIHN0YXlzIHJlYWNoYWJsZS5cbiAqXG4gKiBcIlRoZSB3aG9sZSBjaGFpbiB0aGVuIGRlbGl2ZXJzIGluIGxvZyBvcmRlclwiIHJlc3RzIG9uIHRoZSBQQVlMT0FEJ3Mgc2FmZXR5XG4gKiBuZXQgb2JzZXJ2aW5nIGlkbGUgYmVmb3JlIHRoZSBuZXQgb2YgdGhlIHdhaXQgcGFya2VkIGJlaGluZCBpdC4gSWYgdGhlXG4gKiB3YWl0J3MgbmV0IGZpcmVkIGZpcnN0LCB0aGUgc3RlcCdzIGdhdGUgd291bGQgb3BlbiB3aGlsZSB0aGUgd2FpdCB3YXMgc3RpbGxcbiAqIHBhcmtlZCBvbiB0aGUgcGF5bG9hZCBiYXJyaWVyIGFuZCB0aGUgaW52ZXJzaW9uIGFib3ZlIHdvdWxkIHJlYXBwZWFyLiBXaXRoaW5cbiAqIG9uZSBkcmFpbiB3aW5kb3cgdGhhdCBvcmRlciBpcyBzdHJ1Y3R1cmFsLCBhbmQgY2FycmllZCBieSBGSUZPIG9mIHRoZVxuICogc2FmZXR5LW5ldCBwb2xsczogbmV0cyBhcm0gdmlhIGBzZXRUaW1lb3V0YCBpbiBsb2cgb3JkZXIgZHVyaW5nIHN5bmNocm9ub3VzXG4gKiBjb25zdW1wdGlvbiwgZWFjaCBwb2xsaW5nIHJvdW5kIHJlLWFybXMgdGhyb3VnaCBgcHJvbWlzZVF1ZXVlLnRoZW4oLi4uKWAgaW5cbiAqIHRoZSBvcmRlciB0aGUgY2hlY2tzIHJhbiwgYW5kIGVhY2ggbmV0IHRoYXQgZmlyZXMgZmxpcHNcbiAqIHtAbGluayBoYXNQYXJrZWRDb21taXR0ZWREZWxpdmVyeX0gYmFjayB0byB0cnVlLCByZS1ibG9ja2luZyB0aGUgcmVzdCB1bnRpbFxuICogdGhlIHJlbGVhc2VkIGRlbGl2ZXJ5IGNvbXBsZXRlcy4gUmVwbGF5IOKAlCB3aGVyZSBkaXZlcmdlbmNlIG1hbmlmZXN0cyDigJRcbiAqIGFsd2F5cyBjb25zdW1lcyB0aGUgbG9nIGluIG9uZSB3aW5kb3cuIERvIG5vdCBcIm9wdGltaXplXCIgdGhlIG5ldCBzY2hlZHVsaW5nXG4gKiBpbiBhIHdheSB0aGF0IGJyZWFrcyB0aGF0IHBlci13aW5kb3cgRklGTy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGF3YWl0RWFybGllckRlbGl2ZXJpZXMoXG4gIGN0eDogV29ya2Zsb3dPcmNoZXN0cmF0b3JDb250ZXh0LFxuICBldmVudEluZGV4OiBudW1iZXIgfCB1bmRlZmluZWQsXG4gIGtpbmQ6IERlbGl2ZXJ5S2luZFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIC8vIERlZmVuc2l2ZTogdG9sZXJhdGUgY29udGV4dHMgdGhhdCBwcmVkYXRlIHRoaXMgZmllbGQgKHRlc3QgaGFybmVzc2VzKS5cbiAgaWYgKFxuICAgIGV2ZW50SW5kZXggPT09IHVuZGVmaW5lZCB8fFxuICAgICFjdHgucGVuZGluZ0RlbGl2ZXJ5QmFycmllcnMgfHxcbiAgICBjdHgucGVuZGluZ0RlbGl2ZXJ5QmFycmllcnMuc2l6ZSA9PT0gMFxuICApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3QgYmFycmllcnMgPSBjdHgucGVuZGluZ0RlbGl2ZXJ5QmFycmllcnM7XG4gIGNvbnN0IGVhcmxpZXI6IFByb21pc2U8dm9pZD5bXSA9IFtdO1xuICBmb3IgKGNvbnN0IFtpbmRleCwgZW50cnldIG9mIGJhcnJpZXJzKSB7XG4gICAgaWYgKCFnYXRlc09uKGtpbmQsIGV2ZW50SW5kZXgsIGluZGV4LCBlbnRyeSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBlYXJsaWVyLnB1c2goZW50cnkuZGVsaXZlcmVkKTtcbiAgfVxuICBpZiAoZWFybGllci5sZW5ndGggPiAwKSB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoZWFybGllcik7XG4gICAgLy8gQW4gZWFybGllciBkZWxpdmVyeSBiZWluZyBcImRlbGl2ZXJlZFwiIG9ubHkgbWVhbnMgaXRzIGByZXNvbHZlKClgIHJhbi5cbiAgICAvLyBUaGUgYnJhbmNoIGl0IHdva2UgbWF5IG5lZWQgYW4gYXJiaXRyYXJ5IG51bWJlciBvZiBmdXJ0aGVyIG1pY3JvdGFza1xuICAgIC8vIGhvcHMgYmVmb3JlIGl0IHJlYWNoZXMgaXRzIG5leHQgYHVzZVN0ZXBgIGNhbGwgYW5kIGRyYXdzIGEgVUxJRCDigJQgYVxuICAgIC8vIGBmb3IgYXdhaXRgIG92ZXIgYSBob29rLCBmb3IgaW5zdGFuY2UsIHJlc3VtZXMgdGhlIGdlbmVyYXRvciwgc2V0dGxlc1xuICAgIC8vIHRoZSBwcm9taXNlIGZyb20gYG5leHQoKWAsIGFuZCBvbmx5IHRoZW4gcnVucyB0aGUgbG9vcCBib2R5LiBSZXNvbHZpbmdcbiAgICAvLyB0aGlzIGRlbGl2ZXJ5IG9uIGEgbWljcm90YXNrIHdvdWxkIGxldCBpdCBvdmVydGFrZSB0aGF0IGJyYW5jaCBhbmRcbiAgICAvLyByZW9yZGVyIHRoZSBVTElEIGFsbG9jYXRpb24gYW55d2F5LCB0dXJuaW5nIHRoZSBndWFyYW50ZWUgYmVsb3cgaW50byBhXG4gICAgLy8gaG9wLWNvdW50IHJhY2UgdGhhdCBob2xkcyBvbmx5IGZvciB0aGUgc2hvcnRlc3QgY29uc3VtZXJzLlxuICAgIC8vXG4gICAgLy8gWWllbGRpbmcgYSBtYWNyb3Rhc2sgbGV0cyB0aGUgZWFybGllciBicmFuY2gncyBlbnRpcmUgbWljcm90YXNrIGNoYWluXG4gICAgLy8gZHJhaW4gZmlyc3QsIHdoYXRldmVyIGl0cyBsZW5ndGgsIHNvIGxvZyBvcmRlciBzdXJ2aXZlcyByZWdhcmRsZXNzIG9mXG4gICAgLy8gaG93IHRoZSB3b3JrZmxvdyBjb25zdW1lcyB0aGUgZWFybGllciBkZWxpdmVyeS4gT25seSBkZWxpdmVyaWVzIHRoYXRcbiAgICAvLyBhY3R1YWxseSBoYWQgdG8gZGVmZXIgcGF5IHRoaXMsIHNvIHRoZSBjb21tb24gc2luZ2xlLWRlbGl2ZXJ5IGRyYWluIGlzXG4gICAgLy8gdW5hZmZlY3RlZC5cbiAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCAwKSk7XG4gIH1cbn1cblxuLyoqIEhhbmRsZSBmb3IgYSByZWdpc3RlcmVkIGJyYW5jaC1kZWNpZGluZyBkZWxpdmVyeSBiYXJyaWVyLiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZWxpdmVyeUJhcnJpZXIge1xuICAvKipcbiAgICogTWFyayB0aGlzIGRlbGl2ZXJ5IGFzIGRlbGl2ZXJlZCB0byB0aGUgd29ya2Zsb3cuIFJlc29sdmVzIGl0c1xuICAgKiBgZGVsaXZlcmVkYCBwcm9taXNlIHNvIGFueSBsYXRlci1pbi1sb2cgZGVsaXZlcnkgZ2F0ZWQgb24gaXQgKHZpYVxuICAgKiB7QGxpbmsgYXdhaXRFYXJsaWVyRGVsaXZlcmllc30pIG1heSBwcm9jZWVkLCBhbmQgcmVtb3ZlcyBpdCBmcm9tIHRoZVxuICAgKiByZWdpc3RyeS4gSWRlbXBvdGVudC5cbiAgICovXG4gIG1hcmtEZWxpdmVyZWQ6ICgpID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBNYXJrIHRoaXMgZGVsaXZlcnkgYXMgY29tbWl0dGVkIHRvIGhhcHBlbmluZywgZm9yIGEgYmFycmllciByZWdpc3RlcmVkXG4gICAqIHVuYXJtZWQgKGEgYnVmZmVyZWQgaG9vayBwYXlsb2FkKSBvbmNlIGEgY29uc3VtZXIgaGFzIGNsYWltZWQgaXQuIEZyb21cbiAgICogdGhlbiBvbiBhIGxhdGVyIHN0ZXAgcmVzdWx0IG1heSBiZSBvcmRlcmVkIGJlaGluZCBpdC4gSWRlbXBvdGVudC5cbiAgICovXG4gIGFybTogKCkgPT4gdm9pZDtcbn1cblxuLyoqXG4gKiBSZWdpc3RlciBhIGJyYW5jaC1kZWNpZGluZyBkZWxpdmVyeSBhdCBpdHMgZXZlbnQtbG9nIGluZGV4IHNvIHRoYXQgbGF0ZXJcbiAqIGRlbGl2ZXJpZXMgY2FuIGJlIG9yZGVyZWQgc3RyaWN0bHkgYWZ0ZXIgaXQuIFJldHVybnMgYW4gaW5lcnQgaGFuZGxlIHdoZW5cbiAqIGBwZW5kaW5nRGVsaXZlcnlCYXJyaWVyc2AgaXMgbm90IGluaXRpYWxpemVkLlxuICpcbiAqIFBhc3MgYGFybWVkOiBmYWxzZWAgZm9yIGEgZGVsaXZlcnkgd2hvc2UgcmVzb2x1dGlvbiB3YWl0cyBvbiB3b3JrZmxvdyBjb2RlXG4gKiBhc2tpbmcgZm9yIGl0IChhIGJ1ZmZlcmVkIGhvb2sgcGF5bG9hZCk7IGNhbGwgYGFybSgpYCB3aGVuIGl0IGRvZXMuXG4gKlxuICogVG8gZ3VhcmFudGVlIGEgbGF0ZXIgZGVsaXZlcnkgZ2F0ZWQgb24gdGhpcyBvbmUgY2FuIG5ldmVyIGhhbmcgd2hlbiB0aGlzXG4gKiBkZWxpdmVyeSBpcyBhYmFuZG9uZWQgKHRoZSB3b3JrZmxvdyB0b29rIGEgZGlmZmVyZW50IGJyYW5jaCBvciBpc1xuICogc3VzcGVuZGluZyBhbmQgbmV2ZXIgb2JzZXJ2ZXMgaXQpLCB0aGUgYmFycmllciBhdXRvLXJlc29sdmVzIGF0IGlkbGUuXG4gKlxuICogSU5WQVJJQU5UIHJlcXVpcmVkIG9mIGV2ZXJ5IGNhbGwgc2l0ZTogYSBiYXJyaWVyIHRoYXQgaXMgZXZlciBgYXJtZWRgIG11c3RcbiAqIGJlIHBhaXJlZCB3aXRoIGEgZGVsaXZlcnkgY2hhaW4gdGhhdCBydW5zIHVuY29uZGl0aW9uYWxseSDigJQgYXR0YWNoZWQgd2hlblxuICogdGhlIGV2ZW50IGlzIGNvbnN1bWVkICh3YWl0cywgc3RlcCByZXN1bHRzLCB3YWl0aW5nLWNvbnN1bWVyIGhvb2sgcGF5bG9hZHMsXG4gKiBhYm9ydHMpLCBvciBieSB0aGUgYGNsYWltKClgIHdob3NlIGludm9jYXRpb24gaXMgd2hhdCBhcm1zIGl0IChidWZmZXJlZFxuICogaG9vayBwYXlsb2FkcykuIFRoZSBpZGxlIGNoZWNrICh7QGxpbmsgc2NoZWR1bGVXaGVuSWRsZX0pIHJlZnVzZXMgdG9cbiAqIG9ic2VydmUgaWRsZSB3aGlsZSBhbiBhcm1lZCwgc2VsZi1yZXNvbHZpbmcgYmFycmllciBpcyB1bmRlbGl2ZXJlZCwgYW5kIHRoZVxuICogc2FmZXR5IG5ldCBiZWxvdyBpcyBpdHNlbGYgaWRsZS1nYXRlZCDigJQgc28gYW4gYXJtZWQgYmFycmllciB3aXRoIG5vXG4gKiB1bmNvbmRpdGlvbmFsIGNoYWluIHdvdWxkIGxpdmVsb2NrIGV2ZXJ5IGlkbGUgY2hlY2sgaW4gdGhlIHJ1biwgaW5jbHVkaW5nXG4gKiBpdHMgb3duIHJldGlyZW1lbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlckRlbGl2ZXJ5QmFycmllcihcbiAgY3R4OiBXb3JrZmxvd09yY2hlc3RyYXRvckNvbnRleHQsXG4gIGV2ZW50SW5kZXg6IG51bWJlciB8IHVuZGVmaW5lZCxcbiAga2luZDogRGVsaXZlcnlLaW5kLFxuICBvcHRpb25zOiB7IGFybWVkPzogYm9vbGVhbiB9ID0ge31cbik6IERlbGl2ZXJ5QmFycmllciB7XG4gIGNvbnN0IGJhcnJpZXJzID0gY3R4LnBlbmRpbmdEZWxpdmVyeUJhcnJpZXJzO1xuICBpZiAoIWJhcnJpZXJzIHx8IGV2ZW50SW5kZXggPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB7IG1hcmtEZWxpdmVyZWQ6ICgpID0+IHt9LCBhcm06ICgpID0+IHt9IH07XG4gIH1cblxuICBsZXQgZG9uZSA9IGZhbHNlO1xuICBjb25zdCB7IHByb21pc2UsIHJlc29sdmUgfSA9IHdpdGhSZXNvbHZlcnM8dm9pZD4oKTtcbiAgY29uc3QgZW50cnk6IERlbGl2ZXJ5QmFycmllckVudHJ5ID0ge1xuICAgIGtpbmQsXG4gICAgZGVsaXZlcmVkOiBwcm9taXNlLFxuICAgIGFybWVkOiBvcHRpb25zLmFybWVkID8/IHRydWUsXG4gIH07XG4gIGJhcnJpZXJzLnNldChldmVudEluZGV4LCBlbnRyeSk7XG5cbiAgY29uc3QgZmluaXNoID0gKCkgPT4ge1xuICAgIGlmIChkb25lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGRvbmUgPSB0cnVlO1xuICAgIGlmIChiYXJyaWVycy5nZXQoZXZlbnRJbmRleCkgPT09IGVudHJ5KSB7XG4gICAgICBiYXJyaWVycy5kZWxldGUoZXZlbnRJbmRleCk7XG4gICAgfVxuICAgIHJlc29sdmUoKTtcbiAgfTtcblxuICAvLyBTYWZldHkgbmV0OiBpZiB0aGlzIGRlbGl2ZXJ5IGlzIG5ldmVyIGRlbGl2ZXJlZCB0byB0aGUgd29ya2Zsb3cgKGl0c1xuICAvLyBicmFuY2ggd2FzIG5vdCB0YWtlbiAvIHRoZSBydW4gaXMgc3VzcGVuZGluZywgb3IgYSBidWZmZXJlZCBob29rIHBheWxvYWRcbiAgLy8gaXMgb25seSBjbGFpbWVkIGFmdGVyIGEgbGF0ZXIgZGVsaXZlcnkgdGhlIHdvcmtmbG93IGlzIHN0aWxsIHdhaXRpbmcgb24pLFxuICAvLyByZXNvbHZlIGF0IGlkbGUgc28gYSBsYXRlciBkZWxpdmVyeSBnYXRlZCBvbiBpdCBjYW5ub3QgZGVhZGxvY2sgYW5kIHRoZVxuICAvLyByZWdpc3RyeSBjYW5ub3QgbGVhayBhbiBlbnRyeSBwZXIgYWJhbmRvbmVkIGRlbGl2ZXJ5LlxuICBzY2hlZHVsZVdoZW5JZGxlKGN0eCwgZmluaXNoKTtcblxuICByZXR1cm4ge1xuICAgIG1hcmtEZWxpdmVyZWQ6IGZpbmlzaCxcbiAgICBhcm06ICgpID0+IHtcbiAgICAgIGVudHJ5LmFybWVkID0gdHJ1ZTtcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIFdoZXRoZXIgc29tZSByZWdpc3RlcmVkIGJyYW5jaC1kZWNpZGluZyBkZWxpdmVyeSBpcyBnb2luZyB0byByZWFjaCB0aGVcbiAqIHdvcmtmbG93IHdpdGhvdXQgYW55IGZ1cnRoZXIgaGVscCAoaXQgaXMgYXJtZWQgYW5kIG5vdCB0cmFuc2l0aXZlbHkgcGFya2VkXG4gKiBiZWhpbmQgYW4gdW5jbGFpbWVkIGJ1ZmZlcmVkIHBheWxvYWQg4oCUIHNlZSB7QGxpbmsgcmVzb2x2ZXNPbkl0c093bn0pIGJ1dFxuICogaGFzIG5vdCBiZWVuIGhhbmRlZCBvdmVyIHlldC5cbiAqXG4gKiBUaGlzIGlzIHRoZSBkZWxpdmVyeSBzdGF0ZSBgcGVuZGluZ0RlbGl2ZXJpZXNgIGNhbm5vdCBzZWUuIFRoYXQgY291bnRlclxuICogY292ZXJzIHRoZSBoeWRyYXRpb24gd2luZG93IGluc2lkZSBhIHNlcmlhbCBgcHJvbWlzZVF1ZXVlYCBzbG90IGFuZCBpc1xuICogcmVsZWFzZWQgdGhlcmUsIHdoaWxlIHRoZSBkZWxpdmVyeSdzIGByZXNvbHZlKClgIHJ1bnMgbGF0ZXIsIGZyb20gYVxuICogZGV0YWNoZWQgY29udGludWF0aW9uIGJlaGluZCB7QGxpbmsgYXdhaXRFYXJsaWVyRGVsaXZlcmllc30g4oCUIGluY2x1ZGluZyBpdHNcbiAqIG1hY3JvdGFzayB5aWVsZCB3aGVuZXZlciB0aGUgZGVsaXZlcnkgaGFkIHRvIGRlZmVyLiBSZXBsYXlpbmcgYSBiYXRjaCBvZiBOXG4gKiBwYXJhbGxlbCBzdGVwIHJlc3VsdHMgY29uc3VtZWQgaW4gb25lIGRyYWluIHdpbmRvdyBsZWF2ZXMgTi0xIG9mIHRoZW1cbiAqIHBhcmtlZCBvbiB0aGF0IHlpZWxkIHdpdGggYHBlbmRpbmdEZWxpdmVyaWVzYCBhbHJlYWR5IGF0IDAuIEFuIGlkbGUgY2hlY2tcbiAqIGFybWVkIGR1cmluZyB0aGUgc2FtZSB3aW5kb3cgKGEgcGVuZGluZyBgc2xlZXAoKWAgYXJtcyBvbmUgb24gZXZlcnkgcmVwbGF5KVxuICogY291bGQgdGhlbiBvYnNlcnZlIFwiaWRsZVwiIG1pZC1kZWZlcnJhbCBhbmQgcmFpc2UgYSBgV29ya2Zsb3dTdXNwZW5zaW9uYFxuICogQkVGT1JFIHRoZSB3b3JrZmxvdydzIG93biBjb250aW51YXRpb25zIHJhbiDigJQgYSBzdXNwZW5zaW9uIGNhcnJ5aW5nIG5vbmUgb2ZcbiAqIHRoZSBmb2xsb3ctdXAgd29yayB0aGUgYmF0Y2ggd2FzIGFib3V0IHRvIGNyZWF0ZSwgd2hpY2ggdGhlIHJ1bnRpbWVcbiAqIGR1dGlmdWxseSBzY2hlZHVsZXMgYXMgbm90aGluZywgbGVhdmluZyB0aGUgcnVuIGRvcm1hbnQgdW50aWwgYW4gdW5yZWxhdGVkXG4gKiB0aW1lciBmaXJlcyAodmVyY2VsL3dvcmtmbG93IzMxODMpLlxuICpcbiAqIERlbGl2ZXJpZXMgdGhhdCBkbyBOT1QgcmVzb2x2ZSBvbiB0aGVpciBvd24gbXVzdCBiZSBleGNsdWRlZCwgbm90IGZvclxuICogYWNjdXJhY3kgYnV0IGZvciB0ZXJtaW5hdGlvbjogYW4gdW5jbGFpbWVkIGJ1ZmZlcmVkIGhvb2sgcGF5bG9hZCBpcyByZXRpcmVkXG4gKiBCWSB0aGUgaWRsZSBzYWZldHkgbmV0IGluIHtAbGluayByZWdpc3RlckRlbGl2ZXJ5QmFycmllcn0sIHNvIGNvdW50aW5nIGl0XG4gKiBoZXJlIHdvdWxkIGdhdGUgaXRzIG93biByZXRpcmVtZW50LiBUaGF0IHJlYXNvbmluZyBleHRlbmRzIHRvIHdoYXRldmVyIGlzXG4gKiBwYXJrZWQgYmVoaW5kIHN1Y2ggYSBwYXlsb2FkIOKAlCBhIHdhaXQsIGFuZCBhIHN0ZXAgZ2F0aW5nIG9uIHRoYXQgd2FpdCDigJQgZm9yXG4gKiB0aGUgc2FtZSByZWFzb246IHRoZSB3aG9sZSBjaGFpbiBtb3ZlcyBvbmx5IG9uY2UgdGhlIG5ldCBmaXJlcywgYW5kIGl0XG4gKiBjYW5ub3QgZmlyZSB3aGlsZSB0aGUgY2hhaW4gaXMgY291bnRlZC4gU2VsZi1yZXNvbHZpbmcgZGVsaXZlcmllcyBhbHdheXNcbiAqIGRlbGl2ZXIgZnJvbSB0aGVpciBvd24gY2hhaW5zIChzZWUgdGhlIElOVkFSSUFOVCBvblxuICoge0BsaW5rIHJlZ2lzdGVyRGVsaXZlcnlCYXJyaWVyfSkgYW5kIG5ldmVyIG5lZWQgdGhhdCBuZXQsIHNvIHdhaXRpbmcgb25cbiAqIHRoZW0gaXMgZGVhZGxvY2stZnJlZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc1BhcmtlZENvbW1pdHRlZERlbGl2ZXJ5KFxuICBjdHg6IFdvcmtmbG93T3JjaGVzdHJhdG9yQ29udGV4dFxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IGJhcnJpZXJzID0gY3R4LnBlbmRpbmdEZWxpdmVyeUJhcnJpZXJzO1xuICBpZiAoIWJhcnJpZXJzIHx8IGJhcnJpZXJzLnNpemUgPT09IDApIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gU2hhcmVkIGFjcm9zcyB0aGlzIGNhbGwgb25seSDigJQgc2VlIGByZXNvbHZlc09uSXRzT3duYC5cbiAgY29uc3Qgc2VsZlJlc29sdmluZyA9IG5ldyBNYXA8bnVtYmVyLCBib29sZWFuPigpO1xuICBmb3IgKGNvbnN0IFtpbmRleCwgZW50cnldIG9mIGJhcnJpZXJzKSB7XG4gICAgaWYgKHJlc29sdmVzT25JdHNPd24oYmFycmllcnMsIGluZGV4LCBlbnRyeSwgc2VsZlJlc29sdmluZykpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogV2hldGhlciBubyBkYXRhIGRlbGl2ZXJ5IChzdGVwIHJlc3VsdCwgaG9vayBwYXlsb2FkKSBpcyBpbiBmbGlnaHQgcmlnaHQgbm93LlxuICpcbiAqIFwiSW4gZmxpZ2h0XCIgaXMgdHdvIGRpc3RpbmN0IHdpbmRvd3MsIGVhY2ggd2l0aCBpdHMgb3duIGd1YXJkOlxuICogYHBlbmRpbmdEZWxpdmVyaWVzID4gMGAgY292ZXJzIGh5ZHJhdGlvbiBpbnNpZGUgdGhlIHNlcmlhbCBxdWV1ZSBzbG90cywgYW5kXG4gKiB7QGxpbmsgaGFzUGFya2VkQ29tbWl0dGVkRGVsaXZlcnl9IGNvdmVycyB0aGUgZGV0YWNoZWQgZ2FwIGJldHdlZW4gYSBzbG90XG4gKiByZWxlYXNpbmcgdGhhdCBjb3VudGVyIGFuZCB0aGUgZGVsaXZlcnkncyBgcmVzb2x2ZSgpYCBhY3R1YWxseSBydW5uaW5nIOKAlFxuICogZGVsaWJlcmF0ZWx5IG91dHNpZGUgYHBlbmRpbmdEZWxpdmVyaWVzYCAoc2VlIHN0ZXAudHMpLCBhbmQgaW52aXNpYmxlIHRvIGl0LlxuICpcbiAqIEFueXRoaW5nIHRoYXQgZGVjaWRlcyBhIHJlcGxheSBpcyBvdmVyLCBvciB0aGF0IGEgcmVwbGF5IHdlbnQgd3JvbmcsIGhhcyB0b1xuICogY29uc3VsdCB0aGlzIGZpcnN0OiB3aGlsZSBpdCBpcyBmYWxzZSB0aGUgd29ya2Zsb3cgVk0gaXMgbWlkLXJlYWN0aW9uLCBzb1xuICogd2hhdCBpdCBoYXMgYW5kIGhhcyBub3QgZG9uZSB5ZXQgc2F5cyBub3RoaW5nIGFib3V0IHRoZSBydW4uIFR3byBjYWxsZXJzXG4gKiByZWFkIGl0LCBmb3IgdGhlIHR3byBzdWNoIGRlY2lzaW9uczoge0BsaW5rIHNjaGVkdWxlV2hlbklkbGV9IGZvciB0aGVcbiAqIHN1c3BlbnNpb24sIGFuZCB0aGUgZXZlbnRzIGNvbnN1bWVyJ3MgdW5jb25zdW1lZC1ldmVudCBjaGVjayBmb3IgZGl2ZXJnZW5jZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRGVsaXZlcnlJZGxlKGN0eDogV29ya2Zsb3dPcmNoZXN0cmF0b3JDb250ZXh0KTogYm9vbGVhbiB7XG4gIHJldHVybiBjdHgucGVuZGluZ0RlbGl2ZXJpZXMgPT09IDAgJiYgIWhhc1BhcmtlZENvbW1pdHRlZERlbGl2ZXJ5KGN0eCk7XG59XG5cbi8qKlxuICogU2NoZWR1bGUgYSBjYWxsYmFjayB0byBmaXJlIG9ubHkgYWZ0ZXIgYWxsIHBlbmRpbmcgZGF0YSBkZWxpdmVyaWVzXG4gKiAoc3RlcCByZXN1bHRzLCBob29rIHBheWxvYWRzKSBhbmQgYXN5bmMgZGVzZXJpYWxpemF0aW9uIGhhdmUgY29tcGxldGVkLlxuICogVXNlcyBhIHBvbGxpbmcgbG9vcDogc2V0VGltZW91dCgwKSDihpIgY2hlY2sgcGVuZGluZ0RlbGl2ZXJpZXMgYW5kIHRoZVxuICogYmFycmllciByZWdpc3RyeSDihpIgaWYgYW55dGhpbmcgaXMgc3RpbGwgaW4gZmxpZ2h0LCB3YWl0IGZvciBwcm9taXNlUXVldWUg4oaSXG4gKiByZXBlYXQuIFRoaXMgaGFuZGxlcyB0aGUgbXVsdGktcm91bmQgZGVsaXZlcnkgcGF0dGVybiB3aGVyZSBlYWNoIGhvb2tcbiAqIHBheWxvYWQgZGVsaXZlcnkgY3ljbGUgYXBwZW5kcyBuZXcgYXN5bmMgd29yayB0byB0aGUgcHJvbWlzZVF1ZXVlLiBXaGF0XG4gKiBjb3VudHMgYXMgaW4gZmxpZ2h0IGlzIHtAbGluayBpc0RlbGl2ZXJ5SWRsZX0uXG4gKlxuICogVGhlIGluaXRpYWwgYHNldFRpbWVvdXQoMClgIG1hY3JvdGFzayBpcyBsb2FkLWJlYXJpbmcgYW5kIG11c3QgTk9UIGJlXG4gKiBkb3duZ3JhZGVkIHRvIGEgbWljcm90YXNrIChgcXVldWVNaWNyb3Rhc2tgL2BQcm9taXNlLnJlc29sdmUoKS50aGVuYCkuXG4gKiBgcGVuZGluZ0RlbGl2ZXJpZXNgIG9ubHkgZ3VhcmRzIHRoZSBob3N0LXNpZGUgaHlkcmF0aW9uIHdpbmRvdzsgYmV0d2VlbiBhXG4gKiBkZWxpdmVyeSdzIGByZXNvbHZlKClgIGFuZCB0aGUgd29ya2Zsb3cgVk0gYm9keSBydW5uaW5nIGl0cyBjb250aW51YXRpb24gdG9cbiAqIHJlZ2lzdGVyIHRoZSBuZXh0IHN1YnNjcmliZXIsIGBwZW5kaW5nRGVsaXZlcmllc2AgaXMgYWxyZWFkeSAwIGV2ZW4gdGhvdWdoXG4gKiB0aGUgVk0gaXMgbWlkLXJlYWN0aW9uLiBOb2RlIGRvZXMgbm90IGd1YXJhbnRlZSBhIG1pY3JvdGFzayBzY2hlZHVsZWQgaW5cbiAqIHRoZSBob3N0IGNvbnRleHQgc2V0dGxlcyBhZnRlciB0aGUgY3Jvc3MtVk0gcHJvbWlzZSBjaGFpbiAocmVzb2x2ZSBpbiBob3N0XG4gKiDihpIgd29ya2Zsb3cgY29kZSBpbiBWTSDihpIgc3Vic2NyaWJlIGJhY2sgaW4gaG9zdCk7IHRoZSBtYWNyb3Rhc2sgYm91bmRhcnlcbiAqIGdpdmVzIHRoYXQgY2hhaW4gdGltZSB0byBydW4sIHNvIHRoZSBzdXNwZW5zaW9uIGRvZXMgbm90IHByZWVtcHQgYSBzaWJsaW5nXG4gKiBkZWxpdmVyeSBzdGlsbCBpbiBmbGlnaHQuIEVtcGlyaWNhbGx5LCByZXBsYWNpbmcgaXQgd2l0aCBgcXVldWVNaWNyb3Rhc2tgXG4gKiBicmVha3MgaG9vay9zbGVlcCBgUHJvbWlzZS5yYWNlYCBvcmRlcmluZyAoQ29ycnVwdGVkRXZlbnRMb2dFcnJvcikuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzY2hlZHVsZVdoZW5JZGxlKFxuICBjdHg6IFdvcmtmbG93T3JjaGVzdHJhdG9yQ29udGV4dCxcbiAgZm46ICgpID0+IHZvaWRcbik6IHZvaWQge1xuICBjb25zdCBjaGVjayA9ICgpID0+IHtcbiAgICBpZiAoIWlzRGVsaXZlcnlJZGxlKGN0eCkpIHtcbiAgICAgIC8vIEEgZGVsaXZlcnkgaXMgc3RpbGwgaHlkcmF0aW5nLCBvciBpcyBjb21taXR0ZWQgYnV0IHBhcmtlZCBiZWhpbmQgaXRzXG4gICAgICAvLyBkZWZlcnJhbCAod2hvc2UgcmVzb2x2ZSBydW5zIG9uIGEgZGV0YWNoZWQgdGltZXIsIG5vdCB0aGlzIHF1ZXVlKS5cbiAgICAgIC8vIEVpdGhlciB3YXk6IGxldCB0aGUgcXVldWUgZHJhaW4sIHRoZW4gcmUtY2hlY2sgYSB0aW1lciB0aWNrIGxhdGVyLlxuICAgICAgY3R4LnByb21pc2VRdWV1ZS50aGVuKCgpID0+IHtcbiAgICAgICAgc2V0VGltZW91dChjaGVjaywgMCk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm4oKTtcbiAgICB9XG4gIH07XG4gIHNldFRpbWVvdXQoY2hlY2ssIDApO1xufVxuIl19
@@ -0,0 +1,68 @@
1
+ import type { Event, WorkflowRun } from '@workflow/world';
2
+ import type { PayloadKey } from './serialization/encryption.js';
3
+ import { type PreparedReplayPayload, type ReplayPayloadPreparer } from './serialization.js';
4
+ type ReplayPayloadField = 'result' | 'error' | 'payload';
5
+ /**
6
+ * Invocation-scoped cache for replay payload hydration.
7
+ *
8
+ * A workflow invocation may replay the same event log through several fresh
9
+ * VMs. This cache keeps the VM-independent decrypt/decompress result across
10
+ * those replays. Deserialization still runs against each VM's globals so every
11
+ * replay receives fresh object graphs and correctly revived Workflow objects.
12
+ *
13
+ * Successful prepared plaintext remains resident for the invocation lifetime.
14
+ * Its memory cost is the sum of decrypted and decompressed payload sizes, but
15
+ * it never crosses workflow runs or queue deliveries.
16
+ */
17
+ export declare class ReplayPayloadCache {
18
+ private readonly encryptionKey;
19
+ private readonly preparer;
20
+ private readonly preparedPayloads;
21
+ private readonly primitiveStepResults;
22
+ private nextUnscannedEventIndex;
23
+ constructor(encryptionKey: PayloadKey | undefined, preparer?: ReplayPayloadPreparer);
24
+ /**
25
+ * Start every missing binary preparation before workflow execution. Failures
26
+ * are intentionally retained: the ordered event consumer must observe the
27
+ * original rejection before that entry becomes retryable.
28
+ */
29
+ prewarm(workflowRun: WorkflowRun, events: Event[]): Promise<void>;
30
+ /**
31
+ * Forget how much of the event log has been scanned, so the next
32
+ * {@link prewarm} walks it from the start again.
33
+ *
34
+ * Required before a replay whose event log was reloaded rather than extended:
35
+ * a corrected log inserts the events the previous load was missing, which
36
+ * shifts every later position, so a positional resume would skip exactly the
37
+ * events the reload was for. Already-prepared payloads are kept — they are
38
+ * keyed by event id, so re-scanning re-observes them for free.
39
+ */
40
+ resetScan(): void;
41
+ /** Return the workflow input after shared host-side preparation. */
42
+ prepareWorkflowInput(workflowRun: WorkflowRun): Promise<PreparedReplayPayload>;
43
+ /**
44
+ * Return an event payload after shared host-side preparation. A rejected
45
+ * preparation is evicted only after this ordered consumer requests it, so a
46
+ * later replay can retry without hiding the original failure.
47
+ */
48
+ prepareEventPayload(eventId: string, field: ReplayPayloadField, value: unknown): Promise<PreparedReplayPayload>;
49
+ /**
50
+ * Reuse final step values only when sharing them across VMs is unobservable.
51
+ * Objects and large strings/bigints always run `hydrate` again, producing a
52
+ * fresh VM-specific value from the separately cached prepared payload.
53
+ */
54
+ getStepResult(eventId: string, hydrate: () => Promise<unknown>): Promise<unknown>;
55
+ /**
56
+ * Consumer-facing lookup. Binary payloads share preparation; legacy values
57
+ * bypass the cache because their flattened representation may be mutated.
58
+ */
59
+ private consumePreparation;
60
+ /** Start preparation once and share the exact in-flight promise. */
61
+ private ensurePreparation;
62
+ /** Normalize synchronous and asynchronous preparers to one promise contract. */
63
+ private runPreparation;
64
+ private workflowInputKey;
65
+ private eventPayloadKey;
66
+ }
67
+ export {};
68
+ //# sourceMappingURL=replay-payload-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay-payload-cache.d.ts","sourceRoot":"","sources":["../src/replay-payload-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EACL,KAAK,qBAAqB,EAE1B,KAAK,qBAAqB,EAC3B,MAAM,oBAAoB,CAAC;AAG5B,KAAK,kBAAkB,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAezD;;;;;;;;;;;GAWG;AACH,qBAAa,kBAAkB;IAS3B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAT3B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAG7B;IACJ,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA8B;IACnE,OAAO,CAAC,uBAAuB,CAAK;gBAGjB,aAAa,EAAE,UAAU,GAAG,SAAS,EACrC,QAAQ,GAAE,qBAA4C;IAGzE;;;;OAIG;IACG,OAAO,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAwDvE;;;;;;;;;OASG;IACH,SAAS,IAAI,IAAI;IAIjB,oEAAoE;IACpE,oBAAoB,CAClB,WAAW,EAAE,WAAW,GACvB,OAAO,CAAC,qBAAqB,CAAC;IAOjC;;;;OAIG;IACH,mBAAmB,CACjB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,kBAAkB,EACzB,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,qBAAqB,CAAC;IAIjC;;;;OAIG;IACG,aAAa,CACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAC9B,OAAO,CAAC,OAAO,CAAC;IAYnB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAe1B,oEAAoE;IACpE,OAAO,CAAC,iBAAiB;IAYzB,gFAAgF;YAClE,cAAc;IAI5B,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,eAAe;CAGxB"}