@bitgo/sdk-coin-dot 4.11.7 → 4.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (317) hide show
  1. package/dist/{src → cjs/src}/dot.d.ts +0 -7
  2. package/dist/cjs/src/dot.d.ts.map +1 -0
  3. package/dist/cjs/src/dot.js +623 -0
  4. package/dist/cjs/src/index.d.ts.map +1 -0
  5. package/dist/{src → cjs/src}/index.js +1 -1
  6. package/dist/cjs/src/lib/addressInitializationBuilder.d.ts.map +1 -0
  7. package/dist/cjs/src/lib/addressInitializationBuilder.js +182 -0
  8. package/dist/cjs/src/lib/batchTransactionBuilder.d.ts.map +1 -0
  9. package/dist/cjs/src/lib/batchTransactionBuilder.js +229 -0
  10. package/dist/cjs/src/lib/claimBuilder.d.ts.map +1 -0
  11. package/dist/cjs/src/lib/claimBuilder.js +117 -0
  12. package/dist/cjs/src/lib/errors.d.ts.map +1 -0
  13. package/dist/cjs/src/lib/errors.js +19 -0
  14. package/dist/cjs/src/lib/iface.d.ts.map +1 -0
  15. package/dist/cjs/src/lib/iface.js +128 -0
  16. package/dist/cjs/src/lib/iface_utils.d.ts.map +1 -0
  17. package/dist/cjs/src/lib/iface_utils.js +92 -0
  18. package/dist/{src → cjs/src}/lib/index.d.ts +2 -0
  19. package/dist/cjs/src/lib/index.d.ts.map +1 -0
  20. package/dist/{src → cjs/src}/lib/index.js +4 -2
  21. package/dist/cjs/src/lib/keyPair.d.ts.map +1 -0
  22. package/dist/cjs/src/lib/keyPair.js +117 -0
  23. package/dist/cjs/src/lib/nativeTransferBuilder.d.ts.map +1 -0
  24. package/dist/cjs/src/lib/nativeTransferBuilder.js +219 -0
  25. package/dist/cjs/src/lib/proxyBuilder.d.ts.map +1 -0
  26. package/dist/cjs/src/lib/proxyBuilder.js +116 -0
  27. package/dist/cjs/src/lib/singletonRegistry.d.ts.map +1 -0
  28. package/dist/cjs/src/lib/singletonRegistry.js +20 -0
  29. package/dist/cjs/src/lib/stakingBuilder.d.ts.map +1 -0
  30. package/dist/cjs/src/lib/stakingBuilder.js +167 -0
  31. package/dist/cjs/src/lib/transaction.d.ts.map +1 -0
  32. package/dist/cjs/src/lib/transaction.js +624 -0
  33. package/dist/cjs/src/lib/transactionBuilder.d.ts.map +1 -0
  34. package/dist/cjs/src/lib/transactionBuilder.js +351 -0
  35. package/dist/cjs/src/lib/transactionBuilderFactory.d.ts.map +1 -0
  36. package/dist/cjs/src/lib/transactionBuilderFactory.js +104 -0
  37. package/dist/cjs/src/lib/transferBuilder.d.ts.map +1 -0
  38. package/dist/cjs/src/lib/transferBuilder.js +11 -0
  39. package/dist/cjs/src/lib/txnSchema.d.ts.map +1 -0
  40. package/dist/cjs/src/lib/txnSchema.js +117 -0
  41. package/dist/cjs/src/lib/unnominateBuilder.d.ts.map +1 -0
  42. package/dist/cjs/src/lib/unnominateBuilder.js +48 -0
  43. package/dist/cjs/src/lib/unstakeBuilder.d.ts.map +1 -0
  44. package/dist/cjs/src/lib/unstakeBuilder.js +87 -0
  45. package/dist/cjs/src/lib/utils.d.ts.map +1 -0
  46. package/dist/cjs/src/lib/utils.js +491 -0
  47. package/dist/cjs/src/lib/wasmParser.d.ts +57 -0
  48. package/dist/cjs/src/lib/wasmParser.d.ts.map +1 -0
  49. package/dist/cjs/src/lib/wasmParser.js +345 -0
  50. package/dist/cjs/src/lib/withdrawUnstakedBuilder.d.ts.map +1 -0
  51. package/dist/cjs/src/lib/withdrawUnstakedBuilder.js +88 -0
  52. package/dist/cjs/src/register.d.ts.map +1 -0
  53. package/dist/cjs/src/register.js +11 -0
  54. package/dist/cjs/src/resources/index.d.ts.map +1 -0
  55. package/dist/{src → cjs/src}/resources/index.js +1 -1
  56. package/dist/cjs/src/resources/mainnet.d.ts.map +1 -0
  57. package/dist/cjs/src/resources/mainnet.js +5 -0
  58. package/dist/cjs/src/resources/polkadotAssetHub.d.ts.map +1 -0
  59. package/dist/cjs/src/resources/polkadotAssetHub.js +5 -0
  60. package/dist/cjs/src/resources/westend.d.ts.map +1 -0
  61. package/dist/{test/resources/testnet.js → cjs/src/resources/westend.js} +3 -3
  62. package/dist/cjs/src/resources/westendAssetHub.d.ts.map +1 -0
  63. package/dist/{src → cjs/src}/resources/westendAssetHub.js +1 -1
  64. package/dist/cjs/src/tdot.d.ts.map +1 -0
  65. package/dist/cjs/src/tdot.js +27 -0
  66. package/dist/cjs/test/fixtures.d.ts.map +1 -0
  67. package/dist/cjs/test/fixtures.js +439 -0
  68. package/dist/cjs/test/resources/index.d.ts.map +1 -0
  69. package/dist/cjs/test/resources/index.js +157 -0
  70. package/dist/cjs/test/resources/testnet.d.ts.map +1 -0
  71. package/dist/{src/resources/westend.js → cjs/test/resources/testnet.js} +3 -3
  72. package/dist/{test → cjs/test}/unit/address.d.ts.map +1 -1
  73. package/dist/cjs/test/unit/address.js +45 -0
  74. package/dist/{test → cjs/test}/unit/dot.d.ts.map +1 -1
  75. package/dist/cjs/test/unit/dot.js +944 -0
  76. package/dist/{test → cjs/test}/unit/keypair.d.ts.map +1 -1
  77. package/dist/cjs/test/unit/keypair.js +111 -0
  78. package/dist/cjs/test/unit/transaction.d.ts.map +1 -0
  79. package/dist/cjs/test/unit/transaction.js +269 -0
  80. package/dist/cjs/test/unit/transactionBuilder/addressInitializationBuilder.d.ts.map +1 -0
  81. package/dist/cjs/test/unit/transactionBuilder/addressInitializationBuilder.js +265 -0
  82. package/dist/cjs/test/unit/transactionBuilder/base.d.ts.map +1 -0
  83. package/dist/cjs/test/unit/transactionBuilder/base.js +233 -0
  84. package/dist/cjs/test/unit/transactionBuilder/batchTransactionBuilder.d.ts.map +1 -0
  85. package/dist/cjs/test/unit/transactionBuilder/batchTransactionBuilder.js +521 -0
  86. package/dist/cjs/test/unit/transactionBuilder/claimBuilder.d.ts.map +1 -0
  87. package/dist/cjs/test/unit/transactionBuilder/claimBuilder.js +129 -0
  88. package/dist/cjs/test/unit/transactionBuilder/proxyBuilder.d.ts.map +1 -0
  89. package/dist/cjs/test/unit/transactionBuilder/proxyBuilder.js +88 -0
  90. package/dist/cjs/test/unit/transactionBuilder/singeltonRegistry.d.ts.map +1 -0
  91. package/dist/{test → cjs/test}/unit/transactionBuilder/singeltonRegistry.js +1 -1
  92. package/dist/cjs/test/unit/transactionBuilder/stakingBuilder.d.ts.map +1 -0
  93. package/dist/cjs/test/unit/transactionBuilder/stakingBuilder.js +235 -0
  94. package/dist/cjs/test/unit/transactionBuilder/transactionBuilderFactory.d.ts.map +1 -0
  95. package/dist/cjs/test/unit/transactionBuilder/transactionBuilderFactory.js +107 -0
  96. package/dist/cjs/test/unit/transactionBuilder/transferBuilder.d.ts.map +1 -0
  97. package/dist/cjs/test/unit/transactionBuilder/transferBuilder.js +437 -0
  98. package/dist/cjs/test/unit/transactionBuilder/unnominateBuilder.d.ts.map +1 -0
  99. package/dist/cjs/test/unit/transactionBuilder/unnominateBuilder.js +97 -0
  100. package/dist/cjs/test/unit/transactionBuilder/unstakeBuilder.d.ts.map +1 -0
  101. package/dist/cjs/test/unit/transactionBuilder/unstakeBuilder.js +116 -0
  102. package/dist/cjs/test/unit/transactionBuilder/withdrawUnstakedBuilder.d.ts.map +1 -0
  103. package/dist/cjs/test/unit/transactionBuilder/withdrawUnstakedBuilder.js +115 -0
  104. package/dist/{test → cjs/test}/unit/utils.d.ts.map +1 -1
  105. package/dist/cjs/test/unit/utils.js +117 -0
  106. package/dist/cjs/test/unit/wasmBuilderByteComparison.d.ts +22 -0
  107. package/dist/cjs/test/unit/wasmBuilderByteComparison.d.ts.map +1 -0
  108. package/dist/cjs/test/unit/wasmBuilderByteComparison.js +197 -0
  109. package/dist/cjs/test/unit/wasmParserExplanation.d.ts +15 -0
  110. package/dist/cjs/test/unit/wasmParserExplanation.d.ts.map +1 -0
  111. package/dist/cjs/test/unit/wasmParserExplanation.js +147 -0
  112. package/dist/cjs/tsconfig.tsbuildinfo +1 -0
  113. package/dist/esm/dot.d.ts +147 -0
  114. package/dist/esm/dot.d.ts.map +1 -0
  115. package/dist/esm/dot.js +583 -0
  116. package/dist/esm/index.d.ts +5 -0
  117. package/dist/esm/index.js +5 -0
  118. package/dist/esm/lib/addressInitializationBuilder.d.ts +79 -0
  119. package/dist/esm/lib/addressInitializationBuilder.js +175 -0
  120. package/dist/esm/lib/batchTransactionBuilder.d.ts +62 -0
  121. package/dist/esm/lib/batchTransactionBuilder.js +222 -0
  122. package/dist/esm/lib/claimBuilder.d.ts +58 -0
  123. package/dist/esm/lib/claimBuilder.js +110 -0
  124. package/dist/esm/lib/errors.d.ts +8 -0
  125. package/dist/esm/lib/errors.js +14 -0
  126. package/dist/esm/lib/iface.d.ts +337 -0
  127. package/dist/esm/lib/iface.js +125 -0
  128. package/dist/esm/lib/iface_utils.d.ts +59 -0
  129. package/dist/esm/lib/iface_utils.js +83 -0
  130. package/dist/esm/lib/index.d.ts +21 -0
  131. package/dist/{src → esm}/lib/index.d.ts.map +1 -1
  132. package/dist/esm/lib/index.js +20 -0
  133. package/dist/esm/lib/keyPair.d.ts +38 -0
  134. package/dist/esm/lib/keyPair.js +77 -0
  135. package/dist/esm/lib/nativeTransferBuilder.d.ts +84 -0
  136. package/dist/esm/lib/nativeTransferBuilder.js +212 -0
  137. package/dist/esm/lib/proxyBuilder.d.ts +54 -0
  138. package/dist/esm/lib/proxyBuilder.js +109 -0
  139. package/dist/esm/lib/singletonRegistry.d.ts +7 -0
  140. package/dist/esm/lib/singletonRegistry.js +16 -0
  141. package/dist/esm/lib/stakingBuilder.d.ts +66 -0
  142. package/dist/esm/lib/stakingBuilder.js +160 -0
  143. package/dist/esm/lib/transaction.d.ts +83 -0
  144. package/dist/{src → esm}/lib/transaction.d.ts.map +1 -1
  145. package/dist/esm/lib/transaction.js +584 -0
  146. package/dist/esm/lib/transactionBuilder.d.ts +131 -0
  147. package/dist/esm/lib/transactionBuilder.js +311 -0
  148. package/dist/esm/lib/transactionBuilderFactory.d.ts +28 -0
  149. package/dist/esm/lib/transactionBuilderFactory.js +97 -0
  150. package/dist/esm/lib/transferBuilder.d.ts +11 -0
  151. package/dist/esm/lib/transferBuilder.js +7 -0
  152. package/dist/esm/lib/txnSchema.d.ts +15 -0
  153. package/dist/esm/lib/txnSchema.js +111 -0
  154. package/dist/esm/lib/unnominateBuilder.d.ts +24 -0
  155. package/dist/esm/lib/unnominateBuilder.js +44 -0
  156. package/dist/esm/lib/unstakeBuilder.d.ts +38 -0
  157. package/dist/esm/lib/unstakeBuilder.js +80 -0
  158. package/dist/esm/lib/utils.d.ts +261 -0
  159. package/dist/esm/lib/utils.js +451 -0
  160. package/dist/esm/lib/wasmParser.d.ts +57 -0
  161. package/dist/esm/lib/wasmParser.d.ts.map +1 -0
  162. package/dist/esm/lib/wasmParser.js +341 -0
  163. package/dist/esm/lib/withdrawUnstakedBuilder.d.ts +38 -0
  164. package/dist/esm/lib/withdrawUnstakedBuilder.js +81 -0
  165. package/dist/esm/register.d.ts +3 -0
  166. package/dist/esm/register.js +7 -0
  167. package/dist/esm/resources/index.d.ts +5 -0
  168. package/dist/esm/resources/index.js +5 -0
  169. package/dist/esm/resources/mainnet.d.ts +2 -0
  170. package/dist/esm/resources/mainnet.js +2 -0
  171. package/dist/esm/resources/polkadotAssetHub.d.ts +2 -0
  172. package/dist/esm/resources/polkadotAssetHub.js +2 -0
  173. package/dist/esm/resources/westend.d.ts +2 -0
  174. package/dist/esm/resources/westend.js +2 -0
  175. package/dist/esm/resources/westendAssetHub.d.ts +2 -0
  176. package/dist/esm/resources/westendAssetHub.js +2 -0
  177. package/dist/esm/tdot.d.ts +12 -0
  178. package/dist/esm/tdot.js +23 -0
  179. package/package.json +30 -12
  180. package/dist/src/dot.d.ts.map +0 -1
  181. package/dist/src/dot.js +0 -610
  182. package/dist/src/lib/addressInitializationBuilder.js +0 -182
  183. package/dist/src/lib/batchTransactionBuilder.js +0 -229
  184. package/dist/src/lib/claimBuilder.js +0 -117
  185. package/dist/src/lib/errors.js +0 -19
  186. package/dist/src/lib/iface.js +0 -128
  187. package/dist/src/lib/iface_utils.js +0 -92
  188. package/dist/src/lib/keyPair.js +0 -117
  189. package/dist/src/lib/nativeTransferBuilder.js +0 -219
  190. package/dist/src/lib/proxyBuilder.js +0 -116
  191. package/dist/src/lib/singletonRegistry.js +0 -20
  192. package/dist/src/lib/stakingBuilder.js +0 -167
  193. package/dist/src/lib/transaction.js +0 -610
  194. package/dist/src/lib/transactionBuilder.js +0 -351
  195. package/dist/src/lib/transactionBuilderFactory.js +0 -104
  196. package/dist/src/lib/transferBuilder.js +0 -11
  197. package/dist/src/lib/txnSchema.js +0 -117
  198. package/dist/src/lib/unnominateBuilder.js +0 -48
  199. package/dist/src/lib/unstakeBuilder.js +0 -87
  200. package/dist/src/lib/utils.js +0 -491
  201. package/dist/src/lib/withdrawUnstakedBuilder.js +0 -88
  202. package/dist/src/register.js +0 -11
  203. package/dist/src/resources/mainnet.js +0 -5
  204. package/dist/src/resources/polkadotAssetHub.js +0 -5
  205. package/dist/src/tdot.js +0 -27
  206. package/dist/test/fixtures.d.ts.map +0 -1
  207. package/dist/test/fixtures.js +0 -439
  208. package/dist/test/resources/index.d.ts.map +0 -1
  209. package/dist/test/resources/index.js +0 -157
  210. package/dist/test/resources/testnet.d.ts.map +0 -1
  211. package/dist/test/unit/address.js +0 -45
  212. package/dist/test/unit/dot.js +0 -816
  213. package/dist/test/unit/keypair.js +0 -111
  214. package/dist/test/unit/transaction.d.ts.map +0 -1
  215. package/dist/test/unit/transaction.js +0 -269
  216. package/dist/test/unit/transactionBuilder/addressInitializationBuilder.d.ts.map +0 -1
  217. package/dist/test/unit/transactionBuilder/addressInitializationBuilder.js +0 -265
  218. package/dist/test/unit/transactionBuilder/base.d.ts.map +0 -1
  219. package/dist/test/unit/transactionBuilder/base.js +0 -233
  220. package/dist/test/unit/transactionBuilder/batchTransactionBuilder.d.ts.map +0 -1
  221. package/dist/test/unit/transactionBuilder/batchTransactionBuilder.js +0 -521
  222. package/dist/test/unit/transactionBuilder/claimBuilder.d.ts.map +0 -1
  223. package/dist/test/unit/transactionBuilder/claimBuilder.js +0 -129
  224. package/dist/test/unit/transactionBuilder/proxyBuilder.d.ts.map +0 -1
  225. package/dist/test/unit/transactionBuilder/proxyBuilder.js +0 -88
  226. package/dist/test/unit/transactionBuilder/singeltonRegistry.d.ts.map +0 -1
  227. package/dist/test/unit/transactionBuilder/stakingBuilder.d.ts.map +0 -1
  228. package/dist/test/unit/transactionBuilder/stakingBuilder.js +0 -235
  229. package/dist/test/unit/transactionBuilder/transactionBuilderFactory.d.ts.map +0 -1
  230. package/dist/test/unit/transactionBuilder/transactionBuilderFactory.js +0 -107
  231. package/dist/test/unit/transactionBuilder/transferBuilder.d.ts.map +0 -1
  232. package/dist/test/unit/transactionBuilder/transferBuilder.js +0 -437
  233. package/dist/test/unit/transactionBuilder/unnominateBuilder.d.ts.map +0 -1
  234. package/dist/test/unit/transactionBuilder/unnominateBuilder.js +0 -97
  235. package/dist/test/unit/transactionBuilder/unstakeBuilder.d.ts.map +0 -1
  236. package/dist/test/unit/transactionBuilder/unstakeBuilder.js +0 -116
  237. package/dist/test/unit/transactionBuilder/withdrawUnstakedBuilder.d.ts.map +0 -1
  238. package/dist/test/unit/transactionBuilder/withdrawUnstakedBuilder.js +0 -115
  239. package/dist/test/unit/utils.js +0 -117
  240. package/dist/tsconfig.tsbuildinfo +0 -1
  241. /package/dist/{src → cjs/src}/index.d.ts +0 -0
  242. /package/dist/{src → cjs/src}/lib/addressInitializationBuilder.d.ts +0 -0
  243. /package/dist/{src → cjs/src}/lib/batchTransactionBuilder.d.ts +0 -0
  244. /package/dist/{src → cjs/src}/lib/claimBuilder.d.ts +0 -0
  245. /package/dist/{src → cjs/src}/lib/errors.d.ts +0 -0
  246. /package/dist/{src → cjs/src}/lib/iface.d.ts +0 -0
  247. /package/dist/{src → cjs/src}/lib/iface_utils.d.ts +0 -0
  248. /package/dist/{src → cjs/src}/lib/keyPair.d.ts +0 -0
  249. /package/dist/{src → cjs/src}/lib/nativeTransferBuilder.d.ts +0 -0
  250. /package/dist/{src → cjs/src}/lib/proxyBuilder.d.ts +0 -0
  251. /package/dist/{src → cjs/src}/lib/singletonRegistry.d.ts +0 -0
  252. /package/dist/{src → cjs/src}/lib/stakingBuilder.d.ts +0 -0
  253. /package/dist/{src → cjs/src}/lib/transaction.d.ts +0 -0
  254. /package/dist/{src → cjs/src}/lib/transactionBuilder.d.ts +0 -0
  255. /package/dist/{src → cjs/src}/lib/transactionBuilderFactory.d.ts +0 -0
  256. /package/dist/{src → cjs/src}/lib/transferBuilder.d.ts +0 -0
  257. /package/dist/{src → cjs/src}/lib/txnSchema.d.ts +0 -0
  258. /package/dist/{src → cjs/src}/lib/unnominateBuilder.d.ts +0 -0
  259. /package/dist/{src → cjs/src}/lib/unstakeBuilder.d.ts +0 -0
  260. /package/dist/{src → cjs/src}/lib/utils.d.ts +0 -0
  261. /package/dist/{src → cjs/src}/lib/withdrawUnstakedBuilder.d.ts +0 -0
  262. /package/dist/{src → cjs/src}/register.d.ts +0 -0
  263. /package/dist/{src → cjs/src}/resources/index.d.ts +0 -0
  264. /package/dist/{src → cjs/src}/resources/mainnet.d.ts +0 -0
  265. /package/dist/{src → cjs/src}/resources/polkadotAssetHub.d.ts +0 -0
  266. /package/dist/{src → cjs/src}/resources/westend.d.ts +0 -0
  267. /package/dist/{src → cjs/src}/resources/westendAssetHub.d.ts +0 -0
  268. /package/dist/{src → cjs/src}/tdot.d.ts +0 -0
  269. /package/dist/{test → cjs/test}/fixtures.d.ts +0 -0
  270. /package/dist/{test → cjs/test}/resources/index.d.ts +0 -0
  271. /package/dist/{test → cjs/test}/resources/materialData.json +0 -0
  272. /package/dist/{test → cjs/test}/resources/materialDataModified.json +0 -0
  273. /package/dist/{test → cjs/test}/resources/testnet.d.ts +0 -0
  274. /package/dist/{test → cjs/test}/unit/address.d.ts +0 -0
  275. /package/dist/{test → cjs/test}/unit/dot.d.ts +0 -0
  276. /package/dist/{test → cjs/test}/unit/keypair.d.ts +0 -0
  277. /package/dist/{test → cjs/test}/unit/transaction.d.ts +0 -0
  278. /package/dist/{test → cjs/test}/unit/transactionBuilder/addressInitializationBuilder.d.ts +0 -0
  279. /package/dist/{test → cjs/test}/unit/transactionBuilder/base.d.ts +0 -0
  280. /package/dist/{test → cjs/test}/unit/transactionBuilder/batchTransactionBuilder.d.ts +0 -0
  281. /package/dist/{test → cjs/test}/unit/transactionBuilder/claimBuilder.d.ts +0 -0
  282. /package/dist/{test → cjs/test}/unit/transactionBuilder/proxyBuilder.d.ts +0 -0
  283. /package/dist/{test → cjs/test}/unit/transactionBuilder/singeltonRegistry.d.ts +0 -0
  284. /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingBuilder.d.ts +0 -0
  285. /package/dist/{test → cjs/test}/unit/transactionBuilder/transactionBuilderFactory.d.ts +0 -0
  286. /package/dist/{test → cjs/test}/unit/transactionBuilder/transferBuilder.d.ts +0 -0
  287. /package/dist/{test → cjs/test}/unit/transactionBuilder/unnominateBuilder.d.ts +0 -0
  288. /package/dist/{test → cjs/test}/unit/transactionBuilder/unstakeBuilder.d.ts +0 -0
  289. /package/dist/{test → cjs/test}/unit/transactionBuilder/withdrawUnstakedBuilder.d.ts +0 -0
  290. /package/dist/{test → cjs/test}/unit/utils.d.ts +0 -0
  291. /package/dist/{src → esm}/index.d.ts.map +0 -0
  292. /package/dist/{src → esm}/lib/addressInitializationBuilder.d.ts.map +0 -0
  293. /package/dist/{src → esm}/lib/batchTransactionBuilder.d.ts.map +0 -0
  294. /package/dist/{src → esm}/lib/claimBuilder.d.ts.map +0 -0
  295. /package/dist/{src → esm}/lib/errors.d.ts.map +0 -0
  296. /package/dist/{src → esm}/lib/iface.d.ts.map +0 -0
  297. /package/dist/{src → esm}/lib/iface_utils.d.ts.map +0 -0
  298. /package/dist/{src → esm}/lib/keyPair.d.ts.map +0 -0
  299. /package/dist/{src → esm}/lib/nativeTransferBuilder.d.ts.map +0 -0
  300. /package/dist/{src → esm}/lib/proxyBuilder.d.ts.map +0 -0
  301. /package/dist/{src → esm}/lib/singletonRegistry.d.ts.map +0 -0
  302. /package/dist/{src → esm}/lib/stakingBuilder.d.ts.map +0 -0
  303. /package/dist/{src → esm}/lib/transactionBuilder.d.ts.map +0 -0
  304. /package/dist/{src → esm}/lib/transactionBuilderFactory.d.ts.map +0 -0
  305. /package/dist/{src → esm}/lib/transferBuilder.d.ts.map +0 -0
  306. /package/dist/{src → esm}/lib/txnSchema.d.ts.map +0 -0
  307. /package/dist/{src → esm}/lib/unnominateBuilder.d.ts.map +0 -0
  308. /package/dist/{src → esm}/lib/unstakeBuilder.d.ts.map +0 -0
  309. /package/dist/{src → esm}/lib/utils.d.ts.map +0 -0
  310. /package/dist/{src → esm}/lib/withdrawUnstakedBuilder.d.ts.map +0 -0
  311. /package/dist/{src → esm}/register.d.ts.map +0 -0
  312. /package/dist/{src → esm}/resources/index.d.ts.map +0 -0
  313. /package/dist/{src → esm}/resources/mainnet.d.ts.map +0 -0
  314. /package/dist/{src → esm}/resources/polkadotAssetHub.d.ts.map +0 -0
  315. /package/dist/{src → esm}/resources/westend.d.ts.map +0 -0
  316. /package/dist/{src → esm}/resources/westendAssetHub.d.ts.map +0 -0
  317. /package/dist/{src → esm}/tdot.d.ts.map +0 -0
