@bitgo-beta/sdk-core 8.2.1-beta.86 → 8.2.1-beta.861

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 (491) hide show
  1. package/CHANGELOG.md +2725 -0
  2. package/dist/src/account-lib/baseCoin/baseTransaction.d.ts +0 -1
  3. package/dist/src/account-lib/baseCoin/baseTransaction.d.ts.map +1 -1
  4. package/dist/src/account-lib/baseCoin/baseTransactionBuilder.d.ts +3 -3
  5. package/dist/src/account-lib/baseCoin/baseTransactionBuilder.d.ts.map +1 -1
  6. package/dist/src/account-lib/baseCoin/baseTransactionBuilder.js +4 -3
  7. package/dist/src/account-lib/baseCoin/ed25519KeyPair.d.ts +1 -0
  8. package/dist/src/account-lib/baseCoin/ed25519KeyPair.d.ts.map +1 -1
  9. package/dist/src/account-lib/baseCoin/ed25519KeyPair.js +41 -29
  10. package/dist/src/account-lib/baseCoin/enum.d.ts +14 -2
  11. package/dist/src/account-lib/baseCoin/enum.d.ts.map +1 -1
  12. package/dist/src/account-lib/baseCoin/enum.js +28 -6
  13. package/dist/src/account-lib/baseCoin/errors.js +1 -1
  14. package/dist/src/account-lib/baseCoin/iface.d.ts +11 -35
  15. package/dist/src/account-lib/baseCoin/iface.d.ts.map +1 -1
  16. package/dist/src/account-lib/baseCoin/iface.js +4 -18
  17. package/dist/src/account-lib/baseCoin/index.d.ts +0 -1
  18. package/dist/src/account-lib/baseCoin/index.d.ts.map +1 -1
  19. package/dist/src/account-lib/baseCoin/index.js +7 -5
  20. package/dist/src/account-lib/baseCoin/secp256k1ExtendedKeyPair.d.ts +1 -2
  21. package/dist/src/account-lib/baseCoin/secp256k1ExtendedKeyPair.d.ts.map +1 -1
  22. package/dist/src/account-lib/baseCoin/secp256k1ExtendedKeyPair.js +38 -26
  23. package/dist/src/account-lib/index.js +23 -9
  24. package/dist/src/account-lib/mpc/curves/ed25519.d.ts +4 -18
  25. package/dist/src/account-lib/mpc/curves/ed25519.d.ts.map +1 -1
  26. package/dist/src/account-lib/mpc/curves/ed25519.js +6 -60
  27. package/dist/src/account-lib/mpc/index.d.ts +4 -4
  28. package/dist/src/account-lib/mpc/index.d.ts.map +1 -1
  29. package/dist/src/account-lib/mpc/index.js +11 -7
  30. package/dist/src/account-lib/mpc/shamir.d.ts +5 -37
  31. package/dist/src/account-lib/mpc/shamir.d.ts.map +1 -1
  32. package/dist/src/account-lib/mpc/shamir.js +6 -130
  33. package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.d.ts +38 -9
  34. package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.d.ts.map +1 -1
  35. package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.js +497 -349
  36. package/dist/src/account-lib/mpc/tss/ecdsa/index.js +23 -9
  37. package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.d.ts +2 -2
  38. package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.d.ts.map +1 -1
  39. package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.js +3 -3
  40. package/dist/src/account-lib/mpc/tss/ecdsa/types.d.ts +73 -52
  41. package/dist/src/account-lib/mpc/tss/ecdsa/types.d.ts.map +1 -1
  42. package/dist/src/account-lib/mpc/tss/ecdsa/types.js +1 -1
  43. package/dist/src/account-lib/mpc/tss/eddsa/eddsa.d.ts +1 -2
  44. package/dist/src/account-lib/mpc/tss/eddsa/eddsa.d.ts.map +1 -1
  45. package/dist/src/account-lib/mpc/tss/eddsa/eddsa.js +66 -69
  46. package/dist/src/account-lib/mpc/tss/eddsa/index.js +23 -9
  47. package/dist/src/account-lib/mpc/tss/eddsa/types.d.ts +1 -1
  48. package/dist/src/account-lib/mpc/tss/eddsa/types.d.ts.map +1 -1
  49. package/dist/src/account-lib/mpc/tss/eddsa/types.js +1 -1
  50. package/dist/src/account-lib/mpc/tss/index.js +23 -9
  51. package/dist/src/account-lib/mpc/util.d.ts +7 -1
  52. package/dist/src/account-lib/mpc/util.d.ts.map +1 -1
  53. package/dist/src/account-lib/mpc/util.js +19 -1
  54. package/dist/src/account-lib/staking/index.js +6 -2
  55. package/dist/src/account-lib/staking/utils.js +3 -3
  56. package/dist/src/account-lib/util/crypto.d.ts +8 -2
  57. package/dist/src/account-lib/util/crypto.d.ts.map +1 -1
  58. package/dist/src/account-lib/util/crypto.js +61 -31
  59. package/dist/src/account-lib/util/ed25519KeyDeriver.d.ts +2 -1
  60. package/dist/src/account-lib/util/ed25519KeyDeriver.d.ts.map +1 -1
  61. package/dist/src/account-lib/util/ed25519KeyDeriver.js +5 -3
  62. package/dist/src/api/bip32path.js +2 -3
  63. package/dist/src/api/index.js +6 -2
  64. package/dist/src/api/types.d.ts +8 -0
  65. package/dist/src/api/types.d.ts.map +1 -1
  66. package/dist/src/api/types.js +1 -1
  67. package/dist/src/bitgo/address-book/address-book.d.ts +61 -0
  68. package/dist/src/bitgo/address-book/address-book.d.ts.map +1 -0
  69. package/dist/src/bitgo/address-book/address-book.js +139 -0
  70. package/dist/src/bitgo/address-book/index.d.ts +3 -0
  71. package/dist/src/bitgo/address-book/index.d.ts.map +1 -0
  72. package/dist/src/bitgo/address-book/index.js +19 -0
  73. package/dist/src/bitgo/address-book/types.d.ts +170 -0
  74. package/dist/src/bitgo/address-book/types.d.ts.map +1 -0
  75. package/dist/src/bitgo/address-book/types.js +3 -0
  76. package/dist/src/bitgo/baseCoin/baseCoin.d.ts +77 -8
  77. package/dist/src/bitgo/baseCoin/baseCoin.d.ts.map +1 -1
  78. package/dist/src/bitgo/baseCoin/baseCoin.js +126 -15
  79. package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts +83 -19
  80. package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts.map +1 -1
  81. package/dist/src/bitgo/baseCoin/iBaseCoin.js +7 -3
  82. package/dist/src/bitgo/baseCoin/index.js +6 -2
  83. package/dist/src/bitgo/bip32util.d.ts +0 -1
  84. package/dist/src/bitgo/bip32util.d.ts.map +1 -1
  85. package/dist/src/bitgo/bip32util.js +25 -12
  86. package/dist/src/bitgo/bitcoin.d.ts +0 -1
  87. package/dist/src/bitgo/bitcoin.d.ts.map +1 -1
  88. package/dist/src/bitgo/bitcoin.js +26 -13
  89. package/dist/src/bitgo/bitgoBase.d.ts +6 -2
  90. package/dist/src/bitgo/bitgoBase.d.ts.map +1 -1
  91. package/dist/src/bitgo/bitgoBase.js +1 -1
  92. package/dist/src/bitgo/coinFactory.d.ts +1 -1
  93. package/dist/src/bitgo/coinFactory.d.ts.map +1 -1
  94. package/dist/src/bitgo/coinFactory.js +1 -1
  95. package/dist/src/bitgo/config.d.ts +62 -20
  96. package/dist/src/bitgo/config.d.ts.map +1 -1
  97. package/dist/src/bitgo/config.js +26 -15
  98. package/dist/src/bitgo/ecdh.d.ts +0 -1
  99. package/dist/src/bitgo/ecdh.d.ts.map +1 -1
  100. package/dist/src/bitgo/ecdh.js +26 -13
  101. package/dist/src/bitgo/enterprise/enterprise.d.ts +16 -14
  102. package/dist/src/bitgo/enterprise/enterprise.d.ts.map +1 -1
  103. package/dist/src/bitgo/enterprise/enterprise.js +64 -31
  104. package/dist/src/bitgo/enterprise/enterprises.d.ts +6 -0
  105. package/dist/src/bitgo/enterprise/enterprises.d.ts.map +1 -1
  106. package/dist/src/bitgo/enterprise/enterprises.js +48 -9
  107. package/dist/src/bitgo/enterprise/iEnterprise.d.ts +6 -7
  108. package/dist/src/bitgo/enterprise/iEnterprise.d.ts.map +1 -1
  109. package/dist/src/bitgo/enterprise/iEnterprise.js +1 -1
  110. package/dist/src/bitgo/enterprise/iEnterprises.d.ts +2 -0
  111. package/dist/src/bitgo/enterprise/iEnterprises.d.ts.map +1 -1
  112. package/dist/src/bitgo/enterprise/iEnterprises.js +1 -1
  113. package/dist/src/bitgo/enterprise/index.js +6 -2
  114. package/dist/src/bitgo/environments.d.ts +49 -5
  115. package/dist/src/bitgo/environments.d.ts.map +1 -1
  116. package/dist/src/bitgo/environments.js +80 -18
  117. package/dist/src/bitgo/errors.d.ts +6 -0
  118. package/dist/src/bitgo/errors.d.ts.map +1 -1
  119. package/dist/src/bitgo/errors.js +14 -2
  120. package/dist/src/bitgo/index.d.ts +1 -1
  121. package/dist/src/bitgo/index.d.ts.map +1 -1
  122. package/dist/src/bitgo/index.js +26 -11
  123. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.d.ts +3 -3
  124. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.d.ts.map +1 -1
  125. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.js +1 -1
  126. package/dist/src/bitgo/inscriptionBuilder/index.js +6 -2
  127. package/dist/src/bitgo/internal/index.js +6 -2
  128. package/dist/src/bitgo/internal/internal.js +5 -6
  129. package/dist/src/bitgo/internal/keycard.js +6 -7
  130. package/dist/src/bitgo/keychain/decryptKeychain.d.ts +13 -0
  131. package/dist/src/bitgo/keychain/decryptKeychain.d.ts.map +1 -0
  132. package/dist/src/bitgo/keychain/decryptKeychain.js +35 -0
  133. package/dist/src/bitgo/keychain/iKeychains.d.ts +63 -7
  134. package/dist/src/bitgo/keychain/iKeychains.d.ts.map +1 -1
  135. package/dist/src/bitgo/keychain/iKeychains.js +2 -2
  136. package/dist/src/bitgo/keychain/index.d.ts +1 -0
  137. package/dist/src/bitgo/keychain/index.d.ts.map +1 -1
  138. package/dist/src/bitgo/keychain/index.js +7 -2
  139. package/dist/src/bitgo/keychain/keychains.d.ts +13 -3
  140. package/dist/src/bitgo/keychain/keychains.d.ts.map +1 -1
  141. package/dist/src/bitgo/keychain/keychains.js +128 -37
  142. package/dist/src/bitgo/keychain/ovcJsonCodec.d.ts +3 -3
  143. package/dist/src/bitgo/keychain/ovcJsonCodec.d.ts.map +1 -1
  144. package/dist/src/bitgo/keychain/ovcJsonCodec.js +23 -9
  145. package/dist/src/bitgo/legacyBitcoin.d.ts +0 -1
  146. package/dist/src/bitgo/legacyBitcoin.d.ts.map +1 -1
  147. package/dist/src/bitgo/legacyBitcoin.js +27 -13
  148. package/dist/src/bitgo/lightning/lightningWalletUtil.d.ts +7 -0
  149. package/dist/src/bitgo/lightning/lightningWalletUtil.d.ts.map +1 -0
  150. package/dist/src/bitgo/lightning/lightningWalletUtil.js +25 -0
  151. package/dist/src/bitgo/market/iMarkets.d.ts +2 -2
  152. package/dist/src/bitgo/market/iMarkets.d.ts.map +1 -1
  153. package/dist/src/bitgo/market/index.js +6 -2
  154. package/dist/src/bitgo/market/markets.js +23 -9
  155. package/dist/src/bitgo/pendingApproval/iPendingApproval.d.ts +2 -0
  156. package/dist/src/bitgo/pendingApproval/iPendingApproval.d.ts.map +1 -1
  157. package/dist/src/bitgo/pendingApproval/iPendingApproval.js +4 -4
  158. package/dist/src/bitgo/pendingApproval/index.js +6 -2
  159. package/dist/src/bitgo/pendingApproval/pendingApproval.d.ts +20 -8
  160. package/dist/src/bitgo/pendingApproval/pendingApproval.d.ts.map +1 -1
  161. package/dist/src/bitgo/pendingApproval/pendingApproval.js +216 -107
  162. package/dist/src/bitgo/pendingApproval/pendingApprovals.js +23 -9
  163. package/dist/src/bitgo/recovery/index.js +6 -2
  164. package/dist/src/bitgo/recovery/initiate.d.ts +8 -2
  165. package/dist/src/bitgo/recovery/initiate.d.ts.map +1 -1
  166. package/dist/src/bitgo/recovery/initiate.js +7 -8
  167. package/dist/src/bitgo/staking/goStakingWallet.d.ts +36 -0
  168. package/dist/src/bitgo/staking/goStakingWallet.d.ts.map +1 -0
  169. package/dist/src/bitgo/staking/goStakingWallet.js +92 -0
  170. package/dist/src/bitgo/staking/iGoStakingWallet.d.ts +44 -0
  171. package/dist/src/bitgo/staking/iGoStakingWallet.d.ts.map +1 -0
  172. package/dist/src/bitgo/staking/iGoStakingWallet.js +3 -0
  173. package/dist/src/bitgo/staking/iStakingWallet.d.ts +120 -4
  174. package/dist/src/bitgo/staking/iStakingWallet.d.ts.map +1 -1
  175. package/dist/src/bitgo/staking/iStakingWallet.js +2 -2
  176. package/dist/src/bitgo/staking/index.d.ts +2 -0
  177. package/dist/src/bitgo/staking/index.d.ts.map +1 -1
  178. package/dist/src/bitgo/staking/index.js +8 -2
  179. package/dist/src/bitgo/staking/stakingWallet.d.ts +13 -2
  180. package/dist/src/bitgo/staking/stakingWallet.d.ts.map +1 -1
  181. package/dist/src/bitgo/staking/stakingWallet.js +45 -4
  182. package/dist/src/bitgo/trading/iTradingAccount.d.ts +2 -32
  183. package/dist/src/bitgo/trading/iTradingAccount.d.ts.map +1 -1
  184. package/dist/src/bitgo/trading/iTradingAccount.js +1 -1
  185. package/dist/src/bitgo/trading/index.d.ts +1 -15
  186. package/dist/src/bitgo/trading/index.d.ts.map +1 -1
  187. package/dist/src/bitgo/trading/index.js +7 -17
  188. package/dist/src/bitgo/trading/network/decrypt-aes-gcm.d.ts +8 -0
  189. package/dist/src/bitgo/trading/network/decrypt-aes-gcm.d.ts.map +1 -0
  190. package/dist/src/bitgo/trading/network/decrypt-aes-gcm.js +31 -0
  191. package/dist/src/bitgo/trading/network/decrypt-rsa.d.ts +8 -0
  192. package/dist/src/bitgo/trading/network/decrypt-rsa.d.ts.map +1 -0
  193. package/dist/src/bitgo/trading/network/decrypt-rsa.js +23 -0
  194. package/dist/src/bitgo/trading/network/decrypt.d.ts +14 -0
  195. package/dist/src/bitgo/trading/network/decrypt.d.ts.map +1 -0
  196. package/dist/src/bitgo/trading/network/decrypt.js +23 -0
  197. package/dist/src/bitgo/trading/network/encrypt-aes-gcm.d.ts +8 -0
  198. package/dist/src/bitgo/trading/network/encrypt-aes-gcm.d.ts.map +1 -0
  199. package/dist/src/bitgo/trading/network/encrypt-aes-gcm.js +25 -0
  200. package/dist/src/bitgo/trading/network/encrypt-rsa-browser.d.ts +8 -0
  201. package/dist/src/bitgo/trading/network/encrypt-rsa-browser.d.ts.map +1 -0
  202. package/dist/src/bitgo/trading/network/encrypt-rsa-browser.js +65 -0
  203. package/dist/src/bitgo/trading/network/encrypt-rsa.d.ts +8 -0
  204. package/dist/src/bitgo/trading/network/encrypt-rsa.d.ts.map +1 -0
  205. package/dist/src/bitgo/trading/network/encrypt-rsa.js +23 -0
  206. package/dist/src/bitgo/trading/network/encrypt.d.ts +37 -0
  207. package/dist/src/bitgo/trading/network/encrypt.d.ts.map +1 -0
  208. package/dist/src/bitgo/trading/network/encrypt.js +58 -0
  209. package/dist/src/bitgo/trading/network/index.d.ts +5 -0
  210. package/dist/src/bitgo/trading/network/index.d.ts.map +1 -0
  211. package/dist/src/bitgo/trading/network/index.js +21 -0
  212. package/dist/src/bitgo/trading/network/network.d.ts +36 -0
  213. package/dist/src/bitgo/trading/network/network.d.ts.map +1 -0
  214. package/dist/src/bitgo/trading/network/network.js +101 -0
  215. package/dist/src/bitgo/trading/network/types.d.ts +277 -0
  216. package/dist/src/bitgo/trading/network/types.d.ts.map +1 -0
  217. package/dist/src/bitgo/trading/network/types.js +3 -0
  218. package/dist/src/bitgo/trading/network/utils.d.ts +20 -0
  219. package/dist/src/bitgo/trading/network/utils.d.ts.map +1 -0
  220. package/dist/src/bitgo/trading/network/utils.js +54 -0
  221. package/dist/src/bitgo/trading/tradingAccount.d.ts +11 -35
  222. package/dist/src/bitgo/trading/tradingAccount.d.ts.map +1 -1
  223. package/dist/src/bitgo/trading/tradingAccount.js +9 -96
  224. package/dist/src/bitgo/tss/bitgoPubKeys.d.ts +27 -0
  225. package/dist/src/bitgo/tss/bitgoPubKeys.d.ts.map +1 -0
  226. package/dist/src/bitgo/tss/bitgoPubKeys.js +61 -0
  227. package/dist/src/bitgo/tss/common.d.ts +37 -5
  228. package/dist/src/bitgo/tss/common.d.ts.map +1 -1
  229. package/dist/src/bitgo/tss/common.js +103 -17
  230. package/dist/src/bitgo/tss/ecdsa/ecdsa.d.ts +6 -4
  231. package/dist/src/bitgo/tss/ecdsa/ecdsa.d.ts.map +1 -1
  232. package/dist/src/bitgo/tss/ecdsa/ecdsa.js +78 -66
  233. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.d.ts +15 -0
  234. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
  235. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.js +162 -0
  236. package/dist/src/bitgo/tss/ecdsa/index.d.ts +1 -0
  237. package/dist/src/bitgo/tss/ecdsa/index.d.ts.map +1 -1
  238. package/dist/src/bitgo/tss/ecdsa/index.js +25 -10
  239. package/dist/src/bitgo/tss/ecdsa/types.d.ts +27 -27
  240. package/dist/src/bitgo/tss/ecdsa/types.d.ts.map +1 -1
  241. package/dist/src/bitgo/tss/ecdsa/types.js +3 -3
  242. package/dist/src/bitgo/tss/eddsa/eddsa.d.ts +11 -8
  243. package/dist/src/bitgo/tss/eddsa/eddsa.d.ts.map +1 -1
  244. package/dist/src/bitgo/tss/eddsa/eddsa.js +38 -41
  245. package/dist/src/bitgo/tss/eddsa/index.js +23 -9
  246. package/dist/src/bitgo/tss/eddsa/types.d.ts +4 -4
  247. package/dist/src/bitgo/tss/eddsa/types.d.ts.map +1 -1
  248. package/dist/src/bitgo/tss/index.d.ts +3 -2
  249. package/dist/src/bitgo/tss/index.d.ts.map +1 -1
  250. package/dist/src/bitgo/tss/index.js +26 -10
  251. package/dist/src/bitgo/tss/types.d.ts +3 -3
  252. package/dist/src/bitgo/tss/types.d.ts.map +1 -1
  253. package/dist/src/bitgo/tss/types.js +2 -2
  254. package/dist/src/bitgo/types.d.ts +3 -3
  255. package/dist/src/bitgo/types.d.ts.map +1 -1
  256. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.d.ts +11 -0
  257. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.d.ts.map +1 -1
  258. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.js +66 -10
  259. package/dist/src/bitgo/utils/codecProps.d.ts +7 -0
  260. package/dist/src/bitgo/utils/codecProps.d.ts.map +1 -0
  261. package/dist/src/bitgo/utils/codecProps.js +54 -0
  262. package/dist/src/bitgo/utils/decode.d.ts.map +1 -1
  263. package/dist/src/bitgo/utils/decode.js +30 -16
  264. package/dist/src/bitgo/utils/index.d.ts +2 -2
  265. package/dist/src/bitgo/utils/index.d.ts.map +1 -1
  266. package/dist/src/bitgo/utils/index.js +25 -11
  267. package/dist/src/bitgo/utils/mpcUtils.d.ts +2 -3
  268. package/dist/src/bitgo/utils/mpcUtils.d.ts.map +1 -1
  269. package/dist/src/bitgo/utils/mpcUtils.js +34 -12
  270. package/dist/src/bitgo/utils/notEmpty.d.ts +2 -0
  271. package/dist/src/bitgo/utils/notEmpty.d.ts.map +1 -0
  272. package/dist/src/bitgo/utils/notEmpty.js +7 -0
  273. package/dist/src/bitgo/utils/opengpgUtils.d.ts +11 -9
  274. package/dist/src/bitgo/utils/opengpgUtils.d.ts.map +1 -1
  275. package/dist/src/bitgo/utils/opengpgUtils.js +74 -73
  276. package/dist/src/bitgo/utils/postWithCodec.d.ts +18 -0
  277. package/dist/src/bitgo/utils/postWithCodec.d.ts.map +1 -0
  278. package/dist/src/bitgo/utils/postWithCodec.js +25 -0
  279. package/dist/src/bitgo/utils/promise-utils.d.ts +1 -1
  280. package/dist/src/bitgo/utils/promise-utils.d.ts.map +1 -1
  281. package/dist/src/bitgo/utils/promise-utils.js +2 -3
  282. package/dist/src/bitgo/utils/triple.d.ts +1 -1
  283. package/dist/src/bitgo/utils/triple.d.ts.map +1 -1
  284. package/dist/src/bitgo/utils/triple.js +2 -3
  285. package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts +39 -14
  286. package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts.map +1 -1
  287. package/dist/src/bitgo/utils/tss/baseTSSUtils.js +145 -45
  288. package/dist/src/bitgo/utils/tss/baseTypes.d.ts +202 -34
  289. package/dist/src/bitgo/utils/tss/baseTypes.d.ts.map +1 -1
  290. package/dist/src/bitgo/utils/tss/baseTypes.js +22 -20
  291. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.d.ts +23 -0
  292. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.d.ts.map +1 -0
  293. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.js +157 -0
  294. package/dist/src/bitgo/utils/tss/ecdsa/base.d.ts +28 -0
  295. package/dist/src/bitgo/utils/tss/ecdsa/base.d.ts.map +1 -0
  296. package/dist/src/bitgo/utils/tss/ecdsa/base.js +53 -0
  297. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.d.ts +20 -52
  298. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.d.ts.map +1 -1
  299. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.js +131 -280
  300. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts +199 -0
  301. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
  302. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +936 -0
  303. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.d.ts +8 -0
  304. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.d.ts.map +1 -0
  305. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.js +13 -0
  306. package/dist/src/bitgo/utils/tss/ecdsa/index.d.ts +4 -0
  307. package/dist/src/bitgo/utils/tss/ecdsa/index.d.ts.map +1 -1
  308. package/dist/src/bitgo/utils/tss/ecdsa/index.js +10 -2
  309. package/dist/src/bitgo/utils/tss/ecdsa/types.d.ts +15 -9
  310. package/dist/src/bitgo/utils/tss/ecdsa/types.d.ts.map +1 -1
  311. package/dist/src/bitgo/utils/tss/ecdsa/types.js +1 -1
  312. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.d.ts +107 -0
  313. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.d.ts.map +1 -0
  314. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.js +55 -0
  315. package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts +5 -3
  316. package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts.map +1 -1
  317. package/dist/src/bitgo/utils/tss/eddsa/eddsa.js +75 -58
  318. package/dist/src/bitgo/utils/tss/eddsa/index.js +23 -9
  319. package/dist/src/bitgo/utils/tss/eddsa/types.d.ts +7 -7
  320. package/dist/src/bitgo/utils/tss/eddsa/types.d.ts.map +1 -1
  321. package/dist/src/bitgo/utils/tss/index.js +23 -9
  322. package/dist/src/bitgo/utils/txRequest.d.ts +10 -0
  323. package/dist/src/bitgo/utils/txRequest.d.ts.map +1 -0
  324. package/dist/src/bitgo/utils/txRequest.js +47 -0
  325. package/dist/src/bitgo/utils/util.js +24 -10
  326. package/dist/src/bitgo/utils/wallet.d.ts +7 -0
  327. package/dist/src/bitgo/utils/wallet.d.ts.map +1 -0
  328. package/dist/src/bitgo/utils/wallet.js +48 -0
  329. package/dist/src/bitgo/wallet/BuildParams.d.ts +119 -0
  330. package/dist/src/bitgo/wallet/BuildParams.d.ts.map +1 -0
  331. package/dist/src/bitgo/wallet/BuildParams.js +140 -0
  332. package/dist/src/bitgo/wallet/iWallet.d.ts +199 -19
  333. package/dist/src/bitgo/wallet/iWallet.d.ts.map +1 -1
  334. package/dist/src/bitgo/wallet/iWallet.js +1 -1
  335. package/dist/src/bitgo/wallet/iWallets.d.ts +91 -16
  336. package/dist/src/bitgo/wallet/iWallets.d.ts.map +1 -1
  337. package/dist/src/bitgo/wallet/iWallets.js +43 -3
  338. package/dist/src/bitgo/wallet/index.js +6 -2
  339. package/dist/src/bitgo/wallet/wallet.d.ts +192 -25
  340. package/dist/src/bitgo/wallet/wallet.d.ts.map +1 -1
  341. package/dist/src/bitgo/wallet/wallet.js +910 -348
  342. package/dist/src/bitgo/wallet/wallets.d.ts +96 -9
  343. package/dist/src/bitgo/wallet/wallets.d.ts.map +1 -1
  344. package/dist/src/bitgo/wallet/wallets.js +816 -193
  345. package/dist/src/bitgo/webhook/index.js +6 -2
  346. package/dist/src/bitgo/webhook/webhooks.js +23 -9
  347. package/dist/src/coins/fiataed.d.ts +30 -0
  348. package/dist/src/coins/fiataed.d.ts.map +1 -0
  349. package/dist/src/coins/fiataed.js +57 -0
  350. package/dist/src/coins/fiateur.d.ts +0 -1
  351. package/dist/src/coins/fiateur.d.ts.map +1 -1
  352. package/dist/src/coins/fiatgbp.d.ts +0 -1
  353. package/dist/src/coins/fiatgbp.d.ts.map +1 -1
  354. package/dist/src/coins/fiatsgd.d.ts +30 -0
  355. package/dist/src/coins/fiatsgd.d.ts.map +1 -0
  356. package/dist/src/coins/fiatsgd.js +57 -0
  357. package/dist/src/coins/fiatusd.d.ts +0 -1
  358. package/dist/src/coins/fiatusd.d.ts.map +1 -1
  359. package/dist/src/coins/index.d.ts +4 -0
  360. package/dist/src/coins/index.d.ts.map +1 -1
  361. package/dist/src/coins/index.js +10 -2
  362. package/dist/src/coins/ofc.d.ts +0 -1
  363. package/dist/src/coins/ofc.d.ts.map +1 -1
  364. package/dist/src/coins/ofc.js +2 -2
  365. package/dist/src/coins/ofcToken.js +2 -2
  366. package/dist/src/coins/susd.d.ts +0 -1
  367. package/dist/src/coins/susd.d.ts.map +1 -1
  368. package/dist/src/coins/tfiataed.d.ts +11 -0
  369. package/dist/src/coins/tfiataed.d.ts.map +1 -0
  370. package/dist/src/coins/tfiataed.js +17 -0
  371. package/dist/src/coins/tfiatsgd.d.ts +11 -0
  372. package/dist/src/coins/tfiatsgd.d.ts.map +1 -0
  373. package/dist/src/coins/tfiatsgd.js +17 -0
  374. package/dist/src/common.js +27 -13
  375. package/dist/src/index.d.ts +2 -1
  376. package/dist/src/index.d.ts.map +1 -1
  377. package/dist/src/index.js +26 -11
  378. package/dist/src/units.js +5 -6
  379. package/dist/test/node.utils.d.ts +2 -0
  380. package/dist/test/node.utils.d.ts.map +1 -0
  381. package/dist/test/node.utils.js +5 -0
  382. package/dist/test/unit/account-lib/mpc/tss/ecdsa/ecdsa.d.ts +2 -0
  383. package/dist/test/unit/account-lib/mpc/tss/ecdsa/ecdsa.d.ts.map +1 -0
  384. package/dist/test/unit/account-lib/mpc/tss/ecdsa/ecdsa.js +233 -0
  385. package/dist/test/unit/account-lib/mpc/tss/ecdsa/fixtures.d.ts +3 -0
  386. package/dist/test/unit/account-lib/mpc/tss/ecdsa/fixtures.d.ts.map +1 -0
  387. package/dist/test/unit/account-lib/mpc/tss/ecdsa/fixtures.js +24 -0
  388. package/dist/test/unit/bitgo/trading/network/encrypt.d.ts +2 -0
  389. package/dist/test/unit/bitgo/trading/network/encrypt.d.ts.map +1 -0
  390. package/dist/test/unit/bitgo/trading/network/encrypt.js +71 -0
  391. package/dist/test/unit/bitgo/utils/abstractUtxoCoinUtil.d.ts +2 -0
  392. package/dist/test/unit/bitgo/utils/abstractUtxoCoinUtil.d.ts.map +1 -0
  393. package/dist/test/unit/bitgo/utils/abstractUtxoCoinUtil.js +45 -0
  394. package/dist/test/unit/bitgo/utils/notEmpty.d.ts +2 -0
  395. package/dist/test/unit/bitgo/utils/notEmpty.d.ts.map +1 -0
  396. package/dist/test/unit/bitgo/utils/notEmpty.js +15 -0
  397. package/dist/test/unit/bitgo/utils/postWithCodec.d.ts +2 -0
  398. package/dist/test/unit/bitgo/utils/postWithCodec.d.ts.map +1 -0
  399. package/dist/test/unit/bitgo/utils/postWithCodec.js +73 -0
  400. package/dist/test/unit/bitgo/utils/txRequest.d.ts +2 -0
  401. package/dist/test/unit/bitgo/utils/txRequest.d.ts.map +1 -0
  402. package/dist/test/unit/bitgo/utils/txRequest.js +105 -0
  403. package/dist/test/unit/bitgo/wallet/BuildParams.d.ts +2 -0
  404. package/dist/test/unit/bitgo/wallet/BuildParams.d.ts.map +1 -0
  405. package/dist/test/unit/bitgo/wallet/BuildParams.js +68 -0
  406. package/dist/test/unit/bitgo/wallet/SendTransactionRequest.d.ts +2 -0
  407. package/dist/test/unit/bitgo/wallet/SendTransactionRequest.d.ts.map +1 -0
  408. package/dist/test/unit/bitgo/wallet/SendTransactionRequest.js +58 -0
  409. package/dist/test/unit/units.d.ts +2 -0
  410. package/dist/test/unit/units.d.ts.map +1 -0
  411. package/dist/test/unit/units.js +98 -0
  412. package/dist/tsconfig.tsbuildinfo +1 -1
  413. package/package.json +25 -22
  414. package/dist/src/account-lib/baseCoin/blsKeyPair.d.ts +0 -77
  415. package/dist/src/account-lib/baseCoin/blsKeyPair.d.ts.map +0 -1
  416. package/dist/src/account-lib/baseCoin/blsKeyPair.js +0 -209
  417. package/dist/src/account-lib/mpc/hdTree.d.ts +0 -31
  418. package/dist/src/account-lib/mpc/hdTree.d.ts.map +0 -1
  419. package/dist/src/account-lib/mpc/hdTree.js +0 -141
  420. package/dist/src/account-lib/mpc/types.d.ts +0 -5
  421. package/dist/src/account-lib/mpc/types.d.ts.map +0 -1
  422. package/dist/src/account-lib/mpc/types.js +0 -3
  423. package/dist/src/bitgo/lightning/iLightning.d.ts +0 -186
  424. package/dist/src/bitgo/lightning/iLightning.d.ts.map +0 -1
  425. package/dist/src/bitgo/lightning/iLightning.js +0 -106
  426. package/dist/src/bitgo/lightning/index.d.ts +0 -5
  427. package/dist/src/bitgo/lightning/index.d.ts.map +0 -1
  428. package/dist/src/bitgo/lightning/index.js +0 -17
  429. package/dist/src/bitgo/lightning/lightning.d.ts +0 -25
  430. package/dist/src/bitgo/lightning/lightning.d.ts.map +0 -1
  431. package/dist/src/bitgo/lightning/lightning.js +0 -111
  432. package/dist/src/bitgo/lightning/lightningUtils.d.ts +0 -46
  433. package/dist/src/bitgo/lightning/lightningUtils.d.ts.map +0 -1
  434. package/dist/src/bitgo/lightning/lightningUtils.js +0 -133
  435. package/dist/src/bitgo/lightning/lnurlCodec.d.ts +0 -3
  436. package/dist/src/bitgo/lightning/lnurlCodec.d.ts.map +0 -1
  437. package/dist/src/bitgo/lightning/lnurlCodec.js +0 -28
  438. package/dist/src/bitgo/trading/affirmation.d.ts +0 -35
  439. package/dist/src/bitgo/trading/affirmation.d.ts.map +0 -1
  440. package/dist/src/bitgo/trading/affirmation.js +0 -53
  441. package/dist/src/bitgo/trading/affirmations.d.ts +0 -23
  442. package/dist/src/bitgo/trading/affirmations.d.ts.map +0 -1
  443. package/dist/src/bitgo/trading/affirmations.js +0 -45
  444. package/dist/src/bitgo/trading/iAffirmation.d.ts +0 -15
  445. package/dist/src/bitgo/trading/iAffirmation.d.ts.map +0 -1
  446. package/dist/src/bitgo/trading/iAffirmation.js +0 -13
  447. package/dist/src/bitgo/trading/iAffirmations.d.ts +0 -10
  448. package/dist/src/bitgo/trading/iAffirmations.d.ts.map +0 -1
  449. package/dist/src/bitgo/trading/iAffirmations.js +0 -3
  450. package/dist/src/bitgo/trading/iSettlement.d.ts +0 -25
  451. package/dist/src/bitgo/trading/iSettlement.d.ts.map +0 -1
  452. package/dist/src/bitgo/trading/iSettlement.js +0 -17
  453. package/dist/src/bitgo/trading/iSettlements.d.ts +0 -19
  454. package/dist/src/bitgo/trading/iSettlements.d.ts.map +0 -1
  455. package/dist/src/bitgo/trading/iSettlements.js +0 -3
  456. package/dist/src/bitgo/trading/iTradingPartner.d.ts +0 -14
  457. package/dist/src/bitgo/trading/iTradingPartner.d.ts.map +0 -1
  458. package/dist/src/bitgo/trading/iTradingPartner.js +0 -17
  459. package/dist/src/bitgo/trading/iTradingPartners.d.ts +0 -15
  460. package/dist/src/bitgo/trading/iTradingPartners.d.ts.map +0 -1
  461. package/dist/src/bitgo/trading/iTradingPartners.js +0 -9
  462. package/dist/src/bitgo/trading/lock.d.ts +0 -16
  463. package/dist/src/bitgo/trading/lock.d.ts.map +0 -1
  464. package/dist/src/bitgo/trading/lock.js +0 -12
  465. package/dist/src/bitgo/trading/payload.d.ts +0 -22
  466. package/dist/src/bitgo/trading/payload.d.ts.map +0 -1
  467. package/dist/src/bitgo/trading/payload.js +0 -3
  468. package/dist/src/bitgo/trading/settlement.d.ts +0 -16
  469. package/dist/src/bitgo/trading/settlement.d.ts.map +0 -1
  470. package/dist/src/bitgo/trading/settlement.js +0 -21
  471. package/dist/src/bitgo/trading/settlements.d.ts +0 -32
  472. package/dist/src/bitgo/trading/settlements.d.ts.map +0 -1
  473. package/dist/src/bitgo/trading/settlements.js +0 -61
  474. package/dist/src/bitgo/trading/trade.d.ts +0 -29
  475. package/dist/src/bitgo/trading/trade.d.ts.map +0 -1
  476. package/dist/src/bitgo/trading/trade.js +0 -11
  477. package/dist/src/bitgo/trading/tradingPartner.d.ts +0 -26
  478. package/dist/src/bitgo/trading/tradingPartner.d.ts.map +0 -1
  479. package/dist/src/bitgo/trading/tradingPartner.js +0 -31
  480. package/dist/src/bitgo/trading/tradingPartners.d.ts +0 -24
  481. package/dist/src/bitgo/trading/tradingPartners.d.ts.map +0 -1
  482. package/dist/src/bitgo/trading/tradingPartners.js +0 -32
  483. package/dist/src/bitgo/utils/blsUtils.d.ts +0 -52
  484. package/dist/src/bitgo/utils/blsUtils.d.ts.map +0 -1
  485. package/dist/src/bitgo/utils/blsUtils.js +0 -237
  486. package/dist/src/bitgo/utils/iBlsUtils.d.ts +0 -14
  487. package/dist/src/bitgo/utils/iBlsUtils.d.ts.map +0 -1
  488. package/dist/src/bitgo/utils/iBlsUtils.js +0 -3
  489. package/dist/src/openssl/index.d.ts +0 -5
  490. package/dist/src/openssl/index.d.ts.map +0 -1
  491. package/dist/src/openssl/index.js +0 -9
