@bitgo-beta/sdk-core 8.2.1-beta.202 → 8.2.1-beta.2021

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