@bitgo-beta/sdk-core 8.2.1-beta.190 → 8.2.1-beta.1901

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 (643) hide show
  1. package/dist/src/account-lib/baseCoin/baseTransaction.d.ts +0 -1
  2. package/dist/src/account-lib/baseCoin/baseTransaction.d.ts.map +1 -1
  3. package/dist/src/account-lib/baseCoin/baseTransactionBuilder.d.ts +3 -3
  4. package/dist/src/account-lib/baseCoin/baseTransactionBuilder.d.ts.map +1 -1
  5. package/dist/src/account-lib/baseCoin/baseTransactionBuilder.js +4 -3
  6. package/dist/src/account-lib/baseCoin/ed25519KeyPair.d.ts +1 -0
  7. package/dist/src/account-lib/baseCoin/ed25519KeyPair.d.ts.map +1 -1
  8. package/dist/src/account-lib/baseCoin/ed25519KeyPair.js +41 -29
  9. package/dist/src/account-lib/baseCoin/enum.d.ts +53 -5
  10. package/dist/src/account-lib/baseCoin/enum.d.ts.map +1 -1
  11. package/dist/src/account-lib/baseCoin/enum.js +97 -10
  12. package/dist/src/account-lib/baseCoin/errors.d.ts +3 -0
  13. package/dist/src/account-lib/baseCoin/errors.d.ts.map +1 -1
  14. package/dist/src/account-lib/baseCoin/errors.js +8 -2
  15. package/dist/src/account-lib/baseCoin/iface.d.ts +19 -35
  16. package/dist/src/account-lib/baseCoin/iface.d.ts.map +1 -1
  17. package/dist/src/account-lib/baseCoin/iface.js +26 -18
  18. package/dist/src/account-lib/baseCoin/index.d.ts +1 -1
  19. package/dist/src/account-lib/baseCoin/index.d.ts.map +1 -1
  20. package/dist/src/account-lib/baseCoin/index.js +8 -5
  21. package/dist/src/account-lib/baseCoin/messages/baseMessage.d.ts +88 -0
  22. package/dist/src/account-lib/baseCoin/messages/baseMessage.d.ts.map +1 -0
  23. package/dist/src/account-lib/baseCoin/messages/baseMessage.js +154 -0
  24. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilder.d.ts +67 -0
  25. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilder.d.ts.map +1 -0
  26. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilder.js +144 -0
  27. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts +33 -0
  28. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts.map +1 -0
  29. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilderFactory.js +45 -0
  30. package/dist/src/account-lib/baseCoin/messages/iface.d.ts +164 -0
  31. package/dist/src/account-lib/baseCoin/messages/iface.d.ts.map +1 -0
  32. package/dist/src/account-lib/baseCoin/messages/iface.js +3 -0
  33. package/dist/src/account-lib/baseCoin/messages/index.d.ts +6 -0
  34. package/dist/src/account-lib/baseCoin/messages/index.d.ts.map +1 -0
  35. package/dist/src/account-lib/baseCoin/messages/index.js +22 -0
  36. package/dist/src/account-lib/baseCoin/messages/simple/index.d.ts +3 -0
  37. package/dist/src/account-lib/baseCoin/messages/simple/index.d.ts.map +1 -0
  38. package/dist/src/account-lib/baseCoin/messages/simple/index.js +19 -0
  39. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessage.d.ts +13 -0
  40. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessage.d.ts.map +1 -0
  41. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessage.js +28 -0
  42. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessageBuilder.d.ts +21 -0
  43. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessageBuilder.d.ts.map +1 -0
  44. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessageBuilder.js +28 -0
  45. package/dist/src/account-lib/baseCoin/secp256k1ExtendedKeyPair.d.ts +1 -2
  46. package/dist/src/account-lib/baseCoin/secp256k1ExtendedKeyPair.d.ts.map +1 -1
  47. package/dist/src/account-lib/baseCoin/secp256k1ExtendedKeyPair.js +38 -26
  48. package/dist/src/account-lib/index.js +23 -9
  49. package/dist/src/account-lib/mpc/index.d.ts +1 -1
  50. package/dist/src/account-lib/mpc/index.d.ts.map +1 -1
  51. package/dist/src/account-lib/mpc/index.js +6 -2
  52. package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.d.ts +2 -3
  53. package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.d.ts.map +1 -1
  54. package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.js +376 -354
  55. package/dist/src/account-lib/mpc/tss/ecdsa/index.js +23 -9
  56. package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.d.ts +2 -2
  57. package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.d.ts.map +1 -1
  58. package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.js +3 -3
  59. package/dist/src/account-lib/mpc/tss/ecdsa/types.d.ts +46 -53
  60. package/dist/src/account-lib/mpc/tss/ecdsa/types.d.ts.map +1 -1
  61. package/dist/src/account-lib/mpc/tss/ecdsa/types.js +1 -1
  62. package/dist/src/account-lib/mpc/tss/eddsa/eddsa.d.ts +0 -1
  63. package/dist/src/account-lib/mpc/tss/eddsa/eddsa.d.ts.map +1 -1
  64. package/dist/src/account-lib/mpc/tss/eddsa/eddsa.js +66 -69
  65. package/dist/src/account-lib/mpc/tss/eddsa/index.js +23 -9
  66. package/dist/src/account-lib/mpc/tss/eddsa/types.d.ts +1 -1
  67. package/dist/src/account-lib/mpc/tss/eddsa/types.d.ts.map +1 -1
  68. package/dist/src/account-lib/mpc/tss/eddsa/types.js +1 -1
  69. package/dist/src/account-lib/mpc/tss/index.js +23 -9
  70. package/dist/src/account-lib/mpc/util.d.ts +7 -1
  71. package/dist/src/account-lib/mpc/util.d.ts.map +1 -1
  72. package/dist/src/account-lib/mpc/util.js +24 -1
  73. package/dist/src/account-lib/staking/index.js +6 -2
  74. package/dist/src/account-lib/staking/utils.js +3 -3
  75. package/dist/src/account-lib/util/crypto.d.ts +8 -2
  76. package/dist/src/account-lib/util/crypto.d.ts.map +1 -1
  77. package/dist/src/account-lib/util/crypto.js +69 -38
  78. package/dist/src/account-lib/util/ed25519KeyDeriver.d.ts +2 -1
  79. package/dist/src/account-lib/util/ed25519KeyDeriver.d.ts.map +1 -1
  80. package/dist/src/account-lib/util/ed25519KeyDeriver.js +5 -3
  81. package/dist/src/api/bip32path.js +2 -3
  82. package/dist/src/api/index.js +6 -2
  83. package/dist/src/api/types.d.ts +31 -0
  84. package/dist/src/api/types.d.ts.map +1 -1
  85. package/dist/src/api/types.js +1 -1
  86. package/dist/src/bitgo/address-book/address-book.d.ts +61 -0
  87. package/dist/src/bitgo/address-book/address-book.d.ts.map +1 -0
  88. package/dist/src/bitgo/address-book/address-book.js +150 -0
  89. package/dist/src/bitgo/address-book/index.d.ts +3 -0
  90. package/dist/src/bitgo/address-book/index.d.ts.map +1 -0
  91. package/dist/src/bitgo/address-book/index.js +19 -0
  92. package/dist/src/bitgo/address-book/types.d.ts +170 -0
  93. package/dist/src/bitgo/address-book/types.d.ts.map +1 -0
  94. package/dist/src/bitgo/address-book/types.js +3 -0
  95. package/dist/src/bitgo/baseCoin/baseCoin.d.ts +110 -11
  96. package/dist/src/bitgo/baseCoin/baseCoin.d.ts.map +1 -1
  97. package/dist/src/bitgo/baseCoin/baseCoin.js +169 -16
  98. package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts +270 -27
  99. package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts.map +1 -1
  100. package/dist/src/bitgo/baseCoin/iBaseCoin.js +14 -3
  101. package/dist/src/bitgo/baseCoin/index.js +6 -2
  102. package/dist/src/bitgo/bip32util.d.ts +3 -16
  103. package/dist/src/bitgo/bip32util.d.ts.map +1 -1
  104. package/dist/src/bitgo/bip32util.js +4 -56
  105. package/dist/src/bitgo/bitcoin.d.ts +0 -1
  106. package/dist/src/bitgo/bitcoin.d.ts.map +1 -1
  107. package/dist/src/bitgo/bitcoin.js +26 -13
  108. package/dist/src/bitgo/bitgoBase.d.ts +7 -3
  109. package/dist/src/bitgo/bitgoBase.d.ts.map +1 -1
  110. package/dist/src/bitgo/bitgoBase.js +1 -1
  111. package/dist/src/bitgo/coinFactory.d.ts +17 -3
  112. package/dist/src/bitgo/coinFactory.d.ts.map +1 -1
  113. package/dist/src/bitgo/coinFactory.js +26 -3
  114. package/dist/src/bitgo/config.d.ts +3 -95
  115. package/dist/src/bitgo/config.d.ts.map +1 -1
  116. package/dist/src/bitgo/config.js +26 -15
  117. package/dist/src/bitgo/defi/defiVault.d.ts +87 -0
  118. package/dist/src/bitgo/defi/defiVault.d.ts.map +1 -0
  119. package/dist/src/bitgo/defi/defiVault.js +225 -0
  120. package/dist/src/bitgo/defi/iDefiVault.d.ts +59 -0
  121. package/dist/src/bitgo/defi/iDefiVault.d.ts.map +1 -0
  122. package/dist/src/bitgo/defi/iDefiVault.js +6 -0
  123. package/dist/src/bitgo/defi/index.d.ts +3 -0
  124. package/dist/src/bitgo/defi/index.d.ts.map +1 -0
  125. package/dist/src/bitgo/defi/index.js +22 -0
  126. package/dist/src/bitgo/ecdh.d.ts +0 -1
  127. package/dist/src/bitgo/ecdh.d.ts.map +1 -1
  128. package/dist/src/bitgo/ecdh.js +26 -13
  129. package/dist/src/bitgo/enterprise/enterprise.d.ts +3 -4
  130. package/dist/src/bitgo/enterprise/enterprise.d.ts.map +1 -1
  131. package/dist/src/bitgo/enterprise/enterprise.js +39 -21
  132. package/dist/src/bitgo/enterprise/enterprises.js +27 -13
  133. package/dist/src/bitgo/enterprise/iEnterprise.d.ts +2 -3
  134. package/dist/src/bitgo/enterprise/iEnterprise.d.ts.map +1 -1
  135. package/dist/src/bitgo/enterprise/iEnterprise.js +1 -1
  136. package/dist/src/bitgo/enterprise/index.js +6 -2
  137. package/dist/src/bitgo/environments.d.ts +69 -5
  138. package/dist/src/bitgo/environments.d.ts.map +1 -1
  139. package/dist/src/bitgo/environments.js +417 -40
  140. package/dist/src/bitgo/errors.d.ts +175 -0
  141. package/dist/src/bitgo/errors.d.ts.map +1 -1
  142. package/dist/src/bitgo/errors.js +166 -2
  143. package/dist/src/bitgo/evm/evmUtils.d.ts +26 -0
  144. package/dist/src/bitgo/evm/evmUtils.d.ts.map +1 -0
  145. package/dist/src/bitgo/evm/evmUtils.js +50 -0
  146. package/dist/src/bitgo/index.d.ts +4 -1
  147. package/dist/src/bitgo/index.d.ts.map +1 -1
  148. package/dist/src/bitgo/index.js +30 -11
  149. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.d.ts +3 -3
  150. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.d.ts.map +1 -1
  151. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.js +1 -1
  152. package/dist/src/bitgo/inscriptionBuilder/index.js +6 -2
  153. package/dist/src/bitgo/internal/index.js +6 -2
  154. package/dist/src/bitgo/internal/internal.js +5 -6
  155. package/dist/src/bitgo/internal/keycard.d.ts +12 -8
  156. package/dist/src/bitgo/internal/keycard.d.ts.map +1 -1
  157. package/dist/src/bitgo/internal/keycard.js +60 -48
  158. package/dist/src/bitgo/keychain/decryptKeychain.d.ts +14 -0
  159. package/dist/src/bitgo/keychain/decryptKeychain.d.ts.map +1 -0
  160. package/dist/src/bitgo/keychain/decryptKeychain.js +36 -0
  161. package/dist/src/bitgo/keychain/iKeychains.d.ts +95 -10
  162. package/dist/src/bitgo/keychain/iKeychains.d.ts.map +1 -1
  163. package/dist/src/bitgo/keychain/iKeychains.js +2 -2
  164. package/dist/src/bitgo/keychain/index.d.ts +1 -0
  165. package/dist/src/bitgo/keychain/index.d.ts.map +1 -1
  166. package/dist/src/bitgo/keychain/index.js +7 -2
  167. package/dist/src/bitgo/keychain/keychains.d.ts +39 -7
  168. package/dist/src/bitgo/keychain/keychains.d.ts.map +1 -1
  169. package/dist/src/bitgo/keychain/keychains.js +227 -52
  170. package/dist/src/bitgo/keychain/ovcJsonCodec.d.ts +3 -3
  171. package/dist/src/bitgo/keychain/ovcJsonCodec.d.ts.map +1 -1
  172. package/dist/src/bitgo/keychain/ovcJsonCodec.js +23 -9
  173. package/dist/src/bitgo/legacyBitcoin.d.ts +0 -1
  174. package/dist/src/bitgo/legacyBitcoin.d.ts.map +1 -1
  175. package/dist/src/bitgo/legacyBitcoin.js +27 -13
  176. package/dist/src/bitgo/lightning/lightningWalletUtil.d.ts +7 -0
  177. package/dist/src/bitgo/lightning/lightningWalletUtil.d.ts.map +1 -0
  178. package/dist/src/bitgo/lightning/lightningWalletUtil.js +25 -0
  179. package/dist/src/bitgo/market/iMarkets.d.ts +2 -2
  180. package/dist/src/bitgo/market/iMarkets.d.ts.map +1 -1
  181. package/dist/src/bitgo/market/index.js +6 -2
  182. package/dist/src/bitgo/market/markets.js +23 -9
  183. package/dist/src/bitgo/pendingApproval/iPendingApproval.d.ts +1 -0
  184. package/dist/src/bitgo/pendingApproval/iPendingApproval.d.ts.map +1 -1
  185. package/dist/src/bitgo/pendingApproval/iPendingApproval.js +4 -4
  186. package/dist/src/bitgo/pendingApproval/index.js +6 -2
  187. package/dist/src/bitgo/pendingApproval/pendingApproval.d.ts +20 -8
  188. package/dist/src/bitgo/pendingApproval/pendingApproval.d.ts.map +1 -1
  189. package/dist/src/bitgo/pendingApproval/pendingApproval.js +228 -110
  190. package/dist/src/bitgo/pendingApproval/pendingApprovals.js +23 -9
  191. package/dist/src/bitgo/proofs/WalletProofs.d.ts +19 -0
  192. package/dist/src/bitgo/proofs/WalletProofs.d.ts.map +1 -0
  193. package/dist/src/bitgo/proofs/WalletProofs.js +37 -0
  194. package/dist/src/bitgo/proofs/index.d.ts +2 -0
  195. package/dist/src/bitgo/proofs/index.d.ts.map +1 -0
  196. package/dist/src/bitgo/proofs/index.js +6 -0
  197. package/dist/src/bitgo/proofs/types.d.ts +80 -0
  198. package/dist/src/bitgo/proofs/types.d.ts.map +1 -0
  199. package/dist/src/bitgo/proofs/types.js +80 -0
  200. package/dist/src/bitgo/recovery/index.js +6 -2
  201. package/dist/src/bitgo/recovery/initiate.d.ts +13 -3
  202. package/dist/src/bitgo/recovery/initiate.d.ts.map +1 -1
  203. package/dist/src/bitgo/recovery/initiate.js +49 -41
  204. package/dist/src/bitgo/staking/goStakingInterfaces.d.ts +136 -0
  205. package/dist/src/bitgo/staking/goStakingInterfaces.d.ts.map +1 -0
  206. package/dist/src/bitgo/staking/goStakingInterfaces.js +3 -0
  207. package/dist/src/bitgo/staking/goStakingWallet.d.ts +62 -0
  208. package/dist/src/bitgo/staking/goStakingWallet.d.ts.map +1 -0
  209. package/dist/src/bitgo/staking/goStakingWallet.js +141 -0
  210. package/dist/src/bitgo/staking/iGoStakingWallet.d.ts +17 -0
  211. package/dist/src/bitgo/staking/iGoStakingWallet.d.ts.map +1 -0
  212. package/dist/src/bitgo/staking/iGoStakingWallet.js +3 -0
  213. package/dist/src/bitgo/staking/iStakingWallet.d.ts +178 -7
  214. package/dist/src/bitgo/staking/iStakingWallet.d.ts.map +1 -1
  215. package/dist/src/bitgo/staking/iStakingWallet.js +2 -2
  216. package/dist/src/bitgo/staking/index.d.ts +3 -0
  217. package/dist/src/bitgo/staking/index.d.ts.map +1 -1
  218. package/dist/src/bitgo/staking/index.js +9 -2
  219. package/dist/src/bitgo/staking/stakingWallet.d.ts +21 -8
  220. package/dist/src/bitgo/staking/stakingWallet.d.ts.map +1 -1
  221. package/dist/src/bitgo/staking/stakingWallet.js +140 -7
  222. package/dist/src/bitgo/trading/iTradingAccount.d.ts +15 -1
  223. package/dist/src/bitgo/trading/iTradingAccount.d.ts.map +1 -1
  224. package/dist/src/bitgo/trading/iTradingAccount.js +1 -1
  225. package/dist/src/bitgo/trading/index.d.ts +1 -0
  226. package/dist/src/bitgo/trading/index.d.ts.map +1 -1
  227. package/dist/src/bitgo/trading/index.js +7 -2
  228. package/dist/src/bitgo/trading/network/decrypt-aes-gcm.d.ts +8 -0
  229. package/dist/src/bitgo/trading/network/decrypt-aes-gcm.d.ts.map +1 -0
  230. package/dist/src/bitgo/trading/network/decrypt-aes-gcm.js +31 -0
  231. package/dist/src/bitgo/trading/network/decrypt-rsa.d.ts +8 -0
  232. package/dist/src/bitgo/trading/network/decrypt-rsa.d.ts.map +1 -0
  233. package/dist/src/bitgo/trading/network/decrypt-rsa.js +23 -0
  234. package/dist/src/bitgo/trading/network/decrypt.d.ts +14 -0
  235. package/dist/src/bitgo/trading/network/decrypt.d.ts.map +1 -0
  236. package/dist/src/bitgo/trading/network/decrypt.js +23 -0
  237. package/dist/src/bitgo/trading/network/encrypt-aes-gcm.d.ts +8 -0
  238. package/dist/src/bitgo/trading/network/encrypt-aes-gcm.d.ts.map +1 -0
  239. package/dist/src/bitgo/trading/network/encrypt-aes-gcm.js +25 -0
  240. package/dist/src/bitgo/trading/network/encrypt-rsa-browser.d.ts +8 -0
  241. package/dist/src/bitgo/trading/network/encrypt-rsa-browser.d.ts.map +1 -0
  242. package/dist/src/bitgo/trading/network/encrypt-rsa-browser.js +65 -0
  243. package/dist/src/bitgo/trading/network/encrypt-rsa.d.ts +8 -0
  244. package/dist/src/bitgo/trading/network/encrypt-rsa.d.ts.map +1 -0
  245. package/dist/src/bitgo/trading/network/encrypt-rsa.js +23 -0
  246. package/dist/src/bitgo/trading/network/encrypt.d.ts +37 -0
  247. package/dist/src/bitgo/trading/network/encrypt.d.ts.map +1 -0
  248. package/dist/src/bitgo/trading/network/encrypt.js +58 -0
  249. package/dist/src/bitgo/trading/network/index.d.ts +5 -0
  250. package/dist/src/bitgo/trading/network/index.d.ts.map +1 -0
  251. package/dist/src/bitgo/trading/network/index.js +21 -0
  252. package/dist/src/bitgo/trading/network/network.d.ts +36 -0
  253. package/dist/src/bitgo/trading/network/network.d.ts.map +1 -0
  254. package/dist/src/bitgo/trading/network/network.js +99 -0
  255. package/dist/src/bitgo/trading/network/types.d.ts +277 -0
  256. package/dist/src/bitgo/trading/network/types.d.ts.map +1 -0
  257. package/dist/src/bitgo/trading/network/types.js +3 -0
  258. package/dist/src/bitgo/trading/network/utils.d.ts +20 -0
  259. package/dist/src/bitgo/trading/network/utils.d.ts.map +1 -0
  260. package/dist/src/bitgo/trading/network/utils.js +54 -0
  261. package/dist/src/bitgo/trading/tradingAccount.d.ts +22 -1
  262. package/dist/src/bitgo/trading/tradingAccount.d.ts.map +1 -1
  263. package/dist/src/bitgo/trading/tradingAccount.js +64 -7
  264. package/dist/src/bitgo/tss/bitgoPubKeys.d.ts +38 -0
  265. package/dist/src/bitgo/tss/bitgoPubKeys.d.ts.map +1 -0
  266. package/dist/src/bitgo/tss/bitgoPubKeys.js +72 -0
  267. package/dist/src/bitgo/tss/common.d.ts +40 -6
  268. package/dist/src/bitgo/tss/common.d.ts.map +1 -1
  269. package/dist/src/bitgo/tss/common.js +122 -17
  270. package/dist/src/bitgo/tss/ecdsa/ecdsa.d.ts +6 -4
  271. package/dist/src/bitgo/tss/ecdsa/ecdsa.d.ts.map +1 -1
  272. package/dist/src/bitgo/tss/ecdsa/ecdsa.js +78 -66
  273. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.d.ts +15 -0
  274. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
  275. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.js +167 -0
  276. package/dist/src/bitgo/tss/ecdsa/index.d.ts +1 -0
  277. package/dist/src/bitgo/tss/ecdsa/index.d.ts.map +1 -1
  278. package/dist/src/bitgo/tss/ecdsa/index.js +25 -10
  279. package/dist/src/bitgo/tss/ecdsa/types.d.ts +27 -27
  280. package/dist/src/bitgo/tss/ecdsa/types.d.ts.map +1 -1
  281. package/dist/src/bitgo/tss/ecdsa/types.js +3 -3
  282. package/dist/src/bitgo/tss/eddsa/eddsa.d.ts +15 -6
  283. package/dist/src/bitgo/tss/eddsa/eddsa.d.ts.map +1 -1
  284. package/dist/src/bitgo/tss/eddsa/eddsa.js +47 -40
  285. package/dist/src/bitgo/tss/eddsa/eddsaMPCv2.d.ts +37 -0
  286. package/dist/src/bitgo/tss/eddsa/eddsaMPCv2.d.ts.map +1 -0
  287. package/dist/src/bitgo/tss/eddsa/eddsaMPCv2.js +95 -0
  288. package/dist/src/bitgo/tss/eddsa/index.js +23 -9
  289. package/dist/src/bitgo/tss/eddsa/types.d.ts +4 -4
  290. package/dist/src/bitgo/tss/eddsa/types.d.ts.map +1 -1
  291. package/dist/src/bitgo/tss/index.d.ts +3 -2
  292. package/dist/src/bitgo/tss/index.d.ts.map +1 -1
  293. package/dist/src/bitgo/tss/index.js +26 -10
  294. package/dist/src/bitgo/tss/types.d.ts +3 -3
  295. package/dist/src/bitgo/tss/types.d.ts.map +1 -1
  296. package/dist/src/bitgo/tss/types.js +2 -2
  297. package/dist/src/bitgo/types.d.ts +3 -3
  298. package/dist/src/bitgo/types.d.ts.map +1 -1
  299. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.d.ts +8 -0
  300. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.d.ts.map +1 -1
  301. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.js +55 -13
  302. package/dist/src/bitgo/utils/codecProps.js +24 -11
  303. package/dist/src/bitgo/utils/codecs.d.ts +11 -0
  304. package/dist/src/bitgo/utils/codecs.d.ts.map +1 -0
  305. package/dist/src/bitgo/utils/codecs.js +59 -0
  306. package/dist/src/bitgo/utils/decode.d.ts.map +1 -1
  307. package/dist/src/bitgo/utils/decode.js +30 -16
  308. package/dist/src/bitgo/utils/index.d.ts +4 -2
  309. package/dist/src/bitgo/utils/index.d.ts.map +1 -1
  310. package/dist/src/bitgo/utils/index.js +27 -11
  311. package/dist/src/bitgo/utils/messageTypes.d.ts +40 -0
  312. package/dist/src/bitgo/utils/messageTypes.d.ts.map +1 -0
  313. package/dist/src/bitgo/utils/messageTypes.js +17 -0
  314. package/dist/src/bitgo/utils/mpcUtils.d.ts +4 -4
  315. package/dist/src/bitgo/utils/mpcUtils.d.ts.map +1 -1
  316. package/dist/src/bitgo/utils/mpcUtils.js +153 -14
  317. package/dist/src/bitgo/utils/notEmpty.d.ts +2 -0
  318. package/dist/src/bitgo/utils/notEmpty.d.ts.map +1 -0
  319. package/dist/src/bitgo/utils/notEmpty.js +7 -0
  320. package/dist/src/bitgo/utils/opengpgUtils.d.ts +10 -7
  321. package/dist/src/bitgo/utils/opengpgUtils.d.ts.map +1 -1
  322. package/dist/src/bitgo/utils/opengpgUtils.js +75 -62
  323. package/dist/src/bitgo/utils/postWithCodec.d.ts.map +1 -1
  324. package/dist/src/bitgo/utils/postWithCodec.js +4 -38
  325. package/dist/src/bitgo/utils/promise-utils.d.ts +1 -1
  326. package/dist/src/bitgo/utils/promise-utils.d.ts.map +1 -1
  327. package/dist/src/bitgo/utils/promise-utils.js +2 -3
  328. package/dist/src/bitgo/utils/transactionUtils.d.ts +9 -0
  329. package/dist/src/bitgo/utils/transactionUtils.d.ts.map +1 -0
  330. package/dist/src/bitgo/utils/transactionUtils.js +29 -0
  331. package/dist/src/bitgo/utils/triple.d.ts +1 -1
  332. package/dist/src/bitgo/utils/triple.d.ts.map +1 -1
  333. package/dist/src/bitgo/utils/triple.js +2 -3
  334. package/dist/src/bitgo/utils/tss/addressVerification.d.ts +62 -0
  335. package/dist/src/bitgo/utils/tss/addressVerification.d.ts.map +1 -0
  336. package/dist/src/bitgo/utils/tss/addressVerification.js +93 -0
  337. package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts +97 -18
  338. package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts.map +1 -1
  339. package/dist/src/bitgo/utils/tss/baseTSSUtils.js +307 -46
  340. package/dist/src/bitgo/utils/tss/baseTypes.d.ts +414 -46
  341. package/dist/src/bitgo/utils/tss/baseTypes.d.ts.map +1 -1
  342. package/dist/src/bitgo/utils/tss/baseTypes.js +47 -22
  343. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.d.ts +23 -0
  344. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.d.ts.map +1 -0
  345. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.js +157 -0
  346. package/dist/src/bitgo/utils/tss/ecdsa/base.d.ts +28 -0
  347. package/dist/src/bitgo/utils/tss/ecdsa/base.d.ts.map +1 -0
  348. package/dist/src/bitgo/utils/tss/ecdsa/base.js +53 -0
  349. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.d.ts +24 -51
  350. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.d.ts.map +1 -1
  351. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.js +172 -246
  352. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts +215 -0
  353. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
  354. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +1049 -0
  355. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.d.ts +8 -0
  356. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.d.ts.map +1 -0
  357. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.js +13 -0
  358. package/dist/src/bitgo/utils/tss/ecdsa/index.d.ts +4 -0
  359. package/dist/src/bitgo/utils/tss/ecdsa/index.d.ts.map +1 -1
  360. package/dist/src/bitgo/utils/tss/ecdsa/index.js +10 -2
  361. package/dist/src/bitgo/utils/tss/ecdsa/types.d.ts +7 -10
  362. package/dist/src/bitgo/utils/tss/ecdsa/types.d.ts.map +1 -1
  363. package/dist/src/bitgo/utils/tss/ecdsa/types.js +1 -1
  364. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.d.ts +107 -0
  365. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.d.ts.map +1 -0
  366. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.js +55 -0
  367. package/dist/src/bitgo/utils/tss/eddsa/SMC/utils.d.ts +21 -0
  368. package/dist/src/bitgo/utils/tss/eddsa/SMC/utils.d.ts.map +1 -0
  369. package/dist/src/bitgo/utils/tss/eddsa/SMC/utils.js +118 -0
  370. package/dist/src/bitgo/utils/tss/eddsa/base.d.ts +18 -0
  371. package/dist/src/bitgo/utils/tss/eddsa/base.d.ts.map +1 -0
  372. package/dist/src/bitgo/utils/tss/eddsa/base.js +64 -0
  373. package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts +37 -11
  374. package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts.map +1 -1
  375. package/dist/src/bitgo/utils/tss/eddsa/eddsa.js +254 -96
  376. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts +137 -0
  377. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts.map +1 -0
  378. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.js +643 -0
  379. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.d.ts +6 -0
  380. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.d.ts.map +1 -0
  381. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.js +13 -0
  382. package/dist/src/bitgo/utils/tss/eddsa/index.d.ts +4 -0
  383. package/dist/src/bitgo/utils/tss/eddsa/index.d.ts.map +1 -1
  384. package/dist/src/bitgo/utils/tss/eddsa/index.js +29 -8
  385. package/dist/src/bitgo/utils/tss/eddsa/types.d.ts +12 -7
  386. package/dist/src/bitgo/utils/tss/eddsa/types.d.ts.map +1 -1
  387. package/dist/src/bitgo/utils/tss/eddsa/types.js +1 -1
  388. package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.d.ts +40 -0
  389. package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.d.ts.map +1 -0
  390. package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.js +44 -0
  391. package/dist/src/bitgo/utils/tss/index.d.ts +3 -0
  392. package/dist/src/bitgo/utils/tss/index.d.ts.map +1 -1
  393. package/dist/src/bitgo/utils/tss/index.js +26 -9
  394. package/dist/src/bitgo/utils/tss/preHashedSignable.d.ts +23 -0
  395. package/dist/src/bitgo/utils/tss/preHashedSignable.d.ts.map +1 -0
  396. package/dist/src/bitgo/utils/tss/preHashedSignable.js +26 -0
  397. package/dist/src/bitgo/utils/tss/recipientUtils.d.ts +33 -0
  398. package/dist/src/bitgo/utils/tss/recipientUtils.d.ts.map +1 -0
  399. package/dist/src/bitgo/utils/tss/recipientUtils.js +117 -0
  400. package/dist/src/bitgo/utils/txRequest.d.ts +10 -0
  401. package/dist/src/bitgo/utils/txRequest.d.ts.map +1 -0
  402. package/dist/src/bitgo/utils/txRequest.js +49 -0
  403. package/dist/src/bitgo/utils/util.js +24 -10
  404. package/dist/src/bitgo/utils/wallet.d.ts +7 -0
  405. package/dist/src/bitgo/utils/wallet.d.ts.map +1 -0
  406. package/dist/src/bitgo/utils/wallet.js +48 -0
  407. package/dist/src/bitgo/wallet/BuildParams.d.ts +50 -1
  408. package/dist/src/bitgo/wallet/BuildParams.d.ts.map +1 -1
  409. package/dist/src/bitgo/wallet/BuildParams.js +58 -11
  410. package/dist/src/bitgo/wallet/iWallet.d.ts +496 -23
  411. package/dist/src/bitgo/wallet/iWallet.d.ts.map +1 -1
  412. package/dist/src/bitgo/wallet/iWallet.js +1 -1
  413. package/dist/src/bitgo/wallet/iWallets.d.ts +298 -16
  414. package/dist/src/bitgo/wallet/iWallets.d.ts.map +1 -1
  415. package/dist/src/bitgo/wallet/iWallets.js +63 -3
  416. package/dist/src/bitgo/wallet/index.js +6 -2
  417. package/dist/src/bitgo/wallet/wallet.d.ts +350 -27
  418. package/dist/src/bitgo/wallet/wallet.d.ts.map +1 -1
  419. package/dist/src/bitgo/wallet/wallet.js +1934 -360
  420. package/dist/src/bitgo/wallet/wallets.d.ts +93 -4
  421. package/dist/src/bitgo/wallet/wallets.d.ts.map +1 -1
  422. package/dist/src/bitgo/wallet/wallets.js +1144 -155
  423. package/dist/src/bitgo/walletUtil/iMessageProvider.d.ts +12 -0
  424. package/dist/src/bitgo/walletUtil/iMessageProvider.d.ts.map +1 -0
  425. package/dist/src/bitgo/walletUtil/iMessageProvider.js +3 -0
  426. package/dist/src/bitgo/walletUtil/index.d.ts +3 -0
  427. package/dist/src/bitgo/walletUtil/index.d.ts.map +1 -0
  428. package/dist/src/bitgo/walletUtil/index.js +19 -0
  429. package/dist/src/bitgo/walletUtil/midnightMessageProvider.d.ts +22 -0
  430. package/dist/src/bitgo/walletUtil/midnightMessageProvider.d.ts.map +1 -0
  431. package/dist/src/bitgo/walletUtil/midnightMessageProvider.js +95 -0
  432. package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.d.ts +9 -0
  433. package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.d.ts.map +1 -0
  434. package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.js +72 -0
  435. package/dist/src/bitgo/walletUtil/utxoMessageProof.d.ts +15 -0
  436. package/dist/src/bitgo/walletUtil/utxoMessageProof.d.ts.map +1 -0
  437. package/dist/src/bitgo/walletUtil/utxoMessageProof.js +40 -0
  438. package/dist/src/bitgo/webhook/index.js +6 -2
  439. package/dist/src/bitgo/webhook/webhooks.js +23 -9
  440. package/dist/src/coins/fiat.d.ts +45 -0
  441. package/dist/src/coins/fiat.d.ts.map +1 -0
  442. package/dist/src/coins/fiat.js +94 -0
  443. package/dist/src/coins/index.d.ts +1 -6
  444. package/dist/src/coins/index.d.ts.map +1 -1
  445. package/dist/src/coins/index.js +7 -8
  446. package/dist/src/coins/ofc.d.ts +21 -2
  447. package/dist/src/coins/ofc.d.ts.map +1 -1
  448. package/dist/src/coins/ofc.js +29 -3
  449. package/dist/src/coins/ofcToken.d.ts +15 -4
  450. package/dist/src/coins/ofcToken.d.ts.map +1 -1
  451. package/dist/src/coins/ofcToken.js +43 -5
  452. package/dist/src/coins/susd.d.ts +3 -2
  453. package/dist/src/coins/susd.d.ts.map +1 -1
  454. package/dist/src/coins/susd.js +5 -1
  455. package/dist/src/common.js +27 -13
  456. package/dist/src/index.d.ts +7 -1
  457. package/dist/src/index.d.ts.map +1 -1
  458. package/dist/src/index.js +32 -11
  459. package/dist/src/lightning.d.ts +20 -0
  460. package/dist/src/lightning.d.ts.map +1 -0
  461. package/dist/src/lightning.js +13 -0
  462. package/dist/src/units.js +5 -6
  463. package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.d.ts +2 -0
  464. package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.d.ts.map +1 -0
  465. package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.js +207 -0
  466. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.d.ts +2 -0
  467. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.d.ts.map +1 -0
  468. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.js +174 -0
  469. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts +2 -0
  470. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts.map +1 -0
  471. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.js +108 -0
  472. package/dist/test/unit/account-lib/baseCoin/messages/fixtures.d.ts +46 -0
  473. package/dist/test/unit/account-lib/baseCoin/messages/fixtures.d.ts.map +1 -0
  474. package/dist/test/unit/account-lib/baseCoin/messages/fixtures.js +69 -0
  475. package/dist/test/unit/account-lib/mpc/tss/ecdsa/ecdsa.js +91 -29
  476. package/dist/test/unit/account-lib/mpc/util.d.ts +2 -0
  477. package/dist/test/unit/account-lib/mpc/util.d.ts.map +1 -0
  478. package/dist/test/unit/account-lib/mpc/util.js +53 -0
  479. package/dist/test/unit/bitgo/address-book/address-book.d.ts +2 -0
  480. package/dist/test/unit/bitgo/address-book/address-book.d.ts.map +1 -0
  481. package/dist/test/unit/bitgo/address-book/address-book.js +159 -0
  482. package/dist/test/unit/bitgo/defi/defiVault.d.ts +2 -0
  483. package/dist/test/unit/bitgo/defi/defiVault.d.ts.map +1 -0
  484. package/dist/test/unit/bitgo/defi/defiVault.js +338 -0
  485. package/dist/test/unit/bitgo/environment.d.ts +2 -0
  486. package/dist/test/unit/bitgo/environment.d.ts.map +1 -0
  487. package/dist/test/unit/bitgo/environment.js +38 -0
  488. package/dist/test/unit/bitgo/errors.d.ts +2 -0
  489. package/dist/test/unit/bitgo/errors.d.ts.map +1 -0
  490. package/dist/test/unit/bitgo/errors.js +262 -0
  491. package/dist/test/unit/bitgo/recovery/initiate.d.ts +2 -0
  492. package/dist/test/unit/bitgo/recovery/initiate.d.ts.map +1 -0
  493. package/dist/test/unit/bitgo/recovery/initiate.js +159 -0
  494. package/dist/test/unit/bitgo/trading/network/encrypt.d.ts +2 -0
  495. package/dist/test/unit/bitgo/trading/network/encrypt.d.ts.map +1 -0
  496. package/dist/test/unit/bitgo/trading/network/encrypt.js +71 -0
  497. package/dist/test/unit/bitgo/trading/tradingAccount.d.ts +2 -0
  498. package/dist/test/unit/bitgo/trading/tradingAccount.d.ts.map +1 -0
  499. package/dist/test/unit/bitgo/trading/tradingAccount.js +192 -0
  500. package/dist/test/unit/bitgo/utils/abstractUtxoCoinUtil.js +24 -4
  501. package/dist/test/unit/bitgo/utils/messageTypes.d.ts +2 -0
  502. package/dist/test/unit/bitgo/utils/messageTypes.d.ts.map +1 -0
  503. package/dist/test/unit/bitgo/utils/messageTypes.js +64 -0
  504. package/dist/test/unit/bitgo/utils/notEmpty.d.ts +2 -0
  505. package/dist/test/unit/bitgo/utils/notEmpty.d.ts.map +1 -0
  506. package/dist/test/unit/bitgo/utils/notEmpty.js +15 -0
  507. package/dist/test/unit/bitgo/utils/postWithCodec.js +32 -38
  508. package/dist/test/unit/bitgo/utils/tss/addressVerification.d.ts +2 -0
  509. package/dist/test/unit/bitgo/utils/tss/addressVerification.d.ts.map +1 -0
  510. package/dist/test/unit/bitgo/utils/tss/addressVerification.js +251 -0
  511. package/dist/test/unit/bitgo/utils/tss/baseTSSUtils.d.ts +2 -0
  512. package/dist/test/unit/bitgo/utils/tss/baseTSSUtils.d.ts.map +1 -0
  513. package/dist/test/unit/bitgo/utils/tss/baseTSSUtils.js +399 -0
  514. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaEncryptionVersion.d.ts +2 -0
  515. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaEncryptionVersion.d.ts.map +1 -0
  516. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaEncryptionVersion.js +94 -0
  517. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts +2 -0
  518. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
  519. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +999 -0
  520. package/dist/test/unit/bitgo/utils/tss/ecdsa/gpgKeys.d.ts +5 -0
  521. package/dist/test/unit/bitgo/utils/tss/ecdsa/gpgKeys.d.ts.map +1 -0
  522. package/dist/test/unit/bitgo/utils/tss/ecdsa/gpgKeys.js +36 -0
  523. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaExternalSigner.d.ts +2 -0
  524. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaExternalSigner.d.ts.map +1 -0
  525. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaExternalSigner.js +158 -0
  526. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts +2 -0
  527. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts.map +1 -0
  528. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaMPCv2.js +1279 -0
  529. package/dist/test/unit/bitgo/utils/tss/eddsa/smcUtil.d.ts +2 -0
  530. package/dist/test/unit/bitgo/utils/tss/eddsa/smcUtil.d.ts.map +1 -0
  531. package/dist/test/unit/bitgo/utils/tss/eddsa/smcUtil.js +311 -0
  532. package/dist/test/unit/bitgo/utils/tss/preHashedSignable.d.ts +2 -0
  533. package/dist/test/unit/bitgo/utils/tss/preHashedSignable.d.ts.map +1 -0
  534. package/dist/test/unit/bitgo/utils/tss/preHashedSignable.js +55 -0
  535. package/dist/test/unit/bitgo/utils/tss/recipientUtils.d.ts +2 -0
  536. package/dist/test/unit/bitgo/utils/tss/recipientUtils.d.ts.map +1 -0
  537. package/dist/test/unit/bitgo/utils/tss/recipientUtils.js +171 -0
  538. package/dist/test/unit/bitgo/utils/txRequest.d.ts +2 -0
  539. package/dist/test/unit/bitgo/utils/txRequest.d.ts.map +1 -0
  540. package/dist/test/unit/bitgo/utils/txRequest.js +179 -0
  541. package/dist/test/unit/bitgo/wallet/BuildParams.d.ts +2 -0
  542. package/dist/test/unit/bitgo/wallet/BuildParams.d.ts.map +1 -0
  543. package/dist/test/unit/bitgo/wallet/BuildParams.js +97 -0
  544. package/dist/test/unit/bitgo/wallet/SendTransactionRequest.js +23 -9
  545. package/dist/test/unit/bitgo/wallet/getAccountResources.d.ts +2 -0
  546. package/dist/test/unit/bitgo/wallet/getAccountResources.d.ts.map +1 -0
  547. package/dist/test/unit/bitgo/wallet/getAccountResources.js +133 -0
  548. package/dist/test/unit/bitgo/wallet/getResourceDelegations.d.ts +2 -0
  549. package/dist/test/unit/bitgo/wallet/getResourceDelegations.d.ts.map +1 -0
  550. package/dist/test/unit/bitgo/wallet/getResourceDelegations.js +118 -0
  551. package/dist/test/unit/bitgo/wallet/ofcWalletAddressCreation.d.ts +2 -0
  552. package/dist/test/unit/bitgo/wallet/ofcWalletAddressCreation.d.ts.map +1 -0
  553. package/dist/test/unit/bitgo/wallet/ofcWalletAddressCreation.js +141 -0
  554. package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.d.ts +2 -0
  555. package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.d.ts.map +1 -0
  556. package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.js +185 -0
  557. package/dist/test/unit/bitgo/wallet/resourceManagement.d.ts +3 -0
  558. package/dist/test/unit/bitgo/wallet/resourceManagement.d.ts.map +1 -0
  559. package/dist/test/unit/bitgo/wallet/resourceManagement.js +441 -0
  560. package/dist/test/unit/bitgo/wallet/tokenApproval.d.ts +2 -0
  561. package/dist/test/unit/bitgo/wallet/tokenApproval.d.ts.map +1 -0
  562. package/dist/test/unit/bitgo/wallet/tokenApproval.js +201 -0
  563. package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.d.ts +2 -0
  564. package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.d.ts.map +1 -0
  565. package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.js +181 -0
  566. package/dist/test/unit/bitgo/wallet/walletOptionsCodecs.d.ts +2 -0
  567. package/dist/test/unit/bitgo/wallet/walletOptionsCodecs.d.ts.map +1 -0
  568. package/dist/test/unit/bitgo/wallet/walletOptionsCodecs.js +43 -0
  569. package/dist/test/unit/bitgo/wallet/walletTssAddressVerification.d.ts +2 -0
  570. package/dist/test/unit/bitgo/wallet/walletTssAddressVerification.d.ts.map +1 -0
  571. package/dist/test/unit/bitgo/wallet/walletTssAddressVerification.js +320 -0
  572. package/dist/test/unit/bitgo/wallet/walletsEncryptionVersion.d.ts +2 -0
  573. package/dist/test/unit/bitgo/wallet/walletsEncryptionVersion.d.ts.map +1 -0
  574. package/dist/test/unit/bitgo/wallet/walletsEncryptionVersion.js +228 -0
  575. package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.d.ts +2 -0
  576. package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.d.ts.map +1 -0
  577. package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.js +216 -0
  578. package/dist/test/unit/bitgo/wallet/walletsExternalSigner.d.ts +2 -0
  579. package/dist/test/unit/bitgo/wallet/walletsExternalSigner.d.ts.map +1 -0
  580. package/dist/test/unit/bitgo/wallet/walletsExternalSigner.js +670 -0
  581. package/dist/test/unit/bitgo/wallet/walletsWebauthn.d.ts +2 -0
  582. package/dist/test/unit/bitgo/wallet/walletsWebauthn.d.ts.map +1 -0
  583. package/dist/test/unit/bitgo/wallet/walletsWebauthn.js +201 -0
  584. package/dist/test/unit/coins/ofc.d.ts +2 -0
  585. package/dist/test/unit/coins/ofc.d.ts.map +1 -0
  586. package/dist/test/unit/coins/ofc.js +124 -0
  587. package/dist/test/unit/lightning.d.ts +2 -0
  588. package/dist/test/unit/lightning.d.ts.map +1 -0
  589. package/dist/test/unit/lightning.js +23 -0
  590. package/dist/test/unit/units.d.ts.map +1 -1
  591. package/dist/test/unit/units.js +64 -64
  592. package/dist/tsconfig.tsbuildinfo +1 -1
  593. package/package.json +24 -21
  594. package/.eslintignore +0 -5
  595. package/CHANGELOG.md +0 -1568
  596. package/dist/src/account-lib/baseCoin/blsKeyPair.d.ts +0 -77
  597. package/dist/src/account-lib/baseCoin/blsKeyPair.d.ts.map +0 -1
  598. package/dist/src/account-lib/baseCoin/blsKeyPair.js +0 -209
  599. package/dist/src/bitgo/lightning/iLightning.d.ts +0 -186
  600. package/dist/src/bitgo/lightning/iLightning.d.ts.map +0 -1
  601. package/dist/src/bitgo/lightning/iLightning.js +0 -106
  602. package/dist/src/bitgo/lightning/index.d.ts +0 -5
  603. package/dist/src/bitgo/lightning/index.d.ts.map +0 -1
  604. package/dist/src/bitgo/lightning/index.js +0 -17
  605. package/dist/src/bitgo/lightning/lightning.d.ts +0 -25
  606. package/dist/src/bitgo/lightning/lightning.d.ts.map +0 -1
  607. package/dist/src/bitgo/lightning/lightning.js +0 -111
  608. package/dist/src/bitgo/lightning/lightningUtils.d.ts +0 -46
  609. package/dist/src/bitgo/lightning/lightningUtils.d.ts.map +0 -1
  610. package/dist/src/bitgo/lightning/lightningUtils.js +0 -133
  611. package/dist/src/bitgo/lightning/lnurlCodec.d.ts +0 -3
  612. package/dist/src/bitgo/lightning/lnurlCodec.d.ts.map +0 -1
  613. package/dist/src/bitgo/lightning/lnurlCodec.js +0 -28
  614. package/dist/src/bitgo/utils/blsUtils.d.ts +0 -52
  615. package/dist/src/bitgo/utils/blsUtils.d.ts.map +0 -1
  616. package/dist/src/bitgo/utils/blsUtils.js +0 -237
  617. package/dist/src/bitgo/utils/iBlsUtils.d.ts +0 -14
  618. package/dist/src/bitgo/utils/iBlsUtils.d.ts.map +0 -1
  619. package/dist/src/bitgo/utils/iBlsUtils.js +0 -3
  620. package/dist/src/coins/fiateur.d.ts +0 -31
  621. package/dist/src/coins/fiateur.d.ts.map +0 -1
  622. package/dist/src/coins/fiateur.js +0 -57
  623. package/dist/src/coins/fiatgbp.d.ts +0 -31
  624. package/dist/src/coins/fiatgbp.d.ts.map +0 -1
  625. package/dist/src/coins/fiatgbp.js +0 -57
  626. package/dist/src/coins/fiatusd.d.ts +0 -31
  627. package/dist/src/coins/fiatusd.d.ts.map +0 -1
  628. package/dist/src/coins/fiatusd.js +0 -57
  629. package/dist/src/coins/tfiateur.d.ts +0 -11
  630. package/dist/src/coins/tfiateur.d.ts.map +0 -1
  631. package/dist/src/coins/tfiateur.js +0 -17
  632. package/dist/src/coins/tfiatgbp.d.ts +0 -11
  633. package/dist/src/coins/tfiatgbp.d.ts.map +0 -1
  634. package/dist/src/coins/tfiatgbp.js +0 -17
  635. package/dist/src/coins/tfiatusd.d.ts +0 -11
  636. package/dist/src/coins/tfiatusd.d.ts.map +0 -1
  637. package/dist/src/coins/tfiatusd.js +0 -17
  638. package/dist/src/openssl/index.d.ts +0 -5
  639. package/dist/src/openssl/index.d.ts.map +0 -1
  640. package/dist/src/openssl/index.js +0 -9
  641. package/dist/test/unit/openssl.d.ts +0 -2
  642. package/dist/test/unit/openssl.d.ts.map +0 -1
  643. package/dist/test/unit/openssl.js +0 -39
