@bitgo/sdk-coin-dot 4.5.2 → 4.5.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.d.ts +283 -0
- package/dist/test/fixtures.d.ts.map +1 -0
- package/dist/test/fixtures.js +439 -0
- package/dist/test/resources/assetHubMaterialData.json +8 -0
- package/dist/test/resources/index.d.ts +141 -0
- package/dist/test/resources/index.d.ts.map +1 -0
- package/dist/test/resources/index.js +157 -0
- package/dist/test/resources/materialData.json +8 -0
- package/dist/test/resources/materialDataModified.json +8 -0
- package/dist/test/resources/testnet.d.ts +2 -0
- package/dist/test/resources/testnet.d.ts.map +1 -0
- package/dist/test/resources/testnet.js +5 -0
- package/dist/test/unit/address.d.ts +2 -0
- package/dist/test/unit/address.d.ts.map +1 -0
- package/dist/test/unit/address.js +45 -0
- package/dist/test/unit/dot.d.ts +2 -0
- package/dist/test/unit/dot.d.ts.map +1 -0
- package/dist/test/unit/dot.js +637 -0
- package/dist/test/unit/keypair.d.ts +2 -0
- package/dist/test/unit/keypair.d.ts.map +1 -0
- package/dist/test/unit/keypair.js +111 -0
- package/dist/test/unit/transaction.d.ts +2 -0
- package/dist/test/unit/transaction.d.ts.map +1 -0
- package/dist/test/unit/transaction.js +269 -0
- package/dist/test/unit/transactionBuilder/addressInitializationBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/addressInitializationBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/addressInitializationBuilder.js +265 -0
- package/dist/test/unit/transactionBuilder/base.d.ts +8 -0
- package/dist/test/unit/transactionBuilder/base.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/base.js +233 -0
- package/dist/test/unit/transactionBuilder/batchTransactionBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/batchTransactionBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/batchTransactionBuilder.js +521 -0
- package/dist/test/unit/transactionBuilder/claimBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/claimBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/claimBuilder.js +129 -0
- package/dist/test/unit/transactionBuilder/proxyBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/proxyBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/proxyBuilder.js +88 -0
- package/dist/test/unit/transactionBuilder/singeltonRegistry.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/singeltonRegistry.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/singeltonRegistry.js +59 -0
- package/dist/test/unit/transactionBuilder/stakingBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/stakingBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/stakingBuilder.js +235 -0
- package/dist/test/unit/transactionBuilder/transactionBuilderFactory.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/transactionBuilderFactory.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/transactionBuilderFactory.js +107 -0
- package/dist/test/unit/transactionBuilder/transferBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/transferBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/transferBuilder.js +437 -0
- package/dist/test/unit/transactionBuilder/unnominateBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/unnominateBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/unnominateBuilder.js +97 -0
- package/dist/test/unit/transactionBuilder/unstakeBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/unstakeBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/unstakeBuilder.js +116 -0
- package/dist/test/unit/transactionBuilder/withdrawUnstakedBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/withdrawUnstakedBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/withdrawUnstakedBuilder.js +115 -0
- package/dist/test/unit/utils.d.ts +2 -0
- package/dist/test/unit/utils.d.ts.map +1 -0
- package/dist/test/unit/utils.js +117 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +11 -8
- package/.eslintignore +0 -5
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -1416
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const sdk_api_1 = require("@bitgo/sdk-api");
|
|
37
|
+
const sdk_test_1 = require("@bitgo/sdk-test");
|
|
38
|
+
const crypto_1 = require("crypto");
|
|
39
|
+
const should = require("should");
|
|
40
|
+
const src_1 = require("../../src");
|
|
41
|
+
const testData = __importStar(require("../fixtures"));
|
|
42
|
+
const resources_1 = require("../resources");
|
|
43
|
+
const sinon = __importStar(require("sinon"));
|
|
44
|
+
const sdk_core_1 = require("@bitgo/sdk-core");
|
|
45
|
+
describe('DOT:', function () {
|
|
46
|
+
let bitgo;
|
|
47
|
+
let basecoin;
|
|
48
|
+
let prodCoin;
|
|
49
|
+
before(function () {
|
|
50
|
+
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
|
|
51
|
+
bitgo.safeRegister('dot', src_1.Dot.createInstance);
|
|
52
|
+
bitgo.safeRegister('tdot', src_1.Tdot.createInstance);
|
|
53
|
+
bitgo.initializeTestVars();
|
|
54
|
+
basecoin = bitgo.coin('tdot');
|
|
55
|
+
prodCoin = bitgo.coin('dot');
|
|
56
|
+
});
|
|
57
|
+
describe('Sign Message', () => {
|
|
58
|
+
it('should be performed', async () => {
|
|
59
|
+
const keyPair = new src_1.KeyPair();
|
|
60
|
+
const messageToSign = Buffer.from((0, crypto_1.randomBytes)(32)).toString('hex');
|
|
61
|
+
const signature = await basecoin.signMessage(keyPair.getKeys(), messageToSign);
|
|
62
|
+
keyPair.verifySignature(messageToSign, Uint8Array.from(signature)).should.equals(true);
|
|
63
|
+
});
|
|
64
|
+
it('should fail with missing private key', async () => {
|
|
65
|
+
const keyPair = new src_1.KeyPair({
|
|
66
|
+
pub: '7788327c695dca4b3e649a0db45bc3e703a2c67428fce360e61800cc4248f4f7',
|
|
67
|
+
}).getKeys();
|
|
68
|
+
const messageToSign = Buffer.from((0, crypto_1.randomBytes)(32)).toString('hex');
|
|
69
|
+
await basecoin.signMessage(keyPair, messageToSign).should.be.rejectedWith('Invalid key pair options');
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe('Sign transaction', () => {
|
|
73
|
+
const transaction = {
|
|
74
|
+
id: '0x19de156328eea66bd1ec45843569c168e0bb2f2898221029b403df3f23a5489d',
|
|
75
|
+
sender: '5EGoFA95omzemRssELLDjVenNZ68aXyUeqtKQScXSEBvVJkr',
|
|
76
|
+
referenceBlock: '0x149799bc9602cb5cf201f3425fb8d253b2d4e61fc119dcab3249f307f594754d',
|
|
77
|
+
blockNumber: 3933,
|
|
78
|
+
genesisHash: '0x67f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9',
|
|
79
|
+
nonce: 200,
|
|
80
|
+
specVersion: 1018013,
|
|
81
|
+
transactionVersion: 16,
|
|
82
|
+
eraPeriod: 64,
|
|
83
|
+
chainName: 'Westend Asset Hub',
|
|
84
|
+
tip: 0,
|
|
85
|
+
to: '5Ffp1wJCPu4hzVDTo7XaMLqZSvSadyUQmxWPDw74CBjECSoq',
|
|
86
|
+
amount: '10000000000',
|
|
87
|
+
};
|
|
88
|
+
// TODO: BG-43197
|
|
89
|
+
xit('should sign transaction', async function () {
|
|
90
|
+
const signed = await basecoin.signTransaction({
|
|
91
|
+
txPrebuild: {
|
|
92
|
+
txHex: testData.rawTx.transfer.unsigned,
|
|
93
|
+
transaction,
|
|
94
|
+
},
|
|
95
|
+
pubs: [testData.accounts.account1.publicKey],
|
|
96
|
+
prv: testData.accounts.account1.secretKey,
|
|
97
|
+
});
|
|
98
|
+
signed.txHex.should.equal(testData.rawTx.transfer.signed);
|
|
99
|
+
});
|
|
100
|
+
// TODO: BG-43197
|
|
101
|
+
xit('should fail to sign transaction with an invalid key', async function () {
|
|
102
|
+
try {
|
|
103
|
+
await basecoin.signTransaction({
|
|
104
|
+
txPrebuild: {
|
|
105
|
+
txHex: testData.rawTx.transfer.unsigned,
|
|
106
|
+
transaction,
|
|
107
|
+
},
|
|
108
|
+
pubs: [testData.accounts.account2.publicKey],
|
|
109
|
+
prv: testData.accounts.account1.secretKey,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
should.equal(e.message, 'Private key cannot sign the transaction');
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
it('should fail to build transaction with missing params', async function () {
|
|
117
|
+
try {
|
|
118
|
+
await basecoin.signTransaction({
|
|
119
|
+
txPrebuild: {
|
|
120
|
+
txHex: testData.rawTx.transfer.unsigned,
|
|
121
|
+
key: testData.accounts.account1.publicKey,
|
|
122
|
+
},
|
|
123
|
+
prv: testData.accounts.account1.secretKey,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
catch (e) {
|
|
127
|
+
should.notEqual(e, null);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
describe('Generate wallet key pair: ', () => {
|
|
132
|
+
it('should generate key pair', () => {
|
|
133
|
+
const kp = basecoin.generateKeyPair();
|
|
134
|
+
basecoin.isValidPub(kp.pub).should.equal(true);
|
|
135
|
+
basecoin.isValidPrv(kp.prv).should.equal(true);
|
|
136
|
+
});
|
|
137
|
+
it('should generate key pair from seed', () => {
|
|
138
|
+
const seed = Buffer.from('9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60', 'hex');
|
|
139
|
+
const kp = basecoin.generateKeyPair(seed);
|
|
140
|
+
basecoin.isValidPub(kp.pub).should.equal(true);
|
|
141
|
+
basecoin.isValidPrv(kp.prv).should.equal(true);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
describe('Balance Conversion', () => {
|
|
145
|
+
it('should return 10000000000 as tdot base factor', () => {
|
|
146
|
+
// mainnet uses 10 decimal places
|
|
147
|
+
const baseFactor = prodCoin.getBaseFactor();
|
|
148
|
+
baseFactor.should.equal(10000000000);
|
|
149
|
+
});
|
|
150
|
+
it('should return 1000000000000 as dot base factor', () => {
|
|
151
|
+
// westend (test polkadot) uses 12 decimal places
|
|
152
|
+
const baseFactor = basecoin.getBaseFactor();
|
|
153
|
+
baseFactor.should.equal(1000000000000);
|
|
154
|
+
});
|
|
155
|
+
it('should return 4 Dot when base unit is 40000000000 for dot', () => {
|
|
156
|
+
const bigUnit = prodCoin.baseUnitsToBigUnits('40000000000');
|
|
157
|
+
bigUnit.should.equal('4');
|
|
158
|
+
});
|
|
159
|
+
it('should return 0.04 Dot when base unit is 400000000 for dot', () => {
|
|
160
|
+
const bigUnit = prodCoin.baseUnitsToBigUnits('400000000');
|
|
161
|
+
bigUnit.should.equal('0.04');
|
|
162
|
+
});
|
|
163
|
+
it('should return 4 test Dot when base unit is 4000000000000 for tdot', () => {
|
|
164
|
+
const bigUnit = basecoin.baseUnitsToBigUnits('4000000000000');
|
|
165
|
+
bigUnit.should.equal('4');
|
|
166
|
+
});
|
|
167
|
+
it('should return 0.04 test Dot when base unit is 400000000 for tdot', () => {
|
|
168
|
+
const bigUnit = basecoin.baseUnitsToBigUnits('40000000000');
|
|
169
|
+
bigUnit.should.equal('0.04');
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
describe('Explain Transactions:', () => {
|
|
173
|
+
it('should explain an unsigned transfer transaction', async function () {
|
|
174
|
+
const explainedTransaction = await basecoin.explainTransaction(testData.unsignedTransaction);
|
|
175
|
+
explainedTransaction.should.deepEqual({
|
|
176
|
+
displayOrder: [
|
|
177
|
+
'outputAmount',
|
|
178
|
+
'changeAmount',
|
|
179
|
+
'outputs',
|
|
180
|
+
'changeOutputs',
|
|
181
|
+
'fee',
|
|
182
|
+
'type',
|
|
183
|
+
'sequenceId',
|
|
184
|
+
'id',
|
|
185
|
+
'blockNumber',
|
|
186
|
+
],
|
|
187
|
+
sequenceId: 0,
|
|
188
|
+
fee: '10',
|
|
189
|
+
id: '0x0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8',
|
|
190
|
+
type: '0',
|
|
191
|
+
outputs: [
|
|
192
|
+
{
|
|
193
|
+
address: '5DkddSfPsWojjfuH9iJEcUV7ZseQ9EJ6RjtNmCR1w3CEb8S9',
|
|
194
|
+
valueString: '90034235235350',
|
|
195
|
+
coinName: 'tdot',
|
|
196
|
+
wallet: '62a1205751675b2f0fe72328',
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
blockNumber: 8619307,
|
|
200
|
+
outputAmount: 90034235235350,
|
|
201
|
+
changeOutputs: [],
|
|
202
|
+
changeAmount: '0',
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
describe('Recover Transactions:', () => {
|
|
207
|
+
const sandBox = sinon.createSandbox();
|
|
208
|
+
const destAddr = testData.accounts.account1.address;
|
|
209
|
+
const nonce = 123;
|
|
210
|
+
beforeEach(function () {
|
|
211
|
+
const accountInfoCB = sandBox.stub(src_1.Dot.prototype, 'getAccountInfo');
|
|
212
|
+
accountInfoCB.withArgs(testData.wrwUser.walletAddress0).resolves({
|
|
213
|
+
nonce: nonce,
|
|
214
|
+
freeBalance: 8888,
|
|
215
|
+
});
|
|
216
|
+
const headerInfoCB = sandBox.stub(src_1.Dot.prototype, 'getHeaderInfo');
|
|
217
|
+
headerInfoCB.resolves({
|
|
218
|
+
headerNumber: testData.westendBlock.blockNumber,
|
|
219
|
+
headerHash: testData.westendBlock.hash,
|
|
220
|
+
});
|
|
221
|
+
accountInfoCB.withArgs('5Dtg2zKjVEL8p9keSM4dQ7nD26sVtMfCsyxkhvZZ9fqBbhw6').resolves({
|
|
222
|
+
nonce: 0,
|
|
223
|
+
freeBalance: 1510000000000,
|
|
224
|
+
});
|
|
225
|
+
const getFeeCB = sandBox.stub(src_1.Dot.prototype, 'getFee');
|
|
226
|
+
getFeeCB.withArgs(destAddr, testData.wrwUser.walletAddress0, 1510000000000).resolves(15783812856);
|
|
227
|
+
});
|
|
228
|
+
afterEach(function () {
|
|
229
|
+
sandBox.restore();
|
|
230
|
+
});
|
|
231
|
+
it('should generate unsigned sweep correctly', async function () {
|
|
232
|
+
const commonKeychain = '3cd14f5d60744287cd3a50510e2964746b6feaad4b2300088eaae60d1a35f0abc518534d43b2614370d9a263aadb57edb5d0b78f816a519cd5896e7352920b67';
|
|
233
|
+
const recoveryDestination = '5GPAveMvmDsjxVT6Q2xiu5kYPbFAmdebHaiNZK14FBaSaAKh';
|
|
234
|
+
const unsigned = await basecoin.recover({ bitgoKey: commonKeychain, recoveryDestination });
|
|
235
|
+
unsigned.txRequests.should.not.be.undefined();
|
|
236
|
+
unsigned.txRequests.length.should.equal(1);
|
|
237
|
+
unsigned.txRequests[0].transactions.length.should.equal(1);
|
|
238
|
+
unsigned.txRequests[0].walletCoin.should.equal('tdot');
|
|
239
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.should.not.be.undefined();
|
|
240
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.serializedTx.should.not.be.undefined();
|
|
241
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.scanIndex.should.equal(0);
|
|
242
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.coin.should.equal('tdot');
|
|
243
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.signableHex.should.not.be.undefined();
|
|
244
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.derivationPath.should.equal('m/0');
|
|
245
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.should.not.be.undefined();
|
|
246
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.inputs.should.not.be.undefined();
|
|
247
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.inputs.length.should.equal(1);
|
|
248
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.inputs[0].address.should.equal('5Dtg2zKjVEL8p9keSM4dQ7nD26sVtMfCsyxkhvZZ9fqBbhw6');
|
|
249
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.inputs[0].valueString.should.equal('1510000000000');
|
|
250
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.inputs[0].value.should.equal(1510000000000);
|
|
251
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.outputs.should.not.be.undefined();
|
|
252
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.outputs.length.should.equal(1);
|
|
253
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.outputs[0].address.should.equal('5GPAveMvmDsjxVT6Q2xiu5kYPbFAmdebHaiNZK14FBaSaAKh');
|
|
254
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.outputs[0].valueString.should.equal('1510000000000');
|
|
255
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.outputs[0].coinName.should.equal('tdot');
|
|
256
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.parsedTx.type.should.equal('');
|
|
257
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.feeInfo.should.not.be.undefined();
|
|
258
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.feeInfo.fee.should.equal(0);
|
|
259
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.feeInfo.feeString.should.equal('0');
|
|
260
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.coinSpecific.should.not.be.undefined();
|
|
261
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.coinSpecific.firstValid.should.not.be.undefined();
|
|
262
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.coinSpecific.maxDuration.should.equal(2400);
|
|
263
|
+
unsigned.txRequests[0].transactions[0].unsignedTx.coinSpecific.commonKeychain.should.equal('3cd14f5d60744287cd3a50510e2964746b6feaad4b2300088eaae60d1a35f0abc518534d43b2614370d9a263aadb57edb5d0b78f816a519cd5896e7352920b67');
|
|
264
|
+
});
|
|
265
|
+
// TODO(COIN-919): Fix failing test
|
|
266
|
+
xit('should take OVC output and generate a signed sweep transaction', async function () {
|
|
267
|
+
const params = testData.ovcResponse;
|
|
268
|
+
const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
|
|
269
|
+
recoveryTxn.transactions[0].serializedTx.should.equal('0x2d02840050d1e116cdb32e61ba3ece275b620f503f0c5ae4e7690d9f9aa7e0b50303976c00057c131cde2be39f4ff23eeba11139c46dd8c6d69ff517abede37381d8d24f0bb30fd8805b2e51a9e2a75338d7fb7edb290be9638debedbfc001d10b8132be0b2b4a0400040400bf0678d312b2b2c7effd2b1f214ee13928d339391d5f5f7056608aa0d32b9edf01');
|
|
270
|
+
recoveryTxn.transactions[0].scanIndex.should.equal(0);
|
|
271
|
+
recoveryTxn.lastScanIndex.should.equal(0);
|
|
272
|
+
});
|
|
273
|
+
// TODO(COIN-919): Fix failing test
|
|
274
|
+
xit('should take consolidation OVC output and generate multiple signed sweep transactions', async function () {
|
|
275
|
+
const params = testData.ovcResponse2;
|
|
276
|
+
const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
|
|
277
|
+
recoveryTxn.transactions[0].serializedTx.should.equal('0x2d028400f053d177371f4919b71017421aa34841ac87c926a14e8a7e75f092693665cb4a009871feb8389e12191b460ebea1f9e1716ada8a31d94ac08f5c15cb5f7be24683cdfc300ae3e6802c6f4b044dd92ea03d15b92399ab45803e43beb5cbff582a031b37000004040050d1e116cdb32e61ba3ece275b620f503f0c5ae4e7690d9f9aa7e0b50303976c01');
|
|
278
|
+
recoveryTxn.transactions[0].scanIndex.should.equal(1);
|
|
279
|
+
recoveryTxn.transactions[1].serializedTx.should.equal('0x2d028400cf7ed9f536373c8f874e780a4269ec1bd6799ed7d4a854c670b0c72805fac87600d153cbb683706ddf320f7b225af14ce4b59b868c07440aefa4c4e1297e49bcd5f6ee84f696b0c2e456e2a7f8779a78a2c832dfb47d5b283eba8408b003c7dd031b37000004040050d1e116cdb32e61ba3ece275b620f503f0c5ae4e7690d9f9aa7e0b50303976c01');
|
|
280
|
+
recoveryTxn.transactions[1].scanIndex.should.equal(2);
|
|
281
|
+
recoveryTxn.transactions[2].serializedTx.should.equal('0x2d0284009482ad7e43b40b7df3383244daafed32b3b9fd7541016b5c907f2d9052f85f8600e255698d110977faf33efb3336ba98ad7eaa2a1a926487fc696a277442d4414b2a441ba92d598f2b1f96f13b28785f5e572984035a608d63c48bd35ba955090e1b37000004040050d1e116cdb32e61ba3ece275b620f503f0c5ae4e7690d9f9aa7e0b50303976c01');
|
|
282
|
+
recoveryTxn.transactions[2].scanIndex.should.equal(3);
|
|
283
|
+
recoveryTxn.lastScanIndex.should.equal(20);
|
|
284
|
+
});
|
|
285
|
+
// TODO(COIN-919): Fix failing test
|
|
286
|
+
xit('should recover a txn for non-bitgo recoveries', async function () {
|
|
287
|
+
const res = await basecoin.recover({
|
|
288
|
+
userKey: testData.wrwUser.userKey,
|
|
289
|
+
backupKey: testData.wrwUser.backupKey,
|
|
290
|
+
bitgoKey: testData.wrwUser.bitgoKey,
|
|
291
|
+
walletPassphrase: testData.wrwUser.walletPassphrase,
|
|
292
|
+
recoveryDestination: destAddr,
|
|
293
|
+
});
|
|
294
|
+
res.should.not.be.empty();
|
|
295
|
+
res.should.hasOwnProperty('serializedTx');
|
|
296
|
+
res.should.hasOwnProperty('scanIndex');
|
|
297
|
+
sandBox.assert.calledOnce(basecoin.getAccountInfo);
|
|
298
|
+
sandBox.assert.calledOnce(basecoin.getHeaderInfo);
|
|
299
|
+
// deserialize the txn and verify the fields are what we expect
|
|
300
|
+
const txBuilder = basecoin.getBuilder().from(res.serializedTx);
|
|
301
|
+
// some information isn't deserialized by the from method, so we will
|
|
302
|
+
// supply it again in order to re-build the txn
|
|
303
|
+
txBuilder
|
|
304
|
+
.validity({
|
|
305
|
+
firstValid: testData.westendBlock.blockNumber,
|
|
306
|
+
maxDuration: basecoin.SWEEP_TXN_DURATION,
|
|
307
|
+
})
|
|
308
|
+
.referenceBlock(testData.westendBlock.hash);
|
|
309
|
+
const tx = await txBuilder.build();
|
|
310
|
+
const txJson = tx.toJson();
|
|
311
|
+
should.deepEqual(txJson.sender, testData.wrwUser.walletAddress0);
|
|
312
|
+
should.deepEqual(txJson.blockNumber, testData.westendBlock.blockNumber);
|
|
313
|
+
should.deepEqual(txJson.referenceBlock, testData.westendBlock.hash);
|
|
314
|
+
should.deepEqual(txJson.genesisHash, resources_1.genesisHash);
|
|
315
|
+
should.deepEqual(txJson.specVersion, resources_1.specVersion);
|
|
316
|
+
should.deepEqual(txJson.nonce, nonce);
|
|
317
|
+
should.deepEqual(txJson.tip, 0);
|
|
318
|
+
should.deepEqual(txJson.transactionVersion, resources_1.txVersion);
|
|
319
|
+
should.deepEqual(txJson.chainName, resources_1.chainName);
|
|
320
|
+
should.deepEqual(txJson.eraPeriod, basecoin.SWEEP_TXN_DURATION);
|
|
321
|
+
});
|
|
322
|
+
it('should recover a txn for unsigned-sweep recoveries', async function () {
|
|
323
|
+
const res = await basecoin.recover({
|
|
324
|
+
bitgoKey: testData.wrwUser.bitgoKey,
|
|
325
|
+
recoveryDestination: destAddr,
|
|
326
|
+
});
|
|
327
|
+
res.should.not.be.empty();
|
|
328
|
+
res.txRequests[0].transactions[0].unsignedTx.should.hasOwnProperty('serializedTx');
|
|
329
|
+
res.txRequests[0].transactions[0].unsignedTx.should.hasOwnProperty('scanIndex');
|
|
330
|
+
sandBox.assert.calledOnce(basecoin.getAccountInfo);
|
|
331
|
+
sandBox.assert.calledOnce(basecoin.getHeaderInfo);
|
|
332
|
+
// deserialize the txn and verify the fields are what we expect
|
|
333
|
+
const txBuilder = basecoin.getBuilder().from(res.txRequests[0].transactions[0].unsignedTx.serializedTx);
|
|
334
|
+
// some information isn't deserialized by the from method, so we will
|
|
335
|
+
// supply it again in order to re-build the txn
|
|
336
|
+
txBuilder
|
|
337
|
+
.validity({
|
|
338
|
+
firstValid: testData.westendBlock.blockNumber,
|
|
339
|
+
maxDuration: basecoin.SWEEP_TXN_DURATION,
|
|
340
|
+
})
|
|
341
|
+
.referenceBlock(testData.westendBlock.hash)
|
|
342
|
+
.sender({ address: testData.wrwUser.walletAddress0 });
|
|
343
|
+
const tx = await txBuilder.build();
|
|
344
|
+
const txJson = tx.toJson();
|
|
345
|
+
should.deepEqual(txJson.sender, testData.wrwUser.walletAddress0);
|
|
346
|
+
should.deepEqual(txJson.blockNumber, testData.westendBlock.blockNumber);
|
|
347
|
+
should.deepEqual(txJson.referenceBlock, testData.westendBlock.hash);
|
|
348
|
+
should.deepEqual(txJson.genesisHash, resources_1.genesisHash);
|
|
349
|
+
should.deepEqual(txJson.specVersion, resources_1.specVersion);
|
|
350
|
+
should.deepEqual(txJson.nonce, nonce);
|
|
351
|
+
should.deepEqual(txJson.tip, 0);
|
|
352
|
+
should.deepEqual(txJson.transactionVersion, resources_1.txVersion);
|
|
353
|
+
should.deepEqual(txJson.chainName, resources_1.chainName);
|
|
354
|
+
should.deepEqual(txJson.eraPeriod, basecoin.SWEEP_TXN_DURATION);
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
describe('Build Consolidation Recoveries:', () => {
|
|
358
|
+
const sandBox = sinon.createSandbox();
|
|
359
|
+
const baseAddr = testData.consolidationWrwUser.walletAddress0;
|
|
360
|
+
const nonce = 123;
|
|
361
|
+
beforeEach(function () {
|
|
362
|
+
const accountInfoCB = sandBox.stub(src_1.Dot.prototype, 'getAccountInfo');
|
|
363
|
+
accountInfoCB.withArgs(testData.consolidationWrwUser.walletAddress1).resolves({
|
|
364
|
+
nonce: nonce,
|
|
365
|
+
freeBalance: 10000000000,
|
|
366
|
+
});
|
|
367
|
+
accountInfoCB.withArgs(testData.consolidationWrwUser.walletAddress2).resolves({
|
|
368
|
+
nonce: nonce,
|
|
369
|
+
freeBalance: 1510000000000,
|
|
370
|
+
});
|
|
371
|
+
accountInfoCB.withArgs(testData.consolidationWrwUser.walletAddress3).resolves({
|
|
372
|
+
nonce: nonce,
|
|
373
|
+
freeBalance: 1510000000000,
|
|
374
|
+
});
|
|
375
|
+
const headerInfoCB = sandBox.stub(src_1.Dot.prototype, 'getHeaderInfo');
|
|
376
|
+
headerInfoCB.resolves({
|
|
377
|
+
headerNumber: testData.westendBlock.blockNumber,
|
|
378
|
+
headerHash: testData.westendBlock.hash,
|
|
379
|
+
});
|
|
380
|
+
const getFeeCB = sandBox.stub(src_1.Dot.prototype, 'getFee');
|
|
381
|
+
getFeeCB.withArgs(baseAddr, testData.consolidationWrwUser.walletAddress1, 10000000000).resolves(15783812856);
|
|
382
|
+
getFeeCB.withArgs(baseAddr, testData.consolidationWrwUser.walletAddress2, 1510000000000).resolves(15783812856);
|
|
383
|
+
getFeeCB.withArgs(baseAddr, testData.consolidationWrwUser.walletAddress3, 1510000000000).resolves(15783812856);
|
|
384
|
+
});
|
|
385
|
+
afterEach(function () {
|
|
386
|
+
sandBox.restore();
|
|
387
|
+
});
|
|
388
|
+
// TODO(COIN-919): Fix failing test
|
|
389
|
+
xit('should build signed consolidation recoveries', async function () {
|
|
390
|
+
const res = await basecoin.recoverConsolidations({
|
|
391
|
+
userKey: testData.consolidationWrwUser.userKey,
|
|
392
|
+
backupKey: testData.consolidationWrwUser.backupKey,
|
|
393
|
+
bitgoKey: testData.consolidationWrwUser.bitgoKey,
|
|
394
|
+
walletPassphrase: testData.consolidationWrwUser.walletPassphrase,
|
|
395
|
+
startingScanIndex: 1,
|
|
396
|
+
endingScanIndex: 4,
|
|
397
|
+
});
|
|
398
|
+
res.should.not.be.empty();
|
|
399
|
+
res.transactions.length.should.equal(2);
|
|
400
|
+
sandBox.assert.calledThrice(basecoin.getAccountInfo);
|
|
401
|
+
sandBox.assert.calledTwice(basecoin.getHeaderInfo);
|
|
402
|
+
const txn1 = res.transactions[0];
|
|
403
|
+
txn1.should.hasOwnProperty('serializedTx');
|
|
404
|
+
txn1.should.hasOwnProperty('scanIndex');
|
|
405
|
+
txn1.scanIndex.should.equal(2);
|
|
406
|
+
// deserialize the txn and verify the fields are what we expect
|
|
407
|
+
const txBuilder1 = basecoin.getBuilder().from(txn1.serializedTx);
|
|
408
|
+
// some information isn't deserialized by the from method, so we will
|
|
409
|
+
// supply it again in order to re-build the txn
|
|
410
|
+
txBuilder1
|
|
411
|
+
.validity({
|
|
412
|
+
firstValid: testData.westendBlock.blockNumber,
|
|
413
|
+
maxDuration: basecoin.MAX_VALIDITY_DURATION,
|
|
414
|
+
})
|
|
415
|
+
.referenceBlock(testData.westendBlock.hash);
|
|
416
|
+
const tx1 = await txBuilder1.build();
|
|
417
|
+
const txJson1 = tx1.toJson();
|
|
418
|
+
should.deepEqual(txJson1.sender, testData.consolidationWrwUser.walletAddress2);
|
|
419
|
+
should.deepEqual(txJson1.blockNumber, testData.westendBlock.blockNumber);
|
|
420
|
+
should.deepEqual(txJson1.referenceBlock, testData.westendBlock.hash);
|
|
421
|
+
should.deepEqual(txJson1.genesisHash, resources_1.genesisHash);
|
|
422
|
+
should.deepEqual(txJson1.specVersion, resources_1.specVersion);
|
|
423
|
+
should.deepEqual(txJson1.nonce, nonce);
|
|
424
|
+
should.deepEqual(txJson1.tip, 0);
|
|
425
|
+
should.deepEqual(txJson1.transactionVersion, resources_1.txVersion);
|
|
426
|
+
should.deepEqual(txJson1.chainName, resources_1.chainName);
|
|
427
|
+
// eraPeriod will always round to the next upper power of 2 for any input value, in this case 2400.
|
|
428
|
+
// 4096 is the "highest" value you can set, but the txn still may fail after 2400 blocks.
|
|
429
|
+
const eraPeriod = 4096;
|
|
430
|
+
should.deepEqual(txJson1.eraPeriod, eraPeriod);
|
|
431
|
+
should.deepEqual(txJson1.to, baseAddr);
|
|
432
|
+
res.lastScanIndex.should.equal(3);
|
|
433
|
+
const txn2 = res.transactions[1];
|
|
434
|
+
txn2.should.hasOwnProperty('serializedTx');
|
|
435
|
+
txn2.should.hasOwnProperty('scanIndex');
|
|
436
|
+
txn2.scanIndex.should.equal(3);
|
|
437
|
+
// deserialize the txn and verify the fields are what we expect
|
|
438
|
+
const txBuilder2 = basecoin.getBuilder().from(txn2.serializedTx);
|
|
439
|
+
// some information isn't deserialized by the from method, so we will
|
|
440
|
+
// supply it again in order to re-build the txn
|
|
441
|
+
txBuilder2
|
|
442
|
+
.validity({
|
|
443
|
+
firstValid: testData.westendBlock.blockNumber,
|
|
444
|
+
maxDuration: basecoin.MAX_VALIDITY_DURATION,
|
|
445
|
+
})
|
|
446
|
+
.referenceBlock(testData.westendBlock.hash);
|
|
447
|
+
const tx2 = await txBuilder2.build();
|
|
448
|
+
const txJson2 = tx2.toJson();
|
|
449
|
+
should.deepEqual(txJson2.sender, testData.consolidationWrwUser.walletAddress3);
|
|
450
|
+
should.deepEqual(txJson2.blockNumber, testData.westendBlock.blockNumber);
|
|
451
|
+
should.deepEqual(txJson2.referenceBlock, testData.westendBlock.hash);
|
|
452
|
+
should.deepEqual(txJson2.genesisHash, resources_1.genesisHash);
|
|
453
|
+
should.deepEqual(txJson2.specVersion, resources_1.specVersion);
|
|
454
|
+
should.deepEqual(txJson2.nonce, nonce);
|
|
455
|
+
should.deepEqual(txJson2.tip, 0);
|
|
456
|
+
should.deepEqual(txJson2.transactionVersion, resources_1.txVersion);
|
|
457
|
+
should.deepEqual(txJson2.chainName, resources_1.chainName);
|
|
458
|
+
should.deepEqual(txJson2.eraPeriod, eraPeriod);
|
|
459
|
+
should.deepEqual(txJson2.to, baseAddr);
|
|
460
|
+
});
|
|
461
|
+
it('should build unsigned consolidation recoveries', async function () {
|
|
462
|
+
const res = await basecoin.recoverConsolidations({
|
|
463
|
+
bitgoKey: testData.consolidationWrwUser.bitgoKey,
|
|
464
|
+
startingScanIndex: 1,
|
|
465
|
+
endingScanIndex: 4,
|
|
466
|
+
});
|
|
467
|
+
res.should.not.be.empty();
|
|
468
|
+
res.txRequests.length.should.equal(2);
|
|
469
|
+
sandBox.assert.calledThrice(basecoin.getAccountInfo);
|
|
470
|
+
sandBox.assert.calledTwice(basecoin.getHeaderInfo);
|
|
471
|
+
const txn1 = res.txRequests[0].transactions[0].unsignedTx;
|
|
472
|
+
txn1.should.hasOwnProperty('serializedTx');
|
|
473
|
+
txn1.should.hasOwnProperty('signableHex');
|
|
474
|
+
txn1.should.hasOwnProperty('scanIndex');
|
|
475
|
+
txn1.scanIndex.should.equal(2);
|
|
476
|
+
txn1.should.hasOwnProperty('coin');
|
|
477
|
+
txn1.coin.should.equal('tdot');
|
|
478
|
+
txn1.should.hasOwnProperty('derivationPath');
|
|
479
|
+
txn1.derivationPath.should.equal('m/2');
|
|
480
|
+
txn1.should.hasOwnProperty('coinSpecific');
|
|
481
|
+
const coinSpecific1 = txn1.coinSpecific;
|
|
482
|
+
coinSpecific1.should.hasOwnProperty('commonKeychain');
|
|
483
|
+
coinSpecific1.should.hasOwnProperty('firstValid');
|
|
484
|
+
coinSpecific1.firstValid.should.equal(testData.westendBlock.blockNumber);
|
|
485
|
+
coinSpecific1.should.hasOwnProperty('maxDuration');
|
|
486
|
+
coinSpecific1.maxDuration.should.equal(basecoin.MAX_VALIDITY_DURATION);
|
|
487
|
+
// deserialize the txn and verify the fields are what we expect
|
|
488
|
+
const txBuilder1 = basecoin.getBuilder().from(txn1.serializedTx);
|
|
489
|
+
// some information isn't deserialized by the from method, so we will
|
|
490
|
+
// supply it again in order to re-build the txn
|
|
491
|
+
txBuilder1
|
|
492
|
+
.validity({
|
|
493
|
+
firstValid: testData.westendBlock.blockNumber,
|
|
494
|
+
maxDuration: basecoin.MAX_VALIDITY_DURATION,
|
|
495
|
+
})
|
|
496
|
+
.referenceBlock(testData.westendBlock.hash)
|
|
497
|
+
.sender({ address: testData.consolidationWrwUser.walletAddress2 });
|
|
498
|
+
const tx1 = await txBuilder1.build();
|
|
499
|
+
const txJson1 = tx1.toJson();
|
|
500
|
+
should.deepEqual(txJson1.sender, testData.consolidationWrwUser.walletAddress2);
|
|
501
|
+
should.deepEqual(txJson1.blockNumber, testData.westendBlock.blockNumber);
|
|
502
|
+
should.deepEqual(txJson1.referenceBlock, testData.westendBlock.hash);
|
|
503
|
+
should.deepEqual(txJson1.genesisHash, resources_1.genesisHash);
|
|
504
|
+
should.deepEqual(txJson1.specVersion, resources_1.specVersion);
|
|
505
|
+
should.deepEqual(txJson1.nonce, nonce);
|
|
506
|
+
should.deepEqual(txJson1.tip, 0);
|
|
507
|
+
should.deepEqual(txJson1.transactionVersion, resources_1.txVersion);
|
|
508
|
+
should.deepEqual(txJson1.chainName, resources_1.chainName);
|
|
509
|
+
// eraPeriod will always round to the next upper power of 2 for any input value, in this case 2400.
|
|
510
|
+
// 4096 is the "highest" value you can set, but the txn still may fail after 2400 blocks.
|
|
511
|
+
const eraPeriod = 4096;
|
|
512
|
+
should.deepEqual(txJson1.eraPeriod, eraPeriod);
|
|
513
|
+
should.deepEqual(txJson1.to, baseAddr);
|
|
514
|
+
const txn2 = res.txRequests[1].transactions[0].unsignedTx;
|
|
515
|
+
txn2.should.hasOwnProperty('serializedTx');
|
|
516
|
+
txn2.should.hasOwnProperty('signableHex');
|
|
517
|
+
txn2.should.hasOwnProperty('scanIndex');
|
|
518
|
+
txn2.scanIndex.should.equal(3);
|
|
519
|
+
txn2.should.hasOwnProperty('coin');
|
|
520
|
+
txn2.coin.should.equal('tdot');
|
|
521
|
+
txn2.should.hasOwnProperty('derivationPath');
|
|
522
|
+
txn2.derivationPath.should.equal('m/3');
|
|
523
|
+
txn2.should.hasOwnProperty('coinSpecific');
|
|
524
|
+
const coinSpecific2 = txn2.coinSpecific;
|
|
525
|
+
coinSpecific2.should.hasOwnProperty('commonKeychain');
|
|
526
|
+
coinSpecific2.should.hasOwnProperty('firstValid');
|
|
527
|
+
coinSpecific2.firstValid.should.equal(testData.westendBlock.blockNumber);
|
|
528
|
+
coinSpecific2.should.hasOwnProperty('maxDuration');
|
|
529
|
+
coinSpecific2.maxDuration.should.equal(basecoin.MAX_VALIDITY_DURATION);
|
|
530
|
+
coinSpecific2.should.hasOwnProperty('commonKeychain');
|
|
531
|
+
coinSpecific2.should.hasOwnProperty('lastScanIndex');
|
|
532
|
+
coinSpecific2.lastScanIndex.should.equal(3);
|
|
533
|
+
// deserialize the txn and verify the fields are what we expect
|
|
534
|
+
const txBuilder2 = basecoin.getBuilder().from(txn2.serializedTx);
|
|
535
|
+
// some information isn't deserialized by the from method, so we will
|
|
536
|
+
// supply it again in order to re-build the txn
|
|
537
|
+
txBuilder2
|
|
538
|
+
.validity({
|
|
539
|
+
firstValid: testData.westendBlock.blockNumber,
|
|
540
|
+
maxDuration: basecoin.MAX_VALIDITY_DURATION,
|
|
541
|
+
})
|
|
542
|
+
.referenceBlock(testData.westendBlock.hash)
|
|
543
|
+
.sender({ address: testData.consolidationWrwUser.walletAddress3 });
|
|
544
|
+
const tx2 = await txBuilder2.build();
|
|
545
|
+
const txJson2 = tx2.toJson();
|
|
546
|
+
should.deepEqual(txJson2.sender, testData.consolidationWrwUser.walletAddress3);
|
|
547
|
+
should.deepEqual(txJson2.blockNumber, testData.westendBlock.blockNumber);
|
|
548
|
+
should.deepEqual(txJson2.referenceBlock, testData.westendBlock.hash);
|
|
549
|
+
should.deepEqual(txJson2.genesisHash, resources_1.genesisHash);
|
|
550
|
+
should.deepEqual(txJson2.specVersion, resources_1.specVersion);
|
|
551
|
+
should.deepEqual(txJson2.nonce, nonce);
|
|
552
|
+
should.deepEqual(txJson2.tip, 0);
|
|
553
|
+
should.deepEqual(txJson2.transactionVersion, resources_1.txVersion);
|
|
554
|
+
should.deepEqual(txJson2.chainName, resources_1.chainName);
|
|
555
|
+
should.deepEqual(txJson2.eraPeriod, eraPeriod);
|
|
556
|
+
should.deepEqual(txJson2.to, baseAddr);
|
|
557
|
+
});
|
|
558
|
+
it('should skip building consolidate transaction if balance is equal to zero', async function () {
|
|
559
|
+
await basecoin
|
|
560
|
+
.recoverConsolidations({
|
|
561
|
+
userKey: testData.consolidationWrwUser.userKey,
|
|
562
|
+
backupKey: testData.consolidationWrwUser.backupKey,
|
|
563
|
+
bitgoKey: testData.consolidationWrwUser.bitgoKey,
|
|
564
|
+
walletPassphrase: testData.consolidationWrwUser.walletPassphrase,
|
|
565
|
+
startingScanIndex: 1,
|
|
566
|
+
endingScanIndex: 2,
|
|
567
|
+
})
|
|
568
|
+
.should.rejectedWith('Did not find an address with funds to recover');
|
|
569
|
+
});
|
|
570
|
+
it('should throw if startingScanIndex is not ge to 1', async () => {
|
|
571
|
+
await basecoin
|
|
572
|
+
.recoverConsolidations({
|
|
573
|
+
userKey: testData.consolidationWrwUser.userKey,
|
|
574
|
+
backupKey: testData.consolidationWrwUser.backupKey,
|
|
575
|
+
bitgoKey: testData.consolidationWrwUser.bitgoKey,
|
|
576
|
+
startingScanIndex: -1,
|
|
577
|
+
})
|
|
578
|
+
.should.be.rejectedWith('Invalid starting or ending index to scan for addresses. startingScanIndex: -1, endingScanIndex: 19.');
|
|
579
|
+
});
|
|
580
|
+
it('should throw if scan factor is too high', async () => {
|
|
581
|
+
await basecoin
|
|
582
|
+
.recoverConsolidations({
|
|
583
|
+
userKey: testData.consolidationWrwUser.userKey,
|
|
584
|
+
backupKey: testData.consolidationWrwUser.backupKey,
|
|
585
|
+
bitgoKey: testData.consolidationWrwUser.bitgoKey,
|
|
586
|
+
startingScanIndex: 1,
|
|
587
|
+
endingScanIndex: 300,
|
|
588
|
+
})
|
|
589
|
+
.should.be.rejectedWith('Invalid starting or ending index to scan for addresses. startingScanIndex: 1, endingScanIndex: 300.');
|
|
590
|
+
});
|
|
591
|
+
});
|
|
592
|
+
describe('Recover Transaction Failures:', () => {
|
|
593
|
+
const sandBox = sinon.createSandbox();
|
|
594
|
+
const destAddr = testData.accounts.account1.address;
|
|
595
|
+
const nonce = 123;
|
|
596
|
+
beforeEach(function () {
|
|
597
|
+
const accountInfoCB = sandBox.stub(src_1.Dot.prototype, 'getAccountInfo');
|
|
598
|
+
accountInfoCB.resolves({
|
|
599
|
+
nonce: nonce,
|
|
600
|
+
freeBalance: 0,
|
|
601
|
+
});
|
|
602
|
+
});
|
|
603
|
+
afterEach(function () {
|
|
604
|
+
sandBox.restore();
|
|
605
|
+
});
|
|
606
|
+
it('should fail to recover due to not finding an address with funds', async function () {
|
|
607
|
+
await basecoin
|
|
608
|
+
.recover({
|
|
609
|
+
userKey: testData.wrwUser.userKey,
|
|
610
|
+
backupKey: testData.wrwUser.backupKey,
|
|
611
|
+
bitgoKey: testData.wrwUser.bitgoKey,
|
|
612
|
+
walletPassphrase: testData.wrwUser.walletPassphrase,
|
|
613
|
+
recoveryDestination: destAddr,
|
|
614
|
+
})
|
|
615
|
+
.should.rejectedWith('Did not find address with funds to recover');
|
|
616
|
+
});
|
|
617
|
+
});
|
|
618
|
+
describe('Verify Transaction', function () {
|
|
619
|
+
const address1 = '5Ge59qRnZa8bxyhVFE6BDoY3kuhSrNVETRxXYLty1Hh6XTaf';
|
|
620
|
+
const address2 = '5DiMLZugmcKEH3igPZP367FqummZkWeW5Z6zDCHLfxRjnPXe';
|
|
621
|
+
it('should reject a txPrebuild with more than one recipient', async function () {
|
|
622
|
+
const wallet = new sdk_core_1.Wallet(bitgo, basecoin, {});
|
|
623
|
+
const txParams = {
|
|
624
|
+
recipients: [
|
|
625
|
+
{ amount: '1000000000000', address: address1 },
|
|
626
|
+
{ amount: '2500000000000', address: address2 },
|
|
627
|
+
],
|
|
628
|
+
wallet: wallet,
|
|
629
|
+
walletPassphrase: 'fakeWalletPassphrase',
|
|
630
|
+
};
|
|
631
|
+
await basecoin
|
|
632
|
+
.verifyTransaction({ txParams })
|
|
633
|
+
.should.be.rejectedWith(`tdot doesn't support sending to more than 1 destination address within a single transaction. Try again, using only a single recipient.`);
|
|
634
|
+
});
|
|
635
|
+
});
|
|
636
|
+
});
|
|
637
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG90LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2RvdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDRDQUEwQztBQUMxQyw4Q0FBMEQ7QUFDMUQsbUNBQXFDO0FBQ3JDLGlDQUFrQztBQUNsQyxtQ0FBK0M7QUFDL0Msc0RBQXdDO0FBQ3hDLDRDQUE4RTtBQUM5RSw2Q0FBK0I7QUFDL0IsOENBQXlDO0FBRXpDLFFBQVEsQ0FBQyxNQUFNLEVBQUU7SUFDZixJQUFJLEtBQW1CLENBQUM7SUFDeEIsSUFBSSxRQUFRLENBQUM7SUFDYixJQUFJLFFBQVEsQ0FBQztJQUViLE1BQU0sQ0FBQztRQUNMLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxrQkFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdEQsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsU0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzlDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLFVBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNoRCxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMzQixRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5QixRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMvQixDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxjQUFjLEVBQUUsR0FBRyxFQUFFO1FBQzVCLEVBQUUsQ0FBQyxxQkFBcUIsRUFBRSxLQUFLLElBQUksRUFBRTtZQUNuQyxNQUFNLE9BQU8sR0FBRyxJQUFJLGFBQU8sRUFBRSxDQUFDO1lBQzlCLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBQSxvQkFBVyxFQUFDLEVB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USxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUN6RixRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUUsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzVFLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDeEYsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3JGLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDckYsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDNUYsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekYsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ3ZGLGtEQUFrRCxDQUNuRCxDQUFDO1lBQ0YsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDL0csUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDdkcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDN0YsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDMUYsUUFBUSxDQUFDLFVB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ZSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUU7aUJBQy9DO2dCQUNELE1BQU0sRUFBRSxNQUFNO2dCQUNkLGdCQUFnQixFQUFFLHNCQUFzQjthQUN6QyxDQUFDO1lBRUYsTUFBTSxRQUFRO2lCQUNYLGlCQUFpQixDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUM7aUJBQy9CLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUNyQix3SUFBd0ksQ0FDekksQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvL3Nkay1hcGknO1xuaW1wb3J0IHsgVGVzdEJpdEdvLCBUZXN0Qml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHsgcmFuZG9tQnl0ZXMgfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHNob3VsZCA9IHJlcXVpcmUoJ3Nob3VsZCcpO1xuaW1wb3J0IHsgRG90LCBUZG90LCBLZXlQYWlyIH0gZnJvbSAnLi4vLi4vc3JjJztcbmltcG9ydCAqIGFzIHRlc3REYXRhIGZyb20gJy4uL2ZpeHR1cmVzJztcbmltcG9ydCB7IGNoYWluTmFtZSwgdHhWZXJzaW9uLCBnZW5lc2lzSGFzaCwgc3BlY1ZlcnNpb24gfSBmcm9tICcuLi9yZXNvdXJjZXMnO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IHsgV2FsbGV0IH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcblxuZGVzY3JpYmUoJ0RPVDonLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICBsZXQgYmFzZWNvaW47XG4gIGxldCBwcm9kQ29pbjtcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudjogJ21vY2snIH0pO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcignZG90JywgRG90LmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ3Rkb3QnLCBUZG90LmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3Rkb3QnKTtcbiAgICBwcm9kQ29pbiA9IGJpdGdvLmNvaW4oJ2RvdCcpO1xuICB9KTtcblxuICBkZXNjcmliZSgnU2lnbiBNZXNzYWdlJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgYmUgcGVyZm9ybWVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qga2V5UGFpciA9IG5ldyBLZXlQYWlyKCk7XG4gICAgICBjb25zdCBtZXNzYWdlVG9TaWduID0gQnVmZmVyLmZyb20ocmFuZG9tQnl0ZXMoMzIpKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICBjb25zdCBzaWduYXR1cmUgPSBhd2FpdCBiYXNlY29pbi5zaWduTWVzc2FnZShrZXlQYWlyLmdldEtleXMoKSwgbWVzc2FnZVRvU2lnbik7XG4gICAgICBrZXlQYWlyLnZlcmlmeVNpZ25hdHVyZShtZXNzYWdlVG9TaWduLCBVaW50OEFycmF5LmZyb20oc2lnbmF0dXJlKSkuc2hvdWxkLmVxdWFscyh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB3aXRoIG1pc3NpbmcgcHJpdmF0ZSBrZXknLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBrZXlQYWlyID0gbmV3IEtleVBhaXIoe1xuICAgICAgICBwdWI6ICc3Nzg4MzI3YzY5NWRjYTRiM2U2NDlhMGRiNDViYzNlNzAzYTJjNjc0MjhmY2UzNjBlNjE4MDBjYzQyNDhmNGY3JyxcbiAgICAgIH0pLmdldEtleXMoKTtcbiAgICAgIGNvbnN0IG1lc3NhZ2VUb1NpZ24gPSBCdWZmZXIuZnJvbShyYW5kb21CeXRlcygzMikpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGF3YWl0IGJhc2Vjb2luLnNpZ25NZXNzYWdlKGtleVBhaXIsIG1lc3NhZ2VUb1NpZ24pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0ludmFsaWQga2V5IHBhaXIgb3B0aW9ucycpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnU2lnbiB0cmFuc2FjdGlvbicsICgpID0+IHtcbiAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHtcbiAgICAgIGlkOiAnMHgxOWRlMTU2MzI4ZWVhNjZiZDFlYzQ1ODQzNTY5YzE2OGUwYmIyZjI4OTgyMjEwMjliNDAzZGYzZjIzYTU0ODlkJyxcbiAgICAgIHNlbmRlcjogJzVFR29GQTk1b216ZW1Sc3NFTExEalZlbk5aNjhhWHlVZXF0S1FTY1hTRUJ2VkprcicsXG4gICAgICByZWZlcmVuY2VCbG9jazogJzB4MTQ5Nzk5YmM5NjAyY2I1Y2YyMDFmMzQyNWZiOGQyNTNiMmQ0ZTYxZmMxMTlkY2FiMzI0OWYzMDdmNTk0NzU0ZCcsXG4gICAgICBibG9ja051bWJlcjogMzkzMyxcbiAgICAgIGdlbmVzaXNIYXNoOiAnMHg2N2Y5NzIzMzkzZWY3NjIxNGRmMDExOGMzNGJiYmQzZGJlYmM4ZWQ0NmExMDk3M2E4Yzk2OWQ0OGZlNzU5OGM5JyxcbiAgICAgIG5vbmNlOiAyMDAsXG4gICAgICBzcGVjVmVyc2lvbjogMTAxODAxMyxcbiAgICAgIHRyYW5zYWN0aW9uVmVyc2lvbjogMTYsXG4gICAgICBlcmFQZXJpb2Q6IDY0LFxuICAgICAgY2hhaW5OYW1lOiAnV2VzdGVuZCBBc3NldCBIdWInLFxuICAgICAgdGlwOiAwLFxuICAgICAgdG86ICc1RmZwMXdKQ1B1NGh6VkRUbzdYYU1McVpTdlNhZHlVUW14V1BEdzc0Q0JqRUNTb3EnLFxuICAgICAgYW1vdW50OiAnMTAwMDAwMDAwMDAnLFxuICAgIH07XG5cbiAgICAvLyBUT0RPOiBCRy00MzE5N1xuICAgIHhpdCgnc2hvdWxkIHNpZ24gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzaWduZWQgPSBhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgdHhIZXg6IHRlc3REYXRhLnJhd1R4LnRyYW5zZmVyLnVuc2lnbmVkLFxuICAgICAgICAgIHRyYW5zYWN0aW9uLFxuICAgICAgICB9LFxuICAgICAgICBwdWJzOiBbdGVzdERhdGEuYWNjb3VudHMuYWNjb3VudDEucHVibGljS2V5XSxcbiAgICAgICAgcHJ2OiB0ZXN0RGF0YS5hY2NvdW50cy5hY2NvdW50MS5zZWNyZXRLZXksXG4gICAgICB9KTtcbiAgICAgIHNpZ25lZC50eEhleC5zaG91bGQuZXF1YWwodGVzdERhdGEucmF3VHgudHJhbnNmZXIuc2lnbmVkKTtcbiAgICB9KTtcblxuICAgIC8vIFRPRE86IEJHLTQzMTk3XG4gICAgeGl0KCdzaG91bGQgZmFpbCB0byBzaWduIHRyYW5zYWN0aW9uIHdpdGggYW4gaW52YWxpZCBrZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICAgIHR4SGV4OiB0ZXN0RGF0YS5yYXdUeC50cmFuc2Zlci51bnNpZ25lZCxcbiAgICAgICAgICAgIHRyYW5zYWN0aW9uLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcHViczogW3Rlc3REYXRhLmFjY291bnRzLmFjY291bnQyLnB1YmxpY0tleV0sXG4gICAgICAgICAgcHJ2OiB0ZXN0RGF0YS5hY2NvdW50cy5hY2NvdW50MS5zZWNyZXRLZXksXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBzaG91bGQuZXF1YWwoZS5tZXNzYWdlLCAnUHJpdmF0ZSBrZXkgY2Fubm90IHNpZ24gdGhlIHRyYW5zYWN0aW9uJyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gYnVpbGQgdHJhbnNhY3Rpb24gd2l0aCBtaXNzaW5nIHBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgICAgdHhIZXg6IHRlc3REYXRhLnJhd1R4LnRyYW5zZmVyLnVuc2lnbmVkLFxuICAgICAgICAgICAga2V5OiB0ZXN0RGF0YS5hY2NvdW50cy5hY2NvdW50MS5wdWJsaWNLZXksXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwcnY6IHRlc3REYXRhLmFjY291bnRzLmFjY291bnQxLnNlY3JldEtleSxcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHNob3VsZC5ub3RFcXVhbChlLCBudWxsKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0dlbmVyYXRlIHdhbGxldCBrZXkgcGFpcjogJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUga2V5IHBhaXInLCAoKSA9PiB7XG4gICAgICBjb25zdCBrcCA9IGJhc2Vjb2luLmdlbmVyYXRlS2V5UGFpcigpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZFB1YihrcC5wdWIpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQcnYoa3AucHJ2KS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGtleSBwYWlyIGZyb20gc2VlZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHNlZWQgPSBCdWZmZXIuZnJvbSgnOWQ2MWIxOWRlZmZkNWE2MGJhODQ0YWY0OTJlYzJjYzQ0NDQ5YzU2OTdiMzI2OTE5NzAzYmFjMDMxY2FlN2Y2MCcsICdoZXgnKTtcbiAgICAgIGNvbnN0IGtwID0gYmFzZWNvaW4uZ2VuZXJhdGVLZXlQYWlyKHNlZWQpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZFB1YihrcC5wdWIpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQcnYoa3AucHJ2KS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdCYWxhbmNlIENvbnZlcnNpb24nLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gMTAwMDAwMDAwMDAgYXMgdGRvdCBiYXNlIGZhY3RvcicsICgpID0+IHtcbiAgICAgIC8vIG1haW5uZXQgdXNlcyAxMCBkZWNpbWFsIHBsYWNlc1xuICAgICAgY29uc3QgYmFzZUZhY3RvciA9IHByb2RDb2luLmdldEJhc2VGYWN0b3IoKTtcbiAgICAgIGJhc2VGYWN0b3Iuc2hvdWxkLmVxdWFsKDEwMDAwMDAwMDAwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIDEwMDAwMDAwMDAwMDAgYXMgZG90IGJhc2UgZmFjdG9yJywgKCkgPT4ge1xuICAgICAgLy8gd2VzdGVuZCAodGVzdCBwb2xrYWRvdCkgdXNlcyAxMiBkZWNpbWFsIHBsYWNlc1xuICAgICAgY29uc3QgYmFzZUZhY3RvciA9IGJhc2Vjb2luLmdldEJhc2VGYWN0b3IoKTtcbiAgICAgIGJhc2VGYWN0b3Iuc2hvdWxkLmVxdWFsKDEwMDAwMDAwMDAwMDApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gNCBEb3Qgd2hlbiBiYXNlIHVuaXQgaXMgNDAwMDAwMDAwMDAgZm9yIGRvdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGJpZ1VuaXQgPSBwcm9kQ29pbi5iYXNlVW5pdHNUb0JpZ1VuaXRzKCc0MDAwMDAwMDAwMCcpO1xuICAgICAgYmlnVW5pdC5zaG91bGQuZXF1YWwoJzQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIDAuMDQgRG90IHdoZW4gYmFzZSB1bml0IGlzIDQwMDAwMDAwMCBmb3IgZG90JywgKCkgPT4ge1xuICAgICAgY29uc3QgYmlnVW5pdCA9IHByb2RDb2luLmJhc2VVbml0c1RvQmlnVW5pdHMoJzQwMDAwMDAwMCcpO1xuICAgICAgYmlnVW5pdC5zaG91bGQuZXF1YWwoJzAuMDQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIDQgdGVzdCBEb3Qgd2hlbiBiYXNlIHVuaXQgaXMgNDAwMDAwMDAwMDAwMCBmb3IgdGRvdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGJpZ1VuaXQgPSBiYXNlY29pbi5iYXNlVW5pdHNUb0JpZ1VuaXRzKCc0MDAwMDAwMDAwMDAwJyk7XG4gICAgICBiaWdVbml0LnNob3VsZC5lcXVhbCgnNCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gMC4wNCB0ZXN0IERvdCB3aGVuIGJhc2UgdW5pdCBpcyA0MDAwMDAwMDAgZm9yIHRkb3QnLCAoKSA9PiB7XG4gICAgICBjb25zdCBiaWdVbml0ID0gYmFzZWNvaW4uYmFzZVVuaXRzVG9CaWdVbml0cygnNDAwMDAwMDAwMDAnKTtcbiAgICAgIGJpZ1VuaXQuc2hvdWxkLmVxdWFsKCcwLjA0Jyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFeHBsYWluIFRyYW5zYWN0aW9uczonLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGFuIHVuc2lnbmVkIHRyYW5zZmVyIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24odGVzdERhdGEudW5zaWduZWRUcmFuc2FjdGlvbik7XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbXG4gICAgICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAgICAgJ2NoYW5nZUFtb3VudCcsXG4gICAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICAgICAnZmVlJyxcbiAgICAgICAgICAndHlwZScsXG4gICAgICAgICAgJ3NlcXVlbmNlSWQnLFxuICAgICAgICAgICdpZCcsXG4gICAgICAgICAgJ2Jsb2NrTnVtYmVyJyxcbiAgICAgICAgXSxcbiAgICAgICAgc2VxdWVuY2VJZDogMCxcbiAgICAgICAgZmVlOiAnMTAnLFxuICAgICAgICBpZDogJzB4MGU1NzUxYzAyNmU1NDNiMmU4YWIyZWIwNjA5OWRhYTFkMWU1ZGY0Nzc3OGY3Nzg3ZmFhYjQ1Y2RmMTJmZTNhOCcsXG4gICAgICAgIHR5cGU6ICcwJyxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICc1RGtkZFNmUHNXb2pqZnVIOWlKRWNVVjdac2VROUVKNlJqdE5tQ1IxdzNDRWI4UzknLFxuICAgICAgICAgICAgdmFsdWVTdHJpbmc6ICc5MDAzNDIzNTIzNTM1MCcsXG4gICAgICAgICAgICBjb2luTmFtZTogJ3Rkb3QnLFxuICAgICAgICAgICAgd2FsbGV0OiAnNjJhMTIwNTc1MTY3NWIyZjBmZTcyMzI4JyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBibG9ja051bWJlcjogODYxOTMwNyxcbiAgICAgICAgb3V0cHV0QW1vdW50OiA5MDAzNDIzNTIzNTM1MCxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZWNvdmVyIFRyYW5zYWN0aW9uczonLCAoKSA9PiB7XG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICBjb25zdCBkZXN0QWRkciA9IHRlc3REYXRhLmFjY291bnRzLmFjY291bnQxLmFkZHJlc3M7XG4gICAgY29uc3Qgbm9uY2UgPSAxMjM7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFjY291bnRJbmZvQ0IgPSBzYW5kQm94LnN0dWIoRG90LnByb3RvdHlwZSwgJ2dldEFjY291bnRJbmZvJyBhcyBrZXlvZiBEb3QpO1xuICAgICAgYWNjb3VudEluZm9DQi53aXRoQXJncyh0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwKS5yZXNvbHZlcyh7XG4gICAgICAgIG5vbmNlOiBub25jZSxcbiAgICAgICAgZnJlZUJhbGFuY2U6IDg4ODgsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGhlYWRlckluZm9DQiA9IHNhbmRCb3guc3R1YihEb3QucHJvdG90eXBlLCAnZ2V0SGVhZGVySW5mbycgYXMga2V5b2YgRG90KTtcbiAgICAgIGhlYWRlckluZm9DQi5yZXNvbHZlcyh7XG4gICAgICAgIGhlYWRlck51bWJlcjogdGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyLFxuICAgICAgICBoZWFkZXJIYXNoOiB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suaGFzaCxcbiAgICAgIH0pO1xuICAgICAgYWNjb3VudEluZm9DQi53aXRoQXJncygnNUR0ZzJ6S2pWRUw4cDlrZVNNNGRRN25EMjZzVnRNZkNzeXhraHZaWjlmcUJiaHc2JykucmVzb2x2ZXMoe1xuICAgICAgICBub25jZTogMCxcbiAgICAgICAgZnJlZUJhbGFuY2U6IDE1MTAwMDAwMDAwMDAsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGdldEZlZUNCID0gc2FuZEJveC5zdHViKERvdC5wcm90b3R5cGUsICdnZXRGZWUnIGFzIGtleW9mIERvdCk7XG4gICAgICBnZXRGZWVDQi53aXRoQXJncyhkZXN0QWRkciwgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMCwgMTUxMDAwMDAwMDAwMCkucmVzb2x2ZXMoMTU3ODM4MTI4NTYpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNhbmRCb3gucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSB1bnNpZ25lZCBzd2VlcCBjb3JyZWN0bHknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9XG4gICAgICAgICczY2QxNGY1ZDYwNzQ0Mjg3Y2QzYTUwNTEwZTI5NjQ3NDZiNmZlYWFkNGIyMzAwMDg4ZWFhZTYwZDFhMzVmMGFiYzUxODUzNGQ0M2IyNjE0MzcwZDlhMjYzYWFkYjU3ZWRiNWQwYjc4ZjgxNmE1MTljZDU4OTZlNzM1MjkyMGI2Nyc7XG4gICAgICBjb25zdCByZWNvdmVyeURlc3RpbmF0aW9uID0gJzVHUEF2ZU12bURzanhWVDZRMnhpdTVrWVBiRkFtZGViSGFpTlpLMTRGQmFTYUFLaCc7XG5cbiAgICAgIGNvbnN0IHVuc2lnbmVkID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7IGJpdGdvS2V5OiBjb21tb25LZXljaGFpbiwgcmVjb3ZlcnlEZXN0aW5hdGlvbiB9KTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHMuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLndhbGxldENvaW4uc2hvdWxkLmVxdWFsKCd0ZG90Jyk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5ub3QuYmUudW5kZWZpbmVkKCk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNlcmlhbGl6ZWRUeC5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zY2FuSW5kZXguc2hvdWxkLmVxdWFsKDApO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5jb2luLnNob3VsZC5lcXVhbCgndGRvdCcpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaWduYWJsZUhleC5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5kZXJpdmF0aW9uUGF0aC5zaG91bGQuZXF1YWwoJ20vMCcpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC5pbnB1dHMuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHguaW5wdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4LmlucHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChcbiAgICAgICAgJzVEdGcyektqVkVMOHA5a2VTTTRkUTduRDI2c1Z0TWZDc3l4a2h2Wlo5ZnFCYmh3NidcbiAgICAgICk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4LmlucHV0c1swXS52YWx1ZVN0cmluZy5zaG91bGQuZXF1YWwoJzE1MTAwMDAwMDAwMDAnKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHguaW5wdXRzWzBdLnZhbHVlLnNob3VsZC5lcXVhbCgxNTEwMDAwMDAwMDAwKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHgub3V0cHV0cy5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4Lm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwoXG4gICAgICAgICc1R1BBdmVNdm1Ec2p4VlQ2UTJ4aXU1a1lQYkZBbWRlYkhhaU5aSzE0RkJhU2FBS2gnXG4gICAgICApO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC5vdXRwdXRzWzBdLnZhbHVlU3RyaW5nLnNob3VsZC5lcXVhbCgnMTUxMDAwMDAwMDAwMCcpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC5vdXRwdXRzWzBdLmNvaW5OYW1lLnNob3VsZC5lcXVhbCgndGRvdCcpO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeC50eXBlLnNob3VsZC5lcXVhbCgnJyk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmZlZUluZm8uc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguZmVlSW5mby5mZWUuc2hvdWxkLmVxdWFsKDApO1xuICAgICAgdW5zaWduZWQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5mZWVJbmZvLmZlZVN0cmluZy5zaG91bGQuZXF1YWwoJzAnKTtcbiAgICAgIHVuc2lnbmVkLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguY29pblNwZWNpZmljLnNob3VsZC5ub3QuYmUudW5kZWZpbmVkKCk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpYy5maXJzdFZhbGlkLnNob3VsZC5ub3QuYmUudW5kZWZpbmVkKCk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpYy5tYXhEdXJhdGlvbi5zaG91bGQuZXF1YWwoMjQwMCk7XG4gICAgICB1bnNpZ25lZC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpYy5jb21tb25LZXljaGFpbi5zaG91bGQuZXF1YWwoXG4gICAgICAgICczY2QxNGY1ZDYwNzQ0Mjg3Y2QzYTUwNTEwZTI5NjQ3NDZiNmZlYWFkNGIyMzAwMDg4ZWFhZTYwZDFhMzVmMGFiYzUxODUzNGQ0M2IyNjE0MzcwZDlhMjYzYWFkYjU3ZWRiNWQwYjc4ZjgxNmE1MTljZDU4OTZlNzM1MjkyMGI2NydcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICAvLyBUT0RPKENPSU4tOTE5KTogRml4IGZhaWxpbmcgdGVzdFxuICAgIHhpdCgnc2hvdWxkIHRha2UgT1ZDIG91dHB1dCBhbmQgZ2VuZXJhdGUgYSBzaWduZWQgc3dlZXAgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB0ZXN0RGF0YS5vdmNSZXNwb25zZTtcblxuICAgICAgY29uc3QgcmVjb3ZlcnlUeG4gPSBhd2FpdCBiYXNlY29pbi5jcmVhdGVCcm9hZGNhc3RhYmxlU3dlZXBUcmFuc2FjdGlvbihwYXJhbXMpO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzBdLnNlcmlhbGl6ZWRUeC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcweDJkMDI4NDAwNTBkMWUxMTZjZGIzMmU2MWJhM2VjZTI3NWI2MjBmNTAzZjBjNWFlNGU3NjkwZDlmOWFhN2UwYjUwMzAzOTc2YzAwMDU3YzEzMWNkZTJiZTM5ZjRmZjIzZWViYTExMTM5YzQ2ZGQ4YzZkNjlmZjUxN2FiZWRlMzczODFkOGQyNGYwYmIzMGZkODgwNWIyZTUxYTllMmE3NTMzOGQ3ZmI3ZWRiMjkwYmU5NjM4ZGViZWRiZmMwMDFkMTBiODEzMmJlMGIyYjRhMDQwMDA0MDQwMGJmMDY3OGQzMTJiMmIyYzdlZmZkMmIxZjIxNGVlMTM5MjhkMzM5MzkxZDVmNWY3MDU2NjA4YWEwZDMyYjllZGYwMSdcbiAgICAgICk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMF0uc2NhbkluZGV4LnNob3VsZC5lcXVhbCgwKTtcbiAgICAgIHJlY292ZXJ5VHhuLmxhc3RTY2FuSW5kZXguc2hvdWxkLmVxdWFsKDApO1xuICAgIH0pO1xuXG4gICAgLy8gVE9ETyhDT0lOLTkxOSk6IEZpeCBmYWlsaW5nIHRlc3RcbiAgICB4aXQoJ3Nob3VsZCB0YWtlIGNvbnNvbGlkYXRpb24gT1ZDIG91dHB1dCBhbmQgZ2VuZXJhdGUgbXVsdGlwbGUgc2lnbmVkIHN3ZWVwIHRyYW5zYWN0aW9ucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHRlc3REYXRhLm92Y1Jlc3BvbnNlMjtcblxuICAgICAgY29uc3QgcmVjb3ZlcnlUeG4gPSBhd2FpdCBiYXNlY29pbi5jcmVhdGVCcm9hZGNhc3RhYmxlU3dlZXBUcmFuc2FjdGlvbihwYXJhbXMpO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzBdLnNlcmlhbGl6ZWRUeC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcweDJkMDI4NDAwZjA1M2QxNzczNzFmNDkxOWI3MTAxNzQyMWFhMzQ4NDFhYzg3YzkyNmExNGU4YTdlNzVmMDkyNjkzNjY1Y2I0YTAwOTg3MWZlYjgzODllMTIxOTFiNDYwZWJlYTFmOWUxNzE2YWRhOGEzMWQ5NGFjMDhmNWMxNWNiNWY3YmUyNDY4M2NkZmMzMDBhZTNlNjgwMmM2ZjRiMDQ0ZGQ5MmVhMDNkMTViOTIzOTlhYjQ1ODAzZTQzYmViNWNiZmY1ODJhMDMxYjM3MDAwMDA0MDQwMDUwZDFlMTE2Y2RiMzJlNjFiYTNlY2UyNzViNjIwZjUwM2YwYzVhZTRlNzY5MGQ5ZjlhYTdlMGI1MDMwMzk3NmMwMSdcbiAgICAgICk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMF0uc2NhbkluZGV4LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1sxXS5zZXJpYWxpemVkVHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMHgyZDAyODQwMGNmN2VkOWY1MzYzNzNjOGY4NzRlNzgwYTQyNjllYzFiZDY3OTllZDdkNGE4NTRjNjcwYjBjNzI4MDVmYWM4NzYwMGQxNTNjYmI2ODM3MDZkZGYzMjBmN2IyMjVhZjE0Y2U0YjU5Yjg2OGMwNzQ0MGFlZmE0YzRlMTI5N2U0OWJjZDVmNmVlODRmNjk2YjBjMmU0NTZlMmE3Zjg3NzlhNzhhMmM4MzJkZmI0N2Q1YjI4M2ViYTg0MDhiMDAzYzdkZDAzMWIzNzAwMDAwNDA0MDA1MGQxZTExNmNkYjMyZTYxYmEzZWNlMjc1YjYyMGY1MDNmMGM1YWU0ZTc2OTBkOWY5YWE3ZTBiNTAzMDM5NzZjMDEnXG4gICAgICApO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzFdLnNjYW5JbmRleC5zaG91bGQuZXF1YWwoMik7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMl0uc2VyaWFsaXplZFR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzB4MmQwMjg0MDA5NDgyYWQ3ZTQzYjQwYjdkZjMzODMyNDRkYWFmZWQzMmIzYjlmZDc1NDEwMTZiNWM5MDdmMmQ5MDUyZjg1Zjg2MDBlMjU1Njk4ZDExMDk3N2ZhZjMzZWZiMzMzNmJhOThhZDdlYWEyYTFhOTI2NDg3ZmM2OTZhMjc3NDQyZDQ0MTRiMmE0NDFiYTkyZDU5OGYyYjFmOTZmMTNiMjg3ODVmNWU1NzI5ODQwMzVhNjA4ZDYzYzQ4YmQzNWJhOTU1MDkwZTFiMzcwMDAwMDQwNDAwNTBkMWUxMTZjZGIzMmU2MWJhM2VjZTI3NWI2MjBmNTAzZjBjNWFlNGU3NjkwZDlmOWFhN2UwYjUwMzAzOTc2YzAxJ1xuICAgICAgKTtcbiAgICAgIHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1syXS5zY2FuSW5kZXguc2hvdWxkLmVxdWFsKDMpO1xuICAgICAgcmVjb3ZlcnlUeG4ubGFzdFNjYW5JbmRleC5zaG91bGQuZXF1YWwoMjApO1xuICAgIH0pO1xuXG4gICAgLy8gVE9ETyhDT0lOLTkxOSk6IEZpeCBmYWlsaW5nIHRlc3RcbiAgICB4aXQoJ3Nob3VsZCByZWNvdmVyIGEgdHhuIGZvciBub24tYml0Z28gcmVjb3ZlcmllcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS53cndVc2VyLnVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEud3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS53cndVc2VyLmJpdGdvS2V5LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS53cndVc2VyLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RBZGRyLFxuICAgICAgfSk7XG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICByZXMuc2hvdWxkLmhhc093blByb3BlcnR5KCdzY2FuSW5kZXgnKTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxlZE9uY2UoYmFzZWNvaW4uZ2V0QWNjb3VudEluZm8pO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkT25jZShiYXNlY29pbi5nZXRIZWFkZXJJbmZvKTtcblxuICAgICAgLy8gZGVzZXJpYWxpemUgdGhlIHR4biBhbmQgdmVyaWZ5IHRoZSBmaWVsZHMgYXJlIHdoYXQgd2UgZXhwZWN0XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBiYXNlY29pbi5nZXRCdWlsZGVyKCkuZnJvbShyZXMuc2VyaWFsaXplZFR4KTtcbiAgICAgIC8vIHNvbWUgaW5mb3JtYXRpb24gaXNuJ3QgZGVzZXJpYWxpemVkIGJ5IHRoZSBmcm9tIG1ldGhvZCwgc28gd2Ugd2lsbFxuICAgICAgLy8gc3VwcGx5IGl0IGFnYWluIGluIG9yZGVyIHRvIHJlLWJ1aWxkIHRoZSB0eG5cbiAgICAgIHR4QnVpbGRlclxuICAgICAgICAudmFsaWRpdHkoe1xuICAgICAgICAgIGZpcnN0VmFsaWQ6IHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlcixcbiAgICAgICAgICBtYXhEdXJhdGlvbjogYmFzZWNvaW4uU1dFRVBfVFhOX0RVUkFUSU9OLFxuICAgICAgICB9KVxuICAgICAgICAucmVmZXJlbmNlQmxvY2sodGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uc2VuZGVyLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmJsb2NrTnVtYmVyLCB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucmVmZXJlbmNlQmxvY2ssIHRlc3REYXRhLndlc3RlbmRCbG9jay5oYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmdlbmVzaXNIYXNoLCBnZW5lc2lzSGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5zcGVjVmVyc2lvbiwgc3BlY1ZlcnNpb24pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ubm9uY2UsIG5vbmNlKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnRpcCwgMCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi50cmFuc2FjdGlvblZlcnNpb24sIHR4VmVyc2lvbik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5jaGFpbk5hbWUsIGNoYWluTmFtZSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5lcmFQZXJpb2QsIGJhc2Vjb2luLlNXRUVQX1RYTl9EVVJBVElPTik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgYSB0eG4gZm9yIHVuc2lnbmVkLXN3ZWVwIHJlY292ZXJpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLndyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RBZGRyLFxuICAgICAgfSk7XG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhc093blByb3BlcnR5KCdzZXJpYWxpemVkVHgnKTtcbiAgICAgIHJlcy50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2NhbkluZGV4Jyk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRPbmNlKGJhc2Vjb2luLmdldEFjY291bnRJbmZvKTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxlZE9uY2UoYmFzZWNvaW4uZ2V0SGVhZGVySW5mbyk7XG5cbiAgICAgIC8vIGRlc2VyaWFsaXplIHRoZSB0eG4gYW5kIHZlcmlmeSB0aGUgZmllbGRzIGFyZSB3aGF0IHdlIGV4cGVjdFxuICAgICAgY29uc3QgdHhCdWlsZGVyID0gYmFzZWNvaW4uZ2V0QnVpbGRlcigpLmZyb20ocmVzLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2VyaWFsaXplZFR4KTtcbiAgICAgIC8vIHNvbWUgaW5mb3JtYXRpb24gaXNuJ3QgZGVzZXJpYWxpemVkIGJ5IHRoZSBmcm9tIG1ldGhvZCwgc28gd2Ugd2lsbFxuICAgICAgLy8gc3VwcGx5IGl0IGFnYWluIGluIG9yZGVyIHRvIHJlLWJ1aWxkIHRoZSB0eG5cbiAgICAgIHR4QnVpbGRlclxuICAgICAgICAudmFsaWRpdHkoe1xuICAgICAgICAgIGZpcnN0VmFsaWQ6IHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlcixcbiAgICAgICAgICBtYXhEdXJhdGlvbjogYmFzZWNvaW4uU1dFRVBfVFhOX0RVUkFUSU9OLFxuICAgICAgICB9KVxuICAgICAgICAucmVmZXJlbmNlQmxvY2sodGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpXG4gICAgICAgIC5zZW5kZXIoeyBhZGRyZXNzOiB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwIH0pO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uc2VuZGVyLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmJsb2NrTnVtYmVyLCB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucmVmZXJlbmNlQmxvY2ssIHRlc3REYXRhLndlc3RlbmRCbG9jay5oYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmdlbmVzaXNIYXNoLCBnZW5lc2lzSGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5zcGVjVmVyc2lvbiwgc3BlY1ZlcnNpb24pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ubm9uY2UsIG5vbmNlKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnRpcCwgMCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi50cmFuc2FjdGlvblZlcnNpb24sIHR4VmVyc2lvbik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5jaGFpbk5hbWUsIGNoYWluTmFtZSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5lcmFQZXJpb2QsIGJhc2Vjb2luLlNXRUVQX1RYTl9EVVJBVElPTik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdCdWlsZCBDb25zb2xpZGF0aW9uIFJlY292ZXJpZXM6JywgKCkgPT4ge1xuICAgIGNvbnN0IHNhbmRCb3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgY29uc3QgYmFzZUFkZHIgPSB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci53YWxsZXRBZGRyZXNzMDtcbiAgICBjb25zdCBub25jZSA9IDEyMztcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWNjb3VudEluZm9DQiA9IHNhbmRCb3guc3R1YihEb3QucHJvdG90eXBlLCAnZ2V0QWNjb3VudEluZm8nIGFzIGtleW9mIERvdCk7XG4gICAgICBhY2NvdW50SW5mb0NCLndpdGhBcmdzKHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MxKS5yZXNvbHZlcyh7XG4gICAgICAgIG5vbmNlOiBub25jZSxcbiAgICAgICAgZnJlZUJhbGFuY2U6IDEwMDAwMDAwMDAwLFxuICAgICAgfSk7XG4gICAgICBhY2NvdW50SW5mb0NCLndpdGhBcmdzKHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MyKS5yZXNvbHZlcyh7XG4gICAgICAgIG5vbmNlOiBub25jZSxcbiAgICAgICAgZnJlZUJhbGFuY2U6IDE1MTAwMDAwMDAwMDAsXG4gICAgICB9KTtcbiAgICAgIGFjY291bnRJbmZvQ0Iud2l0aEFyZ3ModGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczMpLnJlc29sdmVzKHtcbiAgICAgICAgbm9uY2U6IG5vbmNlLFxuICAgICAgICBmcmVlQmFsYW5jZTogMTUxMDAwMDAwMDAwMCxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgaGVhZGVySW5mb0NCID0gc2FuZEJveC5zdHViKERvdC5wcm90b3R5cGUsICdnZXRIZWFkZXJJbmZvJyBhcyBrZXlvZiBEb3QpO1xuICAgICAgaGVhZGVySW5mb0NCLnJlc29sdmVzKHtcbiAgICAgICAgaGVhZGVyTnVtYmVyOiB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIsXG4gICAgICAgIGhlYWRlckhhc2g6IHRlc3REYXRhLndlc3RlbmRCbG9jay5oYXNoLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBnZXRGZWVDQiA9IHNhbmRCb3guc3R1YihEb3QucHJvdG90eXBlLCAnZ2V0RmVlJyBhcyBrZXlvZiBEb3QpO1xuICAgICAgZ2V0RmVlQ0Iud2l0aEFyZ3MoYmFzZUFkZHIsIHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MxLCAxMDAwMDAwMDAwMCkucmVzb2x2ZXMoMTU3ODM4MTI4NTYpO1xuICAgICAgZ2V0RmVlQ0Iud2l0aEFyZ3MoYmFzZUFkZHIsIHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MyLCAxNTEwMDAwMDAwMDAwKS5yZXNvbHZlcygxNTc4MzgxMjg1Nik7XG4gICAgICBnZXRGZWVDQi53aXRoQXJncyhiYXNlQWRkciwgdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczMsIDE1MTAwMDAwMDAwMDApLnJlc29sdmVzKDE1NzgzODEyODU2KTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kQm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIC8vIFRPRE8oQ09JTi05MTkpOiBGaXggZmFpbGluZyB0ZXN0XG4gICAgeGl0KCdzaG91bGQgYnVpbGQgc2lnbmVkIGNvbnNvbGlkYXRpb24gcmVjb3ZlcmllcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXJDb25zb2xpZGF0aW9ucyh7XG4gICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLnVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICBiaXRnb0tleTogdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAxLFxuICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDQsXG4gICAgICB9KTtcbiAgICAgIHJlcy5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICByZXMudHJhbnNhY3Rpb25zLmxlbmd0aC5zaG91bGQuZXF1YWwoMik7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRUaHJpY2UoYmFzZWNvaW4uZ2V0QWNjb3VudEluZm8pO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkVHdpY2UoYmFzZWNvaW4uZ2V0SGVhZGVySW5mbyk7XG5cbiAgICAgIGNvbnN0IHR4bjEgPSByZXMudHJhbnNhY3Rpb25zWzBdO1xuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NjYW5JbmRleCcpO1xuICAgICAgdHhuMS5zY2FuSW5kZXguc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgLy8gZGVzZXJpYWxpemUgdGhlIHR4biBhbmQgdmVyaWZ5IHRoZSBmaWVsZHMgYXJlIHdoYXQgd2UgZXhwZWN0XG4gICAgICBjb25zdCB0eEJ1aWxkZXIxID0gYmFzZWNvaW4uZ2V0QnVpbGRlcigpLmZyb20odHhuMS5zZXJpYWxpemVkVHgpO1xuICAgICAgLy8gc29tZSBpbmZvcm1hdGlvbiBpc24ndCBkZXNlcmlhbGl6ZWQgYnkgdGhlIGZyb20gbWV0aG9kLCBzbyB3ZSB3aWxsXG4gICAgICAvLyBzdXBwbHkgaXQgYWdhaW4gaW4gb3JkZXIgdG8gcmUtYnVpbGQgdGhlIHR4blxuICAgICAgdHhCdWlsZGVyMVxuICAgICAgICAudmFsaWRpdHkoe1xuICAgICAgICAgIGZpcnN0VmFsaWQ6IHRlc3REYXRhLndlc3RlbmRCbG9jay5ibG9ja051bWJlcixcbiAgICAgICAgICBtYXhEdXJhdGlvbjogYmFzZWNvaW4uTUFYX1ZBTElESVRZX0RVUkFUSU9OLFxuICAgICAgICB9KVxuICAgICAgICAucmVmZXJlbmNlQmxvY2sodGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpO1xuICAgICAgY29uc3QgdHgxID0gYXdhaXQgdHhCdWlsZGVyMS5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uMSA9IHR4MS50b0pzb24oKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5zZW5kZXIsIHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MyKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5ibG9ja051bWJlciwgdGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5yZWZlcmVuY2VCbG9jaywgdGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLmdlbmVzaXNIYXNoLCBnZW5lc2lzSGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEuc3BlY1ZlcnNpb24sIHNwZWNWZXJzaW9uKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5ub25jZSwgbm9uY2UpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLnRpcCwgMCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEudHJhbnNhY3Rpb25WZXJzaW9uLCB0eFZlcnNpb24pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLmNoYWluTmFtZSwgY2hhaW5OYW1lKTtcbiAgICAgIC8vIGVyYVBlcmlvZCB3aWxsIGFsd2F5cyByb3VuZCB0byB0aGUgbmV4dCB1cHBlciBwb3dlciBvZiAyIGZvciBhbnkgaW5wdXQgdmFsdWUsIGluIHRoaXMgY2FzZSAyNDAwLlxuICAgICAgLy8gNDA5NiBpcyB0aGUgXCJoaWdoZXN0XCIgdmFsdWUgeW91IGNhbiBzZXQsIGJ1dCB0aGUgdHhuIHN0aWxsIG1heSBmYWlsIGFmdGVyIDI0MDAgYmxvY2tzLlxuICAgICAgY29uc3QgZXJhUGVyaW9kID0gNDA5NjtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5lcmFQZXJpb2QsIGVyYVBlcmlvZCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEudG8sIGJhc2VBZGRyKTtcblxuICAgICAgcmVzLmxhc3RTY2FuSW5kZXguc2hvdWxkLmVxdWFsKDMpO1xuICAgICAgY29uc3QgdHhuMiA9IHJlcy50cmFuc2FjdGlvbnNbMV07XG4gICAgICB0eG4yLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICB0eG4yLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2NhbkluZGV4Jyk7XG4gICAgICB0eG4yLnNjYW5JbmRleC5zaG91bGQuZXF1YWwoMyk7XG4gICAgICAvLyBkZXNlcmlhbGl6ZSB0aGUgdHhuIGFuZCB2ZXJpZnkgdGhlIGZpZWxkcyBhcmUgd2hhdCB3ZSBleHBlY3RcbiAgICAgIGNvbnN0IHR4QnVpbGRlcjIgPSBiYXNlY29pbi5nZXRCdWlsZGVyKCkuZnJvbSh0eG4yLnNlcmlhbGl6ZWRUeCk7XG4gICAgICAvLyBzb21lIGluZm9ybWF0aW9uIGlzbid0IGRlc2VyaWFsaXplZCBieSB0aGUgZnJvbSBtZXRob2QsIHNvIHdlIHdpbGxcbiAgICAgIC8vIHN1cHBseSBpdCBhZ2FpbiBpbiBvcmRlciB0byByZS1idWlsZCB0aGUgdHhuXG4gICAgICB0eEJ1aWxkZXIyXG4gICAgICAgIC52YWxpZGl0eSh7XG4gICAgICAgICAgZmlyc3RWYWxpZDogdGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyLFxuICAgICAgICAgIG1heER1cmF0aW9uOiBiYXNlY29pbi5NQVhfVkFMSURJVFlfRFVSQVRJT04sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZWZlcmVuY2VCbG9jayh0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suaGFzaCk7XG4gICAgICBjb25zdCB0eDIgPSBhd2FpdCB0eEJ1aWxkZXIyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eEpzb24yID0gdHgyLnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLnNlbmRlciwgdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczMpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLmJsb2NrTnVtYmVyLCB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLnJlZmVyZW5jZUJsb2NrLCB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suaGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIuZ2VuZXNpc0hhc2gsIGdlbmVzaXNIYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5zcGVjVmVyc2lvbiwgc3BlY1ZlcnNpb24pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLm5vbmNlLCBub25jZSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIudGlwLCAwKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi50cmFuc2FjdGlvblZlcnNpb24sIHR4VmVyc2lvbik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIuY2hhaW5OYW1lLCBjaGFpbk5hbWUpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLmVyYVBlcmlvZCwgZXJhUGVyaW9kKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi50bywgYmFzZUFkZHIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBidWlsZCB1bnNpZ25lZCBjb25zb2xpZGF0aW9uIHJlY292ZXJpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyQ29uc29saWRhdGlvbnMoe1xuICAgICAgICBiaXRnb0tleTogdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAxLFxuICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDQsXG4gICAgICB9KTtcbiAgICAgIHJlcy5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICByZXMudHhSZXF1ZXN0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkVGhyaWNlKGJhc2Vjb2luLmdldEFjY291bnRJbmZvKTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxlZFR3aWNlKGJhc2Vjb2luLmdldEhlYWRlckluZm8pO1xuXG4gICAgICBjb25zdCB0eG4xID0gcmVzLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHg7XG4gICAgICB0eG4xLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICB0eG4xLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2lnbmFibGVIZXgnKTtcbiAgICAgIHR4bjEuc2hvdWxkLmhhc093blByb3BlcnR5KCdzY2FuSW5kZXgnKTtcbiAgICAgIHR4bjEuc2NhbkluZGV4LnNob3VsZC5lcXVhbCgyKTtcbiAgICAgIHR4bjEuc2hvdWxkLmhhc093blByb3BlcnR5KCdjb2luJyk7XG4gICAgICB0eG4xLmNvaW4uc2hvdWxkLmVxdWFsKCd0ZG90Jyk7XG4gICAgICB0eG4xLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnZGVyaXZhdGlvblBhdGgnKTtcbiAgICAgIHR4bjEuZGVyaXZhdGlvblBhdGguc2hvdWxkLmVxdWFsKCdtLzInKTtcblxuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2NvaW5TcGVjaWZpYycpO1xuICAgICAgY29uc3QgY29pblNwZWNpZmljMSA9IHR4bjEuY29pblNwZWNpZmljO1xuICAgICAgY29pblNwZWNpZmljMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2NvbW1vbktleWNoYWluJyk7XG4gICAgICBjb2luU3BlY2lmaWMxLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnZmlyc3RWYWxpZCcpO1xuICAgICAgY29pblNwZWNpZmljMS5maXJzdFZhbGlkLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIpO1xuICAgICAgY29pblNwZWNpZmljMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ21heER1cmF0aW9uJyk7XG4gICAgICBjb2luU3BlY2lmaWMxLm1heER1cmF0aW9uLnNob3VsZC5lcXVhbChiYXNlY29pbi5NQVhfVkFMSURJVFlfRFVSQVRJT04pO1xuXG4gICAgICAvLyBkZXNlcmlhbGl6ZSB0aGUgdHhuIGFuZCB2ZXJpZnkgdGhlIGZpZWxkcyBhcmUgd2hhdCB3ZSBleHBlY3RcbiAgICAgIGNvbnN0IHR4QnVpbGRlcjEgPSBiYXNlY29pbi5nZXRCdWlsZGVyKCkuZnJvbSh0eG4xLnNlcmlhbGl6ZWRUeCk7XG4gICAgICAvLyBzb21lIGluZm9ybWF0aW9uIGlzbid0IGRlc2VyaWFsaXplZCBieSB0aGUgZnJvbSBtZXRob2QsIHNvIHdlIHdpbGxcbiAgICAgIC8vIHN1cHBseSBpdCBhZ2FpbiBpbiBvcmRlciB0byByZS1idWlsZCB0aGUgdHhuXG4gICAgICB0eEJ1aWxkZXIxXG4gICAgICAgIC52YWxpZGl0eSh7XG4gICAgICAgICAgZmlyc3RWYWxpZDogdGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyLFxuICAgICAgICAgIG1heER1cmF0aW9uOiBiYXNlY29pbi5NQVhfVkFMSURJVFlfRFVSQVRJT04sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZWZlcmVuY2VCbG9jayh0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suaGFzaClcbiAgICAgICAgLnNlbmRlcih7IGFkZHJlc3M6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MyIH0pO1xuICAgICAgY29uc3QgdHgxID0gYXdhaXQgdHhCdWlsZGVyMS5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uMSA9IHR4MS50b0pzb24oKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5zZW5kZXIsIHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MyKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5ibG9ja051bWJlciwgdGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5yZWZlcmVuY2VCbG9jaywgdGVzdERhdGEud2VzdGVuZEJsb2NrLmhhc2gpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLmdlbmVzaXNIYXNoLCBnZW5lc2lzSGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEuc3BlY1ZlcnNpb24sIHNwZWNWZXJzaW9uKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5ub25jZSwgbm9uY2UpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLnRpcCwgMCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEudHJhbnNhY3Rpb25WZXJzaW9uLCB0eFZlcnNpb24pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLmNoYWluTmFtZSwgY2hhaW5OYW1lKTtcbiAgICAgIC8vIGVyYVBlcmlvZCB3aWxsIGFsd2F5cyByb3VuZCB0byB0aGUgbmV4dCB1cHBlciBwb3dlciBvZiAyIGZvciBhbnkgaW5wdXQgdmFsdWUsIGluIHRoaXMgY2FzZSAyNDAwLlxuICAgICAgLy8gNDA5NiBpcyB0aGUgXCJoaWdoZXN0XCIgdmFsdWUgeW91IGNhbiBzZXQsIGJ1dCB0aGUgdHhuIHN0aWxsIG1heSBmYWlsIGFmdGVyIDI0MDAgYmxvY2tzLlxuICAgICAgY29uc3QgZXJhUGVyaW9kID0gNDA5NjtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5lcmFQZXJpb2QsIGVyYVBlcmlvZCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEudG8sIGJhc2VBZGRyKTtcblxuICAgICAgY29uc3QgdHhuMiA9IHJlcy50eFJlcXVlc3RzWzFdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4O1xuICAgICAgdHhuMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgdHhuMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NpZ25hYmxlSGV4Jyk7XG4gICAgICB0eG4yLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2NhbkluZGV4Jyk7XG4gICAgICB0eG4yLnNjYW5JbmRleC5zaG91bGQuZXF1YWwoMyk7XG4gICAgICB0eG4yLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnY29pbicpO1xuICAgICAgdHhuMi5jb2luLnNob3VsZC5lcXVhbCgndGRvdCcpO1xuICAgICAgdHhuMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2Rlcml2YXRpb25QYXRoJyk7XG4gICAgICB0eG4yLmRlcml2YXRpb25QYXRoLnNob3VsZC5lcXVhbCgnbS8zJyk7XG5cbiAgICAgIHR4bjIuc2hvdWxkLmhhc093blByb3BlcnR5KCdjb2luU3BlY2lmaWMnKTtcbiAgICAgIGNvbnN0IGNvaW5TcGVjaWZpYzIgPSB0eG4yLmNvaW5TcGVjaWZpYztcbiAgICAgIGNvaW5TcGVjaWZpYzIuc2hvdWxkLmhhc093blByb3BlcnR5KCdjb21tb25LZXljaGFpbicpO1xuICAgICAgY29pblNwZWNpZmljMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2ZpcnN0VmFsaWQnKTtcbiAgICAgIGNvaW5TcGVjaWZpYzIuZmlyc3RWYWxpZC5zaG91bGQuZXF1YWwodGVzdERhdGEud2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyKTtcbiAgICAgIGNvaW5TcGVjaWZpYzIuc2hvdWxkLmhhc093blByb3BlcnR5KCdtYXhEdXJhdGlvbicpO1xuICAgICAgY29pblNwZWNpZmljMi5tYXhEdXJhdGlvbi5zaG91bGQuZXF1YWwoYmFzZWNvaW4uTUFYX1ZBTElESVRZX0RVUkFUSU9OKTtcbiAgICAgIGNvaW5TcGVjaWZpYzIuc2hvdWxkLmhhc093blByb3BlcnR5KCdjb21tb25LZXljaGFpbicpO1xuICAgICAgY29pblNwZWNpZmljMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2xhc3RTY2FuSW5kZXgnKTtcbiAgICAgIGNvaW5TcGVjaWZpYzIubGFzdFNjYW5JbmRleC5zaG91bGQuZXF1YWwoMyk7XG5cbiAgICAgIC8vIGRlc2VyaWFsaXplIHRoZSB0eG4gYW5kIHZlcmlmeSB0aGUgZmllbGRzIGFyZSB3aGF0IHdlIGV4cGVjdFxuICAgICAgY29uc3QgdHhCdWlsZGVyMiA9IGJhc2Vjb2luLmdldEJ1aWxkZXIoKS5mcm9tKHR4bjIuc2VyaWFsaXplZFR4KTtcbiAgICAgIC8vIHNvbWUgaW5mb3JtYXRpb24gaXNuJ3QgZGVzZXJpYWxpemVkIGJ5IHRoZSBmcm9tIG1ldGhvZCwgc28gd2Ugd2lsbFxuICAgICAgLy8gc3VwcGx5IGl0IGFnYWluIGluIG9yZGVyIHRvIHJlLWJ1aWxkIHRoZSB0eG5cbiAgICAgIHR4QnVpbGRlcjJcbiAgICAgICAgLnZhbGlkaXR5KHtcbiAgICAgICAgICBmaXJzdFZhbGlkOiB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIsXG4gICAgICAgICAgbWF4RHVyYXRpb246IGJhc2Vjb2luLk1BWF9WQUxJRElUWV9EVVJBVElPTixcbiAgICAgICAgfSlcbiAgICAgICAgLnJlZmVyZW5jZUJsb2NrKHRlc3REYXRhLndlc3RlbmRCbG9jay5oYXNoKVxuICAgICAgICAuc2VuZGVyKHsgYWRkcmVzczogdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczMgfSk7XG4gICAgICBjb25zdCB0eDIgPSBhd2FpdCB0eEJ1aWxkZXIyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eEpzb24yID0gdHgyLnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLnNlbmRlciwgdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczMpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLmJsb2NrTnVtYmVyLCB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLnJlZmVyZW5jZUJsb2NrLCB0ZXN0RGF0YS53ZXN0ZW5kQmxvY2suaGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIuZ2VuZXNpc0hhc2gsIGdlbmVzaXNIYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5zcGVjVmVyc2lvbiwgc3BlY1ZlcnNpb24pO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLm5vbmNlLCBub25jZSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIudGlwLCAwKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi50cmFuc2FjdGlvblZlcnNpb24sIHR4VmVyc2lvbik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIuY2hhaW5OYW1lLCBjaGFpbk5hbWUpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLmVyYVBlcmlvZCwgZXJhUGVyaW9kKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi50bywgYmFzZUFkZHIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBza2lwIGJ1aWxkaW5nIGNvbnNvbGlkYXRlIHRyYW5zYWN0aW9uIGlmIGJhbGFuY2UgaXMgZXF1YWwgdG8gemVybycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyQ29uc29saWRhdGlvbnMoe1xuICAgICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLnVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLmJpdGdvS2V5LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgc3RhcnRpbmdTY2FuSW5kZXg6IDEsXG4gICAgICAgICAgZW5kaW5nU2NhbkluZGV4OiAyLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnRGlkIG5vdCBmaW5kIGFuIGFkZHJlc3Mgd2l0aCBmdW5kcyB0byByZWNvdmVyJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIHN0YXJ0aW5nU2NhbkluZGV4IGlzIG5vdCBnZSB0byAxJywgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXJDb25zb2xpZGF0aW9ucyh7XG4gICAgICAgICAgdXNlcktleTogdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIudXNlcktleSxcbiAgICAgICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgICBiaXRnb0tleTogdGVzdERhdGEuY29uc29saWRhdGlvbldyd1VzZXIuYml0Z29LZXksXG4gICAgICAgICAgc3RhcnRpbmdTY2FuSW5kZXg6IC0xLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnSW52YWxpZCBzdGFydGluZyBvciBlbmRpbmcgaW5kZXggdG8gc2NhbiBmb3IgYWRkcmVzc2VzLiBzdGFydGluZ1NjYW5JbmRleDogLTEsIGVuZGluZ1NjYW5JbmRleDogMTkuJ1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiBzY2FuIGZhY3RvciBpcyB0b28gaGlnaCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyQ29uc29saWRhdGlvbnMoe1xuICAgICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLnVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS5jb25zb2xpZGF0aW9uV3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLmNvbnNvbGlkYXRpb25XcndVc2VyLmJpdGdvS2V5LFxuICAgICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAxLFxuICAgICAgICAgIGVuZGluZ1NjYW5JbmRleDogMzAwLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnSW52YWxpZCBzdGFydGluZyBvciBlbmRpbmcgaW5kZXggdG8gc2NhbiBmb3IgYWRkcmVzc2VzLiBzdGFydGluZ1NjYW5JbmRleDogMSwgZW5kaW5nU2NhbkluZGV4OiAzMDAuJ1xuICAgICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUmVjb3ZlciBUcmFuc2FjdGlvbiBGYWlsdXJlczonLCAoKSA9PiB7XG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICBjb25zdCBkZXN0QWRkciA9IHRlc3REYXRhLmFjY291bnRzLmFjY291bnQxLmFkZHJlc3M7XG4gICAgY29uc3Qgbm9uY2UgPSAxMjM7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFjY291bnRJbmZvQ0IgPSBzYW5kQm94LnN0dWIoRG90LnByb3RvdHlwZSwgJ2dldEFjY291bnRJbmZvJyBhcyBrZXlvZiBEb3QpO1xuICAgICAgYWNjb3VudEluZm9DQi5yZXNvbHZlcyh7XG4gICAgICAgIG5vbmNlOiBub25jZSxcbiAgICAgICAgZnJlZUJhbGFuY2U6IDAsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kQm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byByZWNvdmVyIGR1ZSB0byBub3QgZmluZGluZyBhbiBhZGRyZXNzIHdpdGggZnVuZHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3Zlcih7XG4gICAgICAgICAgdXNlcktleTogdGVzdERhdGEud3J3VXNlci51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEud3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLndyd1VzZXIuYml0Z29LZXksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEud3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RBZGRyLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnRGlkIG5vdCBmaW5kIGFkZHJlc3Mgd2l0aCBmdW5kcyB0byByZWNvdmVyJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdWZXJpZnkgVHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgYWRkcmVzczEgPSAnNUdlNTlxUm5aYThieHloVkZFNkJEb1kza3VoU3JOVkVUUnhYWUx0eTFIaDZYVGFmJztcbiAgICBjb25zdCBhZGRyZXNzMiA9ICc1RGlNTFp1Z21jS0VIM2lnUFpQMzY3RnF1bW1aa1dlVzVaNnpEQ0hMZnhSam5QWGUnO1xuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgdHhQcmVidWlsZCB3aXRoIG1vcmUgdGhhbiBvbmUgcmVjaXBpZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9LFxuICAgICAgICAgIHsgYW1vdW50OiAnMjUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgYHRkb3QgZG9lc24ndCBzdXBwb3J0IHNlbmRpbmcgdG8gbW9yZSB0aGFuIDEgZGVzdGluYXRpb24gYWRkcmVzcyB3aXRoaW4gYSBzaW5nbGUgdHJhbnNhY3Rpb24uIFRyeSBhZ2FpbiwgdXNpbmcgb25seSBhIHNpbmdsZSByZWNpcGllbnQuYFxuICAgICAgICApO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19
|