@bitgo-beta/abstract-utxo 1.6.1-alpha.452 → 1.6.1-alpha.453

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 (187) hide show
  1. package/dist/cjs/src/abstractUtxoCoin.d.ts +10 -8
  2. package/dist/cjs/src/abstractUtxoCoin.d.ts.map +1 -1
  3. package/dist/cjs/src/abstractUtxoCoin.js +8 -12
  4. package/dist/cjs/src/impl/bch/bch.d.ts +4 -2
  5. package/dist/cjs/src/impl/bch/bch.d.ts.map +1 -1
  6. package/dist/cjs/src/impl/bch/bch.js +4 -3
  7. package/dist/cjs/src/impl/bch/tbch.d.ts +2 -0
  8. package/dist/cjs/src/impl/bch/tbch.d.ts.map +1 -1
  9. package/dist/cjs/src/impl/bch/tbch.js +3 -36
  10. package/dist/cjs/src/impl/bcha/bcha.d.ts +3 -2
  11. package/dist/cjs/src/impl/bcha/bcha.d.ts.map +1 -1
  12. package/dist/cjs/src/impl/bcha/bcha.js +4 -37
  13. package/dist/cjs/src/impl/bcha/tbcha.d.ts +2 -0
  14. package/dist/cjs/src/impl/bcha/tbcha.d.ts.map +1 -1
  15. package/dist/cjs/src/impl/bcha/tbcha.js +3 -36
  16. package/dist/cjs/src/impl/bsv/bsv.d.ts +3 -2
  17. package/dist/cjs/src/impl/bsv/bsv.d.ts.map +1 -1
  18. package/dist/cjs/src/impl/bsv/bsv.js +4 -37
  19. package/dist/cjs/src/impl/bsv/tbsv.d.ts +2 -0
  20. package/dist/cjs/src/impl/bsv/tbsv.d.ts.map +1 -1
  21. package/dist/cjs/src/impl/bsv/tbsv.js +3 -36
  22. package/dist/cjs/src/impl/btc/btc.d.ts +4 -2
  23. package/dist/cjs/src/impl/btc/btc.d.ts.map +1 -1
  24. package/dist/cjs/src/impl/btc/btc.js +4 -37
  25. package/dist/cjs/src/impl/btc/tbtc.d.ts +2 -0
  26. package/dist/cjs/src/impl/btc/tbtc.d.ts.map +1 -1
  27. package/dist/cjs/src/impl/btc/tbtc.js +3 -36
  28. package/dist/cjs/src/impl/btc/tbtc4.d.ts +2 -0
  29. package/dist/cjs/src/impl/btc/tbtc4.d.ts.map +1 -1
  30. package/dist/cjs/src/impl/btc/tbtc4.js +3 -36
  31. package/dist/cjs/src/impl/btc/tbtcbgsig.d.ts +2 -0
  32. package/dist/cjs/src/impl/btc/tbtcbgsig.d.ts.map +1 -1
  33. package/dist/cjs/src/impl/btc/tbtcbgsig.js +3 -36
  34. package/dist/cjs/src/impl/btc/tbtcsig.d.ts +2 -0
  35. package/dist/cjs/src/impl/btc/tbtcsig.d.ts.map +1 -1
  36. package/dist/cjs/src/impl/btc/tbtcsig.js +3 -36
  37. package/dist/cjs/src/impl/btg/btg.d.ts +4 -2
  38. package/dist/cjs/src/impl/btg/btg.d.ts.map +1 -1
  39. package/dist/cjs/src/impl/btg/btg.js +4 -37
  40. package/dist/cjs/src/impl/dash/dash.d.ts +4 -2
  41. package/dist/cjs/src/impl/dash/dash.d.ts.map +1 -1
  42. package/dist/cjs/src/impl/dash/dash.js +4 -37
  43. package/dist/cjs/src/impl/dash/tdash.d.ts +2 -0
  44. package/dist/cjs/src/impl/dash/tdash.d.ts.map +1 -1
  45. package/dist/cjs/src/impl/dash/tdash.js +3 -36
  46. package/dist/cjs/src/impl/doge/doge.d.ts +4 -2
  47. package/dist/cjs/src/impl/doge/doge.d.ts.map +1 -1
  48. package/dist/cjs/src/impl/doge/doge.js +4 -4
  49. package/dist/cjs/src/impl/doge/tdoge.d.ts +2 -0
  50. package/dist/cjs/src/impl/doge/tdoge.d.ts.map +1 -1
  51. package/dist/cjs/src/impl/doge/tdoge.js +3 -36
  52. package/dist/cjs/src/impl/ltc/ltc.d.ts +4 -2
  53. package/dist/cjs/src/impl/ltc/ltc.d.ts.map +1 -1
  54. package/dist/cjs/src/impl/ltc/ltc.js +4 -3
  55. package/dist/cjs/src/impl/ltc/tltc.d.ts +2 -0
  56. package/dist/cjs/src/impl/ltc/tltc.d.ts.map +1 -1
  57. package/dist/cjs/src/impl/ltc/tltc.js +3 -2
  58. package/dist/cjs/src/impl/zec/tzec.d.ts +2 -0
  59. package/dist/cjs/src/impl/zec/tzec.d.ts.map +1 -1
  60. package/dist/cjs/src/impl/zec/tzec.js +3 -36
  61. package/dist/cjs/src/impl/zec/zec.d.ts +4 -2
  62. package/dist/cjs/src/impl/zec/zec.d.ts.map +1 -1
  63. package/dist/cjs/src/impl/zec/zec.js +4 -37
  64. package/dist/cjs/src/names.d.ts +12 -4
  65. package/dist/cjs/src/names.d.ts.map +1 -1
  66. package/dist/cjs/src/names.js +66 -57
  67. package/dist/cjs/src/recovery/backupKeyRecovery.d.ts.map +1 -1
  68. package/dist/cjs/src/recovery/backupKeyRecovery.js +32 -17
  69. package/dist/cjs/src/recovery/crossChainRecovery.d.ts.map +1 -1
  70. package/dist/cjs/src/recovery/crossChainRecovery.js +25 -18
  71. package/dist/cjs/src/recovery/psbt.d.ts +6 -6
  72. package/dist/cjs/src/recovery/psbt.d.ts.map +1 -1
  73. package/dist/cjs/src/recovery/psbt.js +50 -36
  74. package/dist/cjs/src/tnumber.d.ts +4 -0
  75. package/dist/cjs/src/tnumber.d.ts.map +1 -0
  76. package/dist/cjs/src/tnumber.js +12 -0
  77. package/dist/cjs/src/transaction/fixedScript/SigningError.d.ts +1 -1
  78. package/dist/cjs/src/transaction/fixedScript/SigningError.d.ts.map +1 -1
  79. package/dist/cjs/src/transaction/fixedScript/SigningError.js +1 -1
  80. package/dist/cjs/src/transaction/fixedScript/{signPsbt.d.ts → signPsbtUtxolib.d.ts} +4 -13
  81. package/dist/cjs/src/transaction/fixedScript/signPsbtUtxolib.d.ts.map +1 -0
  82. package/dist/cjs/src/transaction/fixedScript/signPsbtUtxolib.js +157 -0
  83. package/dist/cjs/src/transaction/fixedScript/signPsbtWasm.d.ts +2 -7
  84. package/dist/cjs/src/transaction/fixedScript/signPsbtWasm.d.ts.map +1 -1
  85. package/dist/cjs/src/transaction/fixedScript/signPsbtWasm.js +3 -17
  86. package/dist/cjs/src/transaction/fixedScript/signTransaction.d.ts +7 -0
  87. package/dist/cjs/src/transaction/fixedScript/signTransaction.d.ts.map +1 -1
  88. package/dist/cjs/src/transaction/fixedScript/signTransaction.js +25 -6
  89. package/dist/cjs/src/wallet.js +2 -2
  90. package/dist/cjs/test/unit/coins.js +18 -1
  91. package/dist/cjs/test/unit/transaction/fixedScript/parsePsbt.js +2 -2
  92. package/dist/cjs/test/unit/transaction/fixedScript/signPsbt.js +4 -6
  93. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  94. package/dist/esm/abstractUtxoCoin.d.ts +10 -8
  95. package/dist/esm/abstractUtxoCoin.d.ts.map +1 -1
  96. package/dist/esm/abstractUtxoCoin.js +9 -13
  97. package/dist/esm/impl/bch/bch.d.ts +4 -2
  98. package/dist/esm/impl/bch/bch.d.ts.map +1 -1
  99. package/dist/esm/impl/bch/bch.js +4 -3
  100. package/dist/esm/impl/bch/tbch.d.ts +2 -0
  101. package/dist/esm/impl/bch/tbch.d.ts.map +1 -1
  102. package/dist/esm/impl/bch/tbch.js +3 -3
  103. package/dist/esm/impl/bcha/bcha.d.ts +3 -2
  104. package/dist/esm/impl/bcha/bcha.d.ts.map +1 -1
  105. package/dist/esm/impl/bcha/bcha.js +4 -4
  106. package/dist/esm/impl/bcha/tbcha.d.ts +2 -0
  107. package/dist/esm/impl/bcha/tbcha.d.ts.map +1 -1
  108. package/dist/esm/impl/bcha/tbcha.js +3 -3
  109. package/dist/esm/impl/bsv/bsv.d.ts +3 -2
  110. package/dist/esm/impl/bsv/bsv.d.ts.map +1 -1
  111. package/dist/esm/impl/bsv/bsv.js +4 -4
  112. package/dist/esm/impl/bsv/tbsv.d.ts +2 -0
  113. package/dist/esm/impl/bsv/tbsv.d.ts.map +1 -1
  114. package/dist/esm/impl/bsv/tbsv.js +3 -3
  115. package/dist/esm/impl/btc/btc.d.ts +4 -2
  116. package/dist/esm/impl/btc/btc.d.ts.map +1 -1
  117. package/dist/esm/impl/btc/btc.js +4 -4
  118. package/dist/esm/impl/btc/tbtc.d.ts +2 -0
  119. package/dist/esm/impl/btc/tbtc.d.ts.map +1 -1
  120. package/dist/esm/impl/btc/tbtc.js +3 -3
  121. package/dist/esm/impl/btc/tbtc4.d.ts +2 -0
  122. package/dist/esm/impl/btc/tbtc4.d.ts.map +1 -1
  123. package/dist/esm/impl/btc/tbtc4.js +3 -3
  124. package/dist/esm/impl/btc/tbtcbgsig.d.ts +2 -0
  125. package/dist/esm/impl/btc/tbtcbgsig.d.ts.map +1 -1
  126. package/dist/esm/impl/btc/tbtcbgsig.js +3 -3
  127. package/dist/esm/impl/btc/tbtcsig.d.ts +2 -0
  128. package/dist/esm/impl/btc/tbtcsig.d.ts.map +1 -1
  129. package/dist/esm/impl/btc/tbtcsig.js +3 -3
  130. package/dist/esm/impl/btg/btg.d.ts +4 -2
  131. package/dist/esm/impl/btg/btg.d.ts.map +1 -1
  132. package/dist/esm/impl/btg/btg.js +4 -4
  133. package/dist/esm/impl/dash/dash.d.ts +4 -2
  134. package/dist/esm/impl/dash/dash.d.ts.map +1 -1
  135. package/dist/esm/impl/dash/dash.js +4 -4
  136. package/dist/esm/impl/dash/tdash.d.ts +2 -0
  137. package/dist/esm/impl/dash/tdash.d.ts.map +1 -1
  138. package/dist/esm/impl/dash/tdash.js +3 -3
  139. package/dist/esm/impl/doge/doge.d.ts +4 -2
  140. package/dist/esm/impl/doge/doge.d.ts.map +1 -1
  141. package/dist/esm/impl/doge/doge.js +4 -4
  142. package/dist/esm/impl/doge/tdoge.d.ts +2 -0
  143. package/dist/esm/impl/doge/tdoge.d.ts.map +1 -1
  144. package/dist/esm/impl/doge/tdoge.js +3 -3
  145. package/dist/esm/impl/ltc/ltc.d.ts +4 -2
  146. package/dist/esm/impl/ltc/ltc.d.ts.map +1 -1
  147. package/dist/esm/impl/ltc/ltc.js +4 -3
  148. package/dist/esm/impl/ltc/tltc.d.ts +2 -0
  149. package/dist/esm/impl/ltc/tltc.d.ts.map +1 -1
  150. package/dist/esm/impl/ltc/tltc.js +3 -2
  151. package/dist/esm/impl/zec/tzec.d.ts +2 -0
  152. package/dist/esm/impl/zec/tzec.d.ts.map +1 -1
  153. package/dist/esm/impl/zec/tzec.js +3 -3
  154. package/dist/esm/impl/zec/zec.d.ts +4 -2
  155. package/dist/esm/impl/zec/zec.d.ts.map +1 -1
  156. package/dist/esm/impl/zec/zec.js +4 -4
  157. package/dist/esm/names.d.ts +12 -4
  158. package/dist/esm/names.d.ts.map +1 -1
  159. package/dist/esm/names.js +61 -54
  160. package/dist/esm/recovery/backupKeyRecovery.d.ts.map +1 -1
  161. package/dist/esm/recovery/backupKeyRecovery.js +33 -18
  162. package/dist/esm/recovery/crossChainRecovery.d.ts.map +1 -1
  163. package/dist/esm/recovery/crossChainRecovery.js +26 -19
  164. package/dist/esm/recovery/psbt.d.ts +6 -6
  165. package/dist/esm/recovery/psbt.d.ts.map +1 -1
  166. package/dist/esm/recovery/psbt.js +50 -36
  167. package/dist/esm/tnumber.d.ts +4 -0
  168. package/dist/esm/tnumber.d.ts.map +1 -0
  169. package/dist/esm/tnumber.js +9 -0
  170. package/dist/esm/transaction/fixedScript/SigningError.d.ts +1 -1
  171. package/dist/esm/transaction/fixedScript/SigningError.d.ts.map +1 -1
  172. package/dist/esm/transaction/fixedScript/SigningError.js +1 -1
  173. package/dist/esm/transaction/fixedScript/{signPsbt.d.ts → signPsbtUtxolib.d.ts} +4 -13
  174. package/dist/esm/transaction/fixedScript/signPsbtUtxolib.d.ts.map +1 -0
  175. package/dist/esm/transaction/fixedScript/signPsbtUtxolib.js +117 -0
  176. package/dist/esm/transaction/fixedScript/signPsbtWasm.d.ts +2 -7
  177. package/dist/esm/transaction/fixedScript/signPsbtWasm.d.ts.map +1 -1
  178. package/dist/esm/transaction/fixedScript/signPsbtWasm.js +3 -17
  179. package/dist/esm/transaction/fixedScript/signTransaction.d.ts +7 -0
  180. package/dist/esm/transaction/fixedScript/signTransaction.d.ts.map +1 -1
  181. package/dist/esm/transaction/fixedScript/signTransaction.js +25 -7
  182. package/dist/esm/wallet.js +2 -2
  183. package/package.json +11 -11
  184. package/dist/cjs/src/transaction/fixedScript/signPsbt.d.ts.map +0 -1
  185. package/dist/cjs/src/transaction/fixedScript/signPsbt.js +0 -174
  186. package/dist/esm/transaction/fixedScript/signPsbt.d.ts.map +0 -1
  187. package/dist/esm/transaction/fixedScript/signPsbt.js +0 -134
