@bitgo/sdk-coin-opeth 18.7.2 → 18.7.3

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 (35) hide show
  1. package/dist/test/fixtures/opeth.d.ts +54 -0
  2. package/dist/test/fixtures/opeth.d.ts.map +1 -0
  3. package/dist/test/fixtures/opeth.js +66 -0
  4. package/dist/test/getBuilder.d.ts +3 -0
  5. package/dist/test/getBuilder.d.ts.map +1 -0
  6. package/dist/test/getBuilder.js +9 -0
  7. package/dist/test/resources.d.ts +31 -0
  8. package/dist/test/resources.d.ts.map +1 -0
  9. package/dist/test/resources.js +45 -0
  10. package/dist/test/unit/opeth.d.ts +2 -0
  11. package/dist/test/unit/opeth.d.ts.map +1 -0
  12. package/dist/test/unit/opeth.js +902 -0
  13. package/dist/test/unit/opethToken.d.ts +2 -0
  14. package/dist/test/unit/opethToken.d.ts.map +1 -0
  15. package/dist/test/unit/opethToken.js +46 -0
  16. package/dist/test/unit/transaction.d.ts +2 -0
  17. package/dist/test/unit/transaction.d.ts.map +1 -0
  18. package/dist/test/unit/transaction.js +92 -0
  19. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts +2 -0
  20. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts.map +1 -0
  21. package/dist/test/unit/transactionBuilder/addressInitialization.js +105 -0
  22. package/dist/test/unit/transactionBuilder/send.d.ts +2 -0
  23. package/dist/test/unit/transactionBuilder/send.d.ts.map +1 -0
  24. package/dist/test/unit/transactionBuilder/send.js +173 -0
  25. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts +2 -0
  26. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts.map +1 -0
  27. package/dist/test/unit/transactionBuilder/walletInitialization.js +135 -0
  28. package/dist/test/unit/transferBuilder.d.ts +2 -0
  29. package/dist/test/unit/transferBuilder.d.ts.map +1 -0
  30. package/dist/test/unit/transferBuilder.js +137 -0
  31. package/dist/tsconfig.tsbuildinfo +1 -0
  32. package/package.json +10 -7
  33. package/.eslintignore +0 -4
  34. package/.mocharc.yml +0 -8
  35. package/CHANGELOG.md +0 -1016
