@bitgo-beta/sdk-coin-dot 2.2.8-beta.197 → 2.2.8-beta.1971

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 (292) hide show
  1. package/dist/{src → cjs/src}/dot.d.ts +23 -20
  2. package/dist/cjs/src/dot.d.ts.map +1 -0
  3. package/dist/cjs/src/dot.js +636 -0
  4. package/dist/cjs/src/index.d.ts.map +1 -0
  5. package/dist/{src → cjs/src}/index.js +6 -2
  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/{src → cjs/src}/lib/batchTransactionBuilder.d.ts +1 -0
  9. package/dist/cjs/src/lib/batchTransactionBuilder.d.ts.map +1 -0
  10. package/dist/cjs/src/lib/batchTransactionBuilder.js +229 -0
  11. package/dist/cjs/src/lib/claimBuilder.d.ts.map +1 -0
  12. package/dist/cjs/src/lib/claimBuilder.js +117 -0
  13. package/dist/cjs/src/lib/errors.d.ts.map +1 -0
  14. package/dist/cjs/src/lib/errors.js +19 -0
  15. package/dist/{src → cjs/src}/lib/iface.d.ts +16 -13
  16. package/dist/cjs/src/lib/iface.d.ts.map +1 -0
  17. package/dist/cjs/src/lib/iface.js +128 -0
  18. package/dist/cjs/src/lib/iface_utils.d.ts.map +1 -0
  19. package/dist/cjs/src/lib/iface_utils.js +92 -0
  20. package/dist/{src → cjs/src}/lib/index.d.ts +2 -0
  21. package/dist/cjs/src/lib/index.d.ts.map +1 -0
  22. package/dist/cjs/src/lib/index.js +73 -0
  23. package/dist/{src → cjs/src}/lib/keyPair.d.ts +7 -0
  24. package/dist/cjs/src/lib/keyPair.d.ts.map +1 -0
  25. package/dist/cjs/src/lib/keyPair.js +117 -0
  26. package/dist/cjs/src/lib/nativeTransferBuilder.d.ts.map +1 -0
  27. package/dist/cjs/src/lib/nativeTransferBuilder.js +219 -0
  28. package/dist/cjs/src/lib/proxyBuilder.d.ts.map +1 -0
  29. package/dist/cjs/src/lib/proxyBuilder.js +116 -0
  30. package/dist/cjs/src/lib/singletonRegistry.d.ts.map +1 -0
  31. package/dist/cjs/src/lib/singletonRegistry.js +20 -0
  32. package/dist/cjs/src/lib/stakingBuilder.d.ts.map +1 -0
  33. package/dist/cjs/src/lib/stakingBuilder.js +167 -0
  34. package/dist/{src → cjs/src}/lib/transaction.d.ts +0 -1
  35. package/dist/cjs/src/lib/transaction.d.ts.map +1 -0
  36. package/dist/cjs/src/lib/transaction.js +624 -0
  37. package/dist/{src → cjs/src}/lib/transactionBuilder.d.ts +0 -1
  38. package/dist/cjs/src/lib/transactionBuilder.d.ts.map +1 -0
  39. package/dist/cjs/src/lib/transactionBuilder.js +351 -0
  40. package/dist/cjs/src/lib/transactionBuilderFactory.d.ts.map +1 -0
  41. package/dist/cjs/src/lib/transactionBuilderFactory.js +104 -0
  42. package/dist/cjs/src/lib/transferBuilder.d.ts.map +1 -0
  43. package/dist/cjs/src/lib/transferBuilder.js +11 -0
  44. package/dist/cjs/src/lib/txnSchema.d.ts.map +1 -0
  45. package/dist/cjs/src/lib/txnSchema.js +117 -0
  46. package/dist/cjs/src/lib/unnominateBuilder.d.ts.map +1 -0
  47. package/dist/cjs/src/lib/unnominateBuilder.js +48 -0
  48. package/dist/cjs/src/lib/unstakeBuilder.d.ts.map +1 -0
  49. package/dist/cjs/src/lib/unstakeBuilder.js +87 -0
  50. package/dist/{src → cjs/src}/lib/utils.d.ts +10 -2
  51. package/dist/cjs/src/lib/utils.d.ts.map +1 -0
  52. package/dist/cjs/src/lib/utils.js +491 -0
  53. package/dist/cjs/src/lib/wasmParser.d.ts +57 -0
  54. package/dist/cjs/src/lib/wasmParser.d.ts.map +1 -0
  55. package/dist/cjs/src/lib/wasmParser.js +345 -0
  56. package/dist/cjs/src/lib/withdrawUnstakedBuilder.d.ts.map +1 -0
  57. package/dist/cjs/src/lib/withdrawUnstakedBuilder.js +88 -0
  58. package/dist/cjs/src/register.d.ts.map +1 -0
  59. package/dist/cjs/src/register.js +11 -0
  60. package/dist/cjs/src/resources/index.d.ts +5 -0
  61. package/dist/cjs/src/resources/index.d.ts.map +1 -0
  62. package/dist/cjs/src/resources/index.js +21 -0
  63. package/dist/cjs/src/resources/mainnet.d.ts.map +1 -0
  64. package/dist/cjs/src/resources/mainnet.js +5 -0
  65. package/dist/cjs/src/resources/polkadotAssetHub.d.ts +2 -0
  66. package/dist/cjs/src/resources/polkadotAssetHub.d.ts.map +1 -0
  67. package/dist/cjs/src/resources/polkadotAssetHub.js +5 -0
  68. package/dist/cjs/src/resources/westend.d.ts.map +1 -0
  69. package/dist/cjs/src/resources/westend.js +5 -0
  70. package/dist/cjs/src/resources/westendAssetHub.d.ts +2 -0
  71. package/dist/cjs/src/resources/westendAssetHub.d.ts.map +1 -0
  72. package/dist/cjs/src/resources/westendAssetHub.js +5 -0
  73. package/dist/cjs/src/tdot.d.ts.map +1 -0
  74. package/dist/cjs/src/tdot.js +27 -0
  75. package/dist/cjs/test/fixtures.d.ts +283 -0
  76. package/dist/cjs/test/fixtures.d.ts.map +1 -0
  77. package/dist/cjs/test/fixtures.js +439 -0
  78. package/dist/cjs/test/resources/index.d.ts +141 -0
  79. package/dist/cjs/test/resources/index.d.ts.map +1 -0
  80. package/dist/cjs/test/resources/index.js +157 -0
  81. package/dist/cjs/test/resources/materialData.json +8 -0
  82. package/dist/cjs/test/resources/materialDataModified.json +8 -0
  83. package/dist/cjs/test/resources/testnet.d.ts +2 -0
  84. package/dist/cjs/test/resources/testnet.d.ts.map +1 -0
  85. package/dist/{src/resources/westend.js → cjs/test/resources/testnet.js} +3 -3
  86. package/dist/cjs/test/unit/address.d.ts +2 -0
  87. package/dist/cjs/test/unit/address.d.ts.map +1 -0
  88. package/dist/cjs/test/unit/address.js +45 -0
  89. package/dist/cjs/test/unit/dot.d.ts +2 -0
  90. package/dist/cjs/test/unit/dot.d.ts.map +1 -0
  91. package/dist/cjs/test/unit/dot.js +1204 -0
  92. package/dist/cjs/test/unit/keypair.d.ts +2 -0
  93. package/dist/cjs/test/unit/keypair.d.ts.map +1 -0
  94. package/dist/cjs/test/unit/keypair.js +111 -0
  95. package/dist/cjs/test/unit/transaction.d.ts +2 -0
  96. package/dist/cjs/test/unit/transaction.d.ts.map +1 -0
  97. package/dist/cjs/test/unit/transaction.js +269 -0
  98. package/dist/cjs/test/unit/transactionBuilder/addressInitializationBuilder.d.ts +2 -0
  99. package/dist/cjs/test/unit/transactionBuilder/addressInitializationBuilder.d.ts.map +1 -0
  100. package/dist/cjs/test/unit/transactionBuilder/addressInitializationBuilder.js +265 -0
  101. package/dist/cjs/test/unit/transactionBuilder/base.d.ts +8 -0
  102. package/dist/cjs/test/unit/transactionBuilder/base.d.ts.map +1 -0
  103. package/dist/cjs/test/unit/transactionBuilder/base.js +233 -0
  104. package/dist/cjs/test/unit/transactionBuilder/batchTransactionBuilder.d.ts +2 -0
  105. package/dist/cjs/test/unit/transactionBuilder/batchTransactionBuilder.d.ts.map +1 -0
  106. package/dist/cjs/test/unit/transactionBuilder/batchTransactionBuilder.js +521 -0
  107. package/dist/cjs/test/unit/transactionBuilder/claimBuilder.d.ts +2 -0
  108. package/dist/cjs/test/unit/transactionBuilder/claimBuilder.d.ts.map +1 -0
  109. package/dist/cjs/test/unit/transactionBuilder/claimBuilder.js +129 -0
  110. package/dist/cjs/test/unit/transactionBuilder/proxyBuilder.d.ts +2 -0
  111. package/dist/cjs/test/unit/transactionBuilder/proxyBuilder.d.ts.map +1 -0
  112. package/dist/cjs/test/unit/transactionBuilder/proxyBuilder.js +88 -0
  113. package/dist/cjs/test/unit/transactionBuilder/singeltonRegistry.d.ts +2 -0
  114. package/dist/cjs/test/unit/transactionBuilder/singeltonRegistry.d.ts.map +1 -0
  115. package/dist/cjs/test/unit/transactionBuilder/singeltonRegistry.js +59 -0
  116. package/dist/cjs/test/unit/transactionBuilder/stakingBuilder.d.ts +2 -0
  117. package/dist/cjs/test/unit/transactionBuilder/stakingBuilder.d.ts.map +1 -0
  118. package/dist/cjs/test/unit/transactionBuilder/stakingBuilder.js +235 -0
  119. package/dist/cjs/test/unit/transactionBuilder/transactionBuilderFactory.d.ts +2 -0
  120. package/dist/cjs/test/unit/transactionBuilder/transactionBuilderFactory.d.ts.map +1 -0
  121. package/dist/cjs/test/unit/transactionBuilder/transactionBuilderFactory.js +107 -0
  122. package/dist/cjs/test/unit/transactionBuilder/transferBuilder.d.ts +2 -0
  123. package/dist/cjs/test/unit/transactionBuilder/transferBuilder.d.ts.map +1 -0
  124. package/dist/cjs/test/unit/transactionBuilder/transferBuilder.js +437 -0
  125. package/dist/cjs/test/unit/transactionBuilder/unnominateBuilder.d.ts +2 -0
  126. package/dist/cjs/test/unit/transactionBuilder/unnominateBuilder.d.ts.map +1 -0
  127. package/dist/cjs/test/unit/transactionBuilder/unnominateBuilder.js +97 -0
  128. package/dist/cjs/test/unit/transactionBuilder/unstakeBuilder.d.ts +2 -0
  129. package/dist/cjs/test/unit/transactionBuilder/unstakeBuilder.d.ts.map +1 -0
  130. package/dist/cjs/test/unit/transactionBuilder/unstakeBuilder.js +116 -0
  131. package/dist/cjs/test/unit/transactionBuilder/withdrawUnstakedBuilder.d.ts +2 -0
  132. package/dist/cjs/test/unit/transactionBuilder/withdrawUnstakedBuilder.d.ts.map +1 -0
  133. package/dist/cjs/test/unit/transactionBuilder/withdrawUnstakedBuilder.js +115 -0
  134. package/dist/cjs/test/unit/utils.d.ts +2 -0
  135. package/dist/cjs/test/unit/utils.d.ts.map +1 -0
  136. package/dist/cjs/test/unit/utils.js +117 -0
  137. package/dist/cjs/test/unit/wasmBuilderByteComparison.d.ts +22 -0
  138. package/dist/cjs/test/unit/wasmBuilderByteComparison.d.ts.map +1 -0
  139. package/dist/cjs/test/unit/wasmBuilderByteComparison.js +197 -0
  140. package/dist/cjs/test/unit/wasmParserExplanation.d.ts +15 -0
  141. package/dist/cjs/test/unit/wasmParserExplanation.d.ts.map +1 -0
  142. package/dist/cjs/test/unit/wasmParserExplanation.js +147 -0
  143. package/dist/cjs/tsconfig.tsbuildinfo +1 -0
  144. package/dist/esm/dot.d.ts +161 -0
  145. package/dist/esm/dot.d.ts.map +1 -0
  146. package/dist/esm/dot.js +596 -0
  147. package/dist/esm/index.d.ts +5 -0
  148. package/dist/esm/index.js +5 -0
  149. package/dist/esm/lib/addressInitializationBuilder.d.ts +79 -0
  150. package/dist/esm/lib/addressInitializationBuilder.js +175 -0
  151. package/dist/esm/lib/batchTransactionBuilder.d.ts +62 -0
  152. package/dist/{src → esm}/lib/batchTransactionBuilder.d.ts.map +1 -1
  153. package/dist/esm/lib/batchTransactionBuilder.js +222 -0
  154. package/dist/esm/lib/claimBuilder.d.ts +58 -0
  155. package/dist/esm/lib/claimBuilder.js +110 -0
  156. package/dist/esm/lib/errors.d.ts +8 -0
  157. package/dist/esm/lib/errors.js +14 -0
  158. package/dist/esm/lib/iface.d.ts +337 -0
  159. package/dist/esm/lib/iface.d.ts.map +1 -0
  160. package/dist/esm/lib/iface.js +125 -0
  161. package/dist/esm/lib/iface_utils.d.ts +59 -0
  162. package/dist/esm/lib/iface_utils.js +83 -0
  163. package/dist/esm/lib/index.d.ts +21 -0
  164. package/dist/{src → esm}/lib/index.d.ts.map +1 -1
  165. package/dist/esm/lib/index.js +20 -0
  166. package/dist/esm/lib/keyPair.d.ts +38 -0
  167. package/dist/esm/lib/keyPair.d.ts.map +1 -0
  168. package/dist/esm/lib/keyPair.js +77 -0
  169. package/dist/esm/lib/nativeTransferBuilder.d.ts +84 -0
  170. package/dist/esm/lib/nativeTransferBuilder.js +212 -0
  171. package/dist/esm/lib/proxyBuilder.d.ts +54 -0
  172. package/dist/esm/lib/proxyBuilder.js +109 -0
  173. package/dist/esm/lib/singletonRegistry.d.ts +7 -0
  174. package/dist/esm/lib/singletonRegistry.js +16 -0
  175. package/dist/esm/lib/stakingBuilder.d.ts +66 -0
  176. package/dist/esm/lib/stakingBuilder.js +160 -0
  177. package/dist/esm/lib/transaction.d.ts +83 -0
  178. package/dist/esm/lib/transaction.d.ts.map +1 -0
  179. package/dist/esm/lib/transaction.js +584 -0
  180. package/dist/esm/lib/transactionBuilder.d.ts +131 -0
  181. package/dist/esm/lib/transactionBuilder.d.ts.map +1 -0
  182. package/dist/esm/lib/transactionBuilder.js +311 -0
  183. package/dist/esm/lib/transactionBuilderFactory.d.ts +28 -0
  184. package/dist/esm/lib/transactionBuilderFactory.js +97 -0
  185. package/dist/esm/lib/transferBuilder.d.ts +11 -0
  186. package/dist/esm/lib/transferBuilder.js +7 -0
  187. package/dist/esm/lib/txnSchema.d.ts +15 -0
  188. package/dist/esm/lib/txnSchema.js +111 -0
  189. package/dist/esm/lib/unnominateBuilder.d.ts +24 -0
  190. package/dist/esm/lib/unnominateBuilder.js +44 -0
  191. package/dist/esm/lib/unstakeBuilder.d.ts +38 -0
  192. package/dist/esm/lib/unstakeBuilder.js +80 -0
  193. package/dist/esm/lib/utils.d.ts +261 -0
  194. package/dist/esm/lib/utils.d.ts.map +1 -0
  195. package/dist/esm/lib/utils.js +451 -0
  196. package/dist/esm/lib/wasmParser.d.ts +57 -0
  197. package/dist/esm/lib/wasmParser.d.ts.map +1 -0
  198. package/dist/esm/lib/wasmParser.js +341 -0
  199. package/dist/esm/lib/withdrawUnstakedBuilder.d.ts +38 -0
  200. package/dist/esm/lib/withdrawUnstakedBuilder.js +81 -0
  201. package/dist/esm/register.d.ts +3 -0
  202. package/dist/esm/register.js +7 -0
  203. package/dist/esm/resources/index.d.ts +5 -0
  204. package/dist/{src → esm}/resources/index.d.ts.map +1 -1
  205. package/dist/esm/resources/index.js +5 -0
  206. package/dist/esm/resources/mainnet.d.ts +2 -0
  207. package/dist/esm/resources/mainnet.js +2 -0
  208. package/dist/esm/resources/polkadotAssetHub.d.ts +2 -0
  209. package/dist/esm/resources/polkadotAssetHub.d.ts.map +1 -0
  210. package/dist/esm/resources/polkadotAssetHub.js +2 -0
  211. package/dist/esm/resources/westend.d.ts +2 -0
  212. package/dist/esm/resources/westend.js +2 -0
  213. package/dist/esm/resources/westendAssetHub.d.ts +2 -0
  214. package/dist/esm/resources/westendAssetHub.d.ts.map +1 -0
  215. package/dist/esm/resources/westendAssetHub.js +2 -0
  216. package/dist/esm/tdot.d.ts +12 -0
  217. package/dist/esm/tdot.js +23 -0
  218. package/package.json +43 -21
  219. package/.eslintignore +0 -5
  220. package/.mocharc.yml +0 -8
  221. package/CHANGELOG.md +0 -656
  222. package/dist/src/dot.d.ts.map +0 -1
  223. package/dist/src/dot.js +0 -562
  224. package/dist/src/lib/addressInitializationBuilder.js +0 -184
  225. package/dist/src/lib/batchTransactionBuilder.js +0 -220
  226. package/dist/src/lib/claimBuilder.js +0 -119
  227. package/dist/src/lib/errors.js +0 -19
  228. package/dist/src/lib/iface.d.ts.map +0 -1
  229. package/dist/src/lib/iface.js +0 -128
  230. package/dist/src/lib/iface_utils.js +0 -93
  231. package/dist/src/lib/index.js +0 -57
  232. package/dist/src/lib/keyPair.d.ts.map +0 -1
  233. package/dist/src/lib/keyPair.js +0 -70
  234. package/dist/src/lib/nativeTransferBuilder.js +0 -221
  235. package/dist/src/lib/proxyBuilder.js +0 -118
  236. package/dist/src/lib/singletonRegistry.js +0 -20
  237. package/dist/src/lib/stakingBuilder.js +0 -169
  238. package/dist/src/lib/transaction.d.ts.map +0 -1
  239. package/dist/src/lib/transaction.js +0 -590
  240. package/dist/src/lib/transactionBuilder.d.ts.map +0 -1
  241. package/dist/src/lib/transactionBuilder.js +0 -337
  242. package/dist/src/lib/transactionBuilderFactory.js +0 -105
  243. package/dist/src/lib/transferBuilder.js +0 -11
  244. package/dist/src/lib/txnSchema.js +0 -117
  245. package/dist/src/lib/unnominateBuilder.js +0 -50
  246. package/dist/src/lib/unstakeBuilder.js +0 -89
  247. package/dist/src/lib/utils.d.ts.map +0 -1
  248. package/dist/src/lib/utils.js +0 -458
  249. package/dist/src/lib/withdrawUnstakedBuilder.js +0 -90
  250. package/dist/src/register.js +0 -11
  251. package/dist/src/resources/index.d.ts +0 -3
  252. package/dist/src/resources/index.js +0 -15
  253. package/dist/src/resources/mainnet.js +0 -5
  254. package/dist/src/tdot.js +0 -27
  255. /package/dist/{src → cjs/src}/index.d.ts +0 -0
  256. /package/dist/{src → cjs/src}/lib/addressInitializationBuilder.d.ts +0 -0
  257. /package/dist/{src → cjs/src}/lib/claimBuilder.d.ts +0 -0
  258. /package/dist/{src → cjs/src}/lib/errors.d.ts +0 -0
  259. /package/dist/{src → cjs/src}/lib/iface_utils.d.ts +0 -0
  260. /package/dist/{src → cjs/src}/lib/nativeTransferBuilder.d.ts +0 -0
  261. /package/dist/{src → cjs/src}/lib/proxyBuilder.d.ts +0 -0
  262. /package/dist/{src → cjs/src}/lib/singletonRegistry.d.ts +0 -0
  263. /package/dist/{src → cjs/src}/lib/stakingBuilder.d.ts +0 -0
  264. /package/dist/{src → cjs/src}/lib/transactionBuilderFactory.d.ts +0 -0
  265. /package/dist/{src → cjs/src}/lib/transferBuilder.d.ts +0 -0
  266. /package/dist/{src → cjs/src}/lib/txnSchema.d.ts +0 -0
  267. /package/dist/{src → cjs/src}/lib/unnominateBuilder.d.ts +0 -0
  268. /package/dist/{src → cjs/src}/lib/unstakeBuilder.d.ts +0 -0
  269. /package/dist/{src → cjs/src}/lib/withdrawUnstakedBuilder.d.ts +0 -0
  270. /package/dist/{src → cjs/src}/register.d.ts +0 -0
  271. /package/dist/{src → cjs/src}/resources/mainnet.d.ts +0 -0
  272. /package/dist/{src → cjs/src}/resources/westend.d.ts +0 -0
  273. /package/dist/{src → cjs/src}/tdot.d.ts +0 -0
  274. /package/dist/{src → esm}/index.d.ts.map +0 -0
  275. /package/dist/{src → esm}/lib/addressInitializationBuilder.d.ts.map +0 -0
  276. /package/dist/{src → esm}/lib/claimBuilder.d.ts.map +0 -0
  277. /package/dist/{src → esm}/lib/errors.d.ts.map +0 -0
  278. /package/dist/{src → esm}/lib/iface_utils.d.ts.map +0 -0
  279. /package/dist/{src → esm}/lib/nativeTransferBuilder.d.ts.map +0 -0
  280. /package/dist/{src → esm}/lib/proxyBuilder.d.ts.map +0 -0
  281. /package/dist/{src → esm}/lib/singletonRegistry.d.ts.map +0 -0
  282. /package/dist/{src → esm}/lib/stakingBuilder.d.ts.map +0 -0
  283. /package/dist/{src → esm}/lib/transactionBuilderFactory.d.ts.map +0 -0
  284. /package/dist/{src → esm}/lib/transferBuilder.d.ts.map +0 -0
  285. /package/dist/{src → esm}/lib/txnSchema.d.ts.map +0 -0
  286. /package/dist/{src → esm}/lib/unnominateBuilder.d.ts.map +0 -0
  287. /package/dist/{src → esm}/lib/unstakeBuilder.d.ts.map +0 -0
  288. /package/dist/{src → esm}/lib/withdrawUnstakedBuilder.d.ts.map +0 -0
  289. /package/dist/{src → esm}/register.d.ts.map +0 -0
  290. /package/dist/{src → esm}/resources/mainnet.d.ts.map +0 -0
  291. /package/dist/{src → esm}/resources/westend.d.ts.map +0 -0
  292. /package/dist/{src → esm}/tdot.d.ts.map +0 -0
