footprintjs 9.48.2 → 10.0.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 (326) hide show
  1. package/AGENTS.md +12 -10
  2. package/CLAUDE.md +21 -23
  3. package/README.md +1 -1
  4. package/dist/advanced.js +71 -128
  5. package/dist/esm/advanced.d.ts +24 -58
  6. package/dist/esm/advanced.js +13 -51
  7. package/dist/esm/index.d.ts +5 -8
  8. package/dist/esm/index.js +3 -3
  9. package/dist/esm/lib/builder/FlowChartBuilder.d.ts +1 -1
  10. package/dist/esm/lib/builder/FlowChartBuilder.js +3 -3
  11. package/dist/esm/lib/builder/structure/StructureRecorder.d.ts +1 -1
  12. package/dist/esm/lib/builder/structure/StructureRecorder.js +1 -1
  13. package/dist/esm/lib/capture/index.d.ts +0 -1
  14. package/dist/esm/lib/capture/index.js +1 -2
  15. package/dist/esm/lib/engine/graph/prefixNodeTree.js +2 -2
  16. package/dist/esm/lib/engine/handlers/ResumeEntry.d.ts +3 -3
  17. package/dist/esm/lib/engine/handlers/ResumeEntry.js +4 -4
  18. package/dist/esm/lib/engine/handlers/SubflowExecutor.d.ts +1 -2
  19. package/dist/esm/lib/engine/handlers/SubflowExecutor.js +4 -8
  20. package/dist/esm/lib/engine/index.d.ts +1 -1
  21. package/dist/esm/lib/engine/index.js +1 -1
  22. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +4 -4
  23. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +1 -1
  24. package/dist/esm/lib/engine/narrative/index.d.ts +1 -1
  25. package/dist/esm/lib/engine/narrative/index.js +1 -1
  26. package/dist/esm/lib/engine/narrative/narrativeTypes.d.ts +1 -11
  27. package/dist/esm/lib/engine/narrative/narrativeTypes.js +1 -1
  28. package/dist/esm/lib/engine/traversal/FlowchartTraverser.d.ts +2 -10
  29. package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +4 -6
  30. package/dist/esm/lib/engine/traversalContext.d.ts +1 -1
  31. package/dist/esm/lib/engine/traversalContext.js +2 -2
  32. package/dist/esm/lib/engine/types.d.ts +2 -10
  33. package/dist/esm/lib/engine/types.js +1 -1
  34. package/dist/esm/lib/engine/walkSubflowSpec.js +2 -2
  35. package/dist/esm/lib/ids/reservedIds.js +2 -2
  36. package/dist/esm/lib/memory/DiagnosticCollector.js +2 -2
  37. package/dist/esm/lib/memory/StageContext.d.ts +2 -4
  38. package/dist/esm/lib/memory/StageContext.js +2 -2
  39. package/dist/esm/lib/memory/borrowedMutation.js +2 -2
  40. package/dist/esm/lib/memory/index.d.ts +6 -21
  41. package/dist/esm/lib/memory/index.js +4 -22
  42. package/dist/esm/lib/memory/redaction.d.ts +1 -1
  43. package/dist/esm/lib/memory/redaction.js +2 -2
  44. package/dist/esm/lib/memory/runPolicy.d.ts +3 -2
  45. package/dist/esm/lib/memory/runPolicy.js +1 -1
  46. package/dist/esm/lib/reactive/createTypedScope.js +2 -2
  47. package/dist/esm/lib/reactive/writeTraps.js +2 -2
  48. package/dist/esm/lib/recorder/ControlDepRecorder.d.ts +3 -2
  49. package/dist/esm/lib/recorder/ControlDepRecorder.js +3 -2
  50. package/dist/esm/lib/recorder/EmitRecorder.d.ts +1 -1
  51. package/dist/esm/lib/recorder/EmitRecorder.js +1 -1
  52. package/dist/esm/lib/recorder/InOutRecorder.js +2 -2
  53. package/dist/esm/lib/recorder/qualityTrace.d.ts +1 -1
  54. package/dist/esm/lib/recorder/qualityTrace.js +2 -2
  55. package/dist/esm/lib/runner/DeferredObserverTier.js +2 -2
  56. package/dist/esm/lib/runner/ExecutionRuntime.d.ts +4 -5
  57. package/dist/esm/lib/runner/ExecutionRuntime.js +2 -5
  58. package/dist/esm/lib/runner/FlowChartExecutor.d.ts +1 -1
  59. package/dist/esm/lib/runner/FlowChartExecutor.js +1 -1
  60. package/dist/esm/lib/runner/getSubtreeSnapshot.d.ts +1 -1
  61. package/dist/esm/lib/runner/getSubtreeSnapshot.js +4 -4
  62. package/dist/esm/lib/runner/resume.js +2 -2
  63. package/dist/esm/lib/runner/snapshot.js +3 -2
  64. package/dist/esm/lib/scope/ScopeFacade.js +2 -2
  65. package/dist/esm/lib/scope/state/zod/scopeFactory.js +2 -2
  66. package/dist/esm/recorders.d.ts +2 -3
  67. package/dist/esm/recorders.js +1 -1
  68. package/dist/esm/trace.d.ts +11 -57
  69. package/dist/esm/trace.js +10 -68
  70. package/dist/index.js +3 -3
  71. package/dist/lib/builder/FlowChartBuilder.js +5 -5
  72. package/dist/lib/builder/structure/StructureRecorder.js +1 -1
  73. package/dist/lib/capture/index.js +2 -4
  74. package/dist/lib/engine/graph/prefixNodeTree.js +5 -5
  75. package/dist/lib/engine/handlers/ResumeEntry.js +4 -4
  76. package/dist/lib/engine/handlers/SubflowExecutor.js +5 -9
  77. package/dist/lib/engine/index.js +1 -1
  78. package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +1 -1
  79. package/dist/lib/engine/narrative/index.js +1 -1
  80. package/dist/lib/engine/narrative/narrativeTypes.js +1 -1
  81. package/dist/lib/engine/traversal/FlowchartTraverser.js +8 -10
  82. package/dist/lib/engine/traversalContext.js +4 -4
  83. package/dist/lib/engine/types.js +1 -1
  84. package/dist/lib/engine/walkSubflowSpec.js +3 -3
  85. package/dist/lib/ids/reservedIds.js +5 -5
  86. package/dist/lib/memory/DiagnosticCollector.js +3 -3
  87. package/dist/lib/memory/StageContext.js +3 -3
  88. package/dist/lib/memory/borrowedMutation.js +3 -3
  89. package/dist/lib/memory/index.js +7 -42
  90. package/dist/lib/memory/redaction.js +3 -3
  91. package/dist/lib/memory/runPolicy.js +1 -1
  92. package/dist/lib/reactive/createTypedScope.js +3 -3
  93. package/dist/lib/reactive/writeTraps.js +4 -4
  94. package/dist/lib/recorder/ControlDepRecorder.js +3 -2
  95. package/dist/lib/recorder/EmitRecorder.js +1 -1
  96. package/dist/lib/recorder/InOutRecorder.js +3 -3
  97. package/dist/lib/recorder/qualityTrace.js +4 -4
  98. package/dist/lib/runner/DeferredObserverTier.js +3 -3
  99. package/dist/lib/runner/ExecutionRuntime.js +6 -9
  100. package/dist/lib/runner/FlowChartExecutor.js +1 -1
  101. package/dist/lib/runner/getSubtreeSnapshot.js +6 -6
  102. package/dist/lib/runner/resume.js +3 -3
  103. package/dist/lib/runner/snapshot.js +6 -5
  104. package/dist/lib/scope/ScopeFacade.js +3 -3
  105. package/dist/lib/scope/state/zod/scopeFactory.js +4 -4
  106. package/dist/recorders.js +1 -1
  107. package/dist/trace.js +18 -120
  108. package/dist/types/advanced.d.ts +24 -58
  109. package/dist/types/index.d.ts +5 -8
  110. package/dist/types/lib/builder/FlowChartBuilder.d.ts +1 -1
  111. package/dist/types/lib/builder/structure/StructureRecorder.d.ts +1 -1
  112. package/dist/types/lib/capture/index.d.ts +0 -1
  113. package/dist/types/lib/engine/handlers/ResumeEntry.d.ts +3 -3
  114. package/dist/types/lib/engine/handlers/SubflowExecutor.d.ts +1 -2
  115. package/dist/types/lib/engine/index.d.ts +1 -1
  116. package/dist/types/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +4 -4
  117. package/dist/types/lib/engine/narrative/index.d.ts +1 -1
  118. package/dist/types/lib/engine/narrative/narrativeTypes.d.ts +1 -11
  119. package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +2 -10
  120. package/dist/types/lib/engine/traversalContext.d.ts +1 -1
  121. package/dist/types/lib/engine/types.d.ts +2 -10
  122. package/dist/types/lib/memory/StageContext.d.ts +2 -4
  123. package/dist/types/lib/memory/index.d.ts +6 -21
  124. package/dist/types/lib/memory/redaction.d.ts +1 -1
  125. package/dist/types/lib/memory/runPolicy.d.ts +3 -2
  126. package/dist/types/lib/recorder/ControlDepRecorder.d.ts +3 -2
  127. package/dist/types/lib/recorder/EmitRecorder.d.ts +1 -1
  128. package/dist/types/lib/recorder/qualityTrace.d.ts +1 -1
  129. package/dist/types/lib/runner/ExecutionRuntime.d.ts +4 -5
  130. package/dist/types/lib/runner/FlowChartExecutor.d.ts +1 -1
  131. package/dist/types/lib/runner/getSubtreeSnapshot.d.ts +1 -1
  132. package/dist/types/recorders.d.ts +2 -3
  133. package/dist/types/trace.d.ts +11 -57
  134. package/package.json +6 -15
  135. package/dist/esm/lib/capture/freeze.d.ts +0 -91
  136. package/dist/esm/lib/capture/freeze.js +0 -314
  137. package/dist/esm/lib/capture/ownData.d.ts +0 -7
  138. package/dist/esm/lib/capture/ownData.js +0 -15
  139. package/dist/esm/lib/capture/valueKinds.d.ts +0 -57
  140. package/dist/esm/lib/capture/valueKinds.js +0 -142
  141. package/dist/esm/lib/ids/runtimeStageId.d.ts +0 -173
  142. package/dist/esm/lib/ids/runtimeStageId.js +0 -194
  143. package/dist/esm/lib/memory/EventLog.d.ts +0 -105
  144. package/dist/esm/lib/memory/EventLog.js +0 -148
  145. package/dist/esm/lib/memory/RecordFrame.d.ts +0 -232
  146. package/dist/esm/lib/memory/RecordFrame.js +0 -296
  147. package/dist/esm/lib/memory/SharedMemory.d.ts +0 -46
  148. package/dist/esm/lib/memory/SharedMemory.js +0 -88
  149. package/dist/esm/lib/memory/TransactionBuffer.d.ts +0 -521
  150. package/dist/esm/lib/memory/TransactionBuffer.js +0 -946
  151. package/dist/esm/lib/memory/admission.d.ts +0 -81
  152. package/dist/esm/lib/memory/admission.js +0 -153
  153. package/dist/esm/lib/memory/backtrack.d.ts +0 -286
  154. package/dist/esm/lib/memory/backtrack.js +0 -457
  155. package/dist/esm/lib/memory/commitLogUtils.d.ts +0 -217
  156. package/dist/esm/lib/memory/commitLogUtils.js +0 -384
  157. package/dist/esm/lib/memory/deltaEncoding.d.ts +0 -66
  158. package/dist/esm/lib/memory/deltaEncoding.js +0 -122
  159. package/dist/esm/lib/memory/equality.d.ts +0 -93
  160. package/dist/esm/lib/memory/equality.js +0 -262
  161. package/dist/esm/lib/memory/eventPosition.d.ts +0 -18
  162. package/dist/esm/lib/memory/eventPosition.js +0 -2
  163. package/dist/esm/lib/memory/honesty.d.ts +0 -93
  164. package/dist/esm/lib/memory/honesty.js +0 -92
  165. package/dist/esm/lib/memory/keyPaths.d.ts +0 -125
  166. package/dist/esm/lib/memory/keyPaths.js +0 -227
  167. package/dist/esm/lib/memory/logModel.d.ts +0 -76
  168. package/dist/esm/lib/memory/logModel.js +0 -364
  169. package/dist/esm/lib/memory/merge.d.ts +0 -26
  170. package/dist/esm/lib/memory/merge.js +0 -60
  171. package/dist/esm/lib/memory/pathOps.d.ts +0 -115
  172. package/dist/esm/lib/memory/pathOps.js +0 -290
  173. package/dist/esm/lib/memory/paths.d.ts +0 -52
  174. package/dist/esm/lib/memory/paths.js +0 -57
  175. package/dist/esm/lib/memory/placeholders.d.ts +0 -39
  176. package/dist/esm/lib/memory/placeholders.js +0 -40
  177. package/dist/esm/lib/memory/recordCommit.d.ts +0 -45
  178. package/dist/esm/lib/memory/recordCommit.js +0 -61
  179. package/dist/esm/lib/memory/scrub.d.ts +0 -53
  180. package/dist/esm/lib/memory/scrub.js +0 -74
  181. package/dist/esm/lib/memory/types.d.ts +0 -209
  182. package/dist/esm/lib/memory/types.js +0 -10
  183. package/dist/esm/lib/memory/utils.d.ts +0 -73
  184. package/dist/esm/lib/memory/utils.js +0 -159
  185. package/dist/esm/lib/memory/verbs.d.ts +0 -333
  186. package/dist/esm/lib/memory/verbs.js +0 -427
  187. package/dist/esm/lib/recorder/CommitRangeIndex.d.ts +0 -147
  188. package/dist/esm/lib/recorder/CommitRangeIndex.js +0 -207
  189. package/dist/esm/lib/scope/detectCircular.d.ts +0 -13
  190. package/dist/esm/lib/scope/detectCircular.js +0 -14
  191. package/dist/esm/lib/scope/recorders/summarizeValue.d.ts +0 -5
  192. package/dist/esm/lib/scope/recorders/summarizeValue.js +0 -6
  193. package/dist/esm/lib/slice/elementProvenance.d.ts +0 -81
  194. package/dist/esm/lib/slice/elementProvenance.js +0 -190
  195. package/dist/esm/lib/slice/forwardSliceForKey.d.ts +0 -88
  196. package/dist/esm/lib/slice/forwardSliceForKey.js +0 -243
  197. package/dist/esm/lib/slice/index.d.ts +0 -25
  198. package/dist/esm/lib/slice/index.js +0 -25
  199. package/dist/esm/lib/slice/keyIndex.d.ts +0 -137
  200. package/dist/esm/lib/slice/keyIndex.js +0 -293
  201. package/dist/esm/lib/slice/keyTimeline.d.ts +0 -49
  202. package/dist/esm/lib/slice/keyTimeline.js +0 -113
  203. package/dist/esm/lib/slice/keysReadSources.d.ts +0 -51
  204. package/dist/esm/lib/slice/keysReadSources.js +0 -95
  205. package/dist/esm/lib/slice/serialize.d.ts +0 -78
  206. package/dist/esm/lib/slice/serialize.js +0 -278
  207. package/dist/esm/lib/slice/sliceForKey.d.ts +0 -47
  208. package/dist/esm/lib/slice/sliceForKey.js +0 -88
  209. package/dist/esm/lib/slice/types.d.ts +0 -567
  210. package/dist/esm/lib/slice/types.js +0 -25
  211. package/dist/esm/lib/time-travel/axis.d.ts +0 -119
  212. package/dist/esm/lib/time-travel/axis.js +0 -179
  213. package/dist/esm/lib/time-travel/bundles.d.ts +0 -77
  214. package/dist/esm/lib/time-travel/bundles.js +0 -136
  215. package/dist/esm/lib/time-travel/chain.d.ts +0 -93
  216. package/dist/esm/lib/time-travel/chain.js +0 -188
  217. package/dist/esm/lib/time-travel/commitStops.d.ts +0 -55
  218. package/dist/esm/lib/time-travel/commitStops.js +0 -202
  219. package/dist/esm/lib/time-travel/index.d.ts +0 -22
  220. package/dist/esm/lib/time-travel/index.js +0 -21
  221. package/dist/esm/lib/time-travel/stateAt.d.ts +0 -102
  222. package/dist/esm/lib/time-travel/stateAt.js +0 -153
  223. package/dist/esm/lib/time-travel/tagStops.d.ts +0 -72
  224. package/dist/esm/lib/time-travel/tagStops.js +0 -102
  225. package/dist/esm/lib/time-travel/timeTravel.d.ts +0 -70
  226. package/dist/esm/lib/time-travel/timeTravel.js +0 -360
  227. package/dist/esm/lib/time-travel/types.d.ts +0 -470
  228. package/dist/esm/lib/time-travel/types.js +0 -23
  229. package/dist/esm/write.d.ts +0 -47
  230. package/dist/esm/write.js +0 -46
  231. package/dist/lib/capture/freeze.js +0 -320
  232. package/dist/lib/capture/ownData.js +0 -19
  233. package/dist/lib/capture/valueKinds.js +0 -146
  234. package/dist/lib/ids/runtimeStageId.js +0 -210
  235. package/dist/lib/memory/EventLog.js +0 -152
  236. package/dist/lib/memory/RecordFrame.js +0 -300
  237. package/dist/lib/memory/SharedMemory.js +0 -92
  238. package/dist/lib/memory/TransactionBuffer.js +0 -950
  239. package/dist/lib/memory/admission.js +0 -159
  240. package/dist/lib/memory/backtrack.js +0 -463
  241. package/dist/lib/memory/commitLogUtils.js +0 -399
  242. package/dist/lib/memory/deltaEncoding.js +0 -128
  243. package/dist/lib/memory/equality.js +0 -266
  244. package/dist/lib/memory/eventPosition.js +0 -3
  245. package/dist/lib/memory/honesty.js +0 -95
  246. package/dist/lib/memory/keyPaths.js +0 -243
  247. package/dist/lib/memory/logModel.js +0 -372
  248. package/dist/lib/memory/merge.js +0 -64
  249. package/dist/lib/memory/pathOps.js +0 -306
  250. package/dist/lib/memory/paths.js +0 -62
  251. package/dist/lib/memory/placeholders.js +0 -43
  252. package/dist/lib/memory/recordCommit.js +0 -65
  253. package/dist/lib/memory/scrub.js +0 -79
  254. package/dist/lib/memory/types.js +0 -11
  255. package/dist/lib/memory/utils.js +0 -178
  256. package/dist/lib/memory/verbs.js +0 -444
  257. package/dist/lib/recorder/CommitRangeIndex.js +0 -211
  258. package/dist/lib/scope/detectCircular.js +0 -21
  259. package/dist/lib/scope/recorders/summarizeValue.js +0 -10
  260. package/dist/lib/slice/elementProvenance.js +0 -195
  261. package/dist/lib/slice/forwardSliceForKey.js +0 -247
  262. package/dist/lib/slice/index.js +0 -42
  263. package/dist/lib/slice/keyIndex.js +0 -313
  264. package/dist/lib/slice/keyTimeline.js +0 -117
  265. package/dist/lib/slice/keysReadSources.js +0 -101
  266. package/dist/lib/slice/serialize.js +0 -286
  267. package/dist/lib/slice/sliceForKey.js +0 -93
  268. package/dist/lib/slice/types.js +0 -26
  269. package/dist/lib/time-travel/axis.js +0 -184
  270. package/dist/lib/time-travel/bundles.js +0 -144
  271. package/dist/lib/time-travel/chain.js +0 -193
  272. package/dist/lib/time-travel/commitStops.js +0 -206
  273. package/dist/lib/time-travel/index.js +0 -32
  274. package/dist/lib/time-travel/stateAt.js +0 -160
  275. package/dist/lib/time-travel/tagStops.js +0 -106
  276. package/dist/lib/time-travel/timeTravel.js +0 -364
  277. package/dist/lib/time-travel/types.js +0 -24
  278. package/dist/types/lib/capture/freeze.d.ts +0 -91
  279. package/dist/types/lib/capture/ownData.d.ts +0 -7
  280. package/dist/types/lib/capture/valueKinds.d.ts +0 -57
  281. package/dist/types/lib/ids/runtimeStageId.d.ts +0 -173
  282. package/dist/types/lib/memory/EventLog.d.ts +0 -105
  283. package/dist/types/lib/memory/RecordFrame.d.ts +0 -232
  284. package/dist/types/lib/memory/SharedMemory.d.ts +0 -46
  285. package/dist/types/lib/memory/TransactionBuffer.d.ts +0 -521
  286. package/dist/types/lib/memory/admission.d.ts +0 -81
  287. package/dist/types/lib/memory/backtrack.d.ts +0 -286
  288. package/dist/types/lib/memory/commitLogUtils.d.ts +0 -217
  289. package/dist/types/lib/memory/deltaEncoding.d.ts +0 -66
  290. package/dist/types/lib/memory/equality.d.ts +0 -93
  291. package/dist/types/lib/memory/eventPosition.d.ts +0 -18
  292. package/dist/types/lib/memory/honesty.d.ts +0 -93
  293. package/dist/types/lib/memory/keyPaths.d.ts +0 -125
  294. package/dist/types/lib/memory/logModel.d.ts +0 -76
  295. package/dist/types/lib/memory/merge.d.ts +0 -26
  296. package/dist/types/lib/memory/pathOps.d.ts +0 -115
  297. package/dist/types/lib/memory/paths.d.ts +0 -52
  298. package/dist/types/lib/memory/placeholders.d.ts +0 -39
  299. package/dist/types/lib/memory/recordCommit.d.ts +0 -45
  300. package/dist/types/lib/memory/scrub.d.ts +0 -53
  301. package/dist/types/lib/memory/types.d.ts +0 -209
  302. package/dist/types/lib/memory/utils.d.ts +0 -73
  303. package/dist/types/lib/memory/verbs.d.ts +0 -333
  304. package/dist/types/lib/recorder/CommitRangeIndex.d.ts +0 -147
  305. package/dist/types/lib/scope/detectCircular.d.ts +0 -13
  306. package/dist/types/lib/scope/recorders/summarizeValue.d.ts +0 -5
  307. package/dist/types/lib/slice/elementProvenance.d.ts +0 -81
  308. package/dist/types/lib/slice/forwardSliceForKey.d.ts +0 -88
  309. package/dist/types/lib/slice/index.d.ts +0 -25
  310. package/dist/types/lib/slice/keyIndex.d.ts +0 -137
  311. package/dist/types/lib/slice/keyTimeline.d.ts +0 -49
  312. package/dist/types/lib/slice/keysReadSources.d.ts +0 -51
  313. package/dist/types/lib/slice/serialize.d.ts +0 -78
  314. package/dist/types/lib/slice/sliceForKey.d.ts +0 -47
  315. package/dist/types/lib/slice/types.d.ts +0 -567
  316. package/dist/types/lib/time-travel/axis.d.ts +0 -119
  317. package/dist/types/lib/time-travel/bundles.d.ts +0 -77
  318. package/dist/types/lib/time-travel/chain.d.ts +0 -93
  319. package/dist/types/lib/time-travel/commitStops.d.ts +0 -55
  320. package/dist/types/lib/time-travel/index.d.ts +0 -22
  321. package/dist/types/lib/time-travel/stateAt.d.ts +0 -102
  322. package/dist/types/lib/time-travel/tagStops.d.ts +0 -72
  323. package/dist/types/lib/time-travel/timeTravel.d.ts +0 -70
  324. package/dist/types/lib/time-travel/types.d.ts +0 -470
  325. package/dist/types/write.d.ts +0 -47
  326. package/dist/write.js +0 -52
