@bitgo/sdk-coin-ethlike 2.2.2 → 2.2.4
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.
- package/dist/test/fixtures/ethlikeCoin.d.ts +71 -0
- package/dist/test/fixtures/ethlikeCoin.d.ts.map +1 -0
- package/dist/test/fixtures/ethlikeCoin.js +86 -0
- package/dist/test/getBuilder.d.ts +4 -0
- package/dist/test/getBuilder.d.ts.map +1 -0
- package/dist/test/getBuilder.js +9 -0
- package/dist/test/resources.d.ts +8 -0
- package/dist/test/resources.d.ts.map +1 -0
- package/dist/test/resources.js +29 -0
- package/dist/test/unit/ethlikeCoin.d.ts +2 -0
- package/dist/test/unit/ethlikeCoin.d.ts.map +1 -0
- package/dist/test/unit/ethlikeCoin.js +689 -0
- package/dist/test/unit/walletInitialization.d.ts +2 -0
- package/dist/test/unit/walletInitialization.d.ts.map +1 -0
- package/dist/test/unit/walletInitialization.js +169 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +11 -8
- package/.eslintignore +0 -4
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -388
|
@@ -0,0 +1,689 @@
|
|
|
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 assert_1 = __importDefault(require("assert"));
|
|
40
|
+
const sdk_api_1 = require("@bitgo/sdk-api");
|
|
41
|
+
const sdk_core_1 = require("@bitgo/sdk-core");
|
|
42
|
+
const sdk_test_1 = require("@bitgo/sdk-test");
|
|
43
|
+
const secp256k1_1 = require("@bitgo/secp256k1");
|
|
44
|
+
const nock_1 = __importDefault(require("nock"));
|
|
45
|
+
const src_1 = require("../../src");
|
|
46
|
+
const getBuilder_1 = require("../getBuilder");
|
|
47
|
+
const resources_1 = require("../resources");
|
|
48
|
+
const mockData = __importStar(require("../fixtures/ethlikeCoin"));
|
|
49
|
+
nock_1.default.enableNetConnect();
|
|
50
|
+
const coins = [
|
|
51
|
+
{
|
|
52
|
+
name: 'hteth',
|
|
53
|
+
common: (0, resources_1.getCommon)('hteth'),
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: 'tarbeth',
|
|
57
|
+
common: (0, resources_1.getCommon)('tarbeth'),
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
describe('EthLike coin tests', function () {
|
|
61
|
+
let bitgo;
|
|
62
|
+
let basecoin;
|
|
63
|
+
coins.forEach((coin) => {
|
|
64
|
+
describe(coin.name, function () {
|
|
65
|
+
before(function () {
|
|
66
|
+
const env = 'test';
|
|
67
|
+
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env });
|
|
68
|
+
bitgo.safeRegister(coin.name, src_1.TethLikeCoin.createInstance);
|
|
69
|
+
bitgo.initializeTestVars();
|
|
70
|
+
basecoin = bitgo.coin(coin.name);
|
|
71
|
+
});
|
|
72
|
+
after(function () {
|
|
73
|
+
nock_1.default.cleanAll();
|
|
74
|
+
});
|
|
75
|
+
it('should instantiate a coin', function () {
|
|
76
|
+
basecoin.should.be.an.instanceof(src_1.TethLikeCoin);
|
|
77
|
+
});
|
|
78
|
+
it('should reject for missing encryptedPrv for hot wallet', async function () {
|
|
79
|
+
const recoveryId = '0x1234567890abcdef';
|
|
80
|
+
(0, nock_1.default)(bitgo.microservicesUrl(`/api/recovery/v1/crosschain`)).get(`/${recoveryId}/buildtx`).reply(200, {
|
|
81
|
+
txHex: mockData.ccr[coin.name].txHex,
|
|
82
|
+
});
|
|
83
|
+
const walletPassphrase = sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE;
|
|
84
|
+
const params = {
|
|
85
|
+
recoveryId,
|
|
86
|
+
walletPassphrase,
|
|
87
|
+
common: coin.common,
|
|
88
|
+
};
|
|
89
|
+
await basecoin
|
|
90
|
+
.sendCrossChainRecoveryTransaction({ ...params, walletType: 'hot' })
|
|
91
|
+
.should.be.rejectedWith('missing encryptedPrv');
|
|
92
|
+
});
|
|
93
|
+
it('should send cross chain recovery transaction for hot wallet', async function () {
|
|
94
|
+
const recoveryId = '0x1234567890abcdef';
|
|
95
|
+
(0, nock_1.default)(bitgo.microservicesUrl(`/api/recovery/v1/crosschain`)).get(`/${recoveryId}/buildtx`).reply(200, {
|
|
96
|
+
txHex: mockData.ccr[coin.name].txHex,
|
|
97
|
+
});
|
|
98
|
+
(0, nock_1.default)(bitgo.microservicesUrl(`/api/recovery/v1/crosschain`)).post(`/${recoveryId}/sign`).reply(200, {
|
|
99
|
+
coin: coin.name,
|
|
100
|
+
txid: mockData.ccr[coin.name].txid,
|
|
101
|
+
});
|
|
102
|
+
const walletPassphrase = sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE;
|
|
103
|
+
const params = {
|
|
104
|
+
recoveryId,
|
|
105
|
+
walletPassphrase,
|
|
106
|
+
encryptedPrv: mockData.encryptedUserKey,
|
|
107
|
+
common: coin.common,
|
|
108
|
+
};
|
|
109
|
+
const result = await basecoin.sendCrossChainRecoveryTransaction({ ...params, walletType: 'hot' });
|
|
110
|
+
result.coin.should.equal(coin.name);
|
|
111
|
+
result.txid.should.equal(mockData.ccr[coin.name].txid);
|
|
112
|
+
});
|
|
113
|
+
it('should build txn for cross chain recovery for cold wallet', async function () {
|
|
114
|
+
const recoveryId = '0x1234567890abcdef';
|
|
115
|
+
(0, nock_1.default)(bitgo.microservicesUrl(`/api/recovery/v1/crosschain`)).get(`/${recoveryId}/buildtx`).reply(200, {
|
|
116
|
+
txHex: mockData.ccr[coin.name].txHex,
|
|
117
|
+
});
|
|
118
|
+
const params = {
|
|
119
|
+
recoveryId,
|
|
120
|
+
common: coin.common,
|
|
121
|
+
};
|
|
122
|
+
const result = await basecoin.sendCrossChainRecoveryTransaction({ ...params, walletType: 'cold' });
|
|
123
|
+
(0, assert_1.default)(result.txHex);
|
|
124
|
+
result.txHex.should.equal(mockData.ccr[coin.name].txHex);
|
|
125
|
+
});
|
|
126
|
+
it('should generate signature data for custodial hot wallet and sign using hsm signature', async function () {
|
|
127
|
+
const baseAddress = '0x702cf81e03aa310ec9481d814e3d04a20b04b505';
|
|
128
|
+
const destinationAddress = '0xb9f62c71d5f6949cfb211a67fb13ccf079cc760b';
|
|
129
|
+
const tokenContractAddress = '0xe4ab69c077896252fafbd49efd26b5d171a32410';
|
|
130
|
+
const txBuilder = (0, getBuilder_1.getBuilder)(coin.name, coin.common);
|
|
131
|
+
txBuilder.contract(baseAddress);
|
|
132
|
+
txBuilder.contractCounter(0);
|
|
133
|
+
txBuilder.fee({
|
|
134
|
+
fee: '100000',
|
|
135
|
+
gasLimit: '21000',
|
|
136
|
+
});
|
|
137
|
+
const transferBuilder = txBuilder.transfer();
|
|
138
|
+
transferBuilder
|
|
139
|
+
.coin(coin.name)
|
|
140
|
+
.amount('100000000')
|
|
141
|
+
.contractSequenceId(100)
|
|
142
|
+
.expirationTime(1744049633)
|
|
143
|
+
.to(destinationAddress)
|
|
144
|
+
.tokenContractAddress(tokenContractAddress);
|
|
145
|
+
const signatureData = transferBuilder.getSignatureData();
|
|
146
|
+
assert_1.default.strictEqual(signatureData.toString('hex'), mockData.custodialHot[coin.name].signatureData);
|
|
147
|
+
// Set HSM Signature
|
|
148
|
+
transferBuilder.setSignature(mockData.custodialHot[coin.name].signature);
|
|
149
|
+
const tx = await txBuilder.build();
|
|
150
|
+
const txHex = tx.toBroadcastFormat();
|
|
151
|
+
assert_1.default.strictEqual(txHex, mockData.custodialHot[coin.name].signedTxHex);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
describe('EthLikeCoin', function () {
|
|
157
|
+
let bitgo;
|
|
158
|
+
const coinName = 'tbaseeth';
|
|
159
|
+
let basecoin;
|
|
160
|
+
before(function () {
|
|
161
|
+
const bitgoKeyXprv = 'xprv9s21ZrQH143K3tpWBHWe31sLoXNRQ9AvRYJgitkKxQ4ATFQMwvr7hHNqYRUnS7PsjzB7aK1VxqHLuNQjj1sckJ2Jwo2qxmsvejwECSpFMfC';
|
|
162
|
+
const bitgoKey = secp256k1_1.bip32.fromBase58(bitgoKeyXprv);
|
|
163
|
+
if (!bitgoKey.privateKey) {
|
|
164
|
+
throw new Error('no privateKey');
|
|
165
|
+
}
|
|
166
|
+
const bitgoXpub = bitgoKey.neutered().toBase58();
|
|
167
|
+
const env = 'test';
|
|
168
|
+
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env });
|
|
169
|
+
sdk_core_1.common.Environments[env].hsmXpub = bitgoXpub;
|
|
170
|
+
bitgo.safeRegister('baseeth', src_1.EthLikeCoin.createInstance);
|
|
171
|
+
bitgo.safeRegister('tbaseeth', src_1.TethLikeCoin.createInstance);
|
|
172
|
+
bitgo.initializeTestVars();
|
|
173
|
+
basecoin = bitgo.coin('tbaseeth');
|
|
174
|
+
});
|
|
175
|
+
after(function () {
|
|
176
|
+
nock_1.default.cleanAll();
|
|
177
|
+
});
|
|
178
|
+
it('should instantiate a coin', function () {
|
|
179
|
+
let coin = bitgo.coin('tbaseeth');
|
|
180
|
+
coin.should.be.an.instanceof(src_1.TethLikeCoin);
|
|
181
|
+
coin = bitgo.coin('baseeth');
|
|
182
|
+
coin.should.be.an.instanceof(src_1.EthLikeCoin);
|
|
183
|
+
});
|
|
184
|
+
it('should build unsigned transaction', async function () {
|
|
185
|
+
const expireTime = Math.floor(new Date().getTime() / 1000);
|
|
186
|
+
const txBuilder = (0, getBuilder_1.getBuilder)(coinName, resources_1.baseChainCommon);
|
|
187
|
+
txBuilder.type(sdk_core_1.TransactionType.Send);
|
|
188
|
+
txBuilder.fee({
|
|
189
|
+
fee: '1000000000',
|
|
190
|
+
gasLimit: '100000',
|
|
191
|
+
});
|
|
192
|
+
txBuilder.counter(1);
|
|
193
|
+
txBuilder.contract('0x2c2b9c9a4a25e24b174f26114e8926a9f2128fe4');
|
|
194
|
+
const transferBuilder = txBuilder.transfer();
|
|
195
|
+
transferBuilder
|
|
196
|
+
.coin(coinName)
|
|
197
|
+
.expirationTime(expireTime)
|
|
198
|
+
.amount('1000000000000000000')
|
|
199
|
+
.to('0x2c2b9c9a4a25e24b174f26114e8926a9f2128fe4')
|
|
200
|
+
.contractSequenceId(1);
|
|
201
|
+
const tx = await txBuilder.build();
|
|
202
|
+
const txJson = tx.toJson();
|
|
203
|
+
txJson.gasLimit.should.equal('100000');
|
|
204
|
+
txJson.gasPrice.should.equal('1000000000');
|
|
205
|
+
txJson.chainId.should.equal('0x14a34');
|
|
206
|
+
});
|
|
207
|
+
it('should sign a transaction', async function () {
|
|
208
|
+
const account_1 = {
|
|
209
|
+
address: '0x8Ce59c2d1702844F8EdED451AA103961bC37B4e8',
|
|
210
|
+
owner_1: '4ee089aceabf3ddbf748db79b1066c33b7d3ea1ab3eb7e325121bba2bff2f5ca',
|
|
211
|
+
owner_2: '5c7e4efff7304d4dfff6d5f1591844ec6f2adfa6a47e9fece6a3c1a4d755f1e3',
|
|
212
|
+
owner_3: '4421ab25dd91e1a3180d03d57c323a7886dcc313d3b3a4b4256a5791572bf597',
|
|
213
|
+
};
|
|
214
|
+
const expireTime = Math.floor(new Date().getTime() / 1000);
|
|
215
|
+
const txBuilder = (0, getBuilder_1.getBuilder)(coinName, resources_1.baseChainCommon);
|
|
216
|
+
txBuilder.type(sdk_core_1.TransactionType.Send);
|
|
217
|
+
txBuilder.fee({
|
|
218
|
+
fee: '1000000000',
|
|
219
|
+
gasLimit: '100000',
|
|
220
|
+
});
|
|
221
|
+
txBuilder.counter(1);
|
|
222
|
+
txBuilder.contract(account_1.address);
|
|
223
|
+
const transferBuilder = txBuilder.transfer();
|
|
224
|
+
transferBuilder
|
|
225
|
+
.coin(coinName)
|
|
226
|
+
.expirationTime(expireTime)
|
|
227
|
+
.amount('1000000000000000000')
|
|
228
|
+
.to('0x2c2b9c9a4a25e24b174f26114e8926a9f2128fe4')
|
|
229
|
+
.contractSequenceId(1);
|
|
230
|
+
const unsignedTx = await txBuilder.build();
|
|
231
|
+
const unsignedTxHex = unsignedTx.toBroadcastFormat();
|
|
232
|
+
const halfSignedTx = (await basecoin.signTransaction({
|
|
233
|
+
txPrebuild: {
|
|
234
|
+
txHex: unsignedTxHex,
|
|
235
|
+
},
|
|
236
|
+
prv: account_1.owner_1,
|
|
237
|
+
common: resources_1.baseChainCommon,
|
|
238
|
+
}));
|
|
239
|
+
transferBuilder.key(account_1.owner_1);
|
|
240
|
+
const halfSignedTxBuilder = await txBuilder.build();
|
|
241
|
+
const halfSignedTxHexBuilder = halfSignedTxBuilder.toBroadcastFormat();
|
|
242
|
+
halfSignedTxHexBuilder.should.equal(halfSignedTx.halfSigned.txHex);
|
|
243
|
+
// Sign with the second key
|
|
244
|
+
const fullSignedTxn = (await basecoin.signTransaction({
|
|
245
|
+
txPrebuild: {
|
|
246
|
+
halfSigned: {
|
|
247
|
+
txHex: halfSignedTxHexBuilder,
|
|
248
|
+
expireTime: expireTime,
|
|
249
|
+
contractSequenceId: 1,
|
|
250
|
+
signature: '',
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
prv: account_1.owner_2,
|
|
254
|
+
common: resources_1.baseChainCommon,
|
|
255
|
+
isLastSignature: true,
|
|
256
|
+
}));
|
|
257
|
+
(0, assert_1.default)(fullSignedTxn.txHex);
|
|
258
|
+
});
|
|
259
|
+
describe('explainTransaction', function () {
|
|
260
|
+
const txHex = mockData.ccr[coinName].txHex;
|
|
261
|
+
const feeInfo = {
|
|
262
|
+
fee: '1000000000',
|
|
263
|
+
gasLimit: '100000',
|
|
264
|
+
};
|
|
265
|
+
it('should explain transaction when common is provided', async function () {
|
|
266
|
+
const explanation = await basecoin.explainTransaction({
|
|
267
|
+
txHex,
|
|
268
|
+
feeInfo,
|
|
269
|
+
common: resources_1.baseChainCommon,
|
|
270
|
+
});
|
|
271
|
+
explanation.should.have.property('id');
|
|
272
|
+
explanation.should.have.property('outputs');
|
|
273
|
+
explanation.should.have.property('outputAmount');
|
|
274
|
+
explanation.should.have.property('changeOutputs');
|
|
275
|
+
explanation.should.have.property('changeAmount');
|
|
276
|
+
explanation.should.have.property('fee');
|
|
277
|
+
explanation.fee.should.equal(feeInfo);
|
|
278
|
+
explanation.outputs.should.be.an.Array();
|
|
279
|
+
});
|
|
280
|
+
it('should fail to explain transaction when common is not provided', async function () {
|
|
281
|
+
await basecoin
|
|
282
|
+
.explainTransaction({
|
|
283
|
+
txHex,
|
|
284
|
+
feeInfo,
|
|
285
|
+
})
|
|
286
|
+
.should.be.rejectedWith('Common must be provided for EthLikeTransactionBuilder');
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
describe('Recovery', function () {
|
|
290
|
+
const baseUrl = 'https://api-sepolia.basescan.org/';
|
|
291
|
+
const userXpub = 'xpub661MyMwAqRbcEeTc8789MK5PUGEYiPG4F4V17n2Rd2LoTATA1XoCnJT5FAYAShQxSxtFjpo5NHmcWwTp2LiWGBMwpUcAA3HywhxivgYfq7q';
|
|
292
|
+
const backupXpub = 'xpub661MyMwAqRbcFZX15xpZf4ERCGHiVSJm8r5C4yh1yXV2GrdZCUPYo4WQr6tN9oUywKXsgSHo7Risf9r22GH5joVD2hEEEhqnSCvK8qy11wW';
|
|
293
|
+
it('should generate an unsigned sweep transaction', async function () {
|
|
294
|
+
const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
|
|
295
|
+
const backupKeyAddress = '0x4f2c4830cc37f2785c646f89ded8a919219fa0e9';
|
|
296
|
+
(0, nock_1.default)(baseUrl)
|
|
297
|
+
.get('/api')
|
|
298
|
+
.twice()
|
|
299
|
+
.query(mockData.getTxListRequest(backupKeyAddress))
|
|
300
|
+
.reply(200, mockData.getTxListResponse);
|
|
301
|
+
(0, nock_1.default)(baseUrl)
|
|
302
|
+
.get('/api')
|
|
303
|
+
.query(mockData.getBalanceRequest(walletContractAddress))
|
|
304
|
+
.reply(200, mockData.getBalanceResponse);
|
|
305
|
+
(0, nock_1.default)(baseUrl)
|
|
306
|
+
.get('/api')
|
|
307
|
+
.query(mockData.getBalanceRequest(backupKeyAddress))
|
|
308
|
+
.reply(200, mockData.getBalanceResponse);
|
|
309
|
+
(0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
|
|
310
|
+
const baseCoin = bitgo.coin('tbaseeth');
|
|
311
|
+
const transaction = (await baseCoin.recover({
|
|
312
|
+
userKey: userXpub,
|
|
313
|
+
backupKey: backupXpub,
|
|
314
|
+
walletContractAddress: walletContractAddress,
|
|
315
|
+
recoveryDestination: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
|
|
316
|
+
eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
|
|
317
|
+
gasLimit: 500000,
|
|
318
|
+
common: resources_1.baseChainCommon,
|
|
319
|
+
}));
|
|
320
|
+
(0, assert_1.default)(transaction.txHex);
|
|
321
|
+
(0, assert_1.default)(transaction.contractSequenceId);
|
|
322
|
+
assert_1.default.strictEqual(transaction.gasLimit, '500000');
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
describe('Evm Based Cross Chain Recovery transaction:', function () {
|
|
326
|
+
const baseUrl = 'https://api-sepolia.basescan.org/';
|
|
327
|
+
const userXpub = 'xpub661MyMwAqRbcEeTc8789MK5PUGEYiPG4F4V17n2Rd2LoTATA1XoCnJT5FAYAShQxSxtFjpo5NHmcWwTp2LiWGBMwpUcAA3HywhxivgYfq7q';
|
|
328
|
+
it('should generate an unsigned recovery txn for cold wallet', async function () {
|
|
329
|
+
const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
|
|
330
|
+
const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
|
|
331
|
+
const destinationAddress = '0xd5adde17fed8baed3f32b84af05b8f2816f7b560';
|
|
332
|
+
const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
|
|
333
|
+
const basecoin = bitgo.coin('tbaseeth');
|
|
334
|
+
(0, nock_1.default)(baseUrl)
|
|
335
|
+
.get('/api')
|
|
336
|
+
.query(mockData.getTxListRequest(bitgoFeeAddress))
|
|
337
|
+
.reply(200, mockData.getTxListResponse);
|
|
338
|
+
(0, nock_1.default)(baseUrl)
|
|
339
|
+
.get('/api')
|
|
340
|
+
.query(mockData.getBalanceRequest(bitgoFeeAddress))
|
|
341
|
+
.reply(200, mockData.getBalanceResponse);
|
|
342
|
+
(0, nock_1.default)(baseUrl)
|
|
343
|
+
.get('/api')
|
|
344
|
+
.query(mockData.getBalanceRequest(walletContractAddress))
|
|
345
|
+
.reply(200, mockData.getBalanceResponse);
|
|
346
|
+
(0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
|
|
347
|
+
const transaction = (await basecoin.recover({
|
|
348
|
+
userKey: userXpub,
|
|
349
|
+
backupKey: '',
|
|
350
|
+
walletContractAddress: walletContractAddress,
|
|
351
|
+
bitgoFeeAddress: bitgoFeeAddress,
|
|
352
|
+
recoveryDestination: destinationAddress,
|
|
353
|
+
eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
|
|
354
|
+
gasLimit: 500000,
|
|
355
|
+
bitgoDestinationAddress: bitgoDestinationAddress,
|
|
356
|
+
common: resources_1.baseChainCommon,
|
|
357
|
+
}));
|
|
358
|
+
(0, assert_1.default)(transaction);
|
|
359
|
+
transaction.should.have.property('txHex');
|
|
360
|
+
transaction.should.have.property('userKey');
|
|
361
|
+
transaction.should.have.property('coin');
|
|
362
|
+
transaction.should.have.property('contractSequenceId');
|
|
363
|
+
transaction.should.have.property('expireTime');
|
|
364
|
+
transaction.should.have.property('gasLimit');
|
|
365
|
+
transaction.gasLimit.should.equal('500000');
|
|
366
|
+
transaction.should.have.property('isEvmBasedCrossChainRecovery');
|
|
367
|
+
transaction.isEvmBasedCrossChainRecovery?.should.equal(true);
|
|
368
|
+
transaction.should.have.property('walletContractAddress');
|
|
369
|
+
transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
|
|
370
|
+
transaction.should.have.property('recipients');
|
|
371
|
+
const recipient = transaction.recipients[0];
|
|
372
|
+
recipient.should.have.property('address');
|
|
373
|
+
recipient.address.should.equal(destinationAddress);
|
|
374
|
+
recipient.should.have.property('amount');
|
|
375
|
+
recipient.amount.should.equal('9999999999999999928');
|
|
376
|
+
});
|
|
377
|
+
it('should generate an unsigned recovery txn for custody wallet', async function () {
|
|
378
|
+
const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
|
|
379
|
+
const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
|
|
380
|
+
const destinationAddress = '0xd5adde17fed8baed3f32b84af05b8f2816f7b560';
|
|
381
|
+
const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
|
|
382
|
+
const basecoin = bitgo.coin('tbaseeth');
|
|
383
|
+
(0, nock_1.default)(baseUrl)
|
|
384
|
+
.get('/api')
|
|
385
|
+
.query(mockData.getTxListRequest(bitgoFeeAddress))
|
|
386
|
+
.reply(200, mockData.getTxListResponse);
|
|
387
|
+
(0, nock_1.default)(baseUrl)
|
|
388
|
+
.get('/api')
|
|
389
|
+
.query(mockData.getBalanceRequest(bitgoFeeAddress))
|
|
390
|
+
.reply(200, mockData.getBalanceResponse);
|
|
391
|
+
(0, nock_1.default)(baseUrl)
|
|
392
|
+
.get('/api')
|
|
393
|
+
.query(mockData.getBalanceRequest(walletContractAddress))
|
|
394
|
+
.reply(200, mockData.getBalanceResponse);
|
|
395
|
+
(0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
|
|
396
|
+
const transaction = (await basecoin.recover({
|
|
397
|
+
userKey: '',
|
|
398
|
+
backupKey: '',
|
|
399
|
+
walletContractAddress: walletContractAddress,
|
|
400
|
+
bitgoFeeAddress: bitgoFeeAddress,
|
|
401
|
+
recoveryDestination: destinationAddress,
|
|
402
|
+
eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
|
|
403
|
+
gasLimit: 500000,
|
|
404
|
+
bitgoDestinationAddress: bitgoDestinationAddress,
|
|
405
|
+
common: resources_1.baseChainCommon,
|
|
406
|
+
}));
|
|
407
|
+
(0, assert_1.default)(transaction);
|
|
408
|
+
transaction.should.have.property('txHex');
|
|
409
|
+
transaction.should.have.property('coin');
|
|
410
|
+
transaction.should.have.property('contractSequenceId');
|
|
411
|
+
transaction.should.have.property('expireTime');
|
|
412
|
+
transaction.should.have.property('gasLimit');
|
|
413
|
+
transaction.gasLimit.should.equal('500000');
|
|
414
|
+
transaction.should.have.property('isEvmBasedCrossChainRecovery');
|
|
415
|
+
transaction.isEvmBasedCrossChainRecovery?.should.equal(true);
|
|
416
|
+
transaction.should.have.property('walletContractAddress');
|
|
417
|
+
transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
|
|
418
|
+
transaction.should.have.property('recipients');
|
|
419
|
+
const recipient = transaction.recipients[0];
|
|
420
|
+
recipient.should.have.property('address');
|
|
421
|
+
recipient.address.should.equal(destinationAddress);
|
|
422
|
+
recipient.should.have.property('amount');
|
|
423
|
+
recipient.amount.should.equal('9999999999999999928');
|
|
424
|
+
});
|
|
425
|
+
it('should generate an unsigned recovery txn for hot wallet', async function () {
|
|
426
|
+
const userKey = '{"iv":"VFZ3jvXhxo1Z+Yaf2MtZnA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
|
|
427
|
+
':"ccm","adata":"","cipher":"aes","salt":"p+fkHuLa/8k=","ct":"hYG7pvljLIgCjZ\n' +
|
|
428
|
+
'53PBlCde5KZRmlUKKHLtDMk+HJfuU46hW+x+C9WsIAO4gFPnTCvFVmQ8x7czCtcNFub5AO2otOG\n' +
|
|
429
|
+
'OsX4GE2gXOEmCl1TpWwwNhm7yMUjGJUpgW6ZZgXSXdDitSKi4V/hk78SGSzjFOBSPYRa6I="}\n';
|
|
430
|
+
const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
|
|
431
|
+
const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
|
|
432
|
+
const destinationAddress = '0xd5adde17fed8baed3f32b84af05b8f2816f7b560';
|
|
433
|
+
const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
|
|
434
|
+
const walletPassphrase = sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE;
|
|
435
|
+
const basecoin = bitgo.coin('tbaseeth');
|
|
436
|
+
(0, nock_1.default)(baseUrl)
|
|
437
|
+
.get('/api')
|
|
438
|
+
.query(mockData.getTxListRequest(bitgoFeeAddress))
|
|
439
|
+
.reply(200, mockData.getTxListResponse);
|
|
440
|
+
(0, nock_1.default)(baseUrl)
|
|
441
|
+
.get('/api')
|
|
442
|
+
.query(mockData.getBalanceRequest(bitgoFeeAddress))
|
|
443
|
+
.reply(200, mockData.getBalanceResponse);
|
|
444
|
+
(0, nock_1.default)(baseUrl)
|
|
445
|
+
.get('/api')
|
|
446
|
+
.query(mockData.getBalanceRequest(walletContractAddress))
|
|
447
|
+
.reply(200, mockData.getBalanceResponse);
|
|
448
|
+
(0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
|
|
449
|
+
const transaction = (await basecoin.recover({
|
|
450
|
+
userKey: userKey,
|
|
451
|
+
backupKey: '',
|
|
452
|
+
walletPassphrase: walletPassphrase,
|
|
453
|
+
walletContractAddress: walletContractAddress,
|
|
454
|
+
bitgoFeeAddress: bitgoFeeAddress,
|
|
455
|
+
recoveryDestination: destinationAddress,
|
|
456
|
+
eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
|
|
457
|
+
gasLimit: 500000,
|
|
458
|
+
bitgoDestinationAddress: bitgoDestinationAddress,
|
|
459
|
+
common: resources_1.baseChainCommon,
|
|
460
|
+
}));
|
|
461
|
+
(0, assert_1.default)(transaction);
|
|
462
|
+
transaction.should.have.property('txHex');
|
|
463
|
+
transaction.should.have.property('coin');
|
|
464
|
+
transaction.should.have.property('contractSequenceId');
|
|
465
|
+
transaction.should.have.property('expireTime');
|
|
466
|
+
transaction.should.have.property('gasLimit');
|
|
467
|
+
transaction.gasLimit.should.equal('500000');
|
|
468
|
+
transaction.should.have.property('isEvmBasedCrossChainRecovery');
|
|
469
|
+
transaction.isEvmBasedCrossChainRecovery?.should.equal(true);
|
|
470
|
+
transaction.should.have.property('walletContractAddress');
|
|
471
|
+
transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
|
|
472
|
+
transaction.should.have.property('recipients');
|
|
473
|
+
const recipient = transaction.recipients[0];
|
|
474
|
+
recipient.should.have.property('address');
|
|
475
|
+
recipient.address.should.equal(destinationAddress);
|
|
476
|
+
recipient.should.have.property('amount');
|
|
477
|
+
recipient.amount.should.equal('9999999999999999928');
|
|
478
|
+
transaction.should.have.property('feesUsed');
|
|
479
|
+
transaction.feesUsed?.gasLimit.should.equal('500000');
|
|
480
|
+
transaction.should.have.property('halfSigned');
|
|
481
|
+
transaction.halfSigned?.should.have.property('txHex');
|
|
482
|
+
transaction.halfSigned?.should.have.property('recipients');
|
|
483
|
+
});
|
|
484
|
+
it('should generate an unsigned recovery txn of a token for cold wallet ', async function () {
|
|
485
|
+
const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
|
|
486
|
+
const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
|
|
487
|
+
const destinationAddress = '0xd5adde17fed8baed3f32b84af05b8f2816f7b560';
|
|
488
|
+
const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
|
|
489
|
+
const tokenContractAddress = '0x326c977e6efc84e512bb9c30f76e30c160ed06fb';
|
|
490
|
+
const basecoin = bitgo.coin('tbaseeth');
|
|
491
|
+
(0, nock_1.default)(baseUrl)
|
|
492
|
+
.get('/api')
|
|
493
|
+
.query(mockData.getTxListRequest(bitgoFeeAddress))
|
|
494
|
+
.reply(200, mockData.getTxListResponse);
|
|
495
|
+
(0, nock_1.default)(baseUrl)
|
|
496
|
+
.get('/api')
|
|
497
|
+
.query(mockData.getBalanceRequest(bitgoFeeAddress))
|
|
498
|
+
.reply(200, mockData.getBalanceResponse);
|
|
499
|
+
(0, nock_1.default)(baseUrl)
|
|
500
|
+
.get('/api')
|
|
501
|
+
.query(mockData.getTokenBalanceRequest(tokenContractAddress, walletContractAddress))
|
|
502
|
+
.reply(200, mockData.getBalanceResponse);
|
|
503
|
+
(0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
|
|
504
|
+
const transaction = (await basecoin.recover({
|
|
505
|
+
userKey: userXpub,
|
|
506
|
+
backupKey: '',
|
|
507
|
+
walletContractAddress: walletContractAddress,
|
|
508
|
+
bitgoFeeAddress: bitgoFeeAddress,
|
|
509
|
+
recoveryDestination: destinationAddress,
|
|
510
|
+
eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
|
|
511
|
+
gasLimit: 500000,
|
|
512
|
+
bitgoDestinationAddress: bitgoDestinationAddress,
|
|
513
|
+
tokenContractAddress: tokenContractAddress,
|
|
514
|
+
common: resources_1.baseChainCommon,
|
|
515
|
+
}));
|
|
516
|
+
(0, assert_1.default)(transaction);
|
|
517
|
+
transaction.should.have.property('txHex');
|
|
518
|
+
transaction.should.have.property('userKey');
|
|
519
|
+
transaction.should.have.property('coin');
|
|
520
|
+
transaction.coin.should.equal('tbaseeth');
|
|
521
|
+
transaction.should.have.property('contractSequenceId');
|
|
522
|
+
transaction.should.have.property('expireTime');
|
|
523
|
+
transaction.should.have.property('gasLimit');
|
|
524
|
+
transaction.gasLimit.should.equal('500000');
|
|
525
|
+
transaction.should.have.property('isEvmBasedCrossChainRecovery');
|
|
526
|
+
transaction.isEvmBasedCrossChainRecovery?.should.equal(true);
|
|
527
|
+
transaction.should.have.property('walletContractAddress');
|
|
528
|
+
transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
|
|
529
|
+
transaction.should.have.property('recipients');
|
|
530
|
+
const recipient = transaction.recipients[0];
|
|
531
|
+
recipient.should.have.property('address');
|
|
532
|
+
recipient.address.should.equal(destinationAddress);
|
|
533
|
+
recipient.should.have.property('amount');
|
|
534
|
+
recipient.amount.should.equal('9999999999999999928');
|
|
535
|
+
});
|
|
536
|
+
it('should generate an unsigned recovery txn of a token for custody wallet', async function () {
|
|
537
|
+
const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
|
|
538
|
+
const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
|
|
539
|
+
const destinationAddress = '0xd5adde17fed8baed3f32b84af05b8f2816f7b560';
|
|
540
|
+
const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
|
|
541
|
+
const tokenContractAddress = '0x326c977e6efc84e512bb9c30f76e30c160ed06fb'; // unsupported token contract address
|
|
542
|
+
const basecoin = bitgo.coin('tbaseeth');
|
|
543
|
+
(0, nock_1.default)(baseUrl)
|
|
544
|
+
.get('/api')
|
|
545
|
+
.query(mockData.getTxListRequest(bitgoFeeAddress))
|
|
546
|
+
.reply(200, mockData.getTxListResponse);
|
|
547
|
+
(0, nock_1.default)(baseUrl)
|
|
548
|
+
.get('/api')
|
|
549
|
+
.query(mockData.getBalanceRequest(bitgoFeeAddress))
|
|
550
|
+
.reply(200, mockData.getBalanceResponse);
|
|
551
|
+
(0, nock_1.default)(baseUrl)
|
|
552
|
+
.get('/api')
|
|
553
|
+
.query(mockData.getTokenBalanceRequest(tokenContractAddress, walletContractAddress))
|
|
554
|
+
.reply(200, mockData.getBalanceResponse);
|
|
555
|
+
(0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
|
|
556
|
+
const transaction = (await basecoin.recover({
|
|
557
|
+
userKey: '',
|
|
558
|
+
backupKey: '',
|
|
559
|
+
walletContractAddress: walletContractAddress,
|
|
560
|
+
bitgoFeeAddress: bitgoFeeAddress,
|
|
561
|
+
recoveryDestination: destinationAddress,
|
|
562
|
+
eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
|
|
563
|
+
gasLimit: 500000,
|
|
564
|
+
bitgoDestinationAddress: bitgoDestinationAddress,
|
|
565
|
+
tokenContractAddress: tokenContractAddress,
|
|
566
|
+
common: resources_1.baseChainCommon,
|
|
567
|
+
}));
|
|
568
|
+
(0, assert_1.default)(transaction);
|
|
569
|
+
transaction.should.have.property('txHex');
|
|
570
|
+
transaction.should.have.property('coin');
|
|
571
|
+
transaction.coin.should.equal('tbaseeth');
|
|
572
|
+
transaction.should.have.property('contractSequenceId');
|
|
573
|
+
transaction.should.have.property('expireTime');
|
|
574
|
+
transaction.should.have.property('gasLimit');
|
|
575
|
+
transaction.gasLimit.should.equal('500000');
|
|
576
|
+
transaction.should.have.property('isEvmBasedCrossChainRecovery');
|
|
577
|
+
transaction.isEvmBasedCrossChainRecovery?.should.equal(true);
|
|
578
|
+
transaction.should.have.property('walletContractAddress');
|
|
579
|
+
transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
|
|
580
|
+
transaction.should.have.property('recipients');
|
|
581
|
+
const recipient = transaction.recipients[0];
|
|
582
|
+
recipient.should.have.property('address');
|
|
583
|
+
recipient.address.should.equal(destinationAddress);
|
|
584
|
+
recipient.should.have.property('amount');
|
|
585
|
+
recipient.amount.should.equal('9999999999999999928');
|
|
586
|
+
});
|
|
587
|
+
it('should generate an unsigned recovery txn of a token for hot wallet', async function () {
|
|
588
|
+
const userKey = '{"iv":"VFZ3jvXhxo1Z+Yaf2MtZnA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
|
|
589
|
+
':"ccm","adata":"","cipher":"aes","salt":"p+fkHuLa/8k=","ct":"hYG7pvljLIgCjZ\n' +
|
|
590
|
+
'53PBlCde5KZRmlUKKHLtDMk+HJfuU46hW+x+C9WsIAO4gFPnTCvFVmQ8x7czCtcNFub5AO2otOG\n' +
|
|
591
|
+
'OsX4GE2gXOEmCl1TpWwwNhm7yMUjGJUpgW6ZZgXSXdDitSKi4V/hk78SGSzjFOBSPYRa6I="}\n';
|
|
592
|
+
const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
|
|
593
|
+
const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
|
|
594
|
+
const destinationAddress = '0xd5adde17fed8baed3f32b84af05b8f2816f7b560';
|
|
595
|
+
const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
|
|
596
|
+
const walletPassphrase = sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE;
|
|
597
|
+
const tokenContractAddress = '0x326c977e6efc84e512bb9c30f76e30c160ed06fb'; // unsupported contract token address
|
|
598
|
+
const basecoin = bitgo.coin('tbaseeth');
|
|
599
|
+
(0, nock_1.default)(baseUrl)
|
|
600
|
+
.get('/api')
|
|
601
|
+
.query(mockData.getTxListRequest(bitgoFeeAddress))
|
|
602
|
+
.reply(200, mockData.getTxListResponse);
|
|
603
|
+
(0, nock_1.default)(baseUrl)
|
|
604
|
+
.get('/api')
|
|
605
|
+
.query(mockData.getBalanceRequest(bitgoFeeAddress))
|
|
606
|
+
.reply(200, mockData.getBalanceResponse);
|
|
607
|
+
(0, nock_1.default)(baseUrl)
|
|
608
|
+
.get('/api')
|
|
609
|
+
.query(mockData.getTokenBalanceRequest(tokenContractAddress, walletContractAddress))
|
|
610
|
+
.reply(200, mockData.getBalanceResponse);
|
|
611
|
+
(0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
|
|
612
|
+
const transaction = (await basecoin.recover({
|
|
613
|
+
userKey: userKey,
|
|
614
|
+
backupKey: '',
|
|
615
|
+
walletPassphrase: walletPassphrase,
|
|
616
|
+
walletContractAddress: walletContractAddress,
|
|
617
|
+
bitgoFeeAddress: bitgoFeeAddress,
|
|
618
|
+
recoveryDestination: destinationAddress,
|
|
619
|
+
eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
|
|
620
|
+
gasLimit: 500000,
|
|
621
|
+
bitgoDestinationAddress: bitgoDestinationAddress,
|
|
622
|
+
tokenContractAddress: tokenContractAddress,
|
|
623
|
+
common: resources_1.baseChainCommon,
|
|
624
|
+
}));
|
|
625
|
+
(0, assert_1.default)(transaction);
|
|
626
|
+
transaction.should.have.property('txHex');
|
|
627
|
+
transaction.should.have.property('coin');
|
|
628
|
+
transaction.coin.should.equal('tbaseeth');
|
|
629
|
+
transaction.should.have.property('contractSequenceId');
|
|
630
|
+
transaction.should.have.property('expireTime');
|
|
631
|
+
transaction.should.have.property('gasLimit');
|
|
632
|
+
transaction.gasLimit.should.equal('500000');
|
|
633
|
+
transaction.should.have.property('isEvmBasedCrossChainRecovery');
|
|
634
|
+
transaction.isEvmBasedCrossChainRecovery?.should.equal(true);
|
|
635
|
+
transaction.should.have.property('walletContractAddress');
|
|
636
|
+
transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
|
|
637
|
+
transaction.should.have.property('recipients');
|
|
638
|
+
const recipient = transaction.recipients[0];
|
|
639
|
+
recipient.should.have.property('address');
|
|
640
|
+
recipient.address.should.equal(destinationAddress);
|
|
641
|
+
recipient.should.have.property('amount');
|
|
642
|
+
recipient.amount.should.equal('9999999999999999928');
|
|
643
|
+
transaction.should.have.property('feesUsed');
|
|
644
|
+
transaction.feesUsed?.gasLimit.should.equal('500000');
|
|
645
|
+
transaction.should.have.property('halfSigned');
|
|
646
|
+
transaction.halfSigned?.should.have.property('txHex');
|
|
647
|
+
transaction.halfSigned?.should.have.property('recipients');
|
|
648
|
+
});
|
|
649
|
+
});
|
|
650
|
+
describe('Common parameter handling', function () {
|
|
651
|
+
it('should handle plain object common parameter for BASE chain', function () {
|
|
652
|
+
const baseCoin = bitgo.coin('baseeth');
|
|
653
|
+
const plainCommon = { chain: 8453, hardfork: 'london' };
|
|
654
|
+
const txBuilder = baseCoin.getTransactionBuilder(plainCommon);
|
|
655
|
+
txBuilder.should.be.an.instanceof(src_1.EthLikeTransactionBuilder);
|
|
656
|
+
});
|
|
657
|
+
it('should handle plain object common parameter with chainId property', function () {
|
|
658
|
+
const baseCoin = bitgo.coin('baseeth');
|
|
659
|
+
const plainCommon = { chainId: 8453, hardfork: 'london' };
|
|
660
|
+
const txBuilder = baseCoin.getTransactionBuilder(plainCommon);
|
|
661
|
+
txBuilder.should.be.an.instanceof(src_1.EthLikeTransactionBuilder);
|
|
662
|
+
});
|
|
663
|
+
it('should handle EthereumCommon instance', function () {
|
|
664
|
+
const baseCoin = bitgo.coin('baseeth');
|
|
665
|
+
const txBuilder = baseCoin.getTransactionBuilder(resources_1.baseChainCommon);
|
|
666
|
+
txBuilder.should.be.an.instanceof(src_1.EthLikeTransactionBuilder);
|
|
667
|
+
});
|
|
668
|
+
it('should require common parameter and throw error when undefined', function () {
|
|
669
|
+
const baseCoin = bitgo.coin('baseeth');
|
|
670
|
+
(() => {
|
|
671
|
+
baseCoin.getTransactionBuilder(undefined);
|
|
672
|
+
}).should.throw('Common must be provided for EthLikeTransactionBuilder');
|
|
673
|
+
});
|
|
674
|
+
it('should convert plain object common to EthereumCommon with working gteHardfork method', function () {
|
|
675
|
+
const baseCoin = bitgo.coin('baseeth');
|
|
676
|
+
const plainCommon = { chain: 8453, hardfork: 'london' };
|
|
677
|
+
const txBuilder = baseCoin.getTransactionBuilder(plainCommon);
|
|
678
|
+
txBuilder.should.be.an.instanceof(src_1.EthLikeTransactionBuilder);
|
|
679
|
+
const common = txBuilder._common;
|
|
680
|
+
common.should.not.be.undefined;
|
|
681
|
+
common.should.have.property('gteHardfork');
|
|
682
|
+
(typeof common.gteHardfork).should.equal('function');
|
|
683
|
+
const result = common.gteHardfork('homestead');
|
|
684
|
+
(typeof result).should.equal('boolean');
|
|
685
|
+
result.should.equal(true);
|
|
686
|
+
});
|
|
687
|
+
});
|
|
688
|
+
});
|
|
689
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXRobGlrZUNvaW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQvZXRobGlrZUNvaW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsNENBQTBDO0FBQzFDLDhDQUF5RztBQUV6Ryw4Q0FBMEQ7QUFDMUQsZ0RBQXlDO0FBQ3pDLGdEQUF3QjtBQUV4QixtQ0FBaUY7QUFDakYsOENBQTJDO0FBQzNDLDRDQUEwRDtBQUMxRCxrRUFBb0Q7QUFFcEQsY0FBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7QUFFeEIsTUFBTSxLQUFLLEdBQUc7SUFDWjtRQUNFLElBQUksRUFBRSxPQUFPO1FBQ2IsTUFBTSxFQUFFLElBQUEscUJBQVMsRUFBQyxPQUFPLENBQUM7S0FDM0I7SUFDRDtRQUNFLElBQUksRUFBRSxTQUFTO1FBQ2YsTUFBTSxFQUFFLElBQUEscUJBQVMsRUFBQyxTQUFTLENBQUM7S0FDN0I7Q0FDRixDQUFDO0FBRUYsUUFBUSxDQUFDLG9CQUFvQixFQUFFO0lBQzdCLElBQUksS0FBbUIsQ0FBQztJQUN4QixJQUFJLFFBQXNCLENBQUM7SUFDM0IsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1FBQ3JCLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQ2xCLE1BQU0sQ0FBQztnQkFDTCxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUM7Z0JBQ25CLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxrQkFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztnQkFDOUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLGtCQUFZLENBQUMsY0FBYyxDQUFDLENBQUM7Z0JBQzNELEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO2dCQUMzQixRQUFRLEdBQUcsS0FB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LENBQUM7UUFDM0UsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsc0ZBQXNGLEVBQUU7WUFDekYsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQWdCLENBQUM7WUFFdEQsTUFBTSxXQUFXLEdBQUcsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsQ0FBQztZQUV4RCxNQUFNLFNBQVMsR0FBSSxRQUFnQixDQUFDLHFCQUFxQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ3ZFLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsK0JBQXlCLENBQUMsQ0FBQztZQUU3RCxNQUFNLE1BQU0sR0FBSSxTQUFpQixDQUFDLE9BQU8sQ0FBQztZQUMxQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDO1lBRS9CLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUMzQyxDQUFDLE9BQU8sTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7WUFFckQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUMvQyxDQUFDLE9BQU8sTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN4QyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgeyBCaXRHb0FQSSB9IGZyb20gJ0BiaXRnby9zZGstYXBpJztcbmltcG9ydCB7IGNvbW1vbiwgRnVsbHlTaWduZWRUcmFuc2FjdGlvbiwgSGFsZlNpZ25lZFRyYW5zYWN0aW9uLCBUcmFuc2FjdGlvblR5cGUgfSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuaW1wb3J0IHsgT2ZmbGluZVZhdWx0VHhJbmZvLCBUcmFuc2ZlckJ1aWxkZXIgfSBmcm9tICdAYml0Z28vYWJzdHJhY3QtZXRoJztcbmltcG9ydCB7IFRlc3RCaXRHbywgVGVzdEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvL3Nkay10ZXN0JztcbmltcG9ydCB7IGJpcDMyIH0gZnJvbSAnQGJpdGdvL3NlY3AyNTZrMSc7XG5pbXBvcnQgbm9jayBmcm9tICdub2NrJztcblxuaW1wb3J0IHsgRXRoTGlrZUNvaW4sIFRldGhMaWtlQ29pbiwgRXRoTGlrZVRyYW5zYWN0aW9uQnVpbGRlciB9IGZyb20gJy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBnZXRCdWlsZGVyIH0gZnJvbSAnLi4vZ2V0QnVpbGRlcic7XG5pbXBvcnQgeyBiYXNlQ2hhaW5Db21tb24sIGdldENvbW1vbiB9IGZyb20gJy4uL3Jlc291cmNlcyc7XG5pbXBvcnQgKiBhcyBtb2NrRGF0YSBmcm9tICcuLi9maXh0dXJlcy9ldGhsaWtlQ29pbic7XG5cbm5vY2suZW5hYmxlTmV0Q29ubmVjdCgpO1xuXG5jb25zdCBjb2lucyA9IFtcbiAge1xuICAgIG5hbWU6ICdodGV0aCcsXG4gICAgY29tbW9uOiBnZXRDb21tb24oJ2h0ZXRoJyksXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAndGFyYmV0aCcsXG4gICAgY29tbW9uOiBnZXRDb21tb24oJ3RhcmJldGgnKSxcbiAgfSxcbl07XG5cbmRlc2NyaWJlKCdFdGhMaWtlIGNvaW4gdGVzdHMnLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICBsZXQgYmFzZWNvaW46IFRldGhMaWtlQ29pbjtcbiAgY29pbnMuZm9yRWFjaCgoY29pbikgPT4ge1xuICAgIGRlc2NyaWJlKGNvaW4ubmFtZSwgZnVuY3Rpb24gKCkge1xuICAgICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZW52ID0gJ3Rlc3QnO1xuICAgICAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnYgfSk7XG4gICAgICAgIGJpdGdvLnNhZmVSZWdpc3Rlcihjb2luLm5hbWUsIFRldGhMaWtlQ29pbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgICAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4oY29pbi5uYW1lKSBhcyBUZXRoTGlrZUNvaW47XG4gICAgICB9KTtcblxuICAgICAgYWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBpbnN0YW50aWF0ZSBhIGNvaW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJhc2Vjb2luLnNob3VsZC5iZS5hbi5pbnN0YW5jZW9mKFRldGhMaWtlQ29pbik7XG4gICAgICB9KTtcbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGZvciBtaXNzaW5nIGVuY3J5cHRlZFBydiBmb3IgaG90IHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVjb3ZlcnlJZCA9ICcweDEyMzQ1Njc4OTBhYmNkZWYnO1xuICAgICAgICBub2NrKGJpdGdvLm1pY3Jvc2VydmljZXNVcmwoYC9hcGkvcmVjb3ZlcnkvdjEvY3Jvc3NjaGFpbmApKS5nZXQoYC8ke3JlY292ZXJ5SWR9L2J1aWxkdHhgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICB0eEhleDogbW9ja0RhdGEuY2NyW2NvaW4ubmFtZV0udHhIZXgsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gVGVzdEJpdEdvLlYyLlRFU1RfUkVDT1ZFUllfUEFTU0NPREUgYXMgc3RyaW5nO1xuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgcmVjb3ZlcnlJZCxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGNvbW1vbjogY29pbi5jb21tb24sXG4gICAgICAgIH07XG4gICAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgICAgLnNlbmRDcm9zc0NoYWluUmVjb3ZlcnlUcmFuc2FjdGlvbih7IC4uLnBhcmFtcywgd2FsbGV0VHlwZTogJ2hvdCcgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyBlbmNyeXB0ZWRQcnYnKTtcbiAgICAgIH0pO1xuICAgICAgaXQoJ3Nob3VsZCBzZW5kIGNyb3NzIGNoYWluIHJlY292ZXJ5IHRyYW5zYWN0aW9uIGZvciBob3Qgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByZWNvdmVyeUlkID0gJzB4MTIzNDU2Nzg5MGFiY2RlZic7XG4gICAgICAgIG5vY2soYml0Z28ubWljcm9zZXJ2aWNlc1VybChgL2FwaS9yZWNvdmVyeS92MS9jcm9zc2NoYWluYCkpLmdldChgLyR7cmVjb3ZlcnlJZH0vYnVpbGR0eGApLnJlcGx5KDIwMCwge1xuICAgICAgICAgIHR4SGV4OiBtb2NrRGF0YS5jY3JbY29pbi5uYW1lXS50eEhleCxcbiAgICAgICAgfSk7XG4gICAgICAgIG5vY2soYml0Z28ubWljcm9zZXJ2aWNlc1VybChgL2FwaS9yZWNvdmVyeS92MS9jcm9zc2NoYWluYCkpLnBvc3QoYC8ke3JlY292ZXJ5SWR9L3NpZ25gKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICBjb2luOiBjb2luLm5hbWUsXG4gICAgICAgICAgdHhpZDogbW9ja0RhdGEuY2NyW2NvaW4ubmFtZV0udHhpZCxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSBUZXN0Qml0R28uVjIuVEVTVF9SRUNPVkVSWV9QQVNTQ09ERSBhcyBzdHJpbmc7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICByZWNvdmVyeUlkLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiBtb2NrRGF0YS5lbmNyeXB0ZWRVc2VyS2V5LFxuICAgICAgICAgIGNvbW1vbjogY29pbi5jb21tb24sXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnNlbmRDcm9zc0NoYWluUmVjb3ZlcnlUcmFuc2FjdGlvbih7IC4uLnBhcmFtcywgd2FsbGV0VHlwZTogJ2hvdCcgfSk7XG4gICAgICAgIHJlc3VsdC5jb2luLnNob3VsZC5lcXVhbChjb2luLm5hbWUpO1xuICAgICAgICByZXN1bHQudHhpZC5zaG91bGQuZXF1YWwobW9ja0RhdGEuY2NyW2NvaW4ubmFtZV0udHhpZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCB0eG4gZm9yIGNyb3NzIGNoYWluIHJlY292ZXJ5IGZvciBjb2xkIHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVjb3ZlcnlJZCA9ICcweDEyMzQ1Njc4OTBhYmNkZWYnO1xuICAgICAgICBub2NrKGJpdGdvLm1pY3Jvc2VydmljZXNVcmwoYC9hcGkvcmVjb3ZlcnkvdjEvY3Jvc3NjaGFpbmApKS5nZXQoYC8ke3JlY292ZXJ5SWR9L2J1aWxkdHhgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICB0eEhleDogbW9ja0RhdGEuY2NyW2NvaW4ubmFtZV0udHhIZXgsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgcmVjb3ZlcnlJZCxcbiAgICAgICAgICBjb21tb246IGNvaW4uY29tbW9uLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi5zZW5kQ3Jvc3NDaGFpblJlY292ZXJ5VHJhbnNhY3Rpb24oeyAuLi5wYXJhbXMsIHdhbGxldFR5cGU6ICdjb2xkJyB9KTtcbiAgICAgICAgYXNzZXJ0KHJlc3VsdC50eEhleCk7XG4gICAgICAgIHJlc3VsdC50eEhleC5zaG91bGQuZXF1YWwobW9ja0RhdGEuY2NyW2NvaW4ubmFtZV0udHhIZXgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgc2lnbmF0dXJlIGRhdGEgZm9yIGN1c3RvZGlhbCBob3Qgd2FsbGV0IGFuZCBzaWduIHVzaW5nIGhzbSBzaWduYXR1cmUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4NzAyY2Y4MWUwM2FhMzEwZWM5NDgxZDgxNGUzZDA0YTIwYjA0YjUwNSc7XG4gICAgICAgIGNvbnN0IGRlc3RpbmF0aW9uQWRkcmVzcyA9ICcweGI5ZjYyYzcxZDVmNjk0OWNmYjIxMWE2N2ZiMTNjY2YwNzljYzc2MGInO1xuICAgICAgICBjb25zdCB0b2tlbkNvbnRyYWN0QWRkcmVzcyA9ICcweGU0YWI2OWMwNzc4OTYyNTJmYWZiZDQ5ZWZkMjZiNWQxNzFhMzI0MTAnO1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKGNvaW4ubmFtZSwgY29pbi5jb21tb24pIGFzIEV0aExpa2VUcmFuc2FjdGlvbkJ1aWxkZXI7XG5cbiAgICAgICAgdHhCdWlsZGVyLmNvbnRyYWN0KGJhc2VBZGRyZXNzKTtcbiAgICAgICAgdHhCdWlsZGVyLmNvbnRyYWN0Q291bnRlcigwKTtcbiAgICAgICAgdHhCdWlsZGVyLmZlZSh7XG4gICAgICAgICAgZmVlOiAnMTAwMDAwJyxcbiAgICAgICAgICBnYXNMaW1pdDogJzIxMDAwJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdHJhbnNmZXJCdWlsZGVyID0gdHhCdWlsZGVyLnRyYW5zZmVyKCkgYXMgVHJhbnNmZXJCdWlsZGVyO1xuICAgICAgICB0cmFuc2ZlckJ1aWxkZXJcbiAgICAgICAgICAuY29pbihjb2luLm5hbWUpXG4gICAgICAgICAgLmFtb3VudCgnMTAwMDAwMDAwJylcbiAgICAgICAgICAuY29udHJhY3RTZXF1ZW5jZUlkKDEwMClcbiAgICAgICAgICAuZXhwaXJhdGlvblRpbWUoMTc0NDA0OTYzMylcbiAgICAgICAgICAudG8oZGVzdGluYXRpb25BZGRyZXNzKVxuICAgICAgICAgIC50b2tlbkNvbnRyYWN0QWRkcmVzcyh0b2tlbkNvbnRyYWN0QWRkcmVzcyk7XG4gICAgICAgIGNvbnN0IHNpZ25hdHVyZURhdGEgPSB0cmFuc2ZlckJ1aWxkZXIuZ2V0U2lnbmF0dXJlRGF0YSgpO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2lnbmF0dXJlRGF0YS50b1N0cmluZygnaGV4JyksIG1vY2tEYXRhLmN1c3RvZGlhbEhvdFtjb2luLm5hbWVdLnNpZ25hdHVyZURhdGEpO1xuXG4gICAgICAgIC8vIFNldCBIU00gU2lnbmF0dXJlXG4gICAgICAgIHRyYW5zZmVyQnVpbGRlci5zZXRTaWduYXR1cmUobW9ja0RhdGEuY3VzdG9kaWFsSG90W2NvaW4ubmFtZV0uc2lnbmF0dXJlKTtcbiAgICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgY29uc3QgdHhIZXggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHhIZXgsIG1vY2tEYXRhLmN1c3RvZGlhbEhvdFtjb2luLm5hbWVdLnNpZ25lZFR4SGV4KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuZGVzY3JpYmUoJ0V0aExpa2VDb2luJywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgY29uc3QgY29pbk5hbWUgPSAndGJhc2VldGgnO1xuICBsZXQgYmFzZWNvaW46IFRldGhMaWtlQ29pbjtcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGJpdGdvS2V5WHBydiA9XG4gICAgICAneHBydjlzMjFaclFIMTQzSzN0cFdCSFdlMzFzTG9YTlJROUF2UllKZ2l0a0t4UTRBVEZRTXd2cjdoSE5xWVJVblM3UHNqekI3YUsxVnhxSEx1TlFqajFzY2tKMkp3bzJxeG1zdmVqd0VDU3BGTWZDJztcbiAgICBjb25zdCBiaXRnb0tleSA9IGJpcDMyLmZyb21CYXNlNTgoYml0Z29LZXlYcHJ2KTtcbiAgICBpZiAoIWJpdGdvS2V5LnByaXZhdGVLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbm8gcHJpdmF0ZUtleScpO1xuICAgIH1cbiAgICBjb25zdCBiaXRnb1hwdWIgPSBiaXRnb0tleS5uZXV0ZXJlZCgpLnRvQmFzZTU4KCk7XG4gICAgY29uc3QgZW52ID0gJ3Rlc3QnO1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudiB9KTtcbiAgICBjb21tb24uRW52aXJvbm1lbnRzW2Vudl0uaHNtWHB1YiA9IGJpdGdvWHB1YjtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ2Jhc2VldGgnLCBFdGhMaWtlQ29pbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0YmFzZWV0aCcsIFRldGhMaWtlQ29pbi5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0YmFzZWV0aCcpIGFzIFRldGhMaWtlQ29pbjtcbiAgfSk7XG5cbiAgYWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBpbnN0YW50aWF0ZSBhIGNvaW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGNvaW4gPSBiaXRnby5jb2luKCd0YmFzZWV0aCcpO1xuICAgIGNvaW4uc2hvdWxkLmJlLmFuLmluc3RhbmNlb2YoVGV0aExpa2VDb2luKTtcbiAgICBjb2luID0gYml0Z28uY29pbignYmFzZWV0aCcpO1xuICAgIGNvaW4uc2hvdWxkLmJlLmFuLmluc3RhbmNlb2YoRXRoTGlrZUNvaW4pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGJ1aWxkIHVuc2lnbmVkIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGV4cGlyZVRpbWUgPSBNYXRoLmZsb29yKG5ldyBEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCk7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcihjb2luTmFtZSwgYmFzZUNoYWluQ29tbW9uKSBhcyBFdGhMaWtlVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICB0eEJ1aWxkZXIuZmVlKHtcbiAgICAgIGZlZTogJzEwMDAwMDAwMDAnLFxuICAgICAgZ2FzTGltaXQ6ICcxMDAwMDAnLFxuICAgIH0pO1xuICAgIHR4QnVpbGRlci5jb3VudGVyKDEpO1xuICAgIHR4QnVpbGRlci5jb250cmFjdCgnMHgyYzJiOWM5YTRhMjVlMjRiMTc0ZjI2MTE0ZTg5MjZhOWYyMTI4ZmU0Jyk7XG5cbiAgICBjb25zdCB0cmFuc2ZlckJ1aWxkZXIgPSB0eEJ1aWxkZXIudHJhbnNmZXIoKTtcbiAgICB0cmFuc2ZlckJ1aWxkZXJcbiAgICAgIC5jb2luKGNvaW5OYW1lKVxuICAgICAgLmV4cGlyYXRpb25UaW1lKGV4cGlyZVRpbWUpXG4gICAgICAuYW1vdW50KCcxMDAwMDAwMDAwMDAwMDAwMDAwJylcbiAgICAgIC50bygnMHgyYzJiOWM5YTRhMjVlMjRiMTc0ZjI2MTE0ZTg5MjZhOWYyMTI4ZmU0JylcbiAgICAgIC5jb250cmFjdFNlcXVlbmNlSWQoMSk7XG5cbiAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgIHR4SnNvbi5nYXNMaW1pdC5zaG91bGQuZXF1YWwoJzEwMDAwMCcpO1xuICAgIHR4SnNvbi5nYXNQcmljZS5zaG91bGQuZXF1YWwoJzEwMDAwMDAwMDAnKTtcbiAgICB0eEpzb24uY2hhaW5JZC5zaG91bGQuZXF1YWwoJzB4MTRhMzQnKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBzaWduIGEgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgYWNjb3VudF8xID0ge1xuICAgICAgYWRkcmVzczogJzB4OENlNTljMmQxNzAyODQ0RjhFZEVENDUxQUExMDM5NjFiQzM3QjRlOCcsXG4gICAgICBvd25lcl8xOiAnNGVlMDg5YWNlYWJmM2RkYmY3NDhkYjc5YjEwNjZjMzNiN2QzZWExYWIzZWI3ZTMyNTEyMWJiYTJiZmYyZjVjYScsXG4gICAgICBvd25lcl8yOiAnNWM3ZTRlZmZmNzMwNGQ0ZGZmZjZkNWYxNTkxODQ0ZWM2ZjJhZGZhNmE0N2U5ZmVjZTZhM2MxYTRkNzU1ZjFlMycsXG4gICAgICBvd25lcl8zOiAnNDQyMWFiMjVkZDkxZTFhMzE4MGQwM2Q1N2MzMjNhNzg4NmRjYzMxM2QzYjNhNGI0MjU2YTU3OTE1NzJiZjU5NycsXG4gICAgfTtcbiAgICBjb25zdCBleHBpcmVUaW1lID0gTWF0aC5mbG9vcihuZXcgRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDApO1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoY29pbk5hbWUsIGJhc2VDaGFpbkNvbW1vbikgYXMgRXRoTGlrZVRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgdHhCdWlsZGVyLmZlZSh7XG4gICAgICBmZWU6ICcxMDAwMDAwMDAwJyxcbiAgICAgIGdhc0xpbWl0OiAnMTAwMDAwJyxcbiAgICB9KTtcbiAgICB0eEJ1aWxkZXIuY291bnRlcigxKTtcbiAgICB0eEJ1aWxkZXIuY29udHJhY3QoYWNjb3VudF8xLmFkZHJlc3MpO1xuXG4gICAgY29uc3QgdHJhbnNmZXJCdWlsZGVyID0gdHhCdWlsZGVyLnRyYW5zZmVyKCk7XG4gICAgdHJhbnNmZXJCdWlsZGVyXG4gICAgICAuY29pbihjb2luTmFtZSlcbiAgICAgIC5leHBpcmF0aW9uVGltZShleHBpcmVUaW1lKVxuICAgICAgLmFtb3VudCgnMTAwMDAwMDAwMDAwMDAwMDAwMCcpXG4gICAgICAudG8oJzB4MmMyYjljOWE0YTI1ZTI0YjE3NGYyNjExNGU4OTI2YTlmMjEyOGZlNCcpXG4gICAgICAuY29udHJhY3RTZXF1ZW5jZUlkKDEpO1xuXG4gICAgY29uc3QgdW5zaWduZWRUeCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIGNvbnN0IHVuc2lnbmVkVHhIZXggPSB1bnNpZ25lZFR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgY29uc3QgaGFsZlNpZ25lZFR4ID0gKGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgIHR4SGV4OiB1bnNpZ25lZFR4SGV4LFxuICAgICAgfSxcbiAgICAgIHBydjogYWNjb3VudF8xLm93bmVyXzEsXG4gICAgICBjb21tb246IGJhc2VDaGFpbkNvbW1vbixcbiAgICB9KSkgYXMgSGFsZlNpZ25lZFRyYW5zYWN0aW9uO1xuICAgIHRyYW5zZmVyQnVpbGRlci5rZXkoYWNjb3VudF8xLm93bmVyXzEpO1xuICAgIGNvbnN0IGhhbGZTaWduZWRUeEJ1aWxkZXIgPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICBjb25zdCBoYWxmU2lnbmVkVHhIZXhCdWlsZGVyID0gaGFsZlNpZ25lZFR4QnVpbGRlci50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgIGhhbGZTaWduZWRUeEhleEJ1aWxkZXIuc2hvdWxkLmVxdWFsKGhhbGZTaWduZWRUeC5oYWxmU2lnbmVkLnR4SGV4KTtcblxuICAgIC8vIFNpZ24gd2l0aCB0aGUgc2Vjb25kIGtleVxuXG4gICAgY29uc3QgZnVsbFNpZ25lZFR4biA9IChhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICBoYWxmU2lnbmVkOiB7XG4gICAgICAgICAgdHhIZXg6IGhhbGZTaWduZWRUeEhleEJ1aWxkZXIsXG4gICAgICAgICAgZXhwaXJlVGltZTogZXhwaXJlVGltZSxcbiAgICAgICAgICBjb250cmFjdFNlcXVlbmNlSWQ6IDEsXG4gICAgICAgICAgc2lnbmF0dXJlOiAnJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBwcnY6IGFjY291bnRfMS5vd25lcl8yLFxuICAgICAgY29tbW9uOiBiYXNlQ2hhaW5Db21tb24sXG4gICAgICBpc0xhc3RTaWduYXR1cmU6IHRydWUsXG4gICAgfSkpIGFzIEZ1bGx5U2lnbmVkVHJhbnNhY3Rpb247XG5cbiAgICBhc3NlcnQoZnVsbFNpZ25lZFR4bi50eEhleCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdleHBsYWluVHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgdHhIZXggPSBtb2NrRGF0YS5jY3JbY29pbk5hbWVdLnR4SGV4O1xuICAgIGNvbnN0IGZlZUluZm8gPSB7XG4gICAgICBmZWU6ICcxMDAwMDAwMDAwJyxcbiAgICAgIGdhc0xpbWl0OiAnMTAwMDAwJyxcbiAgICB9O1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIHRyYW5zYWN0aW9uIHdoZW4gY29tbW9uIGlzIHByb3ZpZGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFuYXRpb24gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleCxcbiAgICAgICAgZmVlSW5mbyxcbiAgICAgICAgY29tbW9uOiBiYXNlQ2hhaW5Db21tb24sXG4gICAgICB9KTtcblxuICAgICAgZXhwbGFuYXRpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lkJyk7XG4gICAgICBleHBsYW5hdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnb3V0cHV0cycpO1xuICAgICAgZXhwbGFuYXRpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ291dHB1dEFtb3VudCcpO1xuICAgICAgZXhwbGFuYXRpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NoYW5nZU91dHB1dHMnKTtcbiAgICAgIGV4cGxhbmF0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdjaGFuZ2VBbW91bnQnKTtcbiAgICAgIGV4cGxhbmF0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdmZWUnKTtcbiAgICAgIGV4cGxhbmF0aW9uLmZlZS5zaG91bGQuZXF1YWwoZmVlSW5mbyk7XG4gICAgICBleHBsYW5hdGlvbi5vdXRwdXRzLnNob3VsZC5iZS5hbi5BcnJheSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIGV4cGxhaW4gdHJhbnNhY3Rpb24gd2hlbiBjb21tb24gaXMgbm90IHByb3ZpZGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhIZXgsXG4gICAgICAgICAgZmVlSW5mbyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0NvbW1vbiBtdXN0IGJlIHByb3ZpZGVkIGZvciBFdGhMaWtlVHJhbnNhY3Rpb25CdWlsZGVyJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZWNvdmVyeScsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBiYXNlVXJsID0gJ2h0dHBzOi8vYXBpLXNlcG9saWEuYmFzZXNjYW4ub3JnLyc7XG4gICAgY29uc3QgdXNlclhwdWIgPVxuICAgICAgJ3hwdWI2NjFNeU13QXFSYmNFZVRjODc4OU1LNVBVR0VZaVBHNEY0VjE3bjJSZDJMb1RBVEExWG9DbkpUNUZBWUFTaFF4U3h0RmpwbzVOSG1jV3dUcDJMaVdHQk13cFVjQUEzSHl3aHhpdmdZZnE3cSc7XG4gICAgY29uc3QgYmFja3VwWHB1YiA9XG4gICAgICAneHB1YjY2MU15TXdBcVJiY0ZaWDE1eHBaZjRFUkNHSGlWU0ptOHI1QzR5aDF5WFYyR3JkWkNVUFlvNFdRcjZ0TjlvVXl3S1hzZ1NIbzdSaXNmOXIyMkdINWpvVkQyaEVFRWhxblNDdks4cXkxMXdXJztcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gdW5zaWduZWQgc3dlZXAgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgYmFja3VwS2V5QWRkcmVzcyA9ICcweDRmMmM0ODMwY2MzN2YyNzg1YzY0NmY4OWRlZDhhOTE5MjE5ZmEwZTknO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnR3aWNlKClcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldFR4TGlzdFJlcXVlc3QoYmFja3VwS2V5QWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldFR4TGlzdFJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdCh3YWxsZXRDb250cmFjdEFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KGJhY2t1cEtleUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuXG4gICAgICBub2NrKGJhc2VVcmwpLmdldCgnL2FwaScpLnF1ZXJ5KG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlcXVlc3QpLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVzcG9uc2UpO1xuXG4gICAgICBjb25zdCBiYXNlQ29pbiA9IGJpdGdvLmNvaW4oJ3RiYXNlZXRoJykgYXMgVGV0aExpa2VDb2luO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgYmFzZUNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IHVzZXJYcHViLFxuICAgICAgICBiYWNrdXBLZXk6IGJhY2t1cFhwdWIsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogd2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBUZXN0Qml0R28uVjIuVEVTVF9FUkMyMF9UT0tFTl9SRUNJUElFTlQgYXMgc3RyaW5nLFxuICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBjb21tb246IGJhc2VDaGFpbkNvbW1vbixcbiAgICAgIH0pKSBhcyBPZmZsaW5lVmF1bHRUeEluZm87XG4gICAgICBhc3NlcnQodHJhbnNhY3Rpb24udHhIZXgpO1xuICAgICAgYXNzZXJ0KHRyYW5zYWN0aW9uLmNvbnRyYWN0U2VxdWVuY2VJZCk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHJhbnNhY3Rpb24uZ2FzTGltaXQsICc1MDAwMDAnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0V2bSBCYXNlZCBDcm9zcyBDaGFpbiBSZWNvdmVyeSB0cmFuc2FjdGlvbjonLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgYmFzZVVybCA9ICdodHRwczovL2FwaS1zZXBvbGlhLmJhc2VzY2FuLm9yZy8nO1xuICAgIGNvbnN0IHVzZXJYcHViID1cbiAgICAgICd4cHViNjYxTXlNd0FxUmJjRWVUYzg3ODlNSzVQVUdFWWlQRzRGNFYxN24yUmQyTG9UQVRBMVhvQ25KVDVGQVlBU2hReFN4dEZqcG81TkhtY1d3VHAyTGlXR0JNd3BVY0FBM0h5d2h4aXZnWWZxN3EnO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhbiB1bnNpZ25lZCByZWNvdmVyeSB0eG4gZm9yIGNvbGQgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0Q29udHJhY3RBZGRyZXNzID0gVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTIGFzIHN0cmluZztcbiAgICAgIGNvbnN0IGJpdGdvRmVlQWRkcmVzcyA9ICcweDMzYTQyZmFlYTNjNmU4NzAyMTM0N2U1MTcwMGI0OGFhZjQ5YWExZTcnO1xuICAgICAgY29uc3QgZGVzdGluYXRpb25BZGRyZXNzID0gJzB4ZDVhZGRlMTdmZWQ4YmFlZDNmMzJiODRhZjA1YjhmMjgxNmY3YjU2MCc7XG4gICAgICBjb25zdCBiaXRnb0Rlc3RpbmF0aW9uQWRkcmVzcyA9ICcweEU1OTg2Q0U0NDkwRGViNjdkMjk1MDU2MkNlYjkzMERkZjliZTdhMTQnO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3RiYXNlZXRoJykgYXMgVGV0aExpa2VDb2luO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldFR4TGlzdFJlcXVlc3QoYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0VHhMaXN0UmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KGJpdGdvRmVlQWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3Qod2FsbGV0Q29udHJhY3RBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG5cbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gKGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB1c2VyWHB1YixcbiAgICAgICAgYmFja3VwS2V5OiAnJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiB3YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgIGJpdGdvRmVlQWRkcmVzczogYml0Z29GZWVBZGRyZXNzLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAwMDAwMDAwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwMDAwMDAwIH0sXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGJpdGdvRGVzdGluYXRpb25BZGRyZXNzOiBiaXRnb0Rlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgY29tbW9uOiBiYXNlQ2hhaW5Db21tb24sXG4gICAgICB9KSkgYXMgT2ZmbGluZVZhdWx0VHhJbmZvO1xuXG4gICAgICBhc3NlcnQodHJhbnNhY3Rpb24pO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4SGV4Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndXNlcktleScpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvaW4nKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdjb250cmFjdFNlcXVlbmNlSWQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdleHBpcmVUaW1lJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZ2FzTGltaXQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLmdhc0xpbWl0LnNob3VsZC5lcXVhbCgnNTAwMDAwJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaXNFdm1CYXNlZENyb3NzQ2hhaW5SZWNvdmVyeScpO1xuICAgICAgdHJhbnNhY3Rpb24uaXNFdm1CYXNlZENyb3NzQ2hhaW5SZWNvdmVyeT8uc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldENvbnRyYWN0QWRkcmVzcycpO1xuICAgICAgdHJhbnNhY3Rpb24ud2FsbGV0Q29udHJhY3RBZGRyZXNzLnNob3VsZC5lcXVhbChUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudHMnKTtcbiAgICAgIGNvbnN0IHJlY2lwaWVudCA9IHRyYW5zYWN0aW9uLnJlY2lwaWVudHNbMF07XG4gICAgICByZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FkZHJlc3MnKTtcbiAgICAgIHJlY2lwaWVudC5hZGRyZXNzLnNob3VsZC5lcXVhbChkZXN0aW5hdGlvbkFkZHJlc3MpO1xuICAgICAgcmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhbW91bnQnKTtcbiAgICAgIHJlY2lwaWVudC5hbW91bnQuc2hvdWxkLmVxdWFsKCc5OTk5OTk5OTk5OTk5OTk5OTI4Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGFuIHVuc2lnbmVkIHJlY292ZXJ5IHR4biBmb3IgY3VzdG9keSB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgYml0Z29GZWVBZGRyZXNzID0gJzB4MzNhNDJmYWVhM2M2ZTg3MDIxMzQ3ZTUxNzAwYjQ4YWFmNDlhYTFlNyc7XG4gICAgICBjb25zdCBkZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhkNWFkZGUxN2ZlZDhiYWVkM2YzMmI4NGFmMDViOGYyODE2ZjdiNTYwJztcbiAgICAgIGNvbnN0IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzID0gJzB4RTU5ODZDRTQ0OTBEZWI2N2QyOTUwNTYyQ2ViOTMwRGRmOWJlN2ExNCc7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndGJhc2VldGgnKSBhcyBUZXRoTGlrZUNvaW47XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VHhMaXN0UmVxdWVzdChiaXRnb0ZlZUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QoYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdCh3YWxsZXRDb250cmFjdEFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6ICcnLFxuICAgICAgICBiYWNrdXBLZXk6ICcnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgYml0Z29GZWVBZGRyZXNzOiBiaXRnb0ZlZUFkZHJlc3MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3M6IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICBjb21tb246IGJhc2VDaGFpbkNvbW1vbixcbiAgICAgIH0pKSBhcyBPZmZsaW5lVmF1bHRUeEluZm87XG5cbiAgICAgIGFzc2VydCh0cmFuc2FjdGlvbik7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhIZXgnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdjb2luJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29udHJhY3RTZXF1ZW5jZUlkJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZXhwaXJlVGltZScpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc0xpbWl0Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5nYXNMaW1pdC5zaG91bGQuZXF1YWwoJzUwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lzRXZtQmFzZWRDcm9zc0NoYWluUmVjb3ZlcnknKTtcbiAgICAgIHRyYW5zYWN0aW9uLmlzRXZtQmFzZWRDcm9zc0NoYWluUmVjb3Zlcnk/LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRDb250cmFjdEFkZHJlc3MnKTtcbiAgICAgIHRyYW5zYWN0aW9uLndhbGxldENvbnRyYWN0QWRkcmVzcy5zaG91bGQuZXF1YWwoVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNpcGllbnRzJyk7XG4gICAgICBjb25zdCByZWNpcGllbnQgPSB0cmFuc2FjdGlvbi5yZWNpcGllbnRzWzBdO1xuICAgICAgcmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhZGRyZXNzJyk7XG4gICAgICByZWNpcGllbnQuYWRkcmVzcy5zaG91bGQuZXF1YWwoZGVzdGluYXRpb25BZGRyZXNzKTtcbiAgICAgIHJlY2lwaWVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYW1vdW50Jyk7XG4gICAgICByZWNpcGllbnQuYW1vdW50LnNob3VsZC5lcXVhbCgnOTk5OTk5OTk5OTk5OTk5OTkyOCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhbiB1bnNpZ25lZCByZWNvdmVyeSB0eG4gZm9yIGhvdCB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB1c2VyS2V5ID1cbiAgICAgICAgJ3tcIml2XCI6XCJWRlozanZYaHhvMVorWWFmMk10Wm5BPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiXFxuJyArXG4gICAgICAgICc6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJwK2ZrSHVMYS84az1cIixcImN0XCI6XCJoWUc3cHZsakxJZ0NqWlxcbicgK1xuICAgICAgICAnNTNQQmxDZGU1S1pSbWxVS0tITHRETWsrSEpmdVU0NmhXK3grQzlXc0lBTzRnRlBuVEN2RlZtUTh4N2N6Q3RjTkZ1YjVBTzJvdE9HXFxuJyArXG4gICAgICAgICdPc1g0R0UyZ1hPRW1DbDFUcFd3d05obTd5TVVqR0pVcGdXNlpaZ1hTWGREaXRTS2k0Vi9oazc4U0dTempGT0JTUFlSYTZJPVwifVxcbic7XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgYml0Z29GZWVBZGRyZXNzID0gJzB4MzNhNDJmYWVhM2M2ZTg3MDIxMzQ3ZTUxNzAwYjQ4YWFmNDlhYTFlNyc7XG4gICAgICBjb25zdCBkZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhkNWFkZGUxN2ZlZDhiYWVkM2YzMmI4NGFmMDViOGYyODE2ZjdiNTYwJztcbiAgICAgIGNvbnN0IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzID0gJzB4RTU5ODZDRTQ0OTBEZWI2N2QyOTUwNTYyQ2ViOTMwRGRmOWJlN2ExNCc7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gVGVzdEJpdEdvLlYyLlRFU1RfUkVDT1ZFUllfUEFTU0NPREUgYXMgc3RyaW5nO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3RiYXNlZXRoJykgYXMgVGV0aExpa2VDb2luO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldFR4TGlzdFJlcXVlc3QoYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0VHhMaXN0UmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KGJpdGdvRmVlQWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3Qod2FsbGV0Q29udHJhY3RBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG5cbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gKGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB1c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6ICcnLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgYml0Z29GZWVBZGRyZXNzOiBiaXRnb0ZlZUFkZHJlc3MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3M6IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICBjb21tb246IGJhc2VDaGFpbkNvbW1vbixcbiAgICAgIH0pKSBhcyBPZmZsaW5lVmF1bHRUeEluZm87XG5cbiAgICAgIGFzc2VydCh0cmFuc2FjdGlvbik7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhIZXgnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdjb2luJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29udHJhY3RTZXF1ZW5jZUlkJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZXhwaXJlVGltZScpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc0xpbWl0Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5nYXNMaW1pdC5zaG91bGQuZXF1YWwoJzUwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lzRXZtQmFzZWRDcm9zc0NoYWluUmVjb3ZlcnknKTtcbiAgICAgIHRyYW5zYWN0aW9uLmlzRXZtQmFzZWRDcm9zc0NoYWluUmVjb3Zlcnk/LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRDb250cmFjdEFkZHJlc3MnKTtcbiAgICAgIHRyYW5zYWN0aW9uLndhbGxldENvbnRyYWN0QWRkcmVzcy5zaG91bGQuZXF1YWwoVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNpcGllbnRzJyk7XG4gICAgICBjb25zdCByZWNpcGllbnQgPSB0cmFuc2FjdGlvbi5yZWNpcGllbnRzWzBdO1xuICAgICAgcmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhZGRyZXNzJyk7XG4gICAgICByZWNpcGllbnQuYWRkcmVzcy5zaG91bGQuZXF1YWwoZGVzdGluYXRpb25BZGRyZXNzKTtcbiAgICAgIHJlY2lwaWVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYW1vdW50Jyk7XG4gICAgICByZWNpcGllbnQuYW1vdW50LnNob3VsZC5lcXVhbCgnOTk5OTk5OTk5OTk5OTk5OTkyOCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZXNVc2VkJyk7XG4gICAgICB0cmFuc2FjdGlvbi5mZWVzVXNlZD8uZ2FzTGltaXQuc2hvdWxkLmVxdWFsKCc1MDAwMDAnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdoYWxmU2lnbmVkJyk7XG4gICAgICB0cmFuc2FjdGlvbi5oYWxmU2lnbmVkPy5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhIZXgnKTtcbiAgICAgIHRyYW5zYWN0aW9uLmhhbGZTaWduZWQ/LnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNpcGllbnRzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGFuIHVuc2lnbmVkIHJlY292ZXJ5IHR4biBvZiBhIHRva2VuIGZvciBjb2xkIHdhbGxldCAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgYml0Z29GZWVBZGRyZXNzID0gJzB4MzNhNDJmYWVhM2M2ZTg3MDIxMzQ3ZTUxNzAwYjQ4YWFmNDlhYTFlNyc7XG4gICAgICBjb25zdCBkZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhkNWFkZGUxN2ZlZDhiYWVkM2YzMmI4NGFmMDViOGYyODE2ZjdiNTYwJztcbiAgICAgIGNvbnN0IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzID0gJzB4RTU5ODZDRTQ0OTBEZWI2N2QyOTUwNTYyQ2ViOTMwRGRmOWJlN2ExNCc7XG4gICAgICBjb25zdCB0b2tlbkNvbnRyYWN0QWRkcmVzcyA9ICcweDMyNmM5NzdlNmVmYzg0ZTUxMmJiOWMzMGY3NmUzMGMxNjBlZDA2ZmInO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3RiYXNlZXRoJykgYXMgVGV0aExpa2VDb2luO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldFR4TGlzdFJlcXVlc3QoYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0VHhMaXN0UmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KGJpdGdvRmVlQWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VG9rZW5CYWxhbmNlUmVxdWVzdCh0b2tlbkNvbnRyYWN0QWRkcmVzcywgd2FsbGV0Q29udHJhY3RBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG5cbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gKGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB1c2VyWHB1YixcbiAgICAgICAgYmFja3VwS2V5OiAnJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiB3YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgIGJpdGdvRmVlQWRkcmVzczogYml0Z29GZWVBZGRyZXNzLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAwMDAwMDAwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwMDAwMDAwIH0sXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGJpdGdvRGVzdGluYXRpb25BZGRyZXNzOiBiaXRnb0Rlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgdG9rZW5Db250cmFjdEFkZHJlc3M6IHRva2VuQ29udHJhY3RBZGRyZXNzLFxuICAgICAgICBjb21tb246IGJhc2VDaGFpbkNvbW1vbixcbiAgICAgIH0pKSBhcyBPZmZsaW5lVmF1bHRUeEluZm87XG5cbiAgICAgIGFzc2VydCh0cmFuc2FjdGlvbik7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhIZXgnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd1c2VyS2V5Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29pbicpO1xuICAgICAgdHJhbnNhY3Rpb24uY29pbi5zaG91bGQuZXF1YWwoJ3RiYXNlZXRoJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29udHJhY3RTZXF1ZW5jZUlkJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZXhwaXJlVGltZScpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc0xpbWl0Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5nYXNMaW1pdC5zaG91bGQuZXF1YWwoJzUwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lzRXZtQmFzZWRDcm9zc0NoYWluUmVjb3ZlcnknKTtcbiAgICAgIHRyYW5zYWN0aW9uLmlzRXZtQmFzZWRDcm9zc0NoYWluUmVjb3Zlcnk/LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRDb250cmFjdEFkZHJlc3MnKTtcbiAgICAgIHRyYW5zYWN0aW9uLndhbGxldENvbnRyYWN0QWRkcmVzcy5zaG91bGQuZXF1YWwoVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNpcGllbnRzJyk7XG4gICAgICBjb25zdCByZWNpcGllbnQgPSB0cmFuc2FjdGlvbi5yZWNpcGllbnRzWzBdO1xuICAgICAgcmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhZGRyZXNzJyk7XG4gICAgICByZWNpcGllbnQuYWRkcmVzcy5zaG91bGQuZXF1YWwoZGVzdGluYXRpb25BZGRyZXNzKTtcbiAgICAgIHJlY2lwaWVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYW1vdW50Jyk7XG4gICAgICByZWNpcGllbnQuYW1vdW50LnNob3VsZC5lcXVhbCgnOTk5OTk5OTk5OTk5OTk5OTkyOCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhbiB1bnNpZ25lZCByZWNvdmVyeSB0eG4gb2YgYSB0b2tlbiBmb3IgY3VzdG9keSB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgYml0Z29GZWVBZGRyZXNzID0gJzB4MzNhNDJmYWVhM2M2ZTg3MDIxMzQ3ZTUxNzAwYjQ4YWFmNDlhYTFlNyc7XG4gICAgICBjb25zdCBkZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhkNWFkZGUxN2ZlZDhiYWVkM2YzMmI4NGFmMDViOGYyODE2ZjdiNTYwJztcbiAgICAgIGNvbnN0IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzID0gJzB4RTU5ODZDRTQ0OTBEZWI2N2QyOTUwNTYyQ2ViOTMwRGRmOWJlN2ExNCc7XG4gICAgICBjb25zdCB0b2tlbkNvbnRyYWN0QWRkcmVzcyA9ICcweDMyNmM5NzdlNmVmYzg0ZTUxMmJiOWMzMGY3NmUzMGMxNjBlZDA2ZmInOyAvLyB1bnN1cHBvcnRlZCB0b2tlbiBjb250cmFjdCBhZGRyZXNzXG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndGJhc2VldGgnKSBhcyBUZXRoTGlrZUNvaW47XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VHhMaXN0UmVxdWVzdChiaXRnb0ZlZUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QoYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUb2tlbkJhbGFuY2VSZXF1ZXN0KHRva2VuQ29udHJhY3RBZGRyZXNzLCB3YWxsZXRDb250cmFjdEFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6ICcnLFxuICAgICAgICBiYWNrdXBLZXk6ICcnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgYml0Z29GZWVBZGRyZXNzOiBiaXRnb0ZlZUFkZHJlc3MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3M6IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICB0b2tlbkNvbnRyYWN0QWRkcmVzczogdG9rZW5Db250cmFjdEFkZHJlc3MsXG4gICAgICAgIGNvbW1vbjogYmFzZUNoYWluQ29tbW9uLFxuICAgICAgfSkpIGFzIE9mZmxpbmVWYXVsdFR4SW5mbztcblxuICAgICAgYXNzZXJ0KHRyYW5zYWN0aW9uKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvaW4nKTtcbiAgICAgIHRyYW5zYWN0aW9uLmNvaW4uc2hvdWxkLmVxdWFsKCd0YmFzZWV0aCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvbnRyYWN0U2VxdWVuY2VJZCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2V4cGlyZVRpbWUnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdnYXNMaW1pdCcpO1xuICAgICAgdHJhbnNhY3Rpb24uZ2FzTGltaXQuc2hvdWxkLmVxdWFsKCc1MDAwMDAnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdpc0V2bUJhc2VkQ3Jvc3NDaGFpblJlY292ZXJ5Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5pc0V2bUJhc2VkQ3Jvc3NDaGFpblJlY292ZXJ5Py5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0Q29udHJhY3RBZGRyZXNzJyk7XG4gICAgICB0cmFuc2FjdGlvbi53YWxsZXRDb250cmFjdEFkZHJlc3Muc2hvdWxkLmVxdWFsKFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVjaXBpZW50cycpO1xuICAgICAgY29uc3QgcmVjaXBpZW50ID0gdHJhbnNhY3Rpb24ucmVjaXBpZW50c1swXTtcbiAgICAgIHJlY2lwaWVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYWRkcmVzcycpO1xuICAgICAgcmVjaXBpZW50LmFkZHJlc3Muc2hvdWxkLmVxdWFsKGRlc3RpbmF0aW9uQWRkcmVzcyk7XG4gICAgICByZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Ftb3VudCcpO1xuICAgICAgcmVjaXBpZW50LmFtb3VudC5zaG91bGQuZXF1YWwoJzk5OTk5OTk5OTk5OTk5OTk5MjgnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gdW5zaWduZWQgcmVjb3ZlcnkgdHhuIG9mIGEgdG9rZW4gZm9yIGhvdCB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB1c2VyS2V5ID1cbiAgICAgICAgJ3tcIml2XCI6XCJWRlozanZYaHhvMVorWWFmMk10Wm5BPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiXFxuJyArXG4gICAgICAgICc6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJwK2ZrSHVMYS84az1cIixcImN0XCI6XCJoWUc3cHZsakxJZ0NqWlxcbicgK1xuICAgICAgICAnNTNQQmxDZGU1S1pSbWxVS0tITHRETWsrSEpmdVU0NmhXK3grQzlXc0lBTzRnRlBuVEN2RlZtUTh4N2N6Q3RjTkZ1YjVBTzJvdE9HXFxuJyArXG4gICAgICAgICdPc1g0R0UyZ1hPRW1DbDFUcFd3d05obTd5TVVqR0pVcGdXNlpaZ1hTWGREaXRTS2k0Vi9oazc4U0dTempGT0JTUFlSYTZJPVwifVxcbic7XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgYml0Z29GZWVBZGRyZXNzID0gJzB4MzNhNDJmYWVhM2M2ZTg3MDIxMzQ3ZTUxNzAwYjQ4YWFmNDlhYTFlNyc7XG4gICAgICBjb25zdCBkZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhkNWFkZGUxN2ZlZDhiYWVkM2YzMmI4NGFmMDViOGYyODE2ZjdiNTYwJztcbiAgICAgIGNvbnN0IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzID0gJzB4RTU5ODZDRTQ0OTBEZWI2N2QyOTUwNTYyQ2ViOTMwRGRmOWJlN2ExNCc7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gVGVzdEJpdEdvLlYyLlRFU1RfUkVDT1ZFUllfUEFTU0NPREUgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgdG9rZW5Db250cmFjdEFkZHJlc3MgPSAnMHgzMjZjOTc3ZTZlZmM4NGU1MTJiYjljMzBmNzZlMzBjMTYwZWQwNmZiJzsgLy8gdW5zdXBwb3J0ZWQgY29udHJhY3QgdG9rZW4gYWRkcmVzc1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3RiYXNlZXRoJykgYXMgVGV0aExpa2VDb2luO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldFR4TGlzdFJlcXVlc3QoYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0VHhMaXN0UmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KGJpdGdvRmVlQWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VG9rZW5CYWxhbmNlUmVxdWVzdCh0b2tlbkNvbnRyYWN0QWRkcmVzcywgd2FsbGV0Q29udHJhY3RBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG5cbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gKGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB1c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6ICcnLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgYml0Z29GZWVBZGRyZXNzOiBiaXRnb0ZlZUFkZHJlc3MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3M6IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICB0b2tlbkNvbnRyYWN0QWRkcmVzczogdG9rZW5Db250cmFjdEFkZHJlc3MsXG4gICAgICAgIGNvbW1vbjogYmFzZUNoYWluQ29tbW9uLFxuICAgICAgfSkpIGFzIE9mZmxpbmVWYXVsdFR4SW5mbztcblxuICAgICAgYXNzZXJ0KHRyYW5zYWN0aW9uKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvaW4nKTtcbiAgICAgIHRyYW5zYWN0aW9uLmNvaW4uc2hvdWxkLmVxdWFsKCd0YmFzZWV0aCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvbnRyYWN0U2VxdWVuY2VJZCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2V4cGlyZVRpbWUnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdnYXNMaW1pdCcpO1xuICAgICAgdHJhbnNhY3Rpb24uZ2FzTGltaXQuc2hvdWxkLmVxdWFsKCc1MDAwMDAnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdpc0V2bUJhc2VkQ3Jvc3NDaGFpblJlY292ZXJ5Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5pc0V2bUJhc2VkQ3Jvc3NDaGFpblJlY292ZXJ5Py5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0Q29udHJhY3RBZGRyZXNzJyk7XG4gICAgICB0cmFuc2FjdGlvbi53YWxsZXRDb250cmFjdEFkZHJlc3Muc2hvdWxkLmVxdWFsKFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVjaXBpZW50cycpO1xuICAgICAgY29uc3QgcmVjaXBpZW50ID0gdHJhbnNhY3Rpb24ucmVjaXBpZW50c1swXTtcbiAgICAgIHJlY2lwaWVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYWRkcmVzcycpO1xuICAgICAgcmVjaXBpZW50LmFkZHJlc3Muc2hvdWxkLmVxdWFsKGRlc3RpbmF0aW9uQWRkcmVzcyk7XG4gICAgICByZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Ftb3VudCcpO1xuICAgICAgcmVjaXBpZW50LmFtb3VudC5zaG91bGQuZXF1YWwoJzk5OTk5OTk5OTk5OTk5OTk5MjgnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdmZWVzVXNlZCcpO1xuICAgICAgdHJhbnNhY3Rpb24uZmVlc1VzZWQ/Lmdhc0xpbWl0LnNob3VsZC5lcXVhbCgnNTAwMDAwJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaGFsZlNpZ25lZCcpO1xuICAgICAgdHJhbnNhY3Rpb24uaGFsZlNpZ25lZD8uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4SGV4Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5oYWxmU2lnbmVkPy5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVjaXBpZW50cycpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQ29tbW9uIHBhcmFtZXRlciBoYW5kbGluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBwbGFpbiBvYmplY3QgY29tbW9uIHBhcmFtZXRlciBmb3IgQkFTRSBjaGFpbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJhc2VDb2luID0gYml0Z28uY29pbignYmFzZWV0aCcpIGFzIEV0aExpa2VDb2luO1xuXG4gICAgICBjb25zdCBwbGFpbkNvbW1vbiA9IHsgY2hhaW46IDg0NTMsIGhhcmRmb3JrOiAnbG9uZG9uJyB9O1xuXG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSAoYmFzZUNvaW4gYXMgYW55KS5nZXRUcmFuc2FjdGlvbkJ1aWxkZXIocGxhaW5Db21tb24pO1xuICAgICAgdHhCdWlsZGVyLnNob3VsZC5iZS5hbi5pbnN0YW5jZW9mKEV0aExpa2VUcmFuc2FjdGlvbkJ1aWxkZXIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgcGxhaW4gb2JqZWN0IGNvbW1vbiBwYXJhbWV0ZXIgd2l0aCBjaGFpbklkIHByb3BlcnR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmFzZUNvaW4gPSBiaXRnby5jb2luKCdiYXNlZXRoJykgYXMgRXRoTGlrZUNvaW47XG5cbiAgICAgIGNvbnN0IHBsYWluQ29tbW9uID0geyBjaGFpbklkOiA4NDUzLCBoYXJkZm9yazogJ2xvbmRvbicgfTtcblxuICAgICAgY29uc3QgdHhCdWlsZGVyID0gKGJhc2VDb2luIGFzIGFueSkuZ2V0VHJhbnNhY3Rpb25CdWlsZGVyKHBsYWluQ29tbW9uKTtcbiAgICAgIHR4QnVpbGRlci5zaG91bGQuYmUuYW4uaW5zdGFuY2VvZihFdGhMaWtlVHJhbnNhY3Rpb25CdWlsZGVyKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIEV0aGVyZXVtQ29tbW9uIGluc3RhbmNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmFzZUNvaW4gPSBiaXRnby5jb2luKCdiYXNlZXRoJykgYXMgRXRoTGlrZUNvaW47XG5cbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IChiYXNlQ29pbiBhcyBhbnkpLmdldFRyYW5zYWN0aW9uQnVpbGRlcihiYXNlQ2hhaW5Db21tb24pO1xuICAgICAgdHhCdWlsZGVyLnNob3VsZC5iZS5hbi5pbnN0YW5jZW9mKEV0aExpa2VUcmFuc2FjdGlvbkJ1aWxkZXIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXF1aXJlIGNvbW1vbiBwYXJhbWV0ZXIgYW5kIHRocm93IGVycm9yIHdoZW4gdW5kZWZpbmVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmFzZUNvaW4gPSBiaXRnby5jb2luKCdiYXNlZXRoJykgYXMgRXRoTGlrZUNvaW47XG5cbiAgICAgICgoKSA9PiB7XG4gICAgICAgIChiYXNlQ29pbiBhcyBhbnkpLmdldFRyYW5zYWN0aW9uQnVpbGRlcih1bmRlZmluZWQpO1xuICAgICAgfSkuc2hvdWxkLnRocm93KCdDb21tb24gbXVzdCBiZSBwcm92aWRlZCBmb3IgRXRoTGlrZVRyYW5zYWN0aW9uQnVpbGRlcicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb252ZXJ0IHBsYWluIG9iamVjdCBjb21tb24gdG8gRXRoZXJldW1Db21tb24gd2l0aCB3b3JraW5nIGd0ZUhhcmRmb3JrIG1ldGhvZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJhc2VDb2luID0gYml0Z28uY29pbignYmFzZWV0aCcpIGFzIEV0aExpa2VDb2luO1xuXG4gICAgICBjb25zdCBwbGFpbkNvbW1vbiA9IHsgY2hhaW46IDg0NTMsIGhhcmRmb3JrOiAnbG9uZG9uJyB9O1xuXG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSAoYmFzZUNvaW4gYXMgYW55KS5nZXRUcmFuc2FjdGlvbkJ1aWxkZXIocGxhaW5Db21tb24pO1xuICAgICAgdHhCdWlsZGVyLnNob3VsZC5iZS5hbi5pbnN0YW5jZW9mKEV0aExpa2VUcmFuc2FjdGlvbkJ1aWxkZXIpO1xuXG4gICAgICBjb25zdCBjb21tb24gPSAodHhCdWlsZGVyIGFzIGFueSkuX2NvbW1vbjtcbiAgICAgIGNvbW1vbi5zaG91bGQubm90LmJlLnVuZGVmaW5lZDtcblxuICAgICAgY29tbW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdndGVIYXJkZm9yaycpO1xuICAgICAgKHR5cGVvZiBjb21tb24uZ3RlSGFyZGZvcmspLnNob3VsZC5lcXVhbCgnZnVuY3Rpb24nKTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gY29tbW9uLmd0ZUhhcmRmb3JrKCdob21lc3RlYWQnKTtcbiAgICAgICh0eXBlb2YgcmVzdWx0KS5zaG91bGQuZXF1YWwoJ2Jvb2xlYW4nKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
|