@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,1395 @@
1
+ // @logixjs/core subpath bundles for @logixjs/sandbox
2
+
3
+ import {
4
+ getGlobalHostScheduler
5
+ } from "./chunk-UJGVDFZN.js";
6
+ import {
7
+ clearRuntimeDebugEventSeq,
8
+ currentDiagnosticsLevel,
9
+ record,
10
+ toRuntimeDebugEventRef
11
+ } from "./chunk-SH7TP5CJ.js";
12
+ import {
13
+ OBSERVABILITY_PROTOCOL_VERSION,
14
+ exportEvidencePackage
15
+ } from "./chunk-SI5OKFFY.js";
16
+
17
+ // ../logix-core/src/internal/runtime/core/DevtoolsHub.ts
18
+ import { Effect, FiberRef } from "../effect.js";
19
+ var instances = /* @__PURE__ */ new Map();
20
+ var latestStates = /* @__PURE__ */ new Map();
21
+ var latestTraitSummaries = /* @__PURE__ */ new Map();
22
+ var instanceLabels = /* @__PURE__ */ new Map();
23
+ var convergeStaticIrByDigest = /* @__PURE__ */ new Map();
24
+ var liveInstanceKeys = /* @__PURE__ */ new Set();
25
+ var exportBudget = {
26
+ dropped: 0,
27
+ oversized: 0
28
+ };
29
+ var lastRunTs = 0;
30
+ var lastRunTsSeq = 0;
31
+ var nextRunId = () => {
32
+ const ts = Date.now();
33
+ if (ts === lastRunTs) {
34
+ lastRunTsSeq += 1;
35
+ } else {
36
+ lastRunTs = ts;
37
+ lastRunTsSeq = 0;
38
+ }
39
+ return lastRunTsSeq === 0 ? `run-${ts}` : `run-${ts}.${lastRunTsSeq}`;
40
+ };
41
+ var currentRunId = nextRunId();
42
+ var nextSeq = 1;
43
+ var bufferSize = 500;
44
+ var ringBuffer = [];
45
+ var ringBufferSeq = [];
46
+ var snapshotToken = 0;
47
+ var ensureRingBufferSize = () => {
48
+ if (bufferSize <= 0) {
49
+ ringBuffer.length = 0;
50
+ ringBufferSeq.length = 0;
51
+ return;
52
+ }
53
+ if (ringBuffer.length <= bufferSize) return;
54
+ const excess = ringBuffer.length - bufferSize;
55
+ ringBuffer.splice(0, excess);
56
+ ringBufferSeq.splice(0, excess);
57
+ };
58
+ var trimRingBufferIfNeeded = () => {
59
+ if (bufferSize <= 0) {
60
+ ringBuffer.length = 0;
61
+ ringBufferSeq.length = 0;
62
+ return;
63
+ }
64
+ if (bufferSize <= 64) {
65
+ ensureRingBufferSize();
66
+ return;
67
+ }
68
+ const slack = Math.min(1024, Math.floor(bufferSize / 2));
69
+ const threshold = bufferSize + Math.max(1, slack);
70
+ if (ringBuffer.length <= threshold) return;
71
+ const excess = ringBuffer.length - bufferSize;
72
+ ringBuffer.splice(0, excess);
73
+ ringBufferSeq.splice(0, excess);
74
+ };
75
+ var currentSnapshot = {
76
+ snapshotToken,
77
+ instances,
78
+ events: ringBuffer,
79
+ latestStates,
80
+ latestTraitSummaries,
81
+ exportBudget
82
+ };
83
+ var listeners = /* @__PURE__ */ new Set();
84
+ var notifyScheduled = false;
85
+ var scheduleNotify = () => {
86
+ if (listeners.size === 0) return;
87
+ if (notifyScheduled) return;
88
+ notifyScheduled = true;
89
+ getGlobalHostScheduler().scheduleMicrotask(() => {
90
+ notifyScheduled = false;
91
+ for (const listener of listeners) {
92
+ listener();
93
+ }
94
+ });
95
+ };
96
+ var devtoolsEnabled = false;
97
+ var bumpSnapshotToken = () => {
98
+ snapshotToken += 1;
99
+ currentSnapshot.snapshotToken = snapshotToken;
100
+ };
101
+ var markSnapshotChanged = () => {
102
+ bumpSnapshotToken();
103
+ scheduleNotify();
104
+ };
105
+ var configureDevtoolsHub = (options) => {
106
+ devtoolsEnabled = true;
107
+ if (typeof options?.bufferSize === "number" && Number.isFinite(options.bufferSize)) {
108
+ const next = Math.floor(options.bufferSize);
109
+ const nextBufferSize = next >= 0 ? next : 0;
110
+ if (nextBufferSize !== bufferSize) {
111
+ bufferSize = nextBufferSize;
112
+ ensureRingBufferSize();
113
+ markSnapshotChanged();
114
+ }
115
+ }
116
+ };
117
+ var isDevtoolsEnabled = () => devtoolsEnabled;
118
+ var getDevtoolsSnapshot = () => currentSnapshot;
119
+ var getDevtoolsSnapshotToken = () => snapshotToken;
120
+ var subscribeDevtoolsSnapshot = (listener) => {
121
+ listeners.add(listener);
122
+ return () => {
123
+ listeners.delete(listener);
124
+ };
125
+ };
126
+ var getDevtoolsRunId = () => currentRunId;
127
+ var setDevtoolsRunId = (runId) => {
128
+ if (typeof runId !== "string" || runId.length === 0) return;
129
+ if (runId !== currentRunId) {
130
+ currentRunId = runId;
131
+ markSnapshotChanged();
132
+ }
133
+ };
134
+ var startDevtoolsRun = (runId) => {
135
+ currentRunId = typeof runId === "string" && runId.length > 0 ? runId : nextRunId();
136
+ nextSeq = 1;
137
+ clearRuntimeDebugEventSeq();
138
+ clearDevtoolsEvents();
139
+ return currentRunId;
140
+ };
141
+ var clearDevtoolsEvents = () => {
142
+ ringBuffer.length = 0;
143
+ ringBufferSeq.length = 0;
144
+ exportBudget.dropped = 0;
145
+ exportBudget.oversized = 0;
146
+ markSnapshotChanged();
147
+ };
148
+ var setInstanceLabel = (instanceId, label) => {
149
+ instanceLabels.set(instanceId, label);
150
+ markSnapshotChanged();
151
+ };
152
+ var getInstanceLabel = (instanceId) => instanceLabels.get(instanceId);
153
+ var registerConvergeStaticIr = (ir) => {
154
+ convergeStaticIrByDigest.set(ir.staticIrDigest, ir);
155
+ };
156
+ var devtoolsHubConvergeStaticIrCollector = {
157
+ register: registerConvergeStaticIr
158
+ };
159
+ var exportDevtoolsEvidencePackage = (options) => {
160
+ const protocolVersion = options?.protocolVersion ?? OBSERVABILITY_PROTOCOL_VERSION;
161
+ const runId = options?.runId ?? currentRunId;
162
+ const source = options?.source ?? { host: "unknown" };
163
+ const events = ringBuffer.map((payload, i) => ({
164
+ protocolVersion,
165
+ runId,
166
+ seq: ringBufferSeq[i] ?? i + 1,
167
+ timestamp: payload.timestamp,
168
+ type: "debug:event",
169
+ payload
170
+ }));
171
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
172
+ const convergeDigests = /* @__PURE__ */ new Set();
173
+ let sawFullConverge = false;
174
+ for (const ref of ringBuffer) {
175
+ if (ref.kind !== "trait:converge") continue;
176
+ const meta = ref.meta;
177
+ if (!isRecord(meta)) continue;
178
+ const digest = meta.staticIrDigest;
179
+ if (typeof digest === "string" && digest.length > 0) {
180
+ convergeDigests.add(digest);
181
+ }
182
+ const dirty = meta.dirty;
183
+ if (isRecord(dirty) && typeof dirty.rootCount === "number") {
184
+ sawFullConverge = true;
185
+ }
186
+ }
187
+ let summary;
188
+ if (sawFullConverge && convergeDigests.size > 0) {
189
+ const staticIrByDigest = {};
190
+ for (const digest of convergeDigests) {
191
+ const ir = convergeStaticIrByDigest.get(digest);
192
+ if (ir) {
193
+ staticIrByDigest[digest] = ir;
194
+ }
195
+ }
196
+ if (Object.keys(staticIrByDigest).length > 0) {
197
+ summary = { converge: { staticIrByDigest } };
198
+ }
199
+ }
200
+ return exportEvidencePackage({
201
+ protocolVersion,
202
+ runId,
203
+ source,
204
+ events,
205
+ summary
206
+ });
207
+ };
208
+ var devtoolsHubSink = {
209
+ record: (event) => Effect.gen(function* () {
210
+ const level = yield* FiberRef.get(currentDiagnosticsLevel);
211
+ let changed = false;
212
+ if (event.type === "trace:instanceLabel") {
213
+ const instanceId = event.instanceId;
214
+ const data = event.data;
215
+ const label = data && typeof data === "object" && "label" in data ? String(data.label) : void 0;
216
+ if (instanceId && label) {
217
+ instanceLabels.set(instanceId, label);
218
+ changed = true;
219
+ }
220
+ }
221
+ if (event.type === "module:init" || event.type === "module:destroy") {
222
+ const moduleId = event.moduleId ?? "unknown";
223
+ const runtimeLabel = event.runtimeLabel ?? "unknown";
224
+ const instanceId = event.instanceId;
225
+ const key = `${runtimeLabel}::${moduleId}`;
226
+ const prev = instances.get(key) ?? 0;
227
+ if (event.type === "module:init") {
228
+ instances.set(key, prev + 1);
229
+ changed = true;
230
+ if (instanceId) {
231
+ const instanceKey = `${runtimeLabel}::${moduleId}::${instanceId}`;
232
+ liveInstanceKeys.add(instanceKey);
233
+ if (latestStates.delete(instanceKey)) changed = true;
234
+ if (latestTraitSummaries.delete(instanceKey)) changed = true;
235
+ }
236
+ } else {
237
+ const next = prev - 1;
238
+ if (next <= 0) {
239
+ if (instances.delete(key)) changed = true;
240
+ } else {
241
+ instances.set(key, next);
242
+ changed = true;
243
+ }
244
+ if (instanceId) {
245
+ const instanceKey = `${runtimeLabel}::${moduleId}::${instanceId}`;
246
+ liveInstanceKeys.delete(instanceKey);
247
+ if (latestStates.delete(instanceKey)) changed = true;
248
+ if (latestTraitSummaries.delete(instanceKey)) changed = true;
249
+ if (instanceLabels.delete(instanceId)) changed = true;
250
+ changed = true;
251
+ }
252
+ }
253
+ }
254
+ let exportBudgetChanged = false;
255
+ const ref = toRuntimeDebugEventRef(event, {
256
+ diagnosticsLevel: level,
257
+ resolveConvergeStaticIr: (staticIrDigest) => convergeStaticIrByDigest.get(staticIrDigest),
258
+ onMetaProjection: ({ stats }) => {
259
+ if (stats.dropped !== 0 || stats.oversized !== 0) {
260
+ exportBudgetChanged = true;
261
+ }
262
+ exportBudget.dropped += stats.dropped;
263
+ exportBudget.oversized += stats.oversized;
264
+ }
265
+ });
266
+ if (exportBudgetChanged) {
267
+ changed = true;
268
+ }
269
+ if (!ref) {
270
+ if (changed) {
271
+ markSnapshotChanged();
272
+ }
273
+ return;
274
+ }
275
+ if (ref.kind === "state" && ref.label === "state:update") {
276
+ const runtimeLabel = ref.runtimeLabel ?? "unknown";
277
+ const key = `${runtimeLabel}::${ref.moduleId}::${ref.instanceId}`;
278
+ if (liveInstanceKeys.has(key)) {
279
+ if (ref.meta && typeof ref.meta === "object" && !Array.isArray(ref.meta)) {
280
+ const anyMeta = ref.meta;
281
+ if ("state" in anyMeta) {
282
+ latestStates.set(key, anyMeta.state);
283
+ changed = true;
284
+ }
285
+ if ("traitSummary" in anyMeta && anyMeta.traitSummary !== void 0) {
286
+ latestTraitSummaries.set(key, anyMeta.traitSummary);
287
+ changed = true;
288
+ }
289
+ }
290
+ }
291
+ }
292
+ if (bufferSize > 0) {
293
+ const seq = nextSeq++;
294
+ ringBuffer.push(ref);
295
+ ringBufferSeq.push(seq);
296
+ trimRingBufferIfNeeded();
297
+ changed = true;
298
+ }
299
+ if (changed) {
300
+ markSnapshotChanged();
301
+ }
302
+ })
303
+ };
304
+
305
+ // ../logix-core/src/internal/runtime/core/TickScheduler.ts
306
+ import { Effect as Effect5, FiberRef as FiberRef3 } from "../effect.js";
307
+
308
+ // ../logix-core/src/internal/runtime/core/JobQueue.ts
309
+ var maxPriority = (a, b) => a === "normal" || b === "normal" ? "normal" : "low";
310
+ var makeJobQueue = () => {
311
+ let pendingModules = /* @__PURE__ */ new Map();
312
+ let pendingDirtyTopics = /* @__PURE__ */ new Map();
313
+ const hasPending = () => pendingModules.size > 0 || pendingDirtyTopics.size > 0;
314
+ const enqueueModuleCommit = (commit) => {
315
+ const prev = pendingModules.get(commit.moduleInstanceKey);
316
+ if (!prev) {
317
+ pendingModules.set(commit.moduleInstanceKey, commit);
318
+ return false;
319
+ }
320
+ pendingModules.set(commit.moduleInstanceKey, {
321
+ ...commit,
322
+ meta: {
323
+ ...commit.meta,
324
+ priority: maxPriority(prev.meta.priority, commit.meta.priority)
325
+ }
326
+ });
327
+ return true;
328
+ };
329
+ const markTopicDirty = (topicKey, priority) => {
330
+ const prev = pendingDirtyTopics.get(topicKey);
331
+ pendingDirtyTopics.set(topicKey, prev ? maxPriority(prev, priority) : priority);
332
+ return prev != null;
333
+ };
334
+ const drain = () => {
335
+ if (!hasPending()) return void 0;
336
+ const drained = {
337
+ modules: pendingModules,
338
+ dirtyTopics: pendingDirtyTopics
339
+ };
340
+ pendingModules = /* @__PURE__ */ new Map();
341
+ pendingDirtyTopics = /* @__PURE__ */ new Map();
342
+ return drained;
343
+ };
344
+ const requeue = (drain2) => {
345
+ for (const [, commit] of drain2.modules) {
346
+ enqueueModuleCommit(commit);
347
+ }
348
+ for (const [k, p] of drain2.dirtyTopics) {
349
+ markTopicDirty(k, p);
350
+ }
351
+ };
352
+ return {
353
+ hasPending,
354
+ enqueueModuleCommit,
355
+ markTopicDirty,
356
+ drain,
357
+ requeue
358
+ };
359
+ };
360
+
361
+ // ../logix-core/src/internal/runtime/core/TaskRunner.ts
362
+ import { Cause, Effect as Effect4, Fiber, FiberRef as FiberRef2, Ref, Stream } from "../effect.js";
363
+
364
+ // ../logix-core/src/internal/runtime/core/env.ts
365
+ import { Context, Effect as Effect3, Layer } from "../effect.js";
366
+
367
+ // ../logix-core/src/internal/runtime/core/RuntimeStore.ts
368
+ var makeModuleInstanceKey = (moduleId, instanceId) => `${moduleId}::${instanceId}`;
369
+ var makeReadQueryTopicKey = (moduleInstanceKey, selectorId) => `${moduleInstanceKey}::rq:${selectorId}`;
370
+ var parseTopicKey = (topicKey) => {
371
+ const idx = topicKey.indexOf("::");
372
+ if (idx <= 0) return void 0;
373
+ const moduleId = topicKey.slice(0, idx);
374
+ const rest = topicKey.slice(idx + 2);
375
+ if (rest.length === 0) return void 0;
376
+ const idx2 = rest.indexOf("::");
377
+ if (idx2 < 0) {
378
+ return { kind: "module", moduleInstanceKey: `${moduleId}::${rest}` };
379
+ }
380
+ const instanceId = rest.slice(0, idx2);
381
+ const suffix = rest.slice(idx2 + 2);
382
+ if (suffix.startsWith("rq:")) {
383
+ const selectorId = suffix.slice("rq:".length);
384
+ if (selectorId.length === 0) return void 0;
385
+ return {
386
+ kind: "readQuery",
387
+ moduleInstanceKey: `${moduleId}::${instanceId}`,
388
+ selectorId
389
+ };
390
+ }
391
+ return { kind: "module", moduleInstanceKey: `${moduleId}::${instanceId}` };
392
+ };
393
+ var makeRuntimeStore = () => {
394
+ let tickSeq = 0;
395
+ const moduleStates = /* @__PURE__ */ new Map();
396
+ const topicVersions = /* @__PURE__ */ new Map();
397
+ const topicPriorities = /* @__PURE__ */ new Map();
398
+ const listenersByTopic = /* @__PURE__ */ new Map();
399
+ const subscriberCountByModule = /* @__PURE__ */ new Map();
400
+ const getTopicVersion = (topicKey) => topicVersions.get(topicKey) ?? 0;
401
+ const getTopicPriority = (topicKey) => topicPriorities.get(topicKey) ?? "normal";
402
+ const commitTopicBump = (topicKey, priority) => {
403
+ const prev = topicVersions.get(topicKey) ?? 0;
404
+ topicVersions.set(topicKey, prev + 1);
405
+ topicPriorities.set(topicKey, priority);
406
+ };
407
+ const subscribeTopic = (topicKey, listener) => {
408
+ const info = parseTopicKey(topicKey);
409
+ const existing = listenersByTopic.get(topicKey);
410
+ const set = existing ?? /* @__PURE__ */ new Set();
411
+ const alreadyHas = set.has(listener);
412
+ if (!alreadyHas) {
413
+ set.add(listener);
414
+ }
415
+ if (!existing) {
416
+ listenersByTopic.set(topicKey, set);
417
+ }
418
+ if (!alreadyHas && info) {
419
+ const prev = subscriberCountByModule.get(info.moduleInstanceKey) ?? 0;
420
+ subscriberCountByModule.set(info.moduleInstanceKey, prev + 1);
421
+ }
422
+ return () => {
423
+ const current = listenersByTopic.get(topicKey);
424
+ if (!current) return;
425
+ const deleted = current.delete(listener);
426
+ if (deleted && info) {
427
+ const prev = subscriberCountByModule.get(info.moduleInstanceKey) ?? 0;
428
+ const next = prev - 1;
429
+ if (next <= 0) {
430
+ subscriberCountByModule.delete(info.moduleInstanceKey);
431
+ } else {
432
+ subscriberCountByModule.set(info.moduleInstanceKey, next);
433
+ }
434
+ }
435
+ if (current.size === 0) {
436
+ listenersByTopic.delete(topicKey);
437
+ }
438
+ };
439
+ };
440
+ const getTopicSubscriberCount = (topicKey) => listenersByTopic.get(topicKey)?.size ?? 0;
441
+ const getModuleSubscriberCount = (moduleInstanceKey) => subscriberCountByModule.get(moduleInstanceKey) ?? 0;
442
+ const registerModuleInstance = (args) => {
443
+ moduleStates.set(args.moduleInstanceKey, args.initialState);
444
+ if (!topicVersions.has(args.moduleInstanceKey)) {
445
+ topicVersions.set(args.moduleInstanceKey, 0);
446
+ topicPriorities.set(args.moduleInstanceKey, "normal");
447
+ }
448
+ };
449
+ const unregisterModuleInstance = (moduleInstanceKey) => {
450
+ moduleStates.delete(moduleInstanceKey);
451
+ };
452
+ const commitTick = (args) => {
453
+ tickSeq = args.tickSeq;
454
+ for (const [key, commit] of args.accepted.modules) {
455
+ moduleStates.set(key, commit.state);
456
+ }
457
+ const changedTopics = /* @__PURE__ */ new Map();
458
+ for (const [topicKey, priority] of args.accepted.dirtyTopics) {
459
+ commitTopicBump(topicKey, priority);
460
+ const listeners2 = Array.from(listenersByTopic.get(topicKey) ?? []);
461
+ if (listeners2.length > 0) {
462
+ changedTopics.set(topicKey, { priority, listeners: listeners2 });
463
+ }
464
+ }
465
+ return { changedTopics };
466
+ };
467
+ const getModuleState = (moduleInstanceKey) => moduleStates.get(moduleInstanceKey);
468
+ const dispose = () => {
469
+ moduleStates.clear();
470
+ topicVersions.clear();
471
+ topicPriorities.clear();
472
+ listenersByTopic.clear();
473
+ subscriberCountByModule.clear();
474
+ };
475
+ return {
476
+ getTickSeq: () => tickSeq,
477
+ getModuleState,
478
+ getTopicVersion,
479
+ getTopicPriority,
480
+ subscribeTopic,
481
+ getTopicSubscriberCount,
482
+ getModuleSubscriberCount,
483
+ registerModuleInstance,
484
+ unregisterModuleInstance,
485
+ commitTick,
486
+ dispose
487
+ };
488
+ };
489
+
490
+ // ../logix-core/src/internal/runtime/core/DeclarativeLinkRuntime.ts
491
+ import { Effect as Effect2 } from "../effect.js";
492
+ var makeDeclarativeLinkRuntime = () => {
493
+ const moduleAsSourceById = /* @__PURE__ */ new Map();
494
+ const moduleAsSourceIdsBySource = /* @__PURE__ */ new Map();
495
+ const declarativeById = /* @__PURE__ */ new Map();
496
+ const declarativeReadNodesBySource = /* @__PURE__ */ new Map();
497
+ const registerModuleAsSourceLink = (link) => {
498
+ const stored = {
499
+ ...link,
500
+ hasValue: false,
501
+ lastValue: void 0
502
+ };
503
+ moduleAsSourceById.set(link.id, stored);
504
+ const set = moduleAsSourceIdsBySource.get(link.sourceModuleInstanceKey) ?? /* @__PURE__ */ new Set();
505
+ set.add(link.id);
506
+ moduleAsSourceIdsBySource.set(link.sourceModuleInstanceKey, set);
507
+ return () => {
508
+ moduleAsSourceById.delete(link.id);
509
+ const current = moduleAsSourceIdsBySource.get(link.sourceModuleInstanceKey);
510
+ if (!current) return;
511
+ current.delete(link.id);
512
+ if (current.size === 0) {
513
+ moduleAsSourceIdsBySource.delete(link.sourceModuleInstanceKey);
514
+ }
515
+ };
516
+ };
517
+ const registerDeclarativeLink = (link) => {
518
+ const readNodeById = /* @__PURE__ */ new Map();
519
+ for (const n of link.readNodes) {
520
+ readNodeById.set(n.nodeId, n);
521
+ }
522
+ const dispatchNodeById = /* @__PURE__ */ new Map();
523
+ for (const n of link.dispatchNodes) {
524
+ dispatchNodeById.set(n.nodeId, n);
525
+ }
526
+ const incomingByDispatch = /* @__PURE__ */ new Map();
527
+ for (const e of link.ir.edges) {
528
+ const to = e.to;
529
+ const isDispatch = dispatchNodeById.has(to);
530
+ if (!isDispatch) continue;
531
+ incomingByDispatch.set(to, (incomingByDispatch.get(to) ?? 0) + 1);
532
+ const count = incomingByDispatch.get(to) ?? 0;
533
+ if (count > 1) {
534
+ throw new Error(
535
+ `[DeclarativeLinkRuntime] Invalid DeclarativeLinkIR: dispatch node has multiple incoming edges (linkId=${link.linkId}, nodeId=${to}).`
536
+ );
537
+ }
538
+ }
539
+ const dispatchTargetsByReadNode = /* @__PURE__ */ new Map();
540
+ for (const e of link.ir.edges) {
541
+ const from = e.from;
542
+ const to = e.to;
543
+ if (!readNodeById.has(from)) continue;
544
+ if (!dispatchNodeById.has(to)) continue;
545
+ const list = dispatchTargetsByReadNode.get(from) ?? [];
546
+ list.push(to);
547
+ dispatchTargetsByReadNode.set(from, list);
548
+ }
549
+ const stored = {
550
+ ...link,
551
+ readNodeById,
552
+ dispatchNodeById,
553
+ dispatchTargetsByReadNode,
554
+ readNodeState: /* @__PURE__ */ new Map()
555
+ };
556
+ declarativeById.set(link.linkId, stored);
557
+ for (const n of link.readNodes) {
558
+ const list = declarativeReadNodesBySource.get(n.moduleInstanceKey) ?? [];
559
+ list.push({ linkId: link.linkId, nodeId: n.nodeId });
560
+ declarativeReadNodesBySource.set(n.moduleInstanceKey, list);
561
+ }
562
+ return () => {
563
+ declarativeById.delete(link.linkId);
564
+ for (const n of link.readNodes) {
565
+ const list = declarativeReadNodesBySource.get(n.moduleInstanceKey);
566
+ if (!list) continue;
567
+ const next = list.filter((x) => !(x.linkId === link.linkId && x.nodeId === n.nodeId));
568
+ if (next.length === 0) {
569
+ declarativeReadNodesBySource.delete(n.moduleInstanceKey);
570
+ } else {
571
+ declarativeReadNodesBySource.set(n.moduleInstanceKey, next);
572
+ }
573
+ }
574
+ };
575
+ };
576
+ const applyForSources = (args) => Effect2.gen(function* () {
577
+ let scheduled = false;
578
+ for (const sourceKey of args.changedModuleInstanceKeys) {
579
+ const ids = moduleAsSourceIdsBySource.get(sourceKey);
580
+ if (!ids || ids.size === 0) continue;
581
+ const commit = args.acceptedModules.get(sourceKey);
582
+ if (!commit) continue;
583
+ for (const id of ids) {
584
+ const link = moduleAsSourceById.get(id);
585
+ if (!link) continue;
586
+ let selected;
587
+ try {
588
+ selected = link.readQuery.select(commit.state);
589
+ } catch {
590
+ continue;
591
+ }
592
+ const nextValue = link.computeValue(selected);
593
+ if (link.hasValue && link.equalsValue(link.lastValue, nextValue)) {
594
+ continue;
595
+ }
596
+ link.hasValue = true;
597
+ link.lastValue = nextValue;
598
+ scheduled = true;
599
+ yield* link.applyValue(nextValue);
600
+ }
601
+ }
602
+ for (const sourceKey of args.changedModuleInstanceKeys) {
603
+ const refs = declarativeReadNodesBySource.get(sourceKey);
604
+ if (!refs || refs.length === 0) continue;
605
+ const commit = args.acceptedModules.get(sourceKey);
606
+ if (!commit) continue;
607
+ for (const ref of refs) {
608
+ const link = declarativeById.get(ref.linkId);
609
+ if (!link) continue;
610
+ const readNode = link.readNodeById.get(ref.nodeId);
611
+ if (!readNode) continue;
612
+ let value;
613
+ try {
614
+ value = readNode.readQuery.select(commit.state);
615
+ } catch {
616
+ continue;
617
+ }
618
+ const state = link.readNodeState.get(ref.nodeId) ?? { hasValue: false, lastValue: void 0 };
619
+ const changed = !state.hasValue || !Object.is(state.lastValue, value);
620
+ if (!changed) continue;
621
+ state.hasValue = true;
622
+ state.lastValue = value;
623
+ link.readNodeState.set(ref.nodeId, state);
624
+ const targets = link.dispatchTargetsByReadNode.get(ref.nodeId) ?? [];
625
+ for (const dispatchNodeId of targets) {
626
+ const node = link.dispatchNodeById.get(dispatchNodeId);
627
+ if (!node) continue;
628
+ scheduled = true;
629
+ yield* node.dispatch(value);
630
+ }
631
+ }
632
+ }
633
+ return { scheduled };
634
+ });
635
+ return {
636
+ registerModuleAsSourceLink,
637
+ registerDeclarativeLink,
638
+ applyForSources
639
+ };
640
+ };
641
+
642
+ // ../logix-core/src/internal/runtime/core/env.ts
643
+ var getNodeEnv = () => {
644
+ try {
645
+ const env = globalThis?.process?.env;
646
+ return typeof env?.NODE_ENV === "string" ? env.NODE_ENV : void 0;
647
+ } catch {
648
+ return void 0;
649
+ }
650
+ };
651
+ var isDevEnv = () => getNodeEnv() !== "production";
652
+ var getDefaultStateTxnInstrumentation = () => isDevEnv() ? "full" : "light";
653
+ var StateTransactionConfigTagImpl = class extends Context.Tag("@logixjs/core/StateTransactionRuntimeConfig")() {
654
+ };
655
+ var StateTransactionConfigTag = StateTransactionConfigTagImpl;
656
+ var ReadQueryStrictGateConfigTagImpl = class extends Context.Tag("@logixjs/core/ReadQueryStrictGateRuntimeConfig")() {
657
+ };
658
+ var ReadQueryStrictGateConfigTag = ReadQueryStrictGateConfigTagImpl;
659
+ var ReplayModeConfigTagImpl = class extends Context.Tag("@logixjs/core/ReplayModeConfig")() {
660
+ };
661
+ var ReplayModeConfigTag = ReplayModeConfigTagImpl;
662
+ var StateTransactionOverridesTagImpl = class extends Context.Tag("@logixjs/core/StateTransactionOverrides")() {
663
+ };
664
+ var StateTransactionOverridesTag = StateTransactionOverridesTagImpl;
665
+ var ConcurrencyPolicyTagImpl = class extends Context.Tag("@logixjs/core/ConcurrencyPolicy")() {
666
+ };
667
+ var ConcurrencyPolicyTag = ConcurrencyPolicyTagImpl;
668
+ var ConcurrencyPolicyOverridesTagImpl = class extends Context.Tag("@logixjs/core/ConcurrencyPolicyOverrides")() {
669
+ };
670
+ var ConcurrencyPolicyOverridesTag = ConcurrencyPolicyOverridesTagImpl;
671
+ var RuntimeStoreTag = class extends Context.Tag("@logixjs/core/RuntimeStore")() {
672
+ };
673
+ var runtimeStoreLayer = Layer.scoped(
674
+ RuntimeStoreTag,
675
+ Effect3.acquireRelease(
676
+ Effect3.sync(() => makeRuntimeStore()),
677
+ (store) => Effect3.sync(() => store.dispose())
678
+ )
679
+ );
680
+ var HostSchedulerTag = class extends Context.Tag("@logixjs/core/HostScheduler")() {
681
+ };
682
+ var hostSchedulerLayer = Layer.succeed(
683
+ HostSchedulerTag,
684
+ getGlobalHostScheduler()
685
+ );
686
+ var DeclarativeLinkRuntimeTag = class extends Context.Tag("@logixjs/core/DeclarativeLinkRuntime")() {
687
+ };
688
+ var declarativeLinkRuntimeLayer = Layer.succeed(
689
+ DeclarativeLinkRuntimeTag,
690
+ makeDeclarativeLinkRuntime()
691
+ );
692
+ var TickSchedulerTag = class extends Context.Tag("@logixjs/core/TickScheduler")() {
693
+ };
694
+ var tickSchedulerLayer = (config) => Layer.effect(
695
+ TickSchedulerTag,
696
+ Effect3.gen(function* () {
697
+ const store = yield* RuntimeStoreTag;
698
+ const declarativeLinkRuntime = yield* DeclarativeLinkRuntimeTag;
699
+ const hostScheduler = yield* HostSchedulerTag;
700
+ return makeTickScheduler({ runtimeStore: store, declarativeLinkRuntime, hostScheduler, config });
701
+ })
702
+ );
703
+
704
+ // ../logix-core/src/internal/runtime/core/TaskRunner.ts
705
+ var inSyncTransactionFiber = FiberRef2.unsafeMake(false);
706
+ var forceSourceRefresh = FiberRef2.unsafeMake(false);
707
+ var inSyncTransactionGlobalDepth = 0;
708
+ var enterSyncTransaction = () => {
709
+ inSyncTransactionGlobalDepth += 1;
710
+ };
711
+ var exitSyncTransaction = () => {
712
+ inSyncTransactionGlobalDepth = Math.max(0, inSyncTransactionGlobalDepth - 1);
713
+ };
714
+ var isInSyncTransaction = () => inSyncTransactionGlobalDepth > 0;
715
+ var resolve = (eff, payload) => typeof eff === "function" ? eff(payload) : eff;
716
+ var defaultOrigins = (triggerName) => ({
717
+ pending: {
718
+ kind: "task:pending",
719
+ name: triggerName
720
+ },
721
+ success: {
722
+ kind: "service-callback",
723
+ name: "task:success"
724
+ },
725
+ failure: {
726
+ kind: "service-callback",
727
+ name: "task:failure"
728
+ }
729
+ });
730
+ var shouldNoopInSyncTransactionFiber = (options) => Effect4.gen(function* () {
731
+ const inTxn = yield* FiberRef2.get(inSyncTransactionFiber);
732
+ if (!inTxn) {
733
+ return false;
734
+ }
735
+ if (isDevEnv()) {
736
+ yield* record({
737
+ type: "diagnostic",
738
+ moduleId: options.moduleId,
739
+ instanceId: options.instanceId,
740
+ code: options.code,
741
+ severity: options.severity,
742
+ message: options.message,
743
+ hint: options.hint,
744
+ actionTag: options.actionTag,
745
+ kind: options.kind
746
+ });
747
+ }
748
+ return true;
749
+ });
750
+ var resolveConcurrencyLimit = (runtime) => runtime.resolveConcurrencyPolicy ? runtime.resolveConcurrencyPolicy().pipe(Effect4.map((p) => p.concurrencyLimit)) : Effect4.succeed(16);
751
+ var runTaskLifecycle = (payload, runtime, config, getCanWriteBack) => Effect4.gen(function* () {
752
+ const noop = yield* shouldNoopInSyncTransactionFiber({
753
+ moduleId: runtime.moduleId,
754
+ instanceId: runtime.instanceId,
755
+ code: "logic::invalid_usage",
756
+ severity: "error",
757
+ message: "run*Task is not allowed inside a synchronous StateTransaction body (it may deadlock the txnQueue).",
758
+ hint: "Call run*Task from the run section of a watcher (e.g. $.onAction/$.onState/$.on); do not call it directly inside a reducer / trait.run / synchronous transaction body. For long-lived flows, use a multi-entry pattern (pending \u2192 IO \u2192 writeback).",
759
+ kind: "run_task_in_transaction"
760
+ });
761
+ if (noop) {
762
+ return;
763
+ }
764
+ const defaults = defaultOrigins(config.triggerName);
765
+ const origins = {
766
+ pending: config.origin?.pending ?? defaults.pending,
767
+ success: config.origin?.success ?? defaults.success,
768
+ failure: config.origin?.failure ?? defaults.failure
769
+ };
770
+ const pending = config.pending;
771
+ if (pending) {
772
+ yield* Effect4.uninterruptible(
773
+ runtime.runWithStateTransaction(origins.pending, () => Effect4.asVoid(resolve(pending, payload)))
774
+ );
775
+ }
776
+ const io = resolve(config.effect, payload);
777
+ const exit = yield* Effect4.exit(io);
778
+ if (getCanWriteBack) {
779
+ const ok = yield* getCanWriteBack;
780
+ if (!ok) {
781
+ return;
782
+ }
783
+ }
784
+ if (exit._tag === "Success") {
785
+ const success = config.success;
786
+ if (success) {
787
+ yield* runtime.runWithStateTransaction(origins.success, () => Effect4.asVoid(success(exit.value, payload)));
788
+ }
789
+ return;
790
+ }
791
+ const cause = exit.cause;
792
+ if (Cause.isInterrupted(cause)) {
793
+ return;
794
+ }
795
+ const failure = config.failure;
796
+ if (failure) {
797
+ yield* runtime.runWithStateTransaction(origins.failure, () => Effect4.asVoid(failure(cause, payload)));
798
+ }
799
+ }).pipe(
800
+ // Watchers must not crash as a whole due to a single task failure: swallow errors, but keep them diagnosable.
801
+ Effect4.catchAllCause(
802
+ (cause) => record({
803
+ type: "diagnostic",
804
+ moduleId: runtime.moduleId,
805
+ instanceId: runtime.instanceId,
806
+ code: "task_runner::unhandled_failure",
807
+ severity: "error",
808
+ message: "TaskRunner encountered an unhandled failure (pending/IO/writeback).",
809
+ hint: "Add a failure writeback for this task or handle errors explicitly upstream; avoid fire-and-forget swallowing errors.",
810
+ actionTag: config.triggerName,
811
+ kind: "task_runner_unhandled_failure",
812
+ trigger: {
813
+ kind: "task",
814
+ name: config.triggerName
815
+ }
816
+ }).pipe(Effect4.zipRight(Effect4.logError("TaskRunner error", cause)))
817
+ )
818
+ );
819
+ var makeTaskRunner = (stream, mode, runtime, config) => {
820
+ if (mode === "latest") {
821
+ return Effect4.gen(function* () {
822
+ const taskIdRef = yield* Ref.make(0);
823
+ const currentFiberRef = yield* Ref.make(void 0);
824
+ const start = (payload) => Effect4.gen(function* () {
825
+ const taskId = yield* Ref.updateAndGet(taskIdRef, (n) => n + 1);
826
+ const prev = yield* Ref.get(currentFiberRef);
827
+ if (prev) {
828
+ yield* Fiber.interruptFork(prev);
829
+ }
830
+ const canWriteBack = Ref.get(taskIdRef).pipe(Effect4.map((current) => current === taskId));
831
+ const fiber = yield* Effect4.fork(
832
+ runTaskLifecycle(payload, runtime, config, canWriteBack)
833
+ );
834
+ yield* Ref.set(currentFiberRef, fiber);
835
+ });
836
+ return yield* Stream.runForEach(stream, start);
837
+ });
838
+ }
839
+ if (mode === "exhaust") {
840
+ return Effect4.gen(function* () {
841
+ const concurrency = yield* resolveConcurrencyLimit(runtime);
842
+ const busyRef = yield* Ref.make(false);
843
+ const mapper = (payload) => Effect4.gen(function* () {
844
+ const acquired = yield* Ref.modify(
845
+ busyRef,
846
+ (busy) => busy ? [false, busy] : [true, true]
847
+ );
848
+ if (!acquired) {
849
+ return;
850
+ }
851
+ try {
852
+ yield* runTaskLifecycle(payload, runtime, config);
853
+ } finally {
854
+ yield* Ref.set(busyRef, false);
855
+ }
856
+ });
857
+ return yield* Stream.runDrain(stream.pipe(Stream.mapEffect(mapper, { concurrency })));
858
+ });
859
+ }
860
+ if (mode === "parallel") {
861
+ return Effect4.gen(function* () {
862
+ const concurrency = yield* resolveConcurrencyLimit(runtime);
863
+ return yield* Stream.runDrain(
864
+ stream.pipe(
865
+ Stream.mapEffect((payload) => runTaskLifecycle(payload, runtime, config), {
866
+ concurrency
867
+ })
868
+ )
869
+ );
870
+ });
871
+ }
872
+ return Stream.runForEach(
873
+ stream,
874
+ (payload) => runTaskLifecycle(payload, runtime, config)
875
+ );
876
+ };
877
+
878
+ // ../logix-core/src/internal/runtime/core/TickScheduler.ts
879
+ var batchDepth = 0;
880
+ var batchWaiters = /* @__PURE__ */ new Set();
881
+ var enterRuntimeBatch = () => {
882
+ batchDepth += 1;
883
+ };
884
+ var exitRuntimeBatch = () => {
885
+ batchDepth = Math.max(0, batchDepth - 1);
886
+ if (batchDepth !== 0) return;
887
+ const waiters = Array.from(batchWaiters);
888
+ batchWaiters.clear();
889
+ for (const w of waiters) {
890
+ try {
891
+ w.resolve();
892
+ } catch {
893
+ }
894
+ }
895
+ };
896
+ var waitForBatchEndIfNeeded = () => batchDepth === 0 ? Effect5.void : Effect5.async((resume, signal) => {
897
+ let done = false;
898
+ const cleanup = () => {
899
+ if (done) return;
900
+ done = true;
901
+ batchWaiters.delete(waiter);
902
+ try {
903
+ signal.removeEventListener("abort", onAbort);
904
+ } catch {
905
+ }
906
+ };
907
+ const onAbort = () => {
908
+ cleanup();
909
+ };
910
+ const waiter = {
911
+ resolve: () => {
912
+ cleanup();
913
+ resume(Effect5.void);
914
+ }
915
+ };
916
+ batchWaiters.add(waiter);
917
+ try {
918
+ signal.addEventListener("abort", onAbort, { once: true });
919
+ } catch {
920
+ }
921
+ });
922
+ var clampSampleRate = (sampleRate) => {
923
+ if (typeof sampleRate !== "number" || !Number.isFinite(sampleRate)) return 0;
924
+ if (sampleRate <= 0) return 0;
925
+ if (sampleRate >= 1) return 1;
926
+ return sampleRate;
927
+ };
928
+ var shouldSampleTick = (tickSeq, sampleRate) => {
929
+ if (sampleRate <= 0) return false;
930
+ if (sampleRate >= 1) return true;
931
+ const x = tickSeq >>> 0;
932
+ const h = Math.imul(x ^ 2654435769, 2246822507) >>> 0;
933
+ return h / 4294967295 < sampleRate;
934
+ };
935
+ var toTriggerKind = (originKind) => {
936
+ if (originKind === "action") return "dispatch";
937
+ if (originKind === "trait-external-store") return "externalStore";
938
+ if (originKind?.includes("timer")) return "timer";
939
+ return "unknown";
940
+ };
941
+ var toLane = (priority) => priority === "low" ? "nonUrgent" : "urgent";
942
+ var maxPriority2 = (a, b) => a === "normal" || b === "normal" ? "normal" : "low";
943
+ var mergeDrain = (base, next) => {
944
+ const modules = new Map(base.modules);
945
+ for (const [k, commit] of next.modules) {
946
+ const prev = modules.get(k);
947
+ if (!prev) {
948
+ modules.set(k, commit);
949
+ } else {
950
+ modules.set(k, {
951
+ ...commit,
952
+ meta: {
953
+ ...commit.meta,
954
+ priority: maxPriority2(prev.meta.priority, commit.meta.priority)
955
+ }
956
+ });
957
+ }
958
+ }
959
+ const dirtyTopics = new Map(base.dirtyTopics);
960
+ for (const [k, p] of next.dirtyTopics) {
961
+ const prev = dirtyTopics.get(k);
962
+ dirtyTopics.set(k, prev ? maxPriority2(prev, p) : p);
963
+ }
964
+ return { modules, dirtyTopics };
965
+ };
966
+ var emptyDrain = () => ({ modules: /* @__PURE__ */ new Map(), dirtyTopics: /* @__PURE__ */ new Map() });
967
+ var makeTickScheduler = (args) => {
968
+ const store = args.runtimeStore;
969
+ const hostScheduler = args.hostScheduler;
970
+ const declarativeLinks = args.declarativeLinkRuntime;
971
+ const queue = args.queue ?? makeJobQueue();
972
+ const config = {
973
+ maxSteps: args.config?.maxSteps ?? 64,
974
+ urgentStepCap: args.config?.urgentStepCap ?? 512,
975
+ maxDrainRounds: args.config?.maxDrainRounds ?? 8,
976
+ microtaskChainDepthLimit: args.config?.microtaskChainDepthLimit ?? 32
977
+ };
978
+ const telemetry = args.config?.telemetry;
979
+ const telemetrySampleRate = clampSampleRate(telemetry?.sampleRate);
980
+ let tickSeq = 0;
981
+ let scheduled = false;
982
+ let microtaskChainDepth = 0;
983
+ let nextForcedReason;
984
+ let coalescedModules = 0;
985
+ let coalescedTopics = 0;
986
+ const yieldMicrotask = Effect5.async((resume) => {
987
+ hostScheduler.scheduleMicrotask(() => resume(Effect5.void));
988
+ });
989
+ const yieldMacrotask = Effect5.async((resume, signal) => {
990
+ const cancel = hostScheduler.scheduleMacrotask(() => resume(Effect5.void));
991
+ try {
992
+ signal.addEventListener(
993
+ "abort",
994
+ () => {
995
+ cancel();
996
+ },
997
+ { once: true }
998
+ );
999
+ } catch {
1000
+ }
1001
+ });
1002
+ const scheduleTick = () => Effect5.gen(function* () {
1003
+ if (scheduled) return;
1004
+ scheduled = true;
1005
+ const waitedForBatch = batchDepth > 0;
1006
+ const forcedReason = nextForcedReason;
1007
+ nextForcedReason = void 0;
1008
+ const shouldYieldForStarvation = forcedReason == null && microtaskChainDepth >= Math.max(1, config.microtaskChainDepthLimit);
1009
+ const reason = forcedReason ?? (shouldYieldForStarvation ? "microtask_starvation" : void 0);
1010
+ const boundary = reason ? "macrotask" : "microtask";
1011
+ const startedAs = waitedForBatch ? "batch" : boundary;
1012
+ const depthAtSchedule = microtaskChainDepth;
1013
+ yield* Effect5.forkDaemon(
1014
+ Effect5.locally(inSyncTransactionFiber, false)(
1015
+ Effect5.gen(function* () {
1016
+ try {
1017
+ yield* waitForBatchEndIfNeeded();
1018
+ if (boundary === "microtask") {
1019
+ yield* yieldMicrotask;
1020
+ microtaskChainDepth += 1;
1021
+ } else {
1022
+ yield* yieldMacrotask;
1023
+ microtaskChainDepth = 0;
1024
+ }
1025
+ const schedule = {
1026
+ startedAs,
1027
+ microtaskChainDepth: boundary === "macrotask" ? depthAtSchedule : microtaskChainDepth,
1028
+ ...boundary === "macrotask" ? { forcedMacrotask: true, reason: reason ?? "unknown" } : {}
1029
+ };
1030
+ const outcome = yield* flushTick(schedule);
1031
+ if (!outcome.stable) {
1032
+ nextForcedReason = outcome.degradeReason === "budget_steps" ? "budget" : outcome.degradeReason === "cycle_detected" ? "cycle_detected" : "unknown";
1033
+ }
1034
+ } finally {
1035
+ scheduled = false;
1036
+ if (queue.hasPending()) {
1037
+ yield* scheduleTick();
1038
+ } else {
1039
+ microtaskChainDepth = 0;
1040
+ }
1041
+ }
1042
+ })
1043
+ )
1044
+ );
1045
+ });
1046
+ const flushTick = (schedule) => Effect5.gen(function* () {
1047
+ if (!queue.hasPending()) {
1048
+ return { stable: true };
1049
+ }
1050
+ tickSeq += 1;
1051
+ const currentTickSeq = tickSeq;
1052
+ const diagnosticsLevel = yield* FiberRef3.get(currentDiagnosticsLevel);
1053
+ const shouldEmitTrace = isDevtoolsEnabled() && diagnosticsLevel !== "off";
1054
+ const captured = {
1055
+ drainRounds: 0,
1056
+ stable: true,
1057
+ accepted: emptyDrain()
1058
+ };
1059
+ while (captured.drainRounds < config.maxDrainRounds) {
1060
+ const drained = queue.drain();
1061
+ if (!drained) break;
1062
+ captured.drainRounds += 1;
1063
+ captured.accepted = mergeDrain(captured.accepted, drained);
1064
+ if (declarativeLinks && drained.modules.size > 0) {
1065
+ const changedModuleInstanceKeys = Array.from(drained.modules.keys());
1066
+ yield* declarativeLinks.applyForSources({
1067
+ tickSeq: currentTickSeq,
1068
+ acceptedModules: captured.accepted.modules,
1069
+ changedModuleInstanceKeys
1070
+ });
1071
+ }
1072
+ }
1073
+ if (queue.hasPending()) {
1074
+ captured.stable = false;
1075
+ captured.degradeReason = "cycle_detected";
1076
+ }
1077
+ const urgentModules = [];
1078
+ const nonUrgentModules = [];
1079
+ for (const commit of captured.accepted.modules.values()) {
1080
+ if (toLane(commit.meta.priority) === "urgent") {
1081
+ urgentModules.push(commit);
1082
+ } else {
1083
+ nonUrgentModules.push(commit);
1084
+ }
1085
+ }
1086
+ const urgentCapExceeded = urgentModules.length > config.urgentStepCap;
1087
+ const urgentAccepted = urgentCapExceeded ? urgentModules.slice(0, config.urgentStepCap) : urgentModules;
1088
+ const urgentDeferred = urgentCapExceeded ? urgentModules.slice(config.urgentStepCap) : [];
1089
+ const nonUrgentBudget = Math.max(0, config.maxSteps);
1090
+ const nonUrgentAccepted = urgentCapExceeded ? [] : nonUrgentModules.slice(0, nonUrgentBudget);
1091
+ const nonUrgentDeferred = urgentCapExceeded ? nonUrgentModules : nonUrgentModules.slice(nonUrgentBudget);
1092
+ if (urgentCapExceeded) {
1093
+ captured.stable = false;
1094
+ captured.degradeReason = "cycle_detected";
1095
+ } else if (nonUrgentDeferred.length > 0) {
1096
+ captured.stable = false;
1097
+ captured.degradeReason = captured.degradeReason ?? "budget_steps";
1098
+ }
1099
+ const acceptedModules = /* @__PURE__ */ new Map();
1100
+ const deferredModules = /* @__PURE__ */ new Map();
1101
+ for (const c of urgentAccepted) acceptedModules.set(c.moduleInstanceKey, c);
1102
+ for (const c of nonUrgentAccepted) acceptedModules.set(c.moduleInstanceKey, c);
1103
+ for (const c of urgentDeferred) deferredModules.set(c.moduleInstanceKey, c);
1104
+ for (const c of nonUrgentDeferred) deferredModules.set(c.moduleInstanceKey, c);
1105
+ const acceptedTopics = /* @__PURE__ */ new Map();
1106
+ const deferredTopics = /* @__PURE__ */ new Map();
1107
+ for (const [topicKey, priority] of captured.accepted.dirtyTopics) {
1108
+ const info = storeTopicToModuleInstanceKey(topicKey);
1109
+ if (!info) continue;
1110
+ if (acceptedModules.has(info)) {
1111
+ acceptedTopics.set(topicKey, priority);
1112
+ } else if (deferredModules.has(info)) {
1113
+ deferredTopics.set(topicKey, priority);
1114
+ } else {
1115
+ acceptedTopics.set(topicKey, priority);
1116
+ }
1117
+ }
1118
+ const acceptedDrain = {
1119
+ modules: acceptedModules,
1120
+ dirtyTopics: acceptedTopics
1121
+ };
1122
+ const deferredDrain = deferredModules.size > 0 || deferredTopics.size > 0 ? {
1123
+ modules: deferredModules,
1124
+ dirtyTopics: deferredTopics
1125
+ } : void 0;
1126
+ captured.deferred = deferredDrain;
1127
+ let startedAtMs;
1128
+ let triggerSummary;
1129
+ let anchor;
1130
+ let backlog;
1131
+ let result;
1132
+ if (shouldEmitTrace) {
1133
+ startedAtMs = Date.now();
1134
+ triggerSummary = (() => {
1135
+ const triggers = Array.from(captured.accepted.modules.values());
1136
+ const counts = /* @__PURE__ */ new Map();
1137
+ let primary = void 0;
1138
+ for (const t of triggers) {
1139
+ const kind = toTriggerKind(t.meta.originKind);
1140
+ counts.set(kind, (counts.get(kind) ?? 0) + 1);
1141
+ if (!primary) {
1142
+ primary = {
1143
+ kind,
1144
+ moduleId: t.moduleId,
1145
+ instanceId: t.instanceId,
1146
+ fieldPath: kind === "externalStore" ? t.meta.originName : void 0,
1147
+ actionTag: kind === "dispatch" ? t.meta.originName : void 0
1148
+ };
1149
+ }
1150
+ }
1151
+ return {
1152
+ total: triggers.length,
1153
+ kinds: Array.from(counts.entries()).map(([kind, count]) => ({ kind, count })),
1154
+ primary,
1155
+ coalescedCount: {
1156
+ modules: coalescedModules,
1157
+ topics: coalescedTopics
1158
+ }
1159
+ };
1160
+ })();
1161
+ anchor = (() => {
1162
+ const first = captured.accepted.modules.values().next().value;
1163
+ if (!first) return void 0;
1164
+ return {
1165
+ moduleId: first.moduleId,
1166
+ instanceId: first.instanceId,
1167
+ txnSeq: first.meta.txnSeq,
1168
+ txnId: first.meta.txnId,
1169
+ ...typeof first.opSeq === "number" ? { opSeq: first.opSeq } : null
1170
+ };
1171
+ })();
1172
+ backlog = (() => {
1173
+ const deferredWork = captured.deferred;
1174
+ if (!deferredWork) return void 0;
1175
+ const pendingDeferredWork = deferredWork.modules.size + deferredWork.dirtyTopics.size;
1176
+ const deferredModulesList = Array.from(deferredWork.modules.values());
1177
+ const pendingExternalInputs = deferredModulesList.filter((m) => toTriggerKind(m.meta.originKind) === "externalStore").length;
1178
+ const primaryDeferred = deferredModulesList.find((m) => toTriggerKind(m.meta.originKind) === "externalStore") ?? deferredModulesList[0];
1179
+ const kind = primaryDeferred ? toTriggerKind(primaryDeferred.meta.originKind) : "unknown";
1180
+ const deferredPrimary = primaryDeferred != null ? {
1181
+ kind: kind === "externalStore" ? "externalStore" : "unknown",
1182
+ moduleId: primaryDeferred.moduleId,
1183
+ instanceId: primaryDeferred.instanceId,
1184
+ fieldPath: kind === "externalStore" ? primaryDeferred.meta.originName : void 0,
1185
+ storeId: void 0
1186
+ } : void 0;
1187
+ return {
1188
+ pendingExternalInputs,
1189
+ pendingDeferredWork,
1190
+ deferredPrimary
1191
+ };
1192
+ })();
1193
+ result = {
1194
+ stable: captured.stable,
1195
+ ...captured.stable ? null : { degradeReason: captured.degradeReason ?? "unknown" }
1196
+ };
1197
+ }
1198
+ if (shouldEmitTrace && schedule.forcedMacrotask && schedule.reason === "microtask_starvation") {
1199
+ yield* record({
1200
+ type: "warn:microtask-starvation",
1201
+ moduleId: anchor?.moduleId,
1202
+ instanceId: anchor?.instanceId,
1203
+ tickSeq: currentTickSeq,
1204
+ microtaskChainDepth: schedule.microtaskChainDepth
1205
+ });
1206
+ }
1207
+ if (shouldEmitTrace) {
1208
+ yield* record({
1209
+ type: "trace:tick",
1210
+ moduleId: anchor?.moduleId,
1211
+ instanceId: anchor?.instanceId,
1212
+ data: {
1213
+ tickSeq: currentTickSeq,
1214
+ phase: "start",
1215
+ timestampMs: startedAtMs,
1216
+ schedule,
1217
+ triggerSummary,
1218
+ anchors: anchor,
1219
+ budget: {
1220
+ maxSteps: config.maxSteps,
1221
+ elapsedMs: 0,
1222
+ steps: 0,
1223
+ txnCount: acceptedModules.size
1224
+ }
1225
+ }
1226
+ });
1227
+ }
1228
+ if (!captured.stable && shouldEmitTrace) {
1229
+ yield* record({
1230
+ type: "trace:tick",
1231
+ moduleId: anchor?.moduleId,
1232
+ instanceId: anchor?.instanceId,
1233
+ data: {
1234
+ tickSeq: currentTickSeq,
1235
+ phase: "budgetExceeded",
1236
+ timestampMs: Date.now(),
1237
+ schedule,
1238
+ triggerSummary,
1239
+ anchors: anchor,
1240
+ budget: {
1241
+ maxSteps: config.maxSteps,
1242
+ elapsedMs: Math.max(0, Date.now() - startedAtMs),
1243
+ steps: config.maxSteps,
1244
+ txnCount: acceptedModules.size
1245
+ },
1246
+ backlog,
1247
+ result
1248
+ }
1249
+ });
1250
+ }
1251
+ if (deferredDrain) {
1252
+ queue.requeue(deferredDrain);
1253
+ }
1254
+ const committed = store.commitTick({
1255
+ tickSeq: currentTickSeq,
1256
+ accepted: acceptedDrain
1257
+ });
1258
+ for (const { listeners: listeners2 } of committed.changedTopics.values()) {
1259
+ for (const listener of listeners2) {
1260
+ try {
1261
+ listener();
1262
+ } catch {
1263
+ }
1264
+ }
1265
+ }
1266
+ if (!captured.stable && shouldEmitTrace && backlog?.deferredPrimary) {
1267
+ const primary = backlog.deferredPrimary;
1268
+ if (primary.kind === "externalStore") {
1269
+ const moduleInstanceKey = primary.moduleId && primary.instanceId ? `${primary.moduleId}::${primary.instanceId}` : void 0;
1270
+ if (moduleInstanceKey && store.getModuleSubscriberCount(moduleInstanceKey) > 0) {
1271
+ yield* record({
1272
+ type: "warn:priority-inversion",
1273
+ moduleId: primary.moduleId,
1274
+ instanceId: primary.instanceId,
1275
+ tickSeq: currentTickSeq,
1276
+ reason: "deferredBacklog"
1277
+ });
1278
+ }
1279
+ }
1280
+ }
1281
+ if (shouldEmitTrace) {
1282
+ yield* record({
1283
+ type: "trace:tick",
1284
+ moduleId: anchor?.moduleId,
1285
+ instanceId: anchor?.instanceId,
1286
+ data: {
1287
+ tickSeq: currentTickSeq,
1288
+ phase: "settled",
1289
+ timestampMs: Date.now(),
1290
+ schedule,
1291
+ triggerSummary,
1292
+ anchors: anchor,
1293
+ budget: {
1294
+ maxSteps: config.maxSteps,
1295
+ elapsedMs: Math.max(0, Date.now() - startedAtMs),
1296
+ steps: acceptedModules.size,
1297
+ txnCount: acceptedModules.size
1298
+ },
1299
+ backlog,
1300
+ result
1301
+ }
1302
+ });
1303
+ }
1304
+ if (telemetry?.onTickDegraded && (schedule.forcedMacrotask || !captured.stable) && shouldSampleTick(currentTickSeq, telemetrySampleRate)) {
1305
+ try {
1306
+ telemetry.onTickDegraded({
1307
+ tickSeq: currentTickSeq,
1308
+ stable: captured.stable,
1309
+ degradeReason: captured.stable ? void 0 : captured.degradeReason ?? "unknown",
1310
+ forcedMacrotask: schedule.forcedMacrotask,
1311
+ scheduleReason: schedule.reason,
1312
+ microtaskChainDepth: schedule.microtaskChainDepth,
1313
+ deferredWorkCount: deferredDrain ? deferredDrain.modules.size + deferredDrain.dirtyTopics.size : 0
1314
+ });
1315
+ } catch {
1316
+ }
1317
+ }
1318
+ coalescedModules = 0;
1319
+ coalescedTopics = 0;
1320
+ return { stable: captured.stable, degradeReason: captured.degradeReason };
1321
+ });
1322
+ const flushNow = flushTick({ startedAs: "unknown" }).pipe(Effect5.asVoid);
1323
+ const storeTopicToModuleInstanceKey = (topicKey) => {
1324
+ const idx = topicKey.indexOf("::rq:");
1325
+ if (idx > 0) {
1326
+ return topicKey.slice(0, idx);
1327
+ }
1328
+ if (topicKey.includes("::")) {
1329
+ return topicKey;
1330
+ }
1331
+ return void 0;
1332
+ };
1333
+ const onSelectorChanged = ({ moduleInstanceKey, selectorId, priority }) => {
1334
+ const coalesced = queue.markTopicDirty(makeReadQueryTopicKey(moduleInstanceKey, selectorId), priority);
1335
+ if (coalesced) coalescedTopics += 1;
1336
+ };
1337
+ const onModuleCommit = (commit) => Effect5.gen(function* () {
1338
+ const coalescedCommit = queue.enqueueModuleCommit(commit);
1339
+ if (coalescedCommit) coalescedModules += 1;
1340
+ const coalescedTopic = queue.markTopicDirty(commit.moduleInstanceKey, commit.meta.priority);
1341
+ if (coalescedTopic) coalescedTopics += 1;
1342
+ yield* scheduleTick();
1343
+ });
1344
+ return {
1345
+ getTickSeq: () => tickSeq,
1346
+ onModuleCommit,
1347
+ onSelectorChanged,
1348
+ flushNow
1349
+ };
1350
+ };
1351
+
1352
+ export {
1353
+ makeModuleInstanceKey,
1354
+ configureDevtoolsHub,
1355
+ isDevtoolsEnabled,
1356
+ getDevtoolsSnapshot,
1357
+ getDevtoolsSnapshotToken,
1358
+ subscribeDevtoolsSnapshot,
1359
+ getDevtoolsRunId,
1360
+ setDevtoolsRunId,
1361
+ startDevtoolsRun,
1362
+ clearDevtoolsEvents,
1363
+ setInstanceLabel,
1364
+ getInstanceLabel,
1365
+ devtoolsHubConvergeStaticIrCollector,
1366
+ exportDevtoolsEvidencePackage,
1367
+ devtoolsHubSink,
1368
+ enterRuntimeBatch,
1369
+ exitRuntimeBatch,
1370
+ getNodeEnv,
1371
+ isDevEnv,
1372
+ getDefaultStateTxnInstrumentation,
1373
+ StateTransactionConfigTag,
1374
+ ReadQueryStrictGateConfigTag,
1375
+ ReplayModeConfigTag,
1376
+ StateTransactionOverridesTag,
1377
+ ConcurrencyPolicyTag,
1378
+ ConcurrencyPolicyOverridesTag,
1379
+ RuntimeStoreTag,
1380
+ runtimeStoreLayer,
1381
+ HostSchedulerTag,
1382
+ hostSchedulerLayer,
1383
+ DeclarativeLinkRuntimeTag,
1384
+ declarativeLinkRuntimeLayer,
1385
+ TickSchedulerTag,
1386
+ tickSchedulerLayer,
1387
+ inSyncTransactionFiber,
1388
+ forceSourceRefresh,
1389
+ enterSyncTransaction,
1390
+ exitSyncTransaction,
1391
+ isInSyncTransaction,
1392
+ shouldNoopInSyncTransactionFiber,
1393
+ makeTaskRunner
1394
+ };
1395
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvcnVudGltZS9jb3JlL0RldnRvb2xzSHViLnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9UaWNrU2NoZWR1bGVyLnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9Kb2JRdWV1ZS50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9ydW50aW1lL2NvcmUvVGFza1J1bm5lci50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9ydW50aW1lL2NvcmUvZW52LnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9SdW50aW1lU3RvcmUudHMiLCAiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvcnVudGltZS9jb3JlL0RlY2xhcmF0aXZlTGlua1J1bnRpbWUudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCB7IEVmZmVjdCwgRmliZXJSZWYgfSBmcm9tICdlZmZlY3QnXG5pbXBvcnQgdHlwZSB7IEpzb25WYWx1ZSB9IGZyb20gJy4uLy4uL29ic2VydmFiaWxpdHkvanNvblZhbHVlLmpzJ1xuaW1wb3J0IHR5cGUgeyBFdmlkZW5jZVBhY2thZ2UsIEV2aWRlbmNlUGFja2FnZVNvdXJjZSB9IGZyb20gJy4uLy4uL29ic2VydmFiaWxpdHkvZXZpZGVuY2UuanMnXG5pbXBvcnQgeyBleHBvcnRFdmlkZW5jZVBhY2thZ2UsIE9CU0VSVkFCSUxJVFlfUFJPVE9DT0xfVkVSU0lPTiB9IGZyb20gJy4uLy4uL29ic2VydmFiaWxpdHkvZXZpZGVuY2UuanMnXG5pbXBvcnQgdHlwZSB7IENvbnZlcmdlU3RhdGljSXJFeHBvcnQgfSBmcm9tICcuLi8uLi9zdGF0ZS10cmFpdC9jb252ZXJnZS1pci5qcydcbmltcG9ydCB0eXBlIHsgQ29udmVyZ2VTdGF0aWNJckNvbGxlY3RvciB9IGZyb20gJy4vQ29udmVyZ2VTdGF0aWNJckNvbGxlY3Rvci5qcydcbmltcG9ydCB7XG4gIGN1cnJlbnREaWFnbm9zdGljc0xldmVsLFxuICBjbGVhclJ1bnRpbWVEZWJ1Z0V2ZW50U2VxLFxuICB0b1J1bnRpbWVEZWJ1Z0V2ZW50UmVmLFxuICB0eXBlIEV2ZW50LFxuICB0eXBlIFJ1bnRpbWVEZWJ1Z0V2ZW50UmVmLFxuICB0eXBlIFNpbmssXG59IGZyb20gJy4vRGVidWdTaW5rLmpzJ1xuaW1wb3J0IHsgZ2V0R2xvYmFsSG9zdFNjaGVkdWxlciB9IGZyb20gJy4vSG9zdFNjaGVkdWxlci5qcydcblxuLyoqXG4gKiBEZXZ0b29sc0h1Ylx1RkYxQVxuICogLSBQcm9jZXNzL3BhZ2UtbGV2ZWwgRGVidWcgZXZlbnQgYWdncmVnYXRvciAoZ2xvYmFsIHNpbmdsZXRvbikuXG4gKlxuICogTm90ZTogdGhpcyBodWIgaXMgb25seSBhcHBlbmRlZCB0byBEZWJ1ZyBzaW5rcyB3aGVuIGRldnRvb2xzSHViTGF5ZXIgaXMgZXhwbGljaXRseSBlbmFibGVkLlxuICogVGhlIFNuYXBzaG90IEFQSSBpcyBhbHdheXMgYXZhaWxhYmxlIChyZXR1cm5zIGVtcHR5IHNuYXBzaG90cyB3aGVuIGRpc2FibGVkKS5cbiAqXG4gKiBQZXJmb3JtYW5jZTpcbiAqIC0gRGV2dG9vbHMgRGVidWcgZXZlbnRzIGNhbiBiZSBleHRyZW1lbHkgZGVuc2UgaW4gaG90IHBhdGhzIChFZmZlY3RPcCAvIFRyYWl0IC8gU3RhdGVUeG4sIGV0Yy4pLlxuICogLSBUaGUgcHJldmlvdXMgaW1wbGVtZW50YXRpb24gY29waWVkIHJpbmdCdWZmZXIgYW5kIE1hcHMgcGVyIGV2ZW50IHRvIGJ1aWxkIGFuIFwiaW1tdXRhYmxlIHNuYXBzaG90XCIgKE8oYnVmZmVyU2l6ZSkpLlxuICogLSBUaGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBsZXRzIFNuYXBzaG90IHJlZmVyZW5jZSBpbnRlcm5hbCBNYXAvQXJyYXkgZGlyZWN0bHkgKHJlYWQtb25seSBjb252ZW50aW9uKSBhbmQgYmF0Y2hlc1xuICogICBzdWJzY3JpYmVyIG5vdGlmaWNhdGlvbnMgaW4gbWljcm90YXNrcywgYXZvaWRpbmcgcGVyLWV2ZW50IGNvcGllcyBhbmQgcmVkdWNpbmcgbWFpbi10aHJlYWQgaW50ZXJmZXJlbmNlLlxuICovXG5cbmV4cG9ydCBpbnRlcmZhY2UgRGV2dG9vbHNTbmFwc2hvdCB7XG4gIC8qKlxuICAgKiBTbmFwc2hvdFRva2VuXHVGRjFBXG4gICAqIC0gTW9ub3RvbmljIHNuYXBzaG90IGNoYW5nZSB0b2tlbiAoYSBzdWJzY3JpcHRpb24tc2FmZSBzb3VyY2Ugb2YgdHJ1dGgpLlxuICAgKiAtIEFueSBleHRlcm5hbGx5IHZpc2libGUgY2hhbmdlIG11c3QgYWR2YW5jZSB0aGUgdG9rZW4uXG4gICAqIC0gSWYgdGhlIHRva2VuIGRvZXMgbm90IGNoYW5nZSwgZXh0ZXJuYWxseSB2aXNpYmxlIHNuYXBzaG90IGZpZWxkcyBtdXN0IG5vdCBjaGFuZ2UgKGF2b2lkIHRlYXJpbmcgLyBtaXNzZWQgdXBkYXRlcykuXG4gICAqL1xuICByZWFkb25seSBzbmFwc2hvdFRva2VuOiBTbmFwc2hvdFRva2VuXG4gIHJlYWRvbmx5IGluc3RhbmNlczogUmVhZG9ubHlNYXA8c3RyaW5nLCBudW1iZXI+XG4gIHJlYWRvbmx5IGV2ZW50czogUmVhZG9ubHlBcnJheTxSdW50aW1lRGVidWdFdmVudFJlZj5cbiAgcmVhZG9ubHkgbGF0ZXN0U3RhdGVzOiBSZWFkb25seU1hcDxzdHJpbmcsIEpzb25WYWx1ZT5cbiAgcmVhZG9ubHkgbGF0ZXN0VHJhaXRTdW1tYXJpZXM6IFJlYWRvbmx5TWFwPHN0cmluZywgSnNvblZhbHVlPlxuICAvKipcbiAgICogZXhwb3J0QnVkZ2V0XHVGRjFBXG4gICAqIC0gVHJhY2tzIFwiZGVncmFkZSBjb3VudHNcIiBjYXVzZWQgYnkgZXhwb3J0IGJvdW5kYXJpZXMgKEpzb25WYWx1ZSBwcm9qZWN0aW9uL3RyaW1taW5nKSwgZm9yIGV4cGxhaW5hYmlsaXR5LlxuICAgKiAtIENvdW50cyBhcmUgY3VtdWxhdGl2ZSAobWF5IGRpZmZlciBmcm9tIHRoZSByaW5nIGJ1ZmZlciB3aW5kb3cpOyBjbGVhckRldnRvb2xzRXZlbnRzIHJlc2V0cyB0aGVtLlxuICAgKi9cbiAgcmVhZG9ubHkgZXhwb3J0QnVkZ2V0OiB7XG4gICAgcmVhZG9ubHkgZHJvcHBlZDogbnVtYmVyXG4gICAgcmVhZG9ubHkgb3ZlcnNpemVkOiBudW1iZXJcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIERldnRvb2xzSHViT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGJ1ZmZlclNpemU/OiBudW1iZXJcbn1cblxuZXhwb3J0IHR5cGUgU25hcHNob3RUb2tlbiA9IG51bWJlclxuXG4vLyAtLS0tIEdsb2JhbCBtdXRhYmxlIHN0YXRlIChzaW5nbGV0b24pIC0tLS1cblxuY29uc3QgaW5zdGFuY2VzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKVxuY29uc3QgbGF0ZXN0U3RhdGVzID0gbmV3IE1hcDxzdHJpbmcsIEpzb25WYWx1ZT4oKVxuY29uc3QgbGF0ZXN0VHJhaXRTdW1tYXJpZXMgPSBuZXcgTWFwPHN0cmluZywgSnNvblZhbHVlPigpXG5jb25zdCBpbnN0YW5jZUxhYmVscyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KClcbmNvbnN0IGNvbnZlcmdlU3RhdGljSXJCeURpZ2VzdCA9IG5ldyBNYXA8c3RyaW5nLCBDb252ZXJnZVN0YXRpY0lyRXhwb3J0PigpXG5jb25zdCBsaXZlSW5zdGFuY2VLZXlzID0gbmV3IFNldDxzdHJpbmc+KClcblxuY29uc3QgZXhwb3J0QnVkZ2V0ID0ge1xuICBkcm9wcGVkOiAwLFxuICBvdmVyc2l6ZWQ6IDAsXG59XG5cbmxldCBsYXN0UnVuVHMgPSAwXG5sZXQgbGFzdFJ1blRzU2VxID0gMFxuXG5jb25zdCBuZXh0UnVuSWQgPSAoKTogc3RyaW5nID0+IHtcbiAgY29uc3QgdHMgPSBEYXRlLm5vdygpXG4gIGlmICh0cyA9PT0gbGFzdFJ1blRzKSB7XG4gICAgbGFzdFJ1blRzU2VxICs9IDFcbiAgfSBlbHNlIHtcbiAgICBsYXN0UnVuVHMgPSB0c1xuICAgIGxhc3RSdW5Uc1NlcSA9IDBcbiAgfVxuXG4gIHJldHVybiBsYXN0UnVuVHNTZXEgPT09IDAgPyBgcnVuLSR7dHN9YCA6IGBydW4tJHt0c30uJHtsYXN0UnVuVHNTZXF9YFxufVxuXG5sZXQgY3VycmVudFJ1bklkID0gbmV4dFJ1bklkKClcbmxldCBuZXh0U2VxID0gMVxuXG5sZXQgYnVmZmVyU2l6ZSA9IDUwMFxuY29uc3QgcmluZ0J1ZmZlcjogUnVudGltZURlYnVnRXZlbnRSZWZbXSA9IFtdXG5jb25zdCByaW5nQnVmZmVyU2VxOiBudW1iZXJbXSA9IFtdXG5cbmxldCBzbmFwc2hvdFRva2VuOiBTbmFwc2hvdFRva2VuID0gMFxuXG5jb25zdCBlbnN1cmVSaW5nQnVmZmVyU2l6ZSA9ICgpOiB2b2lkID0+IHtcbiAgaWYgKGJ1ZmZlclNpemUgPD0gMCkge1xuICAgIHJpbmdCdWZmZXIubGVuZ3RoID0gMFxuICAgIHJpbmdCdWZmZXJTZXEubGVuZ3RoID0gMFxuICAgIHJldHVyblxuICB9XG5cbiAgaWYgKHJpbmdCdWZmZXIubGVuZ3RoIDw9IGJ1ZmZlclNpemUpIHJldHVyblxuICBjb25zdCBleGNlc3MgPSByaW5nQnVmZmVyLmxlbmd0aCAtIGJ1ZmZlclNpemVcbiAgcmluZ0J1ZmZlci5zcGxpY2UoMCwgZXhjZXNzKVxuICByaW5nQnVmZmVyU2VxLnNwbGljZSgwLCBleGNlc3MpXG59XG5cbmNvbnN0IHRyaW1SaW5nQnVmZmVySWZOZWVkZWQgPSAoKTogdm9pZCA9PiB7XG4gIGlmIChidWZmZXJTaXplIDw9IDApIHtcbiAgICByaW5nQnVmZmVyLmxlbmd0aCA9IDBcbiAgICByaW5nQnVmZmVyU2VxLmxlbmd0aCA9IDBcbiAgICByZXR1cm5cbiAgfVxuXG4gIC8vIFNtYWxsIHdpbmRvd3Mga2VlcCBhIHN0cmljdCB1cHBlciBib3VuZCB0byBhdm9pZCBcInNpemU9NSBidXQgZXZlbnRzLmxlbmd0aCBicmllZmx5ID4gNVwiIHN1cnByaXNlcy5cbiAgLy8gTGFyZ2Ugd2luZG93cyBhbGxvdyBzaG9ydCBidXJzdHMgKyBiYXRjaCB0cmltbWluZyB0byBhdm9pZCBsaW5lYXIgc2hpZnQoKSBjb3N0cyB1bmRlciBzdXN0YWluZWQgbG9hZC5cbiAgaWYgKGJ1ZmZlclNpemUgPD0gNjQpIHtcbiAgICBlbnN1cmVSaW5nQnVmZmVyU2l6ZSgpXG4gICAgcmV0dXJuXG4gIH1cblxuICBjb25zdCBzbGFjayA9IE1hdGgubWluKDEwMjQsIE1hdGguZmxvb3IoYnVmZmVyU2l6ZSAvIDIpKVxuICBjb25zdCB0aHJlc2hvbGQgPSBidWZmZXJTaXplICsgTWF0aC5tYXgoMSwgc2xhY2spXG4gIGlmIChyaW5nQnVmZmVyLmxlbmd0aCA8PSB0aHJlc2hvbGQpIHJldHVyblxuXG4gIGNvbnN0IGV4Y2VzcyA9IHJpbmdCdWZmZXIubGVuZ3RoIC0gYnVmZmVyU2l6ZVxuICByaW5nQnVmZmVyLnNwbGljZSgwLCBleGNlc3MpXG4gIHJpbmdCdWZmZXJTZXEuc3BsaWNlKDAsIGV4Y2Vzcylcbn1cblxuLy8gU25hcHNob3QgcmVmZXJlbmNlcyBpbnRlcm5hbCBzdHJ1Y3R1cmVzIGRpcmVjdGx5IChyZWFkLW9ubHkgY29udmVudGlvbikgdG8gYXZvaWQgY29weSBjb3N0cyBpbiBob3QgcGF0aHMuXG5jb25zdCBjdXJyZW50U25hcHNob3Q6IERldnRvb2xzU25hcHNob3QgPSB7XG4gIHNuYXBzaG90VG9rZW4sXG4gIGluc3RhbmNlcyxcbiAgZXZlbnRzOiByaW5nQnVmZmVyLFxuICBsYXRlc3RTdGF0ZXMsXG4gIGxhdGVzdFRyYWl0U3VtbWFyaWVzLFxuICBleHBvcnRCdWRnZXQsXG59XG5cbmNvbnN0IGxpc3RlbmVycyA9IG5ldyBTZXQ8KCkgPT4gdm9pZD4oKVxuXG5sZXQgbm90aWZ5U2NoZWR1bGVkID0gZmFsc2VcbmNvbnN0IHNjaGVkdWxlTm90aWZ5ID0gKCkgPT4ge1xuICBpZiAobGlzdGVuZXJzLnNpemUgPT09IDApIHJldHVyblxuICBpZiAobm90aWZ5U2NoZWR1bGVkKSByZXR1cm5cbiAgbm90aWZ5U2NoZWR1bGVkID0gdHJ1ZVxuICBnZXRHbG9iYWxIb3N0U2NoZWR1bGVyKCkuc2NoZWR1bGVNaWNyb3Rhc2soKCkgPT4ge1xuICAgIG5vdGlmeVNjaGVkdWxlZCA9IGZhbHNlXG4gICAgZm9yIChjb25zdCBsaXN0ZW5lciBvZiBsaXN0ZW5lcnMpIHtcbiAgICAgIGxpc3RlbmVyKClcbiAgICB9XG4gIH0pXG59XG5cbmxldCBkZXZ0b29sc0VuYWJsZWQgPSBmYWxzZVxuXG5jb25zdCBidW1wU25hcHNob3RUb2tlbiA9ICgpOiB2b2lkID0+IHtcbiAgc25hcHNob3RUb2tlbiArPSAxXG4gIDsoY3VycmVudFNuYXBzaG90IGFzIGFueSkuc25hcHNob3RUb2tlbiA9IHNuYXBzaG90VG9rZW5cbn1cblxuY29uc3QgbWFya1NuYXBzaG90Q2hhbmdlZCA9ICgpOiB2b2lkID0+IHtcbiAgYnVtcFNuYXBzaG90VG9rZW4oKVxuICBzY2hlZHVsZU5vdGlmeSgpXG59XG5cbmV4cG9ydCBjb25zdCBjb25maWd1cmVEZXZ0b29sc0h1YiA9IChvcHRpb25zPzogRGV2dG9vbHNIdWJPcHRpb25zKSA9PiB7XG4gIGRldnRvb2xzRW5hYmxlZCA9IHRydWVcbiAgaWYgKHR5cGVvZiBvcHRpb25zPy5idWZmZXJTaXplID09PSAnbnVtYmVyJyAmJiBOdW1iZXIuaXNGaW5pdGUob3B0aW9ucy5idWZmZXJTaXplKSkge1xuICAgIGNvbnN0IG5leHQgPSBNYXRoLmZsb29yKG9wdGlvbnMuYnVmZmVyU2l6ZSlcbiAgICBjb25zdCBuZXh0QnVmZmVyU2l6ZSA9IG5leHQgPj0gMCA/IG5leHQgOiAwXG4gICAgaWYgKG5leHRCdWZmZXJTaXplICE9PSBidWZmZXJTaXplKSB7XG4gICAgICBidWZmZXJTaXplID0gbmV4dEJ1ZmZlclNpemVcbiAgICAgIGVuc3VyZVJpbmdCdWZmZXJTaXplKClcbiAgICAgIG1hcmtTbmFwc2hvdENoYW5nZWQoKVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgaXNEZXZ0b29sc0VuYWJsZWQgPSAoKTogYm9vbGVhbiA9PiBkZXZ0b29sc0VuYWJsZWRcblxuLy8gLS0tLSBTbmFwc2hvdCBwdWJsaWMgaGVscGVycyAtLS0tXG5cbmV4cG9ydCBjb25zdCBnZXREZXZ0b29sc1NuYXBzaG90ID0gKCk6IERldnRvb2xzU25hcHNob3QgPT4gY3VycmVudFNuYXBzaG90XG5leHBvcnQgY29uc3QgZ2V0RGV2dG9vbHNTbmFwc2hvdFRva2VuID0gKCk6IFNuYXBzaG90VG9rZW4gPT4gc25hcHNob3RUb2tlblxuXG5leHBvcnQgY29uc3Qgc3Vic2NyaWJlRGV2dG9vbHNTbmFwc2hvdCA9IChsaXN0ZW5lcjogKCkgPT4gdm9pZCk6ICgoKSA9PiB2b2lkKSA9PiB7XG4gIGxpc3RlbmVycy5hZGQobGlzdGVuZXIpXG4gIHJldHVybiAoKSA9PiB7XG4gICAgbGlzdGVuZXJzLmRlbGV0ZShsaXN0ZW5lcilcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgZ2V0RGV2dG9vbHNSdW5JZCA9ICgpOiBzdHJpbmcgPT4gY3VycmVudFJ1bklkXG5cbmV4cG9ydCBjb25zdCBzZXREZXZ0b29sc1J1bklkID0gKHJ1bklkOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgaWYgKHR5cGVvZiBydW5JZCAhPT0gJ3N0cmluZycgfHwgcnVuSWQubGVuZ3RoID09PSAwKSByZXR1cm5cbiAgaWYgKHJ1bklkICE9PSBjdXJyZW50UnVuSWQpIHtcbiAgICBjdXJyZW50UnVuSWQgPSBydW5JZFxuICAgIG1hcmtTbmFwc2hvdENoYW5nZWQoKVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBzdGFydERldnRvb2xzUnVuID0gKHJ1bklkPzogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgY3VycmVudFJ1bklkID0gdHlwZW9mIHJ1bklkID09PSAnc3RyaW5nJyAmJiBydW5JZC5sZW5ndGggPiAwID8gcnVuSWQgOiBuZXh0UnVuSWQoKVxuICBuZXh0U2VxID0gMVxuICBjbGVhclJ1bnRpbWVEZWJ1Z0V2ZW50U2VxKClcbiAgY2xlYXJEZXZ0b29sc0V2ZW50cygpXG4gIHJldHVybiBjdXJyZW50UnVuSWRcbn1cblxuZXhwb3J0IGNvbnN0IGNsZWFyRGV2dG9vbHNFdmVudHMgPSAoKTogdm9pZCA9PiB7XG4gIHJpbmdCdWZmZXIubGVuZ3RoID0gMFxuICByaW5nQnVmZmVyU2VxLmxlbmd0aCA9IDBcbiAgZXhwb3J0QnVkZ2V0LmRyb3BwZWQgPSAwXG4gIGV4cG9ydEJ1ZGdldC5vdmVyc2l6ZWQgPSAwXG4gIG1hcmtTbmFwc2hvdENoYW5nZWQoKVxufVxuXG5leHBvcnQgY29uc3Qgc2V0SW5zdGFuY2VMYWJlbCA9IChpbnN0YW5jZUlkOiBzdHJpbmcsIGxhYmVsOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgaW5zdGFuY2VMYWJlbHMuc2V0KGluc3RhbmNlSWQsIGxhYmVsKVxuICBtYXJrU25hcHNob3RDaGFuZ2VkKClcbn1cblxuZXhwb3J0IGNvbnN0IGdldEluc3RhbmNlTGFiZWwgPSAoaW5zdGFuY2VJZDogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+IGluc3RhbmNlTGFiZWxzLmdldChpbnN0YW5jZUlkKVxuXG5jb25zdCByZWdpc3RlckNvbnZlcmdlU3RhdGljSXIgPSAoaXI6IENvbnZlcmdlU3RhdGljSXJFeHBvcnQpOiB2b2lkID0+IHtcbiAgY29udmVyZ2VTdGF0aWNJckJ5RGlnZXN0LnNldChpci5zdGF0aWNJckRpZ2VzdCwgaXIpXG59XG5cbmV4cG9ydCBjb25zdCBkZXZ0b29sc0h1YkNvbnZlcmdlU3RhdGljSXJDb2xsZWN0b3I6IENvbnZlcmdlU3RhdGljSXJDb2xsZWN0b3IgPSB7XG4gIHJlZ2lzdGVyOiByZWdpc3RlckNvbnZlcmdlU3RhdGljSXIsXG59XG5cbmV4cG9ydCBjb25zdCBleHBvcnREZXZ0b29sc0V2aWRlbmNlUGFja2FnZSA9IChvcHRpb25zPzoge1xuICByZWFkb25seSBydW5JZD86IHN0cmluZ1xuICByZWFkb25seSBzb3VyY2U/OiBFdmlkZW5jZVBhY2thZ2VTb3VyY2VcbiAgcmVhZG9ubHkgcHJvdG9jb2xWZXJzaW9uPzogc3RyaW5nXG59KTogRXZpZGVuY2VQYWNrYWdlID0+IHtcbiAgY29uc3QgcHJvdG9jb2xWZXJzaW9uID0gb3B0aW9ucz8ucHJvdG9jb2xWZXJzaW9uID8/IE9CU0VSVkFCSUxJVFlfUFJPVE9DT0xfVkVSU0lPTlxuICBjb25zdCBydW5JZCA9IG9wdGlvbnM/LnJ1bklkID8/IGN1cnJlbnRSdW5JZFxuICBjb25zdCBzb3VyY2UgPSBvcHRpb25zPy5zb3VyY2UgPz8geyBob3N0OiAndW5rbm93bicgfVxuXG4gIGNvbnN0IGV2ZW50cyA9IHJpbmdCdWZmZXIubWFwKChwYXlsb2FkLCBpKSA9PiAoe1xuICAgIHByb3RvY29sVmVyc2lvbixcbiAgICBydW5JZCxcbiAgICBzZXE6IHJpbmdCdWZmZXJTZXFbaV0gPz8gaSArIDEsXG4gICAgdGltZXN0YW1wOiBwYXlsb2FkLnRpbWVzdGFtcCxcbiAgICB0eXBlOiAnZGVidWc6ZXZlbnQnLFxuICAgIHBheWxvYWQ6IHBheWxvYWQgYXMgdW5rbm93biBhcyBKc29uVmFsdWUsXG4gIH0pKVxuXG4gIGNvbnN0IGlzUmVjb3JkID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPT5cbiAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmICFBcnJheS5pc0FycmF5KHZhbHVlKVxuXG4gIC8vIEluIGZ1bGwgZGlhZ25vc3RpY3M6IGRlLWR1cGxpY2F0ZSBieSBzdGF0aWNJckRpZ2VzdCBhbmQgZXhwb3J0IG1hdGNoaW5nIENvbnZlcmdlU3RhdGljSVIgKGZvciBvZmZsaW5lIGV4cGxhbmF0aW9uL3JlcGxheSkuXG4gIGNvbnN0IGNvbnZlcmdlRGlnZXN0cyA9IG5ldyBTZXQ8c3RyaW5nPigpXG4gIGxldCBzYXdGdWxsQ29udmVyZ2UgPSBmYWxzZVxuXG4gIGZvciAoY29uc3QgcmVmIG9mIHJpbmdCdWZmZXIpIHtcbiAgICBpZiAocmVmLmtpbmQgIT09ICd0cmFpdDpjb252ZXJnZScpIGNvbnRpbnVlXG4gICAgY29uc3QgbWV0YSA9IHJlZi5tZXRhXG4gICAgaWYgKCFpc1JlY29yZChtZXRhKSkgY29udGludWVcblxuICAgIGNvbnN0IGRpZ2VzdCA9IG1ldGEuc3RhdGljSXJEaWdlc3RcbiAgICBpZiAodHlwZW9mIGRpZ2VzdCA9PT0gJ3N0cmluZycgJiYgZGlnZXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnZlcmdlRGlnZXN0cy5hZGQoZGlnZXN0KVxuICAgIH1cblxuICAgIGNvbnN0IGRpcnR5ID0gbWV0YS5kaXJ0eVxuICAgIGlmIChpc1JlY29yZChkaXJ0eSkgJiYgdHlwZW9mIGRpcnR5LnJvb3RDb3VudCA9PT0gJ251bWJlcicpIHtcbiAgICAgIHNhd0Z1bGxDb252ZXJnZSA9IHRydWVcbiAgICB9XG4gIH1cblxuICBsZXQgc3VtbWFyeTogSnNvblZhbHVlIHwgdW5kZWZpbmVkXG4gIGlmIChzYXdGdWxsQ29udmVyZ2UgJiYgY29udmVyZ2VEaWdlc3RzLnNpemUgPiAwKSB7XG4gICAgY29uc3Qgc3RhdGljSXJCeURpZ2VzdDogUmVjb3JkPHN0cmluZywgSnNvblZhbHVlPiA9IHt9XG4gICAgZm9yIChjb25zdCBkaWdlc3Qgb2YgY29udmVyZ2VEaWdlc3RzKSB7XG4gICAgICBjb25zdCBpciA9IGNvbnZlcmdlU3RhdGljSXJCeURpZ2VzdC5nZXQoZGlnZXN0KVxuICAgICAgaWYgKGlyKSB7XG4gICAgICAgIHN0YXRpY0lyQnlEaWdlc3RbZGlnZXN0XSA9IGlyIGFzIHVua25vd24gYXMgSnNvblZhbHVlXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChPYmplY3Qua2V5cyhzdGF0aWNJckJ5RGlnZXN0KS5sZW5ndGggPiAwKSB7XG4gICAgICBzdW1tYXJ5ID0geyBjb252ZXJnZTogeyBzdGF0aWNJckJ5RGlnZXN0IH0gfSBhcyB1bmtub3duIGFzIEpzb25WYWx1ZVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBleHBvcnRFdmlkZW5jZVBhY2thZ2Uoe1xuICAgIHByb3RvY29sVmVyc2lvbixcbiAgICBydW5JZCxcbiAgICBzb3VyY2UsXG4gICAgZXZlbnRzLFxuICAgIHN1bW1hcnksXG4gIH0pXG59XG5cbi8vIC0tLS0gSHViIFNpbmsgLS0tLVxuXG5leHBvcnQgY29uc3QgZGV2dG9vbHNIdWJTaW5rOiBTaW5rID0ge1xuICByZWNvcmQ6IChldmVudDogRXZlbnQpID0+XG4gICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgLy8gTk9URTogdGhlIGh1YiBpcyBhIGdsb2JhbCBzaW5nbGV0b24sIGJ1dCB3aGV0aGVyIGV2ZW50cyBhcmUgZXhwb3J0YWJsZS93cml0dGVuIHRvIHRoZSBidWZmZXIgaXMgY29udHJvbGxlZCBieSBGaWJlclJlZixcbiAgICAgIC8vIGVuYWJsaW5nIGRpZmZlcmVudCBwZXJmIGJhc2VsaW5lcy9kaWFnbm9zdGljcyB0aWVycyBhY3Jvc3Mgc2NvcGVzIHdpdGhpbiB0aGUgc2FtZSBwcm9jZXNzLlxuICAgICAgY29uc3QgbGV2ZWwgPSB5aWVsZCogRmliZXJSZWYuZ2V0KGN1cnJlbnREaWFnbm9zdGljc0xldmVsKVxuXG4gICAgICBsZXQgY2hhbmdlZCA9IGZhbHNlXG5cbiAgICAgIC8vIHRyYWNlOmluc3RhbmNlTGFiZWw6IHNldCBhIGh1bWFuLXJlYWRhYmxlIGxhYmVsIGZvciBhIHJ1bnRpbWUgaW5zdGFuY2UuXG4gICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ3RyYWNlOmluc3RhbmNlTGFiZWwnKSB7XG4gICAgICAgIGNvbnN0IGluc3RhbmNlSWQgPSAoZXZlbnQgYXMgYW55KS5pbnN0YW5jZUlkIGFzIHN0cmluZyB8IHVuZGVmaW5lZFxuICAgICAgICBjb25zdCBkYXRhID0gKGV2ZW50IGFzIGFueSkuZGF0YVxuICAgICAgICBjb25zdCBsYWJlbCA9IGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICdvYmplY3QnICYmICdsYWJlbCcgaW4gZGF0YSA/IFN0cmluZygoZGF0YSBhcyBhbnkpLmxhYmVsKSA6IHVuZGVmaW5lZFxuICAgICAgICBpZiAoaW5zdGFuY2VJZCAmJiBsYWJlbCkge1xuICAgICAgICAgIGluc3RhbmNlTGFiZWxzLnNldChpbnN0YW5jZUlkLCBsYWJlbClcbiAgICAgICAgICBjaGFuZ2VkID0gdHJ1ZVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEluc3RhbmNlIGNvdW50ZXJzOiBtYWludGFpbiBhY3RpdmUgaW5zdGFuY2UgY291bnRzIGJ5IHJ1bnRpbWVMYWJlbDo6bW9kdWxlSWQuXG4gICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ21vZHVsZTppbml0JyB8fCBldmVudC50eXBlID09PSAnbW9kdWxlOmRlc3Ryb3knKSB7XG4gICAgICAgIGNvbnN0IG1vZHVsZUlkID0gKGV2ZW50IGFzIGFueSkubW9kdWxlSWQgPz8gJ3Vua25vd24nXG4gICAgICAgIGNvbnN0IHJ1bnRpbWVMYWJlbCA9IChldmVudCBhcyBhbnkpLnJ1bnRpbWVMYWJlbCA/PyAndW5rbm93bidcbiAgICAgICAgY29uc3QgaW5zdGFuY2VJZCA9IChldmVudCBhcyBhbnkpLmluc3RhbmNlSWQgYXMgc3RyaW5nIHwgdW5kZWZpbmVkXG4gICAgICAgIGNvbnN0IGtleSA9IGAke3J1bnRpbWVMYWJlbH06OiR7bW9kdWxlSWR9YFxuICAgICAgICBjb25zdCBwcmV2ID0gaW5zdGFuY2VzLmdldChrZXkpID8/IDBcbiAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09ICdtb2R1bGU6aW5pdCcpIHtcbiAgICAgICAgICBpbnN0YW5jZXMuc2V0KGtleSwgcHJldiArIDEpXG4gICAgICAgICAgY2hhbmdlZCA9IHRydWVcbiAgICAgICAgICBpZiAoaW5zdGFuY2VJZCkge1xuICAgICAgICAgICAgY29uc3QgaW5zdGFuY2VLZXkgPSBgJHtydW50aW1lTGFiZWx9Ojoke21vZHVsZUlkfTo6JHtpbnN0YW5jZUlkfWBcbiAgICAgICAgICAgIGxpdmVJbnN0YW5jZUtleXMuYWRkKGluc3RhbmNlS2V5KVxuICAgICAgICAgICAgLy8gSWYgaW5zdGFuY2VJZCBpcyByZXVzZWQsIGVuc3VyZSBkZXJpdmVkIGNhY2hlcyBkbyBub3QgY2FycnkgbGVmdG92ZXJzIGZyb20gdGhlIHByZXZpb3VzIGxpZmV0aW1lLlxuICAgICAgICAgICAgaWYgKGxhdGVzdFN0YXRlcy5kZWxldGUoaW5zdGFuY2VLZXkpKSBjaGFuZ2VkID0gdHJ1ZVxuICAgICAgICAgICAgaWYgKGxhdGVzdFRyYWl0U3VtbWFyaWVzLmRlbGV0ZShpbnN0YW5jZUtleSkpIGNoYW5nZWQgPSB0cnVlXG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IG5leHQgPSBwcmV2IC0gMVxuICAgICAgICAgIGlmIChuZXh0IDw9IDApIHtcbiAgICAgICAgICAgIGlmIChpbnN0YW5jZXMuZGVsZXRlKGtleSkpIGNoYW5nZWQgPSB0cnVlXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGluc3RhbmNlcy5zZXQoa2V5LCBuZXh0KVxuICAgICAgICAgICAgY2hhbmdlZCA9IHRydWVcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaW5zdGFuY2VJZCkge1xuICAgICAgICAgICAgY29uc3QgaW5zdGFuY2VLZXkgPSBgJHtydW50aW1lTGFiZWx9Ojoke21vZHVsZUlkfTo6JHtpbnN0YW5jZUlkfWBcbiAgICAgICAgICAgIGxpdmVJbnN0YW5jZUtleXMuZGVsZXRlKGluc3RhbmNlS2V5KVxuICAgICAgICAgICAgaWYgKGxhdGVzdFN0YXRlcy5kZWxldGUoaW5zdGFuY2VLZXkpKSBjaGFuZ2VkID0gdHJ1ZVxuICAgICAgICAgICAgaWYgKGxhdGVzdFRyYWl0U3VtbWFyaWVzLmRlbGV0ZShpbnN0YW5jZUtleSkpIGNoYW5nZWQgPSB0cnVlXG4gICAgICAgICAgICBpZiAoaW5zdGFuY2VMYWJlbHMuZGVsZXRlKGluc3RhbmNlSWQpKSBjaGFuZ2VkID0gdHJ1ZVxuICAgICAgICAgICAgY2hhbmdlZCA9IHRydWVcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbGV0IGV4cG9ydEJ1ZGdldENoYW5nZWQgPSBmYWxzZVxuICAgICAgY29uc3QgcmVmID0gdG9SdW50aW1lRGVidWdFdmVudFJlZihldmVudCwge1xuICAgICAgICBkaWFnbm9zdGljc0xldmVsOiBsZXZlbCxcbiAgICAgICAgcmVzb2x2ZUNvbnZlcmdlU3RhdGljSXI6IChzdGF0aWNJckRpZ2VzdCkgPT4gY29udmVyZ2VTdGF0aWNJckJ5RGlnZXN0LmdldChzdGF0aWNJckRpZ2VzdCksXG4gICAgICAgIG9uTWV0YVByb2plY3Rpb246ICh7IHN0YXRzIH0pID0+IHtcbiAgICAgICAgICBpZiAoc3RhdHMuZHJvcHBlZCAhPT0gMCB8fCBzdGF0cy5vdmVyc2l6ZWQgIT09IDApIHtcbiAgICAgICAgICAgIGV4cG9ydEJ1ZGdldENoYW5nZWQgPSB0cnVlXG4gICAgICAgICAgfVxuICAgICAgICAgIGV4cG9ydEJ1ZGdldC5kcm9wcGVkICs9IHN0YXRzLmRyb3BwZWRcbiAgICAgICAgICBleHBvcnRCdWRnZXQub3ZlcnNpemVkICs9IHN0YXRzLm92ZXJzaXplZFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICAgIGlmIChleHBvcnRCdWRnZXRDaGFuZ2VkKSB7XG4gICAgICAgIGNoYW5nZWQgPSB0cnVlXG4gICAgICB9XG4gICAgICBpZiAoIXJlZikge1xuICAgICAgICAvLyBvZmYgdGllcjogZG8gbm90IHdyaXRlIHJpbmcgYnVmZmVyIC8gbGF0ZXN0U3RhdGVzLCBidXQga2VlcCBtaW5pbWFsIGNvdW50ZXJzL2xhYmVscyAoaW5jbHVkaW5nIG1vZHVsZTpkZXN0cm95IGNsZWFudXApLlxuICAgICAgICBpZiAoY2hhbmdlZCkge1xuICAgICAgICAgIG1hcmtTbmFwc2hvdENoYW5nZWQoKVxuICAgICAgICB9XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICAvLyBsYXRlc3RTdGF0ZXMgLyBsYXRlc3RUcmFpdFN1bW1hcmllczogcmVjb3JkIGxhdGVzdCBzbmFwc2hvdHMgYnkgcnVudGltZUxhYmVsOjptb2R1bGVJZDo6aW5zdGFuY2VJZC5cbiAgICAgIGlmIChyZWYua2luZCA9PT0gJ3N0YXRlJyAmJiByZWYubGFiZWwgPT09ICdzdGF0ZTp1cGRhdGUnKSB7XG4gICAgICAgIGNvbnN0IHJ1bnRpbWVMYWJlbCA9IHJlZi5ydW50aW1lTGFiZWwgPz8gJ3Vua25vd24nXG4gICAgICAgIGNvbnN0IGtleSA9IGAke3J1bnRpbWVMYWJlbH06OiR7cmVmLm1vZHVsZUlkfTo6JHtyZWYuaW5zdGFuY2VJZH1gXG5cbiAgICAgICAgLy8gTGF0ZS9yZXBsYXllZCBldmVudHMgYWZ0ZXIgbW9kdWxlOmRlc3Ryb3k6IGFsbG93IGVudGVyaW5nIHRoZSB3aW5kb3cgZm9yIHJlcGxheSwgYnV0IGRvIG5vdCByZWJ1aWxkIGxhdGVzdCogY2FjaGVzLlxuICAgICAgICBpZiAobGl2ZUluc3RhbmNlS2V5cy5oYXMoa2V5KSkge1xuICAgICAgICAgIGlmIChyZWYubWV0YSAmJiB0eXBlb2YgcmVmLm1ldGEgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KHJlZi5tZXRhKSkge1xuICAgICAgICAgICAgY29uc3QgYW55TWV0YSA9IHJlZi5tZXRhIGFzIGFueVxuICAgICAgICAgICAgaWYgKCdzdGF0ZScgaW4gYW55TWV0YSkge1xuICAgICAgICAgICAgICBsYXRlc3RTdGF0ZXMuc2V0KGtleSwgYW55TWV0YS5zdGF0ZSBhcyBKc29uVmFsdWUpXG4gICAgICAgICAgICAgIGNoYW5nZWQgPSB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoJ3RyYWl0U3VtbWFyeScgaW4gYW55TWV0YSAmJiBhbnlNZXRhLnRyYWl0U3VtbWFyeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIGxhdGVzdFRyYWl0U3VtbWFyaWVzLnNldChrZXksIGFueU1ldGEudHJhaXRTdW1tYXJ5IGFzIEpzb25WYWx1ZSlcbiAgICAgICAgICAgICAgY2hhbmdlZCA9IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gcmluZyBidWZmZXI6IGtlZXAgdGhlIG1vc3QgcmVjZW50IGJ1ZmZlclNpemUgUnVudGltZURlYnVnRXZlbnRSZWZzLlxuICAgICAgaWYgKGJ1ZmZlclNpemUgPiAwKSB7XG4gICAgICAgIGNvbnN0IHNlcSA9IG5leHRTZXErK1xuICAgICAgICByaW5nQnVmZmVyLnB1c2gocmVmKVxuICAgICAgICByaW5nQnVmZmVyU2VxLnB1c2goc2VxKVxuICAgICAgICB0cmltUmluZ0J1ZmZlcklmTmVlZGVkKClcbiAgICAgICAgY2hhbmdlZCA9IHRydWVcbiAgICAgIH1cblxuICAgICAgaWYgKGNoYW5nZWQpIHtcbiAgICAgICAgbWFya1NuYXBzaG90Q2hhbmdlZCgpXG4gICAgICB9XG4gICAgfSksXG59XG4iLCAiaW1wb3J0IHsgRWZmZWN0LCBGaWJlclJlZiB9IGZyb20gJ2VmZmVjdCdcbmltcG9ydCAqIGFzIERlYnVnIGZyb20gJy4vRGVidWdTaW5rLmpzJ1xuaW1wb3J0ICogYXMgRGV2dG9vbHNIdWIgZnJvbSAnLi9EZXZ0b29sc0h1Yi5qcydcbmltcG9ydCB0eXBlIHsgRGVjbGFyYXRpdmVMaW5rUnVudGltZSB9IGZyb20gJy4vRGVjbGFyYXRpdmVMaW5rUnVudGltZS5qcydcbmltcG9ydCB0eXBlIHsgSG9zdFNjaGVkdWxlciB9IGZyb20gJy4vSG9zdFNjaGVkdWxlci5qcydcbmltcG9ydCB7IG1ha2VKb2JRdWV1ZSwgdHlwZSBKb2JRdWV1ZSB9IGZyb20gJy4vSm9iUXVldWUuanMnXG5pbXBvcnQgKiBhcyBUYXNrUnVubmVyIGZyb20gJy4vVGFza1J1bm5lci5qcydcbmltcG9ydCB7XG4gIG1ha2VSZWFkUXVlcnlUb3BpY0tleSxcbiAgdHlwZSBNb2R1bGVJbnN0YW5jZUtleSxcbiAgdHlwZSBSdW50aW1lU3RvcmUsXG4gIHR5cGUgUnVudGltZVN0b3JlTW9kdWxlQ29tbWl0LFxuICB0eXBlIFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpbixcbn0gZnJvbSAnLi9SdW50aW1lU3RvcmUuanMnXG5pbXBvcnQgdHlwZSB7IFN0YXRlQ29tbWl0UHJpb3JpdHkgfSBmcm9tICcuL21vZHVsZS5qcydcblxuZXhwb3J0IHR5cGUgVGlja0xhbmUgPSAndXJnZW50JyB8ICdub25VcmdlbnQnXG5cbmV4cG9ydCB0eXBlIFRpY2tEZWdyYWRlUmVhc29uID0gJ2J1ZGdldF9zdGVwcycgfCAnY3ljbGVfZGV0ZWN0ZWQnIHwgJ3Vua25vd24nXG5cbmV4cG9ydCBpbnRlcmZhY2UgVGlja1NjaGVkdWxlckNvbmZpZyB7XG4gIC8qKlxuICAgKiBGaXhwb2ludCBzdGVwIGNhcDpcbiAgICogLSBTdGVwcyBjb3VudCBcIndvcmsgYWNjZXB0YW5jZSB1bml0c1wiIHdpdGhpbiBhIHNpbmdsZSB0aWNrLCBub3QgdGltZS5cbiAgICogLSBFeGNlZWRpbmcgdGhlIGJ1ZGdldCB0cmlnZ2VycyBhIHNvZnQgZGVncmFkZSAoc3RhYmxlPWZhbHNlKSwgZGVmZXJyaW5nIG5vblVyZ2VudCBiYWNrbG9nIHRvIHRoZSBuZXh0IHRpY2suXG4gICAqL1xuICByZWFkb25seSBtYXhTdGVwcz86IG51bWJlclxuICAvKipcbiAgICogVXJnZW50IHNhZmV0eSBjYXA6XG4gICAqIC0gRXZlbiB1cmdlbnQgd29yayBtYXkgYmUgY3V0IHdoZW4gdGhlIHN5c3RlbSBhcHBlYXJzIHRvIGJlIGluIGEgY3ljbGUgKGF2b2lkIGZyZWV6aW5nKS5cbiAgICovXG4gIHJlYWRvbmx5IHVyZ2VudFN0ZXBDYXA/OiBudW1iZXJcbiAgLyoqXG4gICAqIERyYWluLXJvdW5kIGNhcDpcbiAgICogLSBCb3VuZHMgdGhlIG51bWJlciBvZiBkcmFpbiByb3VuZHMgd2hpbGUgY2FwdHVyaW5nIGNvbmN1cnJlbnQgY29tbWl0cyBiZWZvcmUgY29tbWl0dGluZyB0aGUgdGljayBzbmFwc2hvdC5cbiAgICogLSBFeGNlZWRpbmcgdGhlIGNhcCBpcyB0cmVhdGVkIGFzIGEgY3ljbGUgKHN0YWJsZT1mYWxzZSwgZGVncmFkZVJlYXNvbj1jeWNsZV9kZXRlY3RlZCkuXG4gICAqL1xuICByZWFkb25seSBtYXhEcmFpblJvdW5kcz86IG51bWJlclxuICAvKipcbiAgICogTWljcm90YXNrIHN0YXJ2YXRpb24gcHJvdGVjdGlvbiB0aHJlc2hvbGQ6XG4gICAqIC0gQ291bnRzIGNvbnNlY3V0aXZlIHRpY2tzIHNjaGVkdWxlZCBvbiBtaWNyb3Rhc2sgYm91bmRhcmllcyB3aXRob3V0IHlpZWxkaW5nIHRvIGhvc3QgKGJlc3QtZWZmb3J0KS5cbiAgICogLSBFeGNlZWRpbmcgdGhlIGxpbWl0IGZvcmNlcyB0aGUgbmV4dCB0aWNrIHRvIHN0YXJ0IG9uIGEgbWFjcm90YXNrIGJvdW5kYXJ5LlxuICAgKi9cbiAgcmVhZG9ubHkgbWljcm90YXNrQ2hhaW5EZXB0aExpbWl0PzogbnVtYmVyXG4gIC8qKlxuICAgKiBPcHRpb25hbCBkZWdyYWRlZC10aWNrIHRlbGVtZXRyeSAob3B0LWluLCBzYW1wbGVkKTpcbiAgICogLSBSdW5zIGV2ZW4gd2hlbiBkaWFnbm9zdGljcz1vZmYgKERldnRvb2xzIGRpc2FibGVkKS5cbiAgICogLSBJbnRlbmRlZCBmb3IgcHJvZHVjdGlvbiBoZWFsdGggc2lnbmFscyAoZnJlcXVlbmN5IG9mIHN0YWJsZT1mYWxzZSAvIGZvcmNlZCB5aWVsZCkuXG4gICAqL1xuICByZWFkb25seSB0ZWxlbWV0cnk/OiBUaWNrU2NoZWR1bGVyVGVsZW1ldHJ5Q29uZmlnXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGlja1NjaGVkdWxlclRlbGVtZXRyeUV2ZW50IHtcbiAgcmVhZG9ubHkgdGlja1NlcTogbnVtYmVyXG4gIHJlYWRvbmx5IHN0YWJsZTogYm9vbGVhblxuICByZWFkb25seSBkZWdyYWRlUmVhc29uPzogVGlja0RlZ3JhZGVSZWFzb25cbiAgcmVhZG9ubHkgZm9yY2VkTWFjcm90YXNrPzogYm9vbGVhblxuICByZWFkb25seSBzY2hlZHVsZVJlYXNvbj86IFRpY2tTY2hlZHVsZVJlYXNvblxuICByZWFkb25seSBtaWNyb3Rhc2tDaGFpbkRlcHRoPzogbnVtYmVyXG4gIHJlYWRvbmx5IGRlZmVycmVkV29ya0NvdW50PzogbnVtYmVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGlja1NjaGVkdWxlclRlbGVtZXRyeUNvbmZpZyB7XG4gIC8qKiBTYW1wbGUgcmF0ZSBpbiBbMCwgMV0uIERlZmF1bHQ6IDAgKGRpc2FibGVkKS4gKi9cbiAgcmVhZG9ubHkgc2FtcGxlUmF0ZT86IG51bWJlclxuICAvKiogQ2FsbGVkIGZvciB0aWNrcyB0aGF0IGFyZSBkZWdyYWRlZCAoc3RhYmxlPWZhbHNlKSBhbmQvb3Igc3RhcnRlZCBvbiBhIGZvcmNlZCBtYWNyb3Rhc2sgYm91bmRhcnkuICovXG4gIHJlYWRvbmx5IG9uVGlja0RlZ3JhZGVkPzogKGV2ZW50OiBUaWNrU2NoZWR1bGVyVGVsZW1ldHJ5RXZlbnQpID0+IHZvaWRcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUaWNrU2NoZWR1bGVyIHtcbiAgcmVhZG9ubHkgZ2V0VGlja1NlcTogKCkgPT4gbnVtYmVyXG4gIHJlYWRvbmx5IG9uTW9kdWxlQ29tbWl0OiAoY29tbWl0OiBSdW50aW1lU3RvcmVNb2R1bGVDb21taXQpID0+IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIG5ldmVyPlxuICByZWFkb25seSBvblNlbGVjdG9yQ2hhbmdlZDogKGFyZ3M6IHtcbiAgICByZWFkb25seSBtb2R1bGVJbnN0YW5jZUtleTogTW9kdWxlSW5zdGFuY2VLZXlcbiAgICByZWFkb25seSBzZWxlY3RvcklkOiBzdHJpbmdcbiAgICByZWFkb25seSBwcmlvcml0eTogU3RhdGVDb21taXRQcmlvcml0eVxuICB9KSA9PiB2b2lkXG4gIHJlYWRvbmx5IGZsdXNoTm93OiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBuZXZlcj5cbn1cblxuLy8gLS0tLSBSdW50aW1lLmJhdGNoIChzeW5jIGJvdW5kYXJ5KSAtLS0tXG5cbnR5cGUgQmF0Y2hXYWl0ZXIgPSB7IHJlYWRvbmx5IHJlc29sdmU6ICgpID0+IHZvaWQgfVxuXG5sZXQgYmF0Y2hEZXB0aCA9IDBcbmNvbnN0IGJhdGNoV2FpdGVycyA9IG5ldyBTZXQ8QmF0Y2hXYWl0ZXI+KClcblxuZXhwb3J0IGNvbnN0IGVudGVyUnVudGltZUJhdGNoID0gKCk6IHZvaWQgPT4ge1xuICBiYXRjaERlcHRoICs9IDFcbn1cblxuZXhwb3J0IGNvbnN0IGV4aXRSdW50aW1lQmF0Y2ggPSAoKTogdm9pZCA9PiB7XG4gIGJhdGNoRGVwdGggPSBNYXRoLm1heCgwLCBiYXRjaERlcHRoIC0gMSlcbiAgaWYgKGJhdGNoRGVwdGggIT09IDApIHJldHVyblxuICBjb25zdCB3YWl0ZXJzID0gQXJyYXkuZnJvbShiYXRjaFdhaXRlcnMpXG4gIGJhdGNoV2FpdGVycy5jbGVhcigpXG4gIGZvciAoY29uc3QgdyBvZiB3YWl0ZXJzKSB7XG4gICAgdHJ5IHtcbiAgICAgIHcucmVzb2x2ZSgpXG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBiZXN0LWVmZm9ydFxuICAgIH1cbiAgfVxufVxuXG5jb25zdCB3YWl0Rm9yQmF0Y2hFbmRJZk5lZWRlZCA9ICgpOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBuZXZlcj4gPT5cbiAgYmF0Y2hEZXB0aCA9PT0gMFxuICAgID8gRWZmZWN0LnZvaWRcbiAgICA6IEVmZmVjdC5hc3luYzx2b2lkLCBuZXZlcj4oKHJlc3VtZSwgc2lnbmFsKSA9PiB7XG5cbiAgICBsZXQgZG9uZSA9IGZhbHNlXG4gICAgY29uc3QgY2xlYW51cCA9ICgpID0+IHtcbiAgICAgIGlmIChkb25lKSByZXR1cm5cbiAgICAgIGRvbmUgPSB0cnVlXG4gICAgICBiYXRjaFdhaXRlcnMuZGVsZXRlKHdhaXRlcilcbiAgICAgIHRyeSB7XG4gICAgICAgIHNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uQWJvcnQpXG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gYmVzdC1lZmZvcnRcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBvbkFib3J0ID0gKCkgPT4ge1xuICAgICAgY2xlYW51cCgpXG4gICAgfVxuXG4gICAgY29uc3Qgd2FpdGVyOiBCYXRjaFdhaXRlciA9IHtcbiAgICAgIHJlc29sdmU6ICgpID0+IHtcbiAgICAgICAgY2xlYW51cCgpXG4gICAgICAgIHJlc3VtZShFZmZlY3Qudm9pZClcbiAgICAgIH0sXG4gICAgfVxuXG4gICAgYmF0Y2hXYWl0ZXJzLmFkZCh3YWl0ZXIpXG4gICAgdHJ5IHtcbiAgICAgIHNpZ25hbC5hZGRFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uQWJvcnQsIHsgb25jZTogdHJ1ZSB9KVxuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gYmVzdC1lZmZvcnRcbiAgICB9XG4gIH0pXG5cbi8vIC0tLS0gVGlja1NjaGVkdWxlciBpbXBsZW1lbnRhdGlvbiAtLS0tXG5cbnR5cGUgVHJpZ2dlcktpbmQgPSAnZXh0ZXJuYWxTdG9yZScgfCAnZGlzcGF0Y2gnIHwgJ3RpbWVyJyB8ICd1bmtub3duJ1xuXG50eXBlIFRpY2tTY2hlZHVsZVN0YXJ0ZWRBcyA9ICdtaWNyb3Rhc2snIHwgJ21hY3JvdGFzaycgfCAnYmF0Y2gnIHwgJ3Vua25vd24nXG50eXBlIFRpY2tTY2hlZHVsZVJlYXNvbiA9ICdidWRnZXQnIHwgJ2N5Y2xlX2RldGVjdGVkJyB8ICdtaWNyb3Rhc2tfc3RhcnZhdGlvbicgfCAndW5rbm93bidcblxudHlwZSBUaWNrU2NoZWR1bGUgPSB7XG4gIHJlYWRvbmx5IHN0YXJ0ZWRBcz86IFRpY2tTY2hlZHVsZVN0YXJ0ZWRBc1xuICByZWFkb25seSBtaWNyb3Rhc2tDaGFpbkRlcHRoPzogbnVtYmVyXG4gIHJlYWRvbmx5IGZvcmNlZE1hY3JvdGFzaz86IGJvb2xlYW5cbiAgcmVhZG9ubHkgcmVhc29uPzogVGlja1NjaGVkdWxlUmVhc29uXG59XG5cbmNvbnN0IGNsYW1wU2FtcGxlUmF0ZSA9IChzYW1wbGVSYXRlOiBudW1iZXIgfCB1bmRlZmluZWQpOiBudW1iZXIgPT4ge1xuICBpZiAodHlwZW9mIHNhbXBsZVJhdGUgIT09ICdudW1iZXInIHx8ICFOdW1iZXIuaXNGaW5pdGUoc2FtcGxlUmF0ZSkpIHJldHVybiAwXG4gIGlmIChzYW1wbGVSYXRlIDw9IDApIHJldHVybiAwXG4gIGlmIChzYW1wbGVSYXRlID49IDEpIHJldHVybiAxXG4gIHJldHVybiBzYW1wbGVSYXRlXG59XG5cbmNvbnN0IHNob3VsZFNhbXBsZVRpY2sgPSAodGlja1NlcTogbnVtYmVyLCBzYW1wbGVSYXRlOiBudW1iZXIpOiBib29sZWFuID0+IHtcbiAgaWYgKHNhbXBsZVJhdGUgPD0gMCkgcmV0dXJuIGZhbHNlXG4gIGlmIChzYW1wbGVSYXRlID49IDEpIHJldHVybiB0cnVlXG4gIC8vIERldGVybWluaXN0aWMgc2FtcGxpbmc6IHN0YWJsZSBhY3Jvc3MgcnVucywgYXZvaWRzIE1hdGgucmFuZG9tKCkgYW5kIGtlZXBzIG92ZXJoZWFkIG1pbmltYWwuXG4gIGNvbnN0IHggPSB0aWNrU2VxID4+PiAwXG4gIGNvbnN0IGggPSBNYXRoLmltdWwoeCBeIDB4OWUzNzc5YjksIDB4ODVlYmNhNmIpID4+PiAwXG4gIHJldHVybiBoIC8gMHhmZmZmZmZmZiA8IHNhbXBsZVJhdGVcbn1cblxuY29uc3QgdG9UcmlnZ2VyS2luZCA9IChvcmlnaW5LaW5kOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBUcmlnZ2VyS2luZCA9PiB7XG4gIGlmIChvcmlnaW5LaW5kID09PSAnYWN0aW9uJykgcmV0dXJuICdkaXNwYXRjaCdcbiAgaWYgKG9yaWdpbktpbmQgPT09ICd0cmFpdC1leHRlcm5hbC1zdG9yZScpIHJldHVybiAnZXh0ZXJuYWxTdG9yZSdcbiAgaWYgKG9yaWdpbktpbmQ/LmluY2x1ZGVzKCd0aW1lcicpKSByZXR1cm4gJ3RpbWVyJ1xuICByZXR1cm4gJ3Vua25vd24nXG59XG5cbmNvbnN0IHRvTGFuZSA9IChwcmlvcml0eTogU3RhdGVDb21taXRQcmlvcml0eSk6IFRpY2tMYW5lID0+IChwcmlvcml0eSA9PT0gJ2xvdycgPyAnbm9uVXJnZW50JyA6ICd1cmdlbnQnKVxuXG5jb25zdCBtYXhQcmlvcml0eSA9IChhOiBTdGF0ZUNvbW1pdFByaW9yaXR5LCBiOiBTdGF0ZUNvbW1pdFByaW9yaXR5KTogU3RhdGVDb21taXRQcmlvcml0eSA9PlxuICBhID09PSAnbm9ybWFsJyB8fCBiID09PSAnbm9ybWFsJyA/ICdub3JtYWwnIDogJ2xvdydcblxuY29uc3QgbWVyZ2VEcmFpbiA9IChiYXNlOiBSdW50aW1lU3RvcmVQZW5kaW5nRHJhaW4sIG5leHQ6IFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpbik6IFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpbiA9PiB7XG4gIGNvbnN0IG1vZHVsZXMgPSBuZXcgTWFwKGJhc2UubW9kdWxlcylcbiAgZm9yIChjb25zdCBbaywgY29tbWl0XSBvZiBuZXh0Lm1vZHVsZXMpIHtcbiAgICBjb25zdCBwcmV2ID0gbW9kdWxlcy5nZXQoaylcbiAgICBpZiAoIXByZXYpIHtcbiAgICAgIG1vZHVsZXMuc2V0KGssIGNvbW1pdClcbiAgICB9IGVsc2Uge1xuICAgICAgbW9kdWxlcy5zZXQoaywge1xuICAgICAgICAuLi5jb21taXQsXG4gICAgICAgIG1ldGE6IHtcbiAgICAgICAgICAuLi5jb21taXQubWV0YSxcbiAgICAgICAgICBwcmlvcml0eTogbWF4UHJpb3JpdHkocHJldi5tZXRhLnByaW9yaXR5LCBjb21taXQubWV0YS5wcmlvcml0eSksXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGRpcnR5VG9waWNzID0gbmV3IE1hcChiYXNlLmRpcnR5VG9waWNzKVxuICBmb3IgKGNvbnN0IFtrLCBwXSBvZiBuZXh0LmRpcnR5VG9waWNzKSB7XG4gICAgY29uc3QgcHJldiA9IGRpcnR5VG9waWNzLmdldChrKVxuICAgIGRpcnR5VG9waWNzLnNldChrLCBwcmV2ID8gbWF4UHJpb3JpdHkocHJldiwgcCkgOiBwKVxuICB9XG5cbiAgcmV0dXJuIHsgbW9kdWxlcywgZGlydHlUb3BpY3MgfVxufVxuXG5jb25zdCBlbXB0eURyYWluID0gKCk6IFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpbiA9PiAoeyBtb2R1bGVzOiBuZXcgTWFwKCksIGRpcnR5VG9waWNzOiBuZXcgTWFwKCkgfSlcblxuZXhwb3J0IGNvbnN0IG1ha2VUaWNrU2NoZWR1bGVyID0gKGFyZ3M6IHtcbiAgcmVhZG9ubHkgcnVudGltZVN0b3JlOiBSdW50aW1lU3RvcmVcbiAgcmVhZG9ubHkgcXVldWU/OiBKb2JRdWV1ZVxuICByZWFkb25seSBob3N0U2NoZWR1bGVyOiBIb3N0U2NoZWR1bGVyXG4gIHJlYWRvbmx5IGNvbmZpZz86IFRpY2tTY2hlZHVsZXJDb25maWdcbiAgcmVhZG9ubHkgZGVjbGFyYXRpdmVMaW5rUnVudGltZT86IERlY2xhcmF0aXZlTGlua1J1bnRpbWVcbn0pOiBUaWNrU2NoZWR1bGVyID0+IHtcbiAgY29uc3Qgc3RvcmUgPSBhcmdzLnJ1bnRpbWVTdG9yZVxuICBjb25zdCBob3N0U2NoZWR1bGVyID0gYXJncy5ob3N0U2NoZWR1bGVyXG4gIGNvbnN0IGRlY2xhcmF0aXZlTGlua3MgPSBhcmdzLmRlY2xhcmF0aXZlTGlua1J1bnRpbWVcbiAgY29uc3QgcXVldWUgPSBhcmdzLnF1ZXVlID8/IG1ha2VKb2JRdWV1ZSgpXG5cbiAgY29uc3QgY29uZmlnOiBSZXF1aXJlZDxQaWNrPFRpY2tTY2hlZHVsZXJDb25maWcsICdtYXhTdGVwcycgfCAndXJnZW50U3RlcENhcCcgfCAnbWF4RHJhaW5Sb3VuZHMnIHwgJ21pY3JvdGFza0NoYWluRGVwdGhMaW1pdCc+PiA9IHtcbiAgICBtYXhTdGVwczogYXJncy5jb25maWc/Lm1heFN0ZXBzID8/IDY0LFxuICAgIHVyZ2VudFN0ZXBDYXA6IGFyZ3MuY29uZmlnPy51cmdlbnRTdGVwQ2FwID8/IDUxMixcbiAgICBtYXhEcmFpblJvdW5kczogYXJncy5jb25maWc/Lm1heERyYWluUm91bmRzID8/IDgsXG4gICAgbWljcm90YXNrQ2hhaW5EZXB0aExpbWl0OiBhcmdzLmNvbmZpZz8ubWljcm90YXNrQ2hhaW5EZXB0aExpbWl0ID8/IDMyLFxuICB9XG4gIGNvbnN0IHRlbGVtZXRyeSA9IGFyZ3MuY29uZmlnPy50ZWxlbWV0cnlcbiAgY29uc3QgdGVsZW1ldHJ5U2FtcGxlUmF0ZSA9IGNsYW1wU2FtcGxlUmF0ZSh0ZWxlbWV0cnk/LnNhbXBsZVJhdGUpXG5cbiAgbGV0IHRpY2tTZXEgPSAwXG4gIGxldCBzY2hlZHVsZWQgPSBmYWxzZVxuICBsZXQgbWljcm90YXNrQ2hhaW5EZXB0aCA9IDBcbiAgbGV0IG5leHRGb3JjZWRSZWFzb246IFRpY2tTY2hlZHVsZVJlYXNvbiB8IHVuZGVmaW5lZFxuXG4gIGxldCBjb2FsZXNjZWRNb2R1bGVzID0gMFxuICBsZXQgY29hbGVzY2VkVG9waWNzID0gMFxuXG4gIGNvbnN0IHlpZWxkTWljcm90YXNrID0gRWZmZWN0LmFzeW5jPHZvaWQsIG5ldmVyPigocmVzdW1lKSA9PiB7XG4gICAgaG9zdFNjaGVkdWxlci5zY2hlZHVsZU1pY3JvdGFzaygoKSA9PiByZXN1bWUoRWZmZWN0LnZvaWQpKVxuICB9KVxuICBjb25zdCB5aWVsZE1hY3JvdGFzayA9IEVmZmVjdC5hc3luYzx2b2lkLCBuZXZlcj4oKHJlc3VtZSwgc2lnbmFsKSA9PiB7XG4gICAgY29uc3QgY2FuY2VsID0gaG9zdFNjaGVkdWxlci5zY2hlZHVsZU1hY3JvdGFzaygoKSA9PiByZXN1bWUoRWZmZWN0LnZvaWQpKVxuICAgIHRyeSB7XG4gICAgICBzaWduYWwuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgJ2Fib3J0JyxcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIGNhbmNlbCgpXG4gICAgICAgIH0sXG4gICAgICAgIHsgb25jZTogdHJ1ZSB9LFxuICAgICAgKVxuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gYmVzdC1lZmZvcnRcbiAgICB9XG4gIH0pXG5cbiAgY29uc3Qgc2NoZWR1bGVUaWNrID0gKCk6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIG5ldmVyPiA9PlxuICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgIGlmIChzY2hlZHVsZWQpIHJldHVyblxuICAgICAgc2NoZWR1bGVkID0gdHJ1ZVxuXG4gICAgICBjb25zdCB3YWl0ZWRGb3JCYXRjaCA9IGJhdGNoRGVwdGggPiAwXG5cbiAgICAgIGNvbnN0IGZvcmNlZFJlYXNvbiA9IG5leHRGb3JjZWRSZWFzb25cbiAgICAgIG5leHRGb3JjZWRSZWFzb24gPSB1bmRlZmluZWRcblxuICAgICAgY29uc3Qgc2hvdWxkWWllbGRGb3JTdGFydmF0aW9uID1cbiAgICAgICAgZm9yY2VkUmVhc29uID09IG51bGwgJiYgbWljcm90YXNrQ2hhaW5EZXB0aCA+PSBNYXRoLm1heCgxLCBjb25maWcubWljcm90YXNrQ2hhaW5EZXB0aExpbWl0KVxuXG4gICAgICBjb25zdCByZWFzb246IFRpY2tTY2hlZHVsZVJlYXNvbiB8IHVuZGVmaW5lZCA9IGZvcmNlZFJlYXNvbiA/PyAoc2hvdWxkWWllbGRGb3JTdGFydmF0aW9uID8gJ21pY3JvdGFza19zdGFydmF0aW9uJyA6IHVuZGVmaW5lZClcbiAgICAgIGNvbnN0IGJvdW5kYXJ5OiAnbWljcm90YXNrJyB8ICdtYWNyb3Rhc2snID0gcmVhc29uID8gJ21hY3JvdGFzaycgOiAnbWljcm90YXNrJ1xuICAgICAgY29uc3Qgc3RhcnRlZEFzOiBUaWNrU2NoZWR1bGVTdGFydGVkQXMgPSB3YWl0ZWRGb3JCYXRjaCA/ICdiYXRjaCcgOiBib3VuZGFyeVxuICAgICAgY29uc3QgZGVwdGhBdFNjaGVkdWxlID0gbWljcm90YXNrQ2hhaW5EZXB0aFxuXG4gICAgICB5aWVsZCogRWZmZWN0LmZvcmtEYWVtb24oXG4gICAgICAgIEVmZmVjdC5sb2NhbGx5KFRhc2tSdW5uZXIuaW5TeW5jVHJhbnNhY3Rpb25GaWJlciwgZmFsc2UpKFxuICAgICAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIHlpZWxkKiB3YWl0Rm9yQmF0Y2hFbmRJZk5lZWRlZCgpXG4gICAgICAgICAgICAgIGlmIChib3VuZGFyeSA9PT0gJ21pY3JvdGFzaycpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCogeWllbGRNaWNyb3Rhc2tcbiAgICAgICAgICAgICAgICBtaWNyb3Rhc2tDaGFpbkRlcHRoICs9IDFcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB5aWVsZCogeWllbGRNYWNyb3Rhc2tcbiAgICAgICAgICAgICAgICBtaWNyb3Rhc2tDaGFpbkRlcHRoID0gMFxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY29uc3Qgc2NoZWR1bGU6IFRpY2tTY2hlZHVsZSA9IHtcbiAgICAgICAgICAgICAgICBzdGFydGVkQXMsXG4gICAgICAgICAgICAgICAgbWljcm90YXNrQ2hhaW5EZXB0aDogYm91bmRhcnkgPT09ICdtYWNyb3Rhc2snID8gZGVwdGhBdFNjaGVkdWxlIDogbWljcm90YXNrQ2hhaW5EZXB0aCxcbiAgICAgICAgICAgICAgICAuLi4oYm91bmRhcnkgPT09ICdtYWNyb3Rhc2snID8geyBmb3JjZWRNYWNyb3Rhc2s6IHRydWUsIHJlYXNvbjogcmVhc29uID8/ICd1bmtub3duJyB9IDoge30pLFxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY29uc3Qgb3V0Y29tZSA9IHlpZWxkKiBmbHVzaFRpY2soc2NoZWR1bGUpXG4gICAgICAgICAgICAgIGlmICghb3V0Y29tZS5zdGFibGUpIHtcbiAgICAgICAgICAgICAgICBuZXh0Rm9yY2VkUmVhc29uID1cbiAgICAgICAgICAgICAgICAgIG91dGNvbWUuZGVncmFkZVJlYXNvbiA9PT0gJ2J1ZGdldF9zdGVwcydcbiAgICAgICAgICAgICAgICAgICAgPyAnYnVkZ2V0J1xuICAgICAgICAgICAgICAgICAgICA6IG91dGNvbWUuZGVncmFkZVJlYXNvbiA9PT0gJ2N5Y2xlX2RldGVjdGVkJ1xuICAgICAgICAgICAgICAgICAgICAgID8gJ2N5Y2xlX2RldGVjdGVkJ1xuICAgICAgICAgICAgICAgICAgICAgIDogJ3Vua25vd24nXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgIHNjaGVkdWxlZCA9IGZhbHNlXG4gICAgICAgICAgICAgIC8vIElmIHNvbWV0aGluZyB3YXMgcmUtcXVldWVkIG9yIGFycml2ZWQgYWZ0ZXIgY29tbWl0LCBzY2hlZHVsZSB0aGUgbmV4dCB0aWNrIChiZXN0LWVmZm9ydCkuXG4gICAgICAgICAgICAgIGlmIChxdWV1ZS5oYXNQZW5kaW5nKCkpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCogc2NoZWR1bGVUaWNrKClcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNldCBjaGFpbiBkZXB0aCB3aGVuIHRoZSBzeXN0ZW0gYmVjb21lcyBpZGxlIChhdm9pZCBmb3JjaW5nIGEgbWFjcm90YXNrIG9uIHRoZSBuZXh0IHVucmVsYXRlZCB0aWNrKS5cbiAgICAgICAgICAgICAgICBtaWNyb3Rhc2tDaGFpbkRlcHRoID0gMFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICApXG4gICAgfSlcblxuICBjb25zdCBmbHVzaFRpY2sgPSAoc2NoZWR1bGU6IFRpY2tTY2hlZHVsZSk6IEVmZmVjdC5FZmZlY3Q8eyBzdGFibGU6IGJvb2xlYW47IGRlZ3JhZGVSZWFzb24/OiBUaWNrRGVncmFkZVJlYXNvbiB9LCBuZXZlciwgbmV2ZXI+ID0+XG4gICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgIGlmICghcXVldWUuaGFzUGVuZGluZygpKSB7XG4gICAgICByZXR1cm4geyBzdGFibGU6IHRydWUgfVxuICAgIH1cblxuICAgIHRpY2tTZXEgKz0gMVxuICAgIGNvbnN0IGN1cnJlbnRUaWNrU2VxID0gdGlja1NlcVxuXG4gICAgY29uc3QgZGlhZ25vc3RpY3NMZXZlbCA9IHlpZWxkKiBGaWJlclJlZi5nZXQoRGVidWcuY3VycmVudERpYWdub3N0aWNzTGV2ZWwpXG4gICAgY29uc3Qgc2hvdWxkRW1pdFRyYWNlID0gRGV2dG9vbHNIdWIuaXNEZXZ0b29sc0VuYWJsZWQoKSAmJiBkaWFnbm9zdGljc0xldmVsICE9PSAnb2ZmJ1xuXG4gICAgY29uc3QgY2FwdHVyZWQ6IHtcbiAgICAgIGRyYWluUm91bmRzOiBudW1iZXJcbiAgICAgIHN0YWJsZTogYm9vbGVhblxuICAgICAgZGVncmFkZVJlYXNvbj86IFRpY2tEZWdyYWRlUmVhc29uXG4gICAgICBkZWZlcnJlZD86IFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpblxuICAgICAgYWNjZXB0ZWQ6IFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpblxuICAgIH0gPSB7XG4gICAgICBkcmFpblJvdW5kczogMCxcbiAgICAgIHN0YWJsZTogdHJ1ZSxcbiAgICAgIGFjY2VwdGVkOiBlbXB0eURyYWluKCksXG4gICAgfVxuXG4gICAgLy8gRml4cG9pbnQgY2FwdHVyZTogZHJhaW4gLT4gYXBwbHkgZGVjbGFyYXRpdmUgbGlua3MgLT4gZHJhaW4gKGJvdW5kZWQgYnkgbWF4RHJhaW5Sb3VuZHMpLlxuICAgIHdoaWxlIChjYXB0dXJlZC5kcmFpblJvdW5kcyA8IGNvbmZpZy5tYXhEcmFpblJvdW5kcykge1xuICAgICAgY29uc3QgZHJhaW5lZCA9IHF1ZXVlLmRyYWluKClcbiAgICAgIGlmICghZHJhaW5lZCkgYnJlYWtcbiAgICAgIGNhcHR1cmVkLmRyYWluUm91bmRzICs9IDFcbiAgICAgIGNhcHR1cmVkLmFjY2VwdGVkID0gbWVyZ2VEcmFpbihjYXB0dXJlZC5hY2NlcHRlZCwgZHJhaW5lZClcblxuICAgICAgaWYgKGRlY2xhcmF0aXZlTGlua3MgJiYgZHJhaW5lZC5tb2R1bGVzLnNpemUgPiAwKSB7XG4gICAgICAgIGNvbnN0IGNoYW5nZWRNb2R1bGVJbnN0YW5jZUtleXMgPSBBcnJheS5mcm9tKGRyYWluZWQubW9kdWxlcy5rZXlzKCkpXG4gICAgICAgIHlpZWxkKiBkZWNsYXJhdGl2ZUxpbmtzLmFwcGx5Rm9yU291cmNlcyh7XG4gICAgICAgICAgdGlja1NlcTogY3VycmVudFRpY2tTZXEsXG4gICAgICAgICAgYWNjZXB0ZWRNb2R1bGVzOiBjYXB0dXJlZC5hY2NlcHRlZC5tb2R1bGVzLFxuICAgICAgICAgIGNoYW5nZWRNb2R1bGVJbnN0YW5jZUtleXMsXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHF1ZXVlLmhhc1BlbmRpbmcoKSkge1xuICAgICAgY2FwdHVyZWQuc3RhYmxlID0gZmFsc2VcbiAgICAgIGNhcHR1cmVkLmRlZ3JhZGVSZWFzb24gPSAnY3ljbGVfZGV0ZWN0ZWQnXG4gICAgfVxuXG4gICAgLy8gQnVkZ2V0IGVuZm9yY2VtZW50IChkZWZlciBub25VcmdlbnQgb25seTsgdXJnZW50IG1heSBiZSBjdXQgb25seSBpbiBjeWNsZSBzYWZldHktYnJlYWspLlxuICAgIGNvbnN0IHVyZ2VudE1vZHVsZXM6IEFycmF5PFJ1bnRpbWVTdG9yZU1vZHVsZUNvbW1pdD4gPSBbXVxuICAgIGNvbnN0IG5vblVyZ2VudE1vZHVsZXM6IEFycmF5PFJ1bnRpbWVTdG9yZU1vZHVsZUNvbW1pdD4gPSBbXVxuXG4gICAgZm9yIChjb25zdCBjb21taXQgb2YgY2FwdHVyZWQuYWNjZXB0ZWQubW9kdWxlcy52YWx1ZXMoKSkge1xuICAgICAgaWYgKHRvTGFuZShjb21taXQubWV0YS5wcmlvcml0eSkgPT09ICd1cmdlbnQnKSB7XG4gICAgICAgIHVyZ2VudE1vZHVsZXMucHVzaChjb21taXQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub25VcmdlbnRNb2R1bGVzLnB1c2goY29tbWl0KVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHVyZ2VudENhcEV4Y2VlZGVkID0gdXJnZW50TW9kdWxlcy5sZW5ndGggPiBjb25maWcudXJnZW50U3RlcENhcFxuICAgIGNvbnN0IHVyZ2VudEFjY2VwdGVkID0gdXJnZW50Q2FwRXhjZWVkZWQgPyB1cmdlbnRNb2R1bGVzLnNsaWNlKDAsIGNvbmZpZy51cmdlbnRTdGVwQ2FwKSA6IHVyZ2VudE1vZHVsZXNcbiAgICBjb25zdCB1cmdlbnREZWZlcnJlZCA9IHVyZ2VudENhcEV4Y2VlZGVkID8gdXJnZW50TW9kdWxlcy5zbGljZShjb25maWcudXJnZW50U3RlcENhcCkgOiBbXVxuXG4gICAgY29uc3Qgbm9uVXJnZW50QnVkZ2V0ID0gTWF0aC5tYXgoMCwgY29uZmlnLm1heFN0ZXBzKVxuICAgIGNvbnN0IG5vblVyZ2VudEFjY2VwdGVkID0gdXJnZW50Q2FwRXhjZWVkZWQgPyBbXSA6IG5vblVyZ2VudE1vZHVsZXMuc2xpY2UoMCwgbm9uVXJnZW50QnVkZ2V0KVxuICAgIGNvbnN0IG5vblVyZ2VudERlZmVycmVkID0gdXJnZW50Q2FwRXhjZWVkZWQgPyBub25VcmdlbnRNb2R1bGVzIDogbm9uVXJnZW50TW9kdWxlcy5zbGljZShub25VcmdlbnRCdWRnZXQpXG5cbiAgICBpZiAodXJnZW50Q2FwRXhjZWVkZWQpIHtcbiAgICAgIGNhcHR1cmVkLnN0YWJsZSA9IGZhbHNlXG4gICAgICBjYXB0dXJlZC5kZWdyYWRlUmVhc29uID0gJ2N5Y2xlX2RldGVjdGVkJ1xuICAgIH0gZWxzZSBpZiAobm9uVXJnZW50RGVmZXJyZWQubGVuZ3RoID4gMCkge1xuICAgICAgY2FwdHVyZWQuc3RhYmxlID0gZmFsc2VcbiAgICAgIGNhcHR1cmVkLmRlZ3JhZGVSZWFzb24gPSBjYXB0dXJlZC5kZWdyYWRlUmVhc29uID8/ICdidWRnZXRfc3RlcHMnXG4gICAgfVxuXG4gICAgY29uc3QgYWNjZXB0ZWRNb2R1bGVzID0gbmV3IE1hcDxNb2R1bGVJbnN0YW5jZUtleSwgUnVudGltZVN0b3JlTW9kdWxlQ29tbWl0PigpXG4gICAgY29uc3QgZGVmZXJyZWRNb2R1bGVzID0gbmV3IE1hcDxNb2R1bGVJbnN0YW5jZUtleSwgUnVudGltZVN0b3JlTW9kdWxlQ29tbWl0PigpXG5cbiAgICBmb3IgKGNvbnN0IGMgb2YgdXJnZW50QWNjZXB0ZWQpIGFjY2VwdGVkTW9kdWxlcy5zZXQoYy5tb2R1bGVJbnN0YW5jZUtleSwgYylcbiAgICBmb3IgKGNvbnN0IGMgb2Ygbm9uVXJnZW50QWNjZXB0ZWQpIGFjY2VwdGVkTW9kdWxlcy5zZXQoYy5tb2R1bGVJbnN0YW5jZUtleSwgYylcblxuICAgIGZvciAoY29uc3QgYyBvZiB1cmdlbnREZWZlcnJlZCkgZGVmZXJyZWRNb2R1bGVzLnNldChjLm1vZHVsZUluc3RhbmNlS2V5LCBjKVxuICAgIGZvciAoY29uc3QgYyBvZiBub25VcmdlbnREZWZlcnJlZCkgZGVmZXJyZWRNb2R1bGVzLnNldChjLm1vZHVsZUluc3RhbmNlS2V5LCBjKVxuXG4gICAgY29uc3QgYWNjZXB0ZWRUb3BpY3MgPSBuZXcgTWFwPHN0cmluZywgU3RhdGVDb21taXRQcmlvcml0eT4oKVxuICAgIGNvbnN0IGRlZmVycmVkVG9waWNzID0gbmV3IE1hcDxzdHJpbmcsIFN0YXRlQ29tbWl0UHJpb3JpdHk+KClcblxuICAgIGZvciAoY29uc3QgW3RvcGljS2V5LCBwcmlvcml0eV0gb2YgY2FwdHVyZWQuYWNjZXB0ZWQuZGlydHlUb3BpY3MpIHtcbiAgICAgIGNvbnN0IGluZm8gPSBzdG9yZVRvcGljVG9Nb2R1bGVJbnN0YW5jZUtleSh0b3BpY0tleSlcbiAgICAgIGlmICghaW5mbykgY29udGludWVcbiAgICAgIGlmIChhY2NlcHRlZE1vZHVsZXMuaGFzKGluZm8pKSB7XG4gICAgICAgIGFjY2VwdGVkVG9waWNzLnNldCh0b3BpY0tleSwgcHJpb3JpdHkpXG4gICAgICB9IGVsc2UgaWYgKGRlZmVycmVkTW9kdWxlcy5oYXMoaW5mbykpIHtcbiAgICAgICAgZGVmZXJyZWRUb3BpY3Muc2V0KHRvcGljS2V5LCBwcmlvcml0eSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIENvbnNlcnZhdGl2ZSBkZWZhdWx0OiB0cmVhdCB1bmtub3duIHRvcGljcyBhcyBhY2NlcHRlZC5cbiAgICAgICAgYWNjZXB0ZWRUb3BpY3Muc2V0KHRvcGljS2V5LCBwcmlvcml0eSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBhY2NlcHRlZERyYWluOiBSdW50aW1lU3RvcmVQZW5kaW5nRHJhaW4gPSB7XG4gICAgICBtb2R1bGVzOiBhY2NlcHRlZE1vZHVsZXMsXG4gICAgICBkaXJ0eVRvcGljczogYWNjZXB0ZWRUb3BpY3MsXG4gICAgfVxuXG4gICAgY29uc3QgZGVmZXJyZWREcmFpbjogUnVudGltZVN0b3JlUGVuZGluZ0RyYWluIHwgdW5kZWZpbmVkID1cbiAgICAgIGRlZmVycmVkTW9kdWxlcy5zaXplID4gMCB8fCBkZWZlcnJlZFRvcGljcy5zaXplID4gMFxuICAgICAgICA/IHtcbiAgICAgICAgICAgIG1vZHVsZXM6IGRlZmVycmVkTW9kdWxlcyxcbiAgICAgICAgICAgIGRpcnR5VG9waWNzOiBkZWZlcnJlZFRvcGljcyxcbiAgICAgICAgICB9XG4gICAgICAgIDogdW5kZWZpbmVkXG5cbiAgICBjYXB0dXJlZC5kZWZlcnJlZCA9IGRlZmVycmVkRHJhaW5cblxuICAgIGxldCBzdGFydGVkQXRNczogbnVtYmVyIHwgdW5kZWZpbmVkXG4gICAgbGV0IHRyaWdnZXJTdW1tYXJ5OiBhbnkgfCB1bmRlZmluZWRcbiAgICBsZXQgYW5jaG9yOiBhbnkgfCB1bmRlZmluZWRcbiAgICBsZXQgYmFja2xvZzogYW55IHwgdW5kZWZpbmVkXG4gICAgbGV0IHJlc3VsdDogYW55IHwgdW5kZWZpbmVkXG5cbiAgICBpZiAoc2hvdWxkRW1pdFRyYWNlKSB7XG4gICAgICBzdGFydGVkQXRNcyA9IERhdGUubm93KClcblxuICAgICAgdHJpZ2dlclN1bW1hcnkgPSAoKCkgPT4ge1xuICAgICAgICBjb25zdCB0cmlnZ2VycyA9IEFycmF5LmZyb20oY2FwdHVyZWQuYWNjZXB0ZWQubW9kdWxlcy52YWx1ZXMoKSlcbiAgICAgICAgY29uc3QgY291bnRzID0gbmV3IE1hcDxUcmlnZ2VyS2luZCwgbnVtYmVyPigpXG4gICAgICAgIGxldCBwcmltYXJ5OiBhbnkgPSB1bmRlZmluZWRcbiAgICAgICAgZm9yIChjb25zdCB0IG9mIHRyaWdnZXJzKSB7XG4gICAgICAgICAgY29uc3Qga2luZCA9IHRvVHJpZ2dlcktpbmQodC5tZXRhLm9yaWdpbktpbmQpXG4gICAgICAgICAgY291bnRzLnNldChraW5kLCAoY291bnRzLmdldChraW5kKSA/PyAwKSArIDEpXG4gICAgICAgICAgaWYgKCFwcmltYXJ5KSB7XG4gICAgICAgICAgICBwcmltYXJ5ID0ge1xuICAgICAgICAgICAgICBraW5kLFxuICAgICAgICAgICAgICBtb2R1bGVJZDogdC5tb2R1bGVJZCxcbiAgICAgICAgICAgICAgaW5zdGFuY2VJZDogdC5pbnN0YW5jZUlkLFxuICAgICAgICAgICAgICBmaWVsZFBhdGg6IGtpbmQgPT09ICdleHRlcm5hbFN0b3JlJyA/IHQubWV0YS5vcmlnaW5OYW1lIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICBhY3Rpb25UYWc6IGtpbmQgPT09ICdkaXNwYXRjaCcgPyB0Lm1ldGEub3JpZ2luTmFtZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0b3RhbDogdHJpZ2dlcnMubGVuZ3RoLFxuICAgICAgICAgIGtpbmRzOiBBcnJheS5mcm9tKGNvdW50cy5lbnRyaWVzKCkpLm1hcCgoW2tpbmQsIGNvdW50XSkgPT4gKHsga2luZCwgY291bnQgfSkpLFxuICAgICAgICAgIHByaW1hcnksXG4gICAgICAgICAgY29hbGVzY2VkQ291bnQ6IHtcbiAgICAgICAgICAgIG1vZHVsZXM6IGNvYWxlc2NlZE1vZHVsZXMsXG4gICAgICAgICAgICB0b3BpY3M6IGNvYWxlc2NlZFRvcGljcyxcbiAgICAgICAgICB9LFxuICAgICAgICB9XG4gICAgICB9KSgpXG5cbiAgICAgIGFuY2hvciA9ICgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGZpcnN0ID0gY2FwdHVyZWQuYWNjZXB0ZWQubW9kdWxlcy52YWx1ZXMoKS5uZXh0KCkudmFsdWUgYXMgUnVudGltZVN0b3JlTW9kdWxlQ29tbWl0IHwgdW5kZWZpbmVkXG4gICAgICAgIGlmICghZmlyc3QpIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBtb2R1bGVJZDogZmlyc3QubW9kdWxlSWQsXG4gICAgICAgICAgaW5zdGFuY2VJZDogZmlyc3QuaW5zdGFuY2VJZCxcbiAgICAgICAgICB0eG5TZXE6IGZpcnN0Lm1ldGEudHhuU2VxLFxuICAgICAgICAgIHR4bklkOiBmaXJzdC5tZXRhLnR4bklkLFxuICAgICAgICAgIC4uLih0eXBlb2YgZmlyc3Qub3BTZXEgPT09ICdudW1iZXInID8geyBvcFNlcTogZmlyc3Qub3BTZXEgfSA6IG51bGwpLFxuICAgICAgICB9XG4gICAgICB9KSgpXG5cbiAgICAgIGJhY2tsb2cgPSAoKCkgPT4ge1xuICAgICAgICBjb25zdCBkZWZlcnJlZFdvcmsgPSBjYXB0dXJlZC5kZWZlcnJlZFxuICAgICAgICBpZiAoIWRlZmVycmVkV29yaykgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICBjb25zdCBwZW5kaW5nRGVmZXJyZWRXb3JrID0gZGVmZXJyZWRXb3JrLm1vZHVsZXMuc2l6ZSArIGRlZmVycmVkV29yay5kaXJ0eVRvcGljcy5zaXplXG5cbiAgICAgICAgY29uc3QgZGVmZXJyZWRNb2R1bGVzTGlzdCA9IEFycmF5LmZyb20oZGVmZXJyZWRXb3JrLm1vZHVsZXMudmFsdWVzKCkpXG4gICAgICAgIGNvbnN0IHBlbmRpbmdFeHRlcm5hbElucHV0cyA9IGRlZmVycmVkTW9kdWxlc0xpc3QuZmlsdGVyKChtKSA9PiB0b1RyaWdnZXJLaW5kKG0ubWV0YS5vcmlnaW5LaW5kKSA9PT0gJ2V4dGVybmFsU3RvcmUnKS5sZW5ndGhcblxuICAgICAgICBjb25zdCBwcmltYXJ5RGVmZXJyZWQgPVxuICAgICAgICAgIGRlZmVycmVkTW9kdWxlc0xpc3QuZmluZCgobSkgPT4gdG9UcmlnZ2VyS2luZChtLm1ldGEub3JpZ2luS2luZCkgPT09ICdleHRlcm5hbFN0b3JlJykgPz8gZGVmZXJyZWRNb2R1bGVzTGlzdFswXVxuICAgICAgICBjb25zdCBraW5kID0gcHJpbWFyeURlZmVycmVkID8gdG9UcmlnZ2VyS2luZChwcmltYXJ5RGVmZXJyZWQubWV0YS5vcmlnaW5LaW5kKSA6ICd1bmtub3duJ1xuXG4gICAgICAgIGNvbnN0IGRlZmVycmVkUHJpbWFyeSA9XG4gICAgICAgICAgcHJpbWFyeURlZmVycmVkICE9IG51bGxcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgIGtpbmQ6IGtpbmQgPT09ICdleHRlcm5hbFN0b3JlJyA/ICgnZXh0ZXJuYWxTdG9yZScgYXMgY29uc3QpIDogKCd1bmtub3duJyBhcyBjb25zdCksXG4gICAgICAgICAgICAgICAgbW9kdWxlSWQ6IHByaW1hcnlEZWZlcnJlZC5tb2R1bGVJZCxcbiAgICAgICAgICAgICAgICBpbnN0YW5jZUlkOiBwcmltYXJ5RGVmZXJyZWQuaW5zdGFuY2VJZCxcbiAgICAgICAgICAgICAgICBmaWVsZFBhdGg6IGtpbmQgPT09ICdleHRlcm5hbFN0b3JlJyA/IHByaW1hcnlEZWZlcnJlZC5tZXRhLm9yaWdpbk5hbWUgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgc3RvcmVJZDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IHVuZGVmaW5lZFxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcGVuZGluZ0V4dGVybmFsSW5wdXRzLFxuICAgICAgICAgIHBlbmRpbmdEZWZlcnJlZFdvcmssXG4gICAgICAgICAgZGVmZXJyZWRQcmltYXJ5LFxuICAgICAgICB9XG4gICAgICB9KSgpXG5cbiAgICAgIHJlc3VsdCA9IHtcbiAgICAgICAgc3RhYmxlOiBjYXB0dXJlZC5zdGFibGUsXG4gICAgICAgIC4uLihjYXB0dXJlZC5zdGFibGUgPyBudWxsIDogeyBkZWdyYWRlUmVhc29uOiBjYXB0dXJlZC5kZWdyYWRlUmVhc29uID8/ICd1bmtub3duJyB9KSxcbiAgICAgIH0gYXMgY29uc3RcbiAgICB9XG5cbiAgICBpZiAoc2hvdWxkRW1pdFRyYWNlICYmIHNjaGVkdWxlLmZvcmNlZE1hY3JvdGFzayAmJiBzY2hlZHVsZS5yZWFzb24gPT09ICdtaWNyb3Rhc2tfc3RhcnZhdGlvbicpIHtcbiAgICAgIHlpZWxkKiBEZWJ1Zy5yZWNvcmQoe1xuICAgICAgICB0eXBlOiAnd2FybjptaWNyb3Rhc2stc3RhcnZhdGlvbicsXG4gICAgICAgIG1vZHVsZUlkOiBhbmNob3I/Lm1vZHVsZUlkLFxuICAgICAgICBpbnN0YW5jZUlkOiBhbmNob3I/Lmluc3RhbmNlSWQsXG4gICAgICAgIHRpY2tTZXE6IGN1cnJlbnRUaWNrU2VxLFxuICAgICAgICBtaWNyb3Rhc2tDaGFpbkRlcHRoOiBzY2hlZHVsZS5taWNyb3Rhc2tDaGFpbkRlcHRoLFxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAoc2hvdWxkRW1pdFRyYWNlKSB7XG4gICAgICB5aWVsZCogRGVidWcucmVjb3JkKHtcbiAgICAgICAgdHlwZTogJ3RyYWNlOnRpY2snLFxuICAgICAgICBtb2R1bGVJZDogYW5jaG9yPy5tb2R1bGVJZCxcbiAgICAgICAgaW5zdGFuY2VJZDogYW5jaG9yPy5pbnN0YW5jZUlkLFxuICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgdGlja1NlcTogY3VycmVudFRpY2tTZXEsXG4gICAgICAgICAgcGhhc2U6ICdzdGFydCcsXG4gICAgICAgICAgdGltZXN0YW1wTXM6IHN0YXJ0ZWRBdE1zISxcbiAgICAgICAgICBzY2hlZHVsZSxcbiAgICAgICAgICB0cmlnZ2VyU3VtbWFyeSxcbiAgICAgICAgICBhbmNob3JzOiBhbmNob3IsXG4gICAgICAgICAgYnVkZ2V0OiB7XG4gICAgICAgICAgICBtYXhTdGVwczogY29uZmlnLm1heFN0ZXBzLFxuICAgICAgICAgICAgZWxhcHNlZE1zOiAwLFxuICAgICAgICAgICAgc3RlcHM6IDAsXG4gICAgICAgICAgICB0eG5Db3VudDogYWNjZXB0ZWRNb2R1bGVzLnNpemUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgaWYgKCFjYXB0dXJlZC5zdGFibGUgJiYgc2hvdWxkRW1pdFRyYWNlKSB7XG4gICAgICB5aWVsZCogRGVidWcucmVjb3JkKHtcbiAgICAgICAgdHlwZTogJ3RyYWNlOnRpY2snLFxuICAgICAgICBtb2R1bGVJZDogYW5jaG9yPy5tb2R1bGVJZCxcbiAgICAgICAgaW5zdGFuY2VJZDogYW5jaG9yPy5pbnN0YW5jZUlkLFxuICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgdGlja1NlcTogY3VycmVudFRpY2tTZXEsXG4gICAgICAgICAgcGhhc2U6ICdidWRnZXRFeGNlZWRlZCcsXG4gICAgICAgICAgdGltZXN0YW1wTXM6IERhdGUubm93KCksXG4gICAgICAgICAgc2NoZWR1bGUsXG4gICAgICAgICAgdHJpZ2dlclN1bW1hcnksXG4gICAgICAgICAgYW5jaG9yczogYW5jaG9yLFxuICAgICAgICAgIGJ1ZGdldDoge1xuICAgICAgICAgICAgbWF4U3RlcHM6IGNvbmZpZy5tYXhTdGVwcyxcbiAgICAgICAgICAgIGVsYXBzZWRNczogTWF0aC5tYXgoMCwgRGF0ZS5ub3coKSAtIHN0YXJ0ZWRBdE1zISksXG4gICAgICAgICAgICBzdGVwczogY29uZmlnLm1heFN0ZXBzLFxuICAgICAgICAgICAgdHhuQ291bnQ6IGFjY2VwdGVkTW9kdWxlcy5zaXplLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYmFja2xvZyxcbiAgICAgICAgICByZXN1bHQsXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgIH1cblxuICAgIC8vIFJlcXVldWUgZGVmZXJyZWQgYmFja2xvZyBiZWZvcmUgY29tbWl0dGluZyB0aGUgdGljaywgc28gdGhlIG5leHQgdGljayBjYW4gcGljayBpdCB1cC5cbiAgICBpZiAoZGVmZXJyZWREcmFpbikge1xuICAgICAgcXVldWUucmVxdWV1ZShkZWZlcnJlZERyYWluKVxuICAgIH1cblxuICAgIGNvbnN0IGNvbW1pdHRlZCA9IHN0b3JlLmNvbW1pdFRpY2soe1xuICAgICAgdGlja1NlcTogY3VycmVudFRpY2tTZXEsXG4gICAgICBhY2NlcHRlZDogYWNjZXB0ZWREcmFpbixcbiAgICB9KVxuXG4gICAgLy8gTm90aWZ5IGNoYW5nZWQgdG9waWNzIGFmdGVyIGNvbW1pdHRpbmcgdGhlIHNuYXBzaG90IHRva2VuLlxuICAgIGZvciAoY29uc3QgeyBsaXN0ZW5lcnMgfSBvZiBjb21taXR0ZWQuY2hhbmdlZFRvcGljcy52YWx1ZXMoKSkge1xuICAgICAgZm9yIChjb25zdCBsaXN0ZW5lciBvZiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBsaXN0ZW5lcigpXG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIC8vIGJlc3QtZWZmb3J0OiBuZXZlciBsZXQgYSBzdWJzY3JpYmVyIGJyZWFrIHRoZSB0aWNrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWNhcHR1cmVkLnN0YWJsZSAmJiBzaG91bGRFbWl0VHJhY2UgJiYgYmFja2xvZz8uZGVmZXJyZWRQcmltYXJ5KSB7XG4gICAgICBjb25zdCBwcmltYXJ5ID0gYmFja2xvZy5kZWZlcnJlZFByaW1hcnlcbiAgICAgIGlmIChwcmltYXJ5LmtpbmQgPT09ICdleHRlcm5hbFN0b3JlJykge1xuICAgICAgICBjb25zdCBtb2R1bGVJbnN0YW5jZUtleSA9XG4gICAgICAgICAgcHJpbWFyeS5tb2R1bGVJZCAmJiBwcmltYXJ5Lmluc3RhbmNlSWQgPyAoYCR7cHJpbWFyeS5tb2R1bGVJZH06OiR7cHJpbWFyeS5pbnN0YW5jZUlkfWAgYXMgTW9kdWxlSW5zdGFuY2VLZXkpIDogdW5kZWZpbmVkXG4gICAgICAgIGlmIChtb2R1bGVJbnN0YW5jZUtleSAmJiBzdG9yZS5nZXRNb2R1bGVTdWJzY3JpYmVyQ291bnQobW9kdWxlSW5zdGFuY2VLZXkpID4gMCkge1xuICAgICAgICAgIHlpZWxkKiBEZWJ1Zy5yZWNvcmQoe1xuICAgICAgICAgICAgdHlwZTogJ3dhcm46cHJpb3JpdHktaW52ZXJzaW9uJyxcbiAgICAgICAgICAgIG1vZHVsZUlkOiBwcmltYXJ5Lm1vZHVsZUlkLFxuICAgICAgICAgICAgaW5zdGFuY2VJZDogcHJpbWFyeS5pbnN0YW5jZUlkLFxuICAgICAgICAgICAgdGlja1NlcTogY3VycmVudFRpY2tTZXEsXG4gICAgICAgICAgICByZWFzb246ICdkZWZlcnJlZEJhY2tsb2cnLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2hvdWxkRW1pdFRyYWNlKSB7XG4gICAgICB5aWVsZCogRGVidWcucmVjb3JkKHtcbiAgICAgICAgdHlwZTogJ3RyYWNlOnRpY2snLFxuICAgICAgICBtb2R1bGVJZDogYW5jaG9yPy5tb2R1bGVJZCxcbiAgICAgICAgaW5zdGFuY2VJZDogYW5jaG9yPy5pbnN0YW5jZUlkLFxuICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgdGlja1NlcTogY3VycmVudFRpY2tTZXEsXG4gICAgICAgICAgcGhhc2U6ICdzZXR0bGVkJyxcbiAgICAgICAgICB0aW1lc3RhbXBNczogRGF0ZS5ub3coKSxcbiAgICAgICAgICBzY2hlZHVsZSxcbiAgICAgICAgICB0cmlnZ2VyU3VtbWFyeSxcbiAgICAgICAgICBhbmNob3JzOiBhbmNob3IsXG4gICAgICAgICAgYnVkZ2V0OiB7XG4gICAgICAgICAgICBtYXhTdGVwczogY29uZmlnLm1heFN0ZXBzLFxuICAgICAgICAgICAgZWxhcHNlZE1zOiBNYXRoLm1heCgwLCBEYXRlLm5vdygpIC0gc3RhcnRlZEF0TXMhKSxcbiAgICAgICAgICAgIHN0ZXBzOiBhY2NlcHRlZE1vZHVsZXMuc2l6ZSxcbiAgICAgICAgICAgIHR4bkNvdW50OiBhY2NlcHRlZE1vZHVsZXMuc2l6ZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJhY2tsb2csXG4gICAgICAgICAgcmVzdWx0LFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAodGVsZW1ldHJ5Py5vblRpY2tEZWdyYWRlZCAmJiAoc2NoZWR1bGUuZm9yY2VkTWFjcm90YXNrIHx8ICFjYXB0dXJlZC5zdGFibGUpICYmIHNob3VsZFNhbXBsZVRpY2soY3VycmVudFRpY2tTZXEsIHRlbGVtZXRyeVNhbXBsZVJhdGUpKSB7XG4gICAgICB0cnkge1xuICAgICAgICB0ZWxlbWV0cnkub25UaWNrRGVncmFkZWQoe1xuICAgICAgICAgIHRpY2tTZXE6IGN1cnJlbnRUaWNrU2VxLFxuICAgICAgICAgIHN0YWJsZTogY2FwdHVyZWQuc3RhYmxlLFxuICAgICAgICAgIGRlZ3JhZGVSZWFzb246IGNhcHR1cmVkLnN0YWJsZSA/IHVuZGVmaW5lZCA6IChjYXB0dXJlZC5kZWdyYWRlUmVhc29uID8/ICd1bmtub3duJyksXG4gICAgICAgICAgZm9yY2VkTWFjcm90YXNrOiBzY2hlZHVsZS5mb3JjZWRNYWNyb3Rhc2ssXG4gICAgICAgICAgc2NoZWR1bGVSZWFzb246IHNjaGVkdWxlLnJlYXNvbixcbiAgICAgICAgICBtaWNyb3Rhc2tDaGFpbkRlcHRoOiBzY2hlZHVsZS5taWNyb3Rhc2tDaGFpbkRlcHRoLFxuICAgICAgICAgIGRlZmVycmVkV29ya0NvdW50OiBkZWZlcnJlZERyYWluID8gZGVmZXJyZWREcmFpbi5tb2R1bGVzLnNpemUgKyBkZWZlcnJlZERyYWluLmRpcnR5VG9waWNzLnNpemUgOiAwLFxuICAgICAgICB9KVxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIGJlc3QtZWZmb3J0OiBuZXZlciBsZXQgdXNlciB0ZWxlbWV0cnkgYnJlYWsgdGhlIHRpY2tcbiAgICAgIH1cbiAgICB9XG4gICAgY29hbGVzY2VkTW9kdWxlcyA9IDBcbiAgICBjb2FsZXNjZWRUb3BpY3MgPSAwXG5cbiAgICByZXR1cm4geyBzdGFibGU6IGNhcHR1cmVkLnN0YWJsZSwgZGVncmFkZVJlYXNvbjogY2FwdHVyZWQuZGVncmFkZVJlYXNvbiB9XG4gIH0pXG5cbiAgY29uc3QgZmx1c2hOb3c6IFRpY2tTY2hlZHVsZXJbJ2ZsdXNoTm93J10gPSBmbHVzaFRpY2soeyBzdGFydGVkQXM6ICd1bmtub3duJyB9KS5waXBlKEVmZmVjdC5hc1ZvaWQpXG5cbiAgY29uc3Qgc3RvcmVUb3BpY1RvTW9kdWxlSW5zdGFuY2VLZXkgPSAodG9waWNLZXk6IHN0cmluZyk6IE1vZHVsZUluc3RhbmNlS2V5IHwgdW5kZWZpbmVkID0+IHtcbiAgICBjb25zdCBpZHggPSB0b3BpY0tleS5pbmRleE9mKCc6OnJxOicpXG4gICAgaWYgKGlkeCA+IDApIHtcbiAgICAgIHJldHVybiB0b3BpY0tleS5zbGljZSgwLCBpZHgpIGFzIE1vZHVsZUluc3RhbmNlS2V5XG4gICAgfVxuICAgIGlmICh0b3BpY0tleS5pbmNsdWRlcygnOjonKSkge1xuICAgICAgcmV0dXJuIHRvcGljS2V5IGFzIE1vZHVsZUluc3RhbmNlS2V5XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWRcbiAgfVxuXG4gIGNvbnN0IG9uU2VsZWN0b3JDaGFuZ2VkOiBUaWNrU2NoZWR1bGVyWydvblNlbGVjdG9yQ2hhbmdlZCddID0gKHsgbW9kdWxlSW5zdGFuY2VLZXksIHNlbGVjdG9ySWQsIHByaW9yaXR5IH0pID0+IHtcbiAgICBjb25zdCBjb2FsZXNjZWQgPSBxdWV1ZS5tYXJrVG9waWNEaXJ0eShtYWtlUmVhZFF1ZXJ5VG9waWNLZXkobW9kdWxlSW5zdGFuY2VLZXksIHNlbGVjdG9ySWQpLCBwcmlvcml0eSlcbiAgICBpZiAoY29hbGVzY2VkKSBjb2FsZXNjZWRUb3BpY3MgKz0gMVxuICB9XG5cbiAgY29uc3Qgb25Nb2R1bGVDb21taXQ6IFRpY2tTY2hlZHVsZXJbJ29uTW9kdWxlQ29tbWl0J10gPSAoY29tbWl0KSA9PlxuICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgIGNvbnN0IGNvYWxlc2NlZENvbW1pdCA9IHF1ZXVlLmVucXVldWVNb2R1bGVDb21taXQoY29tbWl0KVxuICAgICAgaWYgKGNvYWxlc2NlZENvbW1pdCkgY29hbGVzY2VkTW9kdWxlcyArPSAxXG4gICAgICBjb25zdCBjb2FsZXNjZWRUb3BpYyA9IHF1ZXVlLm1hcmtUb3BpY0RpcnR5KGNvbW1pdC5tb2R1bGVJbnN0YW5jZUtleSwgY29tbWl0Lm1ldGEucHJpb3JpdHkpXG4gICAgICBpZiAoY29hbGVzY2VkVG9waWMpIGNvYWxlc2NlZFRvcGljcyArPSAxXG4gICAgICB5aWVsZCogc2NoZWR1bGVUaWNrKClcbiAgICB9KVxuXG4gIHJldHVybiB7XG4gICAgZ2V0VGlja1NlcTogKCkgPT4gdGlja1NlcSxcbiAgICBvbk1vZHVsZUNvbW1pdCxcbiAgICBvblNlbGVjdG9yQ2hhbmdlZCxcbiAgICBmbHVzaE5vdyxcbiAgfVxufVxuIiwgImltcG9ydCB0eXBlIHsgU3RhdGVDb21taXRQcmlvcml0eSB9IGZyb20gJy4vbW9kdWxlLmpzJ1xuaW1wb3J0IHR5cGUgeyBNb2R1bGVJbnN0YW5jZUtleSwgUnVudGltZVN0b3JlTW9kdWxlQ29tbWl0LCBSdW50aW1lU3RvcmVQZW5kaW5nRHJhaW4sIFRvcGljS2V5IH0gZnJvbSAnLi9SdW50aW1lU3RvcmUuanMnXG5cbmV4cG9ydCBpbnRlcmZhY2UgSm9iUXVldWUge1xuICByZWFkb25seSBoYXNQZW5kaW5nOiAoKSA9PiBib29sZWFuXG4gIC8qKiBSZXR1cm5zIHRydWUgd2hlbiB0aGUgb3BlcmF0aW9uIGNvYWxlc2NlZCB3aXRoIGFuIGV4aXN0aW5nIHBlbmRpbmcgZW50cnkuICovXG4gIHJlYWRvbmx5IGVucXVldWVNb2R1bGVDb21taXQ6IChjb21taXQ6IFJ1bnRpbWVTdG9yZU1vZHVsZUNvbW1pdCkgPT4gYm9vbGVhblxuICAvKiogUmV0dXJucyB0cnVlIHdoZW4gdGhlIG9wZXJhdGlvbiBjb2FsZXNjZWQgd2l0aCBhbiBleGlzdGluZyBwZW5kaW5nIGVudHJ5LiAqL1xuICByZWFkb25seSBtYXJrVG9waWNEaXJ0eTogKHRvcGljS2V5OiBUb3BpY0tleSwgcHJpb3JpdHk6IFN0YXRlQ29tbWl0UHJpb3JpdHkpID0+IGJvb2xlYW5cbiAgcmVhZG9ubHkgZHJhaW46ICgpID0+IFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpbiB8IHVuZGVmaW5lZFxuICByZWFkb25seSByZXF1ZXVlOiAoZHJhaW46IFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpbikgPT4gdm9pZFxufVxuXG5jb25zdCBtYXhQcmlvcml0eSA9IChhOiBTdGF0ZUNvbW1pdFByaW9yaXR5LCBiOiBTdGF0ZUNvbW1pdFByaW9yaXR5KTogU3RhdGVDb21taXRQcmlvcml0eSA9PlxuICBhID09PSAnbm9ybWFsJyB8fCBiID09PSAnbm9ybWFsJyA/ICdub3JtYWwnIDogJ2xvdydcblxuZXhwb3J0IGNvbnN0IG1ha2VKb2JRdWV1ZSA9ICgpOiBKb2JRdWV1ZSA9PiB7XG4gIGxldCBwZW5kaW5nTW9kdWxlcyA9IG5ldyBNYXA8TW9kdWxlSW5zdGFuY2VLZXksIFJ1bnRpbWVTdG9yZU1vZHVsZUNvbW1pdD4oKVxuICBsZXQgcGVuZGluZ0RpcnR5VG9waWNzID0gbmV3IE1hcDxUb3BpY0tleSwgU3RhdGVDb21taXRQcmlvcml0eT4oKVxuXG4gIGNvbnN0IGhhc1BlbmRpbmcgPSAoKTogYm9vbGVhbiA9PiBwZW5kaW5nTW9kdWxlcy5zaXplID4gMCB8fCBwZW5kaW5nRGlydHlUb3BpY3Muc2l6ZSA+IDBcblxuICBjb25zdCBlbnF1ZXVlTW9kdWxlQ29tbWl0ID0gKGNvbW1pdDogUnVudGltZVN0b3JlTW9kdWxlQ29tbWl0KTogYm9vbGVhbiA9PiB7XG4gICAgY29uc3QgcHJldiA9IHBlbmRpbmdNb2R1bGVzLmdldChjb21taXQubW9kdWxlSW5zdGFuY2VLZXkpXG4gICAgaWYgKCFwcmV2KSB7XG4gICAgICBwZW5kaW5nTW9kdWxlcy5zZXQoY29tbWl0Lm1vZHVsZUluc3RhbmNlS2V5LCBjb21taXQpXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBwZW5kaW5nTW9kdWxlcy5zZXQoY29tbWl0Lm1vZHVsZUluc3RhbmNlS2V5LCB7XG4gICAgICAuLi5jb21taXQsXG4gICAgICBtZXRhOiB7XG4gICAgICAgIC4uLmNvbW1pdC5tZXRhLFxuICAgICAgICBwcmlvcml0eTogbWF4UHJpb3JpdHkocHJldi5tZXRhLnByaW9yaXR5LCBjb21taXQubWV0YS5wcmlvcml0eSksXG4gICAgICB9LFxuICAgIH0pXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIGNvbnN0IG1hcmtUb3BpY0RpcnR5ID0gKHRvcGljS2V5OiBUb3BpY0tleSwgcHJpb3JpdHk6IFN0YXRlQ29tbWl0UHJpb3JpdHkpOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBwcmV2ID0gcGVuZGluZ0RpcnR5VG9waWNzLmdldCh0b3BpY0tleSlcbiAgICBwZW5kaW5nRGlydHlUb3BpY3Muc2V0KHRvcGljS2V5LCBwcmV2ID8gbWF4UHJpb3JpdHkocHJldiwgcHJpb3JpdHkpIDogcHJpb3JpdHkpXG4gICAgcmV0dXJuIHByZXYgIT0gbnVsbFxuICB9XG5cbiAgY29uc3QgZHJhaW4gPSAoKTogUnVudGltZVN0b3JlUGVuZGluZ0RyYWluIHwgdW5kZWZpbmVkID0+IHtcbiAgICBpZiAoIWhhc1BlbmRpbmcoKSkgcmV0dXJuIHVuZGVmaW5lZFxuICAgIGNvbnN0IGRyYWluZWQ6IFJ1bnRpbWVTdG9yZVBlbmRpbmdEcmFpbiA9IHtcbiAgICAgIG1vZHVsZXM6IHBlbmRpbmdNb2R1bGVzLFxuICAgICAgZGlydHlUb3BpY3M6IHBlbmRpbmdEaXJ0eVRvcGljcyxcbiAgICB9XG4gICAgcGVuZGluZ01vZHVsZXMgPSBuZXcgTWFwKClcbiAgICBwZW5kaW5nRGlydHlUb3BpY3MgPSBuZXcgTWFwKClcbiAgICByZXR1cm4gZHJhaW5lZFxuICB9XG5cbiAgY29uc3QgcmVxdWV1ZSA9IChkcmFpbjogUnVudGltZVN0b3JlUGVuZGluZ0RyYWluKTogdm9pZCA9PiB7XG4gICAgZm9yIChjb25zdCBbLCBjb21taXRdIG9mIGRyYWluLm1vZHVsZXMpIHtcbiAgICAgIGVucXVldWVNb2R1bGVDb21taXQoY29tbWl0KVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IFtrLCBwXSBvZiBkcmFpbi5kaXJ0eVRvcGljcykge1xuICAgICAgbWFya1RvcGljRGlydHkoaywgcClcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGhhc1BlbmRpbmcsXG4gICAgZW5xdWV1ZU1vZHVsZUNvbW1pdCxcbiAgICBtYXJrVG9waWNEaXJ0eSxcbiAgICBkcmFpbixcbiAgICByZXF1ZXVlLFxuICB9XG59XG5cbiIsICJpbXBvcnQgeyBDYXVzZSwgRWZmZWN0LCBGaWJlciwgRmliZXJSZWYsIFJlZiwgU3RyZWFtIH0gZnJvbSAnZWZmZWN0J1xuaW1wb3J0ICogYXMgRGVidWcgZnJvbSAnLi9EZWJ1Z1NpbmsuanMnXG5pbXBvcnQgeyBpc0RldkVudiB9IGZyb20gJy4vZW52LmpzJ1xuaW1wb3J0IHR5cGUgKiBhcyBMb2dpYyBmcm9tICcuL0xvZ2ljTWlkZGxld2FyZS5qcydcbmltcG9ydCB0eXBlIHsgQW55TW9kdWxlU2hhcGUsIExvZ2ljRWZmZWN0IH0gZnJvbSAnLi9tb2R1bGUuanMnXG5pbXBvcnQgdHlwZSB7IFJ1bnRpbWVJbnRlcm5hbHNSZXNvbHZlZENvbmN1cnJlbmN5UG9saWN5IH0gZnJvbSAnLi9SdW50aW1lSW50ZXJuYWxzLmpzJ1xuaW1wb3J0IHR5cGUgeyBTdGF0ZVR4bk9yaWdpbiB9IGZyb20gJy4vU3RhdGVUcmFuc2FjdGlvbi5qcydcblxuLyoqXG4gKiBQcmV2ZW50cyBjYWxsaW5nIHJ1bipUYXNrIGluc2lkZSBhIFwic3luY2hyb25vdXMgdHJhbnNhY3Rpb24gZXhlY3V0aW9uIGZpYmVyXCIgKGl0IHdvdWxkIGRlYWRsb2NrIHRoZSB0eG5RdWV1ZSkuXG4gKlxuICogLSBNb2R1bGVSdW50aW1lIGxvY2FsbHkgbWFya3MgaXQgYXMgdHJ1ZSB3aGlsZSBleGVjdXRpbmcgZWFjaCB0cmFuc2FjdGlvbiAoZGlzcGF0Y2gvc291cmNlLXJlZnJlc2gvZGV2dG9vbHMvLi4uKS5cbiAqIC0gcnVuKlRhc2sgY2hlY2tzIHRoZSBmbGFnIG9uIHN0YXJ0OiB3aGVuIHRydWUsIGl0IGVtaXRzIGRpYWdub3N0aWNzIG9ubHkgaW4gZGV2L3Rlc3QgYW5kIHRoZW4gbm8tb3BzLlxuICovXG5leHBvcnQgY29uc3QgaW5TeW5jVHJhbnNhY3Rpb25GaWJlciA9IEZpYmVyUmVmLnVuc2FmZU1ha2UoZmFsc2UpXG5cbi8qKlxuICogRm9yY2Ugc291cmNlLnJlZnJlc2g6XG4gKiAtIERlZmF1bHQ6IHdoZW4gc25hcHNob3Qga2V5SGFzaCBpcyB1bmNoYW5nZWQgYW5kIGEgbm9uLWlkbGUgc25hcHNob3QgYWxyZWFkeSBleGlzdHMsIHJlZnJlc2ggU0hPVUxEIGJlIGEgbm8tb3BcbiAqICAgKGF2b2lkIHJlZHVuZGFudCBJTy93cml0ZWJhY2spLlxuICogLSBFeGNlcHRpb246IGV4cGxpY2l0IHJlZnJlc2ggKG1hbnVhbCByZWZyZXNoKSAvIGludmFsaWRhdGlvbi1kcml2ZW4gcmVmcmVzaCBuZWVkcyB0byBcInJlLWZldGNoIGV2ZW4gd2l0aCB0aGUgc2FtZSBrZXlIYXNoXCIuXG4gKlxuICogTm90ZTogdXNlIGEgRmliZXJSZWYgdG8gbG9jYWxseSBwYXNzIFwid2hldGhlciB0aGlzIHJlZnJlc2ggaXMgZm9yY2VkXCIsIGF2b2lkaW5nIGV4cGFuZGluZyB0aGUgc291cmNlIHJlZnJlc2ggaGFuZGxlciBzaWduYXR1cmUuXG4gKi9cbmV4cG9ydCBjb25zdCBmb3JjZVNvdXJjZVJlZnJlc2ggPSBGaWJlclJlZi51bnNhZmVNYWtlKGZhbHNlKVxuXG4vKipcbiAqIFN5bmNocm9ub3VzIHRyYW5zYWN0aW9uIHdpbmRvdyAocHJvY2Vzcy1sZXZlbCkgbWFya2VyOlxuICogLSBVc2VkIGFzIGEgaGFyZCBndWFyZCBpbiBcIm5vbi1FZmZlY3QgQVBJXCIgZW50cnkgcG9pbnRzIChlLmcuIFByb21pc2UvYXN5bmMgZnVuY3Rpb25zKS5cbiAqIC0gRmliZXJSZWYgY2Fubm90IHJlbGlhYmx5IHJlYWQgdGhlIFwiY3VycmVudCBmaWJlclwiIGluIHN1Y2ggZW50cnkgcG9pbnRzLCBzbyB3ZSBuZWVkIGEgc3luY2hyb25vdXMgY2FsbHN0YWNrLWxldmVsIG1hcmtlci5cbiAqXG4gKiBOb3RlOiBpZiBhIHRyYW5zYWN0aW9uIGJvZHkgaW5jb3JyZWN0bHkgY3Jvc3NlcyBhc3luYyBib3VuZGFyaWVzLCB0aGlzIG1hcmtlciB3aWxsIGJlIGhlbGQgbG9uZ2VyOyB0aGF0IGlzIGEgc2V2ZXJlIHZpb2xhdGlvbi5cbiAqL1xubGV0IGluU3luY1RyYW5zYWN0aW9uR2xvYmFsRGVwdGggPSAwXG5cbmV4cG9ydCBjb25zdCBlbnRlclN5bmNUcmFuc2FjdGlvbiA9ICgpOiB2b2lkID0+IHtcbiAgaW5TeW5jVHJhbnNhY3Rpb25HbG9iYWxEZXB0aCArPSAxXG59XG5cbmV4cG9ydCBjb25zdCBleGl0U3luY1RyYW5zYWN0aW9uID0gKCk6IHZvaWQgPT4ge1xuICBpblN5bmNUcmFuc2FjdGlvbkdsb2JhbERlcHRoID0gTWF0aC5tYXgoMCwgaW5TeW5jVHJhbnNhY3Rpb25HbG9iYWxEZXB0aCAtIDEpXG59XG5cbmV4cG9ydCBjb25zdCBpc0luU3luY1RyYW5zYWN0aW9uID0gKCk6IGJvb2xlYW4gPT4gaW5TeW5jVHJhbnNhY3Rpb25HbG9iYWxEZXB0aCA+IDBcblxuZXhwb3J0IHR5cGUgVGFza1J1bm5lck1vZGUgPVxuICB8ICd0YXNrJyAvLyBzZXF1ZW50aWFsXG4gIHwgJ3BhcmFsbGVsJ1xuICB8ICdsYXRlc3QnXG4gIHwgJ2V4aGF1c3QnXG5cbmV4cG9ydCB0eXBlIFRhc2tTdGF0dXMgPSAnaWRsZScgfCAncGVuZGluZycgfCAncnVubmluZycgfCAnc3VjY2VzcycgfCAnZmFpbHVyZScgfCAnaW50ZXJydXB0ZWQnXG5cbmV4cG9ydCBpbnRlcmZhY2UgVGFza0V4ZWN1dGlvbiB7XG4gIHJlYWRvbmx5IHRhc2tJZDogbnVtYmVyXG4gIHJlYWRvbmx5IHN0YXR1czogVGFza1N0YXR1c1xuICByZWFkb25seSBhY2NlcHRlZEF0OiBudW1iZXJcbiAgcmVhZG9ubHkgc3RhcnRlZEF0PzogbnVtYmVyXG4gIHJlYWRvbmx5IGVuZGVkQXQ/OiBudW1iZXJcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUYXNrUnVubmVyT3JpZ2lucyB7XG4gIHJlYWRvbmx5IHBlbmRpbmc/OiBTdGF0ZVR4bk9yaWdpblxuICByZWFkb25seSBzdWNjZXNzPzogU3RhdGVUeG5PcmlnaW5cbiAgcmVhZG9ubHkgZmFpbHVyZT86IFN0YXRlVHhuT3JpZ2luXG59XG5cbnR5cGUgVGFza0hhbmRsZXI8UGF5bG9hZCwgU2ggZXh0ZW5kcyBBbnlNb2R1bGVTaGFwZSwgUj4gPVxuICB8IExvZ2ljRWZmZWN0PFNoLCBSLCB2b2lkLCBuZXZlcj5cbiAgfCAoKHBheWxvYWQ6IFBheWxvYWQpID0+IExvZ2ljRWZmZWN0PFNoLCBSLCB2b2lkLCBuZXZlcj4pXG5cbnR5cGUgVGFza0VmZmVjdDxQYXlsb2FkLCBTaCBleHRlbmRzIEFueU1vZHVsZVNoYXBlLCBSLCBBLCBFPiA9XG4gIHwgTG9naWNFZmZlY3Q8U2gsIFIsIEEsIEU+XG4gIHwgKChwYXlsb2FkOiBQYXlsb2FkKSA9PiBMb2dpY0VmZmVjdDxTaCwgUiwgQSwgRT4pXG5cbmV4cG9ydCBpbnRlcmZhY2UgVGFza1J1bm5lckNvbmZpZzxQYXlsb2FkLCBTaCBleHRlbmRzIEFueU1vZHVsZVNoYXBlLCBSLCBBID0gdm9pZCwgRSA9IG5ldmVyPiB7XG4gIC8qKlxuICAgKiBPcHRpb25hbDogdHJpZ2dlciBzb3VyY2UgbmFtZSAoZS5nLiBhY3Rpb25UYWcgLyBmaWVsZFBhdGgpLCB1c2VkIGFzIHRoZSBkZWZhdWx0IHBlbmRpbmcgb3JpZ2luLm5hbWUuXG4gICAqIC0gQm91bmRBcGlSdW50aW1lIG1heSBmaWxsIHRoaXMgaW4gZm9yIG9uQWN0aW9uKFwieHh4XCIpIC8gdHJhaXRzLnNvdXJjZS5yZWZyZXNoKFwiZmllbGRcIiksIGV0Yy5cbiAgICogLSBPdGhlciBjYWxsZXJzIGFyZSBub3QgcmVxdWlyZWQgdG8gcHJvdmlkZSBpdC5cbiAgICovXG4gIHJlYWRvbmx5IHRyaWdnZXJOYW1lPzogc3RyaW5nXG5cbiAgLyoqXG4gICAqIHBlbmRpbmc6IHN5bmNocm9ub3VzIHN0YXRlIHdyaXRlcyAobG9hZGluZz10cnVlIC8gY2xlYXJpbmcgZXJyb3JzLCBldGMuKSwgYWx3YXlzIGEgc2VwYXJhdGUgdHJhbnNhY3Rpb24gZW50cnkuXG4gICAqIC0gT25seSBleGVjdXRlZCBmb3IgdGFza3MgdGhhdCBhcmUgYWNjZXB0ZWQgYW5kIGFjdHVhbGx5IHN0YXJ0ZWQgKGlnbm9yZWQgdHJpZ2dlcnMgaW4gcnVuRXhoYXVzdFRhc2sgZG8gbm90IHJ1biBwZW5kaW5nKS5cbiAgICovXG4gIHJlYWRvbmx5IHBlbmRpbmc/OiBUYXNrSGFuZGxlcjxQYXlsb2FkLCBTaCwgUj5cblxuICAvKipcbiAgICogZWZmZWN0OiByZWFsIElPIC8gYXN5bmMgd29yayAobXVzdCBydW4gb3V0c2lkZSB0aGUgdHJhbnNhY3Rpb24gd2luZG93KS5cbiAgICovXG4gIHJlYWRvbmx5IGVmZmVjdDogVGFza0VmZmVjdDxQYXlsb2FkLCBTaCwgUiwgQSwgRT5cblxuICAvKipcbiAgICogc3VjY2Vzczogc3VjY2VzcyB3cml0ZWJhY2sgKHNlcGFyYXRlIHRyYW5zYWN0aW9uIGVudHJ5KS5cbiAgICovXG4gIHJlYWRvbmx5IHN1Y2Nlc3M/OiAocmVzdWx0OiBBLCBwYXlsb2FkOiBQYXlsb2FkKSA9PiBMb2dpY0VmZmVjdDxTaCwgUiwgdm9pZCwgbmV2ZXI+XG5cbiAgLyoqXG4gICAqIGZhaWx1cmU6IGZhaWx1cmUgd3JpdGViYWNrIChzZXBhcmF0ZSB0cmFuc2FjdGlvbiBlbnRyeSkuXG4gICAqXG4gICAqIE5vdGU6IHRha2VzIGEgQ2F1c2UgdG8gcHJlc2VydmUgZGVmZWN0L2ludGVycnVwdCBzZW1hbnRpY3M7IGludGVycnVwdHMgZG8gbm90IHRyaWdnZXIgZmFpbHVyZSB3cml0ZWJhY2sgYnkgZGVmYXVsdC5cbiAgICovXG4gIHJlYWRvbmx5IGZhaWx1cmU/OiAoY2F1c2U6IENhdXNlLkNhdXNlPEU+LCBwYXlsb2FkOiBQYXlsb2FkKSA9PiBMb2dpY0VmZmVjdDxTaCwgUiwgdm9pZCwgbmV2ZXI+XG5cbiAgLyoqXG4gICAqIG9yaWdpbjogb3B0aW9uYWwgb3ZlcnJpZGUgZm9yIHRoZSB0aHJlZSB0cmFuc2FjdGlvbiBvcmlnaW5zLlxuICAgKiAtIERlZmF1bHQ6IHBlbmRpbmcua2luZD1cInRhc2s6cGVuZGluZ1wiOyBzdWNjZXNzL2ZhaWx1cmUua2luZD1cInNlcnZpY2UtY2FsbGJhY2tcIi5cbiAgICovXG4gIHJlYWRvbmx5IG9yaWdpbj86IFRhc2tSdW5uZXJPcmlnaW5zXG5cbiAgLyoqXG4gICAqIHByaW9yaXR5OiByZXNlcnZlZCBmb3IgZnV0dXJlIGRlYnVnZ2luZy9zb3J0aW5nOyBkb2VzIG5vdCBjaGFuZ2UgdHJhbnNhY3Rpb24gYm91bmRhcmllcyBvciBjb25jdXJyZW5jeSBzZW1hbnRpY3MuXG4gICAqL1xuICByZWFkb25seSBwcmlvcml0eT86IG51bWJlclxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRhc2tSdW5uZXJSdW50aW1lIHtcbiAgcmVhZG9ubHkgbW9kdWxlSWQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkgaW5zdGFuY2VJZD86IHN0cmluZ1xuICByZWFkb25seSBydW5XaXRoU3RhdGVUcmFuc2FjdGlvbjogKFxuICAgIG9yaWdpbjogU3RhdGVUeG5PcmlnaW4sXG4gICAgYm9keTogKCkgPT4gRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgYW55PixcbiAgKSA9PiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBhbnk+XG4gIHJlYWRvbmx5IHJlc29sdmVDb25jdXJyZW5jeVBvbGljeT86ICgpID0+IEVmZmVjdC5FZmZlY3Q8UnVudGltZUludGVybmFsc1Jlc29sdmVkQ29uY3VycmVuY3lQb2xpY3ksIG5ldmVyLCBhbnk+XG59XG5cbmNvbnN0IHJlc29sdmUgPSA8UGF5bG9hZCwgU2ggZXh0ZW5kcyBBbnlNb2R1bGVTaGFwZSwgUiwgQSwgRT4oXG4gIGVmZjogVGFza0VmZmVjdDxQYXlsb2FkLCBTaCwgUiwgQSwgRT4gfCBUYXNrSGFuZGxlcjxQYXlsb2FkLCBTaCwgUj4sXG4gIHBheWxvYWQ6IFBheWxvYWQsXG4pOiBhbnkgPT4gKHR5cGVvZiBlZmYgPT09ICdmdW5jdGlvbicgPyAoZWZmIGFzIGFueSkocGF5bG9hZCkgOiBlZmYpXG5cbmNvbnN0IGRlZmF1bHRPcmlnaW5zID0gKHRyaWdnZXJOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBSZXF1aXJlZDxUYXNrUnVubmVyT3JpZ2lucz4gPT4gKHtcbiAgcGVuZGluZzoge1xuICAgIGtpbmQ6ICd0YXNrOnBlbmRpbmcnLFxuICAgIG5hbWU6IHRyaWdnZXJOYW1lLFxuICB9LFxuICBzdWNjZXNzOiB7XG4gICAga2luZDogJ3NlcnZpY2UtY2FsbGJhY2snLFxuICAgIG5hbWU6ICd0YXNrOnN1Y2Nlc3MnLFxuICB9LFxuICBmYWlsdXJlOiB7XG4gICAga2luZDogJ3NlcnZpY2UtY2FsbGJhY2snLFxuICAgIG5hbWU6ICd0YXNrOmZhaWx1cmUnLFxuICB9LFxufSlcblxuZXhwb3J0IGNvbnN0IHNob3VsZE5vb3BJblN5bmNUcmFuc2FjdGlvbkZpYmVyID0gKG9wdGlvbnM6IHtcbiAgcmVhZG9ubHkgbW9kdWxlSWQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkgaW5zdGFuY2VJZD86IHN0cmluZ1xuICByZWFkb25seSBjb2RlOiBzdHJpbmdcbiAgcmVhZG9ubHkgc2V2ZXJpdHk6ICdlcnJvcicgfCAnd2FybmluZycgfCAnaW5mbydcbiAgcmVhZG9ubHkgbWVzc2FnZTogc3RyaW5nXG4gIHJlYWRvbmx5IGhpbnQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkgYWN0aW9uVGFnPzogc3RyaW5nXG4gIHJlYWRvbmx5IGtpbmQ/OiBzdHJpbmdcbn0pOiBFZmZlY3QuRWZmZWN0PGJvb2xlYW4+ID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBpblR4biA9IHlpZWxkKiBGaWJlclJlZi5nZXQoaW5TeW5jVHJhbnNhY3Rpb25GaWJlcilcbiAgICBpZiAoIWluVHhuKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgLy8gQWx3YXlzIG5vLW9wIHJlZ2FyZGxlc3Mgb2YgZW52IChvdGhlcndpc2Ugd2UgbWF5IGRlYWRsb2NrKTsgZGlhZ25vc3RpY3MgYXJlIGVtaXR0ZWQgb25seSBpbiBkZXYvdGVzdC5cbiAgICBpZiAoaXNEZXZFbnYoKSkge1xuICAgICAgeWllbGQqIERlYnVnLnJlY29yZCh7XG4gICAgICAgIHR5cGU6ICdkaWFnbm9zdGljJyxcbiAgICAgICAgbW9kdWxlSWQ6IG9wdGlvbnMubW9kdWxlSWQsXG4gICAgICAgIGluc3RhbmNlSWQ6IG9wdGlvbnMuaW5zdGFuY2VJZCxcbiAgICAgICAgY29kZTogb3B0aW9ucy5jb2RlLFxuICAgICAgICBzZXZlcml0eTogb3B0aW9ucy5zZXZlcml0eSxcbiAgICAgICAgbWVzc2FnZTogb3B0aW9ucy5tZXNzYWdlLFxuICAgICAgICBoaW50OiBvcHRpb25zLmhpbnQsXG4gICAgICAgIGFjdGlvblRhZzogb3B0aW9ucy5hY3Rpb25UYWcsXG4gICAgICAgIGtpbmQ6IG9wdGlvbnMua2luZCxcbiAgICAgIH0pXG4gICAgfVxuICAgIHJldHVybiB0cnVlXG4gIH0pXG5cbmNvbnN0IHJlc29sdmVDb25jdXJyZW5jeUxpbWl0ID0gKHJ1bnRpbWU6IFRhc2tSdW5uZXJSdW50aW1lKTogRWZmZWN0LkVmZmVjdDxudW1iZXIgfCAndW5ib3VuZGVkJywgbmV2ZXIsIGFueT4gPT5cbiAgcnVudGltZS5yZXNvbHZlQ29uY3VycmVuY3lQb2xpY3lcbiAgICA/IHJ1bnRpbWUucmVzb2x2ZUNvbmN1cnJlbmN5UG9saWN5KCkucGlwZShFZmZlY3QubWFwKChwKSA9PiBwLmNvbmN1cnJlbmN5TGltaXQpKVxuICAgIDogRWZmZWN0LnN1Y2NlZWQoMTYpXG5cbmNvbnN0IHJ1blRhc2tMaWZlY3ljbGUgPSA8UGF5bG9hZCwgU2ggZXh0ZW5kcyBBbnlNb2R1bGVTaGFwZSwgUiwgQSwgRT4oXG4gIHBheWxvYWQ6IFBheWxvYWQsXG4gIHJ1bnRpbWU6IFRhc2tSdW5uZXJSdW50aW1lLFxuICBjb25maWc6IFRhc2tSdW5uZXJDb25maWc8UGF5bG9hZCwgU2gsIFIsIEEsIEU+LFxuICBnZXRDYW5Xcml0ZUJhY2s/OiBFZmZlY3QuRWZmZWN0PGJvb2xlYW4+LFxuKTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgTG9naWMuRW52PFNoLCBSPj4gPT5cbiAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgIGNvbnN0IG5vb3AgPSB5aWVsZCogc2hvdWxkTm9vcEluU3luY1RyYW5zYWN0aW9uRmliZXIoe1xuICAgICAgbW9kdWxlSWQ6IHJ1bnRpbWUubW9kdWxlSWQsXG4gICAgICBpbnN0YW5jZUlkOiBydW50aW1lLmluc3RhbmNlSWQsXG4gICAgICBjb2RlOiAnbG9naWM6OmludmFsaWRfdXNhZ2UnLFxuICAgICAgc2V2ZXJpdHk6ICdlcnJvcicsXG4gICAgICBtZXNzYWdlOiAncnVuKlRhc2sgaXMgbm90IGFsbG93ZWQgaW5zaWRlIGEgc3luY2hyb25vdXMgU3RhdGVUcmFuc2FjdGlvbiBib2R5IChpdCBtYXkgZGVhZGxvY2sgdGhlIHR4blF1ZXVlKS4nLFxuICAgICAgaGludDpcbiAgICAgICAgJ0NhbGwgcnVuKlRhc2sgZnJvbSB0aGUgcnVuIHNlY3Rpb24gb2YgYSB3YXRjaGVyIChlLmcuICQub25BY3Rpb24vJC5vblN0YXRlLyQub24pOyAnICtcbiAgICAgICAgJ2RvIG5vdCBjYWxsIGl0IGRpcmVjdGx5IGluc2lkZSBhIHJlZHVjZXIgLyB0cmFpdC5ydW4gLyBzeW5jaHJvbm91cyB0cmFuc2FjdGlvbiBib2R5LiBGb3IgbG9uZy1saXZlZCBmbG93cywgdXNlIGEgbXVsdGktZW50cnkgcGF0dGVybiAocGVuZGluZyBcdTIxOTIgSU8gXHUyMTkyIHdyaXRlYmFjaykuJyxcbiAgICAgIGtpbmQ6ICdydW5fdGFza19pbl90cmFuc2FjdGlvbicsXG4gICAgfSlcbiAgICBpZiAobm9vcCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgZGVmYXVsdHMgPSBkZWZhdWx0T3JpZ2lucyhjb25maWcudHJpZ2dlck5hbWUpXG4gICAgY29uc3Qgb3JpZ2luczogUmVxdWlyZWQ8VGFza1J1bm5lck9yaWdpbnM+ID0ge1xuICAgICAgcGVuZGluZzogY29uZmlnLm9yaWdpbj8ucGVuZGluZyA/PyBkZWZhdWx0cy5wZW5kaW5nLFxuICAgICAgc3VjY2VzczogY29uZmlnLm9yaWdpbj8uc3VjY2VzcyA/PyBkZWZhdWx0cy5zdWNjZXNzLFxuICAgICAgZmFpbHVyZTogY29uZmlnLm9yaWdpbj8uZmFpbHVyZSA/PyBkZWZhdWx0cy5mYWlsdXJlLFxuICAgIH1cblxuICAgIC8vIDEpIHBlbmRpbmc6IHNlcGFyYXRlIHRyYW5zYWN0aW9uIGVudHJ5OyBvbmNlIHN0YXJ0ZWQgaXQgc2hvdWxkIG5vdCBiZSBpbnRlcnJ1cHRlZCBieSBydW5MYXRlc3QuXG4gICAgY29uc3QgcGVuZGluZyA9IGNvbmZpZy5wZW5kaW5nXG4gICAgaWYgKHBlbmRpbmcpIHtcbiAgICAgIHlpZWxkKiBFZmZlY3QudW5pbnRlcnJ1cHRpYmxlKFxuICAgICAgICBydW50aW1lLnJ1bldpdGhTdGF0ZVRyYW5zYWN0aW9uKG9yaWdpbnMucGVuZGluZywgKCkgPT4gRWZmZWN0LmFzVm9pZChyZXNvbHZlKHBlbmRpbmcsIHBheWxvYWQpKSksXG4gICAgICApXG4gICAgfVxuXG4gICAgLy8gMikgSU86IHJ1bnMgb3V0c2lkZSB0aGUgdHJhbnNhY3Rpb24gd2luZG93LlxuICAgIGNvbnN0IGlvID0gcmVzb2x2ZShjb25maWcuZWZmZWN0LCBwYXlsb2FkKSBhcyBFZmZlY3QuRWZmZWN0PEEsIEUsIExvZ2ljLkVudjxTaCwgUj4+XG4gICAgY29uc3QgZXhpdCA9IHlpZWxkKiBFZmZlY3QuZXhpdChpbylcblxuICAgIC8vIDMpIHdyaXRlYmFjazogdXNlIHRoZSBndWFyZCB0byBjb25maXJtIGl0J3Mgc3RpbGwgdGhlIGN1cnJlbnQgdGFzayAocnVuTGF0ZXN0VGFzaykuXG4gICAgaWYgKGdldENhbldyaXRlQmFjaykge1xuICAgICAgY29uc3Qgb2sgPSB5aWVsZCogZ2V0Q2FuV3JpdGVCYWNrXG4gICAgICBpZiAoIW9rKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChleGl0Ll90YWcgPT09ICdTdWNjZXNzJykge1xuICAgICAgY29uc3Qgc3VjY2VzcyA9IGNvbmZpZy5zdWNjZXNzXG4gICAgICBpZiAoc3VjY2Vzcykge1xuICAgICAgICB5aWVsZCogcnVudGltZS5ydW5XaXRoU3RhdGVUcmFuc2FjdGlvbihvcmlnaW5zLnN1Y2Nlc3MsICgpID0+IEVmZmVjdC5hc1ZvaWQoc3VjY2VzcyhleGl0LnZhbHVlLCBwYXlsb2FkKSkpXG4gICAgICB9XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBGYWlsdXJlOiBpbnRlcnJ1cHRpb25zIGRvIG5vdCB0cmlnZ2VyIGZhaWx1cmUgd3JpdGViYWNrIChlLmcuIHJ1bkxhdGVzdFRhc2sgY2FuY2VsbGF0aW9uLCBTY29wZSBlbmRpbmcpLlxuICAgIGNvbnN0IGNhdXNlID0gZXhpdC5jYXVzZSBhcyBDYXVzZS5DYXVzZTxFPlxuICAgIGlmIChDYXVzZS5pc0ludGVycnVwdGVkKGNhdXNlKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgZmFpbHVyZSA9IGNvbmZpZy5mYWlsdXJlXG4gICAgaWYgKGZhaWx1cmUpIHtcbiAgICAgIHlpZWxkKiBydW50aW1lLnJ1bldpdGhTdGF0ZVRyYW5zYWN0aW9uKG9yaWdpbnMuZmFpbHVyZSwgKCkgPT4gRWZmZWN0LmFzVm9pZChmYWlsdXJlKGNhdXNlLCBwYXlsb2FkKSkpXG4gICAgfVxuICB9KS5waXBlKFxuICAgIC8vIFdhdGNoZXJzIG11c3Qgbm90IGNyYXNoIGFzIGEgd2hvbGUgZHVlIHRvIGEgc2luZ2xlIHRhc2sgZmFpbHVyZTogc3dhbGxvdyBlcnJvcnMsIGJ1dCBrZWVwIHRoZW0gZGlhZ25vc2FibGUuXG4gICAgRWZmZWN0LmNhdGNoQWxsQ2F1c2UoKGNhdXNlKSA9PlxuICAgICAgRGVidWcucmVjb3JkKHtcbiAgICAgICAgdHlwZTogJ2RpYWdub3N0aWMnLFxuICAgICAgICBtb2R1bGVJZDogcnVudGltZS5tb2R1bGVJZCxcbiAgICAgICAgaW5zdGFuY2VJZDogcnVudGltZS5pbnN0YW5jZUlkLFxuICAgICAgICBjb2RlOiAndGFza19ydW5uZXI6OnVuaGFuZGxlZF9mYWlsdXJlJyxcbiAgICAgICAgc2V2ZXJpdHk6ICdlcnJvcicsXG4gICAgICAgIG1lc3NhZ2U6ICdUYXNrUnVubmVyIGVuY291bnRlcmVkIGFuIHVuaGFuZGxlZCBmYWlsdXJlIChwZW5kaW5nL0lPL3dyaXRlYmFjaykuJyxcbiAgICAgICAgaGludDogJ0FkZCBhIGZhaWx1cmUgd3JpdGViYWNrIGZvciB0aGlzIHRhc2sgb3IgaGFuZGxlIGVycm9ycyBleHBsaWNpdGx5IHVwc3RyZWFtOyBhdm9pZCBmaXJlLWFuZC1mb3JnZXQgc3dhbGxvd2luZyBlcnJvcnMuJyxcbiAgICAgICAgYWN0aW9uVGFnOiBjb25maWcudHJpZ2dlck5hbWUsXG4gICAgICAgIGtpbmQ6ICd0YXNrX3J1bm5lcl91bmhhbmRsZWRfZmFpbHVyZScsXG4gICAgICAgIHRyaWdnZXI6IHtcbiAgICAgICAgICBraW5kOiAndGFzaycsXG4gICAgICAgICAgbmFtZTogY29uZmlnLnRyaWdnZXJOYW1lLFxuICAgICAgICB9LFxuICAgICAgfSkucGlwZShFZmZlY3QuemlwUmlnaHQoRWZmZWN0LmxvZ0Vycm9yKCdUYXNrUnVubmVyIGVycm9yJywgY2F1c2UpKSksXG4gICAgKSxcbiAgKSBhcyBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBMb2dpYy5FbnY8U2gsIFI+PlxuXG4vKipcbiAqIG1ha2VUYXNrUnVubmVyXHVGRjFBXG4gKiAtIFJldXNlcyBGbG93UnVudGltZSBjb25jdXJyZW5jeSBzZW1hbnRpY3MgKHNlcXVlbnRpYWwvcGFyYWxsZWwvbGF0ZXN0L2V4aGF1c3QpLlxuICogLSBTcGxpdHMgYSBzaW5nbGUgdHJpZ2dlciBpbnRvOiBwZW5kaW5nIChzZXBhcmF0ZSB0eG4pIFx1MjE5MiBJTyBcdTIxOTIgc3VjY2Vzcy9mYWlsdXJlIChzZXBhcmF0ZSB0eG4pLlxuICovXG5leHBvcnQgY29uc3QgbWFrZVRhc2tSdW5uZXIgPSA8UGF5bG9hZCwgU2ggZXh0ZW5kcyBBbnlNb2R1bGVTaGFwZSwgUiwgQSA9IHZvaWQsIEUgPSBuZXZlcj4oXG4gIHN0cmVhbTogU3RyZWFtLlN0cmVhbTxQYXlsb2FkPixcbiAgbW9kZTogVGFza1J1bm5lck1vZGUsXG4gIHJ1bnRpbWU6IFRhc2tSdW5uZXJSdW50aW1lLFxuICBjb25maWc6IFRhc2tSdW5uZXJDb25maWc8UGF5bG9hZCwgU2gsIFIsIEEsIEU+LFxuKTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgTG9naWMuRW52PFNoLCBSPj4gPT4ge1xuICBpZiAobW9kZSA9PT0gJ2xhdGVzdCcpIHtcbiAgICByZXR1cm4gRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgY29uc3QgdGFza0lkUmVmID0geWllbGQqIFJlZi5tYWtlKDApXG4gICAgICBjb25zdCBjdXJyZW50RmliZXJSZWYgPSB5aWVsZCogUmVmLm1ha2U8RmliZXIuUnVudGltZUZpYmVyPHZvaWQsIG5ldmVyPiB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKVxuXG4gICAgICBjb25zdCBzdGFydCA9IChwYXlsb2FkOiBQYXlsb2FkKSA9PlxuICAgICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgY29uc3QgdGFza0lkID0geWllbGQqIFJlZi51cGRhdGVBbmRHZXQodGFza0lkUmVmLCAobikgPT4gbiArIDEpXG5cbiAgICAgICAgICBjb25zdCBwcmV2ID0geWllbGQqIFJlZi5nZXQoY3VycmVudEZpYmVyUmVmKVxuICAgICAgICAgIGlmIChwcmV2KSB7XG4gICAgICAgICAgICAvLyBEbyBub3Qgd2FpdCBmb3IgdGhlIG9sZCBmaWJlciB0byBmdWxseSBlbmQgKGF2b2lkIGJsb2NraW5nIG5ldyB0cmlnZ2Vycyk7IHdyaXRlYmFjayBpcyBndWFyZGVkIGJ5IHRhc2tJZC5cbiAgICAgICAgICAgIHlpZWxkKiBGaWJlci5pbnRlcnJ1cHRGb3JrKHByZXYpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgY2FuV3JpdGVCYWNrID0gUmVmLmdldCh0YXNrSWRSZWYpLnBpcGUoRWZmZWN0Lm1hcCgoY3VycmVudCkgPT4gY3VycmVudCA9PT0gdGFza0lkKSlcblxuICAgICAgICAgIGNvbnN0IGZpYmVyID0geWllbGQqIEVmZmVjdC5mb3JrKFxuICAgICAgICAgICAgcnVuVGFza0xpZmVjeWNsZTxQYXlsb2FkLCBTaCwgUiwgQSwgRT4ocGF5bG9hZCwgcnVudGltZSwgY29uZmlnLCBjYW5Xcml0ZUJhY2spLFxuICAgICAgICAgIClcblxuICAgICAgICAgIHlpZWxkKiBSZWYuc2V0KGN1cnJlbnRGaWJlclJlZiwgZmliZXIpXG4gICAgICAgIH0pXG5cbiAgICAgIHJldHVybiB5aWVsZCogU3RyZWFtLnJ1bkZvckVhY2goc3RyZWFtLCBzdGFydClcbiAgICB9KVxuICB9XG5cbiAgaWYgKG1vZGUgPT09ICdleGhhdXN0Jykge1xuICAgIHJldHVybiBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICBjb25zdCBjb25jdXJyZW5jeSA9IHlpZWxkKiByZXNvbHZlQ29uY3VycmVuY3lMaW1pdChydW50aW1lKVxuICAgICAgY29uc3QgYnVzeVJlZiA9IHlpZWxkKiBSZWYubWFrZShmYWxzZSlcblxuICAgICAgY29uc3QgbWFwcGVyID0gKHBheWxvYWQ6IFBheWxvYWQpID0+XG4gICAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICBjb25zdCBhY3F1aXJlZCA9IHlpZWxkKiBSZWYubW9kaWZ5KGJ1c3lSZWYsIChidXN5KSA9PlxuICAgICAgICAgICAgYnVzeSA/IChbZmFsc2UsIGJ1c3ldIGFzIGNvbnN0KSA6IChbdHJ1ZSwgdHJ1ZV0gYXMgY29uc3QpLFxuICAgICAgICAgIClcbiAgICAgICAgICBpZiAoIWFjcXVpcmVkKSB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgdHJpZ2dlcjogbm8gcGVuZGluZyB0cmFuc2FjdGlvbiBpcyBwcm9kdWNlZC5cbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgIH1cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgeWllbGQqIHJ1blRhc2tMaWZlY3ljbGU8UGF5bG9hZCwgU2gsIFIsIEEsIEU+KHBheWxvYWQsIHJ1bnRpbWUsIGNvbmZpZylcbiAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgeWllbGQqIFJlZi5zZXQoYnVzeVJlZiwgZmFsc2UpXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuXG4gICAgICByZXR1cm4geWllbGQqIFN0cmVhbS5ydW5EcmFpbihzdHJlYW0ucGlwZShTdHJlYW0ubWFwRWZmZWN0KG1hcHBlciwgeyBjb25jdXJyZW5jeSB9KSkpXG4gICAgfSkgYXMgRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgTG9naWMuRW52PFNoLCBSPj5cbiAgfVxuXG4gIGlmIChtb2RlID09PSAncGFyYWxsZWwnKSB7XG4gICAgcmV0dXJuIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgIGNvbnN0IGNvbmN1cnJlbmN5ID0geWllbGQqIHJlc29sdmVDb25jdXJyZW5jeUxpbWl0KHJ1bnRpbWUpXG5cbiAgICAgIHJldHVybiB5aWVsZCogU3RyZWFtLnJ1bkRyYWluKFxuICAgICAgICBzdHJlYW0ucGlwZShcbiAgICAgICAgICBTdHJlYW0ubWFwRWZmZWN0KChwYXlsb2FkKSA9PiBydW5UYXNrTGlmZWN5Y2xlPFBheWxvYWQsIFNoLCBSLCBBLCBFPihwYXlsb2FkLCBydW50aW1lLCBjb25maWcpLCB7XG4gICAgICAgICAgICBjb25jdXJyZW5jeSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKSxcbiAgICAgIClcbiAgICB9KSBhcyBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBMb2dpYy5FbnY8U2gsIFI+PlxuICB9XG5cbiAgLy8gbW9kZSA9PT0gXCJ0YXNrXCJcdUZGMDhzZXF1ZW50aWFsXHVGRjA5XG4gIHJldHVybiBTdHJlYW0ucnVuRm9yRWFjaChzdHJlYW0sIChwYXlsb2FkKSA9PlxuICAgIHJ1blRhc2tMaWZlY3ljbGU8UGF5bG9hZCwgU2gsIFIsIEEsIEU+KHBheWxvYWQsIHJ1bnRpbWUsIGNvbmZpZyksXG4gICkgYXMgRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgTG9naWMuRW52PFNoLCBSPj5cbn1cbiIsICJpbXBvcnQgeyBDb250ZXh0LCBFZmZlY3QsIExheWVyIH0gZnJvbSAnZWZmZWN0J1xuaW1wb3J0IHR5cGUgeyBUcmFpdENvbnZlcmdlUmVxdWVzdGVkTW9kZSB9IGZyb20gJy4uLy4uL3N0YXRlLXRyYWl0L21vZGVsLmpzJ1xuaW1wb3J0IHR5cGUgeyBSZWFkUXVlcnlTdHJpY3RHYXRlQ29uZmlnIH0gZnJvbSAnLi9SZWFkUXVlcnkuanMnXG5pbXBvcnQgeyBnZXRHbG9iYWxIb3N0U2NoZWR1bGVyLCB0eXBlIEhvc3RTY2hlZHVsZXIgfSBmcm9tICcuL0hvc3RTY2hlZHVsZXIuanMnXG5pbXBvcnQgeyBtYWtlUnVudGltZVN0b3JlLCB0eXBlIFJ1bnRpbWVTdG9yZSB9IGZyb20gJy4vUnVudGltZVN0b3JlLmpzJ1xuaW1wb3J0IHsgbWFrZVRpY2tTY2hlZHVsZXIsIHR5cGUgVGlja1NjaGVkdWxlciwgdHlwZSBUaWNrU2NoZWR1bGVyQ29uZmlnIH0gZnJvbSAnLi9UaWNrU2NoZWR1bGVyLmpzJ1xuaW1wb3J0IHsgbWFrZURlY2xhcmF0aXZlTGlua1J1bnRpbWUsIHR5cGUgRGVjbGFyYXRpdmVMaW5rUnVudGltZSB9IGZyb20gJy4vRGVjbGFyYXRpdmVMaW5rUnVudGltZS5qcydcblxuLy8gVW5pZmllZCBydW50aW1lIGVudiBkZXRlY3Rpb24sIGF2b2lkaW5nIGJ1bmRsZXJzIGlubGluaW5nIE5PREVfRU5WIGF0IGJ1aWxkIHRpbWUuXG5leHBvcnQgY29uc3QgZ2V0Tm9kZUVudiA9ICgpOiBzdHJpbmcgfCB1bmRlZmluZWQgPT4ge1xuICB0cnkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgZW52ID0gKGdsb2JhbFRoaXMgYXMgYW55KT8ucHJvY2Vzcz8uZW52XG4gICAgcmV0dXJuIHR5cGVvZiBlbnY/Lk5PREVfRU5WID09PSAnc3RyaW5nJyA/IGVudi5OT0RFX0VOViA6IHVuZGVmaW5lZFxuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGlzRGV2RW52ID0gKCk6IGJvb2xlYW4gPT4gZ2V0Tm9kZUVudigpICE9PSAncHJvZHVjdGlvbidcblxuZXhwb3J0IHR5cGUgU3RhdGVUcmFuc2FjdGlvbkluc3RydW1lbnRhdGlvbiA9ICdmdWxsJyB8ICdsaWdodCdcblxuLyoqXG4gKiBnZXREZWZhdWx0U3RhdGVUeG5JbnN0cnVtZW50YXRpb25cdUZGMUFcbiAqIC0gQ3VycmVudGx5IGNob29zZXMgZGVmYXVsdCBpbnN0cnVtZW50YXRpb24gYnkgTk9ERV9FTlY6XG4gKiAgIC0gZGV2IC8gdGVzdDogZnVsbCAoa2VlcCBwYXRjaGVzIGFuZCBzbmFwc2hvdHMgZm9yIGRlYnVnZ2luZykuXG4gKiAgIC0gcHJvZHVjdGlvbjogbGlnaHQgKGtlZXAgbWluaW1hbCBzZW1hbnRpY3MgdG8gcmVkdWNlIG92ZXJoZWFkKS5cbiAqIC0gTWF5IGV2b2x2ZSB3aXRoIGZpbmVyLWdyYWluZWQgb3ZlcnJpZGVzIGluIFJ1bnRpbWUubWFrZSAvIE1vZHVsZS5tYWtlLlxuICovXG5leHBvcnQgY29uc3QgZ2V0RGVmYXVsdFN0YXRlVHhuSW5zdHJ1bWVudGF0aW9uID0gKCk6IFN0YXRlVHJhbnNhY3Rpb25JbnN0cnVtZW50YXRpb24gPT4gKGlzRGV2RW52KCkgPyAnZnVsbCcgOiAnbGlnaHQnKVxuXG4vKipcbiAqIFJ1bnRpbWUtbGV2ZWwgU3RhdGVUcmFuc2FjdGlvbiBjb25maWcgU2VydmljZTpcbiAqIC0gUHJvdmlkZWQgYXQgdGhlIGFwcCBsYXllciBieSBMb2dpeC5SdW50aW1lLm1ha2UgLyBBcHBSdW50aW1lLm1ha2VBcHAuXG4gKiAtIE1vZHVsZVJ1bnRpbWUubWFrZSBjYW4gcmVhZCBydW50aW1lLWxldmVsIGRlZmF1bHRzIGZyb20gRW52LlxuICpcbiAqIE5vdGVzOlxuICogLSBpbnN0cnVtZW50YXRpb24gaXMgb25seSBhIHJ1bnRpbWUtbGV2ZWwgZGVmYXVsdC5cbiAqIC0gRXhwbGljaXQgaW5zdHJ1bWVudGF0aW9uIGluIE1vZHVsZUltcGwgLyBNb2R1bGVSdW50aW1lT3B0aW9ucyBoYXMgaGlnaGVyIHByaW9yaXR5LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVHJhbnNhY3Rpb25SdW50aW1lQ29uZmlnIHtcbiAgcmVhZG9ubHkgaW5zdHJ1bWVudGF0aW9uPzogU3RhdGVUcmFuc2FjdGlvbkluc3RydW1lbnRhdGlvblxuICAvKipcbiAgICogU3RhdGVUcmFpdCBkZXJpdmVkIGNvbnZlcmdlIGJ1ZGdldCAobXMpOlxuICAgKiAtIEV4Y2VlZGluZyB0aGUgYnVkZ2V0IHRyaWdnZXJzIGEgc29mdCBkZWdyYWRlIChmcmVlemUgZGVyaXZlZCBmaWVsZHMsIHByZXNlcnZlIGJhc2Ugd3JpdGVzIGFuZCAwLzEgY29tbWl0IHNlbWFudGljcykuXG4gICAqIC0gRGVmYXVsdCBpcyAyMDBtcyAoYWxpZ25lZCB3aXRoIHRoZSAwMDcgc3BlYyB0aHJlc2hvbGQpLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhaXRDb252ZXJnZUJ1ZGdldE1zPzogbnVtYmVyXG4gIC8qKlxuICAgKiBBdXRvLW1vZGUgZGVjaXNpb24gYnVkZ2V0IChtcyk6XG4gICAqIC0gT25seSB1c2VkIGR1cmluZyB0aGUgZGVjaXNpb24gcGhhc2Ugd2hlbiByZXF1ZXN0ZWRNb2RlPVwiYXV0b1wiLlxuICAgKiAtIEV4Y2VlZGluZyB0aGUgYnVkZ2V0IG11c3QgaW1tZWRpYXRlbHkgZmFsbCBiYWNrIHRvIGZ1bGwgKGFuZCByZWNvcmQgZXZpZGVuY2UpLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhaXRDb252ZXJnZURlY2lzaW9uQnVkZ2V0TXM/OiBudW1iZXJcbiAgLyoqXG4gICAqIFN0YXRlVHJhaXQgY29udmVyZ2Ugc2NoZWR1bGluZyBzdHJhdGVneTpcbiAgICogLSBmdWxsOiBmdWxsIHRvcG8gZXhlY3V0aW9uIChjdXJyZW50IGRlZmF1bHQ7IHNhZmVzdCkuXG4gICAqIC0gZGlydHk6IG1pbmltYWwgdHJpZ2dlcmluZyBiYXNlZCBvbiBkaXJ0eVBhdGhzICsgZGVwcyBpbiB0aGUgdHhuIHdpbmRvdyAocmVxdWlyZXMgYWNjdXJhdGUgZGVwcykuXG4gICAqL1xuICByZWFkb25seSB0cmFpdENvbnZlcmdlTW9kZT86IFRyYWl0Q29udmVyZ2VSZXF1ZXN0ZWRNb2RlXG4gIC8qKlxuICAgKiAwNDM6IFRyYWl0IGNvbnZlcmdlIHRpbWUtc2xpY2luZyAoZXhwbGljaXQgb3B0LWluKS4gRGlzYWJsZWQgYnkgZGVmYXVsdC5cbiAgICovXG4gIHJlYWRvbmx5IHRyYWl0Q29udmVyZ2VUaW1lU2xpY2luZz86IFRyYWl0Q29udmVyZ2VUaW1lU2xpY2luZ1BhdGNoXG4gIC8qKlxuICAgKiAwNjA6IFR4biBMYW5lcyAocHJpb3JpdHkgc2NoZWR1bGluZyBmb3IgdHJhbnNhY3Rpb24gZm9sbG93LXVwIHdvcmspLiBFbmFibGVkIGJ5IGRlZmF1bHQgc2luY2UgMDYyLlxuICAgKi9cbiAgcmVhZG9ubHkgdHhuTGFuZXM/OiBUeG5MYW5lc1BhdGNoXG4gIC8qKlxuICAgKiBSdW50aW1lLWxldmVsIHBlci1tb2R1bGUgb3ZlcnJpZGVzIChob3RmaXggcGF0aCk6XG4gICAqIC0gT25seSBhZmZlY3RzIGNvbnZlcmdlIGJlaGF2aW9yIGZvciB0aGUgc3BlY2lmaWVkIG1vZHVsZUlkLlxuICAgKiAtIExvd2VyIHByaW9yaXR5IHRoYW4gUHJvdmlkZXIgb3ZlcnJpZGVzLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhaXRDb252ZXJnZU92ZXJyaWRlc0J5TW9kdWxlSWQ/OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBTdGF0ZVRyYW5zYWN0aW9uVHJhaXRDb252ZXJnZU92ZXJyaWRlcz4+XG4gIC8qKlxuICAgKiAwNjA6IFR4biBMYW5lcyBydW50aW1lX21vZHVsZSBvdmVycmlkZXMgKGhvdGZpeCAvIGdyYWR1YWwgdHVuaW5nKS5cbiAgICogLSBPbmx5IGFmZmVjdHMgdGhlIHNwZWNpZmllZCBtb2R1bGVJZC5cbiAgICogLSBMb3dlciBwcmlvcml0eSB0aGFuIFByb3ZpZGVyIG92ZXJyaWRlcy5cbiAgICovXG4gIHJlYWRvbmx5IHR4bkxhbmVzT3ZlcnJpZGVzQnlNb2R1bGVJZD86IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIFR4bkxhbmVzUGF0Y2g+PlxufVxuXG5jbGFzcyBTdGF0ZVRyYW5zYWN0aW9uQ29uZmlnVGFnSW1wbCBleHRlbmRzIENvbnRleHQuVGFnKCdAbG9naXhqcy9jb3JlL1N0YXRlVHJhbnNhY3Rpb25SdW50aW1lQ29uZmlnJyk8XG4gIFN0YXRlVHJhbnNhY3Rpb25Db25maWdUYWdJbXBsLFxuICBTdGF0ZVRyYW5zYWN0aW9uUnVudGltZUNvbmZpZ1xuPigpIHt9XG5cbmV4cG9ydCBjb25zdCBTdGF0ZVRyYW5zYWN0aW9uQ29uZmlnVGFnID0gU3RhdGVUcmFuc2FjdGlvbkNvbmZpZ1RhZ0ltcGxcblxuZXhwb3J0IHR5cGUgUmVhZFF1ZXJ5U3RyaWN0R2F0ZVJ1bnRpbWVDb25maWcgPSBSZWFkUXVlcnlTdHJpY3RHYXRlQ29uZmlnXG5cbmNsYXNzIFJlYWRRdWVyeVN0cmljdEdhdGVDb25maWdUYWdJbXBsIGV4dGVuZHMgQ29udGV4dC5UYWcoJ0Bsb2dpeGpzL2NvcmUvUmVhZFF1ZXJ5U3RyaWN0R2F0ZVJ1bnRpbWVDb25maWcnKTxcbiAgUmVhZFF1ZXJ5U3RyaWN0R2F0ZUNvbmZpZ1RhZ0ltcGwsXG4gIFJlYWRRdWVyeVN0cmljdEdhdGVSdW50aW1lQ29uZmlnXG4+KCkge31cblxuZXhwb3J0IGNvbnN0IFJlYWRRdWVyeVN0cmljdEdhdGVDb25maWdUYWcgPSBSZWFkUXVlcnlTdHJpY3RHYXRlQ29uZmlnVGFnSW1wbFxuXG5leHBvcnQgdHlwZSBSZXBsYXlNb2RlID0gJ2xpdmUnIHwgJ3JlcGxheSdcblxuZXhwb3J0IGludGVyZmFjZSBSZXBsYXlNb2RlQ29uZmlnIHtcbiAgcmVhZG9ubHkgbW9kZTogUmVwbGF5TW9kZVxufVxuXG5jbGFzcyBSZXBsYXlNb2RlQ29uZmlnVGFnSW1wbCBleHRlbmRzIENvbnRleHQuVGFnKCdAbG9naXhqcy9jb3JlL1JlcGxheU1vZGVDb25maWcnKTxcbiAgUmVwbGF5TW9kZUNvbmZpZ1RhZ0ltcGwsXG4gIFJlcGxheU1vZGVDb25maWdcbj4oKSB7fVxuXG5leHBvcnQgY29uc3QgUmVwbGF5TW9kZUNvbmZpZ1RhZyA9IFJlcGxheU1vZGVDb25maWdUYWdJbXBsXG5cbmV4cG9ydCBjb25zdCByZXBsYXlNb2RlTGF5ZXIgPSAobW9kZTogUmVwbGF5TW9kZSk6IExheWVyLkxheWVyPFJlcGxheU1vZGVDb25maWdUYWdJbXBsLCBuZXZlciwgbmV2ZXI+ID0+XG4gIExheWVyLnN1Y2NlZWQoUmVwbGF5TW9kZUNvbmZpZ1RhZywgeyBtb2RlIH0pXG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGVUcmFuc2FjdGlvblRyYWl0Q29udmVyZ2VPdmVycmlkZXMge1xuICByZWFkb25seSB0cmFpdENvbnZlcmdlTW9kZT86IFRyYWl0Q29udmVyZ2VSZXF1ZXN0ZWRNb2RlXG4gIHJlYWRvbmx5IHRyYWl0Q29udmVyZ2VCdWRnZXRNcz86IG51bWJlclxuICByZWFkb25seSB0cmFpdENvbnZlcmdlRGVjaXNpb25CdWRnZXRNcz86IG51bWJlclxuICByZWFkb25seSB0cmFpdENvbnZlcmdlVGltZVNsaWNpbmc/OiBUcmFpdENvbnZlcmdlVGltZVNsaWNpbmdQYXRjaFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFR4bkxhbmVzUGF0Y2gge1xuICAvKipcbiAgICogZW5hYmxlZDogd2hldGhlciBUeG4gTGFuZXMgaXMgZW5hYmxlZCAoZGVmYXVsdCBvbiBzaW5jZSAwNjIpLlxuICAgKiAtIHVuZGVmaW5lZDogZGVmYXVsdCBlbmFibGVkICh3aGVuIG5vdCBleHBsaWNpdGx5IGNvbmZpZ3VyZWQpXG4gICAqIC0gZmFsc2U6IGRpc2FibGVkIChyZXR1cm5zIHRvIGJhc2VsaW5lIGJlaGF2aW9yKVxuICAgKiAtIHRydWU6IGVuYWJsZWQgKG9ubHkgYWZmZWN0cyBzY2hlZHVsaW5nIG9mIGZvbGxvdy11cCB3b3JrIG91dHNpZGUgdGhlIHRyYW5zYWN0aW9uOyB0cmFuc2FjdGlvbnMgcmVtYWluIHN5bmNocm9ub3VzKVxuICAgKi9cbiAgcmVhZG9ubHkgZW5hYmxlZD86IGJvb2xlYW5cbiAgLyoqXG4gICAqIG92ZXJyaWRlTW9kZTogcnVudGltZSB0ZW1wb3Jhcnkgb3ZlcnJpZGUgKGZvciBkZWJ1Z2dpbmcvcm9sbGJhY2svY29tcGFyaXNvbikuXG4gICAqIC0gZm9yY2VkX29mZjogZm9yY2libHkgZGlzYWJsZXMgVHhuIExhbmVzIChyZXR1cm5zIHRvIGJhc2VsaW5lIGJlaGF2aW9yKS5cbiAgICogLSBmb3JjZWRfc3luYzogZm9yY2VzIGZ1bGx5IHN5bmNocm9ub3VzIGV4ZWN1dGlvbiAoaWdub3JlcyBub24tdXJnZW50IGRlZmVycmFsIGFuZCB0aW1lLXNsaWNpbmc7IHVzZWQgZm9yIGNvbXBhcmlzb25zKS5cbiAgICpcbiAgICogTm90ZXM6XG4gICAqIC0gT3ZlcnJpZGUgcHJlY2VkZW5jZSBmb2xsb3dzIFN0YXRlVHJhbnNhY3Rpb25PdmVycmlkZXM6IHByb3ZpZGVyID4gcnVudGltZV9tb2R1bGUgPiBydW50aW1lX2RlZmF1bHQgPiBidWlsdGluLlxuICAgKiAtIE92ZXJyaWRlcyBtdXN0IGJlIGV4cGxhaW5hYmxlIGJ5IGV2aWRlbmNlIChzZWUgMDYwIExhbmVFdmlkZW5jZSByZWFzb25zKS5cbiAgICovXG4gIHJlYWRvbmx5IG92ZXJyaWRlTW9kZT86ICdmb3JjZWRfb2ZmJyB8ICdmb3JjZWRfc3luYydcbiAgLyoqIG5vbi11cmdlbnQgd29yayBsb29wIHNsaWNlIGJ1ZGdldCAobXMpLiAqL1xuICByZWFkb25seSBidWRnZXRNcz86IG51bWJlclxuICAvKiogTm9uLXVyZ2VudCBiYWNrbG9nIGNvYWxlc2Npbmcgd2luZG93IChtcykuICovXG4gIHJlYWRvbmx5IGRlYm91bmNlTXM/OiBudW1iZXJcbiAgLyoqIE1heCBsYWcgdXBwZXIgYm91bmQgKG1zKTogZXhjZWVkaW5nIGl0IHRyaWdnZXJzIGFuIGV4cGxhaW5hYmxlIHN0YXJ2YXRpb24gcHJvdGVjdGlvbiAoZm9yY2VkIGNhdGNoLXVwKS4gKi9cbiAgcmVhZG9ubHkgbWF4TGFnTXM/OiBudW1iZXJcbiAgLyoqIFdoZXRoZXIgdG8gYWxsb3cgY29hbGVzY2luZy9jYW5jZWxpbmcgaW50ZXJtZWRpYXRlIG5vbi11cmdlbnQgd29yayAobXVzdCBwcmVzZXJ2ZSBldmVudHVhbCBjb25zaXN0ZW5jeSkuICovXG4gIHJlYWRvbmx5IGFsbG93Q29hbGVzY2U/OiBib29sZWFuXG4gIC8qKlxuICAgKiBZaWVsZCBzdHJhdGVneSBmb3IgdGhlIG5vbi11cmdlbnQgd29yayBsb29wIChwcm9ncmVzc2l2ZSBlbmhhbmNlbWVudCkuXG4gICAqIC0gYmFzZWxpbmU6IHVzZXMgb25seSB0aW1lIGJ1ZGdldCArIGhhcmQgdXBwZXIgYm91bmRcbiAgICogLSBpbnB1dFBlbmRpbmc6IHdoZW4gc3VwcG9ydGVkIGJ5IGJyb3dzZXJzLCBhbHNvIGNvbnN1bHRzIGBuYXZpZ2F0b3Iuc2NoZWR1bGluZy5pc0lucHV0UGVuZGluZ2BcbiAgICovXG4gIHJlYWRvbmx5IHlpZWxkU3RyYXRlZ3k/OiAnYmFzZWxpbmUnIHwgJ2lucHV0UGVuZGluZydcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFpdENvbnZlcmdlVGltZVNsaWNpbmdQYXRjaCB7XG4gIC8qKlxuICAgKiBlbmFibGVkXHVGRjFBXG4gICAqIC0gZmFsc2UvdW5kZWZpbmVkOiBkaXNhYmxlZCAoZGVmYXVsdClcbiAgICogLSB0cnVlOiBlbmFibGVzIHRpbWUtc2xpY2luZyAob25seSBhZmZlY3RzIGNvbXB1dGVkL2xpbmsgZXhwbGljaXRseSBtYXJrZWQgYXMgZGVmZXJyZWQpXG4gICAqL1xuICByZWFkb25seSBlbmFibGVkPzogYm9vbGVhblxuICAvKipcbiAgICogZGVib3VuY2VNczogY29hbGVzY2luZyBpbnRlcnZhbCAobXMpIGZvciB0aGUgZGVmZXJyYWwgd2luZG93OyBtZXJnZXMgaGlnaC1mcmVxdWVuY3kgaW5wdXRzIGludG8gb25lIGRlZmVycmVkIGZsdXNoLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVib3VuY2VNcz86IG51bWJlclxuICAvKipcbiAgICogbWF4TGFnTXM6IG1heCBsYWcgdXBwZXIgYm91bmQgKG1zKTsgZXhjZWVkaW5nIGl0IHRyaWdnZXJzIGFuIGV4cGxhaW5hYmxlIGZvcmNlZCBmbHVzaCAoc3RhcnZhdGlvbiBwcm90ZWN0aW9uKS5cbiAgICovXG4gIHJlYWRvbmx5IG1heExhZ01zPzogbnVtYmVyXG59XG5cbi8qKlxuICogUHJvdmlkZXItc2NvcGVkIFN0YXRlVHJhbnNhY3Rpb25PdmVycmlkZXMgKGRlbHRhIG92ZXJyaWRlcyk6XG4gKiAtIFVzZWQgdG8gaW5qZWN0IG1vcmUgbG9jYWwgb3ZlcnJpZGVzIGludG8gYSBQcm92aWRlciBzdWJ0cmVlIG9uIHRvcCBvZiBpbmhlcml0ZWQgZ2xvYmFsIHJ1bnRpbWUgY29uZmlnLlxuICogLSBPdmVycmlkZSBwcmVjZWRlbmNlOiBwcm92aWRlciA+IHJ1bnRpbWVfbW9kdWxlID4gcnVudGltZV9kZWZhdWx0ID4gYnVpbHRpbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGF0ZVRyYW5zYWN0aW9uT3ZlcnJpZGVzIHtcbiAgcmVhZG9ubHkgdHJhaXRDb252ZXJnZU1vZGU/OiBUcmFpdENvbnZlcmdlUmVxdWVzdGVkTW9kZVxuICByZWFkb25seSB0cmFpdENvbnZlcmdlQnVkZ2V0TXM/OiBudW1iZXJcbiAgcmVhZG9ubHkgdHJhaXRDb252ZXJnZURlY2lzaW9uQnVkZ2V0TXM/OiBudW1iZXJcbiAgcmVhZG9ubHkgdHJhaXRDb252ZXJnZVRpbWVTbGljaW5nPzogVHJhaXRDb252ZXJnZVRpbWVTbGljaW5nUGF0Y2hcbiAgcmVhZG9ubHkgdHJhaXRDb252ZXJnZU92ZXJyaWRlc0J5TW9kdWxlSWQ/OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBTdGF0ZVRyYW5zYWN0aW9uVHJhaXRDb252ZXJnZU92ZXJyaWRlcz4+XG4gIC8qKiAwNjA6IFR4biBMYW5lcyBwcm92aWRlci1sZXZlbCBvdmVycmlkZXMgKGRlbHRhIG92ZXJyaWRlcykuICovXG4gIHJlYWRvbmx5IHR4bkxhbmVzPzogVHhuTGFuZXNQYXRjaFxuICAvKiogMDYwOiBUeG4gTGFuZXMgcHJvdmlkZXJfbW9kdWxlIG92ZXJyaWRlcyAoYnkgbW9kdWxlSWQpLiAqL1xuICByZWFkb25seSB0eG5MYW5lc092ZXJyaWRlc0J5TW9kdWxlSWQ/OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBUeG5MYW5lc1BhdGNoPj5cbn1cblxuY2xhc3MgU3RhdGVUcmFuc2FjdGlvbk92ZXJyaWRlc1RhZ0ltcGwgZXh0ZW5kcyBDb250ZXh0LlRhZygnQGxvZ2l4anMvY29yZS9TdGF0ZVRyYW5zYWN0aW9uT3ZlcnJpZGVzJyk8XG4gIFN0YXRlVHJhbnNhY3Rpb25PdmVycmlkZXNUYWdJbXBsLFxuICBTdGF0ZVRyYW5zYWN0aW9uT3ZlcnJpZGVzXG4+KCkge31cblxuZXhwb3J0IGNvbnN0IFN0YXRlVHJhbnNhY3Rpb25PdmVycmlkZXNUYWcgPSBTdGF0ZVRyYW5zYWN0aW9uT3ZlcnJpZGVzVGFnSW1wbFxuXG5leHBvcnQgdHlwZSBDb25jdXJyZW5jeUxpbWl0ID0gbnVtYmVyIHwgJ3VuYm91bmRlZCdcblxuZXhwb3J0IGludGVyZmFjZSBDb25jdXJyZW5jeVBvbGljeVBhdGNoIHtcbiAgcmVhZG9ubHkgY29uY3VycmVuY3lMaW1pdD86IENvbmN1cnJlbmN5TGltaXRcbiAgcmVhZG9ubHkgbG9zc2xlc3NCYWNrcHJlc3N1cmVDYXBhY2l0eT86IG51bWJlclxuICByZWFkb25seSBhbGxvd1VuYm91bmRlZD86IGJvb2xlYW5cbiAgcmVhZG9ubHkgcHJlc3N1cmVXYXJuaW5nVGhyZXNob2xkPzoge1xuICAgIHJlYWRvbmx5IGJhY2tsb2dDb3VudD86IG51bWJlclxuICAgIHJlYWRvbmx5IGJhY2tsb2dEdXJhdGlvbk1zPzogbnVtYmVyXG4gIH1cbiAgcmVhZG9ubHkgd2FybmluZ0Nvb2xkb3duTXM/OiBudW1iZXJcbn1cblxuLyoqXG4gKiBSdW50aW1lLWxldmVsIENvbmN1cnJlbmN5UG9saWN5OlxuICogLSBQcm92aWRlZCBhdCB0aGUgYXBwIGxheWVyIGJ5IExvZ2l4LlJ1bnRpbWUubWFrZSAvIEFwcFJ1bnRpbWUubWFrZUFwcC5cbiAqIC0gTW9kdWxlUnVudGltZSBtZXJnZXMgc291cmNlcyB2aWEgYSByZXNvbHZlciAoYnVpbHRpbi9ydW50aW1lX21vZHVsZS9wcm92aWRlciwgZXRjLikuXG4gKlxuICogTm90ZXM6XG4gKiAtIG92ZXJyaWRlc0J5TW9kdWxlSWQgaXMgdXNlZCBmb3IgcnVudGltZV9tb2R1bGUgaG90LXN3aXRjaGluZyAoaG90Zml4IC8gZ3JhZHVhbCB0dW5pbmcpIGFuZCBpcyBsb3dlciBwcmlvcml0eSB0aGFuIHByb3ZpZGVyIG92ZXJyaWRlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb25jdXJyZW5jeVBvbGljeSBleHRlbmRzIENvbmN1cnJlbmN5UG9saWN5UGF0Y2gge1xuICByZWFkb25seSBvdmVycmlkZXNCeU1vZHVsZUlkPzogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgQ29uY3VycmVuY3lQb2xpY3lQYXRjaD4+XG59XG5cbmNsYXNzIENvbmN1cnJlbmN5UG9saWN5VGFnSW1wbCBleHRlbmRzIENvbnRleHQuVGFnKCdAbG9naXhqcy9jb3JlL0NvbmN1cnJlbmN5UG9saWN5Jyk8XG4gIENvbmN1cnJlbmN5UG9saWN5VGFnSW1wbCxcbiAgQ29uY3VycmVuY3lQb2xpY3lcbj4oKSB7fVxuXG5leHBvcnQgY29uc3QgQ29uY3VycmVuY3lQb2xpY3lUYWcgPSBDb25jdXJyZW5jeVBvbGljeVRhZ0ltcGxcblxuLyoqXG4gKiBQcm92aWRlci1zY29wZWQgQ29uY3VycmVuY3lQb2xpY3lPdmVycmlkZXMgKGRlbHRhIG92ZXJyaWRlcyk6XG4gKiAtIFVzZWQgdG8gaW5qZWN0IG1vcmUgbG9jYWwgb3ZlcnJpZGVzIGludG8gYSBQcm92aWRlciBzdWJ0cmVlIG9uIHRvcCBvZiBpbmhlcml0ZWQgZ2xvYmFsIHJ1bnRpbWUgY29uZmlnLlxuICogLSBPdmVycmlkZSBwcmVjZWRlbmNlOiBwcm92aWRlciA+IHJ1bnRpbWVfbW9kdWxlID4gcnVudGltZV9kZWZhdWx0ID4gYnVpbHRpbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb25jdXJyZW5jeVBvbGljeU92ZXJyaWRlcyBleHRlbmRzIENvbmN1cnJlbmN5UG9saWN5UGF0Y2gge1xuICByZWFkb25seSBvdmVycmlkZXNCeU1vZHVsZUlkPzogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgQ29uY3VycmVuY3lQb2xpY3lQYXRjaD4+XG59XG5cbmNsYXNzIENvbmN1cnJlbmN5UG9saWN5T3ZlcnJpZGVzVGFnSW1wbCBleHRlbmRzIENvbnRleHQuVGFnKCdAbG9naXhqcy9jb3JlL0NvbmN1cnJlbmN5UG9saWN5T3ZlcnJpZGVzJyk8XG4gIENvbmN1cnJlbmN5UG9saWN5T3ZlcnJpZGVzVGFnSW1wbCxcbiAgQ29uY3VycmVuY3lQb2xpY3lPdmVycmlkZXNcbj4oKSB7fVxuXG5leHBvcnQgY29uc3QgQ29uY3VycmVuY3lQb2xpY3lPdmVycmlkZXNUYWcgPSBDb25jdXJyZW5jeVBvbGljeU92ZXJyaWRlc1RhZ0ltcGxcblxuLy8gLS0tLSAwNzM6IFRpY2tTY2hlZHVsZXIgKyBSdW50aW1lU3RvcmUgKGluamVjdGFibGUgcnVudGltZSBzZXJ2aWNlcykgLS0tLVxuXG5leHBvcnQgaW50ZXJmYWNlIFJ1bnRpbWVTdG9yZVNlcnZpY2UgZXh0ZW5kcyBSdW50aW1lU3RvcmUge31cblxuZXhwb3J0IGNsYXNzIFJ1bnRpbWVTdG9yZVRhZyBleHRlbmRzIENvbnRleHQuVGFnKCdAbG9naXhqcy9jb3JlL1J1bnRpbWVTdG9yZScpPFJ1bnRpbWVTdG9yZVRhZywgUnVudGltZVN0b3JlU2VydmljZT4oKSB7fVxuXG5leHBvcnQgY29uc3QgcnVudGltZVN0b3JlTGF5ZXI6IExheWVyLkxheWVyPGFueSwgbmV2ZXIsIG5ldmVyPiA9IExheWVyLnNjb3BlZChcbiAgUnVudGltZVN0b3JlVGFnLFxuICBFZmZlY3QuYWNxdWlyZVJlbGVhc2UoXG4gICAgRWZmZWN0LnN5bmMoKCkgPT4gbWFrZVJ1bnRpbWVTdG9yZSgpIGFzIFJ1bnRpbWVTdG9yZVNlcnZpY2UpLFxuICAgIChzdG9yZSkgPT4gRWZmZWN0LnN5bmMoKCkgPT4gc3RvcmUuZGlzcG9zZSgpKSxcbiAgKSxcbikgYXMgTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+XG5cbmV4cG9ydCBjb25zdCBydW50aW1lU3RvcmVUZXN0U3R1YkxheWVyID0gKHN0b3JlOiBSdW50aW1lU3RvcmVTZXJ2aWNlKTogTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+ID0+XG4gIExheWVyLnN1Y2NlZWQoUnVudGltZVN0b3JlVGFnLCBzdG9yZSkgYXMgTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+XG5cbmV4cG9ydCBpbnRlcmZhY2UgSG9zdFNjaGVkdWxlclNlcnZpY2UgZXh0ZW5kcyBIb3N0U2NoZWR1bGVyIHt9XG5cbmV4cG9ydCBjbGFzcyBIb3N0U2NoZWR1bGVyVGFnIGV4dGVuZHMgQ29udGV4dC5UYWcoJ0Bsb2dpeGpzL2NvcmUvSG9zdFNjaGVkdWxlcicpPFxuICBIb3N0U2NoZWR1bGVyVGFnLFxuICBIb3N0U2NoZWR1bGVyU2VydmljZVxuPigpIHt9XG5cbmV4cG9ydCBjb25zdCBob3N0U2NoZWR1bGVyTGF5ZXI6IExheWVyLkxheWVyPGFueSwgbmV2ZXIsIG5ldmVyPiA9IExheWVyLnN1Y2NlZWQoXG4gIEhvc3RTY2hlZHVsZXJUYWcsXG4gIGdldEdsb2JhbEhvc3RTY2hlZHVsZXIoKSBhcyBIb3N0U2NoZWR1bGVyU2VydmljZSxcbikgYXMgTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+XG5cbmV4cG9ydCBjb25zdCBob3N0U2NoZWR1bGVyVGVzdFN0dWJMYXllciA9IChzY2hlZHVsZXI6IEhvc3RTY2hlZHVsZXJTZXJ2aWNlKTogTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+ID0+XG4gIExheWVyLnN1Y2NlZWQoSG9zdFNjaGVkdWxlclRhZywgc2NoZWR1bGVyKSBhcyBMYXllci5MYXllcjxhbnksIG5ldmVyLCBuZXZlcj5cblxuZXhwb3J0IGludGVyZmFjZSBEZWNsYXJhdGl2ZUxpbmtSdW50aW1lU2VydmljZSBleHRlbmRzIERlY2xhcmF0aXZlTGlua1J1bnRpbWUge31cblxuZXhwb3J0IGNsYXNzIERlY2xhcmF0aXZlTGlua1J1bnRpbWVUYWcgZXh0ZW5kcyBDb250ZXh0LlRhZygnQGxvZ2l4anMvY29yZS9EZWNsYXJhdGl2ZUxpbmtSdW50aW1lJyk8XG4gIERlY2xhcmF0aXZlTGlua1J1bnRpbWVUYWcsXG4gIERlY2xhcmF0aXZlTGlua1J1bnRpbWVTZXJ2aWNlXG4+KCkge31cblxuZXhwb3J0IGNvbnN0IGRlY2xhcmF0aXZlTGlua1J1bnRpbWVMYXllcjogTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+ID0gTGF5ZXIuc3VjY2VlZChcbiAgRGVjbGFyYXRpdmVMaW5rUnVudGltZVRhZyxcbiAgbWFrZURlY2xhcmF0aXZlTGlua1J1bnRpbWUoKSBhcyBEZWNsYXJhdGl2ZUxpbmtSdW50aW1lU2VydmljZSxcbikgYXMgTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+XG5cbmV4cG9ydCBjb25zdCBkZWNsYXJhdGl2ZUxpbmtSdW50aW1lVGVzdFN0dWJMYXllciA9IChcbiAgcnVudGltZTogRGVjbGFyYXRpdmVMaW5rUnVudGltZVNlcnZpY2UsXG4pOiBMYXllci5MYXllcjxhbnksIG5ldmVyLCBuZXZlcj4gPT4gTGF5ZXIuc3VjY2VlZChEZWNsYXJhdGl2ZUxpbmtSdW50aW1lVGFnLCBydW50aW1lKSBhcyBMYXllci5MYXllcjxhbnksIG5ldmVyLCBuZXZlcj5cblxuZXhwb3J0IGludGVyZmFjZSBUaWNrU2NoZWR1bGVyU2VydmljZSBleHRlbmRzIFRpY2tTY2hlZHVsZXIge31cblxuZXhwb3J0IGNsYXNzIFRpY2tTY2hlZHVsZXJUYWcgZXh0ZW5kcyBDb250ZXh0LlRhZygnQGxvZ2l4anMvY29yZS9UaWNrU2NoZWR1bGVyJyk8VGlja1NjaGVkdWxlclRhZywgVGlja1NjaGVkdWxlclNlcnZpY2U+KCkge31cblxuZXhwb3J0IGNvbnN0IHRpY2tTY2hlZHVsZXJMYXllciA9IChjb25maWc/OiBUaWNrU2NoZWR1bGVyQ29uZmlnKTogTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+ID0+XG4gIExheWVyLmVmZmVjdChcbiAgICBUaWNrU2NoZWR1bGVyVGFnLFxuICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgIGNvbnN0IHN0b3JlID0geWllbGQqIFJ1bnRpbWVTdG9yZVRhZ1xuICAgICAgY29uc3QgZGVjbGFyYXRpdmVMaW5rUnVudGltZSA9IHlpZWxkKiBEZWNsYXJhdGl2ZUxpbmtSdW50aW1lVGFnXG4gICAgICBjb25zdCBob3N0U2NoZWR1bGVyID0geWllbGQqIEhvc3RTY2hlZHVsZXJUYWdcbiAgICAgIHJldHVybiBtYWtlVGlja1NjaGVkdWxlcih7IHJ1bnRpbWVTdG9yZTogc3RvcmUsIGRlY2xhcmF0aXZlTGlua1J1bnRpbWUsIGhvc3RTY2hlZHVsZXIsIGNvbmZpZyB9KSBhcyBUaWNrU2NoZWR1bGVyU2VydmljZVxuICAgIH0pLFxuICApIGFzIExheWVyLkxheWVyPGFueSwgbmV2ZXIsIG5ldmVyPlxuXG5leHBvcnQgY29uc3QgdGlja1NjaGVkdWxlclRlc3RTdHViTGF5ZXIgPSAoc2NoZWR1bGVyOiBUaWNrU2NoZWR1bGVyU2VydmljZSk6IExheWVyLkxheWVyPGFueSwgbmV2ZXIsIG5ldmVyPiA9PlxuICBMYXllci5zdWNjZWVkKFRpY2tTY2hlZHVsZXJUYWcsIHNjaGVkdWxlcikgYXMgTGF5ZXIuTGF5ZXI8YW55LCBuZXZlciwgbmV2ZXI+XG4iLCAiaW1wb3J0IHR5cGUgeyBTdGF0ZUNvbW1pdE1ldGEsIFN0YXRlQ29tbWl0UHJpb3JpdHkgfSBmcm9tICcuL21vZHVsZS5qcydcblxuZXhwb3J0IHR5cGUgTW9kdWxlSW5zdGFuY2VLZXkgPSBgJHtzdHJpbmd9Ojoke3N0cmluZ31gXG5leHBvcnQgdHlwZSBUb3BpY0tleSA9IHN0cmluZ1xuXG5leHBvcnQgdHlwZSBUb3BpY0tpbmQgPSAnbW9kdWxlJyB8ICdyZWFkUXVlcnknXG5cbmV4cG9ydCB0eXBlIFRvcGljSW5mbyA9XG4gIHwgeyByZWFkb25seSBraW5kOiAnbW9kdWxlJzsgcmVhZG9ubHkgbW9kdWxlSW5zdGFuY2VLZXk6IE1vZHVsZUluc3RhbmNlS2V5IH1cbiAgfCB7IHJlYWRvbmx5IGtpbmQ6ICdyZWFkUXVlcnknOyByZWFkb25seSBtb2R1bGVJbnN0YW5jZUtleTogTW9kdWxlSW5zdGFuY2VLZXk7IHJlYWRvbmx5IHNlbGVjdG9ySWQ6IHN0cmluZyB9XG5cbmV4cG9ydCBjb25zdCBtYWtlTW9kdWxlSW5zdGFuY2VLZXkgPSAobW9kdWxlSWQ6IHN0cmluZywgaW5zdGFuY2VJZDogc3RyaW5nKTogTW9kdWxlSW5zdGFuY2VLZXkgPT5cbiAgYCR7bW9kdWxlSWR9Ojoke2luc3RhbmNlSWR9YFxuXG5leHBvcnQgY29uc3QgbWFrZVJlYWRRdWVyeVRvcGljS2V5ID0gKG1vZHVsZUluc3RhbmNlS2V5OiBNb2R1bGVJbnN0YW5jZUtleSwgc2VsZWN0b3JJZDogc3RyaW5nKTogVG9waWNLZXkgPT5cbiAgYCR7bW9kdWxlSW5zdGFuY2VLZXl9OjpycToke3NlbGVjdG9ySWR9YFxuXG5leHBvcnQgY29uc3QgcGFyc2VUb3BpY0tleSA9ICh0b3BpY0tleTogc3RyaW5nKTogVG9waWNJbmZvIHwgdW5kZWZpbmVkID0+IHtcbiAgY29uc3QgaWR4ID0gdG9waWNLZXkuaW5kZXhPZignOjonKVxuICBpZiAoaWR4IDw9IDApIHJldHVybiB1bmRlZmluZWRcblxuICBjb25zdCBtb2R1bGVJZCA9IHRvcGljS2V5LnNsaWNlKDAsIGlkeClcbiAgY29uc3QgcmVzdCA9IHRvcGljS2V5LnNsaWNlKGlkeCArIDIpXG4gIGlmIChyZXN0Lmxlbmd0aCA9PT0gMCkgcmV0dXJuIHVuZGVmaW5lZFxuXG4gIGNvbnN0IGlkeDIgPSByZXN0LmluZGV4T2YoJzo6JylcbiAgaWYgKGlkeDIgPCAwKSB7XG4gICAgcmV0dXJuIHsga2luZDogJ21vZHVsZScsIG1vZHVsZUluc3RhbmNlS2V5OiBgJHttb2R1bGVJZH06OiR7cmVzdH1gIH1cbiAgfVxuXG4gIGNvbnN0IGluc3RhbmNlSWQgPSByZXN0LnNsaWNlKDAsIGlkeDIpXG4gIGNvbnN0IHN1ZmZpeCA9IHJlc3Quc2xpY2UoaWR4MiArIDIpXG4gIGlmIChzdWZmaXguc3RhcnRzV2l0aCgncnE6JykpIHtcbiAgICBjb25zdCBzZWxlY3RvcklkID0gc3VmZml4LnNsaWNlKCdycTonLmxlbmd0aClcbiAgICBpZiAoc2VsZWN0b3JJZC5sZW5ndGggPT09IDApIHJldHVybiB1bmRlZmluZWRcbiAgICByZXR1cm4ge1xuICAgICAga2luZDogJ3JlYWRRdWVyeScsXG4gICAgICBtb2R1bGVJbnN0YW5jZUtleTogYCR7bW9kdWxlSWR9Ojoke2luc3RhbmNlSWR9YCxcbiAgICAgIHNlbGVjdG9ySWQsXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsga2luZDogJ21vZHVsZScsIG1vZHVsZUluc3RhbmNlS2V5OiBgJHttb2R1bGVJZH06OiR7aW5zdGFuY2VJZH1gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBSdW50aW1lU3RvcmVNb2R1bGVDb21taXQge1xuICByZWFkb25seSBtb2R1bGVJZDogc3RyaW5nXG4gIHJlYWRvbmx5IGluc3RhbmNlSWQ6IHN0cmluZ1xuICByZWFkb25seSBtb2R1bGVJbnN0YW5jZUtleTogTW9kdWxlSW5zdGFuY2VLZXlcbiAgcmVhZG9ubHkgc3RhdGU6IHVua25vd25cbiAgcmVhZG9ubHkgbWV0YTogU3RhdGVDb21taXRNZXRhXG4gIHJlYWRvbmx5IG9wU2VxPzogbnVtYmVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVudGltZVN0b3JlUGVuZGluZ0RyYWluIHtcbiAgcmVhZG9ubHkgbW9kdWxlczogUmVhZG9ubHlNYXA8TW9kdWxlSW5zdGFuY2VLZXksIFJ1bnRpbWVTdG9yZU1vZHVsZUNvbW1pdD5cbiAgcmVhZG9ubHkgZGlydHlUb3BpY3M6IFJlYWRvbmx5TWFwPFRvcGljS2V5LCBTdGF0ZUNvbW1pdFByaW9yaXR5PlxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJ1bnRpbWVTdG9yZUNvbW1pdFJlc3VsdCB7XG4gIHJlYWRvbmx5IGNoYW5nZWRUb3BpY3M6IFJlYWRvbmx5TWFwPFRvcGljS2V5LCB7IHJlYWRvbmx5IHByaW9yaXR5OiBTdGF0ZUNvbW1pdFByaW9yaXR5OyByZWFkb25seSBsaXN0ZW5lcnM6IFJlYWRvbmx5QXJyYXk8KCkgPT4gdm9pZD4gfT5cbn1cblxuZXhwb3J0IGludGVyZmFjZSBSdW50aW1lU3RvcmUge1xuICAvLyAtLS0tIFJlYWN0LWZhY2luZyBzeW5jIHNuYXBzaG90IEFQSXMgLS0tLVxuICByZWFkb25seSBnZXRUaWNrU2VxOiAoKSA9PiBudW1iZXJcbiAgcmVhZG9ubHkgZ2V0TW9kdWxlU3RhdGU6IChtb2R1bGVJbnN0YW5jZUtleTogTW9kdWxlSW5zdGFuY2VLZXkpID0+IHVua25vd25cbiAgcmVhZG9ubHkgZ2V0VG9waWNWZXJzaW9uOiAodG9waWNLZXk6IFRvcGljS2V5KSA9PiBudW1iZXJcbiAgcmVhZG9ubHkgZ2V0VG9waWNQcmlvcml0eTogKHRvcGljS2V5OiBUb3BpY0tleSkgPT4gU3RhdGVDb21taXRQcmlvcml0eVxuICByZWFkb25seSBzdWJzY3JpYmVUb3BpYzogKHRvcGljS2V5OiBUb3BpY0tleSwgbGlzdGVuZXI6ICgpID0+IHZvaWQpID0+ICgpID0+IHZvaWRcbiAgcmVhZG9ubHkgZ2V0VG9waWNTdWJzY3JpYmVyQ291bnQ6ICh0b3BpY0tleTogVG9waWNLZXkpID0+IG51bWJlclxuICByZWFkb25seSBnZXRNb2R1bGVTdWJzY3JpYmVyQ291bnQ6IChtb2R1bGVJbnN0YW5jZUtleTogTW9kdWxlSW5zdGFuY2VLZXkpID0+IG51bWJlclxuXG4gIC8vIC0tLS0gUnVudGltZSBpbnRlZ3JhdGlvbiAtLS0tXG4gIHJlYWRvbmx5IHJlZ2lzdGVyTW9kdWxlSW5zdGFuY2U6IChhcmdzOiB7XG4gICAgcmVhZG9ubHkgbW9kdWxlSWQ6IHN0cmluZ1xuICAgIHJlYWRvbmx5IGluc3RhbmNlSWQ6IHN0cmluZ1xuICAgIHJlYWRvbmx5IG1vZHVsZUluc3RhbmNlS2V5OiBNb2R1bGVJbnN0YW5jZUtleVxuICAgIHJlYWRvbmx5IGluaXRpYWxTdGF0ZTogdW5rbm93blxuICB9KSA9PiB2b2lkXG4gIHJlYWRvbmx5IHVucmVnaXN0ZXJNb2R1bGVJbnN0YW5jZTogKG1vZHVsZUluc3RhbmNlS2V5OiBNb2R1bGVJbnN0YW5jZUtleSkgPT4gdm9pZFxuXG4gIC8vIC0tLS0gVGlja1NjaGVkdWxlciBpbnRlZ3JhdGlvbiAoaW50ZXJuYWwpIC0tLS1cbiAgcmVhZG9ubHkgY29tbWl0VGljazogKGFyZ3M6IHtcbiAgICByZWFkb25seSB0aWNrU2VxOiBudW1iZXJcbiAgICByZWFkb25seSBhY2NlcHRlZDogUnVudGltZVN0b3JlUGVuZGluZ0RyYWluXG4gIH0pID0+IFJ1bnRpbWVTdG9yZUNvbW1pdFJlc3VsdFxuXG4gIHJlYWRvbmx5IGRpc3Bvc2U6ICgpID0+IHZvaWRcbn1cblxuZXhwb3J0IGNvbnN0IG1ha2VSdW50aW1lU3RvcmUgPSAoKTogUnVudGltZVN0b3JlID0+IHtcbiAgbGV0IHRpY2tTZXEgPSAwXG5cbiAgLy8gLS0tLSBDb21taXR0ZWQgc25hcHNob3QgKHJlYWQgYnkgUmVhY3QpIC0tLS1cbiAgY29uc3QgbW9kdWxlU3RhdGVzID0gbmV3IE1hcDxNb2R1bGVJbnN0YW5jZUtleSwgdW5rbm93bj4oKVxuICBjb25zdCB0b3BpY1ZlcnNpb25zID0gbmV3IE1hcDxUb3BpY0tleSwgbnVtYmVyPigpXG4gIGNvbnN0IHRvcGljUHJpb3JpdGllcyA9IG5ldyBNYXA8VG9waWNLZXksIFN0YXRlQ29tbWl0UHJpb3JpdHk+KClcblxuICAvLyAtLS0tIFN1YnNjcmlwdGlvbnMgLS0tLVxuICBjb25zdCBsaXN0ZW5lcnNCeVRvcGljID0gbmV3IE1hcDxUb3BpY0tleSwgU2V0PCgpID0+IHZvaWQ+PigpXG4gIGNvbnN0IHN1YnNjcmliZXJDb3VudEJ5TW9kdWxlID0gbmV3IE1hcDxNb2R1bGVJbnN0YW5jZUtleSwgbnVtYmVyPigpXG5cbiAgY29uc3QgZ2V0VG9waWNWZXJzaW9uID0gKHRvcGljS2V5OiBUb3BpY0tleSk6IG51bWJlciA9PiB0b3BpY1ZlcnNpb25zLmdldCh0b3BpY0tleSkgPz8gMFxuICBjb25zdCBnZXRUb3BpY1ByaW9yaXR5ID0gKHRvcGljS2V5OiBUb3BpY0tleSk6IFN0YXRlQ29tbWl0UHJpb3JpdHkgPT4gdG9waWNQcmlvcml0aWVzLmdldCh0b3BpY0tleSkgPz8gJ25vcm1hbCdcblxuICBjb25zdCBjb21taXRUb3BpY0J1bXAgPSAodG9waWNLZXk6IFRvcGljS2V5LCBwcmlvcml0eTogU3RhdGVDb21taXRQcmlvcml0eSk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IHByZXYgPSB0b3BpY1ZlcnNpb25zLmdldCh0b3BpY0tleSkgPz8gMFxuICAgIHRvcGljVmVyc2lvbnMuc2V0KHRvcGljS2V5LCBwcmV2ICsgMSlcbiAgICB0b3BpY1ByaW9yaXRpZXMuc2V0KHRvcGljS2V5LCBwcmlvcml0eSlcbiAgfVxuXG4gIGNvbnN0IHN1YnNjcmliZVRvcGljID0gKHRvcGljS2V5OiBUb3BpY0tleSwgbGlzdGVuZXI6ICgpID0+IHZvaWQpOiAoKCkgPT4gdm9pZCkgPT4ge1xuICAgIGNvbnN0IGluZm8gPSBwYXJzZVRvcGljS2V5KHRvcGljS2V5KVxuICAgIGNvbnN0IGV4aXN0aW5nID0gbGlzdGVuZXJzQnlUb3BpYy5nZXQodG9waWNLZXkpXG4gICAgY29uc3Qgc2V0ID0gZXhpc3RpbmcgPz8gbmV3IFNldDwoKSA9PiB2b2lkPigpXG4gICAgY29uc3QgYWxyZWFkeUhhcyA9IHNldC5oYXMobGlzdGVuZXIpXG4gICAgaWYgKCFhbHJlYWR5SGFzKSB7XG4gICAgICBzZXQuYWRkKGxpc3RlbmVyKVxuICAgIH1cbiAgICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgICBsaXN0ZW5lcnNCeVRvcGljLnNldCh0b3BpY0tleSwgc2V0KVxuICAgIH1cblxuICAgIGlmICghYWxyZWFkeUhhcyAmJiBpbmZvKSB7XG4gICAgICBjb25zdCBwcmV2ID0gc3Vic2NyaWJlckNvdW50QnlNb2R1bGUuZ2V0KGluZm8ubW9kdWxlSW5zdGFuY2VLZXkpID8/IDBcbiAgICAgIHN1YnNjcmliZXJDb3VudEJ5TW9kdWxlLnNldChpbmZvLm1vZHVsZUluc3RhbmNlS2V5LCBwcmV2ICsgMSlcbiAgICB9XG5cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgY29uc3QgY3VycmVudCA9IGxpc3RlbmVyc0J5VG9waWMuZ2V0KHRvcGljS2V5KVxuICAgICAgaWYgKCFjdXJyZW50KSByZXR1cm5cbiAgICAgIGNvbnN0IGRlbGV0ZWQgPSBjdXJyZW50LmRlbGV0ZShsaXN0ZW5lcilcbiAgICAgIGlmIChkZWxldGVkICYmIGluZm8pIHtcbiAgICAgICAgY29uc3QgcHJldiA9IHN1YnNjcmliZXJDb3VudEJ5TW9kdWxlLmdldChpbmZvLm1vZHVsZUluc3RhbmNlS2V5KSA/PyAwXG4gICAgICAgIGNvbnN0IG5leHQgPSBwcmV2IC0gMVxuICAgICAgICBpZiAobmV4dCA8PSAwKSB7XG4gICAgICAgICAgc3Vic2NyaWJlckNvdW50QnlNb2R1bGUuZGVsZXRlKGluZm8ubW9kdWxlSW5zdGFuY2VLZXkpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3Vic2NyaWJlckNvdW50QnlNb2R1bGUuc2V0KGluZm8ubW9kdWxlSW5zdGFuY2VLZXksIG5leHQpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChjdXJyZW50LnNpemUgPT09IDApIHtcbiAgICAgICAgbGlzdGVuZXJzQnlUb3BpYy5kZWxldGUodG9waWNLZXkpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgZ2V0VG9waWNTdWJzY3JpYmVyQ291bnQgPSAodG9waWNLZXk6IFRvcGljS2V5KTogbnVtYmVyID0+IGxpc3RlbmVyc0J5VG9waWMuZ2V0KHRvcGljS2V5KT8uc2l6ZSA/PyAwXG4gIGNvbnN0IGdldE1vZHVsZVN1YnNjcmliZXJDb3VudCA9IChtb2R1bGVJbnN0YW5jZUtleTogTW9kdWxlSW5zdGFuY2VLZXkpOiBudW1iZXIgPT4gc3Vic2NyaWJlckNvdW50QnlNb2R1bGUuZ2V0KG1vZHVsZUluc3RhbmNlS2V5KSA/PyAwXG5cbiAgY29uc3QgcmVnaXN0ZXJNb2R1bGVJbnN0YW5jZSA9IChhcmdzOiB7XG4gICAgcmVhZG9ubHkgbW9kdWxlSWQ6IHN0cmluZ1xuICAgIHJlYWRvbmx5IGluc3RhbmNlSWQ6IHN0cmluZ1xuICAgIHJlYWRvbmx5IG1vZHVsZUluc3RhbmNlS2V5OiBNb2R1bGVJbnN0YW5jZUtleVxuICAgIHJlYWRvbmx5IGluaXRpYWxTdGF0ZTogdW5rbm93blxuICB9KTogdm9pZCA9PiB7XG4gICAgbW9kdWxlU3RhdGVzLnNldChhcmdzLm1vZHVsZUluc3RhbmNlS2V5LCBhcmdzLmluaXRpYWxTdGF0ZSlcbiAgICAvLyBFbnN1cmUgdGhlIG1vZHVsZSB0b3BpYyBleGlzdHMgd2l0aCBhIHN0YWJsZSBiYXNlbGluZSB2ZXJzaW9uL3ByaW9yaXR5LlxuICAgIGlmICghdG9waWNWZXJzaW9ucy5oYXMoYXJncy5tb2R1bGVJbnN0YW5jZUtleSkpIHtcbiAgICAgIHRvcGljVmVyc2lvbnMuc2V0KGFyZ3MubW9kdWxlSW5zdGFuY2VLZXksIDApXG4gICAgICB0b3BpY1ByaW9yaXRpZXMuc2V0KGFyZ3MubW9kdWxlSW5zdGFuY2VLZXksICdub3JtYWwnKVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHVucmVnaXN0ZXJNb2R1bGVJbnN0YW5jZSA9IChtb2R1bGVJbnN0YW5jZUtleTogTW9kdWxlSW5zdGFuY2VLZXkpOiB2b2lkID0+IHtcbiAgICBtb2R1bGVTdGF0ZXMuZGVsZXRlKG1vZHVsZUluc3RhbmNlS2V5KVxuICAgIC8vIEtlZXAgdG9waWMgdmVyc2lvbnMgYnkgZGVmYXVsdCAoaGVscHMgZGVidWdnaW5nKS4gU3Vic2NyaWJlcnMgYXJlIGV4cGVjdGVkIHRvIGRldGFjaCBvbiBtb2R1bGUgZGVzdHJveS5cbiAgfVxuXG4gIGNvbnN0IGNvbW1pdFRpY2sgPSAoYXJnczogeyByZWFkb25seSB0aWNrU2VxOiBudW1iZXI7IHJlYWRvbmx5IGFjY2VwdGVkOiBSdW50aW1lU3RvcmVQZW5kaW5nRHJhaW4gfSk6IFJ1bnRpbWVTdG9yZUNvbW1pdFJlc3VsdCA9PiB7XG4gICAgdGlja1NlcSA9IGFyZ3MudGlja1NlcVxuXG4gICAgZm9yIChjb25zdCBba2V5LCBjb21taXRdIG9mIGFyZ3MuYWNjZXB0ZWQubW9kdWxlcykge1xuICAgICAgbW9kdWxlU3RhdGVzLnNldChrZXksIGNvbW1pdC5zdGF0ZSlcbiAgICB9XG5cbiAgICBjb25zdCBjaGFuZ2VkVG9waWNzID0gbmV3IE1hcDxUb3BpY0tleSwgeyByZWFkb25seSBwcmlvcml0eTogU3RhdGVDb21taXRQcmlvcml0eTsgcmVhZG9ubHkgbGlzdGVuZXJzOiBSZWFkb25seUFycmF5PCgpID0+IHZvaWQ+IH0+KClcblxuICAgIGZvciAoY29uc3QgW3RvcGljS2V5LCBwcmlvcml0eV0gb2YgYXJncy5hY2NlcHRlZC5kaXJ0eVRvcGljcykge1xuICAgICAgY29tbWl0VG9waWNCdW1wKHRvcGljS2V5LCBwcmlvcml0eSlcbiAgICAgIGNvbnN0IGxpc3RlbmVycyA9IEFycmF5LmZyb20obGlzdGVuZXJzQnlUb3BpYy5nZXQodG9waWNLZXkpID8/IFtdKVxuICAgICAgaWYgKGxpc3RlbmVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNoYW5nZWRUb3BpY3Muc2V0KHRvcGljS2V5LCB7IHByaW9yaXR5LCBsaXN0ZW5lcnMgfSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4geyBjaGFuZ2VkVG9waWNzIH1cbiAgfVxuXG4gIGNvbnN0IGdldE1vZHVsZVN0YXRlID0gKG1vZHVsZUluc3RhbmNlS2V5OiBNb2R1bGVJbnN0YW5jZUtleSk6IHVua25vd24gPT4gbW9kdWxlU3RhdGVzLmdldChtb2R1bGVJbnN0YW5jZUtleSlcblxuICBjb25zdCBkaXNwb3NlID0gKCk6IHZvaWQgPT4ge1xuICAgIG1vZHVsZVN0YXRlcy5jbGVhcigpXG4gICAgdG9waWNWZXJzaW9ucy5jbGVhcigpXG4gICAgdG9waWNQcmlvcml0aWVzLmNsZWFyKClcbiAgICBsaXN0ZW5lcnNCeVRvcGljLmNsZWFyKClcbiAgICBzdWJzY3JpYmVyQ291bnRCeU1vZHVsZS5jbGVhcigpXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGdldFRpY2tTZXE6ICgpID0+IHRpY2tTZXEsXG4gICAgZ2V0TW9kdWxlU3RhdGUsXG4gICAgZ2V0VG9waWNWZXJzaW9uLFxuICAgIGdldFRvcGljUHJpb3JpdHksXG4gICAgc3Vic2NyaWJlVG9waWMsXG4gICAgZ2V0VG9waWNTdWJzY3JpYmVyQ291bnQsXG4gICAgZ2V0TW9kdWxlU3Vic2NyaWJlckNvdW50LFxuICAgIHJlZ2lzdGVyTW9kdWxlSW5zdGFuY2UsXG4gICAgdW5yZWdpc3Rlck1vZHVsZUluc3RhbmNlLFxuICAgIGNvbW1pdFRpY2ssXG4gICAgZGlzcG9zZSxcbiAgfVxufVxuIiwgImltcG9ydCB7IEVmZmVjdCB9IGZyb20gJ2VmZmVjdCdcbmltcG9ydCB0eXBlIHsgUmVhZFF1ZXJ5Q29tcGlsZWQgfSBmcm9tICcuL1JlYWRRdWVyeS5qcydcbmltcG9ydCB0eXBlIHsgRGVjbGFyYXRpdmVMaW5rSVIsIERlY2xhcmF0aXZlTGlua05vZGVJZCB9IGZyb20gJy4vRGVjbGFyYXRpdmVMaW5rSVIuanMnXG5pbXBvcnQgdHlwZSB7IE1vZHVsZUluc3RhbmNlS2V5LCBSdW50aW1lU3RvcmVNb2R1bGVDb21taXQgfSBmcm9tICcuL1J1bnRpbWVTdG9yZS5qcydcblxuZXhwb3J0IGludGVyZmFjZSBNb2R1bGVBc1NvdXJjZUxpbmsge1xuICByZWFkb25seSBpZDogc3RyaW5nXG4gIHJlYWRvbmx5IHNvdXJjZU1vZHVsZUluc3RhbmNlS2V5OiBNb2R1bGVJbnN0YW5jZUtleVxuICByZWFkb25seSByZWFkUXVlcnk6IFJlYWRRdWVyeUNvbXBpbGVkPGFueSwgYW55PlxuICByZWFkb25seSBjb21wdXRlVmFsdWU6IChzbmFwc2hvdDogdW5rbm93bikgPT4gdW5rbm93blxuICByZWFkb25seSBlcXVhbHNWYWx1ZTogKGE6IHVua25vd24sIGI6IHVua25vd24pID0+IGJvb2xlYW5cbiAgcmVhZG9ubHkgYXBwbHlWYWx1ZTogKG5leHQ6IHVua25vd24pID0+IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIG5ldmVyPlxufVxuXG5leHBvcnQgaW50ZXJmYWNlIERlY2xhcmF0aXZlTGlua1JlZ2lzdHJhdGlvbiB7XG4gIHJlYWRvbmx5IGxpbmtJZDogc3RyaW5nXG4gIHJlYWRvbmx5IGlyOiBEZWNsYXJhdGl2ZUxpbmtJUlxuICByZWFkb25seSByZWFkTm9kZXM6IFJlYWRvbmx5QXJyYXk8e1xuICAgIHJlYWRvbmx5IG5vZGVJZDogRGVjbGFyYXRpdmVMaW5rTm9kZUlkXG4gICAgcmVhZG9ubHkgbW9kdWxlSW5zdGFuY2VLZXk6IE1vZHVsZUluc3RhbmNlS2V5XG4gICAgcmVhZG9ubHkgcmVhZFF1ZXJ5OiBSZWFkUXVlcnlDb21waWxlZDxhbnksIGFueT5cbiAgfT5cbiAgcmVhZG9ubHkgZGlzcGF0Y2hOb2RlczogUmVhZG9ubHlBcnJheTx7XG4gICAgcmVhZG9ubHkgbm9kZUlkOiBEZWNsYXJhdGl2ZUxpbmtOb2RlSWRcbiAgICByZWFkb25seSBkaXNwYXRjaDogKHBheWxvYWQ6IHVua25vd24pID0+IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIG5ldmVyPlxuICB9PlxufVxuXG5leHBvcnQgaW50ZXJmYWNlIERlY2xhcmF0aXZlTGlua1J1bnRpbWUge1xuICByZWFkb25seSByZWdpc3Rlck1vZHVsZUFzU291cmNlTGluazogKGxpbms6IE1vZHVsZUFzU291cmNlTGluaykgPT4gKCkgPT4gdm9pZFxuICByZWFkb25seSByZWdpc3RlckRlY2xhcmF0aXZlTGluazogKGxpbms6IERlY2xhcmF0aXZlTGlua1JlZ2lzdHJhdGlvbikgPT4gKCkgPT4gdm9pZFxuICByZWFkb25seSBhcHBseUZvclNvdXJjZXM6IChhcmdzOiB7XG4gICAgcmVhZG9ubHkgdGlja1NlcTogbnVtYmVyXG4gICAgcmVhZG9ubHkgYWNjZXB0ZWRNb2R1bGVzOiBSZWFkb25seU1hcDxNb2R1bGVJbnN0YW5jZUtleSwgUnVudGltZVN0b3JlTW9kdWxlQ29tbWl0PlxuICAgIHJlYWRvbmx5IGNoYW5nZWRNb2R1bGVJbnN0YW5jZUtleXM6IFJlYWRvbmx5QXJyYXk8TW9kdWxlSW5zdGFuY2VLZXk+XG4gIH0pID0+IEVmZmVjdC5FZmZlY3Q8eyByZWFkb25seSBzY2hlZHVsZWQ6IGJvb2xlYW4gfSwgbmV2ZXIsIG5ldmVyPlxufVxuXG50eXBlIFN0b3JlZE1vZHVsZUFzU291cmNlTGluayA9IE1vZHVsZUFzU291cmNlTGluayAmIHtcbiAgaGFzVmFsdWU6IGJvb2xlYW5cbiAgbGFzdFZhbHVlOiB1bmtub3duXG59XG5cbnR5cGUgU3RvcmVkRGVjbGFyYXRpdmVMaW5rID0gRGVjbGFyYXRpdmVMaW5rUmVnaXN0cmF0aW9uICYge1xuICByZWFkb25seSByZWFkTm9kZUJ5SWQ6IFJlYWRvbmx5TWFwPHN0cmluZywgeyByZWFkb25seSBub2RlSWQ6IERlY2xhcmF0aXZlTGlua05vZGVJZDsgcmVhZG9ubHkgbW9kdWxlSW5zdGFuY2VLZXk6IE1vZHVsZUluc3RhbmNlS2V5OyByZWFkb25seSByZWFkUXVlcnk6IFJlYWRRdWVyeUNvbXBpbGVkPGFueSwgYW55PiB9PlxuICByZWFkb25seSBkaXNwYXRjaE5vZGVCeUlkOiBSZWFkb25seU1hcDxzdHJpbmcsIHsgcmVhZG9ubHkgbm9kZUlkOiBEZWNsYXJhdGl2ZUxpbmtOb2RlSWQ7IHJlYWRvbmx5IGRpc3BhdGNoOiAocGF5bG9hZDogdW5rbm93bikgPT4gRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgbmV2ZXI+IH0+XG4gIHJlYWRvbmx5IGRpc3BhdGNoVGFyZ2V0c0J5UmVhZE5vZGU6IFJlYWRvbmx5TWFwPHN0cmluZywgUmVhZG9ubHlBcnJheTxEZWNsYXJhdGl2ZUxpbmtOb2RlSWQ+PlxuICByZWFkb25seSByZWFkTm9kZVN0YXRlOiBNYXA8c3RyaW5nLCB7IGhhc1ZhbHVlOiBib29sZWFuOyBsYXN0VmFsdWU6IHVua25vd24gfT5cbn1cblxuZXhwb3J0IGNvbnN0IG1ha2VEZWNsYXJhdGl2ZUxpbmtSdW50aW1lID0gKCk6IERlY2xhcmF0aXZlTGlua1J1bnRpbWUgPT4ge1xuICBjb25zdCBtb2R1bGVBc1NvdXJjZUJ5SWQgPSBuZXcgTWFwPHN0cmluZywgU3RvcmVkTW9kdWxlQXNTb3VyY2VMaW5rPigpXG4gIGNvbnN0IG1vZHVsZUFzU291cmNlSWRzQnlTb3VyY2UgPSBuZXcgTWFwPE1vZHVsZUluc3RhbmNlS2V5LCBTZXQ8c3RyaW5nPj4oKVxuXG4gIGNvbnN0IGRlY2xhcmF0aXZlQnlJZCA9IG5ldyBNYXA8c3RyaW5nLCBTdG9yZWREZWNsYXJhdGl2ZUxpbms+KClcbiAgY29uc3QgZGVjbGFyYXRpdmVSZWFkTm9kZXNCeVNvdXJjZSA9IG5ldyBNYXA8TW9kdWxlSW5zdGFuY2VLZXksIEFycmF5PHsgcmVhZG9ubHkgbGlua0lkOiBzdHJpbmc7IHJlYWRvbmx5IG5vZGVJZDogRGVjbGFyYXRpdmVMaW5rTm9kZUlkIH0+PigpXG5cbiAgY29uc3QgcmVnaXN0ZXJNb2R1bGVBc1NvdXJjZUxpbms6IERlY2xhcmF0aXZlTGlua1J1bnRpbWVbJ3JlZ2lzdGVyTW9kdWxlQXNTb3VyY2VMaW5rJ10gPSAobGluaykgPT4ge1xuICAgIGNvbnN0IHN0b3JlZDogU3RvcmVkTW9kdWxlQXNTb3VyY2VMaW5rID0ge1xuICAgICAgLi4ubGluayxcbiAgICAgIGhhc1ZhbHVlOiBmYWxzZSxcbiAgICAgIGxhc3RWYWx1ZTogdW5kZWZpbmVkLFxuICAgIH1cblxuICAgIG1vZHVsZUFzU291cmNlQnlJZC5zZXQobGluay5pZCwgc3RvcmVkKVxuICAgIGNvbnN0IHNldCA9IG1vZHVsZUFzU291cmNlSWRzQnlTb3VyY2UuZ2V0KGxpbmsuc291cmNlTW9kdWxlSW5zdGFuY2VLZXkpID8/IG5ldyBTZXQ8c3RyaW5nPigpXG4gICAgc2V0LmFkZChsaW5rLmlkKVxuICAgIG1vZHVsZUFzU291cmNlSWRzQnlTb3VyY2Uuc2V0KGxpbmsuc291cmNlTW9kdWxlSW5zdGFuY2VLZXksIHNldClcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBtb2R1bGVBc1NvdXJjZUJ5SWQuZGVsZXRlKGxpbmsuaWQpXG4gICAgICBjb25zdCBjdXJyZW50ID0gbW9kdWxlQXNTb3VyY2VJZHNCeVNvdXJjZS5nZXQobGluay5zb3VyY2VNb2R1bGVJbnN0YW5jZUtleSlcbiAgICAgIGlmICghY3VycmVudCkgcmV0dXJuXG4gICAgICBjdXJyZW50LmRlbGV0ZShsaW5rLmlkKVxuICAgICAgaWYgKGN1cnJlbnQuc2l6ZSA9PT0gMCkge1xuICAgICAgICBtb2R1bGVBc1NvdXJjZUlkc0J5U291cmNlLmRlbGV0ZShsaW5rLnNvdXJjZU1vZHVsZUluc3RhbmNlS2V5KVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHJlZ2lzdGVyRGVjbGFyYXRpdmVMaW5rOiBEZWNsYXJhdGl2ZUxpbmtSdW50aW1lWydyZWdpc3RlckRlY2xhcmF0aXZlTGluayddID0gKGxpbmspID0+IHtcbiAgICBjb25zdCByZWFkTm9kZUJ5SWQgPSBuZXcgTWFwPHN0cmluZywgeyByZWFkb25seSBub2RlSWQ6IERlY2xhcmF0aXZlTGlua05vZGVJZDsgcmVhZG9ubHkgbW9kdWxlSW5zdGFuY2VLZXk6IE1vZHVsZUluc3RhbmNlS2V5OyByZWFkb25seSByZWFkUXVlcnk6IFJlYWRRdWVyeUNvbXBpbGVkPGFueSwgYW55PiB9PigpXG4gICAgZm9yIChjb25zdCBuIG9mIGxpbmsucmVhZE5vZGVzKSB7XG4gICAgICByZWFkTm9kZUJ5SWQuc2V0KG4ubm9kZUlkLCBuKVxuICAgIH1cblxuICAgIGNvbnN0IGRpc3BhdGNoTm9kZUJ5SWQgPSBuZXcgTWFwPFxuICAgICAgc3RyaW5nLFxuICAgICAgeyByZWFkb25seSBub2RlSWQ6IERlY2xhcmF0aXZlTGlua05vZGVJZDsgcmVhZG9ubHkgZGlzcGF0Y2g6IChwYXlsb2FkOiB1bmtub3duKSA9PiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBuZXZlcj4gfVxuICAgID4oKVxuICAgIGZvciAoY29uc3QgbiBvZiBsaW5rLmRpc3BhdGNoTm9kZXMpIHtcbiAgICAgIGRpc3BhdGNoTm9kZUJ5SWQuc2V0KG4ubm9kZUlkLCBuKVxuICAgIH1cblxuICAgIC8vIFYxIGNvbnN0cmFpbnQ6IGRpc3BhdGNoIG11c3QgaGF2ZSBhdCBtb3N0IG9uZSBpbmNvbWluZyBlZGdlLCBpbnRlcnByZXRlZCBhcyBcInBheWxvYWQgZmxvd1wiLlxuICAgIGNvbnN0IGluY29taW5nQnlEaXNwYXRjaCA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KClcbiAgICBmb3IgKGNvbnN0IGUgb2YgbGluay5pci5lZGdlcykge1xuICAgICAgY29uc3QgdG8gPSBlLnRvXG4gICAgICBjb25zdCBpc0Rpc3BhdGNoID0gZGlzcGF0Y2hOb2RlQnlJZC5oYXModG8pXG4gICAgICBpZiAoIWlzRGlzcGF0Y2gpIGNvbnRpbnVlXG4gICAgICBpbmNvbWluZ0J5RGlzcGF0Y2guc2V0KHRvLCAoaW5jb21pbmdCeURpc3BhdGNoLmdldCh0bykgPz8gMCkgKyAxKVxuICAgICAgY29uc3QgY291bnQgPSBpbmNvbWluZ0J5RGlzcGF0Y2guZ2V0KHRvKSA/PyAwXG4gICAgICBpZiAoY291bnQgPiAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgW0RlY2xhcmF0aXZlTGlua1J1bnRpbWVdIEludmFsaWQgRGVjbGFyYXRpdmVMaW5rSVI6IGRpc3BhdGNoIG5vZGUgaGFzIG11bHRpcGxlIGluY29taW5nIGVkZ2VzIChsaW5rSWQ9JHtsaW5rLmxpbmtJZH0sIG5vZGVJZD0ke3RvfSkuYCxcbiAgICAgICAgKVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGRpc3BhdGNoVGFyZ2V0c0J5UmVhZE5vZGUgPSBuZXcgTWFwPHN0cmluZywgQXJyYXk8RGVjbGFyYXRpdmVMaW5rTm9kZUlkPj4oKVxuICAgIGZvciAoY29uc3QgZSBvZiBsaW5rLmlyLmVkZ2VzKSB7XG4gICAgICBjb25zdCBmcm9tID0gZS5mcm9tXG4gICAgICBjb25zdCB0byA9IGUudG9cbiAgICAgIGlmICghcmVhZE5vZGVCeUlkLmhhcyhmcm9tKSkgY29udGludWVcbiAgICAgIGlmICghZGlzcGF0Y2hOb2RlQnlJZC5oYXModG8pKSBjb250aW51ZVxuICAgICAgY29uc3QgbGlzdCA9IGRpc3BhdGNoVGFyZ2V0c0J5UmVhZE5vZGUuZ2V0KGZyb20pID8/IFtdXG4gICAgICBsaXN0LnB1c2godG8pXG4gICAgICBkaXNwYXRjaFRhcmdldHNCeVJlYWROb2RlLnNldChmcm9tLCBsaXN0KVxuICAgIH1cblxuICAgIGNvbnN0IHN0b3JlZDogU3RvcmVkRGVjbGFyYXRpdmVMaW5rID0ge1xuICAgICAgLi4ubGluayxcbiAgICAgIHJlYWROb2RlQnlJZCxcbiAgICAgIGRpc3BhdGNoTm9kZUJ5SWQsXG4gICAgICBkaXNwYXRjaFRhcmdldHNCeVJlYWROb2RlLFxuICAgICAgcmVhZE5vZGVTdGF0ZTogbmV3IE1hcCgpLFxuICAgIH1cblxuICAgIGRlY2xhcmF0aXZlQnlJZC5zZXQobGluay5saW5rSWQsIHN0b3JlZClcblxuICAgIGZvciAoY29uc3QgbiBvZiBsaW5rLnJlYWROb2Rlcykge1xuICAgICAgY29uc3QgbGlzdCA9IGRlY2xhcmF0aXZlUmVhZE5vZGVzQnlTb3VyY2UuZ2V0KG4ubW9kdWxlSW5zdGFuY2VLZXkpID8/IFtdXG4gICAgICBsaXN0LnB1c2goeyBsaW5rSWQ6IGxpbmsubGlua0lkLCBub2RlSWQ6IG4ubm9kZUlkIH0pXG4gICAgICBkZWNsYXJhdGl2ZVJlYWROb2Rlc0J5U291cmNlLnNldChuLm1vZHVsZUluc3RhbmNlS2V5LCBsaXN0KVxuICAgIH1cblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBkZWNsYXJhdGl2ZUJ5SWQuZGVsZXRlKGxpbmsubGlua0lkKVxuICAgICAgZm9yIChjb25zdCBuIG9mIGxpbmsucmVhZE5vZGVzKSB7XG4gICAgICAgIGNvbnN0IGxpc3QgPSBkZWNsYXJhdGl2ZVJlYWROb2Rlc0J5U291cmNlLmdldChuLm1vZHVsZUluc3RhbmNlS2V5KVxuICAgICAgICBpZiAoIWxpc3QpIGNvbnRpbnVlXG4gICAgICAgIGNvbnN0IG5leHQgPSBsaXN0LmZpbHRlcigoeCkgPT4gISh4LmxpbmtJZCA9PT0gbGluay5saW5rSWQgJiYgeC5ub2RlSWQgPT09IG4ubm9kZUlkKSlcbiAgICAgICAgaWYgKG5leHQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgZGVjbGFyYXRpdmVSZWFkTm9kZXNCeVNvdXJjZS5kZWxldGUobi5tb2R1bGVJbnN0YW5jZUtleSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkZWNsYXJhdGl2ZVJlYWROb2Rlc0J5U291cmNlLnNldChuLm1vZHVsZUluc3RhbmNlS2V5LCBuZXh0KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgYXBwbHlGb3JTb3VyY2VzOiBEZWNsYXJhdGl2ZUxpbmtSdW50aW1lWydhcHBseUZvclNvdXJjZXMnXSA9IChhcmdzKSA9PlxuICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgIGxldCBzY2hlZHVsZWQgPSBmYWxzZVxuXG4gICAgICAvLyAtLS0tIE1vZHVsZS1hcy1Tb3VyY2UgZWRnZXMgKG1vZHVsZSByZWFkUXVlcnkgLT4gZXh0ZXJuYWxTdG9yZSB0cmFpdCB3cml0ZWJhY2spIC0tLS1cbiAgICAgIGZvciAoY29uc3Qgc291cmNlS2V5IG9mIGFyZ3MuY2hhbmdlZE1vZHVsZUluc3RhbmNlS2V5cykge1xuICAgICAgICBjb25zdCBpZHMgPSBtb2R1bGVBc1NvdXJjZUlkc0J5U291cmNlLmdldChzb3VyY2VLZXkpXG4gICAgICAgIGlmICghaWRzIHx8IGlkcy5zaXplID09PSAwKSBjb250aW51ZVxuICAgICAgICBjb25zdCBjb21taXQgPSBhcmdzLmFjY2VwdGVkTW9kdWxlcy5nZXQoc291cmNlS2V5KVxuICAgICAgICBpZiAoIWNvbW1pdCkgY29udGludWVcblxuICAgICAgICBmb3IgKGNvbnN0IGlkIG9mIGlkcykge1xuICAgICAgICAgIGNvbnN0IGxpbmsgPSBtb2R1bGVBc1NvdXJjZUJ5SWQuZ2V0KGlkKVxuICAgICAgICAgIGlmICghbGluaykgY29udGludWVcblxuICAgICAgICAgIGxldCBzZWxlY3RlZDogdW5rbm93blxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzZWxlY3RlZCA9IGxpbmsucmVhZFF1ZXJ5LnNlbGVjdChjb21taXQuc3RhdGUgYXMgYW55KVxuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBuZXh0VmFsdWUgPSBsaW5rLmNvbXB1dGVWYWx1ZShzZWxlY3RlZClcbiAgICAgICAgICBpZiAobGluay5oYXNWYWx1ZSAmJiBsaW5rLmVxdWFsc1ZhbHVlKGxpbmsubGFzdFZhbHVlLCBuZXh0VmFsdWUpKSB7XG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGxpbmsuaGFzVmFsdWUgPSB0cnVlXG4gICAgICAgICAgbGluay5sYXN0VmFsdWUgPSBuZXh0VmFsdWVcbiAgICAgICAgICBzY2hlZHVsZWQgPSB0cnVlXG4gICAgICAgICAgeWllbGQqIGxpbmsuYXBwbHlWYWx1ZShuZXh0VmFsdWUpXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gLS0tLSBEZWNsYXJhdGl2ZUxpbmtJUiBlZGdlcyAobW9kdWxlIHJlYWRRdWVyeSAtPiBkaXNwYXRjaCkgLS0tLVxuICAgICAgZm9yIChjb25zdCBzb3VyY2VLZXkgb2YgYXJncy5jaGFuZ2VkTW9kdWxlSW5zdGFuY2VLZXlzKSB7XG4gICAgICAgIGNvbnN0IHJlZnMgPSBkZWNsYXJhdGl2ZVJlYWROb2Rlc0J5U291cmNlLmdldChzb3VyY2VLZXkpXG4gICAgICAgIGlmICghcmVmcyB8fCByZWZzLmxlbmd0aCA9PT0gMCkgY29udGludWVcbiAgICAgICAgY29uc3QgY29tbWl0ID0gYXJncy5hY2NlcHRlZE1vZHVsZXMuZ2V0KHNvdXJjZUtleSlcbiAgICAgICAgaWYgKCFjb21taXQpIGNvbnRpbnVlXG5cbiAgICAgICAgZm9yIChjb25zdCByZWYgb2YgcmVmcykge1xuICAgICAgICAgIGNvbnN0IGxpbmsgPSBkZWNsYXJhdGl2ZUJ5SWQuZ2V0KHJlZi5saW5rSWQpXG4gICAgICAgICAgaWYgKCFsaW5rKSBjb250aW51ZVxuICAgICAgICAgIGNvbnN0IHJlYWROb2RlID0gbGluay5yZWFkTm9kZUJ5SWQuZ2V0KHJlZi5ub2RlSWQpXG4gICAgICAgICAgaWYgKCFyZWFkTm9kZSkgY29udGludWVcblxuICAgICAgICAgIGxldCB2YWx1ZTogdW5rbm93blxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHJlYWROb2RlLnJlYWRRdWVyeS5zZWxlY3QoY29tbWl0LnN0YXRlIGFzIGFueSlcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3Qgc3RhdGUgPSBsaW5rLnJlYWROb2RlU3RhdGUuZ2V0KHJlZi5ub2RlSWQpID8/IHsgaGFzVmFsdWU6IGZhbHNlLCBsYXN0VmFsdWU6IHVuZGVmaW5lZCB9XG4gICAgICAgICAgY29uc3QgY2hhbmdlZCA9ICFzdGF0ZS5oYXNWYWx1ZSB8fCAhT2JqZWN0LmlzKHN0YXRlLmxhc3RWYWx1ZSwgdmFsdWUpXG4gICAgICAgICAgaWYgKCFjaGFuZ2VkKSBjb250aW51ZVxuXG4gICAgICAgICAgc3RhdGUuaGFzVmFsdWUgPSB0cnVlXG4gICAgICAgICAgc3RhdGUubGFzdFZhbHVlID0gdmFsdWVcbiAgICAgICAgICBsaW5rLnJlYWROb2RlU3RhdGUuc2V0KHJlZi5ub2RlSWQsIHN0YXRlKVxuXG4gICAgICAgICAgY29uc3QgdGFyZ2V0cyA9IGxpbmsuZGlzcGF0Y2hUYXJnZXRzQnlSZWFkTm9kZS5nZXQocmVmLm5vZGVJZCkgPz8gW11cbiAgICAgICAgICBmb3IgKGNvbnN0IGRpc3BhdGNoTm9kZUlkIG9mIHRhcmdldHMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5vZGUgPSBsaW5rLmRpc3BhdGNoTm9kZUJ5SWQuZ2V0KGRpc3BhdGNoTm9kZUlkKVxuICAgICAgICAgICAgaWYgKCFub2RlKSBjb250aW51ZVxuICAgICAgICAgICAgc2NoZWR1bGVkID0gdHJ1ZVxuICAgICAgICAgICAgeWllbGQqIG5vZGUuZGlzcGF0Y2godmFsdWUpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IHNjaGVkdWxlZCB9IGFzIGNvbnN0XG4gICAgfSlcblxuICByZXR1cm4ge1xuICAgIHJlZ2lzdGVyTW9kdWxlQXNTb3VyY2VMaW5rLFxuICAgIHJlZ2lzdGVyRGVjbGFyYXRpdmVMaW5rLFxuICAgIGFwcGx5Rm9yU291cmNlcyxcbiAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjog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O0FBQUEsTUFFUjtBQUFBLElBQ0Y7QUFDQSx1QkFBbUI7QUFDbkIsc0JBQWtCO0FBRWxCLFdBQU8sRUFBRSxRQUFRLFNBQVMsUUFBUSxlQUFlLFNBQVMsY0FBYztBQUFBLEVBQzFFLENBQUM7QUFFRCxRQUFNLFdBQXNDLFVBQVUsRUFBRSxXQUFXLFVBQVUsQ0FBQyxFQUFFLEtBQUtILFFBQU8sTUFBTTtBQUVsRyxRQUFNLGdDQUFnQyxDQUFDLGFBQW9EO0FBQ3pGLFVBQU0sTUFBTSxTQUFTLFFBQVEsT0FBTztBQUNwQyxRQUFJLE1BQU0sR0FBRztBQUNYLGFBQU8sU0FBUyxNQUFNLEdBQUcsR0FBRztBQUFBLElBQzlCO0FBQ0EsUUFBSSxTQUFTLFNBQVMsSUFBSSxHQUFHO0FBQzNCLGFBQU87QUFBQSxJQUNUO0FBQ0EsV0FBTztBQUFBLEVBQ1Q7QUFFQSxRQUFNLG9CQUF3RCxDQUFDLEVBQUUsbUJBQW1CLFlBQVksU0FBUyxNQUFNO0FBQzdHLFVBQU0sWUFBWSxNQUFNLGVBQWUsc0JBQXNCLG1CQUFtQixVQUFVLEdBQUcsUUFBUTtBQUNyRyxRQUFJLFVBQVcsb0JBQW1CO0FBQUEsRUFDcEM7QUFFQSxRQUFNLGlCQUFrRCxDQUFDLFdBQ3ZEQSxRQUFPLElBQUksYUFBYTtBQUN0QixVQUFNLGtCQUFrQixNQUFNLG9CQUFvQixNQUFNO0FBQ3hELFFBQUksZ0JBQWlCLHFCQUFvQjtBQUN6QyxVQUFNLGlCQUFpQixNQUFNLGVBQWUsT0FBTyxtQkFBbUIsT0FBTyxLQUFLLFFBQVE7QUFDMUYsUUFBSSxlQUFnQixvQkFBbUI7QUFDdkMsV0FBTyxhQUFhO0FBQUEsRUFDdEIsQ0FBQztBQUVILFNBQU87QUFBQSxJQUNMLFlBQVksTUFBTTtBQUFBLElBQ2xCO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxFQUNGO0FBQ0Y7IiwKICAibmFtZXMiOiBbIkVmZmVjdCIsICJGaWJlclJlZiIsICJkcmFpbiIsICJFZmZlY3QiLCAiRmliZXJSZWYiLCAiRWZmZWN0IiwgImxpc3RlbmVycyIsICJFZmZlY3QiLCAiRWZmZWN0IiwgIkVmZmVjdCIsICJGaWJlclJlZiIsICJFZmZlY3QiLCAiRWZmZWN0IiwgIm1heFByaW9yaXR5IiwgIkZpYmVyUmVmIiwgImxpc3RlbmVycyJdCn0K