@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,1634 @@
1
+ // @logix/core subpath bundles for @logix/sandbox
2
+
3
+ import {
4
+ shouldNoopInSyncTransactionFiber
5
+ } from "./chunk-LYBBX6WM.js";
6
+ import {
7
+ isDevEnv
8
+ } from "./chunk-GP37MEGJ.js";
9
+ import {
10
+ currentDiagnosticsLevel,
11
+ record,
12
+ toRuntimeDebugEventRef,
13
+ toSerializableErrorSummary
14
+ } from "./chunk-4KIYG5E4.js";
15
+ import {
16
+ makeEvidenceSink
17
+ } from "./chunk-O57OZBDR.js";
18
+ import {
19
+ projectJsonValue
20
+ } from "./chunk-RYSSJBGX.js";
21
+
22
+ // ../logix-core/src/internal/runtime/core/process/meta.ts
23
+ var PROCESS_META = /* @__PURE__ */ Symbol.for("@logix/core/processMeta");
24
+ var defineHidden = (target, key, value) => {
25
+ Object.defineProperty(target, key, {
26
+ value,
27
+ enumerable: false,
28
+ configurable: true,
29
+ writable: false
30
+ });
31
+ };
32
+ var getMeta = (effect) => effect[PROCESS_META];
33
+ var getDefinition = (effect) => getMeta(effect)?.definition;
34
+ var attachMeta = (effect, meta) => {
35
+ defineHidden(effect, PROCESS_META, meta);
36
+ return effect;
37
+ };
38
+
39
+ // ../logix-core/src/internal/runtime/core/RuntimeKernel.ts
40
+ import { Context, Effect, Option } from "../effect.js";
41
+ var RuntimeServicesRuntimeConfigTagImpl = class extends Context.Tag(
42
+ "@logix/core/RuntimeServicesRuntimeConfig"
43
+ )() {
44
+ };
45
+ var RuntimeServicesRuntimeConfigTag = RuntimeServicesRuntimeConfigTagImpl;
46
+ var RuntimeServicesProviderOverridesTagImpl = class extends Context.Tag(
47
+ "@logix/core/RuntimeServicesProviderOverrides"
48
+ )() {
49
+ };
50
+ var RuntimeServicesProviderOverridesTag = RuntimeServicesProviderOverridesTagImpl;
51
+ var RuntimeServicesInstanceOverridesTagImpl = class extends Context.Tag(
52
+ "@logix/core/RuntimeServicesInstanceOverrides"
53
+ )() {
54
+ };
55
+ var RuntimeServicesInstanceOverridesTag = RuntimeServicesInstanceOverridesTagImpl;
56
+ var ORDERED_SCOPES = [
57
+ "builtin",
58
+ "runtime_default",
59
+ "runtime_module",
60
+ "provider",
61
+ "instance"
62
+ ];
63
+ var maxScope = (a, b) => {
64
+ const ai = ORDERED_SCOPES.indexOf(a);
65
+ const bi = ORDERED_SCOPES.indexOf(b);
66
+ return ai >= bi ? a : b;
67
+ };
68
+ var isPlainRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
69
+ var normalizeOverride = (value) => {
70
+ if (!isPlainRecord(value)) return void 0;
71
+ const implIdRaw = value.implId;
72
+ const notesRaw = value.notes;
73
+ return {
74
+ implId: typeof implIdRaw === "string" && implIdRaw.length > 0 ? implIdRaw : void 0,
75
+ notes: typeof notesRaw === "string" && notesRaw.length > 0 ? notesRaw : void 0
76
+ };
77
+ };
78
+ var resolveRuntimeServicesOverrides = (args) => Effect.gen(function* () {
79
+ const runtimeConfigOpt = yield* Effect.serviceOption(
80
+ RuntimeServicesRuntimeConfigTag
81
+ );
82
+ const providerOverridesOpt = yield* Effect.serviceOption(
83
+ RuntimeServicesProviderOverridesTag
84
+ );
85
+ const instanceOverridesOpt = yield* Effect.serviceOption(
86
+ RuntimeServicesInstanceOverridesTag
87
+ );
88
+ const runtimeConfig = Option.isSome(runtimeConfigOpt) ? runtimeConfigOpt.value : void 0;
89
+ const providerOverrides = Option.isSome(providerOverridesOpt) ? providerOverridesOpt.value : void 0;
90
+ const instanceOverrides = Option.isSome(instanceOverridesOpt) ? instanceOverridesOpt.value : void 0;
91
+ const moduleId = args.moduleId;
92
+ const runtimeModule = moduleId && runtimeConfig?.servicesByModuleId ? runtimeConfig.servicesByModuleId[moduleId] : void 0;
93
+ const providerModule = moduleId && providerOverrides?.servicesByModuleId ? providerOverrides.servicesByModuleId[moduleId] : void 0;
94
+ return {
95
+ runtimeDefault: runtimeConfig?.services,
96
+ runtimeModule,
97
+ provider: providerOverrides?.services,
98
+ providerModule,
99
+ instance: instanceOverrides
100
+ };
101
+ });
102
+ var selectRuntimeService = (serviceId, impls, overrides) => {
103
+ const builtin = impls[0];
104
+ if (!builtin) {
105
+ throw new Error(`[Logix] RuntimeKernel registry missing builtin impl for: ${serviceId}`);
106
+ }
107
+ let desired;
108
+ const consider = (scope, patch) => {
109
+ const next = patch ? normalizeOverride(patch[serviceId]) : void 0;
110
+ if (!next || !next.implId) return;
111
+ desired = { scope, override: next };
112
+ };
113
+ consider("runtime_default", overrides.runtimeDefault);
114
+ consider("runtime_module", overrides.runtimeModule);
115
+ consider("provider", overrides.provider);
116
+ consider("provider", overrides.providerModule);
117
+ consider("instance", overrides.instance);
118
+ if (!desired) {
119
+ return {
120
+ impl: builtin,
121
+ binding: {
122
+ serviceId,
123
+ implId: builtin.implId,
124
+ implVersion: builtin.implVersion,
125
+ scope: "builtin",
126
+ overridden: false,
127
+ notes: builtin.notes
128
+ },
129
+ overridesApplied: []
130
+ };
131
+ }
132
+ const desiredImplId = desired.override.implId;
133
+ const selected = impls.find((i) => i.implId === desiredImplId);
134
+ const impl = selected ?? builtin;
135
+ const didFallback = selected == null;
136
+ const fallbackNote = didFallback ? `Unknown implId "${desiredImplId}", falling back to builtin "${builtin.implId}"` : void 0;
137
+ const notes = [desired.override.notes, impl.notes, fallbackNote].filter((s) => typeof s === "string" && s.length > 0).join("; ");
138
+ return {
139
+ impl,
140
+ binding: {
141
+ serviceId,
142
+ implId: impl.implId,
143
+ implVersion: impl.implVersion,
144
+ scope: desired.scope,
145
+ overridden: true,
146
+ notes: notes.length > 0 ? notes : void 0
147
+ },
148
+ overridesApplied: [
149
+ didFallback ? `${desired.scope}:${serviceId}=${desiredImplId} (fallback=${builtin.implId})` : `${desired.scope}:${serviceId}=${desiredImplId}`
150
+ ]
151
+ };
152
+ };
153
+ var makeRuntimeServicesEvidence = (args) => {
154
+ let scope = "builtin";
155
+ for (const b of args.bindings) {
156
+ scope = maxScope(scope, b.scope);
157
+ }
158
+ return {
159
+ moduleId: args.moduleId,
160
+ instanceId: args.instanceId,
161
+ scope,
162
+ bindings: args.bindings,
163
+ overridesApplied: args.overridesApplied
164
+ };
165
+ };
166
+ var RUNTIME_SERVICES_EVIDENCE = /* @__PURE__ */ Symbol.for("@logix/core/runtimeServicesEvidence");
167
+ var defineHidden2 = (target, key, value) => {
168
+ Object.defineProperty(target, key, {
169
+ value,
170
+ enumerable: false,
171
+ configurable: true,
172
+ writable: false
173
+ });
174
+ };
175
+ var formatScope = (moduleId, instanceId) => {
176
+ const m = typeof moduleId === "string" && moduleId.length > 0 ? moduleId : "unknown";
177
+ const i = typeof instanceId === "string" && instanceId.length > 0 ? instanceId : "unknown";
178
+ return `moduleId=${m}, instanceId=${i}`;
179
+ };
180
+ var setRuntimeServicesEvidence = (runtime, evidence) => {
181
+ defineHidden2(runtime, RUNTIME_SERVICES_EVIDENCE, evidence);
182
+ };
183
+ var getRuntimeServicesEvidence = (runtime) => {
184
+ const scope = runtime;
185
+ const evidence = runtime[RUNTIME_SERVICES_EVIDENCE];
186
+ if (!evidence) {
187
+ const msg = isDevEnv() ? [
188
+ "[MissingRuntimeServicesEvidence] Runtime services evidence not installed on ModuleRuntime instance.",
189
+ `scope: ${formatScope(scope.moduleId, scope.instanceId)}`,
190
+ "fix:",
191
+ "- Ensure ModuleRuntime.make assembles RuntimeKernel and attaches evidence (020 US2).",
192
+ "- If you created a mock runtime for tests, attach evidence or avoid calling evidence-only APIs."
193
+ ].join("\n") : "Runtime services evidence not installed";
194
+ throw new Error(msg);
195
+ }
196
+ const runtimeInstanceId = scope.instanceId;
197
+ if (typeof runtimeInstanceId === "string" && runtimeInstanceId.length > 0 && runtimeInstanceId !== evidence.instanceId) {
198
+ throw new Error(
199
+ isDevEnv() ? [
200
+ "[InconsistentRuntimeServicesEvidence] Runtime services evidence instanceId mismatch.",
201
+ `runtime: ${formatScope(scope.moduleId, runtimeInstanceId)}`,
202
+ `evidence: ${formatScope(evidence.moduleId, evidence.instanceId)}`
203
+ ].join("\n") : "Runtime services evidence mismatch"
204
+ );
205
+ }
206
+ return evidence;
207
+ };
208
+
209
+ // ../logix-core/src/internal/observability/evidenceCollector.ts
210
+ import { Context as Context2, Effect as Effect2, FiberRef, Layer } from "../effect.js";
211
+ var EvidenceCollectorTagImpl = class extends Context2.Tag(
212
+ "@logix/core/EvidenceCollector"
213
+ )() {
214
+ };
215
+ var EvidenceCollectorTag = EvidenceCollectorTagImpl;
216
+ var evidenceCollectorLayer = (collector) => Layer.succeed(EvidenceCollectorTag, collector);
217
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
218
+ var makeEvidenceCollector = (session) => {
219
+ const sink = makeEvidenceSink(session);
220
+ const convergeStaticIrByDigest = /* @__PURE__ */ new Map();
221
+ let runtimeServicesEvidence;
222
+ const exportBudget = {
223
+ dropped: 0,
224
+ oversized: 0,
225
+ nonSerializable: 0
226
+ };
227
+ const debugSink = {
228
+ record: (event) => Effect2.gen(function* () {
229
+ const level = yield* FiberRef.get(currentDiagnosticsLevel);
230
+ const instanceIdRaw = event.instanceId;
231
+ const instanceId = typeof instanceIdRaw === "string" && instanceIdRaw.length > 0 ? instanceIdRaw : "unknown";
232
+ const eventSeq = level === "off" ? void 0 : session.local.nextSeq("eventSeq", instanceId);
233
+ const ref = toRuntimeDebugEventRef(event, {
234
+ diagnosticsLevel: level,
235
+ eventSeq,
236
+ onMetaProjection: ({ stats }) => {
237
+ exportBudget.dropped += stats.dropped;
238
+ exportBudget.oversized += stats.oversized;
239
+ }
240
+ });
241
+ if (!ref) return;
242
+ const projected = projectJsonValue(ref);
243
+ exportBudget.dropped += projected.stats.dropped;
244
+ exportBudget.oversized += projected.stats.oversized;
245
+ exportBudget.nonSerializable += projected.stats.nonSerializable;
246
+ sink.record("debug:event", projected.value, {
247
+ timestamp: ref.timestamp
248
+ });
249
+ })
250
+ };
251
+ const registerConvergeStaticIr = (staticIr) => {
252
+ if (!isRecord(staticIr)) return;
253
+ const digest = staticIr.staticIrDigest;
254
+ if (typeof digest !== "string" || digest.length === 0) return;
255
+ const projected = projectJsonValue(staticIr);
256
+ exportBudget.dropped += projected.stats.dropped;
257
+ exportBudget.oversized += projected.stats.oversized;
258
+ exportBudget.nonSerializable += projected.stats.nonSerializable;
259
+ convergeStaticIrByDigest.set(digest, projected.value);
260
+ };
261
+ const setRuntimeServicesEvidence2 = (evidence) => {
262
+ const projected = projectJsonValue(evidence);
263
+ exportBudget.dropped += projected.stats.dropped;
264
+ exportBudget.oversized += projected.stats.oversized;
265
+ exportBudget.nonSerializable += projected.stats.nonSerializable;
266
+ runtimeServicesEvidence = projected.value;
267
+ };
268
+ const exportEvidencePackage = (options) => {
269
+ const convergeSummary = convergeStaticIrByDigest.size > 0 ? {
270
+ staticIrByDigest: Object.fromEntries(convergeStaticIrByDigest)
271
+ } : void 0;
272
+ const runtimeSummary = runtimeServicesEvidence != null ? { services: runtimeServicesEvidence } : void 0;
273
+ const summary = convergeSummary != null || runtimeSummary != null ? {
274
+ ...convergeSummary != null ? { converge: convergeSummary } : {},
275
+ ...runtimeSummary != null ? { runtime: runtimeSummary } : {}
276
+ } : void 0;
277
+ return sink.export({
278
+ maxEvents: options?.maxEvents,
279
+ summary
280
+ });
281
+ };
282
+ const clear = () => {
283
+ sink.clear();
284
+ convergeStaticIrByDigest.clear();
285
+ runtimeServicesEvidence = void 0;
286
+ exportBudget.dropped = 0;
287
+ exportBudget.oversized = 0;
288
+ exportBudget.nonSerializable = 0;
289
+ };
290
+ return {
291
+ session,
292
+ debugSink,
293
+ registerConvergeStaticIr,
294
+ setRuntimeServicesEvidence: setRuntimeServicesEvidence2,
295
+ exportEvidencePackage,
296
+ clear
297
+ };
298
+ };
299
+
300
+ // ../logix-core/src/internal/runtime/core/process/ProcessRuntime.ts
301
+ import {
302
+ Cause,
303
+ Context as Context3,
304
+ Deferred,
305
+ Duration,
306
+ Effect as Effect4,
307
+ Fiber as Fiber2,
308
+ FiberRef as FiberRef2,
309
+ Layer as Layer2,
310
+ Option as Option3,
311
+ PubSub,
312
+ Queue,
313
+ Ref as Ref2,
314
+ Scope as Scope2,
315
+ Stream as Stream2
316
+ } from "../effect.js";
317
+
318
+ // ../logix-core/src/internal/runtime/core/process/identity.ts
319
+ var scopeKeyFromScope = (scope) => {
320
+ switch (scope.type) {
321
+ case "app":
322
+ return `app:${scope.appId}`;
323
+ case "moduleInstance":
324
+ return `moduleInstance:${scope.moduleId}::${scope.instanceId}`;
325
+ case "uiSubtree":
326
+ return `uiSubtree:${scope.subtreeId}`;
327
+ }
328
+ };
329
+ var installationKeyFromIdentity = (identity) => `${identity.processId}@@${scopeKeyFromScope(identity.scope)}`;
330
+ var processInstanceIdFromIdentity = (identity) => {
331
+ const scopeKey = scopeKeyFromScope(identity.identity.scope);
332
+ return `process:${identity.identity.processId}::${scopeKey}::r${identity.runSeq}`;
333
+ };
334
+
335
+ // ../logix-core/src/internal/runtime/core/process/concurrency.ts
336
+ import { Effect as Effect3, Fiber, Option as Option2, Ref, Stream } from "../effect.js";
337
+ var DEFAULT_SERIAL_QUEUE_GUARD_LIMIT = 4096;
338
+ var DEFAULT_PARALLEL_LIMIT = 16;
339
+ var resolveQueueLimit = (maxQueue, options) => {
340
+ const defaultGuard = options?.defaultGuard ?? DEFAULT_SERIAL_QUEUE_GUARD_LIMIT;
341
+ const configured = typeof maxQueue === "number" && Number.isFinite(maxQueue) && maxQueue >= 0 ? Math.floor(maxQueue) : "unbounded";
342
+ return {
343
+ configured,
344
+ guard: configured === "unbounded" ? defaultGuard : configured
345
+ };
346
+ };
347
+ var runProcessTriggerStream = (args) => Effect3.gen(function* () {
348
+ const policy = args.policy;
349
+ const defaultQueueGuard = args.defaultQueueGuard ?? DEFAULT_SERIAL_QUEUE_GUARD_LIMIT;
350
+ const runLatest = yield* Ref.make(void 0);
351
+ const latestRunIdRef = yield* Ref.make(0);
352
+ const latestRunningIdRef = yield* Ref.make(0);
353
+ const busyRef = yield* Ref.make(false);
354
+ const serialStateRef = yield* Ref.make({
355
+ running: false,
356
+ queue: [],
357
+ peak: 0
358
+ });
359
+ const parallelStateRef = yield* Ref.make({
360
+ active: 0,
361
+ queue: [],
362
+ peak: 0
363
+ });
364
+ const serialQueueLimit = resolveQueueLimit(policy.maxQueue, { defaultGuard: defaultQueueGuard });
365
+ const parallelQueueLimit = resolveQueueLimit(void 0, { defaultGuard: defaultQueueGuard });
366
+ const parallelLimit = typeof policy.maxParallel === "number" && Number.isFinite(policy.maxParallel) && policy.maxParallel >= 1 ? Math.floor(policy.maxParallel) : args.defaultParallelLimit ?? DEFAULT_PARALLEL_LIMIT;
367
+ const drainSerial = () => Effect3.suspend(
368
+ () => Ref.modify(serialStateRef, (state) => {
369
+ if (state.running || state.queue.length === 0) {
370
+ return [Option2.none(), state];
371
+ }
372
+ const [next, ...rest] = state.queue;
373
+ return [Option2.some(next), { ...state, running: true, queue: rest }];
374
+ }).pipe(
375
+ Effect3.flatMap(
376
+ (next) => Option2.match(next, {
377
+ onNone: () => Effect3.void,
378
+ onSome: (trigger) => Effect3.forkScoped(
379
+ args.run(trigger).pipe(
380
+ Effect3.ensuring(
381
+ Ref.update(serialStateRef, (s) => ({ ...s, running: false }))
382
+ ),
383
+ Effect3.zipRight(drainSerial())
384
+ )
385
+ ).pipe(Effect3.asVoid)
386
+ })
387
+ )
388
+ )
389
+ );
390
+ const drainParallel = () => Effect3.suspend(
391
+ () => Ref.modify(parallelStateRef, (state) => {
392
+ if (state.active >= parallelLimit || state.queue.length === 0) {
393
+ return [Option2.none(), state];
394
+ }
395
+ const [next, ...rest] = state.queue;
396
+ return [Option2.some(next), { ...state, active: state.active + 1, queue: rest }];
397
+ }).pipe(
398
+ Effect3.flatMap(
399
+ (next) => Option2.match(next, {
400
+ onNone: () => Effect3.void,
401
+ onSome: (trigger) => Effect3.forkScoped(
402
+ args.run(trigger).pipe(
403
+ Effect3.ensuring(
404
+ Ref.update(parallelStateRef, (s) => ({
405
+ ...s,
406
+ active: Math.max(0, s.active - 1)
407
+ }))
408
+ ),
409
+ Effect3.zipRight(drainParallel())
410
+ )
411
+ ).pipe(Effect3.asVoid, Effect3.zipRight(drainParallel()))
412
+ })
413
+ )
414
+ )
415
+ );
416
+ const onTrigger = (trigger0) => Effect3.gen(function* () {
417
+ const trigger = args.assignTriggerSeq(trigger0);
418
+ if (policy.mode === "latest") {
419
+ const prevRunning = yield* Ref.get(latestRunningIdRef);
420
+ const prev = yield* Ref.get(runLatest);
421
+ if (prev && prevRunning !== 0) {
422
+ yield* Fiber.interruptFork(prev);
423
+ }
424
+ const runId = yield* Ref.updateAndGet(latestRunIdRef, (n) => n + 1);
425
+ yield* Ref.set(latestRunningIdRef, runId);
426
+ const fiber = yield* Effect3.forkScoped(
427
+ args.run(trigger).pipe(
428
+ Effect3.ensuring(
429
+ Ref.get(latestRunningIdRef).pipe(
430
+ Effect3.flatMap(
431
+ (current) => current === runId ? Ref.set(latestRunningIdRef, 0) : Effect3.void
432
+ )
433
+ )
434
+ )
435
+ )
436
+ );
437
+ yield* Ref.set(runLatest, fiber);
438
+ return;
439
+ }
440
+ if (policy.mode === "drop") {
441
+ const acquired = yield* Ref.modify(
442
+ busyRef,
443
+ (busy) => busy ? [false, busy] : [true, true]
444
+ );
445
+ if (!acquired) {
446
+ yield* args.onDrop(trigger);
447
+ return;
448
+ }
449
+ yield* Effect3.forkScoped(
450
+ args.run(trigger).pipe(
451
+ Effect3.ensuring(Ref.set(busyRef, false))
452
+ )
453
+ );
454
+ return;
455
+ }
456
+ if (policy.mode === "parallel") {
457
+ const nextSize2 = yield* Ref.modify(parallelStateRef, (state) => {
458
+ const queue = [...state.queue, trigger];
459
+ return [
460
+ queue.length,
461
+ { ...state, queue, peak: Math.max(state.peak, queue.length) }
462
+ ];
463
+ });
464
+ if (nextSize2 > parallelQueueLimit.guard) {
465
+ const state = yield* Ref.get(parallelStateRef);
466
+ yield* args.onQueueOverflow({
467
+ mode: "parallel",
468
+ currentLength: nextSize2,
469
+ peak: state.peak,
470
+ limit: parallelQueueLimit,
471
+ policy
472
+ });
473
+ return;
474
+ }
475
+ yield* drainParallel();
476
+ return;
477
+ }
478
+ const nextSize = yield* Ref.modify(serialStateRef, (state) => {
479
+ const queue = [...state.queue, trigger];
480
+ return [
481
+ queue.length,
482
+ { ...state, queue, peak: Math.max(state.peak, queue.length) }
483
+ ];
484
+ });
485
+ if (nextSize > serialQueueLimit.guard) {
486
+ const state = yield* Ref.get(serialStateRef);
487
+ yield* args.onQueueOverflow({
488
+ mode: "serial",
489
+ currentLength: nextSize,
490
+ peak: state.peak,
491
+ limit: serialQueueLimit,
492
+ policy
493
+ });
494
+ return;
495
+ }
496
+ yield* drainSerial();
497
+ });
498
+ return yield* Stream.runForEach(args.stream, onTrigger);
499
+ });
500
+
501
+ // ../logix-core/src/internal/runtime/core/process/events.ts
502
+ var PROCESS_EVENT_MAX_BYTES = 4 * 1024;
503
+ var PROCESS_EVENT_MAX_EVENTS_PER_RUN = 50;
504
+ var PROCESS_EVENT_RESERVED_EVENTS_FOR_SUMMARY = 1;
505
+ var makeProcessRunEventBudgetState = (options) => ({
506
+ maxEvents: typeof options?.maxEvents === "number" && Number.isFinite(options.maxEvents) && options.maxEvents >= 0 ? Math.floor(options.maxEvents) : PROCESS_EVENT_MAX_EVENTS_PER_RUN,
507
+ maxBytes: typeof options?.maxBytes === "number" && Number.isFinite(options.maxBytes) && options.maxBytes >= 0 ? Math.floor(options.maxBytes) : PROCESS_EVENT_MAX_BYTES,
508
+ emitted: 0,
509
+ dropped: 0,
510
+ downgraded: 0,
511
+ summaryEmitted: false
512
+ });
513
+ var makeBudgetSummaryEvent = (args) => ({
514
+ type: "process:trigger",
515
+ identity: args.sourceEvent.identity,
516
+ trigger: args.sourceEvent.trigger,
517
+ severity: "warning",
518
+ eventSeq: args.sourceEvent.eventSeq,
519
+ timestampMs: args.sourceEvent.timestampMs,
520
+ error: {
521
+ message: "Process run event budget exceeded; further trigger/dispatch events are suppressed.",
522
+ code: "process::event_budget_exceeded",
523
+ hint: `maxEvents=${args.maxEvents} maxBytes=${args.maxBytes} emitted=${args.emitted} dropped=${args.dropped} downgraded=${args.downgraded}`
524
+ }
525
+ });
526
+ var applyProcessRunEventBudget = (state, event) => {
527
+ const maxEvents = Math.max(0, state.maxEvents);
528
+ const maxBytes = Math.max(0, state.maxBytes);
529
+ if (state.summaryEmitted) {
530
+ return [
531
+ { _tag: "drop" },
532
+ {
533
+ ...state,
534
+ dropped: state.dropped + 1
535
+ }
536
+ ];
537
+ }
538
+ const reserve = PROCESS_EVENT_RESERVED_EVENTS_FOR_SUMMARY;
539
+ const allowedRegular = Math.max(0, maxEvents - reserve);
540
+ if (state.emitted < allowedRegular) {
541
+ const enforced = enforceProcessEventMaxBytes(event, { maxBytes });
542
+ return [
543
+ { _tag: "emit", event: enforced.event },
544
+ {
545
+ ...state,
546
+ emitted: state.emitted + 1,
547
+ downgraded: state.downgraded + (enforced.downgraded ? 1 : 0)
548
+ }
549
+ ];
550
+ }
551
+ const dropped = state.dropped + 1;
552
+ const summary = makeBudgetSummaryEvent({
553
+ sourceEvent: event,
554
+ maxEvents,
555
+ maxBytes,
556
+ emitted: state.emitted,
557
+ dropped,
558
+ downgraded: state.downgraded
559
+ });
560
+ const enforcedSummary = enforceProcessEventMaxBytes(summary, { maxBytes });
561
+ return [
562
+ { _tag: "emitSummary", event: enforcedSummary.event },
563
+ {
564
+ ...state,
565
+ emitted: Math.min(maxEvents, state.emitted + 1),
566
+ dropped,
567
+ downgraded: state.downgraded + (enforcedSummary.downgraded ? 1 : 0),
568
+ summaryEmitted: true
569
+ }
570
+ ];
571
+ };
572
+ var estimateEventBytes = (event) => {
573
+ const json = JSON.stringify(event);
574
+ return typeof Buffer !== "undefined" ? Buffer.byteLength(json, "utf8") : new TextEncoder().encode(json).length;
575
+ };
576
+ var truncateChars = (value, maxLen) => value.length <= maxLen ? value : value.slice(0, maxLen);
577
+ var normalizeErrorSummary = (error) => {
578
+ const message = typeof error.message === "string" && error.message.length > 0 ? error.message : "Error";
579
+ const hint = typeof error.hint === "string" && error.hint.length > 0 ? truncateChars(error.hint, 1024) : void 0;
580
+ return {
581
+ name: typeof error.name === "string" && error.name.length > 0 ? error.name : void 0,
582
+ message: truncateChars(message, 256),
583
+ code: typeof error.code === "string" && error.code.length > 0 ? error.code : void 0,
584
+ hint
585
+ };
586
+ };
587
+ var enforceProcessEventMaxBytes = (event, options) => {
588
+ const maxBytes = options?.maxBytes ?? PROCESS_EVENT_MAX_BYTES;
589
+ let downgraded = false;
590
+ let next = event;
591
+ if (event.error) {
592
+ const normalized = normalizeErrorSummary(event.error);
593
+ if (normalized.message !== event.error.message || normalized.hint !== event.error.hint || normalized.code !== event.error.code || normalized.name !== event.error.name) {
594
+ downgraded = true;
595
+ next = { ...event, error: normalized };
596
+ }
597
+ }
598
+ if (estimateEventBytes(next) <= maxBytes) {
599
+ return { event: next, downgraded };
600
+ }
601
+ if (!next.error?.hint) {
602
+ return { event: next, downgraded: true };
603
+ }
604
+ const hint = next.error.hint;
605
+ const steps = [512, 256, 128, 64, 32, 0];
606
+ for (const maxLen of steps) {
607
+ const trimmed = maxLen === 0 ? void 0 : truncateChars(hint, maxLen);
608
+ const candidate = {
609
+ ...next,
610
+ error: {
611
+ ...next.error,
612
+ hint: trimmed
613
+ }
614
+ };
615
+ if (estimateEventBytes(candidate) <= maxBytes) {
616
+ return { event: candidate, downgraded: true };
617
+ }
618
+ }
619
+ const fallback = next.error ? {
620
+ ...next,
621
+ error: {
622
+ ...next.error,
623
+ message: truncateChars(next.error.message, 96),
624
+ hint: void 0
625
+ }
626
+ } : next;
627
+ return { event: fallback, downgraded: true };
628
+ };
629
+
630
+ // ../logix-core/src/internal/runtime/core/process/supervision.ts
631
+ var initialState = () => ({ failureTimes: [] });
632
+ var onFailure = (policy, state, nowMs) => {
633
+ if (policy.mode === "failStop") {
634
+ return {
635
+ decision: "stop",
636
+ nextState: state,
637
+ withinWindowFailures: state.failureTimes.length,
638
+ maxRestarts: 0,
639
+ windowMs: policy.windowMs
640
+ };
641
+ }
642
+ const maxRestartsRaw = policy.maxRestarts;
643
+ const maxRestarts = typeof maxRestartsRaw === "number" && Number.isFinite(maxRestartsRaw) && maxRestartsRaw >= 0 ? Math.floor(maxRestartsRaw) : 0;
644
+ if (maxRestarts <= 0) {
645
+ return {
646
+ decision: "stop",
647
+ nextState: state,
648
+ withinWindowFailures: state.failureTimes.length,
649
+ maxRestarts,
650
+ windowMs: policy.windowMs
651
+ };
652
+ }
653
+ const windowMsRaw = policy.windowMs;
654
+ const windowMs = typeof windowMsRaw === "number" && Number.isFinite(windowMsRaw) && windowMsRaw > 0 ? Math.floor(windowMsRaw) : void 0;
655
+ const failureTimesRaw = [...state.failureTimes, nowMs];
656
+ const failureTimes = windowMs ? failureTimesRaw.filter((t) => t >= nowMs - windowMs) : failureTimesRaw;
657
+ const cap = maxRestarts + 1;
658
+ const capped = failureTimes.length > cap ? failureTimes.slice(failureTimes.length - cap) : failureTimes;
659
+ const withinWindowFailures = capped.length;
660
+ const decision = withinWindowFailures <= maxRestarts ? "restart" : "stop";
661
+ return {
662
+ decision,
663
+ nextState: { failureTimes: capped },
664
+ withinWindowFailures,
665
+ maxRestarts,
666
+ windowMs
667
+ };
668
+ };
669
+
670
+ // ../logix-core/src/internal/runtime/core/process/ProcessRuntime.ts
671
+ var ProcessRuntimeTag = class extends Context3.Tag("@logix/core/ProcessRuntime")() {
672
+ };
673
+ var currentProcessTrigger = FiberRef2.unsafeMake(void 0);
674
+ var currentProcessEventBudget = FiberRef2.unsafeMake(void 0);
675
+ var RUNTIME_BOOT_EVENT = "runtime:boot";
676
+ var deriveDebugModuleId = (processId) => `process:${processId}`;
677
+ var deriveTxnAnchor = (event) => {
678
+ const trigger = event.trigger;
679
+ if (!trigger) return {};
680
+ if ((trigger.kind === "moduleAction" || trigger.kind === "moduleStateChange") && typeof trigger.instanceId === "string" && typeof trigger.txnSeq === "number" && Number.isFinite(trigger.txnSeq) && trigger.txnSeq >= 1) {
681
+ const txnSeq = Math.floor(trigger.txnSeq);
682
+ return {
683
+ txnSeq,
684
+ txnId: `${trigger.instanceId}::t${txnSeq}`
685
+ };
686
+ }
687
+ return {};
688
+ };
689
+ var shouldNoopDueToSyncTxn = (scope, kind) => {
690
+ const moduleId = scope.type === "moduleInstance" ? scope.moduleId : void 0;
691
+ const instanceId = scope.type === "moduleInstance" ? scope.instanceId : void 0;
692
+ return shouldNoopInSyncTransactionFiber({
693
+ moduleId,
694
+ instanceId,
695
+ code: "process::invalid_usage",
696
+ severity: "error",
697
+ message: "ProcessRuntime scheduling is not allowed inside a synchronous StateTransaction body (it may deadlock the txnQueue).",
698
+ hint: "Trigger/schedule Process outside the transaction window (e.g. in a watcher's run section or a separate fiber); do not trigger Process directly inside a reducer / synchronous transaction body.",
699
+ kind
700
+ });
701
+ };
702
+ var makeDotPathError = (path, message, hint) => {
703
+ const err = new Error(message);
704
+ err.code = "process::invalid_dot_path";
705
+ err.hint = hint ?? [
706
+ "Expected dot-path syntax: segments separated by '.', numeric segments represent array indices.",
707
+ `path: ${path}`,
708
+ "",
709
+ "examples:",
710
+ "- count",
711
+ "- user.name",
712
+ "- items.0.id"
713
+ ].join("\n");
714
+ return err;
715
+ };
716
+ var parseDotPath = (path) => {
717
+ if (typeof path !== "string" || path.length === 0) {
718
+ return { ok: false, error: makeDotPathError(String(path), "dot-path must be a non-empty string") };
719
+ }
720
+ const raw = path.split(".");
721
+ if (raw.length === 0) {
722
+ return { ok: false, error: makeDotPathError(path, "dot-path must contain at least one segment") };
723
+ }
724
+ const segments = [];
725
+ for (let i = 0; i < raw.length; i++) {
726
+ const seg = raw[i];
727
+ if (seg.length === 0) {
728
+ return {
729
+ ok: false,
730
+ error: makeDotPathError(
731
+ path,
732
+ `Invalid dot-path: empty segment at index ${i}.`,
733
+ [
734
+ "Expected dot-path syntax: segments separated by '.', numeric segments represent array indices.",
735
+ `path: ${path}`,
736
+ "",
737
+ "examples:",
738
+ "- count",
739
+ "- user.name",
740
+ "- items.0.id",
741
+ "",
742
+ "fix:",
743
+ "- Remove consecutive dots or trailing dots."
744
+ ].join("\n")
745
+ )
746
+ };
747
+ }
748
+ if (/^[0-9]+$/.test(seg)) {
749
+ const n = Number(seg);
750
+ if (!Number.isFinite(n) || n < 0) {
751
+ return {
752
+ ok: false,
753
+ error: makeDotPathError(path, `Invalid array index segment "${seg}" at index ${i}.`)
754
+ };
755
+ }
756
+ segments.push(Math.floor(n));
757
+ continue;
758
+ }
759
+ segments.push(seg);
760
+ }
761
+ return { ok: true, segments };
762
+ };
763
+ var selectByDotPath = (segments) => (state) => {
764
+ let current = state;
765
+ for (const seg of segments) {
766
+ if (current == null) return void 0;
767
+ current = current[seg];
768
+ }
769
+ return current;
770
+ };
771
+ var actionIdFromUnknown = (action) => {
772
+ if (!action || typeof action !== "object") return void 0;
773
+ const anyAction = action;
774
+ if (typeof anyAction._tag === "string" && anyAction._tag.length > 0) return anyAction._tag;
775
+ if (typeof anyAction.type === "string" && anyAction.type.length > 0) return anyAction.type;
776
+ return void 0;
777
+ };
778
+ var make = (options) => Effect4.gen(function* () {
779
+ const runtimeScope = yield* Effect4.scope;
780
+ const maxEventHistory = typeof options?.maxEventHistory === "number" && Number.isFinite(options.maxEventHistory) && options.maxEventHistory >= 0 ? Math.floor(options.maxEventHistory) : 500;
781
+ const installations = /* @__PURE__ */ new Map();
782
+ const instances = /* @__PURE__ */ new Map();
783
+ const eventsBuffer = [];
784
+ const eventsHub = yield* PubSub.sliding(Math.max(1, Math.min(2048, maxEventHistory)));
785
+ const trimEvents = () => {
786
+ if (maxEventHistory <= 0) {
787
+ eventsBuffer.length = 0;
788
+ return;
789
+ }
790
+ if (eventsBuffer.length <= maxEventHistory) return;
791
+ const excess = eventsBuffer.length - maxEventHistory;
792
+ eventsBuffer.splice(0, excess);
793
+ };
794
+ const recordDebugEvent = (event) => Effect4.gen(function* () {
795
+ const diagnosticsLevel = yield* FiberRef2.get(currentDiagnosticsLevel);
796
+ if (diagnosticsLevel === "off") {
797
+ return;
798
+ }
799
+ const processId = event.identity.identity.processId;
800
+ const processInstanceId = processInstanceIdFromIdentity(event.identity);
801
+ const moduleId = deriveDebugModuleId(processId);
802
+ const { txnSeq, txnId } = deriveTxnAnchor(event);
803
+ yield* record({
804
+ type: event.type,
805
+ moduleId,
806
+ instanceId: processInstanceId,
807
+ identity: event.identity,
808
+ severity: event.severity,
809
+ eventSeq: event.eventSeq,
810
+ timestampMs: event.timestampMs,
811
+ trigger: event.trigger,
812
+ dispatch: event.dispatch,
813
+ error: event.error,
814
+ txnSeq,
815
+ txnId
816
+ });
817
+ });
818
+ const publishEvent = (event) => Effect4.gen(function* () {
819
+ eventsBuffer.push(event);
820
+ trimEvents();
821
+ yield* PubSub.publish(eventsHub, event);
822
+ yield* recordDebugEvent(event);
823
+ });
824
+ const emit = (event) => Effect4.gen(function* () {
825
+ const budgetRef = yield* FiberRef2.get(currentProcessEventBudget);
826
+ if (budgetRef) {
827
+ const decision = yield* Ref2.modify(budgetRef, (state) => {
828
+ const [nextDecision, nextState] = applyProcessRunEventBudget(state, event);
829
+ return [nextDecision, nextState];
830
+ });
831
+ if (decision._tag === "emit" || decision._tag === "emitSummary") {
832
+ yield* publishEvent(decision.event);
833
+ }
834
+ return;
835
+ }
836
+ const enforced = enforceProcessEventMaxBytes(event);
837
+ yield* publishEvent(enforced.event);
838
+ });
839
+ const emitErrorDiagnostic = (scope, processId, code, message, hint) => {
840
+ if (!isDevEnv()) {
841
+ return Effect4.void;
842
+ }
843
+ const moduleId = scope.type === "moduleInstance" ? scope.moduleId : void 0;
844
+ const instanceId = scope.type === "moduleInstance" ? scope.instanceId : void 0;
845
+ return record({
846
+ type: "diagnostic",
847
+ moduleId,
848
+ instanceId,
849
+ code,
850
+ severity: "error",
851
+ message,
852
+ hint,
853
+ actionTag: processId,
854
+ kind: "process_runtime"
855
+ });
856
+ };
857
+ const resolveMissingDependencies = (installation) => {
858
+ const declared = installation.definition.requires ?? [];
859
+ const implicitFromTriggers = [];
860
+ for (const trigger of installation.definition.triggers) {
861
+ if (trigger.kind === "moduleAction" || trigger.kind === "moduleStateChange") {
862
+ implicitFromTriggers.push(trigger.moduleId);
863
+ }
864
+ }
865
+ const requires = Array.from(/* @__PURE__ */ new Set([...declared, ...implicitFromTriggers]));
866
+ if (requires.length === 0) return [];
867
+ const missing = [];
868
+ for (const dep of requires) {
869
+ if (typeof dep !== "string" || dep.length === 0) continue;
870
+ const tag = Context3.Tag(`@logix/Module/${dep}`)();
871
+ const found = Context3.getOption(installation.env, tag);
872
+ if (Option3.isNone(found)) {
873
+ missing.push(dep);
874
+ }
875
+ }
876
+ return missing;
877
+ };
878
+ const stopInstance = (instance, reason) => Effect4.gen(function* () {
879
+ const fiber = instance.fiber;
880
+ instance.status = {
881
+ ...instance.status,
882
+ status: "stopping",
883
+ stoppedReason: reason
884
+ };
885
+ if (fiber) {
886
+ yield* Fiber2.interrupt(fiber);
887
+ }
888
+ yield* Queue.shutdown(instance.platformTriggersQueue);
889
+ instance.status = {
890
+ ...instance.status,
891
+ status: "stopped",
892
+ stoppedReason: reason
893
+ };
894
+ instance.fiber = void 0;
895
+ const evt = {
896
+ type: "process:stop",
897
+ identity: instance.identity,
898
+ severity: "info",
899
+ eventSeq: instance.nextEventSeq++,
900
+ timestampMs: Date.now()
901
+ };
902
+ yield* emit(evt);
903
+ });
904
+ const startInstallation = (installationKey) => Effect4.gen(function* () {
905
+ const installation = installations.get(installationKey);
906
+ if (!installation) return;
907
+ const noop = yield* shouldNoopDueToSyncTxn(installation.identity.scope, "process_start_in_transaction");
908
+ if (noop) return;
909
+ const currentId = installation.currentInstanceId;
910
+ if (currentId) {
911
+ const current = instances.get(currentId);
912
+ if (current && current.status.status === "running") {
913
+ return;
914
+ }
915
+ }
916
+ const runSeq = installation.nextRunSeq++;
917
+ const identity = {
918
+ identity: installation.identity,
919
+ runSeq
920
+ };
921
+ const processInstanceId = processInstanceIdFromIdentity(identity);
922
+ const platformTriggersQueue = yield* Queue.sliding(64);
923
+ const instanceState = {
924
+ installationKey,
925
+ processInstanceId,
926
+ identity,
927
+ processId: installation.identity.processId,
928
+ scope: installation.identity.scope,
929
+ platformTriggersQueue,
930
+ status: {
931
+ identity,
932
+ status: "starting"
933
+ },
934
+ nextEventSeq: 1,
935
+ nextTriggerSeq: 1
936
+ };
937
+ instances.set(processInstanceId, instanceState);
938
+ installation.currentInstanceId = processInstanceId;
939
+ yield* emit({
940
+ type: "process:start",
941
+ identity,
942
+ severity: "info",
943
+ eventSeq: instanceState.nextEventSeq++,
944
+ timestampMs: Date.now()
945
+ });
946
+ const missing = resolveMissingDependencies(installation);
947
+ if (missing.length > 0) {
948
+ const hint = isDevEnv() ? [
949
+ "Strict scope dependency resolution: missing required modules in the current scope.",
950
+ `missing: ${missing.join(", ")}`,
951
+ "",
952
+ "fix:",
953
+ "- Provide the missing module implementation(s) in the same scope via imports.",
954
+ ` Example: RootModule.implement({ imports: [${missing[0]}.implement(...).impl], processes: [...] })`,
955
+ "- Do not rely on cross-scope fallbacks / guessing instances."
956
+ ].join("\n") : void 0;
957
+ const error = {
958
+ message: `Missing dependencies in scope: ${missing.join(", ")}`,
959
+ code: "process::missing_dependency",
960
+ hint
961
+ };
962
+ instanceState.status = {
963
+ ...instanceState.status,
964
+ status: "failed",
965
+ stoppedReason: "failed",
966
+ lastError: error
967
+ };
968
+ yield* emit({
969
+ type: "process:error",
970
+ identity,
971
+ severity: "error",
972
+ eventSeq: instanceState.nextEventSeq++,
973
+ timestampMs: Date.now(),
974
+ error
975
+ });
976
+ yield* emitErrorDiagnostic(
977
+ installation.identity.scope,
978
+ installation.identity.processId,
979
+ "process::missing_dependency",
980
+ error.message,
981
+ hint
982
+ );
983
+ return;
984
+ }
985
+ const shouldRecordChainEvents = installation.definition.diagnosticsLevel !== "off";
986
+ const baseEnv = installation.env;
987
+ const makeWrappedEnv = () => {
988
+ if (!shouldRecordChainEvents) {
989
+ return baseEnv;
990
+ }
991
+ const requires = installation.definition.requires ?? [];
992
+ if (requires.length === 0) {
993
+ return baseEnv;
994
+ }
995
+ const ids = Array.from(new Set(requires));
996
+ let nextEnv = baseEnv;
997
+ for (const moduleId of ids) {
998
+ if (typeof moduleId !== "string" || moduleId.length === 0) continue;
999
+ const tag = Context3.Tag(`@logix/Module/${moduleId}`)();
1000
+ const found = Context3.getOption(baseEnv, tag);
1001
+ if (Option3.isNone(found)) continue;
1002
+ const runtime = found.value;
1003
+ const recordDispatch = (action) => Effect4.gen(function* () {
1004
+ const trigger = yield* FiberRef2.get(currentProcessTrigger);
1005
+ if (!trigger) return;
1006
+ const actionId = actionIdFromUnknown(action) ?? "unknown";
1007
+ const dispatchModuleId = typeof runtime.moduleId === "string" ? runtime.moduleId : moduleId;
1008
+ const dispatchInstanceId = typeof runtime.instanceId === "string" ? runtime.instanceId : "unknown";
1009
+ const evt = {
1010
+ type: "process:dispatch",
1011
+ identity,
1012
+ trigger,
1013
+ dispatch: {
1014
+ moduleId: dispatchModuleId,
1015
+ instanceId: dispatchInstanceId,
1016
+ actionId
1017
+ },
1018
+ severity: "info",
1019
+ eventSeq: instanceState.nextEventSeq++,
1020
+ timestampMs: Date.now()
1021
+ };
1022
+ yield* emit(evt);
1023
+ });
1024
+ const wrapped = {
1025
+ ...runtime,
1026
+ dispatch: (action) => runtime.dispatch(action).pipe(Effect4.tap(() => recordDispatch(action))),
1027
+ dispatchLowPriority: (action) => runtime.dispatchLowPriority(action).pipe(Effect4.tap(() => recordDispatch(action))),
1028
+ dispatchBatch: (actions) => runtime.dispatchBatch(actions).pipe(
1029
+ Effect4.tap(() => Effect4.forEach(actions, recordDispatch, { discard: true }))
1030
+ )
1031
+ };
1032
+ nextEnv = Context3.add(tag, wrapped)(nextEnv);
1033
+ }
1034
+ return nextEnv;
1035
+ };
1036
+ const wrappedEnv = makeWrappedEnv();
1037
+ const makeTriggerStream = (spec) => Effect4.gen(function* () {
1038
+ if (spec.kind === "timer") {
1039
+ const interval = Duration.decodeUnknown(spec.timerId);
1040
+ if (Option3.isNone(interval)) {
1041
+ const err = new Error(`[ProcessRuntime] invalid timerId (expected DurationInput): ${spec.timerId}`);
1042
+ err.code = "process::invalid_timer_id";
1043
+ err.hint = "timerId must be a valid DurationInput string, e.g. '10 millis', '1 seconds', '5 minutes'.";
1044
+ return yield* Effect4.fail(err);
1045
+ }
1046
+ return Stream2.tick(interval.value).pipe(
1047
+ Stream2.map(
1048
+ () => ({
1049
+ kind: "timer",
1050
+ name: spec.name,
1051
+ timerId: spec.timerId
1052
+ })
1053
+ )
1054
+ );
1055
+ }
1056
+ if (spec.kind === "moduleAction") {
1057
+ const tag2 = Context3.Tag(`@logix/Module/${spec.moduleId}`)();
1058
+ const found2 = Context3.getOption(baseEnv, tag2);
1059
+ if (Option3.isNone(found2)) {
1060
+ return yield* Effect4.fail(new Error(`Missing module runtime in scope: ${spec.moduleId}`));
1061
+ }
1062
+ const runtime2 = found2.value;
1063
+ if (!shouldRecordChainEvents) {
1064
+ const stream2 = runtime2.actions$;
1065
+ if (!stream2) {
1066
+ const err = new Error(
1067
+ "ModuleRuntime does not provide actions$ (required for moduleAction trigger)."
1068
+ );
1069
+ err.code = "process::missing_action_stream";
1070
+ err.hint = `moduleId=${spec.moduleId}`;
1071
+ return yield* Effect4.fail(err);
1072
+ }
1073
+ return stream2.pipe(
1074
+ Stream2.filter((action) => actionIdFromUnknown(action) === spec.actionId),
1075
+ Stream2.map(
1076
+ () => ({
1077
+ kind: "moduleAction",
1078
+ name: spec.name,
1079
+ moduleId: spec.moduleId,
1080
+ instanceId: runtime2.instanceId,
1081
+ actionId: spec.actionId,
1082
+ txnSeq: 1
1083
+ })
1084
+ )
1085
+ );
1086
+ }
1087
+ const stream = runtime2.actionsWithMeta$;
1088
+ if (!stream) {
1089
+ const err = new Error(
1090
+ "ModuleRuntime does not provide actionsWithMeta$ (required for moduleAction trigger)."
1091
+ );
1092
+ err.code = "process::missing_action_meta_stream";
1093
+ err.hint = `moduleId=${spec.moduleId}`;
1094
+ return yield* Effect4.fail(err);
1095
+ }
1096
+ return stream.pipe(
1097
+ Stream2.filter((evt) => actionIdFromUnknown(evt.value) === spec.actionId),
1098
+ Stream2.map((evt) => {
1099
+ const txnSeq = evt?.meta?.txnSeq;
1100
+ return {
1101
+ kind: "moduleAction",
1102
+ name: spec.name,
1103
+ moduleId: spec.moduleId,
1104
+ instanceId: runtime2.instanceId,
1105
+ actionId: spec.actionId,
1106
+ txnSeq: typeof txnSeq === "number" ? txnSeq : 1
1107
+ };
1108
+ })
1109
+ );
1110
+ }
1111
+ const parsed = parseDotPath(spec.path);
1112
+ if (!parsed.ok) {
1113
+ return yield* Effect4.fail(parsed.error);
1114
+ }
1115
+ const tag = Context3.Tag(`@logix/Module/${spec.moduleId}`)();
1116
+ const found = Context3.getOption(baseEnv, tag);
1117
+ if (Option3.isNone(found)) {
1118
+ return yield* Effect4.fail(new Error(`Missing module runtime in scope: ${spec.moduleId}`));
1119
+ }
1120
+ const runtime = found.value;
1121
+ const selectorBase = selectByDotPath(parsed.segments);
1122
+ const prevRef = yield* Ref2.make(Option3.none());
1123
+ const enableSelectorDiagnostics = shouldRecordChainEvents;
1124
+ const selectorDiagnosticsRef = enableSelectorDiagnostics ? yield* Ref2.make({
1125
+ windowStartedMs: Date.now(),
1126
+ triggersInWindow: 0,
1127
+ lastWarningAtMs: 0
1128
+ }) : void 0;
1129
+ const sampleEveryMask = 127;
1130
+ const slowSampleThresholdMs = 4;
1131
+ const triggerWindowMs = 1e3;
1132
+ const triggerWarningThreshold = isDevEnv() ? 20 : 200;
1133
+ const warningCooldownMs = 3e4;
1134
+ let selectorCalls = 0;
1135
+ let selectorSamples = 0;
1136
+ let selectorSlowSamples = 0;
1137
+ let selectorMaxSampleMs = 0;
1138
+ const nowMs = () => {
1139
+ if (typeof performance !== "undefined" && typeof performance.now === "function") {
1140
+ return performance.now();
1141
+ }
1142
+ return Date.now();
1143
+ };
1144
+ const selector = enableSelectorDiagnostics ? ((state) => {
1145
+ selectorCalls += 1;
1146
+ if ((selectorCalls & sampleEveryMask) !== 0) {
1147
+ return selectorBase(state);
1148
+ }
1149
+ const t0 = nowMs();
1150
+ const value = selectorBase(state);
1151
+ const dt = nowMs() - t0;
1152
+ selectorSamples += 1;
1153
+ if (dt >= slowSampleThresholdMs) {
1154
+ selectorSlowSamples += 1;
1155
+ }
1156
+ if (dt > selectorMaxSampleMs) {
1157
+ selectorMaxSampleMs = dt;
1158
+ }
1159
+ return value;
1160
+ }) : selectorBase;
1161
+ const maybeWarnSelector = (trigger) => {
1162
+ if (!selectorDiagnosticsRef) {
1163
+ return Effect4.void;
1164
+ }
1165
+ return Effect4.gen(function* () {
1166
+ const now = Date.now();
1167
+ const decision = yield* Ref2.modify(selectorDiagnosticsRef, (s) => {
1168
+ const windowExpired = now - s.windowStartedMs >= triggerWindowMs;
1169
+ const windowStartedMs = windowExpired ? now : s.windowStartedMs;
1170
+ const triggersInWindow = windowExpired ? 1 : s.triggersInWindow + 1;
1171
+ const shouldCooldown = now - s.lastWarningAtMs < warningCooldownMs;
1172
+ const tooFrequent = triggersInWindow >= triggerWarningThreshold;
1173
+ const tooSlow = selectorMaxSampleMs >= slowSampleThresholdMs && selectorSamples > 0;
1174
+ const shouldWarn = !shouldCooldown && (tooFrequent || tooSlow);
1175
+ const next = shouldWarn ? {
1176
+ windowStartedMs: now,
1177
+ triggersInWindow: 0,
1178
+ lastWarningAtMs: now
1179
+ } : {
1180
+ ...s,
1181
+ windowStartedMs,
1182
+ triggersInWindow
1183
+ };
1184
+ return [
1185
+ {
1186
+ shouldWarn,
1187
+ tooFrequent,
1188
+ tooSlow,
1189
+ triggersInWindow
1190
+ },
1191
+ next
1192
+ ];
1193
+ });
1194
+ if (!decision.shouldWarn) {
1195
+ return;
1196
+ }
1197
+ const code = decision.tooFrequent ? "process::selector_high_frequency" : "process::selector_slow";
1198
+ const hint = [
1199
+ `moduleId=${spec.moduleId}`,
1200
+ `path=${spec.path}`,
1201
+ `windowMs=${triggerWindowMs}`,
1202
+ `triggersInWindow=${decision.triggersInWindow}`,
1203
+ `threshold=${triggerWarningThreshold}`,
1204
+ `cooldownMs=${warningCooldownMs}`,
1205
+ "",
1206
+ "selector sampling:",
1207
+ `calls=${selectorCalls}`,
1208
+ `sampled=${selectorSamples}`,
1209
+ `slowSamples(>=${slowSampleThresholdMs}ms)=${selectorSlowSamples}`,
1210
+ `maxSampleMs=${selectorMaxSampleMs.toFixed(2)}`,
1211
+ "",
1212
+ "notes:",
1213
+ "- Ensure the selected value is stable (prefer primitive/tuple; avoid returning fresh objects).",
1214
+ "- Narrow the path to reduce change frequency; avoid selecting large objects."
1215
+ ].join("\n");
1216
+ selectorSamples = 0;
1217
+ selectorSlowSamples = 0;
1218
+ selectorMaxSampleMs = 0;
1219
+ yield* emit({
1220
+ type: "process:trigger",
1221
+ identity,
1222
+ trigger,
1223
+ severity: "warning",
1224
+ eventSeq: instanceState.nextEventSeq++,
1225
+ timestampMs: Date.now(),
1226
+ error: {
1227
+ message: "moduleStateChange selector diagnostics warning",
1228
+ code,
1229
+ hint
1230
+ }
1231
+ });
1232
+ });
1233
+ };
1234
+ const baseStream = runtime.changesWithMeta(selector).pipe(
1235
+ Stream2.mapEffect(
1236
+ (evt) => Ref2.get(prevRef).pipe(
1237
+ Effect4.flatMap((prev) => {
1238
+ if (Option3.isSome(prev) && Object.is(prev.value, evt.value)) {
1239
+ return Effect4.succeed(Option3.none());
1240
+ }
1241
+ return Ref2.set(prevRef, Option3.some(evt.value)).pipe(
1242
+ Effect4.as(Option3.some(evt))
1243
+ );
1244
+ })
1245
+ )
1246
+ ),
1247
+ Stream2.filterMap((opt) => opt),
1248
+ Stream2.map((evt) => {
1249
+ const txnSeq = evt?.meta?.txnSeq;
1250
+ return {
1251
+ kind: "moduleStateChange",
1252
+ name: spec.name,
1253
+ moduleId: spec.moduleId,
1254
+ instanceId: runtime.instanceId,
1255
+ path: spec.path,
1256
+ txnSeq: typeof txnSeq === "number" ? txnSeq : 1
1257
+ };
1258
+ })
1259
+ );
1260
+ return enableSelectorDiagnostics ? baseStream.pipe(Stream2.tap(maybeWarnSelector)) : baseStream;
1261
+ });
1262
+ const makeRun = (trigger, fatal) => Effect4.locally(currentProcessTrigger, trigger)(
1263
+ Effect4.provide(installation.process, wrappedEnv).pipe(
1264
+ Effect4.catchAllCause((cause) => {
1265
+ if (Cause.isInterruptedOnly(cause)) {
1266
+ return Effect4.void;
1267
+ }
1268
+ return Deferred.succeed(fatal, cause).pipe(Effect4.asVoid, Effect4.catchAll(() => Effect4.void));
1269
+ })
1270
+ )
1271
+ );
1272
+ const makeChainRun = (trigger, fatal) => {
1273
+ if (!shouldRecordChainEvents) {
1274
+ return makeRun(trigger, fatal);
1275
+ }
1276
+ return Effect4.gen(function* () {
1277
+ const budgetRef = yield* Ref2.make(makeProcessRunEventBudgetState());
1278
+ return yield* Effect4.locally(currentProcessEventBudget, budgetRef)(
1279
+ emitTriggerEvent(trigger, "info").pipe(
1280
+ Effect4.zipRight(makeRun(trigger, fatal))
1281
+ )
1282
+ );
1283
+ });
1284
+ };
1285
+ const assignTriggerSeq = (trigger) => ({
1286
+ ...trigger,
1287
+ triggerSeq: instanceState.nextTriggerSeq++
1288
+ });
1289
+ const emitTriggerEvent = (trigger, severity) => {
1290
+ if (!shouldRecordChainEvents) {
1291
+ return Effect4.void;
1292
+ }
1293
+ const evt = {
1294
+ type: "process:trigger",
1295
+ identity,
1296
+ trigger,
1297
+ severity,
1298
+ eventSeq: instanceState.nextEventSeq++,
1299
+ timestampMs: Date.now()
1300
+ };
1301
+ return emit(evt);
1302
+ };
1303
+ const policy = installation.definition.concurrency;
1304
+ const autoStart = installation.definition.triggers.some(
1305
+ (t) => t.kind === "platformEvent" && t.platformEvent === RUNTIME_BOOT_EVENT
1306
+ );
1307
+ const bootTriggerSpec = installation.definition.triggers.find(
1308
+ (t) => t.kind === "platformEvent" && t.platformEvent === RUNTIME_BOOT_EVENT
1309
+ );
1310
+ const instanceProgram = Effect4.gen(function* () {
1311
+ const fatal = yield* Deferred.make();
1312
+ const platformEventStream = Stream2.fromQueue(
1313
+ instanceState.platformTriggersQueue
1314
+ );
1315
+ const streams = yield* Effect4.forEach(
1316
+ installation.definition.triggers.filter((t) => t.kind !== "platformEvent"),
1317
+ makeTriggerStream
1318
+ );
1319
+ const triggerStream = Stream2.mergeAll([platformEventStream, ...streams], {
1320
+ concurrency: "unbounded"
1321
+ });
1322
+ const reportQueueOverflow = (info) => {
1323
+ const err = new Error("Process trigger queue overflow (serial maxQueue guard).");
1324
+ err.code = "process::serial_queue_overflow";
1325
+ err.hint = [
1326
+ `mode=${info.mode}`,
1327
+ `queue: current=${info.currentLength} peak=${info.peak}`,
1328
+ `maxQueue: configured=${info.limit.configured} guard=${info.limit.guard}`,
1329
+ `policy: ${JSON.stringify(info.policy)}`,
1330
+ "",
1331
+ "fix:",
1332
+ "- Configure concurrency.maxQueue (serial) to a finite value, or switch to mode=latest/drop to avoid unbounded backlog."
1333
+ ].join("\n");
1334
+ return Deferred.succeed(fatal, Cause.fail(err)).pipe(Effect4.asVoid, Effect4.catchAll(() => Effect4.void));
1335
+ };
1336
+ const runnerFiber = yield* Effect4.forkScoped(
1337
+ runProcessTriggerStream({
1338
+ stream: triggerStream,
1339
+ policy,
1340
+ assignTriggerSeq,
1341
+ run: (trigger) => makeChainRun(trigger, fatal),
1342
+ onDrop: (trigger) => emitTriggerEvent(trigger, "warning"),
1343
+ onQueueOverflow: reportQueueOverflow
1344
+ })
1345
+ );
1346
+ if (autoStart) {
1347
+ yield* Queue.offer(instanceState.platformTriggersQueue, {
1348
+ kind: "platformEvent",
1349
+ name: bootTriggerSpec?.name,
1350
+ platformEvent: RUNTIME_BOOT_EVENT
1351
+ });
1352
+ }
1353
+ const cause = yield* Deferred.await(fatal);
1354
+ yield* Fiber2.interrupt(runnerFiber);
1355
+ return yield* Effect4.failCause(cause);
1356
+ });
1357
+ const fiber = yield* Effect4.forkIn(installation.forkScope)(
1358
+ Effect4.scoped(instanceProgram).pipe(
1359
+ Effect4.catchAllCause(
1360
+ (cause) => Effect4.gen(function* () {
1361
+ if (Cause.isInterruptedOnly(cause)) {
1362
+ if (instanceState.status.status === "stopping") {
1363
+ return;
1364
+ }
1365
+ instanceState.status = {
1366
+ ...instanceState.status,
1367
+ status: "stopped",
1368
+ stoppedReason: "scopeDisposed"
1369
+ };
1370
+ instanceState.fiber = void 0;
1371
+ yield* emit({
1372
+ type: "process:stop",
1373
+ identity,
1374
+ severity: "info",
1375
+ eventSeq: instanceState.nextEventSeq++,
1376
+ timestampMs: Date.now()
1377
+ });
1378
+ return;
1379
+ }
1380
+ const primary = Option3.getOrElse(
1381
+ Cause.failureOption(cause),
1382
+ () => Option3.getOrElse(Cause.dieOption(cause), () => cause)
1383
+ );
1384
+ const summary = toSerializableErrorSummary(primary);
1385
+ const error = summary.errorSummary;
1386
+ instanceState.status = {
1387
+ ...instanceState.status,
1388
+ status: "failed",
1389
+ stoppedReason: "failed",
1390
+ lastError: error
1391
+ };
1392
+ yield* emit({
1393
+ type: "process:error",
1394
+ identity,
1395
+ severity: "error",
1396
+ eventSeq: instanceState.nextEventSeq++,
1397
+ timestampMs: Date.now(),
1398
+ error
1399
+ });
1400
+ const decision = onFailure(
1401
+ installation.definition.errorPolicy,
1402
+ installation.supervision,
1403
+ Date.now()
1404
+ );
1405
+ installation.supervision = decision.nextState;
1406
+ if (decision.decision === "restart") {
1407
+ yield* emit({
1408
+ type: "process:restart",
1409
+ identity,
1410
+ severity: "warning",
1411
+ eventSeq: instanceState.nextEventSeq++,
1412
+ timestampMs: Date.now(),
1413
+ error
1414
+ });
1415
+ yield* startInstallation(installationKey);
1416
+ } else {
1417
+ yield* emitErrorDiagnostic(
1418
+ installation.identity.scope,
1419
+ installation.identity.processId,
1420
+ "process::failed_stop",
1421
+ "Process failed and stopped (failStop / restart limit reached).",
1422
+ `processId=${installation.identity.processId} scopeKey=${installation.scopeKey} failures=${decision.withinWindowFailures} maxRestarts=${decision.maxRestarts}`
1423
+ );
1424
+ }
1425
+ })
1426
+ )
1427
+ )
1428
+ );
1429
+ instanceState.fiber = fiber;
1430
+ instanceState.status = {
1431
+ ...instanceState.status,
1432
+ status: "running"
1433
+ };
1434
+ yield* Effect4.yieldNow();
1435
+ });
1436
+ const install = (process, options2) => Effect4.gen(function* () {
1437
+ const meta = getMeta(process);
1438
+ if (!meta) {
1439
+ return void 0;
1440
+ }
1441
+ const env = yield* Effect4.context();
1442
+ const forkScopeOpt = Context3.getOption(env, Scope2.Scope);
1443
+ const forkScope = Option3.isSome(forkScopeOpt) ? forkScopeOpt.value : runtimeScope;
1444
+ const scopeKey = scopeKeyFromScope(options2.scope);
1445
+ const identity = {
1446
+ processId: meta.definition.processId,
1447
+ scope: options2.scope
1448
+ };
1449
+ const installationKey = installationKeyFromIdentity(identity);
1450
+ const existing = installations.get(installationKey);
1451
+ if (existing) {
1452
+ existing.enabled = options2.enabled ?? true;
1453
+ existing.installedAt = options2.installedAt ?? existing.installedAt;
1454
+ if (existing.enabled && !existing.currentInstanceId) {
1455
+ yield* startInstallation(installationKey);
1456
+ }
1457
+ return {
1458
+ identity,
1459
+ enabled: existing.enabled,
1460
+ installedAt: existing.installedAt
1461
+ };
1462
+ }
1463
+ const derived = Effect4.suspend(() => process);
1464
+ attachMeta(derived, {
1465
+ ...meta,
1466
+ installationScope: options2.scope
1467
+ });
1468
+ const installation = {
1469
+ identity,
1470
+ scopeKey,
1471
+ definition: meta.definition,
1472
+ env,
1473
+ forkScope,
1474
+ process: derived,
1475
+ kind: meta.kind ?? "process",
1476
+ enabled: options2.enabled ?? true,
1477
+ installedAt: options2.installedAt,
1478
+ nextRunSeq: 1,
1479
+ supervision: initialState()
1480
+ };
1481
+ installations.set(installationKey, installation);
1482
+ if (installation.enabled) {
1483
+ yield* startInstallation(installationKey);
1484
+ }
1485
+ return {
1486
+ identity,
1487
+ enabled: installation.enabled,
1488
+ installedAt: installation.installedAt
1489
+ };
1490
+ });
1491
+ const listInstallations = (filter) => Effect4.sync(() => {
1492
+ const scopeType = filter?.scopeType;
1493
+ const scopeKey = filter?.scopeKey;
1494
+ const out = [];
1495
+ for (const installation of installations.values()) {
1496
+ if (scopeType && installation.identity.scope.type !== scopeType) continue;
1497
+ if (scopeKey && installation.scopeKey !== scopeKey) continue;
1498
+ out.push({
1499
+ identity: installation.identity,
1500
+ enabled: installation.enabled,
1501
+ installedAt: installation.installedAt
1502
+ });
1503
+ }
1504
+ return out;
1505
+ });
1506
+ const getInstanceStatus = (processInstanceId) => Effect4.sync(() => instances.get(processInstanceId)?.status);
1507
+ const controlInstance = (processInstanceId, request) => Effect4.suspend(() => {
1508
+ const instance = instances.get(processInstanceId);
1509
+ if (!instance) {
1510
+ return Effect4.void;
1511
+ }
1512
+ return shouldNoopDueToSyncTxn(instance.scope, "process_control_in_transaction").pipe(
1513
+ Effect4.flatMap((noop) => {
1514
+ if (noop) {
1515
+ return Effect4.void;
1516
+ }
1517
+ if (request.action === "stop") {
1518
+ return stopInstance(instance, "manualStop");
1519
+ }
1520
+ if (request.action === "restart") {
1521
+ return stopInstance(instance, "manualStop").pipe(
1522
+ Effect4.flatMap(() => {
1523
+ const installation = installations.get(instance.installationKey);
1524
+ if (!installation) {
1525
+ return Effect4.void;
1526
+ }
1527
+ installation.currentInstanceId = void 0;
1528
+ return startInstallation(instance.installationKey);
1529
+ })
1530
+ );
1531
+ }
1532
+ if (request.action === "start") {
1533
+ if (instance.status.status === "running" || instance.status.status === "starting") {
1534
+ return Effect4.void;
1535
+ }
1536
+ const installation = installations.get(instance.installationKey);
1537
+ if (!installation) {
1538
+ return Effect4.void;
1539
+ }
1540
+ installation.currentInstanceId = void 0;
1541
+ return startInstallation(instance.installationKey);
1542
+ }
1543
+ return Effect4.void;
1544
+ })
1545
+ );
1546
+ });
1547
+ const deliverPlatformEvent = (event) => Effect4.gen(function* () {
1548
+ const noop = yield* shouldNoopInSyncTransactionFiber({
1549
+ code: "process::invalid_usage",
1550
+ severity: "error",
1551
+ message: "ProcessRuntime platform events are not allowed inside a synchronous StateTransaction body (it may deadlock the txnQueue).",
1552
+ hint: "Deliver platformEvent outside the transaction window.",
1553
+ kind: "process_platform_event_in_transaction"
1554
+ });
1555
+ if (noop) return;
1556
+ const targets = Array.from(instances.values());
1557
+ const eventName = event.eventName;
1558
+ yield* Effect4.forEach(
1559
+ targets,
1560
+ (instance) => Effect4.suspend(() => {
1561
+ if (instance.status.status !== "starting" && instance.status.status !== "running") {
1562
+ return Effect4.void;
1563
+ }
1564
+ const installation = installations.get(instance.installationKey);
1565
+ if (!installation) {
1566
+ return Effect4.void;
1567
+ }
1568
+ const specs = installation.definition.triggers.filter(
1569
+ (t) => t.kind === "platformEvent" && t.platformEvent === eventName
1570
+ );
1571
+ if (specs.length === 0) {
1572
+ return Effect4.void;
1573
+ }
1574
+ return Effect4.forEach(
1575
+ specs,
1576
+ (spec) => Queue.offer(instance.platformTriggersQueue, {
1577
+ kind: "platformEvent",
1578
+ name: spec.name,
1579
+ platformEvent: spec.platformEvent
1580
+ }),
1581
+ { discard: true }
1582
+ );
1583
+ }),
1584
+ { discard: true }
1585
+ );
1586
+ });
1587
+ const eventsStream = Stream2.fromPubSub(eventsHub);
1588
+ const getEventsSnapshot = () => Effect4.sync(() => eventsBuffer.slice());
1589
+ yield* Effect4.addFinalizer(
1590
+ () => Effect4.gen(function* () {
1591
+ for (const instance of instances.values()) {
1592
+ if (instance.fiber) {
1593
+ yield* stopInstance(instance, "scopeDisposed");
1594
+ }
1595
+ }
1596
+ }).pipe(
1597
+ Effect4.catchAllCause(
1598
+ (cause) => Effect4.sync(() => {
1599
+ if (isDevEnv()) {
1600
+ console.warn("[ProcessRuntime] finalizer failed", Cause.pretty(cause));
1601
+ }
1602
+ })
1603
+ )
1604
+ )
1605
+ );
1606
+ return {
1607
+ install,
1608
+ listInstallations,
1609
+ getInstanceStatus,
1610
+ controlInstance,
1611
+ deliverPlatformEvent,
1612
+ events: eventsStream,
1613
+ getEventsSnapshot
1614
+ };
1615
+ });
1616
+ var layer = (options) => Layer2.scoped(ProcessRuntimeTag, make(options));
1617
+
1618
+ export {
1619
+ RuntimeServicesInstanceOverridesTag,
1620
+ resolveRuntimeServicesOverrides,
1621
+ selectRuntimeService,
1622
+ makeRuntimeServicesEvidence,
1623
+ setRuntimeServicesEvidence,
1624
+ getRuntimeServicesEvidence,
1625
+ EvidenceCollectorTag,
1626
+ evidenceCollectorLayer,
1627
+ makeEvidenceCollector,
1628
+ getMeta,
1629
+ getDefinition,
1630
+ attachMeta,
1631
+ ProcessRuntimeTag,
1632
+ layer
1633
+ };
1634
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vbG9naXgtY29yZS9zcmMvaW50ZXJuYWwvcnVudGltZS9jb3JlL3Byb2Nlc3MvbWV0YS50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9ydW50aW1lL2NvcmUvUnVudGltZUtlcm5lbC50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9vYnNlcnZhYmlsaXR5L2V2aWRlbmNlQ29sbGVjdG9yLnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9wcm9jZXNzL1Byb2Nlc3NSdW50aW1lLnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9wcm9jZXNzL2lkZW50aXR5LnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9wcm9jZXNzL2NvbmN1cnJlbmN5LnRzIiwgIi4uLy4uLy4uLy4uL2xvZ2l4LWNvcmUvc3JjL2ludGVybmFsL3J1bnRpbWUvY29yZS9wcm9jZXNzL2V2ZW50cy50cyIsICIuLi8uLi8uLi8uLi9sb2dpeC1jb3JlL3NyYy9pbnRlcm5hbC9ydW50aW1lL2NvcmUvcHJvY2Vzcy9zdXBlcnZpc2lvbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHR5cGUgeyBFZmZlY3QgfSBmcm9tIFwiZWZmZWN0XCJcbmltcG9ydCB0eXBlIHsgUHJvY2Vzc0RlZmluaXRpb24sIFByb2Nlc3NTY29wZSB9IGZyb20gXCIuL3Byb3RvY29sLmpzXCJcblxuZXhwb3J0IHR5cGUgUHJvY2Vzc01ldGEgPSB7XG4gIHJlYWRvbmx5IGRlZmluaXRpb246IFByb2Nlc3NEZWZpbml0aW9uXG4gIC8qKlxuICAgKiBpbnN0YWxsYXRpb25TY29wZVx1RkYxQVN0YXRpYyBJUiBcdTc2ODRcdTRFMDBcdTkwRThcdTUyMDZcdTMwMDJcbiAgICogLSBcdTVCRjlcdTRFOEUgaW5zdGFuY2Utc2NvcGUgLyBzdWJ0cmVlLXNjb3BlIFx1N0I0OVx1NTczQVx1NjY2Rlx1RkYwQ1x1OEZEMFx1ODg0Q1x1NjVGNlx1NEYxQVx1NTcyOFx1NUI4OVx1ODhDNVx1NjVGNlx1NzUyOFx1MjAxQ1x1NkQzRVx1NzUxRiBlZmZlY3RcdTIwMURcdTg5ODZcdTc2RDZcdThCRTVcdTVCNTdcdTZCQjVcdUZGMUJcbiAgICogLSBcdThCRTVcdTVCNTdcdTZCQjVcdTRFQzVcdTc1MjhcdTRFOEVcdTVCRkNcdTUxRkEvXHU4QkNBXHU2NUFEXHVGRjBDXHU0RTBEXHU1M0MyXHU0RTBFXHU3QTMzXHU1QjlBXHU4RUFCXHU0RUZEXHU2RDNFXHU3NTFGXHVGRjA4XHU4RUFCXHU0RUZEXHU2RDNFXHU3NTFGXHU1NzI4IGlkZW50aXR5LnRzIFx1NUI4Q1x1NjIxMFx1RkYwOVx1MzAwMlxuICAgKi9cbiAgcmVhZG9ubHkgaW5zdGFsbGF0aW9uU2NvcGU/OiBQcm9jZXNzU2NvcGVcbiAgcmVhZG9ubHkga2luZD86IFwicHJvY2Vzc1wiIHwgXCJsaW5rXCJcbn1cblxuZXhwb3J0IGNvbnN0IFBST0NFU1NfTUVUQSA9IFN5bWJvbC5mb3IoXCJAbG9naXgvY29yZS9wcm9jZXNzTWV0YVwiKVxuXG5leHBvcnQgdHlwZSBQcm9jZXNzRWZmZWN0PEUgPSBuZXZlciwgUiA9IG5ldmVyPiA9IEVmZmVjdC5FZmZlY3Q8dm9pZCwgRSwgUj4gJiB7XG4gIHJlYWRvbmx5IFtQUk9DRVNTX01FVEFdPzogUHJvY2Vzc01ldGFcbn1cblxuY29uc3QgZGVmaW5lSGlkZGVuID0gKHRhcmdldDogb2JqZWN0LCBrZXk6IHN5bWJvbCwgdmFsdWU6IHVua25vd24pOiB2b2lkID0+IHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCB7XG4gICAgdmFsdWUsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgfSlcbn1cblxuZXhwb3J0IGNvbnN0IGdldE1ldGEgPSAoZWZmZWN0OiBFZmZlY3QuRWZmZWN0PHZvaWQsIGFueSwgYW55Pik6IFByb2Nlc3NNZXRhIHwgdW5kZWZpbmVkID0+XG4gIChlZmZlY3QgYXMgUHJvY2Vzc0VmZmVjdClbUFJPQ0VTU19NRVRBXVxuXG5leHBvcnQgY29uc3QgZ2V0RGVmaW5pdGlvbiA9IChcbiAgZWZmZWN0OiBFZmZlY3QuRWZmZWN0PHZvaWQsIGFueSwgYW55Pixcbik6IFByb2Nlc3NEZWZpbml0aW9uIHwgdW5kZWZpbmVkID0+IGdldE1ldGEoZWZmZWN0KT8uZGVmaW5pdGlvblxuXG5leHBvcnQgY29uc3QgYXR0YWNoTWV0YSA9IDxFLCBSPihcbiAgZWZmZWN0OiBFZmZlY3QuRWZmZWN0PHZvaWQsIEUsIFI+LFxuICBtZXRhOiBQcm9jZXNzTWV0YSxcbik6IFByb2Nlc3NFZmZlY3Q8RSwgUj4gPT4ge1xuICBkZWZpbmVIaWRkZW4oZWZmZWN0IGFzIGFueSwgUFJPQ0VTU19NRVRBLCBtZXRhKVxuICByZXR1cm4gZWZmZWN0IGFzIFByb2Nlc3NFZmZlY3Q8RSwgUj5cbn1cblxuIiwgImltcG9ydCB7IENvbnRleHQsIEVmZmVjdCwgT3B0aW9uIH0gZnJvbSBcImVmZmVjdFwiXG5pbXBvcnQgeyBpc0RldkVudiB9IGZyb20gXCIuL2Vudi5qc1wiXG5cbmV4cG9ydCB0eXBlIE92ZXJyaWRlU2NvcGUgPVxuICB8IFwiYnVpbHRpblwiXG4gIHwgXCJydW50aW1lX2RlZmF1bHRcIlxuICB8IFwicnVudGltZV9tb2R1bGVcIlxuICB8IFwicHJvdmlkZXJcIlxuICB8IFwiaW5zdGFuY2VcIlxuXG5leHBvcnQgdHlwZSBSdW50aW1lU2VydmljZU92ZXJyaWRlID0ge1xuICByZWFkb25seSBpbXBsSWQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkgbm90ZXM/OiBzdHJpbmdcbn1cblxuLyoqXG4gKiBSdW50aW1lU2VydmljZXNPdmVycmlkZXNcdUZGMUFcdTUzRUZcdTVFOEZcdTUyMTdcdTUzMTZcdTc2ODRcdTIwMUNcdTY3MERcdTUyQTFcdTVCOUVcdTczQjBcdTkwMDlcdTYyRTlcdTIwMURcdTg5ODZcdTUxOTlcdTMwMDJcbiAqXG4gKiAtIGtleSBcdTRFM0FcdTdBMzNcdTVCOUEgc2VydmljZUlkXHVGRjFCXG4gKiAtIHZhbHVlIFx1NEVDNVx1NTE0MVx1OEJCOFx1NTMwNVx1NTQyQlx1NTNFRlx1NUU4Rlx1NTIxN1x1NTMxNlx1NUI1N1x1NkJCNVx1RkYwOFx1Nzk4MVx1NkI2Mlx1NTFGRFx1NjU3MC9cdTk1RURcdTUzMDVcdUZGMDlcdUZGMENcdTRFRTVcdTRGQkZcdTc1MUZcdTYyMTBcdTUzRUZcdTg5RTNcdTkxQ0FcdThCQzFcdTYzNkVcdTMwMDJcbiAqL1xuZXhwb3J0IHR5cGUgUnVudGltZVNlcnZpY2VzT3ZlcnJpZGVzID0gUmVhZG9ubHk8XG4gIFJlY29yZDxzdHJpbmcsIFJ1bnRpbWVTZXJ2aWNlT3ZlcnJpZGU+XG4+XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVudGltZVNlcnZpY2VzUnVudGltZUNvbmZpZyB7XG4gIC8qKiBSdW50aW1lIFx1N0VBN1x1OUVEOFx1OEJBNFx1ODk4Nlx1NTE5OVx1RkYwOHJ1bnRpbWVfZGVmYXVsdFx1RkYwOVx1MzAwMiAqL1xuICByZWFkb25seSBzZXJ2aWNlcz86IFJ1bnRpbWVTZXJ2aWNlc092ZXJyaWRlc1xuICAvKiogXHU2MzA5IG1vZHVsZUlkIFx1NzY4NFx1NURFRVx1OTFDRlx1ODk4Nlx1NTE5OVx1RkYwOHJ1bnRpbWVfbW9kdWxlXHVGRjA5XHUzMDAyICovXG4gIHJlYWRvbmx5IHNlcnZpY2VzQnlNb2R1bGVJZD86IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIFJ1bnRpbWVTZXJ2aWNlc092ZXJyaWRlcz4+XG59XG5cbmNsYXNzIFJ1bnRpbWVTZXJ2aWNlc1J1bnRpbWVDb25maWdUYWdJbXBsIGV4dGVuZHMgQ29udGV4dC5UYWcoXG4gIFwiQGxvZ2l4L2NvcmUvUnVudGltZVNlcnZpY2VzUnVudGltZUNvbmZpZ1wiLFxuKTxSdW50aW1lU2VydmljZXNSdW50aW1lQ29uZmlnVGFnSW1wbCwgUnVudGltZVNlcnZpY2VzUnVudGltZUNvbmZpZz4oKSB7fVxuXG5leHBvcnQgY29uc3QgUnVudGltZVNlcnZpY2VzUnVudGltZUNvbmZpZ1RhZyA9IFJ1bnRpbWVTZXJ2aWNlc1J1bnRpbWVDb25maWdUYWdJbXBsXG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVudGltZVNlcnZpY2VzUHJvdmlkZXJPdmVycmlkZXMge1xuICAvKiogUHJvdmlkZXIgXHU4MzAzXHU1NkY0XHU5RUQ4XHU4QkE0XHU4OTg2XHU1MTk5XHVGRjA4cHJvdmlkZXJcdUZGMDlcdTMwMDIgKi9cbiAgcmVhZG9ubHkgc2VydmljZXM/OiBSdW50aW1lU2VydmljZXNPdmVycmlkZXNcbiAgLyoqIFByb3ZpZGVyIFx1ODMwM1x1NTZGNFx1NjMwOSBtb2R1bGVJZCBcdTc2ODRcdTVERUVcdTkxQ0ZcdTg5ODZcdTUxOTlcdUZGMDhwcm92aWRlclx1RkYwOVx1MzAwMiAqL1xuICByZWFkb25seSBzZXJ2aWNlc0J5TW9kdWxlSWQ/OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBSdW50aW1lU2VydmljZXNPdmVycmlkZXM+PlxufVxuXG5jbGFzcyBSdW50aW1lU2VydmljZXNQcm92aWRlck92ZXJyaWRlc1RhZ0ltcGwgZXh0ZW5kcyBDb250ZXh0LlRhZyhcbiAgXCJAbG9naXgvY29yZS9SdW50aW1lU2VydmljZXNQcm92aWRlck92ZXJyaWRlc1wiLFxuKTxSdW50aW1lU2VydmljZXNQcm92aWRlck92ZXJyaWRlc1RhZ0ltcGwsIFJ1bnRpbWVTZXJ2aWNlc1Byb3ZpZGVyT3ZlcnJpZGVzPigpIHt9XG5cbmV4cG9ydCBjb25zdCBSdW50aW1lU2VydmljZXNQcm92aWRlck92ZXJyaWRlc1RhZyA9IFJ1bnRpbWVTZXJ2aWNlc1Byb3ZpZGVyT3ZlcnJpZGVzVGFnSW1wbFxuXG5jbGFzcyBSdW50aW1lU2VydmljZXNJbnN0YW5jZU92ZXJyaWRlc1RhZ0ltcGwgZXh0ZW5kcyBDb250ZXh0LlRhZyhcbiAgXCJAbG9naXgvY29yZS9SdW50aW1lU2VydmljZXNJbnN0YW5jZU92ZXJyaWRlc1wiLFxuKTxSdW50aW1lU2VydmljZXNJbnN0YW5jZU92ZXJyaWRlc1RhZ0ltcGwsIFJ1bnRpbWVTZXJ2aWNlc092ZXJyaWRlcz4oKSB7fVxuXG5leHBvcnQgY29uc3QgUnVudGltZVNlcnZpY2VzSW5zdGFuY2VPdmVycmlkZXNUYWcgPSBSdW50aW1lU2VydmljZXNJbnN0YW5jZU92ZXJyaWRlc1RhZ0ltcGxcblxuZXhwb3J0IGludGVyZmFjZSBSdW50aW1lU2VydmljZUJpbmRpbmcge1xuICByZWFkb25seSBzZXJ2aWNlSWQ6IHN0cmluZ1xuICByZWFkb25seSBpbXBsSWQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkgaW1wbFZlcnNpb24/OiBzdHJpbmdcbiAgcmVhZG9ubHkgc2NvcGU6IE92ZXJyaWRlU2NvcGVcbiAgcmVhZG9ubHkgb3ZlcnJpZGRlbjogYm9vbGVhblxuICByZWFkb25seSBub3Rlcz86IHN0cmluZ1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJ1bnRpbWVTZXJ2aWNlc0V2aWRlbmNlIHtcbiAgcmVhZG9ubHkgbW9kdWxlSWQ/OiBzdHJpbmdcbiAgcmVhZG9ubHkgaW5zdGFuY2VJZDogc3RyaW5nXG4gIHJlYWRvbmx5IHNjb3BlOiBPdmVycmlkZVNjb3BlXG4gIHJlYWRvbmx5IGJpbmRpbmdzOiBSZWFkb25seUFycmF5PFJ1bnRpbWVTZXJ2aWNlQmluZGluZz5cbiAgcmVhZG9ubHkgb3ZlcnJpZGVzQXBwbGllZDogUmVhZG9ubHlBcnJheTxzdHJpbmc+XG59XG5cbmNvbnN0IE9SREVSRURfU0NPUEVTOiBSZWFkb25seUFycmF5PE92ZXJyaWRlU2NvcGU+ID0gW1xuICBcImJ1aWx0aW5cIixcbiAgXCJydW50aW1lX2RlZmF1bHRcIixcbiAgXCJydW50aW1lX21vZHVsZVwiLFxuICBcInByb3ZpZGVyXCIsXG4gIFwiaW5zdGFuY2VcIixcbl1cblxuY29uc3QgbWF4U2NvcGUgPSAoYTogT3ZlcnJpZGVTY29wZSwgYjogT3ZlcnJpZGVTY29wZSk6IE92ZXJyaWRlU2NvcGUgPT4ge1xuICBjb25zdCBhaSA9IE9SREVSRURfU0NPUEVTLmluZGV4T2YoYSlcbiAgY29uc3QgYmkgPSBPUkRFUkVEX1NDT1BFUy5pbmRleE9mKGIpXG4gIHJldHVybiAoYWkgPj0gYmkgPyBhIDogYikgYXMgT3ZlcnJpZGVTY29wZVxufVxuXG5jb25zdCBpc1BsYWluUmVjb3JkID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPT5cbiAgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIHZhbHVlICE9PSBudWxsICYmICFBcnJheS5pc0FycmF5KHZhbHVlKVxuXG5jb25zdCBub3JtYWxpemVPdmVycmlkZSA9ICh2YWx1ZTogdW5rbm93bik6IFJ1bnRpbWVTZXJ2aWNlT3ZlcnJpZGUgfCB1bmRlZmluZWQgPT4ge1xuICBpZiAoIWlzUGxhaW5SZWNvcmQodmFsdWUpKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgY29uc3QgaW1wbElkUmF3ID0gdmFsdWUuaW1wbElkXG4gIGNvbnN0IG5vdGVzUmF3ID0gdmFsdWUubm90ZXNcblxuICByZXR1cm4ge1xuICAgIGltcGxJZDogdHlwZW9mIGltcGxJZFJhdyA9PT0gXCJzdHJpbmdcIiAmJiBpbXBsSWRSYXcubGVuZ3RoID4gMCA/IGltcGxJZFJhdyA6IHVuZGVmaW5lZCxcbiAgICBub3RlczogdHlwZW9mIG5vdGVzUmF3ID09PSBcInN0cmluZ1wiICYmIG5vdGVzUmF3Lmxlbmd0aCA+IDAgPyBub3Rlc1JhdyA6IHVuZGVmaW5lZCxcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgcmVzb2x2ZVJ1bnRpbWVTZXJ2aWNlc092ZXJyaWRlcyA9IChhcmdzOiB7XG4gIHJlYWRvbmx5IG1vZHVsZUlkOiBzdHJpbmcgfCB1bmRlZmluZWRcbn0pOiBFZmZlY3QuRWZmZWN0PFxuICB7XG4gICAgcmVhZG9ubHkgcnVudGltZURlZmF1bHQ/OiBSdW50aW1lU2VydmljZXNPdmVycmlkZXNcbiAgICByZWFkb25seSBydW50aW1lTW9kdWxlPzogUnVudGltZVNlcnZpY2VzT3ZlcnJpZGVzXG4gICAgcmVhZG9ubHkgcHJvdmlkZXI/OiBSdW50aW1lU2VydmljZXNPdmVycmlkZXNcbiAgICByZWFkb25seSBwcm92aWRlck1vZHVsZT86IFJ1bnRpbWVTZXJ2aWNlc092ZXJyaWRlc1xuICAgIHJlYWRvbmx5IGluc3RhbmNlPzogUnVudGltZVNlcnZpY2VzT3ZlcnJpZGVzXG4gIH0sXG4gIG5ldmVyLFxuICBhbnlcbj4gPT5cbiAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgIGNvbnN0IHJ1bnRpbWVDb25maWdPcHQgPSB5aWVsZCogRWZmZWN0LnNlcnZpY2VPcHRpb24oXG4gICAgICBSdW50aW1lU2VydmljZXNSdW50aW1lQ29uZmlnVGFnLFxuICAgIClcbiAgICBjb25zdCBwcm92aWRlck92ZXJyaWRlc09wdCA9IHlpZWxkKiBFZmZlY3Quc2VydmljZU9wdGlvbihcbiAgICAgIFJ1bnRpbWVTZXJ2aWNlc1Byb3ZpZGVyT3ZlcnJpZGVzVGFnLFxuICAgIClcbiAgICBjb25zdCBpbnN0YW5jZU92ZXJyaWRlc09wdCA9IHlpZWxkKiBFZmZlY3Quc2VydmljZU9wdGlvbihcbiAgICAgIFJ1bnRpbWVTZXJ2aWNlc0luc3RhbmNlT3ZlcnJpZGVzVGFnLFxuICAgIClcblxuICAgIGNvbnN0IHJ1bnRpbWVDb25maWcgPSBPcHRpb24uaXNTb21lKHJ1bnRpbWVDb25maWdPcHQpXG4gICAgICA/IHJ1bnRpbWVDb25maWdPcHQudmFsdWVcbiAgICAgIDogdW5kZWZpbmVkXG4gICAgY29uc3QgcHJvdmlkZXJPdmVycmlkZXMgPSBPcHRpb24uaXNTb21lKHByb3ZpZGVyT3ZlcnJpZGVzT3B0KVxuICAgICAgPyBwcm92aWRlck92ZXJyaWRlc09wdC52YWx1ZVxuICAgICAgOiB1bmRlZmluZWRcbiAgICBjb25zdCBpbnN0YW5jZU92ZXJyaWRlcyA9IE9wdGlvbi5pc1NvbWUoaW5zdGFuY2VPdmVycmlkZXNPcHQpXG4gICAgICA/IGluc3RhbmNlT3ZlcnJpZGVzT3B0LnZhbHVlXG4gICAgICA6IHVuZGVmaW5lZFxuXG4gICAgY29uc3QgbW9kdWxlSWQgPSBhcmdzLm1vZHVsZUlkXG5cbiAgICBjb25zdCBydW50aW1lTW9kdWxlID1cbiAgICAgIG1vZHVsZUlkICYmIHJ1bnRpbWVDb25maWc/LnNlcnZpY2VzQnlNb2R1bGVJZFxuICAgICAgICA/IHJ1bnRpbWVDb25maWcuc2VydmljZXNCeU1vZHVsZUlkW21vZHVsZUlkXVxuICAgICAgICA6IHVuZGVmaW5lZFxuXG4gICAgY29uc3QgcHJvdmlkZXJNb2R1bGUgPVxuICAgICAgbW9kdWxlSWQgJiYgcHJvdmlkZXJPdmVycmlkZXM/LnNlcnZpY2VzQnlNb2R1bGVJZFxuICAgICAgICA/IHByb3ZpZGVyT3ZlcnJpZGVzLnNlcnZpY2VzQnlNb2R1bGVJZFttb2R1bGVJZF1cbiAgICAgICAgOiB1bmRlZmluZWRcblxuICAgIHJldHVybiB7XG4gICAgICBydW50aW1lRGVmYXVsdDogcnVudGltZUNvbmZpZz8uc2VydmljZXMsXG4gICAgICBydW50aW1lTW9kdWxlLFxuICAgICAgcHJvdmlkZXI6IHByb3ZpZGVyT3ZlcnJpZGVzPy5zZXJ2aWNlcyxcbiAgICAgIHByb3ZpZGVyTW9kdWxlLFxuICAgICAgaW5zdGFuY2U6IGluc3RhbmNlT3ZlcnJpZGVzLFxuICAgIH1cbiAgfSlcblxuZXhwb3J0IGludGVyZmFjZSBSdW50aW1lU2VydmljZUltcGw8U2VydmljZT4ge1xuICByZWFkb25seSBpbXBsSWQ6IHN0cmluZ1xuICByZWFkb25seSBpbXBsVmVyc2lvbjogc3RyaW5nXG4gIHJlYWRvbmx5IG1ha2U6IEVmZmVjdC5FZmZlY3Q8U2VydmljZSwgbmV2ZXIsIGFueT5cbiAgcmVhZG9ubHkgbm90ZXM/OiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSdW50aW1lU2VydmljZVNlbGVjdGlvbjxTZXJ2aWNlPiB7XG4gIHJlYWRvbmx5IGJpbmRpbmc6IFJ1bnRpbWVTZXJ2aWNlQmluZGluZ1xuICByZWFkb25seSBpbXBsOiBSdW50aW1lU2VydmljZUltcGw8U2VydmljZT5cbiAgcmVhZG9ubHkgb3ZlcnJpZGVzQXBwbGllZDogUmVhZG9ubHlBcnJheTxzdHJpbmc+XG59XG5cbmV4cG9ydCBjb25zdCBzZWxlY3RSdW50aW1lU2VydmljZSA9IDxTZXJ2aWNlPihcbiAgc2VydmljZUlkOiBzdHJpbmcsXG4gIGltcGxzOiBSZWFkb25seUFycmF5PFJ1bnRpbWVTZXJ2aWNlSW1wbDxTZXJ2aWNlPj4sXG4gIG92ZXJyaWRlczoge1xuICAgIHJlYWRvbmx5IHJ1bnRpbWVEZWZhdWx0PzogUnVudGltZVNlcnZpY2VzT3ZlcnJpZGVzXG4gICAgcmVhZG9ubHkgcnVudGltZU1vZHVsZT86IFJ1bnRpbWVTZXJ2aWNlc092ZXJyaWRlc1xuICAgIHJlYWRvbmx5IHByb3ZpZGVyPzogUnVudGltZVNlcnZpY2VzT3ZlcnJpZGVzXG4gICAgcmVhZG9ubHkgcHJvdmlkZXJNb2R1bGU/OiBSdW50aW1lU2VydmljZXNPdmVycmlkZXNcbiAgICByZWFkb25seSBpbnN0YW5jZT86IFJ1bnRpbWVTZXJ2aWNlc092ZXJyaWRlc1xuICB9LFxuKTogUnVudGltZVNlcnZpY2VTZWxlY3Rpb248U2VydmljZT4gPT4ge1xuICBjb25zdCBidWlsdGluID0gaW1wbHNbMF1cbiAgaWYgKCFidWlsdGluKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBbTG9naXhdIFJ1bnRpbWVLZXJuZWwgcmVnaXN0cnkgbWlzc2luZyBidWlsdGluIGltcGwgZm9yOiAke3NlcnZpY2VJZH1gKVxuICB9XG5cbiAgbGV0IGRlc2lyZWQ6IHsgcmVhZG9ubHkgc2NvcGU6IE92ZXJyaWRlU2NvcGU7IHJlYWRvbmx5IG92ZXJyaWRlOiBSdW50aW1lU2VydmljZU92ZXJyaWRlIH0gfCB1bmRlZmluZWRcbiAgY29uc3QgY29uc2lkZXIgPSAoc2NvcGU6IE92ZXJyaWRlU2NvcGUsIHBhdGNoOiBSdW50aW1lU2VydmljZXNPdmVycmlkZXMgfCB1bmRlZmluZWQpOiB2b2lkID0+IHtcbiAgICBjb25zdCBuZXh0ID0gcGF0Y2ggPyBub3JtYWxpemVPdmVycmlkZShwYXRjaFtzZXJ2aWNlSWRdKSA6IHVuZGVmaW5lZFxuICAgIGlmICghbmV4dCB8fCAhbmV4dC5pbXBsSWQpIHJldHVyblxuICAgIGRlc2lyZWQgPSB7IHNjb3BlLCBvdmVycmlkZTogbmV4dCB9XG4gIH1cblxuICAvLyBwcmlvcml0eTogYnVpbHRpbiA8IHJ1bnRpbWVfZGVmYXVsdCA8IHJ1bnRpbWVfbW9kdWxlIDwgcHJvdmlkZXIgPCBpbnN0YW5jZVxuICBjb25zaWRlcihcInJ1bnRpbWVfZGVmYXVsdFwiLCBvdmVycmlkZXMucnVudGltZURlZmF1bHQpXG4gIGNvbnNpZGVyKFwicnVudGltZV9tb2R1bGVcIiwgb3ZlcnJpZGVzLnJ1bnRpbWVNb2R1bGUpXG4gIGNvbnNpZGVyKFwicHJvdmlkZXJcIiwgb3ZlcnJpZGVzLnByb3ZpZGVyKVxuICBjb25zaWRlcihcInByb3ZpZGVyXCIsIG92ZXJyaWRlcy5wcm92aWRlck1vZHVsZSlcbiAgY29uc2lkZXIoXCJpbnN0YW5jZVwiLCBvdmVycmlkZXMuaW5zdGFuY2UpXG5cbiAgaWYgKCFkZXNpcmVkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGltcGw6IGJ1aWx0aW4sXG4gICAgICBiaW5kaW5nOiB7XG4gICAgICAgIHNlcnZpY2VJZCxcbiAgICAgICAgaW1wbElkOiBidWlsdGluLmltcGxJZCxcbiAgICAgICAgaW1wbFZlcnNpb246IGJ1aWx0aW4uaW1wbFZlcnNpb24sXG4gICAgICAgIHNjb3BlOiBcImJ1aWx0aW5cIixcbiAgICAgICAgb3ZlcnJpZGRlbjogZmFsc2UsXG4gICAgICAgIG5vdGVzOiBidWlsdGluLm5vdGVzLFxuICAgICAgfSxcbiAgICAgIG92ZXJyaWRlc0FwcGxpZWQ6IFtdLFxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGRlc2lyZWRJbXBsSWQgPSBkZXNpcmVkLm92ZXJyaWRlLmltcGxJZCFcbiAgY29uc3Qgc2VsZWN0ZWQgPSBpbXBscy5maW5kKChpKSA9PiBpLmltcGxJZCA9PT0gZGVzaXJlZEltcGxJZClcbiAgY29uc3QgaW1wbCA9IHNlbGVjdGVkID8/IGJ1aWx0aW5cblxuICBjb25zdCBkaWRGYWxsYmFjayA9IHNlbGVjdGVkID09IG51bGxcbiAgY29uc3QgZmFsbGJhY2tOb3RlID1cbiAgICBkaWRGYWxsYmFja1xuICAgICAgPyBgVW5rbm93biBpbXBsSWQgXCIke2Rlc2lyZWRJbXBsSWR9XCIsIGZhbGxpbmcgYmFjayB0byBidWlsdGluIFwiJHtidWlsdGluLmltcGxJZH1cImBcbiAgICAgIDogdW5kZWZpbmVkXG5cbiAgY29uc3Qgbm90ZXMgPSBbZGVzaXJlZC5vdmVycmlkZS5ub3RlcywgaW1wbC5ub3RlcywgZmFsbGJhY2tOb3RlXVxuICAgIC5maWx0ZXIoKHMpOiBzIGlzIHN0cmluZyA9PiB0eXBlb2YgcyA9PT0gXCJzdHJpbmdcIiAmJiBzLmxlbmd0aCA+IDApXG4gICAgLmpvaW4oXCI7IFwiKVxuXG4gIHJldHVybiB7XG4gICAgaW1wbCxcbiAgICBiaW5kaW5nOiB7XG4gICAgICBzZXJ2aWNlSWQsXG4gICAgICBpbXBsSWQ6IGltcGwuaW1wbElkLFxuICAgICAgaW1wbFZlcnNpb246IGltcGwuaW1wbFZlcnNpb24sXG4gICAgICBzY29wZTogZGVzaXJlZC5zY29wZSxcbiAgICAgIG92ZXJyaWRkZW46IHRydWUsXG4gICAgICBub3Rlczogbm90ZXMubGVuZ3RoID4gMCA/IG5vdGVzIDogdW5kZWZpbmVkLFxuICAgIH0sXG4gICAgb3ZlcnJpZGVzQXBwbGllZDogW1xuICAgICAgZGlkRmFsbGJhY2tcbiAgICAgICAgPyBgJHtkZXNpcmVkLnNjb3BlfToke3NlcnZpY2VJZH09JHtkZXNpcmVkSW1wbElkfSAoZmFsbGJhY2s9JHtidWlsdGluLmltcGxJZH0pYFxuICAgICAgICA6IGAke2Rlc2lyZWQuc2NvcGV9OiR7c2VydmljZUlkfT0ke2Rlc2lyZWRJbXBsSWR9YCxcbiAgICBdLFxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBtYWtlUnVudGltZVNlcnZpY2VzRXZpZGVuY2UgPSAoYXJnczoge1xuICByZWFkb25seSBtb2R1bGVJZDogc3RyaW5nIHwgdW5kZWZpbmVkXG4gIHJlYWRvbmx5IGluc3RhbmNlSWQ6IHN0cmluZ1xuICByZWFkb25seSBiaW5kaW5nczogUmVhZG9ubHlBcnJheTxSdW50aW1lU2VydmljZUJpbmRpbmc+XG4gIHJlYWRvbmx5IG92ZXJyaWRlc0FwcGxpZWQ6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPlxufSk6IFJ1bnRpbWVTZXJ2aWNlc0V2aWRlbmNlID0+IHtcbiAgbGV0IHNjb3BlOiBPdmVycmlkZVNjb3BlID0gXCJidWlsdGluXCJcbiAgZm9yIChjb25zdCBiIG9mIGFyZ3MuYmluZGluZ3MpIHtcbiAgICBzY29wZSA9IG1heFNjb3BlKHNjb3BlLCBiLnNjb3BlKVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBtb2R1bGVJZDogYXJncy5tb2R1bGVJZCxcbiAgICBpbnN0YW5jZUlkOiBhcmdzLmluc3RhbmNlSWQsXG4gICAgc2NvcGUsXG4gICAgYmluZGluZ3M6IGFyZ3MuYmluZGluZ3MsXG4gICAgb3ZlcnJpZGVzQXBwbGllZDogYXJncy5vdmVycmlkZXNBcHBsaWVkLFxuICB9XG59XG5cbmNvbnN0IFJVTlRJTUVfU0VSVklDRVNfRVZJREVOQ0UgPSBTeW1ib2wuZm9yKFwiQGxvZ2l4L2NvcmUvcnVudGltZVNlcnZpY2VzRXZpZGVuY2VcIilcblxuY29uc3QgZGVmaW5lSGlkZGVuID0gKHRhcmdldDogb2JqZWN0LCBrZXk6IHN5bWJvbCwgdmFsdWU6IHVua25vd24pOiB2b2lkID0+IHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCB7XG4gICAgdmFsdWUsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgfSlcbn1cblxuY29uc3QgZm9ybWF0U2NvcGUgPSAobW9kdWxlSWQ6IHVua25vd24sIGluc3RhbmNlSWQ6IHVua25vd24pOiBzdHJpbmcgPT4ge1xuICBjb25zdCBtID0gdHlwZW9mIG1vZHVsZUlkID09PSBcInN0cmluZ1wiICYmIG1vZHVsZUlkLmxlbmd0aCA+IDAgPyBtb2R1bGVJZCA6IFwidW5rbm93blwiXG4gIGNvbnN0IGkgPSB0eXBlb2YgaW5zdGFuY2VJZCA9PT0gXCJzdHJpbmdcIiAmJiBpbnN0YW5jZUlkLmxlbmd0aCA+IDAgPyBpbnN0YW5jZUlkIDogXCJ1bmtub3duXCJcbiAgcmV0dXJuIGBtb2R1bGVJZD0ke219LCBpbnN0YW5jZUlkPSR7aX1gXG59XG5cbmV4cG9ydCBjb25zdCBzZXRSdW50aW1lU2VydmljZXNFdmlkZW5jZSA9IChydW50aW1lOiBvYmplY3QsIGV2aWRlbmNlOiBSdW50aW1lU2VydmljZXNFdmlkZW5jZSk6IHZvaWQgPT4ge1xuICBkZWZpbmVIaWRkZW4ocnVudGltZSwgUlVOVElNRV9TRVJWSUNFU19FVklERU5DRSwgZXZpZGVuY2UpXG59XG5cbmV4cG9ydCBjb25zdCBnZXRSdW50aW1lU2VydmljZXNFdmlkZW5jZSA9IChydW50aW1lOiBvYmplY3QpOiBSdW50aW1lU2VydmljZXNFdmlkZW5jZSA9PiB7XG4gIGNvbnN0IHNjb3BlID0gcnVudGltZSBhcyB7IHJlYWRvbmx5IG1vZHVsZUlkPzogdW5rbm93bjsgcmVhZG9ubHkgaW5zdGFuY2VJZD86IHVua25vd24gfVxuICBjb25zdCBldmlkZW5jZSA9IChydW50aW1lIGFzIGFueSlbUlVOVElNRV9TRVJWSUNFU19FVklERU5DRV0gYXMgUnVudGltZVNlcnZpY2VzRXZpZGVuY2UgfCB1bmRlZmluZWRcbiAgaWYgKCFldmlkZW5jZSkge1xuICAgIGNvbnN0IG1zZyA9IGlzRGV2RW52KClcbiAgICAgID8gW1xuICAgICAgICAgIFwiW01pc3NpbmdSdW50aW1lU2VydmljZXNFdmlkZW5jZV0gUnVudGltZSBzZXJ2aWNlcyBldmlkZW5jZSBub3QgaW5zdGFsbGVkIG9uIE1vZHVsZVJ1bnRpbWUgaW5zdGFuY2UuXCIsXG4gICAgICAgICAgYHNjb3BlOiAke2Zvcm1hdFNjb3BlKHNjb3BlLm1vZHVsZUlkLCBzY29wZS5pbnN0YW5jZUlkKX1gLFxuICAgICAgICAgIFwiZml4OlwiLFxuICAgICAgICAgIFwiLSBFbnN1cmUgTW9kdWxlUnVudGltZS5tYWtlIGFzc2VtYmxlcyBSdW50aW1lS2VybmVsIGFuZCBhdHRhY2hlcyBldmlkZW5jZSAoMDIwIFVTMikuXCIsXG4gICAgICAgICAgXCItIElmIHlvdSBjcmVhdGVkIGEgbW9jayBydW50aW1lIGZvciB0ZXN0cywgYXR0YWNoIGV2aWRlbmNlIG9yIGF2b2lkIGNhbGxpbmcgZXZpZGVuY2Utb25seSBBUElzLlwiLFxuICAgICAgICBdLmpvaW4oXCJcXG5cIilcbiAgICAgIDogXCJSdW50aW1lIHNlcnZpY2VzIGV2aWRlbmNlIG5vdCBpbnN0YWxsZWRcIlxuICAgIHRocm93IG5ldyBFcnJvcihtc2cpXG4gIH1cblxuICBjb25zdCBydW50aW1lSW5zdGFuY2VJZCA9IHNjb3BlLmluc3RhbmNlSWRcbiAgaWYgKFxuICAgIHR5cGVvZiBydW50aW1lSW5zdGFuY2VJZCA9PT0gXCJzdHJpbmdcIiAmJlxuICAgIHJ1bnRpbWVJbnN0YW5jZUlkLmxlbmd0aCA+IDAgJiZcbiAgICBydW50aW1lSW5zdGFuY2VJZCAhPT0gZXZpZGVuY2UuaW5zdGFuY2VJZFxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBpc0RldkVudigpXG4gICAgICAgID8gW1xuICAgICAgICAgICAgXCJbSW5jb25zaXN0ZW50UnVudGltZVNlcnZpY2VzRXZpZGVuY2VdIFJ1bnRpbWUgc2VydmljZXMgZXZpZGVuY2UgaW5zdGFuY2VJZCBtaXNtYXRjaC5cIixcbiAgICAgICAgICAgIGBydW50aW1lOiAke2Zvcm1hdFNjb3BlKHNjb3BlLm1vZHVsZUlkLCBydW50aW1lSW5zdGFuY2VJZCl9YCxcbiAgICAgICAgICAgIGBldmlkZW5jZTogJHtmb3JtYXRTY29wZShldmlkZW5jZS5tb2R1bGVJZCwgZXZpZGVuY2UuaW5zdGFuY2VJZCl9YCxcbiAgICAgICAgICBdLmpvaW4oXCJcXG5cIilcbiAgICAgICAgOiBcIlJ1bnRpbWUgc2VydmljZXMgZXZpZGVuY2UgbWlzbWF0Y2hcIixcbiAgICApXG4gIH1cblxuICByZXR1cm4gZXZpZGVuY2Vcbn1cbiIsICJpbXBvcnQgeyBDb250ZXh0LCBFZmZlY3QsIEZpYmVyUmVmLCBMYXllciB9IGZyb20gXCJlZmZlY3RcIlxuaW1wb3J0IHR5cGUgeyBKc29uVmFsdWUgfSBmcm9tIFwiLi9qc29uVmFsdWUuanNcIlxuaW1wb3J0IHsgcHJvamVjdEpzb25WYWx1ZSB9IGZyb20gXCIuL2pzb25WYWx1ZS5qc1wiXG5pbXBvcnQgdHlwZSB7IEV2aWRlbmNlUGFja2FnZSB9IGZyb20gXCIuL2V2aWRlbmNlLmpzXCJcbmltcG9ydCB0eXBlIHsgUnVuU2Vzc2lvbiB9IGZyb20gXCIuL3J1blNlc3Npb24uanNcIlxuaW1wb3J0IHsgbWFrZUV2aWRlbmNlU2luayB9IGZyb20gXCIuL3J1blNlc3Npb24uanNcIlxuaW1wb3J0IHtcbiAgY3VycmVudERpYWdub3N0aWNzTGV2ZWwsXG4gIHRvUnVudGltZURlYnVnRXZlbnRSZWYsXG4gIHR5cGUgRXZlbnQgYXMgRGVidWdFdmVudCxcbiAgdHlwZSBTaW5rIGFzIERlYnVnU2luayxcbn0gZnJvbSBcIi4uL3J1bnRpbWUvY29yZS9EZWJ1Z1NpbmsuanNcIlxuXG5leHBvcnQgaW50ZXJmYWNlIEV2aWRlbmNlQ29sbGVjdG9yIHtcbiAgcmVhZG9ubHkgc2Vzc2lvbjogUnVuU2Vzc2lvblxuICByZWFkb25seSBkZWJ1Z1Npbms6IERlYnVnU2lua1xuICByZWFkb25seSByZWdpc3RlckNvbnZlcmdlU3RhdGljSXI6IChzdGF0aWNJcjogdW5rbm93bikgPT4gdm9pZFxuICByZWFkb25seSBzZXRSdW50aW1lU2VydmljZXNFdmlkZW5jZTogKGV2aWRlbmNlOiB1bmtub3duKSA9PiB2b2lkXG4gIHJlYWRvbmx5IGV4cG9ydEV2aWRlbmNlUGFja2FnZTogKG9wdGlvbnM/OiB7IHJlYWRvbmx5IG1heEV2ZW50cz86IG51bWJlciB9KSA9PiBFdmlkZW5jZVBhY2thZ2VcbiAgcmVhZG9ubHkgY2xlYXI6ICgpID0+IHZvaWRcbn1cblxuY2xhc3MgRXZpZGVuY2VDb2xsZWN0b3JUYWdJbXBsIGV4dGVuZHMgQ29udGV4dC5UYWcoXG4gIFwiQGxvZ2l4L2NvcmUvRXZpZGVuY2VDb2xsZWN0b3JcIixcbik8RXZpZGVuY2VDb2xsZWN0b3JUYWdJbXBsLCBFdmlkZW5jZUNvbGxlY3Rvcj4oKSB7fVxuXG5leHBvcnQgY29uc3QgRXZpZGVuY2VDb2xsZWN0b3JUYWcgPSBFdmlkZW5jZUNvbGxlY3RvclRhZ0ltcGxcblxuZXhwb3J0IGNvbnN0IGV2aWRlbmNlQ29sbGVjdG9yTGF5ZXIgPSAoXG4gIGNvbGxlY3RvcjogRXZpZGVuY2VDb2xsZWN0b3IsXG4pOiBMYXllci5MYXllcjxFdmlkZW5jZUNvbGxlY3RvclRhZ0ltcGwsIG5ldmVyLCBuZXZlcj4gPT5cbiAgTGF5ZXIuc3VjY2VlZChFdmlkZW5jZUNvbGxlY3RvclRhZywgY29sbGVjdG9yKSBhcyBMYXllci5MYXllcjxcbiAgICBFdmlkZW5jZUNvbGxlY3RvclRhZ0ltcGwsXG4gICAgbmV2ZXIsXG4gICAgbmV2ZXJcbiAgPlxuXG5jb25zdCBpc1JlY29yZCA9ICh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0+XG4gIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSlcblxuZXhwb3J0IGNvbnN0IG1ha2VFdmlkZW5jZUNvbGxlY3RvciA9IChzZXNzaW9uOiBSdW5TZXNzaW9uKTogRXZpZGVuY2VDb2xsZWN0b3IgPT4ge1xuICBjb25zdCBzaW5rID0gbWFrZUV2aWRlbmNlU2luayhzZXNzaW9uKVxuXG4gIGNvbnN0IGNvbnZlcmdlU3RhdGljSXJCeURpZ2VzdCA9IG5ldyBNYXA8c3RyaW5nLCBKc29uVmFsdWU+KClcbiAgbGV0IHJ1bnRpbWVTZXJ2aWNlc0V2aWRlbmNlOiBKc29uVmFsdWUgfCB1bmRlZmluZWRcblxuICBjb25zdCBleHBvcnRCdWRnZXQgPSB7XG4gICAgZHJvcHBlZDogMCxcbiAgICBvdmVyc2l6ZWQ6IDAsXG4gICAgbm9uU2VyaWFsaXphYmxlOiAwLFxuICB9XG5cbiAgY29uc3QgZGVidWdTaW5rOiBEZWJ1Z1NpbmsgPSB7XG4gICAgcmVjb3JkOiAoZXZlbnQ6IERlYnVnRXZlbnQpID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IGxldmVsID0geWllbGQqIEZpYmVyUmVmLmdldChjdXJyZW50RGlhZ25vc3RpY3NMZXZlbClcbiAgICAgICAgY29uc3QgaW5zdGFuY2VJZFJhdyA9IChldmVudCBhcyBhbnkpLmluc3RhbmNlSWRcbiAgICAgICAgY29uc3QgaW5zdGFuY2VJZCA9XG4gICAgICAgICAgdHlwZW9mIGluc3RhbmNlSWRSYXcgPT09IFwic3RyaW5nXCIgJiYgaW5zdGFuY2VJZFJhdy5sZW5ndGggPiAwXG4gICAgICAgICAgICA/IGluc3RhbmNlSWRSYXdcbiAgICAgICAgICAgIDogXCJ1bmtub3duXCJcbiAgICAgICAgY29uc3QgZXZlbnRTZXEgPVxuICAgICAgICAgIGxldmVsID09PSBcIm9mZlwiXG4gICAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgICAgOiBzZXNzaW9uLmxvY2FsLm5leHRTZXEoXCJldmVudFNlcVwiLCBpbnN0YW5jZUlkKVxuICAgICAgICBjb25zdCByZWYgPSB0b1J1bnRpbWVEZWJ1Z0V2ZW50UmVmKGV2ZW50LCB7XG4gICAgICAgICAgZGlhZ25vc3RpY3NMZXZlbDogbGV2ZWwsXG4gICAgICAgICAgZXZlbnRTZXEsXG4gICAgICAgICAgb25NZXRhUHJvamVjdGlvbjogKHsgc3RhdHMgfSkgPT4ge1xuICAgICAgICAgICAgZXhwb3J0QnVkZ2V0LmRyb3BwZWQgKz0gc3RhdHMuZHJvcHBlZFxuICAgICAgICAgICAgZXhwb3J0QnVkZ2V0Lm92ZXJzaXplZCArPSBzdGF0cy5vdmVyc2l6ZWRcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICBpZiAoIXJlZikgcmV0dXJuXG5cbiAgICAgICAgY29uc3QgcHJvamVjdGVkID0gcHJvamVjdEpzb25WYWx1ZShyZWYpXG4gICAgICAgIGV4cG9ydEJ1ZGdldC5kcm9wcGVkICs9IHByb2plY3RlZC5zdGF0cy5kcm9wcGVkXG4gICAgICAgIGV4cG9ydEJ1ZGdldC5vdmVyc2l6ZWQgKz0gcHJvamVjdGVkLnN0YXRzLm92ZXJzaXplZFxuICAgICAgICBleHBvcnRCdWRnZXQubm9uU2VyaWFsaXphYmxlICs9IHByb2plY3RlZC5zdGF0cy5ub25TZXJpYWxpemFibGVcblxuICAgICAgICBzaW5rLnJlY29yZChcImRlYnVnOmV2ZW50XCIsIHByb2plY3RlZC52YWx1ZSwge1xuICAgICAgICAgIHRpbWVzdGFtcDogcmVmLnRpbWVzdGFtcCxcbiAgICAgICAgfSlcbiAgICAgIH0pLFxuICB9XG5cbiAgY29uc3QgcmVnaXN0ZXJDb252ZXJnZVN0YXRpY0lyID0gKHN0YXRpY0lyOiB1bmtub3duKTogdm9pZCA9PiB7XG4gICAgaWYgKCFpc1JlY29yZChzdGF0aWNJcikpIHJldHVyblxuICAgIGNvbnN0IGRpZ2VzdCA9IHN0YXRpY0lyLnN0YXRpY0lyRGlnZXN0XG4gICAgaWYgKHR5cGVvZiBkaWdlc3QgIT09IFwic3RyaW5nXCIgfHwgZGlnZXN0Lmxlbmd0aCA9PT0gMCkgcmV0dXJuXG4gICAgY29uc3QgcHJvamVjdGVkID0gcHJvamVjdEpzb25WYWx1ZShzdGF0aWNJcilcbiAgICBleHBvcnRCdWRnZXQuZHJvcHBlZCArPSBwcm9qZWN0ZWQuc3RhdHMuZHJvcHBlZFxuICAgIGV4cG9ydEJ1ZGdldC5vdmVyc2l6ZWQgKz0gcHJvamVjdGVkLnN0YXRzLm92ZXJzaXplZFxuICAgIGV4cG9ydEJ1ZGdldC5ub25TZXJpYWxpemFibGUgKz0gcHJvamVjdGVkLnN0YXRzLm5vblNlcmlhbGl6YWJsZVxuICAgIGNvbnZlcmdlU3RhdGljSXJCeURpZ2VzdC5zZXQoZGlnZXN0LCBwcm9qZWN0ZWQudmFsdWUpXG4gIH1cblxuICBjb25zdCBzZXRSdW50aW1lU2VydmljZXNFdmlkZW5jZSA9IChldmlkZW5jZTogdW5rbm93bik6IHZvaWQgPT4ge1xuICAgIGNvbnN0IHByb2plY3RlZCA9IHByb2plY3RKc29uVmFsdWUoZXZpZGVuY2UpXG4gICAgZXhwb3J0QnVkZ2V0LmRyb3BwZWQgKz0gcHJvamVjdGVkLnN0YXRzLmRyb3BwZWRcbiAgICBleHBvcnRCdWRnZXQub3ZlcnNpemVkICs9IHByb2plY3RlZC5zdGF0cy5vdmVyc2l6ZWRcbiAgICBleHBvcnRCdWRnZXQubm9uU2VyaWFsaXphYmxlICs9IHByb2plY3RlZC5zdGF0cy5ub25TZXJpYWxpemFibGVcbiAgICBydW50aW1lU2VydmljZXNFdmlkZW5jZSA9IHByb2plY3RlZC52YWx1ZVxuICB9XG5cbiAgY29uc3QgZXhwb3J0RXZpZGVuY2VQYWNrYWdlID0gKG9wdGlvbnM/OiB7XG4gICAgcmVhZG9ubHkgbWF4RXZlbnRzPzogbnVtYmVyXG4gIH0pOiBFdmlkZW5jZVBhY2thZ2UgPT4ge1xuICAgIGNvbnN0IGNvbnZlcmdlU3VtbWFyeSA9XG4gICAgICBjb252ZXJnZVN0YXRpY0lyQnlEaWdlc3Quc2l6ZSA+IDBcbiAgICAgICAgPyAoe1xuICAgICAgICAgICAgc3RhdGljSXJCeURpZ2VzdDogT2JqZWN0LmZyb21FbnRyaWVzKGNvbnZlcmdlU3RhdGljSXJCeURpZ2VzdCksXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIEpzb25WYWx1ZSlcbiAgICAgICAgOiB1bmRlZmluZWRcblxuICAgIGNvbnN0IHJ1bnRpbWVTdW1tYXJ5ID1cbiAgICAgIHJ1bnRpbWVTZXJ2aWNlc0V2aWRlbmNlICE9IG51bGxcbiAgICAgICAgPyAoeyBzZXJ2aWNlczogcnVudGltZVNlcnZpY2VzRXZpZGVuY2UgfSBhcyB1bmtub3duIGFzIEpzb25WYWx1ZSlcbiAgICAgICAgOiB1bmRlZmluZWRcblxuICAgIGNvbnN0IHN1bW1hcnkgPVxuICAgICAgY29udmVyZ2VTdW1tYXJ5ICE9IG51bGwgfHwgcnVudGltZVN1bW1hcnkgIT0gbnVsbFxuICAgICAgICA/ICh7XG4gICAgICAgICAgICAuLi4oY29udmVyZ2VTdW1tYXJ5ICE9IG51bGwgPyB7IGNvbnZlcmdlOiBjb252ZXJnZVN1bW1hcnkgfSA6IHt9KSxcbiAgICAgICAgICAgIC4uLihydW50aW1lU3VtbWFyeSAhPSBudWxsID8geyBydW50aW1lOiBydW50aW1lU3VtbWFyeSB9IDoge30pLFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBKc29uVmFsdWUpXG4gICAgICAgIDogdW5kZWZpbmVkXG5cbiAgICByZXR1cm4gc2luay5leHBvcnQoe1xuICAgICAgbWF4RXZlbnRzOiBvcHRpb25zPy5tYXhFdmVudHMsXG4gICAgICBzdW1tYXJ5LFxuICAgIH0pXG4gIH1cblxuICBjb25zdCBjbGVhciA9ICgpOiB2b2lkID0+IHtcbiAgICBzaW5rLmNsZWFyKClcbiAgICBjb252ZXJnZVN0YXRpY0lyQnlEaWdlc3QuY2xlYXIoKVxuICAgIHJ1bnRpbWVTZXJ2aWNlc0V2aWRlbmNlID0gdW5kZWZpbmVkXG4gICAgZXhwb3J0QnVkZ2V0LmRyb3BwZWQgPSAwXG4gICAgZXhwb3J0QnVkZ2V0Lm92ZXJzaXplZCA9IDBcbiAgICBleHBvcnRCdWRnZXQubm9uU2VyaWFsaXphYmxlID0gMFxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBzZXNzaW9uLFxuICAgIGRlYnVnU2luayxcbiAgICByZWdpc3RlckNvbnZlcmdlU3RhdGljSXIsXG4gICAgc2V0UnVudGltZVNlcnZpY2VzRXZpZGVuY2UsXG4gICAgZXhwb3J0RXZpZGVuY2VQYWNrYWdlLFxuICAgIGNsZWFyLFxuICB9XG59XG4iLCAiaW1wb3J0IHtcbiAgQ2F1c2UsXG4gIENvbnRleHQsXG4gIERlZmVycmVkLFxuICBEdXJhdGlvbixcbiAgRWZmZWN0LFxuICBGaWJlcixcbiAgRmliZXJSZWYsXG4gIExheWVyLFxuICBPcHRpb24sXG4gIFB1YlN1YixcbiAgUXVldWUsXG4gIFJlZixcbiAgU2NvcGUsXG4gIFN0cmVhbSxcbn0gZnJvbSBcImVmZmVjdFwiXG5pbXBvcnQgKiBhcyBEZWJ1ZyBmcm9tIFwiLi4vRGVidWdTaW5rLmpzXCJcbmltcG9ydCB7IHRvU2VyaWFsaXphYmxlRXJyb3JTdW1tYXJ5IH0gZnJvbSBcIi4uL2Vycm9yU3VtbWFyeS5qc1wiXG5pbXBvcnQgKiBhcyBUYXNrUnVubmVyIGZyb20gXCIuLi9UYXNrUnVubmVyLmpzXCJcbmltcG9ydCB7IGlzRGV2RW52IH0gZnJvbSBcIi4uL2Vudi5qc1wiXG5pbXBvcnQgKiBhcyBJZGVudGl0eSBmcm9tIFwiLi9pZGVudGl0eS5qc1wiXG5pbXBvcnQgKiBhcyBQcm9jZXNzQ29uY3VycmVuY3kgZnJvbSBcIi4vY29uY3VycmVuY3kuanNcIlxuaW1wb3J0ICogYXMgUHJvY2Vzc0V2ZW50cyBmcm9tIFwiLi9ldmVudHMuanNcIlxuaW1wb3J0ICogYXMgTWV0YSBmcm9tIFwiLi9tZXRhLmpzXCJcbmltcG9ydCB0eXBlIHtcbiAgUHJvY2Vzc0NvbnRyb2xSZXF1ZXN0LFxuICBQcm9jZXNzRGVmaW5pdGlvbixcbiAgUHJvY2Vzc0V2ZW50LFxuICBQcm9jZXNzSW5zdGFsbGF0aW9uLFxuICBQcm9jZXNzSW5zdGFuY2VJZGVudGl0eSxcbiAgUHJvY2Vzc0luc3RhbmNlU3RhdHVzLFxuICBQcm9jZXNzUGxhdGZvcm1FdmVudCxcbiAgUHJvY2Vzc1Njb3BlLFxuICBQcm9jZXNzVHJpZ2dlcixcbiAgUHJvY2Vzc1RyaWdnZXJTcGVjLFxuICBTZXJpYWxpemFibGVFcnJvclN1bW1hcnksXG59IGZyb20gXCIuL3Byb3RvY29sLmpzXCJcbmltcG9ydCAqIGFzIFN1cGVydmlzaW9uIGZyb20gXCIuL3N1cGVydmlzaW9uLmpzXCJcblxudHlwZSBJbnN0YWxsYXRpb25LZXkgPSBzdHJpbmdcbnR5cGUgUHJvY2Vzc0luc3RhbmNlSWQgPSBzdHJpbmdcblxudHlwZSBJbnN0YWxsYXRpb25TdGF0ZSA9IHtcbiAgcmVhZG9ubHkgaWRlbnRpdHk6IHtcbiAgICByZWFkb25seSBwcm9jZXNzSWQ6IHN0cmluZ1xuICAgIHJlYWRvbmx5IHNjb3BlOiBQcm9jZXNzU2NvcGVcbiAgfVxuICByZWFkb25seSBzY29wZUtleTogc3RyaW5nXG4gIHJlYWRvbmx5IGRlZmluaXRpb246IFByb2Nlc3NEZWZpbml0aW9uXG4gIHJlYWRvbmx5IGVudjogQ29udGV4dC5Db250ZXh0PGFueT5cbiAgcmVhZG9ubHkgZm9ya1Njb3BlOiBTY29wZS5TY29wZVxuICByZWFkb25seSBwcm9jZXNzOiBFZmZlY3QuRWZmZWN0PHZvaWQsIGFueSwgdW5rbm93bj5cbiAgcmVhZG9ubHkga2luZDogTWV0YS5Qcm9jZXNzTWV0YVtcImtpbmRcIl1cbiAgZW5hYmxlZDogYm9vbGVhblxuICBpbnN0YWxsZWRBdD86IHN0cmluZ1xuICBuZXh0UnVuU2VxOiBudW1iZXJcbiAgc3VwZXJ2aXNpb246IFN1cGVydmlzaW9uLlN1cGVydmlzaW9uU3RhdGVcbiAgY3VycmVudEluc3RhbmNlSWQ/OiBQcm9jZXNzSW5zdGFuY2VJZFxufVxuXG50eXBlIEluc3RhbmNlU3RhdGUgPSB7XG4gIHJlYWRvbmx5IGluc3RhbGxhdGlvbktleTogSW5zdGFsbGF0aW9uS2V5XG4gIHJlYWRvbmx5IHByb2Nlc3NJbnN0YW5jZUlkOiBQcm9jZXNzSW5zdGFuY2VJZFxuICByZWFkb25seSBpZGVudGl0eTogUHJvY2Vzc0luc3RhbmNlSWRlbnRpdHlcbiAgcmVhZG9ubHkgcHJvY2Vzc0lkOiBzdHJpbmdcbiAgcmVhZG9ubHkgc2NvcGU6IFByb2Nlc3NTY29wZVxuICByZWFkb25seSBwbGF0Zm9ybVRyaWdnZXJzUXVldWU6IFF1ZXVlLlF1ZXVlPFByb2Nlc3NUcmlnZ2VyPlxuICBzdGF0dXM6IFByb2Nlc3NJbnN0YW5jZVN0YXR1c1xuICBuZXh0RXZlbnRTZXE6IG51bWJlclxuICBuZXh0VHJpZ2dlclNlcTogbnVtYmVyXG4gIGZpYmVyPzogRmliZXIuUnVudGltZUZpYmVyPHVua25vd24sIHVua25vd24+XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvY2Vzc1J1bnRpbWUge1xuICByZWFkb25seSBpbnN0YWxsOiA8RSwgUj4oXG4gICAgcHJvY2VzczogRWZmZWN0LkVmZmVjdDx2b2lkLCBFLCBSPixcbiAgICBvcHRpb25zOiB7XG4gICAgICByZWFkb25seSBzY29wZTogUHJvY2Vzc1Njb3BlXG4gICAgICByZWFkb25seSBlbmFibGVkPzogYm9vbGVhblxuICAgICAgcmVhZG9ubHkgaW5zdGFsbGVkQXQ/OiBzdHJpbmdcbiAgICB9LFxuICApID0+IEVmZmVjdC5FZmZlY3Q8UHJvY2Vzc0luc3RhbGxhdGlvbiB8IHVuZGVmaW5lZCwgbmV2ZXIsIFI+XG4gIHJlYWRvbmx5IGxpc3RJbnN0YWxsYXRpb25zOiAoZmlsdGVyPzoge1xuICAgIHJlYWRvbmx5IHNjb3BlVHlwZT86IFByb2Nlc3NTY29wZVtcInR5cGVcIl1cbiAgICByZWFkb25seSBzY29wZUtleT86IHN0cmluZ1xuICB9KSA9PiBFZmZlY3QuRWZmZWN0PFJlYWRvbmx5QXJyYXk8UHJvY2Vzc0luc3RhbGxhdGlvbj4+XG4gIHJlYWRvbmx5IGdldEluc3RhbmNlU3RhdHVzOiAoXG4gICAgcHJvY2Vzc0luc3RhbmNlSWQ6IHN0cmluZyxcbiAgKSA9PiBFZmZlY3QuRWZmZWN0PFByb2Nlc3NJbnN0YW5jZVN0YXR1cyB8IHVuZGVmaW5lZD5cbiAgcmVhZG9ubHkgY29udHJvbEluc3RhbmNlOiAoXG4gICAgcHJvY2Vzc0luc3RhbmNlSWQ6IHN0cmluZyxcbiAgICByZXF1ZXN0OiBQcm9jZXNzQ29udHJvbFJlcXVlc3QsXG4gICkgPT4gRWZmZWN0LkVmZmVjdDx2b2lkPlxuICByZWFkb25seSBkZWxpdmVyUGxhdGZvcm1FdmVudDogKGV2ZW50OiBQcm9jZXNzUGxhdGZvcm1FdmVudCkgPT4gRWZmZWN0LkVmZmVjdDx2b2lkPlxuICByZWFkb25seSBldmVudHM6IFN0cmVhbS5TdHJlYW08UHJvY2Vzc0V2ZW50PlxuICByZWFkb25seSBnZXRFdmVudHNTbmFwc2hvdDogKCkgPT4gRWZmZWN0LkVmZmVjdDxSZWFkb25seUFycmF5PFByb2Nlc3NFdmVudD4+XG59XG5cbmV4cG9ydCBjbGFzcyBQcm9jZXNzUnVudGltZVRhZyBleHRlbmRzIENvbnRleHQuVGFnKFwiQGxvZ2l4L2NvcmUvUHJvY2Vzc1J1bnRpbWVcIik8XG4gIFByb2Nlc3NSdW50aW1lVGFnLFxuICBQcm9jZXNzUnVudGltZVxuPigpIHt9XG5cbmNvbnN0IGN1cnJlbnRQcm9jZXNzVHJpZ2dlciA9IEZpYmVyUmVmLnVuc2FmZU1ha2U8UHJvY2Vzc1RyaWdnZXIgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZClcbmNvbnN0IGN1cnJlbnRQcm9jZXNzRXZlbnRCdWRnZXQgPSBGaWJlclJlZi51bnNhZmVNYWtlPFxuICBSZWYuUmVmPFByb2Nlc3NFdmVudHMuUHJvY2Vzc1J1bkV2ZW50QnVkZ2V0U3RhdGU+IHwgdW5kZWZpbmVkXG4+KHVuZGVmaW5lZClcbmNvbnN0IFJVTlRJTUVfQk9PVF9FVkVOVCA9IFwicnVudGltZTpib290XCIgYXMgY29uc3RcblxuY29uc3QgZGVyaXZlRGVidWdNb2R1bGVJZCA9IChwcm9jZXNzSWQ6IHN0cmluZyk6IHN0cmluZyA9PiBgcHJvY2Vzczoke3Byb2Nlc3NJZH1gXG5cbmNvbnN0IGRlcml2ZVR4bkFuY2hvciA9IChcbiAgZXZlbnQ6IFByb2Nlc3NFdmVudCxcbik6IHsgcmVhZG9ubHkgdHhuU2VxPzogbnVtYmVyOyByZWFkb25seSB0eG5JZD86IHN0cmluZyB9ID0+IHtcbiAgY29uc3QgdHJpZ2dlcjogYW55ID0gZXZlbnQudHJpZ2dlclxuICBpZiAoIXRyaWdnZXIpIHJldHVybiB7fVxuICBpZiAoXG4gICAgKHRyaWdnZXIua2luZCA9PT0gXCJtb2R1bGVBY3Rpb25cIiB8fCB0cmlnZ2VyLmtpbmQgPT09IFwibW9kdWxlU3RhdGVDaGFuZ2VcIikgJiZcbiAgICB0eXBlb2YgdHJpZ2dlci5pbnN0YW5jZUlkID09PSBcInN0cmluZ1wiICYmXG4gICAgdHlwZW9mIHRyaWdnZXIudHhuU2VxID09PSBcIm51bWJlclwiICYmXG4gICAgTnVtYmVyLmlzRmluaXRlKHRyaWdnZXIudHhuU2VxKSAmJlxuICAgIHRyaWdnZXIudHhuU2VxID49IDFcbiAgKSB7XG4gICAgY29uc3QgdHhuU2VxID0gTWF0aC5mbG9vcih0cmlnZ2VyLnR4blNlcSlcbiAgICByZXR1cm4ge1xuICAgICAgdHhuU2VxLFxuICAgICAgdHhuSWQ6IGAke3RyaWdnZXIuaW5zdGFuY2VJZH06OnQke3R4blNlcX1gLFxuICAgIH1cbiAgfVxuICByZXR1cm4ge31cbn1cblxuY29uc3Qgc2hvdWxkTm9vcER1ZVRvU3luY1R4biA9IChzY29wZTogUHJvY2Vzc1Njb3BlLCBraW5kOiBzdHJpbmcpOiBFZmZlY3QuRWZmZWN0PGJvb2xlYW4+ID0+IHtcbiAgY29uc3QgbW9kdWxlSWQgPSBzY29wZS50eXBlID09PSBcIm1vZHVsZUluc3RhbmNlXCIgPyBzY29wZS5tb2R1bGVJZCA6IHVuZGVmaW5lZFxuICBjb25zdCBpbnN0YW5jZUlkID0gc2NvcGUudHlwZSA9PT0gXCJtb2R1bGVJbnN0YW5jZVwiID8gc2NvcGUuaW5zdGFuY2VJZCA6IHVuZGVmaW5lZFxuICByZXR1cm4gVGFza1J1bm5lci5zaG91bGROb29wSW5TeW5jVHJhbnNhY3Rpb25GaWJlcih7XG4gICAgbW9kdWxlSWQsXG4gICAgaW5zdGFuY2VJZCxcbiAgICBjb2RlOiBcInByb2Nlc3M6OmludmFsaWRfdXNhZ2VcIixcbiAgICBzZXZlcml0eTogXCJlcnJvclwiLFxuICAgIG1lc3NhZ2U6XG4gICAgICBcIlByb2Nlc3NSdW50aW1lIHNjaGVkdWxpbmcgaXMgbm90IGFsbG93ZWQgaW5zaWRlIGEgc3luY2hyb25vdXMgU3RhdGVUcmFuc2FjdGlvbiBib2R5IChpdCBtYXkgZGVhZGxvY2sgdGhlIHR4blF1ZXVlKS5cIixcbiAgICBoaW50OlxuICAgICAgXCJUcmlnZ2VyL3NjaGVkdWxlIFByb2Nlc3Mgb3V0c2lkZSB0aGUgdHJhbnNhY3Rpb24gd2luZG93IChlLmcuIGluIGEgd2F0Y2hlcidzIHJ1biBzZWN0aW9uIG9yIGEgc2VwYXJhdGUgZmliZXIpOyBcIiArXG4gICAgICBcImRvIG5vdCB0cmlnZ2VyIFByb2Nlc3MgZGlyZWN0bHkgaW5zaWRlIGEgcmVkdWNlciAvIHN5bmNocm9ub3VzIHRyYW5zYWN0aW9uIGJvZHkuXCIsXG4gICAga2luZCxcbiAgfSlcbn1cblxudHlwZSBEb3RQYXRoU2VnbWVudCA9IHN0cmluZyB8IG51bWJlclxuXG5jb25zdCBtYWtlRG90UGF0aEVycm9yID0gKHBhdGg6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nLCBoaW50Pzogc3RyaW5nKTogRXJyb3IgPT4ge1xuICBjb25zdCBlcnIgPSBuZXcgRXJyb3IobWVzc2FnZSlcbiAgOyhlcnIgYXMgYW55KS5jb2RlID0gXCJwcm9jZXNzOjppbnZhbGlkX2RvdF9wYXRoXCJcbiAgOyhlcnIgYXMgYW55KS5oaW50ID1cbiAgICBoaW50ID8/XG4gICAgW1xuICAgICAgXCJFeHBlY3RlZCBkb3QtcGF0aCBzeW50YXg6IHNlZ21lbnRzIHNlcGFyYXRlZCBieSAnLicsIG51bWVyaWMgc2VnbWVudHMgcmVwcmVzZW50IGFycmF5IGluZGljZXMuXCIsXG4gICAgICBgcGF0aDogJHtwYXRofWAsXG4gICAgICBcIlwiLFxuICAgICAgXCJleGFtcGxlczpcIixcbiAgICAgIFwiLSBjb3VudFwiLFxuICAgICAgXCItIHVzZXIubmFtZVwiLFxuICAgICAgXCItIGl0ZW1zLjAuaWRcIixcbiAgICBdLmpvaW4oXCJcXG5cIilcbiAgcmV0dXJuIGVyclxufVxuXG5jb25zdCBwYXJzZURvdFBhdGggPSAoXG4gIHBhdGg6IHN0cmluZyxcbik6IHsgcmVhZG9ubHkgb2s6IHRydWU7IHJlYWRvbmx5IHNlZ21lbnRzOiBSZWFkb25seUFycmF5PERvdFBhdGhTZWdtZW50PiB9IHwgeyByZWFkb25seSBvazogZmFsc2U7IHJlYWRvbmx5IGVycm9yOiBFcnJvciB9ID0+IHtcbiAgaWYgKHR5cGVvZiBwYXRoICE9PSBcInN0cmluZ1wiIHx8IHBhdGgubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHsgb2s6IGZhbHNlLCBlcnJvcjogbWFrZURvdFBhdGhFcnJvcihTdHJpbmcocGF0aCksIFwiZG90LXBhdGggbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmdcIikgfVxuICB9XG5cbiAgY29uc3QgcmF3ID0gcGF0aC5zcGxpdChcIi5cIilcbiAgaWYgKHJhdy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4geyBvazogZmFsc2UsIGVycm9yOiBtYWtlRG90UGF0aEVycm9yKHBhdGgsIFwiZG90LXBhdGggbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSBzZWdtZW50XCIpIH1cbiAgfVxuXG4gIGNvbnN0IHNlZ21lbnRzOiBEb3RQYXRoU2VnbWVudFtdID0gW11cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYXcubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBzZWcgPSByYXdbaV0hXG4gICAgaWYgKHNlZy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9rOiBmYWxzZSxcbiAgICAgICAgZXJyb3I6IG1ha2VEb3RQYXRoRXJyb3IoXG4gICAgICAgICAgcGF0aCxcbiAgICAgICAgICBgSW52YWxpZCBkb3QtcGF0aDogZW1wdHkgc2VnbWVudCBhdCBpbmRleCAke2l9LmAsXG4gICAgICAgICAgW1xuICAgICAgICAgICAgXCJFeHBlY3RlZCBkb3QtcGF0aCBzeW50YXg6IHNlZ21lbnRzIHNlcGFyYXRlZCBieSAnLicsIG51bWVyaWMgc2VnbWVudHMgcmVwcmVzZW50IGFycmF5IGluZGljZXMuXCIsXG4gICAgICAgICAgICBgcGF0aDogJHtwYXRofWAsXG4gICAgICAgICAgICBcIlwiLFxuICAgICAgICAgICAgXCJleGFtcGxlczpcIixcbiAgICAgICAgICAgIFwiLSBjb3VudFwiLFxuICAgICAgICAgICAgXCItIHVzZXIubmFtZVwiLFxuICAgICAgICAgICAgXCItIGl0ZW1zLjAuaWRcIixcbiAgICAgICAgICAgIFwiXCIsXG4gICAgICAgICAgICBcImZpeDpcIixcbiAgICAgICAgICAgIFwiLSBSZW1vdmUgY29uc2VjdXRpdmUgZG90cyBvciB0cmFpbGluZyBkb3RzLlwiLFxuICAgICAgICAgIF0uam9pbihcIlxcblwiKSxcbiAgICAgICAgKSxcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoL15bMC05XSskLy50ZXN0KHNlZykpIHtcbiAgICAgIGNvbnN0IG4gPSBOdW1iZXIoc2VnKVxuICAgICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUobikgfHwgbiA8IDApIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBvazogZmFsc2UsXG4gICAgICAgICAgZXJyb3I6IG1ha2VEb3RQYXRoRXJyb3IocGF0aCwgYEludmFsaWQgYXJyYXkgaW5kZXggc2VnbWVudCBcIiR7c2VnfVwiIGF0IGluZGV4ICR7aX0uYCksXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHNlZ21lbnRzLnB1c2goTWF0aC5mbG9vcihuKSlcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgc2VnbWVudHMucHVzaChzZWcpXG4gIH1cblxuICByZXR1cm4geyBvazogdHJ1ZSwgc2VnbWVudHMgfVxufVxuXG5jb25zdCBzZWxlY3RCeURvdFBhdGggPSAoc2VnbWVudHM6IFJlYWRvbmx5QXJyYXk8RG90UGF0aFNlZ21lbnQ+KSA9PiAoc3RhdGU6IHVua25vd24pOiB1bmtub3duID0+IHtcbiAgbGV0IGN1cnJlbnQ6IGFueSA9IHN0YXRlXG4gIGZvciAoY29uc3Qgc2VnIG9mIHNlZ21lbnRzKSB7XG4gICAgaWYgKGN1cnJlbnQgPT0gbnVsbCkgcmV0dXJuIHVuZGVmaW5lZFxuICAgIGN1cnJlbnQgPSBjdXJyZW50W3NlZyBhcyBhbnldXG4gIH1cbiAgcmV0dXJuIGN1cnJlbnRcbn1cblxuY29uc3QgYWN0aW9uSWRGcm9tVW5rbm93biA9IChhY3Rpb246IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQgPT4ge1xuICBpZiAoIWFjdGlvbiB8fCB0eXBlb2YgYWN0aW9uICE9PSBcIm9iamVjdFwiKSByZXR1cm4gdW5kZWZpbmVkXG4gIGNvbnN0IGFueUFjdGlvbiA9IGFjdGlvbiBhcyBhbnlcbiAgaWYgKHR5cGVvZiBhbnlBY3Rpb24uX3RhZyA9PT0gXCJzdHJpbmdcIiAmJiBhbnlBY3Rpb24uX3RhZy5sZW5ndGggPiAwKSByZXR1cm4gYW55QWN0aW9uLl90YWdcbiAgaWYgKHR5cGVvZiBhbnlBY3Rpb24udHlwZSA9PT0gXCJzdHJpbmdcIiAmJiBhbnlBY3Rpb24udHlwZS5sZW5ndGggPiAwKSByZXR1cm4gYW55QWN0aW9uLnR5cGVcbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG5leHBvcnQgY29uc3QgbWFrZSA9IChvcHRpb25zPzoge1xuICByZWFkb25seSBtYXhFdmVudEhpc3Rvcnk/OiBudW1iZXJcbn0pOiBFZmZlY3QuRWZmZWN0PFByb2Nlc3NSdW50aW1lLCBuZXZlciwgU2NvcGUuU2NvcGU+ID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBydW50aW1lU2NvcGUgPSB5aWVsZCogRWZmZWN0LnNjb3BlXG4gICAgY29uc3QgbWF4RXZlbnRIaXN0b3J5ID1cbiAgICAgIHR5cGVvZiBvcHRpb25zPy5tYXhFdmVudEhpc3RvcnkgPT09IFwibnVtYmVyXCIgJiZcbiAgICAgIE51bWJlci5pc0Zpbml0ZShvcHRpb25zLm1heEV2ZW50SGlzdG9yeSkgJiZcbiAgICAgIG9wdGlvbnMubWF4RXZlbnRIaXN0b3J5ID49IDBcbiAgICAgICAgPyBNYXRoLmZsb29yKG9wdGlvbnMubWF4RXZlbnRIaXN0b3J5KVxuICAgICAgICA6IDUwMFxuXG4gICAgY29uc3QgaW5zdGFsbGF0aW9ucyA9IG5ldyBNYXA8SW5zdGFsbGF0aW9uS2V5LCBJbnN0YWxsYXRpb25TdGF0ZT4oKVxuICAgIGNvbnN0IGluc3RhbmNlcyA9IG5ldyBNYXA8UHJvY2Vzc0luc3RhbmNlSWQsIEluc3RhbmNlU3RhdGU+KClcblxuICAgIGNvbnN0IGV2ZW50c0J1ZmZlcjogUHJvY2Vzc0V2ZW50W10gPSBbXVxuICAgIGNvbnN0IGV2ZW50c0h1YiA9IHlpZWxkKiBQdWJTdWIuc2xpZGluZzxQcm9jZXNzRXZlbnQ+KE1hdGgubWF4KDEsIE1hdGgubWluKDIwNDgsIG1heEV2ZW50SGlzdG9yeSkpKVxuXG4gICAgY29uc3QgdHJpbUV2ZW50cyA9ICgpID0+IHtcbiAgICAgIGlmIChtYXhFdmVudEhpc3RvcnkgPD0gMCkge1xuICAgICAgICBldmVudHNCdWZmZXIubGVuZ3RoID0gMFxuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICAgIGlmIChldmVudHNCdWZmZXIubGVuZ3RoIDw9IG1heEV2ZW50SGlzdG9yeSkgcmV0dXJuXG4gICAgICBjb25zdCBleGNlc3MgPSBldmVudHNCdWZmZXIubGVuZ3RoIC0gbWF4RXZlbnRIaXN0b3J5XG4gICAgICBldmVudHNCdWZmZXIuc3BsaWNlKDAsIGV4Y2VzcylcbiAgICB9XG5cbiAgICBjb25zdCByZWNvcmREZWJ1Z0V2ZW50ID0gKGV2ZW50OiBQcm9jZXNzRXZlbnQpOiBFZmZlY3QuRWZmZWN0PHZvaWQ+ID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IGRpYWdub3N0aWNzTGV2ZWwgPSB5aWVsZCogRmliZXJSZWYuZ2V0KERlYnVnLmN1cnJlbnREaWFnbm9zdGljc0xldmVsKVxuXG4gICAgICAgIC8vIGRpYWdub3N0aWNzPW9mZlx1RkYxQVx1NUMzRFx1OTFDRlx1NEUwRFx1OEZEQlx1NTE2NSBEZWJ1ZyBzaW5rc1x1RkYwOFx1OEZEMVx1OTZGNlx1NjIxMFx1NjcyQ1x1RkYwOVx1RkYxQlx1OTUxOVx1OEJFRlx1NTczQVx1NjY2Rlx1NTNFNlx1ODg0Q1x1OTAxQVx1OEZDNyBkaWFnbm9zdGljIFx1NEU4Qlx1NEVGNlx1NjZCNFx1OTczMlx1MzAwMlxuICAgICAgICBpZiAoZGlhZ25vc3RpY3NMZXZlbCA9PT0gXCJvZmZcIikge1xuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcHJvY2Vzc0lkID0gZXZlbnQuaWRlbnRpdHkuaWRlbnRpdHkucHJvY2Vzc0lkXG4gICAgICAgIGNvbnN0IHByb2Nlc3NJbnN0YW5jZUlkID0gSWRlbnRpdHkucHJvY2Vzc0luc3RhbmNlSWRGcm9tSWRlbnRpdHkoZXZlbnQuaWRlbnRpdHkpXG4gICAgICAgIGNvbnN0IG1vZHVsZUlkID0gZGVyaXZlRGVidWdNb2R1bGVJZChwcm9jZXNzSWQpXG4gICAgICAgIGNvbnN0IHsgdHhuU2VxLCB0eG5JZCB9ID0gZGVyaXZlVHhuQW5jaG9yKGV2ZW50KVxuXG4gICAgICAgIHlpZWxkKiBEZWJ1Zy5yZWNvcmQoe1xuICAgICAgICAgIHR5cGU6IGV2ZW50LnR5cGUsXG4gICAgICAgICAgbW9kdWxlSWQsXG4gICAgICAgICAgaW5zdGFuY2VJZDogcHJvY2Vzc0luc3RhbmNlSWQsXG4gICAgICAgICAgaWRlbnRpdHk6IGV2ZW50LmlkZW50aXR5LFxuICAgICAgICAgIHNldmVyaXR5OiBldmVudC5zZXZlcml0eSxcbiAgICAgICAgICBldmVudFNlcTogZXZlbnQuZXZlbnRTZXEsXG4gICAgICAgICAgdGltZXN0YW1wTXM6IGV2ZW50LnRpbWVzdGFtcE1zLFxuICAgICAgICAgIHRyaWdnZXI6IGV2ZW50LnRyaWdnZXIsXG4gICAgICAgICAgZGlzcGF0Y2g6IGV2ZW50LmRpc3BhdGNoLFxuICAgICAgICAgIGVycm9yOiBldmVudC5lcnJvcixcbiAgICAgICAgICB0eG5TZXEsXG4gICAgICAgICAgdHhuSWQsXG4gICAgICAgIH0gYXMgYW55KVxuICAgICAgfSlcblxuICAgIGNvbnN0IHB1Ymxpc2hFdmVudCA9IChldmVudDogUHJvY2Vzc0V2ZW50KTogRWZmZWN0LkVmZmVjdDx2b2lkPiA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBldmVudHNCdWZmZXIucHVzaChldmVudClcbiAgICAgICAgdHJpbUV2ZW50cygpXG4gICAgICAgIHlpZWxkKiBQdWJTdWIucHVibGlzaChldmVudHNIdWIsIGV2ZW50KVxuICAgICAgICB5aWVsZCogcmVjb3JkRGVidWdFdmVudChldmVudClcbiAgICAgIH0pXG5cbiAgICBjb25zdCBlbWl0ID0gKGV2ZW50OiBQcm9jZXNzRXZlbnQpOiBFZmZlY3QuRWZmZWN0PHZvaWQ+ID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IGJ1ZGdldFJlZiA9IHlpZWxkKiBGaWJlclJlZi5nZXQoY3VycmVudFByb2Nlc3NFdmVudEJ1ZGdldClcbiAgICAgICAgaWYgKGJ1ZGdldFJlZikge1xuICAgICAgICAgIGNvbnN0IGRlY2lzaW9uID0geWllbGQqIFJlZi5tb2RpZnkoYnVkZ2V0UmVmLCAoc3RhdGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IFtuZXh0RGVjaXNpb24sIG5leHRTdGF0ZV0gPSBQcm9jZXNzRXZlbnRzLmFwcGx5UHJvY2Vzc1J1bkV2ZW50QnVkZ2V0KHN0YXRlLCBldmVudClcbiAgICAgICAgICAgIHJldHVybiBbbmV4dERlY2lzaW9uLCBuZXh0U3RhdGVdIGFzIGNvbnN0XG4gICAgICAgICAgfSlcblxuICAgICAgICAgIGlmIChkZWNpc2lvbi5fdGFnID09PSBcImVtaXRcIiB8fCBkZWNpc2lvbi5fdGFnID09PSBcImVtaXRTdW1tYXJ5XCIpIHtcbiAgICAgICAgICAgIHlpZWxkKiBwdWJsaXNoRXZlbnQoZGVjaXNpb24uZXZlbnQpXG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZW5mb3JjZWQgPSBQcm9jZXNzRXZlbnRzLmVuZm9yY2VQcm9jZXNzRXZlbnRNYXhCeXRlcyhldmVudClcbiAgICAgICAgeWllbGQqIHB1Ymxpc2hFdmVudChlbmZvcmNlZC5ldmVudClcbiAgICAgIH0pXG5cbiAgICBjb25zdCBlbWl0RXJyb3JEaWFnbm9zdGljID0gKFxuICAgICAgc2NvcGU6IFByb2Nlc3NTY29wZSxcbiAgICAgIHByb2Nlc3NJZDogc3RyaW5nLFxuICAgICAgY29kZTogc3RyaW5nLFxuICAgICAgbWVzc2FnZTogc3RyaW5nLFxuICAgICAgaGludD86IHN0cmluZyxcbiAgICApOiBFZmZlY3QuRWZmZWN0PHZvaWQ+ID0+IHtcbiAgICAgIGlmICghaXNEZXZFbnYoKSkge1xuICAgICAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICAgIH1cbiAgICAgIGNvbnN0IG1vZHVsZUlkID0gc2NvcGUudHlwZSA9PT0gXCJtb2R1bGVJbnN0YW5jZVwiID8gc2NvcGUubW9kdWxlSWQgOiB1bmRlZmluZWRcbiAgICAgIGNvbnN0IGluc3RhbmNlSWQgPSBzY29wZS50eXBlID09PSBcIm1vZHVsZUluc3RhbmNlXCIgPyBzY29wZS5pbnN0YW5jZUlkIDogdW5kZWZpbmVkXG4gICAgICByZXR1cm4gRGVidWcucmVjb3JkKHtcbiAgICAgICAgdHlwZTogXCJkaWFnbm9zdGljXCIsXG4gICAgICAgIG1vZHVsZUlkLFxuICAgICAgICBpbnN0YW5jZUlkLFxuICAgICAgICBjb2RlLFxuICAgICAgICBzZXZlcml0eTogXCJlcnJvclwiLFxuICAgICAgICBtZXNzYWdlLFxuICAgICAgICBoaW50LFxuICAgICAgICBhY3Rpb25UYWc6IHByb2Nlc3NJZCxcbiAgICAgICAga2luZDogXCJwcm9jZXNzX3J1bnRpbWVcIixcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgY29uc3QgcmVzb2x2ZU1pc3NpbmdEZXBlbmRlbmNpZXMgPSAoaW5zdGFsbGF0aW9uOiBJbnN0YWxsYXRpb25TdGF0ZSk6IFJlYWRvbmx5QXJyYXk8c3RyaW5nPiA9PiB7XG4gICAgICBjb25zdCBkZWNsYXJlZCA9IGluc3RhbGxhdGlvbi5kZWZpbml0aW9uLnJlcXVpcmVzID8/IFtdXG4gICAgICBjb25zdCBpbXBsaWNpdEZyb21UcmlnZ2Vyczogc3RyaW5nW10gPSBbXVxuICAgICAgZm9yIChjb25zdCB0cmlnZ2VyIG9mIGluc3RhbGxhdGlvbi5kZWZpbml0aW9uLnRyaWdnZXJzKSB7XG4gICAgICAgIGlmICh0cmlnZ2VyLmtpbmQgPT09IFwibW9kdWxlQWN0aW9uXCIgfHwgdHJpZ2dlci5raW5kID09PSBcIm1vZHVsZVN0YXRlQ2hhbmdlXCIpIHtcbiAgICAgICAgICBpbXBsaWNpdEZyb21UcmlnZ2Vycy5wdXNoKHRyaWdnZXIubW9kdWxlSWQpXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVxdWlyZXMgPSBBcnJheS5mcm9tKG5ldyBTZXQoWy4uLmRlY2xhcmVkLCAuLi5pbXBsaWNpdEZyb21UcmlnZ2Vyc10pKVxuICAgICAgaWYgKHJlcXVpcmVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdXG5cbiAgICAgIGNvbnN0IG1pc3Npbmc6IHN0cmluZ1tdID0gW11cbiAgICAgIGZvciAoY29uc3QgZGVwIG9mIHJlcXVpcmVzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgZGVwICE9PSBcInN0cmluZ1wiIHx8IGRlcC5sZW5ndGggPT09IDApIGNvbnRpbnVlXG5cbiAgICAgICAgLy8gTW9kdWxlVGFnIFx1NzY4NCBrZXkgXHU3RUE2XHU1QjlBXHU0RTNBIGBAbG9naXgvTW9kdWxlLyR7aWR9YFx1RkYxQlRhZyBpZGVudGl0eSBcdTU3RkFcdTRFOEUga2V5XHVGRjBDXHU1NkUwXHU2QjY0XHU1M0VGXHU0RUU1XHU2MzA5XHU5NzAwXHU2Nzg0XHU5MDIwXHUzMDAyXG4gICAgICAgIGNvbnN0IHRhZyA9IENvbnRleHQuVGFnKGBAbG9naXgvTW9kdWxlLyR7ZGVwfWApKCkgYXMgQ29udGV4dC5UYWc8YW55LCBhbnk+XG4gICAgICAgIGNvbnN0IGZvdW5kID0gQ29udGV4dC5nZXRPcHRpb24oaW5zdGFsbGF0aW9uLmVudiwgdGFnKVxuICAgICAgICBpZiAoT3B0aW9uLmlzTm9uZShmb3VuZCkpIHtcbiAgICAgICAgICBtaXNzaW5nLnB1c2goZGVwKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbWlzc2luZ1xuICAgIH1cblxuICAgIGNvbnN0IHN0b3BJbnN0YW5jZSA9IChcbiAgICAgIGluc3RhbmNlOiBJbnN0YW5jZVN0YXRlLFxuICAgICAgcmVhc29uOiBQcm9jZXNzSW5zdGFuY2VTdGF0dXNbXCJzdG9wcGVkUmVhc29uXCJdLFxuICAgICk6IEVmZmVjdC5FZmZlY3Q8dm9pZD4gPT5cbiAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgY29uc3QgZmliZXIgPSBpbnN0YW5jZS5maWJlclxuICAgICAgICBpbnN0YW5jZS5zdGF0dXMgPSB7XG4gICAgICAgICAgLi4uaW5zdGFuY2Uuc3RhdHVzLFxuICAgICAgICAgIHN0YXR1czogXCJzdG9wcGluZ1wiLFxuICAgICAgICAgIHN0b3BwZWRSZWFzb246IHJlYXNvbixcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmaWJlcikge1xuICAgICAgICAgIHlpZWxkKiBGaWJlci5pbnRlcnJ1cHQoZmliZXIpXG4gICAgICAgIH1cblxuICAgICAgICB5aWVsZCogUXVldWUuc2h1dGRvd24oaW5zdGFuY2UucGxhdGZvcm1UcmlnZ2Vyc1F1ZXVlKVxuXG4gICAgICAgIGluc3RhbmNlLnN0YXR1cyA9IHtcbiAgICAgICAgICAuLi5pbnN0YW5jZS5zdGF0dXMsXG4gICAgICAgICAgc3RhdHVzOiBcInN0b3BwZWRcIixcbiAgICAgICAgICBzdG9wcGVkUmVhc29uOiByZWFzb24sXG4gICAgICAgIH1cbiAgICAgICAgaW5zdGFuY2UuZmliZXIgPSB1bmRlZmluZWRcblxuICAgICAgICBjb25zdCBldnQ6IFByb2Nlc3NFdmVudCA9IHtcbiAgICAgICAgICB0eXBlOiBcInByb2Nlc3M6c3RvcFwiLFxuICAgICAgICAgIGlkZW50aXR5OiBpbnN0YW5jZS5pZGVudGl0eSxcbiAgICAgICAgICBzZXZlcml0eTogXCJpbmZvXCIsXG4gICAgICAgICAgZXZlbnRTZXE6IGluc3RhbmNlLm5leHRFdmVudFNlcSsrLFxuICAgICAgICAgIHRpbWVzdGFtcE1zOiBEYXRlLm5vdygpLFxuICAgICAgICB9XG4gICAgICAgIHlpZWxkKiBlbWl0KGV2dClcbiAgICAgIH0pXG5cbiAgICBjb25zdCBzdGFydEluc3RhbGxhdGlvbjogKGluc3RhbGxhdGlvbktleTogSW5zdGFsbGF0aW9uS2V5KSA9PiBFZmZlY3QuRWZmZWN0PHZvaWQ+ID0gKFxuICAgICAgaW5zdGFsbGF0aW9uS2V5LFxuICAgICkgPT5cbiAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgY29uc3QgaW5zdGFsbGF0aW9uID0gaW5zdGFsbGF0aW9ucy5nZXQoaW5zdGFsbGF0aW9uS2V5KVxuICAgICAgICBpZiAoIWluc3RhbGxhdGlvbikgcmV0dXJuXG5cbiAgICAgICAgY29uc3Qgbm9vcCA9IHlpZWxkKiBzaG91bGROb29wRHVlVG9TeW5jVHhuKGluc3RhbGxhdGlvbi5pZGVudGl0eS5zY29wZSwgXCJwcm9jZXNzX3N0YXJ0X2luX3RyYW5zYWN0aW9uXCIpXG4gICAgICAgIGlmIChub29wKSByZXR1cm5cblxuICAgICAgICAvLyBcdTgyRTVcdTVERjJcdTY3MDlcdTZEM0JcdThEQzNcdTVCOUVcdTRGOEJcdUZGMENcdTUyMTlcdTRFMERcdTkxQ0RcdTU5MERcdTU0MkZcdTUyQThcdTMwMDJcbiAgICAgICAgY29uc3QgY3VycmVudElkID0gaW5zdGFsbGF0aW9uLmN1cnJlbnRJbnN0YW5jZUlkXG4gICAgICAgIGlmIChjdXJyZW50SWQpIHtcbiAgICAgICAgICBjb25zdCBjdXJyZW50ID0gaW5zdGFuY2VzLmdldChjdXJyZW50SWQpXG4gICAgICAgICAgaWYgKGN1cnJlbnQgJiYgY3VycmVudC5zdGF0dXMuc3RhdHVzID09PSBcInJ1bm5pbmdcIikge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcnVuU2VxID0gaW5zdGFsbGF0aW9uLm5leHRSdW5TZXErK1xuICAgICAgICBjb25zdCBpZGVudGl0eTogUHJvY2Vzc0luc3RhbmNlSWRlbnRpdHkgPSB7XG4gICAgICAgICAgaWRlbnRpdHk6IGluc3RhbGxhdGlvbi5pZGVudGl0eSxcbiAgICAgICAgICBydW5TZXEsXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJvY2Vzc0luc3RhbmNlSWQgPSBJZGVudGl0eS5wcm9jZXNzSW5zdGFuY2VJZEZyb21JZGVudGl0eShpZGVudGl0eSlcblxuICAgICAgICBjb25zdCBwbGF0Zm9ybVRyaWdnZXJzUXVldWUgPSB5aWVsZCogUXVldWUuc2xpZGluZzxQcm9jZXNzVHJpZ2dlcj4oNjQpXG5cbiAgICAgICAgY29uc3QgaW5zdGFuY2VTdGF0ZTogSW5zdGFuY2VTdGF0ZSA9IHtcbiAgICAgICAgICBpbnN0YWxsYXRpb25LZXksXG4gICAgICAgICAgcHJvY2Vzc0luc3RhbmNlSWQsXG4gICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgcHJvY2Vzc0lkOiBpbnN0YWxsYXRpb24uaWRlbnRpdHkucHJvY2Vzc0lkLFxuICAgICAgICAgIHNjb3BlOiBpbnN0YWxsYXRpb24uaWRlbnRpdHkuc2NvcGUsXG4gICAgICAgICAgcGxhdGZvcm1UcmlnZ2Vyc1F1ZXVlLFxuICAgICAgICAgIHN0YXR1czoge1xuICAgICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgICBzdGF0dXM6IFwic3RhcnRpbmdcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIG5leHRFdmVudFNlcTogMSxcbiAgICAgICAgICBuZXh0VHJpZ2dlclNlcTogMSxcbiAgICAgICAgfVxuXG4gICAgICAgIGluc3RhbmNlcy5zZXQocHJvY2Vzc0luc3RhbmNlSWQsIGluc3RhbmNlU3RhdGUpXG4gICAgICAgIGluc3RhbGxhdGlvbi5jdXJyZW50SW5zdGFuY2VJZCA9IHByb2Nlc3NJbnN0YW5jZUlkXG5cbiAgICAgICAgLy8gc3RhcnQgXHU0RThCXHU0RUY2XHVGRjFBXHU4ODY4XHU3OTNBXHU1QjlFXHU0RjhCXHU1REYyXHU4RkRCXHU1MTY1XHU1NDJGXHU1MkE4XHU2RDQxXHU3QTBCXHVGRjA4ZmliZXIgXHU1REYyIGZvcmtcdUZGMDlcdTMwMDJcbiAgICAgICAgeWllbGQqIGVtaXQoe1xuICAgICAgICAgIHR5cGU6IFwicHJvY2VzczpzdGFydFwiLFxuICAgICAgICAgIGlkZW50aXR5LFxuICAgICAgICAgIHNldmVyaXR5OiBcImluZm9cIixcbiAgICAgICAgICBldmVudFNlcTogaW5zdGFuY2VTdGF0ZS5uZXh0RXZlbnRTZXErKyxcbiAgICAgICAgICB0aW1lc3RhbXBNczogRGF0ZS5ub3coKSxcbiAgICAgICAgfSlcblxuICAgICAgICBjb25zdCBtaXNzaW5nID0gcmVzb2x2ZU1pc3NpbmdEZXBlbmRlbmNpZXMoaW5zdGFsbGF0aW9uKVxuICAgICAgICBpZiAobWlzc2luZy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3QgaGludCA9IGlzRGV2RW52KClcbiAgICAgICAgICAgID8gW1xuICAgICAgICAgICAgICAgIFwiU3RyaWN0IHNjb3BlIGRlcGVuZGVuY3kgcmVzb2x1dGlvbjogbWlzc2luZyByZXF1aXJlZCBtb2R1bGVzIGluIHRoZSBjdXJyZW50IHNjb3BlLlwiLFxuICAgICAgICAgICAgICAgIGBtaXNzaW5nOiAke21pc3Npbmcuam9pbihcIiwgXCIpfWAsXG4gICAgICAgICAgICAgICAgXCJcIixcbiAgICAgICAgICAgICAgICBcImZpeDpcIixcbiAgICAgICAgICAgICAgICBcIi0gUHJvdmlkZSB0aGUgbWlzc2luZyBtb2R1bGUgaW1wbGVtZW50YXRpb24ocykgaW4gdGhlIHNhbWUgc2NvcGUgdmlhIGltcG9ydHMuXCIsXG4gICAgICAgICAgICAgICAgYCAgRXhhbXBsZTogUm9vdE1vZHVsZS5pbXBsZW1lbnQoeyBpbXBvcnRzOiBbJHttaXNzaW5nWzBdfS5pbXBsZW1lbnQoLi4uKS5pbXBsXSwgcHJvY2Vzc2VzOiBbLi4uXSB9KWAsXG4gICAgICAgICAgICAgICAgXCItIERvIG5vdCByZWx5IG9uIGNyb3NzLXNjb3BlIGZhbGxiYWNrcyAvIGd1ZXNzaW5nIGluc3RhbmNlcy5cIixcbiAgICAgICAgICAgICAgXS5qb2luKFwiXFxuXCIpXG4gICAgICAgICAgICA6IHVuZGVmaW5lZFxuXG4gICAgICAgICAgY29uc3QgZXJyb3I6IFNlcmlhbGl6YWJsZUVycm9yU3VtbWFyeSA9IHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IGBNaXNzaW5nIGRlcGVuZGVuY2llcyBpbiBzY29wZTogJHttaXNzaW5nLmpvaW4oXCIsIFwiKX1gLFxuICAgICAgICAgICAgY29kZTogXCJwcm9jZXNzOjptaXNzaW5nX2RlcGVuZGVuY3lcIixcbiAgICAgICAgICAgIGhpbnQsXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaW5zdGFuY2VTdGF0ZS5zdGF0dXMgPSB7XG4gICAgICAgICAgICAuLi5pbnN0YW5jZVN0YXRlLnN0YXR1cyxcbiAgICAgICAgICAgIHN0YXR1czogXCJmYWlsZWRcIixcbiAgICAgICAgICAgIHN0b3BwZWRSZWFzb246IFwiZmFpbGVkXCIsXG4gICAgICAgICAgICBsYXN0RXJyb3I6IGVycm9yLFxuICAgICAgICAgIH1cblxuICAgICAgICAgIHlpZWxkKiBlbWl0KHtcbiAgICAgICAgICAgIHR5cGU6IFwicHJvY2VzczplcnJvclwiLFxuICAgICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgICBzZXZlcml0eTogXCJlcnJvclwiLFxuICAgICAgICAgICAgZXZlbnRTZXE6IGluc3RhbmNlU3RhdGUubmV4dEV2ZW50U2VxKyssXG4gICAgICAgICAgICB0aW1lc3RhbXBNczogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIGVycm9yLFxuICAgICAgICAgIH0pXG5cbiAgICAgICAgICB5aWVsZCogZW1pdEVycm9yRGlhZ25vc3RpYyhcbiAgICAgICAgICAgIGluc3RhbGxhdGlvbi5pZGVudGl0eS5zY29wZSxcbiAgICAgICAgICAgIGluc3RhbGxhdGlvbi5pZGVudGl0eS5wcm9jZXNzSWQsXG4gICAgICAgICAgICBcInByb2Nlc3M6Om1pc3NpbmdfZGVwZW5kZW5jeVwiLFxuICAgICAgICAgICAgZXJyb3IubWVzc2FnZSxcbiAgICAgICAgICAgIGhpbnQsXG4gICAgICAgICAgKVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc2hvdWxkUmVjb3JkQ2hhaW5FdmVudHMgPSBpbnN0YWxsYXRpb24uZGVmaW5pdGlvbi5kaWFnbm9zdGljc0xldmVsICE9PSBcIm9mZlwiXG5cbiAgICAgICAgY29uc3QgYmFzZUVudiA9IGluc3RhbGxhdGlvbi5lbnZcblxuICAgICAgICBjb25zdCBtYWtlV3JhcHBlZEVudiA9ICgpOiBDb250ZXh0LkNvbnRleHQ8YW55PiA9PiB7XG4gICAgICAgICAgaWYgKCFzaG91bGRSZWNvcmRDaGFpbkV2ZW50cykge1xuICAgICAgICAgICAgcmV0dXJuIGJhc2VFbnZcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCByZXF1aXJlcyA9IGluc3RhbGxhdGlvbi5kZWZpbml0aW9uLnJlcXVpcmVzID8/IFtdXG4gICAgICAgICAgaWYgKHJlcXVpcmVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGJhc2VFbnZcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBpZHMgPSBBcnJheS5mcm9tKG5ldyBTZXQocmVxdWlyZXMpKVxuICAgICAgICAgIGxldCBuZXh0RW52ID0gYmFzZUVudlxuXG4gICAgICAgICAgZm9yIChjb25zdCBtb2R1bGVJZCBvZiBpZHMpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbW9kdWxlSWQgIT09IFwic3RyaW5nXCIgfHwgbW9kdWxlSWQubGVuZ3RoID09PSAwKSBjb250aW51ZVxuICAgICAgICAgICAgY29uc3QgdGFnID0gQ29udGV4dC5UYWcoYEBsb2dpeC9Nb2R1bGUvJHttb2R1bGVJZH1gKSgpIGFzIENvbnRleHQuVGFnPGFueSwgYW55PlxuICAgICAgICAgICAgY29uc3QgZm91bmQgPSBDb250ZXh0LmdldE9wdGlvbihiYXNlRW52LCB0YWcpXG4gICAgICAgICAgICBpZiAoT3B0aW9uLmlzTm9uZShmb3VuZCkpIGNvbnRpbnVlXG4gICAgICAgICAgICBjb25zdCBydW50aW1lID0gZm91bmQudmFsdWUgYXMgYW55XG5cbiAgICAgICAgICAgIGNvbnN0IHJlY29yZERpc3BhdGNoID0gKGFjdGlvbjogdW5rbm93bikgPT5cbiAgICAgICAgICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRyaWdnZXIgPSB5aWVsZCogRmliZXJSZWYuZ2V0KGN1cnJlbnRQcm9jZXNzVHJpZ2dlcilcbiAgICAgICAgICAgICAgICBpZiAoIXRyaWdnZXIpIHJldHVyblxuXG4gICAgICAgICAgICAgICAgY29uc3QgYWN0aW9uSWQgPSBhY3Rpb25JZEZyb21Vbmtub3duKGFjdGlvbikgPz8gXCJ1bmtub3duXCJcbiAgICAgICAgICAgICAgICBjb25zdCBkaXNwYXRjaE1vZHVsZUlkID0gdHlwZW9mIHJ1bnRpbWUubW9kdWxlSWQgPT09IFwic3RyaW5nXCIgPyBydW50aW1lLm1vZHVsZUlkIDogbW9kdWxlSWRcbiAgICAgICAgICAgICAgICBjb25zdCBkaXNwYXRjaEluc3RhbmNlSWQgPSB0eXBlb2YgcnVudGltZS5pbnN0YW5jZUlkID09PSBcInN0cmluZ1wiID8gcnVudGltZS5pbnN0YW5jZUlkIDogXCJ1bmtub3duXCJcblxuICAgICAgICAgICAgICAgIGNvbnN0IGV2dDogUHJvY2Vzc0V2ZW50ID0ge1xuICAgICAgICAgICAgICAgICAgdHlwZTogXCJwcm9jZXNzOmRpc3BhdGNoXCIsXG4gICAgICAgICAgICAgICAgICBpZGVudGl0eSxcbiAgICAgICAgICAgICAgICAgIHRyaWdnZXIsXG4gICAgICAgICAgICAgICAgICBkaXNwYXRjaDoge1xuICAgICAgICAgICAgICAgICAgICBtb2R1bGVJZDogZGlzcGF0Y2hNb2R1bGVJZCxcbiAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VJZDogZGlzcGF0Y2hJbnN0YW5jZUlkLFxuICAgICAgICAgICAgICAgICAgICBhY3Rpb25JZCxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBzZXZlcml0eTogXCJpbmZvXCIsXG4gICAgICAgICAgICAgICAgICBldmVudFNlcTogaW5zdGFuY2VTdGF0ZS5uZXh0RXZlbnRTZXErKyxcbiAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcE1zOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHlpZWxkKiBlbWl0KGV2dClcbiAgICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZCA9IHtcbiAgICAgICAgICAgICAgLi4ucnVudGltZSxcbiAgICAgICAgICAgICAgZGlzcGF0Y2g6IChhY3Rpb246IHVua25vd24pID0+XG4gICAgICAgICAgICAgICAgcnVudGltZS5kaXNwYXRjaChhY3Rpb24pLnBpcGUoRWZmZWN0LnRhcCgoKSA9PiByZWNvcmREaXNwYXRjaChhY3Rpb24pKSksXG4gICAgICAgICAgICAgIGRpc3BhdGNoTG93UHJpb3JpdHk6IChhY3Rpb246IHVua25vd24pID0+XG4gICAgICAgICAgICAgICAgcnVudGltZS5kaXNwYXRjaExvd1ByaW9yaXR5KGFjdGlvbikucGlwZShFZmZlY3QudGFwKCgpID0+IHJlY29yZERpc3BhdGNoKGFjdGlvbikpKSxcbiAgICAgICAgICAgICAgZGlzcGF0Y2hCYXRjaDogKGFjdGlvbnM6IFJlYWRvbmx5QXJyYXk8dW5rbm93bj4pID0+XG4gICAgICAgICAgICAgICAgcnVudGltZS5kaXNwYXRjaEJhdGNoKGFjdGlvbnMpLnBpcGUoXG4gICAgICAgICAgICAgICAgICBFZmZlY3QudGFwKCgpID0+IEVmZmVjdC5mb3JFYWNoKGFjdGlvbnMsIHJlY29yZERpc3BhdGNoLCB7IGRpc2NhcmQ6IHRydWUgfSkpLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG5leHRFbnYgPSBDb250ZXh0LmFkZCh0YWcsIHdyYXBwZWQpKG5leHRFbnYpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIG5leHRFbnZcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHdyYXBwZWRFbnYgPSBtYWtlV3JhcHBlZEVudigpXG5cbiAgICAgICAgY29uc3QgbWFrZVRyaWdnZXJTdHJlYW0gPSAoXG4gICAgICAgICAgc3BlYzogUHJvY2Vzc1RyaWdnZXJTcGVjLFxuICAgICAgICApOiBFZmZlY3QuRWZmZWN0PFN0cmVhbS5TdHJlYW08UHJvY2Vzc1RyaWdnZXI+LCBFcnJvcj4gPT5cbiAgICAgICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBpZiAoc3BlYy5raW5kID09PSBcInRpbWVyXCIpIHtcbiAgICAgICAgICAgICAgY29uc3QgaW50ZXJ2YWwgPSBEdXJhdGlvbi5kZWNvZGVVbmtub3duKHNwZWMudGltZXJJZClcbiAgICAgICAgICAgICAgaWYgKE9wdGlvbi5pc05vbmUoaW50ZXJ2YWwpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyID0gbmV3IEVycm9yKGBbUHJvY2Vzc1J1bnRpbWVdIGludmFsaWQgdGltZXJJZCAoZXhwZWN0ZWQgRHVyYXRpb25JbnB1dCk6ICR7c3BlYy50aW1lcklkfWApXG4gICAgICAgICAgICAgICAgOyhlcnIgYXMgYW55KS5jb2RlID0gXCJwcm9jZXNzOjppbnZhbGlkX3RpbWVyX2lkXCJcbiAgICAgICAgICAgICAgICA7KGVyciBhcyBhbnkpLmhpbnQgPVxuICAgICAgICAgICAgICAgICAgXCJ0aW1lcklkIG11c3QgYmUgYSB2YWxpZCBEdXJhdGlvbklucHV0IHN0cmluZywgZS5nLiAnMTAgbWlsbGlzJywgJzEgc2Vjb25kcycsICc1IG1pbnV0ZXMnLlwiXG4gICAgICAgICAgICAgICAgcmV0dXJuIHlpZWxkKiBFZmZlY3QuZmFpbChlcnIpXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICByZXR1cm4gU3RyZWFtLnRpY2soaW50ZXJ2YWwudmFsdWUpLnBpcGUoXG4gICAgICAgICAgICAgICAgU3RyZWFtLm1hcChcbiAgICAgICAgICAgICAgICAgICgpID0+XG4gICAgICAgICAgICAgICAgICAgICh7XG4gICAgICAgICAgICAgICAgICAgICAga2luZDogXCJ0aW1lclwiLFxuICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IHNwZWMubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICB0aW1lcklkOiBzcGVjLnRpbWVySWQsXG4gICAgICAgICAgICAgICAgICAgIH0pIHNhdGlzZmllcyBQcm9jZXNzVHJpZ2dlcixcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzcGVjLmtpbmQgPT09IFwibW9kdWxlQWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgY29uc3QgdGFnID0gQ29udGV4dC5UYWcoYEBsb2dpeC9Nb2R1bGUvJHtzcGVjLm1vZHVsZUlkfWApKCkgYXMgQ29udGV4dC5UYWc8YW55LCBhbnk+XG4gICAgICAgICAgICAgIGNvbnN0IGZvdW5kID0gQ29udGV4dC5nZXRPcHRpb24oYmFzZUVudiwgdGFnKVxuICAgICAgICAgICAgICBpZiAoT3B0aW9uLmlzTm9uZShmb3VuZCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geWllbGQqIEVmZmVjdC5mYWlsKG5ldyBFcnJvcihgTWlzc2luZyBtb2R1bGUgcnVudGltZSBpbiBzY29wZTogJHtzcGVjLm1vZHVsZUlkfWApKVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY29uc3QgcnVudGltZSA9IGZvdW5kLnZhbHVlIGFzIGFueVxuXG4gICAgICAgICAgICAgIC8vIHBlcmZcdUZGMUFkaWFnbm9zdGljcz1vZmYgXHU2NUY2XHU5MDdGXHU1MTREXHU4QkEyXHU5NjA1IGFjdGlvbnNXaXRoTWV0YSRcdUZGMDhcdThCRTVcdTkwMUFcdTkwNTNcdTU3MjggdHhuIFx1NTE4NSBwdWJsaXNoXHVGRjBDXHU4QkEyXHU5NjA1XHU4MDA1XHU4RDhBXHU1OTFBXHU4RDhBXHU1RjcxXHU1NENEXHU3MEVEXHU4REVGXHU1Rjg0XHVGRjA5XHUzMDAyXG4gICAgICAgICAgICAgIC8vIGRpYWdub3N0aWNzPWxpZ2h0L2Z1bGwgXHU2MjREXHU5NzAwXHU4OTgxIHR4blNlcS90eG5JZCBcdTk1MUFcdTcwQjlcdUZGMENcdTU2RTBcdTZCNjRcdTRFQzVcdTU3MjhcdTVGMDBcdTU0MkZcdTk0RkVcdThERUZcdTRFOEJcdTRFRjZcdTY1RjZcdTRGN0ZcdTc1MjggYWN0aW9uc1dpdGhNZXRhJFx1MzAwMlxuICAgICAgICAgICAgICBpZiAoIXNob3VsZFJlY29yZENoYWluRXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtID0gcnVudGltZS5hY3Rpb25zJCBhcyBTdHJlYW0uU3RyZWFtPGFueT4gfCB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICBpZiAoIXN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgZXJyID0gbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICAgICBcIk1vZHVsZVJ1bnRpbWUgZG9lcyBub3QgcHJvdmlkZSBhY3Rpb25zJCAocmVxdWlyZWQgZm9yIG1vZHVsZUFjdGlvbiB0cmlnZ2VyKS5cIixcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgIDsoZXJyIGFzIGFueSkuY29kZSA9IFwicHJvY2Vzczo6bWlzc2luZ19hY3Rpb25fc3RyZWFtXCJcbiAgICAgICAgICAgICAgICAgIDsoZXJyIGFzIGFueSkuaGludCA9IGBtb2R1bGVJZD0ke3NwZWMubW9kdWxlSWR9YFxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHlpZWxkKiBFZmZlY3QuZmFpbChlcnIpXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0cmVhbS5waXBlKFxuICAgICAgICAgICAgICAgICAgU3RyZWFtLmZpbHRlcigoYWN0aW9uOiBhbnkpID0+IGFjdGlvbklkRnJvbVVua25vd24oYWN0aW9uKSA9PT0gc3BlYy5hY3Rpb25JZCksXG4gICAgICAgICAgICAgICAgICBTdHJlYW0ubWFwKFxuICAgICAgICAgICAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICh7XG4gICAgICAgICAgICAgICAgICAgICAgICBraW5kOiBcIm1vZHVsZUFjdGlvblwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogc3BlYy5uYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlSWQ6IHNwZWMubW9kdWxlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUlkOiBydW50aW1lLmluc3RhbmNlSWQgYXMgc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uSWQ6IHNwZWMuYWN0aW9uSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eG5TZXE6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgfSkgc2F0aXNmaWVzIFByb2Nlc3NUcmlnZ2VyLFxuICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBydW50aW1lLmFjdGlvbnNXaXRoTWV0YSQgYXMgU3RyZWFtLlN0cmVhbTxhbnk+IHwgdW5kZWZpbmVkXG4gICAgICAgICAgICAgIGlmICghc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyID0gbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICAgXCJNb2R1bGVSdW50aW1lIGRvZXMgbm90IHByb3ZpZGUgYWN0aW9uc1dpdGhNZXRhJCAocmVxdWlyZWQgZm9yIG1vZHVsZUFjdGlvbiB0cmlnZ2VyKS5cIixcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgOyhlcnIgYXMgYW55KS5jb2RlID0gXCJwcm9jZXNzOjptaXNzaW5nX2FjdGlvbl9tZXRhX3N0cmVhbVwiXG4gICAgICAgICAgICAgICAgOyhlcnIgYXMgYW55KS5oaW50ID0gYG1vZHVsZUlkPSR7c3BlYy5tb2R1bGVJZH1gXG4gICAgICAgICAgICAgICAgcmV0dXJuIHlpZWxkKiBFZmZlY3QuZmFpbChlcnIpXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICByZXR1cm4gc3RyZWFtLnBpcGUoXG4gICAgICAgICAgICAgICAgU3RyZWFtLmZpbHRlcigoZXZ0OiBhbnkpID0+IGFjdGlvbklkRnJvbVVua25vd24oZXZ0LnZhbHVlKSA9PT0gc3BlYy5hY3Rpb25JZCksXG4gICAgICAgICAgICAgICAgU3RyZWFtLm1hcCgoZXZ0OiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHR4blNlcSA9IGV2dD8ubWV0YT8udHhuU2VxXG4gICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBraW5kOiBcIm1vZHVsZUFjdGlvblwiLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBzcGVjLm5hbWUsXG4gICAgICAgICAgICAgICAgICAgIG1vZHVsZUlkOiBzcGVjLm1vZHVsZUlkLFxuICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUlkOiBydW50aW1lLmluc3RhbmNlSWQgYXMgc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICBhY3Rpb25JZDogc3BlYy5hY3Rpb25JZCxcbiAgICAgICAgICAgICAgICAgICAgdHhuU2VxOiB0eXBlb2YgdHhuU2VxID09PSBcIm51bWJlclwiID8gdHhuU2VxIDogMSxcbiAgICAgICAgICAgICAgICAgIH0gc2F0aXNmaWVzIFByb2Nlc3NUcmlnZ2VyXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gbW9kdWxlU3RhdGVDaGFuZ2VcbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IHBhcnNlRG90UGF0aChzcGVjLnBhdGgpXG4gICAgICAgICAgICBpZiAoIXBhcnNlZC5vaykge1xuICAgICAgICAgICAgICByZXR1cm4geWllbGQqIEVmZmVjdC5mYWlsKHBhcnNlZC5lcnJvcilcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdGFnID0gQ29udGV4dC5UYWcoYEBsb2dpeC9Nb2R1bGUvJHtzcGVjLm1vZHVsZUlkfWApKCkgYXMgQ29udGV4dC5UYWc8YW55LCBhbnk+XG4gICAgICAgICAgICBjb25zdCBmb3VuZCA9IENvbnRleHQuZ2V0T3B0aW9uKGJhc2VFbnYsIHRhZylcbiAgICAgICAgICAgIGlmIChPcHRpb24uaXNOb25lKGZvdW5kKSkge1xuICAgICAgICAgICAgICByZXR1cm4geWllbGQqIEVmZmVjdC5mYWlsKG5ldyBFcnJvcihgTWlzc2luZyBtb2R1bGUgcnVudGltZSBpbiBzY29wZTogJHtzcGVjLm1vZHVsZUlkfWApKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBydW50aW1lID0gZm91bmQudmFsdWUgYXMgYW55XG4gICAgICAgICAgICBjb25zdCBzZWxlY3RvckJhc2UgPSBzZWxlY3RCeURvdFBhdGgocGFyc2VkLnNlZ21lbnRzKVxuICAgICAgICAgICAgY29uc3QgcHJldlJlZiA9IHlpZWxkKiBSZWYubWFrZTxPcHRpb24uT3B0aW9uPHVua25vd24+PihPcHRpb24ubm9uZSgpKVxuXG4gICAgICAgICAgICBjb25zdCBlbmFibGVTZWxlY3RvckRpYWdub3N0aWNzID0gc2hvdWxkUmVjb3JkQ2hhaW5FdmVudHNcblxuICAgICAgICAgICAgY29uc3Qgc2VsZWN0b3JEaWFnbm9zdGljc1JlZiA9IGVuYWJsZVNlbGVjdG9yRGlhZ25vc3RpY3NcbiAgICAgICAgICAgICAgPyB5aWVsZCogUmVmLm1ha2Uoe1xuICAgICAgICAgICAgICAgICAgd2luZG93U3RhcnRlZE1zOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICAgICAgdHJpZ2dlcnNJbldpbmRvdzogMCxcbiAgICAgICAgICAgICAgICAgIGxhc3RXYXJuaW5nQXRNczogMCxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICA6IHVuZGVmaW5lZFxuXG4gICAgICAgICAgICBjb25zdCBzYW1wbGVFdmVyeU1hc2sgPSAweDdmIC8vIHNhbXBsZSBldmVyeSAxMjggY2FsbHNcbiAgICAgICAgICAgIGNvbnN0IHNsb3dTYW1wbGVUaHJlc2hvbGRNcyA9IDRcbiAgICAgICAgICAgIGNvbnN0IHRyaWdnZXJXaW5kb3dNcyA9IDEwMDBcbiAgICAgICAgICAgIGNvbnN0IHRyaWdnZXJXYXJuaW5nVGhyZXNob2xkID0gaXNEZXZFbnYoKSA/IDIwIDogMjAwXG4gICAgICAgICAgICBjb25zdCB3YXJuaW5nQ29vbGRvd25NcyA9IDMwXzAwMFxuXG4gICAgICAgICAgICBsZXQgc2VsZWN0b3JDYWxscyA9IDBcbiAgICAgICAgICAgIGxldCBzZWxlY3RvclNhbXBsZXMgPSAwXG4gICAgICAgICAgICBsZXQgc2VsZWN0b3JTbG93U2FtcGxlcyA9IDBcbiAgICAgICAgICAgIGxldCBzZWxlY3Rvck1heFNhbXBsZU1zID0gMFxuXG4gICAgICAgICAgICBjb25zdCBub3dNcyA9ICgpOiBudW1iZXIgPT4ge1xuICAgICAgICAgICAgICBpZiAodHlwZW9mIHBlcmZvcm1hbmNlICE9PSBcInVuZGVmaW5lZFwiICYmIHR5cGVvZiBwZXJmb3JtYW5jZS5ub3cgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBwZXJmb3JtYW5jZS5ub3coKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBEYXRlLm5vdygpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdG9yID0gZW5hYmxlU2VsZWN0b3JEaWFnbm9zdGljc1xuICAgICAgICAgICAgICA/ICgoc3RhdGU6IHVua25vd24pOiB1bmtub3duID0+IHtcbiAgICAgICAgICAgICAgICAgIHNlbGVjdG9yQ2FsbHMgKz0gMVxuICAgICAgICAgICAgICAgICAgaWYgKChzZWxlY3RvckNhbGxzICYgc2FtcGxlRXZlcnlNYXNrKSAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0b3JCYXNlKHN0YXRlKVxuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICBjb25zdCB0MCA9IG5vd01zKClcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gc2VsZWN0b3JCYXNlKHN0YXRlKVxuICAgICAgICAgICAgICAgICAgY29uc3QgZHQgPSBub3dNcygpIC0gdDBcblxuICAgICAgICAgICAgICAgICAgc2VsZWN0b3JTYW1wbGVzICs9IDFcbiAgICAgICAgICAgICAgICAgIGlmIChkdCA+PSBzbG93U2FtcGxlVGhyZXNob2xkTXMpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3JTbG93U2FtcGxlcyArPSAxXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBpZiAoZHQgPiBzZWxlY3Rvck1heFNhbXBsZU1zKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yTWF4U2FtcGxlTXMgPSBkdFxuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICA6IHNlbGVjdG9yQmFzZVxuXG4gICAgICAgICAgICBjb25zdCBtYXliZVdhcm5TZWxlY3RvciA9ICh0cmlnZ2VyOiBQcm9jZXNzVHJpZ2dlcik6IEVmZmVjdC5FZmZlY3Q8dm9pZD4gPT4ge1xuICAgICAgICAgICAgICBpZiAoIXNlbGVjdG9yRGlhZ25vc3RpY3NSZWYpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHJldHVybiBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKVxuXG4gICAgICAgICAgICAgICAgY29uc3QgZGVjaXNpb24gPSB5aWVsZCogUmVmLm1vZGlmeShzZWxlY3RvckRpYWdub3N0aWNzUmVmLCAocykgPT4ge1xuICAgICAgICAgICAgICAgICAgY29uc3Qgd2luZG93RXhwaXJlZCA9IG5vdyAtIHMud2luZG93U3RhcnRlZE1zID49IHRyaWdnZXJXaW5kb3dNc1xuICAgICAgICAgICAgICAgICAgY29uc3Qgd2luZG93U3RhcnRlZE1zID0gd2luZG93RXhwaXJlZCA/IG5vdyA6IHMud2luZG93U3RhcnRlZE1zXG4gICAgICAgICAgICAgICAgICBjb25zdCB0cmlnZ2Vyc0luV2luZG93ID0gd2luZG93RXhwaXJlZCA/IDEgOiBzLnRyaWdnZXJzSW5XaW5kb3cgKyAxXG5cbiAgICAgICAgICAgICAgICAgIGNvbnN0IHNob3VsZENvb2xkb3duID0gbm93IC0gcy5sYXN0V2FybmluZ0F0TXMgPCB3YXJuaW5nQ29vbGRvd25Nc1xuICAgICAgICAgICAgICAgICAgY29uc3QgdG9vRnJlcXVlbnQgPSB0cmlnZ2Vyc0luV2luZG93ID49IHRyaWdnZXJXYXJuaW5nVGhyZXNob2xkXG4gICAgICAgICAgICAgICAgICBjb25zdCB0b29TbG93ID0gc2VsZWN0b3JNYXhTYW1wbGVNcyA+PSBzbG93U2FtcGxlVGhyZXNob2xkTXMgJiYgc2VsZWN0b3JTYW1wbGVzID4gMFxuICAgICAgICAgICAgICAgICAgY29uc3Qgc2hvdWxkV2FybiA9ICFzaG91bGRDb29sZG93biAmJiAodG9vRnJlcXVlbnQgfHwgdG9vU2xvdylcblxuICAgICAgICAgICAgICAgICAgY29uc3QgbmV4dCA9IHNob3VsZFdhcm5cbiAgICAgICAgICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3dTdGFydGVkTXM6IG5vdyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyaWdnZXJzSW5XaW5kb3c6IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICBsYXN0V2FybmluZ0F0TXM6IG5vdyxcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4ucyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvd1N0YXJ0ZWRNcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyaWdnZXJzSW5XaW5kb3csXG4gICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgc2hvdWxkV2FybixcbiAgICAgICAgICAgICAgICAgICAgICB0b29GcmVxdWVudCxcbiAgICAgICAgICAgICAgICAgICAgICB0b29TbG93LFxuICAgICAgICAgICAgICAgICAgICAgIHRyaWdnZXJzSW5XaW5kb3csXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIG5leHQsXG4gICAgICAgICAgICAgICAgICBdIGFzIGNvbnN0XG4gICAgICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgICAgIGlmICghZGVjaXNpb24uc2hvdWxkV2Fybikge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgY29kZSA9IGRlY2lzaW9uLnRvb0ZyZXF1ZW50XG4gICAgICAgICAgICAgICAgICA/IFwicHJvY2Vzczo6c2VsZWN0b3JfaGlnaF9mcmVxdWVuY3lcIlxuICAgICAgICAgICAgICAgICAgOiBcInByb2Nlc3M6OnNlbGVjdG9yX3Nsb3dcIlxuXG4gICAgICAgICAgICAgICAgY29uc3QgaGludCA9IFtcbiAgICAgICAgICAgICAgICAgIGBtb2R1bGVJZD0ke3NwZWMubW9kdWxlSWR9YCxcbiAgICAgICAgICAgICAgICAgIGBwYXRoPSR7c3BlYy5wYXRofWAsXG4gICAgICAgICAgICAgICAgICBgd2luZG93TXM9JHt0cmlnZ2VyV2luZG93TXN9YCxcbiAgICAgICAgICAgICAgICAgIGB0cmlnZ2Vyc0luV2luZG93PSR7ZGVjaXNpb24udHJpZ2dlcnNJbldpbmRvd31gLFxuICAgICAgICAgICAgICAgICAgYHRocmVzaG9sZD0ke3RyaWdnZXJXYXJuaW5nVGhyZXNob2xkfWAsXG4gICAgICAgICAgICAgICAgICBgY29vbGRvd25Ncz0ke3dhcm5pbmdDb29sZG93bk1zfWAsXG4gICAgICAgICAgICAgICAgICBcIlwiLFxuICAgICAgICAgICAgICAgICAgXCJzZWxlY3RvciBzYW1wbGluZzpcIixcbiAgICAgICAgICAgICAgICAgIGBjYWxscz0ke3NlbGVjdG9yQ2FsbHN9YCxcbiAgICAgICAgICAgICAgICAgIGBzYW1wbGVkPSR7c2VsZWN0b3JTYW1wbGVzfWAsXG4gICAgICAgICAgICAgICAgICBgc2xvd1NhbXBsZXMoPj0ke3Nsb3dTYW1wbGVUaHJlc2hvbGRNc31tcyk9JHtzZWxlY3RvclNsb3dTYW1wbGVzfWAsXG4gICAgICAgICAgICAgICAgICBgbWF4U2FtcGxlTXM9JHtzZWxlY3Rvck1heFNhbXBsZU1zLnRvRml4ZWQoMil9YCxcbiAgICAgICAgICAgICAgICAgIFwiXCIsXG4gICAgICAgICAgICAgICAgICBcIm5vdGVzOlwiLFxuICAgICAgICAgICAgICAgICAgXCItIEVuc3VyZSB0aGUgc2VsZWN0ZWQgdmFsdWUgaXMgc3RhYmxlIChwcmVmZXIgcHJpbWl0aXZlL3R1cGxlOyBhdm9pZCByZXR1cm5pbmcgZnJlc2ggb2JqZWN0cykuXCIsXG4gICAgICAgICAgICAgICAgICBcIi0gTmFycm93IHRoZSBwYXRoIHRvIHJlZHVjZSBjaGFuZ2UgZnJlcXVlbmN5OyBhdm9pZCBzZWxlY3RpbmcgbGFyZ2Ugb2JqZWN0cy5cIixcbiAgICAgICAgICAgICAgICBdLmpvaW4oXCJcXG5cIilcblxuICAgICAgICAgICAgICAgIHNlbGVjdG9yU2FtcGxlcyA9IDBcbiAgICAgICAgICAgICAgICBzZWxlY3RvclNsb3dTYW1wbGVzID0gMFxuICAgICAgICAgICAgICAgIHNlbGVjdG9yTWF4U2FtcGxlTXMgPSAwXG5cbiAgICAgICAgICAgICAgICB5aWVsZCogZW1pdCh7XG4gICAgICAgICAgICAgICAgICB0eXBlOiBcInByb2Nlc3M6dHJpZ2dlclwiLFxuICAgICAgICAgICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgICAgICAgICB0cmlnZ2VyLFxuICAgICAgICAgICAgICAgICAgc2V2ZXJpdHk6IFwid2FybmluZ1wiLFxuICAgICAgICAgICAgICAgICAgZXZlbnRTZXE6IGluc3RhbmNlU3RhdGUubmV4dEV2ZW50U2VxKyssXG4gICAgICAgICAgICAgICAgICB0aW1lc3RhbXBNczogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IFwibW9kdWxlU3RhdGVDaGFuZ2Ugc2VsZWN0b3IgZGlhZ25vc3RpY3Mgd2FybmluZ1wiLFxuICAgICAgICAgICAgICAgICAgICBjb2RlLFxuICAgICAgICAgICAgICAgICAgICBoaW50LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9IHNhdGlzZmllcyBQcm9jZXNzRXZlbnQpXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGJhc2VTdHJlYW0gPSAocnVudGltZS5jaGFuZ2VzV2l0aE1ldGEoc2VsZWN0b3IpIGFzIFN0cmVhbS5TdHJlYW08YW55PikucGlwZShcbiAgICAgICAgICAgICAgU3RyZWFtLm1hcEVmZmVjdCgoZXZ0OiBhbnkpID0+XG4gICAgICAgICAgICAgICAgUmVmLmdldChwcmV2UmVmKS5waXBlKFxuICAgICAgICAgICAgICAgICAgRWZmZWN0LmZsYXRNYXAoKHByZXYpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKE9wdGlvbi5pc1NvbWUocHJldikgJiYgT2JqZWN0LmlzKHByZXYudmFsdWUsIGV2dC52YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRWZmZWN0LnN1Y2NlZWQoT3B0aW9uLm5vbmUoKSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUmVmLnNldChwcmV2UmVmLCBPcHRpb24uc29tZShldnQudmFsdWUpKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgIEVmZmVjdC5hcyhPcHRpb24uc29tZShldnQpKSxcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgU3RyZWFtLmZpbHRlck1hcCgob3B0KSA9PiBvcHQpLFxuICAgICAgICAgICAgICBTdHJlYW0ubWFwKChldnQ6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHR4blNlcSA9IGV2dD8ubWV0YT8udHhuU2VxXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgIGtpbmQ6IFwibW9kdWxlU3RhdGVDaGFuZ2VcIixcbiAgICAgICAgICAgICAgICAgIG5hbWU6IHNwZWMubmFtZSxcbiAgICAgICAgICAgICAgICAgIG1vZHVsZUlkOiBzcGVjLm1vZHVsZUlkLFxuICAgICAgICAgICAgICAgICAgaW5zdGFuY2VJZDogcnVudGltZS5pbnN0YW5jZUlkIGFzIHN0cmluZyxcbiAgICAgICAgICAgICAgICAgIHBhdGg6IHNwZWMucGF0aCxcbiAgICAgICAgICAgICAgICAgIHR4blNlcTogdHlwZW9mIHR4blNlcSA9PT0gXCJudW1iZXJcIiA/IHR4blNlcSA6IDEsXG4gICAgICAgICAgICAgICAgfSBzYXRpc2ZpZXMgUHJvY2Vzc1RyaWdnZXJcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApXG5cbiAgICAgICAgICAgIHJldHVybiBlbmFibGVTZWxlY3RvckRpYWdub3N0aWNzID8gYmFzZVN0cmVhbS5waXBlKFN0cmVhbS50YXAobWF5YmVXYXJuU2VsZWN0b3IpKSA6IGJhc2VTdHJlYW1cbiAgICAgICAgICB9KVxuXG4gICAgICAgIGNvbnN0IG1ha2VSdW4gPSAoXG4gICAgICAgICAgdHJpZ2dlcjogUHJvY2Vzc1RyaWdnZXIsXG4gICAgICAgICAgZmF0YWw6IERlZmVycmVkLkRlZmVycmVkPENhdXNlLkNhdXNlPGFueT4+LFxuICAgICAgICApOiBFZmZlY3QuRWZmZWN0PHZvaWQ+ID0+XG4gICAgICAgICAgRWZmZWN0LmxvY2FsbHkoY3VycmVudFByb2Nlc3NUcmlnZ2VyLCB0cmlnZ2VyKShcbiAgICAgICAgICAgIEVmZmVjdC5wcm92aWRlKGluc3RhbGxhdGlvbi5wcm9jZXNzLCB3cmFwcGVkRW52KS5waXBlKFxuICAgICAgICAgICAgICBFZmZlY3QuY2F0Y2hBbGxDYXVzZSgoY2F1c2UpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoQ2F1c2UuaXNJbnRlcnJ1cHRlZE9ubHkoY2F1c2UpKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIERlZmVycmVkLnN1Y2NlZWQoZmF0YWwsIGNhdXNlKS5waXBlKEVmZmVjdC5hc1ZvaWQsIEVmZmVjdC5jYXRjaEFsbCgoKSA9PiBFZmZlY3Qudm9pZCkpXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApXG5cbiAgICAgICAgY29uc3QgbWFrZUNoYWluUnVuID0gKFxuICAgICAgICAgIHRyaWdnZXI6IFByb2Nlc3NUcmlnZ2VyLFxuICAgICAgICAgIGZhdGFsOiBEZWZlcnJlZC5EZWZlcnJlZDxDYXVzZS5DYXVzZTxhbnk+PixcbiAgICAgICAgKTogRWZmZWN0LkVmZmVjdDx2b2lkPiA9PiB7XG4gICAgICAgICAgaWYgKCFzaG91bGRSZWNvcmRDaGFpbkV2ZW50cykge1xuICAgICAgICAgICAgcmV0dXJuIG1ha2VSdW4odHJpZ2dlciwgZmF0YWwpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZGdldFJlZiA9IHlpZWxkKiBSZWYubWFrZShQcm9jZXNzRXZlbnRzLm1ha2VQcm9jZXNzUnVuRXZlbnRCdWRnZXRTdGF0ZSgpKVxuICAgICAgICAgICAgcmV0dXJuIHlpZWxkKiBFZmZlY3QubG9jYWxseShjdXJyZW50UHJvY2Vzc0V2ZW50QnVkZ2V0LCBidWRnZXRSZWYpKFxuICAgICAgICAgICAgICBlbWl0VHJpZ2dlckV2ZW50KHRyaWdnZXIsIFwiaW5mb1wiKS5waXBlKFxuICAgICAgICAgICAgICAgIEVmZmVjdC56aXBSaWdodChtYWtlUnVuKHRyaWdnZXIsIGZhdGFsKSksXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICApXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFzc2lnblRyaWdnZXJTZXEgPSAodHJpZ2dlcjogUHJvY2Vzc1RyaWdnZXIpOiBQcm9jZXNzVHJpZ2dlciA9PiAoe1xuICAgICAgICAgIC4uLnRyaWdnZXIsXG4gICAgICAgICAgdHJpZ2dlclNlcTogaW5zdGFuY2VTdGF0ZS5uZXh0VHJpZ2dlclNlcSsrLFxuICAgICAgICB9KVxuXG4gICAgICAgIGNvbnN0IGVtaXRUcmlnZ2VyRXZlbnQgPSAoXG4gICAgICAgICAgdHJpZ2dlcjogUHJvY2Vzc1RyaWdnZXIsXG4gICAgICAgICAgc2V2ZXJpdHk6IFByb2Nlc3NFdmVudFtcInNldmVyaXR5XCJdLFxuICAgICAgICApOiBFZmZlY3QuRWZmZWN0PHZvaWQ+ID0+IHtcbiAgICAgICAgICBpZiAoIXNob3VsZFJlY29yZENoYWluRXZlbnRzKSB7XG4gICAgICAgICAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBldnQ6IFByb2Nlc3NFdmVudCA9IHtcbiAgICAgICAgICAgIHR5cGU6IFwicHJvY2Vzczp0cmlnZ2VyXCIsXG4gICAgICAgICAgICBpZGVudGl0eSxcbiAgICAgICAgICAgIHRyaWdnZXIsXG4gICAgICAgICAgICBzZXZlcml0eSxcbiAgICAgICAgICAgIGV2ZW50U2VxOiBpbnN0YW5jZVN0YXRlLm5leHRFdmVudFNlcSsrLFxuICAgICAgICAgICAgdGltZXN0YW1wTXM6IERhdGUubm93KCksXG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBlbWl0KGV2dClcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBvbGljeSA9IGluc3RhbGxhdGlvbi5kZWZpbml0aW9uLmNvbmN1cnJlbmN5XG4gICAgICAgIGNvbnN0IGF1dG9TdGFydCA9IGluc3RhbGxhdGlvbi5kZWZpbml0aW9uLnRyaWdnZXJzLnNvbWUoXG4gICAgICAgICAgKHQpID0+IHQua2luZCA9PT0gXCJwbGF0Zm9ybUV2ZW50XCIgJiYgdC5wbGF0Zm9ybUV2ZW50ID09PSBSVU5USU1FX0JPT1RfRVZFTlQsXG4gICAgICAgIClcbiAgICAgICAgY29uc3QgYm9vdFRyaWdnZXJTcGVjID0gaW5zdGFsbGF0aW9uLmRlZmluaXRpb24udHJpZ2dlcnMuZmluZChcbiAgICAgICAgICAodCk6IHQgaXMgRXh0cmFjdDxQcm9jZXNzVHJpZ2dlclNwZWMsIHsgcmVhZG9ubHkga2luZDogXCJwbGF0Zm9ybUV2ZW50XCIgfT4gPT5cbiAgICAgICAgICAgIHQua2luZCA9PT0gXCJwbGF0Zm9ybUV2ZW50XCIgJiYgdC5wbGF0Zm9ybUV2ZW50ID09PSBSVU5USU1FX0JPT1RfRVZFTlQsXG4gICAgICAgIClcblxuICAgICAgICBjb25zdCBpbnN0YW5jZVByb2dyYW0gPSBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgY29uc3QgZmF0YWwgPSB5aWVsZCogRGVmZXJyZWQubWFrZTxDYXVzZS5DYXVzZTxhbnk+PigpXG5cbiAgICAgICAgICBjb25zdCBwbGF0Zm9ybUV2ZW50U3RyZWFtOiBTdHJlYW0uU3RyZWFtPFByb2Nlc3NUcmlnZ2VyPiA9IFN0cmVhbS5mcm9tUXVldWUoXG4gICAgICAgICAgICBpbnN0YW5jZVN0YXRlLnBsYXRmb3JtVHJpZ2dlcnNRdWV1ZSxcbiAgICAgICAgICApXG5cbiAgICAgICAgICBjb25zdCBzdHJlYW1zID0geWllbGQqIEVmZmVjdC5mb3JFYWNoKFxuICAgICAgICAgICAgaW5zdGFsbGF0aW9uLmRlZmluaXRpb24udHJpZ2dlcnMuZmlsdGVyKCh0KSA9PiB0LmtpbmQgIT09IFwicGxhdGZvcm1FdmVudFwiKSxcbiAgICAgICAgICAgIG1ha2VUcmlnZ2VyU3RyZWFtLFxuICAgICAgICAgIClcblxuICAgICAgICAgIGNvbnN0IHRyaWdnZXJTdHJlYW0gPSBTdHJlYW0ubWVyZ2VBbGwoW3BsYXRmb3JtRXZlbnRTdHJlYW0sIC4uLnN0cmVhbXNdLCB7XG4gICAgICAgICAgICBjb25jdXJyZW5jeTogXCJ1bmJvdW5kZWRcIixcbiAgICAgICAgICB9KVxuXG4gICAgICAgICAgY29uc3QgcmVwb3J0UXVldWVPdmVyZmxvdyA9IChcbiAgICAgICAgICAgIGluZm86IFByb2Nlc3NDb25jdXJyZW5jeS5Qcm9jZXNzVHJpZ2dlclF1ZXVlT3ZlcmZsb3dJbmZvLFxuICAgICAgICAgICk6IEVmZmVjdC5FZmZlY3Q8dm9pZD4gPT4ge1xuICAgICAgICAgICAgY29uc3QgZXJyID0gbmV3IEVycm9yKFwiUHJvY2VzcyB0cmlnZ2VyIHF1ZXVlIG92ZXJmbG93IChzZXJpYWwgbWF4UXVldWUgZ3VhcmQpLlwiKVxuICAgICAgICAgICAgOyhlcnIgYXMgYW55KS5jb2RlID0gXCJwcm9jZXNzOjpzZXJpYWxfcXVldWVfb3ZlcmZsb3dcIlxuICAgICAgICAgICAgOyhlcnIgYXMgYW55KS5oaW50ID0gW1xuICAgICAgICAgICAgICBgbW9kZT0ke2luZm8ubW9kZX1gLFxuICAgICAgICAgICAgICBgcXVldWU6IGN1cnJlbnQ9JHtpbmZvLmN1cnJlbnRMZW5ndGh9IHBlYWs9JHtpbmZvLnBlYWt9YCxcbiAgICAgICAgICAgICAgYG1heFF1ZXVlOiBjb25maWd1cmVkPSR7aW5mby5saW1pdC5jb25maWd1cmVkfSBndWFyZD0ke2luZm8ubGltaXQuZ3VhcmR9YCxcbiAgICAgICAgICAgICAgYHBvbGljeTogJHtKU09OLnN0cmluZ2lmeShpbmZvLnBvbGljeSl9YCxcbiAgICAgICAgICAgICAgXCJcIixcbiAgICAgICAgICAgICAgXCJmaXg6XCIsXG4gICAgICAgICAgICAgIFwiLSBDb25maWd1cmUgY29uY3VycmVuY3kubWF4UXVldWUgKHNlcmlhbCkgdG8gYSBmaW5pdGUgdmFsdWUsIG9yIHN3aXRjaCB0byBtb2RlPWxhdGVzdC9kcm9wIHRvIGF2b2lkIHVuYm91bmRlZCBiYWNrbG9nLlwiLFxuICAgICAgICAgICAgXS5qb2luKFwiXFxuXCIpXG4gICAgICAgICAgICByZXR1cm4gRGVmZXJyZWQuc3VjY2VlZChmYXRhbCwgQ2F1c2UuZmFpbChlcnIpKS5waXBlKEVmZmVjdC5hc1ZvaWQsIEVmZmVjdC5jYXRjaEFsbCgoKSA9PiBFZmZlY3Qudm9pZCkpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgcnVubmVyRmliZXIgPSB5aWVsZCogRWZmZWN0LmZvcmtTY29wZWQoXG4gICAgICAgICAgICBQcm9jZXNzQ29uY3VycmVuY3kucnVuUHJvY2Vzc1RyaWdnZXJTdHJlYW0oe1xuICAgICAgICAgICAgICBzdHJlYW06IHRyaWdnZXJTdHJlYW0sXG4gICAgICAgICAgICAgIHBvbGljeSxcbiAgICAgICAgICAgICAgYXNzaWduVHJpZ2dlclNlcSxcbiAgICAgICAgICAgICAgcnVuOiAodHJpZ2dlcikgPT4gbWFrZUNoYWluUnVuKHRyaWdnZXIsIGZhdGFsKSxcbiAgICAgICAgICAgICAgb25Ecm9wOiAodHJpZ2dlcikgPT4gZW1pdFRyaWdnZXJFdmVudCh0cmlnZ2VyLCBcIndhcm5pbmdcIiksXG4gICAgICAgICAgICAgIG9uUXVldWVPdmVyZmxvdzogcmVwb3J0UXVldWVPdmVyZmxvdyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIClcblxuICAgICAgICAgIGlmIChhdXRvU3RhcnQpIHtcbiAgICAgICAgICAgIHlpZWxkKiBRdWV1ZS5vZmZlcihpbnN0YW5jZVN0YXRlLnBsYXRmb3JtVHJpZ2dlcnNRdWV1ZSwge1xuICAgICAgICAgICAgICBraW5kOiBcInBsYXRmb3JtRXZlbnRcIixcbiAgICAgICAgICAgICAgbmFtZTogYm9vdFRyaWdnZXJTcGVjPy5uYW1lLFxuICAgICAgICAgICAgICBwbGF0Zm9ybUV2ZW50OiBSVU5USU1FX0JPT1RfRVZFTlQsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGNhdXNlID0geWllbGQqIERlZmVycmVkLmF3YWl0KGZhdGFsKVxuICAgICAgICAgIHlpZWxkKiBGaWJlci5pbnRlcnJ1cHQocnVubmVyRmliZXIpXG4gICAgICAgICAgcmV0dXJuIHlpZWxkKiBFZmZlY3QuZmFpbENhdXNlKGNhdXNlKVxuICAgICAgICB9KVxuXG4gICAgICAgIGNvbnN0IGZpYmVyID0geWllbGQqIEVmZmVjdC5mb3JrSW4oaW5zdGFsbGF0aW9uLmZvcmtTY29wZSkoXG4gICAgICAgICAgRWZmZWN0LnNjb3BlZChpbnN0YW5jZVByb2dyYW0pLnBpcGUoXG4gICAgICAgICAgICBFZmZlY3QuY2F0Y2hBbGxDYXVzZSgoY2F1c2UpID0+XG4gICAgICAgICAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgICAgICAvLyBcdTRFMkRcdTY1QURcdUZGMDhcdTkwMUFcdTVFMzhcdTY3NjVcdTgxRUEgc2NvcGUgZGlzcG9zZSAvIFx1NjI0Qlx1NTJBOCBzdG9wXHVGRjA5XHU0RTBEXHU1RTk0XHU4OEFCXHU1RjUzXHU0RjVDIHByb2Nlc3MgZmFpbHVyZVx1MzAwMlxuICAgICAgICAgICAgICAgIC8vIFx1NTQyNlx1NTIxOVx1NEYxQVx1NTcyOFx1NTE3M1x1OTVFRCBzY29wZSBcdTY1RjZcdTRFQTdcdTc1MUYgcHJvY2VzczplcnJvciAvIGRpYWdub3N0aWNcdUZGMENcdTVFNzZcdTUzRUZcdTgwRkRcdTVCRkNcdTgxRjQgZGlzcG9zZSBcdTUzNjFcdTZCN0JcdTMwMDJcbiAgICAgICAgICAgICAgICBpZiAoQ2F1c2UuaXNJbnRlcnJ1cHRlZE9ubHkoY2F1c2UpKSB7XG4gICAgICAgICAgICAgICAgICAvLyBcdTgyRTUgc3RvcEluc3RhbmNlIFx1NURGMlx1N0VDRlx1NjI4QVx1NzJCNlx1NjAwMVx1NjNBOFx1OEZEQlx1NTIzMCBzdG9wcGluZ1x1RkYwQ1x1NTIxOVx1NzUzMSBzdG9wSW5zdGFuY2UgXHU4RDFGXHU4RDIzIHN0b3AgXHU0RThCXHU0RUY2XHU0RTBFXHU2NzAwXHU3RUM4XHU3MkI2XHU2MDAxXHUzMDAyXG4gICAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2VTdGF0ZS5zdGF0dXMuc3RhdHVzID09PSBcInN0b3BwaW5nXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIC8vIFx1NTQyNlx1NTIxOVx1ODlDNlx1NEUzQSBzY29wZSBkaXNwb3NlIFx1NUJGQ1x1ODFGNFx1NzY4NFx1ODFFQVx1NzEzNlx1NTA1Q1x1NkI2Mlx1RkYwOFx1NEY4Qlx1NTk4MiBtb2R1bGVJbnN0YW5jZSBzY29wZSBcdTUxNzNcdTk1RURcdUZGMDlcdTMwMDJcbiAgICAgICAgICAgICAgICAgIGluc3RhbmNlU3RhdGUuc3RhdHVzID0ge1xuICAgICAgICAgICAgICAgICAgICAuLi5pbnN0YW5jZVN0YXRlLnN0YXR1cyxcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiBcInN0b3BwZWRcIixcbiAgICAgICAgICAgICAgICAgICAgc3RvcHBlZFJlYXNvbjogXCJzY29wZURpc3Bvc2VkXCIsXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBpbnN0YW5jZVN0YXRlLmZpYmVyID0gdW5kZWZpbmVkXG5cbiAgICAgICAgICAgICAgICAgIHlpZWxkKiBlbWl0KHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJwcm9jZXNzOnN0b3BcIixcbiAgICAgICAgICAgICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgICAgICAgICAgIHNldmVyaXR5OiBcImluZm9cIixcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRTZXE6IGluc3RhbmNlU3RhdGUubmV4dEV2ZW50U2VxKyssXG4gICAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcE1zOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHByaW1hcnkgPSBPcHRpb24uZ2V0T3JFbHNlKENhdXNlLmZhaWx1cmVPcHRpb24oY2F1c2UpLCAoKSA9PlxuICAgICAgICAgICAgICAgICAgT3B0aW9uLmdldE9yRWxzZShDYXVzZS5kaWVPcHRpb24oY2F1c2UpLCAoKSA9PiBjYXVzZSksXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIGNvbnN0IHN1bW1hcnkgPSB0b1NlcmlhbGl6YWJsZUVycm9yU3VtbWFyeShwcmltYXJ5KVxuICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yOiBTZXJpYWxpemFibGVFcnJvclN1bW1hcnkgPSBzdW1tYXJ5LmVycm9yU3VtbWFyeSBhcyBhbnlcblxuICAgICAgICAgICAgICAgIGluc3RhbmNlU3RhdGUuc3RhdHVzID0ge1xuICAgICAgICAgICAgICAgICAgLi4uaW5zdGFuY2VTdGF0ZS5zdGF0dXMsXG4gICAgICAgICAgICAgICAgICBzdGF0dXM6IFwiZmFpbGVkXCIsXG4gICAgICAgICAgICAgICAgICBzdG9wcGVkUmVhc29uOiBcImZhaWxlZFwiLFxuICAgICAgICAgICAgICAgICAgbGFzdEVycm9yOiBlcnJvcixcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB5aWVsZCogZW1pdCh7XG4gICAgICAgICAgICAgICAgICB0eXBlOiBcInByb2Nlc3M6ZXJyb3JcIixcbiAgICAgICAgICAgICAgICAgIGlkZW50aXR5LFxuICAgICAgICAgICAgICAgICAgc2V2ZXJpdHk6IFwiZXJyb3JcIixcbiAgICAgICAgICAgICAgICAgIGV2ZW50U2VxOiBpbnN0YW5jZVN0YXRlLm5leHRFdmVudFNlcSsrLFxuICAgICAgICAgICAgICAgICAgdGltZXN0YW1wTXM6IERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgICBlcnJvcixcbiAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgICAgY29uc3QgZGVjaXNpb24gPSBTdXBlcnZpc2lvbi5vbkZhaWx1cmUoXG4gICAgICAgICAgICAgICAgICBpbnN0YWxsYXRpb24uZGVmaW5pdGlvbi5lcnJvclBvbGljeSxcbiAgICAgICAgICAgICAgICAgIGluc3RhbGxhdGlvbi5zdXBlcnZpc2lvbixcbiAgICAgICAgICAgICAgICAgIERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIGluc3RhbGxhdGlvbi5zdXBlcnZpc2lvbiA9IGRlY2lzaW9uLm5leHRTdGF0ZVxuXG4gICAgICAgICAgICAgICAgaWYgKGRlY2lzaW9uLmRlY2lzaW9uID09PSBcInJlc3RhcnRcIikge1xuICAgICAgICAgICAgICAgICAgLy8gc3VwZXJ2aXNlXHVGRjFBXHU1M0Q3XHU2M0E3XHU5MUNEXHU1NDJGXHVGRjA4cnVuU2VxIFx1OTAxMlx1NTg5RVx1RkYwOVx1RkYwQ1x1NUU3Nlx1NEVBN1x1NTFGQSByZXN0YXJ0IFx1NEU4Qlx1NEVGNlx1MzAwMlxuICAgICAgICAgICAgICAgICAgeWllbGQqIGVtaXQoe1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiBcInByb2Nlc3M6cmVzdGFydFwiLFxuICAgICAgICAgICAgICAgICAgICBpZGVudGl0eSxcbiAgICAgICAgICAgICAgICAgICAgc2V2ZXJpdHk6IFwid2FybmluZ1wiLFxuICAgICAgICAgICAgICAgICAgICBldmVudFNlcTogaW5zdGFuY2VTdGF0ZS5uZXh0RXZlbnRTZXErKyxcbiAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wTXM6IERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLFxuICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgIHlpZWxkKiBzdGFydEluc3RhbGxhdGlvbihpbnN0YWxsYXRpb25LZXkpXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHlpZWxkKiBlbWl0RXJyb3JEaWFnbm9zdGljKFxuICAgICAgICAgICAgICAgICAgICBpbnN0YWxsYXRpb24uaWRlbnRpdHkuc2NvcGUsXG4gICAgICAgICAgICAgICAgICAgIGluc3RhbGxhdGlvbi5pZGVudGl0eS5wcm9jZXNzSWQsXG4gICAgICAgICAgICAgICAgICAgIFwicHJvY2Vzczo6ZmFpbGVkX3N0b3BcIixcbiAgICAgICAgICAgICAgICAgICAgXCJQcm9jZXNzIGZhaWxlZCBhbmQgc3RvcHBlZCAoZmFpbFN0b3AgLyByZXN0YXJ0IGxpbWl0IHJlYWNoZWQpLlwiLFxuICAgICAgICAgICAgICAgICAgICBgcHJvY2Vzc0lkPSR7aW5zdGFsbGF0aW9uLmlkZW50aXR5LnByb2Nlc3NJZH0gc2NvcGVLZXk9JHtpbnN0YWxsYXRpb24uc2NvcGVLZXl9IGZhaWx1cmVzPSR7ZGVjaXNpb24ud2l0aGluV2luZG93RmFpbHVyZXN9IG1heFJlc3RhcnRzPSR7ZGVjaXNpb24ubWF4UmVzdGFydHN9YCxcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApLFxuICAgICAgICApXG5cbiAgICAgICAgaW5zdGFuY2VTdGF0ZS5maWJlciA9IGZpYmVyIGFzIEZpYmVyLlJ1bnRpbWVGaWJlcjx1bmtub3duLCB1bmtub3duPlxuICAgICAgICBpbnN0YW5jZVN0YXRlLnN0YXR1cyA9IHtcbiAgICAgICAgICAuLi5pbnN0YW5jZVN0YXRlLnN0YXR1cyxcbiAgICAgICAgICBzdGF0dXM6IFwicnVubmluZ1wiLFxuICAgICAgICB9XG5cbiAgICAgICAgLy8gXHU1QzNEXHU5MUNGXHU0RkREXHU4QkMxXHU1NzI4IGluc3RhbGwvc3RhcnQgXHU4RkQ0XHU1NkRFXHU1MjREXHVGRjBDaW5zdGFuY2UgZmliZXIgXHU1REYyXHU1RjAwXHU1OUNCXHU4QkEyXHU5NjA1IHRyaWdnZXIgc3RyZWFtc1x1RkYwQ1xuICAgICAgICAvLyBcdTkwN0ZcdTUxNERcdTIwMUNcdTUyMUEgYnVpbGQgXHU1QjhDIGVudiBcdTVDMzEgZGlzcGF0Y2hcdTIwMURcdTVCRkNcdTgxRjQgbW9kdWxlQWN0aW9uL21vZHVsZVN0YXRlQ2hhbmdlIFx1ODlFNlx1NTNEMVx1NEUyMlx1NTkzMVx1MzAwMlxuICAgICAgICB5aWVsZCogRWZmZWN0LnlpZWxkTm93KClcbiAgICAgIH0pXG5cbiAgICBjb25zdCBpbnN0YWxsID0gPEUsIFI+KFxuICAgICAgcHJvY2VzczogRWZmZWN0LkVmZmVjdDx2b2lkLCBFLCBSPixcbiAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgcmVhZG9ubHkgc2NvcGU6IFByb2Nlc3NTY29wZVxuICAgICAgICByZWFkb25seSBlbmFibGVkPzogYm9vbGVhblxuICAgICAgICByZWFkb25seSBpbnN0YWxsZWRBdD86IHN0cmluZ1xuICAgICAgfSxcbiAgICApOiBFZmZlY3QuRWZmZWN0PFByb2Nlc3NJbnN0YWxsYXRpb24gfCB1bmRlZmluZWQsIG5ldmVyLCBSPiA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBjb25zdCBtZXRhID0gTWV0YS5nZXRNZXRhKHByb2Nlc3MpXG4gICAgICAgIGlmICghbWV0YSkge1xuICAgICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVudiA9IHlpZWxkKiBFZmZlY3QuY29udGV4dDxSPigpXG4gICAgICAgIGNvbnN0IGZvcmtTY29wZU9wdCA9IENvbnRleHQuZ2V0T3B0aW9uKGVudiBhcyBDb250ZXh0LkNvbnRleHQ8YW55PiwgU2NvcGUuU2NvcGUpXG4gICAgICAgIGNvbnN0IGZvcmtTY29wZSA9IE9wdGlvbi5pc1NvbWUoZm9ya1Njb3BlT3B0KSA/IGZvcmtTY29wZU9wdC52YWx1ZSA6IHJ1bnRpbWVTY29wZVxuXG4gICAgICAgIGNvbnN0IHNjb3BlS2V5ID0gSWRlbnRpdHkuc2NvcGVLZXlGcm9tU2NvcGUob3B0aW9ucy5zY29wZSlcbiAgICAgICAgY29uc3QgaWRlbnRpdHkgPSB7XG4gICAgICAgICAgcHJvY2Vzc0lkOiBtZXRhLmRlZmluaXRpb24ucHJvY2Vzc0lkLFxuICAgICAgICAgIHNjb3BlOiBvcHRpb25zLnNjb3BlLFxuICAgICAgICB9IGFzIGNvbnN0XG5cbiAgICAgICAgY29uc3QgaW5zdGFsbGF0aW9uS2V5ID0gSWRlbnRpdHkuaW5zdGFsbGF0aW9uS2V5RnJvbUlkZW50aXR5KGlkZW50aXR5KVxuICAgICAgICBjb25zdCBleGlzdGluZyA9IGluc3RhbGxhdGlvbnMuZ2V0KGluc3RhbGxhdGlvbktleSlcbiAgICAgICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICAgICAgZXhpc3RpbmcuZW5hYmxlZCA9IG9wdGlvbnMuZW5hYmxlZCA/PyB0cnVlXG4gICAgICAgICAgZXhpc3RpbmcuaW5zdGFsbGVkQXQgPSBvcHRpb25zLmluc3RhbGxlZEF0ID8/IGV4aXN0aW5nLmluc3RhbGxlZEF0XG4gICAgICAgICAgaWYgKGV4aXN0aW5nLmVuYWJsZWQgJiYgIWV4aXN0aW5nLmN1cnJlbnRJbnN0YW5jZUlkKSB7XG4gICAgICAgICAgICB5aWVsZCogc3RhcnRJbnN0YWxsYXRpb24oaW5zdGFsbGF0aW9uS2V5KVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgICBlbmFibGVkOiBleGlzdGluZy5lbmFibGVkLFxuICAgICAgICAgICAgaW5zdGFsbGVkQXQ6IGV4aXN0aW5nLmluc3RhbGxlZEF0LFxuICAgICAgICAgIH0gc2F0aXNmaWVzIFByb2Nlc3NJbnN0YWxsYXRpb25cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFx1NEUzQVx1NjcyQ1x1NkIyMVx1NUI4OVx1ODhDNVx1NkQzRVx1NzUxRlx1NEUwMFx1NEUyQSBlZmZlY3RcdUZGMENcdTkwN0ZcdTUxNERcdTg5ODZcdTc2RDZcdTUzOUZcdTU5Q0IgRWZmZWN0IFx1NEUwQVx1NzY4NCBtZXRhXHVGRjA4XHU1OTFBIHNjb3BlIFx1NTkwRFx1NzUyOFx1RkYwOVx1MzAwMlxuICAgICAgICAvLyBcdTZDRThcdTYxMEZcdUZGMUFcdThGRDlcdTkxQ0NcdTRFMERcdTYzRDBcdTUyNEQgcHJvdmlkZSBlbnZcdUZGMENcdTkwN0ZcdTUxNERcdTU0MEVcdTdFRURcdTY1RTBcdTZDRDVcdTU3MjhcdTZCQ0ZcdTZCMjFcdTg5RTZcdTUzRDFcdTYyNjdcdTg4NENcdTY1RjZcdTUzRTBcdTUyQTBcdTk4OURcdTU5MTZcdTRFMEFcdTRFMEJcdTY1ODdcdUZGMDhcdTRGOEJcdTU5ODIgZGlzcGF0Y2ggXHU5NEZFXHU4REVGXHU4QkNBXHU2NUFEXHVGRjA5XHUzMDAyXG4gICAgICAgIGNvbnN0IGRlcml2ZWQgPSBFZmZlY3Quc3VzcGVuZCgoKSA9PiBwcm9jZXNzKVxuICAgICAgICBNZXRhLmF0dGFjaE1ldGEoZGVyaXZlZCwge1xuICAgICAgICAgIC4uLm1ldGEsXG4gICAgICAgICAgaW5zdGFsbGF0aW9uU2NvcGU6IG9wdGlvbnMuc2NvcGUsXG4gICAgICAgIH0pXG5cbiAgICAgICAgY29uc3QgaW5zdGFsbGF0aW9uOiBJbnN0YWxsYXRpb25TdGF0ZSA9IHtcbiAgICAgICAgICBpZGVudGl0eSxcbiAgICAgICAgICBzY29wZUtleSxcbiAgICAgICAgICBkZWZpbml0aW9uOiBtZXRhLmRlZmluaXRpb24sXG4gICAgICAgICAgZW52OiBlbnYgYXMgQ29udGV4dC5Db250ZXh0PGFueT4sXG4gICAgICAgICAgZm9ya1Njb3BlLFxuICAgICAgICAgIHByb2Nlc3M6IGRlcml2ZWQgYXMgdW5rbm93biBhcyBFZmZlY3QuRWZmZWN0PHZvaWQsIGFueSwgdW5rbm93bj4sXG4gICAgICAgICAga2luZDogbWV0YS5raW5kID8/IFwicHJvY2Vzc1wiLFxuICAgICAgICAgIGVuYWJsZWQ6IG9wdGlvbnMuZW5hYmxlZCA/PyB0cnVlLFxuICAgICAgICAgIGluc3RhbGxlZEF0OiBvcHRpb25zLmluc3RhbGxlZEF0LFxuICAgICAgICAgIG5leHRSdW5TZXE6IDEsXG4gICAgICAgICAgc3VwZXJ2aXNpb246IFN1cGVydmlzaW9uLmluaXRpYWxTdGF0ZSgpLFxuICAgICAgICB9XG5cbiAgICAgICAgaW5zdGFsbGF0aW9ucy5zZXQoaW5zdGFsbGF0aW9uS2V5LCBpbnN0YWxsYXRpb24pXG5cbiAgICAgICAgaWYgKGluc3RhbGxhdGlvbi5lbmFibGVkKSB7XG4gICAgICAgICAgeWllbGQqIHN0YXJ0SW5zdGFsbGF0aW9uKGluc3RhbGxhdGlvbktleSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgaWRlbnRpdHksXG4gICAgICAgICAgZW5hYmxlZDogaW5zdGFsbGF0aW9uLmVuYWJsZWQsXG4gICAgICAgICAgaW5zdGFsbGVkQXQ6IGluc3RhbGxhdGlvbi5pbnN0YWxsZWRBdCxcbiAgICAgICAgfSBzYXRpc2ZpZXMgUHJvY2Vzc0luc3RhbGxhdGlvblxuICAgICAgfSlcblxuICAgIGNvbnN0IGxpc3RJbnN0YWxsYXRpb25zOiBQcm9jZXNzUnVudGltZVtcImxpc3RJbnN0YWxsYXRpb25zXCJdID0gKGZpbHRlcikgPT5cbiAgICAgIEVmZmVjdC5zeW5jKCgpID0+IHtcbiAgICAgICAgY29uc3Qgc2NvcGVUeXBlID0gZmlsdGVyPy5zY29wZVR5cGVcbiAgICAgICAgY29uc3Qgc2NvcGVLZXkgPSBmaWx0ZXI/LnNjb3BlS2V5XG4gICAgICAgIGNvbnN0IG91dDogUHJvY2Vzc0luc3RhbGxhdGlvbltdID0gW11cbiAgICAgICAgZm9yIChjb25zdCBpbnN0YWxsYXRpb24gb2YgaW5zdGFsbGF0aW9ucy52YWx1ZXMoKSkge1xuICAgICAgICAgIGlmIChzY29wZVR5cGUgJiYgaW5zdGFsbGF0aW9uLmlkZW50aXR5LnNjb3BlLnR5cGUgIT09IHNjb3BlVHlwZSkgY29udGludWVcbiAgICAgICAgICBpZiAoc2NvcGVLZXkgJiYgaW5zdGFsbGF0aW9uLnNjb3BlS2V5ICE9PSBzY29wZUtleSkgY29udGludWVcbiAgICAgICAgICBvdXQucHVzaCh7XG4gICAgICAgICAgICBpZGVudGl0eTogaW5zdGFsbGF0aW9uLmlkZW50aXR5LFxuICAgICAgICAgICAgZW5hYmxlZDogaW5zdGFsbGF0aW9uLmVuYWJsZWQsXG4gICAgICAgICAgICBpbnN0YWxsZWRBdDogaW5zdGFsbGF0aW9uLmluc3RhbGxlZEF0LFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG91dFxuICAgICAgfSlcblxuICAgIGNvbnN0IGdldEluc3RhbmNlU3RhdHVzOiBQcm9jZXNzUnVudGltZVtcImdldEluc3RhbmNlU3RhdHVzXCJdID0gKHByb2Nlc3NJbnN0YW5jZUlkKSA9PlxuICAgICAgRWZmZWN0LnN5bmMoKCkgPT4gaW5zdGFuY2VzLmdldChwcm9jZXNzSW5zdGFuY2VJZCk/LnN0YXR1cylcblxuICAgIGNvbnN0IGNvbnRyb2xJbnN0YW5jZTogUHJvY2Vzc1J1bnRpbWVbXCJjb250cm9sSW5zdGFuY2VcIl0gPSAocHJvY2Vzc0luc3RhbmNlSWQsIHJlcXVlc3QpID0+XG4gICAgICBFZmZlY3Quc3VzcGVuZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGluc3RhbmNlID0gaW5zdGFuY2VzLmdldChwcm9jZXNzSW5zdGFuY2VJZClcbiAgICAgICAgaWYgKCFpbnN0YW5jZSkge1xuICAgICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNob3VsZE5vb3BEdWVUb1N5bmNUeG4oaW5zdGFuY2Uuc2NvcGUsIFwicHJvY2Vzc19jb250cm9sX2luX3RyYW5zYWN0aW9uXCIpLnBpcGUoXG4gICAgICAgICAgRWZmZWN0LmZsYXRNYXAoKG5vb3ApID0+IHtcbiAgICAgICAgICAgIGlmIChub29wKSB7XG4gICAgICAgICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVxdWVzdC5hY3Rpb24gPT09IFwic3RvcFwiKSB7XG4gICAgICAgICAgICAgIHJldHVybiBzdG9wSW5zdGFuY2UoaW5zdGFuY2UsIFwibWFudWFsU3RvcFwiKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVxdWVzdC5hY3Rpb24gPT09IFwicmVzdGFydFwiKSB7XG4gICAgICAgICAgICAgIHJldHVybiBzdG9wSW5zdGFuY2UoaW5zdGFuY2UsIFwibWFudWFsU3RvcFwiKS5waXBlKFxuICAgICAgICAgICAgICAgIEVmZmVjdC5mbGF0TWFwKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGluc3RhbGxhdGlvbiA9IGluc3RhbGxhdGlvbnMuZ2V0KGluc3RhbmNlLmluc3RhbGxhdGlvbktleSlcbiAgICAgICAgICAgICAgICAgIGlmICghaW5zdGFsbGF0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgaW5zdGFsbGF0aW9uLmN1cnJlbnRJbnN0YW5jZUlkID0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICByZXR1cm4gc3RhcnRJbnN0YWxsYXRpb24oaW5zdGFuY2UuaW5zdGFsbGF0aW9uS2V5KVxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHN0YXJ0XHVGRjFBXHU0RUM1XHU1QkY5XHU1REYyXHU1MDVDXHU2QjYyXHU1QjlFXHU0RjhCXHU3NTFGXHU2NTQ4XHVGRjFCXHU1OTBEXHU3NTI4XHU1RjUzXHU1MjREIHJ1blNlcVx1RkYwQ1x1NEUwRFx1OTAxMlx1NTg5RVx1MzAwMlxuICAgICAgICAgICAgaWYgKHJlcXVlc3QuYWN0aW9uID09PSBcInN0YXJ0XCIpIHtcbiAgICAgICAgICAgICAgaWYgKGluc3RhbmNlLnN0YXR1cy5zdGF0dXMgPT09IFwicnVubmluZ1wiIHx8IGluc3RhbmNlLnN0YXR1cy5zdGF0dXMgPT09IFwic3RhcnRpbmdcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY29uc3QgaW5zdGFsbGF0aW9uID0gaW5zdGFsbGF0aW9ucy5nZXQoaW5zdGFuY2UuaW5zdGFsbGF0aW9uS2V5KVxuICAgICAgICAgICAgICBpZiAoIWluc3RhbGxhdGlvbikge1xuICAgICAgICAgICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGluc3RhbGxhdGlvbi5jdXJyZW50SW5zdGFuY2VJZCA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgICByZXR1cm4gc3RhcnRJbnN0YWxsYXRpb24oaW5zdGFuY2UuaW5zdGFsbGF0aW9uS2V5KVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gRWZmZWN0LnZvaWRcbiAgICAgICAgICB9KSxcbiAgICAgICAgKVxuICAgICAgfSlcblxuICAgIGNvbnN0IGRlbGl2ZXJQbGF0Zm9ybUV2ZW50OiBQcm9jZXNzUnVudGltZVtcImRlbGl2ZXJQbGF0Zm9ybUV2ZW50XCJdID0gKGV2ZW50KSA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBjb25zdCBub29wID0geWllbGQqIFRhc2tSdW5uZXIuc2hvdWxkTm9vcEluU3luY1RyYW5zYWN0aW9uRmliZXIoe1xuICAgICAgICAgIGNvZGU6IFwicHJvY2Vzczo6aW52YWxpZF91c2FnZVwiLFxuICAgICAgICAgIHNldmVyaXR5OiBcImVycm9yXCIsXG4gICAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAgIFwiUHJvY2Vzc1J1bnRpbWUgcGxhdGZvcm0gZXZlbnRzIGFyZSBub3QgYWxsb3dlZCBpbnNpZGUgYSBzeW5jaHJvbm91cyBTdGF0ZVRyYW5zYWN0aW9uIGJvZHkgKGl0IG1heSBkZWFkbG9jayB0aGUgdHhuUXVldWUpLlwiLFxuICAgICAgICAgIGhpbnQ6IFwiRGVsaXZlciBwbGF0Zm9ybUV2ZW50IG91dHNpZGUgdGhlIHRyYW5zYWN0aW9uIHdpbmRvdy5cIixcbiAgICAgICAgICBraW5kOiBcInByb2Nlc3NfcGxhdGZvcm1fZXZlbnRfaW5fdHJhbnNhY3Rpb25cIixcbiAgICAgICAgfSlcbiAgICAgICAgaWYgKG5vb3ApIHJldHVyblxuXG4gICAgICAgIGNvbnN0IHRhcmdldHMgPSBBcnJheS5mcm9tKGluc3RhbmNlcy52YWx1ZXMoKSlcbiAgICAgICAgY29uc3QgZXZlbnROYW1lID0gZXZlbnQuZXZlbnROYW1lXG5cbiAgICAgICAgeWllbGQqIEVmZmVjdC5mb3JFYWNoKFxuICAgICAgICAgIHRhcmdldHMsXG4gICAgICAgICAgKGluc3RhbmNlKSA9PlxuICAgICAgICAgICAgRWZmZWN0LnN1c3BlbmQoKCkgPT4ge1xuICAgICAgICAgICAgICBpZiAoaW5zdGFuY2Uuc3RhdHVzLnN0YXR1cyAhPT0gXCJzdGFydGluZ1wiICYmIGluc3RhbmNlLnN0YXR1cy5zdGF0dXMgIT09IFwicnVubmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBjb25zdCBpbnN0YWxsYXRpb24gPSBpbnN0YWxsYXRpb25zLmdldChpbnN0YW5jZS5pbnN0YWxsYXRpb25LZXkpXG4gICAgICAgICAgICAgIGlmICghaW5zdGFsbGF0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEVmZmVjdC52b2lkXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBjb25zdCBzcGVjcyA9IGluc3RhbGxhdGlvbi5kZWZpbml0aW9uLnRyaWdnZXJzLmZpbHRlcihcbiAgICAgICAgICAgICAgICAodCk6IHQgaXMgRXh0cmFjdDxQcm9jZXNzVHJpZ2dlclNwZWMsIHsgcmVhZG9ubHkga2luZDogXCJwbGF0Zm9ybUV2ZW50XCIgfT4gPT5cbiAgICAgICAgICAgICAgICAgIHQua2luZCA9PT0gXCJwbGF0Zm9ybUV2ZW50XCIgJiYgdC5wbGF0Zm9ybUV2ZW50ID09PSBldmVudE5hbWUsXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgaWYgKHNwZWNzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBFZmZlY3Qudm9pZFxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgcmV0dXJuIEVmZmVjdC5mb3JFYWNoKFxuICAgICAgICAgICAgICAgIHNwZWNzLFxuICAgICAgICAgICAgICAgIChzcGVjKSA9PlxuICAgICAgICAgICAgICAgICAgUXVldWUub2ZmZXIoaW5zdGFuY2UucGxhdGZvcm1UcmlnZ2Vyc1F1ZXVlLCB7XG4gICAgICAgICAgICAgICAgICAgIGtpbmQ6IFwicGxhdGZvcm1FdmVudFwiLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBzcGVjLm5hbWUsXG4gICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtRXZlbnQ6IHNwZWMucGxhdGZvcm1FdmVudCxcbiAgICAgICAgICAgICAgICAgIH0gc2F0aXNmaWVzIFByb2Nlc3NUcmlnZ2VyKSxcbiAgICAgICAgICAgICAgICB7IGRpc2NhcmQ6IHRydWUgfSxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgeyBkaXNjYXJkOiB0cnVlIH0sXG4gICAgICAgIClcbiAgICAgIH0pXG5cbiAgICBjb25zdCBldmVudHNTdHJlYW06IFByb2Nlc3NSdW50aW1lW1wiZXZlbnRzXCJdID0gU3RyZWFtLmZyb21QdWJTdWIoZXZlbnRzSHViKVxuXG4gICAgY29uc3QgZ2V0RXZlbnRzU25hcHNob3Q6IFByb2Nlc3NSdW50aW1lW1wiZ2V0RXZlbnRzU25hcHNob3RcIl0gPSAoKSA9PlxuICAgICAgRWZmZWN0LnN5bmMoKCkgPT4gZXZlbnRzQnVmZmVyLnNsaWNlKCkpXG5cbiAgICB5aWVsZCogRWZmZWN0LmFkZEZpbmFsaXplcigoKSA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBmb3IgKGNvbnN0IGluc3RhbmNlIG9mIGluc3RhbmNlcy52YWx1ZXMoKSkge1xuICAgICAgICAgIGlmIChpbnN0YW5jZS5maWJlcikge1xuICAgICAgICAgICAgeWllbGQqIHN0b3BJbnN0YW5jZShpbnN0YW5jZSwgXCJzY29wZURpc3Bvc2VkXCIpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KS5waXBlKFxuICAgICAgICBFZmZlY3QuY2F0Y2hBbGxDYXVzZSgoY2F1c2UpID0+XG4gICAgICAgICAgRWZmZWN0LnN5bmMoKCkgPT4ge1xuICAgICAgICAgICAgLy8gZmluYWxpemVyIFx1NEUwRFx1NUU5NFx1NjI5Qlx1NTFGQVx1RkYxQlx1OEZEOVx1OTFDQ1x1NEVDNSBiZXN0LWVmZm9ydCBcdThCQjBcdTVGNTVcdTMwMDJcbiAgICAgICAgICAgIGlmIChpc0RldkVudigpKSB7XG4gICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICAgIGNvbnNvbGUud2FybihcIltQcm9jZXNzUnVudGltZV0gZmluYWxpemVyIGZhaWxlZFwiLCBDYXVzZS5wcmV0dHkoY2F1c2UpKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICApXG5cbiAgICByZXR1cm4ge1xuICAgICAgaW5zdGFsbCxcbiAgICAgIGxpc3RJbnN0YWxsYXRpb25zLFxuICAgICAgZ2V0SW5zdGFuY2VTdGF0dXMsXG4gICAgICBjb250cm9sSW5zdGFuY2UsXG4gICAgICBkZWxpdmVyUGxhdGZvcm1FdmVudCxcbiAgICAgIGV2ZW50czogZXZlbnRzU3RyZWFtLFxuICAgICAgZ2V0RXZlbnRzU25hcHNob3QsXG4gICAgfSBzYXRpc2ZpZXMgUHJvY2Vzc1J1bnRpbWVcbiAgfSlcblxuZXhwb3J0IGNvbnN0IGxheWVyID0gKG9wdGlvbnM/OiB7XG4gIHJlYWRvbmx5IG1heEV2ZW50SGlzdG9yeT86IG51bWJlclxufSk6IExheWVyLkxheWVyPFByb2Nlc3NSdW50aW1lVGFnLCBuZXZlciwgbmV2ZXI+ID0+IExheWVyLnNjb3BlZChQcm9jZXNzUnVudGltZVRhZywgbWFrZShvcHRpb25zKSlcbiIsICJpbXBvcnQgdHlwZSB7IFByb2Nlc3NJZGVudGl0eSwgUHJvY2Vzc0luc3RhbmNlSWRlbnRpdHksIFByb2Nlc3NTY29wZSB9IGZyb20gXCIuL3Byb3RvY29sLmpzXCJcblxuZXhwb3J0IHR5cGUgUHJvY2Vzc1Njb3BlS2V5ID0gc3RyaW5nXG5cbmV4cG9ydCBjb25zdCBzY29wZUtleUZyb21TY29wZSA9IChzY29wZTogUHJvY2Vzc1Njb3BlKTogUHJvY2Vzc1Njb3BlS2V5ID0+IHtcbiAgc3dpdGNoIChzY29wZS50eXBlKSB7XG4gICAgY2FzZSBcImFwcFwiOlxuICAgICAgcmV0dXJuIGBhcHA6JHtzY29wZS5hcHBJZH1gXG4gICAgY2FzZSBcIm1vZHVsZUluc3RhbmNlXCI6XG4gICAgICByZXR1cm4gYG1vZHVsZUluc3RhbmNlOiR7c2NvcGUubW9kdWxlSWR9Ojoke3Njb3BlLmluc3RhbmNlSWR9YFxuICAgIGNhc2UgXCJ1aVN1YnRyZWVcIjpcbiAgICAgIHJldHVybiBgdWlTdWJ0cmVlOiR7c2NvcGUuc3VidHJlZUlkfWBcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgaW5zdGFsbGF0aW9uS2V5RnJvbUlkZW50aXR5ID0gKGlkZW50aXR5OiBQcm9jZXNzSWRlbnRpdHkpOiBzdHJpbmcgPT5cbiAgYCR7aWRlbnRpdHkucHJvY2Vzc0lkfUBAJHtzY29wZUtleUZyb21TY29wZShpZGVudGl0eS5zY29wZSl9YFxuXG5leHBvcnQgY29uc3QgcHJvY2Vzc0luc3RhbmNlSWRGcm9tSWRlbnRpdHkgPSAoXG4gIGlkZW50aXR5OiBQcm9jZXNzSW5zdGFuY2VJZGVudGl0eSxcbik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IHNjb3BlS2V5ID0gc2NvcGVLZXlGcm9tU2NvcGUoaWRlbnRpdHkuaWRlbnRpdHkuc2NvcGUpXG4gIHJldHVybiBgcHJvY2Vzczoke2lkZW50aXR5LmlkZW50aXR5LnByb2Nlc3NJZH06OiR7c2NvcGVLZXl9OjpyJHtpZGVudGl0eS5ydW5TZXF9YFxufVxuXG4iLCAiaW1wb3J0IHsgRWZmZWN0LCBGaWJlciwgT3B0aW9uLCBSZWYsIFNjb3BlLCBTdHJlYW0gfSBmcm9tIFwiZWZmZWN0XCJcbmltcG9ydCB0eXBlIHsgVGFza1J1bm5lck1vZGUgfSBmcm9tIFwiLi4vVGFza1J1bm5lci5qc1wiXG5pbXBvcnQgdHlwZSB7IFByb2Nlc3NDb25jdXJyZW5jeVBvbGljeSwgUHJvY2Vzc1RyaWdnZXIgfSBmcm9tIFwiLi9wcm90b2NvbC5qc1wiXG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1NFUklBTF9RVUVVRV9HVUFSRF9MSU1JVCA9IDQwOTZcbmV4cG9ydCBjb25zdCBERUZBVUxUX1BBUkFMTEVMX0xJTUlUID0gMTZcblxuZXhwb3J0IGNvbnN0IHRvVGFza1J1bm5lck1vZGUgPSAocG9saWN5OiBQcm9jZXNzQ29uY3VycmVuY3lQb2xpY3kpOiBUYXNrUnVubmVyTW9kZSA9PiB7XG4gIHN3aXRjaCAocG9saWN5Lm1vZGUpIHtcbiAgICBjYXNlIFwibGF0ZXN0XCI6XG4gICAgICByZXR1cm4gXCJsYXRlc3RcIlxuICAgIGNhc2UgXCJzZXJpYWxcIjpcbiAgICAgIHJldHVybiBcInRhc2tcIlxuICAgIGNhc2UgXCJkcm9wXCI6XG4gICAgICByZXR1cm4gXCJleGhhdXN0XCJcbiAgICBjYXNlIFwicGFyYWxsZWxcIjpcbiAgICAgIHJldHVybiBcInBhcmFsbGVsXCJcbiAgfVxufVxuXG5leHBvcnQgdHlwZSBSZXNvbHZlZFF1ZXVlTGltaXQgPSB7XG4gIC8qKiBcdTc1MjhcdTYyMzdcdTkxNERcdTdGNkVcdTc2ODRcdTRFMEFcdTk2NTBcdUZGMUJcdTY3MkFcdTkxNERcdTdGNkVcdTY1RjZcdTg5QzZcdTRFM0EgdW5saW1pdGVkXHVGRjA4XHU0RjQ2XHU0RUNEXHU1M0Q3IGd1YXJkIFx1OTY1MFx1NTIzNlx1RkYwOVx1MzAwMiAqL1xuICByZWFkb25seSBjb25maWd1cmVkOiBudW1iZXIgfCBcInVuYm91bmRlZFwiXG4gIC8qKiBcdThGRDBcdTg4NENcdTY1RjZcdTVCOUVcdTk2NDVcdTc1MUZcdTY1NDhcdTc2ODRcdTYyQTRcdTY4MEZcdTRFMEFcdTk2NTBcdUZGMDhcdTc1MjhcdTRFOEVcdTk2MzJcdTZCNjJcdTY1RTBcdTc1NENcdTUxODVcdTVCNThcdTU4OUVcdTk1N0ZcdUZGMDlcdTMwMDIgKi9cbiAgcmVhZG9ubHkgZ3VhcmQ6IG51bWJlclxufVxuXG5leHBvcnQgY29uc3QgcmVzb2x2ZVF1ZXVlTGltaXQgPSAoXG4gIG1heFF1ZXVlOiB1bmtub3duLFxuICBvcHRpb25zPzoge1xuICAgIHJlYWRvbmx5IGRlZmF1bHRHdWFyZD86IG51bWJlclxuICB9LFxuKTogUmVzb2x2ZWRRdWV1ZUxpbWl0ID0+IHtcbiAgY29uc3QgZGVmYXVsdEd1YXJkID0gb3B0aW9ucz8uZGVmYXVsdEd1YXJkID8/IERFRkFVTFRfU0VSSUFMX1FVRVVFX0dVQVJEX0xJTUlUXG5cbiAgY29uc3QgY29uZmlndXJlZCA9XG4gICAgdHlwZW9mIG1heFF1ZXVlID09PSBcIm51bWJlclwiICYmIE51bWJlci5pc0Zpbml0ZShtYXhRdWV1ZSkgJiYgbWF4UXVldWUgPj0gMFxuICAgICAgPyBNYXRoLmZsb29yKG1heFF1ZXVlKVxuICAgICAgOiBcInVuYm91bmRlZFwiXG5cbiAgcmV0dXJuIHtcbiAgICBjb25maWd1cmVkLFxuICAgIGd1YXJkOiBjb25maWd1cmVkID09PSBcInVuYm91bmRlZFwiID8gZGVmYXVsdEd1YXJkIDogY29uZmlndXJlZCxcbiAgfVxufVxuXG5leHBvcnQgdHlwZSBQcm9jZXNzVHJpZ2dlclF1ZXVlT3ZlcmZsb3dJbmZvID0ge1xuICByZWFkb25seSBtb2RlOiBcInNlcmlhbFwiIHwgXCJwYXJhbGxlbFwiXG4gIHJlYWRvbmx5IGN1cnJlbnRMZW5ndGg6IG51bWJlclxuICByZWFkb25seSBwZWFrOiBudW1iZXJcbiAgcmVhZG9ubHkgbGltaXQ6IFJlc29sdmVkUXVldWVMaW1pdFxuICByZWFkb25seSBwb2xpY3k6IFByb2Nlc3NDb25jdXJyZW5jeVBvbGljeVxufVxuXG5leHBvcnQgY29uc3QgcnVuUHJvY2Vzc1RyaWdnZXJTdHJlYW0gPSAoYXJnczoge1xuICByZWFkb25seSBzdHJlYW06IFN0cmVhbS5TdHJlYW08UHJvY2Vzc1RyaWdnZXI+XG4gIHJlYWRvbmx5IHBvbGljeTogUHJvY2Vzc0NvbmN1cnJlbmN5UG9saWN5XG4gIHJlYWRvbmx5IGFzc2lnblRyaWdnZXJTZXE6ICh0cmlnZ2VyOiBQcm9jZXNzVHJpZ2dlcikgPT4gUHJvY2Vzc1RyaWdnZXJcbiAgLyoqIHJ1biBhIHRyaWdnZXIgdG8gY29tcGxldGlvbiAodGhlIGNhbGxlciBkZWNpZGVzIHdoYXQgYSBcXFwicnVuXFxcIiBtZWFucykuICovXG4gIHJlYWRvbmx5IHJ1bjogKHRyaWdnZXI6IFByb2Nlc3NUcmlnZ2VyKSA9PiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBTY29wZS5TY29wZT5cbiAgLyoqIGludm9rZWQgd2hlbiBhIHRyaWdnZXIgaXMgZHJvcHBlZCAob25seSBmb3IgbW9kZT1kcm9wKS4gKi9cbiAgcmVhZG9ubHkgb25Ecm9wOiAodHJpZ2dlcjogUHJvY2Vzc1RyaWdnZXIpID0+IEVmZmVjdC5FZmZlY3Q8dm9pZD5cbiAgLyoqIGludm9rZWQgd2hlbiBpbnRlcm5hbCBxdWV1ZSBndWFyZCBpcyBleGNlZWRlZCAoZmFpbC1zdG9wIGJ5IGRlZmF1bHQpLiAqL1xuICByZWFkb25seSBvblF1ZXVlT3ZlcmZsb3c6IChpbmZvOiBQcm9jZXNzVHJpZ2dlclF1ZXVlT3ZlcmZsb3dJbmZvKSA9PiBFZmZlY3QuRWZmZWN0PHZvaWQ+XG4gIHJlYWRvbmx5IGRlZmF1bHRQYXJhbGxlbExpbWl0PzogbnVtYmVyXG4gIHJlYWRvbmx5IGRlZmF1bHRRdWV1ZUd1YXJkPzogbnVtYmVyXG59KTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgU2NvcGUuU2NvcGU+ID0+XG4gIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBwb2xpY3kgPSBhcmdzLnBvbGljeVxuICAgIGNvbnN0IGRlZmF1bHRRdWV1ZUd1YXJkID0gYXJncy5kZWZhdWx0UXVldWVHdWFyZCA/PyBERUZBVUxUX1NFUklBTF9RVUVVRV9HVUFSRF9MSU1JVFxuXG4gICAgY29uc3QgcnVuTGF0ZXN0ID0geWllbGQqIFJlZi5tYWtlPEZpYmVyLlJ1bnRpbWVGaWJlcjx2b2lkLCBuZXZlcj4gfCB1bmRlZmluZWQ+KHVuZGVmaW5lZClcbiAgICBjb25zdCBsYXRlc3RSdW5JZFJlZiA9IHlpZWxkKiBSZWYubWFrZSgwKVxuICAgIGNvbnN0IGxhdGVzdFJ1bm5pbmdJZFJlZiA9IHlpZWxkKiBSZWYubWFrZSgwKVxuICAgIGNvbnN0IGJ1c3lSZWYgPSB5aWVsZCogUmVmLm1ha2UoZmFsc2UpXG4gICAgY29uc3Qgc2VyaWFsU3RhdGVSZWYgPSB5aWVsZCogUmVmLm1ha2Uoe1xuICAgICAgcnVubmluZzogZmFsc2UsXG4gICAgICBxdWV1ZTogW10gYXMgUHJvY2Vzc1RyaWdnZXJbXSxcbiAgICAgIHBlYWs6IDAsXG4gICAgfSlcbiAgICBjb25zdCBwYXJhbGxlbFN0YXRlUmVmID0geWllbGQqIFJlZi5tYWtlKHtcbiAgICAgIGFjdGl2ZTogMCxcbiAgICAgIHF1ZXVlOiBbXSBhcyBQcm9jZXNzVHJpZ2dlcltdLFxuICAgICAgcGVhazogMCxcbiAgICB9KVxuXG4gICAgY29uc3Qgc2VyaWFsUXVldWVMaW1pdCA9IHJlc29sdmVRdWV1ZUxpbWl0KHBvbGljeS5tYXhRdWV1ZSwgeyBkZWZhdWx0R3VhcmQ6IGRlZmF1bHRRdWV1ZUd1YXJkIH0pXG4gICAgY29uc3QgcGFyYWxsZWxRdWV1ZUxpbWl0ID0gcmVzb2x2ZVF1ZXVlTGltaXQodW5kZWZpbmVkLCB7IGRlZmF1bHRHdWFyZDogZGVmYXVsdFF1ZXVlR3VhcmQgfSlcbiAgICBjb25zdCBwYXJhbGxlbExpbWl0ID1cbiAgICAgIHR5cGVvZiBwb2xpY3kubWF4UGFyYWxsZWwgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzRmluaXRlKHBvbGljeS5tYXhQYXJhbGxlbCkgJiYgcG9saWN5Lm1heFBhcmFsbGVsID49IDFcbiAgICAgICAgPyBNYXRoLmZsb29yKHBvbGljeS5tYXhQYXJhbGxlbClcbiAgICAgICAgOiAoYXJncy5kZWZhdWx0UGFyYWxsZWxMaW1pdCA/PyBERUZBVUxUX1BBUkFMTEVMX0xJTUlUKVxuXG4gICAgY29uc3QgZHJhaW5TZXJpYWwgPSAoKTogRWZmZWN0LkVmZmVjdDx2b2lkLCBuZXZlciwgU2NvcGUuU2NvcGU+ID0+XG4gICAgICBFZmZlY3Quc3VzcGVuZCgoKSA9PlxuICAgICAgICBSZWYubW9kaWZ5KHNlcmlhbFN0YXRlUmVmLCAoc3RhdGUpID0+IHtcbiAgICAgICAgICBpZiAoc3RhdGUucnVubmluZyB8fCBzdGF0ZS5xdWV1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBbT3B0aW9uLm5vbmUoKSwgc3RhdGVdIGFzIGNvbnN0XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IFtuZXh0LCAuLi5yZXN0XSA9IHN0YXRlLnF1ZXVlXG4gICAgICAgICAgcmV0dXJuIFtPcHRpb24uc29tZShuZXh0KSwgeyAuLi5zdGF0ZSwgcnVubmluZzogdHJ1ZSwgcXVldWU6IHJlc3QgfV0gYXMgY29uc3RcbiAgICAgICAgfSkucGlwZShcbiAgICAgICAgICBFZmZlY3QuZmxhdE1hcCgobmV4dCkgPT5cbiAgICAgICAgICAgIE9wdGlvbi5tYXRjaChuZXh0LCB7XG4gICAgICAgICAgICAgIG9uTm9uZTogKCkgPT4gRWZmZWN0LnZvaWQsXG4gICAgICAgICAgICAgIG9uU29tZTogKHRyaWdnZXIpID0+XG4gICAgICAgICAgICAgICAgRWZmZWN0LmZvcmtTY29wZWQoXG4gICAgICAgICAgICAgICAgICBhcmdzXG4gICAgICAgICAgICAgICAgICAgIC5ydW4odHJpZ2dlcilcbiAgICAgICAgICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgRWZmZWN0LmVuc3VyaW5nKFxuICAgICAgICAgICAgICAgICAgICAgICAgUmVmLnVwZGF0ZShzZXJpYWxTdGF0ZVJlZiwgKHMpID0+ICh7IC4uLnMsIHJ1bm5pbmc6IGZhbHNlIH0pKSxcbiAgICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICAgIEVmZmVjdC56aXBSaWdodChkcmFpblNlcmlhbCgpKSxcbiAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICApLnBpcGUoRWZmZWN0LmFzVm9pZCksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgKVxuXG4gICAgY29uc3QgZHJhaW5QYXJhbGxlbCA9ICgpOiBFZmZlY3QuRWZmZWN0PHZvaWQsIG5ldmVyLCBTY29wZS5TY29wZT4gPT5cbiAgICAgIEVmZmVjdC5zdXNwZW5kKCgpID0+XG4gICAgICAgIFJlZi5tb2RpZnkocGFyYWxsZWxTdGF0ZVJlZiwgKHN0YXRlKSA9PiB7XG4gICAgICAgICAgaWYgKHN0YXRlLmFjdGl2ZSA+PSBwYXJhbGxlbExpbWl0IHx8IHN0YXRlLnF1ZXVlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIFtPcHRpb24ubm9uZSgpLCBzdGF0ZV0gYXMgY29uc3RcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgW25leHQsIC4uLnJlc3RdID0gc3RhdGUucXVldWVcbiAgICAgICAgICByZXR1cm4gW09wdGlvbi5zb21lKG5leHQpLCB7IC4uLnN0YXRlLCBhY3RpdmU6IHN0YXRlLmFjdGl2ZSArIDEsIHF1ZXVlOiByZXN0IH1dIGFzIGNvbnN0XG4gICAgICAgIH0pLnBpcGUoXG4gICAgICAgICAgRWZmZWN0LmZsYXRNYXAoKG5leHQpID0+XG4gICAgICAgICAgICBPcHRpb24ubWF0Y2gobmV4dCwge1xuICAgICAgICAgICAgICBvbk5vbmU6ICgpID0+IEVmZmVjdC52b2lkLFxuICAgICAgICAgICAgICBvblNvbWU6ICh0cmlnZ2VyKSA9PlxuICAgICAgICAgICAgICAgIEVmZmVjdC5mb3JrU2NvcGVkKFxuICAgICAgICAgICAgICAgICAgYXJnc1xuICAgICAgICAgICAgICAgICAgICAucnVuKHRyaWdnZXIpXG4gICAgICAgICAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgIEVmZmVjdC5lbnN1cmluZyhcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlZi51cGRhdGUocGFyYWxsZWxTdGF0ZVJlZiwgKHMpID0+ICh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZTogTWF0aC5tYXgoMCwgcy5hY3RpdmUgLSAxKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICAgIEVmZmVjdC56aXBSaWdodChkcmFpblBhcmFsbGVsKCkpLFxuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICkucGlwZShFZmZlY3QuYXNWb2lkLCBFZmZlY3QuemlwUmlnaHQoZHJhaW5QYXJhbGxlbCgpKSksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgKVxuXG4gICAgY29uc3Qgb25UcmlnZ2VyID0gKHRyaWdnZXIwOiBQcm9jZXNzVHJpZ2dlcik6IEVmZmVjdC5FZmZlY3Q8dm9pZCwgbmV2ZXIsIFNjb3BlLlNjb3BlPiA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBjb25zdCB0cmlnZ2VyID0gYXJncy5hc3NpZ25UcmlnZ2VyU2VxKHRyaWdnZXIwKVxuXG4gICAgICAgIGlmIChwb2xpY3kubW9kZSA9PT0gXCJsYXRlc3RcIikge1xuICAgICAgICAgIGNvbnN0IHByZXZSdW5uaW5nID0geWllbGQqIFJlZi5nZXQobGF0ZXN0UnVubmluZ0lkUmVmKVxuICAgICAgICAgIGNvbnN0IHByZXYgPSB5aWVsZCogUmVmLmdldChydW5MYXRlc3QpXG4gICAgICAgICAgaWYgKHByZXYgJiYgcHJldlJ1bm5pbmcgIT09IDApIHtcbiAgICAgICAgICAgIC8vIHBlcmZcdUZGMUFcdTkwN0ZcdTUxNERcdTVCRjlcdTIwMUNcdTVERjJcdTdFRDNcdTY3NUYgZmliZXJcdTIwMURcdTkxQ0RcdTU5MEQgaW50ZXJydXB0Rm9ya1x1RkYwOGxhdGVzdCBcdTRGMUFcdTk4OTFcdTdFNDFcdTg5RTZcdTUzRDFcdUZGMENcdTdBN0FcdTRFRkJcdTUyQTFcdTY1RjZcdThCRTVcdTYyMTBcdTY3MkNcdTk3NUVcdTVFMzhcdTUzRUZcdTg5QzJcdUZGMDlcdTMwMDJcbiAgICAgICAgICAgIHlpZWxkKiBGaWJlci5pbnRlcnJ1cHRGb3JrKHByZXYpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgcnVuSWQgPSB5aWVsZCogUmVmLnVwZGF0ZUFuZEdldChsYXRlc3RSdW5JZFJlZiwgKG4pID0+IG4gKyAxKVxuICAgICAgICAgIHlpZWxkKiBSZWYuc2V0KGxhdGVzdFJ1bm5pbmdJZFJlZiwgcnVuSWQpXG5cbiAgICAgICAgICBjb25zdCBmaWJlciA9IHlpZWxkKiBFZmZlY3QuZm9ya1Njb3BlZChcbiAgICAgICAgICAgIGFyZ3MucnVuKHRyaWdnZXIpLnBpcGUoXG4gICAgICAgICAgICAgIEVmZmVjdC5lbnN1cmluZyhcbiAgICAgICAgICAgICAgICBSZWYuZ2V0KGxhdGVzdFJ1bm5pbmdJZFJlZikucGlwZShcbiAgICAgICAgICAgICAgICAgIEVmZmVjdC5mbGF0TWFwKChjdXJyZW50KSA9PlxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID09PSBydW5JZCA/IFJlZi5zZXQobGF0ZXN0UnVubmluZ0lkUmVmLCAwKSA6IEVmZmVjdC52b2lkLFxuICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApXG4gICAgICAgICAgeWllbGQqIFJlZi5zZXQocnVuTGF0ZXN0LCBmaWJlcilcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwb2xpY3kubW9kZSA9PT0gXCJkcm9wXCIpIHtcbiAgICAgICAgICBjb25zdCBhY3F1aXJlZCA9IHlpZWxkKiBSZWYubW9kaWZ5KGJ1c3lSZWYsIChidXN5KSA9PlxuICAgICAgICAgICAgYnVzeSA/IChbZmFsc2UsIGJ1c3ldIGFzIGNvbnN0KSA6IChbdHJ1ZSwgdHJ1ZV0gYXMgY29uc3QpLFxuICAgICAgICAgIClcbiAgICAgICAgICBpZiAoIWFjcXVpcmVkKSB7XG4gICAgICAgICAgICB5aWVsZCogYXJncy5vbkRyb3AodHJpZ2dlcilcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgIH1cblxuICAgICAgICAgIHlpZWxkKiBFZmZlY3QuZm9ya1Njb3BlZChcbiAgICAgICAgICAgIGFyZ3MucnVuKHRyaWdnZXIpLnBpcGUoXG4gICAgICAgICAgICAgIEVmZmVjdC5lbnN1cmluZyhSZWYuc2V0KGJ1c3lSZWYsIGZhbHNlKSksXG4gICAgICAgICAgICApLFxuICAgICAgICAgIClcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwb2xpY3kubW9kZSA9PT0gXCJwYXJhbGxlbFwiKSB7XG4gICAgICAgICAgY29uc3QgbmV4dFNpemUgPSB5aWVsZCogUmVmLm1vZGlmeShwYXJhbGxlbFN0YXRlUmVmLCAoc3RhdGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHF1ZXVlID0gWy4uLnN0YXRlLnF1ZXVlLCB0cmlnZ2VyXVxuICAgICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAgcXVldWUubGVuZ3RoLFxuICAgICAgICAgICAgICB7IC4uLnN0YXRlLCBxdWV1ZSwgcGVhazogTWF0aC5tYXgoc3RhdGUucGVhaywgcXVldWUubGVuZ3RoKSB9LFxuICAgICAgICAgICAgXSBhcyBjb25zdFxuICAgICAgICAgIH0pXG5cbiAgICAgICAgICBpZiAobmV4dFNpemUgPiBwYXJhbGxlbFF1ZXVlTGltaXQuZ3VhcmQpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXRlID0geWllbGQqIFJlZi5nZXQocGFyYWxsZWxTdGF0ZVJlZilcbiAgICAgICAgICAgIHlpZWxkKiBhcmdzLm9uUXVldWVPdmVyZmxvdyh7XG4gICAgICAgICAgICAgIG1vZGU6IFwicGFyYWxsZWxcIixcbiAgICAgICAgICAgICAgY3VycmVudExlbmd0aDogbmV4dFNpemUsXG4gICAgICAgICAgICAgIHBlYWs6IHN0YXRlLnBlYWssXG4gICAgICAgICAgICAgIGxpbWl0OiBwYXJhbGxlbFF1ZXVlTGltaXQsXG4gICAgICAgICAgICAgIHBvbGljeSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB5aWVsZCogZHJhaW5QYXJhbGxlbCgpXG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICAvLyBzZXJpYWxcbiAgICAgICAgY29uc3QgbmV4dFNpemUgPSB5aWVsZCogUmVmLm1vZGlmeShzZXJpYWxTdGF0ZVJlZiwgKHN0YXRlKSA9PiB7XG4gICAgICAgICAgY29uc3QgcXVldWUgPSBbLi4uc3RhdGUucXVldWUsIHRyaWdnZXJdXG4gICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIHF1ZXVlLmxlbmd0aCxcbiAgICAgICAgICAgIHsgLi4uc3RhdGUsIHF1ZXVlLCBwZWFrOiBNYXRoLm1heChzdGF0ZS5wZWFrLCBxdWV1ZS5sZW5ndGgpIH0sXG4gICAgICAgICAgXSBhcyBjb25zdFxuICAgICAgICB9KVxuXG4gICAgICAgIGlmIChuZXh0U2l6ZSA+IHNlcmlhbFF1ZXVlTGltaXQuZ3VhcmQpIHtcbiAgICAgICAgICBjb25zdCBzdGF0ZSA9IHlpZWxkKiBSZWYuZ2V0KHNlcmlhbFN0YXRlUmVmKVxuICAgICAgICAgIHlpZWxkKiBhcmdzLm9uUXVldWVPdmVyZmxvdyh7XG4gICAgICAgICAgICBtb2RlOiBcInNlcmlhbFwiLFxuICAgICAgICAgICAgY3VycmVudExlbmd0aDogbmV4dFNpemUsXG4gICAgICAgICAgICBwZWFrOiBzdGF0ZS5wZWFrLFxuICAgICAgICAgICAgbGltaXQ6IHNlcmlhbFF1ZXVlTGltaXQsXG4gICAgICAgICAgICBwb2xpY3ksXG4gICAgICAgICAgfSlcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIHlpZWxkKiBkcmFpblNlcmlhbCgpXG4gICAgICB9KVxuXG4gICAgcmV0dXJuIHlpZWxkKiBTdHJlYW0ucnVuRm9yRWFjaChhcmdzLnN0cmVhbSwgb25UcmlnZ2VyKVxuICB9KVxuIiwgImltcG9ydCB0eXBlIHsgUHJvY2Vzc0V2ZW50IH0gZnJvbSBcIi4vcHJvdG9jb2wuanNcIlxuXG5leHBvcnQgY29uc3QgUFJPQ0VTU19FVkVOVF9NQVhfQllURVMgPSA0ICogMTAyNFxuZXhwb3J0IGNvbnN0IFBST0NFU1NfRVZFTlRfTUFYX0VWRU5UU19QRVJfUlVOID0gNTBcbmV4cG9ydCBjb25zdCBQUk9DRVNTX0VWRU5UX1JFU0VSVkVEX0VWRU5UU19GT1JfU1VNTUFSWSA9IDFcblxuZXhwb3J0IHR5cGUgUHJvY2Vzc1J1bkV2ZW50QnVkZ2V0U3RhdGUgPSB7XG4gIHJlYWRvbmx5IG1heEV2ZW50czogbnVtYmVyXG4gIHJlYWRvbmx5IG1heEJ5dGVzOiBudW1iZXJcbiAgcmVhZG9ubHkgZW1pdHRlZDogbnVtYmVyXG4gIHJlYWRvbmx5IGRyb3BwZWQ6IG51bWJlclxuICByZWFkb25seSBkb3duZ3JhZGVkOiBudW1iZXJcbiAgcmVhZG9ubHkgc3VtbWFyeUVtaXR0ZWQ6IGJvb2xlYW5cbn1cblxuZXhwb3J0IGNvbnN0IG1ha2VQcm9jZXNzUnVuRXZlbnRCdWRnZXRTdGF0ZSA9IChvcHRpb25zPzoge1xuICByZWFkb25seSBtYXhFdmVudHM/OiBudW1iZXJcbiAgcmVhZG9ubHkgbWF4Qnl0ZXM/OiBudW1iZXJcbn0pOiBQcm9jZXNzUnVuRXZlbnRCdWRnZXRTdGF0ZSA9PiAoe1xuICBtYXhFdmVudHM6XG4gICAgdHlwZW9mIG9wdGlvbnM/Lm1heEV2ZW50cyA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNGaW5pdGUob3B0aW9ucy5tYXhFdmVudHMpICYmIG9wdGlvbnMubWF4RXZlbnRzID49IDBcbiAgICAgID8gTWF0aC5mbG9vcihvcHRpb25zLm1heEV2ZW50cylcbiAgICAgIDogUFJPQ0VTU19FVkVOVF9NQVhfRVZFTlRTX1BFUl9SVU4sXG4gIG1heEJ5dGVzOlxuICAgIHR5cGVvZiBvcHRpb25zPy5tYXhCeXRlcyA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNGaW5pdGUob3B0aW9ucy5tYXhCeXRlcykgJiYgb3B0aW9ucy5tYXhCeXRlcyA+PSAwXG4gICAgICA/IE1hdGguZmxvb3Iob3B0aW9ucy5tYXhCeXRlcylcbiAgICAgIDogUFJPQ0VTU19FVkVOVF9NQVhfQllURVMsXG4gIGVtaXR0ZWQ6IDAsXG4gIGRyb3BwZWQ6IDAsXG4gIGRvd25ncmFkZWQ6IDAsXG4gIHN1bW1hcnlFbWl0dGVkOiBmYWxzZSxcbn0pXG5cbmV4cG9ydCB0eXBlIFByb2Nlc3NSdW5FdmVudEJ1ZGdldERlY2lzaW9uID1cbiAgfCB7XG4gICAgICByZWFkb25seSBfdGFnOiBcImVtaXRcIlxuICAgICAgcmVhZG9ubHkgZXZlbnQ6IFByb2Nlc3NFdmVudFxuICAgIH1cbiAgfCB7XG4gICAgICByZWFkb25seSBfdGFnOiBcImVtaXRTdW1tYXJ5XCJcbiAgICAgIHJlYWRvbmx5IGV2ZW50OiBQcm9jZXNzRXZlbnRcbiAgICB9XG4gIHwge1xuICAgICAgcmVhZG9ubHkgX3RhZzogXCJkcm9wXCJcbiAgICB9XG5cbmNvbnN0IG1ha2VCdWRnZXRTdW1tYXJ5RXZlbnQgPSAoYXJnczoge1xuICByZWFkb25seSBzb3VyY2VFdmVudDogUHJvY2Vzc0V2ZW50XG4gIHJlYWRvbmx5IG1heEV2ZW50czogbnVtYmVyXG4gIHJlYWRvbmx5IG1heEJ5dGVzOiBudW1iZXJcbiAgcmVhZG9ubHkgZW1pdHRlZDogbnVtYmVyXG4gIHJlYWRvbmx5IGRyb3BwZWQ6IG51bWJlclxuICByZWFkb25seSBkb3duZ3JhZGVkOiBudW1iZXJcbn0pOiBQcm9jZXNzRXZlbnQgPT4gKHtcbiAgdHlwZTogXCJwcm9jZXNzOnRyaWdnZXJcIixcbiAgaWRlbnRpdHk6IGFyZ3Muc291cmNlRXZlbnQuaWRlbnRpdHksXG4gIHRyaWdnZXI6IGFyZ3Muc291cmNlRXZlbnQudHJpZ2dlcixcbiAgc2V2ZXJpdHk6IFwid2FybmluZ1wiLFxuICBldmVudFNlcTogYXJncy5zb3VyY2VFdmVudC5ldmVudFNlcSxcbiAgdGltZXN0YW1wTXM6IGFyZ3Muc291cmNlRXZlbnQudGltZXN0YW1wTXMsXG4gIGVycm9yOiB7XG4gICAgbWVzc2FnZTogXCJQcm9jZXNzIHJ1biBldmVudCBidWRnZXQgZXhjZWVkZWQ7IGZ1cnRoZXIgdHJpZ2dlci9kaXNwYXRjaCBldmVudHMgYXJlIHN1cHByZXNzZWQuXCIsXG4gICAgY29kZTogXCJwcm9jZXNzOjpldmVudF9idWRnZXRfZXhjZWVkZWRcIixcbiAgICBoaW50OiBgbWF4RXZlbnRzPSR7YXJncy5tYXhFdmVudHN9IG1heEJ5dGVzPSR7YXJncy5tYXhCeXRlc30gZW1pdHRlZD0ke2FyZ3MuZW1pdHRlZH0gZHJvcHBlZD0ke2FyZ3MuZHJvcHBlZH0gZG93bmdyYWRlZD0ke2FyZ3MuZG93bmdyYWRlZH1gLFxuICB9LFxufSlcblxuZXhwb3J0IGNvbnN0IGFwcGx5UHJvY2Vzc1J1bkV2ZW50QnVkZ2V0ID0gKFxuICBzdGF0ZTogUHJvY2Vzc1J1bkV2ZW50QnVkZ2V0U3RhdGUsXG4gIGV2ZW50OiBQcm9jZXNzRXZlbnQsXG4pOiByZWFkb25seSBbUHJvY2Vzc1J1bkV2ZW50QnVkZ2V0RGVjaXNpb24sIFByb2Nlc3NSdW5FdmVudEJ1ZGdldFN0YXRlXSA9PiB7XG4gIGNvbnN0IG1heEV2ZW50cyA9IE1hdGgubWF4KDAsIHN0YXRlLm1heEV2ZW50cylcbiAgY29uc3QgbWF4Qnl0ZXMgPSBNYXRoLm1heCgwLCBzdGF0ZS5tYXhCeXRlcylcblxuICBpZiAoc3RhdGUuc3VtbWFyeUVtaXR0ZWQpIHtcbiAgICByZXR1cm4gW1xuICAgICAgeyBfdGFnOiBcImRyb3BcIiB9LFxuICAgICAge1xuICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgZHJvcHBlZDogc3RhdGUuZHJvcHBlZCArIDEsXG4gICAgICB9LFxuICAgIF1cbiAgfVxuXG4gIGNvbnN0IHJlc2VydmUgPSBQUk9DRVNTX0VWRU5UX1JFU0VSVkVEX0VWRU5UU19GT1JfU1VNTUFSWVxuICBjb25zdCBhbGxvd2VkUmVndWxhciA9IE1hdGgubWF4KDAsIG1heEV2ZW50cyAtIHJlc2VydmUpXG5cbiAgaWYgKHN0YXRlLmVtaXR0ZWQgPCBhbGxvd2VkUmVndWxhcikge1xuICAgIGNvbnN0IGVuZm9yY2VkID0gZW5mb3JjZVByb2Nlc3NFdmVudE1heEJ5dGVzKGV2ZW50LCB7IG1heEJ5dGVzIH0pXG4gICAgcmV0dXJuIFtcbiAgICAgIHsgX3RhZzogXCJlbWl0XCIsIGV2ZW50OiBlbmZvcmNlZC5ldmVudCB9LFxuICAgICAge1xuICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgZW1pdHRlZDogc3RhdGUuZW1pdHRlZCArIDEsXG4gICAgICAgIGRvd25ncmFkZWQ6IHN0YXRlLmRvd25ncmFkZWQgKyAoZW5mb3JjZWQuZG93bmdyYWRlZCA/IDEgOiAwKSxcbiAgICAgIH0sXG4gICAgXVxuICB9XG5cbiAgY29uc3QgZHJvcHBlZCA9IHN0YXRlLmRyb3BwZWQgKyAxXG4gIGNvbnN0IHN1bW1hcnkgPSBtYWtlQnVkZ2V0U3VtbWFyeUV2ZW50KHtcbiAgICBzb3VyY2VFdmVudDogZXZlbnQsXG4gICAgbWF4RXZlbnRzLFxuICAgIG1heEJ5dGVzLFxuICAgIGVtaXR0ZWQ6IHN0YXRlLmVtaXR0ZWQsXG4gICAgZHJvcHBlZCxcbiAgICBkb3duZ3JhZGVkOiBzdGF0ZS5kb3duZ3JhZGVkLFxuICB9KVxuICBjb25zdCBlbmZvcmNlZFN1bW1hcnkgPSBlbmZvcmNlUHJvY2Vzc0V2ZW50TWF4Qnl0ZXMoc3VtbWFyeSwgeyBtYXhCeXRlcyB9KVxuXG4gIHJldHVybiBbXG4gICAgeyBfdGFnOiBcImVtaXRTdW1tYXJ5XCIsIGV2ZW50OiBlbmZvcmNlZFN1bW1hcnkuZXZlbnQgfSxcbiAgICB7XG4gICAgICAuLi5zdGF0ZSxcbiAgICAgIGVtaXR0ZWQ6IE1hdGgubWluKG1heEV2ZW50cywgc3RhdGUuZW1pdHRlZCArIDEpLFxuICAgICAgZHJvcHBlZCxcbiAgICAgIGRvd25ncmFkZWQ6IHN0YXRlLmRvd25ncmFkZWQgKyAoZW5mb3JjZWRTdW1tYXJ5LmRvd25ncmFkZWQgPyAxIDogMCksXG4gICAgICBzdW1tYXJ5RW1pdHRlZDogdHJ1ZSxcbiAgICB9LFxuICBdXG59XG5cbmV4cG9ydCBjb25zdCBlc3RpbWF0ZUV2ZW50Qnl0ZXMgPSAoZXZlbnQ6IFByb2Nlc3NFdmVudCk6IG51bWJlciA9PiB7XG4gIGNvbnN0IGpzb24gPSBKU09OLnN0cmluZ2lmeShldmVudClcbiAgcmV0dXJuIHR5cGVvZiBCdWZmZXIgIT09IFwidW5kZWZpbmVkXCJcbiAgICA/IEJ1ZmZlci5ieXRlTGVuZ3RoKGpzb24sIFwidXRmOFwiKVxuICAgIDogbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGpzb24pLmxlbmd0aFxufVxuXG5jb25zdCB0cnVuY2F0ZUNoYXJzID0gKHZhbHVlOiBzdHJpbmcsIG1heExlbjogbnVtYmVyKTogc3RyaW5nID0+XG4gIHZhbHVlLmxlbmd0aCA8PSBtYXhMZW4gPyB2YWx1ZSA6IHZhbHVlLnNsaWNlKDAsIG1heExlbilcblxuY29uc3Qgbm9ybWFsaXplRXJyb3JTdW1tYXJ5ID0gKFxuICBlcnJvcjogTm9uTnVsbGFibGU8UHJvY2Vzc0V2ZW50W1wiZXJyb3JcIl0+LFxuKTogTm9uTnVsbGFibGU8UHJvY2Vzc0V2ZW50W1wiZXJyb3JcIl0+ID0+IHtcbiAgY29uc3QgbWVzc2FnZSA9XG4gICAgdHlwZW9mIGVycm9yLm1lc3NhZ2UgPT09IFwic3RyaW5nXCIgJiYgZXJyb3IubWVzc2FnZS5sZW5ndGggPiAwID8gZXJyb3IubWVzc2FnZSA6IFwiRXJyb3JcIlxuXG4gIGNvbnN0IGhpbnQgPVxuICAgIHR5cGVvZiBlcnJvci5oaW50ID09PSBcInN0cmluZ1wiICYmIGVycm9yLmhpbnQubGVuZ3RoID4gMFxuICAgICAgPyB0cnVuY2F0ZUNoYXJzKGVycm9yLmhpbnQsIDEwMjQpXG4gICAgICA6IHVuZGVmaW5lZFxuXG4gIHJldHVybiB7XG4gICAgbmFtZTogdHlwZW9mIGVycm9yLm5hbWUgPT09IFwic3RyaW5nXCIgJiYgZXJyb3IubmFtZS5sZW5ndGggPiAwID8gZXJyb3IubmFtZSA6IHVuZGVmaW5lZCxcbiAgICBtZXNzYWdlOiB0cnVuY2F0ZUNoYXJzKG1lc3NhZ2UsIDI1NiksXG4gICAgY29kZTogdHlwZW9mIGVycm9yLmNvZGUgPT09IFwic3RyaW5nXCIgJiYgZXJyb3IuY29kZS5sZW5ndGggPiAwID8gZXJyb3IuY29kZSA6IHVuZGVmaW5lZCxcbiAgICBoaW50LFxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBlbmZvcmNlUHJvY2Vzc0V2ZW50TWF4Qnl0ZXMgPSAoXG4gIGV2ZW50OiBQcm9jZXNzRXZlbnQsXG4gIG9wdGlvbnM/OiB7XG4gICAgcmVhZG9ubHkgbWF4Qnl0ZXM/OiBudW1iZXJcbiAgfSxcbik6IHsgcmVhZG9ubHkgZXZlbnQ6IFByb2Nlc3NFdmVudDsgcmVhZG9ubHkgZG93bmdyYWRlZDogYm9vbGVhbiB9ID0+IHtcbiAgY29uc3QgbWF4Qnl0ZXMgPSBvcHRpb25zPy5tYXhCeXRlcyA/PyBQUk9DRVNTX0VWRU5UX01BWF9CWVRFU1xuXG4gIGxldCBkb3duZ3JhZGVkID0gZmFsc2VcbiAgbGV0IG5leHQ6IFByb2Nlc3NFdmVudCA9IGV2ZW50XG5cbiAgaWYgKGV2ZW50LmVycm9yKSB7XG4gICAgY29uc3Qgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZUVycm9yU3VtbWFyeShldmVudC5lcnJvcilcbiAgICBpZiAoXG4gICAgICBub3JtYWxpemVkLm1lc3NhZ2UgIT09IGV2ZW50LmVycm9yLm1lc3NhZ2UgfHxcbiAgICAgIG5vcm1hbGl6ZWQuaGludCAhPT0gZXZlbnQuZXJyb3IuaGludCB8fFxuICAgICAgbm9ybWFsaXplZC5jb2RlICE9PSBldmVudC5lcnJvci5jb2RlIHx8XG4gICAgICBub3JtYWxpemVkLm5hbWUgIT09IGV2ZW50LmVycm9yLm5hbWVcbiAgICApIHtcbiAgICAgIGRvd25ncmFkZWQgPSB0cnVlXG4gICAgICBuZXh0ID0geyAuLi5ldmVudCwgZXJyb3I6IG5vcm1hbGl6ZWQgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChlc3RpbWF0ZUV2ZW50Qnl0ZXMobmV4dCkgPD0gbWF4Qnl0ZXMpIHtcbiAgICByZXR1cm4geyBldmVudDogbmV4dCwgZG93bmdyYWRlZCB9XG4gIH1cblxuICAvLyBcdTRFQzVcdTVCRjkgZXJyb3IuaGludCBcdTUwNUFcdThGREJcdTRFMDBcdTZCNjVcdTc2ODRcdTkwMTBcdTZCNjVcdTg4QzFcdTUyNkFcdUZGMDhcdTg5RTZcdTUzRDFcdTcwQjlcdTkwMUFcdTVFMzhcdTY2MkYgbXVsdGktbGluZSBoaW50XHVGRjA5XHUzMDAyXG4gIGlmICghbmV4dC5lcnJvcj8uaGludCkge1xuICAgIC8vIFx1NURGMlx1NjVFMFx1NTNFRlx1ODhDMVx1NTI2QVx1NUI1N1x1NkJCNVx1RkYxQmJlc3QtZWZmb3J0IFx1OEZENFx1NTZERVx1MzAwMlxuICAgIHJldHVybiB7IGV2ZW50OiBuZXh0LCBkb3duZ3JhZGVkOiB0cnVlIH1cbiAgfVxuXG4gIGNvbnN0IGhpbnQgPSBuZXh0LmVycm9yLmhpbnRcbiAgY29uc3Qgc3RlcHMgPSBbNTEyLCAyNTYsIDEyOCwgNjQsIDMyLCAwXVxuXG4gIGZvciAoY29uc3QgbWF4TGVuIG9mIHN0ZXBzKSB7XG4gICAgY29uc3QgdHJpbW1lZCA9IG1heExlbiA9PT0gMCA/IHVuZGVmaW5lZCA6IHRydW5jYXRlQ2hhcnMoaGludCwgbWF4TGVuKVxuICAgIGNvbnN0IGNhbmRpZGF0ZTogUHJvY2Vzc0V2ZW50ID0ge1xuICAgICAgLi4ubmV4dCxcbiAgICAgIGVycm9yOiB7XG4gICAgICAgIC4uLm5leHQuZXJyb3IsXG4gICAgICAgIGhpbnQ6IHRyaW1tZWQsXG4gICAgICB9LFxuICAgIH1cbiAgICBpZiAoZXN0aW1hdGVFdmVudEJ5dGVzKGNhbmRpZGF0ZSkgPD0gbWF4Qnl0ZXMpIHtcbiAgICAgIHJldHVybiB7IGV2ZW50OiBjYW5kaWRhdGUsIGRvd25ncmFkZWQ6IHRydWUgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFx1NTE1Q1x1NUU5NVx1RkYxQVx1NzlGQlx1OTY2NCBoaW50XHVGRjBDXHU3RjI5XHU3N0VEIG1lc3NhZ2VcdUZGMDhcdTRGRERcdThCQzEgcHJvY2VzczplcnJvciBcdTRFQ0RcdTY3MDkgbWVzc2FnZVx1RkYwOVx1MzAwMlxuICBjb25zdCBmYWxsYmFjazogUHJvY2Vzc0V2ZW50ID0gbmV4dC5lcnJvclxuICAgID8gKHtcbiAgICAgICAgLi4ubmV4dCxcbiAgICAgICAgZXJyb3I6IHtcbiAgICAgICAgICAuLi5uZXh0LmVycm9yLFxuICAgICAgICAgIG1lc3NhZ2U6IHRydW5jYXRlQ2hhcnMobmV4dC5lcnJvci5tZXNzYWdlLCA5NiksXG4gICAgICAgICAgaGludDogdW5kZWZpbmVkLFxuICAgICAgICB9LFxuICAgICAgfSBzYXRpc2ZpZXMgUHJvY2Vzc0V2ZW50KVxuICAgIDogbmV4dFxuXG4gIHJldHVybiB7IGV2ZW50OiBmYWxsYmFjaywgZG93bmdyYWRlZDogdHJ1ZSB9XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBQcm9jZXNzRXJyb3JQb2xpY3kgfSBmcm9tIFwiLi9wcm90b2NvbC5qc1wiXG5cbmV4cG9ydCB0eXBlIFN1cGVydmlzaW9uRGVjaXNpb24gPSBcInN0b3BcIiB8IFwicmVzdGFydFwiXG5cbmV4cG9ydCB0eXBlIFN1cGVydmlzaW9uU3RhdGUgPSB7XG4gIHJlYWRvbmx5IGZhaWx1cmVUaW1lczogUmVhZG9ubHlBcnJheTxudW1iZXI+XG59XG5cbmV4cG9ydCBjb25zdCBpbml0aWFsU3RhdGUgPSAoKTogU3VwZXJ2aXNpb25TdGF0ZSA9PiAoeyBmYWlsdXJlVGltZXM6IFtdIH0pXG5cbmV4cG9ydCB0eXBlIEZhaWx1cmVEZWNpc2lvbiA9IHtcbiAgcmVhZG9ubHkgZGVjaXNpb246IFN1cGVydmlzaW9uRGVjaXNpb25cbiAgcmVhZG9ubHkgbmV4dFN0YXRlOiBTdXBlcnZpc2lvblN0YXRlXG4gIHJlYWRvbmx5IHdpdGhpbldpbmRvd0ZhaWx1cmVzOiBudW1iZXJcbiAgcmVhZG9ubHkgbWF4UmVzdGFydHM6IG51bWJlclxuICByZWFkb25seSB3aW5kb3dNcz86IG51bWJlclxufVxuXG5leHBvcnQgY29uc3Qgb25GYWlsdXJlID0gKFxuICBwb2xpY3k6IFByb2Nlc3NFcnJvclBvbGljeSxcbiAgc3RhdGU6IFN1cGVydmlzaW9uU3RhdGUsXG4gIG5vd01zOiBudW1iZXIsXG4pOiBGYWlsdXJlRGVjaXNpb24gPT4ge1xuICBpZiAocG9saWN5Lm1vZGUgPT09IFwiZmFpbFN0b3BcIikge1xuICAgIHJldHVybiB7XG4gICAgICBkZWNpc2lvbjogXCJzdG9wXCIsXG4gICAgICBuZXh0U3RhdGU6IHN0YXRlLFxuICAgICAgd2l0aGluV2luZG93RmFpbHVyZXM6IHN0YXRlLmZhaWx1cmVUaW1lcy5sZW5ndGgsXG4gICAgICBtYXhSZXN0YXJ0czogMCxcbiAgICAgIHdpbmRvd01zOiBwb2xpY3kud2luZG93TXMsXG4gICAgfVxuICB9XG5cbiAgY29uc3QgbWF4UmVzdGFydHNSYXcgPSBwb2xpY3kubWF4UmVzdGFydHNcbiAgY29uc3QgbWF4UmVzdGFydHMgPVxuICAgIHR5cGVvZiBtYXhSZXN0YXJ0c1JhdyA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNGaW5pdGUobWF4UmVzdGFydHNSYXcpICYmIG1heFJlc3RhcnRzUmF3ID49IDBcbiAgICAgID8gTWF0aC5mbG9vcihtYXhSZXN0YXJ0c1JhdylcbiAgICAgIDogMFxuXG4gIGlmIChtYXhSZXN0YXJ0cyA8PSAwKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRlY2lzaW9uOiBcInN0b3BcIixcbiAgICAgIG5leHRTdGF0ZTogc3RhdGUsXG4gICAgICB3aXRoaW5XaW5kb3dGYWlsdXJlczogc3RhdGUuZmFpbHVyZVRpbWVzLmxlbmd0aCxcbiAgICAgIG1heFJlc3RhcnRzLFxuICAgICAgd2luZG93TXM6IHBvbGljeS53aW5kb3dNcyxcbiAgICB9XG4gIH1cblxuICBjb25zdCB3aW5kb3dNc1JhdyA9IHBvbGljeS53aW5kb3dNc1xuICBjb25zdCB3aW5kb3dNcyA9XG4gICAgdHlwZW9mIHdpbmRvd01zUmF3ID09PSBcIm51bWJlclwiICYmIE51bWJlci5pc0Zpbml0ZSh3aW5kb3dNc1JhdykgJiYgd2luZG93TXNSYXcgPiAwXG4gICAgICA/IE1hdGguZmxvb3Iod2luZG93TXNSYXcpXG4gICAgICA6IHVuZGVmaW5lZFxuXG4gIGNvbnN0IGZhaWx1cmVUaW1lc1JhdyA9IFsuLi5zdGF0ZS5mYWlsdXJlVGltZXMsIG5vd01zXVxuICBjb25zdCBmYWlsdXJlVGltZXMgPSB3aW5kb3dNc1xuICAgID8gZmFpbHVyZVRpbWVzUmF3LmZpbHRlcigodCkgPT4gdCA+PSBub3dNcyAtIHdpbmRvd01zKVxuICAgIDogZmFpbHVyZVRpbWVzUmF3XG5cbiAgLy8gS2VlcCBhdCBtb3N0IG1heFJlc3RhcnRzKzEgdGltZXN0YW1wcyB0byBhdm9pZCB1bmJvdW5kZWQgZ3Jvd3RoLlxuICBjb25zdCBjYXAgPSBtYXhSZXN0YXJ0cyArIDFcbiAgY29uc3QgY2FwcGVkID1cbiAgICBmYWlsdXJlVGltZXMubGVuZ3RoID4gY2FwID8gZmFpbHVyZVRpbWVzLnNsaWNlKGZhaWx1cmVUaW1lcy5sZW5ndGggLSBjYXApIDogZmFpbHVyZVRpbWVzXG5cbiAgY29uc3Qgd2l0aGluV2luZG93RmFpbHVyZXMgPSBjYXBwZWQubGVuZ3RoXG4gIGNvbnN0IGRlY2lzaW9uOiBTdXBlcnZpc2lvbkRlY2lzaW9uID1cbiAgICB3aXRoaW5XaW5kb3dGYWlsdXJlcyA8PSBtYXhSZXN0YXJ0cyA/IFwicmVzdGFydFwiIDogXCJzdG9wXCJcblxuICByZXR1cm4ge1xuICAgIGRlY2lzaW9uLFxuICAgIG5leHRTdGF0ZTogeyBmYWlsdXJlVGltZXM6IGNhcHBlZCB9LFxuICAgIHdpdGhpbldpbmRvd0ZhaWx1cmVzLFxuICAgIG1heFJlc3RhcnRzLFxuICAgIHdpbmRvd01zLFxuICB9XG59XG5cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFjTyxJQUFNLGVBQWUsdUJBQU8sSUFBSSx5QkFBeUI7QUFNaEUsSUFBTSxlQUFlLENBQUMsUUFBZ0IsS0FBYSxVQUF5QjtBQUMxRSxTQUFPLGVBQWUsUUFBUSxLQUFLO0FBQUEsSUFDakM7QUFBQSxJQUNBLFlBQVk7QUFBQSxJQUNaLGNBQWM7QUFBQSxJQUNkLFVBQVU7QUFBQSxFQUNaLENBQUM7QUFDSDtBQUVPLElBQU0sVUFBVSxDQUFDLFdBQ3JCLE9BQXlCLFlBQVk7QUFFakMsSUFBTSxnQkFBZ0IsQ0FDM0IsV0FDa0MsUUFBUSxNQUFNLEdBQUc7QUFFOUMsSUFBTSxhQUFhLENBQ3hCLFFBQ0EsU0FDd0I7QUFDeEIsZUFBYSxRQUFlLGNBQWMsSUFBSTtBQUM5QyxTQUFPO0FBQ1Q7OztBQzFDQSxTQUFTLFNBQVMsUUFBUSxjQUFjO0FBZ0N4QyxJQUFNLHNDQUFOLGNBQWtELFFBQVE7QUFBQSxFQUN4RDtBQUNGLEVBQXFFLEVBQUU7QUFBQztBQUVqRSxJQUFNLGtDQUFrQztBQVMvQyxJQUFNLDBDQUFOLGNBQXNELFFBQVE7QUFBQSxFQUM1RDtBQUNGLEVBQTZFLEVBQUU7QUFBQztBQUV6RSxJQUFNLHNDQUFzQztBQUVuRCxJQUFNLDBDQUFOLGNBQXNELFFBQVE7QUFBQSxFQUM1RDtBQUNGLEVBQXFFLEVBQUU7QUFBQztBQUVqRSxJQUFNLHNDQUFzQztBQW1CbkQsSUFBTSxpQkFBK0M7QUFBQSxFQUNuRDtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFDRjtBQUVBLElBQU0sV0FBVyxDQUFDLEdBQWtCLE1BQW9DO0FBQ3RFLFFBQU0sS0FBSyxlQUFlLFFBQVEsQ0FBQztBQUNuQyxRQUFNLEtBQUssZUFBZSxRQUFRLENBQUM7QUFDbkMsU0FBUSxNQUFNLEtBQUssSUFBSTtBQUN6QjtBQUVBLElBQU0sZ0JBQWdCLENBQUMsVUFDckIsT0FBTyxVQUFVLFlBQVksVUFBVSxRQUFRLENBQUMsTUFBTSxRQUFRLEtBQUs7QUFFckUsSUFBTSxvQkFBb0IsQ0FBQyxVQUF1RDtBQUNoRixNQUFJLENBQUMsY0FBYyxLQUFLLEVBQUcsUUFBTztBQUVsQyxRQUFNLFlBQVksTUFBTTtBQUN4QixRQUFNLFdBQVcsTUFBTTtBQUV2QixTQUFPO0FBQUEsSUFDTCxRQUFRLE9BQU8sY0FBYyxZQUFZLFVBQVUsU0FBUyxJQUFJLFlBQVk7QUFBQSxJQUM1RSxPQUFPLE9BQU8sYUFBYSxZQUFZLFNBQVMsU0FBUyxJQUFJLFdBQVc7QUFBQSxFQUMxRTtBQUNGO0FBRU8sSUFBTSxrQ0FBa0MsQ0FBQyxTQWE5QyxPQUFPLElBQUksYUFBYTtBQUN0QixRQUFNLG1CQUFtQixPQUFPLE9BQU87QUFBQSxJQUNyQztBQUFBLEVBQ0Y7QUFDQSxRQUFNLHVCQUF1QixPQUFPLE9BQU87QUFBQSxJQUN6QztBQUFBLEVBQ0Y7QUFDQSxRQUFNLHVCQUF1QixPQUFPLE9BQU87QUFBQSxJQUN6QztBQUFBLEVBQ0Y7QUFFQSxRQUFNLGdCQUFnQixPQUFPLE9BQU8sZ0JBQWdCLElBQ2hELGlCQUFpQixRQUNqQjtBQUNKLFFBQU0sb0JBQW9CLE9BQU8sT0FBTyxvQkFBb0IsSUFDeEQscUJBQXFCLFFBQ3JCO0FBQ0osUUFBTSxvQkFBb0IsT0FBTyxPQUFPLG9CQUFvQixJQUN4RCxxQkFBcUIsUUFDckI7QUFFSixRQUFNLFdBQVcsS0FBSztBQUV0QixRQUFNLGdCQUNKLFlBQVksZUFBZSxxQkFDdkIsY0FBYyxtQkFBbUIsUUFBUSxJQUN6QztBQUVOLFFBQU0saUJBQ0osWUFBWSxtQkFBbUIscUJBQzNCLGtCQUFrQixtQkFBbUIsUUFBUSxJQUM3QztBQUVOLFNBQU87QUFBQSxJQUNMLGdCQUFnQixlQUFlO0FBQUEsSUFDL0I7QUFBQSxJQUNBLFVBQVUsbUJBQW1CO0FBQUEsSUFDN0I7QUFBQSxJQUNBLFVBQVU7QUFBQSxFQUNaO0FBQ0YsQ0FBQztBQWVJLElBQU0sdUJBQXVCLENBQ2xDLFdBQ0EsT0FDQSxjQU9xQztBQUNyQyxRQUFNLFVBQVUsTUFBTSxDQUFDO0FBQ3ZCLE1BQUksQ0FBQyxTQUFTO0FBQ1osVUFBTSxJQUFJLE1BQU0sNERBQTRELFNBQVMsRUFBRTtBQUFBLEVBQ3pGO0FBRUEsTUFBSTtBQUNKLFFBQU0sV0FBVyxDQUFDLE9BQXNCLFVBQXNEO0FBQzVGLFVBQU0sT0FBTyxRQUFRLGtCQUFrQixNQUFNLFNBQVMsQ0FBQyxJQUFJO0FBQzNELFFBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxPQUFRO0FBQzNCLGNBQVUsRUFBRSxPQUFPLFVBQVUsS0FBSztBQUFBLEVBQ3BDO0FBR0EsV0FBUyxtQkFBbUIsVUFBVSxjQUFjO0FBQ3BELFdBQVMsa0JBQWtCLFVBQVUsYUFBYTtBQUNsRCxXQUFTLFlBQVksVUFBVSxRQUFRO0FBQ3ZDLFdBQVMsWUFBWSxVQUFVLGNBQWM7QUFDN0MsV0FBUyxZQUFZLFVBQVUsUUFBUTtBQUV2QyxNQUFJLENBQUMsU0FBUztBQUNaLFdBQU87QUFBQSxNQUNMLE1BQU07QUFBQSxNQUNOLFNBQVM7QUFBQSxRQUNQO0FBQUEsUUFDQSxRQUFRLFFBQVE7QUFBQSxRQUNoQixhQUFhLFFBQVE7QUFBQSxRQUNyQixPQUFPO0FBQUEsUUFDUCxZQUFZO0FBQUEsUUFDWixPQUFPLFFBQVE7QUFBQSxNQUNqQjtBQUFBLE1BQ0Esa0JBQWtCLENBQUM7QUFBQSxJQUNyQjtBQUFBLEVBQ0Y7QUFFQSxRQUFNLGdCQUFnQixRQUFRLFNBQVM7QUFDdkMsUUFBTSxXQUFXLE1BQU0sS0FBSyxDQUFDLE1BQU0sRUFBRSxXQUFXLGFBQWE7QUFDN0QsUUFBTSxPQUFPLFlBQVk7QUFFekIsUUFBTSxjQUFjLFlBQVk7QUFDaEMsUUFBTSxlQUNKLGNBQ0ksbUJBQW1CLGFBQWEsK0JBQStCLFFBQVEsTUFBTSxNQUM3RTtBQUVOLFFBQU0sUUFBUSxDQUFDLFFBQVEsU0FBUyxPQUFPLEtBQUssT0FBTyxZQUFZLEVBQzVELE9BQU8sQ0FBQyxNQUFtQixPQUFPLE1BQU0sWUFBWSxFQUFFLFNBQVMsQ0FBQyxFQUNoRSxLQUFLLElBQUk7QUFFWixTQUFPO0FBQUEsSUFDTDtBQUFBLElBQ0EsU0FBUztBQUFBLE1BQ1A7QUFBQSxNQUNBLFFBQVEsS0FBSztBQUFBLE1BQ2IsYUFBYSxLQUFLO0FBQUEsTUFDbEIsT0FBTyxRQUFRO0FBQUEsTUFDZixZQUFZO0FBQUEsTUFDWixPQUFPLE1BQU0sU0FBUyxJQUFJLFFBQVE7QUFBQSxJQUNwQztBQUFBLElBQ0Esa0JBQWtCO0FBQUEsTUFDaEIsY0FDSSxHQUFHLFFBQVEsS0FBSyxJQUFJLFNBQVMsSUFBSSxhQUFhLGNBQWMsUUFBUSxNQUFNLE1BQzFFLEdBQUcsUUFBUSxLQUFLLElBQUksU0FBUyxJQUFJLGFBQWE7QUFBQSxJQUNwRDtBQUFBLEVBQ0Y7QUFDRjtBQUVPLElBQU0sOEJBQThCLENBQUMsU0FLYjtBQUM3QixNQUFJLFFBQXVCO0FBQzNCLGFBQVcsS0FBSyxLQUFLLFVBQVU7QUFDN0IsWUFBUSxTQUFTLE9BQU8sRUFBRSxLQUFLO0FBQUEsRUFDakM7QUFFQSxTQUFPO0FBQUEsSUFDTCxVQUFVLEtBQUs7QUFBQSxJQUNmLFlBQVksS0FBSztBQUFBLElBQ2pCO0FBQUEsSUFDQSxVQUFVLEtBQUs7QUFBQSxJQUNmLGtCQUFrQixLQUFLO0FBQUEsRUFDekI7QUFDRjtBQUVBLElBQU0sNEJBQTRCLHVCQUFPLElBQUkscUNBQXFDO0FBRWxGLElBQU1BLGdCQUFlLENBQUMsUUFBZ0IsS0FBYSxVQUF5QjtBQUMxRSxTQUFPLGVBQWUsUUFBUSxLQUFLO0FBQUEsSUFDakM7QUFBQSxJQUNBLFlBQVk7QUFBQSxJQUNaLGNBQWM7QUFBQSxJQUNkLFVBQVU7QUFBQSxFQUNaLENBQUM7QUFDSDtBQUVBLElBQU0sY0FBYyxDQUFDLFVBQW1CLGVBQWdDO0FBQ3RFLFFBQU0sSUFBSSxPQUFPLGFBQWEsWUFBWSxTQUFTLFNBQVMsSUFBSSxXQUFXO0FBQzNFLFFBQU0sSUFBSSxPQUFPLGVBQWUsWUFBWSxXQUFXLFNBQVMsSUFBSSxhQUFhO0FBQ2pGLFNBQU8sWUFBWSxDQUFDLGdCQUFnQixDQUFDO0FBQ3ZDO0FBRU8sSUFBTSw2QkFBNkIsQ0FBQyxTQUFpQixhQUE0QztBQUN0RyxFQUFBQSxjQUFhLFNBQVMsMkJBQTJCLFFBQVE7QUFDM0Q7QUFFTyxJQUFNLDZCQUE2QixDQUFDLFlBQTZDO0FBQ3RGLFFBQU0sUUFBUTtBQUNkLFFBQU0sV0FBWSxRQUFnQix5QkFBeUI7QUFDM0QsTUFBSSxDQUFDLFVBQVU7QUFDYixVQUFNLE1BQU0sU0FBUyxJQUNqQjtBQUFBLE1BQ0U7QUFBQSxNQUNBLFVBQVUsWUFBWSxNQUFNLFVBQVUsTUFBTSxVQUFVLENBQUM7QUFBQSxNQUN2RDtBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsSUFDRixFQUFFLEtBQUssSUFBSSxJQUNYO0FBQ0osVUFBTSxJQUFJLE1BQU0sR0FBRztBQUFBLEVBQ3JCO0FBRUEsUUFBTSxvQkFBb0IsTUFBTTtBQUNoQyxNQUNFLE9BQU8sc0JBQXNCLFlBQzdCLGtCQUFrQixTQUFTLEtBQzNCLHNCQUFzQixTQUFTLFlBQy9CO0FBQ0EsVUFBTSxJQUFJO0FBQUEsTUFDUixTQUFTLElBQ0w7QUFBQSxRQUNFO0FBQUEsUUFDQSxZQUFZLFlBQVksTUFBTSxVQUFVLGlCQUFpQixDQUFDO0FBQUEsUUFDMUQsYUFBYSxZQUFZLFNBQVMsVUFBVSxTQUFTLFVBQVUsQ0FBQztBQUFBLE1BQ2xFLEVBQUUsS0FBSyxJQUFJLElBQ1g7QUFBQSxJQUNOO0FBQUEsRUFDRjtBQUVBLFNBQU87QUFDVDs7O0FDblVBLFNBQVMsV0FBQUMsVUFBUyxVQUFBQyxTQUFRLFVBQVUsYUFBYTtBQXNCakQsSUFBTSwyQkFBTixjQUF1Q0MsU0FBUTtBQUFBLEVBQzdDO0FBQ0YsRUFBK0MsRUFBRTtBQUFDO0FBRTNDLElBQU0sdUJBQXVCO0FBRTdCLElBQU0seUJBQXlCLENBQ3BDLGNBRUEsTUFBTSxRQUFRLHNCQUFzQixTQUFTO0FBTS9DLElBQU0sV0FBVyxDQUFDLFVBQ2hCLE9BQU8sVUFBVSxZQUFZLFVBQVUsUUFBUSxDQUFDLE1BQU0sUUFBUSxLQUFLO0FBRTlELElBQU0sd0JBQXdCLENBQUMsWUFBMkM7QUFDL0UsUUFBTSxPQUFPLGlCQUFpQixPQUFPO0FBRXJDLFFBQU0sMkJBQTJCLG9CQUFJLElBQXVCO0FBQzVELE1BQUk7QUFFSixRQUFNLGVBQWU7QUFBQSxJQUNuQixTQUFTO0FBQUEsSUFDVCxXQUFXO0FBQUEsSUFDWCxpQkFBaUI7QUFBQSxFQUNuQjtBQUVBLFFBQU0sWUFBdUI7QUFBQSxJQUMzQixRQUFRLENBQUMsVUFDUEMsUUFBTyxJQUFJLGFBQWE7QUFDdEIsWUFBTSxRQUFRLE9BQU8sU0FBUyxJQUFJLHVCQUF1QjtBQUN6RCxZQUFNLGdCQUFpQixNQUFjO0FBQ3JDLFlBQU0sYUFDSixPQUFPLGtCQUFrQixZQUFZLGNBQWMsU0FBUyxJQUN4RCxnQkFDQTtBQUNOLFlBQU0sV0FDSixVQUFVLFFBQ04sU0FDQSxRQUFRLE1BQU0sUUFBUSxZQUFZLFVBQVU7QUFDbEQsWUFBTSxNQUFNLHVCQUF1QixPQUFPO0FBQUEsUUFDeEMsa0JBQWtCO0FBQUEsUUFDbEI7QUFBQSxRQUNBLGtCQUFrQixDQUFDLEVBQUUsTUFBTSxNQUFNO0FBQy9CLHVCQUFhLFdBQVcsTUFBTTtBQUM5Qix1QkFBYSxhQUFhLE1BQU07QUFBQSxRQUNsQztBQUFBLE1BQ0YsQ0FBQztBQUNELFVBQUksQ0FBQyxJQUFLO0FBRVYsWUFBTSxZQUFZLGlCQUFpQixHQUFHO0FBQ3RDLG1CQUFhLFdBQVcsVUFBVSxNQUFNO0FBQ3hDLG1CQUFhLGFBQWEsVUFBVSxNQUFNO0FBQzFDLG1CQUFhLG1CQUFtQixVQUFVLE1BQU07QUFFaEQsV0FBSyxPQUFPLGVBQWUsVUFBVSxPQUFPO0FBQUEsUUFDMUMsV0FBVyxJQUFJO0FBQUEsTUFDakIsQ0FBQztBQUFBLElBQ0gsQ0FBQztBQUFBLEVBQ0w7QUFFQSxRQUFNLDJCQUEyQixDQUFDLGFBQTRCO0FBQzVELFFBQUksQ0FBQyxTQUFTLFFBQVEsRUFBRztBQUN6QixVQUFNLFNBQVMsU0FBUztBQUN4QixRQUFJLE9BQU8sV0FBVyxZQUFZLE9BQU8sV0FBVyxFQUFHO0FBQ3ZELFVBQU0sWUFBWSxpQkFBaUIsUUFBUTtBQUMzQyxpQkFBYSxXQUFXLFVBQVUsTUFBTTtBQUN4QyxpQkFBYSxhQUFhLFVBQVUsTUFBTTtBQUMxQyxpQkFBYSxtQkFBbUIsVUFBVSxNQUFNO0FBQ2hELDZCQUF5QixJQUFJLFFBQVEsVUFBVSxLQUFLO0FBQUEsRUFDdEQ7QUFFQSxRQUFNQyw4QkFBNkIsQ0FBQyxhQUE0QjtBQUM5RCxVQUFNLFlBQVksaUJBQWlCLFFBQVE7QUFDM0MsaUJBQWEsV0FBVyxVQUFVLE1BQU07QUFDeEMsaUJBQWEsYUFBYSxVQUFVLE1BQU07QUFDMUMsaUJBQWEsbUJBQW1CLFVBQVUsTUFBTTtBQUNoRCw4QkFBMEIsVUFBVTtBQUFBLEVBQ3RDO0FBRUEsUUFBTSx3QkFBd0IsQ0FBQyxZQUVSO0FBQ3JCLFVBQU0sa0JBQ0oseUJBQXlCLE9BQU8sSUFDM0I7QUFBQSxNQUNDLGtCQUFrQixPQUFPLFlBQVksd0JBQXdCO0FBQUEsSUFDL0QsSUFDQTtBQUVOLFVBQU0saUJBQ0osMkJBQTJCLE9BQ3RCLEVBQUUsVUFBVSx3QkFBd0IsSUFDckM7QUFFTixVQUFNLFVBQ0osbUJBQW1CLFFBQVEsa0JBQWtCLE9BQ3hDO0FBQUEsTUFDQyxHQUFJLG1CQUFtQixPQUFPLEVBQUUsVUFBVSxnQkFBZ0IsSUFBSSxDQUFDO0FBQUEsTUFDL0QsR0FBSSxrQkFBa0IsT0FBTyxFQUFFLFNBQVMsZUFBZSxJQUFJLENBQUM7QUFBQSxJQUM5RCxJQUNBO0FBRU4sV0FBTyxLQUFLLE9BQU87QUFBQSxNQUNqQixXQUFXLFNBQVM7QUFBQSxNQUNwQjtBQUFBLElBQ0YsQ0FBQztBQUFBLEVBQ0g7QUFFQSxRQUFNLFFBQVEsTUFBWTtBQUN4QixTQUFLLE1BQU07QUFDWCw2QkFBeUIsTUFBTTtBQUMvQiw4QkFBMEI7QUFDMUIsaUJBQWEsVUFBVTtBQUN2QixpQkFBYSxZQUFZO0FBQ3pCLGlCQUFhLGtCQUFrQjtBQUFBLEVBQ2pDO0FBRUEsU0FBTztBQUFBLElBQ0w7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0EsNEJBQUFBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxFQUNGO0FBQ0Y7OztBQ3ZKQTtBQUFBLEVBQ0U7QUFBQSxFQUNBLFdBQUFDO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBLFVBQUFDO0FBQUEsRUFDQSxTQUFBQztBQUFBLEVBQ0EsWUFBQUM7QUFBQSxFQUNBLFNBQUFDO0FBQUEsRUFDQSxVQUFBQztBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQSxPQUFBQztBQUFBLEVBQ0EsU0FBQUM7QUFBQSxFQUNBLFVBQUFDO0FBQUEsT0FDSzs7O0FDWEEsSUFBTSxvQkFBb0IsQ0FBQyxVQUF5QztBQUN6RSxVQUFRLE1BQU0sTUFBTTtBQUFBLElBQ2xCLEtBQUs7QUFDSCxhQUFPLE9BQU8sTUFBTSxLQUFLO0FBQUEsSUFDM0IsS0FBSztBQUNILGFBQU8sa0JBQWtCLE1BQU0sUUFBUSxLQUFLLE1BQU0sVUFBVTtBQUFBLElBQzlELEtBQUs7QUFDSCxhQUFPLGFBQWEsTUFBTSxTQUFTO0FBQUEsRUFDdkM7QUFDRjtBQUVPLElBQU0sOEJBQThCLENBQUMsYUFDMUMsR0FBRyxTQUFTLFNBQVMsS0FBSyxrQkFBa0IsU0FBUyxLQUFLLENBQUM7QUFFdEQsSUFBTSxnQ0FBZ0MsQ0FDM0MsYUFDVztBQUNYLFFBQU0sV0FBVyxrQkFBa0IsU0FBUyxTQUFTLEtBQUs7QUFDMUQsU0FBTyxXQUFXLFNBQVMsU0FBUyxTQUFTLEtBQUssUUFBUSxNQUFNLFNBQVMsTUFBTTtBQUNqRjs7O0FDdkJBLFNBQVMsVUFBQUMsU0FBUSxPQUFPLFVBQUFDLFNBQVEsS0FBWSxjQUFjO0FBSW5ELElBQU0sbUNBQW1DO0FBQ3pDLElBQU0seUJBQXlCO0FBc0IvQixJQUFNLG9CQUFvQixDQUMvQixVQUNBLFlBR3VCO0FBQ3ZCLFFBQU0sZUFBZSxTQUFTLGdCQUFnQjtBQUU5QyxRQUFNLGFBQ0osT0FBTyxhQUFhLFlBQVksT0FBTyxTQUFTLFFBQVEsS0FBSyxZQUFZLElBQ3JFLEtBQUssTUFBTSxRQUFRLElBQ25CO0FBRU4sU0FBTztBQUFBLElBQ0w7QUFBQSxJQUNBLE9BQU8sZUFBZSxjQUFjLGVBQWU7QUFBQSxFQUNyRDtBQUNGO0FBVU8sSUFBTSwwQkFBMEIsQ0FBQyxTQWF0Q0MsUUFBTyxJQUFJLGFBQWE7QUFDdEIsUUFBTSxTQUFTLEtBQUs7QUFDcEIsUUFBTSxvQkFBb0IsS0FBSyxxQkFBcUI7QUFFcEQsUUFBTSxZQUFZLE9BQU8sSUFBSSxLQUFrRCxNQUFTO0FBQ3hGLFFBQU0saUJBQWlCLE9BQU8sSUFBSSxLQUFLLENBQUM7QUFDeEMsUUFBTSxxQkFBcUIsT0FBTyxJQUFJLEtBQUssQ0FBQztBQUM1QyxRQUFNLFVBQVUsT0FBTyxJQUFJLEtBQUssS0FBSztBQUNyQyxRQUFNLGlCQUFpQixPQUFPLElBQUksS0FBSztBQUFBLElBQ3JDLFNBQVM7QUFBQSxJQUNULE9BQU8sQ0FBQztBQUFBLElBQ1IsTUFBTTtBQUFBLEVBQ1IsQ0FBQztBQUNELFFBQU0sbUJBQW1CLE9BQU8sSUFBSSxLQUFLO0FBQUEsSUFDdkMsUUFBUTtBQUFBLElBQ1IsT0FBTyxDQUFDO0FBQUEsSUFDUixNQUFNO0FBQUEsRUFDUixDQUFDO0FBRUQsUUFBTSxtQkFBbUIsa0JBQWtCLE9BQU8sVUFBVSxFQUFFLGNBQWMsa0JBQWtCLENBQUM7QUFDL0YsUUFBTSxxQkFBcUIsa0JBQWtCLFFBQVcsRUFBRSxjQUFjLGtCQUFrQixDQUFDO0FBQzNGLFFBQU0sZ0JBQ0osT0FBTyxPQUFPLGdCQUFnQixZQUFZLE9BQU8sU0FBUyxPQUFPLFdBQVcsS0FBSyxPQUFPLGVBQWUsSUFDbkcsS0FBSyxNQUFNLE9BQU8sV0FBVyxJQUM1QixLQUFLLHdCQUF3QjtBQUVwQyxRQUFNLGNBQWMsTUFDbEJBLFFBQU87QUFBQSxJQUFRLE1BQ2IsSUFBSSxPQUFPLGdCQUFnQixDQUFDLFVBQVU7QUFDcEMsVUFBSSxNQUFNLFdBQVcsTUFBTSxNQUFNLFdBQVcsR0FBRztBQUM3QyxlQUFPLENBQUNDLFFBQU8sS0FBSyxHQUFHLEtBQUs7QUFBQSxNQUM5QjtBQUNBLFlBQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxJQUFJLE1BQU07QUFDOUIsYUFBTyxDQUFDQSxRQUFPLEtBQUssSUFBSSxHQUFHLEVBQUUsR0FBRyxPQUFPLFNBQVMsTUFBTSxPQUFPLEtBQUssQ0FBQztBQUFBLElBQ3JFLENBQUMsRUFBRTtBQUFBLE1BQ0RELFFBQU87QUFBQSxRQUFRLENBQUMsU0FDZEMsUUFBTyxNQUFNLE1BQU07QUFBQSxVQUNqQixRQUFRLE1BQU1ELFFBQU87QUFBQSxVQUNyQixRQUFRLENBQUMsWUFDUEEsUUFBTztBQUFBLFlBQ0wsS0FDRyxJQUFJLE9BQU8sRUFDWDtBQUFBLGNBQ0NBLFFBQU87QUFBQSxnQkFDTCxJQUFJLE9BQU8sZ0JBQWdCLENBQUMsT0FBTyxFQUFFLEdBQUcsR0FBRyxTQUFTLE1BQU0sRUFBRTtBQUFBLGNBQzlEO0FBQUEsY0FDQUEsUUFBTyxTQUFTLFlBQVksQ0FBQztBQUFBLFlBQy9CO0FBQUEsVUFDSixFQUFFLEtBQUtBLFFBQU8sTUFBTTtBQUFBLFFBQ3hCLENBQUM7QUFBQSxNQUNIO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFFRixRQUFNLGdCQUFnQixNQUNwQkEsUUFBTztBQUFBLElBQVEsTUFDYixJQUFJLE9BQU8sa0JBQWtCLENBQUMsVUFBVTtBQUN0QyxVQUFJLE1BQU0sVUFBVSxpQkFBaUIsTUFBTSxNQUFNLFdBQVcsR0FBRztBQUM3RCxlQUFPLENBQUNDLFFBQU8sS0FBSyxHQUFHLEtBQUs7QUFBQSxNQUM5QjtBQUNBLFlBQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxJQUFJLE1BQU07QUFDOUIsYUFBTyxDQUFDQSxRQUFPLEtBQUssSUFBSSxHQUFHLEVBQUUsR0FBRyxPQUFPLFFBQVEsTUFBTSxTQUFTLEdBQUcsT0FBTyxLQUFLLENBQUM7QUFBQSxJQUNoRixDQUFDLEVBQUU7QUFBQSxNQUNERCxRQUFPO0FBQUEsUUFBUSxDQUFDLFNBQ2RDLFFBQU8sTUFBTSxNQUFNO0FBQUEsVUFDakIsUUFBUSxNQUFNRCxRQUFPO0FBQUEsVUFDckIsUUFBUSxDQUFDLFlBQ1BBLFFBQU87QUFBQSxZQUNMLEtBQ0csSUFBSSxPQUFPLEVBQ1g7QUFBQSxjQUNDQSxRQUFPO0FBQUEsZ0JBQ0wsSUFBSSxPQUFPLGtCQUFrQixDQUFDLE9BQU87QUFBQSxrQkFDbkMsR0FBRztBQUFBLGtCQUNILFFBQVEsS0FBSyxJQUFJLEdBQUcsRUFBRSxTQUFTLENBQUM7QUFBQSxnQkFDbEMsRUFBRTtBQUFBLGNBQ0o7QUFBQSxjQUNBQSxRQUFPLFNBQVMsY0FBYyxDQUFDO0FBQUEsWUFDakM7QUFBQSxVQUNKLEVBQUUsS0FBS0EsUUFBTyxRQUFRQSxRQUFPLFNBQVMsY0FBYyxDQUFDLENBQUM7QUFBQSxRQUMxRCxDQUFDO0FBQUEsTUFDSDtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBRUYsUUFBTSxZQUFZLENBQUMsYUFDakJBLFFBQU8sSUFBSSxhQUFhO0FBQ3RCLFVBQU0sVUFBVSxLQUFLLGlCQUFpQixRQUFRO0FBRTlDLFFBQUksT0FBTyxTQUFTLFVBQVU7QUFDNUIsWUFBTSxjQUFjLE9BQU8sSUFBSSxJQUFJLGtCQUFrQjtBQUNyRCxZQUFNLE9BQU8sT0FBTyxJQUFJLElBQUksU0FBUztBQUNyQyxVQUFJLFFBQVEsZ0JBQWdCLEdBQUc7QUFFN0IsZUFBTyxNQUFNLGNBQWMsSUFBSTtBQUFBLE1BQ2pDO0FBRUEsWUFBTSxRQUFRLE9BQU8sSUFBSSxhQUFhLGdCQUFnQixDQUFDLE1BQU0sSUFBSSxDQUFDO0FBQ2xFLGFBQU8sSUFBSSxJQUFJLG9CQUFvQixLQUFLO0FBRXhDLFlBQU0sUUFBUSxPQUFPQSxRQUFPO0FBQUEsUUFDMUIsS0FBSyxJQUFJLE9BQU8sRUFBRTtBQUFBLFVBQ2hCQSxRQUFPO0FBQUEsWUFDTCxJQUFJLElBQUksa0JBQWtCLEVBQUU7QUFBQSxjQUMxQkEsUUFBTztBQUFBLGdCQUFRLENBQUMsWUFDZCxZQUFZLFFBQVEsSUFBSSxJQUFJLG9CQUFvQixDQUFDLElBQUlBLFFBQU87QUFBQSxjQUM5RDtBQUFBLFlBQ0Y7QUFBQSxVQUNGO0FBQUEsUUFDRjtBQUFBLE1BQ0Y7QUFDQSxhQUFPLElBQUksSUFBSSxXQUFXLEtBQUs7QUFDL0I7QUFBQSxJQUNGO0FBRUEsUUFBSSxPQUFPLFNBQVMsUUFBUTtBQUMxQixZQUFNLFdBQVcsT0FBTyxJQUFJO0FBQUEsUUFBTztBQUFBLFFBQVMsQ0FBQyxTQUMzQyxPQUFRLENBQUMsT0FBTyxJQUFJLElBQWUsQ0FBQyxNQUFNLElBQUk7QUFBQSxNQUNoRDtBQUNBLFVBQUksQ0FBQyxVQUFVO0FBQ2IsZUFBTyxLQUFLLE9BQU8sT0FBTztBQUMxQjtBQUFBLE1BQ0Y7QUFFQSxhQUFPQSxRQUFPO0FBQUEsUUFDWixLQUFLLElBQUksT0FBTyxFQUFFO0FBQUEsVUFDaEJBLFFBQU8sU0FBUyxJQUFJLElBQUksU0FBUyxLQUFLLENBQUM7QUFBQSxRQUN6QztBQUFBLE1BQ0Y7QUFDQTtBQUFBLElBQ0Y7QUFFQSxRQUFJLE9BQU8sU0FBUyxZQUFZO0FBQzlCLFlBQU1FLFlBQVcsT0FBTyxJQUFJLE9BQU8sa0JBQWtCLENBQUMsVUFBVTtBQUM5RCxjQUFNLFFBQVEsQ0FBQyxHQUFHLE1BQU0sT0FBTyxPQUFPO0FBQ3RDLGVBQU87QUFBQSxVQUNMLE1BQU07QUFBQSxVQUNOLEVBQUUsR0FBRyxPQUFPLE9BQU8sTUFBTSxLQUFLLElBQUksTUFBTSxNQUFNLE1BQU0sTUFBTSxFQUFFO0FBQUEsUUFDOUQ7QUFBQSxNQUNGLENBQUM7QUFFRCxVQUFJQSxZQUFXLG1CQUFtQixPQUFPO0FBQ3ZDLGNBQU0sUUFBUSxPQUFPLElBQUksSUFBSSxnQkFBZ0I7QUFDN0MsZUFBTyxLQUFLLGdCQUFnQjtBQUFBLFVBQzFCLE1BQU07QUFBQSxVQUNOLGVBQWVBO0FBQUEsVUFDZixNQUFNLE1BQU07QUFBQSxVQUNaLE9BQU87QUFBQSxVQUNQO0FBQUEsUUFDRixDQUFDO0FBQ0Q7QUFBQSxNQUNGO0FBRUEsYUFBTyxjQUFjO0FBQ3JCO0FBQUEsSUFDRjtBQUdBLFVBQU0sV0FBVyxPQUFPLElBQUksT0FBTyxnQkFBZ0IsQ0FBQyxVQUFVO0FBQzVELFlBQU0sUUFBUSxDQUFDLEdBQUcsTUFBTSxPQUFPLE9BQU87QUFDdEMsYUFBTztBQUFBLFFBQ0wsTUFBTTtBQUFBLFFBQ04sRUFBRSxHQUFHLE9BQU8sT0FBTyxNQUFNLEtBQUssSUFBSSxNQUFNLE1BQU0sTUFBTSxNQUFNLEVBQUU7QUFBQSxNQUM5RDtBQUFBLElBQ0YsQ0FBQztBQUVELFFBQUksV0FBVyxpQkFBaUIsT0FBTztBQUNyQyxZQUFNLFFBQVEsT0FBTyxJQUFJLElBQUksY0FBYztBQUMzQyxhQUFPLEtBQUssZ0JBQWdCO0FBQUEsUUFDMUIsTUFBTTtBQUFBLFFBQ04sZUFBZTtBQUFBLFFBQ2YsTUFBTSxNQUFNO0FBQUEsUUFDWixPQUFPO0FBQUEsUUFDUDtBQUFBLE1BQ0YsQ0FBQztBQUNEO0FBQUEsSUFDRjtBQUVBLFdBQU8sWUFBWTtBQUFBLEVBQ3JCLENBQUM7QUFFSCxTQUFPLE9BQU8sT0FBTyxXQUFXLEtBQUssUUFBUSxTQUFTO0FBQ3hELENBQUM7OztBQ3ZQSSxJQUFNLDBCQUEwQixJQUFJO0FBQ3BDLElBQU0sbUNBQW1DO0FBQ3pDLElBQU0sNENBQTRDO0FBV2xELElBQU0saUNBQWlDLENBQUMsYUFHWjtBQUFBLEVBQ2pDLFdBQ0UsT0FBTyxTQUFTLGNBQWMsWUFBWSxPQUFPLFNBQVMsUUFBUSxTQUFTLEtBQUssUUFBUSxhQUFhLElBQ2pHLEtBQUssTUFBTSxRQUFRLFNBQVMsSUFDNUI7QUFBQSxFQUNOLFVBQ0UsT0FBTyxTQUFTLGFBQWEsWUFBWSxPQUFPLFNBQVMsUUFBUSxRQUFRLEtBQUssUUFBUSxZQUFZLElBQzlGLEtBQUssTUFBTSxRQUFRLFFBQVEsSUFDM0I7QUFBQSxFQUNOLFNBQVM7QUFBQSxFQUNULFNBQVM7QUFBQSxFQUNULFlBQVk7QUFBQSxFQUNaLGdCQUFnQjtBQUNsQjtBQWVBLElBQU0seUJBQXlCLENBQUMsVUFPWDtBQUFBLEVBQ25CLE1BQU07QUFBQSxFQUNOLFVBQVUsS0FBSyxZQUFZO0FBQUEsRUFDM0IsU0FBUyxLQUFLLFlBQVk7QUFBQSxFQUMxQixVQUFVO0FBQUEsRUFDVixVQUFVLEtBQUssWUFBWTtBQUFBLEVBQzNCLGFBQWEsS0FBSyxZQUFZO0FBQUEsRUFDOUIsT0FBTztBQUFBLElBQ0wsU0FBUztBQUFBLElBQ1QsTUFBTTtBQUFBLElBQ04sTUFBTSxhQUFhLEtBQUssU0FBUyxhQUFhLEtBQUssUUFBUSxZQUFZLEtBQUssT0FBTyxZQUFZLEtBQUssT0FBTyxlQUFlLEtBQUssVUFBVTtBQUFBLEVBQzNJO0FBQ0Y7QUFFTyxJQUFNLDZCQUE2QixDQUN4QyxPQUNBLFVBQ3lFO0FBQ3pFLFFBQU0sWUFBWSxLQUFLLElBQUksR0FBRyxNQUFNLFNBQVM7QUFDN0MsUUFBTSxXQUFXLEtBQUssSUFBSSxHQUFHLE1BQU0sUUFBUTtBQUUzQyxNQUFJLE1BQU0sZ0JBQWdCO0FBQ3hCLFdBQU87QUFBQSxNQUNMLEVBQUUsTUFBTSxPQUFPO0FBQUEsTUFDZjtBQUFBLFFBQ0UsR0FBRztBQUFBLFFBQ0gsU0FBUyxNQUFNLFVBQVU7QUFBQSxNQUMzQjtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBRUEsUUFBTSxVQUFVO0FBQ2hCLFFBQU0saUJBQWlCLEtBQUssSUFBSSxHQUFHLFlBQVksT0FBTztBQUV0RCxNQUFJLE1BQU0sVUFBVSxnQkFBZ0I7QUFDbEMsVUFBTSxXQUFXLDRCQUE0QixPQUFPLEVBQUUsU0FBUyxDQUFDO0FBQ2hFLFdBQU87QUFBQSxNQUNMLEVBQUUsTUFBTSxRQUFRLE9BQU8sU0FBUyxNQUFNO0FBQUEsTUFDdEM7QUFBQSxRQUNFLEdBQUc7QUFBQSxRQUNILFNBQVMsTUFBTSxVQUFVO0FBQUEsUUFDekIsWUFBWSxNQUFNLGNBQWMsU0FBUyxhQUFhLElBQUk7QUFBQSxNQUM1RDtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBRUEsUUFBTSxVQUFVLE1BQU0sVUFBVTtBQUNoQyxRQUFNLFVBQVUsdUJBQXVCO0FBQUEsSUFDckMsYUFBYTtBQUFBLElBQ2I7QUFBQSxJQUNBO0FBQUEsSUFDQSxTQUFTLE1BQU07QUFBQSxJQUNmO0FBQUEsSUFDQSxZQUFZLE1BQU07QUFBQSxFQUNwQixDQUFDO0FBQ0QsUUFBTSxrQkFBa0IsNEJBQTRCLFNBQVMsRUFBRSxTQUFTLENBQUM7QUFFekUsU0FBTztBQUFBLElBQ0wsRUFBRSxNQUFNLGVBQWUsT0FBTyxnQkFBZ0IsTUFBTTtBQUFBLElBQ3BEO0FBQUEsTUFDRSxHQUFHO0FBQUEsTUFDSCxTQUFTLEtBQUssSUFBSSxXQUFXLE1BQU0sVUFBVSxDQUFDO0FBQUEsTUFDOUM7QUFBQSxNQUNBLFlBQVksTUFBTSxjQUFjLGdCQUFnQixhQUFhLElBQUk7QUFBQSxNQUNqRSxnQkFBZ0I7QUFBQSxJQUNsQjtBQUFBLEVBQ0Y7QUFDRjtBQUVPLElBQU0scUJBQXFCLENBQUMsVUFBZ0M7QUFDakUsUUFBTSxPQUFPLEtBQUssVUFBVSxLQUFLO0FBQ2pDLFNBQU8sT0FBTyxXQUFXLGNBQ3JCLE9BQU8sV0FBVyxNQUFNLE1BQU0sSUFDOUIsSUFBSSxZQUFZLEVBQUUsT0FBTyxJQUFJLEVBQUU7QUFDckM7QUFFQSxJQUFNLGdCQUFnQixDQUFDLE9BQWUsV0FDcEMsTUFBTSxVQUFVLFNBQVMsUUFBUSxNQUFNLE1BQU0sR0FBRyxNQUFNO0FBRXhELElBQU0sd0JBQXdCLENBQzVCLFVBQ3VDO0FBQ3ZDLFFBQU0sVUFDSixPQUFPLE1BQU0sWUFBWSxZQUFZLE1BQU0sUUFBUSxTQUFTLElBQUksTUFBTSxVQUFVO0FBRWxGLFFBQU0sT0FDSixPQUFPLE1BQU0sU0FBUyxZQUFZLE1BQU0sS0FBSyxTQUFTLElBQ2xELGNBQWMsTUFBTSxNQUFNLElBQUksSUFDOUI7QUFFTixTQUFPO0FBQUEsSUFDTCxNQUFNLE9BQU8sTUFBTSxTQUFTLFlBQVksTUFBTSxLQUFLLFNBQVMsSUFBSSxNQUFNLE9BQU87QUFBQSxJQUM3RSxTQUFTLGNBQWMsU0FBUyxHQUFHO0FBQUEsSUFDbkMsTUFBTSxPQUFPLE1BQU0sU0FBUyxZQUFZLE1BQU0sS0FBSyxTQUFTLElBQUksTUFBTSxPQUFPO0FBQUEsSUFDN0U7QUFBQSxFQUNGO0FBQ0Y7QUFFTyxJQUFNLDhCQUE4QixDQUN6QyxPQUNBLFlBR21FO0FBQ25FLFFBQU0sV0FBVyxTQUFTLFlBQVk7QUFFdEMsTUFBSSxhQUFhO0FBQ2pCLE1BQUksT0FBcUI7QUFFekIsTUFBSSxNQUFNLE9BQU87QUFDZixVQUFNLGFBQWEsc0JBQXNCLE1BQU0sS0FBSztBQUNwRCxRQUNFLFdBQVcsWUFBWSxNQUFNLE1BQU0sV0FDbkMsV0FBVyxTQUFTLE1BQU0sTUFBTSxRQUNoQyxXQUFXLFNBQVMsTUFBTSxNQUFNLFFBQ2hDLFdBQVcsU0FBUyxNQUFNLE1BQU0sTUFDaEM7QUFDQSxtQkFBYTtBQUNiLGFBQU8sRUFBRSxHQUFHLE9BQU8sT0FBTyxXQUFXO0FBQUEsSUFDdkM7QUFBQSxFQUNGO0FBRUEsTUFBSSxtQkFBbUIsSUFBSSxLQUFLLFVBQVU7QUFDeEMsV0FBTyxFQUFFLE9BQU8sTUFBTSxXQUFXO0FBQUEsRUFDbkM7QUFHQSxNQUFJLENBQUMsS0FBSyxPQUFPLE1BQU07QUFFckIsV0FBTyxFQUFFLE9BQU8sTUFBTSxZQUFZLEtBQUs7QUFBQSxFQUN6QztBQUVBLFFBQU0sT0FBTyxLQUFLLE1BQU07QUFDeEIsUUFBTSxRQUFRLENBQUMsS0FBSyxLQUFLLEtBQUssSUFBSSxJQUFJLENBQUM7QUFFdkMsYUFBVyxVQUFVLE9BQU87QUFDMUIsVUFBTSxVQUFVLFdBQVcsSUFBSSxTQUFZLGNBQWMsTUFBTSxNQUFNO0FBQ3JFLFVBQU0sWUFBMEI7QUFBQSxNQUM5QixHQUFHO0FBQUEsTUFDSCxPQUFPO0FBQUEsUUFDTCxHQUFHLEtBQUs7QUFBQSxRQUNSLE1BQU07QUFBQSxNQUNSO0FBQUEsSUFDRjtBQUNBLFFBQUksbUJBQW1CLFNBQVMsS0FBSyxVQUFVO0FBQzdDLGFBQU8sRUFBRSxPQUFPLFdBQVcsWUFBWSxLQUFLO0FBQUEsSUFDOUM7QUFBQSxFQUNGO0FBR0EsUUFBTSxXQUF5QixLQUFLLFFBQy9CO0FBQUEsSUFDQyxHQUFHO0FBQUEsSUFDSCxPQUFPO0FBQUEsTUFDTCxHQUFHLEtBQUs7QUFBQSxNQUNSLFNBQVMsY0FBYyxLQUFLLE1BQU0sU0FBUyxFQUFFO0FBQUEsTUFDN0MsTUFBTTtBQUFBLElBQ1I7QUFBQSxFQUNGLElBQ0E7QUFFSixTQUFPLEVBQUUsT0FBTyxVQUFVLFlBQVksS0FBSztBQUM3Qzs7O0FDL01PLElBQU0sZUFBZSxPQUF5QixFQUFFLGNBQWMsQ0FBQyxFQUFFO0FBVWpFLElBQU0sWUFBWSxDQUN2QixRQUNBLE9BQ0EsVUFDb0I7QUFDcEIsTUFBSSxPQUFPLFNBQVMsWUFBWTtBQUM5QixXQUFPO0FBQUEsTUFDTCxVQUFVO0FBQUEsTUFDVixXQUFXO0FBQUEsTUFDWCxzQkFBc0IsTUFBTSxhQUFhO0FBQUEsTUFDekMsYUFBYTtBQUFBLE1BQ2IsVUFBVSxPQUFPO0FBQUEsSUFDbkI7QUFBQSxFQUNGO0FBRUEsUUFBTSxpQkFBaUIsT0FBTztBQUM5QixRQUFNLGNBQ0osT0FBTyxtQkFBbUIsWUFBWSxPQUFPLFNBQVMsY0FBYyxLQUFLLGtCQUFrQixJQUN2RixLQUFLLE1BQU0sY0FBYyxJQUN6QjtBQUVOLE1BQUksZUFBZSxHQUFHO0FBQ3BCLFdBQU87QUFBQSxNQUNMLFVBQVU7QUFBQSxNQUNWLFdBQVc7QUFBQSxNQUNYLHNCQUFzQixNQUFNLGFBQWE7QUFBQSxNQUN6QztBQUFBLE1BQ0EsVUFBVSxPQUFPO0FBQUEsSUFDbkI7QUFBQSxFQUNGO0FBRUEsUUFBTSxjQUFjLE9BQU87QUFDM0IsUUFBTSxXQUNKLE9BQU8sZ0JBQWdCLFlBQVksT0FBTyxTQUFTLFdBQVcsS0FBSyxjQUFjLElBQzdFLEtBQUssTUFBTSxXQUFXLElBQ3RCO0FBRU4sUUFBTSxrQkFBa0IsQ0FBQyxHQUFHLE1BQU0sY0FBYyxLQUFLO0FBQ3JELFFBQU0sZUFBZSxXQUNqQixnQkFBZ0IsT0FBTyxDQUFDLE1BQU0sS0FBSyxRQUFRLFFBQVEsSUFDbkQ7QUFHSixRQUFNLE1BQU0sY0FBYztBQUMxQixRQUFNLFNBQ0osYUFBYSxTQUFTLE1BQU0sYUFBYSxNQUFNLGFBQWEsU0FBUyxHQUFHLElBQUk7QUFFOUUsUUFBTSx1QkFBdUIsT0FBTztBQUNwQyxRQUFNLFdBQ0osd0JBQXdCLGNBQWMsWUFBWTtBQUVwRCxTQUFPO0FBQUEsSUFDTDtBQUFBLElBQ0EsV0FBVyxFQUFFLGNBQWMsT0FBTztBQUFBLElBQ2xDO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxFQUNGO0FBQ0Y7OztBSnNCTyxJQUFNLG9CQUFOLGNBQWdDQyxTQUFRLElBQUksNEJBQTRCLEVBRzdFLEVBQUU7QUFBQztBQUVMLElBQU0sd0JBQXdCQyxVQUFTLFdBQXVDLE1BQVM7QUFDdkYsSUFBTSw0QkFBNEJBLFVBQVMsV0FFekMsTUFBUztBQUNYLElBQU0scUJBQXFCO0FBRTNCLElBQU0sc0JBQXNCLENBQUMsY0FBOEIsV0FBVyxTQUFTO0FBRS9FLElBQU0sa0JBQWtCLENBQ3RCLFVBQzBEO0FBQzFELFFBQU0sVUFBZSxNQUFNO0FBQzNCLE1BQUksQ0FBQyxRQUFTLFFBQU8sQ0FBQztBQUN0QixPQUNHLFFBQVEsU0FBUyxrQkFBa0IsUUFBUSxTQUFTLHdCQUNyRCxPQUFPLFFBQVEsZUFBZSxZQUM5QixPQUFPLFFBQVEsV0FBVyxZQUMxQixPQUFPLFNBQVMsUUFBUSxNQUFNLEtBQzlCLFFBQVEsVUFBVSxHQUNsQjtBQUNBLFVBQU0sU0FBUyxLQUFLLE1BQU0sUUFBUSxNQUFNO0FBQ3hDLFdBQU87QUFBQSxNQUNMO0FBQUEsTUFDQSxPQUFPLEdBQUcsUUFBUSxVQUFVLE1BQU0sTUFBTTtBQUFBLElBQzFDO0FBQUEsRUFDRjtBQUNBLFNBQU8sQ0FBQztBQUNWO0FBRUEsSUFBTSx5QkFBeUIsQ0FBQyxPQUFxQixTQUF5QztBQUM1RixRQUFNLFdBQVcsTUFBTSxTQUFTLG1CQUFtQixNQUFNLFdBQVc7QUFDcEUsUUFBTSxhQUFhLE1BQU0sU0FBUyxtQkFBbUIsTUFBTSxhQUFhO0FBQ3hFLFNBQWtCLGlDQUFpQztBQUFBLElBQ2pEO0FBQUEsSUFDQTtBQUFBLElBQ0EsTUFBTTtBQUFBLElBQ04sVUFBVTtBQUFBLElBQ1YsU0FDRTtBQUFBLElBQ0YsTUFDRTtBQUFBLElBRUY7QUFBQSxFQUNGLENBQUM7QUFDSDtBQUlBLElBQU0sbUJBQW1CLENBQUMsTUFBYyxTQUFpQixTQUF5QjtBQUNoRixRQUFNLE1BQU0sSUFBSSxNQUFNLE9BQU87QUFDNUIsRUFBQyxJQUFZLE9BQU87QUFDcEIsRUFBQyxJQUFZLE9BQ1osUUFDQTtBQUFBLElBQ0U7QUFBQSxJQUNBLFNBQVMsSUFBSTtBQUFBLElBQ2I7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsRUFDRixFQUFFLEtBQUssSUFBSTtBQUNiLFNBQU87QUFDVDtBQUVBLElBQU0sZUFBZSxDQUNuQixTQUM0SDtBQUM1SCxNQUFJLE9BQU8sU0FBUyxZQUFZLEtBQUssV0FBVyxHQUFHO0FBQ2pELFdBQU8sRUFBRSxJQUFJLE9BQU8sT0FBTyxpQkFBaUIsT0FBTyxJQUFJLEdBQUcscUNBQXFDLEVBQUU7QUFBQSxFQUNuRztBQUVBLFFBQU0sTUFBTSxLQUFLLE1BQU0sR0FBRztBQUMxQixNQUFJLElBQUksV0FBVyxHQUFHO0FBQ3BCLFdBQU8sRUFBRSxJQUFJLE9BQU8sT0FBTyxpQkFBaUIsTUFBTSw0Q0FBNEMsRUFBRTtBQUFBLEVBQ2xHO0FBRUEsUUFBTSxXQUE2QixDQUFDO0FBQ3BDLFdBQVMsSUFBSSxHQUFHLElBQUksSUFBSSxRQUFRLEtBQUs7QUFDbkMsVUFBTSxNQUFNLElBQUksQ0FBQztBQUNqQixRQUFJLElBQUksV0FBVyxHQUFHO0FBQ3BCLGFBQU87QUFBQSxRQUNMLElBQUk7QUFBQSxRQUNKLE9BQU87QUFBQSxVQUNMO0FBQUEsVUFDQSw0Q0FBNEMsQ0FBQztBQUFBLFVBQzdDO0FBQUEsWUFDRTtBQUFBLFlBQ0EsU0FBUyxJQUFJO0FBQUEsWUFDYjtBQUFBLFlBQ0E7QUFBQSxZQUNBO0FBQUEsWUFDQTtBQUFBLFlBQ0E7QUFBQSxZQUNBO0FBQUEsWUFDQTtBQUFBLFlBQ0E7QUFBQSxVQUNGLEVBQUUsS0FBSyxJQUFJO0FBQUEsUUFDYjtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBRUEsUUFBSSxXQUFXLEtBQUssR0FBRyxHQUFHO0FBQ3hCLFlBQU0sSUFBSSxPQUFPLEdBQUc7QUFDcEIsVUFBSSxDQUFDLE9BQU8sU0FBUyxDQUFDLEtBQUssSUFBSSxHQUFHO0FBQ2hDLGVBQU87QUFBQSxVQUNMLElBQUk7QUFBQSxVQUNKLE9BQU8saUJBQWlCLE1BQU0sZ0NBQWdDLEdBQUcsY0FBYyxDQUFDLEdBQUc7QUFBQSxRQUNyRjtBQUFBLE1BQ0Y7QUFDQSxlQUFTLEtBQUssS0FBSyxNQUFNLENBQUMsQ0FBQztBQUMzQjtBQUFBLElBQ0Y7QUFFQSxhQUFTLEtBQUssR0FBRztBQUFBLEVBQ25CO0FBRUEsU0FBTyxFQUFFLElBQUksTUFBTSxTQUFTO0FBQzlCO0FBRUEsSUFBTSxrQkFBa0IsQ0FBQyxhQUE0QyxDQUFDLFVBQTRCO0FBQ2hHLE1BQUksVUFBZTtBQUNuQixhQUFXLE9BQU8sVUFBVTtBQUMxQixRQUFJLFdBQVcsS0FBTSxRQUFPO0FBQzVCLGNBQVUsUUFBUSxHQUFVO0FBQUEsRUFDOUI7QUFDQSxTQUFPO0FBQ1Q7QUFFQSxJQUFNLHNCQUFzQixDQUFDLFdBQXdDO0FBQ25FLE1BQUksQ0FBQyxVQUFVLE9BQU8sV0FBVyxTQUFVLFFBQU87QUFDbEQsUUFBTSxZQUFZO0FBQ2xCLE1BQUksT0FBTyxVQUFVLFNBQVMsWUFBWSxVQUFVLEtBQUssU0FBUyxFQUFHLFFBQU8sVUFBVTtBQUN0RixNQUFJLE9BQU8sVUFBVSxTQUFTLFlBQVksVUFBVSxLQUFLLFNBQVMsRUFBRyxRQUFPLFVBQVU7QUFDdEYsU0FBTztBQUNUO0FBRU8sSUFBTSxPQUFPLENBQUMsWUFHbkJDLFFBQU8sSUFBSSxhQUFhO0FBQ3RCLFFBQU0sZUFBZSxPQUFPQSxRQUFPO0FBQ25DLFFBQU0sa0JBQ0osT0FBTyxTQUFTLG9CQUFvQixZQUNwQyxPQUFPLFNBQVMsUUFBUSxlQUFlLEtBQ3ZDLFFBQVEsbUJBQW1CLElBQ3ZCLEtBQUssTUFBTSxRQUFRLGVBQWUsSUFDbEM7QUFFTixRQUFNLGdCQUFnQixvQkFBSSxJQUF3QztBQUNsRSxRQUFNLFlBQVksb0JBQUksSUFBc0M7QUFFNUQsUUFBTSxlQUErQixDQUFDO0FBQ3RDLFFBQU0sWUFBWSxPQUFPLE9BQU8sUUFBc0IsS0FBSyxJQUFJLEdBQUcsS0FBSyxJQUFJLE1BQU0sZUFBZSxDQUFDLENBQUM7QUFFbEcsUUFBTSxhQUFhLE1BQU07QUFDdkIsUUFBSSxtQkFBbUIsR0FBRztBQUN4QixtQkFBYSxTQUFTO0FBQ3RCO0FBQUEsSUFDRjtBQUNBLFFBQUksYUFBYSxVQUFVLGdCQUFpQjtBQUM1QyxVQUFNLFNBQVMsYUFBYSxTQUFTO0FBQ3JDLGlCQUFhLE9BQU8sR0FBRyxNQUFNO0FBQUEsRUFDL0I7QUFFQSxRQUFNLG1CQUFtQixDQUFDLFVBQ3hCQSxRQUFPLElBQUksYUFBYTtBQUN0QixVQUFNLG1CQUFtQixPQUFPRCxVQUFTLElBQVUsdUJBQXVCO0FBRzFFLFFBQUkscUJBQXFCLE9BQU87QUFDOUI7QUFBQSxJQUNGO0FBRUEsVUFBTSxZQUFZLE1BQU0sU0FBUyxTQUFTO0FBQzFDLFVBQU0sb0JBQTZCLDhCQUE4QixNQUFNLFFBQVE7QUFDL0UsVUFBTSxXQUFXLG9CQUFvQixTQUFTO0FBQzlDLFVBQU0sRUFBRSxRQUFRLE1BQU0sSUFBSSxnQkFBZ0IsS0FBSztBQUUvQyxXQUFhLE9BQU87QUFBQSxNQUNsQixNQUFNLE1BQU07QUFBQSxNQUNaO0FBQUEsTUFDQSxZQUFZO0FBQUEsTUFDWixVQUFVLE1BQU07QUFBQSxNQUNoQixVQUFVLE1BQU07QUFBQSxNQUNoQixVQUFVLE1BQU07QUFBQSxNQUNoQixhQUFhLE1BQU07QUFBQSxNQUNuQixTQUFTLE1BQU07QUFBQSxNQUNmLFVBQVUsTUFBTTtBQUFBLE1BQ2hCLE9BQU8sTUFBTTtBQUFBLE1BQ2I7QUFBQSxNQUNBO0FBQUEsSUFDRixDQUFRO0FBQUEsRUFDVixDQUFDO0FBRUgsUUFBTSxlQUFlLENBQUMsVUFDcEJDLFFBQU8sSUFBSSxhQUFhO0FBQ3RCLGlCQUFhLEtBQUssS0FBSztBQUN2QixlQUFXO0FBQ1gsV0FBTyxPQUFPLFFBQVEsV0FBVyxLQUFLO0FBQ3RDLFdBQU8saUJBQWlCLEtBQUs7QUFBQSxFQUMvQixDQUFDO0FBRUgsUUFBTSxPQUFPLENBQUMsVUFDWkEsUUFBTyxJQUFJLGFBQWE7QUFDdEIsVUFBTSxZQUFZLE9BQU9ELFVBQVMsSUFBSSx5QkFBeUI7QUFDL0QsUUFBSSxXQUFXO0FBQ2IsWUFBTSxXQUFXLE9BQU9FLEtBQUksT0FBTyxXQUFXLENBQUMsVUFBVTtBQUN2RCxjQUFNLENBQUMsY0FBYyxTQUFTLElBQWtCLDJCQUEyQixPQUFPLEtBQUs7QUFDdkYsZUFBTyxDQUFDLGNBQWMsU0FBUztBQUFBLE1BQ2pDLENBQUM7QUFFRCxVQUFJLFNBQVMsU0FBUyxVQUFVLFNBQVMsU0FBUyxlQUFlO0FBQy9ELGVBQU8sYUFBYSxTQUFTLEtBQUs7QUFBQSxNQUNwQztBQUNBO0FBQUEsSUFDRjtBQUVBLFVBQU0sV0FBeUIsNEJBQTRCLEtBQUs7QUFDaEUsV0FBTyxhQUFhLFNBQVMsS0FBSztBQUFBLEVBQ3BDLENBQUM7QUFFSCxRQUFNLHNCQUFzQixDQUMxQixPQUNBLFdBQ0EsTUFDQSxTQUNBLFNBQ3dCO0FBQ3hCLFFBQUksQ0FBQyxTQUFTLEdBQUc7QUFDZixhQUFPRCxRQUFPO0FBQUEsSUFDaEI7QUFDQSxVQUFNLFdBQVcsTUFBTSxTQUFTLG1CQUFtQixNQUFNLFdBQVc7QUFDcEUsVUFBTSxhQUFhLE1BQU0sU0FBUyxtQkFBbUIsTUFBTSxhQUFhO0FBQ3hFLFdBQWEsT0FBTztBQUFBLE1BQ2xCLE1BQU07QUFBQSxNQUNOO0FBQUEsTUFDQTtBQUFBLE1BQ0E7QUFBQSxNQUNBLFVBQVU7QUFBQSxNQUNWO0FBQUEsTUFDQTtBQUFBLE1BQ0EsV0FBVztBQUFBLE1BQ1gsTUFBTTtBQUFBLElBQ1IsQ0FBQztBQUFBLEVBQ0g7QUFFQSxRQUFNLDZCQUE2QixDQUFDLGlCQUEyRDtBQUM3RixVQUFNLFdBQVcsYUFBYSxXQUFXLFlBQVksQ0FBQztBQUN0RCxVQUFNLHVCQUFpQyxDQUFDO0FBQ3hDLGVBQVcsV0FBVyxhQUFhLFdBQVcsVUFBVTtBQUN0RCxVQUFJLFFBQVEsU0FBUyxrQkFBa0IsUUFBUSxTQUFTLHFCQUFxQjtBQUMzRSw2QkFBcUIsS0FBSyxRQUFRLFFBQVE7QUFBQSxNQUM1QztBQUFBLElBQ0Y7QUFFQSxVQUFNLFdBQVcsTUFBTSxLQUFLLG9CQUFJLElBQUksQ0FBQyxHQUFHLFVBQVUsR0FBRyxvQkFBb0IsQ0FBQyxDQUFDO0FBQzNFLFFBQUksU0FBUyxXQUFXLEVBQUcsUUFBTyxDQUFDO0FBRW5DLFVBQU0sVUFBb0IsQ0FBQztBQUMzQixlQUFXLE9BQU8sVUFBVTtBQUMxQixVQUFJLE9BQU8sUUFBUSxZQUFZLElBQUksV0FBVyxFQUFHO0FBR2pELFlBQU0sTUFBTUYsU0FBUSxJQUFJLGlCQUFpQixHQUFHLEVBQUUsRUFBRTtBQUNoRCxZQUFNLFFBQVFBLFNBQVEsVUFBVSxhQUFhLEtBQUssR0FBRztBQUNyRCxVQUFJSSxRQUFPLE9BQU8sS0FBSyxHQUFHO0FBQ3hCLGdCQUFRLEtBQUssR0FBRztBQUFBLE1BQ2xCO0FBQUEsSUFDRjtBQUNBLFdBQU87QUFBQSxFQUNUO0FBRUEsUUFBTSxlQUFlLENBQ25CLFVBQ0EsV0FFQUYsUUFBTyxJQUFJLGFBQWE7QUFDdEIsVUFBTSxRQUFRLFNBQVM7QUFDdkIsYUFBUyxTQUFTO0FBQUEsTUFDaEIsR0FBRyxTQUFTO0FBQUEsTUFDWixRQUFRO0FBQUEsTUFDUixlQUFlO0FBQUEsSUFDakI7QUFFQSxRQUFJLE9BQU87QUFDVCxhQUFPRyxPQUFNLFVBQVUsS0FBSztBQUFBLElBQzlCO0FBRUEsV0FBTyxNQUFNLFNBQVMsU0FBUyxxQkFBcUI7QUFFcEQsYUFBUyxTQUFTO0FBQUEsTUFDaEIsR0FBRyxTQUFTO0FBQUEsTUFDWixRQUFRO0FBQUEsTUFDUixlQUFlO0FBQUEsSUFDakI7QUFDQSxhQUFTLFFBQVE7QUFFakIsVUFBTSxNQUFvQjtBQUFBLE1BQ3hCLE1BQU07QUFBQSxNQUNOLFVBQVUsU0FBUztBQUFBLE1BQ25CLFVBQVU7QUFBQSxNQUNWLFVBQVUsU0FBUztBQUFBLE1BQ25CLGFBQWEsS0FBSyxJQUFJO0FBQUEsSUFDeEI7QUFDQSxXQUFPLEtBQUssR0FBRztBQUFBLEVBQ2pCLENBQUM7QUFFSCxRQUFNLG9CQUErRSxDQUNuRixvQkFFQUgsUUFBTyxJQUFJLGFBQWE7QUFDdEIsVUFBTSxlQUFlLGNBQWMsSUFBSSxlQUFlO0FBQ3RELFFBQUksQ0FBQyxhQUFjO0FBRW5CLFVBQU0sT0FBTyxPQUFPLHVCQUF1QixhQUFhLFNBQVMsT0FBTyw4QkFBOEI7QUFDdEcsUUFBSSxLQUFNO0FBR1YsVUFBTSxZQUFZLGFBQWE7QUFDL0IsUUFBSSxXQUFXO0FBQ2IsWUFBTSxVQUFVLFVBQVUsSUFBSSxTQUFTO0FBQ3ZDLFVBQUksV0FBVyxRQUFRLE9BQU8sV0FBVyxXQUFXO0FBQ2xEO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFFQSxVQUFNLFNBQVMsYUFBYTtBQUM1QixVQUFNLFdBQW9DO0FBQUEsTUFDeEMsVUFBVSxhQUFhO0FBQUEsTUFDdkI7QUFBQSxJQUNGO0FBQ0EsVUFBTSxvQkFBNkIsOEJBQThCLFFBQVE7QUFFekUsVUFBTSx3QkFBd0IsT0FBTyxNQUFNLFFBQXdCLEVBQUU7QUFFckUsVUFBTSxnQkFBK0I7QUFBQSxNQUNuQztBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsTUFDQSxXQUFXLGFBQWEsU0FBUztBQUFBLE1BQ2pDLE9BQU8sYUFBYSxTQUFTO0FBQUEsTUFDN0I7QUFBQSxNQUNBLFFBQVE7QUFBQSxRQUNOO0FBQUEsUUFDQSxRQUFRO0FBQUEsTUFDVjtBQUFBLE1BQ0EsY0FBYztBQUFBLE1BQ2QsZ0JBQWdCO0FBQUEsSUFDbEI7QUFFQSxjQUFVLElBQUksbUJBQW1CLGFBQWE7QUFDOUMsaUJBQWEsb0JBQW9CO0FBR2pDLFdBQU8sS0FBSztBQUFBLE1BQ1YsTUFBTTtBQUFBLE1BQ047QUFBQSxNQUNBLFVBQVU7QUFBQSxNQUNWLFVBQVUsY0FBYztBQUFBLE1BQ3hCLGFBQWEsS0FBSyxJQUFJO0FBQUEsSUFDeEIsQ0FBQztBQUVELFVBQU0sVUFBVSwyQkFBMkIsWUFBWTtBQUN2RCxRQUFJLFFBQVEsU0FBUyxHQUFHO0FBQ3RCLFlBQU0sT0FBTyxTQUFTLElBQ2xCO0FBQUEsUUFDRTtBQUFBLFFBQ0EsWUFBWSxRQUFRLEtBQUssSUFBSSxDQUFDO0FBQUEsUUFDOUI7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0EsK0NBQStDLFFBQVEsQ0FBQyxDQUFDO0FBQUEsUUFDekQ7QUFBQSxNQUNGLEVBQUUsS0FBSyxJQUFJLElBQ1g7QUFFSixZQUFNLFFBQWtDO0FBQUEsUUFDdEMsU0FBUyxrQ0FBa0MsUUFBUSxLQUFLLElBQUksQ0FBQztBQUFBLFFBQzdELE1BQU07QUFBQSxRQUNOO0FBQUEsTUFDRjtBQUVBLG9CQUFjLFNBQVM7QUFBQSxRQUNyQixHQUFHLGNBQWM7QUFBQSxRQUNqQixRQUFRO0FBQUEsUUFDUixlQUFlO0FBQUEsUUFDZixXQUFXO0FBQUEsTUFDYjtBQUVBLGFBQU8sS0FBSztBQUFBLFFBQ1YsTUFBTTtBQUFBLFFBQ047QUFBQSxRQUNBLFVBQVU7QUFBQSxRQUNWLFVBQVUsY0FBYztBQUFBLFFBQ3hCLGFBQWEsS0FBSyxJQUFJO0FBQUEsUUFDdEI7QUFBQSxNQUNGLENBQUM7QUFFRCxhQUFPO0FBQUEsUUFDTCxhQUFhLFNBQVM7QUFBQSxRQUN0QixhQUFhLFNBQVM7QUFBQSxRQUN0QjtBQUFBLFFBQ0EsTUFBTTtBQUFBLFFBQ047QUFBQSxNQUNGO0FBQ0E7QUFBQSxJQUNGO0FBRUEsVUFBTSwwQkFBMEIsYUFBYSxXQUFXLHFCQUFxQjtBQUU3RSxVQUFNLFVBQVUsYUFBYTtBQUU3QixVQUFNLGlCQUFpQixNQUE0QjtBQUNqRCxVQUFJLENBQUMseUJBQXlCO0FBQzVCLGVBQU87QUFBQSxNQUNUO0FBRUEsWUFBTSxXQUFXLGFBQWEsV0FBVyxZQUFZLENBQUM7QUFDdEQsVUFBSSxTQUFTLFdBQVcsR0FBRztBQUN6QixlQUFPO0FBQUEsTUFDVDtBQUVBLFlBQU0sTUFBTSxNQUFNLEtBQUssSUFBSSxJQUFJLFFBQVEsQ0FBQztBQUN4QyxVQUFJLFVBQVU7QUFFZCxpQkFBVyxZQUFZLEtBQUs7QUFDMUIsWUFBSSxPQUFPLGFBQWEsWUFBWSxTQUFTLFdBQVcsRUFBRztBQUMzRCxjQUFNLE1BQU1GLFNBQVEsSUFBSSxpQkFBaUIsUUFBUSxFQUFFLEVBQUU7QUFDckQsY0FBTSxRQUFRQSxTQUFRLFVBQVUsU0FBUyxHQUFHO0FBQzVDLFlBQUlJLFFBQU8sT0FBTyxLQUFLLEVBQUc7QUFDMUIsY0FBTSxVQUFVLE1BQU07QUFFdEIsY0FBTSxpQkFBaUIsQ0FBQyxXQUN0QkYsUUFBTyxJQUFJLGFBQWE7QUFDdEIsZ0JBQU0sVUFBVSxPQUFPRCxVQUFTLElBQUkscUJBQXFCO0FBQ3pELGNBQUksQ0FBQyxRQUFTO0FBRWQsZ0JBQU0sV0FBVyxvQkFBb0IsTUFBTSxLQUFLO0FBQ2hELGdCQUFNLG1CQUFtQixPQUFPLFFBQVEsYUFBYSxXQUFXLFFBQVEsV0FBVztBQUNuRixnQkFBTSxxQkFBcUIsT0FBTyxRQUFRLGVBQWUsV0FBVyxRQUFRLGFBQWE7QUFFekYsZ0JBQU0sTUFBb0I7QUFBQSxZQUN4QixNQUFNO0FBQUEsWUFDTjtBQUFBLFlBQ0E7QUFBQSxZQUNBLFVBQVU7QUFBQSxjQUNSLFVBQVU7QUFBQSxjQUNWLFlBQVk7QUFBQSxjQUNaO0FBQUEsWUFDRjtBQUFBLFlBQ0EsVUFBVTtBQUFBLFlBQ1YsVUFBVSxjQUFjO0FBQUEsWUFDeEIsYUFBYSxLQUFLLElBQUk7QUFBQSxVQUN4QjtBQUVBLGlCQUFPLEtBQUssR0FBRztBQUFBLFFBQ2pCLENBQUM7QUFFSCxjQUFNLFVBQVU7QUFBQSxVQUNkLEdBQUc7QUFBQSxVQUNILFVBQVUsQ0FBQyxXQUNULFFBQVEsU0FBUyxNQUFNLEVBQUUsS0FBS0MsUUFBTyxJQUFJLE1BQU0sZUFBZSxNQUFNLENBQUMsQ0FBQztBQUFBLFVBQ3hFLHFCQUFxQixDQUFDLFdBQ3BCLFFBQVEsb0JBQW9CLE1BQU0sRUFBRSxLQUFLQSxRQUFPLElBQUksTUFBTSxlQUFlLE1BQU0sQ0FBQyxDQUFDO0FBQUEsVUFDbkYsZUFBZSxDQUFDLFlBQ2QsUUFBUSxjQUFjLE9BQU8sRUFBRTtBQUFBLFlBQzdCQSxRQUFPLElBQUksTUFBTUEsUUFBTyxRQUFRLFNBQVMsZ0JBQWdCLEVBQUUsU0FBUyxLQUFLLENBQUMsQ0FBQztBQUFBLFVBQzdFO0FBQUEsUUFDSjtBQUVBLGtCQUFVRixTQUFRLElBQUksS0FBSyxPQUFPLEVBQUUsT0FBTztBQUFBLE1BQzdDO0FBRUEsYUFBTztBQUFBLElBQ1Q7QUFFQSxVQUFNLGFBQWEsZUFBZTtBQUVsQyxVQUFNLG9CQUFvQixDQUN4QixTQUVBRSxRQUFPLElBQUksYUFBYTtBQUN0QixVQUFJLEtBQUssU0FBUyxTQUFTO0FBQ3pCLGNBQU0sV0FBVyxTQUFTLGNBQWMsS0FBSyxPQUFPO0FBQ3BELFlBQUlFLFFBQU8sT0FBTyxRQUFRLEdBQUc7QUFDM0IsZ0JBQU0sTUFBTSxJQUFJLE1BQU0sOERBQThELEtBQUssT0FBTyxFQUFFO0FBQ2pHLFVBQUMsSUFBWSxPQUFPO0FBQ3BCLFVBQUMsSUFBWSxPQUNaO0FBQ0YsaUJBQU8sT0FBT0YsUUFBTyxLQUFLLEdBQUc7QUFBQSxRQUMvQjtBQUVBLGVBQU9JLFFBQU8sS0FBSyxTQUFTLEtBQUssRUFBRTtBQUFBLFVBQ2pDQSxRQUFPO0FBQUEsWUFDTCxPQUNHO0FBQUEsY0FDQyxNQUFNO0FBQUEsY0FDTixNQUFNLEtBQUs7QUFBQSxjQUNYLFNBQVMsS0FBSztBQUFBLFlBQ2hCO0FBQUEsVUFDSjtBQUFBLFFBQ0Y7QUFBQSxNQUNGO0FBRUEsVUFBSSxLQUFLLFNBQVMsZ0JBQWdCO0FBQ2hDLGNBQU1DLE9BQU1QLFNBQVEsSUFBSSxpQkFBaUIsS0FBSyxRQUFRLEVBQUUsRUFBRTtBQUMxRCxjQUFNUSxTQUFRUixTQUFRLFVBQVUsU0FBU08sSUFBRztBQUM1QyxZQUFJSCxRQUFPLE9BQU9JLE1BQUssR0FBRztBQUN4QixpQkFBTyxPQUFPTixRQUFPLEtBQUssSUFBSSxNQUFNLG9DQUFvQyxLQUFLLFFBQVEsRUFBRSxDQUFDO0FBQUEsUUFDMUY7QUFFQSxjQUFNTyxXQUFVRCxPQUFNO0FBSXRCLFlBQUksQ0FBQyx5QkFBeUI7QUFDNUIsZ0JBQU1FLFVBQVNELFNBQVE7QUFDdkIsY0FBSSxDQUFDQyxTQUFRO0FBQ1gsa0JBQU0sTUFBTSxJQUFJO0FBQUEsY0FDZDtBQUFBLFlBQ0Y7QUFDQyxZQUFDLElBQVksT0FBTztBQUNwQixZQUFDLElBQVksT0FBTyxZQUFZLEtBQUssUUFBUTtBQUM5QyxtQkFBTyxPQUFPUixRQUFPLEtBQUssR0FBRztBQUFBLFVBQy9CO0FBRUEsaUJBQU9RLFFBQU87QUFBQSxZQUNaSixRQUFPLE9BQU8sQ0FBQyxXQUFnQixvQkFBb0IsTUFBTSxNQUFNLEtBQUssUUFBUTtBQUFBLFlBQzVFQSxRQUFPO0FBQUEsY0FDTCxPQUNHO0FBQUEsZ0JBQ0MsTUFBTTtBQUFBLGdCQUNOLE1BQU0sS0FBSztBQUFBLGdCQUNYLFVBQVUsS0FBSztBQUFBLGdCQUNmLFlBQVlHLFNBQVE7QUFBQSxnQkFDcEIsVUFBVSxLQUFLO0FBQUEsZ0JBQ2YsUUFBUTtBQUFBLGNBQ1Y7QUFBQSxZQUNKO0FBQUEsVUFDRjtBQUFBLFFBQ0Y7QUFFQSxjQUFNLFNBQVNBLFNBQVE7QUFDdkIsWUFBSSxDQUFDLFFBQVE7QUFDWCxnQkFBTSxNQUFNLElBQUk7QUFBQSxZQUNkO0FBQUEsVUFDRjtBQUNDLFVBQUMsSUFBWSxPQUFPO0FBQ3BCLFVBQUMsSUFBWSxPQUFPLFlBQVksS0FBSyxRQUFRO0FBQzlDLGlCQUFPLE9BQU9QLFFBQU8sS0FBSyxHQUFHO0FBQUEsUUFDL0I7QUFFQSxlQUFPLE9BQU87QUFBQSxVQUNaSSxRQUFPLE9BQU8sQ0FBQyxRQUFhLG9CQUFvQixJQUFJLEtBQUssTUFBTSxLQUFLLFFBQVE7QUFBQSxVQUM1RUEsUUFBTyxJQUFJLENBQUMsUUFBYTtBQUN2QixrQkFBTSxTQUFTLEtBQUssTUFBTTtBQUMxQixtQkFBTztBQUFBLGNBQ0wsTUFBTTtBQUFBLGNBQ04sTUFBTSxLQUFLO0FBQUEsY0FDWCxVQUFVLEtBQUs7QUFBQSxjQUNmLFlBQVlHLFNBQVE7QUFBQSxjQUNwQixVQUFVLEtBQUs7QUFBQSxjQUNmLFFBQVEsT0FBTyxXQUFXLFdBQVcsU0FBUztBQUFBLFlBQ2hEO0FBQUEsVUFDRixDQUFDO0FBQUEsUUFDSDtBQUFBLE1BQ0Y7QUFHQSxZQUFNLFNBQVMsYUFBYSxLQUFLLElBQUk7QUFDckMsVUFBSSxDQUFDLE9BQU8sSUFBSTtBQUNkLGVBQU8sT0FBT1AsUUFBTyxLQUFLLE9BQU8sS0FBSztBQUFBLE1BQ3hDO0FBRUEsWUFBTSxNQUFNRixTQUFRLElBQUksaUJBQWlCLEtBQUssUUFBUSxFQUFFLEVBQUU7QUFDMUQsWUFBTSxRQUFRQSxTQUFRLFVBQVUsU0FBUyxHQUFHO0FBQzVDLFVBQUlJLFFBQU8sT0FBTyxLQUFLLEdBQUc7QUFDeEIsZUFBTyxPQUFPRixRQUFPLEtBQUssSUFBSSxNQUFNLG9DQUFvQyxLQUFLLFFBQVEsRUFBRSxDQUFDO0FBQUEsTUFDMUY7QUFFQSxZQUFNLFVBQVUsTUFBTTtBQUN0QixZQUFNLGVBQWUsZ0JBQWdCLE9BQU8sUUFBUTtBQUNwRCxZQUFNLFVBQVUsT0FBT0MsS0FBSSxLQUE2QkMsUUFBTyxLQUFLLENBQUM7QUFFckUsWUFBTSw0QkFBNEI7QUFFbEMsWUFBTSx5QkFBeUIsNEJBQzNCLE9BQU9ELEtBQUksS0FBSztBQUFBLFFBQ2QsaUJBQWlCLEtBQUssSUFBSTtBQUFBLFFBQzFCLGtCQUFrQjtBQUFBLFFBQ2xCLGlCQUFpQjtBQUFBLE1BQ25CLENBQUMsSUFDRDtBQUVKLFlBQU0sa0JBQWtCO0FBQ3hCLFlBQU0sd0JBQXdCO0FBQzlCLFlBQU0sa0JBQWtCO0FBQ3hCLFlBQU0sMEJBQTBCLFNBQVMsSUFBSSxLQUFLO0FBQ2xELFlBQU0sb0JBQW9CO0FBRTFCLFVBQUksZ0JBQWdCO0FBQ3BCLFVBQUksa0JBQWtCO0FBQ3RCLFVBQUksc0JBQXNCO0FBQzFCLFVBQUksc0JBQXNCO0FBRTFCLFlBQU0sUUFBUSxNQUFjO0FBQzFCLFlBQUksT0FBTyxnQkFBZ0IsZUFBZSxPQUFPLFlBQVksUUFBUSxZQUFZO0FBQy9FLGlCQUFPLFlBQVksSUFBSTtBQUFBLFFBQ3pCO0FBQ0EsZUFBTyxLQUFLLElBQUk7QUFBQSxNQUNsQjtBQUVBLFlBQU0sV0FBVyw2QkFDWixDQUFDLFVBQTRCO0FBQzVCLHlCQUFpQjtBQUNqQixhQUFLLGdCQUFnQixxQkFBcUIsR0FBRztBQUMzQyxpQkFBTyxhQUFhLEtBQUs7QUFBQSxRQUMzQjtBQUVBLGNBQU0sS0FBSyxNQUFNO0FBQ2pCLGNBQU0sUUFBUSxhQUFhLEtBQUs7QUFDaEMsY0FBTSxLQUFLLE1BQU0sSUFBSTtBQUVyQiwyQkFBbUI7QUFDbkIsWUFBSSxNQUFNLHVCQUF1QjtBQUMvQixpQ0FBdUI7QUFBQSxRQUN6QjtBQUNBLFlBQUksS0FBSyxxQkFBcUI7QUFDNUIsZ0NBQXNCO0FBQUEsUUFDeEI7QUFFQSxlQUFPO0FBQUEsTUFDVCxLQUNBO0FBRUosWUFBTSxvQkFBb0IsQ0FBQyxZQUFpRDtBQUMxRSxZQUFJLENBQUMsd0JBQXdCO0FBQzNCLGlCQUFPRCxRQUFPO0FBQUEsUUFDaEI7QUFFQSxlQUFPQSxRQUFPLElBQUksYUFBYTtBQUM3QixnQkFBTSxNQUFNLEtBQUssSUFBSTtBQUVyQixnQkFBTSxXQUFXLE9BQU9DLEtBQUksT0FBTyx3QkFBd0IsQ0FBQyxNQUFNO0FBQ2hFLGtCQUFNLGdCQUFnQixNQUFNLEVBQUUsbUJBQW1CO0FBQ2pELGtCQUFNLGtCQUFrQixnQkFBZ0IsTUFBTSxFQUFFO0FBQ2hELGtCQUFNLG1CQUFtQixnQkFBZ0IsSUFBSSxFQUFFLG1CQUFtQjtBQUVsRSxrQkFBTSxpQkFBaUIsTUFBTSxFQUFFLGtCQUFrQjtBQUNqRCxrQkFBTSxjQUFjLG9CQUFvQjtBQUN4QyxrQkFBTSxVQUFVLHVCQUF1Qix5QkFBeUIsa0JBQWtCO0FBQ2xGLGtCQUFNLGFBQWEsQ0FBQyxtQkFBbUIsZUFBZTtBQUV0RCxrQkFBTSxPQUFPLGFBQ1Q7QUFBQSxjQUNFLGlCQUFpQjtBQUFBLGNBQ2pCLGtCQUFrQjtBQUFBLGNBQ2xCLGlCQUFpQjtBQUFBLFlBQ25CLElBQ0E7QUFBQSxjQUNFLEdBQUc7QUFBQSxjQUNIO0FBQUEsY0FDQTtBQUFBLFlBQ0Y7QUFFSixtQkFBTztBQUFBLGNBQ0w7QUFBQSxnQkFDRTtBQUFBLGdCQUNBO0FBQUEsZ0JBQ0E7QUFBQSxnQkFDQTtBQUFBLGNBQ0Y7QUFBQSxjQUNBO0FBQUEsWUFDRjtBQUFBLFVBQ0YsQ0FBQztBQUVELGNBQUksQ0FBQyxTQUFTLFlBQVk7QUFDeEI7QUFBQSxVQUNGO0FBRUEsZ0JBQU0sT0FBTyxTQUFTLGNBQ2xCLHFDQUNBO0FBRUosZ0JBQU0sT0FBTztBQUFBLFlBQ1gsWUFBWSxLQUFLLFFBQVE7QUFBQSxZQUN6QixRQUFRLEtBQUssSUFBSTtBQUFBLFlBQ2pCLFlBQVksZUFBZTtBQUFBLFlBQzNCLG9CQUFvQixTQUFTLGdCQUFnQjtBQUFBLFlBQzdDLGFBQWEsdUJBQXVCO0FBQUEsWUFDcEMsY0FBYyxpQkFBaUI7QUFBQSxZQUMvQjtBQUFBLFlBQ0E7QUFBQSxZQUNBLFNBQVMsYUFBYTtBQUFBLFlBQ3RCLFdBQVcsZUFBZTtBQUFBLFlBQzFCLGlCQUFpQixxQkFBcUIsT0FBTyxtQkFBbUI7QUFBQSxZQUNoRSxlQUFlLG9CQUFvQixRQUFRLENBQUMsQ0FBQztBQUFBLFlBQzdDO0FBQUEsWUFDQTtBQUFBLFlBQ0E7QUFBQSxZQUNBO0FBQUEsVUFDRixFQUFFLEtBQUssSUFBSTtBQUVYLDRCQUFrQjtBQUNsQixnQ0FBc0I7QUFDdEIsZ0NBQXNCO0FBRXRCLGlCQUFPLEtBQUs7QUFBQSxZQUNWLE1BQU07QUFBQSxZQUNOO0FBQUEsWUFDQTtBQUFBLFlBQ0EsVUFBVTtBQUFBLFlBQ1YsVUFBVSxjQUFjO0FBQUEsWUFDeEIsYUFBYSxLQUFLLElBQUk7QUFBQSxZQUN0QixPQUFPO0FBQUEsY0FDTCxTQUFTO0FBQUEsY0FDVDtBQUFBLGNBQ0E7QUFBQSxZQUNGO0FBQUEsVUFDRixDQUF3QjtBQUFBLFFBQzFCLENBQUM7QUFBQSxNQUNIO0FBRUEsWUFBTSxhQUFjLFFBQVEsZ0JBQWdCLFFBQVEsRUFBeUI7QUFBQSxRQUMzRUcsUUFBTztBQUFBLFVBQVUsQ0FBQyxRQUNoQkgsS0FBSSxJQUFJLE9BQU8sRUFBRTtBQUFBLFlBQ2ZELFFBQU8sUUFBUSxDQUFDLFNBQVM7QUFDdkIsa0JBQUlFLFFBQU8sT0FBTyxJQUFJLEtBQUssT0FBTyxHQUFHLEtBQUssT0FBTyxJQUFJLEtBQUssR0FBRztBQUMzRCx1QkFBT0YsUUFBTyxRQUFRRSxRQUFPLEtBQUssQ0FBQztBQUFBLGNBQ3JDO0FBQ0EscUJBQU9ELEtBQUksSUFBSSxTQUFTQyxRQUFPLEtBQUssSUFBSSxLQUFLLENBQUMsRUFBRTtBQUFBLGdCQUM5Q0YsUUFBTyxHQUFHRSxRQUFPLEtBQUssR0FBRyxDQUFDO0FBQUEsY0FDNUI7QUFBQSxZQUNGLENBQUM7QUFBQSxVQUNIO0FBQUEsUUFDRjtBQUFBLFFBQ0FFLFFBQU8sVUFBVSxDQUFDLFFBQVEsR0FBRztBQUFBLFFBQzdCQSxRQUFPLElBQUksQ0FBQyxRQUFhO0FBQ3ZCLGdCQUFNLFNBQVMsS0FBSyxNQUFNO0FBQzFCLGlCQUFPO0FBQUEsWUFDTCxNQUFNO0FBQUEsWUFDTixNQUFNLEtBQUs7QUFBQSxZQUNYLFVBQVUsS0FBSztBQUFBLFlBQ2YsWUFBWSxRQUFRO0FBQUEsWUFDcEIsTUFBTSxLQUFLO0FBQUEsWUFDWCxRQUFRLE9BQU8sV0FBVyxXQUFXLFNBQVM7QUFBQSxVQUNoRDtBQUFBLFFBQ0YsQ0FBQztBQUFBLE1BQ0g7QUFFQSxhQUFPLDRCQUE0QixXQUFXLEtBQUtBLFFBQU8sSUFBSSxpQkFBaUIsQ0FBQyxJQUFJO0FBQUEsSUFDdEYsQ0FBQztBQUVILFVBQU0sVUFBVSxDQUNkLFNBQ0EsVUFFQUosUUFBTyxRQUFRLHVCQUF1QixPQUFPO0FBQUEsTUFDM0NBLFFBQU8sUUFBUSxhQUFhLFNBQVMsVUFBVSxFQUFFO0FBQUEsUUFDL0NBLFFBQU8sY0FBYyxDQUFDLFVBQVU7QUFDOUIsY0FBSSxNQUFNLGtCQUFrQixLQUFLLEdBQUc7QUFDbEMsbUJBQU9BLFFBQU87QUFBQSxVQUNoQjtBQUNBLGlCQUFPLFNBQVMsUUFBUSxPQUFPLEtBQUssRUFBRSxLQUFLQSxRQUFPLFFBQVFBLFFBQU8sU0FBUyxNQUFNQSxRQUFPLElBQUksQ0FBQztBQUFBLFFBQzlGLENBQUM7QUFBQSxNQUNIO0FBQUEsSUFDRjtBQUVGLFVBQU0sZUFBZSxDQUNuQixTQUNBLFVBQ3dCO0FBQ3hCLFVBQUksQ0FBQyx5QkFBeUI7QUFDNUIsZUFBTyxRQUFRLFNBQVMsS0FBSztBQUFBLE1BQy9CO0FBRUEsYUFBT0EsUUFBTyxJQUFJLGFBQWE7QUFDN0IsY0FBTSxZQUFZLE9BQU9DLEtBQUksS0FBbUIsK0JBQStCLENBQUM7QUFDaEYsZUFBTyxPQUFPRCxRQUFPLFFBQVEsMkJBQTJCLFNBQVM7QUFBQSxVQUMvRCxpQkFBaUIsU0FBUyxNQUFNLEVBQUU7QUFBQSxZQUNoQ0EsUUFBTyxTQUFTLFFBQVEsU0FBUyxLQUFLLENBQUM7QUFBQSxVQUN6QztBQUFBLFFBQ0Y7QUFBQSxNQUNGLENBQUM7QUFBQSxJQUNIO0FBRUEsVUFBTSxtQkFBbUIsQ0FBQyxhQUE2QztBQUFBLE1BQ3JFLEdBQUc7QUFBQSxNQUNILFlBQVksY0FBYztBQUFBLElBQzVCO0FBRUEsVUFBTSxtQkFBbUIsQ0FDdkIsU0FDQSxhQUN3QjtBQUN4QixVQUFJLENBQUMseUJBQXlCO0FBQzVCLGVBQU9BLFFBQU87QUFBQSxNQUNoQjtBQUVBLFlBQU0sTUFBb0I7QUFBQSxRQUN4QixNQUFNO0FBQUEsUUFDTjtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQSxVQUFVLGNBQWM7QUFBQSxRQUN4QixhQUFhLEtBQUssSUFBSTtBQUFBLE1BQ3hCO0FBQ0EsYUFBTyxLQUFLLEdBQUc7QUFBQSxJQUNqQjtBQUVBLFVBQU0sU0FBUyxhQUFhLFdBQVc7QUFDdkMsVUFBTSxZQUFZLGFBQWEsV0FBVyxTQUFTO0FBQUEsTUFDakQsQ0FBQyxNQUFNLEVBQUUsU0FBUyxtQkFBbUIsRUFBRSxrQkFBa0I7QUFBQSxJQUMzRDtBQUNBLFVBQU0sa0JBQWtCLGFBQWEsV0FBVyxTQUFTO0FBQUEsTUFDdkQsQ0FBQyxNQUNDLEVBQUUsU0FBUyxtQkFBbUIsRUFBRSxrQkFBa0I7QUFBQSxJQUN0RDtBQUVBLFVBQU0sa0JBQWtCQSxRQUFPLElBQUksYUFBYTtBQUM5QyxZQUFNLFFBQVEsT0FBTyxTQUFTLEtBQXVCO0FBRXJELFlBQU0sc0JBQXFESSxRQUFPO0FBQUEsUUFDaEUsY0FBYztBQUFBLE1BQ2hCO0FBRUEsWUFBTSxVQUFVLE9BQU9KLFFBQU87QUFBQSxRQUM1QixhQUFhLFdBQVcsU0FBUyxPQUFPLENBQUMsTUFBTSxFQUFFLFNBQVMsZUFBZTtBQUFBLFFBQ3pFO0FBQUEsTUFDRjtBQUVBLFlBQU0sZ0JBQWdCSSxRQUFPLFNBQVMsQ0FBQyxxQkFBcUIsR0FBRyxPQUFPLEdBQUc7QUFBQSxRQUN2RSxhQUFhO0FBQUEsTUFDZixDQUFDO0FBRUQsWUFBTSxzQkFBc0IsQ0FDMUIsU0FDd0I7QUFDeEIsY0FBTSxNQUFNLElBQUksTUFBTSx5REFBeUQ7QUFDOUUsUUFBQyxJQUFZLE9BQU87QUFDcEIsUUFBQyxJQUFZLE9BQU87QUFBQSxVQUNuQixRQUFRLEtBQUssSUFBSTtBQUFBLFVBQ2pCLGtCQUFrQixLQUFLLGFBQWEsU0FBUyxLQUFLLElBQUk7QUFBQSxVQUN0RCx3QkFBd0IsS0FBSyxNQUFNLFVBQVUsVUFBVSxLQUFLLE1BQU0sS0FBSztBQUFBLFVBQ3ZFLFdBQVcsS0FBSyxVQUFVLEtBQUssTUFBTSxDQUFDO0FBQUEsVUFDdEM7QUFBQSxVQUNBO0FBQUEsVUFDQTtBQUFBLFFBQ0YsRUFBRSxLQUFLLElBQUk7QUFDWCxlQUFPLFNBQVMsUUFBUSxPQUFPLE1BQU0sS0FBSyxHQUFHLENBQUMsRUFBRSxLQUFLSixRQUFPLFFBQVFBLFFBQU8sU0FBUyxNQUFNQSxRQUFPLElBQUksQ0FBQztBQUFBLE1BQ3hHO0FBRUEsWUFBTSxjQUFjLE9BQU9BLFFBQU87QUFBQSxRQUNiLHdCQUF3QjtBQUFBLFVBQ3pDLFFBQVE7QUFBQSxVQUNSO0FBQUEsVUFDQTtBQUFBLFVBQ0EsS0FBSyxDQUFDLFlBQVksYUFBYSxTQUFTLEtBQUs7QUFBQSxVQUM3QyxRQUFRLENBQUMsWUFBWSxpQkFBaUIsU0FBUyxTQUFTO0FBQUEsVUFDeEQsaUJBQWlCO0FBQUEsUUFDbkIsQ0FBQztBQUFBLE1BQ0g7QUFFQSxVQUFJLFdBQVc7QUFDYixlQUFPLE1BQU0sTUFBTSxjQUFjLHVCQUF1QjtBQUFBLFVBQ3RELE1BQU07QUFBQSxVQUNOLE1BQU0saUJBQWlCO0FBQUEsVUFDdkIsZUFBZTtBQUFBLFFBQ2pCLENBQUM7QUFBQSxNQUNIO0FBRUEsWUFBTSxRQUFRLE9BQU8sU0FBUyxNQUFNLEtBQUs7QUFDekMsYUFBT0csT0FBTSxVQUFVLFdBQVc7QUFDbEMsYUFBTyxPQUFPSCxRQUFPLFVBQVUsS0FBSztBQUFBLElBQ3RDLENBQUM7QUFFRCxVQUFNLFFBQVEsT0FBT0EsUUFBTyxPQUFPLGFBQWEsU0FBUztBQUFBLE1BQ3ZEQSxRQUFPLE9BQU8sZUFBZSxFQUFFO0FBQUEsUUFDN0JBLFFBQU87QUFBQSxVQUFjLENBQUMsVUFDcEJBLFFBQU8sSUFBSSxhQUFhO0FBR3RCLGdCQUFJLE1BQU0sa0JBQWtCLEtBQUssR0FBRztBQUVsQyxrQkFBSSxjQUFjLE9BQU8sV0FBVyxZQUFZO0FBQzlDO0FBQUEsY0FDRjtBQUdBLDRCQUFjLFNBQVM7QUFBQSxnQkFDckIsR0FBRyxjQUFjO0FBQUEsZ0JBQ2pCLFFBQVE7QUFBQSxnQkFDUixlQUFlO0FBQUEsY0FDakI7QUFDQSw0QkFBYyxRQUFRO0FBRXRCLHFCQUFPLEtBQUs7QUFBQSxnQkFDVixNQUFNO0FBQUEsZ0JBQ047QUFBQSxnQkFDQSxVQUFVO0FBQUEsZ0JBQ1YsVUFBVSxjQUFjO0FBQUEsZ0JBQ3hCLGFBQWEsS0FBSyxJQUFJO0FBQUEsY0FDeEIsQ0FBQztBQUNEO0FBQUEsWUFDRjtBQUVBLGtCQUFNLFVBQVVFLFFBQU87QUFBQSxjQUFVLE1BQU0sY0FBYyxLQUFLO0FBQUEsY0FBRyxNQUMzREEsUUFBTyxVQUFVLE1BQU0sVUFBVSxLQUFLLEdBQUcsTUFBTSxLQUFLO0FBQUEsWUFDdEQ7QUFDQSxrQkFBTSxVQUFVLDJCQUEyQixPQUFPO0FBQ2xELGtCQUFNLFFBQWtDLFFBQVE7QUFFaEQsMEJBQWMsU0FBUztBQUFBLGNBQ3JCLEdBQUcsY0FBYztBQUFBLGNBQ2pCLFFBQVE7QUFBQSxjQUNSLGVBQWU7QUFBQSxjQUNmLFdBQVc7QUFBQSxZQUNiO0FBRUEsbUJBQU8sS0FBSztBQUFBLGNBQ1YsTUFBTTtBQUFBLGNBQ047QUFBQSxjQUNBLFVBQVU7QUFBQSxjQUNWLFVBQVUsY0FBYztBQUFBLGNBQ3hCLGFBQWEsS0FBSyxJQUFJO0FBQUEsY0FDdEI7QUFBQSxZQUNGLENBQUM7QUFFRCxrQkFBTSxXQUF1QjtBQUFBLGNBQzNCLGFBQWEsV0FBVztBQUFBLGNBQ3hCLGFBQWE7QUFBQSxjQUNiLEtBQUssSUFBSTtBQUFBLFlBQ1g7QUFDQSx5QkFBYSxjQUFjLFNBQVM7QUFFcEMsZ0JBQUksU0FBUyxhQUFhLFdBQVc7QUFFbkMscUJBQU8sS0FBSztBQUFBLGdCQUNWLE1BQU07QUFBQSxnQkFDTjtBQUFBLGdCQUNBLFVBQVU7QUFBQSxnQkFDVixVQUFVLGNBQWM7QUFBQSxnQkFDeEIsYUFBYSxLQUFLLElBQUk7QUFBQSxnQkFDdEI7QUFBQSxjQUNGLENBQUM7QUFDRCxxQkFBTyxrQkFBa0IsZUFBZTtBQUFBLFlBQzFDLE9BQU87QUFDTCxxQkFBTztBQUFBLGdCQUNMLGFBQWEsU0FBUztBQUFBLGdCQUN0QixhQUFhLFNBQVM7QUFBQSxnQkFDdEI7QUFBQSxnQkFDQTtBQUFBLGdCQUNBLGFBQWEsYUFBYSxTQUFTLFNBQVMsYUFBYSxhQUFhLFFBQVEsYUFBYSxTQUFTLG9CQUFvQixnQkFBZ0IsU0FBUyxXQUFXO0FBQUEsY0FDOUo7QUFBQSxZQUNGO0FBQUEsVUFDRixDQUFDO0FBQUEsUUFDSDtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBRUEsa0JBQWMsUUFBUTtBQUN0QixrQkFBYyxTQUFTO0FBQUEsTUFDckIsR0FBRyxjQUFjO0FBQUEsTUFDakIsUUFBUTtBQUFBLElBQ1Y7QUFJQSxXQUFPRixRQUFPLFNBQVM7QUFBQSxFQUN6QixDQUFDO0FBRUgsUUFBTSxVQUFVLENBQ2QsU0FDQVMsYUFNQVQsUUFBTyxJQUFJLGFBQWE7QUFDdEIsVUFBTSxPQUFZLFFBQVEsT0FBTztBQUNqQyxRQUFJLENBQUMsTUFBTTtBQUNULGFBQU87QUFBQSxJQUNUO0FBRUEsVUFBTSxNQUFNLE9BQU9BLFFBQU8sUUFBVztBQUNyQyxVQUFNLGVBQWVGLFNBQVEsVUFBVSxLQUE2QlksT0FBTSxLQUFLO0FBQy9FLFVBQU0sWUFBWVIsUUFBTyxPQUFPLFlBQVksSUFBSSxhQUFhLFFBQVE7QUFFckUsVUFBTSxXQUFvQixrQkFBa0JPLFNBQVEsS0FBSztBQUN6RCxVQUFNLFdBQVc7QUFBQSxNQUNmLFdBQVcsS0FBSyxXQUFXO0FBQUEsTUFDM0IsT0FBT0EsU0FBUTtBQUFBLElBQ2pCO0FBRUEsVUFBTSxrQkFBMkIsNEJBQTRCLFFBQVE7QUFDckUsVUFBTSxXQUFXLGNBQWMsSUFBSSxlQUFlO0FBQ2xELFFBQUksVUFBVTtBQUNaLGVBQVMsVUFBVUEsU0FBUSxXQUFXO0FBQ3RDLGVBQVMsY0FBY0EsU0FBUSxlQUFlLFNBQVM7QUFDdkQsVUFBSSxTQUFTLFdBQVcsQ0FBQyxTQUFTLG1CQUFtQjtBQUNuRCxlQUFPLGtCQUFrQixlQUFlO0FBQUEsTUFDMUM7QUFDQSxhQUFPO0FBQUEsUUFDTDtBQUFBLFFBQ0EsU0FBUyxTQUFTO0FBQUEsUUFDbEIsYUFBYSxTQUFTO0FBQUEsTUFDeEI7QUFBQSxJQUNGO0FBSUEsVUFBTSxVQUFVVCxRQUFPLFFBQVEsTUFBTSxPQUFPO0FBQzVDLElBQUssV0FBVyxTQUFTO0FBQUEsTUFDdkIsR0FBRztBQUFBLE1BQ0gsbUJBQW1CUyxTQUFRO0FBQUEsSUFDN0IsQ0FBQztBQUVELFVBQU0sZUFBa0M7QUFBQSxNQUN0QztBQUFBLE1BQ0E7QUFBQSxNQUNBLFlBQVksS0FBSztBQUFBLE1BQ2pCO0FBQUEsTUFDQTtBQUFBLE1BQ0EsU0FBUztBQUFBLE1BQ1QsTUFBTSxLQUFLLFFBQVE7QUFBQSxNQUNuQixTQUFTQSxTQUFRLFdBQVc7QUFBQSxNQUM1QixhQUFhQSxTQUFRO0FBQUEsTUFDckIsWUFBWTtBQUFBLE1BQ1osYUFBeUIsYUFBYTtBQUFBLElBQ3hDO0FBRUEsa0JBQWMsSUFBSSxpQkFBaUIsWUFBWTtBQUUvQyxRQUFJLGFBQWEsU0FBUztBQUN4QixhQUFPLGtCQUFrQixlQUFlO0FBQUEsSUFDMUM7QUFFQSxXQUFPO0FBQUEsTUFDTDtBQUFBLE1BQ0EsU0FBUyxhQUFhO0FBQUEsTUFDdEIsYUFBYSxhQUFhO0FBQUEsSUFDNUI7QUFBQSxFQUNGLENBQUM7QUFFSCxRQUFNLG9CQUF5RCxDQUFDLFdBQzlEVCxRQUFPLEtBQUssTUFBTTtBQUNoQixVQUFNLFlBQVksUUFBUTtBQUMxQixVQUFNLFdBQVcsUUFBUTtBQUN6QixVQUFNLE1BQTZCLENBQUM7QUFDcEMsZUFBVyxnQkFBZ0IsY0FBYyxPQUFPLEdBQUc7QUFDakQsVUFBSSxhQUFhLGFBQWEsU0FBUyxNQUFNLFNBQVMsVUFBVztBQUNqRSxVQUFJLFlBQVksYUFBYSxhQUFhLFNBQVU7QUFDcEQsVUFBSSxLQUFLO0FBQUEsUUFDUCxVQUFVLGFBQWE7QUFBQSxRQUN2QixTQUFTLGFBQWE7QUFBQSxRQUN0QixhQUFhLGFBQWE7QUFBQSxNQUM1QixDQUFDO0FBQUEsSUFDSDtBQUNBLFdBQU87QUFBQSxFQUNULENBQUM7QUFFSCxRQUFNLG9CQUF5RCxDQUFDLHNCQUM5REEsUUFBTyxLQUFLLE1BQU0sVUFBVSxJQUFJLGlCQUFpQixHQUFHLE1BQU07QUFFNUQsUUFBTSxrQkFBcUQsQ0FBQyxtQkFBbUIsWUFDN0VBLFFBQU8sUUFBUSxNQUFNO0FBQ25CLFVBQU0sV0FBVyxVQUFVLElBQUksaUJBQWlCO0FBQ2hELFFBQUksQ0FBQyxVQUFVO0FBQ2IsYUFBT0EsUUFBTztBQUFBLElBQ2hCO0FBRUEsV0FBTyx1QkFBdUIsU0FBUyxPQUFPLGdDQUFnQyxFQUFFO0FBQUEsTUFDOUVBLFFBQU8sUUFBUSxDQUFDLFNBQVM7QUFDdkIsWUFBSSxNQUFNO0FBQ1IsaUJBQU9BLFFBQU87QUFBQSxRQUNoQjtBQUVBLFlBQUksUUFBUSxXQUFXLFFBQVE7QUFDN0IsaUJBQU8sYUFBYSxVQUFVLFlBQVk7QUFBQSxRQUM1QztBQUVBLFlBQUksUUFBUSxXQUFXLFdBQVc7QUFDaEMsaUJBQU8sYUFBYSxVQUFVLFlBQVksRUFBRTtBQUFBLFlBQzFDQSxRQUFPLFFBQVEsTUFBTTtBQUNuQixvQkFBTSxlQUFlLGNBQWMsSUFBSSxTQUFTLGVBQWU7QUFDL0Qsa0JBQUksQ0FBQyxjQUFjO0FBQ2pCLHVCQUFPQSxRQUFPO0FBQUEsY0FDaEI7QUFDQSwyQkFBYSxvQkFBb0I7QUFDakMscUJBQU8sa0JBQWtCLFNBQVMsZUFBZTtBQUFBLFlBQ25ELENBQUM7QUFBQSxVQUNIO0FBQUEsUUFDRjtBQUdBLFlBQUksUUFBUSxXQUFXLFNBQVM7QUFDOUIsY0FBSSxTQUFTLE9BQU8sV0FBVyxhQUFhLFNBQVMsT0FBTyxXQUFXLFlBQVk7QUFDakYsbUJBQU9BLFFBQU87QUFBQSxVQUNoQjtBQUVBLGdCQUFNLGVBQWUsY0FBYyxJQUFJLFNBQVMsZUFBZTtBQUMvRCxjQUFJLENBQUMsY0FBYztBQUNqQixtQkFBT0EsUUFBTztBQUFBLFVBQ2hCO0FBQ0EsdUJBQWEsb0JBQW9CO0FBQ2pDLGlCQUFPLGtCQUFrQixTQUFTLGVBQWU7QUFBQSxRQUNuRDtBQUVBLGVBQU9BLFFBQU87QUFBQSxNQUNoQixDQUFDO0FBQUEsSUFDSDtBQUFBLEVBQ0YsQ0FBQztBQUVILFFBQU0sdUJBQStELENBQUMsVUFDcEVBLFFBQU8sSUFBSSxhQUFhO0FBQ3RCLFVBQU0sT0FBTyxPQUFrQixpQ0FBaUM7QUFBQSxNQUM5RCxNQUFNO0FBQUEsTUFDTixVQUFVO0FBQUEsTUFDVixTQUNFO0FBQUEsTUFDRixNQUFNO0FBQUEsTUFDTixNQUFNO0FBQUEsSUFDUixDQUFDO0FBQ0QsUUFBSSxLQUFNO0FBRVYsVUFBTSxVQUFVLE1BQU0sS0FBSyxVQUFVLE9BQU8sQ0FBQztBQUM3QyxVQUFNLFlBQVksTUFBTTtBQUV4QixXQUFPQSxRQUFPO0FBQUEsTUFDWjtBQUFBLE1BQ0EsQ0FBQyxhQUNDQSxRQUFPLFFBQVEsTUFBTTtBQUNuQixZQUFJLFNBQVMsT0FBTyxXQUFXLGNBQWMsU0FBUyxPQUFPLFdBQVcsV0FBVztBQUNqRixpQkFBT0EsUUFBTztBQUFBLFFBQ2hCO0FBRUEsY0FBTSxlQUFlLGNBQWMsSUFBSSxTQUFTLGVBQWU7QUFDL0QsWUFBSSxDQUFDLGNBQWM7QUFDakIsaUJBQU9BLFFBQU87QUFBQSxRQUNoQjtBQUVBLGNBQU0sUUFBUSxhQUFhLFdBQVcsU0FBUztBQUFBLFVBQzdDLENBQUMsTUFDQyxFQUFFLFNBQVMsbUJBQW1CLEVBQUUsa0JBQWtCO0FBQUEsUUFDdEQ7QUFDQSxZQUFJLE1BQU0sV0FBVyxHQUFHO0FBQ3RCLGlCQUFPQSxRQUFPO0FBQUEsUUFDaEI7QUFFQSxlQUFPQSxRQUFPO0FBQUEsVUFDWjtBQUFBLFVBQ0EsQ0FBQyxTQUNDLE1BQU0sTUFBTSxTQUFTLHVCQUF1QjtBQUFBLFlBQzFDLE1BQU07QUFBQSxZQUNOLE1BQU0sS0FBSztBQUFBLFlBQ1gsZUFBZSxLQUFLO0FBQUEsVUFDdEIsQ0FBMEI7QUFBQSxVQUM1QixFQUFFLFNBQVMsS0FBSztBQUFBLFFBQ2xCO0FBQUEsTUFDRixDQUFDO0FBQUEsTUFDSCxFQUFFLFNBQVMsS0FBSztBQUFBLElBQ2xCO0FBQUEsRUFDRixDQUFDO0FBRUgsUUFBTSxlQUF5Q0ksUUFBTyxXQUFXLFNBQVM7QUFFMUUsUUFBTSxvQkFBeUQsTUFDN0RKLFFBQU8sS0FBSyxNQUFNLGFBQWEsTUFBTSxDQUFDO0FBRXhDLFNBQU9BLFFBQU87QUFBQSxJQUFhLE1BQ3pCQSxRQUFPLElBQUksYUFBYTtBQUN0QixpQkFBVyxZQUFZLFVBQVUsT0FBTyxHQUFHO0FBQ3pDLFlBQUksU0FBUyxPQUFPO0FBQ2xCLGlCQUFPLGFBQWEsVUFBVSxlQUFlO0FBQUEsUUFDL0M7QUFBQSxNQUNGO0FBQUEsSUFDRixDQUFDLEVBQUU7QUFBQSxNQUNEQSxRQUFPO0FBQUEsUUFBYyxDQUFDLFVBQ3BCQSxRQUFPLEtBQUssTUFBTTtBQUVoQixjQUFJLFNBQVMsR0FBRztBQUVkLG9CQUFRLEtBQUsscUNBQXFDLE1BQU0sT0FBTyxLQUFLLENBQUM7QUFBQSxVQUN2RTtBQUFBLFFBQ0YsQ0FBQztBQUFBLE1BQ0g7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUVBLFNBQU87QUFBQSxJQUNMO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0EsUUFBUTtBQUFBLElBQ1I7QUFBQSxFQUNGO0FBQ0YsQ0FBQztBQUVJLElBQU0sUUFBUSxDQUFDLFlBRThCVyxPQUFNLE9BQU8sbUJBQW1CLEtBQUssT0FBTyxDQUFDOyIsCiAgIm5hbWVzIjogWyJkZWZpbmVIaWRkZW4iLCAiQ29udGV4dCIsICJFZmZlY3QiLCAiQ29udGV4dCIsICJFZmZlY3QiLCAic2V0UnVudGltZVNlcnZpY2VzRXZpZGVuY2UiLCAiQ29udGV4dCIsICJFZmZlY3QiLCAiRmliZXIiLCAiRmliZXJSZWYiLCAiTGF5ZXIiLCAiT3B0aW9uIiwgIlJlZiIsICJTY29wZSIsICJTdHJlYW0iLCAiRWZmZWN0IiwgIk9wdGlvbiIsICJFZmZlY3QiLCAiT3B0aW9uIiwgIm5leHRTaXplIiwgIkNvbnRleHQiLCAiRmliZXJSZWYiLCAiRWZmZWN0IiwgIlJlZiIsICJPcHRpb24iLCAiRmliZXIiLCAiU3RyZWFtIiwgInRhZyIsICJmb3VuZCIsICJydW50aW1lIiwgInN0cmVhbSIsICJvcHRpb25zIiwgIlNjb3BlIiwgIkxheWVyIl0KfQo=