@@ -0,0 +1,936 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.EcdsaMPCv2Utils = void 0;
40
+ exports.isGG18SigningMaterial = isGG18SigningMaterial;
41
+ exports.getMpcV2RecoveryKeyShares = getMpcV2RecoveryKeyShares;
42
+ exports.signRecoveryMpcV2 = signRecoveryMpcV2;
43
+ const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
44
+ const sjcl = __importStar(require("@bitgo-beta/sjcl"));
45
+ const assert_1 = __importDefault(require("assert"));
46
+ const buffer_1 = require("buffer");
47
+ const io_ts_types_1 = require("io-ts-types");
48
+ const keccak_1 = __importDefault(require("keccak"));
49
+ const pgp = __importStar(require("openpgp"));
50
+ const public_types_1 = require("@bitgo/public-types");
51
+ const account_lib_1 = require("../../../../account-lib");
52
+ const tss_1 = require("../../../tss");
53
+ const common_1 = require("../../../tss/common");
54
+ const typesMPCv2_1 = require("./typesMPCv2");
55
+ const ecdsaMPCv2_1 = require("../../../tss/ecdsa/ecdsaMPCv2");
56
+ const opengpgUtils_1 = require("../../opengpgUtils");
57
+ const baseTypes_1 = require("../baseTypes");
58
+ const base_1 = require("./base");
59
+ const ecdsaMPCv2KeyGenSender_1 = require("./ecdsaMPCv2KeyGenSender");
60
+ const bitgoPubKeys_1 = require("../../../tss/bitgoPubKeys");
61
+ class EcdsaMPCv2Utils extends base_1.BaseEcdsaUtils {
62
+ /** @inheritdoc */
63
+ async createKeychains(params) {
64
+ const { userSession, backupSession } = this.getUserAndBackupSession(2, 3, params.retrofit);
65
+ const userGpgKey = await (0, opengpgUtils_1.generateGPGKeyPair)('secp256k1');
66
+ const backupGpgKey = await (0, opengpgUtils_1.generateGPGKeyPair)('secp256k1');
67
+ // Get the BitGo public key based on user/enterprise feature flags
68
+ // If it doesn't work, use the default public key from the constants
69
+ const bitgoPublicGpgKey = ((await this.getBitgoGpgPubkeyBasedOnFeatureFlags(params.enterprise, true)) ?? this.bitgoMPCv2PublicGpgKey).armor();
70
+ if ((0, bitgoPubKeys_1.envRequiresBitgoPubGpgKeyConfig)(this.bitgo.getEnv())) {
71
+ // Ensure the public key is one of the expected BitGo public keys when in test or prod.
72
+ (0, assert_1.default)((0, bitgoPubKeys_1.isBitgoMpcPubKey)(bitgoPublicGpgKey, 'mpcv2'), 'Invalid BitGo GPG public key');
73
+ }
74
+ const userGpgPrvKey = {
75
+ partyId: typesMPCv2_1.MPCv2PartiesEnum.USER,
76
+ gpgKey: userGpgKey.privateKey,
77
+ };
78
+ const backupGpgPrvKey = {
79
+ partyId: typesMPCv2_1.MPCv2PartiesEnum.BACKUP,
80
+ gpgKey: backupGpgKey.privateKey,
81
+ };
82
+ const bitgoGpgPubKey = {
83
+ partyId: typesMPCv2_1.MPCv2PartiesEnum.BITGO,
84
+ gpgKey: bitgoPublicGpgKey,
85
+ };
86
+ // #region round 1
87
+ const userRound1BroadcastMsg = await userSession.initDkg();
88
+ const backupRound1BroadcastMsg = await backupSession.initDkg();
89
+ const round1SerializedMessages = sdk_lib_mpc_1.DklsTypes.serializeMessages({
90
+ broadcastMessages: [userRound1BroadcastMsg, backupRound1BroadcastMsg],
91
+ p2pMessages: [],
92
+ });
93
+ const round1Messages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages(round1SerializedMessages, [bitgoGpgPubKey], [userGpgPrvKey, backupGpgPrvKey]);
94
+ const { sessionId, bitgoMsg1, bitgoToBackupMsg2, bitgoToUserMsg2 } = await this.sendKeyGenerationRound1(params.enterprise, userGpgKey.publicKey, backupGpgKey.publicKey, params.retrofit?.walletId
95
+ ? {
96
+ ...round1Messages,
97
+ walletId: params.retrofit.walletId,
98
+ }
99
+ : round1Messages);
100
+ // #endregion
101
+ // #region round 2
102
+ const bitgoRound1BroadcastMessages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ p2pMessages: [], broadcastMessages: [this.formatBitgoBroadcastMessage(bitgoMsg1)] }, [bitgoGpgPubKey], [userGpgPrvKey, backupGpgPrvKey]);
103
+ const bitgoRound1BroadcastMsg = bitgoRound1BroadcastMessages.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
104
+ (0, assert_1.default)(bitgoRound1BroadcastMsg, 'BitGo message 1 not found in broadcast messages');
105
+ const userRound2P2PMessages = userSession.handleIncomingMessages({
106
+ p2pMessages: [],
107
+ broadcastMessages: [sdk_lib_mpc_1.DklsTypes.deserializeBroadcastMessage(bitgoRound1BroadcastMsg), backupRound1BroadcastMsg],
108
+ });
109
+ const userToBitgoMsg2 = userRound2P2PMessages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
110
+ (0, assert_1.default)(userToBitgoMsg2, 'User message 2 not found in P2P messages');
111
+ const serializedUserToBitgoMsg2 = sdk_lib_mpc_1.DklsTypes.serializeP2PMessage(userToBitgoMsg2);
112
+ const backupRound2P2PMessages = backupSession.handleIncomingMessages({
113
+ p2pMessages: [],
114
+ broadcastMessages: [userRound1BroadcastMsg, sdk_lib_mpc_1.DklsTypes.deserializeBroadcastMessage(bitgoRound1BroadcastMsg)],
115
+ });
116
+ const serializedBackupToBitgoMsg2 = sdk_lib_mpc_1.DklsTypes.serializeMessages(backupRound2P2PMessages).p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
117
+ (0, assert_1.default)(serializedBackupToBitgoMsg2, 'Backup message 2 not found in P2P messages');
118
+ const round2Messages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages({ p2pMessages: [serializedUserToBitgoMsg2, serializedBackupToBitgoMsg2], broadcastMessages: [] }, [bitgoGpgPubKey], [userGpgPrvKey, backupGpgPrvKey]);
119
+ const { sessionId: sessionIdRound2, bitgoCommitment2, bitgoToUserMsg3, bitgoToBackupMsg3, } = await this.sendKeyGenerationRound2(params.enterprise, sessionId, round2Messages);
120
+ // #endregion
121
+ // #region round 3
122
+ assert_1.default.equal(sessionId, sessionIdRound2, 'Round 1 and 2 Session IDs do not match');
123
+ const decryptedBitgoToUserRound2Msgs = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ p2pMessages: [this.formatP2PMessage(bitgoToUserMsg2)], broadcastMessages: [] }, [bitgoGpgPubKey], [userGpgPrvKey]);
124
+ const serializedBitgoToUserRound2Msg = decryptedBitgoToUserRound2Msgs.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO && m.to === typesMPCv2_1.MPCv2PartiesEnum.USER);
125
+ (0, assert_1.default)(serializedBitgoToUserRound2Msg, 'BitGo to User message 2 not found in P2P messages');
126
+ const bitgoToUserRound2Msg = sdk_lib_mpc_1.DklsTypes.deserializeP2PMessage(serializedBitgoToUserRound2Msg);
127
+ const decryptedBitgoToBackupRound2Msg = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ p2pMessages: [this.formatP2PMessage(bitgoToBackupMsg2)], broadcastMessages: [] }, [bitgoGpgPubKey], [backupGpgPrvKey]);
128
+ const serializedBitgoToBackupRound2Msg = decryptedBitgoToBackupRound2Msg.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO && m.to === typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
129
+ (0, assert_1.default)(serializedBitgoToBackupRound2Msg, 'BitGo to Backup message 2 not found in P2P messages');
130
+ const bitgoToBackupRound2Msg = sdk_lib_mpc_1.DklsTypes.deserializeP2PMessage(serializedBitgoToBackupRound2Msg);
131
+ const userToBackupMsg2 = userRound2P2PMessages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
132
+ (0, assert_1.default)(userToBackupMsg2, 'User to Backup message 2 not found in P2P messages');
133
+ const backupToUserMsg2 = backupRound2P2PMessages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.USER);
134
+ (0, assert_1.default)(backupToUserMsg2, 'Backup to User message 2 not found in P2P messages');
135
+ const userRound3Messages = userSession.handleIncomingMessages({
136
+ broadcastMessages: [],
137
+ p2pMessages: [bitgoToUserRound2Msg, backupToUserMsg2],
138
+ });
139
+ const userToBackupMsg3 = userRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
140
+ (0, assert_1.default)(userToBackupMsg3, 'User to Backup message 3 not found in P2P messages');
141
+ const userToBitgoMsg3 = userRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
142
+ (0, assert_1.default)(userToBitgoMsg3, 'User to Bitgo message 3 not found in P2P messages');
143
+ const serializedUserToBitgoMsg3 = sdk_lib_mpc_1.DklsTypes.serializeP2PMessage(userToBitgoMsg3);
144
+ const backupRound3Messages = backupSession.handleIncomingMessages({
145
+ broadcastMessages: [],
146
+ p2pMessages: [bitgoToBackupRound2Msg, userToBackupMsg2],
147
+ });
148
+ const backupToUserMsg3 = backupRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.USER);
149
+ (0, assert_1.default)(backupToUserMsg3, 'Backup to User message 3 not found in P2P messages');
150
+ const backupToBitgoMsg3 = backupRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
151
+ (0, assert_1.default)(backupToBitgoMsg3, 'Backup to Bitgo message 3 not found in P2P messages');
152
+ const serializedBackupToBitgoMsg3 = sdk_lib_mpc_1.DklsTypes.serializeP2PMessage(backupToBitgoMsg3);
153
+ const decryptedBitgoToUserRound3Messages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ broadcastMessages: [], p2pMessages: [this.formatP2PMessage(bitgoToUserMsg3, bitgoCommitment2)] }, [bitgoGpgPubKey], [userGpgPrvKey]);
154
+ const serializedBitgoToUserRound3Msg = decryptedBitgoToUserRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO && m.to === typesMPCv2_1.MPCv2PartiesEnum.USER);
155
+ (0, assert_1.default)(serializedBitgoToUserRound3Msg, 'BitGo to User message 3 not found in P2P messages');
156
+ const bitgoToUserRound3Msg = sdk_lib_mpc_1.DklsTypes.deserializeP2PMessage(serializedBitgoToUserRound3Msg);
157
+ const decryptedBitgoToBackupRound3Messages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ broadcastMessages: [], p2pMessages: [this.formatP2PMessage(bitgoToBackupMsg3, bitgoCommitment2)] }, [bitgoGpgPubKey], [backupGpgPrvKey]);
158
+ const serializedBitgoToBackupRound3Msg = decryptedBitgoToBackupRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO && m.to === typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
159
+ (0, assert_1.default)(serializedBitgoToBackupRound3Msg, 'BitGo to Backup message 3 not found in P2P messages');
160
+ const bitgoToBackupRound3Msg = sdk_lib_mpc_1.DklsTypes.deserializeP2PMessage(serializedBitgoToBackupRound3Msg);
161
+ const userRound4Messages = userSession.handleIncomingMessages({
162
+ p2pMessages: [backupToUserMsg3, bitgoToUserRound3Msg],
163
+ broadcastMessages: [],
164
+ });
165
+ const userRound4BroadcastMsg = userRound4Messages.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER);
166
+ (0, assert_1.default)(userRound4BroadcastMsg, 'User message 4 not found in broadcast messages');
167
+ const serializedUserRound4BroadcastMsg = sdk_lib_mpc_1.DklsTypes.serializeBroadcastMessage(userRound4BroadcastMsg);
168
+ const backupRound4Messages = backupSession.handleIncomingMessages({
169
+ p2pMessages: [userToBackupMsg3, bitgoToBackupRound3Msg],
170
+ broadcastMessages: [],
171
+ });
172
+ const backupRound4BroadcastMsg = backupRound4Messages.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
173
+ (0, assert_1.default)(backupRound4BroadcastMsg, 'Backup message 4 not found in broadcast messages');
174
+ const serializedBackupRound4BroadcastMsg = sdk_lib_mpc_1.DklsTypes.serializeBroadcastMessage(backupRound4BroadcastMsg);
175
+ const round3Messages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages({
176
+ p2pMessages: [serializedUserToBitgoMsg3, serializedBackupToBitgoMsg3],
177
+ broadcastMessages: [serializedUserRound4BroadcastMsg, serializedBackupRound4BroadcastMsg],
178
+ }, [bitgoGpgPubKey], [userGpgPrvKey, backupGpgPrvKey]);
179
+ const { sessionId: sessionIdRound3, bitgoMsg4, commonKeychain: bitgoCommonKeychain, } = await this.sendKeyGenerationRound3(params.enterprise, sessionId, round3Messages);
180
+ // #endregion
181
+ // #region keychain creation
182
+ assert_1.default.equal(sessionId, sessionIdRound3, 'Round 1 and 3 Session IDs do not match');
183
+ const bitgoRound4BroadcastMessages = sdk_lib_mpc_1.DklsTypes.deserializeMessages(await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ p2pMessages: [], broadcastMessages: [this.formatBitgoBroadcastMessage(bitgoMsg4)] }, [bitgoGpgPubKey], [])).broadcastMessages;
184
+ const bitgoRound4BroadcastMsg = bitgoRound4BroadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
185
+ (0, assert_1.default)(bitgoRound4BroadcastMsg, 'BitGo message 4 not found in broadcast messages');
186
+ userSession.handleIncomingMessages({
187
+ p2pMessages: [],
188
+ broadcastMessages: [bitgoRound4BroadcastMsg, backupRound4BroadcastMsg],
189
+ });
190
+ backupSession.handleIncomingMessages({
191
+ p2pMessages: [],
192
+ broadcastMessages: [bitgoRound4BroadcastMsg, userRound4BroadcastMsg],
193
+ });
194
+ const userPrivateMaterial = userSession.getKeyShare();
195
+ const backupPrivateMaterial = backupSession.getKeyShare();
196
+ const userReducedPrivateMaterial = userSession.getReducedKeyShare();
197
+ const backupReducedPrivateMaterial = backupSession.getReducedKeyShare();
198
+ const userCommonKeychain = sdk_lib_mpc_1.DklsTypes.getCommonKeychain(userPrivateMaterial);
199
+ const backupCommonKeychain = sdk_lib_mpc_1.DklsTypes.getCommonKeychain(backupPrivateMaterial);
200
+ assert_1.default.equal(bitgoCommonKeychain, userCommonKeychain, 'User and Bitgo Common keychains do not match');
201
+ assert_1.default.equal(bitgoCommonKeychain, backupCommonKeychain, 'Backup and Bitgo Common keychains do not match');
202
+ const userKeychainPromise = this.addUserKeychain(bitgoCommonKeychain, userPrivateMaterial, userReducedPrivateMaterial, params.passphrase, params.originalPasscodeEncryptionCode);
203
+ const backupKeychainPromise = this.addBackupKeychain(bitgoCommonKeychain, userPrivateMaterial, backupReducedPrivateMaterial, params.passphrase, params.originalPasscodeEncryptionCode);
204
+ const bitgoKeychainPromise = this.addBitgoKeychain(bitgoCommonKeychain);
205
+ const [userKeychain, backupKeychain, bitgoKeychain] = await Promise.all([
206
+ userKeychainPromise,
207
+ backupKeychainPromise,
208
+ bitgoKeychainPromise,
209
+ ]);
210
+ // #endregion
211
+ return {
212
+ userKeychain,
213
+ backupKeychain,
214
+ bitgoKeychain,
215
+ };
216
+ }
217
+ // #region keychain utils
218
+ async createParticipantKeychain(participantIndex, commonKeychain, privateMaterial, reducedPrivateMaterial, passphrase, originalPasscodeEncryptionCode) {
219
+ let source;
220
+ let encryptedPrv = undefined;
221
+ let reducedEncryptedPrv = undefined;
222
+ switch (participantIndex) {
223
+ case typesMPCv2_1.MPCv2PartiesEnum.USER:
224
+ case typesMPCv2_1.MPCv2PartiesEnum.BACKUP:
225
+ source = participantIndex === typesMPCv2_1.MPCv2PartiesEnum.USER ? 'user' : 'backup';
226
+ (0, assert_1.default)(privateMaterial, `Private material is required for ${source} keychain`);
227
+ (0, assert_1.default)(reducedPrivateMaterial, `Reduced private material is required for ${source} keychain`);
228
+ (0, assert_1.default)(passphrase, `Passphrase is required for ${source} keychain`);
229
+ encryptedPrv = this.bitgo.encrypt({
230
+ input: privateMaterial.toString('base64'),
231
+ password: passphrase,
232
+ });
233
+ reducedEncryptedPrv = this.bitgo.encrypt({
234
+ // Buffer.toString('base64') can not be used here as it does not work on the browser.
235
+ // The browser deals with a Buffer as Uint8Array, therefore in the browser .toString('base64') just creates a comma seperated string of the array values.
236
+ input: btoa(String.fromCharCode.apply(null, Array.from(new Uint8Array(reducedPrivateMaterial)))),
237
+ password: passphrase,
238
+ });
239
+ break;
240
+ case typesMPCv2_1.MPCv2PartiesEnum.BITGO:
241
+ source = 'bitgo';
242
+ break;
243
+ default:
244
+ throw new Error('Invalid participant index');
245
+ }
246
+ const recipientKeychainParams = {
247
+ source,
248
+ keyType: 'tss',
249
+ commonKeychain,
250
+ encryptedPrv,
251
+ originalPasscodeEncryptionCode,
252
+ isMPCv2: true,
253
+ };
254
+ const keychains = this.baseCoin.keychains();
255
+ return { ...(await keychains.add(recipientKeychainParams)), reducedEncryptedPrv: reducedEncryptedPrv };
256
+ }
257
+ /**
258
+ * Converts a User or Backup MPCv1 SigningMaterial to RetrofitData needed by MPCv2 DKG.
259
+ *
260
+ * @param decryptedKeyshare - MPCv1 decrypted signing material for user or backup as a json.stringify string and bitgo's Big Si.
261
+ * @param partyId - The party ID of the MPCv1 keyshare.
262
+ * @returns The retrofit data needed to start an MPCv2 DKG session.
263
+ * @deprecated
264
+ */
265
+ static getKeyDataForRetrofit(decryptedKeyshare, partyId) {
266
+ const mpc = new account_lib_1.Ecdsa();
267
+ const xiList = [
268
+ Array.from((0, sdk_lib_mpc_1.bigIntToBufferBE)(BigInt(1), 32)),
269
+ Array.from((0, sdk_lib_mpc_1.bigIntToBufferBE)(BigInt(2), 32)),
270
+ Array.from((0, sdk_lib_mpc_1.bigIntToBufferBE)(BigInt(3), 32)),
271
+ ];
272
+ return EcdsaMPCv2Utils.getMpcV2RetrofitDataFromMpcV1Key({
273
+ mpcv1PartyKeyShare: decryptedKeyshare,
274
+ mpcv1PartyIndex: partyId === typesMPCv2_1.MPCv2PartiesEnum.USER ? 1 : 2,
275
+ xiList,
276
+ mpc,
277
+ });
278
+ }
279
+ /**
280
+ * Converts user and backup MPCv1 SigningMaterial to RetrofitData needed by MPCv2 DKG.
281
+ *
282
+ * @param {Object} params - MPCv1 decrypted signing material for user and backup as a json.stringify string and bitgo's Big Si.
283
+ * @returns {{ mpcv2UserKeyShare: DklsTypes.RetrofitData; mpcv2BakcupKeyShare: DklsTypes.RetrofitData }} - the retrofit data needed to start an MPCv2 DKG session.
284
+ */
285
+ getMpcV2RetrofitDataFromMpcV1Keys(params) {
286
+ const mpc = new account_lib_1.Ecdsa();
287
+ const xiList = [
288
+ Array.from((0, sdk_lib_mpc_1.bigIntToBufferBE)(BigInt(1), 32)),
289
+ Array.from((0, sdk_lib_mpc_1.bigIntToBufferBE)(BigInt(2), 32)),
290
+ Array.from((0, sdk_lib_mpc_1.bigIntToBufferBE)(BigInt(3), 32)),
291
+ ];
292
+ return {
293
+ mpcv2UserKeyShare: EcdsaMPCv2Utils.getMpcV2RetrofitDataFromMpcV1Key({
294
+ mpcv1PartyKeyShare: params.mpcv1UserKeyShare,
295
+ mpcv1PartyIndex: 1,
296
+ xiList,
297
+ mpc,
298
+ }),
299
+ mpcv2BackupKeyShare: EcdsaMPCv2Utils.getMpcV2RetrofitDataFromMpcV1Key({
300
+ mpcv1PartyKeyShare: params.mpcv1BackupKeyShare,
301
+ mpcv1PartyIndex: 2,
302
+ xiList,
303
+ mpc,
304
+ }),
305
+ };
306
+ }
307
+ /**
308
+ * Get retrofit data from MPCv1 key share.
309
+ * @param mpcv1PartyKeyShare
310
+ * @param mpcv1PartyIndex
311
+ * @param xiList
312
+ * @param mpc
313
+ * @deprecated
314
+ */
315
+ static getMpcV2RetrofitDataFromMpcV1Key({ mpcv1PartyKeyShare, mpcv1PartyIndex, xiList, mpc, }) {
316
+ const signingMaterial = JSON.parse(mpcv1PartyKeyShare);
317
+ let keyCombined = undefined;
318
+ switch (mpcv1PartyIndex) {
319
+ case 1:
320
+ (0, assert_1.default)(signingMaterial.backupNShare, 'User MPCv1 key material should have backup NShare.');
321
+ (0, assert_1.default)(signingMaterial.bitgoNShare, 'BitGo MPCv1 key material should have user NShare.');
322
+ keyCombined = mpc.keyCombine(signingMaterial.pShare, [
323
+ signingMaterial.backupNShare,
324
+ signingMaterial.bitgoNShare,
325
+ ]);
326
+ break;
327
+ case 2:
328
+ (0, assert_1.default)(signingMaterial.userNShare, 'User MPCv1 key material should have backup NShare.');
329
+ (0, assert_1.default)(signingMaterial.bitgoNShare, 'BitGo MPCv1 key material should have user NShare.');
330
+ keyCombined = mpc.keyCombine(signingMaterial.pShare, [signingMaterial.userNShare, signingMaterial.bitgoNShare]);
331
+ break;
332
+ case 3:
333
+ (0, assert_1.default)(signingMaterial.userNShare, 'User MPCv1 key material should have backup NShare.');
334
+ (0, assert_1.default)(signingMaterial.backupNShare, 'Backup MPCv1 key material should have user NShare.');
335
+ keyCombined = mpc.keyCombine(signingMaterial.pShare, [
336
+ signingMaterial.userNShare,
337
+ signingMaterial.backupNShare,
338
+ ]);
339
+ break;
340
+ default:
341
+ throw new Error('Invalid participant index');
342
+ }
343
+ return {
344
+ xShare: keyCombined.xShare,
345
+ xiList: xiList,
346
+ };
347
+ }
348
+ async addUserKeychain(commonKeychain, privateMaterial, reducedPrivateMaterial, passphrase, originalPasscodeEncryptionCode) {
349
+ return this.createParticipantKeychain(typesMPCv2_1.MPCv2PartiesEnum.USER, commonKeychain, privateMaterial, reducedPrivateMaterial, passphrase, originalPasscodeEncryptionCode);
350
+ }
351
+ async addBackupKeychain(commonKeychain, privateMaterial, reducedPrivateMaterial, passphrase, originalPasscodeEncryptionCode) {
352
+ return this.createParticipantKeychain(typesMPCv2_1.MPCv2PartiesEnum.BACKUP, commonKeychain, privateMaterial, reducedPrivateMaterial, passphrase, originalPasscodeEncryptionCode);
353
+ }
354
+ getUserAndBackupSession(m, n, retrofit) {
355
+ if (retrofit) {
356
+ const retrofitData = this.getMpcV2RetrofitDataFromMpcV1Keys({
357
+ mpcv1UserKeyShare: retrofit.decryptedUserKey,
358
+ mpcv1BackupKeyShare: retrofit.decryptedBackupKey,
359
+ });
360
+ const userSession = new sdk_lib_mpc_1.DklsDkg.Dkg(n, m, typesMPCv2_1.MPCv2PartiesEnum.USER, undefined, retrofitData.mpcv2UserKeyShare);
361
+ const backupSession = new sdk_lib_mpc_1.DklsDkg.Dkg(n, m, typesMPCv2_1.MPCv2PartiesEnum.BACKUP, undefined, retrofitData.mpcv2BackupKeyShare);
362
+ return { userSession, backupSession };
363
+ }
364
+ const userSession = new sdk_lib_mpc_1.DklsDkg.Dkg(n, m, typesMPCv2_1.MPCv2PartiesEnum.USER);
365
+ const backupSession = new sdk_lib_mpc_1.DklsDkg.Dkg(n, m, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
366
+ return { userSession, backupSession };
367
+ }
368
+ async addBitgoKeychain(commonKeychain) {
369
+ return this.createParticipantKeychain(typesMPCv2_1.MPCv2PartiesEnum.BITGO, commonKeychain);
370
+ }
371
+ // #endregion
372
+ async sendKeyGenerationRound1(enterprise, userGpgPublicKey, backupGpgPublicKey, payload) {
373
+ return this.sendKeyGenerationRound1BySender((0, ecdsaMPCv2KeyGenSender_1.KeyGenSenderForEnterprise)(this.bitgo, enterprise), userGpgPublicKey, backupGpgPublicKey, payload);
374
+ }
375
+ async sendKeyGenerationRound2(enterprise, sessionId, payload) {
376
+ return this.sendKeyGenerationRound2BySender((0, ecdsaMPCv2KeyGenSender_1.KeyGenSenderForEnterprise)(this.bitgo, enterprise), sessionId, payload);
377
+ }
378
+ async sendKeyGenerationRound3(enterprise, sessionId, payload) {
379
+ return this.sendKeyGenerationRound3BySender((0, ecdsaMPCv2KeyGenSender_1.KeyGenSenderForEnterprise)(this.bitgo, enterprise), sessionId, payload);
380
+ }
381
+ async sendKeyGenerationRound1BySender(senderFn, userGpgPublicKey, backupGpgPublicKey, payload) {
382
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(userGpgPublicKey), 'User GPG public key is required');
383
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(backupGpgPublicKey), 'Backup GPG public key is required');
384
+ const userMsg1 = payload.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER)?.payload;
385
+ (0, assert_1.default)(userMsg1, 'User message 1 not found in broadcast messages');
386
+ const backupMsg1 = payload.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP)?.payload;
387
+ (0, assert_1.default)(backupMsg1, 'Backup message 1 not found in broadcast messages');
388
+ return senderFn(public_types_1.MPCv2KeyGenStateEnum['MPCv2-R1'], {
389
+ userGpgPublicKey,
390
+ backupGpgPublicKey,
391
+ userMsg1: { from: 0, ...userMsg1 },
392
+ backupMsg1: { from: 1, ...backupMsg1 },
393
+ walletId: payload.walletId,
394
+ });
395
+ }
396
+ async sendKeyGenerationRound2BySender(senderFn, sessionId, payload) {
397
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(sessionId), 'Session ID is required');
398
+ const userMsg2 = payload.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
399
+ (0, assert_1.default)(userMsg2, 'User to Bitgo message 2 not found in P2P messages');
400
+ (0, assert_1.default)(userMsg2.commitment, 'User to Bitgo commitment not found in P2P messages');
401
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(userMsg2.commitment), 'User to Bitgo commitment is required');
402
+ const backupMsg2 = payload.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
403
+ (0, assert_1.default)(backupMsg2, 'Backup to Bitgo message 2 not found in P2P messages');
404
+ (0, assert_1.default)(backupMsg2.commitment, 'Backup to Bitgo commitment not found in P2P messages');
405
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(backupMsg2.commitment), 'Backup to Bitgo commitment is required');
406
+ return senderFn(public_types_1.MPCv2KeyGenStateEnum['MPCv2-R2'], {
407
+ sessionId,
408
+ userMsg2: {
409
+ from: typesMPCv2_1.MPCv2PartiesEnum.USER,
410
+ to: typesMPCv2_1.MPCv2PartiesEnum.BITGO,
411
+ signature: userMsg2.payload.signature,
412
+ encryptedMessage: userMsg2.payload.encryptedMessage,
413
+ },
414
+ userCommitment2: userMsg2.commitment,
415
+ backupMsg2: {
416
+ from: typesMPCv2_1.MPCv2PartiesEnum.BACKUP,
417
+ to: typesMPCv2_1.MPCv2PartiesEnum.BITGO,
418
+ signature: backupMsg2.payload.signature,
419
+ encryptedMessage: backupMsg2.payload.encryptedMessage,
420
+ },
421
+ backupCommitment2: backupMsg2.commitment,
422
+ });
423
+ }
424
+ async sendKeyGenerationRound3BySender(senderFn, sessionId, payload) {
425
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(sessionId), 'Session ID is required');
426
+ const userMsg3 = payload.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO)?.payload;
427
+ (0, assert_1.default)(userMsg3, 'User to Bitgo message 3 not found in P2P messages');
428
+ const backupMsg3 = payload.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO)?.payload;
429
+ (0, assert_1.default)(backupMsg3, 'Backup to Bitgo message 3 not found in P2P messages');
430
+ const userMsg4 = payload.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER)?.payload;
431
+ (0, assert_1.default)(userMsg4, 'User message 1 not found in broadcast messages');
432
+ const backupMsg4 = payload.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP)?.payload;
433
+ (0, assert_1.default)(backupMsg4, 'Backup message 1 not found in broadcast messages');
434
+ return senderFn(public_types_1.MPCv2KeyGenStateEnum['MPCv2-R3'], {
435
+ sessionId,
436
+ userMsg3: { from: 0, to: 2, ...userMsg3 },
437
+ backupMsg3: { from: 1, to: 2, ...backupMsg3 },
438
+ userMsg4: { from: 0, ...userMsg4 },
439
+ backupMsg4: { from: 1, ...backupMsg4 },
440
+ });
441
+ }
442
+ // #endregion
443
+ // #region sign tx request
444
+ /**
445
+ * Signs the transaction associated to the transaction request.
446
+ * @param {string | TxRequest} params.txRequest - transaction request object or id
447
+ * @param {string} params.prv - decrypted private key
448
+ * @param {string} params.reqId - request id
449
+ * @param {string} params.mpcv2PartyId - party id for the signer involved in this mpcv2 request (either 0 for user or 1 for backup)
450
+ * @returns {Promise<TxRequest>} fully signed TxRequest object
451
+ */
452
+ async signTxRequest(params) {
453
+ this.bitgo.setRequestTracer(params.reqId);
454
+ return this.signRequestBase(params, baseTypes_1.RequestType.tx);
455
+ }
456
+ /**
457
+ * Signs the message associated to the transaction request.
458
+ * @param {string | TxRequest} params.txRequest - transaction request object or id
459
+ * @param {string} params.prv - decrypted private key
460
+ * @param {string} params.reqId - request id
461
+ * @returns {Promise<TxRequest>} fully signed TxRequest object
462
+ */
463
+ async signTxRequestForMessage(params) {
464
+ this.bitgo.setRequestTracer(params.reqId);
465
+ return this.signRequestBase(params, baseTypes_1.RequestType.message);
466
+ }
467
+ async signRequestBase(params, requestType) {
468
+ const userKeyShare = buffer_1.Buffer.from(params.prv, 'base64');
469
+ const txRequest = typeof params.txRequest === 'string'
470
+ ? await (0, tss_1.getTxRequest)(this.bitgo, this.wallet.id(), params.txRequest, params.reqId)
471
+ : params.txRequest;
472
+ let txOrMessageToSign;
473
+ let derivationPath;
474
+ let bufferContent;
475
+ const userGpgKey = await (0, opengpgUtils_1.generateGPGKeyPair)('secp256k1');
476
+ const bitgoGpgPubKey = await this.pickBitgoPubGpgKeyForSigning(true, params.reqId, txRequest.enterpriseId);
477
+ if (!bitgoGpgPubKey) {
478
+ throw new Error('Missing BitGo GPG key for MPCv2');
479
+ }
480
+ if (requestType === baseTypes_1.RequestType.tx) {
481
+ (0, assert_1.default)(txRequest.transactions || txRequest.unsignedTxs, 'Unable to find transactions in txRequest');
482
+ const unsignedTx = txRequest.apiVersion === 'full' ? txRequest.transactions[0].unsignedTx : txRequest.unsignedTxs[0];
483
+ await this.baseCoin.verifyTransaction({
484
+ txPrebuild: { txHex: unsignedTx.signableHex },
485
+ txParams: params.txParams || { recipients: [] },
486
+ wallet: this.wallet,
487
+ walletType: this.wallet.multisigType(),
488
+ });
489
+ txOrMessageToSign = unsignedTx.signableHex;
490
+ derivationPath = unsignedTx.derivationPath;
491
+ bufferContent = buffer_1.Buffer.from(txOrMessageToSign, 'hex');
492
+ }
493
+ else if (requestType === baseTypes_1.RequestType.message) {
494
+ txOrMessageToSign = txRequest.messages[0].messageEncoded;
495
+ derivationPath = txRequest.messages[0].derivationPath || 'm/0';
496
+ bufferContent = buffer_1.Buffer.from(txOrMessageToSign, 'hex');
497
+ }
498
+ else {
499
+ throw new Error('Invalid request type');
500
+ }
501
+ let hash;
502
+ try {
503
+ hash = this.baseCoin.getHashFunction();
504
+ }
505
+ catch (err) {
506
+ hash = (0, keccak_1.default)('keccak256');
507
+ }
508
+ // check what the encoding is supposed to be for message
509
+ const hashBuffer = hash.update(bufferContent).digest();
510
+ const otherSigner = new sdk_lib_mpc_1.DklsDsg.Dsg(userKeyShare, params.mpcv2PartyId ? params.mpcv2PartyId : 0, derivationPath, hashBuffer);
511
+ const userSignerBroadcastMsg1 = await otherSigner.init();
512
+ const signatureShareRound1 = await (0, ecdsaMPCv2_1.getSignatureShareRoundOne)(userSignerBroadcastMsg1, userGpgKey, params.mpcv2PartyId);
513
+ let latestTxRequest = await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequest.walletId, txRequest.txRequestId, [signatureShareRound1], requestType, this.baseCoin.getMPCAlgorithm(), userGpgKey.publicKey, undefined, this.wallet.multisigTypeVersion(), params.reqId);
514
+ (0, assert_1.default)(latestTxRequest.transactions || latestTxRequest.messages, 'Invalid txRequest Object');
515
+ let bitgoToUserMessages1And2;
516
+ if (requestType === baseTypes_1.RequestType.tx) {
517
+ bitgoToUserMessages1And2 = latestTxRequest.transactions[0].signatureShares;
518
+ }
519
+ else {
520
+ bitgoToUserMessages1And2 = latestTxRequest.messages[0].signatureShares;
521
+ }
522
+ // TODO: Use codec for parsing
523
+ const parsedBitGoToUserSigShareRoundOne = JSON.parse(bitgoToUserMessages1And2[bitgoToUserMessages1And2.length - 1].share);
524
+ if (parsedBitGoToUserSigShareRoundOne.type !== 'round1Output') {
525
+ throw new Error('Unexpected signature share response. Unable to parse data.');
526
+ }
527
+ const serializedBitGoToUserMessagesRound1And2 = await (0, ecdsaMPCv2_1.verifyBitGoMessagesAndSignaturesRoundOne)(parsedBitGoToUserSigShareRoundOne, userGpgKey, bitgoGpgPubKey, params.mpcv2PartyId);
528
+ /** Round 2 **/
529
+ const deserializedMessages = sdk_lib_mpc_1.DklsTypes.deserializeMessages(serializedBitGoToUserMessagesRound1And2);
530
+ const userToBitGoMessagesRound2 = otherSigner.handleIncomingMessages({
531
+ p2pMessages: [],
532
+ broadcastMessages: deserializedMessages.broadcastMessages,
533
+ });
534
+ const userToBitGoMessagesRound3 = otherSigner.handleIncomingMessages({
535
+ p2pMessages: deserializedMessages.p2pMessages,
536
+ broadcastMessages: [],
537
+ });
538
+ const signatureShareRoundTwo = await (0, ecdsaMPCv2_1.getSignatureShareRoundTwo)(userToBitGoMessagesRound2, userToBitGoMessagesRound3, userGpgKey, bitgoGpgPubKey, params.mpcv2PartyId);
539
+ latestTxRequest = await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequest.walletId, txRequest.txRequestId, [signatureShareRoundTwo], requestType, this.baseCoin.getMPCAlgorithm(), userGpgKey.publicKey, undefined, this.wallet.multisigTypeVersion(), params.reqId);
540
+ (0, assert_1.default)(latestTxRequest.transactions || latestTxRequest.messages, 'Invalid txRequest Object');
541
+ const txRequestSignatureShares = requestType === baseTypes_1.RequestType.tx
542
+ ? latestTxRequest.transactions[0].signatureShares
543
+ : latestTxRequest.messages[0].signatureShares;
544
+ // TODO: Use codec for parsing
545
+ const parsedBitGoToUserSigShareRoundTwo = JSON.parse(txRequestSignatureShares[txRequestSignatureShares.length - 1].share);
546
+ if (parsedBitGoToUserSigShareRoundTwo.type !== 'round2Output') {
547
+ throw new Error('Unexpected signature share response. Unable to parse data.');
548
+ }
549
+ const serializedBitGoToUserMessagesRound3 = await (0, ecdsaMPCv2_1.verifyBitGoMessagesAndSignaturesRoundTwo)(parsedBitGoToUserSigShareRoundTwo, userGpgKey, bitgoGpgPubKey, params.mpcv2PartyId);
550
+ /** Round 3 **/
551
+ const deserializedBitGoToUserMessagesRound3 = sdk_lib_mpc_1.DklsTypes.deserializeMessages({
552
+ p2pMessages: serializedBitGoToUserMessagesRound3.p2pMessages,
553
+ broadcastMessages: [],
554
+ });
555
+ const userToBitGoMessagesRound4 = otherSigner.handleIncomingMessages({
556
+ p2pMessages: deserializedBitGoToUserMessagesRound3.p2pMessages,
557
+ broadcastMessages: [],
558
+ });
559
+ const signatureShareRoundThree = await (0, ecdsaMPCv2_1.getSignatureShareRoundThree)(userToBitGoMessagesRound4, userGpgKey, bitgoGpgPubKey, params.mpcv2PartyId);
560
+ // Submit for final signature share combine
561
+ await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequest.walletId, txRequest.txRequestId, [signatureShareRoundThree], requestType, this.baseCoin.getMPCAlgorithm(), userGpgKey.publicKey, undefined, this.wallet.multisigTypeVersion(), params.reqId);
562
+ return (0, common_1.sendTxRequest)(this.bitgo, txRequest.walletId, txRequest.txRequestId, requestType, params.reqId);
563
+ }
564
+ // #endregion
565
+ // #region formatting utils
566
+ formatBitgoBroadcastMessage(broadcastMessage) {
567
+ return {
568
+ from: broadcastMessage.from,
569
+ payload: { message: broadcastMessage.message, signature: broadcastMessage.signature },
570
+ };
571
+ }
572
+ formatP2PMessage(p2pMessage, commitment) {
573
+ return {
574
+ payload: { encryptedMessage: p2pMessage.encryptedMessage, signature: p2pMessage.signature },
575
+ from: p2pMessage.from,
576
+ to: p2pMessage.to,
577
+ commitment,
578
+ };
579
+ }
580
+ // #endregion
581
+ // #region private utils
582
+ /**
583
+ * Get the hash string and derivation path from the transaction request.
584
+ * @param {TxRequest} txRequest - the transaction request object
585
+ * @param {RequestType} requestType - the request type
586
+ * @returns {{ hashBuffer: Buffer; derivationPath: string }} - the hash string and derivation path
587
+ */
588
+ getHashStringAndDerivationPath(txRequest, requestType = baseTypes_1.RequestType.tx) {
589
+ let txToSign;
590
+ let derivationPath;
591
+ if (requestType === baseTypes_1.RequestType.tx) {
592
+ (0, assert_1.default)(txRequest.transactions && txRequest.transactions.length === 1, 'Unable to find transactions in txRequest');
593
+ txToSign = txRequest.transactions[0].unsignedTx.signableHex;
594
+ derivationPath = txRequest.transactions[0].unsignedTx.derivationPath;
595
+ }
596
+ else if (requestType === baseTypes_1.RequestType.message) {
597
+ // TODO(WP-2176): Add support for message signing
598
+ throw new Error('MPCv2 message signing not supported yet.');
599
+ }
600
+ else {
601
+ throw new Error('Invalid request type, got: ' + requestType);
602
+ }
603
+ let hash;
604
+ try {
605
+ hash = this.baseCoin.getHashFunction();
606
+ }
607
+ catch (err) {
608
+ hash = (0, keccak_1.default)('keccak256');
609
+ }
610
+ const hashBuffer = hash.update(buffer_1.Buffer.from(txToSign, 'hex')).digest();
611
+ return { hashBuffer, derivationPath };
612
+ }
613
+ /**
614
+ * Gets the BitGo and user GPG keys from the BitGo public GPG key and the encrypted user GPG private key.
615
+ * @param {string} bitgoPublicGpgKey - the BitGo public GPG key
616
+ * @param {string} encryptedUserGpgPrvKey - the encrypted user GPG private key
617
+ * @param {string} walletPassphrase - the wallet passphrase
618
+ * @returns {Promise<{ bitgoGpgKey: pgp.Key; userGpgKey: pgp.SerializedKeyPair<string> }>} - the BitGo and user GPG keys
619
+ */
620
+ async getBitgoAndUserGpgKeys(bitgoPublicGpgKey, encryptedUserGpgPrvKey, walletPassphrase) {
621
+ const bitgoGpgKey = await pgp.readKey({ armoredKey: bitgoPublicGpgKey });
622
+ const userDecryptedKey = await pgp.readKey({
623
+ armoredKey: this.bitgo.decrypt({ input: encryptedUserGpgPrvKey, password: walletPassphrase }),
624
+ });
625
+ const userGpgKey = {
626
+ privateKey: userDecryptedKey.armor(),
627
+ publicKey: userDecryptedKey.toPublic().armor(),
628
+ };
629
+ return {
630
+ bitgoGpgKey,
631
+ userGpgKey,
632
+ };
633
+ }
634
+ /**
635
+ * Validates the adata and cyphertext.
636
+ * @param adata string
637
+ * @param cyphertext string
638
+ * @returns void
639
+ * @throws {Error} if the adata or cyphertext is invalid
640
+ */
641
+ validateAdata(adata, cyphertext) {
642
+ let cypherJson;
643
+ try {
644
+ cypherJson = JSON.parse(cyphertext);
645
+ }
646
+ catch (e) {
647
+ throw new Error('Failed to parse cyphertext to JSON, got: ' + cyphertext);
648
+ }
649
+ // using decodeURIComponent to handle special characters
650
+ if (decodeURIComponent(cypherJson.adata) !== decodeURIComponent(adata)) {
651
+ throw new Error('Adata does not match cyphertext adata');
652
+ }
653
+ }
654
+ // #endregion
655
+ // #region external signer
656
+ /** @inheritdoc */
657
+ async signEcdsaMPCv2TssUsingExternalSigner(params, externalSignerMPCv2SigningRound1Generator, externalSignerMPCv2SigningRound2Generator, externalSignerMPCv2SigningRound3Generator, requestType = baseTypes_1.RequestType.tx) {
658
+ const { txRequest, reqId } = params;
659
+ let txRequestResolved;
660
+ // TODO(WP-2176): Add support for message signing
661
+ (0, assert_1.default)(requestType === baseTypes_1.RequestType.tx, 'Only transaction signing is supported for external signer, got: ' + requestType);
662
+ if (typeof txRequest === 'string') {
663
+ txRequestResolved = await (0, tss_1.getTxRequest)(this.bitgo, this.wallet.id(), txRequest, reqId);
664
+ }
665
+ else {
666
+ txRequestResolved = txRequest;
667
+ }
668
+ const bitgoPublicGpgKey = await this.pickBitgoPubGpgKeyForSigning(true, params.reqId, txRequestResolved.enterpriseId);
669
+ if (!bitgoPublicGpgKey) {
670
+ throw new Error('Missing BitGo GPG key for MPCv2');
671
+ }
672
+ // round 1
673
+ const { signatureShareRound1, userGpgPubKey, encryptedRound1Session, encryptedUserGpgPrvKey } = await externalSignerMPCv2SigningRound1Generator({ txRequest: txRequestResolved });
674
+ const round1TxRequest = await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequestResolved.walletId, txRequestResolved.txRequestId, [signatureShareRound1], requestType, this.baseCoin.getMPCAlgorithm(), userGpgPubKey, undefined, this.wallet.multisigTypeVersion(), reqId);
675
+ // round 2
676
+ const { signatureShareRound2, encryptedRound2Session } = await externalSignerMPCv2SigningRound2Generator({
677
+ txRequest: round1TxRequest,
678
+ encryptedRound1Session,
679
+ encryptedUserGpgPrvKey,
680
+ bitgoPublicGpgKey: bitgoPublicGpgKey.armor(),
681
+ });
682
+ const round2TxRequest = await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequestResolved.walletId, txRequestResolved.txRequestId, [signatureShareRound2], requestType, this.baseCoin.getMPCAlgorithm(), userGpgPubKey, undefined, this.wallet.multisigTypeVersion(), reqId);
683
+ (0, assert_1.default)(round2TxRequest.transactions && round2TxRequest.transactions[0].signatureShares, 'Missing signature shares in round 2 txRequest');
684
+ // round 3
685
+ const { signatureShareRound3 } = await externalSignerMPCv2SigningRound3Generator({
686
+ txRequest: round2TxRequest,
687
+ encryptedRound2Session,
688
+ encryptedUserGpgPrvKey,
689
+ bitgoPublicGpgKey: bitgoPublicGpgKey.armor(),
690
+ });
691
+ await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequestResolved.walletId, txRequestResolved.txRequestId, [signatureShareRound3], requestType, this.baseCoin.getMPCAlgorithm(), userGpgPubKey, undefined, this.wallet.multisigTypeVersion(), reqId);
692
+ return (0, common_1.sendTxRequest)(this.bitgo, txRequestResolved.walletId, txRequestResolved.txRequestId, requestType, reqId);
693
+ }
694
+ async createOfflineRound1Share(params) {
695
+ const { prv, walletPassphrase, txRequest } = params;
696
+ const { hashBuffer, derivationPath } = this.getHashStringAndDerivationPath(txRequest);
697
+ const adata = `${hashBuffer.toString('hex')}:${derivationPath}`;
698
+ const userKeyShare = buffer_1.Buffer.from(prv, 'base64');
699
+ const userGpgKey = await (0, opengpgUtils_1.generateGPGKeyPair)('secp256k1');
700
+ const userSigner = new sdk_lib_mpc_1.DklsDsg.Dsg(userKeyShare, 0, derivationPath, hashBuffer);
701
+ const userSignerBroadcastMsg1 = await userSigner.init();
702
+ const signatureShareRound1 = await (0, ecdsaMPCv2_1.getSignatureShareRoundOne)(userSignerBroadcastMsg1, userGpgKey);
703
+ const session = userSigner.getSession();
704
+ const encryptedRound1Session = this.bitgo.encrypt({ input: session, password: walletPassphrase, adata });
705
+ const userGpgPubKey = userGpgKey.publicKey;
706
+ const encryptedUserGpgPrvKey = this.bitgo.encrypt({
707
+ input: userGpgKey.privateKey,
708
+ password: walletPassphrase,
709
+ adata,
710
+ });
711
+ return { signatureShareRound1, userGpgPubKey, encryptedRound1Session, encryptedUserGpgPrvKey };
712
+ }
713
+ async createOfflineRound2Share(params) {
714
+ const { prv, walletPassphrase, encryptedUserGpgPrvKey, encryptedRound1Session, bitgoPublicGpgKey, txRequest } = params;
715
+ const { hashBuffer, derivationPath } = this.getHashStringAndDerivationPath(txRequest);
716
+ const adata = `${hashBuffer.toString('hex')}:${derivationPath}`;
717
+ const { bitgoGpgKey, userGpgKey } = await this.getBitgoAndUserGpgKeys(bitgoPublicGpgKey, encryptedUserGpgPrvKey, walletPassphrase);
718
+ const signatureShares = txRequest.transactions?.[0].signatureShares;
719
+ (0, assert_1.default)(signatureShares, 'Missing signature shares in round 1 txRequest');
720
+ const parsedBitGoToUserSigShareRoundOne = JSON.parse(signatureShares[signatureShares.length - 1].share);
721
+ if (parsedBitGoToUserSigShareRoundOne.type !== 'round1Output') {
722
+ throw new Error('Unexpected signature share response. Unable to parse data.');
723
+ }
724
+ const serializedBitGoToUserMessagesRound1 = await (0, ecdsaMPCv2_1.verifyBitGoMessagesAndSignaturesRoundOne)(parsedBitGoToUserSigShareRoundOne, userGpgKey, bitgoGpgKey);
725
+ const round1Session = this.bitgo.decrypt({ input: encryptedRound1Session, password: walletPassphrase });
726
+ this.validateAdata(adata, encryptedRound1Session);
727
+ const userKeyShare = buffer_1.Buffer.from(prv, 'base64');
728
+ const userSigner = new sdk_lib_mpc_1.DklsDsg.Dsg(userKeyShare, 0, derivationPath, hashBuffer);
729
+ await userSigner.setSession(round1Session);
730
+ const deserializedMessages = sdk_lib_mpc_1.DklsTypes.deserializeMessages(serializedBitGoToUserMessagesRound1);
731
+ const userToBitGoMessagesRound2 = userSigner.handleIncomingMessages({
732
+ p2pMessages: [],
733
+ broadcastMessages: deserializedMessages.broadcastMessages,
734
+ });
735
+ const userToBitGoMessagesRound3 = userSigner.handleIncomingMessages({
736
+ p2pMessages: deserializedMessages.p2pMessages,
737
+ broadcastMessages: [],
738
+ });
739
+ const signatureShareRound2 = await (0, ecdsaMPCv2_1.getSignatureShareRoundTwo)(userToBitGoMessagesRound2, userToBitGoMessagesRound3, userGpgKey, bitgoGpgKey);
740
+ const session = userSigner.getSession();
741
+ const encryptedRound2Session = this.bitgo.encrypt({ input: session, password: walletPassphrase, adata });
742
+ return {
743
+ signatureShareRound2,
744
+ encryptedRound2Session,
745
+ };
746
+ }
747
+ async createOfflineRound3Share(params) {
748
+ const { prv, walletPassphrase, encryptedUserGpgPrvKey, encryptedRound2Session, bitgoPublicGpgKey, txRequest } = params;
749
+ (0, assert_1.default)(txRequest.transactions && txRequest.transactions.length === 1, 'Unable to find transactions in txRequest');
750
+ const { hashBuffer, derivationPath } = this.getHashStringAndDerivationPath(txRequest);
751
+ const adata = `${hashBuffer.toString('hex')}:${derivationPath}`;
752
+ const { bitgoGpgKey, userGpgKey } = await this.getBitgoAndUserGpgKeys(bitgoPublicGpgKey, encryptedUserGpgPrvKey, walletPassphrase);
753
+ const signatureShares = txRequest.transactions?.[0].signatureShares;
754
+ (0, assert_1.default)(signatureShares, 'Missing signature shares in round 2 txRequest');
755
+ const parsedBitGoToUserSigShareRoundTwo = JSON.parse(signatureShares[signatureShares.length - 1].share);
756
+ if (parsedBitGoToUserSigShareRoundTwo.type !== 'round2Output') {
757
+ throw new Error('Unexpected signature share response. Unable to parse data.');
758
+ }
759
+ const serializedBitGoToUserMessagesRound3 = await (0, ecdsaMPCv2_1.verifyBitGoMessagesAndSignaturesRoundTwo)(parsedBitGoToUserSigShareRoundTwo, userGpgKey, bitgoGpgKey);
760
+ const deserializedBitGoToUserMessagesRound3 = sdk_lib_mpc_1.DklsTypes.deserializeMessages({
761
+ p2pMessages: serializedBitGoToUserMessagesRound3.p2pMessages,
762
+ broadcastMessages: [],
763
+ });
764
+ const round2Session = this.bitgo.decrypt({ input: encryptedRound2Session, password: walletPassphrase });
765
+ this.validateAdata(adata, encryptedRound2Session);
766
+ const userKeyShare = buffer_1.Buffer.from(prv, 'base64');
767
+ const userSigner = new sdk_lib_mpc_1.DklsDsg.Dsg(userKeyShare, 0, derivationPath, hashBuffer);
768
+ await userSigner.setSession(round2Session);
769
+ const userToBitGoMessagesRound4 = userSigner.handleIncomingMessages({
770
+ p2pMessages: deserializedBitGoToUserMessagesRound3.p2pMessages,
771
+ broadcastMessages: [],
772
+ });
773
+ const signatureShareRound3 = await (0, ecdsaMPCv2_1.getSignatureShareRoundThree)(userToBitGoMessagesRound4, userGpgKey, bitgoGpgKey);
774
+ return { signatureShareRound3 };
775
+ }
776
+ }
777
+ exports.EcdsaMPCv2Utils = EcdsaMPCv2Utils;
778
+ /**
779
+ * Checks if the given key share, when decrypted, contains valid GG18 signing material.
780
+ *
781
+ * @param {string} keyShare - The encrypted key share string.
782
+ * @param {string|undefined} walletPassphrase - The passphrase used to decrypt the key share
783
+ * @returns {boolean} - Returns `true` if the decrypted data contains valid signing material, otherwise `false`.
784
+ */
785
+ function isGG18SigningMaterial(keyShare, walletPassphrase) {
786
+ const prv = sjcl.decrypt(walletPassphrase, keyShare);
787
+ try {
788
+ const signingMaterial = JSON.parse(prv);
789
+ return (signingMaterial.pShare &&
790
+ signingMaterial.bitgoNShare &&
791
+ (signingMaterial.userNShare || signingMaterial.backupNShare));
792
+ }
793
+ catch (error) {
794
+ return false;
795
+ }
796
+ }
797
+ /**
798
+ * Get the MPC v2 recovery key shares from the provided user and backup key shares.
799
+ * @param encryptedUserKey encrypted gg18 or MPCv2 user key
800
+ * @param encryptedBackupKey encrypted gg18 or MPCv2 backup key
801
+ * @param walletPassphrase password for user and backup key
802
+ * @returns MPC v2 recovery key shares
803
+ */
804
+ async function getMpcV2RecoveryKeyShares(encryptedUserKey, encryptedBackupKey, walletPassphrase) {
805
+ if (isGG18SigningMaterial(encryptedUserKey, walletPassphrase)) {
806
+ return getMpcV2RecoveryKeySharesFromGG18(encryptedUserKey, encryptedBackupKey, walletPassphrase);
807
+ }
808
+ return getMpcV2RecoveryKeySharesFromReducedKey(encryptedUserKey, encryptedBackupKey, walletPassphrase);
809
+ }
810
+ /**
811
+ * Signs a message hash using MPC v2 recovery key shares.
812
+ *
813
+ * @param {Buffer} messageHash
814
+ * @param {Buffer} userKeyShare
815
+ * @param {Buffer} backupKeyShare
816
+ * @param {string} commonKeyChain
817
+ * @returns {Promise<{ recid: number, r: string, s: string, y: string }>}
818
+ *
819
+ * @async
820
+ */
821
+ async function signRecoveryMpcV2(messageHash, userKeyShare, backupKeyShare, commonKeyChain) {
822
+ const userDsg = new sdk_lib_mpc_1.DklsDsg.Dsg(userKeyShare, 0, 'm/0', messageHash);
823
+ const backupDsg = new sdk_lib_mpc_1.DklsDsg.Dsg(backupKeyShare, 1, 'm/0', messageHash);
824
+ const signatureString = sdk_lib_mpc_1.DklsUtils.verifyAndConvertDklsSignature(messageHash, (await sdk_lib_mpc_1.DklsUtils.executeTillRound(5, userDsg, backupDsg)), commonKeyChain, 'm/0', undefined, false);
825
+ const sigParts = signatureString.split(':');
826
+ return {
827
+ recid: parseInt(sigParts[0], 10),
828
+ r: sigParts[1],
829
+ s: sigParts[2],
830
+ y: sigParts[3],
831
+ };
832
+ }
833
+ // #region private utils
834
+ /**
835
+ * Get the MPC v2 recovery key shares from the provided user and backup key shares.
836
+ * @param encryptedGG18UserKey encrypted gg18 user key
837
+ * @param encryptedGG18BackupKey encrypted gg18 backup key
838
+ * @param walletPassphrase password for user and backup key
839
+ * @returns MPC v2 recovery key shares
840
+ */
841
+ async function getMpcV2RecoveryKeySharesFromGG18(encryptedGG18UserKey, encryptedGG18BackupKey, walletPassphrase) {
842
+ const [userKeyCombined, backupKeyCombined] = getKeyCombinedFromTssKeyShares(encryptedGG18UserKey, encryptedGG18BackupKey, walletPassphrase);
843
+ const retrofitDataA = {
844
+ xShare: userKeyCombined.xShare,
845
+ };
846
+ const retrofitDataB = {
847
+ xShare: backupKeyCombined.xShare,
848
+ };
849
+ const [user, backup] = await sdk_lib_mpc_1.DklsUtils.generate2of2KeyShares(retrofitDataA, retrofitDataB);
850
+ const userKeyShare = user.getKeyShare();
851
+ const backupKeyShare = backup.getKeyShare();
852
+ return {
853
+ userKeyShare,
854
+ backupKeyShare,
855
+ commonKeyChain: sdk_lib_mpc_1.DklsTypes.getCommonKeychain(backupKeyShare),
856
+ };
857
+ }
858
+ /**
859
+ * Retrieves the MPC v2 recovery key shares from the provided user and backup key shares.
860
+ *
861
+ * @param {string} encryptedMPCv2UserKey
862
+ * @param {string} encryptedMPCv2BackupKey
863
+ * @param {string} [walletPassphrase] - The passphrase used to decrypt the key shares
864
+ * @returns {Promise<{ userKeyShare: KeyShare, backupKeyShare: KeyShare, commonKeyChain: string }>}
865
+ *
866
+ * @async
867
+ */
868
+ async function getMpcV2RecoveryKeySharesFromReducedKey(encryptedMPCv2UserKey, encryptedMPCv2BackupKey, walletPassphrase) {
869
+ const userCompressedPrv = buffer_1.Buffer.from(sjcl.decrypt(walletPassphrase, encryptedMPCv2UserKey), 'base64');
870
+ const bakcupCompressedPrv = buffer_1.Buffer.from(sjcl.decrypt(walletPassphrase, encryptedMPCv2BackupKey), 'base64');
871
+ const userPrvJSON = sdk_lib_mpc_1.DklsTypes.getDecodedReducedKeyShare(userCompressedPrv);
872
+ const backupPrvJSON = sdk_lib_mpc_1.DklsTypes.getDecodedReducedKeyShare(bakcupCompressedPrv);
873
+ const userKeyRetrofit = {
874
+ xShare: {
875
+ x: buffer_1.Buffer.from(userPrvJSON.prv).toString('hex'),
876
+ y: buffer_1.Buffer.from(userPrvJSON.pub).toString('hex'),
877
+ chaincode: buffer_1.Buffer.from(userPrvJSON.rootChainCode).toString('hex'),
878
+ },
879
+ xiList: userPrvJSON.xList.slice(0, 2),
880
+ };
881
+ const backupKeyRetrofit = {
882
+ xShare: {
883
+ x: buffer_1.Buffer.from(backupPrvJSON.prv).toString('hex'),
884
+ y: buffer_1.Buffer.from(backupPrvJSON.pub).toString('hex'),
885
+ chaincode: buffer_1.Buffer.from(backupPrvJSON.rootChainCode).toString('hex'),
886
+ },
887
+ xiList: backupPrvJSON.xList.slice(0, 2),
888
+ };
889
+ const [user, backup] = await sdk_lib_mpc_1.DklsUtils.generate2of2KeyShares(userKeyRetrofit, backupKeyRetrofit);
890
+ const userKeyShare = user.getKeyShare();
891
+ const backupKeyShare = backup.getKeyShare();
892
+ const commonKeyChain = sdk_lib_mpc_1.DklsTypes.getCommonKeychain(userKeyShare);
893
+ return { userKeyShare, backupKeyShare, commonKeyChain };
894
+ }
895
+ /**
896
+ * Gets the combined key for GG18
897
+ * @param encryptedGG18UserKey encrypted GG18 user key
898
+ * @param encryptedGG18BackupKey encrypted GG18 backup key
899
+ * @param walletPassphrase wallet passphrase
900
+ * @returns key shares
901
+ */
902
+ function getKeyCombinedFromTssKeyShares(encryptedGG18UserKey, encryptedGG18BackupKey, walletPassphrase) {
903
+ let backupPrv;
904
+ let userPrv;
905
+ try {
906
+ backupPrv = sjcl.decrypt(walletPassphrase, encryptedGG18BackupKey);
907
+ userPrv = sjcl.decrypt(walletPassphrase, encryptedGG18UserKey);
908
+ }
909
+ catch (e) {
910
+ throw new Error(`Error decrypting backup keychain: ${e.message}`);
911
+ }
912
+ const userSigningMaterial = JSON.parse(userPrv);
913
+ const backupSigningMaterial = JSON.parse(backupPrv);
914
+ if (!userSigningMaterial.backupNShare) {
915
+ throw new Error('Invalid user key - missing backupNShare');
916
+ }
917
+ if (!backupSigningMaterial.userNShare) {
918
+ throw new Error('Invalid backup key - missing userNShare');
919
+ }
920
+ const MPC = new account_lib_1.Ecdsa();
921
+ const userKeyCombined = MPC.keyCombine(userSigningMaterial.pShare, [
922
+ userSigningMaterial.bitgoNShare,
923
+ userSigningMaterial.backupNShare,
924
+ ]);
925
+ const backupKeyCombined = MPC.keyCombine(backupSigningMaterial.pShare, [
926
+ backupSigningMaterial.userNShare,
927
+ backupSigningMaterial.bitgoNShare,
928
+ ]);
929
+ if (userKeyCombined.xShare.y !== backupKeyCombined.xShare.y ||
930
+ userKeyCombined.xShare.chaincode !== backupKeyCombined.xShare.chaincode) {
931
+ throw new Error('Common keychains do not match');
932
+ }
933
+ return [userKeyCombined, backupKeyCombined];
934
+ }
935
+ // #endregion
936
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNkc2FNUEN2Mi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9iaXRnby91dGlscy90c3MvZWNkc2EvZWNkc2FNUEN2Mi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFzdUNBLHNEQVlDO0FBU0QsOERBYUM7QUFhRCw4Q0E4QkM7QUFuekNELHlEQUE4RztBQUM5Ryx1REFBeUM7QUFDekMsb0RBQTRCO0FBQzVCLG1DQUFnQztBQUVoQyw2Q0FBNkM7QUFDN0Msb0RBQXNDO0FBQ3RDLDZDQUErQjtBQUUvQixzREFVNkI7QUFFN0IseURBQWdEO0FBR2hELHNDQUE4RDtBQUM5RCxnREFBMEU7QUFDMUUsNkNBQWdEO0FBQ2hELDhEQU11QztBQUV2QyxxREFBd0Q7QUFDeEQsNENBV3NCO0FBQ3RCLGlDQUF3QztBQUN4QyxxRUFBNkY7QUFDN0YsNERBQThGO0FBRTlGLE1BQWEsZUFBZ0IsU0FBUSxxQkFBYztJQUNqRCxrQkFBa0I7SUFDbEIsS0FBSyxDQUFDLGVBQWUsQ0FBQyxNQUtyQjtRQUNDLE1BQU0sRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzNGLE1BQU0sVUFBVSxHQUFHLE1BQU0sSUFBQSxpQ0FBa0IsRUFBQyxXQUFXLENBQUMsQ0FBQztRQUN6RCxNQUFNLFlBQVksR0FBRyxNQUFNLElBQUEsaUNBQWtCLEVBQUMsV0FBVyxDQUFDLENBQUM7UUFFM0Qsa0VBQWtFO1FBQ2xFLG9FQUFvRTtRQUNwRSxNQUFNLGlCQUFpQixHQUFHLENBQ3hCLENBQUMsTUFBTSxJQUFJLENBQUMsb0NBQW9DLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxzQkFBc0IsQ0FD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VUFBVSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sRUFBRTtRQUNyRSxxQkFBcUIsQ0FBQyxVQUFVO1FBQ2hDLHFCQUFxQixDQUFDLFdBQVc7S0FDbEMsQ0FBQyxDQUFDO0lBQ0gsSUFDRSxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN2RCxlQUFlLENBQUMsTUFBTSxDQUFDLFNBQVMsS0FBSyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUN2RSxDQUFDO1FBQ0QsTUFBTSxJQUFJLEtBQUssQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFDRCxPQUFPLENBQUMsZUFBZSxFQUFFLGlCQUFpQixDQUFDLENBQUM7QUFDOUMsQ0FBQztBQUVELGFBQWEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBiaWdJbnRUb0J1ZmZlckJFLCBEa2xzQ29tbXMsIERrbHNEa2csIERrbHNEc2csIERrbHNUeXBlcywgRGtsc1V0aWxzIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWxpYi1tcGMnO1xuaW1wb3J0ICogYXMgc2pjbCBmcm9tICdAYml0Z28tYmV0YS9zamNsJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7IEJ1ZmZlciB9IGZyb20gJ2J1ZmZlcic7XG5pbXBvcnQgeyBIYXNoIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCB7IE5vbkVtcHR5U3RyaW5nIH0gZnJvbSAnaW8tdHMtdHlwZXMnO1xuaW1wb3J0IGNyZWF0ZUtlY2Nha0hhc2ggZnJvbSAna2VjY2FrJztcbmltcG9ydCAqIGFzIHBncCBmcm9tICdvcGVucGdwJztcbmltcG9ydCB7IEtleWNoYWluc1RyaXBsZXQgfSBmcm9tICcuLi8uLi8uLi9iYXNlQ29pbic7XG5pbXBvcnQge1xuICBNUEN2MkJyb2FkY2FzdE1lc3NhZ2UsXG4gIE1QQ3YyS2V5R2VuUm91bmQxUmVzcG9uc2UsXG4gIE1QQ3YyS2V5R2VuUm91bmQyUmVzcG9uc2UsXG4gIE1QQ3YyS2V5R2VuUm91bmQzUmVzcG9uc2UsXG4gIE1QQ3YyS2V5R2VuU3RhdGVFbnVtLFxuICBNUEN2MlAyUE1lc3NhZ2UsXG4gIE1QQ3YyUGFydHlGcm9tU3RyaW5nT3JOdW1iZXIsXG4gIE1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFPdXRwdXQsXG4gIE1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJPdXRwdXQsXG59IGZyb20gJ0BiaXRnby9wdWJsaWMtdHlwZXMnO1xuXG5pbXBvcnQgeyBFY2RzYSB9IGZyb20gJy4uLy4uLy4uLy4uL2FjY291bnQtbGliJztcbmltcG9ydCB7IEFkZEtleWNoYWluT3B0aW9ucywgS2V5Y2hhaW4sIEtleVR5cGUgfSBmcm9tICcuLi8uLi8uLi9rZXljaGFpbic7XG5pbXBvcnQgeyBEZWNyeXB0ZWRSZXRyb2ZpdFBheWxvYWQgfSBmcm9tICcuLi8uLi8uLi9rZXljaGFpbi9pS2V5Y2hhaW5zJztcbmltcG9ydCB7IEVDRFNBTWV0aG9kVHlwZXMsIGdldFR4UmVxdWVzdCB9IGZyb20gJy4uLy4uLy4uL3Rzcyc7XG5pbXBvcnQgeyBzZW5kU2lnbmF0dXJlU2hhcmVWMiwgc2VuZFR4UmVxdWVzdCB9IGZyb20gJy4uLy4uLy4uL3Rzcy9jb21tb24nO1xuaW1wb3J0IHsgTVBDdjJQYXJ0aWVzRW51bSB9IGZyb20gJy4vdHlwZXNNUEN2Mic7XG5pbXBvcnQge1xuICBnZXRTaWduYXR1cmVTaGFyZVJvdW5kT25lLFxuICBnZXRTaWduYXR1cmVTaGFyZVJvdW5kVGhyZWUsXG4gIGdldFNpZ25hdHVyZVNoYXJlUm91bmRUd28sXG4gIHZlcmlmeUJpdEdvTWVzc2FnZXNBbmRTaWduYXR1cmVzUm91bmRPbmUsXG4gIHZlcmlmeUJpdEdvTWVzc2FnZXNBbmRTaWduYXR1cmVzUm91bmRUd28sXG59IGZyb20gJy4uLy4uLy4uL3Rzcy9lY2RzYS9lY2RzYU1QQ3YyJztcbmltcG9ydCB7IEtleUNvbWJpbmVkIH0gZnJvbSAnLi4vLi4vLi4vdHNzL2VjZHNhL3R5cGVzJztcbmltcG9ydCB7IGdlbmVyYXRlR1BHS2V5UGFpciB9IGZyb20gJy4uLy4uL29wZW5ncGdVdGlscyc7XG5pbXBvcnQge1xuICBDdXN0b21NUEN2MlNpZ25pbmdSb3VuZDFHZW5lcmF0aW5nRnVuY3Rpb24sXG4gIEN1c3RvbU1QQ3YyU2lnbmluZ1JvdW5kMkdlbmVyYXRpbmdGdW5jdGlvbixcbiAgQ3VzdG9tTVBDdjJTaWduaW5nUm91bmQzR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICBSZXF1ZXN0VHlwZSxcbiAgU2lnbmF0dXJlU2hhcmVSZWNvcmQsXG4gIFRTU1BhcmFtcyxcbiAgVFNTUGFyYW1zRm9yTWVzc2FnZSxcbiAgVFNTUGFyYW1zRm9yTWVzc2FnZVdpdGhQcnYsXG4gIFRTU1BhcmFtc1dpdGhQcnYsXG4gIFR4UmVxdWVzdCxcbn0gZnJvbSAnLi4vYmFzZVR5cGVzJztcbmltcG9ydCB7IEJhc2VFY2RzYVV0aWxzIH0gZnJvbSAnLi9iYXNlJztcbmltcG9ydCB7IEVjZHNhTVBDdjJLZXlHZW5TZW5kRm4sIEtleUdlblNlbmRlckZvckVudGVycHJpc2UgfSBmcm9tICcuL2VjZHNhTVBDdjJLZXlHZW5TZW5kZXInO1xuaW1wb3J0IHsgZW52UmVxdWlyZXNCaXRnb1B1YkdwZ0tleUNvbmZpZywgaXNCaXRnb01wY1B1YktleSB9IGZyb20gJy4uLy4uLy4uL3Rzcy9iaXRnb1B1YktleXMnO1xuXG5leHBvcnQgY2xhc3MgRWNkc2FNUEN2MlV0aWxzIGV4dGVuZHMgQmFzZUVjZHNhVXRpbHMge1xuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgYXN5bmMgY3JlYXRlS2V5Y2hhaW5zKHBhcmFtczoge1xuICAgIHBhc3NwaHJhc2U6IHN0cmluZztcbiAgICBlbnRlcnByaXNlOiBzdHJpbmc7XG4gICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlPzogc3RyaW5nO1xuICAgIHJldHJvZml0PzogRGVjcnlwdGVkUmV0cm9maXRQYXlsb2FkO1xuICB9KTogUHJvbWlzZTxLZXljaGFpbnNUcmlwbGV0PiB7XG4gICAgY29uc3QgeyB1c2VyU2Vzc2lvbiwgYmFja3VwU2Vzc2lvbiB9ID0gdGhpcy5nZXRVc2VyQW5kQmFja3VwU2Vzc2lvbigyLCAzLCBwYXJhbXMucmV0cm9maXQpO1xuICAgIGNvbnN0IHVzZXJHcGdLZXkgPSBhd2FpdCBnZW5lcmF0ZUdQR0tleVBhaXIoJ3NlY3AyNTZrMScpO1xuICAgIGNvbnN0IGJhY2t1cEdwZ0tleSA9IGF3YWl0IGdlbmVyYXRlR1BHS2V5UGFpcignc2VjcDI1NmsxJyk7XG5cbiAgICAvLyBHZXQgdGhlIEJpdEdvIHB1YmxpYyBrZXkgYmFzZWQgb24gdXNlci9lbnRlcnByaXNlIGZlYXR1cmUgZmxhZ3NcbiAgICAvLyBJZiBpdCBkb2Vzbid0IHdvcmssIHVzZSB0aGUgZGVmYXVsdCBwdWJsaWMga2V5IGZyb20gdGhlIGNvbnN0YW50c1xuICAgIGNvbnN0IGJpdGdvUHVibGljR3BnS2V5ID0gKFxuICAgICAgKGF3YWl0IHRoaXMuZ2V0Qml0Z29HcGdQdWJrZXlCYXNlZE9uRmVhdHVyZUZsYWdzKHBhcmFtcy5lbnRlcnByaXNlLCB0cnVlKSkgPz8gdGhpcy5iaXRnb01QQ3YyUHVibGljR3BnS2V5XG4gICAgKS5hcm1vcigpO1xuXG4gICAgaWYgKGVudlJlcXVpcmVzQml0Z29QdWJHcGdLZXlDb25maWcodGhpcy5iaXRnby5nZXRFbnYoKSkpIHtcbiAgICAgIC8vIEVuc3VyZSB0aGUgcHVibGljIGtleSBpcyBvbmUgb2YgdGhlIGV4cGVjdGVkIEJpdEdvIHB1YmxpYyBrZXlzIHdoZW4gaW4gdGVzdCBvciBwcm9kLlxuICAgICAgYXNzZXJ0KGlzQml0Z29NcGNQdWJLZXkoYml0Z29QdWJsaWNHcGdLZXksICdtcGN2MicpLCAnSW52YWxpZCBCaXRHbyBHUEcgcHVibGljIGtleScpO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJHcGdQcnZLZXk6IERrbHNUeXBlcy5QYXJ0eUdwZ0tleSA9IHtcbiAgICAgIHBhcnR5SWQ6IE1QQ3YyUGFydGllc0VudW0uVVNFUixcbiAgICAgIGdwZ0tleTogdXNlckdwZ0tleS5wcml2YXRlS2V5LFxuICAgIH07XG4gICAgY29uc3QgYmFja3VwR3BnUHJ2S2V5OiBEa2xzVHlwZXMuUGFydHlHcGdLZXkgPSB7XG4gICAgICBwYXJ0eUlkOiBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCxcbiAgICAgIGdwZ0tleTogYmFja3VwR3BnS2V5LnByaXZhdGVLZXksXG4gICAgfTtcbiAgICBjb25zdCBiaXRnb0dwZ1B1YktleTogRGtsc1R5cGVzLlBhcnR5R3BnS2V5ID0ge1xuICAgICAgcGFydHlJZDogTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyxcbiAgICAgIGdwZ0tleTogYml0Z29QdWJsaWNHcGdLZXksXG4gICAgfTtcblxuICAgIC8vICNyZWdpb24gcm91bmQgMVxuICAgIGNvbnN0IHVzZXJSb3VuZDFCcm9hZGNhc3RNc2cgPSBhd2FpdCB1c2VyU2Vzc2lvbi5pbml0RGtnKCk7XG4gICAgY29uc3QgYmFja3VwUm91bmQxQnJvYWRjYXN0TXNnID0gYXdhaXQgYmFja3VwU2Vzc2lvbi5pbml0RGtnKCk7XG5cbiAgICBjb25zdCByb3VuZDFTZXJpYWxpemVkTWVzc2FnZXMgPSBEa2xzVHlwZXMuc2VyaWFsaXplTWVzc2FnZXMoe1xuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFt1c2VyUm91bmQxQnJvYWRjYXN0TXNnLCBiYWNrdXBSb3VuZDFCcm9hZGNhc3RNc2ddLFxuICAgICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgIH0pO1xuICAgIGNvbnN0IHJvdW5kMU1lc3NhZ2VzID0gYXdhaXQgRGtsc0NvbW1zLmVuY3J5cHRBbmRBdXRoT3V0Z29pbmdNZXNzYWdlcyhcbiAgICAgIHJvdW5kMVNlcmlhbGl6ZWRNZXNzYWdlcyxcbiAgICAgIFtiaXRnb0dwZ1B1YktleV0sXG4gICAgICBbdXNlckdwZ1BydktleSwgYmFja3VwR3BnUHJ2S2V5XVxuICAgICk7XG5cbiAgICBjb25zdCB7IHNlc3Npb25JZCwgYml0Z29Nc2cxLCBiaXRnb1RvQmFja3VwTXNnMiwgYml0Z29Ub1VzZXJNc2cyIH0gPSBhd2FpdCB0aGlzLnNlbmRLZXlHZW5lcmF0aW9uUm91bmQxKFxuICAgICAgcGFyYW1zLmVudGVycHJpc2UsXG4gICAgICB1c2VyR3BnS2V5LnB1YmxpY0tleSxcbiAgICAgIGJhY2t1cEdwZ0tleS5wdWJsaWNLZXksXG4gICAgICBwYXJhbXMucmV0cm9maXQ/LndhbGxldElkXG4gICAgICAgID8ge1xuICAgICAgICAgICAgLi4ucm91bmQxTWVzc2FnZXMsXG4gICAgICAgICAgICB3YWxsZXRJZDogcGFyYW1zLnJldHJvZml0LndhbGxldElkLFxuICAgICAgICAgIH1cbiAgICAgICAgOiByb3VuZDFNZXNzYWdlc1xuICAgICk7XG4gICAgLy8gI2VuZHJlZ2lvblxuXG4gICAgLy8gI3JlZ2lvbiByb3VuZCAyXG4gICAgY29uc3QgYml0Z29Sb3VuZDFCcm9hZGNhc3RNZXNzYWdlcyA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgIHsgcDJwTWVzc2FnZXM6IFtdLCBicm9hZGNhc3RNZXNzYWdlczogW3RoaXMuZm9ybWF0Qml0Z29Ccm9hZGNhc3RNZXNzYWdlKGJpdGdvTXNnMSldIH0sXG4gICAgICBbYml0Z29HcGdQdWJLZXldLFxuICAgICAgW3VzZXJHcGdQcnZLZXksIGJhY2t1cEdwZ1BydktleV1cbiAgICApO1xuICAgIGNvbnN0IGJpdGdvUm91bmQxQnJvYWRjYXN0TXNnID0gYml0Z29Sb3VuZDFCcm9hZGNhc3RNZXNzYWdlcy5icm9hZGNhc3RNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHT1xuICAgICk7XG4gICAgYXNzZXJ0KGJpdGdvUm91bmQxQnJvYWRjYXN0TXNnLCAnQml0R28gbWVzc2FnZSAxIG5vdCBmb3VuZCBpbiBicm9hZGNhc3QgbWVzc2FnZXMnKTtcblxuICAgIGNvbnN0IHVzZXJSb3VuZDJQMlBNZXNzYWdlcyA9IHVzZXJTZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtEa2xzVHlwZXMuZGVzZXJpYWxpemVCcm9hZGNhc3RNZXNzYWdlKGJpdGdvUm91bmQxQnJvYWRjYXN0TXNnKSwgYmFja3VwUm91bmQxQnJvYWRjYXN0TXNnXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHVzZXJUb0JpdGdvTXNnMiA9IHVzZXJSb3VuZDJQMlBNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSICYmIG0udG8gPT09IE1QQ3YyUGFydGllc0VudW0uQklUR09cbiAgICApO1xuICAgIGFzc2VydCh1c2VyVG9CaXRnb01zZzIsICdVc2VyIG1lc3NhZ2UgMiBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgY29uc3Qgc2VyaWFsaXplZFVzZXJUb0JpdGdvTXNnMiA9IERrbHNUeXBlcy5zZXJpYWxpemVQMlBNZXNzYWdlKHVzZXJUb0JpdGdvTXNnMik7XG5cbiAgICBjb25zdCBiYWNrdXBSb3VuZDJQMlBNZXNzYWdlcyA9IGJhY2t1cFNlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBwMnBNZXNzYWdlczogW10sXG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW3VzZXJSb3VuZDFCcm9hZGNhc3RNc2csIERrbHNUeXBlcy5kZXNlcmlhbGl6ZUJyb2FkY2FzdE1lc3NhZ2UoYml0Z29Sb3VuZDFCcm9hZGNhc3RNc2cpXSxcbiAgICB9KTtcbiAgICBjb25zdCBzZXJpYWxpemVkQmFja3VwVG9CaXRnb01zZzIgPSBEa2xzVHlwZXMuc2VyaWFsaXplTWVzc2FnZXMoYmFja3VwUm91bmQyUDJQTWVzc2FnZXMpLnAycE1lc3NhZ2VzLmZpbmQoXG4gICAgICAobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPXG4gICAgKTtcbiAgICBhc3NlcnQoc2VyaWFsaXplZEJhY2t1cFRvQml0Z29Nc2cyLCAnQmFja3VwIG1lc3NhZ2UgMiBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG5cbiAgICBjb25zdCByb3VuZDJNZXNzYWdlcyA9IGF3YWl0IERrbHNDb21tcy5lbmNyeXB0QW5kQXV0aE91dGdvaW5nTWVzc2FnZXMoXG4gICAgICB7IHAycE1lc3NhZ2VzOiBbc2VyaWFsaXplZFVzZXJUb0JpdGdvTXNnMiwgc2VyaWFsaXplZEJhY2t1cFRvQml0Z29Nc2cyXSwgYnJvYWRjYXN0TWVzc2FnZXM6IFtdIH0sXG4gICAgICBbYml0Z29HcGdQdWJLZXldLFxuICAgICAgW3VzZXJHcGdQcnZLZXksIGJhY2t1cEdwZ1BydktleV1cbiAgICApO1xuXG4gICAgY29uc3Qge1xuICAgICAgc2Vzc2lvbklkOiBzZXNzaW9uSWRSb3VuZDIsXG4gICAgICBiaXRnb0NvbW1pdG1lbnQyLFxuICAgICAgYml0Z29Ub1VzZXJNc2czLFxuICAgICAgYml0Z29Ub0JhY2t1cE1zZzMsXG4gICAgfSA9IGF3YWl0IHRoaXMuc2VuZEtleUdlbmVyYXRpb25Sb3VuZDIocGFyYW1zLmVudGVycHJpc2UsIHNlc3Npb25JZCwgcm91bmQyTWVzc2FnZXMpO1xuICAgIC8vICNlbmRyZWdpb25cblxuICAgIC8vICNyZWdpb24gcm91bmQgM1xuICAgIGFzc2VydC5lcXVhbChzZXNzaW9uSWQsIHNlc3Npb25JZFJvdW5kMiwgJ1JvdW5kIDEgYW5kIDIgU2Vzc2lvbiBJRHMgZG8gbm90IG1hdGNoJyk7XG4gICAgY29uc3QgZGVjcnlwdGVkQml0Z29Ub1VzZXJSb3VuZDJNc2dzID0gYXdhaXQgRGtsc0NvbW1zLmRlY3J5cHRBbmRWZXJpZnlJbmNvbWluZ01lc3NhZ2VzKFxuICAgICAgeyBwMnBNZXNzYWdlczogW3RoaXMuZm9ybWF0UDJQTWVzc2FnZShiaXRnb1RvVXNlck1zZzIpXSwgYnJvYWRjYXN0TWVzc2FnZXM6IFtdIH0sXG4gICAgICBbYml0Z29HcGdQdWJLZXldLFxuICAgICAgW3VzZXJHcGdQcnZLZXldXG4gICAgKTtcbiAgICBjb25zdCBzZXJpYWxpemVkQml0Z29Ub1VzZXJSb3VuZDJNc2cgPSBkZWNyeXB0ZWRCaXRnb1RvVXNlclJvdW5kMk1zZ3MucDJwTWVzc2FnZXMuZmluZChcbiAgICAgIChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uQklUR08gJiYgbS50byA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSXG4gICAgKTtcbiAgICBhc3NlcnQoc2VyaWFsaXplZEJpdGdvVG9Vc2VyUm91bmQyTXNnLCAnQml0R28gdG8gVXNlciBtZXNzYWdlIDIgbm90IGZvdW5kIGluIFAyUCBtZXNzYWdlcycpO1xuICAgIGNvbnN0IGJpdGdvVG9Vc2VyUm91bmQyTXNnID0gRGtsc1R5cGVzLmRlc2VyaWFsaXplUDJQTWVzc2FnZShzZXJpYWxpemVkQml0Z29Ub1VzZXJSb3VuZDJNc2cpO1xuXG4gICAgY29uc3QgZGVjcnlwdGVkQml0Z29Ub0JhY2t1cFJvdW5kMk1zZyA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgIHsgcDJwTWVzc2FnZXM6IFt0aGlzLmZvcm1hdFAyUE1lc3NhZ2UoYml0Z29Ub0JhY2t1cE1zZzIpXSwgYnJvYWRjYXN0TWVzc2FnZXM6IFtdIH0sXG4gICAgICBbYml0Z29HcGdQdWJLZXldLFxuICAgICAgW2JhY2t1cEdwZ1BydktleV1cbiAgICApO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRCaXRnb1RvQmFja3VwUm91bmQyTXNnID0gZGVjcnlwdGVkQml0Z29Ub0JhY2t1cFJvdW5kMk1zZy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUFxuICAgICk7XG4gICAgYXNzZXJ0KHNlcmlhbGl6ZWRCaXRnb1RvQmFja3VwUm91bmQyTXNnLCAnQml0R28gdG8gQmFja3VwIG1lc3NhZ2UgMiBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgY29uc3QgYml0Z29Ub0JhY2t1cFJvdW5kMk1zZyA9IERrbHNUeXBlcy5kZXNlcmlhbGl6ZVAyUE1lc3NhZ2Uoc2VyaWFsaXplZEJpdGdvVG9CYWNrdXBSb3VuZDJNc2cpO1xuXG4gICAgY29uc3QgdXNlclRvQmFja3VwTXNnMiA9IHVzZXJSb3VuZDJQMlBNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSICYmIG0udG8gPT09IE1QQ3YyUGFydGllc0VudW0uQkFDS1VQXG4gICAgKTtcbiAgICBhc3NlcnQodXNlclRvQmFja3VwTXNnMiwgJ1VzZXIgdG8gQmFja3VwIG1lc3NhZ2UgMiBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG5cbiAgICBjb25zdCBiYWNrdXBUb1VzZXJNc2cyID0gYmFja3VwUm91bmQyUDJQTWVzc2FnZXMucDJwTWVzc2FnZXMuZmluZChcbiAgICAgIChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uQkFDS1VQICYmIG0udG8gPT09IE1QQ3YyUGFydGllc0VudW0uVVNFUlxuICAgICk7XG4gICAgYXNzZXJ0KGJhY2t1cFRvVXNlck1zZzIsICdCYWNrdXAgdG8gVXNlciBtZXNzYWdlIDIgbm90IGZvdW5kIGluIFAyUCBtZXNzYWdlcycpO1xuXG4gICAgY29uc3QgdXNlclJvdW5kM01lc3NhZ2VzID0gdXNlclNlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW10sXG4gICAgICBwMnBNZXNzYWdlczogW2JpdGdvVG9Vc2VyUm91bmQyTXNnLCBiYWNrdXBUb1VzZXJNc2cyXSxcbiAgICB9KTtcbiAgICBjb25zdCB1c2VyVG9CYWNrdXBNc2czID0gdXNlclJvdW5kM01lc3NhZ2VzLnAycE1lc3NhZ2VzLmZpbmQoXG4gICAgICAobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIgJiYgbS50byA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVBcbiAgICApO1xuICAgIGFzc2VydCh1c2VyVG9CYWNrdXBNc2czLCAnVXNlciB0byBCYWNrdXAgbWVzc2FnZSAzIG5vdCBmb3VuZCBpbiBQMlAgbWVzc2FnZXMnKTtcbiAgICBjb25zdCB1c2VyVG9CaXRnb01zZzMgPSB1c2VyUm91bmQzTWVzc2FnZXMucDJwTWVzc2FnZXMuZmluZChcbiAgICAgIChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uVVNFUiAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPXG4gICAgKTtcbiAgICBhc3NlcnQodXNlclRvQml0Z29Nc2czLCAnVXNlciB0byBCaXRnbyBtZXNzYWdlIDMgbm90IGZvdW5kIGluIFAyUCBtZXNzYWdlcycpO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRVc2VyVG9CaXRnb01zZzMgPSBEa2xzVHlwZXMuc2VyaWFsaXplUDJQTWVzc2FnZSh1c2VyVG9CaXRnb01zZzMpO1xuXG4gICAgY29uc3QgYmFja3VwUm91bmQzTWVzc2FnZXMgPSBiYWNrdXBTZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICAgICAgcDJwTWVzc2FnZXM6IFtiaXRnb1RvQmFja3VwUm91bmQyTXNnLCB1c2VyVG9CYWNrdXBNc2cyXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGJhY2t1cFRvVXNlck1zZzMgPSBiYWNrdXBSb3VuZDNNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAgJiYgbS50byA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSXG4gICAgKTtcbiAgICBhc3NlcnQoYmFja3VwVG9Vc2VyTXNnMywgJ0JhY2t1cCB0byBVc2VyIG1lc3NhZ2UgMyBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgY29uc3QgYmFja3VwVG9CaXRnb01zZzMgPSBiYWNrdXBSb3VuZDNNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAgJiYgbS50byA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHT1xuICAgICk7XG4gICAgYXNzZXJ0KGJhY2t1cFRvQml0Z29Nc2czLCAnQmFja3VwIHRvIEJpdGdvIG1lc3NhZ2UgMyBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgY29uc3Qgc2VyaWFsaXplZEJhY2t1cFRvQml0Z29Nc2czID0gRGtsc1R5cGVzLnNlcmlhbGl6ZVAyUE1lc3NhZ2UoYmFja3VwVG9CaXRnb01zZzMpO1xuXG4gICAgY29uc3QgZGVjcnlwdGVkQml0Z29Ub1VzZXJSb3VuZDNNZXNzYWdlcyA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgIHsgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLCBwMnBNZXNzYWdlczogW3RoaXMuZm9ybWF0UDJQTWVzc2FnZShiaXRnb1RvVXNlck1zZzMsIGJpdGdvQ29tbWl0bWVudDIpXSB9LFxuICAgICAgW2JpdGdvR3BnUHViS2V5XSxcbiAgICAgIFt1c2VyR3BnUHJ2S2V5XVxuICAgICk7XG4gICAgY29uc3Qgc2VyaWFsaXplZEJpdGdvVG9Vc2VyUm91bmQzTXNnID0gZGVjcnlwdGVkQml0Z29Ub1VzZXJSb3VuZDNNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVJcbiAgICApO1xuICAgIGFzc2VydChzZXJpYWxpemVkQml0Z29Ub1VzZXJSb3VuZDNNc2csICdCaXRHbyB0byBVc2VyIG1lc3NhZ2UgMyBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgY29uc3QgYml0Z29Ub1VzZXJSb3VuZDNNc2cgPSBEa2xzVHlwZXMuZGVzZXJpYWxpemVQMlBNZXNzYWdlKHNlcmlhbGl6ZWRCaXRnb1RvVXNlclJvdW5kM01zZyk7XG5cbiAgICBjb25zdCBkZWNyeXB0ZWRCaXRnb1RvQmFja3VwUm91bmQzTWVzc2FnZXMgPSBhd2FpdCBEa2xzQ29tbXMuZGVjcnlwdEFuZFZlcmlmeUluY29taW5nTWVzc2FnZXMoXG4gICAgICB7IGJyb2FkY2FzdE1lc3NhZ2VzOiBbXSwgcDJwTWVzc2FnZXM6IFt0aGlzLmZvcm1hdFAyUE1lc3NhZ2UoYml0Z29Ub0JhY2t1cE1zZzMsIGJpdGdvQ29tbWl0bWVudDIpXSB9LFxuICAgICAgW2JpdGdvR3BnUHViS2V5XSxcbiAgICAgIFtiYWNrdXBHcGdQcnZLZXldXG4gICAgKTtcbiAgICBjb25zdCBzZXJpYWxpemVkQml0Z29Ub0JhY2t1cFJvdW5kM01zZyA9IGRlY3J5cHRlZEJpdGdvVG9CYWNrdXBSb3VuZDNNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUFxuICAgICk7XG4gICAgYXNzZXJ0KHNlcmlhbGl6ZWRCaXRnb1RvQmFja3VwUm91bmQzTXNnLCAnQml0R28gdG8gQmFja3VwIG1lc3NhZ2UgMyBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgY29uc3QgYml0Z29Ub0JhY2t1cFJvdW5kM01zZyA9IERrbHNUeXBlcy5kZXNlcmlhbGl6ZVAyUE1lc3NhZ2Uoc2VyaWFsaXplZEJpdGdvVG9CYWNrdXBSb3VuZDNNc2cpO1xuXG4gICAgY29uc3QgdXNlclJvdW5kNE1lc3NhZ2VzID0gdXNlclNlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBwMnBNZXNzYWdlczogW2JhY2t1cFRvVXNlck1zZzMsIGJpdGdvVG9Vc2VyUm91bmQzTXNnXSxcbiAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHVzZXJSb3VuZDRCcm9hZGNhc3RNc2cgPSB1c2VyUm91bmQ0TWVzc2FnZXMuYnJvYWRjYXN0TWVzc2FnZXMuZmluZCgobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuICAgIGFzc2VydCh1c2VyUm91bmQ0QnJvYWRjYXN0TXNnLCAnVXNlciBtZXNzYWdlIDQgbm90IGZvdW5kIGluIGJyb2FkY2FzdCBtZXNzYWdlcycpO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRVc2VyUm91bmQ0QnJvYWRjYXN0TXNnID0gRGtsc1R5cGVzLnNlcmlhbGl6ZUJyb2FkY2FzdE1lc3NhZ2UodXNlclJvdW5kNEJyb2FkY2FzdE1zZyk7XG5cbiAgICBjb25zdCBiYWNrdXBSb3VuZDRNZXNzYWdlcyA9IGJhY2t1cFNlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBwMnBNZXNzYWdlczogW3VzZXJUb0JhY2t1cE1zZzMsIGJpdGdvVG9CYWNrdXBSb3VuZDNNc2ddLFxuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICAgIH0pO1xuICAgIGNvbnN0IGJhY2t1cFJvdW5kNEJyb2FkY2FzdE1zZyA9IGJhY2t1cFJvdW5kNE1lc3NhZ2VzLmJyb2FkY2FzdE1lc3NhZ2VzLmZpbmQoXG4gICAgICAobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUFxuICAgICk7XG4gICAgYXNzZXJ0KGJhY2t1cFJvdW5kNEJyb2FkY2FzdE1zZywgJ0JhY2t1cCBtZXNzYWdlIDQgbm90IGZvdW5kIGluIGJyb2FkY2FzdCBtZXNzYWdlcycpO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRCYWNrdXBSb3VuZDRCcm9hZGNhc3RNc2cgPSBEa2xzVHlwZXMuc2VyaWFsaXplQnJvYWRjYXN0TWVzc2FnZShiYWNrdXBSb3VuZDRCcm9hZGNhc3RNc2cpO1xuXG4gICAgY29uc3Qgcm91bmQzTWVzc2FnZXMgPSBhd2FpdCBEa2xzQ29tbXMuZW5jcnlwdEFuZEF1dGhPdXRnb2luZ01lc3NhZ2VzKFxuICAgICAge1xuICAgICAgICBwMnBNZXNzYWdlczogW3NlcmlhbGl6ZWRVc2VyVG9CaXRnb01zZzMsIHNlcmlhbGl6ZWRCYWNrdXBUb0JpdGdvTXNnM10sXG4gICAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbc2VyaWFsaXplZFVzZXJSb3VuZDRCcm9hZGNhc3RNc2csIHNlcmlhbGl6ZWRCYWNrdXBSb3VuZDRCcm9hZGNhc3RNc2ddLFxuICAgICAgfSxcbiAgICAgIFtiaXRnb0dwZ1B1YktleV0sXG4gICAgICBbdXNlckdwZ1BydktleSwgYmFja3VwR3BnUHJ2S2V5XVxuICAgICk7XG5cbiAgICBjb25zdCB7XG4gICAgICBzZXNzaW9uSWQ6IHNlc3Npb25JZFJvdW5kMyxcbiAgICAgIGJpdGdvTXNnNCxcbiAgICAgIGNvbW1vbktleWNoYWluOiBiaXRnb0NvbW1vbktleWNoYWluLFxuICAgIH0gPSBhd2FpdCB0aGlzLnNlbmRLZXlHZW5lcmF0aW9uUm91bmQzKHBhcmFtcy5lbnRlcnByaXNlLCBzZXNzaW9uSWQsIHJvdW5kM01lc3NhZ2VzKTtcblxuICAgIC8vICNlbmRyZWdpb25cblxuICAgIC8vICNyZWdpb24ga2V5Y2hhaW4gY3JlYXRpb25cbiAgICBhc3NlcnQuZXF1YWwoc2Vzc2lvbklkLCBzZXNzaW9uSWRSb3VuZDMsICdSb3VuZCAxIGFuZCAzIFNlc3Npb24gSURzIGRvIG5vdCBtYXRjaCcpO1xuICAgIGNvbnN0IGJpdGdvUm91bmQ0QnJvYWRjYXN0TWVzc2FnZXMgPSBEa2xzVHlwZXMuZGVzZXJpYWxpemVNZXNzYWdlcyhcbiAgICAgIGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgICAgeyBwMnBNZXNzYWdlczogW10sIGJyb2FkY2FzdE1lc3NhZ2VzOiBbdGhpcy5mb3JtYXRCaXRnb0Jyb2FkY2FzdE1lc3NhZ2UoYml0Z29Nc2c0KV0gfSxcbiAgICAgICAgW2JpdGdvR3BnUHViS2V5XSxcbiAgICAgICAgW11cbiAgICAgIClcbiAgICApLmJyb2FkY2FzdE1lc3NhZ2VzO1xuICAgIGNvbnN0IGJpdGdvUm91bmQ0QnJvYWRjYXN0TXNnID0gYml0Z29Sb3VuZDRCcm9hZGNhc3RNZXNzYWdlcy5maW5kKChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuXG4gICAgYXNzZXJ0KGJpdGdvUm91bmQ0QnJvYWRjYXN0TXNnLCAnQml0R28gbWVzc2FnZSA0IG5vdCBmb3VuZCBpbiBicm9hZGNhc3QgbWVzc2FnZXMnKTtcbiAgICB1c2VyU2Vzc2lvbi5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbYml0Z29Sb3VuZDRCcm9hZGNhc3RNc2csIGJhY2t1cFJvdW5kNEJyb2FkY2FzdE1zZ10sXG4gICAgfSk7XG5cbiAgICBiYWNrdXBTZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtiaXRnb1JvdW5kNEJyb2FkY2FzdE1zZywgdXNlclJvdW5kNEJyb2FkY2FzdE1zZ10sXG4gICAgfSk7XG5cbiAgICBjb25zdCB1c2VyUHJpdmF0ZU1hdGVyaWFsID0gdXNlclNlc3Npb24uZ2V0S2V5U2hhcmUoKTtcbiAgICBjb25zdCBiYWNrdXBQcml2YXRlTWF0ZXJpYWwgPSBiYWNrdXBTZXNzaW9uLmdldEtleVNoYXJlKCk7XG4gICAgY29uc3QgdXNlclJlZHVjZWRQcml2YXRlTWF0ZXJpYWwgPSB1c2VyU2Vzc2lvbi5nZXRSZWR1Y2VkS2V5U2hhcmUoKTtcbiAgICBjb25zdCBiYWNrdXBSZWR1Y2VkUHJpdmF0ZU1hdGVyaWFsID0gYmFja3VwU2Vzc2lvbi5nZXRSZWR1Y2VkS2V5U2hhcmUoKTtcblxuICAgIGNvbnN0IHVzZXJDb21tb25LZXljaGFpbiA9IERrbHNUeXBlcy5nZXRDb21tb25LZXljaGFpbih1c2VyUHJpdmF0ZU1hdGVyaWFsKTtcbiAgICBjb25zdCBiYWNrdXBDb21tb25LZXljaGFpbiA9IERrbHNUeXBlcy5nZXRDb21tb25LZXljaGFpbihiYWNrdXBQcml2YXRlTWF0ZXJpYWwpO1xuXG4gICAgYXNzZXJ0LmVxdWFsKGJpdGdvQ29tbW9uS2V5Y2hhaW4sIHVzZXJDb21tb25LZXljaGFpbiwgJ1VzZXIgYW5kIEJpdGdvIENvbW1vbiBrZXljaGFpbnMgZG8gbm90IG1hdGNoJyk7XG4gICAgYXNzZXJ0LmVxdWFsKGJpdGdvQ29tbW9uS2V5Y2hhaW4sIGJhY2t1cENvbW1vbktleWNoYWluLCAnQmFja3VwIGFuZCBCaXRnbyBDb21tb24ga2V5Y2hhaW5zIGRvIG5vdCBtYXRjaCcpO1xuXG4gICAgY29uc3QgdXNlcktleWNoYWluUHJvbWlzZSA9IHRoaXMuYWRkVXNlcktleWNoYWluKFxuICAgICAgYml0Z29Db21tb25LZXljaGFpbixcbiAgICAgIHVzZXJQcml2YXRlTWF0ZXJpYWwsXG4gICAgICB1c2VyUmVkdWNlZFByaXZhdGVNYXRlcmlhbCxcbiAgICAgIHBhcmFtcy5wYXNzcGhyYXNlLFxuICAgICAgcGFyYW1zLm9yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZVxuICAgICk7XG4gICAgY29uc3QgYmFja3VwS2V5Y2hhaW5Qcm9taXNlID0gdGhpcy5hZGRCYWNrdXBLZXljaGFpbihcbiAgICAgIGJpdGdvQ29tbW9uS2V5Y2hhaW4sXG4gICAgICB1c2VyUHJpdmF0ZU1hdGVyaWFsLFxuICAgICAgYmFja3VwUmVkdWNlZFByaXZhdGVNYXRlcmlhbCxcbiAgICAgIHBhcmFtcy5wYXNzcGhyYXNlLFxuICAgICAgcGFyYW1zLm9yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZVxuICAgICk7XG4gICAgY29uc3QgYml0Z29LZXljaGFpblByb21pc2UgPSB0aGlzLmFkZEJpdGdvS2V5Y2hhaW4oYml0Z29Db21tb25LZXljaGFpbik7XG5cbiAgICBjb25zdCBbdXNlcktleWNoYWluLCBiYWNrdXBLZXljaGFpbiwgYml0Z29LZXljaGFpbl0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICB1c2VyS2V5Y2hhaW5Qcm9taXNlLFxuICAgICAgYmFja3VwS2V5Y2hhaW5Qcm9taXNlLFxuICAgICAgYml0Z29LZXljaGFpblByb21pc2UsXG4gICAgXSk7XG4gICAgLy8gI2VuZHJlZ2lvblxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHVzZXJLZXljaGFpbixcbiAgICAgIGJhY2t1cEtleWNoYWluLFxuICAgICAgYml0Z29LZXljaGFpbixcbiAgICB9O1xuICB9XG5cbiAgLy8gI3JlZ2lvbiBrZXljaGFpbiB1dGlsc1xuICBhc3luYyBjcmVhdGVQYXJ0aWNpcGFudEtleWNoYWluKFxuICAgIHBhcnRpY2lwYW50SW5kZXg6IE1QQ3YyUGFydHlGcm9tU3RyaW5nT3JOdW1iZXIsXG4gICAgY29tbW9uS2V5Y2hhaW46IHN0cmluZyxcbiAgICBwcml2YXRlTWF0ZXJpYWw/OiBCdWZmZXIsXG4gICAgcmVkdWNlZFByaXZhdGVNYXRlcmlhbD86IEJ1ZmZlcixcbiAgICBwYXNzcGhyYXNlPzogc3RyaW5nLFxuICAgIG9yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZT86IHN0cmluZ1xuICApOiBQcm9taXNlPEtleWNoYWluPiB7XG4gICAgbGV0IHNvdXJjZTogc3RyaW5nO1xuICAgIGxldCBlbmNyeXB0ZWRQcnY6IHN0cmluZyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICBsZXQgcmVkdWNlZEVuY3J5cHRlZFBydjogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIHN3aXRjaCAocGFydGljaXBhbnRJbmRleCkge1xuICAgICAgY2FzZSBNUEN2MlBhcnRpZXNFbnVtLlVTRVI6XG4gICAgICBjYXNlIE1QQ3YyUGFydGllc0VudW0uQkFDS1VQOlxuICAgICAgICBzb3VyY2UgPSBwYXJ0aWNpcGFudEluZGV4ID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIgPyAndXNlcicgOiAnYmFja3VwJztcbiAgICAgICAgYXNzZXJ0KHByaXZhdGVNYXRlcmlhbCwgYFByaXZhdGUgbWF0ZXJpYWwgaXMgcmVxdWlyZWQgZm9yICR7c291cmNlfSBrZXljaGFpbmApO1xuICAgICAgICBhc3NlcnQocmVkdWNlZFByaXZhdGVNYXRlcmlhbCwgYFJlZHVjZWQgcHJpdmF0ZSBtYXRlcmlhbCBpcyByZXF1aXJlZCBmb3IgJHtzb3VyY2V9IGtleWNoYWluYCk7XG4gICAgICAgIGFzc2VydChwYXNzcGhyYXNlLCBgUGFzc3BocmFzZSBpcyByZXF1aXJlZCBmb3IgJHtzb3VyY2V9IGtleWNoYWluYCk7XG4gICAgICAgIGVuY3J5cHRlZFBydiA9IHRoaXMuYml0Z28uZW5jcnlwdCh7XG4gICAgICAgICAgaW5wdXQ6IHByaXZhdGVNYXRlcmlhbC50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICAgICAgcGFzc3dvcmQ6IHBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuICAgICAgICByZWR1Y2VkRW5jcnlwdGVkUHJ2ID0gdGhpcy5iaXRnby5lbmNyeXB0KHtcbiAgICAgICAgICAvLyBCdWZmZXIudG9TdHJpbmcoJ2Jhc2U2NCcpIGNhbiBub3QgYmUgdXNlZCBoZXJlIGFzIGl0IGRvZXMgbm90IHdvcmsgb24gdGhlIGJyb3dzZXIuXG4gICAgICAgICAgLy8gVGhlIGJyb3dzZXIgZGVhbHMgd2l0aCBhIEJ1ZmZlciBhcyBVaW50OEFycmF5LCB0aGVyZWZvcmUgaW4gdGhlIGJyb3dzZXIgLnRvU3RyaW5nKCdiYXNlNjQnKSBqdXN0IGNyZWF0ZXMgYSBjb21tYSBzZXBlcmF0ZWQgc3RyaW5nIG9mIHRoZSBhcnJheSB2YWx1ZXMuXG4gICAgICAgICAgaW5wdXQ6IGJ0b2EoU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBBcnJheS5mcm9tKG5ldyBVaW50OEFycmF5KHJlZHVjZWRQcml2YXRlTWF0ZXJpYWwpKSkpLFxuICAgICAgICAgIHBhc3N3b3JkOiBwYXNzcGhyYXNlLFxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIE1QQ3YyUGFydGllc0VudW0uQklUR086XG4gICAgICAgIHNvdXJjZSA9ICdiaXRnbyc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHBhcnRpY2lwYW50IGluZGV4Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVjaXBpZW50S2V5Y2hhaW5QYXJhbXM6IEFkZEtleWNoYWluT3B0aW9ucyA9IHtcbiAgICAgIHNvdXJjZSxcbiAgICAgIGtleVR5cGU6ICd0c3MnIGFzIEtleVR5cGUsXG4gICAgICBjb21tb25LZXljaGFpbixcbiAgICAgIGVuY3J5cHRlZFBydixcbiAgICAgIG9yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZSxcbiAgICAgIGlzTVBDdjI6IHRydWUsXG4gICAgfTtcblxuICAgIGNvbnN0IGtleWNoYWlucyA9IHRoaXMuYmFzZUNvaW4ua2V5Y2hhaW5zKCk7XG4gICAgcmV0dXJuIHsgLi4uKGF3YWl0IGtleWNoYWlucy5hZGQocmVjaXBpZW50S2V5Y2hhaW5QYXJhbXMpKSwgcmVkdWNlZEVuY3J5cHRlZFBydjogcmVkdWNlZEVuY3J5cHRlZFBydiB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGEgVXNlciBvciBCYWNrdXAgTVBDdjEgU2lnbmluZ01hdGVyaWFsIHRvIFJldHJvZml0RGF0YSBuZWVkZWQgYnkgTVBDdjIgREtHLlxuICAgKlxuICAgKiBAcGFyYW0gZGVjcnlwdGVkS2V5c2hhcmUgLSBNUEN2MSBkZWNyeXB0ZWQgc2lnbmluZyBtYXRlcmlhbCBmb3IgdXNlciBvciBiYWNrdXAgYXMgYSBqc29uLnN0cmluZ2lmeSBzdHJpbmcgYW5kIGJpdGdvJ3MgQmlnIFNpLlxuICAgKiBAcGFyYW0gcGFydHlJZCAtIFRoZSBwYXJ0eSBJRCBvZiB0aGUgTVBDdjEga2V5c2hhcmUuXG4gICAqIEByZXR1cm5zIFRoZSByZXRyb2ZpdCBkYXRhIG5lZWRlZCB0byBzdGFydCBhbiBNUEN2MiBES0cgc2Vzc2lvbi5cbiAgICogQGRlcHJlY2F0ZWRcbiAgICovXG4gIHN0YXRpYyBnZXRLZXlEYXRhRm9yUmV0cm9maXQoXG4gICAgZGVjcnlwdGVkS2V5c2hhcmU6IHN0cmluZyxcbiAgICBwYXJ0eUlkOiBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCB8IE1QQ3YyUGFydGllc0VudW0uVVNFUlxuICApOiBEa2xzVHlwZXMuUmV0cm9maXREYXRhIHtcbiAgICBjb25zdCBtcGMgPSBuZXcgRWNkc2EoKTtcbiAgICBjb25zdCB4aUxpc3QgPSBbXG4gICAgICBBcnJheS5mcm9tKGJpZ0ludFRvQnVmZmVyQkUoQmlnSW50KDEpLCAzMikpLFxuICAgICAgQXJyYXkuZnJvbShiaWdJbnRUb0J1ZmZlckJFKEJpZ0ludCgyKSwgMzIpKSxcbiAgICAgIEFycmF5LmZyb20oYmlnSW50VG9CdWZmZXJCRShCaWdJbnQoMyksIDMyKSksXG4gICAgXTtcbiAgICByZXR1cm4gRWNkc2FNUEN2MlV0aWxzLmdldE1wY1YyUmV0cm9maXREYXRhRnJvbU1wY1YxS2V5KHtcbiAgICAgIG1wY3YxUGFydHlLZXlTaGFyZTogZGVjcnlwdGVkS2V5c2hhcmUsXG4gICAgICBtcGN2MVBhcnR5SW5kZXg6IHBhcnR5SWQgPT09IE1QQ3YyUGFydGllc0VudW0uVVNFUiA/IDEgOiAyLFxuICAgICAgeGlMaXN0LFxuICAgICAgbXBjLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIHVzZXIgYW5kIGJhY2t1cCBNUEN2MSBTaWduaW5nTWF0ZXJpYWwgdG8gUmV0cm9maXREYXRhIG5lZWRlZCBieSBNUEN2MiBES0cuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgLSBNUEN2MSBkZWNyeXB0ZWQgc2lnbmluZyBtYXRlcmlhbCBmb3IgdXNlciBhbmQgYmFja3VwIGFzIGEganNvbi5zdHJpbmdpZnkgc3RyaW5nIGFuZCBiaXRnbydzIEJpZyBTaS5cbiAgICogQHJldHVybnMge3sgbXBjdjJVc2VyS2V5U2hhcmU6IERrbHNUeXBlcy5SZXRyb2ZpdERhdGE7IG1wY3YyQmFrY3VwS2V5U2hhcmU6IERrbHNUeXBlcy5SZXRyb2ZpdERhdGEgfX0gLSB0aGUgcmV0cm9maXQgZGF0YSBuZWVkZWQgdG8gc3RhcnQgYW4gTVBDdjIgREtHIHNlc3Npb24uXG4gICAqL1xuICBnZXRNcGNWMlJldHJvZml0RGF0YUZyb21NcGNWMUtleXMocGFyYW1zOiB7IG1wY3YxVXNlcktleVNoYXJlOiBzdHJpbmc7IG1wY3YxQmFja3VwS2V5U2hhcmU6IHN0cmluZyB9KToge1xuICAgIG1wY3YyVXNlcktleVNoYXJlOiBEa2xzVHlwZXMuUmV0cm9maXREYXRhO1xuICAgIG1wY3YyQmFja3VwS2V5U2hhcmU6IERrbHNUeXBlcy5SZXRyb2ZpdERhdGE7XG4gIH0ge1xuICAgIGNvbnN0IG1wYyA9IG5ldyBFY2RzYSgpO1xuICAgIGNvbnN0IHhpTGlzdCA9IFtcbiAgICAgIEFycmF5LmZyb20oYmlnSW50VG9CdWZmZXJCRShCaWdJbnQoMSksIDMyKSksXG4gICAgICBBcnJheS5mcm9tKGJpZ0ludFRvQnVmZmVyQkUoQmlnSW50KDIpLCAzMikpLFxuICAgICAgQXJyYXkuZnJvbShiaWdJbnRUb0J1ZmZlckJFKEJpZ0ludCgzKSwgMzIpKSxcbiAgICBdO1xuICAgIHJldHVybiB7XG4gICAgICBtcGN2MlVzZXJLZXlTaGFyZTogRWNkc2FNUEN2MlV0aWxzLmdldE1wY1YyUmV0cm9maXREYXRhRnJvbU1wY1YxS2V5KHtcbiAgICAgICAgbXBjdjFQYXJ0eUtleVNoYXJlOiBwYXJhbXMubXBjdjFVc2VyS2V5U2hhcmUsXG4gICAgICAgIG1wY3YxUGFydHlJbmRleDogMSxcbiAgICAgICAgeGlMaXN0LFxuICAgICAgICBtcGMsXG4gICAgICB9KSxcbiAgICAgIG1wY3YyQmFja3VwS2V5U2hhcmU6IEVjZHNhTVBDdjJVdGlscy5nZXRNcGNWMlJldHJvZml0RGF0YUZyb21NcGNWMUtleSh7XG4gICAgICAgIG1wY3YxUGFydHlLZXlTaGFyZTogcGFyYW1zLm1wY3YxQmFja3VwS2V5U2hhcmUsXG4gICAgICAgIG1wY3YxUGFydHlJbmRleDogMixcbiAgICAgICAgeGlMaXN0LFxuICAgICAgICBtcGMsXG4gICAgICB9KSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCByZXRyb2ZpdCBkYXRhIGZyb20gTVBDdjEga2V5IHNoYXJlLlxuICAgKiBAcGFyYW0gbXBjdjFQYXJ0eUtleVNoYXJlXG4gICAqIEBwYXJhbSBtcGN2MVBhcnR5SW5kZXhcbiAgICogQHBhcmFtIHhpTGlzdFxuICAgKiBAcGFyYW0gbXBjXG4gICAqIEBkZXByZWNhdGVkXG4gICAqL1xuICBzdGF0aWMgZ2V0TXBjVjJSZXRyb2ZpdERhdGFGcm9tTXBjVjFLZXkoe1xuICAgIG1wY3YxUGFydHlLZXlTaGFyZSxcbiAgICBtcGN2MVBhcnR5SW5kZXgsXG4gICAgeGlMaXN0LFxuICAgIG1wYyxcbiAgfToge1xuICAgIG1wY3YxUGFydHlLZXlTaGFyZTogc3RyaW5nO1xuICAgIG1wY3YxUGFydHlJbmRleDogbnVtYmVyO1xuICAgIHhpTGlzdDogbnVtYmVyW11bXTtcbiAgICBtcGM6IEVjZHNhO1xuICB9KTogRGtsc1R5cGVzLlJldHJvZml0RGF0YSB7XG4gICAgY29uc3Qgc2lnbmluZ01hdGVyaWFsOiBFQ0RTQU1ldGhvZFR5cGVzLlNpZ25pbmdNYXRlcmlhbCA9IEpTT04ucGFyc2UobXBjdjFQYXJ0eUtleVNoYXJlKTtcbiAgICBsZXQga2V5Q29tYmluZWQ6IEtleUNvbWJpbmVkIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIHN3aXRjaCAobXBjdjFQYXJ0eUluZGV4KSB7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIGFzc2VydChzaWduaW5nTWF0ZXJpYWwuYmFja3VwTlNoYXJlLCAnVXNlciBNUEN2MSBrZXkgbWF0ZXJpYWwgc2hvdWxkIGhhdmUgYmFja3VwIE5TaGFyZS4nKTtcbiAgICAgICAgYXNzZXJ0KHNpZ25pbmdNYXRlcmlhbC5iaXRnb05TaGFyZSwgJ0JpdEdvIE1QQ3YxIGtleSBtYXRlcmlhbCBzaG91bGQgaGF2ZSB1c2VyIE5TaGFyZS4nKTtcbiAgICAgICAga2V5Q29tYmluZWQgPSBtcGMua2V5Q29tYmluZShzaWduaW5nTWF0ZXJpYWwucFNoYXJlLCBbXG4gICAgICAgICAgc2lnbmluZ01hdGVyaWFsLmJhY2t1cE5TaGFyZSxcbiAgICAgICAgICBzaWduaW5nTWF0ZXJpYWwuYml0Z29OU2hhcmUsXG4gICAgICAgIF0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgYXNzZXJ0KHNpZ25pbmdNYXRlcmlhbC51c2VyTlNoYXJlLCAnVXNlciBNUEN2MSBrZXkgbWF0ZXJpYWwgc2hvdWxkIGhhdmUgYmFja3VwIE5TaGFyZS4nKTtcbiAgICAgICAgYXNzZXJ0KHNpZ25pbmdNYXRlcmlhbC5iaXRnb05TaGFyZSwgJ0JpdEdvIE1QQ3YxIGtleSBtYXRlcmlhbCBzaG91bGQgaGF2ZSB1c2VyIE5TaGFyZS4nKTtcbiAgICAgICAga2V5Q29tYmluZWQgPSBtcGMua2V5Q29tYmluZShzaWduaW5nTWF0ZXJpYWwucFNoYXJlLCBbc2lnbmluZ01hdGVyaWFsLnVzZXJOU2hhcmUsIHNpZ25pbmdNYXRlcmlhbC5iaXRnb05TaGFyZV0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgYXNzZXJ0KHNpZ25pbmdNYXRlcmlhbC51c2VyTlNoYXJlLCAnVXNlciBNUEN2MSBrZXkgbWF0ZXJpYWwgc2hvdWxkIGhhdmUgYmFja3VwIE5TaGFyZS4nKTtcbiAgICAgICAgYXNzZXJ0KHNpZ25pbmdNYXRlcmlhbC5iYWNrdXBOU2hhcmUsICdCYWNrdXAgTVBDdjEga2V5IG1hdGVyaWFsIHNob3VsZCBoYXZlIHVzZXIgTlNoYXJlLicpO1xuICAgICAgICBrZXlDb21iaW5lZCA9IG1wYy5rZXlDb21iaW5lKHNpZ25pbmdNYXRlcmlhbC5wU2hhcmUsIFtcbiAgICAgICAgICBzaWduaW5nTWF0ZXJpYWwudXNlck5TaGFyZSxcbiAgICAgICAgICBzaWduaW5nTWF0ZXJpYWwuYmFja3VwTlNoYXJlLFxuICAgICAgICBdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgcGFydGljaXBhbnQgaW5kZXgnKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHhTaGFyZToga2V5Q29tYmluZWQueFNoYXJlLFxuICAgICAgeGlMaXN0OiB4aUxpc3QsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgYWRkVXNlcktleWNoYWluKFxuICAgIGNvbW1vbktleWNoYWluOiBzdHJpbmcsXG4gICAgcHJpdmF0ZU1hdGVyaWFsOiBCdWZmZXIsXG4gICAgcmVkdWNlZFByaXZhdGVNYXRlcmlhbDogQnVmZmVyLFxuICAgIHBhc3NwaHJhc2U6IHN0cmluZyxcbiAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGU/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxLZXljaGFpbj4ge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZVBhcnRpY2lwYW50S2V5Y2hhaW4oXG4gICAgICBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsXG4gICAgICBjb21tb25LZXljaGFpbixcbiAgICAgIHByaXZhdGVNYXRlcmlhbCxcbiAgICAgIHJlZHVjZWRQcml2YXRlTWF0ZXJpYWwsXG4gICAgICBwYXNzcGhyYXNlLFxuICAgICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgYWRkQmFja3VwS2V5Y2hhaW4oXG4gICAgY29tbW9uS2V5Y2hhaW46IHN0cmluZyxcbiAgICBwcml2YXRlTWF0ZXJpYWw6IEJ1ZmZlcixcbiAgICByZWR1Y2VkUHJpdmF0ZU1hdGVyaWFsOiBCdWZmZXIsXG4gICAgcGFzc3BocmFzZTogc3RyaW5nLFxuICAgIG9yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZT86IHN0cmluZ1xuICApOiBQcm9taXNlPEtleWNoYWluPiB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlUGFydGljaXBhbnRLZXljaGFpbihcbiAgICAgIE1QQ3YyUGFydGllc0VudW0uQkFDS1VQLFxuICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICBwcml2YXRlTWF0ZXJpYWwsXG4gICAgICByZWR1Y2VkUHJpdmF0ZU1hdGVyaWFsLFxuICAgICAgcGFzc3BocmFzZSxcbiAgICAgIG9yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGdldFVzZXJBbmRCYWNrdXBTZXNzaW9uKG06IG51bWJlciwgbjogbnVtYmVyLCByZXRyb2ZpdD86IERlY3J5cHRlZFJldHJvZml0UGF5bG9hZCkge1xuICAgIGlmIChyZXRyb2ZpdCkge1xuICAgICAgY29uc3QgcmV0cm9maXREYXRhID0gdGhpcy5nZXRNcGNWMlJldHJvZml0RGF0YUZyb21NcGNWMUtleXMoe1xuICAgICAgICBtcGN2MVVzZXJLZXlTaGFyZTogcmV0cm9maXQuZGVjcnlwdGVkVXNlcktleSxcbiAgICAgICAgbXBjdjFCYWNrdXBLZXlTaGFyZTogcmV0cm9maXQuZGVjcnlwdGVkQmFja3VwS2V5LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHVzZXJTZXNzaW9uID0gbmV3IERrbHNEa2cuRGtnKG4sIG0sIE1QQ3YyUGFydGllc0VudW0uVVNFUiwgdW5kZWZpbmVkLCByZXRyb2ZpdERhdGEubXBjdjJVc2VyS2V5U2hhcmUpO1xuICAgICAgY29uc3QgYmFja3VwU2Vzc2lvbiA9IG5ldyBEa2xzRGtnLkRrZyhuLCBtLCBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCwgdW5kZWZpbmVkLCByZXRyb2ZpdERhdGEubXBjdjJCYWNrdXBLZXlTaGFyZSk7XG5cbiAgICAgIHJldHVybiB7IHVzZXJTZXNzaW9uLCBiYWNrdXBTZXNzaW9uIH07XG4gICAgfVxuXG4gICAgY29uc3QgdXNlclNlc3Npb24gPSBuZXcgRGtsc0RrZy5Ea2cobiwgbSwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcbiAgICBjb25zdCBiYWNrdXBTZXNzaW9uID0gbmV3IERrbHNEa2cuRGtnKG4sIG0sIE1QQ3YyUGFydGllc0VudW0uQkFDS1VQKTtcblxuICAgIHJldHVybiB7IHVzZXJTZXNzaW9uLCBiYWNrdXBTZXNzaW9uIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGFkZEJpdGdvS2V5Y2hhaW4oY29tbW9uS2V5Y2hhaW46IHN0cmluZyk6IFByb21pc2U8S2V5Y2hhaW4+IHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVQYXJ0aWNpcGFudEtleWNoYWluKE1QQ3YyUGFydGllc0VudW0uQklUR08sIGNvbW1vbktleWNoYWluKTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uXG5cbiAgYXN5bmMgc2VuZEtleUdlbmVyYXRpb25Sb3VuZDEoXG4gICAgZW50ZXJwcmlzZTogc3RyaW5nLFxuICAgIHVzZXJHcGdQdWJsaWNLZXk6IHN0cmluZyxcbiAgICBiYWNrdXBHcGdQdWJsaWNLZXk6IHN0cmluZyxcbiAgICBwYXlsb2FkOiBEa2xzVHlwZXMuQXV0aEVuY01lc3NhZ2VzICYgeyB3YWxsZXRJZD86IHN0cmluZyB9XG4gICk6IFByb21pc2U8TVBDdjJLZXlHZW5Sb3VuZDFSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnNlbmRLZXlHZW5lcmF0aW9uUm91bmQxQnlTZW5kZXIoXG4gICAgICBLZXlHZW5TZW5kZXJGb3JFbnRlcnByaXNlKHRoaXMuYml0Z28sIGVudGVycHJpc2UpLFxuICAgICAgdXNlckdwZ1B1YmxpY0tleSxcbiAgICAgIGJhY2t1cEdwZ1B1YmxpY0tleSxcbiAgICAgIHBheWxvYWRcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgc2VuZEtleUdlbmVyYXRpb25Sb3VuZDIoXG4gICAgZW50ZXJwcmlzZTogc3RyaW5nLFxuICAgIHNlc3Npb25JZDogc3RyaW5nLFxuICAgIHBheWxvYWQ6IERrbHNUeXBlcy5BdXRoRW5jTWVzc2FnZXNcbiAgKTogUHJvbWlzZTxNUEN2MktleUdlblJvdW5kMlJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMuc2VuZEtleUdlbmVyYXRpb25Sb3VuZDJCeVNlbmRlcihLZXlHZW5TZW5kZXJGb3JFbnRlcnByaXNlKHRoaXMuYml0Z28sIGVudGVycHJpc2UpLCBzZXNzaW9uSWQsIHBheWxvYWQpO1xuICB9XG5cbiAgYXN5bmMgc2VuZEtleUdlbmVyYXRpb25Sb3VuZDMoXG4gICAgZW50ZXJwcmlzZTogc3RyaW5nLFxuICAgIHNlc3Npb25JZDogc3RyaW5nLFxuICAgIHBheWxvYWQ6IERrbHNUeXBlcy5BdXRoRW5jTWVzc2FnZXNcbiAgKTogUHJvbWlzZTxNUEN2MktleUdlblJvdW5kM1Jlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMuc2VuZEtleUdlbmVyYXRpb25Sb3VuZDNCeVNlbmRlcihLZXlHZW5TZW5kZXJGb3JFbnRlcnByaXNlKHRoaXMuYml0Z28sIGVudGVycHJpc2UpLCBzZXNzaW9uSWQsIHBheWxvYWQpO1xuICB9XG5cbiAgYXN5bmMgc2VuZEtleUdlbmVyYXRpb25Sb3VuZDFCeVNlbmRlcihcbiAgICBzZW5kZXJGbjogRWNkc2FNUEN2MktleUdlblNlbmRGbjxNUEN2MktleUdlblJvdW5kMVJlc3BvbnNlPixcbiAgICB1c2VyR3BnUHVibGljS2V5OiBzdHJpbmcsXG4gICAgYmFja3VwR3BnUHVibGljS2V5OiBzdHJpbmcsXG4gICAgcGF5bG9hZDogRGtsc1R5cGVzLkF1dGhFbmNNZXNzYWdlcyAmIHsgd2FsbGV0SWQ/OiBzdHJpbmcgfVxuICApOiBQcm9taXNlPE1QQ3YyS2V5R2VuUm91bmQxUmVzcG9uc2U+IHtcbiAgICBhc3NlcnQoTm9uRW1wdHlTdHJpbmcuaXModXNlckdwZ1B1YmxpY0tleSksICdVc2VyIEdQRyBwdWJsaWMga2V5IGlzIHJlcXVpcmVkJyk7XG4gICAgYXNzZXJ0KE5vbkVtcHR5U3RyaW5nLmlzKGJhY2t1cEdwZ1B1YmxpY0tleSksICdCYWNrdXAgR1BHIHB1YmxpYyBrZXkgaXMgcmVxdWlyZWQnKTtcbiAgICBjb25zdCB1c2VyTXNnMSA9IHBheWxvYWQuYnJvYWRjYXN0TWVzc2FnZXMuZmluZCgobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpPy5wYXlsb2FkO1xuICAgIGFzc2VydCh1c2VyTXNnMSwgJ1VzZXIgbWVzc2FnZSAxIG5vdCBmb3VuZCBpbiBicm9hZGNhc3QgbWVzc2FnZXMnKTtcbiAgICBjb25zdCBiYWNrdXBNc2cxID0gcGF5bG9hZC5icm9hZGNhc3RNZXNzYWdlcy5maW5kKChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uQkFDS1VQKT8ucGF5bG9hZDtcbiAgICBhc3NlcnQoYmFja3VwTXNnMSwgJ0JhY2t1cCBtZXNzYWdlIDEgbm90IGZvdW5kIGluIGJyb2FkY2FzdCBtZXNzYWdlcycpO1xuXG4gICAgcmV0dXJuIHNlbmRlckZuKE1QQ3YyS2V5R2VuU3RhdGVFbnVtWydNUEN2Mi1SMSddLCB7XG4gICAgICB1c2VyR3BnUHVibGljS2V5LFxuICAgICAgYmFja3VwR3BnUHVibGljS2V5LFxuICAgICAgdXNlck1zZzE6IHsgZnJvbTogMCwgLi4udXNlck1zZzEgfSxcbiAgICAgIGJhY2t1cE1zZzE6IHsgZnJvbTogMSwgLi4uYmFja3VwTXNnMSB9LFxuICAgICAgd2FsbGV0SWQ6IHBheWxvYWQud2FsbGV0SWQsXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBzZW5kS2V5R2VuZXJhdGlvblJvdW5kMkJ5U2VuZGVyKFxuICAgIHNlbmRlckZuOiBFY2RzYU1QQ3YyS2V5R2VuU2VuZEZuPE1QQ3YyS2V5R2VuUm91bmQyUmVzcG9uc2U+LFxuICAgIHNlc3Npb25JZDogc3RyaW5nLFxuICAgIHBheWxvYWQ6IERrbHNUeXBlcy5BdXRoRW5jTWVzc2FnZXNcbiAgKTogUHJvbWlzZTxNUEN2MktleUdlblJvdW5kMlJlc3BvbnNlPiB7XG4gICAgYXNzZXJ0KE5vbkVtcHR5U3RyaW5nLmlzKHNlc3Npb25JZCksICdTZXNzaW9uIElEIGlzIHJlcXVpcmVkJyk7XG4gICAgY29uc3QgdXNlck1zZzIgPSBwYXlsb2FkLnAycE1lc3NhZ2VzLmZpbmQoXG4gICAgICAobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIgJiYgbS50byA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHT1xuICAgICk7XG4gICAgYXNzZXJ0KHVzZXJNc2cyLCAnVXNlciB0byBCaXRnbyBtZXNzYWdlIDIgbm90IGZvdW5kIGluIFAyUCBtZXNzYWdlcycpO1xuICAgIGFzc2VydCh1c2VyTXNnMi5jb21taXRtZW50LCAnVXNlciB0byBCaXRnbyBjb21taXRtZW50IG5vdCBmb3VuZCBpbiBQMlAgbWVzc2FnZXMnKTtcbiAgICBhc3NlcnQoTm9uRW1wdHlTdHJpbmcuaXModXNlck1zZzIuY29tbWl0bWVudCksICdVc2VyIHRvIEJpdGdvIGNvbW1pdG1lbnQgaXMgcmVxdWlyZWQnKTtcbiAgICBjb25zdCBiYWNrdXBNc2cyID0gcGF5bG9hZC5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAgJiYgbS50byA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHT1xuICAgICk7XG4gICAgYXNzZXJ0KGJhY2t1cE1zZzIsICdCYWNrdXAgdG8gQml0Z28gbWVzc2FnZSAyIG5vdCBmb3VuZCBpbiBQMlAgbWVzc2FnZXMnKTtcbiAgICBhc3NlcnQoYmFja3VwTXNnMi5jb21taXRtZW50LCAnQmFja3VwIHRvIEJpdGdvIGNvbW1pdG1lbnQgbm90IGZvdW5kIGluIFAyUCBtZXNzYWdlcycpO1xuICAgIGFzc2VydChOb25FbXB0eVN0cmluZy5pcyhiYWNrdXBNc2cyLmNvbW1pdG1lbnQpLCAnQmFja3VwIHRvIEJpdGdvIGNvbW1pdG1lbnQgaXMgcmVxdWlyZWQnKTtcblxuICAgIHJldHVybiBzZW5kZXJGbihNUEN2MktleUdlblN0YXRlRW51bVsnTVBDdjItUjInXSwge1xuICAgICAgc2Vzc2lvbklkLFxuICAgICAgdXNlck1zZzI6IHtcbiAgICAgICAgZnJvbTogTVBDdjJQYXJ0aWVzRW51bS5VU0VSLFxuICAgICAgICB0bzogTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyxcbiAgICAgICAgc2lnbmF0dXJlOiB1c2VyTXNnMi5wYXlsb2FkLnNpZ25hdHVyZSxcbiAgICAgICAgZW5jcnlwdGVkTWVzc2FnZTogdXNlck1zZzIucGF5bG9hZC5lbmNyeXB0ZWRNZXNzYWdlLFxuICAgICAgfSxcbiAgICAgIHVzZXJDb21taXRtZW50MjogdXNlck1zZzIuY29tbWl0bWVudCxcbiAgICAgIGJhY2t1cE1zZzI6IHtcbiAgICAgICAgZnJvbTogTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAsXG4gICAgICAgIHRvOiBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPLFxuICAgICAgICBzaWduYXR1cmU6IGJhY2t1cE1zZzIucGF5bG9hZC5zaWduYXR1cmUsXG4gICAgICAgIGVuY3J5cHRlZE1lc3NhZ2U6IGJhY2t1cE1zZzIucGF5bG9hZC5lbmNyeXB0ZWRNZXNzYWdlLFxuICAgICAgfSxcbiAgICAgIGJhY2t1cENvbW1pdG1lbnQyOiBiYWNrdXBNc2cyLmNvbW1pdG1lbnQsXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBzZW5kS2V5R2VuZXJhdGlvblJvdW5kM0J5U2VuZGVyKFxuICAgIHNlbmRlckZuOiBFY2RzYU1QQ3YyS2V5R2VuU2VuZEZuPE1QQ3YyS2V5R2VuUm91bmQzUmVzcG9uc2U+LFxuICAgIHNlc3Npb25JZDogc3RyaW5nLFxuICAgIHBheWxvYWQ6IERrbHNUeXBlcy5BdXRoRW5jTWVzc2FnZXNcbiAgKTogUHJvbWlzZTxNUEN2MktleUdlblJvdW5kM1Jlc3BvbnNlPiB7XG4gICAgYXNzZXJ0KE5vbkVtcHR5U3RyaW5nLmlzKHNlc3Npb25JZCksICdTZXNzaW9uIElEIGlzIHJlcXVpcmVkJyk7XG4gICAgY29uc3QgdXNlck1zZzMgPSBwYXlsb2FkLnAycE1lc3NhZ2VzLmZpbmQoXG4gICAgICAobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIgJiYgbS50byA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHT1xuICAgICk/LnBheWxvYWQ7XG4gICAgYXNzZXJ0KHVzZXJNc2czLCAnVXNlciB0byBCaXRnbyBtZXNzYWdlIDMgbm90IGZvdW5kIGluIFAyUCBtZXNzYWdlcycpO1xuICAgIGNvbnN0IGJhY2t1cE1zZzMgPSBwYXlsb2FkLnAycE1lc3NhZ2VzLmZpbmQoXG4gICAgICAobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPXG4gICAgKT8ucGF5bG9hZDtcbiAgICBhc3NlcnQoYmFja3VwTXNnMywgJ0JhY2t1cCB0byBCaXRnbyBtZXNzYWdlIDMgbm90IGZvdW5kIGluIFAyUCBtZXNzYWdlcycpO1xuICAgIGNvbnN0IHVzZXJNc2c0ID0gcGF5bG9hZC5icm9hZGNhc3RNZXNzYWdlcy5maW5kKChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uVVNFUik/LnBheWxvYWQ7XG4gICAgYXNzZXJ0KHVzZXJNc2c0LCAnVXNlciBtZXNzYWdlIDEgbm90IGZvdW5kIGluIGJyb2FkY2FzdCBtZXNzYWdlcycpO1xuICAgIGNvbnN0IGJhY2t1cE1zZzQgPSBwYXlsb2FkLmJyb2FkY2FzdE1lc3NhZ2VzLmZpbmQoKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVApPy5wYXlsb2FkO1xuICAgIGFzc2VydChiYWNrdXBNc2c0LCAnQmFja3VwIG1lc3NhZ2UgMSBub3QgZm91bmQgaW4gYnJvYWRjYXN0IG1lc3NhZ2VzJyk7XG5cbiAgICByZXR1cm4gc2VuZGVyRm4oTVBDdjJLZXlHZW5TdGF0ZUVudW1bJ01QQ3YyLVIzJ10sIHtcbiAgICAgIHNlc3Npb25JZCxcbiAgICAgIHVzZXJNc2czOiB7IGZyb206IDAsIHRvOiAyLCAuLi51c2VyTXNnMyB9LFxuICAgICAgYmFja3VwTXNnMzogeyBmcm9tOiAxLCB0bzogMiwgLi4uYmFja3VwTXNnMyB9LFxuICAgICAgdXNlck1zZzQ6IHsgZnJvbTogMCwgLi4udXNlck1zZzQgfSxcbiAgICAgIGJhY2t1cE1zZzQ6IHsgZnJvbTogMSwgLi4uYmFja3VwTXNnNCB9LFxuICAgIH0pO1xuICB9XG5cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gc2lnbiB0eCByZXF1ZXN0XG5cbiAgLyoqXG4gICAqIFNpZ25zIHRoZSB0cmFuc2FjdGlvbiBhc3NvY2lhdGVkIHRvIHRoZSB0cmFuc2FjdGlvbiByZXF1ZXN0LlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IFR4UmVxdWVzdH0gcGFyYW1zLnR4UmVxdWVzdCAtIHRyYW5zYWN0aW9uIHJlcXVlc3Qgb2JqZWN0IG9yIGlkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXJhbXMucHJ2IC0gZGVjcnlwdGVkIHByaXZhdGUga2V5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXJhbXMucmVxSWQgLSByZXF1ZXN0IGlkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXJhbXMubXBjdjJQYXJ0eUlkIC0gcGFydHkgaWQgZm9yIHRoZSBzaWduZXIgaW52b2x2ZWQgaW4gdGhpcyBtcGN2MiByZXF1ZXN0IChlaXRoZXIgMCBmb3IgdXNlciBvciAxIGZvciBiYWNrdXApXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFR4UmVxdWVzdD59IGZ1bGx5IHNpZ25lZCBUeFJlcXVlc3Qgb2JqZWN0XG4gICAqL1xuXG4gIGFzeW5jIHNpZ25UeFJlcXVlc3QocGFyYW1zOiBUU1NQYXJhbXNXaXRoUHJ2KTogUHJvbWlzZTxUeFJlcXVlc3Q+IHtcbiAgICB0aGlzLmJpdGdvLnNldFJlcXVlc3RUcmFjZXIocGFyYW1zLnJlcUlkKTtcbiAgICByZXR1cm4gdGhpcy5zaWduUmVxdWVzdEJhc2UocGFyYW1zLCBSZXF1ZXN0VHlwZS50eCk7XG4gIH1cblxuICAvKipcbiAgICogU2lnbnMgdGhlIG1lc3NhZ2UgYXNzb2NpYXRlZCB0byB0aGUgdHJhbnNhY3Rpb24gcmVxdWVzdC5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBUeFJlcXVlc3R9IHBhcmFtcy50eFJlcXVlc3QgLSB0cmFuc2FjdGlvbiByZXF1ZXN0IG9iamVjdCBvciBpZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGFyYW1zLnBydiAtIGRlY3J5cHRlZCBwcml2YXRlIGtleVxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGFyYW1zLnJlcUlkIC0gcmVxdWVzdCBpZFxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUeFJlcXVlc3Q+fSBmdWxseSBzaWduZWQgVHhSZXF1ZXN0IG9iamVjdFxuICAgKi9cbiAgYXN5bmMgc2lnblR4UmVxdWVzdEZvck1lc3NhZ2UocGFyYW1zOiBUU1NQYXJhbXNGb3JNZXNzYWdlV2l0aFBydik6IFByb21pc2U8VHhSZXF1ZXN0PiB7XG4gICAgdGhpcy5iaXRnby5zZXRSZXF1ZXN0VHJhY2VyKHBhcmFtcy5yZXFJZCk7XG4gICAgcmV0dXJuIHRoaXMuc2lnblJlcXVlc3RCYXNlKHBhcmFtcywgUmVxdWVzdFR5cGUubWVzc2FnZSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNpZ25SZXF1ZXN0QmFzZShcbiAgICBwYXJhbXM6IFRTU1BhcmFtc1dpdGhQcnYgfCBUU1NQYXJhbXNGb3JNZXNzYWdlV2l0aFBydixcbiAgICByZXF1ZXN0VHlwZTogUmVxdWVzdFR5cGVcbiAgKTogUHJvbWlzZTxUeFJlcXVlc3Q+IHtcbiAgICBjb25zdCB1c2VyS2V5U2hhcmUgPSBCdWZmZXIuZnJvbShwYXJhbXMucHJ2LCAnYmFzZTY0Jyk7XG4gICAgY29uc3QgdHhSZXF1ZXN0OiBUeFJlcXVlc3QgPVxuICAgICAgdHlwZW9mIHBhcmFtcy50eFJlcXVlc3QgPT09ICdzdHJpbmcnXG4gICAgICAgID8gYXdhaXQgZ2V0VHhSZXF1ZXN0KHRoaXMuYml0Z28sIHRoaXMud2FsbGV0LmlkKCksIHBhcmFtcy50eFJlcXVlc3QsIHBhcmFtcy5yZXFJZClcbiAgICAgICAgOiBwYXJhbXMudHhSZXF1ZXN0O1xuICAgIGxldCB0eE9yTWVzc2FnZVRvU2lnbjtcbiAgICBsZXQgZGVyaXZhdGlvblBhdGg7XG4gICAgbGV0IGJ1ZmZlckNvbnRlbnQ7XG4gICAgY29uc3QgdXNlckdwZ0tleSA9IGF3YWl0IGdlbmVyYXRlR1BHS2V5UGFpcignc2VjcDI1NmsxJyk7XG4gICAgY29uc3QgYml0Z29HcGdQdWJLZXkgPSBhd2FpdCB0aGlzLnBpY2tCaXRnb1B1YkdwZ0tleUZvclNpZ25pbmcodHJ1ZSwgcGFyYW1zLnJlcUlkLCB0eFJlcXVlc3QuZW50ZXJwcmlzZUlkKTtcblxuICAgIGlmICghYml0Z29HcGdQdWJLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBCaXRHbyBHUEcga2V5IGZvciBNUEN2MicpO1xuICAgIH1cblxuICAgIGlmIChyZXF1ZXN0VHlwZSA9PT0gUmVxdWVzdFR5cGUudHgpIHtcbiAgICAgIGFzc2VydCh0eFJlcXVlc3QudHJhbnNhY3Rpb25zIHx8IHR4UmVxdWVzdC51bnNpZ25lZFR4cywgJ1VuYWJsZSB0byBmaW5kIHRyYW5zYWN0aW9ucyBpbiB0eFJlcXVlc3QnKTtcbiAgICAgIGNvbnN0IHVuc2lnbmVkVHggPVxuICAgICAgICB0eFJlcXVlc3QuYXBpVmVyc2lvbiA9PT0gJ2Z1bGwnID8gdHhSZXF1ZXN0LnRyYW5zYWN0aW9ucyFbMF0udW5zaWduZWRUeCA6IHR4UmVxdWVzdC51bnNpZ25lZFR4c1swXTtcbiAgICAgIGF3YWl0IHRoaXMuYmFzZUNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4OiB1bnNpZ25lZFR4LnNpZ25hYmxlSGV4IH0sXG4gICAgICAgIHR4UGFyYW1zOiBwYXJhbXMudHhQYXJhbXMgfHwgeyByZWNpcGllbnRzOiBbXSB9LFxuICAgICAgICB3YWxsZXQ6IHRoaXMud2FsbGV0LFxuICAgICAgICB3YWxsZXRUeXBlOiB0aGlzLndhbGxldC5tdWx0aXNpZ1R5cGUoKSxcbiAgICAgIH0pO1xuICAgICAgdHhPck1lc3NhZ2VUb1NpZ24gPSB1bnNpZ25lZFR4LnNpZ25hYmxlSGV4O1xuICAgICAgZGVyaXZhdGlvblBhdGggPSB1bnNpZ25lZFR4LmRlcml2YXRpb25QYXRoO1xuICAgICAgYnVmZmVyQ29udGVudCA9IEJ1ZmZlci5mcm9tKHR4T3JNZXNzYWdlVG9TaWduLCAnaGV4Jyk7XG4gICAgfSBlbHNlIGlmIChyZXF1ZXN0VHlwZSA9PT0gUmVxdWVzdFR5cGUubWVzc2FnZSkge1xuICAgICAgdHhPck1lc3NhZ2VUb1NpZ24gPSB0eFJlcXVlc3QubWVzc2FnZXMhWzBdLm1lc3NhZ2VFbmNvZGVkO1xuICAgICAgZGVyaXZhdGlvblBhdGggPSB0eFJlcXVlc3QubWVzc2FnZXMhWzBdLmRlcml2YXRpb25QYXRoIHx8ICdtLzAnO1xuICAgICAgYnVmZmVyQ29udGVudCA9IEJ1ZmZlci5mcm9tKHR4T3JNZXNzYWdlVG9TaWduLCAnaGV4Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCByZXF1ZXN0IHR5cGUnKTtcbiAgICB9XG5cbiAgICBsZXQgaGFzaDogSGFzaDtcbiAgICB0cnkge1xuICAgICAgaGFzaCA9IHRoaXMuYmFzZUNvaW4uZ2V0SGFzaEZ1bmN0aW9uKCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBoYXNoID0gY3JlYXRlS2VjY2FrSGFzaCgna2VjY2FrMjU2JykgYXMgSGFzaDtcbiAgICB9XG4gICAgLy8gY2hlY2sgd2hhdCB0aGUgZW5jb2RpbmcgaXMgc3VwcG9zZWQgdG8gYmUgZm9yIG1lc3NhZ2VcbiAgICBjb25zdCBoYXNoQnVmZmVyID0gaGFzaC51cGRhdGUoYnVmZmVyQ29udGVudCkuZGlnZXN0KCk7XG4gICAgY29uc3Qgb3RoZXJTaWduZXIgPSBuZXcgRGtsc0RzZy5Ec2coXG4gICAgICB1c2VyS2V5U2hhcmUsXG4gICAgICBwYXJhbXMubXBjdjJQYXJ0eUlkID8gcGFyYW1zLm1wY3YyUGFydHlJZCA6IDAsXG4gICAgICBkZXJpdmF0aW9uUGF0aCxcbiAgICAgIGhhc2hCdWZmZXJcbiAgICApO1xuICAgIGNvbnN0IHVzZXJTaWduZXJCcm9hZGNhc3RNc2cxID0gYXdhaXQgb3RoZXJTaWduZXIuaW5pdCgpO1xuICAgIGNvbnN0IHNpZ25hdHVyZVNoYXJlUm91bmQxID0gYXdhaXQgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZE9uZShcbiAgICAgIHVzZXJTaWduZXJCcm9hZGNhc3RNc2cxLFxuICAgICAgdXNlckdwZ0tleSxcbiAgICAgIHBhcmFtcy5tcGN2MlBhcnR5SWRcbiAgICApO1xuXG4gICAgbGV0IGxhdGVzdFR4UmVxdWVzdCA9IGF3YWl0IHNlbmRTaWduYXR1cmVTaGFyZVYyKFxuICAgICAgdGhpcy5iaXRnbyxcbiAgICAgIHR4UmVxdWVzdC53YWxsZXRJZCxcbiAgICAgIHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgIFtzaWduYXR1cmVTaGFyZVJvdW5kMV0sXG4gICAgICByZXF1ZXN0VHlwZSxcbiAgICAgIHRoaXMuYmFzZUNvaW4uZ2V0TVBDQWxnb3JpdGhtKCksXG4gICAgICB1c2VyR3BnS2V5LnB1YmxpY0tleSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHRoaXMud2FsbGV0Lm11bHRpc2lnVHlwZVZlcnNpb24oKSxcbiAgICAgIHBhcmFtcy5yZXFJZFxuICAgICk7XG5cbiAgICBhc3NlcnQobGF0ZXN0VHhSZXF1ZXN0LnRyYW5zYWN0aW9ucyB8fCBsYXRlc3RUeFJlcXVlc3QubWVzc2FnZXMsICdJbnZhbGlkIHR4UmVxdWVzdCBPYmplY3QnKTtcblxuICAgIGxldCBiaXRnb1RvVXNlck1lc3NhZ2VzMUFuZDI6IGFueTtcbiAgICBpZiAocmVxdWVzdFR5cGUgPT09IFJlcXVlc3RUeXBlLnR4KSB7XG4gICAgICBiaXRnb1RvVXNlck1lc3NhZ2VzMUFuZDIgPSBsYXRlc3RUeFJlcXVlc3QudHJhbnNhY3Rpb25zIVswXS5zaWduYXR1cmVTaGFyZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJpdGdvVG9Vc2VyTWVzc2FnZXMxQW5kMiA9IGxhdGVzdFR4UmVxdWVzdC5tZXNzYWdlcyFbMF0uc2lnbmF0dXJlU2hhcmVzO1xuICAgIH1cbiAgICAvLyBUT0RPOiBVc2UgY29kZWMgZm9yIHBhcnNpbmdcbiAgICBjb25zdCBwYXJzZWRCaXRHb1RvVXNlclNpZ1NoYXJlUm91bmRPbmUgPSBKU09OLnBhcnNlKFxuICAgICAgYml0Z29Ub1VzZXJNZXNzYWdlczFBbmQyW2JpdGdvVG9Vc2VyTWVzc2FnZXMxQW5kMi5sZW5ndGggLSAxXS5zaGFyZVxuICAgICkgYXMgTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMU91dHB1dDtcbiAgICBpZiAocGFyc2VkQml0R29Ub1VzZXJTaWdTaGFyZVJvdW5kT25lLnR5cGUgIT09ICdyb3VuZDFPdXRwdXQnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgc2lnbmF0dXJlIHNoYXJlIHJlc3BvbnNlLiBVbmFibGUgdG8gcGFyc2UgZGF0YS4nKTtcbiAgICB9XG4gICAgY29uc3Qgc2VyaWFsaXplZEJpdEdvVG9Vc2VyTWVzc2FnZXNSb3VuZDFBbmQyID0gYXdhaXQgdmVyaWZ5Qml0R29NZXNzYWdlc0FuZFNpZ25hdHVyZXNSb3VuZE9uZShcbiAgICAgIHBhcnNlZEJpdEdvVG9Vc2VyU2lnU2hhcmVSb3VuZE9uZSxcbiAgICAgIHVzZXJHcGdLZXksXG4gICAgICBiaXRnb0dwZ1B1YktleSxcbiAgICAgIHBhcmFtcy5tcGN2MlBhcnR5SWRcbiAgICApO1xuXG4gICAgLyoqIFJvdW5kIDIgKiovXG4gICAgY29uc3QgZGVzZXJpYWxpemVkTWVzc2FnZXMgPSBEa2xzVHlwZXMuZGVzZXJpYWxpemVNZXNzYWdlcyhzZXJpYWxpemVkQml0R29Ub1VzZXJNZXNzYWdlc1JvdW5kMUFuZDIpO1xuICAgIGNvbnN0IHVzZXJUb0JpdEdvTWVzc2FnZXNSb3VuZDIgPSBvdGhlclNpZ25lci5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBkZXNlcmlhbGl6ZWRNZXNzYWdlcy5icm9hZGNhc3RNZXNzYWdlcyxcbiAgICB9KTtcbiAgICBjb25zdCB1c2VyVG9CaXRHb01lc3NhZ2VzUm91bmQzID0gb3RoZXJTaWduZXIuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBwMnBNZXNzYWdlczogZGVzZXJpYWxpemVkTWVzc2FnZXMucDJwTWVzc2FnZXMsXG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW10sXG4gICAgfSk7XG4gICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVSb3VuZFR3byA9IGF3YWl0IGdldFNpZ25hdHVyZVNoYXJlUm91bmRUd28oXG4gICAgICB1c2VyVG9CaXRHb01lc3NhZ2VzUm91bmQyLFxuICAgICAgdXNlclRvQml0R29NZXNzYWdlc1JvdW5kMyxcbiAgICAgIHVzZXJHcGdLZXksXG4gICAgICBiaXRnb0dwZ1B1YktleSxcbiAgICAgIHBhcmFtcy5tcGN2MlBhcnR5SWRcbiAgICApO1xuICAgIGxhdGVzdFR4UmVxdWVzdCA9IGF3YWl0IHNlbmRTaWduYXR1cmVTaGFyZVYyKFxuICAgICAgdGhpcy5iaXRnbyxcbiAgICAgIHR4UmVxdWVzdC53YWxsZXRJZCxcbiAgICAgIHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgIFtzaWduYXR1cmVTaGFyZVJvdW5kVHdvXSxcbiAgICAgIHJlcXVlc3RUeXBlLFxuICAgICAgdGhpcy5iYXNlQ29pbi5nZXRNUENBbGdvcml0aG0oKSxcbiAgICAgIHVzZXJHcGdLZXkucHVibGljS2V5LFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdGhpcy53YWxsZXQubXVsdGlzaWdUeXBlVmVyc2lvbigpLFxuICAgICAgcGFyYW1zLnJlcUlkXG4gICAgKTtcbiAgICBhc3NlcnQobGF0ZXN0VHhSZXF1ZXN0LnRyYW5zYWN0aW9ucyB8fCBsYXRlc3RUeFJlcXVlc3QubWVzc2FnZXMsICdJbnZhbGlkIHR4UmVxdWVzdCBPYmplY3QnKTtcblxuICAgIGNvbnN0IHR4UmVxdWVzdFNpZ25hdHVyZVNoYXJlcyA9XG4gICAgICByZXF1ZXN0VHlwZSA9PT0gUmVxdWVzdFR5cGUudHhcbiAgICAgICAgPyBsYXRlc3RUeFJlcXVlc3QudHJhbnNhY3Rpb25zIVswXS5zaWduYXR1cmVTaGFyZXNcbiAgICAgICAgOiBsYXRlc3RUeFJlcXVlc3QubWVzc2FnZXMhWzBdLnNpZ25hdHVyZVNoYXJlcztcbiAgICAvLyBUT0RPOiBVc2UgY29kZWMgZm9yIHBhcnNpbmdcbiAgICBjb25zdCBwYXJzZWRCaXRHb1RvVXNlclNpZ1NoYXJlUm91bmRUd28gPSBKU09OLnBhcnNlKFxuICAgICAgdHhSZXF1ZXN0U2lnbmF0dXJlU2hhcmVzW3R4UmVxdWVzdFNpZ25hdHVyZVNoYXJlcy5sZW5ndGggLSAxXS5zaGFyZVxuICAgICkgYXMgTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMk91dHB1dDtcbiAgICBpZiAocGFyc2VkQml0R29Ub1VzZXJTaWdTaGFyZVJvdW5kVHdvLnR5cGUgIT09ICdyb3VuZDJPdXRwdXQnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgc2lnbmF0dXJlIHNoYXJlIHJlc3BvbnNlLiBVbmFibGUgdG8gcGFyc2UgZGF0YS4nKTtcbiAgICB9XG4gICAgY29uc3Qgc2VyaWFsaXplZEJpdEdvVG9Vc2VyTWVzc2FnZXNSb3VuZDMgPSBhd2FpdCB2ZXJpZnlCaXRHb01lc3NhZ2VzQW5kU2lnbmF0dXJlc1JvdW5kVHdvKFxuICAgICAgcGFyc2VkQml0R29Ub1VzZXJTaWdTaGFyZVJvdW5kVHdvLFxuICAgICAgdXNlckdwZ0tleSxcbiAgICAgIGJpdGdvR3BnUHViS2V5LFxuICAgICAgcGFyYW1zLm1wY3YyUGFydHlJZFxuICAgICk7XG5cbiAgICAvKiogUm91bmQgMyAqKi9cbiAgICBjb25zdCBkZXNlcmlhbGl6ZWRCaXRHb1RvVXNlck1lc3NhZ2VzUm91bmQzID0gRGtsc1R5cGVzLmRlc2VyaWFsaXplTWVzc2FnZXMoe1xuICAgICAgcDJwTWVzc2FnZXM6IHNlcmlhbGl6ZWRCaXRHb1RvVXNlck1lc3NhZ2VzUm91bmQzLnAycE1lc3NhZ2VzLFxuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICAgIH0pO1xuICAgIGNvbnN0IHVzZXJUb0JpdEdvTWVzc2FnZXNSb3VuZDQgPSBvdGhlclNpZ25lci5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICAgIHAycE1lc3NhZ2VzOiBkZXNlcmlhbGl6ZWRCaXRHb1RvVXNlck1lc3NhZ2VzUm91bmQzLnAycE1lc3NhZ2VzLFxuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVSb3VuZFRocmVlID0gYXdhaXQgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFRocmVlKFxuICAgICAgdXNlclRvQml0R29NZXNzYWdlc1JvdW5kNCxcbiAgICAgIHVzZXJHcGdLZXksXG4gICAgICBiaXRnb0dwZ1B1YktleSxcbiAgICAgIHBhcmFtcy5tcGN2MlBhcnR5SWRcbiAgICApO1xuICAgIC8vIFN1Ym1pdCBmb3IgZmluYWwgc2lnbmF0dXJlIHNoYXJlIGNvbWJpbmVcbiAgICBhd2FpdCBzZW5kU2lnbmF0dXJlU2hhcmVWMihcbiAgICAgIHRoaXMuYml0Z28sXG4gICAgICB0eFJlcXVlc3Qud2FsbGV0SWQsXG4gICAgICB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICBbc2lnbmF0dXJlU2hhcmVSb3VuZFRocmVlXSxcbiAgICAgIHJlcXVlc3RUeXBlLFxuICAgICAgdGhpcy5iYXNlQ29pbi5nZXRNUENBbGdvcml0aG0oKSxcbiAgICAgIHVzZXJHcGdLZXkucHVibGljS2V5LFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdGhpcy53YWxsZXQubXVsdGlzaWdUeXBlVmVyc2lvbigpLFxuICAgICAgcGFyYW1zLnJlcUlkXG4gICAgKTtcblxuICAgIHJldHVybiBzZW5kVHhSZXF1ZXN0KHRoaXMuYml0Z28sIHR4UmVxdWVzdC53YWxsZXRJZCwgdHhSZXF1ZXN0LnR4UmVxdWVzdElkLCByZXF1ZXN0VHlwZSwgcGFyYW1zLnJlcUlkKTtcbiAgfVxuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIGZvcm1hdHRpbmcgdXRpbHNcbiAgZm9ybWF0Qml0Z29Ccm9hZGNhc3RNZXNzYWdlKGJyb2FkY2FzdE1lc3NhZ2U6IE1QQ3YyQnJvYWRjYXN0TWVzc2FnZSkge1xuICAgIHJldHVybiB7XG4gICAgICBmcm9tOiBicm9hZGNhc3RNZXNzYWdlLmZyb20sXG4gICAgICBwYXlsb2FkOiB7IG1lc3NhZ2U6IGJyb2FkY2FzdE1lc3NhZ2UubWVzc2FnZSwgc2lnbmF0dXJlOiBicm9hZGNhc3RNZXNzYWdlLnNpZ25hdHVyZSB9LFxuICAgIH07XG4gIH1cblxuICBmb3JtYXRQMlBNZXNzYWdlKHAycE1lc3NhZ2U6IE1QQ3YyUDJQTWVzc2FnZSwgY29tbWl0bWVudD86IHN0cmluZykge1xuICAgIHJldHVybiB7XG4gICAgICBwYXlsb2FkOiB7IGVuY3J5cHRlZE1lc3NhZ2U6IHAycE1lc3NhZ2UuZW5jcnlwdGVkTWVzc2FnZSwgc2lnbmF0dXJlOiBwMnBNZXNzYWdlLnNpZ25hdHVyZSB9LFxuICAgICAgZnJvbTogcDJwTWVzc2FnZS5mcm9tLFxuICAgICAgdG86IHAycE1lc3NhZ2UudG8sXG4gICAgICBjb21taXRtZW50LFxuICAgIH07XG4gIH1cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gcHJpdmF0ZSB1dGlsc1xuICAvKipcbiAgICogR2V0IHRoZSBoYXNoIHN0cmluZyBhbmQgZGVyaXZhdGlvbiBwYXRoIGZyb20gdGhlIHRyYW5zYWN0aW9uIHJlcXVlc3QuXG4gICAqIEBwYXJhbSB7VHhSZXF1ZXN0fSB0eFJlcXVlc3QgLSB0aGUgdHJhbnNhY3Rpb24gcmVxdWVzdCBvYmplY3RcbiAgICogQHBhcmFtIHtSZXF1ZXN0VHlwZX0gcmVxdWVzdFR5cGUgLSB0aGUgcmVxdWVzdCB0eXBlXG4gICAqIEByZXR1cm5zIHt7IGhhc2hCdWZmZXI6IEJ1ZmZlcjsgZGVyaXZhdGlvblBhdGg6IHN0cmluZyB9fSAtIHRoZSBoYXNoIHN0cmluZyBhbmQgZGVyaXZhdGlvbiBwYXRoXG4gICAqL1xuICBwcml2YXRlIGdldEhhc2hTdHJpbmdBbmREZXJpdmF0aW9uUGF0aChcbiAgICB0eFJlcXVlc3Q6IFR4UmVxdWVzdCxcbiAgICByZXF1ZXN0VHlwZTogUmVxdWVzdFR5cGUgPSBSZXF1ZXN0VHlwZS50eFxuICApOiB7IGhhc2hCdWZmZXI6IEJ1ZmZlcjsgZGVyaXZhdGlvblBhdGg6IHN0cmluZyB9IHtcbiAgICBsZXQgdHhUb1NpZ246IHN0cmluZztcbiAgICBsZXQgZGVyaXZhdGlvblBhdGg6IHN0cmluZztcbiAgICBpZiAocmVxdWVzdFR5cGUgPT09IFJlcXVlc3RUeXBlLnR4KSB7XG4gICAgICBhc3NlcnQodHhSZXF1ZXN0LnRyYW5zYWN0aW9ucyAmJiB0eFJlcXVlc3QudHJhbnNhY3Rpb25zLmxlbmd0aCA9PT0gMSwgJ1VuYWJsZSB0byBmaW5kIHRyYW5zYWN0aW9ucyBpbiB0eFJlcXVlc3QnKTtcbiAgICAgIHR4VG9TaWduID0gdHhSZXF1ZXN0LnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNpZ25hYmxlSGV4O1xuICAgICAgZGVyaXZhdGlvblBhdGggPSB0eFJlcXVlc3QudHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguZGVyaXZhdGlvblBhdGg7XG4gICAgfSBlbHNlIGlmIChyZXF1ZXN0VHlwZSA9PT0gUmVxdWVzdFR5cGUubWVzc2FnZSkge1xuICAgICAgLy8gVE9ETyhXUC0yMTc2KTogQWRkIHN1cHBvcnQgZm9yIG1lc3NhZ2Ugc2lnbmluZ1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNUEN2MiBtZXNzYWdlIHNpZ25pbmcgbm90IHN1cHBvcnRlZCB5ZXQuJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCByZXF1ZXN0IHR5cGUsIGdvdDogJyArIHJlcXVlc3RUeXBlKTtcbiAgICB9XG5cbiAgICBsZXQgaGFzaDogSGFzaDtcbiAgICB0cnkge1xuICAgICAgaGFzaCA9IHRoaXMuYmFzZUNvaW4uZ2V0SGFzaEZ1bmN0aW9uKCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBoYXNoID0gY3JlYXRlS2VjY2FrSGFzaCgna2VjY2FrMjU2JykgYXMgSGFzaDtcbiAgICB9XG4gICAgY29uc3QgaGFzaEJ1ZmZlciA9IGhhc2gudXBkYXRlKEJ1ZmZlci5mcm9tKHR4VG9TaWduLCAnaGV4JykpLmRpZ2VzdCgpO1xuXG4gICAgcmV0dXJuIHsgaGFzaEJ1ZmZlciwgZGVyaXZhdGlvblBhdGggfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBCaXRHbyBhbmQgdXNlciBHUEcga2V5cyBmcm9tIHRoZSBCaXRHbyBwdWJsaWMgR1BHIGtleSBhbmQgdGhlIGVuY3J5cHRlZCB1c2VyIEdQRyBwcml2YXRlIGtleS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGJpdGdvUHVibGljR3BnS2V5ICAtIHRoZSBCaXRHbyBwdWJsaWMgR1BHIGtleVxuICAgKiBAcGFyYW0ge3N0cmluZ30gZW5jcnlwdGVkVXNlckdwZ1BydktleSAgLSB0aGUgZW5jcnlwdGVkIHVzZXIgR1BHIHByaXZhdGUga2V5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSB3YWxsZXRQYXNzcGhyYXNlICAtIHRoZSB3YWxsZXQgcGFzc3BocmFzZVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7IGJpdGdvR3BnS2V5OiBwZ3AuS2V5OyB1c2VyR3BnS2V5OiBwZ3AuU2VyaWFsaXplZEtleVBhaXI8c3RyaW5nPiB9Pn0gLSB0aGUgQml0R28gYW5kIHVzZXIgR1BHIGtleXNcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0Qml0Z29BbmRVc2VyR3BnS2V5cyhcbiAgICBiaXRnb1B1YmxpY0dwZ0tleTogc3RyaW5nLFxuICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHN0cmluZyxcbiAgICB3YWxsZXRQYXNzcGhyYXNlOiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7XG4gICAgYml0Z29HcGdLZXk6IHBncC5LZXk7XG4gICAgdXNlckdwZ0tleTogcGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz47XG4gIH0+IHtcbiAgICBjb25zdCBiaXRnb0dwZ0tleSA9IGF3YWl0IHBncC5yZWFkS2V5KHsgYXJtb3JlZEtleTogYml0Z29QdWJsaWNHcGdLZXkgfSk7XG4gICAgY29uc3QgdXNlckRlY3J5cHRlZEtleSA9IGF3YWl0IHBncC5yZWFkS2V5KHtcbiAgICAgIGFybW9yZWRLZXk6IHRoaXMuYml0Z28uZGVjcnlwdCh7IGlucHV0OiBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICB9KTtcbiAgICBjb25zdCB1c2VyR3BnS2V5OiBwZ3AuU2VyaWFsaXplZEtleVBhaXI8c3RyaW5nPiA9IHtcbiAgICAgIHByaXZhdGVLZXk6IHVzZXJEZWNyeXB0ZWRLZXkuYXJtb3IoKSxcbiAgICAgIHB1YmxpY0tleTogdXNlckRlY3J5cHRlZEtleS50b1B1YmxpYygpLmFybW9yKCksXG4gICAgfTtcbiAgICByZXR1cm4ge1xuICAgICAgYml0Z29HcGdLZXksXG4gICAgICB1c2VyR3BnS2V5LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoZSBhZGF0YSBhbmQgY3lwaGVydGV4dC5cbiAgICogQHBhcmFtIGFkYXRhIHN0cmluZ1xuICAgKiBAcGFyYW0gY3lwaGVydGV4dCBzdHJpbmdcbiAgICogQHJldHVybnMgdm9pZFxuICAgKiBAdGhyb3dzIHtFcnJvcn0gaWYgdGhlIGFkYXRhIG9yIGN5cGhlcnRleHQgaXMgaW52YWxpZFxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZUFkYXRhKGFkYXRhOiBzdHJpbmcsIGN5cGhlcnRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGxldCBjeXBoZXJKc29uO1xuICAgIHRyeSB7XG4gICAgICBjeXBoZXJKc29uID0gSlNPTi5wYXJzZShjeXBoZXJ0ZXh0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBwYXJzZSBjeXBoZXJ0ZXh0IHRvIEpTT04sIGdvdDogJyArIGN5cGhlcnRleHQpO1xuICAgIH1cbiAgICAvLyB1c2luZyBkZWNvZGVVUklDb21wb25lbnQgdG8gaGFuZGxlIHNwZWNpYWwgY2hhcmFjdGVyc1xuICAgIGlmIChkZWNvZGVVUklDb21wb25lbnQoY3lwaGVySnNvbi5hZGF0YSkgIT09IGRlY29kZVVSSUNvbXBvbmVudChhZGF0YSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQWRhdGEgZG9lcyBub3QgbWF0Y2ggY3lwaGVydGV4dCBhZGF0YScpO1xuICAgIH1cbiAgfVxuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIGV4dGVybmFsIHNpZ25lclxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgYXN5bmMgc2lnbkVjZHNhTVBDdjJUc3NVc2luZ0V4dGVybmFsU2lnbmVyKFxuICAgIHBhcmFtczogVFNTUGFyYW1zIHwgVFNTUGFyYW1zRm9yTWVzc2FnZSxcbiAgICBleHRlcm5hbFNpZ25lck1QQ3YyU2lnbmluZ1JvdW5kMUdlbmVyYXRvcjogQ3VzdG9tTVBDdjJTaWduaW5nUm91bmQxR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICAgIGV4dGVybmFsU2lnbmVyTVBDdjJTaWduaW5nUm91bmQyR2VuZXJhdG9yOiBDdXN0b21NUEN2MlNpZ25pbmdSb3VuZDJHZW5lcmF0aW5nRnVuY3Rpb24sXG4gICAgZXh0ZXJuYWxTaWduZXJNUEN2MlNpZ25pbmdSb3VuZDNHZW5lcmF0b3I6IEN1c3RvbU1QQ3YyU2lnbmluZ1JvdW5kM0dlbmVyYXRpbmdGdW5jdGlvbixcbiAgICByZXF1ZXN0VHlwZTogUmVxdWVzdFR5cGUgPSBSZXF1ZXN0VHlwZS50eFxuICApOiBQcm9taXNlPFR4UmVxdWVzdD4ge1xuICAgIGNvbnN0IHsgdHhSZXF1ZXN0LCByZXFJZCB9ID0gcGFyYW1zO1xuICAgIGxldCB0eFJlcXVlc3RSZXNvbHZlZDogVHhSZXF1ZXN0O1xuXG4gICAgLy8gVE9ETyhXUC0yMTc2KTogQWRkIHN1cHBvcnQgZm9yIG1lc3NhZ2Ugc2lnbmluZ1xuICAgIGFzc2VydChcbiAgICAgIHJlcXVlc3RUeXBlID09PSBSZXF1ZXN0VHlwZS50eCxcbiAgICAgICdPbmx5IHRyYW5zYWN0aW9uIHNpZ25pbmcgaXMgc3VwcG9ydGVkIGZvciBleHRlcm5hbCBzaWduZXIsIGdvdDogJyArIHJlcXVlc3RUeXBlXG4gICAgKTtcblxuICAgIGlmICh0eXBlb2YgdHhSZXF1ZXN0ID09PSAnc3RyaW5nJykge1xuICAgICAgdHhSZXF1ZXN0UmVzb2x2ZWQgPSBhd2FpdCBnZXRUeFJlcXVlc3QodGhpcy5iaXRnbywgdGhpcy53YWxsZXQuaWQoKSwgdHhSZXF1ZXN0LCByZXFJZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHR4UmVxdWVzdFJlc29sdmVkID0gdHhSZXF1ZXN0O1xuICAgIH1cblxuICAgIGNvbnN0IGJpdGdvUHVibGljR3BnS2V5ID0gYXdhaXQgdGhpcy5waWNrQml0Z29QdWJHcGdLZXlGb3JTaWduaW5nKFxuICAgICAgdHJ1ZSxcbiAgICAgIHBhcmFtcy5yZXFJZCxcbiAgICAgIHR4UmVxdWVzdFJlc29sdmVkLmVudGVycHJpc2VJZFxuICAgICk7XG5cbiAgICBpZiAoIWJpdGdvUHVibGljR3BnS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgQml0R28gR1BHIGtleSBmb3IgTVBDdjInKTtcbiAgICB9XG5cbiAgICAvLyByb3VuZCAxXG4gICAgY29uc3QgeyBzaWduYXR1cmVTaGFyZVJvdW5kMSwgdXNlckdwZ1B1YktleSwgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiwgZW5jcnlwdGVkVXNlckdwZ1BydktleSB9ID1cbiAgICAgIGF3YWl0IGV4dGVybmFsU2lnbmVyTVBDdjJTaWduaW5nUm91bmQxR2VuZXJhdG9yKHsgdHhSZXF1ZXN0OiB0eFJlcXVlc3RSZXNvbHZlZCB9KTtcbiAgICBjb25zdCByb3VuZDFUeFJlcXVlc3QgPSBhd2FpdCBzZW5kU2lnbmF0dXJlU2hhcmVWMihcbiAgICAgIHRoaXMuYml0Z28sXG4gICAgICB0eFJlcXVlc3RSZXNvbHZlZC53YWxsZXRJZCxcbiAgICAgIHR4UmVxdWVzdFJlc29sdmVkLnR4UmVxdWVzdElkLFxuICAgICAgW3NpZ25hdHVyZVNoYXJlUm91bmQxXSxcbiAgICAgIHJlcXVlc3RUeXBlLFxuICAgICAgdGhpcy5iYXNlQ29pbi5nZXRNUENBbGdvcml0aG0oKSxcbiAgICAgIHVzZXJHcGdQdWJLZXksXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB0aGlzLndhbGxldC5tdWx0aXNpZ1R5cGVWZXJzaW9uKCksXG4gICAgICByZXFJZFxuICAgICk7XG5cbiAgICAvLyByb3VuZCAyXG4gICAgY29uc3QgeyBzaWduYXR1cmVTaGFyZVJvdW5kMiwgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbiB9ID0gYXdhaXQgZXh0ZXJuYWxTaWduZXJNUEN2MlNpZ25pbmdSb3VuZDJHZW5lcmF0b3Ioe1xuICAgICAgdHhSZXF1ZXN0OiByb3VuZDFUeFJlcXVlc3QsXG4gICAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLFxuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb1B1YmxpY0dwZ0tleS5hcm1vcigpLFxuICAgIH0pO1xuICAgIGNvbnN0IHJvdW5kMlR4UmVxdWVzdCA9IGF3YWl0IHNlbmRTaWduYXR1cmVTaGFyZVYyKFxuICAgICAgdGhpcy5iaXRnbyxcbiAgICAgIHR4UmVxdWVzdFJlc29sdmVkLndhbGxldElkLFxuICAgICAgdHhSZXF1ZXN0UmVzb2x2ZWQudHhSZXF1ZXN0SWQsXG4gICAgICBbc2lnbmF0dXJlU2hhcmVSb3VuZDJdLFxuICAgICAgcmVxdWVzdFR5cGUsXG4gICAgICB0aGlzLmJhc2VDb2luLmdldE1QQ0FsZ29yaXRobSgpLFxuICAgICAgdXNlckdwZ1B1YktleSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHRoaXMud2FsbGV0Lm11bHRpc2lnVHlwZVZlcnNpb24oKSxcbiAgICAgIHJlcUlkXG4gICAgKTtcbiAgICBhc3NlcnQoXG4gICAgICByb3VuZDJUeFJlcXVlc3QudHJhbnNhY3Rpb25zICYmIHJvdW5kMlR4UmVxdWVzdC50cmFuc2FjdGlvbnNbMF0uc2lnbmF0dXJlU2hhcmVzLFxuICAgICAgJ01pc3Npbmcgc2lnbmF0dXJlIHNoYXJlcyBpbiByb3VuZCAyIHR4UmVxdWVzdCdcbiAgICApO1xuXG4gICAgLy8gcm91bmQgM1xuICAgIGNvbnN0IHsgc2lnbmF0dXJlU2hhcmVSb3VuZDMgfSA9IGF3YWl0IGV4dGVybmFsU2lnbmVyTVBDdjJTaWduaW5nUm91bmQzR2VuZXJhdG9yKHtcbiAgICAgIHR4UmVxdWVzdDogcm91bmQyVHhSZXF1ZXN0LFxuICAgICAgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbixcbiAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXksXG4gICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29QdWJsaWNHcGdLZXkuYXJtb3IoKSxcbiAgICB9KTtcbiAgICBhd2FpdCBzZW5kU2lnbmF0dXJlU2hhcmVWMihcbiAgICAgIHRoaXMuYml0Z28sXG4gICAgICB0eFJlcXVlc3RSZXNvbHZlZC53YWxsZXRJZCxcbiAgICAgIHR4UmVxdWVzdFJlc29sdmVkLnR4UmVxdWVzdElkLFxuICAgICAgW3NpZ25hdHVyZVNoYXJlUm91bmQzXSxcbiAgICAgIHJlcXVlc3RUeXBlLFxuICAgICAgdGhpcy5iYXNlQ29pbi5nZXRNUENBbGdvcml0aG0oKSxcbiAgICAgIHVzZXJHcGdQdWJLZXksXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB0aGlzLndhbGxldC5tdWx0aXNpZ1R5cGVWZXJzaW9uKCksXG4gICAgICByZXFJZFxuICAgICk7XG5cbiAgICByZXR1cm4gc2VuZFR4UmVxdWVzdCh0aGlzLmJpdGdvLCB0eFJlcXVlc3RSZXNvbHZlZC53YWxsZXRJZCwgdHhSZXF1ZXN0UmVzb2x2ZWQudHhSZXF1ZXN0SWQsIHJlcXVlc3RUeXBlLCByZXFJZCk7XG4gIH1cblxuICBhc3luYyBjcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUocGFyYW1zOiB7IHR4UmVxdWVzdDogVHhSZXF1ZXN0OyBwcnY6IHN0cmluZzsgd2FsbGV0UGFzc3BocmFzZTogc3RyaW5nIH0pOiBQcm9taXNlPHtcbiAgICBzaWduYXR1cmVTaGFyZVJvdW5kMTogU2lnbmF0dXJlU2hhcmVSZWNvcmQ7XG4gICAgdXNlckdwZ1B1YktleTogc3RyaW5nO1xuICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246IHN0cmluZztcbiAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiBzdHJpbmc7XG4gIH0+IHtcbiAgICBjb25zdCB7IHBydiwgd2FsbGV0UGFzc3BocmFzZSwgdHhSZXF1ZXN0IH0gPSBwYXJhbXM7XG4gICAgY29uc3QgeyBoYXNoQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCB9ID0gdGhpcy5nZXRIYXNoU3RyaW5nQW5kRGVyaXZhdGlvblBhdGgodHhSZXF1ZXN0KTtcbiAgICBjb25zdCBhZGF0YSA9IGAke2hhc2hCdWZmZXIudG9TdHJpbmcoJ2hleCcpfToke2Rlcml2YXRpb25QYXRofWA7XG5cbiAgICBjb25zdCB1c2VyS2V5U2hhcmUgPSBCdWZmZXIuZnJvbShwcnYsICdiYXNlNjQnKTtcbiAgICBjb25zdCB1c2VyR3BnS2V5ID0gYXdhaXQgZ2VuZXJhdGVHUEdLZXlQYWlyKCdzZWNwMjU2azEnKTtcblxuICAgIGNvbnN0IHVzZXJTaWduZXIgPSBuZXcgRGtsc0RzZy5Ec2codXNlcktleVNoYXJlLCAwLCBkZXJpdmF0aW9uUGF0aCwgaGFzaEJ1ZmZlcik7XG4gICAgY29uc3QgdXNlclNpZ25lckJyb2FkY2FzdE1zZzEgPSBhd2FpdCB1c2VyU2lnbmVyLmluaXQoKTtcbiAgICBjb25zdCBzaWduYXR1cmVTaGFyZVJvdW5kMSA9IGF3YWl0IGdldFNpZ25hdHVyZVNoYXJlUm91bmRPbmUodXNlclNpZ25lckJyb2FkY2FzdE1zZzEsIHVzZXJHcGdLZXkpO1xuICAgIGNvbnN0IHNlc3Npb24gPSB1c2VyU2lnbmVyLmdldFNlc3Npb24oKTtcbiAgICBjb25zdCBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uID0gdGhpcy5iaXRnby5lbmNyeXB0KHsgaW5wdXQ6IHNlc3Npb24sIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLCBhZGF0YSB9KTtcblxuICAgIGNvbnN0IHVzZXJHcGdQdWJLZXkgPSB1c2VyR3BnS2V5LnB1YmxpY0tleTtcbiAgICBjb25zdCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5ID0gdGhpcy5iaXRnby5lbmNyeXB0KHtcbiAgICAgIGlucHV0OiB1c2VyR3BnS2V5LnByaXZhdGVLZXksXG4gICAgICBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIGFkYXRhLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHsgc2lnbmF0dXJlU2hhcmVSb3VuZDEsIHVzZXJHcGdQdWJLZXksIGVuY3J5cHRlZFJvdW5kMVNlc3Npb24sIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXkgfTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZU9mZmxpbmVSb3VuZDJTaGFyZShwYXJhbXM6IHtcbiAgICB0eFJlcXVlc3Q6IFR4UmVxdWVzdDtcbiAgICBwcnY6IHN0cmluZztcbiAgICB3YWxsZXRQYXNzcGhyYXNlOiBzdHJpbmc7XG4gICAgYml0Z29QdWJsaWNHcGdLZXk6IHN0cmluZztcbiAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiBzdHJpbmc7XG4gICAgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbjogc3RyaW5nO1xuICB9KTogUHJvbWlzZTx7XG4gICAgc2lnbmF0dXJlU2hhcmVSb3VuZDI6IFNpZ25hdHVyZVNoYXJlUmVjb3JkO1xuICAgIGVuY3J5cHRlZFJvdW5kMlNlc3Npb246IHN0cmluZztcbiAgfT4ge1xuICAgIGNvbnN0IHsgcHJ2LCB3YWxsZXRQYXNzcGhyYXNlLCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LCBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLCBiaXRnb1B1YmxpY0dwZ0tleSwgdHhSZXF1ZXN0IH0gPVxuICAgICAgcGFyYW1zO1xuXG4gICAgY29uc3QgeyBoYXNoQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCB9ID0gdGhpcy5nZXRIYXNoU3RyaW5nQW5kRGVyaXZhdGlvblBhdGgodHhSZXF1ZXN0KTtcbiAgICBjb25zdCBhZGF0YSA9IGAke2hhc2hCdWZmZXIudG9TdHJpbmcoJ2hleCcpfToke2Rlcml2YXRpb25QYXRofWA7XG4gICAgY29uc3QgeyBiaXRnb0dwZ0tleSwgdXNlckdwZ0tleSB9ID0gYXdhaXQgdGhpcy5nZXRCaXRnb0FuZFVzZXJHcGdLZXlzKFxuICAgICAgYml0Z29QdWJsaWNHcGdLZXksXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgd2FsbGV0UGFzc3BocmFzZVxuICAgICk7XG5cbiAgICBjb25zdCBzaWduYXR1cmVTaGFyZXMgPSB0eFJlcXVlc3QudHJhbnNhY3Rpb25zPy5bMF0uc2lnbmF0dXJlU2hhcmVzO1xuICAgIGFzc2VydChzaWduYXR1cmVTaGFyZXMsICdNaXNzaW5nIHNpZ25hdHVyZSBzaGFyZXMgaW4gcm91bmQgMSB0eFJlcXVlc3QnKTtcbiAgICBjb25zdCBwYXJzZWRCaXRHb1RvVXNlclNpZ1NoYXJlUm91bmRPbmUgPSBKU09OLnBhcnNlKFxuICAgICAgc2lnbmF0dXJlU2hhcmVzW3NpZ25hdHVyZVNoYXJlcy5sZW5ndGggLSAxXS5zaGFyZVxuICAgICkgYXMgTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMU91dHB1dDtcbiAgICBpZiAocGFyc2VkQml0R29Ub1VzZXJTaWdTaGFyZVJvdW5kT25lLnR5cGUgIT09ICdyb3VuZDFPdXRwdXQnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgc2lnbmF0dXJlIHNoYXJlIHJlc3BvbnNlLiBVbmFibGUgdG8gcGFyc2UgZGF0YS4nKTtcbiAgICB9XG4gICAgY29uc3Qgc2VyaWFsaXplZEJpdEdvVG9Vc2VyTWVzc2FnZXNSb3VuZDEgPSBhd2FpdCB2ZXJpZnlCaXRHb01lc3NhZ2VzQW5kU2lnbmF0dXJlc1JvdW5kT25lKFxuICAgICAgcGFyc2VkQml0R29Ub1VzZXJTaWdTaGFyZVJvdW5kT25lLFxuICAgICAgdXNlckdwZ0tleSxcbiAgICAgIGJpdGdvR3BnS2V5XG4gICAgKTtcblxuICAgIGNvbnN0IHJvdW5kMVNlc3Npb24gPSB0aGlzLmJpdGdvLmRlY3J5cHQoeyBpbnB1dDogZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSk7XG5cbiAgICB0aGlzLnZhbGlkYXRlQWRhdGEoYWRhdGEsIGVuY3J5cHRlZFJvdW5kMVNlc3Npb24pO1xuICAgIGNvbnN0IHVzZXJLZXlTaGFyZSA9IEJ1ZmZlci5mcm9tKHBydiwgJ2Jhc2U2NCcpO1xuICAgIGNvbnN0IHVzZXJTaWduZXIgPSBuZXcgRGtsc0RzZy5Ec2codXNlcktleVNoYXJlLCAwLCBkZXJpdmF0aW9uUGF0aCwgaGFzaEJ1ZmZlcik7XG4gICAgYXdhaXQgdXNlclNpZ25lci5zZXRTZXNzaW9uKHJvdW5kMVNlc3Npb24pO1xuXG4gICAgY29uc3QgZGVzZXJpYWxpemVkTWVzc2FnZXMgPSBEa2xzVHlwZXMuZGVzZXJpYWxpemVNZXNzYWdlcyhzZXJpYWxpemVkQml0R29Ub1VzZXJNZXNzYWdlc1JvdW5kMSk7XG4gICAgY29uc3QgdXNlclRvQml0R29NZXNzYWdlc1JvdW5kMiA9IHVzZXJTaWduZXIuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBwMnBNZXNzYWdlczogW10sXG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogZGVzZXJpYWxpemVkTWVzc2FnZXMuYnJvYWRjYXN0TWVzc2FnZXMsXG4gICAgfSk7XG4gICAgY29uc3QgdXNlclRvQml0R29NZXNzYWdlc1JvdW5kMyA9IHVzZXJTaWduZXIuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBwMnBNZXNzYWdlczogZGVzZXJpYWxpemVkTWVzc2FnZXMucDJwTWVzc2FnZXMsXG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW10sXG4gICAgfSk7XG4gICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVSb3VuZDIgPSBhd2FpdCBnZXRTaWduYXR1cmVTaGFyZVJvdW5kVHdvKFxuICAgICAgdXNlclRvQml0R29NZXNzYWdlc1JvdW5kMixcbiAgICAgIHVzZXJUb0JpdEdvTWVzc2FnZXNSb3VuZDMsXG4gICAgICB1c2VyR3BnS2V5LFxuICAgICAgYml0Z29HcGdLZXlcbiAgICApO1xuICAgIGNvbnN0IHNlc3Npb24gPSB1c2VyU2lnbmVyLmdldFNlc3Npb24oKTtcbiAgICBjb25zdCBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uID0gdGhpcy5iaXRnby5lbmNyeXB0KHsgaW5wdXQ6IHNlc3Npb24sIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLCBhZGF0YSB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBzaWduYXR1cmVTaGFyZVJvdW5kMixcbiAgICAgIGVuY3J5cHRlZFJvdW5kMlNlc3Npb24sXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZU9mZmxpbmVSb3VuZDNTaGFyZShwYXJhbXM6IHtcbiAgICB0eFJlcXVlc3Q6IFR4UmVxdWVzdDtcbiAgICBwcnY6IHN0cmluZztcbiAgICB3YWxsZXRQYXNzcGhyYXNlOiBzdHJpbmc7XG4gICAgYml0Z29QdWJsaWNHcGdLZXk6IHN0cmluZztcbiAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiBzdHJpbmc7XG4gICAgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbjogc3RyaW5nO1xuICB9KTogUHJvbWlzZTx7XG4gICAgc2lnbmF0dXJlU2hhcmVSb3VuZDM6IFNpZ25hdHVyZVNoYXJlUmVjb3JkO1xuICB9PiB7XG4gICAgY29uc3QgeyBwcnYsIHdhbGxldFBhc3NwaHJhc2UsIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXksIGVuY3J5cHRlZFJvdW5kMlNlc3Npb24sIGJpdGdvUHVibGljR3BnS2V5LCB0eFJlcXVlc3QgfSA9XG4gICAgICBwYXJhbXM7XG5cbiAgICBhc3NlcnQodHhSZXF1ZXN0LnRyYW5zYWN0aW9ucyAmJiB0eFJlcXVlc3QudHJhbnNhY3Rpb25zLmxlbmd0aCA9PT0gMSwgJ1VuYWJsZSB0byBmaW5kIHRyYW5zYWN0aW9ucyBpbiB0eFJlcXVlc3QnKTtcbiAgICBjb25zdCB7IGhhc2hCdWZmZXIsIGRlcml2YXRpb25QYXRoIH0gPSB0aGlzLmdldEhhc2hTdHJpbmdBbmREZXJpdmF0aW9uUGF0aCh0eFJlcXVlc3QpO1xuICAgIGNvbnN0IGFkYXRhID0gYCR7aGFzaEJ1ZmZlci50b1N0cmluZygnaGV4Jyl9OiR7ZGVyaXZhdGlvblBhdGh9YDtcblxuICAgIGNvbnN0IHsgYml0Z29HcGdLZXksIHVzZXJHcGdLZXkgfSA9IGF3YWl0IHRoaXMuZ2V0Qml0Z29BbmRVc2VyR3BnS2V5cyhcbiAgICAgIGJpdGdvUHVibGljR3BnS2V5LFxuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2VcbiAgICApO1xuXG4gICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVzID0gdHhSZXF1ZXN0LnRyYW5zYWN0aW9ucz8uWzBdLnNpZ25hdHVyZVNoYXJlcztcbiAgICBhc3NlcnQoc2lnbmF0dXJlU2hhcmVzLCAnTWlzc2luZyBzaWduYXR1cmUgc2hhcmVzIGluIHJvdW5kIDIgdHhSZXF1ZXN0Jyk7XG4gICAgY29uc3QgcGFyc2VkQml0R29Ub1VzZXJTaWdTaGFyZVJvdW5kVHdvID0gSlNPTi5wYXJzZShcbiAgICAgIHNpZ25hdHVyZVNoYXJlc1tzaWduYXR1cmVTaGFyZXMubGVuZ3RoIC0gMV0uc2hhcmVcbiAgICApIGFzIE1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJPdXRwdXQ7XG4gICAgaWYgKHBhcnNlZEJpdEdvVG9Vc2VyU2lnU2hhcmVSb3VuZFR3by50eXBlICE9PSAncm91bmQyT3V0cHV0Jykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmV4cGVjdGVkIHNpZ25hdHVyZSBzaGFyZSByZXNwb25zZS4gVW5hYmxlIHRvIHBhcnNlIGRhdGEuJyk7XG4gICAgfVxuICAgIGNvbnN0IHNlcmlhbGl6ZWRCaXRHb1RvVXNlck1lc3NhZ2VzUm91bmQzID0gYXdhaXQgdmVyaWZ5Qml0R29NZXNzYWdlc0FuZFNpZ25hdHVyZXNSb3VuZFR3byhcbiAgICAgIHBhcnNlZEJpdEdvVG9Vc2VyU2lnU2hhcmVSb3VuZFR3byxcbiAgICAgIHVzZXJHcGdLZXksXG4gICAgICBiaXRnb0dwZ0tleVxuICAgICk7XG5cbiAgICBjb25zdCBkZXNlcmlhbGl6ZWRCaXRHb1RvVXNlck1lc3NhZ2VzUm91bmQzID0gRGtsc1R5cGVzLmRlc2VyaWFsaXplTWVzc2FnZXMoe1xuICAgICAgcDJwTWVzc2FnZXM6IHNlcmlhbGl6ZWRCaXRHb1RvVXNlck1lc3NhZ2VzUm91bmQzLnAycE1lc3NhZ2VzLFxuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgcm91bmQyU2Vzc2lvbiA9IHRoaXMuYml0Z28uZGVjcnlwdCh7IGlucHV0OiBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KTtcbiAgICB0aGlzLnZhbGlkYXRlQWRhdGEoYWRhdGEsIGVuY3J5cHRlZFJvdW5kMlNlc3Npb24pO1xuICAgIGNvbnN0IHVzZXJLZXlTaGFyZSA9IEJ1ZmZlci5mcm9tKHBydiwgJ2Jhc2U2NCcpO1xuICAgIGNvbnN0IHVzZXJTaWduZXIgPSBuZXcgRGtsc0RzZy5Ec2codXNlcktleVNoYXJlLCAwLCBkZXJpdmF0aW9uUGF0aCwgaGFzaEJ1ZmZlcik7XG4gICAgYXdhaXQgdXNlclNpZ25lci5zZXRTZXNzaW9uKHJvdW5kMlNlc3Npb24pO1xuXG4gICAgY29uc3QgdXNlclRvQml0R29NZXNzYWdlc1JvdW5kNCA9IHVzZXJTaWduZXIuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBwMnBNZXNzYWdlczogZGVzZXJpYWxpemVkQml0R29Ub1VzZXJNZXNzYWdlc1JvdW5kMy5wMnBNZXNzYWdlcyxcbiAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHNpZ25hdHVyZVNoYXJlUm91bmQzID0gYXdhaXQgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFRocmVlKHVzZXJUb0JpdEdvTWVzc2FnZXNSb3VuZDQsIHVzZXJHcGdLZXksIGJpdGdvR3BnS2V5KTtcblxuICAgIHJldHVybiB7IHNpZ25hdHVyZVNoYXJlUm91bmQzIH07XG4gIH1cbiAgLy8gI2VuZHJlZ2lvblxufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4ga2V5IHNoYXJlLCB3aGVuIGRlY3J5cHRlZCwgY29udGFpbnMgdmFsaWQgR0cxOCBzaWduaW5nIG1hdGVyaWFsLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlTaGFyZSAtIFRoZSBlbmNyeXB0ZWQga2V5IHNoYXJlIHN0cmluZy5cbiAqIEBwYXJhbSB7c3RyaW5nfHVuZGVmaW5lZH0gd2FsbGV0UGFzc3BocmFzZSAtIFRoZSBwYXNzcGhyYXNlIHVzZWQgdG8gZGVjcnlwdCB0aGUga2V5IHNoYXJlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZGVjcnlwdGVkIGRhdGEgY29udGFpbnMgdmFsaWQgc2lnbmluZyBtYXRlcmlhbCwgb3RoZXJ3aXNlIGBmYWxzZWAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0dHMThTaWduaW5nTWF0ZXJpYWwoa2V5U2hhcmU6IHN0cmluZywgd2FsbGV0UGFzc3BocmFzZTogc3RyaW5nIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gIGNvbnN0IHBydiA9IHNqY2wuZGVjcnlwdCh3YWxsZXRQYXNzcGhyYXNlLCBrZXlTaGFyZSk7XG4gIHRyeSB7XG4gICAgY29uc3Qgc2lnbmluZ01hdGVyaWFsID0gSlNPTi5wYXJzZShwcnYpO1xuICAgIHJldHVybiAoXG4gICAgICBzaWduaW5nTWF0ZXJpYWwucFNoYXJlICYmXG4gICAgICBzaWduaW5nTWF0ZXJpYWwuYml0Z29OU2hhcmUgJiZcbiAgICAgIChzaWduaW5nTWF0ZXJpYWwudXNlck5TaGFyZSB8fCBzaWduaW5nTWF0ZXJpYWwuYmFja3VwTlNoYXJlKVxuICAgICk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogR2V0IHRoZSBNUEMgdjIgcmVjb3Zlcnkga2V5IHNoYXJlcyBmcm9tIHRoZSBwcm92aWRlZCB1c2VyIGFuZCBiYWNrdXAga2V5IHNoYXJlcy5cbiAqIEBwYXJhbSBlbmNyeXB0ZWRVc2VyS2V5IGVuY3J5cHRlZCBnZzE4IG9yIE1QQ3YyIHVzZXIga2V5XG4gKiBAcGFyYW0gZW5jcnlwdGVkQmFja3VwS2V5IGVuY3J5cHRlZCBnZzE4IG9yIE1QQ3YyIGJhY2t1cCBrZXlcbiAqIEBwYXJhbSB3YWxsZXRQYXNzcGhyYXNlIHBhc3N3b3JkIGZvciB1c2VyIGFuZCBiYWNrdXAga2V5XG4gKiBAcmV0dXJucyBNUEMgdjIgcmVjb3Zlcnkga2V5IHNoYXJlc1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0TXBjVjJSZWNvdmVyeUtleVNoYXJlcyhcbiAgZW5jcnlwdGVkVXNlcktleTogc3RyaW5nLFxuICBlbmNyeXB0ZWRCYWNrdXBLZXk6IHN0cmluZyxcbiAgd2FsbGV0UGFzc3BocmFzZT86IHN0cmluZ1xuKTogUHJvbWlzZTx7XG4gIHVzZXJLZXlTaGFyZTogQnVmZmVyO1xuICBiYWNrdXBLZXlTaGFyZTogQnVmZmVyO1xuICBjb21tb25LZXlDaGFpbjogc3RyaW5nO1xufT4ge1xuICBpZiAoaXNHRzE4U2lnbmluZ01hdGVyaWFsKGVuY3J5cHRlZFVzZXJLZXksIHdhbGxldFBhc3NwaHJhc2UpKSB7XG4gICAgcmV0dXJuIGdldE1wY1YyUmVjb3ZlcnlLZXlTaGFyZXNGcm9tR0cxOChlbmNyeXB0ZWRVc2VyS2V5LCBlbmNyeXB0ZWRCYWNrdXBLZXksIHdhbGxldFBhc3NwaHJhc2UpO1xuICB9XG4gIHJldHVybiBnZXRNcGNWMlJlY292ZXJ5S2V5U2hhcmVzRnJvbVJlZHVjZWRLZXkoZW5jcnlwdGVkVXNlcktleSwgZW5jcnlwdGVkQmFja3VwS2V5LCB3YWxsZXRQYXNzcGhyYXNlKTtcbn1cblxuLyoqXG4gKiBTaWducyBhIG1lc3NhZ2UgaGFzaCB1c2luZyBNUEMgdjIgcmVjb3Zlcnkga2V5IHNoYXJlcy5cbiAqXG4gKiBAcGFyYW0ge0J1ZmZlcn0gbWVzc2FnZUhhc2hcbiAqIEBwYXJhbSB7QnVmZmVyfSB1c2VyS2V5U2hhcmVcbiAqIEBwYXJhbSB7QnVmZmVyfSBiYWNrdXBLZXlTaGFyZVxuICogQHBhcmFtIHtzdHJpbmd9IGNvbW1vbktleUNoYWluXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx7IHJlY2lkOiBudW1iZXIsIHI6IHN0cmluZywgczogc3RyaW5nLCB5OiBzdHJpbmcgfT59XG4gKlxuICogQGFzeW5jXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaWduUmVjb3ZlcnlNcGNWMihcbiAgbWVzc2FnZUhhc2g6IEJ1ZmZlcixcbiAgdXNlcktleVNoYXJlOiBCdWZmZXIsXG4gIGJhY2t1cEtleVNoYXJlOiBCdWZmZXIsXG4gIGNvbW1vbktleUNoYWluOiBzdHJpbmdcbik6IFByb21pc2U8e1xuICByZWNpZDogbnVtYmVyO1xuICByOiBzdHJpbmc7XG4gIHM6IHN0cmluZztcbiAgeTogc3RyaW5nO1xufT4ge1xuICBjb25zdCB1c2VyRHNnID0gbmV3IERrbHNEc2cuRHNnKHVzZXJLZXlTaGFyZSwgMCwgJ20vMCcsIG1lc3NhZ2VIYXNoKTtcbiAgY29uc3QgYmFja3VwRHNnID0gbmV3IERrbHNEc2cuRHNnKGJhY2t1cEtleVNoYXJlLCAxLCAnbS8wJywgbWVzc2FnZUhhc2gpO1xuXG4gIGNvbnN0IHNpZ25hdHVyZVN0cmluZyA9IERrbHNVdGlscy52ZXJpZnlBbmRDb252ZXJ0RGtsc1NpZ25hdHVyZShcbiAgICBtZXNzYWdlSGFzaCxcbiAgICAoYXdhaXQgRGtsc1V0aWxzLmV4ZWN1dGVUaWxsUm91bmQoNSwgdXNlckRzZywgYmFja3VwRHNnKSkgYXMgRGtsc1R5cGVzLkRlc2VyaWFsaXplZERrbHNTaWduYXR1cmUsXG4gICAgY29tbW9uS2V5Q2hhaW4sXG4gICAgJ20vMCcsXG4gICAgdW5kZWZpbmVkLFxuICAgIGZhbHNlXG4gICk7XG4gIGNvbnN0IHNpZ1BhcnRzID0gc2lnbmF0dXJlU3RyaW5nLnNwbGl0KCc6Jyk7XG5cbiAgcmV0dXJuIHtcbiAgICByZWNpZDogcGFyc2VJbnQoc2lnUGFydHNbMF0sIDEwKSxcbiAgICByOiBzaWdQYXJ0c1sxXSxcbiAgICBzOiBzaWdQYXJ0c1syXSxcbiAgICB5OiBzaWdQYXJ0c1szXSxcbiAgfTtcbn1cblxuLy8gI3JlZ2lvbiBwcml2YXRlIHV0aWxzXG5cbi8qKlxuICogR2V0IHRoZSBNUEMgdjIgcmVjb3Zlcnkga2V5IHNoYXJlcyBmcm9tIHRoZSBwcm92aWRlZCB1c2VyIGFuZCBiYWNrdXAga2V5IHNoYXJlcy5cbiAqIEBwYXJhbSBlbmNyeXB0ZWRHRzE4VXNlcktleSBlbmNyeXB0ZWQgZ2cxOCB1c2VyIGtleVxuICogQHBhcmFtIGVuY3J5cHRlZEdHMThCYWNrdXBLZXkgZW5jcnlwdGVkIGdnMTggYmFja3VwIGtleVxuICogQHBhcmFtIHdhbGxldFBhc3NwaHJhc2UgcGFzc3dvcmQgZm9yIHVzZXIgYW5kIGJhY2t1cCBrZXlcbiAqIEByZXR1cm5zIE1QQyB2MiByZWNvdmVyeSBrZXkgc2hhcmVzXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldE1wY1YyUmVjb3ZlcnlLZXlTaGFyZXNGcm9tR0cxOChcbiAgZW5jcnlwdGVkR0cxOFVzZXJLZXk6IHN0cmluZyxcbiAgZW5jcnlwdGVkR0cxOEJhY2t1cEtleTogc3RyaW5nLFxuICB3YWxsZXRQYXNzcGhyYXNlPzogc3RyaW5nXG4pOiBQcm9taXNlPHtcbiAgdXNlcktleVNoYXJlOiBCdWZmZXI7XG4gIGJhY2t1cEtleVNoYXJlOiBCdWZmZXI7XG4gIGNvbW1vbktleUNoYWluOiBzdHJpbmc7XG59PiB7XG4gIGNvbnN0IFt1c2VyS2V5Q29tYmluZWQsIGJhY2t1cEtleUNvbWJpbmVkXSA9IGdldEtleUNvbWJpbmVkRnJvbVRzc0tleVNoYXJlcyhcbiAgICBlbmNyeXB0ZWRHRzE4VXNlcktleSxcbiAgICBlbmNyeXB0ZWRHRzE4QmFja3VwS2V5LFxuICAgIHdhbGxldFBhc3NwaHJhc2VcbiAgKTtcbiAgY29uc3QgcmV0cm9maXREYXRhQTogRGtsc1R5cGVzLlJldHJvZml0RGF0YSA9IHtcbiAgICB4U2hhcmU6IHVzZXJLZXlDb21iaW5lZC54U2hhcmUsXG4gIH07XG4gIGNvbnN0IHJldHJvZml0RGF0YUI6IERrbHNUeXBlcy5SZXRyb2ZpdERhdGEgPSB7XG4gICAgeFNoYXJlOiBiYWNrdXBLZXlDb21iaW5lZC54U2hhcmUsXG4gIH07XG4gIGNvbnN0IFt1c2VyLCBiYWNrdXBdID0gYXdhaXQgRGtsc1V0aWxzLmdlbmVyYXRlMm9mMktleVNoYXJlcyhyZXRyb2ZpdERhdGFBLCByZXRyb2ZpdERhdGFCKTtcblxuICBjb25zdCB1c2VyS2V5U2hhcmUgPSB1c2VyLmdldEtleVNoYXJlKCk7XG4gIGNvbnN0IGJhY2t1cEtleVNoYXJlID0gYmFja3VwLmdldEtleVNoYXJlKCk7XG4gIHJldHVybiB7XG4gICAgdXNlcktleVNoYXJlLFxuICAgIGJhY2t1cEtleVNoYXJlLFxuICAgIGNvbW1vbktleUNoYWluOiBEa2xzVHlwZXMuZ2V0Q29tbW9uS2V5Y2hhaW4oYmFja3VwS2V5U2hhcmUpLFxuICB9O1xufVxuXG4vKipcbiAqIFJldHJpZXZlcyB0aGUgTVBDIHYyIHJlY292ZXJ5IGtleSBzaGFyZXMgZnJvbSB0aGUgcHJvdmlkZWQgdXNlciBhbmQgYmFja3VwIGtleSBzaGFyZXMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGVuY3J5cHRlZE1QQ3YyVXNlcktleVxuICogQHBhcmFtIHtzdHJpbmd9IGVuY3J5cHRlZE1QQ3YyQmFja3VwS2V5XG4gKiBAcGFyYW0ge3N0cmluZ30gW3dhbGxldFBhc3NwaHJhc2VdIC0gVGhlIHBhc3NwaHJhc2UgdXNlZCB0byBkZWNyeXB0IHRoZSBrZXkgc2hhcmVzXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx7IHVzZXJLZXlTaGFyZTogS2V5U2hhcmUsIGJhY2t1cEtleVNoYXJlOiBLZXlTaGFyZSwgY29tbW9uS2V5Q2hhaW46IHN0cmluZyB9Pn1cbiAqXG4gKiBAYXN5bmNcbiAqL1xuYXN5bmMgZnVuY3Rpb24gZ2V0TXBjVjJSZWNvdmVyeUtleVNoYXJlc0Zyb21SZWR1Y2VkS2V5KFxuICBlbmNyeXB0ZWRNUEN2MlVzZXJLZXk6IHN0cmluZyxcbiAgZW5jcnlwdGVkTVBDdjJCYWNrdXBLZXk6IHN0cmluZyxcbiAgd2FsbGV0UGFzc3BocmFzZT86IHN0cmluZ1xuKTogUHJvbWlzZTx7XG4gIHVzZXJLZXlTaGFyZTogQnVmZmVyO1xuICBiYWNrdXBLZXlTaGFyZTogQnVmZmVyO1xuICBjb21tb25LZXlDaGFpbjogc3RyaW5nO1xufT4ge1xuICBjb25zdCB1c2VyQ29tcHJlc3NlZFBydiA9IEJ1ZmZlci5mcm9tKHNqY2wuZGVjcnlwdCh3YWxsZXRQYXNzcGhyYXNlLCBlbmNyeXB0ZWRNUEN2MlVzZXJLZXkpLCAnYmFzZTY0Jyk7XG4gIGNvbnN0IGJha2N1cENvbXByZXNzZWRQcnYgPSBCdWZmZXIuZnJvbShzamNsLmRlY3J5cHQod2FsbGV0UGFzc3BocmFzZSwgZW5jcnlwdGVkTVBDdjJCYWNrdXBLZXkpLCAnYmFzZTY0Jyk7XG5cbiAgY29uc3QgdXNlclBydkpTT046IERrbHNUeXBlcy5SZWR1Y2VkS2V5U2hhcmUgPSBEa2xzVHlwZXMuZ2V0RGVjb2RlZFJlZHVjZWRLZXlTaGFyZSh1c2VyQ29tcHJlc3NlZFBydik7XG4gIGNvbnN0IGJhY2t1cFBydkpTT046IERrbHNUeXBlcy5SZWR1Y2VkS2V5U2hhcmUgPSBEa2xzVHlwZXMuZ2V0RGVjb2RlZFJlZHVjZWRLZXlTaGFyZShiYWtjdXBDb21wcmVzc2VkUHJ2KTtcbiAgY29uc3QgdXNlcktleVJldHJvZml0OiBEa2xzVHlwZXMuUmV0cm9maXREYXRhID0ge1xuICAgIHhTaGFyZToge1xuICAgICAgeDogQnVmZmVyLmZyb20odXNlclBydkpTT04ucHJ2KS50b1N0cmluZygnaGV4JyksXG4gICAgICB5OiBCdWZmZXIuZnJvbSh1c2VyUHJ2SlNPTi5wdWIpLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgIGNoYWluY29kZTogQnVmZmVyLmZyb20odXNlclBydkpTT04ucm9vdENoYWluQ29kZSkudG9TdHJpbmcoJ2hleCcpLFxuICAgIH0sXG4gICAgeGlMaXN0OiB1c2VyUHJ2SlNPTi54TGlzdC5zbGljZSgwLCAyKSxcbiAgfTtcbiAgY29uc3QgYmFja3VwS2V5UmV0cm9maXQ6IERrbHNUeXBlcy5SZXRyb2ZpdERhdGEgPSB7XG4gICAgeFNoYXJlOiB7XG4gICAgICB4OiBCdWZmZXIuZnJvbShiYWNrdXBQcnZKU09OLnBydikudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgeTogQnVmZmVyLmZyb20oYmFja3VwUHJ2SlNPTi5wdWIpLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgIGNoYWluY29kZTogQnVmZmVyLmZyb20oYmFja3VwUHJ2SlNPTi5yb290Q2hhaW5Db2RlKS50b1N0cmluZygnaGV4JyksXG4gICAgfSxcbiAgICB4aUxpc3Q6IGJhY2t1cFBydkpTT04ueExpc3Quc2xpY2UoMCwgMiksXG4gIH07XG4gIGNvbnN0IFt1c2VyLCBiYWNrdXBdID0gYXdhaXQgRGtsc1V0aWxzLmdlbmVyYXRlMm9mMktleVNoYXJlcyh1c2VyS2V5UmV0cm9maXQsIGJhY2t1cEtleVJldHJvZml0KTtcbiAgY29uc3QgdXNlcktleVNoYXJlID0gdXNlci5nZXRLZXlTaGFyZSgpO1xuICBjb25zdCBiYWNrdXBLZXlTaGFyZSA9IGJhY2t1cC5nZXRLZXlTaGFyZSgpO1xuICBjb25zdCBjb21tb25LZXlDaGFpbiA9IERrbHNUeXBlcy5nZXRDb21tb25LZXljaGFpbih1c2VyS2V5U2hhcmUpO1xuICByZXR1cm4geyB1c2VyS2V5U2hhcmUsIGJhY2t1cEtleVNoYXJlLCBjb21tb25LZXlDaGFpbiB9O1xufVxuXG4vKipcbiAqIEdldHMgdGhlIGNvbWJpbmVkIGtleSBmb3IgR0cxOFxuICogQHBhcmFtIGVuY3J5cHRlZEdHMThVc2VyS2V5IGVuY3J5cHRlZCBHRzE4IHVzZXIga2V5XG4gKiBAcGFyYW0gZW5jcnlwdGVkR0cxOEJhY2t1cEtleSBlbmNyeXB0ZWQgR0cxOCBiYWNrdXAga2V5XG4gKiBAcGFyYW0gd2FsbGV0UGFzc3BocmFzZSB3YWxsZXQgcGFzc3BocmFzZVxuICogQHJldHVybnMga2V5IHNoYXJlc1xuICovXG5mdW5jdGlvbiBnZXRLZXlDb21iaW5lZEZyb21Uc3NLZXlTaGFyZXMoXG4gIGVuY3J5cHRlZEdHMThVc2VyS2V5OiBzdHJpbmcsXG4gIGVuY3J5cHRlZEdHMThCYWNrdXBLZXk6IHN0cmluZyxcbiAgd2FsbGV0UGFzc3BocmFzZT86IHN0cmluZ1xuKTogW0VDRFNBTWV0aG9kVHlwZXMuS2V5Q29tYmluZWQsIEVDRFNBTWV0aG9kVHlwZXMuS2V5Q29tYmluZWRdIHtcbiAgbGV0IGJhY2t1cFBydjtcbiAgbGV0IHVzZXJQcnY7XG4gIHRyeSB7XG4gICAgYmFja3VwUHJ2ID0gc2pjbC5kZWNyeXB0KHdhbGxldFBhc3NwaHJhc2UsIGVuY3J5cHRlZEdHMThCYWNrdXBLZXkpO1xuICAgIHVzZXJQcnYgPSBzamNsLmRlY3J5cHQod2FsbGV0UGFzc3BocmFzZSwgZW5jcnlwdGVkR0cxOFVzZXJLZXkpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBFcnJvciBkZWNyeXB0aW5nIGJhY2t1cCBrZXljaGFpbjogJHtlLm1lc3NhZ2V9YCk7XG4gIH1cblxuICBjb25zdCB1c2VyU2lnbmluZ01hdGVyaWFsID0gSlNPTi5wYXJzZSh1c2VyUHJ2KSBhcyBFQ0RTQU1ldGhvZFR5cGVzLlNpZ25pbmdNYXRlcmlhbDtcbiAgY29uc3QgYmFja3VwU2lnbmluZ01hdGVyaWFsID0gSlNPTi5wYXJzZShiYWNrdXBQcnYpIGFzIEVDRFNBTWV0aG9kVHlwZXMuU2lnbmluZ01hdGVyaWFsO1xuXG4gIGlmICghdXNlclNpZ25pbmdNYXRlcmlhbC5iYWNrdXBOU2hhcmUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdXNlciBrZXkgLSBtaXNzaW5nIGJhY2t1cE5TaGFyZScpO1xuICB9XG5cbiAgaWYgKCFiYWNrdXBTaWduaW5nTWF0ZXJpYWwudXNlck5TaGFyZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBiYWNrdXAga2V5IC0gbWlzc2luZyB1c2VyTlNoYXJlJyk7XG4gIH1cblxuICBjb25zdCBNUEMgPSBuZXcgRWNkc2EoKTtcblxuICBjb25zdCB1c2VyS2V5Q29tYmluZWQgPSBNUEMua2V5Q29tYmluZSh1c2VyU2lnbmluZ01hdGVyaWFsLnBTaGFyZSwgW1xuICAgIHVzZXJTaWduaW5nTWF0ZXJpYWwuYml0Z29OU2hhcmUsXG4gICAgdXNlclNpZ25pbmdNYXRlcmlhbC5iYWNrdXBOU2hhcmUsXG4gIF0pO1xuICBjb25zdCBiYWNrdXBLZXlDb21iaW5lZCA9IE1QQy5rZXlDb21iaW5lKGJhY2t1cFNpZ25pbmdNYXRlcmlhbC5wU2hhcmUsIFtcbiAgICBiYWNrdXBTaWduaW5nTWF0ZXJpYWwudXNlck5TaGFyZSxcbiAgICBiYWNrdXBTaWduaW5nTWF0ZXJpYWwuYml0Z29OU2hhcmUsXG4gIF0pO1xuICBpZiAoXG4gICAgdXNlcktleUNvbWJpbmVkLnhTaGFyZS55ICE9PSBiYWNrdXBLZXlDb21iaW5lZC54U2hhcmUueSB8fFxuICAgIHVzZXJLZXlDb21iaW5lZC54U2hhcmUuY2hhaW5jb2RlICE9PSBiYWNrdXBLZXlDb21iaW5lZC54U2hhcmUuY2hhaW5jb2RlXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29tbW9uIGtleWNoYWlucyBkbyBub3QgbWF0Y2gnKTtcbiAgfVxuICByZXR1cm4gW3VzZXJLZXlDb21iaW5lZCwgYmFja3VwS2V5Q29tYmluZWRdO1xufVxuXG4vLyAjZW5kcmVnaW9uXG4iXX0=