@@ -0,0 +1,902 @@
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
+ const should = __importStar(require("should"));
40
+ const secp256k1_1 = require("@bitgo/secp256k1");
41
+ const secp256k1 = __importStar(require("secp256k1"));
42
+ const nock_1 = __importDefault(require("nock"));
43
+ const sdk_core_1 = require("@bitgo/sdk-core");
44
+ const sdk_test_1 = require("@bitgo/sdk-test");
45
+ const sdk_api_1 = require("@bitgo/sdk-api");
46
+ const abstract_eth_1 = require("@bitgo/abstract-eth");
47
+ const index_1 = require("../../src/index");
48
+ const mockData = __importStar(require("../fixtures/opeth"));
49
+ const getBuilder_1 = require("../getBuilder");
50
+ nock_1.default.enableNetConnect();
51
+ describe('Optimism', function () {
52
+ let bitgo;
53
+ let basecoin;
54
+ let hopTxBitgoSignature;
55
+ const address1 = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
56
+ const address2 = '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6';
57
+ const hopContractAddress = '0x47ce7cc86efefef19f8fb516b11735d183da8635';
58
+ const hopDestinationAddress = '0x9c7e8ce6825bD48278B3Ab59228EE26f8BE7925b';
59
+ const hopTx = '0xf86b808504a817c8ff8252ff949c7e8ce6825bd48278b3ab59228ee26f8be7925b87038d7ea4c68000801ca011bc22c664570133dfca4f08a0b8d02339cf467046d6a4152f04f368d0eaf99ea01d6dc5cf0c897c8d4c3e1df53d0d042784c424536a4cc5b802552b7d64fee8b5';
60
+ const hopTxid = '0x4af65143bc77da2b50f35b3d13cacb4db18f026bf84bc0743550bc57b9b53351';
61
+ const userReqSig = '0x404db307f6147f0d8cd338c34c13906ef46a6faa7e0e119d5194ef05aec16e6f3d710f9b7901460f97e924066b62efd74443bd34402c6d40b49c203a559ff2c8';
62
+ before(function () {
63
+ const bitgoKeyXprv = 'xprv9s21ZrQH143K3tpWBHWe31sLoXNRQ9AvRYJgitkKxQ4ATFQMwvr7hHNqYRUnS7PsjzB7aK1VxqHLuNQjj1sckJ2Jwo2qxmsvejwECSpFMfC';
64
+ const bitgoKey = secp256k1_1.bip32.fromBase58(bitgoKeyXprv);
65
+ if (!bitgoKey.privateKey) {
66
+ throw new Error('no privateKey');
67
+ }
68
+ const bitgoXpub = bitgoKey.neutered().toBase58();
69
+ hopTxBitgoSignature =
70
+ '0xaa' +
71
+ Buffer.from(secp256k1.ecdsaSign(Buffer.from(hopTxid.slice(2), 'hex'), bitgoKey.privateKey).signature).toString('hex');
72
+ const env = 'test';
73
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env });
74
+ sdk_core_1.common.Environments[env].hsmXpub = bitgoXpub;
75
+ bitgo.safeRegister('opeth', index_1.Opeth.createInstance);
76
+ bitgo.safeRegister('topeth', index_1.Topeth.createInstance);
77
+ bitgo.initializeTestVars();
78
+ basecoin = bitgo.coin('topeth');
79
+ });
80
+ /**
81
+ * Build an unsigned account-lib multi-signature send transactino
82
+ * @param destination The destination address of the transaction
83
+ * @param contractAddress The address of the smart contract processing the transaction
84
+ * @param contractSequenceId The sequence id of the contract
85
+ * @param nonce The nonce of the sending address
86
+ * @param expireTime The expire time of the transaction
87
+ * @param amount The amount to send to the recipient
88
+ * @param gasPrice The gas price of the transaction
89
+ * @param gasLimit The gas limit of the transaction
90
+ */
91
+ const buildUnsignedTransaction = async function ({ destination, contractAddress, contractSequenceId = 1, nonce = 0, expireTime = Math.floor(new Date().getTime() / 1000), amount = '100000', gasPrice = '10000', gasLimit = '20000', }) {
92
+ const txBuilder = (0, getBuilder_1.getBuilder)('topeth');
93
+ txBuilder.type(sdk_core_1.TransactionType.Send);
94
+ txBuilder.fee({
95
+ fee: gasPrice,
96
+ gasLimit: gasLimit,
97
+ });
98
+ txBuilder.counter(nonce);
99
+ txBuilder.contract(contractAddress);
100
+ const transferBuilder = txBuilder.transfer();
101
+ transferBuilder
102
+ .coin('topeth')
103
+ .expirationTime(expireTime)
104
+ .amount(amount)
105
+ .to(destination)
106
+ .contractSequenceId(contractSequenceId);
107
+ return await txBuilder.build();
108
+ };
109
+ describe('Basic Coin Info', function () {
110
+ it('should return the right info for opeth', function () {
111
+ const opeth = bitgo.coin('opeth');
112
+ opeth.should.be.an.instanceof(index_1.Opeth);
113
+ opeth.getChain().should.equal('opeth');
114
+ opeth.getFamily().should.equal('opeth');
115
+ opeth.getFullName().should.equal('Optimism Ethereum (L2 Chain)');
116
+ opeth.getBaseFactor().should.equal(1e18);
117
+ });
118
+ it('should return the right info for topeth', function () {
119
+ const topeth = bitgo.coin('topeth');
120
+ topeth.should.be.an.instanceof(index_1.Topeth);
121
+ topeth.getChain().should.equal('topeth');
122
+ topeth.getFamily().should.equal('opeth');
123
+ topeth.getFullName().should.equal('Testnet Optimism Ethereum (L2 Chain)');
124
+ topeth.getBaseFactor().should.equal(1e18);
125
+ });
126
+ });
127
+ describe('Explain transaction:', () => {
128
+ it('should fail if the options object is missing parameters', async function () {
129
+ const explainParams = {
130
+ feeInfo: { fee: 1 },
131
+ txHex: null,
132
+ };
133
+ await basecoin.explainTransaction(explainParams).should.be.rejectedWith('missing explain tx parameters');
134
+ });
135
+ it('explain a transfer transaction', async function () {
136
+ const destination = '0xfaa8f14f46a99eb439c50e0c3b835cc21dad51b4';
137
+ const contractAddress = '0x9e2c5712ab4caf402a98c4bf58c79a0dfe718ad1';
138
+ const unsignedTransaction = await buildUnsignedTransaction({
139
+ destination,
140
+ contractAddress,
141
+ });
142
+ const explainParams = {
143
+ halfSigned: {
144
+ txHex: unsignedTransaction.toBroadcastFormat(),
145
+ },
146
+ feeInfo: { fee: 1 },
147
+ };
148
+ const explanation = await basecoin.explainTransaction(explainParams);
149
+ should.exist(explanation.id);
150
+ });
151
+ });
152
+ describe('Sign Transaction', () => {
153
+ const account_1 = {
154
+ address: '0x8Ce59c2d1702844F8EdED451AA103961bC37B4e8',
155
+ owner_1: '4ee089aceabf3ddbf748db79b1066c33b7d3ea1ab3eb7e325121bba2bff2f5ca',
156
+ owner_2: '5c7e4efff7304d4dfff6d5f1591844ec6f2adfa6a47e9fece6a3c1a4d755f1e3',
157
+ owner_3: '4421ab25dd91e1a3180d03d57c323a7886dcc313d3b3a4b4256a5791572bf597',
158
+ };
159
+ const account_2 = {
160
+ address: '0xeeaf0F05f37891ab4a21208B105A0687d12c5aF7',
161
+ owner_1: '4ee089aceabf3ddbf748db79b1066c33b7d3ea1ab3eb7e325121bba2bff2f5ca',
162
+ owner_2: '5ca116d25aec5f765465432cc421ff25ef9ffdc330b10bb3d9ad61e3baad88d7',
163
+ owner_3: '1fae946cc84af8bd74d610a88537e24e19c3349d478d86fc5bb59ba4c88fb9cc',
164
+ };
165
+ it('should sign an unsigned test tx', async function () {
166
+ const builder = (0, getBuilder_1.getBuilder)('topeth');
167
+ builder.fee({
168
+ fee: '280000000000',
169
+ gasLimit: '7000000',
170
+ });
171
+ builder.counter(1);
172
+ builder.type(sdk_core_1.TransactionType.Send);
173
+ builder.contract(account_1.address);
174
+ const transferBuilder = builder.transfer();
175
+ transferBuilder.coin('topeth').amount('1').to(account_2.address).expirationTime(10000).contractSequenceId(1);
176
+ const unsignedTx = await builder.build();
177
+ const unsignedTxForBroadcasting = unsignedTx.toBroadcastFormat();
178
+ const halfSignedRawTx = await basecoin.signTransaction({
179
+ txPrebuild: {
180
+ txHex: unsignedTxForBroadcasting,
181
+ },
182
+ prv: account_1.owner_2,
183
+ });
184
+ builder.transfer().key(account_1.owner_2);
185
+ const halfSignedTx = await builder.build();
186
+ const halfSignedTxForBroadcasting = halfSignedTx.toBroadcastFormat();
187
+ halfSignedRawTx.halfSigned.txHex.should.equals(halfSignedTxForBroadcasting);
188
+ halfSignedRawTx.halfSigned.recipients.length.should.equals(1);
189
+ halfSignedRawTx.halfSigned.recipients[0].address.toLowerCase().should.equals(account_2.address.toLowerCase());
190
+ halfSignedRawTx.halfSigned.recipients[0].amount.toLowerCase().should.equals('1');
191
+ });
192
+ it('should sign an unsigned test tx with eip1559', async function () {
193
+ const builder = (0, getBuilder_1.getBuilder)('topeth');
194
+ builder.fee({
195
+ fee: '280000000000',
196
+ gasLimit: '7000000',
197
+ eip1559: {
198
+ maxFeePerGas: '7593123',
199
+ maxPriorityFeePerGas: '150',
200
+ },
201
+ });
202
+ builder.counter(1);
203
+ builder.type(sdk_core_1.TransactionType.Send);
204
+ builder.contract(account_1.address);
205
+ const transferBuilder = builder.transfer();
206
+ transferBuilder.coin('topeth').amount('1').to(account_2.address).expirationTime(10000).contractSequenceId(1);
207
+ const unsignedTx = await builder.build();
208
+ const unsignedTxForBroadcasting = unsignedTx.toBroadcastFormat();
209
+ const halfSignedRawTx = await basecoin.signTransaction({
210
+ txPrebuild: {
211
+ txHex: unsignedTxForBroadcasting,
212
+ eip1559: {
213
+ maxFeePerGas: '7593123',
214
+ maxPriorityFeePerGas: '150',
215
+ },
216
+ },
217
+ prv: account_1.owner_2,
218
+ });
219
+ builder.transfer().key(account_1.owner_2);
220
+ const halfSignedTx = await builder.build();
221
+ const halfSignedTxForBroadcasting = halfSignedTx.toBroadcastFormat();
222
+ halfSignedRawTx.halfSigned.txHex.should.equals(halfSignedTxForBroadcasting);
223
+ halfSignedRawTx.halfSigned.recipients.length.should.equals(1);
224
+ halfSignedRawTx.halfSigned.recipients[0].address.toLowerCase().should.equals(account_2.address.toLowerCase());
225
+ halfSignedRawTx.halfSigned.recipients[0].amount.toLowerCase().should.equals('1');
226
+ halfSignedRawTx.halfSigned.eip1559.maxFeePerGas.should.equal('7593123');
227
+ halfSignedRawTx.halfSigned.eip1559.maxPriorityFeePerGas.should.equal('150');
228
+ });
229
+ it('should sign an unsigned test tx with data', async function () {
230
+ const builder = (0, getBuilder_1.getBuilder)('topeth');
231
+ builder.fee({
232
+ fee: '280000000000',
233
+ gasLimit: '7000000',
234
+ eip1559: {
235
+ maxFeePerGas: '7593123',
236
+ maxPriorityFeePerGas: '150',
237
+ },
238
+ });
239
+ builder.counter(1);
240
+ builder.type(sdk_core_1.TransactionType.Send);
241
+ builder.contract(account_1.address);
242
+ const transferBuilder = builder.transfer();
243
+ transferBuilder.coin('topeth').amount('1').to(account_2.address).expirationTime(10000).contractSequenceId(1);
244
+ const unsignedTx = await builder.build();
245
+ const unsignedTxForBroadcasting = unsignedTx.toBroadcastFormat();
246
+ const halfSignedRawTx = await basecoin.signTransaction({
247
+ txPrebuild: {
248
+ txHex: unsignedTxForBroadcasting,
249
+ eip1559: {
250
+ maxFeePerGas: '7593123',
251
+ maxPriorityFeePerGas: '150',
252
+ },
253
+ recipients: [
254
+ {
255
+ address: account_2.address,
256
+ amount: '1',
257
+ data: '0xaaaa',
258
+ },
259
+ ],
260
+ },
261
+ prv: account_1.owner_2,
262
+ });
263
+ builder.transfer().key(account_1.owner_2);
264
+ const halfSignedTx = await builder.build();
265
+ const halfSignedTxForBroadcasting = halfSignedTx.toBroadcastFormat();
266
+ halfSignedRawTx.halfSigned.txHex.should.equals(halfSignedTxForBroadcasting);
267
+ halfSignedRawTx.halfSigned.recipients.length.should.equals(1);
268
+ halfSignedRawTx.halfSigned.recipients[0].address.toLowerCase().should.equals(account_2.address.toLowerCase());
269
+ halfSignedRawTx.halfSigned.recipients[0].amount.toLowerCase().should.equals('1');
270
+ halfSignedRawTx.halfSigned.recipients[0].data.toLowerCase().should.equals('0xaaaa');
271
+ halfSignedRawTx.halfSigned.eip1559.maxFeePerGas.should.equal('7593123');
272
+ halfSignedRawTx.halfSigned.eip1559.maxPriorityFeePerGas.should.equal('150');
273
+ });
274
+ });
275
+ describe('Transaction Verification', function () {
276
+ it('should verify a normal txPrebuild from the bitgo server that matches the client txParams', async function () {
277
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
278
+ const txParams = {
279
+ recipients: [{ amount: '1000000000000', address: address1 }],
280
+ wallet: wallet,
281
+ walletPassphrase: 'fakeWalletPassphrase',
282
+ };
283
+ const txPrebuild = {
284
+ recipients: [{ amount: '1000000000000', address: address1 }],
285
+ nextContractSequenceId: 0,
286
+ gasPrice: 20000000000,
287
+ gasLimit: 500000,
288
+ isBatch: false,
289
+ coin: 'topeth',
290
+ walletId: 'fakeWalletId',
291
+ walletContractAddress: 'fakeWalletContractAddress',
292
+ };
293
+ const verification = {};
294
+ const isTransactionVerified = await basecoin.verifyTransaction({ txParams, txPrebuild, wallet, verification });
295
+ isTransactionVerified.should.equal(true);
296
+ });
297
+ it('should verify a hop txPrebuild from the bitgo server that matches the client txParams', async function () {
298
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
299
+ const txParams = {
300
+ recipients: [{ amount: 1000000000000000, address: hopDestinationAddress }],
301
+ wallet: wallet,
302
+ walletPassphrase: 'fakeWalletPassphrase',
303
+ hop: true,
304
+ };
305
+ const txPrebuild = {
306
+ recipients: [{ amount: '5000000000000000', address: hopContractAddress }],
307
+ nextContractSequenceId: 0,
308
+ gasPrice: 20000000000,
309
+ gasLimit: 500000,
310
+ isBatch: false,
311
+ coin: 'topeth',
312
+ walletId: 'fakeWalletId',
313
+ walletContractAddress: 'fakeWalletContractAddress',
314
+ hopTransaction: {
315
+ tx: hopTx,
316
+ id: hopTxid,
317
+ signature: hopTxBitgoSignature,
318
+ paymentId: '2773928196',
319
+ gasPrice: 20000000000,
320
+ gasLimit: 500000,
321
+ amount: '1000000000000000',
322
+ recipient: hopDestinationAddress,
323
+ nonce: 0,
324
+ userReqSig: userReqSig,
325
+ gasPriceMax: 500000000000,
326
+ },
327
+ };
328
+ const verification = {};
329
+ const isTransactionVerified = await basecoin.verifyTransaction({ txParams, txPrebuild, wallet, verification });
330
+ isTransactionVerified.should.equal(true);
331
+ });
332
+ it('should reject when client txParams are missing', async function () {
333
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
334
+ const txParams = null;
335
+ const txPrebuild = {
336
+ recipients: [{ amount: '1000000000000', address: address1 }],
337
+ nextContractSequenceId: 0,
338
+ gasPrice: 20000000000,
339
+ gasLimit: 500000,
340
+ isBatch: false,
341
+ coin: 'topeth',
342
+ walletId: 'fakeWalletId',
343
+ walletContractAddress: 'fakeWalletContractAddress',
344
+ };
345
+ const verification = {};
346
+ await basecoin
347
+ .verifyTransaction({ txParams, txPrebuild, wallet, verification })
348
+ .should.be.rejectedWith('missing params');
349
+ });
350
+ it('should reject txPrebuild that is both batch and hop', async function () {
351
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
352
+ const txParams = {
353
+ recipients: [
354
+ { amount: '1000000000000', address: address1 },
355
+ { amount: '2500000000000', address: address2 },
356
+ ],
357
+ wallet: wallet,
358
+ walletPassphrase: 'fakeWalletPassphrase',
359
+ hop: true,
360
+ };
361
+ const txPrebuild = {
362
+ recipients: [{ amount: '3500000000000', address: address1 }],
363
+ nextContractSequenceId: 0,
364
+ gasPrice: 20000000000,
365
+ gasLimit: 500000,
366
+ isBatch: true,
367
+ coin: 'topeth',
368
+ walletId: 'fakeWalletId',
369
+ walletContractAddress: 'fakeWalletContractAddress',
370
+ hopTransaction: {
371
+ tx: hopTx,
372
+ id: hopTxid,
373
+ signature: hopTxBitgoSignature,
374
+ paymentId: '2773928196',
375
+ gasPrice: 20000000000,
376
+ gasLimit: 500000,
377
+ amount: '1000000000000000',
378
+ recipient: hopDestinationAddress,
379
+ nonce: 0,
380
+ userReqSig: userReqSig,
381
+ gasPriceMax: 500000000000,
382
+ },
383
+ };
384
+ const verification = {};
385
+ await basecoin
386
+ .verifyTransaction({ txParams, txPrebuild, wallet, verification })
387
+ .should.be.rejectedWith('tx cannot be both a batch and hop transaction');
388
+ });
389
+ it('should reject a txPrebuild with more than one recipient', async function () {
390
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
391
+ const txParams = {
392
+ recipients: [
393
+ { amount: '1000000000000', address: address1 },
394
+ { amount: '2500000000000', address: address2 },
395
+ ],
396
+ wallet: wallet,
397
+ walletPassphrase: 'fakeWalletPassphrase',
398
+ };
399
+ const txPrebuild = {
400
+ recipients: [
401
+ { amount: '1000000000000', address: address1 },
402
+ { amount: '2500000000000', address: address2 },
403
+ ],
404
+ nextContractSequenceId: 0,
405
+ gasPrice: 20000000000,
406
+ gasLimit: 500000,
407
+ isBatch: true,
408
+ coin: 'topeth',
409
+ walletId: 'fakeWalletId',
410
+ walletContractAddress: 'fakeWalletContractAddress',
411
+ };
412
+ const verification = {};
413
+ await basecoin
414
+ .verifyTransaction({ txParams, txPrebuild, wallet, verification })
415
+ .should.be.rejectedWith(`topeth doesn't support sending to more than 1 destination address within a single transaction. Try again, using only a single recipient.`);
416
+ });
417
+ it('should reject a hop txPrebuild that does not send to its hop address', async function () {
418
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
419
+ const txParams = {
420
+ recipients: [{ amount: '1000000000000000', address: hopDestinationAddress }],
421
+ wallet: wallet,
422
+ walletPassphrase: 'fakeWalletPassphrase',
423
+ hop: true,
424
+ };
425
+ const txPrebuild = {
426
+ recipients: [{ amount: '5000000000000000', address: address1 }],
427
+ nextContractSequenceId: 0,
428
+ gasPrice: 20000000000,
429
+ gasLimit: 500000,
430
+ isBatch: false,
431
+ coin: 'topeth',
432
+ walletId: 'fakeWalletId',
433
+ walletContractAddress: 'fakeWalletContractAddress',
434
+ hopTransaction: {
435
+ tx: hopTx,
436
+ id: hopTxid,
437
+ signature: hopTxBitgoSignature,
438
+ paymentId: '0',
439
+ gasPrice: 20000000000,
440
+ gasLimit: 500000,
441
+ amount: '1000000000000000',
442
+ recipient: hopDestinationAddress,
443
+ nonce: 0,
444
+ userReqSig: userReqSig,
445
+ gasPriceMax: 500000000000,
446
+ },
447
+ };
448
+ const verification = {};
449
+ await basecoin
450
+ .verifyTransaction({ txParams, txPrebuild, wallet, verification })
451
+ .should.be.rejectedWith('recipient address of txPrebuild does not match hop address');
452
+ });
453
+ it('should reject a normal txPrebuild from the bitgo server with the wrong amount', async function () {
454
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
455
+ const txParams = {
456
+ recipients: [{ amount: '1000000000000', address: address1 }],
457
+ wallet: wallet,
458
+ walletPassphrase: 'fakeWalletPassphrase',
459
+ };
460
+ const txPrebuild = {
461
+ recipients: [{ amount: '2000000000000', address: address1 }],
462
+ nextContractSequenceId: 0,
463
+ gasPrice: 20000000000,
464
+ gasLimit: 500000,
465
+ isBatch: false,
466
+ coin: 'topeth',
467
+ walletId: 'fakeWalletId',
468
+ walletContractAddress: 'fakeWalletContractAddress',
469
+ };
470
+ const verification = {};
471
+ await basecoin
472
+ .verifyTransaction({ txParams, txPrebuild, wallet, verification })
473
+ .should.be.rejectedWith('normal transaction amount in txPrebuild received from BitGo servers does not match txParams supplied by client');
474
+ });
475
+ it('should reject a normal txPrebuild from the bitgo server with the wrong recipient', async function () {
476
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
477
+ const txParams = {
478
+ recipients: [{ amount: '1000000000000', address: address1 }],
479
+ wallet: wallet,
480
+ walletPassphrase: 'fakeWalletPassphrase',
481
+ };
482
+ const txPrebuild = {
483
+ recipients: [{ amount: '1000000000000', address: address2 }],
484
+ nextContractSequenceId: 0,
485
+ gasPrice: 20000000000,
486
+ gasLimit: 500000,
487
+ isBatch: false,
488
+ coin: 'topeth',
489
+ walletId: 'fakeWalletId',
490
+ walletContractAddress: 'fakeWalletContractAddress',
491
+ };
492
+ const verification = {};
493
+ await basecoin
494
+ .verifyTransaction({ txParams, txPrebuild, wallet, verification })
495
+ .should.be.rejectedWith('destination address in normal txPrebuild does not match that in txParams supplied by client');
496
+ });
497
+ it('should reject a txPrebuild from the bitgo server with the wrong coin', async function () {
498
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
499
+ const txParams = {
500
+ recipients: [{ amount: '1000000000000', address: address1 }],
501
+ wallet: wallet,
502
+ walletPassphrase: 'fakeWalletPassphrase',
503
+ };
504
+ const txPrebuild = {
505
+ recipients: [{ amount: '1000000000000', address: address1 }],
506
+ nextContractSequenceId: 0,
507
+ gasPrice: 20000000000,
508
+ gasLimit: 500000,
509
+ isBatch: false,
510
+ coin: 'btc',
511
+ walletId: 'fakeWalletId',
512
+ walletContractAddress: 'fakeWalletContractAddress',
513
+ };
514
+ const verification = {};
515
+ await basecoin
516
+ .verifyTransaction({ txParams, txPrebuild, wallet, verification })
517
+ .should.be.rejectedWith('coin in txPrebuild did not match that in txParams supplied by client');
518
+ });
519
+ it('should verify a txPrebuild with more than one recipient in case of token batch transfer', async function () {
520
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
521
+ const txParams = {
522
+ tokenName: 'topeth:terc18dp',
523
+ recipients: [
524
+ { amount: '1', address: address1 },
525
+ { amount: '2', address: address2 },
526
+ { amount: '3', address: address2 },
527
+ ],
528
+ wallet: wallet,
529
+ walletPassphrase: 'fakeWalletPassphrase',
530
+ };
531
+ const txPrebuild = {
532
+ recipients: [
533
+ { amount: '0', address: (basecoin?.staticsCoin?.network).batcherContractAddress },
534
+ ],
535
+ nextContractSequenceId: 0,
536
+ gasPrice: 20000000000,
537
+ gasLimit: 500000,
538
+ isBatch: true,
539
+ coin: 'topeth',
540
+ walletId: 'fakeWalletId',
541
+ walletContractAddress: 'fakeWalletContractAddress',
542
+ };
543
+ const verification = {};
544
+ const isTransactionVerified = await basecoin.verifyTransaction({ txParams, txPrebuild, wallet, verification });
545
+ isTransactionVerified.should.equal(true);
546
+ });
547
+ it('should reject a txPrebuild with more than one recipient in case of token batch transfer with wrong amount', async function () {
548
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
549
+ const txParams = {
550
+ tokenName: 'topeth:terc18dp',
551
+ recipients: [
552
+ { amount: '1', address: address1 },
553
+ { amount: '2', address: address2 },
554
+ { amount: '3', address: address2 },
555
+ ],
556
+ wallet: wallet,
557
+ walletPassphrase: 'fakeWalletPassphrase',
558
+ };
559
+ const txPrebuild = {
560
+ recipients: [
561
+ { amount: '6', address: (basecoin?.staticsCoin?.network).batcherContractAddress },
562
+ ],
563
+ nextContractSequenceId: 0,
564
+ gasPrice: 20000000000,
565
+ gasLimit: 500000,
566
+ isBatch: true,
567
+ coin: 'topeth',
568
+ walletId: 'fakeWalletId',
569
+ walletContractAddress: 'fakeWalletContractAddress',
570
+ };
571
+ const verification = {};
572
+ await basecoin
573
+ .verifyTransaction({ txParams, txPrebuild, wallet, verification })
574
+ .should.be.rejectedWith(`batch token transaction amount in txPrebuild should be zero for token transfers`);
575
+ });
576
+ it('should reject a txPrebuild with more than one recipient in case of token batch transfer with wrong batcher contract address', async function () {
577
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
578
+ const txParams = {
579
+ tokenName: 'topeth:terc18dp',
580
+ recipients: [
581
+ { amount: '1', address: address1 },
582
+ { amount: '2', address: address2 },
583
+ { amount: '3', address: address2 },
584
+ ],
585
+ wallet: wallet,
586
+ walletPassphrase: 'fakeWalletPassphrase',
587
+ };
588
+ const txPrebuild = {
589
+ recipients: [{ amount: '0', address: 'fakeContractAddress' }],
590
+ nextContractSequenceId: 0,
591
+ gasPrice: 20000000000,
592
+ gasLimit: 500000,
593
+ isBatch: true,
594
+ coin: 'topeth',
595
+ walletId: 'fakeWalletId',
596
+ walletContractAddress: 'fakeWalletContractAddress',
597
+ };
598
+ const verification = {};
599
+ await basecoin
600
+ .verifyTransaction({ txParams, txPrebuild, wallet, verification })
601
+ .should.be.rejectedWith(`recipient address of txPrebuild does not match batcher address`);
602
+ });
603
+ });
604
+ describe('Recover transaction:', function () {
605
+ const baseUrl = sdk_core_1.common.Environments.test.optimisticEtherscanBaseUrl;
606
+ const userXpub = 'xpub661MyMwAqRbcEeTc8789MK5PUGEYiPG4F4V17n2Rd2LoTATA1XoCnJT5FAYAShQxSxtFjpo5NHmcWwTp2LiWGBMwpUcAA3HywhxivgYfq7q';
607
+ const userXprv = 'xprv9s21ZrQH143K2AP925b8zB8evEQ4JvYCsqZQKPcp4gopaN81TzUxEW8bPtVyDgjmddGhRRETn8xi1cVAB9bf1Bx9kGRRFgTZXxJayZLnag1';
608
+ const backupXpub = 'xpub661MyMwAqRbcFZX15xpZf4ERCGHiVSJm8r5C4yh1yXV2GrdZCUPYo4WQr6tN9oUywKXsgSHo7Risf9r22GH5joVD2hEEEhqnSCvK8qy11wW';
609
+ const backupXprv = 'xprv9s21ZrQH143K35SXywHZHvHgeETE5yaumd9bGbHQRBx3Q4JQew5JFGBvzqiZjCUkBdBUZnfuMDTGURRayN1hFSWxEJQsCEAMm1D3pk1h7Jj';
610
+ it('should generate an unsigned sweep', async function () {
611
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
612
+ const backupKeyAddress = '0x4f2c4830cc37f2785c646f89ded8a919219fa0e9';
613
+ (0, nock_1.default)(baseUrl)
614
+ .get('/api')
615
+ .twice()
616
+ .query(mockData.getTxListRequest(backupKeyAddress))
617
+ .reply(200, mockData.getTxListResponse);
618
+ (0, nock_1.default)(baseUrl)
619
+ .get('/api')
620
+ .query(mockData.getBalanceRequest(walletContractAddress))
621
+ .reply(200, mockData.getBalanceResponse);
622
+ (0, nock_1.default)(baseUrl)
623
+ .get('/api')
624
+ .query(mockData.getBalanceRequest(backupKeyAddress))
625
+ .reply(200, mockData.getBalanceResponse);
626
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
627
+ const basecoin = bitgo.coin('topeth');
628
+ const transaction = (await basecoin.recover({
629
+ userKey: userXpub,
630
+ backupKey: backupXpub,
631
+ walletContractAddress: walletContractAddress,
632
+ recoveryDestination: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
633
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
634
+ gasLimit: 500000,
635
+ }));
636
+ should.exist(transaction);
637
+ transaction.should.have.property('txHex');
638
+ transaction.should.have.property('contractSequenceId');
639
+ transaction.should.have.property('expireTime');
640
+ transaction.should.have.property('gasLimit');
641
+ transaction.gasLimit.should.equal('500000');
642
+ transaction.should.have.property('walletContractAddress');
643
+ transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
644
+ transaction.should.have.property('recipients');
645
+ const recipient = transaction.recipients[0];
646
+ recipient.should.have.property('address');
647
+ recipient.address.should.equal(sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT);
648
+ recipient.should.have.property('amount');
649
+ recipient.amount.should.equal('9999999999999999928');
650
+ });
651
+ it('should throw an error in case fee address is having less funds than required', async function () {
652
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
653
+ const backupKeyAddress = '0x4f2c4830cc37f2785c646f89ded8a919219fa0e9';
654
+ (0, nock_1.default)(baseUrl)
655
+ .get('/api')
656
+ .twice()
657
+ .query(mockData.getTxListRequest(backupKeyAddress))
658
+ .reply(200, mockData.getTxListResponse);
659
+ (0, nock_1.default)(baseUrl)
660
+ .get('/api')
661
+ .query(mockData.getBalanceRequest(walletContractAddress))
662
+ .reply(200, mockData.getBalanceResponse);
663
+ (0, nock_1.default)(baseUrl)
664
+ .get('/api')
665
+ .query(mockData.getBalanceRequest(backupKeyAddress))
666
+ .reply(200, mockData.getFeeAddressLowBalanceResponse);
667
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
668
+ const basecoin = bitgo.coin('topeth');
669
+ try {
670
+ (await basecoin.recover({
671
+ userKey: userXpub,
672
+ backupKey: backupXpub,
673
+ walletContractAddress: walletContractAddress,
674
+ recoveryDestination: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
675
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
676
+ gasLimit: 500000,
677
+ }));
678
+ }
679
+ catch (e) {
680
+ e.message.should.equal('Backup key address 0x4f2c4830cc37f2785c646f89ded8a919219fa0e9 has balance 100000 Gwei.This address must have a balance of at least 11000000 Gwei to perform recoveries. Try sending some funds to this address then retry.');
681
+ }
682
+ });
683
+ it('should construct a recovery transaction without BitGo', async function () {
684
+ const backupKeyAddress = '0x6d22efdd634996248170c948e5726007fc251bb3';
685
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
686
+ (0, nock_1.default)(baseUrl)
687
+ .get('/api')
688
+ .query(mockData.getTxListRequest(backupKeyAddress))
689
+ .reply(200, mockData.getTxListResponse);
690
+ (0, nock_1.default)(baseUrl)
691
+ .get('/api')
692
+ .query(mockData.getBalanceRequest(walletContractAddress))
693
+ .reply(200, mockData.getBalanceResponse);
694
+ (0, nock_1.default)(baseUrl)
695
+ .get('/api')
696
+ .query(mockData.getBalanceRequest(backupKeyAddress))
697
+ .reply(200, mockData.getBalanceResponse);
698
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
699
+ const basecoin = bitgo.coin('topeth');
700
+ const transaction = (await basecoin.recover({
701
+ userKey: '{"iv":"VFZ3jvXhxo1Z+Yaf2MtZnA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
702
+ ':"ccm","adata":"","cipher":"aes","salt":"p+fkHuLa/8k=","ct":"hYG7pvljLIgCjZ\n' +
703
+ '53PBlCde5KZRmlUKKHLtDMk+HJfuU46hW+x+C9WsIAO4gFPnTCvFVmQ8x7czCtcNFub5AO2otOG\n' +
704
+ 'OsX4GE2gXOEmCl1TpWwwNhm7yMUjGJUpgW6ZZgXSXdDitSKi4V/hk78SGSzjFOBSPYRa6I="}\n',
705
+ backupKey: '{"iv":"AbsCtv1qwPIhOgyrCpNagA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
706
+ ':"ccm","adata":"","cipher":"aes","salt":"5vpUDBUlzm8=","ct":"PapYYCjBXRLUKA\n' +
707
+ 'JbOsB/EJ9B8fUmVQTxMPjUnQyAky12me9K66GiMEAxTD7kd6bYAQJuuTkATXKU7Bnf7vK9JxNOw\n' +
708
+ 'oji7HF9eFH0aD4/hX5SWFfHF2Qfi+TnXv6hVsMAoisDZs3/F67/ZUaDYR0ZsdrQ4Q/cLD0="}\n',
709
+ walletContractAddress: walletContractAddress,
710
+ walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
711
+ recoveryDestination: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
712
+ gasLimit: 500000,
713
+ }));
714
+ should.exist(transaction);
715
+ transaction.should.have.property('tx');
716
+ transaction.should.have.property('id');
717
+ const decodedTx = abstract_eth_1.optionalDeps.EthTx.Transaction.fromSerializedTx(abstract_eth_1.optionalDeps.ethUtil.toBuffer(transaction.tx));
718
+ decodedTx.should.have.property('gasPrice');
719
+ decodedTx.should.have.property('nonce');
720
+ decodedTx.should.have.property('to');
721
+ });
722
+ it('should be able to second sign', async function () {
723
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
724
+ const backupKeyAddress = '0x4f2c4830cc37f2785c646f89ded8a919219fa0e9';
725
+ (0, nock_1.default)(baseUrl)
726
+ .get('/api')
727
+ .twice()
728
+ .query(mockData.getTxListRequest(backupKeyAddress))
729
+ .reply(200, mockData.getTxListResponse);
730
+ (0, nock_1.default)(baseUrl)
731
+ .get('/api')
732
+ .query(mockData.getBalanceRequest(walletContractAddress))
733
+ .reply(200, mockData.getBalanceResponse);
734
+ (0, nock_1.default)(baseUrl)
735
+ .get('/api')
736
+ .query(mockData.getBalanceRequest(backupKeyAddress))
737
+ .reply(200, mockData.getBalanceResponse);
738
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
739
+ const basecoin = bitgo.coin('topeth');
740
+ const transaction = (await basecoin.recover({
741
+ userKey: userXpub,
742
+ backupKey: backupXpub,
743
+ walletContractAddress: walletContractAddress,
744
+ recoveryDestination: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
745
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
746
+ replayProtectionOptions: { chain: 80001, hardfork: 'london' },
747
+ gasLimit: 500000,
748
+ }));
749
+ const txPrebuild = {
750
+ txHex: transaction.txHex,
751
+ };
752
+ const params = {
753
+ txPrebuild,
754
+ prv: userXprv,
755
+ };
756
+ // sign transaction once
757
+ const halfSigned = await basecoin.signTransaction(params);
758
+ const halfSignedParams = {
759
+ txPrebuild: halfSigned,
760
+ isLastSignature: true,
761
+ walletContractAddress: walletContractAddress,
762
+ prv: backupXprv,
763
+ };
764
+ const finalSigned = (await basecoin.signTransaction(halfSignedParams));
765
+ finalSigned.should.have.property('txHex');
766
+ const txBuilder = (0, getBuilder_1.getBuilder)('topeth');
767
+ txBuilder.from(finalSigned.txHex);
768
+ const rebuiltTx = await txBuilder.build();
769
+ rebuiltTx.signature.length.should.equal(2);
770
+ rebuiltTx.outputs.length.should.equal(1);
771
+ });
772
+ });
773
+ describe('Evm Based Cross Chain Recovery transaction:', function () {
774
+ const baseUrl = sdk_core_1.common.Environments.test.optimisticEtherscanBaseUrl;
775
+ const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
776
+ const destinationAddress = '0xd5adde17fed8baed3f32b84af05b8f2816f7b560';
777
+ const bitgoDestinationAddress = '0xe5986ce4490deb67d2950562ceb930ddf9be7a14';
778
+ it('should generate an half signed recovery txn for hot wallet', async function () {
779
+ const userKey = '{"iv":"VFZ3jvXhxo1Z+Yaf2MtZnA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
780
+ ':"ccm","adata":"","cipher":"aes","salt":"p+fkHuLa/8k=","ct":"hYG7pvljLIgCjZ\n' +
781
+ '53PBlCde5KZRmlUKKHLtDMk+HJfuU46hW+x+C9WsIAO4gFPnTCvFVmQ8x7czCtcNFub5AO2otOG\n' +
782
+ 'OsX4GE2gXOEmCl1TpWwwNhm7yMUjGJUpgW6ZZgXSXdDitSKi4V/hk78SGSzjFOBSPYRa6I="}\n';
783
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
784
+ const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
785
+ const destinationAddress = '0xd5adde17fed8baed3f32b84af05b8f2816f7b560';
786
+ const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
787
+ const walletPassphrase = sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE;
788
+ const basecoin = bitgo.coin('topeth');
789
+ (0, nock_1.default)(baseUrl)
790
+ .get('/api')
791
+ .query(mockData.getTxListRequest(bitgoFeeAddress))
792
+ .reply(200, mockData.getTxListResponse);
793
+ (0, nock_1.default)(baseUrl)
794
+ .get('/api')
795
+ .query(mockData.getBalanceRequest(bitgoFeeAddress))
796
+ .reply(200, mockData.getBalanceResponse);
797
+ (0, nock_1.default)(baseUrl)
798
+ .get('/api')
799
+ .query(mockData.getBalanceRequest(walletContractAddress))
800
+ .reply(200, mockData.getBalanceResponse);
801
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
802
+ const transaction = (await basecoin.recover({
803
+ userKey: userKey,
804
+ backupKey: '',
805
+ walletPassphrase: walletPassphrase,
806
+ walletContractAddress: walletContractAddress,
807
+ bitgoFeeAddress: bitgoFeeAddress,
808
+ recoveryDestination: destinationAddress,
809
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
810
+ gasLimit: 500000,
811
+ bitgoDestinationAddress: bitgoDestinationAddress,
812
+ }));
813
+ should.exist(transaction);
814
+ transaction.should.have.property('txHex');
815
+ transaction.should.have.property('coin');
816
+ transaction.should.have.property('contractSequenceId');
817
+ transaction.should.have.property('expireTime');
818
+ transaction.should.have.property('gasLimit');
819
+ transaction.gasLimit.should.equal('500000');
820
+ transaction.should.have.property('isEvmBasedCrossChainRecovery');
821
+ transaction.isEvmBasedCrossChainRecovery?.should.equal(true);
822
+ transaction.should.have.property('walletContractAddress');
823
+ transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
824
+ transaction.should.have.property('recipients');
825
+ const recipient = transaction.recipients[0];
826
+ recipient.should.have.property('address');
827
+ recipient.address.should.equal(destinationAddress);
828
+ recipient.should.have.property('amount');
829
+ recipient.amount.should.equal('9999999999999999928');
830
+ transaction.should.have.property('feesUsed');
831
+ transaction.feesUsed?.gasLimit.should.equal('500000');
832
+ transaction.should.have.property('halfSigned');
833
+ transaction.halfSigned?.should.have.property('txHex');
834
+ transaction.halfSigned?.should.have.property('recipients');
835
+ });
836
+ it('should generate an half signed recovery txn of an unsupported token for hot wallet', async function () {
837
+ const userKey = '{"iv":"VFZ3jvXhxo1Z+Yaf2MtZnA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
838
+ ':"ccm","adata":"","cipher":"aes","salt":"p+fkHuLa/8k=","ct":"hYG7pvljLIgCjZ\n' +
839
+ '53PBlCde5KZRmlUKKHLtDMk+HJfuU46hW+x+C9WsIAO4gFPnTCvFVmQ8x7czCtcNFub5AO2otOG\n' +
840
+ 'OsX4GE2gXOEmCl1TpWwwNhm7yMUjGJUpgW6ZZgXSXdDitSKi4V/hk78SGSzjFOBSPYRa6I="}\n';
841
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
842
+ const walletPassphrase = sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE;
843
+ const tokenContractAddress = '0xe4ab69c077896252fafbd49efd26b5d171a32410'; // topeth-link contract token address
844
+ const basecoin = bitgo.coin('topeth');
845
+ (0, nock_1.default)(baseUrl)
846
+ .get('/api')
847
+ .query(mockData.getTxListRequest(bitgoFeeAddress))
848
+ .reply(200, mockData.getTxListResponse);
849
+ (0, nock_1.default)(baseUrl)
850
+ .get('/api')
851
+ .query(mockData.getBalanceRequest(bitgoFeeAddress))
852
+ .reply(200, mockData.getBalanceResponse);
853
+ (0, nock_1.default)(baseUrl)
854
+ .get('/api')
855
+ .query(mockData.getTokenBalanceRequest(tokenContractAddress, walletContractAddress))
856
+ .reply(200, mockData.getBalanceResponse);
857
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
858
+ const transaction = (await basecoin.recover({
859
+ userKey: userKey,
860
+ backupKey: '',
861
+ walletPassphrase: walletPassphrase,
862
+ walletContractAddress: walletContractAddress,
863
+ bitgoFeeAddress: bitgoFeeAddress,
864
+ recoveryDestination: destinationAddress,
865
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
866
+ gasLimit: 500000,
867
+ bitgoDestinationAddress: bitgoDestinationAddress,
868
+ tokenContractAddress: tokenContractAddress,
869
+ }));
870
+ should.exist(transaction);
871
+ transaction.should.have.property('txHex');
872
+ const txBuilder = (0, getBuilder_1.getBuilder)('topeth');
873
+ txBuilder.from(transaction.txHex);
874
+ const rebuiltTx = await txBuilder.build();
875
+ const rebuiltTxJson = rebuiltTx.toJson();
876
+ rebuiltTxJson.should.have.property('data');
877
+ rebuiltTxJson.data.should.startWith('0x0dcd7a6c'); // sendMultiSigToken func
878
+ transaction.should.have.property('coin');
879
+ transaction.coin.should.equal('topeth');
880
+ transaction.should.have.property('contractSequenceId');
881
+ transaction.should.have.property('expireTime');
882
+ transaction.should.have.property('gasLimit');
883
+ transaction.gasLimit.should.equal('500000');
884
+ transaction.should.have.property('isEvmBasedCrossChainRecovery');
885
+ transaction.isEvmBasedCrossChainRecovery?.should.equal(true);
886
+ transaction.should.have.property('walletContractAddress');
887
+ transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
888
+ transaction.should.have.property('recipients');
889
+ const recipient = transaction.recipients[0];
890
+ recipient.should.have.property('address');
891
+ recipient.address.should.equal(destinationAddress);
892
+ recipient.should.have.property('amount');
893
+ recipient.amount.should.equal('9999999999999999928');
894
+ transaction.should.have.property('feesUsed');
895
+ transaction.feesUsed?.gasLimit.should.equal('500000');
896
+ transaction.should.have.property('halfSigned');
897
+ transaction.halfSigned?.should.have.property('txHex');
898
+ transaction.halfSigned?.should.have.property('recipients');
899
+ });
900
+ });
901
+ });
902
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BldGguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQvb3BldGgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQ0FBaUM7QUFDakMsZ0RBQXlDO0FBQ3pDLHFEQUF1QztBQUN2QyxnREFBd0I7QUFDeEIsOENBQTBGO0FBQzFGLDhDQUEwRDtBQUMxRCw0Q0FBMEM7QUFDMUMsc0RBQStGO0FBRS9GLDJDQUFxRjtBQUNyRiw0REFBOEM7QUFDOUMsOENBQTJDO0FBRzNDLGNBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0FBRXhCLFFBQVEsQ0FBQyxVQUFVLEVBQUU7SUFDbkIsSUFBSSxLQUFtQixDQUFDO0lBQ3hCLElBQUksUUFBUSxDQUFDO0lBQ2IsSUFBSSxtQkFBbUIsQ0FBQztJQUV4QixNQUFNLFFBQVEsR0FBRyw0Q0FBNEMsQ0FBQztJQUM5RCxNQUFNLFFBQVEsR0FBRyw0Q0FBNEMsQ0FBQztJQUM5RCxNQUFNLGtCQUFrQixHQUFHLDRDQUE0QyxDQUFDO0lBQ3hFLE1BQU0scUJBQXFCLEdBQUcsNENBQTRDLENBQUM7SUFDM0UsTUFBTSxLQUFLLEdBQ1QsOE5BQThOLENBQUM7SUFDak8sTUFBTSxPQUFPLEdBQUcsb0VBQW9FLENBQUM7SUFDckYsTUFBTSxVQUFVLEdBQ2Qsb0lBQW9JLENBQUM7SUFFdkksTUFBTSxDQUFDO1FBQ0wsTUFBTSxZQUFZLEdBQ2hCLGlIQUFpSCxDQUFDO1FBQ3BILE1BQU0sUUFBUSxHQUFHLGlCQUFLLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDekIsTUFBTSxJQUFJLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUNuQyxDQUFDO1FBQ0QsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEs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TUFBTSxDQUFDLEtBQUssQ0FBQyxvQkFBUyxDQUFDLEVBQUUsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1lBQzNGLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUMvQyxNQUFNLFNBQVMsR0FBRyxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUMxQyxTQUFTLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQztZQUNuRCxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDekMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHFCQUFxQixDQUFDLENBQUM7WUFDckQsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzdDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDdEQsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQy9DLFdBQVcsQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDdEQsV0FBVyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM3RCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCB7IGJpcDMyIH0gZnJvbSAnQGJpdGdvL3NlY3AyNTZrMSc7XG5pbXBvcnQgKiBhcyBzZWNwMjU2azEgZnJvbSAnc2VjcDI1NmsxJztcbmltcG9ydCBub2NrIGZyb20gJ25vY2snO1xuaW1wb3J0IHsgY29tbW9uLCBGdWxseVNpZ25lZFRyYW5zYWN0aW9uLCBUcmFuc2FjdGlvblR5cGUsIFdhbGxldCB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgeyBUZXN0Qml0R28sIFRlc3RCaXRHb0FQSSB9IGZyb20gJ0BiaXRnby9zZGstdGVzdCc7XG5pbXBvcnQgeyBCaXRHb0FQSSB9IGZyb20gJ0BiaXRnby9zZGstYXBpJztcbmltcG9ydCB7IE9mZmxpbmVWYXVsdFR4SW5mbywgb3B0aW9uYWxEZXBzLCBTaWduVHJhbnNhY3Rpb25PcHRpb25zIH0gZnJvbSAnQGJpdGdvL2Fic3RyYWN0LWV0aCc7XG5cbmltcG9ydCB7IE9wZXRoLCBUb3BldGgsIFRyYW5zYWN0aW9uQnVpbGRlciwgVHJhbnNmZXJCdWlsZGVyIH0gZnJvbSAnLi4vLi4vc3JjL2luZGV4JztcbmltcG9ydCAqIGFzIG1vY2tEYXRhIGZyb20gJy4uL2ZpeHR1cmVzL29wZXRoJztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuLi9nZXRCdWlsZGVyJztcbmltcG9ydCB7IEV0aGVyZXVtTmV0d29yayB9IGZyb20gJ0BiaXRnby9zdGF0aWNzJztcblxubm9jay5lbmFibGVOZXRDb25uZWN0KCk7XG5cbmRlc2NyaWJlKCdPcHRpbWlzbScsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IGJpdGdvOiBUZXN0Qml0R29BUEk7XG4gIGxldCBiYXNlY29pbjtcbiAgbGV0IGhvcFR4Qml0Z29TaWduYXR1cmU7XG5cbiAgY29uc3QgYWRkcmVzczEgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgY29uc3QgYWRkcmVzczIgPSAnMHg3ZTg1YmRjMjdjMDUwZTM5MDVlYmY0YjhlNjM0ZDlhZDZlZGQwZGU2JztcbiAgY29uc3QgaG9wQ29udHJhY3RBZGRyZXNzID0gJzB4NDdjZTdjYzg2ZWZlZmVmMTlmOGZiNTE2YjExNzM1ZDE4M2RhODYzNSc7XG4gIGNvbnN0IGhvcERlc3RpbmF0aW9uQWRkcmVzcyA9ICcweDljN2U4Y2U2ODI1YkQ0ODI3OEIzQWI1OTIyOEVFMjZmOEJFNzkyNWInO1xuICBjb25zdCBob3BUeCA9XG4gICAgJzB4Zjg2YjgwODUwNGE4MTdjOGZmODI1MmZmOTQ5YzdlOGNlNjgyNWJkNDgyNzhiM2FiNTkyMjhlZTI2ZjhiZTc5MjViODcwMzhkN2VhNGM2ODAwMDgwMWNhMDExYmMyMmM2NjQ1NzAxMzNkZmNhNGYwOGEwYjhkMDIzMzljZjQ2NzA0NmQ2YTQxNTJmMDRmMzY4ZDBlYWY5OWVhMDFkNmRjNWNmMGM4OTdjOGQ0YzNlMWRmNTNkMGQwNDI3ODRjNDI0NTM2YTRjYzViODAyNTUyYjdkNjRmZWU4YjUnO1xuICBjb25zdCBob3BUeGlkID0gJzB4NGFmNjUxNDNiYzc3ZGEyYjUwZjM1YjNkMTNjYWNiNGRiMThmMDI2YmY4NGJjMDc0MzU1MGJjNTdiOWI1MzM1MSc7XG4gIGNvbnN0IHVzZXJSZXFTaWcgPVxuICAgICcweDQwNGRiMzA3ZjYxNDdmMGQ4Y2QzMzhjMzRjMTM5MDZlZjQ2YTZmYWE3ZTBlMTE5ZDUxOTRlZjA1YWVjMTZlNmYzZDcxMGY5Yjc5MDE0NjBmOTdlOTI0MDY2YjYyZWZkNzQ0NDNiZDM0NDAyYzZkNDBiNDljMjAzYTU1OWZmMmM4JztcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGJpdGdvS2V5WHBydiA9XG4gICAgICAneHBydjlzMjFaclFIMTQzSzN0cFdCSFdlMzFzTG9YTlJROUF2UllKZ2l0a0t4UTRBVEZRTXd2cjdoSE5xWVJVblM3UHNqekI3YUsxVnhxSEx1TlFqajFzY2tKMkp3bzJxeG1zdmVqd0VDU3BGTWZDJztcbiAgICBjb25zdCBiaXRnb0tleSA9IGJpcDMyLmZyb21CYXNlNTgoYml0Z29LZXlYcHJ2KTtcbiAgICBpZiAoIWJpdGdvS2V5LnByaXZhdGVLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbm8gcHJpdmF0ZUtleScpO1xuICAgIH1cbiAgICBjb25zdCBiaXRnb1hwdWIgPSBiaXRnb0tleS5uZXV0ZXJlZCgpLnRvQmFzZTU4KCk7XG4gICAgaG9wVHhCaXRnb1NpZ25hdHVyZSA9XG4gICAgICAnMHhhYScgK1xuICAgICAgQnVmZmVyLmZyb20oc2VjcDI1NmsxLmVjZHNhU2lnbihCdWZmZXIuZnJvbShob3BUeGlkLnNsaWNlKDIpLCAnaGV4JyksIGJpdGdvS2V5LnByaXZhdGVLZXkpLnNpZ25hdHVyZSkudG9TdHJpbmcoXG4gICAgICAgICdoZXgnXG4gICAgICApO1xuXG4gICAgY29uc3QgZW52ID0gJ3Rlc3QnO1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudiB9KTtcbiAgICBjb21tb24uRW52aXJvbm1lbnRzW2Vudl0uaHNtWHB1YiA9IGJpdGdvWHB1YjtcblxuICAgIGJpdGdvLnNhZmVSZWdpc3Rlcignb3BldGgnLCBPcGV0aC5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0b3BldGgnLCBUb3BldGguY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIGJhc2Vjb2luID0gYml0Z28uY29pbigndG9wZXRoJyk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBCdWlsZCBhbiB1bnNpZ25lZCBhY2NvdW50LWxpYiBtdWx0aS1zaWduYXR1cmUgc2VuZCB0cmFuc2FjdGlub1xuICAgKiBAcGFyYW0gZGVzdGluYXRpb24gVGhlIGRlc3RpbmF0aW9uIGFkZHJlc3Mgb2YgdGhlIHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSBjb250cmFjdEFkZHJlc3MgVGhlIGFkZHJlc3Mgb2YgdGhlIHNtYXJ0IGNvbnRyYWN0IHByb2Nlc3NpbmcgdGhlIHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSBjb250cmFjdFNlcXVlbmNlSWQgVGhlIHNlcXVlbmNlIGlkIG9mIHRoZSBjb250cmFjdFxuICAgKiBAcGFyYW0gbm9uY2UgVGhlIG5vbmNlIG9mIHRoZSBzZW5kaW5nIGFkZHJlc3NcbiAgICogQHBhcmFtIGV4cGlyZVRpbWUgVGhlIGV4cGlyZSB0aW1lIG9mIHRoZSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0gYW1vdW50IFRoZSBhbW91bnQgdG8gc2VuZCB0byB0aGUgcmVjaXBpZW50XG4gICAqIEBwYXJhbSBnYXNQcmljZSBUaGUgZ2FzIHByaWNlIG9mIHRoZSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0gZ2FzTGltaXQgVGhlIGdhcyBsaW1pdCBvZiB0aGUgdHJhbnNhY3Rpb25cbiAgICovXG4gIGNvbnN0IGJ1aWxkVW5zaWduZWRUcmFuc2FjdGlvbiA9IGFzeW5jIGZ1bmN0aW9uICh7XG4gICAgZGVzdGluYXRpb24sXG4gICAgY29udHJhY3RBZGRyZXNzLFxuICAgIGNvbnRyYWN0U2VxdWVuY2VJZCA9IDEsXG4gICAgbm9uY2UgPSAwLFxuICAgIGV4cGlyZVRpbWUgPSBNYXRoLmZsb29yKG5ldyBEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCksXG4gICAgYW1vdW50ID0gJzEwMDAwMCcsXG4gICAgZ2FzUHJpY2UgPSAnMTAwMDAnLFxuICAgIGdhc0xpbWl0ID0gJzIwMDAwJyxcbiAgfSkge1xuICAgIGNvbnN0IHR4QnVpbGRlcjogVHJhbnNhY3Rpb25CdWlsZGVyID0gZ2V0QnVpbGRlcigndG9wZXRoJykgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICB0eEJ1aWxkZXIuZmVlKHtcbiAgICAgIGZlZTogZ2FzUHJpY2UsXG4gICAgICBnYXNMaW1pdDogZ2FzTGltaXQsXG4gICAgfSk7XG4gICAgdHhCdWlsZGVyLmNvdW50ZXIobm9uY2UpO1xuICAgIHR4QnVpbGRlci5jb250cmFjdChjb250cmFjdEFkZHJlc3MpO1xuICAgIGNvbnN0IHRyYW5zZmVyQnVpbGRlciA9IHR4QnVpbGRlci50cmFuc2ZlcigpIGFzIFRyYW5zZmVyQnVpbGRlcjtcblxuICAgIHRyYW5zZmVyQnVpbGRlclxuICAgICAgLmNvaW4oJ3RvcGV0aCcpXG4gICAgICAuZXhwaXJhdGlvblRpbWUoZXhwaXJlVGltZSlcbiAgICAgIC5hbW91bnQoYW1vdW50KVxuICAgICAgLnRvKGRlc3RpbmF0aW9uKVxuICAgICAgLmNvbnRyYWN0U2VxdWVuY2VJZChjb250cmFjdFNlcXVlbmNlSWQpO1xuXG4gICAgcmV0dXJuIGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICB9O1xuXG4gIGRlc2NyaWJlKCdCYXNpYyBDb2luIEluZm8nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIHJpZ2h0IGluZm8gZm9yIG9wZXRoJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgb3BldGggPSBiaXRnby5jb2luKCdvcGV0aCcpO1xuXG4gICAgICBvcGV0aC5zaG91bGQuYmUuYW4uaW5zdGFuY2VvZihPcGV0aCk7XG4gICAgICBvcGV0aC5nZXRDaGFpbigpLnNob3VsZC5lcXVhbCgnb3BldGgnKTtcbiAgICAgIG9wZXRoLmdldEZhbWlseSgpLnNob3VsZC5lcXVhbCgnb3BldGgnKTtcbiAgICAgIG9wZXRoLmdldEZ1bGxOYW1lKCkuc2hvdWxkLmVxdWFsKCdPcHRpbWlzbSBFdGhlcmV1bSAoTDIgQ2hhaW4pJyk7XG4gICAgICBvcGV0aC5nZXRCYXNlRmFjdG9yKCkuc2hvdWxkLmVxdWFsKDFlMTgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIHJpZ2h0IGluZm8gZm9yIHRvcGV0aCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRvcGV0aCA9IGJpdGdvLmNvaW4oJ3RvcGV0aCcpO1xuXG4gICAgICB0b3BldGguc2hvdWxkLmJlLmFuLmluc3RhbmNlb2YoVG9wZXRoKTtcbiAgICAgIHRvcGV0aC5nZXRDaGFpbigpLnNob3VsZC5lcXVhbCgndG9wZXRoJyk7XG4gICAgICB0b3BldGguZ2V0RmFtaWx5KCkuc2hvdWxkLmVxdWFsKCdvcGV0aCcpO1xuICAgICAgdG9wZXRoLmdldEZ1bGxOYW1lKCkuc2hvdWxkLmVxdWFsKCdUZXN0bmV0IE9wdGltaXNtIEV0aGVyZXVtIChMMiBDaGFpbiknKTtcbiAgICAgIHRvcGV0aC5nZXRCYXNlRmFjdG9yKCkuc2hvdWxkLmVxdWFsKDFlMTgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRXhwbGFpbiB0cmFuc2FjdGlvbjonLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBmYWlsIGlmIHRoZSBvcHRpb25zIG9iamVjdCBpcyBtaXNzaW5nIHBhcmFtZXRlcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluUGFyYW1zID0ge1xuICAgICAgICBmZWVJbmZvOiB7IGZlZTogMSB9LFxuICAgICAgICB0eEhleDogbnVsbCxcbiAgICAgIH07XG4gICAgICBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oZXhwbGFpblBhcmFtcykuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyBleHBsYWluIHR4IHBhcmFtZXRlcnMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdleHBsYWluIGEgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkZXN0aW5hdGlvbiA9ICcweGZhYThmMTRmNDZhOTllYjQzOWM1MGUwYzNiODM1Y2MyMWRhZDUxYjQnO1xuICAgICAgY29uc3QgY29udHJhY3RBZGRyZXNzID0gJzB4OWUyYzU3MTJhYjRjYWY0MDJhOThjNGJmNThjNzlhMGRmZTcxOGFkMSc7XG5cbiAgICAgIGNvbnN0IHVuc2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBidWlsZFVuc2lnbmVkVHJhbnNhY3Rpb24oe1xuICAgICAgICBkZXN0aW5hdGlvbixcbiAgICAgICAgY29udHJhY3RBZGRyZXNzLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGV4cGxhaW5QYXJhbXMgPSB7XG4gICAgICAgIGhhbGZTaWduZWQ6IHtcbiAgICAgICAgICB0eEhleDogdW5zaWduZWRUcmFuc2FjdGlvbi50b0Jyb2FkY2FzdEZvcm1hdCgpLFxuICAgICAgICB9LFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogMSB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGV4cGxhbmF0aW9uID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKGV4cGxhaW5QYXJhbXMpO1xuICAgICAgc2hvdWxkLmV4aXN0KGV4cGxhbmF0aW9uLmlkKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1NpZ24gVHJhbnNhY3Rpb24nLCAoKSA9PiB7XG4gICAgY29uc3QgYWNjb3VudF8xID0ge1xuICAgICAgYWRkcmVzczogJzB4OENlNTljMmQxNzAyODQ0RjhFZEVENDUxQUExMDM5NjFiQzM3QjRlOCcsXG4gICAgICBvd25lcl8xOiAnNGVlMDg5YWNlYWJmM2RkYmY3NDhkYjc5YjEwNjZjMzNiN2QzZWExYWIzZWI3ZTMyNTEyMWJiYTJiZmYyZjVjYScsXG4gICAgICBvd25lcl8yOiAnNWM3ZTRlZmZmNzMwNGQ0ZGZmZjZkNWYxNTkxODQ0ZWM2ZjJhZGZhNmE0N2U5ZmVjZTZhM2MxYTRkNzU1ZjFlMycsXG4gICAgICBvd25lcl8zOiAnNDQyMWFiMjVkZDkxZTFhMzE4MGQwM2Q1N2MzMjNhNzg4NmRjYzMxM2QzYjNhNGI0MjU2YTU3OTE1NzJiZjU5NycsXG4gICAgfTtcblxuICAgIGNvbnN0IGFjY291bnRfMiA9IHtcbiAgICAgIGFkZHJlc3M6ICcweGVlYWYwRjA1ZjM3ODkxYWI0YTIxMjA4QjEwNUEwNjg3ZDEyYzVhRjcnLFxuICAgICAgb3duZXJfMTogJzRlZTA4OWFjZWFiZjNkZGJmNzQ4ZGI3OWIxMDY2YzMzYjdkM2VhMWFiM2ViN2UzMjUxMjFiYmEyYmZmMmY1Y2EnLFxuICAgICAgb3duZXJfMjogJzVjYTExNmQyNWFlYzVmNzY1NDY1NDMyY2M0MjFmZjI1ZWY5ZmZkYzMzMGIxMGJiM2Q5YWQ2MWUzYmFhZDg4ZDcnLFxuICAgICAgb3duZXJfMzogJzFmYWU5NDZjYzg0YWY4YmQ3NGQ2MTBhODg1MzdlMjRlMTljMzM0OWQ0NzhkODZmYzViYjU5YmE0Yzg4ZmI5Y2MnLFxuICAgIH07XG5cbiAgICBpdCgnc2hvdWxkIHNpZ24gYW4gdW5zaWduZWQgdGVzdCB0eCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBnZXRCdWlsZGVyKCd0b3BldGgnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICBidWlsZGVyLmZlZSh7XG4gICAgICAgIGZlZTogJzI4MDAwMDAwMDAwMCcsXG4gICAgICAgIGdhc0xpbWl0OiAnNzAwMDAwMCcsXG4gICAgICB9KTtcbiAgICAgIGJ1aWxkZXIuY291bnRlcigxKTtcbiAgICAgIGJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgICBidWlsZGVyLmNvbnRyYWN0KGFjY291bnRfMS5hZGRyZXNzKTtcbiAgICAgIGNvbnN0IHRyYW5zZmVyQnVpbGRlciA9IGJ1aWxkZXIudHJhbnNmZXIoKSBhcyBUcmFuc2ZlckJ1aWxkZXI7XG4gICAgICB0cmFuc2ZlckJ1aWxkZXIuY29pbigndG9wZXRoJykuYW1vdW50KCcxJykudG8oYWNjb3VudF8yLmFkZHJlc3MpLmV4cGlyYXRpb25UaW1lKDEwMDAwKS5jb250cmFjdFNlcXVlbmNlSWQoMSk7XG5cbiAgICAgIGNvbnN0IHVuc2lnbmVkVHggPSBhd2FpdCBidWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB1bnNpZ25lZFR4Rm9yQnJvYWRjYXN0aW5nID0gdW5zaWduZWRUeC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICBjb25zdCBoYWxmU2lnbmVkUmF3VHggPSBhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgdHhIZXg6IHVuc2lnbmVkVHhGb3JCcm9hZGNhc3RpbmcsXG4gICAgICAgIH0sXG4gICAgICAgIHBydjogYWNjb3VudF8xLm93bmVyXzIsXG4gICAgICB9KTtcblxuICAgICAgYnVpbGRlci50cmFuc2ZlcigpLmtleShhY2NvdW50XzEub3duZXJfMik7XG4gICAgICBjb25zdCBoYWxmU2lnbmVkVHggPSBhd2FpdCBidWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCBoYWxmU2lnbmVkVHhGb3JCcm9hZGNhc3RpbmcgPSBoYWxmU2lnbmVkVHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgaGFsZlNpZ25lZFJhd1R4LmhhbGZTaWduZWQudHhIZXguc2hvdWxkLmVxdWFscyhoYWxmU2lnbmVkVHhGb3JCcm9hZGNhc3RpbmcpO1xuICAgICAgaGFsZlNpZ25lZFJhd1R4LmhhbGZTaWduZWQucmVjaXBpZW50cy5sZW5ndGguc2hvdWxkLmVxdWFscygxKTtcbiAgICAgIGhhbGZTaWduZWRSYXdUeC5oYWxmU2lnbmVkLnJlY2lwaWVudHNbMF0uYWRkcmVzcy50b0xvd2VyQ2FzZSgpLnNob3VsZC5lcXVhbHMoYWNjb3VudF8yLmFkZHJlc3MudG9Mb3dlckNhc2UoKSk7XG4gICAgICBoYWxmU2lnbmVkUmF3VHguaGFsZlNpZ25lZC5yZWNpcGllbnRzWzBdLmFtb3VudC50b0xvd2VyQ2FzZSgpLnNob3VsZC5lcXVhbHMoJzEnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2lnbiBhbiB1bnNpZ25lZCB0ZXN0IHR4IHdpdGggZWlwMTU1OScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBnZXRCdWlsZGVyKCd0b3BldGgnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICBidWlsZGVyLmZlZSh7XG4gICAgICAgIGZlZTogJzI4MDAwMDAwMDAwMCcsXG4gICAgICAgIGdhc0xpbWl0OiAnNzAwMDAwMCcsXG4gICAgICAgIGVpcDE1NTk6IHtcbiAgICAgICAgICBtYXhGZWVQZXJHYXM6ICc3NTkzMTIzJyxcbiAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogJzE1MCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGJ1aWxkZXIuY291bnRlcigxKTtcbiAgICAgIGJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgICBidWlsZGVyLmNvbnRyYWN0KGFjY291bnRfMS5hZGRyZXNzKTtcbiAgICAgIGNvbnN0IHRyYW5zZmVyQnVpbGRlciA9IGJ1aWxkZXIudHJhbnNmZXIoKSBhcyBUcmFuc2ZlckJ1aWxkZXI7XG4gICAgICB0cmFuc2ZlckJ1aWxkZXIuY29pbigndG9wZXRoJykuYW1vdW50KCcxJykudG8oYWNjb3VudF8yLmFkZHJlc3MpLmV4cGlyYXRpb25UaW1lKDEwMDAwKS5jb250cmFjdFNlcXVlbmNlSWQoMSk7XG5cbiAgICAgIGNvbnN0IHVuc2lnbmVkVHggPSBhd2FpdCBidWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB1bnNpZ25lZFR4Rm9yQnJvYWRjYXN0aW5nID0gdW5zaWduZWRUeC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICBjb25zdCBoYWxmU2lnbmVkUmF3VHggPSBhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgdHhIZXg6IHVuc2lnbmVkVHhGb3JCcm9hZGNhc3RpbmcsXG4gICAgICAgICAgZWlwMTU1OToge1xuICAgICAgICAgICAgbWF4RmVlUGVyR2FzOiAnNzU5MzEyMycsXG4gICAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogJzE1MCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgcHJ2OiBhY2NvdW50XzEub3duZXJfMixcbiAgICAgIH0pO1xuXG4gICAgICBidWlsZGVyLnRyYW5zZmVyKCkua2V5KGFjY291bnRfMS5vd25lcl8yKTtcbiAgICAgIGNvbnN0IGhhbGZTaWduZWRUeCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IGhhbGZTaWduZWRUeEZvckJyb2FkY2FzdGluZyA9IGhhbGZTaWduZWRUeC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICBoYWxmU2lnbmVkUmF3VHguaGFsZlNpZ25lZC50eEhleC5zaG91bGQuZXF1YWxzKGhhbGZTaWduZWRUeEZvckJyb2FkY2FzdGluZyk7XG4gICAgICBoYWxmU2lnbmVkUmF3VHguaGFsZlNpZ25lZC5yZWNpcGllbnRzLmxlbmd0aC5zaG91bGQuZXF1YWxzKDEpO1xuICAgICAgaGFsZlNpZ25lZFJhd1R4LmhhbGZTaWduZWQucmVjaXBpZW50c1swXS5hZGRyZXNzLnRvTG93ZXJDYXNlKCkuc2hvdWxkLmVxdWFscyhhY2NvdW50XzIuYWRkcmVzcy50b0xvd2VyQ2FzZSgpKTtcbiAgICAgIGhhbGZTaWduZWRSYXdUeC5oYWxmU2lnbmVkLnJlY2lwaWVudHNbMF0uYW1vdW50LnRvTG93ZXJDYXNlKCkuc2hvdWxkLmVxdWFscygnMScpO1xuICAgICAgaGFsZlNpZ25lZFJhd1R4LmhhbGZTaWduZWQuZWlwMTU1OS5tYXhGZWVQZXJHYXMuc2hvdWxkLmVxdWFsKCc3NTkzMTIzJyk7XG4gICAgICBoYWxmU2lnbmVkUmF3VHguaGFsZlNpZ25lZC5laXAxNTU5Lm1heFByaW9yaXR5RmVlUGVyR2FzLnNob3VsZC5lcXVhbCgnMTUwJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNpZ24gYW4gdW5zaWduZWQgdGVzdCB0eCB3aXRoIGRhdGEnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZ2V0QnVpbGRlcigndG9wZXRoJykgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgICAgYnVpbGRlci5mZWUoe1xuICAgICAgICBmZWU6ICcyODAwMDAwMDAwMDAnLFxuICAgICAgICBnYXNMaW1pdDogJzcwMDAwMDAnLFxuICAgICAgICBlaXAxNTU5OiB7XG4gICAgICAgICAgbWF4RmVlUGVyR2FzOiAnNzU5MzEyMycsXG4gICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6ICcxNTAnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBidWlsZGVyLmNvdW50ZXIoMSk7XG4gICAgICBidWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLlNlbmQpO1xuICAgICAgYnVpbGRlci5jb250cmFjdChhY2NvdW50XzEuYWRkcmVzcyk7XG4gICAgICBjb25zdCB0cmFuc2ZlckJ1aWxkZXIgPSBidWlsZGVyLnRyYW5zZmVyKCkgYXMgVHJhbnNmZXJCdWlsZGVyO1xuICAgICAgdHJhbnNmZXJCdWlsZGVyLmNvaW4oJ3RvcGV0aCcpLmFtb3VudCgnMScpLnRvKGFjY291bnRfMi5hZGRyZXNzKS5leHBpcmF0aW9uVGltZSgxMDAwMCkuY29udHJhY3RTZXF1ZW5jZUlkKDEpO1xuXG4gICAgICBjb25zdCB1bnNpZ25lZFR4ID0gYXdhaXQgYnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgdW5zaWduZWRUeEZvckJyb2FkY2FzdGluZyA9IHVuc2lnbmVkVHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgY29uc3QgaGFsZlNpZ25lZFJhd1R4ID0gYXdhaXQgYmFzZWNvaW4uc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgIHR4SGV4OiB1bnNpZ25lZFR4Rm9yQnJvYWRjYXN0aW5nLFxuICAgICAgICAgIGVpcDE1NTk6IHtcbiAgICAgICAgICAgIG1heEZlZVBlckdhczogJzc1OTMxMjMnLFxuICAgICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6ICcxNTAnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhZGRyZXNzOiBhY2NvdW50XzIuYWRkcmVzcyxcbiAgICAgICAgICAgICAgYW1vdW50OiAnMScsXG4gICAgICAgICAgICAgIGRhdGE6ICcweGFhYWEnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBwcnY6IGFjY291bnRfMS5vd25lcl8yLFxuICAgICAgfSk7XG5cbiAgICAgIGJ1aWxkZXIudHJhbnNmZXIoKS5rZXkoYWNjb3VudF8xLm93bmVyXzIpO1xuICAgICAgY29uc3QgaGFsZlNpZ25lZFR4ID0gYXdhaXQgYnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgaGFsZlNpZ25lZFR4Rm9yQnJvYWRjYXN0aW5nID0gaGFsZlNpZ25lZFR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgIGhhbGZTaWduZWRSYXdUeC5oYWxmU2lnbmVkLnR4SGV4LnNob3VsZC5lcXVhbHMoaGFsZlNpZ25lZFR4Rm9yQnJvYWRjYXN0aW5nKTtcbiAgICAgIGhhbGZTaWduZWRSYXdUeC5oYWxmU2lnbmVkLnJlY2lwaWVudHMubGVuZ3RoLnNob3VsZC5lcXVhbHMoMSk7XG4gICAgICBoYWxmU2lnbmVkUmF3VHguaGFsZlNpZ25lZC5yZWNpcGllbnRzWzBdLmFkZHJlc3MudG9Mb3dlckNhc2UoKS5zaG91bGQuZXF1YWxzKGFjY291bnRfMi5hZGRyZXNzLnRvTG93ZXJDYXNlKCkpO1xuICAgICAgaGFsZlNpZ25lZFJhd1R4LmhhbGZTaWduZWQucmVjaXBpZW50c1swXS5hbW91bnQudG9Mb3dlckNhc2UoKS5zaG91bGQuZXF1YWxzKCcxJyk7XG4gICAgICBoYWxmU2lnbmVkUmF3VHguaGFsZlNpZ25lZC5yZWNpcGllbnRzWzBdLmRhdGEudG9Mb3dlckNhc2UoKS5zaG91bGQuZXF1YWxzKCcweGFhYWEnKTtcbiAgICAgIGhhbGZTaWduZWRSYXdUeC5oYWxmU2lnbmVkLmVpcDE1NTkubWF4RmVlUGVyR2FzLnNob3VsZC5lcXVhbCgnNzU5MzEyMycpO1xuICAgICAgaGFsZlNpZ25lZFJhd1R4LmhhbGZTaWduZWQuZWlwMTU1OS5tYXhQcmlvcml0eUZlZVBlckdhcy5zaG91bGQuZXF1YWwoJzE1MCcpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVHJhbnNhY3Rpb24gVmVyaWZpY2F0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgbm9ybWFsIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHRoYXQgbWF0Y2hlcyB0aGUgY2xpZW50IHR4UGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0b3BldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgaG9wIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHRoYXQgbWF0Y2hlcyB0aGUgY2xpZW50IHR4UGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogMTAwMDAwMDAwMDAwMDAwMCwgYWRkcmVzczogaG9wRGVzdGluYXRpb25BZGRyZXNzIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgaG9wOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnNTAwMDAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGhvcENvbnRyYWN0QWRkcmVzcyB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RvcGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICAgIGhvcFRyYW5zYWN0aW9uOiB7XG4gICAgICAgICAgdHg6IGhvcFR4LFxuICAgICAgICAgIGlkOiBob3BUeGlkLFxuICAgICAgICAgIHNpZ25hdHVyZTogaG9wVHhCaXRnb1NpZ25hdHVyZSxcbiAgICAgICAgICBwYXltZW50SWQ6ICcyNzczOTI4MTk2JyxcbiAgICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgICByZWNpcGllbnQ6IGhvcERlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgICBub25jZTogMCxcbiAgICAgICAgICB1c2VyUmVxU2lnOiB1c2VyUmVxU2lnLFxuICAgICAgICAgIGdhc1ByaWNlTWF4OiA1MDAwMDAwMDAwMDAsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3Qgd2hlbiBjbGllbnQgdHhQYXJhbXMgYXJlIG1pc3NpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG51bGw7XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RvcGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHBhcmFtcycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgdHhQcmVidWlsZCB0aGF0IGlzIGJvdGggYmF0Y2ggYW5kIGhvcCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzI1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgaG9wOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMzUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IHRydWUsXG4gICAgICAgIGNvaW46ICd0b3BldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgICBob3BUcmFuc2FjdGlvbjoge1xuICAgICAgICAgIHR4OiBob3BUeCxcbiAgICAgICAgICBpZDogaG9wVHhpZCxcbiAgICAgICAgICBzaWduYXR1cmU6IGhvcFR4Qml0Z29TaWduYXR1cmUsXG4gICAgICAgICAgcGF5bWVudElkOiAnMjc3MzkyODE5NicsXG4gICAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgICAgYW1vdW50OiAnMTAwMDAwMDAwMDAwMDAwMCcsXG4gICAgICAgICAgcmVjaXBpZW50OiBob3BEZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgICAgbm9uY2U6IDAsXG4gICAgICAgICAgdXNlclJlcVNpZzogdXNlclJlcVNpZyxcbiAgICAgICAgICBnYXNQcmljZU1heDogNTAwMDAwMDAwMDAwLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgndHggY2Fubm90IGJlIGJvdGggYSBiYXRjaCBhbmQgaG9wIHRyYW5zYWN0aW9uJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIHR4UHJlYnVpbGQgd2l0aCBtb3JlIHRoYW4gb25lIHJlY2lwaWVudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzI1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9LFxuICAgICAgICAgIHsgYW1vdW50OiAnMjUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH0sXG4gICAgICAgIF0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogdHJ1ZSxcbiAgICAgICAgY29pbjogJ3RvcGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgIGB0b3BldGggZG9lc24ndCBzdXBwb3J0IHNlbmRpbmcgdG8gbW9yZSB0aGFuIDEgZGVzdGluYXRpb24gYWRkcmVzcyB3aXRoaW4gYSBzaW5nbGUgdHJhbnNhY3Rpb24uIFRyeSBhZ2FpbiwgdXNpbmcgb25seSBhIHNpbmdsZSByZWNpcGllbnQuYFxuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBob3AgdHhQcmVidWlsZCB0aGF0IGRvZXMgbm90IHNlbmQgdG8gaXRzIGhvcCBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBob3BEZXN0aW5hdGlvbkFkZHJlc3MgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgICBob3A6IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICc1MDAwMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0b3BldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgICBob3BUcmFuc2FjdGlvbjoge1xuICAgICAgICAgIHR4OiBob3BUeCxcbiAgICAgICAgICBpZDogaG9wVHhpZCxcbiAgICAgICAgICBzaWduYXR1cmU6IGhvcFR4Qml0Z29TaWduYXR1cmUsXG4gICAgICAgICAgcGF5bWVudElkOiAnMCcsXG4gICAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgICAgYW1vdW50OiAnMTAwMDAwMDAwMDAwMDAwMCcsXG4gICAgICAgICAgcmVjaXBpZW50OiBob3BEZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgICAgbm9uY2U6IDAsXG4gICAgICAgICAgdXNlclJlcVNpZzogdXNlclJlcVNpZyxcbiAgICAgICAgICBnYXNQcmljZU1heDogNTAwMDAwMDAwMDAwLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgncmVjaXBpZW50IGFkZHJlc3Mgb2YgdHhQcmVidWlsZCBkb2VzIG5vdCBtYXRjaCBob3AgYWRkcmVzcycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBub3JtYWwgdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgd2l0aCB0aGUgd3JvbmcgYW1vdW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcyMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0b3BldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnbm9ybWFsIHRyYW5zYWN0aW9uIGFtb3VudCBpbiB0eFByZWJ1aWxkIHJlY2VpdmVkIGZyb20gQml0R28gc2VydmVycyBkb2VzIG5vdCBtYXRjaCB0eFBhcmFtcyBzdXBwbGllZCBieSBjbGllbnQnXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIG5vcm1hbCB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB3aXRoIHRoZSB3cm9uZyByZWNpcGllbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RvcGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdkZXN0aW5hdGlvbiBhZGRyZXNzIGluIG5vcm1hbCB0eFByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIHRoYXQgaW4gdHhQYXJhbXMgc3VwcGxpZWQgYnkgY2xpZW50J1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB3aXRoIHRoZSB3cm9uZyBjb2luJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICdidGMnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnY29pbiBpbiB0eFByZWJ1aWxkIGRpZCBub3QgbWF0Y2ggdGhhdCBpbiB0eFBhcmFtcyBzdXBwbGllZCBieSBjbGllbnQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgdHhQcmVidWlsZCB3aXRoIG1vcmUgdGhhbiBvbmUgcmVjaXBpZW50IGluIGNhc2Ugb2YgdG9rZW4gYmF0Y2ggdHJhbnNmZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgdG9rZW5OYW1lOiAndG9wZXRoOnRlcmMxOGRwJyxcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMScsIGFkZHJlc3M6IGFkZHJlc3MxIH0sXG4gICAgICAgICAgeyBhbW91bnQ6ICcyJywgYWRkcmVzczogYWRkcmVzczIgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzMnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzAnLCBhZGRyZXNzOiAoYmFzZWNvaW4/LnN0YXRpY3NDb2luPy5uZXR3b3JrIGFzIEV0aGVyZXVtTmV0d29yaykuYmF0Y2hlckNvbnRyYWN0QWRkcmVzcyB9LFxuICAgICAgICBdLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IHRydWUsXG4gICAgICAgIGNvaW46ICd0b3BldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgdHhQcmVidWlsZCB3aXRoIG1vcmUgdGhhbiBvbmUgcmVjaXBpZW50IGluIGNhc2Ugb2YgdG9rZW4gYmF0Y2ggdHJhbnNmZXIgd2l0aCB3cm9uZyBhbW91bnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgdG9rZW5OYW1lOiAndG9wZXRoOnRlcmMxOGRwJyxcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMScsIGFkZHJlc3M6IGFkZHJlc3MxIH0sXG4gICAgICAgICAgeyBhbW91bnQ6ICcyJywgYWRkcmVzczogYWRkcmVzczIgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzMnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzYnLCBhZGRyZXNzOiAoYmFzZWNvaW4/LnN0YXRpY3NDb2luPy5uZXR3b3JrIGFzIEV0aGVyZXVtTmV0d29yaykuYmF0Y2hlckNvbnRyYWN0QWRkcmVzcyB9LFxuICAgICAgICBdLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IHRydWUsXG4gICAgICAgIGNvaW46ICd0b3BldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChgYmF0Y2ggdG9rZW4gdHJhbnNhY3Rpb24gYW1vdW50IGluIHR4UHJlYnVpbGQgc2hvdWxkIGJlIHplcm8gZm9yIHRva2VuIHRyYW5zZmVyc2ApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSB0eFByZWJ1aWxkIHdpdGggbW9yZSB0aGFuIG9uZSByZWNpcGllbnQgaW4gY2FzZSBvZiB0b2tlbiBiYXRjaCB0cmFuc2ZlciB3aXRoIHdyb25nIGJhdGNoZXIgY29udHJhY3QgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICB0b2tlbk5hbWU6ICd0b3BldGg6dGVyYzE4ZHAnLFxuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzInLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICAgIHsgYW1vdW50OiAnMycsIGFkZHJlc3M6IGFkZHJlc3MyIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMCcsIGFkZHJlc3M6ICdmYWtlQ29udHJhY3RBZGRyZXNzJyB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiB0cnVlLFxuICAgICAgICBjb2luOiAndG9wZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoYHJlY2lwaWVudCBhZGRyZXNzIG9mIHR4UHJlYnVpbGQgZG9lcyBub3QgbWF0Y2ggYmF0Y2hlciBhZGRyZXNzYCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZWNvdmVyIHRyYW5zYWN0aW9uOicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBiYXNlVXJsID0gY29tbW9uLkVudmlyb25tZW50cy50ZXN0Lm9wdGltaXN0aWNFdGhlcnNjYW5CYXNlVXJsIGFzIHN0cmluZztcbiAgICBjb25zdCB1c2VyWHB1YiA9XG4gICAgICAneHB1YjY2MU15TXdBcVJiY0VlVGM4Nzg5TUs1UFVHRVlpUEc0RjRWMTduMlJkMkxvVEFUQTFYb0NuSlQ1RkFZQVNoUXhTeHRGanBvNU5IbWNXd1RwMkxpV0dCTXdwVWNBQTNIeXdoeGl2Z1lmcTdxJztcbiAgICBjb25zdCB1c2VyWHBydiA9XG4gICAgICAneHBydjlzMjFaclFIMTQzSzJBUDkyNWI4ekI4ZXZFUTRKdllDc3FaUUtQY3A0Z29wYU44MVR6VXhFVzhiUHRWeURnam1kZEdoUlJFVG44eGkxY1ZBQjliZjFCeDlrR1JSRmdUWlh4SmF5WkxuYWcxJztcbiAgICBjb25zdCBiYWNrdXBYcHViID1cbiAgICAgICd4cHViNjYxTXlNd0FxUmJjRlpYMTV4cFpmNEVSQ0dIaVZTSm04cjVDNHloMXlYVjJHcmRaQ1VQWW80V1FyNnROOW9VeXdLWHNnU0hvN1Jpc2Y5cjIyR0g1am9WRDJoRUVFaHFuU0N2SzhxeTExd1cnO1xuICAgIGNvbnN0IGJhY2t1cFhwcnYgPVxuICAgICAgJ3hwcnY5czIxWnJRSDE0M0szNVNYeXdIWkh2SGdlRVRFNXlhdW1kOWJHYkhRUkJ4M1E0SlFldzVKRkdCdnpxaVpqQ1VrQmRCVVpuZnVNRFRHVVJSYXlOMWhGU1d4RUpRc0NFQU1tMUQzcGsxaDdKaic7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGFuIHVuc2lnbmVkIHN3ZWVwJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0Q29udHJhY3RBZGRyZXNzID0gVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTIGFzIHN0cmluZztcbiAgICAgIGNvbnN0IGJhY2t1cEtleUFkZHJlc3MgPSAnMHg0ZjJjNDgzMGNjMzdmMjc4NWM2NDZmODlkZWQ4YTkxOTIxOWZhMGU5JztcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC50d2ljZSgpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KGJhY2t1cEtleUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3Qod2FsbGV0Q29udHJhY3RBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChiYWNrdXBLZXlBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3RvcGV0aCcpIGFzIE9wZXRoO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IHVzZXJYcHViLFxuICAgICAgICBiYWNrdXBLZXk6IGJhY2t1cFhwdWIsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogd2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBUZXN0Qml0R28uVjIuVEVTVF9FUkMyMF9UT0tFTl9SRUNJUElFTlQgYXMgc3RyaW5nLFxuICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgfSkpIGFzIE9mZmxpbmVWYXVsdFR4SW5mbztcbiAgICAgIHNob3VsZC5leGlzdCh0cmFuc2FjdGlvbik7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhIZXgnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdjb250cmFjdFNlcXVlbmNlSWQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdleHBpcmVUaW1lJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZ2FzTGltaXQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLmdhc0xpbWl0LnNob3VsZC5lcXVhbCgnNTAwMDAwJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0Q29udHJhY3RBZGRyZXNzJyk7XG4gICAgICB0cmFuc2FjdGlvbi53YWxsZXRDb250cmFjdEFkZHJlc3Muc2hvdWxkLmVxdWFsKFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVjaXBpZW50cycpO1xuICAgICAgY29uc3QgcmVjaXBpZW50ID0gdHJhbnNhY3Rpb24ucmVjaXBpZW50c1swXTtcbiAgICAgIHJlY2lwaWVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYWRkcmVzcycpO1xuICAgICAgcmVjaXBpZW50LmFkZHJlc3Muc2hvdWxkLmVxdWFsKFRlc3RCaXRHby5WMi5URVNUX0VSQzIwX1RPS0VOX1JFQ0lQSUVOVCk7XG4gICAgICByZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Ftb3VudCcpO1xuICAgICAgcmVjaXBpZW50LmFtb3VudC5zaG91bGQuZXF1YWwoJzk5OTk5OTk5OTk5OTk5OTk5MjgnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgaW4gY2FzZSBmZWUgYWRkcmVzcyBpcyBoYXZpbmcgbGVzcyBmdW5kcyB0aGFuIHJlcXVpcmVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0Q29udHJhY3RBZGRyZXNzID0gVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTIGFzIHN0cmluZztcbiAgICAgIGNvbnN0IGJhY2t1cEtleUFkZHJlc3MgPSAnMHg0ZjJjNDgzMGNjMzdmMjc4NWM2NDZmODlkZWQ4YTkxOTIxOWZhMGU5JztcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC50d2ljZSgpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KGJhY2t1cEtleUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3Qod2FsbGV0Q29udHJhY3RBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChiYWNrdXBLZXlBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0RmVlQWRkcmVzc0xvd0JhbGFuY2VSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpLmdldCgnL2FwaScpLnF1ZXJ5KG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlcXVlc3QpLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVzcG9uc2UpO1xuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0b3BldGgnKSBhcyBPcGV0aDtcbiAgICAgIHRyeSB7XG4gICAgICAgIChhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OiB1c2VyWHB1YixcbiAgICAgICAgICBiYWNrdXBLZXk6IGJhY2t1cFhwdWIsXG4gICAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiB3YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogVGVzdEJpdEdvLlYyLlRFU1RfRVJDMjBfVE9LRU5fUkVDSVBJRU5UIGFzIHN0cmluZyxcbiAgICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LFxuICAgICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIH0pKSBhcyBPZmZsaW5lVmF1bHRUeEluZm87XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGUubWVzc2FnZS5zaG91bGQuZXF1YWwoXG4gICAgICAgICAgJ0JhY2t1cCBrZXkgYWRkcmVzcyAweDRmMmM0ODMwY2MzN2YyNzg1YzY0NmY4OWRlZDhhOTE5MjE5ZmEwZTkgaGFzIGJhbGFuY2UgMTAwMDAwIEd3ZWkuVGhpcyBhZGRyZXNzIG11c3QgaGF2ZSBhIGJhbGFuY2Ugb2YgYXQgbGVhc3QgMTEwMDAwMDAgR3dlaSB0byBwZXJmb3JtIHJlY292ZXJpZXMuIFRyeSBzZW5kaW5nIHNvbWUgZnVuZHMgdG8gdGhpcyBhZGRyZXNzIHRoZW4gcmV0cnkuJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb25zdHJ1Y3QgYSByZWNvdmVyeSB0cmFuc2FjdGlvbiB3aXRob3V0IEJpdEdvJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmFja3VwS2V5QWRkcmVzcyA9ICcweDZkMjJlZmRkNjM0OTk2MjQ4MTcwYzk0OGU1NzI2MDA3ZmMyNTFiYjMnO1xuICAgICAgY29uc3Qgd2FsbGV0Q29udHJhY3RBZGRyZXNzID0gVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTIGFzIHN0cmluZztcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KGJhY2t1cEtleUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3Qod2FsbGV0Q29udHJhY3RBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChiYWNrdXBLZXlBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3RvcGV0aCcpIGFzIE9wZXRoO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6XG4gICAgICAgICAgJ3tcIml2XCI6XCJWRlozanZYaHhvMVorWWFmMk10Wm5BPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiXFxuJyArXG4gICAgICAgICAgJzpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcInArZmtIdUxhLzhrPVwiLFwiY3RcIjpcImhZRzdwdmxqTElnQ2paXFxuJyArXG4gICAgICAgICAgJzUzUEJsQ2RlNUtaUm1sVUtLSEx0RE1rK0hKZnVVNDZoVyt4K0M5V3NJQU80Z0ZQblRDdkZWbVE4eDdjekN0Y05GdWI1QU8yb3RPR1xcbicgK1xuICAgICAgICAgICdPc1g0R0UyZ1hPRW1DbDFUcFd3d05obTd5TVVqR0pVcGdXNlpaZ1hTWGREaXRTS2k0Vi9oazc4U0dTempGT0JTUFlSYTZJPVwifVxcbicsXG4gICAgICAgIGJhY2t1cEtleTpcbiAgICAgICAgICAne1wiaXZcIjpcIkFic0N0djFxd1BJaE9neXJDcE5hZ0E9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCJcXG4nICtcbiAgICAgICAgICAnOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiNXZwVURCVWx6bTg9XCIsXCJjdFwiOlwiUGFwWVlDakJYUkxVS0FcXG4nICtcbiAgICAgICAgICAnSmJPc0IvRUo5QjhmVW1WUVR4TVBqVW5ReUFreTEybWU5SzY2R2lNRUF4VEQ3a2Q2YllBUUp1dVRrQVRYS1U3Qm5mN3ZLOUp4Tk93XFxuJyArXG4gICAgICAgICAgJ29qaTdIRjllRkgwYUQ0L2hYNVNXRmZIRjJRZmkrVG5YdjZoVnNNQW9pc0RaczMvRjY3L1pVYURZUjBac2RyUTRRL2NMRDA9XCJ9XFxuJyxcblxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlYyLlRFU1RfUkVDT1ZFUllfUEFTU0NPREUsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IFRlc3RCaXRHby5WMi5URVNUX0VSQzIwX1RPS0VOX1JFQ0lQSUVOVCBhcyBzdHJpbmcsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICB9KSkgYXMgT2ZmbGluZVZhdWx0VHhJbmZvO1xuICAgICAgc2hvdWxkLmV4aXN0KHRyYW5zYWN0aW9uKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lkJyk7XG4gICAgICBjb25zdCBkZWNvZGVkVHggPSBvcHRpb25hbERlcHMuRXRoVHguVHJhbnNhY3Rpb24uZnJvbVNlcmlhbGl6ZWRUeChvcHRpb25hbERlcHMuZXRoVXRpbC50b0J1ZmZlcih0cmFuc2FjdGlvbi50eCkpO1xuICAgICAgZGVjb2RlZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdnYXNQcmljZScpO1xuICAgICAgZGVjb2RlZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdub25jZScpO1xuICAgICAgZGVjb2RlZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0bycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBiZSBhYmxlIHRvIHNlY29uZCBzaWduJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0Q29udHJhY3RBZGRyZXNzID0gVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTIGFzIHN0cmluZztcbiAgICAgIGNvbnN0IGJhY2t1cEtleUFkZHJlc3MgPSAnMHg0ZjJjNDgzMGNjMzdmMjc4NWM2NDZmODlkZWQ4YTkxOTIxOWZhMGU5JztcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC50d2ljZSgpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KGJhY2t1cEtleUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3Qod2FsbGV0Q29udHJhY3RBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChiYWNrdXBLZXlBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3RvcGV0aCcpIGFzIE9wZXRoO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IHVzZXJYcHViLFxuICAgICAgICBiYWNrdXBLZXk6IGJhY2t1cFhwdWIsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogd2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBUZXN0Qml0R28uVjIuVEVTVF9FUkMyMF9UT0tFTl9SRUNJUElFTlQgYXMgc3RyaW5nLFxuICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LFxuICAgICAgICByZXBsYXlQcm90ZWN0aW9uT3B0aW9uczogeyBjaGFpbjogODAwMDEsIGhhcmRmb3JrOiAnbG9uZG9uJyB9LFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgfSkpIGFzIE9mZmxpbmVWYXVsdFR4SW5mbztcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6IHRyYW5zYWN0aW9uLnR4SGV4LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICBwcnY6IHVzZXJYcHJ2LFxuICAgICAgfTtcbiAgICAgIC8vIHNpZ24gdHJhbnNhY3Rpb24gb25jZVxuICAgICAgY29uc3QgaGFsZlNpZ25lZCA9IGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbihwYXJhbXMgYXMgU2lnblRyYW5zYWN0aW9uT3B0aW9ucyk7XG4gICAgICBjb25zdCBoYWxmU2lnbmVkUGFyYW1zID0ge1xuICAgICAgICB0eFByZWJ1aWxkOiBoYWxmU2lnbmVkLFxuICAgICAgICBpc0xhc3RTaWduYXR1cmU6IHRydWUsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogd2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICBwcnY6IGJhY2t1cFhwcnYsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBmaW5hbFNpZ25lZCA9IChhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24oXG4gICAgICAgIGhhbGZTaWduZWRQYXJhbXMgYXMgU2lnblRyYW5zYWN0aW9uT3B0aW9uc1xuICAgICAgKSkgYXMgRnVsbHlTaWduZWRUcmFuc2FjdGlvbjtcbiAgICAgIGZpbmFsU2lnbmVkLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcigndG9wZXRoJykgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgICAgdHhCdWlsZGVyLmZyb20oZmluYWxTaWduZWQudHhIZXgpO1xuICAgICAgY29uc3QgcmVidWlsdFR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICByZWJ1aWx0VHguc2lnbmF0dXJlLmxlbmd0aC5zaG91bGQuZXF1YWwoMik7XG4gICAgICByZWJ1aWx0VHgub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRXZtIEJhc2VkIENyb3NzIENoYWluIFJlY292ZXJ5IHRyYW5zYWN0aW9uOicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBiYXNlVXJsID0gY29tbW9uLkVudmlyb25tZW50cy50ZXN0Lm9wdGltaXN0aWNFdGhlcnNjYW5CYXNlVXJsIGFzIHN0cmluZztcbiAgICBjb25zdCBiaXRnb0ZlZUFkZHJlc3MgPSAnMHgzM2E0MmZhZWEzYzZlODcwMjEzNDdlNTE3MDBiNDhhYWY0OWFhMWU3JztcbiAgICBjb25zdCBkZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhkNWFkZGUxN2ZlZDhiYWVkM2YzMmI4NGFmMDViOGYyODE2ZjdiNTYwJztcbiAgICBjb25zdCBiaXRnb0Rlc3RpbmF0aW9uQWRkcmVzcyA9ICcweGU1OTg2Y2U0NDkwZGViNjdkMjk1MDU2MmNlYjkzMGRkZjliZTdhMTQnO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhbiBoYWxmIHNpZ25lZCByZWNvdmVyeSB0eG4gZm9yIGhvdCB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB1c2VyS2V5ID1cbiAgICAgICAgJ3tcIml2XCI6XCJWRlozanZYaHhvMVorWWFmMk10Wm5BPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiXFxuJyArXG4gICAgICAgICc6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJwK2ZrSHVMYS84az1cIixcImN0XCI6XCJoWUc3cHZsakxJZ0NqWlxcbicgK1xuICAgICAgICAnNTNQQmxDZGU1S1pSbWxVS0tITHRETWsrSEpmdVU0NmhXK3grQzlXc0lBTzRnRlBuVEN2RlZtUTh4N2N6Q3RjTkZ1YjVBTzJvdE9HXFxuJyArXG4gICAgICAgICdPc1g0R0UyZ1hPRW1DbDFUcFd3d05obTd5TVVqR0pVcGdXNlpaZ1hTWGREaXRTS2k0Vi9oazc4U0dTempGT0JTUFlSYTZJPVwifVxcbic7XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgYml0Z29GZWVBZGRyZXNzID0gJzB4MzNhNDJmYWVhM2M2ZTg3MDIxMzQ3ZTUxNzAwYjQ4YWFmNDlhYTFlNyc7XG4gICAgICBjb25zdCBkZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhkNWFkZGUxN2ZlZDhiYWVkM2YzMmI4NGFmMDViOGYyODE2ZjdiNTYwJztcbiAgICAgIGNvbnN0IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzID0gJzB4RTU5ODZDRTQ0OTBEZWI2N2QyOTUwNTYyQ2ViOTMwRGRmOWJlN2ExNCc7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gVGVzdEJpdEdvLlYyLlRFU1RfUkVDT1ZFUllfUEFTU0NPREUgYXMgc3RyaW5nO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3RvcGV0aCcpIGFzIE9wZXRoO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldFR4TGlzdFJlcXVlc3QoYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0VHhMaXN0UmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KGJpdGdvRmVlQWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3Qod2FsbGV0Q29udHJhY3RBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG5cbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gKGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB1c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6ICcnLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgYml0Z29GZWVBZGRyZXNzOiBiaXRnb0ZlZUFkZHJlc3MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3M6IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgfSkpIGFzIE9mZmxpbmVWYXVsdFR4SW5mbztcblxuICAgICAgc2hvdWxkLmV4aXN0KHRyYW5zYWN0aW9uKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvaW4nKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdjb250cmFjdFNlcXVlbmNlSWQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdleHBpcmVUaW1lJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZ2FzTGltaXQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLmdhc0xpbWl0LnNob3VsZC5lcXVhbCgnNTAwMDAwJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaXNFdm1CYXNlZENyb3NzQ2hhaW5SZWNvdmVyeScpO1xuICAgICAgdHJhbnNhY3Rpb24uaXNFdm1CYXNlZENyb3NzQ2hhaW5SZWNvdmVyeT8uc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldENvbnRyYWN0QWRkcmVzcycpO1xuICAgICAgdHJhbnNhY3Rpb24ud2FsbGV0Q29udHJhY3RBZGRyZXNzLnNob3VsZC5lcXVhbChUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudHMnKTtcbiAgICAgIGNvbnN0IHJlY2lwaWVudCA9IHRyYW5zYWN0aW9uLnJlY2lwaWVudHNbMF07XG4gICAgICByZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FkZHJlc3MnKTtcbiAgICAgIHJlY2lwaWVudC5hZGRyZXNzLnNob3VsZC5lcXVhbChkZXN0aW5hdGlvbkFkZHJlc3MpO1xuICAgICAgcmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhbW91bnQnKTtcbiAgICAgIHJlY2lwaWVudC5hbW91bnQuc2hvdWxkLmVxdWFsKCc5OTk5OTk5OTk5OTk5OTk5OTI4Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlc1VzZWQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLmZlZXNVc2VkPy5nYXNMaW1pdC5zaG91bGQuZXF1YWwoJzUwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2hhbGZTaWduZWQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLmhhbGZTaWduZWQ/LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgdHJhbnNhY3Rpb24uaGFsZlNpZ25lZD8uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudHMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gaGFsZiBzaWduZWQgcmVjb3ZlcnkgdHhuIG9mIGFuIHVuc3VwcG9ydGVkIHRva2VuIGZvciBob3Qgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdXNlcktleSA9XG4gICAgICAgICd7XCJpdlwiOlwiVkZaM2p2WGh4bzFaK1lhZjJNdFpuQT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIlxcbicgK1xuICAgICAgICAnOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwicCtma0h1TGEvOGs9XCIsXCJjdFwiOlwiaFlHN3B2bGpMSWdDalpcXG4nICtcbiAgICAgICAgJzUzUEJsQ2RlNUtaUm1sVUtLSEx0RE1rK0hKZnVVNDZoVyt4K0M5V3NJQU80Z0ZQblRDdkZWbVE4eDdjekN0Y05GdWI1QU8yb3RPR1xcbicgK1xuICAgICAgICAnT3NYNEdFMmdYT0VtQ2wxVHBXd3dOaG03eU1VakdKVXBnVzZaWmdYU1hkRGl0U0tpNFYvaGs3OFNHU3pqRk9CU1BZUmE2ST1cIn1cXG4nO1xuICAgICAgY29uc3Qgd2FsbGV0Q29udHJhY3RBZGRyZXNzID0gVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTIGFzIHN0cmluZztcbiAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSBUZXN0Qml0R28uVjIuVEVTVF9SRUNPVkVSWV9QQVNTQ09ERSBhcyBzdHJpbmc7XG4gICAgICBjb25zdCB0b2tlbkNvbnRyYWN0QWRkcmVzcyA9ICcweGU0YWI2OWMwNzc4OTYyNTJmYWZiZDQ5ZWZkMjZiNWQxNzFhMzI0MTAnOyAvLyB0b3BldGgtbGluayBjb250cmFjdCB0b2tlbiBhZGRyZXNzXG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndG9wZXRoJykgYXMgT3BldGg7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VHhMaXN0UmVxdWVzdChiaXRnb0ZlZUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QoYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUb2tlbkJhbGFuY2VSZXF1ZXN0KHRva2VuQ29udHJhY3RBZGRyZXNzLCB3YWxsZXRDb250cmFjdEFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IHVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogJycsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogd2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICBiaXRnb0ZlZUFkZHJlc3M6IGJpdGdvRmVlQWRkcmVzcyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBiaXRnb0Rlc3RpbmF0aW9uQWRkcmVzczogYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIHRva2VuQ29udHJhY3RBZGRyZXNzOiB0b2tlbkNvbnRyYWN0QWRkcmVzcyxcbiAgICAgIH0pKSBhcyBPZmZsaW5lVmF1bHRUeEluZm87XG5cbiAgICAgIHNob3VsZC5leGlzdCh0cmFuc2FjdGlvbik7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhIZXgnKTtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ3RvcGV0aCcpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICAgIHR4QnVpbGRlci5mcm9tKHRyYW5zYWN0aW9uLnR4SGV4KTtcbiAgICAgIGNvbnN0IHJlYnVpbHRUeCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgcmVidWlsdFR4SnNvbiA9IHJlYnVpbHRUeC50b0pzb24oKTtcbiAgICAgIHJlYnVpbHRUeEpzb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2RhdGEnKTtcbiAgICAgIHJlYnVpbHRUeEpzb24uZGF0YS5zaG91bGQuc3RhcnRXaXRoKCcweDBkY2Q3YTZjJyk7IC8vIHNlbmRNdWx0aVNpZ1Rva2VuIGZ1bmNcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdjb2luJyk7XG4gICAgICB0cmFuc2FjdGlvbi5jb2luLnNob3VsZC5lcXVhbCgndG9wZXRoJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29udHJhY3RTZXF1ZW5jZUlkJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZXhwaXJlVGltZScpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc0xpbWl0Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5nYXNMaW1pdC5zaG91bGQuZXF1YWwoJzUwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lzRXZtQmFzZWRDcm9zc0NoYWluUmVjb3ZlcnknKTtcbiAgICAgIHRyYW5zYWN0aW9uLmlzRXZtQmFzZWRDcm9zc0NoYWluUmVjb3Zlcnk/LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRDb250cmFjdEFkZHJlc3MnKTtcbiAgICAgIHRyYW5zYWN0aW9uLndhbGxldENvbnRyYWN0QWRkcmVzcy5zaG91bGQuZXF1YWwoVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNpcGllbnRzJyk7XG4gICAgICBjb25zdCByZWNpcGllbnQgPSB0cmFuc2FjdGlvbi5yZWNpcGllbnRzWzBdO1xuICAgICAgcmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhZGRyZXNzJyk7XG4gICAgICByZWNpcGllbnQuYWRkcmVzcy5zaG91bGQuZXF1YWwoZGVzdGluYXRpb25BZGRyZXNzKTtcbiAgICAgIHJlY2lwaWVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYW1vdW50Jyk7XG4gICAgICByZWNpcGllbnQuYW1vdW50LnNob3VsZC5lcXVhbCgnOTk5OTk5OTk5OTk5OTk5OTkyOCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZXNVc2VkJyk7XG4gICAgICB0cmFuc2FjdGlvbi5mZWVzVXNlZD8uZ2FzTGltaXQuc2hvdWxkLmVxdWFsKCc1MDAwMDAnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdoYWxmU2lnbmVkJyk7XG4gICAgICB0cmFuc2FjdGlvbi5oYWxmU2lnbmVkPy5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhIZXgnKTtcbiAgICAgIHRyYW5zYWN0aW9uLmhhbGZTaWduZWQ/LnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNpcGllbnRzJyk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=