@@ -1,816 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- const sdk_api_1 = require("@bitgo/sdk-api");
37
- const sdk_test_1 = require("@bitgo/sdk-test");
38
- const crypto_1 = require("crypto");
39
- const should = require("should");
40
- const assert = require("assert");
41
- const src_1 = require("../../src");
42
- const testData = __importStar(require("../fixtures"));
43
- const resources_1 = require("../resources");
44
- const sinon = __importStar(require("sinon"));
45
- const sdk_core_1 = require("@bitgo/sdk-core");
46
- describe('DOT:', function () {
47
- let bitgo;
48
- let basecoin;
49
- let prodCoin;
50
- before(function () {
51
- bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
52
- bitgo.safeRegister('dot', src_1.Dot.createInstance);
53
- bitgo.safeRegister('tdot', src_1.Tdot.createInstance);
54
- bitgo.initializeTestVars();
55
- basecoin = bitgo.coin('tdot');
56
- prodCoin = bitgo.coin('dot');
57
- });
58
- describe('Sign Message', () => {
59
- it('should be performed', async () => {
60
- const keyPair = new src_1.KeyPair();
61
- const messageToSign = Buffer.from((0, crypto_1.randomBytes)(32)).toString('hex');
62
- const signature = await basecoin.signMessage(keyPair.getKeys(), messageToSign);
63
- keyPair.verifySignature(messageToSign, Uint8Array.from(signature)).should.equals(true);
64
- });
65
- it('should fail with missing private key', async () => {
66
- const keyPair = new src_1.KeyPair({
67
- pub: '7788327c695dca4b3e649a0db45bc3e703a2c67428fce360e61800cc4248f4f7',
68
- }).getKeys();
69
- const messageToSign = Buffer.from((0, crypto_1.randomBytes)(32)).toString('hex');
70
- await basecoin.signMessage(keyPair, messageToSign).should.be.rejectedWith('Invalid key pair options');
71
- });
72
- });
73
- describe('Sign transaction', () => {
74
- const transaction = {
75
- id: '0x19de156328eea66bd1ec45843569c168e0bb2f2898221029b403df3f23a5489d',
76
- sender: '5EGoFA95omzemRssELLDjVenNZ68aXyUeqtKQScXSEBvVJkr',
77
- referenceBlock: '0x149799bc9602cb5cf201f3425fb8d253b2d4e61fc119dcab3249f307f594754d',
78
- blockNumber: 3933,
79
- genesisHash: '0x67f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9',
80
- nonce: 200,
81
- specVersion: 1018013,
82
- transactionVersion: 16,
83
- eraPeriod: 64,
84
- chainName: 'Westend Asset Hub',
85
- tip: 0,
86
- to: '5Ffp1wJCPu4hzVDTo7XaMLqZSvSadyUQmxWPDw74CBjECSoq',
87
- amount: '10000000000',
88
- };
89
- // TODO: BG-43197
90
- xit('should sign transaction', async function () {
91
- const signed = await basecoin.signTransaction({
92
- txPrebuild: {
93
- txHex: testData.rawTx.transfer.unsigned,
94
- transaction,
95
- },
96
- pubs: [testData.accounts.account1.publicKey],
97
- prv: testData.accounts.account1.secretKey,
98
- });
99
- signed.txHex.should.equal(testData.rawTx.transfer.signed);
100
- });
101
- // TODO: BG-43197
102
- xit('should fail to sign transaction with an invalid key', async function () {
103
- try {
104
- await basecoin.signTransaction({
105
- txPrebuild: {
106
- txHex: testData.rawTx.transfer.unsigned,
107
- transaction,
108
- },
109
- pubs: [testData.accounts.account2.publicKey],
110
- prv: testData.accounts.account1.secretKey,
111
- });
112
- }
113
- catch (e) {
114
- should.equal(e.message, 'Private key cannot sign the transaction');
115
- }
116
- });
117
- it('should fail to build transaction with missing params', async function () {
118
- try {
119
- await basecoin.signTransaction({
120
- txPrebuild: {
121
- txHex: testData.rawTx.transfer.unsigned,
122
- key: testData.accounts.account1.publicKey,
123
- },
124
- prv: testData.accounts.account1.secretKey,
125
- });
126
- }
127
- catch (e) {
128
- should.notEqual(e, null);
129
- }
130
- });
131
- });
132
- describe('Generate wallet key pair: ', () => {
133
- it('should generate key pair', () => {
134
- const kp = basecoin.generateKeyPair();
135
- basecoin.isValidPub(kp.pub).should.equal(true);
136
- basecoin.isValidPrv(kp.prv).should.equal(true);
137
- });
138
- it('should generate key pair from seed', () => {
139
- const seed = Buffer.from('9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60', 'hex');
140
- const kp = basecoin.generateKeyPair(seed);
141
- basecoin.isValidPub(kp.pub).should.equal(true);
142
- basecoin.isValidPrv(kp.prv).should.equal(true);
143
- });
144
- });
145
- describe('Balance Conversion', () => {
146
- it('should return 10000000000 as tdot base factor', () => {
147
- // mainnet uses 10 decimal places
148
- const baseFactor = prodCoin.getBaseFactor();
149
- baseFactor.should.equal(10000000000);
150
- });
151
- it('should return 1000000000000 as dot base factor', () => {
152
- // westend (test polkadot) uses 12 decimal places
153
- const baseFactor = basecoin.getBaseFactor();
154
- baseFactor.should.equal(1000000000000);
155
- });
156
- it('should return 4 Dot when base unit is 40000000000 for dot', () => {
157
- const bigUnit = prodCoin.baseUnitsToBigUnits('40000000000');
158
- bigUnit.should.equal('4');
159
- });
160
- it('should return 0.04 Dot when base unit is 400000000 for dot', () => {
161
- const bigUnit = prodCoin.baseUnitsToBigUnits('400000000');
162
- bigUnit.should.equal('0.04');
163
- });
164
- it('should return 4 test Dot when base unit is 4000000000000 for tdot', () => {
165
- const bigUnit = basecoin.baseUnitsToBigUnits('4000000000000');
166
- bigUnit.should.equal('4');
167
- });
168
- it('should return 0.04 test Dot when base unit is 400000000 for tdot', () => {
169
- const bigUnit = basecoin.baseUnitsToBigUnits('40000000000');
170
- bigUnit.should.equal('0.04');
171
- });
172
- });
173
- describe('Explain Transactions:', () => {
174
- it('should explain an unsigned transfer transaction', async function () {
175
- const explainedTransaction = await basecoin.explainTransaction(testData.unsignedTransaction);
176
- explainedTransaction.should.deepEqual({
177
- displayOrder: [
178
- 'outputAmount',
179
- 'changeAmount',
180
- 'outputs',
181
- 'changeOutputs',
182
- 'fee',
183
- 'type',
184
- 'sequenceId',
185
- 'id',
186
- 'blockNumber',
187
- ],
188
- sequenceId: 0,
189
- fee: '10',
190
- id: '0x0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8',
191
- type: '0',
192
- outputs: [
193
- {
194
- address: '5DkddSfPsWojjfuH9iJEcUV7ZseQ9EJ6RjtNmCR1w3CEb8S9',
195
- valueString: '90034235235350',
196
- coinName: 'tdot',
197
- wallet: '62a1205751675b2f0fe72328',
198
- },
199
- ],
200
- blockNumber: 8619307,
201
- outputAmount: 90034235235350,
202
- changeOutputs: [],
203
- changeAmount: '0',
204
- });
205
- });
206
- });
207
- describe('Recover Transactions:', () => {
208
- const sandBox = sinon.createSandbox();
209
- const destAddr = testData.accounts.account1.address;
210
- const nonce = 123;
211
- beforeEach(function () {
212
- const accountInfoCB = sandBox.stub(src_1.Dot.prototype, 'getAccountInfo');
213
- accountInfoCB.withArgs(testData.wrwUser.walletAddress0).resolves({
214
- nonce: nonce,
215
- freeBalance: 8888,
216
- });
217
- const headerInfoCB = sandBox.stub(src_1.Dot.prototype, 'getHeaderInfo');
218
- headerInfoCB.resolves({
219
- headerNumber: testData.westendBlock.blockNumber,
220
- headerHash: testData.westendBlock.hash,
221
- });
222
- accountInfoCB.withArgs('5Dtg2zKjVEL8p9keSM4dQ7nD26sVtMfCsyxkhvZZ9fqBbhw6').resolves({
223
- nonce: 0,
224
- freeBalance: 1510000000000,
225
- });
226
- const getFeeCB = sandBox.stub(src_1.Dot.prototype, 'getFee');
227
- getFeeCB.withArgs(destAddr, testData.wrwUser.walletAddress0, 1510000000000).resolves(15783812856);
228
- });
229
- afterEach(function () {
230
- sandBox.restore();
231
- });
232
- it('should generate unsigned sweep correctly', async function () {
233
- const commonKeychain = '3cd14f5d60744287cd3a50510e2964746b6feaad4b2300088eaae60d1a35f0abc518534d43b2614370d9a263aadb57edb5d0b78f816a519cd5896e7352920b67';
234
- const recoveryDestination = '5GPAveMvmDsjxVT6Q2xiu5kYPbFAmdebHaiNZK14FBaSaAKh';
235
- const unsigned = await basecoin.recover({ bitgoKey: commonKeychain, recoveryDestination });
236
- unsigned.txRequests.should.not.be.undefined();
237
- unsigned.txRequests.length.should.equal(1);
238
- unsigned.txRequests[0].transactions.length.should.equal(1);
239
- unsigned.txRequests[0].walletCoin.should.equal('tdot');
240
- unsigned.txRequests[0].transactions[0].unsignedTx.should.not.be.undefined();
241
- unsigned.txRequests[0].transactions[0].unsignedTx.serializedTx.should.not.be.undefined();
242
- unsigned.txRequests[0].transactions[0].unsignedTx.scanIndex.should.equal(0);
243
- unsigned.txRequests[0].transactions[0].unsignedTx.coin.should.equal('tdot');
244
- unsigned.txRequests[0].transactions[0].unsignedTx.signableHex.should.not.be.undefined();
245
- unsigned.txRequests[0].transactions[0].unsignedTx.derivationPath.should.equal('m/0');
246
- unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.should.not.be.undefined();
247
- unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.inputs.should.not.be.undefined();
248
- unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.inputs.length.should.equal(1);
249
- unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.inputs[0].address.should.equal('5Dtg2zKjVEL8p9keSM4dQ7nD26sVtMfCsyxkhvZZ9fqBbhw6');
250
- unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.inputs[0].valueString.should.equal('1510000000000');
251
- unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.inputs[0].value.should.equal(1510000000000);
252
- unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.outputs.should.not.be.undefined();
253
- unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.outputs.length.should.equal(1);
254
- unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.outputs[0].address.should.equal('5GPAveMvmDsjxVT6Q2xiu5kYPbFAmdebHaiNZK14FBaSaAKh');
255
- unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.outputs[0].valueString.should.equal('1510000000000');
256
- unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.outputs[0].coinName.should.equal('tdot');
257
- unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.type.should.equal('');
258
- unsigned.txRequests[0].transactions[0].unsignedTx.feeInfo.should.not.be.undefined();
259
- unsigned.txRequests[0].transactions[0].unsignedTx.feeInfo.fee.should.equal(0);
260
- unsigned.txRequests[0].transactions[0].unsignedTx.feeInfo.feeString.should.equal('0');
261
- unsigned.txRequests[0].transactions[0].unsignedTx.coinSpecific.should.not.be.undefined();
262
- unsigned.txRequests[0].transactions[0].unsignedTx.coinSpecific.firstValid.should.not.be.undefined();
263
- unsigned.txRequests[0].transactions[0].unsignedTx.coinSpecific.maxDuration.should.equal(2400);
264
- unsigned.txRequests[0].transactions[0].unsignedTx.coinSpecific.commonKeychain.should.equal('3cd14f5d60744287cd3a50510e2964746b6feaad4b2300088eaae60d1a35f0abc518534d43b2614370d9a263aadb57edb5d0b78f816a519cd5896e7352920b67');
265
- });
266
- // TODO(COIN-919): Fix failing test
267
- xit('should take OVC output and generate a signed sweep transaction', async function () {
268
- const params = testData.ovcResponse;
269
- const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
270
- recoveryTxn.transactions[0].serializedTx.should.equal('0x2d02840050d1e116cdb32e61ba3ece275b620f503f0c5ae4e7690d9f9aa7e0b50303976c00057c131cde2be39f4ff23eeba11139c46dd8c6d69ff517abede37381d8d24f0bb30fd8805b2e51a9e2a75338d7fb7edb290be9638debedbfc001d10b8132be0b2b4a0400040400bf0678d312b2b2c7effd2b1f214ee13928d339391d5f5f7056608aa0d32b9edf01');
271
- recoveryTxn.transactions[0].scanIndex.should.equal(0);
272
- recoveryTxn.lastScanIndex.should.equal(0);
273
- });
274
- // TODO(COIN-919): Fix failing test
275
- xit('should take consolidation OVC output and generate multiple signed sweep transactions', async function () {
276
- const params = testData.ovcResponse2;
277
- const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
278
- recoveryTxn.transactions[0].serializedTx.should.equal('0x2d028400f053d177371f4919b71017421aa34841ac87c926a14e8a7e75f092693665cb4a009871feb8389e12191b460ebea1f9e1716ada8a31d94ac08f5c15cb5f7be24683cdfc300ae3e6802c6f4b044dd92ea03d15b92399ab45803e43beb5cbff582a031b37000004040050d1e116cdb32e61ba3ece275b620f503f0c5ae4e7690d9f9aa7e0b50303976c01');
279
- recoveryTxn.transactions[0].scanIndex.should.equal(1);
280
- recoveryTxn.transactions[1].serializedTx.should.equal('0x2d028400cf7ed9f536373c8f874e780a4269ec1bd6799ed7d4a854c670b0c72805fac87600d153cbb683706ddf320f7b225af14ce4b59b868c07440aefa4c4e1297e49bcd5f6ee84f696b0c2e456e2a7f8779a78a2c832dfb47d5b283eba8408b003c7dd031b37000004040050d1e116cdb32e61ba3ece275b620f503f0c5ae4e7690d9f9aa7e0b50303976c01');
281
- recoveryTxn.transactions[1].scanIndex.should.equal(2);
282
- recoveryTxn.transactions[2].serializedTx.should.equal('0x2d0284009482ad7e43b40b7df3383244daafed32b3b9fd7541016b5c907f2d9052f85f8600e255698d110977faf33efb3336ba98ad7eaa2a1a926487fc696a277442d4414b2a441ba92d598f2b1f96f13b28785f5e572984035a608d63c48bd35ba955090e1b37000004040050d1e116cdb32e61ba3ece275b620f503f0c5ae4e7690d9f9aa7e0b50303976c01');
283
- recoveryTxn.transactions[2].scanIndex.should.equal(3);
284
- recoveryTxn.lastScanIndex.should.equal(20);
285
- });
286
- // TODO(COIN-919): Fix failing test
287
- xit('should recover a txn for non-bitgo recoveries', async function () {
288
- const res = await basecoin.recover({
289
- userKey: testData.wrwUser.userKey,
290
- backupKey: testData.wrwUser.backupKey,
291
- bitgoKey: testData.wrwUser.bitgoKey,
292
- walletPassphrase: testData.wrwUser.walletPassphrase,
293
- recoveryDestination: destAddr,
294
- });
295
- res.should.not.be.empty();
296
- res.should.hasOwnProperty('serializedTx');
297
- res.should.hasOwnProperty('scanIndex');
298
- sandBox.assert.calledOnce(basecoin.getAccountInfo);
299
- sandBox.assert.calledOnce(basecoin.getHeaderInfo);
300
- // deserialize the txn and verify the fields are what we expect
301
- const txBuilder = basecoin.getBuilder().from(res.serializedTx);
302
- // some information isn't deserialized by the from method, so we will
303
- // supply it again in order to re-build the txn
304
- txBuilder
305
- .validity({
306
- firstValid: testData.westendBlock.blockNumber,
307
- maxDuration: basecoin.SWEEP_TXN_DURATION,
308
- })
309
- .referenceBlock(testData.westendBlock.hash);
310
- const tx = await txBuilder.build();
311
- const txJson = tx.toJson();
312
- should.deepEqual(txJson.sender, testData.wrwUser.walletAddress0);
313
- should.deepEqual(txJson.blockNumber, testData.westendBlock.blockNumber);
314
- should.deepEqual(txJson.referenceBlock, testData.westendBlock.hash);
315
- should.deepEqual(txJson.genesisHash, resources_1.genesisHash);
316
- should.deepEqual(txJson.specVersion, resources_1.specVersion);
317
- should.deepEqual(txJson.nonce, nonce);
318
- should.deepEqual(txJson.tip, 0);
319
- should.deepEqual(txJson.transactionVersion, resources_1.txVersion);
320
- should.deepEqual(txJson.chainName, resources_1.chainName);
321
- should.deepEqual(txJson.eraPeriod, basecoin.SWEEP_TXN_DURATION);
322
- });
323
- it('should recover a txn for unsigned-sweep recoveries', async function () {
324
- const res = await basecoin.recover({
325
- bitgoKey: testData.wrwUser.bitgoKey,
326
- recoveryDestination: destAddr,
327
- });
328
- res.should.not.be.empty();
329
- res.txRequests[0].transactions[0].unsignedTx.should.hasOwnProperty('serializedTx');
330
- res.txRequests[0].transactions[0].unsignedTx.should.hasOwnProperty('scanIndex');
331
- sandBox.assert.calledOnce(basecoin.getAccountInfo);
332
- sandBox.assert.calledOnce(basecoin.getHeaderInfo);
333
- // deserialize the txn and verify the fields are what we expect
334
- const txBuilder = basecoin.getBuilder().from(res.txRequests[0].transactions[0].unsignedTx.serializedTx);
335
- // some information isn't deserialized by the from method, so we will
336
- // supply it again in order to re-build the txn
337
- txBuilder
338
- .validity({
339
- firstValid: testData.westendBlock.blockNumber,
340
- maxDuration: basecoin.SWEEP_TXN_DURATION,
341
- })
342
- .referenceBlock(testData.westendBlock.hash)
343
- .sender({ address: testData.wrwUser.walletAddress0 });
344
- const tx = await txBuilder.build();
345
- const txJson = tx.toJson();
346
- should.deepEqual(txJson.sender, testData.wrwUser.walletAddress0);
347
- should.deepEqual(txJson.blockNumber, testData.westendBlock.blockNumber);
348
- should.deepEqual(txJson.referenceBlock, testData.westendBlock.hash);
349
- should.deepEqual(txJson.genesisHash, resources_1.genesisHash);
350
- should.deepEqual(txJson.specVersion, resources_1.specVersion);
351
- should.deepEqual(txJson.nonce, nonce);
352
- should.deepEqual(txJson.tip, 0);
353
- should.deepEqual(txJson.transactionVersion, resources_1.txVersion);
354
- should.deepEqual(txJson.chainName, resources_1.chainName);
355
- should.deepEqual(txJson.eraPeriod, basecoin.SWEEP_TXN_DURATION);
356
- });
357
- });
358
- describe('Build Consolidation Recoveries:', () => {
359
- const sandBox = sinon.createSandbox();
360
- const baseAddr = testData.consolidationWrwUser.walletAddress0;
361
- const nonce = 123;
362
- beforeEach(function () {
363
- const accountInfoCB = sandBox.stub(src_1.Dot.prototype, 'getAccountInfo');
364
- accountInfoCB.withArgs(testData.consolidationWrwUser.walletAddress1).resolves({
365
- nonce: nonce,
366
- freeBalance: 10000000000,
367
- });
368
- accountInfoCB.withArgs(testData.consolidationWrwUser.walletAddress2).resolves({
369
- nonce: nonce,
370
- freeBalance: 1510000000000,
371
- });
372
- accountInfoCB.withArgs(testData.consolidationWrwUser.walletAddress3).resolves({
373
- nonce: nonce,
374
- freeBalance: 1510000000000,
375
- });
376
- const headerInfoCB = sandBox.stub(src_1.Dot.prototype, 'getHeaderInfo');
377
- headerInfoCB.resolves({
378
- headerNumber: testData.westendBlock.blockNumber,
379
- headerHash: testData.westendBlock.hash,
380
- });
381
- const getFeeCB = sandBox.stub(src_1.Dot.prototype, 'getFee');
382
- getFeeCB.withArgs(baseAddr, testData.consolidationWrwUser.walletAddress1, 10000000000).resolves(15783812856);
383
- getFeeCB.withArgs(baseAddr, testData.consolidationWrwUser.walletAddress2, 1510000000000).resolves(15783812856);
384
- getFeeCB.withArgs(baseAddr, testData.consolidationWrwUser.walletAddress3, 1510000000000).resolves(15783812856);
385
- });
386
- afterEach(function () {
387
- sandBox.restore();
388
- });
389
- // TODO(COIN-919): Fix failing test
390
- xit('should build signed consolidation recoveries', async function () {
391
- const res = await basecoin.recoverConsolidations({
392
- userKey: testData.consolidationWrwUser.userKey,
393
- backupKey: testData.consolidationWrwUser.backupKey,
394
- bitgoKey: testData.consolidationWrwUser.bitgoKey,
395
- walletPassphrase: testData.consolidationWrwUser.walletPassphrase,
396
- startingScanIndex: 1,
397
- endingScanIndex: 4,
398
- });
399
- res.should.not.be.empty();
400
- res.transactions.length.should.equal(2);
401
- sandBox.assert.calledThrice(basecoin.getAccountInfo);
402
- sandBox.assert.calledTwice(basecoin.getHeaderInfo);
403
- const txn1 = res.transactions[0];
404
- txn1.should.hasOwnProperty('serializedTx');
405
- txn1.should.hasOwnProperty('scanIndex');
406
- txn1.scanIndex.should.equal(2);
407
- // deserialize the txn and verify the fields are what we expect
408
- const txBuilder1 = basecoin.getBuilder().from(txn1.serializedTx);
409
- // some information isn't deserialized by the from method, so we will
410
- // supply it again in order to re-build the txn
411
- txBuilder1
412
- .validity({
413
- firstValid: testData.westendBlock.blockNumber,
414
- maxDuration: basecoin.MAX_VALIDITY_DURATION,
415
- })
416
- .referenceBlock(testData.westendBlock.hash);
417
- const tx1 = await txBuilder1.build();
418
- const txJson1 = tx1.toJson();
419
- should.deepEqual(txJson1.sender, testData.consolidationWrwUser.walletAddress2);
420
- should.deepEqual(txJson1.blockNumber, testData.westendBlock.blockNumber);
421
- should.deepEqual(txJson1.referenceBlock, testData.westendBlock.hash);
422
- should.deepEqual(txJson1.genesisHash, resources_1.genesisHash);
423
- should.deepEqual(txJson1.specVersion, resources_1.specVersion);
424
- should.deepEqual(txJson1.nonce, nonce);
425
- should.deepEqual(txJson1.tip, 0);
426
- should.deepEqual(txJson1.transactionVersion, resources_1.txVersion);
427
- should.deepEqual(txJson1.chainName, resources_1.chainName);
428
- // eraPeriod will always round to the next upper power of 2 for any input value, in this case 2400.
429
- // 4096 is the "highest" value you can set, but the txn still may fail after 2400 blocks.
430
- const eraPeriod = 4096;
431
- should.deepEqual(txJson1.eraPeriod, eraPeriod);
432
- should.deepEqual(txJson1.to, baseAddr);
433
- res.lastScanIndex.should.equal(3);
434
- const txn2 = res.transactions[1];
435
- txn2.should.hasOwnProperty('serializedTx');
436
- txn2.should.hasOwnProperty('scanIndex');
437
- txn2.scanIndex.should.equal(3);
438
- // deserialize the txn and verify the fields are what we expect
439
- const txBuilder2 = basecoin.getBuilder().from(txn2.serializedTx);
440
- // some information isn't deserialized by the from method, so we will
441
- // supply it again in order to re-build the txn
442
- txBuilder2
443
- .validity({
444
- firstValid: testData.westendBlock.blockNumber,
445
- maxDuration: basecoin.MAX_VALIDITY_DURATION,
446
- })
447
- .referenceBlock(testData.westendBlock.hash);
448
- const tx2 = await txBuilder2.build();
449
- const txJson2 = tx2.toJson();
450
- should.deepEqual(txJson2.sender, testData.consolidationWrwUser.walletAddress3);
451
- should.deepEqual(txJson2.blockNumber, testData.westendBlock.blockNumber);
452
- should.deepEqual(txJson2.referenceBlock, testData.westendBlock.hash);
453
- should.deepEqual(txJson2.genesisHash, resources_1.genesisHash);
454
- should.deepEqual(txJson2.specVersion, resources_1.specVersion);
455
- should.deepEqual(txJson2.nonce, nonce);
456
- should.deepEqual(txJson2.tip, 0);
457
- should.deepEqual(txJson2.transactionVersion, resources_1.txVersion);
458
- should.deepEqual(txJson2.chainName, resources_1.chainName);
459
- should.deepEqual(txJson2.eraPeriod, eraPeriod);
460
- should.deepEqual(txJson2.to, baseAddr);
461
- });
462
- it('should build unsigned consolidation recoveries', async function () {
463
- const res = await basecoin.recoverConsolidations({
464
- bitgoKey: testData.consolidationWrwUser.bitgoKey,
465
- startingScanIndex: 1,
466
- endingScanIndex: 4,
467
- });
468
- res.should.not.be.empty();
469
- res.txRequests.length.should.equal(2);
470
- sandBox.assert.calledThrice(basecoin.getAccountInfo);
471
- sandBox.assert.calledTwice(basecoin.getHeaderInfo);
472
- const txn1 = res.txRequests[0].transactions[0].unsignedTx;
473
- txn1.should.hasOwnProperty('serializedTx');
474
- txn1.should.hasOwnProperty('signableHex');
475
- txn1.should.hasOwnProperty('scanIndex');
476
- txn1.scanIndex.should.equal(2);
477
- txn1.should.hasOwnProperty('coin');
478
- txn1.coin.should.equal('tdot');
479
- txn1.should.hasOwnProperty('derivationPath');
480
- txn1.derivationPath.should.equal('m/2');
481
- txn1.should.hasOwnProperty('coinSpecific');
482
- const coinSpecific1 = txn1.coinSpecific;
483
- coinSpecific1.should.hasOwnProperty('commonKeychain');
484
- coinSpecific1.should.hasOwnProperty('firstValid');
485
- coinSpecific1.firstValid.should.equal(testData.westendBlock.blockNumber);
486
- coinSpecific1.should.hasOwnProperty('maxDuration');
487
- coinSpecific1.maxDuration.should.equal(basecoin.MAX_VALIDITY_DURATION);
488
- // deserialize the txn and verify the fields are what we expect
489
- const txBuilder1 = basecoin.getBuilder().from(txn1.serializedTx);
490
- // some information isn't deserialized by the from method, so we will
491
- // supply it again in order to re-build the txn
492
- txBuilder1
493
- .validity({
494
- firstValid: testData.westendBlock.blockNumber,
495
- maxDuration: basecoin.MAX_VALIDITY_DURATION,
496
- })
497
- .referenceBlock(testData.westendBlock.hash)
498
- .sender({ address: testData.consolidationWrwUser.walletAddress2 });
499
- const tx1 = await txBuilder1.build();
500
- const txJson1 = tx1.toJson();
501
- should.deepEqual(txJson1.sender, testData.consolidationWrwUser.walletAddress2);
502
- should.deepEqual(txJson1.blockNumber, testData.westendBlock.blockNumber);
503
- should.deepEqual(txJson1.referenceBlock, testData.westendBlock.hash);
504
- should.deepEqual(txJson1.genesisHash, resources_1.genesisHash);
505
- should.deepEqual(txJson1.specVersion, resources_1.specVersion);
506
- should.deepEqual(txJson1.nonce, nonce);
507
- should.deepEqual(txJson1.tip, 0);
508
- should.deepEqual(txJson1.transactionVersion, resources_1.txVersion);
509
- should.deepEqual(txJson1.chainName, resources_1.chainName);
510
- // eraPeriod will always round to the next upper power of 2 for any input value, in this case 2400.
511
- // 4096 is the "highest" value you can set, but the txn still may fail after 2400 blocks.
512
- const eraPeriod = 4096;
513
- should.deepEqual(txJson1.eraPeriod, eraPeriod);
514
- should.deepEqual(txJson1.to, baseAddr);
515
- const txn2 = res.txRequests[1].transactions[0].unsignedTx;
516
- txn2.should.hasOwnProperty('serializedTx');
517
- txn2.should.hasOwnProperty('signableHex');
518
- txn2.should.hasOwnProperty('scanIndex');
519
- txn2.scanIndex.should.equal(3);
520
- txn2.should.hasOwnProperty('coin');
521
- txn2.coin.should.equal('tdot');
522
- txn2.should.hasOwnProperty('derivationPath');
523
- txn2.derivationPath.should.equal('m/3');
524
- txn2.should.hasOwnProperty('coinSpecific');
525
- const coinSpecific2 = txn2.coinSpecific;
526
- coinSpecific2.should.hasOwnProperty('commonKeychain');
527
- coinSpecific2.should.hasOwnProperty('firstValid');
528
- coinSpecific2.firstValid.should.equal(testData.westendBlock.blockNumber);
529
- coinSpecific2.should.hasOwnProperty('maxDuration');
530
- coinSpecific2.maxDuration.should.equal(basecoin.MAX_VALIDITY_DURATION);
531
- coinSpecific2.should.hasOwnProperty('commonKeychain');
532
- coinSpecific2.should.hasOwnProperty('lastScanIndex');
533
- coinSpecific2.lastScanIndex.should.equal(3);
534
- // deserialize the txn and verify the fields are what we expect
535
- const txBuilder2 = basecoin.getBuilder().from(txn2.serializedTx);
536
- // some information isn't deserialized by the from method, so we will
537
- // supply it again in order to re-build the txn
538
- txBuilder2
539
- .validity({
540
- firstValid: testData.westendBlock.blockNumber,
541
- maxDuration: basecoin.MAX_VALIDITY_DURATION,
542
- })
543
- .referenceBlock(testData.westendBlock.hash)
544
- .sender({ address: testData.consolidationWrwUser.walletAddress3 });
545
- const tx2 = await txBuilder2.build();
546
- const txJson2 = tx2.toJson();
547
- should.deepEqual(txJson2.sender, testData.consolidationWrwUser.walletAddress3);
548
- should.deepEqual(txJson2.blockNumber, testData.westendBlock.blockNumber);
549
- should.deepEqual(txJson2.referenceBlock, testData.westendBlock.hash);
550
- should.deepEqual(txJson2.genesisHash, resources_1.genesisHash);
551
- should.deepEqual(txJson2.specVersion, resources_1.specVersion);
552
- should.deepEqual(txJson2.nonce, nonce);
553
- should.deepEqual(txJson2.tip, 0);
554
- should.deepEqual(txJson2.transactionVersion, resources_1.txVersion);
555
- should.deepEqual(txJson2.chainName, resources_1.chainName);
556
- should.deepEqual(txJson2.eraPeriod, eraPeriod);
557
- should.deepEqual(txJson2.to, baseAddr);
558
- });
559
- it('should skip building consolidate transaction if balance is equal to zero', async function () {
560
- await basecoin
561
- .recoverConsolidations({
562
- userKey: testData.consolidationWrwUser.userKey,
563
- backupKey: testData.consolidationWrwUser.backupKey,
564
- bitgoKey: testData.consolidationWrwUser.bitgoKey,
565
- walletPassphrase: testData.consolidationWrwUser.walletPassphrase,
566
- startingScanIndex: 1,
567
- endingScanIndex: 2,
568
- })
569
- .should.rejectedWith('Did not find an address with funds to recover');
570
- });
571
- it('should throw if startingScanIndex is not ge to 1', async () => {
572
- await basecoin
573
- .recoverConsolidations({
574
- userKey: testData.consolidationWrwUser.userKey,
575
- backupKey: testData.consolidationWrwUser.backupKey,
576
- bitgoKey: testData.consolidationWrwUser.bitgoKey,
577
- startingScanIndex: -1,
578
- })
579
- .should.be.rejectedWith('Invalid starting or ending index to scan for addresses. startingScanIndex: -1, endingScanIndex: 19.');
580
- });
581
- it('should throw if scan factor is too high', async () => {
582
- await basecoin
583
- .recoverConsolidations({
584
- userKey: testData.consolidationWrwUser.userKey,
585
- backupKey: testData.consolidationWrwUser.backupKey,
586
- bitgoKey: testData.consolidationWrwUser.bitgoKey,
587
- startingScanIndex: 1,
588
- endingScanIndex: 300,
589
- })
590
- .should.be.rejectedWith('Invalid starting or ending index to scan for addresses. startingScanIndex: 1, endingScanIndex: 300.');
591
- });
592
- });
593
- describe('Recover Transaction Failures:', () => {
594
- const sandBox = sinon.createSandbox();
595
- const destAddr = testData.accounts.account1.address;
596
- const nonce = 123;
597
- beforeEach(function () {
598
- const accountInfoCB = sandBox.stub(src_1.Dot.prototype, 'getAccountInfo');
599
- accountInfoCB.resolves({
600
- nonce: nonce,
601
- freeBalance: 0,
602
- });
603
- });
604
- afterEach(function () {
605
- sandBox.restore();
606
- });
607
- it('should fail to recover due to not finding an address with funds', async function () {
608
- await basecoin
609
- .recover({
610
- userKey: testData.wrwUser.userKey,
611
- backupKey: testData.wrwUser.backupKey,
612
- bitgoKey: testData.wrwUser.bitgoKey,
613
- walletPassphrase: testData.wrwUser.walletPassphrase,
614
- recoveryDestination: destAddr,
615
- })
616
- .should.rejectedWith('Did not find address with funds to recover');
617
- });
618
- });
619
- describe('Verify Transaction', function () {
620
- const address1 = '5Ge59qRnZa8bxyhVFE6BDoY3kuhSrNVETRxXYLty1Hh6XTaf';
621
- const address2 = '5DiMLZugmcKEH3igPZP367FqummZkWeW5Z6zDCHLfxRjnPXe';
622
- it('should reject a txPrebuild with more than one recipient', async function () {
623
- const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
624
- const txParams = {
625
- recipients: [
626
- { amount: '1000000000000', address: address1 },
627
- { amount: '2500000000000', address: address2 },
628
- ],
629
- wallet: wallet,
630
- walletPassphrase: 'fakeWalletPassphrase',
631
- };
632
- const txPrebuild = {
633
- txHex: '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300',
634
- };
635
- await basecoin
636
- .verifyTransaction({ txPrebuild, txParams })
637
- .should.be.rejectedWith(`tdot doesn't support sending to more than 1 destination address within a single transaction. Try again, using only a single recipient.`);
638
- });
639
- it('should reject a txPrebuild with more than invalid amount', async function () {
640
- const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
641
- const txParams = {
642
- recipients: [{ amount: '20000000000', address: '5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD' }],
643
- wallet: wallet,
644
- walletPassphrase: 'fakeWalletPassphrase',
645
- };
646
- const txPrebuild = {
647
- txHex: '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300',
648
- };
649
- await basecoin
650
- .verifyTransaction({ txPrebuild, txParams })
651
- .should.be.rejectedWith(`Recipient amount 20000000000 does not match transaction amount 2000000000000`);
652
- });
653
- it('should reject a txPrebuild with more than invalid recipient', async function () {
654
- const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
655
- const txParams = {
656
- recipients: [{ amount: '2000000000000', address: '5CZh773vKGwKFCUjGc31AwXCbf7TPkavduk2XoujJMjbBD' }],
657
- wallet: wallet,
658
- walletPassphrase: 'fakeWalletPassphrase',
659
- };
660
- const txPrebuild = {
661
- txHex: '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300',
662
- };
663
- await basecoin
664
- .verifyTransaction({ txPrebuild, txParams })
665
- .should.be.rejectedWith(`Recipient address 5CZh773vKGwKFCUjGc31AwXCbf7TPkavduk2XoujJMjbBD does not match transaction destination address 5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD`);
666
- });
667
- it('should accept a txPrebuild with more than valid recipient and amount', async function () {
668
- const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
669
- const txParams = {
670
- recipients: [{ amount: '2000000000000', address: '5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD' }],
671
- wallet: wallet,
672
- walletPassphrase: 'fakeWalletPassphrase',
673
- };
674
- const txPrebuild = {
675
- txHex: '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300',
676
- };
677
- const result = await basecoin.verifyTransaction({ txPrebuild, txParams });
678
- assert.strictEqual(result, true);
679
- });
680
- it('should verify a valid consolidation transaction', async function () {
681
- const mockedWallet = {
682
- coinSpecific: () => ({
683
- baseAddress: '5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD',
684
- }),
685
- };
686
- const txPrebuild = {
687
- txHex: '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300',
688
- };
689
- const result = await basecoin.verifyTransaction({
690
- txPrebuild,
691
- txParams: {},
692
- wallet: mockedWallet,
693
- verification: {
694
- consolidationToBaseAddress: true,
695
- },
696
- });
697
- assert.strictEqual(result, true);
698
- });
699
- it('should reject a consolidation transaction with invalid destination address', async function () {
700
- const mockedWallet = {
701
- coinSpecific: () => ({
702
- baseAddress: '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74',
703
- }),
704
- };
705
- const txPrebuild = {
706
- txHex: '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300',
707
- };
708
- await basecoin
709
- .verifyTransaction({
710
- txPrebuild,
711
- txParams: {},
712
- wallet: mockedWallet,
713
- verification: {
714
- consolidationToBaseAddress: true,
715
- },
716
- })
717
- .should.be.rejectedWith('Transaction destination address 5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD does not match wallet base address 5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74');
718
- });
719
- it('should verify a transferAll (sweep) transaction with empty txParams', async function () {
720
- const mockedWallet = {
721
- coinSpecific: () => ({
722
- baseAddress: '5Ffp1wJCPu4hzVDTo7XaMLqZSvSadyUQmxWPDw74CBjECSoq',
723
- }),
724
- };
725
- // TransferAll tx (sweep) - uses method 0a04 (balances.transferAll)
726
- const txPrebuild = {
727
- txHex: '0x900a04009f7b0675db59d19b4bd9c8c72eaabba75a9863d02b30115b8b3c3ca5c20f025401d50121030000009d880f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9149799bc9602cb5cf201f3425fb8d253b2d4e61fc119dcab3249f307f594754d00',
728
- };
729
- const result = await basecoin.verifyTransaction({
730
- txPrebuild,
731
- txParams: {},
732
- wallet: mockedWallet,
733
- verification: {
734
- consolidationToBaseAddress: true,
735
- },
736
- });
737
- assert.strictEqual(result, true);
738
- });
739
- it('should verify a transferAll (sweep) transaction with recipients in txParams', async function () {
740
- const mockedWallet = {
741
- coinSpecific: () => ({
742
- baseAddress: '5Ffp1wJCPu4hzVDTo7XaMLqZSvSadyUQmxWPDw74CBjECSoq',
743
- }),
744
- };
745
- // TransferAll tx (sweep) - _amount is undefined for these transactions
746
- const txPrebuild = {
747
- txHex: '0x900a04009f7b0675db59d19b4bd9c8c72eaabba75a9863d02b30115b8b3c3ca5c20f025401d50121030000009d880f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9149799bc9602cb5cf201f3425fb8d253b2d4e61fc119dcab3249f307f594754d00',
748
- };
749
- const txParams = {
750
- recipients: [{ address: '5Ffp1wJCPu4hzVDTo7XaMLqZSvSadyUQmxWPDw74CBjECSoq', amount: '1000000000000' }],
751
- };
752
- const result = await basecoin.verifyTransaction({
753
- txPrebuild,
754
- txParams,
755
- wallet: mockedWallet,
756
- verification: {
757
- consolidationToBaseAddress: true,
758
- },
759
- });
760
- assert.strictEqual(result, true);
761
- });
762
- });
763
- describe('isWalletAddress', () => {
764
- it('should verify valid wallet address with correct keychain and index', async function () {
765
- const address = '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74';
766
- const commonKeychain = '6d2d5150f6e435dfd9b4f225f2cc29d95ec3b61b34e8bec98693b1a7ffe44cd764f99ee5058838d785c73360ad4f24d78e0255ab2c368c09060b29a9b27f040e';
767
- const index = '3';
768
- const keychains = [{ id: '1', type: 'tss', commonKeychain }];
769
- const result = await basecoin.isWalletAddress({ keychains, address, index });
770
- result.should.equal(true);
771
- });
772
- it('should return false for address with incorrect keychain', async function () {
773
- const address = '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74';
774
- const wrongKeychain = '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
775
- const index = '3';
776
- const keychains = [{ id: '1', type: 'tss', commonKeychain: wrongKeychain }];
777
- const result = await basecoin.isWalletAddress({ keychains, address, index });
778
- result.should.equal(false);
779
- });
780
- it('should return false for address with incorrect index', async function () {
781
- const address = '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74';
782
- const commonKeychain = '6d2d5150f6e435dfd9b4f225f2cc29d95ec3b61b34e8bec98693b1a7ffe44cd764f99ee5058838d785c73360ad4f24d78e0255ab2c368c09060b29a9b27f040e';
783
- const wrongIndex = '999';
784
- const keychains = [{ id: '1', type: 'tss', commonKeychain }];
785
- const result = await basecoin.isWalletAddress({ keychains, address, index: wrongIndex });
786
- result.should.equal(false);
787
- });
788
- it('should throw error for invalid address', async function () {
789
- const invalidAddress = 'invalidaddress';
790
- const commonKeychain = '6d2d5150f6e435dfd9b4f225f2cc29d95ec3b61b34e8bec98693b1a7ffe44cd764f99ee5058838d785c73360ad4f24d78e0255ab2c368c09060b29a9b27f040e';
791
- const index = '3';
792
- const keychains = [{ id: '1', type: 'tss', commonKeychain }];
793
- await assert.rejects(async () => await basecoin.isWalletAddress({ keychains, address: invalidAddress, index }), {
794
- message: `invalid address: ${invalidAddress}`,
795
- });
796
- });
797
- });
798
- describe('getAddressFromPublicKey', () => {
799
- it('should convert public key to SS58 address for testnet', function () {
800
- const publicKey = '53845d7b6a6e4a666fa2a0f500b88849b02926da5590993731d2b428b7643690';
801
- const expectedAddress = '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74';
802
- const address = basecoin.getAddressFromPublicKey(publicKey);
803
- address.should.equal(expectedAddress);
804
- });
805
- it('should convert public key to SS58 address for mainnet', function () {
806
- const publicKey = '53845d7b6a6e4a666fa2a0f500b88849b02926da5590993731d2b428b7643690';
807
- // Mainnet uses different SS58 prefix (0) vs testnet (42)
808
- const address = prodCoin.getAddressFromPublicKey(publicKey);
809
- address.should.be.type('string');
810
- address.length.should.be.greaterThan(0);
811
- // Should be different from testnet address
812
- address.should.not.equal('5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74');
813
- });
814
- });
815
- });
816
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG90LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2RvdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDRDQUEwQztBQUMxQyw4Q0FBMEQ7QUFDMUQsbUNBQXFDO0FBQ3JDLGlDQUFrQztBQUNsQyxpQ0FBa0M7QUFDbEMsbUNBQStDO0FBQy9DLHNEQUF3QztBQUN4Qyw0Q0FBOEU7QUFDOUUsNkNBQStCO0FBQy9CLDhDQUF5QztBQUV6QyxRQUFRLENBQUMsTUFBTSxFQUFFO0lBQ2YsSUFBSSxLQUFtQixDQUFDO0lBQ3hCLElBQUksUUFBUSxDQUFDO0lBQ2IsSUFBSSxRQUFRLENBQUM7SUFFYixNQUFNLENBQUM7UUFDTCxLQUFLLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsa0JBQVEsRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3RELEtBQUssQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLFNBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUM5QyxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxVQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDaEQsS0FBSyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDM0IsUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDOUIsUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsY0FBYyxFQUFFLEdBQUcsRUFBRTtRQUM1QixFQUFFLENBQUMscUJBQXFCLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDbkMsTUFBTSxPQUFPLEdBQUcsSUFBSSxhQUFPLEVBQUUsQ0FBQztZQUM5QixNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUEs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QUFDO1lBQzVFLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDekYsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVFLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM1RSxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3hGLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNyRixRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3JGLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQzVGLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pGLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUN2RixrREFBa0QsQ0FDbkQsQ0FBQztZQUNGLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQy9HLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ3ZHLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQzdGLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFG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QUFDO1FBRUgsRUFBRSxDQUFDLHVEQUF1RCxFQUFFO1lBQzFELE1BQU0sU0FBUyxHQUFHLGtFQUFrRSxDQUFDO1lBQ3JGLHlEQUF5RDtZQUN6RCxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsdUJBQXVCLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDNUQsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2pDLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEMsMkNBQTJDO1lBQzNDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxrREFBa0QsQ0FBQyxDQUFDO1FBQy9FLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvL3Nkay1hcGknO1xuaW1wb3J0IHsgVGVzdEJpdEdvLCBUZXN0Qml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHsgcmFuZG9tQnl0ZXMgfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHNob3VsZCA9IHJlcXVpcmUoJ3Nob3VsZCcpO1xuaW1wb3J0IGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpO1xuaW1wb3J0IHsgRG90LCBUZG90LCBLZXlQYWlyIH0gZnJvbSAnLi4vLi4vc3JjJztcbmltcG9ydCAqIGFzIHRlc3REYXRhIGZyb20gJy4uL2ZpeHR1cmVzJztcbmltcG9ydCB7IGNoYWluTmFtZSwgdHhWZXJzaW9uLCBnZW5lc2lzSGFzaCwgc3BlY1ZlcnNpb24gfSBmcm9tICcuLi9yZXNvdXJjZXMnO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IHsgV2FsbGV0IH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcblxuZGVzY3JpYmUoJ0RPVDonLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICBsZXQgYmFzZWNvaW47XG4gIGxldCBwcm9kQ29pbjtcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudjogJ21vY2snIH0pO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcignZG90JywgRG90LmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ3Rkb3QnLCBUZG90LmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3Rkb3QnKTtcbiAgICBwcm9kQ29pbiA9IGJpdGdvLmNvaW4oJ2RvdCcpO1xuICB9KTtcblxuICBkZXNjcmliZSgnU2lnbiBNZXNzYWdlJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgYmUgcGVyZm9ybWVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qga2V5UGFpciA9IG5ldyBLZXlQYWlyKCk7XG4gICAgICBjb25zdCBtZXNzYWdlVG9TaWduID0gQnVmZmVyLmZyb20ocmFuZG9tQnl0ZXMoMzIpKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICBjb25zdCBzaWduYXR1cmUgPSBhd2FpdCBiYXNlY29pbi5zaWduTWVzc2FnZShrZXlQYWlyLmdldEtleXMoKSwgbWVzc2FnZVRvU2lnbik7XG4gICAgICBrZXlQYWlyLnZlcmlmeVNpZ25hdHVyZShtZXNzYWdlVG9TaWduLCBVaW50OEFycmF5LmZyb20oc2lnbmF0dXJlKSkuc2hvdWxkLmVxdWFscyh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB3aXRoIG1pc3NpbmcgcHJpdmF0ZSBrZXknLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBrZXlQYWlyID0gbmV3IEtleVBhaXIoe1xuICAgICAgICBwdWI6ICc3Nzg4MzI3YzY5NWRjYTRiM2U2NDlhMGRiNDViYzNlNzAzYTJjNjc0MjhmY2UzNjBlNjE4MDBjYzQyNDhmNGY3JyxcbiAgICAgIH0pLmdldEtleXMoKTtcbiAgICAgIGNvbnN0IG1lc3NhZ2VUb1NpZ24gPSBCdWZmZXIuZnJvbShyYW5kb21CeXRlcygzMikpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGF3YWl0IGJhc2Vjb2luLnNpZ25NZXNzYWdlKGtleVBhaXIsIG1lc3NhZ2VUb1NpZ24pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0ludmFsaWQga2V5IHBhaXIgb3B0aW9ucycpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnU2lnbiB0cmFuc2FjdGlvbicsICgpID0+IHtcbiAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHtcbiAgICAgIGlkOiAnMHgxOWRlMTU2MzI4ZWVhNjZiZDFlYzQ1ODQzNTY5YzE2OGUwYmIyZjI4OTgyMjEwMjliNDAzZGYzZjIzYTU0ODlkJyxcbiAgICAgIHNlbmRlcjogJzVFR29GQTk1b216ZW1Sc3NFTExEalZlbk5aNjhhWHlVZXF0S1FTY1hTRUJ2VkprcicsXG4gICAgICByZWZlcmVuY2VCbG9jazogJzB4MTQ5Nzk5YmM5NjAyY2I1Y2YyMDFmMzQyNWZiOGQyNTNiMmQ0ZTYxZmMxMTlkY2FiMzI0OWYzMDdmNTk0NzU0ZCcsXG4gICAgICBibG9ja051bWJlcjogMzkzMyxcbiAgICAgIGdlbmVzaXNIYXNoOiAnMHg2N2Y5NzIzMzkzZWY3NjIxNGRmMDExOGMzNGJiYmQzZGJlYmM4ZWQ0NmExMDk3M2E4Yzk2OWQ0OGZlNzU5OGM5JyxcbiAgICAgIG5vbmNlOiAyMDAsXG4gICAgICBzcGVjVmVyc2lvbjogMTAxODAxMyxcbiAgICAgIHRyYW5zYWN0aW9uVmVyc2lvbjogMTYsXG4gICAgICBlcmFQZXJpb2Q6IDY0LFxuICAgICAgY2hhaW5OYW1lOiAnV2VzdGVuZCBBc3NldCBIdWInLFxuICAgICAgdGlwOiAwLFxuICAgICAgdG86ICc1RmZwMXdKQ1B1NGh6VkRUbzdYYU1McVpTdlNhZHlVUW14V1BEdzc0Q0JqRUNTb3EnLFxuICAgICAgYW1vdW50OiAnMTAwMDAwMDAwMDAnLFxuICAgIH07XG5cbiAgICAvLyBUT0RPOiBCRy00MzE5N1xuICAgIHhpdCgnc2hvdWxkIHNpZ24gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzaWduZWQgPSBhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgdHhIZXg6IHRlc3REYXRhLnJhd1R4LnRyYW5zZmVyLnVuc2lnbmVkLFxuICAgICAgICAgIHRyYW5zYWN0aW9uLFxuICAgICAgICB9LFxuICAgICAgICBwdWJzOiBbdGVzdERhdGEuYWNjb3VudHMuYWNjb3VudDEucHVibGljS2V5XSxcbiAgICAgICAgcHJ2OiB0ZXN0RGF0YS5hY2NvdW50cy5hY2NvdW50MS5zZWNyZXRLZXksXG4gICAgICB9KTtcbiAgICAgIHNpZ25lZC50eEhleC5zaG91bGQuZXF1YWwodGVzdERhdGEucmF3VHgudHJhbnNmZXIuc2lnbmVkKTtcbiAgICB9KTtcblxuICAgIC8vIFRPRE86IEJHLTQzMTk3XG4gICAgeGl0KCdzaG91bGQgZmFpbCB0byBzaWduIHRyYW5zYWN0aW9uIHdpdGggYW4gaW52YWxpZCBrZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICAgIHR4SGV4OiB0ZXN0RGF0YS5yYXdUeC50cmFuc2Zlci51bnNpZ25lZCxcbiAgICAgICAgICAgIHRyYW5zYWN0aW9uLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcHViczogW3Rlc3REYXRhLmFjY291bnRzLmFjY291bnQyLnB1YmxpY0tleV0sXG4gICAgICAgICAgcHJ2OiB0ZXN0RGF0YS5hY2NvdW50cy5hY2NvdW50MS5zZWNyZXRLZXksXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBzaG91bGQuZXF1YWwoZS5tZXNzYWdlLCAnUHJpdmF0ZSBrZXkgY2Fubm90IHNpZ24gdGhlIHRyYW5zYWN0aW9uJyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gYnVpbGQgdHJhbnNhY3Rpb24gd2l0aCBtaXNzaW5nIHBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgICAgdHhIZXg6IHRlc3REYXRhLnJhd1R4LnRyYW5zZmVyLnVuc2lnbmVkLFxuICAgICAgICAgICAga2V5OiB0ZXN0RGF0YS5hY2NvdW50cy5hY2NvdW50MS5wdWJsaWNLZXksXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwcnY6IHRlc3REYXRhLmFjY291bnRzLmFjY291bnQxLnNlY3JldEtleSxcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHNob3VsZC5ub3RFcXVhbChlLCBudWxsKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0dlbmVyYXRlIHdhbGxldCBrZXkgcGFpcjogJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUga2V5IHBhaXInLCAoKSA9PiB7XG4gICAgICBjb25zdCBrcCA9IGJhc2Vjb2luLmdlbmVyYXRlS2V5UGFpcigpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZFB1YihrcC5wdWIpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQcnYoa3AucHJ2KS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGtleSBwYWlyIGZyb20gc2VlZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHNlZWQgPSBCdWZmZXIuZnJvbSgnOWQ2MWIxOWRlZmZkNWE2MGJhODQ0YWY0OTJlYzJjYzQ0NDQ5YzU2OTdiMzI2OTE5NzAzYmFjMDMxY2FlN2Y2MCcsICdoZXgnKTtcbiAgICAgIGNvbnN0IGtwID0gYmFzZWNvaW4uZ2VuZXJhdGVLZXlQYWlyKHNlZWQpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZFB1YihrcC5wdWIpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQcnYoa3AucHJ2KS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdCYWxhbmNlIENvbnZlcnNpb24nLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gMTAwMDAwMDAwMDAgYXMgdGRvdCBiYXNlIGZhY3RvcicsICgpID0+IHtcbiAgICAgIC8vIG1haW5uZXQgdXNlcyAxMCBkZWNpbWFsIHBsYWNlc1xuICAgICAgY29uc3QgYmFzZUZhY3RvciA9IHByb2RDb2luLmdldEJhc2VGYWN0b3IoKTtcbiAgICAgIGJhc2VGYWN0b3Iuc2hvdWxkLmVxdWFsKDEwMDAwMDAwMDAwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIDEwMDAwMDAwMDAwMDAgYXMgZG90IGJhc2UgZmFjdG9yJywgKCkgPT4ge1xuICAgICAgLy8gd2VzdGVuZCAodGVzdCBwb2xrYWRvdCkgdXNlcyAxMiBkZWNpbWFsIHBsYWNlc1xuICAgICAgY29uc3QgYmFzZUZhY3RvciA9IGJhc2Vjb2luLmdldEJhc2VGYWN0b3IoKTtcbiAgICAgIGJhc2VGYWN0b3Iuc2hvdWxkLmVxdWFsKDEwMDAwMDAwMDAwMDApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gNCBEb3Qgd2hlbiBiYXNlIHVuaXQgaXMgNDAwMDAwMDAwMDAgZm9yIGRvdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGJpZ1VuaXQgPSBwcm9kQ29pbi5iYXNlVW5pdHNUb0JpZ1VuaXRzKCc0MDAwMDAwMDAwMCcpO1xuICAgICAgYmlnVW5pdC5zaG91bGQuZXF1YWwoJzQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIDAuMDQgRG90IHdoZW4gYmFzZSB1bml0IGlzIDQwMDAwMDAwMCBmb3IgZG90JywgKCkgPT4ge1xuICAgICAgY29uc3QgYmlnVW5pdCA9IHByb2RDb2luLmJhc2VVbml0c1RvQmlnVW5pdHMoJzQwMDAwMDAwMCcpO1xuICAgICAgYmlnVW5pdC5zaG91bGQuZXF1YWwoJzAuMDQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIDQgdGVzdCBEb3Qgd2hlbiBiYXNlIHVuaXQgaXMgNDAwMDAwMDAwMDAwMCBmb3IgdGRvdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGJpZ1VuaXQgPSBiYXNlY29pbi5iYXNlVW5pdHNUb0JpZ1VuaXRzKCc0MDAwMDAwMDAwMDAwJyk7XG4gICAgICBiaWdVbml0LnNob3VsZC5lcXVhbCgnNCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gMC4wNCB0ZXN0IERvdCB3aGVuIGJhc2UgdW5pdCBpcyA0MDAwMDAwMDAgZm9yIHRkb3QnLCAoKSA9PiB7XG4gICAgICBjb25zdCBiaWdVbml0ID0gYmFzZWNvaW4uYmFzZVVuaXRzVG9CaWdVbml0cygnNDAwMDAwMDAwMDAnKTtcbiAgICAgIGJpZ1VuaXQuc2hvdWxkLmVxdWFsKCcwLjA0Jyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFeHBsYWluIFRyYW5zYWN0aW9uczonLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGFuIHVuc2lnbmVkIHRyYW5zZmVyIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24odGVzdERhdGEudW5zaWduZWRUcmFuc2FjdGlvbik7XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbXG4gICAgICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAgICAgJ2NoYW5nZUFtb3VudCcsXG4gICAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICAgICAnZmVlJyxcbiAgICAgICAgICAndHlwZScsXG4gICAgICAgICAgJ3NlcXVlbmNlSWQnLFxuICAgICAgICAgICdpZCcsXG4gICAgICAgICAgJ2Jsb2NrTnVtYmVyJyxcbiAgICAgICAgXSxcbiAgICAgICAgc2VxdWVuY2VJZDogMCxcbiAgICAgICAgZmVlOiAnMTAnLFxuICAgICAgICBpZDogJzB4MGU1NzUxYzAyNmU1NDNiMmU4YWIyZWIwNjA5OWRhYTFkMWU1ZGY0Nzc3OGY3Nzg3ZmFhYjQ1Y2RmMTJmZTNhOCcsXG4gICAgICAgIHR5cGU6ICcwJyxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICc1RGtkZFNmUHNXb2pqZnVIOWlKRWNVVjdac2VROUVKNlJqdE5tQ1IxdzNDRWI4UzknLFxuICAgICAgICAgICAgdmFsdWVTdHJpbmc6ICc5MDAzNDIzNTIzNTM1MCcsXG4gICAgICAgICAgICBjb2luTmFtZTogJ3Rkb3QnLFxuICAgICAgICAgICAgd2FsbGV0OiAnNjJhMTIwNTc1MTY3NWIyZjBmZTcyMzI4JyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBibG9ja051bWJlcjogODYxOTMwNyxcbiAgICAgICAgb3V0cHV0QW1vdW50OiA5MDAzNDIzNTIzNTM1MCxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZWNvdmVyIFRyYW5zYWN0aW9uczonLCAoKSA9PiB7XG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICBjb25zdCBkZXN0QWRkciA9IHRlc3REYXRhLmFjY291bnRzLmFjY291bnQxLmFkZHJlc3M7XG4gICAgY29uc3Qgbm9uY2UgPSAxMjM7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFjY291bnRJbmZvQ0IgPSBzYW5kQm94LnN0dWIoRG90LnByb3RvdHlwZSwgJ2dldEFjY291bnRJbmZvJyBhcyBrZXlvZiBEb3QpO1xuICAgICAgYWNjb3VudEluZm9DQi53aXRoQXJncyh0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwKS5yZXNvbHZlcyh7XG4gICAgICAgIG5vbmNlOiBub25jZSxcbiAgICAgICAgZnJlZUJhbGFuY2U6IDg4ODgsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGhlYWRlckluZm9DQiA9IHNhbmRCb3guc3R1YihEb3QucHJvdG90eXBlLCAnZ2V0SGVhZGVySW5mbycgYXMga2V5b2YgRG90KTtcbiAgICAgIGhlYWRlckluZm9DQi5yZXNvbHZlcyh7XG4gICAgICAgIGhlYWRlck51bWJlcjogdGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyLFxuICAgICAgICBoZWFkZXJIYXNoOiB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suaGFzaCxcbiAgICAgIH0pO1xuICAgICAgYWNjb3VudEluZm9DQi53aXRoQXJncygnNUR0ZzJ6S2pWRUw4cDlrZVNNNGRRN25EMjZzVnRNZkNzeXhraHZaWjlmcUJiaHc2JykucmVzb2x2ZXMoe1xuICAgICAgICBub25jZTogMCxcbiAgICAgICAgZnJlZUJhbGFuY2U6IDE1MTAwMDAwMDAwMDAsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGdldEZlZUNCID0gc2FuZEJveC5zdHViKERvdC5wcm90b3R5cGUsICdnZXRGZWUnIGFzIGtleW9mIERvdCk7XG4gICAgICBnZXRGZWVDQi53aXRoQXJncyhkZXN0QWRkciwgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMCwgMTUxMDAwMDAwMDAwMCkucmVzb2x2ZXMoMTU3ODM4MTI4NTYpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNhbmRCb3gucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSB1bnNpZ25lZCBzd2VlcCBjb3JyZWN0bHknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9XG4gICAgICAgICczY2QxNGY1ZDYwNzQ0Mjg3Y2QzYTUwNTEwZTI5NjQ3NDZiNmZlYWFkNGIyMzAwMDg4ZWFhZTYwZDFhMzVmMGFiYzUxODUzNGQ0M2IyNjE0MzcwZDlhMjYzYWFkYjU3ZWRiNWQwYjc4ZjgxNmE1MTljZDU4OTZlNzM1MjkyMGI2Nyc7XG4gICAgICBjb25zdCByZWNvdmVyeURlc3RpbmF0aW9uID0gJzVHUEF2ZU12bURzanhWVDZRMnhpdTVrWVBiRkFtZGViSGFpTlpLMTRGQmFTYUFLaCc7XG5cbiAgICAgIGNvbnN0IHVuc2lnbmVkID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7IGJpdGdvS2V5OiBjb21tb25LZXljaGFpbiwgcmVjb3ZlcnlEZXN0aW5hdGlvbiB9KTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHMuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLndhbGxldENvaW4uc2hvdWxkLmVxdWFsKCd0ZG90Jyk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5ub3QuYmUudW5kZWZpbmVkKCk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNlcmlhbGl6ZWRUeC5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zY2FuSW5kZXguc2hvdWxkLmVxdWFsKDApO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5jb2luLnNob3VsZC5lcXVhbCgndGRvdCcpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaWduYWJsZUhleC5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5kZXJpdmF0aW9uUGF0aC5zaG91bGQuZXF1YWwoJ20vMCcpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC5pbnB1dHMuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHguaW5wdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4LmlucHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChcbiAgICAgICAgJzVEdGcyektqVkVMOHA5a2VTTTRkUTduRDI2c1Z0TWZDc3l4a2h2Wlo5ZnFCYmh3NidcbiAgICAgICk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4LmlucHV0c1swXS52YWx1ZVN0cmluZy5zaG91bGQuZXF1YWwoJzE1MTAwMDAwMDAwMDAnKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHguaW5wdXRzWzBdLnZhbHVlLnNob3VsZC5lcXVhbCgxNTEwMDAwMDAwMDAwKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHgub3V0cHV0cy5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4Lm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwoXG4gICAgICAgICc1R1BBdmVNdm1Ec2p4VlQ2UTJ4aXU1a1lQYkZBbWRlYkhhaU5aSzE0RkJhU2FBS2gnXG4gICAgICApO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC5vdXRwdXRzWzBdLnZhbHVlU3RyaW5nLnNob3VsZC5lcXVhbCgnMTUxMDAwMDAwMDAwMCcpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC5vdXRwdXRzWzBdLmNvaW5OYW1lLnNob3VsZC5lcXVhbCgndGRvdCcpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC50eXBlLnNob3VsZC5lcXVhbCgnJyk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmZlZUluZm8uc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguZmVlSW5mby5mZWUuc2hvdWxkLmVxdWFsKDApO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5mZWVJbmZvLmZlZVN0cmluZy5zaG91bGQuZXF1YWwoJzAnKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguY29pblNwZWNpZmljLnNob3VsZC5ub3QuYmUudW5kZWZpbmVkKCk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpYy5maXJzdFZhbGlkLnNob3VsZC5ub3QuYmUudW5kZWZpbmVkKCk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpYy5tYXhEdXJhdGlvbi5zaG91bGQuZXF1YWwoMjQwMCk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpYy5jb21tb25LZXljaGFpbi5zaG91bGQuZXF1YWwoXG4gICAgICAgICczY2QxNGY1ZDYwNzQ0Mjg3Y2QzYTUwNTEwZTI5NjQ3NDZiNmZlYWFkNGIyMzAwMDg4ZWFhZTYwZDFhMzVmMGFiYzUxODUzNGQ0M2IyNjE0MzcwZDlhMjYzYWFkYjU3ZWRiNWQwYjc4ZjgxNmE1MTljZDU4OTZlNzM1MjkyMGI2NydcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICAvLyBUT0RPKENPSU4tOTE5KTogRml4IGZhaWxpbmcgdGVzdFxuICAgIHhpdCgnc2hvdWxkIHRha2UgT1ZDIG91dHB1dCBhbmQgZ2VuZXJhdGUgYSBzaWduZWQgc3dlZXAgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB0ZXN0RGF0YS5vdmNSZXNwb25zZTtcblxuICAgICAgY29uc3QgcmVjb3ZlcnlUeG4gPSBhd2FpdCBiYXNlY29pbi5jcmVhdGVCcm9hZGNhc3RhYmxlU3dlZXBUcmFuc2FjdGlvbihwYXJhbXMpO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzBdLnNlcmlhbGl6ZWRUeC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcweDJkMDI4NDAwNTBkMWUxMTZjZGIzMmU2MWJhM2VjZTI3NWI2MjBmNTAzZjBjNWFlNGU3NjkwZDlmOWFhN2UwYjUwMzAzOTc2YzAwMDU3YzEzMWNkZTJiZTM5ZjRmZjIzZWViYTExMTM5YzQ2ZGQ4YzZkNjlmZjUxN2FiZWRlMzczODFkOGQyNGYwYmIzMGZkODgwNWIyZTUxYTllMmE3NTMzOGQ3ZmI3ZWRiMjkwYmU5NjM4ZGViZWRiZmMwMDFkMTBiODEzMmJlMGIyYjRhMDQwMDA0MDQwMGJmMDY3OGQzMTJiMmIyYzdlZmZkMmIxZjIxNGVlMTM5MjhkMzM5MzkxZDVmNWY3MDU2NjA4YWEwZDMyYjllZGYwMSdcbiAgICAgICk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMF0uc2NhbkluZGV4LnNob3VsZC5lcXVhbCgwKTtcbiAgICAgIHJlY292ZXJ5VHhuLmxhc3RTY2FuSW5kZXguc2hvdWxkLmVxdWFsKDApO1xuICAgIH0pO1xuXG4gICAgLy8gVE9ETyhDT0lOLTkxOSk6IEZpeCBmYWlsaW5nIHRlc3RcbiAgICB4aXQoJ3Nob3VsZCB0YWtlIGNvbnNvbGlkYXRpb24gT1ZDIG91dHB1dCBhbmQgZ2VuZXJhdGUgbXVsdGlwbGUgc2lnbmVkIHN3ZWVwIHRyYW5zYWN0aW9ucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHRlc3REYXRhLm92Y1Jlc3BvbnNlMjtcblxuICAgICAgY29uc3QgcmVjb3ZlcnlUeG4gPSBhd2FpdCBiYXNlY29pbi5jcmVhdGVCcm9hZGNhc3RhYmxlU3dlZXBUcmFuc2FjdGlvbihwYXJhbXMpO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzBdLnNlcmlhbGl6ZWRUeC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcweDJkMDI4NDAwZjA1M2QxNzczNzFmNDkxOWI3MTAxNzQyMWFhMzQ4NDFhYzg3YzkyNmExNGU4YTdlNzVmMDkyNjkzNjY1Y2I0YTAwOTg3MWZlYjgzODllMTIxOTFiNDYwZWJlYTFmOWUxNzE2YWRhOGEzMWQ5NGFjMDhmNWMxNWNiNWY3YmUyNDY4M2NkZmMzMDBhZTNlNjgwMmM2ZjRiMDQ0ZGQ5MmVhMDNkMTViOTIzOTlhYjQ1ODAzZTQzYmViNWNiZmY1ODJhMDMxYjM3MDAwMDA0MDQwMDUwZDFlMTE2Y2RiMzJlNjFiYTNlY2UyNzViNjIwZjUwM2YwYzVhZTRlNzY5MGQ5ZjlhYTdlMGI1MDMwMzk3NmMwMSdcbiAgICAgICk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMF0uc2NhbkluZGV4LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1sxXS5zZXJpYWxpemVkVHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMHgyZDAyODQwMGNmN2VkOWY1MzYzNzNjOGY4NzRlNzgwYTQyNjllYzFiZDY3OTllZDdkNGE4NTRjNjcwYjBjNzI4MDVmYWM4NzYwMGQxNTNjYmI2ODM3MDZkZGYzMjBmN2IyMjVhZjE0Y2U0YjU5Yjg2OGMwNzQ0MGFlZmE0YzRlMTI5N2U0OWJjZDVmNmVlODRmNjk2YjBjMmU0NTZlMmE3Zjg3NzlhNzhhMmM4MzJkZmI0N2Q1YjI4M2ViYTg0MDhiMDAzYzdkZDAzMWIzNzAwMDAwNDA0MDA1MGQxZTExNmNkYjMyZTYxYmEzZWNlMjc1YjYyMGY1MDNmMGM1YWU0ZTc2OTBkOWY5YWE3ZTBiNTAzMDM5NzZjMDEnXG4gICAgICApO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzFdLnNjYW5JbmRleC5zaG91bGQuZXF1YWwoMik7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMl0uc2VyaWFsaXplZFR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzB4MmQwMjg0MDA5NDgyYWQ3ZTQzYjQwYjdkZjMzODMyNDRkYWFmZWQzMmIzYjlmZDc1NDEwMTZiNWM5MDdmMmQ5MDUyZjg1Zjg2MDBlMjU1Njk4ZDExMDk3N2ZhZjMzZWZiMzMzNmJhOThhZDdlYWEyYTFhOTI2NDg3ZmM2OTZhMjc3NDQyZDQ0MTRiMmE0NDFiYTkyZDU5OGYyYjFmOTZmMTNiMjg3ODVmNWU1NzI5ODQwMzVhNjA4ZDYzYzQ4YmQzNWJhOTU1MDkwZTFiMzcwMDAwMDQwNDAwNTBkMWUxMTZjZGIzMmU2MWJhM2VjZTI3NWI2MjBmNTAzZjBjNWFlNGU3NjkwZDlmOWFhN2UwYjUwMzAzOTc2YzAxJ1xuICAgICAgKTtcbiAgICAgIHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1syXS5zY2FuSW5kZXguc2hvdWxkLmVxdWFsKDMpO1xuICAgICAgcmVjb3ZlcnlUeG4ubGFzdFNjYW5JbmRleC5zaG91bGQuZXF1YWwoMjApO1xuICAgIH0pO1xuXG4gICAgLy8gVE9ETyhDT0lOLTkxOSk6IEZpeCBmYWlsaW5nIHRlc3RcbiAgICB4aXQoJ3Nob3VsZCByZWNvdmVyIGEgdHhuIGZvciBub24tYml0Z28gcmVjb3ZlcmllcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS53cndVc2VyLnVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEud3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS53cndVc2VyLmJpdGdvS2V5LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS53cndVc2VyLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RBZGRyLFxuICAgICAgfSk7XG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICByZXMuc2hvdWxkLmhhc093blByb3BlcnR5KCdzY2FuSW5kZXgnKTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxlZE9uY2UoYmFzZWNvaW4uZ2V0QWNjb3VudEluZm8pO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkT25jZShiYXNlY29pbi5nZXRIZWFkZXJJbmZvKTtcblxuICAgICAgLy8gZGVzZXJpYWxpemUgdGhlIHR4biBhbmQgdmVyaWZ5IHRoZSBmaWVsZHMgYXJlIHdoYXQgd2UgZXhwZWN0XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBiYXNlY29pbi5nZXRCdWlsZGVyKCkuZnJvbShyZXMuc2VyaWFsaXplZFR4KTtcbiAgICAgIC8vIHNvbWUgaW5mb3JtYXRpb24gaXNuJ3QgZGVzZXJpYWxpemVkIGJ5IHRoZSBmcm9tIG1ldGhvZCwgc28gd2Ugd2lsbFxuICAgICAgLy8gc3VwcGx5IGl0IGFnYWluIGluIG9yZGVyIHRvIHJlLWJ1aWxkIHRoZSB0eG5cbiAgICAgIHR4QnVpbGRlclxuICAgICAgICAudmFsaWRpdHkoe1xuICAgICAgICAgIGZpcnN0VmFsaWQ6IHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlcixcbiAgICAgICAgICBtYXhEdXJhdGlvbjogYmFzZWNvaW4uU1dFRVBfVFhOX0RVUkFUSU9OLFxuICAgICAgICB9KVxuICAgICAgICAucmVmZXJlbmNlQmxvY2sodGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uc2VuZGVyLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmJsb2NrTnVtYmVyLCB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucmVmZXJlbmNlQmxvY2ssIHRlc3REYXRhLndlc3RlbmRCbG9jay5oYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmdlbmVzaXNIYXNoLCBnZW5lc2lzSGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5zcGVjVmVyc2lvbiwgc3BlY1ZlcnNpb24pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ubm9uY2UsIG5vbmNlKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnRpcCwgMCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi50cmFuc2FjdGlvblZlcnNpb24sIHR4VmVyc2lvbik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5jaGFpbk5hbWUsIGNoYWluTmFtZSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5lcmFQZXJpb2QsIGJhc2Vjb2luLlNXRUVQX1RYTl9EVVJBVElPTik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgYSB0eG4gZm9yIHVuc2lnbmVkLXN3ZWVwIHJlY292ZXJpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLndyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RBZGRyLFxuICAgICAgfSk7XG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhc093blByb3BlcnR5KCdzZXJpYWxpemVkVHgnKTtcbiAgICAgIHJlcy50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2NhbkluZGV4Jyk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRPbmNlKGJhc2Vjb2luLmdldEFjY291bnRJbmZvKTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxlZE9uY2UoYmFzZWNvaW4uZ2V0SGVhZGVySW5mbyk7XG5cbiAgICAgIC8vIGRlc2VyaWFsaXplIHRoZSB0eG4gYW5kIHZlcmlmeSB0aGUgZmllbGRzIGFyZSB3aGF0IHdlIGV4cGVjdFxuICAgICAgY29uc3QgdHhCdWlsZGVyID0gYmFzZWNvaW4uZ2V0QnVpbGRlcigpLmZyb20ocmVzLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2VyaWFsaXplZFR4KTtcbiAgICAgIC8vIHNvbWUgaW5mb3JtYXRpb24gaXNuJ3QgZGVzZXJpYWxpemVkIGJ5IHRoZSBmcm9tIG1ldGhvZCwgc28gd2Ugd2lsbFxuICAgICAgLy8gc3VwcGx5IGl0IGFnYWluIGluIG9yZGVyIHRvIHJlLWJ1aWxkIHRoZSB0eG5cbiAgICAgIHR4QnVpbGRlclxuICAgICAgICAudmFsaWRpdHkoe1xuICAgICAgICAgIGZpcnN0VmFsaWQ6IHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlcixcbiAgICAgICAgICBtYXhEdXJhdGlvbjogYmFzZWNvaW4uU1dFRVBfVFhOX0RVUkFUSU9OLFxuICAgICAgICB9KVxuICAgICAgICAucmVmZXJlbmNlQmxvY2sodGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpXG4gICAgICAgIC5zZW5kZXIoeyBhZGRyZXNzOiB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwIH0pO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uc2VuZGVyLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmJsb2NrTnVtYmVyLCB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucmVmZXJlbmNlQmxvY2ssIHRlc3REYXRhLndlc3RlbmRCbG9jay5oYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmdlbmVzaXNIYXNoLCBnZW5lc2lzSGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5zcGVjVmVyc2lvbiwgc3BlY1ZlcnNpb24pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ubm9uY2UsIG5vbmNlKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnRpcCwgMCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi50cmFuc2FjdGlvblZlcnNpb24sIHR4VmVyc2lvbik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5jaGFpbk5hbWUsIGNoYWluTmFtZSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5lcmFQZXJpb2QsIGJhc2Vjb2luLlNXRUVQX1RYTl9EVVJBVElPTik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdCdWlsZCBDb25zb2xpZGF0aW9uIFJlY292ZXJpZXM6JywgKCkgPT4ge1xuICAgIGNvbnN0IHNhbmRCb3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgY29uc3QgYmFzZUFkZHIgPSB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci53YWxsZXRBZGRyZXNzMDtcbiAgICBjb25zdCBub25jZSA9IDEyMztcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWNjb3VudEluZm9DQiA9IHNhbmRCb3guc3R1YihEb3QucHJvdG90eXBlLCAnZ2V0QWNjb3VudEluZm8nIGFzIGtleW9mIERvdCk7XG4gICAgICBhY2NvdW50SW5mb0NCLndpdGhBcmdzKHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MxKS5yZXNvbHZlcyh7XG4gICAgICAgIG5vbmNlOiBub25jZSxcbiAgICAgICAgZnJlZUJhbGFuY2U6IDEwMDAwMDAwMDAwLFxuICAgICAgfSk7XG4gICAgICBhY2NvdW50SW5mb0NCLndpdGhBcmdzKHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MyKS5yZXNvbHZlcyh7XG4gICAgICAgIG5vbmNlOiBub25jZSxcbiAgICAgICAgZnJlZUJhbGFuY2U6IDE1MTAwMDAwMDAwMDAsXG4gICAgICB9KTtcbiAgICAgIGFjY291bnRJbmZvQ0Iud2l0aEFyZ3ModGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczMpLnJlc29sdmVzKHtcbiAgICAgICAgbm9uY2U6IG5vbmNlLFxuICAgICAgICBmcmVlQmFsYW5jZTogMTUxMDAwMDAwMDAwMCxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgaGVhZGVySW5mb0NCID0gc2FuZEJveC5zdHViKERvdC5wcm90b3R5cGUsICdnZXRIZWFkZXJJbmZvJyBhcyBrZXlvZiBEb3QpO1xuICAgICAgaGVhZGVySW5mb0NCLnJlc29sdmVzKHtcbiAgICAgICAgaGVhZGVyTnVtYmVyOiB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIsXG4gICAgICAgIGhlYWRlckhhc2g6IHRlc3REYXRhLndlc3RlbmRCbG9jay5oYXNoLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBnZXRGZWVDQiA9IHNhbmRCb3guc3R1YihEb3QucHJvdG90eXBlLCAnZ2V0RmVlJyBhcyBrZXlvZiBEb3QpO1xuICAgICAgZ2V0RmVlQ0Iud2l0aEFyZ3MoYmFzZUFkZHIsIHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MxLCAxMDAwMDAwMDAwMCkucmVzb2x2ZXMoMTU3ODM4MTI4NTYpO1xuICAgICAgZ2V0RmVlQ0Iud2l0aEFyZ3MoYmFzZUFkZHIsIHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MyLCAxNTEwMDAwMDAwMDAwKS5yZXNvbHZlcygxNTc4MzgxMjg1Nik7XG4gICAgICBnZXRGZWVDQi53aXRoQXJncyhiYXNlQWRkciwgdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczMsIDE1MTAwMDAwMDAwMDApLnJlc29sdmVzKDE1NzgzODEyODU2KTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kQm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIC8vIFRPRE8oQ09JTi05MTkpOiBGaXggZmFpbGluZyB0ZXN0XG4gICAgeGl0KCdzaG91bGQgYnVpbGQgc2lnbmVkIGNvbnNvbGlkYXRpb24gcmVjb3ZlcmllcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXJDb25zb2xpZGF0aW9ucyh7XG4gICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLnVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICBiaXRnb0tleTogdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAxLFxuICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDQsXG4gICAgICB9KTtcbiAgICAgIHJlcy5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICByZXMudHJhbnNhY3Rpb25zLmxlbmd0aC5zaG91bGQuZXF1YWwoMik7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRUaHJpY2UoYmFzZWNvaW4uZ2V0QWNjb3VudEluZm8pO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkVHdpY2UoYmFzZWNvaW4uZ2V0SGVhZGVySW5mbyk7XG5cbiAgICAgIGNvbnN0IHR4bjEgPSByZXMudHJhbnNhY3Rpb25zWzBdO1xuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NjYW5JbmRleCcpO1xuICAgICAgdHhuMS5zY2FuSW5kZXguc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgLy8gZGVzZXJpYWxpemUgdGhlIHR4biBhbmQgdmVyaWZ5IHRoZSBmaWVsZHMgYXJlIHdoYXQgd2UgZXhwZWN0XG4gICAgICBjb25zdCB0eEJ1aWxkZXIxID0gYmFzZWNvaW4uZ2V0QnVpbGRlcigpLmZyb20odHhuMS5zZXJpYWxpemVkVHgpO1xuICAgICAgLy8gc29tZSBpbmZvcm1hdGlvbiBpc24ndCBkZXNlcmlhbGl6ZWQgYnkgdGhlIGZyb20gbWV0aG9kLCBzbyB3ZSB3aWxsXG4gICAgICAvLyBzdXBwbHkgaXQgYWdhaW4gaW4gb3JkZXIgdG8gcmUtYnVpbGQgdGhlIHR4blxuICAgICAgdHhCdWlsZGVyMVxuICAgICAgICAudmFsaWRpdHkoe1xuICAgICAgICAgIGZpcnN0VmFsaWQ6IHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlcixcbiAgICAgICAgICBtYXhEdXJhdGlvbjogYmFzZWNvaW4uTUFYX1ZBTElESVRZX0RVUkFUSU9OLFxuICAgICAgICB9KVxuICAgICAgICAucmVmZXJlbmNlQmxvY2sodGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpO1xuICAgICAgY29uc3QgdHgxID0gYXdhaXQgdHhCdWlsZGVyMS5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uMSA9IHR4MS50b0pzb24oKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5zZW5kZXIsIHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MyKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5ibG9ja051bWJlciwgdGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5yZWZlcmVuY2VCbG9jaywgdGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLmdlbmVzaXNIYXNoLCBnZW5lc2lzSGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEuc3BlY1ZlcnNpb24sIHNwZWNWZXJzaW9uKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5ub25jZSwgbm9uY2UpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLnRpcCwgMCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEudHJhbnNhY3Rpb25WZXJzaW9uLCB0eFZlcnNpb24pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLmNoYWluTmFtZSwgY2hhaW5OYW1lKTtcbiAgICAgIC8vIGVyYVBlcmlvZCB3aWxsIGFsd2F5cyByb3VuZCB0byB0aGUgbmV4dCB1cHBlciBwb3dlciBvZiAyIGZvciBhbnkgaW5wdXQgdmFsdWUsIGluIHRoaXMgY2FzZSAyNDAwLlxuICAgICAgLy8gNDA5NiBpcyB0aGUgXCJoaWdoZXN0XCIgdmFsdWUgeW91IGNhbiBzZXQsIGJ1dCB0aGUgdHhuIHN0aWxsIG1heSBmYWlsIGFmdGVyIDI0MDAgYmxvY2tzLlxuICAgICAgY29uc3QgZXJhUGVyaW9kID0gNDA5NjtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5lcmFQZXJpb2QsIGVyYVBlcmlvZCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEudG8sIGJhc2VBZGRyKTtcblxuICAgICAgcmVzLmxhc3RTY2FuSW5kZXguc2hvdWxkLmVxdWFsKDMpO1xuICAgICAgY29uc3QgdHhuMiA9IHJlcy50cmFuc2FjdGlvbnNbMV07XG4gICAgICB0eG4yLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICB0eG4yLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2NhbkluZGV4Jyk7XG4gICAgICB0eG4yLnNjYW5JbmRleC5zaG91bGQuZXF1YWwoMyk7XG4gICAgICAvLyBkZXNlcmlhbGl6ZSB0aGUgdHhuIGFuZCB2ZXJpZnkgdGhlIGZpZWxkcyBhcmUgd2hhdCB3ZSBleHBlY3RcbiAgICAgIGNvbnN0IHR4QnVpbGRlcjIgPSBiYXNlY29pbi5nZXRCdWlsZGVyKCkuZnJvbSh0eG4yLnNlcmlhbGl6ZWRUeCk7XG4gICAgICAvLyBzb21lIGluZm9ybWF0aW9uIGlzbid0IGRlc2VyaWFsaXplZCBieSB0aGUgZnJvbSBtZXRob2QsIHNvIHdlIHdpbGxcbiAgICAgIC8vIHN1cHBseSBpdCBhZ2FpbiBpbiBvcmRlciB0byByZS1idWlsZCB0aGUgdHhuXG4gICAgICB0eEJ1aWxkZXIyXG4gICAgICAgIC52YWxpZGl0eSh7XG4gICAgICAgICAgZmlyc3RWYWxpZDogdGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyLFxuICAgICAgICAgIG1heER1cmF0aW9uOiBiYXNlY29pbi5NQVhfVkFMSURJVFlfRFVSQVRJT04sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZWZlcmVuY2VCbG9jayh0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suaGFzaCk7XG4gICAgICBjb25zdCB0eDIgPSBhd2FpdCB0eEJ1aWxkZXIyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eEpzb24yID0gdHgyLnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLnNlbmRlciwgdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczMpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLmJsb2NrTnVtYmVyLCB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLnJlZmVyZW5jZUJsb2NrLCB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suaGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIuZ2VuZXNpc0hhc2gsIGdlbmVzaXNIYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5zcGVjVmVyc2lvbiwgc3BlY1ZlcnNpb24pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLm5vbmNlLCBub25jZSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIudGlwLCAwKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi50cmFuc2FjdGlvblZlcnNpb24sIHR4VmVyc2lvbik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIuY2hhaW5OYW1lLCBjaGFpbk5hbWUpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLmVyYVBlcmlvZCwgZXJhUGVyaW9kKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi50bywgYmFzZUFkZHIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBidWlsZCB1bnNpZ25lZCBjb25zb2xpZGF0aW9uIHJlY292ZXJpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyQ29uc29saWRhdGlvbnMoe1xuICAgICAgICBiaXRnb0tleTogdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAxLFxuICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDQsXG4gICAgICB9KTtcbiAgICAgIHJlcy5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICByZXMudHhSZXF1ZXN0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkVGhyaWNlKGJhc2Vjb2luLmdldEFjY291bnRJbmZvKTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxlZFR3aWNlKGJhc2Vjb2luLmdldEhlYWRlckluZm8pO1xuXG4gICAgICBjb25zdCB0eG4xID0gcmVzLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHg7XG4gICAgICB0eG4xLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICB0eG4xLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2lnbmFibGVIZXgnKTtcbiAgICAgIHR4bjEuc2hvdWxkLmhhc093blByb3BlcnR5KCdzY2FuSW5kZXgnKTtcbiAgICAgIHR4bjEuc2NhbkluZGV4LnNob3VsZC5lcXVhbCgyKTtcbiAgICAgIHR4bjEuc2hvdWxkLmhhc093blByb3BlcnR5KCdjb2luJyk7XG4gICAgICB0eG4xLmNvaW4uc2hvdWxkLmVxdWFsKCd0ZG90Jyk7XG4gICAgICB0eG4xLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnZGVyaXZhdGlvblBhdGgnKTtcbiAgICAgIHR4bjEuZGVyaXZhdGlvblBhdGguc2hvdWxkLmVxdWFsKCdtLzInKTtcblxuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2NvaW5TcGVjaWZpYycpO1xuICAgICAgY29uc3QgY29pblNwZWNpZmljMSA9IHR4bjEuY29pblNwZWNpZmljO1xuICAgICAgY29pblNwZWNpZmljMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2NvbW1vbktleWNoYWluJyk7XG4gICAgICBjb2luU3BlY2lmaWMxLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnZmlyc3RWYWxpZCcpO1xuICAgICAgY29pblNwZWNpZmljMS5maXJzdFZhbGlkLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIpO1xuICAgICAgY29pblNwZWNpZmljMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ21heER1cmF0aW9uJyk7XG4gICAgICBjb2luU3BlY2lmaWMxLm1heER1cmF0aW9uLnNob3VsZC5lcXVhbChiYXNlY29pbi5NQVhfVkFMSURJVFlfRFVSQVRJT04pO1xuXG4gICAgICAvLyBkZXNlcmlhbGl6ZSB0aGUgdHhuIGFuZCB2ZXJpZnkgdGhlIGZpZWxkcyBhcmUgd2hhdCB3ZSBleHBlY3RcbiAgICAgIGNvbnN0IHR4QnVpbGRlcjEgPSBiYXNlY29pbi5nZXRCdWlsZGVyKCkuZnJvbSh0eG4xLnNlcmlhbGl6ZWRUeCk7XG4gICAgICAvLyBzb21lIGluZm9ybWF0aW9uIGlzbid0IGRlc2VyaWFsaXplZCBieSB0aGUgZnJvbSBtZXRob2QsIHNvIHdlIHdpbGxcbiAgICAgIC8vIHN1cHBseSBpdCBhZ2FpbiBpbiBvcmRlciB0byByZS1idWlsZCB0aGUgdHhuXG4gICAgICB0eEJ1aWxkZXIxXG4gICAgICAgIC52YWxpZGl0eSh7XG4gICAgICAgICAgZmlyc3RWYWxpZDogdGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyLFxuICAgICAgICAgIG1heER1cmF0aW9uOiBiYXNlY29pbi5NQVhfVkFMSURJVFlfRFVSQVRJT04sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZWZlcmVuY2VCbG9jayh0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suaGFzaClcbiAgICAgICAgLnNlbmRlcih7IGFkZHJlc3M6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MyIH0pO1xuICAgICAgY29uc3QgdHgxID0gYXdhaXQgdHhCdWlsZGVyMS5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uMSA9IHR4MS50b0pzb24oKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5zZW5kZXIsIHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MyKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5ibG9ja051bWJlciwgdGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5yZWZlcmVuY2VCbG9jaywgdGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLmdlbmVzaXNIYXNoLCBnZW5lc2lzSGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEuc3BlY1ZlcnNpb24sIHNwZWNWZXJzaW9uKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5ub25jZSwgbm9uY2UpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLnRpcCwgMCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEudHJhbnNhY3Rpb25WZXJzaW9uLCB0eFZlcnNpb24pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLmNoYWluTmFtZSwgY2hhaW5OYW1lKTtcbiAgICAgIC8vIGVyYVBlcmlvZCB3aWxsIGFsd2F5cyByb3VuZCB0byB0aGUgbmV4dCB1cHBlciBwb3dlciBvZiAyIGZvciBhbnkgaW5wdXQgdmFsdWUsIGluIHRoaXMgY2FzZSAyNDAwLlxuICAgICAgLy8gNDA5NiBpcyB0aGUgXCJoaWdoZXN0XCIgdmFsdWUgeW91IGNhbiBzZXQsIGJ1dCB0aGUgdHhuIHN0aWxsIG1heSBmYWlsIGFmdGVyIDI0MDAgYmxvY2tzLlxuICAgICAgY29uc3QgZXJhUGVyaW9kID0gNDA5NjtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5lcmFQZXJpb2QsIGVyYVBlcmlvZCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEudG8sIGJhc2VBZGRyKTtcblxuICAgICAgY29uc3QgdHhuMiA9IHJlcy50eFJlcXVlc3RzWzFdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4O1xuICAgICAgdHhuMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgdHhuMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NpZ25hYmxlSGV4Jyk7XG4gICAgICB0eG4yLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2NhbkluZGV4Jyk7XG4gICAgICB0eG4yLnNjYW5JbmRleC5zaG91bGQuZXF1YWwoMyk7XG4gICAgICB0eG4yLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnY29pbicpO1xuICAgICAgdHhuMi5jb2luLnNob3VsZC5lcXVhbCgndGRvdCcpO1xuICAgICAgdHhuMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2Rlcml2YXRpb25QYXRoJyk7XG4gICAgICB0eG4yLmRlcml2YXRpb25QYXRoLnNob3VsZC5lcXVhbCgnbS8zJyk7XG5cbiAgICAgIHR4bjIuc2hvdWxkLmhhc093blByb3BlcnR5KCdjb2luU3BlY2lmaWMnKTtcbiAgICAgIGNvbnN0IGNvaW5TcGVjaWZpYzIgPSB0eG4yLmNvaW5TcGVjaWZpYztcbiAgICAgIGNvaW5TcGVjaWZpYzIuc2hvdWxkLmhhc093blByb3BlcnR5KCdjb21tb25LZXljaGFpbicpO1xuICAgICAgY29pblNwZWNpZmljMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2ZpcnN0VmFsaWQnKTtcbiAgICAgIGNvaW5TcGVjaWZpYzIuZmlyc3RWYWxpZC5zaG91bGQuZXF1YWwodGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyKTtcbiAgICAgIGNvaW5TcGVjaWZpYzIuc2hvdWxkLmhhc093blByb3BlcnR5KCdtYXhEdXJhdGlvbicpO1xuICAgICAgY29pblNwZWNpZmljMi5tYXhEdXJhdGlvbi5zaG91bGQuZXF1YWwoYmFzZWNvaW4uTUFYX1ZBTElESVRZX0RVUkFUSU9OKTtcbiAgICAgIGNvaW5TcGVjaWZpYzIuc2hvdWxkLmhhc093blByb3BlcnR5KCdjb21tb25LZXljaGFpbicpO1xuICAgICAgY29pblNwZWNpZmljMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2xhc3RTY2FuSW5kZXgnKTtcbiAgICAgIGNvaW5TcGVjaWZpYzIubGFzdFNjYW5JbmRleC5zaG91bGQuZXF1YWwoMyk7XG5cbiAgICAgIC8vIGRlc2VyaWFsaXplIHRoZSB0eG4gYW5kIHZlcmlmeSB0aGUgZmllbGRzIGFyZSB3aGF0IHdlIGV4cGVjdFxuICAgICAgY29uc3QgdHhCdWlsZGVyMiA9IGJhc2Vjb2luLmdldEJ1aWxkZXIoKS5mcm9tKHR4bjIuc2VyaWFsaXplZFR4KTtcbiAgICAgIC8vIHNvbWUgaW5mb3JtYXRpb24gaXNuJ3QgZGVzZXJpYWxpemVkIGJ5IHRoZSBmcm9tIG1ldGhvZCwgc28gd2Ugd2lsbFxuICAgICAgLy8gc3VwcGx5IGl0IGFnYWluIGluIG9yZGVyIHRvIHJlLWJ1aWxkIHRoZSB0eG5cbiAgICAgIHR4QnVpbGRlcjJcbiAgICAgICAgLnZhbGlkaXR5KHtcbiAgICAgICAgICBmaXJzdFZhbGlkOiB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIsXG4gICAgICAgICAgbWF4RHVyYXRpb246IGJhc2Vjb2luLk1BWF9WQUxJRElUWV9EVVJBVElPTixcbiAgICAgICAgfSlcbiAgICAgICAgLnJlZmVyZW5jZUJsb2NrKHRlc3REYXRhLndlc3RlbmRCbG9jay5oYXNoKVxuICAgICAgICAuc2VuZGVyKHsgYWRkcmVzczogdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczMgfSk7XG4gICAgICBjb25zdCB0eDIgPSBhd2FpdCB0eEJ1aWxkZXIyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eEpzb24yID0gdHgyLnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLnNlbmRlciwgdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczMpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLmJsb2NrTnVtYmVyLCB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLnJlZmVyZW5jZUJsb2NrLCB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suaGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIuZ2VuZXNpc0hhc2gsIGdlbmVzaXNIYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5zcGVjVmVyc2lvbiwgc3BlY1ZlcnNpb24pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLm5vbmNlLCBub25jZSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIudGlwLCAwKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi50cmFuc2FjdGlvblZlcnNpb24sIHR4VmVyc2lvbik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIuY2hhaW5OYW1lLCBjaGFpbk5hbWUpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLmVyYVBlcmlvZCwgZXJhUGVyaW9kKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi50bywgYmFzZUFkZHIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBza2lwIGJ1aWxkaW5nIGNvbnNvbGlkYXRlIHRyYW5zYWN0aW9uIGlmIGJhbGFuY2UgaXMgZXF1YWwgdG8gemVybycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyQ29uc29saWRhdGlvbnMoe1xuICAgICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLnVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLmJpdGdvS2V5LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgc3RhcnRpbmdTY2FuSW5kZXg6IDEsXG4gICAgICAgICAgZW5kaW5nU2NhbkluZGV4OiAyLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnRGlkIG5vdCBmaW5kIGFuIGFkZHJlc3Mgd2l0aCBmdW5kcyB0byByZWNvdmVyJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIHN0YXJ0aW5nU2NhbkluZGV4IGlzIG5vdCBnZSB0byAxJywgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXJDb25zb2xpZGF0aW9ucyh7XG4gICAgICAgICAgdXNlcktleTogdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIudXNlcktleSxcbiAgICAgICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgICBiaXRnb0tleTogdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIuYml0Z29LZXksXG4gICAgICAgICAgc3RhcnRpbmdTY2FuSW5kZXg6IC0xLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnSW52YWxpZCBzdGFydGluZyBvciBlbmRpbmcgaW5kZXggdG8gc2NhbiBmb3IgYWRkcmVzc2VzLiBzdGFydGluZ1NjYW5JbmRleDogLTEsIGVuZGluZ1NjYW5JbmRleDogMTkuJ1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiBzY2FuIGZhY3RvciBpcyB0b28gaGlnaCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyQ29uc29saWRhdGlvbnMoe1xuICAgICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLnVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLmJpdGdvS2V5LFxuICAgICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAxLFxuICAgICAgICAgIGVuZGluZ1NjYW5JbmRleDogMzAwLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnSW52YWxpZCBzdGFydGluZyBvciBlbmRpbmcgaW5kZXggdG8gc2NhbiBmb3IgYWRkcmVzc2VzLiBzdGFydGluZ1NjYW5JbmRleDogMSwgZW5kaW5nU2NhbkluZGV4OiAzMDAuJ1xuICAgICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUmVjb3ZlciBUcmFuc2FjdGlvbiBGYWlsdXJlczonLCAoKSA9PiB7XG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICBjb25zdCBkZXN0QWRkciA9IHRlc3REYXRhLmFjY291bnRzLmFjY291bnQxLmFkZHJlc3M7XG4gICAgY29uc3Qgbm9uY2UgPSAxMjM7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFjY291bnRJbmZvQ0IgPSBzYW5kQm94LnN0dWIoRG90LnByb3RvdHlwZSwgJ2dldEFjY291bnRJbmZvJyBhcyBrZXlvZiBEb3QpO1xuICAgICAgYWNjb3VudEluZm9DQi5yZXNvbHZlcyh7XG4gICAgICAgIG5vbmNlOiBub25jZSxcbiAgICAgICAgZnJlZUJhbGFuY2U6IDAsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kQm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byByZWNvdmVyIGR1ZSB0byBub3QgZmluZGluZyBhbiBhZGRyZXNzIHdpdGggZnVuZHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3Zlcih7XG4gICAgICAgICAgdXNlcktleTogdGVzdERhdGEud3J3VXNlci51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEud3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLndyd1VzZXIuYml0Z29LZXksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEud3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RBZGRyLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnRGlkIG5vdCBmaW5kIGFkZHJlc3Mgd2l0aCBmdW5kcyB0byByZWNvdmVyJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdWZXJpZnkgVHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgYWRkcmVzczEgPSAnNUdlNTlxUm5aYThieHloVkZFNkJEb1kza3VoU3JOVkVUUnhYWUx0eTFIaDZYVGFmJztcbiAgICBjb25zdCBhZGRyZXNzMiA9ICc1RGlNTFp1Z21jS0VIM2lnUFpQMzY3RnF1bW1aa1dlVzVaNnpEQ0hMZnhSam5QWGUnO1xuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgdHhQcmVidWlsZCB3aXRoIG1vcmUgdGhhbiBvbmUgcmVjaXBpZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9LFxuICAgICAgICAgIHsgYW1vdW50OiAnMjUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6XG4gICAgICAgICAgJzB4YTgwYTAzMDAxNjFiOTY5YjZiNTNlZjgxMjI1ZmVlYTM4ODIyODRjNzc4Y2Q0YTQwNmQyMzIxNWZjZjQ5MmU4M2Y3NWQ0Mjk2MGIwMDIwNGFhOWQxMDFlYjYwMDQwMDAwMDA2NTkwMGYwMDEwMDAwMDAwNjdmOTcyMzM5M2VmNzYyMTRkZjAxMThjMzRiYmJkM2RiZWJjOGVkNDZhMTA5NzNhOGM5NjlkNDhmZTc1OThjOWE3Yjc0MjBlZTNlNGZlMmI4OGRhMGZjNDJiMzA4OTdlMThkNTZkOGI1NmExOTM0MjExZDlkZTczMGNmOTZkZTMwMCcsXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFByZWJ1aWxkLCB0eFBhcmFtcyB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICBgdGRvdCBkb2Vzbid0IHN1cHBvcnQgc2VuZGluZyB0byBtb3JlIHRoYW4gMSBkZXN0aW5hdGlvbiBhZGRyZXNzIHdpdGhpbiBhIHNpbmdsZSB0cmFuc2FjdGlvbi4gVHJ5IGFnYWluLCB1c2luZyBvbmx5IGEgc2luZ2xlIHJlY2lwaWVudC5gXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIHR4UHJlYnVpbGQgd2l0aCBtb3JlIHRoYW4gaW52YWxpZCBhbW91bnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwge30pO1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzIwMDAwMDAwMDAwJywgYWRkcmVzczogJzVDWmg3NzN2S0d3S0ZDWVVqR2MzMUF3WENiZjdUUGthdmRldWsyWG91akpNamJCRCcgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OlxuICAgICAgICAgICcweGE4MGEwMzAwMTYxYjk2OWI2YjUzZWY4MTIyNWZlZWEzODgyMjg0Yzc3OGNkNGE0MDZkMjMyMTVmY2Y0OTJlODNmNzVkNDI5NjBiMDAyMDRhYTlkMTAxZWI2MDA0MDAwMDAwNjU5MDBmMDAxMDAwMDAwMDY3Zjk3MjMzOTNlZjc2MjE0ZGYwMTE4YzM0YmJiZDNkYmViYzhlZDQ2YTEwOTczYThjOTY5ZDQ4ZmU3NTk4YzlhN2I3NDIwZWUzZTRmZTJiODhkYTBmYzQyYjMwODk3ZTE4ZDU2ZDhiNTZhMTkzNDIxMWQ5ZGU3MzBjZjk2ZGUzMDAnLFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQcmVidWlsZCwgdHhQYXJhbXMgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoYFJlY2lwaWVudCBhbW91bnQgMjAwMDAwMDAwMDAgZG9lcyBub3QgbWF0Y2ggdHJhbnNhY3Rpb24gYW1vdW50IDIwMDAwMDAwMDAwMDBgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgdHhQcmVidWlsZCB3aXRoIG1vcmUgdGhhbiBpbnZhbGlkIHJlY2lwaWVudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB7fSk7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMjAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6ICc1Q1poNzczdktHd0tGQ1VqR2MzMUF3WENiZjdUUGthdmR1azJYb3VqSk1qYkJEJyB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6XG4gICAgICAgICAgJzB4YTgwYTAzMDAxNjFiOTY5YjZiNTNlZjgxMjI1ZmVlYTM4ODIyODRjNzc4Y2Q0YTQwNmQyMzIxNWZjZjQ5MmU4M2Y3NWQ0Mjk2MGIwMDIwNGFhOWQxMDFlYjYwMDQwMDAwMDA2NTkwMGYwMDEwMDAwMDAwNjdmOTcyMzM5M2VmNzYyMTRkZjAxMThjMzRiYmJkM2RiZWJjOGVkNDZhMTA5NzNhOGM5NjlkNDhmZTc1OThjOWE3Yjc0MjBlZTNlNGZlMmI4OGRhMGZjNDJiMzA4OTdlMThkNTZkOGI1NmExOTM0MjExZDlkZTczMGNmOTZkZTMwMCcsXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFByZWJ1aWxkLCB0eFBhcmFtcyB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICBgUmVjaXBpZW50IGFkZHJlc3MgNUNaaDc3M3ZLR3dLRkNVakdjMzFBd1hDYmY3VFBrYXZkdWsyWG91akpNamJCRCBkb2VzIG5vdCBtYXRjaCB0cmFuc2FjdGlvbiBkZXN0aW5hdGlvbiBhZGRyZXNzIDVDWmg3NzN2S0d3S0ZDWVVqR2MzMUF3WENiZjdUUGthdmRldWsyWG91akpNamJCRGBcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYWNjZXB0IGEgdHhQcmVidWlsZCB3aXRoIG1vcmUgdGhhbiB2YWxpZCByZWNpcGllbnQgYW5kIGFtb3VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB7fSk7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMjAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6ICc1Q1poNzczdktHd0tGQ1lVakdjMzFBd1hDYmY3VFBrYXZkZXVrMlhvdWpKTWpiQkQnIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEhleDpcbiAgICAgICAgICAnMHhhODBhMDMwMDE2MWI5NjliNmI1M2VmODEyMjVmZWVhMzg4MjI4NGM3NzhjZDRhNDA2ZDIzMjE1ZmNmNDkyZTgzZjc1ZDQyOTYwYjAwMjA0YWE5ZDEwMWViNjAwNDAwMDAwMDY1OTAwZjAwMTAwMDAwMDA2N2Y5NzIzMzkzZWY3NjIxNGRmMDExOGMzNGJiYmQzZGJlYmM4ZWQ0NmExMDk3M2E4Yzk2OWQ0OGZlNzU5OGM5YTdiNzQyMGVlM2U0ZmUyYjg4ZGEwZmM0MmIzMDg5N2UxOGQ1NmQ4YjU2YTE5MzQyMTFkOWRlNzMwY2Y5NmRlMzAwJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQcmVidWlsZCwgdHhQYXJhbXMgfSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgdmFsaWQgY29uc29saWRhdGlvbiB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1vY2tlZFdhbGxldCA9IHtcbiAgICAgICAgY29pblNwZWNpZmljOiAoKSA9PiAoe1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiAnNUNaaDc3M3ZLR3dLRkNZVWpHYzMxQXdYQ2JmN1RQa2F2ZGV1azJYb3VqSk1qYkJEJyxcbiAgICAgICAgfSksXG4gICAgICB9O1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6XG4gICAgICAgICAgJzB4YTgwYTAzMDAxNjFiOTY5YjZiNTNlZjgxMjI1ZmVlYTM4ODIyODRjNzc4Y2Q0YTQwNmQyMzIxNWZjZjQ5MmU4M2Y3NWQ0Mjk2MGIwMDIwNGFhOWQxMDFlYjYwMDQwMDAwMDA2NTkwMGYwMDEwMDAwMDAwNjdmOTcyMzM5M2VmNzYyMTRkZjAxMThjMzRiYmJkM2RiZWJjOGVkNDZhMTA5NzNhOGM5NjlkNDhmZTc1OThjOWE3Yjc0MjBlZTNlNGZlMmI4OGRhMGZjNDJiMzA4OTdlMThkNTZkOGI1NmExOTM0MjExZDlkZTczMGNmOTZkZTMwMCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgIHR4UGFyYW1zOiB7fSxcbiAgICAgICAgd2FsbGV0OiBtb2NrZWRXYWxsZXQgYXMgYW55LFxuICAgICAgICB2ZXJpZmljYXRpb246IHtcbiAgICAgICAgICBjb25zb2xpZGF0aW9uVG9CYXNlQWRkcmVzczogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIGNvbnNvbGlkYXRpb24gdHJhbnNhY3Rpb24gd2l0aCBpbnZhbGlkIGRlc3RpbmF0aW9uIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtb2NrZWRXYWxsZXQgPSB7XG4gICAgICAgIGNvaW5TcGVjaWZpYzogKCkgPT4gKHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzVEeEQ5blQxNkdRTHJVNmFCNXBTUzVWdHhvWmJWanUzTkhVQ2Nhd3haeVpDVGY3NCcsXG4gICAgICAgIH0pLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OlxuICAgICAgICAgICcweGE4MGEwMzAwMTYxYjk2OWI2YjUzZWY4MTIyNWZlZWEzODgyMjg0Yzc3OGNkNGE0MDZkMjMyMTVmY2Y0OTJlODNmNzVkNDI5NjBiMDAyMDRhYTlkMTAxZWI2MDA0MDAwMDAwNjU5MDBmMDAxMDAwMDAwMDY3Zjk3MjMzOTNlZjc2MjE0ZGYwMTE4YzM0YmJiZDNkYmViYzhlZDQ2YTEwOTczYThjOTY5ZDQ4ZmU3NTk4YzlhN2I3NDIwZWUzZTRmZTJiODhkYTBmYzQyYjMwODk3ZTE4ZDU2ZDhiNTZhMTkzNDIxMWQ5ZGU3MzBjZjk2ZGUzMDAnLFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICAgIHR4UGFyYW1zOiB7fSxcbiAgICAgICAgICB3YWxsZXQ6IG1vY2tlZFdhbGxldCBhcyBhbnksXG4gICAgICAgICAgdmVyaWZpY2F0aW9uOiB7XG4gICAgICAgICAgICBjb25zb2xpZGF0aW9uVG9CYXNlQWRkcmVzczogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnVHJhbnNhY3Rpb24gZGVzdGluYXRpb24gYWRkcmVzcyA1Q1poNzczdktHd0tGQ1lVakdjMzFBd1hDYmY3VFBrYXZkZXVrMlhvdWpKTWpiQkQgZG9lcyBub3QgbWF0Y2ggd2FsbGV0IGJhc2UgYWRkcmVzcyA1RHhEOW5UMTZHUUxyVTZhQjVwU1M1VnR4b1piVmp1M05IVUNjYXd4WnlaQ1RmNzQnXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIHRyYW5zZmVyQWxsIChzd2VlcCkgdHJhbnNhY3Rpb24gd2l0aCBlbXB0eSB0eFBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1vY2tlZFdhbGxldCA9IHtcbiAgICAgICAgY29pblNwZWNpZmljOiAoKSA9PiAoe1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiAnNUZmcDF3SkNQdTRoelZEVG83WGFNTHFaU3ZTYWR5VVFteFdQRHc3NENCakVDU29xJyxcbiAgICAgICAgfSksXG4gICAgICB9O1xuXG4gICAgICAvLyBUcmFuc2ZlckFsbCB0eCAoc3dlZXApIC0gdXNlcyBtZXRob2QgMGEwNCAoYmFsYW5jZXMudHJhbnNmZXJBbGwpXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEhleDpcbiAgICAgICAgICAnMHg5MDBhMDQwMDlmN2IwNjc1ZGI1OWQxOWI0YmQ5YzhjNzJlYWFiYmE3NWE5ODYzZDAyYjMwMTE1YjhiM2MzY2E1YzIwZjAyNTQwMWQ1MDEyMTAzMDAwMDAwOWQ4ODBmMDAxMDAwMDAwMDY3Zjk3MjMzOTNlZjc2MjE0ZGYwMTE4YzM0YmJiZDNkYmViYzhlZDQ2YTEwOTczYThjOTY5ZDQ4ZmU3NTk4YzkxNDk3OTliYzk2MDJjYjVjZjIwMWYzNDI1ZmI4ZDI1M2IyZDRlNjFmYzExOWRjYWIzMjQ5ZjMwN2Y1OTQ3NTRkMDAnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICB0eFBhcmFtczoge30sXG4gICAgICAgIHdhbGxldDogbW9ja2VkV2FsbGV0IGFzIGFueSxcbiAgICAgICAgdmVyaWZpY2F0aW9uOiB7XG4gICAgICAgICAgY29uc29saWRhdGlvblRvQmFzZUFkZHJlc3M6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQsIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSB0cmFuc2ZlckFsbCAoc3dlZXApIHRyYW5zYWN0aW9uIHdpdGggcmVjaXBpZW50cyBpbiB0eFBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1vY2tlZFdhbGxldCA9IHtcbiAgICAgICAgY29pblNwZWNpZmljOiAoKSA9PiAoe1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiAnNUZmcDF3SkNQdTRoelZEVG83WGFNTHFaU3ZTYWR5VVFteFdQRHc3NENCakVDU29xJyxcbiAgICAgICAgfSksXG4gICAgICB9O1xuXG4gICAgICAvLyBUcmFuc2ZlckFsbCB0eCAoc3dlZXApIC0gX2Ftb3VudCBpcyB1bmRlZmluZWQgZm9yIHRoZXNlIHRyYW5zYWN0aW9uc1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6XG4gICAgICAgICAgJzB4OTAwYTA0MDA5ZjdiMDY3NWRiNTlkMTliNGJkOWM4YzcyZWFhYmJhNzVhOTg2M2QwMmIzMDExNWI4YjNjM2NhNWMyMGYwMjU0MDFkNTAxMjEwMzAwMDAwMDlkODgwZjAwMTAwMDAwMDA2N2Y5NzIzMzkzZWY3NjIxNGRmMDExOGMzNGJiYmQzZGJlYmM4ZWQ0NmExMDk3M2E4Yzk2OWQ0OGZlNzU5OGM5MTQ5Nzk5YmM5NjAyY2I1Y2YyMDFmMzQyNWZiOGQyNTNiMmQ0ZTYxZmMxMTlkY2FiMzI0OWYzMDdmNTk0NzU0ZDAwJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhZGRyZXNzOiAnNUZmcDF3SkNQdTRoelZEVG83WGFNTHFaU3ZTYWR5VVFteFdQRHc3NENCakVDU29xJywgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcgfV0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB3YWxsZXQ6IG1vY2tlZFdhbGxldCBhcyBhbnksXG4gICAgICAgIHZlcmlmaWNhdGlvbjoge1xuICAgICAgICAgIGNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LCB0cnVlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzV2FsbGV0QWRkcmVzcycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHZlcmlmeSB2YWxpZCB3YWxsZXQgYWRkcmVzcyB3aXRoIGNvcnJlY3Qga2V5Y2hhaW4gYW5kIGluZGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICc1RHhEOW5UMTZHUUxyVTZhQjVwU1M1VnR4b1piVmp1M05IVUNjYXd4WnlaQ1RmNzQnO1xuICAgICAgY29uc3QgY29tbW9uS2V5Y2hhaW4gPVxuICAgICAgICAnNmQyZDUxNTBmNmU0MzVkZmQ5YjRmMjI1ZjJjYzI5ZDk1ZWMzYjYxYjM0ZThiZWM5ODY5M2IxYTdmZmU0NGNkNzY0Zjk5ZWU1MDU4ODM4ZDc4NWM3MzM2MGFkNGYyNGQ3OGUwMjU1YWIyYzM2OGMwOTA2MGIyOWE5YjI3ZjA0MGUnO1xuICAgICAgY29uc3QgaW5kZXggPSAnMyc7XG4gICAgICBjb25zdCBrZXljaGFpbnMgPSBbeyBpZDogJzEnLCB0eXBlOiAndHNzJyBhcyBjb25zdCwgY29tbW9uS2V5Y2hhaW4gfV07XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLmlzV2FsbGV0QWRkcmVzcyh7IGtleWNoYWlucywgYWRkcmVzcywgaW5kZXggfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIGFkZHJlc3Mgd2l0aCBpbmNvcnJlY3Qga2V5Y2hhaW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gJzVEeEQ5blQxNkdRTHJVNmFCNXBTUzVWdHhvWmJWanUzTkhVQ2Nhd3haeVpDVGY3NCc7XG4gICAgICBjb25zdCB3cm9uZ0tleWNoYWluID1cbiAgICAgICAgJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAnO1xuICAgICAgY29uc3QgaW5kZXggPSAnMyc7XG4gICAgICBjb25zdCBrZXljaGFpbnMgPSBbeyBpZDogJzEnLCB0eXBlOiAndHNzJyBhcyBjb25zdCwgY29tbW9uS2V5Y2hhaW46IHdyb25nS2V5Y2hhaW4gfV07XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLmlzV2FsbGV0QWRkcmVzcyh7IGtleWNoYWlucywgYWRkcmVzcywgaW5kZXggfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBhZGRyZXNzIHdpdGggaW5jb3JyZWN0IGluZGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICc1RHhEOW5UMTZHUUxyVTZhQjVwU1M1VnR4b1piVmp1M05IVUNjYXd4WnlaQ1RmNzQnO1xuICAgICAgY29uc3QgY29tbW9uS2V5Y2hhaW4gPVxuICAgICAgICAnNmQyZDUxNTBmNmU0MzVkZmQ5YjRmMjI1ZjJjYzI5ZDk1ZWMzYjYxYjM0ZThiZWM5ODY5M2IxYTdmZmU0NGNkNzY0Zjk5ZWU1MDU4ODM4ZDc4NWM3MzM2MGFkNGYyNGQ3OGUwMjU1YWIyYzM2OGMwOTA2MGIyOWE5YjI3ZjA0MGUnO1xuICAgICAgY29uc3Qgd3JvbmdJbmRleCA9ICc5OTknO1xuICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW3sgaWQ6ICcxJywgdHlwZTogJ3RzcycgYXMgY29uc3QsIGNvbW1vbktleWNoYWluIH1dO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi5pc1dhbGxldEFkZHJlc3MoeyBrZXljaGFpbnMsIGFkZHJlc3MsIGluZGV4OiB3cm9uZ0luZGV4IH0pO1xuICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbChmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBpbnZhbGlkIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZhbGlkQWRkcmVzcyA9ICdpbnZhbGlkYWRkcmVzcyc7XG4gICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9XG4gICAgICAgICc2ZDJkNTE1MGY2ZTQzNWRmZDliNGYyMjVmMmNjMjlkOTVlYzNiNjFiMzRlOGJlYzk4NjkzYjFhN2ZmZTQ0Y2Q3NjRmOTllZTUwNTg4MzhkNzg1YzczMzYwYWQ0ZjI0ZDc4ZTAyNTVhYjJjMzY4YzA5MDYwYjI5YTliMjdmMDQwZSc7XG4gICAgICBjb25zdCBpbmRleCA9ICczJztcbiAgICAgIGNvbnN0IGtleWNoYWlucyA9IFt7IGlkOiAnMScsIHR5cGU6ICd0c3MnIGFzIGNvbnN0LCBjb21tb25LZXljaGFpbiB9XTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gYXdhaXQgYmFzZWNvaW4uaXNXYWxsZXRBZGRyZXNzKHsga2V5Y2hhaW5zLCBhZGRyZXNzOiBpbnZhbGlkQWRkcmVzcywgaW5kZXggfSksIHtcbiAgICAgICAgbWVzc2FnZTogYGludmFsaWQgYWRkcmVzczogJHtpbnZhbGlkQWRkcmVzc31gLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRBZGRyZXNzRnJvbVB1YmxpY0tleScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGNvbnZlcnQgcHVibGljIGtleSB0byBTUzU4IGFkZHJlc3MgZm9yIHRlc3RuZXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwdWJsaWNLZXkgPSAnNTM4NDVkN2I2YTZlNGE2NjZmYTJhMGY1MDBiODg4NDliMDI5MjZkYTU1OTA5OTM3MzFkMmI0MjhiNzY0MzY5MCc7XG4gICAgICBjb25zdCBleHBlY3RlZEFkZHJlc3MgPSAnNUR4RDluVDE2R1FMclU2YUI1cFNTNVZ0eG9aYlZqdTNOSFVDY2F3eFp5WkNUZjc0JztcblxuICAgICAgY29uc3QgYWRkcmVzcyA9IGJhc2Vjb2luLmdldEFkZHJlc3NGcm9tUHVibGljS2V5KHB1YmxpY0tleSk7XG4gICAgICBhZGRyZXNzLnNob3VsZC5lcXVhbChleHBlY3RlZEFkZHJlc3MpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb252ZXJ0IHB1YmxpYyBrZXkgdG8gU1M1OCBhZGRyZXNzIGZvciBtYWlubmV0JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHVibGljS2V5ID0gJzUzODQ1ZDdiNmE2ZTRhNjY2ZmEyYTBmNTAwYjg4ODQ5YjAyOTI2ZGE1NTkwOTkzNzMxZDJiNDI4Yjc2NDM2OTAnO1xuICAgICAgLy8gTWFpbm5ldCB1c2VzIGRpZmZlcmVudCBTUzU4IHByZWZpeCAoMCkgdnMgdGVzdG5ldCAoNDIpXG4gICAgICBjb25zdCBhZGRyZXNzID0gcHJvZENvaW4uZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkocHVibGljS2V5KTtcbiAgICAgIGFkZHJlc3Muc2hvdWxkLmJlLnR5cGUoJ3N0cmluZycpO1xuICAgICAgYWRkcmVzcy5sZW5ndGguc2hvdWxkLmJlLmdyZWF0ZXJUaGFuKDApO1xuICAgICAgLy8gU2hvdWxkIGJlIGRpZmZlcmVudCBmcm9tIHRlc3RuZXQgYWRkcmVzc1xuICAgICAgYWRkcmVzcy5zaG91bGQubm90LmVxdWFsKCc1RHhEOW5UMTZHUUxyVTZhQjVwU1M1VnR4b1piVmp1M05IVUNjYXd4WnlaQ1RmNzQnKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==