@bitgo-beta/abstract-eth 1.2.3-alpha.26 → 1.2.3-alpha.261

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 (88) hide show
  1. package/CHANGELOG.md +1521 -0
  2. package/dist/src/abstractEthLikeCoin.d.ts +13 -8
  3. package/dist/src/abstractEthLikeCoin.d.ts.map +1 -1
  4. package/dist/src/abstractEthLikeCoin.js +16 -13
  5. package/dist/src/abstractEthLikeNewCoins.d.ts +647 -0
  6. package/dist/src/abstractEthLikeNewCoins.d.ts.map +1 -0
  7. package/dist/src/abstractEthLikeNewCoins.js +1834 -0
  8. package/dist/src/ethLikeToken.d.ts +35 -5
  9. package/dist/src/ethLikeToken.d.ts.map +1 -1
  10. package/dist/src/ethLikeToken.js +280 -7
  11. package/dist/src/index.d.ts +2 -0
  12. package/dist/src/index.d.ts.map +1 -1
  13. package/dist/src/index.js +8 -2
  14. package/dist/src/lib/contractCall.d.ts +8 -0
  15. package/dist/src/lib/contractCall.d.ts.map +1 -0
  16. package/dist/src/lib/contractCall.js +17 -0
  17. package/dist/src/lib/iface.d.ts +132 -0
  18. package/dist/src/lib/iface.d.ts.map +1 -0
  19. package/dist/src/lib/iface.js +8 -0
  20. package/dist/src/lib/index.d.ts +15 -0
  21. package/dist/src/lib/index.d.ts.map +1 -0
  22. package/dist/src/lib/index.js +56 -0
  23. package/dist/src/lib/keyPair.d.ts +26 -0
  24. package/dist/src/lib/keyPair.d.ts.map +1 -0
  25. package/dist/src/lib/keyPair.js +65 -0
  26. package/dist/src/lib/transaction.d.ts +64 -0
  27. package/dist/src/lib/transaction.d.ts.map +1 -0
  28. package/dist/src/lib/transaction.js +137 -0
  29. package/dist/src/lib/transactionBuilder.d.ts +249 -0
  30. package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
  31. package/dist/src/lib/transactionBuilder.js +741 -0
  32. package/dist/src/lib/transferBuilder.d.ts +70 -0
  33. package/dist/src/lib/transferBuilder.d.ts.map +1 -0
  34. package/dist/src/lib/transferBuilder.js +269 -0
  35. package/dist/src/lib/transferBuilders/baseNFTTransferBuilder.d.ts +54 -0
  36. package/dist/src/lib/transferBuilders/baseNFTTransferBuilder.d.ts.map +1 -0
  37. package/dist/src/lib/transferBuilders/baseNFTTransferBuilder.js +120 -0
  38. package/dist/src/lib/transferBuilders/index.d.ts +4 -0
  39. package/dist/src/lib/transferBuilders/index.d.ts.map +1 -0
  40. package/dist/src/lib/transferBuilders/index.js +20 -0
  41. package/dist/src/lib/transferBuilders/transferBuilderERC1155.d.ts +16 -0
  42. package/dist/src/lib/transferBuilders/transferBuilderERC1155.d.ts.map +1 -0
  43. package/dist/src/lib/transferBuilders/transferBuilderERC1155.js +93 -0
  44. package/dist/src/lib/transferBuilders/transferBuilderERC721.d.ts +15 -0
  45. package/dist/src/lib/transferBuilders/transferBuilderERC721.d.ts.map +1 -0
  46. package/dist/src/lib/transferBuilders/transferBuilderERC721.js +78 -0
  47. package/dist/src/lib/types.d.ts +39 -0
  48. package/dist/src/lib/types.d.ts.map +1 -0
  49. package/dist/src/lib/types.js +137 -0
  50. package/dist/src/lib/utils.d.ts +267 -0
  51. package/dist/src/lib/utils.d.ts.map +1 -0
  52. package/dist/src/lib/utils.js +688 -0
  53. package/dist/src/lib/walletUtil.d.ts +30 -0
  54. package/dist/src/lib/walletUtil.d.ts.map +1 -0
  55. package/dist/src/lib/walletUtil.js +33 -0
  56. package/dist/test/index.d.ts +2 -0
  57. package/dist/test/index.d.ts.map +1 -0
  58. package/dist/test/index.js +18 -0
  59. package/dist/test/unit/coin.d.ts +8 -0
  60. package/dist/test/unit/coin.d.ts.map +1 -0
  61. package/dist/test/unit/coin.js +577 -0
  62. package/dist/test/unit/index.d.ts +5 -0
  63. package/dist/test/unit/index.d.ts.map +1 -0
  64. package/dist/test/unit/index.js +21 -0
  65. package/dist/test/unit/token.d.ts +2 -0
  66. package/dist/test/unit/token.d.ts.map +1 -0
  67. package/dist/test/unit/token.js +37 -0
  68. package/dist/test/unit/transaction.d.ts +3 -0
  69. package/dist/test/unit/transaction.d.ts.map +1 -0
  70. package/dist/test/unit/transaction.js +60 -0
  71. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts +8 -0
  72. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts.map +1 -0
  73. package/dist/test/unit/transactionBuilder/addressInitialization.js +95 -0
  74. package/dist/test/unit/transactionBuilder/index.d.ts +4 -0
  75. package/dist/test/unit/transactionBuilder/index.d.ts.map +1 -0
  76. package/dist/test/unit/transactionBuilder/index.js +20 -0
  77. package/dist/test/unit/transactionBuilder/send.d.ts +3 -0
  78. package/dist/test/unit/transactionBuilder/send.d.ts.map +1 -0
  79. package/dist/test/unit/transactionBuilder/send.js +197 -0
  80. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts +10 -0
  81. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts.map +1 -0
  82. package/dist/test/unit/transactionBuilder/walletInitialization.js +124 -0
  83. package/dist/test/unit/transferBuilder.d.ts +2 -0
  84. package/dist/test/unit/transferBuilder.d.ts.map +1 -0
  85. package/dist/test/unit/transferBuilder.js +76 -0
  86. package/dist/tsconfig.tsbuildinfo +1 -8182
  87. package/index.ts +2 -0
  88. package/package.json +28 -9
