@bitgo-beta/sdk-coin-dot 2.2.8-beta.132 → 2.2.8-beta.1321

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