@@ -0,0 +1,1204 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const sdk_api_1 = require("@bitgo-beta/sdk-api");
40
+ const sdk_test_1 = require("@bitgo-beta/sdk-test");
41
+ const crypto_1 = require("crypto");
42
+ const should = require("should");
43
+ const assert = require("assert");
44
+ const src_1 = require("../../src");
45
+ const testData = __importStar(require("../fixtures"));
46
+ const resources_1 = require("../resources");
47
+ const sinon = __importStar(require("sinon"));
48
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
49
+ const statics_1 = require("@bitgo-beta/statics");
50
+ const wasm_dot_1 = require("@bitgo/wasm-dot");
51
+ const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
52
+ const utils_1 = __importDefault(require("../../src/lib/utils"));
53
+ const lib_1 = require("../../src/lib");
54
+ describe('DOT:', function () {
55
+ let bitgo;
56
+ let basecoin;
57
+ let prodCoin;
58
+ before(function () {
59
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
60
+ bitgo.safeRegister('dot', src_1.Dot.createInstance);
61
+ bitgo.safeRegister('tdot', src_1.Tdot.createInstance);
62
+ bitgo.initializeTestVars();
63
+ basecoin = bitgo.coin('tdot');
64
+ prodCoin = bitgo.coin('dot');
65
+ });
66
+ describe('Sign Message', () => {
67
+ it('should be performed', async () => {
68
+ const keyPair = new src_1.KeyPair();
69
+ const messageToSign = Buffer.from((0, crypto_1.randomBytes)(32)).toString('hex');
70
+ const signature = await basecoin.signMessage(keyPair.getKeys(), messageToSign);
71
+ keyPair.verifySignature(messageToSign, Uint8Array.from(signature)).should.equals(true);
72
+ });
73
+ it('should fail with missing private key', async () => {
74
+ const keyPair = new src_1.KeyPair({
75
+ pub: '7788327c695dca4b3e649a0db45bc3e703a2c67428fce360e61800cc4248f4f7',
76
+ }).getKeys();
77
+ const messageToSign = Buffer.from((0, crypto_1.randomBytes)(32)).toString('hex');
78
+ await basecoin.signMessage(keyPair, messageToSign).should.be.rejectedWith('Invalid key pair options');
79
+ });
80
+ });
81
+ describe('Sign transaction', () => {
82
+ const transaction = {
83
+ id: '0x19de156328eea66bd1ec45843569c168e0bb2f2898221029b403df3f23a5489d',
84
+ sender: '5EGoFA95omzemRssELLDjVenNZ68aXyUeqtKQScXSEBvVJkr',
85
+ referenceBlock: '0x149799bc9602cb5cf201f3425fb8d253b2d4e61fc119dcab3249f307f594754d',
86
+ blockNumber: 3933,
87
+ genesisHash: '0x67f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9',
88
+ nonce: 200,
89
+ specVersion: 1018013,
90
+ transactionVersion: 16,
91
+ eraPeriod: 64,
92
+ chainName: 'Westend Asset Hub',
93
+ tip: 0,
94
+ to: '5Ffp1wJCPu4hzVDTo7XaMLqZSvSadyUQmxWPDw74CBjECSoq',
95
+ amount: '10000000000',
96
+ };
97
+ // TODO: BG-43197
98
+ xit('should sign transaction', async function () {
99
+ const signed = await basecoin.signTransaction({
100
+ txPrebuild: {
101
+ txHex: testData.rawTx.transfer.unsigned,
102
+ transaction,
103
+ },
104
+ pubs: [testData.accounts.account1.publicKey],
105
+ prv: testData.accounts.account1.secretKey,
106
+ });
107
+ signed.txHex.should.equal(testData.rawTx.transfer.signed);
108
+ });
109
+ // TODO: BG-43197
110
+ xit('should fail to sign transaction with an invalid key', async function () {
111
+ try {
112
+ await basecoin.signTransaction({
113
+ txPrebuild: {
114
+ txHex: testData.rawTx.transfer.unsigned,
115
+ transaction,
116
+ },
117
+ pubs: [testData.accounts.account2.publicKey],
118
+ prv: testData.accounts.account1.secretKey,
119
+ });
120
+ }
121
+ catch (e) {
122
+ should.equal(e.message, 'Private key cannot sign the transaction');
123
+ }
124
+ });
125
+ it('should fail to build transaction with missing params', async function () {
126
+ try {
127
+ await basecoin.signTransaction({
128
+ txPrebuild: {
129
+ txHex: testData.rawTx.transfer.unsigned,
130
+ key: testData.accounts.account1.publicKey,
131
+ },
132
+ prv: testData.accounts.account1.secretKey,
133
+ });
134
+ }
135
+ catch (e) {
136
+ should.notEqual(e, null);
137
+ }
138
+ });
139
+ });
140
+ describe('Generate wallet key pair: ', () => {
141
+ it('should generate key pair', () => {
142
+ const kp = basecoin.generateKeyPair();
143
+ basecoin.isValidPub(kp.pub).should.equal(true);
144
+ basecoin.isValidPrv(kp.prv).should.equal(true);
145
+ });
146
+ it('should generate key pair from seed', () => {
147
+ const seed = Buffer.from('9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60', 'hex');
148
+ const kp = basecoin.generateKeyPair(seed);
149
+ basecoin.isValidPub(kp.pub).should.equal(true);
150
+ basecoin.isValidPrv(kp.prv).should.equal(true);
151
+ });
152
+ });
153
+ describe('Balance Conversion', () => {
154
+ it('should return 10000000000 as tdot base factor', () => {
155
+ // mainnet uses 10 decimal places
156
+ const baseFactor = prodCoin.getBaseFactor();
157
+ baseFactor.should.equal(10000000000);
158
+ });
159
+ it('should return 1000000000000 as dot base factor', () => {
160
+ // westend (test polkadot) uses 12 decimal places
161
+ const baseFactor = basecoin.getBaseFactor();
162
+ baseFactor.should.equal(1000000000000);
163
+ });
164
+ it('should return 4 Dot when base unit is 40000000000 for dot', () => {
165
+ const bigUnit = prodCoin.baseUnitsToBigUnits('40000000000');
166
+ bigUnit.should.equal('4');
167
+ });
168
+ it('should return 0.04 Dot when base unit is 400000000 for dot', () => {
169
+ const bigUnit = prodCoin.baseUnitsToBigUnits('400000000');
170
+ bigUnit.should.equal('0.04');
171
+ });
172
+ it('should return 4 test Dot when base unit is 4000000000000 for tdot', () => {
173
+ const bigUnit = basecoin.baseUnitsToBigUnits('4000000000000');
174
+ bigUnit.should.equal('4');
175
+ });
176
+ it('should return 0.04 test Dot when base unit is 400000000 for tdot', () => {
177
+ const bigUnit = basecoin.baseUnitsToBigUnits('40000000000');
178
+ bigUnit.should.equal('0.04');
179
+ });
180
+ });
181
+ describe('Explain Transactions:', () => {
182
+ it('should explain an unsigned transfer transaction', async function () {
183
+ const explainedTransaction = await prodCoin.explainTransaction(testData.unsignedTransaction);
184
+ explainedTransaction.should.deepEqual({
185
+ displayOrder: [
186
+ 'outputAmount',
187
+ 'changeAmount',
188
+ 'outputs',
189
+ 'changeOutputs',
190
+ 'fee',
191
+ 'type',
192
+ 'sequenceId',
193
+ 'id',
194
+ 'blockNumber',
195
+ ],
196
+ sequenceId: 0,
197
+ fee: '10',
198
+ id: '0x0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8',
199
+ type: '0',
200
+ outputs: [
201
+ {
202
+ address: '5DkddSfPsWojjfuH9iJEcUV7ZseQ9EJ6RjtNmCR1w3CEb8S9',
203
+ valueString: '90034235235350',
204
+ coinName: 'tdot',
205
+ wallet: '62a1205751675b2f0fe72328',
206
+ },
207
+ ],
208
+ blockNumber: 8619307,
209
+ outputAmount: 90034235235350,
210
+ changeOutputs: [],
211
+ changeAmount: '0',
212
+ });
213
+ });
214
+ });
215
+ describe('Explain Transactions (WASM):', () => {
216
+ const coin = statics_1.coins.get('tdot');
217
+ const material = utils_1.default.getMaterial(coin);
218
+ const SENDER = testData.accounts.account1.address;
219
+ const RECIPIENT = testData.accounts.account2.address;
220
+ function wasmContext(nonce = 0) {
221
+ return {
222
+ sender: SENDER,
223
+ nonce,
224
+ material: material,
225
+ validity: { firstValid: testData.westendBlock.blockNumber, maxDuration: 2400 },
226
+ referenceBlock: testData.westendBlock.hash,
227
+ };
228
+ }
229
+ it('should explain a transfer via explainDotTransaction', function () {
230
+ const tx = (0, wasm_dot_1.buildTransaction)({ type: 'payment', to: RECIPIENT, amount: 1000000000000n }, wasmContext());
231
+ const explained = (0, lib_1.explainDotTransaction)({
232
+ txHex: tx.toBroadcastFormat(),
233
+ material,
234
+ senderAddress: SENDER,
235
+ });
236
+ assert.strictEqual(explained.type, sdk_core_1.TransactionType.Send);
237
+ assert.strictEqual(explained.outputs.length, 1);
238
+ assert.strictEqual(explained.outputs[0].address, RECIPIENT);
239
+ assert.strictEqual(explained.outputs[0].amount, '1000000000000');
240
+ assert.strictEqual(explained.outputAmount, '1000000000000');
241
+ assert.strictEqual(explained.sender, SENDER);
242
+ assert.strictEqual(explained.methodName, 'balances.transferKeepAlive');
243
+ });
244
+ it('should explain a staking bond via explainDotTransaction', function () {
245
+ const tx = (0, wasm_dot_1.buildTransaction)({ type: 'stake', amount: 5000000000000n, payee: { type: 'stash' } }, wasmContext(1));
246
+ const explained = (0, lib_1.explainDotTransaction)({
247
+ txHex: tx.toBroadcastFormat(),
248
+ material,
249
+ senderAddress: SENDER,
250
+ });
251
+ assert.strictEqual(explained.type, sdk_core_1.TransactionType.StakingActivate);
252
+ assert.strictEqual(explained.outputs.length, 1);
253
+ // STAKING_DESTINATION: SS58(0x00..00) sentinel, bond doesn't transfer to an external address
254
+ assert.strictEqual(explained.outputs[0].address, '5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM');
255
+ assert.strictEqual(explained.outputs[0].amount, '5000000000000');
256
+ });
257
+ it('should explain a transfer via explainDotTransaction with sender', function () {
258
+ const tx = (0, wasm_dot_1.buildTransaction)({ type: 'payment', to: RECIPIENT, amount: 1000000000000n }, wasmContext());
259
+ const explained = (0, lib_1.explainDotTransaction)({
260
+ txHex: tx.toBroadcastFormat(),
261
+ material,
262
+ senderAddress: SENDER,
263
+ });
264
+ assert.strictEqual(explained.type, sdk_core_1.TransactionType.Send);
265
+ assert.strictEqual(explained.outputs.length, 1);
266
+ assert.strictEqual(explained.outputs[0].address, RECIPIENT);
267
+ assert.strictEqual(explained.outputs[0].amount, '1000000000000');
268
+ assert.strictEqual(explained.sender, SENDER);
269
+ assert.strictEqual(explained.nonce, 0);
270
+ });
271
+ });
272
+ describe('Recover Transactions:', () => {
273
+ const sandBox = sinon.createSandbox();
274
+ const destAddr = testData.accounts.account1.address;
275
+ const nonce = 123;
276
+ beforeEach(function () {
277
+ const accountInfoCB = sandBox.stub(src_1.Dot.prototype, 'getAccountInfo');
278
+ accountInfoCB.withArgs(testData.wrwUser.walletAddress0).resolves({
279
+ nonce: nonce,
280
+ // Must exceed stubbed getFee so recover() does not throw (matches getFee withArgs amount).
281
+ freeBalance: 1510000000000,
282
+ });
283
+ const headerInfoCB = sandBox.stub(src_1.Dot.prototype, 'getHeaderInfo');
284
+ headerInfoCB.resolves({
285
+ headerNumber: testData.westendBlock.blockNumber,
286
+ headerHash: testData.westendBlock.hash,
287
+ });
288
+ accountInfoCB.withArgs('5Dtg2zKjVEL8p9keSM4dQ7nD26sVtMfCsyxkhvZZ9fqBbhw6').resolves({
289
+ nonce: 0,
290
+ freeBalance: 1510000000000,
291
+ });
292
+ const getFeeCB = sandBox.stub(src_1.Dot.prototype, 'getFee');
293
+ // Default avoids RPC when tests use a recoveryDestination other than destAddr (e.g. unsigned sweep fixture).
294
+ getFeeCB.resolves(15783812856);
295
+ getFeeCB.withArgs(destAddr, testData.wrwUser.walletAddress0, 1510000000000).resolves(15783812856);
296
+ const getMaterialCB = sandBox.stub(src_1.Dot.prototype, 'getMaterial');
297
+ getMaterialCB.resolves(utils_1.default.getMaterial(statics_1.coins.get('tdot')));
298
+ });
299
+ afterEach(function () {
300
+ sandBox.restore();
301
+ });
302
+ it('should generate unsigned sweep correctly', async function () {
303
+ const commonKeychain = '3cd14f5d60744287cd3a50510e2964746b6feaad4b2300088eaae60d1a35f0abc518534d43b2614370d9a263aadb57edb5d0b78f816a519cd5896e7352920b67';
304
+ const recoveryDestination = '5GPAveMvmDsjxVT6Q2xiu5kYPbFAmdebHaiNZK14FBaSaAKh';
305
+ const unsigned = await basecoin.recover({ bitgoKey: commonKeychain, recoveryDestination });
306
+ unsigned.txRequests.should.not.be.undefined();
307
+ unsigned.txRequests.length.should.equal(1);
308
+ unsigned.txRequests[0].transactions.length.should.equal(1);
309
+ unsigned.txRequests[0].walletCoin.should.equal('tdot');
310
+ unsigned.txRequests[0].transactions[0].unsignedTx.should.not.be.undefined();
311
+ unsigned.txRequests[0].transactions[0].unsignedTx.serializedTx.should.not.be.undefined();
312
+ unsigned.txRequests[0].transactions[0].unsignedTx.scanIndex.should.equal(0);
313
+ unsigned.txRequests[0].transactions[0].unsignedTx.coin.should.equal('tdot');
314
+ unsigned.txRequests[0].transactions[0].unsignedTx.signableHex.should.not.be.undefined();
315
+ unsigned.txRequests[0].transactions[0].unsignedTx.derivationPath.should.equal('m/0');
316
+ unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.should.not.be.undefined();
317
+ unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.inputs.should.not.be.undefined();
318
+ unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.inputs.length.should.equal(1);
319
+ unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.inputs[0].address.should.equal('5Dtg2zKjVEL8p9keSM4dQ7nD26sVtMfCsyxkhvZZ9fqBbhw6');
320
+ unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.inputs[0].valueString.should.equal('1510000000000');
321
+ unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.inputs[0].value.should.equal(1510000000000);
322
+ unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.outputs.should.not.be.undefined();
323
+ unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.outputs.length.should.equal(1);
324
+ unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.outputs[0].address.should.equal('5GPAveMvmDsjxVT6Q2xiu5kYPbFAmdebHaiNZK14FBaSaAKh');
325
+ unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.outputs[0].valueString.should.equal('1510000000000');
326
+ unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.outputs[0].coinName.should.equal('tdot');
327
+ unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.type.should.equal('');
328
+ unsigned.txRequests[0].transactions[0].unsignedTx.feeInfo.should.not.be.undefined();
329
+ unsigned.txRequests[0].transactions[0].unsignedTx.feeInfo.fee.should.equal(0);
330
+ unsigned.txRequests[0].transactions[0].unsignedTx.feeInfo.feeString.should.equal('0');
331
+ unsigned.txRequests[0].transactions[0].unsignedTx.coinSpecific.should.not.be.undefined();
332
+ unsigned.txRequests[0].transactions[0].unsignedTx.coinSpecific.firstValid.should.not.be.undefined();
333
+ unsigned.txRequests[0].transactions[0].unsignedTx.coinSpecific.maxDuration.should.equal(2400);
334
+ unsigned.txRequests[0].transactions[0].unsignedTx.coinSpecific.commonKeychain.should.equal('3cd14f5d60744287cd3a50510e2964746b6feaad4b2300088eaae60d1a35f0abc518534d43b2614370d9a263aadb57edb5d0b78f816a519cd5896e7352920b67');
335
+ });
336
+ // TODO(COIN-919): Fix failing test
337
+ xit('should take OVC output and generate a signed sweep transaction', async function () {
338
+ const params = testData.ovcResponse;
339
+ const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
340
+ recoveryTxn.transactions[0].serializedTx.should.equal('0x2d02840050d1e116cdb32e61ba3ece275b620f503f0c5ae4e7690d9f9aa7e0b50303976c00057c131cde2be39f4ff23eeba11139c46dd8c6d69ff517abede37381d8d24f0bb30fd8805b2e51a9e2a75338d7fb7edb290be9638debedbfc001d10b8132be0b2b4a0400040400bf0678d312b2b2c7effd2b1f214ee13928d339391d5f5f7056608aa0d32b9edf01');
341
+ recoveryTxn.transactions[0].scanIndex.should.equal(0);
342
+ recoveryTxn.lastScanIndex.should.equal(0);
343
+ });
344
+ // TODO(COIN-919): Fix failing test
345
+ xit('should take consolidation OVC output and generate multiple signed sweep transactions', async function () {
346
+ const params = testData.ovcResponse2;
347
+ const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
348
+ recoveryTxn.transactions[0].serializedTx.should.equal('0x2d028400f053d177371f4919b71017421aa34841ac87c926a14e8a7e75f092693665cb4a009871feb8389e12191b460ebea1f9e1716ada8a31d94ac08f5c15cb5f7be24683cdfc300ae3e6802c6f4b044dd92ea03d15b92399ab45803e43beb5cbff582a031b37000004040050d1e116cdb32e61ba3ece275b620f503f0c5ae4e7690d9f9aa7e0b50303976c01');
349
+ recoveryTxn.transactions[0].scanIndex.should.equal(1);
350
+ recoveryTxn.transactions[1].serializedTx.should.equal('0x2d028400cf7ed9f536373c8f874e780a4269ec1bd6799ed7d4a854c670b0c72805fac87600d153cbb683706ddf320f7b225af14ce4b59b868c07440aefa4c4e1297e49bcd5f6ee84f696b0c2e456e2a7f8779a78a2c832dfb47d5b283eba8408b003c7dd031b37000004040050d1e116cdb32e61ba3ece275b620f503f0c5ae4e7690d9f9aa7e0b50303976c01');
351
+ recoveryTxn.transactions[1].scanIndex.should.equal(2);
352
+ recoveryTxn.transactions[2].serializedTx.should.equal('0x2d0284009482ad7e43b40b7df3383244daafed32b3b9fd7541016b5c907f2d9052f85f8600e255698d110977faf33efb3336ba98ad7eaa2a1a926487fc696a277442d4414b2a441ba92d598f2b1f96f13b28785f5e572984035a608d63c48bd35ba955090e1b37000004040050d1e116cdb32e61ba3ece275b620f503f0c5ae4e7690d9f9aa7e0b50303976c01');
353
+ recoveryTxn.transactions[2].scanIndex.should.equal(3);
354
+ recoveryTxn.lastScanIndex.should.equal(20);
355
+ });
356
+ // TODO(COIN-919): Fix failing test
357
+ xit('should recover a txn for non-bitgo recoveries', async function () {
358
+ const res = await basecoin.recover({
359
+ userKey: testData.wrwUser.userKey,
360
+ backupKey: testData.wrwUser.backupKey,
361
+ bitgoKey: testData.wrwUser.bitgoKey,
362
+ walletPassphrase: testData.wrwUser.walletPassphrase,
363
+ recoveryDestination: destAddr,
364
+ });
365
+ res.should.not.be.empty();
366
+ res.should.hasOwnProperty('serializedTx');
367
+ res.should.hasOwnProperty('scanIndex');
368
+ sandBox.assert.calledOnce(basecoin.getAccountInfo);
369
+ sandBox.assert.calledOnce(basecoin.getHeaderInfo);
370
+ // deserialize the txn and verify the fields are what we expect
371
+ const txBuilder = basecoin.getBuilder().from(res.serializedTx);
372
+ // some information isn't deserialized by the from method, so we will
373
+ // supply it again in order to re-build the txn
374
+ txBuilder
375
+ .validity({
376
+ firstValid: testData.westendBlock.blockNumber,
377
+ maxDuration: basecoin.SWEEP_TXN_DURATION,
378
+ })
379
+ .referenceBlock(testData.westendBlock.hash);
380
+ const tx = await txBuilder.build();
381
+ const txJson = tx.toJson();
382
+ should.deepEqual(txJson.sender, testData.wrwUser.walletAddress0);
383
+ should.deepEqual(txJson.blockNumber, testData.westendBlock.blockNumber);
384
+ should.deepEqual(txJson.referenceBlock, testData.westendBlock.hash);
385
+ should.deepEqual(txJson.genesisHash, resources_1.genesisHash);
386
+ should.deepEqual(txJson.specVersion, resources_1.specVersion);
387
+ should.deepEqual(txJson.nonce, nonce);
388
+ should.deepEqual(txJson.tip, 0);
389
+ should.deepEqual(txJson.transactionVersion, resources_1.txVersion);
390
+ should.deepEqual(txJson.chainName, resources_1.chainName);
391
+ should.deepEqual(txJson.eraPeriod, basecoin.SWEEP_TXN_DURATION);
392
+ });
393
+ it('should recover a txn for unsigned-sweep recoveries', async function () {
394
+ const res = await basecoin.recover({
395
+ bitgoKey: testData.wrwUser.bitgoKey,
396
+ recoveryDestination: destAddr,
397
+ });
398
+ res.should.not.be.empty();
399
+ res.txRequests[0].transactions[0].unsignedTx.should.hasOwnProperty('serializedTx');
400
+ res.txRequests[0].transactions[0].unsignedTx.should.hasOwnProperty('scanIndex');
401
+ sandBox.assert.calledOnce(basecoin.getAccountInfo);
402
+ sandBox.assert.calledOnce(basecoin.getHeaderInfo);
403
+ // deserialize the txn and verify the fields are what we expect
404
+ const txBuilder = basecoin.getBuilder().from(res.txRequests[0].transactions[0].unsignedTx.serializedTx);
405
+ // some information isn't deserialized by the from method, so we will
406
+ // supply it again in order to re-build the txn
407
+ txBuilder
408
+ .validity({
409
+ firstValid: testData.westendBlock.blockNumber,
410
+ maxDuration: basecoin.SWEEP_TXN_DURATION,
411
+ })
412
+ .referenceBlock(testData.westendBlock.hash)
413
+ .sender({ address: testData.wrwUser.walletAddress0 });
414
+ const tx = await txBuilder.build();
415
+ const txJson = tx.toJson();
416
+ should.deepEqual(txJson.sender, testData.wrwUser.walletAddress0);
417
+ should.deepEqual(txJson.blockNumber, testData.westendBlock.blockNumber);
418
+ should.deepEqual(txJson.referenceBlock, testData.westendBlock.hash);
419
+ should.deepEqual(txJson.genesisHash, resources_1.genesisHash);
420
+ should.deepEqual(txJson.specVersion, resources_1.specVersion);
421
+ should.deepEqual(txJson.nonce, nonce);
422
+ should.deepEqual(txJson.tip, 0);
423
+ should.deepEqual(txJson.transactionVersion, resources_1.txVersion);
424
+ should.deepEqual(txJson.chainName, resources_1.chainName);
425
+ should.deepEqual(txJson.eraPeriod, basecoin.SWEEP_TXN_DURATION);
426
+ });
427
+ });
428
+ describe('Recover Transactions (MPCv2):', () => {
429
+ const sandBox = sinon.createSandbox();
430
+ const destAddr = testData.accounts.account1.address;
431
+ const nonce = 123;
432
+ const walletPassphrase = testData.wrwUser.walletPassphrase;
433
+ let mpcV2UserKey;
434
+ let mpcV2BackupKey;
435
+ let mpcV2CommonKeyChain;
436
+ let mpcV2WalletAddress;
437
+ let mismatchedBitgoKey;
438
+ let mismatchedWalletAddress;
439
+ before(async function () {
440
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
441
+ const [otherUserDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
442
+ mpcV2UserKey = await (0, sdk_api_1.encrypt)(walletPassphrase, userDkg.getReducedKeyShare().toString('base64'));
443
+ mpcV2BackupKey = await (0, sdk_api_1.encrypt)(walletPassphrase, backupDkg.getReducedKeyShare().toString('base64'));
444
+ mpcV2CommonKeyChain = userDkg.getCommonKeychain();
445
+ const mpc = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
446
+ mpcV2WalletAddress = basecoin.getAddressFromPublicKey(mpc.deriveUnhardened(mpcV2CommonKeyChain, 'm/0').slice(0, 64));
447
+ mismatchedBitgoKey = otherUserDkg.getCommonKeychain();
448
+ mismatchedWalletAddress = basecoin.getAddressFromPublicKey(mpc.deriveUnhardened(mismatchedBitgoKey, 'm/0').slice(0, 64));
449
+ });
450
+ beforeEach(function () {
451
+ const accountInfoCB = sandBox.stub(src_1.Dot.prototype, 'getAccountInfo');
452
+ accountInfoCB.withArgs(mpcV2WalletAddress).resolves({
453
+ nonce: nonce,
454
+ freeBalance: 1510000000000,
455
+ });
456
+ accountInfoCB.withArgs(mismatchedWalletAddress).resolves({
457
+ nonce: nonce,
458
+ freeBalance: 1510000000000,
459
+ });
460
+ const headerInfoCB = sandBox.stub(src_1.Dot.prototype, 'getHeaderInfo');
461
+ headerInfoCB.resolves({
462
+ headerNumber: testData.westendBlock.blockNumber,
463
+ headerHash: testData.westendBlock.hash,
464
+ });
465
+ const getFeeCB = sandBox.stub(src_1.Dot.prototype, 'getFee');
466
+ getFeeCB.resolves(15783812856);
467
+ const getMaterialCB = sandBox.stub(src_1.Dot.prototype, 'getMaterial');
468
+ getMaterialCB.resolves(utils_1.default.getMaterial(statics_1.coins.get('tdot')));
469
+ });
470
+ afterEach(function () {
471
+ sandBox.restore();
472
+ });
473
+ it('should route to MPCv2 path for native DOT recovery when keycard is MPCv2', async function () {
474
+ const getTSSSignatureSpy = sandBox.spy(sdk_core_1.EDDSAMethods, 'getTSSSignature');
475
+ const res = (await basecoin.recover({
476
+ userKey: mpcV2UserKey,
477
+ backupKey: mpcV2BackupKey,
478
+ bitgoKey: mpcV2CommonKeyChain,
479
+ walletPassphrase,
480
+ recoveryDestination: destAddr,
481
+ }));
482
+ res.should.not.be.empty();
483
+ res.should.hasOwnProperty('serializedTx');
484
+ res.should.hasOwnProperty('scanIndex');
485
+ should.equal(res.scanIndex, 0);
486
+ sandBox.assert.calledOnce(basecoin.getAccountInfo);
487
+ sandBox.assert.notCalled(getTSSSignatureSpy);
488
+ });
489
+ it('should throw when MPCv2 commonKeyChain does not match bitgoKey', async function () {
490
+ await basecoin
491
+ .recover({
492
+ userKey: mpcV2UserKey,
493
+ backupKey: mpcV2BackupKey,
494
+ bitgoKey: mismatchedBitgoKey,
495
+ walletPassphrase,
496
+ recoveryDestination: destAddr,
497
+ })
498
+ .should.be.rejectedWith('EdDSA MPCv2 recovery: commonKeyChain from keycard does not match bitgoKey');
499
+ });
500
+ it('should throw missing userKey when backupKey and walletPassphrase are present but userKey is not', async function () {
501
+ await basecoin
502
+ .recover({
503
+ userKey: undefined,
504
+ backupKey: mpcV2BackupKey,
505
+ bitgoKey: mpcV2CommonKeyChain,
506
+ walletPassphrase,
507
+ recoveryDestination: destAddr,
508
+ })
509
+ .should.be.rejectedWith('missing userKey');
510
+ });
511
+ it('should throw missing backupKey when userKey and walletPassphrase are present but backupKey is not', async function () {
512
+ await basecoin
513
+ .recover({
514
+ userKey: mpcV2UserKey,
515
+ backupKey: undefined,
516
+ bitgoKey: mpcV2CommonKeyChain,
517
+ walletPassphrase,
518
+ recoveryDestination: destAddr,
519
+ })
520
+ .should.be.rejectedWith('missing backupKey');
521
+ });
522
+ it('should throw missing wallet passphrase when userKey and backupKey are present but walletPassphrase is not', async function () {
523
+ await basecoin
524
+ .recover({
525
+ userKey: mpcV2UserKey,
526
+ backupKey: mpcV2BackupKey,
527
+ bitgoKey: mpcV2CommonKeyChain,
528
+ walletPassphrase: undefined,
529
+ recoveryDestination: destAddr,
530
+ })
531
+ .should.be.rejectedWith('missing wallet passphrase');
532
+ });
533
+ it('should still use the MPCv1 path (getTSSSignature) for MPCv1 JSON keycards', async function () {
534
+ const getTSSSignatureSpy = sandBox.spy(sdk_core_1.EDDSAMethods, 'getTSSSignature');
535
+ src_1.Dot.prototype.getAccountInfo
536
+ .withArgs(testData.wrwUser.walletAddress0)
537
+ .resolves({
538
+ nonce,
539
+ freeBalance: 1510000000000,
540
+ });
541
+ const result = (await basecoin.recover({
542
+ userKey: testData.wrwUser.userKey,
543
+ backupKey: testData.wrwUser.backupKey,
544
+ bitgoKey: testData.wrwUser.bitgoKey,
545
+ walletPassphrase: testData.wrwUser.walletPassphrase,
546
+ recoveryDestination: destAddr,
547
+ }));
548
+ result.should.not.be.empty();
549
+ result.should.hasOwnProperty('serializedTx');
550
+ sandBox.assert.calledOnce(getTSSSignatureSpy);
551
+ });
552
+ it('should call getEddsaSigningMaterial exactly once per recover() call', async function () {
553
+ const getEddsaMaterialSpy = sandBox.spy(basecoin, 'getEddsaSigningMaterial');
554
+ const res = (await basecoin.recover({
555
+ userKey: mpcV2UserKey,
556
+ backupKey: mpcV2BackupKey,
557
+ bitgoKey: mpcV2CommonKeyChain,
558
+ walletPassphrase,
559
+ recoveryDestination: destAddr,
560
+ }));
561
+ res.should.not.be.empty();
562
+ sandBox.assert.calledOnce(getEddsaMaterialSpy);
563
+ });
564
+ });
565
+ describe('Build Consolidation Recoveries:', () => {
566
+ const sandBox = sinon.createSandbox();
567
+ const baseAddr = testData.consolidationWrwUser.walletAddress0;
568
+ const nonce = 123;
569
+ beforeEach(function () {
570
+ const accountInfoCB = sandBox.stub(src_1.Dot.prototype, 'getAccountInfo');
571
+ accountInfoCB.withArgs(testData.consolidationWrwUser.walletAddress1).resolves({
572
+ nonce: nonce,
573
+ freeBalance: 10000000000,
574
+ });
575
+ accountInfoCB.withArgs(testData.consolidationWrwUser.walletAddress2).resolves({
576
+ nonce: nonce,
577
+ freeBalance: 1510000000000,
578
+ });
579
+ accountInfoCB.withArgs(testData.consolidationWrwUser.walletAddress3).resolves({
580
+ nonce: nonce,
581
+ freeBalance: 1510000000000,
582
+ });
583
+ const headerInfoCB = sandBox.stub(src_1.Dot.prototype, 'getHeaderInfo');
584
+ headerInfoCB.resolves({
585
+ headerNumber: testData.westendBlock.blockNumber,
586
+ headerHash: testData.westendBlock.hash,
587
+ });
588
+ const getFeeCB = sandBox.stub(src_1.Dot.prototype, 'getFee');
589
+ getFeeCB.withArgs(baseAddr, testData.consolidationWrwUser.walletAddress1, 10000000000).resolves(15783812856);
590
+ getFeeCB.withArgs(baseAddr, testData.consolidationWrwUser.walletAddress2, 1510000000000).resolves(15783812856);
591
+ getFeeCB.withArgs(baseAddr, testData.consolidationWrwUser.walletAddress3, 1510000000000).resolves(15783812856);
592
+ const getMaterialCB = sandBox.stub(src_1.Dot.prototype, 'getMaterial');
593
+ getMaterialCB.resolves(utils_1.default.getMaterial(statics_1.coins.get('tdot')));
594
+ });
595
+ afterEach(function () {
596
+ sandBox.restore();
597
+ });
598
+ // TODO(COIN-919): Fix failing test
599
+ xit('should build signed consolidation recoveries', async function () {
600
+ const res = await basecoin.recoverConsolidations({
601
+ userKey: testData.consolidationWrwUser.userKey,
602
+ backupKey: testData.consolidationWrwUser.backupKey,
603
+ bitgoKey: testData.consolidationWrwUser.bitgoKey,
604
+ walletPassphrase: testData.consolidationWrwUser.walletPassphrase,
605
+ startingScanIndex: 1,
606
+ endingScanIndex: 4,
607
+ });
608
+ res.should.not.be.empty();
609
+ res.transactions.length.should.equal(2);
610
+ sandBox.assert.calledThrice(basecoin.getAccountInfo);
611
+ sandBox.assert.calledTwice(basecoin.getHeaderInfo);
612
+ const txn1 = res.transactions[0];
613
+ txn1.should.hasOwnProperty('serializedTx');
614
+ txn1.should.hasOwnProperty('scanIndex');
615
+ txn1.scanIndex.should.equal(2);
616
+ // deserialize the txn and verify the fields are what we expect
617
+ const txBuilder1 = basecoin.getBuilder().from(txn1.serializedTx);
618
+ // some information isn't deserialized by the from method, so we will
619
+ // supply it again in order to re-build the txn
620
+ txBuilder1
621
+ .validity({
622
+ firstValid: testData.westendBlock.blockNumber,
623
+ maxDuration: basecoin.MAX_VALIDITY_DURATION,
624
+ })
625
+ .referenceBlock(testData.westendBlock.hash);
626
+ const tx1 = await txBuilder1.build();
627
+ const txJson1 = tx1.toJson();
628
+ should.deepEqual(txJson1.sender, testData.consolidationWrwUser.walletAddress2);
629
+ should.deepEqual(txJson1.blockNumber, testData.westendBlock.blockNumber);
630
+ should.deepEqual(txJson1.referenceBlock, testData.westendBlock.hash);
631
+ should.deepEqual(txJson1.genesisHash, resources_1.genesisHash);
632
+ should.deepEqual(txJson1.specVersion, resources_1.specVersion);
633
+ should.deepEqual(txJson1.nonce, nonce);
634
+ should.deepEqual(txJson1.tip, 0);
635
+ should.deepEqual(txJson1.transactionVersion, resources_1.txVersion);
636
+ should.deepEqual(txJson1.chainName, resources_1.chainName);
637
+ // eraPeriod will always round to the next upper power of 2 for any input value, in this case 2400.
638
+ // 4096 is the "highest" value you can set, but the txn still may fail after 2400 blocks.
639
+ const eraPeriod = 4096;
640
+ should.deepEqual(txJson1.eraPeriod, eraPeriod);
641
+ should.deepEqual(txJson1.to, baseAddr);
642
+ res.lastScanIndex.should.equal(3);
643
+ const txn2 = res.transactions[1];
644
+ txn2.should.hasOwnProperty('serializedTx');
645
+ txn2.should.hasOwnProperty('scanIndex');
646
+ txn2.scanIndex.should.equal(3);
647
+ // deserialize the txn and verify the fields are what we expect
648
+ const txBuilder2 = basecoin.getBuilder().from(txn2.serializedTx);
649
+ // some information isn't deserialized by the from method, so we will
650
+ // supply it again in order to re-build the txn
651
+ txBuilder2
652
+ .validity({
653
+ firstValid: testData.westendBlock.blockNumber,
654
+ maxDuration: basecoin.MAX_VALIDITY_DURATION,
655
+ })
656
+ .referenceBlock(testData.westendBlock.hash);
657
+ const tx2 = await txBuilder2.build();
658
+ const txJson2 = tx2.toJson();
659
+ should.deepEqual(txJson2.sender, testData.consolidationWrwUser.walletAddress3);
660
+ should.deepEqual(txJson2.blockNumber, testData.westendBlock.blockNumber);
661
+ should.deepEqual(txJson2.referenceBlock, testData.westendBlock.hash);
662
+ should.deepEqual(txJson2.genesisHash, resources_1.genesisHash);
663
+ should.deepEqual(txJson2.specVersion, resources_1.specVersion);
664
+ should.deepEqual(txJson2.nonce, nonce);
665
+ should.deepEqual(txJson2.tip, 0);
666
+ should.deepEqual(txJson2.transactionVersion, resources_1.txVersion);
667
+ should.deepEqual(txJson2.chainName, resources_1.chainName);
668
+ should.deepEqual(txJson2.eraPeriod, eraPeriod);
669
+ should.deepEqual(txJson2.to, baseAddr);
670
+ });
671
+ it('should build unsigned consolidation recoveries', async function () {
672
+ const res = await basecoin.recoverConsolidations({
673
+ bitgoKey: testData.consolidationWrwUser.bitgoKey,
674
+ startingScanIndex: 1,
675
+ endingScanIndex: 4,
676
+ });
677
+ res.should.not.be.empty();
678
+ res.txRequests.length.should.equal(2);
679
+ sandBox.assert.calledThrice(basecoin.getAccountInfo);
680
+ sandBox.assert.calledTwice(basecoin.getHeaderInfo);
681
+ const txn1 = res.txRequests[0].transactions[0].unsignedTx;
682
+ txn1.should.hasOwnProperty('serializedTx');
683
+ txn1.should.hasOwnProperty('signableHex');
684
+ txn1.should.hasOwnProperty('scanIndex');
685
+ txn1.scanIndex.should.equal(2);
686
+ txn1.should.hasOwnProperty('coin');
687
+ txn1.coin.should.equal('tdot');
688
+ txn1.should.hasOwnProperty('derivationPath');
689
+ txn1.derivationPath.should.equal('m/2');
690
+ txn1.should.hasOwnProperty('coinSpecific');
691
+ const coinSpecific1 = txn1.coinSpecific;
692
+ coinSpecific1.should.hasOwnProperty('commonKeychain');
693
+ coinSpecific1.should.hasOwnProperty('firstValid');
694
+ coinSpecific1.firstValid.should.equal(testData.westendBlock.blockNumber);
695
+ coinSpecific1.should.hasOwnProperty('maxDuration');
696
+ coinSpecific1.maxDuration.should.equal(basecoin.MAX_VALIDITY_DURATION);
697
+ // deserialize the txn and verify the fields are what we expect
698
+ const txBuilder1 = basecoin.getBuilder().from(txn1.serializedTx);
699
+ // some information isn't deserialized by the from method, so we will
700
+ // supply it again in order to re-build the txn
701
+ txBuilder1
702
+ .validity({
703
+ firstValid: testData.westendBlock.blockNumber,
704
+ maxDuration: basecoin.MAX_VALIDITY_DURATION,
705
+ })
706
+ .referenceBlock(testData.westendBlock.hash)
707
+ .sender({ address: testData.consolidationWrwUser.walletAddress2 });
708
+ const tx1 = await txBuilder1.build();
709
+ const txJson1 = tx1.toJson();
710
+ should.deepEqual(txJson1.sender, testData.consolidationWrwUser.walletAddress2);
711
+ should.deepEqual(txJson1.blockNumber, testData.westendBlock.blockNumber);
712
+ should.deepEqual(txJson1.referenceBlock, testData.westendBlock.hash);
713
+ should.deepEqual(txJson1.genesisHash, resources_1.genesisHash);
714
+ should.deepEqual(txJson1.specVersion, resources_1.specVersion);
715
+ should.deepEqual(txJson1.nonce, nonce);
716
+ should.deepEqual(txJson1.tip, 0);
717
+ should.deepEqual(txJson1.transactionVersion, resources_1.txVersion);
718
+ should.deepEqual(txJson1.chainName, resources_1.chainName);
719
+ // eraPeriod will always round to the next upper power of 2 for any input value, in this case 2400.
720
+ // 4096 is the "highest" value you can set, but the txn still may fail after 2400 blocks.
721
+ const eraPeriod = 4096;
722
+ should.deepEqual(txJson1.eraPeriod, eraPeriod);
723
+ should.deepEqual(txJson1.to, baseAddr);
724
+ const txn2 = res.txRequests[1].transactions[0].unsignedTx;
725
+ txn2.should.hasOwnProperty('serializedTx');
726
+ txn2.should.hasOwnProperty('signableHex');
727
+ txn2.should.hasOwnProperty('scanIndex');
728
+ txn2.scanIndex.should.equal(3);
729
+ txn2.should.hasOwnProperty('coin');
730
+ txn2.coin.should.equal('tdot');
731
+ txn2.should.hasOwnProperty('derivationPath');
732
+ txn2.derivationPath.should.equal('m/3');
733
+ txn2.should.hasOwnProperty('coinSpecific');
734
+ const coinSpecific2 = txn2.coinSpecific;
735
+ coinSpecific2.should.hasOwnProperty('commonKeychain');
736
+ coinSpecific2.should.hasOwnProperty('firstValid');
737
+ coinSpecific2.firstValid.should.equal(testData.westendBlock.blockNumber);
738
+ coinSpecific2.should.hasOwnProperty('maxDuration');
739
+ coinSpecific2.maxDuration.should.equal(basecoin.MAX_VALIDITY_DURATION);
740
+ coinSpecific2.should.hasOwnProperty('commonKeychain');
741
+ coinSpecific2.should.hasOwnProperty('lastScanIndex');
742
+ coinSpecific2.lastScanIndex.should.equal(3);
743
+ // deserialize the txn and verify the fields are what we expect
744
+ const txBuilder2 = basecoin.getBuilder().from(txn2.serializedTx);
745
+ // some information isn't deserialized by the from method, so we will
746
+ // supply it again in order to re-build the txn
747
+ txBuilder2
748
+ .validity({
749
+ firstValid: testData.westendBlock.blockNumber,
750
+ maxDuration: basecoin.MAX_VALIDITY_DURATION,
751
+ })
752
+ .referenceBlock(testData.westendBlock.hash)
753
+ .sender({ address: testData.consolidationWrwUser.walletAddress3 });
754
+ const tx2 = await txBuilder2.build();
755
+ const txJson2 = tx2.toJson();
756
+ should.deepEqual(txJson2.sender, testData.consolidationWrwUser.walletAddress3);
757
+ should.deepEqual(txJson2.blockNumber, testData.westendBlock.blockNumber);
758
+ should.deepEqual(txJson2.referenceBlock, testData.westendBlock.hash);
759
+ should.deepEqual(txJson2.genesisHash, resources_1.genesisHash);
760
+ should.deepEqual(txJson2.specVersion, resources_1.specVersion);
761
+ should.deepEqual(txJson2.nonce, nonce);
762
+ should.deepEqual(txJson2.tip, 0);
763
+ should.deepEqual(txJson2.transactionVersion, resources_1.txVersion);
764
+ should.deepEqual(txJson2.chainName, resources_1.chainName);
765
+ should.deepEqual(txJson2.eraPeriod, eraPeriod);
766
+ should.deepEqual(txJson2.to, baseAddr);
767
+ });
768
+ it('should skip building consolidate transaction if balance is equal to zero', async function () {
769
+ await basecoin
770
+ .recoverConsolidations({
771
+ userKey: testData.consolidationWrwUser.userKey,
772
+ backupKey: testData.consolidationWrwUser.backupKey,
773
+ bitgoKey: testData.consolidationWrwUser.bitgoKey,
774
+ walletPassphrase: testData.consolidationWrwUser.walletPassphrase,
775
+ startingScanIndex: 1,
776
+ endingScanIndex: 2,
777
+ })
778
+ .should.rejectedWith('Did not find an address with funds to recover');
779
+ });
780
+ it('should throw if startingScanIndex is not ge to 1', async () => {
781
+ await basecoin
782
+ .recoverConsolidations({
783
+ userKey: testData.consolidationWrwUser.userKey,
784
+ backupKey: testData.consolidationWrwUser.backupKey,
785
+ bitgoKey: testData.consolidationWrwUser.bitgoKey,
786
+ startingScanIndex: -1,
787
+ })
788
+ .should.be.rejectedWith('Invalid starting or ending index to scan for addresses. startingScanIndex: -1, endingScanIndex: 19.');
789
+ });
790
+ it('should throw if scan factor is too high', async () => {
791
+ await basecoin
792
+ .recoverConsolidations({
793
+ userKey: testData.consolidationWrwUser.userKey,
794
+ backupKey: testData.consolidationWrwUser.backupKey,
795
+ bitgoKey: testData.consolidationWrwUser.bitgoKey,
796
+ startingScanIndex: 1,
797
+ endingScanIndex: 300,
798
+ })
799
+ .should.be.rejectedWith('Invalid starting or ending index to scan for addresses. startingScanIndex: 1, endingScanIndex: 300.');
800
+ });
801
+ });
802
+ describe('Build Consolidation Recoveries (MPCv2):', () => {
803
+ const sandBox = sinon.createSandbox();
804
+ const nonce = 123;
805
+ const walletPassphrase = testData.wrwUser.walletPassphrase;
806
+ let mpcV2UserKey;
807
+ let mpcV2BackupKey;
808
+ let mpcV2CommonKeyChain;
809
+ let baseAddr;
810
+ let mpcV2Address1;
811
+ let mpcV2Address2;
812
+ let mpcV2Address3;
813
+ before(async function () {
814
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
815
+ mpcV2UserKey = await (0, sdk_api_1.encrypt)(walletPassphrase, userDkg.getReducedKeyShare().toString('base64'));
816
+ mpcV2BackupKey = await (0, sdk_api_1.encrypt)(walletPassphrase, backupDkg.getReducedKeyShare().toString('base64'));
817
+ mpcV2CommonKeyChain = userDkg.getCommonKeychain();
818
+ const mpc = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
819
+ baseAddr = basecoin.getAddressFromPublicKey(mpc.deriveUnhardened(mpcV2CommonKeyChain, 'm/0').slice(0, 64));
820
+ mpcV2Address1 = basecoin.getAddressFromPublicKey(mpc.deriveUnhardened(mpcV2CommonKeyChain, 'm/1').slice(0, 64));
821
+ mpcV2Address2 = basecoin.getAddressFromPublicKey(mpc.deriveUnhardened(mpcV2CommonKeyChain, 'm/2').slice(0, 64));
822
+ mpcV2Address3 = basecoin.getAddressFromPublicKey(mpc.deriveUnhardened(mpcV2CommonKeyChain, 'm/3').slice(0, 64));
823
+ });
824
+ beforeEach(function () {
825
+ const accountInfoCB = sandBox.stub(src_1.Dot.prototype, 'getAccountInfo');
826
+ accountInfoCB.withArgs(mpcV2Address1).resolves({ nonce, freeBalance: 0 });
827
+ accountInfoCB.withArgs(mpcV2Address2).resolves({ nonce, freeBalance: 1510000000000 });
828
+ accountInfoCB.withArgs(mpcV2Address3).resolves({ nonce, freeBalance: 1510000000000 });
829
+ const headerInfoCB = sandBox.stub(src_1.Dot.prototype, 'getHeaderInfo');
830
+ headerInfoCB.resolves({
831
+ headerNumber: testData.westendBlock.blockNumber,
832
+ headerHash: testData.westendBlock.hash,
833
+ });
834
+ const getFeeCB = sandBox.stub(src_1.Dot.prototype, 'getFee');
835
+ getFeeCB.resolves(15783812856);
836
+ const getMaterialCB = sandBox.stub(src_1.Dot.prototype, 'getMaterial');
837
+ getMaterialCB.resolves(utils_1.default.getMaterial(statics_1.coins.get('tdot')));
838
+ });
839
+ afterEach(function () {
840
+ sandBox.restore();
841
+ });
842
+ it('should build MPCv2 signed consolidation recoveries across 2+ funded indexes, sweeping to the MPCv2 base address', async function () {
843
+ const getEddsaMaterialSpy = sandBox.spy(basecoin, 'getEddsaSigningMaterial');
844
+ const res = (await basecoin.recoverConsolidations({
845
+ userKey: mpcV2UserKey,
846
+ backupKey: mpcV2BackupKey,
847
+ bitgoKey: mpcV2CommonKeyChain,
848
+ walletPassphrase,
849
+ startingScanIndex: 1,
850
+ endingScanIndex: 4,
851
+ }));
852
+ res.should.not.be.empty();
853
+ res.transactions.length.should.equal(2);
854
+ should.equal(res.lastScanIndex, 3);
855
+ const txBuilder1 = basecoin.getBuilder().from(res.transactions[0].serializedTx);
856
+ txBuilder1
857
+ .validity({ firstValid: testData.westendBlock.blockNumber, maxDuration: basecoin.MAX_VALIDITY_DURATION })
858
+ .referenceBlock(testData.westendBlock.hash);
859
+ const tx1 = await txBuilder1.build();
860
+ should.deepEqual(tx1.toJson().to, baseAddr);
861
+ // recoverConsolidations must detect signing material exactly once at the top of the scan
862
+ // loop, not per-iteration inside recover() — precomputedMaterial bypasses per-call detection.
863
+ sandBox.assert.calledOnce(getEddsaMaterialSpy);
864
+ });
865
+ it('should call getEddsaSigningMaterial exactly once across all recover() iterations', async function () {
866
+ const getEddsaMaterialSpy = sandBox.spy(basecoin, 'getEddsaSigningMaterial');
867
+ await basecoin.recoverConsolidations({
868
+ userKey: mpcV2UserKey,
869
+ backupKey: mpcV2BackupKey,
870
+ bitgoKey: mpcV2CommonKeyChain,
871
+ walletPassphrase,
872
+ startingScanIndex: 1,
873
+ endingScanIndex: 4,
874
+ });
875
+ sandBox.assert.calledOnce(getEddsaMaterialSpy);
876
+ });
877
+ it('should leave MPCv1 base address derivation and signing unchanged (regression)', async function () {
878
+ const baseAddrV1 = testData.consolidationWrwUser.walletAddress0;
879
+ basecoin.getAccountInfo.withArgs(testData.consolidationWrwUser.walletAddress1).resolves({
880
+ nonce,
881
+ freeBalance: 10000000000,
882
+ });
883
+ basecoin.getAccountInfo.withArgs(testData.consolidationWrwUser.walletAddress2).resolves({
884
+ nonce,
885
+ freeBalance: 1510000000000,
886
+ });
887
+ const getTSSSignatureSpy = sandBox.spy(sdk_core_1.EDDSAMethods, 'getTSSSignature');
888
+ const res = (await basecoin.recoverConsolidations({
889
+ userKey: testData.consolidationWrwUser.userKey,
890
+ backupKey: testData.consolidationWrwUser.backupKey,
891
+ bitgoKey: testData.consolidationWrwUser.bitgoKey,
892
+ walletPassphrase: testData.consolidationWrwUser.walletPassphrase,
893
+ startingScanIndex: 1,
894
+ endingScanIndex: 3,
895
+ }));
896
+ res.should.not.be.empty();
897
+ sandBox.assert.calledOnce(getTSSSignatureSpy);
898
+ const txBuilder1 = basecoin.getBuilder().from(res.transactions[0].serializedTx);
899
+ txBuilder1
900
+ .validity({ firstValid: testData.westendBlock.blockNumber, maxDuration: basecoin.MAX_VALIDITY_DURATION })
901
+ .referenceBlock(testData.westendBlock.hash);
902
+ const tx1 = await txBuilder1.build();
903
+ should.deepEqual(tx1.toJson().to, baseAddrV1);
904
+ });
905
+ it('should leave the unsigned (no passphrase) cold path unchanged when keycard is MPCv2', async function () {
906
+ const res = (await basecoin.recoverConsolidations({
907
+ bitgoKey: mpcV2CommonKeyChain,
908
+ startingScanIndex: 1,
909
+ endingScanIndex: 4,
910
+ }));
911
+ res.should.not.be.empty();
912
+ res.txRequests.length.should.equal(2);
913
+ });
914
+ });
915
+ describe('Recover Transaction Failures:', () => {
916
+ const sandBox = sinon.createSandbox();
917
+ const destAddr = testData.accounts.account1.address;
918
+ const nonce = 123;
919
+ beforeEach(function () {
920
+ const accountInfoCB = sandBox.stub(src_1.Dot.prototype, 'getAccountInfo');
921
+ accountInfoCB.resolves({
922
+ nonce: nonce,
923
+ freeBalance: 0,
924
+ });
925
+ const getFeeCB = sandBox.stub(src_1.Dot.prototype, 'getFee');
926
+ getFeeCB.resolves(15783812856);
927
+ });
928
+ afterEach(function () {
929
+ sandBox.restore();
930
+ });
931
+ it('should fail to recover due to not finding an address with funds', async function () {
932
+ await basecoin
933
+ .recover({
934
+ userKey: testData.wrwUser.userKey,
935
+ backupKey: testData.wrwUser.backupKey,
936
+ bitgoKey: testData.wrwUser.bitgoKey,
937
+ walletPassphrase: testData.wrwUser.walletPassphrase,
938
+ recoveryDestination: destAddr,
939
+ })
940
+ .should.rejectedWith('Did not find address with funds to recover');
941
+ });
942
+ });
943
+ describe('Verify Transaction', function () {
944
+ const address1 = '5Ge59qRnZa8bxyhVFE6BDoY3kuhSrNVETRxXYLty1Hh6XTaf';
945
+ const address2 = '5DiMLZugmcKEH3igPZP367FqummZkWeW5Z6zDCHLfxRjnPXe';
946
+ it('should reject a txPrebuild with more than one recipient', async function () {
947
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
948
+ const txParams = {
949
+ recipients: [
950
+ { amount: '1000000000000', address: address1 },
951
+ { amount: '2500000000000', address: address2 },
952
+ ],
953
+ wallet: wallet,
954
+ walletPassphrase: 'fakeWalletPassphrase',
955
+ };
956
+ const txPrebuild = {
957
+ txHex: '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300',
958
+ };
959
+ await basecoin
960
+ .verifyTransaction({ txPrebuild, txParams })
961
+ .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.`);
962
+ });
963
+ it('should reject a txPrebuild with more than invalid amount', async function () {
964
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
965
+ const txParams = {
966
+ recipients: [{ amount: '20000000000', address: '5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD' }],
967
+ wallet: wallet,
968
+ walletPassphrase: 'fakeWalletPassphrase',
969
+ };
970
+ const txPrebuild = {
971
+ txHex: '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300',
972
+ };
973
+ await basecoin
974
+ .verifyTransaction({ txPrebuild, txParams })
975
+ .should.be.rejectedWith(`Recipient amount 20000000000 does not match transaction amount 2000000000000`);
976
+ });
977
+ it('should reject a txPrebuild with more than invalid recipient', async function () {
978
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
979
+ const txParams = {
980
+ recipients: [{ amount: '2000000000000', address: '5CZh773vKGwKFCUjGc31AwXCbf7TPkavduk2XoujJMjbBD' }],
981
+ wallet: wallet,
982
+ walletPassphrase: 'fakeWalletPassphrase',
983
+ };
984
+ const txPrebuild = {
985
+ txHex: '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300',
986
+ };
987
+ await basecoin
988
+ .verifyTransaction({ txPrebuild, txParams })
989
+ .should.be.rejectedWith(`Recipient address 5CZh773vKGwKFCUjGc31AwXCbf7TPkavduk2XoujJMjbBD does not match transaction destination address 5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD`);
990
+ });
991
+ it('should accept a txPrebuild with more than valid recipient and amount', async function () {
992
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
993
+ const txParams = {
994
+ recipients: [{ amount: '2000000000000', address: '5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD' }],
995
+ wallet: wallet,
996
+ walletPassphrase: 'fakeWalletPassphrase',
997
+ };
998
+ const txPrebuild = {
999
+ txHex: '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300',
1000
+ };
1001
+ const result = await basecoin.verifyTransaction({ txPrebuild, txParams });
1002
+ assert.strictEqual(result, true);
1003
+ });
1004
+ it('should verify a valid consolidation transaction', async function () {
1005
+ const mockedWallet = {
1006
+ coinSpecific: () => ({
1007
+ baseAddress: '5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD',
1008
+ }),
1009
+ };
1010
+ const txPrebuild = {
1011
+ txHex: '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300',
1012
+ };
1013
+ const result = await basecoin.verifyTransaction({
1014
+ txPrebuild,
1015
+ txParams: {},
1016
+ wallet: mockedWallet,
1017
+ verification: {
1018
+ consolidationToBaseAddress: true,
1019
+ },
1020
+ });
1021
+ assert.strictEqual(result, true);
1022
+ });
1023
+ it('should reject a consolidation transaction with invalid destination address', async function () {
1024
+ const mockedWallet = {
1025
+ coinSpecific: () => ({
1026
+ baseAddress: '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74',
1027
+ }),
1028
+ };
1029
+ const txPrebuild = {
1030
+ txHex: '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300',
1031
+ };
1032
+ await basecoin
1033
+ .verifyTransaction({
1034
+ txPrebuild,
1035
+ txParams: {},
1036
+ wallet: mockedWallet,
1037
+ verification: {
1038
+ consolidationToBaseAddress: true,
1039
+ },
1040
+ })
1041
+ .should.be.rejectedWith('Transaction destination address 5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD does not match wallet base address 5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74');
1042
+ });
1043
+ it('should verify a transferAll (sweep) transaction with empty txParams', async function () {
1044
+ const mockedWallet = {
1045
+ coinSpecific: () => ({
1046
+ baseAddress: '5Ffp1wJCPu4hzVDTo7XaMLqZSvSadyUQmxWPDw74CBjECSoq',
1047
+ }),
1048
+ };
1049
+ // TransferAll tx (sweep) - uses method 0a04 (balances.transferAll)
1050
+ const txPrebuild = {
1051
+ txHex: '0x900a04009f7b0675db59d19b4bd9c8c72eaabba75a9863d02b30115b8b3c3ca5c20f025401d50121030000009d880f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9149799bc9602cb5cf201f3425fb8d253b2d4e61fc119dcab3249f307f594754d00',
1052
+ };
1053
+ const result = await basecoin.verifyTransaction({
1054
+ txPrebuild,
1055
+ txParams: {},
1056
+ wallet: mockedWallet,
1057
+ verification: {
1058
+ consolidationToBaseAddress: true,
1059
+ },
1060
+ });
1061
+ assert.strictEqual(result, true);
1062
+ });
1063
+ it('should verify a transferAll (sweep) transaction with recipients in txParams', async function () {
1064
+ const mockedWallet = {
1065
+ coinSpecific: () => ({
1066
+ baseAddress: '5Ffp1wJCPu4hzVDTo7XaMLqZSvSadyUQmxWPDw74CBjECSoq',
1067
+ }),
1068
+ };
1069
+ // TransferAll tx (sweep) - _amount is undefined for these transactions
1070
+ const txPrebuild = {
1071
+ txHex: '0x900a04009f7b0675db59d19b4bd9c8c72eaabba75a9863d02b30115b8b3c3ca5c20f025401d50121030000009d880f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9149799bc9602cb5cf201f3425fb8d253b2d4e61fc119dcab3249f307f594754d00',
1072
+ };
1073
+ const txParams = {
1074
+ recipients: [{ address: '5Ffp1wJCPu4hzVDTo7XaMLqZSvSadyUQmxWPDw74CBjECSoq', amount: '1000000000000' }],
1075
+ };
1076
+ const result = await basecoin.verifyTransaction({
1077
+ txPrebuild,
1078
+ txParams,
1079
+ wallet: mockedWallet,
1080
+ verification: {
1081
+ consolidationToBaseAddress: true,
1082
+ },
1083
+ });
1084
+ assert.strictEqual(result, true);
1085
+ });
1086
+ const wasmTransferKeepAliveHex = '0xa80a0300161b969b6b53ef81225feea3882284c778cd4a406d23215fcf492e83f75d42960b00204aa9d101eb600400000065900f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9a7b7420ee3e4fe2b88da0fc42b30897e18d56d8b56a1934211d9de730cf96de300';
1087
+ const wasmTransferAllHex = '0x900a04009f7b0675db59d19b4bd9c8c72eaabba75a9863d02b30115b8b3c3ca5c20f025401d50121030000009d880f001000000067f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9149799bc9602cb5cf201f3425fb8d253b2d4e61fc119dcab3249f307f594754d00';
1088
+ it('should accept a valid WASM-built payment (tdot)', async function () {
1089
+ const txParams = {
1090
+ recipients: [{ amount: '2000000000000', address: '5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD' }],
1091
+ };
1092
+ const result = await basecoin.verifyTransaction({ txPrebuild: { txHex: wasmTransferKeepAliveHex }, txParams });
1093
+ assert.strictEqual(result, true);
1094
+ });
1095
+ it('should reject WASM-built payment with wrong amount (tdot)', async function () {
1096
+ const txParams = {
1097
+ recipients: [{ amount: '9999', address: '5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD' }],
1098
+ };
1099
+ await basecoin
1100
+ .verifyTransaction({ txPrebuild: { txHex: wasmTransferKeepAliveHex }, txParams })
1101
+ .should.be.rejectedWith(/does not match transaction amount/);
1102
+ });
1103
+ it('should reject WASM-built payment with wrong recipient (tdot)', async function () {
1104
+ const txParams = {
1105
+ recipients: [{ amount: '2000000000000', address: '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74' }],
1106
+ };
1107
+ await basecoin
1108
+ .verifyTransaction({ txPrebuild: { txHex: wasmTransferKeepAliveHex }, txParams })
1109
+ .should.be.rejectedWith(/does not match transaction destination address/);
1110
+ });
1111
+ it('should verify WASM-built transferAll consolidation (tdot)', async function () {
1112
+ const mockedWallet = {
1113
+ coinSpecific: () => ({ baseAddress: '5Ffp1wJCPu4hzVDTo7XaMLqZSvSadyUQmxWPDw74CBjECSoq' }),
1114
+ };
1115
+ const result = await basecoin.verifyTransaction({
1116
+ txPrebuild: { txHex: wasmTransferAllHex },
1117
+ txParams: {},
1118
+ wallet: mockedWallet,
1119
+ verification: { consolidationToBaseAddress: true },
1120
+ });
1121
+ assert.strictEqual(result, true);
1122
+ });
1123
+ it('should verify WASM-built transferAll with recipients skips amount check (tdot)', async function () {
1124
+ const mockedWallet = {
1125
+ coinSpecific: () => ({ baseAddress: '5Ffp1wJCPu4hzVDTo7XaMLqZSvSadyUQmxWPDw74CBjECSoq' }),
1126
+ };
1127
+ const txParams = {
1128
+ recipients: [{ address: '5Ffp1wJCPu4hzVDTo7XaMLqZSvSadyUQmxWPDw74CBjECSoq', amount: '999999' }],
1129
+ };
1130
+ const result = await basecoin.verifyTransaction({
1131
+ txPrebuild: { txHex: wasmTransferAllHex },
1132
+ txParams,
1133
+ wallet: mockedWallet,
1134
+ verification: { consolidationToBaseAddress: true },
1135
+ });
1136
+ assert.strictEqual(result, true);
1137
+ });
1138
+ it('should decode wasm-built signing payload with legacy TransactionBuilderFactory', async function () {
1139
+ const { TransactionBuilderFactory } = await Promise.resolve().then(() => __importStar(require('../../src/lib')));
1140
+ const factory = new TransactionBuilderFactory(statics_1.coins.get('tdot'));
1141
+ const txBuilder = factory.from(wasmTransferKeepAliveHex);
1142
+ txBuilder.sender({ address: '5EGoFA95omzemRssELLDjVenNZ68aXyUeqtKQScXSEBvVJkr' });
1143
+ txBuilder.validity({ firstValid: 1000 });
1144
+ txBuilder.referenceBlock('0x149799bc9602cb5cf201f3425fb8d253b2d4e61fc119dcab3249f307f594754d');
1145
+ const tx = await txBuilder.build();
1146
+ const json = tx.toJson();
1147
+ assert.strictEqual(json.to, '5CZh773vKGwKFCYUjGc31AwXCbf7TPkavdeuk2XoujJMjbBD');
1148
+ assert.strictEqual(json.amount, '2000000000000');
1149
+ });
1150
+ });
1151
+ describe('isWalletAddress', () => {
1152
+ it('should verify valid wallet address with correct keychain and index', async function () {
1153
+ const address = '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74';
1154
+ const commonKeychain = '6d2d5150f6e435dfd9b4f225f2cc29d95ec3b61b34e8bec98693b1a7ffe44cd764f99ee5058838d785c73360ad4f24d78e0255ab2c368c09060b29a9b27f040e';
1155
+ const index = '3';
1156
+ const keychains = [{ id: '1', type: 'tss', commonKeychain }];
1157
+ const result = await basecoin.isWalletAddress({ keychains, address, index });
1158
+ result.should.equal(true);
1159
+ });
1160
+ it('should return false for address with incorrect keychain', async function () {
1161
+ const address = '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74';
1162
+ const wrongKeychain = '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
1163
+ const index = '3';
1164
+ const keychains = [{ id: '1', type: 'tss', commonKeychain: wrongKeychain }];
1165
+ const result = await basecoin.isWalletAddress({ keychains, address, index });
1166
+ result.should.equal(false);
1167
+ });
1168
+ it('should return false for address with incorrect index', async function () {
1169
+ const address = '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74';
1170
+ const commonKeychain = '6d2d5150f6e435dfd9b4f225f2cc29d95ec3b61b34e8bec98693b1a7ffe44cd764f99ee5058838d785c73360ad4f24d78e0255ab2c368c09060b29a9b27f040e';
1171
+ const wrongIndex = '999';
1172
+ const keychains = [{ id: '1', type: 'tss', commonKeychain }];
1173
+ const result = await basecoin.isWalletAddress({ keychains, address, index: wrongIndex });
1174
+ result.should.equal(false);
1175
+ });
1176
+ it('should throw error for invalid address', async function () {
1177
+ const invalidAddress = 'invalidaddress';
1178
+ const commonKeychain = '6d2d5150f6e435dfd9b4f225f2cc29d95ec3b61b34e8bec98693b1a7ffe44cd764f99ee5058838d785c73360ad4f24d78e0255ab2c368c09060b29a9b27f040e';
1179
+ const index = '3';
1180
+ const keychains = [{ id: '1', type: 'tss', commonKeychain }];
1181
+ await assert.rejects(async () => await basecoin.isWalletAddress({ keychains, address: invalidAddress, index }), {
1182
+ message: `invalid address: ${invalidAddress}`,
1183
+ });
1184
+ });
1185
+ });
1186
+ describe('getAddressFromPublicKey', () => {
1187
+ it('should convert public key to SS58 address for testnet', function () {
1188
+ const publicKey = '53845d7b6a6e4a666fa2a0f500b88849b02926da5590993731d2b428b7643690';
1189
+ const expectedAddress = '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74';
1190
+ const address = basecoin.getAddressFromPublicKey(publicKey);
1191
+ address.should.equal(expectedAddress);
1192
+ });
1193
+ it('should convert public key to SS58 address for mainnet', function () {
1194
+ const publicKey = '53845d7b6a6e4a666fa2a0f500b88849b02926da5590993731d2b428b7643690';
1195
+ // Mainnet uses different SS58 prefix (0) vs testnet (42)
1196
+ const address = prodCoin.getAddressFromPublicKey(publicKey);
1197
+ address.should.be.type('string');
1198
+ address.length.should.be.greaterThan(0);
1199
+ // Should be different from testnet address
1200
+ address.should.not.equal('5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74');
1201
+ });
1202
+ });
1203
+ });
1204
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG90LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L2RvdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLGlEQUF3RDtBQUN4RCxtREFBK0Q7QUFDL0QsbUNBQXFDO0FBQ3JDLGlDQUFrQztBQUNsQyxpQ0FBa0M7QUFDbEMsbUNBQStDO0FBQy9DLHNEQUF3QztBQUN4Qyw0Q0FBOEU7QUFDOUUsNkNBQStCO0FBQy9CLG1EQUE0RjtBQUM1RixpREFBNEM7QUFDNUMsOENBQXFGO0FBQ3JGLHlEQUFrRDtBQUNsRCxnRUFBd0M7QUFDeEMsdUNBQXNEO0FBRXRELFFBQVEsQ0FBQyxNQUFNLEVBQUU7SUFDZixJQUFJLEtBQW1CLENBQUM7SUFDeEIsSUFBSSxRQUFRLENBQUM7SUFDYixJQUFJLFFBQVEsQ0FBQztJQUViLE1BQU0sQ0FBQztRQUNMLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxrQkFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdEQsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsU0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzlDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLFVBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNoRCxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMzQixRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5QixRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMvQixDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxjQUFjLEVBQUUsR0FBRyxFQUFFO1FBQzVCLEVBQUUsQ0FBQyxxQkFBcUIsRUFBRSxLQUFLLElBQUksRUFBRTtZQUNuQyxNQUFNLE9BQU8s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TUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0MsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0QsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN2RCxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDNUUsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUN6RixRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUUsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzVFLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDeEYsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3JGLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDckYsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDNUYsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekYsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ3ZGLGtEQUFrRCxDQUNuRCxDQUFDO1lBQ0YsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDL0csUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDdkcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDN0YsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDMUYsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ3hGLGtEQUFrRCxDQUNuRCxDQUFDO1lBQ0YsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDaEgsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDcEcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNqRixRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3BGLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDOUUsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN0RixRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3pGLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3BHLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDOUYsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENB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QUFrRCxDQUFDLENBQUM7UUFDL0UsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQml0R29BUEksIGVuY3J5cHQgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstYXBpJztcbmltcG9ydCB7IFRlc3RCaXRHbywgVGVzdEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLXRlc3QnO1xuaW1wb3J0IHsgcmFuZG9tQnl0ZXMgfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHNob3VsZCA9IHJlcXVpcmUoJ3Nob3VsZCcpO1xuaW1wb3J0IGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpO1xuaW1wb3J0IHsgRG90LCBUZG90LCBLZXlQYWlyIH0gZnJvbSAnLi4vLi4vc3JjJztcbmltcG9ydCAqIGFzIHRlc3REYXRhIGZyb20gJy4uL2ZpeHR1cmVzJztcbmltcG9ydCB7IGNoYWluTmFtZSwgdHhWZXJzaW9uLCBnZW5lc2lzSGFzaCwgc3BlY1ZlcnNpb24gfSBmcm9tICcuLi9yZXNvdXJjZXMnO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IHsgRUREU0FNZXRob2RzLCBNUENUeCwgTVBDVHhzLCBUcmFuc2FjdGlvblR5cGUsIFdhbGxldCB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IGNvaW5zIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQgeyBidWlsZFRyYW5zYWN0aW9uLCB0eXBlIEJ1aWxkQ29udGV4dCwgdHlwZSBNYXRlcmlhbCB9IGZyb20gJ0BiaXRnby93YXNtLWRvdCc7XG5pbXBvcnQgeyBNUFNVdGlsIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWxpYi1tcGMnO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4uLy4uL3NyYy9saWIvdXRpbHMnO1xuaW1wb3J0IHsgZXhwbGFpbkRvdFRyYW5zYWN0aW9uIH0gZnJvbSAnLi4vLi4vc3JjL2xpYic7XG5cbmRlc2NyaWJlKCdET1Q6JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGJhc2Vjb2luO1xuICBsZXQgcHJvZENvaW47XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ2RvdCcsIERvdC5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0ZG90JywgVGRvdC5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0ZG90Jyk7XG4gICAgcHJvZENvaW4gPSBiaXRnby5jb2luKCdkb3QnKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1NpZ24gTWVzc2FnZScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGJlIHBlcmZvcm1lZCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGtleVBhaXIgPSBuZXcgS2V5UGFpcigpO1xuICAgICAgY29uc3QgbWVzc2FnZVRvU2lnbiA9IEJ1ZmZlci5mcm9tKHJhbmRvbUJ5dGVzKDMyKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gYXdhaXQgYmFzZWNvaW4uc2lnbk1lc3NhZ2Uoa2V5UGFpci5nZXRLZXlzKCksIG1lc3NhZ2VUb1NpZ24pO1xuICAgICAga2V5UGFpci52ZXJpZnlTaWduYXR1cmUobWVzc2FnZVRvU2lnbiwgVWludDhBcnJheS5mcm9tKHNpZ25hdHVyZSkpLnNob3VsZC5lcXVhbHModHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgd2l0aCBtaXNzaW5nIHByaXZhdGUga2V5JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qga2V5UGFpciA9IG5ldyBLZXlQYWlyKHtcbiAgICAgICAgcHViOiAnNzc4ODMyN2M2OTVkY2E0YjNlNjQ5YTBkYjQ1YmMzZTcwM2EyYzY3NDI4ZmNlMzYwZTYxODAwY2M0MjQ4ZjRmNycsXG4gICAgICB9KS5nZXRLZXlzKCk7XG4gICAgICBjb25zdCBtZXNzYWdlVG9TaWduID0gQnVmZmVyLmZyb20ocmFuZG9tQnl0ZXMoMzIpKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICBhd2FpdCBiYXNlY29pbi5zaWduTWVzc2FnZShrZXlQYWlyLCBtZXNzYWdlVG9TaWduKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIGtleSBwYWlyIG9wdGlvbnMnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1NpZ24gdHJhbnNhY3Rpb24nLCAoKSA9PiB7XG4gICAgY29uc3QgdHJhbnNhY3Rpb24gPSB7XG4gICAgICBpZDogJzB4MTlkZTE1NjMyOGVlYTY2YmQxZWM0NTg0MzU2OWMxNjhlMGJiMmYyODk4MjIxMDI5YjQwM2RmM2YyM2E1NDg5ZCcsXG4gICAgICBzZW5kZXI6ICc1RUdvRkE5NW9temVtUnNzRUxMRGpWZW5OWjY4YVh5VWVxdEtRU2NYU0VCdlZKa3InLFxuICAgICAgcmVmZXJlbmNlQmxvY2s6ICcweDE0OTc5OWJjOTYwMmNiNWNmMjAxZjM0MjVmYjhkMjUzYjJkNGU2MWZjMTE5ZGNhYjMyNDlmMzA3ZjU5NDc1NGQnLFxuICAgICAgYmxvY2tOdW1iZXI6IDM5MzMsXG4gICAgICBnZW5lc2lzSGFzaDogJzB4NjdmOTcyMzM5M2VmNzYyMTRkZjAxMThjMzRiYmJkM2RiZWJjOGVkNDZhMTA5NzNhOGM5NjlkNDhmZTc1OThjOScsXG4gICAgICBub25jZTogMjAwLFxuICAgICAgc3BlY1ZlcnNpb246IDEwMTgwMTMsXG4gICAgICB0cmFuc2FjdGlvblZlcnNpb246IDE2LFxuICAgICAgZXJhUGVyaW9kOiA2NCxcbiAgICAgIGNoYWluTmFtZTogJ1dlc3RlbmQgQXNzZXQgSHViJyxcbiAgICAgIHRpcDogMCxcbiAgICAgIHRvOiAnNUZmcDF3SkNQdTRoelZEVG83WGFNTHFaU3ZTYWR5VVFteFdQRHc3NENCakVDU29xJyxcbiAgICAgIGFtb3VudDogJzEwMDAwMDAwMDAwJyxcbiAgICB9O1xuXG4gICAgLy8gVE9ETzogQkctNDMxOTdcbiAgICB4aXQoJ3Nob3VsZCBzaWduIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnbmVkID0gYXdhaXQgYmFzZWNvaW4uc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgIHR4SGV4OiB0ZXN0RGF0YS5yYXdUeC50cmFuc2Zlci51bnNpZ25lZCxcbiAgICAgICAgICB0cmFuc2FjdGlvbixcbiAgICAgICAgfSxcbiAgICAgICAgcHViczogW3Rlc3REYXRhLmFjY291bnRzLmFjY291bnQxLnB1YmxpY0tleV0sXG4gICAgICAgIHBydjogdGVzdERhdGEuYWNjb3VudHMuYWNjb3VudDEuc2VjcmV0S2V5LFxuICAgICAgfSk7XG4gICAgICBzaWduZWQudHhIZXguc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4LnRyYW5zZmVyLnNpZ25lZCk7XG4gICAgfSk7XG5cbiAgICAvLyBUT0RPOiBCRy00MzE5N1xuICAgIHhpdCgnc2hvdWxkIGZhaWwgdG8gc2lnbiB0cmFuc2FjdGlvbiB3aXRoIGFuIGludmFsaWQga2V5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgYmFzZWNvaW4uc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgICB0eEhleDogdGVzdERhdGEucmF3VHgudHJhbnNmZXIudW5zaWduZWQsXG4gICAgICAgICAgICB0cmFuc2FjdGlvbixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHB1YnM6IFt0ZXN0RGF0YS5hY2NvdW50cy5hY2NvdW50Mi5wdWJsaWNLZXldLFxuICAgICAgICAgIHBydjogdGVzdERhdGEuYWNjb3VudHMuYWNjb3VudDEuc2VjcmV0S2V5LFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgc2hvdWxkLmVxdWFsKGUubWVzc2FnZSwgJ1ByaXZhdGUga2V5IGNhbm5vdCBzaWduIHRoZSB0cmFuc2FjdGlvbicpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIGJ1aWxkIHRyYW5zYWN0aW9uIHdpdGggbWlzc2luZyBwYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICAgIHR4SGV4OiB0ZXN0RGF0YS5yYXdUeC50cmFuc2Zlci51bnNpZ25lZCxcbiAgICAgICAgICAgIGtleTogdGVzdERhdGEuYWNjb3VudHMuYWNjb3VudDEucHVibGljS2V5LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcHJ2OiB0ZXN0RGF0YS5hY2NvdW50cy5hY2NvdW50MS5zZWNyZXRLZXksXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBzaG91bGQubm90RXF1YWwoZSwgbnVsbCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdHZW5lcmF0ZSB3YWxsZXQga2V5IHBhaXI6ICcsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGtleSBwYWlyJywgKCkgPT4ge1xuICAgICAgY29uc3Qga3AgPSBiYXNlY29pbi5nZW5lcmF0ZUtleVBhaXIoKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQdWIoa3AucHViKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkUHJ2KGtwLnBydikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBrZXkgcGFpciBmcm9tIHNlZWQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBzZWVkID0gQnVmZmVyLmZyb20oJzlkNjFiMTlkZWZmZDVhNjBiYTg0NGFmNDkyZWMyY2M0NDQ0OWM1Njk3YjMyNjkxOTcwM2JhYzAzMWNhZTdmNjAnLCAnaGV4Jyk7XG4gICAgICBjb25zdCBrcCA9IGJhc2Vjb2luLmdlbmVyYXRlS2V5UGFpcihzZWVkKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQdWIoa3AucHViKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkUHJ2KGtwLnBydikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQmFsYW5jZSBDb252ZXJzaW9uJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIDEwMDAwMDAwMDAwIGFzIHRkb3QgYmFzZSBmYWN0b3InLCAoKSA9PiB7XG4gICAgICAvLyBtYWlubmV0IHVzZXMgMTAgZGVjaW1hbCBwbGFjZXNcbiAgICAgIGNvbnN0IGJhc2VGYWN0b3IgPSBwcm9kQ29pbi5nZXRCYXNlRmFjdG9yKCk7XG4gICAgICBiYXNlRmFjdG9yLnNob3VsZC5lcXVhbCgxMDAwMDAwMDAwMCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiAxMDAwMDAwMDAwMDAwIGFzIGRvdCBiYXNlIGZhY3RvcicsICgpID0+IHtcbiAgICAgIC8vIHdlc3RlbmQgKHRlc3QgcG9sa2Fkb3QpIHVzZXMgMTIgZGVjaW1hbCBwbGFjZXNcbiAgICAgIGNvbnN0IGJhc2VGYWN0b3IgPSBiYXNlY29pbi5nZXRCYXNlRmFjdG9yKCk7XG4gICAgICBiYXNlRmFjdG9yLnNob3VsZC5lcXVhbCgxMDAwMDAwMDAwMDAwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIDQgRG90IHdoZW4gYmFzZSB1bml0IGlzIDQwMDAwMDAwMDAwIGZvciBkb3QnLCAoKSA9PiB7XG4gICAgICBjb25zdCBiaWdVbml0ID0gcHJvZENvaW4uYmFzZVVuaXRzVG9CaWdVbml0cygnNDAwMDAwMDAwMDAnKTtcbiAgICAgIGJpZ1VuaXQuc2hvdWxkLmVxdWFsKCc0Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiAwLjA0IERvdCB3aGVuIGJhc2UgdW5pdCBpcyA0MDAwMDAwMDAgZm9yIGRvdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGJpZ1VuaXQgPSBwcm9kQ29pbi5iYXNlVW5pdHNUb0JpZ1VuaXRzKCc0MDAwMDAwMDAnKTtcbiAgICAgIGJpZ1VuaXQuc2hvdWxkLmVxdWFsKCcwLjA0Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiA0IHRlc3QgRG90IHdoZW4gYmFzZSB1bml0IGlzIDQwMDAwMDAwMDAwMDAgZm9yIHRkb3QnLCAoKSA9PiB7XG4gICAgICBjb25zdCBiaWdVbml0ID0gYmFzZWNvaW4uYmFzZVVuaXRzVG9CaWdVbml0cygnNDAwMDAwMDAwMDAwMCcpO1xuICAgICAgYmlnVW5pdC5zaG91bGQuZXF1YWwoJzQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIDAuMDQgdGVzdCBEb3Qgd2hlbiBiYXNlIHVuaXQgaXMgNDAwMDAwMDAwIGZvciB0ZG90JywgKCkgPT4ge1xuICAgICAgY29uc3QgYmlnVW5pdCA9IGJhc2Vjb2luLmJhc2VVbml0c1RvQmlnVW5pdHMoJzQwMDAwMDAwMDAwJyk7XG4gICAgICBiaWdVbml0LnNob3VsZC5lcXVhbCgnMC4wNCcpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRXhwbGFpbiBUcmFuc2FjdGlvbnM6JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiB1bnNpZ25lZCB0cmFuc2ZlciB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGxhaW5lZFRyYW5zYWN0aW9uID0gYXdhaXQgcHJvZENvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHRlc3REYXRhLnVuc2lnbmVkVHJhbnNhY3Rpb24pO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogW1xuICAgICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAgICdjaGFuZ2VBbW91bnQnLFxuICAgICAgICAgICdvdXRwdXRzJyxcbiAgICAgICAgICAnY2hhbmdlT3V0cHV0cycsXG4gICAgICAgICAgJ2ZlZScsXG4gICAgICAgICAgJ3R5cGUnLFxuICAgICAgICAgICdzZXF1ZW5jZUlkJyxcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICdibG9ja051bWJlcicsXG4gICAgICAgIF0sXG4gICAgICAgIHNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGZlZTogJzEwJyxcbiAgICAgICAgaWQ6ICcweDBlNTc1MWMwMjZlNTQzYjJlOGFiMmViMDYwOTlkYWExZDFlNWRmNDc3NzhmNzc4N2ZhYWI0NWNkZjEyZmUzYTgnLFxuICAgICAgICB0eXBlOiAnMCcsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnNURrZGRTZlBzV29qamZ1SDlpSkVjVVY3WnNlUTlFSjZSanRObUNSMXczQ0ViOFM5JyxcbiAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnOTAwMzQyMzUyMzUzNTAnLFxuICAgICAgICAgICAgY29pbk5hbWU6ICd0ZG90JyxcbiAgICAgICAgICAgIHdhbGxldDogJzYyYTEyMDU3NTE2NzViMmYwZmU3MjMyOCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgYmxvY2tOdW1iZXI6IDg2MTkzMDcsXG4gICAgICAgIG91dHB1dEFtb3VudDogOTAwMzQyMzUyMzUzNTAsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRXhwbGFpbiBUcmFuc2FjdGlvbnMgKFdBU00pOicsICgpID0+IHtcbiAgICBjb25zdCBjb2luID0gY29pbnMuZ2V0KCd0ZG90Jyk7XG4gICAgY29uc3QgbWF0ZXJpYWwgPSB1dGlscy5nZXRNYXRlcmlhbChjb2luKTtcbiAgICBjb25zdCBTRU5ERVIgPSB0ZXN0RGF0YS5hY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzO1xuICAgIGNvbnN0IFJFQ0lQSUVOVCA9IHRlc3REYXRhLmFjY291bnRzLmFjY291bnQyLmFkZHJlc3M7XG5cbiAgICBmdW5jdGlvbiB3YXNtQ29udGV4dChub25jZSA9IDApOiBCdWlsZENvbnRleHQge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc2VuZGVyOiBTRU5ERVIsXG4gICAgICAgIG5vbmNlLFxuICAgICAgICBtYXRlcmlhbDogbWF0ZXJpYWwgYXMgTWF0ZXJpYWwsXG4gICAgICAgIHZhbGlkaXR5OiB7IGZpcnN0VmFsaWQ6IHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlciwgbWF4RHVyYXRpb246IDI0MDAgfSxcbiAgICAgICAgcmVmZXJlbmNlQmxvY2s6IHRlc3REYXRhLndlc3RlbmRCbG9jay5oYXNoLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYSB0cmFuc2ZlciB2aWEgZXhwbGFpbkRvdFRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSBidWlsZFRyYW5zYWN0aW9uKHsgdHlwZTogJ3BheW1lbnQnLCB0bzogUkVDSVBJRU5ULCBhbW91bnQ6IDEwMDAwMDAwMDAwMDBuIH0sIHdhc21Db250ZXh0KCkpO1xuICAgICAgY29uc3QgZXhwbGFpbmVkID0gZXhwbGFpbkRvdFRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhIZXg6IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCksXG4gICAgICAgIG1hdGVyaWFsLFxuICAgICAgICBzZW5kZXJBZGRyZXNzOiBTRU5ERVIsXG4gICAgICB9KTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGV4cGxhaW5lZC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXhwbGFpbmVkLm91dHB1dHMubGVuZ3RoLCAxKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChleHBsYWluZWQub3V0cHV0c1swXS5hZGRyZXNzLCBSRUNJUElFTlQpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGV4cGxhaW5lZC5vdXRwdXRzWzBdLmFtb3VudCwgJzEwMDAwMDAwMDAwMDAnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChleHBsYWluZWQub3V0cHV0QW1vdW50LCAnMTAwMDAwMDAwMDAwMCcpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGV4cGxhaW5lZC5zZW5kZXIsIFNFTkRFUik7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXhwbGFpbmVkLm1ldGhvZE5hbWUsICdiYWxhbmNlcy50cmFuc2ZlcktlZXBBbGl2ZScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGEgc3Rha2luZyBib25kIHZpYSBleHBsYWluRG90VHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IGJ1aWxkVHJhbnNhY3Rpb24oeyB0eXBlOiAnc3Rha2UnLCBhbW91bnQ6IDUwMDAwMDAwMDAwMDBuLCBwYXllZTogeyB0eXBlOiAnc3Rhc2gnIH0gfSwgd2FzbUNvbnRleHQoMSkpO1xuICAgICAgY29uc3QgZXhwbGFpbmVkID0gZXhwbGFpbkRvdFRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhIZXg6IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCksXG4gICAgICAgIG1hdGVyaWFsLFxuICAgICAgICBzZW5kZXJBZGRyZXNzOiBTRU5ERVIsXG4gICAgICB9KTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGV4cGxhaW5lZC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0FjdGl2YXRlKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChleHBsYWluZWQub3V0cHV0cy5sZW5ndGgsIDEpO1xuICAgICAgLy8gU1RBS0lOR19ERVNUSU5BVElPTjogU1M1OCgweDAwLi4wMCkgc2VudGluZWwsIGJvbmQgZG9lc24ndCB0cmFuc2ZlciB0byBhbiBleHRlcm5hbCBhZGRyZXNzXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXhwbGFpbmVkLm91dHB1dHNbMF0uYWRkcmVzcywgJzVDNGhyZmp3OURqWFpUelYzTXd6cnJBcjlQMU1KaFNydldHV3FpMWVTdXlVcG5oTScpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGV4cGxhaW5lZC5vdXRwdXRzWzBdLmFtb3VudCwgJzUwMDAwMDAwMDAwMDAnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIHRyYW5zZmVyIHZpYSBleHBsYWluRG90VHJhbnNhY3Rpb24gd2l0aCBzZW5kZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IGJ1aWxkVHJhbnNhY3Rpb24oeyB0eXBlOiAncGF5bWVudCcsIHRvOiBSRUNJUElFTlQsIGFtb3VudDogMTAwMDAwMDAwMDAwMG4gfSwgd2FzbUNvbnRleHQoKSk7XG4gICAgICBjb25zdCBleHBsYWluZWQgPSBleHBsYWluRG90VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogdHgudG9Ccm9hZGNhc3RGb3JtYXQoKSxcbiAgICAgICAgbWF0ZXJpYWwsXG4gICAgICAgIHNlbmRlckFkZHJlc3M6IFNFTkRFUixcbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXhwbGFpbmVkLnR5cGUsIFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChleHBsYWluZWQub3V0cHV0cy5sZW5ndGgsIDEpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGV4cGxhaW5lZC5vdXRwdXRzWzBdLmFkZHJlc3MsIFJFQ0lQSUVOVCk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXhwbGFpbmVkLm91dHB1dHNbMF0uYW1vdW50LCAnMTAwMDAwMDAwMDAwMCcpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGV4cGxhaW5lZC5zZW5kZXIsIFNFTkRFUik7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXhwbGFpbmVkLm5vbmNlLCAwKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JlY292ZXIgVHJhbnNhY3Rpb25zOicsICgpID0+IHtcbiAgICBjb25zdCBzYW5kQm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgIGNvbnN0IGRlc3RBZGRyID0gdGVzdERhdGEuYWNjb3VudHMuYWNjb3VudDEuYWRkcmVzcztcbiAgICBjb25zdCBub25jZSA9IDEyMztcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWNjb3VudEluZm9DQiA9IHNhbmRCb3guc3R1YihEb3QucHJvdG90eXBlLCAnZ2V0QWNjb3VudEluZm8nIGFzIGtleW9mIERvdCk7XG4gICAgICBhY2NvdW50SW5mb0NCLndpdGhBcmdzKHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczApLnJlc29sdmVzKHtcbiAgICAgICAgbm9uY2U6IG5vbmNlLFxuICAgICAgICAvLyBNdXN0IGV4Y2VlZCBzdHViYmVkIGdldEZlZSBzbyByZWNvdmVyKCkgZG9lcyBub3QgdGhyb3cgKG1hdGNoZXMgZ2V0RmVlIHdpdGhBcmdzIGFtb3VudCkuXG4gICAgICAgIGZyZWVCYWxhbmNlOiAxNTEwMDAwMDAwMDAwLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBoZWFkZXJJbmZvQ0IgPSBzYW5kQm94LnN0dWIoRG90LnByb3RvdHlwZSwgJ2dldEhlYWRlckluZm8nIGFzIGtleW9mIERvdCk7XG4gICAgICBoZWFkZXJJbmZvQ0IucmVzb2x2ZXMoe1xuICAgICAgICBoZWFkZXJOdW1iZXI6IHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlcixcbiAgICAgICAgaGVhZGVySGFzaDogdGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gsXG4gICAgICB9KTtcbiAgICAgIGFjY291bnRJbmZvQ0Iud2l0aEFyZ3MoJzVEdGcyektqVkVMOHA5a2VTTTRkUTduRDI2c1Z0TWZDc3l4a2h2Wlo5ZnFCYmh3NicpLnJlc29sdmVzKHtcbiAgICAgICAgbm9uY2U6IDAsXG4gICAgICAgIGZyZWVCYWxhbmNlOiAxNTEwMDAwMDAwMDAwLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBnZXRGZWVDQiA9IHNhbmRCb3guc3R1YihEb3QucHJvdG90eXBlLCAnZ2V0RmVlJyBhcyBrZXlvZiBEb3QpO1xuICAgICAgLy8gRGVmYXVsdCBhdm9pZHMgUlBDIHdoZW4gdGVzdHMgdXNlIGEgcmVjb3ZlcnlEZXN0aW5hdGlvbiBvdGhlciB0aGFuIGRlc3RBZGRyIChlLmcuIHVuc2lnbmVkIHN3ZWVwIGZpeHR1cmUpLlxuICAgICAgZ2V0RmVlQ0IucmVzb2x2ZXMoMTU3ODM4MTI4NTYpO1xuICAgICAgZ2V0RmVlQ0Iud2l0aEFyZ3MoZGVzdEFkZHIsIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczAsIDE1MTAwMDAwMDAwMDApLnJlc29sdmVzKDE1NzgzODEyODU2KTtcbiAgICAgIGNvbnN0IGdldE1hdGVyaWFsQ0IgPSBzYW5kQm94LnN0dWIoRG90LnByb3RvdHlwZSwgJ2dldE1hdGVyaWFsJyBhcyBrZXlvZiBEb3QpO1xuICAgICAgZ2V0TWF0ZXJpYWxDQi5yZXNvbHZlcyh1dGlscy5nZXRNYXRlcmlhbChjb2lucy5nZXQoJ3Rkb3QnKSkpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNhbmRCb3gucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSB1bnNpZ25lZCBzd2VlcCBjb3JyZWN0bHknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9XG4gICAgICAgICczY2QxNGY1ZDYwNzQ0Mjg3Y2QzYTUwNTEwZTI5NjQ3NDZiNmZlYWFkNGIyMzAwMDg4ZWFhZTYwZDFhMzVmMGFiYzUxODUzNGQ0M2IyNjE0MzcwZDlhMjYzYWFkYjU3ZWRiNWQwYjc4ZjgxNmE1MTljZDU4OTZlNzM1MjkyMGI2Nyc7XG4gICAgICBjb25zdCByZWNvdmVyeURlc3RpbmF0aW9uID0gJzVHUEF2ZU12bURzanhWVDZRMnhpdTVrWVBiRkFtZGViSGFpTlpLMTRGQmFTYUFLaCc7XG5cbiAgICAgIGNvbnN0IHVuc2lnbmVkID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7IGJpdGdvS2V5OiBjb21tb25LZXljaGFpbiwgcmVjb3ZlcnlEZXN0aW5hdGlvbiB9KTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHMuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLndhbGxldENvaW4uc2hvdWxkLmVxdWFsKCd0ZG90Jyk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5ub3QuYmUudW5kZWZpbmVkKCk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNlcmlhbGl6ZWRUeC5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zY2FuSW5kZXguc2hvdWxkLmVxdWFsKDApO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5jb2luLnNob3VsZC5lcXVhbCgndGRvdCcpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaWduYWJsZUhleC5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5kZXJpdmF0aW9uUGF0aC5zaG91bGQuZXF1YWwoJ20vMCcpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC5pbnB1dHMuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHguaW5wdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4LmlucHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChcbiAgICAgICAgJzVEdGcyektqVkVMOHA5a2VTTTRkUTduRDI2c1Z0TWZDc3l4a2h2Wlo5ZnFCYmh3NidcbiAgICAgICk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4LmlucHV0c1swXS52YWx1ZVN0cmluZy5zaG91bGQuZXF1YWwoJzE1MTAwMDAwMDAwMDAnKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHguaW5wdXRzWzBdLnZhbHVlLnNob3VsZC5lcXVhbCgxNTEwMDAwMDAwMDAwKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHgub3V0cHV0cy5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4Lm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwoXG4gICAgICAgICc1R1BBdmVNdm1Ec2p4VlQ2UTJ4aXU1a1lQYkZBbWRlYkhhaU5aSzE0RkJhU2FBS2gnXG4gICAgICApO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC5vdXRwdXRzWzBdLnZhbHVlU3RyaW5nLnNob3VsZC5lcXVhbCgnMTUxMDAwMDAwMDAwMCcpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC5vdXRwdXRzWzBdLmNvaW5OYW1lLnNob3VsZC5lcXVhbCgndGRvdCcpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC50eXBlLnNob3VsZC5lcXVhbCgnJyk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmZlZUluZm8uc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguZmVlSW5mby5mZWUuc2hvdWxkLmVxdWFsKDApO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5mZWVJbmZvLmZlZVN0cmluZy5zaG91bGQuZXF1YWwoJzAnKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguY29pblNwZWNpZmljLnNob3VsZC5ub3QuYmUudW5kZWZpbmVkKCk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpYy5maXJzdFZhbGlkLnNob3VsZC5ub3QuYmUudW5kZWZpbmVkKCk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpYy5tYXhEdXJhdGlvbi5zaG91bGQuZXF1YWwoMjQwMCk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpYy5jb21tb25LZXljaGFpbi5zaG91bGQuZXF1YWwoXG4gICAgICAgICczY2QxNGY1ZDYwNzQ0Mjg3Y2QzYTUwNTEwZTI5NjQ3NDZiNmZlYWFkNGIyMzAwMDg4ZWFhZTYwZDFhMzVmMGFiYzUxODUzNGQ0M2IyNjE0MzcwZDlhMjYzYWFkYjU3ZWRiNWQwYjc4ZjgxNmE1MTljZDU4OTZlNzM1MjkyMGI2NydcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICAvLyBUT0RPKENPSU4tOTE5KTogRml4IGZhaWxpbmcgdGVzdFxuICAgIHhpdCgnc2hvdWxkIHRha2UgT1ZDIG91dHB1dCBhbmQgZ2VuZXJhdGUgYSBzaWduZWQgc3dlZXAgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB0ZXN0RGF0YS5vdmNSZXNwb25zZTtcblxuICAgICAgY29uc3QgcmVjb3ZlcnlUeG4gPSBhd2FpdCBiYXNlY29pbi5jcmVhdGVCcm9hZGNhc3RhYmxlU3dlZXBUcmFuc2FjdGlvbihwYXJhbXMpO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzBdLnNlcmlhbGl6ZWRUeC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcweDJkMDI4NDAwNTBkMWUxMTZjZGIzMmU2MWJhM2VjZTI3NWI2MjBmNTAzZjBjNWFlNGU3NjkwZDlmOWFhN2UwYjUwMzAzOTc2YzAwMDU3YzEzMWNkZTJiZTM5ZjRmZjIzZWViYTExMTM5YzQ2ZGQ4YzZkNjlmZjUxN2FiZWRlMzczODFkOGQyNGYwYmIzMGZkODgwNWIyZTUxYTllMmE3NTMzOGQ3ZmI3ZWRiMjkwYmU5NjM4ZGViZWRiZmMwMDFkMTBiODEzMmJlMGIyYjRhMDQwMDA0MDQwMGJmMDY3OGQzMTJiMmIyYzdlZmZkMmIxZjIxNGVlMTM5MjhkMzM5MzkxZDVmNWY3MDU2NjA4YWEwZDMyYjllZGYwMSdcbiAgICAgICk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMF0uc2NhbkluZGV4LnNob3VsZC5lcXVhbCgwKTtcbiAgICAgIHJlY292ZXJ5VHhuLmxhc3RTY2FuSW5kZXguc2hvdWxkLmVxdWFsKDApO1xuICAgIH0pO1xuXG4gICAgLy8gVE9ETyhDT0lOLTkxOSk6IEZpeCBmYWlsaW5nIHRlc3RcbiAgICB4aXQoJ3Nob3VsZCB0YWtlIGNvbnNvbGlkYXRpb24gT1ZDIG91dHB1dCBhbmQgZ2VuZXJhdGUgbXVsdGlwbGUgc2lnbmVkIHN3ZWVwIHRyYW5zYWN0aW9ucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHRlc3REYXRhLm92Y1Jlc3BvbnNlMjtcblxuICAgICAgY29uc3QgcmVjb3ZlcnlUeG4gPSBhd2FpdCBiYXNlY29pbi5jcmVhdGVCcm9hZGNhc3RhYmxlU3dlZXBUcmFuc2FjdGlvbihwYXJhbXMpO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzBdLnNlcmlhbGl6ZWRUeC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcweDJkMDI4NDAwZjA1M2QxNzczNzFmNDkxOWI3MTAxNzQyMWFhMzQ4NDFhYzg3YzkyNmExNGU4YTdlNzVmMDkyNjkzNjY1Y2I0YTAwOTg3MWZlYjgzODllMTIxOTFiNDYwZWJlYTFmOWUxNzE2YWRhOGEzMWQ5NGFjMDhmNWMxNWNiNWY3YmUyNDY4M2NkZmMzMDBhZTNlNjgwMmM2ZjRiMDQ0ZGQ5MmVhMDNkMTViOTIzOTlhYjQ1ODAzZTQzYmViNWNiZmY1ODJhMDMxYjM3MDAwMDA0MDQwMDUwZDFlMTE2Y2RiMzJlNjFiYTNlY2UyNzViNjIwZjUwM2YwYzVhZTRlNzY5MGQ5ZjlhYTdlMGI1MDMwMzk3NmMwMSdcbiAgICAgICk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMF0uc2NhbkluZGV4LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1sxXS5zZXJpYWxpemVkVHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMHgyZDAyODQwMGNmN2VkOWY1MzYzNzNjOGY4NzRlNzgwYTQyNjllYzFiZDY3OTllZDdkNGE4NTRjNjcwYjBjNzI4MDVmYWM4NzYwMGQxNTNjYmI2ODM3MDZkZGYzMjBmN2IyMjVhZjE0Y2U0YjU5Yjg2OGMwNzQ0MGFlZmE0YzRlMTI5N2U0OWJjZDVmNmVlODRmNjk2YjBjMmU0NTZlMmE3Zjg3NzlhNzhhMmM4MzJkZmI0N2Q1YjI4M2ViYTg0MDhiMDAzYzdkZDAzMWIzNzAwMDAwNDA0MDA1MGQxZTExNmNkYjMyZTYxYmEzZWNlMjc1YjYyMGY1MDNmMGM1YWU0ZTc2OTBkOWY5YWE3ZTBiNTAzMDM5NzZjMDEnXG4gICAgICApO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzFdLnNjYW5JbmRleC5zaG91bGQuZXF1YWwoMik7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMl0uc2VyaWFsaXplZFR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzB4MmQwMjg0MDA5NDgyYWQ3ZTQzYjQwYjdkZjMzODMyNDRkYWFmZWQzMmIzYjlmZDc1NDEwMTZiNWM5MDdmMmQ5MDUyZjg1Zjg2MDBlMjU1Njk4ZDExMDk3N2ZhZjMzZWZiMzMzNmJhOThhZDdlYWEyYTFhOTI2NDg3ZmM2OTZhMjc3NDQyZDQ0MTRiMmE0NDFiYTkyZDU5OGYyYjFmOTZmMTNiMjg3ODVmNWU1NzI5ODQwMzVhNjA4ZDYzYzQ4YmQzNWJhOTU1MDkwZTFiMzcwMDAwMDQwNDAwNTBkMWUxMTZjZGIzMmU2MWJhM2VjZTI3NWI2MjBmNTAzZjBjNWFlNGU3NjkwZDlmOWFhN2UwYjUwMzAzOTc2YzAxJ1xuICAgICAgKTtcbiAgICAgIHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1syXS5zY2FuSW5kZXguc2hvdWxkLmVxdWFsKDMpO1xuICAgICAgcmVjb3ZlcnlUeG4ubGFzdFNjYW5JbmRleC5zaG91bGQuZXF1YWwoMjApO1xuICAgIH0pO1xuXG4gICAgLy8gVE9ETyhDT0lOLTkxOSk6IEZpeCBmYWlsaW5nIHRlc3RcbiAgICB4aXQoJ3Nob3VsZCByZWNvdmVyIGEgdHhuIGZvciBub24tYml0Z28gcmVjb3ZlcmllcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS53cndVc2VyLnVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEud3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS53cndVc2VyLmJpdGdvS2V5LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS53cndVc2VyLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RBZGRyLFxuICAgICAgfSk7XG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICByZXMuc2hvdWxkLmhhc093blByb3BlcnR5KCdzY2FuSW5kZXgnKTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxlZE9uY2UoYmFzZWNvaW4uZ2V0QWNjb3VudEluZm8pO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkT25jZShiYXNlY29pbi5nZXRIZWFkZXJJbmZvKTtcblxuICAgICAgLy8gZGVzZXJpYWxpemUgdGhlIHR4biBhbmQgdmVyaWZ5IHRoZSBmaWVsZHMgYXJlIHdoYXQgd2UgZXhwZWN0XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBiYXNlY29pbi5nZXRCdWlsZGVyKCkuZnJvbShyZXMuc2VyaWFsaXplZFR4KTtcbiAgICAgIC8vIHNvbWUgaW5mb3JtYXRpb24gaXNuJ3QgZGVzZXJpYWxpemVkIGJ5IHRoZSBmcm9tIG1ldGhvZCwgc28gd2Ugd2lsbFxuICAgICAgLy8gc3VwcGx5IGl0IGFnYWluIGluIG9yZGVyIHRvIHJlLWJ1aWxkIHRoZSB0eG5cbiAgICAgIHR4QnVpbGRlclxuICAgICAgICAudmFsaWRpdHkoe1xuICAgICAgICAgIGZpcnN0VmFsaWQ6IHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlcixcbiAgICAgICAgICBtYXhEdXJhdGlvbjogYmFzZWNvaW4uU1dFRVBfVFhOX0RVUkFUSU9OLFxuICAgICAgICB9KVxuICAgICAgICAucmVmZXJlbmNlQmxvY2sodGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uc2VuZGVyLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmJsb2NrTnVtYmVyLCB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucmVmZXJlbmNlQmxvY2ssIHRlc3REYXRhLndlc3RlbmRCbG9jay5oYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmdlbmVzaXNIYXNoLCBnZW5lc2lzSGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5zcGVjVmVyc2lvbiwgc3BlY1ZlcnNpb24pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ubm9uY2UsIG5vbmNlKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnRpcCwgMCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi50cmFuc2FjdGlvblZlcnNpb24sIHR4VmVyc2lvbik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5jaGFpbk5hbWUsIGNoYWluTmFtZSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5lcmFQZXJpb2QsIGJhc2Vjb2luLlNXRUVQX1RYTl9EVVJBVElPTik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgYSB0eG4gZm9yIHVuc2lnbmVkLXN3ZWVwIHJlY292ZXJpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLndyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RBZGRyLFxuICAgICAgfSk7XG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhc093blByb3BlcnR5KCdzZXJpYWxpemVkVHgnKTtcbiAgICAgIHJlcy50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2NhbkluZGV4Jyk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRPbmNlKGJhc2Vjb2luLmdldEFjY291bnRJbmZvKTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxlZE9uY2UoYmFzZWNvaW4uZ2V0SGVhZGVySW5mbyk7XG5cbiAgICAgIC8vIGRlc2VyaWFsaXplIHRoZSB0eG4gYW5kIHZlcmlmeSB0aGUgZmllbGRzIGFyZSB3aGF0IHdlIGV4cGVjdFxuICAgICAgY29uc3QgdHhCdWlsZGVyID0gYmFzZWNvaW4uZ2V0QnVpbGRlcigpLmZyb20ocmVzLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2VyaWFsaXplZFR4KTtcbiAgICAgIC8vIHNvbWUgaW5mb3JtYXRpb24gaXNuJ3QgZGVzZXJpYWxpemVkIGJ5IHRoZSBmcm9tIG1ldGhvZCwgc28gd2Ugd2lsbFxuICAgICAgLy8gc3VwcGx5IGl0IGFnYWluIGluIG9yZGVyIHRvIHJlLWJ1aWxkIHRoZSB0eG5cbiAgICAgIHR4QnVpbGRlclxuICAgICAgICAudmFsaWRpdHkoe1xuICAgICAgICAgIGZpcnN0VmFsaWQ6IHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlcixcbiAgICAgICAgICBtYXhEdXJhdGlvbjogYmFzZWNvaW4uU1dFRVBfVFhOX0RVUkFUSU9OLFxuICAgICAgICB9KVxuICAgICAgICAucmVmZXJlbmNlQmxvY2sodGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpXG4gICAgICAgIC5zZW5kZXIoeyBhZGRyZXNzOiB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwIH0pO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uc2VuZGVyLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmJsb2NrTnVtYmVyLCB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucmVmZXJlbmNlQmxvY2ssIHRlc3REYXRhLndlc3RlbmRCbG9jay5oYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmdlbmVzaXNIYXNoLCBnZW5lc2lzSGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5zcGVjVmVyc2lvbiwgc3BlY1ZlcnNpb24pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ubm9uY2UsIG5vbmNlKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnRpcCwgMCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi50cmFuc2FjdGlvblZlcnNpb24sIHR4VmVyc2lvbik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5jaGFpbk5hbWUsIGNoYWluTmFtZSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5lcmFQZXJpb2QsIGJhc2Vjb2luLlNXRUVQX1RYTl9EVVJBVElPTik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZWNvdmVyIFRyYW5zYWN0aW9ucyAoTVBDdjIpOicsICgpID0+IHtcbiAgICBjb25zdCBzYW5kQm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgIGNvbnN0IGRlc3RBZGRyID0gdGVzdERhdGEuYWNjb3VudHMuYWNjb3VudDEuYWRkcmVzcztcbiAgICBjb25zdCBub25jZSA9IDEyMztcbiAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gdGVzdERhdGEud3J3VXNlci53YWxsZXRQYXNzcGhyYXNlO1xuICAgIGxldCBtcGNWMlVzZXJLZXk6IHN0cmluZztcbiAgICBsZXQgbXBjVjJCYWNrdXBLZXk6IHN0cmluZztcbiAgICBsZXQgbXBjVjJDb21tb25LZXlDaGFpbjogc3RyaW5nO1xuICAgIGxldCBtcGNWMldhbGxldEFkZHJlc3M6IHN0cmluZztcbiAgICBsZXQgbWlzbWF0Y2hlZEJpdGdvS2V5OiBzdHJpbmc7XG4gICAgbGV0IG1pc21hdGNoZWRXYWxsZXRBZGRyZXNzOiBzdHJpbmc7XG5cbiAgICBiZWZvcmUoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgW3VzZXJEa2csIGJhY2t1cERrZ10gPSBhd2FpdCBNUFNVdGlsLmdlbmVyYXRlRWREc2FES0dLZXlTaGFyZXMoKTtcbiAgICAgIGNvbnN0IFtvdGhlclVzZXJEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG5cbiAgICAgIG1wY1YyVXNlcktleSA9IGF3YWl0IGVuY3J5cHQod2FsbGV0UGFzc3BocmFzZSwgdXNlckRrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKS50b1N0cmluZygnYmFzZTY0JykpO1xuICAgICAgbXBjVjJCYWNrdXBLZXkgPSBhd2FpdCBlbmNyeXB0KHdhbGxldFBhc3NwaHJhc2UsIGJhY2t1cERrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKS50b1N0cmluZygnYmFzZTY0JykpO1xuICAgICAgbXBjVjJDb21tb25LZXlDaGFpbiA9IHVzZXJEa2cuZ2V0Q29tbW9uS2V5Y2hhaW4oKTtcbiAgICAgIGNvbnN0IG1wYyA9IGF3YWl0IEVERFNBTWV0aG9kcy5nZXRJbml0aWFsaXplZE1wY0luc3RhbmNlKCk7XG4gICAgICBtcGNWMldhbGxldEFkZHJlc3MgPSBiYXNlY29pbi5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShcbiAgICAgICAgbXBjLmRlcml2ZVVuaGFyZGVuZWQobXBjVjJDb21tb25LZXlDaGFpbiwgJ20vMCcpLnNsaWNlKDAsIDY0KVxuICAgICAgKTtcblxuICAgICAgbWlzbWF0Y2hlZEJpdGdvS2V5ID0gb3RoZXJVc2VyRGtnLmdldENvbW1vbktleWNoYWluKCk7XG4gICAgICBtaXNtYXRjaGVkV2FsbGV0QWRkcmVzcyA9IGJhc2Vjb2luLmdldEFkZHJlc3NGcm9tUHVibGljS2V5KFxuICAgICAgICBtcGMuZGVyaXZlVW5oYXJkZW5lZChtaXNtYXRjaGVkQml0Z29LZXksICdtLzAnKS5zbGljZSgwLCA2NClcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFjY291bnRJbmZvQ0IgPSBzYW5kQm94LnN0dWIoRG90LnByb3RvdHlwZSwgJ2dldEFjY291bnRJbmZvJyBhcyBrZXlvZiBEb3QpO1xuICAgICAgYWNjb3VudEluZm9DQi53aXRoQXJncyhtcGNWMldhbGxldEFkZHJlc3MpLnJlc29sdmVzKHtcbiAgICAgICAgbm9uY2U6IG5vbmNlLFxuICAgICAgICBmcmVlQmFsYW5jZTogMTUxMDAwMDAwMDAwMCxcbiAgICAgIH0pO1xuICAgICAgYWNjb3VudEluZm9DQi53aXRoQXJncyhtaXNtYXRjaGVkV2FsbGV0QWRkcmVzcykucmVzb2x2ZXMoe1xuICAgICAgICBub25jZTogbm9uY2UsXG4gICAgICAgIGZyZWVCYWxhbmNlOiAxNTEwMDAwMDAwMDAwLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBoZWFkZXJJbmZvQ0IgPSBzYW5kQm94LnN0dWIoRG90LnByb3RvdHlwZSwgJ2dldEhlYWRlckluZm8nIGFzIGtleW9mIERvdCk7XG4gICAgICBoZWFkZXJJbmZvQ0IucmVzb2x2ZXMoe1xuICAgICAgICBoZWFkZXJOdW1iZXI6IHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlcixcbiAgICAgICAgaGVhZGVySGFzaDogdGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGdldEZlZUNCID0gc2FuZEJveC5zdHViKERvdC5wcm90b3R5cGUsICdnZXRGZWUnIGFzIGtleW9mIERvdCk7XG4gICAgICBnZXRGZWVDQi5yZXNvbHZlcygxNTc4MzgxMjg1Nik7XG4gICAgICBjb25zdCBnZXRNYXRlcmlhbENCID0gc2FuZEJveC5zdHViKERvdC5wcm90b3R5cGUsICdnZXRNYXRlcmlhbCcgYXMga2V5b2YgRG90KTtcbiAgICAgIGdldE1hdGVyaWFsQ0IucmVzb2x2ZXModXRpbHMuZ2V0TWF0ZXJpYWwoY29pbnMuZ2V0KCd0ZG90JykpKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kQm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcm91dGUgdG8gTVBDdjIgcGF0aCBmb3IgbmF0aXZlIERPVCByZWNvdmVyeSB3aGVuIGtleWNhcmQgaXMgTVBDdjInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBnZXRUU1NTaWduYXR1cmVTcHkgPSBzYW5kQm94LnNweShFRERTQU1ldGhvZHMsICdnZXRUU1NTaWduYXR1cmUnKTtcblxuICAgICAgY29uc3QgcmVzID0gKGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiBtcGNWMlVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogbXBjVjJCYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiBtcGNWMkNvbW1vbktleUNoYWluLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0QWRkcixcbiAgICAgIH0pKSBhcyBNUENUeDtcblxuICAgICAgcmVzLnNob3VsZC5ub3QuYmUuZW1wdHkoKTtcbiAgICAgIHJlcy5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgcmVzLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2NhbkluZGV4Jyk7XG4gICAgICBzaG91bGQuZXF1YWwocmVzLnNjYW5JbmRleCwgMCk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRPbmNlKGJhc2Vjb2luLmdldEFjY291bnRJbmZvKTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0Lm5vdENhbGxlZChnZXRUU1NTaWduYXR1cmVTcHkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIE1QQ3YyIGNvbW1vbktleUNoYWluIGRvZXMgbm90IG1hdGNoIGJpdGdvS2V5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6IG1wY1YyVXNlcktleSxcbiAgICAgICAgICBiYWNrdXBLZXk6IG1wY1YyQmFja3VwS2V5LFxuICAgICAgICAgIGJpdGdvS2V5OiBtaXNtYXRjaGVkQml0Z29LZXksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0QWRkcixcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0VkRFNBIE1QQ3YyIHJlY292ZXJ5OiBjb21tb25LZXlDaGFpbiBmcm9tIGtleWNhcmQgZG9lcyBub3QgbWF0Y2ggYml0Z29LZXknKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgbWlzc2luZyB1c2VyS2V5IHdoZW4gYmFja3VwS2V5IGFuZCB3YWxsZXRQYXNzcGhyYXNlIGFyZSBwcmVzZW50IGJ1dCB1c2VyS2V5IGlzIG5vdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OiB1bmRlZmluZWQsXG4gICAgICAgICAgYmFja3VwS2V5OiBtcGNWMkJhY2t1cEtleSxcbiAgICAgICAgICBiaXRnb0tleTogbXBjVjJDb21tb25LZXlDaGFpbixcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RBZGRyLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyB1c2VyS2V5Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IG1pc3NpbmcgYmFja3VwS2V5IHdoZW4gdXNlcktleSBhbmQgd2FsbGV0UGFzc3BocmFzZSBhcmUgcHJlc2VudCBidXQgYmFja3VwS2V5IGlzIG5vdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OiBtcGNWMlVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiB1bmRlZmluZWQsXG4gICAgICAgICAgYml0Z29LZXk6IG1wY1YyQ29tbW9uS2V5Q2hhaW4sXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0QWRkcixcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ21pc3NpbmcgYmFja3VwS2V5Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IG1pc3Npbmcgd2FsbGV0IHBhc3NwaHJhc2Ugd2hlbiB1c2VyS2V5IGFuZCBiYWNrdXBLZXkgYXJlIHByZXNlbnQgYnV0IHdhbGxldFBhc3NwaHJhc2UgaXMgbm90JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6IG1wY1YyVXNlcktleSxcbiAgICAgICAgICBiYWNrdXBLZXk6IG1wY1YyQmFja3VwS2V5LFxuICAgICAgICAgIGJpdGdvS2V5OiBtcGNWMkNvbW1vbktleUNoYWluLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0QWRkcixcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ21pc3Npbmcgd2FsbGV0IHBhc3NwaHJhc2UnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc3RpbGwgdXNlIHRoZSBNUEN2MSBwYXRoIChnZXRUU1NTaWduYXR1cmUpIGZvciBNUEN2MSBKU09OIGtleWNhcmRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZ2V0VFNTU2lnbmF0dXJlU3B5ID0gc2FuZEJveC5zcHkoRUREU0FNZXRob2RzLCAnZ2V0VFNTU2lnbmF0dXJlJyk7XG4gICAgICAoRG90LnByb3RvdHlwZSBhcyB1bmtub3duIGFzIHsgZ2V0QWNjb3VudEluZm86IHNpbm9uLlNpbm9uU3R1YiB9KS5nZXRBY2NvdW50SW5mb1xuICAgICAgICAud2l0aEFyZ3ModGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMClcbiAgICAgICAgLnJlc29sdmVzKHtcbiAgICAgICAgICBub25jZSxcbiAgICAgICAgICBmcmVlQmFsYW5jZTogMTUxMDAwMDAwMDAwMCxcbiAgICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IChhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTogdGVzdERhdGEud3J3VXNlci51c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLndyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICBiaXRnb0tleTogdGVzdERhdGEud3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEud3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0QWRkcixcbiAgICAgIH0pKSBhcyBNUENUeDtcblxuICAgICAgcmVzdWx0LnNob3VsZC5ub3QuYmUuZW1wdHkoKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkT25jZShnZXRUU1NTaWduYXR1cmVTcHkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjYWxsIGdldEVkZHNhU2lnbmluZ01hdGVyaWFsIGV4YWN0bHkgb25jZSBwZXIgcmVjb3ZlcigpIGNhbGwnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBnZXRFZGRzYU1hdGVyaWFsU3B5ID0gc2FuZEJveC5zcHkoXG4gICAgICAgIGJhc2Vjb2luIGFzIHVua25vd24gYXMgeyBnZXRFZGRzYVNpZ25pbmdNYXRlcmlhbDogdW5rbm93biB9LFxuICAgICAgICAnZ2V0RWRkc2FTaWduaW5nTWF0ZXJpYWwnXG4gICAgICApO1xuXG4gICAgICBjb25zdCByZXMgPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IG1wY1YyVXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiBtcGNWMkJhY2t1cEtleSxcbiAgICAgICAgYml0Z29LZXk6IG1wY1YyQ29tbW9uS2V5Q2hhaW4sXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RBZGRyLFxuICAgICAgfSkpIGFzIE1QQ1R4O1xuXG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkT25jZShnZXRFZGRzYU1hdGVyaWFsU3B5KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0J1aWxkIENvbnNvbGlkYXRpb24gUmVjb3ZlcmllczonLCAoKSA9PiB7XG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICBjb25zdCBiYXNlQWRkciA9IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MwO1xuICAgIGNvbnN0IG5vbmNlID0gMTIzO1xuXG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhY2NvdW50SW5mb0NCID0gc2FuZEJveC5zdHViKERvdC5wcm90b3R5cGUsICdnZXRBY2NvdW50SW5mbycgYXMga2V5b2YgRG90KTtcbiAgICAgIGFjY291bnRJbmZvQ0Iud2l0aEFyZ3ModGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczEpLnJlc29sdmVzKHtcbiAgICAgICAgbm9uY2U6IG5vbmNlLFxuICAgICAgICBmcmVlQmFsYW5jZTogMTAwMDAwMDAwMDAsXG4gICAgICB9KTtcbiAgICAgIGFjY291bnRJbmZvQ0Iud2l0aEFyZ3ModGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczIpLnJlc29sdmVzKHtcbiAgICAgICAgbm9uY2U6IG5vbmNlLFxuICAgICAgICBmcmVlQmFsYW5jZTogMTUxMDAwMDAwMDAwMCxcbiAgICAgIH0pO1xuICAgICAgYWNjb3VudEluZm9DQi53aXRoQXJncyh0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci53YWxsZXRBZGRyZXNzMykucmVzb2x2ZXMoe1xuICAgICAgICBub25jZTogbm9uY2UsXG4gICAgICAgIGZyZWVCYWxhbmNlOiAxNTEwMDAwMDAwMDAwLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBoZWFkZXJJbmZvQ0IgPSBzYW5kQm94LnN0dWIoRG90LnByb3RvdHlwZSwgJ2dldEhlYWRlckluZm8nIGFzIGtleW9mIERvdCk7XG4gICAgICBoZWFkZXJJbmZvQ0IucmVzb2x2ZXMoe1xuICAgICAgICBoZWFkZXJOdW1iZXI6IHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlcixcbiAgICAgICAgaGVhZGVySGFzaDogdGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGdldEZlZUNCID0gc2FuZEJveC5zdHViKERvdC5wcm90b3R5cGUsICdnZXRGZWUnIGFzIGtleW9mIERvdCk7XG4gICAgICBnZXRGZWVDQi53aXRoQXJncyhiYXNlQWRkciwgdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczEsIDEwMDAwMDAwMDAwKS5yZXNvbHZlcygxNTc4MzgxMjg1Nik7XG4gICAgICBnZXRGZWVDQi53aXRoQXJncyhiYXNlQWRkciwgdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczIsIDE1MTAwMDAwMDAwMDApLnJlc29sdmVzKDE1NzgzODEyODU2KTtcbiAgICAgIGdldEZlZUNCLndpdGhBcmdzKGJhc2VBZGRyLCB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci53YWxsZXRBZGRyZXNzMywgMTUxMDAwMDAwMDAwMCkucmVzb2x2ZXMoMTU3ODM4MTI4NTYpO1xuICAgICAgY29uc3QgZ2V0TWF0ZXJpYWxDQiA9IHNhbmRCb3guc3R1YihEb3QucHJvdG90eXBlLCAnZ2V0TWF0ZXJpYWwnIGFzIGtleW9mIERvdCk7XG4gICAgICBnZXRNYXRlcmlhbENCLnJlc29sdmVzKHV0aWxzLmdldE1hdGVyaWFsKGNvaW5zLmdldCgndGRvdCcpKSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgc2FuZEJveC5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICAvLyBUT0RPKENPSU4tOTE5KTogRml4IGZhaWxpbmcgdGVzdFxuICAgIHhpdCgnc2hvdWxkIGJ1aWxkIHNpZ25lZCBjb25zb2xpZGF0aW9uIHJlY292ZXJpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyQ29uc29saWRhdGlvbnMoe1xuICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci51c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLmJpdGdvS2V5LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICBzdGFydGluZ1NjYW5JbmRleDogMSxcbiAgICAgICAgZW5kaW5nU2NhbkluZGV4OiA0LFxuICAgICAgfSk7XG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnRyYW5zYWN0aW9ucy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkVGhyaWNlKGJhc2Vjb2luLmdldEFjY291bnRJbmZvKTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxlZFR3aWNlKGJhc2Vjb2luLmdldEhlYWRlckluZm8pO1xuXG4gICAgICBjb25zdCB0eG4xID0gcmVzLnRyYW5zYWN0aW9uc1swXTtcbiAgICAgIHR4bjEuc2hvdWxkLmhhc093blByb3BlcnR5KCdzZXJpYWxpemVkVHgnKTtcbiAgICAgIHR4bjEuc2hvdWxkLmhhc093blByb3BlcnR5KCdzY2FuSW5kZXgnKTtcbiAgICAgIHR4bjEuc2NhbkluZGV4LnNob3VsZC5lcXVhbCgyKTtcbiAgICAgIC8vIGRlc2VyaWFsaXplIHRoZSB0eG4gYW5kIHZlcmlmeSB0aGUgZmllbGRzIGFyZSB3aGF0IHdlIGV4cGVjdFxuICAgICAgY29uc3QgdHhCdWlsZGVyMSA9IGJhc2Vjb2luLmdldEJ1aWxkZXIoKS5mcm9tKHR4bjEuc2VyaWFsaXplZFR4KTtcbiAgICAgIC8vIHNvbWUgaW5mb3JtYXRpb24gaXNuJ3QgZGVzZXJpYWxpemVkIGJ5IHRoZSBmcm9tIG1ldGhvZCwgc28gd2Ugd2lsbFxuICAgICAgLy8gc3VwcGx5IGl0IGFnYWluIGluIG9yZGVyIHRvIHJlLWJ1aWxkIHRoZSB0eG5cbiAgICAgIHR4QnVpbGRlcjFcbiAgICAgICAgLnZhbGlkaXR5KHtcbiAgICAgICAgICBmaXJzdFZhbGlkOiB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIsXG4gICAgICAgICAgbWF4RHVyYXRpb246IGJhc2Vjb2luLk1BWF9WQUxJRElUWV9EVVJBVElPTixcbiAgICAgICAgfSlcbiAgICAgICAgLnJlZmVyZW5jZUJsb2NrKHRlc3REYXRhLndlc3RlbmRCbG9jay5oYXNoKTtcbiAgICAgIGNvbnN0IHR4MSA9IGF3YWl0IHR4QnVpbGRlcjEuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbjEgPSB0eDEudG9Kc29uKCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEuc2VuZGVyLCB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci53YWxsZXRBZGRyZXNzMik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEuYmxvY2tOdW1iZXIsIHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlcik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEucmVmZXJlbmNlQmxvY2ssIHRlc3REYXRhLndlc3RlbmRCbG9jay5oYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5nZW5lc2lzSGFzaCwgZ2VuZXNpc0hhc2gpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLnNwZWNWZXJzaW9uLCBzcGVjVmVyc2lvbik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEubm9uY2UsIG5vbmNlKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS50aXAsIDApO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLnRyYW5zYWN0aW9uVmVyc2lvbiwgdHhWZXJzaW9uKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5jaGFpbk5hbWUsIGNoYWluTmFtZSk7XG4gICAgICAvLyBlcmFQZXJpb2Qgd2lsbCBhbHdheXMgcm91bmQgdG8gdGhlIG5leHQgdXBwZXIgcG93ZXIgb2YgMiBmb3IgYW55IGlucHV0IHZhbHVlLCBpbiB0aGlzIGNhc2UgMjQwMC5cbiAgICAgIC8vIDQwOTYgaXMgdGhlIFwiaGlnaGVzdFwiIHZhbHVlIHlvdSBjYW4gc2V0LCBidXQgdGhlIHR4biBzdGlsbCBtYXkgZmFpbCBhZnRlciAyNDAwIGJsb2Nrcy5cbiAgICAgIGNvbnN0IGVyYVBlcmlvZCA9IDQwOTY7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEuZXJhUGVyaW9kLCBlcmFQZXJpb2QpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLnRvLCBiYXNlQWRkcik7XG5cbiAgICAgIHJlcy5sYXN0U2NhbkluZGV4LnNob3VsZC5lcXVhbCgzKTtcbiAgICAgIGNvbnN0IHR4bjIgPSByZXMudHJhbnNhY3Rpb25zWzFdO1xuICAgICAgdHhuMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgdHhuMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NjYW5JbmRleCcpO1xuICAgICAgdHhuMi5zY2FuSW5kZXguc2hvdWxkLmVxdWFsKDMpO1xuICAgICAgLy8gZGVzZXJpYWxpemUgdGhlIHR4biBhbmQgdmVyaWZ5IHRoZSBmaWVsZHMgYXJlIHdoYXQgd2UgZXhwZWN0XG4gICAgICBjb25zdCB0eEJ1aWxkZXIyID0gYmFzZWNvaW4uZ2V0QnVpbGRlcigpLmZyb20odHhuMi5zZXJpYWxpemVkVHgpO1xuICAgICAgLy8gc29tZSBpbmZvcm1hdGlvbiBpc24ndCBkZXNlcmlhbGl6ZWQgYnkgdGhlIGZyb20gbWV0aG9kLCBzbyB3ZSB3aWxsXG4gICAgICAvLyBzdXBwbHkgaXQgYWdhaW4gaW4gb3JkZXIgdG8gcmUtYnVpbGQgdGhlIHR4blxuICAgICAgdHhCdWlsZGVyMlxuICAgICAgICAudmFsaWRpdHkoe1xuICAgICAgICAgIGZpcnN0VmFsaWQ6IHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlcixcbiAgICAgICAgICBtYXhEdXJhdGlvbjogYmFzZWNvaW4uTUFYX1ZBTElESVRZX0RVUkFUSU9OLFxuICAgICAgICB9KVxuICAgICAgICAucmVmZXJlbmNlQmxvY2sodGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpO1xuICAgICAgY29uc3QgdHgyID0gYXdhaXQgdHhCdWlsZGVyMi5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uMiA9IHR4Mi50b0pzb24oKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5zZW5kZXIsIHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MzKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5ibG9ja051bWJlciwgdGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5yZWZlcmVuY2VCbG9jaywgdGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLmdlbmVzaXNIYXNoLCBnZW5lc2lzSGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIuc3BlY1ZlcnNpb24sIHNwZWNWZXJzaW9uKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5ub25jZSwgbm9uY2UpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLnRpcCwgMCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIudHJhbnNhY3Rpb25WZXJzaW9uLCB0eFZlcnNpb24pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLmNoYWluTmFtZSwgY2hhaW5OYW1lKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5lcmFQZXJpb2QsIGVyYVBlcmlvZCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIudG8sIGJhc2VBZGRyKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnVpbGQgdW5zaWduZWQgY29uc29saWRhdGlvbiByZWNvdmVyaWVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgYmFzZWNvaW4ucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLmJpdGdvS2V5LFxuICAgICAgICBzdGFydGluZ1NjYW5JbmRleDogMSxcbiAgICAgICAgZW5kaW5nU2NhbkluZGV4OiA0LFxuICAgICAgfSk7XG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnR4UmVxdWVzdHMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxlZFRocmljZShiYXNlY29pbi5nZXRBY2NvdW50SW5mbyk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRUd2ljZShiYXNlY29pbi5nZXRIZWFkZXJJbmZvKTtcblxuICAgICAgY29uc3QgdHhuMSA9IHJlcy50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4O1xuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NpZ25hYmxlSGV4Jyk7XG4gICAgICB0eG4xLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2NhbkluZGV4Jyk7XG4gICAgICB0eG4xLnNjYW5JbmRleC5zaG91bGQuZXF1YWwoMik7XG4gICAgICB0eG4xLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnY29pbicpO1xuICAgICAgdHhuMS5jb2luLnNob3VsZC5lcXVhbCgndGRvdCcpO1xuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2Rlcml2YXRpb25QYXRoJyk7XG4gICAgICB0eG4xLmRlcml2YXRpb25QYXRoLnNob3VsZC5lcXVhbCgnbS8yJyk7XG5cbiAgICAgIHR4bjEuc2hvdWxkLmhhc093blByb3BlcnR5KCdjb2luU3BlY2lmaWMnKTtcbiAgICAgIGNvbnN0IGNvaW5TcGVjaWZpYzEgPSB0eG4xLmNvaW5TcGVjaWZpYztcbiAgICAgIGNvaW5TcGVjaWZpYzEuc2hvdWxkLmhhc093blByb3BlcnR5KCdjb21tb25LZXljaGFpbicpO1xuICAgICAgY29pblNwZWNpZmljMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2ZpcnN0VmFsaWQnKTtcbiAgICAgIGNvaW5TcGVjaWZpYzEuZmlyc3RWYWxpZC5zaG91bGQuZXF1YWwodGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyKTtcbiAgICAgIGNvaW5TcGVjaWZpYzEuc2hvdWxkLmhhc093blByb3BlcnR5KCdtYXhEdXJhdGlvbicpO1xuICAgICAgY29pblNwZWNpZmljMS5tYXhEdXJhdGlvbi5zaG91bGQuZXF1YWwoYmFzZWNvaW4uTUFYX1ZBTElESVRZX0RVUkFUSU9OKTtcblxuICAgICAgLy8gZGVzZXJpYWxpemUgdGhlIHR4biBhbmQgdmVyaWZ5IHRoZSBmaWVsZHMgYXJlIHdoYXQgd2UgZXhwZWN0XG4gICAgICBjb25zdCB0eEJ1aWxkZXIxID0gYmFzZWNvaW4uZ2V0QnVpbGRlcigpLmZyb20odHhuMS5zZXJpYWxpemVkVHgpO1xuICAgICAgLy8gc29tZSBpbmZvcm1hdGlvbiBpc24ndCBkZXNlcmlhbGl6ZWQgYnkgdGhlIGZyb20gbWV0aG9kLCBzbyB3ZSB3aWxsXG4gICAgICAvLyBzdXBwbHkgaXQgYWdhaW4gaW4gb3JkZXIgdG8gcmUtYnVpbGQgdGhlIHR4blxuICAgICAgdHhCdWlsZGVyMVxuICAgICAgICAudmFsaWRpdHkoe1xuICAgICAgICAgIGZpcnN0VmFsaWQ6IHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlcixcbiAgICAgICAgICBtYXhEdXJhdGlvbjogYmFzZWNvaW4uTUFYX1ZBTElESVRZX0RVUkFUSU9OLFxuICAgICAgICB9KVxuICAgICAgICAucmVmZXJlbmNlQmxvY2sodGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpXG4gICAgICAgIC5zZW5kZXIoeyBhZGRyZXNzOiB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci53YWxsZXRBZGRyZXNzMiB9KTtcbiAgICAgIGNvbnN0IHR4MSA9IGF3YWl0IHR4QnVpbGRlcjEuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbjEgPSB0eDEudG9Kc29uKCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEuc2VuZGVyLCB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci53YWxsZXRBZGRyZXNzMik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEuYmxvY2tOdW1iZXIsIHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlcik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEucmVmZXJlbmNlQmxvY2ssIHRlc3REYXRhLndlc3RlbmRCbG9jay5oYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5nZW5lc2lzSGFzaCwgZ2VuZXNpc0hhc2gpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLnNwZWNWZXJzaW9uLCBzcGVjVmVyc2lvbik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEubm9uY2UsIG5vbmNlKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS50aXAsIDApO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLnRyYW5zYWN0aW9uVmVyc2lvbiwgdHhWZXJzaW9uKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5jaGFpbk5hbWUsIGNoYWluTmFtZSk7XG4gICAgICAvLyBlcmFQZXJpb2Qgd2lsbCBhbHdheXMgcm91bmQgdG8gdGhlIG5leHQgdXBwZXIgcG93ZXIgb2YgMiBmb3IgYW55IGlucHV0IHZhbHVlLCBpbiB0aGlzIGNhc2UgMjQwMC5cbiAgICAgIC8vIDQwOTYgaXMgdGhlIFwiaGlnaGVzdFwiIHZhbHVlIHlvdSBjYW4gc2V0LCBidXQgdGhlIHR4biBzdGlsbCBtYXkgZmFpbCBhZnRlciAyNDAwIGJsb2Nrcy5cbiAgICAgIGNvbnN0IGVyYVBlcmlvZCA9IDQwOTY7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEuZXJhUGVyaW9kLCBlcmFQZXJpb2QpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLnRvLCBiYXNlQWRkcik7XG5cbiAgICAgIGNvbnN0IHR4bjIgPSByZXMudHhSZXF1ZXN0c1sxXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeDtcbiAgICAgIHR4bjIuc2hvdWxkLmhhc093blByb3BlcnR5KCdzZXJpYWxpemVkVHgnKTtcbiAgICAgIHR4bjIuc2hvdWxkLmhhc093blByb3BlcnR5KCdzaWduYWJsZUhleCcpO1xuICAgICAgdHhuMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NjYW5JbmRleCcpO1xuICAgICAgdHhuMi5zY2FuSW5kZXguc2hvdWxkLmVxdWFsKDMpO1xuICAgICAgdHhuMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2NvaW4nKTtcbiAgICAgIHR4bjIuY29pbi5zaG91bGQuZXF1YWwoJ3Rkb3QnKTtcbiAgICAgIHR4bjIuc2hvdWxkLmhhc093blByb3BlcnR5KCdkZXJpdmF0aW9uUGF0aCcpO1xuICAgICAgdHhuMi5kZXJpdmF0aW9uUGF0aC5zaG91bGQuZXF1YWwoJ20vMycpO1xuXG4gICAgICB0eG4yLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnY29pblNwZWNpZmljJyk7XG4gICAgICBjb25zdCBjb2luU3BlY2lmaWMyID0gdHhuMi5jb2luU3BlY2lmaWM7XG4gICAgICBjb2luU3BlY2lmaWMyLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnY29tbW9uS2V5Y2hhaW4nKTtcbiAgICAgIGNvaW5TcGVjaWZpYzIuc2hvdWxkLmhhc093blByb3BlcnR5KCdmaXJzdFZhbGlkJyk7XG4gICAgICBjb2luU3BlY2lmaWMyLmZpcnN0VmFsaWQuc2hvdWxkLmVxdWFsKHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlcik7XG4gICAgICBjb2luU3BlY2lmaWMyLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnbWF4RHVyYXRpb24nKTtcbiAgICAgIGNvaW5TcGVjaWZpYzIubWF4RHVyYXRpb24uc2hvdWxkLmVxdWFsKGJhc2Vjb2luLk1BWF9WQUxJRElUWV9EVVJBVElPTik7XG4gICAgICBjb2luU3BlY2lmaWMyLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnY29tbW9uS2V5Y2hhaW4nKTtcbiAgICAgIGNvaW5TcGVjaWZpYzIuc2hvdWxkLmhhc093blByb3BlcnR5KCdsYXN0U2NhbkluZGV4Jyk7XG4gICAgICBjb2luU3BlY2lmaWMyLmxhc3RTY2FuSW5kZXguc2hvdWxkLmVxdWFsKDMpO1xuXG4gICAgICAvLyBkZXNlcmlhbGl6ZSB0aGUgdHhuIGFuZCB2ZXJpZnkgdGhlIGZpZWxkcyBhcmUgd2hhdCB3ZSBleHBlY3RcbiAgICAgIGNvbnN0IHR4QnVpbGRlcjIgPSBiYXNlY29pbi5nZXRCdWlsZGVyKCkuZnJvbSh0eG4yLnNlcmlhbGl6ZWRUeCk7XG4gICAgICAvLyBzb21lIGluZm9ybWF0aW9uIGlzbid0IGRlc2VyaWFsaXplZCBieSB0aGUgZnJvbSBtZXRob2QsIHNvIHdlIHdpbGxcbiAgICAgIC8vIHN1cHBseSBpdCBhZ2FpbiBpbiBvcmRlciB0byByZS1idWlsZCB0aGUgdHhuXG4gICAgICB0eEJ1aWxkZXIyXG4gICAgICAgIC52YWxpZGl0eSh7XG4gICAgICAgICAgZmlyc3RWYWxpZDogdGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyLFxuICAgICAgICAgIG1heER1cmF0aW9uOiBiYXNlY29pbi5NQVhfVkFMSURJVFlfRFVSQVRJT04sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZWZlcmVuY2VCbG9jayh0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suaGFzaClcbiAgICAgICAgLnNlbmRlcih7IGFkZHJlc3M6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MzIH0pO1xuICAgICAgY29uc3QgdHgyID0gYXdhaXQgdHhCdWlsZGVyMi5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uMiA9IHR4Mi50b0pzb24oKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5zZW5kZXIsIHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MzKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5ibG9ja051bWJlciwgdGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5yZWZlcmVuY2VCbG9jaywgdGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLmdlbmVzaXNIYXNoLCBnZW5lc2lzSGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIuc3BlY1ZlcnNpb24sIHNwZWNWZXJzaW9uKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5ub25jZSwgbm9uY2UpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLnRpcCwgMCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIudHJhbnNhY3Rpb25WZXJzaW9uLCB0eFZlcnNpb24pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLmNoYWluTmFtZSwgY2hhaW5OYW1lKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5lcmFQZXJpb2QsIGVyYVBlcmlvZCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIudG8sIGJhc2VBZGRyKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2tpcCBidWlsZGluZyBjb25zb2xpZGF0ZSB0cmFuc2FjdGlvbiBpZiBiYWxhbmNlIGlzIGVxdWFsIHRvIHplcm8nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAxLFxuICAgICAgICAgIGVuZGluZ1NjYW5JbmRleDogMixcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ0RpZCBub3QgZmluZCBhbiBhZGRyZXNzIHdpdGggZnVuZHMgdG8gcmVjb3ZlcicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiBzdGFydGluZ1NjYW5JbmRleCBpcyBub3QgZ2UgdG8gMScsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyQ29uc29saWRhdGlvbnMoe1xuICAgICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLnVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLmJpdGdvS2V5LFxuICAgICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAtMSxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ0ludmFsaWQgc3RhcnRpbmcgb3IgZW5kaW5nIGluZGV4IHRvIHNjYW4gZm9yIGFkZHJlc3Nlcy4gc3RhcnRpbmdTY2FuSW5kZXg6IC0xLCBlbmRpbmdTY2FuSW5kZXg6IDE5LidcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgc2NhbiBmYWN0b3IgaXMgdG9vIGhpZ2gnLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgICBzdGFydGluZ1NjYW5JbmRleDogMSxcbiAgICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDMwMCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ0ludmFsaWQgc3RhcnRpbmcgb3IgZW5kaW5nIGluZGV4IHRvIHNjYW4gZm9yIGFkZHJlc3Nlcy4gc3RhcnRpbmdTY2FuSW5kZXg6IDEsIGVuZGluZ1NjYW5JbmRleDogMzAwLidcbiAgICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0J1aWxkIENvbnNvbGlkYXRpb24gUmVjb3ZlcmllcyAoTVBDdjIpOicsICgpID0+IHtcbiAgICBjb25zdCBzYW5kQm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgIGNvbnN0IG5vbmNlID0gMTIzO1xuICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSB0ZXN0RGF0YS53cndVc2VyLndhbGxldFBhc3NwaHJhc2U7XG4gICAgbGV0IG1wY1YyVXNlcktleTogc3RyaW5nO1xuICAgIGxldCBtcGNWMkJhY2t1cEtleTogc3RyaW5nO1xuICAgIGxldCBtcGNWMkNvbW1vbktleUNoYWluOiBzdHJpbmc7XG4gICAgbGV0IGJhc2VBZGRyOiBzdHJpbmc7XG4gICAgbGV0IG1wY1YyQWRkcmVzczE6IHN0cmluZztcbiAgICBsZXQgbXBjVjJBZGRyZXNzMjogc3RyaW5nO1xuICAgIGxldCBtcGNWMkFkZHJlc3MzOiBzdHJpbmc7XG5cbiAgICBiZWZvcmUoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgW3VzZXJEa2csIGJhY2t1cERrZ10gPSBhd2FpdCBNUFNVdGlsLmdlbmVyYXRlRWREc2FES0dLZXlTaGFyZXMoKTtcblxuICAgICAgbXBjVjJVc2VyS2V5ID0gYXdhaXQgZW5jcnlwdCh3YWxsZXRQYXNzcGhyYXNlLCB1c2VyRGtnLmdldFJlZHVjZWRLZXlTaGFyZSgpLnRvU3RyaW5nKCdiYXNlNjQnKSk7XG4gICAgICBtcGNWMkJhY2t1cEtleSA9IGF3YWl0IGVuY3J5cHQod2FsbGV0UGFzc3BocmFzZSwgYmFja3VwRGtnLmdldFJlZHVjZWRLZXlTaGFyZSgpLnRvU3RyaW5nKCdiYXNlNjQnKSk7XG4gICAgICBtcGNWMkNvbW1vbktleUNoYWluID0gdXNlckRrZy5nZXRDb21tb25LZXljaGFpbigpO1xuICAgICAgY29uc3QgbXBjID0gYXdhaXQgRUREU0FNZXRob2RzLmdldEluaXRpYWxpemVkTXBjSW5zdGFuY2UoKTtcbiAgICAgIGJhc2VBZGRyID0gYmFzZWNvaW4uZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkobXBjLmRlcml2ZVVuaGFyZGVuZWQobXBjVjJDb21tb25LZXlDaGFpbiwgJ20vMCcpLnNsaWNlKDAsIDY0KSk7XG4gICAgICBtcGNWMkFkZHJlc3MxID0gYmFzZWNvaW4uZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkobXBjLmRlcml2ZVVuaGFyZGVuZWQobXBjVjJDb21tb25LZXlDaGFpbiwgJ20vMScpLnNsaWNlKDAsIDY0KSk7XG4gICAgICBtcGNWMkFkZHJlc3MyID0gYmFzZWNvaW4uZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkobXBjLmRlcml2ZVVuaGFyZGVuZWQobXBjVjJDb21tb25LZXlDaGFpbiwgJ20vMicpLnNsaWNlKDAsIDY0KSk7XG4gICAgICBtcGNWMkFkZHJlc3MzID0gYmFzZWNvaW4uZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkobXBjLmRlcml2ZVVuaGFyZGVuZWQobXBjVjJDb21tb25LZXlDaGFpbiwgJ20vMycpLnNsaWNlKDAsIDY0KSk7XG4gICAgfSk7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFjY291bnRJbmZvQ0IgPSBzYW5kQm94LnN0dWIoRG90LnByb3RvdHlwZSwgJ2dldEFjY291bnRJbmZvJyBhcyBrZXlvZiBEb3QpO1xuICAgICAgYWNjb3VudEluZm9DQi53aXRoQXJncyhtcGNWMkFkZHJlc3MxKS5yZXNvbHZlcyh7IG5vbmNlLCBmcmVlQmFsYW5jZTogMCB9KTtcbiAgICAgIGFjY291bnRJbmZvQ0Iud2l0aEFyZ3MobXBjVjJBZGRyZXNzMikucmVzb2x2ZXMoeyBub25jZSwgZnJlZUJhbGFuY2U6IDE1MTAwMDAwMDAwMDAgfSk7XG4gICAgICBhY2NvdW50SW5mb0NCLndpdGhBcmdzKG1wY1YyQWRkcmVzczMpLnJlc29sdmVzKHsgbm9uY2UsIGZyZWVCYWxhbmNlOiAxNTEwMDAwMDAwMDAwIH0pO1xuICAgICAgY29uc3QgaGVhZGVySW5mb0NCID0gc2FuZEJveC5zdHViKERvdC5wcm90b3R5cGUsICdnZXRIZWFkZXJJbmZvJyBhcyBrZXlvZiBEb3QpO1xuICAgICAgaGVhZGVySW5mb0NCLnJlc29sdmVzKHtcbiAgICAgICAgaGVhZGVyTnVtYmVyOiB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIsXG4gICAgICAgIGhlYWRlckhhc2g6IHRlc3REYXRhLndlc3RlbmRCbG9jay5oYXNoLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBnZXRGZWVDQiA9IHNhbmRCb3guc3R1YihEb3QucHJvdG90eXBlLCAnZ2V0RmVlJyBhcyBrZXlvZiBEb3QpO1xuICAgICAgZ2V0RmVlQ0IucmVzb2x2ZXMoMTU3ODM4MTI4NTYpO1xuICAgICAgY29uc3QgZ2V0TWF0ZXJpYWxDQiA9IHNhbmRCb3guc3R1YihEb3QucHJvdG90eXBlLCAnZ2V0TWF0ZXJpYWwnIGFzIGtleW9mIERvdCk7XG4gICAgICBnZXRNYXRlcmlhbENCLnJlc29sdmVzKHV0aWxzLmdldE1hdGVyaWFsKGNvaW5zLmdldCgndGRvdCcpKSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgc2FuZEJveC5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJ1aWxkIE1QQ3YyIHNpZ25lZCBjb25zb2xpZGF0aW9uIHJlY292ZXJpZXMgYWNyb3NzIDIrIGZ1bmRlZCBpbmRleGVzLCBzd2VlcGluZyB0byB0aGUgTVBDdjIgYmFzZSBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZ2V0RWRkc2FNYXRlcmlhbFNweSA9IHNhbmRCb3guc3B5KFxuICAgICAgICBiYXNlY29pbiBhcyB1bmtub3duIGFzIHsgZ2V0RWRkc2FTaWduaW5nTWF0ZXJpYWw6IHVua25vd24gfSxcbiAgICAgICAgJ2dldEVkZHNhU2lnbmluZ01hdGVyaWFsJ1xuICAgICAgKTtcblxuICAgICAgY29uc3QgcmVzID0gKGF3YWl0IGJhc2Vjb2luLnJlY292ZXJDb25zb2xpZGF0aW9ucyh7XG4gICAgICAgIHVzZXJLZXk6IG1wY1YyVXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiBtcGNWMkJhY2t1cEtleSxcbiAgICAgICAgYml0Z29LZXk6IG1wY1YyQ29tbW9uS2V5Q2hhaW4sXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAxLFxuICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDQsXG4gICAgICB9KSkgYXMgTVBDVHhzO1xuXG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnRyYW5zYWN0aW9ucy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgc2hvdWxkLmVxdWFsKHJlcy5sYXN0U2NhbkluZGV4LCAzKTtcblxuICAgICAgY29uc3QgdHhCdWlsZGVyMSA9IGJhc2Vjb2luLmdldEJ1aWxkZXIoKS5mcm9tKHJlcy50cmFuc2FjdGlvbnNbMF0uc2VyaWFsaXplZFR4KTtcbiAgICAgIHR4QnVpbGRlcjFcbiAgICAgICAgLnZhbGlkaXR5KHsgZmlyc3RWYWxpZDogdGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyLCBtYXhEdXJhdGlvbjogYmFzZWNvaW4uTUFYX1ZBTElESVRZX0RVUkFUSU9OIH0pXG4gICAgICAgIC5yZWZlcmVuY2VCbG9jayh0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suaGFzaCk7XG4gICAgICBjb25zdCB0eDEgPSBhd2FpdCB0eEJ1aWxkZXIxLmJ1aWxkKCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4MS50b0pzb24oKS50bywgYmFzZUFkZHIpO1xuXG4gICAgICAvLyByZWNvdmVyQ29uc29saWRhdGlvbnMgbXVzdCBkZXRlY3Qgc2lnbmluZyBtYXRlcmlhbCBleGFjdGx5IG9uY2UgYXQgdGhlIHRvcCBvZiB0aGUgc2NhblxuICAgICAgLy8gbG9vcCwgbm90IHBlci1pdGVyYXRpb24gaW5zaWRlIHJlY292ZXIoKSDigJQgcHJlY29tcHV0ZWRNYXRlcmlhbCBieXBhc3NlcyBwZXItY2FsbCBkZXRlY3Rpb24uXG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRPbmNlKGdldEVkZHNhTWF0ZXJpYWxTcHkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjYWxsIGdldEVkZHNhU2lnbmluZ01hdGVyaWFsIGV4YWN0bHkgb25jZSBhY3Jvc3MgYWxsIHJlY292ZXIoKSBpdGVyYXRpb25zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZ2V0RWRkc2FNYXRlcmlhbFNweSA9IHNhbmRCb3guc3B5KFxuICAgICAgICBiYXNlY29pbiBhcyB1bmtub3duIGFzIHsgZ2V0RWRkc2FTaWduaW5nTWF0ZXJpYWw6IHVua25vd24gfSxcbiAgICAgICAgJ2dldEVkZHNhU2lnbmluZ01hdGVyaWFsJ1xuICAgICAgKTtcblxuICAgICAgYXdhaXQgYmFzZWNvaW4ucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgdXNlcktleTogbXBjVjJVc2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IG1wY1YyQmFja3VwS2V5LFxuICAgICAgICBiaXRnb0tleTogbXBjVjJDb21tb25LZXlDaGFpbixcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgc3RhcnRpbmdTY2FuSW5kZXg6IDEsXG4gICAgICAgIGVuZGluZ1NjYW5JbmRleDogNCxcbiAgICAgIH0pO1xuXG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRPbmNlKGdldEVkZHNhTWF0ZXJpYWxTcHkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBsZWF2ZSBNUEN2MSBiYXNlIGFkZHJlc3MgZGVyaXZhdGlvbiBhbmQgc2lnbmluZyB1bmNoYW5nZWQgKHJlZ3Jlc3Npb24pJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmFzZUFkZHJWMSA9IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MwO1xuICAgICAgKGJhc2Vjb2luLmdldEFjY291bnRJbmZvIGFzIHNpbm9uLlNpbm9uU3R1Yikud2l0aEFyZ3ModGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczEpLnJlc29sdmVzKHtcbiAgICAgICAgbm9uY2UsXG4gICAgICAgIGZyZWVCYWxhbmNlOiAxMDAwMDAwMDAwMCxcbiAgICAgIH0pO1xuICAgICAgKGJhc2Vjb2luLmdldEFjY291bnRJbmZvIGFzIHNpbm9uLlNpbm9uU3R1Yikud2l0aEFyZ3ModGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczIpLnJlc29sdmVzKHtcbiAgICAgICAgbm9uY2UsXG4gICAgICAgIGZyZWVCYWxhbmNlOiAxNTEwMDAwMDAwMDAwLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGdldFRTU1NpZ25hdHVyZVNweSA9IHNhbmRCb3guc3B5KEVERFNBTWV0aG9kcywgJ2dldFRTU1NpZ25hdHVyZScpO1xuXG4gICAgICBjb25zdCByZXMgPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgdXNlcktleTogdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIudXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgc3RhcnRpbmdTY2FuSW5kZXg6IDEsXG4gICAgICAgIGVuZGluZ1NjYW5JbmRleDogMyxcbiAgICAgIH0pKSBhcyBNUENUeHM7XG5cbiAgICAgIHJlcy5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRPbmNlKGdldFRTU1NpZ25hdHVyZVNweSk7XG5cbiAgICAgIGNvbnN0IHR4QnVpbGRlcjEgPSBiYXNlY29pbi5nZXRCdWlsZGVyKCkuZnJvbShyZXMudHJhbnNhY3Rpb25zWzBdLnNlcmlhbGl6ZWRUeCk7XG4gICAgICB0eEJ1aWxkZXIxXG4gICAgICAgIC52YWxpZGl0eSh7IGZpcnN0VmFsaWQ6IHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlciwgbWF4RHVyYXRpb246IGJhc2Vjb2luLk1BWF9WQUxJRElUWV9EVVJBVElPTiB9KVxuICAgICAgICAucmVmZXJlbmNlQmxvY2sodGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpO1xuICAgICAgY29uc3QgdHgxID0gYXdhaXQgdHhCdWlsZGVyMS5idWlsZCgpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eDEudG9Kc29uKCkudG8sIGJhc2VBZGRyVjEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBsZWF2ZSB0aGUgdW5zaWduZWQgKG5vIHBhc3NwaHJhc2UpIGNvbGQgcGF0aCB1bmNoYW5nZWQgd2hlbiBrZXljYXJkIGlzIE1QQ3YyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVzID0gKGF3YWl0IGJhc2Vjb2luLnJlY292ZXJDb25zb2xpZGF0aW9ucyh7XG4gICAgICAgIGJpdGdvS2V5OiBtcGNWMkNvbW1vbktleUNoYWluLFxuICAgICAgICBzdGFydGluZ1NjYW5JbmRleDogMSxcbiAgICAgICAgZW5kaW5nU2NhbkluZGV4OiA0LFxuICAgICAgfSkpIGFzIHsgdHhSZXF1ZXN0czogdW5rbm93bltdIH07XG5cbiAgICAgIHJlcy5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICByZXMudHhSZXF1ZXN0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUmVjb3ZlciBUcmFuc2FjdGlvbiBGYWlsdXJlczonLCAoKSA9PiB7XG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICBjb25zdCBkZXN0QWRkciA9IHRlc3REYXRhLmFjY291bnRzLmFjY291bnQxLmFkZHJlc3M7XG4gICAgY29uc3Qgbm9uY2UgPSAxMjM7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFjY291bnRJbmZvQ0IgPSBzYW5kQm94LnN0dWIoRG90LnByb3RvdHlwZSwgJ2dldEFjY291bnRJbmZvJyBhcyBrZXlvZiBEb3QpO1xuICAgICAgYWNjb3VudEluZm9DQi5yZXNvbHZlcyh7XG4gICAgICAgIG5vbmNlOiBub25jZSxcbiAgICAgICAgZnJlZUJhbGFuY2U6IDAsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGdldEZlZUNCID0gc2FuZEJveC5zdHViKERvdC5wcm90b3R5cGUsICdnZXRGZWUnIGFzIGtleW9mIERvdCk7XG4gICAgICBnZXRGZWVDQi5yZXNvbHZlcygxNTc4MzgxMjg1Nik7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgc2FuZEJveC5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gcmVjb3ZlciBkdWUgdG8gbm90IGZpbmRpbmcgYW4gYWRkcmVzcyB3aXRoIGZ1bmRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLndyd1VzZXIudXNlcktleSxcbiAgICAgICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLndyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS53cndVc2VyLmJpdGdvS2V5LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHRlc3REYXRhLndyd1VzZXIud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0QWRkcixcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ0RpZCBub3QgZmluZCBhZGRyZXNzIHdpdGggZnVuZHMgdG8gcmVjb3ZlcicpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVmVyaWZ5IFRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGFkZHJlc3MxID0gJzVHZTU5cVJuWmE4Ynh5aFZGRTZCRG9ZM2t1aFNyTlZFVFJ4WFlMdHkxSGg2WFRhZic7XG4gICAgY29uc3QgYWRkcmVzczIgPSAnNURpTUxadWdtY0tFSDNpZ1BaUDM2N0ZxdW1tWmtXZVc1WjZ6RENITGZ4UmpuUFhlJztcbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIHR4UHJlYnVpbGQgd2l0aCBtb3JlIHRoYW4gb25lIHJlY2lwaWVudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzI1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OlxuICAgICAgICAgICcweGE4MGEwMzAwMTYxYjk2OWI2YjUzZWY4MTIyNWZlZWEzODgyMjg0Yzc3OGNkNGE0MDZkMjMyMTVmY2Y0OTJlODNmNzVkNDI5NjBiMDAyMDRhYTlkMTAxZWI2MDA0MDAwMDAwNjU5MDBmMDAxMDAwMDAwMDY3Zjk3MjMzOTNlZjc2MjE0ZGYwMTE4YzM0YmJiZDNkYmViYzhlZDQ2YTEwOTczYThjOTY5ZDQ4ZmU3NTk4YzlhN2I3NDIwZWUzZTRmZTJiODhkYTBmYzQyYjMwODk3ZTE4ZDU2ZDhiNTZhMTkzNDIxMWQ5ZGU3MzBjZjk2ZGUzMDAnLFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQcmVidWlsZCwgdHhQYXJhbXMgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgYHRkb3QgZG9lc24ndCBzdXBwb3J0IHNlbmRpbmcgdG8gbW9yZSB0aGFuIDEgZGVzdGluYXRpb24gYWRkcmVzcyB3aXRoaW4gYSBzaW5nbGUgdHJhbnNhY3Rpb24uIFRyeSBhZ2FpbiwgdXNpbmcgb25seSBhIHNpbmdsZSByZWNpcGllbnQuYFxuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSB0eFByZWJ1aWxkIHdpdGggbW9yZSB0aGFuIGludmFsaWQgYW1vdW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHt9KTtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcyMDAwMDAwMDAwMCcsIGFkZHJlc3M6ICc1Q1poNzczdktHd0tGQ1lVakdjMzFBd1hDYmY3VFBrYXZkZXVrMlhvdWpKTWpiQkQnIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEhleDpcbiAgICAgICAgICAnMHhhODBhMDMwMDE2MWI5NjliNmI1M2VmODEyMjVmZWVhMzg4MjI4NGM3NzhjZDRhNDA2ZDIzMjE1ZmNmNDkyZTgzZjc1ZDQyOTYwYjAwMjA0YWE5ZDEwMWViNjAwNDAwMDAwMDY1OTAwZjAwMTAwMDAwMDA2N2Y5NzIzMzkzZWY3NjIxNGRmMDExOGMzNGJiYmQzZGJlYmM4ZWQ0NmExMDk3M2E4Yzk2OWQ0OGZlNzU5OGM5YTdiNzQyMGVlM2U0ZmUyYjg4ZGEwZmM0MmIzMDg5N2UxOGQ1NmQ4YjU2YTE5MzQyMTFkOWRlNzMwY2Y5NmRlMzAwJyxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UHJlYnVpbGQsIHR4UGFyYW1zIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKGBSZWNpcGllbnQgYW1vdW50IDIwMDAwMDAwMDAwIGRvZXMgbm90IG1hdGNoIHRyYW5zYWN0aW9uIGFtb3VudCAyMDAwMDAwMDAwMDAwYCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIHR4UHJlYnVpbGQgd2l0aCBtb3JlIHRoYW4gaW52YWxpZCByZWNpcGllbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwge30pO1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzIwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiAnNUNaaDc3M3ZLR3dLRkNVakdjMzFBd1hDYmY3VFBrYXZkdWsyWG91akpNamJCRCcgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OlxuICAgICAgICAgICcweGE4MGEwMzAwMTYxYjk2OWI2YjUzZWY4MTIyNWZlZWEzODgyMjg0Yzc3OGNkNGE0MDZkMjMyMTVmY2Y0OTJlODNmNzVkNDI5NjBiMDAyMDRhYTlkMTAxZWI2MDA0MDAwMDAwNjU5MDBmMDAxMDAwMDAwMDY3Zjk3MjMzOTNlZjc2MjE0ZGYwMTE4YzM0YmJiZDNkYmViYzhlZDQ2YTEwOTczYThjOTY5ZDQ4ZmU3NTk4YzlhN2I3NDIwZWUzZTRmZTJiODhkYTBmYzQyYjMwODk3ZTE4ZDU2ZDhiNTZhMTkzNDIxMWQ5ZGU3MzBjZjk2ZGUzMDAnLFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQcmVidWlsZCwgdHhQYXJhbXMgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgYFJlY2lwaWVudCBhZGRyZXNzIDVDWmg3NzN2S0d3S0ZDVWpHYzMxQXdYQ2JmN1RQa2F2ZHVrMlhvdWpKTWpiQkQgZG9lcyBub3QgbWF0Y2ggdHJhbnNhY3Rpb24gZGVzdGluYXRpb24gYWRkcmVzcyA1Q1poNzczdktHd0tGQ1lVakdjMzFBd1hDYmY3VFBrYXZkZXVrMlhvdWpKTWpiQkRgXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFjY2VwdCBhIHR4UHJlYnVpbGQgd2l0aCBtb3JlIHRoYW4gdmFsaWQgcmVjaXBpZW50IGFuZCBhbW91bnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwge30pO1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzIwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiAnNUNaaDc3M3ZLR3dLRkNZVWpHYzMxQXdYQ2JmN1RQa2F2ZGV1azJYb3VqSk1qYkJEJyB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6XG4gICAgICAgICAgJzB4YTgwYTAzMDAxNjFiOTY5YjZiNTNlZjgxMjI1ZmVlYTM4ODIyODRjNzc4Y2Q0YTQwNmQyMzIxNWZjZjQ5MmU4M2Y3NWQ0Mjk2MGIwMDIwNGFhOWQxMDFlYjYwMDQwMDAwMDA2NTkwMGYwMDEwMDAwMDAwNjdmOTcyMzM5M2VmNzYyMTRkZjAxMThjMzRiYmJkM2RiZWJjOGVkNDZhMTA5NzNhOGM5NjlkNDhmZTc1OThjOWE3Yjc0MjBlZTNlNGZlMmI4OGRhMGZjNDJiMzA4OTdlMThkNTZkOGI1NmExOTM0MjExZDlkZTczMGNmOTZkZTMwMCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UHJlYnVpbGQsIHR4UGFyYW1zIH0pO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIHZhbGlkIGNvbnNvbGlkYXRpb24gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtb2NrZWRXYWxsZXQgPSB7XG4gICAgICAgIGNvaW5TcGVjaWZpYzogKCkgPT4gKHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzVDWmg3NzN2S0d3S0ZDWVVqR2MzMUF3WENiZjdUUGthdmRldWsyWG91akpNamJCRCcsXG4gICAgICAgIH0pLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OlxuICAgICAgICAgICcweGE4MGEwMzAwMTYxYjk2OWI2YjUzZWY4MTIyNWZlZWEzODgyMjg0Yzc3OGNkNGE0MDZkMjMyMTVmY2Y0OTJlODNmNzVkNDI5NjBiMDAyMDRhYTlkMTAxZWI2MDA0MDAwMDAwNjU5MDBmMDAxMDAwMDAwMDY3Zjk3MjMzOTNlZjc2MjE0ZGYwMTE4YzM0YmJiZDNkYmViYzhlZDQ2YTEwOTczYThjOTY5ZDQ4ZmU3NTk4YzlhN2I3NDIwZWUzZTRmZTJiODhkYTBmYzQyYjMwODk3ZTE4ZDU2ZDhiNTZhMTkzNDIxMWQ5ZGU3MzBjZjk2ZGUzMDAnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICB0eFBhcmFtczoge30sXG4gICAgICAgIHdhbGxldDogbW9ja2VkV2FsbGV0IGFzIGFueSxcbiAgICAgICAgdmVyaWZpY2F0aW9uOiB7XG4gICAgICAgICAgY29uc29saWRhdGlvblRvQmFzZUFkZHJlc3M6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQsIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBjb25zb2xpZGF0aW9uIHRyYW5zYWN0aW9uIHdpdGggaW52YWxpZCBkZXN0aW5hdGlvbiBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbW9ja2VkV2FsbGV0ID0ge1xuICAgICAgICBjb2luU3BlY2lmaWM6ICgpID0+ICh7XG4gICAgICAgICAgYmFzZUFkZHJlc3M6ICc1RHhEOW5UMTZHUUxyVTZhQjVwU1M1VnR4b1piVmp1M05IVUNjYXd4WnlaQ1RmNzQnLFxuICAgICAgICB9KSxcbiAgICAgIH07XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEhleDpcbiAgICAgICAgICAnMHhhODBhMDMwMDE2MWI5NjliNmI1M2VmODEyMjVmZWVhMzg4MjI4NGM3NzhjZDRhNDA2ZDIzMjE1ZmNmNDkyZTgzZjc1ZDQyOTYwYjAwMjA0YWE5ZDEwMWViNjAwNDAwMDAwMDY1OTAwZjAwMTAwMDAwMDA2N2Y5NzIzMzkzZWY3NjIxNGRmMDExOGMzNGJiYmQzZGJlYmM4ZWQ0NmExMDk3M2E4Yzk2OWQ0OGZlNzU5OGM5YTdiNzQyMGVlM2U0ZmUyYjg4ZGEwZmM0MmIzMDg5N2UxOGQ1NmQ4YjU2YTE5MzQyMTFkOWRlNzMwY2Y5NmRlMzAwJyxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgICB0eFBhcmFtczoge30sXG4gICAgICAgICAgd2FsbGV0OiBtb2NrZWRXYWxsZXQgYXMgYW55LFxuICAgICAgICAgIHZlcmlmaWNhdGlvbjoge1xuICAgICAgICAgICAgY29uc29saWRhdGlvblRvQmFzZUFkZHJlc3M6IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ1RyYW5zYWN0aW9uIGRlc3RpbmF0aW9uIGFkZHJlc3MgNUNaaDc3M3ZLR3dLRkNZVWpHYzMxQXdYQ2JmN1RQa2F2ZGV1azJYb3VqSk1qYkJEIGRvZXMgbm90IG1hdGNoIHdhbGxldCBiYXNlIGFkZHJlc3MgNUR4RDluVDE2R1FMclU2YUI1cFNTNVZ0eG9aYlZqdTNOSFVDY2F3eFp5WkNUZjc0J1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSB0cmFuc2ZlckFsbCAoc3dlZXApIHRyYW5zYWN0aW9uIHdpdGggZW1wdHkgdHhQYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtb2NrZWRXYWxsZXQgPSB7XG4gICAgICAgIGNvaW5TcGVjaWZpYzogKCkgPT4gKHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzVGZnAxd0pDUHU0aHpWRFRvN1hhTUxxWlN2U2FkeVVRbXhXUER3NzRDQmpFQ1NvcScsXG4gICAgICAgIH0pLFxuICAgICAgfTtcblxuICAgICAgLy8gVHJhbnNmZXJBbGwgdHggKHN3ZWVwKSAtIHVzZXMgbWV0aG9kIDBhMDQgKGJhbGFuY2VzLnRyYW5zZmVyQWxsKVxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6XG4gICAgICAgICAgJzB4OTAwYTA0MDA5ZjdiMDY3NWRiNTlkMTliNGJkOWM4YzcyZWFhYmJhNzVhOTg2M2QwMmIzMDExNWI4YjNjM2NhNWMyMGYwMjU0MDFkNTAxMjEwMzAwMDAwMDlkODgwZjAwMTAwMDAwMDA2N2Y5NzIzMzkzZWY3NjIxNGRmMDExOGMzNGJiYmQzZGJlYmM4ZWQ0NmExMDk3M2E4Yzk2OWQ0OGZlNzU5OGM5MTQ5Nzk5YmM5NjAyY2I1Y2YyMDFmMzQyNWZiOGQyNTNiMmQ0ZTYxZmMxMTlkY2FiMzI0OWYzMDdmNTk0NzU0ZDAwJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgdHhQYXJhbXM6IHt9LFxuICAgICAgICB3YWxsZXQ6IG1vY2tlZFdhbGxldCBhcyBhbnksXG4gICAgICAgIHZlcmlmaWNhdGlvbjoge1xuICAgICAgICAgIGNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgdHJhbnNmZXJBbGwgKHN3ZWVwKSB0cmFuc2FjdGlvbiB3aXRoIHJlY2lwaWVudHMgaW4gdHhQYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtb2NrZWRXYWxsZXQgPSB7XG4gICAgICAgIGNvaW5TcGVjaWZpYzogKCkgPT4gKHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzVGZnAxd0pDUHU0aHpWRFRvN1hhTUxxWlN2U2FkeVVRbXhXUER3NzRDQmpFQ1NvcScsXG4gICAgICAgIH0pLFxuICAgICAgfTtcblxuICAgICAgLy8gVHJhbnNmZXJBbGwgdHggKHN3ZWVwKSAtIF9hbW91bnQgaXMgdW5kZWZpbmVkIGZvciB0aGVzZSB0cmFuc2FjdGlvbnNcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OlxuICAgICAgICAgICcweDkwMGEwNDAwOWY3YjA2NzVkYjU5ZDE5YjRiZDljOGM3MmVhYWJiYTc1YTk4NjNkMDJiMzAxMTViOGIzYzNjYTVjMjBmMDI1NDAxZDUwMTIxMDMwMDAwMDA5ZDg4MGYwMDEwMDAwMDAwNjdmOTcyMzM5M2VmNzYyMTRkZjAxMThjMzRiYmJkM2RiZWJjOGVkNDZhMTA5NzNhOGM5NjlkNDhmZTc1OThjOTE0OTc5OWJjOTYwMmNiNWNmMjAxZjM0MjVmYjhkMjUzYjJkNGU2MWZjMTE5ZGNhYjMyNDlmMzA3ZjU5NDc1NGQwMCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYWRkcmVzczogJzVGZnAxd0pDUHU0aHpWRFRvN1hhTUxxWlN2U2FkeVVRbXhXUER3NzRDQmpFQ1NvcScsIGFtb3VudDogJzEwMDAwMDAwMDAwMDAnIH1dLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgd2FsbGV0OiBtb2NrZWRXYWxsZXQgYXMgYW55LFxuICAgICAgICB2ZXJpZmljYXRpb246IHtcbiAgICAgICAgICBjb25zb2xpZGF0aW9uVG9CYXNlQWRkcmVzczogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCB3YXNtVHJhbnNmZXJLZWVwQWxpdmVIZXggPVxuICAgICAgJzB4YTgwYTAzMDAxNjFiOTY5YjZiNTNlZjgxMjI1ZmVlYTM4ODIyODRjNzc4Y2Q0YTQwNmQyMzIxNWZjZjQ5MmU4M2Y3NWQ0Mjk2MGIwMDIwNGFhOWQxMDFlYjYwMDQwMDAwMDA2NTkwMGYwMDEwMDAwMDAwNjdmOTcyMzM5M2VmNzYyMTRkZjAxMThjMzRiYmJkM2RiZWJjOGVkNDZhMTA5NzNhOGM5NjlkNDhmZTc1OThjOWE3Yjc0MjBlZTNlNGZlMmI4OGRhMGZjNDJiMzA4OTdlMThkNTZkOGI1NmExOTM0MjExZDlkZTczMGNmOTZkZTMwMCc7XG4gICAgY29uc3Qgd2FzbVRyYW5zZmVyQWxsSGV4ID1cbiAgICAgICcweDkwMGEwNDAwOWY3YjA2NzVkYjU5ZDE5YjRiZDljOGM3MmVhYWJiYTc1YTk4NjNkMDJiMzAxMTViOGIzYzNjYTVjMjBmMDI1NDAxZDUwMTIxMDMwMDAwMDA5ZDg4MGYwMDEwMDAwMDAwNjdmOTcyMzM5M2VmNzYyMTRkZjAxMThjMzRiYmJkM2RiZWJjOGVkNDZhMTA5NzNhOGM5NjlkNDhmZTc1OThjOTE0OTc5OWJjOTYwMmNiNWNmMjAxZjM0MjVmYjhkMjUzYjJkNGU2MWZjMTE5ZGNhYjMyNDlmMzA3ZjU5NDc1NGQwMCc7XG5cbiAgICBpdCgnc2hvdWxkIGFjY2VwdCBhIHZhbGlkIFdBU00tYnVpbHQgcGF5bWVudCAodGRvdCknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMjAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6ICc1Q1poNzczdktHd0tGQ1lVakdjMzFBd1hDYmY3VFBrYXZkZXVrMlhvdWpKTWpiQkQnIH1dLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQcmVidWlsZDogeyB0eEhleDogd2FzbVRyYW5zZmVyS2VlcEFsaXZlSGV4IH0sIHR4UGFyYW1zIH0pO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBXQVNNLWJ1aWx0IHBheW1lbnQgd2l0aCB3cm9uZyBhbW91bnQgKHRkb3QpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzk5OTknLCBhZGRyZXNzOiAnNUNaaDc3M3ZLR3dLRkNZVWpHYzMxQXdYQ2JmN1RQa2F2ZGV1azJYb3VqSk1qYkJEJyB9XSxcbiAgICAgIH07XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFByZWJ1aWxkOiB7IHR4SGV4OiB3YXNtVHJhbnNmZXJLZWVwQWxpdmVIZXggfSwgdHhQYXJhbXMgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL2RvZXMgbm90IG1hdGNoIHRyYW5zYWN0aW9uIGFtb3VudC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgV0FTTS1idWlsdCBwYXltZW50IHdpdGggd3JvbmcgcmVjaXBpZW50ICh0ZG90KScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcyMDAwMDAwMDAwMDAwJywgYWRkcmVzczogJzVEeEQ5blQxNkdRTHJVNmFCNXBTUzVWdHhvWmJWanUzTkhVQ2Nhd3haeVpDVGY3NCcgfV0sXG4gICAgICB9O1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQcmVidWlsZDogeyB0eEhleDogd2FzbVRyYW5zZmVyS2VlcEFsaXZlSGV4IH0sIHR4UGFyYW1zIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9kb2VzIG5vdCBtYXRjaCB0cmFuc2FjdGlvbiBkZXN0aW5hdGlvbiBhZGRyZXNzLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBXQVNNLWJ1aWx0IHRyYW5zZmVyQWxsIGNvbnNvbGlkYXRpb24gKHRkb3QpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbW9ja2VkV2FsbGV0ID0ge1xuICAgICAgICBjb2luU3BlY2lmaWM6ICgpID0+ICh7IGJhc2VBZGRyZXNzOiAnNUZmcDF3SkNQdTRoelZEVG83WGFNTHFaU3ZTYWR5VVFteFdQRHc3NENCakVDU29xJyB9KSxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXg6IHdhc21UcmFuc2ZlckFsbEhleCB9LFxuICAgICAgICB0eFBhcmFtczoge30sXG4gICAgICAgIHdhbGxldDogbW9ja2VkV2FsbGV0IGFzIGFueSxcbiAgICAgICAgdmVyaWZpY2F0aW9uOiB7IGNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzOiB0cnVlIH0sXG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQsIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgV0FTTS1idWlsdCB0cmFuc2ZlckFsbCB3aXRoIHJlY2lwaWVudHMgc2tpcHMgYW1vdW50IGNoZWNrICh0ZG90KScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1vY2tlZFdhbGxldCA9IHtcbiAgICAgICAgY29pblNwZWNpZmljOiAoKSA9PiAoeyBiYXNlQWRkcmVzczogJzVGZnAxd0pDUHU0aHpWRFRvN1hhTUxxWlN2U2FkeVVRbXhXUER3NzRDQmpFQ1NvcScgfSksXG4gICAgICB9O1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6ICc1RmZwMXdKQ1B1NGh6VkRUbzdYYU1McVpTdlNhZHlVUW14V1BEdzc0Q0JqRUNTb3EnLCBhbW91bnQ6ICc5OTk5OTknIH1dLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleDogd2FzbVRyYW5zZmVyQWxsSGV4IH0sXG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB3YWxsZXQ6IG1vY2tlZFdhbGxldCBhcyBhbnksXG4gICAgICAgIHZlcmlmaWNhdGlvbjogeyBjb25zb2xpZGF0aW9uVG9CYXNlQWRkcmVzczogdHJ1ZSB9LFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZGVjb2RlIHdhc20tYnVpbHQgc2lnbmluZyBwYXlsb2FkIHdpdGggbGVnYWN5IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB7IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkgfSA9IGF3YWl0IGltcG9ydCgnLi4vLi4vc3JjL2xpYicpO1xuICAgICAgY29uc3QgZmFjdG9yeSA9IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCgndGRvdCcpKTtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZnJvbSh3YXNtVHJhbnNmZXJLZWVwQWxpdmVIZXgpO1xuICAgICAgdHhCdWlsZGVyLnNlbmRlcih7IGFkZHJlc3M6ICc1RUdvRkE5NW9temVtUnNzRUxMRGpWZW5OWjY4YVh5VWVxdEtRU2NYU0VCdlZKa3InIH0pO1xuICAgICAgdHhCdWlsZGVyLnZhbGlkaXR5KHsgZmlyc3RWYWxpZDogMTAwMCB9KTtcbiAgICAgIHR4QnVpbGRlci5yZWZlcmVuY2VCbG9jaygnMHgxNDk3OTliYzk2MDJjYjVjZjIwMWYzNDI1ZmI4ZDI1M2IyZDRlNjFmYzExOWRjYWIzMjQ5ZjMwN2Y1OTQ3NTRkJyk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QganNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKChqc29uIGFzIGFueSkudG8sICc1Q1poNzczdktHd0tGQ1lVakdjMzFBd1hDYmY3VFBrYXZkZXVrMlhvdWpKTWpiQkQnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCgoanNvbiBhcyBhbnkpLmFtb3VudCwgJzIwMDAwMDAwMDAwMDAnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzV2FsbGV0QWRkcmVzcycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHZlcmlmeSB2YWxpZCB3YWxsZXQgYWRkcmVzcyB3aXRoIGNvcnJlY3Qga2V5Y2hhaW4gYW5kIGluZGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICc1RHhEOW5UMTZHUUxyVTZhQjVwU1M1VnR4b1piVmp1M05IVUNjYXd4WnlaQ1RmNzQnO1xuICAgICAgY29uc3QgY29tbW9uS2V5Y2hhaW4gPVxuICAgICAgICAnNmQyZDUxNTBmNmU0MzVkZmQ5YjRmMjI1ZjJjYzI5ZDk1ZWMzYjYxYjM0ZThiZWM5ODY5M2IxYTdmZmU0NGNkNzY0Zjk5ZWU1MDU4ODM4ZDc4NWM3MzM2MGFkNGYyNGQ3OGUwMjU1YWIyYzM2OGMwOTA2MGIyOWE5YjI3ZjA0MGUnO1xuICAgICAgY29uc3QgaW5kZXggPSAnMyc7XG4gICAgICBjb25zdCBrZXljaGFpbnMgPSBbeyBpZDogJzEnLCB0eXBlOiAndHNzJyBhcyBjb25zdCwgY29tbW9uS2V5Y2hhaW4gfV07XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLmlzV2FsbGV0QWRkcmVzcyh7IGtleWNoYWlucywgYWRkcmVzcywgaW5kZXggfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIGFkZHJlc3Mgd2l0aCBpbmNvcnJlY3Qga2V5Y2hhaW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gJzVEeEQ5blQxNkdRTHJVNmFCNXBTUzVWdHhvWmJWanUzTkhVQ2Nhd3haeVpDVGY3NCc7XG4gICAgICBjb25zdCB3cm9uZ0tleWNoYWluID1cbiAgICAgICAgJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAnO1xuICAgICAgY29uc3QgaW5kZXggPSAnMyc7XG4gICAgICBjb25zdCBrZXljaGFpbnMgPSBbeyBpZDogJzEnLCB0eXBlOiAndHNzJyBhcyBjb25zdCwgY29tbW9uS2V5Y2hhaW46IHdyb25nS2V5Y2hhaW4gfV07XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLmlzV2FsbGV0QWRkcmVzcyh7IGtleWNoYWlucywgYWRkcmVzcywgaW5kZXggfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBhZGRyZXNzIHdpdGggaW5jb3JyZWN0IGluZGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICc1RHhEOW5UMTZHUUxyVTZhQjVwU1M1VnR4b1piVmp1M05IVUNjYXd4WnlaQ1RmNzQnO1xuICAgICAgY29uc3QgY29tbW9uS2V5Y2hhaW4gPVxuICAgICAgICAnNmQyZDUxNTBmNmU0MzVkZmQ5YjRmMjI1ZjJjYzI5ZDk1ZWMzYjYxYjM0ZThiZWM5ODY5M2IxYTdmZmU0NGNkNzY0Zjk5ZWU1MDU4ODM4ZDc4NWM3MzM2MGFkNGYyNGQ3OGUwMjU1YWIyYzM2OGMwOTA2MGIyOWE5YjI3ZjA0MGUnO1xuICAgICAgY29uc3Qgd3JvbmdJbmRleCA9ICc5OTknO1xuICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW3sgaWQ6ICcxJywgdHlwZTogJ3RzcycgYXMgY29uc3QsIGNvbW1vbktleWNoYWluIH1dO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi5pc1dhbGxldEFkZHJlc3MoeyBrZXljaGFpbnMsIGFkZHJlc3MsIGluZGV4OiB3cm9uZ0luZGV4IH0pO1xuICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbChmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBpbnZhbGlkIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZhbGlkQWRkcmVzcyA9ICdpbnZhbGlkYWRkcmVzcyc7XG4gICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9XG4gICAgICAgICc2ZDJkNTE1MGY2ZTQzNWRmZDliNGYyMjVmMmNjMjlkOTVlYzNiNjFiMzRlOGJlYzk4NjkzYjFhN2ZmZTQ0Y2Q3NjRmOTllZTUwNTg4MzhkNzg1YzczMzYwYWQ0ZjI0ZDc4ZTAyNTVhYjJjMzY4YzA5MDYwYjI5YTliMjdmMDQwZSc7XG4gICAgICBjb25zdCBpbmRleCA9ICczJztcbiAgICAgIGNvbnN0IGtleWNoYWlucyA9IFt7IGlkOiAnMScsIHR5cGU6ICd0c3MnIGFzIGNvbnN0LCBjb21tb25LZXljaGFpbiB9XTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gYXdhaXQgYmFzZWNvaW4uaXNXYWxsZXRBZGRyZXNzKHsga2V5Y2hhaW5zLCBhZGRyZXNzOiBpbnZhbGlkQWRkcmVzcywgaW5kZXggfSksIHtcbiAgICAgICAgbWVzc2FnZTogYGludmFsaWQgYWRkcmVzczogJHtpbnZhbGlkQWRkcmVzc31gLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRBZGRyZXNzRnJvbVB1YmxpY0tleScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGNvbnZlcnQgcHVibGljIGtleSB0byBTUzU4IGFkZHJlc3MgZm9yIHRlc3RuZXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwdWJsaWNLZXkgPSAnNTM4NDVkN2I2YTZlNGE2NjZmYTJhMGY1MDBiODg4NDliMDI5MjZkYTU1OTA5OTM3MzFkMmI0MjhiNzY0MzY5MCc7XG4gICAgICBjb25zdCBleHBlY3RlZEFkZHJlc3MgPSAnNUR4RDluVDE2R1FMclU2YUI1cFNTNVZ0eG9aYlZqdTNOSFVDY2F3eFp5WkNUZjc0JztcblxuICAgICAgY29uc3QgYWRkcmVzcyA9IGJhc2Vjb2luLmdldEFkZHJlc3NGcm9tUHVibGljS2V5KHB1YmxpY0tleSk7XG4gICAgICBhZGRyZXNzLnNob3VsZC5lcXVhbChleHBlY3RlZEFkZHJlc3MpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb252ZXJ0IHB1YmxpYyBrZXkgdG8gU1M1OCBhZGRyZXNzIGZvciBtYWlubmV0JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHVibGljS2V5ID0gJzUzODQ1ZDdiNmE2ZTRhNjY2ZmEyYTBmNTAwYjg4ODQ5YjAyOTI2ZGE1NTkwOTkzNzMxZDJiNDI4Yjc2NDM2OTAnO1xuICAgICAgLy8gTWFpbm5ldCB1c2VzIGRpZmZlcmVudCBTUzU4IHByZWZpeCAoMCkgdnMgdGVzdG5ldCAoNDIpXG4gICAgICBjb25zdCBhZGRyZXNzID0gcHJvZENvaW4uZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkocHVibGljS2V5KTtcbiAgICAgIGFkZHJlc3Muc2hvdWxkLmJlLnR5cGUoJ3N0cmluZycpO1xuICAgICAgYWRkcmVzcy5sZW5ndGguc2hvdWxkLmJlLmdyZWF0ZXJUaGFuKDApO1xuICAgICAgLy8gU2hvdWxkIGJlIGRpZmZlcmVudCBmcm9tIHRlc3RuZXQgYWRkcmVzc1xuICAgICAgYWRkcmVzcy5zaG91bGQubm90LmVxdWFsKCc1RHhEOW5UMTZHUUxyVTZhQjVwU1M1VnR4b1piVmp1M05IVUNjYXd4WnlaQ1RmNzQnKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==