@@ -1,360 +0,0 @@
1
- /**
2
- * timeTravel — a reader's cursor over a finished trace.
3
- *
4
- * The five laws this file implements (and the folder README states with an
5
- * example each):
6
- *
7
- * 1. ONE cursor. This object holds the only position. `drill()` returns a
8
- * separate cursor over a separate log, never a second position here.
9
- * 2. A miss never moves. Every refusal returns the reason and leaves the
10
- * cursor exactly where it was.
11
- * 3. A fold result is detached. `stateAt` returns frozen, cloned state that
12
- * shares nothing with the engine.
13
- * 4. Marks live beside the log. They are the reader's notes, never written
14
- * into the run's record.
15
- * 5. Stops are DERIVED from the recorded log — read-time queries over
16
- * collected data, never a re-walk that invents what was not recorded.
17
- *
18
- * A CHAIN (9.18.0) does not add a sixth law and does not bend these five: it
19
- * is still one cursor, over sources that are still only read. What it adds is
20
- * that the STEPS run across a pause/resume — see `chain.ts` for the ordering
21
- * and lineage checks, and for why commit indices stay run-local.
22
- */
23
- import { executionIndexOf, isExecutionKey, stageIdOf } from '../ids/runtimeStageId.js';
24
- import { isPlainish, readTree } from './bundles.js';
25
- import { refuseChain } from './chain.js';
26
- import { commitStopsStrategy } from './commitStops.js';
27
- import { foldLegsFrom, readSource } from './stateAt.js';
28
- class Cursor {
29
- stops;
30
- path;
31
- mountRuntimeStageId;
32
- parent;
33
- sourceCount;
34
- legs;
35
- sources;
36
- options;
37
- _marks;
38
- step;
39
- /** The last fold's working copy, so a step forward applies one bundle (9.25.0). */
40
- foldMemo;
41
- constructor(sources, options, path, parent, mountRuntimeStageId) {
42
- this.sources = sources;
43
- this.options = options;
44
- this.path = path;
45
- this.parent = parent;
46
- this.mountRuntimeStageId = mountRuntimeStageId;
47
- this.legs = sources.map((source) => readSource(source));
48
- this.sourceCount = sources.length;
49
- // The shipped strategy has no vocabulary of its own (`meta` is never set),
50
- // so it serves any `TMeta` a caller asked for.
51
- const strategy = options.strategy ?? commitStopsStrategy;
52
- // ONE CALL PER SOURCE, with that source's own log and tree: a strategy
53
- // never has to know it is part of a chain, and its indices stay local to
54
- // the leg it was handed.
55
- const perSource = this.legs.map((leg, i) => strategy.stopsFor(leg.log, readTree(sources[i].executionTree), sources[i].subflowResults));
56
- this.stops = Object.freeze(sources.length === 1 ? perSource[0] : chainStops(perSource));
57
- this._marks = [...(options.marks ?? [])];
58
- this.step = 0;
59
- }
60
- // ── Position ─────────────────────────────────────────────────────────────
61
- at() {
62
- return this.stops[this.step];
63
- }
64
- moveTo(step) {
65
- const from = this.at();
66
- this.step = step;
67
- return { moved: true, from, to: this.stops[step] };
68
- }
69
- /** Law 2: a refusal never touches `this.step`. */
70
- refuse(reason, nearest) {
71
- const at = this.at();
72
- return nearest ? { moved: false, reason, at, nearest } : { moved: false, reason, at };
73
- }
74
- first() {
75
- if (this.stops.length === 0)
76
- return this.refuse('empty');
77
- if (this.step === 0)
78
- return this.refuse('clamped');
79
- return this.moveTo(0);
80
- }
81
- last() {
82
- if (this.stops.length === 0)
83
- return this.refuse('empty');
84
- const end = this.stops.length - 1;
85
- if (this.step === end)
86
- return this.refuse('clamped');
87
- return this.moveTo(end);
88
- }
89
- prev() {
90
- if (this.stops.length === 0)
91
- return this.refuse('empty');
92
- if (this.step === 0)
93
- return this.refuse('clamped');
94
- return this.moveTo(this.step - 1);
95
- }
96
- next() {
97
- if (this.stops.length === 0)
98
- return this.refuse('empty');
99
- if (this.step >= this.stops.length - 1)
100
- return this.refuse('clamped');
101
- return this.moveTo(this.step + 1);
102
- }
103
- jumpTo(target) {
104
- if (this.stops.length === 0)
105
- return this.refuse('empty');
106
- if (typeof target === 'number') {
107
- const step = Math.trunc(target);
108
- if (Number.isNaN(step))
109
- return this.refuse('miss');
110
- if (step < 0)
111
- return this.refuse('clamped', this.stops[0]);
112
- if (step > this.stops.length - 1)
113
- return this.refuse('clamped', this.stops[this.stops.length - 1]);
114
- if (step === this.step)
115
- return this.refuse('clamped');
116
- return this.moveTo(step);
117
- }
118
- // `''` is not an address: it is what the bookends and any pre-stage
119
- // root commit carry. Those are reached by step, never by id.
120
- if (target === '')
121
- return this.refuse('miss');
122
- const hit = this.stops.find((stop) => stop.runtimeStageId === target);
123
- if (!hit)
124
- return this.refuse('miss', this.nearestTo(target));
125
- if (hit.step === this.step)
126
- return this.refuse('clamped');
127
- return this.moveTo(hit.step);
128
- }
129
- /**
130
- * The closest namable stop for a `runtimeStageId` that is not on this axis:
131
- * the last stop of the same STAGE (a different iteration of the same node),
132
- * else the last stop whose commit precedes the missed id's execution index.
133
- * Naming a neighbour is a courtesy for the UI — it never moves the cursor.
134
- */
135
- nearestTo(runtimeStageId) {
136
- if (!isExecutionKey(runtimeStageId))
137
- return undefined;
138
- const stagePart = stageIdOf(runtimeStageId);
139
- const wanted = executionIndexOf(runtimeStageId);
140
- let sameStage;
141
- let byIndex;
142
- for (const stop of this.stops) {
143
- if (!isExecutionKey(stop.runtimeStageId))
144
- continue;
145
- if (stageIdOf(stop.runtimeStageId) === stagePart)
146
- sameStage = stop;
147
- if (!Number.isNaN(wanted)) {
148
- const idx = executionIndexOf(stop.runtimeStageId);
149
- if (!Number.isNaN(idx) && idx <= wanted)
150
- byIndex = stop;
151
- }
152
- }
153
- return sameStage ?? byIndex;
154
- }
155
- // ── Reading ──────────────────────────────────────────────────────────────
156
- stateAt(stop) {
157
- const target = stop ?? this.at();
158
- const leg = target?.sourceIdx ?? 0;
159
- const fold = foldLegsFrom(this.legs, leg, target ? target.lastCommitIdx : -1, this.foldMemo);
160
- this.foldMemo = fold.memo;
161
- const folded = fold.folded;
162
- // Which leg the index belongs to, but only when there is more than one —
163
- // a single-source fold keeps the 9.17.0 shape exactly.
164
- return this.legs.length > 1 ? { ...folded, sourceIdx: leg } : folded;
165
- }
166
- changedSince(from) {
167
- const to = this.at();
168
- if (!to)
169
- return Object.freeze([]);
170
- const start = from ?? this.stops[this.step - 1];
171
- // No earlier stop (we are at `'start'`) ⇒ everything up to here: nothing
172
- // on a run cursor, and the subflow's `inputMapper` seed on a drilled one
173
- // (the start bookend covers the seed that precedes stage one — `commitStops`).
174
- const toLeg = to.sourceIdx ?? 0;
175
- const fromLeg = start ? start.sourceIdx ?? 0 : toLeg;
176
- const afterIdx = start ? start.lastCommitIdx : -1;
177
- const keys = new Set();
178
- // A range that crosses a chain seam is walked leg by leg: the tail of the
179
- // leg it started in, every leg in between whole, then the head of the leg
180
- // it ends in. Backwards ranges walk nothing and give `[]`, as before.
181
- for (let leg = fromLeg; leg <= toLeg && leg < this.legs.length; leg++) {
182
- const log = this.legs[leg].log;
183
- const lo = leg === fromLeg ? afterIdx + 1 : 0;
184
- const hi = leg === toLeg ? to.lastCommitIdx : log.length - 1;
185
- for (let i = lo; i <= hi; i++) {
186
- const bundle = log[i];
187
- if (!bundle)
188
- continue;
189
- for (const entry of bundle.trace)
190
- keys.add(entry.path);
191
- }
192
- }
193
- return Object.freeze([...keys].sort());
194
- }
195
- // ── Marks (law 4: beside the log, never in it) ───────────────────────────
196
- mark(name, stop) {
197
- const target = stop ?? this.at();
198
- if (!target)
199
- return undefined;
200
- const entry = Object.freeze({ name, runtimeStageId: target.runtimeStageId, step: target.step });
201
- const existing = this._marks.findIndex((m) => m.name === name);
202
- if (existing >= 0)
203
- this._marks[existing] = entry;
204
- else
205
- this._marks.push(entry);
206
- return entry;
207
- }
208
- marks() {
209
- return Object.freeze([...this._marks]);
210
- }
211
- jumpToMark(name) {
212
- if (this.stops.length === 0)
213
- return this.refuse('empty');
214
- const entry = this._marks.find((m) => m.name === name);
215
- if (!entry)
216
- return this.refuse('miss');
217
- // Resolve by runtimeStageId first — the address that survives a change of
218
- // strategy — and fall back to the remembered step only for the bookends,
219
- // which have no stage id of their own.
220
- const byId = entry.runtimeStageId
221
- ? this.stops.find((stop) => stop.runtimeStageId === entry.runtimeStageId)
222
- : this.stops[entry.step];
223
- if (!byId)
224
- return this.refuse('miss', this.nearestTo(entry.runtimeStageId));
225
- if (byId.step === this.step)
226
- return this.refuse('clamped');
227
- return this.moveTo(byId.step);
228
- }
229
- // ── Drilling (law 1: a separate cursor, not a second position) ───────────
230
- drill(mountRuntimeStageId) {
231
- // On a chain, the mount is looked for in every leg — a subflow that ran
232
- // before the pause is in the first snapshot's results, one that ran after
233
- // is in the second's. Ids are unique across a sound chain (chain.ts
234
- // refuses one where they are not), so the first hit is the only hit.
235
- let results;
236
- let result;
237
- for (const source of this.sources) {
238
- // A stored recording's results are parsed JSON: read them as a map only
239
- // when they are one, and as "no subflows" otherwise.
240
- if (!isPlainish(source.subflowResults))
241
- continue;
242
- const hit = source.subflowResults[mountRuntimeStageId];
243
- if (hit) {
244
- results = source.subflowResults;
245
- result = hit;
246
- break;
247
- }
248
- }
249
- const tree = result?.treeContext;
250
- if (!results || !result || !tree || !Array.isArray(tree.history))
251
- return undefined;
252
- // `path` is the subflow PATH — the same string for every iteration of a
253
- // mount inside a loop. `mountRuntimeStageId` is the iteration actually
254
- // opened, so a UI can label and key three drill panels over `sfx#2`,
255
- // `sfx#8`, `sfx#14` apart instead of calling all three 'sfx'.
256
- const childPath = result.subflowId ?? mountRuntimeStageId;
257
- const child = {
258
- // Rows are narrowed per bundle when the child reads them — a stored
259
- // recording's inner history needs no cast either.
260
- commitLog: tree.history,
261
- initialState: tree.initialState,
262
- executionTree: tree.stageContexts,
263
- // Nested subflow results are merged UP into one flat, dual-keyed map, so
264
- // the child can drill further through the same map.
265
- subflowResults: results,
266
- };
267
- return new Cursor([child], { strategy: this.options.strategy }, childPath, this, mountRuntimeStageId);
268
- }
269
- }
270
- /**
271
- * Re-step per-source stops into ONE axis.
272
- *
273
- * The INTERIOR bookends go: a `'start'` on any leg but the first, and an
274
- * `'end'` on any leg but the last, are bookends of a leg and not of the run —
275
- * keeping them would put "the run is over" in the middle of the axis. The
276
- * commits they covered are not orphaned: a fold always replays its leg from
277
- * that leg's own base, and `changedSince` walks a seam-crossing range leg by
278
- * leg (including the head of the leg it ends in). The stops' `commitIdx` /
279
- * `lastCommitIdx` ranges PARTITION EACH LEG, never span the seam: a stop's
280
- * range ends at its own leg's last index, and the next leg's first stop opens
281
- * at that leg's 0.
282
- */
283
- function chainStops(perSource) {
284
- // "Interior" is measured against the legs that actually CONTRIBUTE stops: a
285
- // leg whose log was empty has no bookends to drop and must not make its
286
- // neighbour's `'start'` or `'end'` interior — the chained axis still opens
287
- // with the first stop that exists and closes with the last.
288
- const contributing = perSource.map((stops) => stops.length > 0);
289
- const firstLeg = contributing.indexOf(true);
290
- const lastLeg = contributing.lastIndexOf(true);
291
- const out = [];
292
- for (const [sourceIdx, stops] of perSource.entries()) {
293
- for (const stop of stops) {
294
- if (sourceIdx > firstLeg && stop.kind === 'start')
295
- continue;
296
- if (sourceIdx < lastLeg && stop.kind === 'end')
297
- continue;
298
- out.push({ ...stop, step: out.length, sourceIdx });
299
- }
300
- }
301
- return out;
302
- }
303
- /**
304
- * Open a reader's cursor over a finished run.
305
- *
306
- * Nothing here executes anything: `snapshot` is a record of a run that already
307
- * happened, and every question is answered by reading it. A stored JSON
308
- * snapshot works exactly like a live one — since 9.18.0 its `commitLog` may be
309
- * an unvalidated `unknown[]`, narrowed per bundle where the fold reads it, so
310
- * a replayed recording needs no cast.
311
- *
312
- * @param snapshot `executor.getSnapshot()`, or any object with the same
313
- * shape — including one round-tripped through JSON, or a subflow subtree
314
- * (`getSubtreeSnapshot()`, whose log is spelled `history`). An ARRAY of them
315
- * is a CHAIN: a pause and its resume read as one axis (see below).
316
- * @param options `strategy` chooses how stops are derived (default:
317
- * `commitStops`, one stop per executed stage); `marks` seeds the cursor with
318
- * bookmarks, e.g. restored from a saved reading session.
319
- *
320
- * @throws when a chain is not in run order, or its legs are not from one
321
- * lineage — three checks, each with its own reason (see `chain.ts`):
322
- * no `runtimeStageId` may appear in two legs; each leg's first execution
323
- * index must be past the previous leg's last (the engine never resets the
324
- * counter across a resume); and each leg's `initialState` must deep-equal
325
- * the state the legs before it fold to — on a resume that base IS the state
326
- * at the pause, so a foreign leg whose indices merely happen to be higher
327
- * is refused too. The third check runs only where the record allows it: the
328
- * later leg must carry an `initialState` and the earlier legs must fold from
329
- * a real base with no unreadable rows; otherwise (an older recording with
330
- * no base) the chain rests on the two index checks alone, and the fold's
331
- * `basis` says what it stood on.
332
- *
333
- * @example
334
- * ```typescript
335
- * const tt = timeTravel(executor.getSnapshot());
336
- * tt.jumpTo('score-risk#4');
337
- * console.log(tt.changedSince()); // ['riskScore', 'tier']
338
- * console.log(tt.stateAt().state); // state as that stage left it
339
- * tt.mark('the bad one');
340
- * const inner = tt.drill('sf-payment#7'); // a separate cursor, its own log
341
- *
342
- * // A pause and its resume, read as ONE axis:
343
- * const chained = timeTravel([pausedSnapshot, resumedSnapshot]);
344
- * chained.last(); // the run's real end
345
- * chained.at()!.sourceIdx; // 1 — which leg the indices are in
346
- * chained.jumpTo('approve#3'); // finds it in either leg
347
- * ```
348
- */
349
- export function timeTravel(snapshot, options = {}) {
350
- const sources = Array.isArray(snapshot) ? snapshot : [snapshot];
351
- // A one-element array is not a chain: it is the plain cursor, and skips the
352
- // lineage checks a single source cannot fail.
353
- if (sources.length !== 1) {
354
- const refusal = refuseChain(sources.map((source) => readSource(source)));
355
- if (refusal)
356
- throw new Error(refusal);
357
- }
358
- return new Cursor(sources, options);
359
- }
360
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZVRyYXZlbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvdGltZS10cmF2ZWwvdGltZVRyYXZlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJHO0FBRUgsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGNBQWMsRUFBRSxTQUFTLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN2RixPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNwRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3ZELE9BQU8sRUFBa0MsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQXNCeEYsTUFBTSxNQUFNO0lBQ0QsS0FBSyxDQUF5QjtJQUM5QixJQUFJLENBQXFCO0lBQ3pCLG1CQUFtQixDQUFxQjtJQUN4QyxNQUFNLENBQWdDO0lBQ3RDLFdBQVcsQ0FBUztJQUVaLElBQUksQ0FBd0I7SUFDNUIsT0FBTyxDQUE4QjtJQUNyQyxPQUFPLENBQTJCO0lBQ2xDLE1BQU0sQ0FBUztJQUN4QixJQUFJLENBQVM7SUFDckIsbUZBQW1GO0lBQzNFLFFBQVEsQ0FBdUI7SUFFdkMsWUFDRSxPQUFvQyxFQUNwQyxPQUFpQyxFQUNqQyxJQUFhLEVBQ2IsTUFBMEIsRUFDMUIsbUJBQTRCO1FBRTVCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxtQkFBbUIsQ0FBQztRQUMvQyxJQUFJLENBQUMsSUFB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b3Igb3ZlciBhIGZpbmlzaGVkIHRyYWNlLlxuICpcbiAqIFRoZSBmaXZlIGxhd3MgdGhpcyBmaWxlIGltcGxlbWVudHMgKGFuZCB0aGUgZm9sZGVyIFJFQURNRSBzdGF0ZXMgd2l0aCBhblxuICogZXhhbXBsZSBlYWNoKTpcbiAqXG4gKiAgIDEuIE9ORSBjdXJzb3IuIFRoaXMgb2JqZWN0IGhvbGRzIHRoZSBvbmx5IHBvc2l0aW9uLiBgZHJpbGwoKWAgcmV0dXJucyBhXG4gKiAgICAgIHNlcGFyYXRlIGN1cnNvciBvdmVyIGEgc2VwYXJhdGUgbG9nLCBuZXZlciBhIHNlY29uZCBwb3NpdGlvbiBoZXJlLlxuICogICAyLiBBIG1pc3MgbmV2ZXIgbW92ZXMuIEV2ZXJ5IHJlZnVzYWwgcmV0dXJucyB0aGUgcmVhc29uIGFuZCBsZWF2ZXMgdGhlXG4gKiAgICAgIGN1cnNvciBleGFjdGx5IHdoZXJlIGl0IHdhcy5cbiAqICAgMy4gQSBmb2xkIHJlc3VsdCBpcyBkZXRhY2hlZC4gYHN0YXRlQXRgIHJldHVybnMgZnJvemVuLCBjbG9uZWQgc3RhdGUgdGhhdFxuICogICAgICBzaGFyZXMgbm90aGluZyB3aXRoIHRoZSBlbmdpbmUuXG4gKiAgIDQuIE1hcmtzIGxpdmUgYmVzaWRlIHRoZSBsb2cuIFRoZXkgYXJlIHRoZSByZWFkZXIncyBub3RlcywgbmV2ZXIgd3JpdHRlblxuICogICAgICBpbnRvIHRoZSBydW4ncyByZWNvcmQuXG4gKiAgIDUuIFN0b3BzIGFyZSBERVJJVkVEIGZyb20gdGhlIHJlY29yZGVkIGxvZyDigJQgcmVhZC10aW1lIHF1ZXJpZXMgb3ZlclxuICogICAgICBjb2xsZWN0ZWQgZGF0YSwgbmV2ZXIgYSByZS13YWxrIHRoYXQgaW52ZW50cyB3aGF0IHdhcyBub3QgcmVjb3JkZWQuXG4gKlxuICogQSBDSEFJTiAoOS4xOC4wKSBkb2VzIG5vdCBhZGQgYSBzaXh0aCBsYXcgYW5kIGRvZXMgbm90IGJlbmQgdGhlc2UgZml2ZTogaXRcbiAqIGlzIHN0aWxsIG9uZSBjdXJzb3IsIG92ZXIgc291cmNlcyB0aGF0IGFyZSBzdGlsbCBvbmx5IHJlYWQuIFdoYXQgaXQgYWRkcyBpc1xuICogdGhhdCB0aGUgU1RFUFMgcnVuIGFjcm9zcyBhIHBhdXNlL3Jlc3VtZSDigJQgc2VlIGBjaGFpbi50c2AgZm9yIHRoZSBvcmRlcmluZ1xuICogYW5kIGxpbmVhZ2UgY2hlY2tzLCBhbmQgZm9yIHdoeSBjb21taXQgaW5kaWNlcyBzdGF5IHJ1bi1sb2NhbC5cbiAqL1xuXG5pbXBvcnQgeyBleGVjdXRpb25JbmRleE9mLCBpc0V4ZWN1dGlvbktleSwgc3RhZ2VJZE9mIH0gZnJvbSAnLi4vaWRzL3J1bnRpbWVTdGFnZUlkLmpzJztcbmltcG9ydCB7IGlzUGxhaW5pc2gsIHJlYWRUcmVlIH0gZnJvbSAnLi9idW5kbGVzLmpzJztcbmltcG9ydCB7IHJlZnVzZUNoYWluIH0gZnJvbSAnLi9jaGFpbi5qcyc7XG5pbXBvcnQgeyBjb21taXRTdG9wc1N0cmF0ZWd5IH0gZnJvbSAnLi9jb21taXRTdG9wcy5qcyc7XG5pbXBvcnQgeyB0eXBlIEZvbGRNZW1vLCB0eXBlIFJlYWRTb3VyY2UsIGZvbGRMZWdzRnJvbSwgcmVhZFNvdXJjZSB9IGZyb20gJy4vc3RhdGVBdC5qcyc7XG5pbXBvcnQgdHlwZSB7XG4gIEZvbGRlZFN0YXRlLFxuICBNYXJrLFxuICBNb3ZlLFxuICBTdG9wLFxuICBUaW1lVHJhdmVsLFxuICBUaW1lVHJhdmVsT3B0aW9ucyxcbiAgVGltZVRyYXZlbFNvdXJjZSxcbiAgVGltZVRyYXZlbFN0cmF0ZWd5LFxufSBmcm9tICcuL3R5cGVzLmpzJztcblxuLyoqIEEgc3ViZmxvdyByZXN1bHQgYXMgdGhpcyBtb2R1bGUgbmVlZHMgdG8gcmVhZCBpdCDigJQgZHVjay10eXBlZCBvbiBwdXJwb3NlLiAqL1xuaW50ZXJmYWNlIFN1YmZsb3dSZXN1bHRTaGFwZSB7XG4gIHN1YmZsb3dJZD86IHN0cmluZztcbiAgdHJlZUNvbnRleHQ/OiB7XG4gICAgaGlzdG9yeT86IHVua25vd25bXTtcbiAgICBpbml0aWFsU3RhdGU/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICBzdGFnZUNvbnRleHRzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIH07XG59XG5cbmNsYXNzIEN1cnNvcjxUTWV0YT4gaW1wbGVtZW50cyBUaW1lVHJhdmVsPFRNZXRhPiB7XG4gIHJlYWRvbmx5IHN0b3BzOiByZWFkb25seSBTdG9wPFRNZXRhPltdO1xuICByZWFkb25seSBwYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIHJlYWRvbmx5IG1vdW50UnVudGltZVN0YWdlSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgcmVhZG9ubHkgcGFyZW50OiBUaW1lVHJhdmVsPFRNZXRhPiB8IHVuZGVmaW5lZDtcbiAgcmVhZG9ubHkgc291cmNlQ291bnQ6IG51bWJlcjtcblxuICBwcml2YXRlIHJlYWRvbmx5IGxlZ3M6IHJlYWRvbmx5IFJlYWRTb3VyY2VbXTtcbiAgcHJpdmF0ZSByZWFkb25seSBzb3VyY2VzOiByZWFkb25seSBUaW1lVHJhdmVsU291cmNlW107XG4gIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogVGltZVRyYXZlbE9wdGlvbnM8VE1ldGE+O1xuICBwcml2YXRlIHJlYWRvbmx5IF9tYXJrczogTWFya1tdO1xuICBwcml2YXRlIHN0ZXA6IG51bWJlcjtcbiAgLyoqIFRoZSBsYXN0IGZvbGQncyB3b3JraW5nIGNvcHksIHNvIGEgc3RlcCBmb3J3YXJkIGFwcGxpZXMgb25lIGJ1bmRsZSAoOS4yNS4wKS4gKi9cbiAgcHJpdmF0ZSBmb2xkTWVtbzogRm9sZE1lbW8gfCB1bmRlZmluZWQ7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc291cmNlczogcmVhZG9ubHkgVGltZVRyYXZlbFNvdXJjZVtdLFxuICAgIG9wdGlvbnM6IFRpbWVUcmF2ZWxPcHRpb25zPFRNZXRhPixcbiAgICBwYXRoPzogc3RyaW5nLFxuICAgIHBhcmVudD86IFRpbWVUcmF2ZWw8VE1ldGE+LFxuICAgIG1vdW50UnVudGltZVN0YWdlSWQ/OiBzdHJpbmcsXG4gICkge1xuICAgIHRoaXMuc291cmNlcyA9IHNvdXJjZXM7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICB0aGlzLnBhdGggPSBwYXRoO1xuICAgIHRoaXMucGFyZW50ID0gcGFyZW50O1xuICAgIHRoaXMubW91bnRSdW50aW1lU3RhZ2VJZCA9IG1vdW50UnVudGltZVN0YWdlSWQ7XG4gICAgdGhpcy5sZWdzID0gc291cmNlcy5tYXAoKHNvdXJjZSkgPT4gcmVhZFNvdXJjZShzb3VyY2UpKTtcbiAgICB0aGlzLnNvdXJjZUNvdW50ID0gc291cmNlcy5sZW5ndGg7XG5cbiAgICAvLyBUaGUgc2hpcHBlZCBzdHJhdGVneSBoYXMgbm8gdm9jYWJ1bGFyeSBvZiBpdHMgb3duIChgbWV0YWAgaXMgbmV2ZXIgc2V0KSxcbiAgICAvLyBzbyBpdCBzZXJ2ZXMgYW55IGBUTWV0YWAgYSBjYWxsZXIgYXNrZWQgZm9yLlxuICAgIGNvbnN0IHN0cmF0ZWd5ID0gb3B0aW9ucy5zdHJhdGVneSA/PyAoY29tbWl0U3RvcHNTdHJhdGVneSBhcyBUaW1lVHJhdmVsU3RyYXRlZ3k8VE1ldGE+KTtcbiAgICAvLyBPTkUgQ0FMTCBQRVIgU09VUkNFLCB3aXRoIHRoYXQgc291cmNlJ3Mgb3duIGxvZyBhbmQgdHJlZTogYSBzdHJhdGVneVxuICAgIC8vIG5ldmVyIGhhcyB0byBrbm93IGl0IGlzIHBhcnQgb2YgYSBjaGFpbiwgYW5kIGl0cyBpbmRpY2VzIHN0YXkgbG9jYWwgdG9cbiAgICAvLyB0aGUgbGVnIGl0IHdhcyBoYW5kZWQuXG4gICAgY29uc3QgcGVyU291cmNlID0gdGhpcy5sZWdzLm1hcCgobGVnLCBpKSA9PlxuICAgICAgc3RyYXRlZ3kuc3RvcHNGb3IobGVnLmxvZywgcmVhZFRyZWUoc291cmNlc1tpXS5leGVjdXRpb25UcmVlKSwgc291cmNlc1tpXS5zdWJmbG93UmVzdWx0cyksXG4gICAgKTtcbiAgICB0aGlzLnN0b3BzID0gT2JqZWN0LmZyZWV6ZShzb3VyY2VzLmxlbmd0aCA9PT0gMSA/IHBlclNvdXJjZVswXSA6IGNoYWluU3RvcHMocGVyU291cmNlKSk7XG4gICAgdGhpcy5fbWFya3MgPSBbLi4uKG9wdGlvbnMubWFya3MgPz8gW10pXTtcbiAgICB0aGlzLnN0ZXAgPSAwO1xuICB9XG5cbiAgLy8g4pSA4pSAIFBvc2l0aW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGF0KCk6IFN0b3A8VE1ldGE+IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5zdG9wc1t0aGlzLnN0ZXBdO1xuICB9XG5cbiAgcHJpdmF0ZSBtb3ZlVG8oc3RlcDogbnVtYmVyKTogTW92ZTxUTWV0YT4ge1xuICAgIGNvbnN0IGZyb20gPSB0aGlzLmF0KCk7XG4gICAgdGhpcy5zdGVwID0gc3RlcDtcbiAgICByZXR1cm4geyBtb3ZlZDogdHJ1ZSwgZnJvbSwgdG86IHRoaXMuc3RvcHNbc3RlcF0gfTtcbiAgfVxuXG4gIC8qKiBMYXcgMjogYSByZWZ1c2FsIG5ldmVyIHRvdWNoZXMgYHRoaXMuc3RlcGAuICovXG4gIHByaXZhdGUgcmVmdXNlKHJlYXNvbjogJ2NsYW1wZWQnIHwgJ21pc3MnIHwgJ2VtcHR5JywgbmVhcmVzdD86IFN0b3A8VE1ldGE+KTogTW92ZTxUTWV0YT4ge1xuICAgIGNvbnN0IGF0ID0gdGhpcy5hdCgpO1xuICAgIHJldHVybiBuZWFyZXN0ID8geyBtb3ZlZDogZmFsc2UsIHJlYXNvbiwgYXQsIG5lYXJlc3QgfSA6IHsgbW92ZWQ6IGZhbHNlLCByZWFzb24sIGF0IH07XG4gIH1cblxuICBmaXJzdCgpOiBNb3ZlPFRNZXRhPiB7XG4gICAgaWYgKHRoaXMuc3RvcHMubGVuZ3RoID09PSAwKSByZXR1cm4gdGhpcy5yZWZ1c2UoJ2VtcHR5Jyk7XG4gICAgaWYgKHRoaXMuc3RlcCA9PT0gMCkgcmV0dXJuIHRoaXMucmVmdXNlKCdjbGFtcGVkJyk7XG4gICAgcmV0dXJuIHRoaXMubW92ZVRvKDApO1xuICB9XG5cbiAgbGFzdCgpOiBNb3ZlPFRNZXRhPiB7XG4gICAgaWYgKHRoaXMuc3RvcHMubGVuZ3RoID09PSAwKSByZXR1cm4gdGhpcy5yZWZ1c2UoJ2VtcHR5Jyk7XG4gICAgY29uc3QgZW5kID0gdGhpcy5zdG9wcy5sZW5ndGggLSAxO1xuICAgIGlmICh0aGlzLnN0ZXAgPT09IGVuZCkgcmV0dXJuIHRoaXMucmVmdXNlKCdjbGFtcGVkJyk7XG4gICAgcmV0dXJuIHRoaXMubW92ZVRvKGVuZCk7XG4gIH1cblxuICBwcmV2KCk6IE1vdmU8VE1ldGE+IHtcbiAgICBpZiAodGhpcy5zdG9wcy5sZW5ndGggPT09IDApIHJldHVybiB0aGlzLnJlZnVzZSgnZW1wdHknKTtcbiAgICBpZiAodGhpcy5zdGVwID09PSAwKSByZXR1cm4gdGhpcy5yZWZ1c2UoJ2NsYW1wZWQnKTtcbiAgICByZXR1cm4gdGhpcy5tb3ZlVG8odGhpcy5zdGVwIC0gMSk7XG4gIH1cblxuICBuZXh0KCk6IE1vdmU8VE1ldGE+IHtcbiAgICBpZiAodGhpcy5zdG9wcy5sZW5ndGggPT09IDApIHJldHVybiB0aGlzLnJlZnVzZSgnZW1wdHknKTtcbiAgICBpZiAodGhpcy5zdGVwID49IHRoaXMuc3RvcHMubGVuZ3RoIC0gMSkgcmV0dXJuIHRoaXMucmVmdXNlKCdjbGFtcGVkJyk7XG4gICAgcmV0dXJuIHRoaXMubW92ZVRvKHRoaXMuc3RlcCArIDEpO1xuICB9XG5cbiAganVtcFRvKHRhcmdldDogbnVtYmVyIHwgc3RyaW5nKTogTW92ZTxUTWV0YT4ge1xuICAgIGlmICh0aGlzLnN0b3BzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHRoaXMucmVmdXNlKCdlbXB0eScpO1xuXG4gICAgaWYgKHR5cGVvZiB0YXJnZXQgPT09ICdudW1iZXInKSB7XG4gICAgICBjb25zdCBzdGVwID0gTWF0aC50cnVuYyh0YXJnZXQpO1xuICAgICAgaWYgKE51bWJlci5pc05hTihzdGVwKSkgcmV0dXJuIHRoaXMucmVmdXNlKCdtaXNzJyk7XG4gICAgICBpZiAoc3RlcCA8IDApIHJldHVybiB0aGlzLnJlZnVzZSgnY2xhbXBlZCcsIHRoaXMuc3RvcHNbMF0pO1xuICAgICAgaWYgKHN0ZXAgPiB0aGlzLnN0b3BzLmxlbmd0aCAtIDEpIHJldHVybiB0aGlzLnJlZnVzZSgnY2xhbXBlZCcsIHRoaXMuc3RvcHNbdGhpcy5zdG9wcy5sZW5ndGggLSAxXSk7XG4gICAgICBpZiAoc3RlcCA9PT0gdGhpcy5zdGVwKSByZXR1cm4gdGhpcy5yZWZ1c2UoJ2NsYW1wZWQnKTtcbiAgICAgIHJldHVybiB0aGlzLm1vdmVUbyhzdGVwKTtcbiAgICB9XG5cbiAgICAvLyBgJydgIGlzIG5vdCBhbiBhZGRyZXNzOiBpdCBpcyB3aGF0IHRoZSBib29rZW5kcyBhbmQgYW55IHByZS1zdGFnZVxuICAgIC8vIHJvb3QgY29tbWl0IGNhcnJ5LiBUaG9zZSBhcmUgcmVhY2hlZCBieSBzdGVwLCBuZXZlciBieSBpZC5cbiAgICBpZiAodGFyZ2V0ID09PSAnJykgcmV0dXJuIHRoaXMucmVmdXNlKCdtaXNzJyk7XG4gICAgY29uc3QgaGl0ID0gdGhpcy5zdG9wcy5maW5kKChzdG9wKSA9PiBzdG9wLnJ1bnRpbWVTdGFnZUlkID09PSB0YXJnZXQpO1xuICAgIGlmICghaGl0KSByZXR1cm4gdGhpcy5yZWZ1c2UoJ21pc3MnLCB0aGlzLm5lYXJlc3RUbyh0YXJnZXQpKTtcbiAgICBpZiAoaGl0LnN0ZXAgPT09IHRoaXMuc3RlcCkgcmV0dXJuIHRoaXMucmVmdXNlKCdjbGFtcGVkJyk7XG4gICAgcmV0dXJuIHRoaXMubW92ZVRvKGhpdC5zdGVwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgY2xvc2VzdCBuYW1hYmxlIHN0b3AgZm9yIGEgYHJ1bnRpbWVTdGFnZUlkYCB0aGF0IGlzIG5vdCBvbiB0aGlzIGF4aXM6XG4gICAqIHRoZSBsYXN0IHN0b3Agb2YgdGhlIHNhbWUgU1RBR0UgKGEgZGlmZmVyZW50IGl0ZXJhdGlvbiBvZiB0aGUgc2FtZSBub2RlKSxcbiAgICogZWxzZSB0aGUgbGFzdCBzdG9wIHdob3NlIGNvbW1pdCBwcmVjZWRlcyB0aGUgbWlzc2VkIGlkJ3MgZXhlY3V0aW9uIGluZGV4LlxuICAgKiBOYW1pbmcgYSBuZWlnaGJvdXIgaXMgYSBjb3VydGVzeSBmb3IgdGhlIFVJIOKAlCBpdCBuZXZlciBtb3ZlcyB0aGUgY3Vyc29yLlxuICAgKi9cbiAgcHJpdmF0ZSBuZWFyZXN0VG8ocnVudGltZVN0YWdlSWQ6IHN0cmluZyk6IFN0b3A8VE1ldGE+IHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIWlzRXhlY3V0aW9uS2V5KHJ1bnRpbWVTdGFnZUlkKSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBjb25zdCBzdGFnZVBhcnQgPSBzdGFnZUlkT2YocnVudGltZVN0YWdlSWQpO1xuICAgIGNvbnN0IHdhbnRlZCA9IGV4ZWN1dGlvbkluZGV4T2YocnVudGltZVN0YWdlSWQpO1xuXG4gICAgbGV0IHNhbWVTdGFnZTogU3RvcDxUTWV0YT4gfCB1bmRlZmluZWQ7XG4gICAgbGV0IGJ5SW5kZXg6IFN0b3A8VE1ldGE+IHwgdW5kZWZpbmVkO1xuICAgIGZvciAoY29uc3Qgc3RvcCBvZiB0aGlzLnN0b3BzKSB7XG4gICAgICBpZiAoIWlzRXhlY3V0aW9uS2V5KHN0b3AucnVudGltZVN0YWdlSWQpKSBjb250aW51ZTtcbiAgICAgIGlmIChzdGFnZUlkT2Yoc3RvcC5ydW50aW1lU3RhZ2VJZCkgPT09IHN0YWdlUGFydCkgc2FtZVN0YWdlID0gc3RvcDtcbiAgICAgIGlmICghTnVtYmVyLmlzTmFOKHdhbnRlZCkpIHtcbiAgICAgICAgY29uc3QgaWR4ID0gZXhlY3V0aW9uSW5kZXhPZihzdG9wLnJ1bnRpbWVTdGFnZUlkKTtcbiAgICAgICAgaWYgKCFOdW1iZXIuaXNOYU4oaWR4KSAmJiBpZHggPD0gd2FudGVkKSBieUluZGV4ID0gc3RvcDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNhbWVTdGFnZSA/PyBieUluZGV4O1xuICB9XG5cbiAgLy8g4pSA4pSAIFJlYWRpbmcg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgc3RhdGVBdChzdG9wPzogU3RvcDxUTWV0YT4pOiBGb2xkZWRTdGF0ZSB7XG4gICAgY29uc3QgdGFyZ2V0ID0gc3RvcCA/PyB0aGlzLmF0KCk7XG4gICAgY29uc3QgbGVnID0gdGFyZ2V0Py5zb3VyY2VJZHggPz8gMDtcbiAgICBjb25zdCBmb2xkID0gZm9sZExlZ3NGcm9tKHRoaXMubGVncywgbGVnLCB0YXJnZXQgPyB0YXJnZXQubGFzdENvbW1pdElkeCA6IC0xLCB0aGlzLmZvbGRNZW1vKTtcbiAgICB0aGlzLmZvbGRNZW1vID0gZm9sZC5tZW1vO1xuICAgIGNvbnN0IGZvbGRlZCA9IGZvbGQuZm9sZGVkO1xuICAgIC8vIFdoaWNoIGxlZyB0aGUgaW5kZXggYmVsb25ncyB0bywgYnV0IG9ubHkgd2hlbiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIOKAlFxuICAgIC8vIGEgc2luZ2xlLXNvdXJjZSBmb2xkIGtlZXBzIHRoZSA5LjE3LjAgc2hhcGUgZXhhY3RseS5cbiAgICByZXR1cm4gdGhpcy5sZWdzLmxlbmd0aCA+IDEgPyB7IC4uLmZvbGRlZCwgc291cmNlSWR4OiBsZWcgfSA6IGZvbGRlZDtcbiAgfVxuXG4gIGNoYW5nZWRTaW5jZShmcm9tPzogU3RvcDxUTWV0YT4pOiByZWFkb25seSBzdHJpbmdbXSB7XG4gICAgY29uc3QgdG8gPSB0aGlzLmF0KCk7XG4gICAgaWYgKCF0bykgcmV0dXJuIE9iamVjdC5mcmVlemUoW10pO1xuICAgIGNvbnN0IHN0YXJ0ID0gZnJvbSA/PyB0aGlzLnN0b3BzW3RoaXMuc3RlcCAtIDFdO1xuICAgIC8vIE5vIGVhcmxpZXIgc3RvcCAod2UgYXJlIGF0IGAnc3RhcnQnYCkg4oeSIGV2ZXJ5dGhpbmcgdXAgdG8gaGVyZTogbm90aGluZ1xuICAgIC8vIG9uIGEgcnVuIGN1cnNvciwgYW5kIHRoZSBzdWJmbG93J3MgYGlucHV0TWFwcGVyYCBzZWVkIG9uIGEgZHJpbGxlZCBvbmVcbiAgICAvLyAodGhlIHN0YXJ0IGJvb2tlbmQgY292ZXJzIHRoZSBzZWVkIHRoYXQgcHJlY2VkZXMgc3RhZ2Ugb25lIOKAlCBgY29tbWl0U3RvcHNgKS5cbiAgICBjb25zdCB0b0xlZyA9IHRvLnNvdXJjZUlkeCA/PyAwO1xuICAgIGNvbnN0IGZyb21MZWcgPSBzdGFydCA/IHN0YXJ0LnNvdXJjZUlkeCA/PyAwIDogdG9MZWc7XG4gICAgY29uc3QgYWZ0ZXJJZHggPSBzdGFydCA/IHN0YXJ0Lmxhc3RDb21taXRJZHggOiAtMTtcbiAgICBjb25zdCBrZXlzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgLy8gQSByYW5nZSB0aGF0IGNyb3NzZXMgYSBjaGFpbiBzZWFtIGlzIHdhbGtlZCBsZWcgYnkgbGVnOiB0aGUgdGFpbCBvZiB0aGVcbiAgICAvLyBsZWcgaXQgc3RhcnRlZCBpbiwgZXZlcnkgbGVnIGluIGJldHdlZW4gd2hvbGUsIHRoZW4gdGhlIGhlYWQgb2YgdGhlIGxlZ1xuICAgIC8vIGl0IGVuZHMgaW4uIEJhY2t3YXJkcyByYW5nZXMgd2FsayBub3RoaW5nIGFuZCBnaXZlIGBbXWAsIGFzIGJlZm9yZS5cbiAgICBmb3IgKGxldCBsZWcgPSBmcm9tTGVnOyBsZWcgPD0gdG9MZWcgJiYgbGVnIDwgdGhpcy5sZWdzLmxlbmd0aDsgbGVnKyspIHtcbiAgICAgIGNvbnN0IGxvZyA9IHRoaXMubGVnc1tsZWddLmxvZztcbiAgICAgIGNvbnN0IGxvID0gbGVnID09PSBmcm9tTGVnID8gYWZ0ZXJJZHggKyAxIDogMDtcbiAgICAgIGNvbnN0IGhpID0gbGVnID09PSB0b0xlZyA/IHRvLmxhc3RDb21taXRJZHggOiBsb2cubGVuZ3RoIC0gMTtcbiAgICAgIGZvciAobGV0IGkgPSBsbzsgaSA8PSBoaTsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGJ1bmRsZSA9IGxvZ1tpXTtcbiAgICAgICAgaWYgKCFidW5kbGUpIGNvbnRpbnVlO1xuICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGJ1bmRsZS50cmFjZSkga2V5cy5hZGQoZW50cnkucGF0aCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBPYmplY3QuZnJlZXplKFsuLi5rZXlzXS5zb3J0KCkpO1xuICB9XG5cbiAgLy8g4pSA4pSAIE1hcmtzIChsYXcgNDogYmVzaWRlIHRoZSBsb2csIG5ldmVyIGluIGl0KSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBtYXJrKG5hbWU6IHN0cmluZywgc3RvcD86IFN0b3A8VE1ldGE+KTogTWFyayB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgdGFyZ2V0ID0gc3RvcCA/PyB0aGlzLmF0KCk7XG4gICAgaWYgKCF0YXJnZXQpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgY29uc3QgZW50cnk6IE1hcmsgPSBPYmplY3QuZnJlZXplKHsgbmFtZSwgcnVudGltZVN0YWdlSWQ6IHRhcmdldC5ydW50aW1lU3RhZ2VJZCwgc3RlcDogdGFyZ2V0LnN0ZXAgfSk7XG4gICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLl9tYXJrcy5maW5kSW5kZXgoKG0pID0+IG0ubmFtZSA9PT0gbmFtZSk7XG4gICAgaWYgKGV4aXN0aW5nID49IDApIHRoaXMuX21hcmtzW2V4aXN0aW5nXSA9IGVudHJ5O1xuICAgIGVsc2UgdGhpcy5fbWFya3MucHVzaChlbnRyeSk7XG4gICAgcmV0dXJuIGVudHJ5O1xuICB9XG5cbiAgbWFya3MoKTogcmVhZG9ubHkgTWFya1tdIHtcbiAgICByZXR1cm4gT2JqZWN0LmZyZWV6ZShbLi4udGhpcy5fbWFya3NdKTtcbiAgfVxuXG4gIGp1bXBUb01hcmsobmFtZTogc3RyaW5nKTogTW92ZTxUTWV0YT4ge1xuICAgIGlmICh0aGlzLnN0b3BzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHRoaXMucmVmdXNlKCdlbXB0eScpO1xuICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5fbWFya3MuZmluZCgobSkgPT4gbS5uYW1lID09PSBuYW1lKTtcbiAgICBpZiAoIWVudHJ5KSByZXR1cm4gdGhpcy5yZWZ1c2UoJ21pc3MnKTtcbiAgICAvLyBSZXNvbHZlIGJ5IHJ1bnRpbWVTdGFnZUlkIGZpcnN0IOKAlCB0aGUgYWRkcmVzcyB0aGF0IHN1cnZpdmVzIGEgY2hhbmdlIG9mXG4gICAgLy8gc3RyYXRlZ3kg4oCUIGFuZCBmYWxsIGJhY2sgdG8gdGhlIHJlbWVtYmVyZWQgc3RlcCBvbmx5IGZvciB0aGUgYm9va2VuZHMsXG4gICAgLy8gd2hpY2ggaGF2ZSBubyBzdGFnZSBpZCBvZiB0aGVpciBvd24uXG4gICAgY29uc3QgYnlJZCA9IGVudHJ5LnJ1bnRpbWVTdGFnZUlkXG4gICAgICA/IHRoaXMuc3RvcHMuZmluZCgoc3RvcCkgPT4gc3RvcC5ydW50aW1lU3RhZ2VJZCA9PT0gZW50cnkucnVudGltZVN0YWdlSWQpXG4gICAgICA6IHRoaXMuc3RvcHNbZW50cnkuc3RlcF07XG4gICAgaWYgKCFieUlkKSByZXR1cm4gdGhpcy5yZWZ1c2UoJ21pc3MnLCB0aGlzLm5lYXJlc3RUbyhlbnRyeS5ydW50aW1lU3RhZ2VJZCkpO1xuICAgIGlmIChieUlkLnN0ZXAgPT09IHRoaXMuc3RlcCkgcmV0dXJuIHRoaXMucmVmdXNlKCdjbGFtcGVkJyk7XG4gICAgcmV0dXJuIHRoaXMubW92ZVRvKGJ5SWQuc3RlcCk7XG4gIH1cblxuICAvLyDilIDilIAgRHJpbGxpbmcgKGxhdyAxOiBhIHNlcGFyYXRlIGN1cnNvciwgbm90IGEgc2Vjb25kIHBvc2l0aW9uKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBkcmlsbChtb3VudFJ1bnRpbWVTdGFnZUlkOiBzdHJpbmcpOiBUaW1lVHJhdmVsPFRNZXRhPiB8IHVuZGVmaW5lZCB7XG4gICAgLy8gT24gYSBjaGFpbiwgdGhlIG1vdW50IGlzIGxvb2tlZCBmb3IgaW4gZXZlcnkgbGVnIOKAlCBhIHN1YmZsb3cgdGhhdCByYW5cbiAgICAvLyBiZWZvcmUgdGhlIHBhdXNlIGlzIGluIHRoZSBmaXJzdCBzbmFwc2hvdCdzIHJlc3VsdHMsIG9uZSB0aGF0IHJhbiBhZnRlclxuICAgIC8vIGlzIGluIHRoZSBzZWNvbmQncy4gSWRzIGFyZSB1bmlxdWUgYWNyb3NzIGEgc291bmQgY2hhaW4gKGNoYWluLnRzXG4gICAgLy8gcmVmdXNlcyBvbmUgd2hlcmUgdGhleSBhcmUgbm90KSwgc28gdGhlIGZpcnN0IGhpdCBpcyB0aGUgb25seSBoaXQuXG4gICAgbGV0IHJlc3VsdHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkO1xuICAgIGxldCByZXN1bHQ6IFN1YmZsb3dSZXN1bHRTaGFwZSB8IHVuZGVmaW5lZDtcbiAgICBmb3IgKGNvbnN0IHNvdXJjZSBvZiB0aGlzLnNvdXJjZXMpIHtcbiAgICAgIC8vIEEgc3RvcmVkIHJlY29yZGluZydzIHJlc3VsdHMgYXJlIHBhcnNlZCBKU09OOiByZWFkIHRoZW0gYXMgYSBtYXAgb25seVxuICAgICAgLy8gd2hlbiB0aGV5IGFyZSBvbmUsIGFuZCBhcyBcIm5vIHN1YmZsb3dzXCIgb3RoZXJ3aXNlLlxuICAgICAgaWYgKCFpc1BsYWluaXNoKHNvdXJjZS5zdWJmbG93UmVzdWx0cykpIGNvbnRpbnVlO1xuICAgICAgY29uc3QgaGl0ID0gc291cmNlLnN1YmZsb3dSZXN1bHRzW21vdW50UnVudGltZVN0YWdlSWRdIGFzIFN1YmZsb3dSZXN1bHRTaGFwZSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChoaXQpIHtcbiAgICAgICAgcmVzdWx0cyA9IHNvdXJjZS5zdWJmbG93UmVzdWx0cztcbiAgICAgICAgcmVzdWx0ID0gaGl0O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgdHJlZSA9IHJlc3VsdD8udHJlZUNvbnRleHQ7XG4gICAgaWYgKCFyZXN1bHRzIHx8ICFyZXN1bHQgfHwgIXRyZWUgfHwgIUFycmF5LmlzQXJyYXkodHJlZS5oaXN0b3J5KSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIC8vIGBwYXRoYCBpcyB0aGUgc3ViZmxvdyBQQVRIIOKAlCB0aGUgc2FtZSBzdHJpbmcgZm9yIGV2ZXJ5IGl0ZXJhdGlvbiBvZiBhXG4gICAgLy8gbW91bnQgaW5zaWRlIGEgbG9vcC4gYG1vdW50UnVudGltZVN0YWdlSWRgIGlzIHRoZSBpdGVyYXRpb24gYWN0dWFsbHlcbiAgICAvLyBvcGVuZWQsIHNvIGEgVUkgY2FuIGxhYmVsIGFuZCBrZXkgdGhyZWUgZHJpbGwgcGFuZWxzIG92ZXIgYHNmeCMyYCxcbiAgICAvLyBgc2Z4IzhgLCBgc2Z4IzE0YCBhcGFydCBpbnN0ZWFkIG9mIGNhbGxpbmcgYWxsIHRocmVlICdzZngnLlxuICAgIGNvbnN0IGNoaWxkUGF0aCA9IHJlc3VsdC5zdWJmbG93SWQgPz8gbW91bnRSdW50aW1lU3RhZ2VJZDtcbiAgICBjb25zdCBjaGlsZDogVGltZVRyYXZlbFNvdXJjZSA9IHtcbiAgICAgIC8vIFJvd3MgYXJlIG5hcnJvd2VkIHBlciBidW5kbGUgd2hlbiB0aGUgY2hpbGQgcmVhZHMgdGhlbSDigJQgYSBzdG9yZWRcbiAgICAgIC8vIHJlY29yZGluZydzIGlubmVyIGhpc3RvcnkgbmVlZHMgbm8gY2FzdCBlaXRoZXIuXG4gICAgICBjb21taXRMb2c6IHRyZWUuaGlzdG9yeSxcbiAgICAgIGluaXRpYWxTdGF0ZTogdHJlZS5pbml0aWFsU3RhdGUsXG4gICAgICBleGVjdXRpb25UcmVlOiB0cmVlLnN0YWdlQ29udGV4dHMsXG4gICAgICAvLyBOZXN0ZWQgc3ViZmxvdyByZXN1bHRzIGFyZSBtZXJnZWQgVVAgaW50byBvbmUgZmxhdCwgZHVhbC1rZXllZCBtYXAsIHNvXG4gICAgICAvLyB0aGUgY2hpbGQgY2FuIGRyaWxsIGZ1cnRoZXIgdGhyb3VnaCB0aGUgc2FtZSBtYXAuXG4gICAgICBzdWJmbG93UmVzdWx0czogcmVzdWx0cyxcbiAgICB9O1xuICAgIHJldHVybiBuZXcgQ3Vyc29yPFRNZXRhPihbY2hpbGRdLCB7IHN0cmF0ZWd5OiB0aGlzLm9wdGlvbnMuc3RyYXRlZ3kgfSwgY2hpbGRQYXRoLCB0aGlzLCBtb3VudFJ1bnRpbWVTdGFnZUlkKTtcbiAgfVxufVxuXG4vKipcbiAqIFJlLXN0ZXAgcGVyLXNvdXJjZSBzdG9wcyBpbnRvIE9ORSBheGlzLlxuICpcbiAqIFRoZSBJTlRFUklPUiBib29rZW5kcyBnbzogYSBgJ3N0YXJ0J2Agb24gYW55IGxlZyBidXQgdGhlIGZpcnN0LCBhbmQgYW5cbiAqIGAnZW5kJ2Agb24gYW55IGxlZyBidXQgdGhlIGxhc3QsIGFyZSBib29rZW5kcyBvZiBhIGxlZyBhbmQgbm90IG9mIHRoZSBydW4g4oCUXG4gKiBrZWVwaW5nIHRoZW0gd291bGQgcHV0IFwidGhlIHJ1biBpcyBvdmVyXCIgaW4gdGhlIG1pZGRsZSBvZiB0aGUgYXhpcy4gVGhlXG4gKiBjb21taXRzIHRoZXkgY292ZXJlZCBhcmUgbm90IG9ycGhhbmVkOiBhIGZvbGQgYWx3YXlzIHJlcGxheXMgaXRzIGxlZyBmcm9tXG4gKiB0aGF0IGxlZydzIG93biBiYXNlLCBhbmQgYGNoYW5nZWRTaW5jZWAgd2Fsa3MgYSBzZWFtLWNyb3NzaW5nIHJhbmdlIGxlZyBieVxuICogbGVnIChpbmNsdWRpbmcgdGhlIGhlYWQgb2YgdGhlIGxlZyBpdCBlbmRzIGluKS4gVGhlIHN0b3BzJyBgY29tbWl0SWR4YCAvXG4gKiBgbGFzdENvbW1pdElkeGAgcmFuZ2VzIFBBUlRJVElPTiBFQUNIIExFRywgbmV2ZXIgc3BhbiB0aGUgc2VhbTogYSBzdG9wJ3NcbiAqIHJhbmdlIGVuZHMgYXQgaXRzIG93biBsZWcncyBsYXN0IGluZGV4LCBhbmQgdGhlIG5leHQgbGVnJ3MgZmlyc3Qgc3RvcCBvcGVuc1xuICogYXQgdGhhdCBsZWcncyAwLlxuICovXG5mdW5jdGlvbiBjaGFpblN0b3BzPFRNZXRhPihwZXJTb3VyY2U6IHJlYWRvbmx5IFN0b3A8VE1ldGE+W11bXSk6IFN0b3A8VE1ldGE+W10ge1xuICAvLyBcIkludGVyaW9yXCIgaXMgbWVhc3VyZWQgYWdhaW5zdCB0aGUgbGVncyB0aGF0IGFjdHVhbGx5IENPTlRSSUJVVEUgc3RvcHM6IGFcbiAgLy8gbGVnIHdob3NlIGxvZyB3YXMgZW1wdHkgaGFzIG5vIGJvb2tlbmRzIHRvIGRyb3AgYW5kIG11c3Qgbm90IG1ha2UgaXRzXG4gIC8vIG5laWdoYm91cidzIGAnc3RhcnQnYCBvciBgJ2VuZCdgIGludGVyaW9yIOKAlCB0aGUgY2hhaW5lZCBheGlzIHN0aWxsIG9wZW5zXG4gIC8vIHdpdGggdGhlIGZpcnN0IHN0b3AgdGhhdCBleGlzdHMgYW5kIGNsb3NlcyB3aXRoIHRoZSBsYXN0LlxuICBjb25zdCBjb250cmlidXRpbmcgPSBwZXJTb3VyY2UubWFwKChzdG9wcykgPT4gc3RvcHMubGVuZ3RoID4gMCk7XG4gIGNvbnN0IGZpcnN0TGVnID0gY29udHJpYnV0aW5nLmluZGV4T2YodHJ1ZSk7XG4gIGNvbnN0IGxhc3RMZWcgPSBjb250cmlidXRpbmcubGFzdEluZGV4T2YodHJ1ZSk7XG4gIGNvbnN0IG91dDogU3RvcDxUTWV0YT5bXSA9IFtdO1xuICBmb3IgKGNvbnN0IFtzb3VyY2VJZHgsIHN0b3BzXSBvZiBwZXJTb3VyY2UuZW50cmllcygpKSB7XG4gICAgZm9yIChjb25zdCBzdG9wIG9mIHN0b3BzKSB7XG4gICAgICBpZiAoc291cmNlSWR4ID4gZmlyc3RMZWcgJiYgc3RvcC5raW5kID09PSAnc3RhcnQnKSBjb250aW51ZTtcbiAgICAgIGlmIChzb3VyY2VJZHggPCBsYXN0TGVnICYmIHN0b3Aua2luZCA9PT0gJ2VuZCcpIGNvbnRpbnVlO1xuICAgICAgb3V0LnB1c2goeyAuLi5zdG9wLCBzdGVwOiBvdXQubGVuZ3RoLCBzb3VyY2VJZHggfSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKlxuICogT3BlbiBhIHJlYWRlcidzIGN1cnNvciBvdmVyIGEgZmluaXNoZWQgcnVuLlxuICpcbiAqIE5vdGhpbmcgaGVyZSBleGVjdXRlcyBhbnl0aGluZzogYHNuYXBzaG90YCBpcyBhIHJlY29yZCBvZiBhIHJ1biB0aGF0IGFscmVhZHlcbiAqIGhhcHBlbmVkLCBhbmQgZXZlcnkgcXVlc3Rpb24gaXMgYW5zd2VyZWQgYnkgcmVhZGluZyBpdC4gQSBzdG9yZWQgSlNPTlxuICogc25hcHNob3Qgd29ya3MgZXhhY3RseSBsaWtlIGEgbGl2ZSBvbmUg4oCUIHNpbmNlIDkuMTguMCBpdHMgYGNvbW1pdExvZ2AgbWF5IGJlXG4gKiBhbiB1bnZhbGlkYXRlZCBgdW5rbm93bltdYCwgbmFycm93ZWQgcGVyIGJ1bmRsZSB3aGVyZSB0aGUgZm9sZCByZWFkcyBpdCwgc29cbiAqIGEgcmVwbGF5ZWQgcmVjb3JkaW5nIG5lZWRzIG5vIGNhc3QuXG4gKlxuICogQHBhcmFtIHNuYXBzaG90IGBleGVjdXRvci5nZXRTbmFwc2hvdCgpYCwgb3IgYW55IG9iamVjdCB3aXRoIHRoZSBzYW1lXG4gKiAgIHNoYXBlIOKAlCBpbmNsdWRpbmcgb25lIHJvdW5kLXRyaXBwZWQgdGhyb3VnaCBKU09OLCBvciBhIHN1YmZsb3cgc3VidHJlZVxuICogICAoYGdldFN1YnRyZWVTbmFwc2hvdCgpYCwgd2hvc2UgbG9nIGlzIHNwZWxsZWQgYGhpc3RvcnlgKS4gQW4gQVJSQVkgb2YgdGhlbVxuICogICBpcyBhIENIQUlOOiBhIHBhdXNlIGFuZCBpdHMgcmVzdW1lIHJlYWQgYXMgb25lIGF4aXMgKHNlZSBiZWxvdykuXG4gKiBAcGFyYW0gb3B0aW9ucyBgc3RyYXRlZ3lgIGNob29zZXMgaG93IHN0b3BzIGFyZSBkZXJpdmVkIChkZWZhdWx0OlxuICogICBgY29tbWl0U3RvcHNgLCBvbmUgc3RvcCBwZXIgZXhlY3V0ZWQgc3RhZ2UpOyBgbWFya3NgIHNlZWRzIHRoZSBjdXJzb3Igd2l0aFxuICogICBib29rbWFya3MsIGUuZy4gcmVzdG9yZWQgZnJvbSBhIHNhdmVkIHJlYWRpbmcgc2Vzc2lvbi5cbiAqXG4gKiBAdGhyb3dzIHdoZW4gYSBjaGFpbiBpcyBub3QgaW4gcnVuIG9yZGVyLCBvciBpdHMgbGVncyBhcmUgbm90IGZyb20gb25lXG4gKiAgIGxpbmVhZ2Ug4oCUIHRocmVlIGNoZWNrcywgZWFjaCB3aXRoIGl0cyBvd24gcmVhc29uIChzZWUgYGNoYWluLnRzYCk6XG4gKiAgIG5vIGBydW50aW1lU3RhZ2VJZGAgbWF5IGFwcGVhciBpbiB0d28gbGVnczsgZWFjaCBsZWcncyBmaXJzdCBleGVjdXRpb25cbiAqICAgaW5kZXggbXVzdCBiZSBwYXN0IHRoZSBwcmV2aW91cyBsZWcncyBsYXN0ICh0aGUgZW5naW5lIG5ldmVyIHJlc2V0cyB0aGVcbiAqICAgY291bnRlciBhY3Jvc3MgYSByZXN1bWUpOyBhbmQgZWFjaCBsZWcncyBgaW5pdGlhbFN0YXRlYCBtdXN0IGRlZXAtZXF1YWxcbiAqICAgdGhlIHN0YXRlIHRoZSBsZWdzIGJlZm9yZSBpdCBmb2xkIHRvIOKAlCBvbiBhIHJlc3VtZSB0aGF0IGJhc2UgSVMgdGhlIHN0YXRlXG4gKiAgIGF0IHRoZSBwYXVzZSwgc28gYSBmb3JlaWduIGxlZyB3aG9zZSBpbmRpY2VzIG1lcmVseSBoYXBwZW4gdG8gYmUgaGlnaGVyXG4gKiAgIGlzIHJlZnVzZWQgdG9vLiBUaGUgdGhpcmQgY2hlY2sgcnVucyBvbmx5IHdoZXJlIHRoZSByZWNvcmQgYWxsb3dzIGl0OiB0aGVcbiAqICAgbGF0ZXIgbGVnIG11c3QgY2FycnkgYW4gYGluaXRpYWxTdGF0ZWAgYW5kIHRoZSBlYXJsaWVyIGxlZ3MgbXVzdCBmb2xkIGZyb21cbiAqICAgYSByZWFsIGJhc2Ugd2l0aCBubyB1bnJlYWRhYmxlIHJvd3M7IG90aGVyd2lzZSAoYW4gb2xkZXIgcmVjb3JkaW5nIHdpdGhcbiAqICAgbm8gYmFzZSkgdGhlIGNoYWluIHJlc3RzIG9uIHRoZSB0d28gaW5kZXggY2hlY2tzIGFsb25lLCBhbmQgdGhlIGZvbGQnc1xuICogICBgYmFzaXNgIHNheXMgd2hhdCBpdCBzdG9vZCBvbi5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgdHQgPSB0aW1lVHJhdmVsKGV4ZWN1dG9yLmdldFNuYXBzaG90KCkpO1xuICogdHQuanVtcFRvKCdzY29yZS1yaXNrIzQnKTtcbiAqIGNvbnNvbGUubG9nKHR0LmNoYW5nZWRTaW5jZSgpKTsgICAgICAgIC8vIFsncmlza1Njb3JlJywgJ3RpZXInXVxuICogY29uc29sZS5sb2codHQuc3RhdGVBdCgpLnN0YXRlKTsgICAgICAgLy8gc3RhdGUgYXMgdGhhdCBzdGFnZSBsZWZ0IGl0XG4gKiB0dC5tYXJrKCd0aGUgYmFkIG9uZScpO1xuICogY29uc3QgaW5uZXIgPSB0dC5kcmlsbCgnc2YtcGF5bWVudCM3Jyk7IC8vIGEgc2VwYXJhdGUgY3Vyc29yLCBpdHMgb3duIGxvZ1xuICpcbiAqIC8vIEEgcGF1c2UgYW5kIGl0cyByZXN1bWUsIHJlYWQgYXMgT05FIGF4aXM6XG4gKiBjb25zdCBjaGFpbmVkID0gdGltZVRyYXZlbChbcGF1c2VkU25hcHNob3QsIHJlc3VtZWRTbmFwc2hvdF0pO1xuICogY2hhaW5lZC5sYXN0KCk7ICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBydW4ncyByZWFsIGVuZFxuICogY2hhaW5lZC5hdCgpIS5zb3VyY2VJZHg7ICAgICAgICAgICAgICAgIC8vIDEg4oCUIHdoaWNoIGxlZyB0aGUgaW5kaWNlcyBhcmUgaW5cbiAqIGNoYWluZWQuanVtcFRvKCdhcHByb3ZlIzMnKTsgICAgICAgICAgICAvLyBmaW5kcyBpdCBpbiBlaXRoZXIgbGVnXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRpbWVUcmF2ZWw8VE1ldGEgPSB1bmtub3duPihcbiAgc25hcHNob3Q6IFRpbWVUcmF2ZWxTb3VyY2UgfCByZWFkb25seSBUaW1lVHJhdmVsU291cmNlW10sXG4gIG9wdGlvbnM6IFRpbWVUcmF2ZWxPcHRpb25zPFRNZXRhPiA9IHt9LFxuKTogVGltZVRyYXZlbDxUTWV0YT4ge1xuICBjb25zdCBzb3VyY2VzID0gQXJyYXkuaXNBcnJheShzbmFwc2hvdCkgPyAoc25hcHNob3QgYXMgcmVhZG9ubHkgVGltZVRyYXZlbFNvdXJjZVtdKSA6IFtzbmFwc2hvdCBhcyBUaW1lVHJhdmVsU291cmNlXTtcbiAgLy8gQSBvbmUtZWxlbWVudCBhcnJheSBpcyBub3QgYSBjaGFpbjogaXQgaXMgdGhlIHBsYWluIGN1cnNvciwgYW5kIHNraXBzIHRoZVxuICAvLyBsaW5lYWdlIGNoZWNrcyBhIHNpbmdsZSBzb3VyY2UgY2Fubm90IGZhaWwuXG4gIGlmIChzb3VyY2VzLmxlbmd0aCAhPT0gMSkge1xuICAgIGNvbnN0IHJlZnVzYWwgPSByZWZ1c2VDaGFpbihzb3VyY2VzLm1hcCgoc291cmNlKSA9PiByZWFkU291cmNlKHNvdXJjZSkpKTtcbiAgICBpZiAocmVmdXNhbCkgdGhyb3cgbmV3IEVycm9yKHJlZnVzYWwpO1xuICB9XG4gIHJldHVybiBuZXcgQ3Vyc29yPFRNZXRhPihzb3VyY2VzLCBvcHRpb25zKTtcbn1cbiJdfQ==