@logixjs/sandbox 0.0.1 → 0.0.2

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 (248) hide show
  1. package/LICENSE +201 -0
  2. package/package.json +3 -1
  3. package/public/sandbox/chunks/chunk-2AUQRESB.js +1114 -0
  4. package/public/sandbox/chunks/chunk-2F72LQKW.js +194 -0
  5. package/public/sandbox/chunks/chunk-2PYDGDD3.js +4071 -0
  6. package/public/sandbox/chunks/chunk-2UGKSXDZ.js +16 -0
  7. package/public/sandbox/chunks/chunk-2XVE7F26.js +153 -0
  8. package/public/sandbox/chunks/chunk-3A7TFNZN.js +219 -0
  9. package/public/sandbox/chunks/chunk-3BHC6JAV.js +1070 -0
  10. package/public/sandbox/chunks/chunk-3U4CAKCX.js +61 -0
  11. package/public/sandbox/chunks/chunk-3VU3JLZO.js +272 -0
  12. package/public/sandbox/chunks/chunk-4CPONKWY.js +1170 -0
  13. package/public/sandbox/chunks/chunk-4GMUQTWH.js +850 -0
  14. package/public/sandbox/chunks/chunk-4KIYG5E4.js +749 -0
  15. package/public/sandbox/chunks/chunk-4MY35XR3.js +175 -0
  16. package/public/sandbox/chunks/chunk-5DNHJMHA.js +69 -0
  17. package/public/sandbox/chunks/chunk-5EC4S7X6.js +42 -0
  18. package/public/sandbox/chunks/chunk-5FB7QFSH.js +227 -0
  19. package/public/sandbox/chunks/chunk-5GEYCJW2.js +206 -0
  20. package/public/sandbox/chunks/chunk-5PT7Q5SS.js +373 -0
  21. package/public/sandbox/chunks/chunk-5WN5IGKA.js +166 -0
  22. package/public/sandbox/chunks/chunk-5XOBKSOT.js +213 -0
  23. package/public/sandbox/chunks/chunk-67RVISUC.js +313 -0
  24. package/public/sandbox/chunks/chunk-6ELJEKZS.js +12 -0
  25. package/public/sandbox/chunks/chunk-6FKWRVP4.js +85 -0
  26. package/public/sandbox/chunks/chunk-6JRP52YT.js +34 -0
  27. package/public/sandbox/chunks/chunk-6JYAC3G6.js +42 -0
  28. package/public/sandbox/chunks/chunk-6TUOP63Q.js +86 -0
  29. package/public/sandbox/chunks/{chunk-A6JFUNQQ.js → chunk-74C5VW7Z.js} +2 -2
  30. package/public/sandbox/chunks/chunk-75DQFC5M.js +16 -0
  31. package/public/sandbox/chunks/{chunk-UCFEP3BH.js → chunk-7GPAF2UK.js} +1 -1
  32. package/public/sandbox/chunks/chunk-7KQFTS2Y.js +135 -0
  33. package/public/sandbox/chunks/chunk-7POKWYE3.js +112 -0
  34. package/public/sandbox/chunks/chunk-7VUEF5F3.js +395 -0
  35. package/public/sandbox/chunks/chunk-7W5APZS2.js +77 -0
  36. package/public/sandbox/chunks/chunk-A6OFCXDQ.js +397 -0
  37. package/public/sandbox/chunks/chunk-A7HLOSO6.js +216 -0
  38. package/public/sandbox/chunks/chunk-AGF4RRCB.js +408 -0
  39. package/public/sandbox/chunks/chunk-ASJSJAAL.js +122 -0
  40. package/public/sandbox/chunks/chunk-ASVMK364.js +283 -0
  41. package/public/sandbox/chunks/chunk-AUDTI2BQ.js +895 -0
  42. package/public/sandbox/chunks/chunk-B2SZTA3M.js +16 -0
  43. package/public/sandbox/chunks/chunk-B6YS2UMV.js +372 -0
  44. package/public/sandbox/chunks/chunk-BCEO3MGD.js +244 -0
  45. package/public/sandbox/chunks/chunk-BCOO65D4.js +373 -0
  46. package/public/sandbox/chunks/chunk-BJOWSSEL.js +38 -0
  47. package/public/sandbox/chunks/chunk-BS2WBFW4.js +373 -0
  48. package/public/sandbox/chunks/chunk-BUVHG3NJ.js +439 -0
  49. package/public/sandbox/chunks/chunk-BVE33AN6.js +42 -0
  50. package/public/sandbox/chunks/chunk-BWTGJZVP.js +19 -0
  51. package/public/sandbox/chunks/chunk-BXD7GZC3.js +1025 -0
  52. package/public/sandbox/chunks/chunk-BZH4EUUD.js +164 -0
  53. package/public/sandbox/chunks/{chunk-HFV5GJPK.js → chunk-C2MYMMO4.js} +3 -3
  54. package/public/sandbox/chunks/chunk-CRE4NJJ6.js +271 -0
  55. package/public/sandbox/chunks/chunk-CVZPRIDB.js +706 -0
  56. package/public/sandbox/chunks/chunk-CWOXD5NG.js +991 -0
  57. package/public/sandbox/chunks/chunk-D6DOC3BJ.js +373 -0
  58. package/public/sandbox/chunks/chunk-DEPSGFSY.js +1698 -0
  59. package/public/sandbox/chunks/chunk-DM7C5NP5.js +819 -0
  60. package/public/sandbox/chunks/chunk-DN33LMOF.js +1112 -0
  61. package/public/sandbox/chunks/{chunk-S46P7MC6.js → chunk-DT7YIIWE.js} +2 -2
  62. package/public/sandbox/chunks/chunk-DVB5WRCI.js +260 -0
  63. package/public/sandbox/chunks/{chunk-TOHCFMQS.js → chunk-E3EVW7NR.js} +11 -18
  64. package/public/sandbox/chunks/chunk-E5BV567Q.js +417 -0
  65. package/public/sandbox/chunks/chunk-E7BIWMQQ.js +203 -0
  66. package/public/sandbox/chunks/chunk-EAKGPSOQ.js +83 -0
  67. package/public/sandbox/chunks/chunk-EGUYL2ER.js +75 -0
  68. package/public/sandbox/chunks/chunk-EP5GQYZ5.js +85 -0
  69. package/public/sandbox/chunks/chunk-ET6CJEHC.js +221 -0
  70. package/public/sandbox/chunks/chunk-EU67YZHZ.js +1070 -0
  71. package/public/sandbox/chunks/{chunk-PTSJJANP.js → chunk-EYNDQLSB.js} +1 -1
  72. package/public/sandbox/chunks/{chunk-CEGSWZ5S.js → chunk-EZTMVCJF.js} +1 -1
  73. package/public/sandbox/chunks/chunk-F5CLVIS6.js +907 -0
  74. package/public/sandbox/chunks/chunk-F743SKYD.js +85 -0
  75. package/public/sandbox/chunks/chunk-FEGFZ5OX.js +86 -0
  76. package/public/sandbox/chunks/chunk-FG5B7ZX3.js +373 -0
  77. package/public/sandbox/chunks/chunk-FKZPYMDG.js +373 -0
  78. package/public/sandbox/chunks/chunk-FNLXHWIU.js +220 -0
  79. package/public/sandbox/chunks/chunk-FQRUTYAD.js +1991 -0
  80. package/public/sandbox/chunks/{chunk-VLYP4WUS.js → chunk-FY5A73NK.js} +5 -5
  81. package/public/sandbox/chunks/chunk-G7FAOG3O.js +221 -0
  82. package/public/sandbox/chunks/chunk-GFXHUC7Y.js +73 -0
  83. package/public/sandbox/chunks/chunk-GIPXUIZQ.js +534 -0
  84. package/public/sandbox/chunks/chunk-GP37MEGJ.js +52 -0
  85. package/public/sandbox/chunks/chunk-GXL5QCMF.js +4511 -0
  86. package/public/sandbox/chunks/chunk-GZ2NSE6A.js +177 -0
  87. package/public/sandbox/chunks/chunk-GZATW4YD.js +69 -0
  88. package/public/sandbox/chunks/chunk-H4EBXROQ.js +166 -0
  89. package/public/sandbox/chunks/chunk-HETCPK6Z.js +153 -0
  90. package/public/sandbox/chunks/chunk-HGUFQ2QC.js +4431 -0
  91. package/public/sandbox/chunks/chunk-HGV3VNH3.js +255 -0
  92. package/public/sandbox/chunks/chunk-HIJ67QWR.js +5397 -0
  93. package/public/sandbox/chunks/chunk-IDHERBKW.js +1114 -0
  94. package/public/sandbox/chunks/chunk-IDTK4FIY.js +102 -0
  95. package/public/sandbox/chunks/chunk-ILFVY7H5.js +164 -0
  96. package/public/sandbox/chunks/chunk-ISGSRYGO.js +57 -0
  97. package/public/sandbox/chunks/chunk-J45VPU24.js +408 -0
  98. package/public/sandbox/chunks/chunk-JAUIM3O5.js +42 -0
  99. package/public/sandbox/chunks/chunk-JB7OQEM6.js +373 -0
  100. package/public/sandbox/chunks/chunk-JCKW6NHD.js +15 -0
  101. package/public/sandbox/chunks/chunk-JMA7GY7Z.js +221 -0
  102. package/public/sandbox/chunks/chunk-JY46J6IL.js +836 -0
  103. package/public/sandbox/chunks/{chunk-X72PZOFA.js → chunk-K2MQ66O7.js} +1 -1
  104. package/public/sandbox/chunks/chunk-KA7PZA6F.js +464 -0
  105. package/public/sandbox/chunks/chunk-KDEQTUID.js +102 -0
  106. package/public/sandbox/chunks/chunk-KDJR27JV.js +1696 -0
  107. package/public/sandbox/chunks/chunk-KFE3JO6N.js +77 -0
  108. package/public/sandbox/chunks/chunk-KLDSYWT5.js +536 -0
  109. package/public/sandbox/chunks/chunk-KQWWFYBF.js +203 -0
  110. package/public/sandbox/chunks/chunk-KTFZSXOW.js +6473 -0
  111. package/public/sandbox/chunks/chunk-KXVIC55U.js +108 -0
  112. package/public/sandbox/chunks/{chunk-HNEDTEGQ.js → chunk-L4PNO2H6.js} +1 -1
  113. package/public/sandbox/chunks/{chunk-WE4STGO2.js → chunk-L4ZNW5DI.js} +2 -2
  114. package/public/sandbox/chunks/chunk-LBUINGZ4.js +836 -0
  115. package/public/sandbox/chunks/chunk-LIYPPU6I.js +112 -0
  116. package/public/sandbox/chunks/chunk-LJHTOJXW.js +221 -0
  117. package/public/sandbox/chunks/{chunk-BWSNPKO5.js → chunk-LQL23SWJ.js} +2 -2
  118. package/public/sandbox/chunks/chunk-LTFCYZQ6.js +46 -0
  119. package/public/sandbox/chunks/chunk-LTWLVCKQ.js +166 -0
  120. package/public/sandbox/chunks/chunk-LWI7BXFN.js +395 -0
  121. package/public/sandbox/chunks/chunk-LYBBX6WM.js +225 -0
  122. package/public/sandbox/chunks/chunk-MXE7HIBM.js +474 -0
  123. package/public/sandbox/chunks/chunk-MYBDYNK4.js +6004 -0
  124. package/public/sandbox/chunks/chunk-NC2MIWZX.js +732 -0
  125. package/public/sandbox/chunks/chunk-NE447XAF.js +597 -0
  126. package/public/sandbox/chunks/chunk-NEAYV5C2.js +255 -0
  127. package/public/sandbox/chunks/chunk-NMGFJZ4I.js +26 -0
  128. package/public/sandbox/chunks/chunk-NWCJJZNQ.js +71 -0
  129. package/public/sandbox/chunks/chunk-O57OZBDR.js +214 -0
  130. package/public/sandbox/chunks/chunk-OJJT664Q.js +731 -0
  131. package/public/sandbox/chunks/chunk-OKTBUTCH.js +1175 -0
  132. package/public/sandbox/chunks/chunk-OQ4SYV5D.js +534 -0
  133. package/public/sandbox/chunks/chunk-OTVVIHJD.js +219 -0
  134. package/public/sandbox/chunks/chunk-OWTMSCF7.js +1052 -0
  135. package/public/sandbox/chunks/chunk-P5ZQNFC3.js +122 -0
  136. package/public/sandbox/chunks/chunk-PBPT2U2N.js +1698 -0
  137. package/public/sandbox/chunks/chunk-PHBJLCP3.js +836 -0
  138. package/public/sandbox/chunks/chunk-PHV4HYHB.js +397 -0
  139. package/public/sandbox/chunks/chunk-PIXQ6SOX.js +4071 -0
  140. package/public/sandbox/chunks/chunk-PKJL6YLK.js +73 -0
  141. package/public/sandbox/chunks/chunk-PKPOITIU.js +221 -0
  142. package/public/sandbox/chunks/{chunk-NQW73ACJ.js → chunk-PMXBOYQI.js} +1 -1
  143. package/public/sandbox/chunks/chunk-PQLZD7NR.js +836 -0
  144. package/public/sandbox/chunks/chunk-QEESVOZU.js +16 -0
  145. package/public/sandbox/chunks/chunk-QGIM3FQK.js +159 -0
  146. package/public/sandbox/chunks/chunk-QL5JNEDO.js +69 -0
  147. package/public/sandbox/chunks/chunk-QQOZ3RMH.js +867 -0
  148. package/public/sandbox/chunks/chunk-QUMEVT2F.js +194 -0
  149. package/public/sandbox/chunks/chunk-QVZBXYVY.js +102 -0
  150. package/public/sandbox/chunks/chunk-R5HQS6RB.js +135 -0
  151. package/public/sandbox/chunks/chunk-R75Q2CTT.js +900 -0
  152. package/public/sandbox/chunks/chunk-RBB6SHW2.js +253 -0
  153. package/public/sandbox/chunks/chunk-RDHNRWQP.js +383 -0
  154. package/public/sandbox/chunks/chunk-RIWOEI3T.js +1101 -0
  155. package/public/sandbox/chunks/chunk-RS5FFPUV.js +103 -0
  156. package/public/sandbox/chunks/chunk-RYSSJBGX.js +203 -0
  157. package/public/sandbox/chunks/chunk-S3KBAE5Z.js +1114 -0
  158. package/public/sandbox/chunks/chunk-S6ZZHV6G.js +244 -0
  159. package/public/sandbox/chunks/chunk-SFXJ24HY.js +499 -0
  160. package/public/sandbox/chunks/chunk-SH7TP5CJ.js +1109 -0
  161. package/public/sandbox/chunks/chunk-SI5OKFFY.js +317 -0
  162. package/public/sandbox/chunks/chunk-SIXNQNIR.js +86 -0
  163. package/public/sandbox/chunks/chunk-ST353BOX.js +42 -0
  164. package/public/sandbox/chunks/chunk-SYEHKMLP.js +1140 -0
  165. package/public/sandbox/chunks/chunk-SZ4KQUJU.js +69 -0
  166. package/public/sandbox/chunks/{chunk-5SOP6EKV.js → chunk-SZI65PSP.js} +5 -10
  167. package/public/sandbox/chunks/chunk-T7RLTSMX.js +78 -0
  168. package/public/sandbox/chunks/chunk-TJ2RLUTW.js +57 -0
  169. package/public/sandbox/chunks/chunk-TJB73XPN.js +4071 -0
  170. package/public/sandbox/chunks/chunk-TXJCYO56.js +4046 -0
  171. package/public/sandbox/chunks/chunk-U5J3LCYI.js +731 -0
  172. package/public/sandbox/chunks/chunk-UABFN3NH.js +208 -0
  173. package/public/sandbox/chunks/chunk-UBMUY7WO.js +13 -0
  174. package/public/sandbox/chunks/chunk-UC27CE32.js +69 -0
  175. package/public/sandbox/chunks/chunk-UJGVDFZN.js +147 -0
  176. package/public/sandbox/chunks/chunk-UNVLTK4N.js +122 -0
  177. package/public/sandbox/chunks/chunk-UQKQ6V3V.js +208 -0
  178. package/public/sandbox/chunks/chunk-UZZBHWIO.js +703 -0
  179. package/public/sandbox/chunks/chunk-VKZIJERL.js +1114 -0
  180. package/public/sandbox/chunks/chunk-VQQEAGID.js +372 -0
  181. package/public/sandbox/chunks/{chunk-3LX3KIQQ.js → chunk-W365QUZ5.js} +3 -5
  182. package/public/sandbox/chunks/chunk-WJY2LSWG.js +1052 -0
  183. package/public/sandbox/chunks/chunk-WNOBN3DX.js +391 -0
  184. package/public/sandbox/chunks/chunk-X2Z5VYG3.js +245 -0
  185. package/public/sandbox/chunks/chunk-X74KU74D.js +959 -0
  186. package/public/sandbox/chunks/chunk-XE7ULSGQ.js +46 -0
  187. package/public/sandbox/chunks/chunk-XRXUJZ3X.js +431 -0
  188. package/public/sandbox/chunks/chunk-XWHIN7CC.js +85 -0
  189. package/public/sandbox/chunks/chunk-Y2TVGGVL.js +527 -0
  190. package/public/sandbox/chunks/chunk-YMVMZA3U.js +1395 -0
  191. package/public/sandbox/chunks/chunk-YOBLFWDV.js +431 -0
  192. package/public/sandbox/chunks/chunk-YR2RFEZA.js +11 -0
  193. package/public/sandbox/chunks/chunk-YTD6A35P.js +836 -0
  194. package/public/sandbox/chunks/chunk-Z5L7EZXS.js +81 -0
  195. package/public/sandbox/chunks/chunk-Z65I5ET2.js +108 -0
  196. package/public/sandbox/chunks/chunk-Z6LV34RO.js +390 -0
  197. package/public/sandbox/chunks/chunk-ZAKUP6QG.js +1634 -0
  198. package/public/sandbox/chunks/chunk-ZHNYE2YH.js +731 -0
  199. package/public/sandbox/chunks/chunk-ZHQX3B3Y.js +867 -0
  200. package/public/sandbox/chunks/chunk-ZIXDFRHJ.js +731 -0
  201. package/public/sandbox/chunks/chunk-ZPZ2MZ4D.js +528 -0
  202. package/public/sandbox/chunks/chunk-ZQD6NZXB.js +373 -0
  203. package/public/sandbox/chunks/chunk-ZVVBP7ON.js +16 -0
  204. package/public/sandbox/chunks/chunk-ZWE3P6X2.js +11 -0
  205. package/public/sandbox/logix-core/Bound.js +14 -14
  206. package/public/sandbox/logix-core/Debug.js +12 -10
  207. package/public/sandbox/logix-core/EffectOp.js +3 -4
  208. package/public/sandbox/logix-core/Env.js +5 -2
  209. package/public/sandbox/logix-core/ExternalStore.js +239 -0
  210. package/public/sandbox/logix-core/Flow.js +7 -8
  211. package/public/sandbox/logix-core/Kernel.js +7 -4
  212. package/public/sandbox/logix-core/Link.js +33 -25
  213. package/public/sandbox/logix-core/Middleware.js +13 -11
  214. package/public/sandbox/logix-core/Module.js +93 -30
  215. package/public/sandbox/logix-core/ModuleTag.js +28 -25
  216. package/public/sandbox/logix-core/Observability.js +21 -19
  217. package/public/sandbox/logix-core/Process.js +27 -22
  218. package/public/sandbox/logix-core/ReadQuery.js +7 -11
  219. package/public/sandbox/logix-core/Reflection.js +173 -53
  220. package/public/sandbox/logix-core/Resource.js +6 -3
  221. package/public/sandbox/logix-core/Root.js +7 -3
  222. package/public/sandbox/logix-core/Runtime.js +54 -40
  223. package/public/sandbox/logix-core/ScopeRegistry.js +6 -3
  224. package/public/sandbox/logix-core/StateTrait.js +17 -14
  225. package/public/sandbox/logix-core/TraitLifecycle.js +8 -8
  226. package/public/sandbox/logix-core/Workflow.js +332 -0
  227. package/public/sandbox/logix-core.js +11133 -6622
  228. package/public/sandbox/logix-core.manifest.json +4 -2
  229. package/public/sandbox/worker.js +3 -3
  230. package/public/sandbox/chunks/chunk-4LRLOTMA.js +0 -1698
  231. package/public/sandbox/chunks/chunk-CDLXJHXY.js +0 -120
  232. package/public/sandbox/chunks/chunk-CZRI7MHA.js +0 -46
  233. package/public/sandbox/chunks/chunk-EJDFUZ4B.js +0 -408
  234. package/public/sandbox/chunks/chunk-IP63FME6.js +0 -282
  235. package/public/sandbox/chunks/chunk-JIXTOQXJ.js +0 -1103
  236. package/public/sandbox/chunks/chunk-MPUSOFJ3.js +0 -1928
  237. package/public/sandbox/chunks/chunk-ON2LY6HJ.js +0 -135
  238. package/public/sandbox/chunks/chunk-POIBXAH5.js +0 -995
  239. package/public/sandbox/chunks/chunk-PQ652ULI.js +0 -6359
  240. package/public/sandbox/chunks/chunk-RJQ4PG2F.js +0 -77
  241. package/public/sandbox/chunks/chunk-S4EXG3OS.js +0 -533
  242. package/public/sandbox/chunks/chunk-SUXDGXVE.js +0 -390
  243. package/public/sandbox/chunks/chunk-TOQ6SJ6O.js +0 -244
  244. package/public/sandbox/chunks/chunk-UKYAF3NL.js +0 -1036
  245. package/public/sandbox/chunks/chunk-UMVN3AWO.js +0 -395
  246. package/public/sandbox/chunks/chunk-WFV5PPWJ.js +0 -194
  247. package/public/sandbox/chunks/chunk-YF6IO732.js +0 -206
  248. package/public/sandbox/chunks/chunk-ZUBABAAO.js +0 -86
