footprintjs 10.0.1 → 10.2.0

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 (368) hide show
  1. package/AGENTS.md +2 -1
  2. package/CLAUDE.md +61 -7
  3. package/README.md +136 -312
  4. package/dist/esm/index.d.ts +62 -2
  5. package/dist/esm/index.js +13 -6
  6. package/dist/esm/lib/attempt/anySignal.d.ts +19 -0
  7. package/dist/esm/lib/attempt/anySignal.js +39 -0
  8. package/dist/esm/lib/attempt/call.d.ts +88 -0
  9. package/dist/esm/lib/attempt/call.js +129 -0
  10. package/dist/esm/lib/attempt/category.d.ts +37 -0
  11. package/dist/esm/lib/attempt/category.js +131 -0
  12. package/dist/esm/lib/attempt/correlation.d.ts +95 -0
  13. package/dist/esm/lib/attempt/correlation.js +178 -0
  14. package/dist/esm/lib/attempt/deadline.d.ts +44 -0
  15. package/dist/esm/lib/attempt/deadline.js +101 -0
  16. package/dist/esm/lib/attempt/decision.d.ts +52 -0
  17. package/dist/esm/lib/attempt/decision.js +134 -0
  18. package/dist/esm/lib/attempt/effect.d.ts +76 -0
  19. package/dist/esm/lib/attempt/effect.js +160 -0
  20. package/dist/esm/lib/attempt/errors.d.ts +41 -0
  21. package/dist/esm/lib/attempt/errors.js +44 -0
  22. package/dist/esm/lib/attempt/index.d.ts +18 -0
  23. package/dist/esm/lib/attempt/index.js +15 -0
  24. package/dist/esm/lib/attempt/name.d.ts +21 -0
  25. package/dist/esm/lib/attempt/name.js +43 -0
  26. package/dist/esm/lib/attempt/observed.d.ts +66 -0
  27. package/dist/esm/lib/attempt/observed.js +171 -0
  28. package/dist/esm/lib/attempt/policy.d.ts +45 -0
  29. package/dist/esm/lib/attempt/policy.js +83 -0
  30. package/dist/esm/lib/attempt/record.d.ts +11 -0
  31. package/dist/esm/lib/attempt/record.js +24 -0
  32. package/dist/esm/lib/attempt/retryLoopContext.d.ts +18 -0
  33. package/dist/esm/lib/attempt/retryLoopContext.js +24 -0
  34. package/dist/esm/lib/attempt/retryLoopTypes.d.ts +18 -0
  35. package/dist/esm/lib/attempt/retryLoopTypes.js +2 -0
  36. package/dist/esm/lib/attempt/runner.d.ts +157 -0
  37. package/dist/esm/lib/attempt/runner.js +523 -0
  38. package/dist/esm/lib/attempt/standalone.d.ts +47 -0
  39. package/dist/esm/lib/attempt/standalone.js +126 -0
  40. package/dist/esm/lib/attempt/types.d.ts +453 -0
  41. package/dist/esm/lib/attempt/types.js +16 -0
  42. package/dist/esm/lib/budget/index.d.ts +9 -0
  43. package/dist/esm/lib/budget/index.js +9 -0
  44. package/dist/esm/lib/budget/timeBudget.d.ts +136 -0
  45. package/dist/esm/lib/budget/timeBudget.js +666 -0
  46. package/dist/esm/lib/builder/FlowChartBuilder.d.ts +88 -3
  47. package/dist/esm/lib/builder/FlowChartBuilder.js +199 -9
  48. package/dist/esm/lib/builder/retryLoop.d.ts +56 -0
  49. package/dist/esm/lib/builder/retryLoop.js +283 -0
  50. package/dist/esm/lib/builder/types.d.ts +35 -1
  51. package/dist/esm/lib/builder/types.js +1 -1
  52. package/dist/esm/lib/decide/decide.js +2 -2
  53. package/dist/esm/lib/decide/index.d.ts +1 -1
  54. package/dist/esm/lib/decide/index.js +2 -2
  55. package/dist/esm/lib/decide/types.d.ts +3 -0
  56. package/dist/esm/lib/decide/types.js +1 -8
  57. package/dist/esm/lib/engine/graph/StageNode.d.ts +11 -1
  58. package/dist/esm/lib/engine/graph/StageNode.js +1 -1
  59. package/dist/esm/lib/engine/graph/prefixNodeTree.js +5 -1
  60. package/dist/esm/lib/engine/handlers/ChildrenExecutor.js +36 -6
  61. package/dist/esm/lib/engine/handlers/DeciderHandler.js +9 -5
  62. package/dist/esm/lib/engine/handlers/ResumeEntry.js +3 -1
  63. package/dist/esm/lib/engine/handlers/SelectorHandler.js +6 -5
  64. package/dist/esm/lib/engine/handlers/StageRunner.d.ts +8 -1
  65. package/dist/esm/lib/engine/handlers/StageRunner.js +36 -9
  66. package/dist/esm/lib/engine/handlers/SubflowExecutor.js +24 -5
  67. package/dist/esm/lib/engine/handlers/commitStage.d.ts +7 -0
  68. package/dist/esm/lib/engine/handlers/commitStage.js +22 -4
  69. package/dist/esm/lib/engine/handlers/stageError.d.ts +9 -0
  70. package/dist/esm/lib/engine/handlers/stageError.js +23 -1
  71. package/dist/esm/lib/engine/index.d.ts +2 -2
  72. package/dist/esm/lib/engine/index.js +1 -1
  73. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +27 -13
  74. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +68 -40
  75. package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.d.ts +4 -1
  76. package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.js +19 -2
  77. package/dist/esm/lib/engine/narrative/NarrativeFlowRecorder.d.ts +22 -3
  78. package/dist/esm/lib/engine/narrative/NarrativeFlowRecorder.js +61 -9
  79. package/dist/esm/lib/engine/narrative/NullControlFlowNarrativeGenerator.d.ts +1 -0
  80. package/dist/esm/lib/engine/narrative/NullControlFlowNarrativeGenerator.js +2 -1
  81. package/dist/esm/lib/engine/narrative/formatting/sentences.d.ts +23 -0
  82. package/dist/esm/lib/engine/narrative/formatting/sentences.js +127 -1
  83. package/dist/esm/lib/engine/narrative/index.d.ts +2 -2
  84. package/dist/esm/lib/engine/narrative/index.js +1 -1
  85. package/dist/esm/lib/engine/narrative/narrativeTypes.d.ts +27 -21
  86. package/dist/esm/lib/engine/narrative/narrativeTypes.js +1 -1
  87. package/dist/esm/lib/engine/narrative/recorders/ManifestFlowRecorder.d.ts +45 -2
  88. package/dist/esm/lib/engine/narrative/recorders/ManifestFlowRecorder.js +55 -2
  89. package/dist/esm/lib/engine/narrative/recorders/index.d.ts +1 -1
  90. package/dist/esm/lib/engine/narrative/recorders/index.js +1 -1
  91. package/dist/esm/lib/engine/narrative/types.d.ts +74 -5
  92. package/dist/esm/lib/engine/narrative/types.js +1 -1
  93. package/dist/esm/lib/engine/traversal/FlowchartTraverser.d.ts +59 -19
  94. package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +194 -118
  95. package/dist/esm/lib/engine/traversalContext.d.ts +7 -2
  96. package/dist/esm/lib/engine/traversalContext.js +6 -3
  97. package/dist/esm/lib/engine/types.d.ts +52 -57
  98. package/dist/esm/lib/engine/types.js +1 -1
  99. package/dist/esm/lib/errors/terminalFailure.d.ts +29 -0
  100. package/dist/esm/lib/errors/terminalFailure.js +60 -0
  101. package/dist/esm/lib/{decide → filter}/evaluator.d.ts +7 -2
  102. package/dist/esm/lib/filter/evaluator.js +135 -0
  103. package/dist/esm/lib/ids/idempotencyKey.d.ts +14 -0
  104. package/dist/esm/lib/ids/idempotencyKey.js +24 -0
  105. package/dist/esm/lib/memory/StageContext.d.ts +123 -3
  106. package/dist/esm/lib/memory/StageContext.js +245 -4
  107. package/dist/esm/lib/memory/attention.d.ts +26 -0
  108. package/dist/esm/lib/memory/attention.js +171 -0
  109. package/dist/esm/lib/memory/borrowedMutation.d.ts +8 -0
  110. package/dist/esm/lib/memory/borrowedMutation.js +14 -1
  111. package/dist/esm/lib/memory/frameTypes.d.ts +38 -0
  112. package/dist/esm/lib/memory/frameTypes.js +3 -1
  113. package/dist/esm/lib/memory/redaction.d.ts +12 -0
  114. package/dist/esm/lib/memory/redaction.js +54 -5
  115. package/dist/esm/lib/pause/record.js +10 -1
  116. package/dist/esm/lib/pause/types.d.ts +19 -0
  117. package/dist/esm/lib/pause/types.js +17 -1
  118. package/dist/esm/lib/reactive/createTypedScope.js +3 -1
  119. package/dist/esm/lib/reactive/types.d.ts +36 -4
  120. package/dist/esm/lib/reactive/types.js +3 -1
  121. package/dist/esm/lib/recorder/AttemptRecorder.d.ts +141 -0
  122. package/dist/esm/lib/recorder/AttemptRecorder.js +412 -0
  123. package/dist/esm/lib/recorder/ControlDepRecorder.d.ts +36 -2
  124. package/dist/esm/lib/recorder/ControlDepRecorder.js +50 -2
  125. package/dist/esm/lib/recorder/EmitRecorder.d.ts +3 -0
  126. package/dist/esm/lib/recorder/EmitRecorder.js +1 -1
  127. package/dist/esm/lib/recorder/InOutRecorder.d.ts +37 -1
  128. package/dist/esm/lib/recorder/InOutRecorder.js +75 -6
  129. package/dist/esm/lib/recorder/QualityRecorder.d.ts +32 -5
  130. package/dist/esm/lib/recorder/QualityRecorder.js +87 -29
  131. package/dist/esm/lib/recorder/TopologyRecorder.d.ts +35 -5
  132. package/dist/esm/lib/recorder/TopologyRecorder.js +76 -2
  133. package/dist/esm/lib/recorder/attemptMetricRows.d.ts +11 -0
  134. package/dist/esm/lib/recorder/attemptMetricRows.js +202 -0
  135. package/dist/esm/lib/recorder/attemptMetrics.d.ts +7 -0
  136. package/dist/esm/lib/recorder/attemptMetrics.js +165 -0
  137. package/dist/esm/lib/recorder/attemptMetricsTypes.d.ts +114 -0
  138. package/dist/esm/lib/recorder/attemptMetricsTypes.js +2 -0
  139. package/dist/esm/lib/recorder/attemptOTel.d.ts +78 -0
  140. package/dist/esm/lib/recorder/attemptOTel.js +107 -0
  141. package/dist/esm/lib/recorder/attemptSeries.d.ts +81 -0
  142. package/dist/esm/lib/recorder/attemptSeries.js +103 -0
  143. package/dist/esm/lib/recorder/hooks.d.ts +9 -0
  144. package/dist/esm/lib/recorder/hooks.js +4 -1
  145. package/dist/esm/lib/runner/DeferredObserverTier.js +13 -1
  146. package/dist/esm/lib/runner/ExecutionRuntime.d.ts +54 -6
  147. package/dist/esm/lib/runner/ExecutionRuntime.js +57 -5
  148. package/dist/esm/lib/runner/FlowChartExecutor.d.ts +46 -2
  149. package/dist/esm/lib/runner/FlowChartExecutor.js +330 -101
  150. package/dist/esm/lib/runner/RunnableChart.d.ts +6 -0
  151. package/dist/esm/lib/runner/RunnableChart.js +5 -1
  152. package/dist/esm/lib/runner/attach.d.ts +2 -1
  153. package/dist/esm/lib/runner/attach.js +8 -2
  154. package/dist/esm/lib/runner/checkpoint.js +3 -1
  155. package/dist/esm/lib/runner/deadline.d.ts +42 -0
  156. package/dist/esm/lib/runner/deadline.js +90 -0
  157. package/dist/esm/lib/runner/index.d.ts +3 -1
  158. package/dist/esm/lib/runner/index.js +2 -1
  159. package/dist/esm/lib/runner/options.d.ts +17 -0
  160. package/dist/esm/lib/runner/options.js +3 -1
  161. package/dist/esm/lib/runner/recordSink.d.ts +128 -0
  162. package/dist/esm/lib/runner/recordSink.js +296 -0
  163. package/dist/esm/lib/runner/resume.d.ts +3 -0
  164. package/dist/esm/lib/runner/resume.js +22 -2
  165. package/dist/esm/lib/runner/snapshot.d.ts +2 -2
  166. package/dist/esm/lib/runner/snapshot.js +6 -2
  167. package/dist/esm/lib/scope/ScopeFacade.d.ts +118 -4
  168. package/dist/esm/lib/scope/ScopeFacade.js +304 -7
  169. package/dist/esm/lib/scope/recorders/DebugRecorder.d.ts +17 -3
  170. package/dist/esm/lib/scope/recorders/DebugRecorder.js +79 -13
  171. package/dist/esm/lib/scope/recorders/MetricRecorder.d.ts +10 -0
  172. package/dist/esm/lib/scope/recorders/MetricRecorder.js +15 -2
  173. package/dist/esm/lib/scope/runtime.d.ts +3 -0
  174. package/dist/esm/lib/scope/runtime.js +1 -1
  175. package/dist/esm/lib/scope/types.d.ts +6 -0
  176. package/dist/esm/lib/scope/types.js +1 -1
  177. package/dist/esm/lib/sinks/fileSink.d.ts +135 -0
  178. package/dist/esm/lib/sinks/fileSink.js +387 -0
  179. package/dist/esm/recorders.d.ts +8 -2
  180. package/dist/esm/recorders.js +7 -1
  181. package/dist/esm/sinks.d.ts +23 -0
  182. package/dist/esm/sinks.js +23 -0
  183. package/dist/esm/trace.d.ts +2 -2
  184. package/dist/esm/trace.js +1 -1
  185. package/dist/index.js +77 -60
  186. package/dist/lib/attempt/anySignal.js +43 -0
  187. package/dist/lib/attempt/call.js +134 -0
  188. package/dist/lib/attempt/category.js +136 -0
  189. package/dist/lib/attempt/correlation.js +186 -0
  190. package/dist/lib/attempt/deadline.js +112 -0
  191. package/dist/lib/attempt/decision.js +139 -0
  192. package/dist/lib/attempt/effect.js +174 -0
  193. package/dist/lib/attempt/errors.js +49 -0
  194. package/dist/lib/attempt/index.js +26 -0
  195. package/dist/lib/attempt/name.js +48 -0
  196. package/dist/lib/attempt/observed.js +177 -0
  197. package/dist/lib/attempt/policy.js +92 -0
  198. package/dist/lib/attempt/record.js +29 -0
  199. package/dist/lib/attempt/retryLoopContext.js +31 -0
  200. package/dist/lib/attempt/retryLoopTypes.js +3 -0
  201. package/dist/lib/attempt/runner.js +530 -0
  202. package/dist/lib/attempt/standalone.js +130 -0
  203. package/dist/lib/attempt/types.js +17 -0
  204. package/dist/lib/budget/index.js +17 -0
  205. package/dist/lib/budget/timeBudget.js +674 -0
  206. package/dist/lib/builder/FlowChartBuilder.js +199 -9
  207. package/dist/lib/builder/retryLoop.js +287 -0
  208. package/dist/lib/builder/types.js +1 -1
  209. package/dist/lib/decide/decide.js +2 -2
  210. package/dist/lib/decide/index.js +2 -2
  211. package/dist/lib/decide/types.js +1 -8
  212. package/dist/lib/engine/graph/StageNode.js +1 -1
  213. package/dist/lib/engine/graph/prefixNodeTree.js +5 -1
  214. package/dist/lib/engine/handlers/ChildrenExecutor.js +36 -6
  215. package/dist/lib/engine/handlers/DeciderHandler.js +7 -3
  216. package/dist/lib/engine/handlers/ResumeEntry.js +3 -1
  217. package/dist/lib/engine/handlers/SelectorHandler.js +4 -3
  218. package/dist/lib/engine/handlers/StageRunner.js +36 -9
  219. package/dist/lib/engine/handlers/SubflowExecutor.js +24 -5
  220. package/dist/lib/engine/handlers/commitStage.js +24 -5
  221. package/dist/lib/engine/handlers/stageError.js +26 -2
  222. package/dist/lib/engine/index.js +1 -1
  223. package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +67 -39
  224. package/dist/lib/engine/narrative/FlowRecorderDispatcher.js +19 -2
  225. package/dist/lib/engine/narrative/NarrativeFlowRecorder.js +60 -8
  226. package/dist/lib/engine/narrative/NullControlFlowNarrativeGenerator.js +2 -1
  227. package/dist/lib/engine/narrative/formatting/sentences.js +131 -2
  228. package/dist/lib/engine/narrative/index.js +1 -1
  229. package/dist/lib/engine/narrative/narrativeTypes.js +1 -1
  230. package/dist/lib/engine/narrative/recorders/ManifestFlowRecorder.js +55 -2
  231. package/dist/lib/engine/narrative/recorders/index.js +1 -1
  232. package/dist/lib/engine/narrative/types.js +1 -1
  233. package/dist/lib/engine/traversal/FlowchartTraverser.js +192 -116
  234. package/dist/lib/engine/traversalContext.js +6 -3
  235. package/dist/lib/engine/types.js +1 -1
  236. package/dist/lib/errors/terminalFailure.js +64 -0
  237. package/dist/lib/filter/evaluator.js +139 -0
  238. package/dist/lib/ids/idempotencyKey.js +28 -0
  239. package/dist/lib/memory/StageContext.js +246 -5
  240. package/dist/lib/memory/attention.js +175 -0
  241. package/dist/lib/memory/borrowedMutation.js +16 -2
  242. package/dist/lib/memory/frameTypes.js +3 -1
  243. package/dist/lib/memory/redaction.js +54 -5
  244. package/dist/lib/pause/record.js +10 -1
  245. package/dist/lib/pause/types.js +17 -1
  246. package/dist/lib/reactive/createTypedScope.js +3 -1
  247. package/dist/lib/reactive/types.js +3 -1
  248. package/dist/lib/recorder/AttemptRecorder.js +417 -0
  249. package/dist/lib/recorder/ControlDepRecorder.js +50 -2
  250. package/dist/lib/recorder/EmitRecorder.js +1 -1
  251. package/dist/lib/recorder/InOutRecorder.js +75 -6
  252. package/dist/lib/recorder/QualityRecorder.js +87 -29
  253. package/dist/lib/recorder/TopologyRecorder.js +76 -2
  254. package/dist/lib/recorder/attemptMetricRows.js +209 -0
  255. package/dist/lib/recorder/attemptMetrics.js +174 -0
  256. package/dist/lib/recorder/attemptMetricsTypes.js +3 -0
  257. package/dist/lib/recorder/attemptOTel.js +111 -0
  258. package/dist/lib/recorder/attemptSeries.js +113 -0
  259. package/dist/lib/recorder/hooks.js +4 -1
  260. package/dist/lib/runner/DeferredObserverTier.js +13 -1
  261. package/dist/lib/runner/ExecutionRuntime.js +57 -5
  262. package/dist/lib/runner/FlowChartExecutor.js +330 -101
  263. package/dist/lib/runner/RunnableChart.js +5 -1
  264. package/dist/lib/runner/attach.js +8 -2
  265. package/dist/lib/runner/checkpoint.js +3 -1
  266. package/dist/lib/runner/deadline.js +94 -0
  267. package/dist/lib/runner/index.js +4 -2
  268. package/dist/lib/runner/options.js +3 -1
  269. package/dist/lib/runner/recordSink.js +302 -0
  270. package/dist/lib/runner/resume.js +22 -2
  271. package/dist/lib/runner/snapshot.js +6 -2
  272. package/dist/lib/scope/ScopeFacade.js +303 -6
  273. package/dist/lib/scope/recorders/DebugRecorder.js +79 -13
  274. package/dist/lib/scope/recorders/MetricRecorder.js +15 -2
  275. package/dist/lib/scope/runtime.js +1 -1
  276. package/dist/lib/scope/types.js +1 -1
  277. package/dist/lib/sinks/fileSink.js +392 -0
  278. package/dist/recorders.js +10 -2
  279. package/dist/sinks.js +32 -0
  280. package/dist/trace.js +1 -1
  281. package/dist/types/index.d.ts +62 -2
  282. package/dist/types/lib/attempt/anySignal.d.ts +19 -0
  283. package/dist/types/lib/attempt/call.d.ts +88 -0
  284. package/dist/types/lib/attempt/category.d.ts +37 -0
  285. package/dist/types/lib/attempt/correlation.d.ts +95 -0
  286. package/dist/types/lib/attempt/deadline.d.ts +44 -0
  287. package/dist/types/lib/attempt/decision.d.ts +52 -0
  288. package/dist/types/lib/attempt/effect.d.ts +76 -0
  289. package/dist/types/lib/attempt/errors.d.ts +41 -0
  290. package/dist/types/lib/attempt/index.d.ts +18 -0
  291. package/dist/types/lib/attempt/name.d.ts +21 -0
  292. package/dist/types/lib/attempt/observed.d.ts +66 -0
  293. package/dist/types/lib/attempt/policy.d.ts +45 -0
  294. package/dist/types/lib/attempt/record.d.ts +11 -0
  295. package/dist/types/lib/attempt/retryLoopContext.d.ts +18 -0
  296. package/dist/types/lib/attempt/retryLoopTypes.d.ts +18 -0
  297. package/dist/types/lib/attempt/runner.d.ts +157 -0
  298. package/dist/types/lib/attempt/standalone.d.ts +47 -0
  299. package/dist/types/lib/attempt/types.d.ts +453 -0
  300. package/dist/types/lib/budget/index.d.ts +9 -0
  301. package/dist/types/lib/budget/timeBudget.d.ts +136 -0
  302. package/dist/types/lib/builder/FlowChartBuilder.d.ts +88 -3
  303. package/dist/types/lib/builder/retryLoop.d.ts +56 -0
  304. package/dist/types/lib/builder/types.d.ts +35 -1
  305. package/dist/types/lib/decide/index.d.ts +1 -1
  306. package/dist/types/lib/decide/types.d.ts +3 -0
  307. package/dist/types/lib/engine/graph/StageNode.d.ts +11 -1
  308. package/dist/types/lib/engine/handlers/StageRunner.d.ts +8 -1
  309. package/dist/types/lib/engine/handlers/commitStage.d.ts +7 -0
  310. package/dist/types/lib/engine/handlers/stageError.d.ts +9 -0
  311. package/dist/types/lib/engine/index.d.ts +2 -2
  312. package/dist/types/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +27 -13
  313. package/dist/types/lib/engine/narrative/FlowRecorderDispatcher.d.ts +4 -1
  314. package/dist/types/lib/engine/narrative/NarrativeFlowRecorder.d.ts +22 -3
  315. package/dist/types/lib/engine/narrative/NullControlFlowNarrativeGenerator.d.ts +1 -0
  316. package/dist/types/lib/engine/narrative/formatting/sentences.d.ts +23 -0
  317. package/dist/types/lib/engine/narrative/index.d.ts +2 -2
  318. package/dist/types/lib/engine/narrative/narrativeTypes.d.ts +27 -21
  319. package/dist/types/lib/engine/narrative/recorders/ManifestFlowRecorder.d.ts +45 -2
  320. package/dist/types/lib/engine/narrative/recorders/index.d.ts +1 -1
  321. package/dist/types/lib/engine/narrative/types.d.ts +74 -5
  322. package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +59 -19
  323. package/dist/types/lib/engine/traversalContext.d.ts +7 -2
  324. package/dist/types/lib/engine/types.d.ts +52 -57
  325. package/dist/types/lib/errors/terminalFailure.d.ts +29 -0
  326. package/dist/types/lib/{decide → filter}/evaluator.d.ts +7 -2
  327. package/dist/types/lib/ids/idempotencyKey.d.ts +14 -0
  328. package/dist/types/lib/memory/StageContext.d.ts +123 -3
  329. package/dist/types/lib/memory/attention.d.ts +26 -0
  330. package/dist/types/lib/memory/borrowedMutation.d.ts +8 -0
  331. package/dist/types/lib/memory/frameTypes.d.ts +38 -0
  332. package/dist/types/lib/memory/redaction.d.ts +12 -0
  333. package/dist/types/lib/pause/types.d.ts +19 -0
  334. package/dist/types/lib/reactive/types.d.ts +36 -4
  335. package/dist/types/lib/recorder/AttemptRecorder.d.ts +141 -0
  336. package/dist/types/lib/recorder/ControlDepRecorder.d.ts +36 -2
  337. package/dist/types/lib/recorder/EmitRecorder.d.ts +3 -0
  338. package/dist/types/lib/recorder/InOutRecorder.d.ts +37 -1
  339. package/dist/types/lib/recorder/QualityRecorder.d.ts +32 -5
  340. package/dist/types/lib/recorder/TopologyRecorder.d.ts +35 -5
  341. package/dist/types/lib/recorder/attemptMetricRows.d.ts +11 -0
  342. package/dist/types/lib/recorder/attemptMetrics.d.ts +7 -0
  343. package/dist/types/lib/recorder/attemptMetricsTypes.d.ts +114 -0
  344. package/dist/types/lib/recorder/attemptOTel.d.ts +78 -0
  345. package/dist/types/lib/recorder/attemptSeries.d.ts +81 -0
  346. package/dist/types/lib/recorder/hooks.d.ts +9 -0
  347. package/dist/types/lib/runner/ExecutionRuntime.d.ts +54 -6
  348. package/dist/types/lib/runner/FlowChartExecutor.d.ts +46 -2
  349. package/dist/types/lib/runner/RunnableChart.d.ts +6 -0
  350. package/dist/types/lib/runner/attach.d.ts +2 -1
  351. package/dist/types/lib/runner/deadline.d.ts +42 -0
  352. package/dist/types/lib/runner/index.d.ts +3 -1
  353. package/dist/types/lib/runner/options.d.ts +17 -0
  354. package/dist/types/lib/runner/recordSink.d.ts +128 -0
  355. package/dist/types/lib/runner/resume.d.ts +3 -0
  356. package/dist/types/lib/runner/snapshot.d.ts +2 -2
  357. package/dist/types/lib/scope/ScopeFacade.d.ts +118 -4
  358. package/dist/types/lib/scope/recorders/DebugRecorder.d.ts +17 -3
  359. package/dist/types/lib/scope/recorders/MetricRecorder.d.ts +10 -0
  360. package/dist/types/lib/scope/runtime.d.ts +3 -0
  361. package/dist/types/lib/scope/types.d.ts +6 -0
  362. package/dist/types/lib/sinks/fileSink.d.ts +135 -0
  363. package/dist/types/recorders.d.ts +8 -2
  364. package/dist/types/sinks.d.ts +23 -0
  365. package/dist/types/trace.d.ts +2 -2
  366. package/package.json +20 -6
  367. package/dist/esm/lib/decide/evaluator.js +0 -130
  368. package/dist/lib/decide/evaluator.js +0 -134