@@ -0,0 +1,1279 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const assert = __importStar(require("assert"));
37
+ const sinon = __importStar(require("sinon"));
38
+ const pgp = __importStar(require("openpgp"));
39
+ const crypto_1 = require("crypto");
40
+ const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
41
+ const ed25519_1 = require("@noble/curves/ed25519");
42
+ const sjcl = __importStar(require("@bitgo-beta/sjcl"));
43
+ const public_types_1 = require("@bitgo/public-types");
44
+ const src_1 = require("../../../../../../src");
45
+ const eddsaMPCv2_1 = require("../../../../../../src/bitgo/tss/eddsa/eddsaMPCv2");
46
+ const eddsa_1 = require("../../../../../../src/bitgo/tss/eddsa/eddsa");
47
+ const common_1 = require("../../../../../../src/bitgo/tss/common");
48
+ const codecs_1 = require("../../../../../../src/bitgo/utils/codecs");
49
+ const opengpgUtils_1 = require("../../../../../../src/bitgo/utils/opengpgUtils");
50
+ const typesMPCv2_1 = require("../../../../../../src/bitgo/utils/tss/ecdsa/typesMPCv2");
51
+ const baseTypes_1 = require("../../../../../../src/bitgo/utils/tss/baseTypes");
52
+ describe('EdDSA MPS DSG helper functions', async () => {
53
+ let userKeyShare;
54
+ let backupKeyShare;
55
+ let bitgoKeyShare;
56
+ let userGpgPrivKey;
57
+ let backupGpgPrivKey;
58
+ let bitgoGpgPrivKey;
59
+ let bitgoGpgPubKey;
60
+ const signableHex = 'deadbeef';
61
+ const derivationPath = 'm/0';
62
+ before('generate EdDSA DKG key shares', async () => {
63
+ const userGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
64
+ const backupGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
65
+ const bitgoGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
66
+ userGpgPrivKey = await pgp.readPrivateKey({ armoredKey: userGpgKeyPair.privateKey });
67
+ backupGpgPrivKey = await pgp.readPrivateKey({ armoredKey: backupGpgKeyPair.privateKey });
68
+ bitgoGpgPrivKey = await pgp.readPrivateKey({ armoredKey: bitgoGpgKeyPair.privateKey });
69
+ bitgoGpgPubKey = await pgp.readKey({ armoredKey: bitgoGpgKeyPair.publicKey });
70
+ const [userDkg, backupDkg, bitgoDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
71
+ userKeyShare = userDkg.getKeyShare();
72
+ backupKeyShare = backupDkg.getKeyShare();
73
+ bitgoKeyShare = bitgoDkg.getKeyShare();
74
+ });
75
+ // ── Round 1 ─────────────────────────────────────────────────────────────────
76
+ it('getSignatureShareRoundOne should build a valid round-1 share', async () => {
77
+ const messageBuffer = Buffer.from(signableHex, 'hex');
78
+ const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER);
79
+ await userDsg.initDsg(userKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
80
+ const userMsg1 = userDsg.getFirstMessage();
81
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundOne)(userMsg1, userGpgPrivKey);
82
+ assert.strictEqual(share.from, src_1.SignatureShareType.USER);
83
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
84
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound1Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound1Input');
85
+ assert.strictEqual(parsed.type, 'round1Input');
86
+ assert.ok(parsed.data.msg1.message, 'msg1.message should be set');
87
+ assert.ok(parsed.data.msg1.signature, 'msg1.signature should be set');
88
+ });
89
+ it('getSignatureShareRoundOne should build a valid backup round-1 share', async () => {
90
+ const messageBuffer = Buffer.from(signableHex, 'hex');
91
+ const backupDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
92
+ await backupDsg.initDsg(backupKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
93
+ const backupMsg1 = backupDsg.getFirstMessage();
94
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundOne)(backupMsg1, backupGpgPrivKey, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
95
+ assert.strictEqual(share.from, src_1.SignatureShareType.BACKUP);
96
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
97
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound1Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound1Input');
98
+ assert.strictEqual(parsed.type, 'round1Input');
99
+ assert.ok(parsed.data.msg1.message, 'msg1.message should be set');
100
+ assert.ok(parsed.data.msg1.signature, 'msg1.signature should be set');
101
+ });
102
+ it('verifyPeerMessageRoundOne should verify a valid BitGo round-1 message', async () => {
103
+ const messageBuffer = Buffer.from(signableHex, 'hex');
104
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
105
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
106
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
107
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
108
+ const round1Output = {
109
+ type: 'round1Output',
110
+ data: { msg1: bitgoSignedMsg1 },
111
+ };
112
+ const result = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)(round1Output, bitgoGpgPubKey);
113
+ assert.strictEqual(result.from, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
114
+ assert.ok(result.payload.length > 0, 'payload should be non-empty');
115
+ });
116
+ it('verifyPeerMessageRoundOne should throw on a tampered message', async () => {
117
+ const round1Output = {
118
+ type: 'round1Output',
119
+ data: {
120
+ msg1: {
121
+ message: Buffer.from('tampered').toString('base64'),
122
+ signature: '-----BEGIN PGP SIGNATURE-----\n\nINVALID\n-----END PGP SIGNATURE-----\n',
123
+ },
124
+ },
125
+ };
126
+ await assert.rejects((0, eddsaMPCv2_1.verifyPeerMessageRoundOne)(round1Output, bitgoGpgPubKey), 'should throw on invalid signature');
127
+ });
128
+ // ── Round 2 ─────────────────────────────────────────────────────────────────
129
+ it('getSignatureShareRoundTwo should build a valid round-2 share', async () => {
130
+ const messageBuffer = Buffer.from(signableHex, 'hex');
131
+ const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER);
132
+ await userDsg.initDsg(userKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
133
+ const userMsg1 = userDsg.getFirstMessage();
134
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
135
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
136
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
137
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
138
+ const bitgoDeserializedMsg1 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)({ type: 'round1Output', data: { msg1: bitgoSignedMsg1 } }, bitgoGpgPubKey);
139
+ const [userMsg2] = userDsg.handleIncomingMessages([userMsg1, bitgoDeserializedMsg1]);
140
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundTwo)(userMsg2, userGpgPrivKey);
141
+ assert.strictEqual(share.from, src_1.SignatureShareType.USER);
142
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
143
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound2Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound2Input');
144
+ assert.strictEqual(parsed.type, 'round2Input');
145
+ assert.ok(parsed.data.msg2.message, 'msg2.message should be set');
146
+ assert.ok(parsed.data.msg2.signature, 'msg2.signature should be set');
147
+ });
148
+ it('getSignatureShareRoundTwo should build a valid backup round-2 share', async () => {
149
+ const messageBuffer = Buffer.from(signableHex, 'hex');
150
+ const backupDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
151
+ await backupDsg.initDsg(backupKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
152
+ const backupMsg1 = backupDsg.getFirstMessage();
153
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
154
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
155
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
156
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
157
+ const bitgoDeserializedMsg1 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)({ type: 'round1Output', data: { msg1: bitgoSignedMsg1 } }, bitgoGpgPubKey);
158
+ const [backupMsg2] = backupDsg.handleIncomingMessages([backupMsg1, bitgoDeserializedMsg1]);
159
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundTwo)(backupMsg2, backupGpgPrivKey, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
160
+ assert.strictEqual(share.from, src_1.SignatureShareType.BACKUP);
161
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
162
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound2Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound2Input');
163
+ assert.strictEqual(parsed.type, 'round2Input');
164
+ assert.ok(parsed.data.msg2.message, 'msg2.message should be set');
165
+ assert.ok(parsed.data.msg2.signature, 'msg2.signature should be set');
166
+ });
167
+ it('verifyPeerMessageRoundTwo should verify a valid BitGo round-2 message', async () => {
168
+ const messageBuffer = Buffer.from(signableHex, 'hex');
169
+ const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER);
170
+ await userDsg.initDsg(userKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
171
+ const userMsg1 = userDsg.getFirstMessage();
172
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
173
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
174
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
175
+ const [bitgoMsg2] = bitgoDsg.handleIncomingMessages([bitgoMsg1, userMsg1]);
176
+ const bitgoSignedMsg2 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg2.payload), bitgoGpgPrivKey);
177
+ const round2Output = {
178
+ type: 'round2Output',
179
+ data: { msg2: bitgoSignedMsg2 },
180
+ };
181
+ const result = await (0, eddsaMPCv2_1.verifyPeerMessageRoundTwo)(round2Output, bitgoGpgPubKey);
182
+ assert.strictEqual(result.from, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
183
+ assert.ok(result.payload.length > 0, 'payload should be non-empty');
184
+ });
185
+ it('verifyPeerMessageRoundTwo should throw on a tampered message', async () => {
186
+ const round2Output = {
187
+ type: 'round2Output',
188
+ data: {
189
+ msg2: {
190
+ message: Buffer.from('tampered').toString('base64'),
191
+ signature: '-----BEGIN PGP SIGNATURE-----\n\nINVALID\n-----END PGP SIGNATURE-----\n',
192
+ },
193
+ },
194
+ };
195
+ await assert.rejects((0, eddsaMPCv2_1.verifyPeerMessageRoundTwo)(round2Output, bitgoGpgPubKey), 'should throw on invalid signature');
196
+ });
197
+ // ── Round 3 ─────────────────────────────────────────────────────────────────
198
+ it('getSignatureShareRoundThree should build a valid round-3 share', async () => {
199
+ const messageBuffer = Buffer.from(signableHex, 'hex');
200
+ const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER);
201
+ await userDsg.initDsg(userKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
202
+ const userMsg1 = userDsg.getFirstMessage();
203
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
204
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
205
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
206
+ // Advance to round 2
207
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
208
+ const bitgoDeserializedMsg1 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)({ type: 'round1Output', data: { msg1: bitgoSignedMsg1 } }, bitgoGpgPubKey);
209
+ const [userMsg2] = userDsg.handleIncomingMessages([userMsg1, bitgoDeserializedMsg1]);
210
+ const [bitgoMsg2] = bitgoDsg.handleIncomingMessages([bitgoMsg1, userMsg1]);
211
+ const bitgoSignedMsg2 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg2.payload), bitgoGpgPrivKey);
212
+ const bitgoDeserializedMsg2 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundTwo)({ type: 'round2Output', data: { msg2: bitgoSignedMsg2 } }, bitgoGpgPubKey);
213
+ const [userMsg3] = userDsg.handleIncomingMessages([userMsg2, bitgoDeserializedMsg2]);
214
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundThree)(userMsg3, userGpgPrivKey);
215
+ assert.strictEqual(share.from, src_1.SignatureShareType.USER);
216
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
217
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound3Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound3Input');
218
+ assert.strictEqual(parsed.type, 'round3Input');
219
+ assert.ok(parsed.data.msg3.message, 'msg3.message should be set');
220
+ assert.ok(parsed.data.msg3.signature, 'msg3.signature should be set');
221
+ });
222
+ it('getSignatureShareRoundThree should build a valid backup round-3 share', async () => {
223
+ const messageBuffer = Buffer.from(signableHex, 'hex');
224
+ const backupDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
225
+ await backupDsg.initDsg(backupKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
226
+ const backupMsg1 = backupDsg.getFirstMessage();
227
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
228
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
229
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
230
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
231
+ const bitgoDeserializedMsg1 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)({ type: 'round1Output', data: { msg1: bitgoSignedMsg1 } }, bitgoGpgPubKey);
232
+ const [backupMsg2] = backupDsg.handleIncomingMessages([backupMsg1, bitgoDeserializedMsg1]);
233
+ const [bitgoMsg2] = bitgoDsg.handleIncomingMessages([bitgoMsg1, backupMsg1]);
234
+ const bitgoSignedMsg2 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg2.payload), bitgoGpgPrivKey);
235
+ const bitgoDeserializedMsg2 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundTwo)({ type: 'round2Output', data: { msg2: bitgoSignedMsg2 } }, bitgoGpgPubKey);
236
+ const [backupMsg3] = backupDsg.handleIncomingMessages([backupMsg2, bitgoDeserializedMsg2]);
237
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundThree)(backupMsg3, backupGpgPrivKey, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
238
+ assert.strictEqual(share.from, src_1.SignatureShareType.BACKUP);
239
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
240
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound3Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound3Input');
241
+ assert.strictEqual(parsed.type, 'round3Input');
242
+ assert.ok(parsed.data.msg3.message, 'msg3.message should be set');
243
+ assert.ok(parsed.data.msg3.signature, 'msg3.signature should be set');
244
+ });
245
+ });
246
+ describe('getEddsaMPCv2RecoveryKeyShares', () => {
247
+ const walletPassphrase = 'testPass';
248
+ const encryptKey = (keyShare) => sjcl.encrypt(walletPassphrase, keyShare.toString('base64'));
249
+ it('should return recovery key shares from v1-encrypted reduced keys (no bitgo instance)', async () => {
250
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
251
+ const result = await src_1.EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey(encryptKey(userDkg.getReducedKeyShare()), encryptKey(backupDkg.getReducedKeyShare()), walletPassphrase);
252
+ assert.deepStrictEqual(result.userKeyShare, userDkg.getKeyShare());
253
+ assert.deepStrictEqual(result.backupKeyShare, backupDkg.getKeyShare());
254
+ assert.strictEqual(result.commonKeyChain, userDkg.getCommonKeychain());
255
+ });
256
+ it('should route decryption through bitgo.decrypt when a bitgo instance is provided', async () => {
257
+ // sdk-core has no devDependency on sdk-api or argon2, so we cannot encrypt with a real v2 envelope here.
258
+ // The stub verifies that the function delegates to bitgo.decrypt (which supports v1 + v2 in
259
+ // production) rather than falling back to sjcl.decrypt.
260
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
261
+ const userKeyBase64 = userDkg.getReducedKeyShare().toString('base64');
262
+ const backupKeyBase64 = backupDkg.getReducedKeyShare().toString('base64');
263
+ const mockBitgo = {
264
+ decrypt: sinon.stub().onFirstCall().resolves(userKeyBase64).onSecondCall().resolves(backupKeyBase64),
265
+ };
266
+ const result = await src_1.EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey('encrypted-user-key', 'encrypted-backup-key', walletPassphrase, mockBitgo);
267
+ sinon.assert.calledTwice(mockBitgo.decrypt);
268
+ assert.deepStrictEqual(result.userKeyShare, userDkg.getKeyShare());
269
+ assert.deepStrictEqual(result.backupKeyShare, backupDkg.getKeyShare());
270
+ assert.strictEqual(result.commonKeyChain, userDkg.getCommonKeychain());
271
+ });
272
+ it('should reject a malformed keycard with a descriptive error', async () => {
273
+ const [userDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
274
+ const malformedKey = sjcl.encrypt(walletPassphrase, (0, crypto_1.randomBytes)(64).toString('base64'));
275
+ await assert.rejects(src_1.EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey(malformedKey, encryptKey(userDkg.getReducedKeyShare()), walletPassphrase), /unable to decode reduced key share/);
276
+ });
277
+ it('should reject reduced keys from different wallets', async () => {
278
+ const [userDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
279
+ const [, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
280
+ await assert.rejects(src_1.EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey(encryptKey(userDkg.getReducedKeyShare()), encryptKey(backupDkg.getReducedKeyShare()), walletPassphrase), /pub keys do not match/);
281
+ });
282
+ it('should reject reduced keys with matching pub but mismatched rootChainCodes', async () => {
283
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
284
+ const userReducedKeyShare = userDkg.getReducedKeyShare();
285
+ const backupReducedKeyShare = backupDkg.getReducedKeyShare();
286
+ const getDecodedReducedKeyShare = sdk_lib_mpc_1.MPSTypes.getDecodedReducedKeyShare;
287
+ const decodeStub = sinon.stub(sdk_lib_mpc_1.MPSTypes, 'getDecodedReducedKeyShare').callsFake((buf) => {
288
+ const reduced = getDecodedReducedKeyShare(buf);
289
+ if (Buffer.from(buf).equals(backupReducedKeyShare)) {
290
+ return {
291
+ ...reduced,
292
+ rootChainCode: Array.from((0, crypto_1.randomBytes)(32)),
293
+ };
294
+ }
295
+ return reduced;
296
+ });
297
+ try {
298
+ await assert.rejects(src_1.EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey(encryptKey(userReducedKeyShare), encryptKey(backupReducedKeyShare), walletPassphrase), /rootChainCodes do not match/);
299
+ }
300
+ finally {
301
+ decodeStub.restore();
302
+ }
303
+ });
304
+ });
305
+ describe('EddsaMPCv2Utils.createOfflineRound1Share', () => {
306
+ let eddsaMPCv2Utils;
307
+ let mockBitgo;
308
+ let userKeyShare;
309
+ const walletPassphrase = 'testPass';
310
+ const signableHex = 'deadbeef';
311
+ const derivationPath = 'm/0/0';
312
+ const expectedAdata = `${signableHex}:${derivationPath}`;
313
+ const txRequest = {
314
+ txRequestId: 'txreq-eddsa-round1',
315
+ walletId: 'wallet-eddsa-round1',
316
+ enterpriseId: 'enterprise-eddsa-round1',
317
+ apiVersion: 'full',
318
+ transactions: [
319
+ {
320
+ unsignedTx: {
321
+ signableHex,
322
+ derivationPath,
323
+ serializedTxHex: signableHex,
324
+ },
325
+ signatureShares: [],
326
+ },
327
+ ],
328
+ intent: { intentType: 'payment' },
329
+ unsignedTxs: [],
330
+ };
331
+ before('generate EdDSA user key share', async () => {
332
+ const [userDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
333
+ userKeyShare = userDkg.getKeyShare();
334
+ });
335
+ beforeEach(() => {
336
+ const sjclEncrypt = (params) => {
337
+ const salt = (0, crypto_1.randomBytes)(8);
338
+ const iv = (0, crypto_1.randomBytes)(16);
339
+ return sjcl.encrypt(params.password, params.input, {
340
+ salt: [bytesToWord(salt.subarray(0, 4)), bytesToWord(salt.subarray(4))],
341
+ iv: [
342
+ bytesToWord(iv.subarray(0, 4)),
343
+ bytesToWord(iv.subarray(4, 8)),
344
+ bytesToWord(iv.subarray(8, 12)),
345
+ bytesToWord(iv.subarray(12, 16)),
346
+ ],
347
+ adata: params.adata,
348
+ });
349
+ };
350
+ mockBitgo = {
351
+ encrypt: sinon.stub().callsFake(async (params) => sjclEncrypt(params)),
352
+ };
353
+ const mockCoin = {
354
+ getMPCAlgorithm: sinon.stub().returns('eddsa'),
355
+ };
356
+ eddsaMPCv2Utils = new src_1.EddsaMPCv2Utils(mockBitgo, mockCoin);
357
+ });
358
+ it('should create a round-1 share and encrypted SJCL session payload', async () => {
359
+ const result = await eddsaMPCv2Utils.createOfflineRound1Share({
360
+ txRequest,
361
+ prv: userKeyShare.toString('base64'),
362
+ walletPassphrase,
363
+ });
364
+ assert.strictEqual(result.signatureShareRound1.from, src_1.SignatureShareType.USER);
365
+ assert.strictEqual(result.signatureShareRound1.to, src_1.SignatureShareType.BITGO);
366
+ assert.ok(result.userGpgPubKey.includes('BEGIN PGP PUBLIC KEY BLOCK'));
367
+ assert.ok(JSON.parse(result.encryptedRound1Session).ct, 'encryptedRound1Session should be an SJCL JSON blob');
368
+ assert.ok(JSON.parse(result.encryptedUserGpgPrvKey).ct, 'encryptedUserGpgPrvKey should be an SJCL JSON blob');
369
+ const parsedShare = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound1Input, JSON.parse(result.signatureShareRound1.share), 'EddsaMPCv2SignatureShareRound1Input');
370
+ assert.strictEqual(parsedShare.type, 'round1Input');
371
+ assert.ok(parsedShare.data.msg1.message, 'msg1.message should be set');
372
+ assert.ok(parsedShare.data.msg1.signature, 'msg1.signature should be set');
373
+ const encryptedRound1Session = JSON.parse(result.encryptedRound1Session);
374
+ const encryptedUserGpgPrvKey = JSON.parse(result.encryptedUserGpgPrvKey);
375
+ assert.strictEqual(decodeURIComponent(encryptedRound1Session.adata), `MPS_DSG_SIGNING_ROUND1_STATE:${expectedAdata}`, 'round-1 session adata should bind the signing context');
376
+ assert.strictEqual(decodeURIComponent(encryptedUserGpgPrvKey.adata), `MPS_DSG_SIGNING_USER_GPG_KEY:${expectedAdata}`, 'GPG private key adata should bind the signing context');
377
+ const sessionPayload = JSON.parse(sjcl.decrypt(walletPassphrase, result.encryptedRound1Session));
378
+ assert.ok(sessionPayload.dsgSession, 'dsgSession should be persisted for round 2');
379
+ assert.ok(sessionPayload.userMsgPayload, 'userMsgPayload should be persisted for round 2');
380
+ });
381
+ it('should use v2 encryption when encryptedPrv is a v2 envelope', async () => {
382
+ const encrypt = sinon
383
+ .stub()
384
+ .callsFake((input, adata) => Promise.resolve(JSON.stringify({ v: 2, input, adata })));
385
+ const destroy = sinon.stub();
386
+ const createEncryptionSession = sinon.stub().resolves({ encrypt, destroy });
387
+ mockBitgo.createEncryptionSession = createEncryptionSession;
388
+ const result = await eddsaMPCv2Utils.createOfflineRound1Share({
389
+ txRequest,
390
+ prv: userKeyShare.toString('base64'),
391
+ walletPassphrase,
392
+ encryptedPrv: JSON.stringify({ v: 2 }),
393
+ });
394
+ sinon.assert.calledOnce(createEncryptionSession);
395
+ assert.strictEqual(createEncryptionSession.getCall(0).args[0], walletPassphrase);
396
+ sinon.assert.notCalled(mockBitgo.encrypt);
397
+ sinon.assert.calledTwice(encrypt);
398
+ sinon.assert.calledOnce(destroy);
399
+ const encryptedRound1Session = JSON.parse(result.encryptedRound1Session);
400
+ const encryptedUserGpgPrvKey = JSON.parse(result.encryptedUserGpgPrvKey);
401
+ assert.strictEqual(encryptedRound1Session.v, 2);
402
+ assert.strictEqual(encryptedRound1Session.adata, `MPS_DSG_SIGNING_ROUND1_STATE:${expectedAdata}`);
403
+ assert.strictEqual(encryptedUserGpgPrvKey.v, 2);
404
+ assert.strictEqual(encryptedUserGpgPrvKey.adata, `MPS_DSG_SIGNING_USER_GPG_KEY:${expectedAdata}`);
405
+ const sessionPayload = JSON.parse(encryptedRound1Session.input);
406
+ assert.ok(sessionPayload.dsgSession, 'dsgSession should be persisted for round 2');
407
+ assert.ok(sessionPayload.userMsgPayload, 'userMsgPayload should be persisted for round 2');
408
+ });
409
+ it('should use SJCL encryption when encryptedPrv is a v1 blob', async () => {
410
+ mockBitgo.createEncryptionSession = sinon.stub();
411
+ const encryptedPrv = sjcl.encrypt(walletPassphrase, userKeyShare.toString('base64'));
412
+ const result = await eddsaMPCv2Utils.createOfflineRound1Share({
413
+ txRequest,
414
+ prv: userKeyShare.toString('base64'),
415
+ walletPassphrase,
416
+ encryptedPrv,
417
+ });
418
+ sinon.assert.notCalled(mockBitgo.createEncryptionSession);
419
+ sinon.assert.calledTwice(mockBitgo.encrypt);
420
+ assert.ok(JSON.parse(result.encryptedRound1Session).ct, 'encryptedRound1Session should be an SJCL JSON blob');
421
+ assert.ok(JSON.parse(result.encryptedUserGpgPrvKey).ct, 'encryptedUserGpgPrvKey should be an SJCL JSON blob');
422
+ });
423
+ it('should propagate the tx-only guard when transactions are missing', async () => {
424
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound1Share({
425
+ txRequest: { ...txRequest, transactions: undefined },
426
+ prv: userKeyShare.toString('base64'),
427
+ walletPassphrase,
428
+ }), /Unable to find transactions in txRequest/);
429
+ });
430
+ });
431
+ describe('EddsaMPCv2Utils.createOfflineRound2Share', () => {
432
+ let eddsaMPCv2Utils;
433
+ let mockBitgo;
434
+ let userKeyShare;
435
+ let bitgoKeyShare;
436
+ let bitgoGpgKeyPair;
437
+ let bitgoGpgPrivKey;
438
+ const walletPassphrase = 'testPass';
439
+ const signableHex = 'deadbeef';
440
+ const derivationPath = 'm/0/0';
441
+ const expectedAdata = `${signableHex}:${derivationPath}`;
442
+ const baseTxRequest = {
443
+ txRequestId: 'txreq-eddsa-round2',
444
+ walletId: 'wallet-eddsa-round2',
445
+ enterpriseId: 'enterprise-eddsa-round2',
446
+ apiVersion: 'full',
447
+ transactions: [
448
+ {
449
+ unsignedTx: {
450
+ signableHex,
451
+ derivationPath,
452
+ serializedTxHex: signableHex,
453
+ },
454
+ signatureShares: [],
455
+ },
456
+ ],
457
+ intent: { intentType: 'payment' },
458
+ unsignedTxs: [],
459
+ };
460
+ before('generate EdDSA key shares and GPG keys', async () => {
461
+ const [userDkg, , bitgoDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
462
+ userKeyShare = userDkg.getKeyShare();
463
+ bitgoKeyShare = bitgoDkg.getKeyShare();
464
+ bitgoGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
465
+ bitgoGpgPrivKey = await pgp.readPrivateKey({ armoredKey: bitgoGpgKeyPair.privateKey });
466
+ });
467
+ beforeEach(() => {
468
+ mockBitgo = {
469
+ encrypt: sinon.stub().callsFake(async (params) => {
470
+ const salt = (0, crypto_1.randomBytes)(8);
471
+ const iv = (0, crypto_1.randomBytes)(16);
472
+ return sjcl.encrypt(params.password, params.input, {
473
+ salt: [bytesToWord(salt.subarray(0, 4)), bytesToWord(salt.subarray(4))],
474
+ iv: [
475
+ bytesToWord(iv.subarray(0, 4)),
476
+ bytesToWord(iv.subarray(4, 8)),
477
+ bytesToWord(iv.subarray(8, 12)),
478
+ bytesToWord(iv.subarray(12, 16)),
479
+ ],
480
+ adata: params.adata,
481
+ });
482
+ }),
483
+ decrypt: sinon.stub().callsFake(async (params) => sjcl.decrypt(params.password, params.input)),
484
+ };
485
+ const mockCoin = {
486
+ getMPCAlgorithm: sinon.stub().returns('eddsa'),
487
+ };
488
+ eddsaMPCv2Utils = new src_1.EddsaMPCv2Utils(mockBitgo, mockCoin);
489
+ });
490
+ it('should create a round-2 share from offline round 1', async () => {
491
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
492
+ txRequest: baseTxRequest,
493
+ prv: userKeyShare.toString('base64'),
494
+ walletPassphrase,
495
+ });
496
+ const messageBuffer = Buffer.from(signableHex, 'hex');
497
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
498
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
499
+ const txRequestRound1 = await signBitgoEddsaRound1(bitgoDsg, cloneTxRequestWithEmptySignatureShares(baseTxRequest), round1.signatureShareRound1, round1.userGpgPubKey, bitgoGpgPrivKey);
500
+ const round2 = await eddsaMPCv2Utils.createOfflineRound2Share({
501
+ txRequest: txRequestRound1,
502
+ walletPassphrase,
503
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
504
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
505
+ encryptedRound1Session: round1.encryptedRound1Session,
506
+ });
507
+ assert.strictEqual(round2.signatureShareRound2.from, src_1.SignatureShareType.USER);
508
+ assert.strictEqual(round2.signatureShareRound2.to, src_1.SignatureShareType.BITGO);
509
+ const parsedShare = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound2Input, JSON.parse(round2.signatureShareRound2.share), 'EddsaMPCv2SignatureShareRound2Input');
510
+ assert.strictEqual(parsedShare.type, 'round2Input');
511
+ assert.ok(parsedShare.data.msg2.message, 'msg2.message should be set');
512
+ assert.ok(parsedShare.data.msg2.signature, 'msg2.signature should be set');
513
+ const encryptedRound2Session = JSON.parse(round2.encryptedRound2Session);
514
+ assert.strictEqual(decodeURIComponent(encryptedRound2Session.adata), `MPS_DSG_SIGNING_ROUND2_STATE:${expectedAdata}`);
515
+ const sessionPayload = JSON.parse(sjcl.decrypt(walletPassphrase, round2.encryptedRound2Session));
516
+ assert.ok(sessionPayload.dsgSession, 'dsgSession should be persisted for round 3');
517
+ assert.ok(sessionPayload.userMsgPayload, 'userMsgPayload should be persisted for round 3');
518
+ });
519
+ it('should use v2 decryption when encryptedRound1Session is a v2 envelope', async () => {
520
+ const encrypt = sinon
521
+ .stub()
522
+ .callsFake((input, adata) => Promise.resolve(JSON.stringify({ v: 2, input, adata })));
523
+ const destroy = sinon.stub();
524
+ const createEncryptionSession = sinon.stub().resolves({ encrypt, destroy });
525
+ mockBitgo.createEncryptionSession = createEncryptionSession;
526
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
527
+ txRequest: baseTxRequest,
528
+ prv: userKeyShare.toString('base64'),
529
+ walletPassphrase,
530
+ encryptedPrv: JSON.stringify({ v: 2 }),
531
+ });
532
+ const messageBuffer = Buffer.from(signableHex, 'hex');
533
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
534
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
535
+ const txRequestRound1 = await signBitgoEddsaRound1(bitgoDsg, cloneTxRequestWithEmptySignatureShares(baseTxRequest), round1.signatureShareRound1, round1.userGpgPubKey, bitgoGpgPrivKey);
536
+ const decrypt = sinon.stub().callsFake(async (params) => {
537
+ const envelope = JSON.parse(params.input);
538
+ return envelope.input;
539
+ });
540
+ mockBitgo.decrypt = decrypt;
541
+ const round2 = await eddsaMPCv2Utils.createOfflineRound2Share({
542
+ txRequest: txRequestRound1,
543
+ walletPassphrase,
544
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
545
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
546
+ encryptedRound1Session: round1.encryptedRound1Session,
547
+ });
548
+ sinon.assert.called(mockBitgo.decrypt);
549
+ assert.strictEqual(round2.signatureShareRound2.from, src_1.SignatureShareType.USER);
550
+ const encryptedRound2Session = JSON.parse(round2.encryptedRound2Session);
551
+ assert.strictEqual(encryptedRound2Session.v, 2);
552
+ assert.strictEqual(encryptedRound2Session.adata, `MPS_DSG_SIGNING_ROUND2_STATE:${expectedAdata}`);
553
+ });
554
+ it('should reject tampered encryptedRound1Session adata', async () => {
555
+ const otherTxRequest = {
556
+ ...baseTxRequest,
557
+ transactions: [
558
+ {
559
+ unsignedTx: {
560
+ signableHex: 'cafebabe',
561
+ derivationPath: 'm/1/2',
562
+ serializedTxHex: 'cafebabe',
563
+ },
564
+ signatureShares: [],
565
+ },
566
+ ],
567
+ };
568
+ const round1Other = await eddsaMPCv2Utils.createOfflineRound1Share({
569
+ txRequest: otherTxRequest,
570
+ prv: userKeyShare.toString('base64'),
571
+ walletPassphrase,
572
+ });
573
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
574
+ txRequest: baseTxRequest,
575
+ prv: userKeyShare.toString('base64'),
576
+ walletPassphrase,
577
+ });
578
+ const messageBuffer = Buffer.from(signableHex, 'hex');
579
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
580
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
581
+ const txRequestRound1 = await signBitgoEddsaRound1(bitgoDsg, cloneTxRequestWithEmptySignatureShares(baseTxRequest), round1.signatureShareRound1, round1.userGpgPubKey, bitgoGpgPrivKey);
582
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound2Share({
583
+ txRequest: txRequestRound1,
584
+ walletPassphrase,
585
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
586
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
587
+ encryptedRound1Session: round1Other.encryptedRound1Session,
588
+ }), /Adata does not match cyphertext adata/);
589
+ });
590
+ it('should reject tampered encryptedUserGpgPrvKey adata', async () => {
591
+ const otherTxRequest = {
592
+ ...baseTxRequest,
593
+ transactions: [
594
+ {
595
+ unsignedTx: {
596
+ signableHex: 'cafebabe',
597
+ derivationPath: 'm/1/2',
598
+ serializedTxHex: 'cafebabe',
599
+ },
600
+ signatureShares: [],
601
+ },
602
+ ],
603
+ };
604
+ const round1Other = await eddsaMPCv2Utils.createOfflineRound1Share({
605
+ txRequest: otherTxRequest,
606
+ prv: userKeyShare.toString('base64'),
607
+ walletPassphrase,
608
+ });
609
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
610
+ txRequest: baseTxRequest,
611
+ prv: userKeyShare.toString('base64'),
612
+ walletPassphrase,
613
+ });
614
+ const messageBuffer = Buffer.from(signableHex, 'hex');
615
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
616
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
617
+ const txRequestRound1 = await signBitgoEddsaRound1(bitgoDsg, cloneTxRequestWithEmptySignatureShares(baseTxRequest), round1.signatureShareRound1, round1.userGpgPubKey, bitgoGpgPrivKey);
618
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound2Share({
619
+ txRequest: txRequestRound1,
620
+ walletPassphrase,
621
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
622
+ encryptedUserGpgPrvKey: round1Other.encryptedUserGpgPrvKey,
623
+ encryptedRound1Session: round1.encryptedRound1Session,
624
+ }), /Adata does not match cyphertext adata/);
625
+ });
626
+ it('should reject when BitGo signature share is missing', async () => {
627
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
628
+ txRequest: baseTxRequest,
629
+ prv: userKeyShare.toString('base64'),
630
+ walletPassphrase,
631
+ });
632
+ const baseTransaction = assertSingleTransaction(baseTxRequest);
633
+ const txRequestNoBitgoShare = {
634
+ ...baseTxRequest,
635
+ transactions: [
636
+ {
637
+ ...baseTransaction,
638
+ signatureShares: [round1.signatureShareRound1],
639
+ },
640
+ ],
641
+ };
642
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound2Share({
643
+ txRequest: txRequestNoBitgoShare,
644
+ walletPassphrase,
645
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
646
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
647
+ encryptedRound1Session: round1.encryptedRound1Session,
648
+ }), /Missing BitGo round1Output signature share/);
649
+ });
650
+ it('should propagate the tx-only guard when transactions are missing', async () => {
651
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
652
+ txRequest: baseTxRequest,
653
+ prv: userKeyShare.toString('base64'),
654
+ walletPassphrase,
655
+ });
656
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound2Share({
657
+ txRequest: { ...baseTxRequest, transactions: undefined },
658
+ walletPassphrase,
659
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
660
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
661
+ encryptedRound1Session: round1.encryptedRound1Session,
662
+ }), /Unable to find transactions in txRequest/);
663
+ });
664
+ it('should reject when transactions array is empty', async () => {
665
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
666
+ txRequest: baseTxRequest,
667
+ prv: userKeyShare.toString('base64'),
668
+ walletPassphrase,
669
+ });
670
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound2Share({
671
+ txRequest: { ...baseTxRequest, transactions: [] },
672
+ walletPassphrase,
673
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
674
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
675
+ encryptedRound1Session: round1.encryptedRound1Session,
676
+ }), /Unable to find transactions in txRequest/);
677
+ });
678
+ });
679
+ describe('EddsaMPCv2Utils.createOfflineRound3Share', () => {
680
+ let eddsaMPCv2Utils;
681
+ let mockBitgo;
682
+ let userKeyShare;
683
+ let bitgoKeyShare;
684
+ let bitgoGpgKeyPair;
685
+ let bitgoGpgPrivKey;
686
+ const walletPassphrase = 'testPass';
687
+ const signableHex = 'deadbeef';
688
+ const derivationPath = 'm/0/0';
689
+ const baseTxRequest = {
690
+ txRequestId: 'txreq-eddsa-round3',
691
+ walletId: 'wallet-eddsa-round3',
692
+ enterpriseId: 'enterprise-eddsa-round3',
693
+ apiVersion: 'full',
694
+ transactions: [
695
+ {
696
+ unsignedTx: {
697
+ signableHex,
698
+ derivationPath,
699
+ serializedTxHex: signableHex,
700
+ },
701
+ signatureShares: [],
702
+ },
703
+ ],
704
+ intent: { intentType: 'payment' },
705
+ unsignedTxs: [],
706
+ };
707
+ before('generate EdDSA key shares and GPG keys', async () => {
708
+ const [userDkg, , bitgoDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
709
+ userKeyShare = userDkg.getKeyShare();
710
+ bitgoKeyShare = bitgoDkg.getKeyShare();
711
+ bitgoGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
712
+ bitgoGpgPrivKey = await pgp.readPrivateKey({ armoredKey: bitgoGpgKeyPair.privateKey });
713
+ });
714
+ beforeEach(() => {
715
+ mockBitgo = {
716
+ encrypt: sinon.stub().callsFake(async (params) => {
717
+ const salt = (0, crypto_1.randomBytes)(8);
718
+ const iv = (0, crypto_1.randomBytes)(16);
719
+ return sjcl.encrypt(params.password, params.input, {
720
+ salt: [bytesToWord(salt.subarray(0, 4)), bytesToWord(salt.subarray(4))],
721
+ iv: [
722
+ bytesToWord(iv.subarray(0, 4)),
723
+ bytesToWord(iv.subarray(4, 8)),
724
+ bytesToWord(iv.subarray(8, 12)),
725
+ bytesToWord(iv.subarray(12, 16)),
726
+ ],
727
+ adata: params.adata,
728
+ });
729
+ }),
730
+ decrypt: sinon.stub().callsFake(async (params) => sjcl.decrypt(params.password, params.input)),
731
+ };
732
+ const mockCoin = {
733
+ getMPCAlgorithm: sinon.stub().returns('eddsa'),
734
+ };
735
+ eddsaMPCv2Utils = new src_1.EddsaMPCv2Utils(mockBitgo, mockCoin);
736
+ });
737
+ async function createRound2Flow(txRequest, encryptedPrv) {
738
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
739
+ txRequest,
740
+ prv: userKeyShare.toString('base64'),
741
+ walletPassphrase,
742
+ encryptedPrv,
743
+ });
744
+ const transaction = assertSingleTransaction(txRequest);
745
+ const messageBuffer = Buffer.from(transaction.unsignedTx.signableHex, 'hex');
746
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
747
+ await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, transaction.unsignedTx.derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
748
+ const txRequestRound1 = await signBitgoEddsaRound1(bitgoDsg, cloneTxRequestWithEmptySignatureShares(txRequest), round1.signatureShareRound1, round1.userGpgPubKey, bitgoGpgPrivKey);
749
+ const round2 = await eddsaMPCv2Utils.createOfflineRound2Share({
750
+ txRequest: txRequestRound1,
751
+ walletPassphrase,
752
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
753
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
754
+ encryptedRound1Session: round1.encryptedRound1Session,
755
+ });
756
+ const round1Transaction = assertSingleTransaction(txRequestRound1);
757
+ const txRequestRound2 = await signBitgoEddsaRound2(bitgoDsg, {
758
+ ...txRequestRound1,
759
+ transactions: [
760
+ {
761
+ ...round1Transaction,
762
+ signatureShares: [...round1Transaction.signatureShares],
763
+ },
764
+ ],
765
+ }, round2.signatureShareRound2, round1.userGpgPubKey, bitgoGpgPrivKey);
766
+ return { round1, round2, txRequestRound1, txRequestRound2, messageBuffer };
767
+ }
768
+ it('should create a round-3 share from offline round 2', async () => {
769
+ const { round1, round2, txRequestRound2 } = await createRound2Flow(baseTxRequest);
770
+ const round3 = await eddsaMPCv2Utils.createOfflineRound3Share({
771
+ txRequest: txRequestRound2,
772
+ walletPassphrase,
773
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
774
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
775
+ encryptedRound2Session: round2.encryptedRound2Session,
776
+ });
777
+ assert.strictEqual(round3.signatureShareRound3.from, src_1.SignatureShareType.USER);
778
+ assert.strictEqual(round3.signatureShareRound3.to, src_1.SignatureShareType.BITGO);
779
+ const parsedShare = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound3Input, JSON.parse(round3.signatureShareRound3.share), 'EddsaMPCv2SignatureShareRound3Input');
780
+ assert.strictEqual(parsedShare.type, 'round3Input');
781
+ assert.ok(parsedShare.data.msg3.message, 'msg3.message should be set');
782
+ assert.ok(parsedShare.data.msg3.signature, 'msg3.signature should be set');
783
+ });
784
+ it('should use v2 decryption when encryptedRound2Session is a v2 envelope', async () => {
785
+ const encrypt = sinon
786
+ .stub()
787
+ .callsFake((input, adata) => Promise.resolve(JSON.stringify({ v: 2, input, adata })));
788
+ const destroy = sinon.stub();
789
+ const createEncryptionSession = sinon.stub().resolves({ encrypt, destroy });
790
+ mockBitgo.createEncryptionSession = createEncryptionSession;
791
+ const decrypt = sinon.stub().callsFake(async (params) => {
792
+ const envelope = JSON.parse(params.input);
793
+ return envelope.input;
794
+ });
795
+ mockBitgo.decrypt = decrypt;
796
+ const { round1, round2, txRequestRound2 } = await createRound2Flow(baseTxRequest, JSON.stringify({ v: 2 }));
797
+ const round3 = await eddsaMPCv2Utils.createOfflineRound3Share({
798
+ txRequest: txRequestRound2,
799
+ walletPassphrase,
800
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
801
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
802
+ encryptedRound2Session: round2.encryptedRound2Session,
803
+ });
804
+ assert.strictEqual(mockBitgo.decrypt.callCount, 4);
805
+ assert.strictEqual(round3.signatureShareRound3.from, src_1.SignatureShareType.USER);
806
+ });
807
+ it('should reject tampered encryptedRound2Session adata', async () => {
808
+ const otherTxRequest = {
809
+ ...baseTxRequest,
810
+ transactions: [
811
+ {
812
+ unsignedTx: {
813
+ signableHex: 'cafebabe',
814
+ derivationPath: 'm/1/2',
815
+ serializedTxHex: 'cafebabe',
816
+ },
817
+ signatureShares: [],
818
+ },
819
+ ],
820
+ };
821
+ const otherFlow = await createRound2Flow(otherTxRequest);
822
+ const { round1, txRequestRound2 } = await createRound2Flow(baseTxRequest);
823
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound3Share({
824
+ txRequest: txRequestRound2,
825
+ walletPassphrase,
826
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
827
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
828
+ encryptedRound2Session: otherFlow.round2.encryptedRound2Session,
829
+ }), /Adata does not match cyphertext adata/);
830
+ });
831
+ it('should reject tampered encryptedUserGpgPrvKey adata', async () => {
832
+ const otherTxRequest = {
833
+ ...baseTxRequest,
834
+ transactions: [
835
+ {
836
+ unsignedTx: {
837
+ signableHex: 'cafebabe',
838
+ derivationPath: 'm/1/2',
839
+ serializedTxHex: 'cafebabe',
840
+ },
841
+ signatureShares: [],
842
+ },
843
+ ],
844
+ };
845
+ const otherFlow = await createRound2Flow(otherTxRequest);
846
+ const { round2, txRequestRound2 } = await createRound2Flow(baseTxRequest);
847
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound3Share({
848
+ txRequest: txRequestRound2,
849
+ walletPassphrase,
850
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
851
+ encryptedUserGpgPrvKey: otherFlow.round1.encryptedUserGpgPrvKey,
852
+ encryptedRound2Session: round2.encryptedRound2Session,
853
+ }), /Adata does not match cyphertext adata/);
854
+ });
855
+ it('should reject when BitGo round-2 signature share is missing', async () => {
856
+ const { round1, round2, txRequestRound1 } = await createRound2Flow(baseTxRequest);
857
+ const round1Transaction = assertSingleTransaction(txRequestRound1);
858
+ const txRequestNoBitgoRound2Share = {
859
+ ...txRequestRound1,
860
+ transactions: [
861
+ {
862
+ ...round1Transaction,
863
+ signatureShares: [...round1Transaction.signatureShares, round2.signatureShareRound2],
864
+ },
865
+ ],
866
+ };
867
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound3Share({
868
+ txRequest: txRequestNoBitgoRound2Share,
869
+ walletPassphrase,
870
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
871
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
872
+ encryptedRound2Session: round2.encryptedRound2Session,
873
+ }), /Missing BitGo round2Output signature share/);
874
+ });
875
+ it('should propagate the tx-only guard when transactions are missing', async () => {
876
+ const { round1, round2 } = await createRound2Flow(baseTxRequest);
877
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound3Share({
878
+ txRequest: { ...baseTxRequest, transactions: undefined },
879
+ walletPassphrase,
880
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
881
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
882
+ encryptedRound2Session: round2.encryptedRound2Session,
883
+ }), /Unable to find transactions in txRequest/);
884
+ });
885
+ it('should reject when transactions array is empty', async () => {
886
+ const { round1, round2 } = await createRound2Flow(baseTxRequest);
887
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound3Share({
888
+ txRequest: { ...baseTxRequest, transactions: [] },
889
+ walletPassphrase,
890
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
891
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
892
+ encryptedRound2Session: round2.encryptedRound2Session,
893
+ }), /Unable to find transactions in txRequest/);
894
+ });
895
+ });
896
+ describe('getBitgoSignatureShare', () => {
897
+ const round1OutputShare = {
898
+ from: src_1.SignatureShareType.BITGO,
899
+ to: src_1.SignatureShareType.USER,
900
+ share: JSON.stringify({ type: 'round1Output', data: {} }),
901
+ };
902
+ const round2OutputShare = {
903
+ from: src_1.SignatureShareType.BITGO,
904
+ to: src_1.SignatureShareType.USER,
905
+ share: JSON.stringify({ type: 'round2Output', data: {} }),
906
+ };
907
+ it('selects the requested BitGo round output when multiple round outputs are present', () => {
908
+ const signatureShares = [round1OutputShare, round2OutputShare];
909
+ assert.strictEqual((0, common_1.getBitgoSignatureShare)(signatureShares, src_1.SignatureShareType.USER, 'round2Output'), round2OutputShare);
910
+ assert.strictEqual((0, common_1.getBitgoSignatureShare)(signatureShares, src_1.SignatureShareType.USER, 'round1Output'), round1OutputShare);
911
+ });
912
+ it('skips malformed share records while selecting the requested BitGo round output', () => {
913
+ const malformedShare = {
914
+ from: src_1.SignatureShareType.BITGO,
915
+ to: src_1.SignatureShareType.USER,
916
+ share: 'not-json',
917
+ };
918
+ assert.strictEqual((0, common_1.getBitgoSignatureShare)([malformedShare, round2OutputShare], src_1.SignatureShareType.USER, 'round2Output'), round2OutputShare);
919
+ });
920
+ });
921
+ function assertSingleTransaction(txRequest) {
922
+ assert.ok(txRequest.transactions, 'txRequest must include transactions');
923
+ assert.strictEqual(txRequest.transactions.length, 1, 'txRequest must have exactly one transaction');
924
+ return txRequest.transactions[0];
925
+ }
926
+ function cloneTxRequestWithEmptySignatureShares(txRequest) {
927
+ const transaction = assertSingleTransaction(txRequest);
928
+ return {
929
+ ...txRequest,
930
+ transactions: [{ ...transaction, signatureShares: [] }],
931
+ };
932
+ }
933
+ async function signBitgoEddsaRound1(bitgoDsg, txRequest, userRound1Share, userGpgPubKeyArmored, bitgoGpgPrivKey) {
934
+ const transaction = assertSingleTransaction(txRequest);
935
+ transaction.signatureShares.push(userRound1Share);
936
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
937
+ const parsedUserShare = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound1Input, JSON.parse(userRound1Share.share), 'EddsaMPCv2SignatureShareRound1Input');
938
+ const userGpgKey = await pgp.readKey({ armoredKey: userGpgPubKeyArmored });
939
+ const userRawMsg1Bytes = await sdk_lib_mpc_1.MPSComms.verifyMpsMessage(parsedUserShare.data.msg1, userGpgKey);
940
+ const userMsg1 = {
941
+ from: typesMPCv2_1.MPCv2PartiesEnum.USER,
942
+ payload: new Uint8Array(userRawMsg1Bytes),
943
+ };
944
+ const [bitgoMsg2] = bitgoDsg.handleIncomingMessages([bitgoMsg1, userMsg1]);
945
+ assert.ok(bitgoMsg2, 'BitGo DSG produced no round-2 output');
946
+ bitgoDsg.round2Message = bitgoMsg2;
947
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
948
+ const round1Output = {
949
+ type: 'round1Output',
950
+ data: { msg1: bitgoSignedMsg1 },
951
+ };
952
+ transaction.signatureShares.push({
953
+ from: src_1.SignatureShareType.BITGO,
954
+ to: src_1.SignatureShareType.USER,
955
+ share: JSON.stringify(round1Output),
956
+ });
957
+ return txRequest;
958
+ }
959
+ async function signBitgoEddsaRound2(bitgoDsg, txRequest, userRound2Share, userGpgPubKeyArmored, bitgoGpgPrivKey) {
960
+ const transaction = assertSingleTransaction(txRequest);
961
+ transaction.signatureShares.push(userRound2Share);
962
+ const userGpgKey = await pgp.readKey({ armoredKey: userGpgPubKeyArmored });
963
+ const bitgoMsg2 = bitgoDsg.round2Message;
964
+ assert.ok(bitgoMsg2, 'BitGo DSG is missing the cached round-2 output');
965
+ const parsedUserRound2Share = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound2Input, JSON.parse(userRound2Share.share), 'EddsaMPCv2SignatureShareRound2Input');
966
+ const userRawMsg2Bytes = await sdk_lib_mpc_1.MPSComms.verifyMpsMessage(parsedUserRound2Share.data.msg2, userGpgKey);
967
+ const userMsg2 = {
968
+ from: typesMPCv2_1.MPCv2PartiesEnum.USER,
969
+ payload: new Uint8Array(userRawMsg2Bytes),
970
+ };
971
+ const bitgoSignedMsg2 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg2.payload), bitgoGpgPrivKey);
972
+ const round2Output = {
973
+ type: 'round2Output',
974
+ data: { msg2: bitgoSignedMsg2 },
975
+ };
976
+ transaction.signatureShares.push({
977
+ from: src_1.SignatureShareType.BITGO,
978
+ to: src_1.SignatureShareType.USER,
979
+ share: JSON.stringify(round2Output),
980
+ });
981
+ bitgoDsg.handleIncomingMessages([bitgoMsg2, userMsg2]);
982
+ return txRequest;
983
+ }
984
+ describe('EddsaMPCv2Utils.signEddsaMPCv2TssUsingExternalSigner', () => {
985
+ let sandbox;
986
+ let eddsaMPCv2Utils;
987
+ let mockBitgo;
988
+ let bitgoGpgKeyPair;
989
+ let bitgoGpgPubKey;
990
+ const walletId = 'abc123wallet';
991
+ const txRequestId = 'txreq-001';
992
+ const enterpriseId = 'ent-001';
993
+ const mockTxRequest = {
994
+ txRequestId,
995
+ walletId,
996
+ enterpriseId,
997
+ apiVersion: 'full',
998
+ transactions: [
999
+ {
1000
+ unsignedTx: {
1001
+ signableHex: 'deadbeef',
1002
+ derivationPath: 'm/0',
1003
+ serializedTxHex: 'deadbeef',
1004
+ },
1005
+ signatureShares: [
1006
+ {
1007
+ from: src_1.SignatureShareType.BITGO,
1008
+ to: src_1.SignatureShareType.USER,
1009
+ share: JSON.stringify({ type: 'round1Output', data: {} }),
1010
+ },
1011
+ ],
1012
+ },
1013
+ ],
1014
+ intent: { intentType: 'payment' },
1015
+ unsignedTxs: [],
1016
+ };
1017
+ const mockTxRequestTransaction = assertSingleTransaction(mockTxRequest);
1018
+ const mockTxRequestRound2 = {
1019
+ ...mockTxRequest,
1020
+ transactions: [
1021
+ {
1022
+ ...mockTxRequestTransaction,
1023
+ signatureShares: [
1024
+ {
1025
+ from: src_1.SignatureShareType.BITGO,
1026
+ to: src_1.SignatureShareType.USER,
1027
+ share: JSON.stringify({ type: 'round2Output', data: {} }),
1028
+ },
1029
+ ],
1030
+ },
1031
+ ],
1032
+ };
1033
+ const dummyShare = {
1034
+ from: src_1.SignatureShareType.USER,
1035
+ to: src_1.SignatureShareType.BITGO,
1036
+ share: JSON.stringify({ type: 'round1Input', data: {} }),
1037
+ };
1038
+ // Returns a chain compatible with: bitgo.post(url).send(body).result()
1039
+ const makePostChain = (response) => ({ send: () => ({ result: sinon.stub().resolves(response) }) });
1040
+ // Returns a chain compatible with: bitgo.get(url).query(params).retry(n).result()
1041
+ const makeGetChain = (txRequests) => ({
1042
+ query: () => ({
1043
+ retry: () => ({ result: sinon.stub().resolves({ txRequests }) }),
1044
+ }),
1045
+ });
1046
+ before(async () => {
1047
+ bitgoGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
1048
+ bitgoGpgPubKey = await pgp.readKey({ armoredKey: bitgoGpgKeyPair.publicKey });
1049
+ });
1050
+ beforeEach(async () => {
1051
+ sandbox = sinon.createSandbox();
1052
+ // Full mock of the BitGo HTTP client (consistent with other sdk-core tests such as
1053
+ // tokenApproval.ts and walletsEvmKeyring.ts). Module-level stubs on tssCommon functions
1054
+ // do not work under tsx 4.x (ESM live bindings), so we mock at the bitgo object level.
1055
+ mockBitgo = {
1056
+ getEnv: sinon.stub().returns('test'),
1057
+ setRequestTracer: sinon.stub(),
1058
+ url: sinon.stub().callsFake((path) => `https://test.bitgo.com${path}`),
1059
+ post: sinon.stub(),
1060
+ get: sinon.stub(),
1061
+ };
1062
+ const mockCoin = {
1063
+ getMPCAlgorithm: sinon.stub().returns('eddsa'),
1064
+ };
1065
+ const mockWallet = {
1066
+ id: sinon.stub().returns(walletId),
1067
+ keyIds: sinon.stub().returns(['userKeyId', 'backupKeyId', 'bitgoKeyId']),
1068
+ multisigTypeVersion: sinon.stub().returns('MPCv2'),
1069
+ };
1070
+ eddsaMPCv2Utils = new src_1.EddsaMPCv2Utils(mockBitgo, mockCoin, mockWallet);
1071
+ sandbox.stub(eddsaMPCv2Utils, 'pickBitgoPubGpgKeyForSigning').resolves(bitgoGpgPubKey);
1072
+ });
1073
+ afterEach(() => {
1074
+ sandbox.restore();
1075
+ });
1076
+ it('should call all 3 generators and return the final tx request', async () => {
1077
+ const finalTxRequest = { ...mockTxRequest, txRequestId };
1078
+ // sendSignatureShareV2 is called 3 times (one per round), sendTxRequest once — all use bitgo.post
1079
+ mockBitgo.post
1080
+ .onCall(0)
1081
+ .returns(makePostChain(mockTxRequest)) // round 1 sign
1082
+ .onCall(1)
1083
+ .returns(makePostChain(mockTxRequestRound2)) // round 2 sign
1084
+ .onCall(2)
1085
+ .returns(makePostChain(mockTxRequestRound2)) // round 3 sign
1086
+ .onCall(3)
1087
+ .returns(makePostChain(finalTxRequest)); // sendTxRequest (send)
1088
+ const encryptedRound1Session = 'encrypted-r1-session';
1089
+ const encryptedRound2Session = 'encrypted-r2-session';
1090
+ const encryptedUserGpgPrvKey = 'encrypted-gpg-key';
1091
+ const userGpgPubKey = bitgoGpgKeyPair.publicKey;
1092
+ const round1Share = { ...dummyShare };
1093
+ const round2Share = { ...dummyShare, share: JSON.stringify({ type: 'round2Input' }) };
1094
+ const round3Share = { ...dummyShare, share: JSON.stringify({ type: 'round3Input' }) };
1095
+ const round1Generator = sinon
1096
+ .stub()
1097
+ .resolves({ signatureShareRound1: round1Share, userGpgPubKey, encryptedRound1Session, encryptedUserGpgPrvKey });
1098
+ const round2Generator = sinon.stub().resolves({ signatureShareRound2: round2Share, encryptedRound2Session });
1099
+ const round3Generator = sinon.stub().resolves({ signatureShareRound3: round3Share });
1100
+ const result = await eddsaMPCv2Utils.signEddsaMPCv2TssUsingExternalSigner({ txRequest: mockTxRequest, reqId: new src_1.RequestTracer() }, round1Generator, round2Generator, round3Generator);
1101
+ assert.deepStrictEqual(result, finalTxRequest);
1102
+ sinon.assert.calledOnce(round1Generator);
1103
+ sinon.assert.calledWith(round1Generator, { txRequest: mockTxRequest });
1104
+ sinon.assert.calledOnce(round2Generator);
1105
+ const round2Call = round2Generator.getCall(0);
1106
+ assert.strictEqual(round2Call.args[0].txRequest, mockTxRequest);
1107
+ assert.strictEqual(round2Call.args[0].encryptedRound1Session, encryptedRound1Session);
1108
+ assert.strictEqual(round2Call.args[0].encryptedUserGpgPrvKey, encryptedUserGpgPrvKey);
1109
+ assert.strictEqual(round2Call.args[0].bitgoPublicGpgKey, bitgoGpgPubKey.armor());
1110
+ sinon.assert.calledOnce(round3Generator);
1111
+ const round3Call = round3Generator.getCall(0);
1112
+ assert.strictEqual(round3Call.args[0].txRequest, mockTxRequestRound2);
1113
+ assert.strictEqual(round3Call.args[0].encryptedRound2Session, encryptedRound2Session);
1114
+ assert.strictEqual(round3Call.args[0].encryptedUserGpgPrvKey, encryptedUserGpgPrvKey);
1115
+ assert.strictEqual(round3Call.args[0].bitgoPublicGpgKey, bitgoGpgPubKey.armor());
1116
+ // 3 sendSignatureShareV2 calls + 1 sendTxRequest = 4 POST calls total
1117
+ assert.strictEqual(mockBitgo.post.callCount, 4);
1118
+ });
1119
+ it('should resolve txRequest by ID string using getTxRequest', async () => {
1120
+ // getTxRequest uses bitgo.get; sendSignatureShareV2 (×3) + sendTxRequest use bitgo.post
1121
+ mockBitgo.get.returns(makeGetChain([mockTxRequest]));
1122
+ mockBitgo.post
1123
+ .onCall(0)
1124
+ .returns(makePostChain(mockTxRequest))
1125
+ .onCall(1)
1126
+ .returns(makePostChain(mockTxRequestRound2))
1127
+ .onCall(2)
1128
+ .returns(makePostChain(mockTxRequestRound2))
1129
+ .onCall(3)
1130
+ .returns(makePostChain(mockTxRequest));
1131
+ const round1Generator = sinon.stub().resolves({
1132
+ signatureShareRound1: dummyShare,
1133
+ userGpgPubKey: bitgoGpgKeyPair.publicKey,
1134
+ encryptedRound1Session: 'r1',
1135
+ encryptedUserGpgPrvKey: 'key',
1136
+ });
1137
+ const round2Generator = sinon.stub().resolves({ signatureShareRound2: dummyShare, encryptedRound2Session: 'r2' });
1138
+ const round3Generator = sinon.stub().resolves({ signatureShareRound3: dummyShare });
1139
+ await eddsaMPCv2Utils.signEddsaMPCv2TssUsingExternalSigner({ txRequest: txRequestId, reqId: new src_1.RequestTracer() }, round1Generator, round2Generator, round3Generator);
1140
+ sinon.assert.calledOnce(mockBitgo.get);
1141
+ sinon.assert.calledWith(round1Generator, { txRequest: mockTxRequest });
1142
+ });
1143
+ it('should throw when round 2 txRequest is missing signatureShares', async () => {
1144
+ const round2NoShares = {
1145
+ ...mockTxRequest,
1146
+ transactions: [{ ...mockTxRequestTransaction, signatureShares: undefined }],
1147
+ };
1148
+ mockBitgo.post
1149
+ .onCall(0)
1150
+ .returns(makePostChain(mockTxRequest))
1151
+ .onCall(1)
1152
+ .returns(makePostChain(round2NoShares));
1153
+ const round1Generator = sinon.stub().resolves({
1154
+ signatureShareRound1: dummyShare,
1155
+ userGpgPubKey: bitgoGpgKeyPair.publicKey,
1156
+ encryptedRound1Session: 'r1',
1157
+ encryptedUserGpgPrvKey: 'key',
1158
+ });
1159
+ const round2Generator = sinon.stub().resolves({ signatureShareRound2: dummyShare, encryptedRound2Session: 'r2' });
1160
+ const round3Generator = sinon.stub().resolves({ signatureShareRound3: dummyShare });
1161
+ await assert.rejects(() => eddsaMPCv2Utils.signEddsaMPCv2TssUsingExternalSigner({ txRequest: mockTxRequest, reqId: new src_1.RequestTracer() }, round1Generator, round2Generator, round3Generator), /Missing signature shares in round 2 txRequest/);
1162
+ });
1163
+ it('should pass armored BitGo public GPG key to round 2 and round 3 generators', async () => {
1164
+ mockBitgo.post
1165
+ .onCall(0)
1166
+ .returns(makePostChain(mockTxRequest))
1167
+ .onCall(1)
1168
+ .returns(makePostChain(mockTxRequestRound2))
1169
+ .onCall(2)
1170
+ .returns(makePostChain(mockTxRequestRound2))
1171
+ .onCall(3)
1172
+ .returns(makePostChain(mockTxRequest));
1173
+ const round1Generator = sinon.stub().resolves({
1174
+ signatureShareRound1: dummyShare,
1175
+ userGpgPubKey: bitgoGpgKeyPair.publicKey,
1176
+ encryptedRound1Session: 'r1',
1177
+ encryptedUserGpgPrvKey: 'key',
1178
+ });
1179
+ const round2Generator = sinon.stub().resolves({ signatureShareRound2: dummyShare, encryptedRound2Session: 'r2' });
1180
+ const round3Generator = sinon.stub().resolves({ signatureShareRound3: dummyShare });
1181
+ await eddsaMPCv2Utils.signEddsaMPCv2TssUsingExternalSigner({ txRequest: mockTxRequest, reqId: new src_1.RequestTracer() }, round1Generator, round2Generator, round3Generator);
1182
+ const armoredKey = bitgoGpgPubKey.armor();
1183
+ assert.strictEqual(round2Generator.getCall(0).args[0].bitgoPublicGpgKey, armoredKey, 'round 2 should receive armored BitGo GPG key');
1184
+ assert.strictEqual(round3Generator.getCall(0).args[0].bitgoPublicGpgKey, armoredKey, 'round 3 should receive armored BitGo GPG key');
1185
+ });
1186
+ });
1187
+ function bytesToWord(bytes) {
1188
+ if (!(bytes instanceof Uint8Array) || bytes.length !== 4) {
1189
+ throw new Error('bytes must be a Uint8Array with length 4');
1190
+ }
1191
+ return bytes.reduce((num, byte) => num * 0x100 + byte, 0);
1192
+ }
1193
+ describe('EDDSAUtils.isEddsaMpcV1SigningMaterial', () => {
1194
+ const PASSPHRASE = 'test-passphrase';
1195
+ const MPCv1_MATERIAL_BACKUP = {
1196
+ uShare: { i: 1, t: 2, n: 3, y: 'aabbcc', seed: 'deadbeef01234567', chaincode: '00' },
1197
+ bitgoYShare: { i: 3, j: 1, y: 'aabbcc', u: 'bitgo-u-value', chaincode: '00' },
1198
+ backupYShare: { i: 2, j: 1, y: 'aabbcc', u: 'backup-u-value', chaincode: '00' },
1199
+ };
1200
+ const MPCv1_MATERIAL_USER = {
1201
+ uShare: { i: 2, t: 2, n: 3, y: 'aabbcc', seed: 'deadbeef01234567', chaincode: '00' },
1202
+ bitgoYShare: { i: 3, j: 2, y: 'aabbcc', u: 'bitgo-u-value', chaincode: '00' },
1203
+ userYShare: { i: 1, j: 2, y: 'aabbcc', u: 'user-u-value', chaincode: '00' },
1204
+ };
1205
+ const MPCv2_CBOR_BYTES = Buffer.from([0xd9, 0x01, 0x04, 0xa3, 0x61, 0x78, 0x18, 0x00]).toString('base64');
1206
+ let mockBitgo;
1207
+ beforeEach(() => {
1208
+ // sdk-core has no devDependency on sdk-api/argon2, so v2 envelopes are simulated here.
1209
+ // Real bitgo.decrypt routes v2 to Argon2id; the stub returns MPCv2 CBOR plaintext instead.
1210
+ mockBitgo = {
1211
+ decrypt: sinon.stub().callsFake(async (params) => {
1212
+ if ((0, baseTypes_1.isV2Envelope)(params.input)) {
1213
+ return MPCv2_CBOR_BYTES;
1214
+ }
1215
+ return sjcl.decrypt(params.password, params.input);
1216
+ }),
1217
+ };
1218
+ });
1219
+ it('returns true for MPCv1 SJCL-encrypted keycard with backupYShare + correct passphrase', async () => {
1220
+ const encrypted = sjcl.encrypt(PASSPHRASE, JSON.stringify(MPCv1_MATERIAL_BACKUP));
1221
+ assert.strictEqual(await src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(encrypted, PASSPHRASE), true);
1222
+ });
1223
+ it('returns true for MPCv1 SJCL-encrypted keycard with userYShare + correct passphrase', async () => {
1224
+ const encrypted = sjcl.encrypt(PASSPHRASE, JSON.stringify(MPCv1_MATERIAL_USER));
1225
+ assert.strictEqual(await src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(encrypted, PASSPHRASE), true);
1226
+ });
1227
+ it('returns false for MPCv2 CBOR content wrapped in SJCL envelope + correct passphrase', async () => {
1228
+ const encrypted = sjcl.encrypt(PASSPHRASE, MPCv2_CBOR_BYTES);
1229
+ assert.strictEqual(await src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(encrypted, PASSPHRASE), false);
1230
+ });
1231
+ it('returns false for MPCv2 Argon2id envelope (v2) + correct passphrase (forward-compat)', async () => {
1232
+ const fakeV2Envelope = JSON.stringify({ v: 2, m: 65536, t: 3, p: 4, salt: 'AAAA', iv: 'AAAA', ct: 'AAAA' });
1233
+ assert.strictEqual(await src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(fakeV2Envelope, PASSPHRASE, mockBitgo), false);
1234
+ });
1235
+ it('throws on wrong passphrase', async () => {
1236
+ const encrypted = sjcl.encrypt(PASSPHRASE, JSON.stringify(MPCv1_MATERIAL_BACKUP));
1237
+ await assert.rejects(src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(encrypted, 'wrong-passphrase'), /ccm: tag doesn't match/);
1238
+ });
1239
+ it('returns false when neither backupYShare.u nor userYShare.u is present', async () => {
1240
+ const partial = { uShare: { seed: 'abc' }, bitgoYShare: { u: 'xyz' } };
1241
+ const encrypted = sjcl.encrypt(PASSPHRASE, JSON.stringify(partial));
1242
+ assert.strictEqual(await src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(encrypted, PASSPHRASE), false);
1243
+ });
1244
+ });
1245
+ describe('signRecoveryEddsaMPCv2', () => {
1246
+ const derivationPath = 'm/0/0';
1247
+ it('should return a 64-byte signature that verifies against the derived public key', async () => {
1248
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
1249
+ const message = Buffer.from('deadbeef', 'hex');
1250
+ const commonKeyChain = userDkg.getCommonKeychain();
1251
+ const signature = await src_1.EDDSAUtils.signRecoveryEddsaMPCv2(message, derivationPath, userDkg.getKeyShare(), backupDkg.getKeyShare(), commonKeyChain);
1252
+ assert.strictEqual(signature.length, 64);
1253
+ const mpc = await (0, eddsa_1.getInitializedMpcInstance)();
1254
+ const derivedKeychain = mpc.deriveUnhardened(commonKeyChain, derivationPath);
1255
+ const publicKeyBytes = Buffer.from(derivedKeychain.slice(0, 64), 'hex');
1256
+ const ok = ed25519_1.ed25519.verify(new Uint8Array(signature), new Uint8Array(message), new Uint8Array(publicKeyBytes));
1257
+ assert.strictEqual(ok, true);
1258
+ });
1259
+ it('should return false when verifying the signature against a different message', async () => {
1260
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
1261
+ const message = Buffer.from('deadbeef', 'hex');
1262
+ const commonKeyChain = userDkg.getCommonKeychain();
1263
+ const signature = await src_1.EDDSAUtils.signRecoveryEddsaMPCv2(message, derivationPath, userDkg.getKeyShare(), backupDkg.getKeyShare(), commonKeyChain);
1264
+ const differentMessage = Buffer.from('cafebabe', 'hex');
1265
+ const mpc = await (0, eddsa_1.getInitializedMpcInstance)();
1266
+ const derivedKeychain = mpc.deriveUnhardened(commonKeyChain, derivationPath);
1267
+ const publicKeyBytes = Buffer.from(derivedKeychain.slice(0, 64), 'hex');
1268
+ const ok = ed25519_1.ed25519.verify(new Uint8Array(signature), new Uint8Array(differentMessage), new Uint8Array(publicKeyBytes));
1269
+ assert.strictEqual(ok, false);
1270
+ });
1271
+ it('should throw when a wrong commonKeyChain is provided (verification mismatch)', async () => {
1272
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
1273
+ const [wrongDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
1274
+ const message = Buffer.from('deadbeef', 'hex');
1275
+ await assert.rejects(() => src_1.EDDSAUtils.signRecoveryEddsaMPCv2(message, derivationPath, userDkg.getKeyShare(), backupDkg.getKeyShare(), wrongDkg.getCommonKeychain() // key chain from a different wallet
1276
+ ), /EdDSA MPCv2 recovery signature verification failed/);
1277
+ });
1278
+ });
1279
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRkc2FNUEN2Mi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Rlc3QvdW5pdC9iaXRnby91dGlscy90c3MvZWRkc2EvZWRkc2FNUEN2Mi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtDQUFpQztBQUNqQyw2Q0FBK0I7QUFDL0IsNkNBQStCO0FBQy9CLG1DQUFxQztBQUNyQyx5REFBbUY7QUFDbkYsbURBQWdEO0FBQ2hELHVEQUF5QztBQUN6QyxzREFNNkI7QUFDN0IsK0NBYytCO0FBQy9CLGlGQU0wRDtBQUMxRCx1RUFBd0Y7QUFDeEYsbUVBQWdGO0FBQ2hGLHFFQUEyRTtBQUMzRSxpRkFBb0Y7QUFDcEYsdUZBQTBGO0FBQzFGLCtFQUErRTtBQUUvRSxRQUFRLENBQUMsZ0NBQWdDLEVBQUUsS0FBSyxJQUFJLEVBQUU7SUFDcEQsSUFBSSxZQUFvQixDQUFDO0lBQ3pCLElBQUksY0FBc0IsQ0FBQztJQUMzQixJQUFJLGFBQXFCLENBQUM7SUFDMUIsSUFBSSxjQUE4QixDQUFDO0lBQ25DLElBQUksZ0JBQWdDLENBQUM7SUFDckMsSUFBSSxlQUErQixDQUFDO0lBQ3BDLElBQUksY0FBdUIsQ0FBQztJQUU1QixNQUFNLFdBQVcsR0FBRyxVQUFVLENBQUM7SUFDL0IsTUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDO0lBRTdCLE1BQU0sQ0FBQywrQkFBK0IsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNqRCxNQUFNLGNBQWMsR0FBRyxNQUFNLElBQUEsaUNBQWtCLEVBQUMsU0FBUyxDQUFDLENBQUM7UUFDM0QsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLElBQUEsaUNBQWtCLEVBQUMsU0FBUyxDQUFDLENBQUM7UUFDN0QsTUFBTSxlQUFlLEdBQUcsTUFBTSxJQUFBLGlDQUFrQixFQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRTVELGNBQWMsR0FBRyxNQUFNLEdB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RSxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzVGLE1BQU0sQ0FBQyxPQUFPLEVBQUUsU0FBUyxDQUFDLEdBQUcsTUFBTSxxQkFBTyxDQUFDLHlCQUF5QixFQUFFLENBQUM7UUFDdkUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLE1BQU0scUJBQU8sQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO1FBQzdELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRS9DLE1BQU0sTUFBTSxDQUFDLE9BQU8sQ0FDbEIsR0FBRyxFQUFFLENBQ0gsZ0JBQVUsQ0FBQyxzQkFBc0IsQ0FDL0IsT0FBTyxFQUNQLGNBQWMsRUFDZCxPQUFPLENBQUMsV0FBVyxFQUFFLEVBQ3JCLFNBQVMsQ0FBQyxXQUFXLEVBQUUsRUFDdkIsUUFBUSxDQUFDLGlCQUFpQixFQUFFLENBQUMsb0NBQW9DO1NBQ2xFLEVBQ0gsb0RBQW9ELENBQ3JELENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgKiBhcyBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgKiBhcyBwZ3AgZnJvbSAnb3BlbnBncCc7XG5pbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBFZGRzYU1QU0RzZywgTVBTQ29tbXMsIE1QU1R5cGVzLCBNUFNVdGlsIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWxpYi1tcGMnO1xuaW1wb3J0IHsgZWQyNTUxOSB9IGZyb20gJ0Bub2JsZS9jdXJ2ZXMvZWQyNTUxOSc7XG5pbXBvcnQgKiBhcyBzamNsIGZyb20gJ0BiaXRnby1iZXRhL3NqY2wnO1xuaW1wb3J0IHtcbiAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQsXG4gIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMU91dHB1dCxcbiAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQySW5wdXQsXG4gIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMk91dHB1dCxcbiAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQzSW5wdXQsXG59IGZyb20gJ0BiaXRnby9wdWJsaWMtdHlwZXMnO1xuaW1wb3J0IHtcbiAgQml0R29CYXNlLFxuICBCaXRHb1JlcXVlc3QsXG4gIEN1c3RvbUVkZHNhTVBDdjJTaWduaW5nUm91bmQxR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kMkdlbmVyYXRpbmdGdW5jdGlvbixcbiAgQ3VzdG9tRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDNHZW5lcmF0aW5nRnVuY3Rpb24sXG4gIEVERFNBVXRpbHMsXG4gIEVkZHNhTVBDdjJVdGlscyxcbiAgSUJhc2VDb2luLFxuICBJV2FsbGV0LFxuICBSZXF1ZXN0VHJhY2VyLFxuICBTaWduYXR1cmVTaGFyZVJlY29yZCxcbiAgU2lnbmF0dXJlU2hhcmVUeXBlLFxuICBUeFJlcXVlc3QsXG59IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL3NyYyc7XG5pbXBvcnQge1xuICBnZXRTaWduYXR1cmVTaGFyZVJvdW5kT25lLFxuICBnZXRTaWduYXR1cmVTaGFyZVJvdW5kVHdvLFxuICBnZXRTaWduYXR1cmVTaGFyZVJvdW5kVGhyZWUsXG4gIHZlcmlmeVBlZXJNZXNzYWdlUm91bmRPbmUsXG4gIHZlcmlmeVBlZXJNZXNzYWdlUm91bmRUd28sXG59IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9iaXRnby90c3MvZWRkc2EvZWRkc2FNUEN2Mic7XG5pbXBvcnQgeyBnZXRJbml0aWFsaXplZE1wY0luc3RhbmNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2JpdGdvL3Rzcy9lZGRzYS9lZGRzYSc7XG5pbXBvcnQgeyBnZXRCaXRnb1NpZ25hdHVyZVNoYXJlIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2JpdGdvL3Rzcy9jb21tb24nO1xuaW1wb3J0IHsgZGVjb2RlV2l0aENvZGVjIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2JpdGdvL3V0aWxzL2NvZGVjcyc7XG5pbXBvcnQgeyBnZW5lcmF0ZUdQR0tleVBhaXIgfSBmcm9tICcuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYml0Z28vdXRpbHMvb3BlbmdwZ1V0aWxzJztcbmltcG9ydCB7IE1QQ3YyUGFydGllc0VudW0gfSBmcm9tICcuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYml0Z28vdXRpbHMvdHNzL2VjZHNhL3R5cGVzTVBDdjInO1xuaW1wb3J0IHsgaXNWMkVudmVsb3BlIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2JpdGdvL3V0aWxzL3Rzcy9iYXNlVHlwZXMnO1xuXG5kZXNjcmliZSgnRWREU0EgTVBTIERTRyBoZWxwZXIgZnVuY3Rpb25zJywgYXN5bmMgKCkgPT4ge1xuICBsZXQgdXNlcktleVNoYXJlOiBCdWZmZXI7XG4gIGxldCBiYWNrdXBLZXlTaGFyZTogQnVmZmVyO1xuICBsZXQgYml0Z29LZXlTaGFyZTogQnVmZmVyO1xuICBsZXQgdXNlckdwZ1ByaXZLZXk6IHBncC5Qcml2YXRlS2V5O1xuICBsZXQgYmFja3VwR3BnUHJpdktleTogcGdwLlByaXZhdGVLZXk7XG4gIGxldCBiaXRnb0dwZ1ByaXZLZXk6IHBncC5Qcml2YXRlS2V5O1xuICBsZXQgYml0Z29HcGdQdWJLZXk6IHBncC5LZXk7XG5cbiAgY29uc3Qgc2lnbmFibGVIZXggPSAnZGVhZGJlZWYnO1xuICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9ICdtLzAnO1xuXG4gIGJlZm9yZSgnZ2VuZXJhdGUgRWREU0EgREtHIGtleSBzaGFyZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdXNlckdwZ0tleVBhaXIgPSBhd2FpdCBnZW5lcmF0ZUdQR0tleVBhaXIoJ2VkMjU1MTknKTtcbiAgICBjb25zdCBiYWNrdXBHcGdLZXlQYWlyID0gYXdhaXQgZ2VuZXJhdGVHUEdLZXlQYWlyKCdlZDI1NTE5Jyk7XG4gICAgY29uc3QgYml0Z29HcGdLZXlQYWlyID0gYXdhaXQgZ2VuZXJhdGVHUEdLZXlQYWlyKCdlZDI1NTE5Jyk7XG5cbiAgICB1c2VyR3BnUHJpdktleSA9IGF3YWl0IHBncC5yZWFkUHJpdmF0ZUtleSh7IGFybW9yZWRLZXk6IHVzZXJHcGdLZXlQYWlyLnByaXZhdGVLZXkgfSk7XG4gICAgYmFja3VwR3BnUHJpdktleSA9IGF3YWl0IHBncC5yZWFkUHJpdmF0ZUtleSh7IGFybW9yZWRLZXk6IGJhY2t1cEdwZ0tleVBhaXIucHJpdmF0ZUtleSB9KTtcbiAgICBiaXRnb0dwZ1ByaXZLZXkgPSBhd2FpdCBwZ3AucmVhZFByaXZhdGVLZXkoeyBhcm1vcmVkS2V5OiBiaXRnb0dwZ0tleVBhaXIucHJpdmF0ZUtleSB9KTtcbiAgICBiaXRnb0dwZ1B1YktleSA9IGF3YWl0IHBncC5yZWFkS2V5KHsgYXJtb3JlZEtleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSB9KTtcblxuICAgIGNvbnN0IFt1c2VyRGtnLCBiYWNrdXBEa2csIGJpdGdvRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIHVzZXJLZXlTaGFyZSA9IHVzZXJEa2cuZ2V0S2V5U2hhcmUoKTtcbiAgICBiYWNrdXBLZXlTaGFyZSA9IGJhY2t1cERrZy5nZXRLZXlTaGFyZSgpO1xuICAgIGJpdGdvS2V5U2hhcmUgPSBiaXRnb0RrZy5nZXRLZXlTaGFyZSgpO1xuICB9KTtcblxuICAvLyDilIDilIAgUm91bmQgMSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBpdCgnZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZE9uZSBzaG91bGQgYnVpbGQgYSB2YWxpZCByb3VuZC0xIHNoYXJlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbShzaWduYWJsZUhleCwgJ2hleCcpO1xuICAgIGNvbnN0IHVzZXJEc2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uVVNFUik7XG4gICAgYXdhaXQgdXNlckRzZy5pbml0RHNnKHVzZXJLZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGNvbnN0IHVzZXJNc2cxID0gdXNlckRzZy5nZXRGaXJzdE1lc3NhZ2UoKTtcblxuICAgIGNvbnN0IHNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCA9IGF3YWl0IGdldFNpZ25hdHVyZVNoYXJlUm91bmRPbmUodXNlck1zZzEsIHVzZXJHcGdQcml2S2V5KTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaGFyZS5mcm9tLCBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNoYXJlLnRvLCBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08pO1xuXG4gICAgY29uc3QgcGFyc2VkID0gZGVjb2RlV2l0aENvZGVjKFxuICAgICAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQsXG4gICAgICBKU09OLnBhcnNlKHNoYXJlLnNoYXJlKSxcbiAgICAgICdFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFJbnB1dCdcbiAgICApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChwYXJzZWQudHlwZSwgJ3JvdW5kMUlucHV0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZC5kYXRhLm1zZzEubWVzc2FnZSwgJ21zZzEubWVzc2FnZSBzaG91bGQgYmUgc2V0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZC5kYXRhLm1zZzEuc2lnbmF0dXJlLCAnbXNnMS5zaWduYXR1cmUgc2hvdWxkIGJlIHNldCcpO1xuICB9KTtcblxuICBpdCgnZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZE9uZSBzaG91bGQgYnVpbGQgYSB2YWxpZCBiYWNrdXAgcm91bmQtMSBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCBiYWNrdXBEc2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQkFDS1VQKTtcbiAgICBhd2FpdCBiYWNrdXBEc2cuaW5pdERzZyhiYWNrdXBLZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGNvbnN0IGJhY2t1cE1zZzEgPSBiYWNrdXBEc2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG5cbiAgICBjb25zdCBzaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSBhd2FpdCBnZXRTaWduYXR1cmVTaGFyZVJvdW5kT25lKFxuICAgICAgYmFja3VwTXNnMSxcbiAgICAgIGJhY2t1cEdwZ1ByaXZLZXksXG4gICAgICBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUFxuICAgICk7XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2hhcmUuZnJvbSwgU2lnbmF0dXJlU2hhcmVUeXBlLkJBQ0tVUCk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNoYXJlLnRvLCBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08pO1xuXG4gICAgY29uc3QgcGFyc2VkID0gZGVjb2RlV2l0aENvZGVjKFxuICAgICAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQsXG4gICAgICBKU09OLnBhcnNlKHNoYXJlLnNoYXJlKSxcbiAgICAgICdFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFJbnB1dCdcbiAgICApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChwYXJzZWQudHlwZSwgJ3JvdW5kMUlucHV0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZC5kYXRhLm1zZzEubWVzc2FnZSwgJ21zZzEubWVzc2FnZSBzaG91bGQgYmUgc2V0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZC5kYXRhLm1zZzEuc2lnbmF0dXJlLCAnbXNnMS5zaWduYXR1cmUgc2hvdWxkIGJlIHNldCcpO1xuICB9KTtcblxuICBpdCgndmVyaWZ5UGVlck1lc3NhZ2VSb3VuZE9uZSBzaG91bGQgdmVyaWZ5IGEgdmFsaWQgQml0R28gcm91bmQtMSBtZXNzYWdlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbShzaWduYWJsZUhleCwgJ2hleCcpO1xuICAgIGNvbnN0IGJpdGdvRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhd2FpdCBiaXRnb0RzZy5pbml0RHNnKGJpdGdvS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuICAgIGNvbnN0IGJpdGdvTXNnMSA9IGJpdGdvRHNnLmdldEZpcnN0TWVzc2FnZSgpO1xuXG4gICAgY29uc3QgYml0Z29TaWduZWRNc2cxID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYml0Z29Nc2cxLnBheWxvYWQpLCBiaXRnb0dwZ1ByaXZLZXkpO1xuICAgIGNvbnN0IHJvdW5kMU91dHB1dDogRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxT3V0cHV0ID0ge1xuICAgICAgdHlwZTogJ3JvdW5kMU91dHB1dCcsXG4gICAgICBkYXRhOiB7IG1zZzE6IGJpdGdvU2lnbmVkTXNnMSB9LFxuICAgIH07XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kT25lKHJvdW5kMU91dHB1dCwgYml0Z29HcGdQdWJLZXkpO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5mcm9tLCBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhc3NlcnQub2socmVzdWx0LnBheWxvYWQubGVuZ3RoID4gMCwgJ3BheWxvYWQgc2hvdWxkIGJlIG5vbi1lbXB0eScpO1xuICB9KTtcblxuICBpdCgndmVyaWZ5UGVlck1lc3NhZ2VSb3VuZE9uZSBzaG91bGQgdGhyb3cgb24gYSB0YW1wZXJlZCBtZXNzYWdlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJvdW5kMU91dHB1dDogRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxT3V0cHV0ID0ge1xuICAgICAgdHlwZTogJ3JvdW5kMU91dHB1dCcsXG4gICAgICBkYXRhOiB7XG4gICAgICAgIG1zZzE6IHtcbiAgICAgICAgICBtZXNzYWdlOiBCdWZmZXIuZnJvbSgndGFtcGVyZWQnKS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICAgICAgc2lnbmF0dXJlOiAnLS0tLS1CRUdJTiBQR1AgU0lHTkFUVVJFLS0tLS1cXG5cXG5JTlZBTElEXFxuLS0tLS1FTkQgUEdQIFNJR05BVFVSRS0tLS0tXFxuJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKHZlcmlmeVBlZXJNZXNzYWdlUm91bmRPbmUocm91bmQxT3V0cHV0LCBiaXRnb0dwZ1B1YktleSksICdzaG91bGQgdGhyb3cgb24gaW52YWxpZCBzaWduYXR1cmUnKTtcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFJvdW5kIDIg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgaXQoJ2dldFNpZ25hdHVyZVNoYXJlUm91bmRUd28gc2hvdWxkIGJ1aWxkIGEgdmFsaWQgcm91bmQtMiBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCB1c2VyRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuICAgIGF3YWl0IHVzZXJEc2cuaW5pdERzZyh1c2VyS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBjb25zdCB1c2VyTXNnMSA9IHVzZXJEc2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG5cbiAgICBjb25zdCBiaXRnb0RzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYXdhaXQgYml0Z29Ec2cuaW5pdERzZyhiaXRnb0tleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcbiAgICBjb25zdCBiaXRnb01zZzEgPSBiaXRnb0RzZy5nZXRGaXJzdE1lc3NhZ2UoKTtcblxuICAgIGNvbnN0IGJpdGdvU2lnbmVkTXNnMSA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKGJpdGdvTXNnMS5wYXlsb2FkKSwgYml0Z29HcGdQcml2S2V5KTtcbiAgICBjb25zdCBiaXRnb0Rlc2VyaWFsaXplZE1zZzEgPSBhd2FpdCB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kT25lKFxuICAgICAgeyB0eXBlOiAncm91bmQxT3V0cHV0JywgZGF0YTogeyBtc2cxOiBiaXRnb1NpZ25lZE1zZzEgfSB9LFxuICAgICAgYml0Z29HcGdQdWJLZXlcbiAgICApO1xuICAgIGNvbnN0IFt1c2VyTXNnMl0gPSB1c2VyRHNnLmhhbmRsZUluY29taW5nTWVzc2FnZXMoW3VzZXJNc2cxLCBiaXRnb0Rlc2VyaWFsaXplZE1zZzFdKTtcblxuICAgIGNvbnN0IHNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCA9IGF3YWl0IGdldFNpZ25hdHVyZVNoYXJlUm91bmRUd28odXNlck1zZzIsIHVzZXJHcGdQcml2S2V5KTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaGFyZS5mcm9tLCBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNoYXJlLnRvLCBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08pO1xuXG4gICAgY29uc3QgcGFyc2VkID0gZGVjb2RlV2l0aENvZGVjKFxuICAgICAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQySW5wdXQsXG4gICAgICBKU09OLnBhcnNlKHNoYXJlLnNoYXJlKSxcbiAgICAgICdFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJJbnB1dCdcbiAgICApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChwYXJzZWQudHlwZSwgJ3JvdW5kMklucHV0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZC5kYXRhLm1zZzIubWVzc2FnZSwgJ21zZzIubWVzc2FnZSBzaG91bGQgYmUgc2V0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZC5kYXRhLm1zZzIuc2lnbmF0dXJlLCAnbXNnMi5zaWduYXR1cmUgc2hvdWxkIGJlIHNldCcpO1xuICB9KTtcblxuICBpdCgnZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFR3byBzaG91bGQgYnVpbGQgYSB2YWxpZCBiYWNrdXAgcm91bmQtMiBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCBiYWNrdXBEc2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQkFDS1VQKTtcbiAgICBhd2FpdCBiYWNrdXBEc2cuaW5pdERzZyhiYWNrdXBLZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGNvbnN0IGJhY2t1cE1zZzEgPSBiYWNrdXBEc2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG5cbiAgICBjb25zdCBiaXRnb0RzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYXdhaXQgYml0Z29Ec2cuaW5pdERzZyhiaXRnb0tleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVApO1xuICAgIGNvbnN0IGJpdGdvTXNnMSA9IGJpdGdvRHNnLmdldEZpcnN0TWVzc2FnZSgpO1xuXG4gICAgY29uc3QgYml0Z29TaWduZWRNc2cxID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYml0Z29Nc2cxLnBheWxvYWQpLCBiaXRnb0dwZ1ByaXZLZXkpO1xuICAgIGNvbnN0IGJpdGdvRGVzZXJpYWxpemVkTXNnMSA9IGF3YWl0IHZlcmlmeVBlZXJNZXNzYWdlUm91bmRPbmUoXG4gICAgICB7IHR5cGU6ICdyb3VuZDFPdXRwdXQnLCBkYXRhOiB7IG1zZzE6IGJpdGdvU2lnbmVkTXNnMSB9IH0sXG4gICAgICBiaXRnb0dwZ1B1YktleVxuICAgICk7XG4gICAgY29uc3QgW2JhY2t1cE1zZzJdID0gYmFja3VwRHNnLmhhbmRsZUluY29taW5nTWVzc2FnZXMoW2JhY2t1cE1zZzEsIGJpdGdvRGVzZXJpYWxpemVkTXNnMV0pO1xuXG4gICAgY29uc3Qgc2hhcmU6IFNpZ25hdHVyZVNoYXJlUmVjb3JkID0gYXdhaXQgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFR3byhcbiAgICAgIGJhY2t1cE1zZzIsXG4gICAgICBiYWNrdXBHcGdQcml2S2V5LFxuICAgICAgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVBcbiAgICApO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNoYXJlLmZyb20sIFNpZ25hdHVyZVNoYXJlVHlwZS5CQUNLVVApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaGFyZS50bywgU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPKTtcblxuICAgIGNvbnN0IHBhcnNlZCA9IGRlY29kZVdpdGhDb2RlYyhcbiAgICAgIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMklucHV0LFxuICAgICAgSlNPTi5wYXJzZShzaGFyZS5zaGFyZSksXG4gICAgICAnRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQySW5wdXQnXG4gICAgKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFyc2VkLnR5cGUsICdyb3VuZDJJbnB1dCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWQuZGF0YS5tc2cyLm1lc3NhZ2UsICdtc2cyLm1lc3NhZ2Ugc2hvdWxkIGJlIHNldCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWQuZGF0YS5tc2cyLnNpZ25hdHVyZSwgJ21zZzIuc2lnbmF0dXJlIHNob3VsZCBiZSBzZXQnKTtcbiAgfSk7XG5cbiAgaXQoJ3ZlcmlmeVBlZXJNZXNzYWdlUm91bmRUd28gc2hvdWxkIHZlcmlmeSBhIHZhbGlkIEJpdEdvIHJvdW5kLTIgbWVzc2FnZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCB1c2VyRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuICAgIGF3YWl0IHVzZXJEc2cuaW5pdERzZyh1c2VyS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBjb25zdCB1c2VyTXNnMSA9IHVzZXJEc2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG5cbiAgICBjb25zdCBiaXRnb0RzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYXdhaXQgYml0Z29Ec2cuaW5pdERzZyhiaXRnb0tleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcbiAgICBjb25zdCBiaXRnb01zZzEgPSBiaXRnb0RzZy5nZXRGaXJzdE1lc3NhZ2UoKTtcblxuICAgIGNvbnN0IFtiaXRnb01zZzJdID0gYml0Z29Ec2cuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhbYml0Z29Nc2cxLCB1c2VyTXNnMV0pO1xuICAgIGNvbnN0IGJpdGdvU2lnbmVkTXNnMiA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKGJpdGdvTXNnMi5wYXlsb2FkKSwgYml0Z29HcGdQcml2S2V5KTtcblxuICAgIGNvbnN0IHJvdW5kMk91dHB1dDogRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQyT3V0cHV0ID0ge1xuICAgICAgdHlwZTogJ3JvdW5kMk91dHB1dCcsXG4gICAgICBkYXRhOiB7IG1zZzI6IGJpdGdvU2lnbmVkTXNnMiB9LFxuICAgIH07XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kVHdvKHJvdW5kMk91dHB1dCwgYml0Z29HcGdQdWJLZXkpO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5mcm9tLCBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhc3NlcnQub2socmVzdWx0LnBheWxvYWQubGVuZ3RoID4gMCwgJ3BheWxvYWQgc2hvdWxkIGJlIG5vbi1lbXB0eScpO1xuICB9KTtcblxuICBpdCgndmVyaWZ5UGVlck1lc3NhZ2VSb3VuZFR3byBzaG91bGQgdGhyb3cgb24gYSB0YW1wZXJlZCBtZXNzYWdlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJvdW5kMk91dHB1dDogRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQyT3V0cHV0ID0ge1xuICAgICAgdHlwZTogJ3JvdW5kMk91dHB1dCcsXG4gICAgICBkYXRhOiB7XG4gICAgICAgIG1zZzI6IHtcbiAgICAgICAgICBtZXNzYWdlOiBCdWZmZXIuZnJvbSgndGFtcGVyZWQnKS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICAgICAgc2lnbmF0dXJlOiAnLS0tLS1CRUdJTiBQR1AgU0lHTkFUVVJFLS0tLS1cXG5cXG5JTlZBTElEXFxuLS0tLS1FTkQgUEdQIFNJR05BVFVSRS0tLS0tXFxuJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKHZlcmlmeVBlZXJNZXNzYWdlUm91bmRUd28ocm91bmQyT3V0cHV0LCBiaXRnb0dwZ1B1YktleSksICdzaG91bGQgdGhyb3cgb24gaW52YWxpZCBzaWduYXR1cmUnKTtcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFJvdW5kIDMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgaXQoJ2dldFNpZ25hdHVyZVNoYXJlUm91bmRUaHJlZSBzaG91bGQgYnVpbGQgYSB2YWxpZCByb3VuZC0zIHNoYXJlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbShzaWduYWJsZUhleCwgJ2hleCcpO1xuICAgIGNvbnN0IHVzZXJEc2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uVVNFUik7XG4gICAgYXdhaXQgdXNlckRzZy5pbml0RHNnKHVzZXJLZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGNvbnN0IHVzZXJNc2cxID0gdXNlckRzZy5nZXRGaXJzdE1lc3NhZ2UoKTtcblxuICAgIGNvbnN0IGJpdGdvRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhd2FpdCBiaXRnb0RzZy5pbml0RHNnKGJpdGdvS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuICAgIGNvbnN0IGJpdGdvTXNnMSA9IGJpdGdvRHNnLmdldEZpcnN0TWVzc2FnZSgpO1xuXG4gICAgLy8gQWR2YW5jZSB0byByb3VuZCAyXG4gICAgY29uc3QgYml0Z29TaWduZWRNc2cxID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYml0Z29Nc2cxLnBheWxvYWQpLCBiaXRnb0dwZ1ByaXZLZXkpO1xuICAgIGNvbnN0IGJpdGdvRGVzZXJpYWxpemVkTXNnMSA9IGF3YWl0IHZlcmlmeVBlZXJNZXNzYWdlUm91bmRPbmUoXG4gICAgICB7IHR5cGU6ICdyb3VuZDFPdXRwdXQnLCBkYXRhOiB7IG1zZzE6IGJpdGdvU2lnbmVkTXNnMSB9IH0sXG4gICAgICBiaXRnb0dwZ1B1YktleVxuICAgICk7XG4gICAgY29uc3QgW3VzZXJNc2cyXSA9IHVzZXJEc2cuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhbdXNlck1zZzEsIGJpdGdvRGVzZXJpYWxpemVkTXNnMV0pO1xuXG4gICAgY29uc3QgW2JpdGdvTXNnMl0gPSBiaXRnb0RzZy5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKFtiaXRnb01zZzEsIHVzZXJNc2cxXSk7XG4gICAgY29uc3QgYml0Z29TaWduZWRNc2cyID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYml0Z29Nc2cyLnBheWxvYWQpLCBiaXRnb0dwZ1ByaXZLZXkpO1xuICAgIGNvbnN0IGJpdGdvRGVzZXJpYWxpemVkTXNnMiA9IGF3YWl0IHZlcmlmeVBlZXJNZXNzYWdlUm91bmRUd28oXG4gICAgICB7IHR5cGU6ICdyb3VuZDJPdXRwdXQnLCBkYXRhOiB7IG1zZzI6IGJpdGdvU2lnbmVkTXNnMiB9IH0sXG4gICAgICBiaXRnb0dwZ1B1YktleVxuICAgICk7XG4gICAgY29uc3QgW3VzZXJNc2czXSA9IHVzZXJEc2cuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhbdXNlck1zZzIsIGJpdGdvRGVzZXJpYWxpemVkTXNnMl0pO1xuXG4gICAgY29uc3Qgc2hhcmU6IFNpZ25hdHVyZVNoYXJlUmVjb3JkID0gYXdhaXQgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFRocmVlKHVzZXJNc2czLCB1c2VyR3BnUHJpdktleSk7XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2hhcmUuZnJvbSwgU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaGFyZS50bywgU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPKTtcblxuICAgIGNvbnN0IHBhcnNlZCA9IGRlY29kZVdpdGhDb2RlYyhcbiAgICAgIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kM0lucHV0LFxuICAgICAgSlNPTi5wYXJzZShzaGFyZS5zaGFyZSksXG4gICAgICAnRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQzSW5wdXQnXG4gICAgKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFyc2VkLnR5cGUsICdyb3VuZDNJbnB1dCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWQuZGF0YS5tc2czLm1lc3NhZ2UsICdtc2czLm1lc3NhZ2Ugc2hvdWxkIGJlIHNldCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWQuZGF0YS5tc2czLnNpZ25hdHVyZSwgJ21zZzMuc2lnbmF0dXJlIHNob3VsZCBiZSBzZXQnKTtcbiAgfSk7XG5cbiAgaXQoJ2dldFNpZ25hdHVyZVNoYXJlUm91bmRUaHJlZSBzaG91bGQgYnVpbGQgYSB2YWxpZCBiYWNrdXAgcm91bmQtMyBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCBiYWNrdXBEc2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQkFDS1VQKTtcbiAgICBhd2FpdCBiYWNrdXBEc2cuaW5pdERzZyhiYWNrdXBLZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGNvbnN0IGJhY2t1cE1zZzEgPSBiYWNrdXBEc2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG5cbiAgICBjb25zdCBiaXRnb0RzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYXdhaXQgYml0Z29Ec2cuaW5pdERzZyhiaXRnb0tleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVApO1xuICAgIGNvbnN0IGJpdGdvTXNnMSA9IGJpdGdvRHNnLmdldEZpcnN0TWVzc2FnZSgpO1xuXG4gICAgY29uc3QgYml0Z29TaWduZWRNc2cxID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYml0Z29Nc2cxLnBheWxvYWQpLCBiaXRnb0dwZ1ByaXZLZXkpO1xuICAgIGNvbnN0IGJpdGdvRGVzZXJpYWxpemVkTXNnMSA9IGF3YWl0IHZlcmlmeVBlZXJNZXNzYWdlUm91bmRPbmUoXG4gICAgICB7IHR5cGU6ICdyb3VuZDFPdXRwdXQnLCBkYXRhOiB7IG1zZzE6IGJpdGdvU2lnbmVkTXNnMSB9IH0sXG4gICAgICBiaXRnb0dwZ1B1YktleVxuICAgICk7XG4gICAgY29uc3QgW2JhY2t1cE1zZzJdID0gYmFja3VwRHNnLmhhbmRsZUluY29taW5nTWVzc2FnZXMoW2JhY2t1cE1zZzEsIGJpdGdvRGVzZXJpYWxpemVkTXNnMV0pO1xuXG4gICAgY29uc3QgW2JpdGdvTXNnMl0gPSBiaXRnb0RzZy5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKFtiaXRnb01zZzEsIGJhY2t1cE1zZzFdKTtcbiAgICBjb25zdCBiaXRnb1NpZ25lZE1zZzIgPSBhd2FpdCBNUFNDb21tcy5kZXRhY2hTaWduTXBzTWVzc2FnZShCdWZmZXIuZnJvbShiaXRnb01zZzIucGF5bG9hZCksIGJpdGdvR3BnUHJpdktleSk7XG4gICAgY29uc3QgYml0Z29EZXNlcmlhbGl6ZWRNc2cyID0gYXdhaXQgdmVyaWZ5UGVlck1lc3NhZ2VSb3VuZFR3byhcbiAgICAgIHsgdHlwZTogJ3JvdW5kMk91dHB1dCcsIGRhdGE6IHsgbXNnMjogYml0Z29TaWduZWRNc2cyIH0gfSxcbiAgICAgIGJpdGdvR3BnUHViS2V5XG4gICAgKTtcbiAgICBjb25zdCBbYmFja3VwTXNnM10gPSBiYWNrdXBEc2cuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhbYmFja3VwTXNnMiwgYml0Z29EZXNlcmlhbGl6ZWRNc2cyXSk7XG5cbiAgICBjb25zdCBzaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSBhd2FpdCBnZXRTaWduYXR1cmVTaGFyZVJvdW5kVGhyZWUoXG4gICAgICBiYWNrdXBNc2czLFxuICAgICAgYmFja3VwR3BnUHJpdktleSxcbiAgICAgIE1QQ3YyUGFydGllc0VudW0uQkFDS1VQXG4gICAgKTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaGFyZS5mcm9tLCBTaWduYXR1cmVTaGFyZVR5cGUuQkFDS1VQKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2hhcmUudG8sIFNpZ25hdHVyZVNoYXJlVHlwZS5CSVRHTyk7XG5cbiAgICBjb25zdCBwYXJzZWQgPSBkZWNvZGVXaXRoQ29kZWMoXG4gICAgICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDNJbnB1dCxcbiAgICAgIEpTT04ucGFyc2Uoc2hhcmUuc2hhcmUpLFxuICAgICAgJ0VkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kM0lucHV0J1xuICAgICk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBhcnNlZC50eXBlLCAncm91bmQzSW5wdXQnKTtcbiAgICBhc3NlcnQub2socGFyc2VkLmRhdGEubXNnMy5tZXNzYWdlLCAnbXNnMy5tZXNzYWdlIHNob3VsZCBiZSBzZXQnKTtcbiAgICBhc3NlcnQub2socGFyc2VkLmRhdGEubXNnMy5zaWduYXR1cmUsICdtc2czLnNpZ25hdHVyZSBzaG91bGQgYmUgc2V0Jyk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdnZXRFZGRzYU1QQ3YyUmVjb3ZlcnlLZXlTaGFyZXMnLCAoKSA9PiB7XG4gIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAndGVzdFBhc3MnO1xuXG4gIGNvbnN0IGVuY3J5cHRLZXkgPSAoa2V5U2hhcmU6IEJ1ZmZlcik6IHN0cmluZyA9PiBzamNsLmVuY3J5cHQod2FsbGV0UGFzc3BocmFzZSwga2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpKTtcblxuICBpdCgnc2hvdWxkIHJldHVybiByZWNvdmVyeSBrZXkgc2hhcmVzIGZyb20gdjEtZW5jcnlwdGVkIHJlZHVjZWQga2V5cyAobm8gYml0Z28gaW5zdGFuY2UpJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IFt1c2VyRGtnLCBiYWNrdXBEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgRUREU0FVdGlscy5nZXRFZGRzYU1wY1YyUmVjb3ZlcnlLZXlTaGFyZXNGcm9tUmVkdWNlZEtleShcbiAgICAgIGVuY3J5cHRLZXkodXNlckRrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKSksXG4gICAgICBlbmNyeXB0S2V5KGJhY2t1cERrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKSksXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlXG4gICAgKTtcblxuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwocmVzdWx0LnVzZXJLZXlTaGFyZSwgdXNlckRrZy5nZXRLZXlTaGFyZSgpKTtcbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHJlc3VsdC5iYWNrdXBLZXlTaGFyZSwgYmFja3VwRGtnLmdldEtleVNoYXJlKCkpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuY29tbW9uS2V5Q2hhaW4sIHVzZXJEa2cuZ2V0Q29tbW9uS2V5Y2hhaW4oKSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcm91dGUgZGVjcnlwdGlvbiB0aHJvdWdoIGJpdGdvLmRlY3J5cHQgd2hlbiBhIGJpdGdvIGluc3RhbmNlIGlzIHByb3ZpZGVkJywgYXN5bmMgKCkgPT4ge1xuICAgIC8vIHNkay1jb3JlIGhhcyBubyBkZXZEZXBlbmRlbmN5IG9uIHNkay1hcGkgb3IgYXJnb24yLCBzbyB3ZSBjYW5ub3QgZW5jcnlwdCB3aXRoIGEgcmVhbCB2MiBlbnZlbG9wZSBoZXJlLlxuICAgIC8vIFRoZSBzdHViIHZlcmlmaWVzIHRoYXQgdGhlIGZ1bmN0aW9uIGRlbGVnYXRlcyB0byBiaXRnby5kZWNyeXB0ICh3aGljaCBzdXBwb3J0cyB2MSArIHYyIGluXG4gICAgLy8gcHJvZHVjdGlvbikgcmF0aGVyIHRoYW4gZmFsbGluZyBiYWNrIHRvIHNqY2wuZGVjcnlwdC5cbiAgICBjb25zdCBbdXNlckRrZywgYmFja3VwRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIGNvbnN0IHVzZXJLZXlCYXNlNjQgPSB1c2VyRGtnLmdldFJlZHVjZWRLZXlTaGFyZSgpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICBjb25zdCBiYWNrdXBLZXlCYXNlNjQgPSBiYWNrdXBEa2cuZ2V0UmVkdWNlZEtleVNoYXJlKCkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuXG4gICAgY29uc3QgbW9ja0JpdGdvID0ge1xuICAgICAgZGVjcnlwdDogc2lub24uc3R1YigpLm9uRmlyc3RDYWxsKCkucmVzb2x2ZXModXNlcktleUJhc2U2NCkub25TZWNvbmRDYWxsKCkucmVzb2x2ZXMoYmFja3VwS2V5QmFzZTY0KSxcbiAgICB9IGFzIHVua25vd24gYXMgQml0R29CYXNlO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgRUREU0FVdGlscy5nZXRFZGRzYU1wY1YyUmVjb3ZlcnlLZXlTaGFyZXNGcm9tUmVkdWNlZEtleShcbiAgICAgICdlbmNyeXB0ZWQtdXNlci1rZXknLFxuICAgICAgJ2VuY3J5cHRlZC1iYWNrdXAta2V5JyxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBtb2NrQml0Z29cbiAgICApO1xuXG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZFR3aWNlKG1vY2tCaXRnby5kZWNyeXB0IGFzIHNpbm9uLlNpbm9uU3R1Yik7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChyZXN1bHQudXNlcktleVNoYXJlLCB1c2VyRGtnLmdldEtleVNoYXJlKCkpO1xuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwocmVzdWx0LmJhY2t1cEtleVNoYXJlLCBiYWNrdXBEa2cuZ2V0S2V5U2hhcmUoKSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5jb21tb25LZXlDaGFpbiwgdXNlckRrZy5nZXRDb21tb25LZXljaGFpbigpKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWplY3QgYSBtYWxmb3JtZWQga2V5Y2FyZCB3aXRoIGEgZGVzY3JpcHRpdmUgZXJyb3InLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgW3VzZXJEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgY29uc3QgbWFsZm9ybWVkS2V5ID0gc2pjbC5lbmNyeXB0KHdhbGxldFBhc3NwaHJhc2UsIHJhbmRvbUJ5dGVzKDY0KS50b1N0cmluZygnYmFzZTY0JykpO1xuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgRUREU0FVdGlscy5nZXRFZGRzYU1wY1YyUmVjb3ZlcnlLZXlTaGFyZXNGcm9tUmVkdWNlZEtleShcbiAgICAgICAgbWFsZm9ybWVkS2V5LFxuICAgICAgICBlbmNyeXB0S2V5KHVzZXJEa2cuZ2V0UmVkdWNlZEtleVNoYXJlKCkpLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlXG4gICAgICApLFxuICAgICAgL3VuYWJsZSB0byBkZWNvZGUgcmVkdWNlZCBrZXkgc2hhcmUvXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWplY3QgcmVkdWNlZCBrZXlzIGZyb20gZGlmZmVyZW50IHdhbGxldHMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgW3VzZXJEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgY29uc3QgWywgYmFja3VwRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgRUREU0FVdGlscy5nZXRFZGRzYU1wY1YyUmVjb3ZlcnlLZXlTaGFyZXNGcm9tUmVkdWNlZEtleShcbiAgICAgICAgZW5jcnlwdEtleSh1c2VyRGtnLmdldFJlZHVjZWRLZXlTaGFyZSgpKSxcbiAgICAgICAgZW5jcnlwdEtleShiYWNrdXBEa2cuZ2V0UmVkdWNlZEtleVNoYXJlKCkpLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlXG4gICAgICApLFxuICAgICAgL3B1YiBrZXlzIGRvIG5vdCBtYXRjaC9cbiAgICApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJlamVjdCByZWR1Y2VkIGtleXMgd2l0aCBtYXRjaGluZyBwdWIgYnV0IG1pc21hdGNoZWQgcm9vdENoYWluQ29kZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgW3VzZXJEa2csIGJhY2t1cERrZ10gPSBhd2FpdCBNUFNVdGlsLmdlbmVyYXRlRWREc2FES0dLZXlTaGFyZXMoKTtcbiAgICBjb25zdCB1c2VyUmVkdWNlZEtleVNoYXJlID0gdXNlckRrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKTtcbiAgICBjb25zdCBiYWNrdXBSZWR1Y2VkS2V5U2hhcmUgPSBiYWNrdXBEa2cuZ2V0UmVkdWNlZEtleVNoYXJlKCk7XG4gICAgY29uc3QgZ2V0RGVjb2RlZFJlZHVjZWRLZXlTaGFyZSA9IE1QU1R5cGVzLmdldERlY29kZWRSZWR1Y2VkS2V5U2hhcmU7XG4gICAgY29uc3QgZGVjb2RlU3R1YiA9IHNpbm9uLnN0dWIoTVBTVHlwZXMsICdnZXREZWNvZGVkUmVkdWNlZEtleVNoYXJlJykuY2FsbHNGYWtlKChidWYpID0+IHtcbiAgICAgIGNvbnN0IHJlZHVjZWQgPSBnZXREZWNvZGVkUmVkdWNlZEtleVNoYXJlKGJ1Zik7XG4gICAgICBpZiAoQnVmZmVyLmZyb20oYnVmKS5lcXVhbHMoYmFja3VwUmVkdWNlZEtleVNoYXJlKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLnJlZHVjZWQsXG4gICAgICAgICAgcm9vdENoYWluQ29kZTogQXJyYXkuZnJvbShyYW5kb21CeXRlcygzMikpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlZHVjZWQ7XG4gICAgfSk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgIEVERFNBVXRpbHMuZ2V0RWRkc2FNcGNWMlJlY292ZXJ5S2V5U2hhcmVzRnJvbVJlZHVjZWRLZXkoXG4gICAgICAgICAgZW5jcnlwdEtleSh1c2VyUmVkdWNlZEtleVNoYXJlKSxcbiAgICAgICAgICBlbmNyeXB0S2V5KGJhY2t1cFJlZHVjZWRLZXlTaGFyZSksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZVxuICAgICAgICApLFxuICAgICAgICAvcm9vdENoYWluQ29kZXMgZG8gbm90IG1hdGNoL1xuICAgICAgKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgZGVjb2RlU3R1Yi5yZXN0b3JlKCk7XG4gICAgfVxuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnRWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZScsICgpID0+IHtcbiAgbGV0IGVkZHNhTVBDdjJVdGlsczogRWRkc2FNUEN2MlV0aWxzO1xuICBsZXQgbW9ja0JpdGdvOiBCaXRHb0Jhc2U7XG4gIGxldCB1c2VyS2V5U2hhcmU6IEJ1ZmZlcjtcblxuICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3Rlc3RQYXNzJztcbiAgY29uc3Qgc2lnbmFibGVIZXggPSAnZGVhZGJlZWYnO1xuICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9ICdtLzAvMCc7XG4gIGNvbnN0IGV4cGVjdGVkQWRhdGEgPSBgJHtzaWduYWJsZUhleH06JHtkZXJpdmF0aW9uUGF0aH1gO1xuICBjb25zdCB0eFJlcXVlc3Q6IFR4UmVxdWVzdCA9IHtcbiAgICB0eFJlcXVlc3RJZDogJ3R4cmVxLWVkZHNhLXJvdW5kMScsXG4gICAgd2FsbGV0SWQ6ICd3YWxsZXQtZWRkc2Etcm91bmQxJyxcbiAgICBlbnRlcnByaXNlSWQ6ICdlbnRlcnByaXNlLWVkZHNhLXJvdW5kMScsXG4gICAgYXBpVmVyc2lvbjogJ2Z1bGwnLFxuICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAge1xuICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgc2lnbmFibGVIZXgsXG4gICAgICAgICAgZGVyaXZhdGlvblBhdGgsXG4gICAgICAgICAgc2VyaWFsaXplZFR4SGV4OiBzaWduYWJsZUhleCxcbiAgICAgICAgfSxcbiAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXSxcbiAgICAgIH0sXG4gICAgXSxcbiAgICBpbnRlbnQ6IHsgaW50ZW50VHlwZTogJ3BheW1lbnQnIH0sXG4gICAgdW5zaWduZWRUeHM6IFtdLFxuICB9IGFzIHVua25vd24gYXMgVHhSZXF1ZXN0O1xuXG4gIGJlZm9yZSgnZ2VuZXJhdGUgRWREU0EgdXNlciBrZXkgc2hhcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgW3VzZXJEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgdXNlcktleVNoYXJlID0gdXNlckRrZy5nZXRLZXlTaGFyZSgpO1xuICB9KTtcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBjb25zdCBzamNsRW5jcnlwdCA9IChwYXJhbXM6IHsgcGFzc3dvcmQ6IHN0cmluZzsgaW5wdXQ6IHN0cmluZzsgYWRhdGE/OiBzdHJpbmcgfSkgPT4ge1xuICAgICAgY29uc3Qgc2FsdCA9IHJhbmRvbUJ5dGVzKDgpO1xuICAgICAgY29uc3QgaXYgPSByYW5kb21CeXRlcygxNik7XG4gICAgICByZXR1cm4gc2pjbC5lbmNyeXB0KHBhcmFtcy5wYXNzd29yZCwgcGFyYW1zLmlucHV0LCB7XG4gICAgICAgIHNhbHQ6IFtieXRlc1RvV29yZChzYWx0LnN1YmFycmF5KDAsIDQpKSwgYnl0ZXNUb1dvcmQoc2FsdC5zdWJhcnJheSg0KSldLFxuICAgICAgICBpdjogW1xuICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDAsIDQpKSxcbiAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSg0LCA4KSksXG4gICAgICAgICAgYnl0ZXNUb1dvcmQoaXYuc3ViYXJyYXkoOCwgMTIpKSxcbiAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSgxMiwgMTYpKSxcbiAgICAgICAgXSxcbiAgICAgICAgYWRhdGE6IHBhcmFtcy5hZGF0YSxcbiAgICAgIH0pO1xuICAgIH07XG4gICAgbW9ja0JpdGdvID0ge1xuICAgICAgZW5jcnlwdDogc2lub24uc3R1YigpLmNhbGxzRmFrZShhc3luYyAocGFyYW1zKSA9PiBzamNsRW5jcnlwdChwYXJhbXMpKSxcbiAgICB9IGFzIHVua25vd24gYXMgQml0R29CYXNlO1xuXG4gICAgY29uc3QgbW9ja0NvaW4gPSB7XG4gICAgICBnZXRNUENBbGdvcml0aG06IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCdlZGRzYScpLFxuICAgIH0gYXMgdW5rbm93biBhcyBJQmFzZUNvaW47XG5cbiAgICBlZGRzYU1QQ3YyVXRpbHMgPSBuZXcgRWRkc2FNUEN2MlV0aWxzKG1vY2tCaXRnbywgbW9ja0NvaW4pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGNyZWF0ZSBhIHJvdW5kLTEgc2hhcmUgYW5kIGVuY3J5cHRlZCBTSkNMIHNlc3Npb24gcGF5bG9hZCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHtcbiAgICAgIHR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgfSk7XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LnNpZ25hdHVyZVNoYXJlUm91bmQxLmZyb20sIFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LnNpZ25hdHVyZVNoYXJlUm91bmQxLnRvLCBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08pO1xuICAgIGFzc2VydC5vayhyZXN1bHQudXNlckdwZ1B1YktleS5pbmNsdWRlcygnQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0snKSk7XG4gICAgYXNzZXJ0Lm9rKEpTT04ucGFyc2UocmVzdWx0LmVuY3J5cHRlZFJvdW5kMVNlc3Npb24pLmN0LCAnZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiBzaG91bGQgYmUgYW4gU0pDTCBKU09OIGJsb2InKTtcbiAgICBhc3NlcnQub2soSlNPTi5wYXJzZShyZXN1bHQuZW5jcnlwdGVkVXNlckdwZ1BydktleSkuY3QsICdlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5IHNob3VsZCBiZSBhbiBTSkNMIEpTT04gYmxvYicpO1xuXG4gICAgY29uc3QgcGFyc2VkU2hhcmUgPSBkZWNvZGVXaXRoQ29kZWMoXG4gICAgICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFJbnB1dCxcbiAgICAgIEpTT04ucGFyc2UocmVzdWx0LnNpZ25hdHVyZVNoYXJlUm91bmQxLnNoYXJlKSxcbiAgICAgICdFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFJbnB1dCdcbiAgICApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChwYXJzZWRTaGFyZS50eXBlLCAncm91bmQxSW5wdXQnKTtcbiAgICBhc3NlcnQub2socGFyc2VkU2hhcmUuZGF0YS5tc2cxLm1lc3NhZ2UsICdtc2cxLm1lc3NhZ2Ugc2hvdWxkIGJlIHNldCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWRTaGFyZS5kYXRhLm1zZzEuc2lnbmF0dXJlLCAnbXNnMS5zaWduYXR1cmUgc2hvdWxkIGJlIHNldCcpO1xuXG4gICAgY29uc3QgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiA9IEpTT04ucGFyc2UocmVzdWx0LmVuY3J5cHRlZFJvdW5kMVNlc3Npb24pO1xuICAgIGNvbnN0IGVuY3J5cHRlZFVzZXJHcGdQcnZLZXkgPSBKU09OLnBhcnNlKHJlc3VsdC5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5KTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICBkZWNvZGVVUklDb21wb25lbnQoZW5jcnlwdGVkUm91bmQxU2Vzc2lvbi5hZGF0YSksXG4gICAgICBgTVBTX0RTR19TSUdOSU5HX1JPVU5EMV9TVEFURToke2V4cGVjdGVkQWRhdGF9YCxcbiAgICAgICdyb3VuZC0xIHNlc3Npb24gYWRhdGEgc2hvdWxkIGJpbmQgdGhlIHNpZ25pbmcgY29udGV4dCdcbiAgICApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgIGRlY29kZVVSSUNvbXBvbmVudChlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LmFkYXRhKSxcbiAgICAgIGBNUFNfRFNHX1NJR05JTkdfVVNFUl9HUEdfS0VZOiR7ZXhwZWN0ZWRBZGF0YX1gLFxuICAgICAgJ0dQRyBwcml2YXRlIGtleSBhZGF0YSBzaG91bGQgYmluZCB0aGUgc2lnbmluZyBjb250ZXh0J1xuICAgICk7XG5cbiAgICBjb25zdCBzZXNzaW9uUGF5bG9hZCA9IEpTT04ucGFyc2Uoc2pjbC5kZWNyeXB0KHdhbGxldFBhc3NwaHJhc2UsIHJlc3VsdC5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uKSk7XG4gICAgYXNzZXJ0Lm9rKHNlc3Npb25QYXlsb2FkLmRzZ1Nlc3Npb24sICdkc2dTZXNzaW9uIHNob3VsZCBiZSBwZXJzaXN0ZWQgZm9yIHJvdW5kIDInKTtcbiAgICBhc3NlcnQub2soc2Vzc2lvblBheWxvYWQudXNlck1zZ1BheWxvYWQsICd1c2VyTXNnUGF5bG9hZCBzaG91bGQgYmUgcGVyc2lzdGVkIGZvciByb3VuZCAyJyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgdXNlIHYyIGVuY3J5cHRpb24gd2hlbiBlbmNyeXB0ZWRQcnYgaXMgYSB2MiBlbnZlbG9wZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBlbmNyeXB0ID0gc2lub25cbiAgICAgIC5zdHViKClcbiAgICAgIC5jYWxsc0Zha2UoKGlucHV0OiBzdHJpbmcsIGFkYXRhOiBzdHJpbmcpID0+IFByb21pc2UucmVzb2x2ZShKU09OLnN0cmluZ2lmeSh7IHY6IDIsIGlucHV0LCBhZGF0YSB9KSkpO1xuICAgIGNvbnN0IGRlc3Ryb3kgPSBzaW5vbi5zdHViKCk7XG4gICAgY29uc3QgY3JlYXRlRW5jcnlwdGlvblNlc3Npb24gPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBlbmNyeXB0LCBkZXN0cm95IH0pO1xuICAgIG1vY2tCaXRnby5jcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbiA9IGNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZSh7XG4gICAgICB0eFJlcXVlc3QsXG4gICAgICBwcnY6IHVzZXJLZXlTaGFyZS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgZW5jcnlwdGVkUHJ2OiBKU09OLnN0cmluZ2lmeSh7IHY6IDIgfSksXG4gICAgfSk7XG5cbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShjcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uLmdldENhbGwoMCkuYXJnc1swXSwgd2FsbGV0UGFzc3BocmFzZSk7XG4gICAgc2lub24uYXNzZXJ0Lm5vdENhbGxlZChtb2NrQml0Z28uZW5jcnlwdCBhcyBzaW5vbi5TaW5vblN0dWIpO1xuICAgIHNpbm9uLmFzc2VydC5jYWxsZWRUd2ljZShlbmNyeXB0KTtcbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShkZXN0cm95KTtcblxuICAgIGNvbnN0IGVuY3J5cHRlZFJvdW5kMVNlc3Npb24gPSBKU09OLnBhcnNlKHJlc3VsdC5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uKTtcbiAgICBjb25zdCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5ID0gSlNPTi5wYXJzZShyZXN1bHQuZW5jcnlwdGVkVXNlckdwZ1BydktleSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGVuY3J5cHRlZFJvdW5kMVNlc3Npb24udiwgMik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGVuY3J5cHRlZFJvdW5kMVNlc3Npb24uYWRhdGEsIGBNUFNfRFNHX1NJR05JTkdfUk9VTkQxX1NUQVRFOiR7ZXhwZWN0ZWRBZGF0YX1gKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZW5jcnlwdGVkVXNlckdwZ1BydktleS52LCAyKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZW5jcnlwdGVkVXNlckdwZ1BydktleS5hZGF0YSwgYE1QU19EU0dfU0lHTklOR19VU0VSX0dQR19LRVk6JHtleHBlY3RlZEFkYXRhfWApO1xuXG4gICAgY29uc3Qgc2Vzc2lvblBheWxvYWQgPSBKU09OLnBhcnNlKGVuY3J5cHRlZFJvdW5kMVNlc3Npb24uaW5wdXQpO1xuICAgIGFzc2VydC5vayhzZXNzaW9uUGF5bG9hZC5kc2dTZXNzaW9uLCAnZHNnU2Vzc2lvbiBzaG91bGQgYmUgcGVyc2lzdGVkIGZvciByb3VuZCAyJyk7XG4gICAgYXNzZXJ0Lm9rKHNlc3Npb25QYXlsb2FkLnVzZXJNc2dQYXlsb2FkLCAndXNlck1zZ1BheWxvYWQgc2hvdWxkIGJlIHBlcnNpc3RlZCBmb3Igcm91bmQgMicpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHVzZSBTSkNMIGVuY3J5cHRpb24gd2hlbiBlbmNyeXB0ZWRQcnYgaXMgYSB2MSBibG9iJywgYXN5bmMgKCkgPT4ge1xuICAgIG1vY2tCaXRnby5jcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbiA9IHNpbm9uLnN0dWIoKTtcbiAgICBjb25zdCBlbmNyeXB0ZWRQcnYgPSBzamNsLmVuY3J5cHQod2FsbGV0UGFzc3BocmFzZSwgdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHtcbiAgICAgIHR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBlbmNyeXB0ZWRQcnYsXG4gICAgfSk7XG5cbiAgICBzaW5vbi5hc3NlcnQubm90Q2FsbGVkKG1vY2tCaXRnby5jcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbiBhcyBzaW5vbi5TaW5vblN0dWIpO1xuICAgIHNpbm9uLmFzc2VydC5jYWxsZWRUd2ljZShtb2NrQml0Z28uZW5jcnlwdCBhcyBzaW5vbi5TaW5vblN0dWIpO1xuICAgIGFzc2VydC5vayhKU09OLnBhcnNlKHJlc3VsdC5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uKS5jdCwgJ2VuY3J5cHRlZFJvdW5kMVNlc3Npb24gc2hvdWxkIGJlIGFuIFNKQ0wgSlNPTiBibG9iJyk7XG4gICAgYXNzZXJ0Lm9rKEpTT04ucGFyc2UocmVzdWx0LmVuY3J5cHRlZFVzZXJHcGdQcnZLZXkpLmN0LCAnZW5jcnlwdGVkVXNlckdwZ1BydktleSBzaG91bGQgYmUgYW4gU0pDTCBKU09OIGJsb2InKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBwcm9wYWdhdGUgdGhlIHR4LW9ubHkgZ3VhcmQgd2hlbiB0cmFuc2FjdGlvbnMgYXJlIG1pc3NpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PlxuICAgICAgICBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHtcbiAgICAgICAgICB0eFJlcXVlc3Q6IHsgLi4udHhSZXF1ZXN0LCB0cmFuc2FjdGlvbnM6IHVuZGVmaW5lZCB9IGFzIHVua25vd24gYXMgVHhSZXF1ZXN0LFxuICAgICAgICAgIHBydjogdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KSxcbiAgICAgIC9VbmFibGUgdG8gZmluZCB0cmFuc2FjdGlvbnMgaW4gdHhSZXF1ZXN0L1xuICAgICk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdFZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMlNoYXJlJywgKCkgPT4ge1xuICBsZXQgZWRkc2FNUEN2MlV0aWxzOiBFZGRzYU1QQ3YyVXRpbHM7XG4gIGxldCBtb2NrQml0Z286IEJpdEdvQmFzZTtcbiAgbGV0IHVzZXJLZXlTaGFyZTogQnVmZmVyO1xuICBsZXQgYml0Z29LZXlTaGFyZTogQnVmZmVyO1xuICBsZXQgYml0Z29HcGdLZXlQYWlyOiBwZ3AuU2VyaWFsaXplZEtleVBhaXI8c3RyaW5nPjtcbiAgbGV0IGJpdGdvR3BnUHJpdktleTogcGdwLlByaXZhdGVLZXk7XG5cbiAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICd0ZXN0UGFzcyc7XG4gIGNvbnN0IHNpZ25hYmxlSGV4ID0gJ2RlYWRiZWVmJztcbiAgY29uc3QgZGVyaXZhdGlvblBhdGggPSAnbS8wLzAnO1xuICBjb25zdCBleHBlY3RlZEFkYXRhID0gYCR7c2lnbmFibGVIZXh9OiR7ZGVyaXZhdGlvblBhdGh9YDtcblxuICBjb25zdCBiYXNlVHhSZXF1ZXN0OiBUeFJlcXVlc3QgPSB7XG4gICAgdHhSZXF1ZXN0SWQ6ICd0eHJlcS1lZGRzYS1yb3VuZDInLFxuICAgIHdhbGxldElkOiAnd2FsbGV0LWVkZHNhLXJvdW5kMicsXG4gICAgZW50ZXJwcmlzZUlkOiAnZW50ZXJwcmlzZS1lZGRzYS1yb3VuZDInLFxuICAgIGFwaVZlcnNpb246ICdmdWxsJyxcbiAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgIHtcbiAgICAgICAgdW5zaWduZWRUeDoge1xuICAgICAgICAgIHNpZ25hYmxlSGV4LFxuICAgICAgICAgIGRlcml2YXRpb25QYXRoLFxuICAgICAgICAgIHNlcmlhbGl6ZWRUeEhleDogc2lnbmFibGVIZXgsXG4gICAgICAgIH0sXG4gICAgICAgIHNpZ25hdHVyZVNoYXJlczogW10sXG4gICAgICB9LFxuICAgIF0sXG4gICAgaW50ZW50OiB7IGludGVudFR5cGU6ICdwYXltZW50JyB9LFxuICAgIHVuc2lnbmVkVHhzOiBbXSxcbiAgfSBhcyB1bmtub3duIGFzIFR4UmVxdWVzdDtcblxuICBiZWZvcmUoJ2dlbmVyYXRlIEVkRFNBIGtleSBzaGFyZXMgYW5kIEdQRyBrZXlzJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IFt1c2VyRGtnLCAsIGJpdGdvRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIHVzZXJLZXlTaGFyZSA9IHVzZXJEa2cuZ2V0S2V5U2hhcmUoKTtcbiAgICBiaXRnb0tleVNoYXJlID0gYml0Z29Ea2cuZ2V0S2V5U2hhcmUoKTtcblxuICAgIGJpdGdvR3BnS2V5UGFpciA9IGF3YWl0IGdlbmVyYXRlR1BHS2V5UGFpcignZWQyNTUxOScpO1xuICAgIGJpdGdvR3BnUHJpdktleSA9IGF3YWl0IHBncC5yZWFkUHJpdmF0ZUtleSh7IGFybW9yZWRLZXk6IGJpdGdvR3BnS2V5UGFpci5wcml2YXRlS2V5IH0pO1xuICB9KTtcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBtb2NrQml0Z28gPSB7XG4gICAgICBlbmNyeXB0OiBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKGFzeW5jIChwYXJhbXMpID0+IHtcbiAgICAgICAgY29uc3Qgc2FsdCA9IHJhbmRvbUJ5dGVzKDgpO1xuICAgICAgICBjb25zdCBpdiA9IHJhbmRvbUJ5dGVzKDE2KTtcbiAgICAgICAgcmV0dXJuIHNqY2wuZW5jcnlwdChwYXJhbXMucGFzc3dvcmQsIHBhcmFtcy5pbnB1dCwge1xuICAgICAgICAgIHNhbHQ6IFtieXRlc1RvV29yZChzYWx0LnN1YmFycmF5KDAsIDQpKSwgYnl0ZXNUb1dvcmQoc2FsdC5zdWJhcnJheSg0KSldLFxuICAgICAgICAgIGl2OiBbXG4gICAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSgwLCA0KSksXG4gICAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSg0LCA4KSksXG4gICAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSg4LCAxMikpLFxuICAgICAgICAgICAgYnl0ZXNUb1dvcmQoaXYuc3ViYXJyYXkoMTIsIDE2KSksXG4gICAgICAgICAgXSxcbiAgICAgICAgICBhZGF0YTogcGFyYW1zLmFkYXRhLFxuICAgICAgICB9KTtcbiAgICAgIH0pLFxuICAgICAgZGVjcnlwdDogc2lub24uc3R1YigpLmNhbGxzRmFrZShhc3luYyAocGFyYW1zKSA9PiBzamNsLmRlY3J5cHQocGFyYW1zLnBhc3N3b3JkLCBwYXJhbXMuaW5wdXQpKSxcbiAgICB9IGFzIHVua25vd24gYXMgQml0R29CYXNlO1xuXG4gICAgY29uc3QgbW9ja0NvaW4gPSB7XG4gICAgICBnZXRNUENBbGdvcml0aG06IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCdlZGRzYScpLFxuICAgIH0gYXMgdW5rbm93biBhcyBJQmFzZUNvaW47XG5cbiAgICBlZGRzYU1QQ3YyVXRpbHMgPSBuZXcgRWRkc2FNUEN2MlV0aWxzKG1vY2tCaXRnbywgbW9ja0NvaW4pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGNyZWF0ZSBhIHJvdW5kLTIgc2hhcmUgZnJvbSBvZmZsaW5lIHJvdW5kIDEnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qgcm91bmQxID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZSh7XG4gICAgICB0eFJlcXVlc3Q6IGJhc2VUeFJlcXVlc3QsXG4gICAgICBwcnY6IHVzZXJLZXlTaGFyZS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgbWVzc2FnZUJ1ZmZlciA9IEJ1ZmZlci5mcm9tKHNpZ25hYmxlSGV4LCAnaGV4Jyk7XG4gICAgY29uc3QgYml0Z29Ec2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGF3YWl0IGJpdGdvRHNnLmluaXREc2coYml0Z29LZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uVVNFUik7XG5cbiAgICBjb25zdCB0eFJlcXVlc3RSb3VuZDEgPSBhd2FpdCBzaWduQml0Z29FZGRzYVJvdW5kMShcbiAgICAgIGJpdGdvRHNnLFxuICAgICAgY2xvbmVUeFJlcXVlc3RXaXRoRW1wdHlTaWduYXR1cmVTaGFyZXMoYmFzZVR4UmVxdWVzdCksXG4gICAgICByb3VuZDEuc2lnbmF0dXJlU2hhcmVSb3VuZDEsXG4gICAgICByb3VuZDEudXNlckdwZ1B1YktleSxcbiAgICAgIGJpdGdvR3BnUHJpdktleVxuICAgICk7XG5cbiAgICBjb25zdCByb3VuZDIgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMlNoYXJlKHtcbiAgICAgIHR4UmVxdWVzdDogdHhSZXF1ZXN0Um91bmQxLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogcm91bmQxLmVuY3J5cHRlZFVzZXJHcGdQcnZLZXksXG4gICAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uOiByb3VuZDEuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbixcbiAgICB9KTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyb3VuZDIuc2lnbmF0dXJlU2hhcmVSb3VuZDIuZnJvbSwgU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyb3VuZDIuc2lnbmF0dXJlU2hhcmVSb3VuZDIudG8sIFNpZ25hdHVyZVNoYXJlVHlwZS5CSVRHTyk7XG5cbiAgICBjb25zdCBwYXJzZWRTaGFyZSA9IGRlY29kZVdpdGhDb2RlYyhcbiAgICAgIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMklucHV0LFxuICAgICAgSlNPTi5wYXJzZShyb3VuZDIuc2lnbmF0dXJlU2hhcmVSb3VuZDIuc2hhcmUpLFxuICAgICAgJ0VkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMklucHV0J1xuICAgICk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBhcnNlZFNoYXJlLnR5cGUsICdyb3VuZDJJbnB1dCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWRTaGFyZS5kYXRhLm1zZzIubWVzc2FnZSwgJ21zZzIubWVzc2FnZSBzaG91bGQgYmUgc2V0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZFNoYXJlLmRhdGEubXNnMi5zaWduYXR1cmUsICdtc2cyLnNpZ25hdHVyZSBzaG91bGQgYmUgc2V0Jyk7XG5cbiAgICBjb25zdCBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uID0gSlNPTi5wYXJzZShyb3VuZDIuZW5jcnlwdGVkUm91bmQyU2Vzc2lvbik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgICAgZGVjb2RlVVJJQ29tcG9uZW50KGVuY3J5cHRlZFJvdW5kMlNlc3Npb24uYWRhdGEpLFxuICAgICAgYE1QU19EU0dfU0lHTklOR19ST1VORDJfU1RBVEU6JHtleHBlY3RlZEFkYXRhfWBcbiAgICApO1xuXG4gICAgY29uc3Qgc2Vzc2lvblBheWxvYWQgPSBKU09OLnBhcnNlKHNqY2wuZGVjcnlwdCh3YWxsZXRQYXNzcGhyYXNlLCByb3VuZDIuZW5jcnlwdGVkUm91bmQyU2Vzc2lvbikpO1xuICAgIGFzc2VydC5vayhzZXNzaW9uUGF5bG9hZC5kc2dTZXNzaW9uLCAnZHNnU2Vzc2lvbiBzaG91bGQgYmUgcGVyc2lzdGVkIGZvciByb3VuZCAzJyk7XG4gICAgYXNzZXJ0Lm9rKHNlc3Npb25QYXlsb2FkLnVzZXJNc2dQYXlsb2FkLCAndXNlck1zZ1BheWxvYWQgc2hvdWxkIGJlIHBlcnNpc3RlZCBmb3Igcm91bmQgMycpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHVzZSB2MiBkZWNyeXB0aW9uIHdoZW4gZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiBpcyBhIHYyIGVudmVsb3BlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGVuY3J5cHQgPSBzaW5vblxuICAgICAgLnN0dWIoKVxuICAgICAgLmNhbGxzRmFrZSgoaW5wdXQ6IHN0cmluZywgYWRhdGE6IHN0cmluZykgPT4gUHJvbWlzZS5yZXNvbHZlKEpTT04uc3RyaW5naWZ5KHsgdjogMiwgaW5wdXQsIGFkYXRhIH0pKSk7XG4gICAgY29uc3QgZGVzdHJveSA9IHNpbm9uLnN0dWIoKTtcbiAgICBjb25zdCBjcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbiA9IHNpbm9uLnN0dWIoKS5yZXNvbHZlcyh7IGVuY3J5cHQsIGRlc3Ryb3kgfSk7XG4gICAgbW9ja0JpdGdvLmNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uID0gY3JlYXRlRW5jcnlwdGlvblNlc3Npb247XG5cbiAgICBjb25zdCByb3VuZDEgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHtcbiAgICAgIHR4UmVxdWVzdDogYmFzZVR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBlbmNyeXB0ZWRQcnY6IEpTT04uc3RyaW5naWZ5KHsgdjogMiB9KSxcbiAgICB9KTtcblxuICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbShzaWduYWJsZUhleCwgJ2hleCcpO1xuICAgIGNvbnN0IGJpdGdvRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhd2FpdCBiaXRnb0RzZy5pbml0RHNnKGJpdGdvS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuXG4gICAgY29uc3QgdHhSZXF1ZXN0Um91bmQxID0gYXdhaXQgc2lnbkJpdGdvRWRkc2FSb3VuZDEoXG4gICAgICBiaXRnb0RzZyxcbiAgICAgIGNsb25lVHhSZXF1ZXN0V2l0aEVtcHR5U2lnbmF0dXJlU2hhcmVzKGJhc2VUeFJlcXVlc3QpLFxuICAgICAgcm91bmQxLnNpZ25hdHVyZVNoYXJlUm91bmQxLFxuICAgICAgcm91bmQxLnVzZXJHcGdQdWJLZXksXG4gICAgICBiaXRnb0dwZ1ByaXZLZXlcbiAgICApO1xuXG4gICAgY29uc3QgZGVjcnlwdCA9IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoYXN5bmMgKHBhcmFtczogeyBpbnB1dDogc3RyaW5nIH0pID0+IHtcbiAgICAgIGNvbnN0IGVudmVsb3BlID0gSlNPTi5wYXJzZShwYXJhbXMuaW5wdXQpO1xuICAgICAgcmV0dXJuIGVudmVsb3BlLmlucHV0O1xuICAgIH0pO1xuICAgIG1vY2tCaXRnby5kZWNyeXB0ID0gZGVjcnlwdDtcblxuICAgIGNvbnN0IHJvdW5kMiA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQyU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3RSb3VuZDEsXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgYml0Z29QdWJsaWNHcGdLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDEuZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246IHJvdW5kMS5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLFxuICAgIH0pO1xuXG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZChtb2NrQml0Z28uZGVjcnlwdCBhcyBzaW5vbi5TaW5vblN0dWIpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyb3VuZDIuc2lnbmF0dXJlU2hhcmVSb3VuZDIuZnJvbSwgU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIpO1xuXG4gICAgY29uc3QgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbiA9IEpTT04ucGFyc2Uocm91bmQyLmVuY3J5cHRlZFJvdW5kMlNlc3Npb24pO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLnYsIDIpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLmFkYXRhLCBgTVBTX0RTR19TSUdOSU5HX1JPVU5EMl9TVEFURToke2V4cGVjdGVkQWRhdGF9YCk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmVqZWN0IHRhbXBlcmVkIGVuY3J5cHRlZFJvdW5kMVNlc3Npb24gYWRhdGEnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qgb3RoZXJUeFJlcXVlc3Q6IFR4UmVxdWVzdCA9IHtcbiAgICAgIC4uLmJhc2VUeFJlcXVlc3QsXG4gICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAge1xuICAgICAgICAgIHVuc2lnbmVkVHg6IHtcbiAgICAgICAgICAgIHNpZ25hYmxlSGV4OiAnY2FmZWJhYmUnLFxuICAgICAgICAgICAgZGVyaXZhdGlvblBhdGg6ICdtLzEvMicsXG4gICAgICAgICAgICBzZXJpYWxpemVkVHhIZXg6ICdjYWZlYmFiZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFtdLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9IGFzIHVua25vd24gYXMgVHhSZXF1ZXN0O1xuXG4gICAgY29uc3Qgcm91bmQxT3RoZXIgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHtcbiAgICAgIHR4UmVxdWVzdDogb3RoZXJUeFJlcXVlc3QsXG4gICAgICBwcnY6IHVzZXJLZXlTaGFyZS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgcm91bmQxID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZSh7XG4gICAgICB0eFJlcXVlc3Q6IGJhc2VUeFJlcXVlc3QsXG4gICAgICBwcnY6IHVzZXJLZXlTaGFyZS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgbWVzc2FnZUJ1ZmZlciA9IEJ1ZmZlci5mcm9tKHNpZ25hYmxlSGV4LCAnaGV4Jyk7XG4gICAgY29uc3QgYml0Z29Ec2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGF3YWl0IGJpdGdvRHNnLmluaXREc2coYml0Z29LZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uVVNFUik7XG5cbiAgICBjb25zdCB0eFJlcXVlc3RSb3VuZDEgPSBhd2FpdCBzaWduQml0Z29FZGRzYVJvdW5kMShcbiAgICAgIGJpdGdvRHNnLFxuICAgICAgY2xvbmVUeFJlcXVlc3RXaXRoRW1wdHlTaWduYXR1cmVTaGFyZXMoYmFzZVR4UmVxdWVzdCksXG4gICAgICByb3VuZDEuc2lnbmF0dXJlU2hhcmVSb3VuZDEsXG4gICAgICByb3VuZDEudXNlckdwZ1B1YktleSxcbiAgICAgIGJpdGdvR3BnUHJpdktleVxuICAgICk7XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+XG4gICAgICAgIGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQyU2hhcmUoe1xuICAgICAgICAgIHR4UmVxdWVzdDogdHhSZXF1ZXN0Um91bmQxLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgYml0Z29QdWJsaWNHcGdLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogcm91bmQxLmVuY3J5cHRlZFVzZXJHcGdQcnZLZXksXG4gICAgICAgICAgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbjogcm91bmQxT3RoZXIuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbixcbiAgICAgICAgfSksXG4gICAgICAvQWRhdGEgZG9lcyBub3QgbWF0Y2ggY3lwaGVydGV4dCBhZGF0YS9cbiAgICApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJlamVjdCB0YW1wZXJlZCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5IGFkYXRhJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG90aGVyVHhSZXF1ZXN0OiBUeFJlcXVlc3QgPSB7XG4gICAgICAuLi5iYXNlVHhSZXF1ZXN0LFxuICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgICBzaWduYWJsZUhleDogJ2NhZmViYWJlJyxcbiAgICAgICAgICAgIGRlcml2YXRpb25QYXRoOiAnbS8xLzInLFxuICAgICAgICAgICAgc2VyaWFsaXplZFR4SGV4OiAnY2FmZWJhYmUnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSBhcyB1bmtub3duIGFzIFR4UmVxdWVzdDtcblxuICAgIGNvbnN0IHJvdW5kMU90aGVyID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZSh7XG4gICAgICB0eFJlcXVlc3Q6IG90aGVyVHhSZXF1ZXN0LFxuICAgICAgcHJ2OiB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJvdW5kMSA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0OiBiYXNlVHhSZXF1ZXN0LFxuICAgICAgcHJ2OiB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbShzaWduYWJsZUhleCwgJ2hleCcpO1xuICAgIGNvbnN0IGJpdGdvRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhd2FpdCBiaXRnb0RzZy5pbml0RHNnKGJpdGdvS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuXG4gICAgY29uc3QgdHhSZXF1ZXN0Um91bmQxID0gYXdhaXQgc2lnbkJpdGdvRWRkc2FSb3VuZDEoXG4gICAgICBiaXRnb0RzZyxcbiAgICAgIGNsb25lVHhSZXF1ZXN0V2l0aEVtcHR5U2lnbmF0dXJlU2hhcmVzKGJhc2VUeFJlcXVlc3QpLFxuICAgICAgcm91bmQxLnNpZ25hdHVyZVNoYXJlUm91bmQxLFxuICAgICAgcm91bmQxLnVzZXJHcGdQdWJLZXksXG4gICAgICBiaXRnb0dwZ1ByaXZLZXlcbiAgICApO1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PlxuICAgICAgICBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMlNoYXJlKHtcbiAgICAgICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdFJvdW5kMSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHJvdW5kMU90aGVyLmVuY3J5cHRlZFVzZXJHcGdQcnZLZXksXG4gICAgICAgICAgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbjogcm91bmQxLmVuY3J5cHRlZFJvdW5kMVNlc3Npb24sXG4gICAgICAgIH0pLFxuICAgICAgL0FkYXRhIGRvZXMgbm90IG1hdGNoIGN5cGhlcnRleHQgYWRhdGEvXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWplY3Qgd2hlbiBCaXRHbyBzaWduYXR1cmUgc2hhcmUgaXMgbWlzc2luZycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByb3VuZDEgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHtcbiAgICAgIHR4UmVxdWVzdDogYmFzZVR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgfSk7XG5cbiAgICBjb25zdCBiYXNlVHJhbnNhY3Rpb24gPSBhc3NlcnRTaW5nbGVUcmFuc2FjdGlvbihiYXNlVHhSZXF1ZXN0KTtcbiAgICBjb25zdCB0eFJlcXVlc3ROb0JpdGdvU2hhcmU6IFR4UmVxdWVzdCA9IHtcbiAgICAgIC4uLmJhc2VUeFJlcXVlc3QsXG4gICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAge1xuICAgICAgICAgIC4uLmJhc2VUcmFuc2FjdGlvbixcbiAgICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFtyb3VuZDEuc2lnbmF0dXJlU2hhcmVSb3VuZDFdLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PlxuICAgICAgICBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMlNoYXJlKHtcbiAgICAgICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdE5vQml0Z29TaGFyZSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246IHJvdW5kMS5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLFxuICAgICAgICB9KSxcbiAgICAgIC9NaXNzaW5nIEJpdEdvIHJvdW5kMU91dHB1dCBzaWduYXR1cmUgc2hhcmUvXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBwcm9wYWdhdGUgdGhlIHR4LW9ubHkgZ3VhcmQgd2hlbiB0cmFuc2FjdGlvbnMgYXJlIG1pc3NpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qgcm91bmQxID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZSh7XG4gICAgICB0eFJlcXVlc3Q6IGJhc2VUeFJlcXVlc3QsXG4gICAgICBwcnY6IHVzZXJLZXlTaGFyZS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgIH0pO1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PlxuICAgICAgICBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMlNoYXJlKHtcbiAgICAgICAgICB0eFJlcXVlc3Q6IHsgLi4uYmFzZVR4UmVxdWVzdCwgdHJhbnNhY3Rpb25zOiB1bmRlZmluZWQgfSBhcyB1bmtub3duIGFzIFR4UmVxdWVzdCxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246IHJvdW5kMS5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLFxuICAgICAgICB9KSxcbiAgICAgIC9VbmFibGUgdG8gZmluZCB0cmFuc2FjdGlvbnMgaW4gdHhSZXF1ZXN0L1xuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmVqZWN0IHdoZW4gdHJhbnNhY3Rpb25zIGFycmF5IGlzIGVtcHR5JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJvdW5kMSA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0OiBiYXNlVHhSZXF1ZXN0LFxuICAgICAgcHJ2OiB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICB9KTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDJTaGFyZSh7XG4gICAgICAgICAgdHhSZXF1ZXN0OiB7IC4uLmJhc2VUeFJlcXVlc3QsIHRyYW5zYWN0aW9uczogW10gfSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246IHJvdW5kMS5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLFxuICAgICAgICB9KSxcbiAgICAgIC9VbmFibGUgdG8gZmluZCB0cmFuc2FjdGlvbnMgaW4gdHhSZXF1ZXN0L1xuICAgICk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdFZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kM1NoYXJlJywgKCkgPT4ge1xuICBsZXQgZWRkc2FNUEN2MlV0aWxzOiBFZGRzYU1QQ3YyVXRpbHM7XG4gIGxldCBtb2NrQml0Z286IEJpdEdvQmFzZTtcbiAgbGV0IHVzZXJLZXlTaGFyZTogQnVmZmVyO1xuICBsZXQgYml0Z29LZXlTaGFyZTogQnVmZmVyO1xuICBsZXQgYml0Z29HcGdLZXlQYWlyOiBwZ3AuU2VyaWFsaXplZEtleVBhaXI8c3RyaW5nPjtcbiAgbGV0IGJpdGdvR3BnUHJpdktleTogcGdwLlByaXZhdGVLZXk7XG5cbiAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICd0ZXN0UGFzcyc7XG4gIGNvbnN0IHNpZ25hYmxlSGV4ID0gJ2RlYWRiZWVmJztcbiAgY29uc3QgZGVyaXZhdGlvblBhdGggPSAnbS8wLzAnO1xuXG4gIGNvbnN0IGJhc2VUeFJlcXVlc3Q6IFR4UmVxdWVzdCA9IHtcbiAgICB0eFJlcXVlc3RJZDogJ3R4cmVxLWVkZHNhLXJvdW5kMycsXG4gICAgd2FsbGV0SWQ6ICd3YWxsZXQtZWRkc2Etcm91bmQzJyxcbiAgICBlbnRlcnByaXNlSWQ6ICdlbnRlcnByaXNlLWVkZHNhLXJvdW5kMycsXG4gICAgYXBpVmVyc2lvbjogJ2Z1bGwnLFxuICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAge1xuICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgc2lnbmFibGVIZXgsXG4gICAgICAgICAgZGVyaXZhdGlvblBhdGgsXG4gICAgICAgICAgc2VyaWFsaXplZFR4SGV4OiBzaWduYWJsZUhleCxcbiAgICAgICAgfSxcbiAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXSxcbiAgICAgIH0sXG4gICAgXSxcbiAgICBpbnRlbnQ6IHsgaW50ZW50VHlwZTogJ3BheW1lbnQnIH0sXG4gICAgdW5zaWduZWRUeHM6IFtdLFxuICB9IGFzIHVua25vd24gYXMgVHhSZXF1ZXN0O1xuXG4gIGJlZm9yZSgnZ2VuZXJhdGUgRWREU0Ega2V5IHNoYXJlcyBhbmQgR1BHIGtleXMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgW3VzZXJEa2csICwgYml0Z29Ea2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgdXNlcktleVNoYXJlID0gdXNlckRrZy5nZXRLZXlTaGFyZSgpO1xuICAgIGJpdGdvS2V5U2hhcmUgPSBiaXRnb0RrZy5nZXRLZXlTaGFyZSgpO1xuXG4gICAgYml0Z29HcGdLZXlQYWlyID0gYXdhaXQgZ2VuZXJhdGVHUEdLZXlQYWlyKCdlZDI1NTE5Jyk7XG4gICAgYml0Z29HcGdQcml2S2V5ID0gYXdhaXQgcGdwLnJlYWRQcml2YXRlS2V5KHsgYXJtb3JlZEtleTogYml0Z29HcGdLZXlQYWlyLnByaXZhdGVLZXkgfSk7XG4gIH0pO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIG1vY2tCaXRnbyA9IHtcbiAgICAgIGVuY3J5cHQ6IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoYXN5bmMgKHBhcmFtcykgPT4ge1xuICAgICAgICBjb25zdCBzYWx0ID0gcmFuZG9tQnl0ZXMoOCk7XG4gICAgICAgIGNvbnN0IGl2ID0gcmFuZG9tQnl0ZXMoMTYpO1xuICAgICAgICByZXR1cm4gc2pjbC5lbmNyeXB0KHBhcmFtcy5wYXNzd29yZCwgcGFyYW1zLmlucHV0LCB7XG4gICAgICAgICAgc2FsdDogW2J5dGVzVG9Xb3JkKHNhbHQuc3ViYXJyYXkoMCwgNCkpLCBieXRlc1RvV29yZChzYWx0LnN1YmFycmF5KDQpKV0sXG4gICAgICAgICAgaXY6IFtcbiAgICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDAsIDQpKSxcbiAgICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDQsIDgpKSxcbiAgICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDgsIDEyKSksXG4gICAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSgxMiwgMTYpKSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGFkYXRhOiBwYXJhbXMuYWRhdGEsXG4gICAgICAgIH0pO1xuICAgICAgfSksXG4gICAgICBkZWNyeXB0OiBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKGFzeW5jIChwYXJhbXMpID0+IHNqY2wuZGVjcnlwdChwYXJhbXMucGFzc3dvcmQsIHBhcmFtcy5pbnB1dCkpLFxuICAgIH0gYXMgdW5rbm93biBhcyBCaXRHb0Jhc2U7XG5cbiAgICBjb25zdCBtb2NrQ29pbiA9IHtcbiAgICAgIGdldE1QQ0FsZ29yaXRobTogc2lub24uc3R1YigpLnJldHVybnMoJ2VkZHNhJyksXG4gICAgfSBhcyB1bmtub3duIGFzIElCYXNlQ29pbjtcblxuICAgIGVkZHNhTVBDdjJVdGlscyA9IG5ldyBFZGRzYU1QQ3YyVXRpbHMobW9ja0JpdGdvLCBtb2NrQ29pbik7XG4gIH0pO1xuXG4gIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVJvdW5kMkZsb3coXG4gICAgdHhSZXF1ZXN0OiBUeFJlcXVlc3QsXG4gICAgZW5jcnlwdGVkUHJ2Pzogc3RyaW5nXG4gICk6IFByb21pc2U8e1xuICAgIHJvdW5kMToge1xuICAgICAgc2lnbmF0dXJlU2hhcmVSb3VuZDE6IFNpZ25hdHVyZVNoYXJlUmVjb3JkO1xuICAgICAgdXNlckdwZ1B1YktleTogc3RyaW5nO1xuICAgICAgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbjogc3RyaW5nO1xuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogc3RyaW5nO1xuICAgIH07XG4gICAgcm91bmQyOiB7XG4gICAgICBzaWduYXR1cmVTaGFyZVJvdW5kMjogU2lnbmF0dXJlU2hhcmVSZWNvcmQ7XG4gICAgICBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uOiBzdHJpbmc7XG4gICAgfTtcbiAgICB0eFJlcXVlc3RSb3VuZDE6IFR4UmVxdWVzdDtcbiAgICB0eFJlcXVlc3RSb3VuZDI6IFR4UmVxdWVzdDtcbiAgICBtZXNzYWdlQnVmZmVyOiBCdWZmZXI7XG4gIH0+IHtcbiAgICBjb25zdCByb3VuZDEgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHtcbiAgICAgIHR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBlbmNyeXB0ZWRQcnYsXG4gICAgfSk7XG5cbiAgICBjb25zdCB0cmFuc2FjdGlvbiA9IGFzc2VydFNpbmdsZVRyYW5zYWN0aW9uKHR4UmVxdWVzdCk7XG4gICAgY29uc3QgbWVzc2FnZUJ1ZmZlciA9IEJ1ZmZlci5mcm9tKHRyYW5zYWN0aW9uLnVuc2lnbmVkVHguc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCBiaXRnb0RzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYXdhaXQgYml0Z29Ec2cuaW5pdERzZyhiaXRnb0tleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCB0cmFuc2FjdGlvbi51bnNpZ25lZFR4LmRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuXG4gICAgY29uc3QgdHhSZXF1ZXN0Um91bmQxID0gYXdhaXQgc2lnbkJpdGdvRWRkc2FSb3VuZDEoXG4gICAgICBiaXRnb0RzZyxcbiAgICAgIGNsb25lVHhSZXF1ZXN0V2l0aEVtcHR5U2lnbmF0dXJlU2hhcmVzKHR4UmVxdWVzdCksXG4gICAgICByb3VuZDEuc2lnbmF0dXJlU2hhcmVSb3VuZDEsXG4gICAgICByb3VuZDEudXNlckdwZ1B1YktleSxcbiAgICAgIGJpdGdvR3BnUHJpdktleVxuICAgICk7XG5cbiAgICBjb25zdCByb3VuZDIgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMlNoYXJlKHtcbiAgICAgIHR4UmVxdWVzdDogdHhSZXF1ZXN0Um91bmQxLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogcm91bmQxLmVuY3J5cHRlZFVzZXJHcGdQcnZLZXksXG4gICAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uOiByb3VuZDEuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbixcbiAgICB9KTtcblxuICAgIGNvbnN0IHJvdW5kMVRyYW5zYWN0aW9uID0gYXNzZXJ0U2luZ2xlVHJhbnNhY3Rpb24odHhSZXF1ZXN0Um91bmQxKTtcbiAgICBjb25zdCB0eFJlcXVlc3RSb3VuZDIgPSBhd2FpdCBzaWduQml0Z29FZGRzYVJvdW5kMihcbiAgICAgIGJpdGdvRHNnLFxuICAgICAge1xuICAgICAgICAuLi50eFJlcXVlc3RSb3VuZDEsXG4gICAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLnJvdW5kMVRyYW5zYWN0aW9uLFxuICAgICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbLi4ucm91bmQxVHJhbnNhY3Rpb24uc2lnbmF0dXJlU2hhcmVzXSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSxcbiAgICAgIHJvdW5kMi5zaWduYXR1cmVTaGFyZVJvdW5kMixcbiAgICAgIHJvdW5kMS51c2VyR3BnUHViS2V5LFxuICAgICAgYml0Z29HcGdQcml2S2V5XG4gICAgKTtcblxuICAgIHJldHVybiB7IHJvdW5kMSwgcm91bmQyLCB0eFJlcXVlc3RSb3VuZDEsIHR4UmVxdWVzdFJvdW5kMiwgbWVzc2FnZUJ1ZmZlciB9O1xuICB9XG5cbiAgaXQoJ3Nob3VsZCBjcmVhdGUgYSByb3VuZC0zIHNoYXJlIGZyb20gb2ZmbGluZSByb3VuZCAyJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHsgcm91bmQxLCByb3VuZDIsIHR4UmVxdWVzdFJvdW5kMiB9ID0gYXdhaXQgY3JlYXRlUm91bmQyRmxvdyhiYXNlVHhSZXF1ZXN0KTtcblxuICAgIGNvbnN0IHJvdW5kMyA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQzU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3RSb3VuZDIsXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgYml0Z29QdWJsaWNHcGdLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDEuZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgIGVuY3J5cHRlZFJvdW5kMlNlc3Npb246IHJvdW5kMi5lbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLFxuICAgIH0pO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJvdW5kMy5zaWduYXR1cmVTaGFyZVJvdW5kMy5mcm9tLCBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJvdW5kMy5zaWduYXR1cmVTaGFyZVJvdW5kMy50bywgU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPKTtcblxuICAgIGNvbnN0IHBhcnNlZFNoYXJlID0gZGVjb2RlV2l0aENvZGVjKFxuICAgICAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQzSW5wdXQsXG4gICAgICBKU09OLnBhcnNlKHJvdW5kMy5zaWduYXR1cmVTaGFyZVJvdW5kMy5zaGFyZSksXG4gICAgICAnRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQzSW5wdXQnXG4gICAgKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFyc2VkU2hhcmUudHlwZSwgJ3JvdW5kM0lucHV0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZFNoYXJlLmRhdGEubXNnMy5tZXNzYWdlLCAnbXNnMy5tZXNzYWdlIHNob3VsZCBiZSBzZXQnKTtcbiAgICBhc3NlcnQub2socGFyc2VkU2hhcmUuZGF0YS5tc2czLnNpZ25hdHVyZSwgJ21zZzMuc2lnbmF0dXJlIHNob3VsZCBiZSBzZXQnKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB1c2UgdjIgZGVjcnlwdGlvbiB3aGVuIGVuY3J5cHRlZFJvdW5kMlNlc3Npb24gaXMgYSB2MiBlbnZlbG9wZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBlbmNyeXB0ID0gc2lub25cbiAgICAgIC5zdHViKClcbiAgICAgIC5jYWxsc0Zha2UoKGlucHV0OiBzdHJpbmcsIGFkYXRhOiBzdHJpbmcpID0+IFByb21pc2UucmVzb2x2ZShKU09OLnN0cmluZ2lmeSh7IHY6IDIsIGlucHV0LCBhZGF0YSB9KSkpO1xuICAgIGNvbnN0IGRlc3Ryb3kgPSBzaW5vbi5zdHViKCk7XG4gICAgY29uc3QgY3JlYXRlRW5jcnlwdGlvblNlc3Npb24gPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBlbmNyeXB0LCBkZXN0cm95IH0pO1xuICAgIG1vY2tCaXRnby5jcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbiA9IGNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uO1xuXG4gICAgY29uc3QgZGVjcnlwdCA9IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoYXN5bmMgKHBhcmFtczogeyBpbnB1dDogc3RyaW5nIH0pID0+IHtcbiAgICAgIGNvbnN0IGVudmVsb3BlID0gSlNPTi5wYXJzZShwYXJhbXMuaW5wdXQpO1xuICAgICAgcmV0dXJuIGVudmVsb3BlLmlucHV0O1xuICAgIH0pO1xuICAgIG1vY2tCaXRnby5kZWNyeXB0ID0gZGVjcnlwdDtcblxuICAgIGNvbnN0IHsgcm91bmQxLCByb3VuZDIsIHR4UmVxdWVzdFJvdW5kMiB9ID0gYXdhaXQgY3JlYXRlUm91bmQyRmxvdyhiYXNlVHhSZXF1ZXN0LCBKU09OLnN0cmluZ2lmeSh7IHY6IDIgfSkpO1xuXG4gICAgY29uc3Qgcm91bmQzID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDNTaGFyZSh7XG4gICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdFJvdW5kMixcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbjogcm91bmQyLmVuY3J5cHRlZFJvdW5kMlNlc3Npb24sXG4gICAgfSk7XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoKG1vY2tCaXRnby5kZWNyeXB0IGFzIHNpbm9uLlNpbm9uU3R1YikuY2FsbENvdW50LCA0KTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocm91bmQzLnNpZ25hdHVyZVNoYXJlUm91bmQzLmZyb20sIFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWplY3QgdGFtcGVyZWQgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbiBhZGF0YScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBvdGhlclR4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgICAgLi4uYmFzZVR4UmVxdWVzdCxcbiAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICB7XG4gICAgICAgICAgdW5zaWduZWRUeDoge1xuICAgICAgICAgICAgc2lnbmFibGVIZXg6ICdjYWZlYmFiZScsXG4gICAgICAgICAgICBkZXJpdmF0aW9uUGF0aDogJ20vMS8yJyxcbiAgICAgICAgICAgIHNlcmlhbGl6ZWRUeEhleDogJ2NhZmViYWJlJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogW10sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0gYXMgdW5rbm93biBhcyBUeFJlcXVlc3Q7XG5cbiAgICBjb25zdCBvdGhlckZsb3cgPSBhd2FpdCBjcmVhdGVSb3VuZDJGbG93KG90aGVyVHhSZXF1ZXN0KTtcbiAgICBjb25zdCB7IHJvdW5kMSwgdHhSZXF1ZXN0Um91bmQyIH0gPSBhd2FpdCBjcmVhdGVSb3VuZDJGbG93KGJhc2VUeFJlcXVlc3QpO1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PlxuICAgICAgICBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kM1NoYXJlKHtcbiAgICAgICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdFJvdW5kMixcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFJvdW5kMlNlc3Npb246IG90aGVyRmxvdy5yb3VuZDIuZW5jcnlwdGVkUm91bmQyU2Vzc2lvbixcbiAgICAgICAgfSksXG4gICAgICAvQWRhdGEgZG9lcyBub3QgbWF0Y2ggY3lwaGVydGV4dCBhZGF0YS9cbiAgICApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJlamVjdCB0YW1wZXJlZCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5IGFkYXRhJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG90aGVyVHhSZXF1ZXN0OiBUeFJlcXVlc3QgPSB7XG4gICAgICAuLi5iYXNlVHhSZXF1ZXN0LFxuICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgICBzaWduYWJsZUhleDogJ2NhZmViYWJlJyxcbiAgICAgICAgICAgIGRlcml2YXRpb25QYXRoOiAnbS8xLzInLFxuICAgICAgICAgICAgc2VyaWFsaXplZFR4SGV4OiAnY2FmZWJhYmUnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSBhcyB1bmtub3duIGFzIFR4UmVxdWVzdDtcblxuICAgIGNvbnN0IG90aGVyRmxvdyA9IGF3YWl0IGNyZWF0ZVJvdW5kMkZsb3cob3RoZXJUeFJlcXVlc3QpO1xuICAgIGNvbnN0IHsgcm91bmQyLCB0eFJlcXVlc3RSb3VuZDIgfSA9IGF3YWl0IGNyZWF0ZVJvdW5kMkZsb3coYmFzZVR4UmVxdWVzdCk7XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+XG4gICAgICAgIGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQzU2hhcmUoe1xuICAgICAgICAgIHR4UmVxdWVzdDogdHhSZXF1ZXN0Um91bmQyLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgYml0Z29QdWJsaWNHcGdLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogb3RoZXJGbG93LnJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFJvdW5kMlNlc3Npb246IHJvdW5kMi5lbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLFxuICAgICAgICB9KSxcbiAgICAgIC9BZGF0YSBkb2VzIG5vdCBtYXRjaCBjeXBoZXJ0ZXh0IGFkYXRhL1xuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmVqZWN0IHdoZW4gQml0R28gcm91bmQtMiBzaWduYXR1cmUgc2hhcmUgaXMgbWlzc2luZycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB7IHJvdW5kMSwgcm91bmQyLCB0eFJlcXVlc3RSb3VuZDEgfSA9IGF3YWl0IGNyZWF0ZVJvdW5kMkZsb3coYmFzZVR4UmVxdWVzdCk7XG5cbiAgICBjb25zdCByb3VuZDFUcmFuc2FjdGlvbiA9IGFzc2VydFNpbmdsZVRyYW5zYWN0aW9uKHR4UmVxdWVzdFJvdW5kMSk7XG4gICAgY29uc3QgdHhSZXF1ZXN0Tm9CaXRnb1JvdW5kMlNoYXJlOiBUeFJlcXVlc3QgPSB7XG4gICAgICAuLi50eFJlcXVlc3RSb3VuZDEsXG4gICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAge1xuICAgICAgICAgIC4uLnJvdW5kMVRyYW5zYWN0aW9uLFxuICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogWy4uLnJvdW5kMVRyYW5zYWN0aW9uLnNpZ25hdHVyZVNoYXJlcywgcm91bmQyLnNpZ25hdHVyZVNoYXJlUm91bmQyXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDNTaGFyZSh7XG4gICAgICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3ROb0JpdGdvUm91bmQyU2hhcmUsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDEuZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgICAgICBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uOiByb3VuZDIuZW5jcnlwdGVkUm91bmQyU2Vzc2lvbixcbiAgICAgICAgfSksXG4gICAgICAvTWlzc2luZyBCaXRHbyByb3VuZDJPdXRwdXQgc2lnbmF0dXJlIHNoYXJlL1xuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcHJvcGFnYXRlIHRoZSB0eC1vbmx5IGd1YXJkIHdoZW4gdHJhbnNhY3Rpb25zIGFyZSBtaXNzaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHsgcm91bmQxLCByb3VuZDIgfSA9IGF3YWl0IGNyZWF0ZVJvdW5kMkZsb3coYmFzZVR4UmVxdWVzdCk7XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+XG4gICAgICAgIGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQzU2hhcmUoe1xuICAgICAgICAgIHR4UmVxdWVzdDogeyAuLi5iYXNlVHhSZXF1ZXN0LCB0cmFuc2FjdGlvbnM6IHVuZGVmaW5lZCB9IGFzIHVua25vd24gYXMgVHhSZXF1ZXN0LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgYml0Z29QdWJsaWNHcGdLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogcm91bmQxLmVuY3J5cHRlZFVzZXJHcGdQcnZLZXksXG4gICAgICAgICAgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbjogcm91bmQyLmVuY3J5cHRlZFJvdW5kMlNlc3Npb24sXG4gICAgICAgIH0pLFxuICAgICAgL1VuYWJsZSB0byBmaW5kIHRyYW5zYWN0aW9ucyBpbiB0eFJlcXVlc3QvXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWplY3Qgd2hlbiB0cmFuc2FjdGlvbnMgYXJyYXkgaXMgZW1wdHknLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeyByb3VuZDEsIHJvdW5kMiB9ID0gYXdhaXQgY3JlYXRlUm91bmQyRmxvdyhiYXNlVHhSZXF1ZXN0KTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDNTaGFyZSh7XG4gICAgICAgICAgdHhSZXF1ZXN0OiB7IC4uLmJhc2VUeFJlcXVlc3QsIHRyYW5zYWN0aW9uczogW10gfSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFJvdW5kMlNlc3Npb246IHJvdW5kMi5lbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLFxuICAgICAgICB9KSxcbiAgICAgIC9VbmFibGUgdG8gZmluZCB0cmFuc2FjdGlvbnMgaW4gdHhSZXF1ZXN0L1xuICAgICk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdnZXRCaXRnb1NpZ25hdHVyZVNoYXJlJywgKCkgPT4ge1xuICBjb25zdCByb3VuZDFPdXRwdXRTaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSB7XG4gICAgZnJvbTogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgIHRvOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUixcbiAgICBzaGFyZTogSlNPTi5zdHJpbmdpZnkoeyB0eXBlOiAncm91bmQxT3V0cHV0JywgZGF0YToge30gfSksXG4gIH07XG4gIGNvbnN0IHJvdW5kMk91dHB1dFNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCA9IHtcbiAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgdG86IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLFxuICAgIHNoYXJlOiBKU09OLnN0cmluZ2lmeSh7IHR5cGU6ICdyb3VuZDJPdXRwdXQnLCBkYXRhOiB7fSB9KSxcbiAgfTtcblxuICBpdCgnc2VsZWN0cyB0aGUgcmVxdWVzdGVkIEJpdEdvIHJvdW5kIG91dHB1dCB3aGVuIG11bHRpcGxlIHJvdW5kIG91dHB1dHMgYXJlIHByZXNlbnQnLCAoKSA9PiB7XG4gICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVzID0gW3JvdW5kMU91dHB1dFNoYXJlLCByb3VuZDJPdXRwdXRTaGFyZV07XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICBnZXRCaXRnb1NpZ25hdHVyZVNoYXJlKHNpZ25hdHVyZVNoYXJlcywgU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsICdyb3VuZDJPdXRwdXQnKSxcbiAgICAgIHJvdW5kMk91dHB1dFNoYXJlXG4gICAgKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICBnZXRCaXRnb1NpZ25hdHVyZVNoYXJlKHNpZ25hdHVyZVNoYXJlcywgU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsICdyb3VuZDFPdXRwdXQnKSxcbiAgICAgIHJvdW5kMU91dHB1dFNoYXJlXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3NraXBzIG1hbGZvcm1lZCBzaGFyZSByZWNvcmRzIHdoaWxlIHNlbGVjdGluZyB0aGUgcmVxdWVzdGVkIEJpdEdvIHJvdW5kIG91dHB1dCcsICgpID0+IHtcbiAgICBjb25zdCBtYWxmb3JtZWRTaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSB7XG4gICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsXG4gICAgICBzaGFyZTogJ25vdC1qc29uJyxcbiAgICB9O1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgICAgZ2V0Qml0Z29TaWduYXR1cmVTaGFyZShbbWFsZm9ybWVkU2hhcmUsIHJvdW5kMk91dHB1dFNoYXJlXSwgU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsICdyb3VuZDJPdXRwdXQnKSxcbiAgICAgIHJvdW5kMk91dHB1dFNoYXJlXG4gICAgKTtcbiAgfSk7XG59KTtcblxudHlwZSBUeFJlcXVlc3RUcmFuc2FjdGlvbiA9IE5vbk51bGxhYmxlPFR4UmVxdWVzdFsndHJhbnNhY3Rpb25zJ10+W251bWJlcl07XG5cbmZ1bmN0aW9uIGFzc2VydFNpbmdsZVRyYW5zYWN0aW9uKHR4UmVxdWVzdDogVHhSZXF1ZXN0KTogVHhSZXF1ZXN0VHJhbnNhY3Rpb24ge1xuICBhc3NlcnQub2sodHhSZXF1ZXN0LnRyYW5zYWN0aW9ucywgJ3R4UmVxdWVzdCBtdXN0IGluY2x1ZGUgdHJhbnNhY3Rpb25zJyk7XG4gIGFzc2VydC5zdHJpY3RFcXVhbCh0eFJlcXVlc3QudHJhbnNhY3Rpb25zLmxlbmd0aCwgMSwgJ3R4UmVxdWVzdCBtdXN0IGhhdmUgZXhhY3RseSBvbmUgdHJhbnNhY3Rpb24nKTtcbiAgcmV0dXJuIHR4UmVxdWVzdC50cmFuc2FjdGlvbnNbMF07XG59XG5cbmZ1bmN0aW9uIGNsb25lVHhSZXF1ZXN0V2l0aEVtcHR5U2lnbmF0dXJlU2hhcmVzKHR4UmVxdWVzdDogVHhSZXF1ZXN0KTogVHhSZXF1ZXN0IHtcbiAgY29uc3QgdHJhbnNhY3Rpb24gPSBhc3NlcnRTaW5nbGVUcmFuc2FjdGlvbih0eFJlcXVlc3QpO1xuICByZXR1cm4ge1xuICAgIC4uLnR4UmVxdWVzdCxcbiAgICB0cmFuc2FjdGlvbnM6IFt7IC4uLnRyYW5zYWN0aW9uLCBzaWduYXR1cmVTaGFyZXM6IFtdIH1dLFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzaWduQml0Z29FZGRzYVJvdW5kMShcbiAgYml0Z29Ec2c6IEVkZHNhTVBTRHNnLkRTRyxcbiAgdHhSZXF1ZXN0OiBUeFJlcXVlc3QsXG4gIHVzZXJSb3VuZDFTaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQsXG4gIHVzZXJHcGdQdWJLZXlBcm1vcmVkOiBzdHJpbmcsXG4gIGJpdGdvR3BnUHJpdktleTogcGdwLlByaXZhdGVLZXlcbik6IFByb21pc2U8VHhSZXF1ZXN0PiB7XG4gIGNvbnN0IHRyYW5zYWN0aW9uID0gYXNzZXJ0U2luZ2xlVHJhbnNhY3Rpb24odHhSZXF1ZXN0KTtcbiAgdHJhbnNhY3Rpb24uc2lnbmF0dXJlU2hhcmVzLnB1c2godXNlclJvdW5kMVNoYXJlKTtcblxuICBjb25zdCBiaXRnb01zZzEgPSBiaXRnb0RzZy5nZXRGaXJzdE1lc3NhZ2UoKTtcblxuICBjb25zdCBwYXJzZWRVc2VyU2hhcmUgPSBkZWNvZGVXaXRoQ29kZWMoXG4gICAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQsXG4gICAgSlNPTi5wYXJzZSh1c2VyUm91bmQxU2hhcmUuc2hhcmUpLFxuICAgICdFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFJbnB1dCdcbiAgKTtcbiAgY29uc3QgdXNlckdwZ0tleSA9IGF3YWl0IHBncC5yZWFkS2V5KHsgYXJtb3JlZEtleTogdXNlckdwZ1B1YktleUFybW9yZWQgfSk7XG4gIGNvbnN0IHVzZXJSYXdNc2cxQnl0ZXMgPSBhd2FpdCBNUFNDb21tcy52ZXJpZnlNcHNNZXNzYWdlKHBhcnNlZFVzZXJTaGFyZS5kYXRhLm1zZzEsIHVzZXJHcGdLZXkpO1xuICBjb25zdCB1c2VyTXNnMSA9IHtcbiAgICBmcm9tOiBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsXG4gICAgcGF5bG9hZDogbmV3IFVpbnQ4QXJyYXkodXNlclJhd01zZzFCeXRlcyksXG4gIH07XG5cbiAgY29uc3QgW2JpdGdvTXNnMl0gPSBiaXRnb0RzZy5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKFtiaXRnb01zZzEsIHVzZXJNc2cxXSk7XG4gIGFzc2VydC5vayhiaXRnb01zZzIsICdCaXRHbyBEU0cgcHJvZHVjZWQgbm8gcm91bmQtMiBvdXRwdXQnKTtcbiAgKGJpdGdvRHNnIGFzIEVkZHNhTVBTRHNnLkRTRyAmIHsgcm91bmQyTWVzc2FnZT86IE1QU1R5cGVzLkRlc2VyaWFsaXplZE1lc3NhZ2UgfSkucm91bmQyTWVzc2FnZSA9IGJpdGdvTXNnMjtcblxuICBjb25zdCBiaXRnb1NpZ25lZE1zZzEgPSBhd2FpdCBNUFNDb21tcy5kZXRhY2hTaWduTXBzTWVzc2FnZShCdWZmZXIuZnJvbShiaXRnb01zZzEucGF5bG9hZCksIGJpdGdvR3BnUHJpdktleSk7XG4gIGNvbnN0IHJvdW5kMU91dHB1dDogRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxT3V0cHV0ID0ge1xuICAgIHR5cGU6ICdyb3VuZDFPdXRwdXQnLFxuICAgIGRhdGE6IHsgbXNnMTogYml0Z29TaWduZWRNc2cxIH0sXG4gIH07XG5cbiAgdHJhbnNhY3Rpb24uc2lnbmF0dXJlU2hhcmVzLnB1c2goe1xuICAgIGZyb206IFNpZ25hdHVyZVNoYXJlVHlwZS5CSVRHTyxcbiAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsXG4gICAgc2hhcmU6IEpTT04uc3RyaW5naWZ5KHJvdW5kMU91dHB1dCksXG4gIH0pO1xuXG4gIHJldHVybiB0eFJlcXVlc3Q7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNpZ25CaXRnb0VkZHNhUm91bmQyKFxuICBiaXRnb0RzZzogRWRkc2FNUFNEc2cuRFNHLFxuICB0eFJlcXVlc3Q6IFR4UmVxdWVzdCxcbiAgdXNlclJvdW5kMlNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCxcbiAgdXNlckdwZ1B1YktleUFybW9yZWQ6IHN0cmluZyxcbiAgYml0Z29HcGdQcml2S2V5OiBwZ3AuUHJpdmF0ZUtleVxuKTogUHJvbWlzZTxUeFJlcXVlc3Q+IHtcbiAgY29uc3QgdHJhbnNhY3Rpb24gPSBhc3NlcnRTaW5nbGVUcmFuc2FjdGlvbih0eFJlcXVlc3QpO1xuICB0cmFuc2FjdGlvbi5zaWduYXR1cmVTaGFyZXMucHVzaCh1c2VyUm91bmQyU2hhcmUpO1xuXG4gIGNvbnN0IHVzZXJHcGdLZXkgPSBhd2FpdCBwZ3AucmVhZEtleSh7IGFybW9yZWRLZXk6IHVzZXJHcGdQdWJLZXlBcm1vcmVkIH0pO1xuICBjb25zdCBiaXRnb01zZzIgPSAoYml0Z29Ec2cgYXMgRWRkc2FNUFNEc2cuRFNHICYgeyByb3VuZDJNZXNzYWdlPzogTVBTVHlwZXMuRGVzZXJpYWxpemVkTWVzc2FnZSB9KS5yb3VuZDJNZXNzYWdlO1xuICBhc3NlcnQub2soYml0Z29Nc2cyLCAnQml0R28gRFNHIGlzIG1pc3NpbmcgdGhlIGNhY2hlZCByb3VuZC0yIG91dHB1dCcpO1xuXG4gIGNvbnN0IHBhcnNlZFVzZXJSb3VuZDJTaGFyZSA9IGRlY29kZVdpdGhDb2RlYyhcbiAgICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJJbnB1dCxcbiAgICBKU09OLnBhcnNlKHVzZXJSb3VuZDJTaGFyZS5zaGFyZSksXG4gICAgJ0VkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMklucHV0J1xuICApO1xuICBjb25zdCB1c2VyUmF3TXNnMkJ5dGVzID0gYXdhaXQgTVBTQ29tbXMudmVyaWZ5TXBzTWVzc2FnZShwYXJzZWRVc2VyUm91bmQyU2hhcmUuZGF0YS5tc2cyLCB1c2VyR3BnS2V5KTtcbiAgY29uc3QgdXNlck1zZzIgPSB7XG4gICAgZnJvbTogTVBDdjJQYXJ0aWVzRW51bS5VU0VSLFxuICAgIHBheWxvYWQ6IG5ldyBVaW50OEFycmF5KHVzZXJSYXdNc2cyQnl0ZXMpLFxuICB9O1xuXG4gIGNvbnN0IGJpdGdvU2lnbmVkTXNnMiA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKGJpdGdvTXNnMi5wYXlsb2FkKSwgYml0Z29HcGdQcml2S2V5KTtcbiAgY29uc3Qgcm91bmQyT3V0cHV0OiBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJPdXRwdXQgPSB7XG4gICAgdHlwZTogJ3JvdW5kMk91dHB1dCcsXG4gICAgZGF0YTogeyBtc2cyOiBiaXRnb1NpZ25lZE1zZzIgfSxcbiAgfTtcblxuICB0cmFuc2FjdGlvbi5zaWduYXR1cmVTaGFyZXMucHVzaCh7XG4gICAgZnJvbTogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgIHRvOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUixcbiAgICBzaGFyZTogSlNPTi5zdHJpbmdpZnkocm91bmQyT3V0cHV0KSxcbiAgfSk7XG5cbiAgYml0Z29Ec2cuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhbYml0Z29Nc2cyLCB1c2VyTXNnMl0pO1xuXG4gIHJldHVybiB0eFJlcXVlc3Q7XG59XG5cbmRlc2NyaWJlKCdFZGRzYU1QQ3YyVXRpbHMuc2lnbkVkZHNhTVBDdjJUc3NVc2luZ0V4dGVybmFsU2lnbmVyJywgKCkgPT4ge1xuICBsZXQgc2FuZGJveDogc2lub24uU2lub25TYW5kYm94O1xuICBsZXQgZWRkc2FNUEN2MlV0aWxzOiBFZGRzYU1QQ3YyVXRpbHM7XG4gIGxldCBtb2NrQml0Z286IEJpdEdvQmFzZTtcbiAgbGV0IGJpdGdvR3BnS2V5UGFpcjogcGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz47XG4gIGxldCBiaXRnb0dwZ1B1YktleTogcGdwLktleTtcblxuICBjb25zdCB3YWxsZXRJZCA9ICdhYmMxMjN3YWxsZXQnO1xuICBjb25zdCB0eFJlcXVlc3RJZCA9ICd0eHJlcS0wMDEnO1xuICBjb25zdCBlbnRlcnByaXNlSWQgPSAnZW50LTAwMSc7XG5cbiAgY29uc3QgbW9ja1R4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgIHR4UmVxdWVzdElkLFxuICAgIHdhbGxldElkLFxuICAgIGVudGVycHJpc2VJZCxcbiAgICBhcGlWZXJzaW9uOiAnZnVsbCcsXG4gICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICB7XG4gICAgICAgIHVuc2lnbmVkVHg6IHtcbiAgICAgICAgICBzaWduYWJsZUhleDogJ2RlYWRiZWVmJyxcbiAgICAgICAgICBkZXJpdmF0aW9uUGF0aDogJ20vMCcsXG4gICAgICAgICAgc2VyaWFsaXplZFR4SGV4OiAnZGVhZGJlZWYnLFxuICAgICAgICB9LFxuICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgICAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsXG4gICAgICAgICAgICBzaGFyZTogSlNPTi5zdHJpbmdpZnkoeyB0eXBlOiAncm91bmQxT3V0cHV0JywgZGF0YToge30gfSksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgXSxcbiAgICBpbnRlbnQ6IHsgaW50ZW50VHlwZTogJ3BheW1lbnQnIH0sXG4gICAgdW5zaWduZWRUeHM6IFtdLFxuICB9IGFzIHVua25vd24gYXMgVHhSZXF1ZXN0O1xuXG4gIGNvbnN0IG1vY2tUeFJlcXVlc3RUcmFuc2FjdGlvbiA9IGFzc2VydFNpbmdsZVRyYW5zYWN0aW9uKG1vY2tUeFJlcXVlc3QpO1xuICBjb25zdCBtb2NrVHhSZXF1ZXN0Um91bmQyOiBUeFJlcXVlc3QgPSB7XG4gICAgLi4ubW9ja1R4UmVxdWVzdCxcbiAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgIHtcbiAgICAgICAgLi4ubW9ja1R4UmVxdWVzdFRyYW5zYWN0aW9uLFxuICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgICAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsXG4gICAgICAgICAgICBzaGFyZTogSlNPTi5zdHJpbmdpZnkoeyB0eXBlOiAncm91bmQyT3V0cHV0JywgZGF0YToge30gfSksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfTtcblxuICBjb25zdCBkdW1teVNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCA9IHtcbiAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUixcbiAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgIHNoYXJlOiBKU09OLnN0cmluZ2lmeSh7IHR5cGU6ICdyb3VuZDFJbnB1dCcsIGRhdGE6IHt9IH0pLFxuICB9O1xuXG4gIC8vIFJldHVybnMgYSBjaGFpbiBjb21wYXRpYmxlIHdpdGg6IGJpdGdvLnBvc3QodXJsKS5zZW5kKGJvZHkpLnJlc3VsdCgpXG4gIGNvbnN0IG1ha2VQb3N0Q2hhaW4gPSAocmVzcG9uc2U6IFR4UmVxdWVzdCk6IEJpdEdvUmVxdWVzdDxUeFJlcXVlc3Q+ID0+XG4gICAgKHsgc2VuZDogKCkgPT4gKHsgcmVzdWx0OiBzaW5vbi5zdHViKCkucmVzb2x2ZXMocmVzcG9uc2UpIH0pIH0gYXMgdW5rbm93biBhcyBCaXRHb1JlcXVlc3Q8VHhSZXF1ZXN0Pik7XG5cbiAgLy8gUmV0dXJucyBhIGNoYWluIGNvbXBhdGlibGUgd2l0aDogYml0Z28uZ2V0KHVybCkucXVlcnkocGFyYW1zKS5yZXRyeShuKS5yZXN1bHQoKVxuICBjb25zdCBtYWtlR2V0Q2hhaW4gPSAodHhSZXF1ZXN0czogVHhSZXF1ZXN0W10pOiBCaXRHb1JlcXVlc3Q8eyB0eFJlcXVlc3RzOiBUeFJlcXVlc3RbXSB9PiA9PlxuICAgICh7XG4gICAgICBxdWVyeTogKCkgPT4gKHtcbiAgICAgICAgcmV0cnk6ICgpID0+ICh7IHJlc3VsdDogc2lub24uc3R1YigpLnJlc29sdmVzKHsgdHhSZXF1ZXN0cyB9KSB9KSxcbiAgICAgIH0pLFxuICAgIH0gYXMgdW5rbm93biBhcyBCaXRHb1JlcXVlc3Q8eyB0eFJlcXVlc3RzOiBUeFJlcXVlc3RbXSB9Pik7XG5cbiAgYmVmb3JlKGFzeW5jICgpID0+IHtcbiAgICBiaXRnb0dwZ0tleVBhaXIgPSBhd2FpdCBnZW5lcmF0ZUdQR0tleVBhaXIoJ2VkMjU1MTknKTtcbiAgICBiaXRnb0dwZ1B1YktleSA9IGF3YWl0IHBncC5yZWFkS2V5KHsgYXJtb3JlZEtleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSB9KTtcbiAgfSk7XG5cbiAgYmVmb3JlRWFjaChhc3luYyAoKSA9PiB7XG4gICAgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgIC8vIEZ1bGwgbW9jayBvZiB0aGUgQml0R28gSFRUUCBjbGllbnQgKGNvbnNpc3RlbnQgd2l0aCBvdGhlciBzZGstY29yZSB0ZXN0cyBzdWNoIGFzXG4gICAgLy8gdG9rZW5BcHByb3ZhbC50cyBhbmQgd2FsbGV0c0V2bUtleXJpbmcudHMpLiAgTW9kdWxlLWxldmVsIHN0dWJzIG9uIHRzc0NvbW1vbiBmdW5jdGlvbnNcbiAgICAvLyBkbyBub3Qgd29yayB1bmRlciB0c3ggNC54IChFU00gbGl2ZSBiaW5kaW5ncyksIHNvIHdlIG1vY2sgYXQgdGhlIGJpdGdvIG9iamVjdCBsZXZlbC5cbiAgICBtb2NrQml0Z28gPSB7XG4gICAgICBnZXRFbnY6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCd0ZXN0JyksXG4gICAgICBzZXRSZXF1ZXN0VHJhY2VyOiBzaW5vbi5zdHViKCksXG4gICAgICB1cmw6IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoKHBhdGg6IHN0cmluZykgPT4gYGh0dHBzOi8vdGVzdC5iaXRnby5jb20ke3BhdGh9YCksXG4gICAgICBwb3N0OiBzaW5vbi5zdHViKCksXG4gICAgICBnZXQ6IHNpbm9uLnN0dWIoKSxcbiAgICB9IGFzIHVua25vd24gYXMgQml0R29CYXNlO1xuXG4gICAgY29uc3QgbW9ja0NvaW4gPSB7XG4gICAgICBnZXRNUENBbGdvcml0aG06IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCdlZGRzYScpLFxuICAgIH0gYXMgdW5rbm93biBhcyBJQmFzZUNvaW47XG5cbiAgICBjb25zdCBtb2NrV2FsbGV0ID0ge1xuICAgICAgaWQ6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKHdhbGxldElkKSxcbiAgICAgIGtleUlkczogc2lub24uc3R1YigpLnJldHVybnMoWyd1c2VyS2V5SWQnLCAnYmFja3VwS2V5SWQnLCAnYml0Z29LZXlJZCddKSxcbiAgICAgIG11bHRpc2lnVHlwZVZlcnNpb246IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCdNUEN2MicpLFxuICAgIH0gYXMgdW5rbm93biBhcyBJV2FsbGV0O1xuXG4gICAgZWRkc2FNUEN2MlV0aWxzID0gbmV3IEVkZHNhTVBDdjJVdGlscyhtb2NrQml0Z28sIG1vY2tDb2luLCBtb2NrV2FsbGV0KTtcblxuICAgIHNhbmRib3guc3R1YihlZGRzYU1QQ3YyVXRpbHMsICdwaWNrQml0Z29QdWJHcGdLZXlGb3JTaWduaW5nJykucmVzb2x2ZXMoYml0Z29HcGdQdWJLZXkpO1xuICB9KTtcblxuICBhZnRlckVhY2goKCkgPT4ge1xuICAgIHNhbmRib3gucmVzdG9yZSgpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGNhbGwgYWxsIDMgZ2VuZXJhdG9ycyBhbmQgcmV0dXJuIHRoZSBmaW5hbCB0eCByZXF1ZXN0JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGZpbmFsVHhSZXF1ZXN0ID0geyAuLi5tb2NrVHhSZXF1ZXN0LCB0eFJlcXVlc3RJZCB9O1xuXG4gICAgLy8gc2VuZFNpZ25hdHVyZVNoYXJlVjIgaXMgY2FsbGVkIDMgdGltZXMgKG9uZSBwZXIgcm91bmQpLCBzZW5kVHhSZXF1ZXN0IG9uY2Ug4oCUIGFsbCB1c2UgYml0Z28ucG9zdFxuICAgIChtb2NrQml0Z28ucG9zdCBhcyBzaW5vbi5TaW5vblN0dWIpXG4gICAgICAub25DYWxsKDApXG4gICAgICAucmV0dXJucyhtYWtlUG9zdENoYWluKG1vY2tUeFJlcXVlc3QpKSAvLyByb3VuZCAxIHNpZ25cbiAgICAgIC5vbkNhbGwoMSlcbiAgICAgIC5yZXR1cm5zKG1ha2VQb3N0Q2hhaW4obW9ja1R4UmVxdWVzdFJvdW5kMikpIC8vIHJvdW5kIDIgc2lnblxuICAgICAgLm9uQ2FsbCgyKVxuICAgICAgLnJldHVybnMobWFrZVBvc3RDaGFpbihtb2NrVHhSZXF1ZXN0Um91bmQyKSkgLy8gcm91bmQgMyBzaWduXG4gICAgICAub25DYWxsKDMpXG4gICAgICAucmV0dXJucyhtYWtlUG9zdENoYWluKGZpbmFsVHhSZXF1ZXN0KSk7IC8vIHNlbmRUeFJlcXVlc3QgKHNlbmQpXG5cbiAgICBjb25zdCBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uID0gJ2VuY3J5cHRlZC1yMS1zZXNzaW9uJztcbiAgICBjb25zdCBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uID0gJ2VuY3J5cHRlZC1yMi1zZXNzaW9uJztcbiAgICBjb25zdCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5ID0gJ2VuY3J5cHRlZC1ncGcta2V5JztcbiAgICBjb25zdCB1c2VyR3BnUHViS2V5ID0gYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleTtcblxuICAgIGNvbnN0IHJvdW5kMVNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCA9IHsgLi4uZHVtbXlTaGFyZSB9O1xuICAgIGNvbnN0IHJvdW5kMlNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCA9IHsgLi4uZHVtbXlTaGFyZSwgc2hhcmU6IEpTT04uc3RyaW5naWZ5KHsgdHlwZTogJ3JvdW5kMklucHV0JyB9KSB9O1xuICAgIGNvbnN0IHJvdW5kM1NoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCA9IHsgLi4uZHVtbXlTaGFyZSwgc2hhcmU6IEpTT04uc3RyaW5naWZ5KHsgdHlwZTogJ3JvdW5kM0lucHV0JyB9KSB9O1xuXG4gICAgY29uc3Qgcm91bmQxR2VuZXJhdG9yID0gc2lub25cbiAgICAgIC5zdHViKClcbiAgICAgIC5yZXNvbHZlcyh7IHNpZ25hdHVyZVNoYXJlUm91bmQxOiByb3VuZDFTaGFyZSwgdXNlckdwZ1B1YktleSwgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiwgZW5jcnlwdGVkVXNlckdwZ1BydktleSB9KTtcbiAgICBjb25zdCByb3VuZDJHZW5lcmF0b3IgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBzaWduYXR1cmVTaGFyZVJvdW5kMjogcm91bmQyU2hhcmUsIGVuY3J5cHRlZFJvdW5kMlNlc3Npb24gfSk7XG4gICAgY29uc3Qgcm91bmQzR2VuZXJhdG9yID0gc2lub24uc3R1YigpLnJlc29sdmVzKHsgc2lnbmF0dXJlU2hhcmVSb3VuZDM6IHJvdW5kM1NoYXJlIH0pO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLnNpZ25FZGRzYU1QQ3YyVHNzVXNpbmdFeHRlcm5hbFNpZ25lcihcbiAgICAgIHsgdHhSZXF1ZXN0OiBtb2NrVHhSZXF1ZXN0LCByZXFJZDogbmV3IFJlcXVlc3RUcmFjZXIoKSB9LFxuICAgICAgcm91bmQxR2VuZXJhdG9yIGFzIHVua25vd24gYXMgQ3VzdG9tRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDFHZW5lcmF0aW5nRnVuY3Rpb24sXG4gICAgICByb3VuZDJHZW5lcmF0b3IgYXMgdW5rbm93biBhcyBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kMkdlbmVyYXRpbmdGdW5jdGlvbixcbiAgICAgIHJvdW5kM0dlbmVyYXRvciBhcyB1bmtub3duIGFzIEN1c3RvbUVkZHNhTVBDdjJTaWduaW5nUm91bmQzR2VuZXJhdGluZ0Z1bmN0aW9uXG4gICAgKTtcblxuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwocmVzdWx0LCBmaW5hbFR4UmVxdWVzdCk7XG5cbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShyb3VuZDFHZW5lcmF0b3IpO1xuICAgIHNpbm9uLmFzc2VydC5jYWxsZWRXaXRoKHJvdW5kMUdlbmVyYXRvciwgeyB0eFJlcXVlc3Q6IG1vY2tUeFJlcXVlc3QgfSk7XG5cbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShyb3VuZDJHZW5lcmF0b3IpO1xuICAgIGNvbnN0IHJvdW5kMkNhbGwgPSByb3VuZDJHZW5lcmF0b3IuZ2V0Q2FsbCgwKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocm91bmQyQ2FsbC5hcmdzWzBdLnR4UmVxdWVzdCwgbW9ja1R4UmVxdWVzdCk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJvdW5kMkNhbGwuYXJnc1swXS5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLCBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocm91bmQyQ2FsbC5hcmdzWzBdLmVuY3J5cHRlZFVzZXJHcGdQcnZLZXksIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXkpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyb3VuZDJDYWxsLmFyZ3NbMF0uYml0Z29QdWJsaWNHcGdLZXksIGJpdGdvR3BnUHViS2V5LmFybW9yKCkpO1xuXG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2Uocm91bmQzR2VuZXJhdG9yKTtcbiAgICBjb25zdCByb3VuZDNDYWxsID0gcm91bmQzR2VuZXJhdG9yLmdldENhbGwoMCk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJvdW5kM0NhbGwuYXJnc1swXS50eFJlcXVlc3QsIG1vY2tUeFJlcXVlc3RSb3VuZDIpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyb3VuZDNDYWxsLmFyZ3NbMF0uZW5jcnlwdGVkUm91bmQyU2Vzc2lvbiwgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJvdW5kM0NhbGwuYXJnc1swXS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5KTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocm91bmQzQ2FsbC5hcmdzWzBdLmJpdGdvUHVibGljR3BnS2V5LCBiaXRnb0dwZ1B1YktleS5hcm1vcigpKTtcblxuICAgIC8vIDMgc2VuZFNpZ25hdHVyZVNoYXJlVjIgY2FsbHMgKyAxIHNlbmRUeFJlcXVlc3QgPSA0IFBPU1QgY2FsbHMgdG90YWxcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoKG1vY2tCaXRnby5wb3N0IGFzIHNpbm9uLlNpbm9uU3R1YikuY2FsbENvdW50LCA0KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZXNvbHZlIHR4UmVxdWVzdCBieSBJRCBzdHJpbmcgdXNpbmcgZ2V0VHhSZXF1ZXN0JywgYXN5bmMgKCkgPT4ge1xuICAgIC8vIGdldFR4UmVxdWVzdCB1c2VzIGJpdGdvLmdldDsgc2VuZFNpZ25hdHVyZVNoYXJlVjIgKMOXMykgKyBzZW5kVHhSZXF1ZXN0IHVzZSBiaXRnby5wb3N0XG4gICAgKG1vY2tCaXRnby5nZXQgYXMgc2lub24uU2lub25TdHViKS5yZXR1cm5zKG1ha2VHZXRDaGFpbihbbW9ja1R4UmVxdWVzdF0pKTtcbiAgICAobW9ja0JpdGdvLnBvc3QgYXMgc2lub24uU2lub25TdHViKVxuICAgICAgLm9uQ2FsbCgwKVxuICAgICAgLnJldHVybnMobWFrZVBvc3RDaGFpbihtb2NrVHhSZXF1ZXN0KSlcbiAgICAgIC5vbkNhbGwoMSlcbiAgICAgIC5yZXR1cm5zKG1ha2VQb3N0Q2hhaW4obW9ja1R4UmVxdWVzdFJvdW5kMikpXG4gICAgICAub25DYWxsKDIpXG4gICAgICAucmV0dXJucyhtYWtlUG9zdENoYWluKG1vY2tUeFJlcXVlc3RSb3VuZDIpKVxuICAgICAgLm9uQ2FsbCgzKVxuICAgICAgLnJldHVybnMobWFrZVBvc3RDaGFpbihtb2NrVHhSZXF1ZXN0KSk7XG5cbiAgICBjb25zdCByb3VuZDFHZW5lcmF0b3IgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoe1xuICAgICAgc2lnbmF0dXJlU2hhcmVSb3VuZDE6IGR1bW15U2hhcmUsXG4gICAgICB1c2VyR3BnUHViS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbjogJ3IxJyxcbiAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6ICdrZXknLFxuICAgIH0pO1xuICAgIGNvbnN0IHJvdW5kMkdlbmVyYXRvciA9IHNpbm9uLnN0dWIoKS5yZXNvbHZlcyh7IHNpZ25hdHVyZVNoYXJlUm91bmQyOiBkdW1teVNoYXJlLCBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uOiAncjInIH0pO1xuICAgIGNvbnN0IHJvdW5kM0dlbmVyYXRvciA9IHNpbm9uLnN0dWIoKS5yZXNvbHZlcyh7IHNpZ25hdHVyZVNoYXJlUm91bmQzOiBkdW1teVNoYXJlIH0pO1xuXG4gICAgYXdhaXQgZWRkc2FNUEN2MlV0aWxzLnNpZ25FZGRzYU1QQ3YyVHNzVXNpbmdFeHRlcm5hbFNpZ25lcihcbiAgICAgIHsgdHhSZXF1ZXN0OiB0eFJlcXVlc3RJZCwgcmVxSWQ6IG5ldyBSZXF1ZXN0VHJhY2VyKCkgfSxcbiAgICAgIHJvdW5kMUdlbmVyYXRvciBhcyB1bmtub3duIGFzIEN1c3RvbUVkZHNhTVBDdjJTaWduaW5nUm91bmQxR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICAgICAgcm91bmQyR2VuZXJhdG9yIGFzIHVua25vd24gYXMgQ3VzdG9tRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDJHZW5lcmF0aW5nRnVuY3Rpb24sXG4gICAgICByb3VuZDNHZW5lcmF0b3IgYXMgdW5rbm93biBhcyBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kM0dlbmVyYXRpbmdGdW5jdGlvblxuICAgICk7XG5cbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShtb2NrQml0Z28uZ2V0IGFzIHNpbm9uLlNpbm9uU3R1Yik7XG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZFdpdGgocm91bmQxR2VuZXJhdG9yLCB7IHR4UmVxdWVzdDogbW9ja1R4UmVxdWVzdCB9KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIHJvdW5kIDIgdHhSZXF1ZXN0IGlzIG1pc3Npbmcgc2lnbmF0dXJlU2hhcmVzJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJvdW5kMk5vU2hhcmVzOiBUeFJlcXVlc3QgPSB7XG4gICAgICAuLi5tb2NrVHhSZXF1ZXN0LFxuICAgICAgdHJhbnNhY3Rpb25zOiBbeyAuLi5tb2NrVHhSZXF1ZXN0VHJhbnNhY3Rpb24sIHNpZ25hdHVyZVNoYXJlczogdW5kZWZpbmVkIGFzIHVua25vd24gYXMgW10gfV0sXG4gICAgfTtcblxuICAgIChtb2NrQml0Z28ucG9zdCBhcyBzaW5vbi5TaW5vblN0dWIpXG4gICAgICAub25DYWxsKDApXG4gICAgICAucmV0dXJucyhtYWtlUG9zdENoYWluKG1vY2tUeFJlcXVlc3QpKVxuICAgICAgLm9uQ2FsbCgxKVxuICAgICAgLnJldHVybnMobWFrZVBvc3RDaGFpbihyb3VuZDJOb1NoYXJlcykpO1xuXG4gICAgY29uc3Qgcm91bmQxR2VuZXJhdG9yID0gc2lub24uc3R1YigpLnJlc29sdmVzKHtcbiAgICAgIHNpZ25hdHVyZVNoYXJlUm91bmQxOiBkdW1teVNoYXJlLFxuICAgICAgdXNlckdwZ1B1YktleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246ICdyMScsXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiAna2V5JyxcbiAgICB9KTtcbiAgICBjb25zdCByb3VuZDJHZW5lcmF0b3IgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBzaWduYXR1cmVTaGFyZVJvdW5kMjogZHVtbXlTaGFyZSwgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbjogJ3IyJyB9KTtcbiAgICBjb25zdCByb3VuZDNHZW5lcmF0b3IgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBzaWduYXR1cmVTaGFyZVJvdW5kMzogZHVtbXlTaGFyZSB9KTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgZWRkc2FNUEN2MlV0aWxzLnNpZ25FZGRzYU1QQ3YyVHNzVXNpbmdFeHRlcm5hbFNpZ25lcihcbiAgICAgICAgICB7IHR4UmVxdWVzdDogbW9ja1R4UmVxdWVzdCwgcmVxSWQ6IG5ldyBSZXF1ZXN0VHJhY2VyKCkgfSxcbiAgICAgICAgICByb3VuZDFHZW5lcmF0b3IgYXMgdW5rbm93biBhcyBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kMUdlbmVyYXRpbmdGdW5jdGlvbixcbiAgICAgICAgICByb3VuZDJHZW5lcmF0b3IgYXMgdW5rbm93biBhcyBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kMkdlbmVyYXRpbmdGdW5jdGlvbixcbiAgICAgICAgICByb3VuZDNHZW5lcmF0b3IgYXMgdW5rbm93biBhcyBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kM0dlbmVyYXRpbmdGdW5jdGlvblxuICAgICAgICApLFxuICAgICAgL01pc3Npbmcgc2lnbmF0dXJlIHNoYXJlcyBpbiByb3VuZCAyIHR4UmVxdWVzdC9cbiAgICApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHBhc3MgYXJtb3JlZCBCaXRHbyBwdWJsaWMgR1BHIGtleSB0byByb3VuZCAyIGFuZCByb3VuZCAzIGdlbmVyYXRvcnMnLCBhc3luYyAoKSA9PiB7XG4gICAgKG1vY2tCaXRnby5wb3N0IGFzIHNpbm9uLlNpbm9uU3R1YilcbiAgICAgIC5vbkNhbGwoMClcbiAgICAgIC5yZXR1cm5zKG1ha2VQb3N0Q2hhaW4obW9ja1R4UmVxdWVzdCkpXG4gICAgICAub25DYWxsKDEpXG4gICAgICAucmV0dXJucyhtYWtlUG9zdENoYWluKG1vY2tUeFJlcXVlc3RSb3VuZDIpKVxuICAgICAgLm9uQ2FsbCgyKVxuICAgICAgLnJldHVybnMobWFrZVBvc3RDaGFpbihtb2NrVHhSZXF1ZXN0Um91bmQyKSlcbiAgICAgIC5vbkNhbGwoMylcbiAgICAgIC5yZXR1cm5zKG1ha2VQb3N0Q2hhaW4obW9ja1R4UmVxdWVzdCkpO1xuXG4gICAgY29uc3Qgcm91bmQxR2VuZXJhdG9yID0gc2lub24uc3R1YigpLnJlc29sdmVzKHtcbiAgICAgIHNpZ25hdHVyZVNoYXJlUm91bmQxOiBkdW1teVNoYXJlLFxuICAgICAgdXNlckdwZ1B1YktleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246ICdyMScsXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiAna2V5JyxcbiAgICB9KTtcbiAgICBjb25zdCByb3VuZDJHZW5lcmF0b3IgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBzaWduYXR1cmVTaGFyZVJvdW5kMjogZHVtbXlTaGFyZSwgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbjogJ3IyJyB9KTtcbiAgICBjb25zdCByb3VuZDNHZW5lcmF0b3IgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBzaWduYXR1cmVTaGFyZVJvdW5kMzogZHVtbXlTaGFyZSB9KTtcblxuICAgIGF3YWl0IGVkZHNhTVBDdjJVdGlscy5zaWduRWRkc2FNUEN2MlRzc1VzaW5nRXh0ZXJuYWxTaWduZXIoXG4gICAgICB7IHR4UmVxdWVzdDogbW9ja1R4UmVxdWVzdCwgcmVxSWQ6IG5ldyBSZXF1ZXN0VHJhY2VyKCkgfSxcbiAgICAgIHJvdW5kMUdlbmVyYXRvciBhcyB1bmtub3duIGFzIEN1c3RvbUVkZHNhTVBDdjJTaWduaW5nUm91bmQxR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICAgICAgcm91bmQyR2VuZXJhdG9yIGFzIHVua25vd24gYXMgQ3VzdG9tRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDJHZW5lcmF0aW5nRnVuY3Rpb24sXG4gICAgICByb3VuZDNHZW5lcmF0b3IgYXMgdW5rbm93biBhcyBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kM0dlbmVyYXRpbmdGdW5jdGlvblxuICAgICk7XG5cbiAgICBjb25zdCBhcm1vcmVkS2V5ID0gYml0Z29HcGdQdWJLZXkuYXJtb3IoKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICByb3VuZDJHZW5lcmF0b3IuZ2V0Q2FsbCgwKS5hcmdzWzBdLmJpdGdvUHVibGljR3BnS2V5LFxuICAgICAgYXJtb3JlZEtleSxcbiAgICAgICdyb3VuZCAyIHNob3VsZCByZWNlaXZlIGFybW9yZWQgQml0R28gR1BHIGtleSdcbiAgICApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgIHJvdW5kM0dlbmVyYXRvci5nZXRDYWxsKDApLmFyZ3NbMF0uYml0Z29QdWJsaWNHcGdLZXksXG4gICAgICBhcm1vcmVkS2V5LFxuICAgICAgJ3JvdW5kIDMgc2hvdWxkIHJlY2VpdmUgYXJtb3JlZCBCaXRHbyBHUEcga2V5J1xuICAgICk7XG4gIH0pO1xufSk7XG5cbmZ1bmN0aW9uIGJ5dGVzVG9Xb3JkKGJ5dGVzPzogVWludDhBcnJheSB8IG51bWJlcltdKTogbnVtYmVyIHtcbiAgaWYgKCEoYnl0ZXMgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB8fCBieXRlcy5sZW5ndGggIT09IDQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2J5dGVzIG11c3QgYmUgYSBVaW50OEFycmF5IHdpdGggbGVuZ3RoIDQnKTtcbiAgfVxuXG4gIHJldHVybiBieXRlcy5yZWR1Y2UoKG51bSwgYnl0ZSkgPT4gbnVtICogMHgxMDAgKyBieXRlLCAwKTtcbn1cblxuZGVzY3JpYmUoJ0VERFNBVXRpbHMuaXNFZGRzYU1wY1YxU2lnbmluZ01hdGVyaWFsJywgKCkgPT4ge1xuICBjb25zdCBQQVNTUEhSQVNFID0gJ3Rlc3QtcGFzc3BocmFzZSc7XG5cbiAgY29uc3QgTVBDdjFfTUFURVJJQUxfQkFDS1VQID0ge1xuICAgIHVTaGFyZTogeyBpOiAxLCB0OiAyLCBuOiAzLCB5OiAnYWFiYmNjJywgc2VlZDogJ2RlYWRiZWVmMDEyMzQ1NjcnLCBjaGFpbmNvZGU6ICcwMCcgfSxcbiAgICBiaXRnb1lTaGFyZTogeyBpOiAzLCBqOiAxLCB5OiAnYWFiYmNjJywgdTogJ2JpdGdvLXUtdmFsdWUnLCBjaGFpbmNvZGU6ICcwMCcgfSxcbiAgICBiYWNrdXBZU2hhcmU6IHsgaTogMiwgajogMSwgeTogJ2FhYmJjYycsIHU6ICdiYWNrdXAtdS12YWx1ZScsIGNoYWluY29kZTogJzAwJyB9LFxuICB9O1xuXG4gIGNvbnN0IE1QQ3YxX01BVEVSSUFMX1VTRVIgPSB7XG4gICAgdVNoYXJlOiB7IGk6IDIsIHQ6IDIsIG46IDMsIHk6ICdhYWJiY2MnLCBzZWVkOiAnZGVhZGJlZWYwMTIzNDU2NycsIGNoYWluY29kZTogJzAwJyB9LFxuICAgIGJpdGdvWVNoYXJlOiB7IGk6IDMsIGo6IDIsIHk6ICdhYWJiY2MnLCB1OiAnYml0Z28tdS12YWx1ZScsIGNoYWluY29kZTogJzAwJyB9LFxuICAgIHVzZXJZU2hhcmU6IHsgaTogMSwgajogMiwgeTogJ2FhYmJjYycsIHU6ICd1c2VyLXUtdmFsdWUnLCBjaGFpbmNvZGU6ICcwMCcgfSxcbiAgfTtcblxuICBjb25zdCBNUEN2Ml9DQk9SX0JZVEVTID0gQnVmZmVyLmZyb20oWzB4ZDksIDB4MDEsIDB4MDQsIDB4YTMsIDB4NjEsIDB4NzgsIDB4MTgsIDB4MDBdKS50b1N0cmluZygnYmFzZTY0Jyk7XG5cbiAgbGV0IG1vY2tCaXRnbzogQml0R29CYXNlO1xuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAvLyBzZGstY29yZSBoYXMgbm8gZGV2RGVwZW5kZW5jeSBvbiBzZGstYXBpL2FyZ29uMiwgc28gdjIgZW52ZWxvcGVzIGFyZSBzaW11bGF0ZWQgaGVyZS5cbiAgICAvLyBSZWFsIGJpdGdvLmRlY3J5cHQgcm91dGVzIHYyIHRvIEFyZ29uMmlkOyB0aGUgc3R1YiByZXR1cm5zIE1QQ3YyIENCT1IgcGxhaW50ZXh0IGluc3RlYWQuXG4gICAgbW9ja0JpdGdvID0ge1xuICAgICAgZGVjcnlwdDogc2lub24uc3R1YigpLmNhbGxzRmFrZShhc3luYyAocGFyYW1zOiB7IGlucHV0OiBzdHJpbmc7IHBhc3N3b3JkOiBzdHJpbmcgfSkgPT4ge1xuICAgICAgICBpZiAoaXNWMkVudmVsb3BlKHBhcmFtcy5pbnB1dCkpIHtcbiAgICAgICAgICByZXR1cm4gTVBDdjJfQ0JPUl9CWVRFUztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2pjbC5kZWNyeXB0KHBhcmFtcy5wYXNzd29yZCwgcGFyYW1zLmlucHV0KTtcbiAgICAgIH0pLFxuICAgIH0gYXMgdW5rbm93biBhcyBCaXRHb0Jhc2U7XG4gIH0pO1xuXG4gIGl0KCdyZXR1cm5zIHRydWUgZm9yIE1QQ3YxIFNKQ0wtZW5jcnlwdGVkIGtleWNhcmQgd2l0aCBiYWNrdXBZU2hhcmUgKyBjb3JyZWN0IHBhc3NwaHJhc2UnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZW5jcnlwdGVkID0gc2pjbC5lbmNyeXB0KFBBU1NQSFJBU0UsIEpTT04uc3RyaW5naWZ5KE1QQ3YxX01BVEVSSUFMX0JBQ0tVUCkpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChhd2FpdCBFRERTQVV0aWxzLmlzRWRkc2FNcGNWMVNpZ25pbmdNYXRlcmlhbChlbmNyeXB0ZWQsIFBBU1NQSFJBU0UpLCB0cnVlKTtcbiAgfSk7XG5cbiAgaXQoJ3JldHVybnMgdHJ1ZSBmb3IgTVBDdjEgU0pDTC1lbmNyeXB0ZWQga2V5Y2FyZCB3aXRoIHVzZXJZU2hhcmUgKyBjb3JyZWN0IHBhc3NwaHJhc2UnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZW5jcnlwdGVkID0gc2pjbC5lbmNyeXB0KFBBU1NQSFJBU0UsIEpTT04uc3RyaW5naWZ5KE1QQ3YxX01BVEVSSUFMX1VTRVIpKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYXdhaXQgRUREU0FVdGlscy5pc0VkZHNhTXBjVjFTaWduaW5nTWF0ZXJpYWwoZW5jcnlwdGVkLCBQQVNTUEhSQVNFKSwgdHJ1ZSk7XG4gIH0pO1xuXG4gIGl0KCdyZXR1cm5zIGZhbHNlIGZvciBNUEN2MiBDQk9SIGNvbnRlbnQgd3JhcHBlZCBpbiBTSkNMIGVudmVsb3BlICsgY29ycmVjdCBwYXNzcGhyYXNlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGVuY3J5cHRlZCA9IHNqY2wuZW5jcnlwdChQQVNTUEhSQVNFLCBNUEN2Ml9DQk9SX0JZVEVTKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYXdhaXQgRUREU0FVdGlscy5pc0VkZHNhTXBjVjFTaWduaW5nTWF0ZXJpYWwoZW5jcnlwdGVkLCBQQVNTUEhSQVNFKSwgZmFsc2UpO1xuICB9KTtcblxuICBpdCgncmV0dXJucyBmYWxzZSBmb3IgTVBDdjIgQXJnb24yaWQgZW52ZWxvcGUgKHYyKSArIGNvcnJlY3QgcGFzc3BocmFzZSAoZm9yd2FyZC1jb21wYXQpJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGZha2VWMkVudmVsb3BlID0gSlNPTi5zdHJpbmdpZnkoeyB2OiAyLCBtOiA2NTUzNiwgdDogMywgcDogNCwgc2FsdDogJ0FBQUEnLCBpdjogJ0FBQUEnLCBjdDogJ0FBQUEnIH0pO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChhd2FpdCBFRERTQVV0aWxzLmlzRWRkc2FNcGNWMVNpZ25pbmdNYXRlcmlhbChmYWtlVjJFbnZlbG9wZSwgUEFTU1BIUkFTRSwgbW9ja0JpdGdvKSwgZmFsc2UpO1xuICB9KTtcblxuICBpdCgndGhyb3dzIG9uIHdyb25nIHBhc3NwaHJhc2UnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZW5jcnlwdGVkID0gc2pjbC5lbmNyeXB0KFBBU1NQSFJBU0UsIEpTT04uc3RyaW5naWZ5KE1QQ3YxX01BVEVSSUFMX0JBQ0tVUCkpO1xuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgRUREU0FVdGlscy5pc0VkZHNhTXBjVjFTaWduaW5nTWF0ZXJpYWwoZW5jcnlwdGVkLCAnd3JvbmctcGFzc3BocmFzZScpLFxuICAgICAgL2NjbTogdGFnIGRvZXNuJ3QgbWF0Y2gvXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3JldHVybnMgZmFsc2Ugd2hlbiBuZWl0aGVyIGJhY2t1cFlTaGFyZS51IG5vciB1c2VyWVNoYXJlLnUgaXMgcHJlc2VudCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBwYXJ0aWFsID0geyB1U2hhcmU6IHsgc2VlZDogJ2FiYycgfSwgYml0Z29ZU2hhcmU6IHsgdTogJ3h5eicgfSB9O1xuICAgIGNvbnN0IGVuY3J5cHRlZCA9IHNqY2wuZW5jcnlwdChQQVNTUEhSQVNFLCBKU09OLnN0cmluZ2lmeShwYXJ0aWFsKSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGF3YWl0IEVERFNBVXRpbHMuaXNFZGRzYU1wY1YxU2lnbmluZ01hdGVyaWFsKGVuY3J5cHRlZCwgUEFTU1BIUkFTRSksIGZhbHNlKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ3NpZ25SZWNvdmVyeUVkZHNhTVBDdjInLCAoKSA9PiB7XG4gIGNvbnN0IGRlcml2YXRpb25QYXRoID0gJ20vMC8wJztcblxuICBpdCgnc2hvdWxkIHJldHVybiBhIDY0LWJ5dGUgc2lnbmF0dXJlIHRoYXQgdmVyaWZpZXMgYWdhaW5zdCB0aGUgZGVyaXZlZCBwdWJsaWMga2V5JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IFt1c2VyRGtnLCBiYWNrdXBEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKCdkZWFkYmVlZicsICdoZXgnKTtcbiAgICBjb25zdCBjb21tb25LZXlDaGFpbiA9IHVzZXJEa2cuZ2V0Q29tbW9uS2V5Y2hhaW4oKTtcblxuICAgIGNvbnN0IHNpZ25hdHVyZSA9IGF3YWl0IEVERFNBVXRpbHMuc2lnblJlY292ZXJ5RWRkc2FNUEN2MihcbiAgICAgIG1lc3NhZ2UsXG4gICAgICBkZXJpdmF0aW9uUGF0aCxcbiAgICAgIHVzZXJEa2cuZ2V0S2V5U2hhcmUoKSxcbiAgICAgIGJhY2t1cERrZy5nZXRLZXlTaGFyZSgpLFxuICAgICAgY29tbW9uS2V5Q2hhaW5cbiAgICApO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNpZ25hdHVyZS5sZW5ndGgsIDY0KTtcblxuICAgIGNvbnN0IG1wYyA9IGF3YWl0IGdldEluaXRpYWxpemVkTXBjSW5zdGFuY2UoKTtcbiAgICBjb25zdCBkZXJpdmVkS2V5Y2hhaW4gPSBtcGMuZGVyaXZlVW5oYXJkZW5lZChjb21tb25LZXlDaGFpbiwgZGVyaXZhdGlvblBhdGgpO1xuICAgIGNvbnN0IHB1YmxpY0tleUJ5dGVzID0gQnVmZmVyLmZyb20oZGVyaXZlZEtleWNoYWluLnNsaWNlKDAsIDY0KSwgJ2hleCcpO1xuICAgIGNvbnN0IG9rID0gZWQyNTUxOS52ZXJpZnkobmV3IFVpbnQ4QXJyYXkoc2lnbmF0dXJlKSwgbmV3IFVpbnQ4QXJyYXkobWVzc2FnZSksIG5ldyBVaW50OEFycmF5KHB1YmxpY0tleUJ5dGVzKSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKG9rLCB0cnVlKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2Ugd2hlbiB2ZXJpZnlpbmcgdGhlIHNpZ25hdHVyZSBhZ2FpbnN0IGEgZGlmZmVyZW50IG1lc3NhZ2UnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgW3VzZXJEa2csIGJhY2t1cERrZ10gPSBhd2FpdCBNUFNVdGlsLmdlbmVyYXRlRWREc2FES0dLZXlTaGFyZXMoKTtcbiAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oJ2RlYWRiZWVmJywgJ2hleCcpO1xuICAgIGNvbnN0IGNvbW1vbktleUNoYWluID0gdXNlckRrZy5nZXRDb21tb25LZXljaGFpbigpO1xuXG4gICAgY29uc3Qgc2lnbmF0dXJlID0gYXdhaXQgRUREU0FVdGlscy5zaWduUmVjb3ZlcnlFZGRzYU1QQ3YyKFxuICAgICAgbWVzc2FnZSxcbiAgICAgIGRlcml2YXRpb25QYXRoLFxuICAgICAgdXNlckRrZy5nZXRLZXlTaGFyZSgpLFxuICAgICAgYmFja3VwRGtnLmdldEtleVNoYXJlKCksXG4gICAgICBjb21tb25LZXlDaGFpblxuICAgICk7XG5cbiAgICBjb25zdCBkaWZmZXJlbnRNZXNzYWdlID0gQnVmZmVyLmZyb20oJ2NhZmViYWJlJywgJ2hleCcpO1xuICAgIGNvbnN0IG1wYyA9IGF3YWl0IGdldEluaXRpYWxpemVkTXBjSW5zdGFuY2UoKTtcbiAgICBjb25zdCBkZXJpdmVkS2V5Y2hhaW4gPSBtcGMuZGVyaXZlVW5oYXJkZW5lZChjb21tb25LZXlDaGFpbiwgZGVyaXZhdGlvblBhdGgpO1xuICAgIGNvbnN0IHB1YmxpY0tleUJ5dGVzID0gQnVmZmVyLmZyb20oZGVyaXZlZEtleWNoYWluLnNsaWNlKDAsIDY0KSwgJ2hleCcpO1xuICAgIGNvbnN0IG9rID0gZWQyNTUxOS52ZXJpZnkoXG4gICAgICBuZXcgVWludDhBcnJheShzaWduYXR1cmUpLFxuICAgICAgbmV3IFVpbnQ4QXJyYXkoZGlmZmVyZW50TWVzc2FnZSksXG4gICAgICBuZXcgVWludDhBcnJheShwdWJsaWNLZXlCeXRlcylcbiAgICApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChvaywgZmFsc2UpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHRocm93IHdoZW4gYSB3cm9uZyBjb21tb25LZXlDaGFpbiBpcyBwcm92aWRlZCAodmVyaWZpY2F0aW9uIG1pc21hdGNoKScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBbdXNlckRrZywgYmFja3VwRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIGNvbnN0IFt3cm9uZ0RrZ10gPSBhd2FpdCBNUFNVdGlsLmdlbmVyYXRlRWREc2FES0dLZXlTaGFyZXMoKTtcbiAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oJ2RlYWRiZWVmJywgJ2hleCcpO1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PlxuICAgICAgICBFRERTQVV0aWxzLnNpZ25SZWNvdmVyeUVkZHNhTVBDdjIoXG4gICAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgICBkZXJpdmF0aW9uUGF0aCxcbiAgICAgICAgICB1c2VyRGtnLmdldEtleVNoYXJlKCksXG4gICAgICAgICAgYmFja3VwRGtnLmdldEtleVNoYXJlKCksXG4gICAgICAgICAgd3JvbmdEa2cuZ2V0Q29tbW9uS2V5Y2hhaW4oKSAvLyBrZXkgY2hhaW4gZnJvbSBhIGRpZmZlcmVudCB3YWxsZXRcbiAgICAgICAgKSxcbiAgICAgIC9FZERTQSBNUEN2MiByZWNvdmVyeSBzaWduYXR1cmUgdmVyaWZpY2F0aW9uIGZhaWxlZC9cbiAgICApO1xuICB9KTtcbn0pO1xuIl19