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,950 +0,0 @@
1
- "use strict";
2
- /**
3
- * TransactionBuffer — Per-stage STAGING buffer for state mutations
4
- *
5
- * What it IS: a staging buffer with read-your-writes and net-change commits.
6
- * - Changes are staged here during stage execution and flushed to
7
- * SharedMemory in ONE batch per stage (`commit()`) — other stages and
8
- * parallel siblings never observe a stage's half-finished writes.
9
- * - Read-after-write consistency within a stage — a stage sees its own
10
- * staged writes immediately.
11
- * - `commit()` records the stage's NET change (see {@link commit}), plus an
12
- * operation trace for deterministic replay.
13
- *
14
- * What it is NOT: a rollback mechanism. Despite the name, there is no
15
- * abort/rollback path — when a stage THROWS, the engine still commits
16
- * everything staged so far before re-throwing (commit-on-error in
17
- * `FlowchartTraverser`). That is deliberate: the audit trail must record
18
- * what the failing stage changed. Do not rely on "stage failed → its
19
- * writes vanished".
20
- *
21
- * The patch trees hold REFERENCES until commit (9.23.0). A `set` stores the
22
- * caller's own value in `overwritePatch` exactly as it always did in
23
- * `workingCopy`; the copy the record needs is taken ONCE per surviving path
24
- * when the payload leaves the buffer (`toChangeOnlyPayload` /
25
- * `toDeltaPayload` — every value they emit passes through `structuredClone`
26
- * there). The law "the record never aliases a caller's object" is kept at
27
- * the commit boundary instead of at every write, which is what makes N
28
- * writes to one path O(N) instead of O(N × size). Consequence, by design: a
29
- * caller who mutates its own object AFTER the write and BEFORE the stage
30
- * ends commits the value as the stage read it back — the record agrees with
31
- * the stage (CLAUDE.md landmine 3's first bite, closed). The one place the
32
- * engine itself edits THROUGH a staged value — a later nested op under a
33
- * `set` path — detaches that value first ({@link detachHeldAncestors}), so
34
- * `workingCopy` and `overwritePatch` never share a container the engine
35
- * mutates on one side only.
36
- *
37
- * COPY-ON-WRITE (9.29.0 — docs/design/2026-10-copy-on-write-commit.md). The
38
- * buffer no longer clones the committed state it starts from. `baseSnapshot`
39
- * IS the committed generation the stage first touched (held by reference —
40
- * committed state is immutable-after-swap), and `workingCopy` starts as a
41
- * copy of its ROOT only: each write copies the containers on its own path
42
- * ({@link ownSpine}), and the first READ after the stage's first write of a
43
- * container still shared with committed state takes a private deep copy of
44
- * it ({@link privatise}) — what the whole-state clone used to give every
45
- * read, so an in-place edit of a read value stays private exactly as it did.
46
- * A read the working copy cannot answer is served from live state by the
47
- * caller, as before; the buffer then replaces that path of its diff base
48
- * with a private copy ({@link detachBase}), as the clone had it.
49
- *
50
- * THE ADMITTED RECORD (9.30.0 — docs/design/2026-10-admitted-record.md). A
51
- * commit is admitted only if its bundle folds back to the stage's
52
- * read-your-writes view at every path the stage touched (and at every
53
- * container its writes created on the way there, below the stage's address).
54
- * Both encoders commit the value the stage read: a compact row — a `merge`
55
- * delta, an `append` tail — is kept where it provably folds back; a family of
56
- * rows that does not is recorded as `set` rows of the values the stage read
57
- * ({@link admit}). Before 9.30.0 the one accumulated merge delta per path was
58
- * replayed at every `merge` row of that path, which lied across a hard write
59
- * (`$update(k,{x}); k = {y}; $update(k,{z})` committed `{y, x, z}` for a
60
- * read-back of `{y, z}`), an `[]` clear, a kind change or an array union
61
- * deduplicated by reference. Verified when the stage staged a `merge` or a
62
- * nested op; a stage that staged only `set` / `delete` of keys directly under
63
- * its address is coherent by construction — both trees receive the same
64
- * write — and is admitted without the fold.
65
- */
66
- Object.defineProperty(exports, "__esModule", { value: true });
67
- exports.TransactionBuffer = void 0;
68
- const admission_js_1 = require("./admission.js");
69
- const deltaEncoding_js_1 = require("./deltaEncoding.js");
70
- const keyPaths_js_1 = require("./keyPaths.js");
71
- const pathOps_js_1 = require("./pathOps.js");
72
- const utils_js_1 = require("./utils.js");
73
- class TransactionBuffer {
74
- /**
75
- * The net-change diff base: the committed generation the stage first
76
- * touched, by reference — except where {@link detachBase} replaced a path
77
- * of it with a private copy (its root and the containers on the way are
78
- * then copies too, owned by {@link baseOwned}).
79
- */
80
- baseSnapshot;
81
- workingCopy;
82
- overwritePatch = {};
83
- updatePatch = {};
84
- opTrace = [];
85
- redactedPaths = new Set();
86
- /**
87
- * Paths whose `overwritePatch` value is the caller's own object (9.23.0):
88
- * a `set` of a container stores the reference, and this is the ledger of
89
- * which ones are still shared with the caller (and with `workingCopy`).
90
- * Consulted only by the engine's nested ops — see
91
- * {@link detachHeldAncestors}; the commit payload clones every surviving
92
- * value anyway and never asks. Cleared with the rest at `commit()`.
93
- */
94
- heldRefs = new Set();
95
- /** Commit-value encoding policy (#13c-B). `'full'` = historical bytes. */
96
- commitValues;
97
- /** Per-write read-provenance source (#P1). When set (the
98
- * `writeProvenance: 'reads-prefix'` dial), every staged op snapshots the
99
- * keys tracked-read so far — the temporal-prefix attribution consumed by
100
- * causal slicing. Undefined (default) = zero cost, byte-identical ops. */
101
- readKeysProvider;
102
- /**
103
- * The containers in `workingCopy` this buffer CREATED: its root copy, the
104
- * path copies its writes made, the merge results it built, and every
105
- * container of the private copies its reads took. A write edits these in
106
- * place. Everything else in `workingCopy` is SHARED — with the committed
107
- * generation the stage first touched, or with a value the stage staged —
108
- * and is copied before a write passes through it ({@link ownSpine}).
109
- */
110
- owned = new WeakSet();
111
- /**
112
- * Container values the stage staged with {@link set} — its own objects,
113
- * held by reference (9.23.0). A read hands them back as they are, exactly
114
- * as the private working copy always did, and never privatises them: a
115
- * private copy of a staged value would leave `workingCopy` and
116
- * `overwritePatch` disagreeing about a value the stage wrote.
117
- */
118
- staged = new WeakSet();
119
- /**
120
- * Owned containers with no container still shared with committed state
121
- * anywhere below them (a private deep copy, a merge result built on a
122
- * private base, a path copy whose shared children were privatised). A read
123
- * that lands on one needs no walk — see {@link privatiseBelow}.
124
- */
125
- privateTrees = new WeakSet();
126
- /**
127
- * The containers of {@link baseSnapshot} that {@link detachBase} created:
128
- * its root copy and the copies on the way to a detached path. Allocated
129
- * only by the first detach — the in-contract stage never pays for it.
130
- */
131
- baseOwned;
132
- /**
133
- * The private deep copies {@link detachBase} put into the diff base: nothing
134
- * at or below one is committed state, so a later detach inside it is a no-op.
135
- */
136
- detachedBase;
137
- /**
138
- * Where the stage writes (9.30.0): a path prefix its frame computed and
139
- * hands over as data (C2 — for the engine, the frame's run namespace, or
140
- * `[]` for the root). Its containers are the stage's ADDRESS, not a value
141
- * the stage reads (every read it makes is a key below it), so a shell a
142
- * write leaves there is no part of the read-back the record must hold.
143
- */
144
- address;
145
- /** `merge` ops staged since the last commit — see {@link admit}. */
146
- stagedMerges = 0;
147
- /** Ops staged deeper than one key below the stage's address — see {@link admit}. */
148
- nestedOps = 0;
149
- constructor(base, commitValues = 'full', readKeysProvider, address = []) {
150
- // `base` is the committed generation the stage first touched —
151
- // immutable-after-swap, the invariant the first-touch view already rests
152
- // on — so the diff base is held by REFERENCE, and the working copy starts
153
- // as a copy of its ROOT only. Before 9.29.0 these two lines were two
154
- // `structuredClone`s of the whole state, paid by every stage that wrote.
155
- this.baseSnapshot = base;
156
- this.workingCopy = (0, pathOps_js_1.ownedRootOf)(base, this.owned);
157
- this.commitValues = commitValues;
158
- this.readKeysProvider = readKeysProvider;
159
- this.address = address;
160
- }
161
- /** Stamp the current read prefix onto a staged op — only when the
162
- * provenance dial is on (provider present), so the default path allocates
163
- * nothing and commit bundles stay byte-identical. */
164
- stampReadKeys(op) {
165
- if (this.readKeysProvider)
166
- op.readKeys = this.readKeysProvider();
167
- return op;
168
- }
169
- /** Stage an op into `opTrace`, counting what decides whether {@link admit} must fold. */
170
- stage(path, key, verb) {
171
- if (verb === 'merge')
172
- this.stagedMerges++;
173
- if (path.length - (0, admission_js_1.addressDepthOf)(path, this.address) > 1)
174
- this.nestedOps++;
175
- this.opTrace.push(this.stampReadKeys({ path: key, verb }));
176
- }
177
- /**
178
- * Hard overwrite at the specified path. Stores the REFERENCE in both trees
179
- * (9.23.0) — the record's copy is taken once, at commit; see the header.
180
- */
181
- set(path, value, shouldRedact = false) {
182
- const key = (0, utils_js_1.normalisePath)(path);
183
- this.detachHeldAncestors(path);
184
- (0, pathOps_js_1.ownSpine)(this.workingCopy, path, this.owned);
185
- (0, pathOps_js_1.nativeSet)(this.workingCopy, path, value);
186
- (0, pathOps_js_1.nativeSet)(this.overwritePatch, path, value);
187
- if ((0, pathOps_js_1.isContainer)(value)) {
188
- this.heldRefs.add(key);
189
- this.staged.add(value);
190
- }
191
- else {
192
- this.heldRefs.delete(key);
193
- }
194
- if (shouldRedact) {
195
- this.redactedPaths.add(key);
196
- }
197
- this.stage(path, key, 'set');
198
- }
199
- /**
200
- * A nested op is about to write THROUGH a path whose `overwritePatch`
201
- * value is a held reference (9.23.0). Today's law is that the two trees
202
- * receive the same nested `set`/`delete` mutations but ONLY `workingCopy`
203
- * receives a nested `merge`'s result (`updatePatch` gets the delta) — so a
204
- * container shared between the trees would leak the merged value into the
205
- * overwrite payload, and a shared container is also the caller's own
206
- * object, which the engine must not edit on the record's behalf. Replacing
207
- * the held ancestor with its clone in `overwritePatch` restores exactly
208
- * the private tree the per-write clone used to give it, paid once per
209
- * ancestor and only on the nested-op path the public surface never takes
210
- * (the scope proxy writes ROOT keys). `workingCopy` keeps the reference,
211
- * as it always did.
212
- */
213
- detachHeldAncestors(path) {
214
- if (this.heldRefs.size === 0)
215
- return;
216
- for (let i = 1; i < path.length; i++) {
217
- const ancestor = path.slice(0, i);
218
- const key = (0, utils_js_1.normalisePath)(ancestor);
219
- if (!this.heldRefs.has(key))
220
- continue;
221
- const held = (0, pathOps_js_1.nativeGet)(this.overwritePatch, ancestor);
222
- if (held !== null && typeof held === 'object')
223
- (0, pathOps_js_1.nativeSet)(this.overwritePatch, ancestor, structuredClone(held));
224
- this.heldRefs.delete(key);
225
- }
226
- }
227
- /**
228
- * Explicit key deletion at the specified path (#13c-B; absorbs backlog B8).
229
- *
230
- * Stages EXACTLY the same buffer mutations as `set(path, undefined)` —
231
- * `workingCopy`/`overwritePatch` get an own `undefined` at the path (the
232
- * historical flattening, preserving read behavior and the dedup diff base
233
- * across modes) — but records the op verb as `'delete'`. At commit:
234
- * `'full'` mode maps it back to a `'set'` trace entry (byte-identical to
235
- * today); `'delta'` mode emits a real `'delete'` entry whose replay
236
- * REMOVES the key instead of leaving `key: undefined` behind.
237
- *
238
- * The net-change filter reads that staged own `undefined` as ABSENT
239
- * (`deepEqual`, 9.19.1) — so under `'delta'`, whose committed state really
240
- * lacks the key, deleting an absent key inside a container the stage also
241
- * re-wrote is the no-op it is, not a `set` of the whole container.
242
- */
243
- delete(path, shouldRedact = false) {
244
- const key = (0, utils_js_1.normalisePath)(path);
245
- this.detachHeldAncestors(path);
246
- (0, pathOps_js_1.ownSpine)(this.workingCopy, path, this.owned);
247
- (0, pathOps_js_1.nativeSet)(this.workingCopy, path, undefined);
248
- (0, pathOps_js_1.nativeSet)(this.overwritePatch, path, undefined);
249
- this.heldRefs.delete(key);
250
- if (shouldRedact) {
251
- this.redactedPaths.add(key);
252
- }
253
- this.stage(path, key, 'delete');
254
- }
255
- /** Deep union merge at the specified path. `deepSmartMerge` builds fresh
256
- * containers, so neither tree ever holds the merge INPUT by reference;
257
- * the nested-op detach guards the ancestor it writes INTO.
258
- *
259
- * The value merged INTO is made private first (`privatise`), as the
260
- * whole-state clone made it before 9.29.0. Not only for the reads that
261
- * follow: `deepSmartMerge` unions arrays BY REFERENCE, so whether an
262
- * element the stage passes in is "already there" depends on which objects
263
- * the base holds — a committed array would dedup an element the stage
264
- * read from it before its first write, where the private copy (and
265
- * 9.28.0) appends it. */
266
- merge(path, value, shouldRedact = false) {
267
- const key = (0, utils_js_1.normalisePath)(path);
268
- this.detachHeldAncestors(path);
269
- this.privatise(path);
270
- const existing = (0, pathOps_js_1.nativeGet)(this.workingCopy, path) ?? {};
271
- const merged = (0, utils_js_1.deepSmartMerge)(existing, value);
272
- (0, pathOps_js_1.ownSpine)(this.workingCopy, path, this.owned);
273
- (0, pathOps_js_1.own)(merged, this.owned);
274
- if ((0, pathOps_js_1.isContainer)(merged))
275
- this.privateTrees.add(merged);
276
- (0, pathOps_js_1.nativeSet)(this.workingCopy, path, merged);
277
- (0, pathOps_js_1.nativeSet)(this.updatePatch, path, (0, utils_js_1.deepSmartMerge)((0, pathOps_js_1.nativeGet)(this.updatePatch, path) ?? {}, value));
278
- if (shouldRedact) {
279
- this.redactedPaths.add(key);
280
- }
281
- this.stage(path, key, 'merge');
282
- }
283
- /**
284
- * Field-level redaction (9.19.0): mark dot-paths INSIDE the value staged at
285
- * `path` as secret, so `scrubPatch` scrubs them in the commit log and the
286
- * mirror the same way a whole-key redaction is scrubbed. A field is
287
- * registered as a literal key AND, when dotted, as the nested path it
288
- * names — whichever exists in the patch is the one `scrubPatch` finds.
289
- * Marked paths survive commit only while the op path they sit under does
290
- * (see {@link survivingRedactedPaths}).
291
- */
292
- markRedactedFields(path, fields) {
293
- for (const field of fields) {
294
- this.redactedPaths.add((0, utils_js_1.normalisePath)([...path, field]));
295
- if (field.includes('.'))
296
- this.redactedPaths.add((0, utils_js_1.normalisePath)([...path, ...field.split('.')]));
297
- }
298
- }
299
- /**
300
- * Does a redaction mark address an array ELEMENT right below `path`
301
- * (`list.1.token`)? An `append` row re-bases the indices onto the tail, so
302
- * such a path takes the whole-value `set` (`deltaEncoding · pushValueRow`).
303
- * A mark by NAME below an array (`obj.y`) means the same thing on the tail
304
- * as on the whole value, so the compact row stays (byte-identical).
305
- */
306
- markedBelow(path) {
307
- const prefix = path + utils_js_1.DELIM;
308
- for (const marked of this.redactedPaths) {
309
- if (!marked.startsWith(prefix))
310
- continue;
311
- const next = marked.slice(prefix.length).split(utils_js_1.DELIM)[0];
312
- if (/^(0|[1-9]\d*)$/.test(next))
313
- return true;
314
- }
315
- return false;
316
- }
317
- /**
318
- * The redacted paths that survive the net-change filter: a path survives
319
- * when it IS a surviving op path (a whole-key redaction) or sits UNDER one
320
- * (a field inside a surviving write). A dropped op takes its fields with it.
321
- */
322
- survivingRedactedPaths(survivingPaths) {
323
- const out = new Set();
324
- for (const path of this.redactedPaths) {
325
- if (survivingPaths.has(path)) {
326
- out.add(path);
327
- continue;
328
- }
329
- for (const op of survivingPaths) {
330
- if (path.startsWith(op + utils_js_1.DELIM)) {
331
- out.add(path);
332
- break;
333
- }
334
- }
335
- }
336
- return out;
337
- }
338
- /**
339
- * Read current value at path (includes uncommitted changes). The value is
340
- * the stage's own — private to it, as the whole-state clone made every read
341
- * after the first write before 9.29.0 (`privatise`).
342
- */
343
- get(path, defaultValue) {
344
- this.privatise(path);
345
- return (0, pathOps_js_1.nativeGet)(this.workingCopy, path, defaultValue);
346
- }
347
- /**
348
- * Read the working copy at `path` WITHOUT taking a private copy — for a
349
- * reader that only compares (the dev-mode borrowed-mutation report in
350
- * `StageContext.commit`), never for a value handed to a stage.
351
- */
352
- peek(path) {
353
- return (0, pathOps_js_1.nativeGet)(this.workingCopy, path);
354
- }
355
- /**
356
- * Keep the diff base exact under a read the working copy cannot answer.
357
- *
358
- * When `workingCopy` holds nothing at `path` — the stage deleted or unset
359
- * it, or a write replaced a container above it — `RecordFrame · read`
360
- * serves the read from LIVE committed state, exactly as 9.28.0
361
- * did, so the value it hands out is committed state itself. On 9.28.0 the
362
- * diff base was a whole-state clone taken at the stage's first write, and
363
- * an in-place edit of that value (out of contract — reads are borrowed)
364
- * could not move it: written back, the edit was recorded. Here the diff
365
- * base IS a committed generation, and it very often holds that same
366
- * container at `path` — the edit would move the base with it, and the
367
- * write-back would commit no change. So before the value goes out, the
368
- * base's value at `path` is replaced by a private deep copy (the base's
369
- * root and the containers on the way copied shallowly) — what 9.28.0's
370
- * base held there. The commit's net-change test compares against it and
371
- * the delta encoder replays from it; the value handed out stays the live
372
- * one, so whatever else an edit of it reaches (live state, the next
373
- * generation) behaves as on 9.28.0 too.
374
- *
375
- * Not `privatise`: a private copy handed to the stage would also keep the
376
- * edit out of live state, where 9.28.0 let it in — a run-namespaced read
377
- * that falls back to a global key would then end differently (the
378
- * differential's NESTED family fails within 100 programs that way).
379
- *
380
- * Copies nothing when the base holds no container at `path`, and nothing
381
- * twice: a path at or below an earlier detach is already private. O(path)
382
- * otherwise, plus O(value) once per detached path.
383
- */
384
- detachBase(path) {
385
- if (path.length === 0 || !(0, pathOps_js_1.isContainer)(this.baseSnapshot))
386
- return;
387
- let at = this.baseSnapshot;
388
- for (const k of path) {
389
- if (this.detachedBase?.has(at))
390
- return;
391
- const child = (0, pathOps_js_1.ownChild)(at, k);
392
- if (!(0, pathOps_js_1.isContainer)(child))
393
- return;
394
- at = child;
395
- }
396
- if (this.detachedBase?.has(at))
397
- return;
398
- const owned = (this.baseOwned ??= new WeakSet());
399
- if (!owned.has(this.baseSnapshot))
400
- this.baseSnapshot = (0, pathOps_js_1.ownedRootOf)(this.baseSnapshot, owned);
401
- (0, pathOps_js_1.ownSpine)(this.baseSnapshot, path, owned);
402
- const copy = structuredClone(at);
403
- (this.detachedBase ??= new WeakSet()).add(copy);
404
- (0, pathOps_js_1.nativeSet)(this.baseSnapshot, path, copy);
405
- }
406
- /**
407
- * Private reads (9.29.0): make the value at `path` the stage's own before
408
- * a read hands it out — so a read after the stage's first write behaves
409
- * exactly as it did when the buffer began with a deep clone of the whole
410
- * state. An in-place edit of what the read returned (out of contract —
411
- * reads are borrowed) stays inside the buffer, and committed state is never
412
- * touched. Whether the RECORD keeps it is the admitted record's law
413
- * (9.30.0, owner ruling R1 — the record keeps what the stage read back): it
414
- * is kept when the edited value lies at or below a path the stage wrote in
415
- * this stage — set, merged or written back alike — and lost otherwise.
416
- *
417
- * Walking the path from the (owned) root:
418
- * - a container still SHARED with committed state at the same position is
419
- * replaced by a private deep copy when it is the value read, or by a
420
- * shallow copy when it is a container on the way to it (so a read of
421
- * `k` under a fork child's address copies `k`, not every child's namespace);
422
- * - a container the stage STAGED (or anything else the buffer did not
423
- * take from committed state) is handed back by reference, as before;
424
- * - a container the buffer owns is walked on — and when it is the value
425
- * read, its still-shared descendants are privatised
426
- * ({@link privatiseBelow}).
427
- *
428
- * Cost: O(path) per read, plus O(value) ONCE per shared container a stage
429
- * reads after its first write. A stage that never reads after writing pays
430
- * nothing; a read before the first write never reaches the buffer.
431
- */
432
- privatise(path) {
433
- if (path.length === 0)
434
- return;
435
- // Resolve first: a read that lands on nothing (a missing key, a refused
436
- // segment, a primitive) returns nothing and must copy nothing.
437
- const chain = [];
438
- let at = this.workingCopy;
439
- for (const k of path) {
440
- at = (0, pathOps_js_1.ownChild)(at, k);
441
- if (!(0, pathOps_js_1.isContainer)(at))
442
- return;
443
- chain.push(at);
444
- }
445
- let parent = this.workingCopy;
446
- let base = this.baseSnapshot;
447
- for (let i = 0; i < path.length; i++) {
448
- const k = path[i];
449
- const atBase = (0, pathOps_js_1.ownChild)(base, k);
450
- let value = chain[i];
451
- if (!this.owned.has(value)) {
452
- if (value !== atBase || this.staged.has(value))
453
- return;
454
- if (i === path.length - 1) {
455
- parent[k] = this.privateCopyOf(value);
456
- return;
457
- }
458
- value = (0, pathOps_js_1.shallowCopy)(value);
459
- this.owned.add(value);
460
- parent[k] = value;
461
- }
462
- parent = value;
463
- base = atBase;
464
- }
465
- this.privatiseBelow(parent, base);
466
- }
467
- /**
468
- * An OWNED container is about to be read whole (a path copy a nested write
469
- * made, say): its descendants still shared with committed state are
470
- * replaced by private deep copies, so nothing the read hands out is
471
- * committed state. Walks owned containers only; marks each one finished
472
- * ({@link privateTrees}), so a container is scanned once per stage.
473
- */
474
- privatiseBelow(container, base) {
475
- const work = [[container, base]];
476
- while (work.length > 0) {
477
- const [node, nodeBase] = work.pop();
478
- if (this.privateTrees.has(node))
479
- continue;
480
- for (const key of Object.keys(node)) {
481
- const child = (0, pathOps_js_1.ownChild)(node, key);
482
- if (!(0, pathOps_js_1.isContainer)(child))
483
- continue;
484
- const atBase = (0, pathOps_js_1.ownChild)(nodeBase, key);
485
- if (this.owned.has(child))
486
- work.push([child, atBase]);
487
- else if (child === atBase && !this.staged.has(child)) {
488
- node[key] = this.privateCopyOf(child);
489
- }
490
- }
491
- this.privateTrees.add(node);
492
- }
493
- }
494
- /** A private deep copy of a committed container — owned through and through. */
495
- privateCopyOf(value) {
496
- const copy = structuredClone(value);
497
- (0, pathOps_js_1.adopt)(copy, this.owned);
498
- this.privateTrees.add(copy);
499
- return copy;
500
- }
501
- /**
502
- * Did any staged op touch `path`, or a path above or below it?
503
- *
504
- * The dev-mode borrowed-read check (`StageContext.commit`) asks this before
505
- * accusing a stage of mutating a value in place: a key the stage legitimately
506
- * WROTE is expected to differ from what it read, and writes reach the buffer
507
- * from paths that bypass user-level write tracking too (the subflow seed,
508
- * `outputMapper` merge-back, the resume re-seed). Dev-mode only — nothing on
509
- * the hot path calls it.
510
- */
511
- wasStaged(path) {
512
- const target = (0, utils_js_1.normalisePath)(path);
513
- for (const op of this.opTrace) {
514
- // On the path, below it or above it — the one path relation every key query asks.
515
- if ((0, keyPaths_js_1.relation)(op.path, target) !== undefined)
516
- return true;
517
- }
518
- return false;
519
- }
520
- /**
521
- * Flush all staged mutations and return the commit bundle — recording the
522
- * stage's NET CHANGE, not its raw write log.
523
- *
524
- * ── WHY (the defect this fixes) ─────────────────────────────────────────
525
- * Previously every `set`/`merge` was recorded verbatim, so the commit bundle
526
- * was a log of *operations* rather than *changes*. Two operations produce no
527
- * net change yet were still committed as "mutations":
528
- *
529
- * 1. No-op write — writing a key the value it already holds (e.g. an
530
- * agent context slot re-emitting identical content every
531
- * turn). base K=1, stage writes K=1.
532
- * 2. Write-revert — changing then restoring a key within one stage.
533
- * base K=1, stage writes K=2 then K=1.
534
- *
535
- * Recording these as mutations (a) bloated causal slicing / backtracking with
536
- * spurious dependencies on intermediate values that never reach final state,
537
- * and (b) made downstream "what changed here?" consumers light up stages that
538
- * changed nothing — most visibly the lens highlight flagging every slot.
539
- *
540
- * ── HOW ─────────────────────────────────────────────────────────────────
541
- * At commit we hold BOTH `baseSnapshot` (state when the stage began) and
542
- * `workingCopy` (state after all its writes). For each path the stage touched
543
- * we keep it in the bundle ONLY if its final value differs from the base
544
- * value ({@link deepEqual}). No-op AND write-revert paths drop out, because
545
- * both compare equal to base. This is a single net-delta diff at commit time
546
- * — one deep compare per touched path, O(changed state), paid once per stage
547
- * (NOT per write). A naive per-write deep-equal skip would be more expensive
548
- * and would still miss write-revert (the intermediate write differs from the
549
- * value present at the moment of writing).
550
- *
551
- * ── TWO HONEST TIERS (by design — do not "unify" them) ──────────────────
552
- * • commit (here) = CHANGE-level — truthful net delta. Feeds the commit
553
- * log, causal chain, narrative, and the lens highlight.
554
- * • `onWrite` event = OP-level — fires on EVERY write attempt regardless of
555
- * net change. Feeds metrics / behavioural observability
556
- * (a debugger wants to see "wrote 2, then reverted").
557
- * `onWrite` is unchanged by this method; only the COMMIT becomes change-only.
558
- *
559
- * ── EMPTY COMMITS ARE INTENTIONAL ───────────────────────────────────────
560
- * A stage that nets no change commits an EMPTY patch — NOT nothing.
561
- * {@link StageContext.commit} still records the bundle unconditionally, so
562
- * every executed stage remains a time-travel cursor stop (its `runtimeStageId`
563
- * marker is preserved); only its PATCH is empty. This is what keeps the
564
- * commit-indexed slider stable while making the highlight truthful.
565
- *
566
- * ── KNOWN LIMITATIONS / FUTURE ──────────────────────────────────────────
567
- * • Explicit key DELETION under the default 'full' mode is still
568
- * flattened to set-of-`undefined` (a removed key cannot be expressed
569
- * in MemoryPatch alone). CLOSED under `commitValues: 'delta'` (#13c-B):
570
- * {@link delete} stages a distinct op and the bundle carries a real
571
- * `delete` trace verb whose replay removes the key.
572
- * • Array-merge dedup in {@link deepSmartMerge} still uses reference equality
573
- * (`new Set`), so deep-equal *objects* in a merged array are not deduped.
574
- * Orthogonal to this change; tracked separately.
575
- *
576
- * Resets the buffer to empty state after commit.
577
- */
578
- commit() {
579
- const rows = this.commitValues === 'delta' ? this.toDeltaPayload() : this.toChangeOnlyPayload();
580
- const redactedPaths = this.survivingRedactedPaths(new Set(rows.trace.map((t) => t.path)));
581
- // The bundle's key order is `recordCommit`'s; a direct caller keeps this same order.
582
- const payload = { overwrite: rows.overwrite, updates: rows.updates, redactedPaths, trace: rows.trace };
583
- this.overwritePatch = {};
584
- this.updatePatch = {};
585
- this.opTrace.length = 0;
586
- this.redactedPaths.clear();
587
- this.heldRefs.clear();
588
- this.workingCopy = {};
589
- this.owned = new WeakSet();
590
- this.owned.add(this.workingCopy);
591
- this.staged = new WeakSet();
592
- this.privateTrees = new WeakSet();
593
- this.stagedMerges = 0;
594
- this.nestedOps = 0;
595
- return payload;
596
- }
597
- /**
598
- * Rebuild overwrite / updates / trace keeping ONLY paths whose final value
599
- * differs from the base value — i.e. the stage's net change. See
600
- * {@link TransactionBuffer.commit} for the rationale.
601
- *
602
- * Paths are compared at the exact granularity they were written (each trace
603
- * entry's path), against `workingCopy` (final) vs `baseSnapshot` (start).
604
- * Surviving `set` paths copy their final value from `overwritePatch`;
605
- * surviving `merge` paths copy their accumulated delta from `updatePatch`,
606
- * keeping the set-vs-merge verb — and the result is ADMITTED ({@link admit}):
607
- * a family of rows whose replay does not give back what the stage read is
608
- * recorded as `set` rows of the read-back instead (9.30.0).
609
- *
610
- * This is the DEFAULT (`commitValues: 'full'`) payload, including the
611
- * historical flattening of staged `delete` ops into `set`-of-`undefined`
612
- * trace entries. The delta encoding lives in {@link toDeltaPayload}.
613
- *
614
- * Work, not bytes (9.22.1): the net-change verdict is paid once per PATH
615
- * and the clone once per CONSECUTIVE run of ops on a path, not once per op
616
- * — see the two memos inside. Pinned by
617
- * test/lib/memory/scenario/repeated-path-byte-identity.test.ts against the
618
- * 9.22.0 bytes. Since 9.23.0 that clone is THE clone: the patch trees hold
619
- * the caller's references (see the class header), so this loop is the one
620
- * place the record is detached from them.
621
- */
622
- toChangeOnlyPayload() {
623
- return this.admit((lossy) => this.changeOnlyRows(lossy));
624
- }
625
- /** The 'full' rows; a family in `lossy` is written as its read-back, at its last touch ({@link emitReadBack}). */
626
- changeOnlyRows(lossy) {
627
- const rows = { overwrite: {}, updates: {}, trace: [] };
628
- const { overwrite, updates, trace } = rows;
629
- // Per PATH, decided once (9.22.1): base and final value are fixed at
630
- // commit, so every later op on a path gets the verdict its first op got.
631
- // `undefined` = not yet decided; the surviving paths are the `true` keys.
632
- const survives = new Map();
633
- // The path the LAST surviving op copied into each patch tree (9.22.1).
634
- // The value at a path is fixed at commit, so an op whose predecessor on
635
- // the SAME tree already copied that path would write the same bytes over
636
- // the same key — it keeps its trace row (the log is byte-identical) and
637
- // pays no second clone. The 9.22.0 element-write funnel stages N
638
- // whole-array sets on ONE path; this is what makes that commit O(N)
639
- // instead of O(N × ops). CONSECUTIVE only — an op on another path in
640
- // between may have coerced or grown this one's container (a descendant
641
- // `nativeSet` through a primitive, a `key: undefined` shell) and the
642
- // re-copy is what repairs it; a `merge` between two sets touches the
643
- // other tree and does not count. Same law as `supersededByNextSet`.
644
- let lastSetPath;
645
- let lastMergePath;
646
- for (let i = 0; i < this.opTrace.length; i++) {
647
- const op = this.opTrace[i];
648
- const family = lossy?.families.get(lossy.rootOf.get(op.path));
649
- if (family !== undefined) {
650
- if (i === family.slot) {
651
- this.emitReadBack(family, rows, 'full');
652
- lastSetPath = lastMergePath = undefined;
653
- }
654
- continue;
655
- }
656
- let keep = survives.get(op.path);
657
- if (keep === undefined) {
658
- keep = this.changedSinceBase(op.path.split(utils_js_1.DELIM));
659
- survives.set(op.path, keep);
660
- }
661
- if (!keep)
662
- continue; // no-op or write-then-revert → no net change
663
- trace.push(flattenedTraceRow(op));
664
- if (op.verb === 'merge') {
665
- if (lastMergePath === op.path)
666
- continue;
667
- lastMergePath = op.path;
668
- const segments = op.path.split(utils_js_1.DELIM);
669
- (0, pathOps_js_1.nativeSet)(updates, segments, structuredClone((0, pathOps_js_1.nativeGet)(this.updatePatch, segments)));
670
- }
671
- else {
672
- if (lastSetPath === op.path)
673
- continue;
674
- lastSetPath = op.path;
675
- const segments = op.path.split(utils_js_1.DELIM);
676
- (0, pathOps_js_1.nativeSet)(overwrite, segments, structuredClone((0, pathOps_js_1.nativeGet)(this.overwritePatch, segments)));
677
- }
678
- }
679
- return rows;
680
- }
681
- /**
682
- * Delta-encoded payload (`commitValues: 'delta'`, #13c-B) — same net-change
683
- * filter as {@link toChangeOnlyPayload}, three encoding differences:
684
- *
685
- * 1. **One trace entry per surviving path** (the §2.5 dedup rule — `append`
686
- * is NOT idempotent on replay, so duplicate entries would multiply
687
- * tails). The verb is resolved from the path's op mix + base→final
688
- * relationship; entries are ordered by each path's LAST touch,
689
- * preserving last-writer-wins for nested/overlapping paths.
690
- * 2. **Verb resolution per path** — for a path with NO surviving relative
691
- * (see 3):
692
- * - last op `'delete'` AND final value gone → `delete` (the path stays
693
- * enumerated in `overwrite` with `undefined` for key-set consumers).
694
- * Requires the parent to be a real container in the base — replay uses
695
- * `nativeDelete`, which is inert on a primitive/absent parent, whereas
696
- * the `'full'` flattening (`_set` of `undefined`) COERCES that parent
697
- * into an object; when they would disagree we keep the flattening;
698
- * - ONLY `'merge'` ops → `merge` with the accumulated `updatePatch`
699
- * delta;
700
- * - otherwise (`set`/mixed): the value the stage's 'full' rows give the
701
- * path ({@link fullRowsValue}). If base and that value are arrays and
702
- * base is a STRICT PREFIX → `append` storing only the tail; else `set`
703
- * storing the full value.
704
- * 3. **OVERLAP FAMILIES take the full-value fallback.** `overwrite` /
705
- * `updates` are nested path TREES, so two surviving paths where one is
706
- * an ancestor of the other (`a` and `a.p`) share storage. Delta's
707
- * per-path encodings would clobber each other there (an `append`
708
- * ancestor stores only a TAIL, a `delete` ancestor `undefined`), so every
709
- * path that has a surviving ancestor/descendant is committed as a plain
710
- * `set` of the value the 'full' rows give it, and the family's
711
- * shallowest path (whose set covers the whole subtree) is emitted LAST.
712
- *
713
- * The result is ADMITTED ({@link admit}) like the 'full' payload: a compact
714
- * row is kept only where the bundle provably folds back, and a family that
715
- * does not is recorded as what the stage read. So both encodings commit the
716
- * value the stage read; before 9.30.0 they shared a replay that did not
717
- * (`replayPathVerbs` / `replayFamilyVerbs`, deleted).
718
- */
719
- toDeltaPayload() {
720
- const fullValueAt = this.fullRowsValue();
721
- return this.admit((lossy) => this.deltaRows(lossy, fullValueAt));
722
- }
723
- /** The delta rows; a family in `lossy` is written as its read-back, at its last touch ({@link emitReadBack}). */
724
- deltaRows(lossy, fullValueAt) {
725
- const rows = { overwrite: {}, updates: {}, trace: [] };
726
- const { overwrite, updates, trace } = rows;
727
- const inLossy = (path) => lossy?.families.has(lossy.rootOf.get(path)) === true;
728
- const survivors = this.netChangeSurvivors(this.opsByPath()).filter((s) => !inLossy(s.path));
729
- const { rootOf, byRoot } = (0, deltaEncoding_js_1.groupIntoFamilies)(survivors, new Set(survivors.map((s) => s.path)));
730
- // THE VERB CHOICE — the delta encoder picks a verb per path; the VALUES
731
- // it encodes come from the one replay (`fullValueAt`), never a replica of
732
- // the verb law (9.30.0: CLAUDE.md's verb-switch replicas lost two here).
733
- const emit = (s) => {
734
- const { path, segments, verbs, before } = s;
735
- const prov = provenance(s.readKeys);
736
- if (byRoot.get(rootOf.get(path)).length > 1) {
737
- // Rule 3 — one coherent tree: every member a set of its value.
738
- trace.push({ path, verb: 'set', ...prov });
739
- (0, pathOps_js_1.nativeSet)(overwrite, segments, structuredClone(fullValueAt(segments)));
740
- return;
741
- }
742
- const lastVerb = verbs[verbs.length - 1];
743
- if (lastVerb === 'delete' && s.after === undefined && this.deleteReplaysAsFlattening(segments)) {
744
- // Real deletion — replay removes the key. Keep the path enumerated
745
- // in `overwrite` (undefined) so Object.keys consumers see it.
746
- trace.push({ path, verb: 'delete', ...prov });
747
- (0, pathOps_js_1.nativeSet)(overwrite, segments, undefined);
748
- }
749
- else if (verbs.every((v) => v === 'merge')) {
750
- trace.push({ path, verb: 'merge', ...prov });
751
- (0, pathOps_js_1.nativeSet)(updates, segments, structuredClone((0, pathOps_js_1.nativeGet)(this.updatePatch, segments)));
752
- }
753
- else {
754
- (0, deltaEncoding_js_1.pushValueRow)(rows, path, segments, before, fullValueAt(segments), prov, this.markedBelow(path));
755
- }
756
- };
757
- // A family that did not fold back takes its place by its last touch.
758
- const pending = lossy === undefined ? [] : [...lossy.families.values()].sort((a, b) => a.slot - b.slot);
759
- let next = 0;
760
- const flushBefore = (touch) => {
761
- while (next < pending.length && pending[next].slot < touch)
762
- this.emitReadBack(pending[next++], rows, 'delta');
763
- };
764
- (0, deltaEncoding_js_1.emitInFamilyOrder)(survivors, rootOf, byRoot, emit, flushBefore);
765
- flushBefore(Infinity);
766
- return rows;
767
- }
768
- // ── The admitted record (9.30.0) ───────────────────────────────────────
769
- /**
770
- * THE ADMISSION — a commit is admitted only if its bundle folds back to the
771
- * stage's read-your-writes view at every path the stage touched. `build`
772
- * lays the rows out (one encoder: `'full'` or `'delta'`); the candidate is
773
- * checked ({@link lossyFamilies}), and when some family's rows do not fold
774
- * back the rows are laid out again with those families written as what the
775
- * stage read ({@link emitReadBack}) — every other family's bytes exactly as
776
- * the first layout made them.
777
- */
778
- admit(build) {
779
- const candidate = build(undefined);
780
- const lossy = this.lossyFamilies(candidate);
781
- return lossy === undefined ? candidate : build(lossy);
782
- }
783
- /**
784
- * The families whose rows do not fold back to what the stage read —
785
- * `undefined` when there are none (`admission.ts · lossyFamilies`: the
786
- * candidate replayed onto the diff base by `dryFold`, every family of
787
- * touched paths compared with the working copy at its root and on the way
788
- * down to it).
789
- *
790
- * Without a fold, when the stage staged no `merge` and no nested op: its
791
- * rows are `set` / `delete` of keys directly under its address, each
792
- * writing the SAME value into `workingCopy` and `overwritePatch` — the
793
- * record is the read-back by construction (the property's ROOT-ONLY arm
794
- * pins this). That keeps the commit of the typed scope's root-key writes
795
- * exactly as cheap as it was.
796
- */
797
- lossyFamilies(candidate) {
798
- if (this.stagedMerges === 0 && this.nestedOps === 0)
799
- return undefined;
800
- return (0, admission_js_1.lossyFamilies)(candidate, this.baseSnapshot, this.workingCopy, this.opTrace, this.address);
801
- }
802
- /**
803
- * A family whose rows did not fold back, written as what the stage read:
804
- * one `set` row per member that changed (descendants by last touch, each
805
- * with its own read prefix), the ROOT last, and the root's read-back value
806
- * in `overwrite` — one coherent tree, so no row can clobber another. The
807
- * root's row is written even when the root itself did not change: it is the
808
- * row that carries the family's read-back (and the containers L-1's dropped
809
- * op left). A lone root under `'delta'` keeps the compact `append` when the
810
- * value it read is its base plus a tail.
811
- */
812
- emitReadBack(family, rows, encoding) {
813
- let root = family.members[0];
814
- let changed = 0;
815
- for (const m of family.members) {
816
- if (m.path === family.root) {
817
- root = m;
818
- continue;
819
- }
820
- if (!this.changedSinceBase(m.path.split(utils_js_1.DELIM)))
821
- continue;
822
- rows.trace.push({ path: m.path, verb: 'set', ...provenance(m.readKeys) });
823
- changed++;
824
- }
825
- const after = (0, pathOps_js_1.nativeGet)(this.workingCopy, family.rootSegments);
826
- if (encoding === 'delta' && changed === 0 && after !== undefined) {
827
- const before = (0, pathOps_js_1.nativeGet)(this.baseSnapshot, family.rootSegments);
828
- (0, deltaEncoding_js_1.pushValueRow)(rows, family.root, family.rootSegments, before, after, provenance(root.readKeys), this.markedBelow(family.root));
829
- return;
830
- }
831
- rows.trace.push({ path: family.root, verb: 'set', ...provenance(root.readKeys) });
832
- // The clone the check took (`admission.ts · foldsBack`), when it took one.
833
- (0, pathOps_js_1.nativeSet)(rows.overwrite, family.rootSegments, family.held !== undefined ? family.held.value : structuredClone(after));
834
- }
835
- /**
836
- * The value the stage's 'full' rows give a path — what the delta encoder
837
- * commits for a family member or a path with a `set` — read from ONE
838
- * {@link dryFold} of those rows over the patch trees themselves, taken the
839
- * first time it is asked. By reference, as the stage held them: an element
840
- * a `set` and a `merge` of one path share stays one element. A stage that
841
- * staged no `merge` and no nested op needs no fold — a path's value is its
842
- * last staged value. (Before 9.30.0: two replicas of the verb law,
843
- * `replayPathVerbs` and `replayFamilyVerbs`.)
844
- */
845
- fullRowsValue() {
846
- if (this.stagedMerges === 0 && this.nestedOps === 0)
847
- return (segments) => (0, pathOps_js_1.nativeGet)(this.overwritePatch, segments);
848
- let fold;
849
- return (segments) => {
850
- fold ??= (0, utils_js_1.dryFold)(this.baseSnapshot, this.updatePatch, this.overwritePatch, this.fullRows());
851
- return (0, pathOps_js_1.nativeGet)(fold, segments);
852
- };
853
- }
854
- /** The stage's 'full' rows: every op on a path the net-change filter keeps, a `delete` spelled `set`. */
855
- fullRows() {
856
- const keep = new Map();
857
- const rows = [];
858
- for (const op of this.opTrace) {
859
- let k = keep.get(op.path);
860
- if (k === undefined)
861
- keep.set(op.path, (k = this.changedSinceBase(op.path.split(utils_js_1.DELIM))));
862
- if (k)
863
- rows.push({ path: op.path, verb: op.verb === 'merge' ? 'merge' : 'set' });
864
- }
865
- return rows;
866
- }
867
- /**
868
- * Did the stage change the value at `segments`? Base and final value are
869
- * fixed at commit, so this is the ONE net-change verdict both payload
870
- * encodings apply (a no-op write and a write-then-revert both fail it).
871
- */
872
- changedSinceBase(segments) {
873
- return !(0, utils_js_1.deepEqual)((0, pathOps_js_1.nativeGet)(this.baseSnapshot, segments), (0, pathOps_js_1.nativeGet)(this.workingCopy, segments));
874
- }
875
- /**
876
- * Path → its op-verb sequence, ordered by LAST touch (delete + re-insert
877
- * moves a re-touched path to the end of the Map's insertion order —
878
- * preserving last-writer-wins for nested/overlapping paths). Per-write
879
- * provenance (#P1): the LAST op's readKeys is kept — read prefixes only grow
880
- * within a stage, so last == union across the path.
881
- */
882
- opsByPath() {
883
- const byPath = new Map();
884
- for (let i = 0; i < this.opTrace.length; i++) {
885
- const op = this.opTrace[i];
886
- const prev = byPath.get(op.path);
887
- if (prev) {
888
- prev.verbs.push(op.verb);
889
- prev.last = i;
890
- if (op.readKeys !== undefined)
891
- prev.readKeys = op.readKeys;
892
- byPath.delete(op.path);
893
- byPath.set(op.path, prev);
894
- }
895
- else {
896
- byPath.set(op.path, {
897
- verbs: [op.verb],
898
- last: i,
899
- ...(op.readKeys !== undefined && { readKeys: op.readKeys }),
900
- });
901
- }
902
- }
903
- return byPath;
904
- }
905
- /** The net-change filter — identical to 'full' ({@link changedSinceBase}). Survivors keep last-touch order. */
906
- netChangeSurvivors(byPath) {
907
- const survivors = [];
908
- for (const [path, { verbs, readKeys, last }] of byPath) {
909
- const segments = path.split(utils_js_1.DELIM);
910
- if (!this.changedSinceBase(segments))
911
- continue; // no-op or write-then-revert → no net change
912
- const before = (0, pathOps_js_1.nativeGet)(this.baseSnapshot, segments);
913
- const after = (0, pathOps_js_1.nativeGet)(this.workingCopy, segments);
914
- survivors.push({ path, segments, verbs, readKeys, last, before, after });
915
- }
916
- return survivors;
917
- }
918
- /**
919
- * May a staged `delete` at this path commit as the `'delete'` verb?
920
- *
921
- * Only when removing the key and the `'full'` mode's flattening (`_set` of
922
- * `undefined`) land in the same place. They diverge when the parent is not
923
- * a container: `nativeDelete` walks away untouched, while `nativeSet`
924
- * COERCES the primitive parent into an object to hold the key. Committing
925
- * `delete` there would silently drop a state change the stage really made,
926
- * so those (pathological) deletes keep the historical flattening.
927
- */
928
- deleteReplaysAsFlattening(segments) {
929
- if (segments.length === 1)
930
- return true; // parent is the state root — always a container
931
- const parent = (0, pathOps_js_1.nativeGet)(this.baseSnapshot, segments.slice(0, -1));
932
- return parent !== null && typeof parent === 'object';
933
- }
934
- }
935
- exports.TransactionBuffer = TransactionBuffer;
936
- /**
937
- * Historical flattening for the `'full'` payload: an explicit delete commits
938
- * as set-of-undefined. Per-write provenance (#P1) rides each surviving entry
939
- * untouched.
940
- */
941
- function flattenedTraceRow(op) {
942
- return op.verb === 'delete'
943
- ? { path: op.path, verb: 'set', ...(op.readKeys !== undefined && { readKeys: op.readKeys }) }
944
- : op;
945
- }
946
- /** A row's `readKeys` fragment — absent unless the provenance dial recorded one (#P1). */
947
- function provenance(readKeys) {
948
- return readKeys !== undefined ? { readKeys } : undefined;
949
- }
950
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNhY3Rpb25CdWZmZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL21lbW9yeS9UcmFuc2FjdGlvbkJ1ZmZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStERzs7O0FBRUgsaURBQWdIO0FBQ2hILHlEQUFvSDtBQUNwSCwrQ0FBeUM7QUFDekMsNkNBVXNCO0FBRXRCLHlDQUFzRjtBQUV0RixNQUFhLGlCQUFpQjtJQUM1Qjs7Ozs7T0FLRztJQUNLLFlBQVksQ0FBTTtJQUNsQixXQUFXLENBQU07SUFFakIsY0FBYyxHQUFnQixFQUFFLENBQUM7SUFDakMsV0FBVyxHQUFnQixFQUFFLENBQUM7SUFDOUIsT0FBTyxHQUEwRCxFQUFFLENBQUM7SUFDcEUsYUFBYSxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFDMUM7Ozs7Ozs7T0FPRztJQUNLLFFBQVEsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0lBQ3JDLDBFQUEwRTtJQUN6RCxZQUFZLENBQW1CO0lBRWhEOzs7K0VBRzJFO0lBQzFELGdCQUFnQixDQUFrQjtJQUVuRDs7Ozs7OztPQU9HO0lBQ0ssS0FBSyxHQUFHLElBQUksT0FBTyxFQUFVLENBQUM7SUFFdEM7Ozs7OztPQU1HO0lBQ0ssTUFBTSxHQUFHLElBQUksT0FBTyxFQUFVLENBQUM7SUFFdkM7Ozs7O09BS0c7SUFDSyxZQUFZLEdBQUcsSUFBSSxPQUFPLEVBQVUsQ0FBQztJQUU3Qzs7OztPQUlHO0lBQ0ssU0FBUyxDQUFtQjtJQUVwQzs7O09BR0c7SUFDSyxZQUFZLENBQW1CO0lBRXZDOzs7Ozs7T0FNRztJQUNjLE9BQU8sQ0FBb0I7SUFFNUMsb0VBQW9FO0lBQzVELFlBQVksR0FBRyxDQUFDLENBQUM7SUFDekIsb0ZBQW9GO0lBQzVFLFNBQVMsR0FBRyxDQUFDLENBQUM7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O0lBQ2hGLE9BQU8sRUFBRSxDQUFDLElBQUksS0FBSyxRQUFRO1FBQ3pCLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFjLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxRQUFRLEtBQUssU0FBUyxJQUFJLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFO1FBQ3RHLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDVCxDQUFDO0FBRUQsMEZBQTBGO0FBQzFGLFNBQVMsVUFBVSxDQUFDLFFBQThCO0lBQ2hELE9BQU8sUUFBUSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQzNELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRyYW5zYWN0aW9uQnVmZmVyIOKAlCBQZXItc3RhZ2UgU1RBR0lORyBidWZmZXIgZm9yIHN0YXRlIG11dGF0aW9uc1xuICpcbiAqIFdoYXQgaXQgSVM6IGEgc3RhZ2luZyBidWZmZXIgd2l0aCByZWFkLXlvdXItd3JpdGVzIGFuZCBuZXQtY2hhbmdlIGNvbW1pdHMuXG4gKiAtIENoYW5nZXMgYXJlIHN0YWdlZCBoZXJlIGR1cmluZyBzdGFnZSBleGVjdXRpb24gYW5kIGZsdXNoZWQgdG9cbiAqICAgU2hhcmVkTWVtb3J5IGluIE9ORSBiYXRjaCBwZXIgc3RhZ2UgKGBjb21taXQoKWApIOKAlCBvdGhlciBzdGFnZXMgYW5kXG4gKiAgIHBhcmFsbGVsIHNpYmxpbmdzIG5ldmVyIG9ic2VydmUgYSBzdGFnZSdzIGhhbGYtZmluaXNoZWQgd3JpdGVzLlxuICogLSBSZWFkLWFmdGVyLXdyaXRlIGNvbnNpc3RlbmN5IHdpdGhpbiBhIHN0YWdlIOKAlCBhIHN0YWdlIHNlZXMgaXRzIG93blxuICogICBzdGFnZWQgd3JpdGVzIGltbWVkaWF0ZWx5LlxuICogLSBgY29tbWl0KClgIHJlY29yZHMgdGhlIHN0YWdlJ3MgTkVUIGNoYW5nZSAoc2VlIHtAbGluayBjb21taXR9KSwgcGx1cyBhblxuICogICBvcGVyYXRpb24gdHJhY2UgZm9yIGRldGVybWluaXN0aWMgcmVwbGF5LlxuICpcbiAqIFdoYXQgaXQgaXMgTk9UOiBhIHJvbGxiYWNrIG1lY2hhbmlzbS4gRGVzcGl0ZSB0aGUgbmFtZSwgdGhlcmUgaXMgbm9cbiAqIGFib3J0L3JvbGxiYWNrIHBhdGgg4oCUIHdoZW4gYSBzdGFnZSBUSFJPV1MsIHRoZSBlbmdpbmUgc3RpbGwgY29tbWl0c1xuICogZXZlcnl0aGluZyBzdGFnZWQgc28gZmFyIGJlZm9yZSByZS10aHJvd2luZyAoY29tbWl0LW9uLWVycm9yIGluXG4gKiBgRmxvd2NoYXJ0VHJhdmVyc2VyYCkuIFRoYXQgaXMgZGVsaWJlcmF0ZTogdGhlIGF1ZGl0IHRyYWlsIG11c3QgcmVjb3JkXG4gKiB3aGF0IHRoZSBmYWlsaW5nIHN0YWdlIGNoYW5nZWQuIERvIG5vdCByZWx5IG9uIFwic3RhZ2UgZmFpbGVkIOKGkiBpdHNcbiAqIHdyaXRlcyB2YW5pc2hlZFwiLlxuICpcbiAqIFRoZSBwYXRjaCB0cmVlcyBob2xkIFJFRkVSRU5DRVMgdW50aWwgY29tbWl0ICg5LjIzLjApLiBBIGBzZXRgIHN0b3JlcyB0aGVcbiAqIGNhbGxlcidzIG93biB2YWx1ZSBpbiBgb3ZlcndyaXRlUGF0Y2hgIGV4YWN0bHkgYXMgaXQgYWx3YXlzIGRpZCBpblxuICogYHdvcmtpbmdDb3B5YDsgdGhlIGNvcHkgdGhlIHJlY29yZCBuZWVkcyBpcyB0YWtlbiBPTkNFIHBlciBzdXJ2aXZpbmcgcGF0aFxuICogd2hlbiB0aGUgcGF5bG9hZCBsZWF2ZXMgdGhlIGJ1ZmZlciAoYHRvQ2hhbmdlT25seVBheWxvYWRgIC9cbiAqIGB0b0RlbHRhUGF5bG9hZGAg4oCUIGV2ZXJ5IHZhbHVlIHRoZXkgZW1pdCBwYXNzZXMgdGhyb3VnaCBgc3RydWN0dXJlZENsb25lYFxuICogdGhlcmUpLiBUaGUgbGF3IFwidGhlIHJlY29yZCBuZXZlciBhbGlhc2VzIGEgY2FsbGVyJ3Mgb2JqZWN0XCIgaXMga2VwdCBhdFxuICogdGhlIGNvbW1pdCBib3VuZGFyeSBpbnN0ZWFkIG9mIGF0IGV2ZXJ5IHdyaXRlLCB3aGljaCBpcyB3aGF0IG1ha2VzIE5cbiAqIHdyaXRlcyB0byBvbmUgcGF0aCBPKE4pIGluc3RlYWQgb2YgTyhOIMOXIHNpemUpLiBDb25zZXF1ZW5jZSwgYnkgZGVzaWduOiBhXG4gKiBjYWxsZXIgd2hvIG11dGF0ZXMgaXRzIG93biBvYmplY3QgQUZURVIgdGhlIHdyaXRlIGFuZCBCRUZPUkUgdGhlIHN0YWdlXG4gKiBlbmRzIGNvbW1pdHMgdGhlIHZhbHVlIGFzIHRoZSBzdGFnZSByZWFkIGl0IGJhY2sg4oCUIHRoZSByZWNvcmQgYWdyZWVzIHdpdGhcbiAqIHRoZSBzdGFnZSAoQ0xBVURFLm1kIGxhbmRtaW5lIDMncyBmaXJzdCBiaXRlLCBjbG9zZWQpLiBUaGUgb25lIHBsYWNlIHRoZVxuICogZW5naW5lIGl0c2VsZiBlZGl0cyBUSFJPVUdIIGEgc3RhZ2VkIHZhbHVlIOKAlCBhIGxhdGVyIG5lc3RlZCBvcCB1bmRlciBhXG4gKiBgc2V0YCBwYXRoIOKAlCBkZXRhY2hlcyB0aGF0IHZhbHVlIGZpcnN0ICh7QGxpbmsgZGV0YWNoSGVsZEFuY2VzdG9yc30pLCBzb1xuICogYHdvcmtpbmdDb3B5YCBhbmQgYG92ZXJ3cml0ZVBhdGNoYCBuZXZlciBzaGFyZSBhIGNvbnRhaW5lciB0aGUgZW5naW5lXG4gKiBtdXRhdGVzIG9uIG9uZSBzaWRlIG9ubHkuXG4gKlxuICogQ09QWS1PTi1XUklURSAoOS4yOS4wIOKAlCBkb2NzL2Rlc2lnbi8yMDI2LTEwLWNvcHktb24td3JpdGUtY29tbWl0Lm1kKS4gVGhlXG4gKiBidWZmZXIgbm8gbG9uZ2VyIGNsb25lcyB0aGUgY29tbWl0dGVkIHN0YXRlIGl0IHN0YXJ0cyBmcm9tLiBgYmFzZVNuYXBzaG90YFxuICogSVMgdGhlIGNvbW1pdHRlZCBnZW5lcmF0aW9uIHRoZSBzdGFnZSBmaXJzdCB0b3VjaGVkIChoZWxkIGJ5IHJlZmVyZW5jZSDigJRcbiAqIGNvbW1pdHRlZCBzdGF0ZSBpcyBpbW11dGFibGUtYWZ0ZXItc3dhcCksIGFuZCBgd29ya2luZ0NvcHlgIHN0YXJ0cyBhcyBhXG4gKiBjb3B5IG9mIGl0cyBST09UIG9ubHk6IGVhY2ggd3JpdGUgY29waWVzIHRoZSBjb250YWluZXJzIG9uIGl0cyBvd24gcGF0aFxuICogKHtAbGluayBvd25TcGluZX0pLCBhbmQgdGhlIGZpcnN0IFJFQUQgYWZ0ZXIgdGhlIHN0YWdlJ3MgZmlyc3Qgd3JpdGUgb2YgYVxuICogY29udGFpbmVyIHN0aWxsIHNoYXJlZCB3aXRoIGNvbW1pdHRlZCBzdGF0ZSB0YWtlcyBhIHByaXZhdGUgZGVlcCBjb3B5IG9mXG4gKiBpdCAoe0BsaW5rIHByaXZhdGlzZX0pIOKAlCB3aGF0IHRoZSB3aG9sZS1zdGF0ZSBjbG9uZSB1c2VkIHRvIGdpdmUgZXZlcnlcbiAqIHJlYWQsIHNvIGFuIGluLXBsYWNlIGVkaXQgb2YgYSByZWFkIHZhbHVlIHN0YXlzIHByaXZhdGUgZXhhY3RseSBhcyBpdCBkaWQuXG4gKiBBIHJlYWQgdGhlIHdvcmtpbmcgY29weSBjYW5ub3QgYW5zd2VyIGlzIHNlcnZlZCBmcm9tIGxpdmUgc3RhdGUgYnkgdGhlXG4gKiBjYWxsZXIsIGFzIGJlZm9yZTsgdGhlIGJ1ZmZlciB0aGVuIHJlcGxhY2VzIHRoYXQgcGF0aCBvZiBpdHMgZGlmZiBiYXNlXG4gKiB3aXRoIGEgcHJpdmF0ZSBjb3B5ICh7QGxpbmsgZGV0YWNoQmFzZX0pLCBhcyB0aGUgY2xvbmUgaGFkIGl0LlxuICpcbiAqIFRIRSBBRE1JVFRFRCBSRUNPUkQgKDkuMzAuMCDigJQgZG9jcy9kZXNpZ24vMjAyNi0xMC1hZG1pdHRlZC1yZWNvcmQubWQpLiBBXG4gKiBjb21taXQgaXMgYWRtaXR0ZWQgb25seSBpZiBpdHMgYnVuZGxlIGZvbGRzIGJhY2sgdG8gdGhlIHN0YWdlJ3NcbiAqIHJlYWQteW91ci13cml0ZXMgdmlldyBhdCBldmVyeSBwYXRoIHRoZSBzdGFnZSB0b3VjaGVkIChhbmQgYXQgZXZlcnlcbiAqIGNvbnRhaW5lciBpdHMgd3JpdGVzIGNyZWF0ZWQgb24gdGhlIHdheSB0aGVyZSwgYmVsb3cgdGhlIHN0YWdlJ3MgYWRkcmVzcykuXG4gKiBCb3RoIGVuY29kZXJzIGNvbW1pdCB0aGUgdmFsdWUgdGhlIHN0YWdlIHJlYWQ6IGEgY29tcGFjdCByb3cg4oCUIGEgYG1lcmdlYFxuICogZGVsdGEsIGFuIGBhcHBlbmRgIHRhaWwg4oCUIGlzIGtlcHQgd2hlcmUgaXQgcHJvdmFibHkgZm9sZHMgYmFjazsgYSBmYW1pbHkgb2ZcbiAqIHJvd3MgdGhhdCBkb2VzIG5vdCBpcyByZWNvcmRlZCBhcyBgc2V0YCByb3dzIG9mIHRoZSB2YWx1ZXMgdGhlIHN0YWdlIHJlYWRcbiAqICh7QGxpbmsgYWRtaXR9KS4gQmVmb3JlIDkuMzAuMCB0aGUgb25lIGFjY3VtdWxhdGVkIG1lcmdlIGRlbHRhIHBlciBwYXRoIHdhc1xuICogcmVwbGF5ZWQgYXQgZXZlcnkgYG1lcmdlYCByb3cgb2YgdGhhdCBwYXRoLCB3aGljaCBsaWVkIGFjcm9zcyBhIGhhcmQgd3JpdGVcbiAqIChgJHVwZGF0ZShrLHt4fSk7IGsgPSB7eX07ICR1cGRhdGUoayx7en0pYCBjb21taXR0ZWQgYHt5LCB4LCB6fWAgZm9yIGFcbiAqIHJlYWQtYmFjayBvZiBge3ksIHp9YCksIGFuIGBbXWAgY2xlYXIsIGEga2luZCBjaGFuZ2Ugb3IgYW4gYXJyYXkgdW5pb25cbiAqIGRlZHVwbGljYXRlZCBieSByZWZlcmVuY2UuIFZlcmlmaWVkIHdoZW4gdGhlIHN0YWdlIHN0YWdlZCBhIGBtZXJnZWAgb3IgYVxuICogbmVzdGVkIG9wOyBhIHN0YWdlIHRoYXQgc3RhZ2VkIG9ubHkgYHNldGAgLyBgZGVsZXRlYCBvZiBrZXlzIGRpcmVjdGx5IHVuZGVyXG4gKiBpdHMgYWRkcmVzcyBpcyBjb2hlcmVudCBieSBjb25zdHJ1Y3Rpb24g4oCUIGJvdGggdHJlZXMgcmVjZWl2ZSB0aGUgc2FtZVxuICogd3JpdGUg4oCUIGFuZCBpcyBhZG1pdHRlZCB3aXRob3V0IHRoZSBmb2xkLlxuICovXG5cbmltcG9ydCB7IHR5cGUgRmFtaWx5LCB0eXBlIExvc3N5LCB0eXBlIE1lbWJlciwgdHlwZSBSb3dzLCBhZGRyZXNzRGVwdGhPZiwgbG9zc3lGYW1pbGllcyB9IGZyb20gJy4vYWRtaXNzaW9uLmpzJztcbmltcG9ydCB7IHR5cGUgT3BWZXJiLCB0eXBlIFN1cnZpdm9yLCBlbWl0SW5GYW1pbHlPcmRlciwgZ3JvdXBJbnRvRmFtaWxpZXMsIHB1c2hWYWx1ZVJvdyB9IGZyb20gJy4vZGVsdGFFbmNvZGluZy5qcyc7XG5pbXBvcnQgeyByZWxhdGlvbiB9IGZyb20gJy4va2V5UGF0aHMuanMnO1xuaW1wb3J0IHtcbiAgYWRvcHQsXG4gIGlzQ29udGFpbmVyLFxuICBuYXRpdmVHZXQgYXMgX2dldCxcbiAgbmF0aXZlU2V0IGFzIF9zZXQsXG4gIG93bixcbiAgb3duQ2hpbGQsXG4gIG93bmVkUm9vdE9mLFxuICBvd25TcGluZSxcbiAgc2hhbGxvd0NvcHksXG59IGZyb20gJy4vcGF0aE9wcy5qcyc7XG5pbXBvcnQgdHlwZSB7IENvbW1pdFZhbHVlc01vZGUsIE1lbW9yeVBhdGNoLCBUcmFjZUVudHJ5IH0gZnJvbSAnLi90eXBlcy5qcyc7XG5pbXBvcnQgeyBkZWVwRXF1YWwsIGRlZXBTbWFydE1lcmdlLCBERUxJTSwgZHJ5Rm9sZCwgbm9ybWFsaXNlUGF0aCB9IGZyb20gJy4vdXRpbHMuanMnO1xuXG5leHBvcnQgY2xhc3MgVHJhbnNhY3Rpb25CdWZmZXIge1xuICAvKipcbiAgICogVGhlIG5ldC1jaGFuZ2UgZGlmZiBiYXNlOiB0aGUgY29tbWl0dGVkIGdlbmVyYXRpb24gdGhlIHN0YWdlIGZpcnN0XG4gICAqIHRvdWNoZWQsIGJ5IHJlZmVyZW5jZSDigJQgZXhjZXB0IHdoZXJlIHtAbGluayBkZXRhY2hCYXNlfSByZXBsYWNlZCBhIHBhdGhcbiAgICogb2YgaXQgd2l0aCBhIHByaXZhdGUgY29weSAoaXRzIHJvb3QgYW5kIHRoZSBjb250YWluZXJzIG9uIHRoZSB3YXkgYXJlXG4gICAqIHRoZW4gY29waWVzIHRvbywgb3duZWQgYnkge0BsaW5rIGJhc2VPd25lZH0pLlxuICAgKi9cbiAgcHJpdmF0ZSBiYXNlU25hcHNob3Q6IGFueTtcbiAgcHJpdmF0ZSB3b3JraW5nQ29weTogYW55O1xuXG4gIHByaXZhdGUgb3ZlcndyaXRlUGF0Y2g6IE1lbW9yeVBhdGNoID0ge307XG4gIHByaXZhdGUgdXBkYXRlUGF0Y2g6IE1lbW9yeVBhdGNoID0ge307XG4gIHByaXZhdGUgb3BUcmFjZTogeyBwYXRoOiBzdHJpbmc7IHZlcmI6IE9wVmVyYjsgcmVhZEtleXM/OiBzdHJpbmdbXSB9W10gPSBbXTtcbiAgcHJpdmF0ZSByZWRhY3RlZFBhdGhzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIC8qKlxuICAgKiBQYXRocyB3aG9zZSBgb3ZlcndyaXRlUGF0Y2hgIHZhbHVlIGlzIHRoZSBjYWxsZXIncyBvd24gb2JqZWN0ICg5LjIzLjApOlxuICAgKiBhIGBzZXRgIG9mIGEgY29udGFpbmVyIHN0b3JlcyB0aGUgcmVmZXJlbmNlLCBhbmQgdGhpcyBpcyB0aGUgbGVkZ2VyIG9mXG4gICAqIHdoaWNoIG9uZXMgYXJlIHN0aWxsIHNoYXJlZCB3aXRoIHRoZSBjYWxsZXIgKGFuZCB3aXRoIGB3b3JraW5nQ29weWApLlxuICAgKiBDb25zdWx0ZWQgb25seSBieSB0aGUgZW5naW5lJ3MgbmVzdGVkIG9wcyDigJQgc2VlXG4gICAqIHtAbGluayBkZXRhY2hIZWxkQW5jZXN0b3JzfTsgdGhlIGNvbW1pdCBwYXlsb2FkIGNsb25lcyBldmVyeSBzdXJ2aXZpbmdcbiAgICogdmFsdWUgYW55d2F5IGFuZCBuZXZlciBhc2tzLiBDbGVhcmVkIHdpdGggdGhlIHJlc3QgYXQgYGNvbW1pdCgpYC5cbiAgICovXG4gIHByaXZhdGUgaGVsZFJlZnMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgLyoqIENvbW1pdC12YWx1ZSBlbmNvZGluZyBwb2xpY3kgKCMxM2MtQikuIGAnZnVsbCdgID0gaGlzdG9yaWNhbCBieXRlcy4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBjb21taXRWYWx1ZXM6IENvbW1pdFZhbHVlc01vZGU7XG5cbiAgLyoqIFBlci13cml0ZSByZWFkLXByb3ZlbmFuY2Ugc291cmNlICgjUDEpLiBXaGVuIHNldCAodGhlXG4gICAqICBgd3JpdGVQcm92ZW5hbmNlOiAncmVhZHMtcHJlZml4J2AgZGlhbCksIGV2ZXJ5IHN0YWdlZCBvcCBzbmFwc2hvdHMgdGhlXG4gICAqICBrZXlzIHRyYWNrZWQtcmVhZCBzbyBmYXIg4oCUIHRoZSB0ZW1wb3JhbC1wcmVmaXggYXR0cmlidXRpb24gY29uc3VtZWQgYnlcbiAgICogIGNhdXNhbCBzbGljaW5nLiBVbmRlZmluZWQgKGRlZmF1bHQpID0gemVybyBjb3N0LCBieXRlLWlkZW50aWNhbCBvcHMuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgcmVhZEtleXNQcm92aWRlcj86ICgpID0+IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgY29udGFpbmVycyBpbiBgd29ya2luZ0NvcHlgIHRoaXMgYnVmZmVyIENSRUFURUQ6IGl0cyByb290IGNvcHksIHRoZVxuICAgKiBwYXRoIGNvcGllcyBpdHMgd3JpdGVzIG1hZGUsIHRoZSBtZXJnZSByZXN1bHRzIGl0IGJ1aWx0LCBhbmQgZXZlcnlcbiAgICogY29udGFpbmVyIG9mIHRoZSBwcml2YXRlIGNvcGllcyBpdHMgcmVhZHMgdG9vay4gQSB3cml0ZSBlZGl0cyB0aGVzZSBpblxuICAgKiBwbGFjZS4gRXZlcnl0aGluZyBlbHNlIGluIGB3b3JraW5nQ29weWAgaXMgU0hBUkVEIOKAlCB3aXRoIHRoZSBjb21taXR0ZWRcbiAgICogZ2VuZXJhdGlvbiB0aGUgc3RhZ2UgZmlyc3QgdG91Y2hlZCwgb3Igd2l0aCBhIHZhbHVlIHRoZSBzdGFnZSBzdGFnZWQg4oCUXG4gICAqIGFuZCBpcyBjb3BpZWQgYmVmb3JlIGEgd3JpdGUgcGFzc2VzIHRocm91Z2ggaXQgKHtAbGluayBvd25TcGluZX0pLlxuICAgKi9cbiAgcHJpdmF0ZSBvd25lZCA9IG5ldyBXZWFrU2V0PG9iamVjdD4oKTtcblxuICAvKipcbiAgICogQ29udGFpbmVyIHZhbHVlcyB0aGUgc3RhZ2Ugc3RhZ2VkIHdpdGgge0BsaW5rIHNldH0g4oCUIGl0cyBvd24gb2JqZWN0cyxcbiAgICogaGVsZCBieSByZWZlcmVuY2UgKDkuMjMuMCkuIEEgcmVhZCBoYW5kcyB0aGVtIGJhY2sgYXMgdGhleSBhcmUsIGV4YWN0bHlcbiAgICogYXMgdGhlIHByaXZhdGUgd29ya2luZyBjb3B5IGFsd2F5cyBkaWQsIGFuZCBuZXZlciBwcml2YXRpc2VzIHRoZW06IGFcbiAgICogcHJpdmF0ZSBjb3B5IG9mIGEgc3RhZ2VkIHZhbHVlIHdvdWxkIGxlYXZlIGB3b3JraW5nQ29weWAgYW5kXG4gICAqIGBvdmVyd3JpdGVQYXRjaGAgZGlzYWdyZWVpbmcgYWJvdXQgYSB2YWx1ZSB0aGUgc3RhZ2Ugd3JvdGUuXG4gICAqL1xuICBwcml2YXRlIHN0YWdlZCA9IG5ldyBXZWFrU2V0PG9iamVjdD4oKTtcblxuICAvKipcbiAgICogT3duZWQgY29udGFpbmVycyB3aXRoIG5vIGNvbnRhaW5lciBzdGlsbCBzaGFyZWQgd2l0aCBjb21taXR0ZWQgc3RhdGVcbiAgICogYW55d2hlcmUgYmVsb3cgdGhlbSAoYSBwcml2YXRlIGRlZXAgY29weSwgYSBtZXJnZSByZXN1bHQgYnVpbHQgb24gYVxuICAgKiBwcml2YXRlIGJhc2UsIGEgcGF0aCBjb3B5IHdob3NlIHNoYXJlZCBjaGlsZHJlbiB3ZXJlIHByaXZhdGlzZWQpLiBBIHJlYWRcbiAgICogdGhhdCBsYW5kcyBvbiBvbmUgbmVlZHMgbm8gd2FsayDigJQgc2VlIHtAbGluayBwcml2YXRpc2VCZWxvd30uXG4gICAqL1xuICBwcml2YXRlIHByaXZhdGVUcmVlcyA9IG5ldyBXZWFrU2V0PG9iamVjdD4oKTtcblxuICAvKipcbiAgICogVGhlIGNvbnRhaW5lcnMgb2Yge0BsaW5rIGJhc2VTbmFwc2hvdH0gdGhhdCB7QGxpbmsgZGV0YWNoQmFzZX0gY3JlYXRlZDpcbiAgICogaXRzIHJvb3QgY29weSBhbmQgdGhlIGNvcGllcyBvbiB0aGUgd2F5IHRvIGEgZGV0YWNoZWQgcGF0aC4gQWxsb2NhdGVkXG4gICAqIG9ubHkgYnkgdGhlIGZpcnN0IGRldGFjaCDigJQgdGhlIGluLWNvbnRyYWN0IHN0YWdlIG5ldmVyIHBheXMgZm9yIGl0LlxuICAgKi9cbiAgcHJpdmF0ZSBiYXNlT3duZWQ/OiBXZWFrU2V0PG9iamVjdD47XG5cbiAgLyoqXG4gICAqIFRoZSBwcml2YXRlIGRlZXAgY29waWVzIHtAbGluayBkZXRhY2hCYXNlfSBwdXQgaW50byB0aGUgZGlmZiBiYXNlOiBub3RoaW5nXG4gICAqIGF0IG9yIGJlbG93IG9uZSBpcyBjb21taXR0ZWQgc3RhdGUsIHNvIGEgbGF0ZXIgZGV0YWNoIGluc2lkZSBpdCBpcyBhIG5vLW9wLlxuICAgKi9cbiAgcHJpdmF0ZSBkZXRhY2hlZEJhc2U/OiBXZWFrU2V0PG9iamVjdD47XG5cbiAgLyoqXG4gICAqIFdoZXJlIHRoZSBzdGFnZSB3cml0ZXMgKDkuMzAuMCk6IGEgcGF0aCBwcmVmaXggaXRzIGZyYW1lIGNvbXB1dGVkIGFuZFxuICAgKiBoYW5kcyBvdmVyIGFzIGRhdGEgKEMyIOKAlCBmb3IgdGhlIGVuZ2luZSwgdGhlIGZyYW1lJ3MgcnVuIG5hbWVzcGFjZSwgb3JcbiAgICogYFtdYCBmb3IgdGhlIHJvb3QpLiBJdHMgY29udGFpbmVycyBhcmUgdGhlIHN0YWdlJ3MgQUREUkVTUywgbm90IGEgdmFsdWVcbiAgICogdGhlIHN0YWdlIHJlYWRzIChldmVyeSByZWFkIGl0IG1ha2VzIGlzIGEga2V5IGJlbG93IGl0KSwgc28gYSBzaGVsbCBhXG4gICAqIHdyaXRlIGxlYXZlcyB0aGVyZSBpcyBubyBwYXJ0IG9mIHRoZSByZWFkLWJhY2sgdGhlIHJlY29yZCBtdXN0IGhvbGQuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGFkZHJlc3M6IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4gIC8qKiBgbWVyZ2VgIG9wcyBzdGFnZWQgc2luY2UgdGhlIGxhc3QgY29tbWl0IOKAlCBzZWUge0BsaW5rIGFkbWl0fS4gKi9cbiAgcHJpdmF0ZSBzdGFnZWRNZXJnZXMgPSAwO1xuICAvKiogT3BzIHN0YWdlZCBkZWVwZXIgdGhhbiBvbmUga2V5IGJlbG93IHRoZSBzdGFnZSdzIGFkZHJlc3Mg4oCUIHNlZSB7QGxpbmsgYWRtaXR9LiAqL1xuICBwcml2YXRlIG5lc3RlZE9wcyA9IDA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgYmFzZTogYW55LFxuICAgIGNvbW1pdFZhbHVlczogQ29tbWl0VmFsdWVzTW9kZSA9ICdmdWxsJyxcbiAgICByZWFkS2V5c1Byb3ZpZGVyPzogKCkgPT4gc3RyaW5nW10sXG4gICAgYWRkcmVzczogcmVhZG9ubHkgc3RyaW5nW10gPSBbXSxcbiAgKSB7XG4gICAgLy8gYGJhc2VgIGlzIHRoZSBjb21taXR0ZWQgZ2VuZXJhdGlvbiB0aGUgc3RhZ2UgZmlyc3QgdG91Y2hlZCDigJRcbiAgICAvLyBpbW11dGFibGUtYWZ0ZXItc3dhcCwgdGhlIGludmFyaWFudCB0aGUgZmlyc3QtdG91Y2ggdmlldyBhbHJlYWR5IHJlc3RzXG4gICAgLy8gb24g4oCUIHNvIHRoZSBkaWZmIGJhc2UgaXMgaGVsZCBieSBSRUZFUkVOQ0UsIGFuZCB0aGUgd29ya2luZyBjb3B5IHN0YXJ0c1xuICAgIC8vIGFzIGEgY29weSBvZiBpdHMgUk9PVCBvbmx5LiBCZWZvcmUgOS4yOS4wIHRoZXNlIHR3byBsaW5lcyB3ZXJlIHR3b1xuICAgIC8vIGBzdHJ1Y3R1cmVkQ2xvbmVgcyBvZiB0aGUgd2hvbGUgc3RhdGUsIHBhaWQgYnkgZXZlcnkgc3RhZ2UgdGhhdCB3cm90ZS5cbiAgICB0aGlzLmJhc2VTbmFwc2hvdCA9IGJhc2U7XG4gICAgdGhpcy53b3JraW5nQ29weSA9IG93bmVkUm9vdE9mKGJhc2UsIHRoaXMub3duZWQpO1xuICAgIHRoaXMuY29tbWl0VmFsdWVzID0gY29tbWl0VmFsdWVzO1xuICAgIHRoaXMucmVhZEtleXNQcm92aWRlciA9IHJlYWRLZXlzUHJvdmlkZXI7XG4gICAgdGhpcy5hZGRyZXNzID0gYWRkcmVzcztcbiAgfVxuXG4gIC8qKiBTdGFtcCB0aGUgY3VycmVudCByZWFkIHByZWZpeCBvbnRvIGEgc3RhZ2VkIG9wIOKAlCBvbmx5IHdoZW4gdGhlXG4gICAqICBwcm92ZW5hbmNlIGRpYWwgaXMgb24gKHByb3ZpZGVyIHByZXNlbnQpLCBzbyB0aGUgZGVmYXVsdCBwYXRoIGFsbG9jYXRlc1xuICAgKiAgbm90aGluZyBhbmQgY29tbWl0IGJ1bmRsZXMgc3RheSBieXRlLWlkZW50aWNhbC4gKi9cbiAgcHJpdmF0ZSBzdGFtcFJlYWRLZXlzKG9wOiB7IHBhdGg6IHN0cmluZzsgdmVyYjogT3BWZXJiOyByZWFkS2V5cz86IHN0cmluZ1tdIH0pOiB0eXBlb2Ygb3Age1xuICAgIGlmICh0aGlzLnJlYWRLZXlzUHJvdmlkZXIpIG9wLnJlYWRLZXlzID0gdGhpcy5yZWFkS2V5c1Byb3ZpZGVyKCk7XG4gICAgcmV0dXJuIG9wO1xuICB9XG5cbiAgLyoqIFN0YWdlIGFuIG9wIGludG8gYG9wVHJhY2VgLCBjb3VudGluZyB3aGF0IGRlY2lkZXMgd2hldGhlciB7QGxpbmsgYWRtaXR9IG11c3QgZm9sZC4gKi9cbiAgcHJpdmF0ZSBzdGFnZShwYXRoOiAoc3RyaW5nIHwgbnVtYmVyKVtdLCBrZXk6IHN0cmluZywgdmVyYjogT3BWZXJiKTogdm9pZCB7XG4gICAgaWYgKHZlcmIgPT09ICdtZXJnZScpIHRoaXMuc3RhZ2VkTWVyZ2VzKys7XG4gICAgaWYgKHBhdGgubGVuZ3RoIC0gYWRkcmVzc0RlcHRoT2YocGF0aCwgdGhpcy5hZGRyZXNzKSA+IDEpIHRoaXMubmVzdGVkT3BzKys7XG4gICAgdGhpcy5vcFRyYWNlLnB1c2godGhpcy5zdGFtcFJlYWRLZXlzKHsgcGF0aDoga2V5LCB2ZXJiIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYXJkIG92ZXJ3cml0ZSBhdCB0aGUgc3BlY2lmaWVkIHBhdGguIFN0b3JlcyB0aGUgUkVGRVJFTkNFIGluIGJvdGggdHJlZXNcbiAgICogKDkuMjMuMCkg4oCUIHRoZSByZWNvcmQncyBjb3B5IGlzIHRha2VuIG9uY2UsIGF0IGNvbW1pdDsgc2VlIHRoZSBoZWFkZXIuXG4gICAqL1xuICBzZXQocGF0aDogKHN0cmluZyB8IG51bWJlcilbXSwgdmFsdWU6IGFueSwgc2hvdWxkUmVkYWN0ID0gZmFsc2UpOiB2b2lkIHtcbiAgICBjb25zdCBrZXkgPSBub3JtYWxpc2VQYXRoKHBhdGgpO1xuICAgIHRoaXMuZGV0YWNoSGVsZEFuY2VzdG9ycyhwYXRoKTtcbiAgICBvd25TcGluZSh0aGlzLndvcmtpbmdDb3B5LCBwYXRoLCB0aGlzLm93bmVkKTtcbiAgICBfc2V0KHRoaXMud29ya2luZ0NvcHksIHBhdGgsIHZhbHVlKTtcbiAgICBfc2V0KHRoaXMub3ZlcndyaXRlUGF0Y2gsIHBhdGgsIHZhbHVlKTtcbiAgICBpZiAoaXNDb250YWluZXIodmFsdWUpKSB7XG4gICAgICB0aGlzLmhlbGRSZWZzLmFkZChrZXkpO1xuICAgICAgdGhpcy5zdGFnZWQuYWRkKHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5oZWxkUmVmcy5kZWxldGUoa2V5KTtcbiAgICB9XG4gICAgaWYgKHNob3VsZFJlZGFjdCkge1xuICAgICAgdGhpcy5yZWRhY3RlZFBhdGhzLmFkZChrZXkpO1xuICAgIH1cbiAgICB0aGlzLnN0YWdlKHBhdGgsIGtleSwgJ3NldCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgbmVzdGVkIG9wIGlzIGFib3V0IHRvIHdyaXRlIFRIUk9VR0ggYSBwYXRoIHdob3NlIGBvdmVyd3JpdGVQYXRjaGBcbiAgICogdmFsdWUgaXMgYSBoZWxkIHJlZmVyZW5jZSAoOS4yMy4wKS4gVG9kYXkncyBsYXcgaXMgdGhhdCB0aGUgdHdvIHRyZWVzXG4gICAqIHJlY2VpdmUgdGhlIHNhbWUgbmVzdGVkIGBzZXRgL2BkZWxldGVgIG11dGF0aW9ucyBidXQgT05MWSBgd29ya2luZ0NvcHlgXG4gICAqIHJlY2VpdmVzIGEgbmVzdGVkIGBtZXJnZWAncyByZXN1bHQgKGB1cGRhdGVQYXRjaGAgZ2V0cyB0aGUgZGVsdGEpIOKAlCBzbyBhXG4gICAqIGNvbnRhaW5lciBzaGFyZWQgYmV0d2VlbiB0aGUgdHJlZXMgd291bGQgbGVhayB0aGUgbWVyZ2VkIHZhbHVlIGludG8gdGhlXG4gICAqIG92ZXJ3cml0ZSBwYXlsb2FkLCBhbmQgYSBzaGFyZWQgY29udGFpbmVyIGlzIGFsc28gdGhlIGNhbGxlcidzIG93blxuICAgKiBvYmplY3QsIHdoaWNoIHRoZSBlbmdpbmUgbXVzdCBub3QgZWRpdCBvbiB0aGUgcmVjb3JkJ3MgYmVoYWxmLiBSZXBsYWNpbmdcbiAgICogdGhlIGhlbGQgYW5jZXN0b3Igd2l0aCBpdHMgY2xvbmUgaW4gYG92ZXJ3cml0ZVBhdGNoYCByZXN0b3JlcyBleGFjdGx5XG4gICAqIHRoZSBwcml2YXRlIHRyZWUgdGhlIHBlci13cml0ZSBjbG9uZSB1c2VkIHRvIGdpdmUgaXQsIHBhaWQgb25jZSBwZXJcbiAgICogYW5jZXN0b3IgYW5kIG9ubHkgb24gdGhlIG5lc3RlZC1vcCBwYXRoIHRoZSBwdWJsaWMgc3VyZmFjZSBuZXZlciB0YWtlc1xuICAgKiAodGhlIHNjb3BlIHByb3h5IHdyaXRlcyBST09UIGtleXMpLiBgd29ya2luZ0NvcHlgIGtlZXBzIHRoZSByZWZlcmVuY2UsXG4gICAqIGFzIGl0IGFsd2F5cyBkaWQuXG4gICAqL1xuICBwcml2YXRlIGRldGFjaEhlbGRBbmNlc3RvcnMocGF0aDogKHN0cmluZyB8IG51bWJlcilbXSk6IHZvaWQge1xuICAgIGlmICh0aGlzLmhlbGRSZWZzLnNpemUgPT09IDApIHJldHVybjtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHBhdGgubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGFuY2VzdG9yID0gcGF0aC5zbGljZSgwLCBpKTtcbiAgICAgIGNvbnN0IGtleSA9IG5vcm1hbGlzZVBhdGgoYW5jZXN0b3IpO1xuICAgICAgaWYgKCF0aGlzLmhlbGRSZWZzLmhhcyhrZXkpKSBjb250aW51ZTtcbiAgICAgIGNvbnN0IGhlbGQgPSBfZ2V0KHRoaXMub3ZlcndyaXRlUGF0Y2gsIGFuY2VzdG9yKTtcbiAgICAgIGlmIChoZWxkICE9PSBudWxsICYmIHR5cGVvZiBoZWxkID09PSAnb2JqZWN0JykgX3NldCh0aGlzLm92ZXJ3cml0ZVBhdGNoLCBhbmNlc3Rvciwgc3RydWN0dXJlZENsb25lKGhlbGQpKTtcbiAgICAgIHRoaXMuaGVsZFJlZnMuZGVsZXRlKGtleSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEV4cGxpY2l0IGtleSBkZWxldGlvbiBhdCB0aGUgc3BlY2lmaWVkIHBhdGggKCMxM2MtQjsgYWJzb3JicyBiYWNrbG9nIEI4KS5cbiAgICpcbiAgICogU3RhZ2VzIEVYQUNUTFkgdGhlIHNhbWUgYnVmZmVyIG11dGF0aW9ucyBhcyBgc2V0KHBhdGgsIHVuZGVmaW5lZClgIOKAlFxuICAgKiBgd29ya2luZ0NvcHlgL2BvdmVyd3JpdGVQYXRjaGAgZ2V0IGFuIG93biBgdW5kZWZpbmVkYCBhdCB0aGUgcGF0aCAodGhlXG4gICAqIGhpc3RvcmljYWwgZmxhdHRlbmluZywgcHJlc2VydmluZyByZWFkIGJlaGF2aW9yIGFuZCB0aGUgZGVkdXAgZGlmZiBiYXNlXG4gICAqIGFjcm9zcyBtb2Rlcykg4oCUIGJ1dCByZWNvcmRzIHRoZSBvcCB2ZXJiIGFzIGAnZGVsZXRlJ2AuIEF0IGNvbW1pdDpcbiAgICogYCdmdWxsJ2AgbW9kZSBtYXBzIGl0IGJhY2sgdG8gYSBgJ3NldCdgIHRyYWNlIGVudHJ5IChieXRlLWlkZW50aWNhbCB0b1xuICAgKiB0b2RheSk7IGAnZGVsdGEnYCBtb2RlIGVtaXRzIGEgcmVhbCBgJ2RlbGV0ZSdgIGVudHJ5IHdob3NlIHJlcGxheVxuICAgKiBSRU1PVkVTIHRoZSBrZXkgaW5zdGVhZCBvZiBsZWF2aW5nIGBrZXk6IHVuZGVmaW5lZGAgYmVoaW5kLlxuICAgKlxuICAgKiBUaGUgbmV0LWNoYW5nZSBmaWx0ZXIgcmVhZHMgdGhhdCBzdGFnZWQgb3duIGB1bmRlZmluZWRgIGFzIEFCU0VOVFxuICAgKiAoYGRlZXBFcXVhbGAsIDkuMTkuMSkg4oCUIHNvIHVuZGVyIGAnZGVsdGEnYCwgd2hvc2UgY29tbWl0dGVkIHN0YXRlIHJlYWxseVxuICAgKiBsYWNrcyB0aGUga2V5LCBkZWxldGluZyBhbiBhYnNlbnQga2V5IGluc2lkZSBhIGNvbnRhaW5lciB0aGUgc3RhZ2UgYWxzb1xuICAgKiByZS13cm90ZSBpcyB0aGUgbm8tb3AgaXQgaXMsIG5vdCBhIGBzZXRgIG9mIHRoZSB3aG9sZSBjb250YWluZXIuXG4gICAqL1xuICBkZWxldGUocGF0aDogKHN0cmluZyB8IG51bWJlcilbXSwgc2hvdWxkUmVkYWN0ID0gZmFsc2UpOiB2b2lkIHtcbiAgICBjb25zdCBrZXkgPSBub3JtYWxpc2VQYXRoKHBhdGgpO1xuICAgIHRoaXMuZGV0YWNoSGVsZEFuY2VzdG9ycyhwYXRoKTtcbiAgICBvd25TcGluZSh0aGlzLndvcmtpbmdDb3B5LCBwYXRoLCB0aGlzLm93bmVkKTtcbiAgICBfc2V0KHRoaXMud29ya2luZ0NvcHksIHBhdGgsIHVuZGVmaW5lZCk7XG4gICAgX3NldCh0aGlzLm92ZXJ3cml0ZVBhdGNoLCBwYXRoLCB1bmRlZmluZWQpO1xuICAgIHRoaXMuaGVsZFJlZnMuZGVsZXRlKGtleSk7XG4gICAgaWYgKHNob3VsZFJlZGFjdCkge1xuICAgICAgdGhpcy5yZWRhY3RlZFBhdGhzLmFkZChrZXkpO1xuICAgIH1cbiAgICB0aGlzLnN0YWdlKHBhdGgsIGtleSwgJ2RlbGV0ZScpO1xuICB9XG5cbiAgLyoqIERlZXAgdW5pb24gbWVyZ2UgYXQgdGhlIHNwZWNpZmllZCBwYXRoLiBgZGVlcFNtYXJ0TWVyZ2VgIGJ1aWxkcyBmcmVzaFxuICAgKiAgY29udGFpbmVycywgc28gbmVpdGhlciB0cmVlIGV2ZXIgaG9sZHMgdGhlIG1lcmdlIElOUFVUIGJ5IHJlZmVyZW5jZTtcbiAgICogIHRoZSBuZXN0ZWQtb3AgZGV0YWNoIGd1YXJkcyB0aGUgYW5jZXN0b3IgaXQgd3JpdGVzIElOVE8uXG4gICAqXG4gICAqICBUaGUgdmFsdWUgbWVyZ2VkIElOVE8gaXMgbWFkZSBwcml2YXRlIGZpcnN0IChgcHJpdmF0aXNlYCksIGFzIHRoZVxuICAgKiAgd2hvbGUtc3RhdGUgY2xvbmUgbWFkZSBpdCBiZWZvcmUgOS4yOS4wLiBOb3Qgb25seSBmb3IgdGhlIHJlYWRzIHRoYXRcbiAgICogIGZvbGxvdzogYGRlZXBTbWFydE1lcmdlYCB1bmlvbnMgYXJyYXlzIEJZIFJFRkVSRU5DRSwgc28gd2hldGhlciBhblxuICAgKiAgZWxlbWVudCB0aGUgc3RhZ2UgcGFzc2VzIGluIGlzIFwiYWxyZWFkeSB0aGVyZVwiIGRlcGVuZHMgb24gd2hpY2ggb2JqZWN0c1xuICAgKiAgdGhlIGJhc2UgaG9sZHMg4oCUIGEgY29tbWl0dGVkIGFycmF5IHdvdWxkIGRlZHVwIGFuIGVsZW1lbnQgdGhlIHN0YWdlXG4gICAqICByZWFkIGZyb20gaXQgYmVmb3JlIGl0cyBmaXJzdCB3cml0ZSwgd2hlcmUgdGhlIHByaXZhdGUgY29weSAoYW5kXG4gICAqICA5LjI4LjApIGFwcGVuZHMgaXQuICovXG4gIG1lcmdlKHBhdGg6IChzdHJpbmcgfCBudW1iZXIpW10sIHZhbHVlOiBhbnksIHNob3VsZFJlZGFjdCA9IGZhbHNlKTogdm9pZCB7XG4gICAgY29uc3Qga2V5ID0gbm9ybWFsaXNlUGF0aChwYXRoKTtcbiAgICB0aGlzLmRldGFjaEhlbGRBbmNlc3RvcnMocGF0aCk7XG4gICAgdGhpcy5wcml2YXRpc2UocGF0aCk7XG4gICAgY29uc3QgZXhpc3RpbmcgPSBfZ2V0KHRoaXMud29ya2luZ0NvcHksIHBhdGgpID8/IHt9O1xuICAgIGNvbnN0IG1lcmdlZCA9IGRlZXBTbWFydE1lcmdlKGV4aXN0aW5nLCB2YWx1ZSk7XG4gICAgb3duU3BpbmUodGhpcy53b3JraW5nQ29weSwgcGF0aCwgdGhpcy5vd25lZCk7XG4gICAgb3duKG1lcmdlZCwgdGhpcy5vd25lZCk7XG4gICAgaWYgKGlzQ29udGFpbmVyKG1lcmdlZCkpIHRoaXMucHJpdmF0ZVRyZWVzLmFkZChtZXJnZWQpO1xuICAgIF9zZXQodGhpcy53b3JraW5nQ29weSwgcGF0aCwgbWVyZ2VkKTtcbiAgICBfc2V0KHRoaXMudXBkYXRlUGF0Y2gsIHBhdGgsIGRlZXBTbWFydE1lcmdlKF9nZXQodGhpcy51cGRhdGVQYXRjaCwgcGF0aCkgPz8ge30sIHZhbHVlKSk7XG4gICAgaWYgKHNob3VsZFJlZGFjdCkge1xuICAgICAgdGhpcy5yZWRhY3RlZFBhdGhzLmFkZChrZXkpO1xuICAgIH1cbiAgICB0aGlzLnN0YWdlKHBhdGgsIGtleSwgJ21lcmdlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmllbGQtbGV2ZWwgcmVkYWN0aW9uICg5LjE5LjApOiBtYXJrIGRvdC1wYXRocyBJTlNJREUgdGhlIHZhbHVlIHN0YWdlZCBhdFxuICAgKiBgcGF0aGAgYXMgc2VjcmV0LCBzbyBgc2NydWJQYXRjaGAgc2NydWJzIHRoZW0gaW4gdGhlIGNvbW1pdCBsb2cgYW5kIHRoZVxuICAgKiBtaXJyb3IgdGhlIHNhbWUgd2F5IGEgd2hvbGUta2V5IHJlZGFjdGlvbiBpcyBzY3J1YmJlZC4gQSBmaWVsZCBpc1xuICAgKiByZWdpc3RlcmVkIGFzIGEgbGl0ZXJhbCBrZXkgQU5ELCB3aGVuIGRvdHRlZCwgYXMgdGhlIG5lc3RlZCBwYXRoIGl0XG4gICAqIG5hbWVzIOKAlCB3aGljaGV2ZXIgZXhpc3RzIGluIHRoZSBwYXRjaCBpcyB0aGUgb25lIGBzY3J1YlBhdGNoYCBmaW5kcy5cbiAgICogTWFya2VkIHBhdGhzIHN1cnZpdmUgY29tbWl0IG9ubHkgd2hpbGUgdGhlIG9wIHBhdGggdGhleSBzaXQgdW5kZXIgZG9lc1xuICAgKiAoc2VlIHtAbGluayBzdXJ2aXZpbmdSZWRhY3RlZFBhdGhzfSkuXG4gICAqL1xuICBtYXJrUmVkYWN0ZWRGaWVsZHMocGF0aDogKHN0cmluZyB8IG51bWJlcilbXSwgZmllbGRzOiByZWFkb25seSBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGZvciAoY29uc3QgZmllbGQgb2YgZmllbGRzKSB7XG4gICAgICB0aGlzLnJlZGFjdGVkUGF0aHMuYWRkKG5vcm1hbGlzZVBhdGgoWy4uLnBhdGgsIGZpZWxkXSkpO1xuICAgICAgaWYgKGZpZWxkLmluY2x1ZGVzKCcuJykpIHRoaXMucmVkYWN0ZWRQYXRocy5hZGQobm9ybWFsaXNlUGF0aChbLi4ucGF0aCwgLi4uZmllbGQuc3BsaXQoJy4nKV0pKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRG9lcyBhIHJlZGFjdGlvbiBtYXJrIGFkZHJlc3MgYW4gYXJyYXkgRUxFTUVOVCByaWdodCBiZWxvdyBgcGF0aGBcbiAgICogKGBsaXN0LjEudG9rZW5gKT8gQW4gYGFwcGVuZGAgcm93IHJlLWJhc2VzIHRoZSBpbmRpY2VzIG9udG8gdGhlIHRhaWwsIHNvXG4gICAqIHN1Y2ggYSBwYXRoIHRha2VzIHRoZSB3aG9sZS12YWx1ZSBgc2V0YCAoYGRlbHRhRW5jb2RpbmcgwrcgcHVzaFZhbHVlUm93YCkuXG4gICAqIEEgbWFyayBieSBOQU1FIGJlbG93IGFuIGFycmF5IChgb2JqLnlgKSBtZWFucyB0aGUgc2FtZSB0aGluZyBvbiB0aGUgdGFpbFxuICAgKiBhcyBvbiB0aGUgd2hvbGUgdmFsdWUsIHNvIHRoZSBjb21wYWN0IHJvdyBzdGF5cyAoYnl0ZS1pZGVudGljYWwpLlxuICAgKi9cbiAgcHJpdmF0ZSBtYXJrZWRCZWxvdyhwYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBwcmVmaXggPSBwYXRoICsgREVMSU07XG4gICAgZm9yIChjb25zdCBtYXJrZWQgb2YgdGhpcy5yZWRhY3RlZFBhdGhzKSB7XG4gICAgICBpZiAoIW1hcmtlZC5zdGFydHNXaXRoKHByZWZpeCkpIGNvbnRpbnVlO1xuICAgICAgY29uc3QgbmV4dCA9IG1hcmtlZC5zbGljZShwcmVmaXgubGVuZ3RoKS5zcGxpdChERUxJTSlbMF07XG4gICAgICBpZiAoL14oMHxbMS05XVxcZCopJC8udGVzdChuZXh0KSkgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcmVkYWN0ZWQgcGF0aHMgdGhhdCBzdXJ2aXZlIHRoZSBuZXQtY2hhbmdlIGZpbHRlcjogYSBwYXRoIHN1cnZpdmVzXG4gICAqIHdoZW4gaXQgSVMgYSBzdXJ2aXZpbmcgb3AgcGF0aCAoYSB3aG9sZS1rZXkgcmVkYWN0aW9uKSBvciBzaXRzIFVOREVSIG9uZVxuICAgKiAoYSBmaWVsZCBpbnNpZGUgYSBzdXJ2aXZpbmcgd3JpdGUpLiBBIGRyb3BwZWQgb3AgdGFrZXMgaXRzIGZpZWxkcyB3aXRoIGl0LlxuICAgKi9cbiAgcHJpdmF0ZSBzdXJ2aXZpbmdSZWRhY3RlZFBhdGhzKHN1cnZpdmluZ1BhdGhzOiBTZXQ8c3RyaW5nPik6IFNldDxzdHJpbmc+IHtcbiAgICBjb25zdCBvdXQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBmb3IgKGNvbnN0IHBhdGggb2YgdGhpcy5yZWRhY3RlZFBhdGhzKSB7XG4gICAgICBpZiAoc3Vydml2aW5nUGF0aHMuaGFzKHBhdGgpKSB7XG4gICAgICAgIG91dC5hZGQocGF0aCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBvcCBvZiBzdXJ2aXZpbmdQYXRocykge1xuICAgICAgICBpZiAocGF0aC5zdGFydHNXaXRoKG9wICsgREVMSU0pKSB7XG4gICAgICAgICAgb3V0LmFkZChwYXRoKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb3V0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWQgY3VycmVudCB2YWx1ZSBhdCBwYXRoIChpbmNsdWRlcyB1bmNvbW1pdHRlZCBjaGFuZ2VzKS4gVGhlIHZhbHVlIGlzXG4gICAqIHRoZSBzdGFnZSdzIG93biDigJQgcHJpdmF0ZSB0byBpdCwgYXMgdGhlIHdob2xlLXN0YXRlIGNsb25lIG1hZGUgZXZlcnkgcmVhZFxuICAgKiBhZnRlciB0aGUgZmlyc3Qgd3JpdGUgYmVmb3JlIDkuMjkuMCAoYHByaXZhdGlzZWApLlxuICAgKi9cbiAgZ2V0KHBhdGg6IChzdHJpbmcgfCBudW1iZXIpW10sIGRlZmF1bHRWYWx1ZT86IGFueSkge1xuICAgIHRoaXMucHJpdmF0aXNlKHBhdGgpO1xuICAgIHJldHVybiBfZ2V0KHRoaXMud29ya2luZ0NvcHksIHBhdGgsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogUmVhZCB0aGUgd29ya2luZyBjb3B5IGF0IGBwYXRoYCBXSVRIT1VUIHRha2luZyBhIHByaXZhdGUgY29weSDigJQgZm9yIGFcbiAgICogcmVhZGVyIHRoYXQgb25seSBjb21wYXJlcyAodGhlIGRldi1tb2RlIGJvcnJvd2VkLW11dGF0aW9uIHJlcG9ydCBpblxuICAgKiBgU3RhZ2VDb250ZXh0LmNvbW1pdGApLCBuZXZlciBmb3IgYSB2YWx1ZSBoYW5kZWQgdG8gYSBzdGFnZS5cbiAgICovXG4gIHBlZWsocGF0aDogKHN0cmluZyB8IG51bWJlcilbXSk6IHVua25vd24ge1xuICAgIHJldHVybiBfZ2V0KHRoaXMud29ya2luZ0NvcHksIHBhdGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEtlZXAgdGhlIGRpZmYgYmFzZSBleGFjdCB1bmRlciBhIHJlYWQgdGhlIHdvcmtpbmcgY29weSBjYW5ub3QgYW5zd2VyLlxuICAgKlxuICAgKiBXaGVuIGB3b3JraW5nQ29weWAgaG9sZHMgbm90aGluZyBhdCBgcGF0aGAg4oCUIHRoZSBzdGFnZSBkZWxldGVkIG9yIHVuc2V0XG4gICAqIGl0LCBvciBhIHdyaXRlIHJlcGxhY2VkIGEgY29udGFpbmVyIGFib3ZlIGl0IOKAlCBgUmVjb3JkRnJhbWUgwrcgcmVhZGBcbiAgICogc2VydmVzIHRoZSByZWFkIGZyb20gTElWRSBjb21taXR0ZWQgc3RhdGUsIGV4YWN0bHkgYXMgOS4yOC4wXG4gICAqIGRpZCwgc28gdGhlIHZhbHVlIGl0IGhhbmRzIG91dCBpcyBjb21taXR0ZWQgc3RhdGUgaXRzZWxmLiBPbiA5LjI4LjAgdGhlXG4gICAqIGRpZmYgYmFzZSB3YXMgYSB3aG9sZS1zdGF0ZSBjbG9uZSB0YWtlbiBhdCB0aGUgc3RhZ2UncyBmaXJzdCB3cml0ZSwgYW5kXG4gICAqIGFuIGluLXBsYWNlIGVkaXQgb2YgdGhhdCB2YWx1ZSAob3V0IG9mIGNvbnRyYWN0IOKAlCByZWFkcyBhcmUgYm9ycm93ZWQpXG4gICAqIGNvdWxkIG5vdCBtb3ZlIGl0OiB3cml0dGVuIGJhY2ssIHRoZSBlZGl0IHdhcyByZWNvcmRlZC4gSGVyZSB0aGUgZGlmZlxuICAgKiBiYXNlIElTIGEgY29tbWl0dGVkIGdlbmVyYXRpb24sIGFuZCBpdCB2ZXJ5IG9mdGVuIGhvbGRzIHRoYXQgc2FtZVxuICAgKiBjb250YWluZXIgYXQgYHBhdGhgIOKAlCB0aGUgZWRpdCB3b3VsZCBtb3ZlIHRoZSBiYXNlIHdpdGggaXQsIGFuZCB0aGVcbiAgICogd3JpdGUtYmFjayB3b3VsZCBjb21taXQgbm8gY2hhbmdlLiBTbyBiZWZvcmUgdGhlIHZhbHVlIGdvZXMgb3V0LCB0aGVcbiAgICogYmFzZSdzIHZhbHVlIGF0IGBwYXRoYCBpcyByZXBsYWNlZCBieSBhIHByaXZhdGUgZGVlcCBjb3B5ICh0aGUgYmFzZSdzXG4gICAqIHJvb3QgYW5kIHRoZSBjb250YWluZXJzIG9uIHRoZSB3YXkgY29waWVkIHNoYWxsb3dseSkg4oCUIHdoYXQgOS4yOC4wJ3NcbiAgICogYmFzZSBoZWxkIHRoZXJlLiBUaGUgY29tbWl0J3MgbmV0LWNoYW5nZSB0ZXN0IGNvbXBhcmVzIGFnYWluc3QgaXQgYW5kXG4gICAqIHRoZSBkZWx0YSBlbmNvZGVyIHJlcGxheXMgZnJvbSBpdDsgdGhlIHZhbHVlIGhhbmRlZCBvdXQgc3RheXMgdGhlIGxpdmVcbiAgICogb25lLCBzbyB3aGF0ZXZlciBlbHNlIGFuIGVkaXQgb2YgaXQgcmVhY2hlcyAobGl2ZSBzdGF0ZSwgdGhlIG5leHRcbiAgICogZ2VuZXJhdGlvbikgYmVoYXZlcyBhcyBvbiA5LjI4LjAgdG9vLlxuICAgKlxuICAgKiBOb3QgYHByaXZhdGlzZWA6IGEgcHJpdmF0ZSBjb3B5IGhhbmRlZCB0byB0aGUgc3RhZ2Ugd291bGQgYWxzbyBrZWVwIHRoZVxuICAgKiBlZGl0IG91dCBvZiBsaXZlIHN0YXRlLCB3aGVyZSA5LjI4LjAgbGV0IGl0IGluIOKAlCBhIHJ1bi1uYW1lc3BhY2VkIHJlYWRcbiAgICogdGhhdCBmYWxscyBiYWNrIHRvIGEgZ2xvYmFsIGtleSB3b3VsZCB0aGVuIGVuZCBkaWZmZXJlbnRseSAodGhlXG4gICAqIGRpZmZlcmVudGlhbCdzIE5FU1RFRCBmYW1pbHkgZmFpbHMgd2l0aGluIDEwMCBwcm9ncmFtcyB0aGF0IHdheSkuXG4gICAqXG4gICAqIENvcGllcyBub3RoaW5nIHdoZW4gdGhlIGJhc2UgaG9sZHMgbm8gY29udGFpbmVyIGF0IGBwYXRoYCwgYW5kIG5vdGhpbmdcbiAgICogdHdpY2U6IGEgcGF0aCBhdCBvciBiZWxvdyBhbiBlYXJsaWVyIGRldGFjaCBpcyBhbHJlYWR5IHByaXZhdGUuIE8ocGF0aClcbiAgICogb3RoZXJ3aXNlLCBwbHVzIE8odmFsdWUpIG9uY2UgcGVyIGRldGFjaGVkIHBhdGguXG4gICAqL1xuICBkZXRhY2hCYXNlKHBhdGg6IChzdHJpbmcgfCBudW1iZXIpW10pOiB2b2lkIHtcbiAgICBpZiAocGF0aC5sZW5ndGggPT09IDAgfHwgIWlzQ29udGFpbmVyKHRoaXMuYmFzZVNuYXBzaG90KSkgcmV0dXJuO1xuICAgIGxldCBhdDogb2JqZWN0ID0gdGhpcy5iYXNlU25hcHNob3Q7XG4gICAgZm9yIChjb25zdCBrIG9mIHBhdGgpIHtcbiAgICAgIGlmICh0aGlzLmRldGFjaGVkQmFzZT8uaGFzKGF0KSkgcmV0dXJuO1xuICAgICAgY29uc3QgY2hpbGQgPSBvd25DaGlsZChhdCwgayk7XG4gICAgICBpZiAoIWlzQ29udGFpbmVyKGNoaWxkKSkgcmV0dXJuO1xuICAgICAgYXQgPSBjaGlsZDtcbiAgICB9XG4gICAgaWYgKHRoaXMuZGV0YWNoZWRCYXNlPy5oYXMoYXQpKSByZXR1cm47XG4gICAgY29uc3Qgb3duZWQgPSAodGhpcy5iYXNlT3duZWQgPz89IG5ldyBXZWFrU2V0PG9iamVjdD4oKSk7XG4gICAgaWYgKCFvd25lZC5oYXModGhpcy5iYXNlU25hcHNob3QpKSB0aGlzLmJhc2VTbmFwc2hvdCA9IG93bmVkUm9vdE9mKHRoaXMuYmFzZVNuYXBzaG90LCBvd25lZCk7XG4gICAgb3duU3BpbmUodGhpcy5iYXNlU25hcHNob3QsIHBhdGgsIG93bmVkKTtcbiAgICBjb25zdCBjb3B5OiBvYmplY3QgPSBzdHJ1Y3R1cmVkQ2xvbmUoYXQpO1xuICAgICh0aGlzLmRldGFjaGVkQmFzZSA/Pz0gbmV3IFdlYWtTZXQ8b2JqZWN0PigpKS5hZGQoY29weSk7XG4gICAgX3NldCh0aGlzLmJhc2VTbmFwc2hvdCwgcGF0aCwgY29weSk7XG4gIH1cblxuICAvKipcbiAgICogUHJpdmF0ZSByZWFkcyAoOS4yOS4wKTogbWFrZSB0aGUgdmFsdWUgYXQgYHBhdGhgIHRoZSBzdGFnZSdzIG93biBiZWZvcmVcbiAgICogYSByZWFkIGhhbmRzIGl0IG91dCDigJQgc28gYSByZWFkIGFmdGVyIHRoZSBzdGFnZSdzIGZpcnN0IHdyaXRlIGJlaGF2ZXNcbiAgICogZXhhY3RseSBhcyBpdCBkaWQgd2hlbiB0aGUgYnVmZmVyIGJlZ2FuIHdpdGggYSBkZWVwIGNsb25lIG9mIHRoZSB3aG9sZVxuICAgKiBzdGF0ZS4gQW4gaW4tcGxhY2UgZWRpdCBvZiB3aGF0IHRoZSByZWFkIHJldHVybmVkIChvdXQgb2YgY29udHJhY3Qg4oCUXG4gICAqIHJlYWRzIGFyZSBib3Jyb3dlZCkgc3RheXMgaW5zaWRlIHRoZSBidWZmZXIsIGFuZCBjb21taXR0ZWQgc3RhdGUgaXMgbmV2ZXJcbiAgICogdG91Y2hlZC4gV2hldGhlciB0aGUgUkVDT1JEIGtlZXBzIGl0IGlzIHRoZSBhZG1pdHRlZCByZWNvcmQncyBsYXdcbiAgICogKDkuMzAuMCwgb3duZXIgcnVsaW5nIFIxIOKAlCB0aGUgcmVjb3JkIGtlZXBzIHdoYXQgdGhlIHN0YWdlIHJlYWQgYmFjayk6IGl0XG4gICAqIGlzIGtlcHQgd2hlbiB0aGUgZWRpdGVkIHZhbHVlIGxpZXMgYXQgb3IgYmVsb3cgYSBwYXRoIHRoZSBzdGFnZSB3cm90ZSBpblxuICAgKiB0aGlzIHN0YWdlIOKAlCBzZXQsIG1lcmdlZCBvciB3cml0dGVuIGJhY2sgYWxpa2Ug4oCUIGFuZCBsb3N0IG90aGVyd2lzZS5cbiAgICpcbiAgICogV2Fsa2luZyB0aGUgcGF0aCBmcm9tIHRoZSAob3duZWQpIHJvb3Q6XG4gICAqICAtIGEgY29udGFpbmVyIHN0aWxsIFNIQVJFRCB3aXRoIGNvbW1pdHRlZCBzdGF0ZSBhdCB0aGUgc2FtZSBwb3NpdGlvbiBpc1xuICAgKiAgICByZXBsYWNlZCBieSBhIHByaXZhdGUgZGVlcCBjb3B5IHdoZW4gaXQgaXMgdGhlIHZhbHVlIHJlYWQsIG9yIGJ5IGFcbiAgICogICAgc2hhbGxvdyBjb3B5IHdoZW4gaXQgaXMgYSBjb250YWluZXIgb24gdGhlIHdheSB0byBpdCAoc28gYSByZWFkIG9mXG4gICAqICAgIGBrYCB1bmRlciBhIGZvcmsgY2hpbGQncyBhZGRyZXNzIGNvcGllcyBga2AsIG5vdCBldmVyeSBjaGlsZCdzIG5hbWVzcGFjZSk7XG4gICAqICAtIGEgY29udGFpbmVyIHRoZSBzdGFnZSBTVEFHRUQgKG9yIGFueXRoaW5nIGVsc2UgdGhlIGJ1ZmZlciBkaWQgbm90XG4gICAqICAgIHRha2UgZnJvbSBjb21taXR0ZWQgc3RhdGUpIGlzIGhhbmRlZCBiYWNrIGJ5IHJlZmVyZW5jZSwgYXMgYmVmb3JlO1xuICAgKiAgLSBhIGNvbnRhaW5lciB0aGUgYnVmZmVyIG93bnMgaXMgd2Fsa2VkIG9uIOKAlCBhbmQgd2hlbiBpdCBpcyB0aGUgdmFsdWVcbiAgICogICAgcmVhZCwgaXRzIHN0aWxsLXNoYXJlZCBkZXNjZW5kYW50cyBhcmUgcHJpdmF0aXNlZFxuICAgKiAgICAoe0BsaW5rIHByaXZhdGlzZUJlbG93fSkuXG4gICAqXG4gICAqIENvc3Q6IE8ocGF0aCkgcGVyIHJlYWQsIHBsdXMgTyh2YWx1ZSkgT05DRSBwZXIgc2hhcmVkIGNvbnRhaW5lciBhIHN0YWdlXG4gICAqIHJlYWRzIGFmdGVyIGl0cyBmaXJzdCB3cml0ZS4gQSBzdGFnZSB0aGF0IG5ldmVyIHJlYWRzIGFmdGVyIHdyaXRpbmcgcGF5c1xuICAgKiBub3RoaW5nOyBhIHJlYWQgYmVmb3JlIHRoZSBmaXJzdCB3cml0ZSBuZXZlciByZWFjaGVzIHRoZSBidWZmZXIuXG4gICAqL1xuICBwcml2YXRlIHByaXZhdGlzZShwYXRoOiAoc3RyaW5nIHwgbnVtYmVyKVtdKTogdm9pZCB7XG4gICAgaWYgKHBhdGgubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgLy8gUmVzb2x2ZSBmaXJzdDogYSByZWFkIHRoYXQgbGFuZHMgb24gbm90aGluZyAoYSBtaXNzaW5nIGtleSwgYSByZWZ1c2VkXG4gICAgLy8gc2VnbWVudCwgYSBwcmltaXRpdmUpIHJldHVybnMgbm90aGluZyBhbmQgbXVzdCBjb3B5IG5vdGhpbmcuXG4gICAgY29uc3QgY2hhaW46IG9iamVjdFtdID0gW107XG4gICAgbGV0IGF0OiB1bmtub3duID0gdGhpcy53b3JraW5nQ29weTtcbiAgICBmb3IgKGNvbnN0IGsgb2YgcGF0aCkge1xuICAgICAgYXQgPSBvd25DaGlsZChhdCwgayk7XG4gICAgICBpZiAoIWlzQ29udGFpbmVyKGF0KSkgcmV0dXJuO1xuICAgICAgY2hhaW4ucHVzaChhdCk7XG4gICAgfVxuICAgIGxldCBwYXJlbnQ6IGFueSA9IHRoaXMud29ya2luZ0NvcHk7XG4gICAgbGV0IGJhc2U6IHVua25vd24gPSB0aGlzLmJhc2VTbmFwc2hvdDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhdGgubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGsgPSBwYXRoW2ldO1xuICAgICAgY29uc3QgYXRCYXNlID0gb3duQ2hpbGQoYmFzZSwgayk7XG4gICAgICBsZXQgdmFsdWUgPSBjaGFpbltpXTtcbiAgICAgIGlmICghdGhpcy5vd25lZC5oYXModmFsdWUpKSB7XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gYXRCYXNlIHx8IHRoaXMuc3RhZ2VkLmhhcyh2YWx1ZSkpIHJldHVybjtcbiAgICAgICAgaWYgKGkgPT09IHBhdGgubGVuZ3RoIC0gMSkge1xuICAgICAgICAgIHBhcmVudFtrXSA9IHRoaXMucHJpdmF0ZUNvcHlPZih2YWx1ZSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhbHVlID0gc2hhbGxvd0NvcHkodmFsdWUpO1xuICAgICAgICB0aGlzLm93bmVkLmFkZCh2YWx1ZSk7XG4gICAgICAgIHBhcmVudFtrXSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgcGFyZW50ID0gdmFsdWU7XG4gICAgICBiYXNlID0gYXRCYXNlO1xuICAgIH1cbiAgICB0aGlzLnByaXZhdGlzZUJlbG93KHBhcmVudCwgYmFzZSk7XG4gIH1cblxuICAvKipcbiAgICogQW4gT1dORUQgY29udGFpbmVyIGlzIGFib3V0IHRvIGJlIHJlYWQgd2hvbGUgKGEgcGF0aCBjb3B5IGEgbmVzdGVkIHdyaXRlXG4gICAqIG1hZGUsIHNheSk6IGl0cyBkZXNjZW5kYW50cyBzdGlsbCBzaGFyZWQgd2l0aCBjb21taXR0ZWQgc3RhdGUgYXJlXG4gICAqIHJlcGxhY2VkIGJ5IHByaXZhdGUgZGVlcCBjb3BpZXMsIHNvIG5vdGhpbmcgdGhlIHJlYWQgaGFuZHMgb3V0IGlzXG4gICAqIGNvbW1pdHRlZCBzdGF0ZS4gV2Fsa3Mgb3duZWQgY29udGFpbmVycyBvbmx5OyBtYXJrcyBlYWNoIG9uZSBmaW5pc2hlZFxuICAgKiAoe0BsaW5rIHByaXZhdGVUcmVlc30pLCBzbyBhIGNvbnRhaW5lciBpcyBzY2FubmVkIG9uY2UgcGVyIHN0YWdlLlxuICAgKi9cbiAgcHJpdmF0ZSBwcml2YXRpc2VCZWxvdyhjb250YWluZXI6IG9iamVjdCwgYmFzZTogdW5rbm93bik6IHZvaWQge1xuICAgIGNvbnN0IHdvcms6IEFycmF5PFtvYmplY3QsIHVua25vd25dPiA9IFtbY29udGFpbmVyLCBiYXNlXV07XG4gICAgd2hpbGUgKHdvcmsubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgW25vZGUsIG5vZGVCYXNlXSA9IHdvcmsucG9wKCkhO1xuICAgICAgaWYgKHRoaXMucHJpdmF0ZVRyZWVzLmhhcyhub2RlKSkgY29udGludWU7XG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhub2RlKSkge1xuICAgICAgICBjb25zdCBjaGlsZCA9IG93bkNoaWxkKG5vZGUsIGtleSk7XG4gICAgICAgIGlmICghaXNDb250YWluZXIoY2hpbGQpKSBjb250aW51ZTtcbiAgICAgICAgY29uc3QgYXRCYXNlID0gb3duQ2hpbGQobm9kZUJhc2UsIGtleSk7XG4gICAgICAgIGlmICh0aGlzLm93bmVkLmhhcyhjaGlsZCkpIHdvcmsucHVzaChbY2hpbGQsIGF0QmFzZV0pO1xuICAgICAgICBlbHNlIGlmIChjaGlsZCA9PT0gYXRCYXNlICYmICF0aGlzLnN0YWdlZC5oYXMoY2hpbGQpKSB7XG4gICAgICAgICAgKG5vZGUgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW2tleV0gPSB0aGlzLnByaXZhdGVDb3B5T2YoY2hpbGQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLnByaXZhdGVUcmVlcy5hZGQobm9kZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEEgcHJpdmF0ZSBkZWVwIGNvcHkgb2YgYSBjb21taXR0ZWQgY29udGFpbmVyIOKAlCBvd25lZCB0aHJvdWdoIGFuZCB0aHJvdWdoLiAqL1xuICBwcml2YXRlIHByaXZhdGVDb3B5T2YodmFsdWU6IG9iamVjdCk6IG9iamVjdCB7XG4gICAgY29uc3QgY29weSA9IHN0cnVjdHVyZWRDbG9uZSh2YWx1ZSk7XG4gICAgYWRvcHQoY29weSwgdGhpcy5vd25lZCk7XG4gICAgdGhpcy5wcml2YXRlVHJlZXMuYWRkKGNvcHkpO1xuICAgIHJldHVybiBjb3B5O1xuICB9XG5cbiAgLyoqXG4gICAqIERpZCBhbnkgc3RhZ2VkIG9wIHRvdWNoIGBwYXRoYCwgb3IgYSBwYXRoIGFib3ZlIG9yIGJlbG93IGl0P1xuICAgKlxuICAgKiBUaGUgZGV2LW1vZGUgYm9ycm93ZWQtcmVhZCBjaGVjayAoYFN0YWdlQ29udGV4dC5jb21taXRgKSBhc2tzIHRoaXMgYmVmb3JlXG4gICAqIGFjY3VzaW5nIGEgc3RhZ2Ugb2YgbXV0YXRpbmcgYSB2YWx1ZSBpbiBwbGFjZTogYSBrZXkgdGhlIHN0YWdlIGxlZ2l0aW1hdGVseVxuICAgKiBXUk9URSBpcyBleHBlY3RlZCB0byBkaWZmZXIgZnJvbSB3aGF0IGl0IHJlYWQsIGFuZCB3cml0ZXMgcmVhY2ggdGhlIGJ1ZmZlclxuICAgKiBmcm9tIHBhdGhzIHRoYXQgYnlwYXNzIHVzZXItbGV2ZWwgd3JpdGUgdHJhY2tpbmcgdG9vICh0aGUgc3ViZmxvdyBzZWVkLFxuICAgKiBgb3V0cHV0TWFwcGVyYCBtZXJnZS1iYWNrLCB0aGUgcmVzdW1lIHJlLXNlZWQpLiBEZXYtbW9kZSBvbmx5IOKAlCBub3RoaW5nIG9uXG4gICAqIHRoZSBob3QgcGF0aCBjYWxscyBpdC5cbiAgICovXG4gIHdhc1N0YWdlZChwYXRoOiAoc3RyaW5nIHwgbnVtYmVyKVtdKTogYm9vbGVhbiB7XG4gICAgY29uc3QgdGFyZ2V0ID0gbm9ybWFsaXNlUGF0aChwYXRoKTtcbiAgICBmb3IgKGNvbnN0IG9wIG9mIHRoaXMub3BUcmFjZSkge1xuICAgICAgLy8gT24gdGhlIHBhdGgsIGJlbG93IGl0IG9yIGFib3ZlIGl0IOKAlCB0aGUgb25lIHBhdGggcmVsYXRpb24gZXZlcnkga2V5IHF1ZXJ5IGFza3MuXG4gICAgICBpZiAocmVsYXRpb24ob3AucGF0aCwgdGFyZ2V0KSAhPT0gdW5kZWZpbmVkKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEZsdXNoIGFsbCBzdGFnZWQgbXV0YXRpb25zIGFuZCByZXR1cm4gdGhlIGNvbW1pdCBidW5kbGUg4oCUIHJlY29yZGluZyB0aGVcbiAgICogc3RhZ2UncyBORVQgQ0hBTkdFLCBub3QgaXRzIHJhdyB3cml0ZSBsb2cuXG4gICAqXG4gICAqIOKUgOKUgCBXSFkgKHRoZSBkZWZlY3QgdGhpcyBmaXhlcykg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gICAqIFByZXZpb3VzbHkgZXZlcnkgYHNldGAvYG1lcmdlYCB3YXMgcmVjb3JkZWQgdmVyYmF0aW0sIHNvIHRoZSBjb21taXQgYnVuZGxlXG4gICAqIHdhcyBhIGxvZyBvZiAqb3BlcmF0aW9ucyogcmF0aGVyIHRoYW4gKmNoYW5nZXMqLiBUd28gb3BlcmF0aW9ucyBwcm9kdWNlIG5vXG4gICAqIG5ldCBjaGFuZ2UgeWV0IHdlcmUgc3RpbGwgY29tbWl0dGVkIGFzIFwibXV0YXRpb25zXCI6XG4gICAqXG4gICAqICAgMS4gTm8tb3Agd3JpdGUgICDigJQgd3JpdGluZyBhIGtleSB0aGUgdmFsdWUgaXQgYWxyZWFkeSBob2xkcyAoZS5nLiBhblxuICAgKiAgICAgICAgICAgICAgICAgICAgICBhZ2VudCBjb250ZXh0IHNsb3QgcmUtZW1pdHRpbmcgaWRlbnRpY2FsIGNvbnRlbnQgZXZlcnlcbiAgICogICAgICAgICAgICAgICAgICAgICAgdHVybikuIGJhc2UgSz0xLCBzdGFnZSB3cml0ZXMgSz0xLlxuICAgKiAgIDIuIFdyaXRlLXJldmVydCAg4oCUIGNoYW5naW5nIHRoZW4gcmVzdG9yaW5nIGEga2V5IHdpdGhpbiBvbmUgc3RhZ2UuXG4gICAqICAgICAgICAgICAgICAgICAgICAgIGJhc2UgSz0xLCBzdGFnZSB3cml0ZXMgSz0yIHRoZW4gSz0xLlxuICAgKlxuICAgKiBSZWNvcmRpbmcgdGhlc2UgYXMgbXV0YXRpb25zIChhKSBibG9hdGVkIGNhdXNhbCBzbGljaW5nIC8gYmFja3RyYWNraW5nIHdpdGhcbiAgICogc3B1cmlvdXMgZGVwZW5kZW5jaWVzIG9uIGludGVybWVkaWF0ZSB2YWx1ZXMgdGhhdCBuZXZlciByZWFjaCBmaW5hbCBzdGF0ZSxcbiAgICogYW5kIChiKSBtYWRlIGRvd25zdHJlYW0gXCJ3aGF0IGNoYW5nZWQgaGVyZT9cIiBjb25zdW1lcnMgbGlnaHQgdXAgc3RhZ2VzIHRoYXRcbiAgICogY2hhbmdlZCBub3RoaW5nIOKAlCBtb3N0IHZpc2libHkgdGhlIGxlbnMgaGlnaGxpZ2h0IGZsYWdnaW5nIGV2ZXJ5IHNsb3QuXG4gICAqXG4gICAqIOKUgOKUgCBIT1cg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gICAqIEF0IGNvbW1pdCB3ZSBob2xkIEJPVEggYGJhc2VTbmFwc2hvdGAgKHN0YXRlIHdoZW4gdGhlIHN0YWdlIGJlZ2FuKSBhbmRcbiAgICogYHdvcmtpbmdDb3B5YCAoc3RhdGUgYWZ0ZXIgYWxsIGl0cyB3cml0ZXMpLiBGb3IgZWFjaCBwYXRoIHRoZSBzdGFnZSB0b3VjaGVkXG4gICAqIHdlIGtlZXAgaXQgaW4gdGhlIGJ1bmRsZSBPTkxZIGlmIGl0cyBmaW5hbCB2YWx1ZSBkaWZmZXJzIGZyb20gdGhlIGJhc2VcbiAgICogdmFsdWUgKHtAbGluayBkZWVwRXF1YWx9KS4gTm8tb3AgQU5EIHdyaXRlLXJldmVydCBwYXRocyBkcm9wIG91dCwgYmVjYXVzZVxuICAgKiBib3RoIGNvbXBhcmUgZXF1YWwgdG8gYmFzZS4gVGhpcyBpcyBhIHNpbmdsZSBuZXQtZGVsdGEgZGlmZiBhdCBjb21taXQgdGltZVxuICAgKiDigJQgb25lIGRlZXAgY29tcGFyZSBwZXIgdG91Y2hlZCBwYXRoLCBPKGNoYW5nZWQgc3RhdGUpLCBwYWlkIG9uY2UgcGVyIHN0YWdlXG4gICAqIChOT1QgcGVyIHdyaXRlKS4gQSBuYWl2ZSBwZXItd3JpdGUgZGVlcC1lcXVhbCBza2lwIHdvdWxkIGJlIG1vcmUgZXhwZW5zaXZlXG4gICAqIGFuZCB3b3VsZCBzdGlsbCBtaXNzIHdyaXRlLXJldmVydCAodGhlIGludGVybWVkaWF0ZSB3cml0ZSBkaWZmZXJzIGZyb20gdGhlXG4gICAqIHZhbHVlIHByZXNlbnQgYXQgdGhlIG1vbWVudCBvZiB3cml0aW5nKS5cbiAgICpcbiAgICog4pSA4pSAIFRXTyBIT05FU1QgVElFUlMgKGJ5IGRlc2lnbiDigJQgZG8gbm90IFwidW5pZnlcIiB0aGVtKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgICogICDigKIgY29tbWl0IChoZXJlKSAgID0gQ0hBTkdFLWxldmVsIOKAlCB0cnV0aGZ1bCBuZXQgZGVsdGEuIEZlZWRzIHRoZSBjb21taXRcbiAgICogICAgICAgICAgICAgICAgICAgICAgIGxvZywgY2F1c2FsIGNoYWluLCBuYXJyYXRpdmUsIGFuZCB0aGUgbGVucyBoaWdobGlnaHQuXG4gICAqICAg4oCiIGBvbldyaXRlYCBldmVudCA9IE9QLWxldmVsIOKAlCBmaXJlcyBvbiBFVkVSWSB3cml0ZSBhdHRlbXB0IHJlZ2FyZGxlc3Mgb2ZcbiAgICogICAgICAgICAgICAgICAgICAgICAgIG5ldCBjaGFuZ2UuIEZlZWRzIG1ldHJpY3MgLyBiZWhhdmlvdXJhbCBvYnNlcnZhYmlsaXR5XG4gICAqICAgICAgICAgICAgICAgICAgICAgICAoYSBkZWJ1Z2dlciB3YW50cyB0byBzZWUgXCJ3cm90ZSAyLCB0aGVuIHJldmVydGVkXCIpLlxuICAgKiBgb25Xcml0ZWAgaXMgdW5jaGFuZ2VkIGJ5IHRoaXMgbWV0aG9kOyBvbmx5IHRoZSBDT01NSVQgYmVjb21lcyBjaGFuZ2Utb25seS5cbiAgICpcbiAgICog4pSA4pSAIEVNUFRZIENPTU1JVFMgQVJFIElOVEVOVElPTkFMIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgKiBBIHN0YWdlIHRoYXQgbmV0cyBubyBjaGFuZ2UgY29tbWl0cyBhbiBFTVBUWSBwYXRjaCDigJQgTk9UIG5vdGhpbmcuXG4gICAqIHtAbGluayBTdGFnZUNvbnRleHQuY29tbWl0fSBzdGlsbCByZWNvcmRzIHRoZSBidW5kbGUgdW5jb25kaXRpb25hbGx5LCBzb1xuICAgKiBldmVyeSBleGVjdXRlZCBzdGFnZSByZW1haW5zIGEgdGltZS10cmF2ZWwgY3Vyc29yIHN0b3AgKGl0cyBgcnVudGltZVN0YWdlSWRgXG4gICAqIG1hcmtlciBpcyBwcmVzZXJ2ZWQpOyBvbmx5IGl0cyBQQVRDSCBpcyBlbXB0eS4gVGhpcyBpcyB3aGF0IGtlZXBzIHRoZVxuICAgKiBjb21taXQtaW5kZXhlZCBzbGlkZXIgc3RhYmxlIHdoaWxlIG1ha2luZyB0aGUgaGlnaGxpZ2h0IHRydXRoZnVsLlxuICAgKlxuICAgKiDilIDilIAgS05PV04gTElNSVRBVElPTlMgLyBGVVRVUkUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gICAqICAg4oCiIEV4cGxpY2l0IGtleSBERUxFVElPTiB1bmRlciB0aGUgZGVmYXVsdCAnZnVsbCcgbW9kZSBpcyBzdGlsbFxuICAgKiAgICAgZmxhdHRlbmVkIHRvIHNldC1vZi1gdW5kZWZpbmVkYCAoYSByZW1vdmVkIGtleSBjYW5ub3QgYmUgZXhwcmVzc2VkXG4gICAqICAgICBpbiBNZW1vcnlQYXRjaCBhbG9uZSkuIENMT1NFRCB1bmRlciBgY29tbWl0VmFsdWVzOiAnZGVsdGEnYCAoIzEzYy1CKTpcbiAgICogICAgIHtAbGluayBkZWxldGV9IHN0YWdlcyBhIGRpc3RpbmN0IG9wIGFuZCB0aGUgYnVuZGxlIGNhcnJpZXMgYSByZWFsXG4gICAqICAgICBgZGVsZXRlYCB0cmFjZSB2ZXJiIHdob3NlIHJlcGxheSByZW1vdmVzIHRoZSBrZXkuXG4gICAqICAg4oCiIEFycmF5LW1lcmdlIGRlZHVwIGluIHtAbGluayBkZWVwU21hcnRNZXJnZX0gc3RpbGwgdXNlcyByZWZlcmVuY2UgZXF1YWxpdHlcbiAgICogICAgIChgbmV3IFNldGApLCBzbyBkZWVwLWVxdWFsICpvYmplY3RzKiBpbiBhIG1lcmdlZCBhcnJheSBhcmUgbm90IGRlZHVwZWQuXG4gICAqICAgICBPcnRob2dvbmFsIHRvIHRoaXMgY2hhbmdlOyB0cmFja2VkIHNlcGFyYXRlbHkuXG4gICAqXG4gICAqIFJlc2V0cyB0aGUgYnVmZmVyIHRvIGVtcHR5IHN0YXRlIGFmdGVyIGNvbW1pdC5cbiAgICovXG4gIGNvbW1pdCgpOiB7XG4gICAgb3ZlcndyaXRlOiBNZW1vcnlQYXRjaDtcbiAgICB1cGRhdGVzOiBNZW1vcnlQYXRjaDtcbiAgICByZWRhY3RlZFBhdGhzOiBTZXQ8c3RyaW5nPjtcbiAgICB0cmFjZTogVHJhY2VFbnRyeVtdO1xuICB9IHtcbiAgICBjb25zdCByb3dzID0gdGhpcy5jb21taXRWYWx1ZXMgPT09ICdkZWx0YScgPyB0aGlzLnRvRGVsdGFQYXlsb2FkKCkgOiB0aGlzLnRvQ2hhbmdlT25seVBheWxvYWQoKTtcbiAgICBjb25zdCByZWRhY3RlZFBhdGhzID0gdGhpcy5zdXJ2aXZpbmdSZWRhY3RlZFBhdGhzKG5ldyBTZXQocm93cy50cmFjZS5tYXAoKHQpID0+IHQucGF0aCkpKTtcbiAgICAvLyBUaGUgYnVuZGxlJ3Mga2V5IG9yZGVyIGlzIGByZWNvcmRDb21taXRgJ3M7IGEgZGlyZWN0IGNhbGxlciBrZWVwcyB0aGlzIHNhbWUgb3JkZXIuXG4gICAgY29uc3QgcGF5bG9hZCA9IHsgb3ZlcndyaXRlOiByb3dzLm92ZXJ3cml0ZSwgdXBkYXRlczogcm93cy51cGRhdGVzLCByZWRhY3RlZFBhdGhzLCB0cmFjZTogcm93cy50cmFjZSB9O1xuXG4gICAgdGhpcy5vdmVyd3JpdGVQYXRjaCA9IHt9O1xuICAgIHRoaXMudXBkYXRlUGF0Y2ggPSB7fTtcbiAgICB0aGlzLm9wVHJhY2UubGVuZ3RoID0gMDtcbiAgICB0aGlzLnJlZGFjdGVkUGF0aHMuY2xlYXIoKTtcbiAgICB0aGlzLmhlbGRSZWZzLmNsZWFyKCk7XG4gICAgdGhpcy53b3JraW5nQ29weSA9IHt9O1xuICAgIHRoaXMub3duZWQgPSBuZXcgV2Vha1NldCgpO1xuICAgIHRoaXMub3duZWQuYWRkKHRoaXMud29ya2luZ0NvcHkpO1xuICAgIHRoaXMuc3RhZ2VkID0gbmV3IFdlYWtTZXQoKTtcbiAgICB0aGlzLnByaXZhdGVUcmVlcyA9IG5ldyBXZWFrU2V0KCk7XG4gICAgdGhpcy5zdGFnZWRNZXJnZXMgPSAwO1xuICAgIHRoaXMubmVzdGVkT3BzID0gMDtcblxuICAgIHJldHVybiBwYXlsb2FkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYnVpbGQgb3ZlcndyaXRlIC8gdXBkYXRlcyAvIHRyYWNlIGtlZXBpbmcgT05MWSBwYXRocyB3aG9zZSBmaW5hbCB2YWx1ZVxuICAgKiBkaWZmZXJzIGZyb20gdGhlIGJhc2UgdmFsdWUg4oCUIGkuZS4gdGhlIHN0YWdlJ3MgbmV0IGNoYW5nZS4gU2VlXG4gICAqIHtAbGluayBUcmFuc2FjdGlvbkJ1ZmZlci5jb21taXR9IGZvciB0aGUgcmF0aW9uYWxlLlxuICAgKlxuICAgKiBQYXRocyBhcmUgY29tcGFyZWQgYXQgdGhlIGV4YWN0IGdyYW51bGFyaXR5IHRoZXkgd2VyZSB3cml0dGVuIChlYWNoIHRyYWNlXG4gICAqIGVudHJ5J3MgcGF0aCksIGFnYWluc3QgYHdvcmtpbmdDb3B5YCAoZmluYWwpIHZzIGBiYXNlU25hcHNob3RgIChzdGFydCkuXG4gICAqIFN1cnZpdmluZyBgc2V0YCBwYXRocyBjb3B5IHRoZWlyIGZpbmFsIHZhbHVlIGZyb20gYG92ZXJ3cml0ZVBhdGNoYDtcbiAgICogc3Vydml2aW5nIGBtZXJnZWAgcGF0aHMgY29weSB0aGVpciBhY2N1bXVsYXRlZCBkZWx0YSBmcm9tIGB1cGRhdGVQYXRjaGAsXG4gICAqIGtlZXBpbmcgdGhlIHNldC12cy1tZXJnZSB2ZXJiIOKAlCBhbmQgdGhlIHJlc3VsdCBpcyBBRE1JVFRFRCAoe0BsaW5rIGFkbWl0fSk6XG4gICAqIGEgZmFtaWx5IG9mIHJvd3Mgd2hvc2UgcmVwbGF5IGRvZXMgbm90IGdpdmUgYmFjayB3aGF0IHRoZSBzdGFnZSByZWFkIGlzXG4gICAqIHJlY29yZGVkIGFzIGBzZXRgIHJvd3Mgb2YgdGhlIHJlYWQtYmFjayBpbnN0ZWFkICg5LjMwLjApLlxuICAgKlxuICAgKiBUaGlzIGlzIHRoZSBERUZBVUxUIChgY29tbWl0VmFsdWVzOiAnZnVsbCdgKSBwYXlsb2FkLCBpbmNsdWRpbmcgdGhlXG4gICAqIGhpc3RvcmljYWwgZmxhdHRlbmluZyBvZiBzdGFnZWQgYGRlbGV0ZWAgb3BzIGludG8gYHNldGAtb2YtYHVuZGVmaW5lZGBcbiAgICogdHJhY2UgZW50cmllcy4gVGhlIGRlbHRhIGVuY29kaW5nIGxpdmVzIGluIHtAbGluayB0b0RlbHRhUGF5bG9hZH0uXG4gICAqXG4gICAqIFdvcmssIG5vdCBieXRlcyAoOS4yMi4xKTogdGhlIG5ldC1jaGFuZ2UgdmVyZGljdCBpcyBwYWlkIG9uY2UgcGVyIFBBVEhcbiAgICogYW5kIHRoZSBjbG9uZSBvbmNlIHBlciBDT05TRUNVVElWRSBydW4gb2Ygb3BzIG9uIGEgcGF0aCwgbm90IG9uY2UgcGVyIG9wXG4gICAqIOKAlCBzZWUgdGhlIHR3byBtZW1vcyBpbnNpZGUuIFBpbm5lZCBieVxuICAgKiB0ZXN0L2xpYi9tZW1vcnkvc2NlbmFyaW8vcmVwZWF0ZWQtcGF0aC1ieXRlLWlkZW50aXR5LnRlc3QudHMgYWdhaW5zdCB0aGVcbiAgICogOS4yMi4wIGJ5dGVzLiBTaW5jZSA5LjIzLjAgdGhhdCBjbG9uZSBpcyBUSEUgY2xvbmU6IHRoZSBwYXRjaCB0cmVlcyBob2xkXG4gICAqIHRoZSBjYWxsZXIncyByZWZlcmVuY2VzIChzZWUgdGhlIGNsYXNzIGhlYWRlciksIHNvIHRoaXMgbG9vcCBpcyB0aGUgb25lXG4gICAqIHBsYWNlIHRoZSByZWNvcmQgaXMgZGV0YWNoZWQgZnJvbSB0aGVtLlxuICAgKi9cbiAgcHJpdmF0ZSB0b0NoYW5nZU9ubHlQYXlsb2FkKCk6IFJvd3Mge1xuICAgIHJldHVybiB0aGlzLmFkbWl0KChsb3NzeSkgPT4gdGhpcy5jaGFuZ2VPbmx5Um93cyhsb3NzeSkpO1xuICB9XG5cbiAgLyoqIFRoZSAnZnVsbCcgcm93czsgYSBmYW1pbHkgaW4gYGxvc3N5YCBpcyB3cml0dGVuIGFzIGl0cyByZWFkLWJhY2ssIGF0IGl0cyBsYXN0IHRvdWNoICh7QGxpbmsgZW1pdFJlYWRCYWNrfSkuICovXG4gIHByaXZhdGUgY2hhbmdlT25seVJvd3MobG9zc3k6IExvc3N5IHwgdW5kZWZpbmVkKTogUm93cyB7XG4gICAgY29uc3Qgcm93czogUm93cyA9IHsgb3ZlcndyaXRlOiB7fSwgdXBkYXRlczoge30sIHRyYWNlOiBbXSB9O1xuICAgIGNvbnN0IHsgb3ZlcndyaXRlLCB1cGRhdGVzLCB0cmFjZSB9ID0gcm93cztcbiAgICAvLyBQZXIgUEFUSCwgZGVjaWRlZCBvbmNlICg5LjIyLjEpOiBiYXNlIGFuZCBmaW5hbCB2YWx1ZSBhcmUgZml4ZWQgYXRcbiAgICAvLyBjb21taXQsIHNvIGV2ZXJ5IGxhdGVyIG9wIG9uIGEgcGF0aCBnZXRzIHRoZSB2ZXJkaWN0IGl0cyBmaXJzdCBvcCBnb3QuXG4gICAgLy8gYHVuZGVmaW5lZGAgPSBub3QgeWV0IGRlY2lkZWQ7IHRoZSBzdXJ2aXZpbmcgcGF0aHMgYXJlIHRoZSBgdHJ1ZWAga2V5cy5cbiAgICBjb25zdCBzdXJ2aXZlcyA9IG5ldyBNYXA8c3RyaW5nLCBib29sZWFuPigpO1xuICAgIC8vIFRoZSBwYXRoIHRoZSBMQVNUIHN1cnZpdmluZyBvcCBjb3BpZWQgaW50byBlYWNoIHBhdGNoIHRyZWUgKDkuMjIuMSkuXG4gICAgLy8gVGhlIHZhbHVlIGF0IGEgcGF0aCBpcyBmaXhlZCBhdCBjb21taXQsIHNvIGFuIG9wIHdob3NlIHByZWRlY2Vzc29yIG9uXG4gICAgLy8gdGhlIFNBTUUgdHJlZSBhbHJlYWR5IGNvcGllZCB0aGF0IHBhdGggd291bGQgd3JpdGUgdGhlIHNhbWUgYnl0ZXMgb3ZlclxuICAgIC8vIHRoZSBzYW1lIGtleSDigJQgaXQga2VlcHMgaXRzIHRyYWNlIHJvdyAodGhlIGxvZyBpcyBieXRlLWlkZW50aWNhbCkgYW5kXG4gICAgLy8gcGF5cyBubyBzZWNvbmQgY2xvbmUuIFRoZSA5LjIyLjAgZWxlbWVudC13cml0ZSBmdW5uZWwgc3RhZ2VzIE5cbiAgICAvLyB3aG9sZS1hcnJheSBzZXRzIG9uIE9ORSBwYXRoOyB0aGlzIGlzIHdoYXQgbWFrZXMgdGhhdCBjb21taXQgTyhOKVxuICAgIC8vIGluc3RlYWQgb2YgTyhOIMOXIG9wcykuIENPTlNFQ1VUSVZFIG9ubHkg4oCUIGFuIG9wIG9uIGFub3RoZXIgcGF0aCBpblxuICAgIC8vIGJldHdlZW4gbWF5IGhhdmUgY29lcmNlZCBvciBncm93biB0aGlzIG9uZSdzIGNvbnRhaW5lciAoYSBkZXNjZW5kYW50XG4gICAgLy8gYG5hdGl2ZVNldGAgdGhyb3VnaCBhIHByaW1pdGl2ZSwgYSBga2V5OiB1bmRlZmluZWRgIHNoZWxsKSBhbmQgdGhlXG4gICAgLy8gcmUtY29weSBpcyB3aGF0IHJlcGFpcnMgaXQ7IGEgYG1lcmdlYCBiZXR3ZWVuIHR3byBzZXRzIHRvdWNoZXMgdGhlXG4gICAgLy8gb3RoZXIgdHJlZSBhbmQgZG9lcyBub3QgY291bnQuIFNhbWUgbGF3IGFzIGBzdXBlcnNlZGVkQnlOZXh0U2V0YC5cbiAgICBsZXQgbGFzdFNldFBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBsZXQgbGFzdE1lcmdlUGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm9wVHJhY2UubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IG9wID0gdGhpcy5vcFRyYWNlW2ldO1xuICAgICAgY29uc3QgZmFtaWx5ID0gbG9zc3k/LmZhbWlsaWVzLmdldChsb3NzeS5yb290T2YuZ2V0KG9wLnBhdGgpIGFzIHN0cmluZyk7XG4gICAgICBpZiAoZmFtaWx5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKGkgPT09IGZhbWlseS5zbG90KSB7XG4gICAgICAgICAgdGhpcy5lbWl0UmVhZEJhY2soZmFtaWx5LCByb3dzLCAnZnVsbCcpO1xuICAgICAgICAgIGxhc3RTZXRQYXRoID0gbGFzdE1lcmdlUGF0aCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGxldCBrZWVwID0gc3Vydml2ZXMuZ2V0KG9wLnBhdGgpO1xuICAgICAgaWYgKGtlZXAgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBrZWVwID0gdGhpcy5jaGFuZ2VkU2luY2VCYXNlKG9wLnBhdGguc3BsaXQoREVMSU0pKTtcbiAgICAgICAgc3Vydml2ZXMuc2V0KG9wLnBhdGgsIGtlZXApO1xuICAgICAgfVxuICAgICAgaWYgKCFrZWVwKSBjb250aW51ZTsgLy8gbm8tb3Agb3Igd3JpdGUtdGhlbi1yZXZlcnQg4oaSIG5vIG5ldCBjaGFuZ2VcblxuICAgICAgdHJhY2UucHVzaChmbGF0dGVuZWRUcmFjZVJvdyhvcCkpO1xuICAgICAgaWYgKG9wLnZlcmIgPT09ICdtZXJnZScpIHtcbiAgICAgICAgaWYgKGxhc3RNZXJnZVBhdGggPT09IG9wLnBhdGgpIGNvbnRpbnVlO1xuICAgICAgICBsYXN0TWVyZ2VQYXRoID0gb3AucGF0aDtcbiAgICAgICAgY29uc3Qgc2VnbWVudHMgPSBvcC5wYXRoLnNwbGl0KERFTElNKTtcbiAgICAgICAgX3NldCh1cGRhdGVzLCBzZWdtZW50cywgc3RydWN0dXJlZENsb25lKF9nZXQodGhpcy51cGRhdGVQYXRjaCwgc2VnbWVudHMpKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAobGFzdFNldFBhdGggPT09IG9wLnBhdGgpIGNvbnRpbnVlO1xuICAgICAgICBsYXN0U2V0UGF0aCA9IG9wLnBhdGg7XG4gICAgICAgIGNvbnN0IHNlZ21lbnRzID0gb3AucGF0aC5zcGxpdChERUxJTSk7XG4gICAgICAgIF9zZXQob3ZlcndyaXRlLCBzZWdtZW50cywgc3RydWN0dXJlZENsb25lKF9nZXQodGhpcy5vdmVyd3JpdGVQYXRjaCwgc2VnbWVudHMpKSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByb3dzO1xuICB9XG5cbiAgLyoqXG4gICAqIERlbHRhLWVuY29kZWQgcGF5bG9hZCAoYGNvbW1pdFZhbHVlczogJ2RlbHRhJ2AsICMxM2MtQikg4oCUIHNhbWUgbmV0LWNoYW5nZVxuICAgKiBmaWx0ZXIgYXMge0BsaW5rIHRvQ2hhbmdlT25seVBheWxvYWR9LCB0aHJlZSBlbmNvZGluZyBkaWZmZXJlbmNlczpcbiAgICpcbiAgICogMS4gKipPbmUgdHJhY2UgZW50cnkgcGVyIHN1cnZpdmluZyBwYXRoKiogKHRoZSDCpzIuNSBkZWR1cCBydWxlIOKAlCBgYXBwZW5kYFxuICAgKiAgICBpcyBOT1QgaWRlbXBvdGVudCBvbiByZXBsYXksIHNvIGR1cGxpY2F0ZSBlbnRyaWVzIHdvdWxkIG11bHRpcGx5XG4gICAqICAgIHRhaWxzKS4gVGhlIHZlcmIgaXMgcmVzb2x2ZWQgZnJvbSB0aGUgcGF0aCdzIG9wIG1peCArIGJhc2XihpJmaW5hbFxuICAgKiAgICByZWxhdGlvbnNoaXA7IGVudHJpZXMgYXJlIG9yZGVyZWQgYnkgZWFjaCBwYXRoJ3MgTEFTVCB0b3VjaCxcbiAgICogICAgcHJlc2VydmluZyBsYXN0LXdyaXRlci13aW5zIGZvciBuZXN0ZWQvb3ZlcmxhcHBpbmcgcGF0aHMuXG4gICAqIDIuICoqVmVyYiByZXNvbHV0aW9uIHBlciBwYXRoKiog4oCUIGZvciBhIHBhdGggd2l0aCBOTyBzdXJ2aXZpbmcgcmVsYXRpdmVcbiAgICogICAgKHNlZSAzKTpcbiAgICogICAgLSBsYXN0IG9wIGAnZGVsZXRlJ2AgQU5EIGZpbmFsIHZhbHVlIGdvbmUg4oaSIGBkZWxldGVgICh0aGUgcGF0aCBzdGF5c1xuICAgKiAgICAgIGVudW1lcmF0ZWQgaW4gYG92ZXJ3cml0ZWAgd2l0aCBgdW5kZWZpbmVkYCBmb3Iga2V5LXNldCBjb25zdW1lcnMpLlxuICAgKiAgICAgIFJlcXVpcmVzIHRoZSBwYXJlbnQgdG8gYmUgYSByZWFsIGNvbnRhaW5lciBpbiB0aGUgYmFzZSDigJQgcmVwbGF5IHVzZXNcbiAgICogICAgICBgbmF0aXZlRGVsZXRlYCwgd2hpY2ggaXMgaW5lcnQgb24gYSBwcmltaXRpdmUvYWJzZW50IHBhcmVudCwgd2hlcmVhc1xuICAgKiAgICAgIHRoZSBgJ2Z1bGwnYCBmbGF0dGVuaW5nIChgX3NldGAgb2YgYHVuZGVmaW5lZGApIENPRVJDRVMgdGhhdCBwYXJlbnRcbiAgICogICAgICBpbnRvIGFuIG9iamVjdDsgd2hlbiB0aGV5IHdvdWxkIGRpc2FncmVlIHdlIGtlZXAgdGhlIGZsYXR0ZW5pbmc7XG4gICAqICAgIC0gT05MWSBgJ21lcmdlJ2Agb3BzIOKGkiBgbWVyZ2VgIHdpdGggdGhlIGFjY3VtdWxhdGVkIGB1cGRhdGVQYXRjaGBcbiAgICogICAgICBkZWx0YTtcbiAgICogICAgLSBvdGhlcndpc2UgKGBzZXRgL21peGVkKTogdGhlIHZhbHVlIHRoZSBzdGFnZSdzICdmdWxsJyByb3dzIGdpdmUgdGhlXG4gICAqICAgICAgcGF0aCAoe0BsaW5rIGZ1bGxSb3dzVmFsdWV9KS4gSWYgYmFzZSBhbmQgdGhhdCB2YWx1ZSBhcmUgYXJyYXlzIGFuZFxuICAgKiAgICAgIGJhc2UgaXMgYSBTVFJJQ1QgUFJFRklYIOKGkiBgYXBwZW5kYCBzdG9yaW5nIG9ubHkgdGhlIHRhaWw7IGVsc2UgYHNldGBcbiAgICogICAgICBzdG9yaW5nIHRoZSBmdWxsIHZhbHVlLlxuICAgKiAzLiAqKk9WRVJMQVAgRkFNSUxJRVMgdGFrZSB0aGUgZnVsbC12YWx1ZSBmYWxsYmFjay4qKiBgb3ZlcndyaXRlYCAvXG4gICAqICAgIGB1cGRhdGVzYCBhcmUgbmVzdGVkIHBhdGggVFJFRVMsIHNvIHR3byBzdXJ2aXZpbmcgcGF0aHMgd2hlcmUgb25lIGlzXG4gICAqICAgIGFuIGFuY2VzdG9yIG9mIHRoZSBvdGhlciAoYGFgIGFuZCBgYS5wYCkgc2hhcmUgc3RvcmFnZS4gRGVsdGEnc1xuICAgKiAgICBwZXItcGF0aCBlbmNvZGluZ3Mgd291bGQgY2xvYmJlciBlYWNoIG90aGVyIHRoZXJlIChhbiBgYXBwZW5kYFxuICAgKiAgICBhbmNlc3RvciBzdG9yZXMgb25seSBhIFRBSUwsIGEgYGRlbGV0ZWAgYW5jZXN0b3IgYHVuZGVmaW5lZGApLCBzbyBldmVyeVxuICAgKiAgICBwYXRoIHRoYXQgaGFzIGEgc3Vydml2aW5nIGFuY2VzdG9yL2Rlc2NlbmRhbnQgaXMgY29tbWl0dGVkIGFzIGEgcGxhaW5cbiAgICogICAgYHNldGAgb2YgdGhlIHZhbHVlIHRoZSAnZnVsbCcgcm93cyBnaXZlIGl0LCBhbmQgdGhlIGZhbWlseSdzXG4gICAqICAgIHNoYWxsb3dlc3QgcGF0aCAod2hvc2Ugc2V0IGNvdmVycyB0aGUgd2hvbGUgc3VidHJlZSkgaXMgZW1pdHRlZCBMQVNULlxuICAgKlxuICAgKiBUaGUgcmVzdWx0IGlzIEFETUlUVEVEICh7QGxpbmsgYWRtaXR9KSBsaWtlIHRoZSAnZnVsbCcgcGF5bG9hZDogYSBjb21wYWN0XG4gICAqIHJvdyBpcyBrZXB0IG9ubHkgd2hlcmUgdGhlIGJ1bmRsZSBwcm92YWJseSBmb2xkcyBiYWNrLCBhbmQgYSBmYW1pbHkgdGhhdFxuICAgKiBkb2VzIG5vdCBpcyByZWNvcmRlZCBhcyB3aGF0IHRoZSBzdGFnZSByZWFkLiBTbyBib3RoIGVuY29kaW5ncyBjb21taXQgdGhlXG4gICAqIHZhbHVlIHRoZSBzdGFnZSByZWFkOyBiZWZvcmUgOS4zMC4wIHRoZXkgc2hhcmVkIGEgcmVwbGF5IHRoYXQgZGlkIG5vdFxuICAgKiAoYHJlcGxheVBhdGhWZXJic2AgLyBgcmVwbGF5RmFtaWx5VmVyYnNgLCBkZWxldGVkKS5cbiAgICovXG4gIHByaXZhdGUgdG9EZWx0YVBheWxvYWQoKTogUm93cyB7XG4gICAgY29uc3QgZnVsbFZhbHVlQXQgPSB0aGlzLmZ1bGxSb3dzVmFsdWUoKTtcbiAgICByZXR1cm4gdGhpcy5hZG1pdCgobG9zc3kpID0+IHRoaXMuZGVsdGFSb3dzKGxvc3N5LCBmdWxsVmFsdWVBdCkpO1xuICB9XG5cbiAgLyoqIFRoZSBkZWx0YSByb3dzOyBhIGZhbWlseSBpbiBgbG9zc3lgIGlzIHdyaXR0ZW4gYXMgaXRzIHJlYWQtYmFjaywgYXQgaXRzIGxhc3QgdG91Y2ggKHtAbGluayBlbWl0UmVhZEJhY2t9KS4gKi9cbiAgcHJpdmF0ZSBkZWx0YVJvd3MobG9zc3k6IExvc3N5IHwgdW5kZWZpbmVkLCBmdWxsVmFsdWVBdDogKHNlZ21lbnRzOiBzdHJpbmdbXSkgPT4gdW5rbm93bik6IFJvd3Mge1xuICAgIGNvbnN0IHJvd3M6IFJvd3MgPSB7IG92ZXJ3cml0ZToge30sIHVwZGF0ZXM6IHt9LCB0cmFjZTogW10gfTtcbiAgICBjb25zdCB7IG92ZXJ3cml0ZSwgdXBkYXRlcywgdHJhY2UgfSA9IHJvd3M7XG4gICAgY29uc3QgaW5Mb3NzeSA9IChwYXRoOiBzdHJpbmcpID0+IGxvc3N5Py5mYW1pbGllcy5oYXMobG9zc3kucm9vdE9mLmdldChwYXRoKSBhcyBzdHJpbmcpID09PSB0cnVlO1xuICAgIGNvbnN0IHN1cnZpdm9ycyA9IHRoaXMubmV0Q2hhbmdlU3Vydml2b3JzKHRoaXMub3BzQnlQYXRoKCkpLmZpbHRlcigocykgPT4gIWluTG9zc3kocy5wYXRoKSk7XG4gICAgY29uc3QgeyByb290T2YsIGJ5Um9vdCB9ID0gZ3JvdXBJbnRvRmFtaWxpZXMoc3Vydml2b3JzLCBuZXcgU2V0KHN1cnZpdm9ycy5tYXAoKHMpID0+IHMucGF0aCkpKTtcblxuICAgIC8vIFRIRSBWRVJCIENIT0lDRSDigJQgdGhlIGRlbHRhIGVuY29kZXIgcGlja3MgYSB2ZXJiIHBlciBwYXRoOyB0aGUgVkFMVUVTXG4gICAgLy8gaXQgZW5jb2RlcyBjb21lIGZyb20gdGhlIG9uZSByZXBsYXkgKGBmdWxsVmFsdWVBdGApLCBuZXZlciBhIHJlcGxpY2Egb2ZcbiAgICAvLyB0aGUgdmVyYiBsYXcgKDkuMzAuMDogQ0xBVURFLm1kJ3MgdmVyYi1zd2l0Y2ggcmVwbGljYXMgbG9zdCB0d28gaGVyZSkuXG4gICAgY29uc3QgZW1pdCA9IChzOiBTdXJ2aXZvcik6IHZvaWQgPT4ge1xuICAgICAgY29uc3QgeyBwYXRoLCBzZWdtZW50cywgdmVyYnMsIGJlZm9yZSB9ID0gcztcbiAgICAgIGNvbnN0IHByb3YgPSBwcm92ZW5hbmNlKHMucmVhZEtleXMpO1xuICAgICAgaWYgKChieVJvb3QuZ2V0KHJvb3RPZi5nZXQocGF0aCkgYXMgc3RyaW5nKSBhcyBTdXJ2aXZvcltdKS5sZW5ndGggPiAxKSB7XG4gICAgICAgIC8vIFJ1bGUgMyDigJQgb25lIGNvaGVyZW50IHRyZWU6IGV2ZXJ5IG1lbWJlciBhIHNldCBvZiBpdHMgdmFsdWUuXG4gICAgICAgIHRyYWNlLnB1c2goeyBwYXRoLCB2ZXJiOiAnc2V0JywgLi4ucHJvdiB9KTtcbiAgICAgICAgX3NldChvdmVyd3JpdGUsIHNlZ21lbnRzLCBzdHJ1Y3R1cmVkQ2xvbmUoZnVsbFZhbHVlQXQoc2VnbWVudHMpKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGxhc3RWZXJiID0gdmVyYnNbdmVyYnMubGVuZ3RoIC0gMV07XG4gICAgICBpZiAobGFzdFZlcmIgPT09ICdkZWxldGUnICYmIHMuYWZ0ZXIgPT09IHVuZGVmaW5lZCAmJiB0aGlzLmRlbGV0ZVJlcGxheXNBc0ZsYXR0ZW5pbmcoc2VnbWVudHMpKSB7XG4gICAgICAgIC8vIFJlYWwgZGVsZXRpb24g4oCUIHJlcGxheSByZW1vdmVzIHRoZSBrZXkuIEtlZXAgdGhlIHBhdGggZW51bWVyYXRlZFxuICAgICAgICAvLyBpbiBgb3ZlcndyaXRlYCAodW5kZWZpbmVkKSBzbyBPYmplY3Qua2V5cyBjb25zdW1lcnMgc2VlIGl0LlxuICAgICAgICB0cmFjZS5wdXNoKHsgcGF0aCwgdmVyYjogJ2RlbGV0ZScsIC4uLnByb3YgfSk7XG4gICAgICAgIF9zZXQob3ZlcndyaXRlLCBzZWdtZW50cywgdW5kZWZpbmVkKTtcbiAgICAgIH0gZWxzZSBpZiAodmVyYnMuZXZlcnkoKHYpID0+IHYgPT09ICdtZXJnZScpKSB7XG4gICAgICAgIHRyYWNlLnB1c2goeyBwYXRoLCB2ZXJiOiAnbWVyZ2UnLCAuLi5wcm92IH0pO1xuICAgICAgICBfc2V0KHVwZGF0ZXMsIHNlZ21lbnRzLCBzdHJ1Y3R1cmVkQ2xvbmUoX2dldCh0aGlzLnVwZGF0ZVBhdGNoLCBzZWdtZW50cykpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHB1c2hWYWx1ZVJvdyhyb3dzLCBwYXRoLCBzZWdtZW50cywgYmVmb3JlLCBmdWxsVmFsdWVBdChzZWdtZW50cyksIHByb3YsIHRoaXMubWFya2VkQmVsb3cocGF0aCkpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBBIGZhbWlseSB0aGF0IGRpZCBub3QgZm9sZCBiYWNrIHRha2VzIGl0cyBwbGFjZSBieSBpdHMgbGFzdCB0b3VjaC5cbiAgICBjb25zdCBwZW5kaW5nID0gbG9zc3kgPT09IHVuZGVmaW5lZCA/IFtdIDogWy4uLmxvc3N5LmZhbWlsaWVzLnZhbHVlcygpXS5zb3J0KChhLCBiKSA9PiBhLnNsb3QgLSBiLnNsb3QpO1xuICAgIGxldCBuZXh0ID0gMDtcbiAgICBjb25zdCBmbHVzaEJlZm9yZSA9ICh0b3VjaDogbnVtYmVyKTogdm9pZCA9PiB7XG4gICAgICB3aGlsZSAobmV4dCA8IHBlbmRpbmcubGVuZ3RoICYmIHBlbmRpbmdbbmV4dF0uc2xvdCA8IHRvdWNoKSB0aGlzLmVtaXRSZWFkQmFjayhwZW5kaW5nW25leHQrK10sIHJvd3MsICdkZWx0YScpO1xuICAgIH07XG4gICAgZW1pdEluRmFtaWx5T3JkZXIoc3Vydml2b3JzLCByb290T2YsIGJ5Um9vdCwgZW1pdCwgZmx1c2hCZWZvcmUpO1xuICAgIGZsdXNoQmVmb3JlKEluZmluaXR5KTtcbiAgICByZXR1cm4gcm93cztcbiAgfVxuXG4gIC8vIOKUgOKUgCBUaGUgYWRtaXR0ZWQgcmVjb3JkICg5LjMwLjApIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKlxuICAgKiBUSEUgQURNSVNTSU9OIOKAlCBhIGNvbW1pdCBpcyBhZG1pdHRlZCBvbmx5IGlmIGl0cyBidW5kbGUgZm9sZHMgYmFjayB0byB0aGVcbiAgICogc3RhZ2UncyByZWFkLXlvdXItd3JpdGVzIHZpZXcgYXQgZXZlcnkgcGF0aCB0aGUgc3RhZ2UgdG91Y2hlZC4gYGJ1aWxkYFxuICAgKiBsYXlzIHRoZSByb3dzIG91dCAob25lIGVuY29kZXI6IGAnZnVsbCdgIG9yIGAnZGVsdGEnYCk7IHRoZSBjYW5kaWRhdGUgaXNcbiAgICogY2hlY2tlZCAoe0BsaW5rIGxvc3N5RmFtaWxpZXN9KSwgYW5kIHdoZW4gc29tZSBmYW1pbHkncyByb3dzIGRvIG5vdCBmb2xkXG4gICAqIGJhY2sgdGhlIHJvd3MgYXJlIGxhaWQgb3V0IGFnYWluIHdpdGggdGhvc2UgZmFtaWxpZXMgd3JpdHRlbiBhcyB3aGF0IHRoZVxuICAgKiBzdGFnZSByZWFkICh7QGxpbmsgZW1pdFJlYWRCYWNrfSkg4oCUIGV2ZXJ5IG90aGVyIGZhbWlseSdzIGJ5dGVzIGV4YWN0bHkgYXNcbiAgICogdGhlIGZpcnN0IGxheW91dCBtYWRlIHRoZW0uXG4gICAqL1xuICBwcml2YXRlIGFkbWl0KGJ1aWxkOiAobG9zc3k6IExvc3N5IHwgdW5kZWZpbmVkKSA9PiBSb3dzKTogUm93cyB7XG4gICAgY29uc3QgY2FuZGlkYXRlID0gYnVpbGQodW5kZWZpbmVkKTtcbiAgICBjb25zdCBsb3NzeSA9IHRoaXMubG9zc3lGYW1pbGllcyhjYW5kaWRhdGUpO1xuICAgIHJldHVybiBsb3NzeSA9PT0gdW5kZWZpbmVkID8gY2FuZGlkYXRlIDogYnVpbGQobG9zc3kpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBmYW1pbGllcyB3aG9zZSByb3dzIGRvIG5vdCBmb2xkIGJhY2sgdG8gd2hhdCB0aGUgc3RhZ2UgcmVhZCDigJRcbiAgICogYHVuZGVmaW5lZGAgd2hlbiB0aGVyZSBhcmUgbm9uZSAoYGFkbWlzc2lvbi50cyDCtyBsb3NzeUZhbWlsaWVzYDogdGhlXG4gICAqIGNhbmRpZGF0ZSByZXBsYXllZCBvbnRvIHRoZSBkaWZmIGJhc2UgYnkgYGRyeUZvbGRgLCBldmVyeSBmYW1pbHkgb2ZcbiAgICogdG91Y2hlZCBwYXRocyBjb21wYXJlZCB3aXRoIHRoZSB3b3JraW5nIGNvcHkgYXQgaXRzIHJvb3QgYW5kIG9uIHRoZSB3YXlcbiAgICogZG93biB0byBpdCkuXG4gICAqXG4gICAqIFdpdGhvdXQgYSBmb2xkLCB3aGVuIHRoZSBzdGFnZSBzdGFnZWQgbm8gYG1lcmdlYCBhbmQgbm8gbmVzdGVkIG9wOiBpdHNcbiAgICogcm93cyBhcmUgYHNldGAgLyBgZGVsZXRlYCBvZiBrZXlzIGRpcmVjdGx5IHVuZGVyIGl0cyBhZGRyZXNzLCBlYWNoXG4gICAqIHdyaXRpbmcgdGhlIFNBTUUgdmFsdWUgaW50byBgd29ya2luZ0NvcHlgIGFuZCBgb3ZlcndyaXRlUGF0Y2hgIOKAlCB0aGVcbiAgICogcmVjb3JkIGlzIHRoZSByZWFkLWJhY2sgYnkgY29uc3RydWN0aW9uICh0aGUgcHJvcGVydHkncyBST09ULU9OTFkgYXJtXG4gICAqIHBpbnMgdGhpcykuIFRoYXQga2VlcHMgdGhlIGNvbW1pdCBvZiB0aGUgdHlwZWQgc2NvcGUncyByb290LWtleSB3cml0ZXNcbiAgICogZXhhY3RseSBhcyBjaGVhcCBhcyBpdCB3YXMuXG4gICAqL1xuICBwcml2YXRlIGxvc3N5RmFtaWxpZXMoY2FuZGlkYXRlOiBSb3dzKTogTG9zc3kgfCB1bmRlZmluZWQge1xuICAgIGlmICh0aGlzLnN0YWdlZE1lcmdlcyA9PT0gMCAmJiB0aGlzLm5lc3RlZE9wcyA9PT0gMCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICByZXR1cm4gbG9zc3lGYW1pbGllcyhjYW5kaWRhdGUsIHRoaXMuYmFzZVNuYXBzaG90LCB0aGlzLndvcmtpbmdDb3B5LCB0aGlzLm9wVHJhY2UsIHRoaXMuYWRkcmVzcyk7XG4gIH1cblxuICAvKipcbiAgICogQSBmYW1pbHkgd2hvc2Ugcm93cyBkaWQgbm90IGZvbGQgYmFjaywgd3JpdHRlbiBhcyB3aGF0IHRoZSBzdGFnZSByZWFkOlxuICAgKiBvbmUgYHNldGAgcm93IHBlciBtZW1iZXIgdGhhdCBjaGFuZ2VkIChkZXNjZW5kYW50cyBieSBsYXN0IHRvdWNoLCBlYWNoXG4gICAqIHdpdGggaXRzIG93biByZWFkIHByZWZpeCksIHRoZSBST09UIGxhc3QsIGFuZCB0aGUgcm9vdCdzIHJlYWQtYmFjayB2YWx1ZVxuICAgKiBpbiBgb3ZlcndyaXRlYCDigJQgb25lIGNvaGVyZW50IHRyZWUsIHNvIG5vIHJvdyBjYW4gY2xvYmJlciBhbm90aGVyLiBUaGVcbiAgICogcm9vdCdzIHJvdyBpcyB3cml0dGVuIGV2ZW4gd2hlbiB0aGUgcm9vdCBpdHNlbGYgZGlkIG5vdCBjaGFuZ2U6IGl0IGlzIHRoZVxuICAgKiByb3cgdGhhdCBjYXJyaWVzIHRoZSBmYW1pbHkncyByZWFkLWJhY2sgKGFuZCB0aGUgY29udGFpbmVycyBMLTEncyBkcm9wcGVkXG4gICAqIG9wIGxlZnQpLiBBIGxvbmUgcm9vdCB1bmRlciBgJ2RlbHRhJ2Aga2VlcHMgdGhlIGNvbXBhY3QgYGFwcGVuZGAgd2hlbiB0aGVcbiAgICogdmFsdWUgaXQgcmVhZCBpcyBpdHMgYmFzZSBwbHVzIGEgdGFpbC5cbiAgICovXG4gIHByaXZhdGUgZW1pdFJlYWRCYWNrKGZhbWlseTogRmFtaWx5LCByb3dzOiBSb3dzLCBlbmNvZGluZzogQ29tbWl0VmFsdWVzTW9kZSk6IHZvaWQge1xuICAgIGxldCByb290OiBNZW1iZXIgPSBmYW1pbHkubWVtYmVyc1swXTtcbiAgICBsZXQgY2hhbmdlZCA9IDA7XG4gICAgZm9yIChjb25zdCBtIG9mIGZhbWlseS5tZW1iZXJzKSB7XG4gICAgICBpZiAobS5wYXRoID09PSBmYW1pbHkucm9vdCkge1xuICAgICAgICByb290ID0gbTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuY2hhbmdlZFNpbmNlQmFzZShtLnBhdGguc3BsaXQoREVMSU0pKSkgY29udGludWU7XG4gICAgICByb3dzLnRyYWNlLnB1c2goeyBwYXRoOiBtLnBhdGgsIHZlcmI6ICdzZXQnLCAuLi5wcm92ZW5hbmNlKG0ucmVhZEtleXMpIH0pO1xuICAgICAgY2hhbmdlZCsrO1xuICAgIH1cbiAgICBjb25zdCBhZnRlciA9IF9nZXQodGhpcy53b3JraW5nQ29weSwgZmFtaWx5LnJvb3RTZWdtZW50cyk7XG4gICAgaWYgKGVuY29kaW5nID09PSAnZGVsdGEnICYmIGNoYW5nZWQgPT09IDAgJiYgYWZ0ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgYmVmb3JlID0gX2dldCh0aGlzLmJhc2VTbmFwc2hvdCwgZmFtaWx5LnJvb3RTZWdtZW50cyk7XG4gICAgICBwdXNoVmFsdWVSb3coXG4gICAgICAgIHJvd3MsXG4gICAgICAgIGZhbWlseS5yb290LFxuICAgICAgICBmYW1pbHkucm9vdFNlZ21lbnRzLFxuICAgICAgICBiZWZvcmUsXG4gICAgICAgIGFmdGVyLFxuICAgICAgICBwcm92ZW5hbmNlKHJvb3QucmVhZEtleXMpLFxuICAgICAgICB0aGlzLm1hcmtlZEJlbG93KGZhbWlseS5yb290KSxcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJvd3MudHJhY2UucHVzaCh7IHBhdGg6IGZhbWlseS5yb290LCB2ZXJiOiAnc2V0JywgLi4ucHJvdmVuYW5jZShyb290LnJlYWRLZXlzKSB9KTtcbiAgICAvLyBUaGUgY2xvbmUgdGhlIGNoZWNrIHRvb2sgKGBhZG1pc3Npb24udHMgwrcgZm9sZHNCYWNrYCksIHdoZW4gaXQgdG9vayBvbmUuXG4gICAgX3NldChyb3dzLm92ZXJ3cml0ZSwgZmFtaWx5LnJvb3RTZWdtZW50cywgZmFtaWx5LmhlbGQgIT09IHVuZGVmaW5lZCA/IGZhbWlseS5oZWxkLnZhbHVlIDogc3RydWN0dXJlZENsb25lKGFmdGVyKSk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHZhbHVlIHRoZSBzdGFnZSdzICdmdWxsJyByb3dzIGdpdmUgYSBwYXRoIOKAlCB3aGF0IHRoZSBkZWx0YSBlbmNvZGVyXG4gICAqIGNvbW1pdHMgZm9yIGEgZmFtaWx5IG1lbWJlciBvciBhIHBhdGggd2l0aCBhIGBzZXRgIOKAlCByZWFkIGZyb20gT05FXG4gICAqIHtAbGluayBkcnlGb2xkfSBvZiB0aG9zZSByb3dzIG92ZXIgdGhlIHBhdGNoIHRyZWVzIHRoZW1zZWx2ZXMsIHRha2VuIHRoZVxuICAgKiBmaXJzdCB0aW1lIGl0IGlzIGFza2VkLiBCeSByZWZlcmVuY2UsIGFzIHRoZSBzdGFnZSBoZWxkIHRoZW06IGFuIGVsZW1lbnRcbiAgICogYSBgc2V0YCBhbmQgYSBgbWVyZ2VgIG9mIG9uZSBwYXRoIHNoYXJlIHN0YXlzIG9uZSBlbGVtZW50LiBBIHN0YWdlIHRoYXRcbiAgICogc3RhZ2VkIG5vIGBtZXJnZWAgYW5kIG5vIG5lc3RlZCBvcCBuZWVkcyBubyBmb2xkIOKAlCBhIHBhdGgncyB2YWx1ZSBpcyBpdHNcbiAgICogbGFzdCBzdGFnZWQgdmFsdWUuIChCZWZvcmUgOS4zMC4wOiB0d28gcmVwbGljYXMgb2YgdGhlIHZlcmIgbGF3LFxuICAgKiBgcmVwbGF5UGF0aFZlcmJzYCBhbmQgYHJlcGxheUZhbWlseVZlcmJzYC4pXG4gICAqL1xuICBwcml2YXRlIGZ1bGxSb3dzVmFsdWUoKTogKHNlZ21lbnRzOiBzdHJpbmdbXSkgPT4gdW5rbm93biB7XG4gICAgaWYgKHRoaXMuc3RhZ2VkTWVyZ2VzID09PSAwICYmIHRoaXMubmVzdGVkT3BzID09PSAwKSByZXR1cm4gKHNlZ21lbnRzKSA9PiBfZ2V0KHRoaXMub3ZlcndyaXRlUGF0Y2gsIHNlZ21lbnRzKTtcbiAgICBsZXQgZm9sZDogdW5rbm93bjtcbiAgICByZXR1cm4gKHNlZ21lbnRzKSA9PiB7XG4gICAgICBmb2xkID8/PSBkcnlGb2xkKHRoaXMuYmFzZVNuYXBzaG90LCB0aGlzLnVwZGF0ZVBhdGNoLCB0aGlzLm92ZXJ3cml0ZVBhdGNoLCB0aGlzLmZ1bGxSb3dzKCkpO1xuICAgICAgcmV0dXJuIF9nZXQoZm9sZCwgc2VnbWVudHMpO1xuICAgIH07XG4gIH1cblxuICAvKiogVGhlIHN0YWdlJ3MgJ2Z1bGwnIHJvd3M6IGV2ZXJ5IG9wIG9uIGEgcGF0aCB0aGUgbmV0LWNoYW5nZSBmaWx0ZXIga2VlcHMsIGEgYGRlbGV0ZWAgc3BlbGxlZCBgc2V0YC4gKi9cbiAgcHJpdmF0ZSBmdWxsUm93cygpOiBUcmFjZUVudHJ5W10ge1xuICAgIGNvbnN0IGtlZXAgPSBuZXcgTWFwPHN0cmluZywgYm9vbGVhbj4oKTtcbiAgICBjb25zdCByb3dzOiBUcmFjZUVudHJ5W10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IG9wIG9mIHRoaXMub3BUcmFjZSkge1xuICAgICAgbGV0IGsgPSBrZWVwLmdldChvcC5wYXRoKTtcbiAgICAgIGlmIChrID09PSB1bmRlZmluZWQpIGtlZXAuc2V0KG9wLnBhdGgsIChrID0gdGhpcy5jaGFuZ2VkU2luY2VCYXNlKG9wLnBhdGguc3BsaXQoREVMSU0pKSkpO1xuICAgICAgaWYgKGspIHJvd3MucHVzaCh7IHBhdGg6IG9wLnBhdGgsIHZlcmI6IG9wLnZlcmIgPT09ICdtZXJnZScgPyAnbWVyZ2UnIDogJ3NldCcgfSk7XG4gICAgfVxuICAgIHJldHVybiByb3dzO1xuICB9XG5cbiAgLyoqXG4gICAqIERpZCB0aGUgc3RhZ2UgY2hhbmdlIHRoZSB2YWx1ZSBhdCBgc2VnbWVudHNgPyBCYXNlIGFuZCBmaW5hbCB2YWx1ZSBhcmVcbiAgICogZml4ZWQgYXQgY29tbWl0LCBzbyB0aGlzIGlzIHRoZSBPTkUgbmV0LWNoYW5nZSB2ZXJkaWN0IGJvdGggcGF5bG9hZFxuICAgKiBlbmNvZGluZ3MgYXBwbHkgKGEgbm8tb3Agd3JpdGUgYW5kIGEgd3JpdGUtdGhlbi1yZXZlcnQgYm90aCBmYWlsIGl0KS5cbiAgICovXG4gIHByaXZhdGUgY2hhbmdlZFNpbmNlQmFzZShzZWdtZW50czogc3RyaW5nW10pOiBib29sZWFuIHtcbiAgICByZXR1cm4gIWRlZXBFcXVhbChfZ2V0KHRoaXMuYmFzZVNuYXBzaG90LCBzZWdtZW50cyksIF9nZXQodGhpcy53b3JraW5nQ29weSwgc2VnbWVudHMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXRoIOKGkiBpdHMgb3AtdmVyYiBzZXF1ZW5jZSwgb3JkZXJlZCBieSBMQVNUIHRvdWNoIChkZWxldGUgKyByZS1pbnNlcnRcbiAgICogbW92ZXMgYSByZS10b3VjaGVkIHBhdGggdG8gdGhlIGVuZCBvZiB0aGUgTWFwJ3MgaW5zZXJ0aW9uIG9yZGVyIOKAlFxuICAgKiBwcmVzZXJ2aW5nIGxhc3Qtd3JpdGVyLXdpbnMgZm9yIG5lc3RlZC9vdmVybGFwcGluZyBwYXRocykuIFBlci13cml0ZVxuICAgKiBwcm92ZW5hbmNlICgjUDEpOiB0aGUgTEFTVCBvcCdzIHJlYWRLZXlzIGlzIGtlcHQg4oCUIHJlYWQgcHJlZml4ZXMgb25seSBncm93XG4gICAqIHdpdGhpbiBhIHN0YWdlLCBzbyBsYXN0ID09IHVuaW9uIGFjcm9zcyB0aGUgcGF0aC5cbiAgICovXG4gIHByaXZhdGUgb3BzQnlQYXRoKCk6IE1hcDxzdHJpbmcsIHsgdmVyYnM6IE9wVmVyYltdOyByZWFkS2V5cz86IHN0cmluZ1tdOyBsYXN0OiBudW1iZXIgfT4ge1xuICAgIGNvbnN0IGJ5UGF0aCA9IG5ldyBNYXA8c3RyaW5nLCB7IHZlcmJzOiBPcFZlcmJbXTsgcmVhZEtleXM/OiBzdHJpbmdbXTsgbGFzdDogbnVtYmVyIH0+KCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm9wVHJhY2UubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IG9wID0gdGhpcy5vcFRyYWNlW2ldO1xuICAgICAgY29uc3QgcHJldiA9IGJ5UGF0aC5nZXQob3AucGF0aCk7XG4gICAgICBpZiAocHJldikge1xuICAgICAgICBwcmV2LnZlcmJzLnB1c2gob3AudmVyYik7XG4gICAgICAgIHByZXYubGFzdCA9IGk7XG4gICAgICAgIGlmIChvcC5yZWFkS2V5cyAhPT0gdW5kZWZpbmVkKSBwcmV2LnJlYWRLZXlzID0gb3AucmVhZEtleXM7XG4gICAgICAgIGJ5UGF0aC5kZWxldGUob3AucGF0aCk7XG4gICAgICAgIGJ5UGF0aC5zZXQob3AucGF0aCwgcHJldik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBieVBhdGguc2V0KG9wLnBhdGgsIHtcbiAgICAgICAgICB2ZXJiczogW29wLnZlcmJdLFxuICAgICAgICAgIGxhc3Q6IGksXG4gICAgICAgICAgLi4uKG9wLnJlYWRLZXlzICE9PSB1bmRlZmluZWQgJiYgeyByZWFkS2V5czogb3AucmVhZEtleXMgfSksXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYnlQYXRoO1xuICB9XG5cbiAgLyoqIFRoZSBuZXQtY2hhbmdlIGZpbHRlciDigJQgaWRlbnRpY2FsIHRvICdmdWxsJyAoe0BsaW5rIGNoYW5nZWRTaW5jZUJhc2V9KS4gU3Vydml2b3JzIGtlZXAgbGFzdC10b3VjaCBvcmRlci4gKi9cbiAgcHJpdmF0ZSBuZXRDaGFuZ2VTdXJ2aXZvcnMoYnlQYXRoOiBNYXA8c3RyaW5nLCB7IHZlcmJzOiBPcFZlcmJbXTsgcmVhZEtleXM/OiBzdHJpbmdbXTsgbGFzdDogbnVtYmVyIH0+KTogU3Vydml2b3JbXSB7XG4gICAgY29uc3Qgc3Vydml2b3JzOiBTdXJ2aXZvcltdID0gW107XG4gICAgZm9yIChjb25zdCBbcGF0aCwgeyB2ZXJicywgcmVhZEtleXMsIGxhc3QgfV0gb2YgYnlQYXRoKSB7XG4gICAgICBjb25zdCBzZWdtZW50cyA9IHBhdGguc3BsaXQoREVMSU0pO1xuICAgICAgaWYgKCF0aGlzLmNoYW5nZWRTaW5jZUJhc2Uoc2VnbWVudHMpKSBjb250aW51ZTsgLy8gbm8tb3Agb3Igd3JpdGUtdGhlbi1yZXZlcnQg4oaSIG5vIG5ldCBjaGFuZ2VcbiAgICAgIGNvbnN0IGJlZm9yZSA9IF9nZXQodGhpcy5iYXNlU25hcHNob3QsIHNlZ21lbnRzKTtcbiAgICAgIGNvbnN0IGFmdGVyID0gX2dldCh0aGlzLndvcmtpbmdDb3B5LCBzZWdtZW50cyk7XG4gICAgICBzdXJ2aXZvcnMucHVzaCh7IHBhdGgsIHNlZ21lbnRzLCB2ZXJicywgcmVhZEtleXMsIGxhc3QsIGJlZm9yZSwgYWZ0ZXIgfSk7XG4gICAgfVxuICAgIHJldHVybiBzdXJ2aXZvcnM7XG4gIH1cblxuICAvKipcbiAgICogTWF5IGEgc3RhZ2VkIGBkZWxldGVgIGF0IHRoaXMgcGF0aCBjb21taXQgYXMgdGhlIGAnZGVsZXRlJ2AgdmVyYj9cbiAgICpcbiAgICogT25seSB3aGVuIHJlbW92aW5nIHRoZSBrZXkgYW5kIHRoZSBgJ2Z1bGwnYCBtb2RlJ3MgZmxhdHRlbmluZyAoYF9zZXRgIG9mXG4gICAqIGB1bmRlZmluZWRgKSBsYW5kIGluIHRoZSBzYW1lIHBsYWNlLiBUaGV5IGRpdmVyZ2Ugd2hlbiB0aGUgcGFyZW50IGlzIG5vdFxuICAgKiBhIGNvbnRhaW5lcjogYG5hdGl2ZURlbGV0ZWAgd2Fsa3MgYXdheSB1bnRvdWNoZWQsIHdoaWxlIGBuYXRpdmVTZXRgXG4gICAqIENPRVJDRVMgdGhlIHByaW1pdGl2ZSBwYXJlbnQgaW50byBhbiBvYmplY3QgdG8gaG9sZCB0aGUga2V5LiBDb21taXR0aW5nXG4gICAqIGBkZWxldGVgIHRoZXJlIHdvdWxkIHNpbGVudGx5IGRyb3AgYSBzdGF0ZSBjaGFuZ2UgdGhlIHN0YWdlIHJlYWxseSBtYWRlLFxuICAgKiBzbyB0aG9zZSAocGF0aG9sb2dpY2FsKSBkZWxldGVzIGtlZXAgdGhlIGhpc3RvcmljYWwgZmxhdHRlbmluZy5cbiAgICovXG4gIHByaXZhdGUgZGVsZXRlUmVwbGF5c0FzRmxhdHRlbmluZyhzZWdtZW50czogc3RyaW5nW10pOiBib29sZWFuIHtcbiAgICBpZiAoc2VnbWVudHMubGVuZ3RoID09PSAxKSByZXR1cm4gdHJ1ZTsgLy8gcGFyZW50IGlzIHRoZSBzdGF0ZSByb290IOKAlCBhbHdheXMgYSBjb250YWluZXJcbiAgICBjb25zdCBwYXJlbnQgPSBfZ2V0KHRoaXMuYmFzZVNuYXBzaG90LCBzZWdtZW50cy5zbGljZSgwLCAtMSkpO1xuICAgIHJldHVybiBwYXJlbnQgIT09IG51bGwgJiYgdHlwZW9mIHBhcmVudCA9PT0gJ29iamVjdCc7XG4gIH1cbn1cblxuLyoqXG4gKiBIaXN0b3JpY2FsIGZsYXR0ZW5pbmcgZm9yIHRoZSBgJ2Z1bGwnYCBwYXlsb2FkOiBhbiBleHBsaWNpdCBkZWxldGUgY29tbWl0c1xuICogYXMgc2V0LW9mLXVuZGVmaW5lZC4gUGVyLXdyaXRlIHByb3ZlbmFuY2UgKCNQMSkgcmlkZXMgZWFjaCBzdXJ2aXZpbmcgZW50cnlcbiAqIHVudG91Y2hlZC5cbiAqL1xuZnVuY3Rpb24gZmxhdHRlbmVkVHJhY2VSb3cob3A6IHsgcGF0aDogc3RyaW5nOyB2ZXJiOiBPcFZlcmI7IHJlYWRLZXlzPzogc3RyaW5nW10gfSk6IFRyYWNlRW50cnkge1xuICByZXR1cm4gb3AudmVyYiA9PT0gJ2RlbGV0ZSdcbiAgICA/IHsgcGF0aDogb3AucGF0aCwgdmVyYjogJ3NldCcgYXMgY29uc3QsIC4uLihvcC5yZWFkS2V5cyAhPT0gdW5kZWZpbmVkICYmIHsgcmVhZEtleXM6IG9wLnJlYWRLZXlzIH0pIH1cbiAgICA6IG9wO1xufVxuXG4vKiogQSByb3cncyBgcmVhZEtleXNgIGZyYWdtZW50IOKAlCBhYnNlbnQgdW5sZXNzIHRoZSBwcm92ZW5hbmNlIGRpYWwgcmVjb3JkZWQgb25lICgjUDEpLiAqL1xuZnVuY3Rpb24gcHJvdmVuYW5jZShyZWFkS2V5czogc3RyaW5nW10gfCB1bmRlZmluZWQpOiB7IHJlYWRLZXlzOiBzdHJpbmdbXSB9IHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHJlYWRLZXlzICE9PSB1bmRlZmluZWQgPyB7IHJlYWRLZXlzIH0gOiB1bmRlZmluZWQ7XG59XG4iXX0=