@bitgo-beta/sdk-coin-iota 1.0.1-beta.34 → 1.0.1-beta.340

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 (69) hide show
  1. package/README.md +1 -1
  2. package/dist/src/iota.d.ts +130 -23
  3. package/dist/src/iota.d.ts.map +1 -1
  4. package/dist/src/iota.js +280 -46
  5. package/dist/src/lib/constants.d.ts +59 -6
  6. package/dist/src/lib/constants.d.ts.map +1 -1
  7. package/dist/src/lib/constants.js +76 -8
  8. package/dist/src/lib/iface.d.ts +174 -2
  9. package/dist/src/lib/iface.d.ts.map +1 -1
  10. package/dist/src/lib/iface.js +1 -1
  11. package/dist/src/lib/index.d.ts +1 -0
  12. package/dist/src/lib/index.d.ts.map +1 -1
  13. package/dist/src/lib/index.js +4 -2
  14. package/dist/src/lib/keyPair.d.ts +100 -6
  15. package/dist/src/lib/keyPair.d.ts.map +1 -1
  16. package/dist/src/lib/keyPair.js +103 -10
  17. package/dist/src/lib/transaction.d.ts +175 -5
  18. package/dist/src/lib/transaction.d.ts.map +1 -1
  19. package/dist/src/lib/transaction.js +390 -6
  20. package/dist/src/lib/transactionBuilder.d.ts +109 -9
  21. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  22. package/dist/src/lib/transactionBuilder.js +200 -14
  23. package/dist/src/lib/transactionBuilderFactory.d.ts +98 -2
  24. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
  25. package/dist/src/lib/transactionBuilderFactory.js +132 -5
  26. package/dist/src/lib/transferBuilder.d.ts +52 -2
  27. package/dist/src/lib/transferBuilder.d.ts.map +1 -1
  28. package/dist/src/lib/transferBuilder.js +86 -3
  29. package/dist/src/lib/transferTransaction.d.ts +124 -0
  30. package/dist/src/lib/transferTransaction.d.ts.map +1 -0
  31. package/dist/src/lib/transferTransaction.js +341 -0
  32. package/dist/src/lib/utils.d.ts +108 -7
  33. package/dist/src/lib/utils.d.ts.map +1 -1
  34. package/dist/src/lib/utils.js +146 -11
  35. package/dist/test/resources/iota.d.ts +35 -0
  36. package/dist/test/resources/iota.d.ts.map +1 -0
  37. package/dist/test/resources/iota.js +93 -0
  38. package/dist/test/unit/helpers/testHelpers.d.ts +57 -0
  39. package/dist/test/unit/helpers/testHelpers.d.ts.map +1 -0
  40. package/dist/test/unit/helpers/testHelpers.js +176 -0
  41. package/dist/test/unit/index.d.ts +2 -0
  42. package/dist/test/unit/index.d.ts.map +1 -0
  43. package/dist/test/unit/index.js +16 -0
  44. package/dist/test/unit/iota.d.ts +2 -0
  45. package/dist/test/unit/iota.d.ts.map +1 -0
  46. package/dist/test/unit/iota.js +498 -0
  47. package/dist/test/unit/keyPair.d.ts +2 -0
  48. package/dist/test/unit/keyPair.d.ts.map +1 -0
  49. package/dist/test/unit/keyPair.js +108 -0
  50. package/dist/test/unit/transactionBuilder/transactionBuilder.d.ts +2 -0
  51. package/dist/test/unit/transactionBuilder/transactionBuilder.d.ts.map +1 -0
  52. package/dist/test/unit/transactionBuilder/transactionBuilder.js +188 -0
  53. package/dist/test/unit/transactionBuilder/transactionBuilderFactory.d.ts +2 -0
  54. package/dist/test/unit/transactionBuilder/transactionBuilderFactory.d.ts.map +1 -0
  55. package/dist/test/unit/transactionBuilder/transactionBuilderFactory.js +178 -0
  56. package/dist/test/unit/transactionBuilder/transferBuilder.d.ts +2 -0
  57. package/dist/test/unit/transactionBuilder/transferBuilder.d.ts.map +1 -0
  58. package/dist/test/unit/transactionBuilder/transferBuilder.js +438 -0
  59. package/dist/test/unit/transferTransaction.d.ts +2 -0
  60. package/dist/test/unit/transferTransaction.d.ts.map +1 -0
  61. package/dist/test/unit/transferTransaction.js +218 -0
  62. package/dist/test/unit/utils.d.ts +2 -0
  63. package/dist/test/unit/utils.d.ts.map +1 -0
  64. package/dist/test/unit/utils.js +252 -0
  65. package/dist/tsconfig.tsbuildinfo +1 -0
  66. package/package.json +16 -10
  67. package/.eslintignore +0 -5
  68. package/.mocharc.yml +0 -8
  69. package/CHANGELOG.md +0 -28