@@ -0,0 +1,577 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.runBasicCoinInfoTests = runBasicCoinInfoTests;
40
+ exports.runExplainTransactionTests = runExplainTransactionTests;
41
+ exports.runSignTransactionTests = runSignTransactionTests;
42
+ exports.runTransactionVerificationTests = runTransactionVerificationTests;
43
+ exports.runRecoveryTransactionTests = runRecoveryTransactionTests;
44
+ const sdk_test_1 = require("@bitgo-beta/sdk-test");
45
+ const utxo_lib_1 = require("@bitgo-beta/utxo-lib");
46
+ const secp256k1 = __importStar(require("secp256k1"));
47
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
48
+ const nock_1 = __importDefault(require("nock"));
49
+ const should = __importStar(require("should"));
50
+ const src_1 = require("../../src");
51
+ nock_1.default.enableNetConnect();
52
+ function runBasicCoinInfoTests(coinName, bitgo, MainCoin, TestCoin, testData) {
53
+ describe(`${coinName} basic info test`, () => {
54
+ const coinTest = testData.COIN;
55
+ const coinMain = coinTest.slice(1);
56
+ it(`should return the right info for ${coinMain}`, () => {
57
+ const coin = bitgo.coin(coinMain);
58
+ coin.should.be.an.instanceof(MainCoin);
59
+ coin.getChain().should.equal(coinMain);
60
+ coin.getFamily().should.equal(coinMain);
61
+ coin.getFullName().should.equal(testData.CHAIN_FULL_NAME);
62
+ coin.getBaseFactor().should.equal(1e18);
63
+ });
64
+ it(`should return the right info for ${coinTest}`, () => {
65
+ const coin = bitgo.coin(coinTest);
66
+ coin.should.be.an.instanceof(TestCoin);
67
+ coin.getChain().should.equal(coinTest);
68
+ coin.getFamily().should.equal(coinMain);
69
+ coin.getFullName().should.equal(`Testnet ${testData.CHAIN_FULL_NAME}`);
70
+ coin.getBaseFactor().should.equal(1e18);
71
+ });
72
+ });
73
+ }
74
+ function runExplainTransactionTests(coinName, txBuilder, basecoin, testData) {
75
+ describe(`${coinName} explain transaction`, () => {
76
+ const coinTest = testData.COIN;
77
+ /**
78
+ * Build an unsigned account-lib multi-signature send transactino
79
+ * @param destination The destination address of the transaction
80
+ * @param contractAddress The address of the smart contract processing the transaction
81
+ * @param contractSequenceId The sequence id of the contract
82
+ * @param nonce The nonce of the sending address
83
+ * @param expireTime The expire time of the transaction
84
+ * @param amount The amount to send to the recipient
85
+ * @param gasPrice The gas price of the transaction
86
+ * @param gasLimit The gas limit of the transaction
87
+ */
88
+ const buildUnsignedTransaction = async function ({ destination, contractAddress, contractSequenceId = 1, nonce = 0, expireTime = Math.floor(new Date().getTime() / 1000), amount = '100000', gasPrice = '10000', gasLimit = '20000', }) {
89
+ txBuilder.type(sdk_core_1.TransactionType.Send);
90
+ txBuilder.fee({
91
+ fee: gasPrice,
92
+ gasLimit: gasLimit,
93
+ });
94
+ txBuilder.counter(nonce);
95
+ txBuilder.contract(contractAddress);
96
+ const transferBuilder = txBuilder.transfer();
97
+ transferBuilder
98
+ .coin(coinTest)
99
+ .expirationTime(expireTime)
100
+ .amount(amount)
101
+ .to(destination)
102
+ .contractSequenceId(contractSequenceId);
103
+ return await txBuilder.build();
104
+ };
105
+ it('should fail if the options object is missing parameters', async () => {
106
+ const explainParams = {
107
+ feeInfo: { fee: 1 },
108
+ txHex: null,
109
+ };
110
+ await basecoin.explainTransaction(explainParams).should.be.rejectedWith('missing explain tx parameters');
111
+ });
112
+ it('explain a transfer transaction', async () => {
113
+ const destination = '0xfaa8f14f46a99eb439c50e0c3b835cc21dad51b4';
114
+ const contractAddress = '0x9e2c5712ab4caf402a98c4bf58c79a0dfe718ad1';
115
+ const unsignedTransaction = await buildUnsignedTransaction({
116
+ destination,
117
+ contractAddress,
118
+ });
119
+ const explainParams = {
120
+ halfSigned: {
121
+ txHex: unsignedTransaction.toBroadcastFormat(),
122
+ },
123
+ feeInfo: { fee: 1 },
124
+ };
125
+ const explanation = await basecoin.explainTransaction(explainParams);
126
+ should.exist(explanation.id);
127
+ });
128
+ });
129
+ }
130
+ function runSignTransactionTests(coinName, builder, basecoin, testData) {
131
+ describe(`${coinName} sign transaction tests`, async () => {
132
+ const account_1 = {
133
+ address: '0x8Ce59c2d1702844F8EdED451AA103961bC37B4e8',
134
+ owner_1: '4ee089aceabf3ddbf748db79b1066c33b7d3ea1ab3eb7e325121bba2bff2f5ca',
135
+ owner_2: '5c7e4efff7304d4dfff6d5f1591844ec6f2adfa6a47e9fece6a3c1a4d755f1e3',
136
+ owner_3: '4421ab25dd91e1a3180d03d57c323a7886dcc313d3b3a4b4256a5791572bf597',
137
+ };
138
+ const account_2 = {
139
+ address: '0xeeaf0F05f37891ab4a21208B105A0687d12c5aF7',
140
+ owner_1: '4ee089aceabf3ddbf748db79b1066c33b7d3ea1ab3eb7e325121bba2bff2f5ca',
141
+ owner_2: '5ca116d25aec5f765465432cc421ff25ef9ffdc330b10bb3d9ad61e3baad88d7',
142
+ owner_3: '1fae946cc84af8bd74d610a88537e24e19c3349d478d86fc5bb59ba4c88fb9cc',
143
+ };
144
+ const coinTest = testData.COIN;
145
+ it('should sign an unsigned test tx', async () => {
146
+ builder.fee({
147
+ fee: '280000000000',
148
+ gasLimit: '7000000',
149
+ });
150
+ builder.counter(1);
151
+ builder.type(sdk_core_1.TransactionType.Send);
152
+ builder.contract(account_1.address);
153
+ const transferBuilder = builder.transfer();
154
+ transferBuilder.coin(coinTest).amount('1').to(account_2.address).expirationTime(10000).contractSequenceId(1);
155
+ const unsignedTx = await builder.build();
156
+ const unsignedTxForBroadcasting = unsignedTx.toBroadcastFormat();
157
+ const halfSignedRawTx = await basecoin.signTransaction({
158
+ txPrebuild: {
159
+ txHex: unsignedTxForBroadcasting,
160
+ },
161
+ prv: account_1.owner_2,
162
+ });
163
+ builder.transfer().key(account_1.owner_2);
164
+ const halfSignedTx = await builder.build();
165
+ const halfSignedTxForBroadcasting = halfSignedTx.toBroadcastFormat();
166
+ halfSignedRawTx.halfSigned.txHex.should.equals(halfSignedTxForBroadcasting);
167
+ halfSignedRawTx.halfSigned.recipients.length.should.equals(1);
168
+ halfSignedRawTx.halfSigned.recipients[0].address.toLowerCase().should.equals(account_2.address.toLowerCase());
169
+ halfSignedRawTx.halfSigned.recipients[0].amount.toLowerCase().should.equals('1');
170
+ });
171
+ it('should sign an unsigned test tx with eip1559', async () => {
172
+ builder.fee({
173
+ fee: '280000000000',
174
+ gasLimit: '7000000',
175
+ eip1559: {
176
+ maxFeePerGas: '7593123',
177
+ maxPriorityFeePerGas: '150',
178
+ },
179
+ });
180
+ builder.counter(1);
181
+ builder.type(sdk_core_1.TransactionType.Send);
182
+ builder.contract(account_1.address);
183
+ const transferBuilder = builder.transfer();
184
+ transferBuilder.coin(coinTest).amount('1').to(account_2.address).expirationTime(10000).contractSequenceId(1);
185
+ const unsignedTx = await builder.build();
186
+ const unsignedTxForBroadcasting = unsignedTx.toBroadcastFormat();
187
+ const halfSignedRawTx = await basecoin.signTransaction({
188
+ txPrebuild: {
189
+ txHex: unsignedTxForBroadcasting,
190
+ eip1559: {
191
+ maxFeePerGas: '7593123',
192
+ maxPriorityFeePerGas: '150',
193
+ },
194
+ },
195
+ prv: account_1.owner_2,
196
+ });
197
+ builder.transfer().key(account_1.owner_2);
198
+ const halfSignedTx = await builder.build();
199
+ const halfSignedTxForBroadcasting = halfSignedTx.toBroadcastFormat();
200
+ halfSignedRawTx.halfSigned.txHex.should.equals(halfSignedTxForBroadcasting);
201
+ halfSignedRawTx.halfSigned.recipients.length.should.equals(1);
202
+ halfSignedRawTx.halfSigned.recipients[0].address.toLowerCase().should.equals(account_2.address.toLowerCase());
203
+ halfSignedRawTx.halfSigned.recipients[0].amount.toLowerCase().should.equals('1');
204
+ halfSignedRawTx.halfSigned.eip1559.maxFeePerGas.should.equal('7593123');
205
+ halfSignedRawTx.halfSigned.eip1559.maxPriorityFeePerGas.should.equal('150');
206
+ });
207
+ });
208
+ }
209
+ function runTransactionVerificationTests(coinName, bitgo, basecoin, testData) {
210
+ describe(`${coinName} Transaction Verification`, () => {
211
+ const coinTest = testData.COIN;
212
+ const address1 = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
213
+ const address2 = '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6';
214
+ const hopDestinationAddress = '0x9c7e8ce6825bD48278B3Ab59228EE26f8BE7925b';
215
+ const hopTx = '0xf86b808504a817c8ff8252ff949c7e8ce6825bd48278b3ab59228ee26f8be7925b87038d7ea4c68000801ca011bc22c664570133dfca4f08a0b8d02339cf467046d6a4152f04f368d0eaf99ea01d6dc5cf0c897c8d4c3e1df53d0d042784c424536a4cc5b802552b7d64fee8b5';
216
+ const hopTxid = '0x4af65143bc77da2b50f35b3d13cacb4db18f026bf84bc0743550bc57b9b53351';
217
+ const userReqSig = '0x404db307f6147f0d8cd338c34c13906ef46a6faa7e0e119d5194ef05aec16e6f3d710f9b7901460f97e924066b62efd74443bd34402c6d40b49c203a559ff2c8';
218
+ const bitgoKeyXprv = 'xprv9s21ZrQH143K3tpWBHWe31sLoXNRQ9AvRYJgitkKxQ4ATFQMwvr7hHNqYRUnS7PsjzB7aK1VxqHLuNQjj1sckJ2Jwo2qxmsvejwECSpFMfC';
219
+ const bitgoKey = utxo_lib_1.bip32.fromBase58(bitgoKeyXprv);
220
+ if (!bitgoKey.privateKey) {
221
+ throw new Error('no privateKey');
222
+ }
223
+ const hopTxBitgoSignature = '0xaa' +
224
+ Buffer.from(secp256k1.ecdsaSign(Buffer.from(hopTxid.slice(2), 'hex'), bitgoKey.privateKey).signature).toString('hex');
225
+ it('should verify a normal txPrebuild from the bitgo server that matches the client txParams', async () => {
226
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
227
+ const txParams = {
228
+ recipients: [{ amount: '1000000000000', address: address1 }],
229
+ wallet: wallet,
230
+ walletPassphrase: 'fakeWalletPassphrase',
231
+ };
232
+ const txPrebuild = {
233
+ recipients: [{ amount: '1000000000000', address: address1 }],
234
+ nextContractSequenceId: 0,
235
+ gasPrice: 20000000000,
236
+ gasLimit: 500000,
237
+ isBatch: false,
238
+ coin: coinTest,
239
+ walletId: 'fakeWalletId',
240
+ walletContractAddress: 'fakeWalletContractAddress',
241
+ };
242
+ const verification = {};
243
+ const isTransactionVerified = await basecoin.verifyTransaction({ txParams, txPrebuild, wallet, verification });
244
+ isTransactionVerified.should.equal(true);
245
+ });
246
+ it('should reject when client txParams are missing', async () => {
247
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
248
+ const txParams = null;
249
+ const txPrebuild = {
250
+ recipients: [{ amount: '1000000000000', address: address1 }],
251
+ nextContractSequenceId: 0,
252
+ gasPrice: 20000000000,
253
+ gasLimit: 500000,
254
+ isBatch: false,
255
+ coin: coinTest,
256
+ walletId: 'fakeWalletId',
257
+ walletContractAddress: 'fakeWalletContractAddress',
258
+ };
259
+ const verification = {};
260
+ await basecoin
261
+ .verifyTransaction({ txParams, txPrebuild, wallet, verification })
262
+ .should.be.rejectedWith('missing params');
263
+ });
264
+ it('should reject txPrebuild that is both batch and hop', async () => {
265
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
266
+ const txParams = {
267
+ recipients: [
268
+ { amount: '1000000000000', address: address1 },
269
+ { amount: '2500000000000', address: address2 },
270
+ ],
271
+ wallet: wallet,
272
+ walletPassphrase: 'fakeWalletPassphrase',
273
+ hop: true,
274
+ };
275
+ const txPrebuild = {
276
+ recipients: [{ amount: '3500000000000', address: address1 }],
277
+ nextContractSequenceId: 0,
278
+ gasPrice: 20000000000,
279
+ gasLimit: 500000,
280
+ isBatch: true,
281
+ coin: coinTest,
282
+ walletId: 'fakeWalletId',
283
+ walletContractAddress: 'fakeWalletContractAddress',
284
+ hopTransaction: {
285
+ tx: hopTx,
286
+ id: hopTxid,
287
+ signature: hopTxBitgoSignature,
288
+ paymentId: '2773928196',
289
+ gasPrice: 20000000000,
290
+ gasLimit: 500000,
291
+ amount: '1000000000000000',
292
+ recipient: hopDestinationAddress,
293
+ nonce: 0,
294
+ userReqSig: userReqSig,
295
+ gasPriceMax: 500000000000,
296
+ },
297
+ };
298
+ const verification = {};
299
+ await basecoin
300
+ .verifyTransaction({ txParams, txPrebuild, wallet, verification })
301
+ .should.be.rejectedWith('tx cannot be both a batch and hop transaction');
302
+ });
303
+ it('should reject a txPrebuild with more than one recipient', async () => {
304
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
305
+ const txParams = {
306
+ recipients: [
307
+ { amount: '1000000000000', address: address1 },
308
+ { amount: '2500000000000', address: address2 },
309
+ ],
310
+ wallet: wallet,
311
+ walletPassphrase: 'fakeWalletPassphrase',
312
+ };
313
+ const txPrebuild = {
314
+ recipients: [
315
+ { amount: '1000000000000', address: address1 },
316
+ { amount: '2500000000000', address: address2 },
317
+ ],
318
+ nextContractSequenceId: 0,
319
+ gasPrice: 20000000000,
320
+ gasLimit: 500000,
321
+ isBatch: true,
322
+ coin: coinTest,
323
+ walletId: 'fakeWalletId',
324
+ walletContractAddress: 'fakeWalletContractAddress',
325
+ };
326
+ const verification = {};
327
+ await basecoin
328
+ .verifyTransaction({ txParams, txPrebuild, wallet, verification })
329
+ .should.be.rejectedWith(`${coinTest} doesn't support sending to more than 1 destination address within a single transaction. Try again, using only a single recipient.`);
330
+ });
331
+ it('should reject a hop txPrebuild that does not send to its hop address', async () => {
332
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
333
+ const txParams = {
334
+ recipients: [{ amount: '1000000000000000', address: hopDestinationAddress }],
335
+ wallet: wallet,
336
+ walletPassphrase: 'fakeWalletPassphrase',
337
+ hop: true,
338
+ };
339
+ const txPrebuild = {
340
+ recipients: [{ amount: '5000000000000000', address: address1 }],
341
+ nextContractSequenceId: 0,
342
+ gasPrice: 20000000000,
343
+ gasLimit: 500000,
344
+ isBatch: false,
345
+ coin: coinTest,
346
+ walletId: 'fakeWalletId',
347
+ walletContractAddress: 'fakeWalletContractAddress',
348
+ hopTransaction: {
349
+ tx: hopTx,
350
+ id: hopTxid,
351
+ signature: hopTxBitgoSignature,
352
+ paymentId: '0',
353
+ gasPrice: 20000000000,
354
+ gasLimit: 500000,
355
+ amount: '1000000000000000',
356
+ recipient: hopDestinationAddress,
357
+ nonce: 0,
358
+ userReqSig: userReqSig,
359
+ gasPriceMax: 500000000000,
360
+ },
361
+ };
362
+ const verification = {};
363
+ await basecoin
364
+ .verifyTransaction({ txParams, txPrebuild, wallet, verification })
365
+ .should.be.rejectedWith('recipient address of txPrebuild does not match hop address');
366
+ });
367
+ it('should reject a normal txPrebuild from the bitgo server with the wrong amount', async () => {
368
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
369
+ const txParams = {
370
+ recipients: [{ amount: '1000000000000', address: address1 }],
371
+ wallet: wallet,
372
+ walletPassphrase: 'fakeWalletPassphrase',
373
+ };
374
+ const txPrebuild = {
375
+ recipients: [{ amount: '2000000000000', address: address1 }],
376
+ nextContractSequenceId: 0,
377
+ gasPrice: 20000000000,
378
+ gasLimit: 500000,
379
+ isBatch: false,
380
+ coin: coinTest,
381
+ walletId: 'fakeWalletId',
382
+ walletContractAddress: 'fakeWalletContractAddress',
383
+ };
384
+ const verification = {};
385
+ await basecoin
386
+ .verifyTransaction({ txParams, txPrebuild, wallet, verification })
387
+ .should.be.rejectedWith('normal transaction amount in txPrebuild received from BitGo servers does not match txParams supplied by client');
388
+ });
389
+ it('should reject a normal txPrebuild from the bitgo server with the wrong recipient', async () => {
390
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
391
+ const txParams = {
392
+ recipients: [{ amount: '1000000000000', address: address1 }],
393
+ wallet: wallet,
394
+ walletPassphrase: 'fakeWalletPassphrase',
395
+ };
396
+ const txPrebuild = {
397
+ recipients: [{ amount: '1000000000000', address: address2 }],
398
+ nextContractSequenceId: 0,
399
+ gasPrice: 20000000000,
400
+ gasLimit: 500000,
401
+ isBatch: false,
402
+ coin: coinTest,
403
+ walletId: 'fakeWalletId',
404
+ walletContractAddress: 'fakeWalletContractAddress',
405
+ };
406
+ const verification = {};
407
+ await basecoin
408
+ .verifyTransaction({ txParams, txPrebuild, wallet, verification })
409
+ .should.be.rejectedWith('destination address in normal txPrebuild does not match that in txParams supplied by client');
410
+ });
411
+ it('should reject a txPrebuild from the bitgo server with the wrong coin', async () => {
412
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
413
+ const txParams = {
414
+ recipients: [{ amount: '1000000000000', address: address1 }],
415
+ wallet: wallet,
416
+ walletPassphrase: 'fakeWalletPassphrase',
417
+ };
418
+ const txPrebuild = {
419
+ recipients: [{ amount: '1000000000000', address: address1 }],
420
+ nextContractSequenceId: 0,
421
+ gasPrice: 20000000000,
422
+ gasLimit: 500000,
423
+ isBatch: false,
424
+ coin: 'btc',
425
+ walletId: 'fakeWalletId',
426
+ walletContractAddress: 'fakeWalletContractAddress',
427
+ };
428
+ const verification = {};
429
+ await basecoin
430
+ .verifyTransaction({ txParams, txPrebuild, wallet, verification })
431
+ .should.be.rejectedWith('coin in txPrebuild did not match that in txParams supplied by client');
432
+ });
433
+ });
434
+ }
435
+ function runRecoveryTransactionTests(coinName, txBuilder, bitgo, testData, mockData) {
436
+ describe(`${coinName} Recover transaction:`, function () {
437
+ const baseUrl = testData.BASE_URL;
438
+ const userXpub = 'xpub661MyMwAqRbcEeTc8789MK5PUGEYiPG4F4V17n2Rd2LoTATA1XoCnJT5FAYAShQxSxtFjpo5NHmcWwTp2LiWGBMwpUcAA3HywhxivgYfq7q';
439
+ const userXprv = 'xprv9s21ZrQH143K2AP925b8zB8evEQ4JvYCsqZQKPcp4gopaN81TzUxEW8bPtVyDgjmddGhRRETn8xi1cVAB9bf1Bx9kGRRFgTZXxJayZLnag1';
440
+ const backupXpub = 'xpub661MyMwAqRbcFZX15xpZf4ERCGHiVSJm8r5C4yh1yXV2GrdZCUPYo4WQr6tN9oUywKXsgSHo7Risf9r22GH5joVD2hEEEhqnSCvK8qy11wW';
441
+ const backupXprv = 'xprv9s21ZrQH143K35SXywHZHvHgeETE5yaumd9bGbHQRBx3Q4JQew5JFGBvzqiZjCUkBdBUZnfuMDTGURRayN1hFSWxEJQsCEAMm1D3pk1h7Jj';
442
+ const coin = testData.COIN;
443
+ after(function () {
444
+ nock_1.default.cleanAll();
445
+ });
446
+ it('should generate an unsigned sweep', async () => {
447
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
448
+ const backupKeyAddress = '0x4f2c4830cc37f2785c646f89ded8a919219fa0e9';
449
+ (0, nock_1.default)(baseUrl)
450
+ .get('/api')
451
+ .twice()
452
+ .query(mockData.getTxListRequest(backupKeyAddress))
453
+ .reply(200, mockData.getTxListResponse);
454
+ (0, nock_1.default)(baseUrl)
455
+ .get('/api')
456
+ .query(mockData.getBalanceRequest(walletContractAddress))
457
+ .reply(200, mockData.getBalanceResponse);
458
+ (0, nock_1.default)(baseUrl)
459
+ .get('/api')
460
+ .query(mockData.getBalanceRequest(backupKeyAddress))
461
+ .reply(200, mockData.getBalanceResponse);
462
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
463
+ const basecoin = bitgo.coin(coin);
464
+ const transaction = (await basecoin.recover({
465
+ userKey: userXpub,
466
+ backupKey: backupXpub,
467
+ walletContractAddress: walletContractAddress,
468
+ recoveryDestination: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
469
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
470
+ gasLimit: 500000,
471
+ }));
472
+ should.exist(transaction);
473
+ transaction.should.have.property('txHex');
474
+ transaction.should.have.property('contractSequenceId');
475
+ transaction.should.have.property('expireTime');
476
+ transaction.should.have.property('gasLimit');
477
+ transaction.gasLimit.should.equal('500000');
478
+ transaction.should.have.property('walletContractAddress');
479
+ transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
480
+ transaction.should.have.property('recipients');
481
+ const recipient = transaction.recipients[0];
482
+ recipient.should.have.property('address');
483
+ recipient.address.should.equal(sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT);
484
+ recipient.should.have.property('amount');
485
+ recipient.amount.should.equal('9999999999999999928');
486
+ });
487
+ it('should construct a recovery transaction without BitGo', async () => {
488
+ const backupKeyAddress = '0x6d22efdd634996248170c948e5726007fc251bb3';
489
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
490
+ (0, nock_1.default)(baseUrl)
491
+ .get('/api')
492
+ .query(mockData.getTxListRequest(backupKeyAddress))
493
+ .reply(200, mockData.getTxListResponse);
494
+ (0, nock_1.default)(baseUrl)
495
+ .get('/api')
496
+ .query(mockData.getBalanceRequest(walletContractAddress))
497
+ .reply(200, mockData.getBalanceResponse);
498
+ (0, nock_1.default)(baseUrl)
499
+ .get('/api')
500
+ .query(mockData.getBalanceRequest(backupKeyAddress))
501
+ .reply(200, mockData.getBalanceResponse);
502
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
503
+ const basecoin = bitgo.coin(coin);
504
+ const transaction = (await basecoin.recover({
505
+ userKey: '{"iv":"VFZ3jvXhxo1Z+Yaf2MtZnA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
506
+ ':"ccm","adata":"","cipher":"aes","salt":"p+fkHuLa/8k=","ct":"hYG7pvljLIgCjZ\n' +
507
+ '53PBlCde5KZRmlUKKHLtDMk+HJfuU46hW+x+C9WsIAO4gFPnTCvFVmQ8x7czCtcNFub5AO2otOG\n' +
508
+ 'OsX4GE2gXOEmCl1TpWwwNhm7yMUjGJUpgW6ZZgXSXdDitSKi4V/hk78SGSzjFOBSPYRa6I="}\n',
509
+ backupKey: '{"iv":"AbsCtv1qwPIhOgyrCpNagA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
510
+ ':"ccm","adata":"","cipher":"aes","salt":"5vpUDBUlzm8=","ct":"PapYYCjBXRLUKA\n' +
511
+ 'JbOsB/EJ9B8fUmVQTxMPjUnQyAky12me9K66GiMEAxTD7kd6bYAQJuuTkATXKU7Bnf7vK9JxNOw\n' +
512
+ 'oji7HF9eFH0aD4/hX5SWFfHF2Qfi+TnXv6hVsMAoisDZs3/F67/ZUaDYR0ZsdrQ4Q/cLD0="}\n',
513
+ walletContractAddress: walletContractAddress,
514
+ walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
515
+ recoveryDestination: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
516
+ gasLimit: 500000,
517
+ }));
518
+ should.exist(transaction);
519
+ transaction.should.have.property('tx');
520
+ transaction.should.have.property('id');
521
+ const decodedTx = src_1.optionalDeps.EthTx.Transaction.fromSerializedTx(src_1.optionalDeps.ethUtil.toBuffer(transaction.tx));
522
+ decodedTx.should.have.property('gasPrice');
523
+ decodedTx.should.have.property('nonce');
524
+ decodedTx.should.have.property('to');
525
+ });
526
+ it('should be able to second sign', async () => {
527
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
528
+ const backupKeyAddress = '0x4f2c4830cc37f2785c646f89ded8a919219fa0e9';
529
+ (0, nock_1.default)(baseUrl)
530
+ .get('/api')
531
+ .twice()
532
+ .query(mockData.getTxListRequest(backupKeyAddress))
533
+ .reply(200, mockData.getTxListResponse);
534
+ (0, nock_1.default)(baseUrl)
535
+ .get('/api')
536
+ .query(mockData.getBalanceRequest(walletContractAddress))
537
+ .reply(200, mockData.getBalanceResponse);
538
+ (0, nock_1.default)(baseUrl)
539
+ .get('/api')
540
+ .query(mockData.getBalanceRequest(backupKeyAddress))
541
+ .reply(200, mockData.getBalanceResponse);
542
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
543
+ const basecoin = bitgo.coin(coin);
544
+ const transaction = (await basecoin.recover({
545
+ userKey: userXpub,
546
+ backupKey: backupXpub,
547
+ walletContractAddress: walletContractAddress,
548
+ recoveryDestination: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
549
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
550
+ replayProtectionOptions: { chain: 80001, hardfork: 'london' },
551
+ gasLimit: 500000,
552
+ }));
553
+ const txPrebuild = {
554
+ txHex: transaction.txHex,
555
+ };
556
+ const params = {
557
+ txPrebuild,
558
+ prv: userXprv,
559
+ };
560
+ // sign transaction once
561
+ const halfSigned = await basecoin.signTransaction(params);
562
+ const halfSignedParams = {
563
+ txPrebuild: halfSigned,
564
+ isLastSignature: true,
565
+ walletContractAddress: walletContractAddress,
566
+ prv: backupXprv,
567
+ };
568
+ const finalSigned = (await basecoin.signTransaction(halfSignedParams));
569
+ finalSigned.should.have.property('txHex');
570
+ txBuilder.from(finalSigned.txHex);
571
+ const rebuiltTx = await txBuilder.build();
572
+ rebuiltTx.signature.length.should.equal(2);
573
+ rebuiltTx.outputs.length.should.equal(1);
574
+ });
575
+ });
576
+ }
577
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29pbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvdW5pdC9jb2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ0JBLHNEQXdCQztBQUVELGdFQXFFQztBQUVELDBEQTBGQztBQUVELDBFQW9SQztBQUVELGtFQW1LQztBQXRvQkQsbURBQStEO0FBQy9ELG1EQUE2QztBQUM3QyxxREFBdUM7QUFDdkMsbURBQXVGO0FBQ3ZGLGdEQUF3QjtBQUN4QiwrQ0FBaUM7QUFDakMsbUNBTW1CO0FBRW5CLGNBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0FBRXhCLFNBQWdCLHFCQUFxQixDQUFDLFFBQWdCLEVBQUUsS0FBbUIsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLFFBQWE7SUFDNUcsUUFBUSxDQUFDLEdBQUcsUUFBUSxrQkFBa0IsRUFBRSxHQUFHLEVBQUU7UUFDM0MsTUFBTSxRQUFRLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQztRQUMvQixNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25DLEVBQUUsQ0FBQyxvQ0FBb0MsUUFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFO1lBQ3RELE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7WUFFbEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN2QyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN2QyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN4QyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLEtB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QUFDO1lBRTFCLE1BQU0sVUFBVSxHQUFHO2dCQUNqQixLQUFLLEVBQUUsV0FBVyxDQUFDLEtBQUs7YUFDekIsQ0FBQztZQUVGLE1BQU0sTUFBTSxHQUFHO2dCQUNiLFVBQVU7Z0JBQ1YsR0FBRyxFQUFFLFFBQVE7YUFDZCxDQUFDO1lBQ0Ysd0JBQXdCO1lBQ3hCLE1BQU0sVUFBVSxHQUFHLE1BQU0sUUFBUSxDQUFDLGVBQWUsQ0FBQyxNQUFnQyxDQUFDLENBQUM7WUFDcEYsTUFBTSxnQkFBZ0IsR0FBRztnQkFDdkIsVUFBVSxFQUFFLFVBQVU7Z0JBQ3RCLGVBQWUsRUFBRSxJQUFJO2dCQUNyQixxQkFBcUIsRUFBRSxxQkFBcUI7Z0JBQzVDLEdBQUcsRUFBRSxVQUFVO2FBQ2hCLENBQUM7WUFFRixNQUFNLFdBQVcsR0FBRyxDQUFDLE1BQU0sUUFBUSxDQUFDLGVBQWUsQ0FDakQsZ0JBQTBDLENBQzNDLENBQTJCLENBQUM7WUFDN0IsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2xDLE1BQU0sU0FBUyxHQUFHLE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0MsU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRlc3RCaXRHbywgVGVzdEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLXRlc3QnO1xuaW1wb3J0IHsgYmlwMzIgfSBmcm9tICdAYml0Z28tYmV0YS91dHhvLWxpYic7XG5pbXBvcnQgKiBhcyBzZWNwMjU2azEgZnJvbSAnc2VjcDI1NmsxJztcbmltcG9ydCB7IEZ1bGx5U2lnbmVkVHJhbnNhY3Rpb24sIFRyYW5zYWN0aW9uVHlwZSwgV2FsbGV0IH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IG5vY2sgZnJvbSAnbm9jayc7XG5pbXBvcnQgKiBhcyBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCB7XG4gIE9mZmxpbmVWYXVsdFR4SW5mbyxcbiAgb3B0aW9uYWxEZXBzLFxuICBTaWduVHJhbnNhY3Rpb25PcHRpb25zLFxuICBUcmFuc2ZlckJ1aWxkZXIsXG4gIFRyYW5zYWN0aW9uQnVpbGRlcixcbn0gZnJvbSAnLi4vLi4vc3JjJztcblxubm9jay5lbmFibGVOZXRDb25uZWN0KCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBydW5CYXNpY0NvaW5JbmZvVGVzdHMoY29pbk5hbWU6IHN0cmluZywgYml0Z286IFRlc3RCaXRHb0FQSSwgTWFpbkNvaW4sIFRlc3RDb2luLCB0ZXN0RGF0YTogYW55KSB7XG4gIGRlc2NyaWJlKGAke2NvaW5OYW1lfSBiYXNpYyBpbmZvIHRlc3RgLCAoKSA9PiB7XG4gICAgY29uc3QgY29pblRlc3QgPSB0ZXN0RGF0YS5DT0lOO1xuICAgIGNvbnN0IGNvaW5NYWluID0gY29pblRlc3Quc2xpY2UoMSk7XG4gICAgaXQoYHNob3VsZCByZXR1cm4gdGhlIHJpZ2h0IGluZm8gZm9yICR7Y29pbk1haW59YCwgKCkgPT4ge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oY29pbk1haW4pO1xuXG4gICAgICBjb2luLnNob3VsZC5iZS5hbi5pbnN0YW5jZW9mKE1haW5Db2luKTtcbiAgICAgIGNvaW4uZ2V0Q2hhaW4oKS5zaG91bGQuZXF1YWwoY29pbk1haW4pO1xuICAgICAgY29pbi5nZXRGYW1pbHkoKS5zaG91bGQuZXF1YWwoY29pbk1haW4pO1xuICAgICAgY29pbi5nZXRGdWxsTmFtZSgpLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5DSEFJTl9GVUxMX05BTUUpO1xuICAgICAgY29pbi5nZXRCYXNlRmFjdG9yKCkuc2hvdWxkLmVxdWFsKDFlMTgpO1xuICAgIH0pO1xuXG4gICAgaXQoYHNob3VsZCByZXR1cm4gdGhlIHJpZ2h0IGluZm8gZm9yICR7Y29pblRlc3R9YCwgKCkgPT4ge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oY29pblRlc3QpO1xuXG4gICAgICBjb2luLnNob3VsZC5iZS5hbi5pbnN0YW5jZW9mKFRlc3RDb2luKTtcbiAgICAgIGNvaW4uZ2V0Q2hhaW4oKS5zaG91bGQuZXF1YWwoY29pblRlc3QpO1xuICAgICAgY29pbi5nZXRGYW1pbHkoKS5zaG91bGQuZXF1YWwoY29pbk1haW4pO1xuICAgICAgY29pbi5nZXRGdWxsTmFtZSgpLnNob3VsZC5lcXVhbChgVGVzdG5ldCAke3Rlc3REYXRhLkNIQUlOX0ZVTExfTkFNRX1gKTtcbiAgICAgIGNvaW4uZ2V0QmFzZUZhY3RvcigpLnNob3VsZC5lcXVhbCgxZTE4KTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBydW5FeHBsYWluVHJhbnNhY3Rpb25UZXN0cyhjb2luTmFtZTogc3RyaW5nLCB0eEJ1aWxkZXI6IFRyYW5zYWN0aW9uQnVpbGRlciwgYmFzZWNvaW4sIHRlc3REYXRhOiBhbnkpIHtcbiAgZGVzY3JpYmUoYCR7Y29pbk5hbWV9IGV4cGxhaW4gdHJhbnNhY3Rpb25gLCAoKSA9PiB7XG4gICAgY29uc3QgY29pblRlc3QgPSB0ZXN0RGF0YS5DT0lOO1xuICAgIC8qKlxuICAgICAqIEJ1aWxkIGFuIHVuc2lnbmVkIGFjY291bnQtbGliIG11bHRpLXNpZ25hdHVyZSBzZW5kIHRyYW5zYWN0aW5vXG4gICAgICogQHBhcmFtIGRlc3RpbmF0aW9uIFRoZSBkZXN0aW5hdGlvbiBhZGRyZXNzIG9mIHRoZSB0cmFuc2FjdGlvblxuICAgICAqIEBwYXJhbSBjb250cmFjdEFkZHJlc3MgVGhlIGFkZHJlc3Mgb2YgdGhlIHNtYXJ0IGNvbnRyYWN0IHByb2Nlc3NpbmcgdGhlIHRyYW5zYWN0aW9uXG4gICAgICogQHBhcmFtIGNvbnRyYWN0U2VxdWVuY2VJZCBUaGUgc2VxdWVuY2UgaWQgb2YgdGhlIGNvbnRyYWN0XG4gICAgICogQHBhcmFtIG5vbmNlIFRoZSBub25jZSBvZiB0aGUgc2VuZGluZyBhZGRyZXNzXG4gICAgICogQHBhcmFtIGV4cGlyZVRpbWUgVGhlIGV4cGlyZSB0aW1lIG9mIHRoZSB0cmFuc2FjdGlvblxuICAgICAqIEBwYXJhbSBhbW91bnQgVGhlIGFtb3VudCB0byBzZW5kIHRvIHRoZSByZWNpcGllbnRcbiAgICAgKiBAcGFyYW0gZ2FzUHJpY2UgVGhlIGdhcyBwcmljZSBvZiB0aGUgdHJhbnNhY3Rpb25cbiAgICAgKiBAcGFyYW0gZ2FzTGltaXQgVGhlIGdhcyBsaW1pdCBvZiB0aGUgdHJhbnNhY3Rpb25cbiAgICAgKi9cbiAgICBjb25zdCBidWlsZFVuc2lnbmVkVHJhbnNhY3Rpb24gPSBhc3luYyBmdW5jdGlvbiAoe1xuICAgICAgZGVzdGluYXRpb24sXG4gICAgICBjb250cmFjdEFkZHJlc3MsXG4gICAgICBjb250cmFjdFNlcXVlbmNlSWQgPSAxLFxuICAgICAgbm9uY2UgPSAwLFxuICAgICAgZXhwaXJlVGltZSA9IE1hdGguZmxvb3IobmV3IERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKSxcbiAgICAgIGFtb3VudCA9ICcxMDAwMDAnLFxuICAgICAgZ2FzUHJpY2UgPSAnMTAwMDAnLFxuICAgICAgZ2FzTGltaXQgPSAnMjAwMDAnLFxuICAgIH0pIHtcbiAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICAgIHR4QnVpbGRlci5mZWUoe1xuICAgICAgICBmZWU6IGdhc1ByaWNlLFxuICAgICAgICBnYXNMaW1pdDogZ2FzTGltaXQsXG4gICAgICB9KTtcbiAgICAgIHR4QnVpbGRlci5jb3VudGVyKG5vbmNlKTtcbiAgICAgIHR4QnVpbGRlci5jb250cmFjdChjb250cmFjdEFkZHJlc3MpO1xuICAgICAgY29uc3QgdHJhbnNmZXJCdWlsZGVyID0gdHhCdWlsZGVyLnRyYW5zZmVyKCkgYXMgVHJhbnNmZXJCdWlsZGVyO1xuXG4gICAgICB0cmFuc2ZlckJ1aWxkZXJcbiAgICAgICAgLmNvaW4oY29pblRlc3QpXG4gICAgICAgIC5leHBpcmF0aW9uVGltZShleHBpcmVUaW1lKVxuICAgICAgICAuYW1vdW50KGFtb3VudClcbiAgICAgICAgLnRvKGRlc3RpbmF0aW9uKVxuICAgICAgICAuY29udHJhY3RTZXF1ZW5jZUlkKGNvbnRyYWN0U2VxdWVuY2VJZCk7XG5cbiAgICAgIHJldHVybiBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICB9O1xuICAgIGl0KCdzaG91bGQgZmFpbCBpZiB0aGUgb3B0aW9ucyBvYmplY3QgaXMgbWlzc2luZyBwYXJhbWV0ZXJzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgZXhwbGFpblBhcmFtcyA9IHtcbiAgICAgICAgZmVlSW5mbzogeyBmZWU6IDEgfSxcbiAgICAgICAgdHhIZXg6IG51bGwsXG4gICAgICB9O1xuICAgICAgYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKGV4cGxhaW5QYXJhbXMpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ21pc3NpbmcgZXhwbGFpbiB0eCBwYXJhbWV0ZXJzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnZXhwbGFpbiBhIHRyYW5zZmVyIHRyYW5zYWN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgZGVzdGluYXRpb24gPSAnMHhmYWE4ZjE0ZjQ2YTk5ZWI0MzljNTBlMGMzYjgzNWNjMjFkYWQ1MWI0JztcbiAgICAgIGNvbnN0IGNvbnRyYWN0QWRkcmVzcyA9ICcweDllMmM1NzEyYWI0Y2FmNDAyYTk4YzRiZjU4Yzc5YTBkZmU3MThhZDEnO1xuXG4gICAgICBjb25zdCB1bnNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgYnVpbGRVbnNpZ25lZFRyYW5zYWN0aW9uKHtcbiAgICAgICAgZGVzdGluYXRpb24sXG4gICAgICAgIGNvbnRyYWN0QWRkcmVzcyxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBleHBsYWluUGFyYW1zID0ge1xuICAgICAgICBoYWxmU2lnbmVkOiB7XG4gICAgICAgICAgdHhIZXg6IHVuc2lnbmVkVHJhbnNhY3Rpb24udG9Ccm9hZGNhc3RGb3JtYXQoKSxcbiAgICAgICAgfSxcbiAgICAgICAgZmVlSW5mbzogeyBmZWU6IDEgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBleHBsYW5hdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbihleHBsYWluUGFyYW1zKTtcbiAgICAgIHNob3VsZC5leGlzdChleHBsYW5hdGlvbi5pZCk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcnVuU2lnblRyYW5zYWN0aW9uVGVzdHMoY29pbk5hbWU6IHN0cmluZywgYnVpbGRlcjogVHJhbnNhY3Rpb25CdWlsZGVyLCBiYXNlY29pbiwgdGVzdERhdGE6IGFueSkge1xuICBkZXNjcmliZShgJHtjb2luTmFtZX0gc2lnbiB0cmFuc2FjdGlvbiB0ZXN0c2AsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhY2NvdW50XzEgPSB7XG4gICAgICBhZGRyZXNzOiAnMHg4Q2U1OWMyZDE3MDI4NDRGOEVkRUQ0NTFBQTEwMzk2MWJDMzdCNGU4JyxcbiAgICAgIG93bmVyXzE6ICc0ZWUwODlhY2VhYmYzZGRiZjc0OGRiNzliMTA2NmMzM2I3ZDNlYTFhYjNlYjdlMzI1MTIxYmJhMmJmZjJmNWNhJyxcbiAgICAgIG93bmVyXzI6ICc1YzdlNGVmZmY3MzA0ZDRkZmZmNmQ1ZjE1OTE4NDRlYzZmMmFkZmE2YTQ3ZTlmZWNlNmEzYzFhNGQ3NTVmMWUzJyxcbiAgICAgIG93bmVyXzM6ICc0NDIxYWIyNWRkOTFlMWEzMTgwZDAzZDU3YzMyM2E3ODg2ZGNjMzEzZDNiM2E0YjQyNTZhNTc5MTU3MmJmNTk3JyxcbiAgICB9O1xuXG4gICAgY29uc3QgYWNjb3VudF8yID0ge1xuICAgICAgYWRkcmVzczogJzB4ZWVhZjBGMDVmMzc4OTFhYjRhMjEyMDhCMTA1QTA2ODdkMTJjNWFGNycsXG4gICAgICBvd25lcl8xOiAnNGVlMDg5YWNlYWJmM2RkYmY3NDhkYjc5YjEwNjZjMzNiN2QzZWExYWIzZWI3ZTMyNTEyMWJiYTJiZmYyZjVjYScsXG4gICAgICBvd25lcl8yOiAnNWNhMTE2ZDI1YWVjNWY3NjU0NjU0MzJjYzQyMWZmMjVlZjlmZmRjMzMwYjEwYmIzZDlhZDYxZTNiYWFkODhkNycsXG4gICAgICBvd25lcl8zOiAnMWZhZTk0NmNjODRhZjhiZDc0ZDYxMGE4ODUzN2UyNGUxOWMzMzQ5ZDQ3OGQ4NmZjNWJiNTliYTRjODhmYjljYycsXG4gICAgfTtcblxuICAgIGNvbnN0IGNvaW5UZXN0ID0gdGVzdERhdGEuQ09JTjtcblxuICAgIGl0KCdzaG91bGQgc2lnbiBhbiB1bnNpZ25lZCB0ZXN0IHR4JywgYXN5bmMgKCkgPT4ge1xuICAgICAgYnVpbGRlci5mZWUoe1xuICAgICAgICBmZWU6ICcyODAwMDAwMDAwMDAnLFxuICAgICAgICBnYXNMaW1pdDogJzcwMDAwMDAnLFxuICAgICAgfSk7XG4gICAgICBidWlsZGVyLmNvdW50ZXIoMSk7XG4gICAgICBidWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLlNlbmQpO1xuICAgICAgYnVpbGRlci5jb250cmFjdChhY2NvdW50XzEuYWRkcmVzcyk7XG4gICAgICBjb25zdCB0cmFuc2ZlckJ1aWxkZXIgPSBidWlsZGVyLnRyYW5zZmVyKCkgYXMgVHJhbnNmZXJCdWlsZGVyO1xuICAgICAgdHJhbnNmZXJCdWlsZGVyLmNvaW4oY29pblRlc3QpLmFtb3VudCgnMScpLnRvKGFjY291bnRfMi5hZGRyZXNzKS5leHBpcmF0aW9uVGltZSgxMDAwMCkuY29udHJhY3RTZXF1ZW5jZUlkKDEpO1xuXG4gICAgICBjb25zdCB1bnNpZ25lZFR4ID0gYXdhaXQgYnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgdW5zaWduZWRUeEZvckJyb2FkY2FzdGluZyA9IHVuc2lnbmVkVHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgY29uc3QgaGFsZlNpZ25lZFJhd1R4ID0gYXdhaXQgYmFzZWNvaW4uc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgIHR4SGV4OiB1bnNpZ25lZFR4Rm9yQnJvYWRjYXN0aW5nLFxuICAgICAgICB9LFxuICAgICAgICBwcnY6IGFjY291bnRfMS5vd25lcl8yLFxuICAgICAgfSk7XG5cbiAgICAgIGJ1aWxkZXIudHJhbnNmZXIoKS5rZXkoYWNjb3VudF8xLm93bmVyXzIpO1xuICAgICAgY29uc3QgaGFsZlNpZ25lZFR4ID0gYXdhaXQgYnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgaGFsZlNpZ25lZFR4Rm9yQnJvYWRjYXN0aW5nID0gaGFsZlNpZ25lZFR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgIGhhbGZTaWduZWRSYXdUeC5oYWxmU2lnbmVkLnR4SGV4LnNob3VsZC5lcXVhbHMoaGFsZlNpZ25lZFR4Rm9yQnJvYWRjYXN0aW5nKTtcbiAgICAgIGhhbGZTaWduZWRSYXdUeC5oYWxmU2lnbmVkLnJlY2lwaWVudHMubGVuZ3RoLnNob3VsZC5lcXVhbHMoMSk7XG4gICAgICBoYWxmU2lnbmVkUmF3VHguaGFsZlNpZ25lZC5yZWNpcGllbnRzWzBdLmFkZHJlc3MudG9Mb3dlckNhc2UoKS5zaG91bGQuZXF1YWxzKGFjY291bnRfMi5hZGRyZXNzLnRvTG93ZXJDYXNlKCkpO1xuICAgICAgaGFsZlNpZ25lZFJhd1R4LmhhbGZTaWduZWQucmVjaXBpZW50c1swXS5hbW91bnQudG9Mb3dlckNhc2UoKS5zaG91bGQuZXF1YWxzKCcxJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNpZ24gYW4gdW5zaWduZWQgdGVzdCB0eCB3aXRoIGVpcDE1NTknLCBhc3luYyAoKSA9PiB7XG4gICAgICBidWlsZGVyLmZlZSh7XG4gICAgICAgIGZlZTogJzI4MDAwMDAwMDAwMCcsXG4gICAgICAgIGdhc0xpbWl0OiAnNzAwMDAwMCcsXG4gICAgICAgIGVpcDE1NTk6IHtcbiAgICAgICAgICBtYXhGZWVQZXJHYXM6ICc3NTkzMTIzJyxcbiAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogJzE1MCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGJ1aWxkZXIuY291bnRlcigxKTtcbiAgICAgIGJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgICBidWlsZGVyLmNvbnRyYWN0KGFjY291bnRfMS5hZGRyZXNzKTtcbiAgICAgIGNvbnN0IHRyYW5zZmVyQnVpbGRlciA9IGJ1aWxkZXIudHJhbnNmZXIoKSBhcyBUcmFuc2ZlckJ1aWxkZXI7XG4gICAgICB0cmFuc2ZlckJ1aWxkZXIuY29pbihjb2luVGVzdCkuYW1vdW50KCcxJykudG8oYWNjb3VudF8yLmFkZHJlc3MpLmV4cGlyYXRpb25UaW1lKDEwMDAwKS5jb250cmFjdFNlcXVlbmNlSWQoMSk7XG5cbiAgICAgIGNvbnN0IHVuc2lnbmVkVHggPSBhd2FpdCBidWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB1bnNpZ25lZFR4Rm9yQnJvYWRjYXN0aW5nID0gdW5zaWduZWRUeC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICBjb25zdCBoYWxmU2lnbmVkUmF3VHggPSBhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgdHhIZXg6IHVuc2lnbmVkVHhGb3JCcm9hZGNhc3RpbmcsXG4gICAgICAgICAgZWlwMTU1OToge1xuICAgICAgICAgICAgbWF4RmVlUGVyR2FzOiAnNzU5MzEyMycsXG4gICAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogJzE1MCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgcHJ2OiBhY2NvdW50XzEub3duZXJfMixcbiAgICAgIH0pO1xuXG4gICAgICBidWlsZGVyLnRyYW5zZmVyKCkua2V5KGFjY291bnRfMS5vd25lcl8yKTtcbiAgICAgIGNvbnN0IGhhbGZTaWduZWRUeCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IGhhbGZTaWduZWRUeEZvckJyb2FkY2FzdGluZyA9IGhhbGZTaWduZWRUeC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICBoYWxmU2lnbmVkUmF3VHguaGFsZlNpZ25lZC50eEhleC5zaG91bGQuZXF1YWxzKGhhbGZTaWduZWRUeEZvckJyb2FkY2FzdGluZyk7XG4gICAgICBoYWxmU2lnbmVkUmF3VHguaGFsZlNpZ25lZC5yZWNpcGllbnRzLmxlbmd0aC5zaG91bGQuZXF1YWxzKDEpO1xuICAgICAgaGFsZlNpZ25lZFJhd1R4LmhhbGZTaWduZWQucmVjaXBpZW50c1swXS5hZGRyZXNzLnRvTG93ZXJDYXNlKCkuc2hvdWxkLmVxdWFscyhhY2NvdW50XzIuYWRkcmVzcy50b0xvd2VyQ2FzZSgpKTtcbiAgICAgIGhhbGZTaWduZWRSYXdUeC5oYWxmU2lnbmVkLnJlY2lwaWVudHNbMF0uYW1vdW50LnRvTG93ZXJDYXNlKCkuc2hvdWxkLmVxdWFscygnMScpO1xuICAgICAgaGFsZlNpZ25lZFJhd1R4LmhhbGZTaWduZWQuZWlwMTU1OS5tYXhGZWVQZXJHYXMuc2hvdWxkLmVxdWFsKCc3NTkzMTIzJyk7XG4gICAgICBoYWxmU2lnbmVkUmF3VHguaGFsZlNpZ25lZC5laXAxNTU5Lm1heFByaW9yaXR5RmVlUGVyR2FzLnNob3VsZC5lcXVhbCgnMTUwJyk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcnVuVHJhbnNhY3Rpb25WZXJpZmljYXRpb25UZXN0cyhjb2luTmFtZTogc3RyaW5nLCBiaXRnbzogVGVzdEJpdEdvQVBJLCBiYXNlY29pbiwgdGVzdERhdGE6IGFueSkge1xuICBkZXNjcmliZShgJHtjb2luTmFtZX0gVHJhbnNhY3Rpb24gVmVyaWZpY2F0aW9uYCwgKCkgPT4ge1xuICAgIGNvbnN0IGNvaW5UZXN0ID0gdGVzdERhdGEuQ09JTjtcbiAgICBjb25zdCBhZGRyZXNzMSA9ICcweDE3NGNmZDgyM2FmOGNlMjdlZDBhZmVlM2ZjZjNjM2JhMjU5MTE2YmUnO1xuICAgIGNvbnN0IGFkZHJlc3MyID0gJzB4N2U4NWJkYzI3YzA1MGUzOTA1ZWJmNGI4ZTYzNGQ5YWQ2ZWRkMGRlNic7XG4gICAgY29uc3QgaG9wRGVzdGluYXRpb25BZGRyZXNzID0gJzB4OWM3ZThjZTY4MjViRDQ4Mjc4QjNBYjU5MjI4RUUyNmY4QkU3OTI1Yic7XG4gICAgY29uc3QgaG9wVHggPVxuICAgICAgJzB4Zjg2YjgwODUwNGE4MTdjOGZmODI1MmZmOTQ5YzdlOGNlNjgyNWJkNDgyNzhiM2FiNTkyMjhlZTI2ZjhiZTc5MjViODcwMzhkN2VhNGM2ODAwMDgwMWNhMDExYmMyMmM2NjQ1NzAxMzNkZmNhNGYwOGEwYjhkMDIzMzljZjQ2NzA0NmQ2YTQxNTJmMDRmMzY4ZDBlYWY5OWVhMDFkNmRjNWNmMGM4OTdjOGQ0YzNlMWRmNTNkMGQwNDI3ODRjNDI0NTM2YTRjYzViODAyNTUyYjdkNjRmZWU4YjUnO1xuICAgIGNvbnN0IGhvcFR4aWQgPSAnMHg0YWY2NTE0M2JjNzdkYTJiNTBmMzViM2QxM2NhY2I0ZGIxOGYwMjZiZjg0YmMwNzQzNTUwYmM1N2I5YjUzMzUxJztcbiAgICBjb25zdCB1c2VyUmVxU2lnID1cbiAgICAgICcweDQwNGRiMzA3ZjYxNDdmMGQ4Y2QzMzhjMzRjMTM5MDZlZjQ2YTZmYWE3ZTBlMTE5ZDUxOTRlZjA1YWVjMTZlNmYzZDcxMGY5Yjc5MDE0NjBmOTdlOTI0MDY2YjYyZWZkNzQ0NDNiZDM0NDAyYzZkNDBiNDljMjAzYTU1OWZmMmM4JztcbiAgICBjb25zdCBiaXRnb0tleVhwcnYgPVxuICAgICAgJ3hwcnY5czIxWnJRSDE0M0szdHBXQkhXZTMxc0xvWE5SUTlBdlJZSmdpdGtLeFE0QVRGUU13dnI3aEhOcVlSVW5TN1BzanpCN2FLMVZ4cUhMdU5Ramoxc2NrSjJKd28ycXhtc3ZlandFQ1NwRk1mQyc7XG4gICAgY29uc3QgYml0Z29LZXkgPSBiaXAzMi5mcm9tQmFzZTU4KGJpdGdvS2V5WHBydik7XG4gICAgaWYgKCFiaXRnb0tleS5wcml2YXRlS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIHByaXZhdGVLZXknKTtcbiAgICB9XG4gICAgY29uc3QgaG9wVHhCaXRnb1NpZ25hdHVyZSA9XG4gICAgICAnMHhhYScgK1xuICAgICAgQnVmZmVyLmZyb20oc2VjcDI1NmsxLmVjZHNhU2lnbihCdWZmZXIuZnJvbShob3BUeGlkLnNsaWNlKDIpLCAnaGV4JyksIGJpdGdvS2V5LnByaXZhdGVLZXkpLnNpZ25hdHVyZSkudG9TdHJpbmcoXG4gICAgICAgICdoZXgnXG4gICAgICApO1xuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgbm9ybWFsIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHRoYXQgbWF0Y2hlcyB0aGUgY2xpZW50IHR4UGFyYW1zJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46IGNvaW5UZXN0LFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IHdoZW4gY2xpZW50IHR4UGFyYW1zIGFyZSBtaXNzaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSBudWxsO1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46IGNvaW5UZXN0LFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyBwYXJhbXMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IHR4UHJlYnVpbGQgdGhhdCBpcyBib3RoIGJhdGNoIGFuZCBob3AnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH0sXG4gICAgICAgICAgeyBhbW91bnQ6ICcyNTAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICAgIGhvcDogdHJ1ZSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzM1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiB0cnVlLFxuICAgICAgICBjb2luOiBjb2luVGVzdCxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgICAgaG9wVHJhbnNhY3Rpb246IHtcbiAgICAgICAgICB0eDogaG9wVHgsXG4gICAgICAgICAgaWQ6IGhvcFR4aWQsXG4gICAgICAgICAgc2lnbmF0dXJlOiBob3BUeEJpdGdvU2lnbmF0dXJlLFxuICAgICAgICAgIHBheW1lbnRJZDogJzI3NzM5MjgxOTYnLFxuICAgICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAwMDAwMDAwMDAnLFxuICAgICAgICAgIHJlY2lwaWVudDogaG9wRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICAgIG5vbmNlOiAwLFxuICAgICAgICAgIHVzZXJSZXFTaWc6IHVzZXJSZXFTaWcsXG4gICAgICAgICAgZ2FzUHJpY2VNYXg6IDUwMDAwMDAwMDAwMCxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3R4IGNhbm5vdCBiZSBib3RoIGEgYmF0Y2ggYW5kIGhvcCB0cmFuc2FjdGlvbicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSB0eFByZWJ1aWxkIHdpdGggbW9yZSB0aGFuIG9uZSByZWNpcGllbnQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH0sXG4gICAgICAgICAgeyBhbW91bnQ6ICcyNTAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzI1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IHRydWUsXG4gICAgICAgIGNvaW46IGNvaW5UZXN0LFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICBgJHtjb2luVGVzdH0gZG9lc24ndCBzdXBwb3J0IHNlbmRpbmcgdG8gbW9yZSB0aGFuIDEgZGVzdGluYXRpb24gYWRkcmVzcyB3aXRoaW4gYSBzaW5nbGUgdHJhbnNhY3Rpb24uIFRyeSBhZ2FpbiwgdXNpbmcgb25seSBhIHNpbmdsZSByZWNpcGllbnQuYFxuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBob3AgdHhQcmVidWlsZCB0aGF0IGRvZXMgbm90IHNlbmQgdG8gaXRzIGhvcCBhZGRyZXNzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBob3BEZXN0aW5hdGlvbkFkZHJlc3MgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgICBob3A6IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICc1MDAwMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46IGNvaW5UZXN0LFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgICBob3BUcmFuc2FjdGlvbjoge1xuICAgICAgICAgIHR4OiBob3BUeCxcbiAgICAgICAgICBpZDogaG9wVHhpZCxcbiAgICAgICAgICBzaWduYXR1cmU6IGhvcFR4Qml0Z29TaWduYXR1cmUsXG4gICAgICAgICAgcGF5bWVudElkOiAnMCcsXG4gICAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgICAgYW1vdW50OiAnMTAwMDAwMDAwMDAwMDAwMCcsXG4gICAgICAgICAgcmVjaXBpZW50OiBob3BEZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgICAgbm9uY2U6IDAsXG4gICAgICAgICAgdXNlclJlcVNpZzogdXNlclJlcVNpZyxcbiAgICAgICAgICBnYXNQcmljZU1heDogNTAwMDAwMDAwMDAwLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgncmVjaXBpZW50IGFkZHJlc3Mgb2YgdHhQcmVidWlsZCBkb2VzIG5vdCBtYXRjaCBob3AgYWRkcmVzcycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBub3JtYWwgdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgd2l0aCB0aGUgd3JvbmcgYW1vdW50JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcyMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46IGNvaW5UZXN0LFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnbm9ybWFsIHRyYW5zYWN0aW9uIGFtb3VudCBpbiB0eFByZWJ1aWxkIHJlY2VpdmVkIGZyb20gQml0R28gc2VydmVycyBkb2VzIG5vdCBtYXRjaCB0eFBhcmFtcyBzdXBwbGllZCBieSBjbGllbnQnXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIG5vcm1hbCB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB3aXRoIHRoZSB3cm9uZyByZWNpcGllbnQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogY29pblRlc3QsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdkZXN0aW5hdGlvbiBhZGRyZXNzIGluIG5vcm1hbCB0eFByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIHRoYXQgaW4gdHhQYXJhbXMgc3VwcGxpZWQgYnkgY2xpZW50J1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB3aXRoIHRoZSB3cm9uZyBjb2luJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICdidGMnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnY29pbiBpbiB0eFByZWJ1aWxkIGRpZCBub3QgbWF0Y2ggdGhhdCBpbiB0eFBhcmFtcyBzdXBwbGllZCBieSBjbGllbnQnKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBydW5SZWNvdmVyeVRyYW5zYWN0aW9uVGVzdHMoXG4gIGNvaW5OYW1lOiBzdHJpbmcsXG4gIHR4QnVpbGRlcjogVHJhbnNhY3Rpb25CdWlsZGVyLFxuICBiaXRnbzogVGVzdEJpdEdvQVBJLFxuICB0ZXN0RGF0YTogYW55LFxuICBtb2NrRGF0YTogYW55XG4pIHtcbiAgZGVzY3JpYmUoYCR7Y29pbk5hbWV9IFJlY292ZXIgdHJhbnNhY3Rpb246YCwgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGJhc2VVcmwgPSB0ZXN0RGF0YS5CQVNFX1VSTDtcbiAgICBjb25zdCB1c2VyWHB1YiA9XG4gICAgICAneHB1YjY2MU15TXdBcVJiY0VlVGM4Nzg5TUs1UFVHRVlpUEc0RjRWMTduMlJkMkxvVEFUQTFYb0NuSlQ1RkFZQVNoUXhTeHRGanBvNU5IbWNXd1RwMkxpV0dCTXdwVWNBQTNIeXdoeGl2Z1lmcTdxJztcbiAgICBjb25zdCB1c2VyWHBydiA9XG4gICAgICAneHBydjlzMjFaclFIMTQzSzJBUDkyNWI4ekI4ZXZFUTRKdllDc3FaUUtQY3A0Z29wYU44MVR6VXhFVzhiUHRWeURnam1kZEdoUlJFVG44eGkxY1ZBQjliZjFCeDlrR1JSRmdUWlh4SmF5WkxuYWcxJztcbiAgICBjb25zdCBiYWNrdXBYcHViID1cbiAgICAgICd4cHViNjYxTXlNd0FxUmJjRlpYMTV4cFpmNEVSQ0dIaVZTSm04cjVDNHloMXlYVjJHcmRaQ1VQWW80V1FyNnROOW9VeXdLWHNnU0hvN1Jpc2Y5cjIyR0g1am9WRDJoRUVFaHFuU0N2SzhxeTExd1cnO1xuICAgIGNvbnN0IGJhY2t1cFhwcnYgPVxuICAgICAgJ3hwcnY5czIxWnJRSDE0M0szNVNYeXdIWkh2SGdlRVRFNXlhdW1kOWJHYkhRUkJ4M1E0SlFldzVKRkdCdnpxaVpqQ1VrQmRCVVpuZnVNRFRHVVJSYXlOMWhGU1d4RUpRc0NFQU1tMUQzcGsxaDdKaic7XG4gICAgY29uc3QgY29pbiA9IHRlc3REYXRhLkNPSU47XG5cbiAgICBhZnRlcihmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGFuIHVuc2lnbmVkIHN3ZWVwJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgd2FsbGV0Q29udHJhY3RBZGRyZXNzID0gVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTIGFzIHN0cmluZztcbiAgICAgIGNvbnN0IGJhY2t1cEtleUFkZHJlc3MgPSAnMHg0ZjJjNDgzMGNjMzdmMjc4NWM2NDZmODlkZWQ4YTkxOTIxOWZhMGU5JztcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC50d2ljZSgpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KGJhY2t1cEtleUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3Qod2FsbGV0Q29udHJhY3RBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChiYWNrdXBLZXlBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG4gICAgICBjb25zdCBiYXNlY29pbjogYW55ID0gYml0Z28uY29pbihjb2luKTtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gKGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB1c2VyWHB1YixcbiAgICAgICAgYmFja3VwS2V5OiBiYWNrdXBYcHViLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogVGVzdEJpdEdvLlYyLlRFU1RfRVJDMjBfVE9LRU5fUkVDSVBJRU5UIGFzIHN0cmluZyxcbiAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgIH0pKSBhcyBPZmZsaW5lVmF1bHRUeEluZm87XG4gICAgICBzaG91bGQuZXhpc3QodHJhbnNhY3Rpb24pO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4SGV4Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29udHJhY3RTZXF1ZW5jZUlkJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZXhwaXJlVGltZScpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc0xpbWl0Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5nYXNMaW1pdC5zaG91bGQuZXF1YWwoJzUwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldENvbnRyYWN0QWRkcmVzcycpO1xuICAgICAgdHJhbnNhY3Rpb24ud2FsbGV0Q29udHJhY3RBZGRyZXNzLnNob3VsZC5lcXVhbChUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudHMnKTtcbiAgICAgIGNvbnN0IHJlY2lwaWVudCA9IHRyYW5zYWN0aW9uLnJlY2lwaWVudHNbMF07XG4gICAgICByZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FkZHJlc3MnKTtcbiAgICAgIHJlY2lwaWVudC5hZGRyZXNzLnNob3VsZC5lcXVhbChUZXN0Qml0R28uVjIuVEVTVF9FUkMyMF9UT0tFTl9SRUNJUElFTlQpO1xuICAgICAgcmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhbW91bnQnKTtcbiAgICAgIHJlY2lwaWVudC5hbW91bnQuc2hvdWxkLmVxdWFsKCc5OTk5OTk5OTk5OTk5OTk5OTI4Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNvbnN0cnVjdCBhIHJlY292ZXJ5IHRyYW5zYWN0aW9uIHdpdGhvdXQgQml0R28nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBiYWNrdXBLZXlBZGRyZXNzID0gJzB4NmQyMmVmZGQ2MzQ5OTYyNDgxNzBjOTQ4ZTU3MjYwMDdmYzI1MWJiMyc7XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MgYXMgc3RyaW5nO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldFR4TGlzdFJlcXVlc3QoYmFja3VwS2V5QWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldFR4TGlzdFJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdCh3YWxsZXRDb250cmFjdEFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KGJhY2t1cEtleUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcbiAgICAgIGNvbnN0IGJhc2Vjb2luOiBhbnkgPSBiaXRnby5jb2luKGNvaW4pO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6XG4gICAgICAgICAgJ3tcIml2XCI6XCJWRlozanZYaHhvMVorWWFmMk10Wm5BPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiXFxuJyArXG4gICAgICAgICAgJzpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcInArZmtIdUxhLzhrPVwiLFwiY3RcIjpcImhZRzdwdmxqTElnQ2paXFxuJyArXG4gICAgICAgICAgJzUzUEJsQ2RlNUtaUm1sVUtLSEx0RE1rK0hKZnVVNDZoVyt4K0M5V3NJQU80Z0ZQblRDdkZWbVE4eDdjekN0Y05GdWI1QU8yb3RPR1xcbicgK1xuICAgICAgICAgICdPc1g0R0UyZ1hPRW1DbDFUcFd3d05obTd5TVVqR0pVcGdXNlpaZ1hTWGREaXRTS2k0Vi9oazc4U0dTempGT0JTUFlSYTZJPVwifVxcbicsXG4gICAgICAgIGJhY2t1cEtleTpcbiAgICAgICAgICAne1wiaXZcIjpcIkFic0N0djFxd1BJaE9neXJDcE5hZ0E9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCJcXG4nICtcbiAgICAgICAgICAnOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiNXZwVURCVWx6bTg9XCIsXCJjdFwiOlwiUGFwWVlDakJYUkxVS0FcXG4nICtcbiAgICAgICAgICAnSmJPc0IvRUo5QjhmVW1WUVR4TVBqVW5ReUFreTEybWU5SzY2R2lNRUF4VEQ3a2Q2YllBUUp1dVRrQVRYS1U3Qm5mN3ZLOUp4Tk93XFxuJyArXG4gICAgICAgICAgJ29qaTdIRjllRkgwYUQ0L2hYNVNXRmZIRjJRZmkrVG5YdjZoVnNNQW9pc0RaczMvRjY3L1pVYURZUjBac2RyUTRRL2NMRDA9XCJ9XFxuJyxcblxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlYyLlRFU1RfUkVDT1ZFUllfUEFTU0NPREUsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IFRlc3RCaXRHby5WMi5URVNUX0VSQzIwX1RPS0VOX1JFQ0lQSUVOVCBhcyBzdHJpbmcsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICB9KSkgYXMgT2ZmbGluZVZhdWx0VHhJbmZvO1xuICAgICAgc2hvdWxkLmV4aXN0KHRyYW5zYWN0aW9uKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lkJyk7XG4gICAgICBjb25zdCBkZWNvZGVkVHggPSBvcHRpb25hbERlcHMuRXRoVHguVHJhbnNhY3Rpb24uZnJvbVNlcmlhbGl6ZWRUeChvcHRpb25hbERlcHMuZXRoVXRpbC50b0J1ZmZlcih0cmFuc2FjdGlvbi50eCkpO1xuICAgICAgZGVjb2RlZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdnYXNQcmljZScpO1xuICAgICAgZGVjb2RlZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdub25jZScpO1xuICAgICAgZGVjb2RlZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0bycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBiZSBhYmxlIHRvIHNlY29uZCBzaWduJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgd2FsbGV0Q29udHJhY3RBZGRyZXNzID0gVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTIGFzIHN0cmluZztcbiAgICAgIGNvbnN0IGJhY2t1cEtleUFkZHJlc3MgPSAnMHg0ZjJjNDgzMGNjMzdmMjc4NWM2NDZmODlkZWQ4YTkxOTIxOWZhMGU5JztcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC50d2ljZSgpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KGJhY2t1cEtleUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3Qod2FsbGV0Q29udHJhY3RBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChiYWNrdXBLZXlBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG4gICAgICBjb25zdCBiYXNlY29pbjogYW55ID0gYml0Z28uY29pbihjb2luKTtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gKGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB1c2VyWHB1YixcbiAgICAgICAgYmFja3VwS2V5OiBiYWNrdXBYcHViLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogVGVzdEJpdEdvLlYyLlRFU1RfRVJDMjBfVE9LRU5fUkVDSVBJRU5UIGFzIHN0cmluZyxcbiAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSxcbiAgICAgICAgcmVwbGF5UHJvdGVjdGlvbk9wdGlvbnM6IHsgY2hhaW46IDgwMDAxLCBoYXJkZm9yazogJ2xvbmRvbicgfSxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgIH0pKSBhcyBPZmZsaW5lVmF1bHRUeEluZm87XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OiB0cmFuc2FjdGlvbi50eEhleCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgcHJ2OiB1c2VyWHBydixcbiAgICAgIH07XG4gICAgICAvLyBzaWduIHRyYW5zYWN0aW9uIG9uY2VcbiAgICAgIGNvbnN0IGhhbGZTaWduZWQgPSBhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24ocGFyYW1zIGFzIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMpO1xuICAgICAgY29uc3QgaGFsZlNpZ25lZFBhcmFtcyA9IHtcbiAgICAgICAgdHhQcmVidWlsZDogaGFsZlNpZ25lZCxcbiAgICAgICAgaXNMYXN0U2lnbmF0dXJlOiB0cnVlLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgcHJ2OiBiYWNrdXBYcHJ2LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgZmluYWxTaWduZWQgPSAoYXdhaXQgYmFzZWNvaW4uc2lnblRyYW5zYWN0aW9uKFxuICAgICAgICBoYWxmU2lnbmVkUGFyYW1zIGFzIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnNcbiAgICAgICkpIGFzIEZ1bGx5U2lnbmVkVHJhbnNhY3Rpb247XG4gICAgICBmaW5hbFNpZ25lZC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhIZXgnKTtcbiAgICAgIHR4QnVpbGRlci5mcm9tKGZpbmFsU2lnbmVkLnR4SGV4KTtcbiAgICAgIGNvbnN0IHJlYnVpbHRUeCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgcmVidWlsdFR4LnNpZ25hdHVyZS5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgcmVidWlsdFR4Lm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICB9KTtcbiAgfSk7XG59XG4iXX0=