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,666 @@
1
+ /**
2
+ * budget/timeBudget.ts — `timeBudget(chart)`: the slowest a chart can take, from what it declares (design
3
+ * docs/design/2026-10-time-and-failure-evidence.md §3.2, packet P5).
4
+ *
5
+ * WHY: a retry policy is a promise about time. `{ attempts: 4, timeoutMs: 40_000, backoffMs: 1_000 }` allows
6
+ * 4 × 40 000 + 3 × 1 000 = 163 000 ms, and a caller who gave the chart 120 s is not served by it — which is
7
+ * knowable before a single stage runs. `.budget(ms)` declares the caller's contract on the chart; `build()` refuses
8
+ * a chart whose declared policies already allow longer (owner ruling Q2) and warns, by name, about every stage it
9
+ * cannot bound. An unbounded stage is never guessed around: it is counted as 0 and named.
10
+ *
11
+ * THE RULES (one walk of the built StageNode graph; each chain of `next` pointers is computed once per start):
12
+ * - a stage with a function: `attempts × timeoutMs` plus the waits between its attempts, as the runner waits them
13
+ * (`attempt/policy.ts`). A number `backoffMs` is arithmetic, under `maxBackoffMs` when declared. A FUNCTION is
14
+ * never asked: it may read the error (a stated `Retry-After`) and no error exists here, so asking it with none
15
+ * could UNDERESTIMATE. It counts at its declared ceiling, `maxBackoffMs` per wait (the runner enforces it); with
16
+ * no ceiling the stage is unbounded `'backoff'`. No `timeoutMs` → unbounded `'no-timeout'`;
17
+ * - a sequence: the sum. A decider, a selector, a fork: the node's own stage plus its slowest child (a fork's
18
+ * children, and a selector's picks, run at once);
19
+ * - a mounted subflow: its chart, walked the same way, under the ids the run gives its stages (`pay/charge`);
20
+ * a lazy one is unbounded `'lazy-subflow'` unless `assume.lazy[subflowId]` names the chart it resolves to;
21
+ * - `parallelForEach`: ONE branch — the branches run at once and `maxBranches` truncates, so the item count never
22
+ * adds time. The branch chart is built at run time, so it is unbounded `'items'` unless
23
+ * `assume.branches[stageId]` names it (its stages are reported under the first branch, `review~0/score`);
24
+ * - a loop is NEVER iterated. With no assumption it is unbounded `'loop'`, named by its target, and counted once.
25
+ * `assume.loops[targetId] = n` bounds it: each time the chart reaches the loop, every stage from the target to
26
+ * the loop's furthest source runs at most `n` times, each at its slowest. Nested loops multiply; two loops that
27
+ * overlap without nesting are one region bounded by the product of their passes (each can re-enter the other).
28
+ *
29
+ * TWO NUMBERS. `knownMs` counts what is bounded (an unbounded stage as 0, an unassumed loop once). Without
30
+ * assumptions it is a time the declared policies ALLOW a run to take (`retryOn` is not read: it may only end a series
31
+ * sooner), so a budget below it cannot be promised — `over` and the build refusal read it, on an unbounded path too.
32
+ * `worstCaseMs` is `knownMs` when every path is bounded, `null` otherwise; with an assumed loop it is an upper bound
33
+ * under that assumption (every pass is counted at its slowest branch).
34
+ *
35
+ * THREAT MODEL. The walk terminates on any graph: a chain is walked with a visited set (a `next` that closes on
36
+ * itself is a loop), nesting is an explicit stack (no recursion — a 5 000-deep subflow nesting walks), a chain that
37
+ * reaches itself through its children or a subflow is a loop, and every chain is computed once per start however
38
+ * often it is mounted. The walk is CAPPED: past `MAX_WALK` node visits it stops with a `RangeError` — a builder chart
39
+ * visits each node at most twice, but a hand-built graph whose chains share their tails is walked once per chain.
40
+ * Sums and products saturate at `Number.MAX_SAFE_INTEGER` — never `Infinity` or `NaN`. Assumptions are copied ONCE,
41
+ * own enumerable properties only, into fresh null-prototype records, and only that copy is read.
42
+ *
43
+ * What it does NOT count: the engine's own work between stages, a stage function that blocks the thread (a timeout
44
+ * stops the WAITING, see the attempt runner), and a StageNode a stage returns at run time — any stage may grow the
45
+ * graph that way, so the budget is of the graph the chart DECLARES.
46
+ */
47
+ import { joinPath } from 'foottrace';
48
+ import { attemptCeiling, attemptTimeoutMs, backoffCeilingMs, cappedWaitMs } from '../attempt/policy.js';
49
+ import { retryLoopBudget } from '../attempt/retryLoopContext.js';
50
+ import { resolveBackoffMs } from '../attempt/runner.js';
51
+ import { isDevMode } from '../devMode.js';
52
+ import { buildBranchSegment } from '../ids/branchSegment.js';
53
+ /**
54
+ * The most node visits one walk makes. A builder chart visits each node at most twice, so 250 000 is far past any
55
+ * real chart; a hand-built graph whose chains share their tails can need more (each chain walks the shared tail),
56
+ * and the check stops there with a `RangeError` rather than grow without bound.
57
+ */
58
+ export const MAX_WALK = 250_000;
59
+ // ─────────────────────────────────────────────────────────────────────────────
60
+ // The entry points
61
+ // ─────────────────────────────────────────────────────────────────────────────
62
+ /**
63
+ * The slowest the chart can take, computed from its declared retry policies — and every stage that makes a path
64
+ * unbounded, by name. See the module header for the rules.
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * const report = timeBudget(chart, { budgetMs: 120_000, assume: { loops: { 'ask-again': 3 } } });
69
+ * report.worstCaseMs; // number, or null when a path is unbounded
70
+ * report.criticalPath; // [{ stageId, attempts, timeoutMs, backoffMs, worstMs, passes }]
71
+ * report.unbounded; // [{ stageId, why: 'no-timeout' | 'backoff' | 'loop' | 'lazy-subflow' | 'items' }]
72
+ * report.over; // true when the declared policies allow longer than budgetMs
73
+ * ```
74
+ */
75
+ export function timeBudget(chart, options) {
76
+ if (!isChart(chart)) {
77
+ throw new TypeError('timeBudget(chart): pass a built chart — the result of flowChart(...).build().');
78
+ }
79
+ if (options?.budgetMs !== undefined && !isPositiveMs(options.budgetMs)) {
80
+ throw new TypeError('timeBudget: budgetMs must be a number of milliseconds > 0, at most Number.MAX_SAFE_INTEGER ' +
81
+ `(got ${shown(options.budgetMs)}).`);
82
+ }
83
+ const budgetMs = options?.budgetMs ?? declaredBudget(chart);
84
+ const walk = new BudgetWalk(admitAssumptions(options?.assume));
85
+ const ctx = walk.ctxOf(chart, '');
86
+ const root = walk.evaluate({ ctx, start: chart.root });
87
+ // A loop whose target the chart does not hold cannot be bounded by any assumption.
88
+ const rootFlags = [...root.open].map((target) => ({ stageId: reported(ctx, target), why: 'loop' }));
89
+ const bounded = root.bounded && root.open.size === 0;
90
+ return Object.freeze({
91
+ worstCaseMs: bounded ? root.known : null,
92
+ knownMs: root.known,
93
+ criticalPath: Object.freeze(criticalPathOf(root, walk.computed)),
94
+ unbounded: Object.freeze(unboundedOf(root, rootFlags)),
95
+ ...(budgetMs !== undefined && { budgetMs }),
96
+ over: budgetMs !== undefined && root.known > budgetMs,
97
+ });
98
+ }
99
+ /** The chart's declared budget (`.budget(ms)`, the spec root's `budgetMs`), or `undefined`. */
100
+ export function declaredBudget(chart) {
101
+ const budgetMs = chart.buildTimeStructure?.budgetMs;
102
+ return isPositiveMs(budgetMs) ? budgetMs : undefined;
103
+ }
104
+ /** `build()`'s refusal for a declared budget the chart can already exceed, or `undefined` when it can keep it. */
105
+ export function budgetRefusal(report) {
106
+ if (!report.over || report.budgetMs === undefined)
107
+ return undefined;
108
+ const counted = report.criticalPath.filter((step) => contribution(step) > 0);
109
+ const shownSteps = slowestInPathOrder(counted, 5).map(stepText);
110
+ const more = counted.length > shownSteps.length ? `, and ${counted.length - shownSteps.length} more` : '';
111
+ const uncounted = report.unbounded.length > 0 ? ` Not counted, having no bound: ${unboundedText(report.unbounded)}.` : '';
112
+ return (`budget(${report.budgetMs}): its declared policies allow ${report.knownMs} ms, over its budget by ` +
113
+ `${report.knownMs - report.budgetMs} ms. Slowest path: ${shownSteps.join('; ')}${more}. Lower attempts or ` +
114
+ `timeoutMs on these stages, or raise the budget.${uncounted}`);
115
+ }
116
+ /** `build()`'s dev-mode warning for a declared budget it cannot check on every path, or `undefined`. */
117
+ export function budgetWarning(report, chartName) {
118
+ if (report.budgetMs === undefined || report.unbounded.length === 0)
119
+ return undefined;
120
+ return (`[footprint] chart '${chartName}' declares a budget of ${report.budgetMs} ms, but the check cannot bound ` +
121
+ `every path: ${unboundedText(report.unbounded)}. Give a stage a retry({ timeoutMs }) and a function backoff a ` +
122
+ 'maxBackoffMs; bound a loop, a lazy subflow or a parallelForEach with timeBudget(chart, { assume }).');
123
+ }
124
+ /** Charts already warned at run start — the warning is said once per chart. */
125
+ const warnedAtRunStart = new WeakSet();
126
+ /**
127
+ * The run-start warning (dev mode, once per chart): the run's deadline leaves the chart less time than its declared
128
+ * budget, so a run that takes the time the chart declares will be cut short. `startedAt` is read BEFORE the run's
129
+ * deadline is armed, so `timeoutMs` equal to the budget never warns.
130
+ */
131
+ export function warnDeadlineUnderBudget(chart, deadline, startedAt) {
132
+ if (deadline === undefined || !isDevMode())
133
+ return;
134
+ const budgetMs = declaredBudget(chart);
135
+ if (budgetMs === undefined)
136
+ return;
137
+ const leftMs = deadline - startedAt;
138
+ if (leftMs >= budgetMs || warnedAtRunStart.has(chart))
139
+ return;
140
+ warnedAtRunStart.add(chart);
141
+ // eslint-disable-next-line no-console
142
+ console.warn(`[footprint] this run's deadline leaves ${Math.max(0, leftMs)} ms, less than the chart's declared budget of ` +
143
+ `${budgetMs} ms ('${chart.root.name}'): a run that takes the time the chart declares will be cut short. Give ` +
144
+ 'the run its budget, or declare a smaller one.');
145
+ }
146
+ // ─────────────────────────────────────────────────────────────────────────────
147
+ // The walk
148
+ // ─────────────────────────────────────────────────────────────────────────────
149
+ const IN_PROGRESS = Symbol('in-progress');
150
+ const NONE = { kind: 'none' };
151
+ const EMPTY = new Set();
152
+ class BudgetWalk {
153
+ assume;
154
+ /** Every chain, in the order computed: each one after every chain it runs inside itself. */
155
+ computed = [];
156
+ ctxs = new Map();
157
+ /** Node visits so far — capped at `MAX_WALK`. */
158
+ walked = 0;
159
+ constructor(assume) {
160
+ this.assume = assume;
161
+ }
162
+ /** The chain from `start` — every node visit counted against `MAX_WALK`. */
163
+ chainOf(start) {
164
+ const nodes = [];
165
+ const seen = new Set();
166
+ let cur = start;
167
+ while (isNode(cur)) {
168
+ if (cur.isLoopRef)
169
+ return { nodes, backId: String(cur.id) };
170
+ if (seen.has(cur))
171
+ return { nodes, backTo: cur };
172
+ if (++this.walked > MAX_WALK) {
173
+ throw new RangeError(`timeBudget: the walk passed ${MAX_WALK} node visits and stopped. A builder chart visits each node at ` +
174
+ 'most twice; a hand-built graph whose chains share their tails walks the shared tail once per chain. ' +
175
+ 'The budget of this graph cannot be computed.');
176
+ }
177
+ seen.add(cur);
178
+ nodes.push(cur);
179
+ cur = cur.next;
180
+ }
181
+ return { nodes };
182
+ }
183
+ ctxOf(owner, prefix) {
184
+ let byPrefix = this.ctxs.get(owner);
185
+ if (byPrefix === undefined) {
186
+ byPrefix = new Map();
187
+ this.ctxs.set(owner, byPrefix);
188
+ }
189
+ let ctx = byPrefix.get(prefix);
190
+ if (ctx === undefined) {
191
+ ctx = { subflows: owner.subflows, stageMap: owner.stageMap, prefix, memo: new Map() };
192
+ byPrefix.set(prefix, ctx);
193
+ }
194
+ return ctx;
195
+ }
196
+ /**
197
+ * Compute `root` and every chain it runs — an explicit stack, never recursion. A chain is marked in progress on
198
+ * its first visit and pushes the chains it needs; it is computed on its second, when they are done. A chain that
199
+ * needs one still in progress needs itself: an object cycle, counted as a loop.
200
+ */
201
+ evaluate(root) {
202
+ const stack = [root];
203
+ while (stack.length > 0) {
204
+ const ref = stack[stack.length - 1];
205
+ const state = ref.ctx.memo.get(ref.start);
206
+ if (state !== undefined && state !== IN_PROGRESS) {
207
+ stack.pop();
208
+ continue;
209
+ }
210
+ const nodes = this.chainOf(ref.start);
211
+ const insides = nodes.nodes.map((node) => this.insideOf(node, ref.ctx));
212
+ if (state === undefined) {
213
+ ref.ctx.memo.set(ref.start, IN_PROGRESS);
214
+ const before = stack.length;
215
+ for (const inside of insides) {
216
+ if (inside.kind !== 'chains')
217
+ continue;
218
+ for (const dep of inside.refs)
219
+ if (!dep.ctx.memo.has(dep.start))
220
+ stack.push(dep);
221
+ }
222
+ if (stack.length > before)
223
+ continue;
224
+ }
225
+ stack.pop();
226
+ const chain = this.chainResult(ref.ctx, nodes, insides);
227
+ ref.ctx.memo.set(ref.start, chain);
228
+ this.computed.push(chain);
229
+ }
230
+ return root.ctx.memo.get(root.start);
231
+ }
232
+ insideOf(node, ctx) {
233
+ if (node.isDynamicParallel) {
234
+ const stageId = reported(ctx, node.id);
235
+ const chart = own(this.assume.branches, stageId);
236
+ if (chart === undefined)
237
+ return { kind: 'unbounded', why: 'items', stageId };
238
+ const branch = buildBranchSegment(stageId, 0);
239
+ return { kind: 'chains', refs: [{ ctx: this.ctxOf(chart, branch), start: chart.root }], boundary: true };
240
+ }
241
+ if (isMount(node))
242
+ return this.mountOf(node, ctx);
243
+ const children = childrenOf(node);
244
+ if (children.length > 0)
245
+ return { kind: 'chains', refs: children.map((start) => ({ ctx, start })), boundary: false };
246
+ return NONE;
247
+ }
248
+ /** A subflow mount — resolved the way the engine resolves it (`NodeResolver · resolveSubflowReference`). */
249
+ mountOf(node, ctx) {
250
+ const subflowId = reported(ctx, String(node.subflowId));
251
+ if (node.subflowResolver !== undefined) {
252
+ const chart = own(this.assume.lazy, subflowId);
253
+ if (chart === undefined)
254
+ return { kind: 'unbounded', why: 'lazy-subflow', stageId: subflowId };
255
+ return { kind: 'chains', refs: [{ ctx: this.ctxOf(chart, subflowId), start: chart.root }], boundary: true };
256
+ }
257
+ const inline = node.subflowDef;
258
+ if (inline?.root !== undefined) {
259
+ return {
260
+ kind: 'chains',
261
+ refs: [{ ctx: this.ctxOf(inline, ctx.prefix), start: inline.root }],
262
+ boundary: true,
263
+ };
264
+ }
265
+ const def = subflowDefOf(ctx.subflows, node);
266
+ return def === undefined ? NONE : { kind: 'chains', refs: [{ ctx, start: def.root }], boundary: true };
267
+ }
268
+ chainResult(ctx, shape, insides) {
269
+ const { nodes } = shape;
270
+ const at = new Map();
271
+ nodes.forEach((node, i) => {
272
+ if (!at.has(node.id))
273
+ at.set(node.id, i);
274
+ });
275
+ const backEdges = [];
276
+ const open = new Set();
277
+ // A jump to a target this chain holds at or before `from` is a loop over [target, from]; a forward jump repeats
278
+ // nothing; a target the chain does not hold is the enclosing chain's to resolve.
279
+ const jump = (target, from) => {
280
+ const j = at.get(target);
281
+ if (j === undefined)
282
+ open.add(target);
283
+ else if (j <= from)
284
+ backEdges.push([j, from]);
285
+ };
286
+ let bounded = true;
287
+ const positions = nodes.map((node, q) => {
288
+ const stageId = reported(ctx, node.id);
289
+ const flags = [];
290
+ // A mount runs its subflow in place of a function of its own (the engine never asks its stage map).
291
+ const cost = !isMount(node) && hasFunction(node, ctx) ? helperCost(retryLoopBudget(node), node.retry) : undefined;
292
+ if (cost?.why !== undefined)
293
+ flags.push({ stageId, why: cost.why });
294
+ const inner = this.innerOf(insides[q], flags);
295
+ for (const target of inner.open)
296
+ jump(target, q);
297
+ if (cost?.worstMs === null || !inner.bounded)
298
+ bounded = false;
299
+ return {
300
+ stageId,
301
+ cost,
302
+ innerKnown: inner.known,
303
+ via: inner.via,
304
+ deps: inner.deps,
305
+ flags,
306
+ multiplier: 1,
307
+ declaredPasses: retryLoopBudget(node)?.passes,
308
+ };
309
+ });
310
+ if (shape.backTo !== undefined)
311
+ backEdges.push([nodes.indexOf(shape.backTo), nodes.length - 1]);
312
+ if (shape.backId !== undefined)
313
+ jump(shape.backId, nodes.length - 1);
314
+ if (!this.applyLoops(positions, backEdges))
315
+ bounded = false;
316
+ let known = 0;
317
+ for (const p of positions)
318
+ known = add(known, mul(p.multiplier, add(p.cost?.knownMs ?? 0, p.innerKnown)));
319
+ return { known, bounded, open, positions };
320
+ }
321
+ /** The slowest of the chains a node runs inside itself (they are alternatives, or run at once). */
322
+ innerOf(inside, flags) {
323
+ if (inside.kind === 'none')
324
+ return { known: 0, bounded: true, deps: [], open: EMPTY };
325
+ if (inside.kind === 'unbounded') {
326
+ flags.push({ stageId: inside.stageId, why: inside.why });
327
+ return { known: 0, bounded: false, deps: [], open: EMPTY };
328
+ }
329
+ let via;
330
+ let bounded = true;
331
+ const deps = [];
332
+ const open = new Set();
333
+ for (const ref of inside.refs) {
334
+ const chain = ref.ctx.memo.get(ref.start);
335
+ if (chain === undefined || chain === IN_PROGRESS) {
336
+ flags.push({ stageId: reported(ref.ctx, ref.start.id), why: 'loop' });
337
+ bounded = false;
338
+ continue;
339
+ }
340
+ deps.push(chain);
341
+ if (!chain.bounded)
342
+ bounded = false;
343
+ for (const target of chain.open) {
344
+ if (!inside.boundary) {
345
+ open.add(target);
346
+ continue;
347
+ }
348
+ // A subflow's own traverser looks its loop targets up in its own chart: one it does not hold never resolves.
349
+ flags.push({ stageId: reported(ref.ctx, target), why: 'loop' });
350
+ bounded = false;
351
+ }
352
+ if (via === undefined || chain.known > via.known)
353
+ via = chain;
354
+ }
355
+ return { known: via?.known ?? 0, bounded, ...(via !== undefined && { via }), deps, open };
356
+ }
357
+ /**
358
+ * Turn a chain's back-edges into each position's multiplier. One loop per target, spanning to its furthest
359
+ * source. Loops are taken in start order on a stack of nested ones; a loop that overlaps the one it starts inside
360
+ * without nesting merges with it (the product of their passes — each can re-enter the other), so what is left is
361
+ * laminar, and one sweep multiplies every position by the loops around it. Returns false when a loop has no
362
+ * assumed passes (it is flagged on its target and counted once).
363
+ */
364
+ applyLoops(positions, backEdges) {
365
+ if (backEdges.length === 0)
366
+ return true;
367
+ const ends = new Map();
368
+ for (const [target, source] of backEdges)
369
+ ends.set(target, Math.max(ends.get(target) ?? target, source));
370
+ let bounded = true;
371
+ const done = [];
372
+ const active = [];
373
+ for (const [start, end] of [...ends].sort((a, b) => a[0] - b[0])) {
374
+ const target = positions[start];
375
+ const assumed = own(this.assume.loops, target.stageId);
376
+ const passes = target.declaredPasses === undefined ? assumed : Math.max(target.declaredPasses, assumed ?? 1);
377
+ if (passes === undefined) {
378
+ target.flags.push({ stageId: target.stageId, why: 'loop' });
379
+ bounded = false;
380
+ }
381
+ // The active loops nest (each inside the one below it): the innermost ends first.
382
+ let top = lastOf(active);
383
+ while (top !== undefined && top.end < start) {
384
+ done.push(top);
385
+ active.pop();
386
+ top = lastOf(active);
387
+ }
388
+ // Starts inside `top` and ends past it: they overlap without nesting — one region, the product of passes.
389
+ let loop = { start, end, passes: passes ?? 1 };
390
+ while (top !== undefined && top.end < loop.end) {
391
+ active.pop();
392
+ loop = { start: top.start, end: loop.end, passes: mul(top.passes, loop.passes) };
393
+ top = lastOf(active);
394
+ }
395
+ active.push(loop);
396
+ }
397
+ done.push(...active);
398
+ done.sort((a, b) => a.start - b.start || b.end - a.end);
399
+ const around = [];
400
+ let next = 0;
401
+ for (let q = 0; q < positions.length; q++) {
402
+ while (around.length > 0 && around[around.length - 1].end < q)
403
+ around.pop();
404
+ while (next < done.length && done[next].start === q) {
405
+ const outer = around.length > 0 ? around[around.length - 1].product : 1;
406
+ around.push({ end: done[next].end, product: mul(outer, done[next].passes) });
407
+ next++;
408
+ }
409
+ positions[q].multiplier = around.length > 0 ? around[around.length - 1].product : 1;
410
+ }
411
+ return bounded;
412
+ }
413
+ }
414
+ // ─────────────────────────────────────────────────────────────────────────────
415
+ // One stage
416
+ // ─────────────────────────────────────────────────────────────────────────────
417
+ /**
418
+ * The engine's mount test (`FlowchartTraverser` Phase 0 with `NodeResolver · resolveSubflowReference`): a subflow
419
+ * root with a subflow id runs its subflow — a lazy one always, an eager one when it has no function of its OWN and no
420
+ * children (the resolver never asks the stage map). Anything else is a node like any other.
421
+ */
422
+ function isMount(node) {
423
+ if (node.isSubflowRoot !== true || typeof node.subflowId !== 'string' || node.subflowId === '')
424
+ return false;
425
+ return node.subflowResolver !== undefined || (typeof node.fn !== 'function' && childrenOf(node).length === 0);
426
+ }
427
+ /** A node's children that are nodes — a hand-built `null` is skipped, never dereferenced. */
428
+ function childrenOf(node) {
429
+ return Array.isArray(node.children) ? node.children.filter(isNode) : [];
430
+ }
431
+ const isNode = (value) => value !== null && typeof value === 'object';
432
+ /** The engine's lookup (`FlowchartTraverser · getStageFn`): the node's own function, else the map's by id or name. */
433
+ function hasFunction(node, ctx) {
434
+ if (typeof node.fn === 'function')
435
+ return true;
436
+ const map = ctx.stageMap;
437
+ return map !== undefined && (map.get(node.id) !== undefined || map.get(node.name) !== undefined);
438
+ }
439
+ /** A stage's worst case under its policy — read by the engine's own readings of it (`attempt/policy.ts`). */
440
+ function helperCost(budget, policy) {
441
+ if (budget === undefined)
442
+ return stageCost(policy);
443
+ if (budget.role === 'callback')
444
+ return stageCost({ attempts: 1, timeoutMs: budget.timeoutMs });
445
+ const ms = budget.role === 'control' ? 0 : budget.waitMs;
446
+ return {
447
+ attempts: 1,
448
+ timeoutMs: ms ?? 0,
449
+ backoffMs: 0,
450
+ knownMs: ms ?? 0,
451
+ worstMs: ms ?? null,
452
+ ...(ms === undefined ? { why: 'backoff' } : {}),
453
+ };
454
+ }
455
+ function stageCost(policy) {
456
+ const attempts = policy === undefined ? 1 : attemptCeiling(policy.attempts);
457
+ const timeoutMs = policy === undefined ? undefined : attemptTimeoutMs(policy.timeoutMs);
458
+ const waits = waitsOf(policy, attempts);
459
+ const knownMs = add(timeoutMs === undefined ? 0 : mul(attempts, timeoutMs), waits.ms);
460
+ const why = timeoutMs === undefined ? 'no-timeout' : waits.known ? undefined : 'backoff';
461
+ return {
462
+ attempts,
463
+ ...(timeoutMs !== undefined && { timeoutMs }),
464
+ backoffMs: waits.ms,
465
+ knownMs,
466
+ worstMs: why === undefined ? knownMs : null,
467
+ ...(why !== undefined && { why }),
468
+ };
469
+ }
470
+ /**
471
+ * The waits between `attempts` attempts, as the runner waits them (`attempt/policy.ts · cappedWaitMs`). A number
472
+ * backoff is arithmetic, under the declared ceiling. A function backoff is NEVER asked — its answer may depend on the
473
+ * error, and no error exists here — so it counts at its declared ceiling per wait, or, with none, is not known
474
+ * (its waits count 0 and the stage is unbounded).
475
+ */
476
+ function waitsOf(policy, attempts) {
477
+ const waits = attempts - 1;
478
+ const backoffMs = policy?.backoffMs;
479
+ if (waits <= 0 || backoffMs === undefined)
480
+ return { ms: 0, known: true };
481
+ if (typeof backoffMs === 'function') {
482
+ const ceiling = backoffCeilingMs(policy?.maxBackoffMs);
483
+ return ceiling === undefined ? { ms: 0, known: false } : { ms: mul(waits, ceiling), known: true };
484
+ }
485
+ return { ms: mul(waits, cappedWaitMs(resolveBackoffMs(backoffMs, 1), policy?.maxBackoffMs)), known: true };
486
+ }
487
+ // ─────────────────────────────────────────────────────────────────────────────
488
+ // The report
489
+ // ─────────────────────────────────────────────────────────────────────────────
490
+ /**
491
+ * The slowest path: how many times each chain on it runs (parents before children — the reverse of the order they
492
+ * were computed in), then its stages in the order a run first reaches them. Each chain is visited once, so a
493
+ * definition mounted twice at every level of a deep nesting is one step with its passes multiplied.
494
+ */
495
+ function criticalPathOf(root, computed) {
496
+ const runs = new Map([[root, 1]]);
497
+ for (let i = computed.length - 1; i >= 0; i--) {
498
+ const chain = computed[i];
499
+ const count = runs.get(chain);
500
+ if (count === undefined)
501
+ continue;
502
+ for (const p of chain.positions) {
503
+ if (p.via !== undefined)
504
+ runs.set(p.via, add(runs.get(p.via) ?? 0, mul(count, p.multiplier)));
505
+ }
506
+ }
507
+ const steps = new Map();
508
+ walkPositions(root, (p) => p.via, (chain, p) => {
509
+ if (p.cost === undefined)
510
+ return;
511
+ const passes = mul(runs.get(chain) ?? 0, p.multiplier);
512
+ const step = steps.get(p.stageId);
513
+ if (step !== undefined) {
514
+ step.passes = add(step.passes, passes);
515
+ return;
516
+ }
517
+ steps.set(p.stageId, {
518
+ stageId: p.stageId,
519
+ attempts: p.cost.attempts,
520
+ ...(p.cost.timeoutMs !== undefined && { timeoutMs: p.cost.timeoutMs }),
521
+ backoffMs: p.cost.backoffMs,
522
+ worstMs: p.cost.worstMs,
523
+ passes,
524
+ });
525
+ });
526
+ return [...steps.values()].map((step) => Object.freeze(step));
527
+ }
528
+ /** Every unbounded stage, once, in the order a walk of the whole chart reaches it. */
529
+ function unboundedOf(root, rootFlags) {
530
+ const out = [];
531
+ const seen = new Set();
532
+ const note = (flag) => {
533
+ const key = `${flag.why}\u0000${flag.stageId}`;
534
+ if (seen.has(key))
535
+ return;
536
+ seen.add(key);
537
+ out.push(Object.freeze({ stageId: flag.stageId, why: flag.why }));
538
+ };
539
+ walkPositions(root, (p) => p.deps, (_chain, p) => p.flags.forEach(note));
540
+ rootFlags.forEach(note);
541
+ return out;
542
+ }
543
+ /** A preorder walk of positions, descending into each chain `next` names the first time it is reached. */
544
+ function walkPositions(root, next, visit) {
545
+ const visited = new Set([root]);
546
+ const stack = [{ chain: root, q: 0 }];
547
+ while (stack.length > 0) {
548
+ const top = stack[stack.length - 1];
549
+ if (top.q >= top.chain.positions.length) {
550
+ stack.pop();
551
+ continue;
552
+ }
553
+ const p = top.chain.positions[top.q++];
554
+ visit(top.chain, p);
555
+ const inner = next(p);
556
+ const chains = inner === undefined ? [] : Array.isArray(inner) ? inner : [inner];
557
+ for (let i = chains.length - 1; i >= 0; i--) {
558
+ if (visited.has(chains[i]))
559
+ continue;
560
+ visited.add(chains[i]);
561
+ stack.push({ chain: chains[i], q: 0 });
562
+ }
563
+ }
564
+ }
565
+ // ─────────────────────────────────────────────────────────────────────────────
566
+ // Words
567
+ // ─────────────────────────────────────────────────────────────────────────────
568
+ const contribution = (s) => mul(s.passes, add(mul(s.attempts, s.timeoutMs ?? 0), s.backoffMs));
569
+ /** The `limit` largest contributors, kept in path order. */
570
+ function slowestInPathOrder(steps, limit) {
571
+ const keep = new Set([...steps]
572
+ .sort((a, b) => contribution(b) - contribution(a))
573
+ .slice(0, limit)
574
+ .map((s) => s.stageId));
575
+ return steps.filter((s) => keep.has(s.stageId));
576
+ }
577
+ function stepText(s) {
578
+ const own = s.timeoutMs === undefined
579
+ ? `${s.backoffMs} ms of waits (no timeoutMs)`
580
+ : `${s.attempts} × ${s.timeoutMs} ms + ${s.backoffMs} ms of waits = ${add(mul(s.attempts, s.timeoutMs), s.backoffMs)} ms`;
581
+ return `${s.stageId}: ${own}${s.passes > 1 ? `, ${s.passes} passes` : ''}`;
582
+ }
583
+ function unboundedText(stages) {
584
+ const listed = stages.slice(0, 10).map((s) => `${s.stageId} (${s.why})`);
585
+ return stages.length > listed.length
586
+ ? `${listed.join(', ')}, and ${stages.length - listed.length} more`
587
+ : listed.join(', ');
588
+ }
589
+ // ─────────────────────────────────────────────────────────────────────────────
590
+ // Small laws
591
+ // ─────────────────────────────────────────────────────────────────────────────
592
+ /** Saturating arithmetic on non-negative milliseconds: never past `Number.MAX_SAFE_INTEGER`, never `NaN`. */
593
+ const CEILING = Number.MAX_SAFE_INTEGER;
594
+ const add = (a, b) => Math.min(a + b, CEILING);
595
+ const mul = (a, b) => (a === 0 || b === 0 ? 0 : Math.min(a * b, CEILING));
596
+ const lastOf = (items) => items[items.length - 1];
597
+ /** A budget: a number of milliseconds > 0 and no more than the saturated sums can be compared against. */
598
+ const isPositiveMs = (value) => typeof value === 'number' && value > 0 && value <= Number.MAX_SAFE_INTEGER;
599
+ const shown = (value) => (typeof value === 'number' ? String(value) : typeof value);
600
+ /** An id as the run names it: under the prefix of the chart it lives in (a lazy or branch chart's mount path). */
601
+ const reported = (ctx, id) => (ctx.prefix === '' ? id : joinPath(ctx.prefix, id));
602
+ function isChart(value) {
603
+ if (value === null || typeof value !== 'object')
604
+ return false;
605
+ const root = value.root;
606
+ return root !== null && typeof root === 'object';
607
+ }
608
+ /** An own property only — a prototype member is never an assumption or a subflow. */
609
+ function own(record, key) {
610
+ return record !== undefined && Object.prototype.hasOwnProperty.call(record, key) ? record[key] : undefined;
611
+ }
612
+ /** The engine's subflow lookup: by subflow id, then subflow name, then node name. */
613
+ function subflowDefOf(subflows, node) {
614
+ for (const key of [node.subflowId, node.subflowName, node.name]) {
615
+ if (key === undefined || key === '')
616
+ continue;
617
+ const def = own(subflows, key);
618
+ if (def !== undefined && def !== null && typeof def.root === 'object' && def.root !== null)
619
+ return def;
620
+ }
621
+ return undefined;
622
+ }
623
+ /**
624
+ * Validate the assumptions and COPY them: each own enumerable key is read exactly once, into a fresh null-prototype
625
+ * record. A getter that changes between reads, a Proxy, or a non-enumerable key can therefore never hand the walk
626
+ * a value that was not validated, and no prototype member is ever an assumption.
627
+ */
628
+ function admitAssumptions(assume) {
629
+ if (assume !== undefined && (assume === null || typeof assume !== 'object')) {
630
+ throw new TypeError('timeBudget: assume must be an object ({ loops?, lazy?, branches? }).');
631
+ }
632
+ const given = (assume ?? {});
633
+ return {
634
+ loops: snapshot(given.loops, 'loops', (key, passes) => {
635
+ if (typeof passes === 'number' && Number.isInteger(passes) && passes >= 1)
636
+ return passes;
637
+ throw new TypeError(`timeBudget: assume.loops['${key}'] must be a whole number of passes >= 1 (got ${shown(passes)}).`);
638
+ }),
639
+ lazy: snapshot(given.lazy, 'lazy', (key, chart) => assumedChart('lazy', key, chart)),
640
+ branches: snapshot(given.branches, 'branches', (key, chart) => assumedChart('branches', key, chart)),
641
+ };
642
+ }
643
+ function snapshot(record, field, admit) {
644
+ const copy = Object.create(null);
645
+ if (record === undefined)
646
+ return copy;
647
+ if (record === null || typeof record !== 'object') {
648
+ throw new TypeError(`timeBudget: assume.${field} must be an object keyed by id.`);
649
+ }
650
+ for (const key of Object.keys(record))
651
+ copy[key] = admit(key, record[key]);
652
+ return Object.freeze(copy);
653
+ }
654
+ function assumedChart(field, key, chart) {
655
+ const root = isChart(chart) ? chart.root : undefined;
656
+ if (!isNode(root)) {
657
+ throw new TypeError(`timeBudget: assume.${field}['${key}'] must be a built chart (flowChart(...).build()).`);
658
+ }
659
+ const { subflows, stageMap } = chart;
660
+ return Object.freeze({
661
+ root,
662
+ ...(subflows !== undefined && { subflows: subflows }),
663
+ ...(stageMap instanceof Map && { stageMap }),
664
+ });
665
+ }
666
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZUJ1ZGdldC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvYnVkZ2V0L3RpbWVCdWRnZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTZDRztBQUVILE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFckMsT0FBTyxFQUFFLGNBQWMsRUFBRSxnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV4RyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDakUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFHeEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUxQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQXFFN0Q7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUM7QUFFaEMsZ0ZBQWdGO0FBQ2hGLG1CQUFtQjtBQUNuQixnRkFBZ0Y7QUFFaEY7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsTUFBTSxVQUFVLFVBQVUsQ0FBQyxLQUFnQixFQUFFLE9BQTJCO0lBQ3RFLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNwQixNQUFNLElBQUksU0FBUyxDQUFDLCtFQUErRSxDQUFDLENBQUM7SUFDdkcsQ0FBQztJQUNELElBQUksT0FBTyxFQUFFLFFBQVEsS0FBSyxTQUFTLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDdkUsTUFBTSxJQUFJLFNBQVMsQ0FDakIsNkZBQTZGO1lBQzNGLFFBQVEsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxD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QUNuQixJQUFJO1FBQ0osR0FBRyxDQUFDLFFBQVEsS0FBSyxTQUFTLElBQUksRUFBRSxRQUFRLEVBQUUsUUFBK0MsRUFBRSxDQUFDO1FBQzVGLEdBQUcsQ0FBQyxRQUFRLFlBQVksR0FBRyxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUM7S0FDN0MsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogYnVkZ2V0L3RpbWVCdWRnZXQudHMg4oCUIGB0aW1lQnVkZ2V0KGNoYXJ0KWA6IHRoZSBzbG93ZXN0IGEgY2hhcnQgY2FuIHRha2UsIGZyb20gd2hhdCBpdCBkZWNsYXJlcyAoZGVzaWduXG4gKiBkb2NzL2Rlc2lnbi8yMDI2LTEwLXRpbWUtYW5kLWZhaWx1cmUtZXZpZGVuY2UubWQgwqczLjIsIHBhY2tldCBQNSkuXG4gKlxuICogV0hZOiBhIHJldHJ5IHBvbGljeSBpcyBhIHByb21pc2UgYWJvdXQgdGltZS4gYHsgYXR0ZW1wdHM6IDQsIHRpbWVvdXRNczogNDBfMDAwLCBiYWNrb2ZmTXM6IDFfMDAwIH1gIGFsbG93c1xuICogNCDDlyA0MCAwMDAgKyAzIMOXIDEgMDAwID0gMTYzIDAwMCBtcywgYW5kIGEgY2FsbGVyIHdobyBnYXZlIHRoZSBjaGFydCAxMjAgcyBpcyBub3Qgc2VydmVkIGJ5IGl0IOKAlCB3aGljaCBpc1xuICoga25vd2FibGUgYmVmb3JlIGEgc2luZ2xlIHN0YWdlIHJ1bnMuIGAuYnVkZ2V0KG1zKWAgZGVjbGFyZXMgdGhlIGNhbGxlcidzIGNvbnRyYWN0IG9uIHRoZSBjaGFydDsgYGJ1aWxkKClgIHJlZnVzZXNcbiAqIGEgY2hhcnQgd2hvc2UgZGVjbGFyZWQgcG9saWNpZXMgYWxyZWFkeSBhbGxvdyBsb25nZXIgKG93bmVyIHJ1bGluZyBRMikgYW5kIHdhcm5zLCBieSBuYW1lLCBhYm91dCBldmVyeSBzdGFnZSBpdFxuICogY2Fubm90IGJvdW5kLiBBbiB1bmJvdW5kZWQgc3RhZ2UgaXMgbmV2ZXIgZ3Vlc3NlZCBhcm91bmQ6IGl0IGlzIGNvdW50ZWQgYXMgMCBhbmQgbmFtZWQuXG4gKlxuICogVEhFIFJVTEVTIChvbmUgd2FsayBvZiB0aGUgYnVpbHQgU3RhZ2VOb2RlIGdyYXBoOyBlYWNoIGNoYWluIG9mIGBuZXh0YCBwb2ludGVycyBpcyBjb21wdXRlZCBvbmNlIHBlciBzdGFydCk6XG4gKiAgIC0gYSBzdGFnZSB3aXRoIGEgZnVuY3Rpb246IGBhdHRlbXB0cyDDlyB0aW1lb3V0TXNgIHBsdXMgdGhlIHdhaXRzIGJldHdlZW4gaXRzIGF0dGVtcHRzLCBhcyB0aGUgcnVubmVyIHdhaXRzIHRoZW1cbiAqICAgICAoYGF0dGVtcHQvcG9saWN5LnRzYCkuIEEgbnVtYmVyIGBiYWNrb2ZmTXNgIGlzIGFyaXRobWV0aWMsIHVuZGVyIGBtYXhCYWNrb2ZmTXNgIHdoZW4gZGVjbGFyZWQuIEEgRlVOQ1RJT04gaXNcbiAqICAgICBuZXZlciBhc2tlZDogaXQgbWF5IHJlYWQgdGhlIGVycm9yIChhIHN0YXRlZCBgUmV0cnktQWZ0ZXJgKSBhbmQgbm8gZXJyb3IgZXhpc3RzIGhlcmUsIHNvIGFza2luZyBpdCB3aXRoIG5vbmVcbiAqICAgICBjb3VsZCBVTkRFUkVTVElNQVRFLiBJdCBjb3VudHMgYXQgaXRzIGRlY2xhcmVkIGNlaWxpbmcsIGBtYXhCYWNrb2ZmTXNgIHBlciB3YWl0ICh0aGUgcnVubmVyIGVuZm9yY2VzIGl0KTsgd2l0aFxuICogICAgIG5vIGNlaWxpbmcgdGhlIHN0YWdlIGlzIHVuYm91bmRlZCBgJ2JhY2tvZmYnYC4gTm8gYHRpbWVvdXRNc2Ag4oaSIHVuYm91bmRlZCBgJ25vLXRpbWVvdXQnYDtcbiAqICAgLSBhIHNlcXVlbmNlOiB0aGUgc3VtLiBBIGRlY2lkZXIsIGEgc2VsZWN0b3IsIGEgZm9yazogdGhlIG5vZGUncyBvd24gc3RhZ2UgcGx1cyBpdHMgc2xvd2VzdCBjaGlsZCAoYSBmb3JrJ3NcbiAqICAgICBjaGlsZHJlbiwgYW5kIGEgc2VsZWN0b3IncyBwaWNrcywgcnVuIGF0IG9uY2UpO1xuICogICAtIGEgbW91bnRlZCBzdWJmbG93OiBpdHMgY2hhcnQsIHdhbGtlZCB0aGUgc2FtZSB3YXksIHVuZGVyIHRoZSBpZHMgdGhlIHJ1biBnaXZlcyBpdHMgc3RhZ2VzIChgcGF5L2NoYXJnZWApO1xuICogICAgIGEgbGF6eSBvbmUgaXMgdW5ib3VuZGVkIGAnbGF6eS1zdWJmbG93J2AgdW5sZXNzIGBhc3N1bWUubGF6eVtzdWJmbG93SWRdYCBuYW1lcyB0aGUgY2hhcnQgaXQgcmVzb2x2ZXMgdG87XG4gKiAgIC0gYHBhcmFsbGVsRm9yRWFjaGA6IE9ORSBicmFuY2gg4oCUIHRoZSBicmFuY2hlcyBydW4gYXQgb25jZSBhbmQgYG1heEJyYW5jaGVzYCB0cnVuY2F0ZXMsIHNvIHRoZSBpdGVtIGNvdW50IG5ldmVyXG4gKiAgICAgYWRkcyB0aW1lLiBUaGUgYnJhbmNoIGNoYXJ0IGlzIGJ1aWx0IGF0IHJ1biB0aW1lLCBzbyBpdCBpcyB1bmJvdW5kZWQgYCdpdGVtcydgIHVubGVzc1xuICogICAgIGBhc3N1bWUuYnJhbmNoZXNbc3RhZ2VJZF1gIG5hbWVzIGl0IChpdHMgc3RhZ2VzIGFyZSByZXBvcnRlZCB1bmRlciB0aGUgZmlyc3QgYnJhbmNoLCBgcmV2aWV3fjAvc2NvcmVgKTtcbiAqICAgLSBhIGxvb3AgaXMgTkVWRVIgaXRlcmF0ZWQuIFdpdGggbm8gYXNzdW1wdGlvbiBpdCBpcyB1bmJvdW5kZWQgYCdsb29wJ2AsIG5hbWVkIGJ5IGl0cyB0YXJnZXQsIGFuZCBjb3VudGVkIG9uY2UuXG4gKiAgICAgYGFzc3VtZS5sb29wc1t0YXJnZXRJZF0gPSBuYCBib3VuZHMgaXQ6IGVhY2ggdGltZSB0aGUgY2hhcnQgcmVhY2hlcyB0aGUgbG9vcCwgZXZlcnkgc3RhZ2UgZnJvbSB0aGUgdGFyZ2V0IHRvXG4gKiAgICAgdGhlIGxvb3AncyBmdXJ0aGVzdCBzb3VyY2UgcnVucyBhdCBtb3N0IGBuYCB0aW1lcywgZWFjaCBhdCBpdHMgc2xvd2VzdC4gTmVzdGVkIGxvb3BzIG11bHRpcGx5OyB0d28gbG9vcHMgdGhhdFxuICogICAgIG92ZXJsYXAgd2l0aG91dCBuZXN0aW5nIGFyZSBvbmUgcmVnaW9uIGJvdW5kZWQgYnkgdGhlIHByb2R1Y3Qgb2YgdGhlaXIgcGFzc2VzIChlYWNoIGNhbiByZS1lbnRlciB0aGUgb3RoZXIpLlxuICpcbiAqIFRXTyBOVU1CRVJTLiBga25vd25Nc2AgY291bnRzIHdoYXQgaXMgYm91bmRlZCAoYW4gdW5ib3VuZGVkIHN0YWdlIGFzIDAsIGFuIHVuYXNzdW1lZCBsb29wIG9uY2UpLiBXaXRob3V0XG4gKiBhc3N1bXB0aW9ucyBpdCBpcyBhIHRpbWUgdGhlIGRlY2xhcmVkIHBvbGljaWVzIEFMTE9XIGEgcnVuIHRvIHRha2UgKGByZXRyeU9uYCBpcyBub3QgcmVhZDogaXQgbWF5IG9ubHkgZW5kIGEgc2VyaWVzXG4gKiBzb29uZXIpLCBzbyBhIGJ1ZGdldCBiZWxvdyBpdCBjYW5ub3QgYmUgcHJvbWlzZWQg4oCUIGBvdmVyYCBhbmQgdGhlIGJ1aWxkIHJlZnVzYWwgcmVhZCBpdCwgb24gYW4gdW5ib3VuZGVkIHBhdGggdG9vLlxuICogYHdvcnN0Q2FzZU1zYCBpcyBga25vd25Nc2Agd2hlbiBldmVyeSBwYXRoIGlzIGJvdW5kZWQsIGBudWxsYCBvdGhlcndpc2U7IHdpdGggYW4gYXNzdW1lZCBsb29wIGl0IGlzIGFuIHVwcGVyIGJvdW5kXG4gKiB1bmRlciB0aGF0IGFzc3VtcHRpb24gKGV2ZXJ5IHBhc3MgaXMgY291bnRlZCBhdCBpdHMgc2xvd2VzdCBicmFuY2gpLlxuICpcbiAqIFRIUkVBVCBNT0RFTC4gVGhlIHdhbGsgdGVybWluYXRlcyBvbiBhbnkgZ3JhcGg6IGEgY2hhaW4gaXMgd2Fsa2VkIHdpdGggYSB2aXNpdGVkIHNldCAoYSBgbmV4dGAgdGhhdCBjbG9zZXMgb25cbiAqIGl0c2VsZiBpcyBhIGxvb3ApLCBuZXN0aW5nIGlzIGFuIGV4cGxpY2l0IHN0YWNrIChubyByZWN1cnNpb24g4oCUIGEgNSAwMDAtZGVlcCBzdWJmbG93IG5lc3Rpbmcgd2Fsa3MpLCBhIGNoYWluIHRoYXRcbiAqIHJlYWNoZXMgaXRzZWxmIHRocm91Z2ggaXRzIGNoaWxkcmVuIG9yIGEgc3ViZmxvdyBpcyBhIGxvb3AsIGFuZCBldmVyeSBjaGFpbiBpcyBjb21wdXRlZCBvbmNlIHBlciBzdGFydCBob3dldmVyXG4gKiBvZnRlbiBpdCBpcyBtb3VudGVkLiBUaGUgd2FsayBpcyBDQVBQRUQ6IHBhc3QgYE1BWF9XQUxLYCBub2RlIHZpc2l0cyBpdCBzdG9wcyB3aXRoIGEgYFJhbmdlRXJyb3JgIOKAlCBhIGJ1aWxkZXIgY2hhcnRcbiAqIHZpc2l0cyBlYWNoIG5vZGUgYXQgbW9zdCB0d2ljZSwgYnV0IGEgaGFuZC1idWlsdCBncmFwaCB3aG9zZSBjaGFpbnMgc2hhcmUgdGhlaXIgdGFpbHMgaXMgd2Fsa2VkIG9uY2UgcGVyIGNoYWluLlxuICogU3VtcyBhbmQgcHJvZHVjdHMgc2F0dXJhdGUgYXQgYE51bWJlci5NQVhfU0FGRV9JTlRFR0VSYCDigJQgbmV2ZXIgYEluZmluaXR5YCBvciBgTmFOYC4gQXNzdW1wdGlvbnMgYXJlIGNvcGllZCBPTkNFLFxuICogb3duIGVudW1lcmFibGUgcHJvcGVydGllcyBvbmx5LCBpbnRvIGZyZXNoIG51bGwtcHJvdG90eXBlIHJlY29yZHMsIGFuZCBvbmx5IHRoYXQgY29weSBpcyByZWFkLlxuICpcbiAqIFdoYXQgaXQgZG9lcyBOT1QgY291bnQ6IHRoZSBlbmdpbmUncyBvd24gd29yayBiZXR3ZWVuIHN0YWdlcywgYSBzdGFnZSBmdW5jdGlvbiB0aGF0IGJsb2NrcyB0aGUgdGhyZWFkIChhIHRpbWVvdXRcbiAqIHN0b3BzIHRoZSBXQUlUSU5HLCBzZWUgdGhlIGF0dGVtcHQgcnVubmVyKSwgYW5kIGEgU3RhZ2VOb2RlIGEgc3RhZ2UgcmV0dXJucyBhdCBydW4gdGltZSDigJQgYW55IHN0YWdlIG1heSBncm93IHRoZVxuICogZ3JhcGggdGhhdCB3YXksIHNvIHRoZSBidWRnZXQgaXMgb2YgdGhlIGdyYXBoIHRoZSBjaGFydCBERUNMQVJFUy5cbiAqL1xuXG5pbXBvcnQgeyBqb2luUGF0aCB9IGZyb20gJ2Zvb3R0cmFjZSc7XG5cbmltcG9ydCB7IGF0dGVtcHRDZWlsaW5nLCBhdHRlbXB0VGltZW91dE1zLCBiYWNrb2ZmQ2VpbGluZ01zLCBjYXBwZWRXYWl0TXMgfSBmcm9tICcuLi9hdHRlbXB0L3BvbGljeS5qcyc7XG5pbXBvcnQgdHlwZSB7IFJldHJ5TG9vcEJ1ZGdldCB9IGZyb20gJy4uL2F0dGVtcHQvcmV0cnlMb29wQ29udGV4dC5qcyc7XG5pbXBvcnQgeyByZXRyeUxvb3BCdWRnZXQgfSBmcm9tICcuLi9hdHRlbXB0L3JldHJ5TG9vcENvbnRleHQuanMnO1xuaW1wb3J0IHsgcmVzb2x2ZUJhY2tvZmZNcyB9IGZyb20gJy4uL2F0dGVtcHQvcnVubmVyLmpzJztcbmltcG9ydCB0eXBlIHsgUmV0cnlQb2xpY3kgfSBmcm9tICcuLi9hdHRlbXB0L3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIHsgRmxvd0NoYXJ0IH0gZnJvbSAnLi4vYnVpbGRlci90eXBlcy5qcyc7XG5pbXBvcnQgeyBpc0Rldk1vZGUgfSBmcm9tICcuLi9kZXZNb2RlLmpzJztcbmltcG9ydCB0eXBlIHsgU3RhZ2VOb2RlIH0gZnJvbSAnLi4vZW5naW5lL2dyYXBoL1N0YWdlTm9kZS5qcyc7XG5pbXBvcnQgeyBidWlsZEJyYW5jaFNlZ21lbnQgfSBmcm9tICcuLi9pZHMvYnJhbmNoU2VnbWVudC5qcyc7XG5cbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gUHVibGljIHNoYXBlc1xuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbi8qKlxuICogV2h5IGEgc3RhZ2Uga2VlcHMgYSBwYXRoIHVuYm91bmRlZDogbm8gcGVyLWF0dGVtcHQgY2FwIChgJ25vLXRpbWVvdXQnYCk7IGEgZnVuY3Rpb24gYmFja29mZiB3aXRoIG5vIGRlY2xhcmVkXG4gKiBgbWF4QmFja29mZk1zYCAoYCdiYWNrb2ZmJ2Ag4oCUIGl0cyB3YWl0cyBtYXkgZGVwZW5kIG9uIGFuIGVycm9yIHRoYXQgZG9lcyBub3QgZXhpc3QgYXQgYnVpbGQpOyBhIGxvb3Agd2l0aCBub1xuICogYXNzdW1lZCBwYXNzZXMgKGAnbG9vcCdgLCBuYW1lZCBieSBpdHMgdGFyZ2V0KTsgYSBsYXp5IHN1YmZsb3cgd2hvc2UgY2hhcnQgaXMgdW5rbm93biBhdCBidWlsZCAoYCdsYXp5LXN1YmZsb3cnYCk7XG4gKiBhIGBwYXJhbGxlbEZvckVhY2hgIHdob3NlIGJyYW5jaCBjaGFydCBpcyBidWlsdCBhdCBydW4gdGltZSAoYCdpdGVtcydgKS5cbiAqL1xuZXhwb3J0IHR5cGUgVW5ib3VuZGVkUmVhc29uID0gJ25vLXRpbWVvdXQnIHwgJ2JhY2tvZmYnIHwgJ2xvb3AnIHwgJ2xhenktc3ViZmxvdycgfCAnaXRlbXMnO1xuXG4vKiogQSBzdGFnZSBvbiB0aGUgc2xvd2VzdCBwYXRoLCB3aXRoIHdoYXQgaXQgZGVjbGFyZXMgYW5kIGhvdyBtYW55IHRpbWVzIHRoZSBwYXRoIHJ1bnMgaXQuICovXG5leHBvcnQgaW50ZXJmYWNlIEJ1ZGdldFN0ZXAge1xuICAvKiogVGhlIHN0YWdlIGlkIGFzIHRoZSBydW4gbmFtZXMgaXQg4oCUIGEgc3ViZmxvdydzIHN0YWdlcyB1bmRlciB0aGVpciBtb3VudCAoYHBheS9jaGFyZ2VgKS4gKi9cbiAgcmVhZG9ubHkgc3RhZ2VJZDogc3RyaW5nO1xuICAvKiogSG93IG1hbnkgYXR0ZW1wdHMgaXRzIHBvbGljeSBhbGxvd3MgKDEgd2l0aG91dCBvbmUpLiAqL1xuICByZWFkb25seSBhdHRlbXB0czogbnVtYmVyO1xuICAvKiogVGhlIGNhcCBvbiBvbmUgYXR0ZW1wdDsgYWJzZW50IHdoZW4gdGhlIHN0YWdlIGRlY2xhcmVzIG5vbmUgKHRoZW4gYHdvcnN0TXNgIGlzIGBudWxsYCkuICovXG4gIHJlYWRvbmx5IHRpbWVvdXRNcz86IG51bWJlcjtcbiAgLyoqIFRoZSB3YWl0cyBiZXR3ZWVuIGl0cyBhdHRlbXB0cywgaW4gdG90YWwuICovXG4gIHJlYWRvbmx5IGJhY2tvZmZNczogbnVtYmVyO1xuICAvKiogYGF0dGVtcHRzIMOXIHRpbWVvdXRNcyArIGJhY2tvZmZNc2Ag4oCUIGBudWxsYCB3aGVuIHRoZSBzdGFnZSBpcyB1bmJvdW5kZWQuICovXG4gIHJlYWRvbmx5IHdvcnN0TXM6IG51bWJlciB8IG51bGw7XG4gIC8qKiBIb3cgbWFueSB0aW1lcyB0aGUgcGF0aCBydW5zIGl0IOKAlCBtb3JlIHRoYW4gMSBvbmx5IGluc2lkZSBhbiBhc3N1bWVkIGxvb3AuICovXG4gIHJlYWRvbmx5IHBhc3NlczogbnVtYmVyO1xufVxuXG4vKiogQSBzdGFnZSB0aGUgY2hlY2sgY2Fubm90IGJvdW5kLCBhbmQgd2h5LiAqL1xuZXhwb3J0IGludGVyZmFjZSBVbmJvdW5kZWRTdGFnZSB7XG4gIHJlYWRvbmx5IHN0YWdlSWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgd2h5OiBVbmJvdW5kZWRSZWFzb247XG59XG5cbi8qKiBXaGF0IHRoZSBjYWxsZXIga25vd3MgdGhhdCB0aGUgY2hhcnQgZG9lcyBub3QgZGVjbGFyZS4gS2V5cyBhcmUgaWRzIGFzIHRoZSBydW4gbmFtZXMgdGhlbS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQnVkZ2V0QXNzdW1wdGlvbnMge1xuICAvKiogQSBsb29wJ3MgVEFSR0VUIGlkICh3aGF0IGBsb29wVG9gIG5hbWVzKSDihpIgdGhlIG1vc3QgcGFzc2VzIHRocm91Z2ggaXQgZWFjaCB0aW1lIHRoZSBjaGFydCByZWFjaGVzIGl0ICjiiaUgMSkuICovXG4gIHJlYWRvbmx5IGxvb3BzPzogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgbnVtYmVyPj47XG4gIC8qKiBBIGxhenkgbW91bnQncyBzdWJmbG93IGlkIOKGkiB0aGUgY2hhcnQgaXQgcmVzb2x2ZXMgdG8uICovXG4gIHJlYWRvbmx5IGxhenk/OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBGbG93Q2hhcnQ+PjtcbiAgLyoqIEEgYHBhcmFsbGVsRm9yRWFjaGAgc3RhZ2UgaWQg4oaSIHRoZSBjaGFydCBvbmUgYnJhbmNoIHJ1bnMuICovXG4gIHJlYWRvbmx5IGJyYW5jaGVzPzogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgRmxvd0NoYXJ0Pj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGltZUJ1ZGdldE9wdGlvbnMge1xuICAvKiogVGhlIGJ1ZGdldCB0byBjaGVjayBhZ2FpbnN0LiBEZWZhdWx0cyB0byB0aGUgY2hhcnQncyBkZWNsYXJlZCBgLmJ1ZGdldChtcylgLiBBIGZpbml0ZSBudW1iZXIgPiAwLiAqL1xuICByZWFkb25seSBidWRnZXRNcz86IG51bWJlcjtcbiAgcmVhZG9ubHkgYXNzdW1lPzogQnVkZ2V0QXNzdW1wdGlvbnM7XG59XG5cbi8qKiBXaGF0IGB0aW1lQnVkZ2V0KGNoYXJ0KWAgcmVwb3J0cy4gSlNPTi1zYWZlIGFuZCBmcm96ZW4uICovXG5leHBvcnQgaW50ZXJmYWNlIFRpbWVCdWRnZXRSZXBvcnQge1xuICAvKiogVGhlIHdvcnN0IGNhc2Ugb2YgdGhlIHNsb3dlc3QgcGF0aCDigJQgYG51bGxgIHdoZW4gYW55IHBhdGggaXMgdW5ib3VuZGVkIChzZWUgYHVuYm91bmRlZGApLiAqL1xuICByZWFkb25seSB3b3JzdENhc2VNczogbnVtYmVyIHwgbnVsbDtcbiAgLyoqIFRoZSB3b3JzdCBjYXNlIG9mIHdoYXQgSVMgYm91bmRlZDogYW4gdW5ib3VuZGVkIHN0YWdlIGNvdW50cyAwLCBhbiB1bmFzc3VtZWQgbG9vcCBvbmUgcGFzcy4gKi9cbiAgcmVhZG9ubHkga25vd25NczogbnVtYmVyO1xuICAvKiogVGhlIHN0YWdlcyBvZiB0aGUgc2xvd2VzdCBwYXRoLCBpbiB0aGUgb3JkZXIgYSBydW4gZmlyc3QgcmVhY2hlcyB0aGVtIOKAlCB0aGUgcGF0aCB0aGF0IG1ha2VzIGB3b3JzdENhc2VNc2AsXG4gICAqICBvciBga25vd25Nc2Agd2hlbiBhIHBhdGggaXMgdW5ib3VuZGVkLiBga25vd25NcyA9IM6jIHBhc3NlcyDDlyAoYXR0ZW1wdHMgw5cgKHRpbWVvdXRNcyA/PyAwKSArIGJhY2tvZmZNcylgLiAqL1xuICByZWFkb25seSBjcml0aWNhbFBhdGg6IHJlYWRvbmx5IEJ1ZGdldFN0ZXBbXTtcbiAgLyoqIEV2ZXJ5IHN0YWdlIHRoYXQga2VlcHMgYSBwYXRoIHVuYm91bmRlZCwgZWFjaCBuYW1lZCBvbmNlLCBpbiBjaGFydCBvcmRlci4gKi9cbiAgcmVhZG9ubHkgdW5ib3VuZGVkOiByZWFkb25seSBVbmJvdW5kZWRTdGFnZVtdO1xuICAvKiogVGhlIGJ1ZGdldCBjaGVja2VkIGFnYWluc3Qg4oCUIGFic2VudCB3aGVuIHRoZXJlIGlzIG5vbmUuICovXG4gIHJlYWRvbmx5IGJ1ZGdldE1zPzogbnVtYmVyO1xuICAvKiogYGtub3duTXMgPiBidWRnZXRNc2A6IHRoZSBkZWNsYXJlZCBwb2xpY2llcyBhbGxvdyBsb25nZXIgdGhhbiB0aGUgYnVkZ2V0LiBBbHdheXMgYGZhbHNlYCB3aXRob3V0IG9uZS4gKi9cbiAgcmVhZG9ubHkgb3ZlcjogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBUaGUgbW9zdCBub2RlIHZpc2l0cyBvbmUgd2FsayBtYWtlcy4gQSBidWlsZGVyIGNoYXJ0IHZpc2l0cyBlYWNoIG5vZGUgYXQgbW9zdCB0d2ljZSwgc28gMjUwIDAwMCBpcyBmYXIgcGFzdCBhbnlcbiAqIHJlYWwgY2hhcnQ7IGEgaGFuZC1idWlsdCBncmFwaCB3aG9zZSBjaGFpbnMgc2hhcmUgdGhlaXIgdGFpbHMgY2FuIG5lZWQgbW9yZSAoZWFjaCBjaGFpbiB3YWxrcyB0aGUgc2hhcmVkIHRhaWwpLFxuICogYW5kIHRoZSBjaGVjayBzdG9wcyB0aGVyZSB3aXRoIGEgYFJhbmdlRXJyb3JgIHJhdGhlciB0aGFuIGdyb3cgd2l0aG91dCBib3VuZC5cbiAqL1xuZXhwb3J0IGNvbnN0IE1BWF9XQUxLID0gMjUwXzAwMDtcblxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vLyBUaGUgZW50cnkgcG9pbnRzXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuLyoqXG4gKiBUaGUgc2xvd2VzdCB0aGUgY2hhcnQgY2FuIHRha2UsIGNvbXB1dGVkIGZyb20gaXRzIGRlY2xhcmVkIHJldHJ5IHBvbGljaWVzIOKAlCBhbmQgZXZlcnkgc3RhZ2UgdGhhdCBtYWtlcyBhIHBhdGhcbiAqIHVuYm91bmRlZCwgYnkgbmFtZS4gU2VlIHRoZSBtb2R1bGUgaGVhZGVyIGZvciB0aGUgcnVsZXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBjb25zdCByZXBvcnQgPSB0aW1lQnVkZ2V0KGNoYXJ0LCB7IGJ1ZGdldE1zOiAxMjBfMDAwLCBhc3N1bWU6IHsgbG9vcHM6IHsgJ2Fzay1hZ2Fpbic6IDMgfSB9IH0pO1xuICogcmVwb3J0LndvcnN0Q2FzZU1zOyAgLy8gbnVtYmVyLCBvciBudWxsIHdoZW4gYSBwYXRoIGlzIHVuYm91bmRlZFxuICogcmVwb3J0LmNyaXRpY2FsUGF0aDsgLy8gW3sgc3RhZ2VJZCwgYXR0ZW1wdHMsIHRpbWVvdXRNcywgYmFja29mZk1zLCB3b3JzdE1zLCBwYXNzZXMgfV1cbiAqIHJlcG9ydC51bmJvdW5kZWQ7ICAgIC8vIFt7IHN0YWdlSWQsIHdoeTogJ25vLXRpbWVvdXQnIHwgJ2JhY2tvZmYnIHwgJ2xvb3AnIHwgJ2xhenktc3ViZmxvdycgfCAnaXRlbXMnIH1dXG4gKiByZXBvcnQub3ZlcjsgICAgICAgICAvLyB0cnVlIHdoZW4gdGhlIGRlY2xhcmVkIHBvbGljaWVzIGFsbG93IGxvbmdlciB0aGFuIGJ1ZGdldE1zXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRpbWVCdWRnZXQoY2hhcnQ6IEZsb3dDaGFydCwgb3B0aW9ucz86IFRpbWVCdWRnZXRPcHRpb25zKTogVGltZUJ1ZGdldFJlcG9ydCB7XG4gIGlmICghaXNDaGFydChjaGFydCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aW1lQnVkZ2V0KGNoYXJ0KTogcGFzcyBhIGJ1aWx0IGNoYXJ0IOKAlCB0aGUgcmVzdWx0IG9mIGZsb3dDaGFydCguLi4pLmJ1aWxkKCkuJyk7XG4gIH1cbiAgaWYgKG9wdGlvbnM/LmJ1ZGdldE1zICE9PSB1bmRlZmluZWQgJiYgIWlzUG9zaXRpdmVNcyhvcHRpb25zLmJ1ZGdldE1zKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAndGltZUJ1ZGdldDogYnVkZ2V0TXMgbXVzdCBiZSBhIG51bWJlciBvZiBtaWxsaXNlY29uZHMgPiAwLCBhdCBtb3N0IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSICcgK1xuICAgICAgICBgKGdvdCAke3Nob3duKG9wdGlvbnMuYnVkZ2V0TXMpfSkuYCxcbiAgICApO1xuICB9XG4gIGNvbnN0IGJ1ZGdldE1zID0gb3B0aW9ucz8uYnVkZ2V0TXMgPz8gZGVjbGFyZWRCdWRnZXQoY2hhcnQpO1xuICBjb25zdCB3YWxrID0gbmV3IEJ1ZGdldFdhbGsoYWRtaXRBc3N1bXB0aW9ucyhvcHRpb25zPy5hc3N1bWUpKTtcbiAgY29uc3QgY3R4ID0gd2Fsay5jdHhPZihjaGFydCwgJycpO1xuICBjb25zdCByb290ID0gd2Fsay5ldmFsdWF0ZSh7IGN0eCwgc3RhcnQ6IGNoYXJ0LnJvb3QgfSk7XG5cbiAgLy8gQSBsb29wIHdob3NlIHRhcmdldCB0aGUgY2hhcnQgZG9lcyBub3QgaG9sZCBjYW5ub3QgYmUgYm91bmRlZCBieSBhbnkgYXNzdW1wdGlvbi5cbiAgY29uc3Qgcm9vdEZsYWdzID0gWy4uLnJvb3Qub3Blbl0ubWFwKCh0YXJnZXQpID0+ICh7IHN0YWdlSWQ6IHJlcG9ydGVkKGN0eCwgdGFyZ2V0KSwgd2h5OiAnbG9vcCcgYXMgY29uc3QgfSkpO1xuICBjb25zdCBib3VuZGVkID0gcm9vdC5ib3VuZGVkICYmIHJvb3Qub3Blbi5zaXplID09PSAwO1xuICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG4gICAgd29yc3RDYXNlTXM6IGJvdW5kZWQgPyByb290Lmtub3duIDogbnVsbCxcbiAgICBrbm93bk1zOiByb290Lmtub3duLFxuICAgIGNyaXRpY2FsUGF0aDogT2JqZWN0LmZyZWV6ZShjcml0aWNhbFBhdGhPZihyb290LCB3YWxrLmNvbXB1dGVkKSksXG4gICAgdW5ib3VuZGVkOiBPYmplY3QuZnJlZXplKHVuYm91bmRlZE9mKHJvb3QsIHJvb3RGbGFncykpLFxuICAgIC4uLihidWRnZXRNcyAhPT0gdW5kZWZpbmVkICYmIHsgYnVkZ2V0TXMgfSksXG4gICAgb3ZlcjogYnVkZ2V0TXMgIT09IHVuZGVmaW5lZCAmJiByb290Lmtub3duID4gYnVkZ2V0TXMsXG4gIH0pO1xufVxuXG4vKiogVGhlIGNoYXJ0J3MgZGVjbGFyZWQgYnVkZ2V0IChgLmJ1ZGdldChtcylgLCB0aGUgc3BlYyByb290J3MgYGJ1ZGdldE1zYCksIG9yIGB1bmRlZmluZWRgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlY2xhcmVkQnVkZ2V0KGNoYXJ0OiBGbG93Q2hhcnQpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICBjb25zdCBidWRnZXRNcyA9IGNoYXJ0LmJ1aWxkVGltZVN0cnVjdHVyZT8uYnVkZ2V0TXM7XG4gIHJldHVybiBpc1Bvc2l0aXZlTXMoYnVkZ2V0TXMpID8gYnVkZ2V0TXMgOiB1bmRlZmluZWQ7XG59XG5cbi8qKiBgYnVpbGQoKWAncyByZWZ1c2FsIGZvciBhIGRlY2xhcmVkIGJ1ZGdldCB0aGUgY2hhcnQgY2FuIGFscmVhZHkgZXhjZWVkLCBvciBgdW5kZWZpbmVkYCB3aGVuIGl0IGNhbiBrZWVwIGl0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1ZGdldFJlZnVzYWwocmVwb3J0OiBUaW1lQnVkZ2V0UmVwb3J0KTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgaWYgKCFyZXBvcnQub3ZlciB8fCByZXBvcnQuYnVkZ2V0TXMgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgY291bnRlZCA9IHJlcG9ydC5jcml0aWNhbFBhdGguZmlsdGVyKChzdGVwKSA9PiBjb250cmlidXRpb24oc3RlcCkgPiAwKTtcbiAgY29uc3Qgc2hvd25TdGVwcyA9IHNsb3dlc3RJblBhdGhPcmRlcihjb3VudGVkLCA1KS5tYXAoc3RlcFRleHQpO1xuICBjb25zdCBtb3JlID0gY291bnRlZC5sZW5ndGggPiBzaG93blN0ZXBzLmxlbmd0aCA/IGAsIGFuZCAke2NvdW50ZWQubGVuZ3RoIC0gc2hvd25TdGVwcy5sZW5ndGh9IG1vcmVgIDogJyc7XG4gIGNvbnN0IHVuY291bnRlZCA9XG4gICAgcmVwb3J0LnVuYm91bmRlZC5sZW5ndGggPiAwID8gYCBOb3QgY291bnRlZCwgaGF2aW5nIG5vIGJvdW5kOiAke3VuYm91bmRlZFRleHQocmVwb3J0LnVuYm91bmRlZCl9LmAgOiAnJztcbiAgcmV0dXJuIChcbiAgICBgYnVkZ2V0KCR7cmVwb3J0LmJ1ZGdldE1zfSk6IGl0cyBkZWNsYXJlZCBwb2xpY2llcyBhbGxvdyAke3JlcG9ydC5rbm93bk1zfSBtcywgb3ZlciBpdHMgYnVkZ2V0IGJ5IGAgK1xuICAgIGAke3JlcG9ydC5rbm93bk1zIC0gcmVwb3J0LmJ1ZGdldE1zfSBtcy4gU2xvd2VzdCBwYXRoOiAke3Nob3duU3RlcHMuam9pbignOyAnKX0ke21vcmV9LiBMb3dlciBhdHRlbXB0cyBvciBgICtcbiAgICBgdGltZW91dE1zIG9uIHRoZXNlIHN0YWdlcywgb3IgcmFpc2UgdGhlIGJ1ZGdldC4ke3VuY291bnRlZH1gXG4gICk7XG59XG5cbi8qKiBgYnVpbGQoKWAncyBkZXYtbW9kZSB3YXJuaW5nIGZvciBhIGRlY2xhcmVkIGJ1ZGdldCBpdCBjYW5ub3QgY2hlY2sgb24gZXZlcnkgcGF0aCwgb3IgYHVuZGVmaW5lZGAuICovXG5leHBvcnQgZnVuY3Rpb24gYnVkZ2V0V2FybmluZyhyZXBvcnQ6IFRpbWVCdWRnZXRSZXBvcnQsIGNoYXJ0TmFtZTogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHJlcG9ydC5idWRnZXRNcyA9PT0gdW5kZWZpbmVkIHx8IHJlcG9ydC51bmJvdW5kZWQubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4gKFxuICAgIGBbZm9vdHByaW50XSBjaGFydCAnJHtjaGFydE5hbWV9JyBkZWNsYXJlcyBhIGJ1ZGdldCBvZiAke3JlcG9ydC5idWRnZXRNc30gbXMsIGJ1dCB0aGUgY2hlY2sgY2Fubm90IGJvdW5kIGAgK1xuICAgIGBldmVyeSBwYXRoOiAke3VuYm91bmRlZFRleHQocmVwb3J0LnVuYm91bmRlZCl9LiBHaXZlIGEgc3RhZ2UgYSByZXRyeSh7IHRpbWVvdXRNcyB9KSBhbmQgYSBmdW5jdGlvbiBiYWNrb2ZmIGEgYCArXG4gICAgJ21heEJhY2tvZmZNczsgYm91bmQgYSBsb29wLCBhIGxhenkgc3ViZmxvdyBvciBhIHBhcmFsbGVsRm9yRWFjaCB3aXRoIHRpbWVCdWRnZXQoY2hhcnQsIHsgYXNzdW1lIH0pLidcbiAgKTtcbn1cblxuLyoqIENoYXJ0cyBhbHJlYWR5IHdhcm5lZCBhdCBydW4gc3RhcnQg4oCUIHRoZSB3YXJuaW5nIGlzIHNhaWQgb25jZSBwZXIgY2hhcnQuICovXG5jb25zdCB3YXJuZWRBdFJ1blN0YXJ0ID0gbmV3IFdlYWtTZXQ8b2JqZWN0PigpO1xuXG4vKipcbiAqIFRoZSBydW4tc3RhcnQgd2FybmluZyAoZGV2IG1vZGUsIG9uY2UgcGVyIGNoYXJ0KTogdGhlIHJ1bidzIGRlYWRsaW5lIGxlYXZlcyB0aGUgY2hhcnQgbGVzcyB0aW1lIHRoYW4gaXRzIGRlY2xhcmVkXG4gKiBidWRnZXQsIHNvIGEgcnVuIHRoYXQgdGFrZXMgdGhlIHRpbWUgdGhlIGNoYXJ0IGRlY2xhcmVzIHdpbGwgYmUgY3V0IHNob3J0LiBgc3RhcnRlZEF0YCBpcyByZWFkIEJFRk9SRSB0aGUgcnVuJ3NcbiAqIGRlYWRsaW5lIGlzIGFybWVkLCBzbyBgdGltZW91dE1zYCBlcXVhbCB0byB0aGUgYnVkZ2V0IG5ldmVyIHdhcm5zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2FybkRlYWRsaW5lVW5kZXJCdWRnZXQoY2hhcnQ6IEZsb3dDaGFydCwgZGVhZGxpbmU6IG51bWJlciB8IHVuZGVmaW5lZCwgc3RhcnRlZEF0OiBudW1iZXIpOiB2b2lkIHtcbiAgaWYgKGRlYWRsaW5lID09PSB1bmRlZmluZWQgfHwgIWlzRGV2TW9kZSgpKSByZXR1cm47XG4gIGNvbnN0IGJ1ZGdldE1zID0gZGVjbGFyZWRCdWRnZXQoY2hhcnQpO1xuICBpZiAoYnVkZ2V0TXMgPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICBjb25zdCBsZWZ0TXMgPSBkZWFkbGluZSAtIHN0YXJ0ZWRBdDtcbiAgaWYgKGxlZnRNcyA+PSBidWRnZXRNcyB8fCB3YXJuZWRBdFJ1blN0YXJ0LmhhcyhjaGFydCkpIHJldHVybjtcbiAgd2FybmVkQXRSdW5TdGFydC5hZGQoY2hhcnQpO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICBjb25zb2xlLndhcm4oXG4gICAgYFtmb290cHJpbnRdIHRoaXMgcnVuJ3MgZGVhZGxpbmUgbGVhdmVzICR7TWF0aC5tYXgoMCwgbGVmdE1zKX0gbXMsIGxlc3MgdGhhbiB0aGUgY2hhcnQncyBkZWNsYXJlZCBidWRnZXQgb2YgYCArXG4gICAgICBgJHtidWRnZXRNc30gbXMgKCcke2NoYXJ0LnJvb3QubmFtZX0nKTogYSBydW4gdGhhdCB0YWtlcyB0aGUgdGltZSB0aGUgY2hhcnQgZGVjbGFyZXMgd2lsbCBiZSBjdXQgc2hvcnQuIEdpdmUgYCArXG4gICAgICAndGhlIHJ1biBpdHMgYnVkZ2V0LCBvciBkZWNsYXJlIGEgc21hbGxlciBvbmUuJyxcbiAgKTtcbn1cblxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vLyBUaGUgd2Fsa1xuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmNvbnN0IElOX1BST0dSRVNTID0gU3ltYm9sKCdpbi1wcm9ncmVzcycpO1xuXG4vKiogV2hlcmUgYSBjaGFpbidzIGlkcyBsaXZlOiBpdHMgY2hhcnQncyBzdWJmbG93IGRpY3Rpb25hcnkgYW5kIHN0YWdlIG1hcCwgYW5kIHRoZSBwcmVmaXggdGhlIHJ1biBnaXZlcyB0aGVtLiAqL1xuaW50ZXJmYWNlIEN0eCB7XG4gIHJlYWRvbmx5IHN1YmZsb3dzOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB7IHJvb3Q6IFN0YWdlTm9kZSB9Pj4gfCB1bmRlZmluZWQ7XG4gIHJlYWRvbmx5IHN0YWdlTWFwOiBSZWFkb25seU1hcDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkO1xuICByZWFkb25seSBwcmVmaXg6IHN0cmluZztcbiAgcmVhZG9ubHkgbWVtbzogTWFwPFN0YWdlTm9kZSwgQ2hhaW4gfCB0eXBlb2YgSU5fUFJPR1JFU1M+O1xufVxuXG5pbnRlcmZhY2UgQ2hhaW5SZWYge1xuICByZWFkb25seSBjdHg6IEN0eDtcbiAgcmVhZG9ubHkgc3RhcnQ6IFN0YWdlTm9kZTtcbn1cblxuLyoqIFdoYXQgYSBub2RlIHJ1bnMgaW5zaWRlIGl0c2VsZiwgYmVzaWRlcyBpdHMgb3duIGZ1bmN0aW9uLiAqL1xudHlwZSBJbnNpZGUgPVxuICB8IHsgcmVhZG9ubHkga2luZDogJ25vbmUnIH1cbiAgfCB7IHJlYWRvbmx5IGtpbmQ6ICd1bmJvdW5kZWQnOyByZWFkb25seSB3aHk6IFVuYm91bmRlZFJlYXNvbjsgcmVhZG9ubHkgc3RhZ2VJZDogc3RyaW5nIH1cbiAgLyoqIGBib3VuZGFyeWA6IHRoZSBjaGFpbnMgYXJlIGFub3RoZXIgY2hhcnQgKGEgc3ViZmxvdykg4oCUIGEgbG9vcCBjYW5ub3QgbGVhdmUgdGhlbS4gKi9cbiAgfCB7IHJlYWRvbmx5IGtpbmQ6ICdjaGFpbnMnOyByZWFkb25seSByZWZzOiByZWFkb25seSBDaGFpblJlZltdOyByZWFkb25seSBib3VuZGFyeTogYm9vbGVhbiB9O1xuXG5pbnRlcmZhY2UgU3RhZ2VDb3N0IHtcbiAgcmVhZG9ubHkgYXR0ZW1wdHM6IG51bWJlcjtcbiAgcmVhZG9ubHkgdGltZW91dE1zPzogbnVtYmVyO1xuICByZWFkb25seSBiYWNrb2ZmTXM6IG51bWJlcjtcbiAgcmVhZG9ubHkga25vd25NczogbnVtYmVyO1xuICByZWFkb25seSB3b3JzdE1zOiBudW1iZXIgfCBudWxsO1xuICByZWFkb25seSB3aHk/OiBVbmJvdW5kZWRSZWFzb247XG59XG5cbi8qKiBPbmUgbm9kZSBvZiBhIGNoYWluLiBgbXVsdGlwbGllcmAgaXMgaG93IG1hbnkgdGltZXMgdGhlIGNoYWluIHJ1bnMgaXQgcGVyIHBhc3Mgb2YgdGhlIGNoYWluLiAqL1xuaW50ZXJmYWNlIFBvc2l0aW9uIHtcbiAgcmVhZG9ubHkgc3RhZ2VJZDogc3RyaW5nO1xuICByZWFkb25seSBjb3N0OiBTdGFnZUNvc3QgfCB1bmRlZmluZWQ7XG4gIHJlYWRvbmx5IGlubmVyS25vd246IG51bWJlcjtcbiAgLyoqIFRoZSBzbG93ZXN0IGNoYWluIGl0IHJ1bnMgaW5zaWRlIGl0c2VsZiDigJQgdGhlIGNyaXRpY2FsIHBhdGggZ29lcyB0aHJvdWdoIGl0LiAqL1xuICByZWFkb25seSB2aWE6IENoYWluIHwgdW5kZWZpbmVkO1xuICAvKiogRXZlcnkgY2hhaW4gaXQgcnVucyBpbnNpZGUgaXRzZWxmLCBpbiBvcmRlci4gKi9cbiAgcmVhZG9ubHkgZGVwczogcmVhZG9ubHkgQ2hhaW5bXTtcbiAgcmVhZG9ubHkgZmxhZ3M6IFVuYm91bmRlZFN0YWdlW107XG4gIG11bHRpcGxpZXI6IG51bWJlcjtcbiAgcmVhZG9ubHkgZGVjbGFyZWRQYXNzZXM/OiBudW1iZXI7XG59XG5cbi8qKiBBIGNvbXB1dGVkIGNoYWluOiBhIHJ1biBvZiBgbmV4dGAgcG9pbnRlcnMsIGFuZCB3aGF0IHRoZSBub2RlcyBvbiBpdCBydW4gaW5zaWRlIHRoZW1zZWx2ZXMuICovXG5pbnRlcmZhY2UgQ2hhaW4ge1xuICByZWFkb25seSBrbm93bjogbnVtYmVyO1xuICByZWFkb25seSBib3VuZGVkOiBib29sZWFuO1xuICAvKiogTG9vcCB0YXJnZXRzIChyYXcgaWRzKSB0aGlzIGNoYWluIGp1bXBzIGJhY2sgdG8gYW5kIGRvZXMgbm90IGhvbGQg4oCUIHRoZSBlbmNsb3NpbmcgY2hhaW4gcmVzb2x2ZXMgdGhlbS4gKi9cbiAgcmVhZG9ubHkgb3BlbjogUmVhZG9ubHlTZXQ8c3RyaW5nPjtcbiAgcmVhZG9ubHkgcG9zaXRpb25zOiByZWFkb25seSBQb3NpdGlvbltdO1xufVxuXG5pbnRlcmZhY2UgTG9vcCB7XG4gIHJlYWRvbmx5IHN0YXJ0OiBudW1iZXI7XG4gIHJlYWRvbmx5IGVuZDogbnVtYmVyO1xuICByZWFkb25seSBwYXNzZXM6IG51bWJlcjtcbn1cblxuY29uc3QgTk9ORTogSW5zaWRlID0geyBraW5kOiAnbm9uZScgfTtcbmNvbnN0IEVNUFRZOiBSZWFkb25seVNldDxzdHJpbmc+ID0gbmV3IFNldCgpO1xuXG5jbGFzcyBCdWRnZXRXYWxrIHtcbiAgLyoqIEV2ZXJ5IGNoYWluLCBpbiB0aGUgb3JkZXIgY29tcHV0ZWQ6IGVhY2ggb25lIGFmdGVyIGV2ZXJ5IGNoYWluIGl0IHJ1bnMgaW5zaWRlIGl0c2VsZi4gKi9cbiAgcmVhZG9ubHkgY29tcHV0ZWQ6IENoYWluW10gPSBbXTtcbiAgcHJpdmF0ZSByZWFkb25seSBjdHhzID0gbmV3IE1hcDxvYmplY3QsIE1hcDxzdHJpbmcsIEN0eD4+KCk7XG5cbiAgLyoqIE5vZGUgdmlzaXRzIHNvIGZhciDigJQgY2FwcGVkIGF0IGBNQVhfV0FMS2AuICovXG4gIHByaXZhdGUgd2Fsa2VkID0gMDtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGFzc3VtZTogQWRtaXR0ZWRBc3N1bXB0aW9ucykge31cblxuICAvKiogVGhlIGNoYWluIGZyb20gYHN0YXJ0YCDigJQgZXZlcnkgbm9kZSB2aXNpdCBjb3VudGVkIGFnYWluc3QgYE1BWF9XQUxLYC4gKi9cbiAgcHJpdmF0ZSBjaGFpbk9mKHN0YXJ0OiBTdGFnZU5vZGUpOiBDaGFpblNoYXBlIHtcbiAgICBjb25zdCBub2RlczogU3RhZ2VOb2RlW10gPSBbXTtcbiAgICBjb25zdCBzZWVuID0gbmV3IFNldDxTdGFnZU5vZGU+KCk7XG4gICAgbGV0IGN1cjogU3RhZ2VOb2RlIHwgdW5kZWZpbmVkID0gc3RhcnQ7XG4gICAgd2hpbGUgKGlzTm9kZShjdXIpKSB7XG4gICAgICBpZiAoY3VyLmlzTG9vcFJlZikgcmV0dXJuIHsgbm9kZXMsIGJhY2tJZDogU3RyaW5nKGN1ci5pZCkgfTtcbiAgICAgIGlmIChzZWVuLmhhcyhjdXIpKSByZXR1cm4geyBub2RlcywgYmFja1RvOiBjdXIgfTtcbiAgICAgIGlmICgrK3RoaXMud2Fsa2VkID4gTUFYX1dBTEspIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXG4gICAgICAgICAgYHRpbWVCdWRnZXQ6IHRoZSB3YWxrIHBhc3NlZCAke01BWF9XQUxLfSBub2RlIHZpc2l0cyBhbmQgc3RvcHBlZC4gQSBidWlsZGVyIGNoYXJ0IHZpc2l0cyBlYWNoIG5vZGUgYXQgYCArXG4gICAgICAgICAgICAnbW9zdCB0d2ljZTsgYSBoYW5kLWJ1aWx0IGdyYXBoIHdob3NlIGNoYWlucyBzaGFyZSB0aGVpciB0YWlscyB3YWxrcyB0aGUgc2hhcmVkIHRhaWwgb25jZSBwZXIgY2hhaW4uICcgK1xuICAgICAgICAgICAgJ1RoZSBidWRnZXQgb2YgdGhpcyBncmFwaCBjYW5ub3QgYmUgY29tcHV0ZWQuJyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHNlZW4uYWRkKGN1cik7XG4gICAgICBub2Rlcy5wdXNoKGN1cik7XG4gICAgICBjdXIgPSBjdXIubmV4dDtcbiAgICB9XG4gICAgcmV0dXJuIHsgbm9kZXMgfTtcbiAgfVxuXG4gIGN0eE9mKFxuICAgIG93bmVyOiB7XG4gICAgICByZWFkb25seSBzdWJmbG93cz86IFJlY29yZDxzdHJpbmcsIHsgcm9vdDogU3RhZ2VOb2RlIH0+O1xuICAgICAgcmVhZG9ubHkgc3RhZ2VNYXA/OiBSZWFkb25seU1hcDxzdHJpbmcsIHVua25vd24+O1xuICAgIH0sXG4gICAgcHJlZml4OiBzdHJpbmcsXG4gICk6IEN0eCB7XG4gICAgbGV0IGJ5UHJlZml4ID0gdGhpcy5jdHhzLmdldChvd25lcik7XG4gICAgaWYgKGJ5UHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGJ5UHJlZml4ID0gbmV3IE1hcCgpO1xuICAgICAgdGhpcy5jdHhzLnNldChvd25lciwgYnlQcmVmaXgpO1xuICAgIH1cbiAgICBsZXQgY3R4ID0gYnlQcmVmaXguZ2V0KHByZWZpeCk7XG4gICAgaWYgKGN0eCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjdHggPSB7IHN1YmZsb3dzOiBvd25lci5zdWJmbG93cywgc3RhZ2VNYXA6IG93bmVyLnN0YWdlTWFwLCBwcmVmaXgsIG1lbW86IG5ldyBNYXAoKSB9O1xuICAgICAgYnlQcmVmaXguc2V0KHByZWZpeCwgY3R4KTtcbiAgICB9XG4gICAgcmV0dXJuIGN0eDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlIGByb290YCBhbmQgZXZlcnkgY2hhaW4gaXQgcnVucyDigJQgYW4gZXhwbGljaXQgc3RhY2ssIG5ldmVyIHJlY3Vyc2lvbi4gQSBjaGFpbiBpcyBtYXJrZWQgaW4gcHJvZ3Jlc3Mgb25cbiAgICogaXRzIGZpcnN0IHZpc2l0IGFuZCBwdXNoZXMgdGhlIGNoYWlucyBpdCBuZWVkczsgaXQgaXMgY29tcHV0ZWQgb24gaXRzIHNlY29uZCwgd2hlbiB0aGV5IGFyZSBkb25lLiBBIGNoYWluIHRoYXRcbiAgICogbmVlZHMgb25lIHN0aWxsIGluIHByb2dyZXNzIG5lZWRzIGl0c2VsZjogYW4gb2JqZWN0IGN5Y2xlLCBjb3VudGVkIGFzIGEgbG9vcC5cbiAgICovXG4gIGV2YWx1YXRlKHJvb3Q6IENoYWluUmVmKTogQ2hhaW4ge1xuICAgIGNvbnN0IHN0YWNrOiBDaGFpblJlZltdID0gW3Jvb3RdO1xuICAgIHdoaWxlIChzdGFjay5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCByZWYgPSBzdGFja1tzdGFjay5sZW5ndGggLSAxXTtcbiAgICAgIGNvbnN0IHN0YXRlID0gcmVmLmN0eC5tZW1vLmdldChyZWYuc3RhcnQpO1xuICAgICAgaWYgKHN0YXRlICE9PSB1bmRlZmluZWQgJiYgc3RhdGUgIT09IElOX1BST0dSRVNTKSB7XG4gICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG5vZGVzID0gdGhpcy5jaGFpbk9mKHJlZi5zdGFydCk7XG4gICAgICBjb25zdCBpbnNpZGVzID0gbm9kZXMubm9kZXMubWFwKChub2RlKSA9PiB0aGlzLmluc2lkZU9mKG5vZGUsIHJlZi5jdHgpKTtcbiAgICAgIGlmIChzdGF0ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJlZi5jdHgubWVtby5zZXQocmVmLnN0YXJ0LCBJTl9QUk9HUkVTUyk7XG4gICAgICAgIGNvbnN0IGJlZm9yZSA9IHN0YWNrLmxlbmd0aDtcbiAgICAgICAgZm9yIChjb25zdCBpbnNpZGUgb2YgaW5zaWRlcykge1xuICAgICAgICAgIGlmIChpbnNpZGUua2luZCAhPT0gJ2NoYWlucycpIGNvbnRpbnVlO1xuICAgICAgICAgIGZvciAoY29uc3QgZGVwIG9mIGluc2lkZS5yZWZzKSBpZiAoIWRlcC5jdHgubWVtby5oYXMoZGVwLnN0YXJ0KSkgc3RhY2sucHVzaChkZXApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGFjay5sZW5ndGggPiBiZWZvcmUpIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgc3RhY2sucG9wKCk7XG4gICAgICBjb25zdCBjaGFpbiA9IHRoaXMuY2hhaW5SZXN1bHQocmVmLmN0eCwgbm9kZXMsIGluc2lkZXMpO1xuICAgICAgcmVmLmN0eC5tZW1vLnNldChyZWYuc3RhcnQsIGNoYWluKTtcbiAgICAgIHRoaXMuY29tcHV0ZWQucHVzaChjaGFpbik7XG4gICAgfVxuICAgIHJldHVybiByb290LmN0eC5tZW1vLmdldChyb290LnN0YXJ0KSBhcyBDaGFpbjtcbiAgfVxuXG4gIHByaXZhdGUgaW5zaWRlT2Yobm9kZTogU3RhZ2VOb2RlLCBjdHg6IEN0eCk6IEluc2lkZSB7XG4gICAgaWYgKG5vZGUuaXNEeW5hbWljUGFyYWxsZWwpIHtcbiAgICAgIGNvbnN0IHN0YWdlSWQgPSByZXBvcnRlZChjdHgsIG5vZGUuaWQpO1xuICAgICAgY29uc3QgY2hhcnQgPSBvd24odGhpcy5hc3N1bWUuYnJhbmNoZXMsIHN0YWdlSWQpO1xuICAgICAgaWYgKGNoYXJ0ID09PSB1bmRlZmluZWQpIHJldHVybiB7IGtpbmQ6ICd1bmJvdW5kZWQnLCB3aHk6ICdpdGVtcycsIHN0YWdlSWQgfTtcbiAgICAgIGNvbnN0IGJyYW5jaCA9IGJ1aWxkQnJhbmNoU2VnbWVudChzdGFnZUlkLCAwKTtcbiAgICAgIHJldHVybiB7IGtpbmQ6ICdjaGFpbnMnLCByZWZzOiBbeyBjdHg6IHRoaXMuY3R4T2YoY2hhcnQsIGJyYW5jaCksIHN0YXJ0OiBjaGFydC5yb290IH1dLCBib3VuZGFyeTogdHJ1ZSB9O1xuICAgIH1cbiAgICBpZiAoaXNNb3VudChub2RlKSkgcmV0dXJuIHRoaXMubW91bnRPZihub2RlLCBjdHgpO1xuICAgIGNvbnN0IGNoaWxkcmVuID0gY2hpbGRyZW5PZihub2RlKTtcbiAgICBpZiAoY2hpbGRyZW4ubGVuZ3RoID4gMClcbiAgICAgIHJldHVybiB7IGtpbmQ6ICdjaGFpbnMnLCByZWZzOiBjaGlsZHJlbi5tYXAoKHN0YXJ0KSA9PiAoeyBjdHgsIHN0YXJ0IH0pKSwgYm91bmRhcnk6IGZhbHNlIH07XG4gICAgcmV0dXJuIE5PTkU7XG4gIH1cblxuICAvKiogQSBzdWJmbG93IG1vdW50IOKAlCByZXNvbHZlZCB0aGUgd2F5IHRoZSBlbmdpbmUgcmVzb2x2ZXMgaXQgKGBOb2RlUmVzb2x2ZXIgwrcgcmVzb2x2ZVN1YmZsb3dSZWZlcmVuY2VgKS4gKi9cbiAgcHJpdmF0ZSBtb3VudE9mKG5vZGU6IFN0YWdlTm9kZSwgY3R4OiBDdHgpOiBJbnNpZGUge1xuICAgIGNvbnN0IHN1YmZsb3dJZCA9IHJlcG9ydGVkKGN0eCwgU3RyaW5nKG5vZGUuc3ViZmxvd0lkKSk7XG4gICAgaWYgKG5vZGUuc3ViZmxvd1Jlc29sdmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IGNoYXJ0ID0gb3duKHRoaXMuYXNzdW1lLmxhenksIHN1YmZsb3dJZCk7XG4gICAgICBpZiAoY2hhcnQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHsga2luZDogJ3VuYm91bmRlZCcsIHdoeTogJ2xhenktc3ViZmxvdycsIHN0YWdlSWQ6IHN1YmZsb3dJZCB9O1xuICAgICAgcmV0dXJuIHsga2luZDogJ2NoYWlucycsIHJlZnM6IFt7IGN0eDogdGhpcy5jdHhPZihjaGFydCwgc3ViZmxvd0lkKSwgc3RhcnQ6IGNoYXJ0LnJvb3QgfV0sIGJvdW5kYXJ5OiB0cnVlIH07XG4gICAgfVxuICAgIGNvbnN0IGlubGluZSA9IG5vZGUuc3ViZmxvd0RlZjtcbiAgICBpZiAoaW5saW5lPy5yb290ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGtpbmQ6ICdjaGFpbnMnLFxuICAgICAgICByZWZzOiBbeyBjdHg6IHRoaXMuY3R4T2YoaW5saW5lIGFzIFBhcmFtZXRlcnM8QnVkZ2V0V2Fsa1snY3R4T2YnXT5bMF0sIGN0eC5wcmVmaXgpLCBzdGFydDogaW5saW5lLnJvb3QgfV0sXG4gICAgICAgIGJvdW5kYXJ5OiB0cnVlLFxuICAgICAgfTtcbiAgICB9XG4gICAgY29uc3QgZGVmID0gc3ViZmxvd0RlZk9mKGN0eC5zdWJmbG93cywgbm9kZSk7XG4gICAgcmV0dXJuIGRlZiA9PT0gdW5kZWZpbmVkID8gTk9ORSA6IHsga2luZDogJ2NoYWlucycsIHJlZnM6IFt7IGN0eCwgc3RhcnQ6IGRlZi5yb290IH1dLCBib3VuZGFyeTogdHJ1ZSB9O1xuICB9XG5cbiAgcHJpdmF0ZSBjaGFpblJlc3VsdChjdHg6IEN0eCwgc2hhcGU6IENoYWluU2hhcGUsIGluc2lkZXM6IHJlYWRvbmx5IEluc2lkZVtdKTogQ2hhaW4ge1xuICAgIGNvbnN0IHsgbm9kZXMgfSA9IHNoYXBlO1xuICAgIGNvbnN0IGF0ID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgICBub2Rlcy5mb3JFYWNoKChub2RlLCBpKSA9PiB7XG4gICAgICBpZiAoIWF0Lmhhcyhub2RlLmlkKSkgYXQuc2V0KG5vZGUuaWQsIGkpO1xuICAgIH0pO1xuICAgIGNvbnN0IGJhY2tFZGdlczogQXJyYXk8cmVhZG9ubHkgW251bWJlciwgbnVtYmVyXT4gPSBbXTtcbiAgICBjb25zdCBvcGVuID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgLy8gQSBqdW1wIHRvIGEgdGFyZ2V0IHRoaXMgY2hhaW4gaG9sZHMgYXQgb3IgYmVmb3JlIGBmcm9tYCBpcyBhIGxvb3Agb3ZlciBbdGFyZ2V0LCBmcm9tXTsgYSBmb3J3YXJkIGp1bXAgcmVwZWF0c1xuICAgIC8vIG5vdGhpbmc7IGEgdGFyZ2V0IHRoZSBjaGFpbiBkb2VzIG5vdCBob2xkIGlzIHRoZSBlbmNsb3NpbmcgY2hhaW4ncyB0byByZXNvbHZlLlxuICAgIGNvbnN0IGp1bXAgPSAodGFyZ2V0OiBzdHJpbmcsIGZyb206IG51bWJlcikgPT4ge1xuICAgICAgY29uc3QgaiA9IGF0LmdldCh0YXJnZXQpO1xuICAgICAgaWYgKGogPT09IHVuZGVmaW5lZCkgb3Blbi5hZGQodGFyZ2V0KTtcbiAgICAgIGVsc2UgaWYgKGogPD0gZnJvbSkgYmFja0VkZ2VzLnB1c2goW2osIGZyb21dKTtcbiAgICB9O1xuXG4gICAgbGV0IGJvdW5kZWQgPSB0cnVlO1xuICAgIGNvbnN0IHBvc2l0aW9uczogUG9zaXRpb25bXSA9IG5vZGVzLm1hcCgobm9kZSwgcSkgPT4ge1xuICAgICAgY29uc3Qgc3RhZ2VJZCA9IHJlcG9ydGVkKGN0eCwgbm9kZS5pZCk7XG4gICAgICBjb25zdCBmbGFnczogVW5ib3VuZGVkU3RhZ2VbXSA9IFtdO1xuICAgICAgLy8gQSBtb3VudCBydW5zIGl0cyBzdWJmbG93IGluIHBsYWNlIG9mIGEgZnVuY3Rpb24gb2YgaXRzIG93biAodGhlIGVuZ2luZSBuZXZlciBhc2tzIGl0cyBzdGFnZSBtYXApLlxuICAgICAgY29uc3QgY29zdCA9ICFpc01vdW50KG5vZGUpICYmIGhhc0Z1bmN0aW9uKG5vZGUsIGN0eCkgPyBoZWxwZXJDb3N0KHJldHJ5TG9vcEJ1ZGdldChub2RlKSwgbm9kZS5yZXRyeSkgOiB1bmRlZmluZWQ7XG4gICAgICBpZiAoY29zdD8ud2h5ICE9PSB1bmRlZmluZWQpIGZsYWdzLnB1c2goeyBzdGFnZUlkLCB3aHk6IGNvc3Qud2h5IH0pO1xuICAgICAgY29uc3QgaW5uZXIgPSB0aGlzLmlubmVyT2YoaW5zaWRlc1txXSwgZmxhZ3MpO1xuICAgICAgZm9yIChjb25zdCB0YXJnZXQgb2YgaW5uZXIub3BlbikganVtcCh0YXJnZXQsIHEpO1xuICAgICAgaWYgKGNvc3Q/LndvcnN0TXMgPT09IG51bGwgfHwgIWlubmVyLmJvdW5kZWQpIGJvdW5kZWQgPSBmYWxzZTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN0YWdlSWQsXG4gICAgICAgIGNvc3QsXG4gICAgICAgIGlubmVyS25vd246IGlubmVyLmtub3duLFxuICAgICAgICB2aWE6IGlubmVyLnZpYSxcbiAgICAgICAgZGVwczogaW5uZXIuZGVwcyxcbiAgICAgICAgZmxhZ3MsXG4gICAgICAgIG11bHRpcGxpZXI6IDEsXG4gICAgICAgIGRlY2xhcmVkUGFzc2VzOiByZXRyeUxvb3BCdWRnZXQobm9kZSk/LnBhc3NlcyxcbiAgICAgIH07XG4gICAgfSk7XG4gICAgaWYgKHNoYXBlLmJhY2tUbyAhPT0gdW5kZWZpbmVkKSBiYWNrRWRnZXMucHVzaChbbm9kZXMuaW5kZXhPZihzaGFwZS5iYWNrVG8pLCBub2Rlcy5sZW5ndGggLSAxXSk7XG4gICAgaWYgKHNoYXBlLmJhY2tJZCAhPT0gdW5kZWZpbmVkKSBqdW1wKHNoYXBlLmJhY2tJZCwgbm9kZXMubGVuZ3RoIC0gMSk7XG5cbiAgICBpZiAoIXRoaXMuYXBwbHlMb29wcyhwb3NpdGlvbnMsIGJhY2tFZGdlcykpIGJvdW5kZWQgPSBmYWxzZTtcbiAgICBsZXQga25vd24gPSAwO1xuICAgIGZvciAoY29uc3QgcCBvZiBwb3NpdGlvbnMpIGtub3duID0gYWRkKGtub3duLCBtdWwocC5tdWx0aXBsaWVyLCBhZGQocC5jb3N0Py5rbm93bk1zID8/IDAsIHAuaW5uZXJLbm93bikpKTtcbiAgICByZXR1cm4geyBrbm93biwgYm91bmRlZCwgb3BlbiwgcG9zaXRpb25zIH07XG4gIH1cblxuICAvKiogVGhlIHNsb3dlc3Qgb2YgdGhlIGNoYWlucyBhIG5vZGUgcnVucyBpbnNpZGUgaXRzZWxmICh0aGV5IGFyZSBhbHRlcm5hdGl2ZXMsIG9yIHJ1biBhdCBvbmNlKS4gKi9cbiAgcHJpdmF0ZSBpbm5lck9mKFxuICAgIGluc2lkZTogSW5zaWRlLFxuICAgIGZsYWdzOiBVbmJvdW5kZWRTdGFnZVtdLFxuICApOiB7IGtub3duOiBudW1iZXI7IGJvdW5kZWQ6IGJvb2xlYW47IHZpYT86IENoYWluOyBkZXBzOiBDaGFpbltdOyBvcGVuOiBSZWFkb25seVNldDxzdHJpbmc+IH0ge1xuICAgIGlmIChpbnNpZGUua2luZCA9PT0gJ25vbmUnKSByZXR1cm4geyBrbm93bjogMCwgYm91bmRlZDogdHJ1ZSwgZGVwczogW10sIG9wZW46IEVNUFRZIH07XG4gICAgaWYgKGluc2lkZS5raW5kID09PSAndW5ib3VuZGVkJykge1xuICAgICAgZmxhZ3MucHVzaCh7IHN0YWdlSWQ6IGluc2lkZS5zdGFnZUlkLCB3aHk6IGluc2lkZS53aHkgfSk7XG4gICAgICByZXR1cm4geyBrbm93bjogMCwgYm91bmRlZDogZmFsc2UsIGRlcHM6IFtdLCBvcGVuOiBFTVBUWSB9O1xuICAgIH1cbiAgICBsZXQgdmlhOiBDaGFpbiB8IHVuZGVmaW5lZDtcbiAgICBsZXQgYm91bmRlZCA9IHRydWU7XG4gICAgY29uc3QgZGVwczogQ2hhaW5bXSA9IFtdO1xuICAgIGNvbnN0IG9wZW4gPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBmb3IgKGNvbnN0IHJlZiBvZiBpbnNpZGUucmVmcykge1xuICAgICAgY29uc3QgY2hhaW4gPSByZWYuY3R4Lm1lbW8uZ2V0KHJlZi5zdGFydCk7XG4gICAgICBpZiAoY2hhaW4gPT09IHVuZGVmaW5lZCB8fCBjaGFpbiA9PT0gSU5fUFJPR1JFU1MpIHtcbiAgICAgICAgZmxhZ3MucHVzaCh7IHN0YWdlSWQ6IHJlcG9ydGVkKHJlZi5jdHgsIHJlZi5zdGFydC5pZCksIHdoeTogJ2xvb3AnIH0pO1xuICAgICAgICBib3VuZGVkID0gZmFsc2U7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgZGVwcy5wdXNoKGNoYWluKTtcbiAgICAgIGlmICghY2hhaW4uYm91bmRlZCkgYm91bmRlZCA9IGZhbHNlO1xuICAgICAgZm9yIChjb25zdCB0YXJnZXQgb2YgY2hhaW4ub3Blbikge1xuICAgICAgICBpZiAoIWluc2lkZS5ib3VuZGFyeSkge1xuICAgICAgICAgIG9wZW4uYWRkKHRhcmdldCk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQSBzdWJmbG93J3Mgb3duIHRyYXZlcnNlciBsb29rcyBpdHMgbG9vcCB0YXJnZXRzIHVwIGluIGl0cyBvd24gY2hhcnQ6IG9uZSBpdCBkb2VzIG5vdCBob2xkIG5ldmVyIHJlc29sdmVzLlxuICAgICAgICBmbGFncy5wdXNoKHsgc3RhZ2VJZDogcmVwb3J0ZWQocmVmLmN0eCwgdGFyZ2V0KSwgd2h5OiAnbG9vcCcgfSk7XG4gICAgICAgIGJvdW5kZWQgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmICh2aWEgPT09IHVuZGVmaW5lZCB8fCBjaGFpbi5rbm93biA+IHZpYS5rbm93bikgdmlhID0gY2hhaW47XG4gICAgfVxuICAgIHJldHVybiB7IGtub3duOiB2aWE/Lmtub3duID8/IDAsIGJvdW5kZWQsIC4uLih2aWEgIT09IHVuZGVmaW5lZCAmJiB7IHZpYSB9KSwgZGVwcywgb3BlbiB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFR1cm4gYSBjaGFpbidzIGJhY2stZWRnZXMgaW50byBlYWNoIHBvc2l0aW9uJ3MgbXVsdGlwbGllci4gT25lIGxvb3AgcGVyIHRhcmdldCwgc3Bhbm5pbmcgdG8gaXRzIGZ1cnRoZXN0XG4gICAqIHNvdXJjZS4gTG9vcHMgYXJlIHRha2VuIGluIHN0YXJ0IG9yZGVyIG9uIGEgc3RhY2sgb2YgbmVzdGVkIG9uZXM7IGEgbG9vcCB0aGF0IG92ZXJsYXBzIHRoZSBvbmUgaXQgc3RhcnRzIGluc2lkZVxuICAgKiB3aXRob3V0IG5lc3RpbmcgbWVyZ2VzIHdpdGggaXQgKHRoZSBwcm9kdWN0IG9mIHRoZWlyIHBhc3NlcyDigJQgZWFjaCBjYW4gcmUtZW50ZXIgdGhlIG90aGVyKSwgc28gd2hhdCBpcyBsZWZ0IGlzXG4gICAqIGxhbWluYXIsIGFuZCBvbmUgc3dlZXAgbXVsdGlwbGllcyBldmVyeSBwb3NpdGlvbiBieSB0aGUgbG9vcHMgYXJvdW5kIGl0LiBSZXR1cm5zIGZhbHNlIHdoZW4gYSBsb29wIGhhcyBub1xuICAgKiBhc3N1bWVkIHBhc3NlcyAoaXQgaXMgZmxhZ2dlZCBvbiBpdHMgdGFyZ2V0IGFuZCBjb3VudGVkIG9uY2UpLlxuICAgKi9cbiAgcHJpdmF0ZSBhcHBseUxvb3BzKHBvc2l0aW9uczogUG9zaXRpb25bXSwgYmFja0VkZ2VzOiBSZWFkb25seUFycmF5PHJlYWRvbmx5IFtudW1iZXIsIG51bWJlcl0+KTogYm9vbGVhbiB7XG4gICAgaWYgKGJhY2tFZGdlcy5sZW5ndGggPT09IDApIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IGVuZHMgPSBuZXcgTWFwPG51bWJlciwgbnVtYmVyPigpO1xuICAgIGZvciAoY29uc3QgW3RhcmdldCwgc291cmNlXSBvZiBiYWNrRWRnZXMpIGVuZHMuc2V0KHRhcmdldCwgTWF0aC5tYXgoZW5kcy5nZXQodGFyZ2V0KSA/PyB0YXJnZXQsIHNvdXJjZSkpO1xuXG4gICAgbGV0IGJvdW5kZWQgPSB0cnVlO1xuICAgIGNvbnN0IGRvbmU6IExvb3BbXSA9IFtdO1xuICAgIGNvbnN0IGFjdGl2ZTogTG9vcFtdID0gW107XG4gICAgZm9yIChjb25zdCBbc3RhcnQsIGVuZF0gb2YgWy4uLmVuZHNdLnNvcnQoKGEsIGIpID0+IGFbMF0gLSBiWzBdKSkge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gcG9zaXRpb25zW3N0YXJ0XTtcbiAgICAgIGNvbnN0IGFzc3VtZWQgPSBvd24odGhpcy5hc3N1bWUubG9vcHMsIHRhcmdldC5zdGFnZUlkKTtcbiAgICAgIGNvbnN0IHBhc3NlcyA9IHRhcmdldC5kZWNsYXJlZFBhc3NlcyA9PT0gdW5kZWZpbmVkID8gYXNzdW1lZCA6IE1hdGgubWF4KHRhcmdldC5kZWNsYXJlZFBhc3NlcywgYXNzdW1lZCA/PyAxKTtcbiAgICAgIGlmIChwYXNzZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0YXJnZXQuZmxhZ3MucHVzaCh7IHN0YWdlSWQ6IHRhcmdldC5zdGFnZUlkLCB3aHk6ICdsb29wJyB9KTtcbiAgICAgICAgYm91bmRlZCA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgLy8gVGhlIGFjdGl2ZSBsb29wcyBuZXN0IChlYWNoIGluc2lkZSB0aGUgb25lIGJlbG93IGl0KTogdGhlIGlubmVybW9zdCBlbmRzIGZpcnN0LlxuICAgICAgbGV0IHRvcCA9IGxhc3RPZihhY3RpdmUpO1xuICAgICAgd2hpbGUgKHRvcCAhPT0gdW5kZWZpbmVkICYmIHRvcC5lbmQgPCBzdGFydCkge1xuICAgICAgICBkb25lLnB1c2godG9wKTtcbiAgICAgICAgYWN0aXZlLnBvcCgpO1xuICAgICAgICB0b3AgPSBsYXN0T2YoYWN0aXZlKTtcbiAgICAgIH1cbiAgICAgIC8vIFN0YXJ0cyBpbnNpZGUgYHRvcGAgYW5kIGVuZHMgcGFzdCBpdDogdGhleSBvdmVybGFwIHdpdGhvdXQgbmVzdGluZyDigJQgb25lIHJlZ2lvbiwgdGhlIHByb2R1Y3Qgb2YgcGFzc2VzLlxuICAgICAgbGV0IGxvb3A6IExvb3AgPSB7IHN0YXJ0LCBlbmQsIHBhc3NlczogcGFzc2VzID8/IDEgfTtcbiAgICAgIHdoaWxlICh0b3AgIT09IHVuZGVmaW5lZCAmJiB0b3AuZW5kIDwgbG9vcC5lbmQpIHtcbiAgICAgICAgYWN0aXZlLnBvcCgpO1xuICAgICAgICBsb29wID0geyBzdGFydDogdG9wLnN0YXJ0LCBlbmQ6IGxvb3AuZW5kLCBwYXNzZXM6IG11bCh0b3AucGFzc2VzLCBsb29wLnBhc3NlcykgfTtcbiAgICAgICAgdG9wID0gbGFzdE9mKGFjdGl2ZSk7XG4gICAgICB9XG4gICAgICBhY3RpdmUucHVzaChsb29wKTtcbiAgICB9XG4gICAgZG9uZS5wdXNoKC4uLmFjdGl2ZSk7XG5cbiAgICBkb25lLnNvcnQoKGEsIGIpID0+IGEuc3RhcnQgLSBiLnN0YXJ0IHx8IGIuZW5kIC0gYS5lbmQpO1xuICAgIGNvbnN0IGFyb3VuZDogQXJyYXk8eyByZWFkb25seSBlbmQ6IG51bWJlcjsgcmVhZG9ubHkgcHJvZHVjdDogbnVtYmVyIH0+ID0gW107XG4gICAgbGV0IG5leHQgPSAwO1xuICAgIGZvciAobGV0IHEgPSAwOyBxIDwgcG9zaXRpb25zLmxlbmd0aDsgcSsrKSB7XG4gICAgICB3aGlsZSAoYXJvdW5kLmxlbmd0aCA+IDAgJiYgYXJvdW5kW2Fyb3VuZC5sZW5ndGggLSAxXS5lbmQgPCBxKSBhcm91bmQucG9wKCk7XG4gICAgICB3aGlsZSAobmV4dCA8IGRvbmUubGVuZ3RoICYmIGRvbmVbbmV4dF0uc3RhcnQgPT09IHEpIHtcbiAgICAgICAgY29uc3Qgb3V0ZXIgPSBhcm91bmQubGVuZ3RoID4gMCA/IGFyb3VuZFthcm91bmQubGVuZ3RoIC0gMV0ucHJvZHVjdCA6IDE7XG4gICAgICAgIGFyb3VuZC5wdXNoKHsgZW5kOiBkb25lW25leHRdLmVuZCwgcHJvZHVjdDogbXVsKG91dGVyLCBkb25lW25leHRdLnBhc3NlcykgfSk7XG4gICAgICAgIG5leHQrKztcbiAgICAgIH1cbiAgICAgIHBvc2l0aW9uc1txXS5tdWx0aXBsaWVyID0gYXJvdW5kLmxlbmd0aCA+IDAgPyBhcm91bmRbYXJvdW5kLmxlbmd0aCAtIDFdLnByb2R1Y3QgOiAxO1xuICAgIH1cbiAgICByZXR1cm4gYm91bmRlZDtcbiAgfVxufVxuXG4vKiogQSBydW4gb2YgYG5leHRgIHBvaW50ZXJzIGZyb20gYHN0YXJ0YDogaXRzIG5vZGVzLCBhbmQgd2hlcmUgaXQganVtcHMgYmFjayB0byAoYSBsb29wIHN0dWIncyBpZCwgb3IgYSBjeWNsZSkuICovXG5pbnRlcmZhY2UgQ2hhaW5TaGFwZSB7XG4gIHJlYWRvbmx5IG5vZGVzOiByZWFkb25seSBTdGFnZU5vZGVbXTtcbiAgcmVhZG9ubHkgYmFja0lkPzogc3RyaW5nO1xuICByZWFkb25seSBiYWNrVG8/OiBTdGFnZU5vZGU7XG59XG5cbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLy8gT25lIHN0YWdlXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuLyoqXG4gKiBUaGUgZW5naW5lJ3MgbW91bnQgdGVzdCAoYEZsb3djaGFydFRyYXZlcnNlcmAgUGhhc2UgMCB3aXRoIGBOb2RlUmVzb2x2ZXIgwrcgcmVzb2x2ZVN1YmZsb3dSZWZlcmVuY2VgKTogYSBzdWJmbG93XG4gKiByb290IHdpdGggYSBzdWJmbG93IGlkIHJ1bnMgaXRzIHN1YmZsb3cg4oCUIGEgbGF6eSBvbmUgYWx3YXlzLCBhbiBlYWdlciBvbmUgd2hlbiBpdCBoYXMgbm8gZnVuY3Rpb24gb2YgaXRzIE9XTiBhbmQgbm9cbiAqIGNoaWxkcmVuICh0aGUgcmVzb2x2ZXIgbmV2ZXIgYXNrcyB0aGUgc3RhZ2UgbWFwKS4gQW55dGhpbmcgZWxzZSBpcyBhIG5vZGUgbGlrZSBhbnkgb3RoZXIuXG4gKi9cbmZ1bmN0aW9uIGlzTW91bnQobm9kZTogU3RhZ2VOb2RlKTogYm9vbGVhbiB7XG4gIGlmIChub2RlLmlzU3ViZmxvd1Jvb3QgIT09IHRydWUgfHwgdHlwZW9mIG5vZGUuc3ViZmxvd0lkICE9PSAnc3RyaW5nJyB8fCBub2RlLnN1YmZsb3dJZCA9PT0gJycpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIG5vZGUuc3ViZmxvd1Jlc29sdmVyICE9PSB1bmRlZmluZWQgfHwgKHR5cGVvZiBub2RlLmZuICE9PSAnZnVuY3Rpb24nICYmIGNoaWxkcmVuT2Yobm9kZSkubGVuZ3RoID09PSAwKTtcbn1cblxuLyoqIEEgbm9kZSdzIGNoaWxkcmVuIHRoYXQgYXJlIG5vZGVzIOKAlCBhIGhhbmQtYnVpbHQgYG51bGxgIGlzIHNraXBwZWQsIG5ldmVyIGRlcmVmZXJlbmNlZC4gKi9cbmZ1bmN0aW9uIGNoaWxkcmVuT2Yobm9kZTogU3RhZ2VOb2RlKTogU3RhZ2VOb2RlW10ge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheShub2RlLmNoaWxkcmVuKSA/IG5vZGUuY2hpbGRyZW4uZmlsdGVyKGlzTm9kZSkgOiBbXTtcbn1cblxuY29uc3QgaXNOb2RlID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgU3RhZ2VOb2RlID0+IHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCc7XG5cbi8qKiBUaGUgZW5naW5lJ3MgbG9va3VwIChgRmxvd2NoYXJ0VHJhdmVyc2VyIMK3IGdldFN0YWdlRm5gKTogdGhlIG5vZGUncyBvd24gZnVuY3Rpb24sIGVsc2UgdGhlIG1hcCdzIGJ5IGlkIG9yIG5hbWUuICovXG5mdW5jdGlvbiBoYXNGdW5jdGlvbihub2RlOiBTdGFnZU5vZGUsIGN0eDogQ3R4KTogYm9vbGVhbiB7XG4gIGlmICh0eXBlb2Ygbm9kZS5mbiA9PT0gJ2Z1bmN0aW9uJykgcmV0dXJuIHRydWU7XG4gIGNvbnN0IG1hcCA9IGN0eC5zdGFnZU1hcDtcbiAgcmV0dXJuIG1hcCAhPT0gdW5kZWZpbmVkICYmIChtYXAuZ2V0KG5vZGUuaWQpICE9PSB1bmRlZmluZWQgfHwgbWFwLmdldChub2RlLm5hbWUpICE9PSB1bmRlZmluZWQpO1xufVxuXG4vKiogQSBzdGFnZSdzIHdvcnN0IGNhc2UgdW5kZXIgaXRzIHBvbGljeSDigJQgcmVhZCBieSB0aGUgZW5naW5lJ3Mgb3duIHJlYWRpbmdzIG9mIGl0IChgYXR0ZW1wdC9wb2xpY3kudHNgKS4gKi9cbmZ1bmN0aW9uIGhlbHBlckNvc3QoYnVkZ2V0OiBSZXRyeUxvb3BCdWRnZXQgfCB1bmRlZmluZWQsIHBvbGljeTogUmV0cnlQb2xpY3kgfCB1bmRlZmluZWQpOiBTdGFnZUNvc3Qge1xuICBpZiAoYnVkZ2V0ID09PSB1bmRlZmluZWQpIHJldHVybiBzdGFnZUNvc3QocG9saWN5KTtcbiAgaWYgKGJ1ZGdldC5yb2xlID09PSAnY2FsbGJhY2snKSByZXR1cm4gc3RhZ2VDb3N0KHsgYXR0ZW1wdHM6IDEsIHRpbWVvdXRNczogYnVkZ2V0LnRpbWVvdXRNcyB9KTtcbiAgY29uc3QgbXMgPSBidWRnZXQucm9sZSA9PT0gJ2NvbnRyb2wnID8gMCA6IGJ1ZGdldC53YWl0TXM7XG4gIHJldHVybiB7XG4gICAgYXR0ZW1wdHM6IDEsXG4gICAgdGltZW91dE1zOiBtcyA/PyAwLFxuICAgIGJhY2tvZmZNczogMCxcbiAgICBrbm93bk1zOiBtcyA/PyAwLFxuICAgIHdvcnN0TXM6IG1zID8/IG51bGwsXG4gICAgLi4uKG1zID09PSB1bmRlZmluZWQgPyB7IHdoeTogJ2JhY2tvZmYnIGFzIGNvbnN0IH0gOiB7fSksXG4gIH07XG59XG5cbmZ1bmN0aW9uIHN0YWdlQ29zdChwb2xpY3k6IFJldHJ5UG9saWN5IHwgdW5kZWZpbmVkKTogU3RhZ2VDb3N0IHtcbiAgY29uc3QgYXR0ZW1wdHMgPSBwb2xpY3kgPT09IHVuZGVmaW5lZCA/IDEgOiBhdHRlbXB0Q2VpbGluZyhwb2xpY3kuYXR0ZW1wdHMpO1xuICBjb25zdCB0aW1lb3V0TXMgPSBwb2xpY3kgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGF0dGVtcHRUaW1lb3V0TXMocG9saWN5LnRpbWVvdXRNcyk7XG4gIGNvbnN0IHdhaXRzID0gd2FpdHNPZihwb2xpY3ksIGF0dGVtcHRzKTtcbiAgY29uc3Qga25vd25NcyA9IGFkZCh0aW1lb3V0TXMgPT09IHVuZGVmaW5lZCA/IDAgOiBtdWwoYXR0ZW1wdHMsIHRpbWVvdXRNcyksIHdhaXRzLm1zKTtcbiAgY29uc3Qgd2h5OiBVbmJvdW5kZWRSZWFzb24gfCB1bmRlZmluZWQgPSB0aW1lb3V0TXMgPT09IHVuZGVmaW5lZCA/ICduby10aW1lb3V0JyA6IHdhaXRzLmtub3duID8gdW5kZWZpbmVkIDogJ2JhY2tvZmYnO1xuICByZXR1cm4ge1xuICAgIGF0dGVtcHRzLFxuICAgIC4uLih0aW1lb3V0TXMgIT09IHVuZGVmaW5lZCAmJiB7IHRpbWVvdXRNcyB9KSxcbiAgICBiYWNrb2ZmTXM6IHdhaXRzLm1zLFxuICAgIGtub3duTXMsXG4gICAgd29yc3RNczogd2h5ID09PSB1bmRlZmluZWQgPyBrbm93bk1zIDogbnVsbCxcbiAgICAuLi4od2h5ICE9PSB1bmRlZmluZWQgJiYgeyB3aHkgfSksXG4gIH07XG59XG5cbi8qKlxuICogVGhlIHdhaXRzIGJldHdlZW4gYGF0dGVtcHRzYCBhdHRlbXB0cywgYXMgdGhlIHJ1bm5lciB3YWl0cyB0aGVtIChgYXR0ZW1wdC9wb2xpY3kudHMgwrcgY2FwcGVkV2FpdE1zYCkuIEEgbnVtYmVyXG4gKiBiYWNrb2ZmIGlzIGFyaXRobWV0aWMsIHVuZGVyIHRoZSBkZWNsYXJlZCBjZWlsaW5nLiBBIGZ1bmN0aW9uIGJhY2tvZmYgaXMgTkVWRVIgYXNrZWQg4oCUIGl0cyBhbnN3ZXIgbWF5IGRlcGVuZCBvbiB0aGVcbiAqIGVycm9yLCBhbmQgbm8gZXJyb3IgZXhpc3RzIGhlcmUg4oCUIHNvIGl0IGNvdW50cyBhdCBpdHMgZGVjbGFyZWQgY2VpbGluZyBwZXIgd2FpdCwgb3IsIHdpdGggbm9uZSwgaXMgbm90IGtub3duXG4gKiAoaXRzIHdhaXRzIGNvdW50IDAgYW5kIHRoZSBzdGFnZSBpcyB1bmJvdW5kZWQpLlxuICovXG5mdW5jdGlvbiB3YWl0c09mKHBvbGljeTogUmV0cnlQb2xpY3kgfCB1bmRlZmluZWQsIGF0dGVtcHRzOiBudW1iZXIpOiB7IG1zOiBudW1iZXI7IGtub3duOiBib29sZWFuIH0ge1xuICBjb25zdCB3YWl0cyA9IGF0dGVtcHRzIC0gMTtcbiAgY29uc3QgYmFja29mZk1zID0gcG9saWN5Py5iYWNrb2ZmTXM7XG4gIGlmICh3YWl0cyA8PSAwIHx8IGJhY2tvZmZNcyA9PT0gdW5kZWZpbmVkKSByZXR1cm4geyBtczogMCwga25vd246IHRydWUgfTtcbiAgaWYgKHR5cGVvZiBiYWNrb2ZmTXMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjb25zdCBjZWlsaW5nID0gYmFja29mZkNlaWxpbmdNcyhwb2xpY3k/Lm1heEJhY2tvZmZNcyk7XG4gICAgcmV0dXJuIGNlaWxpbmcgPT09IHVuZGVmaW5lZCA/IHsgbXM6IDAsIGtub3duOiBmYWxzZSB9IDogeyBtczogbXVsKHdhaXRzLCBjZWlsaW5nKSwga25vd246IHRydWUgfTtcbiAgfVxuICByZXR1cm4geyBtczogbXVsKHdhaXRzLCBjYXBwZWRXYWl0TXMocmVzb2x2ZUJhY2tvZmZNcyhiYWNrb2ZmTXMsIDEpLCBwb2xpY3k/Lm1heEJhY2tvZmZNcykpLCBrbm93bjogdHJ1ZSB9O1xufVxuXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIFRoZSByZXBvcnRcbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4vKipcbiAqIFRoZSBzbG93ZXN0IHBhdGg6IGhvdyBtYW55IHRpbWVzIGVhY2ggY2hhaW4gb24gaXQgcnVucyAocGFyZW50cyBiZWZvcmUgY2hpbGRyZW4g4oCUIHRoZSByZXZlcnNlIG9mIHRoZSBvcmRlciB0aGV5XG4gKiB3ZXJlIGNvbXB1dGVkIGluKSwgdGhlbiBpdHMgc3RhZ2VzIGluIHRoZSBvcmRlciBhIHJ1biBmaXJzdCByZWFjaGVzIHRoZW0uIEVhY2ggY2hhaW4gaXMgdmlzaXRlZCBvbmNlLCBzbyBhXG4gKiBkZWZpbml0aW9uIG1vdW50ZWQgdHdpY2UgYXQgZXZlcnkgbGV2ZWwgb2YgYSBkZWVwIG5lc3RpbmcgaXMgb25lIHN0ZXAgd2l0aCBpdHMgcGFzc2VzIG11bHRpcGxpZWQuXG4gKi9cbmZ1bmN0aW9uIGNyaXRpY2FsUGF0aE9mKHJvb3Q6IENoYWluLCBjb21wdXRlZDogcmVhZG9ubHkgQ2hhaW5bXSk6IEJ1ZGdldFN0ZXBbXSB7XG4gIGNvbnN0IHJ1bnMgPSBuZXcgTWFwPENoYWluLCBudW1iZXI+KFtbcm9vdCwgMV1dKTtcbiAgZm9yIChsZXQgaSA9IGNvbXB1dGVkLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgY29uc3QgY2hhaW4gPSBjb21wdXRlZFtpXTtcbiAgICBjb25zdCBjb3VudCA9IHJ1bnMuZ2V0KGNoYWluKTtcbiAgICBpZiAoY291bnQgPT09IHVuZGVmaW5lZCkgY29udGludWU7XG4gICAgZm9yIChjb25zdCBwIG9mIGNoYWluLnBvc2l0aW9ucykge1xuICAgICAgaWYgKHAudmlhICE9PSB1bmRlZmluZWQpIHJ1bnMuc2V0KHAudmlhLCBhZGQocnVucy5nZXQocC52aWEpID8/IDAsIG11bChjb3VudCwgcC5tdWx0aXBsaWVyKSkpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHN0ZXBzID0gbmV3IE1hcDxzdHJpbmcsIHsgLXJlYWRvbmx5IFtLIGluIGtleW9mIEJ1ZGdldFN0ZXBdOiBCdWRnZXRTdGVwW0tdIH0+KCk7XG4gIHdhbGtQb3NpdGlvbnMoXG4gICAgcm9vdCxcbiAgICAocCkgPT4gcC52aWEsXG4gICAgKGNoYWluLCBwKSA9PiB7XG4gICAgICBpZiAocC5jb3N0ID09PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICAgIGNvbnN0IHBhc3NlcyA9IG11bChydW5zLmdldChjaGFpbikgPz8gMCwgcC5tdWx0aXBsaWVyKTtcbiAgICAgIGNvbnN0IHN0ZXAgPSBzdGVwcy5nZXQocC5zdGFnZUlkKTtcbiAgICAgIGlmIChzdGVwICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc3RlcC5wYXNzZXMgPSBhZGQoc3RlcC5wYXNzZXMsIHBhc3Nlcyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHN0ZXBzLnNldChwLnN0YWdlSWQsIHtcbiAgICAgICAgc3RhZ2VJZDogcC5zdGFnZUlkLFxuICAgICAgICBhdHRlbXB0czogcC5jb3N0LmF0dGVtcHRzLFxuICAgICAgICAuLi4ocC5jb3N0LnRpbWVvdXRNcyAhPT0gdW5kZWZpbmVkICYmIHsgdGltZW91dE1zOiBwLmNvc3QudGltZW91dE1zIH0pLFxuICAgICAgICBiYWNrb2ZmTXM6IHAuY29zdC5iYWNrb2ZmTXMsXG4gICAgICAgIHdvcnN0TXM6IHAuY29zdC53b3JzdE1zLFxuICAgICAgICBwYXNzZXMsXG4gICAgICB9KTtcbiAgICB9LFxuICApO1xuICByZXR1cm4gWy4uLnN0ZXBzLnZhbHVlcygpXS5tYXAoKHN0ZXApID0+IE9iamVjdC5mcmVlemUoc3RlcCkpO1xufVxuXG4vKiogRXZlcnkgdW5ib3VuZGVkIHN0YWdlLCBvbmNlLCBpbiB0aGUgb3JkZXIgYSB3YWxrIG9mIHRoZSB3aG9sZSBjaGFydCByZWFjaGVzIGl0LiAqL1xuZnVuY3Rpb24gdW5ib3VuZGVkT2Yocm9vdDogQ2hhaW4sIHJvb3RGbGFnczogcmVhZG9ubHkgVW5ib3VuZGVkU3RhZ2VbXSk6IFVuYm91bmRlZFN0YWdlW10ge1xuICBjb25zdCBvdXQ6IFVuYm91bmRlZFN0YWdlW10gPSBbXTtcbiAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBjb25zdCBub3RlID0gKGZsYWc6IFVuYm91bmRlZFN0YWdlKSA9PiB7XG4gICAgY29uc3Qga2V5ID0gYCR7ZmxhZy53aHl9XFx1MDAwMCR7ZmxhZy5zdGFnZUlkfWA7XG4gICAgaWYgKHNlZW4uaGFzKGtleSkpIHJldHVybjtcbiAgICBzZWVuLmFkZChrZXkpO1xuICAgIG91dC5wdXNoKE9iamVjdC5mcmVlemUoeyBzdGFnZUlkOiBmbGFnLnN0YWdlSWQsIHdoeTogZmxhZy53aHkgfSkpO1xuICB9O1xuICB3YWxrUG9zaXRpb25zKFxuICAgIHJvb3QsXG4gICAgKHApID0+IHAuZGVwcyxcbiAgICAoX2NoYWluLCBwKSA9PiBwLmZsYWdzLmZvckVhY2gobm90ZSksXG4gICk7XG4gIHJvb3RGbGFncy5mb3JFYWNoKG5vdGUpO1xuICByZXR1cm4gb3V0O1xufVxuXG4vKiogQSBwcmVvcmRlciB3YWxrIG9mIHBvc2l0aW9ucywgZGVzY2VuZGluZyBpbnRvIGVhY2ggY2hhaW4gYG5leHRgIG5hbWVzIHRoZSBmaXJzdCB0aW1lIGl0IGlzIHJlYWNoZWQuICovXG5mdW5jdGlvbiB3YWxrUG9zaXRpb25zKFxuICByb290OiBDaGFpbixcbiAgbmV4dDogKHA6IFBvc2l0aW9uKSA9PiBDaGFpbiB8IHJlYWRvbmx5IENoYWluW10gfCB1bmRlZmluZWQsXG4gIHZpc2l0OiAoY2hhaW46IENoYWluLCBwOiBQb3NpdGlvbikgPT4gdm9pZCxcbik6IHZvaWQge1xuICBjb25zdCB2aXNpdGVkID0gbmV3IFNldDxDaGFpbj4oW3Jvb3RdKTtcbiAgY29uc3Qgc3RhY2s6IEFycmF5PHsgY2hhaW46IENoYWluOyBxOiBudW1iZXIgfT4gPSBbeyBjaGFpbjogcm9vdCwgcTogMCB9XTtcbiAgd2hpbGUgKHN0YWNrLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCB0b3AgPSBzdGFja1tzdGFjay5sZW5ndGggLSAxXTtcbiAgICBpZiAodG9wLnEgPj0gdG9wLmNoYWluLnBvc2l0aW9ucy5sZW5ndGgpIHtcbiAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IHAgPSB0b3AuY2hhaW4ucG9zaXRpb25zW3RvcC5xKytdO1xuICAgIHZpc2l0KHRvcC5jaGFpbiwgcCk7XG4gICAgY29uc3QgaW5uZXIgPSBuZXh0KHApO1xuICAgIGNvbnN0IGNoYWlucyA9IGlubmVyID09PSB1bmRlZmluZWQgPyBbXSA6IEFycmF5LmlzQXJyYXkoaW5uZXIpID8gaW5uZXIgOiBbaW5uZXIgYXMgQ2hhaW5dO1xuICAgIGZvciAobGV0IGkgPSBjaGFpbnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGlmICh2aXNpdGVkLmhhcyhjaGFpbnNbaV0pKSBjb250aW51ZTtcbiAgICAgIHZpc2l0ZWQuYWRkKGNoYWluc1tpXSk7XG4gICAgICBzdGFjay5wdXNoKHsgY2hhaW46IGNoYWluc1tpXSwgcTogMCB9KTtcbiAgICB9XG4gIH1cbn1cblxuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4vLyBXb3Jkc1xuLy8g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmNvbnN0IGNvbnRyaWJ1dGlvbiA9IChzOiBCdWRnZXRTdGVwKSA9PiBtdWwocy5wYXNzZXMsIGFkZChtdWwocy5hdHRlbXB0cywgcy50aW1lb3V0TXMgPz8gMCksIHMuYmFja29mZk1zKSk7XG5cbi8qKiBUaGUgYGxpbWl0YCBsYXJnZXN0IGNvbnRyaWJ1dG9ycywga2VwdCBpbiBwYXRoIG9yZGVyLiAqL1xuZnVuY3Rpb24gc2xvd2VzdEluUGF0aE9yZGVyKHN0ZXBzOiByZWFkb25seSBCdWRnZXRTdGVwW10sIGxpbWl0OiBudW1iZXIpOiBCdWRnZXRTdGVwW10ge1xuICBjb25zdCBrZWVwID0gbmV3IFNldChcbiAgICBbLi4uc3RlcHNdXG4gICAgICAuc29ydCgoYSwgYikgPT4gY29udHJpYnV0aW9uKGIpIC0gY29udHJpYnV0aW9uKGEpKVxuICAgICAgLnNsaWNlKDAsIGxpbWl0KVxuICAgICAgLm1hcCgocykgPT4gcy5zdGFnZUlkKSxcbiAgKTtcbiAgcmV0dXJuIHN0ZXBzLmZpbHRlcigocykgPT4ga2VlcC5oYXMocy5zdGFnZUlkKSk7XG59XG5cbmZ1bmN0aW9uIHN0ZXBUZXh0KHM6IEJ1ZGdldFN0ZXApOiBzdHJpbmcge1xuICBjb25zdCBvd24gPVxuICAgIHMudGltZW91dE1zID09PSB1bmRlZmluZWRcbiAgICAgID8gYCR7cy5iYWNrb2ZmTXN9IG1zIG9mIHdhaXRzIChubyB0aW1lb3V0TXMpYFxuICAgICAgOiBgJHtzLmF0dGVtcHRzfSDDlyAke3MudGltZW91dE1zfSBtcyArICR7cy5iYWNrb2ZmTXN9IG1zIG9mIHdhaXRzID0gJHthZGQoXG4gICAgICAgICAgbXVsKHMuYXR0ZW1wdHMsIHMudGltZW91dE1zKSxcbiAgICAgICAgICBzLmJhY2tvZmZNcyxcbiAgICAgICAgKX0gbXNgO1xuICByZXR1cm4gYCR7cy5zdGFnZUlkfTogJHtvd259JHtzLnBhc3NlcyA+IDEgPyBgLCAke3MucGFzc2VzfSBwYXNzZXNgIDogJyd9YDtcbn1cblxuZnVuY3Rpb24gdW5ib3VuZGVkVGV4dChzdGFnZXM6IHJlYWRvbmx5IFVuYm91bmRlZFN0YWdlW10pOiBzdHJpbmcge1xuICBjb25zdCBsaXN0ZWQgPSBzdGFnZXMuc2xpY2UoMCwgMTApLm1hcCgocykgPT4gYCR7cy5zdGFnZUlkfSAoJHtzLndoeX0pYCk7XG4gIHJldHVybiBzdGFnZXMubGVuZ3RoID4gbGlzdGVkLmxlbmd0aFxuICAgID8gYCR7bGlzdGVkLmpvaW4oJywgJyl9LCBhbmQgJHtzdGFnZXMubGVuZ3RoIC0gbGlzdGVkLmxlbmd0aH0gbW9yZWBcbiAgICA6IGxpc3RlZC5qb2luKCcsICcpO1xufVxuXG4vLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIFNtYWxsIGxhd3Ncbi8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4vKiogU2F0dXJhdGluZyBhcml0aG1ldGljIG9uIG5vbi1uZWdhdGl2ZSBtaWxsaXNlY29uZHM6IG5ldmVyIHBhc3QgYE51bWJlci5NQVhfU0FGRV9JTlRFR0VSYCwgbmV2ZXIgYE5hTmAuICovXG5jb25zdCBDRUlMSU5HID0gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVI7XG5jb25zdCBhZGQgPSAoYTogbnVtYmVyLCBiOiBudW1iZXIpOiBudW1iZXIgPT4gTWF0aC5taW4oYSArIGIsIENFSUxJTkcpO1xuY29uc3QgbXVsID0gKGE6IG51bWJlciwgYjogbnVtYmVyKTogbnVtYmVyID0+IChhID09PSAwIHx8IGIgPT09IDAgPyAwIDogTWF0aC5taW4oYSAqIGIsIENFSUxJTkcpKTtcblxuY29uc3QgbGFzdE9mID0gPFQ+KGl0ZW1zOiByZWFkb25seSBUW10pOiBUIHwgdW5kZWZpbmVkID0+IGl0ZW1zW2l0ZW1zLmxlbmd0aCAtIDFdO1xuXG4vKiogQSBidWRnZXQ6IGEgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyA+IDAgYW5kIG5vIG1vcmUgdGhhbiB0aGUgc2F0dXJhdGVkIHN1bXMgY2FuIGJlIGNvbXBhcmVkIGFnYWluc3QuICovXG5jb25zdCBpc1Bvc2l0aXZlTXMgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBudW1iZXIgPT5cbiAgdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiB2YWx1ZSA+IDAgJiYgdmFsdWUgPD0gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVI7XG5cbmNvbnN0IHNob3duID0gKHZhbHVlOiB1bmtub3duKTogc3RyaW5nID0+ICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInID8gU3RyaW5nKHZhbHVlKSA6IHR5cGVvZiB2YWx1ZSk7XG5cbi8qKiBBbiBpZCBhcyB0aGUgcnVuIG5hbWVzIGl0OiB1bmRlciB0aGUgcHJlZml4IG9mIHRoZSBjaGFydCBpdCBsaXZlcyBpbiAoYSBsYXp5IG9yIGJyYW5jaCBjaGFydCdzIG1vdW50IHBhdGgpLiAqL1xuY29uc3QgcmVwb3J0ZWQgPSAoY3R4OiBDdHgsIGlkOiBzdHJpbmcpOiBzdHJpbmcgPT4gKGN0eC5wcmVmaXggPT09ICcnID8gaWQgOiBqb2luUGF0aChjdHgucHJlZml4LCBpZCkpO1xuXG5mdW5jdGlvbiBpc0NoYXJ0KHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgRmxvd0NoYXJ0IHtcbiAgaWYgKHZhbHVlID09PSBudWxsIHx8IHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHJldHVybiBmYWxzZTtcbiAgY29uc3Qgcm9vdCA9ICh2YWx1ZSBhcyB7IHJvb3Q/OiB1bmtub3duIH0pLnJvb3Q7XG4gIHJldHVybiByb290ICE9PSBudWxsICYmIHR5cGVvZiByb290ID09PSAnb2JqZWN0Jztcbn1cblxuLyoqIEFuIG93biBwcm9wZXJ0eSBvbmx5IOKAlCBhIHByb3RvdHlwZSBtZW1iZXIgaXMgbmV2ZXIgYW4gYXNzdW1wdGlvbiBvciBhIHN1YmZsb3cuICovXG5mdW5jdGlvbiBvd248VD4ocmVjb3JkOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBUPj4gfCB1bmRlZmluZWQsIGtleTogc3RyaW5nKTogVCB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiByZWNvcmQgIT09IHVuZGVmaW5lZCAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVjb3JkLCBrZXkpID8gcmVjb3JkW2tleV0gOiB1bmRlZmluZWQ7XG59XG5cbi8qKiBUaGUgZW5naW5lJ3Mgc3ViZmxvdyBsb29rdXA6IGJ5IHN1YmZsb3cgaWQsIHRoZW4gc3ViZmxvdyBuYW1lLCB0aGVuIG5vZGUgbmFtZS4gKi9cbmZ1bmN0aW9uIHN1YmZsb3dEZWZPZihcbiAgc3ViZmxvd3M6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHsgcm9vdDogU3RhZ2VOb2RlIH0+PiB8IHVuZGVmaW5lZCxcbiAgbm9kZTogU3RhZ2VOb2RlLFxuKTogeyByb290OiBTdGFnZU5vZGUgfSB8IHVuZGVmaW5lZCB7XG4gIGZvciAoY29uc3Qga2V5IG9mIFtub2RlLnN1YmZsb3dJZCwgbm9kZS5zdWJmbG93TmFtZSwgbm9kZS5uYW1lXSkge1xuICAgIGlmIChrZXkgPT09IHVuZGVmaW5lZCB8fCBrZXkgPT09ICcnKSBjb250aW51ZTtcbiAgICBjb25zdCBkZWYgPSBvd24oc3ViZmxvd3MsIGtleSk7XG4gICAgaWYgKGRlZiAhPT0gdW5kZWZpbmVkICYmIGRlZiAhPT0gbnVsbCAmJiB0eXBlb2YgZGVmLnJvb3QgPT09ICdvYmplY3QnICYmIGRlZi5yb290ICE9PSBudWxsKSByZXR1cm4gZGVmO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKiBXaGF0IGEgY2hhcnQgYXNzdW1lZCBmb3IgYSBsYXp5IG1vdW50IG9yIGEgYnJhbmNoIGlzLCByZWFkIG9uY2U6IGl0cyByb290LCBpdHMgc3ViZmxvd3MsIGl0cyBzdGFnZSBtYXAuICovXG5pbnRlcmZhY2UgQXNzdW1lZENoYXJ0IHtcbiAgcmVhZG9ubHkgcm9vdDogU3RhZ2VOb2RlO1xuICByZWFkb25seSBzdWJmbG93cz86IFJlY29yZDxzdHJpbmcsIHsgcm9vdDogU3RhZ2VOb2RlIH0+O1xuICByZWFkb25seSBzdGFnZU1hcD86IFJlYWRvbmx5TWFwPHN0cmluZywgdW5rbm93bj47XG59XG5cbi8qKiBUaGUgY2FsbGVyJ3MgYXNzdW1wdGlvbnMsIHZhbGlkYXRlZCBhbmQgY29waWVkIG9uY2Ug4oCUIHRoZSB3YWxrIHJlYWRzIG9ubHkgdGhlc2UgbnVsbC1wcm90b3R5cGUgcmVjb3Jkcy4gKi9cbmludGVyZmFjZSBBZG1pdHRlZEFzc3VtcHRpb25zIHtcbiAgcmVhZG9ubHkgbG9vcHM6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIG51bWJlcj4+O1xuICByZWFkb25seSBsYXp5OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBBc3N1bWVkQ2hhcnQ+PjtcbiAgcmVhZG9ubHkgYnJhbmNoZXM6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIEFzc3VtZWRDaGFydD4+O1xufVxuXG4vKipcbiAqIFZhbGlkYXRlIHRoZSBhc3N1bXB0aW9ucyBhbmQgQ09QWSB0aGVtOiBlYWNoIG93biBlbnVtZXJhYmxlIGtleSBpcyByZWFkIGV4YWN0bHkgb25jZSwgaW50byBhIGZyZXNoIG51bGwtcHJvdG90eXBlXG4gKiByZWNvcmQuIEEgZ2V0dGVyIHRoYXQgY2hhbmdlcyBiZXR3ZWVuIHJlYWRzLCBhIFByb3h5LCBvciBhIG5vbi1lbnVtZXJhYmxlIGtleSBjYW4gdGhlcmVmb3JlIG5ldmVyIGhhbmQgdGhlIHdhbGtcbiAqIGEgdmFsdWUgdGhhdCB3YXMgbm90IHZhbGlkYXRlZCwgYW5kIG5vIHByb3RvdHlwZSBtZW1iZXIgaXMgZXZlciBhbiBhc3N1bXB0aW9uLlxuICovXG5mdW5jdGlvbiBhZG1pdEFzc3VtcHRpb25zKGFzc3VtZTogdW5rbm93bik6IEFkbWl0dGVkQXNzdW1wdGlvbnMge1xuICBpZiAoYXNzdW1lICE9PSB1bmRlZmluZWQgJiYgKGFzc3VtZSA9PT0gbnVsbCB8fCB0eXBlb2YgYXNzdW1lICE9PSAnb2JqZWN0JykpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aW1lQnVkZ2V0OiBhc3N1bWUgbXVzdCBiZSBhbiBvYmplY3QgKHsgbG9vcHM/LCBsYXp5PywgYnJhbmNoZXM/IH0pLicpO1xuICB9XG4gIGNvbnN0IGdpdmVuID0gKGFzc3VtZSA/PyB7fSkgYXMgUmVjb3JkPCdsb29wcycgfCAnbGF6eScgfCAnYnJhbmNoZXMnLCB1bmtub3duPjtcbiAgcmV0dXJuIHtcbiAgICBsb29wczogc25hcHNob3QoZ2l2ZW4ubG9vcHMsICdsb29wcycsIChrZXksIHBhc3NlcykgPT4ge1xuICAgICAgaWYgKHR5cGVvZiBwYXNzZXMgPT09ICdudW1iZXInICYmIE51bWJlci5pc0ludGVnZXIocGFzc2VzKSAmJiBwYXNzZXMgPj0gMSkgcmV0dXJuIHBhc3NlcztcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgIGB0aW1lQnVkZ2V0OiBhc3N1bWUubG9vcHNbJyR7a2V5fSddIG11c3QgYmUgYSB3aG9sZSBudW1iZXIgb2YgcGFzc2VzID49IDEgKGdvdCAke3Nob3duKHBhc3Nlcyl9KS5gLFxuICAgICAgKTtcbiAgICB9KSxcbiAgICBsYXp5OiBzbmFwc2hvdChnaXZlbi5sYXp5LCAnbGF6eScsIChrZXksIGNoYXJ0KSA9PiBhc3N1bWVkQ2hhcnQoJ2xhenknLCBrZXksIGNoYXJ0KSksXG4gICAgYnJhbmNoZXM6IHNuYXBzaG90KGdpdmVuLmJyYW5jaGVzLCAnYnJhbmNoZXMnLCAoa2V5LCBjaGFydCkgPT4gYXNzdW1lZENoYXJ0KCdicmFuY2hlcycsIGtleSwgY2hhcnQpKSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gc25hcHNob3Q8VD4ocmVjb3JkOiB1bmtub3duLCBmaWVsZDogc3RyaW5nLCBhZG1pdDogKGtleTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bikgPT4gVCk6IFJlY29yZDxzdHJpbmcsIFQ+IHtcbiAgY29uc3QgY29weSA9IE9iamVjdC5jcmVhdGUobnVsbCkgYXMgUmVjb3JkPHN0cmluZywgVD47XG4gIGlmIChyZWNvcmQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGNvcHk7XG4gIGlmIChyZWNvcmQgPT09IG51bGwgfHwgdHlwZW9mIHJlY29yZCAhPT0gJ29iamVjdCcpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGB0aW1lQnVkZ2V0OiBhc3N1bWUuJHtmaWVsZH0gbXVzdCBiZSBhbiBvYmplY3Qga2V5ZWQgYnkgaWQuYCk7XG4gIH1cbiAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMocmVjb3JkKSkgY29weVtrZXldID0gYWRtaXQoa2V5LCAocmVjb3JkIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtrZXldKTtcbiAgcmV0dXJuIE9iamVjdC5mcmVlemUoY29weSk7XG59XG5cbmZ1bmN0aW9uIGFzc3VtZWRDaGFydChmaWVsZDogc3RyaW5nLCBrZXk6IHN0cmluZywgY2hhcnQ6IHVua25vd24pOiBBc3N1bWVkQ2hhcnQge1xuICBjb25zdCByb290ID0gaXNDaGFydChjaGFydCkgPyAoY2hhcnQgYXMgeyByb290OiB1bmtub3duIH0pLnJvb3QgOiB1bmRlZmluZWQ7XG4gIGlmICghaXNOb2RlKHJvb3QpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgdGltZUJ1ZGdldDogYXNzdW1lLiR7ZmllbGR9Wycke2tleX0nXSBtdXN0IGJlIGEgYnVpbHQgY2hhcnQgKGZsb3dDaGFydCguLi4pLmJ1aWxkKCkpLmApO1xuICB9XG4gIGNvbnN0IHsgc3ViZmxvd3MsIHN0YWdlTWFwIH0gPSBjaGFydCBhcyBGbG93Q2hhcnQ7XG4gIHJldHVybiBPYmplY3QuZnJlZXplKHtcbiAgICByb290LFxuICAgIC4uLihzdWJmbG93cyAhPT0gdW5kZWZpbmVkICYmIHsgc3ViZmxvd3M6IHN1YmZsb3dzIGFzIFJlY29yZDxzdHJpbmcsIHsgcm9vdDogU3RhZ2VOb2RlIH0+IH0pLFxuICAgIC4uLihzdGFnZU1hcCBpbnN0YW5jZW9mIE1hcCAmJiB7IHN0YWdlTWFwIH0pLFxuICB9KTtcbn1cbiJdfQ==