@@ -0,0 +1,498 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const should_1 = __importDefault(require("should"));
40
+ const sdk_test_1 = require("@bitgo-beta/sdk-test");
41
+ const sdk_api_1 = require("@bitgo-beta/sdk-api");
42
+ const src_1 = require("../../src");
43
+ const assert_1 = __importDefault(require("assert"));
44
+ const statics_1 = require("@bitgo-beta/statics");
45
+ const testData = __importStar(require("../resources/iota"));
46
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
47
+ const testHelpers_1 = require("./helpers/testHelpers");
48
+ describe('IOTA:', function () {
49
+ let bitgo;
50
+ let basecoin;
51
+ before(function () {
52
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
53
+ bitgo.safeRegister('iota', src_1.Iota.createInstance);
54
+ bitgo.safeRegister('tiota', src_1.Iota.createInstance);
55
+ bitgo.initializeTestVars();
56
+ basecoin = bitgo.coin('tiota');
57
+ });
58
+ it('should return the right info', function () {
59
+ const iota = bitgo.coin('iota');
60
+ const tiota = bitgo.coin('tiota');
61
+ const iotaStatics = statics_1.coins.get('iota');
62
+ const tiotaStatics = statics_1.coins.get('tiota');
63
+ iota.getChain().should.equal('iota');
64
+ iota.getFamily().should.equal('iota');
65
+ iota.getFullName().should.equal('Iota');
66
+ iota.getBaseFactor().should.equal(1e9);
67
+ tiota.getChain().should.equal('tiota');
68
+ tiota.getFamily().should.equal('iota');
69
+ tiota.getFullName().should.equal('Testnet Iota');
70
+ tiota.getBaseFactor().should.equal(1e9);
71
+ iotaStatics.gasTankLowBalanceAlertFactor.should.equal(80);
72
+ tiotaStatics.gasTankLowBalanceAlertFactor.should.equal(80);
73
+ iotaStatics.gasTankMinBalanceRecommendationFactor.should.equal(200);
74
+ tiotaStatics.gasTankMinBalanceRecommendationFactor.should.equal(200);
75
+ });
76
+ it('is valid pub', function () {
77
+ // with 0x prefix
78
+ basecoin.isValidPub('0x9b4e96086d111500259f9b38680b0509a405c1904da18976455a20c691d3bb07').should.equal(false);
79
+ // without 0x prefix
80
+ basecoin.isValidPub('9b4e96086d111500259f9b38680b0509a405c1904da18976455a20c691d3bb07').should.equal(true);
81
+ });
82
+ describe('Address Validation', () => {
83
+ let keychains;
84
+ let commonKeychain;
85
+ before(function () {
86
+ commonKeychain =
87
+ '19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781';
88
+ keychains = [
89
+ {
90
+ id: '6424c353eaf78d000766e95949868468',
91
+ source: 'user',
92
+ type: 'tss',
93
+ commonKeychain: '19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781',
94
+ encryptedPrv: '{"iv":"cZd5i7L4RxtwrALW2rK7UA==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"5zgoH1Bd3Fw=","ct":"9vVlnXFRtrM9FVEo+d2chbGHlM9lFZemueBuAs3BIkPo33Fo7jzwwNK/kIWkEyg+NmEBd5IaqAS157nvvvwzzsmMWlQdUz9qbmXNv3pg987cXFR08exS+4uhwP1YNOjJTRvRNcO9ZqHb46d4fmyJ/yC9/susCge7r/EsbaN5C3afv1dzybuq912FwaQElZLYYp5BICudFOMZ9k0UDMfKM/PMDkH7WexoGHr9GKq/bgCH2B39TZZyHKU6Uy47lXep2s6h0DrMwHOrnmiL3DZjOj88Ynvphlzxuo4eOlD2UHia2+nvIaISYs29Pr0DAvREutchvcBpExj1kWWPv7hQYrv8F0NAdatsbWl3w+xKyfiMKo1USlrwyJviypGtQtXOJyw0XPN0rv2+L5lW8BbjpzHfYYN13fJTedlGTFhhkzVtbbPAKE02kx7zCJcjYaiexdSTsrDLScYNT9/Jhdt27KpsooehwVohLfSKz4vbFfRu2MPZw3/+c/hfiJNgtz6esWbnxGrcE8U2IwPYCaK+Ghk4DcqWNIni59RI5B5kAsQOToII40qPN510uTgxBSPO7q7MHgkxdd4CqBq+ojr9j0P7oao8E5Y+CBDJrojDoCh1oCCDW9vo2dXlVcD8SIbw7U/9AfvEbA4xyE/5md1M7CIwLnWs2Ynv0YtaKoqhdS9x6FmHlMDhN/DKHinrwmowtrTT82fOkpO5g9saSmgU7Qy3gLt8t+VwdEyeFeQUKRSyci8qgqXQaZIg4+aXgaSOnlCFMtmB8ekYxEhTY5uzRfrNgS4s1QeqFBpNtUF+Ydi297pbVXnJoXAN+SVWd80GCx+yI2dpVC89k3rOWK9WeyqlnzuLJWp2RIOB9cdW8GFv/fN+QAJpYeVxOE4+nZDsKnsj8nKcg9t4Dlx1G6gLM1/Vq9YxNLbuzuRC0asUYvdMnoMvszmpm++TxndYisgNYscpZSoz7wvcazJNEPfhPVjEkd6tUUuN4GM35H0DmKCUQNT+a6B6hmHlTZvjxiyGAg5bY59hdjvJ+22QduazlEEC6LI3HrA7uK0TpplWzS1tCIFvTMUhj65DEZmNJ2+ZY9bQ4vsMf+DRR3OOG4t+DMlNfjOd3zNv3QoY95BjfWpryFwPzDq7bCP67JDsoj7j2TY5FRSrRkD77H0Ewlux2cWfjRTwcMHcdQxxuV0OP0aNjGDjybFN"}',
95
+ },
96
+ {
97
+ id: '6424c353eaf78d000766e96137d4404b',
98
+ source: 'backup',
99
+ type: 'tss',
100
+ commonKeychain: '19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781',
101
+ encryptedPrv: '{"iv":"vi0dPef/Rx7kG/pRySQi6Q==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"9efhQsiEvVs=","ct":"Gw6atvf6gxKzsjtl3xseipO3rAxp1mAz7Yu1ihFsi5/lf2vMZegApgZx+pyILFS9KKLHbNF3U6WgSYdrr2t4vzdLsXkH1WIxfHS+cd2C5N59yADZDnPJBT6pv/IRvaYelP0Ck3nIYQ2hSMm8op+VOWC/SzHeh7slYDqwEHTGan0Wigfvk1yRd7CCJTaEAomnc/4eFi2NY3X3gt/3opy9IAgknnwUFohn96EWpEQ0F6pbzH/Z8VF6gF+DUcrrByAxExUPnHQZiFk3YHU/vVV4FxBU/mVAE8xBsBn5ul5e5SUMPfc7TBuJWv4BByTNg9xDShF/91Yx2nbfUm5d9QmM8lpKgzzQvcK8POAPk87gRCuKnsGh5vNS0UppkHc+ocfzRQlGA6jze7QyyQO0rMj5Ly8kWjwk2vISvKYHYS1NR7VU549UIXo7NXjatunKSc3+IreoRUHIshiaLg6hl+pxCCuc0qQ43V0mdIfCjTN8gkGWLNk8R7tAGPz9jyapQPcPEGHgEz0ATIi6yMNWCsibS2eLiE1uVEJONoM4lk6FPl3Q2CHbW2MeEbqjY8hbaw18mNb2xSBH/Fwpiial+Tvi2imqgnCO4ZpO9bllKftZPcQy0stN+eGBlb5ufyflKkDSiChHYroGjEpmiFicdde48cJszF52uKNnf1q67fA9/S2FAHQab3EXojxH2Gbk+kkV2h/TYKFFZSWC3vi4e8mO+vjMUcR0AdsgPFyEIz0SCGuba3CnTLNdEuZwsauAeHkx2vUTnRgJPVgNeeuXmsVG76Sy2ggJHuals0Hj8U2Xda0qO1RuFfoCWfss9wn6HGRwPPkhSB/8oNguAqmRVGKkd8Zwt3IvrTd9fk0/rFFDJKGz7WyNHkYgUmNiGcItD12v0jx7FZ52EJzl3Av1RyJUQK18+8EYPh3SGiU9dt7VX0aF0uo6JouKhOeldUvMP+AugQz8fUclwTQsbboVg27Yxo0DyATVwThW5a56R6Qf5ZiQJluFuzs5y98rq0S5q046lE6o3vVmJpEdwjeSCJoET5CL4nTgkXyWvhm4eB8u/e66l3o0qbaSx8q9YYmT9EpRcl5TP4ThLBKETYdzVvg4exjQfektMatk5EyUpEIhZPXh5vXpJZesdfO9LJ8zTaHBsBjDPU7cdNgQMbebpataRi8A0el2/IJXl+E+olgAz5zC4i2O1Q=="}',
102
+ },
103
+ {
104
+ id: '6424c353eaf78d000766e9510b125fba',
105
+ source: 'bitgo',
106
+ type: 'tss',
107
+ commonKeychain: '19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781',
108
+ verifiedVssProof: true,
109
+ isBitGo: true,
110
+ },
111
+ ];
112
+ });
113
+ const addressValidationTests = [
114
+ {
115
+ address: '0xf941ae3cbe5645dccc15da8346b533f7f91f202089a5521653c062b2ff10b304',
116
+ valid: true,
117
+ description: 'valid 0x-prefixed address',
118
+ },
119
+ { address: '0x2959bfc3fdb7dc23fed8deba2fafb70f3e606a59', valid: false, description: 'old format address' },
120
+ { address: 'wrongaddress', valid: false, description: 'incorrectly formatted address' },
121
+ ];
122
+ addressValidationTests.forEach(({ address, valid, description }) => {
123
+ it(`should return ${valid} when validating ${description}`, function () {
124
+ basecoin.isValidAddress(address).should.equal(valid);
125
+ });
126
+ });
127
+ it('should return true for isWalletAddress with valid address for index 4', async function () {
128
+ const newAddress = '0x3f4b2a95d9b696989814f02f899cee491b4d600b1b918e979caec307af4b8dfc';
129
+ const index = 4;
130
+ const params = { commonKeychain, address: newAddress, index, keychains };
131
+ (await basecoin.isWalletAddress(params)).should.equal(true);
132
+ });
133
+ it('should throw error for isWalletAddress when keychains is missing', async function () {
134
+ const address = '0x2959bfc3fdb7dc23fed8deba2fafb70f3e606a59';
135
+ const index = 0;
136
+ const params = { commonKeychain, address, index };
137
+ await assert_1.default.rejects(async () => basecoin.isWalletAddress(params));
138
+ });
139
+ it('should throw error for isWalletAddress when new address is invalid', async function () {
140
+ const wrongAddress = 'badAddress';
141
+ const index = 0;
142
+ const params = { commonKeychain, address: wrongAddress, index };
143
+ await assert_1.default.rejects(async () => basecoin.isWalletAddress(params), {
144
+ message: `invalid address: ${wrongAddress}`,
145
+ });
146
+ });
147
+ });
148
+ describe('Transaction Methods', () => {
149
+ let factory;
150
+ before(function () {
151
+ factory = new src_1.TransactionBuilderFactory(statics_1.coins.get('tiota'));
152
+ });
153
+ describe('explainTransaction', () => {
154
+ it('should throw error for missing txHex', async function () {
155
+ await assert_1.default.rejects(async () => await basecoin.explainTransaction({ txHex: '' }), /missing required tx prebuild property txHex/);
156
+ });
157
+ it('should throw error for invalid transaction', async function () {
158
+ await assert_1.default.rejects(async () => await basecoin.explainTransaction({ txHex: 'invalidTxHex' }), /Failed to rebuild transaction/);
159
+ });
160
+ it('should call explainTransaction on transaction object', async function () {
161
+ const txBuilder = (0, testHelpers_1.createTransferBuilderWithGas)();
162
+ const tx = (await txBuilder.build());
163
+ const explanation = tx.explainTransaction();
164
+ explanation.should.have.property('id');
165
+ explanation.should.have.property('outputs');
166
+ explanation.should.have.property('outputAmount');
167
+ explanation.should.have.property('fee');
168
+ explanation.should.have.property('type');
169
+ explanation.type.should.equal(sdk_core_1.TransactionType.Send);
170
+ explanation.fee.fee.should.equal(testData.GAS_BUDGET.toString());
171
+ });
172
+ });
173
+ describe('verifyTransaction', () => {
174
+ it('should throw error for missing txHex', async function () {
175
+ await assert_1.default.rejects(async () => await basecoin.verifyTransaction({
176
+ txPrebuild: {},
177
+ txParams: { recipients: testData.recipients },
178
+ }), /missing required tx prebuild property txHex/);
179
+ });
180
+ it('should verify transaction with matching recipients', async function () {
181
+ const txBuilder = (0, testHelpers_1.createTransferBuilderWithGas)();
182
+ const tx = (await txBuilder.build());
183
+ const txHex = Buffer.from(await tx.toBroadcastFormat(), 'base64').toString('hex');
184
+ should_1.default.equal(await basecoin.verifyTransaction({
185
+ txPrebuild: { txHex },
186
+ txParams: { recipients: testData.recipients },
187
+ }), true);
188
+ });
189
+ it('should verify transaction with recipients containing extra fields', async function () {
190
+ const txBuilder = (0, testHelpers_1.createTransferBuilderWithGas)();
191
+ const tx = (await txBuilder.build());
192
+ const txHex = Buffer.from(await tx.toBroadcastFormat(), 'base64').toString('hex');
193
+ const recipientsWithExtraFields = testData.recipients.map((r) => ({
194
+ ...r,
195
+ extraField: 'should be ignored',
196
+ anotherField: 123,
197
+ }));
198
+ should_1.default.equal(await basecoin.verifyTransaction({
199
+ txPrebuild: { txHex },
200
+ txParams: { recipients: recipientsWithExtraFields },
201
+ }), true);
202
+ });
203
+ it('should detect mismatched recipients', async function () {
204
+ const txBuilder = (0, testHelpers_1.createTransferBuilderWithGas)();
205
+ const tx = (await txBuilder.build());
206
+ const txHex = Buffer.from(await tx.toBroadcastFormat(), 'base64').toString('hex');
207
+ const mismatchedRecipients = [
208
+ {
209
+ address: testData.addresses.validAddresses[2],
210
+ amount: '9999',
211
+ },
212
+ ];
213
+ await assert_1.default.rejects(async () => await basecoin.verifyTransaction({
214
+ txPrebuild: { txHex },
215
+ txParams: { recipients: mismatchedRecipients },
216
+ }), /Tx recipients does not match with expected txParams recipients/);
217
+ });
218
+ it('should verify transaction without recipients parameter', async function () {
219
+ const txBuilder = (0, testHelpers_1.createTransferBuilderWithGas)();
220
+ const tx = (await txBuilder.build());
221
+ const txHex = Buffer.from(await tx.toBroadcastFormat(), 'base64').toString('hex');
222
+ should_1.default.equal(await basecoin.verifyTransaction({
223
+ txPrebuild: { txHex },
224
+ txParams: {},
225
+ }), true);
226
+ });
227
+ });
228
+ describe('parseTransaction', () => {
229
+ it('should throw error for invalid transaction', async function () {
230
+ await assert_1.default.rejects(async () => await basecoin.parseTransaction({ txHex: 'invalidTxHex' }), /Failed to rebuild transaction/);
231
+ });
232
+ it('should parse transaction using JSON format', async function () {
233
+ const txBuilder = (0, testHelpers_1.createTransferBuilderWithGas)();
234
+ const tx = (await txBuilder.build());
235
+ const explanation = tx.explainTransaction();
236
+ explanation.should.have.property('id');
237
+ explanation.should.have.property('outputs');
238
+ explanation.should.have.property('outputAmount');
239
+ explanation.should.have.property('fee');
240
+ explanation.outputs.length.should.equal(testData.recipients.length);
241
+ explanation.outputs.forEach((output, index) => {
242
+ output.address.should.equal(testData.recipients[index].address);
243
+ output.amount.should.equal(testData.recipients[index].amount);
244
+ });
245
+ const totalAmount = testData.recipients.reduce((sum, r) => sum + Number(r.amount), 0);
246
+ explanation.outputAmount.should.equal(totalAmount.toString());
247
+ explanation.fee.fee.should.equal(testData.GAS_BUDGET.toString());
248
+ });
249
+ it('should parse transaction with single recipient', async function () {
250
+ const singleRecipient = [testData.recipients[0]];
251
+ const txBuilder = factory.getTransferBuilder();
252
+ txBuilder.sender(testData.sender.address);
253
+ txBuilder.recipients(singleRecipient);
254
+ txBuilder.paymentObjects(testData.paymentObjects);
255
+ txBuilder.gasData(testData.gasData);
256
+ const tx = (await txBuilder.build());
257
+ const explanation = tx.explainTransaction();
258
+ explanation.outputs.length.should.equal(1);
259
+ explanation.outputs[0].address.should.equal(singleRecipient[0].address);
260
+ explanation.outputs[0].amount.should.equal(singleRecipient[0].amount);
261
+ explanation.outputAmount.should.equal(singleRecipient[0].amount);
262
+ });
263
+ it('should parse transaction with multiple recipients', async function () {
264
+ const multipleRecipients = [
265
+ { address: testData.addresses.validAddresses[0], amount: '1000' },
266
+ { address: testData.addresses.validAddresses[1], amount: '2000' },
267
+ { address: testData.addresses.validAddresses[2], amount: '3000' },
268
+ ];
269
+ const txBuilder = factory.getTransferBuilder();
270
+ txBuilder.sender(testData.sender.address);
271
+ txBuilder.recipients(multipleRecipients);
272
+ txBuilder.paymentObjects(testData.paymentObjects);
273
+ txBuilder.gasData(testData.gasData);
274
+ const tx = (await txBuilder.build());
275
+ const explanation = tx.explainTransaction();
276
+ explanation.outputs.length.should.equal(3);
277
+ explanation.outputAmount.should.equal('6000');
278
+ });
279
+ });
280
+ describe('getSignablePayload', () => {
281
+ it('should get signable payload from transaction directly', async function () {
282
+ const txBuilder = (0, testHelpers_1.createTransferBuilderWithGas)();
283
+ const tx = (await txBuilder.build());
284
+ const signablePayload = tx.signablePayload;
285
+ signablePayload.should.be.instanceOf(Buffer);
286
+ signablePayload.length.should.equal(32);
287
+ });
288
+ it('should throw error for invalid transaction', async function () {
289
+ await assert_1.default.rejects(async () => await basecoin.getSignablePayload('invalidTxBase64'), /Failed to rebuild transaction/);
290
+ });
291
+ it('should generate consistent signable payload for identical transactions', async function () {
292
+ const txBuilder1 = (0, testHelpers_1.createTransferBuilderWithGas)();
293
+ const tx1 = (await txBuilder1.build());
294
+ const txBuilder2 = (0, testHelpers_1.createTransferBuilderWithGas)();
295
+ const tx2 = (await txBuilder2.build());
296
+ tx1.signablePayload.toString('hex').should.equal(tx2.signablePayload.toString('hex'));
297
+ });
298
+ it('should generate different signable payloads for different transactions', async function () {
299
+ const txBuilder1 = (0, testHelpers_1.createTransferBuilderWithGas)();
300
+ const tx1 = (await txBuilder1.build());
301
+ const differentRecipients = [{ address: testData.addresses.validAddresses[0], amount: '5000' }];
302
+ const txBuilder2 = factory.getTransferBuilder();
303
+ txBuilder2.sender(testData.sender.address);
304
+ txBuilder2.recipients(differentRecipients);
305
+ txBuilder2.paymentObjects(testData.paymentObjects);
306
+ txBuilder2.gasData(testData.gasData);
307
+ const tx2 = (await txBuilder2.build());
308
+ tx1.signablePayload.toString('hex').should.not.equal(tx2.signablePayload.toString('hex'));
309
+ });
310
+ it('should throw error when getting payload from simulate transaction', async function () {
311
+ const txBuilder = factory.getTransferBuilder();
312
+ txBuilder.sender(testData.sender.address);
313
+ txBuilder.recipients(testData.recipients);
314
+ txBuilder.paymentObjects(testData.paymentObjects);
315
+ const tx = (await txBuilder.build());
316
+ should_1.default.equal(tx.isSimulateTx, true);
317
+ (0, should_1.default)(() => tx.signablePayload).throwError('Cannot sign a simulate tx');
318
+ });
319
+ });
320
+ describe('setCoinSpecificFieldsInIntent', () => {
321
+ it('should set unspents in intent', function () {
322
+ const intent = {};
323
+ const params = {
324
+ unspents: [
325
+ { objectId: '0x123', version: '1', digest: 'abc' },
326
+ { objectId: '0x456', version: '2', digest: 'def' },
327
+ ],
328
+ };
329
+ basecoin.setCoinSpecificFieldsInIntent(intent, params);
330
+ intent.should.have.property('unspents');
331
+ intent.unspents.should.deepEqual(params.unspents);
332
+ });
333
+ it('should handle empty unspents', function () {
334
+ const intent = {};
335
+ const params = { unspents: [] };
336
+ basecoin.setCoinSpecificFieldsInIntent(intent, params);
337
+ intent.should.have.property('unspents');
338
+ intent.unspents.should.deepEqual([]);
339
+ });
340
+ it('should handle undefined unspents', function () {
341
+ const intent = {};
342
+ const params = {};
343
+ basecoin.setCoinSpecificFieldsInIntent(intent, params);
344
+ intent.should.have.property('unspents');
345
+ (intent.unspents === undefined).should.be.true();
346
+ });
347
+ });
348
+ describe('Transaction with Gas Sponsor', () => {
349
+ it('should build transaction with gas sponsor', async function () {
350
+ const txBuilder = (0, testHelpers_1.createTransferBuilderWithGas)();
351
+ txBuilder.gasSponsor(testData.gasSponsor.address);
352
+ const tx = (await txBuilder.build());
353
+ should_1.default.equal(tx.sender, testData.sender.address);
354
+ should_1.default.equal(tx.gasSponsor, testData.gasSponsor.address);
355
+ should_1.default.notEqual(tx.sender, tx.gasSponsor);
356
+ should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
357
+ });
358
+ it('should handle transaction where sender and gas sponsor are same', async function () {
359
+ const txBuilder = (0, testHelpers_1.createTransferBuilderWithGas)();
360
+ txBuilder.gasSponsor(testData.sender.address);
361
+ const tx = (await txBuilder.build());
362
+ should_1.default.equal(tx.sender, testData.sender.address);
363
+ should_1.default.equal(tx.gasSponsor, testData.sender.address);
364
+ });
365
+ });
366
+ describe('Transaction ID Consistency', () => {
367
+ it('should generate same ID for identical transactions', async function () {
368
+ const txBuilder1 = (0, testHelpers_1.createTransferBuilderWithGas)();
369
+ const tx1 = (await txBuilder1.build());
370
+ const txBuilder2 = (0, testHelpers_1.createTransferBuilderWithGas)();
371
+ const tx2 = (await txBuilder2.build());
372
+ should_1.default.equal(tx1.id, tx2.id);
373
+ });
374
+ it('should generate different IDs for different transactions', async function () {
375
+ const txBuilder1 = (0, testHelpers_1.createTransferBuilderWithGas)();
376
+ const tx1 = (await txBuilder1.build());
377
+ const differentRecipients = [{ address: testData.addresses.validAddresses[0], amount: '9999' }];
378
+ const txBuilder2 = factory.getTransferBuilder();
379
+ txBuilder2.sender(testData.sender.address);
380
+ txBuilder2.recipients(differentRecipients);
381
+ txBuilder2.paymentObjects(testData.paymentObjects);
382
+ txBuilder2.gasData(testData.gasData);
383
+ const tx2 = (await txBuilder2.build());
384
+ should_1.default.notEqual(tx1.id, tx2.id);
385
+ });
386
+ });
387
+ describe('Gas Configuration Edge Cases', () => {
388
+ it('should handle minimum gas values', async function () {
389
+ const minGasData = {
390
+ gasBudget: 1000,
391
+ gasPrice: 100,
392
+ gasPaymentObjects: [testData.gasPaymentObjects[0]],
393
+ };
394
+ const txBuilder = factory.getTransferBuilder();
395
+ txBuilder.sender(testData.sender.address);
396
+ txBuilder.recipients(testData.recipients);
397
+ txBuilder.paymentObjects(testData.paymentObjects);
398
+ txBuilder.gasData(minGasData);
399
+ const tx = (await txBuilder.build());
400
+ should_1.default.equal(tx.gasBudget, 1000);
401
+ should_1.default.equal(tx.gasPrice, 100);
402
+ should_1.default.equal(tx.gasPaymentObjects?.length, 1);
403
+ });
404
+ it('should handle large gas values', async function () {
405
+ const largeGasData = {
406
+ gasBudget: 50000000000, // 50 billion
407
+ gasPrice: 100000,
408
+ gasPaymentObjects: testData.gasPaymentObjects,
409
+ };
410
+ const txBuilder = factory.getTransferBuilder();
411
+ txBuilder.sender(testData.sender.address);
412
+ txBuilder.recipients(testData.recipients);
413
+ txBuilder.paymentObjects(testData.paymentObjects);
414
+ txBuilder.gasData(largeGasData);
415
+ const tx = (await txBuilder.build());
416
+ should_1.default.equal(tx.gasBudget, 50000000000);
417
+ should_1.default.equal(tx.gasPrice, 100000);
418
+ });
419
+ it('should return gas fee from transaction', async function () {
420
+ const txBuilder = (0, testHelpers_1.createTransferBuilderWithGas)();
421
+ const tx = (await txBuilder.build());
422
+ const fee = tx.getFee();
423
+ should_1.default.exist(fee);
424
+ should_1.default.equal(fee, testData.GAS_BUDGET.toString());
425
+ });
426
+ });
427
+ describe('Transaction State Management', () => {
428
+ it('should track simulate mode correctly', async function () {
429
+ // Build without gas data - should be simulate mode
430
+ const simulateBuilder = factory.getTransferBuilder();
431
+ simulateBuilder.sender(testData.sender.address);
432
+ simulateBuilder.recipients(testData.recipients);
433
+ simulateBuilder.paymentObjects(testData.paymentObjects);
434
+ const simulateTx = (await simulateBuilder.build());
435
+ should_1.default.equal(simulateTx.isSimulateTx, true);
436
+ // Build with gas data - should not be simulate mode
437
+ const realBuilder = factory.getTransferBuilder();
438
+ realBuilder.sender(testData.sender.address);
439
+ realBuilder.recipients(testData.recipients);
440
+ realBuilder.paymentObjects(testData.paymentObjects);
441
+ realBuilder.gasData(testData.gasData);
442
+ const realTx = (await realBuilder.build());
443
+ should_1.default.equal(realTx.isSimulateTx, false);
444
+ });
445
+ it('should handle canSign based on simulate mode', async function () {
446
+ // Simulate transaction cannot be signed
447
+ const simulateBuilder = factory.getTransferBuilder();
448
+ simulateBuilder.sender(testData.sender.address);
449
+ simulateBuilder.recipients(testData.recipients);
450
+ simulateBuilder.paymentObjects(testData.paymentObjects);
451
+ const simulateTx = (await simulateBuilder.build());
452
+ should_1.default.equal(simulateTx.canSign({}), false);
453
+ // Real transaction can be signed
454
+ const realBuilder = factory.getTransferBuilder();
455
+ realBuilder.sender(testData.sender.address);
456
+ realBuilder.recipients(testData.recipients);
457
+ realBuilder.paymentObjects(testData.paymentObjects);
458
+ realBuilder.gasData(testData.gasData);
459
+ const realTx = (await realBuilder.build());
460
+ should_1.default.equal(realTx.canSign({}), true);
461
+ });
462
+ it('should handle transaction type correctly', async function () {
463
+ const txBuilder = (0, testHelpers_1.createTransferBuilderWithGas)();
464
+ const tx = (await txBuilder.build());
465
+ should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
466
+ });
467
+ });
468
+ describe('Transaction Serialization Formats', () => {
469
+ it('should serialize to consistent broadcast format', async function () {
470
+ const txBuilder1 = (0, testHelpers_1.createTransferBuilderWithGas)();
471
+ const tx1 = (await txBuilder1.build());
472
+ const broadcast1 = await tx1.toBroadcastFormat();
473
+ const txBuilder2 = (0, testHelpers_1.createTransferBuilderWithGas)();
474
+ const tx2 = (await txBuilder2.build());
475
+ const broadcast2 = await tx2.toBroadcastFormat();
476
+ should_1.default.equal(broadcast1, broadcast2);
477
+ });
478
+ it('should produce valid base64 broadcast format', async function () {
479
+ const txBuilder = (0, testHelpers_1.createTransferBuilderWithGas)();
480
+ const tx = (await txBuilder.build());
481
+ const broadcast = await tx.toBroadcastFormat();
482
+ should_1.default.equal(typeof broadcast, 'string');
483
+ should_1.default.equal(/^[A-Za-z0-9+/]*={0,2}$/.test(broadcast), true);
484
+ should_1.default.equal(broadcast.length > 0, true);
485
+ const decoded = Buffer.from(broadcast, 'base64');
486
+ should_1.default.equal(decoded.length > 0, true);
487
+ });
488
+ it('should maintain JSON serialization consistency', async function () {
489
+ const txBuilder = (0, testHelpers_1.createTransferBuilderWithGas)();
490
+ const tx = (await txBuilder.build());
491
+ const json1 = tx.toJson();
492
+ const json2 = tx.toJson();
493
+ should_1.default.deepEqual(json1, json2);
494
+ });
495
+ });
496
+ });
497
+ });
498
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW90YS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvdW5pdC9pb3RhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsb0RBQTRCO0FBQzVCLG1EQUErRDtBQUMvRCxpREFBK0M7QUFDL0MsbUNBQWlGO0FBQ2pGLG9EQUE0QjtBQUM1QixpREFBZ0U7QUFDaEUsNERBQThDO0FBQzlDLG1EQUF1RDtBQUN2RCx1REFBcUU7QUFFckUsUUFBUSxDQUFDLE9BQU8sRUFBRTtJQUNoQixJQUFJLEtBQW1CLENBQUM7SUFDeEIsSUFBSSxRQUFRLENBQUM7SUFFYixNQUFNLENBQUM7UUFDTCxLQUFLLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsa0JBQVEsRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3RELEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLFVBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNoRCxLQUFLLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxVQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDakQsS0FBSyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDM0IsUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDakMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsOEJBQThCLEVBQUU7UUFDakMsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoQyxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2xDLE1BQU0sV0FBVyxHQUFHLGVBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUF1QixDQUFDO1FBQzVELE1BQU0sWUFBWSxHQUFHLGVBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxD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LElBQUksQ0FBQyxDQUFDO1lBQ3pDLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLGdEQUFnRCxFQUFFLEtBQUs7Z0JBQ3hELE1BQU0sU0FBUyxHQUFHLElBQUEsMENBQTRCLEdBQUUsQ0FBQztnQkFDakQsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBd0IsQ0FBQztnQkFDNUQsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUMxQixNQUFNLEtBQUssR0FBRyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBRTFCLGdCQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNqQyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCB7IFRlc3RCaXRHbywgVGVzdEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLXRlc3QnO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstYXBpJztcbmltcG9ydCB7IElvdGEsIFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnksIFRyYW5zZmVyVHJhbnNhY3Rpb24gfSBmcm9tICcuLi8uLi9zcmMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgY29pbnMsIEdhc1RhbmtBY2NvdW50Q29pbiB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0ICogYXMgdGVzdERhdGEgZnJvbSAnLi4vcmVzb3VyY2VzL2lvdGEnO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25UeXBlIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgY3JlYXRlVHJhbnNmZXJCdWlsZGVyV2l0aEdhcyB9IGZyb20gJy4vaGVscGVycy90ZXN0SGVscGVycyc7XG5cbmRlc2NyaWJlKCdJT1RBOicsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IGJpdGdvOiBUZXN0Qml0R29BUEk7XG4gIGxldCBiYXNlY29pbjtcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudjogJ21vY2snIH0pO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcignaW90YScsIElvdGEuY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcigndGlvdGEnLCBJb3RhLmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3Rpb3RhJyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmV0dXJuIHRoZSByaWdodCBpbmZvJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGlvdGEgPSBiaXRnby5jb2luKCdpb3RhJyk7XG4gICAgY29uc3QgdGlvdGEgPSBiaXRnby5jb2luKCd0aW90YScpO1xuICAgIGNvbnN0IGlvdGFTdGF0aWNzID0gY29pbnMuZ2V0KCdpb3RhJykgYXMgR2FzVGFua0FjY291bnRDb2luO1xuICAgIGNvbnN0IHRpb3RhU3RhdGljcyA9IGNvaW5zLmdldCgndGlvdGEnKSBhcyBHYXNUYW5rQWNjb3VudENvaW47XG5cbiAgICBpb3RhLmdldENoYWluKCkuc2hvdWxkLmVxdWFsKCdpb3RhJyk7XG4gICAgaW90YS5nZXRGYW1pbHkoKS5zaG91bGQuZXF1YWwoJ2lvdGEnKTtcbiAgICBpb3RhLmdldEZ1bGxOYW1lKCkuc2hvdWxkLmVxdWFsKCdJb3RhJyk7XG4gICAgaW90YS5nZXRCYXNlRmFjdG9yKCkuc2hvdWxkLmVxdWFsKDFlOSk7XG5cbiAgICB0aW90YS5nZXRDaGFpbigpLnNob3VsZC5lcXVhbCgndGlvdGEnKTtcbiAgICB0aW90YS5nZXRGYW1pbHkoKS5zaG91bGQuZXF1YWwoJ2lvdGEnKTtcbiAgICB0aW90YS5nZXRGdWxsTmFtZSgpLnNob3VsZC5lcXVhbCgnVGVzdG5ldCBJb3RhJyk7XG4gICAgdGlvdGEuZ2V0QmFzZUZhY3RvcigpLnNob3VsZC5lcXVhbCgxZTkpO1xuXG4gICAgaW90YVN0YXRpY3MuZ2FzVGFua0xvd0JhbGFuY2VBbGVydEZhY3Rvci5zaG91bGQuZXF1YWwoODApO1xuICAgIHRpb3RhU3RhdGljcy5nYXNUYW5rTG93QmFsYW5jZUFsZXJ0RmFjdG9yLnNob3VsZC5lcXVhbCg4MCk7XG4gICAgaW90YVN0YXRpY3MuZ2FzVGFua01pbkJhbGFuY2VSZWNvbW1lbmRhdGlvbkZhY3Rvci5zaG91bGQuZXF1YWwoMjAwKTtcbiAgICB0aW90YVN0YXRpY3MuZ2FzVGFua01pbkJhbGFuY2VSZWNvbW1lbmRhdGlvbkZhY3Rvci5zaG91bGQuZXF1YWwoMjAwKTtcbiAgfSk7XG5cbiAgaXQoJ2lzIHZhbGlkIHB1YicsIGZ1bmN0aW9uICgpIHtcbiAgICAvLyB3aXRoIDB4IHByZWZpeFxuICAgIGJhc2Vjb2luLmlzVmFsaWRQdWIoJzB4OWI0ZTk2MDg2ZDExMTUwMDI1OWY5YjM4NjgwYjA1MDlhNDA1YzE5MDRkYTE4OTc2NDU1YTIwYzY5MWQzYmIwNycpLnNob3VsZC5lcXVhbChmYWxzZSk7XG4gICAgLy8gd2l0aG91dCAweCBwcmVmaXhcbiAgICBiYXNlY29pbi5pc1ZhbGlkUHViKCc5YjRlOTYwODZkMTExNTAwMjU5ZjliMzg2ODBiMDUwOWE0MDVjMTkwNGRhMTg5NzY0NTVhMjBjNjkxZDNiYjA3Jykuc2hvdWxkLmVxdWFsKHRydWUpO1xuICB9KTtcblxuICBkZXNjcmliZSgnQWRkcmVzcyBWYWxpZGF0aW9uJywgKCkgPT4ge1xuICAgIGxldCBrZXljaGFpbnM7XG4gICAgbGV0IGNvbW1vbktleWNoYWluO1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbW1vbktleWNoYWluID1cbiAgICAgICAgJzE5YmRmZTJhNGI0OThhMDU1MTEzODEyMzVhODg5MmQ1NDI2NzgwN2M0YTNmNjU0ZTMxMGI5MzhiOGI0MjRmZjRhZGVkYmU5MmY0YzE0NmRlNjQxYzY3NTA4YTk2MTMyNGM4NTA0Y2RmOGUwYzBhY2JiNjhkNjEwNGNjY2NkNzgxJztcbiAgICAgIGtleWNoYWlucyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnNjQyNGMzNTNlYWY3OGQwMDA3NjZlOTU5NDk4Njg0NjgnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgJzE5YmRmZTJhNGI0OThhMDU1MTEzODEyMzVhODg5MmQ1NDI2NzgwN2M0YTNmNjU0ZTMxMGI5MzhiOGI0MjRmZjRhZGVkYmU5MmY0YzE0NmRlNjQxYzY3NTA4YTk2MTMyNGM4NTA0Y2RmOGUwYzBhY2JiNjhkNjEwNGNjY2NkNzgxJyxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6XG4gICAgICAgICAgICAne1wiaXZcIjpcImNaZDVpN0w0Unh0d3JBTFcycks3VUE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCI1emdvSDFCZDNGdz1cIixcImN0XCI6XCI5dlZsblhGUnRyTTlGVkVvK2QyY2hiR0hsTTlsRlplbXVlQnVBczNCSWtQbzMzRm83anp3d05LL2tJV2tFeWcrTm1FQmQ1SWFxQVMxNTdudnZ2d3p6c21NV2xRZFV6OXFibVhOdjNwZzk4N2NYRlIwOGV4Uys0dWh3UDFZTk9qSlRSdlJOY085WnFIYjQ2ZDRmbXlKL3lDOS9zdXNDZ2U3ci9Fc2JhTjVDM2FmdjFkenlidXE5MTJGd2FRRWxaTFlZcDVCSUN1ZEZPTVo5azBVRE1mS00vUE1Ea0g3V2V4b0dIcjlHS3EvYmdDSDJCMzlUWlp5SEtVNlV5NDdsWGVwMnM2aDBEck13SE9ybm1pTDNEWmpPajg4WW52cGhsenh1bzRlT2xEMlVIaWEyK252SWFJU1lzMjlQcjBEQXZSRXV0Y2h2Y0JwRXhqMWtXV1B2N2hRWXJ2OEYwTkFkYXRzYldsM3creEt5ZmlNS28xVVNscnd5SnZpeXBHdFF0WE9KeXcwWFBOMHJ2MitMNWxXOEJianB6SGZZWU4xM2ZKVGVkbEdURmhoa3pWdGJiUEFLRTAya3g3ekNKY2pZYWlleGRTVHNyRExTY1lOVDkvSmhkdDI3S3Bzb29laHdWb2hMZlNLejR2YkZmUnUyTVBadzMvK2MvaGZpSk5ndHo2ZXNXYm54R3JjRThVMkl3UFlDYUsrR2hrNERjcVdOSW5pNTlSSTVCNWtBc1FPVG9JSTQwcVBONTEwdVRneEJTUE83cTdNSGdreGRkNENxQnErb2pyOWowUDdvYW84RTVZK0NCREpyb2pEb0NoMW9DQ0RXOXZvMmRYbFZjRDhTSWJ3N1UvOUFmdkViQTR4eUUvNW1kMU03Q0l3TG5XczJZbnYwWXRhS29xaGRTOXg2Rm1IbE1EaE4vREtIaW5yd21vd3RyVFQ4MmZPa3BPNWc5c2FTbWdVN1F5M2dMdDh0K1Z3ZEV5ZUZlUVVLUlN5Y2k4cWdxWFFhWklnNCthWGdhU09ubENGTXRtQjhla1l4RWhUWTV1elJmck5nUzRzMVFlcUZCcE50VUYrWWRpMjk3cGJWWG5Kb1hBTitTVldkODBHQ3greUkyZHBWQzg5azNyT1dLOVdleXFsbnp1TEpXcDJSSU9COWNkVzhHRnYvZk4rUUFKcFllVnhPRTQrblpEc0tuc2o4bktjZzl0NERseDFHNmdMTTEvVnE5WXhOTGJ1enVSQzBhc1VZdmRNbm9NdnN6bXBtKytUeG5kWWlzZ05Zc2NwWlNvejd3dmNhekpORVBmaFBWakVrZDZ0VVV1TjRHTTM1SDBEbUtDVVFOVCthNkI2aG1IbFRadmp4aXlHQWc1Ylk1OWhkanZKKzIyUWR1YXpsRUVDNkxJM0hyQTd1SzBUcHBsV3pTMXRDSUZ2VE1VaGo2NURFWm1OSjIrWlk5YlE0dnNNZitEUlIzT09HNHQrRE1sTmZqT2Qzek52M1FvWTk1QmpmV3ByeUZ3UHpEcTdiQ1A2N0pEc29qN2oyVFk1RlJTclJrRDc3SDBFd2x1eDJjV2ZqUlR3Y01IY2RReHh1VjBPUDBhTmpHRGp5YkZOXCJ9JyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnNjQyNGMzNTNlYWY3OGQwMDA3NjZlOTYxMzdkNDQwNGInLFxuICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAnMTliZGZlMmE0YjQ5OGEwNTUxMTM4MTIzNWE4ODkyZDU0MjY3ODA3YzRhM2Y2NTRlMzEwYjkzOGI4YjQyNGZmNGFkZWRiZTkyZjRjMTQ2ZGU2NDFjNjc1MDhhOTYxMzI0Yzg1MDRjZGY4ZTBjMGFjYmI2OGQ2MTA0Y2NjY2Q3ODEnLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjpcbiAgICAgICAgICAgICd7XCJpdlwiOlwidmkwZFBlZi9SeDdrRy9wUnlTUWk2UT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIjllZmhRc2lFdlZzPVwiLFwiY3RcIjpcIkd3NmF0dmY2Z3hLenNqdGwzeHNlaXBPM3JBeHAxbUF6N1l1MWloRnNpNS9sZjJ2TVplZ0FwZ1p4K3B5SUxGUzlLS0xIYk5GM1U2V2dTWWRycjJ0NHZ6ZExzWGtIMVdJeGZIUytjZDJDNU41OXlBRFpEblBKQlQ2cHYvSVJ2YVllbFAwQ2szbklZUTJoU01tOG9wK1ZPV0MvU3pIZWg3c2xZRHF3RUhUR2FuMFdpZ2Z2azF5UmQ3Q0NKVGFFQW9tbmMvNGVGaTJOWTNYM2d0LzNvcHk5SUFna25ud1VGb2huOTZFV3BFUTBGNnBiekgvWjhWRjZnRitEVWNyckJ5QXhFeFVQbkhRWmlGazNZSFUvdlZWNEZ4QlUvbVZBRTh4QnNCbjV1bDVlNVNVTVBmYzdUQnVKV3Y0QkJ5VE5nOXhEU2hGLzkxWXgybmJmVW01ZDlRbU04bHBLZ3p6UXZjSzhQT0FQazg3Z1JDdUtuc0doNXZOUzBVcHBrSGMrb2NmelJRbEdBNmp6ZTdReXlRTzByTWo1THk4a1dqd2sydklTdktZSFlTMU5SN1ZVNTQ5VUlYbzdOWGphdHVuS1NjMytJcmVvUlVISXNoaWFMZzZobCtweENDdWMwcVE0M1YwbWRJZkNqVE44Z2tHV0xOazhSN3RBR1B6OWp5YXBRUGNQRUdIZ0V6MEFUSWk2eU1OV0NzaWJTMmVMaUUxdVZFSk9Ob000bGs2RlBsM1EyQ0hiVzJNZUVicWpZOGhiYXcxOG1OYjJ4U0JIL0Z3cGlpYWwrVHZpMmltcWduQ080WnBPOWJsbEtmdFpQY1F5MHN0TitlR0JsYjV1ZnlmbEtrRFNpQ2hIWXJvR2pFcG1pRmljZGRlNDhjSnN6RjUydUtObmYxcTY3ZkE5L1MyRkFIUWFiM0VYb2p4SDJHYmsra2tWMmgvVFlLRkZaU1dDM3ZpNGU4bU8rdmpNVWNSMEFkc2dQRnlFSXowU0NHdWJhM0NuVExOZEV1WndzYXVBZUhreDJ2VVRuUmdKUFZnTmVldVhtc1ZHNzZTeTJnZ0pIdWFsczBIajhVMlhkYTBxTzFSdUZmb0NXZnNzOXduNkhHUndQUGtoU0IvOG9OZ3VBcW1SVkdLa2Q4Wnd0M0l2clRkOWZrMC9yRkZESktHejdXeU5Ia1lnVW1OaUdjSXREMTJ2MGp4N0ZaNTJFSnpsM0F2MVJ5SlVRSzE4KzhFWVBoM1NHaVU5ZHQ3VlgwYUYwdW82Sm91S2hPZWxkVXZNUCtBdWdRejhmVWNsd1RRc2Jib1ZnMjdZeG8wRHlBVFZ3VGhXNWE1NlI2UWY1WmlRSmx1RnV6czV5OThycTBTNXEwNDZsRTZvM3ZWbUpwRWR3amVTQ0pvRVQ1Q0w0blRna1h5V3ZobTRlQjh1L2U2NmwzbzBxYmFTeDhxOVlZbVQ5RXBSY2w1VFA0VGhMQktFVFlkelZ2ZzRleGpRZmVrdE1hdGs1RXlVcEVJaFpQWGg1dlhwSlplc2RmTzlMSjh6VGFIQnNCakRQVTdjZE5nUU1iZWJwYXRhUmk4QTBlbDIvSUpYbCtFK29sZ0F6NXpDNGkyTzFRPT1cIn0nLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaWQ6ICc2NDI0YzM1M2VhZjc4ZDAwMDc2NmU5NTEwYjEyNWZiYScsXG4gICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgJzE5YmRmZTJhNGI0OThhMDU1MTEzODEyMzVhODg5MmQ1NDI2NzgwN2M0YTNmNjU0ZTMxMGI5MzhiOGI0MjRmZjRhZGVkYmU5MmY0YzE0NmRlNjQxYzY3NTA4YTk2MTMyNGM4NTA0Y2RmOGUwYzBhY2JiNjhkNjEwNGNjY2NkNzgxJyxcbiAgICAgICAgICB2ZXJpZmllZFZzc1Byb29mOiB0cnVlLFxuICAgICAgICAgIGlzQml0R286IHRydWUsXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgIH0pO1xuXG4gICAgY29uc3QgYWRkcmVzc1ZhbGlkYXRpb25UZXN0cyA9IFtcbiAgICAgIHtcbiAgICAgICAgYWRkcmVzczogJzB4Zjk0MWFlM2NiZTU2NDVkY2NjMTVkYTgzNDZiNTMzZjdmOTFmMjAyMDg5YTU1MjE2NTNjMDYyYjJmZjEwYjMwNCcsXG4gICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ3ZhbGlkIDB4LXByZWZpeGVkIGFkZHJlc3MnLFxuICAgICAgfSxcbiAgICAgIHsgYWRkcmVzczogJzB4Mjk1OWJmYzNmZGI3ZGMyM2ZlZDhkZWJhMmZhZmI3MGYzZTYwNmE1OScsIHZhbGlkOiBmYWxzZSwgZGVzY3JpcHRpb246ICdvbGQgZm9ybWF0IGFkZHJlc3MnIH0sXG4gICAgICB7IGFkZHJlc3M6ICd3cm9uZ2FkZHJlc3MnLCB2YWxpZDogZmFsc2UsIGRlc2NyaXB0aW9uOiAnaW5jb3JyZWN0bHkgZm9ybWF0dGVkIGFkZHJlc3MnIH0sXG4gICAgXTtcblxuICAgIGFkZHJlc3NWYWxpZGF0aW9uVGVzdHMuZm9yRWFjaCgoeyBhZGRyZXNzLCB2YWxpZCwgZGVzY3JpcHRpb24gfSkgPT4ge1xuICAgICAgaXQoYHNob3VsZCByZXR1cm4gJHt2YWxpZH0gd2hlbiB2YWxpZGF0aW5nICR7ZGVzY3JpcHRpb259YCwgZnVuY3Rpb24gKCkge1xuICAgICAgICBiYXNlY29pbi5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKS5zaG91bGQuZXF1YWwodmFsaWQpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBpc1dhbGxldEFkZHJlc3Mgd2l0aCB2YWxpZCBhZGRyZXNzIGZvciBpbmRleCA0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbmV3QWRkcmVzcyA9ICcweDNmNGIyYTk1ZDliNjk2OTg5ODE0ZjAyZjg5OWNlZTQ5MWI0ZDYwMGIxYjkxOGU5NzljYWVjMzA3YWY0YjhkZmMnO1xuICAgICAgY29uc3QgaW5kZXggPSA0O1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7IGNvbW1vbktleWNoYWluLCBhZGRyZXNzOiBuZXdBZGRyZXNzLCBpbmRleCwga2V5Y2hhaW5zIH07XG4gICAgICAoYXdhaXQgYmFzZWNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcykpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGlzV2FsbGV0QWRkcmVzcyB3aGVuIGtleWNoYWlucyBpcyBtaXNzaW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICcweDI5NTliZmMzZmRiN2RjMjNmZWQ4ZGViYTJmYWZiNzBmM2U2MDZhNTknO1xuICAgICAgY29uc3QgaW5kZXggPSAwO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7IGNvbW1vbktleWNoYWluLCBhZGRyZXNzLCBpbmRleCB9O1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gYmFzZWNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgaXNXYWxsZXRBZGRyZXNzIHdoZW4gbmV3IGFkZHJlc3MgaXMgaW52YWxpZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdyb25nQWRkcmVzcyA9ICdiYWRBZGRyZXNzJztcbiAgICAgIGNvbnN0IGluZGV4ID0gMDtcblxuICAgICAgY29uc3QgcGFyYW1zID0geyBjb21tb25LZXljaGFpbiwgYWRkcmVzczogd3JvbmdBZGRyZXNzLCBpbmRleCB9O1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gYmFzZWNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyksIHtcbiAgICAgICAgbWVzc2FnZTogYGludmFsaWQgYWRkcmVzczogJHt3cm9uZ0FkZHJlc3N9YCxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVHJhbnNhY3Rpb24gTWV0aG9kcycsICgpID0+IHtcbiAgICBsZXQgZmFjdG9yeTogVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeTtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICBmYWN0b3J5ID0gbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCd0aW90YScpKTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdleHBsYWluVHJhbnNhY3Rpb24nLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBtaXNzaW5nIHR4SGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgICBhc3luYyAoKSA9PiBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oeyB0eEhleDogJycgfSksXG4gICAgICAgICAgL21pc3NpbmcgcmVxdWlyZWQgdHggcHJlYnVpbGQgcHJvcGVydHkgdHhIZXgvXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgaW52YWxpZCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgYXN5bmMgKCkgPT4gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHsgdHhIZXg6ICdpbnZhbGlkVHhIZXgnIH0pLFxuICAgICAgICAgIC9GYWlsZWQgdG8gcmVidWlsZCB0cmFuc2FjdGlvbi9cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGNhbGwgZXhwbGFpblRyYW5zYWN0aW9uIG9uIHRyYW5zYWN0aW9uIG9iamVjdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gY3JlYXRlVHJhbnNmZXJCdWlsZGVyV2l0aEdhcygpO1xuICAgICAgICBjb25zdCB0eCA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcbiAgICAgICAgY29uc3QgZXhwbGFuYXRpb24gPSB0eC5leHBsYWluVHJhbnNhY3Rpb24oKTtcblxuICAgICAgICBleHBsYW5hdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaWQnKTtcbiAgICAgICAgZXhwbGFuYXRpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ291dHB1dHMnKTtcbiAgICAgICAgZXhwbGFuYXRpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ291dHB1dEFtb3VudCcpO1xuICAgICAgICBleHBsYW5hdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlJyk7XG4gICAgICAgIGV4cGxhbmF0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eXBlJyk7XG4gICAgICAgIGV4cGxhbmF0aW9uLnR5cGUuc2hvdWxkLmVxdWFsKFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICAgICAgZXhwbGFuYXRpb24uZmVlLmZlZS5zaG91bGQuZXF1YWwodGVzdERhdGEuR0FTX0JVREdFVC50b1N0cmluZygpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3ZlcmlmeVRyYW5zYWN0aW9uJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgbWlzc2luZyB0eEhleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgYXN5bmMgKCkgPT5cbiAgICAgICAgICAgIGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICAgICAgdHhQcmVidWlsZDoge30sXG4gICAgICAgICAgICAgIHR4UGFyYW1zOiB7IHJlY2lwaWVudHM6IHRlc3REYXRhLnJlY2lwaWVudHMgfSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIC9taXNzaW5nIHJlcXVpcmVkIHR4IHByZWJ1aWxkIHByb3BlcnR5IHR4SGV4L1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IHRyYW5zYWN0aW9uIHdpdGggbWF0Y2hpbmcgcmVjaXBpZW50cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gY3JlYXRlVHJhbnNmZXJCdWlsZGVyV2l0aEdhcygpO1xuICAgICAgICBjb25zdCB0eCA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcbiAgICAgICAgY29uc3QgdHhIZXggPSBCdWZmZXIuZnJvbShhd2FpdCB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICAgIHNob3VsZC5lcXVhbChcbiAgICAgICAgICBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4IH0sXG4gICAgICAgICAgICB0eFBhcmFtczogeyByZWNpcGllbnRzOiB0ZXN0RGF0YS5yZWNpcGllbnRzIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICAgdHJ1ZVxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IHRyYW5zYWN0aW9uIHdpdGggcmVjaXBpZW50cyBjb250YWluaW5nIGV4dHJhIGZpZWxkcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gY3JlYXRlVHJhbnNmZXJCdWlsZGVyV2l0aEdhcygpO1xuICAgICAgICBjb25zdCB0eCA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcbiAgICAgICAgY29uc3QgdHhIZXggPSBCdWZmZXIuZnJvbShhd2FpdCB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICAgIGNvbnN0IHJlY2lwaWVudHNXaXRoRXh0cmFGaWVsZHMgPSB0ZXN0RGF0YS5yZWNpcGllbnRzLm1hcCgocikgPT4gKHtcbiAgICAgICAgICAuLi5yLFxuICAgICAgICAgIGV4dHJhRmllbGQ6ICdzaG91bGQgYmUgaWdub3JlZCcsXG4gICAgICAgICAgYW5vdGhlckZpZWxkOiAxMjMsXG4gICAgICAgIH0pKTtcblxuICAgICAgICBzaG91bGQuZXF1YWwoXG4gICAgICAgICAgYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCB9LFxuICAgICAgICAgICAgdHhQYXJhbXM6IHsgcmVjaXBpZW50czogcmVjaXBpZW50c1dpdGhFeHRyYUZpZWxkcyB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHRydWVcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGRldGVjdCBtaXNtYXRjaGVkIHJlY2lwaWVudHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhHYXMoKTtcbiAgICAgICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG4gICAgICAgIGNvbnN0IHR4SGV4ID0gQnVmZmVyLmZyb20oYXdhaXQgdHgudG9Ccm9hZGNhc3RGb3JtYXQoKSwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgICBjb25zdCBtaXNtYXRjaGVkUmVjaXBpZW50cyA9IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiB0ZXN0RGF0YS5hZGRyZXNzZXMudmFsaWRBZGRyZXNzZXNbMl0sXG4gICAgICAgICAgICBhbW91bnQ6ICc5OTk5JyxcbiAgICAgICAgICB9LFxuICAgICAgICBdO1xuXG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgIGFzeW5jICgpID0+XG4gICAgICAgICAgICBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgICAgICAgdHhQYXJhbXM6IHsgcmVjaXBpZW50czogbWlzbWF0Y2hlZFJlY2lwaWVudHMgfSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIC9UeCByZWNpcGllbnRzIGRvZXMgbm90IG1hdGNoIHdpdGggZXhwZWN0ZWQgdHhQYXJhbXMgcmVjaXBpZW50cy9cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHZlcmlmeSB0cmFuc2FjdGlvbiB3aXRob3V0IHJlY2lwaWVudHMgcGFyYW1ldGVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBjcmVhdGVUcmFuc2ZlckJ1aWxkZXJXaXRoR2FzKCk7XG4gICAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuICAgICAgICBjb25zdCB0eEhleCA9IEJ1ZmZlci5mcm9tKGF3YWl0IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCksICdiYXNlNjQnKS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAgICAgc2hvdWxkLmVxdWFsKFxuICAgICAgICAgIGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXggfSxcbiAgICAgICAgICAgIHR4UGFyYW1zOiB7fSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICB0cnVlXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdwYXJzZVRyYW5zYWN0aW9uJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgaW52YWxpZCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgYXN5bmMgKCkgPT4gYXdhaXQgYmFzZWNvaW4ucGFyc2VUcmFuc2FjdGlvbih7IHR4SGV4OiAnaW52YWxpZFR4SGV4JyB9KSxcbiAgICAgICAgICAvRmFpbGVkIHRvIHJlYnVpbGQgdHJhbnNhY3Rpb24vXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBwYXJzZSB0cmFuc2FjdGlvbiB1c2luZyBKU09OIGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gY3JlYXRlVHJhbnNmZXJCdWlsZGVyV2l0aEdhcygpO1xuICAgICAgICBjb25zdCB0eCA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcbiAgICAgICAgY29uc3QgZXhwbGFuYXRpb24gPSB0eC5leHBsYWluVHJhbnNhY3Rpb24oKTtcblxuICAgICAgICBleHBsYW5hdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaWQnKTtcbiAgICAgICAgZXhwbGFuYXRpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ291dHB1dHMnKTtcbiAgICAgICAgZXhwbGFuYXRpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ291dHB1dEFtb3VudCcpO1xuICAgICAgICBleHBsYW5hdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlJyk7XG5cbiAgICAgICAgZXhwbGFuYXRpb24ub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJlY2lwaWVudHMubGVuZ3RoKTtcbiAgICAgICAgZXhwbGFuYXRpb24ub3V0cHV0cy5mb3JFYWNoKChvdXRwdXQsIGluZGV4KSA9PiB7XG4gICAgICAgICAgb3V0cHV0LmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJlY2lwaWVudHNbaW5kZXhdLmFkZHJlc3MpO1xuICAgICAgICAgIG91dHB1dC5hbW91bnQuc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJlY2lwaWVudHNbaW5kZXhdLmFtb3VudCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHRvdGFsQW1vdW50ID0gdGVzdERhdGEucmVjaXBpZW50cy5yZWR1Y2UoKHN1bSwgcikgPT4gc3VtICsgTnVtYmVyKHIuYW1vdW50KSwgMCk7XG4gICAgICAgIGV4cGxhbmF0aW9uLm91dHB1dEFtb3VudC5zaG91bGQuZXF1YWwodG90YWxBbW91bnQudG9TdHJpbmcoKSk7XG4gICAgICAgIGV4cGxhbmF0aW9uLmZlZS5mZWUuc2hvdWxkLmVxdWFsKHRlc3REYXRhLkdBU19CVURHRVQudG9TdHJpbmcoKSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBwYXJzZSB0cmFuc2FjdGlvbiB3aXRoIHNpbmdsZSByZWNpcGllbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNpbmdsZVJlY2lwaWVudCA9IFt0ZXN0RGF0YS5yZWNpcGllbnRzWzBdXTtcblxuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgICAgICB0eEJ1aWxkZXIuc2VuZGVyKHRlc3REYXRhLnNlbmRlci5hZGRyZXNzKTtcbiAgICAgICAgdHhCdWlsZGVyLnJlY2lwaWVudHMoc2luZ2xlUmVjaXBpZW50KTtcbiAgICAgICAgdHhCdWlsZGVyLnBheW1lbnRPYmplY3RzKHRlc3REYXRhLnBheW1lbnRPYmplY3RzKTtcbiAgICAgICAgdHhCdWlsZGVyLmdhc0RhdGEodGVzdERhdGEuZ2FzRGF0YSk7XG5cbiAgICAgICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG4gICAgICAgIGNvbnN0IGV4cGxhbmF0aW9uID0gdHguZXhwbGFpblRyYW5zYWN0aW9uKCk7XG5cbiAgICAgICAgZXhwbGFuYXRpb24ub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICBleHBsYW5hdGlvbi5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHNpbmdsZVJlY2lwaWVudFswXS5hZGRyZXNzKTtcbiAgICAgICAgZXhwbGFuYXRpb24ub3V0cHV0c1swXS5hbW91bnQuc2hvdWxkLmVxdWFsKHNpbmdsZVJlY2lwaWVudFswXS5hbW91bnQpO1xuICAgICAgICBleHBsYW5hdGlvbi5vdXRwdXRBbW91bnQuc2hvdWxkLmVxdWFsKHNpbmdsZVJlY2lwaWVudFswXS5hbW91bnQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcGFyc2UgdHJhbnNhY3Rpb24gd2l0aCBtdWx0aXBsZSByZWNpcGllbnRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBtdWx0aXBsZVJlY2lwaWVudHMgPSBbXG4gICAgICAgICAgeyBhZGRyZXNzOiB0ZXN0RGF0YS5hZGRyZXNzZXMudmFsaWRBZGRyZXNzZXNbMF0sIGFtb3VudDogJzEwMDAnIH0sXG4gICAgICAgICAgeyBhZGRyZXNzOiB0ZXN0RGF0YS5hZGRyZXNzZXMudmFsaWRBZGRyZXNzZXNbMV0sIGFtb3VudDogJzIwMDAnIH0sXG4gICAgICAgICAgeyBhZGRyZXNzOiB0ZXN0RGF0YS5hZGRyZXNzZXMudmFsaWRBZGRyZXNzZXNbMl0sIGFtb3VudDogJzMwMDAnIH0sXG4gICAgICAgIF07XG5cbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgICAgICAgdHhCdWlsZGVyLnNlbmRlcih0ZXN0RGF0YS5zZW5kZXIuYWRkcmVzcyk7XG4gICAgICAgIHR4QnVpbGRlci5yZWNpcGllbnRzKG11bHRpcGxlUmVjaXBpZW50cyk7XG4gICAgICAgIHR4QnVpbGRlci5wYXltZW50T2JqZWN0cyh0ZXN0RGF0YS5wYXltZW50T2JqZWN0cyk7XG4gICAgICAgIHR4QnVpbGRlci5nYXNEYXRhKHRlc3REYXRhLmdhc0RhdGEpO1xuXG4gICAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuICAgICAgICBjb25zdCBleHBsYW5hdGlvbiA9IHR4LmV4cGxhaW5UcmFuc2FjdGlvbigpO1xuXG4gICAgICAgIGV4cGxhbmF0aW9uLm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgzKTtcbiAgICAgICAgZXhwbGFuYXRpb24ub3V0cHV0QW1vdW50LnNob3VsZC5lcXVhbCgnNjAwMCcpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZ2V0U2lnbmFibGVQYXlsb2FkJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCBnZXQgc2lnbmFibGUgcGF5bG9hZCBmcm9tIHRyYW5zYWN0aW9uIGRpcmVjdGx5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBjcmVhdGVUcmFuc2ZlckJ1aWxkZXJXaXRoR2FzKCk7XG4gICAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuICAgICAgICBjb25zdCBzaWduYWJsZVBheWxvYWQgPSB0eC5zaWduYWJsZVBheWxvYWQ7XG5cbiAgICAgICAgc2lnbmFibGVQYXlsb2FkLnNob3VsZC5iZS5pbnN0YW5jZU9mKEJ1ZmZlcik7XG4gICAgICAgIHNpZ25hYmxlUGF5bG9hZC5sZW5ndGguc2hvdWxkLmVxdWFsKDMyKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBpbnZhbGlkIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgICBhc3luYyAoKSA9PiBhd2FpdCBiYXNlY29pbi5nZXRTaWduYWJsZVBheWxvYWQoJ2ludmFsaWRUeEJhc2U2NCcpLFxuICAgICAgICAgIC9GYWlsZWQgdG8gcmVidWlsZCB0cmFuc2FjdGlvbi9cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGNvbnNpc3RlbnQgc2lnbmFibGUgcGF5bG9hZCBmb3IgaWRlbnRpY2FsIHRyYW5zYWN0aW9ucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHhCdWlsZGVyMSA9IGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhHYXMoKTtcbiAgICAgICAgY29uc3QgdHgxID0gKGF3YWl0IHR4QnVpbGRlcjEuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcblxuICAgICAgICBjb25zdCB0eEJ1aWxkZXIyID0gY3JlYXRlVHJhbnNmZXJCdWlsZGVyV2l0aEdhcygpO1xuICAgICAgICBjb25zdCB0eDIgPSAoYXdhaXQgdHhCdWlsZGVyMi5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuXG4gICAgICAgIHR4MS5zaWduYWJsZVBheWxvYWQudG9TdHJpbmcoJ2hleCcpLnNob3VsZC5lcXVhbCh0eDIuc2lnbmFibGVQYXlsb2FkLnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBkaWZmZXJlbnQgc2lnbmFibGUgcGF5bG9hZHMgZm9yIGRpZmZlcmVudCB0cmFuc2FjdGlvbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlcjEgPSBjcmVhdGVUcmFuc2ZlckJ1aWxkZXJXaXRoR2FzKCk7XG4gICAgICAgIGNvbnN0IHR4MSA9IChhd2FpdCB0eEJ1aWxkZXIxLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG5cbiAgICAgICAgY29uc3QgZGlmZmVyZW50UmVjaXBpZW50cyA9IFt7IGFkZHJlc3M6IHRlc3REYXRhLmFkZHJlc3Nlcy52YWxpZEFkZHJlc3Nlc1swXSwgYW1vdW50OiAnNTAwMCcgfV07XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlcjIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgICAgICB0eEJ1aWxkZXIyLnNlbmRlcih0ZXN0RGF0YS5zZW5kZXIuYWRkcmVzcyk7XG4gICAgICAgIHR4QnVpbGRlcjIucmVjaXBpZW50cyhkaWZmZXJlbnRSZWNpcGllbnRzKTtcbiAgICAgICAgdHhCdWlsZGVyMi5wYXltZW50T2JqZWN0cyh0ZXN0RGF0YS5wYXltZW50T2JqZWN0cyk7XG4gICAgICAgIHR4QnVpbGRlcjIuZ2FzRGF0YSh0ZXN0RGF0YS5nYXNEYXRhKTtcbiAgICAgICAgY29uc3QgdHgyID0gKGF3YWl0IHR4QnVpbGRlcjIuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcblxuICAgICAgICB0eDEuc2lnbmFibGVQYXlsb2FkLnRvU3RyaW5nKCdoZXgnKS5zaG91bGQubm90LmVxdWFsKHR4Mi5zaWduYWJsZVBheWxvYWQudG9TdHJpbmcoJ2hleCcpKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIHdoZW4gZ2V0dGluZyBwYXlsb2FkIGZyb20gc2ltdWxhdGUgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICAgIHR4QnVpbGRlci5zZW5kZXIodGVzdERhdGEuc2VuZGVyLmFkZHJlc3MpO1xuICAgICAgICB0eEJ1aWxkZXIucmVjaXBpZW50cyh0ZXN0RGF0YS5yZWNpcGllbnRzKTtcbiAgICAgICAgdHhCdWlsZGVyLnBheW1lbnRPYmplY3RzKHRlc3REYXRhLnBheW1lbnRPYmplY3RzKTtcblxuICAgICAgICBjb25zdCB0eCA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHR4LmlzU2ltdWxhdGVUeCwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZCgoKSA9PiB0eC5zaWduYWJsZVBheWxvYWQpLnRocm93RXJyb3IoJ0Nhbm5vdCBzaWduIGEgc2ltdWxhdGUgdHgnKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3NldENvaW5TcGVjaWZpY0ZpZWxkc0luSW50ZW50JywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCBzZXQgdW5zcGVudHMgaW4gaW50ZW50JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBpbnRlbnQgPSB7fSBhcyBhbnk7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICB1bnNwZW50czogW1xuICAgICAgICAgICAgeyBvYmplY3RJZDogJzB4MTIzJywgdmVyc2lvbjogJzEnLCBkaWdlc3Q6ICdhYmMnIH0sXG4gICAgICAgICAgICB7IG9iamVjdElkOiAnMHg0NTYnLCB2ZXJzaW9uOiAnMicsIGRpZ2VzdDogJ2RlZicgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9IGFzIGFueTtcblxuICAgICAgICBiYXNlY29pbi5zZXRDb2luU3BlY2lmaWNGaWVsZHNJbkludGVudChpbnRlbnQsIHBhcmFtcyk7XG5cbiAgICAgICAgaW50ZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCd1bnNwZW50cycpO1xuICAgICAgICBpbnRlbnQudW5zcGVudHMuc2hvdWxkLmRlZXBFcXVhbChwYXJhbXMudW5zcGVudHMpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGVtcHR5IHVuc3BlbnRzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBpbnRlbnQgPSB7fSBhcyBhbnk7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHsgdW5zcGVudHM6IFtdIH0gYXMgYW55O1xuXG4gICAgICAgIGJhc2Vjb2luLnNldENvaW5TcGVjaWZpY0ZpZWxkc0luSW50ZW50KGludGVudCwgcGFyYW1zKTtcblxuICAgICAgICBpbnRlbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3Vuc3BlbnRzJyk7XG4gICAgICAgIGludGVudC51bnNwZW50cy5zaG91bGQuZGVlcEVxdWFsKFtdKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSB1bmRlZmluZWQgdW5zcGVudHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGludGVudCA9IHt9IGFzIGFueTtcbiAgICAgICAgY29uc3QgcGFyYW1zID0ge30gYXMgYW55O1xuXG4gICAgICAgIGJhc2Vjb2luLnNldENvaW5TcGVjaWZpY0ZpZWxkc0luSW50ZW50KGludGVudCwgcGFyYW1zKTtcblxuICAgICAgICBpbnRlbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3Vuc3BlbnRzJyk7XG4gICAgICAgIChpbnRlbnQudW5zcGVudHMgPT09IHVuZGVmaW5lZCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ1RyYW5zYWN0aW9uIHdpdGggR2FzIFNwb25zb3InLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIGJ1aWxkIHRyYW5zYWN0aW9uIHdpdGggZ2FzIHNwb25zb3InLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhHYXMoKTtcbiAgICAgICAgdHhCdWlsZGVyLmdhc1Nwb25zb3IodGVzdERhdGEuZ2FzU3BvbnNvci5hZGRyZXNzKTtcbiAgICAgICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG5cbiAgICAgICAgc2hvdWxkLmVxdWFsKHR4LnNlbmRlciwgdGVzdERhdGEuc2VuZGVyLmFkZHJlc3MpO1xuICAgICAgICBzaG91bGQuZXF1YWwodHguZ2FzU3BvbnNvciwgdGVzdERhdGEuZ2FzU3BvbnNvci5hZGRyZXNzKTtcbiAgICAgICAgc2hvdWxkLm5vdEVxdWFsKHR4LnNlbmRlciwgdHguZ2FzU3BvbnNvcik7XG4gICAgICAgIHNob3VsZC5lcXVhbCh0eC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgdHJhbnNhY3Rpb24gd2hlcmUgc2VuZGVyIGFuZCBnYXMgc3BvbnNvciBhcmUgc2FtZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gY3JlYXRlVHJhbnNmZXJCdWlsZGVyV2l0aEdhcygpO1xuICAgICAgICB0eEJ1aWxkZXIuZ2FzU3BvbnNvcih0ZXN0RGF0YS5zZW5kZXIuYWRkcmVzcyk7XG4gICAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuXG4gICAgICAgIHNob3VsZC5lcXVhbCh0eC5zZW5kZXIsIHRlc3REYXRhLnNlbmRlci5hZGRyZXNzKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHR4Lmdhc1Nwb25zb3IsIHRlc3REYXRhLnNlbmRlci5hZGRyZXNzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ1RyYW5zYWN0aW9uIElEIENvbnNpc3RlbmN5JywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBzYW1lIElEIGZvciBpZGVudGljYWwgdHJhbnNhY3Rpb25zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIxID0gY3JlYXRlVHJhbnNmZXJCdWlsZGVyV2l0aEdhcygpO1xuICAgICAgICBjb25zdCB0eDEgPSAoYXdhaXQgdHhCdWlsZGVyMS5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuXG4gICAgICAgIGNvbnN0IHR4QnVpbGRlcjIgPSBjcmVhdGVUcmFuc2ZlckJ1aWxkZXJXaXRoR2FzKCk7XG4gICAgICAgIGNvbnN0IHR4MiA9IChhd2FpdCB0eEJ1aWxkZXIyLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG5cbiAgICAgICAgc2hvdWxkLmVxdWFsKHR4MS5pZCwgdHgyLmlkKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGRpZmZlcmVudCBJRHMgZm9yIGRpZmZlcmVudCB0cmFuc2FjdGlvbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlcjEgPSBjcmVhdGVUcmFuc2ZlckJ1aWxkZXJXaXRoR2FzKCk7XG4gICAgICAgIGNvbnN0IHR4MSA9IChhd2FpdCB0eEJ1aWxkZXIxLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG5cbiAgICAgICAgY29uc3QgZGlmZmVyZW50UmVjaXBpZW50cyA9IFt7IGFkZHJlc3M6IHRlc3REYXRhLmFkZHJlc3Nlcy52YWxpZEFkZHJlc3Nlc1swXSwgYW1vdW50OiAnOTk5OScgfV07XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlcjIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgICAgICB0eEJ1aWxkZXIyLnNlbmRlcih0ZXN0RGF0YS5zZW5kZXIuYWRkcmVzcyk7XG4gICAgICAgIHR4QnVpbGRlcjIucmVjaXBpZW50cyhkaWZmZXJlbnRSZWNpcGllbnRzKTtcbiAgICAgICAgdHhCdWlsZGVyMi5wYXltZW50T2JqZWN0cyh0ZXN0RGF0YS5wYXltZW50T2JqZWN0cyk7XG4gICAgICAgIHR4QnVpbGRlcjIuZ2FzRGF0YSh0ZXN0RGF0YS5nYXNEYXRhKTtcbiAgICAgICAgY29uc3QgdHgyID0gKGF3YWl0IHR4QnVpbGRlcjIuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcblxuICAgICAgICBzaG91bGQubm90RXF1YWwodHgxLmlkLCB0eDIuaWQpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnR2FzIENvbmZpZ3VyYXRpb24gRWRnZSBDYXNlcycsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIG1pbmltdW0gZ2FzIHZhbHVlcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgbWluR2FzRGF0YSA9IHtcbiAgICAgICAgICBnYXNCdWRnZXQ6IDEwMDAsXG4gICAgICAgICAgZ2FzUHJpY2U6IDEwMCxcbiAgICAgICAgICBnYXNQYXltZW50T2JqZWN0czogW3Rlc3REYXRhLmdhc1BheW1lbnRPYmplY3RzWzBdXSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgICAgICB0eEJ1aWxkZXIuc2VuZGVyKHRlc3REYXRhLnNlbmRlci5hZGRyZXNzKTtcbiAgICAgICAgdHhCdWlsZGVyLnJlY2lwaWVudHModGVzdERhdGEucmVjaXBpZW50cyk7XG4gICAgICAgIHR4QnVpbGRlci5wYXltZW50T2JqZWN0cyh0ZXN0RGF0YS5wYXltZW50T2JqZWN0cyk7XG4gICAgICAgIHR4QnVpbGRlci5nYXNEYXRhKG1pbkdhc0RhdGEpO1xuXG4gICAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuXG4gICAgICAgIHNob3VsZC5lcXVhbCh0eC5nYXNCdWRnZXQsIDEwMDApO1xuICAgICAgICBzaG91bGQuZXF1YWwodHguZ2FzUHJpY2UsIDEwMCk7XG4gICAgICAgIHNob3VsZC5lcXVhbCh0eC5nYXNQYXltZW50T2JqZWN0cz8ubGVuZ3RoLCAxKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBsYXJnZSBnYXMgdmFsdWVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBsYXJnZUdhc0RhdGEgPSB7XG4gICAgICAgICAgZ2FzQnVkZ2V0OiA1MDAwMDAwMDAwMCwgLy8gNTAgYmlsbGlvblxuICAgICAgICAgIGdhc1ByaWNlOiAxMDAwMDAsXG4gICAgICAgICAgZ2FzUGF5bWVudE9iamVjdHM6IHRlc3REYXRhLmdhc1BheW1lbnRPYmplY3RzLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICAgIHR4QnVpbGRlci5zZW5kZXIodGVzdERhdGEuc2VuZGVyLmFkZHJlc3MpO1xuICAgICAgICB0eEJ1aWxkZXIucmVjaXBpZW50cyh0ZXN0RGF0YS5yZWNpcGllbnRzKTtcbiAgICAgICAgdHhCdWlsZGVyLnBheW1lbnRPYmplY3RzKHRlc3REYXRhLnBheW1lbnRPYmplY3RzKTtcbiAgICAgICAgdHhCdWlsZGVyLmdhc0RhdGEobGFyZ2VHYXNEYXRhKTtcblxuICAgICAgICBjb25zdCB0eCA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcblxuICAgICAgICBzaG91bGQuZXF1YWwodHguZ2FzQnVkZ2V0LCA1MDAwMDAwMDAwMCk7XG4gICAgICAgIHNob3VsZC5lcXVhbCh0eC5nYXNQcmljZSwgMTAwMDAwKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJldHVybiBnYXMgZmVlIGZyb20gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhHYXMoKTtcbiAgICAgICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG4gICAgICAgIGNvbnN0IGZlZSA9IHR4LmdldEZlZSgpO1xuXG4gICAgICAgIHNob3VsZC5leGlzdChmZWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwoZmVlLCB0ZXN0RGF0YS5HQVNfQlVER0VULnRvU3RyaW5nKCkpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnVHJhbnNhY3Rpb24gU3RhdGUgTWFuYWdlbWVudCcsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgdHJhY2sgc2ltdWxhdGUgbW9kZSBjb3JyZWN0bHknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIEJ1aWxkIHdpdGhvdXQgZ2FzIGRhdGEgLSBzaG91bGQgYmUgc2ltdWxhdGUgbW9kZVxuICAgICAgICBjb25zdCBzaW11bGF0ZUJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgICAgICBzaW11bGF0ZUJ1aWxkZXIuc2VuZGVyKHRlc3REYXRhLnNlbmRlci5hZGRyZXNzKTtcbiAgICAgICAgc2ltdWxhdGVCdWlsZGVyLnJlY2lwaWVudHModGVzdERhdGEucmVjaXBpZW50cyk7XG4gICAgICAgIHNpbXVsYXRlQnVpbGRlci5wYXltZW50T2JqZWN0cyh0ZXN0RGF0YS5wYXltZW50T2JqZWN0cyk7XG5cbiAgICAgICAgY29uc3Qgc2ltdWxhdGVUeCA9IChhd2FpdCBzaW11bGF0ZUJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHNpbXVsYXRlVHguaXNTaW11bGF0ZVR4LCB0cnVlKTtcblxuICAgICAgICAvLyBCdWlsZCB3aXRoIGdhcyBkYXRhIC0gc2hvdWxkIG5vdCBiZSBzaW11bGF0ZSBtb2RlXG4gICAgICAgIGNvbnN0IHJlYWxCdWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgICAgICAgcmVhbEJ1aWxkZXIuc2VuZGVyKHRlc3REYXRhLnNlbmRlci5hZGRyZXNzKTtcbiAgICAgICAgcmVhbEJ1aWxkZXIucmVjaXBpZW50cyh0ZXN0RGF0YS5yZWNpcGllbnRzKTtcbiAgICAgICAgcmVhbEJ1aWxkZXIucGF5bWVudE9iamVjdHModGVzdERhdGEucGF5bWVudE9iamVjdHMpO1xuICAgICAgICByZWFsQnVpbGRlci5nYXNEYXRhKHRlc3REYXRhLmdhc0RhdGEpO1xuXG4gICAgICAgIGNvbnN0IHJlYWxUeCA9IChhd2FpdCByZWFsQnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVhbFR4LmlzU2ltdWxhdGVUeCwgZmFsc2UpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGNhblNpZ24gYmFzZWQgb24gc2ltdWxhdGUgbW9kZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gU2ltdWxhdGUgdHJhbnNhY3Rpb24gY2Fubm90IGJlIHNpZ25lZFxuICAgICAgICBjb25zdCBzaW11bGF0ZUJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgICAgICBzaW11bGF0ZUJ1aWxkZXIuc2VuZGVyKHRlc3REYXRhLnNlbmRlci5hZGRyZXNzKTtcbiAgICAgICAgc2ltdWxhdGVCdWlsZGVyLnJlY2lwaWVudHModGVzdERhdGEucmVjaXBpZW50cyk7XG4gICAgICAgIHNpbXVsYXRlQnVpbGRlci5wYXltZW50T2JqZWN0cyh0ZXN0RGF0YS5wYXltZW50T2JqZWN0cyk7XG5cbiAgICAgICAgY29uc3Qgc2ltdWxhdGVUeCA9IChhd2FpdCBzaW11bGF0ZUJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHNpbXVsYXRlVHguY2FuU2lnbih7fSBhcyBhbnkpLCBmYWxzZSk7XG5cbiAgICAgICAgLy8gUmVhbCB0cmFuc2FjdGlvbiBjYW4gYmUgc2lnbmVkXG4gICAgICAgIGNvbnN0IHJlYWxCdWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgICAgICAgcmVhbEJ1aWxkZXIuc2VuZGVyKHRlc3REYXRhLnNlbmRlci5hZGRyZXNzKTtcbiAgICAgICAgcmVhbEJ1aWxkZXIucmVjaXBpZW50cyh0ZXN0RGF0YS5yZWNpcGllbnRzKTtcbiAgICAgICAgcmVhbEJ1aWxkZXIucGF5bWVudE9iamVjdHModGVzdERhdGEucGF5bWVudE9iamVjdHMpO1xuICAgICAgICByZWFsQnVpbGRlci5nYXNEYXRhKHRlc3REYXRhLmdhc0RhdGEpO1xuXG4gICAgICAgIGNvbnN0IHJlYWxUeCA9IChhd2FpdCByZWFsQnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVhbFR4LmNhblNpZ24oe30gYXMgYW55KSwgdHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgdHJhbnNhY3Rpb24gdHlwZSBjb3JyZWN0bHknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhHYXMoKTtcbiAgICAgICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG5cbiAgICAgICAgc2hvdWxkLmVxdWFsKHR4LnR5cGUsIFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ1RyYW5zYWN0aW9uIFNlcmlhbGl6YXRpb24gRm9ybWF0cycsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgc2VyaWFsaXplIHRvIGNvbnNpc3RlbnQgYnJvYWRjYXN0IGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHhCdWlsZGVyMSA9IGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhHYXMoKTtcbiAgICAgICAgY29uc3QgdHgxID0gKGF3YWl0IHR4QnVpbGRlcjEuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcbiAgICAgICAgY29uc3QgYnJvYWRjYXN0MSA9IGF3YWl0IHR4MS50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICAgIGNvbnN0IHR4QnVpbGRlcjIgPSBjcmVhdGVUcmFuc2ZlckJ1aWxkZXJXaXRoR2FzKCk7XG4gICAgICAgIGNvbnN0IHR4MiA9IChhd2FpdCB0eEJ1aWxkZXIyLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG4gICAgICAgIGNvbnN0IGJyb2FkY2FzdDIgPSBhd2FpdCB0eDIudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgICBzaG91bGQuZXF1YWwoYnJvYWRjYXN0MSwgYnJvYWRjYXN0Mik7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBwcm9kdWNlIHZhbGlkIGJhc2U2NCBicm9hZGNhc3QgZm9ybWF0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBjcmVhdGVUcmFuc2ZlckJ1aWxkZXJXaXRoR2FzKCk7XG4gICAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuICAgICAgICBjb25zdCBicm9hZGNhc3QgPSBhd2FpdCB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICAgIHNob3VsZC5lcXVhbCh0eXBlb2YgYnJvYWRjYXN0LCAnc3RyaW5nJyk7XG4gICAgICAgIHNob3VsZC5lcXVhbCgvXltBLVphLXowLTkrL10qPXswLDJ9JC8udGVzdChicm9hZGNhc3QpLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKGJyb2FkY2FzdC5sZW5ndGggPiAwLCB0cnVlKTtcblxuICAgICAgICBjb25zdCBkZWNvZGVkID0gQnVmZmVyLmZyb20oYnJvYWRjYXN0LCAnYmFzZTY0Jyk7XG4gICAgICAgIHNob3VsZC5lcXVhbChkZWNvZGVkLmxlbmd0aCA+IDAsIHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgbWFpbnRhaW4gSlNPTiBzZXJpYWxpemF0aW9uIGNvbnNpc3RlbmN5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBjcmVhdGVUcmFuc2ZlckJ1aWxkZXJXaXRoR2FzKCk7XG4gICAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuICAgICAgICBjb25zdCBqc29uMSA9IHR4LnRvSnNvbigpO1xuICAgICAgICBjb25zdCBqc29uMiA9IHR4LnRvSnNvbigpO1xuXG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwoanNvbjEsIGpzb24yKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19