@@ -1,134 +0,0 @@
1
- import assert from 'assert';
2
- import * as utxolib from '@bitgo-beta/utxo-lib';
3
- import { bitgo } from '@bitgo-beta/utxo-lib';
4
- import debugLib from 'debug';
5
- import { InputSigningError, TransactionSigningError } from './SigningError';
6
- const debug = debugLib('bitgo:v2:utxo');
7
- /**
8
- * Sign all inputs of a psbt and verify signatures after signing.
9
- * Collects and logs signing errors and verification errors, throws error in the end if any of them
10
- * failed.
11
- *
12
- * If it is the last signature, finalize and extract the transaction from the psbt.
13
- *
14
- * This function mirrors signAndVerifyWalletTransaction, but is used for signing PSBTs instead of
15
- * using TransactionBuilder
16
- *
17
- * @param psbt
18
- * @param signerKeychain
19
- * @param isLastSignature
20
- */
21
- export function signAndVerifyPsbt(psbt, signerKeychain, { isLastSignature,
22
- /** deprecated */
23
- allowNonSegwitSigningWithoutPrevTx, }) {
24
- const txInputs = psbt.txInputs;
25
- const outputIds = [];
26
- const scriptTypes = [];
27
- const signErrors = psbt.data.inputs
28
- .map((input, inputIndex) => {
29
- const outputId = utxolib.bitgo.formatOutputId(utxolib.bitgo.getOutputIdForInput(txInputs[inputIndex]));
30
- outputIds.push(outputId);
31
- const { scriptType } = utxolib.bitgo.parsePsbtInput(input);
32
- scriptTypes.push(scriptType);
33
- if (scriptType === 'p2shP2pk') {
34
- debug('Skipping signature for input %d of %d (RP input?)', inputIndex + 1, psbt.data.inputs.length);
35
- return;
36
- }
37
- try {
38
- psbt.signInputHD(inputIndex, signerKeychain);
39
- debug('Successfully signed input %d of %d', inputIndex + 1, psbt.data.inputs.length);
40
- }
41
- catch (e) {
42
- return new InputSigningError(inputIndex, scriptType, { id: outputId }, e);
43
- }
44
- })
45
- .filter((e) => e !== undefined);
46
- const verifyErrors = psbt.data.inputs
47
- .map((input, inputIndex) => {
48
- const scriptType = scriptTypes[inputIndex];
49
- if (scriptType === 'p2shP2pk') {
50
- debug('Skipping input signature %d of %d (unspent from replay protection address which is platform signed only)', inputIndex + 1, psbt.data.inputs.length);
51
- return;
52
- }
53
- const outputId = outputIds[inputIndex];
54
- try {
55
- if (!psbt.validateSignaturesOfInputHD(inputIndex, signerKeychain)) {
56
- return new InputSigningError(inputIndex, scriptType, { id: outputId }, new Error(`invalid signature`));
57
- }
58
- }
59
- catch (e) {
60
- debug('Invalid signature');
61
- return new InputSigningError(inputIndex, scriptType, { id: outputId }, e);
62
- }
63
- })
64
- .filter((e) => e !== undefined);
65
- if (signErrors.length || verifyErrors.length) {
66
- throw new TransactionSigningError(signErrors, verifyErrors);
67
- }
68
- if (isLastSignature) {
69
- psbt.finalizeAllInputs();
70
- return psbt.extractTransaction();
71
- }
72
- return psbt;
73
- }
74
- /**
75
- * Key Value: Unsigned tx id => PSBT
76
- * It is used to cache PSBTs with taproot key path (MuSig2) inputs during external express signer is activated.
77
- * Reason: MuSig2 signer secure nonce is cached in the UtxoPsbt object. It will be required during the signing step.
78
- * For more info, check SignTransactionOptions.signingStep
79
- *
80
- * TODO BTC-276: This cache may need to be done with LRU like memory safe caching if memory issues comes up.
81
- */
82
- const PSBT_CACHE = new Map();
83
- export async function signPsbtWithMusig2Participant(coin, tx, signerKeychain, params) {
84
- if (bitgo.isTransactionWithKeyPathSpendInput(tx)) {
85
- // We can only be the first signature on a transaction with taproot key path spend inputs because
86
- // we require the secret nonce in the cache of the first signer, which is impossible to retrieve if
87
- // deserialized from a hex.
88
- if (params.isLastSignature) {
89
- throw new Error('Cannot be last signature on a transaction with key path spend inputs');
90
- }
91
- switch (params.signingStep) {
92
- case 'signerNonce':
93
- assert(signerKeychain);
94
- tx.setAllInputsMusig2NonceHD(signerKeychain);
95
- PSBT_CACHE.set(tx.getUnsignedTx().getId(), tx);
96
- return tx;
97
- case 'cosignerNonce':
98
- assert(params.walletId, 'walletId is required for MuSig2 bitgo nonce');
99
- return await coin.getMusig2Nonces(tx, params.walletId);
100
- case 'signerSignature':
101
- const txId = tx.getUnsignedTx().getId();
102
- const psbt = PSBT_CACHE.get(txId);
103
- assert(psbt, `Psbt is missing from txCache (cache size ${PSBT_CACHE.size}).
104
- This may be due to the request being routed to a different BitGo-Express instance that for signing step 'signerNonce'.`);
105
- PSBT_CACHE.delete(txId);
106
- tx = psbt.combine(tx);
107
- break;
108
- default:
109
- // this instance is not an external signer
110
- assert(params.walletId, 'walletId is required for MuSig2 bitgo nonce');
111
- assert(signerKeychain);
112
- tx.setAllInputsMusig2NonceHD(signerKeychain);
113
- const response = await coin.getMusig2Nonces(tx, params.walletId);
114
- tx = tx.combine(response);
115
- break;
116
- }
117
- }
118
- else {
119
- switch (params.signingStep) {
120
- case 'signerNonce':
121
- case 'cosignerNonce':
122
- /**
123
- * In certain cases, the caller of this method may not know whether the txHex contains a psbt with taproot key path spend input(s).
124
- * Instead of throwing error, no-op and return the txHex. So that the caller can call this method in the same sequence.
125
- */
126
- return tx;
127
- }
128
- }
129
- assert(signerKeychain);
130
- return signAndVerifyPsbt(tx, signerKeychain, {
131
- isLastSignature: params.isLastSignature,
132
- });
133
- }
134
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnblBzYnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdHJhbnNhY3Rpb24vZml4ZWRTY3JpcHQvc2lnblBzYnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBRTVCLE9BQU8sS0FBSyxPQUFPLE1BQU0sc0JBQXNCLENBQUM7QUFFaEQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzdDLE9BQU8sUUFBUSxNQUFNLE9BQU8sQ0FBQztBQUU3QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUc1RSxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7QUFjeEM7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FDL0IsSUFBNEIsRUFDNUIsY0FBc0MsRUFDdEMsRUFDRSxlQUFlO0FBQ2YsaUJBQWlCO0FBQ2pCLGtDQUFrQyxHQUN5QztJQUU3RSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQy9CLE1BQU0sU0FBUyxHQUFhLEVBQUUsQ0FBQztJQUMvQixNQUFNLFdBQVcsR0FBMkIsRUFBRSxDQUFDO0lBRS9DLE1BQU0sVUFBVSxHQUFnQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU07U0FDN0QsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLFVBQWtCLEVBQUUsRUFBRTtRQUNqQyxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkcsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUV6QixNQUFNLEVBQUUsVUFBVSxFQUFFLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0QsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUU3QixJQUFJLFVBQVUsS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUM5QixLQUFLLENBQUMsbURBQW1ELEVBQUUsVUFBVSxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNwRyxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQztZQUNILElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1lBQzdDLEtBQUssQ0FBQyxvQ0FBb0MsRUFBRSxVQUFVLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZGLENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsT0FBTyxJQUFJLGlCQUFpQixDQUFTLFVBQVUsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDcEYsQ0FBQztJQUNILENBQUMsQ0FBQztTQUNELE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBa0MsRUFBRSxDQUFDLENBQUMsS0FBSyxTQUFTLENBQUMsQ0FBQztJQUVsRSxNQUFNLFlBQVksR0FBZ0MsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNO1NBQy9ELEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxVQUFVLEVBQUUsRUFBRTtRQUN6QixNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDM0MsSUFBSSxVQUFVLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDOUIsS0FBSyxDQUNILDBHQUEwRyxFQUMxRyxVQUFVLEdBQUcsQ0FBQyxFQUNkLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FDeEIsQ0FBQztZQUNGLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQztZQUNILElBQUksQ0FBQyxJQUFJLENBQUMsMkJBQTJCLENBQUMsVUFBVSxFQUFFLGNBQWMsQ0FBQyxFQUFFLENBQUM7Z0JBQ2xFLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxFQUFFLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztZQUN6RyxDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDWCxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQztZQUMzQixPQUFPLElBQUksaUJBQWlCLENBQVMsVUFBVSxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNwRixDQUFDO0lBQ0gsQ0FBQyxDQUFDO1NBQ0QsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFrQyxFQUFFLENBQUMsQ0FBQyxLQUFLLFNBQVMsQ0FBQyxDQUFDO0lBRWxFLElBQUksVUFBVSxDQUFDLE1BQU0sSUFBSSxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDN0MsTUFBTSxJQUFJLHVCQUF1QixDQUFDLFVBQVUsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBRUQsSUFBSSxlQUFlLEVBQUUsQ0FBQztRQUNwQixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUN6QixPQUFPLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQ25DLENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLEdBQUcsSUFBSSxHQUFHLEVBQWtDLENBQUM7QUFFN0QsTUFBTSxDQUFDLEtBQUssVUFBVSw2QkFBNkIsQ0FDakQsSUFBK0MsRUFDL0MsRUFBMEIsRUFDMUIsY0FBMEMsRUFDMUMsTUFJQztJQUVELElBQUksS0FBSyxDQUFDLGtDQUFrQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFDakQsaUdBQWlHO1FBQ2pHLG1HQUFtRztRQUNuRywyQkFBMkI7UUFDM0IsSUFBSSxNQUFNLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FBQyxzRUFBc0UsQ0FBQyxDQUFDO1FBQzFGLENBQUM7UUFFRCxRQUFRLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUMzQixLQUFLLGFBQWE7Z0JBQ2hCLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztnQkFDdkIsRUFBRSxDQUFDLHlCQUF5QixDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUM3QyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDL0MsT0FBTyxFQUFFLENBQUM7WUFDWixLQUFLLGVBQWU7Z0JBQ2xCLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLDZDQUE2QyxDQUFDLENBQUM7Z0JBQ3ZFLE9BQU8sTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDekQsS0FBSyxpQkFBaUI7Z0JBQ3BCLE1BQU0sSUFBSSxHQUFHLEVBQUUsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDeEMsTUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDbEMsTUFBTSxDQUNKLElBQUksRUFDSiw0Q0FBNEMsVUFBVSxDQUFDLElBQUk7bUlBQzhELENBQzFILENBQUM7Z0JBQ0YsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDeEIsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ3RCLE1BQU07WUFDUjtnQkFDRSwwQ0FBMEM7Z0JBQzFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLDZDQUE2QyxDQUFDLENBQUM7Z0JBQ3ZFLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztnQkFDdkIsRUFBRSxDQUFDLHlCQUF5QixDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUM3QyxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDakUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQzFCLE1BQU07UUFDVixDQUFDO0lBQ0gsQ0FBQztTQUFNLENBQUM7UUFDTixRQUFRLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUMzQixLQUFLLGFBQWEsQ0FBQztZQUNuQixLQUFLLGVBQWU7Z0JBQ2xCOzs7bUJBR0c7Z0JBQ0gsT0FBTyxFQUFFLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUN2QixPQUFPLGlCQUFpQixDQUFDLEVBQUUsRUFBRSxjQUFjLEVBQUU7UUFDM0MsZUFBZSxFQUFFLE1BQU0sQ0FBQyxlQUFlO0tBQ3hDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCAqIGFzIHV0eG9saWIgZnJvbSAnQGJpdGdvLWJldGEvdXR4by1saWInO1xuaW1wb3J0IHsgQklQMzJJbnRlcmZhY2UgfSBmcm9tICdAYml0Z28tYmV0YS9zZWNwMjU2azEnO1xuaW1wb3J0IHsgYml0Z28gfSBmcm9tICdAYml0Z28tYmV0YS91dHhvLWxpYic7XG5pbXBvcnQgZGVidWdMaWIgZnJvbSAnZGVidWcnO1xuXG5pbXBvcnQgeyBJbnB1dFNpZ25pbmdFcnJvciwgVHJhbnNhY3Rpb25TaWduaW5nRXJyb3IgfSBmcm9tICcuL1NpZ25pbmdFcnJvcic7XG5pbXBvcnQgeyBNdXNpZzJQYXJ0aWNpcGFudCB9IGZyb20gJy4vbXVzaWcyJztcblxuY29uc3QgZGVidWcgPSBkZWJ1Z0xpYignYml0Z286djI6dXR4bycpO1xuXG5leHBvcnQgdHlwZSBQc2J0UGFyc2VkU2NyaXB0VHlwZSA9XG4gIHwgJ3Ayc2gnXG4gIHwgJ3Ayd3NoJ1xuICB8ICdwMnNoUDJ3c2gnXG4gIHwgJ3Ayc2hQMnBrJ1xuICB8ICd0YXByb290S2V5UGF0aFNwZW5kJ1xuICB8ICd0YXByb290U2NyaXB0UGF0aFNwZW5kJ1xuICAvLyB3YXNtLXV0eG8gdHlwZXNcbiAgfCAncDJ0ckxlZ2FjeSdcbiAgfCAncDJ0ck11c2lnMlNjcmlwdFBhdGgnXG4gIHwgJ3AydHJNdXNpZzJLZXlQYXRoJztcblxuLyoqXG4gKiBTaWduIGFsbCBpbnB1dHMgb2YgYSBwc2J0IGFuZCB2ZXJpZnkgc2lnbmF0dXJlcyBhZnRlciBzaWduaW5nLlxuICogQ29sbGVjdHMgYW5kIGxvZ3Mgc2lnbmluZyBlcnJvcnMgYW5kIHZlcmlmaWNhdGlvbiBlcnJvcnMsIHRocm93cyBlcnJvciBpbiB0aGUgZW5kIGlmIGFueSBvZiB0aGVtXG4gKiBmYWlsZWQuXG4gKlxuICogSWYgaXQgaXMgdGhlIGxhc3Qgc2lnbmF0dXJlLCBmaW5hbGl6ZSBhbmQgZXh0cmFjdCB0aGUgdHJhbnNhY3Rpb24gZnJvbSB0aGUgcHNidC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIG1pcnJvcnMgc2lnbkFuZFZlcmlmeVdhbGxldFRyYW5zYWN0aW9uLCBidXQgaXMgdXNlZCBmb3Igc2lnbmluZyBQU0JUcyBpbnN0ZWFkIG9mXG4gKiB1c2luZyBUcmFuc2FjdGlvbkJ1aWxkZXJcbiAqXG4gKiBAcGFyYW0gcHNidFxuICogQHBhcmFtIHNpZ25lcktleWNoYWluXG4gKiBAcGFyYW0gaXNMYXN0U2lnbmF0dXJlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzaWduQW5kVmVyaWZ5UHNidChcbiAgcHNidDogdXR4b2xpYi5iaXRnby5VdHhvUHNidCxcbiAgc2lnbmVyS2V5Y2hhaW46IHV0eG9saWIuQklQMzJJbnRlcmZhY2UsXG4gIHtcbiAgICBpc0xhc3RTaWduYXR1cmUsXG4gICAgLyoqIGRlcHJlY2F0ZWQgKi9cbiAgICBhbGxvd05vblNlZ3dpdFNpZ25pbmdXaXRob3V0UHJldlR4LFxuICB9OiB7IGlzTGFzdFNpZ25hdHVyZTogYm9vbGVhbjsgYWxsb3dOb25TZWd3aXRTaWduaW5nV2l0aG91dFByZXZUeD86IGJvb2xlYW4gfVxuKTogdXR4b2xpYi5iaXRnby5VdHhvUHNidCB8IHV0eG9saWIuYml0Z28uVXR4b1RyYW5zYWN0aW9uPGJpZ2ludD4ge1xuICBjb25zdCB0eElucHV0cyA9IHBzYnQudHhJbnB1dHM7XG4gIGNvbnN0IG91dHB1dElkczogc3RyaW5nW10gPSBbXTtcbiAgY29uc3Qgc2NyaXB0VHlwZXM6IFBzYnRQYXJzZWRTY3JpcHRUeXBlW10gPSBbXTtcblxuICBjb25zdCBzaWduRXJyb3JzOiBJbnB1dFNpZ25pbmdFcnJvcjxiaWdpbnQ+W10gPSBwc2J0LmRhdGEuaW5wdXRzXG4gICAgLm1hcCgoaW5wdXQsIGlucHV0SW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgY29uc3Qgb3V0cHV0SWQgPSB1dHhvbGliLmJpdGdvLmZvcm1hdE91dHB1dElkKHV0eG9saWIuYml0Z28uZ2V0T3V0cHV0SWRGb3JJbnB1dCh0eElucHV0c1tpbnB1dEluZGV4XSkpO1xuICAgICAgb3V0cHV0SWRzLnB1c2gob3V0cHV0SWQpO1xuXG4gICAgICBjb25zdCB7IHNjcmlwdFR5cGUgfSA9IHV0eG9saWIuYml0Z28ucGFyc2VQc2J0SW5wdXQoaW5wdXQpO1xuICAgICAgc2NyaXB0VHlwZXMucHVzaChzY3JpcHRUeXBlKTtcblxuICAgICAgaWYgKHNjcmlwdFR5cGUgPT09ICdwMnNoUDJwaycpIHtcbiAgICAgICAgZGVidWcoJ1NraXBwaW5nIHNpZ25hdHVyZSBmb3IgaW5wdXQgJWQgb2YgJWQgKFJQIGlucHV0PyknLCBpbnB1dEluZGV4ICsgMSwgcHNidC5kYXRhLmlucHV0cy5sZW5ndGgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHBzYnQuc2lnbklucHV0SEQoaW5wdXRJbmRleCwgc2lnbmVyS2V5Y2hhaW4pO1xuICAgICAgICBkZWJ1ZygnU3VjY2Vzc2Z1bGx5IHNpZ25lZCBpbnB1dCAlZCBvZiAlZCcsIGlucHV0SW5kZXggKyAxLCBwc2J0LmRhdGEuaW5wdXRzLmxlbmd0aCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBuZXcgSW5wdXRTaWduaW5nRXJyb3I8YmlnaW50PihpbnB1dEluZGV4LCBzY3JpcHRUeXBlLCB7IGlkOiBvdXRwdXRJZCB9LCBlKTtcbiAgICAgIH1cbiAgICB9KVxuICAgIC5maWx0ZXIoKGUpOiBlIGlzIElucHV0U2lnbmluZ0Vycm9yPGJpZ2ludD4gPT4gZSAhPT0gdW5kZWZpbmVkKTtcblxuICBjb25zdCB2ZXJpZnlFcnJvcnM6IElucHV0U2lnbmluZ0Vycm9yPGJpZ2ludD5bXSA9IHBzYnQuZGF0YS5pbnB1dHNcbiAgICAubWFwKChpbnB1dCwgaW5wdXRJbmRleCkgPT4ge1xuICAgICAgY29uc3Qgc2NyaXB0VHlwZSA9IHNjcmlwdFR5cGVzW2lucHV0SW5kZXhdO1xuICAgICAgaWYgKHNjcmlwdFR5cGUgPT09ICdwMnNoUDJwaycpIHtcbiAgICAgICAgZGVidWcoXG4gICAgICAgICAgJ1NraXBwaW5nIGlucHV0IHNpZ25hdHVyZSAlZCBvZiAlZCAodW5zcGVudCBmcm9tIHJlcGxheSBwcm90ZWN0aW9uIGFkZHJlc3Mgd2hpY2ggaXMgcGxhdGZvcm0gc2lnbmVkIG9ubHkpJyxcbiAgICAgICAgICBpbnB1dEluZGV4ICsgMSxcbiAgICAgICAgICBwc2J0LmRhdGEuaW5wdXRzLmxlbmd0aFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG91dHB1dElkID0gb3V0cHV0SWRzW2lucHV0SW5kZXhdO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCFwc2J0LnZhbGlkYXRlU2lnbmF0dXJlc09mSW5wdXRIRChpbnB1dEluZGV4LCBzaWduZXJLZXljaGFpbikpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IElucHV0U2lnbmluZ0Vycm9yKGlucHV0SW5kZXgsIHNjcmlwdFR5cGUsIHsgaWQ6IG91dHB1dElkIH0sIG5ldyBFcnJvcihgaW52YWxpZCBzaWduYXR1cmVgKSk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgZGVidWcoJ0ludmFsaWQgc2lnbmF0dXJlJyk7XG4gICAgICAgIHJldHVybiBuZXcgSW5wdXRTaWduaW5nRXJyb3I8YmlnaW50PihpbnB1dEluZGV4LCBzY3JpcHRUeXBlLCB7IGlkOiBvdXRwdXRJZCB9LCBlKTtcbiAgICAgIH1cbiAgICB9KVxuICAgIC5maWx0ZXIoKGUpOiBlIGlzIElucHV0U2lnbmluZ0Vycm9yPGJpZ2ludD4gPT4gZSAhPT0gdW5kZWZpbmVkKTtcblxuICBpZiAoc2lnbkVycm9ycy5sZW5ndGggfHwgdmVyaWZ5RXJyb3JzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBUcmFuc2FjdGlvblNpZ25pbmdFcnJvcihzaWduRXJyb3JzLCB2ZXJpZnlFcnJvcnMpO1xuICB9XG5cbiAgaWYgKGlzTGFzdFNpZ25hdHVyZSkge1xuICAgIHBzYnQuZmluYWxpemVBbGxJbnB1dHMoKTtcbiAgICByZXR1cm4gcHNidC5leHRyYWN0VHJhbnNhY3Rpb24oKTtcbiAgfVxuXG4gIHJldHVybiBwc2J0O1xufVxuXG4vKipcbiAqIEtleSBWYWx1ZTogVW5zaWduZWQgdHggaWQgPT4gUFNCVFxuICogSXQgaXMgdXNlZCB0byBjYWNoZSBQU0JUcyB3aXRoIHRhcHJvb3Qga2V5IHBhdGggKE11U2lnMikgaW5wdXRzIGR1cmluZyBleHRlcm5hbCBleHByZXNzIHNpZ25lciBpcyBhY3RpdmF0ZWQuXG4gKiBSZWFzb246IE11U2lnMiBzaWduZXIgc2VjdXJlIG5vbmNlIGlzIGNhY2hlZCBpbiB0aGUgVXR4b1BzYnQgb2JqZWN0LiBJdCB3aWxsIGJlIHJlcXVpcmVkIGR1cmluZyB0aGUgc2lnbmluZyBzdGVwLlxuICogRm9yIG1vcmUgaW5mbywgY2hlY2sgU2lnblRyYW5zYWN0aW9uT3B0aW9ucy5zaWduaW5nU3RlcFxuICpcbiAqIFRPRE8gQlRDLTI3NjogVGhpcyBjYWNoZSBtYXkgbmVlZCB0byBiZSBkb25lIHdpdGggTFJVIGxpa2UgbWVtb3J5IHNhZmUgY2FjaGluZyBpZiBtZW1vcnkgaXNzdWVzIGNvbWVzIHVwLlxuICovXG5jb25zdCBQU0JUX0NBQ0hFID0gbmV3IE1hcDxzdHJpbmcsIHV0eG9saWIuYml0Z28uVXR4b1BzYnQ+KCk7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaWduUHNidFdpdGhNdXNpZzJQYXJ0aWNpcGFudChcbiAgY29pbjogTXVzaWcyUGFydGljaXBhbnQ8dXR4b2xpYi5iaXRnby5VdHhvUHNidD4sXG4gIHR4OiB1dHhvbGliLmJpdGdvLlV0eG9Qc2J0LFxuICBzaWduZXJLZXljaGFpbjogQklQMzJJbnRlcmZhY2UgfCB1bmRlZmluZWQsXG4gIHBhcmFtczoge1xuICAgIGlzTGFzdFNpZ25hdHVyZTogYm9vbGVhbjtcbiAgICBzaWduaW5nU3RlcDogJ3NpZ25lck5vbmNlJyB8ICdjb3NpZ25lck5vbmNlJyB8ICdzaWduZXJTaWduYXR1cmUnIHwgdW5kZWZpbmVkO1xuICAgIHdhbGxldElkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIH1cbik6IFByb21pc2U8dXR4b2xpYi5iaXRnby5VdHhvUHNidCB8IHV0eG9saWIuYml0Z28uVXR4b1RyYW5zYWN0aW9uPGJpZ2ludD4+IHtcbiAgaWYgKGJpdGdvLmlzVHJhbnNhY3Rpb25XaXRoS2V5UGF0aFNwZW5kSW5wdXQodHgpKSB7XG4gICAgLy8gV2UgY2FuIG9ubHkgYmUgdGhlIGZpcnN0IHNpZ25hdHVyZSBvbiBhIHRyYW5zYWN0aW9uIHdpdGggdGFwcm9vdCBrZXkgcGF0aCBzcGVuZCBpbnB1dHMgYmVjYXVzZVxuICAgIC8vIHdlIHJlcXVpcmUgdGhlIHNlY3JldCBub25jZSBpbiB0aGUgY2FjaGUgb2YgdGhlIGZpcnN0IHNpZ25lciwgd2hpY2ggaXMgaW1wb3NzaWJsZSB0byByZXRyaWV2ZSBpZlxuICAgIC8vIGRlc2VyaWFsaXplZCBmcm9tIGEgaGV4LlxuICAgIGlmIChwYXJhbXMuaXNMYXN0U2lnbmF0dXJlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBiZSBsYXN0IHNpZ25hdHVyZSBvbiBhIHRyYW5zYWN0aW9uIHdpdGgga2V5IHBhdGggc3BlbmQgaW5wdXRzJyk7XG4gICAgfVxuXG4gICAgc3dpdGNoIChwYXJhbXMuc2lnbmluZ1N0ZXApIHtcbiAgICAgIGNhc2UgJ3NpZ25lck5vbmNlJzpcbiAgICAgICAgYXNzZXJ0KHNpZ25lcktleWNoYWluKTtcbiAgICAgICAgdHguc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChzaWduZXJLZXljaGFpbik7XG4gICAgICAgIFBTQlRfQ0FDSEUuc2V0KHR4LmdldFVuc2lnbmVkVHgoKS5nZXRJZCgpLCB0eCk7XG4gICAgICAgIHJldHVybiB0eDtcbiAgICAgIGNhc2UgJ2Nvc2lnbmVyTm9uY2UnOlxuICAgICAgICBhc3NlcnQocGFyYW1zLndhbGxldElkLCAnd2FsbGV0SWQgaXMgcmVxdWlyZWQgZm9yIE11U2lnMiBiaXRnbyBub25jZScpO1xuICAgICAgICByZXR1cm4gYXdhaXQgY29pbi5nZXRNdXNpZzJOb25jZXModHgsIHBhcmFtcy53YWxsZXRJZCk7XG4gICAgICBjYXNlICdzaWduZXJTaWduYXR1cmUnOlxuICAgICAgICBjb25zdCB0eElkID0gdHguZ2V0VW5zaWduZWRUeCgpLmdldElkKCk7XG4gICAgICAgIGNvbnN0IHBzYnQgPSBQU0JUX0NBQ0hFLmdldCh0eElkKTtcbiAgICAgICAgYXNzZXJ0KFxuICAgICAgICAgIHBzYnQsXG4gICAgICAgICAgYFBzYnQgaXMgbWlzc2luZyBmcm9tIHR4Q2FjaGUgKGNhY2hlIHNpemUgJHtQU0JUX0NBQ0hFLnNpemV9KS5cbiAgICAgICAgICAgIFRoaXMgbWF5IGJlIGR1ZSB0byB0aGUgcmVxdWVzdCBiZWluZyByb3V0ZWQgdG8gYSBkaWZmZXJlbnQgQml0R28tRXhwcmVzcyBpbnN0YW5jZSB0aGF0IGZvciBzaWduaW5nIHN0ZXAgJ3NpZ25lck5vbmNlJy5gXG4gICAgICAgICk7XG4gICAgICAgIFBTQlRfQ0FDSEUuZGVsZXRlKHR4SWQpO1xuICAgICAgICB0eCA9IHBzYnQuY29tYmluZSh0eCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgLy8gdGhpcyBpbnN0YW5jZSBpcyBub3QgYW4gZXh0ZXJuYWwgc2lnbmVyXG4gICAgICAgIGFzc2VydChwYXJhbXMud2FsbGV0SWQsICd3YWxsZXRJZCBpcyByZXF1aXJlZCBmb3IgTXVTaWcyIGJpdGdvIG5vbmNlJyk7XG4gICAgICAgIGFzc2VydChzaWduZXJLZXljaGFpbik7XG4gICAgICAgIHR4LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQoc2lnbmVyS2V5Y2hhaW4pO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNvaW4uZ2V0TXVzaWcyTm9uY2VzKHR4LCBwYXJhbXMud2FsbGV0SWQpO1xuICAgICAgICB0eCA9IHR4LmNvbWJpbmUocmVzcG9uc2UpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgc3dpdGNoIChwYXJhbXMuc2lnbmluZ1N0ZXApIHtcbiAgICAgIGNhc2UgJ3NpZ25lck5vbmNlJzpcbiAgICAgIGNhc2UgJ2Nvc2lnbmVyTm9uY2UnOlxuICAgICAgICAvKipcbiAgICAgICAgICogSW4gY2VydGFpbiBjYXNlcywgdGhlIGNhbGxlciBvZiB0aGlzIG1ldGhvZCBtYXkgbm90IGtub3cgd2hldGhlciB0aGUgdHhIZXggY29udGFpbnMgYSBwc2J0IHdpdGggdGFwcm9vdCBrZXkgcGF0aCBzcGVuZCBpbnB1dChzKS5cbiAgICAgICAgICogSW5zdGVhZCBvZiB0aHJvd2luZyBlcnJvciwgbm8tb3AgYW5kIHJldHVybiB0aGUgdHhIZXguIFNvIHRoYXQgdGhlIGNhbGxlciBjYW4gY2FsbCB0aGlzIG1ldGhvZCBpbiB0aGUgc2FtZSBzZXF1ZW5jZS5cbiAgICAgICAgICovXG4gICAgICAgIHJldHVybiB0eDtcbiAgICB9XG4gIH1cblxuICBhc3NlcnQoc2lnbmVyS2V5Y2hhaW4pO1xuICByZXR1cm4gc2lnbkFuZFZlcmlmeVBzYnQodHgsIHNpZ25lcktleWNoYWluLCB7XG4gICAgaXNMYXN0U2lnbmF0dXJlOiBwYXJhbXMuaXNMYXN0U2lnbmF0dXJlLFxuICB9KTtcbn1cbiJdfQ==