@bitgo-beta/sdk-core 8.2.1-beta.209 → 8.2.1-beta.2091

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 (806) hide show
  1. package/dist/src/account-lib/baseCoin/baseTransaction.d.ts +0 -1
  2. package/dist/src/account-lib/baseCoin/baseTransaction.d.ts.map +1 -1
  3. package/dist/src/account-lib/baseCoin/baseTransactionBuilder.d.ts +3 -3
  4. package/dist/src/account-lib/baseCoin/baseTransactionBuilder.d.ts.map +1 -1
  5. package/dist/src/account-lib/baseCoin/baseTransactionBuilder.js +4 -3
  6. package/dist/src/account-lib/baseCoin/ed25519KeyPair.d.ts +1 -0
  7. package/dist/src/account-lib/baseCoin/ed25519KeyPair.d.ts.map +1 -1
  8. package/dist/src/account-lib/baseCoin/ed25519KeyPair.js +43 -31
  9. package/dist/src/account-lib/baseCoin/enum.d.ts +59 -5
  10. package/dist/src/account-lib/baseCoin/enum.d.ts.map +1 -1
  11. package/dist/src/account-lib/baseCoin/enum.js +112 -10
  12. package/dist/src/account-lib/baseCoin/errors.d.ts +3 -0
  13. package/dist/src/account-lib/baseCoin/errors.d.ts.map +1 -1
  14. package/dist/src/account-lib/baseCoin/errors.js +8 -2
  15. package/dist/src/account-lib/baseCoin/iface.d.ts +19 -35
  16. package/dist/src/account-lib/baseCoin/iface.d.ts.map +1 -1
  17. package/dist/src/account-lib/baseCoin/iface.js +26 -18
  18. package/dist/src/account-lib/baseCoin/index.d.ts +1 -1
  19. package/dist/src/account-lib/baseCoin/index.d.ts.map +1 -1
  20. package/dist/src/account-lib/baseCoin/index.js +8 -5
  21. package/dist/src/account-lib/baseCoin/messages/baseMessage.d.ts +88 -0
  22. package/dist/src/account-lib/baseCoin/messages/baseMessage.d.ts.map +1 -0
  23. package/dist/src/account-lib/baseCoin/messages/baseMessage.js +154 -0
  24. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilder.d.ts +67 -0
  25. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilder.d.ts.map +1 -0
  26. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilder.js +144 -0
  27. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts +33 -0
  28. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts.map +1 -0
  29. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilderFactory.js +45 -0
  30. package/dist/src/account-lib/baseCoin/messages/iface.d.ts +164 -0
  31. package/dist/src/account-lib/baseCoin/messages/iface.d.ts.map +1 -0
  32. package/dist/src/account-lib/baseCoin/messages/iface.js +3 -0
  33. package/dist/src/account-lib/baseCoin/messages/index.d.ts +6 -0
  34. package/dist/src/account-lib/baseCoin/messages/index.d.ts.map +1 -0
  35. package/dist/src/account-lib/baseCoin/messages/index.js +22 -0
  36. package/dist/src/account-lib/baseCoin/messages/simple/index.d.ts +3 -0
  37. package/dist/src/account-lib/baseCoin/messages/simple/index.d.ts.map +1 -0
  38. package/dist/src/account-lib/baseCoin/messages/simple/index.js +19 -0
  39. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessage.d.ts +13 -0
  40. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessage.d.ts.map +1 -0
  41. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessage.js +28 -0
  42. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessageBuilder.d.ts +21 -0
  43. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessageBuilder.d.ts.map +1 -0
  44. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessageBuilder.js +28 -0
  45. package/dist/src/account-lib/baseCoin/secp256k1ExtendedKeyPair.d.ts +1 -2
  46. package/dist/src/account-lib/baseCoin/secp256k1ExtendedKeyPair.d.ts.map +1 -1
  47. package/dist/src/account-lib/baseCoin/secp256k1ExtendedKeyPair.js +38 -26
  48. package/dist/src/account-lib/index.d.ts +0 -1
  49. package/dist/src/account-lib/index.d.ts.map +1 -1
  50. package/dist/src/account-lib/index.js +23 -10
  51. package/dist/src/account-lib/mpc/index.d.ts +1 -1
  52. package/dist/src/account-lib/mpc/index.d.ts.map +1 -1
  53. package/dist/src/account-lib/mpc/index.js +6 -2
  54. package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.d.ts +2 -3
  55. package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.d.ts.map +1 -1
  56. package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.js +376 -354
  57. package/dist/src/account-lib/mpc/tss/ecdsa/index.js +23 -9
  58. package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.d.ts +2 -2
  59. package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.d.ts.map +1 -1
  60. package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.js +3 -3
  61. package/dist/src/account-lib/mpc/tss/ecdsa/types.d.ts +46 -53
  62. package/dist/src/account-lib/mpc/tss/ecdsa/types.d.ts.map +1 -1
  63. package/dist/src/account-lib/mpc/tss/ecdsa/types.js +1 -1
  64. package/dist/src/account-lib/mpc/tss/eddsa/eddsa.d.ts +0 -1
  65. package/dist/src/account-lib/mpc/tss/eddsa/eddsa.d.ts.map +1 -1
  66. package/dist/src/account-lib/mpc/tss/eddsa/eddsa.js +66 -69
  67. package/dist/src/account-lib/mpc/tss/eddsa/index.js +23 -9
  68. package/dist/src/account-lib/mpc/tss/eddsa/types.d.ts +1 -1
  69. package/dist/src/account-lib/mpc/tss/eddsa/types.d.ts.map +1 -1
  70. package/dist/src/account-lib/mpc/tss/eddsa/types.js +1 -1
  71. package/dist/src/account-lib/mpc/tss/index.js +23 -9
  72. package/dist/src/account-lib/mpc/util.d.ts +7 -1
  73. package/dist/src/account-lib/mpc/util.d.ts.map +1 -1
  74. package/dist/src/account-lib/mpc/util.js +24 -1
  75. package/dist/src/account-lib/staking/index.js +6 -2
  76. package/dist/src/account-lib/staking/utils.js +3 -3
  77. package/dist/src/account-lib/util/crypto.d.ts +8 -2
  78. package/dist/src/account-lib/util/crypto.d.ts.map +1 -1
  79. package/dist/src/account-lib/util/crypto.js +69 -38
  80. package/dist/src/api/bip32path.js +2 -3
  81. package/dist/src/api/index.js +6 -2
  82. package/dist/src/api/types.d.ts +37 -0
  83. package/dist/src/api/types.d.ts.map +1 -1
  84. package/dist/src/api/types.js +8 -1
  85. package/dist/src/bitgo/address-book/address-book.d.ts.map +1 -1
  86. package/dist/src/bitgo/address-book/address-book.js +20 -12
  87. package/dist/src/bitgo/address-book/index.js +6 -2
  88. package/dist/src/bitgo/address-book/types.d.ts +36 -36
  89. package/dist/src/bitgo/address-book/types.d.ts.map +1 -1
  90. package/dist/src/bitgo/baseCoin/baseCoin.d.ts +123 -13
  91. package/dist/src/bitgo/baseCoin/baseCoin.d.ts.map +1 -1
  92. package/dist/src/bitgo/baseCoin/baseCoin.js +200 -16
  93. package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts +301 -31
  94. package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts.map +1 -1
  95. package/dist/src/bitgo/baseCoin/iBaseCoin.js +14 -3
  96. package/dist/src/bitgo/baseCoin/index.js +6 -2
  97. package/dist/src/bitgo/bip32util.d.ts +3 -16
  98. package/dist/src/bitgo/bip32util.d.ts.map +1 -1
  99. package/dist/src/bitgo/bip32util.js +4 -56
  100. package/dist/src/bitgo/bitcoin.d.ts +0 -1
  101. package/dist/src/bitgo/bitcoin.d.ts.map +1 -1
  102. package/dist/src/bitgo/bitcoin.js +26 -13
  103. package/dist/src/bitgo/bitgoBase.d.ts +17 -4
  104. package/dist/src/bitgo/bitgoBase.d.ts.map +1 -1
  105. package/dist/src/bitgo/bitgoBase.js +1 -1
  106. package/dist/src/bitgo/coinFactory.d.ts +24 -3
  107. package/dist/src/bitgo/coinFactory.d.ts.map +1 -1
  108. package/dist/src/bitgo/coinFactory.js +35 -3
  109. package/dist/src/bitgo/config.d.ts +3 -101
  110. package/dist/src/bitgo/config.d.ts.map +1 -1
  111. package/dist/src/bitgo/config.js +26 -15
  112. package/dist/src/bitgo/defi/defiVault.d.ts +171 -0
  113. package/dist/src/bitgo/defi/defiVault.d.ts.map +1 -0
  114. package/dist/src/bitgo/defi/defiVault.js +445 -0
  115. package/dist/src/bitgo/defi/iDefiVault.d.ts +101 -0
  116. package/dist/src/bitgo/defi/iDefiVault.d.ts.map +1 -0
  117. package/dist/src/bitgo/defi/iDefiVault.js +6 -0
  118. package/dist/src/bitgo/defi/index.d.ts +3 -0
  119. package/dist/src/bitgo/defi/index.d.ts.map +1 -0
  120. package/dist/src/bitgo/defi/index.js +22 -0
  121. package/dist/src/bitgo/ecdh.d.ts +0 -1
  122. package/dist/src/bitgo/ecdh.d.ts.map +1 -1
  123. package/dist/src/bitgo/ecdh.js +26 -13
  124. package/dist/src/bitgo/enterprise/enterprise.d.ts +9 -4
  125. package/dist/src/bitgo/enterprise/enterprise.d.ts.map +1 -1
  126. package/dist/src/bitgo/enterprise/enterprise.js +47 -21
  127. package/dist/src/bitgo/enterprise/enterprises.js +27 -13
  128. package/dist/src/bitgo/enterprise/iEnterprise.d.ts +5 -3
  129. package/dist/src/bitgo/enterprise/iEnterprise.d.ts.map +1 -1
  130. package/dist/src/bitgo/enterprise/iEnterprise.js +1 -1
  131. package/dist/src/bitgo/enterprise/index.js +6 -2
  132. package/dist/src/bitgo/environments.d.ts +73 -3
  133. package/dist/src/bitgo/environments.d.ts.map +1 -1
  134. package/dist/src/bitgo/environments.js +415 -34
  135. package/dist/src/bitgo/errors.d.ts +183 -1
  136. package/dist/src/bitgo/errors.d.ts.map +1 -1
  137. package/dist/src/bitgo/errors.js +178 -3
  138. package/dist/src/bitgo/evm/evmUtils.d.ts +26 -0
  139. package/dist/src/bitgo/evm/evmUtils.d.ts.map +1 -0
  140. package/dist/src/bitgo/evm/evmUtils.js +50 -0
  141. package/dist/src/bitgo/index.d.ts +6 -1
  142. package/dist/src/bitgo/index.d.ts.map +1 -1
  143. package/dist/src/bitgo/index.js +32 -11
  144. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.d.ts +3 -3
  145. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.d.ts.map +1 -1
  146. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.js +1 -1
  147. package/dist/src/bitgo/inscriptionBuilder/index.js +6 -2
  148. package/dist/src/bitgo/internal/index.js +6 -2
  149. package/dist/src/bitgo/internal/internal.js +5 -6
  150. package/dist/src/bitgo/internal/keycard.d.ts +13 -8
  151. package/dist/src/bitgo/internal/keycard.d.ts.map +1 -1
  152. package/dist/src/bitgo/internal/keycard.js +63 -48
  153. package/dist/src/bitgo/keychain/decryptKeychain.d.ts +14 -0
  154. package/dist/src/bitgo/keychain/decryptKeychain.d.ts.map +1 -0
  155. package/dist/src/bitgo/keychain/decryptKeychain.js +36 -0
  156. package/dist/src/bitgo/keychain/iKeychains.d.ts +160 -11
  157. package/dist/src/bitgo/keychain/iKeychains.d.ts.map +1 -1
  158. package/dist/src/bitgo/keychain/iKeychains.js +2 -2
  159. package/dist/src/bitgo/keychain/index.d.ts +1 -0
  160. package/dist/src/bitgo/keychain/index.d.ts.map +1 -1
  161. package/dist/src/bitgo/keychain/index.js +7 -2
  162. package/dist/src/bitgo/keychain/keychains.d.ts +106 -13
  163. package/dist/src/bitgo/keychain/keychains.d.ts.map +1 -1
  164. package/dist/src/bitgo/keychain/keychains.js +393 -72
  165. package/dist/src/bitgo/keychain/ovcJsonCodec.d.ts +3 -3
  166. package/dist/src/bitgo/keychain/ovcJsonCodec.d.ts.map +1 -1
  167. package/dist/src/bitgo/keychain/ovcJsonCodec.js +23 -9
  168. package/dist/src/bitgo/legacyBitcoin.d.ts +0 -1
  169. package/dist/src/bitgo/legacyBitcoin.d.ts.map +1 -1
  170. package/dist/src/bitgo/legacyBitcoin.js +27 -13
  171. package/dist/src/bitgo/lightning/lightningWalletUtil.d.ts +7 -0
  172. package/dist/src/bitgo/lightning/lightningWalletUtil.d.ts.map +1 -0
  173. package/dist/src/bitgo/lightning/lightningWalletUtil.js +25 -0
  174. package/dist/src/bitgo/market/iMarkets.d.ts +2 -2
  175. package/dist/src/bitgo/market/iMarkets.d.ts.map +1 -1
  176. package/dist/src/bitgo/market/index.js +6 -2
  177. package/dist/src/bitgo/market/markets.js +23 -9
  178. package/dist/src/bitgo/pendingApproval/iPendingApproval.d.ts +5 -1
  179. package/dist/src/bitgo/pendingApproval/iPendingApproval.d.ts.map +1 -1
  180. package/dist/src/bitgo/pendingApproval/iPendingApproval.js +4 -4
  181. package/dist/src/bitgo/pendingApproval/index.js +6 -2
  182. package/dist/src/bitgo/pendingApproval/pendingApproval.d.ts +20 -8
  183. package/dist/src/bitgo/pendingApproval/pendingApproval.d.ts.map +1 -1
  184. package/dist/src/bitgo/pendingApproval/pendingApproval.js +246 -111
  185. package/dist/src/bitgo/pendingApproval/pendingApprovals.js +23 -9
  186. package/dist/src/bitgo/proofs/WalletProofs.d.ts +19 -0
  187. package/dist/src/bitgo/proofs/WalletProofs.d.ts.map +1 -0
  188. package/dist/src/bitgo/proofs/WalletProofs.js +37 -0
  189. package/dist/src/bitgo/proofs/index.d.ts +2 -0
  190. package/dist/src/bitgo/proofs/index.d.ts.map +1 -0
  191. package/dist/src/bitgo/proofs/index.js +6 -0
  192. package/dist/src/bitgo/proofs/types.d.ts +80 -0
  193. package/dist/src/bitgo/proofs/types.d.ts.map +1 -0
  194. package/dist/src/bitgo/proofs/types.js +80 -0
  195. package/dist/src/bitgo/recovery/index.js +6 -2
  196. package/dist/src/bitgo/recovery/initiate.d.ts +13 -3
  197. package/dist/src/bitgo/recovery/initiate.d.ts.map +1 -1
  198. package/dist/src/bitgo/recovery/initiate.js +49 -41
  199. package/dist/src/bitgo/safe/derivableEd25519Pub.d.ts +13 -0
  200. package/dist/src/bitgo/safe/derivableEd25519Pub.d.ts.map +1 -0
  201. package/dist/src/bitgo/safe/derivableEd25519Pub.js +35 -0
  202. package/dist/src/bitgo/safe/iSafe.d.ts +124 -0
  203. package/dist/src/bitgo/safe/iSafe.d.ts.map +1 -0
  204. package/dist/src/bitgo/safe/iSafe.js +3 -0
  205. package/dist/src/bitgo/safe/iSafes.d.ts +94 -0
  206. package/dist/src/bitgo/safe/iSafes.d.ts.map +1 -0
  207. package/dist/src/bitgo/safe/iSafes.js +3 -0
  208. package/dist/src/bitgo/safe/index.d.ts +8 -0
  209. package/dist/src/bitgo/safe/index.d.ts.map +1 -0
  210. package/dist/src/bitgo/safe/index.js +24 -0
  211. package/dist/src/bitgo/safe/recovery.d.ts +82 -0
  212. package/dist/src/bitgo/safe/recovery.d.ts.map +1 -0
  213. package/dist/src/bitgo/safe/recovery.js +133 -0
  214. package/dist/src/bitgo/safe/rootCoin.d.ts +15 -0
  215. package/dist/src/bitgo/safe/rootCoin.d.ts.map +1 -0
  216. package/dist/src/bitgo/safe/rootCoin.js +47 -0
  217. package/dist/src/bitgo/safe/safe.d.ts +88 -0
  218. package/dist/src/bitgo/safe/safe.d.ts.map +1 -0
  219. package/dist/src/bitgo/safe/safe.js +409 -0
  220. package/dist/src/bitgo/safe/safes.d.ts +102 -0
  221. package/dist/src/bitgo/safe/safes.d.ts.map +1 -0
  222. package/dist/src/bitgo/safe/safes.js +281 -0
  223. package/dist/src/bitgo/staking/goStakingInterfaces.d.ts +136 -0
  224. package/dist/src/bitgo/staking/goStakingInterfaces.d.ts.map +1 -0
  225. package/dist/src/bitgo/staking/goStakingInterfaces.js +3 -0
  226. package/dist/src/bitgo/staking/goStakingWallet.d.ts +62 -0
  227. package/dist/src/bitgo/staking/goStakingWallet.d.ts.map +1 -0
  228. package/dist/src/bitgo/staking/goStakingWallet.js +141 -0
  229. package/dist/src/bitgo/staking/iGoStakingWallet.d.ts +17 -0
  230. package/dist/src/bitgo/staking/iGoStakingWallet.d.ts.map +1 -0
  231. package/dist/src/bitgo/staking/iGoStakingWallet.js +3 -0
  232. package/dist/src/bitgo/staking/iStakingWallet.d.ts +165 -8
  233. package/dist/src/bitgo/staking/iStakingWallet.d.ts.map +1 -1
  234. package/dist/src/bitgo/staking/iStakingWallet.js +2 -2
  235. package/dist/src/bitgo/staking/index.d.ts +3 -0
  236. package/dist/src/bitgo/staking/index.d.ts.map +1 -1
  237. package/dist/src/bitgo/staking/index.js +9 -2
  238. package/dist/src/bitgo/staking/stakingWallet.d.ts +21 -8
  239. package/dist/src/bitgo/staking/stakingWallet.d.ts.map +1 -1
  240. package/dist/src/bitgo/staking/stakingWallet.js +153 -7
  241. package/dist/src/bitgo/trading/iTradingAccount.d.ts +13 -1
  242. package/dist/src/bitgo/trading/iTradingAccount.d.ts.map +1 -1
  243. package/dist/src/bitgo/trading/iTradingAccount.js +1 -1
  244. package/dist/src/bitgo/trading/index.d.ts +1 -0
  245. package/dist/src/bitgo/trading/index.d.ts.map +1 -1
  246. package/dist/src/bitgo/trading/index.js +7 -2
  247. package/dist/src/bitgo/trading/network/decrypt-aes-gcm.d.ts +8 -0
  248. package/dist/src/bitgo/trading/network/decrypt-aes-gcm.d.ts.map +1 -0
  249. package/dist/src/bitgo/trading/network/decrypt-aes-gcm.js +31 -0
  250. package/dist/src/bitgo/trading/network/decrypt-rsa.d.ts +8 -0
  251. package/dist/src/bitgo/trading/network/decrypt-rsa.d.ts.map +1 -0
  252. package/dist/src/bitgo/trading/network/decrypt-rsa.js +23 -0
  253. package/dist/src/bitgo/trading/network/decrypt.d.ts +14 -0
  254. package/dist/src/bitgo/trading/network/decrypt.d.ts.map +1 -0
  255. package/dist/src/bitgo/trading/network/decrypt.js +23 -0
  256. package/dist/src/bitgo/trading/network/encrypt-aes-gcm.d.ts +8 -0
  257. package/dist/src/bitgo/trading/network/encrypt-aes-gcm.d.ts.map +1 -0
  258. package/dist/src/bitgo/trading/network/encrypt-aes-gcm.js +25 -0
  259. package/dist/src/bitgo/trading/network/encrypt-rsa-browser.d.ts +8 -0
  260. package/dist/src/bitgo/trading/network/encrypt-rsa-browser.d.ts.map +1 -0
  261. package/dist/src/bitgo/trading/network/encrypt-rsa-browser.js +65 -0
  262. package/dist/src/bitgo/trading/network/encrypt-rsa.d.ts +8 -0
  263. package/dist/src/bitgo/trading/network/encrypt-rsa.d.ts.map +1 -0
  264. package/dist/src/bitgo/trading/network/encrypt-rsa.js +23 -0
  265. package/dist/src/bitgo/trading/network/encrypt.d.ts +37 -0
  266. package/dist/src/bitgo/trading/network/encrypt.d.ts.map +1 -0
  267. package/dist/src/bitgo/trading/network/encrypt.js +58 -0
  268. package/dist/src/bitgo/trading/network/index.d.ts +2 -0
  269. package/dist/src/bitgo/trading/network/index.d.ts.map +1 -1
  270. package/dist/src/bitgo/trading/network/index.js +8 -2
  271. package/dist/src/bitgo/trading/network/network.d.ts +4 -3
  272. package/dist/src/bitgo/trading/network/network.d.ts.map +1 -1
  273. package/dist/src/bitgo/trading/network/network.js +24 -27
  274. package/dist/src/bitgo/trading/network/types.d.ts +79 -46
  275. package/dist/src/bitgo/trading/network/types.d.ts.map +1 -1
  276. package/dist/src/bitgo/trading/network/types.js +1 -1
  277. package/dist/src/bitgo/trading/network/utils.d.ts +20 -0
  278. package/dist/src/bitgo/trading/network/utils.d.ts.map +1 -0
  279. package/dist/src/bitgo/trading/network/utils.js +54 -0
  280. package/dist/src/bitgo/trading/tradingAccount.d.ts +15 -1
  281. package/dist/src/bitgo/trading/tradingAccount.d.ts.map +1 -1
  282. package/dist/src/bitgo/trading/tradingAccount.js +55 -7
  283. package/dist/src/bitgo/tss/bitgoPubKeys.d.ts +49 -0
  284. package/dist/src/bitgo/tss/bitgoPubKeys.d.ts.map +1 -0
  285. package/dist/src/bitgo/tss/bitgoPubKeys.js +92 -0
  286. package/dist/src/bitgo/tss/common.d.ts +41 -6
  287. package/dist/src/bitgo/tss/common.d.ts.map +1 -1
  288. package/dist/src/bitgo/tss/common.js +127 -17
  289. package/dist/src/bitgo/tss/ecdsa/ecdsa.d.ts +6 -4
  290. package/dist/src/bitgo/tss/ecdsa/ecdsa.d.ts.map +1 -1
  291. package/dist/src/bitgo/tss/ecdsa/ecdsa.js +78 -66
  292. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.d.ts +15 -0
  293. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
  294. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.js +167 -0
  295. package/dist/src/bitgo/tss/ecdsa/index.d.ts +1 -0
  296. package/dist/src/bitgo/tss/ecdsa/index.d.ts.map +1 -1
  297. package/dist/src/bitgo/tss/ecdsa/index.js +25 -10
  298. package/dist/src/bitgo/tss/ecdsa/types.d.ts +27 -27
  299. package/dist/src/bitgo/tss/ecdsa/types.d.ts.map +1 -1
  300. package/dist/src/bitgo/tss/ecdsa/types.js +3 -3
  301. package/dist/src/bitgo/tss/eddsa/eddsa.d.ts +15 -6
  302. package/dist/src/bitgo/tss/eddsa/eddsa.d.ts.map +1 -1
  303. package/dist/src/bitgo/tss/eddsa/eddsa.js +47 -40
  304. package/dist/src/bitgo/tss/eddsa/eddsaMPCv2.d.ts +42 -0
  305. package/dist/src/bitgo/tss/eddsa/eddsaMPCv2.d.ts.map +1 -0
  306. package/dist/src/bitgo/tss/eddsa/eddsaMPCv2.js +104 -0
  307. package/dist/src/bitgo/tss/eddsa/index.js +23 -9
  308. package/dist/src/bitgo/tss/eddsa/types.d.ts +4 -4
  309. package/dist/src/bitgo/tss/eddsa/types.d.ts.map +1 -1
  310. package/dist/src/bitgo/tss/index.d.ts +3 -2
  311. package/dist/src/bitgo/tss/index.d.ts.map +1 -1
  312. package/dist/src/bitgo/tss/index.js +26 -10
  313. package/dist/src/bitgo/tss/redpallas/redpallasMPCv2.d.ts +79 -0
  314. package/dist/src/bitgo/tss/redpallas/redpallasMPCv2.d.ts.map +1 -0
  315. package/dist/src/bitgo/tss/redpallas/redpallasMPCv2.js +179 -0
  316. package/dist/src/bitgo/tss/types.d.ts +3 -3
  317. package/dist/src/bitgo/tss/types.d.ts.map +1 -1
  318. package/dist/src/bitgo/tss/types.js +2 -2
  319. package/dist/src/bitgo/types.d.ts +3 -3
  320. package/dist/src/bitgo/types.d.ts.map +1 -1
  321. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.d.ts +10 -0
  322. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.d.ts.map +1 -1
  323. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.js +76 -14
  324. package/dist/src/bitgo/utils/codecProps.js +24 -11
  325. package/dist/src/bitgo/utils/codecs.d.ts +11 -0
  326. package/dist/src/bitgo/utils/codecs.d.ts.map +1 -0
  327. package/dist/src/bitgo/utils/codecs.js +59 -0
  328. package/dist/src/bitgo/utils/decode.d.ts.map +1 -1
  329. package/dist/src/bitgo/utils/decode.js +30 -16
  330. package/dist/src/bitgo/utils/index.d.ts +5 -2
  331. package/dist/src/bitgo/utils/index.d.ts.map +1 -1
  332. package/dist/src/bitgo/utils/index.js +28 -11
  333. package/dist/src/bitgo/utils/messageTypes.d.ts +46 -0
  334. package/dist/src/bitgo/utils/messageTypes.d.ts.map +1 -0
  335. package/dist/src/bitgo/utils/messageTypes.js +23 -0
  336. package/dist/src/bitgo/utils/mpcUtils.d.ts +4 -4
  337. package/dist/src/bitgo/utils/mpcUtils.d.ts.map +1 -1
  338. package/dist/src/bitgo/utils/mpcUtils.js +208 -14
  339. package/dist/src/bitgo/utils/notEmpty.d.ts +2 -0
  340. package/dist/src/bitgo/utils/notEmpty.d.ts.map +1 -0
  341. package/dist/src/bitgo/utils/notEmpty.js +7 -0
  342. package/dist/src/bitgo/utils/opengpgUtils.d.ts +11 -7
  343. package/dist/src/bitgo/utils/opengpgUtils.d.ts.map +1 -1
  344. package/dist/src/bitgo/utils/opengpgUtils.js +79 -62
  345. package/dist/src/bitgo/utils/postWithCodec.d.ts.map +1 -1
  346. package/dist/src/bitgo/utils/postWithCodec.js +4 -38
  347. package/dist/src/bitgo/utils/promise-utils.d.ts +1 -1
  348. package/dist/src/bitgo/utils/promise-utils.d.ts.map +1 -1
  349. package/dist/src/bitgo/utils/promise-utils.js +2 -3
  350. package/dist/src/bitgo/utils/siws.d.ts +17 -0
  351. package/dist/src/bitgo/utils/siws.d.ts.map +1 -0
  352. package/dist/src/bitgo/utils/siws.js +171 -0
  353. package/dist/src/bitgo/utils/transactionUtils.d.ts +9 -0
  354. package/dist/src/bitgo/utils/transactionUtils.d.ts.map +1 -0
  355. package/dist/src/bitgo/utils/transactionUtils.js +29 -0
  356. package/dist/src/bitgo/utils/triple.d.ts +1 -1
  357. package/dist/src/bitgo/utils/triple.d.ts.map +1 -1
  358. package/dist/src/bitgo/utils/triple.js +2 -3
  359. package/dist/src/bitgo/utils/tss/addressVerification.d.ts +62 -0
  360. package/dist/src/bitgo/utils/tss/addressVerification.d.ts.map +1 -0
  361. package/dist/src/bitgo/utils/tss/addressVerification.js +93 -0
  362. package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts +99 -17
  363. package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts.map +1 -1
  364. package/dist/src/bitgo/utils/tss/baseTSSUtils.js +321 -45
  365. package/dist/src/bitgo/utils/tss/baseTypes.d.ts +456 -55
  366. package/dist/src/bitgo/utils/tss/baseTypes.d.ts.map +1 -1
  367. package/dist/src/bitgo/utils/tss/baseTypes.js +47 -22
  368. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.d.ts +23 -0
  369. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.d.ts.map +1 -0
  370. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.js +157 -0
  371. package/dist/src/bitgo/utils/tss/ecdsa/base.d.ts +28 -0
  372. package/dist/src/bitgo/utils/tss/ecdsa/base.d.ts.map +1 -0
  373. package/dist/src/bitgo/utils/tss/ecdsa/base.js +53 -0
  374. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.d.ts +25 -51
  375. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.d.ts.map +1 -1
  376. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.js +173 -246
  377. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts +240 -0
  378. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
  379. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +1076 -0
  380. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.d.ts +16 -0
  381. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.d.ts.map +1 -0
  382. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.js +37 -0
  383. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaVrfMPCv2.d.ts +69 -0
  384. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaVrfMPCv2.d.ts.map +1 -0
  385. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaVrfMPCv2.js +442 -0
  386. package/dist/src/bitgo/utils/tss/ecdsa/index.d.ts +5 -0
  387. package/dist/src/bitgo/utils/tss/ecdsa/index.d.ts.map +1 -1
  388. package/dist/src/bitgo/utils/tss/ecdsa/index.js +11 -2
  389. package/dist/src/bitgo/utils/tss/ecdsa/types.d.ts +7 -10
  390. package/dist/src/bitgo/utils/tss/ecdsa/types.d.ts.map +1 -1
  391. package/dist/src/bitgo/utils/tss/ecdsa/types.js +1 -1
  392. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.d.ts +125 -0
  393. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.d.ts.map +1 -0
  394. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.js +55 -0
  395. package/dist/src/bitgo/utils/tss/eddsa/SMC/utils.d.ts +21 -0
  396. package/dist/src/bitgo/utils/tss/eddsa/SMC/utils.d.ts.map +1 -0
  397. package/dist/src/bitgo/utils/tss/eddsa/SMC/utils.js +119 -0
  398. package/dist/src/bitgo/utils/tss/eddsa/base.d.ts +18 -0
  399. package/dist/src/bitgo/utils/tss/eddsa/base.d.ts.map +1 -0
  400. package/dist/src/bitgo/utils/tss/eddsa/base.js +64 -0
  401. package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts +43 -11
  402. package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts.map +1 -1
  403. package/dist/src/bitgo/utils/tss/eddsa/eddsa.js +261 -96
  404. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts +233 -0
  405. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts.map +1 -0
  406. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.js +905 -0
  407. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.d.ts +11 -0
  408. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.d.ts.map +1 -0
  409. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.js +26 -0
  410. package/dist/src/bitgo/utils/tss/eddsa/eddsaVrfMPCv2.d.ts +44 -0
  411. package/dist/src/bitgo/utils/tss/eddsa/eddsaVrfMPCv2.d.ts.map +1 -0
  412. package/dist/src/bitgo/utils/tss/eddsa/eddsaVrfMPCv2.js +295 -0
  413. package/dist/src/bitgo/utils/tss/eddsa/index.d.ts +5 -0
  414. package/dist/src/bitgo/utils/tss/eddsa/index.d.ts.map +1 -1
  415. package/dist/src/bitgo/utils/tss/eddsa/index.js +30 -8
  416. package/dist/src/bitgo/utils/tss/eddsa/types.d.ts +15 -7
  417. package/dist/src/bitgo/utils/tss/eddsa/types.d.ts.map +1 -1
  418. package/dist/src/bitgo/utils/tss/eddsa/types.js +1 -1
  419. package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.d.ts +56 -0
  420. package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.d.ts.map +1 -0
  421. package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.js +55 -0
  422. package/dist/src/bitgo/utils/tss/index.d.ts +7 -0
  423. package/dist/src/bitgo/utils/tss/index.d.ts.map +1 -1
  424. package/dist/src/bitgo/utils/tss/index.js +31 -10
  425. package/dist/src/bitgo/utils/tss/keyShareEnvelope.d.ts +40 -0
  426. package/dist/src/bitgo/utils/tss/keyShareEnvelope.d.ts.map +1 -0
  427. package/dist/src/bitgo/utils/tss/keyShareEnvelope.js +103 -0
  428. package/dist/src/bitgo/utils/tss/keyVerification.d.ts +45 -0
  429. package/dist/src/bitgo/utils/tss/keyVerification.d.ts.map +1 -0
  430. package/dist/src/bitgo/utils/tss/keyVerification.js +192 -0
  431. package/dist/src/bitgo/utils/tss/preHashedSignable.d.ts +23 -0
  432. package/dist/src/bitgo/utils/tss/preHashedSignable.d.ts.map +1 -0
  433. package/dist/src/bitgo/utils/tss/preHashedSignable.js +26 -0
  434. package/dist/src/bitgo/utils/tss/recipientUtils.d.ts +42 -0
  435. package/dist/src/bitgo/utils/tss/recipientUtils.d.ts.map +1 -0
  436. package/dist/src/bitgo/utils/tss/recipientUtils.js +168 -0
  437. package/dist/src/bitgo/utils/tss/redpallas/SMC/utils.d.ts +29 -0
  438. package/dist/src/bitgo/utils/tss/redpallas/SMC/utils.d.ts.map +1 -0
  439. package/dist/src/bitgo/utils/tss/redpallas/SMC/utils.js +126 -0
  440. package/dist/src/bitgo/utils/tss/redpallas/index.d.ts +4 -0
  441. package/dist/src/bitgo/utils/tss/redpallas/index.d.ts.map +1 -0
  442. package/dist/src/bitgo/utils/tss/redpallas/index.js +20 -0
  443. package/dist/src/bitgo/utils/tss/redpallas/redpallasMPCv2.d.ts +27 -0
  444. package/dist/src/bitgo/utils/tss/redpallas/redpallasMPCv2.d.ts.map +1 -0
  445. package/dist/src/bitgo/utils/tss/redpallas/redpallasMPCv2.js +43 -0
  446. package/dist/src/bitgo/utils/tss/redpallas/redpallasMPCv2KeyGenSender.d.ts +45 -0
  447. package/dist/src/bitgo/utils/tss/redpallas/redpallasMPCv2KeyGenSender.d.ts.map +1 -0
  448. package/dist/src/bitgo/utils/tss/redpallas/redpallasMPCv2KeyGenSender.js +55 -0
  449. package/dist/src/bitgo/utils/tss/serializedTxHexVerify.d.ts +8 -0
  450. package/dist/src/bitgo/utils/tss/serializedTxHexVerify.d.ts.map +1 -0
  451. package/dist/src/bitgo/utils/tss/serializedTxHexVerify.js +13 -0
  452. package/dist/src/bitgo/utils/tss/signableConsistency.d.ts +12 -0
  453. package/dist/src/bitgo/utils/tss/signableConsistency.d.ts.map +1 -0
  454. package/dist/src/bitgo/utils/tss/signableConsistency.js +9 -0
  455. package/dist/src/bitgo/utils/txRequest.d.ts +10 -0
  456. package/dist/src/bitgo/utils/txRequest.d.ts.map +1 -0
  457. package/dist/src/bitgo/utils/txRequest.js +49 -0
  458. package/dist/src/bitgo/utils/util.js +24 -10
  459. package/dist/src/bitgo/utils/wallet.d.ts +7 -0
  460. package/dist/src/bitgo/utils/wallet.d.ts.map +1 -0
  461. package/dist/src/bitgo/utils/wallet.js +48 -0
  462. package/dist/src/bitgo/v1Wallets.d.ts +170 -0
  463. package/dist/src/bitgo/v1Wallets.d.ts.map +1 -0
  464. package/dist/src/bitgo/v1Wallets.js +3 -0
  465. package/dist/src/bitgo/wallet/BuildParams.d.ts +90 -1
  466. package/dist/src/bitgo/wallet/BuildParams.d.ts.map +1 -1
  467. package/dist/src/bitgo/wallet/BuildParams.js +92 -11
  468. package/dist/src/bitgo/wallet/iWallet.d.ts +623 -33
  469. package/dist/src/bitgo/wallet/iWallet.d.ts.map +1 -1
  470. package/dist/src/bitgo/wallet/iWallet.js +1 -1
  471. package/dist/src/bitgo/wallet/iWallets.d.ts +310 -16
  472. package/dist/src/bitgo/wallet/iWallets.d.ts.map +1 -1
  473. package/dist/src/bitgo/wallet/iWallets.js +84 -3
  474. package/dist/src/bitgo/wallet/index.d.ts +1 -0
  475. package/dist/src/bitgo/wallet/index.d.ts.map +1 -1
  476. package/dist/src/bitgo/wallet/index.js +7 -2
  477. package/dist/src/bitgo/wallet/safeKeychain.d.ts +75 -0
  478. package/dist/src/bitgo/wallet/safeKeychain.d.ts.map +1 -0
  479. package/dist/src/bitgo/wallet/safeKeychain.js +151 -0
  480. package/dist/src/bitgo/wallet/wallet.d.ts +379 -27
  481. package/dist/src/bitgo/wallet/wallet.d.ts.map +1 -1
  482. package/dist/src/bitgo/wallet/wallet.js +2323 -442
  483. package/dist/src/bitgo/wallet/wallets.d.ts +99 -4
  484. package/dist/src/bitgo/wallet/wallets.d.ts.map +1 -1
  485. package/dist/src/bitgo/wallet/wallets.js +1242 -156
  486. package/dist/src/bitgo/walletUtil/iMessageProvider.d.ts +12 -0
  487. package/dist/src/bitgo/walletUtil/iMessageProvider.d.ts.map +1 -0
  488. package/dist/src/bitgo/walletUtil/iMessageProvider.js +3 -0
  489. package/dist/src/bitgo/walletUtil/index.d.ts +3 -0
  490. package/dist/src/bitgo/walletUtil/index.d.ts.map +1 -0
  491. package/dist/src/bitgo/walletUtil/index.js +19 -0
  492. package/dist/src/bitgo/walletUtil/midnightMessageProvider.d.ts +22 -0
  493. package/dist/src/bitgo/walletUtil/midnightMessageProvider.d.ts.map +1 -0
  494. package/dist/src/bitgo/walletUtil/midnightMessageProvider.js +95 -0
  495. package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.d.ts +9 -0
  496. package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.d.ts.map +1 -0
  497. package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.js +72 -0
  498. package/dist/src/bitgo/walletUtil/utxoMessageProof.d.ts +15 -0
  499. package/dist/src/bitgo/walletUtil/utxoMessageProof.d.ts.map +1 -0
  500. package/dist/src/bitgo/walletUtil/utxoMessageProof.js +40 -0
  501. package/dist/src/bitgo/webauthn/base64url.d.ts +16 -0
  502. package/dist/src/bitgo/webauthn/base64url.d.ts.map +1 -0
  503. package/dist/src/bitgo/webauthn/base64url.js +27 -0
  504. package/dist/src/bitgo/webauthn/deriveEnterpriseSalt.d.ts +18 -0
  505. package/dist/src/bitgo/webauthn/deriveEnterpriseSalt.d.ts.map +1 -0
  506. package/dist/src/bitgo/webauthn/deriveEnterpriseSalt.js +26 -0
  507. package/dist/src/bitgo/webauthn/derivePassword.d.ts +11 -0
  508. package/dist/src/bitgo/webauthn/derivePassword.d.ts.map +1 -0
  509. package/dist/src/bitgo/webauthn/derivePassword.js +16 -0
  510. package/dist/src/bitgo/webauthn/index.d.ts +5 -0
  511. package/dist/src/bitgo/webauthn/index.d.ts.map +1 -0
  512. package/dist/src/bitgo/webauthn/index.js +21 -0
  513. package/dist/src/bitgo/webauthn/types.d.ts +18 -0
  514. package/dist/src/bitgo/webauthn/types.d.ts.map +1 -0
  515. package/dist/src/bitgo/webauthn/types.js +3 -0
  516. package/dist/src/bitgo/webhook/index.js +6 -2
  517. package/dist/src/bitgo/webhook/webhooks.js +23 -9
  518. package/dist/src/coins/fiat.d.ts +45 -0
  519. package/dist/src/coins/fiat.d.ts.map +1 -0
  520. package/dist/src/coins/fiat.js +94 -0
  521. package/dist/src/coins/index.d.ts +1 -6
  522. package/dist/src/coins/index.d.ts.map +1 -1
  523. package/dist/src/coins/index.js +7 -8
  524. package/dist/src/coins/ofc.d.ts +21 -2
  525. package/dist/src/coins/ofc.d.ts.map +1 -1
  526. package/dist/src/coins/ofc.js +29 -3
  527. package/dist/src/coins/ofcToken.d.ts +15 -4
  528. package/dist/src/coins/ofcToken.d.ts.map +1 -1
  529. package/dist/src/coins/ofcToken.js +43 -5
  530. package/dist/src/coins/susd.d.ts +3 -2
  531. package/dist/src/coins/susd.d.ts.map +1 -1
  532. package/dist/src/coins/susd.js +5 -1
  533. package/dist/src/common.js +27 -13
  534. package/dist/src/index.d.ts +9 -1
  535. package/dist/src/index.d.ts.map +1 -1
  536. package/dist/src/index.js +40 -11
  537. package/dist/src/lightning.d.ts +20 -0
  538. package/dist/src/lightning.d.ts.map +1 -0
  539. package/dist/src/lightning.js +13 -0
  540. package/dist/src/units.js +5 -6
  541. package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.d.ts +2 -0
  542. package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.d.ts.map +1 -0
  543. package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.js +207 -0
  544. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.d.ts +2 -0
  545. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.d.ts.map +1 -0
  546. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.js +174 -0
  547. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts +2 -0
  548. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts.map +1 -0
  549. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.js +108 -0
  550. package/dist/test/unit/account-lib/baseCoin/messages/fixtures.d.ts +46 -0
  551. package/dist/test/unit/account-lib/baseCoin/messages/fixtures.d.ts.map +1 -0
  552. package/dist/test/unit/account-lib/baseCoin/messages/fixtures.js +69 -0
  553. package/dist/test/unit/account-lib/mpc/tss/ecdsa/ecdsa.js +91 -29
  554. package/dist/test/unit/account-lib/mpc/util.d.ts +2 -0
  555. package/dist/test/unit/account-lib/mpc/util.d.ts.map +1 -0
  556. package/dist/test/unit/account-lib/mpc/util.js +53 -0
  557. package/dist/test/unit/bitgo/address-book/address-book.d.ts +2 -0
  558. package/dist/test/unit/bitgo/address-book/address-book.d.ts.map +1 -0
  559. package/dist/test/unit/bitgo/address-book/address-book.js +159 -0
  560. package/dist/test/unit/bitgo/defi/defiVault.d.ts +2 -0
  561. package/dist/test/unit/bitgo/defi/defiVault.d.ts.map +1 -0
  562. package/dist/test/unit/bitgo/defi/defiVault.js +863 -0
  563. package/dist/test/unit/bitgo/environment.d.ts +2 -0
  564. package/dist/test/unit/bitgo/environment.d.ts.map +1 -0
  565. package/dist/test/unit/bitgo/environment.js +38 -0
  566. package/dist/test/unit/bitgo/errors.d.ts +2 -0
  567. package/dist/test/unit/bitgo/errors.d.ts.map +1 -0
  568. package/dist/test/unit/bitgo/errors.js +262 -0
  569. package/dist/test/unit/bitgo/keychain/keychains.d.ts +2 -0
  570. package/dist/test/unit/bitgo/keychain/keychains.d.ts.map +1 -0
  571. package/dist/test/unit/bitgo/keychain/keychains.js +426 -0
  572. package/dist/test/unit/bitgo/recovery/initiate.d.ts +2 -0
  573. package/dist/test/unit/bitgo/recovery/initiate.d.ts.map +1 -0
  574. package/dist/test/unit/bitgo/recovery/initiate.js +159 -0
  575. package/dist/test/unit/bitgo/safe/derivableEd25519Pub.d.ts +2 -0
  576. package/dist/test/unit/bitgo/safe/derivableEd25519Pub.d.ts.map +1 -0
  577. package/dist/test/unit/bitgo/safe/derivableEd25519Pub.js +133 -0
  578. package/dist/test/unit/bitgo/safe/fixtures/derivableEd25519Pub.json +72 -0
  579. package/dist/test/unit/bitgo/safe/recovery.d.ts +2 -0
  580. package/dist/test/unit/bitgo/safe/recovery.d.ts.map +1 -0
  581. package/dist/test/unit/bitgo/safe/recovery.js +253 -0
  582. package/dist/test/unit/bitgo/safe/rootCoin.d.ts +2 -0
  583. package/dist/test/unit/bitgo/safe/rootCoin.d.ts.map +1 -0
  584. package/dist/test/unit/bitgo/safe/rootCoin.js +13 -0
  585. package/dist/test/unit/bitgo/safe/safe.d.ts +2 -0
  586. package/dist/test/unit/bitgo/safe/safe.d.ts.map +1 -0
  587. package/dist/test/unit/bitgo/safe/safe.js +585 -0
  588. package/dist/test/unit/bitgo/safe/safeDerivation.d.ts +2 -0
  589. package/dist/test/unit/bitgo/safe/safeDerivation.d.ts.map +1 -0
  590. package/dist/test/unit/bitgo/safe/safeDerivation.js +75 -0
  591. package/dist/test/unit/bitgo/safe/safes.d.ts +2 -0
  592. package/dist/test/unit/bitgo/safe/safes.d.ts.map +1 -0
  593. package/dist/test/unit/bitgo/safe/safes.js +376 -0
  594. package/dist/test/unit/bitgo/trading/network/encrypt.d.ts +2 -0
  595. package/dist/test/unit/bitgo/trading/network/encrypt.d.ts.map +1 -0
  596. package/dist/test/unit/bitgo/trading/network/encrypt.js +71 -0
  597. package/dist/test/unit/bitgo/trading/network/network.test.d.ts +2 -0
  598. package/dist/test/unit/bitgo/trading/network/network.test.d.ts.map +1 -0
  599. package/dist/test/unit/bitgo/trading/network/network.test.js +136 -0
  600. package/dist/test/unit/bitgo/trading/tradingAccount.d.ts +2 -0
  601. package/dist/test/unit/bitgo/trading/tradingAccount.d.ts.map +1 -0
  602. package/dist/test/unit/bitgo/trading/tradingAccount.js +192 -0
  603. package/dist/test/unit/bitgo/tss/bitgoPubKeys.d.ts +2 -0
  604. package/dist/test/unit/bitgo/tss/bitgoPubKeys.d.ts.map +1 -0
  605. package/dist/test/unit/bitgo/tss/bitgoPubKeys.js +66 -0
  606. package/dist/test/unit/bitgo/tss/common.d.ts +2 -0
  607. package/dist/test/unit/bitgo/tss/common.d.ts.map +1 -0
  608. package/dist/test/unit/bitgo/tss/common.js +77 -0
  609. package/dist/test/unit/bitgo/tss/redpallas/redpallasMPCv2.d.ts +2 -0
  610. package/dist/test/unit/bitgo/tss/redpallas/redpallasMPCv2.d.ts.map +1 -0
  611. package/dist/test/unit/bitgo/tss/redpallas/redpallasMPCv2.js +249 -0
  612. package/dist/test/unit/bitgo/utils/abstractUtxoCoinUtil.js +45 -4
  613. package/dist/test/unit/bitgo/utils/messageTypes.d.ts +2 -0
  614. package/dist/test/unit/bitgo/utils/messageTypes.d.ts.map +1 -0
  615. package/dist/test/unit/bitgo/utils/messageTypes.js +64 -0
  616. package/dist/test/unit/bitgo/utils/mpcUtils.unwrap.d.ts +2 -0
  617. package/dist/test/unit/bitgo/utils/mpcUtils.unwrap.d.ts.map +1 -0
  618. package/dist/test/unit/bitgo/utils/mpcUtils.unwrap.js +109 -0
  619. package/dist/test/unit/bitgo/utils/mpcUtils.wrapApprove.d.ts +2 -0
  620. package/dist/test/unit/bitgo/utils/mpcUtils.wrapApprove.d.ts.map +1 -0
  621. package/dist/test/unit/bitgo/utils/mpcUtils.wrapApprove.js +106 -0
  622. package/dist/test/unit/bitgo/utils/notEmpty.d.ts +2 -0
  623. package/dist/test/unit/bitgo/utils/notEmpty.d.ts.map +1 -0
  624. package/dist/test/unit/bitgo/utils/notEmpty.js +15 -0
  625. package/dist/test/unit/bitgo/utils/postWithCodec.js +32 -38
  626. package/dist/test/unit/bitgo/utils/siws.d.ts +2 -0
  627. package/dist/test/unit/bitgo/utils/siws.d.ts.map +1 -0
  628. package/dist/test/unit/bitgo/utils/siws.js +206 -0
  629. package/dist/test/unit/bitgo/utils/tss/addressVerification.d.ts +2 -0
  630. package/dist/test/unit/bitgo/utils/tss/addressVerification.d.ts.map +1 -0
  631. package/dist/test/unit/bitgo/utils/tss/addressVerification.js +251 -0
  632. package/dist/test/unit/bitgo/utils/tss/baseTSSUtils.d.ts +2 -0
  633. package/dist/test/unit/bitgo/utils/tss/baseTSSUtils.d.ts.map +1 -0
  634. package/dist/test/unit/bitgo/utils/tss/baseTSSUtils.js +348 -0
  635. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaEncryptionVersion.d.ts +2 -0
  636. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaEncryptionVersion.d.ts.map +1 -0
  637. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaEncryptionVersion.js +94 -0
  638. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts +2 -0
  639. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
  640. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +1068 -0
  641. package/dist/test/unit/bitgo/utils/tss/ecdsa/gpgKeys.d.ts +5 -0
  642. package/dist/test/unit/bitgo/utils/tss/ecdsa/gpgKeys.d.ts.map +1 -0
  643. package/dist/test/unit/bitgo/utils/tss/ecdsa/gpgKeys.js +36 -0
  644. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaExternalSigner.d.ts +2 -0
  645. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaExternalSigner.d.ts.map +1 -0
  646. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaExternalSigner.js +158 -0
  647. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts +2 -0
  648. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts.map +1 -0
  649. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaMPCv2.js +1993 -0
  650. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaVrfMPCv2.d.ts +2 -0
  651. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaVrfMPCv2.d.ts.map +1 -0
  652. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaVrfMPCv2.js +380 -0
  653. package/dist/test/unit/bitgo/utils/tss/eddsa/smcUtil.d.ts +2 -0
  654. package/dist/test/unit/bitgo/utils/tss/eddsa/smcUtil.d.ts.map +1 -0
  655. package/dist/test/unit/bitgo/utils/tss/eddsa/smcUtil.js +376 -0
  656. package/dist/test/unit/bitgo/utils/tss/keyShareEnvelope.d.ts +2 -0
  657. package/dist/test/unit/bitgo/utils/tss/keyShareEnvelope.d.ts.map +1 -0
  658. package/dist/test/unit/bitgo/utils/tss/keyShareEnvelope.js +83 -0
  659. package/dist/test/unit/bitgo/utils/tss/keyVerification.d.ts +2 -0
  660. package/dist/test/unit/bitgo/utils/tss/keyVerification.d.ts.map +1 -0
  661. package/dist/test/unit/bitgo/utils/tss/keyVerification.js +229 -0
  662. package/dist/test/unit/bitgo/utils/tss/preHashedSignable.d.ts +2 -0
  663. package/dist/test/unit/bitgo/utils/tss/preHashedSignable.d.ts.map +1 -0
  664. package/dist/test/unit/bitgo/utils/tss/preHashedSignable.js +55 -0
  665. package/dist/test/unit/bitgo/utils/tss/recipientUtils.d.ts +2 -0
  666. package/dist/test/unit/bitgo/utils/tss/recipientUtils.d.ts.map +1 -0
  667. package/dist/test/unit/bitgo/utils/tss/recipientUtils.js +462 -0
  668. package/dist/test/unit/bitgo/utils/tss/redpallas/redpallasMPCv2.d.ts +2 -0
  669. package/dist/test/unit/bitgo/utils/tss/redpallas/redpallasMPCv2.d.ts.map +1 -0
  670. package/dist/test/unit/bitgo/utils/tss/redpallas/redpallasMPCv2.js +80 -0
  671. package/dist/test/unit/bitgo/utils/tss/redpallas/smcUtil.d.ts +2 -0
  672. package/dist/test/unit/bitgo/utils/tss/redpallas/smcUtil.d.ts.map +1 -0
  673. package/dist/test/unit/bitgo/utils/tss/redpallas/smcUtil.js +279 -0
  674. package/dist/test/unit/bitgo/utils/tss/redpallasBitgoGpgKey.d.ts +2 -0
  675. package/dist/test/unit/bitgo/utils/tss/redpallasBitgoGpgKey.d.ts.map +1 -0
  676. package/dist/test/unit/bitgo/utils/tss/redpallasBitgoGpgKey.js +111 -0
  677. package/dist/test/unit/bitgo/utils/txRequest.d.ts +2 -0
  678. package/dist/test/unit/bitgo/utils/txRequest.d.ts.map +1 -0
  679. package/dist/test/unit/bitgo/utils/txRequest.js +179 -0
  680. package/dist/test/unit/bitgo/utils/wallet.d.ts +2 -0
  681. package/dist/test/unit/bitgo/utils/wallet.d.ts.map +1 -0
  682. package/dist/test/unit/bitgo/utils/wallet.js +55 -0
  683. package/dist/test/unit/bitgo/wallet/BuildParams.d.ts +2 -0
  684. package/dist/test/unit/bitgo/wallet/BuildParams.d.ts.map +1 -0
  685. package/dist/test/unit/bitgo/wallet/BuildParams.js +154 -0
  686. package/dist/test/unit/bitgo/wallet/SendTransactionRequest.js +79 -9
  687. package/dist/test/unit/bitgo/wallet/getAccountResources.d.ts +2 -0
  688. package/dist/test/unit/bitgo/wallet/getAccountResources.d.ts.map +1 -0
  689. package/dist/test/unit/bitgo/wallet/getAccountResources.js +133 -0
  690. package/dist/test/unit/bitgo/wallet/getPotentialStuckTxs.d.ts +2 -0
  691. package/dist/test/unit/bitgo/wallet/getPotentialStuckTxs.d.ts.map +1 -0
  692. package/dist/test/unit/bitgo/wallet/getPotentialStuckTxs.js +88 -0
  693. package/dist/test/unit/bitgo/wallet/getResourceDelegations.d.ts +2 -0
  694. package/dist/test/unit/bitgo/wallet/getResourceDelegations.d.ts.map +1 -0
  695. package/dist/test/unit/bitgo/wallet/getResourceDelegations.js +118 -0
  696. package/dist/test/unit/bitgo/wallet/ofcWalletAddressCreation.d.ts +2 -0
  697. package/dist/test/unit/bitgo/wallet/ofcWalletAddressCreation.d.ts.map +1 -0
  698. package/dist/test/unit/bitgo/wallet/ofcWalletAddressCreation.js +141 -0
  699. package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.d.ts +2 -0
  700. package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.d.ts.map +1 -0
  701. package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.js +185 -0
  702. package/dist/test/unit/bitgo/wallet/prebuildTransactionTypes.d.ts +2 -0
  703. package/dist/test/unit/bitgo/wallet/prebuildTransactionTypes.d.ts.map +1 -0
  704. package/dist/test/unit/bitgo/wallet/prebuildTransactionTypes.js +20 -0
  705. package/dist/test/unit/bitgo/wallet/resourceManagement.d.ts +3 -0
  706. package/dist/test/unit/bitgo/wallet/resourceManagement.d.ts.map +1 -0
  707. package/dist/test/unit/bitgo/wallet/resourceManagement.js +441 -0
  708. package/dist/test/unit/bitgo/wallet/safeGetUserPrv.d.ts +5 -0
  709. package/dist/test/unit/bitgo/wallet/safeGetUserPrv.d.ts.map +1 -0
  710. package/dist/test/unit/bitgo/wallet/safeGetUserPrv.js +671 -0
  711. package/dist/test/unit/bitgo/wallet/safeShareWallet.d.ts +9 -0
  712. package/dist/test/unit/bitgo/wallet/safeShareWallet.d.ts.map +1 -0
  713. package/dist/test/unit/bitgo/wallet/safeShareWallet.js +303 -0
  714. package/dist/test/unit/bitgo/wallet/tokenApproval.d.ts +2 -0
  715. package/dist/test/unit/bitgo/wallet/tokenApproval.d.ts.map +1 -0
  716. package/dist/test/unit/bitgo/wallet/tokenApproval.js +210 -0
  717. package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.d.ts +2 -0
  718. package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.d.ts.map +1 -0
  719. package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.js +181 -0
  720. package/dist/test/unit/bitgo/wallet/walletOptionsCodecs.d.ts +2 -0
  721. package/dist/test/unit/bitgo/wallet/walletOptionsCodecs.d.ts.map +1 -0
  722. package/dist/test/unit/bitgo/wallet/walletOptionsCodecs.js +69 -0
  723. package/dist/test/unit/bitgo/wallet/walletTssAddressVerification.d.ts +2 -0
  724. package/dist/test/unit/bitgo/wallet/walletTssAddressVerification.d.ts.map +1 -0
  725. package/dist/test/unit/bitgo/wallet/walletTssAddressVerification.js +320 -0
  726. package/dist/test/unit/bitgo/wallet/walletVerifyKey.d.ts +2 -0
  727. package/dist/test/unit/bitgo/wallet/walletVerifyKey.d.ts.map +1 -0
  728. package/dist/test/unit/bitgo/wallet/walletVerifyKey.js +160 -0
  729. package/dist/test/unit/bitgo/wallet/walletsEncryptionVersion.d.ts +2 -0
  730. package/dist/test/unit/bitgo/wallet/walletsEncryptionVersion.d.ts.map +1 -0
  731. package/dist/test/unit/bitgo/wallet/walletsEncryptionVersion.js +304 -0
  732. package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.d.ts +2 -0
  733. package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.d.ts.map +1 -0
  734. package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.js +216 -0
  735. package/dist/test/unit/bitgo/wallet/walletsExternalSigner.d.ts +2 -0
  736. package/dist/test/unit/bitgo/wallet/walletsExternalSigner.d.ts.map +1 -0
  737. package/dist/test/unit/bitgo/wallet/walletsExternalSigner.js +675 -0
  738. package/dist/test/unit/bitgo/wallet/walletsGoAccount.d.ts +2 -0
  739. package/dist/test/unit/bitgo/wallet/walletsGoAccount.d.ts.map +1 -0
  740. package/dist/test/unit/bitgo/wallet/walletsGoAccount.js +150 -0
  741. package/dist/test/unit/bitgo/wallet/walletsWebauthn.d.ts +2 -0
  742. package/dist/test/unit/bitgo/wallet/walletsWebauthn.d.ts.map +1 -0
  743. package/dist/test/unit/bitgo/wallet/walletsWebauthn.js +201 -0
  744. package/dist/test/unit/coins/ofc.d.ts +2 -0
  745. package/dist/test/unit/coins/ofc.d.ts.map +1 -0
  746. package/dist/test/unit/coins/ofc.js +124 -0
  747. package/dist/test/unit/lightning.d.ts +2 -0
  748. package/dist/test/unit/lightning.d.ts.map +1 -0
  749. package/dist/test/unit/lightning.js +23 -0
  750. package/dist/test/unit/units.d.ts.map +1 -1
  751. package/dist/test/unit/units.js +64 -64
  752. package/dist/tsconfig.tsbuildinfo +1 -1
  753. package/package.json +25 -22
  754. package/.eslintignore +0 -5
  755. package/CHANGELOG.md +0 -1866
  756. package/dist/src/account-lib/baseCoin/blsKeyPair.d.ts +0 -77
  757. package/dist/src/account-lib/baseCoin/blsKeyPair.d.ts.map +0 -1
  758. package/dist/src/account-lib/baseCoin/blsKeyPair.js +0 -209
  759. package/dist/src/account-lib/util/ed25519KeyDeriver.d.ts +0 -49
  760. package/dist/src/account-lib/util/ed25519KeyDeriver.d.ts.map +0 -1
  761. package/dist/src/account-lib/util/ed25519KeyDeriver.js +0 -87
  762. package/dist/src/bitgo/lightning/iLightning.d.ts +0 -186
  763. package/dist/src/bitgo/lightning/iLightning.d.ts.map +0 -1
  764. package/dist/src/bitgo/lightning/iLightning.js +0 -106
  765. package/dist/src/bitgo/lightning/index.d.ts +0 -5
  766. package/dist/src/bitgo/lightning/index.d.ts.map +0 -1
  767. package/dist/src/bitgo/lightning/index.js +0 -17
  768. package/dist/src/bitgo/lightning/lightning.d.ts +0 -25
  769. package/dist/src/bitgo/lightning/lightning.d.ts.map +0 -1
  770. package/dist/src/bitgo/lightning/lightning.js +0 -111
  771. package/dist/src/bitgo/lightning/lightningUtils.d.ts +0 -46
  772. package/dist/src/bitgo/lightning/lightningUtils.d.ts.map +0 -1
  773. package/dist/src/bitgo/lightning/lightningUtils.js +0 -133
  774. package/dist/src/bitgo/lightning/lnurlCodec.d.ts +0 -3
  775. package/dist/src/bitgo/lightning/lnurlCodec.d.ts.map +0 -1
  776. package/dist/src/bitgo/lightning/lnurlCodec.js +0 -28
  777. package/dist/src/bitgo/utils/blsUtils.d.ts +0 -52
  778. package/dist/src/bitgo/utils/blsUtils.d.ts.map +0 -1
  779. package/dist/src/bitgo/utils/blsUtils.js +0 -237
  780. package/dist/src/bitgo/utils/iBlsUtils.d.ts +0 -14
  781. package/dist/src/bitgo/utils/iBlsUtils.d.ts.map +0 -1
  782. package/dist/src/bitgo/utils/iBlsUtils.js +0 -3
  783. package/dist/src/coins/fiateur.d.ts +0 -31
  784. package/dist/src/coins/fiateur.d.ts.map +0 -1
  785. package/dist/src/coins/fiateur.js +0 -57
  786. package/dist/src/coins/fiatgbp.d.ts +0 -31
  787. package/dist/src/coins/fiatgbp.d.ts.map +0 -1
  788. package/dist/src/coins/fiatgbp.js +0 -57
  789. package/dist/src/coins/fiatusd.d.ts +0 -31
  790. package/dist/src/coins/fiatusd.d.ts.map +0 -1
  791. package/dist/src/coins/fiatusd.js +0 -57
  792. package/dist/src/coins/tfiateur.d.ts +0 -11
  793. package/dist/src/coins/tfiateur.d.ts.map +0 -1
  794. package/dist/src/coins/tfiateur.js +0 -17
  795. package/dist/src/coins/tfiatgbp.d.ts +0 -11
  796. package/dist/src/coins/tfiatgbp.d.ts.map +0 -1
  797. package/dist/src/coins/tfiatgbp.js +0 -17
  798. package/dist/src/coins/tfiatusd.d.ts +0 -11
  799. package/dist/src/coins/tfiatusd.d.ts.map +0 -1
  800. package/dist/src/coins/tfiatusd.js +0 -17
  801. package/dist/src/openssl/index.d.ts +0 -5
  802. package/dist/src/openssl/index.d.ts.map +0 -1
  803. package/dist/src/openssl/index.js +0 -9
  804. package/dist/test/unit/openssl.d.ts +0 -2
  805. package/dist/test/unit/openssl.d.ts.map +0 -1
  806. package/dist/test/unit/openssl.js +0 -39
@@ -0,0 +1,1993 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const cbor_x_1 = require("cbor-x");
37
+ const assert = __importStar(require("assert"));
38
+ const sinon = __importStar(require("sinon"));
39
+ const pgp = __importStar(require("openpgp"));
40
+ const crypto_1 = require("crypto");
41
+ const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
42
+ const ed25519_1 = require("@noble/curves/ed25519");
43
+ const sjcl = __importStar(require("@bitgo-beta/sjcl"));
44
+ const public_types_1 = require("@bitgo/public-types");
45
+ const src_1 = require("../../../../../../src");
46
+ const eddsaMPCv2_1 = require("../../../../../../src/bitgo/tss/eddsa/eddsaMPCv2");
47
+ const eddsa_1 = require("../../../../../../src/bitgo/tss/eddsa/eddsa");
48
+ const common_1 = require("../../../../../../src/bitgo/tss/common");
49
+ const codecs_1 = require("../../../../../../src/bitgo/utils/codecs");
50
+ const opengpgUtils_1 = require("../../../../../../src/bitgo/utils/opengpgUtils");
51
+ const typesMPCv2_1 = require("../../../../../../src/bitgo/utils/tss/ecdsa/typesMPCv2");
52
+ const baseTypes_1 = require("../../../../../../src/bitgo/utils/tss/baseTypes");
53
+ describe('EdDSA MPS DSG helper functions', async () => {
54
+ let userKeyShare;
55
+ let backupKeyShare;
56
+ let bitgoKeyShare;
57
+ let userGpgPrivKey;
58
+ let backupGpgPrivKey;
59
+ let bitgoGpgPrivKey;
60
+ let bitgoGpgPubKey;
61
+ const signableHex = 'deadbeef';
62
+ const derivationPath = 'm/0';
63
+ before('generate EdDSA DKG key shares', async () => {
64
+ const userGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
65
+ const backupGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
66
+ const bitgoGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
67
+ userGpgPrivKey = await pgp.readPrivateKey({ armoredKey: userGpgKeyPair.privateKey });
68
+ backupGpgPrivKey = await pgp.readPrivateKey({ armoredKey: backupGpgKeyPair.privateKey });
69
+ bitgoGpgPrivKey = await pgp.readPrivateKey({ armoredKey: bitgoGpgKeyPair.privateKey });
70
+ bitgoGpgPubKey = await pgp.readKey({ armoredKey: bitgoGpgKeyPair.publicKey });
71
+ const [userDkg, backupDkg, bitgoDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
72
+ userKeyShare = userDkg.getKeyShare();
73
+ backupKeyShare = backupDkg.getKeyShare();
74
+ bitgoKeyShare = bitgoDkg.getKeyShare();
75
+ });
76
+ // ── Round 1 ─────────────────────────────────────────────────────────────────
77
+ it('getSignatureShareRoundOne should build a valid round-1 share', async () => {
78
+ const messageBuffer = Buffer.from(signableHex, 'hex');
79
+ const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER);
80
+ await userDsg.initDsg(userKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
81
+ const userMsg1 = userDsg.getFirstMessage();
82
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundOne)(userMsg1, userGpgPrivKey);
83
+ assert.strictEqual(share.from, src_1.SignatureShareType.USER);
84
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
85
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound1Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound1Input');
86
+ assert.strictEqual(parsed.type, 'round1Input');
87
+ assert.ok(parsed.data.msg1.message, 'msg1.message should be set');
88
+ assert.ok(parsed.data.msg1.signature, 'msg1.signature should be set');
89
+ });
90
+ it('getSignatureShareRoundOne should build a valid backup round-1 share', async () => {
91
+ const messageBuffer = Buffer.from(signableHex, 'hex');
92
+ const backupDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
93
+ await backupDsg.initDsg(backupKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
94
+ const backupMsg1 = backupDsg.getFirstMessage();
95
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundOne)(backupMsg1, backupGpgPrivKey, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
96
+ assert.strictEqual(share.from, src_1.SignatureShareType.BACKUP);
97
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
98
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound1Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound1Input');
99
+ assert.strictEqual(parsed.type, 'round1Input');
100
+ assert.ok(parsed.data.msg1.message, 'msg1.message should be set');
101
+ assert.ok(parsed.data.msg1.signature, 'msg1.signature should be set');
102
+ });
103
+ it('verifyPeerMessageRoundOne should verify a valid BitGo round-1 message', async () => {
104
+ const messageBuffer = Buffer.from(signableHex, 'hex');
105
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
106
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
107
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
108
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
109
+ const round1Output = {
110
+ type: 'round1Output',
111
+ data: { msg1: bitgoSignedMsg1 },
112
+ };
113
+ const result = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)(round1Output, bitgoGpgPubKey);
114
+ assert.strictEqual(result.from, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
115
+ assert.ok(result.payload.length > 0, 'payload should be non-empty');
116
+ });
117
+ it('verifyPeerMessageRoundOne should throw on a tampered message', async () => {
118
+ const round1Output = {
119
+ type: 'round1Output',
120
+ data: {
121
+ msg1: {
122
+ message: Buffer.from('tampered').toString('base64'),
123
+ signature: '-----BEGIN PGP SIGNATURE-----\n\nINVALID\n-----END PGP SIGNATURE-----\n',
124
+ },
125
+ },
126
+ };
127
+ await assert.rejects((0, eddsaMPCv2_1.verifyPeerMessageRoundOne)(round1Output, bitgoGpgPubKey), 'should throw on invalid signature');
128
+ });
129
+ // ── Round 2 ─────────────────────────────────────────────────────────────────
130
+ it('getSignatureShareRoundTwo should build a valid round-2 share', async () => {
131
+ const messageBuffer = Buffer.from(signableHex, 'hex');
132
+ const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER);
133
+ await userDsg.initDsg(userKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
134
+ const userMsg1 = userDsg.getFirstMessage();
135
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
136
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
137
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
138
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
139
+ const bitgoDeserializedMsg1 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)({ type: 'round1Output', data: { msg1: bitgoSignedMsg1 } }, bitgoGpgPubKey);
140
+ const [userMsg2] = userDsg.handleIncomingMessages([userMsg1, bitgoDeserializedMsg1]);
141
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundTwo)(userMsg2, userGpgPrivKey);
142
+ assert.strictEqual(share.from, src_1.SignatureShareType.USER);
143
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
144
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound2Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound2Input');
145
+ assert.strictEqual(parsed.type, 'round2Input');
146
+ assert.ok(parsed.data.msg2.message, 'msg2.message should be set');
147
+ assert.ok(parsed.data.msg2.signature, 'msg2.signature should be set');
148
+ });
149
+ it('getSignatureShareRoundTwo should build a valid backup round-2 share', async () => {
150
+ const messageBuffer = Buffer.from(signableHex, 'hex');
151
+ const backupDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
152
+ await backupDsg.initDsg(backupKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
153
+ const backupMsg1 = backupDsg.getFirstMessage();
154
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
155
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
156
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
157
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
158
+ const bitgoDeserializedMsg1 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)({ type: 'round1Output', data: { msg1: bitgoSignedMsg1 } }, bitgoGpgPubKey);
159
+ const [backupMsg2] = backupDsg.handleIncomingMessages([backupMsg1, bitgoDeserializedMsg1]);
160
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundTwo)(backupMsg2, backupGpgPrivKey, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
161
+ assert.strictEqual(share.from, src_1.SignatureShareType.BACKUP);
162
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
163
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound2Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound2Input');
164
+ assert.strictEqual(parsed.type, 'round2Input');
165
+ assert.ok(parsed.data.msg2.message, 'msg2.message should be set');
166
+ assert.ok(parsed.data.msg2.signature, 'msg2.signature should be set');
167
+ });
168
+ it('verifyPeerMessageRoundTwo should verify a valid BitGo round-2 message', async () => {
169
+ const messageBuffer = Buffer.from(signableHex, 'hex');
170
+ const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER);
171
+ await userDsg.initDsg(userKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
172
+ const userMsg1 = userDsg.getFirstMessage();
173
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
174
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
175
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
176
+ const [bitgoMsg2] = bitgoDsg.handleIncomingMessages([bitgoMsg1, userMsg1]);
177
+ const bitgoSignedMsg2 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg2.payload), bitgoGpgPrivKey);
178
+ const round2Output = {
179
+ type: 'round2Output',
180
+ data: { msg2: bitgoSignedMsg2 },
181
+ };
182
+ const result = await (0, eddsaMPCv2_1.verifyPeerMessageRoundTwo)(round2Output, bitgoGpgPubKey);
183
+ assert.strictEqual(result.from, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
184
+ assert.ok(result.payload.length > 0, 'payload should be non-empty');
185
+ });
186
+ it('verifyPeerMessageRoundTwo should throw on a tampered message', async () => {
187
+ const round2Output = {
188
+ type: 'round2Output',
189
+ data: {
190
+ msg2: {
191
+ message: Buffer.from('tampered').toString('base64'),
192
+ signature: '-----BEGIN PGP SIGNATURE-----\n\nINVALID\n-----END PGP SIGNATURE-----\n',
193
+ },
194
+ },
195
+ };
196
+ await assert.rejects((0, eddsaMPCv2_1.verifyPeerMessageRoundTwo)(round2Output, bitgoGpgPubKey), 'should throw on invalid signature');
197
+ });
198
+ // ── Round 3 ─────────────────────────────────────────────────────────────────
199
+ it('getSignatureShareRoundThree should build a valid round-3 share', async () => {
200
+ const messageBuffer = Buffer.from(signableHex, 'hex');
201
+ const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER);
202
+ await userDsg.initDsg(userKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
203
+ const userMsg1 = userDsg.getFirstMessage();
204
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
205
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
206
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
207
+ // Advance to round 2
208
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
209
+ const bitgoDeserializedMsg1 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)({ type: 'round1Output', data: { msg1: bitgoSignedMsg1 } }, bitgoGpgPubKey);
210
+ const [userMsg2] = userDsg.handleIncomingMessages([userMsg1, bitgoDeserializedMsg1]);
211
+ const [bitgoMsg2] = bitgoDsg.handleIncomingMessages([bitgoMsg1, userMsg1]);
212
+ const bitgoSignedMsg2 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg2.payload), bitgoGpgPrivKey);
213
+ const bitgoDeserializedMsg2 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundTwo)({ type: 'round2Output', data: { msg2: bitgoSignedMsg2 } }, bitgoGpgPubKey);
214
+ const [userMsg3] = userDsg.handleIncomingMessages([userMsg2, bitgoDeserializedMsg2]);
215
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundThree)(userMsg3, userGpgPrivKey);
216
+ assert.strictEqual(share.from, src_1.SignatureShareType.USER);
217
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
218
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound3Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound3Input');
219
+ assert.strictEqual(parsed.type, 'round3Input');
220
+ assert.ok(parsed.data.msg3.message, 'msg3.message should be set');
221
+ assert.ok(parsed.data.msg3.signature, 'msg3.signature should be set');
222
+ });
223
+ it('getSignatureShareRoundThree should build a valid backup round-3 share', async () => {
224
+ const messageBuffer = Buffer.from(signableHex, 'hex');
225
+ const backupDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
226
+ await backupDsg.initDsg(backupKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
227
+ const backupMsg1 = backupDsg.getFirstMessage();
228
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
229
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
230
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
231
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
232
+ const bitgoDeserializedMsg1 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)({ type: 'round1Output', data: { msg1: bitgoSignedMsg1 } }, bitgoGpgPubKey);
233
+ const [backupMsg2] = backupDsg.handleIncomingMessages([backupMsg1, bitgoDeserializedMsg1]);
234
+ const [bitgoMsg2] = bitgoDsg.handleIncomingMessages([bitgoMsg1, backupMsg1]);
235
+ const bitgoSignedMsg2 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg2.payload), bitgoGpgPrivKey);
236
+ const bitgoDeserializedMsg2 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundTwo)({ type: 'round2Output', data: { msg2: bitgoSignedMsg2 } }, bitgoGpgPubKey);
237
+ const [backupMsg3] = backupDsg.handleIncomingMessages([backupMsg2, bitgoDeserializedMsg2]);
238
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundThree)(backupMsg3, backupGpgPrivKey, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
239
+ assert.strictEqual(share.from, src_1.SignatureShareType.BACKUP);
240
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
241
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound3Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound3Input');
242
+ assert.strictEqual(parsed.type, 'round3Input');
243
+ assert.ok(parsed.data.msg3.message, 'msg3.message should be set');
244
+ assert.ok(parsed.data.msg3.signature, 'msg3.signature should be set');
245
+ });
246
+ it('verifyPeerMessageRoundThree should verify a valid BitGo round-3 message', async () => {
247
+ const messageBuffer = Buffer.from(signableHex, 'hex');
248
+ const [, [bitgoMsg3]] = (await sdk_lib_mpc_1.MPSUtil.executeTillRound(2, new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER), new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO), userKeyShare, bitgoKeyShare, messageBuffer, derivationPath));
249
+ const bitgoSignedMsg3 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg3.payload), bitgoGpgPrivKey);
250
+ const round3Output = {
251
+ type: 'round3Output',
252
+ data: { msg3: bitgoSignedMsg3 },
253
+ };
254
+ const result = await (0, eddsaMPCv2_1.verifyPeerMessageRoundThree)(round3Output, bitgoGpgPubKey);
255
+ assert.strictEqual(result.from, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
256
+ assert.ok(result.payload.length > 0, 'payload should be non-empty');
257
+ });
258
+ it('verifyPeerMessageRoundThree should throw on a tampered message', async () => {
259
+ const round3Output = {
260
+ type: 'round3Output',
261
+ data: {
262
+ msg3: {
263
+ message: Buffer.from('tampered').toString('base64'),
264
+ signature: '-----BEGIN PGP SIGNATURE-----\n\nINVALID\n-----END PGP SIGNATURE-----\n',
265
+ },
266
+ },
267
+ };
268
+ await assert.rejects((0, eddsaMPCv2_1.verifyPeerMessageRoundThree)(round3Output, bitgoGpgPubKey), 'should throw on invalid signature');
269
+ });
270
+ });
271
+ describe('getEddsaMPCv2RecoveryKeyShares', () => {
272
+ const walletPassphrase = 'testPass';
273
+ const encryptKey = (keyShare) => sjcl.encrypt(walletPassphrase, keyShare.toString('base64'));
274
+ it('should return recovery key shares from v1-encrypted reduced keys (no bitgo instance)', async () => {
275
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
276
+ const result = await src_1.EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey(encryptKey(userDkg.getReducedKeyShare()), encryptKey(backupDkg.getReducedKeyShare()), walletPassphrase);
277
+ assert.deepStrictEqual(result.userKeyShare, userDkg.getKeyShare());
278
+ assert.deepStrictEqual(result.backupKeyShare, backupDkg.getKeyShare());
279
+ assert.strictEqual(result.commonKeyChain, userDkg.getCommonKeychain());
280
+ });
281
+ it('should unwrap versioned safe-root envelopes and return VRF keyshares', async () => {
282
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
283
+ const userVrfKeyShare = Buffer.from('user-vrf-keyshare');
284
+ const backupVrfKeyShare = Buffer.from('backup-vrf-keyshare');
285
+ const encodeEnvelope = (reducedKeyShare, vrfKeyShare) => Buffer.from((0, cbor_x_1.encode)({
286
+ version: 1,
287
+ prvKeyShare: new Uint8Array(reducedKeyShare),
288
+ vrf: new Uint8Array(vrfKeyShare),
289
+ }));
290
+ const result = await src_1.EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey(encryptKey(encodeEnvelope(userDkg.getReducedKeyShare(), userVrfKeyShare)), encryptKey(encodeEnvelope(backupDkg.getReducedKeyShare(), backupVrfKeyShare)), walletPassphrase);
291
+ assert.strictEqual(Buffer.compare(result.userKeyShare, userDkg.getKeyShare()), 0);
292
+ assert.strictEqual(Buffer.compare(result.backupKeyShare, backupDkg.getKeyShare()), 0);
293
+ assert.strictEqual(result.commonKeyChain, userDkg.getCommonKeychain());
294
+ assert.ok(result.userVrfKeyShare);
295
+ assert.ok(result.backupVrfKeyShare);
296
+ assert.strictEqual(Buffer.compare(result.userVrfKeyShare, userVrfKeyShare), 0);
297
+ assert.strictEqual(Buffer.compare(result.backupVrfKeyShare, backupVrfKeyShare), 0);
298
+ });
299
+ it('should route decryption through bitgo.decrypt when a bitgo instance is provided', async () => {
300
+ // sdk-core has no devDependency on sdk-api or argon2, so we cannot encrypt with a real v2 envelope here.
301
+ // The stub verifies that the function delegates to bitgo.decrypt (which supports v1 + v2 in
302
+ // production) rather than falling back to sjcl.decrypt.
303
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
304
+ const userKeyBase64 = userDkg.getReducedKeyShare().toString('base64');
305
+ const backupKeyBase64 = backupDkg.getReducedKeyShare().toString('base64');
306
+ const mockBitgo = {
307
+ decrypt: sinon.stub().onFirstCall().resolves(userKeyBase64).onSecondCall().resolves(backupKeyBase64),
308
+ };
309
+ const result = await src_1.EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey('encrypted-user-key', 'encrypted-backup-key', walletPassphrase, mockBitgo);
310
+ sinon.assert.calledTwice(mockBitgo.decrypt);
311
+ assert.deepStrictEqual(result.userKeyShare, userDkg.getKeyShare());
312
+ assert.deepStrictEqual(result.backupKeyShare, backupDkg.getKeyShare());
313
+ assert.strictEqual(result.commonKeyChain, userDkg.getCommonKeychain());
314
+ });
315
+ it('should reject a malformed keycard with a descriptive error', async () => {
316
+ const [userDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
317
+ const malformedKey = sjcl.encrypt(walletPassphrase, (0, crypto_1.randomBytes)(64).toString('base64'));
318
+ await assert.rejects(src_1.EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey(malformedKey, encryptKey(userDkg.getReducedKeyShare()), walletPassphrase), /unable to decode reduced key share/);
319
+ });
320
+ it('should reject reduced keys from different wallets', async () => {
321
+ const [userDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
322
+ const [, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
323
+ await assert.rejects(src_1.EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey(encryptKey(userDkg.getReducedKeyShare()), encryptKey(backupDkg.getReducedKeyShare()), walletPassphrase), /pub keys do not match/);
324
+ });
325
+ it('should reject reduced keys with matching pub but mismatched rootChainCodes', async () => {
326
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
327
+ const userReducedKeyShare = userDkg.getReducedKeyShare();
328
+ const backupReducedKeyShare = backupDkg.getReducedKeyShare();
329
+ const getDecodedReducedKeyShare = sdk_lib_mpc_1.MPSTypes.getDecodedReducedKeyShare;
330
+ const decodeStub = sinon.stub(sdk_lib_mpc_1.MPSTypes, 'getDecodedReducedKeyShare').callsFake((buf) => {
331
+ const reduced = getDecodedReducedKeyShare(buf);
332
+ if (Buffer.from(buf).equals(backupReducedKeyShare)) {
333
+ return {
334
+ ...reduced,
335
+ rootChainCode: Array.from((0, crypto_1.randomBytes)(32)),
336
+ };
337
+ }
338
+ return reduced;
339
+ });
340
+ try {
341
+ await assert.rejects(src_1.EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey(encryptKey(userReducedKeyShare), encryptKey(backupReducedKeyShare), walletPassphrase), /rootChainCodes do not match/);
342
+ }
343
+ finally {
344
+ decodeStub.restore();
345
+ }
346
+ });
347
+ });
348
+ describe('EddsaMPCv2Utils.createOfflineRound1Share', () => {
349
+ let eddsaMPCv2Utils;
350
+ let mockBitgo;
351
+ let userKeyShare;
352
+ const walletPassphrase = 'testPass';
353
+ const signableHex = 'deadbeef';
354
+ const derivationPath = 'm/0/0';
355
+ const expectedAdata = `${signableHex}:${derivationPath}`;
356
+ const txRequest = {
357
+ txRequestId: 'txreq-eddsa-round1',
358
+ walletId: 'wallet-eddsa-round1',
359
+ enterpriseId: 'enterprise-eddsa-round1',
360
+ apiVersion: 'full',
361
+ transactions: [
362
+ {
363
+ unsignedTx: {
364
+ signableHex,
365
+ derivationPath,
366
+ serializedTxHex: signableHex,
367
+ },
368
+ signatureShares: [],
369
+ },
370
+ ],
371
+ intent: { intentType: 'payment' },
372
+ unsignedTxs: [],
373
+ };
374
+ before('generate EdDSA user key share', async () => {
375
+ const [userDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
376
+ userKeyShare = userDkg.getKeyShare();
377
+ });
378
+ beforeEach(() => {
379
+ const sjclEncrypt = (params) => {
380
+ const salt = (0, crypto_1.randomBytes)(8);
381
+ const iv = (0, crypto_1.randomBytes)(16);
382
+ return sjcl.encrypt(params.password, params.input, {
383
+ salt: [bytesToWord(salt.subarray(0, 4)), bytesToWord(salt.subarray(4))],
384
+ iv: [
385
+ bytesToWord(iv.subarray(0, 4)),
386
+ bytesToWord(iv.subarray(4, 8)),
387
+ bytesToWord(iv.subarray(8, 12)),
388
+ bytesToWord(iv.subarray(12, 16)),
389
+ ],
390
+ adata: params.adata,
391
+ });
392
+ };
393
+ mockBitgo = {
394
+ encrypt: sinon.stub().callsFake(async (params) => sjclEncrypt(params)),
395
+ };
396
+ const mockCoin = {
397
+ getMPCAlgorithm: sinon.stub().returns('eddsa'),
398
+ };
399
+ eddsaMPCv2Utils = new src_1.EddsaMPCv2Utils(mockBitgo, mockCoin);
400
+ });
401
+ it('should create a round-1 share and encrypted SJCL session payload', async () => {
402
+ const result = await eddsaMPCv2Utils.createOfflineRound1Share({
403
+ txRequest,
404
+ prv: userKeyShare.toString('base64'),
405
+ walletPassphrase,
406
+ });
407
+ assert.strictEqual(result.signatureShareRound1.from, src_1.SignatureShareType.USER);
408
+ assert.strictEqual(result.signatureShareRound1.to, src_1.SignatureShareType.BITGO);
409
+ assert.ok(result.userGpgPubKey.includes('BEGIN PGP PUBLIC KEY BLOCK'));
410
+ assert.ok(JSON.parse(result.encryptedRound1Session).ct, 'encryptedRound1Session should be an SJCL JSON blob');
411
+ assert.ok(JSON.parse(result.encryptedUserGpgPrvKey).ct, 'encryptedUserGpgPrvKey should be an SJCL JSON blob');
412
+ const parsedShare = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound1Input, JSON.parse(result.signatureShareRound1.share), 'EddsaMPCv2SignatureShareRound1Input');
413
+ assert.strictEqual(parsedShare.type, 'round1Input');
414
+ assert.ok(parsedShare.data.msg1.message, 'msg1.message should be set');
415
+ assert.ok(parsedShare.data.msg1.signature, 'msg1.signature should be set');
416
+ const encryptedRound1Session = JSON.parse(result.encryptedRound1Session);
417
+ const encryptedUserGpgPrvKey = JSON.parse(result.encryptedUserGpgPrvKey);
418
+ assert.strictEqual(decodeURIComponent(encryptedRound1Session.adata), `MPS_DSG_SIGNING_ROUND1_STATE:${expectedAdata}`, 'round-1 session adata should bind the signing context');
419
+ assert.strictEqual(decodeURIComponent(encryptedUserGpgPrvKey.adata), `MPS_DSG_SIGNING_USER_GPG_KEY:${expectedAdata}`, 'GPG private key adata should bind the signing context');
420
+ const sessionPayload = JSON.parse(sjcl.decrypt(walletPassphrase, result.encryptedRound1Session));
421
+ assert.ok(sessionPayload.dsgSession, 'dsgSession should be persisted for round 2');
422
+ assert.ok(sessionPayload.userMsgPayload, 'userMsgPayload should be persisted for round 2');
423
+ });
424
+ it('should use v2 encryption when encryptedPrv is a v2 envelope', async () => {
425
+ const encrypt = sinon
426
+ .stub()
427
+ .callsFake((input, adata) => Promise.resolve(JSON.stringify({ v: 2, input, adata })));
428
+ const destroy = sinon.stub();
429
+ const createEncryptionSession = sinon.stub().resolves({ encrypt, destroy });
430
+ mockBitgo.createEncryptionSession = createEncryptionSession;
431
+ const result = await eddsaMPCv2Utils.createOfflineRound1Share({
432
+ txRequest,
433
+ prv: userKeyShare.toString('base64'),
434
+ walletPassphrase,
435
+ encryptedPrv: JSON.stringify({ v: 2 }),
436
+ });
437
+ sinon.assert.calledOnce(createEncryptionSession);
438
+ assert.strictEqual(createEncryptionSession.getCall(0).args[0], walletPassphrase);
439
+ sinon.assert.notCalled(mockBitgo.encrypt);
440
+ sinon.assert.calledTwice(encrypt);
441
+ sinon.assert.calledOnce(destroy);
442
+ const encryptedRound1Session = JSON.parse(result.encryptedRound1Session);
443
+ const encryptedUserGpgPrvKey = JSON.parse(result.encryptedUserGpgPrvKey);
444
+ assert.strictEqual(encryptedRound1Session.v, 2);
445
+ assert.strictEqual(encryptedRound1Session.adata, `MPS_DSG_SIGNING_ROUND1_STATE:${expectedAdata}`);
446
+ assert.strictEqual(encryptedUserGpgPrvKey.v, 2);
447
+ assert.strictEqual(encryptedUserGpgPrvKey.adata, `MPS_DSG_SIGNING_USER_GPG_KEY:${expectedAdata}`);
448
+ const sessionPayload = JSON.parse(encryptedRound1Session.input);
449
+ assert.ok(sessionPayload.dsgSession, 'dsgSession should be persisted for round 2');
450
+ assert.ok(sessionPayload.userMsgPayload, 'userMsgPayload should be persisted for round 2');
451
+ });
452
+ it('should use SJCL encryption when encryptedPrv is a v1 blob', async () => {
453
+ mockBitgo.createEncryptionSession = sinon.stub();
454
+ const encryptedPrv = sjcl.encrypt(walletPassphrase, userKeyShare.toString('base64'));
455
+ const result = await eddsaMPCv2Utils.createOfflineRound1Share({
456
+ txRequest,
457
+ prv: userKeyShare.toString('base64'),
458
+ walletPassphrase,
459
+ encryptedPrv,
460
+ });
461
+ sinon.assert.notCalled(mockBitgo.createEncryptionSession);
462
+ sinon.assert.calledTwice(mockBitgo.encrypt);
463
+ assert.ok(JSON.parse(result.encryptedRound1Session).ct, 'encryptedRound1Session should be an SJCL JSON blob');
464
+ assert.ok(JSON.parse(result.encryptedUserGpgPrvKey).ct, 'encryptedUserGpgPrvKey should be an SJCL JSON blob');
465
+ });
466
+ it('should propagate the tx-only guard when transactions are missing', async () => {
467
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound1Share({
468
+ txRequest: { ...txRequest, transactions: undefined },
469
+ prv: userKeyShare.toString('base64'),
470
+ walletPassphrase,
471
+ }), /Unable to find transactions in txRequest/);
472
+ });
473
+ });
474
+ describe('EddsaMPCv2Utils.createOfflineKeyGenRound1Share', () => {
475
+ let eddsaMPCv2Utils;
476
+ let mockBitgo;
477
+ let userGpgKeyPair;
478
+ let backupGpgKeyPair;
479
+ let bitgoGpgKeyPair;
480
+ const walletPassphrase = 'testPass';
481
+ before('generate GPG key pairs', async () => {
482
+ userGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
483
+ backupGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
484
+ bitgoGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
485
+ });
486
+ beforeEach(() => {
487
+ const sjclEncrypt = (params) => {
488
+ const salt = (0, crypto_1.randomBytes)(8);
489
+ const iv = (0, crypto_1.randomBytes)(16);
490
+ return sjcl.encrypt(params.password, params.input, {
491
+ salt: [bytesToWord(salt.subarray(0, 4)), bytesToWord(salt.subarray(4))],
492
+ iv: [
493
+ bytesToWord(iv.subarray(0, 4)),
494
+ bytesToWord(iv.subarray(4, 8)),
495
+ bytesToWord(iv.subarray(8, 12)),
496
+ bytesToWord(iv.subarray(12, 16)),
497
+ ],
498
+ adata: params.adata,
499
+ });
500
+ };
501
+ mockBitgo = {
502
+ encrypt: sinon.stub().callsFake(sjclEncrypt),
503
+ encryptAsync: sinon.stub().callsFake(async (params) => sjclEncrypt(params)),
504
+ decrypt: sinon.stub().callsFake((params) => sjcl.decrypt(params.password, params.input)),
505
+ decryptAsync: sinon.stub().callsFake(async (params) => sjcl.decrypt(params.password, params.input)),
506
+ getEnv: sinon.stub().returns('mock'),
507
+ };
508
+ const mockCoin = {
509
+ getMPCAlgorithm: sinon.stub().returns('eddsa'),
510
+ };
511
+ eddsaMPCv2Utils = new src_1.EddsaMPCv2Utils(mockBitgo, mockCoin);
512
+ });
513
+ it('should produce valid signedMsg1 and encrypted round-1 session', async () => {
514
+ const encryptedUserGpgPrvKey = sjcl.encrypt(walletPassphrase, userGpgKeyPair.privateKey);
515
+ const result = await eddsaMPCv2Utils.createOfflineKeyGenRound1Share({
516
+ walletPassphrase,
517
+ encryptedUserGpgPrvKey,
518
+ bitgoGpgPubKey: bitgoGpgKeyPair.publicKey,
519
+ counterPartyGpgPubKey: backupGpgKeyPair.publicKey,
520
+ });
521
+ assert.ok(result.signedMsg1.message, 'signedMsg1.message should be set');
522
+ assert.ok(result.signedMsg1.signature.includes('BEGIN PGP SIGNATURE'), 'signedMsg1.signature should be PGP armored');
523
+ assert.ok(JSON.parse(result.encryptedRound1Session).ct, 'encryptedRound1Session should be an SJCL JSON blob');
524
+ });
525
+ it('encryptedRound1Session should only be decryptable with correct walletPassphrase', async () => {
526
+ const encryptedUserGpgPrvKey = sjcl.encrypt(walletPassphrase, userGpgKeyPair.privateKey);
527
+ const result = await eddsaMPCv2Utils.createOfflineKeyGenRound1Share({
528
+ walletPassphrase,
529
+ encryptedUserGpgPrvKey,
530
+ bitgoGpgPubKey: bitgoGpgKeyPair.publicKey,
531
+ counterPartyGpgPubKey: backupGpgKeyPair.publicKey,
532
+ });
533
+ const decrypted = sjcl.decrypt(walletPassphrase, result.encryptedRound1Session);
534
+ const session = JSON.parse(decrypted);
535
+ assert.ok(session.dkgSession, 'dkgSession should be persisted');
536
+ assert.ok(session.ownMsgPayload, 'ownMsgPayload should be persisted');
537
+ assert.strictEqual(typeof session.ownMsgFrom, 'number', 'ownMsgFrom should be a number');
538
+ assert.throws(() => sjcl.decrypt('wrongpassphrase', result.encryptedRound1Session), 'should throw on wrong passphrase');
539
+ });
540
+ it('should restore DKG session and handle round-2 messages after round 1', async () => {
541
+ const encryptedUserGpgPrvKey = sjcl.encrypt(walletPassphrase, userGpgKeyPair.privateKey);
542
+ const result = await eddsaMPCv2Utils.createOfflineKeyGenRound1Share({
543
+ walletPassphrase,
544
+ encryptedUserGpgPrvKey,
545
+ bitgoGpgPubKey: bitgoGpgKeyPair.publicKey,
546
+ counterPartyGpgPubKey: backupGpgKeyPair.publicKey,
547
+ });
548
+ const decrypted = sjcl.decrypt(walletPassphrase, result.encryptedRound1Session);
549
+ const { dkgSession, ownMsgPayload, ownMsgFrom } = JSON.parse(decrypted);
550
+ const restoredDkg = new sdk_lib_mpc_1.EddsaMPSDkg.DKG(3, 2, typesMPCv2_1.MPCv2PartiesEnum.USER);
551
+ await restoredDkg.restoreSession(dkgSession);
552
+ const ownMsg1 = {
553
+ from: ownMsgFrom,
554
+ payload: new Uint8Array(Buffer.from(ownMsgPayload, 'base64')),
555
+ };
556
+ assert.ok(ownMsg1.payload.length > 0, 'restored payload should be non-empty');
557
+ const userGpgKey = await pgp.readKey({ armoredKey: userGpgKeyPair.publicKey });
558
+ const rawBytes = await sdk_lib_mpc_1.MPSComms.verifyMpsMessage(result.signedMsg1, userGpgKey);
559
+ assert.ok(rawBytes.length > 0, 'signedMsg1 should verify against user GPG key');
560
+ });
561
+ it('should reject invalid encryptedUserGpgPrvKey', async () => {
562
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineKeyGenRound1Share({
563
+ walletPassphrase,
564
+ encryptedUserGpgPrvKey: sjcl.encrypt(walletPassphrase, 'not-a-gpg-key'),
565
+ bitgoGpgPubKey: bitgoGpgKeyPair.publicKey,
566
+ counterPartyGpgPubKey: backupGpgKeyPair.publicKey,
567
+ }), 'should throw when GPG key cannot be parsed');
568
+ });
569
+ it('USER and BACKUP partyId produce different encrypted session state', async () => {
570
+ const userEncryptedGpgPrvKey = sjcl.encrypt(walletPassphrase, userGpgKeyPair.privateKey);
571
+ const userResult = await eddsaMPCv2Utils.createOfflineKeyGenRound1Share({
572
+ walletPassphrase,
573
+ encryptedUserGpgPrvKey: userEncryptedGpgPrvKey,
574
+ bitgoGpgPubKey: bitgoGpgKeyPair.publicKey,
575
+ counterPartyGpgPubKey: backupGpgKeyPair.publicKey,
576
+ partyId: typesMPCv2_1.MPCv2PartiesEnum.USER,
577
+ });
578
+ const backupEncryptedGpgPrvKey2 = sjcl.encrypt(walletPassphrase, backupGpgKeyPair.privateKey);
579
+ const backupResult = await eddsaMPCv2Utils.createOfflineKeyGenRound1Share({
580
+ walletPassphrase,
581
+ encryptedUserGpgPrvKey: backupEncryptedGpgPrvKey2,
582
+ bitgoGpgPubKey: bitgoGpgKeyPair.publicKey,
583
+ counterPartyGpgPubKey: userGpgKeyPair.publicKey,
584
+ partyId: typesMPCv2_1.MPCv2PartiesEnum.BACKUP,
585
+ });
586
+ const userSession = JSON.parse(sjcl.decrypt(walletPassphrase, userResult.encryptedRound1Session));
587
+ const backupSession = JSON.parse(sjcl.decrypt(walletPassphrase, backupResult.encryptedRound1Session));
588
+ assert.strictEqual(userSession.ownMsgFrom, typesMPCv2_1.MPCv2PartiesEnum.USER);
589
+ assert.strictEqual(backupSession.ownMsgFrom, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
590
+ assert.notStrictEqual(userSession.dkgSession, backupSession.dkgSession, 'Sessions should differ between parties');
591
+ // Sessions encrypted with party-bound adata — tampered adata fails CCM tag check
592
+ const tamperedSession = (() => {
593
+ const parsed = JSON.parse(userResult.encryptedRound1Session);
594
+ parsed.adata = encodeURIComponent(`MPS_DKG_KEYGEN_ROUND1_STATE:${typesMPCv2_1.MPCv2PartiesEnum.BACKUP}`);
595
+ return JSON.stringify(parsed);
596
+ })();
597
+ assert.throws(() => sjcl.decrypt(walletPassphrase, tamperedSession), 'should fail to decrypt with wrong party adata');
598
+ });
599
+ });
600
+ describe('EddsaMPCv2Utils.createOfflineRound2Share', () => {
601
+ let eddsaMPCv2Utils;
602
+ let mockBitgo;
603
+ let userKeyShare;
604
+ let bitgoKeyShare;
605
+ let bitgoGpgKeyPair;
606
+ let bitgoGpgPrivKey;
607
+ const walletPassphrase = 'testPass';
608
+ const signableHex = 'deadbeef';
609
+ const derivationPath = 'm/0/0';
610
+ const expectedAdata = `${signableHex}:${derivationPath}`;
611
+ const baseTxRequest = {
612
+ txRequestId: 'txreq-eddsa-round2',
613
+ walletId: 'wallet-eddsa-round2',
614
+ enterpriseId: 'enterprise-eddsa-round2',
615
+ apiVersion: 'full',
616
+ transactions: [
617
+ {
618
+ unsignedTx: {
619
+ signableHex,
620
+ derivationPath,
621
+ serializedTxHex: signableHex,
622
+ },
623
+ signatureShares: [],
624
+ },
625
+ ],
626
+ intent: { intentType: 'payment' },
627
+ unsignedTxs: [],
628
+ };
629
+ before('generate EdDSA key shares and GPG keys', async () => {
630
+ const [userDkg, , bitgoDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
631
+ userKeyShare = userDkg.getKeyShare();
632
+ bitgoKeyShare = bitgoDkg.getKeyShare();
633
+ bitgoGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
634
+ bitgoGpgPrivKey = await pgp.readPrivateKey({ armoredKey: bitgoGpgKeyPair.privateKey });
635
+ });
636
+ beforeEach(() => {
637
+ mockBitgo = {
638
+ encrypt: sinon.stub().callsFake(async (params) => {
639
+ const salt = (0, crypto_1.randomBytes)(8);
640
+ const iv = (0, crypto_1.randomBytes)(16);
641
+ return sjcl.encrypt(params.password, params.input, {
642
+ salt: [bytesToWord(salt.subarray(0, 4)), bytesToWord(salt.subarray(4))],
643
+ iv: [
644
+ bytesToWord(iv.subarray(0, 4)),
645
+ bytesToWord(iv.subarray(4, 8)),
646
+ bytesToWord(iv.subarray(8, 12)),
647
+ bytesToWord(iv.subarray(12, 16)),
648
+ ],
649
+ adata: params.adata,
650
+ });
651
+ }),
652
+ decrypt: sinon.stub().callsFake(async (params) => sjcl.decrypt(params.password, params.input)),
653
+ };
654
+ const mockCoin = {
655
+ getMPCAlgorithm: sinon.stub().returns('eddsa'),
656
+ };
657
+ eddsaMPCv2Utils = new src_1.EddsaMPCv2Utils(mockBitgo, mockCoin);
658
+ });
659
+ it('should create a round-2 share from offline round 1', async () => {
660
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
661
+ txRequest: baseTxRequest,
662
+ prv: userKeyShare.toString('base64'),
663
+ walletPassphrase,
664
+ });
665
+ const messageBuffer = Buffer.from(signableHex, 'hex');
666
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
667
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
668
+ const txRequestRound1 = await signBitgoEddsaRound1(bitgoDsg, cloneTxRequestWithEmptySignatureShares(baseTxRequest), round1.signatureShareRound1, round1.userGpgPubKey, bitgoGpgPrivKey);
669
+ const round2 = await eddsaMPCv2Utils.createOfflineRound2Share({
670
+ txRequest: txRequestRound1,
671
+ walletPassphrase,
672
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
673
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
674
+ encryptedRound1Session: round1.encryptedRound1Session,
675
+ });
676
+ assert.strictEqual(round2.signatureShareRound2.from, src_1.SignatureShareType.USER);
677
+ assert.strictEqual(round2.signatureShareRound2.to, src_1.SignatureShareType.BITGO);
678
+ const parsedShare = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound2Input, JSON.parse(round2.signatureShareRound2.share), 'EddsaMPCv2SignatureShareRound2Input');
679
+ assert.strictEqual(parsedShare.type, 'round2Input');
680
+ assert.ok(parsedShare.data.msg2.message, 'msg2.message should be set');
681
+ assert.ok(parsedShare.data.msg2.signature, 'msg2.signature should be set');
682
+ const encryptedRound2Session = JSON.parse(round2.encryptedRound2Session);
683
+ assert.strictEqual(decodeURIComponent(encryptedRound2Session.adata), `MPS_DSG_SIGNING_ROUND2_STATE:${expectedAdata}`);
684
+ const sessionPayload = JSON.parse(sjcl.decrypt(walletPassphrase, round2.encryptedRound2Session));
685
+ assert.ok(sessionPayload.dsgSession, 'dsgSession should be persisted for round 3');
686
+ assert.ok(sessionPayload.userMsgPayload, 'userMsgPayload should be persisted for round 3');
687
+ });
688
+ it('should use v2 decryption when encryptedRound1Session is a v2 envelope', async () => {
689
+ const encrypt = sinon
690
+ .stub()
691
+ .callsFake((input, adata) => Promise.resolve(JSON.stringify({ v: 2, input, adata })));
692
+ const destroy = sinon.stub();
693
+ const createEncryptionSession = sinon.stub().resolves({ encrypt, destroy });
694
+ mockBitgo.createEncryptionSession = createEncryptionSession;
695
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
696
+ txRequest: baseTxRequest,
697
+ prv: userKeyShare.toString('base64'),
698
+ walletPassphrase,
699
+ encryptedPrv: JSON.stringify({ v: 2 }),
700
+ });
701
+ const messageBuffer = Buffer.from(signableHex, 'hex');
702
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
703
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
704
+ const txRequestRound1 = await signBitgoEddsaRound1(bitgoDsg, cloneTxRequestWithEmptySignatureShares(baseTxRequest), round1.signatureShareRound1, round1.userGpgPubKey, bitgoGpgPrivKey);
705
+ const decrypt = sinon.stub().callsFake(async (params) => {
706
+ const envelope = JSON.parse(params.input);
707
+ return envelope.input;
708
+ });
709
+ mockBitgo.decrypt = decrypt;
710
+ const round2 = await eddsaMPCv2Utils.createOfflineRound2Share({
711
+ txRequest: txRequestRound1,
712
+ walletPassphrase,
713
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
714
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
715
+ encryptedRound1Session: round1.encryptedRound1Session,
716
+ });
717
+ sinon.assert.called(mockBitgo.decrypt);
718
+ assert.strictEqual(round2.signatureShareRound2.from, src_1.SignatureShareType.USER);
719
+ const encryptedRound2Session = JSON.parse(round2.encryptedRound2Session);
720
+ assert.strictEqual(encryptedRound2Session.v, 2);
721
+ assert.strictEqual(encryptedRound2Session.adata, `MPS_DSG_SIGNING_ROUND2_STATE:${expectedAdata}`);
722
+ });
723
+ it('should reject tampered encryptedRound1Session adata', async () => {
724
+ const otherTxRequest = {
725
+ ...baseTxRequest,
726
+ transactions: [
727
+ {
728
+ unsignedTx: {
729
+ signableHex: 'cafebabe',
730
+ derivationPath: 'm/1/2',
731
+ serializedTxHex: 'cafebabe',
732
+ },
733
+ signatureShares: [],
734
+ },
735
+ ],
736
+ };
737
+ const round1Other = await eddsaMPCv2Utils.createOfflineRound1Share({
738
+ txRequest: otherTxRequest,
739
+ prv: userKeyShare.toString('base64'),
740
+ walletPassphrase,
741
+ });
742
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
743
+ txRequest: baseTxRequest,
744
+ prv: userKeyShare.toString('base64'),
745
+ walletPassphrase,
746
+ });
747
+ const messageBuffer = Buffer.from(signableHex, 'hex');
748
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
749
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
750
+ const txRequestRound1 = await signBitgoEddsaRound1(bitgoDsg, cloneTxRequestWithEmptySignatureShares(baseTxRequest), round1.signatureShareRound1, round1.userGpgPubKey, bitgoGpgPrivKey);
751
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound2Share({
752
+ txRequest: txRequestRound1,
753
+ walletPassphrase,
754
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
755
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
756
+ encryptedRound1Session: round1Other.encryptedRound1Session,
757
+ }), /Adata does not match cyphertext adata/);
758
+ });
759
+ it('should reject tampered encryptedUserGpgPrvKey adata', async () => {
760
+ const otherTxRequest = {
761
+ ...baseTxRequest,
762
+ transactions: [
763
+ {
764
+ unsignedTx: {
765
+ signableHex: 'cafebabe',
766
+ derivationPath: 'm/1/2',
767
+ serializedTxHex: 'cafebabe',
768
+ },
769
+ signatureShares: [],
770
+ },
771
+ ],
772
+ };
773
+ const round1Other = await eddsaMPCv2Utils.createOfflineRound1Share({
774
+ txRequest: otherTxRequest,
775
+ prv: userKeyShare.toString('base64'),
776
+ walletPassphrase,
777
+ });
778
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
779
+ txRequest: baseTxRequest,
780
+ prv: userKeyShare.toString('base64'),
781
+ walletPassphrase,
782
+ });
783
+ const messageBuffer = Buffer.from(signableHex, 'hex');
784
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
785
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
786
+ const txRequestRound1 = await signBitgoEddsaRound1(bitgoDsg, cloneTxRequestWithEmptySignatureShares(baseTxRequest), round1.signatureShareRound1, round1.userGpgPubKey, bitgoGpgPrivKey);
787
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound2Share({
788
+ txRequest: txRequestRound1,
789
+ walletPassphrase,
790
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
791
+ encryptedUserGpgPrvKey: round1Other.encryptedUserGpgPrvKey,
792
+ encryptedRound1Session: round1.encryptedRound1Session,
793
+ }), /Adata does not match cyphertext adata/);
794
+ });
795
+ it('should reject when BitGo signature share is missing', async () => {
796
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
797
+ txRequest: baseTxRequest,
798
+ prv: userKeyShare.toString('base64'),
799
+ walletPassphrase,
800
+ });
801
+ const baseTransaction = assertSingleTransaction(baseTxRequest);
802
+ const txRequestNoBitgoShare = {
803
+ ...baseTxRequest,
804
+ transactions: [
805
+ {
806
+ ...baseTransaction,
807
+ signatureShares: [round1.signatureShareRound1],
808
+ },
809
+ ],
810
+ };
811
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound2Share({
812
+ txRequest: txRequestNoBitgoShare,
813
+ walletPassphrase,
814
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
815
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
816
+ encryptedRound1Session: round1.encryptedRound1Session,
817
+ }), /Missing BitGo round1Output signature share/);
818
+ });
819
+ it('should propagate the tx-only guard when transactions are missing', async () => {
820
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
821
+ txRequest: baseTxRequest,
822
+ prv: userKeyShare.toString('base64'),
823
+ walletPassphrase,
824
+ });
825
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound2Share({
826
+ txRequest: { ...baseTxRequest, transactions: undefined },
827
+ walletPassphrase,
828
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
829
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
830
+ encryptedRound1Session: round1.encryptedRound1Session,
831
+ }), /Unable to find transactions in txRequest/);
832
+ });
833
+ it('should reject when transactions array is empty', async () => {
834
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
835
+ txRequest: baseTxRequest,
836
+ prv: userKeyShare.toString('base64'),
837
+ walletPassphrase,
838
+ });
839
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound2Share({
840
+ txRequest: { ...baseTxRequest, transactions: [] },
841
+ walletPassphrase,
842
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
843
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
844
+ encryptedRound1Session: round1.encryptedRound1Session,
845
+ }), /Unable to find transactions in txRequest/);
846
+ });
847
+ });
848
+ describe('EddsaMPCv2Utils.createOfflineRound3Share', () => {
849
+ let eddsaMPCv2Utils;
850
+ let mockBitgo;
851
+ let userKeyShare;
852
+ let bitgoKeyShare;
853
+ let bitgoGpgKeyPair;
854
+ let bitgoGpgPrivKey;
855
+ const walletPassphrase = 'testPass';
856
+ const signableHex = 'deadbeef';
857
+ const derivationPath = 'm/0/0';
858
+ const baseTxRequest = {
859
+ txRequestId: 'txreq-eddsa-round3',
860
+ walletId: 'wallet-eddsa-round3',
861
+ enterpriseId: 'enterprise-eddsa-round3',
862
+ apiVersion: 'full',
863
+ transactions: [
864
+ {
865
+ unsignedTx: {
866
+ signableHex,
867
+ derivationPath,
868
+ serializedTxHex: signableHex,
869
+ },
870
+ signatureShares: [],
871
+ },
872
+ ],
873
+ intent: { intentType: 'payment' },
874
+ unsignedTxs: [],
875
+ };
876
+ before('generate EdDSA key shares and GPG keys', async () => {
877
+ const [userDkg, , bitgoDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
878
+ userKeyShare = userDkg.getKeyShare();
879
+ bitgoKeyShare = bitgoDkg.getKeyShare();
880
+ bitgoGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
881
+ bitgoGpgPrivKey = await pgp.readPrivateKey({ armoredKey: bitgoGpgKeyPair.privateKey });
882
+ });
883
+ beforeEach(() => {
884
+ mockBitgo = {
885
+ encrypt: sinon.stub().callsFake(async (params) => {
886
+ const salt = (0, crypto_1.randomBytes)(8);
887
+ const iv = (0, crypto_1.randomBytes)(16);
888
+ return sjcl.encrypt(params.password, params.input, {
889
+ salt: [bytesToWord(salt.subarray(0, 4)), bytesToWord(salt.subarray(4))],
890
+ iv: [
891
+ bytesToWord(iv.subarray(0, 4)),
892
+ bytesToWord(iv.subarray(4, 8)),
893
+ bytesToWord(iv.subarray(8, 12)),
894
+ bytesToWord(iv.subarray(12, 16)),
895
+ ],
896
+ adata: params.adata,
897
+ });
898
+ }),
899
+ decrypt: sinon.stub().callsFake(async (params) => sjcl.decrypt(params.password, params.input)),
900
+ };
901
+ const mockCoin = {
902
+ getMPCAlgorithm: sinon.stub().returns('eddsa'),
903
+ };
904
+ eddsaMPCv2Utils = new src_1.EddsaMPCv2Utils(mockBitgo, mockCoin);
905
+ });
906
+ async function createRound2Flow(txRequest, encryptedPrv) {
907
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
908
+ txRequest,
909
+ prv: userKeyShare.toString('base64'),
910
+ walletPassphrase,
911
+ encryptedPrv,
912
+ });
913
+ const transaction = assertSingleTransaction(txRequest);
914
+ const messageBuffer = Buffer.from(transaction.unsignedTx.signableHex, 'hex');
915
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
916
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, transaction.unsignedTx.derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
917
+ const txRequestRound1 = await signBitgoEddsaRound1(bitgoDsg, cloneTxRequestWithEmptySignatureShares(txRequest), round1.signatureShareRound1, round1.userGpgPubKey, bitgoGpgPrivKey);
918
+ const round2 = await eddsaMPCv2Utils.createOfflineRound2Share({
919
+ txRequest: txRequestRound1,
920
+ walletPassphrase,
921
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
922
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
923
+ encryptedRound1Session: round1.encryptedRound1Session,
924
+ });
925
+ const round1Transaction = assertSingleTransaction(txRequestRound1);
926
+ const txRequestRound2 = await signBitgoEddsaRound2(bitgoDsg, {
927
+ ...txRequestRound1,
928
+ transactions: [
929
+ {
930
+ ...round1Transaction,
931
+ signatureShares: [...round1Transaction.signatureShares],
932
+ },
933
+ ],
934
+ }, round2.signatureShareRound2, round1.userGpgPubKey, bitgoGpgPrivKey);
935
+ return { round1, round2, txRequestRound1, txRequestRound2, messageBuffer };
936
+ }
937
+ it('should create a round-3 share from offline round 2', async () => {
938
+ const { round1, round2, txRequestRound2 } = await createRound2Flow(baseTxRequest);
939
+ const round3 = await eddsaMPCv2Utils.createOfflineRound3Share({
940
+ txRequest: txRequestRound2,
941
+ walletPassphrase,
942
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
943
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
944
+ encryptedRound2Session: round2.encryptedRound2Session,
945
+ });
946
+ assert.strictEqual(round3.signatureShareRound3.from, src_1.SignatureShareType.USER);
947
+ assert.strictEqual(round3.signatureShareRound3.to, src_1.SignatureShareType.BITGO);
948
+ const parsedShare = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound3Input, JSON.parse(round3.signatureShareRound3.share), 'EddsaMPCv2SignatureShareRound3Input');
949
+ assert.strictEqual(parsedShare.type, 'round3Input');
950
+ assert.ok(parsedShare.data.msg3.message, 'msg3.message should be set');
951
+ assert.ok(parsedShare.data.msg3.signature, 'msg3.signature should be set');
952
+ });
953
+ it('should use v2 decryption when encryptedRound2Session is a v2 envelope', async () => {
954
+ const encrypt = sinon
955
+ .stub()
956
+ .callsFake((input, adata) => Promise.resolve(JSON.stringify({ v: 2, input, adata })));
957
+ const destroy = sinon.stub();
958
+ const createEncryptionSession = sinon.stub().resolves({ encrypt, destroy });
959
+ mockBitgo.createEncryptionSession = createEncryptionSession;
960
+ const decrypt = sinon.stub().callsFake(async (params) => {
961
+ const envelope = JSON.parse(params.input);
962
+ return envelope.input;
963
+ });
964
+ mockBitgo.decrypt = decrypt;
965
+ const { round1, round2, txRequestRound2 } = await createRound2Flow(baseTxRequest, JSON.stringify({ v: 2 }));
966
+ const round3 = await eddsaMPCv2Utils.createOfflineRound3Share({
967
+ txRequest: txRequestRound2,
968
+ walletPassphrase,
969
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
970
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
971
+ encryptedRound2Session: round2.encryptedRound2Session,
972
+ });
973
+ assert.strictEqual(mockBitgo.decrypt.callCount, 4);
974
+ assert.strictEqual(round3.signatureShareRound3.from, src_1.SignatureShareType.USER);
975
+ });
976
+ it('should reject tampered encryptedRound2Session adata', async () => {
977
+ const otherTxRequest = {
978
+ ...baseTxRequest,
979
+ transactions: [
980
+ {
981
+ unsignedTx: {
982
+ signableHex: 'cafebabe',
983
+ derivationPath: 'm/1/2',
984
+ serializedTxHex: 'cafebabe',
985
+ },
986
+ signatureShares: [],
987
+ },
988
+ ],
989
+ };
990
+ const otherFlow = await createRound2Flow(otherTxRequest);
991
+ const { round1, txRequestRound2 } = await createRound2Flow(baseTxRequest);
992
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound3Share({
993
+ txRequest: txRequestRound2,
994
+ walletPassphrase,
995
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
996
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
997
+ encryptedRound2Session: otherFlow.round2.encryptedRound2Session,
998
+ }), /Adata does not match cyphertext adata/);
999
+ });
1000
+ it('should reject tampered encryptedUserGpgPrvKey adata', async () => {
1001
+ const otherTxRequest = {
1002
+ ...baseTxRequest,
1003
+ transactions: [
1004
+ {
1005
+ unsignedTx: {
1006
+ signableHex: 'cafebabe',
1007
+ derivationPath: 'm/1/2',
1008
+ serializedTxHex: 'cafebabe',
1009
+ },
1010
+ signatureShares: [],
1011
+ },
1012
+ ],
1013
+ };
1014
+ const otherFlow = await createRound2Flow(otherTxRequest);
1015
+ const { round2, txRequestRound2 } = await createRound2Flow(baseTxRequest);
1016
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound3Share({
1017
+ txRequest: txRequestRound2,
1018
+ walletPassphrase,
1019
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
1020
+ encryptedUserGpgPrvKey: otherFlow.round1.encryptedUserGpgPrvKey,
1021
+ encryptedRound2Session: round2.encryptedRound2Session,
1022
+ }), /Adata does not match cyphertext adata/);
1023
+ });
1024
+ it('should reject when BitGo round-2 signature share is missing', async () => {
1025
+ const { round1, round2, txRequestRound1 } = await createRound2Flow(baseTxRequest);
1026
+ const round1Transaction = assertSingleTransaction(txRequestRound1);
1027
+ const txRequestNoBitgoRound2Share = {
1028
+ ...txRequestRound1,
1029
+ transactions: [
1030
+ {
1031
+ ...round1Transaction,
1032
+ signatureShares: [...round1Transaction.signatureShares, round2.signatureShareRound2],
1033
+ },
1034
+ ],
1035
+ };
1036
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound3Share({
1037
+ txRequest: txRequestNoBitgoRound2Share,
1038
+ walletPassphrase,
1039
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
1040
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
1041
+ encryptedRound2Session: round2.encryptedRound2Session,
1042
+ }), /Missing BitGo round2Output signature share/);
1043
+ });
1044
+ it('should propagate the tx-only guard when transactions are missing', async () => {
1045
+ const { round1, round2 } = await createRound2Flow(baseTxRequest);
1046
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound3Share({
1047
+ txRequest: { ...baseTxRequest, transactions: undefined },
1048
+ walletPassphrase,
1049
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
1050
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
1051
+ encryptedRound2Session: round2.encryptedRound2Session,
1052
+ }), /Unable to find transactions in txRequest/);
1053
+ });
1054
+ it('should reject when transactions array is empty', async () => {
1055
+ const { round1, round2 } = await createRound2Flow(baseTxRequest);
1056
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound3Share({
1057
+ txRequest: { ...baseTxRequest, transactions: [] },
1058
+ walletPassphrase,
1059
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
1060
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
1061
+ encryptedRound2Session: round2.encryptedRound2Session,
1062
+ }), /Unable to find transactions in txRequest/);
1063
+ });
1064
+ });
1065
+ describe('getBitgoSignatureShare', () => {
1066
+ const round1OutputShare = {
1067
+ from: src_1.SignatureShareType.BITGO,
1068
+ to: src_1.SignatureShareType.USER,
1069
+ share: JSON.stringify({ type: 'round1Output', data: {} }),
1070
+ };
1071
+ const round2OutputShare = {
1072
+ from: src_1.SignatureShareType.BITGO,
1073
+ to: src_1.SignatureShareType.USER,
1074
+ share: JSON.stringify({ type: 'round2Output', data: {} }),
1075
+ };
1076
+ it('selects the requested BitGo round output when multiple round outputs are present', () => {
1077
+ const signatureShares = [round1OutputShare, round2OutputShare];
1078
+ assert.strictEqual((0, common_1.getBitgoSignatureShare)(signatureShares, src_1.SignatureShareType.USER, 'round2Output'), round2OutputShare);
1079
+ assert.strictEqual((0, common_1.getBitgoSignatureShare)(signatureShares, src_1.SignatureShareType.USER, 'round1Output'), round1OutputShare);
1080
+ });
1081
+ it('skips malformed share records while selecting the requested BitGo round output', () => {
1082
+ const malformedShare = {
1083
+ from: src_1.SignatureShareType.BITGO,
1084
+ to: src_1.SignatureShareType.USER,
1085
+ share: 'not-json',
1086
+ };
1087
+ assert.strictEqual((0, common_1.getBitgoSignatureShare)([malformedShare, round2OutputShare], src_1.SignatureShareType.USER, 'round2Output'), round2OutputShare);
1088
+ });
1089
+ });
1090
+ function assertSingleTransaction(txRequest) {
1091
+ assert.ok(txRequest.transactions, 'txRequest must include transactions');
1092
+ assert.strictEqual(txRequest.transactions.length, 1, 'txRequest must have exactly one transaction');
1093
+ return txRequest.transactions[0];
1094
+ }
1095
+ function cloneTxRequestWithEmptySignatureShares(txRequest) {
1096
+ const transaction = assertSingleTransaction(txRequest);
1097
+ return {
1098
+ ...txRequest,
1099
+ transactions: [{ ...transaction, signatureShares: [] }],
1100
+ };
1101
+ }
1102
+ async function signBitgoEddsaRound1(bitgoDsg, txRequest, userRound1Share, userGpgPubKeyArmored, bitgoGpgPrivKey) {
1103
+ const transaction = assertSingleTransaction(txRequest);
1104
+ transaction.signatureShares.push(userRound1Share);
1105
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
1106
+ const parsedUserShare = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound1Input, JSON.parse(userRound1Share.share), 'EddsaMPCv2SignatureShareRound1Input');
1107
+ const userGpgKey = await pgp.readKey({ armoredKey: userGpgPubKeyArmored });
1108
+ const userRawMsg1Bytes = await sdk_lib_mpc_1.MPSComms.verifyMpsMessage(parsedUserShare.data.msg1, userGpgKey);
1109
+ const userMsg1 = {
1110
+ from: typesMPCv2_1.MPCv2PartiesEnum.USER,
1111
+ payload: new Uint8Array(userRawMsg1Bytes),
1112
+ };
1113
+ const [bitgoMsg2] = bitgoDsg.handleIncomingMessages([bitgoMsg1, userMsg1]);
1114
+ assert.ok(bitgoMsg2, 'BitGo DSG produced no round-2 output');
1115
+ bitgoDsg.round2Message = bitgoMsg2;
1116
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
1117
+ const round1Output = {
1118
+ type: 'round1Output',
1119
+ data: { msg1: bitgoSignedMsg1 },
1120
+ };
1121
+ transaction.signatureShares.push({
1122
+ from: src_1.SignatureShareType.BITGO,
1123
+ to: src_1.SignatureShareType.USER,
1124
+ share: JSON.stringify(round1Output),
1125
+ });
1126
+ return txRequest;
1127
+ }
1128
+ async function signBitgoEddsaRound2(bitgoDsg, txRequest, userRound2Share, userGpgPubKeyArmored, bitgoGpgPrivKey) {
1129
+ const transaction = assertSingleTransaction(txRequest);
1130
+ transaction.signatureShares.push(userRound2Share);
1131
+ const userGpgKey = await pgp.readKey({ armoredKey: userGpgPubKeyArmored });
1132
+ const bitgoMsg2 = bitgoDsg.round2Message;
1133
+ assert.ok(bitgoMsg2, 'BitGo DSG is missing the cached round-2 output');
1134
+ const parsedUserRound2Share = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound2Input, JSON.parse(userRound2Share.share), 'EddsaMPCv2SignatureShareRound2Input');
1135
+ const userRawMsg2Bytes = await sdk_lib_mpc_1.MPSComms.verifyMpsMessage(parsedUserRound2Share.data.msg2, userGpgKey);
1136
+ const userMsg2 = {
1137
+ from: typesMPCv2_1.MPCv2PartiesEnum.USER,
1138
+ payload: new Uint8Array(userRawMsg2Bytes),
1139
+ };
1140
+ const bitgoSignedMsg2 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg2.payload), bitgoGpgPrivKey);
1141
+ const round2Output = {
1142
+ type: 'round2Output',
1143
+ data: { msg2: bitgoSignedMsg2 },
1144
+ };
1145
+ transaction.signatureShares.push({
1146
+ from: src_1.SignatureShareType.BITGO,
1147
+ to: src_1.SignatureShareType.USER,
1148
+ share: JSON.stringify(round2Output),
1149
+ });
1150
+ bitgoDsg.handleIncomingMessages([bitgoMsg2, userMsg2]);
1151
+ return txRequest;
1152
+ }
1153
+ describe('EddsaMPCv2Utils.signEddsaMPCv2TssUsingExternalSigner', () => {
1154
+ let sandbox;
1155
+ let eddsaMPCv2Utils;
1156
+ let mockBitgo;
1157
+ let bitgoGpgKeyPair;
1158
+ let bitgoGpgPubKey;
1159
+ const walletId = 'abc123wallet';
1160
+ const txRequestId = 'txreq-001';
1161
+ const enterpriseId = 'ent-001';
1162
+ const mockTxRequest = {
1163
+ txRequestId,
1164
+ walletId,
1165
+ enterpriseId,
1166
+ apiVersion: 'full',
1167
+ transactions: [
1168
+ {
1169
+ unsignedTx: {
1170
+ signableHex: 'deadbeef',
1171
+ derivationPath: 'm/0',
1172
+ serializedTxHex: 'deadbeef',
1173
+ },
1174
+ signatureShares: [
1175
+ {
1176
+ from: src_1.SignatureShareType.BITGO,
1177
+ to: src_1.SignatureShareType.USER,
1178
+ share: JSON.stringify({ type: 'round1Output', data: {} }),
1179
+ },
1180
+ ],
1181
+ },
1182
+ ],
1183
+ intent: { intentType: 'payment' },
1184
+ unsignedTxs: [],
1185
+ };
1186
+ const mockTxRequestTransaction = assertSingleTransaction(mockTxRequest);
1187
+ const mockTxRequestRound2 = {
1188
+ ...mockTxRequest,
1189
+ transactions: [
1190
+ {
1191
+ ...mockTxRequestTransaction,
1192
+ signatureShares: [
1193
+ {
1194
+ from: src_1.SignatureShareType.BITGO,
1195
+ to: src_1.SignatureShareType.USER,
1196
+ share: JSON.stringify({ type: 'round2Output', data: {} }),
1197
+ },
1198
+ ],
1199
+ },
1200
+ ],
1201
+ };
1202
+ const dummyShare = {
1203
+ from: src_1.SignatureShareType.USER,
1204
+ to: src_1.SignatureShareType.BITGO,
1205
+ share: JSON.stringify({ type: 'round1Input', data: {} }),
1206
+ };
1207
+ // Returns a chain compatible with: bitgo.post(url).send(body).result()
1208
+ const makePostChain = (response) => ({ send: () => ({ result: sinon.stub().resolves(response) }) });
1209
+ // Returns a chain compatible with: bitgo.get(url).query(params).retry(n).result()
1210
+ const makeGetChain = (txRequests) => ({
1211
+ query: () => ({
1212
+ retry: () => ({ result: sinon.stub().resolves({ txRequests }) }),
1213
+ }),
1214
+ });
1215
+ before(async () => {
1216
+ bitgoGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
1217
+ bitgoGpgPubKey = await pgp.readKey({ armoredKey: bitgoGpgKeyPair.publicKey });
1218
+ });
1219
+ beforeEach(async () => {
1220
+ sandbox = sinon.createSandbox();
1221
+ // Full mock of the BitGo HTTP client (consistent with other sdk-core tests such as
1222
+ // tokenApproval.ts and walletsEvmKeyring.ts). Module-level stubs on tssCommon functions
1223
+ // do not work under tsx 4.x (ESM live bindings), so we mock at the bitgo object level.
1224
+ mockBitgo = {
1225
+ getEnv: sinon.stub().returns('test'),
1226
+ setRequestTracer: sinon.stub(),
1227
+ url: sinon.stub().callsFake((path) => `https://test.bitgo.com${path}`),
1228
+ post: sinon.stub(),
1229
+ get: sinon.stub(),
1230
+ };
1231
+ const mockCoin = {
1232
+ getMPCAlgorithm: sinon.stub().returns('eddsa'),
1233
+ };
1234
+ const mockWallet = {
1235
+ id: sinon.stub().returns(walletId),
1236
+ keyIds: sinon.stub().returns(['userKeyId', 'backupKeyId', 'bitgoKeyId']),
1237
+ multisigTypeVersion: sinon.stub().returns('MPCv2'),
1238
+ };
1239
+ eddsaMPCv2Utils = new src_1.EddsaMPCv2Utils(mockBitgo, mockCoin, mockWallet);
1240
+ sandbox.stub(eddsaMPCv2Utils, 'pickBitgoPubGpgKeyForSigning').resolves(bitgoGpgPubKey);
1241
+ });
1242
+ afterEach(() => {
1243
+ sandbox.restore();
1244
+ });
1245
+ it('should call all 3 generators and return the final tx request', async () => {
1246
+ const finalTxRequest = { ...mockTxRequest, txRequestId };
1247
+ // sendSignatureShareV2 is called 3 times (one per round), sendTxRequest once — all use bitgo.post
1248
+ mockBitgo.post
1249
+ .onCall(0)
1250
+ .returns(makePostChain(mockTxRequest)) // round 1 sign
1251
+ .onCall(1)
1252
+ .returns(makePostChain(mockTxRequestRound2)) // round 2 sign
1253
+ .onCall(2)
1254
+ .returns(makePostChain(mockTxRequestRound2)) // round 3 sign
1255
+ .onCall(3)
1256
+ .returns(makePostChain(finalTxRequest)); // sendTxRequest (send)
1257
+ const encryptedRound1Session = 'encrypted-r1-session';
1258
+ const encryptedRound2Session = 'encrypted-r2-session';
1259
+ const encryptedUserGpgPrvKey = 'encrypted-gpg-key';
1260
+ const userGpgPubKey = bitgoGpgKeyPair.publicKey;
1261
+ const round1Share = { ...dummyShare };
1262
+ const round2Share = { ...dummyShare, share: JSON.stringify({ type: 'round2Input' }) };
1263
+ const round3Share = { ...dummyShare, share: JSON.stringify({ type: 'round3Input' }) };
1264
+ const round1Generator = sinon
1265
+ .stub()
1266
+ .resolves({ signatureShareRound1: round1Share, userGpgPubKey, encryptedRound1Session, encryptedUserGpgPrvKey });
1267
+ const round2Generator = sinon.stub().resolves({ signatureShareRound2: round2Share, encryptedRound2Session });
1268
+ const round3Generator = sinon.stub().resolves({ signatureShareRound3: round3Share });
1269
+ const result = await eddsaMPCv2Utils.signEddsaMPCv2TssUsingExternalSigner({ txRequest: mockTxRequest, reqId: new src_1.RequestTracer() }, round1Generator, round2Generator, round3Generator);
1270
+ assert.deepStrictEqual(result, finalTxRequest);
1271
+ sinon.assert.calledOnce(round1Generator);
1272
+ sinon.assert.calledWith(round1Generator, { txRequest: mockTxRequest });
1273
+ sinon.assert.calledOnce(round2Generator);
1274
+ const round2Call = round2Generator.getCall(0);
1275
+ assert.strictEqual(round2Call.args[0].txRequest, mockTxRequest);
1276
+ assert.strictEqual(round2Call.args[0].encryptedRound1Session, encryptedRound1Session);
1277
+ assert.strictEqual(round2Call.args[0].encryptedUserGpgPrvKey, encryptedUserGpgPrvKey);
1278
+ assert.strictEqual(round2Call.args[0].bitgoPublicGpgKey, bitgoGpgPubKey.armor());
1279
+ sinon.assert.calledOnce(round3Generator);
1280
+ const round3Call = round3Generator.getCall(0);
1281
+ assert.strictEqual(round3Call.args[0].txRequest, mockTxRequestRound2);
1282
+ assert.strictEqual(round3Call.args[0].encryptedRound2Session, encryptedRound2Session);
1283
+ assert.strictEqual(round3Call.args[0].encryptedUserGpgPrvKey, encryptedUserGpgPrvKey);
1284
+ assert.strictEqual(round3Call.args[0].bitgoPublicGpgKey, bitgoGpgPubKey.armor());
1285
+ // 3 sendSignatureShareV2 calls + 1 sendTxRequest = 4 POST calls total
1286
+ assert.strictEqual(mockBitgo.post.callCount, 4);
1287
+ });
1288
+ it('should resolve txRequest by ID string using getTxRequest', async () => {
1289
+ // getTxRequest uses bitgo.get; sendSignatureShareV2 (×3) + sendTxRequest use bitgo.post
1290
+ mockBitgo.get.returns(makeGetChain([mockTxRequest]));
1291
+ mockBitgo.post
1292
+ .onCall(0)
1293
+ .returns(makePostChain(mockTxRequest))
1294
+ .onCall(1)
1295
+ .returns(makePostChain(mockTxRequestRound2))
1296
+ .onCall(2)
1297
+ .returns(makePostChain(mockTxRequestRound2))
1298
+ .onCall(3)
1299
+ .returns(makePostChain(mockTxRequest));
1300
+ const round1Generator = sinon.stub().resolves({
1301
+ signatureShareRound1: dummyShare,
1302
+ userGpgPubKey: bitgoGpgKeyPair.publicKey,
1303
+ encryptedRound1Session: 'r1',
1304
+ encryptedUserGpgPrvKey: 'key',
1305
+ });
1306
+ const round2Generator = sinon.stub().resolves({ signatureShareRound2: dummyShare, encryptedRound2Session: 'r2' });
1307
+ const round3Generator = sinon.stub().resolves({ signatureShareRound3: dummyShare });
1308
+ await eddsaMPCv2Utils.signEddsaMPCv2TssUsingExternalSigner({ txRequest: txRequestId, reqId: new src_1.RequestTracer() }, round1Generator, round2Generator, round3Generator);
1309
+ sinon.assert.calledOnce(mockBitgo.get);
1310
+ sinon.assert.calledWith(round1Generator, { txRequest: mockTxRequest });
1311
+ });
1312
+ it('should throw when round 2 txRequest is missing signatureShares', async () => {
1313
+ const round2NoShares = {
1314
+ ...mockTxRequest,
1315
+ transactions: [{ ...mockTxRequestTransaction, signatureShares: undefined }],
1316
+ };
1317
+ mockBitgo.post
1318
+ .onCall(0)
1319
+ .returns(makePostChain(mockTxRequest))
1320
+ .onCall(1)
1321
+ .returns(makePostChain(round2NoShares));
1322
+ const round1Generator = sinon.stub().resolves({
1323
+ signatureShareRound1: dummyShare,
1324
+ userGpgPubKey: bitgoGpgKeyPair.publicKey,
1325
+ encryptedRound1Session: 'r1',
1326
+ encryptedUserGpgPrvKey: 'key',
1327
+ });
1328
+ const round2Generator = sinon.stub().resolves({ signatureShareRound2: dummyShare, encryptedRound2Session: 'r2' });
1329
+ const round3Generator = sinon.stub().resolves({ signatureShareRound3: dummyShare });
1330
+ await assert.rejects(() => eddsaMPCv2Utils.signEddsaMPCv2TssUsingExternalSigner({ txRequest: mockTxRequest, reqId: new src_1.RequestTracer() }, round1Generator, round2Generator, round3Generator), /Missing signature shares in round 2 txRequest/);
1331
+ });
1332
+ it('should pass armored BitGo public GPG key to round 2 and round 3 generators', async () => {
1333
+ mockBitgo.post
1334
+ .onCall(0)
1335
+ .returns(makePostChain(mockTxRequest))
1336
+ .onCall(1)
1337
+ .returns(makePostChain(mockTxRequestRound2))
1338
+ .onCall(2)
1339
+ .returns(makePostChain(mockTxRequestRound2))
1340
+ .onCall(3)
1341
+ .returns(makePostChain(mockTxRequest));
1342
+ const round1Generator = sinon.stub().resolves({
1343
+ signatureShareRound1: dummyShare,
1344
+ userGpgPubKey: bitgoGpgKeyPair.publicKey,
1345
+ encryptedRound1Session: 'r1',
1346
+ encryptedUserGpgPrvKey: 'key',
1347
+ });
1348
+ const round2Generator = sinon.stub().resolves({ signatureShareRound2: dummyShare, encryptedRound2Session: 'r2' });
1349
+ const round3Generator = sinon.stub().resolves({ signatureShareRound3: dummyShare });
1350
+ await eddsaMPCv2Utils.signEddsaMPCv2TssUsingExternalSigner({ txRequest: mockTxRequest, reqId: new src_1.RequestTracer() }, round1Generator, round2Generator, round3Generator);
1351
+ const armoredKey = bitgoGpgPubKey.armor();
1352
+ assert.strictEqual(round2Generator.getCall(0).args[0].bitgoPublicGpgKey, armoredKey, 'round 2 should receive armored BitGo GPG key');
1353
+ assert.strictEqual(round3Generator.getCall(0).args[0].bitgoPublicGpgKey, armoredKey, 'round 3 should receive armored BitGo GPG key');
1354
+ });
1355
+ });
1356
+ function bytesToWord(bytes) {
1357
+ if (!(bytes instanceof Uint8Array) || bytes.length !== 4) {
1358
+ throw new Error('bytes must be a Uint8Array with length 4');
1359
+ }
1360
+ return bytes.reduce((num, byte) => num * 0x100 + byte, 0);
1361
+ }
1362
+ describe('EDDSAUtils.isEddsaMpcV1SigningMaterial', () => {
1363
+ const PASSPHRASE = 'test-passphrase';
1364
+ const MPCv1_MATERIAL_BACKUP = {
1365
+ uShare: { i: 1, t: 2, n: 3, y: 'aabbcc', seed: 'deadbeef01234567', chaincode: '00' },
1366
+ bitgoYShare: { i: 3, j: 1, y: 'aabbcc', u: 'bitgo-u-value', chaincode: '00' },
1367
+ backupYShare: { i: 2, j: 1, y: 'aabbcc', u: 'backup-u-value', chaincode: '00' },
1368
+ };
1369
+ const MPCv1_MATERIAL_USER = {
1370
+ uShare: { i: 2, t: 2, n: 3, y: 'aabbcc', seed: 'deadbeef01234567', chaincode: '00' },
1371
+ bitgoYShare: { i: 3, j: 2, y: 'aabbcc', u: 'bitgo-u-value', chaincode: '00' },
1372
+ userYShare: { i: 1, j: 2, y: 'aabbcc', u: 'user-u-value', chaincode: '00' },
1373
+ };
1374
+ const MPCv2_CBOR_BYTES = Buffer.from([0xd9, 0x01, 0x04, 0xa3, 0x61, 0x78, 0x18, 0x00]).toString('base64');
1375
+ let mockBitgo;
1376
+ beforeEach(() => {
1377
+ // sdk-core has no devDependency on sdk-api/argon2, so v2 envelopes are simulated here.
1378
+ // Real bitgo.decrypt routes v2 to Argon2id; the stub returns MPCv2 CBOR plaintext instead.
1379
+ mockBitgo = {
1380
+ decrypt: sinon.stub().callsFake(async (params) => {
1381
+ if ((0, baseTypes_1.isV2Envelope)(params.input)) {
1382
+ return MPCv2_CBOR_BYTES;
1383
+ }
1384
+ return sjcl.decrypt(params.password, params.input);
1385
+ }),
1386
+ };
1387
+ });
1388
+ it('returns true for MPCv1 SJCL-encrypted keycard with backupYShare + correct passphrase', async () => {
1389
+ const encrypted = sjcl.encrypt(PASSPHRASE, JSON.stringify(MPCv1_MATERIAL_BACKUP));
1390
+ assert.strictEqual(await src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(encrypted, PASSPHRASE), true);
1391
+ });
1392
+ it('returns true for MPCv1 SJCL-encrypted keycard with userYShare + correct passphrase', async () => {
1393
+ const encrypted = sjcl.encrypt(PASSPHRASE, JSON.stringify(MPCv1_MATERIAL_USER));
1394
+ assert.strictEqual(await src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(encrypted, PASSPHRASE), true);
1395
+ });
1396
+ it('returns false for MPCv2 CBOR content wrapped in SJCL envelope + correct passphrase', async () => {
1397
+ const encrypted = sjcl.encrypt(PASSPHRASE, MPCv2_CBOR_BYTES);
1398
+ assert.strictEqual(await src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(encrypted, PASSPHRASE), false);
1399
+ });
1400
+ it('returns false for MPCv2 Argon2id envelope (v2) + correct passphrase (forward-compat)', async () => {
1401
+ const fakeV2Envelope = JSON.stringify({ v: 2, m: 65536, t: 3, p: 4, salt: 'AAAA', iv: 'AAAA', ct: 'AAAA' });
1402
+ assert.strictEqual(await src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(fakeV2Envelope, PASSPHRASE, mockBitgo), false);
1403
+ });
1404
+ it('throws on wrong passphrase', async () => {
1405
+ const encrypted = sjcl.encrypt(PASSPHRASE, JSON.stringify(MPCv1_MATERIAL_BACKUP));
1406
+ await assert.rejects(src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(encrypted, 'wrong-passphrase'), /ccm: tag doesn't match/);
1407
+ });
1408
+ it('returns false when neither backupYShare.u nor userYShare.u is present', async () => {
1409
+ const partial = { uShare: { seed: 'abc' }, bitgoYShare: { u: 'xyz' } };
1410
+ const encrypted = sjcl.encrypt(PASSPHRASE, JSON.stringify(partial));
1411
+ assert.strictEqual(await src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(encrypted, PASSPHRASE), false);
1412
+ });
1413
+ });
1414
+ describe('signRecoveryEddsaMPCv2', () => {
1415
+ const derivationPath = 'm/0/0';
1416
+ it('should return a 64-byte signature that verifies against the derived public key', async () => {
1417
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
1418
+ const message = Buffer.from('deadbeef', 'hex');
1419
+ const commonKeyChain = userDkg.getCommonKeychain();
1420
+ const signature = await src_1.EDDSAUtils.signRecoveryEddsaMPCv2(message, derivationPath, userDkg.getKeyShare(), backupDkg.getKeyShare(), commonKeyChain);
1421
+ assert.strictEqual(signature.length, 64);
1422
+ const mpc = await (0, eddsa_1.getInitializedMpcInstance)();
1423
+ const derivedKeychain = mpc.deriveUnhardened(commonKeyChain, derivationPath);
1424
+ const publicKeyBytes = Buffer.from(derivedKeychain.slice(0, 64), 'hex');
1425
+ const ok = ed25519_1.ed25519.verify(new Uint8Array(signature), new Uint8Array(message), new Uint8Array(publicKeyBytes));
1426
+ assert.strictEqual(ok, true);
1427
+ });
1428
+ it('should return false when verifying the signature against a different message', async () => {
1429
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
1430
+ const message = Buffer.from('deadbeef', 'hex');
1431
+ const commonKeyChain = userDkg.getCommonKeychain();
1432
+ const signature = await src_1.EDDSAUtils.signRecoveryEddsaMPCv2(message, derivationPath, userDkg.getKeyShare(), backupDkg.getKeyShare(), commonKeyChain);
1433
+ const differentMessage = Buffer.from('cafebabe', 'hex');
1434
+ const mpc = await (0, eddsa_1.getInitializedMpcInstance)();
1435
+ const derivedKeychain = mpc.deriveUnhardened(commonKeyChain, derivationPath);
1436
+ const publicKeyBytes = Buffer.from(derivedKeychain.slice(0, 64), 'hex');
1437
+ const ok = ed25519_1.ed25519.verify(new Uint8Array(signature), new Uint8Array(differentMessage), new Uint8Array(publicKeyBytes));
1438
+ assert.strictEqual(ok, false);
1439
+ });
1440
+ it('should throw when a wrong commonKeyChain is provided (verification mismatch)', async () => {
1441
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
1442
+ const [wrongDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
1443
+ const message = Buffer.from('deadbeef', 'hex');
1444
+ await assert.rejects(() => src_1.EDDSAUtils.signRecoveryEddsaMPCv2(message, derivationPath, userDkg.getKeyShare(), backupDkg.getKeyShare(), wrongDkg.getCommonKeychain() // key chain from a different wallet
1445
+ ), /EdDSA MPCv2 recovery signature verification failed/);
1446
+ });
1447
+ });
1448
+ describe('getEddsaSigningMaterial', () => {
1449
+ const PASSPHRASE = 'test-passphrase';
1450
+ const MPCv1_MATERIAL = {
1451
+ uShare: { i: 1, t: 2, n: 3, y: 'aabbcc', seed: 'deadbeef01234567', chaincode: '00' },
1452
+ bitgoYShare: { i: 3, j: 1, y: 'aabbcc', u: 'bitgo-u-value', chaincode: '00' },
1453
+ backupYShare: { i: 2, j: 1, y: 'aabbcc', u: 'backup-u-value', chaincode: '00' },
1454
+ };
1455
+ it('returns { version: v1, userPrv } for MPCv1 JSON keycard', async () => {
1456
+ const encrypted = sjcl.encrypt(PASSPHRASE, JSON.stringify(MPCv1_MATERIAL));
1457
+ const decryptStub = sinon.stub().resolves(JSON.stringify(MPCv1_MATERIAL));
1458
+ const mockBitgo = { decrypt: decryptStub };
1459
+ const result = await (0, src_1.getEddsaSigningMaterial)(encrypted, PASSPHRASE, mockBitgo);
1460
+ assert.strictEqual(result.version, 'v1');
1461
+ assert.strictEqual(result.userPrv, JSON.stringify(MPCv1_MATERIAL));
1462
+ sinon.assert.calledOnce(decryptStub);
1463
+ sinon.assert.calledWithMatch(decryptStub, { input: sinon.match.string, password: PASSPHRASE });
1464
+ });
1465
+ it('returns { version: v2, encryptedUserKey } for MPCv2 CBOR keycard', async () => {
1466
+ const MPCv2_CBOR_BYTES = Buffer.from([0xd9, 0x01, 0x04, 0xa3, 0x61, 0x78, 0x18, 0x00]).toString('base64');
1467
+ const encrypted = sjcl.encrypt(PASSPHRASE, MPCv2_CBOR_BYTES);
1468
+ const normalizedKey = encrypted.replace(/\s/g, '');
1469
+ const result = await (0, src_1.getEddsaSigningMaterial)(encrypted, PASSPHRASE);
1470
+ assert.strictEqual(result.version, 'v2');
1471
+ assert.ok('encryptedUserKey' in result);
1472
+ assert.strictEqual(result.encryptedUserKey, normalizedKey);
1473
+ });
1474
+ it('throws with context message when decryption fails', async () => {
1475
+ const encrypted = sjcl.encrypt(PASSPHRASE, JSON.stringify(MPCv1_MATERIAL));
1476
+ await assert.rejects(() => (0, src_1.getEddsaSigningMaterial)(encrypted, 'wrong-passphrase'), /Error decrypting user keychain/);
1477
+ });
1478
+ it('returns v1 via sjcl fallback when bitgo is omitted', async () => {
1479
+ const encrypted = sjcl.encrypt(PASSPHRASE, JSON.stringify(MPCv1_MATERIAL));
1480
+ const result = await (0, src_1.getEddsaSigningMaterial)(encrypted, PASSPHRASE);
1481
+ assert.strictEqual(result.version, 'v1');
1482
+ assert.strictEqual(result.userPrv, JSON.stringify(MPCv1_MATERIAL));
1483
+ });
1484
+ });
1485
+ describe('isEddsaSigningMaterial', () => {
1486
+ it('returns true for a valid v1 shape', () => {
1487
+ assert.strictEqual((0, src_1.isEddsaSigningMaterial)({ version: 'v1', userPrv: '{}' }), true);
1488
+ });
1489
+ it('returns true for a valid v2 shape', () => {
1490
+ assert.strictEqual((0, src_1.isEddsaSigningMaterial)({ version: 'v2', encryptedUserKey: 'abc123' }), true);
1491
+ });
1492
+ it('returns false for a v1 shape with a non-string userPrv', () => {
1493
+ assert.strictEqual((0, src_1.isEddsaSigningMaterial)({ version: 'v1', userPrv: 123 }), false);
1494
+ });
1495
+ it('returns false for a v2 shape with a non-string encryptedUserKey', () => {
1496
+ assert.strictEqual((0, src_1.isEddsaSigningMaterial)({ version: 'v2', encryptedUserKey: 123 }), false);
1497
+ });
1498
+ it('returns false for an unrecognized version value', () => {
1499
+ assert.strictEqual((0, src_1.isEddsaSigningMaterial)({ version: 'v3', userPrv: '{}' }), false);
1500
+ });
1501
+ it('returns false for an object missing a version field', () => {
1502
+ assert.strictEqual((0, src_1.isEddsaSigningMaterial)({ userPrv: '{}' }), false);
1503
+ });
1504
+ it('returns false for null', () => {
1505
+ assert.strictEqual((0, src_1.isEddsaSigningMaterial)(null), false);
1506
+ });
1507
+ it('returns false for undefined', () => {
1508
+ assert.strictEqual((0, src_1.isEddsaSigningMaterial)(undefined), false);
1509
+ });
1510
+ it('returns false for primitive values', () => {
1511
+ assert.strictEqual((0, src_1.isEddsaSigningMaterial)('a string'), false);
1512
+ assert.strictEqual((0, src_1.isEddsaSigningMaterial)(42), false);
1513
+ assert.strictEqual((0, src_1.isEddsaSigningMaterial)(true), false);
1514
+ });
1515
+ it('returns false for an ArrayBuffer (regression: WRW openSSLBytes collision)', () => {
1516
+ // WRW's generic Electron 'recover' IPC handler passes openSSLBytes as a second
1517
+ // positional argument to every coin's recover(), colliding with precomputedMaterial
1518
+ // on coins that accept it. This must be rejected rather than misread as signing material.
1519
+ assert.strictEqual((0, src_1.isEddsaSigningMaterial)(new ArrayBuffer(8)), false);
1520
+ });
1521
+ });
1522
+ describe('signEddsaMpcV2RecoveryTx', () => {
1523
+ const derivationPath = 'm/0/0';
1524
+ const walletPassphrase = 'testPass';
1525
+ const makeDecryptBitgo = (userKeyBase64, backupKeyBase64) => ({
1526
+ decrypt: sinon.stub().onFirstCall().resolves(userKeyBase64).onSecondCall().resolves(backupKeyBase64),
1527
+ });
1528
+ it('returns a 64-byte signature that verifies against the derived public key', async () => {
1529
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
1530
+ const message = Buffer.from('deadbeef', 'hex');
1531
+ const commonKeyChain = userDkg.getCommonKeychain();
1532
+ const mockBitgo = makeDecryptBitgo(userDkg.getReducedKeyShare().toString('base64'), backupDkg.getReducedKeyShare().toString('base64'));
1533
+ const result = await (0, src_1.signEddsaMpcV2RecoveryTx)({
1534
+ message,
1535
+ userKey: 'encrypted-user-key',
1536
+ backupKey: 'encrypted-backup-key',
1537
+ walletPassphrase,
1538
+ bitgoKey: commonKeyChain,
1539
+ derivationPath,
1540
+ bitgo: mockBitgo,
1541
+ });
1542
+ assert.strictEqual(result.length, 64);
1543
+ const mpc = await (0, eddsa_1.getInitializedMpcInstance)();
1544
+ const derivedKeychain = mpc.deriveUnhardened(commonKeyChain, derivationPath);
1545
+ const publicKeyBytes = Buffer.from(derivedKeychain.slice(0, 64), 'hex');
1546
+ const ok = ed25519_1.ed25519.verify(new Uint8Array(result), new Uint8Array(message), new Uint8Array(publicKeyBytes));
1547
+ assert.strictEqual(ok, true);
1548
+ });
1549
+ it('throws when commonKeyChain does not match bitgoKey', async () => {
1550
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
1551
+ const message = Buffer.from('deadbeef', 'hex');
1552
+ const mockBitgo = makeDecryptBitgo(userDkg.getReducedKeyShare().toString('base64'), backupDkg.getReducedKeyShare().toString('base64'));
1553
+ await assert.rejects(() => (0, src_1.signEddsaMpcV2RecoveryTx)({
1554
+ message,
1555
+ userKey: 'encrypted-user-key',
1556
+ backupKey: 'encrypted-backup-key',
1557
+ walletPassphrase,
1558
+ bitgoKey: 'bbbb'.repeat(32),
1559
+ derivationPath,
1560
+ bitgo: mockBitgo,
1561
+ }), /commonKeyChain from keycard does not match bitgoKey/);
1562
+ });
1563
+ it('passes userKey, backupKey, passphrase, and bitgo to getEddsaMpcV2RecoveryKeySharesFromReducedKey', async () => {
1564
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
1565
+ const message = Buffer.from('deadbeef', 'hex');
1566
+ const decryptStub = sinon
1567
+ .stub()
1568
+ .onFirstCall()
1569
+ .resolves(userDkg.getReducedKeyShare().toString('base64'))
1570
+ .onSecondCall()
1571
+ .resolves(backupDkg.getReducedKeyShare().toString('base64'));
1572
+ const mockBitgo = { decrypt: decryptStub };
1573
+ await (0, src_1.signEddsaMpcV2RecoveryTx)({
1574
+ message,
1575
+ userKey: 'u-key',
1576
+ backupKey: 'b-key',
1577
+ walletPassphrase,
1578
+ bitgoKey: userDkg.getCommonKeychain(),
1579
+ derivationPath,
1580
+ bitgo: mockBitgo,
1581
+ });
1582
+ sinon.assert.calledWith(decryptStub.firstCall, { input: 'u-key', password: walletPassphrase });
1583
+ sinon.assert.calledWith(decryptStub.secondCall, { input: 'b-key', password: walletPassphrase });
1584
+ });
1585
+ });
1586
+ describe('EddsaMPCv2Utils.createKeychainsWithExternalSigner', function () {
1587
+ let utils;
1588
+ let callbacks;
1589
+ const enterprise = 'enterprise-id';
1590
+ const sessionId = 'session-001';
1591
+ const commonKeychain = 'common-keychain-hex';
1592
+ const userState = { encryptedData: 'u-data', encryptedDataKey: 'u-data-key' };
1593
+ const backupState = { encryptedData: 'b-data', encryptedDataKey: 'b-data-key' };
1594
+ const userSignedMsg1 = { message: 'umsg1', signature: 'usig1' };
1595
+ const backupSignedMsg1 = { message: 'bmsg1', signature: 'bsig1' };
1596
+ const userSignedMsg2 = { message: 'umsg2', signature: 'usig2' };
1597
+ const backupSignedMsg2 = { message: 'bmsg2', signature: 'bsig2' };
1598
+ const bitgoMsg1 = { message: 'bitgo-msg1', signature: 'bitgo-sig1' };
1599
+ const bitgoMsg2 = { message: 'bitgo-msg2', signature: 'bitgo-sig2' };
1600
+ beforeEach(function () {
1601
+ callbacks = {
1602
+ initializeCallback: sinon.stub().resolves({
1603
+ userGpgPublicKey: 'user-gpg-pub',
1604
+ backupGpgPublicKey: 'backup-gpg-pub',
1605
+ userState,
1606
+ backupState,
1607
+ }),
1608
+ round1Callback: sinon.stub().resolves({
1609
+ userSignedMsg1,
1610
+ backupSignedMsg1,
1611
+ userState,
1612
+ backupState,
1613
+ }),
1614
+ round2Callback: sinon.stub().resolves({
1615
+ userSignedMsg2,
1616
+ backupSignedMsg2,
1617
+ userState,
1618
+ backupState,
1619
+ }),
1620
+ finalizeCallback: sinon.stub().resolves({ commonKeychain }),
1621
+ };
1622
+ const mockBitGo = {
1623
+ getEnv: sinon.stub().returns('dev'),
1624
+ };
1625
+ const mockKeychains = {
1626
+ add: sinon
1627
+ .stub()
1628
+ .callsFake((params) => Promise.resolve({ id: `${params.source}-key-id`, commonKeychain, isMPCv2: true })),
1629
+ };
1630
+ const mockCoin = {
1631
+ keychains: sinon.stub().returns(mockKeychains),
1632
+ };
1633
+ utils = new src_1.EddsaMPCv2Utils(mockBitGo, mockCoin);
1634
+ sinon.stub(utils, 'getBitgoGpgPubkeyBasedOnFeatureFlags').resolves({ eddsaMpcv2PublicKey: null });
1635
+ utils.bitgoEddsaMpcv2PublicGpgKey = { armor: () => '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' };
1636
+ sinon.stub(utils, 'sendKeyGenerationRound1').resolves({
1637
+ sessionId: sessionId,
1638
+ bitgoMsg1,
1639
+ });
1640
+ sinon.stub(utils, 'sendKeyGenerationRound2').resolves({
1641
+ sessionId: sessionId,
1642
+ commonPublicKeychain: commonKeychain,
1643
+ bitgoMsg2,
1644
+ });
1645
+ sinon.stub(utils, 'addBitgoKeychain').resolves({ id: 'bitgo-key-id', commonKeychain, isMPCv2: true });
1646
+ });
1647
+ afterEach(function () {
1648
+ sinon.restore();
1649
+ });
1650
+ it('should invoke callbacks in order and return keychains', async function () {
1651
+ const keychains = await utils.createKeychainsWithExternalSigner({ enterprise, callbacks });
1652
+ assert.ok(keychains.userKeychain);
1653
+ assert.ok(keychains.backupKeychain);
1654
+ assert.ok(keychains.bitgoKeychain);
1655
+ sinon.assert.calledOnce(callbacks.initializeCallback);
1656
+ sinon.assert.calledOnce(callbacks.round1Callback);
1657
+ sinon.assert.calledOnce(callbacks.round2Callback);
1658
+ sinon.assert.calledOnce(callbacks.finalizeCallback);
1659
+ });
1660
+ it('should pass round1 response to round2Callback', async function () {
1661
+ await utils.createKeychainsWithExternalSigner({ enterprise, callbacks });
1662
+ const round2Args = callbacks.round2Callback.firstCall.args[0];
1663
+ assert.deepStrictEqual(round2Args.bitgoMsg1, bitgoMsg1);
1664
+ assert.deepStrictEqual(round2Args.userSignedMsg1, userSignedMsg1);
1665
+ assert.deepStrictEqual(round2Args.backupSignedMsg1, backupSignedMsg1);
1666
+ assert.deepStrictEqual(round2Args.userState, userState);
1667
+ assert.deepStrictEqual(round2Args.backupState, backupState);
1668
+ });
1669
+ it('should pass round2 response to finalizeCallback', async function () {
1670
+ await utils.createKeychainsWithExternalSigner({ enterprise, callbacks });
1671
+ const finalizeArgs = callbacks.finalizeCallback.firstCall.args[0];
1672
+ assert.deepStrictEqual(finalizeArgs.bitgoMsg2, bitgoMsg2);
1673
+ assert.strictEqual(finalizeArgs.bitgoCommonKeychain, commonKeychain);
1674
+ assert.deepStrictEqual(finalizeArgs.userState, userState);
1675
+ assert.deepStrictEqual(finalizeArgs.backupState, backupState);
1676
+ });
1677
+ it('should register keychains with isMPCv2: true', async function () {
1678
+ await utils.createKeychainsWithExternalSigner({ enterprise, callbacks });
1679
+ const mockKeychains = utils.baseCoin.keychains();
1680
+ const addCalls = mockKeychains.add.getCalls();
1681
+ assert.ok(addCalls.length >= 2, 'keychains.add should be called for user and backup');
1682
+ for (const call of addCalls) {
1683
+ assert.strictEqual(call.args[0].isMPCv2, true);
1684
+ assert.strictEqual(call.args[0].keyType, 'tss');
1685
+ assert.strictEqual(call.args[0].commonKeychain, commonKeychain);
1686
+ }
1687
+ });
1688
+ it('should reject when finalizeCallback returns mismatched commonKeychain', async function () {
1689
+ callbacks.finalizeCallback.resolves({ commonKeychain: 'different-keychain' });
1690
+ await assert.rejects(() => utils.createKeychainsWithExternalSigner({ enterprise, callbacks }), /Common keychains do not match/);
1691
+ });
1692
+ it('should reject when round2 returns mismatched sessionId', async function () {
1693
+ utils.sendKeyGenerationRound2.resolves({
1694
+ sessionId: 'different-session',
1695
+ commonPublicKeychain: commonKeychain,
1696
+ bitgoMsg2,
1697
+ });
1698
+ await assert.rejects(() => utils.createKeychainsWithExternalSigner({ enterprise, callbacks }), /Round 1 and round 2 session IDs do not match/);
1699
+ });
1700
+ it('should reject when BitGo EdDSA MPCv2 GPG public key is missing', async function () {
1701
+ utils.bitgoEddsaMpcv2PublicGpgKey = undefined;
1702
+ await assert.rejects(() => utils.createKeychainsWithExternalSigner({ enterprise, callbacks }), /Failed to get BitGo EdDSA MPCv2 GPG public key/);
1703
+ });
1704
+ });
1705
+ describe('EddsaMPCv2Utils.getMpcV2RetrofitDataFromMpcV1Keys', () => {
1706
+ let utils;
1707
+ // Real 3-party MPCv1 EdDSA key shares: 1 = user, 2 = backup, 3 = bitgo.
1708
+ let userSigningMaterial;
1709
+ let backupSigningMaterial;
1710
+ let expectedUserPShare;
1711
+ let expectedBackupPShare;
1712
+ before(async () => {
1713
+ const MPC = await (0, eddsa_1.getInitializedMpcInstance)();
1714
+ const user = MPC.keyShare(1, 2, 3);
1715
+ const backup = MPC.keyShare(2, 2, 3);
1716
+ const bitgo = MPC.keyShare(3, 2, 3);
1717
+ expectedUserPShare = MPC.keyCombine(user.uShare, [backup.yShares[1], bitgo.yShares[1]]).pShare;
1718
+ expectedBackupPShare = MPC.keyCombine(backup.uShare, [user.yShares[2], bitgo.yShares[2]]).pShare;
1719
+ userSigningMaterial = {
1720
+ uShare: user.uShare,
1721
+ bitgoYShare: bitgo.yShares[1],
1722
+ backupYShare: backup.yShares[1],
1723
+ };
1724
+ backupSigningMaterial = {
1725
+ uShare: backup.uShare,
1726
+ bitgoYShare: bitgo.yShares[2],
1727
+ userYShare: user.yShares[2],
1728
+ };
1729
+ });
1730
+ beforeEach(() => {
1731
+ const mockBitGo = {};
1732
+ const mockCoin = {};
1733
+ utils = new src_1.EddsaMPCv2Utils(mockBitGo, mockCoin);
1734
+ });
1735
+ it('derives matching expectedPk and chainCode for user and backup from real MPCv1 key combine', async () => {
1736
+ const { userRetrofitData, backupRetrofitData } = await utils.getMpcV2RetrofitDataFromMpcV1Keys({
1737
+ mpcv1UserKeyShare: JSON.stringify(userSigningMaterial),
1738
+ mpcv1BackupKeyShare: JSON.stringify(backupSigningMaterial),
1739
+ });
1740
+ assert.strictEqual(userRetrofitData.expectedPk, expectedUserPShare.y);
1741
+ assert.strictEqual(backupRetrofitData.expectedPk, expectedBackupPShare.y);
1742
+ assert.strictEqual(userRetrofitData.expectedPk, backupRetrofitData.expectedPk);
1743
+ assert.strictEqual(userRetrofitData.chainCode, expectedUserPShare.chaincode);
1744
+ assert.strictEqual(backupRetrofitData.chainCode, expectedBackupPShare.chaincode);
1745
+ assert.strictEqual(userRetrofitData.chainCode, backupRetrofitData.chainCode);
1746
+ });
1747
+ it('derives s_i_0 as the combined pShare.u (clamped scalar) for each party', async () => {
1748
+ const { userRetrofitData, backupRetrofitData } = await utils.getMpcV2RetrofitDataFromMpcV1Keys({
1749
+ mpcv1UserKeyShare: JSON.stringify(userSigningMaterial),
1750
+ mpcv1BackupKeyShare: JSON.stringify(backupSigningMaterial),
1751
+ });
1752
+ assert.strictEqual(userRetrofitData.s_i_0, expectedUserPShare.u);
1753
+ assert.strictEqual(backupRetrofitData.s_i_0, expectedBackupPShare.u);
1754
+ assert.notStrictEqual(userRetrofitData.s_i_0, backupRetrofitData.s_i_0);
1755
+ });
1756
+ it('throws if user key is missing uShare', async () => {
1757
+ const keyNoUShare = JSON.stringify({
1758
+ bitgoYShare: userSigningMaterial.bitgoYShare,
1759
+ backupYShare: userSigningMaterial.backupYShare,
1760
+ });
1761
+ await assert.rejects(() => utils.getMpcV2RetrofitDataFromMpcV1Keys({
1762
+ mpcv1UserKeyShare: keyNoUShare,
1763
+ mpcv1BackupKeyShare: JSON.stringify(backupSigningMaterial),
1764
+ }), /MPCv1 key material missing uShare/);
1765
+ });
1766
+ it('throws if user key is missing bitgoYShare', async () => {
1767
+ const keyNoBitgoYShare = JSON.stringify({
1768
+ uShare: userSigningMaterial.uShare,
1769
+ backupYShare: userSigningMaterial.backupYShare,
1770
+ });
1771
+ await assert.rejects(() => utils.getMpcV2RetrofitDataFromMpcV1Keys({
1772
+ mpcv1UserKeyShare: keyNoBitgoYShare,
1773
+ mpcv1BackupKeyShare: JSON.stringify(backupSigningMaterial),
1774
+ }), /MPCv1 key material missing bitgoYShare/);
1775
+ });
1776
+ it('throws if user key is missing backupYShare', async () => {
1777
+ const keyNoBackupYShare = JSON.stringify({
1778
+ uShare: userSigningMaterial.uShare,
1779
+ bitgoYShare: userSigningMaterial.bitgoYShare,
1780
+ });
1781
+ await assert.rejects(() => utils.getMpcV2RetrofitDataFromMpcV1Keys({
1782
+ mpcv1UserKeyShare: keyNoBackupYShare,
1783
+ mpcv1BackupKeyShare: JSON.stringify(backupSigningMaterial),
1784
+ }), /User MPCv1 key material missing backupYShare/);
1785
+ });
1786
+ it('throws if backup key is missing uShare', async () => {
1787
+ const keyNoUShare = JSON.stringify({
1788
+ bitgoYShare: backupSigningMaterial.bitgoYShare,
1789
+ userYShare: backupSigningMaterial.userYShare,
1790
+ });
1791
+ await assert.rejects(() => utils.getMpcV2RetrofitDataFromMpcV1Keys({
1792
+ mpcv1UserKeyShare: JSON.stringify(userSigningMaterial),
1793
+ mpcv1BackupKeyShare: keyNoUShare,
1794
+ }), /MPCv1 key material missing uShare/);
1795
+ });
1796
+ it('throws if backup key is missing bitgoYShare', async () => {
1797
+ const keyNoBitgoYShare = JSON.stringify({
1798
+ uShare: backupSigningMaterial.uShare,
1799
+ userYShare: backupSigningMaterial.userYShare,
1800
+ });
1801
+ await assert.rejects(() => utils.getMpcV2RetrofitDataFromMpcV1Keys({
1802
+ mpcv1UserKeyShare: JSON.stringify(userSigningMaterial),
1803
+ mpcv1BackupKeyShare: keyNoBitgoYShare,
1804
+ }), /MPCv1 key material missing bitgoYShare/);
1805
+ });
1806
+ it('throws if backup key is missing userYShare', async () => {
1807
+ const keyNoUserYShare = JSON.stringify({
1808
+ uShare: backupSigningMaterial.uShare,
1809
+ bitgoYShare: backupSigningMaterial.bitgoYShare,
1810
+ });
1811
+ await assert.rejects(() => utils.getMpcV2RetrofitDataFromMpcV1Keys({
1812
+ mpcv1UserKeyShare: JSON.stringify(userSigningMaterial),
1813
+ mpcv1BackupKeyShare: keyNoUserYShare,
1814
+ }), /Backup MPCv1 key material missing userYShare/);
1815
+ });
1816
+ });
1817
+ describe('EddsaMPCv2Utils.getKeyDataForRetrofit', () => {
1818
+ let userSigningMaterial;
1819
+ let backupSigningMaterial;
1820
+ let expectedUserPShare;
1821
+ let expectedBackupPShare;
1822
+ before(async () => {
1823
+ const MPC = await (0, eddsa_1.getInitializedMpcInstance)();
1824
+ const user = MPC.keyShare(1, 2, 3);
1825
+ const backup = MPC.keyShare(2, 2, 3);
1826
+ const bitgo = MPC.keyShare(3, 2, 3);
1827
+ expectedUserPShare = MPC.keyCombine(user.uShare, [backup.yShares[1], bitgo.yShares[1]]).pShare;
1828
+ expectedBackupPShare = MPC.keyCombine(backup.uShare, [user.yShares[2], bitgo.yShares[2]]).pShare;
1829
+ userSigningMaterial = {
1830
+ uShare: user.uShare,
1831
+ bitgoYShare: bitgo.yShares[1],
1832
+ backupYShare: backup.yShares[1],
1833
+ };
1834
+ backupSigningMaterial = {
1835
+ uShare: backup.uShare,
1836
+ bitgoYShare: bitgo.yShares[2],
1837
+ userYShare: user.yShares[2],
1838
+ };
1839
+ });
1840
+ it('derives USER retrofit data matching keyCombine pShare fields', async () => {
1841
+ const retrofitData = await src_1.EddsaMPCv2Utils.getKeyDataForRetrofit(JSON.stringify(userSigningMaterial), typesMPCv2_1.MPCv2PartiesEnum.USER);
1842
+ assert.strictEqual(retrofitData.s_i_0, expectedUserPShare.u);
1843
+ assert.strictEqual(retrofitData.expectedPk, expectedUserPShare.y);
1844
+ assert.strictEqual(retrofitData.chainCode, expectedUserPShare.chaincode);
1845
+ });
1846
+ it('derives BACKUP retrofit data matching keyCombine pShare fields', async () => {
1847
+ const retrofitData = await src_1.EddsaMPCv2Utils.getKeyDataForRetrofit(JSON.stringify(backupSigningMaterial), typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
1848
+ assert.strictEqual(retrofitData.s_i_0, expectedBackupPShare.u);
1849
+ assert.strictEqual(retrofitData.expectedPk, expectedBackupPShare.y);
1850
+ assert.strictEqual(retrofitData.chainCode, expectedBackupPShare.chaincode);
1851
+ });
1852
+ it('throws if USER material is missing backupYShare', async () => {
1853
+ const keyNoBackupYShare = JSON.stringify({
1854
+ uShare: userSigningMaterial.uShare,
1855
+ bitgoYShare: userSigningMaterial.bitgoYShare,
1856
+ });
1857
+ await assert.rejects(() => src_1.EddsaMPCv2Utils.getKeyDataForRetrofit(keyNoBackupYShare, typesMPCv2_1.MPCv2PartiesEnum.USER), /User MPCv1 key material missing backupYShare/);
1858
+ });
1859
+ it('throws if BACKUP material is missing userYShare', async () => {
1860
+ const keyNoUserYShare = JSON.stringify({
1861
+ uShare: backupSigningMaterial.uShare,
1862
+ bitgoYShare: backupSigningMaterial.bitgoYShare,
1863
+ });
1864
+ await assert.rejects(() => src_1.EddsaMPCv2Utils.getKeyDataForRetrofit(keyNoUserYShare, typesMPCv2_1.MPCv2PartiesEnum.BACKUP), /Backup MPCv1 key material missing userYShare/);
1865
+ });
1866
+ it('USER and BACKUP expectedPk and chainCode match when built from the same three keyShares', async () => {
1867
+ const userRetrofitData = await src_1.EddsaMPCv2Utils.getKeyDataForRetrofit(JSON.stringify(userSigningMaterial), typesMPCv2_1.MPCv2PartiesEnum.USER);
1868
+ const backupRetrofitData = await src_1.EddsaMPCv2Utils.getKeyDataForRetrofit(JSON.stringify(backupSigningMaterial), typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
1869
+ assert.strictEqual(userRetrofitData.expectedPk, backupRetrofitData.expectedPk);
1870
+ assert.strictEqual(userRetrofitData.chainCode, backupRetrofitData.chainCode);
1871
+ });
1872
+ });
1873
+ describe('EddsaMPCv2Utils.getUserAndBackupSession', () => {
1874
+ let utils;
1875
+ let userSigningMaterial;
1876
+ let backupSigningMaterial;
1877
+ before(async () => {
1878
+ const MPC = await (0, eddsa_1.getInitializedMpcInstance)();
1879
+ const user = MPC.keyShare(1, 2, 3);
1880
+ const backup = MPC.keyShare(2, 2, 3);
1881
+ const bitgo = MPC.keyShare(3, 2, 3);
1882
+ userSigningMaterial = {
1883
+ uShare: user.uShare,
1884
+ bitgoYShare: bitgo.yShares[1],
1885
+ backupYShare: backup.yShares[1],
1886
+ };
1887
+ backupSigningMaterial = {
1888
+ uShare: backup.uShare,
1889
+ bitgoYShare: bitgo.yShares[2],
1890
+ userYShare: user.yShares[2],
1891
+ };
1892
+ });
1893
+ beforeEach(() => {
1894
+ const mockBitGo = {};
1895
+ const mockCoin = {};
1896
+ utils = new src_1.EddsaMPCv2Utils(mockBitGo, mockCoin);
1897
+ });
1898
+ afterEach(() => {
1899
+ sinon.restore();
1900
+ });
1901
+ it('returns plain DKG sessions when retrofit is undefined', async () => {
1902
+ const { userDkg, backupDkg } = await utils.getUserAndBackupSession(undefined);
1903
+ assert.ok(userDkg, 'user DKG should be created');
1904
+ assert.ok(backupDkg, 'backup DKG should be created');
1905
+ });
1906
+ it('returns retrofit-seeded DKG sessions when retrofit payload is supplied', async () => {
1907
+ const retrofit = {
1908
+ decryptedUserKey: JSON.stringify(userSigningMaterial),
1909
+ decryptedBackupKey: JSON.stringify(backupSigningMaterial),
1910
+ walletId: 'wallet-123',
1911
+ };
1912
+ const { userDkg, backupDkg } = await utils.getUserAndBackupSession(retrofit);
1913
+ assert.ok(userDkg, 'user DKG should be created with retrofit data');
1914
+ assert.ok(backupDkg, 'backup DKG should be created with retrofit data');
1915
+ });
1916
+ });
1917
+ describe('EddsaMPCv2Utils.createKeychains with retrofit wiring', () => {
1918
+ let utils;
1919
+ let userSigningMaterial;
1920
+ let backupSigningMaterial;
1921
+ let bitgoGpgPublicKeyArmored;
1922
+ const enterprise = 'enterprise-id';
1923
+ const sessionId = 'session-001';
1924
+ const walletId = 'wallet-retrofit-123';
1925
+ before(async () => {
1926
+ const MPC = await (0, eddsa_1.getInitializedMpcInstance)();
1927
+ const user = MPC.keyShare(1, 2, 3);
1928
+ const backup = MPC.keyShare(2, 2, 3);
1929
+ const bitgo = MPC.keyShare(3, 2, 3);
1930
+ userSigningMaterial = {
1931
+ uShare: user.uShare,
1932
+ bitgoYShare: bitgo.yShares[1],
1933
+ backupYShare: backup.yShares[1],
1934
+ };
1935
+ backupSigningMaterial = {
1936
+ uShare: backup.uShare,
1937
+ bitgoYShare: bitgo.yShares[2],
1938
+ userYShare: user.yShares[2],
1939
+ };
1940
+ // Generate a real Ed25519 GPG key to stand in for the BitGo GPG key
1941
+ const bitgoGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
1942
+ bitgoGpgPublicKeyArmored = bitgoGpgKeyPair.publicKey;
1943
+ });
1944
+ beforeEach(() => {
1945
+ const mockBitGo = {
1946
+ getEnv: sinon.stub().returns('dev'),
1947
+ encrypt: sinon.stub().resolves('encrypted'),
1948
+ };
1949
+ const mockKeychains = {
1950
+ add: sinon
1951
+ .stub()
1952
+ .callsFake((params) => Promise.resolve({ id: `${params.source}-key-id`, commonKeychain: 'a'.repeat(128), isMPCv2: true })),
1953
+ };
1954
+ const mockCoin = {
1955
+ keychains: sinon.stub().returns(mockKeychains),
1956
+ };
1957
+ utils = new src_1.EddsaMPCv2Utils(mockBitGo, mockCoin);
1958
+ sinon.stub(utils, 'getBitgoGpgPubkeyBasedOnFeatureFlags').resolves({ eddsaMpcv2PublicKey: null });
1959
+ // Use a real armored GPG public key so pgp.readKey() succeeds inside createKeychains
1960
+ utils.bitgoEddsaMpcv2PublicGpgKey = { armor: () => bitgoGpgPublicKeyArmored };
1961
+ sinon.stub(utils, 'addBitgoKeychain').resolves({ id: 'bitgo-key-id', commonKeychain: 'a'.repeat(128) });
1962
+ });
1963
+ afterEach(() => {
1964
+ sinon.restore();
1965
+ });
1966
+ it('spreads walletId into round-1 payload when retrofit is provided', async () => {
1967
+ const capturedPayloads = [];
1968
+ sinon.stub(utils, 'sendKeyGenerationRound1').callsFake(async (_enterprise, payload) => {
1969
+ capturedPayloads.push(payload);
1970
+ // Return a bad bitgoMsg1 to short-circuit the ceremony after R1 capture
1971
+ return { sessionId: sessionId, bitgoMsg1: { message: '', signature: '' } };
1972
+ });
1973
+ const retrofit = {
1974
+ decryptedUserKey: JSON.stringify(userSigningMaterial),
1975
+ decryptedBackupKey: JSON.stringify(backupSigningMaterial),
1976
+ walletId,
1977
+ };
1978
+ await assert.rejects(() => utils.createKeychains({ passphrase: 'test', enterprise, retrofit }), () => true);
1979
+ assert.strictEqual(capturedPayloads.length, 1, 'sendKeyGenerationRound1 should be called once');
1980
+ assert.strictEqual(capturedPayloads[0].walletId, walletId, 'walletId must be present in round-1 payload');
1981
+ });
1982
+ it('omits walletId from round-1 payload when retrofit is absent', async () => {
1983
+ const capturedPayloads = [];
1984
+ sinon.stub(utils, 'sendKeyGenerationRound1').callsFake(async (_enterprise, payload) => {
1985
+ capturedPayloads.push(payload);
1986
+ return { sessionId: sessionId, bitgoMsg1: { message: '', signature: '' } };
1987
+ });
1988
+ await assert.rejects(() => utils.createKeychains({ passphrase: 'test', enterprise }), () => true);
1989
+ assert.strictEqual(capturedPayloads.length, 1, 'sendKeyGenerationRound1 should be called once');
1990
+ assert.strictEqual(capturedPayloads[0].walletId, undefined, 'walletId must be absent when no retrofit');
1991
+ });
1992
+ });
1993
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRkc2FNUEN2Mi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Rlc3QvdW5pdC9iaXRnby91dGlscy90c3MvZWRkc2EvZWRkc2FNUEN2Mi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG1DQUFnQztBQUNoQywrQ0FBaUM7QUFDakMsNkNBQStCO0FBQy9CLDZDQUErQjtBQUMvQixtQ0FBcUM7QUFDckMseURBQWdHO0FBQ2hHLG1EQUFnRDtBQUNoRCx1REFBeUM7QUFDekMsc0RBTzZCO0FBQzdCLCtDQWtCK0I7QUFDL0IsaUZBTzBEO0FBQzFELHVFQUF3RjtBQUN4RixtRUFBZ0Y7QUFDaEYscUVBQTJFO0FBQzNFLGlGQUFvRjtBQUNwRix1RkFBMEY7QUFDMUYsK0VBQStFO0FBRS9FLFFBQVEsQ0FBQyxnQ0FBZ0MsRUFBRSxLQUFLLElBQUksRUFBRTtJQUNwRCxJQUFJLFlBQW9CLENBQUM7SUFDekIsSUFBSSxjQUFzQixDQUFDO0lBQzNCLElBQUksYUFBcUIsQ0FBQztJQUMxQixJQUFJLGNBQThCLENBQUM7SUFDbkMsSUFBSSxnQkFBZ0MsQ0FBQztJQUNyQyxJQUFJLGVBQStCLENBQUM7SUFDcEMsSUFBSSxjQUF1QixDQUFDO0lBRTVCLE1BQU0sV0FBVyxHQUFHLFVBQVUsQ0FBQztJQUMvQixNQUFNLGNBQWMsR0FBRyxLQUFLLENBQUM7SUFFN0IsTUFBTSxDQUFDLCtCQUErQixFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ2pELE1BQU0sY0FBYyxHQUFHLE1BQU0sSUFBQSxpQ0FBa0IsRUFBQyxTQUFTLENBQUMsQ0FBQztRQUMzRCxNQUFNLGdCQUFnQixHQUFHLE1BQU0sSUFBQSxpQ0FBa0IsRUFBQyxTQUFTLENBQUMsQ0FBQztRQUM3RCxNQUFNLGVBQWUsR0FBRyxNQUFNLElBQUEsaUNBQWtCLEVBQUMsU0FBUyxDQUFDLENBQUM7UUFFNUQsY0FB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QUFtQixFQUFFLE9BQVksRUFBRSxFQUFFO1lBQ2pHLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMvQixPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQWdCLEVBQUUsU0FBUyxFQUFFLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFTLEVBQUUsQ0FBQztRQUMzRixDQUFDLENBQUMsQ0FBQztRQUVILE1BQU0sTUFBTSxDQUFDLE9BQU8sQ0FDbEIsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFDL0QsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUNYLENBQUM7UUFFRixNQUFNLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsK0NBQStDLENBQUMsQ0FBQztRQUNoRyxNQUFNLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUsMENBQTBDLENBQUMsQ0FBQztJQUMxRyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZW5jb2RlIH0gZnJvbSAnY2Jvci14JztcbmltcG9ydCAqIGFzIGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0ICogYXMgcGdwIGZyb20gJ29wZW5wZ3AnO1xuaW1wb3J0IHsgcmFuZG9tQnl0ZXMgfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHsgRWRkc2FNUFNEa2csIEVkZHNhTVBTRHNnLCBNUFNDb21tcywgTVBTVHlwZXMsIE1QU1V0aWwgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstbGliLW1wYyc7XG5pbXBvcnQgeyBlZDI1NTE5IH0gZnJvbSAnQG5vYmxlL2N1cnZlcy9lZDI1NTE5JztcbmltcG9ydCAqIGFzIHNqY2wgZnJvbSAnQGJpdGdvLWJldGEvc2pjbCc7XG5pbXBvcnQge1xuICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFJbnB1dCxcbiAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxT3V0cHV0LFxuICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJJbnB1dCxcbiAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQyT3V0cHV0LFxuICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDNJbnB1dCxcbiAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQzT3V0cHV0LFxufSBmcm9tICdAYml0Z28vcHVibGljLXR5cGVzJztcbmltcG9ydCB7XG4gIEJpdEdvQmFzZSxcbiAgQml0R29SZXF1ZXN0LFxuICBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kMUdlbmVyYXRpbmdGdW5jdGlvbixcbiAgQ3VzdG9tRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDJHZW5lcmF0aW5nRnVuY3Rpb24sXG4gIEN1c3RvbUVkZHNhTVBDdjJTaWduaW5nUm91bmQzR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICBFRERTQVV0aWxzLFxuICBFZGRzYU1QQ3YyS2V5R2VuQ2FsbGJhY2tzLFxuICBFZGRzYU1QQ3YyVXRpbHMsXG4gIElCYXNlQ29pbixcbiAgSVdhbGxldCxcbiAgUmVxdWVzdFRyYWNlcixcbiAgU2lnbmF0dXJlU2hhcmVSZWNvcmQsXG4gIFNpZ25hdHVyZVNoYXJlVHlwZSxcbiAgVHhSZXF1ZXN0LFxuICBnZXRFZGRzYVNpZ25pbmdNYXRlcmlhbCxcbiAgaXNFZGRzYVNpZ25pbmdNYXRlcmlhbCxcbiAgc2lnbkVkZHNhTXBjVjJSZWNvdmVyeVR4LFxufSBmcm9tICcuLi8uLi8uLi8uLi8uLi8uLi9zcmMnO1xuaW1wb3J0IHtcbiAgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZE9uZSxcbiAgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFR3byxcbiAgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFRocmVlLFxuICB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kT25lLFxuICB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kVHdvLFxuICB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kVGhyZWUsXG59IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9iaXRnby90c3MvZWRkc2EvZWRkc2FNUEN2Mic7XG5pbXBvcnQgeyBnZXRJbml0aWFsaXplZE1wY0luc3RhbmNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2JpdGdvL3Rzcy9lZGRzYS9lZGRzYSc7XG5pbXBvcnQgeyBnZXRCaXRnb1NpZ25hdHVyZVNoYXJlIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2JpdGdvL3Rzcy9jb21tb24nO1xuaW1wb3J0IHsgZGVjb2RlV2l0aENvZGVjIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2JpdGdvL3V0aWxzL2NvZGVjcyc7XG5pbXBvcnQgeyBnZW5lcmF0ZUdQR0tleVBhaXIgfSBmcm9tICcuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYml0Z28vdXRpbHMvb3BlbmdwZ1V0aWxzJztcbmltcG9ydCB7IE1QQ3YyUGFydGllc0VudW0gfSBmcm9tICcuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYml0Z28vdXRpbHMvdHNzL2VjZHNhL3R5cGVzTVBDdjInO1xuaW1wb3J0IHsgaXNWMkVudmVsb3BlIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2JpdGdvL3V0aWxzL3Rzcy9iYXNlVHlwZXMnO1xuXG5kZXNjcmliZSgnRWREU0EgTVBTIERTRyBoZWxwZXIgZnVuY3Rpb25zJywgYXN5bmMgKCkgPT4ge1xuICBsZXQgdXNlcktleVNoYXJlOiBCdWZmZXI7XG4gIGxldCBiYWNrdXBLZXlTaGFyZTogQnVmZmVyO1xuICBsZXQgYml0Z29LZXlTaGFyZTogQnVmZmVyO1xuICBsZXQgdXNlckdwZ1ByaXZLZXk6IHBncC5Qcml2YXRlS2V5O1xuICBsZXQgYmFja3VwR3BnUHJpdktleTogcGdwLlByaXZhdGVLZXk7XG4gIGxldCBiaXRnb0dwZ1ByaXZLZXk6IHBncC5Qcml2YXRlS2V5O1xuICBsZXQgYml0Z29HcGdQdWJLZXk6IHBncC5LZXk7XG5cbiAgY29uc3Qgc2lnbmFibGVIZXggPSAnZGVhZGJlZWYnO1xuICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9ICdtLzAnO1xuXG4gIGJlZm9yZSgnZ2VuZXJhdGUgRWREU0EgREtHIGtleSBzaGFyZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdXNlckdwZ0tleVBhaXIgPSBhd2FpdCBnZW5lcmF0ZUdQR0tleVBhaXIoJ2VkMjU1MTknKTtcbiAgICBjb25zdCBiYWNrdXBHcGdLZXlQYWlyID0gYXdhaXQgZ2VuZXJhdGVHUEdLZXlQYWlyKCdlZDI1NTE5Jyk7XG4gICAgY29uc3QgYml0Z29HcGdLZXlQYWlyID0gYXdhaXQgZ2VuZXJhdGVHUEdLZXlQYWlyKCdlZDI1NTE5Jyk7XG5cbiAgICB1c2VyR3BnUHJpdktleSA9IGF3YWl0IHBncC5yZWFkUHJpdmF0ZUtleSh7IGFybW9yZWRLZXk6IHVzZXJHcGdLZXlQYWlyLnByaXZhdGVLZXkgfSk7XG4gICAgYmFja3VwR3BnUHJpdktleSA9IGF3YWl0IHBncC5yZWFkUHJpdmF0ZUtleSh7IGFybW9yZWRLZXk6IGJhY2t1cEdwZ0tleVBhaXIucHJpdmF0ZUtleSB9KTtcbiAgICBiaXRnb0dwZ1ByaXZLZXkgPSBhd2FpdCBwZ3AucmVhZFByaXZhdGVLZXkoeyBhcm1vcmVkS2V5OiBiaXRnb0dwZ0tleVBhaXIucHJpdmF0ZUtleSB9KTtcbiAgICBiaXRnb0dwZ1B1YktleSA9IGF3YWl0IHBncC5yZWFkS2V5KHsgYXJtb3JlZEtleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSB9KTtcblxuICAgIGNvbnN0IFt1c2VyRGtnLCBiYWNrdXBEa2csIGJpdGdvRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIHVzZXJLZXlTaGFyZSA9IHVzZXJEa2cuZ2V0S2V5U2hhcmUoKTtcbiAgICBiYWNrdXBLZXlTaGFyZSA9IGJhY2t1cERrZy5nZXRLZXlTaGFyZSgpO1xuICAgIGJpdGdvS2V5U2hhcmUgPSBiaXRnb0RrZy5nZXRLZXlTaGFyZSgpO1xuICB9KTtcblxuICAvLyDilIDilIAgUm91bmQgMSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBpdCgnZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZE9uZSBzaG91bGQgYnVpbGQgYSB2YWxpZCByb3VuZC0xIHNoYXJlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbShzaWduYWJsZUhleCwgJ2hleCcpO1xuICAgIGNvbnN0IHVzZXJEc2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uVVNFUik7XG4gICAgYXdhaXQgdXNlckRzZy5pbml0RHNnKHVzZXJLZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGNvbnN0IHVzZXJNc2cxID0gdXNlckRzZy5nZXRGaXJzdE1lc3NhZ2UoKTtcblxuICAgIGNvbnN0IHNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCA9IGF3YWl0IGdldFNpZ25hdHVyZVNoYXJlUm91bmRPbmUodXNlck1zZzEsIHVzZXJHcGdQcml2S2V5KTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaGFyZS5mcm9tLCBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNoYXJlLnRvLCBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08pO1xuXG4gICAgY29uc3QgcGFyc2VkID0gZGVjb2RlV2l0aENvZGVjKFxuICAgICAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQsXG4gICAgICBKU09OLnBhcnNlKHNoYXJlLnNoYXJlKSxcbiAgICAgICdFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFJbnB1dCdcbiAgICApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChwYXJzZWQudHlwZSwgJ3JvdW5kMUlucHV0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZC5kYXRhLm1zZzEubWVzc2FnZSwgJ21zZzEubWVzc2FnZSBzaG91bGQgYmUgc2V0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZC5kYXRhLm1zZzEuc2lnbmF0dXJlLCAnbXNnMS5zaWduYXR1cmUgc2hvdWxkIGJlIHNldCcpO1xuICB9KTtcblxuICBpdCgnZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZE9uZSBzaG91bGQgYnVpbGQgYSB2YWxpZCBiYWNrdXAgcm91bmQtMSBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCBiYWNrdXBEc2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQkFDS1VQKTtcbiAgICBhd2FpdCBiYWNrdXBEc2cuaW5pdERzZyhiYWNrdXBLZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGNvbnN0IGJhY2t1cE1zZzEgPSBiYWNrdXBEc2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG5cbiAgICBjb25zdCBzaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSBhd2FpdCBnZXRTaWduYXR1cmVTaGFyZVJvdW5kT25lKFxuICAgICAgYmFja3VwTXNnMSxcbiAgICAgIGJhY2t1cEdwZ1ByaXZLZXksXG4gICAgICBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUFxuICAgICk7XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2hhcmUuZnJvbSwgU2lnbmF0dXJlU2hhcmVUeXBlLkJBQ0tVUCk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNoYXJlLnRvLCBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08pO1xuXG4gICAgY29uc3QgcGFyc2VkID0gZGVjb2RlV2l0aENvZGVjKFxuICAgICAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQsXG4gICAgICBKU09OLnBhcnNlKHNoYXJlLnNoYXJlKSxcbiAgICAgICdFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFJbnB1dCdcbiAgICApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChwYXJzZWQudHlwZSwgJ3JvdW5kMUlucHV0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZC5kYXRhLm1zZzEubWVzc2FnZSwgJ21zZzEubWVzc2FnZSBzaG91bGQgYmUgc2V0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZC5kYXRhLm1zZzEuc2lnbmF0dXJlLCAnbXNnMS5zaWduYXR1cmUgc2hvdWxkIGJlIHNldCcpO1xuICB9KTtcblxuICBpdCgndmVyaWZ5UGVlck1lc3NhZ2VSb3VuZE9uZSBzaG91bGQgdmVyaWZ5IGEgdmFsaWQgQml0R28gcm91bmQtMSBtZXNzYWdlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbShzaWduYWJsZUhleCwgJ2hleCcpO1xuICAgIGNvbnN0IGJpdGdvRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhd2FpdCBiaXRnb0RzZy5pbml0RHNnKGJpdGdvS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuICAgIGNvbnN0IGJpdGdvTXNnMSA9IGJpdGdvRHNnLmdldEZpcnN0TWVzc2FnZSgpO1xuXG4gICAgY29uc3QgYml0Z29TaWduZWRNc2cxID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYml0Z29Nc2cxLnBheWxvYWQpLCBiaXRnb0dwZ1ByaXZLZXkpO1xuICAgIGNvbnN0IHJvdW5kMU91dHB1dDogRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxT3V0cHV0ID0ge1xuICAgICAgdHlwZTogJ3JvdW5kMU91dHB1dCcsXG4gICAgICBkYXRhOiB7IG1zZzE6IGJpdGdvU2lnbmVkTXNnMSB9LFxuICAgIH07XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kT25lKHJvdW5kMU91dHB1dCwgYml0Z29HcGdQdWJLZXkpO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5mcm9tLCBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhc3NlcnQub2socmVzdWx0LnBheWxvYWQubGVuZ3RoID4gMCwgJ3BheWxvYWQgc2hvdWxkIGJlIG5vbi1lbXB0eScpO1xuICB9KTtcblxuICBpdCgndmVyaWZ5UGVlck1lc3NhZ2VSb3VuZE9uZSBzaG91bGQgdGhyb3cgb24gYSB0YW1wZXJlZCBtZXNzYWdlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJvdW5kMU91dHB1dDogRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxT3V0cHV0ID0ge1xuICAgICAgdHlwZTogJ3JvdW5kMU91dHB1dCcsXG4gICAgICBkYXRhOiB7XG4gICAgICAgIG1zZzE6IHtcbiAgICAgICAgICBtZXNzYWdlOiBCdWZmZXIuZnJvbSgndGFtcGVyZWQnKS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICAgICAgc2lnbmF0dXJlOiAnLS0tLS1CRUdJTiBQR1AgU0lHTkFUVVJFLS0tLS1cXG5cXG5JTlZBTElEXFxuLS0tLS1FTkQgUEdQIFNJR05BVFVSRS0tLS0tXFxuJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKHZlcmlmeVBlZXJNZXNzYWdlUm91bmRPbmUocm91bmQxT3V0cHV0LCBiaXRnb0dwZ1B1YktleSksICdzaG91bGQgdGhyb3cgb24gaW52YWxpZCBzaWduYXR1cmUnKTtcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFJvdW5kIDIg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgaXQoJ2dldFNpZ25hdHVyZVNoYXJlUm91bmRUd28gc2hvdWxkIGJ1aWxkIGEgdmFsaWQgcm91bmQtMiBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCB1c2VyRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuICAgIGF3YWl0IHVzZXJEc2cuaW5pdERzZyh1c2VyS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBjb25zdCB1c2VyTXNnMSA9IHVzZXJEc2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG5cbiAgICBjb25zdCBiaXRnb0RzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYXdhaXQgYml0Z29Ec2cuaW5pdERzZyhiaXRnb0tleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcbiAgICBjb25zdCBiaXRnb01zZzEgPSBiaXRnb0RzZy5nZXRGaXJzdE1lc3NhZ2UoKTtcblxuICAgIGNvbnN0IGJpdGdvU2lnbmVkTXNnMSA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKGJpdGdvTXNnMS5wYXlsb2FkKSwgYml0Z29HcGdQcml2S2V5KTtcbiAgICBjb25zdCBiaXRnb0Rlc2VyaWFsaXplZE1zZzEgPSBhd2FpdCB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kT25lKFxuICAgICAgeyB0eXBlOiAncm91bmQxT3V0cHV0JywgZGF0YTogeyBtc2cxOiBiaXRnb1NpZ25lZE1zZzEgfSB9LFxuICAgICAgYml0Z29HcGdQdWJLZXlcbiAgICApO1xuICAgIGNvbnN0IFt1c2VyTXNnMl0gPSB1c2VyRHNnLmhhbmRsZUluY29taW5nTWVzc2FnZXMoW3VzZXJNc2cxLCBiaXRnb0Rlc2VyaWFsaXplZE1zZzFdKTtcblxuICAgIGNvbnN0IHNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCA9IGF3YWl0IGdldFNpZ25hdHVyZVNoYXJlUm91bmRUd28odXNlck1zZzIsIHVzZXJHcGdQcml2S2V5KTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaGFyZS5mcm9tLCBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNoYXJlLnRvLCBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08pO1xuXG4gICAgY29uc3QgcGFyc2VkID0gZGVjb2RlV2l0aENvZGVjKFxuICAgICAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQySW5wdXQsXG4gICAgICBKU09OLnBhcnNlKHNoYXJlLnNoYXJlKSxcbiAgICAgICdFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJJbnB1dCdcbiAgICApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChwYXJzZWQudHlwZSwgJ3JvdW5kMklucHV0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZC5kYXRhLm1zZzIubWVzc2FnZSwgJ21zZzIubWVzc2FnZSBzaG91bGQgYmUgc2V0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZC5kYXRhLm1zZzIuc2lnbmF0dXJlLCAnbXNnMi5zaWduYXR1cmUgc2hvdWxkIGJlIHNldCcpO1xuICB9KTtcblxuICBpdCgnZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFR3byBzaG91bGQgYnVpbGQgYSB2YWxpZCBiYWNrdXAgcm91bmQtMiBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCBiYWNrdXBEc2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQkFDS1VQKTtcbiAgICBhd2FpdCBiYWNrdXBEc2cuaW5pdERzZyhiYWNrdXBLZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGNvbnN0IGJhY2t1cE1zZzEgPSBiYWNrdXBEc2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG5cbiAgICBjb25zdCBiaXRnb0RzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYXdhaXQgYml0Z29Ec2cuaW5pdERzZyhiaXRnb0tleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVApO1xuICAgIGNvbnN0IGJpdGdvTXNnMSA9IGJpdGdvRHNnLmdldEZpcnN0TWVzc2FnZSgpO1xuXG4gICAgY29uc3QgYml0Z29TaWduZWRNc2cxID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYml0Z29Nc2cxLnBheWxvYWQpLCBiaXRnb0dwZ1ByaXZLZXkpO1xuICAgIGNvbnN0IGJpdGdvRGVzZXJpYWxpemVkTXNnMSA9IGF3YWl0IHZlcmlmeVBlZXJNZXNzYWdlUm91bmRPbmUoXG4gICAgICB7IHR5cGU6ICdyb3VuZDFPdXRwdXQnLCBkYXRhOiB7IG1zZzE6IGJpdGdvU2lnbmVkTXNnMSB9IH0sXG4gICAgICBiaXRnb0dwZ1B1YktleVxuICAgICk7XG4gICAgY29uc3QgW2JhY2t1cE1zZzJdID0gYmFja3VwRHNnLmhhbmRsZUluY29taW5nTWVzc2FnZXMoW2JhY2t1cE1zZzEsIGJpdGdvRGVzZXJpYWxpemVkTXNnMV0pO1xuXG4gICAgY29uc3Qgc2hhcmU6IFNpZ25hdHVyZVNoYXJlUmVjb3JkID0gYXdhaXQgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFR3byhcbiAgICAgIGJhY2t1cE1zZzIsXG4gICAgICBiYWNrdXBHcGdQcml2S2V5LFxuICAgICAgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVBcbiAgICApO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNoYXJlLmZyb20sIFNpZ25hdHVyZVNoYXJlVHlwZS5CQUNLVVApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaGFyZS50bywgU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPKTtcblxuICAgIGNvbnN0IHBhcnNlZCA9IGRlY29kZVdpdGhDb2RlYyhcbiAgICAgIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMklucHV0LFxuICAgICAgSlNPTi5wYXJzZShzaGFyZS5zaGFyZSksXG4gICAgICAnRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQySW5wdXQnXG4gICAgKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFyc2VkLnR5cGUsICdyb3VuZDJJbnB1dCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWQuZGF0YS5tc2cyLm1lc3NhZ2UsICdtc2cyLm1lc3NhZ2Ugc2hvdWxkIGJlIHNldCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWQuZGF0YS5tc2cyLnNpZ25hdHVyZSwgJ21zZzIuc2lnbmF0dXJlIHNob3VsZCBiZSBzZXQnKTtcbiAgfSk7XG5cbiAgaXQoJ3ZlcmlmeVBlZXJNZXNzYWdlUm91bmRUd28gc2hvdWxkIHZlcmlmeSBhIHZhbGlkIEJpdEdvIHJvdW5kLTIgbWVzc2FnZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCB1c2VyRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuICAgIGF3YWl0IHVzZXJEc2cuaW5pdERzZyh1c2VyS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBjb25zdCB1c2VyTXNnMSA9IHVzZXJEc2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG5cbiAgICBjb25zdCBiaXRnb0RzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYXdhaXQgYml0Z29Ec2cuaW5pdERzZyhiaXRnb0tleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcbiAgICBjb25zdCBiaXRnb01zZzEgPSBiaXRnb0RzZy5nZXRGaXJzdE1lc3NhZ2UoKTtcblxuICAgIGNvbnN0IFtiaXRnb01zZzJdID0gYml0Z29Ec2cuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhbYml0Z29Nc2cxLCB1c2VyTXNnMV0pO1xuICAgIGNvbnN0IGJpdGdvU2lnbmVkTXNnMiA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKGJpdGdvTXNnMi5wYXlsb2FkKSwgYml0Z29HcGdQcml2S2V5KTtcblxuICAgIGNvbnN0IHJvdW5kMk91dHB1dDogRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQyT3V0cHV0ID0ge1xuICAgICAgdHlwZTogJ3JvdW5kMk91dHB1dCcsXG4gICAgICBkYXRhOiB7IG1zZzI6IGJpdGdvU2lnbmVkTXNnMiB9LFxuICAgIH07XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kVHdvKHJvdW5kMk91dHB1dCwgYml0Z29HcGdQdWJLZXkpO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5mcm9tLCBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhc3NlcnQub2socmVzdWx0LnBheWxvYWQubGVuZ3RoID4gMCwgJ3BheWxvYWQgc2hvdWxkIGJlIG5vbi1lbXB0eScpO1xuICB9KTtcblxuICBpdCgndmVyaWZ5UGVlck1lc3NhZ2VSb3VuZFR3byBzaG91bGQgdGhyb3cgb24gYSB0YW1wZXJlZCBtZXNzYWdlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJvdW5kMk91dHB1dDogRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQyT3V0cHV0ID0ge1xuICAgICAgdHlwZTogJ3JvdW5kMk91dHB1dCcsXG4gICAgICBkYXRhOiB7XG4gICAgICAgIG1zZzI6IHtcbiAgICAgICAgICBtZXNzYWdlOiBCdWZmZXIuZnJvbSgndGFtcGVyZWQnKS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICAgICAgc2lnbmF0dXJlOiAnLS0tLS1CRUdJTiBQR1AgU0lHTkFUVVJFLS0tLS1cXG5cXG5JTlZBTElEXFxuLS0tLS1FTkQgUEdQIFNJR05BVFVSRS0tLS0tXFxuJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKHZlcmlmeVBlZXJNZXNzYWdlUm91bmRUd28ocm91bmQyT3V0cHV0LCBiaXRnb0dwZ1B1YktleSksICdzaG91bGQgdGhyb3cgb24gaW52YWxpZCBzaWduYXR1cmUnKTtcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFJvdW5kIDMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgaXQoJ2dldFNpZ25hdHVyZVNoYXJlUm91bmRUaHJlZSBzaG91bGQgYnVpbGQgYSB2YWxpZCByb3VuZC0zIHNoYXJlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbShzaWduYWJsZUhleCwgJ2hleCcpO1xuICAgIGNvbnN0IHVzZXJEc2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uVVNFUik7XG4gICAgYXdhaXQgdXNlckRzZy5pbml0RHNnKHVzZXJLZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGNvbnN0IHVzZXJNc2cxID0gdXNlckRzZy5nZXRGaXJzdE1lc3NhZ2UoKTtcblxuICAgIGNvbnN0IGJpdGdvRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhd2FpdCBiaXRnb0RzZy5pbml0RHNnKGJpdGdvS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuICAgIGNvbnN0IGJpdGdvTXNnMSA9IGJpdGdvRHNnLmdldEZpcnN0TWVzc2FnZSgpO1xuXG4gICAgLy8gQWR2YW5jZSB0byByb3VuZCAyXG4gICAgY29uc3QgYml0Z29TaWduZWRNc2cxID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYml0Z29Nc2cxLnBheWxvYWQpLCBiaXRnb0dwZ1ByaXZLZXkpO1xuICAgIGNvbnN0IGJpdGdvRGVzZXJpYWxpemVkTXNnMSA9IGF3YWl0IHZlcmlmeVBlZXJNZXNzYWdlUm91bmRPbmUoXG4gICAgICB7IHR5cGU6ICdyb3VuZDFPdXRwdXQnLCBkYXRhOiB7IG1zZzE6IGJpdGdvU2lnbmVkTXNnMSB9IH0sXG4gICAgICBiaXRnb0dwZ1B1YktleVxuICAgICk7XG4gICAgY29uc3QgW3VzZXJNc2cyXSA9IHVzZXJEc2cuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhbdXNlck1zZzEsIGJpdGdvRGVzZXJpYWxpemVkTXNnMV0pO1xuXG4gICAgY29uc3QgW2JpdGdvTXNnMl0gPSBiaXRnb0RzZy5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKFtiaXRnb01zZzEsIHVzZXJNc2cxXSk7XG4gICAgY29uc3QgYml0Z29TaWduZWRNc2cyID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYml0Z29Nc2cyLnBheWxvYWQpLCBiaXRnb0dwZ1ByaXZLZXkpO1xuICAgIGNvbnN0IGJpdGdvRGVzZXJpYWxpemVkTXNnMiA9IGF3YWl0IHZlcmlmeVBlZXJNZXNzYWdlUm91bmRUd28oXG4gICAgICB7IHR5cGU6ICdyb3VuZDJPdXRwdXQnLCBkYXRhOiB7IG1zZzI6IGJpdGdvU2lnbmVkTXNnMiB9IH0sXG4gICAgICBiaXRnb0dwZ1B1YktleVxuICAgICk7XG4gICAgY29uc3QgW3VzZXJNc2czXSA9IHVzZXJEc2cuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhbdXNlck1zZzIsIGJpdGdvRGVzZXJpYWxpemVkTXNnMl0pO1xuXG4gICAgY29uc3Qgc2hhcmU6IFNpZ25hdHVyZVNoYXJlUmVjb3JkID0gYXdhaXQgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFRocmVlKHVzZXJNc2czLCB1c2VyR3BnUHJpdktleSk7XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2hhcmUuZnJvbSwgU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaGFyZS50bywgU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPKTtcblxuICAgIGNvbnN0IHBhcnNlZCA9IGRlY29kZVdpdGhDb2RlYyhcbiAgICAgIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kM0lucHV0LFxuICAgICAgSlNPTi5wYXJzZShzaGFyZS5zaGFyZSksXG4gICAgICAnRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQzSW5wdXQnXG4gICAgKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFyc2VkLnR5cGUsICdyb3VuZDNJbnB1dCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWQuZGF0YS5tc2czLm1lc3NhZ2UsICdtc2czLm1lc3NhZ2Ugc2hvdWxkIGJlIHNldCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWQuZGF0YS5tc2czLnNpZ25hdHVyZSwgJ21zZzMuc2lnbmF0dXJlIHNob3VsZCBiZSBzZXQnKTtcbiAgfSk7XG5cbiAgaXQoJ2dldFNpZ25hdHVyZVNoYXJlUm91bmRUaHJlZSBzaG91bGQgYnVpbGQgYSB2YWxpZCBiYWNrdXAgcm91bmQtMyBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCBiYWNrdXBEc2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQkFDS1VQKTtcbiAgICBhd2FpdCBiYWNrdXBEc2cuaW5pdERzZyhiYWNrdXBLZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGNvbnN0IGJhY2t1cE1zZzEgPSBiYWNrdXBEc2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG5cbiAgICBjb25zdCBiaXRnb0RzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYXdhaXQgYml0Z29Ec2cuaW5pdERzZyhiaXRnb0tleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVApO1xuICAgIGNvbnN0IGJpdGdvTXNnMSA9IGJpdGdvRHNnLmdldEZpcnN0TWVzc2FnZSgpO1xuXG4gICAgY29uc3QgYml0Z29TaWduZWRNc2cxID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYml0Z29Nc2cxLnBheWxvYWQpLCBiaXRnb0dwZ1ByaXZLZXkpO1xuICAgIGNvbnN0IGJpdGdvRGVzZXJpYWxpemVkTXNnMSA9IGF3YWl0IHZlcmlmeVBlZXJNZXNzYWdlUm91bmRPbmUoXG4gICAgICB7IHR5cGU6ICdyb3VuZDFPdXRwdXQnLCBkYXRhOiB7IG1zZzE6IGJpdGdvU2lnbmVkTXNnMSB9IH0sXG4gICAgICBiaXRnb0dwZ1B1YktleVxuICAgICk7XG4gICAgY29uc3QgW2JhY2t1cE1zZzJdID0gYmFja3VwRHNnLmhhbmRsZUluY29taW5nTWVzc2FnZXMoW2JhY2t1cE1zZzEsIGJpdGdvRGVzZXJpYWxpemVkTXNnMV0pO1xuXG4gICAgY29uc3QgW2JpdGdvTXNnMl0gPSBiaXRnb0RzZy5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKFtiaXRnb01zZzEsIGJhY2t1cE1zZzFdKTtcbiAgICBjb25zdCBiaXRnb1NpZ25lZE1zZzIgPSBhd2FpdCBNUFNDb21tcy5kZXRhY2hTaWduTXBzTWVzc2FnZShCdWZmZXIuZnJvbShiaXRnb01zZzIucGF5bG9hZCksIGJpdGdvR3BnUHJpdktleSk7XG4gICAgY29uc3QgYml0Z29EZXNlcmlhbGl6ZWRNc2cyID0gYXdhaXQgdmVyaWZ5UGVlck1lc3NhZ2VSb3VuZFR3byhcbiAgICAgIHsgdHlwZTogJ3JvdW5kMk91dHB1dCcsIGRhdGE6IHsgbXNnMjogYml0Z29TaWduZWRNc2cyIH0gfSxcbiAgICAgIGJpdGdvR3BnUHViS2V5XG4gICAgKTtcbiAgICBjb25zdCBbYmFja3VwTXNnM10gPSBiYWNrdXBEc2cuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhbYmFja3VwTXNnMiwgYml0Z29EZXNlcmlhbGl6ZWRNc2cyXSk7XG5cbiAgICBjb25zdCBzaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSBhd2FpdCBnZXRTaWduYXR1cmVTaGFyZVJvdW5kVGhyZWUoXG4gICAgICBiYWNrdXBNc2czLFxuICAgICAgYmFja3VwR3BnUHJpdktleSxcbiAgICAgIE1QQ3YyUGFydGllc0VudW0uQkFDS1VQXG4gICAgKTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaGFyZS5mcm9tLCBTaWduYXR1cmVTaGFyZVR5cGUuQkFDS1VQKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2hhcmUudG8sIFNpZ25hdHVyZVNoYXJlVHlwZS5CSVRHTyk7XG5cbiAgICBjb25zdCBwYXJzZWQgPSBkZWNvZGVXaXRoQ29kZWMoXG4gICAgICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDNJbnB1dCxcbiAgICAgIEpTT04ucGFyc2Uoc2hhcmUuc2hhcmUpLFxuICAgICAgJ0VkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kM0lucHV0J1xuICAgICk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBhcnNlZC50eXBlLCAncm91bmQzSW5wdXQnKTtcbiAgICBhc3NlcnQub2socGFyc2VkLmRhdGEubXNnMy5tZXNzYWdlLCAnbXNnMy5tZXNzYWdlIHNob3VsZCBiZSBzZXQnKTtcbiAgICBhc3NlcnQub2socGFyc2VkLmRhdGEubXNnMy5zaWduYXR1cmUsICdtc2czLnNpZ25hdHVyZSBzaG91bGQgYmUgc2V0Jyk7XG4gIH0pO1xuXG4gIGl0KCd2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kVGhyZWUgc2hvdWxkIHZlcmlmeSBhIHZhbGlkIEJpdEdvIHJvdW5kLTMgbWVzc2FnZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCBbLCBbYml0Z29Nc2czXV0gPSAoYXdhaXQgTVBTVXRpbC5leGVjdXRlVGlsbFJvdW5kKFxuICAgICAgMixcbiAgICAgIG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5VU0VSKSxcbiAgICAgIG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyksXG4gICAgICB1c2VyS2V5U2hhcmUsXG4gICAgICBiaXRnb0tleVNoYXJlLFxuICAgICAgbWVzc2FnZUJ1ZmZlcixcbiAgICAgIGRlcml2YXRpb25QYXRoXG4gICAgKSkgYXMgTVBTVHlwZXMuRGVzZXJpYWxpemVkTWVzc2FnZXNbXTtcbiAgICBjb25zdCBiaXRnb1NpZ25lZE1zZzMgPSBhd2FpdCBNUFNDb21tcy5kZXRhY2hTaWduTXBzTWVzc2FnZShCdWZmZXIuZnJvbShiaXRnb01zZzMucGF5bG9hZCksIGJpdGdvR3BnUHJpdktleSk7XG5cbiAgICBjb25zdCByb3VuZDNPdXRwdXQ6IEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kM091dHB1dCA9IHtcbiAgICAgIHR5cGU6ICdyb3VuZDNPdXRwdXQnLFxuICAgICAgZGF0YTogeyBtc2czOiBiaXRnb1NpZ25lZE1zZzMgfSxcbiAgICB9O1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdmVyaWZ5UGVlck1lc3NhZ2VSb3VuZFRocmVlKHJvdW5kM091dHB1dCwgYml0Z29HcGdQdWJLZXkpO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5mcm9tLCBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhc3NlcnQub2socmVzdWx0LnBheWxvYWQubGVuZ3RoID4gMCwgJ3BheWxvYWQgc2hvdWxkIGJlIG5vbi1lbXB0eScpO1xuICB9KTtcblxuICBpdCgndmVyaWZ5UGVlck1lc3NhZ2VSb3VuZFRocmVlIHNob3VsZCB0aHJvdyBvbiBhIHRhbXBlcmVkIG1lc3NhZ2UnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qgcm91bmQzT3V0cHV0OiBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDNPdXRwdXQgPSB7XG4gICAgICB0eXBlOiAncm91bmQzT3V0cHV0JyxcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgbXNnMzoge1xuICAgICAgICAgIG1lc3NhZ2U6IEJ1ZmZlci5mcm9tKCd0YW1wZXJlZCcpLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgICAgICBzaWduYXR1cmU6ICctLS0tLUJFR0lOIFBHUCBTSUdOQVRVUkUtLS0tLVxcblxcbklOVkFMSURcXG4tLS0tLUVORCBQR1AgU0lHTkFUVVJFLS0tLS1cXG4nLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kVGhyZWUocm91bmQzT3V0cHV0LCBiaXRnb0dwZ1B1YktleSksXG4gICAgICAnc2hvdWxkIHRocm93IG9uIGludmFsaWQgc2lnbmF0dXJlJ1xuICAgICk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdnZXRFZGRzYU1QQ3YyUmVjb3ZlcnlLZXlTaGFyZXMnLCAoKSA9PiB7XG4gIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAndGVzdFBhc3MnO1xuXG4gIGNvbnN0IGVuY3J5cHRLZXkgPSAoa2V5U2hhcmU6IEJ1ZmZlcik6IHN0cmluZyA9PiBzamNsLmVuY3J5cHQod2FsbGV0UGFzc3BocmFzZSwga2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpKTtcblxuICBpdCgnc2hvdWxkIHJldHVybiByZWNvdmVyeSBrZXkgc2hhcmVzIGZyb20gdjEtZW5jcnlwdGVkIHJlZHVjZWQga2V5cyAobm8gYml0Z28gaW5zdGFuY2UpJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IFt1c2VyRGtnLCBiYWNrdXBEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgRUREU0FVdGlscy5nZXRFZGRzYU1wY1YyUmVjb3ZlcnlLZXlTaGFyZXNGcm9tUmVkdWNlZEtleShcbiAgICAgIGVuY3J5cHRLZXkodXNlckRrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKSksXG4gICAgICBlbmNyeXB0S2V5KGJhY2t1cERrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKSksXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlXG4gICAgKTtcblxuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwocmVzdWx0LnVzZXJLZXlTaGFyZSwgdXNlckRrZy5nZXRLZXlTaGFyZSgpKTtcbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHJlc3VsdC5iYWNrdXBLZXlTaGFyZSwgYmFja3VwRGtnLmdldEtleVNoYXJlKCkpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuY29tbW9uS2V5Q2hhaW4sIHVzZXJEa2cuZ2V0Q29tbW9uS2V5Y2hhaW4oKSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgdW53cmFwIHZlcnNpb25lZCBzYWZlLXJvb3QgZW52ZWxvcGVzIGFuZCByZXR1cm4gVlJGIGtleXNoYXJlcycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBbdXNlckRrZywgYmFja3VwRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIGNvbnN0IHVzZXJWcmZLZXlTaGFyZSA9IEJ1ZmZlci5mcm9tKCd1c2VyLXZyZi1rZXlzaGFyZScpO1xuICAgIGNvbnN0IGJhY2t1cFZyZktleVNoYXJlID0gQnVmZmVyLmZyb20oJ2JhY2t1cC12cmYta2V5c2hhcmUnKTtcbiAgICBjb25zdCBlbmNvZGVFbnZlbG9wZSA9IChyZWR1Y2VkS2V5U2hhcmU6IEJ1ZmZlciwgdnJmS2V5U2hhcmU6IEJ1ZmZlcik6IEJ1ZmZlciA9PlxuICAgICAgQnVmZmVyLmZyb20oXG4gICAgICAgIGVuY29kZSh7XG4gICAgICAgICAgdmVyc2lvbjogMSxcbiAgICAgICAgICBwcnZLZXlTaGFyZTogbmV3IFVpbnQ4QXJyYXkocmVkdWNlZEtleVNoYXJlKSxcbiAgICAgICAgICB2cmY6IG5ldyBVaW50OEFycmF5KHZyZktleVNoYXJlKSxcbiAgICAgICAgfSlcbiAgICAgICk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBFRERTQVV0aWxzLmdldEVkZHNhTXBjVjJSZWNvdmVyeUtleVNoYXJlc0Zyb21SZWR1Y2VkS2V5KFxuICAgICAgZW5jcnlwdEtleShlbmNvZGVFbnZlbG9wZSh1c2VyRGtnLmdldFJlZHVjZWRLZXlTaGFyZSgpLCB1c2VyVnJmS2V5U2hhcmUpKSxcbiAgICAgIGVuY3J5cHRLZXkoZW5jb2RlRW52ZWxvcGUoYmFja3VwRGtnLmdldFJlZHVjZWRLZXlTaGFyZSgpLCBiYWNrdXBWcmZLZXlTaGFyZSkpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZVxuICAgICk7XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoQnVmZmVyLmNvbXBhcmUocmVzdWx0LnVzZXJLZXlTaGFyZSwgdXNlckRrZy5nZXRLZXlTaGFyZSgpKSwgMCk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKEJ1ZmZlci5jb21wYXJlKHJlc3VsdC5iYWNrdXBLZXlTaGFyZSwgYmFja3VwRGtnLmdldEtleVNoYXJlKCkpLCAwKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LmNvbW1vbktleUNoYWluLCB1c2VyRGtnLmdldENvbW1vbktleWNoYWluKCkpO1xuICAgIGFzc2VydC5vayhyZXN1bHQudXNlclZyZktleVNoYXJlKTtcbiAgICBhc3NlcnQub2socmVzdWx0LmJhY2t1cFZyZktleVNoYXJlKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoQnVmZmVyLmNvbXBhcmUocmVzdWx0LnVzZXJWcmZLZXlTaGFyZSwgdXNlclZyZktleVNoYXJlKSwgMCk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKEJ1ZmZlci5jb21wYXJlKHJlc3VsdC5iYWNrdXBWcmZLZXlTaGFyZSwgYmFja3VwVnJmS2V5U2hhcmUpLCAwKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByb3V0ZSBkZWNyeXB0aW9uIHRocm91Z2ggYml0Z28uZGVjcnlwdCB3aGVuIGEgYml0Z28gaW5zdGFuY2UgaXMgcHJvdmlkZWQnLCBhc3luYyAoKSA9PiB7XG4gICAgLy8gc2RrLWNvcmUgaGFzIG5vIGRldkRlcGVuZGVuY3kgb24gc2RrLWFwaSBvciBhcmdvbjIsIHNvIHdlIGNhbm5vdCBlbmNyeXB0IHdpdGggYSByZWFsIHYyIGVudmVsb3BlIGhlcmUuXG4gICAgLy8gVGhlIHN0dWIgdmVyaWZpZXMgdGhhdCB0aGUgZnVuY3Rpb24gZGVsZWdhdGVzIHRvIGJpdGdvLmRlY3J5cHQgKHdoaWNoIHN1cHBvcnRzIHYxICsgdjIgaW5cbiAgICAvLyBwcm9kdWN0aW9uKSByYXRoZXIgdGhhbiBmYWxsaW5nIGJhY2sgdG8gc2pjbC5kZWNyeXB0LlxuICAgIGNvbnN0IFt1c2VyRGtnLCBiYWNrdXBEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgY29uc3QgdXNlcktleUJhc2U2NCA9IHVzZXJEa2cuZ2V0UmVkdWNlZEtleVNoYXJlKCkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIGNvbnN0IGJhY2t1cEtleUJhc2U2NCA9IGJhY2t1cERrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKS50b1N0cmluZygnYmFzZTY0Jyk7XG5cbiAgICBjb25zdCBtb2NrQml0Z28gPSB7XG4gICAgICBkZWNyeXB0OiBzaW5vbi5zdHViKCkub25GaXJzdENhbGwoKS5yZXNvbHZlcyh1c2VyS2V5QmFzZTY0KS5vblNlY29uZENhbGwoKS5yZXNvbHZlcyhiYWNrdXBLZXlCYXNlNjQpLFxuICAgIH0gYXMgdW5rbm93biBhcyBCaXRHb0Jhc2U7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBFRERTQVV0aWxzLmdldEVkZHNhTXBjVjJSZWNvdmVyeUtleVNoYXJlc0Zyb21SZWR1Y2VkS2V5KFxuICAgICAgJ2VuY3J5cHRlZC11c2VyLWtleScsXG4gICAgICAnZW5jcnlwdGVkLWJhY2t1cC1rZXknLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIG1vY2tCaXRnb1xuICAgICk7XG5cbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkVHdpY2UobW9ja0JpdGdvLmRlY3J5cHQgYXMgc2lub24uU2lub25TdHViKTtcbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHJlc3VsdC51c2VyS2V5U2hhcmUsIHVzZXJEa2cuZ2V0S2V5U2hhcmUoKSk7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChyZXN1bHQuYmFja3VwS2V5U2hhcmUsIGJhY2t1cERrZy5nZXRLZXlTaGFyZSgpKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LmNvbW1vbktleUNoYWluLCB1c2VyRGtnLmdldENvbW1vbktleWNoYWluKCkpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJlamVjdCBhIG1hbGZvcm1lZCBrZXljYXJkIHdpdGggYSBkZXNjcmlwdGl2ZSBlcnJvcicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBbdXNlckRrZ10gPSBhd2FpdCBNUFNVdGlsLmdlbmVyYXRlRWREc2FES0dLZXlTaGFyZXMoKTtcbiAgICBjb25zdCBtYWxmb3JtZWRLZXkgPSBzamNsLmVuY3J5cHQod2FsbGV0UGFzc3BocmFzZSwgcmFuZG9tQnl0ZXMoNjQpLnRvU3RyaW5nKCdiYXNlNjQnKSk7XG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICBFRERTQVV0aWxzLmdldEVkZHNhTXBjVjJSZWNvdmVyeUtleVNoYXJlc0Zyb21SZWR1Y2VkS2V5KFxuICAgICAgICBtYWxmb3JtZWRLZXksXG4gICAgICAgIGVuY3J5cHRLZXkodXNlckRrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKSksXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2VcbiAgICAgICksXG4gICAgICAvdW5hYmxlIHRvIGRlY29kZSByZWR1Y2VkIGtleSBzaGFyZS9cbiAgICApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJlamVjdCByZWR1Y2VkIGtleXMgZnJvbSBkaWZmZXJlbnQgd2FsbGV0cycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBbdXNlckRrZ10gPSBhd2FpdCBNUFNVdGlsLmdlbmVyYXRlRWREc2FES0dLZXlTaGFyZXMoKTtcbiAgICBjb25zdCBbLCBiYWNrdXBEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICBFRERTQVV0aWxzLmdldEVkZHNhTXBjVjJSZWNvdmVyeUtleVNoYXJlc0Zyb21SZWR1Y2VkS2V5KFxuICAgICAgICBlbmNyeXB0S2V5KHVzZXJEa2cuZ2V0UmVkdWNlZEtleVNoYXJlKCkpLFxuICAgICAgICBlbmNyeXB0S2V5KGJhY2t1cERrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKSksXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2VcbiAgICAgICksXG4gICAgICAvcHViIGtleXMgZG8gbm90IG1hdGNoL1xuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmVqZWN0IHJlZHVjZWQga2V5cyB3aXRoIG1hdGNoaW5nIHB1YiBidXQgbWlzbWF0Y2hlZCByb290Q2hhaW5Db2RlcycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBbdXNlckRrZywgYmFja3VwRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIGNvbnN0IHVzZXJSZWR1Y2VkS2V5U2hhcmUgPSB1c2VyRGtnLmdldFJlZHVjZWRLZXlTaGFyZSgpO1xuICAgIGNvbnN0IGJhY2t1cFJlZHVjZWRLZXlTaGFyZSA9IGJhY2t1cERrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKTtcbiAgICBjb25zdCBnZXREZWNvZGVkUmVkdWNlZEtleVNoYXJlID0gTVBTVHlwZXMuZ2V0RGVjb2RlZFJlZHVjZWRLZXlTaGFyZTtcbiAgICBjb25zdCBkZWNvZGVTdHViID0gc2lub24uc3R1YihNUFNUeXBlcywgJ2dldERlY29kZWRSZWR1Y2VkS2V5U2hhcmUnKS5jYWxsc0Zha2UoKGJ1ZikgPT4ge1xuICAgICAgY29uc3QgcmVkdWNlZCA9IGdldERlY29kZWRSZWR1Y2VkS2V5U2hhcmUoYnVmKTtcbiAgICAgIGlmIChCdWZmZXIuZnJvbShidWYpLmVxdWFscyhiYWNrdXBSZWR1Y2VkS2V5U2hhcmUpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4ucmVkdWNlZCxcbiAgICAgICAgICByb290Q2hhaW5Db2RlOiBBcnJheS5mcm9tKHJhbmRvbUJ5dGVzKDMyKSksXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVkdWNlZDtcbiAgICB9KTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgRUREU0FVdGlscy5nZXRFZGRzYU1wY1YyUmVjb3ZlcnlLZXlTaGFyZXNGcm9tUmVkdWNlZEtleShcbiAgICAgICAgICBlbmNyeXB0S2V5KHVzZXJSZWR1Y2VkS2V5U2hhcmUpLFxuICAgICAgICAgIGVuY3J5cHRLZXkoYmFja3VwUmVkdWNlZEtleVNoYXJlKSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlXG4gICAgICAgICksXG4gICAgICAgIC9yb290Q2hhaW5Db2RlcyBkbyBub3QgbWF0Y2gvXG4gICAgICApO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBkZWNvZGVTdHViLnJlc3RvcmUoKTtcbiAgICB9XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdFZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlJywgKCkgPT4ge1xuICBsZXQgZWRkc2FNUEN2MlV0aWxzOiBFZGRzYU1QQ3YyVXRpbHM7XG4gIGxldCBtb2NrQml0Z286IEJpdEdvQmFzZTtcbiAgbGV0IHVzZXJLZXlTaGFyZTogQnVmZmVyO1xuXG4gIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAndGVzdFBhc3MnO1xuICBjb25zdCBzaWduYWJsZUhleCA9ICdkZWFkYmVlZic7XG4gIGNvbnN0IGRlcml2YXRpb25QYXRoID0gJ20vMC8wJztcbiAgY29uc3QgZXhwZWN0ZWRBZGF0YSA9IGAke3NpZ25hYmxlSGV4fToke2Rlcml2YXRpb25QYXRofWA7XG4gIGNvbnN0IHR4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgIHR4UmVxdWVzdElkOiAndHhyZXEtZWRkc2Etcm91bmQxJyxcbiAgICB3YWxsZXRJZDogJ3dhbGxldC1lZGRzYS1yb3VuZDEnLFxuICAgIGVudGVycHJpc2VJZDogJ2VudGVycHJpc2UtZWRkc2Etcm91bmQxJyxcbiAgICBhcGlWZXJzaW9uOiAnZnVsbCcsXG4gICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICB7XG4gICAgICAgIHVuc2lnbmVkVHg6IHtcbiAgICAgICAgICBzaWduYWJsZUhleCxcbiAgICAgICAgICBkZXJpdmF0aW9uUGF0aCxcbiAgICAgICAgICBzZXJpYWxpemVkVHhIZXg6IHNpZ25hYmxlSGV4LFxuICAgICAgICB9LFxuICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFtdLFxuICAgICAgfSxcbiAgICBdLFxuICAgIGludGVudDogeyBpbnRlbnRUeXBlOiAncGF5bWVudCcgfSxcbiAgICB1bnNpZ25lZFR4czogW10sXG4gIH0gYXMgdW5rbm93biBhcyBUeFJlcXVlc3Q7XG5cbiAgYmVmb3JlKCdnZW5lcmF0ZSBFZERTQSB1c2VyIGtleSBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBbdXNlckRrZ10gPSBhd2FpdCBNUFNVdGlsLmdlbmVyYXRlRWREc2FES0dLZXlTaGFyZXMoKTtcbiAgICB1c2VyS2V5U2hhcmUgPSB1c2VyRGtnLmdldEtleVNoYXJlKCk7XG4gIH0pO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGNvbnN0IHNqY2xFbmNyeXB0ID0gKHBhcmFtczogeyBwYXNzd29yZDogc3RyaW5nOyBpbnB1dDogc3RyaW5nOyBhZGF0YT86IHN0cmluZyB9KSA9PiB7XG4gICAgICBjb25zdCBzYWx0ID0gcmFuZG9tQnl0ZXMoOCk7XG4gICAgICBjb25zdCBpdiA9IHJhbmRvbUJ5dGVzKDE2KTtcbiAgICAgIHJldHVybiBzamNsLmVuY3J5cHQocGFyYW1zLnBhc3N3b3JkLCBwYXJhbXMuaW5wdXQsIHtcbiAgICAgICAgc2FsdDogW2J5dGVzVG9Xb3JkKHNhbHQuc3ViYXJyYXkoMCwgNCkpLCBieXRlc1RvV29yZChzYWx0LnN1YmFycmF5KDQpKV0sXG4gICAgICAgIGl2OiBbXG4gICAgICAgICAgYnl0ZXNUb1dvcmQoaXYuc3ViYXJyYXkoMCwgNCkpLFxuICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDQsIDgpKSxcbiAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSg4LCAxMikpLFxuICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDEyLCAxNikpLFxuICAgICAgICBdLFxuICAgICAgICBhZGF0YTogcGFyYW1zLmFkYXRhLFxuICAgICAgfSk7XG4gICAgfTtcbiAgICBtb2NrQml0Z28gPSB7XG4gICAgICBlbmNyeXB0OiBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKGFzeW5jIChwYXJhbXMpID0+IHNqY2xFbmNyeXB0KHBhcmFtcykpLFxuICAgIH0gYXMgdW5rbm93biBhcyBCaXRHb0Jhc2U7XG5cbiAgICBjb25zdCBtb2NrQ29pbiA9IHtcbiAgICAgIGdldE1QQ0FsZ29yaXRobTogc2lub24uc3R1YigpLnJldHVybnMoJ2VkZHNhJyksXG4gICAgfSBhcyB1bmtub3duIGFzIElCYXNlQ29pbjtcblxuICAgIGVkZHNhTVBDdjJVdGlscyA9IG5ldyBFZGRzYU1QQ3YyVXRpbHMobW9ja0JpdGdvLCBtb2NrQ29pbik7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgY3JlYXRlIGEgcm91bmQtMSBzaGFyZSBhbmQgZW5jcnlwdGVkIFNKQ0wgc2Vzc2lvbiBwYXlsb2FkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0LFxuICAgICAgcHJ2OiB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICB9KTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuc2lnbmF0dXJlU2hhcmVSb3VuZDEuZnJvbSwgU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuc2lnbmF0dXJlU2hhcmVSb3VuZDEudG8sIFNpZ25hdHVyZVNoYXJlVHlwZS5CSVRHTyk7XG4gICAgYXNzZXJ0Lm9rKHJlc3VsdC51c2VyR3BnUHViS2V5LmluY2x1ZGVzKCdCRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSycpKTtcbiAgICBhc3NlcnQub2soSlNPTi5wYXJzZShyZXN1bHQuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbikuY3QsICdlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uIHNob3VsZCBiZSBhbiBTSkNMIEpTT04gYmxvYicpO1xuICAgIGFzc2VydC5vayhKU09OLnBhcnNlKHJlc3VsdC5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5KS5jdCwgJ2VuY3J5cHRlZFVzZXJHcGdQcnZLZXkgc2hvdWxkIGJlIGFuIFNKQ0wgSlNPTiBibG9iJyk7XG5cbiAgICBjb25zdCBwYXJzZWRTaGFyZSA9IGRlY29kZVdpdGhDb2RlYyhcbiAgICAgIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMUlucHV0LFxuICAgICAgSlNPTi5wYXJzZShyZXN1bHQuc2lnbmF0dXJlU2hhcmVSb3VuZDEuc2hhcmUpLFxuICAgICAgJ0VkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMUlucHV0J1xuICAgICk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBhcnNlZFNoYXJlLnR5cGUsICdyb3VuZDFJbnB1dCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWRTaGFyZS5kYXRhLm1zZzEubWVzc2FnZSwgJ21zZzEubWVzc2FnZSBzaG91bGQgYmUgc2V0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZFNoYXJlLmRhdGEubXNnMS5zaWduYXR1cmUsICdtc2cxLnNpZ25hdHVyZSBzaG91bGQgYmUgc2V0Jyk7XG5cbiAgICBjb25zdCBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uID0gSlNPTi5wYXJzZShyZXN1bHQuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbik7XG4gICAgY29uc3QgZW5jcnlwdGVkVXNlckdwZ1BydktleSA9IEpTT04ucGFyc2UocmVzdWx0LmVuY3J5cHRlZFVzZXJHcGdQcnZLZXkpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgIGRlY29kZVVSSUNvbXBvbmVudChlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLmFkYXRhKSxcbiAgICAgIGBNUFNfRFNHX1NJR05JTkdfUk9VTkQxX1NUQVRFOiR7ZXhwZWN0ZWRBZGF0YX1gLFxuICAgICAgJ3JvdW5kLTEgc2Vzc2lvbiBhZGF0YSBzaG91bGQgYmluZCB0aGUgc2lnbmluZyBjb250ZXh0J1xuICAgICk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgICAgZGVjb2RlVVJJQ29tcG9uZW50KGVuY3J5cHRlZFVzZXJHcGdQcnZLZXkuYWRhdGEpLFxuICAgICAgYE1QU19EU0dfU0lHTklOR19VU0VSX0dQR19LRVk6JHtleHBlY3RlZEFkYXRhfWAsXG4gICAgICAnR1BHIHByaXZhdGUga2V5IGFkYXRhIHNob3VsZCBiaW5kIHRoZSBzaWduaW5nIGNvbnRleHQnXG4gICAgKTtcblxuICAgIGNvbnN0IHNlc3Npb25QYXlsb2FkID0gSlNPTi5wYXJzZShzamNsLmRlY3J5cHQod2FsbGV0UGFzc3BocmFzZSwgcmVzdWx0LmVuY3J5cHRlZFJvdW5kMVNlc3Npb24pKTtcbiAgICBhc3NlcnQub2soc2Vzc2lvblBheWxvYWQuZHNnU2Vzc2lvbiwgJ2RzZ1Nlc3Npb24gc2hvdWxkIGJlIHBlcnNpc3RlZCBmb3Igcm91bmQgMicpO1xuICAgIGFzc2VydC5vayhzZXNzaW9uUGF5bG9hZC51c2VyTXNnUGF5bG9hZCwgJ3VzZXJNc2dQYXlsb2FkIHNob3VsZCBiZSBwZXJzaXN0ZWQgZm9yIHJvdW5kIDInKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB1c2UgdjIgZW5jcnlwdGlvbiB3aGVuIGVuY3J5cHRlZFBydiBpcyBhIHYyIGVudmVsb3BlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGVuY3J5cHQgPSBzaW5vblxuICAgICAgLnN0dWIoKVxuICAgICAgLmNhbGxzRmFrZSgoaW5wdXQ6IHN0cmluZywgYWRhdGE6IHN0cmluZykgPT4gUHJvbWlzZS5yZXNvbHZlKEpTT04uc3RyaW5naWZ5KHsgdjogMiwgaW5wdXQsIGFkYXRhIH0pKSk7XG4gICAgY29uc3QgZGVzdHJveSA9IHNpbm9uLnN0dWIoKTtcbiAgICBjb25zdCBjcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbiA9IHNpbm9uLnN0dWIoKS5yZXNvbHZlcyh7IGVuY3J5cHQsIGRlc3Ryb3kgfSk7XG4gICAgbW9ja0JpdGdvLmNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uID0gY3JlYXRlRW5jcnlwdGlvblNlc3Npb247XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHtcbiAgICAgIHR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBlbmNyeXB0ZWRQcnY6IEpTT04uc3RyaW5naWZ5KHsgdjogMiB9KSxcbiAgICB9KTtcblxuICAgIHNpbm9uLmFzc2VydC5jYWxsZWRPbmNlKGNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoY3JlYXRlRW5jcnlwdGlvblNlc3Npb24uZ2V0Q2FsbCgwKS5hcmdzWzBdLCB3YWxsZXRQYXNzcGhyYXNlKTtcbiAgICBzaW5vbi5hc3NlcnQubm90Q2FsbGVkKG1vY2tCaXRnby5lbmNyeXB0IGFzIHNpbm9uLlNpbm9uU3R1Yik7XG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZFR3aWNlKGVuY3J5cHQpO1xuICAgIHNpbm9uLmFzc2VydC5jYWxsZWRPbmNlKGRlc3Ryb3kpO1xuXG4gICAgY29uc3QgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiA9IEpTT04ucGFyc2UocmVzdWx0LmVuY3J5cHRlZFJvdW5kMVNlc3Npb24pO1xuICAgIGNvbnN0IGVuY3J5cHRlZFVzZXJHcGdQcnZLZXkgPSBKU09OLnBhcnNlKHJlc3VsdC5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5KTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZW5jcnlwdGVkUm91bmQxU2Vzc2lvbi52LCAyKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZW5jcnlwdGVkUm91bmQxU2Vzc2lvbi5hZGF0YSwgYE1QU19EU0dfU0lHTklOR19ST1VORDFfU1RBVEU6JHtleHBlY3RlZEFkYXRhfWApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LnYsIDIpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LmFkYXRhLCBgTVBTX0RTR19TSUdOSU5HX1VTRVJfR1BHX0tFWToke2V4cGVjdGVkQWRhdGF9YCk7XG5cbiAgICBjb25zdCBzZXNzaW9uUGF5bG9hZCA9IEpTT04ucGFyc2UoZW5jcnlwdGVkUm91bmQxU2Vzc2lvbi5pbnB1dCk7XG4gICAgYXNzZXJ0Lm9rKHNlc3Npb25QYXlsb2FkLmRzZ1Nlc3Npb24sICdkc2dTZXNzaW9uIHNob3VsZCBiZSBwZXJzaXN0ZWQgZm9yIHJvdW5kIDInKTtcbiAgICBhc3NlcnQub2soc2Vzc2lvblBheWxvYWQudXNlck1zZ1BheWxvYWQsICd1c2VyTXNnUGF5bG9hZCBzaG91bGQgYmUgcGVyc2lzdGVkIGZvciByb3VuZCAyJyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgdXNlIFNKQ0wgZW5jcnlwdGlvbiB3aGVuIGVuY3J5cHRlZFBydiBpcyBhIHYxIGJsb2InLCBhc3luYyAoKSA9PiB7XG4gICAgbW9ja0JpdGdvLmNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uID0gc2lub24uc3R1YigpO1xuICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IHNqY2wuZW5jcnlwdCh3YWxsZXRQYXNzcGhyYXNlLCB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpKTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0LFxuICAgICAgcHJ2OiB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIGVuY3J5cHRlZFBydixcbiAgICB9KTtcblxuICAgIHNpbm9uLmFzc2VydC5ub3RDYWxsZWQobW9ja0JpdGdvLmNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uIGFzIHNpbm9uLlNpbm9uU3R1Yik7XG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZFR3aWNlKG1vY2tCaXRnby5lbmNyeXB0IGFzIHNpbm9uLlNpbm9uU3R1Yik7XG4gICAgYXNzZXJ0Lm9rKEpTT04ucGFyc2UocmVzdWx0LmVuY3J5cHRlZFJvdW5kMVNlc3Npb24pLmN0LCAnZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiBzaG91bGQgYmUgYW4gU0pDTCBKU09OIGJsb2InKTtcbiAgICBhc3NlcnQub2soSlNPTi5wYXJzZShyZXN1bHQuZW5jcnlwdGVkVXNlckdwZ1BydktleSkuY3QsICdlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5IHNob3VsZCBiZSBhbiBTSkNMIEpTT04gYmxvYicpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHByb3BhZ2F0ZSB0aGUgdHgtb25seSBndWFyZCB3aGVuIHRyYW5zYWN0aW9ucyBhcmUgbWlzc2luZycsIGFzeW5jICgpID0+IHtcbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+XG4gICAgICAgIGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUoe1xuICAgICAgICAgIHR4UmVxdWVzdDogeyAuLi50eFJlcXVlc3QsIHRyYW5zYWN0aW9uczogdW5kZWZpbmVkIH0gYXMgdW5rbm93biBhcyBUeFJlcXVlc3QsXG4gICAgICAgICAgcHJ2OiB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pLFxuICAgICAgL1VuYWJsZSB0byBmaW5kIHRyYW5zYWN0aW9ucyBpbiB0eFJlcXVlc3QvXG4gICAgKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ0VkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lS2V5R2VuUm91bmQxU2hhcmUnLCAoKSA9PiB7XG4gIGxldCBlZGRzYU1QQ3YyVXRpbHM6IEVkZHNhTVBDdjJVdGlscztcbiAgbGV0IG1vY2tCaXRnbzogQml0R29CYXNlO1xuICBsZXQgdXNlckdwZ0tleVBhaXI6IHBncC5TZXJpYWxpemVkS2V5UGFpcjxzdHJpbmc+O1xuICBsZXQgYmFja3VwR3BnS2V5UGFpcjogcGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz47XG4gIGxldCBiaXRnb0dwZ0tleVBhaXI6IHBncC5TZXJpYWxpemVkS2V5UGFpcjxzdHJpbmc+O1xuXG4gIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAndGVzdFBhc3MnO1xuXG4gIGJlZm9yZSgnZ2VuZXJhdGUgR1BHIGtleSBwYWlycycsIGFzeW5jICgpID0+IHtcbiAgICB1c2VyR3BnS2V5UGFpciA9IGF3YWl0IGdlbmVyYXRlR1BHS2V5UGFpcignZWQyNTUxOScpO1xuICAgIGJhY2t1cEdwZ0tleVBhaXIgPSBhd2FpdCBnZW5lcmF0ZUdQR0tleVBhaXIoJ2VkMjU1MTknKTtcbiAgICBiaXRnb0dwZ0tleVBhaXIgPSBhd2FpdCBnZW5lcmF0ZUdQR0tleVBhaXIoJ2VkMjU1MTknKTtcbiAgfSk7XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgY29uc3Qgc2pjbEVuY3J5cHQgPSAocGFyYW1zOiB7IHBhc3N3b3JkOiBzdHJpbmc7IGlucHV0OiBzdHJpbmc7IGFkYXRhPzogc3RyaW5nIH0pID0+IHtcbiAgICAgIGNvbnN0IHNhbHQgPSByYW5kb21CeXRlcyg4KTtcbiAgICAgIGNvbnN0IGl2ID0gcmFuZG9tQnl0ZXMoMTYpO1xuICAgICAgcmV0dXJuIHNqY2wuZW5jcnlwdChwYXJhbXMucGFzc3dvcmQsIHBhcmFtcy5pbnB1dCwge1xuICAgICAgICBzYWx0OiBbYnl0ZXNUb1dvcmQoc2FsdC5zdWJhcnJheSgwLCA0KSksIGJ5dGVzVG9Xb3JkKHNhbHQuc3ViYXJyYXkoNCkpXSxcbiAgICAgICAgaXY6IFtcbiAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSgwLCA0KSksXG4gICAgICAgICAgYnl0ZXNUb1dvcmQoaXYuc3ViYXJyYXkoNCwgOCkpLFxuICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDgsIDEyKSksXG4gICAgICAgICAgYnl0ZXNUb1dvcmQoaXYuc3ViYXJyYXkoMTIsIDE2KSksXG4gICAgICAgIF0sXG4gICAgICAgIGFkYXRhOiBwYXJhbXMuYWRhdGEsXG4gICAgICB9KTtcbiAgICB9O1xuICAgIG1vY2tCaXRnbyA9IHtcbiAgICAgIGVuY3J5cHQ6IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2Uoc2pjbEVuY3J5cHQpLFxuICAgICAgZW5jcnlwdEFzeW5jOiBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKGFzeW5jIChwYXJhbXMpID0+IHNqY2xFbmNyeXB0KHBhcmFtcykpLFxuICAgICAgZGVjcnlwdDogc2lub24uc3R1YigpLmNhbGxzRmFrZSgocGFyYW1zKSA9PiBzamNsLmRlY3J5cHQocGFyYW1zLnBhc3N3b3JkLCBwYXJhbXMuaW5wdXQpKSxcbiAgICAgIGRlY3J5cHRBc3luYzogc2lub24uc3R1YigpLmNhbGxzRmFrZShhc3luYyAocGFyYW1zKSA9PiBzamNsLmRlY3J5cHQocGFyYW1zLnBhc3N3b3JkLCBwYXJhbXMuaW5wdXQpKSxcbiAgICAgIGdldEVudjogc2lub24uc3R1YigpLnJldHVybnMoJ21vY2snKSxcbiAgICB9IGFzIHVua25vd24gYXMgQml0R29CYXNlO1xuXG4gICAgY29uc3QgbW9ja0NvaW4gPSB7XG4gICAgICBnZXRNUENBbGdvcml0aG06IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCdlZGRzYScpLFxuICAgIH0gYXMgdW5rbm93biBhcyBJQmFzZUNvaW47XG5cbiAgICBlZGRzYU1QQ3YyVXRpbHMgPSBuZXcgRWRkc2FNUEN2MlV0aWxzKG1vY2tCaXRnbywgbW9ja0NvaW4pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHByb2R1Y2UgdmFsaWQgc2lnbmVkTXNnMSBhbmQgZW5jcnlwdGVkIHJvdW5kLTEgc2Vzc2lvbicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5ID0gc2pjbC5lbmNyeXB0KHdhbGxldFBhc3NwaHJhc2UsIHVzZXJHcGdLZXlQYWlyLnByaXZhdGVLZXkpO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVLZXlHZW5Sb3VuZDFTaGFyZSh7XG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgIGJpdGdvR3BnUHViS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgY291bnRlclBhcnR5R3BnUHViS2V5OiBiYWNrdXBHcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICB9KTtcblxuICAgIGFzc2VydC5vayhyZXN1bHQuc2lnbmVkTXNnMS5tZXNzYWdlLCAnc2lnbmVkTXNnMS5tZXNzYWdlIHNob3VsZCBiZSBzZXQnKTtcbiAgICBhc3NlcnQub2soXG4gICAgICByZXN1bHQuc2lnbmVkTXNnMS5zaWduYXR1cmUuaW5jbHVkZXMoJ0JFR0lOIFBHUCBTSUdOQVRVUkUnKSxcbiAgICAgICdzaWduZWRNc2cxLnNpZ25hdHVyZSBzaG91bGQgYmUgUEdQIGFybW9yZWQnXG4gICAgKTtcbiAgICBhc3NlcnQub2soSlNPTi5wYXJzZShyZXN1bHQuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbikuY3QsICdlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uIHNob3VsZCBiZSBhbiBTSkNMIEpTT04gYmxvYicpO1xuICB9KTtcblxuICBpdCgnZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiBzaG91bGQgb25seSBiZSBkZWNyeXB0YWJsZSB3aXRoIGNvcnJlY3Qgd2FsbGV0UGFzc3BocmFzZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5ID0gc2pjbC5lbmNyeXB0KHdhbGxldFBhc3NwaHJhc2UsIHVzZXJHcGdLZXlQYWlyLnByaXZhdGVLZXkpO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVLZXlHZW5Sb3VuZDFTaGFyZSh7XG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgIGJpdGdvR3BnUHViS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgY291bnRlclBhcnR5R3BnUHViS2V5OiBiYWNrdXBHcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGRlY3J5cHRlZCA9IHNqY2wuZGVjcnlwdCh3YWxsZXRQYXNzcGhyYXNlLCByZXN1bHQuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbik7XG4gICAgY29uc3Qgc2Vzc2lvbiA9IEpTT04ucGFyc2UoZGVjcnlwdGVkKTtcbiAgICBhc3NlcnQub2soc2Vzc2lvbi5ka2dTZXNzaW9uLCAnZGtnU2Vzc2lvbiBzaG91bGQgYmUgcGVyc2lzdGVkJyk7XG4gICAgYXNzZXJ0Lm9rKHNlc3Npb24ub3duTXNnUGF5bG9hZCwgJ293bk1zZ1BheWxvYWQgc2hvdWxkIGJlIHBlcnNpc3RlZCcpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlb2Ygc2Vzc2lvbi5vd25Nc2dGcm9tLCAnbnVtYmVyJywgJ293bk1zZ0Zyb20gc2hvdWxkIGJlIGEgbnVtYmVyJyk7XG5cbiAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgKCkgPT4gc2pjbC5kZWNyeXB0KCd3cm9uZ3Bhc3NwaHJhc2UnLCByZXN1bHQuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiksXG4gICAgICAnc2hvdWxkIHRocm93IG9uIHdyb25nIHBhc3NwaHJhc2UnXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZXN0b3JlIERLRyBzZXNzaW9uIGFuZCBoYW5kbGUgcm91bmQtMiBtZXNzYWdlcyBhZnRlciByb3VuZCAxJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGVuY3J5cHRlZFVzZXJHcGdQcnZLZXkgPSBzamNsLmVuY3J5cHQod2FsbGV0UGFzc3BocmFzZSwgdXNlckdwZ0tleVBhaXIucHJpdmF0ZUtleSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZUtleUdlblJvdW5kMVNoYXJlKHtcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgYml0Z29HcGdQdWJLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICBjb3VudGVyUGFydHlHcGdQdWJLZXk6IGJhY2t1cEdwZ0tleVBhaXIucHVibGljS2V5LFxuICAgIH0pO1xuXG4gICAgY29uc3QgZGVjcnlwdGVkID0gc2pjbC5kZWNyeXB0KHdhbGxldFBhc3NwaHJhc2UsIHJlc3VsdC5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uKTtcbiAgICBjb25zdCB7IGRrZ1Nlc3Npb24sIG93bk1zZ1BheWxvYWQsIG93bk1zZ0Zyb20gfSA9IEpTT04ucGFyc2UoZGVjcnlwdGVkKSBhcyB7XG4gICAgICBka2dTZXNzaW9uOiBzdHJpbmc7XG4gICAgICBvd25Nc2dQYXlsb2FkOiBzdHJpbmc7XG4gICAgICBvd25Nc2dGcm9tOiBudW1iZXI7XG4gICAgfTtcblxuICAgIGNvbnN0IHJlc3RvcmVkRGtnID0gbmV3IEVkZHNhTVBTRGtnLkRLRygzLCAyLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuICAgIGF3YWl0IHJlc3RvcmVkRGtnLnJlc3RvcmVTZXNzaW9uKGRrZ1Nlc3Npb24pO1xuXG4gICAgY29uc3Qgb3duTXNnMTogTVBTVHlwZXMuRGVzZXJpYWxpemVkTWVzc2FnZSA9IHtcbiAgICAgIGZyb206IG93bk1zZ0Zyb20sXG4gICAgICBwYXlsb2FkOiBuZXcgVWludDhBcnJheShCdWZmZXIuZnJvbShvd25Nc2dQYXlsb2FkLCAnYmFzZTY0JykpLFxuICAgIH07XG4gICAgYXNzZXJ0Lm9rKG93bk1zZzEucGF5bG9hZC5sZW5ndGggPiAwLCAncmVzdG9yZWQgcGF5bG9hZCBzaG91bGQgYmUgbm9uLWVtcHR5Jyk7XG5cbiAgICBjb25zdCB1c2VyR3BnS2V5ID0gYXdhaXQgcGdwLnJlYWRLZXkoeyBhcm1vcmVkS2V5OiB1c2VyR3BnS2V5UGFpci5wdWJsaWNLZXkgfSk7XG4gICAgY29uc3QgcmF3Qnl0ZXMgPSBhd2FpdCBNUFNDb21tcy52ZXJpZnlNcHNNZXNzYWdlKHJlc3VsdC5zaWduZWRNc2cxLCB1c2VyR3BnS2V5KTtcbiAgICBhc3NlcnQub2socmF3Qnl0ZXMubGVuZ3RoID4gMCwgJ3NpZ25lZE1zZzEgc2hvdWxkIHZlcmlmeSBhZ2FpbnN0IHVzZXIgR1BHIGtleScpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJlamVjdCBpbnZhbGlkIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXknLCBhc3luYyAoKSA9PiB7XG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PlxuICAgICAgICBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZUtleUdlblJvdW5kMVNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHNqY2wuZW5jcnlwdCh3YWxsZXRQYXNzcGhyYXNlLCAnbm90LWEtZ3BnLWtleScpLFxuICAgICAgICAgIGJpdGdvR3BnUHViS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgICAgIGNvdW50ZXJQYXJ0eUdwZ1B1YktleTogYmFja3VwR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICAgIH0pLFxuICAgICAgJ3Nob3VsZCB0aHJvdyB3aGVuIEdQRyBrZXkgY2Fubm90IGJlIHBhcnNlZCdcbiAgICApO1xuICB9KTtcblxuICBpdCgnVVNFUiBhbmQgQkFDS1VQIHBhcnR5SWQgcHJvZHVjZSBkaWZmZXJlbnQgZW5jcnlwdGVkIHNlc3Npb24gc3RhdGUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdXNlckVuY3J5cHRlZEdwZ1BydktleSA9IHNqY2wuZW5jcnlwdCh3YWxsZXRQYXNzcGhyYXNlLCB1c2VyR3BnS2V5UGFpci5wcml2YXRlS2V5KTtcblxuICAgIGNvbnN0IHVzZXJSZXN1bHQgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZUtleUdlblJvdW5kMVNoYXJlKHtcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiB1c2VyRW5jcnlwdGVkR3BnUHJ2S2V5LFxuICAgICAgYml0Z29HcGdQdWJLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICBjb3VudGVyUGFydHlHcGdQdWJLZXk6IGJhY2t1cEdwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgcGFydHlJZDogTVBDdjJQYXJ0aWVzRW51bS5VU0VSLFxuICAgIH0pO1xuXG4gICAgY29uc3QgYmFja3VwRW5jcnlwdGVkR3BnUHJ2S2V5MiA9IHNqY2wuZW5jcnlwdCh3YWxsZXRQYXNzcGhyYXNlLCBiYWNrdXBHcGdLZXlQYWlyLnByaXZhdGVLZXkpO1xuICAgIGNvbnN0IGJhY2t1cFJlc3VsdCA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lS2V5R2VuUm91bmQxU2hhcmUoe1xuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IGJhY2t1cEVuY3J5cHRlZEdwZ1BydktleTIsXG4gICAgICBiaXRnb0dwZ1B1YktleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgIGNvdW50ZXJQYXJ0eUdwZ1B1YktleTogdXNlckdwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgcGFydHlJZDogTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAsXG4gICAgfSk7XG5cbiAgICBjb25zdCB1c2VyU2Vzc2lvbiA9IEpTT04ucGFyc2Uoc2pjbC5kZWNyeXB0KHdhbGxldFBhc3NwaHJhc2UsIHVzZXJSZXN1bHQuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbikpO1xuICAgIGNvbnN0IGJhY2t1cFNlc3Npb24gPSBKU09OLnBhcnNlKHNqY2wuZGVjcnlwdCh3YWxsZXRQYXNzcGhyYXNlLCBiYWNrdXBSZXN1bHQuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbikpO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHVzZXJTZXNzaW9uLm93bk1zZ0Zyb20sIE1QQ3YyUGFydGllc0VudW0uVVNFUik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJhY2t1cFNlc3Npb24ub3duTXNnRnJvbSwgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVApO1xuICAgIGFzc2VydC5ub3RTdHJpY3RFcXVhbCh1c2VyU2Vzc2lvbi5ka2dTZXNzaW9uLCBiYWNrdXBTZXNzaW9uLmRrZ1Nlc3Npb24sICdTZXNzaW9ucyBzaG91bGQgZGlmZmVyIGJldHdlZW4gcGFydGllcycpO1xuXG4gICAgLy8gU2Vzc2lvbnMgZW5jcnlwdGVkIHdpdGggcGFydHktYm91bmQgYWRhdGEg4oCUIHRhbXBlcmVkIGFkYXRhIGZhaWxzIENDTSB0YWcgY2hlY2tcbiAgICBjb25zdCB0YW1wZXJlZFNlc3Npb24gPSAoKCkgPT4ge1xuICAgICAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZSh1c2VyUmVzdWx0LmVuY3J5cHRlZFJvdW5kMVNlc3Npb24pO1xuICAgICAgcGFyc2VkLmFkYXRhID0gZW5jb2RlVVJJQ29tcG9uZW50KGBNUFNfREtHX0tFWUdFTl9ST1VORDFfU1RBVEU6JHtNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUH1gKTtcbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShwYXJzZWQpO1xuICAgIH0pKCk7XG4gICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICgpID0+IHNqY2wuZGVjcnlwdCh3YWxsZXRQYXNzcGhyYXNlLCB0YW1wZXJlZFNlc3Npb24pLFxuICAgICAgJ3Nob3VsZCBmYWlsIHRvIGRlY3J5cHQgd2l0aCB3cm9uZyBwYXJ0eSBhZGF0YSdcbiAgICApO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnRWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDJTaGFyZScsICgpID0+IHtcbiAgbGV0IGVkZHNhTVBDdjJVdGlsczogRWRkc2FNUEN2MlV0aWxzO1xuICBsZXQgbW9ja0JpdGdvOiBCaXRHb0Jhc2U7XG4gIGxldCB1c2VyS2V5U2hhcmU6IEJ1ZmZlcjtcbiAgbGV0IGJpdGdvS2V5U2hhcmU6IEJ1ZmZlcjtcbiAgbGV0IGJpdGdvR3BnS2V5UGFpcjogcGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz47XG4gIGxldCBiaXRnb0dwZ1ByaXZLZXk6IHBncC5Qcml2YXRlS2V5O1xuXG4gIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAndGVzdFBhc3MnO1xuICBjb25zdCBzaWduYWJsZUhleCA9ICdkZWFkYmVlZic7XG4gIGNvbnN0IGRlcml2YXRpb25QYXRoID0gJ20vMC8wJztcbiAgY29uc3QgZXhwZWN0ZWRBZGF0YSA9IGAke3NpZ25hYmxlSGV4fToke2Rlcml2YXRpb25QYXRofWA7XG5cbiAgY29uc3QgYmFzZVR4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgIHR4UmVxdWVzdElkOiAndHhyZXEtZWRkc2Etcm91bmQyJyxcbiAgICB3YWxsZXRJZDogJ3dhbGxldC1lZGRzYS1yb3VuZDInLFxuICAgIGVudGVycHJpc2VJZDogJ2VudGVycHJpc2UtZWRkc2Etcm91bmQyJyxcbiAgICBhcGlWZXJzaW9uOiAnZnVsbCcsXG4gICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICB7XG4gICAgICAgIHVuc2lnbmVkVHg6IHtcbiAgICAgICAgICBzaWduYWJsZUhleCxcbiAgICAgICAgICBkZXJpdmF0aW9uUGF0aCxcbiAgICAgICAgICBzZXJpYWxpemVkVHhIZXg6IHNpZ25hYmxlSGV4LFxuICAgICAgICB9LFxuICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFtdLFxuICAgICAgfSxcbiAgICBdLFxuICAgIGludGVudDogeyBpbnRlbnRUeXBlOiAncGF5bWVudCcgfSxcbiAgICB1bnNpZ25lZFR4czogW10sXG4gIH0gYXMgdW5rbm93biBhcyBUeFJlcXVlc3Q7XG5cbiAgYmVmb3JlKCdnZW5lcmF0ZSBFZERTQSBrZXkgc2hhcmVzIGFuZCBHUEcga2V5cycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBbdXNlckRrZywgLCBiaXRnb0RrZ10gPSBhd2FpdCBNUFNVdGlsLmdlbmVyYXRlRWREc2FES0dLZXlTaGFyZXMoKTtcbiAgICB1c2VyS2V5U2hhcmUgPSB1c2VyRGtnLmdldEtleVNoYXJlKCk7XG4gICAgYml0Z29LZXlTaGFyZSA9IGJpdGdvRGtnLmdldEtleVNoYXJlKCk7XG5cbiAgICBiaXRnb0dwZ0tleVBhaXIgPSBhd2FpdCBnZW5lcmF0ZUdQR0tleVBhaXIoJ2VkMjU1MTknKTtcbiAgICBiaXRnb0dwZ1ByaXZLZXkgPSBhd2FpdCBwZ3AucmVhZFByaXZhdGVLZXkoeyBhcm1vcmVkS2V5OiBiaXRnb0dwZ0tleVBhaXIucHJpdmF0ZUtleSB9KTtcbiAgfSk7XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgbW9ja0JpdGdvID0ge1xuICAgICAgZW5jcnlwdDogc2lub24uc3R1YigpLmNhbGxzRmFrZShhc3luYyAocGFyYW1zKSA9PiB7XG4gICAgICAgIGNvbnN0IHNhbHQgPSByYW5kb21CeXRlcyg4KTtcbiAgICAgICAgY29uc3QgaXYgPSByYW5kb21CeXRlcygxNik7XG4gICAgICAgIHJldHVybiBzamNsLmVuY3J5cHQocGFyYW1zLnBhc3N3b3JkLCBwYXJhbXMuaW5wdXQsIHtcbiAgICAgICAgICBzYWx0OiBbYnl0ZXNUb1dvcmQoc2FsdC5zdWJhcnJheSgwLCA0KSksIGJ5dGVzVG9Xb3JkKHNhbHQuc3ViYXJyYXkoNCkpXSxcbiAgICAgICAgICBpdjogW1xuICAgICAgICAgICAgYnl0ZXNUb1dvcmQoaXYuc3ViYXJyYXkoMCwgNCkpLFxuICAgICAgICAgICAgYnl0ZXNUb1dvcmQoaXYuc3ViYXJyYXkoNCwgOCkpLFxuICAgICAgICAgICAgYnl0ZXNUb1dvcmQoaXYuc3ViYXJyYXkoOCwgMTIpKSxcbiAgICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDEyLCAxNikpLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgYWRhdGE6IHBhcmFtcy5hZGF0YSxcbiAgICAgICAgfSk7XG4gICAgICB9KSxcbiAgICAgIGRlY3J5cHQ6IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoYXN5bmMgKHBhcmFtcykgPT4gc2pjbC5kZWNyeXB0KHBhcmFtcy5wYXNzd29yZCwgcGFyYW1zLmlucHV0KSksXG4gICAgfSBhcyB1bmtub3duIGFzIEJpdEdvQmFzZTtcblxuICAgIGNvbnN0IG1vY2tDb2luID0ge1xuICAgICAgZ2V0TVBDQWxnb3JpdGhtOiBzaW5vbi5zdHViKCkucmV0dXJucygnZWRkc2EnKSxcbiAgICB9IGFzIHVua25vd24gYXMgSUJhc2VDb2luO1xuXG4gICAgZWRkc2FNUEN2MlV0aWxzID0gbmV3IEVkZHNhTVBDdjJVdGlscyhtb2NrQml0Z28sIG1vY2tDb2luKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBjcmVhdGUgYSByb3VuZC0yIHNoYXJlIGZyb20gb2ZmbGluZSByb3VuZCAxJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJvdW5kMSA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0OiBiYXNlVHhSZXF1ZXN0LFxuICAgICAgcHJ2OiB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbShzaWduYWJsZUhleCwgJ2hleCcpO1xuICAgIGNvbnN0IGJpdGdvRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhd2FpdCBiaXRnb0RzZy5pbml0RHNnKGJpdGdvS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuXG4gICAgY29uc3QgdHhSZXF1ZXN0Um91bmQxID0gYXdhaXQgc2lnbkJpdGdvRWRkc2FSb3VuZDEoXG4gICAgICBiaXRnb0RzZyxcbiAgICAgIGNsb25lVHhSZXF1ZXN0V2l0aEVtcHR5U2lnbmF0dXJlU2hhcmVzKGJhc2VUeFJlcXVlc3QpLFxuICAgICAgcm91bmQxLnNpZ25hdHVyZVNoYXJlUm91bmQxLFxuICAgICAgcm91bmQxLnVzZXJHcGdQdWJLZXksXG4gICAgICBiaXRnb0dwZ1ByaXZLZXlcbiAgICApO1xuXG4gICAgY29uc3Qgcm91bmQyID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDJTaGFyZSh7XG4gICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdFJvdW5kMSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbjogcm91bmQxLmVuY3J5cHRlZFJvdW5kMVNlc3Npb24sXG4gICAgfSk7XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocm91bmQyLnNpZ25hdHVyZVNoYXJlUm91bmQyLmZyb20sIFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocm91bmQyLnNpZ25hdHVyZVNoYXJlUm91bmQyLnRvLCBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08pO1xuXG4gICAgY29uc3QgcGFyc2VkU2hhcmUgPSBkZWNvZGVXaXRoQ29kZWMoXG4gICAgICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJJbnB1dCxcbiAgICAgIEpTT04ucGFyc2Uocm91bmQyLnNpZ25hdHVyZVNoYXJlUm91bmQyLnNoYXJlKSxcbiAgICAgICdFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJJbnB1dCdcbiAgICApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChwYXJzZWRTaGFyZS50eXBlLCAncm91bmQySW5wdXQnKTtcbiAgICBhc3NlcnQub2socGFyc2VkU2hhcmUuZGF0YS5tc2cyLm1lc3NhZ2UsICdtc2cyLm1lc3NhZ2Ugc2hvdWxkIGJlIHNldCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWRTaGFyZS5kYXRhLm1zZzIuc2lnbmF0dXJlLCAnbXNnMi5zaWduYXR1cmUgc2hvdWxkIGJlIHNldCcpO1xuXG4gICAgY29uc3QgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbiA9IEpTT04ucGFyc2Uocm91bmQyLmVuY3J5cHRlZFJvdW5kMlNlc3Npb24pO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgIGRlY29kZVVSSUNvbXBvbmVudChlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLmFkYXRhKSxcbiAgICAgIGBNUFNfRFNHX1NJR05JTkdfUk9VTkQyX1NUQVRFOiR7ZXhwZWN0ZWRBZGF0YX1gXG4gICAgKTtcblxuICAgIGNvbnN0IHNlc3Npb25QYXlsb2FkID0gSlNPTi5wYXJzZShzamNsLmRlY3J5cHQod2FsbGV0UGFzc3BocmFzZSwgcm91bmQyLmVuY3J5cHRlZFJvdW5kMlNlc3Npb24pKTtcbiAgICBhc3NlcnQub2soc2Vzc2lvblBheWxvYWQuZHNnU2Vzc2lvbiwgJ2RzZ1Nlc3Npb24gc2hvdWxkIGJlIHBlcnNpc3RlZCBmb3Igcm91bmQgMycpO1xuICAgIGFzc2VydC5vayhzZXNzaW9uUGF5bG9hZC51c2VyTXNnUGF5bG9hZCwgJ3VzZXJNc2dQYXlsb2FkIHNob3VsZCBiZSBwZXJzaXN0ZWQgZm9yIHJvdW5kIDMnKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB1c2UgdjIgZGVjcnlwdGlvbiB3aGVuIGVuY3J5cHRlZFJvdW5kMVNlc3Npb24gaXMgYSB2MiBlbnZlbG9wZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBlbmNyeXB0ID0gc2lub25cbiAgICAgIC5zdHViKClcbiAgICAgIC5jYWxsc0Zha2UoKGlucHV0OiBzdHJpbmcsIGFkYXRhOiBzdHJpbmcpID0+IFByb21pc2UucmVzb2x2ZShKU09OLnN0cmluZ2lmeSh7IHY6IDIsIGlucHV0LCBhZGF0YSB9KSkpO1xuICAgIGNvbnN0IGRlc3Ryb3kgPSBzaW5vbi5zdHViKCk7XG4gICAgY29uc3QgY3JlYXRlRW5jcnlwdGlvblNlc3Npb24gPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBlbmNyeXB0LCBkZXN0cm95IH0pO1xuICAgIG1vY2tCaXRnby5jcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbiA9IGNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uO1xuXG4gICAgY29uc3Qgcm91bmQxID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZSh7XG4gICAgICB0eFJlcXVlc3Q6IGJhc2VUeFJlcXVlc3QsXG4gICAgICBwcnY6IHVzZXJLZXlTaGFyZS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgZW5jcnlwdGVkUHJ2OiBKU09OLnN0cmluZ2lmeSh7IHY6IDIgfSksXG4gICAgfSk7XG5cbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCBiaXRnb0RzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYXdhaXQgYml0Z29Ec2cuaW5pdERzZyhiaXRnb0tleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcblxuICAgIGNvbnN0IHR4UmVxdWVzdFJvdW5kMSA9IGF3YWl0IHNpZ25CaXRnb0VkZHNhUm91bmQxKFxuICAgICAgYml0Z29Ec2csXG4gICAgICBjbG9uZVR4UmVxdWVzdFdpdGhFbXB0eVNpZ25hdHVyZVNoYXJlcyhiYXNlVHhSZXF1ZXN0KSxcbiAgICAgIHJvdW5kMS5zaWduYXR1cmVTaGFyZVJvdW5kMSxcbiAgICAgIHJvdW5kMS51c2VyR3BnUHViS2V5LFxuICAgICAgYml0Z29HcGdQcml2S2V5XG4gICAgKTtcblxuICAgIGNvbnN0IGRlY3J5cHQgPSBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKGFzeW5jIChwYXJhbXM6IHsgaW5wdXQ6IHN0cmluZyB9KSA9PiB7XG4gICAgICBjb25zdCBlbnZlbG9wZSA9IEpTT04ucGFyc2UocGFyYW1zLmlucHV0KTtcbiAgICAgIHJldHVybiBlbnZlbG9wZS5pbnB1dDtcbiAgICB9KTtcbiAgICBtb2NrQml0Z28uZGVjcnlwdCA9IGRlY3J5cHQ7XG5cbiAgICBjb25zdCByb3VuZDIgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMlNoYXJlKHtcbiAgICAgIHR4UmVxdWVzdDogdHhSZXF1ZXN0Um91bmQxLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogcm91bmQxLmVuY3J5cHRlZFVzZXJHcGdQcnZLZXksXG4gICAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uOiByb3VuZDEuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbixcbiAgICB9KTtcblxuICAgIHNpbm9uLmFzc2VydC5jYWxsZWQobW9ja0JpdGdvLmRlY3J5cHQgYXMgc2lub24uU2lub25TdHViKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocm91bmQyLnNpZ25hdHVyZVNoYXJlUm91bmQyLmZyb20sIFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSKTtcblxuICAgIGNvbnN0IGVuY3J5cHRlZFJvdW5kMlNlc3Npb24gPSBKU09OLnBhcnNlKHJvdW5kMi5lbmNyeXB0ZWRSb3VuZDJTZXNzaW9uKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZW5jcnlwdGVkUm91bmQyU2Vzc2lvbi52LCAyKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZW5jcnlwdGVkUm91bmQyU2Vzc2lvbi5hZGF0YSwgYE1QU19EU0dfU0lHTklOR19ST1VORDJfU1RBVEU6JHtleHBlY3RlZEFkYXRhfWApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJlamVjdCB0YW1wZXJlZCBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uIGFkYXRhJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG90aGVyVHhSZXF1ZXN0OiBUeFJlcXVlc3QgPSB7XG4gICAgICAuLi5iYXNlVHhSZXF1ZXN0LFxuICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgICBzaWduYWJsZUhleDogJ2NhZmViYWJlJyxcbiAgICAgICAgICAgIGRlcml2YXRpb25QYXRoOiAnbS8xLzInLFxuICAgICAgICAgICAgc2VyaWFsaXplZFR4SGV4OiAnY2FmZWJhYmUnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSBhcyB1bmtub3duIGFzIFR4UmVxdWVzdDtcblxuICAgIGNvbnN0IHJvdW5kMU90aGVyID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZSh7XG4gICAgICB0eFJlcXVlc3Q6IG90aGVyVHhSZXF1ZXN0LFxuICAgICAgcHJ2OiB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJvdW5kMSA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0OiBiYXNlVHhSZXF1ZXN0LFxuICAgICAgcHJ2OiB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbShzaWduYWJsZUhleCwgJ2hleCcpO1xuICAgIGNvbnN0IGJpdGdvRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhd2FpdCBiaXRnb0RzZy5pbml0RHNnKGJpdGdvS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuXG4gICAgY29uc3QgdHhSZXF1ZXN0Um91bmQxID0gYXdhaXQgc2lnbkJpdGdvRWRkc2FSb3VuZDEoXG4gICAgICBiaXRnb0RzZyxcbiAgICAgIGNsb25lVHhSZXF1ZXN0V2l0aEVtcHR5U2lnbmF0dXJlU2hhcmVzKGJhc2VUeFJlcXVlc3QpLFxuICAgICAgcm91bmQxLnNpZ25hdHVyZVNoYXJlUm91bmQxLFxuICAgICAgcm91bmQxLnVzZXJHcGdQdWJLZXksXG4gICAgICBiaXRnb0dwZ1ByaXZLZXlcbiAgICApO1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PlxuICAgICAgICBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMlNoYXJlKHtcbiAgICAgICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdFJvdW5kMSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246IHJvdW5kMU90aGVyLmVuY3J5cHRlZFJvdW5kMVNlc3Npb24sXG4gICAgICAgIH0pLFxuICAgICAgL0FkYXRhIGRvZXMgbm90IG1hdGNoIGN5cGhlcnRleHQgYWRhdGEvXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWplY3QgdGFtcGVyZWQgZW5jcnlwdGVkVXNlckdwZ1BydktleSBhZGF0YScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBvdGhlclR4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgICAgLi4uYmFzZVR4UmVxdWVzdCxcbiAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICB7XG4gICAgICAgICAgdW5zaWduZWRUeDoge1xuICAgICAgICAgICAgc2lnbmFibGVIZXg6ICdjYWZlYmFiZScsXG4gICAgICAgICAgICBkZXJpdmF0aW9uUGF0aDogJ20vMS8yJyxcbiAgICAgICAgICAgIHNlcmlhbGl6ZWRUeEhleDogJ2NhZmViYWJlJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogW10sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0gYXMgdW5rbm93biBhcyBUeFJlcXVlc3Q7XG5cbiAgICBjb25zdCByb3VuZDFPdGhlciA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0OiBvdGhlclR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgfSk7XG5cbiAgICBjb25zdCByb3VuZDEgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHtcbiAgICAgIHR4UmVxdWVzdDogYmFzZVR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgfSk7XG5cbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCBiaXRnb0RzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYXdhaXQgYml0Z29Ec2cuaW5pdERzZyhiaXRnb0tleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcblxuICAgIGNvbnN0IHR4UmVxdWVzdFJvdW5kMSA9IGF3YWl0IHNpZ25CaXRnb0VkZHNhUm91bmQxKFxuICAgICAgYml0Z29Ec2csXG4gICAgICBjbG9uZVR4UmVxdWVzdFdpdGhFbXB0eVNpZ25hdHVyZVNoYXJlcyhiYXNlVHhSZXF1ZXN0KSxcbiAgICAgIHJvdW5kMS5zaWduYXR1cmVTaGFyZVJvdW5kMSxcbiAgICAgIHJvdW5kMS51c2VyR3BnUHViS2V5LFxuICAgICAgYml0Z29HcGdQcml2S2V5XG4gICAgKTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDJTaGFyZSh7XG4gICAgICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3RSb3VuZDEsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDFPdGhlci5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246IHJvdW5kMS5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLFxuICAgICAgICB9KSxcbiAgICAgIC9BZGF0YSBkb2VzIG5vdCBtYXRjaCBjeXBoZXJ0ZXh0IGFkYXRhL1xuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmVqZWN0IHdoZW4gQml0R28gc2lnbmF0dXJlIHNoYXJlIGlzIG1pc3NpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qgcm91bmQxID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZSh7XG4gICAgICB0eFJlcXVlc3Q6IGJhc2VUeFJlcXVlc3QsXG4gICAgICBwcnY6IHVzZXJLZXlTaGFyZS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgYmFzZVRyYW5zYWN0aW9uID0gYXNzZXJ0U2luZ2xlVHJhbnNhY3Rpb24oYmFzZVR4UmVxdWVzdCk7XG4gICAgY29uc3QgdHhSZXF1ZXN0Tm9CaXRnb1NoYXJlOiBUeFJlcXVlc3QgPSB7XG4gICAgICAuLi5iYXNlVHhSZXF1ZXN0LFxuICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICAuLi5iYXNlVHJhbnNhY3Rpb24sXG4gICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbcm91bmQxLnNpZ25hdHVyZVNoYXJlUm91bmQxXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDJTaGFyZSh7XG4gICAgICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3ROb0JpdGdvU2hhcmUsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDEuZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgICAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uOiByb3VuZDEuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbixcbiAgICAgICAgfSksXG4gICAgICAvTWlzc2luZyBCaXRHbyByb3VuZDFPdXRwdXQgc2lnbmF0dXJlIHNoYXJlL1xuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcHJvcGFnYXRlIHRoZSB0eC1vbmx5IGd1YXJkIHdoZW4gdHJhbnNhY3Rpb25zIGFyZSBtaXNzaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJvdW5kMSA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0OiBiYXNlVHhSZXF1ZXN0LFxuICAgICAgcHJ2OiB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICB9KTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDJTaGFyZSh7XG4gICAgICAgICAgdHhSZXF1ZXN0OiB7IC4uLmJhc2VUeFJlcXVlc3QsIHRyYW5zYWN0aW9uczogdW5kZWZpbmVkIH0gYXMgdW5rbm93biBhcyBUeFJlcXVlc3QsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDEuZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgICAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uOiByb3VuZDEuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbixcbiAgICAgICAgfSksXG4gICAgICAvVW5hYmxlIHRvIGZpbmQgdHJhbnNhY3Rpb25zIGluIHR4UmVxdWVzdC9cbiAgICApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJlamVjdCB3aGVuIHRyYW5zYWN0aW9ucyBhcnJheSBpcyBlbXB0eScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByb3VuZDEgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHtcbiAgICAgIHR4UmVxdWVzdDogYmFzZVR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgfSk7XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+XG4gICAgICAgIGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQyU2hhcmUoe1xuICAgICAgICAgIHR4UmVxdWVzdDogeyAuLi5iYXNlVHhSZXF1ZXN0LCB0cmFuc2FjdGlvbnM6IFtdIH0sXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDEuZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgICAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uOiByb3VuZDEuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbixcbiAgICAgICAgfSksXG4gICAgICAvVW5hYmxlIHRvIGZpbmQgdHJhbnNhY3Rpb25zIGluIHR4UmVxdWVzdC9cbiAgICApO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnRWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDNTaGFyZScsICgpID0+IHtcbiAgbGV0IGVkZHNhTVBDdjJVdGlsczogRWRkc2FNUEN2MlV0aWxzO1xuICBsZXQgbW9ja0JpdGdvOiBCaXRHb0Jhc2U7XG4gIGxldCB1c2VyS2V5U2hhcmU6IEJ1ZmZlcjtcbiAgbGV0IGJpdGdvS2V5U2hhcmU6IEJ1ZmZlcjtcbiAgbGV0IGJpdGdvR3BnS2V5UGFpcjogcGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz47XG4gIGxldCBiaXRnb0dwZ1ByaXZLZXk6IHBncC5Qcml2YXRlS2V5O1xuXG4gIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAndGVzdFBhc3MnO1xuICBjb25zdCBzaWduYWJsZUhleCA9ICdkZWFkYmVlZic7XG4gIGNvbnN0IGRlcml2YXRpb25QYXRoID0gJ20vMC8wJztcblxuICBjb25zdCBiYXNlVHhSZXF1ZXN0OiBUeFJlcXVlc3QgPSB7XG4gICAgdHhSZXF1ZXN0SWQ6ICd0eHJlcS1lZGRzYS1yb3VuZDMnLFxuICAgIHdhbGxldElkOiAnd2FsbGV0LWVkZHNhLXJvdW5kMycsXG4gICAgZW50ZXJwcmlzZUlkOiAnZW50ZXJwcmlzZS1lZGRzYS1yb3VuZDMnLFxuICAgIGFwaVZlcnNpb246ICdmdWxsJyxcbiAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgIHtcbiAgICAgICAgdW5zaWduZWRUeDoge1xuICAgICAgICAgIHNpZ25hYmxlSGV4LFxuICAgICAgICAgIGRlcml2YXRpb25QYXRoLFxuICAgICAgICAgIHNlcmlhbGl6ZWRUeEhleDogc2lnbmFibGVIZXgsXG4gICAgICAgIH0sXG4gICAgICAgIHNpZ25hdHVyZVNoYXJlczogW10sXG4gICAgICB9LFxuICAgIF0sXG4gICAgaW50ZW50OiB7IGludGVudFR5cGU6ICdwYXltZW50JyB9LFxuICAgIHVuc2lnbmVkVHhzOiBbXSxcbiAgfSBhcyB1bmtub3duIGFzIFR4UmVxdWVzdDtcblxuICBiZWZvcmUoJ2dlbmVyYXRlIEVkRFNBIGtleSBzaGFyZXMgYW5kIEdQRyBrZXlzJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IFt1c2VyRGtnLCAsIGJpdGdvRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIHVzZXJLZXlTaGFyZSA9IHVzZXJEa2cuZ2V0S2V5U2hhcmUoKTtcbiAgICBiaXRnb0tleVNoYXJlID0gYml0Z29Ea2cuZ2V0S2V5U2hhcmUoKTtcblxuICAgIGJpdGdvR3BnS2V5UGFpciA9IGF3YWl0IGdlbmVyYXRlR1BHS2V5UGFpcignZWQyNTUxOScpO1xuICAgIGJpdGdvR3BnUHJpdktleSA9IGF3YWl0IHBncC5yZWFkUHJpdmF0ZUtleSh7IGFybW9yZWRLZXk6IGJpdGdvR3BnS2V5UGFpci5wcml2YXRlS2V5IH0pO1xuICB9KTtcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBtb2NrQml0Z28gPSB7XG4gICAgICBlbmNyeXB0OiBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKGFzeW5jIChwYXJhbXMpID0+IHtcbiAgICAgICAgY29uc3Qgc2FsdCA9IHJhbmRvbUJ5dGVzKDgpO1xuICAgICAgICBjb25zdCBpdiA9IHJhbmRvbUJ5dGVzKDE2KTtcbiAgICAgICAgcmV0dXJuIHNqY2wuZW5jcnlwdChwYXJhbXMucGFzc3dvcmQsIHBhcmFtcy5pbnB1dCwge1xuICAgICAgICAgIHNhbHQ6IFtieXRlc1RvV29yZChzYWx0LnN1YmFycmF5KDAsIDQpKSwgYnl0ZXNUb1dvcmQoc2FsdC5zdWJhcnJheSg0KSldLFxuICAgICAgICAgIGl2OiBbXG4gICAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSgwLCA0KSksXG4gICAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSg0LCA4KSksXG4gICAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSg4LCAxMikpLFxuICAgICAgICAgICAgYnl0ZXNUb1dvcmQoaXYuc3ViYXJyYXkoMTIsIDE2KSksXG4gICAgICAgICAgXSxcbiAgICAgICAgICBhZGF0YTogcGFyYW1zLmFkYXRhLFxuICAgICAgICB9KTtcbiAgICAgIH0pLFxuICAgICAgZGVjcnlwdDogc2lub24uc3R1YigpLmNhbGxzRmFrZShhc3luYyAocGFyYW1zKSA9PiBzamNsLmRlY3J5cHQocGFyYW1zLnBhc3N3b3JkLCBwYXJhbXMuaW5wdXQpKSxcbiAgICB9IGFzIHVua25vd24gYXMgQml0R29CYXNlO1xuXG4gICAgY29uc3QgbW9ja0NvaW4gPSB7XG4gICAgICBnZXRNUENBbGdvcml0aG06IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCdlZGRzYScpLFxuICAgIH0gYXMgdW5rbm93biBhcyBJQmFzZUNvaW47XG5cbiAgICBlZGRzYU1QQ3YyVXRpbHMgPSBuZXcgRWRkc2FNUEN2MlV0aWxzKG1vY2tCaXRnbywgbW9ja0NvaW4pO1xuICB9KTtcblxuICBhc3luYyBmdW5jdGlvbiBjcmVhdGVSb3VuZDJGbG93KFxuICAgIHR4UmVxdWVzdDogVHhSZXF1ZXN0LFxuICAgIGVuY3J5cHRlZFBydj86IHN0cmluZ1xuICApOiBQcm9taXNlPHtcbiAgICByb3VuZDE6IHtcbiAgICAgIHNpZ25hdHVyZVNoYXJlUm91bmQxOiBTaWduYXR1cmVTaGFyZVJlY29yZDtcbiAgICAgIHVzZXJHcGdQdWJLZXk6IHN0cmluZztcbiAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246IHN0cmluZztcbiAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHN0cmluZztcbiAgICB9O1xuICAgIHJvdW5kMjoge1xuICAgICAgc2lnbmF0dXJlU2hhcmVSb3VuZDI6IFNpZ25hdHVyZVNoYXJlUmVjb3JkO1xuICAgICAgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbjogc3RyaW5nO1xuICAgIH07XG4gICAgdHhSZXF1ZXN0Um91bmQxOiBUeFJlcXVlc3Q7XG4gICAgdHhSZXF1ZXN0Um91bmQyOiBUeFJlcXVlc3Q7XG4gICAgbWVzc2FnZUJ1ZmZlcjogQnVmZmVyO1xuICB9PiB7XG4gICAgY29uc3Qgcm91bmQxID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZSh7XG4gICAgICB0eFJlcXVlc3QsXG4gICAgICBwcnY6IHVzZXJLZXlTaGFyZS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgZW5jcnlwdGVkUHJ2LFxuICAgIH0pO1xuXG4gICAgY29uc3QgdHJhbnNhY3Rpb24gPSBhc3NlcnRTaW5nbGVUcmFuc2FjdGlvbih0eFJlcXVlc3QpO1xuICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbSh0cmFuc2FjdGlvbi51bnNpZ25lZFR4LnNpZ25hYmxlSGV4LCAnaGV4Jyk7XG4gICAgY29uc3QgYml0Z29Ec2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGF3YWl0IGJpdGdvRHNnLmluaXREc2coYml0Z29LZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgdHJhbnNhY3Rpb24udW5zaWduZWRUeC5kZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcblxuICAgIGNvbnN0IHR4UmVxdWVzdFJvdW5kMSA9IGF3YWl0IHNpZ25CaXRnb0VkZHNhUm91bmQxKFxuICAgICAgYml0Z29Ec2csXG4gICAgICBjbG9uZVR4UmVxdWVzdFdpdGhFbXB0eVNpZ25hdHVyZVNoYXJlcyh0eFJlcXVlc3QpLFxuICAgICAgcm91bmQxLnNpZ25hdHVyZVNoYXJlUm91bmQxLFxuICAgICAgcm91bmQxLnVzZXJHcGdQdWJLZXksXG4gICAgICBiaXRnb0dwZ1ByaXZLZXlcbiAgICApO1xuXG4gICAgY29uc3Qgcm91bmQyID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDJTaGFyZSh7XG4gICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdFJvdW5kMSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbjogcm91bmQxLmVuY3J5cHRlZFJvdW5kMVNlc3Npb24sXG4gICAgfSk7XG5cbiAgICBjb25zdCByb3VuZDFUcmFuc2FjdGlvbiA9IGFzc2VydFNpbmdsZVRyYW5zYWN0aW9uKHR4UmVxdWVzdFJvdW5kMSk7XG4gICAgY29uc3QgdHhSZXF1ZXN0Um91bmQyID0gYXdhaXQgc2lnbkJpdGdvRWRkc2FSb3VuZDIoXG4gICAgICBiaXRnb0RzZyxcbiAgICAgIHtcbiAgICAgICAgLi4udHhSZXF1ZXN0Um91bmQxLFxuICAgICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi5yb3VuZDFUcmFuc2FjdGlvbixcbiAgICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogWy4uLnJvdW5kMVRyYW5zYWN0aW9uLnNpZ25hdHVyZVNoYXJlc10sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgICByb3VuZDIuc2lnbmF0dXJlU2hhcmVSb3VuZDIsXG4gICAgICByb3VuZDEudXNlckdwZ1B1YktleSxcbiAgICAgIGJpdGdvR3BnUHJpdktleVxuICAgICk7XG5cbiAgICByZXR1cm4geyByb3VuZDEsIHJvdW5kMiwgdHhSZXF1ZXN0Um91bmQxLCB0eFJlcXVlc3RSb3VuZDIsIG1lc3NhZ2VCdWZmZXIgfTtcbiAgfVxuXG4gIGl0KCdzaG91bGQgY3JlYXRlIGEgcm91bmQtMyBzaGFyZSBmcm9tIG9mZmxpbmUgcm91bmQgMicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB7IHJvdW5kMSwgcm91bmQyLCB0eFJlcXVlc3RSb3VuZDIgfSA9IGF3YWl0IGNyZWF0ZVJvdW5kMkZsb3coYmFzZVR4UmVxdWVzdCk7XG5cbiAgICBjb25zdCByb3VuZDMgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kM1NoYXJlKHtcbiAgICAgIHR4UmVxdWVzdDogdHhSZXF1ZXN0Um91bmQyLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogcm91bmQxLmVuY3J5cHRlZFVzZXJHcGdQcnZLZXksXG4gICAgICBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uOiByb3VuZDIuZW5jcnlwdGVkUm91bmQyU2Vzc2lvbixcbiAgICB9KTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyb3VuZDMuc2lnbmF0dXJlU2hhcmVSb3VuZDMuZnJvbSwgU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyb3VuZDMuc2lnbmF0dXJlU2hhcmVSb3VuZDMudG8sIFNpZ25hdHVyZVNoYXJlVHlwZS5CSVRHTyk7XG5cbiAgICBjb25zdCBwYXJzZWRTaGFyZSA9IGRlY29kZVdpdGhDb2RlYyhcbiAgICAgIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kM0lucHV0LFxuICAgICAgSlNPTi5wYXJzZShyb3VuZDMuc2lnbmF0dXJlU2hhcmVSb3VuZDMuc2hhcmUpLFxuICAgICAgJ0VkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kM0lucHV0J1xuICAgICk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBhcnNlZFNoYXJlLnR5cGUsICdyb3VuZDNJbnB1dCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWRTaGFyZS5kYXRhLm1zZzMubWVzc2FnZSwgJ21zZzMubWVzc2FnZSBzaG91bGQgYmUgc2V0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZFNoYXJlLmRhdGEubXNnMy5zaWduYXR1cmUsICdtc2czLnNpZ25hdHVyZSBzaG91bGQgYmUgc2V0Jyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgdXNlIHYyIGRlY3J5cHRpb24gd2hlbiBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uIGlzIGEgdjIgZW52ZWxvcGUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZW5jcnlwdCA9IHNpbm9uXG4gICAgICAuc3R1YigpXG4gICAgICAuY2FsbHNGYWtlKChpbnB1dDogc3RyaW5nLCBhZGF0YTogc3RyaW5nKSA9PiBQcm9taXNlLnJlc29sdmUoSlNPTi5zdHJpbmdpZnkoeyB2OiAyLCBpbnB1dCwgYWRhdGEgfSkpKTtcbiAgICBjb25zdCBkZXN0cm95ID0gc2lub24uc3R1YigpO1xuICAgIGNvbnN0IGNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uID0gc2lub24uc3R1YigpLnJlc29sdmVzKHsgZW5jcnlwdCwgZGVzdHJveSB9KTtcbiAgICBtb2NrQml0Z28uY3JlYXRlRW5jcnlwdGlvblNlc3Npb24gPSBjcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbjtcblxuICAgIGNvbnN0IGRlY3J5cHQgPSBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKGFzeW5jIChwYXJhbXM6IHsgaW5wdXQ6IHN0cmluZyB9KSA9PiB7XG4gICAgICBjb25zdCBlbnZlbG9wZSA9IEpTT04ucGFyc2UocGFyYW1zLmlucHV0KTtcbiAgICAgIHJldHVybiBlbnZlbG9wZS5pbnB1dDtcbiAgICB9KTtcbiAgICBtb2NrQml0Z28uZGVjcnlwdCA9IGRlY3J5cHQ7XG5cbiAgICBjb25zdCB7IHJvdW5kMSwgcm91bmQyLCB0eFJlcXVlc3RSb3VuZDIgfSA9IGF3YWl0IGNyZWF0ZVJvdW5kMkZsb3coYmFzZVR4UmVxdWVzdCwgSlNPTi5zdHJpbmdpZnkoeyB2OiAyIH0pKTtcblxuICAgIGNvbnN0IHJvdW5kMyA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQzU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3RSb3VuZDIsXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgYml0Z29QdWJsaWNHcGdLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDEuZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgIGVuY3J5cHRlZFJvdW5kMlNlc3Npb246IHJvdW5kMi5lbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLFxuICAgIH0pO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKChtb2NrQml0Z28uZGVjcnlwdCBhcyBzaW5vbi5TaW5vblN0dWIpLmNhbGxDb3VudCwgNCk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJvdW5kMy5zaWduYXR1cmVTaGFyZVJvdW5kMy5mcm9tLCBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUik7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmVqZWN0IHRhbXBlcmVkIGVuY3J5cHRlZFJvdW5kMlNlc3Npb24gYWRhdGEnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qgb3RoZXJUeFJlcXVlc3Q6IFR4UmVxdWVzdCA9IHtcbiAgICAgIC4uLmJhc2VUeFJlcXVlc3QsXG4gICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAge1xuICAgICAgICAgIHVuc2lnbmVkVHg6IHtcbiAgICAgICAgICAgIHNpZ25hYmxlSGV4OiAnY2FmZWJhYmUnLFxuICAgICAgICAgICAgZGVyaXZhdGlvblBhdGg6ICdtLzEvMicsXG4gICAgICAgICAgICBzZXJpYWxpemVkVHhIZXg6ICdjYWZlYmFiZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFtdLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9IGFzIHVua25vd24gYXMgVHhSZXF1ZXN0O1xuXG4gICAgY29uc3Qgb3RoZXJGbG93ID0gYXdhaXQgY3JlYXRlUm91bmQyRmxvdyhvdGhlclR4UmVxdWVzdCk7XG4gICAgY29uc3QgeyByb3VuZDEsIHR4UmVxdWVzdFJvdW5kMiB9ID0gYXdhaXQgY3JlYXRlUm91bmQyRmxvdyhiYXNlVHhSZXF1ZXN0KTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDNTaGFyZSh7XG4gICAgICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3RSb3VuZDIsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDEuZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgICAgICBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uOiBvdGhlckZsb3cucm91bmQyLmVuY3J5cHRlZFJvdW5kMlNlc3Npb24sXG4gICAgICAgIH0pLFxuICAgICAgL0FkYXRhIGRvZXMgbm90IG1hdGNoIGN5cGhlcnRleHQgYWRhdGEvXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWplY3QgdGFtcGVyZWQgZW5jcnlwdGVkVXNlckdwZ1BydktleSBhZGF0YScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBvdGhlclR4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgICAgLi4uYmFzZVR4UmVxdWVzdCxcbiAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICB7XG4gICAgICAgICAgdW5zaWduZWRUeDoge1xuICAgICAgICAgICAgc2lnbmFibGVIZXg6ICdjYWZlYmFiZScsXG4gICAgICAgICAgICBkZXJpdmF0aW9uUGF0aDogJ20vMS8yJyxcbiAgICAgICAgICAgIHNlcmlhbGl6ZWRUeEhleDogJ2NhZmViYWJlJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogW10sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0gYXMgdW5rbm93biBhcyBUeFJlcXVlc3Q7XG5cbiAgICBjb25zdCBvdGhlckZsb3cgPSBhd2FpdCBjcmVhdGVSb3VuZDJGbG93KG90aGVyVHhSZXF1ZXN0KTtcbiAgICBjb25zdCB7IHJvdW5kMiwgdHhSZXF1ZXN0Um91bmQyIH0gPSBhd2FpdCBjcmVhdGVSb3VuZDJGbG93KGJhc2VUeFJlcXVlc3QpO1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PlxuICAgICAgICBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kM1NoYXJlKHtcbiAgICAgICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdFJvdW5kMixcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IG90aGVyRmxvdy5yb3VuZDEuZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgICAgICBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uOiByb3VuZDIuZW5jcnlwdGVkUm91bmQyU2Vzc2lvbixcbiAgICAgICAgfSksXG4gICAgICAvQWRhdGEgZG9lcyBub3QgbWF0Y2ggY3lwaGVydGV4dCBhZGF0YS9cbiAgICApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJlamVjdCB3aGVuIEJpdEdvIHJvdW5kLTIgc2lnbmF0dXJlIHNoYXJlIGlzIG1pc3NpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeyByb3VuZDEsIHJvdW5kMiwgdHhSZXF1ZXN0Um91bmQxIH0gPSBhd2FpdCBjcmVhdGVSb3VuZDJGbG93KGJhc2VUeFJlcXVlc3QpO1xuXG4gICAgY29uc3Qgcm91bmQxVHJhbnNhY3Rpb24gPSBhc3NlcnRTaW5nbGVUcmFuc2FjdGlvbih0eFJlcXVlc3RSb3VuZDEpO1xuICAgIGNvbnN0IHR4UmVxdWVzdE5vQml0Z29Sb3VuZDJTaGFyZTogVHhSZXF1ZXN0ID0ge1xuICAgICAgLi4udHhSZXF1ZXN0Um91bmQxLFxuICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICAuLi5yb3VuZDFUcmFuc2FjdGlvbixcbiAgICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFsuLi5yb3VuZDFUcmFuc2FjdGlvbi5zaWduYXR1cmVTaGFyZXMsIHJvdW5kMi5zaWduYXR1cmVTaGFyZVJvdW5kMl0sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+XG4gICAgICAgIGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQzU2hhcmUoe1xuICAgICAgICAgIHR4UmVxdWVzdDogdHhSZXF1ZXN0Tm9CaXRnb1JvdW5kMlNoYXJlLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgYml0Z29QdWJsaWNHcGdLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogcm91bmQxLmVuY3J5cHRlZFVzZXJHcGdQcnZLZXksXG4gICAgICAgICAgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbjogcm91bmQyLmVuY3J5cHRlZFJvdW5kMlNlc3Npb24sXG4gICAgICAgIH0pLFxuICAgICAgL01pc3NpbmcgQml0R28gcm91bmQyT3V0cHV0IHNpZ25hdHVyZSBzaGFyZS9cbiAgICApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHByb3BhZ2F0ZSB0aGUgdHgtb25seSBndWFyZCB3aGVuIHRyYW5zYWN0aW9ucyBhcmUgbWlzc2luZycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB7IHJvdW5kMSwgcm91bmQyIH0gPSBhd2FpdCBjcmVhdGVSb3VuZDJGbG93KGJhc2VUeFJlcXVlc3QpO1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PlxuICAgICAgICBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kM1NoYXJlKHtcbiAgICAgICAgICB0eFJlcXVlc3Q6IHsgLi4uYmFzZVR4UmVxdWVzdCwgdHJhbnNhY3Rpb25zOiB1bmRlZmluZWQgfSBhcyB1bmtub3duIGFzIFR4UmVxdWVzdCxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFJvdW5kMlNlc3Npb246IHJvdW5kMi5lbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLFxuICAgICAgICB9KSxcbiAgICAgIC9VbmFibGUgdG8gZmluZCB0cmFuc2FjdGlvbnMgaW4gdHhSZXF1ZXN0L1xuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmVqZWN0IHdoZW4gdHJhbnNhY3Rpb25zIGFycmF5IGlzIGVtcHR5JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHsgcm91bmQxLCByb3VuZDIgfSA9IGF3YWl0IGNyZWF0ZVJvdW5kMkZsb3coYmFzZVR4UmVxdWVzdCk7XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+XG4gICAgICAgIGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQzU2hhcmUoe1xuICAgICAgICAgIHR4UmVxdWVzdDogeyAuLi5iYXNlVHhSZXF1ZXN0LCB0cmFuc2FjdGlvbnM6IFtdIH0sXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDEuZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgICAgICBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uOiByb3VuZDIuZW5jcnlwdGVkUm91bmQyU2Vzc2lvbixcbiAgICAgICAgfSksXG4gICAgICAvVW5hYmxlIHRvIGZpbmQgdHJhbnNhY3Rpb25zIGluIHR4UmVxdWVzdC9cbiAgICApO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnZ2V0Qml0Z29TaWduYXR1cmVTaGFyZScsICgpID0+IHtcbiAgY29uc3Qgcm91bmQxT3V0cHV0U2hhcmU6IFNpZ25hdHVyZVNoYXJlUmVjb3JkID0ge1xuICAgIGZyb206IFNpZ25hdHVyZVNoYXJlVHlwZS5CSVRHTyxcbiAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsXG4gICAgc2hhcmU6IEpTT04uc3RyaW5naWZ5KHsgdHlwZTogJ3JvdW5kMU91dHB1dCcsIGRhdGE6IHt9IH0pLFxuICB9O1xuICBjb25zdCByb3VuZDJPdXRwdXRTaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSB7XG4gICAgZnJvbTogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgIHRvOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUixcbiAgICBzaGFyZTogSlNPTi5zdHJpbmdpZnkoeyB0eXBlOiAncm91bmQyT3V0cHV0JywgZGF0YToge30gfSksXG4gIH07XG5cbiAgaXQoJ3NlbGVjdHMgdGhlIHJlcXVlc3RlZCBCaXRHbyByb3VuZCBvdXRwdXQgd2hlbiBtdWx0aXBsZSByb3VuZCBvdXRwdXRzIGFyZSBwcmVzZW50JywgKCkgPT4ge1xuICAgIGNvbnN0IHNpZ25hdHVyZVNoYXJlcyA9IFtyb3VuZDFPdXRwdXRTaGFyZSwgcm91bmQyT3V0cHV0U2hhcmVdO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgICAgZ2V0Qml0Z29TaWduYXR1cmVTaGFyZShzaWduYXR1cmVTaGFyZXMsIFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLCAncm91bmQyT3V0cHV0JyksXG4gICAgICByb3VuZDJPdXRwdXRTaGFyZVxuICAgICk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgICAgZ2V0Qml0Z29TaWduYXR1cmVTaGFyZShzaWduYXR1cmVTaGFyZXMsIFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLCAncm91bmQxT3V0cHV0JyksXG4gICAgICByb3VuZDFPdXRwdXRTaGFyZVxuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdza2lwcyBtYWxmb3JtZWQgc2hhcmUgcmVjb3JkcyB3aGlsZSBzZWxlY3RpbmcgdGhlIHJlcXVlc3RlZCBCaXRHbyByb3VuZCBvdXRwdXQnLCAoKSA9PiB7XG4gICAgY29uc3QgbWFsZm9ybWVkU2hhcmU6IFNpZ25hdHVyZVNoYXJlUmVjb3JkID0ge1xuICAgICAgZnJvbTogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgICAgdG86IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLFxuICAgICAgc2hhcmU6ICdub3QtanNvbicsXG4gICAgfTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgIGdldEJpdGdvU2lnbmF0dXJlU2hhcmUoW21hbGZvcm1lZFNoYXJlLCByb3VuZDJPdXRwdXRTaGFyZV0sIFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLCAncm91bmQyT3V0cHV0JyksXG4gICAgICByb3VuZDJPdXRwdXRTaGFyZVxuICAgICk7XG4gIH0pO1xufSk7XG5cbnR5cGUgVHhSZXF1ZXN0VHJhbnNhY3Rpb24gPSBOb25OdWxsYWJsZTxUeFJlcXVlc3RbJ3RyYW5zYWN0aW9ucyddPltudW1iZXJdO1xuXG5mdW5jdGlvbiBhc3NlcnRTaW5nbGVUcmFuc2FjdGlvbih0eFJlcXVlc3Q6IFR4UmVxdWVzdCk6IFR4UmVxdWVzdFRyYW5zYWN0aW9uIHtcbiAgYXNzZXJ0Lm9rKHR4UmVxdWVzdC50cmFuc2FjdGlvbnMsICd0eFJlcXVlc3QgbXVzdCBpbmNsdWRlIHRyYW5zYWN0aW9ucycpO1xuICBhc3NlcnQuc3RyaWN0RXF1YWwodHhSZXF1ZXN0LnRyYW5zYWN0aW9ucy5sZW5ndGgsIDEsICd0eFJlcXVlc3QgbXVzdCBoYXZlIGV4YWN0bHkgb25lIHRyYW5zYWN0aW9uJyk7XG4gIHJldHVybiB0eFJlcXVlc3QudHJhbnNhY3Rpb25zWzBdO1xufVxuXG5mdW5jdGlvbiBjbG9uZVR4UmVxdWVzdFdpdGhFbXB0eVNpZ25hdHVyZVNoYXJlcyh0eFJlcXVlc3Q6IFR4UmVxdWVzdCk6IFR4UmVxdWVzdCB7XG4gIGNvbnN0IHRyYW5zYWN0aW9uID0gYXNzZXJ0U2luZ2xlVHJhbnNhY3Rpb24odHhSZXF1ZXN0KTtcbiAgcmV0dXJuIHtcbiAgICAuLi50eFJlcXVlc3QsXG4gICAgdHJhbnNhY3Rpb25zOiBbeyAuLi50cmFuc2FjdGlvbiwgc2lnbmF0dXJlU2hhcmVzOiBbXSB9XSxcbiAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc2lnbkJpdGdvRWRkc2FSb3VuZDEoXG4gIGJpdGdvRHNnOiBFZGRzYU1QU0RzZy5EU0csXG4gIHR4UmVxdWVzdDogVHhSZXF1ZXN0LFxuICB1c2VyUm91bmQxU2hhcmU6IFNpZ25hdHVyZVNoYXJlUmVjb3JkLFxuICB1c2VyR3BnUHViS2V5QXJtb3JlZDogc3RyaW5nLFxuICBiaXRnb0dwZ1ByaXZLZXk6IHBncC5Qcml2YXRlS2V5XG4pOiBQcm9taXNlPFR4UmVxdWVzdD4ge1xuICBjb25zdCB0cmFuc2FjdGlvbiA9IGFzc2VydFNpbmdsZVRyYW5zYWN0aW9uKHR4UmVxdWVzdCk7XG4gIHRyYW5zYWN0aW9uLnNpZ25hdHVyZVNoYXJlcy5wdXNoKHVzZXJSb3VuZDFTaGFyZSk7XG5cbiAgY29uc3QgYml0Z29Nc2cxID0gYml0Z29Ec2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG5cbiAgY29uc3QgcGFyc2VkVXNlclNoYXJlID0gZGVjb2RlV2l0aENvZGVjKFxuICAgIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMUlucHV0LFxuICAgIEpTT04ucGFyc2UodXNlclJvdW5kMVNoYXJlLnNoYXJlKSxcbiAgICAnRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQnXG4gICk7XG4gIGNvbnN0IHVzZXJHcGdLZXkgPSBhd2FpdCBwZ3AucmVhZEtleSh7IGFybW9yZWRLZXk6IHVzZXJHcGdQdWJLZXlBcm1vcmVkIH0pO1xuICBjb25zdCB1c2VyUmF3TXNnMUJ5dGVzID0gYXdhaXQgTVBTQ29tbXMudmVyaWZ5TXBzTWVzc2FnZShwYXJzZWRVc2VyU2hhcmUuZGF0YS5tc2cxLCB1c2VyR3BnS2V5KTtcbiAgY29uc3QgdXNlck1zZzEgPSB7XG4gICAgZnJvbTogTVBDdjJQYXJ0aWVzRW51bS5VU0VSLFxuICAgIHBheWxvYWQ6IG5ldyBVaW50OEFycmF5KHVzZXJSYXdNc2cxQnl0ZXMpLFxuICB9O1xuXG4gIGNvbnN0IFtiaXRnb01zZzJdID0gYml0Z29Ec2cuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhbYml0Z29Nc2cxLCB1c2VyTXNnMV0pO1xuICBhc3NlcnQub2soYml0Z29Nc2cyLCAnQml0R28gRFNHIHByb2R1Y2VkIG5vIHJvdW5kLTIgb3V0cHV0Jyk7XG4gIChiaXRnb0RzZyBhcyBFZGRzYU1QU0RzZy5EU0cgJiB7IHJvdW5kMk1lc3NhZ2U/OiBNUFNUeXBlcy5EZXNlcmlhbGl6ZWRNZXNzYWdlIH0pLnJvdW5kMk1lc3NhZ2UgPSBiaXRnb01zZzI7XG5cbiAgY29uc3QgYml0Z29TaWduZWRNc2cxID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYml0Z29Nc2cxLnBheWxvYWQpLCBiaXRnb0dwZ1ByaXZLZXkpO1xuICBjb25zdCByb3VuZDFPdXRwdXQ6IEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMU91dHB1dCA9IHtcbiAgICB0eXBlOiAncm91bmQxT3V0cHV0JyxcbiAgICBkYXRhOiB7IG1zZzE6IGJpdGdvU2lnbmVkTXNnMSB9LFxuICB9O1xuXG4gIHRyYW5zYWN0aW9uLnNpZ25hdHVyZVNoYXJlcy5wdXNoKHtcbiAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgdG86IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLFxuICAgIHNoYXJlOiBKU09OLnN0cmluZ2lmeShyb3VuZDFPdXRwdXQpLFxuICB9KTtcblxuICByZXR1cm4gdHhSZXF1ZXN0O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzaWduQml0Z29FZGRzYVJvdW5kMihcbiAgYml0Z29Ec2c6IEVkZHNhTVBTRHNnLkRTRyxcbiAgdHhSZXF1ZXN0OiBUeFJlcXVlc3QsXG4gIHVzZXJSb3VuZDJTaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQsXG4gIHVzZXJHcGdQdWJLZXlBcm1vcmVkOiBzdHJpbmcsXG4gIGJpdGdvR3BnUHJpdktleTogcGdwLlByaXZhdGVLZXlcbik6IFByb21pc2U8VHhSZXF1ZXN0PiB7XG4gIGNvbnN0IHRyYW5zYWN0aW9uID0gYXNzZXJ0U2luZ2xlVHJhbnNhY3Rpb24odHhSZXF1ZXN0KTtcbiAgdHJhbnNhY3Rpb24uc2lnbmF0dXJlU2hhcmVzLnB1c2godXNlclJvdW5kMlNoYXJlKTtcblxuICBjb25zdCB1c2VyR3BnS2V5ID0gYXdhaXQgcGdwLnJlYWRLZXkoeyBhcm1vcmVkS2V5OiB1c2VyR3BnUHViS2V5QXJtb3JlZCB9KTtcbiAgY29uc3QgYml0Z29Nc2cyID0gKGJpdGdvRHNnIGFzIEVkZHNhTVBTRHNnLkRTRyAmIHsgcm91bmQyTWVzc2FnZT86IE1QU1R5cGVzLkRlc2VyaWFsaXplZE1lc3NhZ2UgfSkucm91bmQyTWVzc2FnZTtcbiAgYXNzZXJ0Lm9rKGJpdGdvTXNnMiwgJ0JpdEdvIERTRyBpcyBtaXNzaW5nIHRoZSBjYWNoZWQgcm91bmQtMiBvdXRwdXQnKTtcblxuICBjb25zdCBwYXJzZWRVc2VyUm91bmQyU2hhcmUgPSBkZWNvZGVXaXRoQ29kZWMoXG4gICAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQySW5wdXQsXG4gICAgSlNPTi5wYXJzZSh1c2VyUm91bmQyU2hhcmUuc2hhcmUpLFxuICAgICdFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJJbnB1dCdcbiAgKTtcbiAgY29uc3QgdXNlclJhd01zZzJCeXRlcyA9IGF3YWl0IE1QU0NvbW1zLnZlcmlmeU1wc01lc3NhZ2UocGFyc2VkVXNlclJvdW5kMlNoYXJlLmRhdGEubXNnMiwgdXNlckdwZ0tleSk7XG4gIGNvbnN0IHVzZXJNc2cyID0ge1xuICAgIGZyb206IE1QQ3YyUGFydGllc0VudW0uVVNFUixcbiAgICBwYXlsb2FkOiBuZXcgVWludDhBcnJheSh1c2VyUmF3TXNnMkJ5dGVzKSxcbiAgfTtcblxuICBjb25zdCBiaXRnb1NpZ25lZE1zZzIgPSBhd2FpdCBNUFNDb21tcy5kZXRhY2hTaWduTXBzTWVzc2FnZShCdWZmZXIuZnJvbShiaXRnb01zZzIucGF5bG9hZCksIGJpdGdvR3BnUHJpdktleSk7XG4gIGNvbnN0IHJvdW5kMk91dHB1dDogRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQyT3V0cHV0ID0ge1xuICAgIHR5cGU6ICdyb3VuZDJPdXRwdXQnLFxuICAgIGRhdGE6IHsgbXNnMjogYml0Z29TaWduZWRNc2cyIH0sXG4gIH07XG5cbiAgdHJhbnNhY3Rpb24uc2lnbmF0dXJlU2hhcmVzLnB1c2goe1xuICAgIGZyb206IFNpZ25hdHVyZVNoYXJlVHlwZS5CSVRHTyxcbiAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsXG4gICAgc2hhcmU6IEpTT04uc3RyaW5naWZ5KHJvdW5kMk91dHB1dCksXG4gIH0pO1xuXG4gIGJpdGdvRHNnLmhhbmRsZUluY29taW5nTWVzc2FnZXMoW2JpdGdvTXNnMiwgdXNlck1zZzJdKTtcblxuICByZXR1cm4gdHhSZXF1ZXN0O1xufVxuXG5kZXNjcmliZSgnRWRkc2FNUEN2MlV0aWxzLnNpZ25FZGRzYU1QQ3YyVHNzVXNpbmdFeHRlcm5hbFNpZ25lcicsICgpID0+IHtcbiAgbGV0IHNhbmRib3g6IHNpbm9uLlNpbm9uU2FuZGJveDtcbiAgbGV0IGVkZHNhTVBDdjJVdGlsczogRWRkc2FNUEN2MlV0aWxzO1xuICBsZXQgbW9ja0JpdGdvOiBCaXRHb0Jhc2U7XG4gIGxldCBiaXRnb0dwZ0tleVBhaXI6IHBncC5TZXJpYWxpemVkS2V5UGFpcjxzdHJpbmc+O1xuICBsZXQgYml0Z29HcGdQdWJLZXk6IHBncC5LZXk7XG5cbiAgY29uc3Qgd2FsbGV0SWQgPSAnYWJjMTIzd2FsbGV0JztcbiAgY29uc3QgdHhSZXF1ZXN0SWQgPSAndHhyZXEtMDAxJztcbiAgY29uc3QgZW50ZXJwcmlzZUlkID0gJ2VudC0wMDEnO1xuXG4gIGNvbnN0IG1vY2tUeFJlcXVlc3Q6IFR4UmVxdWVzdCA9IHtcbiAgICB0eFJlcXVlc3RJZCxcbiAgICB3YWxsZXRJZCxcbiAgICBlbnRlcnByaXNlSWQsXG4gICAgYXBpVmVyc2lvbjogJ2Z1bGwnLFxuICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAge1xuICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgc2lnbmFibGVIZXg6ICdkZWFkYmVlZicsXG4gICAgICAgICAgZGVyaXZhdGlvblBhdGg6ICdtLzAnLFxuICAgICAgICAgIHNlcmlhbGl6ZWRUeEhleDogJ2RlYWRiZWVmJyxcbiAgICAgICAgfSxcbiAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgZnJvbTogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgICAgICAgICAgdG86IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLFxuICAgICAgICAgICAgc2hhcmU6IEpTT04uc3RyaW5naWZ5KHsgdHlwZTogJ3JvdW5kMU91dHB1dCcsIGRhdGE6IHt9IH0pLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgIF0sXG4gICAgaW50ZW50OiB7IGludGVudFR5cGU6ICdwYXltZW50JyB9LFxuICAgIHVuc2lnbmVkVHhzOiBbXSxcbiAgfSBhcyB1bmtub3duIGFzIFR4UmVxdWVzdDtcblxuICBjb25zdCBtb2NrVHhSZXF1ZXN0VHJhbnNhY3Rpb24gPSBhc3NlcnRTaW5nbGVUcmFuc2FjdGlvbihtb2NrVHhSZXF1ZXN0KTtcbiAgY29uc3QgbW9ja1R4UmVxdWVzdFJvdW5kMjogVHhSZXF1ZXN0ID0ge1xuICAgIC4uLm1vY2tUeFJlcXVlc3QsXG4gICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICB7XG4gICAgICAgIC4uLm1vY2tUeFJlcXVlc3RUcmFuc2FjdGlvbixcbiAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgZnJvbTogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgICAgICAgICAgdG86IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLFxuICAgICAgICAgICAgc2hhcmU6IEpTT04uc3RyaW5naWZ5KHsgdHlwZTogJ3JvdW5kMk91dHB1dCcsIGRhdGE6IHt9IH0pLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgIF0sXG4gIH07XG5cbiAgY29uc3QgZHVtbXlTaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSB7XG4gICAgZnJvbTogU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsXG4gICAgdG86IFNpZ25hdHVyZVNoYXJlVHlwZS5CSVRHTyxcbiAgICBzaGFyZTogSlNPTi5zdHJpbmdpZnkoeyB0eXBlOiAncm91bmQxSW5wdXQnLCBkYXRhOiB7fSB9KSxcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgY2hhaW4gY29tcGF0aWJsZSB3aXRoOiBiaXRnby5wb3N0KHVybCkuc2VuZChib2R5KS5yZXN1bHQoKVxuICBjb25zdCBtYWtlUG9zdENoYWluID0gKHJlc3BvbnNlOiBUeFJlcXVlc3QpOiBCaXRHb1JlcXVlc3Q8VHhSZXF1ZXN0PiA9PlxuICAgICh7IHNlbmQ6ICgpID0+ICh7IHJlc3VsdDogc2lub24uc3R1YigpLnJlc29sdmVzKHJlc3BvbnNlKSB9KSB9IGFzIHVua25vd24gYXMgQml0R29SZXF1ZXN0PFR4UmVxdWVzdD4pO1xuXG4gIC8vIFJldHVybnMgYSBjaGFpbiBjb21wYXRpYmxlIHdpdGg6IGJpdGdvLmdldCh1cmwpLnF1ZXJ5KHBhcmFtcykucmV0cnkobikucmVzdWx0KClcbiAgY29uc3QgbWFrZUdldENoYWluID0gKHR4UmVxdWVzdHM6IFR4UmVxdWVzdFtdKTogQml0R29SZXF1ZXN0PHsgdHhSZXF1ZXN0czogVHhSZXF1ZXN0W10gfT4gPT5cbiAgICAoe1xuICAgICAgcXVlcnk6ICgpID0+ICh7XG4gICAgICAgIHJldHJ5OiAoKSA9PiAoeyByZXN1bHQ6IHNpbm9uLnN0dWIoKS5yZXNvbHZlcyh7IHR4UmVxdWVzdHMgfSkgfSksXG4gICAgICB9KSxcbiAgICB9IGFzIHVua25vd24gYXMgQml0R29SZXF1ZXN0PHsgdHhSZXF1ZXN0czogVHhSZXF1ZXN0W10gfT4pO1xuXG4gIGJlZm9yZShhc3luYyAoKSA9PiB7XG4gICAgYml0Z29HcGdLZXlQYWlyID0gYXdhaXQgZ2VuZXJhdGVHUEdLZXlQYWlyKCdlZDI1NTE5Jyk7XG4gICAgYml0Z29HcGdQdWJLZXkgPSBhd2FpdCBwZ3AucmVhZEtleSh7IGFybW9yZWRLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXkgfSk7XG4gIH0pO1xuXG4gIGJlZm9yZUVhY2goYXN5bmMgKCkgPT4ge1xuICAgIHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG5cbiAgICAvLyBGdWxsIG1vY2sgb2YgdGhlIEJpdEdvIEhUVFAgY2xpZW50IChjb25zaXN0ZW50IHdpdGggb3RoZXIgc2RrLWNvcmUgdGVzdHMgc3VjaCBhc1xuICAgIC8vIHRva2VuQXBwcm92YWwudHMgYW5kIHdhbGxldHNFdm1LZXlyaW5nLnRzKS4gIE1vZHVsZS1sZXZlbCBzdHVicyBvbiB0c3NDb21tb24gZnVuY3Rpb25zXG4gICAgLy8gZG8gbm90IHdvcmsgdW5kZXIgdHN4IDQueCAoRVNNIGxpdmUgYmluZGluZ3MpLCBzbyB3ZSBtb2NrIGF0IHRoZSBiaXRnbyBvYmplY3QgbGV2ZWwuXG4gICAgbW9ja0JpdGdvID0ge1xuICAgICAgZ2V0RW52OiBzaW5vbi5zdHViKCkucmV0dXJucygndGVzdCcpLFxuICAgICAgc2V0UmVxdWVzdFRyYWNlcjogc2lub24uc3R1YigpLFxuICAgICAgdXJsOiBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKChwYXRoOiBzdHJpbmcpID0+IGBodHRwczovL3Rlc3QuYml0Z28uY29tJHtwYXRofWApLFxuICAgICAgcG9zdDogc2lub24uc3R1YigpLFxuICAgICAgZ2V0OiBzaW5vbi5zdHViKCksXG4gICAgfSBhcyB1bmtub3duIGFzIEJpdEdvQmFzZTtcblxuICAgIGNvbnN0IG1vY2tDb2luID0ge1xuICAgICAgZ2V0TVBDQWxnb3JpdGhtOiBzaW5vbi5zdHViKCkucmV0dXJucygnZWRkc2EnKSxcbiAgICB9IGFzIHVua25vd24gYXMgSUJhc2VDb2luO1xuXG4gICAgY29uc3QgbW9ja1dhbGxldCA9IHtcbiAgICAgIGlkOiBzaW5vbi5zdHViKCkucmV0dXJucyh3YWxsZXRJZCksXG4gICAgICBrZXlJZHM6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKFsndXNlcktleUlkJywgJ2JhY2t1cEtleUlkJywgJ2JpdGdvS2V5SWQnXSksXG4gICAgICBtdWx0aXNpZ1R5cGVWZXJzaW9uOiBzaW5vbi5zdHViKCkucmV0dXJucygnTVBDdjInKSxcbiAgICB9IGFzIHVua25vd24gYXMgSVdhbGxldDtcblxuICAgIGVkZHNhTVBDdjJVdGlscyA9IG5ldyBFZGRzYU1QQ3YyVXRpbHMobW9ja0JpdGdvLCBtb2NrQ29pbiwgbW9ja1dhbGxldCk7XG5cbiAgICBzYW5kYm94LnN0dWIoZWRkc2FNUEN2MlV0aWxzLCAncGlja0JpdGdvUHViR3BnS2V5Rm9yU2lnbmluZycpLnJlc29sdmVzKGJpdGdvR3BnUHViS2V5KTtcbiAgfSk7XG5cbiAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICBzYW5kYm94LnJlc3RvcmUoKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBjYWxsIGFsbCAzIGdlbmVyYXRvcnMgYW5kIHJldHVybiB0aGUgZmluYWwgdHggcmVxdWVzdCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBmaW5hbFR4UmVxdWVzdCA9IHsgLi4ubW9ja1R4UmVxdWVzdCwgdHhSZXF1ZXN0SWQgfTtcblxuICAgIC8vIHNlbmRTaWduYXR1cmVTaGFyZVYyIGlzIGNhbGxlZCAzIHRpbWVzIChvbmUgcGVyIHJvdW5kKSwgc2VuZFR4UmVxdWVzdCBvbmNlIOKAlCBhbGwgdXNlIGJpdGdvLnBvc3RcbiAgICAobW9ja0JpdGdvLnBvc3QgYXMgc2lub24uU2lub25TdHViKVxuICAgICAgLm9uQ2FsbCgwKVxuICAgICAgLnJldHVybnMobWFrZVBvc3RDaGFpbihtb2NrVHhSZXF1ZXN0KSkgLy8gcm91bmQgMSBzaWduXG4gICAgICAub25DYWxsKDEpXG4gICAgICAucmV0dXJucyhtYWtlUG9zdENoYWluKG1vY2tUeFJlcXVlc3RSb3VuZDIpKSAvLyByb3VuZCAyIHNpZ25cbiAgICAgIC5vbkNhbGwoMilcbiAgICAgIC5yZXR1cm5zKG1ha2VQb3N0Q2hhaW4obW9ja1R4UmVxdWVzdFJvdW5kMikpIC8vIHJvdW5kIDMgc2lnblxuICAgICAgLm9uQ2FsbCgzKVxuICAgICAgLnJldHVybnMobWFrZVBvc3RDaGFpbihmaW5hbFR4UmVxdWVzdCkpOyAvLyBzZW5kVHhSZXF1ZXN0IChzZW5kKVxuXG4gICAgY29uc3QgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiA9ICdlbmNyeXB0ZWQtcjEtc2Vzc2lvbic7XG4gICAgY29uc3QgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbiA9ICdlbmNyeXB0ZWQtcjItc2Vzc2lvbic7XG4gICAgY29uc3QgZW5jcnlwdGVkVXNlckdwZ1BydktleSA9ICdlbmNyeXB0ZWQtZ3BnLWtleSc7XG4gICAgY29uc3QgdXNlckdwZ1B1YktleSA9IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXk7XG5cbiAgICBjb25zdCByb3VuZDFTaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSB7IC4uLmR1bW15U2hhcmUgfTtcbiAgICBjb25zdCByb3VuZDJTaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSB7IC4uLmR1bW15U2hhcmUsIHNoYXJlOiBKU09OLnN0cmluZ2lmeSh7IHR5cGU6ICdyb3VuZDJJbnB1dCcgfSkgfTtcbiAgICBjb25zdCByb3VuZDNTaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSB7IC4uLmR1bW15U2hhcmUsIHNoYXJlOiBKU09OLnN0cmluZ2lmeSh7IHR5cGU6ICdyb3VuZDNJbnB1dCcgfSkgfTtcblxuICAgIGNvbnN0IHJvdW5kMUdlbmVyYXRvciA9IHNpbm9uXG4gICAgICAuc3R1YigpXG4gICAgICAucmVzb2x2ZXMoeyBzaWduYXR1cmVTaGFyZVJvdW5kMTogcm91bmQxU2hhcmUsIHVzZXJHcGdQdWJLZXksIGVuY3J5cHRlZFJvdW5kMVNlc3Npb24sIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXkgfSk7XG4gICAgY29uc3Qgcm91bmQyR2VuZXJhdG9yID0gc2lub24uc3R1YigpLnJlc29sdmVzKHsgc2lnbmF0dXJlU2hhcmVSb3VuZDI6IHJvdW5kMlNoYXJlLCBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uIH0pO1xuICAgIGNvbnN0IHJvdW5kM0dlbmVyYXRvciA9IHNpbm9uLnN0dWIoKS5yZXNvbHZlcyh7IHNpZ25hdHVyZVNoYXJlUm91bmQzOiByb3VuZDNTaGFyZSB9KTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5zaWduRWRkc2FNUEN2MlRzc1VzaW5nRXh0ZXJuYWxTaWduZXIoXG4gICAgICB7IHR4UmVxdWVzdDogbW9ja1R4UmVxdWVzdCwgcmVxSWQ6IG5ldyBSZXF1ZXN0VHJhY2VyKCkgfSxcbiAgICAgIHJvdW5kMUdlbmVyYXRvciBhcyB1bmtub3duIGFzIEN1c3RvbUVkZHNhTVBDdjJTaWduaW5nUm91bmQxR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICAgICAgcm91bmQyR2VuZXJhdG9yIGFzIHVua25vd24gYXMgQ3VzdG9tRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDJHZW5lcmF0aW5nRnVuY3Rpb24sXG4gICAgICByb3VuZDNHZW5lcmF0b3IgYXMgdW5rbm93biBhcyBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kM0dlbmVyYXRpbmdGdW5jdGlvblxuICAgICk7XG5cbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHJlc3VsdCwgZmluYWxUeFJlcXVlc3QpO1xuXG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2Uocm91bmQxR2VuZXJhdG9yKTtcbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkV2l0aChyb3VuZDFHZW5lcmF0b3IsIHsgdHhSZXF1ZXN0OiBtb2NrVHhSZXF1ZXN0IH0pO1xuXG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2Uocm91bmQyR2VuZXJhdG9yKTtcbiAgICBjb25zdCByb3VuZDJDYWxsID0gcm91bmQyR2VuZXJhdG9yLmdldENhbGwoMCk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJvdW5kMkNhbGwuYXJnc1swXS50eFJlcXVlc3QsIG1vY2tUeFJlcXVlc3QpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyb3VuZDJDYWxsLmFyZ3NbMF0uZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiwgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJvdW5kMkNhbGwuYXJnc1swXS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5KTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocm91bmQyQ2FsbC5hcmdzWzBdLmJpdGdvUHVibGljR3BnS2V5LCBiaXRnb0dwZ1B1YktleS5hcm1vcigpKTtcblxuICAgIHNpbm9uLmFzc2VydC5jYWxsZWRPbmNlKHJvdW5kM0dlbmVyYXRvcik7XG4gICAgY29uc3Qgcm91bmQzQ2FsbCA9IHJvdW5kM0dlbmVyYXRvci5nZXRDYWxsKDApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyb3VuZDNDYWxsLmFyZ3NbMF0udHhSZXF1ZXN0LCBtb2NrVHhSZXF1ZXN0Um91bmQyKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocm91bmQzQ2FsbC5hcmdzWzBdLmVuY3J5cHRlZFJvdW5kMlNlc3Npb24sIGVuY3J5cHRlZFJvdW5kMlNlc3Npb24pO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyb3VuZDNDYWxsLmFyZ3NbMF0uZW5jcnlwdGVkVXNlckdwZ1BydktleSwgZW5jcnlwdGVkVXNlckdwZ1BydktleSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJvdW5kM0NhbGwuYXJnc1swXS5iaXRnb1B1YmxpY0dwZ0tleSwgYml0Z29HcGdQdWJLZXkuYXJtb3IoKSk7XG5cbiAgICAvLyAzIHNlbmRTaWduYXR1cmVTaGFyZVYyIGNhbGxzICsgMSBzZW5kVHhSZXF1ZXN0ID0gNCBQT1NUIGNhbGxzIHRvdGFsXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKChtb2NrQml0Z28ucG9zdCBhcyBzaW5vbi5TaW5vblN0dWIpLmNhbGxDb3VudCwgNCk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmVzb2x2ZSB0eFJlcXVlc3QgYnkgSUQgc3RyaW5nIHVzaW5nIGdldFR4UmVxdWVzdCcsIGFzeW5jICgpID0+IHtcbiAgICAvLyBnZXRUeFJlcXVlc3QgdXNlcyBiaXRnby5nZXQ7IHNlbmRTaWduYXR1cmVTaGFyZVYyICjDlzMpICsgc2VuZFR4UmVxdWVzdCB1c2UgYml0Z28ucG9zdFxuICAgIChtb2NrQml0Z28uZ2V0IGFzIHNpbm9uLlNpbm9uU3R1YikucmV0dXJucyhtYWtlR2V0Q2hhaW4oW21vY2tUeFJlcXVlc3RdKSk7XG4gICAgKG1vY2tCaXRnby5wb3N0IGFzIHNpbm9uLlNpbm9uU3R1YilcbiAgICAgIC5vbkNhbGwoMClcbiAgICAgIC5yZXR1cm5zKG1ha2VQb3N0Q2hhaW4obW9ja1R4UmVxdWVzdCkpXG4gICAgICAub25DYWxsKDEpXG4gICAgICAucmV0dXJucyhtYWtlUG9zdENoYWluKG1vY2tUeFJlcXVlc3RSb3VuZDIpKVxuICAgICAgLm9uQ2FsbCgyKVxuICAgICAgLnJldHVybnMobWFrZVBvc3RDaGFpbihtb2NrVHhSZXF1ZXN0Um91bmQyKSlcbiAgICAgIC5vbkNhbGwoMylcbiAgICAgIC5yZXR1cm5zKG1ha2VQb3N0Q2hhaW4obW9ja1R4UmVxdWVzdCkpO1xuXG4gICAgY29uc3Qgcm91bmQxR2VuZXJhdG9yID0gc2lub24uc3R1YigpLnJlc29sdmVzKHtcbiAgICAgIHNpZ25hdHVyZVNoYXJlUm91bmQxOiBkdW1teVNoYXJlLFxuICAgICAgdXNlckdwZ1B1YktleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246ICdyMScsXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiAna2V5JyxcbiAgICB9KTtcbiAgICBjb25zdCByb3VuZDJHZW5lcmF0b3IgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBzaWduYXR1cmVTaGFyZVJvdW5kMjogZHVtbXlTaGFyZSwgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbjogJ3IyJyB9KTtcbiAgICBjb25zdCByb3VuZDNHZW5lcmF0b3IgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBzaWduYXR1cmVTaGFyZVJvdW5kMzogZHVtbXlTaGFyZSB9KTtcblxuICAgIGF3YWl0IGVkZHNhTVBDdjJVdGlscy5zaWduRWRkc2FNUEN2MlRzc1VzaW5nRXh0ZXJuYWxTaWduZXIoXG4gICAgICB7IHR4UmVxdWVzdDogdHhSZXF1ZXN0SWQsIHJlcUlkOiBuZXcgUmVxdWVzdFRyYWNlcigpIH0sXG4gICAgICByb3VuZDFHZW5lcmF0b3IgYXMgdW5rbm93biBhcyBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kMUdlbmVyYXRpbmdGdW5jdGlvbixcbiAgICAgIHJvdW5kMkdlbmVyYXRvciBhcyB1bmtub3duIGFzIEN1c3RvbUVkZHNhTVBDdjJTaWduaW5nUm91bmQyR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICAgICAgcm91bmQzR2VuZXJhdG9yIGFzIHVua25vd24gYXMgQ3VzdG9tRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDNHZW5lcmF0aW5nRnVuY3Rpb25cbiAgICApO1xuXG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2UobW9ja0JpdGdvLmdldCBhcyBzaW5vbi5TaW5vblN0dWIpO1xuICAgIHNpbm9uLmFzc2VydC5jYWxsZWRXaXRoKHJvdW5kMUdlbmVyYXRvciwgeyB0eFJlcXVlc3Q6IG1vY2tUeFJlcXVlc3QgfSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgdGhyb3cgd2hlbiByb3VuZCAyIHR4UmVxdWVzdCBpcyBtaXNzaW5nIHNpZ25hdHVyZVNoYXJlcycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByb3VuZDJOb1NoYXJlczogVHhSZXF1ZXN0ID0ge1xuICAgICAgLi4ubW9ja1R4UmVxdWVzdCxcbiAgICAgIHRyYW5zYWN0aW9uczogW3sgLi4ubW9ja1R4UmVxdWVzdFRyYW5zYWN0aW9uLCBzaWduYXR1cmVTaGFyZXM6IHVuZGVmaW5lZCBhcyB1bmtub3duIGFzIFtdIH1dLFxuICAgIH07XG5cbiAgICAobW9ja0JpdGdvLnBvc3QgYXMgc2lub24uU2lub25TdHViKVxuICAgICAgLm9uQ2FsbCgwKVxuICAgICAgLnJldHVybnMobWFrZVBvc3RDaGFpbihtb2NrVHhSZXF1ZXN0KSlcbiAgICAgIC5vbkNhbGwoMSlcbiAgICAgIC5yZXR1cm5zKG1ha2VQb3N0Q2hhaW4ocm91bmQyTm9TaGFyZXMpKTtcblxuICAgIGNvbnN0IHJvdW5kMUdlbmVyYXRvciA9IHNpbm9uLnN0dWIoKS5yZXNvbHZlcyh7XG4gICAgICBzaWduYXR1cmVTaGFyZVJvdW5kMTogZHVtbXlTaGFyZSxcbiAgICAgIHVzZXJHcGdQdWJLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uOiAncjEnLFxuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogJ2tleScsXG4gICAgfSk7XG4gICAgY29uc3Qgcm91bmQyR2VuZXJhdG9yID0gc2lub24uc3R1YigpLnJlc29sdmVzKHsgc2lnbmF0dXJlU2hhcmVSb3VuZDI6IGR1bW15U2hhcmUsIGVuY3J5cHRlZFJvdW5kMlNlc3Npb246ICdyMicgfSk7XG4gICAgY29uc3Qgcm91bmQzR2VuZXJhdG9yID0gc2lub24uc3R1YigpLnJlc29sdmVzKHsgc2lnbmF0dXJlU2hhcmVSb3VuZDM6IGR1bW15U2hhcmUgfSk7XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+XG4gICAgICAgIGVkZHNhTVBDdjJVdGlscy5zaWduRWRkc2FNUEN2MlRzc1VzaW5nRXh0ZXJuYWxTaWduZXIoXG4gICAgICAgICAgeyB0eFJlcXVlc3Q6IG1vY2tUeFJlcXVlc3QsIHJlcUlkOiBuZXcgUmVxdWVzdFRyYWNlcigpIH0sXG4gICAgICAgICAgcm91bmQxR2VuZXJhdG9yIGFzIHVua25vd24gYXMgQ3VzdG9tRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDFHZW5lcmF0aW5nRnVuY3Rpb24sXG4gICAgICAgICAgcm91bmQyR2VuZXJhdG9yIGFzIHVua25vd24gYXMgQ3VzdG9tRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDJHZW5lcmF0aW5nRnVuY3Rpb24sXG4gICAgICAgICAgcm91bmQzR2VuZXJhdG9yIGFzIHVua25vd24gYXMgQ3VzdG9tRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDNHZW5lcmF0aW5nRnVuY3Rpb25cbiAgICAgICAgKSxcbiAgICAgIC9NaXNzaW5nIHNpZ25hdHVyZSBzaGFyZXMgaW4gcm91bmQgMiB0eFJlcXVlc3QvXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBwYXNzIGFybW9yZWQgQml0R28gcHVibGljIEdQRyBrZXkgdG8gcm91bmQgMiBhbmQgcm91bmQgMyBnZW5lcmF0b3JzJywgYXN5bmMgKCkgPT4ge1xuICAgIChtb2NrQml0Z28ucG9zdCBhcyBzaW5vbi5TaW5vblN0dWIpXG4gICAgICAub25DYWxsKDApXG4gICAgICAucmV0dXJucyhtYWtlUG9zdENoYWluKG1vY2tUeFJlcXVlc3QpKVxuICAgICAgLm9uQ2FsbCgxKVxuICAgICAgLnJldHVybnMobWFrZVBvc3RDaGFpbihtb2NrVHhSZXF1ZXN0Um91bmQyKSlcbiAgICAgIC5vbkNhbGwoMilcbiAgICAgIC5yZXR1cm5zKG1ha2VQb3N0Q2hhaW4obW9ja1R4UmVxdWVzdFJvdW5kMikpXG4gICAgICAub25DYWxsKDMpXG4gICAgICAucmV0dXJucyhtYWtlUG9zdENoYWluKG1vY2tUeFJlcXVlc3QpKTtcblxuICAgIGNvbnN0IHJvdW5kMUdlbmVyYXRvciA9IHNpbm9uLnN0dWIoKS5yZXNvbHZlcyh7XG4gICAgICBzaWduYXR1cmVTaGFyZVJvdW5kMTogZHVtbXlTaGFyZSxcbiAgICAgIHVzZXJHcGdQdWJLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uOiAncjEnLFxuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogJ2tleScsXG4gICAgfSk7XG4gICAgY29uc3Qgcm91bmQyR2VuZXJhdG9yID0gc2lub24uc3R1YigpLnJlc29sdmVzKHsgc2lnbmF0dXJlU2hhcmVSb3VuZDI6IGR1bW15U2hhcmUsIGVuY3J5cHRlZFJvdW5kMlNlc3Npb246ICdyMicgfSk7XG4gICAgY29uc3Qgcm91bmQzR2VuZXJhdG9yID0gc2lub24uc3R1YigpLnJlc29sdmVzKHsgc2lnbmF0dXJlU2hhcmVSb3VuZDM6IGR1bW15U2hhcmUgfSk7XG5cbiAgICBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuc2lnbkVkZHNhTVBDdjJUc3NVc2luZ0V4dGVybmFsU2lnbmVyKFxuICAgICAgeyB0eFJlcXVlc3Q6IG1vY2tUeFJlcXVlc3QsIHJlcUlkOiBuZXcgUmVxdWVzdFRyYWNlcigpIH0sXG4gICAgICByb3VuZDFHZW5lcmF0b3IgYXMgdW5rbm93biBhcyBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kMUdlbmVyYXRpbmdGdW5jdGlvbixcbiAgICAgIHJvdW5kMkdlbmVyYXRvciBhcyB1bmtub3duIGFzIEN1c3RvbUVkZHNhTVBDdjJTaWduaW5nUm91bmQyR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICAgICAgcm91bmQzR2VuZXJhdG9yIGFzIHVua25vd24gYXMgQ3VzdG9tRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDNHZW5lcmF0aW5nRnVuY3Rpb25cbiAgICApO1xuXG4gICAgY29uc3QgYXJtb3JlZEtleSA9IGJpdGdvR3BnUHViS2V5LmFybW9yKCk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgICAgcm91bmQyR2VuZXJhdG9yLmdldENhbGwoMCkuYXJnc1swXS5iaXRnb1B1YmxpY0dwZ0tleSxcbiAgICAgIGFybW9yZWRLZXksXG4gICAgICAncm91bmQgMiBzaG91bGQgcmVjZWl2ZSBhcm1vcmVkIEJpdEdvIEdQRyBrZXknXG4gICAgKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICByb3VuZDNHZW5lcmF0b3IuZ2V0Q2FsbCgwKS5hcmdzWzBdLmJpdGdvUHVibGljR3BnS2V5LFxuICAgICAgYXJtb3JlZEtleSxcbiAgICAgICdyb3VuZCAzIHNob3VsZCByZWNlaXZlIGFybW9yZWQgQml0R28gR1BHIGtleSdcbiAgICApO1xuICB9KTtcbn0pO1xuXG5mdW5jdGlvbiBieXRlc1RvV29yZChieXRlcz86IFVpbnQ4QXJyYXkgfCBudW1iZXJbXSk6IG51bWJlciB7XG4gIGlmICghKGJ5dGVzIGluc3RhbmNlb2YgVWludDhBcnJheSkgfHwgYnl0ZXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdieXRlcyBtdXN0IGJlIGEgVWludDhBcnJheSB3aXRoIGxlbmd0aCA0Jyk7XG4gIH1cblxuICByZXR1cm4gYnl0ZXMucmVkdWNlKChudW0sIGJ5dGUpID0+IG51bSAqIDB4MTAwICsgYnl0ZSwgMCk7XG59XG5cbmRlc2NyaWJlKCdFRERTQVV0aWxzLmlzRWRkc2FNcGNWMVNpZ25pbmdNYXRlcmlhbCcsICgpID0+IHtcbiAgY29uc3QgUEFTU1BIUkFTRSA9ICd0ZXN0LXBhc3NwaHJhc2UnO1xuXG4gIGNvbnN0IE1QQ3YxX01BVEVSSUFMX0JBQ0tVUCA9IHtcbiAgICB1U2hhcmU6IHsgaTogMSwgdDogMiwgbjogMywgeTogJ2FhYmJjYycsIHNlZWQ6ICdkZWFkYmVlZjAxMjM0NTY3JywgY2hhaW5jb2RlOiAnMDAnIH0sXG4gICAgYml0Z29ZU2hhcmU6IHsgaTogMywgajogMSwgeTogJ2FhYmJjYycsIHU6ICdiaXRnby11LXZhbHVlJywgY2hhaW5jb2RlOiAnMDAnIH0sXG4gICAgYmFja3VwWVNoYXJlOiB7IGk6IDIsIGo6IDEsIHk6ICdhYWJiY2MnLCB1OiAnYmFja3VwLXUtdmFsdWUnLCBjaGFpbmNvZGU6ICcwMCcgfSxcbiAgfTtcblxuICBjb25zdCBNUEN2MV9NQVRFUklBTF9VU0VSID0ge1xuICAgIHVTaGFyZTogeyBpOiAyLCB0OiAyLCBuOiAzLCB5OiAnYWFiYmNjJywgc2VlZDogJ2RlYWRiZWVmMDEyMzQ1NjcnLCBjaGFpbmNvZGU6ICcwMCcgfSxcbiAgICBiaXRnb1lTaGFyZTogeyBpOiAzLCBqOiAyLCB5OiAnYWFiYmNjJywgdTogJ2JpdGdvLXUtdmFsdWUnLCBjaGFpbmNvZGU6ICcwMCcgfSxcbiAgICB1c2VyWVNoYXJlOiB7IGk6IDEsIGo6IDIsIHk6ICdhYWJiY2MnLCB1OiAndXNlci11LXZhbHVlJywgY2hhaW5jb2RlOiAnMDAnIH0sXG4gIH07XG5cbiAgY29uc3QgTVBDdjJfQ0JPUl9CWVRFUyA9IEJ1ZmZlci5mcm9tKFsweGQ5LCAweDAxLCAweDA0LCAweGEzLCAweDYxLCAweDc4LCAweDE4LCAweDAwXSkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuXG4gIGxldCBtb2NrQml0Z286IEJpdEdvQmFzZTtcbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgLy8gc2RrLWNvcmUgaGFzIG5vIGRldkRlcGVuZGVuY3kgb24gc2RrLWFwaS9hcmdvbjIsIHNvIHYyIGVudmVsb3BlcyBhcmUgc2ltdWxhdGVkIGhlcmUuXG4gICAgLy8gUmVhbCBiaXRnby5kZWNyeXB0IHJvdXRlcyB2MiB0byBBcmdvbjJpZDsgdGhlIHN0dWIgcmV0dXJucyBNUEN2MiBDQk9SIHBsYWludGV4dCBpbnN0ZWFkLlxuICAgIG1vY2tCaXRnbyA9IHtcbiAgICAgIGRlY3J5cHQ6IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoYXN5bmMgKHBhcmFtczogeyBpbnB1dDogc3RyaW5nOyBwYXNzd29yZDogc3RyaW5nIH0pID0+IHtcbiAgICAgICAgaWYgKGlzVjJFbnZlbG9wZShwYXJhbXMuaW5wdXQpKSB7XG4gICAgICAgICAgcmV0dXJuIE1QQ3YyX0NCT1JfQllURVM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNqY2wuZGVjcnlwdChwYXJhbXMucGFzc3dvcmQsIHBhcmFtcy5pbnB1dCk7XG4gICAgICB9KSxcbiAgICB9IGFzIHVua25vd24gYXMgQml0R29CYXNlO1xuICB9KTtcblxuICBpdCgncmV0dXJucyB0cnVlIGZvciBNUEN2MSBTSkNMLWVuY3J5cHRlZCBrZXljYXJkIHdpdGggYmFja3VwWVNoYXJlICsgY29ycmVjdCBwYXNzcGhyYXNlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGVuY3J5cHRlZCA9IHNqY2wuZW5jcnlwdChQQVNTUEhSQVNFLCBKU09OLnN0cmluZ2lmeShNUEN2MV9NQVRFUklBTF9CQUNLVVApKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYXdhaXQgRUREU0FVdGlscy5pc0VkZHNhTXBjVjFTaWduaW5nTWF0ZXJpYWwoZW5jcnlwdGVkLCBQQVNTUEhSQVNFKSwgdHJ1ZSk7XG4gIH0pO1xuXG4gIGl0KCdyZXR1cm5zIHRydWUgZm9yIE1QQ3YxIFNKQ0wtZW5jcnlwdGVkIGtleWNhcmQgd2l0aCB1c2VyWVNoYXJlICsgY29ycmVjdCBwYXNzcGhyYXNlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGVuY3J5cHRlZCA9IHNqY2wuZW5jcnlwdChQQVNTUEhSQVNFLCBKU09OLnN0cmluZ2lmeShNUEN2MV9NQVRFUklBTF9VU0VSKSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGF3YWl0IEVERFNBVXRpbHMuaXNFZGRzYU1wY1YxU2lnbmluZ01hdGVyaWFsKGVuY3J5cHRlZCwgUEFTU1BIUkFTRSksIHRydWUpO1xuICB9KTtcblxuICBpdCgncmV0dXJucyBmYWxzZSBmb3IgTVBDdjIgQ0JPUiBjb250ZW50IHdyYXBwZWQgaW4gU0pDTCBlbnZlbG9wZSArIGNvcnJlY3QgcGFzc3BocmFzZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBlbmNyeXB0ZWQgPSBzamNsLmVuY3J5cHQoUEFTU1BIUkFTRSwgTVBDdjJfQ0JPUl9CWVRFUyk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGF3YWl0IEVERFNBVXRpbHMuaXNFZGRzYU1wY1YxU2lnbmluZ01hdGVyaWFsKGVuY3J5cHRlZCwgUEFTU1BIUkFTRSksIGZhbHNlKTtcbiAgfSk7XG5cbiAgaXQoJ3JldHVybnMgZmFsc2UgZm9yIE1QQ3YyIEFyZ29uMmlkIGVudmVsb3BlICh2MikgKyBjb3JyZWN0IHBhc3NwaHJhc2UgKGZvcndhcmQtY29tcGF0KScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBmYWtlVjJFbnZlbG9wZSA9IEpTT04uc3RyaW5naWZ5KHsgdjogMiwgbTogNjU1MzYsIHQ6IDMsIHA6IDQsIHNhbHQ6ICdBQUFBJywgaXY6ICdBQUFBJywgY3Q6ICdBQUFBJyB9KTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYXdhaXQgRUREU0FVdGlscy5pc0VkZHNhTXBjVjFTaWduaW5nTWF0ZXJpYWwoZmFrZVYyRW52ZWxvcGUsIFBBU1NQSFJBU0UsIG1vY2tCaXRnbyksIGZhbHNlKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyBvbiB3cm9uZyBwYXNzcGhyYXNlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGVuY3J5cHRlZCA9IHNqY2wuZW5jcnlwdChQQVNTUEhSQVNFLCBKU09OLnN0cmluZ2lmeShNUEN2MV9NQVRFUklBTF9CQUNLVVApKTtcbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgIEVERFNBVXRpbHMuaXNFZGRzYU1wY1YxU2lnbmluZ01hdGVyaWFsKGVuY3J5cHRlZCwgJ3dyb25nLXBhc3NwaHJhc2UnKSxcbiAgICAgIC9jY206IHRhZyBkb2Vzbid0IG1hdGNoL1xuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdyZXR1cm5zIGZhbHNlIHdoZW4gbmVpdGhlciBiYWNrdXBZU2hhcmUudSBub3IgdXNlcllTaGFyZS51IGlzIHByZXNlbnQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcGFydGlhbCA9IHsgdVNoYXJlOiB7IHNlZWQ6ICdhYmMnIH0sIGJpdGdvWVNoYXJlOiB7IHU6ICd4eXonIH0gfTtcbiAgICBjb25zdCBlbmNyeXB0ZWQgPSBzamNsLmVuY3J5cHQoUEFTU1BIUkFTRSwgSlNPTi5zdHJpbmdpZnkocGFydGlhbCkpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChhd2FpdCBFRERTQVV0aWxzLmlzRWRkc2FNcGNWMVNpZ25pbmdNYXRlcmlhbChlbmNyeXB0ZWQsIFBBU1NQSFJBU0UpLCBmYWxzZSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdzaWduUmVjb3ZlcnlFZGRzYU1QQ3YyJywgKCkgPT4ge1xuICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9ICdtLzAvMCc7XG5cbiAgaXQoJ3Nob3VsZCByZXR1cm4gYSA2NC1ieXRlIHNpZ25hdHVyZSB0aGF0IHZlcmlmaWVzIGFnYWluc3QgdGhlIGRlcml2ZWQgcHVibGljIGtleScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBbdXNlckRrZywgYmFja3VwRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbSgnZGVhZGJlZWYnLCAnaGV4Jyk7XG4gICAgY29uc3QgY29tbW9uS2V5Q2hhaW4gPSB1c2VyRGtnLmdldENvbW1vbktleWNoYWluKCk7XG5cbiAgICBjb25zdCBzaWduYXR1cmUgPSBhd2FpdCBFRERTQVV0aWxzLnNpZ25SZWNvdmVyeUVkZHNhTVBDdjIoXG4gICAgICBtZXNzYWdlLFxuICAgICAgZGVyaXZhdGlvblBhdGgsXG4gICAgICB1c2VyRGtnLmdldEtleVNoYXJlKCksXG4gICAgICBiYWNrdXBEa2cuZ2V0S2V5U2hhcmUoKSxcbiAgICAgIGNvbW1vbktleUNoYWluXG4gICAgKTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaWduYXR1cmUubGVuZ3RoLCA2NCk7XG5cbiAgICBjb25zdCBtcGMgPSBhd2FpdCBnZXRJbml0aWFsaXplZE1wY0luc3RhbmNlKCk7XG4gICAgY29uc3QgZGVyaXZlZEtleWNoYWluID0gbXBjLmRlcml2ZVVuaGFyZGVuZWQoY29tbW9uS2V5Q2hhaW4sIGRlcml2YXRpb25QYXRoKTtcbiAgICBjb25zdCBwdWJsaWNLZXlCeXRlcyA9IEJ1ZmZlci5mcm9tKGRlcml2ZWRLZXljaGFpbi5zbGljZSgwLCA2NCksICdoZXgnKTtcbiAgICBjb25zdCBvayA9IGVkMjU1MTkudmVyaWZ5KG5ldyBVaW50OEFycmF5KHNpZ25hdHVyZSksIG5ldyBVaW50OEFycmF5KG1lc3NhZ2UpLCBuZXcgVWludDhBcnJheShwdWJsaWNLZXlCeXRlcykpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChvaywgdHJ1ZSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIHdoZW4gdmVyaWZ5aW5nIHRoZSBzaWduYXR1cmUgYWdhaW5zdCBhIGRpZmZlcmVudCBtZXNzYWdlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IFt1c2VyRGtnLCBiYWNrdXBEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKCdkZWFkYmVlZicsICdoZXgnKTtcbiAgICBjb25zdCBjb21tb25LZXlDaGFpbiA9IHVzZXJEa2cuZ2V0Q29tbW9uS2V5Y2hhaW4oKTtcblxuICAgIGNvbnN0IHNpZ25hdHVyZSA9IGF3YWl0IEVERFNBVXRpbHMuc2lnblJlY292ZXJ5RWRkc2FNUEN2MihcbiAgICAgIG1lc3NhZ2UsXG4gICAgICBkZXJpdmF0aW9uUGF0aCxcbiAgICAgIHVzZXJEa2cuZ2V0S2V5U2hhcmUoKSxcbiAgICAgIGJhY2t1cERrZy5nZXRLZXlTaGFyZSgpLFxuICAgICAgY29tbW9uS2V5Q2hhaW5cbiAgICApO1xuXG4gICAgY29uc3QgZGlmZmVyZW50TWVzc2FnZSA9IEJ1ZmZlci5mcm9tKCdjYWZlYmFiZScsICdoZXgnKTtcbiAgICBjb25zdCBtcGMgPSBhd2FpdCBnZXRJbml0aWFsaXplZE1wY0luc3RhbmNlKCk7XG4gICAgY29uc3QgZGVyaXZlZEtleWNoYWluID0gbXBjLmRlcml2ZVVuaGFyZGVuZWQoY29tbW9uS2V5Q2hhaW4sIGRlcml2YXRpb25QYXRoKTtcbiAgICBjb25zdCBwdWJsaWNLZXlCeXRlcyA9IEJ1ZmZlci5mcm9tKGRlcml2ZWRLZXljaGFpbi5zbGljZSgwLCA2NCksICdoZXgnKTtcbiAgICBjb25zdCBvayA9IGVkMjU1MTkudmVyaWZ5KFxuICAgICAgbmV3IFVpbnQ4QXJyYXkoc2lnbmF0dXJlKSxcbiAgICAgIG5ldyBVaW50OEFycmF5KGRpZmZlcmVudE1lc3NhZ2UpLFxuICAgICAgbmV3IFVpbnQ4QXJyYXkocHVibGljS2V5Qnl0ZXMpXG4gICAgKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwob2ssIGZhbHNlKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIGEgd3JvbmcgY29tbW9uS2V5Q2hhaW4gaXMgcHJvdmlkZWQgKHZlcmlmaWNhdGlvbiBtaXNtYXRjaCknLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgW3VzZXJEa2csIGJhY2t1cERrZ10gPSBhd2FpdCBNUFNVdGlsLmdlbmVyYXRlRWREc2FES0dLZXlTaGFyZXMoKTtcbiAgICBjb25zdCBbd3JvbmdEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKCdkZWFkYmVlZicsICdoZXgnKTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgRUREU0FVdGlscy5zaWduUmVjb3ZlcnlFZGRzYU1QQ3YyKFxuICAgICAgICAgIG1lc3NhZ2UsXG4gICAgICAgICAgZGVyaXZhdGlvblBhdGgsXG4gICAgICAgICAgdXNlckRrZy5nZXRLZXlTaGFyZSgpLFxuICAgICAgICAgIGJhY2t1cERrZy5nZXRLZXlTaGFyZSgpLFxuICAgICAgICAgIHdyb25nRGtnLmdldENvbW1vbktleWNoYWluKCkgLy8ga2V5IGNoYWluIGZyb20gYSBkaWZmZXJlbnQgd2FsbGV0XG4gICAgICAgICksXG4gICAgICAvRWREU0EgTVBDdjIgcmVjb3Zlcnkgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiBmYWlsZWQvXG4gICAgKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ2dldEVkZHNhU2lnbmluZ01hdGVyaWFsJywgKCkgPT4ge1xuICBjb25zdCBQQVNTUEhSQVNFID0gJ3Rlc3QtcGFzc3BocmFzZSc7XG5cbiAgY29uc3QgTVBDdjFfTUFURVJJQUwgPSB7XG4gICAgdVNoYXJlOiB7IGk6IDEsIHQ6IDIsIG46IDMsIHk6ICdhYWJiY2MnLCBzZWVkOiAnZGVhZGJlZWYwMTIzNDU2NycsIGNoYWluY29kZTogJzAwJyB9LFxuICAgIGJpdGdvWVNoYXJlOiB7IGk6IDMsIGo6IDEsIHk6ICdhYWJiY2MnLCB1OiAnYml0Z28tdS12YWx1ZScsIGNoYWluY29kZTogJzAwJyB9LFxuICAgIGJhY2t1cFlTaGFyZTogeyBpOiAyLCBqOiAxLCB5OiAnYWFiYmNjJywgdTogJ2JhY2t1cC11LXZhbHVlJywgY2hhaW5jb2RlOiAnMDAnIH0sXG4gIH07XG5cbiAgaXQoJ3JldHVybnMgeyB2ZXJzaW9uOiB2MSwgdXNlclBydiB9IGZvciBNUEN2MSBKU09OIGtleWNhcmQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZW5jcnlwdGVkID0gc2pjbC5lbmNyeXB0KFBBU1NQSFJBU0UsIEpTT04uc3RyaW5naWZ5KE1QQ3YxX01BVEVSSUFMKSk7XG4gICAgY29uc3QgZGVjcnlwdFN0dWIgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoSlNPTi5zdHJpbmdpZnkoTVBDdjFfTUFURVJJQUwpKTtcbiAgICBjb25zdCBtb2NrQml0Z28gPSB7IGRlY3J5cHQ6IGRlY3J5cHRTdHViIH0gYXMgdW5rbm93biBhcyBCaXRHb0Jhc2U7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBnZXRFZGRzYVNpZ25pbmdNYXRlcmlhbChlbmNyeXB0ZWQsIFBBU1NQSFJBU0UsIG1vY2tCaXRnbyk7XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LnZlcnNpb24sICd2MScpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbCgocmVzdWx0IGFzIHsgdmVyc2lvbjogJ3YxJzsgdXNlclBydjogc3RyaW5nIH0pLnVzZXJQcnYsIEpTT04uc3RyaW5naWZ5KE1QQ3YxX01BVEVSSUFMKSk7XG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2UoZGVjcnlwdFN0dWIpO1xuICAgIHNpbm9uLmFzc2VydC5jYWxsZWRXaXRoTWF0Y2goZGVjcnlwdFN0dWIsIHsgaW5wdXQ6IHNpbm9uLm1hdGNoLnN0cmluZywgcGFzc3dvcmQ6IFBBU1NQSFJBU0UgfSk7XG4gIH0pO1xuXG4gIGl0KCdyZXR1cm5zIHsgdmVyc2lvbjogdjIsIGVuY3J5cHRlZFVzZXJLZXkgfSBmb3IgTVBDdjIgQ0JPUiBrZXljYXJkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IE1QQ3YyX0NCT1JfQllURVMgPSBCdWZmZXIuZnJvbShbMHhkOSwgMHgwMSwgMHgwNCwgMHhhMywgMHg2MSwgMHg3OCwgMHgxOCwgMHgwMF0pLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICBjb25zdCBlbmNyeXB0ZWQgPSBzamNsLmVuY3J5cHQoUEFTU1BIUkFTRSwgTVBDdjJfQ0JPUl9CWVRFUyk7XG4gICAgY29uc3Qgbm9ybWFsaXplZEtleSA9IGVuY3J5cHRlZC5yZXBsYWNlKC9cXHMvZywgJycpO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZ2V0RWRkc2FTaWduaW5nTWF0ZXJpYWwoZW5jcnlwdGVkLCBQQVNTUEhSQVNFKTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQudmVyc2lvbiwgJ3YyJyk7XG4gICAgYXNzZXJ0Lm9rKCdlbmNyeXB0ZWRVc2VyS2V5JyBpbiByZXN1bHQpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbCgocmVzdWx0IGFzIHsgdmVyc2lvbjogJ3YyJzsgZW5jcnlwdGVkVXNlcktleTogc3RyaW5nIH0pLmVuY3J5cHRlZFVzZXJLZXksIG5vcm1hbGl6ZWRLZXkpO1xuICB9KTtcblxuICBpdCgndGhyb3dzIHdpdGggY29udGV4dCBtZXNzYWdlIHdoZW4gZGVjcnlwdGlvbiBmYWlscycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBlbmNyeXB0ZWQgPSBzamNsLmVuY3J5cHQoUEFTU1BIUkFTRSwgSlNPTi5zdHJpbmdpZnkoTVBDdjFfTUFURVJJQUwpKTtcbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+IGdldEVkZHNhU2lnbmluZ01hdGVyaWFsKGVuY3J5cHRlZCwgJ3dyb25nLXBhc3NwaHJhc2UnKSxcbiAgICAgIC9FcnJvciBkZWNyeXB0aW5nIHVzZXIga2V5Y2hhaW4vXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3JldHVybnMgdjEgdmlhIHNqY2wgZmFsbGJhY2sgd2hlbiBiaXRnbyBpcyBvbWl0dGVkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGVuY3J5cHRlZCA9IHNqY2wuZW5jcnlwdChQQVNTUEhSQVNFLCBKU09OLnN0cmluZ2lmeShNUEN2MV9NQVRFUklBTCkpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdldEVkZHNhU2lnbmluZ01hdGVyaWFsKGVuY3J5cHRlZCwgUEFTU1BIUkFTRSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC52ZXJzaW9uLCAndjEnKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoKHJlc3VsdCBhcyB7IHZlcnNpb246ICd2MSc7IHVzZXJQcnY6IHN0cmluZyB9KS51c2VyUHJ2LCBKU09OLnN0cmluZ2lmeShNUEN2MV9NQVRFUklBTCkpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnaXNFZGRzYVNpZ25pbmdNYXRlcmlhbCcsICgpID0+IHtcbiAgaXQoJ3JldHVybnMgdHJ1ZSBmb3IgYSB2YWxpZCB2MSBzaGFwZScsICgpID0+IHtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoaXNFZGRzYVNpZ25pbmdNYXRlcmlhbCh7IHZlcnNpb246ICd2MScsIHVzZXJQcnY6ICd7fScgfSksIHRydWUpO1xuICB9KTtcblxuICBpdCgncmV0dXJucyB0cnVlIGZvciBhIHZhbGlkIHYyIHNoYXBlJywgKCkgPT4ge1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChpc0VkZHNhU2lnbmluZ01hdGVyaWFsKHsgdmVyc2lvbjogJ3YyJywgZW5jcnlwdGVkVXNlcktleTogJ2FiYzEyMycgfSksIHRydWUpO1xuICB9KTtcblxuICBpdCgncmV0dXJucyBmYWxzZSBmb3IgYSB2MSBzaGFwZSB3aXRoIGEgbm9uLXN0cmluZyB1c2VyUHJ2JywgKCkgPT4ge1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChpc0VkZHNhU2lnbmluZ01hdGVyaWFsKHsgdmVyc2lvbjogJ3YxJywgdXNlclBydjogMTIzIH0pLCBmYWxzZSk7XG4gIH0pO1xuXG4gIGl0KCdyZXR1cm5zIGZhbHNlIGZvciBhIHYyIHNoYXBlIHdpdGggYSBub24tc3RyaW5nIGVuY3J5cHRlZFVzZXJLZXknLCAoKSA9PiB7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGlzRWRkc2FTaWduaW5nTWF0ZXJpYWwoeyB2ZXJzaW9uOiAndjInLCBlbmNyeXB0ZWRVc2VyS2V5OiAxMjMgfSksIGZhbHNlKTtcbiAgfSk7XG5cbiAgaXQoJ3JldHVybnMgZmFsc2UgZm9yIGFuIHVucmVjb2duaXplZCB2ZXJzaW9uIHZhbHVlJywgKCkgPT4ge1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChpc0VkZHNhU2lnbmluZ01hdGVyaWFsKHsgdmVyc2lvbjogJ3YzJywgdXNlclBydjogJ3t9JyB9KSwgZmFsc2UpO1xuICB9KTtcblxuICBpdCgncmV0dXJucyBmYWxzZSBmb3IgYW4gb2JqZWN0IG1pc3NpbmcgYSB2ZXJzaW9uIGZpZWxkJywgKCkgPT4ge1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChpc0VkZHNhU2lnbmluZ01hdGVyaWFsKHsgdXNlclBydjogJ3t9JyB9KSwgZmFsc2UpO1xuICB9KTtcblxuICBpdCgncmV0dXJucyBmYWxzZSBmb3IgbnVsbCcsICgpID0+IHtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoaXNFZGRzYVNpZ25pbmdNYXRlcmlhbChudWxsKSwgZmFsc2UpO1xuICB9KTtcblxuICBpdCgncmV0dXJucyBmYWxzZSBmb3IgdW5kZWZpbmVkJywgKCkgPT4ge1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChpc0VkZHNhU2lnbmluZ01hdGVyaWFsKHVuZGVmaW5lZCksIGZhbHNlKTtcbiAgfSk7XG5cbiAgaXQoJ3JldHVybnMgZmFsc2UgZm9yIHByaW1pdGl2ZSB2YWx1ZXMnLCAoKSA9PiB7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGlzRWRkc2FTaWduaW5nTWF0ZXJpYWwoJ2Egc3RyaW5nJyksIGZhbHNlKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoaXNFZGRzYVNpZ25pbmdNYXRlcmlhbCg0MiksIGZhbHNlKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoaXNFZGRzYVNpZ25pbmdNYXRlcmlhbCh0cnVlKSwgZmFsc2UpO1xuICB9KTtcblxuICBpdCgncmV0dXJucyBmYWxzZSBmb3IgYW4gQXJyYXlCdWZmZXIgKHJlZ3Jlc3Npb246IFdSVyBvcGVuU1NMQnl0ZXMgY29sbGlzaW9uKScsICgpID0+IHtcbiAgICAvLyBXUlcncyBnZW5lcmljIEVsZWN0cm9uICdyZWNvdmVyJyBJUEMgaGFuZGxlciBwYXNzZXMgb3BlblNTTEJ5dGVzIGFzIGEgc2Vjb25kXG4gICAgLy8gcG9zaXRpb25hbCBhcmd1bWVudCB0byBldmVyeSBjb2luJ3MgcmVjb3ZlcigpLCBjb2xsaWRpbmcgd2l0aCBwcmVjb21wdXRlZE1hdGVyaWFsXG4gICAgLy8gb24gY29pbnMgdGhhdCBhY2NlcHQgaXQuIFRoaXMgbXVzdCBiZSByZWplY3RlZCByYXRoZXIgdGhhbiBtaXNyZWFkIGFzIHNpZ25pbmcgbWF0ZXJpYWwuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGlzRWRkc2FTaWduaW5nTWF0ZXJpYWwobmV3IEFycmF5QnVmZmVyKDgpKSwgZmFsc2UpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnc2lnbkVkZHNhTXBjVjJSZWNvdmVyeVR4JywgKCkgPT4ge1xuICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9ICdtLzAvMCc7XG4gIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAndGVzdFBhc3MnO1xuXG4gIGNvbnN0IG1ha2VEZWNyeXB0Qml0Z28gPSAodXNlcktleUJhc2U2NDogc3RyaW5nLCBiYWNrdXBLZXlCYXNlNjQ6IHN0cmluZyk6IEJpdEdvQmFzZSA9PlxuICAgICh7XG4gICAgICBkZWNyeXB0OiBzaW5vbi5zdHViKCkub25GaXJzdENhbGwoKS5yZXNvbHZlcyh1c2VyS2V5QmFzZTY0KS5vblNlY29uZENhbGwoKS5yZXNvbHZlcyhiYWNrdXBLZXlCYXNlNjQpLFxuICAgIH0gYXMgdW5rbm93biBhcyBCaXRHb0Jhc2UpO1xuXG4gIGl0KCdyZXR1cm5zIGEgNjQtYnl0ZSBzaWduYXR1cmUgdGhhdCB2ZXJpZmllcyBhZ2FpbnN0IHRoZSBkZXJpdmVkIHB1YmxpYyBrZXknLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgW3VzZXJEa2csIGJhY2t1cERrZ10gPSBhd2FpdCBNUFNVdGlsLmdlbmVyYXRlRWREc2FES0dLZXlTaGFyZXMoKTtcbiAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oJ2RlYWRiZWVmJywgJ2hleCcpO1xuICAgIGNvbnN0IGNvbW1vbktleUNoYWluID0gdXNlckRrZy5nZXRDb21tb25LZXljaGFpbigpO1xuICAgIGNvbnN0IG1vY2tCaXRnbyA9IG1ha2VEZWNyeXB0Qml0Z28oXG4gICAgICB1c2VyRGtnLmdldFJlZHVjZWRLZXlTaGFyZSgpLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIGJhY2t1cERrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKS50b1N0cmluZygnYmFzZTY0JylcbiAgICApO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2lnbkVkZHNhTXBjVjJSZWNvdmVyeVR4KHtcbiAgICAgIG1lc3NhZ2UsXG4gICAgICB1c2VyS2V5OiAnZW5jcnlwdGVkLXVzZXIta2V5JyxcbiAgICAgIGJhY2t1cEtleTogJ2VuY3J5cHRlZC1iYWNrdXAta2V5JyxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBiaXRnb0tleTogY29tbW9uS2V5Q2hhaW4sXG4gICAgICBkZXJpdmF0aW9uUGF0aCxcbiAgICAgIGJpdGdvOiBtb2NrQml0Z28sXG4gICAgfSk7XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0Lmxlbmd0aCwgNjQpO1xuICAgIGNvbnN0IG1wYyA9IGF3YWl0IGdldEluaXRpYWxpemVkTXBjSW5zdGFuY2UoKTtcbiAgICBjb25zdCBkZXJpdmVkS2V5Y2hhaW4gPSBtcGMuZGVyaXZlVW5oYXJkZW5lZChjb21tb25LZXlDaGFpbiwgZGVyaXZhdGlvblBhdGgpO1xuICAgIGNvbnN0IHB1YmxpY0tleUJ5dGVzID0gQnVmZmVyLmZyb20oZGVyaXZlZEtleWNoYWluLnNsaWNlKDAsIDY0KSwgJ2hleCcpO1xuICAgIGNvbnN0IG9rID0gZWQyNTUxOS52ZXJpZnkobmV3IFVpbnQ4QXJyYXkocmVzdWx0KSwgbmV3IFVpbnQ4QXJyYXkobWVzc2FnZSksIG5ldyBVaW50OEFycmF5KHB1YmxpY0tleUJ5dGVzKSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKG9rLCB0cnVlKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyB3aGVuIGNvbW1vbktleUNoYWluIGRvZXMgbm90IG1hdGNoIGJpdGdvS2V5JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IFt1c2VyRGtnLCBiYWNrdXBEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKCdkZWFkYmVlZicsICdoZXgnKTtcbiAgICBjb25zdCBtb2NrQml0Z28gPSBtYWtlRGVjcnlwdEJpdGdvKFxuICAgICAgdXNlckRrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICBiYWNrdXBEa2cuZ2V0UmVkdWNlZEtleVNoYXJlKCkudG9TdHJpbmcoJ2Jhc2U2NCcpXG4gICAgKTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgc2lnbkVkZHNhTXBjVjJSZWNvdmVyeVR4KHtcbiAgICAgICAgICBtZXNzYWdlLFxuICAgICAgICAgIHVzZXJLZXk6ICdlbmNyeXB0ZWQtdXNlci1rZXknLFxuICAgICAgICAgIGJhY2t1cEtleTogJ2VuY3J5cHRlZC1iYWNrdXAta2V5JyxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGJpdGdvS2V5OiAnYmJiYicucmVwZWF0KDMyKSxcbiAgICAgICAgICBkZXJpdmF0aW9uUGF0aCxcbiAgICAgICAgICBiaXRnbzogbW9ja0JpdGdvLFxuICAgICAgICB9KSxcbiAgICAgIC9jb21tb25LZXlDaGFpbiBmcm9tIGtleWNhcmQgZG9lcyBub3QgbWF0Y2ggYml0Z29LZXkvXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3Bhc3NlcyB1c2VyS2V5LCBiYWNrdXBLZXksIHBhc3NwaHJhc2UsIGFuZCBiaXRnbyB0byBnZXRFZGRzYU1wY1YyUmVjb3ZlcnlLZXlTaGFyZXNGcm9tUmVkdWNlZEtleScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBbdXNlckRrZywgYmFja3VwRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbSgnZGVhZGJlZWYnLCAnaGV4Jyk7XG4gICAgY29uc3QgZGVjcnlwdFN0dWIgPSBzaW5vblxuICAgICAgLnN0dWIoKVxuICAgICAgLm9uRmlyc3RDYWxsKClcbiAgICAgIC5yZXNvbHZlcyh1c2VyRGtnLmdldFJlZHVjZWRLZXlTaGFyZSgpLnRvU3RyaW5nKCdiYXNlNjQnKSlcbiAgICAgIC5vblNlY29uZENhbGwoKVxuICAgICAgLnJlc29sdmVzKGJhY2t1cERrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKS50b1N0cmluZygnYmFzZTY0JykpO1xuICAgIGNvbnN0IG1vY2tCaXRnbyA9IHsgZGVjcnlwdDogZGVjcnlwdFN0dWIgfSBhcyB1bmtub3duIGFzIEJpdEdvQmFzZTtcblxuICAgIGF3YWl0IHNpZ25FZGRzYU1wY1YyUmVjb3ZlcnlUeCh7XG4gICAgICBtZXNzYWdlLFxuICAgICAgdXNlcktleTogJ3Uta2V5JyxcbiAgICAgIGJhY2t1cEtleTogJ2Ita2V5JyxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBiaXRnb0tleTogdXNlckRrZy5nZXRDb21tb25LZXljaGFpbigpLFxuICAgICAgZGVyaXZhdGlvblBhdGgsXG4gICAgICBiaXRnbzogbW9ja0JpdGdvLFxuICAgIH0pO1xuXG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZFdpdGgoZGVjcnlwdFN0dWIuZmlyc3RDYWxsLCB7IGlucHV0OiAndS1rZXknLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KTtcbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkV2l0aChkZWNyeXB0U3R1Yi5zZWNvbmRDYWxsLCB7IGlucHV0OiAnYi1rZXknLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ0VkZHNhTVBDdjJVdGlscy5jcmVhdGVLZXljaGFpbnNXaXRoRXh0ZXJuYWxTaWduZXInLCBmdW5jdGlvbiAoKSB7XG4gIGxldCB1dGlsczogRWRkc2FNUEN2MlV0aWxzO1xuICBsZXQgY2FsbGJhY2tzOiBFZGRzYU1QQ3YyS2V5R2VuQ2FsbGJhY2tzO1xuICBjb25zdCBlbnRlcnByaXNlID0gJ2VudGVycHJpc2UtaWQnO1xuICBjb25zdCBzZXNzaW9uSWQgPSAnc2Vzc2lvbi0wMDEnO1xuICBjb25zdCBjb21tb25LZXljaGFpbiA9ICdjb21tb24ta2V5Y2hhaW4taGV4JztcblxuICBjb25zdCB1c2VyU3RhdGUgPSB7IGVuY3J5cHRlZERhdGE6ICd1LWRhdGEnLCBlbmNyeXB0ZWREYXRhS2V5OiAndS1kYXRhLWtleScgfTtcbiAgY29uc3QgYmFja3VwU3RhdGUgPSB7IGVuY3J5cHRlZERhdGE6ICdiLWRhdGEnLCBlbmNyeXB0ZWREYXRhS2V5OiAnYi1kYXRhLWtleScgfTtcbiAgY29uc3QgdXNlclNpZ25lZE1zZzE6IE1QU1R5cGVzLk1QU1NpZ25lZE1lc3NhZ2UgPSB7IG1lc3NhZ2U6ICd1bXNnMScsIHNpZ25hdHVyZTogJ3VzaWcxJyB9O1xuICBjb25zdCBiYWNrdXBTaWduZWRNc2cxOiBNUFNUeXBlcy5NUFNTaWduZWRNZXNzYWdlID0geyBtZXNzYWdlOiAnYm1zZzEnLCBzaWduYXR1cmU6ICdic2lnMScgfTtcbiAgY29uc3QgdXNlclNpZ25lZE1zZzI6IE1QU1R5cGVzLk1QU1NpZ25lZE1lc3NhZ2UgPSB7IG1lc3NhZ2U6ICd1bXNnMicsIHNpZ25hdHVyZTogJ3VzaWcyJyB9O1xuICBjb25zdCBiYWNrdXBTaWduZWRNc2cyOiBNUFNUeXBlcy5NUFNTaWduZWRNZXNzYWdlID0geyBtZXNzYWdlOiAnYm1zZzInLCBzaWduYXR1cmU6ICdic2lnMicgfTtcbiAgY29uc3QgYml0Z29Nc2cxOiBNUFNUeXBlcy5NUFNTaWduZWRNZXNzYWdlID0geyBtZXNzYWdlOiAnYml0Z28tbXNnMScsIHNpZ25hdHVyZTogJ2JpdGdvLXNpZzEnIH07XG4gIGNvbnN0IGJpdGdvTXNnMjogTVBTVHlwZXMuTVBTU2lnbmVkTWVzc2FnZSA9IHsgbWVzc2FnZTogJ2JpdGdvLW1zZzInLCBzaWduYXR1cmU6ICdiaXRnby1zaWcyJyB9O1xuXG4gIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgIGNhbGxiYWNrcyA9IHtcbiAgICAgIGluaXRpYWxpemVDYWxsYmFjazogc2lub24uc3R1YigpLnJlc29sdmVzKHtcbiAgICAgICAgdXNlckdwZ1B1YmxpY0tleTogJ3VzZXItZ3BnLXB1YicsXG4gICAgICAgIGJhY2t1cEdwZ1B1YmxpY0tleTogJ2JhY2t1cC1ncGctcHViJyxcbiAgICAgICAgdXNlclN0YXRlLFxuICAgICAgICBiYWNrdXBTdGF0ZSxcbiAgICAgIH0pLFxuICAgICAgcm91bmQxQ2FsbGJhY2s6IHNpbm9uLnN0dWIoKS5yZXNvbHZlcyh7XG4gICAgICAgIHVzZXJTaWduZWRNc2cxLFxuICAgICAgICBiYWNrdXBTaWduZWRNc2cxLFxuICAgICAgICB1c2VyU3RhdGUsXG4gICAgICAgIGJhY2t1cFN0YXRlLFxuICAgICAgfSksXG4gICAgICByb3VuZDJDYWxsYmFjazogc2lub24uc3R1YigpLnJlc29sdmVzKHtcbiAgICAgICAgdXNlclNpZ25lZE1zZzIsXG4gICAgICAgIGJhY2t1cFNpZ25lZE1zZzIsXG4gICAgICAgIHVzZXJTdGF0ZSxcbiAgICAgICAgYmFja3VwU3RhdGUsXG4gICAgICB9KSxcbiAgICAgIGZpbmFsaXplQ2FsbGJhY2s6IHNpbm9uLnN0dWIoKS5yZXNvbHZlcyh7IGNvbW1vbktleWNoYWluIH0pLFxuICAgIH07XG5cbiAgICBjb25zdCBtb2NrQml0R28gPSB7XG4gICAgICBnZXRFbnY6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCdkZXYnKSxcbiAgICB9IGFzIGFueTtcblxuICAgIGNvbnN0IG1vY2tLZXljaGFpbnMgPSB7XG4gICAgICBhZGQ6IHNpbm9uXG4gICAgICAgIC5zdHViKClcbiAgICAgICAgLmNhbGxzRmFrZSgocGFyYW1zOiBhbnkpID0+IFByb21pc2UucmVzb2x2ZSh7IGlkOiBgJHtwYXJhbXMuc291cmNlfS1rZXktaWRgLCBjb21tb25LZXljaGFpbiwgaXNNUEN2MjogdHJ1ZSB9KSksXG4gICAgfTtcblxuICAgIGNvbnN0IG1vY2tDb2luID0ge1xuICAgICAga2V5Y2hhaW5zOiBzaW5vbi5zdHViKCkucmV0dXJucyhtb2NrS2V5Y2hhaW5zKSxcbiAgICB9IGFzIGFueTtcblxuICAgIHV0aWxzID0gbmV3IEVkZHNhTVBDdjJVdGlscyhtb2NrQml0R28sIG1vY2tDb2luKTtcblxuICAgIHNpbm9uLnN0dWIodXRpbHMsICdnZXRCaXRnb0dwZ1B1YmtleUJhc2VkT25GZWF0dXJlRmxhZ3MnIGFzIGFueSkucmVzb2x2ZXMoeyBlZGRzYU1wY3YyUHVibGljS2V5OiBudWxsIH0pO1xuICAgICh1dGlscyBhcyBhbnkpLmJpdGdvRWRkc2FNcGN2MlB1YmxpY0dwZ0tleSA9IHsgYXJtb3I6ICgpID0+ICctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nIH07XG5cbiAgICBzaW5vbi5zdHViKHV0aWxzLCAnc2VuZEtleUdlbmVyYXRpb25Sb3VuZDEnKS5yZXNvbHZlcyh7XG4gICAgICBzZXNzaW9uSWQ6IHNlc3Npb25JZCBhcyBhbnksXG4gICAgICBiaXRnb01zZzEsXG4gICAgfSk7XG4gICAgc2lub24uc3R1Yih1dGlscywgJ3NlbmRLZXlHZW5lcmF0aW9uUm91bmQyJykucmVzb2x2ZXMoe1xuICAgICAgc2Vzc2lvbklkOiBzZXNzaW9uSWQgYXMgYW55LFxuICAgICAgY29tbW9uUHVibGljS2V5Y2hhaW46IGNvbW1vbktleWNoYWluIGFzIGFueSxcbiAgICAgIGJpdGdvTXNnMixcbiAgICB9KTtcbiAgICBzaW5vbi5zdHViKHV0aWxzIGFzIGFueSwgJ2FkZEJpdGdvS2V5Y2hhaW4nKS5yZXNvbHZlcyh7IGlkOiAnYml0Z28ta2V5LWlkJywgY29tbW9uS2V5Y2hhaW4sIGlzTVBDdjI6IHRydWUgfSk7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgc2lub24ucmVzdG9yZSgpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGludm9rZSBjYWxsYmFja3MgaW4gb3JkZXIgYW5kIHJldHVybiBrZXljaGFpbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qga2V5Y2hhaW5zID0gYXdhaXQgdXRpbHMuY3JlYXRlS2V5Y2hhaW5zV2l0aEV4dGVybmFsU2lnbmVyKHsgZW50ZXJwcmlzZSwgY2FsbGJhY2tzIH0pO1xuXG4gICAgYXNzZXJ0Lm9rKGtleWNoYWlucy51c2VyS2V5Y2hhaW4pO1xuICAgIGFzc2VydC5vayhrZXljaGFpbnMuYmFja3VwS2V5Y2hhaW4pO1xuICAgIGFzc2VydC5vayhrZXljaGFpbnMuYml0Z29LZXljaGFpbik7XG5cbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShjYWxsYmFja3MuaW5pdGlhbGl6ZUNhbGxiYWNrIGFzIHNpbm9uLlNpbm9uU3R1Yik7XG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2UoY2FsbGJhY2tzLnJvdW5kMUNhbGxiYWNrIGFzIHNpbm9uLlNpbm9uU3R1Yik7XG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2UoY2FsbGJhY2tzLnJvdW5kMkNhbGxiYWNrIGFzIHNpbm9uLlNpbm9uU3R1Yik7XG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2UoY2FsbGJhY2tzLmZpbmFsaXplQ2FsbGJhY2sgYXMgc2lub24uU2lub25TdHViKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBwYXNzIHJvdW5kMSByZXNwb25zZSB0byByb3VuZDJDYWxsYmFjaycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBhd2FpdCB1dGlscy5jcmVhdGVLZXljaGFpbnNXaXRoRXh0ZXJuYWxTaWduZXIoeyBlbnRlcnByaXNlLCBjYWxsYmFja3MgfSk7XG5cbiAgICBjb25zdCByb3VuZDJBcmdzID0gKGNhbGxiYWNrcy5yb3VuZDJDYWxsYmFjayBhcyBzaW5vbi5TaW5vblN0dWIpLmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwocm91bmQyQXJncy5iaXRnb01zZzEsIGJpdGdvTXNnMSk7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChyb3VuZDJBcmdzLnVzZXJTaWduZWRNc2cxLCB1c2VyU2lnbmVkTXNnMSk7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChyb3VuZDJBcmdzLmJhY2t1cFNpZ25lZE1zZzEsIGJhY2t1cFNpZ25lZE1zZzEpO1xuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwocm91bmQyQXJncy51c2VyU3RhdGUsIHVzZXJTdGF0ZSk7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChyb3VuZDJBcmdzLmJhY2t1cFN0YXRlLCBiYWNrdXBTdGF0ZSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcGFzcyByb3VuZDIgcmVzcG9uc2UgdG8gZmluYWxpemVDYWxsYmFjaycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBhd2FpdCB1dGlscy5jcmVhdGVLZXljaGFpbnNXaXRoRXh0ZXJuYWxTaWduZXIoeyBlbnRlcnByaXNlLCBjYWxsYmFja3MgfSk7XG5cbiAgICBjb25zdCBmaW5hbGl6ZUFyZ3MgPSAoY2FsbGJhY2tzLmZpbmFsaXplQ2FsbGJhY2sgYXMgc2lub24uU2lub25TdHViKS5maXJzdENhbGwuYXJnc1swXTtcbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGZpbmFsaXplQXJncy5iaXRnb01zZzIsIGJpdGdvTXNnMik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGZpbmFsaXplQXJncy5iaXRnb0NvbW1vbktleWNoYWluLCBjb21tb25LZXljaGFpbik7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChmaW5hbGl6ZUFyZ3MudXNlclN0YXRlLCB1c2VyU3RhdGUpO1xuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoZmluYWxpemVBcmdzLmJhY2t1cFN0YXRlLCBiYWNrdXBTdGF0ZSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmVnaXN0ZXIga2V5Y2hhaW5zIHdpdGggaXNNUEN2MjogdHJ1ZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBhd2FpdCB1dGlscy5jcmVhdGVLZXljaGFpbnNXaXRoRXh0ZXJuYWxTaWduZXIoeyBlbnRlcnByaXNlLCBjYWxsYmFja3MgfSk7XG5cbiAgICBjb25zdCBtb2NrS2V5Y2hhaW5zID0gKHV0aWxzIGFzIGFueSkuYmFzZUNvaW4ua2V5Y2hhaW5zKCk7XG4gICAgY29uc3QgYWRkQ2FsbHMgPSAobW9ja0tleWNoYWlucy5hZGQgYXMgc2lub24uU2lub25TdHViKS5nZXRDYWxscygpO1xuICAgIGFzc2VydC5vayhhZGRDYWxscy5sZW5ndGggPj0gMiwgJ2tleWNoYWlucy5hZGQgc2hvdWxkIGJlIGNhbGxlZCBmb3IgdXNlciBhbmQgYmFja3VwJyk7XG4gICAgZm9yIChjb25zdCBjYWxsIG9mIGFkZENhbGxzKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoY2FsbC5hcmdzWzBdLmlzTVBDdjIsIHRydWUpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGNhbGwuYXJnc1swXS5rZXlUeXBlLCAndHNzJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoY2FsbC5hcmdzWzBdLmNvbW1vbktleWNoYWluLCBjb21tb25LZXljaGFpbik7XG4gICAgfVxuICB9KTtcblxuICBpdCgnc2hvdWxkIHJlamVjdCB3aGVuIGZpbmFsaXplQ2FsbGJhY2sgcmV0dXJucyBtaXNtYXRjaGVkIGNvbW1vbktleWNoYWluJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIChjYWxsYmFja3MuZmluYWxpemVDYWxsYmFjayBhcyBzaW5vbi5TaW5vblN0dWIpLnJlc29sdmVzKHsgY29tbW9uS2V5Y2hhaW46ICdkaWZmZXJlbnQta2V5Y2hhaW4nIH0pO1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PiB1dGlscy5jcmVhdGVLZXljaGFpbnNXaXRoRXh0ZXJuYWxTaWduZXIoeyBlbnRlcnByaXNlLCBjYWxsYmFja3MgfSksXG4gICAgICAvQ29tbW9uIGtleWNoYWlucyBkbyBub3QgbWF0Y2gvXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWplY3Qgd2hlbiByb3VuZDIgcmV0dXJucyBtaXNtYXRjaGVkIHNlc3Npb25JZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAodXRpbHMuc2VuZEtleUdlbmVyYXRpb25Sb3VuZDIgYXMgc2lub24uU2lub25TdHViKS5yZXNvbHZlcyh7XG4gICAgICBzZXNzaW9uSWQ6ICdkaWZmZXJlbnQtc2Vzc2lvbicgYXMgYW55LFxuICAgICAgY29tbW9uUHVibGljS2V5Y2hhaW46IGNvbW1vbktleWNoYWluIGFzIGFueSxcbiAgICAgIGJpdGdvTXNnMixcbiAgICB9KTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT4gdXRpbHMuY3JlYXRlS2V5Y2hhaW5zV2l0aEV4dGVybmFsU2lnbmVyKHsgZW50ZXJwcmlzZSwgY2FsbGJhY2tzIH0pLFxuICAgICAgL1JvdW5kIDEgYW5kIHJvdW5kIDIgc2Vzc2lvbiBJRHMgZG8gbm90IG1hdGNoL1xuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmVqZWN0IHdoZW4gQml0R28gRWREU0EgTVBDdjIgR1BHIHB1YmxpYyBrZXkgaXMgbWlzc2luZycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAodXRpbHMgYXMgYW55KS5iaXRnb0VkZHNhTXBjdjJQdWJsaWNHcGdLZXkgPSB1bmRlZmluZWQ7XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+IHV0aWxzLmNyZWF0ZUtleWNoYWluc1dpdGhFeHRlcm5hbFNpZ25lcih7IGVudGVycHJpc2UsIGNhbGxiYWNrcyB9KSxcbiAgICAgIC9GYWlsZWQgdG8gZ2V0IEJpdEdvIEVkRFNBIE1QQ3YyIEdQRyBwdWJsaWMga2V5L1xuICAgICk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdFZGRzYU1QQ3YyVXRpbHMuZ2V0TXBjVjJSZXRyb2ZpdERhdGFGcm9tTXBjVjFLZXlzJywgKCkgPT4ge1xuICBsZXQgdXRpbHM6IEVkZHNhTVBDdjJVdGlscztcbiAgLy8gUmVhbCAzLXBhcnR5IE1QQ3YxIEVkRFNBIGtleSBzaGFyZXM6IDEgPSB1c2VyLCAyID0gYmFja3VwLCAzID0gYml0Z28uXG4gIGxldCB1c2VyU2lnbmluZ01hdGVyaWFsOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgbGV0IGJhY2t1cFNpZ25pbmdNYXRlcmlhbDogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGxldCBleHBlY3RlZFVzZXJQU2hhcmU6IHsgeTogc3RyaW5nOyB1OiBzdHJpbmc7IGNoYWluY29kZTogc3RyaW5nIH07XG4gIGxldCBleHBlY3RlZEJhY2t1cFBTaGFyZTogeyB5OiBzdHJpbmc7IHU6IHN0cmluZzsgY2hhaW5jb2RlOiBzdHJpbmcgfTtcblxuICBiZWZvcmUoYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IE1QQyA9IGF3YWl0IGdldEluaXRpYWxpemVkTXBjSW5zdGFuY2UoKTtcbiAgICBjb25zdCB1c2VyID0gTVBDLmtleVNoYXJlKDEsIDIsIDMpO1xuICAgIGNvbnN0IGJhY2t1cCA9IE1QQy5rZXlTaGFyZSgyLCAyLCAzKTtcbiAgICBjb25zdCBiaXRnbyA9IE1QQy5rZXlTaGFyZSgzLCAyLCAzKTtcblxuICAgIGV4cGVjdGVkVXNlclBTaGFyZSA9IE1QQy5rZXlDb21iaW5lKHVzZXIudVNoYXJlLCBbYmFja3VwLnlTaGFyZXNbMV0sIGJpdGdvLnlTaGFyZXNbMV1dKS5wU2hhcmU7XG4gICAgZXhwZWN0ZWRCYWNrdXBQU2hhcmUgPSBNUEMua2V5Q29tYmluZShiYWNrdXAudVNoYXJlLCBbdXNlci55U2hhcmVzWzJdLCBiaXRnby55U2hhcmVzWzJdXSkucFNoYXJlO1xuXG4gICAgdXNlclNpZ25pbmdNYXRlcmlhbCA9IHtcbiAgICAgIHVTaGFyZTogdXNlci51U2hhcmUsXG4gICAgICBiaXRnb1lTaGFyZTogYml0Z28ueVNoYXJlc1sxXSxcbiAgICAgIGJhY2t1cFlTaGFyZTogYmFja3VwLnlTaGFyZXNbMV0sXG4gICAgfTtcbiAgICBiYWNrdXBTaWduaW5nTWF0ZXJpYWwgPSB7XG4gICAgICB1U2hhcmU6IGJhY2t1cC51U2hhcmUsXG4gICAgICBiaXRnb1lTaGFyZTogYml0Z28ueVNoYXJlc1syXSxcbiAgICAgIHVzZXJZU2hhcmU6IHVzZXIueVNoYXJlc1syXSxcbiAgICB9O1xuICB9KTtcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBjb25zdCBtb2NrQml0R28gPSB7fSBhcyB1bmtub3duIGFzIEJpdEdvQmFzZTtcbiAgICBjb25zdCBtb2NrQ29pbiA9IHt9IGFzIHVua25vd24gYXMgSUJhc2VDb2luO1xuICAgIHV0aWxzID0gbmV3IEVkZHNhTVBDdjJVdGlscyhtb2NrQml0R28sIG1vY2tDb2luKTtcbiAgfSk7XG5cbiAgaXQoJ2Rlcml2ZXMgbWF0Y2hpbmcgZXhwZWN0ZWRQayBhbmQgY2hhaW5Db2RlIGZvciB1c2VyIGFuZCBiYWNrdXAgZnJvbSByZWFsIE1QQ3YxIGtleSBjb21iaW5lJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHsgdXNlclJldHJvZml0RGF0YSwgYmFja3VwUmV0cm9maXREYXRhIH0gPSBhd2FpdCB1dGlscy5nZXRNcGNWMlJldHJvZml0RGF0YUZyb21NcGNWMUtleXMoe1xuICAgICAgbXBjdjFVc2VyS2V5U2hhcmU6IEpTT04uc3RyaW5naWZ5KHVzZXJTaWduaW5nTWF0ZXJpYWwpLFxuICAgICAgbXBjdjFCYWNrdXBLZXlTaGFyZTogSlNPTi5zdHJpbmdpZnkoYmFja3VwU2lnbmluZ01hdGVyaWFsKSxcbiAgICB9KTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1c2VyUmV0cm9maXREYXRhLmV4cGVjdGVkUGssIGV4cGVjdGVkVXNlclBTaGFyZS55KTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYmFja3VwUmV0cm9maXREYXRhLmV4cGVjdGVkUGssIGV4cGVjdGVkQmFja3VwUFNoYXJlLnkpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1c2VyUmV0cm9maXREYXRhLmV4cGVjdGVkUGssIGJhY2t1cFJldHJvZml0RGF0YS5leHBlY3RlZFBrKTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1c2VyUmV0cm9maXREYXRhLmNoYWluQ29kZSwgZXhwZWN0ZWRVc2VyUFNoYXJlLmNoYWluY29kZSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJhY2t1cFJldHJvZml0RGF0YS5jaGFpbkNvZGUsIGV4cGVjdGVkQmFja3VwUFNoYXJlLmNoYWluY29kZSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHVzZXJSZXRyb2ZpdERhdGEuY2hhaW5Db2RlLCBiYWNrdXBSZXRyb2ZpdERhdGEuY2hhaW5Db2RlKTtcbiAgfSk7XG5cbiAgaXQoJ2Rlcml2ZXMgc19pXzAgYXMgdGhlIGNvbWJpbmVkIHBTaGFyZS51IChjbGFtcGVkIHNjYWxhcikgZm9yIGVhY2ggcGFydHknLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeyB1c2VyUmV0cm9maXREYXRhLCBiYWNrdXBSZXRyb2ZpdERhdGEgfSA9IGF3YWl0IHV0aWxzLmdldE1wY1YyUmV0cm9maXREYXRhRnJvbU1wY1YxS2V5cyh7XG4gICAgICBtcGN2MVVzZXJLZXlTaGFyZTogSlNPTi5zdHJpbmdpZnkodXNlclNpZ25pbmdNYXRlcmlhbCksXG4gICAgICBtcGN2MUJhY2t1cEtleVNoYXJlOiBKU09OLnN0cmluZ2lmeShiYWNrdXBTaWduaW5nTWF0ZXJpYWwpLFxuICAgIH0pO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHVzZXJSZXRyb2ZpdERhdGEuc19pXzAsIGV4cGVjdGVkVXNlclBTaGFyZS51KTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYmFja3VwUmV0cm9maXREYXRhLnNfaV8wLCBleHBlY3RlZEJhY2t1cFBTaGFyZS51KTtcbiAgICBhc3NlcnQubm90U3RyaWN0RXF1YWwodXNlclJldHJvZml0RGF0YS5zX2lfMCwgYmFja3VwUmV0cm9maXREYXRhLnNfaV8wKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyBpZiB1c2VyIGtleSBpcyBtaXNzaW5nIHVTaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBrZXlOb1VTaGFyZSA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIGJpdGdvWVNoYXJlOiB1c2VyU2lnbmluZ01hdGVyaWFsLmJpdGdvWVNoYXJlLFxuICAgICAgYmFja3VwWVNoYXJlOiB1c2VyU2lnbmluZ01hdGVyaWFsLmJhY2t1cFlTaGFyZSxcbiAgICB9KTtcbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+XG4gICAgICAgIHV0aWxzLmdldE1wY1YyUmV0cm9maXREYXRhRnJvbU1wY1YxS2V5cyh7XG4gICAgICAgICAgbXBjdjFVc2VyS2V5U2hhcmU6IGtleU5vVVNoYXJlLFxuICAgICAgICAgIG1wY3YxQmFja3VwS2V5U2hhcmU6IEpTT04uc3RyaW5naWZ5KGJhY2t1cFNpZ25pbmdNYXRlcmlhbCksXG4gICAgICAgIH0pLFxuICAgICAgL01QQ3YxIGtleSBtYXRlcmlhbCBtaXNzaW5nIHVTaGFyZS9cbiAgICApO1xuICB9KTtcblxuICBpdCgndGhyb3dzIGlmIHVzZXIga2V5IGlzIG1pc3NpbmcgYml0Z29ZU2hhcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qga2V5Tm9CaXRnb1lTaGFyZSA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIHVTaGFyZTogdXNlclNpZ25pbmdNYXRlcmlhbC51U2hhcmUsXG4gICAgICBiYWNrdXBZU2hhcmU6IHVzZXJTaWduaW5nTWF0ZXJpYWwuYmFja3VwWVNoYXJlLFxuICAgIH0pO1xuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXRpbHMuZ2V0TXBjVjJSZXRyb2ZpdERhdGFGcm9tTXBjVjFLZXlzKHtcbiAgICAgICAgICBtcGN2MVVzZXJLZXlTaGFyZToga2V5Tm9CaXRnb1lTaGFyZSxcbiAgICAgICAgICBtcGN2MUJhY2t1cEtleVNoYXJlOiBKU09OLnN0cmluZ2lmeShiYWNrdXBTaWduaW5nTWF0ZXJpYWwpLFxuICAgICAgICB9KSxcbiAgICAgIC9NUEN2MSBrZXkgbWF0ZXJpYWwgbWlzc2luZyBiaXRnb1lTaGFyZS9cbiAgICApO1xuICB9KTtcblxuICBpdCgndGhyb3dzIGlmIHVzZXIga2V5IGlzIG1pc3NpbmcgYmFja3VwWVNoYXJlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGtleU5vQmFja3VwWVNoYXJlID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgdVNoYXJlOiB1c2VyU2lnbmluZ01hdGVyaWFsLnVTaGFyZSxcbiAgICAgIGJpdGdvWVNoYXJlOiB1c2VyU2lnbmluZ01hdGVyaWFsLmJpdGdvWVNoYXJlLFxuICAgIH0pO1xuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXRpbHMuZ2V0TXBjVjJSZXRyb2ZpdERhdGFGcm9tTXBjVjFLZXlzKHtcbiAgICAgICAgICBtcGN2MVVzZXJLZXlTaGFyZToga2V5Tm9CYWNrdXBZU2hhcmUsXG4gICAgICAgICAgbXBjdjFCYWNrdXBLZXlTaGFyZTogSlNPTi5zdHJpbmdpZnkoYmFja3VwU2lnbmluZ01hdGVyaWFsKSxcbiAgICAgICAgfSksXG4gICAgICAvVXNlciBNUEN2MSBrZXkgbWF0ZXJpYWwgbWlzc2luZyBiYWNrdXBZU2hhcmUvXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyBpZiBiYWNrdXAga2V5IGlzIG1pc3NpbmcgdVNoYXJlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGtleU5vVVNoYXJlID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgYml0Z29ZU2hhcmU6IGJhY2t1cFNpZ25pbmdNYXRlcmlhbC5iaXRnb1lTaGFyZSxcbiAgICAgIHVzZXJZU2hhcmU6IGJhY2t1cFNpZ25pbmdNYXRlcmlhbC51c2VyWVNoYXJlLFxuICAgIH0pO1xuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgdXRpbHMuZ2V0TXBjVjJSZXRyb2ZpdERhdGFGcm9tTXBjVjFLZXlzKHtcbiAgICAgICAgICBtcGN2MVVzZXJLZXlTaGFyZTogSlNPTi5zdHJpbmdpZnkodXNlclNpZ25pbmdNYXRlcmlhbCksXG4gICAgICAgICAgbXBjdjFCYWNrdXBLZXlTaGFyZToga2V5Tm9VU2hhcmUsXG4gICAgICAgIH0pLFxuICAgICAgL01QQ3YxIGtleSBtYXRlcmlhbCBtaXNzaW5nIHVTaGFyZS9cbiAgICApO1xuICB9KTtcblxuICBpdCgndGhyb3dzIGlmIGJhY2t1cCBrZXkgaXMgbWlzc2luZyBiaXRnb1lTaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBrZXlOb0JpdGdvWVNoYXJlID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgdVNoYXJlOiBiYWNrdXBTaWduaW5nTWF0ZXJpYWwudVNoYXJlLFxuICAgICAgdXNlcllTaGFyZTogYmFja3VwU2lnbmluZ01hdGVyaWFsLnVzZXJZU2hhcmUsXG4gICAgfSk7XG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PlxuICAgICAgICB1dGlscy5nZXRNcGNWMlJldHJvZml0RGF0YUZyb21NcGNWMUtleXMoe1xuICAgICAgICAgIG1wY3YxVXNlcktleVNoYXJlOiBKU09OLnN0cmluZ2lmeSh1c2VyU2lnbmluZ01hdGVyaWFsKSxcbiAgICAgICAgICBtcGN2MUJhY2t1cEtleVNoYXJlOiBrZXlOb0JpdGdvWVNoYXJlLFxuICAgICAgICB9KSxcbiAgICAgIC9NUEN2MSBrZXkgbWF0ZXJpYWwgbWlzc2luZyBiaXRnb1lTaGFyZS9cbiAgICApO1xuICB9KTtcblxuICBpdCgndGhyb3dzIGlmIGJhY2t1cCBrZXkgaXMgbWlzc2luZyB1c2VyWVNoYXJlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGtleU5vVXNlcllTaGFyZSA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIHVTaGFyZTogYmFja3VwU2lnbmluZ01hdGVyaWFsLnVTaGFyZSxcbiAgICAgIGJpdGdvWVNoYXJlOiBiYWNrdXBTaWduaW5nTWF0ZXJpYWwuYml0Z29ZU2hhcmUsXG4gICAgfSk7XG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PlxuICAgICAgICB1dGlscy5nZXRNcGNWMlJldHJvZml0RGF0YUZyb21NcGNWMUtleXMoe1xuICAgICAgICAgIG1wY3YxVXNlcktleVNoYXJlOiBKU09OLnN0cmluZ2lmeSh1c2VyU2lnbmluZ01hdGVyaWFsKSxcbiAgICAgICAgICBtcGN2MUJhY2t1cEtleVNoYXJlOiBrZXlOb1VzZXJZU2hhcmUsXG4gICAgICAgIH0pLFxuICAgICAgL0JhY2t1cCBNUEN2MSBrZXkgbWF0ZXJpYWwgbWlzc2luZyB1c2VyWVNoYXJlL1xuICAgICk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdFZGRzYU1QQ3YyVXRpbHMuZ2V0S2V5RGF0YUZvclJldHJvZml0JywgKCkgPT4ge1xuICBsZXQgdXNlclNpZ25pbmdNYXRlcmlhbDogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGxldCBiYWNrdXBTaWduaW5nTWF0ZXJpYWw6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBsZXQgZXhwZWN0ZWRVc2VyUFNoYXJlOiB7IHk6IHN0cmluZzsgdTogc3RyaW5nOyBjaGFpbmNvZGU6IHN0cmluZyB9O1xuICBsZXQgZXhwZWN0ZWRCYWNrdXBQU2hhcmU6IHsgeTogc3RyaW5nOyB1OiBzdHJpbmc7IGNoYWluY29kZTogc3RyaW5nIH07XG5cbiAgYmVmb3JlKGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBNUEMgPSBhd2FpdCBnZXRJbml0aWFsaXplZE1wY0luc3RhbmNlKCk7XG4gICAgY29uc3QgdXNlciA9IE1QQy5rZXlTaGFyZSgxLCAyLCAzKTtcbiAgICBjb25zdCBiYWNrdXAgPSBNUEMua2V5U2hhcmUoMiwgMiwgMyk7XG4gICAgY29uc3QgYml0Z28gPSBNUEMua2V5U2hhcmUoMywgMiwgMyk7XG5cbiAgICBleHBlY3RlZFVzZXJQU2hhcmUgPSBNUEMua2V5Q29tYmluZSh1c2VyLnVTaGFyZSwgW2JhY2t1cC55U2hhcmVzWzFdLCBiaXRnby55U2hhcmVzWzFdXSkucFNoYXJlO1xuICAgIGV4cGVjdGVkQmFja3VwUFNoYXJlID0gTVBDLmtleUNvbWJpbmUoYmFja3VwLnVTaGFyZSwgW3VzZXIueVNoYXJlc1syXSwgYml0Z28ueVNoYXJlc1syXV0pLnBTaGFyZTtcblxuICAgIHVzZXJTaWduaW5nTWF0ZXJpYWwgPSB7XG4gICAgICB1U2hhcmU6IHVzZXIudVNoYXJlLFxuICAgICAgYml0Z29ZU2hhcmU6IGJpdGdvLnlTaGFyZXNbMV0sXG4gICAgICBiYWNrdXBZU2hhcmU6IGJhY2t1cC55U2hhcmVzWzFdLFxuICAgIH07XG4gICAgYmFja3VwU2lnbmluZ01hdGVyaWFsID0ge1xuICAgICAgdVNoYXJlOiBiYWNrdXAudVNoYXJlLFxuICAgICAgYml0Z29ZU2hhcmU6IGJpdGdvLnlTaGFyZXNbMl0sXG4gICAgICB1c2VyWVNoYXJlOiB1c2VyLnlTaGFyZXNbMl0sXG4gICAgfTtcbiAgfSk7XG5cbiAgaXQoJ2Rlcml2ZXMgVVNFUiByZXRyb2ZpdCBkYXRhIG1hdGNoaW5nIGtleUNvbWJpbmUgcFNoYXJlIGZpZWxkcycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXRyb2ZpdERhdGEgPSBhd2FpdCBFZGRzYU1QQ3YyVXRpbHMuZ2V0S2V5RGF0YUZvclJldHJvZml0KFxuICAgICAgSlNPTi5zdHJpbmdpZnkodXNlclNpZ25pbmdNYXRlcmlhbCksXG4gICAgICBNUEN2MlBhcnRpZXNFbnVtLlVTRVJcbiAgICApO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJldHJvZml0RGF0YS5zX2lfMCwgZXhwZWN0ZWRVc2VyUFNoYXJlLnUpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXRyb2ZpdERhdGEuZXhwZWN0ZWRQaywgZXhwZWN0ZWRVc2VyUFNoYXJlLnkpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXRyb2ZpdERhdGEuY2hhaW5Db2RlLCBleHBlY3RlZFVzZXJQU2hhcmUuY2hhaW5jb2RlKTtcbiAgfSk7XG5cbiAgaXQoJ2Rlcml2ZXMgQkFDS1VQIHJldHJvZml0IGRhdGEgbWF0Y2hpbmcga2V5Q29tYmluZSBwU2hhcmUgZmllbGRzJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJldHJvZml0RGF0YSA9IGF3YWl0IEVkZHNhTVBDdjJVdGlscy5nZXRLZXlEYXRhRm9yUmV0cm9maXQoXG4gICAgICBKU09OLnN0cmluZ2lmeShiYWNrdXBTaWduaW5nTWF0ZXJpYWwpLFxuICAgICAgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVBcbiAgICApO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJldHJvZml0RGF0YS5zX2lfMCwgZXhwZWN0ZWRCYWNrdXBQU2hhcmUudSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJldHJvZml0RGF0YS5leHBlY3RlZFBrLCBleHBlY3RlZEJhY2t1cFBTaGFyZS55KTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmV0cm9maXREYXRhLmNoYWluQ29kZSwgZXhwZWN0ZWRCYWNrdXBQU2hhcmUuY2hhaW5jb2RlKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyBpZiBVU0VSIG1hdGVyaWFsIGlzIG1pc3NpbmcgYmFja3VwWVNoYXJlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGtleU5vQmFja3VwWVNoYXJlID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgdVNoYXJlOiB1c2VyU2lnbmluZ01hdGVyaWFsLnVTaGFyZSxcbiAgICAgIGJpdGdvWVNoYXJlOiB1c2VyU2lnbmluZ01hdGVyaWFsLmJpdGdvWVNoYXJlLFxuICAgIH0pO1xuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT4gRWRkc2FNUEN2MlV0aWxzLmdldEtleURhdGFGb3JSZXRyb2ZpdChrZXlOb0JhY2t1cFlTaGFyZSwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKSxcbiAgICAgIC9Vc2VyIE1QQ3YxIGtleSBtYXRlcmlhbCBtaXNzaW5nIGJhY2t1cFlTaGFyZS9cbiAgICApO1xuICB9KTtcblxuICBpdCgndGhyb3dzIGlmIEJBQ0tVUCBtYXRlcmlhbCBpcyBtaXNzaW5nIHVzZXJZU2hhcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qga2V5Tm9Vc2VyWVNoYXJlID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgdVNoYXJlOiBiYWNrdXBTaWduaW5nTWF0ZXJpYWwudVNoYXJlLFxuICAgICAgYml0Z29ZU2hhcmU6IGJhY2t1cFNpZ25pbmdNYXRlcmlhbC5iaXRnb1lTaGFyZSxcbiAgICB9KTtcbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+IEVkZHNhTVBDdjJVdGlscy5nZXRLZXlEYXRhRm9yUmV0cm9maXQoa2V5Tm9Vc2VyWVNoYXJlLCBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCksXG4gICAgICAvQmFja3VwIE1QQ3YxIGtleSBtYXRlcmlhbCBtaXNzaW5nIHVzZXJZU2hhcmUvXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ1VTRVIgYW5kIEJBQ0tVUCBleHBlY3RlZFBrIGFuZCBjaGFpbkNvZGUgbWF0Y2ggd2hlbiBidWlsdCBmcm9tIHRoZSBzYW1lIHRocmVlIGtleVNoYXJlcycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB1c2VyUmV0cm9maXREYXRhID0gYXdhaXQgRWRkc2FNUEN2MlV0aWxzLmdldEtleURhdGFGb3JSZXRyb2ZpdChcbiAgICAgIEpTT04uc3RyaW5naWZ5KHVzZXJTaWduaW5nTWF0ZXJpYWwpLFxuICAgICAgTVBDdjJQYXJ0aWVzRW51bS5VU0VSXG4gICAgKTtcbiAgICBjb25zdCBiYWNrdXBSZXRyb2ZpdERhdGEgPSBhd2FpdCBFZGRzYU1QQ3YyVXRpbHMuZ2V0S2V5RGF0YUZvclJldHJvZml0KFxuICAgICAgSlNPTi5zdHJpbmdpZnkoYmFja3VwU2lnbmluZ01hdGVyaWFsKSxcbiAgICAgIE1QQ3YyUGFydGllc0VudW0uQkFDS1VQXG4gICAgKTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1c2VyUmV0cm9maXREYXRhLmV4cGVjdGVkUGssIGJhY2t1cFJldHJvZml0RGF0YS5leHBlY3RlZFBrKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXNlclJldHJvZml0RGF0YS5jaGFpbkNvZGUsIGJhY2t1cFJldHJvZml0RGF0YS5jaGFpbkNvZGUpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnRWRkc2FNUEN2MlV0aWxzLmdldFVzZXJBbmRCYWNrdXBTZXNzaW9uJywgKCkgPT4ge1xuICBsZXQgdXRpbHM6IEVkZHNhTVBDdjJVdGlscztcbiAgbGV0IHVzZXJTaWduaW5nTWF0ZXJpYWw6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBsZXQgYmFja3VwU2lnbmluZ01hdGVyaWFsOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcblxuICBiZWZvcmUoYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IE1QQyA9IGF3YWl0IGdldEluaXRpYWxpemVkTXBjSW5zdGFuY2UoKTtcbiAgICBjb25zdCB1c2VyID0gTVBDLmtleVNoYXJlKDEsIDIsIDMpO1xuICAgIGNvbnN0IGJhY2t1cCA9IE1QQy5rZXlTaGFyZSgyLCAyLCAzKTtcbiAgICBjb25zdCBiaXRnbyA9IE1QQy5rZXlTaGFyZSgzLCAyLCAzKTtcbiAgICB1c2VyU2lnbmluZ01hdGVyaWFsID0ge1xuICAgICAgdVNoYXJlOiB1c2VyLnVTaGFyZSxcbiAgICAgIGJpdGdvWVNoYXJlOiBiaXRnby55U2hhcmVzWzFdLFxuICAgICAgYmFja3VwWVNoYXJlOiBiYWNrdXAueVNoYXJlc1sxXSxcbiAgICB9O1xuICAgIGJhY2t1cFNpZ25pbmdNYXRlcmlhbCA9IHtcbiAgICAgIHVTaGFyZTogYmFja3VwLnVTaGFyZSxcbiAgICAgIGJpdGdvWVNoYXJlOiBiaXRnby55U2hhcmVzWzJdLFxuICAgICAgdXNlcllTaGFyZTogdXNlci55U2hhcmVzWzJdLFxuICAgIH07XG4gIH0pO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGNvbnN0IG1vY2tCaXRHbyA9IHt9IGFzIHVua25vd24gYXMgQml0R29CYXNlO1xuICAgIGNvbnN0IG1vY2tDb2luID0ge30gYXMgdW5rbm93biBhcyBJQmFzZUNvaW47XG4gICAgdXRpbHMgPSBuZXcgRWRkc2FNUEN2MlV0aWxzKG1vY2tCaXRHbywgbW9ja0NvaW4pO1xuICB9KTtcblxuICBhZnRlckVhY2goKCkgPT4ge1xuICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgfSk7XG5cbiAgaXQoJ3JldHVybnMgcGxhaW4gREtHIHNlc3Npb25zIHdoZW4gcmV0cm9maXQgaXMgdW5kZWZpbmVkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHsgdXNlckRrZywgYmFja3VwRGtnIH0gPSBhd2FpdCAodXRpbHMgYXMgYW55KS5nZXRVc2VyQW5kQmFja3VwU2Vzc2lvbih1bmRlZmluZWQpO1xuICAgIGFzc2VydC5vayh1c2VyRGtnLCAndXNlciBES0cgc2hvdWxkIGJlIGNyZWF0ZWQnKTtcbiAgICBhc3NlcnQub2soYmFja3VwRGtnLCAnYmFja3VwIERLRyBzaG91bGQgYmUgY3JlYXRlZCcpO1xuICB9KTtcblxuICBpdCgncmV0dXJucyByZXRyb2ZpdC1zZWVkZWQgREtHIHNlc3Npb25zIHdoZW4gcmV0cm9maXQgcGF5bG9hZCBpcyBzdXBwbGllZCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXRyb2ZpdCA9IHtcbiAgICAgIGRlY3J5cHRlZFVzZXJLZXk6IEpTT04uc3RyaW5naWZ5KHVzZXJTaWduaW5nTWF0ZXJpYWwpLFxuICAgICAgZGVjcnlwdGVkQmFja3VwS2V5OiBKU09OLnN0cmluZ2lmeShiYWNrdXBTaWduaW5nTWF0ZXJpYWwpLFxuICAgICAgd2FsbGV0SWQ6ICd3YWxsZXQtMTIzJyxcbiAgICB9O1xuICAgIGNvbnN0IHsgdXNlckRrZywgYmFja3VwRGtnIH0gPSBhd2FpdCAodXRpbHMgYXMgYW55KS5nZXRVc2VyQW5kQmFja3VwU2Vzc2lvbihyZXRyb2ZpdCk7XG4gICAgYXNzZXJ0Lm9rKHVzZXJEa2csICd1c2VyIERLRyBzaG91bGQgYmUgY3JlYXRlZCB3aXRoIHJldHJvZml0IGRhdGEnKTtcbiAgICBhc3NlcnQub2soYmFja3VwRGtnLCAnYmFja3VwIERLRyBzaG91bGQgYmUgY3JlYXRlZCB3aXRoIHJldHJvZml0IGRhdGEnKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ0VkZHNhTVBDdjJVdGlscy5jcmVhdGVLZXljaGFpbnMgd2l0aCByZXRyb2ZpdCB3aXJpbmcnLCAoKSA9PiB7XG4gIGxldCB1dGlsczogRWRkc2FNUEN2MlV0aWxzO1xuICBsZXQgdXNlclNpZ25pbmdNYXRlcmlhbDogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGxldCBiYWNrdXBTaWduaW5nTWF0ZXJpYWw6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBsZXQgYml0Z29HcGdQdWJsaWNLZXlBcm1vcmVkOiBzdHJpbmc7XG4gIGNvbnN0IGVudGVycHJpc2UgPSAnZW50ZXJwcmlzZS1pZCc7XG4gIGNvbnN0IHNlc3Npb25JZCA9ICdzZXNzaW9uLTAwMSc7XG4gIGNvbnN0IHdhbGxldElkID0gJ3dhbGxldC1yZXRyb2ZpdC0xMjMnO1xuXG4gIGJlZm9yZShhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgTVBDID0gYXdhaXQgZ2V0SW5pdGlhbGl6ZWRNcGNJbnN0YW5jZSgpO1xuICAgIGNvbnN0IHVzZXIgPSBNUEMua2V5U2hhcmUoMSwgMiwgMyk7XG4gICAgY29uc3QgYmFja3VwID0gTVBDLmtleVNoYXJlKDIsIDIsIDMpO1xuICAgIGNvbnN0IGJpdGdvID0gTVBDLmtleVNoYXJlKDMsIDIsIDMpO1xuICAgIHVzZXJTaWduaW5nTWF0ZXJpYWwgPSB7XG4gICAgICB1U2hhcmU6IHVzZXIudVNoYXJlLFxuICAgICAgYml0Z29ZU2hhcmU6IGJpdGdvLnlTaGFyZXNbMV0sXG4gICAgICBiYWNrdXBZU2hhcmU6IGJhY2t1cC55U2hhcmVzWzFdLFxuICAgIH07XG4gICAgYmFja3VwU2lnbmluZ01hdGVyaWFsID0ge1xuICAgICAgdVNoYXJlOiBiYWNrdXAudVNoYXJlLFxuICAgICAgYml0Z29ZU2hhcmU6IGJpdGdvLnlTaGFyZXNbMl0sXG4gICAgICB1c2VyWVNoYXJlOiB1c2VyLnlTaGFyZXNbMl0sXG4gICAgfTtcbiAgICAvLyBHZW5lcmF0ZSBhIHJlYWwgRWQyNTUxOSBHUEcga2V5IHRvIHN0YW5kIGluIGZvciB0aGUgQml0R28gR1BHIGtleVxuICAgIGNvbnN0IGJpdGdvR3BnS2V5UGFpciA9IGF3YWl0IGdlbmVyYXRlR1BHS2V5UGFpcignZWQyNTUxOScpO1xuICAgIGJpdGdvR3BnUHVibGljS2V5QXJtb3JlZCA9IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXk7XG4gIH0pO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGNvbnN0IG1vY2tCaXRHbyA9IHtcbiAgICAgIGdldEVudjogc2lub24uc3R1YigpLnJldHVybnMoJ2RldicpLFxuICAgICAgZW5jcnlwdDogc2lub24uc3R1YigpLnJlc29sdmVzKCdlbmNyeXB0ZWQnKSxcbiAgICB9IGFzIGFueTtcbiAgICBjb25zdCBtb2NrS2V5Y2hhaW5zID0ge1xuICAgICAgYWRkOiBzaW5vblxuICAgICAgICAuc3R1YigpXG4gICAgICAgIC5jYWxsc0Zha2UoKHBhcmFtczogYW55KSA9PlxuICAgICAgICAgIFByb21pc2UucmVzb2x2ZSh7IGlkOiBgJHtwYXJhbXMuc291cmNlfS1rZXktaWRgLCBjb21tb25LZXljaGFpbjogJ2EnLnJlcGVhdCgxMjgpLCBpc01QQ3YyOiB0cnVlIH0pXG4gICAgICAgICksXG4gICAgfTtcbiAgICBjb25zdCBtb2NrQ29pbiA9IHtcbiAgICAgIGtleWNoYWluczogc2lub24uc3R1YigpLnJldHVybnMobW9ja0tleWNoYWlucyksXG4gICAgfSBhcyBhbnk7XG5cbiAgICB1dGlscyA9IG5ldyBFZGRzYU1QQ3YyVXRpbHMobW9ja0JpdEdvLCBtb2NrQ29pbik7XG4gICAgc2lub24uc3R1Yih1dGlscywgJ2dldEJpdGdvR3BnUHVia2V5QmFzZWRPbkZlYXR1cmVGbGFncycgYXMgYW55KS5yZXNvbHZlcyh7IGVkZHNhTXBjdjJQdWJsaWNLZXk6IG51bGwgfSk7XG4gICAgLy8gVXNlIGEgcmVhbCBhcm1vcmVkIEdQRyBwdWJsaWMga2V5IHNvIHBncC5yZWFkS2V5KCkgc3VjY2VlZHMgaW5zaWRlIGNyZWF0ZUtleWNoYWluc1xuICAgICh1dGlscyBhcyBhbnkpLmJpdGdvRWRkc2FNcGN2MlB1YmxpY0dwZ0tleSA9IHsgYXJtb3I6ICgpID0+IGJpdGdvR3BnUHVibGljS2V5QXJtb3JlZCB9O1xuICAgIHNpbm9uLnN0dWIodXRpbHMgYXMgYW55LCAnYWRkQml0Z29LZXljaGFpbicpLnJlc29sdmVzKHsgaWQ6ICdiaXRnby1rZXktaWQnLCBjb21tb25LZXljaGFpbjogJ2EnLnJlcGVhdCgxMjgpIH0pO1xuICB9KTtcblxuICBhZnRlckVhY2goKCkgPT4ge1xuICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgfSk7XG5cbiAgaXQoJ3NwcmVhZHMgd2FsbGV0SWQgaW50byByb3VuZC0xIHBheWxvYWQgd2hlbiByZXRyb2ZpdCBpcyBwcm92aWRlZCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBjYXB0dXJlZFBheWxvYWRzOiBhbnlbXSA9IFtdO1xuICAgIHNpbm9uLnN0dWIodXRpbHMsICdzZW5kS2V5R2VuZXJhdGlvblJvdW5kMScpLmNhbGxzRmFrZShhc3luYyAoX2VudGVycHJpc2U6IHN0cmluZywgcGF5bG9hZDogYW55KSA9PiB7XG4gICAgICBjYXB0dXJlZFBheWxvYWRzLnB1c2gocGF5bG9hZCk7XG4gICAgICAvLyBSZXR1cm4gYSBiYWQgYml0Z29Nc2cxIHRvIHNob3J0LWNpcmN1aXQgdGhlIGNlcmVtb255IGFmdGVyIFIxIGNhcHR1cmVcbiAgICAgIHJldHVybiB7IHNlc3Npb25JZDogc2Vzc2lvbklkIGFzIGFueSwgYml0Z29Nc2cxOiB7IG1lc3NhZ2U6ICcnLCBzaWduYXR1cmU6ICcnIH0gYXMgYW55IH07XG4gICAgfSk7XG5cbiAgICBjb25zdCByZXRyb2ZpdCA9IHtcbiAgICAgIGRlY3J5cHRlZFVzZXJLZXk6IEpTT04uc3RyaW5naWZ5KHVzZXJTaWduaW5nTWF0ZXJpYWwpLFxuICAgICAgZGVjcnlwdGVkQmFja3VwS2V5OiBKU09OLnN0cmluZ2lmeShiYWNrdXBTaWduaW5nTWF0ZXJpYWwpLFxuICAgICAgd2FsbGV0SWQsXG4gICAgfTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT4gdXRpbHMuY3JlYXRlS2V5Y2hhaW5zKHsgcGFzc3BocmFzZTogJ3Rlc3QnLCBlbnRlcnByaXNlLCByZXRyb2ZpdCB9KSxcbiAgICAgICgpID0+IHRydWVcbiAgICApO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGNhcHR1cmVkUGF5bG9hZHMubGVuZ3RoLCAxLCAnc2VuZEtleUdlbmVyYXRpb25Sb3VuZDEgc2hvdWxkIGJlIGNhbGxlZCBvbmNlJyk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGNhcHR1cmVkUGF5bG9hZHNbMF0ud2FsbGV0SWQsIHdhbGxldElkLCAnd2FsbGV0SWQgbXVzdCBiZSBwcmVzZW50IGluIHJvdW5kLTEgcGF5bG9hZCcpO1xuICB9KTtcblxuICBpdCgnb21pdHMgd2FsbGV0SWQgZnJvbSByb3VuZC0xIHBheWxvYWQgd2hlbiByZXRyb2ZpdCBpcyBhYnNlbnQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgY2FwdHVyZWRQYXlsb2FkczogYW55W10gPSBbXTtcbiAgICBzaW5vbi5zdHViKHV0aWxzLCAnc2VuZEtleUdlbmVyYXRpb25Sb3VuZDEnKS5jYWxsc0Zha2UoYXN5bmMgKF9lbnRlcnByaXNlOiBzdHJpbmcsIHBheWxvYWQ6IGFueSkgPT4ge1xuICAgICAgY2FwdHVyZWRQYXlsb2Fkcy5wdXNoKHBheWxvYWQpO1xuICAgICAgcmV0dXJuIHsgc2Vzc2lvbklkOiBzZXNzaW9uSWQgYXMgYW55LCBiaXRnb01zZzE6IHsgbWVzc2FnZTogJycsIHNpZ25hdHVyZTogJycgfSBhcyBhbnkgfTtcbiAgICB9KTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT4gdXRpbHMuY3JlYXRlS2V5Y2hhaW5zKHsgcGFzc3BocmFzZTogJ3Rlc3QnLCBlbnRlcnByaXNlIH0pLFxuICAgICAgKCkgPT4gdHJ1ZVxuICAgICk7XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoY2FwdHVyZWRQYXlsb2Fkcy5sZW5ndGgsIDEsICdzZW5kS2V5R2VuZXJhdGlvblJvdW5kMSBzaG91bGQgYmUgY2FsbGVkIG9uY2UnKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoY2FwdHVyZWRQYXlsb2Fkc1swXS53YWxsZXRJZCwgdW5kZWZpbmVkLCAnd2FsbGV0SWQgbXVzdCBiZSBhYnNlbnQgd2hlbiBubyByZXRyb2ZpdCcpO1xuICB9KTtcbn0pO1xuIl19