@@ -0,0 +1,523 @@
1
+ /**
2
+ * attempt/runner.ts — `runAttempts`, THE retry loop (design §3.1, law 1: one runner, one record).
3
+ *
4
+ * Runs a function under a policy and records every try: one frozen `AttemptRecord` per attempt, carrying its
5
+ * timing, outcome, failure category and the retry-or-stop decision (`attempt/decision.ts`), and one
6
+ * `AttemptSummary` when the series ends. The engine's stage retry (`FlowchartTraverser · executeStage`) runs on
7
+ * it; later packets run in-stage calls and standalone `attempt()` on it too.
8
+ *
9
+ * The loop, per attempt n — for a failed attempt, the 9.15 loop's order, step for step:
10
+ *
11
+ * start → run(n) → outcome (ok | failed | aborted [it threw the run's abort reason] | paused [a PauseSignal])
12
+ * → decide over the inputs, first match wins (`retryRules`) — retryOn is asked here (rule 5)
13
+ * → the run's signal aborted inside retryOn? decide again: rule 3 stops the series here, before the
14
+ * discard and before backoffMs, as the 9.15 abort check did
15
+ * → retry: between(n) — the discard — and THEN backoffMs(n), the wait's length
16
+ * → the error's served form and category, read after retryOn and backoffMs ran → the record
17
+ * → onEnd(summary) only when the series ends here
18
+ * → onAttempt(record, served error)
19
+ * → done: return the value · stop: rethrow the attempt's OWN error
20
+ * → retry: onRetry(n, of, delay, served error) → wait (cut short by the signal) → aborted? stop
21
+ *
22
+ * WHAT IT PRESERVES (the 9.15 loop's behaviour, moved here unchanged): the function runs the same number of
23
+ * times; `retryOn` is asked only for a failed, non-final attempt; `backoffMs` only when a retry follows, after
24
+ * the discard; a throwing predicate is "do not retry", a throwing or non-finite backoff is "no wait"; a pause is
25
+ * never retried; the attempt's own error is rethrown, never a wrapper; and a failed attempt's order —
26
+ * `retryOn` → the abort check → the discard (`between`) → `backoffMs` → the served error → the retry event →
27
+ * the wait → the abort check. So an abort inside `retryOn` stops before the discard and never asks `backoffMs`;
28
+ * an abort inside `backoffMs` comes after the discard, still fires the retry event, then ends at the wait; and
29
+ * the served error shows what `retryOn` did to the thrown value. The one difference: when the run's signal has
30
+ * ALREADY aborted as the attempt fails, the series stops without asking `retryOn` (the abort decides first —
31
+ * rule 3 before rule 5).
32
+ *
33
+ * WHAT IT ADDS: the record and the summary. A record is frozen to its leaves and holds only clone-safe data —
34
+ * the error as the run SERVES it (`serve`, the redaction rule's form) without `raw`. The hook gets the served
35
+ * `StructuredErrorInfo` whole, `raw` included, as `onStageRetry` always has. A record never rewrites what the
36
+ * attempt did: an attempt that threw its own error is `failed`, with its category, even when the run aborted
37
+ * around it — the abort is the series' stop reason (`reason: 'aborted'`); a throwing `retryOn` is `declined`
38
+ * with `retryOnThrew: true`, apart from a real `false`.
39
+ *
40
+ * TIME (P1b). Each attempt runs under `min(policy.timeoutMs, time left before options.deadline)` and gets an
41
+ * `AttemptContext` — its signal, composed from the run's and its own cap's timer (`LiveAttempt`). The cap's timer
42
+ * aborts with an `AttemptTimeoutError`; the run's deadline aborts the run's signal with a branded reason
43
+ * (`attempt/deadline.ts`). Either way the attempt is `'timeout'`, never `'aborted'`: the deadline is not a
44
+ * cancellation, so rule 3 does not match and rule 6 (`timeLeftAfterWaitMs ≤ 0`) stops a series whose next wait
45
+ * would outlast it. Under a deadline rule 6 needs the wait's length, so `backoffMs(n, error)` is asked DURING the
46
+ * decision — before the discard; without one the 9.15 order above holds unchanged. No attempt starts at or past
47
+ * the deadline: a wait the deadline cut ends the series `no-time-left`, recording no further attempt.
48
+ *
49
+ * THE FENCE. The moment an attempt ends without an answer — its signal aborts (synchronously, before any listener
50
+ * the function added) or it throws — `onAbandon(n)` fires once, and the engine closes that attempt's scope: the
51
+ * function may still be running, and nothing it does afterwards may land beside a later attempt.
52
+ *
53
+ * ONE async frame with ONE await per attempt: the engine relies on that to keep a retried stage's microtask
54
+ * shape, so parallel siblings settle in the order they always did. The engine races the attempt's signal itself,
55
+ * at the stage boundary (`raced: true`); any other caller gets the race here, so the series never waits on an
56
+ * attempt past its cap.
57
+ *
58
+ * CALLS (P2). The same loop runs a call a stage makes (`attempt/call.ts · runCall`, kind `'call'`, its `target` on
59
+ * every record) and the standalone `attempt()`. An attempt's cap is the DEADLINE of every call made inside it, so
60
+ * the cap's reason is branded a time limit (`attempt/deadline.ts · markTimeLimit`): a call cut by its stage
61
+ * attempt's cap timed out, it was not cancelled. `attemptEndsAt` says when an attempt must end; an `interrupt()`
62
+ * thrown inside a call is a pause, like a `PauseSignal` — never retried.
63
+ */
64
+ import { extractErrorInfo } from '../errors/errorInfo.js';
65
+ import { isInterruptSignal } from '../pause/interrupt.js';
66
+ import { isPauseSignal } from '../pause/types.js';
67
+ import { anySignal } from './anySignal.js';
68
+ import { errorCategory, terminalCategory } from './category.js';
69
+ import { isCancelled, isDeadlineReason, markTimeLimit, readDeadline, setLongTimeout } from './deadline.js';
70
+ import { decideAttempt, retryRules } from './decision.js';
71
+ import { effectOf, recordedKeyOf, refuseKeylessRetry, unknownEffectError } from './effect.js';
72
+ import { AttemptTimeoutError } from './errors.js';
73
+ import { attemptCeiling, attemptTimeoutMs, cappedWaitMs } from './policy.js';
74
+ import { freezeDeep, recordedError } from './record.js';
75
+ /** When each live attempt must end, epoch ms — `startedAt + cap`, for an attempt that has a cap (`attemptEndsAt`). */
76
+ const ATTEMPT_ENDS = new WeakMap();
77
+ /**
78
+ * When the attempt behind `context` must end, epoch milliseconds — its start plus its cap (`min(timeoutMs, time
79
+ * left)`, so never past the run's deadline) — or `undefined` for an uncapped attempt. A call made inside the
80
+ * attempt runs under it as its deadline (`attempt/call.ts`). Only the runner's own contexts are known.
81
+ */
82
+ export function attemptEndsAt(context) {
83
+ return context === undefined ? undefined : ATTEMPT_ENDS.get(context);
84
+ }
85
+ /**
86
+ * Run `run` until it succeeds or the policy stops it; resolve with its value or reject with the LAST attempt's
87
+ * own error. `run(n)` is called with the attempt number, 1-based.
88
+ */
89
+ export async function runAttempts(run, policy, options) {
90
+ const of = attemptCeiling(policy.attempts);
91
+ const rules = retryRules({ attempts: of });
92
+ const now = options.now ?? Date.now;
93
+ const deadline = readDeadline(options.deadline);
94
+ const ownCap = attemptTimeoutMs(policy.timeoutMs);
95
+ const tally = new SeriesTally();
96
+ if (options.effect)
97
+ refuseKeylessRetry(options.effect, of);
98
+ /** An earlier attempt of this touching series left the effect unknown — a later answer of `none` cannot clear it. */
99
+ let unknownSoFar = false;
100
+ for (let attempt = 1;; attempt++) {
101
+ const startedAt = now();
102
+ const live = new LiveAttempt(options, attempt, of, startedAt, deadline, ownCap, now);
103
+ let value;
104
+ let failure;
105
+ try {
106
+ const pending = run(attempt, live.context);
107
+ // Started under a signal that had ALREADY aborted (a decider entered after a cancel): its synchronous part
108
+ // ran as it always did; from here on nobody waits for it, so nothing it does after its first await lands.
109
+ if (live.context.signal.aborted)
110
+ live.abandonStarted();
111
+ value = await (options.raced ? pending : live.race(pending));
112
+ }
113
+ catch (error) {
114
+ failure = { error };
115
+ }
116
+ const durationMs = Math.max(0, now() - startedAt);
117
+ const outcome = outcomeOf(failure, options.signal, live.timeoutReason);
118
+ live.end(outcome);
119
+ const inputs = new AttemptInputReader(policy, options, attempt, of, outcome, failure, deadline, now);
120
+ let decision = decideAttempt(rules, inputs.read);
121
+ // 9.15 asked retryOn, THEN checked the signal. Deciding again reads the signal afresh: rule 3 now matches,
122
+ // ahead of every user function, so none is asked twice — and nothing is discarded, nothing waited for.
123
+ if (decision.next === 'retry' && isCancelled(options.signal))
124
+ decision = decideAttempt(rules, inputs.read);
125
+ // The discard comes BEFORE the wait's length is asked for, as it did in 9.15 — without a deadline. Under one,
126
+ // rule 6 needs the wait's length to decide, so `backoffMs` was asked during the decision, before the discard.
127
+ if (decision.next === 'retry')
128
+ options.between?.(attempt);
129
+ const delayMs = decision.next === 'retry' ? inputs.delayMs() : inputs.delayIfAsked();
130
+ const timeLeftMs = deadline === undefined ? undefined : inputs.timeLeft();
131
+ const category = inputs.category();
132
+ // Private terminal semantics are fixed before serving or observer fan-out.
133
+ // An already-unresolved call wrapper must not become its physical cause
134
+ // if a consumer later changes the raw error's properties or prototype.
135
+ const terminal = options.onFailure && failure ? terminalCategory(failure.error, category) : category ?? 'unknown';
136
+ const served = inputs.failed ? (options.serve ?? extractErrorInfo)(inputs.failed.error) : undefined;
137
+ const effect = options.effect ? effectOf(inputs.outcome, failure?.error) : undefined;
138
+ const recordedKey = options.effect ? recordedKeyOf(options.effect) : undefined;
139
+ const record = freezeDeep({
140
+ series: options.series,
141
+ kind: options.kind ?? 'stage',
142
+ ...(options.target !== undefined && { target: options.target }),
143
+ attempt,
144
+ of,
145
+ startedAt,
146
+ durationMs,
147
+ outcome: inputs.outcome,
148
+ ...(category !== undefined && { category }),
149
+ decision: decision.evidence,
150
+ next: decision.next,
151
+ reason: decision.reason,
152
+ ...(inputs.retryOnThrew && { retryOnThrew: true }),
153
+ ...(delayMs !== undefined && { delayMs }),
154
+ ...(live.capMs !== undefined && { timeoutMs: live.capMs }),
155
+ ...(timeLeftMs !== undefined && { timeLeftMs }),
156
+ ...(served !== undefined && { error: recordedError(served) }),
157
+ ...(options.effect !== undefined && { system: options.effect.system }),
158
+ ...(recordedKey !== undefined && { idempotencyKey: recordedKey }),
159
+ ...(effect !== undefined && { effect }),
160
+ });
161
+ tally.add(record);
162
+ if (record.effect === 'unknown')
163
+ unknownSoFar = true;
164
+ if (record.next !== 'retry')
165
+ options.onEnd?.(tally.summary(lastOf(record, unknownSoFar)));
166
+ options.onAttempt?.(record, served);
167
+ if (record.next === 'done')
168
+ return value;
169
+ if (record.next === 'stop')
170
+ throw stoppedFailure(options, record, failure, unknownSoFar, terminal);
171
+ options.onRetry?.(attempt, of, delayMs ?? 0, served);
172
+ if (delayMs !== undefined && delayMs > 0) {
173
+ try {
174
+ await sleep(delayMs, options.signal);
175
+ }
176
+ catch (error) {
177
+ options.onFailure?.(error, 'unknown');
178
+ throw error;
179
+ }
180
+ }
181
+ // No attempt follows a cut wait, so none is recorded: the summary says how the series ended. No attempt
182
+ // STARTS at or past the deadline either — rule 6 decided with the clock, and the clock may have moved on.
183
+ const cut = isCancelled(options.signal)
184
+ ? 'aborted'
185
+ : options.signal?.aborted || (deadline !== undefined && now() >= deadline)
186
+ ? 'no-time-left'
187
+ : undefined;
188
+ if (cut !== undefined) {
189
+ options.onEnd?.(tally.summary({ ...lastOf(record, unknownSoFar), next: 'stop', reason: cut }));
190
+ throw stoppedFailure(options, record, failure, unknownSoFar, terminal);
191
+ }
192
+ }
193
+ }
194
+ /** The final physical attempt owns its category; a wrapper or cut wait has no such category. */
195
+ function stoppedFailure(options, record, failure, unknownSoFar, terminal) {
196
+ const error = stopError(options.effect, record, failure, unknownSoFar);
197
+ if (record.outcome !== 'paused') {
198
+ const category = record.next === 'stop' && Object.is(error, failure?.error) ? terminal : 'unknown';
199
+ options.onFailure?.(error, category);
200
+ }
201
+ return error;
202
+ }
203
+ /**
204
+ * What a stopped series throws: the last attempt's own error — or, on a touching target where ANY attempt left the
205
+ * effect unknown, `UnknownEffectError` with the last attempt's error as its cause. An earlier timeout may have
206
+ * applied the effect; a later attempt that says "nothing was sent" speaks for itself only, so it cannot turn the
207
+ * series into a plain failure. A pause is never converted: it is control flow.
208
+ */
209
+ function stopError(effect, record, failure, unknownSoFar) {
210
+ if (effect === undefined || !unknownSoFar || record.outcome === 'paused')
211
+ return failure?.error;
212
+ return unknownEffectError(effect, record, failure?.error);
213
+ }
214
+ /**
215
+ * One attempt in flight: its cap, its signal (the run's, composed with its own timer), and the fence. Its own
216
+ * timer is armed when the policy's cap is SHORTER than the time left; at the deadline the run's own signal aborts,
217
+ * with the deadline's reason (so a run rejects with the reason it always did). Everything it arms is released
218
+ * when the attempt ends.
219
+ */
220
+ class LiveAttempt {
221
+ options;
222
+ attempt;
223
+ context;
224
+ /** The cap this attempt runs under — `min(timeoutMs, time left)`, never negative; absent when uncapped. */
225
+ capMs;
226
+ /** The reason the attempt's OWN timer aborted with — set only if it fired. */
227
+ timeoutReason;
228
+ cancelTimer;
229
+ composed;
230
+ abandoned = false;
231
+ /** The attempt is over, however it ended — an `observed` report after this is the owner's to refuse. */
232
+ ended = false;
233
+ onAbort = () => this.abandon();
234
+ constructor(options, attempt, of, startedAt, deadline, ownCap, now) {
235
+ this.options = options;
236
+ this.attempt = attempt;
237
+ const left = deadline === undefined ? Infinity : Math.max(0, deadline - startedAt);
238
+ const cap = Math.min(ownCap ?? Infinity, left);
239
+ this.capMs = Number.isFinite(cap) ? cap : undefined;
240
+ // Its own timer when its own cap is the shorter, or when no run signal will abort at the deadline (a caller
241
+ // with a deadline and no signal). Otherwise the run's signal ends it at the deadline, with the deadline's reason.
242
+ const ownTimer = this.capMs !== undefined && ((ownCap !== undefined && ownCap < left) || !options.signal);
243
+ const own = ownTimer ? new AbortController() : undefined;
244
+ if (own) {
245
+ const capMs = this.capMs;
246
+ this.cancelTimer = setLongTimeout(() => {
247
+ // A time limit, branded like the run's deadline: a call made inside this attempt that it cuts timed out.
248
+ this.timeoutReason = markTimeLimit(new AttemptTimeoutError(attempt, capMs));
249
+ own.abort(this.timeoutReason);
250
+ }, capMs);
251
+ }
252
+ this.composed = anySignal([options.signal, own?.signal]);
253
+ // Registered BEFORE the function runs, so the fence closes before any listener the function adds. A signal
254
+ // ALREADY aborted (a decider entered after a cancel — no abort check precedes it) does not fence the attempt
255
+ // before it runs: it runs as it did before the fence existed, and is fenced when it ends without an answer.
256
+ this.composed.signal.addEventListener('abort', this.onAbort, { once: true });
257
+ const signal = this.composed.signal;
258
+ const capMs = this.capMs;
259
+ this.context = Object.freeze({
260
+ series: options.series,
261
+ attempt,
262
+ of,
263
+ signal,
264
+ ...(deadline !== undefined && { deadline }),
265
+ ...(capMs !== undefined && { timeoutMs: capMs }),
266
+ ...(options.effect !== undefined && { system: options.effect.system }),
267
+ ...(options.effect?.idempotencyKey !== undefined && { idempotencyKey: options.effect.idempotencyKey }),
268
+ timeLeftMs: () => (deadline === undefined ? Infinity : deadline - now()),
269
+ observed: (report) => {
270
+ if (!options.observe) {
271
+ throw new TypeError('observed(): report an outside attempt through `scope.$attempt().observed(...)`');
272
+ }
273
+ options.observe(report, { attempt, ended: this.ended });
274
+ },
275
+ });
276
+ if (capMs !== undefined)
277
+ ATTEMPT_ENDS.set(this.context, startedAt + capMs);
278
+ }
279
+ /** `value`, or the attempt signal's reason the moment it aborts first — the engine stops waiting at the cap. */
280
+ race(value) {
281
+ if (!(value instanceof Promise))
282
+ return value;
283
+ const signal = this.composed.signal;
284
+ return new Promise((resolve, reject) => {
285
+ const onAbort = () => reject(signal.reason);
286
+ value.then((v) => {
287
+ signal.removeEventListener('abort', onAbort);
288
+ resolve(v);
289
+ }, (e) => {
290
+ signal.removeEventListener('abort', onAbort);
291
+ reject(e);
292
+ });
293
+ // Already aborted (the function aborted it as it ran): a value that already settled still wins — its
294
+ // reaction was queued above, first — and a pending one is cut on the next microtask.
295
+ if (signal.aborted)
296
+ queueMicrotask(onAbort);
297
+ else
298
+ signal.addEventListener('abort', onAbort, { once: true });
299
+ });
300
+ }
301
+ /** The attempt is over: release the timer and the listeners; fence it if it ended without an answer. */
302
+ end(outcome) {
303
+ this.ended = true;
304
+ this.cancelTimer?.();
305
+ this.composed.signal.removeEventListener('abort', this.onAbort);
306
+ this.composed.dispose();
307
+ if (outcome !== 'ok' && outcome !== 'paused')
308
+ this.abandon();
309
+ }
310
+ /** Fence an attempt that started under an already-aborted signal, once its synchronous part has run. */
311
+ abandonStarted() {
312
+ this.abandon();
313
+ }
314
+ abandon() {
315
+ if (this.abandoned)
316
+ return;
317
+ this.abandoned = true;
318
+ this.options.onAbandon?.(this.attempt);
319
+ }
320
+ }
321
+ /** The signal aborted at a time limit — the run's deadline, or a call's attempt cap — not by a cancellation. */
322
+ function timedOut(signal) {
323
+ return signal?.aborted === true && isDeadlineReason(signal.reason);
324
+ }
325
+ /**
326
+ * How the attempt itself ended. A thrown value is the attempt's own failure unless it IS what a signal aborted
327
+ * with (StageRunner's race rejects with it; a stage may rethrow it): its own cap's `AttemptTimeoutError` or the
328
+ * run's deadline → `'timeout'`; the run's cancellation → `'aborted'`.
329
+ */
330
+ function outcomeOf(failure, signal, timeoutReason) {
331
+ if (!failure)
332
+ return 'ok';
333
+ // An `interrupt()` thrown inside a call is converted to a pause at the stage boundary, past this runner.
334
+ if (isPauseSignal(failure.error) || isInterruptSignal(failure.error))
335
+ return 'paused';
336
+ // Its own cap ran out — the attempt's timer is the one that fired, and the attempt threw what it aborted with.
337
+ if (timeoutReason !== undefined && failure.error === timeoutReason)
338
+ return 'timeout';
339
+ if (signal?.aborted !== true || failure.error !== signal.reason)
340
+ return 'failed';
341
+ // The run's signal ended it: at the deadline the attempt ran out of time (law 4); otherwise it was cancelled.
342
+ return isDeadlineReason(signal.reason) ? 'timeout' : 'aborted';
343
+ }
344
+ /**
345
+ * One attempt's decision inputs, each read only when a rule reaches it (`decideAttempt`'s reader): the user's
346
+ * `retryOn` and `backoffMs` run at most once each, and only when the 9.15 loop would have run them.
347
+ */
348
+ class AttemptInputReader {
349
+ policy;
350
+ options;
351
+ attempt;
352
+ of;
353
+ outcome;
354
+ deadline;
355
+ now;
356
+ /** The failure a category and a served error are read from — none for `'ok'` and `'paused'`. */
357
+ failed;
358
+ /** `true` once `retryOn` threw (its verdict is then `false`). */
359
+ retryOnThrew = false;
360
+ retryOnVerdict;
361
+ wait;
362
+ failureCategory;
363
+ categoryRead = false;
364
+ left;
365
+ constructor(policy, options, attempt, of, outcome, failure, deadline, now) {
366
+ this.policy = policy;
367
+ this.options = options;
368
+ this.attempt = attempt;
369
+ this.of = of;
370
+ this.outcome = outcome;
371
+ this.deadline = deadline;
372
+ this.now = now;
373
+ this.failed = failure && outcome !== 'paused' ? failure : undefined;
374
+ }
375
+ /** One input by its `AttemptInputs` key. */
376
+ read = (key) => {
377
+ switch (key) {
378
+ case 'outcome':
379
+ return this.outcome;
380
+ case 'category':
381
+ return this.category();
382
+ case 'aborted':
383
+ // Live: a decision taken again after `retryOn` sees an abort raised inside it. The deadline is not a
384
+ // cancellation — rule 6 owns it.
385
+ return isCancelled(this.options.signal);
386
+ case 'attempt':
387
+ return this.attempt;
388
+ case 'of':
389
+ return this.of;
390
+ case 'timeLeftMs':
391
+ return this.timeLeft();
392
+ case 'timeLeftAfterWaitMs':
393
+ // Without a deadline the time left is unbounded, before any wait and after it — so deciding needs no
394
+ // wait, and `backoffMs` is asked after the discard, as in 9.15. Under one, the wait's length decides.
395
+ return this.unbounded() ? Infinity : this.timeLeft() - this.delayMs();
396
+ case 'delayMs':
397
+ return this.delayMs();
398
+ case 'retryOn':
399
+ return this.retryOn();
400
+ case 'keyPresent':
401
+ return this.options.effect?.idempotencyKey !== undefined;
402
+ default:
403
+ return undefined;
404
+ }
405
+ };
406
+ /** The failure's category, read once — at the first rule that asks, or after the decision. */
407
+ category() {
408
+ if (!this.categoryRead) {
409
+ this.categoryRead = true;
410
+ this.failureCategory = this.failed ? errorCategory(this.failed.error, this.outcome) : undefined;
411
+ }
412
+ return this.failureCategory;
413
+ }
414
+ /** The policy's wait after this attempt (`resolveBackoffMs`), asked once — capped at its `maxBackoffMs`. */
415
+ delayMs() {
416
+ return (this.wait ??= cappedWaitMs(resolveBackoffMs(this.policy.backoffMs, this.attempt, this.failed?.error), this.policy.maxBackoffMs));
417
+ }
418
+ /** The wait, if the decision already asked for it (rule 6 under a deadline); never asks `backoffMs` itself. */
419
+ delayIfAsked() {
420
+ return this.wait;
421
+ }
422
+ /** Milliseconds before the deadline at the decision, read once (`Infinity` without one). */
423
+ timeLeft() {
424
+ if (this.unbounded())
425
+ return Infinity;
426
+ if (this.left === undefined) {
427
+ const clock = this.deadline === undefined ? Infinity : this.deadline - this.now();
428
+ // A time limit already reached — the signal aborted at the deadline (or, for a call, at its attempt's cap) —
429
+ // leaves no time, whatever the clock says: a host timer may fire a millisecond before the clock gets there.
430
+ this.left = timedOut(this.options.signal) ? Math.min(clock, 0) : clock;
431
+ }
432
+ return this.left;
433
+ }
434
+ /** No deadline and no time limit reached: the time left is `Infinity`, and no wait need be asked for. */
435
+ unbounded() {
436
+ return this.deadline === undefined && !timedOut(this.options.signal);
437
+ }
438
+ /** The `retryOn` gate, asked once. A throwing predicate is "do not retry" — a broken one never loops. */
439
+ retryOn() {
440
+ if (this.retryOnVerdict === undefined)
441
+ this.retryOnVerdict = this.askRetryOn();
442
+ return this.retryOnVerdict;
443
+ }
444
+ askRetryOn() {
445
+ if (!this.policy.retryOn)
446
+ return true;
447
+ try {
448
+ return this.policy.retryOn(this.failed?.error) === true;
449
+ }
450
+ catch (thrown) {
451
+ this.retryOnThrew = true;
452
+ this.options.onRetryOnThrew?.(thrown);
453
+ return false;
454
+ }
455
+ }
456
+ }
457
+ /**
458
+ * Resolve a policy's `backoffMs` for the attempt that just failed (1-based) and its error. Anything that is not a finite,
459
+ * positive number — a missing dial, a negative value, a `NaN` from a consumer's arithmetic, or a throwing
460
+ * function — becomes `0`, i.e. retry immediately. A backoff dial must never be able to crash a run or park it
461
+ * forever.
462
+ */
463
+ export function resolveBackoffMs(backoffMs, attempt, error) {
464
+ if (backoffMs === undefined)
465
+ return 0;
466
+ let value;
467
+ if (typeof backoffMs === 'function') {
468
+ try {
469
+ value = backoffMs(attempt, error);
470
+ }
471
+ catch {
472
+ return 0;
473
+ }
474
+ }
475
+ else {
476
+ value = backoffMs;
477
+ }
478
+ return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : 0;
479
+ }
480
+ /**
481
+ * Await `ms`, cut short by an abort. Resolves either way — the caller re-checks `signal.aborted` and rethrows
482
+ * the attempt's own error, so a cancelled run never sits out a long backoff and never loses the failure that
483
+ * caused it. The timer and the listener are always cleaned up.
484
+ */
485
+ export function sleep(ms, signal) {
486
+ if (signal?.aborted)
487
+ return Promise.resolve();
488
+ return new Promise((resolve) => {
489
+ const done = () => {
490
+ cancel();
491
+ signal?.removeEventListener('abort', done);
492
+ resolve();
493
+ };
494
+ const cancel = setLongTimeout(done, ms);
495
+ signal?.addEventListener('abort', done, { once: true });
496
+ });
497
+ }
498
+ /**
499
+ * How a record ended its series, as the summary's `last` says it. On a touching target the effect is the SERIES'
500
+ * (`unknownSoFar`): unknown once any attempt left it unknown, unless the series ended with an answer.
501
+ */
502
+ function lastOf(record, unknownSoFar = false) {
503
+ const effect = record.effect !== undefined && unknownSoFar && record.outcome !== 'ok' ? 'unknown' : record.effect;
504
+ return {
505
+ next: record.next,
506
+ reason: record.reason,
507
+ ...(record.category !== undefined && { category: record.category }),
508
+ ...(record.retryOnThrew && { retryOnThrew: true }),
509
+ ...(effect !== undefined && { effect }),
510
+ };
511
+ }
512
+ /** Per-outcome counts of a series, for its summary. */
513
+ class SeriesTally {
514
+ counts = { count: 0, ok: 0, failed: 0, timeout: 0, aborted: 0, paused: 0 };
515
+ add(record) {
516
+ this.counts.count += 1;
517
+ this.counts[record.outcome] += 1;
518
+ }
519
+ summary(last) {
520
+ return freezeDeep({ ...this.counts, last });
521
+ }
522
+ }
523
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVubmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9hdHRlbXB0L3J1bm5lci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4REc7QUFHSCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxhQUFhLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLGNBQWMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRyxPQUFPLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUxRCxPQUFPLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxrQkFBa0IsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM5RixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDN0UsT0FBTyxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUM7QUE2RXhELHNIQUFzSDtBQUN0SCxNQUFNLFlBQVksR0FBRyxJQUFJLE9BQU8sRUFBMEIsQ0FBQztBQUUzRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxPQUFtQztJQUMvRCxPQUFP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TyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ2xILE9BQU87UUFDTCxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQXNDO1FBQ25ELE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTTtRQUNyQixHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsS0FBSyxTQUFTLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ25FLEdBQUcsQ0FBQyxNQUFNLENBQUMsWUFBWSxJQUFJLEVBQUUsWUFBWSxFQUFFLElBQWEsRUFBRSxDQUFDO1FBQzNELEdBQUcsQ0FBQyxNQUFNLEtBQUssU0FBUyxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUM7S0FDeEMsQ0FBQztBQUNKLENBQUM7QUFFRCx1REFBdUQ7QUFDdkQsTUFBTSxXQUFXO0lBQ0UsTUFBTSxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUU1RixHQUFHLENBQUMsTUFBcUI7UUFDdkIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsT0FBTyxDQUFDLElBQTRCO1FBQ2xDLE9BQU8sVUFBVSxDQUFpQixFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzlELENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogYXR0ZW1wdC9ydW5uZXIudHMg4oCUIGBydW5BdHRlbXB0c2AsIFRIRSByZXRyeSBsb29wIChkZXNpZ24gwqczLjEsIGxhdyAxOiBvbmUgcnVubmVyLCBvbmUgcmVjb3JkKS5cbiAqXG4gKiBSdW5zIGEgZnVuY3Rpb24gdW5kZXIgYSBwb2xpY3kgYW5kIHJlY29yZHMgZXZlcnkgdHJ5OiBvbmUgZnJvemVuIGBBdHRlbXB0UmVjb3JkYCBwZXIgYXR0ZW1wdCwgY2FycnlpbmcgaXRzXG4gKiB0aW1pbmcsIG91dGNvbWUsIGZhaWx1cmUgY2F0ZWdvcnkgYW5kIHRoZSByZXRyeS1vci1zdG9wIGRlY2lzaW9uIChgYXR0ZW1wdC9kZWNpc2lvbi50c2ApLCBhbmQgb25lXG4gKiBgQXR0ZW1wdFN1bW1hcnlgIHdoZW4gdGhlIHNlcmllcyBlbmRzLiBUaGUgZW5naW5lJ3Mgc3RhZ2UgcmV0cnkgKGBGbG93Y2hhcnRUcmF2ZXJzZXIgwrcgZXhlY3V0ZVN0YWdlYCkgcnVucyBvblxuICogaXQ7IGxhdGVyIHBhY2tldHMgcnVuIGluLXN0YWdlIGNhbGxzIGFuZCBzdGFuZGFsb25lIGBhdHRlbXB0KClgIG9uIGl0IHRvby5cbiAqXG4gKiBUaGUgbG9vcCwgcGVyIGF0dGVtcHQgbiDigJQgZm9yIGEgZmFpbGVkIGF0dGVtcHQsIHRoZSA5LjE1IGxvb3AncyBvcmRlciwgc3RlcCBmb3Igc3RlcDpcbiAqXG4gKiAgIHN0YXJ0IOKGkiBydW4obikg4oaSIG91dGNvbWUgKG9rIHwgZmFpbGVkIHwgYWJvcnRlZCBbaXQgdGhyZXcgdGhlIHJ1bidzIGFib3J0IHJlYXNvbl0gfCBwYXVzZWQgW2EgUGF1c2VTaWduYWxdKVxuICogICAgICAgICDihpIgZGVjaWRlIG92ZXIgdGhlIGlucHV0cywgZmlyc3QgbWF0Y2ggd2lucyAoYHJldHJ5UnVsZXNgKSDigJQgcmV0cnlPbiBpcyBhc2tlZCBoZXJlIChydWxlIDUpXG4gKiAgICAgICAgIOKGkiB0aGUgcnVuJ3Mgc2lnbmFsIGFib3J0ZWQgaW5zaWRlIHJldHJ5T24/IGRlY2lkZSBhZ2FpbjogcnVsZSAzIHN0b3BzIHRoZSBzZXJpZXMgaGVyZSwgYmVmb3JlIHRoZVxuICogICAgICAgICAgIGRpc2NhcmQgYW5kIGJlZm9yZSBiYWNrb2ZmTXMsIGFzIHRoZSA5LjE1IGFib3J0IGNoZWNrIGRpZFxuICogICAgICAgICDihpIgcmV0cnk6IGJldHdlZW4obikg4oCUIHRoZSBkaXNjYXJkIOKAlCBhbmQgVEhFTiBiYWNrb2ZmTXMobiksIHRoZSB3YWl0J3MgbGVuZ3RoXG4gKiAgICAgICAgIOKGkiB0aGUgZXJyb3IncyBzZXJ2ZWQgZm9ybSBhbmQgY2F0ZWdvcnksIHJlYWQgYWZ0ZXIgcmV0cnlPbiBhbmQgYmFja29mZk1zIHJhbiDihpIgdGhlIHJlY29yZFxuICogICAgICAgICDihpIgb25FbmQoc3VtbWFyeSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHkgd2hlbiB0aGUgc2VyaWVzIGVuZHMgaGVyZVxuICogICAgICAgICDihpIgb25BdHRlbXB0KHJlY29yZCwgc2VydmVkIGVycm9yKVxuICogICAgICAgICDihpIgZG9uZTogcmV0dXJuIHRoZSB2YWx1ZSDCtyBzdG9wOiByZXRocm93IHRoZSBhdHRlbXB0J3MgT1dOIGVycm9yXG4gKiAgICAgICAgIOKGkiByZXRyeTogb25SZXRyeShuLCBvZiwgZGVsYXksIHNlcnZlZCBlcnJvcikg4oaSIHdhaXQgKGN1dCBzaG9ydCBieSB0aGUgc2lnbmFsKSDihpIgYWJvcnRlZD8gc3RvcFxuICpcbiAqIFdIQVQgSVQgUFJFU0VSVkVTICh0aGUgOS4xNSBsb29wJ3MgYmVoYXZpb3VyLCBtb3ZlZCBoZXJlIHVuY2hhbmdlZCk6IHRoZSBmdW5jdGlvbiBydW5zIHRoZSBzYW1lIG51bWJlciBvZlxuICogdGltZXM7IGByZXRyeU9uYCBpcyBhc2tlZCBvbmx5IGZvciBhIGZhaWxlZCwgbm9uLWZpbmFsIGF0dGVtcHQ7IGBiYWNrb2ZmTXNgIG9ubHkgd2hlbiBhIHJldHJ5IGZvbGxvd3MsIGFmdGVyXG4gKiB0aGUgZGlzY2FyZDsgYSB0aHJvd2luZyBwcmVkaWNhdGUgaXMgXCJkbyBub3QgcmV0cnlcIiwgYSB0aHJvd2luZyBvciBub24tZmluaXRlIGJhY2tvZmYgaXMgXCJubyB3YWl0XCI7IGEgcGF1c2UgaXNcbiAqIG5ldmVyIHJldHJpZWQ7IHRoZSBhdHRlbXB0J3Mgb3duIGVycm9yIGlzIHJldGhyb3duLCBuZXZlciBhIHdyYXBwZXI7IGFuZCBhIGZhaWxlZCBhdHRlbXB0J3Mgb3JkZXIg4oCUXG4gKiBgcmV0cnlPbmAg4oaSIHRoZSBhYm9ydCBjaGVjayDihpIgdGhlIGRpc2NhcmQgKGBiZXR3ZWVuYCkg4oaSIGBiYWNrb2ZmTXNgIOKGkiB0aGUgc2VydmVkIGVycm9yIOKGkiB0aGUgcmV0cnkgZXZlbnQg4oaSXG4gKiB0aGUgd2FpdCDihpIgdGhlIGFib3J0IGNoZWNrLiBTbyBhbiBhYm9ydCBpbnNpZGUgYHJldHJ5T25gIHN0b3BzIGJlZm9yZSB0aGUgZGlzY2FyZCBhbmQgbmV2ZXIgYXNrcyBgYmFja29mZk1zYDtcbiAqIGFuIGFib3J0IGluc2lkZSBgYmFja29mZk1zYCBjb21lcyBhZnRlciB0aGUgZGlzY2FyZCwgc3RpbGwgZmlyZXMgdGhlIHJldHJ5IGV2ZW50LCB0aGVuIGVuZHMgYXQgdGhlIHdhaXQ7IGFuZFxuICogdGhlIHNlcnZlZCBlcnJvciBzaG93cyB3aGF0IGByZXRyeU9uYCBkaWQgdG8gdGhlIHRocm93biB2YWx1ZS4gVGhlIG9uZSBkaWZmZXJlbmNlOiB3aGVuIHRoZSBydW4ncyBzaWduYWwgaGFzXG4gKiBBTFJFQURZIGFib3J0ZWQgYXMgdGhlIGF0dGVtcHQgZmFpbHMsIHRoZSBzZXJpZXMgc3RvcHMgd2l0aG91dCBhc2tpbmcgYHJldHJ5T25gICh0aGUgYWJvcnQgZGVjaWRlcyBmaXJzdCDigJRcbiAqIHJ1bGUgMyBiZWZvcmUgcnVsZSA1KS5cbiAqXG4gKiBXSEFUIElUIEFERFM6IHRoZSByZWNvcmQgYW5kIHRoZSBzdW1tYXJ5LiBBIHJlY29yZCBpcyBmcm96ZW4gdG8gaXRzIGxlYXZlcyBhbmQgaG9sZHMgb25seSBjbG9uZS1zYWZlIGRhdGEg4oCUXG4gKiB0aGUgZXJyb3IgYXMgdGhlIHJ1biBTRVJWRVMgaXQgKGBzZXJ2ZWAsIHRoZSByZWRhY3Rpb24gcnVsZSdzIGZvcm0pIHdpdGhvdXQgYHJhd2AuIFRoZSBob29rIGdldHMgdGhlIHNlcnZlZFxuICogYFN0cnVjdHVyZWRFcnJvckluZm9gIHdob2xlLCBgcmF3YCBpbmNsdWRlZCwgYXMgYG9uU3RhZ2VSZXRyeWAgYWx3YXlzIGhhcy4gQSByZWNvcmQgbmV2ZXIgcmV3cml0ZXMgd2hhdCB0aGVcbiAqIGF0dGVtcHQgZGlkOiBhbiBhdHRlbXB0IHRoYXQgdGhyZXcgaXRzIG93biBlcnJvciBpcyBgZmFpbGVkYCwgd2l0aCBpdHMgY2F0ZWdvcnksIGV2ZW4gd2hlbiB0aGUgcnVuIGFib3J0ZWRcbiAqIGFyb3VuZCBpdCDigJQgdGhlIGFib3J0IGlzIHRoZSBzZXJpZXMnIHN0b3AgcmVhc29uIChgcmVhc29uOiAnYWJvcnRlZCdgKTsgYSB0aHJvd2luZyBgcmV0cnlPbmAgaXMgYGRlY2xpbmVkYFxuICogd2l0aCBgcmV0cnlPblRocmV3OiB0cnVlYCwgYXBhcnQgZnJvbSBhIHJlYWwgYGZhbHNlYC5cbiAqXG4gKiBUSU1FIChQMWIpLiBFYWNoIGF0dGVtcHQgcnVucyB1bmRlciBgbWluKHBvbGljeS50aW1lb3V0TXMsIHRpbWUgbGVmdCBiZWZvcmUgb3B0aW9ucy5kZWFkbGluZSlgIGFuZCBnZXRzIGFuXG4gKiBgQXR0ZW1wdENvbnRleHRgIOKAlCBpdHMgc2lnbmFsLCBjb21wb3NlZCBmcm9tIHRoZSBydW4ncyBhbmQgaXRzIG93biBjYXAncyB0aW1lciAoYExpdmVBdHRlbXB0YCkuIFRoZSBjYXAncyB0aW1lclxuICogYWJvcnRzIHdpdGggYW4gYEF0dGVtcHRUaW1lb3V0RXJyb3JgOyB0aGUgcnVuJ3MgZGVhZGxpbmUgYWJvcnRzIHRoZSBydW4ncyBzaWduYWwgd2l0aCBhIGJyYW5kZWQgcmVhc29uXG4gKiAoYGF0dGVtcHQvZGVhZGxpbmUudHNgKS4gRWl0aGVyIHdheSB0aGUgYXR0ZW1wdCBpcyBgJ3RpbWVvdXQnYCwgbmV2ZXIgYCdhYm9ydGVkJ2A6IHRoZSBkZWFkbGluZSBpcyBub3QgYVxuICogY2FuY2VsbGF0aW9uLCBzbyBydWxlIDMgZG9lcyBub3QgbWF0Y2ggYW5kIHJ1bGUgNiAoYHRpbWVMZWZ0QWZ0ZXJXYWl0TXMg4omkIDBgKSBzdG9wcyBhIHNlcmllcyB3aG9zZSBuZXh0IHdhaXRcbiAqIHdvdWxkIG91dGxhc3QgaXQuIFVuZGVyIGEgZGVhZGxpbmUgcnVsZSA2IG5lZWRzIHRoZSB3YWl0J3MgbGVuZ3RoLCBzbyBgYmFja29mZk1zKG4sIGVycm9yKWAgaXMgYXNrZWQgRFVSSU5HIHRoZVxuICogZGVjaXNpb24g4oCUIGJlZm9yZSB0aGUgZGlzY2FyZDsgd2l0aG91dCBvbmUgdGhlIDkuMTUgb3JkZXIgYWJvdmUgaG9sZHMgdW5jaGFuZ2VkLiBObyBhdHRlbXB0IHN0YXJ0cyBhdCBvciBwYXN0XG4gKiB0aGUgZGVhZGxpbmU6IGEgd2FpdCB0aGUgZGVhZGxpbmUgY3V0IGVuZHMgdGhlIHNlcmllcyBgbm8tdGltZS1sZWZ0YCwgcmVjb3JkaW5nIG5vIGZ1cnRoZXIgYXR0ZW1wdC5cbiAqXG4gKiBUSEUgRkVOQ0UuIFRoZSBtb21lbnQgYW4gYXR0ZW1wdCBlbmRzIHdpdGhvdXQgYW4gYW5zd2VyIOKAlCBpdHMgc2lnbmFsIGFib3J0cyAoc3luY2hyb25vdXNseSwgYmVmb3JlIGFueSBsaXN0ZW5lclxuICogdGhlIGZ1bmN0aW9uIGFkZGVkKSBvciBpdCB0aHJvd3Mg4oCUIGBvbkFiYW5kb24obilgIGZpcmVzIG9uY2UsIGFuZCB0aGUgZW5naW5lIGNsb3NlcyB0aGF0IGF0dGVtcHQncyBzY29wZTogdGhlXG4gKiBmdW5jdGlvbiBtYXkgc3RpbGwgYmUgcnVubmluZywgYW5kIG5vdGhpbmcgaXQgZG9lcyBhZnRlcndhcmRzIG1heSBsYW5kIGJlc2lkZSBhIGxhdGVyIGF0dGVtcHQuXG4gKlxuICogT05FIGFzeW5jIGZyYW1lIHdpdGggT05FIGF3YWl0IHBlciBhdHRlbXB0OiB0aGUgZW5naW5lIHJlbGllcyBvbiB0aGF0IHRvIGtlZXAgYSByZXRyaWVkIHN0YWdlJ3MgbWljcm90YXNrXG4gKiBzaGFwZSwgc28gcGFyYWxsZWwgc2libGluZ3Mgc2V0dGxlIGluIHRoZSBvcmRlciB0aGV5IGFsd2F5cyBkaWQuIFRoZSBlbmdpbmUgcmFjZXMgdGhlIGF0dGVtcHQncyBzaWduYWwgaXRzZWxmLFxuICogYXQgdGhlIHN0YWdlIGJvdW5kYXJ5IChgcmFjZWQ6IHRydWVgKTsgYW55IG90aGVyIGNhbGxlciBnZXRzIHRoZSByYWNlIGhlcmUsIHNvIHRoZSBzZXJpZXMgbmV2ZXIgd2FpdHMgb24gYW5cbiAqIGF0dGVtcHQgcGFzdCBpdHMgY2FwLlxuICpcbiAqIENBTExTIChQMikuIFRoZSBzYW1lIGxvb3AgcnVucyBhIGNhbGwgYSBzdGFnZSBtYWtlcyAoYGF0dGVtcHQvY2FsbC50cyDCtyBydW5DYWxsYCwga2luZCBgJ2NhbGwnYCwgaXRzIGB0YXJnZXRgIG9uXG4gKiBldmVyeSByZWNvcmQpIGFuZCB0aGUgc3RhbmRhbG9uZSBgYXR0ZW1wdCgpYC4gQW4gYXR0ZW1wdCdzIGNhcCBpcyB0aGUgREVBRExJTkUgb2YgZXZlcnkgY2FsbCBtYWRlIGluc2lkZSBpdCwgc29cbiAqIHRoZSBjYXAncyByZWFzb24gaXMgYnJhbmRlZCBhIHRpbWUgbGltaXQgKGBhdHRlbXB0L2RlYWRsaW5lLnRzIMK3IG1hcmtUaW1lTGltaXRgKTogYSBjYWxsIGN1dCBieSBpdHMgc3RhZ2VcbiAqIGF0dGVtcHQncyBjYXAgdGltZWQgb3V0LCBpdCB3YXMgbm90IGNhbmNlbGxlZC4gYGF0dGVtcHRFbmRzQXRgIHNheXMgd2hlbiBhbiBhdHRlbXB0IG11c3QgZW5kOyBhbiBgaW50ZXJydXB0KClgXG4gKiB0aHJvd24gaW5zaWRlIGEgY2FsbCBpcyBhIHBhdXNlLCBsaWtlIGEgYFBhdXNlU2lnbmFsYCDigJQgbmV2ZXIgcmV0cmllZC5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFN0cnVjdHVyZWRFcnJvckluZm8gfSBmcm9tICcuLi9lcnJvcnMvZXJyb3JJbmZvLmpzJztcbmltcG9ydCB7IGV4dHJhY3RFcnJvckluZm8gfSBmcm9tICcuLi9lcnJvcnMvZXJyb3JJbmZvLmpzJztcbmltcG9ydCB7IGlzSW50ZXJydXB0U2lnbmFsIH0gZnJvbSAnLi4vcGF1c2UvaW50ZXJydXB0LmpzJztcbmltcG9ydCB7IGlzUGF1c2VTaWduYWwgfSBmcm9tICcuLi9wYXVzZS90eXBlcy5qcyc7XG5pbXBvcnQgeyBhbnlTaWduYWwgfSBmcm9tICcuL2FueVNpZ25hbC5qcyc7XG5pbXBvcnQgeyBlcnJvckNhdGVnb3J5LCB0ZXJtaW5hbENhdGVnb3J5IH0gZnJvbSAnLi9jYXRlZ29yeS5qcyc7XG5pbXBvcnQgeyBpc0NhbmNlbGxlZCwgaXNEZWFkbGluZVJlYXNvbiwgbWFya1RpbWVMaW1pdCwgcmVhZERlYWRsaW5lLCBzZXRMb25nVGltZW91dCB9IGZyb20gJy4vZGVhZGxpbmUuanMnO1xuaW1wb3J0IHsgZGVjaWRlQXR0ZW1wdCwgcmV0cnlSdWxlcyB9IGZyb20gJy4vZGVjaXNpb24uanMnO1xuaW1wb3J0IHR5cGUgeyBFZmZlY3RUYXJnZXQgfSBmcm9tICcuL2VmZmVjdC5qcyc7XG5pbXBvcnQgeyBlZmZlY3RPZiwgcmVjb3JkZWRLZXlPZiwgcmVmdXNlS2V5bGVzc1JldHJ5LCB1bmtub3duRWZmZWN0RXJyb3IgfSBmcm9tICcuL2VmZmVjdC5qcyc7XG5pbXBvcnQgeyBBdHRlbXB0VGltZW91dEVycm9yIH0gZnJvbSAnLi9lcnJvcnMuanMnO1xuaW1wb3J0IHsgYXR0ZW1wdENlaWxpbmcsIGF0dGVtcHRUaW1lb3V0TXMsIGNhcHBlZFdhaXRNcyB9IGZyb20gJy4vcG9saWN5LmpzJztcbmltcG9ydCB7IGZyZWV6ZURlZXAsIHJlY29yZGVkRXJyb3IgfSBmcm9tICcuL3JlY29yZC5qcyc7XG5pbXBvcnQgdHlwZSB7XG4gIEF0dGVtcHRDYXRlZ29yeSxcbiAgQXR0ZW1wdENvbnRleHQsXG4gIEF0dGVtcHRLaW5kLFxuICBBdHRlbXB0T3V0Y29tZSxcbiAgQXR0ZW1wdFJlY29yZCxcbiAgQXR0ZW1wdFN1bW1hcnksXG4gIE9ic2VydmVkQXR0ZW1wdCxcbiAgUmV0cnlQb2xpY3ksXG59IGZyb20gJy4vdHlwZXMuanMnO1xuXG4vKiogV2hhdCBhIHNlcmllcyByZXBvcnRzLCBhbmQgdGhlIGVuZ2luZSdzIGJldHdlZW4tYXR0ZW1wdCBzdGVwLiBFdmVyeSBtZW1iZXIgaXMgb3B0aW9uYWwuICovXG5leHBvcnQgaW50ZXJmYWNlIEF0dGVtcHRSdW5PcHRpb25zIHtcbiAgLyoqIFRoZSBzZXJpZXMgZXZlcnkgcmVjb3JkIG5hbWVzIOKAlCBmb3IgYSBzdGFnZSBhdHRlbXB0LCBpdHMgZXhlY3V0aW9uJ3MgYHJ1bnRpbWVTdGFnZUlkYC4gKi9cbiAgcmVhZG9ubHkgc2VyaWVzOiBzdHJpbmc7XG4gIC8qKiBEZWZhdWx0IGAnc3RhZ2UnYC4gKi9cbiAgcmVhZG9ubHkga2luZD86IEF0dGVtcHRLaW5kO1xuICAvKiogVGhlIG91dHNpZGUgdGFyZ2V0IGV2ZXJ5IHJlY29yZCBuYW1lcyDigJQgYSBjYWxsJ3MgKGAkY2FsbGAsIGBhdHRlbXB0KClgKTsgYWJzZW50IGZvciBhIHN0YWdlIGF0dGVtcHQuICovXG4gIHJlYWRvbmx5IHRhcmdldD86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBydW4ncyBzaWduYWwuIE9uY2UgaXQgaGFzIGFib3J0ZWQgKG90aGVyIHRoYW4gYXQgdGhlIGRlYWRsaW5lKSwgcnVsZSAzIHN0b3BzIHRoZSBzZXJpZXNcbiAgICogKGByZWFzb246ICdhYm9ydGVkJ2ApOyBpdCBjdXRzIGEgd2FpdCBzaG9ydC4gQW4gYXR0ZW1wdCB0aGF0IHRocmV3IGl0cyByZWFzb24gaXMgcmVjb3JkZWQgYCdhYm9ydGVkJ2Ag4oCUIG9yXG4gICAqIGAndGltZW91dCdgIHdoZW4gdGhlIHJlYXNvbiBpcyB0aGUgZGVhZGxpbmUncyAoYGF0dGVtcHQvZGVhZGxpbmUudHNgKS5cbiAgICovXG4gIHJlYWRvbmx5IHNpZ25hbD86IEFib3J0U2lnbmFsO1xuICAvKipcbiAgICogVGhlIHJ1bidzIGRlYWRsaW5lLCBlcG9jaCBtaWxsaXNlY29uZHMuIEV2ZXJ5IGF0dGVtcHQgaXMgY2FwcGVkIGJ5IHRoZSB0aW1lIGxlZnQ7IHJ1bGUgNiBzdG9wcyBhIHNlcmllcyB3aG9zZVxuICAgKiBuZXh0IHdhaXQgd291bGQgb3V0bGFzdCBpdCAoYG5vLXRpbWUtbGVmdGApLiBBYnNlbnQgKG9yIG5vdCBmaW5pdGUpID0gbm8gZGVhZGxpbmU6IHRoZSB0aW1lIGxlZnQgaXMgYEluZmluaXR5YC5cbiAgICovXG4gIHJlYWRvbmx5IGRlYWRsaW5lPzogbnVtYmVyO1xuICAvKiogVGhlIGNsb2NrLCBlcG9jaCBtaWxsaXNlY29uZHMuIERlZmF1bHQgYERhdGUubm93YC4gKi9cbiAgcmVhZG9ubHkgbm93PzogKCkgPT4gbnVtYmVyO1xuICAvKiogVGhlIHNlcnZlZCBmb3JtIG9mIGEgZmFpbGVkIGF0dGVtcHQncyBlcnJvci4gRGVmYXVsdCBgZXh0cmFjdEVycm9ySW5mb2AgKG5vIHJlZGFjdGlvbiBydWxlKS4gKi9cbiAgcmVhZG9ubHkgc2VydmU/OiAoZXJyb3I6IHVua25vd24pID0+IFN0cnVjdHVyZWRFcnJvckluZm87XG4gIC8qKiBCZXR3ZWVuIGEgZmFpbGVkIGF0dGVtcHQgYW5kIHRoZSBuZXh0LCBiZWZvcmUgYGJhY2tvZmZNc2A6IHRoZSBlbmdpbmUgZGlzY2FyZHMgdGhlIGF0dGVtcHQncyBzdGFnZWQgd3JpdGVzLiAqL1xuICByZWFkb25seSBiZXR3ZWVuPzogKGF0dGVtcHQ6IG51bWJlcikgPT4gdm9pZDtcbiAgLyoqIEV2ZXJ5IGF0dGVtcHQsIGF0IGl0cyBlbmQsIHdpdGggaXRzIHNlcnZlZCBlcnJvciAoYHVuZGVmaW5lZGAgZm9yIGAnb2snYCBhbmQgYCdwYXVzZWQnYCkuICovXG4gIHJlYWRvbmx5IG9uQXR0ZW1wdD86IChyZWNvcmQ6IEF0dGVtcHRSZWNvcmQsIHN0cnVjdHVyZWRFcnJvcjogU3RydWN0dXJlZEVycm9ySW5mbyB8IHVuZGVmaW5lZCkgPT4gdm9pZDtcbiAgLyoqIEEgZmFpbGVkIGF0dGVtcHQgdGhhdCBXSUxMIGJlIHJldHJpZWQg4oCUIGFmdGVyIGBiZXR3ZWVuYCBhbmQgYG9uQXR0ZW1wdGAsIGJlZm9yZSB0aGUgd2FpdC4gKi9cbiAgcmVhZG9ubHkgb25SZXRyeT86IChhdHRlbXB0OiBudW1iZXIsIG9mOiBudW1iZXIsIGRlbGF5TXM6IG51bWJlciwgc3RydWN0dXJlZEVycm9yOiBTdHJ1Y3R1cmVkRXJyb3JJbmZvKSA9PiB2b2lkO1xuICAvKiogVGhlIHNlcmllcyBlbmRlZDogY2FsbGVkIG9uY2UsIGJlZm9yZSB0aGUgbGFzdCBgb25BdHRlbXB0YCAob3IgYWZ0ZXIgYSB3YWl0IHRoZSBydW4ncyBzaWduYWwgY3V0KS4gKi9cbiAgcmVhZG9ubHkgb25FbmQ/OiAoc3VtbWFyeTogQXR0ZW1wdFN1bW1hcnkpID0+IHZvaWQ7XG4gIC8qKiBAaW50ZXJuYWwgTmF0aXZlIG93bmVyIG9ubHk6IHRoZSBleGFjdCBlc2NhcGluZyB2YWx1ZSBhbmQgY2F0ZWdvcnksIGJlZm9yZSBpdHMgc3RhZ2Ugc2VydmVzIHRoZSBlcnJvci4gKi9cbiAgcmVhZG9ubHkgb25GYWlsdXJlPzogKGVycm9yOiB1bmtub3duLCBjYXRlZ29yeTogQXR0ZW1wdENhdGVnb3J5KSA9PiB2b2lkO1xuICAvKiogYHJldHJ5T25gIHRocmV3IOKAlCB0aGUgYXR0ZW1wdCBpcyB0cmVhdGVkIGFzIGRlY2xpbmVkOyB0aGUgZW5naW5lIGxvZ3MgdGhlIHRocm93IGhlcmUuICovXG4gIHJlYWRvbmx5IG9uUmV0cnlPblRocmV3PzogKHRocm93bjogdW5rbm93bikgPT4gdm9pZDtcbiAgLyoqXG4gICAqIFRoZSBhdHRlbXB0IGVuZGVkIHdpdGhvdXQgYW4gYW5zd2VyIOKAlCBjYWxsZWQgU1lOQ0hST05PVVNMWSB0aGUgbW9tZW50IGl0cyBzaWduYWwgYWJvcnRzIChpdHMgY2FwLCB0aGUgZGVhZGxpbmUsXG4gICAqIGEgY2FuY2VsbGF0aW9uKSwgZWxzZSBhcyBzb29uIGFzIGl0IGZhaWxlZC4gV2hhdGV2ZXIgdGhlIGFiYW5kb25lZCBmdW5jdGlvbiBkb2VzIGFmdGVyd2FyZHMgaXMgbm90IHRoaXNcbiAgICogc2VyaWVzJzogdGhlIGVuZ2luZSBmZW5jZXMgaXRzIHNjb3BlIGhlcmUuIE9uY2UgcGVyIGF0dGVtcHQ7IG5ldmVyIGZvciBgJ29rJ2Agb3IgYCdwYXVzZWQnYCDigJQgZXhjZXB0IGFuIGF0dGVtcHRcbiAgICogdGhhdCBTVEFSVEVEIHVuZGVyIGFuIGFscmVhZHktYWJvcnRlZCBzaWduYWwsIGZlbmNlZCBvbmNlIGl0cyBzeW5jaHJvbm91cyBwYXJ0IGhhcyBydW4gKG5vYm9keSB3YWl0cyBmb3IgaXQpLlxuICAgKi9cbiAgcmVhZG9ubHkgb25BYmFuZG9uPzogKGF0dGVtcHQ6IG51bWJlcikgPT4gdm9pZDtcbiAgLyoqXG4gICAqIFRoZSBjYWxsZXIgcmFjZXMgYHJ1bmAncyBwcm9taXNlIGFnYWluc3QgdGhlIGF0dGVtcHQncyBzaWduYWwgaXRzZWxmIOKAlCB0aGUgZW5naW5lIGRvZXMsIGF0IHRoZSBzdGFnZSBib3VuZGFyeVxuICAgKiAoYFN0YWdlUnVubmVyYCksIHNvIGEgc3RhZ2Uga2VlcHMgaXRzIG9uZSBhd2FpdCBwZXIgYXR0ZW1wdC4gT3RoZXJ3aXNlIHRoZSBydW5uZXIgcmFjZXMgaXQ6IHRoZSBzZXJpZXMgbmV2ZXJcbiAgICogd2FpdHMgb24gYW4gYXR0ZW1wdCBwYXN0IGl0cyBjYXAuXG4gICAqL1xuICByZWFkb25seSByYWNlZD86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBXaGF0IGFuIGF0dGVtcHQncyBgb2JzZXJ2ZWQocmVwb3J0KWAgZG9lcyAoUDIpIOKAlCB0aGUgb3duZXIgb2YgdGhlIGF0dGVtcHQgcmVjb3JkcyB0aGUgcmVwb3J0OiBgcnVuQ2FsbGAgaGFuZHNcbiAgICogYSBjYWxsJ3MgcmVwb3J0cyB0byB0aGUgc2NvcGUsIGBhdHRlbXB0KClgIGtlZXBzIGl0cyBvd24uIGBlbmRlZGAgc2F5cyB0aGUgYXR0ZW1wdCBoYWQgYWxyZWFkeSBlbmRlZCB3aGVuIHRoZVxuICAgKiByZXBvcnQgY2FtZSAodGhlIG93bmVyIGRyb3BzIGl0KS4gQWJzZW50IOKAlCBhIHN0YWdlIGF0dGVtcHQncyBjb250ZXh0LCB3aG9zZSBgb2JzZXJ2ZWRgIHRoZSBzY29wZSdzXG4gICAqIGAkYXR0ZW1wdCgpYCByZXBsYWNlcyDigJQgYG9ic2VydmVkYCBpcyByZWZ1c2VkIHdpdGggYSBgVHlwZUVycm9yYC5cbiAgICovXG4gIHJlYWRvbmx5IG9ic2VydmU/OiAocmVwb3J0OiBPYnNlcnZlZEF0dGVtcHQsIGF0OiB7IHJlYWRvbmx5IGF0dGVtcHQ6IG51bWJlcjsgcmVhZG9ubHkgZW5kZWQ6IGJvb2xlYW4gfSkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIFRoZSBvdXRzaWRlIHN5c3RlbSB0aGUgdGFyZ2V0IHRvdWNoZXMgKFAzLCBkZXNpZ24gwqczLjMpLiBFdmVyeSByZWNvcmQgdGhlbiBzYXlzIHdoYXQgaXRzIGF0dGVtcHQgZGlkIHRvIGl0XG4gICAqIChgZWZmZWN0YCkgYW5kIG5hbWVzIHRoZSBzeXN0ZW0gYW5kIHRoZSBSRUNPUkRFRCBrZXk7IGV2ZXJ5IGF0dGVtcHQncyBjb250ZXh0IGNhcnJpZXMgdGhlIFJFQUwga2V5LiBBIHNlcmllc1xuICAgKiB0aGF0IGVuZHMgd2l0aG91dCBhbiBhbnN3ZXIgYWZ0ZXIgYW55IGF0dGVtcHQgb2YgdW5rbm93biBlZmZlY3QgZmFpbHMgd2l0aCBgVW5rbm93bkVmZmVjdEVycm9yYCAoaXRzIGBjYXVzZWAgdGhlIGF0dGVtcHQncyBvd24gZXJyb3IpIOKAlFxuICAgKiBleGNlcHQgYSBwYXVzZSwgd2hpY2ggc3RheXMgYSBwYXVzZS4gQSB0b3VjaGluZyBzZXJpZXMgdGhhdCBtYXkgcmV0cnkgd2l0aG91dCBhIGtleSBpcyByZWZ1c2VkIGJlZm9yZSBhbnl0aGluZ1xuICAgKiBydW5zOiB0aGUgbGF3J3MgbGFzdCBkb29yLlxuICAgKi9cbiAgcmVhZG9ubHkgZWZmZWN0PzogRWZmZWN0VGFyZ2V0O1xufVxuXG4vKiogV2hlbiBlYWNoIGxpdmUgYXR0ZW1wdCBtdXN0IGVuZCwgZXBvY2ggbXMg4oCUIGBzdGFydGVkQXQgKyBjYXBgLCBmb3IgYW4gYXR0ZW1wdCB0aGF0IGhhcyBhIGNhcCAoYGF0dGVtcHRFbmRzQXRgKS4gKi9cbmNvbnN0IEFUVEVNUFRfRU5EUyA9IG5ldyBXZWFrTWFwPEF0dGVtcHRDb250ZXh0LCBudW1iZXI+KCk7XG5cbi8qKlxuICogV2hlbiB0aGUgYXR0ZW1wdCBiZWhpbmQgYGNvbnRleHRgIG11c3QgZW5kLCBlcG9jaCBtaWxsaXNlY29uZHMg4oCUIGl0cyBzdGFydCBwbHVzIGl0cyBjYXAgKGBtaW4odGltZW91dE1zLCB0aW1lXG4gKiBsZWZ0KWAsIHNvIG5ldmVyIHBhc3QgdGhlIHJ1bidzIGRlYWRsaW5lKSDigJQgb3IgYHVuZGVmaW5lZGAgZm9yIGFuIHVuY2FwcGVkIGF0dGVtcHQuIEEgY2FsbCBtYWRlIGluc2lkZSB0aGVcbiAqIGF0dGVtcHQgcnVucyB1bmRlciBpdCBhcyBpdHMgZGVhZGxpbmUgKGBhdHRlbXB0L2NhbGwudHNgKS4gT25seSB0aGUgcnVubmVyJ3Mgb3duIGNvbnRleHRzIGFyZSBrbm93bi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGF0dGVtcHRFbmRzQXQoY29udGV4dDogQXR0ZW1wdENvbnRleHQgfCB1bmRlZmluZWQpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICByZXR1cm4gY29udGV4dCA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogQVRURU1QVF9FTkRTLmdldChjb250ZXh0KTtcbn1cblxuLyoqIEEgZmFpbGVkIGF0dGVtcHQncyB0aHJvd24gdmFsdWUsIGJveGVkOiBgdW5kZWZpbmVkYCBpcyBhIHZhbHVlIGEgc3RhZ2UgbWF5IHRocm93LiAqL1xuaW50ZXJmYWNlIEZhaWx1cmUge1xuICByZWFkb25seSBlcnJvcjogdW5rbm93bjtcbn1cblxuLyoqXG4gKiBSdW4gYHJ1bmAgdW50aWwgaXQgc3VjY2VlZHMgb3IgdGhlIHBvbGljeSBzdG9wcyBpdDsgcmVzb2x2ZSB3aXRoIGl0cyB2YWx1ZSBvciByZWplY3Qgd2l0aCB0aGUgTEFTVCBhdHRlbXB0J3NcbiAqIG93biBlcnJvci4gYHJ1bihuKWAgaXMgY2FsbGVkIHdpdGggdGhlIGF0dGVtcHQgbnVtYmVyLCAxLWJhc2VkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuQXR0ZW1wdHM8VD4oXG4gIHJ1bjogKGF0dGVtcHQ6IG51bWJlciwgY29udGV4dDogQXR0ZW1wdENvbnRleHQpID0+IFByb21pc2U8VD4gfCBULFxuICBwb2xpY3k6IFJldHJ5UG9saWN5LFxuICBvcHRpb25zOiBBdHRlbXB0UnVuT3B0aW9ucyxcbik6IFByb21pc2U8VD4ge1xuICBjb25zdCBvZiA9IGF0dGVtcHRDZWlsaW5nKHBvbGljeS5hdHRlbXB0cyk7XG4gIGNvbnN0IHJ1bGVzID0gcmV0cnlSdWxlcyh7IGF0dGVtcHRzOiBvZiB9KTtcbiAgY29uc3Qgbm93ID0gb3B0aW9ucy5ub3cgPz8gRGF0ZS5ub3c7XG4gIGNvbnN0IGRlYWRsaW5lID0gcmVhZERlYWRsaW5lKG9wdGlvbnMuZGVhZGxpbmUpO1xuICBjb25zdCBvd25DYXAgPSBhdHRlbXB0VGltZW91dE1zKHBvbGljeS50aW1lb3V0TXMpO1xuICBjb25zdCB0YWxseSA9IG5ldyBTZXJpZXNUYWxseSgpO1xuICBpZiAob3B0aW9ucy5lZmZlY3QpIHJlZnVzZUtleWxlc3NSZXRyeShvcHRpb25zLmVmZmVjdCwgb2YpO1xuICAvKiogQW4gZWFybGllciBhdHRlbXB0IG9mIHRoaXMgdG91Y2hpbmcgc2VyaWVzIGxlZnQgdGhlIGVmZmVjdCB1bmtub3duIOKAlCBhIGxhdGVyIGFuc3dlciBvZiBgbm9uZWAgY2Fubm90IGNsZWFyIGl0LiAqL1xuICBsZXQgdW5rbm93blNvRmFyID0gZmFsc2U7XG5cbiAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IDsgYXR0ZW1wdCsrKSB7XG4gICAgY29uc3Qgc3RhcnRlZEF0ID0gbm93KCk7XG4gICAgY29uc3QgbGl2ZSA9IG5ldyBMaXZlQXR0ZW1wdChvcHRpb25zLCBhdHRlbXB0LCBvZiwgc3RhcnRlZEF0LCBkZWFkbGluZSwgb3duQ2FwLCBub3cpO1xuICAgIGxldCB2YWx1ZTogVCB8IHVuZGVmaW5lZDtcbiAgICBsZXQgZmFpbHVyZTogRmFpbHVyZSB8IHVuZGVmaW5lZDtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGVuZGluZyA9IHJ1bihhdHRlbXB0LCBsaXZlLmNvbnRleHQpO1xuICAgICAgLy8gU3RhcnRlZCB1bmRlciBhIHNpZ25hbCB0aGF0IGhhZCBBTFJFQURZIGFib3J0ZWQgKGEgZGVjaWRlciBlbnRlcmVkIGFmdGVyIGEgY2FuY2VsKTogaXRzIHN5bmNocm9ub3VzIHBhcnRcbiAgICAgIC8vIHJhbiBhcyBpdCBhbHdheXMgZGlkOyBmcm9tIGhlcmUgb24gbm9ib2R5IHdhaXRzIGZvciBpdCwgc28gbm90aGluZyBpdCBkb2VzIGFmdGVyIGl0cyBmaXJzdCBhd2FpdCBsYW5kcy5cbiAgICAgIGlmIChsaXZlLmNvbnRleHQuc2lnbmFsLmFib3J0ZWQpIGxpdmUuYWJhbmRvblN0YXJ0ZWQoKTtcbiAgICAgIHZhbHVlID0gYXdhaXQgKG9wdGlvbnMucmFjZWQgPyBwZW5kaW5nIDogbGl2ZS5yYWNlKHBlbmRpbmcpKTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgZmFpbHVyZSA9IHsgZXJyb3IgfTtcbiAgICB9XG4gICAgY29uc3QgZHVyYXRpb25NcyA9IE1hdGgubWF4KDAsIG5vdygpIC0gc3RhcnRlZEF0KTtcbiAgICBjb25zdCBvdXRjb21lID0gb3V0Y29tZU9mKGZhaWx1cmUsIG9wdGlvbnMuc2lnbmFsLCBsaXZlLnRpbWVvdXRSZWFzb24pO1xuICAgIGxpdmUuZW5kKG91dGNvbWUpO1xuICAgIGNvbnN0IGlucHV0cyA9IG5ldyBBdHRlbXB0SW5wdXRSZWFkZXIocG9saWN5LCBvcHRpb25zLCBhdHRlbXB0LCBvZiwgb3V0Y29tZSwgZmFpbHVyZSwgZGVhZGxpbmUsIG5vdyk7XG5cbiAgICBsZXQgZGVjaXNpb24gPSBkZWNpZGVBdHRlbXB0KHJ1bGVzLCBpbnB1dHMucmVhZCk7XG4gICAgLy8gOS4xNSBhc2tlZCByZXRyeU9uLCBUSEVOIGNoZWNrZWQgdGhlIHNpZ25hbC4gRGVjaWRpbmcgYWdhaW4gcmVhZHMgdGhlIHNpZ25hbCBhZnJlc2g6IHJ1bGUgMyBub3cgbWF0Y2hlcyxcbiAgICAvLyBhaGVhZCBvZiBldmVyeSB1c2VyIGZ1bmN0aW9uLCBzbyBub25lIGlzIGFza2VkIHR3aWNlIOKAlCBhbmQgbm90aGluZyBpcyBkaXNjYXJkZWQsIG5vdGhpbmcgd2FpdGVkIGZvci5cbiAgICBpZiAoZGVjaXNpb24ubmV4dCA9PT0gJ3JldHJ5JyAmJiBpc0NhbmNlbGxlZChvcHRpb25zLnNpZ25hbCkpIGRlY2lzaW9uID0gZGVjaWRlQXR0ZW1wdChydWxlcywgaW5wdXRzLnJlYWQpO1xuXG4gICAgLy8gVGhlIGRpc2NhcmQgY29tZXMgQkVGT1JFIHRoZSB3YWl0J3MgbGVuZ3RoIGlzIGFza2VkIGZvciwgYXMgaXQgZGlkIGluIDkuMTUg4oCUIHdpdGhvdXQgYSBkZWFkbGluZS4gVW5kZXIgb25lLFxuICAgIC8vIHJ1bGUgNiBuZWVkcyB0aGUgd2FpdCdzIGxlbmd0aCB0byBkZWNpZGUsIHNvIGBiYWNrb2ZmTXNgIHdhcyBhc2tlZCBkdXJpbmcgdGhlIGRlY2lzaW9uLCBiZWZvcmUgdGhlIGRpc2NhcmQuXG4gICAgaWYgKGRlY2lzaW9uLm5leHQgPT09ICdyZXRyeScpIG9wdGlvbnMuYmV0d2Vlbj8uKGF0dGVtcHQpO1xuICAgIGNvbnN0IGRlbGF5TXMgPSBkZWNpc2lvbi5uZXh0ID09PSAncmV0cnknID8gaW5wdXRzLmRlbGF5TXMoKSA6IGlucHV0cy5kZWxheUlmQXNrZWQoKTtcbiAgICBjb25zdCB0aW1lTGVmdE1zID0gZGVhZGxpbmUgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGlucHV0cy50aW1lTGVmdCgpO1xuXG4gICAgY29uc3QgY2F0ZWdvcnkgPSBpbnB1dHMuY2F0ZWdvcnkoKTtcbiAgICAvLyBQcml2YXRlIHRlcm1pbmFsIHNlbWFudGljcyBhcmUgZml4ZWQgYmVmb3JlIHNlcnZpbmcgb3Igb2JzZXJ2ZXIgZmFuLW91dC5cbiAgICAvLyBBbiBhbHJlYWR5LXVucmVzb2x2ZWQgY2FsbCB3cmFwcGVyIG11c3Qgbm90IGJlY29tZSBpdHMgcGh5c2ljYWwgY2F1c2VcbiAgICAvLyBpZiBhIGNvbnN1bWVyIGxhdGVyIGNoYW5nZXMgdGhlIHJhdyBlcnJvcidzIHByb3BlcnRpZXMgb3IgcHJvdG90eXBlLlxuICAgIGNvbnN0IHRlcm1pbmFsID0gb3B0aW9ucy5vbkZhaWx1cmUgJiYgZmFpbHVyZSA/IHRlcm1pbmFsQ2F0ZWdvcnkoZmFpbHVyZS5lcnJvciwgY2F0ZWdvcnkpIDogY2F0ZWdvcnkgPz8gJ3Vua25vd24nO1xuICAgIGNvbnN0IHNlcnZlZCA9IGlucHV0cy5mYWlsZWQgPyAob3B0aW9ucy5zZXJ2ZSA/PyBleHRyYWN0RXJyb3JJbmZvKShpbnB1dHMuZmFpbGVkLmVycm9yKSA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBlZmZlY3QgPSBvcHRpb25zLmVmZmVjdCA/IGVmZmVjdE9mKGlucHV0cy5vdXRjb21lLCBmYWlsdXJlPy5lcnJvcikgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgcmVjb3JkZWRLZXkgPSBvcHRpb25zLmVmZmVjdCA/IHJlY29yZGVkS2V5T2Yob3B0aW9ucy5lZmZlY3QpIDogdW5kZWZpbmVkO1xuICAgIGNvbnN0IHJlY29yZCA9IGZyZWV6ZURlZXA8QXR0ZW1wdFJlY29yZD4oe1xuICAgICAgc2VyaWVzOiBvcHRpb25zLnNlcmllcyxcbiAgICAgIGtpbmQ6IG9wdGlvbnMua2luZCA/PyAnc3RhZ2UnLFxuICAgICAgLi4uKG9wdGlvbnMudGFyZ2V0ICE9PSB1bmRlZmluZWQgJiYgeyB0YXJnZXQ6IG9wdGlvbnMudGFyZ2V0IH0pLFxuICAgICAgYXR0ZW1wdCxcbiAgICAgIG9mLFxuICAgICAgc3RhcnRlZEF0LFxuICAgICAgZHVyYXRpb25NcyxcbiAgICAgIG91dGNvbWU6IGlucHV0cy5vdXRjb21lLFxuICAgICAgLi4uKGNhdGVnb3J5ICE9PSB1bmRlZmluZWQgJiYgeyBjYXRlZ29yeSB9KSxcbiAgICAgIGRlY2lzaW9uOiBkZWNpc2lvbi5ldmlkZW5jZSxcbiAgICAgIG5leHQ6IGRlY2lzaW9uLm5leHQsXG4gICAgICByZWFzb246IGRlY2lzaW9uLnJlYXNvbixcbiAgICAgIC4uLihpbnB1dHMucmV0cnlPblRocmV3ICYmIHsgcmV0cnlPblRocmV3OiB0cnVlIGFzIGNvbnN0IH0pLFxuICAgICAgLi4uKGRlbGF5TXMgIT09IHVuZGVmaW5lZCAmJiB7IGRlbGF5TXMgfSksXG4gICAgICAuLi4obGl2ZS5jYXBNcyAhPT0gdW5kZWZpbmVkICYmIHsgdGltZW91dE1zOiBsaXZlLmNhcE1zIH0pLFxuICAgICAgLi4uKHRpbWVMZWZ0TXMgIT09IHVuZGVmaW5lZCAmJiB7IHRpbWVMZWZ0TXMgfSksXG4gICAgICAuLi4oc2VydmVkICE9PSB1bmRlZmluZWQgJiYgeyBlcnJvcjogcmVjb3JkZWRFcnJvcihzZXJ2ZWQpIH0pLFxuICAgICAgLi4uKG9wdGlvbnMuZWZmZWN0ICE9PSB1bmRlZmluZWQgJiYgeyBzeXN0ZW06IG9wdGlvbnMuZWZmZWN0LnN5c3RlbSB9KSxcbiAgICAgIC4uLihyZWNvcmRlZEtleSAhPT0gdW5kZWZpbmVkICYmIHsgaWRlbXBvdGVuY3lLZXk6IHJlY29yZGVkS2V5IH0pLFxuICAgICAgLi4uKGVmZmVjdCAhPT0gdW5kZWZpbmVkICYmIHsgZWZmZWN0IH0pLFxuICAgIH0pO1xuICAgIHRhbGx5LmFkZChyZWNvcmQpO1xuICAgIGlmIChyZWNvcmQuZWZmZWN0ID09PSAndW5rbm93bicpIHVua25vd25Tb0ZhciA9IHRydWU7XG4gICAgaWYgKHJlY29yZC5uZXh0ICE9PSAncmV0cnknKSBvcHRpb25zLm9uRW5kPy4odGFsbHkuc3VtbWFyeShsYXN0T2YocmVjb3JkLCB1bmtub3duU29GYXIpKSk7XG4gICAgb3B0aW9ucy5vbkF0dGVtcHQ/LihyZWNvcmQsIHNlcnZlZCk7XG5cbiAgICBpZiAocmVjb3JkLm5leHQgPT09ICdkb25lJykgcmV0dXJuIHZhbHVlIGFzIFQ7XG4gICAgaWYgKHJlY29yZC5uZXh0ID09PSAnc3RvcCcpIHRocm93IHN0b3BwZWRGYWlsdXJlKG9wdGlvbnMsIHJlY29yZCwgZmFpbHVyZSwgdW5rbm93blNvRmFyLCB0ZXJtaW5hbCk7XG5cbiAgICBvcHRpb25zLm9uUmV0cnk/LihhdHRlbXB0LCBvZiwgZGVsYXlNcyA/PyAwLCBzZXJ2ZWQgYXMgU3RydWN0dXJlZEVycm9ySW5mbyk7XG4gICAgaWYgKGRlbGF5TXMgIT09IHVuZGVmaW5lZCAmJiBkZWxheU1zID4gMCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2xlZXAoZGVsYXlNcywgb3B0aW9ucy5zaWduYWwpO1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgb3B0aW9ucy5vbkZhaWx1cmU/LihlcnJvciwgJ3Vua25vd24nKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIE5vIGF0dGVtcHQgZm9sbG93cyBhIGN1dCB3YWl0LCBzbyBub25lIGlzIHJlY29yZGVkOiB0aGUgc3VtbWFyeSBzYXlzIGhvdyB0aGUgc2VyaWVzIGVuZGVkLiBObyBhdHRlbXB0XG4gICAgLy8gU1RBUlRTIGF0IG9yIHBhc3QgdGhlIGRlYWRsaW5lIGVpdGhlciDigJQgcnVsZSA2IGRlY2lkZWQgd2l0aCB0aGUgY2xvY2ssIGFuZCB0aGUgY2xvY2sgbWF5IGhhdmUgbW92ZWQgb24uXG4gICAgY29uc3QgY3V0ID0gaXNDYW5jZWxsZWQob3B0aW9ucy5zaWduYWwpXG4gICAgICA/ICdhYm9ydGVkJ1xuICAgICAgOiBvcHRpb25zLnNpZ25hbD8uYWJvcnRlZCB8fCAoZGVhZGxpbmUgIT09IHVuZGVmaW5lZCAmJiBub3coKSA+PSBkZWFkbGluZSlcbiAgICAgID8gJ25vLXRpbWUtbGVmdCdcbiAgICAgIDogdW5kZWZpbmVkO1xuICAgIGlmIChjdXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb3B0aW9ucy5vbkVuZD8uKHRhbGx5LnN1bW1hcnkoeyAuLi5sYXN0T2YocmVjb3JkLCB1bmtub3duU29GYXIpLCBuZXh0OiAnc3RvcCcsIHJlYXNvbjogY3V0IH0pKTtcbiAgICAgIHRocm93IHN0b3BwZWRGYWlsdXJlKG9wdGlvbnMsIHJlY29yZCwgZmFpbHVyZSwgdW5rbm93blNvRmFyLCB0ZXJtaW5hbCk7XG4gICAgfVxuICB9XG59XG5cbi8qKiBUaGUgZmluYWwgcGh5c2ljYWwgYXR0ZW1wdCBvd25zIGl0cyBjYXRlZ29yeTsgYSB3cmFwcGVyIG9yIGN1dCB3YWl0IGhhcyBubyBzdWNoIGNhdGVnb3J5LiAqL1xuZnVuY3Rpb24gc3RvcHBlZEZhaWx1cmUoXG4gIG9wdGlvbnM6IEF0dGVtcHRSdW5PcHRpb25zLFxuICByZWNvcmQ6IEF0dGVtcHRSZWNvcmQsXG4gIGZhaWx1cmU6IEZhaWx1cmUgfCB1bmRlZmluZWQsXG4gIHVua25vd25Tb0ZhcjogYm9vbGVhbixcbiAgdGVybWluYWw6IEF0dGVtcHRDYXRlZ29yeSxcbik6IHVua25vd24ge1xuICBjb25zdCBlcnJvciA9IHN0b3BFcnJvcihvcHRpb25zLmVmZmVjdCwgcmVjb3JkLCBmYWlsdXJlLCB1bmtub3duU29GYXIpO1xuICBpZiAocmVjb3JkLm91dGNvbWUgIT09ICdwYXVzZWQnKSB7XG4gICAgY29uc3QgY2F0ZWdvcnkgPSByZWNvcmQubmV4dCA9PT0gJ3N0b3AnICYmIE9iamVjdC5pcyhlcnJvciwgZmFpbHVyZT8uZXJyb3IpID8gdGVybWluYWwgOiAndW5rbm93bic7XG4gICAgb3B0aW9ucy5vbkZhaWx1cmU/LihlcnJvciwgY2F0ZWdvcnkpO1xuICB9XG4gIHJldHVybiBlcnJvcjtcbn1cblxuLyoqXG4gKiBXaGF0IGEgc3RvcHBlZCBzZXJpZXMgdGhyb3dzOiB0aGUgbGFzdCBhdHRlbXB0J3Mgb3duIGVycm9yIOKAlCBvciwgb24gYSB0b3VjaGluZyB0YXJnZXQgd2hlcmUgQU5ZIGF0dGVtcHQgbGVmdCB0aGVcbiAqIGVmZmVjdCB1bmtub3duLCBgVW5rbm93bkVmZmVjdEVycm9yYCB3aXRoIHRoZSBsYXN0IGF0dGVtcHQncyBlcnJvciBhcyBpdHMgY2F1c2UuIEFuIGVhcmxpZXIgdGltZW91dCBtYXkgaGF2ZVxuICogYXBwbGllZCB0aGUgZWZmZWN0OyBhIGxhdGVyIGF0dGVtcHQgdGhhdCBzYXlzIFwibm90aGluZyB3YXMgc2VudFwiIHNwZWFrcyBmb3IgaXRzZWxmIG9ubHksIHNvIGl0IGNhbm5vdCB0dXJuIHRoZVxuICogc2VyaWVzIGludG8gYSBwbGFpbiBmYWlsdXJlLiBBIHBhdXNlIGlzIG5ldmVyIGNvbnZlcnRlZDogaXQgaXMgY29udHJvbCBmbG93LlxuICovXG5mdW5jdGlvbiBzdG9wRXJyb3IoXG4gIGVmZmVjdDogRWZmZWN0VGFyZ2V0IHwgdW5kZWZpbmVkLFxuICByZWNvcmQ6IEF0dGVtcHRSZWNvcmQsXG4gIGZhaWx1cmU6IEZhaWx1cmUgfCB1bmRlZmluZWQsXG4gIHVua25vd25Tb0ZhcjogYm9vbGVhbixcbik6IHVua25vd24ge1xuICBpZiAoZWZmZWN0ID09PSB1bmRlZmluZWQgfHwgIXVua25vd25Tb0ZhciB8fCByZWNvcmQub3V0Y29tZSA9PT0gJ3BhdXNlZCcpIHJldHVybiBmYWlsdXJlPy5lcnJvcjtcbiAgcmV0dXJuIHVua25vd25FZmZlY3RFcnJvcihlZmZlY3QsIHJlY29yZCwgZmFpbHVyZT8uZXJyb3IpO1xufVxuXG4vKipcbiAqIE9uZSBhdHRlbXB0IGluIGZsaWdodDogaXRzIGNhcCwgaXRzIHNpZ25hbCAodGhlIHJ1bidzLCBjb21wb3NlZCB3aXRoIGl0cyBvd24gdGltZXIpLCBhbmQgdGhlIGZlbmNlLiBJdHMgb3duXG4gKiB0aW1lciBpcyBhcm1lZCB3aGVuIHRoZSBwb2xpY3kncyBjYXAgaXMgU0hPUlRFUiB0aGFuIHRoZSB0aW1lIGxlZnQ7IGF0IHRoZSBkZWFkbGluZSB0aGUgcnVuJ3Mgb3duIHNpZ25hbCBhYm9ydHMsXG4gKiB3aXRoIHRoZSBkZWFkbGluZSdzIHJlYXNvbiAoc28gYSBydW4gcmVqZWN0cyB3aXRoIHRoZSByZWFzb24gaXQgYWx3YXlzIGRpZCkuIEV2ZXJ5dGhpbmcgaXQgYXJtcyBpcyByZWxlYXNlZFxuICogd2hlbiB0aGUgYXR0ZW1wdCBlbmRzLlxuICovXG5jbGFzcyBMaXZlQXR0ZW1wdCB7XG4gIHJlYWRvbmx5IGNvbnRleHQ6IEF0dGVtcHRDb250ZXh0O1xuICAvKiogVGhlIGNhcCB0aGlzIGF0dGVtcHQgcnVucyB1bmRlciDigJQgYG1pbih0aW1lb3V0TXMsIHRpbWUgbGVmdClgLCBuZXZlciBuZWdhdGl2ZTsgYWJzZW50IHdoZW4gdW5jYXBwZWQuICovXG4gIHJlYWRvbmx5IGNhcE1zOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIC8qKiBUaGUgcmVhc29uIHRoZSBhdHRlbXB0J3MgT1dOIHRpbWVyIGFib3J0ZWQgd2l0aCDigJQgc2V0IG9ubHkgaWYgaXQgZmlyZWQuICovXG4gIHRpbWVvdXRSZWFzb246IEF0dGVtcHRUaW1lb3V0RXJyb3IgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2FuY2VsVGltZXI6ICgoKSA9PiB2b2lkKSB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSBjb21wb3NlZDogeyByZWFkb25seSBzaWduYWw6IEFib3J0U2lnbmFsOyBkaXNwb3NlKCk6IHZvaWQgfTtcbiAgcHJpdmF0ZSBhYmFuZG9uZWQgPSBmYWxzZTtcbiAgLyoqIFRoZSBhdHRlbXB0IGlzIG92ZXIsIGhvd2V2ZXIgaXQgZW5kZWQg4oCUIGFuIGBvYnNlcnZlZGAgcmVwb3J0IGFmdGVyIHRoaXMgaXMgdGhlIG93bmVyJ3MgdG8gcmVmdXNlLiAqL1xuICBwcml2YXRlIGVuZGVkID0gZmFsc2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgb25BYm9ydCA9ICgpID0+IHRoaXMuYWJhbmRvbigpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogQXR0ZW1wdFJ1bk9wdGlvbnMsXG4gICAgcHJpdmF0ZSByZWFkb25seSBhdHRlbXB0OiBudW1iZXIsXG4gICAgb2Y6IG51bWJlcixcbiAgICBzdGFydGVkQXQ6IG51bWJlcixcbiAgICBkZWFkbGluZTogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICAgIG93bkNhcDogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICAgIG5vdzogKCkgPT4gbnVtYmVyLFxuICApIHtcbiAgICBjb25zdCBsZWZ0ID0gZGVhZGxpbmUgPT09IHVuZGVmaW5lZCA/IEluZmluaXR5IDogTWF0aC5tYXgoMCwgZGVhZGxpbmUgLSBzdGFydGVkQXQpO1xuICAgIGNvbnN0IGNhcCA9IE1hdGgubWluKG93bkNhcCA/PyBJbmZpbml0eSwgbGVmdCk7XG4gICAgdGhpcy5jYXBNcyA9IE51bWJlci5pc0Zpbml0ZShjYXApID8gY2FwIDogdW5kZWZpbmVkO1xuICAgIC8vIEl0cyBvd24gdGltZXIgd2hlbiBpdHMgb3duIGNhcCBpcyB0aGUgc2hvcnRlciwgb3Igd2hlbiBubyBydW4gc2lnbmFsIHdpbGwgYWJvcnQgYXQgdGhlIGRlYWRsaW5lIChhIGNhbGxlclxuICAgIC8vIHdpdGggYSBkZWFkbGluZSBhbmQgbm8gc2lnbmFsKS4gT3RoZXJ3aXNlIHRoZSBydW4ncyBzaWduYWwgZW5kcyBpdCBhdCB0aGUgZGVhZGxpbmUsIHdpdGggdGhlIGRlYWRsaW5lJ3MgcmVhc29uLlxuICAgIGNvbnN0IG93blRpbWVyID0gdGhpcy5jYXBNcyAhPT0gdW5kZWZpbmVkICYmICgob3duQ2FwICE9PSB1bmRlZmluZWQgJiYgb3duQ2FwIDwgbGVmdCkgfHwgIW9wdGlvbnMuc2lnbmFsKTtcbiAgICBjb25zdCBvd24gPSBvd25UaW1lciA/IG5ldyBBYm9ydENvbnRyb2xsZXIoKSA6IHVuZGVmaW5lZDtcbiAgICBpZiAob3duKSB7XG4gICAgICBjb25zdCBjYXBNcyA9IHRoaXMuY2FwTXMgYXMgbnVtYmVyO1xuICAgICAgdGhpcy5jYW5jZWxUaW1lciA9IHNldExvbmdUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgLy8gQSB0aW1lIGxpbWl0LCBicmFuZGVkIGxpa2UgdGhlIHJ1bidzIGRlYWRsaW5lOiBhIGNhbGwgbWFkZSBpbnNpZGUgdGhpcyBhdHRlbXB0IHRoYXQgaXQgY3V0cyB0aW1lZCBvdXQuXG4gICAgICAgIHRoaXMudGltZW91dFJlYXNvbiA9IG1hcmtUaW1lTGltaXQobmV3IEF0dGVtcHRUaW1lb3V0RXJyb3IoYXR0ZW1wdCwgY2FwTXMpKTtcbiAgICAgICAgb3duLmFib3J0KHRoaXMudGltZW91dFJlYXNvbik7XG4gICAgICB9LCBjYXBNcyk7XG4gICAgfVxuICAgIHRoaXMuY29tcG9zZWQgPSBhbnlTaWduYWwoW29wdGlvbnMuc2lnbmFsLCBvd24/LnNpZ25hbF0pO1xuICAgIC8vIFJlZ2lzdGVyZWQgQkVGT1JFIHRoZSBmdW5jdGlvbiBydW5zLCBzbyB0aGUgZmVuY2UgY2xvc2VzIGJlZm9yZSBhbnkgbGlzdGVuZXIgdGhlIGZ1bmN0aW9uIGFkZHMuIEEgc2lnbmFsXG4gICAgLy8gQUxSRUFEWSBhYm9ydGVkIChhIGRlY2lkZXIgZW50ZXJlZCBhZnRlciBhIGNhbmNlbCDigJQgbm8gYWJvcnQgY2hlY2sgcHJlY2VkZXMgaXQpIGRvZXMgbm90IGZlbmNlIHRoZSBhdHRlbXB0XG4gICAgLy8gYmVmb3JlIGl0IHJ1bnM6IGl0IHJ1bnMgYXMgaXQgZGlkIGJlZm9yZSB0aGUgZmVuY2UgZXhpc3RlZCwgYW5kIGlzIGZlbmNlZCB3aGVuIGl0IGVuZHMgd2l0aG91dCBhbiBhbnN3ZXIuXG4gICAgdGhpcy5jb21wb3NlZC5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCB0aGlzLm9uQWJvcnQsIHsgb25jZTogdHJ1ZSB9KTtcbiAgICBjb25zdCBzaWduYWwgPSB0aGlzLmNvbXBvc2VkLnNpZ25hbDtcbiAgICBjb25zdCBjYXBNcyA9IHRoaXMuY2FwTXM7XG4gICAgdGhpcy5jb250ZXh0ID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgICBzZXJpZXM6IG9wdGlvbnMuc2VyaWVzLFxuICAgICAgYXR0ZW1wdCxcbiAgICAgIG9mLFxuICAgICAgc2lnbmFsLFxuICAgICAgLi4uKGRlYWRsaW5lICE9PSB1bmRlZmluZWQgJiYgeyBkZWFkbGluZSB9KSxcbiAgICAgIC4uLihjYXBNcyAhPT0gdW5kZWZpbmVkICYmIHsgdGltZW91dE1zOiBjYXBNcyB9KSxcbiAgICAgIC4uLihvcHRpb25zLmVmZmVjdCAhPT0gdW5kZWZpbmVkICYmIHsgc3lzdGVtOiBvcHRpb25zLmVmZmVjdC5zeXN0ZW0gfSksXG4gICAgICAuLi4ob3B0aW9ucy5lZmZlY3Q/LmlkZW1wb3RlbmN5S2V5ICE9PSB1bmRlZmluZWQgJiYgeyBpZGVtcG90ZW5jeUtleTogb3B0aW9ucy5lZmZlY3QuaWRlbXBvdGVuY3lLZXkgfSksXG4gICAgICB0aW1lTGVmdE1zOiAoKSA9PiAoZGVhZGxpbmUgPT09IHVuZGVmaW5lZCA/IEluZmluaXR5IDogZGVhZGxpbmUgLSBub3coKSksXG4gICAgICBvYnNlcnZlZDogKHJlcG9ydDogT2JzZXJ2ZWRBdHRlbXB0KSA9PiB7XG4gICAgICAgIGlmICghb3B0aW9ucy5vYnNlcnZlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb2JzZXJ2ZWQoKTogcmVwb3J0IGFuIG91dHNpZGUgYXR0ZW1wdCB0aHJvdWdoIGBzY29wZS4kYXR0ZW1wdCgpLm9ic2VydmVkKC4uLilgJyk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5vYnNlcnZlKHJlcG9ydCwgeyBhdHRlbXB0LCBlbmRlZDogdGhpcy5lbmRlZCB9KTtcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgaWYgKGNhcE1zICE9PSB1bmRlZmluZWQpIEFUVEVNUFRfRU5EUy5zZXQodGhpcy5jb250ZXh0LCBzdGFydGVkQXQgKyBjYXBNcyk7XG4gIH1cblxuICAvKiogYHZhbHVlYCwgb3IgdGhlIGF0dGVtcHQgc2lnbmFsJ3MgcmVhc29uIHRoZSBtb21lbnQgaXQgYWJvcnRzIGZpcnN0IOKAlCB0aGUgZW5naW5lIHN0b3BzIHdhaXRpbmcgYXQgdGhlIGNhcC4gKi9cbiAgcmFjZTxUPih2YWx1ZTogUHJvbWlzZTxUPiB8IFQpOiBQcm9taXNlPFQ+IHwgVCB7XG4gICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSkgcmV0dXJuIHZhbHVlO1xuICAgIGNvbnN0IHNpZ25hbCA9IHRoaXMuY29tcG9zZWQuc2lnbmFsO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxUPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBvbkFib3J0ID0gKCkgPT4gcmVqZWN0KHNpZ25hbC5yZWFzb24pO1xuICAgICAgdmFsdWUudGhlbihcbiAgICAgICAgKHYpID0+IHtcbiAgICAgICAgICBzaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkFib3J0KTtcbiAgICAgICAgICByZXNvbHZlKHYpO1xuICAgICAgICB9LFxuICAgICAgICAoZTogdW5rbm93bikgPT4ge1xuICAgICAgICAgIHNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uQWJvcnQpO1xuICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgICAvLyBBbHJlYWR5IGFib3J0ZWQgKHRoZSBmdW5jdGlvbiBhYm9ydGVkIGl0IGFzIGl0IHJhbik6IGEgdmFsdWUgdGhhdCBhbHJlYWR5IHNldHRsZWQgc3RpbGwgd2lucyDigJQgaXRzXG4gICAgICAvLyByZWFjdGlvbiB3YXMgcXVldWVkIGFib3ZlLCBmaXJzdCDigJQgYW5kIGEgcGVuZGluZyBvbmUgaXMgY3V0IG9uIHRoZSBuZXh0IG1pY3JvdGFzay5cbiAgICAgIGlmIChzaWduYWwuYWJvcnRlZCkgcXVldWVNaWNyb3Rhc2sob25BYm9ydCk7XG4gICAgICBlbHNlIHNpZ25hbC5hZGRFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uQWJvcnQsIHsgb25jZTogdHJ1ZSB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBUaGUgYXR0ZW1wdCBpcyBvdmVyOiByZWxlYXNlIHRoZSB0aW1lciBhbmQgdGhlIGxpc3RlbmVyczsgZmVuY2UgaXQgaWYgaXQgZW5kZWQgd2l0aG91dCBhbiBhbnN3ZXIuICovXG4gIGVuZChvdXRjb21lOiBBdHRlbXB0T3V0Y29tZSk6IHZvaWQge1xuICAgIHRoaXMuZW5kZWQgPSB0cnVlO1xuICAgIHRoaXMuY2FuY2VsVGltZXI/LigpO1xuICAgIHRoaXMuY29tcG9zZWQuc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgdGhpcy5vbkFib3J0KTtcbiAgICB0aGlzLmNvbXBvc2VkLmRpc3Bvc2UoKTtcbiAgICBpZiAob3V0Y29tZSAhPT0gJ29rJyAmJiBvdXRjb21lICE9PSAncGF1c2VkJykgdGhpcy5hYmFuZG9uKCk7XG4gIH1cblxuICAvKiogRmVuY2UgYW4gYXR0ZW1wdCB0aGF0IHN0YXJ0ZWQgdW5kZXIgYW4gYWxyZWFkeS1hYm9ydGVkIHNpZ25hbCwgb25jZSBpdHMgc3luY2hyb25vdXMgcGFydCBoYXMgcnVuLiAqL1xuICBhYmFuZG9uU3RhcnRlZCgpOiB2b2lkIHtcbiAgICB0aGlzLmFiYW5kb24oKTtcbiAgfVxuXG4gIHByaXZhdGUgYWJhbmRvbigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hYmFuZG9uZWQpIHJldHVybjtcbiAgICB0aGlzLmFiYW5kb25lZCA9IHRydWU7XG4gICAgdGhpcy5vcHRpb25zLm9uQWJhbmRvbj8uKHRoaXMuYXR0ZW1wdCk7XG4gIH1cbn1cblxuLyoqIFRoZSBzaWduYWwgYWJvcnRlZCBhdCBhIHRpbWUgbGltaXQg4oCUIHRoZSBydW4ncyBkZWFkbGluZSwgb3IgYSBjYWxsJ3MgYXR0ZW1wdCBjYXAg4oCUIG5vdCBieSBhIGNhbmNlbGxhdGlvbi4gKi9cbmZ1bmN0aW9uIHRpbWVkT3V0KHNpZ25hbDogQWJvcnRTaWduYWwgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgcmV0dXJuIHNpZ25hbD8uYWJvcnRlZCA9PT0gdHJ1ZSAmJiBpc0RlYWRsaW5lUmVhc29uKHNpZ25hbC5yZWFzb24pO1xufVxuXG4vKipcbiAqIEhvdyB0aGUgYXR0ZW1wdCBpdHNlbGYgZW5kZWQuIEEgdGhyb3duIHZhbHVlIGlzIHRoZSBhdHRlbXB0J3Mgb3duIGZhaWx1cmUgdW5sZXNzIGl0IElTIHdoYXQgYSBzaWduYWwgYWJvcnRlZFxuICogd2l0aCAoU3RhZ2VSdW5uZXIncyByYWNlIHJlamVjdHMgd2l0aCBpdDsgYSBzdGFnZSBtYXkgcmV0aHJvdyBpdCk6IGl0cyBvd24gY2FwJ3MgYEF0dGVtcHRUaW1lb3V0RXJyb3JgIG9yIHRoZVxuICogcnVuJ3MgZGVhZGxpbmUg4oaSIGAndGltZW91dCdgOyB0aGUgcnVuJ3MgY2FuY2VsbGF0aW9uIOKGkiBgJ2Fib3J0ZWQnYC5cbiAqL1xuZnVuY3Rpb24gb3V0Y29tZU9mKFxuICBmYWlsdXJlOiBGYWlsdXJlIHwgdW5kZWZpbmVkLFxuICBzaWduYWw6IEFib3J0U2lnbmFsIHwgdW5kZWZpbmVkLFxuICB0aW1lb3V0UmVhc29uOiBBdHRlbXB0VGltZW91dEVycm9yIHwgdW5kZWZpbmVkLFxuKTogQXR0ZW1wdE91dGNvbWUge1xuICBpZiAoIWZhaWx1cmUpIHJldHVybiAnb2snO1xuICAvLyBBbiBgaW50ZXJydXB0KClgIHRocm93biBpbnNpZGUgYSBjYWxsIGlzIGNvbnZlcnRlZCB0byBhIHBhdXNlIGF0IHRoZSBzdGFnZSBib3VuZGFyeSwgcGFzdCB0aGlzIHJ1bm5lci5cbiAgaWYgKGlzUGF1c2VTaWduYWwoZmFpbHVyZS5lcnJvcikgfHwgaXNJbnRlcnJ1cHRTaWduYWwoZmFpbHVyZS5lcnJvcikpIHJldHVybiAncGF1c2VkJztcbiAgLy8gSXRzIG93biBjYXAgcmFuIG91dCDigJQgdGhlIGF0dGVtcHQncyB0aW1lciBpcyB0aGUgb25lIHRoYXQgZmlyZWQsIGFuZCB0aGUgYXR0ZW1wdCB0aHJldyB3aGF0IGl0IGFib3J0ZWQgd2l0aC5cbiAgaWYgKHRpbWVvdXRSZWFzb24gIT09IHVuZGVmaW5lZCAmJiBmYWlsdXJlLmVycm9yID09PSB0aW1lb3V0UmVhc29uKSByZXR1cm4gJ3RpbWVvdXQnO1xuICBpZiAoc2lnbmFsPy5hYm9ydGVkICE9PSB0cnVlIHx8IGZhaWx1cmUuZXJyb3IgIT09IHNpZ25hbC5yZWFzb24pIHJldHVybiAnZmFpbGVkJztcbiAgLy8gVGhlIHJ1bidzIHNpZ25hbCBlbmRlZCBpdDogYXQgdGhlIGRlYWRsaW5lIHRoZSBhdHRlbXB0IHJhbiBvdXQgb2YgdGltZSAobGF3IDQpOyBvdGhlcndpc2UgaXQgd2FzIGNhbmNlbGxlZC5cbiAgcmV0dXJuIGlzRGVhZGxpbmVSZWFzb24oc2lnbmFsLnJlYXNvbikgPyAndGltZW91dCcgOiAnYWJvcnRlZCc7XG59XG5cbi8qKlxuICogT25lIGF0dGVtcHQncyBkZWNpc2lvbiBpbnB1dHMsIGVhY2ggcmVhZCBvbmx5IHdoZW4gYSBydWxlIHJlYWNoZXMgaXQgKGBkZWNpZGVBdHRlbXB0YCdzIHJlYWRlcik6IHRoZSB1c2VyJ3NcbiAqIGByZXRyeU9uYCBhbmQgYGJhY2tvZmZNc2AgcnVuIGF0IG1vc3Qgb25jZSBlYWNoLCBhbmQgb25seSB3aGVuIHRoZSA5LjE1IGxvb3Agd291bGQgaGF2ZSBydW4gdGhlbS5cbiAqL1xuY2xhc3MgQXR0ZW1wdElucHV0UmVhZGVyIHtcbiAgLyoqIFRoZSBmYWlsdXJlIGEgY2F0ZWdvcnkgYW5kIGEgc2VydmVkIGVycm9yIGFyZSByZWFkIGZyb20g4oCUIG5vbmUgZm9yIGAnb2snYCBhbmQgYCdwYXVzZWQnYC4gKi9cbiAgcmVhZG9ubHkgZmFpbGVkOiBGYWlsdXJlIHwgdW5kZWZpbmVkO1xuICAvKiogYHRydWVgIG9uY2UgYHJldHJ5T25gIHRocmV3IChpdHMgdmVyZGljdCBpcyB0aGVuIGBmYWxzZWApLiAqL1xuICByZXRyeU9uVGhyZXcgPSBmYWxzZTtcbiAgcHJpdmF0ZSByZXRyeU9uVmVyZGljdDogYm9vbGVhbiB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSB3YWl0OiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgZmFpbHVyZUNhdGVnb3J5OiBBdHRlbXB0Q2F0ZWdvcnkgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgY2F0ZWdvcnlSZWFkID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBsZWZ0OiBudW1iZXIgfCB1bmRlZmluZWQ7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBwb2xpY3k6IFJldHJ5UG9saWN5LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogQXR0ZW1wdFJ1bk9wdGlvbnMsXG4gICAgcHJpdmF0ZSByZWFkb25seSBhdHRlbXB0OiBudW1iZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBvZjogbnVtYmVyLFxuICAgIHJlYWRvbmx5IG91dGNvbWU6IEF0dGVtcHRPdXRjb21lLFxuICAgIGZhaWx1cmU6IEZhaWx1cmUgfCB1bmRlZmluZWQsXG4gICAgcHJpdmF0ZSByZWFkb25seSBkZWFkbGluZTogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbm93OiAoKSA9PiBudW1iZXIsXG4gICkge1xuICAgIHRoaXMuZmFpbGVkID0gZmFpbHVyZSAmJiBvdXRjb21lICE9PSAncGF1c2VkJyA/IGZhaWx1cmUgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKiogT25lIGlucHV0IGJ5IGl0cyBgQXR0ZW1wdElucHV0c2Aga2V5LiAqL1xuICByZWFkb25seSByZWFkID0gKGtleTogc3RyaW5nKTogdW5rbm93biA9PiB7XG4gICAgc3dpdGNoIChrZXkpIHtcbiAgICAgIGNhc2UgJ291dGNvbWUnOlxuICAgICAgICByZXR1cm4gdGhpcy5vdXRjb21lO1xuICAgICAgY2FzZSAnY2F0ZWdvcnknOlxuICAgICAgICByZXR1cm4gdGhpcy5jYXRlZ29yeSgpO1xuICAgICAgY2FzZSAnYWJvcnRlZCc6XG4gICAgICAgIC8vIExpdmU6IGEgZGVjaXNpb24gdGFrZW4gYWdhaW4gYWZ0ZXIgYHJldHJ5T25gIHNlZXMgYW4gYWJvcnQgcmFpc2VkIGluc2lkZSBpdC4gVGhlIGRlYWRsaW5lIGlzIG5vdCBhXG4gICAgICAgIC8vIGNhbmNlbGxhdGlvbiDigJQgcnVsZSA2IG93bnMgaXQuXG4gICAgICAgIHJldHVybiBpc0NhbmNlbGxlZCh0aGlzLm9wdGlvbnMuc2lnbmFsKTtcbiAgICAgIGNhc2UgJ2F0dGVtcHQnOlxuICAgICAgICByZXR1cm4gdGhpcy5hdHRlbXB0O1xuICAgICAgY2FzZSAnb2YnOlxuICAgICAgICByZXR1cm4gdGhpcy5vZjtcbiAgICAgIGNhc2UgJ3RpbWVMZWZ0TXMnOlxuICAgICAgICByZXR1cm4gdGhpcy50aW1lTGVmdCgpO1xuICAgICAgY2FzZSAndGltZUxlZnRBZnRlcldhaXRNcyc6XG4gICAgICAgIC8vIFdpdGhvdXQgYSBkZWFkbGluZSB0aGUgdGltZSBsZWZ0IGlzIHVuYm91bmRlZCwgYmVmb3JlIGFueSB3YWl0IGFuZCBhZnRlciBpdCDigJQgc28gZGVjaWRpbmcgbmVlZHMgbm9cbiAgICAgICAgLy8gd2FpdCwgYW5kIGBiYWNrb2ZmTXNgIGlzIGFza2VkIGFmdGVyIHRoZSBkaXNjYXJkLCBhcyBpbiA5LjE1LiBVbmRlciBvbmUsIHRoZSB3YWl0J3MgbGVuZ3RoIGRlY2lkZXMuXG4gICAgICAgIHJldHVybiB0aGlzLnVuYm91bmRlZCgpID8gSW5maW5pdHkgOiB0aGlzLnRpbWVMZWZ0KCkgLSB0aGlzLmRlbGF5TXMoKTtcbiAgICAgIGNhc2UgJ2RlbGF5TXMnOlxuICAgICAgICByZXR1cm4gdGhpcy5kZWxheU1zKCk7XG4gICAgICBjYXNlICdyZXRyeU9uJzpcbiAgICAgICAgcmV0dXJuIHRoaXMucmV0cnlPbigpO1xuICAgICAgY2FzZSAna2V5UHJlc2VudCc6XG4gICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuZWZmZWN0Py5pZGVtcG90ZW5jeUtleSAhPT0gdW5kZWZpbmVkO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH07XG5cbiAgLyoqIFRoZSBmYWlsdXJlJ3MgY2F0ZWdvcnksIHJlYWQgb25jZSDigJQgYXQgdGhlIGZpcnN0IHJ1bGUgdGhhdCBhc2tzLCBvciBhZnRlciB0aGUgZGVjaXNpb24uICovXG4gIGNhdGVnb3J5KCk6IEF0dGVtcHRDYXRlZ29yeSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCF0aGlzLmNhdGVnb3J5UmVhZCkge1xuICAgICAgdGhpcy5jYXRlZ29yeVJlYWQgPSB0cnVlO1xuICAgICAgdGhpcy5mYWlsdXJlQ2F0ZWdvcnkgPSB0aGlzLmZhaWxlZCA/IGVycm9yQ2F0ZWdvcnkodGhpcy5mYWlsZWQuZXJyb3IsIHRoaXMub3V0Y29tZSkgOiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmZhaWx1cmVDYXRlZ29yeTtcbiAgfVxuXG4gIC8qKiBUaGUgcG9saWN5J3Mgd2FpdCBhZnRlciB0aGlzIGF0dGVtcHQgKGByZXNvbHZlQmFja29mZk1zYCksIGFza2VkIG9uY2Ug4oCUIGNhcHBlZCBhdCBpdHMgYG1heEJhY2tvZmZNc2AuICovXG4gIGRlbGF5TXMoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKHRoaXMud2FpdCA/Pz0gY2FwcGVkV2FpdE1zKFxuICAgICAgcmVzb2x2ZUJhY2tvZmZNcyh0aGlzLnBvbGljeS5iYWNrb2ZmTXMsIHRoaXMuYXR0ZW1wdCwgdGhpcy5mYWlsZWQ/LmVycm9yKSxcbiAgICAgIHRoaXMucG9saWN5Lm1heEJhY2tvZmZNcyxcbiAgICApKTtcbiAgfVxuXG4gIC8qKiBUaGUgd2FpdCwgaWYgdGhlIGRlY2lzaW9uIGFscmVhZHkgYXNrZWQgZm9yIGl0IChydWxlIDYgdW5kZXIgYSBkZWFkbGluZSk7IG5ldmVyIGFza3MgYGJhY2tvZmZNc2AgaXRzZWxmLiAqL1xuICBkZWxheUlmQXNrZWQoKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy53YWl0O1xuICB9XG5cbiAgLyoqIE1pbGxpc2Vjb25kcyBiZWZvcmUgdGhlIGRlYWRsaW5lIGF0IHRoZSBkZWNpc2lvbiwgcmVhZCBvbmNlIChgSW5maW5pdHlgIHdpdGhvdXQgb25lKS4gKi9cbiAgdGltZUxlZnQoKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy51bmJvdW5kZWQoKSkgcmV0dXJuIEluZmluaXR5O1xuICAgIGlmICh0aGlzLmxlZnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgY2xvY2sgPSB0aGlzLmRlYWRsaW5lID09PSB1bmRlZmluZWQgPyBJbmZpbml0eSA6IHRoaXMuZGVhZGxpbmUgLSB0aGlzLm5vdygpO1xuICAgICAgLy8gQSB0aW1lIGxpbWl0IGFscmVhZHkgcmVhY2hlZCDigJQgdGhlIHNpZ25hbCBhYm9ydGVkIGF0IHRoZSBkZWFkbGluZSAob3IsIGZvciBhIGNhbGwsIGF0IGl0cyBhdHRlbXB0J3MgY2FwKSDigJRcbiAgICAgIC8vIGxlYXZlcyBubyB0aW1lLCB3aGF0ZXZlciB0aGUgY2xvY2sgc2F5czogYSBob3N0IHRpbWVyIG1heSBmaXJlIGEgbWlsbGlzZWNvbmQgYmVmb3JlIHRoZSBjbG9jayBnZXRzIHRoZXJlLlxuICAgICAgdGhpcy5sZWZ0ID0gdGltZWRPdXQodGhpcy5vcHRpb25zLnNpZ25hbCkgPyBNYXRoLm1pbihjbG9jaywgMCkgOiBjbG9jaztcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubGVmdDtcbiAgfVxuXG4gIC8qKiBObyBkZWFkbGluZSBhbmQgbm8gdGltZSBsaW1pdCByZWFjaGVkOiB0aGUgdGltZSBsZWZ0IGlzIGBJbmZpbml0eWAsIGFuZCBubyB3YWl0IG5lZWQgYmUgYXNrZWQgZm9yLiAqL1xuICBwcml2YXRlIHVuYm91bmRlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5kZWFkbGluZSA9PT0gdW5kZWZpbmVkICYmICF0aW1lZE91dCh0aGlzLm9wdGlvbnMuc2lnbmFsKTtcbiAgfVxuXG4gIC8qKiBUaGUgYHJldHJ5T25gIGdhdGUsIGFza2VkIG9uY2UuIEEgdGhyb3dpbmcgcHJlZGljYXRlIGlzIFwiZG8gbm90IHJldHJ5XCIg4oCUIGEgYnJva2VuIG9uZSBuZXZlciBsb29wcy4gKi9cbiAgcHJpdmF0ZSByZXRyeU9uKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnJldHJ5T25WZXJkaWN0ID09PSB1bmRlZmluZWQpIHRoaXMucmV0cnlPblZlcmRpY3QgPSB0aGlzLmFza1JldHJ5T24oKTtcbiAgICByZXR1cm4gdGhpcy5yZXRyeU9uVmVyZGljdDtcbiAgfVxuXG4gIHByaXZhdGUgYXNrUmV0cnlPbigpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMucG9saWN5LnJldHJ5T24pIHJldHVybiB0cnVlO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gdGhpcy5wb2xpY3kucmV0cnlPbih0aGlzLmZhaWxlZD8uZXJyb3IpID09PSB0cnVlO1xuICAgIH0gY2F0Y2ggKHRocm93bikge1xuICAgICAgdGhpcy5yZXRyeU9uVGhyZXcgPSB0cnVlO1xuICAgICAgdGhpcy5vcHRpb25zLm9uUmV0cnlPblRocmV3Py4odGhyb3duKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgcG9saWN5J3MgYGJhY2tvZmZNc2AgZm9yIHRoZSBhdHRlbXB0IHRoYXQganVzdCBmYWlsZWQgKDEtYmFzZWQpIGFuZCBpdHMgZXJyb3IuIEFueXRoaW5nIHRoYXQgaXMgbm90IGEgZmluaXRlLFxuICogcG9zaXRpdmUgbnVtYmVyIOKAlCBhIG1pc3NpbmcgZGlhbCwgYSBuZWdhdGl2ZSB2YWx1ZSwgYSBgTmFOYCBmcm9tIGEgY29uc3VtZXIncyBhcml0aG1ldGljLCBvciBhIHRocm93aW5nXG4gKiBmdW5jdGlvbiDigJQgYmVjb21lcyBgMGAsIGkuZS4gcmV0cnkgaW1tZWRpYXRlbHkuIEEgYmFja29mZiBkaWFsIG11c3QgbmV2ZXIgYmUgYWJsZSB0byBjcmFzaCBhIHJ1biBvciBwYXJrIGl0XG4gKiBmb3JldmVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUJhY2tvZmZNcyhiYWNrb2ZmTXM6IFJldHJ5UG9saWN5WydiYWNrb2ZmTXMnXSwgYXR0ZW1wdDogbnVtYmVyLCBlcnJvcj86IHVua25vd24pOiBudW1iZXIge1xuICBpZiAoYmFja29mZk1zID09PSB1bmRlZmluZWQpIHJldHVybiAwO1xuICBsZXQgdmFsdWU6IHVua25vd247XG4gIGlmICh0eXBlb2YgYmFja29mZk1zID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbHVlID0gYmFja29mZk1zKGF0dGVtcHQsIGVycm9yKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YWx1ZSA9IGJhY2tvZmZNcztcbiAgfVxuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiBOdW1iZXIuaXNGaW5pdGUodmFsdWUpICYmIHZhbHVlID4gMCA/IHZhbHVlIDogMDtcbn1cblxuLyoqXG4gKiBBd2FpdCBgbXNgLCBjdXQgc2hvcnQgYnkgYW4gYWJvcnQuIFJlc29sdmVzIGVpdGhlciB3YXkg4oCUIHRoZSBjYWxsZXIgcmUtY2hlY2tzIGBzaWduYWwuYWJvcnRlZGAgYW5kIHJldGhyb3dzXG4gKiB0aGUgYXR0ZW1wdCdzIG93biBlcnJvciwgc28gYSBjYW5jZWxsZWQgcnVuIG5ldmVyIHNpdHMgb3V0IGEgbG9uZyBiYWNrb2ZmIGFuZCBuZXZlciBsb3NlcyB0aGUgZmFpbHVyZSB0aGF0XG4gKiBjYXVzZWQgaXQuIFRoZSB0aW1lciBhbmQgdGhlIGxpc3RlbmVyIGFyZSBhbHdheXMgY2xlYW5lZCB1cC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNsZWVwKG1zOiBudW1iZXIsIHNpZ25hbD86IEFib3J0U2lnbmFsKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmIChzaWduYWw/LmFib3J0ZWQpIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgY29uc3QgZG9uZSA9ICgpID0+IHtcbiAgICAgIGNhbmNlbCgpO1xuICAgICAgc2lnbmFsPy5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIGRvbmUpO1xuICAgICAgcmVzb2x2ZSgpO1xuICAgIH07XG4gICAgY29uc3QgY2FuY2VsID0gc2V0TG9uZ1RpbWVvdXQoZG9uZSwgbXMpO1xuICAgIHNpZ25hbD8uYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBkb25lLCB7IG9uY2U6IHRydWUgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEhvdyBhIHJlY29yZCBlbmRlZCBpdHMgc2VyaWVzLCBhcyB0aGUgc3VtbWFyeSdzIGBsYXN0YCBzYXlzIGl0LiBPbiBhIHRvdWNoaW5nIHRhcmdldCB0aGUgZWZmZWN0IGlzIHRoZSBTRVJJRVMnXG4gKiAoYHVua25vd25Tb0ZhcmApOiB1bmtub3duIG9uY2UgYW55IGF0dGVtcHQgbGVmdCBpdCB1bmtub3duLCB1bmxlc3MgdGhlIHNlcmllcyBlbmRlZCB3aXRoIGFuIGFuc3dlci5cbiAqL1xuZnVuY3Rpb24gbGFzdE9mKHJlY29yZDogQXR0ZW1wdFJlY29yZCwgdW5rbm93blNvRmFyID0gZmFsc2UpOiBBdHRlbXB0U3VtbWFyeVsnbGFzdCddIHtcbiAgY29uc3QgZWZmZWN0ID0gcmVjb3JkLmVmZmVjdCAhPT0gdW5kZWZpbmVkICYmIHVua25vd25Tb0ZhciAmJiByZWNvcmQub3V0Y29tZSAhPT0gJ29rJyA/ICd1bmtub3duJyA6IHJlY29yZC5lZmZlY3Q7XG4gIHJldHVybiB7XG4gICAgbmV4dDogcmVjb3JkLm5leHQgYXMgQXR0ZW1wdFN1bW1hcnlbJ2xhc3QnXVsnbmV4dCddLFxuICAgIHJlYXNvbjogcmVjb3JkLnJlYXNvbixcbiAgICAuLi4ocmVjb3JkLmNhdGVnb3J5ICE9PSB1bmRlZmluZWQgJiYgeyBjYXRlZ29yeTogcmVjb3JkLmNhdGVnb3J5IH0pLFxuICAgIC4uLihyZWNvcmQucmV0cnlPblRocmV3ICYmIHsgcmV0cnlPblRocmV3OiB0cnVlIGFzIGNvbnN0IH0pLFxuICAgIC4uLihlZmZlY3QgIT09IHVuZGVmaW5lZCAmJiB7IGVmZmVjdCB9KSxcbiAgfTtcbn1cblxuLyoqIFBlci1vdXRjb21lIGNvdW50cyBvZiBhIHNlcmllcywgZm9yIGl0cyBzdW1tYXJ5LiAqL1xuY2xhc3MgU2VyaWVzVGFsbHkge1xuICBwcml2YXRlIHJlYWRvbmx5IGNvdW50cyA9IHsgY291bnQ6IDAsIG9rOiAwLCBmYWlsZWQ6IDAsIHRpbWVvdXQ6IDAsIGFib3J0ZWQ6IDAsIHBhdXNlZDogMCB9O1xuXG4gIGFkZChyZWNvcmQ6IEF0dGVtcHRSZWNvcmQpOiB2b2lkIHtcbiAgICB0aGlzLmNvdW50cy5jb3VudCArPSAxO1xuICAgIHRoaXMuY291bnRzW3JlY29yZC5vdXRjb21lXSArPSAxO1xuICB9XG5cbiAgc3VtbWFyeShsYXN0OiBBdHRlbXB0U3VtbWFyeVsnbGFzdCddKTogQXR0ZW1wdFN1bW1hcnkge1xuICAgIHJldHVybiBmcmVlemVEZWVwPEF0dGVtcHRTdW1tYXJ5Pih7IC4uLnRoaXMuY291bnRzLCBsYXN0IH0pO1xuICB9XG59XG4iXX0=