@@ -0,0 +1,819 @@
1
+ // @logixjs/core subpath bundles for @logixjs/sandbox
2
+
3
+ import {
4
+ compileWorkflowRuntimeStepsV1,
5
+ evalInputExpr,
6
+ makeWorkflowError
7
+ } from "./chunk-UZZBHWIO.js";
8
+ import {
9
+ attachLogicUnitMeta,
10
+ currentTxnOriginOverride
11
+ } from "./chunk-BJOWSSEL.js";
12
+ import {
13
+ RootContextTag
14
+ } from "./chunk-UBMUY7WO.js";
15
+ import {
16
+ getRuntimeInternals
17
+ } from "./chunk-7GPAF2UK.js";
18
+ import {
19
+ HostSchedulerTag,
20
+ TickSchedulerTag,
21
+ forceSourceRefresh,
22
+ inSyncTransactionFiber
23
+ } from "./chunk-YMVMZA3U.js";
24
+ import {
25
+ makeInRunSession,
26
+ run
27
+ } from "./chunk-W365QUZ5.js";
28
+ import {
29
+ currentDiagnosticsLevel,
30
+ record,
31
+ toSerializableErrorSummary
32
+ } from "./chunk-SH7TP5CJ.js";
33
+ import {
34
+ EffectOpMiddlewareTag
35
+ } from "./chunk-SI5OKFFY.js";
36
+
37
+ // ../logix-core/src/internal/runtime/core/WorkflowRuntime.ts
38
+ import { Cause, Context, Deferred, Effect, Exit, Fiber, FiberRef, Option, Stream } from "../effect.js";
39
+ var WORKFLOW_REGISTRY = /* @__PURE__ */ Symbol.for("@logixjs/core/workflowRegistry");
40
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
41
+ var isObjectLike = (value) => typeof value === "object" && value !== null || typeof value === "function";
42
+ var getRegistry = (runtime) => runtime[WORKFLOW_REGISTRY];
43
+ var resolveActionTag = (action) => {
44
+ const tag = isObjectLike(action) ? action._tag : void 0;
45
+ if (typeof tag === "string" && tag.length > 0) return tag;
46
+ const type = isObjectLike(action) ? action.type : void 0;
47
+ if (typeof type === "string" && type.length > 0) return type;
48
+ if (tag != null) return String(tag);
49
+ if (type != null) return String(type);
50
+ return void 0;
51
+ };
52
+ var asNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
53
+ var KERNEL_PORT_SOURCE_REFRESH = "logix/kernel/sourceRefresh";
54
+ var resolveServicePort = (runtime, env, serviceId, programId, stepKey) => {
55
+ if (serviceId === KERNEL_PORT_SOURCE_REFRESH) {
56
+ return (input) => Effect.gen(function* () {
57
+ const fieldPath = asNonEmptyString(isRecord(input) ? input.fieldPath : void 0);
58
+ if (!fieldPath) {
59
+ throw makeWorkflowError({
60
+ code: "WORKFLOW_INVALID_STEP",
61
+ message: "KernelPort sourceRefresh requires input.fieldPath (non-empty string).",
62
+ programId,
63
+ source: { stepKey },
64
+ detail: { serviceId, input }
65
+ });
66
+ }
67
+ const internals = getRuntimeInternals(runtime);
68
+ const handler = internals.traits.getSourceRefreshHandler(fieldPath);
69
+ if (!handler) {
70
+ return;
71
+ }
72
+ const force = isRecord(input) && input.force === true;
73
+ const runHandler = (state) => force ? Effect.locally(forceSourceRefresh, true)(handler(state)) : handler(state);
74
+ const inTxn = yield* FiberRef.get(inSyncTransactionFiber);
75
+ if (inTxn) {
76
+ const state = yield* runtime.getState;
77
+ yield* runHandler(state);
78
+ return;
79
+ }
80
+ yield* internals.txn.runWithStateTransaction(
81
+ {
82
+ kind: "source-refresh",
83
+ name: fieldPath
84
+ },
85
+ () => Effect.gen(function* () {
86
+ const state = yield* runtime.getState;
87
+ yield* runHandler(state);
88
+ })
89
+ );
90
+ });
91
+ }
92
+ const tag = Context.GenericTag(serviceId);
93
+ const opt = Context.getOption(env, tag);
94
+ if (Option.isNone(opt)) {
95
+ throw makeWorkflowError({
96
+ code: "WORKFLOW_MISSING_SERVICE",
97
+ message: `Missing service for serviceId="${serviceId}".`,
98
+ programId,
99
+ source: { stepKey },
100
+ detail: { serviceId }
101
+ });
102
+ }
103
+ const value = opt.value;
104
+ if (typeof value === "function") {
105
+ const fn = value;
106
+ return (input) => fn(input);
107
+ }
108
+ const callFn = isObjectLike(value) ? value.call : void 0;
109
+ if (typeof callFn === "function") {
110
+ const call = callFn;
111
+ return (input) => call.call(value, input);
112
+ }
113
+ throw makeWorkflowError({
114
+ code: "WORKFLOW_INVALID_SERVICE_PORT",
115
+ message: `Invalid service port for serviceId="${serviceId}" (expected a function or { call(input): Effect }).`,
116
+ programId,
117
+ source: { stepKey },
118
+ detail: { serviceId, portType: typeof value }
119
+ });
120
+ };
121
+ var compileSteps = (steps, resolvePort) => {
122
+ const visit = (step) => {
123
+ switch (step.kind) {
124
+ case "dispatch":
125
+ return {
126
+ kind: "dispatch",
127
+ key: step.key,
128
+ actionTag: step.actionTag,
129
+ ...step.payload ? { payload: step.payload } : null
130
+ };
131
+ case "delay":
132
+ return { kind: "delay", key: step.key, ms: step.ms };
133
+ case "call":
134
+ return {
135
+ kind: "call",
136
+ key: step.key,
137
+ serviceId: step.serviceId,
138
+ port: resolvePort(step.serviceId, step.key),
139
+ ...step.input ? { input: step.input } : null,
140
+ ...step.timeoutMs !== void 0 ? { timeoutMs: step.timeoutMs } : null,
141
+ ...step.retryTimes !== void 0 ? { retryTimes: step.retryTimes } : null,
142
+ onSuccess: step.onSuccess.map(visit),
143
+ onFailure: step.onFailure.map(visit)
144
+ };
145
+ }
146
+ };
147
+ return steps.map(visit);
148
+ };
149
+ var resolveConcurrency = (def) => def.policy?.concurrency ?? "parallel";
150
+ var resolvePriority = (def) => def.policy?.priority ?? "urgent";
151
+ var makeRunId = (instanceId, programId, runSeq) => `${instanceId}::wf:${programId}::r${runSeq}`;
152
+ var runBoundary = (args) => Effect.gen(function* () {
153
+ const op = yield* makeInRunSession({
154
+ kind: args.kind,
155
+ name: args.name,
156
+ effect: args.effect,
157
+ payload: args.payload,
158
+ meta: args.meta
159
+ });
160
+ const stack = args.middleware?.stack ?? [];
161
+ return yield* run(op, stack);
162
+ });
163
+ var makeTimer = (args) => Effect.async((resume) => {
164
+ let fired = false;
165
+ const cancel = args.host.scheduleTimeout(args.ms, () => {
166
+ fired = true;
167
+ args.host.scheduleMicrotask(() => resume(Effect.void));
168
+ });
169
+ return Effect.sync(() => {
170
+ cancel();
171
+ }).pipe(Effect.zipRight(fired ? Effect.void : args.onCancel));
172
+ });
173
+ var ensureLimiterReady = (registry, runtime) => Effect.gen(function* () {
174
+ if (registry.parallelLimiter !== void 0) return;
175
+ const internals = getRuntimeInternals(runtime);
176
+ const policy = yield* internals.concurrency.resolveConcurrencyPolicy();
177
+ const limit = policy.concurrencyLimit;
178
+ if (limit === "unbounded") {
179
+ registry.parallelLimiter = null;
180
+ return;
181
+ }
182
+ const n = typeof limit === "number" && Number.isFinite(limit) && limit >= 1 ? Math.floor(limit) : 16;
183
+ registry.parallelLimiter = yield* Effect.makeSemaphore(n);
184
+ });
185
+ var withRootEnvIfAvailable = (eff) => Effect.gen(function* () {
186
+ const rootOpt = yield* Effect.serviceOption(RootContextTag);
187
+ if (Option.isNone(rootOpt)) {
188
+ return yield* eff;
189
+ }
190
+ const root = rootOpt.value;
191
+ const rootEnv = root.context ?? (yield* Deferred.await(root.ready));
192
+ const currentEnv = yield* Effect.context();
193
+ const mergedEnv = Context.merge(rootEnv, currentEnv);
194
+ return yield* Effect.provide(eff, mergedEnv);
195
+ });
196
+ var ensurePortsResolved = (registry, runtime) => Effect.gen(function* () {
197
+ const done = yield* Deferred.isDone(registry.portsReady);
198
+ if (done) {
199
+ yield* Deferred.await(registry.portsReady);
200
+ return;
201
+ }
202
+ if (registry.portsResolving) {
203
+ yield* Deferred.await(registry.portsReady);
204
+ return;
205
+ }
206
+ registry.portsResolving = true;
207
+ const env = yield* Effect.context();
208
+ yield* Effect.sync(() => {
209
+ const portCache = /* @__PURE__ */ new Map();
210
+ for (const entry of registry.entries) {
211
+ const program = entry.program;
212
+ if (program.steps) continue;
213
+ const resolvePort = (serviceId, stepKey) => {
214
+ const cached = portCache.get(serviceId);
215
+ if (cached) return cached;
216
+ const resolved = resolveServicePort(runtime, env, serviceId, program.programId, stepKey);
217
+ portCache.set(serviceId, resolved);
218
+ return resolved;
219
+ };
220
+ program.steps = compileSteps(program.compiledSteps, resolvePort);
221
+ }
222
+ }).pipe(
223
+ Effect.tap(() => Deferred.succeed(registry.portsReady, void 0)),
224
+ Effect.catchAllCause((cause) => Deferred.failCause(registry.portsReady, cause).pipe(Effect.zipRight(Effect.failCause(cause)))),
225
+ Effect.ensuring(
226
+ Effect.sync(() => {
227
+ registry.portsResolving = false;
228
+ })
229
+ )
230
+ );
231
+ });
232
+ var shouldObserveForRun = (diagnostics, runSeq) => {
233
+ if (diagnostics === "off") return false;
234
+ if (diagnostics === "sampled") {
235
+ return (runSeq & 15) === 0;
236
+ }
237
+ return true;
238
+ };
239
+ var startProgramRun = (args) => Effect.gen(function* () {
240
+ const { entry, runtime, registry } = args;
241
+ const { program, state } = entry;
242
+ const diagnostics = yield* FiberRef.get(currentDiagnosticsLevel);
243
+ const beginRun = () => {
244
+ if (state.mode === "latest") {
245
+ state.runSeq += 1;
246
+ const runSeq3 = state.runSeq;
247
+ const runId3 = makeRunId(runtime.instanceId, program.programId, runSeq3);
248
+ return {
249
+ runSeq: runSeq3,
250
+ runId: runId3,
251
+ canWriteBack: () => state.runSeq === runSeq3
252
+ };
253
+ }
254
+ state.runSeq += 1;
255
+ const runSeq2 = state.runSeq;
256
+ const runId2 = makeRunId(runtime.instanceId, program.programId, runSeq2);
257
+ return {
258
+ runSeq: runSeq2,
259
+ runId: runId2,
260
+ canWriteBack: () => true
261
+ };
262
+ };
263
+ if (state.mode === "exhaust") {
264
+ if (state.busy) {
265
+ if (diagnostics !== "off") {
266
+ const observe2 = shouldObserveForRun(diagnostics, state.runSeq);
267
+ const tickSeq = observe2 ? (yield* TickSchedulerTag).getTickSeq() : void 0;
268
+ yield* runBoundary({
269
+ kind: "flow",
270
+ name: "workflow.drop",
271
+ payload: { programId: program.programId, trigger: args.trigger },
272
+ meta: {
273
+ moduleId: runtime.moduleId,
274
+ instanceId: runtime.instanceId,
275
+ programId: program.programId,
276
+ ...tickSeq !== void 0 ? { tickSeq } : null,
277
+ policy: { disableObservers: !observe2 },
278
+ reason: "exhaust"
279
+ },
280
+ effect: Effect.void,
281
+ middleware: args.middleware
282
+ });
283
+ }
284
+ return;
285
+ }
286
+ state.busy = true;
287
+ }
288
+ const { runSeq, runId, canWriteBack } = beginRun();
289
+ if (state.mode === "latest") {
290
+ const prev = state.current;
291
+ const prevRunId = state.currentRunId;
292
+ if (prev) {
293
+ yield* Fiber.interruptFork(prev);
294
+ if (diagnostics !== "off") {
295
+ const observe2 = shouldObserveForRun(diagnostics, runSeq);
296
+ const tickSeq = observe2 ? (yield* TickSchedulerTag).getTickSeq() : void 0;
297
+ yield* runBoundary({
298
+ kind: "flow",
299
+ name: "workflow.cancel",
300
+ payload: { programId: program.programId, cancelled: prevRunId, by: runId },
301
+ meta: {
302
+ moduleId: runtime.moduleId,
303
+ instanceId: runtime.instanceId,
304
+ programId: program.programId,
305
+ ...tickSeq !== void 0 ? { tickSeq } : null,
306
+ policy: { disableObservers: !observe2 },
307
+ reason: "latest",
308
+ cancelledByRunId: runId,
309
+ cancelledRunId: prevRunId
310
+ },
311
+ effect: Effect.void,
312
+ middleware: args.middleware
313
+ });
314
+ }
315
+ }
316
+ state.currentRunId = runId;
317
+ }
318
+ const observe = shouldObserveForRun(diagnostics, runSeq);
319
+ const policy = { disableObservers: !observe };
320
+ const programEffect = Effect.gen(function* () {
321
+ const host = yield* HostSchedulerTag;
322
+ const tick = yield* TickSchedulerTag;
323
+ if (!program.steps) {
324
+ const env = yield* Effect.context();
325
+ const portCache = /* @__PURE__ */ new Map();
326
+ const resolvePort = (serviceId, stepKey) => {
327
+ const cached = portCache.get(serviceId);
328
+ if (cached) return cached;
329
+ const resolved = resolveServicePort(runtime, env, serviceId, program.programId, stepKey);
330
+ portCache.set(serviceId, resolved);
331
+ return resolved;
332
+ };
333
+ program.steps = compileSteps(program.compiledSteps, resolvePort);
334
+ }
335
+ const getTickSeq = () => observe ? tick.getTickSeq() : void 0;
336
+ const emitTimerEvents = observe && diagnostics === "full";
337
+ const evalPayload = (expr) => expr ? evalInputExpr(expr, args.payload) : void 0;
338
+ const defaultInputForCall = () => args.trigger.kind === "action" ? args.payload : void 0;
339
+ let timerTriggered = false;
340
+ const runSteps = (steps) => Effect.gen(function* () {
341
+ for (const step of steps) {
342
+ if (!canWriteBack()) return;
343
+ if (step.kind === "dispatch") {
344
+ const payload = evalPayload(step.payload);
345
+ const action = { _tag: step.actionTag, payload };
346
+ const tickSeq = getTickSeq();
347
+ const dispatchEffectBase = program.priority === "nonUrgent" ? runtime.dispatchLowPriority(action) : runtime.dispatch(action);
348
+ const dispatchEffect = timerTriggered ? Effect.locally(
349
+ currentTxnOriginOverride,
350
+ {
351
+ kind: "workflow.timer",
352
+ name: `timer:${program.programId}:${step.key}`
353
+ }
354
+ )(dispatchEffectBase) : dispatchEffectBase;
355
+ yield* runBoundary({
356
+ kind: "flow",
357
+ name: "workflow.dispatch",
358
+ payload: { actionTag: step.actionTag },
359
+ meta: {
360
+ moduleId: runtime.moduleId,
361
+ instanceId: runtime.instanceId,
362
+ programId: program.programId,
363
+ runId,
364
+ stepKey: step.key,
365
+ ...tickSeq !== void 0 ? { tickSeq } : null,
366
+ policy
367
+ },
368
+ effect: dispatchEffect,
369
+ middleware: args.middleware
370
+ }).pipe(Effect.asVoid);
371
+ continue;
372
+ }
373
+ if (step.kind === "delay") {
374
+ const timerId = emitTimerEvents ? `${runId}::timer:${step.key}` : void 0;
375
+ const recordTimerEvent = (name, patchMeta) => Effect.gen(function* () {
376
+ const tickSeq2 = getTickSeq();
377
+ yield* runBoundary({
378
+ kind: "flow",
379
+ name,
380
+ payload: { ms: step.ms },
381
+ meta: {
382
+ moduleId: runtime.moduleId,
383
+ instanceId: runtime.instanceId,
384
+ programId: program.programId,
385
+ runId,
386
+ stepKey: step.key,
387
+ ...timerId ? { timerId } : null,
388
+ ...tickSeq2 !== void 0 ? { tickSeq: tickSeq2 } : null,
389
+ policy,
390
+ ...patchMeta ?? null
391
+ },
392
+ effect: Effect.void,
393
+ middleware: args.middleware
394
+ });
395
+ });
396
+ const schedule = emitTimerEvents ? recordTimerEvent("workflow.timer.schedule") : Effect.void;
397
+ const onCancel = emitTimerEvents ? recordTimerEvent("workflow.timer.cancel", { reason: "interrupt" }) : Effect.void;
398
+ const fired = emitTimerEvents ? recordTimerEvent("workflow.timer.fired") : Effect.void;
399
+ const delayEffect = schedule.pipe(
400
+ Effect.zipRight(makeTimer({ host, ms: step.ms, onCancel })),
401
+ Effect.zipRight(fired)
402
+ );
403
+ const tickSeq = getTickSeq();
404
+ yield* runBoundary({
405
+ kind: "flow",
406
+ name: "workflow.delay",
407
+ payload: { ms: step.ms },
408
+ meta: {
409
+ moduleId: runtime.moduleId,
410
+ instanceId: runtime.instanceId,
411
+ programId: program.programId,
412
+ runId,
413
+ stepKey: step.key,
414
+ ...tickSeq !== void 0 ? { tickSeq } : null,
415
+ ...timerId ? { timerId } : null,
416
+ policy
417
+ },
418
+ effect: delayEffect,
419
+ middleware: args.middleware
420
+ }).pipe(Effect.asVoid);
421
+ timerTriggered = true;
422
+ continue;
423
+ }
424
+ const input = step.input ? evalInputExpr(step.input, args.payload) : defaultInputForCall();
425
+ const maxRetries = step.retryTimes ?? 0;
426
+ let exit;
427
+ for (let attempt = 1; attempt <= maxRetries + 1; attempt += 1) {
428
+ const tickSeq = getTickSeq();
429
+ const base = runBoundary({
430
+ kind: "service",
431
+ name: `workflow.call:${step.serviceId}`,
432
+ payload: { serviceId: step.serviceId },
433
+ meta: {
434
+ moduleId: runtime.moduleId,
435
+ instanceId: runtime.instanceId,
436
+ programId: program.programId,
437
+ runId,
438
+ stepKey: step.key,
439
+ serviceId: step.serviceId,
440
+ attempt,
441
+ ...tickSeq !== void 0 ? { tickSeq } : null,
442
+ policy
443
+ },
444
+ effect: step.port(input),
445
+ middleware: args.middleware
446
+ });
447
+ const withTimeout = step.timeoutMs === void 0 ? base : Effect.gen(function* () {
448
+ const timeoutMs = step.timeoutMs;
449
+ if (timeoutMs === void 0) {
450
+ return yield* base;
451
+ }
452
+ const timerId = emitTimerEvents ? `${runId}::timeout:${step.key}:a${attempt}` : void 0;
453
+ const recordTimeoutEvent = (name, patchMeta) => Effect.gen(function* () {
454
+ const tickSeq2 = getTickSeq();
455
+ yield* runBoundary({
456
+ kind: "flow",
457
+ name,
458
+ payload: { ms: timeoutMs },
459
+ meta: {
460
+ moduleId: runtime.moduleId,
461
+ instanceId: runtime.instanceId,
462
+ programId: program.programId,
463
+ runId,
464
+ stepKey: step.key,
465
+ attempt,
466
+ ...timerId ? { timerId } : null,
467
+ ...tickSeq2 !== void 0 ? { tickSeq: tickSeq2 } : null,
468
+ policy,
469
+ ...patchMeta ?? null
470
+ },
471
+ effect: Effect.void,
472
+ middleware: args.middleware
473
+ });
474
+ });
475
+ const schedule = emitTimerEvents ? recordTimeoutEvent("workflow.timeout.schedule") : Effect.void;
476
+ const onCancel = emitTimerEvents ? recordTimeoutEvent("workflow.timeout.cancel", { reason: "interrupt" }) : Effect.void;
477
+ const fired = emitTimerEvents ? recordTimeoutEvent("workflow.timeout.fired") : Effect.void;
478
+ const timeoutError = makeWorkflowError({
479
+ code: "WORKFLOW_CALL_TIMEOUT",
480
+ message: `Workflow call timed out (serviceId="${step.serviceId}", timeoutMs=${timeoutMs}).`,
481
+ programId: program.programId,
482
+ source: { stepKey: step.key },
483
+ detail: { serviceId: step.serviceId, timeoutMs, attempt }
484
+ });
485
+ const timeoutFail = schedule.pipe(
486
+ Effect.zipRight(makeTimer({ host, ms: timeoutMs, onCancel })),
487
+ Effect.zipRight(fired),
488
+ Effect.zipRight(Effect.fail(timeoutError))
489
+ );
490
+ return yield* Effect.raceFirst(base, timeoutFail);
491
+ });
492
+ const attemptExit = yield* Effect.exit(withTimeout);
493
+ exit = attemptExit;
494
+ if (!canWriteBack() || Exit.isSuccess(attemptExit)) {
495
+ break;
496
+ }
497
+ if (Cause.isInterrupted(attemptExit.cause) || Option.isNone(Cause.failureOption(attemptExit.cause))) {
498
+ break;
499
+ }
500
+ if (attempt < maxRetries + 1) {
501
+ continue;
502
+ }
503
+ break;
504
+ }
505
+ if (!exit) {
506
+ exit = Exit.succeed(void 0);
507
+ }
508
+ if (!canWriteBack()) return;
509
+ if (Exit.isSuccess(exit)) {
510
+ yield* runSteps(step.onSuccess);
511
+ } else {
512
+ const failure = Option.getOrUndefined(Cause.failureOption(exit.cause));
513
+ const isTimeout = isObjectLike(failure) && failure._tag === "WorkflowError" && failure.code === "WORKFLOW_CALL_TIMEOUT";
514
+ if (isTimeout) timerTriggered = true;
515
+ yield* runSteps(step.onFailure);
516
+ }
517
+ }
518
+ });
519
+ const runTickSeq = getTickSeq();
520
+ yield* runBoundary({
521
+ kind: "flow",
522
+ name: "workflow.run",
523
+ payload: { trigger: args.trigger },
524
+ meta: {
525
+ moduleId: runtime.moduleId,
526
+ instanceId: runtime.instanceId,
527
+ programId: program.programId,
528
+ runId,
529
+ ...runTickSeq !== void 0 ? { tickSeq: runTickSeq } : null,
530
+ policy
531
+ },
532
+ effect: runSteps(program.steps),
533
+ middleware: args.middleware
534
+ }).pipe(Effect.asVoid);
535
+ });
536
+ const limited = registry.parallelLimiter ? registry.parallelLimiter.withPermits(1)(programEffect) : programEffect;
537
+ const fiber = yield* Effect.forkScoped(
538
+ limited.pipe(
539
+ Effect.catchAllCause((cause) => {
540
+ const { errorSummary, downgrade } = toSerializableErrorSummary(cause);
541
+ const downgradeHint = downgrade ? ` (downgrade=${downgrade})` : "";
542
+ return record({
543
+ type: "diagnostic",
544
+ moduleId: runtime.moduleId,
545
+ instanceId: runtime.instanceId,
546
+ code: "workflow::run_crashed",
547
+ severity: "error",
548
+ message: `Workflow run crashed for programId="${program.programId}" runId="${runId}".${downgradeHint}`,
549
+ hint: `${errorSummary.name ? `${errorSummary.name}: ` : ""}${errorSummary.message}`,
550
+ actionTag: args.trigger.kind === "action" ? args.trigger.actionTag : void 0,
551
+ kind: "workflow_run_crashed",
552
+ trigger: {
553
+ kind: "workflow",
554
+ name: "run",
555
+ details: {
556
+ programId: program.programId,
557
+ runId,
558
+ trigger: args.trigger
559
+ }
560
+ }
561
+ }).pipe(Effect.catchAllCause(() => Effect.void));
562
+ }),
563
+ Effect.ensuring(
564
+ Effect.sync(() => {
565
+ if (state.mode === "exhaust") {
566
+ state.busy = false;
567
+ }
568
+ })
569
+ )
570
+ )
571
+ );
572
+ if (state.mode === "latest") {
573
+ state.current = fiber;
574
+ }
575
+ });
576
+ var ensureRegistry = (runtime) => Effect.gen(function* () {
577
+ const existing = getRegistry(runtime);
578
+ if (existing) {
579
+ return {
580
+ moduleId: runtime.moduleId,
581
+ instanceId: runtime.instanceId,
582
+ registry: existing
583
+ };
584
+ }
585
+ const portsReady = yield* Deferred.make();
586
+ const next = {
587
+ byActionTag: /* @__PURE__ */ new Map(),
588
+ entries: [],
589
+ watcherStarted: false,
590
+ watcherStartCount: 0,
591
+ portsResolving: false,
592
+ portsReady,
593
+ parallelLimiter: void 0
594
+ };
595
+ Object.defineProperty(runtime, WORKFLOW_REGISTRY, {
596
+ value: next,
597
+ enumerable: false,
598
+ configurable: true,
599
+ writable: false
600
+ });
601
+ return { moduleId: runtime.moduleId, instanceId: runtime.instanceId, registry: next };
602
+ });
603
+ var registerPrograms = (args) => Effect.gen(function* () {
604
+ const runtime = yield* args.moduleTag;
605
+ const { moduleId, instanceId, registry } = yield* ensureRegistry(runtime);
606
+ if (registry.parallelLimiter === void 0) {
607
+ yield* ensureLimiterReady(registry, runtime);
608
+ }
609
+ const validateNoIoStepsForOnInit = (steps, programId) => {
610
+ const visit = (step) => {
611
+ if (step.kind === "call" || step.kind === "delay") {
612
+ throw makeWorkflowError({
613
+ code: "WORKFLOW_INVALID_TRIGGER",
614
+ message: "Lifecycle onInit programs must not include call/delay (initRequired must stay sync-only; use onStart for IO/time).",
615
+ programId,
616
+ source: { stepKey: step.key },
617
+ detail: { kind: step.kind }
618
+ });
619
+ }
620
+ };
621
+ for (const s of steps) visit(s);
622
+ };
623
+ const programHasCall = (steps) => steps.some((s) => s.kind === "call");
624
+ const insertEntry = (actionTag, entry) => {
625
+ const prev = registry.byActionTag.get(actionTag);
626
+ registry.byActionTag.set(actionTag, prev ? [...prev, entry] : [entry]);
627
+ };
628
+ const internals = getRuntimeInternals(runtime);
629
+ for (const program of args.programs) {
630
+ const def = program.def;
631
+ const localId = asNonEmptyString(def.localId);
632
+ if (!localId) {
633
+ throw makeWorkflowError({
634
+ code: "WORKFLOW_INVALID_DEF",
635
+ message: "Workflow.install: def.localId must be a non-empty string.",
636
+ detail: { localId: def.localId }
637
+ });
638
+ }
639
+ const programId = `${moduleId}.${localId}`;
640
+ const compiled = compileWorkflowRuntimeStepsV1({ def });
641
+ if (def.trigger.kind === "lifecycle" && def.trigger.phase === "onInit") {
642
+ validateNoIoStepsForOnInit(compiled, programId);
643
+ }
644
+ const compiledProgram = {
645
+ programId,
646
+ localId,
647
+ trigger: def.trigger,
648
+ concurrency: resolveConcurrency(def),
649
+ priority: resolvePriority(def),
650
+ compiledSteps: compiled
651
+ };
652
+ if (!programHasCall(compiled)) {
653
+ compiledProgram.steps = compileSteps(compiled, () => {
654
+ throw makeWorkflowError({
655
+ code: "WORKFLOW_MISSING_SERVICE",
656
+ message: "Internal error: unexpected call step while resolving call-less program.",
657
+ programId,
658
+ detail: { programId }
659
+ });
660
+ });
661
+ }
662
+ const state = compiledProgram.concurrency === "latest" ? { mode: "latest", runSeq: 0, current: void 0, currentRunId: void 0 } : compiledProgram.concurrency === "exhaust" ? { mode: "exhaust", runSeq: 0, busy: false } : { mode: "parallel", runSeq: 0 };
663
+ const entry = { program: compiledProgram, state };
664
+ registry.entries.push(entry);
665
+ if (def.trigger.kind === "action") {
666
+ insertEntry(def.trigger.actionTag, entry);
667
+ } else {
668
+ if (def.trigger.phase === "onStart") {
669
+ internals.lifecycle.registerStart(
670
+ withRootEnvIfAvailable(
671
+ Effect.gen(function* () {
672
+ const middlewareOpt = yield* Effect.serviceOption(EffectOpMiddlewareTag);
673
+ const middleware = Option.isSome(middlewareOpt) ? middlewareOpt.value : void 0;
674
+ yield* ensurePortsResolved(registry, runtime).pipe(Effect.orDie);
675
+ yield* startProgramRun({
676
+ entry,
677
+ runtime,
678
+ registry,
679
+ trigger: { kind: "lifecycle", phase: "onStart" },
680
+ payload: void 0,
681
+ middleware
682
+ });
683
+ })
684
+ ),
685
+ { name: `workflow:${localId}` }
686
+ );
687
+ } else {
688
+ internals.lifecycle.registerInitRequired(
689
+ Effect.gen(function* () {
690
+ const middlewareOpt = yield* Effect.serviceOption(EffectOpMiddlewareTag);
691
+ const middleware = Option.isSome(middlewareOpt) ? middlewareOpt.value : void 0;
692
+ yield* startProgramRun({
693
+ entry,
694
+ runtime,
695
+ registry,
696
+ trigger: { kind: "lifecycle", phase: "onInit" },
697
+ payload: void 0,
698
+ middleware
699
+ });
700
+ }),
701
+ { name: `workflow:${localId}` }
702
+ );
703
+ }
704
+ }
705
+ }
706
+ void instanceId;
707
+ });
708
+ var startWatcherIfNeeded = (args) => Effect.gen(function* () {
709
+ const runtime = yield* args.moduleTag;
710
+ const init = yield* ensureRegistry(runtime);
711
+ const registry = init.registry;
712
+ if (registry.watcherStarted) {
713
+ return;
714
+ }
715
+ registry.watcherStarted = true;
716
+ registry.watcherStartCount += 1;
717
+ const middlewareOpt = yield* Effect.serviceOption(EffectOpMiddlewareTag);
718
+ const middleware = Option.isSome(middlewareOpt) ? middlewareOpt.value : void 0;
719
+ const actions$ = runtime.actions$;
720
+ const portsExit = yield* Effect.exit(ensurePortsResolved(registry, runtime));
721
+ if (Exit.isFailure(portsExit)) {
722
+ const { errorSummary, downgrade } = toSerializableErrorSummary(portsExit.cause);
723
+ const downgradeHint = downgrade ? ` (downgrade=${downgrade})` : "";
724
+ yield* record({
725
+ type: "diagnostic",
726
+ moduleId: runtime.moduleId,
727
+ instanceId: runtime.instanceId,
728
+ code: "workflow::ports_resolution_failed",
729
+ severity: "error",
730
+ message: `Workflow ports resolution failed before starting watcher.${downgradeHint}`,
731
+ hint: `${errorSummary.name ? `${errorSummary.name}: ` : ""}${errorSummary.message}`,
732
+ kind: "workflow_ports_resolution_failed",
733
+ trigger: {
734
+ kind: "workflow",
735
+ name: "portsResolution",
736
+ details: {
737
+ entryLabel: args.entryLabel
738
+ }
739
+ }
740
+ });
741
+ return;
742
+ }
743
+ yield* Stream.runForEach(
744
+ actions$,
745
+ (action) => Effect.gen(function* () {
746
+ const actionTag = resolveActionTag(action);
747
+ if (!actionTag) return;
748
+ const entries = registry.byActionTag.get(actionTag);
749
+ if (!entries || entries.length === 0) return;
750
+ const payload = isRecord(action) ? action.payload : void 0;
751
+ yield* Effect.forEach(
752
+ entries,
753
+ (entry) => startProgramRun({
754
+ entry,
755
+ runtime,
756
+ registry,
757
+ trigger: { kind: "action", actionTag },
758
+ payload,
759
+ middleware
760
+ }),
761
+ { discard: true }
762
+ );
763
+ })
764
+ ).pipe(
765
+ Effect.catchAllCause((cause) => {
766
+ const { errorSummary, downgrade } = toSerializableErrorSummary(cause);
767
+ const downgradeHint = downgrade ? ` (downgrade=${downgrade})` : "";
768
+ return record({
769
+ type: "diagnostic",
770
+ moduleId: runtime.moduleId,
771
+ instanceId: runtime.instanceId,
772
+ code: "workflow::watcher_crashed",
773
+ severity: "error",
774
+ message: `Workflow watcher crashed.${downgradeHint}`,
775
+ hint: `${errorSummary.name ? `${errorSummary.name}: ` : ""}${errorSummary.message}`,
776
+ kind: "workflow_watcher_crashed",
777
+ trigger: {
778
+ kind: "workflow",
779
+ name: "watcher",
780
+ details: {
781
+ entryLabel: args.entryLabel
782
+ }
783
+ }
784
+ });
785
+ })
786
+ );
787
+ void args.entryLabel;
788
+ });
789
+ var mountAll = (args) => {
790
+ const plan = {
791
+ setup: registerPrograms({ moduleTag: args.moduleTag, programs: args.programs, entryLabel: "mountAll" }),
792
+ run: startWatcherIfNeeded({ moduleTag: args.moduleTag, entryLabel: "mountAll" })
793
+ };
794
+ attachLogicUnitMeta(plan, {
795
+ id: "__logix_internal:workflows",
796
+ kind: "internal",
797
+ name: "workflows"
798
+ });
799
+ return plan;
800
+ };
801
+ var installOne = (args) => {
802
+ const localId = asNonEmptyString(args.program.def.localId) ?? "unknown";
803
+ const plan = {
804
+ setup: registerPrograms({ moduleTag: args.moduleTag, programs: [args.program], entryLabel: `install:${localId}` }),
805
+ run: startWatcherIfNeeded({ moduleTag: args.moduleTag, entryLabel: `install:${localId}` })
806
+ };
807
+ attachLogicUnitMeta(plan, {
808
+ id: `workflow:${localId}`,
809
+ kind: "workflow",
810
+ name: localId
811
+ });
812
+ return plan;
813
+ };
814
+
815
+ export {
816
+ mountAll,
817
+ installOne
818
+ };
819
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvcnVudGltZS9jb3JlL1dvcmtmbG93UnVudGltZS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHsgQ2F1c2UsIENvbnRleHQsIERlZmVycmVkLCBFZmZlY3QsIEV4aXQsIEZpYmVyLCBGaWJlclJlZiwgT3B0aW9uLCBTdHJlYW0gfSBmcm9tICdlZmZlY3QnXG5pbXBvcnQgKiBhcyBFZmZlY3RPcENvcmUgZnJvbSAnLi9FZmZlY3RPcENvcmUuanMnXG5pbXBvcnQgKiBhcyBEZWJ1ZyBmcm9tICcuL0RlYnVnU2luay5qcydcbmltcG9ydCAqIGFzIExvZ2ljVW5pdE1ldGEgZnJvbSAnLi9Mb2dpY1VuaXRNZXRhLmpzJ1xuaW1wb3J0IHsgdG9TZXJpYWxpemFibGVFcnJvclN1bW1hcnkgfSBmcm9tICcuL2Vycm9yU3VtbWFyeS5qcydcbmltcG9ydCB0eXBlIHsgQW55TW9kdWxlU2hhcGUsIExvZ2ljUGxhbiwgTW9kdWxlUnVudGltZSBhcyBQdWJsaWNNb2R1bGVSdW50aW1lIH0gZnJvbSAnLi9tb2R1bGUuanMnXG5pbXBvcnQgeyBIb3N0U2NoZWR1bGVyVGFnLCBUaWNrU2NoZWR1bGVyVGFnIH0gZnJvbSAnLi9lbnYuanMnXG5pbXBvcnQgeyBjdXJyZW50VHhuT3JpZ2luT3ZlcnJpZGUgfSBmcm9tICcuL1R4bk9yaWdpbk92ZXJyaWRlLmpzJ1xuaW1wb3J0IHsgZ2V0UnVudGltZUludGVybmFscyB9IGZyb20gJy4vcnVudGltZUludGVybmFsc0FjY2Vzc29yLmpzJ1xuaW1wb3J0IHsgUm9vdENvbnRleHRUYWcsIHR5cGUgUm9vdENvbnRleHQgfSBmcm9tICcuL1Jvb3RDb250ZXh0LmpzJ1xuaW1wb3J0ICogYXMgVGFza1J1bm5lciBmcm9tICcuL1Rhc2tSdW5uZXIuanMnXG5pbXBvcnQgKiBhcyBFZmZlY3RPcCBmcm9tICcuLi8uLi9lZmZlY3Qtb3AuanMnXG5pbXBvcnQgeyBtYWtlV29ya2Zsb3dFcnJvciB9IGZyb20gJy4uLy4uL3dvcmtmbG93L2Vycm9ycy5qcydcbmltcG9ydCB7IGNvbXBpbGVXb3JrZmxvd1J1bnRpbWVTdGVwc1YxLCB0eXBlIENvbXBpbGVkV29ya2Zsb3dTdGVwIH0gZnJvbSAnLi4vLi4vd29ya2Zsb3cvY29tcGlsZXIuanMnXG5pbXBvcnQgeyBldmFsSW5wdXRFeHByLCB0eXBlIENvbXBpbGVkSW5wdXRFeHByIH0gZnJvbSAnLi4vLi4vd29ya2Zsb3cvaW5wdXRFeHByLmpzJ1xuaW1wb3J0IHR5cGUgeyBXb3JrZmxvd0RlZlYxLCBXb3JrZmxvd1RyaWdnZXJWMSB9IGZyb20gJy4uLy4uL3dvcmtmbG93L21vZGVsLmpzJ1xuXG50eXBlIE1vZHVsZVRhZyA9IENvbnRleHQuVGFnPHVua25vd24sIFB1YmxpY01vZHVsZVJ1bnRpbWU8dW5rbm93biwgdW5rbm93bj4+XG5cbmV4cG9ydCB0eXBlIFdvcmtmbG93TGlrZSA9IHtcbiAgcmVhZG9ubHkgX3RhZz86ICdXb3JrZmxvdydcbiAgcmVhZG9ubHkgZGVmOiBXb3JrZmxvd0RlZlYxXG4gIHJlYWRvbmx5IHZhbGlkYXRlPzogKCkgPT4gdm9pZFxufVxuXG50eXBlIENvbmN1cnJlbmN5TW9kZSA9ICdsYXRlc3QnIHwgJ2V4aGF1c3QnIHwgJ3BhcmFsbGVsJ1xudHlwZSBQcmlvcml0eSA9ICd1cmdlbnQnIHwgJ25vblVyZ2VudCdcblxudHlwZSBTZXJ2aWNlUG9ydCA9IChpbnB1dDogdW5rbm93bikgPT4gRWZmZWN0LkVmZmVjdDx1bmtub3duLCB1bmtub3duLCB1bmtub3duPlxuXG50eXBlIENvbXBpbGVkUnVudGltZVN0ZXAgPVxuICB8IHsgcmVhZG9ubHkga2luZDogJ2Rpc3BhdGNoJzsgcmVhZG9ubHkga2V5OiBzdHJpbmc7IHJlYWRvbmx5IGFjdGlvblRhZzogc3RyaW5nOyByZWFkb25seSBwYXlsb2FkPzogQ29tcGlsZWRJbnB1dEV4cHIgfVxuICB8IHsgcmVhZG9ubHkga2luZDogJ2RlbGF5JzsgcmVhZG9ubHkga2V5OiBzdHJpbmc7IHJlYWRvbmx5IG1zOiBudW1iZXIgfVxuICB8IHtcbiAgICAgIHJlYWRvbmx5IGtpbmQ6ICdjYWxsJ1xuICAgICAgcmVhZG9ubHkga2V5OiBzdHJpbmdcbiAgICAgIHJlYWRvbmx5IHNlcnZpY2VJZDogc3RyaW5nXG4gICAgICByZWFkb25seSBpbnB1dD86IENvbXBpbGVkSW5wdXRFeHByXG4gICAgICByZWFkb25seSB0aW1lb3V0TXM/OiBudW1iZXJcbiAgICAgIHJlYWRvbmx5IHJldHJ5VGltZXM/OiBudW1iZXJcbiAgICAgIHJlYWRvbmx5IHBvcnQ6IFNlcnZpY2VQb3J0XG4gICAgICByZWFkb25seSBvblN1Y2Nlc3M6IFJlYWRvbmx5QXJyYXk8Q29tcGlsZWRSdW50aW1lU3RlcD5cbiAgICAgIHJlYWRvbmx5IG9uRmFpbHVyZTogUmVhZG9ubHlBcnJheTxDb21waWxlZFJ1bnRpbWVTdGVwPlxuICAgIH1cblxudHlwZSBDb21waWxlZFByb2dyYW0gPSB7XG4gIHJlYWRvbmx5IHByb2dyYW1JZDogc3RyaW5nXG4gIHJlYWRvbmx5IGxvY2FsSWQ6IHN0cmluZ1xuICByZWFkb25seSB0cmlnZ2VyOiBXb3JrZmxvd1RyaWdnZXJWMVxuICByZWFkb25seSBjb25jdXJyZW5jeTogQ29uY3VycmVuY3lNb2RlXG4gIHJlYWRvbmx5IHByaW9yaXR5OiBQcmlvcml0eVxuICByZWFkb25seSBjb21waWxlZFN0ZXBzOiBSZWFkb25seUFycmF5PENvbXBpbGVkV29ya2Zsb3dTdGVwPlxuICBzdGVwcz86IFJlYWRvbmx5QXJyYXk8Q29tcGlsZWRSdW50aW1lU3RlcD5cbn1cblxudHlwZSBQcm9ncmFtU3RhdGUgPVxuICB8IHsgcmVhZG9ubHkgbW9kZTogJ2xhdGVzdCc7IHJ1blNlcTogbnVtYmVyOyBjdXJyZW50PzogRmliZXIuUnVudGltZUZpYmVyPHZvaWQsIG5ldmVyPjsgY3VycmVudFJ1bklkPzogc3RyaW5nIH1cbiAgfCB7IHJlYWRvbmx5IG1vZGU6ICdleGhhdXN0JzsgcnVuU2VxOiBudW1iZXI7IGJ1c3k6IGJvb2xlYW4gfVxuICB8IHsgcmVhZG9ubHkgbW9kZTogJ3BhcmFsbGVsJzsgcnVuU2VxOiBudW1iZXIgfVxuXG50eXBlIFByb2dyYW1FbnRyeSA9IHtcbiAgcmVhZG9ubHkgcHJvZ3JhbTogQ29tcGlsZWRQcm9ncmFtXG4gIHJlYWRvbmx5IHN0YXRlOiBQcm9ncmFtU3RhdGVcbn1cblxudHlwZSBXb3JrZmxvd1JlZ2lzdHJ5VjEgPSB7XG4gIHJlYWRvbmx5IGJ5QWN0aW9uVGFnOiBNYXA8c3RyaW5nLCBSZWFkb25seUFycmF5PFByb2dyYW1FbnRyeT4+XG4gIHJlYWRvbmx5IGVudHJpZXM6IEFycmF5PFByb2dyYW1FbnRyeT5cbiAgd2F0Y2hlclN0YXJ0ZWQ6IGJvb2xlYW5cbiAgd2F0Y2hlclN0YXJ0Q291bnQ6IG51bWJlclxuICBwb3J0c1Jlc29sdmluZzogYm9vbGVhblxuICBwb3J0c1JlYWR5OiBEZWZlcnJlZC5EZWZlcnJlZDx2b2lkLCB1bmtub3duPlxuICBwYXJhbGxlbExpbWl0ZXI6IEVmZmVjdC5TZW1hcGhvcmUgfCBudWxsIHwgdW5kZWZpbmVkXG59XG5cbmNvbnN0IFdPUktGTE9XX1JFR0lTVFJZID0gU3ltYm9sLmZvcignQGxvZ2l4anMvY29yZS93b3JrZmxvd1JlZ2lzdHJ5JylcblxuY29uc3QgaXNSZWNvcmQgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9PlxuICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmICFBcnJheS5pc0FycmF5KHZhbHVlKVxuXG5jb25zdCBpc09iamVjdExpa2UgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8ICgoLi4uYXJnczogbmV2ZXJbXSkgPT4gdW5rbm93bikgPT5cbiAgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwpIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJ1xuXG5jb25zdCBnZXRSZWdpc3RyeSA9IChydW50aW1lOiBvYmplY3QpOiBXb3JrZmxvd1JlZ2lzdHJ5VjEgfCB1bmRlZmluZWQgPT5cbiAgKHJ1bnRpbWUgYXMgUmVjb3JkPFByb3BlcnR5S2V5LCB1bmtub3duPilbV09SS0ZMT1dfUkVHSVNUUlldIGFzIFdvcmtmbG93UmVnaXN0cnlWMSB8IHVuZGVmaW5lZFxuXG5jb25zdCByZXNvbHZlQWN0aW9uVGFnID0gKGFjdGlvbjogdW5rbm93bik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIGNvbnN0IHRhZyA9IGlzT2JqZWN0TGlrZShhY3Rpb24pID8gKGFjdGlvbiBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikuX3RhZyA6IHVuZGVmaW5lZFxuICBpZiAodHlwZW9mIHRhZyA9PT0gJ3N0cmluZycgJiYgdGFnLmxlbmd0aCA+IDApIHJldHVybiB0YWdcbiAgY29uc3QgdHlwZSA9IGlzT2JqZWN0TGlrZShhY3Rpb24pID8gKGFjdGlvbiBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikudHlwZSA6IHVuZGVmaW5lZFxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnICYmIHR5cGUubGVuZ3RoID4gMCkgcmV0dXJuIHR5cGVcbiAgaWYgKHRhZyAhPSBudWxsKSByZXR1cm4gU3RyaW5nKHRhZylcbiAgaWYgKHR5cGUgIT0gbnVsbCkgcmV0dXJuIFN0cmluZyh0eXBlKVxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbmNvbnN0IGFzTm9uRW1wdHlTdHJpbmcgPSAodmFsdWU6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQgPT5cbiAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS50cmltKCkubGVuZ3RoID4gMCA/IHZhbHVlLnRyaW0oKSA6IHVuZGVmaW5lZFxuXG5jb25zdCBLRVJORUxfUE9SVF9TT1VSQ0VfUkVGUkVTSCA9ICdsb2dpeC9rZXJuZWwvc291cmNlUmVmcmVzaCdcblxuY29uc3QgcmVzb2x2ZVNlcnZpY2VQb3J0ID0gKFxuICBydW50aW1lOiBQdWJsaWNNb2R1bGVSdW50aW1lPHVua25vd24sIHVua25vd24+LFxuICBlbnY6IENvbnRleHQuQ29udGV4dDx1bmtub3duPixcbiAgc2VydmljZUlkOiBzdHJpbmcsXG4gIHByb2dyYW1JZDogc3RyaW5nLFxuICBzdGVwS2V5OiBzdHJpbmcsXG4pOiBTZXJ2aWNlUG9ydCA9PiB7XG4gIGlmIChzZXJ2aWNlSWQgPT09IEtFUk5FTF9QT1JUX1NPVVJDRV9SRUZSRVNIKSB7XG4gICAgcmV0dXJuIChpbnB1dCkgPT5cbiAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgY29uc3QgZmllbGRQYXRoID0gYXNOb25FbXB0eVN0cmluZyhpc1JlY29yZChpbnB1dCkgPyBpbnB1dC5maWVsZFBhdGggOiB1bmRlZmluZWQpXG4gICAgICAgIGlmICghZmllbGRQYXRoKSB7XG4gICAgICAgICAgdGhyb3cgbWFrZVdvcmtmbG93RXJyb3Ioe1xuICAgICAgICAgICAgY29kZTogJ1dPUktGTE9XX0lOVkFMSURfU1RFUCcsXG4gICAgICAgICAgICBtZXNzYWdlOiAnS2VybmVsUG9ydCBzb3VyY2VSZWZyZXNoIHJlcXVpcmVzIGlucHV0LmZpZWxkUGF0aCAobm9uLWVtcHR5IHN0cmluZykuJyxcbiAgICAgICAgICAgIHByb2dyYW1JZCxcbiAgICAgICAgICAgIHNvdXJjZTogeyBzdGVwS2V5IH0sXG4gICAgICAgICAgICBkZXRhaWw6IHsgc2VydmljZUlkLCBpbnB1dCB9LFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpbnRlcm5hbHMgPSBnZXRSdW50aW1lSW50ZXJuYWxzKHJ1bnRpbWUpXG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSBpbnRlcm5hbHMudHJhaXRzLmdldFNvdXJjZVJlZnJlc2hIYW5kbGVyKGZpZWxkUGF0aClcblxuICAgICAgICAvLyBJZiBubyByZWZyZXNoIGhhbmRsZXIgaXMgcmVnaXN0ZXJlZCwgdHJlYXQgaXQgYXMgYSBuby1vcCAoYWxpZ25zIHdpdGggQm91bmRBcGlSdW50aW1lIGJlaGF2aW9yKS5cbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmb3JjZSA9IGlzUmVjb3JkKGlucHV0KSAmJiBpbnB1dC5mb3JjZSA9PT0gdHJ1ZVxuICAgICAgICBjb25zdCBydW5IYW5kbGVyID0gKHN0YXRlOiB1bmtub3duKSA9PlxuICAgICAgICAgIGZvcmNlID8gRWZmZWN0LmxvY2FsbHkoVGFza1J1bm5lci5mb3JjZVNvdXJjZVJlZnJlc2gsIHRydWUpKGhhbmRsZXIoc3RhdGUpKSA6IGhhbmRsZXIoc3RhdGUpXG5cbiAgICAgICAgY29uc3QgaW5UeG4gPSB5aWVsZCogRmliZXJSZWYuZ2V0KFRhc2tSdW5uZXIuaW5TeW5jVHJhbnNhY3Rpb25GaWJlcilcbiAgICAgICAgaWYgKGluVHhuKSB7XG4gICAgICAgICAgY29uc3Qgc3RhdGUgPSB5aWVsZCogcnVudGltZS5nZXRTdGF0ZVxuICAgICAgICAgIHlpZWxkKiBydW5IYW5kbGVyKHN0YXRlKVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgeWllbGQqIGludGVybmFscy50eG4ucnVuV2l0aFN0YXRlVHJhbnNhY3Rpb24oXG4gICAgICAgICAge1xuICAgICAgICAgICAga2luZDogJ3NvdXJjZS1yZWZyZXNoJyxcbiAgICAgICAgICAgIG5hbWU6IGZpZWxkUGF0aCxcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+XG4gICAgICAgICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHN0YXRlID0geWllbGQqIHJ1bnRpbWUuZ2V0U3RhdGVcbiAgICAgICAgICAgICAgeWllbGQqIHJ1bkhhbmRsZXIoc3RhdGUpXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKVxuICAgICAgfSlcbiAgfVxuXG4gIGNvbnN0IHRhZyA9IENvbnRleHQuR2VuZXJpY1RhZzx1bmtub3duPihzZXJ2aWNlSWQpXG4gIGNvbnN0IG9wdCA9IENvbnRleHQuZ2V0T3B0aW9uKGVudiwgdGFnKVxuICBpZiAoT3B0aW9uLmlzTm9uZShvcHQpKSB7XG4gICAgdGhyb3cgbWFrZVdvcmtmbG93RXJyb3Ioe1xuICAgICAgY29kZTogJ1dPUktGTE9XX01JU1NJTkdfU0VSVklDRScsXG4gICAgICBtZXNzYWdlOiBgTWlzc2luZyBzZXJ2aWNlIGZvciBzZXJ2aWNlSWQ9XCIke3NlcnZpY2VJZH1cIi5gLFxuICAgICAgcHJvZ3JhbUlkLFxuICAgICAgc291cmNlOiB7IHN0ZXBLZXkgfSxcbiAgICAgIGRldGFpbDogeyBzZXJ2aWNlSWQgfSxcbiAgICB9KVxuICB9XG5cbiAgY29uc3QgdmFsdWU6IHVua25vd24gPSBvcHQudmFsdWVcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNvbnN0IGZuID0gdmFsdWUgYXMgKGlucHV0OiB1bmtub3duKSA9PiBFZmZlY3QuRWZmZWN0PHVua25vd24sIHVua25vd24sIHVua25vd24+XG4gICAgcmV0dXJuIChpbnB1dCkgPT4gZm4oaW5wdXQpXG4gIH1cblxuICBjb25zdCBjYWxsRm4gPSBpc09iamVjdExpa2UodmFsdWUpID8gKHZhbHVlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5jYWxsIDogdW5kZWZpbmVkXG4gIGlmICh0eXBlb2YgY2FsbEZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY29uc3QgY2FsbCA9IGNhbGxGbiBhcyAodGhpczogdW5rbm93biwgaW5wdXQ6IHVua25vd24pID0+IEVmZmVjdC5FZmZlY3Q8dW5rbm93biwgdW5rbm93biwgdW5rbm93bj5cbiAgICByZXR1cm4gKGlucHV0KSA9PiBjYWxsLmNhbGwodmFsdWUsIGlucHV0KVxuICB9XG5cbiAgdGhyb3cgbWFrZVdvcmtmbG93RXJyb3Ioe1xuICAgIGNvZGU6ICdXT1JLRkxPV19JTlZBTElEX1NFUlZJQ0VfUE9SVCcsXG4gICAgbWVzc2FnZTogYEludmFsaWQgc2VydmljZSBwb3J0IGZvciBzZXJ2aWNlSWQ9XCIke3NlcnZpY2VJZH1cIiAoZXhwZWN0ZWQgYSBmdW5jdGlvbiBvciB7IGNhbGwoaW5wdXQpOiBFZmZlY3QgfSkuYCxcbiAgICBwcm9ncmFtSWQsXG4gICAgc291cmNlOiB7IHN0ZXBLZXkgfSxcbiAgICBkZXRhaWw6IHsgc2VydmljZUlkLCBwb3J0VHlwZTogdHlwZW9mIHZhbHVlIH0sXG4gIH0pXG59XG5cbmNvbnN0IGNvbXBpbGVTdGVwcyA9IChzdGVwczogUmVhZG9ubHlBcnJheTxDb21waWxlZFdvcmtmbG93U3RlcD4sIHJlc29sdmVQb3J0OiAoc2VydmljZUlkOiBzdHJpbmcsIHN0ZXBLZXk6IHN0cmluZykgPT4gU2VydmljZVBvcnQpID0+IHtcbiAgY29uc3QgdmlzaXQgPSAoc3RlcDogQ29tcGlsZWRXb3JrZmxvd1N0ZXApOiBDb21waWxlZFJ1bnRpbWVTdGVwID0+IHtcbiAgICBzd2l0Y2ggKHN0ZXAua2luZCkge1xuICAgICAgY2FzZSAnZGlzcGF0Y2gnOlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGtpbmQ6ICdkaXNwYXRjaCcsXG4gICAgICAgICAga2V5OiBzdGVwLmtleSxcbiAgICAgICAgICBhY3Rpb25UYWc6IHN0ZXAuYWN0aW9uVGFnLFxuICAgICAgICAgIC4uLihzdGVwLnBheWxvYWQgPyB7IHBheWxvYWQ6IHN0ZXAucGF5bG9hZCB9IDogbnVsbCksXG4gICAgICAgIH1cbiAgICAgIGNhc2UgJ2RlbGF5JzpcbiAgICAgICAgcmV0dXJuIHsga2luZDogJ2RlbGF5Jywga2V5OiBzdGVwLmtleSwgbXM6IHN0ZXAubXMgfVxuICAgICAgY2FzZSAnY2FsbCc6XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAga2luZDogJ2NhbGwnLFxuICAgICAgICAgIGtleTogc3RlcC5rZXksXG4gICAgICAgICAgc2VydmljZUlkOiBzdGVwLnNlcnZpY2VJZCxcbiAgICAgICAgICBwb3J0OiByZXNvbHZlUG9ydChzdGVwLnNlcnZpY2VJZCwgc3RlcC5rZXkpLFxuICAgICAgICAgIC4uLihzdGVwLmlucHV0ID8geyBpbnB1dDogc3RlcC5pbnB1dCB9IDogbnVsbCksXG4gICAgICAgICAgLi4uKHN0ZXAudGltZW91dE1zICE9PSB1bmRlZmluZWQgPyB7IHRpbWVvdXRNczogc3RlcC50aW1lb3V0TXMgfSA6IG51bGwpLFxuICAgICAgICAgIC4uLihzdGVwLnJldHJ5VGltZXMgIT09IHVuZGVmaW5lZCA/IHsgcmV0cnlUaW1lczogc3RlcC5yZXRyeVRpbWVzIH0gOiBudWxsKSxcbiAgICAgICAgICBvblN1Y2Nlc3M6IHN0ZXAub25TdWNjZXNzLm1hcCh2aXNpdCksXG4gICAgICAgICAgb25GYWlsdXJlOiBzdGVwLm9uRmFpbHVyZS5tYXAodmlzaXQpLFxuICAgICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHN0ZXBzLm1hcCh2aXNpdClcbn1cblxuY29uc3QgcmVzb2x2ZUNvbmN1cnJlbmN5ID0gKGRlZjogV29ya2Zsb3dEZWZWMSk6IENvbmN1cnJlbmN5TW9kZSA9PiAoZGVmLnBvbGljeT8uY29uY3VycmVuY3kgPz8gJ3BhcmFsbGVsJykgYXMgQ29uY3VycmVuY3lNb2RlXG5jb25zdCByZXNvbHZlUHJpb3JpdHkgPSAoZGVmOiBXb3JrZmxvd0RlZlYxKTogUHJpb3JpdHkgPT4gKGRlZi5wb2xpY3k/LnByaW9yaXR5ID8/ICd1cmdlbnQnKSBhcyBQcmlvcml0eVxuXG5jb25zdCBtYWtlUnVuSWQgPSAoaW5zdGFuY2VJZDogc3RyaW5nLCBwcm9ncmFtSWQ6IHN0cmluZywgcnVuU2VxOiBudW1iZXIpOiBzdHJpbmcgPT5cbiAgYCR7aW5zdGFuY2VJZH06OndmOiR7cHJvZ3JhbUlkfTo6ciR7cnVuU2VxfWBcblxuY29uc3QgcnVuQm91bmRhcnkgPSA8QSwgRSwgUj4oYXJnczoge1xuICByZWFkb25seSBraW5kOiBFZmZlY3RPcC5FZmZlY3RPcFsna2luZCddXG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZ1xuICByZWFkb25seSBlZmZlY3Q6IEVmZmVjdC5FZmZlY3Q8QSwgRSwgUj5cbiAgcmVhZG9ubHkgcGF5bG9hZD86IHVua25vd25cbiAgcmVhZG9ubHkgbWV0YT86IEVmZmVjdE9wLkVmZmVjdE9wWydtZXRhJ11cbiAgcmVhZG9ubHkgbWlkZGxld2FyZTogRWZmZWN0T3BDb3JlLkVmZmVjdE9wTWlkZGxld2FyZUVudiB8IHVuZGVmaW5lZFxufSk6IEVmZmVjdC5FZmZlY3Q8QSwgRSwgUj4gPT5cbiAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgIGNvbnN0IG9wID0geWllbGQqIEVmZmVjdE9wLm1ha2VJblJ1blNlc3Npb24oe1xuICAgICAga2luZDogYXJncy5raW5kLFxuICAgICAgbmFtZTogYXJncy5uYW1lLFxuICAgICAgZWZmZWN0OiBhcmdzLmVmZmVjdCxcbiAgICAgIHBheWxvYWQ6IGFyZ3MucGF5bG9hZCxcbiAgICAgIG1ldGE6IGFyZ3MubWV0YSxcbiAgICB9KVxuICAgIGNvbnN0IHN0YWNrID0gYXJncy5taWRkbGV3YXJlPy5zdGFjayA/PyBbXVxuICAgIHJldHVybiB5aWVsZCogRWZmZWN0T3AucnVuKG9wLCBzdGFjaylcbiAgfSkgYXMgdW5rbm93biBhcyBFZmZlY3QuRWZmZWN0PEEsIEUsIFI+XG5cbmNvbnN0IG1ha2VUaW1lciA9IChhcmdzOiB7XG4gIHJlYWRvbmx5IGhvc3Q6IHtcbiAgICByZWFkb25seSBzY2hlZHVsZU1pY3JvdGFzazogKGNiOiAoKSA9PiB2b2lkKSA9PiB2b2lkXG4gICAgcmVhZG9ubHkgc2NoZWR1bGVUaW1lb3V0OiAobXM6IG51bWJlciwgY2I6ICgpID0+IHZvaWQpID0+ICgpID0+IHZvaWRcbiAgfVxuICByZWFkb25seSBtczogbnVtYmVyXG4gIHJlYWRvbmx5IG9uQ2FuY2VsOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCB1bmtub3duPlxufSk6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIHVua25vd24+ID0+XG4gIEVmZmVjdC5hc3luYzx2b2lkLCBuZXZlciwgdW5rbm93bj4oKHJlc3VtZSkgPT4ge1xuICAgIGxldCBmaXJlZCA9IGZhbHNlXG4gICAgY29uc3QgY2FuY2VsID0gYXJncy5ob3N0LnNjaGVkdWxlVGltZW91dChhcmdzLm1zLCAoKSA9PiB7XG4gICAgICBmaXJlZCA9IHRydWVcbiAgICAgIC8vIFJvdXRlIHJlc3VtcHRpb24gdGhyb3VnaCBhIG1pY3JvdGFzayBib3VuZGFyeTpcbiAgICAgIC8vIC0gSW1wcm92ZXMgZGV0ZXJtaW5pc20gaW4gdGVzdHMgKGRldGVybWluaXN0aWMgSG9zdFNjaGVkdWxlcikuXG4gICAgICAvLyAtIEF2b2lkcyBkZWVwIEpTLW1pY3JvdGFzayBjaGFpbnMgdGhhdCBhcmUgaW52aXNpYmxlIHRvIEhvc3RTY2hlZHVsZXIgZmx1c2hpbmcuXG4gICAgICBhcmdzLmhvc3Quc2NoZWR1bGVNaWNyb3Rhc2soKCkgPT4gcmVzdW1lKEVmZmVjdC52b2lkKSlcbiAgICB9KVxuICAgIHJldHVybiBFZmZlY3Quc3luYygoKSA9PiB7XG4gICAgICBjYW5jZWwoKVxuICAgIH0pLnBpcGUoRWZmZWN0LnppcFJpZ2h0KGZpcmVkID8gRWZmZWN0LnZvaWQgOiBhcmdzLm9uQ2FuY2VsKSlcbiAgfSlcblxuY29uc3QgZW5zdXJlTGltaXRlclJlYWR5ID0gKHJlZ2lzdHJ5OiBXb3JrZmxvd1JlZ2lzdHJ5VjEsIHJ1bnRpbWU6IFB1YmxpY01vZHVsZVJ1bnRpbWU8dW5rbm93biwgdW5rbm93bj4pID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBpZiAocmVnaXN0cnkucGFyYWxsZWxMaW1pdGVyICE9PSB1bmRlZmluZWQpIHJldHVyblxuXG4gICAgY29uc3QgaW50ZXJuYWxzID0gZ2V0UnVudGltZUludGVybmFscyhydW50aW1lKVxuICAgIGNvbnN0IHBvbGljeSA9IHlpZWxkKiBpbnRlcm5hbHMuY29uY3VycmVuY3kucmVzb2x2ZUNvbmN1cnJlbmN5UG9saWN5KClcbiAgICBjb25zdCBsaW1pdCA9IHBvbGljeS5jb25jdXJyZW5jeUxpbWl0XG4gICAgaWYgKGxpbWl0ID09PSAndW5ib3VuZGVkJykge1xuICAgICAgcmVnaXN0cnkucGFyYWxsZWxMaW1pdGVyID0gbnVsbFxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgbiA9IHR5cGVvZiBsaW1pdCA9PT0gJ251bWJlcicgJiYgTnVtYmVyLmlzRmluaXRlKGxpbWl0KSAmJiBsaW1pdCA+PSAxID8gTWF0aC5mbG9vcihsaW1pdCkgOiAxNlxuICAgIHJlZ2lzdHJ5LnBhcmFsbGVsTGltaXRlciA9IHlpZWxkKiBFZmZlY3QubWFrZVNlbWFwaG9yZShuKVxuICB9KVxuXG5jb25zdCB3aXRoUm9vdEVudklmQXZhaWxhYmxlID0gPEEsIEUsIFI+KGVmZjogRWZmZWN0LkVmZmVjdDxBLCBFLCBSPik6IEVmZmVjdC5FZmZlY3Q8QSwgRSwgUj4gPT5cbiAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgIGNvbnN0IHJvb3RPcHQgPSB5aWVsZCogRWZmZWN0LnNlcnZpY2VPcHRpb24oUm9vdENvbnRleHRUYWcpXG4gICAgaWYgKE9wdGlvbi5pc05vbmUocm9vdE9wdCkpIHtcbiAgICAgIHJldHVybiB5aWVsZCogZWZmXG4gICAgfVxuICAgIGNvbnN0IHJvb3Q6IFJvb3RDb250ZXh0ID0gcm9vdE9wdC52YWx1ZVxuICAgIGNvbnN0IHJvb3RFbnYgPSByb290LmNvbnRleHQgPz8gKHlpZWxkKiBEZWZlcnJlZC5hd2FpdChyb290LnJlYWR5KSlcblxuICAgIGNvbnN0IGN1cnJlbnRFbnYgPSB5aWVsZCogRWZmZWN0LmNvbnRleHQ8dW5rbm93bj4oKVxuICAgIGNvbnN0IG1lcmdlZEVudiA9IENvbnRleHQubWVyZ2Uocm9vdEVudiBhcyB1bmtub3duIGFzIENvbnRleHQuQ29udGV4dDx1bmtub3duPiwgY3VycmVudEVudilcbiAgICByZXR1cm4geWllbGQqIChFZmZlY3QucHJvdmlkZShlZmYgYXMgdW5rbm93biBhcyBFZmZlY3QuRWZmZWN0PEEsIEUsIHVua25vd24+LCBtZXJnZWRFbnYpIGFzIHVua25vd24gYXMgRWZmZWN0LkVmZmVjdDxBLCBFLCBSPilcbiAgfSkgYXMgdW5rbm93biBhcyBFZmZlY3QuRWZmZWN0PEEsIEUsIFI+XG5cbmNvbnN0IGVuc3VyZVBvcnRzUmVzb2x2ZWQgPSAoXG4gIHJlZ2lzdHJ5OiBXb3JrZmxvd1JlZ2lzdHJ5VjEsXG4gIHJ1bnRpbWU6IFB1YmxpY01vZHVsZVJ1bnRpbWU8dW5rbm93biwgdW5rbm93bj4sXG4pOiBFZmZlY3QuRWZmZWN0PHZvaWQsIHVua25vd24sIHVua25vd24+ID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBkb25lID0geWllbGQqIERlZmVycmVkLmlzRG9uZShyZWdpc3RyeS5wb3J0c1JlYWR5KVxuICAgIGlmIChkb25lKSB7XG4gICAgICB5aWVsZCogRGVmZXJyZWQuYXdhaXQocmVnaXN0cnkucG9ydHNSZWFkeSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChyZWdpc3RyeS5wb3J0c1Jlc29sdmluZykge1xuICAgICAgeWllbGQqIERlZmVycmVkLmF3YWl0KHJlZ2lzdHJ5LnBvcnRzUmVhZHkpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICByZWdpc3RyeS5wb3J0c1Jlc29sdmluZyA9IHRydWVcbiAgICBjb25zdCBlbnYgPSB5aWVsZCogRWZmZWN0LmNvbnRleHQ8dW5rbm93bj4oKVxuXG4gICAgeWllbGQqIEVmZmVjdC5zeW5jKCgpID0+IHtcbiAgICAgIGNvbnN0IHBvcnRDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBTZXJ2aWNlUG9ydD4oKVxuICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiByZWdpc3RyeS5lbnRyaWVzKSB7XG4gICAgICAgIGNvbnN0IHByb2dyYW0gPSBlbnRyeS5wcm9ncmFtXG4gICAgICAgIGlmIChwcm9ncmFtLnN0ZXBzKSBjb250aW51ZVxuXG4gICAgICAgIGNvbnN0IHJlc29sdmVQb3J0ID0gKHNlcnZpY2VJZDogc3RyaW5nLCBzdGVwS2V5OiBzdHJpbmcpOiBTZXJ2aWNlUG9ydCA9PiB7XG4gICAgICAgICAgY29uc3QgY2FjaGVkID0gcG9ydENhY2hlLmdldChzZXJ2aWNlSWQpXG4gICAgICAgICAgaWYgKGNhY2hlZCkgcmV0dXJuIGNhY2hlZFxuICAgICAgICAgIGNvbnN0IHJlc29sdmVkID0gcmVzb2x2ZVNlcnZpY2VQb3J0KHJ1bnRpbWUsIGVudiwgc2VydmljZUlkLCBwcm9ncmFtLnByb2dyYW1JZCwgc3RlcEtleSlcbiAgICAgICAgICBwb3J0Q2FjaGUuc2V0KHNlcnZpY2VJZCwgcmVzb2x2ZWQpXG4gICAgICAgICAgcmV0dXJuIHJlc29sdmVkXG4gICAgICAgIH1cblxuICAgICAgICBwcm9ncmFtLnN0ZXBzID0gY29tcGlsZVN0ZXBzKHByb2dyYW0uY29tcGlsZWRTdGVwcywgcmVzb2x2ZVBvcnQpXG4gICAgICB9XG4gICAgfSkucGlwZShcbiAgICAgIEVmZmVjdC50YXAoKCkgPT4gRGVmZXJyZWQuc3VjY2VlZChyZWdpc3RyeS5wb3J0c1JlYWR5LCB1bmRlZmluZWQpKSxcbiAgICAgIEVmZmVjdC5jYXRjaEFsbENhdXNlKChjYXVzZSkgPT4gRGVmZXJyZWQuZmFpbENhdXNlKHJlZ2lzdHJ5LnBvcnRzUmVhZHksIGNhdXNlKS5waXBlKEVmZmVjdC56aXBSaWdodChFZmZlY3QuZmFpbENhdXNlKGNhdXNlKSkpKSxcbiAgICAgIEVmZmVjdC5lbnN1cmluZyhcbiAgICAgICAgRWZmZWN0LnN5bmMoKCkgPT4ge1xuICAgICAgICAgIHJlZ2lzdHJ5LnBvcnRzUmVzb2x2aW5nID0gZmFsc2VcbiAgICAgICAgfSksXG4gICAgICApLFxuICAgIClcbiAgfSlcblxuY29uc3Qgc2hvdWxkT2JzZXJ2ZUZvclJ1biA9IChkaWFnbm9zdGljczogRGVidWcuRGlhZ25vc3RpY3NMZXZlbCwgcnVuU2VxOiBudW1iZXIpOiBib29sZWFuID0+IHtcbiAgaWYgKGRpYWdub3N0aWNzID09PSAnb2ZmJykgcmV0dXJuIGZhbHNlXG4gIGlmIChkaWFnbm9zdGljcyA9PT0gJ3NhbXBsZWQnKSB7XG4gICAgLy8gRGV0ZXJtaW5pc3RpYyBzYW1wbGluZyAobm8gTWF0aC5yYW5kb20pOiAxLzE2IGJ5IHJ1blNlcS5cbiAgICByZXR1cm4gKHJ1blNlcSAmIDB4MGYpID09PSAwXG4gIH1cbiAgcmV0dXJuIHRydWVcbn1cblxuY29uc3Qgc3RhcnRQcm9ncmFtUnVuID0gKGFyZ3M6IHtcbiAgcmVhZG9ubHkgZW50cnk6IFByb2dyYW1FbnRyeVxuICByZWFkb25seSBydW50aW1lOiBQdWJsaWNNb2R1bGVSdW50aW1lPHVua25vd24sIHVua25vd24+XG4gIHJlYWRvbmx5IHJlZ2lzdHJ5OiBXb3JrZmxvd1JlZ2lzdHJ5VjFcbiAgcmVhZG9ubHkgdHJpZ2dlcjogeyByZWFkb25seSBraW5kOiAnYWN0aW9uJzsgcmVhZG9ubHkgYWN0aW9uVGFnOiBzdHJpbmcgfSB8IHsgcmVhZG9ubHkga2luZDogJ2xpZmVjeWNsZSc7IHJlYWRvbmx5IHBoYXNlOiBzdHJpbmcgfVxuICByZWFkb25seSBwYXlsb2FkOiB1bmtub3duXG4gIHJlYWRvbmx5IG1pZGRsZXdhcmU6IEVmZmVjdE9wQ29yZS5FZmZlY3RPcE1pZGRsZXdhcmVFbnYgfCB1bmRlZmluZWRcbn0pOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCB1bmtub3duPiA9PlxuICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgY29uc3QgeyBlbnRyeSwgcnVudGltZSwgcmVnaXN0cnkgfSA9IGFyZ3NcbiAgICBjb25zdCB7IHByb2dyYW0sIHN0YXRlIH0gPSBlbnRyeVxuXG4gICAgY29uc3QgZGlhZ25vc3RpY3MgPSB5aWVsZCogRmliZXJSZWYuZ2V0KERlYnVnLmN1cnJlbnREaWFnbm9zdGljc0xldmVsKVxuXG4gICAgY29uc3QgYmVnaW5SdW4gPSAoKTogeyByZWFkb25seSBydW5TZXE6IG51bWJlcjsgcmVhZG9ubHkgcnVuSWQ6IHN0cmluZzsgcmVhZG9ubHkgY2FuV3JpdGVCYWNrOiAoKSA9PiBib29sZWFuIH0gPT4ge1xuICAgICAgaWYgKHN0YXRlLm1vZGUgPT09ICdsYXRlc3QnKSB7XG4gICAgICAgIHN0YXRlLnJ1blNlcSArPSAxXG4gICAgICAgIGNvbnN0IHJ1blNlcSA9IHN0YXRlLnJ1blNlcVxuICAgICAgICBjb25zdCBydW5JZCA9IG1ha2VSdW5JZChydW50aW1lLmluc3RhbmNlSWQsIHByb2dyYW0ucHJvZ3JhbUlkLCBydW5TZXEpXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcnVuU2VxLFxuICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgIGNhbldyaXRlQmFjazogKCkgPT4gc3RhdGUucnVuU2VxID09PSBydW5TZXEsXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc3RhdGUucnVuU2VxICs9IDFcbiAgICAgIGNvbnN0IHJ1blNlcSA9IHN0YXRlLnJ1blNlcVxuICAgICAgY29uc3QgcnVuSWQgPSBtYWtlUnVuSWQocnVudGltZS5pbnN0YW5jZUlkLCBwcm9ncmFtLnByb2dyYW1JZCwgcnVuU2VxKVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcnVuU2VxLFxuICAgICAgICBydW5JZCxcbiAgICAgICAgY2FuV3JpdGVCYWNrOiAoKSA9PiB0cnVlLFxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzdGF0ZS5tb2RlID09PSAnZXhoYXVzdCcpIHtcbiAgICAgIGlmIChzdGF0ZS5idXN5KSB7XG4gICAgICAgIGlmIChkaWFnbm9zdGljcyAhPT0gJ29mZicpIHtcbiAgICAgICAgICBjb25zdCBvYnNlcnZlID0gc2hvdWxkT2JzZXJ2ZUZvclJ1bihkaWFnbm9zdGljcywgc3RhdGUucnVuU2VxKVxuICAgICAgICAgIGNvbnN0IHRpY2tTZXEgPSBvYnNlcnZlID8gKHlpZWxkKiBUaWNrU2NoZWR1bGVyVGFnKS5nZXRUaWNrU2VxKCkgOiB1bmRlZmluZWRcbiAgICAgICAgICB5aWVsZCogcnVuQm91bmRhcnkoe1xuICAgICAgICAgICAga2luZDogJ2Zsb3cnLFxuICAgICAgICAgICAgbmFtZTogJ3dvcmtmbG93LmRyb3AnLFxuICAgICAgICAgICAgcGF5bG9hZDogeyBwcm9ncmFtSWQ6IHByb2dyYW0ucHJvZ3JhbUlkLCB0cmlnZ2VyOiBhcmdzLnRyaWdnZXIgfSxcbiAgICAgICAgICAgIG1ldGE6IHtcbiAgICAgICAgICAgICAgbW9kdWxlSWQ6IHJ1bnRpbWUubW9kdWxlSWQsXG4gICAgICAgICAgICAgIGluc3RhbmNlSWQ6IHJ1bnRpbWUuaW5zdGFuY2VJZCxcbiAgICAgICAgICAgICAgcHJvZ3JhbUlkOiBwcm9ncmFtLnByb2dyYW1JZCxcbiAgICAgICAgICAgICAgLi4uKHRpY2tTZXEgIT09IHVuZGVmaW5lZCA/IHsgdGlja1NlcSB9IDogbnVsbCksXG4gICAgICAgICAgICAgIHBvbGljeTogeyBkaXNhYmxlT2JzZXJ2ZXJzOiAhb2JzZXJ2ZSB9LFxuICAgICAgICAgICAgICByZWFzb246ICdleGhhdXN0JyBhcyBjb25zdCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlZmZlY3Q6IEVmZmVjdC52b2lkLFxuICAgICAgICAgICAgbWlkZGxld2FyZTogYXJncy5taWRkbGV3YXJlLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICBzdGF0ZS5idXN5ID0gdHJ1ZVxuICAgIH1cblxuICAgIGNvbnN0IHsgcnVuU2VxLCBydW5JZCwgY2FuV3JpdGVCYWNrIH0gPSBiZWdpblJ1bigpXG5cbiAgICBpZiAoc3RhdGUubW9kZSA9PT0gJ2xhdGVzdCcpIHtcbiAgICAgIGNvbnN0IHByZXYgPSBzdGF0ZS5jdXJyZW50XG4gICAgICBjb25zdCBwcmV2UnVuSWQgPSBzdGF0ZS5jdXJyZW50UnVuSWRcbiAgICAgIGlmIChwcmV2KSB7XG4gICAgICAgIHlpZWxkKiBGaWJlci5pbnRlcnJ1cHRGb3JrKHByZXYpXG4gICAgICAgIGlmIChkaWFnbm9zdGljcyAhPT0gJ29mZicpIHtcbiAgICAgICAgICBjb25zdCBvYnNlcnZlID0gc2hvdWxkT2JzZXJ2ZUZvclJ1bihkaWFnbm9zdGljcywgcnVuU2VxKVxuICAgICAgICAgIGNvbnN0IHRpY2tTZXEgPSBvYnNlcnZlID8gKHlpZWxkKiBUaWNrU2NoZWR1bGVyVGFnKS5nZXRUaWNrU2VxKCkgOiB1bmRlZmluZWRcbiAgICAgICAgICB5aWVsZCogcnVuQm91bmRhcnkoe1xuICAgICAgICAgICAga2luZDogJ2Zsb3cnLFxuICAgICAgICAgICAgbmFtZTogJ3dvcmtmbG93LmNhbmNlbCcsXG4gICAgICAgICAgICBwYXlsb2FkOiB7IHByb2dyYW1JZDogcHJvZ3JhbS5wcm9ncmFtSWQsIGNhbmNlbGxlZDogcHJldlJ1bklkLCBieTogcnVuSWQgfSxcbiAgICAgICAgICAgIG1ldGE6IHtcbiAgICAgICAgICAgICAgbW9kdWxlSWQ6IHJ1bnRpbWUubW9kdWxlSWQsXG4gICAgICAgICAgICAgIGluc3RhbmNlSWQ6IHJ1bnRpbWUuaW5zdGFuY2VJZCxcbiAgICAgICAgICAgICAgcHJvZ3JhbUlkOiBwcm9ncmFtLnByb2dyYW1JZCxcbiAgICAgICAgICAgICAgLi4uKHRpY2tTZXEgIT09IHVuZGVmaW5lZCA/IHsgdGlja1NlcSB9IDogbnVsbCksXG4gICAgICAgICAgICAgIHBvbGljeTogeyBkaXNhYmxlT2JzZXJ2ZXJzOiAhb2JzZXJ2ZSB9LFxuICAgICAgICAgICAgICByZWFzb246ICdsYXRlc3QnIGFzIGNvbnN0LFxuICAgICAgICAgICAgICBjYW5jZWxsZWRCeVJ1bklkOiBydW5JZCxcbiAgICAgICAgICAgICAgY2FuY2VsbGVkUnVuSWQ6IHByZXZSdW5JZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlZmZlY3Q6IEVmZmVjdC52b2lkLFxuICAgICAgICAgICAgbWlkZGxld2FyZTogYXJncy5taWRkbGV3YXJlLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN0YXRlLmN1cnJlbnRSdW5JZCA9IHJ1bklkXG4gICAgfVxuXG4gICAgY29uc3Qgb2JzZXJ2ZSA9IHNob3VsZE9ic2VydmVGb3JSdW4oZGlhZ25vc3RpY3MsIHJ1blNlcSlcbiAgICBjb25zdCBwb2xpY3kgPSB7IGRpc2FibGVPYnNlcnZlcnM6ICFvYnNlcnZlIH0gc2F0aXNmaWVzIE5vbk51bGxhYmxlPEVmZmVjdE9wLkVmZmVjdE9wWydtZXRhJ10+Wydwb2xpY3knXVxuXG4gICAgY29uc3QgcHJvZ3JhbUVmZmVjdCA9IEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgIGNvbnN0IGhvc3QgPSB5aWVsZCogSG9zdFNjaGVkdWxlclRhZ1xuICAgICAgY29uc3QgdGljayA9IHlpZWxkKiBUaWNrU2NoZWR1bGVyVGFnXG5cbiAgICAgIGlmICghcHJvZ3JhbS5zdGVwcykge1xuICAgICAgICBjb25zdCBlbnYgPSB5aWVsZCogRWZmZWN0LmNvbnRleHQ8dW5rbm93bj4oKVxuICAgICAgICBjb25zdCBwb3J0Q2FjaGUgPSBuZXcgTWFwPHN0cmluZywgU2VydmljZVBvcnQ+KClcbiAgICAgICAgY29uc3QgcmVzb2x2ZVBvcnQgPSAoc2VydmljZUlkOiBzdHJpbmcsIHN0ZXBLZXk6IHN0cmluZyk6IFNlcnZpY2VQb3J0ID0+IHtcbiAgICAgICAgICBjb25zdCBjYWNoZWQgPSBwb3J0Q2FjaGUuZ2V0KHNlcnZpY2VJZClcbiAgICAgICAgICBpZiAoY2FjaGVkKSByZXR1cm4gY2FjaGVkXG4gICAgICAgICAgY29uc3QgcmVzb2x2ZWQgPSByZXNvbHZlU2VydmljZVBvcnQocnVudGltZSwgZW52LCBzZXJ2aWNlSWQsIHByb2dyYW0ucHJvZ3JhbUlkLCBzdGVwS2V5KVxuICAgICAgICAgIHBvcnRDYWNoZS5zZXQoc2VydmljZUlkLCByZXNvbHZlZClcbiAgICAgICAgICByZXR1cm4gcmVzb2x2ZWRcbiAgICAgICAgfVxuICAgICAgICBwcm9ncmFtLnN0ZXBzID0gY29tcGlsZVN0ZXBzKHByb2dyYW0uY29tcGlsZWRTdGVwcywgcmVzb2x2ZVBvcnQpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGdldFRpY2tTZXEgPSAoKTogbnVtYmVyIHwgdW5kZWZpbmVkID0+IChvYnNlcnZlID8gdGljay5nZXRUaWNrU2VxKCkgOiB1bmRlZmluZWQpXG4gICAgICBjb25zdCBlbWl0VGltZXJFdmVudHMgPSBvYnNlcnZlICYmIGRpYWdub3N0aWNzID09PSAnZnVsbCdcblxuICAgICAgY29uc3QgZXZhbFBheWxvYWQgPSAoZXhwcjogQ29tcGlsZWRJbnB1dEV4cHIgfCB1bmRlZmluZWQpOiB1bmtub3duID0+IChleHByID8gZXZhbElucHV0RXhwcihleHByLCBhcmdzLnBheWxvYWQpIDogdW5kZWZpbmVkKVxuXG4gICAgICBjb25zdCBkZWZhdWx0SW5wdXRGb3JDYWxsID0gKCk6IHVua25vd24gPT5cbiAgICAgICAgYXJncy50cmlnZ2VyLmtpbmQgPT09ICdhY3Rpb24nID8gYXJncy5wYXlsb2FkIDogdW5kZWZpbmVkXG5cbiAgICAgIGxldCB0aW1lclRyaWdnZXJlZCA9IGZhbHNlXG5cbiAgICAgIGNvbnN0IHJ1blN0ZXBzID0gKHN0ZXBzOiBSZWFkb25seUFycmF5PENvbXBpbGVkUnVudGltZVN0ZXA+KTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgdW5rbm93bj4gPT5cbiAgICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgIGZvciAoY29uc3Qgc3RlcCBvZiBzdGVwcykge1xuICAgICAgICAgICAgaWYgKCFjYW5Xcml0ZUJhY2soKSkgcmV0dXJuXG5cbiAgICAgICAgICAgIGlmIChzdGVwLmtpbmQgPT09ICdkaXNwYXRjaCcpIHtcbiAgICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGV2YWxQYXlsb2FkKHN0ZXAucGF5bG9hZClcbiAgICAgICAgICAgICAgY29uc3QgYWN0aW9uID0geyBfdGFnOiBzdGVwLmFjdGlvblRhZywgcGF5bG9hZCB9XG4gICAgICAgICAgICAgIGNvbnN0IHRpY2tTZXEgPSBnZXRUaWNrU2VxKClcblxuICAgICAgICAgICAgICBjb25zdCBkaXNwYXRjaEVmZmVjdEJhc2UgPVxuICAgICAgICAgICAgICAgIHByb2dyYW0ucHJpb3JpdHkgPT09ICdub25VcmdlbnQnID8gcnVudGltZS5kaXNwYXRjaExvd1ByaW9yaXR5KGFjdGlvbikgOiBydW50aW1lLmRpc3BhdGNoKGFjdGlvbilcblxuICAgICAgICAgICAgICBjb25zdCBkaXNwYXRjaEVmZmVjdCA9IHRpbWVyVHJpZ2dlcmVkXG4gICAgICAgICAgICAgICAgPyBFZmZlY3QubG9jYWxseShcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudFR4bk9yaWdpbk92ZXJyaWRlLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAga2luZDogJ3dvcmtmbG93LnRpbWVyJyxcbiAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBgdGltZXI6JHtwcm9ncmFtLnByb2dyYW1JZH06JHtzdGVwLmtleX1gLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgKShkaXNwYXRjaEVmZmVjdEJhc2UpXG4gICAgICAgICAgICAgICAgOiBkaXNwYXRjaEVmZmVjdEJhc2VcblxuICAgICAgICAgICAgICB5aWVsZCogcnVuQm91bmRhcnkoe1xuICAgICAgICAgICAgICAgIGtpbmQ6ICdmbG93JyxcbiAgICAgICAgICAgICAgICBuYW1lOiAnd29ya2Zsb3cuZGlzcGF0Y2gnLFxuICAgICAgICAgICAgICAgIHBheWxvYWQ6IHsgYWN0aW9uVGFnOiBzdGVwLmFjdGlvblRhZyB9LFxuICAgICAgICAgICAgICAgIG1ldGE6IHtcbiAgICAgICAgICAgICAgICAgIG1vZHVsZUlkOiBydW50aW1lLm1vZHVsZUlkLFxuICAgICAgICAgICAgICAgICAgaW5zdGFuY2VJZDogcnVudGltZS5pbnN0YW5jZUlkLFxuICAgICAgICAgICAgICAgICAgcHJvZ3JhbUlkOiBwcm9ncmFtLnByb2dyYW1JZCxcbiAgICAgICAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgICAgICAgc3RlcEtleTogc3RlcC5rZXksXG4gICAgICAgICAgICAgICAgICAuLi4odGlja1NlcSAhPT0gdW5kZWZpbmVkID8geyB0aWNrU2VxIH0gOiBudWxsKSxcbiAgICAgICAgICAgICAgICAgIHBvbGljeSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVmZmVjdDogZGlzcGF0Y2hFZmZlY3QsXG4gICAgICAgICAgICAgICAgbWlkZGxld2FyZTogYXJncy5taWRkbGV3YXJlLFxuICAgICAgICAgICAgICB9KS5waXBlKEVmZmVjdC5hc1ZvaWQpXG4gICAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzdGVwLmtpbmQgPT09ICdkZWxheScpIHtcbiAgICAgICAgICAgICAgY29uc3QgdGltZXJJZCA9IGVtaXRUaW1lckV2ZW50cyA/IGAke3J1bklkfTo6dGltZXI6JHtzdGVwLmtleX1gIDogdW5kZWZpbmVkXG5cbiAgICAgICAgICAgICAgY29uc3QgcmVjb3JkVGltZXJFdmVudCA9IChuYW1lOiBzdHJpbmcsIHBhdGNoTWV0YT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PlxuICAgICAgICAgICAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHRpY2tTZXEgPSBnZXRUaWNrU2VxKClcbiAgICAgICAgICAgICAgICAgIHlpZWxkKiBydW5Cb3VuZGFyeSh7XG4gICAgICAgICAgICAgICAgICAgIGtpbmQ6ICdmbG93JyxcbiAgICAgICAgICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgcGF5bG9hZDogeyBtczogc3RlcC5tcyB9LFxuICAgICAgICAgICAgICAgICAgICBtZXRhOiB7XG4gICAgICAgICAgICAgICAgICAgICAgbW9kdWxlSWQ6IHJ1bnRpbWUubW9kdWxlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VJZDogcnVudGltZS5pbnN0YW5jZUlkLFxuICAgICAgICAgICAgICAgICAgICAgIHByb2dyYW1JZDogcHJvZ3JhbS5wcm9ncmFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICAgICAgICAgICAgc3RlcEtleTogc3RlcC5rZXksXG4gICAgICAgICAgICAgICAgICAgICAgLi4uKHRpbWVySWQgPyB7IHRpbWVySWQgfSA6IG51bGwpLFxuICAgICAgICAgICAgICAgICAgICAgIC4uLih0aWNrU2VxICE9PSB1bmRlZmluZWQgPyB7IHRpY2tTZXEgfSA6IG51bGwpLFxuICAgICAgICAgICAgICAgICAgICAgIHBvbGljeSxcbiAgICAgICAgICAgICAgICAgICAgICAuLi4ocGF0Y2hNZXRhID8/IG51bGwpLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBlZmZlY3Q6IEVmZmVjdC52b2lkLFxuICAgICAgICAgICAgICAgICAgICBtaWRkbGV3YXJlOiBhcmdzLm1pZGRsZXdhcmUsXG4gICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgICAgY29uc3Qgc2NoZWR1bGUgPSBlbWl0VGltZXJFdmVudHMgPyByZWNvcmRUaW1lckV2ZW50KCd3b3JrZmxvdy50aW1lci5zY2hlZHVsZScpIDogRWZmZWN0LnZvaWRcbiAgICAgICAgICAgICAgY29uc3Qgb25DYW5jZWwgPSBlbWl0VGltZXJFdmVudHMgPyByZWNvcmRUaW1lckV2ZW50KCd3b3JrZmxvdy50aW1lci5jYW5jZWwnLCB7IHJlYXNvbjogJ2ludGVycnVwdCcgfSkgOiBFZmZlY3Qudm9pZFxuICAgICAgICAgICAgICBjb25zdCBmaXJlZCA9IGVtaXRUaW1lckV2ZW50cyA/IHJlY29yZFRpbWVyRXZlbnQoJ3dvcmtmbG93LnRpbWVyLmZpcmVkJykgOiBFZmZlY3Qudm9pZFxuXG4gICAgICAgICAgICAgIGNvbnN0IGRlbGF5RWZmZWN0ID0gc2NoZWR1bGUucGlwZShcbiAgICAgICAgICAgICAgICBFZmZlY3QuemlwUmlnaHQobWFrZVRpbWVyKHsgaG9zdCwgbXM6IHN0ZXAubXMsIG9uQ2FuY2VsIH0pKSxcbiAgICAgICAgICAgICAgICBFZmZlY3QuemlwUmlnaHQoZmlyZWQpLFxuICAgICAgICAgICAgICApXG5cbiAgICAgICAgICAgICAgY29uc3QgdGlja1NlcSA9IGdldFRpY2tTZXEoKVxuXG4gICAgICAgICAgICAgIHlpZWxkKiBydW5Cb3VuZGFyeSh7XG4gICAgICAgICAgICAgICAga2luZDogJ2Zsb3cnLFxuICAgICAgICAgICAgICAgIG5hbWU6ICd3b3JrZmxvdy5kZWxheScsXG4gICAgICAgICAgICAgICAgcGF5bG9hZDogeyBtczogc3RlcC5tcyB9LFxuICAgICAgICAgICAgICAgIG1ldGE6IHtcbiAgICAgICAgICAgICAgICAgIG1vZHVsZUlkOiBydW50aW1lLm1vZHVsZUlkLFxuICAgICAgICAgICAgICAgICAgaW5zdGFuY2VJZDogcnVudGltZS5pbnN0YW5jZUlkLFxuICAgICAgICAgICAgICAgICAgcHJvZ3JhbUlkOiBwcm9ncmFtLnByb2dyYW1JZCxcbiAgICAgICAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgICAgICAgc3RlcEtleTogc3RlcC5rZXksXG4gICAgICAgICAgICAgICAgICAuLi4odGlja1NlcSAhPT0gdW5kZWZpbmVkID8geyB0aWNrU2VxIH0gOiBudWxsKSxcbiAgICAgICAgICAgICAgICAgIC4uLih0aW1lcklkID8geyB0aW1lcklkIH0gOiBudWxsKSxcbiAgICAgICAgICAgICAgICAgIHBvbGljeSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVmZmVjdDogZGVsYXlFZmZlY3QsXG4gICAgICAgICAgICAgICAgbWlkZGxld2FyZTogYXJncy5taWRkbGV3YXJlLFxuICAgICAgICAgICAgICB9KS5waXBlKEVmZmVjdC5hc1ZvaWQpXG5cbiAgICAgICAgICAgICAgdGltZXJUcmlnZ2VyZWQgPSB0cnVlXG4gICAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGNhbGxcbiAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gc3RlcC5pbnB1dCA/IGV2YWxJbnB1dEV4cHIoc3RlcC5pbnB1dCwgYXJncy5wYXlsb2FkKSA6IGRlZmF1bHRJbnB1dEZvckNhbGwoKVxuICAgICAgICAgICAgY29uc3QgbWF4UmV0cmllcyA9IHN0ZXAucmV0cnlUaW1lcyA/PyAwXG4gICAgICAgICAgICAvLyBBdHRlbXB0IGlkIGlzIDEtYmFzZWQgYW5kIHN0YWJsZSB3aXRoaW4gYSBydW4uXG4gICAgICAgICAgICBsZXQgZXhpdDogRXhpdC5FeGl0PHVua25vd24sIHVua25vd24+IHwgdW5kZWZpbmVkXG4gICAgICAgICAgICBmb3IgKGxldCBhdHRlbXB0ID0gMTsgYXR0ZW1wdCA8PSBtYXhSZXRyaWVzICsgMTsgYXR0ZW1wdCArPSAxKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHRpY2tTZXEgPSBnZXRUaWNrU2VxKClcblxuICAgICAgICAgICAgICBjb25zdCBiYXNlID0gcnVuQm91bmRhcnkoe1xuICAgICAgICAgICAgICAgIGtpbmQ6ICdzZXJ2aWNlJyxcbiAgICAgICAgICAgICAgICBuYW1lOiBgd29ya2Zsb3cuY2FsbDoke3N0ZXAuc2VydmljZUlkfWAsXG4gICAgICAgICAgICAgICAgcGF5bG9hZDogeyBzZXJ2aWNlSWQ6IHN0ZXAuc2VydmljZUlkIH0sXG4gICAgICAgICAgICAgICAgbWV0YToge1xuICAgICAgICAgICAgICAgICAgbW9kdWxlSWQ6IHJ1bnRpbWUubW9kdWxlSWQsXG4gICAgICAgICAgICAgICAgICBpbnN0YW5jZUlkOiBydW50aW1lLmluc3RhbmNlSWQsXG4gICAgICAgICAgICAgICAgICBwcm9ncmFtSWQ6IHByb2dyYW0ucHJvZ3JhbUlkLFxuICAgICAgICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICAgICAgICBzdGVwS2V5OiBzdGVwLmtleSxcbiAgICAgICAgICAgICAgICAgIHNlcnZpY2VJZDogc3RlcC5zZXJ2aWNlSWQsXG4gICAgICAgICAgICAgICAgICBhdHRlbXB0LFxuICAgICAgICAgICAgICAgICAgLi4uKHRpY2tTZXEgIT09IHVuZGVmaW5lZCA/IHsgdGlja1NlcSB9IDogbnVsbCksXG4gICAgICAgICAgICAgICAgICBwb2xpY3ksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlZmZlY3Q6IHN0ZXAucG9ydChpbnB1dCksXG4gICAgICAgICAgICAgICAgbWlkZGxld2FyZTogYXJncy5taWRkbGV3YXJlLFxuICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgIGNvbnN0IHdpdGhUaW1lb3V0ID1cbiAgICAgICAgICAgICAgICBzdGVwLnRpbWVvdXRNcyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICA/IGJhc2VcbiAgICAgICAgICAgICAgICAgIDogRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRpbWVvdXRNcyA9IHN0ZXAudGltZW91dE1zXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHRpbWVvdXRNcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBEZWZlbnNpdmU6IFRTIGRvZXNuJ3Qga2VlcCBuYXJyb3dpbmcgYWNyb3NzIGdlbmVyYXRvciBib3VuZGFyaWVzLlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHlpZWxkKiBiYXNlXG4gICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgLy8gVW5pcXVlIHBlciBhdHRlbXB0IChvdGhlcndpc2UgcmV0cmllcyB3b3VsZCByZXVzZSB0aGUgc2FtZSB0aW1lcklkIGFuZCBicmVhayBleHBsYWluYWJpbGl0eSkuXG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGltZXJJZCA9IGVtaXRUaW1lckV2ZW50cyA/IGAke3J1bklkfTo6dGltZW91dDoke3N0ZXAua2V5fTphJHthdHRlbXB0fWAgOiB1bmRlZmluZWRcblxuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlY29yZFRpbWVvdXRFdmVudCA9IChuYW1lOiBzdHJpbmcsIHBhdGNoTWV0YT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0aWNrU2VxID0gZ2V0VGlja1NlcSgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHlpZWxkKiBydW5Cb3VuZGFyeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAga2luZDogJ2Zsb3cnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF5bG9hZDogeyBtczogdGltZW91dE1zIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0YToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlSWQ6IHJ1bnRpbWUubW9kdWxlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUlkOiBydW50aW1lLmluc3RhbmNlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9ncmFtSWQ6IHByb2dyYW0ucHJvZ3JhbUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwS2V5OiBzdGVwLmtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dGVtcHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi4odGltZXJJZCA/IHsgdGltZXJJZCB9IDogbnVsbCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi4odGlja1NlcSAhPT0gdW5kZWZpbmVkID8geyB0aWNrU2VxIH0gOiBudWxsKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvbGljeSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLihwYXRjaE1ldGEgPz8gbnVsbCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3Q6IEVmZmVjdC52b2lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pZGRsZXdhcmU6IGFyZ3MubWlkZGxld2FyZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzY2hlZHVsZSA9IGVtaXRUaW1lckV2ZW50cyA/IHJlY29yZFRpbWVvdXRFdmVudCgnd29ya2Zsb3cudGltZW91dC5zY2hlZHVsZScpIDogRWZmZWN0LnZvaWRcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvbkNhbmNlbCA9IGVtaXRUaW1lckV2ZW50c1xuICAgICAgICAgICAgICAgICAgICAgICAgPyByZWNvcmRUaW1lb3V0RXZlbnQoJ3dvcmtmbG93LnRpbWVvdXQuY2FuY2VsJywgeyByZWFzb246ICdpbnRlcnJ1cHQnIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICA6IEVmZmVjdC52b2lkXG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWQgPSBlbWl0VGltZXJFdmVudHMgPyByZWNvcmRUaW1lb3V0RXZlbnQoJ3dvcmtmbG93LnRpbWVvdXQuZmlyZWQnKSA6IEVmZmVjdC52b2lkXG5cbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0aW1lb3V0RXJyb3IgPSBtYWtlV29ya2Zsb3dFcnJvcih7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2RlOiAnV09SS0ZMT1dfQ0FMTF9USU1FT1VUJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGBXb3JrZmxvdyBjYWxsIHRpbWVkIG91dCAoc2VydmljZUlkPVwiJHtzdGVwLnNlcnZpY2VJZH1cIiwgdGltZW91dE1zPSR7dGltZW91dE1zfSkuYCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2dyYW1JZDogcHJvZ3JhbS5wcm9ncmFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IHsgc3RlcEtleTogc3RlcC5rZXkgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRldGFpbDogeyBzZXJ2aWNlSWQ6IHN0ZXAuc2VydmljZUlkLCB0aW1lb3V0TXMsIGF0dGVtcHQgfSxcbiAgICAgICAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGltZW91dEZhaWwgPSBzY2hlZHVsZS5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgRWZmZWN0LnppcFJpZ2h0KG1ha2VUaW1lcih7IGhvc3QsIG1zOiB0aW1lb3V0TXMsIG9uQ2FuY2VsIH0pKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIEVmZmVjdC56aXBSaWdodChmaXJlZCksXG4gICAgICAgICAgICAgICAgICAgICAgICBFZmZlY3QuemlwUmlnaHQoRWZmZWN0LmZhaWwodGltZW91dEVycm9yKSksXG4gICAgICAgICAgICAgICAgICAgICAgKVxuXG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHlpZWxkKiBFZmZlY3QucmFjZUZpcnN0KGJhc2UsIHRpbWVvdXRGYWlsKVxuICAgICAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgIGNvbnN0IGF0dGVtcHRFeGl0ID0geWllbGQqIEVmZmVjdC5leGl0KHdpdGhUaW1lb3V0KVxuICAgICAgICAgICAgICBleGl0ID0gYXR0ZW1wdEV4aXRcblxuICAgICAgICAgICAgICBpZiAoIWNhbldyaXRlQmFjaygpIHx8IEV4aXQuaXNTdWNjZXNzKGF0dGVtcHRFeGl0KSkge1xuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBEbyBub3QgcmV0cnkgZGVmZWN0cy9pbnRlcnJ1cHRzOyBvbmx5IHJldHJ5IGZhaWx1cmUtY2hhbm5lbCBlcnJvcnMuXG4gICAgICAgICAgICAgIGlmIChDYXVzZS5pc0ludGVycnVwdGVkKGF0dGVtcHRFeGl0LmNhdXNlKSB8fCBPcHRpb24uaXNOb25lKENhdXNlLmZhaWx1cmVPcHRpb24oYXR0ZW1wdEV4aXQuY2F1c2UpKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBSZXRyeSBpZiB3ZSBzdGlsbCBoYXZlIHJlbWFpbmluZyBhdHRlbXB0cy5cbiAgICAgICAgICAgICAgaWYgKGF0dGVtcHQgPCBtYXhSZXRyaWVzICsgMSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBEZWZlbnNpdmU6IGF0dGVtcHQgbG9vcCBhbHdheXMgcnVucyBhdCBsZWFzdCBvbmNlLlxuICAgICAgICAgICAgaWYgKCFleGl0KSB7XG4gICAgICAgICAgICAgIGV4aXQgPSBFeGl0LnN1Y2NlZWQodW5kZWZpbmVkKSBhcyBFeGl0LkV4aXQ8dW5rbm93biwgdW5rbm93bj5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFjYW5Xcml0ZUJhY2soKSkgcmV0dXJuXG5cbiAgICAgICAgICAgIGlmIChFeGl0LmlzU3VjY2VzcyhleGl0KSkge1xuICAgICAgICAgICAgICB5aWVsZCogcnVuU3RlcHMoc3RlcC5vblN1Y2Nlc3MpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBUaW1lb3V0IHVzZXMgYSB0aW1lcjsgbWFyayB0aGUgY29udGludWF0aW9uIGFzIHRpbWVyLXRyaWdnZXJlZCAoZm9yIHRyYWNlOnRpY2sudHJpZ2dlclN1bW1hcnkpLlxuICAgICAgICAgICAgICBjb25zdCBmYWlsdXJlID0gT3B0aW9uLmdldE9yVW5kZWZpbmVkKENhdXNlLmZhaWx1cmVPcHRpb24oZXhpdC5jYXVzZSkpXG4gICAgICAgICAgICAgIGNvbnN0IGlzVGltZW91dCA9XG4gICAgICAgICAgICAgICAgaXNPYmplY3RMaWtlKGZhaWx1cmUpICYmXG4gICAgICAgICAgICAgICAgKGZhaWx1cmUgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLl90YWcgPT09ICdXb3JrZmxvd0Vycm9yJyAmJlxuICAgICAgICAgICAgICAgIChmYWlsdXJlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5jb2RlID09PSAnV09SS0ZMT1dfQ0FMTF9USU1FT1VUJ1xuICAgICAgICAgICAgICBpZiAoaXNUaW1lb3V0KSB0aW1lclRyaWdnZXJlZCA9IHRydWVcbiAgICAgICAgICAgICAgeWllbGQqIHJ1blN0ZXBzKHN0ZXAub25GYWlsdXJlKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgY29uc3QgcnVuVGlja1NlcSA9IGdldFRpY2tTZXEoKVxuICAgICAgeWllbGQqIHJ1bkJvdW5kYXJ5KHtcbiAgICAgICAga2luZDogJ2Zsb3cnLFxuICAgICAgICBuYW1lOiAnd29ya2Zsb3cucnVuJyxcbiAgICAgICAgcGF5bG9hZDogeyB0cmlnZ2VyOiBhcmdzLnRyaWdnZXIgfSxcbiAgICAgICAgbWV0YToge1xuICAgICAgICAgIG1vZHVsZUlkOiBydW50aW1lLm1vZHVsZUlkLFxuICAgICAgICAgIGluc3RhbmNlSWQ6IHJ1bnRpbWUuaW5zdGFuY2VJZCxcbiAgICAgICAgICBwcm9ncmFtSWQ6IHByb2dyYW0ucHJvZ3JhbUlkLFxuICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgIC4uLihydW5UaWNrU2VxICE9PSB1bmRlZmluZWQgPyB7IHRpY2tTZXE6IHJ1blRpY2tTZXEgfSA6IG51bGwpLFxuICAgICAgICAgIHBvbGljeSxcbiAgICAgICAgfSxcbiAgICAgICAgZWZmZWN0OiBydW5TdGVwcyhwcm9ncmFtLnN0ZXBzISksXG4gICAgICAgIG1pZGRsZXdhcmU6IGFyZ3MubWlkZGxld2FyZSxcbiAgICAgIH0pLnBpcGUoRWZmZWN0LmFzVm9pZClcbiAgICB9KVxuXG4gICAgY29uc3QgbGltaXRlZCA9IHJlZ2lzdHJ5LnBhcmFsbGVsTGltaXRlciA/IHJlZ2lzdHJ5LnBhcmFsbGVsTGltaXRlci53aXRoUGVybWl0cygxKShwcm9ncmFtRWZmZWN0KSA6IHByb2dyYW1FZmZlY3RcblxuICAgIGNvbnN0IGZpYmVyID0geWllbGQqIEVmZmVjdC5mb3JrU2NvcGVkKFxuICAgICAgbGltaXRlZC5waXBlKFxuICAgICAgICBFZmZlY3QuY2F0Y2hBbGxDYXVzZSgoY2F1c2UpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVycm9yU3VtbWFyeSwgZG93bmdyYWRlIH0gPSB0b1NlcmlhbGl6YWJsZUVycm9yU3VtbWFyeShjYXVzZSlcbiAgICAgICAgICBjb25zdCBkb3duZ3JhZGVIaW50ID0gZG93bmdyYWRlID8gYCAoZG93bmdyYWRlPSR7ZG93bmdyYWRlfSlgIDogJydcbiAgICAgICAgICByZXR1cm4gRGVidWcucmVjb3JkKHtcbiAgICAgICAgICAgIHR5cGU6ICdkaWFnbm9zdGljJyxcbiAgICAgICAgICAgIG1vZHVsZUlkOiBydW50aW1lLm1vZHVsZUlkLFxuICAgICAgICAgICAgaW5zdGFuY2VJZDogcnVudGltZS5pbnN0YW5jZUlkLFxuICAgICAgICAgICAgY29kZTogJ3dvcmtmbG93OjpydW5fY3Jhc2hlZCcsXG4gICAgICAgICAgICBzZXZlcml0eTogJ2Vycm9yJyxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGBXb3JrZmxvdyBydW4gY3Jhc2hlZCBmb3IgcHJvZ3JhbUlkPVwiJHtwcm9ncmFtLnByb2dyYW1JZH1cIiBydW5JZD1cIiR7cnVuSWR9XCIuJHtkb3duZ3JhZGVIaW50fWAsXG4gICAgICAgICAgICBoaW50OiBgJHtlcnJvclN1bW1hcnkubmFtZSA/IGAke2Vycm9yU3VtbWFyeS5uYW1lfTogYCA6ICcnfSR7ZXJyb3JTdW1tYXJ5Lm1lc3NhZ2V9YCxcbiAgICAgICAgICAgIGFjdGlvblRhZzogYXJncy50cmlnZ2VyLmtpbmQgPT09ICdhY3Rpb24nID8gYXJncy50cmlnZ2VyLmFjdGlvblRhZyA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGtpbmQ6ICd3b3JrZmxvd19ydW5fY3Jhc2hlZCcsXG4gICAgICAgICAgICB0cmlnZ2VyOiB7XG4gICAgICAgICAgICAgIGtpbmQ6ICd3b3JrZmxvdycsXG4gICAgICAgICAgICAgIG5hbWU6ICdydW4nLFxuICAgICAgICAgICAgICBkZXRhaWxzOiB7XG4gICAgICAgICAgICAgICAgcHJvZ3JhbUlkOiBwcm9ncmFtLnByb2dyYW1JZCxcbiAgICAgICAgICAgICAgICBydW5JZCxcbiAgICAgICAgICAgICAgICB0cmlnZ2VyOiBhcmdzLnRyaWdnZXIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLnBpcGUoRWZmZWN0LmNhdGNoQWxsQ2F1c2UoKCkgPT4gRWZmZWN0LnZvaWQpKVxuICAgICAgICB9KSxcbiAgICAgICAgRWZmZWN0LmVuc3VyaW5nKFxuICAgICAgICAgIEVmZmVjdC5zeW5jKCgpID0+IHtcbiAgICAgICAgICAgIGlmIChzdGF0ZS5tb2RlID09PSAnZXhoYXVzdCcpIHtcbiAgICAgICAgICAgICAgc3RhdGUuYnVzeSA9IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICApLFxuICAgIClcblxuICAgIGlmIChzdGF0ZS5tb2RlID09PSAnbGF0ZXN0Jykge1xuICAgICAgc3RhdGUuY3VycmVudCA9IGZpYmVyIGFzIEZpYmVyLlJ1bnRpbWVGaWJlcjx2b2lkLCBuZXZlcj5cbiAgICB9XG4gIH0pXG5cbnR5cGUgUmVnaXN0cnlJbml0ID0ge1xuICByZWFkb25seSBtb2R1bGVJZDogc3RyaW5nXG4gIHJlYWRvbmx5IGluc3RhbmNlSWQ6IHN0cmluZ1xuICByZWFkb25seSByZWdpc3RyeTogV29ya2Zsb3dSZWdpc3RyeVYxXG59XG5cbmNvbnN0IGVuc3VyZVJlZ2lzdHJ5ID0gKHJ1bnRpbWU6IFB1YmxpY01vZHVsZVJ1bnRpbWU8dW5rbm93biwgdW5rbm93bj4pID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IGdldFJlZ2lzdHJ5KHJ1bnRpbWUpXG4gICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBtb2R1bGVJZDogcnVudGltZS5tb2R1bGVJZCxcbiAgICAgICAgaW5zdGFuY2VJZDogcnVudGltZS5pbnN0YW5jZUlkLFxuICAgICAgICByZWdpc3RyeTogZXhpc3RpbmcsXG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcG9ydHNSZWFkeSA9IHlpZWxkKiBEZWZlcnJlZC5tYWtlPHZvaWQsIHVua25vd24+KClcblxuICAgIGNvbnN0IG5leHQ6IFdvcmtmbG93UmVnaXN0cnlWMSA9IHtcbiAgICAgIGJ5QWN0aW9uVGFnOiBuZXcgTWFwKCksXG4gICAgICBlbnRyaWVzOiBbXSxcbiAgICAgIHdhdGNoZXJTdGFydGVkOiBmYWxzZSxcbiAgICAgIHdhdGNoZXJTdGFydENvdW50OiAwLFxuICAgICAgcG9ydHNSZXNvbHZpbmc6IGZhbHNlLFxuICAgICAgcG9ydHNSZWFkeSxcbiAgICAgIHBhcmFsbGVsTGltaXRlcjogdW5kZWZpbmVkLFxuICAgIH1cblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShydW50aW1lLCBXT1JLRkxPV19SRUdJU1RSWSwge1xuICAgICAgdmFsdWU6IG5leHQsXG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICB9KVxuXG4gICAgcmV0dXJuIHsgbW9kdWxlSWQ6IHJ1bnRpbWUubW9kdWxlSWQsIGluc3RhbmNlSWQ6IHJ1bnRpbWUuaW5zdGFuY2VJZCwgcmVnaXN0cnk6IG5leHQgfVxuICB9KVxuXG5jb25zdCByZWdpc3RlclByb2dyYW1zID0gKGFyZ3M6IHtcbiAgcmVhZG9ubHkgbW9kdWxlVGFnOiBNb2R1bGVUYWdcbiAgcmVhZG9ubHkgcHJvZ3JhbXM6IFJlYWRvbmx5QXJyYXk8V29ya2Zsb3dMaWtlPlxuICByZWFkb25seSBlbnRyeUxhYmVsOiBzdHJpbmdcbn0pOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCB1bmtub3duPiA9PlxuICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgY29uc3QgcnVudGltZSA9IHlpZWxkKiBhcmdzLm1vZHVsZVRhZ1xuICAgIGNvbnN0IHsgbW9kdWxlSWQsIGluc3RhbmNlSWQsIHJlZ2lzdHJ5IH0gPSB5aWVsZCogZW5zdXJlUmVnaXN0cnkocnVudGltZSlcblxuICAgIC8vIExhemlseSByZXNvbHZlIHRoZSBnbG9iYWwgcGFyYWxsZWwgbGltaXRlciBvbmNlLlxuICAgIGlmIChyZWdpc3RyeS5wYXJhbGxlbExpbWl0ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgeWllbGQqIGVuc3VyZUxpbWl0ZXJSZWFkeShyZWdpc3RyeSwgcnVudGltZSlcbiAgICB9XG5cbiAgICBjb25zdCB2YWxpZGF0ZU5vSW9TdGVwc0Zvck9uSW5pdCA9IChzdGVwczogUmVhZG9ubHlBcnJheTxDb21waWxlZFdvcmtmbG93U3RlcD4sIHByb2dyYW1JZDogc3RyaW5nKTogdm9pZCA9PiB7XG4gICAgICBjb25zdCB2aXNpdCA9IChzdGVwOiBDb21waWxlZFdvcmtmbG93U3RlcCk6IHZvaWQgPT4ge1xuICAgICAgICBpZiAoc3RlcC5raW5kID09PSAnY2FsbCcgfHwgc3RlcC5raW5kID09PSAnZGVsYXknKSB7XG4gICAgICAgICAgdGhyb3cgbWFrZVdvcmtmbG93RXJyb3Ioe1xuICAgICAgICAgICAgY29kZTogJ1dPUktGTE9XX0lOVkFMSURfVFJJR0dFUicsXG4gICAgICAgICAgICBtZXNzYWdlOiAnTGlmZWN5Y2xlIG9uSW5pdCBwcm9ncmFtcyBtdXN0IG5vdCBpbmNsdWRlIGNhbGwvZGVsYXkgKGluaXRSZXF1aXJlZCBtdXN0IHN0YXkgc3luYy1vbmx5OyB1c2Ugb25TdGFydCBmb3IgSU8vdGltZSkuJyxcbiAgICAgICAgICAgIHByb2dyYW1JZCxcbiAgICAgICAgICAgIHNvdXJjZTogeyBzdGVwS2V5OiBzdGVwLmtleSB9LFxuICAgICAgICAgICAgZGV0YWlsOiB7IGtpbmQ6IHN0ZXAua2luZCB9LFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgcyBvZiBzdGVwcykgdmlzaXQocylcbiAgICB9XG5cbiAgICBjb25zdCBwcm9ncmFtSGFzQ2FsbCA9IChzdGVwczogUmVhZG9ubHlBcnJheTxDb21waWxlZFdvcmtmbG93U3RlcD4pOiBib29sZWFuID0+XG4gICAgICBzdGVwcy5zb21lKChzKSA9PiBzLmtpbmQgPT09ICdjYWxsJylcblxuICAgIGNvbnN0IGluc2VydEVudHJ5ID0gKGFjdGlvblRhZzogc3RyaW5nLCBlbnRyeTogUHJvZ3JhbUVudHJ5KTogdm9pZCA9PiB7XG4gICAgICBjb25zdCBwcmV2ID0gcmVnaXN0cnkuYnlBY3Rpb25UYWcuZ2V0KGFjdGlvblRhZylcbiAgICAgIHJlZ2lzdHJ5LmJ5QWN0aW9uVGFnLnNldChhY3Rpb25UYWcsIHByZXYgPyBbLi4ucHJldiwgZW50cnldIDogW2VudHJ5XSlcbiAgICB9XG5cbiAgICBjb25zdCBpbnRlcm5hbHMgPSBnZXRSdW50aW1lSW50ZXJuYWxzKHJ1bnRpbWUpXG5cbiAgICBmb3IgKGNvbnN0IHByb2dyYW0gb2YgYXJncy5wcm9ncmFtcykge1xuICAgICAgY29uc3QgZGVmID0gcHJvZ3JhbS5kZWZcbiAgICAgIGNvbnN0IGxvY2FsSWQgPSBhc05vbkVtcHR5U3RyaW5nKGRlZi5sb2NhbElkKVxuICAgICAgaWYgKCFsb2NhbElkKSB7XG4gICAgICAgIHRocm93IG1ha2VXb3JrZmxvd0Vycm9yKHtcbiAgICAgICAgICBjb2RlOiAnV09SS0ZMT1dfSU5WQUxJRF9ERUYnLFxuICAgICAgICAgIG1lc3NhZ2U6ICdXb3JrZmxvdy5pbnN0YWxsOiBkZWYubG9jYWxJZCBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZy4nLFxuICAgICAgICAgIGRldGFpbDogeyBsb2NhbElkOiBkZWYubG9jYWxJZCB9LFxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICBjb25zdCBwcm9ncmFtSWQgPSBgJHttb2R1bGVJZH0uJHtsb2NhbElkfWBcbiAgICAgIGNvbnN0IGNvbXBpbGVkID0gY29tcGlsZVdvcmtmbG93UnVudGltZVN0ZXBzVjEoeyBkZWYgfSlcblxuICAgICAgaWYgKGRlZi50cmlnZ2VyLmtpbmQgPT09ICdsaWZlY3ljbGUnICYmIGRlZi50cmlnZ2VyLnBoYXNlID09PSAnb25Jbml0Jykge1xuICAgICAgICB2YWxpZGF0ZU5vSW9TdGVwc0Zvck9uSW5pdChjb21waWxlZCwgcHJvZ3JhbUlkKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBjb21waWxlZFByb2dyYW06IENvbXBpbGVkUHJvZ3JhbSA9IHtcbiAgICAgICAgcHJvZ3JhbUlkLFxuICAgICAgICBsb2NhbElkLFxuICAgICAgICB0cmlnZ2VyOiBkZWYudHJpZ2dlcixcbiAgICAgICAgY29uY3VycmVuY3k6IHJlc29sdmVDb25jdXJyZW5jeShkZWYpLFxuICAgICAgICBwcmlvcml0eTogcmVzb2x2ZVByaW9yaXR5KGRlZiksXG4gICAgICAgIGNvbXBpbGVkU3RlcHM6IGNvbXBpbGVkLFxuICAgICAgfVxuXG4gICAgICBpZiAoIXByb2dyYW1IYXNDYWxsKGNvbXBpbGVkKSkge1xuICAgICAgICBjb21waWxlZFByb2dyYW0uc3RlcHMgPSBjb21waWxlU3RlcHMoY29tcGlsZWQsICgpID0+IHtcbiAgICAgICAgICB0aHJvdyBtYWtlV29ya2Zsb3dFcnJvcih7XG4gICAgICAgICAgICBjb2RlOiAnV09SS0ZMT1dfTUlTU0lOR19TRVJWSUNFJyxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdJbnRlcm5hbCBlcnJvcjogdW5leHBlY3RlZCBjYWxsIHN0ZXAgd2hpbGUgcmVzb2x2aW5nIGNhbGwtbGVzcyBwcm9ncmFtLicsXG4gICAgICAgICAgICBwcm9ncmFtSWQsXG4gICAgICAgICAgICBkZXRhaWw6IHsgcHJvZ3JhbUlkIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RhdGU6IFByb2dyYW1TdGF0ZSA9XG4gICAgICAgIGNvbXBpbGVkUHJvZ3JhbS5jb25jdXJyZW5jeSA9PT0gJ2xhdGVzdCdcbiAgICAgICAgICA/IHsgbW9kZTogJ2xhdGVzdCcsIHJ1blNlcTogMCwgY3VycmVudDogdW5kZWZpbmVkLCBjdXJyZW50UnVuSWQ6IHVuZGVmaW5lZCB9XG4gICAgICAgICAgOiBjb21waWxlZFByb2dyYW0uY29uY3VycmVuY3kgPT09ICdleGhhdXN0J1xuICAgICAgICAgICAgPyB7IG1vZGU6ICdleGhhdXN0JywgcnVuU2VxOiAwLCBidXN5OiBmYWxzZSB9XG4gICAgICAgICAgICA6IHsgbW9kZTogJ3BhcmFsbGVsJywgcnVuU2VxOiAwIH1cblxuICAgICAgY29uc3QgZW50cnk6IFByb2dyYW1FbnRyeSA9IHsgcHJvZ3JhbTogY29tcGlsZWRQcm9ncmFtLCBzdGF0ZSB9XG4gICAgICByZWdpc3RyeS5lbnRyaWVzLnB1c2goZW50cnkpXG5cbiAgICAgIGlmIChkZWYudHJpZ2dlci5raW5kID09PSAnYWN0aW9uJykge1xuICAgICAgICBpbnNlcnRFbnRyeShkZWYudHJpZ2dlci5hY3Rpb25UYWcsIGVudHJ5KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGRlZi50cmlnZ2VyLnBoYXNlID09PSAnb25TdGFydCcpIHtcbiAgICAgICAgICBpbnRlcm5hbHMubGlmZWN5Y2xlLnJlZ2lzdGVyU3RhcnQoXG4gICAgICAgICAgICB3aXRoUm9vdEVudklmQXZhaWxhYmxlKFxuICAgICAgICAgICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWlkZGxld2FyZU9wdCA9IHlpZWxkKiBFZmZlY3Quc2VydmljZU9wdGlvbihFZmZlY3RPcENvcmUuRWZmZWN0T3BNaWRkbGV3YXJlVGFnKVxuICAgICAgICAgICAgICAgIGNvbnN0IG1pZGRsZXdhcmUgPSBPcHRpb24uaXNTb21lKG1pZGRsZXdhcmVPcHQpID8gbWlkZGxld2FyZU9wdC52YWx1ZSA6IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIHlpZWxkKiBlbnN1cmVQb3J0c1Jlc29sdmVkKHJlZ2lzdHJ5LCBydW50aW1lKS5waXBlKEVmZmVjdC5vckRpZSlcbiAgICAgICAgICAgICAgICB5aWVsZCogc3RhcnRQcm9ncmFtUnVuKHtcbiAgICAgICAgICAgICAgICAgIGVudHJ5LFxuICAgICAgICAgICAgICAgICAgcnVudGltZSxcbiAgICAgICAgICAgICAgICAgIHJlZ2lzdHJ5LFxuICAgICAgICAgICAgICAgICAgdHJpZ2dlcjogeyBraW5kOiAnbGlmZWN5Y2xlJywgcGhhc2U6ICdvblN0YXJ0JyB9LFxuICAgICAgICAgICAgICAgICAgcGF5bG9hZDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgbWlkZGxld2FyZSxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICB7IG5hbWU6IGB3b3JrZmxvdzoke2xvY2FsSWR9YCB9LFxuICAgICAgICAgIClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpbnRlcm5hbHMubGlmZWN5Y2xlLnJlZ2lzdGVySW5pdFJlcXVpcmVkKFxuICAgICAgICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgICBjb25zdCBtaWRkbGV3YXJlT3B0ID0geWllbGQqIEVmZmVjdC5zZXJ2aWNlT3B0aW9uKEVmZmVjdE9wQ29yZS5FZmZlY3RPcE1pZGRsZXdhcmVUYWcpXG4gICAgICAgICAgICAgIGNvbnN0IG1pZGRsZXdhcmUgPSBPcHRpb24uaXNTb21lKG1pZGRsZXdhcmVPcHQpID8gbWlkZGxld2FyZU9wdC52YWx1ZSA6IHVuZGVmaW5lZFxuICAgICAgICAgICAgICB5aWVsZCogc3RhcnRQcm9ncmFtUnVuKHtcbiAgICAgICAgICAgICAgICBlbnRyeSxcbiAgICAgICAgICAgICAgICBydW50aW1lLFxuICAgICAgICAgICAgICAgIHJlZ2lzdHJ5LFxuICAgICAgICAgICAgICAgIHRyaWdnZXI6IHsga2luZDogJ2xpZmVjeWNsZScsIHBoYXNlOiAnb25Jbml0JyB9LFxuICAgICAgICAgICAgICAgIHBheWxvYWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBtaWRkbGV3YXJlLFxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB7IG5hbWU6IGB3b3JrZmxvdzoke2xvY2FsSWR9YCB9LFxuICAgICAgICAgIClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHZvaWQgaW5zdGFuY2VJZFxuICB9KVxuXG5jb25zdCBzdGFydFdhdGNoZXJJZk5lZWRlZCA9IChhcmdzOiB7XG4gIHJlYWRvbmx5IG1vZHVsZVRhZzogTW9kdWxlVGFnXG4gIHJlYWRvbmx5IGVudHJ5TGFiZWw6IHN0cmluZ1xufSk6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIHVua25vd24+ID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBydW50aW1lID0geWllbGQqIGFyZ3MubW9kdWxlVGFnXG4gICAgY29uc3QgaW5pdCA9IHlpZWxkKiBlbnN1cmVSZWdpc3RyeShydW50aW1lKVxuICAgIGNvbnN0IHJlZ2lzdHJ5ID0gaW5pdC5yZWdpc3RyeVxuXG4gICAgaWYgKHJlZ2lzdHJ5LndhdGNoZXJTdGFydGVkKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICByZWdpc3RyeS53YXRjaGVyU3RhcnRlZCA9IHRydWVcbiAgICByZWdpc3RyeS53YXRjaGVyU3RhcnRDb3VudCArPSAxXG5cbiAgICBjb25zdCBtaWRkbGV3YXJlT3B0ID0geWllbGQqIEVmZmVjdC5zZXJ2aWNlT3B0aW9uKEVmZmVjdE9wQ29yZS5FZmZlY3RPcE1pZGRsZXdhcmVUYWcpXG4gICAgY29uc3QgbWlkZGxld2FyZSA9IE9wdGlvbi5pc1NvbWUobWlkZGxld2FyZU9wdCkgPyBtaWRkbGV3YXJlT3B0LnZhbHVlIDogdW5kZWZpbmVkXG5cbiAgICBjb25zdCBhY3Rpb25zJCA9IHJ1bnRpbWUuYWN0aW9ucyQgYXMgU3RyZWFtLlN0cmVhbTx1bmtub3duPlxuXG4gICAgY29uc3QgcG9ydHNFeGl0ID0geWllbGQqIEVmZmVjdC5leGl0KGVuc3VyZVBvcnRzUmVzb2x2ZWQocmVnaXN0cnksIHJ1bnRpbWUpKVxuICAgIGlmIChFeGl0LmlzRmFpbHVyZShwb3J0c0V4aXQpKSB7XG4gICAgICBjb25zdCB7IGVycm9yU3VtbWFyeSwgZG93bmdyYWRlIH0gPSB0b1NlcmlhbGl6YWJsZUVycm9yU3VtbWFyeShwb3J0c0V4aXQuY2F1c2UpXG4gICAgICBjb25zdCBkb3duZ3JhZGVIaW50ID0gZG93bmdyYWRlID8gYCAoZG93bmdyYWRlPSR7ZG93bmdyYWRlfSlgIDogJydcbiAgICAgIHlpZWxkKiBEZWJ1Zy5yZWNvcmQoe1xuICAgICAgICB0eXBlOiAnZGlhZ25vc3RpYycsXG4gICAgICAgIG1vZHVsZUlkOiBydW50aW1lLm1vZHVsZUlkLFxuICAgICAgICBpbnN0YW5jZUlkOiBydW50aW1lLmluc3RhbmNlSWQsXG4gICAgICAgIGNvZGU6ICd3b3JrZmxvdzo6cG9ydHNfcmVzb2x1dGlvbl9mYWlsZWQnLFxuICAgICAgICBzZXZlcml0eTogJ2Vycm9yJyxcbiAgICAgICAgbWVzc2FnZTogYFdvcmtmbG93IHBvcnRzIHJlc29sdXRpb24gZmFpbGVkIGJlZm9yZSBzdGFydGluZyB3YXRjaGVyLiR7ZG93bmdyYWRlSGludH1gLFxuICAgICAgICBoaW50OiBgJHtlcnJvclN1bW1hcnkubmFtZSA/IGAke2Vycm9yU3VtbWFyeS5uYW1lfTogYCA6ICcnfSR7ZXJyb3JTdW1tYXJ5Lm1lc3NhZ2V9YCxcbiAgICAgICAga2luZDogJ3dvcmtmbG93X3BvcnRzX3Jlc29sdXRpb25fZmFpbGVkJyxcbiAgICAgICAgdHJpZ2dlcjoge1xuICAgICAgICAgIGtpbmQ6ICd3b3JrZmxvdycsXG4gICAgICAgICAgbmFtZTogJ3BvcnRzUmVzb2x1dGlvbicsXG4gICAgICAgICAgZGV0YWlsczoge1xuICAgICAgICAgICAgZW50cnlMYWJlbDogYXJncy5lbnRyeUxhYmVsLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgeWllbGQqIFN0cmVhbS5ydW5Gb3JFYWNoKGFjdGlvbnMkLCAoYWN0aW9uKSA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBjb25zdCBhY3Rpb25UYWcgPSByZXNvbHZlQWN0aW9uVGFnKGFjdGlvbilcbiAgICAgICAgaWYgKCFhY3Rpb25UYWcpIHJldHVyblxuXG4gICAgICAgIGNvbnN0IGVudHJpZXMgPSByZWdpc3RyeS5ieUFjdGlvblRhZy5nZXQoYWN0aW9uVGFnKVxuICAgICAgICBpZiAoIWVudHJpZXMgfHwgZW50cmllcy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSBpc1JlY29yZChhY3Rpb24pID8gYWN0aW9uLnBheWxvYWQgOiB1bmRlZmluZWRcblxuICAgICAgICB5aWVsZCogRWZmZWN0LmZvckVhY2goXG4gICAgICAgICAgZW50cmllcyxcbiAgICAgICAgICAoZW50cnkpID0+XG4gICAgICAgICAgICBzdGFydFByb2dyYW1SdW4oe1xuICAgICAgICAgICAgICBlbnRyeSxcbiAgICAgICAgICAgICAgcnVudGltZSxcbiAgICAgICAgICAgICAgcmVnaXN0cnksXG4gICAgICAgICAgICAgIHRyaWdnZXI6IHsga2luZDogJ2FjdGlvbicsIGFjdGlvblRhZyB9LFxuICAgICAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICAgICAgICBtaWRkbGV3YXJlLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgeyBkaXNjYXJkOiB0cnVlIH0sXG4gICAgICAgIClcbiAgICAgIH0pLFxuICAgICkucGlwZShcbiAgICAgIEVmZmVjdC5jYXRjaEFsbENhdXNlKChjYXVzZSkgPT4ge1xuICAgICAgICBjb25zdCB7IGVycm9yU3VtbWFyeSwgZG93bmdyYWRlIH0gPSB0b1NlcmlhbGl6YWJsZUVycm9yU3VtbWFyeShjYXVzZSlcbiAgICAgICAgY29uc3QgZG93bmdyYWRlSGludCA9IGRvd25ncmFkZSA/IGAgKGRvd25ncmFkZT0ke2Rvd25ncmFkZX0pYCA6ICcnXG4gICAgICAgIHJldHVybiBEZWJ1Zy5yZWNvcmQoe1xuICAgICAgICAgIHR5cGU6ICdkaWFnbm9zdGljJyxcbiAgICAgICAgICBtb2R1bGVJZDogcnVudGltZS5tb2R1bGVJZCxcbiAgICAgICAgICBpbnN0YW5jZUlkOiBydW50aW1lLmluc3RhbmNlSWQsXG4gICAgICAgICAgY29kZTogJ3dvcmtmbG93Ojp3YXRjaGVyX2NyYXNoZWQnLFxuICAgICAgICAgIHNldmVyaXR5OiAnZXJyb3InLFxuICAgICAgICAgIG1lc3NhZ2U6IGBXb3JrZmxvdyB3YXRjaGVyIGNyYXNoZWQuJHtkb3duZ3JhZGVIaW50fWAsXG4gICAgICAgICAgaGludDogYCR7ZXJyb3JTdW1tYXJ5Lm5hbWUgPyBgJHtlcnJvclN1bW1hcnkubmFtZX06IGAgOiAnJ30ke2Vycm9yU3VtbWFyeS5tZXNzYWdlfWAsXG4gICAgICAgICAga2luZDogJ3dvcmtmbG93X3dhdGNoZXJfY3Jhc2hlZCcsXG4gICAgICAgICAgdHJpZ2dlcjoge1xuICAgICAgICAgICAga2luZDogJ3dvcmtmbG93JyxcbiAgICAgICAgICAgIG5hbWU6ICd3YXRjaGVyJyxcbiAgICAgICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICAgICAgZW50cnlMYWJlbDogYXJncy5lbnRyeUxhYmVsLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgfSksXG4gICAgKVxuXG4gICAgdm9pZCBhcmdzLmVudHJ5TGFiZWxcbiAgfSlcblxuZXhwb3J0IGNvbnN0IG1vdW50QWxsID0gKGFyZ3M6IHtcbiAgcmVhZG9ubHkgbW9kdWxlVGFnOiBNb2R1bGVUYWdcbiAgcmVhZG9ubHkgcHJvZ3JhbXM6IFJlYWRvbmx5QXJyYXk8V29ya2Zsb3dMaWtlPlxufSk6IExvZ2ljUGxhbjxBbnlNb2R1bGVTaGFwZSwgdW5rbm93biwgbmV2ZXI+ID0+IHtcbiAgY29uc3QgcGxhbiA9IHtcbiAgICBzZXR1cDogcmVnaXN0ZXJQcm9ncmFtcyh7IG1vZHVsZVRhZzogYXJncy5tb2R1bGVUYWcsIHByb2dyYW1zOiBhcmdzLnByb2dyYW1zLCBlbnRyeUxhYmVsOiAnbW91bnRBbGwnIH0pLFxuICAgIHJ1bjogc3RhcnRXYXRjaGVySWZOZWVkZWQoeyBtb2R1bGVUYWc6IGFyZ3MubW9kdWxlVGFnLCBlbnRyeUxhYmVsOiAnbW91bnRBbGwnIH0pLFxuICB9IHNhdGlzZmllcyBMb2dpY1BsYW48QW55TW9kdWxlU2hhcGUsIHVua25vd24sIG5ldmVyPlxuXG4gIExvZ2ljVW5pdE1ldGEuYXR0YWNoTG9naWNVbml0TWV0YShwbGFuLCB7XG4gICAgaWQ6ICdfX2xvZ2l4X2ludGVybmFsOndvcmtmbG93cycsXG4gICAga2luZDogJ2ludGVybmFsJyxcbiAgICBuYW1lOiAnd29ya2Zsb3dzJyxcbiAgfSlcblxuICByZXR1cm4gcGxhblxufVxuXG5leHBvcnQgY29uc3QgaW5zdGFsbE9uZSA9IChhcmdzOiB7XG4gIHJlYWRvbmx5IG1vZHVsZVRhZzogTW9kdWxlVGFnXG4gIHJlYWRvbmx5IHByb2dyYW06IFdvcmtmbG93TGlrZVxufSk6IExvZ2ljUGxhbjxBbnlNb2R1bGVTaGFwZSwgdW5rbm93biwgbmV2ZXI+ID0+IHtcbiAgY29uc3QgbG9jYWxJZCA9IGFzTm9uRW1wdHlTdHJpbmcoYXJncy5wcm9ncmFtLmRlZi5sb2NhbElkKSA/PyAndW5rbm93bidcbiAgY29uc3QgcGxhbiA9IHtcbiAgICBzZXR1cDogcmVnaXN0ZXJQcm9ncmFtcyh7IG1vZHVsZVRhZzogYXJncy5tb2R1bGVUYWcsIHByb2dyYW1zOiBbYXJncy5wcm9ncmFtXSwgZW50cnlMYWJlbDogYGluc3RhbGw6JHtsb2NhbElkfWAgfSksXG4gICAgcnVuOiBzdGFydFdhdGNoZXJJZk5lZWRlZCh7IG1vZHVsZVRhZzogYXJncy5tb2R1bGVUYWcsIGVudHJ5TGFiZWw6IGBpbnN0YWxsOiR7bG9jYWxJZH1gIH0pLFxuICB9IHNhdGlzZmllcyBMb2dpY1BsYW48QW55TW9kdWxlU2hhcGUsIHVua25vd24sIG5ldmVyPlxuXG4gIExvZ2ljVW5pdE1ldGEuYXR0YWNoTG9naWNVbml0TWV0YShwbGFuLCB7XG4gICAgaWQ6IGB3b3JrZmxvdzoke2xvY2FsSWR9YCxcbiAgICBraW5kOiAnd29ya2Zsb3cnLFxuICAgIG5hbWU6IGxvY2FsSWQsXG4gIH0pXG5cbiAgcmV0dXJuIHBsYW5cbn1cblxuLy8gdGVzdC1vbmx5IHByb2JlOiB3aGV0aGVyIGEgd2F0Y2hlciBoYXMgc3RhcnRlZCAoZm9yIHNpbmdsZS1zdWJzY3JpcHRpb24gZ2F0ZXMpLlxuZXhwb3J0IGNvbnN0IF9fdW5zYWZlR2V0V2F0Y2hlclN0YXJ0Q291bnQgPSAocnVudGltZTogdW5rbm93bik6IG51bWJlciA9PiB7XG4gIGlmICghcnVudGltZSB8fCB0eXBlb2YgcnVudGltZSAhPT0gJ29iamVjdCcpIHJldHVybiAwXG4gIGNvbnN0IHJlZyA9IGdldFJlZ2lzdHJ5KHJ1bnRpbWUpXG4gIHJldHVybiByZWcgPyByZWcud2F0Y2hlclN0YXJ0Q291bnQgOiAwXG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsU0FBUyxPQUFP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