@bitgo-beta/sdk-coin-algo 1.3.3-alpha.43 → 1.3.3-alpha.430

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 (83) hide show
  1. package/dist/src/algo.d.ts +117 -16
  2. package/dist/src/algo.d.ts.map +1 -1
  3. package/dist/src/algo.js +430 -46
  4. package/dist/src/algoToken.d.ts +1 -1
  5. package/dist/src/algoToken.d.ts.map +1 -1
  6. package/dist/src/algoToken.js +3 -3
  7. package/dist/src/index.js +23 -9
  8. package/dist/src/lib/assetTransferBuilder.d.ts +1 -1
  9. package/dist/src/lib/assetTransferBuilder.js +2 -2
  10. package/dist/src/lib/ifaces.d.ts +0 -1
  11. package/dist/src/lib/ifaces.d.ts.map +1 -1
  12. package/dist/src/lib/index.js +23 -9
  13. package/dist/src/lib/keyPair.js +24 -10
  14. package/dist/src/lib/keyRegistrationBuilder.js +1 -1
  15. package/dist/src/lib/seedEncoding.js +23 -9
  16. package/dist/src/lib/transaction.js +3 -4
  17. package/dist/src/lib/transactionBuilder.d.ts +6 -0
  18. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  19. package/dist/src/lib/transactionBuilder.js +45 -29
  20. package/dist/src/lib/transactionBuilderFactory.js +1 -1
  21. package/dist/src/lib/transferBuilder.js +1 -1
  22. package/dist/src/lib/txnSchema.js +1 -1
  23. package/dist/src/lib/utils.d.ts +6 -1
  24. package/dist/src/lib/utils.d.ts.map +1 -1
  25. package/dist/src/lib/utils.js +35 -11
  26. package/dist/src/seedValidator.js +23 -9
  27. package/dist/test/fixtures/algo.d.ts +101 -0
  28. package/dist/test/fixtures/algo.d.ts.map +1 -0
  29. package/dist/test/fixtures/algo.js +239 -0
  30. package/dist/test/fixtures/resources.d.ts +121 -0
  31. package/dist/test/fixtures/resources.d.ts.map +1 -0
  32. package/dist/test/fixtures/resources.js +131 -0
  33. package/dist/test/integration/algo.integration.d.ts +2 -0
  34. package/dist/test/integration/algo.integration.d.ts.map +1 -0
  35. package/dist/test/integration/algo.integration.js +71 -0
  36. package/dist/test/unit/algo.d.ts +2 -0
  37. package/dist/test/unit/algo.d.ts.map +1 -0
  38. package/dist/test/unit/algo.js +1223 -0
  39. package/dist/test/unit/algoIsWalletAddress.d.ts +2 -0
  40. package/dist/test/unit/algoIsWalletAddress.d.ts.map +1 -0
  41. package/dist/test/unit/algoIsWalletAddress.js +118 -0
  42. package/dist/test/unit/algoToken.d.ts +2 -0
  43. package/dist/test/unit/algoToken.d.ts.map +1 -0
  44. package/dist/test/unit/algoToken.js +79 -0
  45. package/dist/test/unit/fixtures/algoBackupKey.d.ts +4 -0
  46. package/dist/test/unit/fixtures/algoBackupKey.d.ts.map +1 -0
  47. package/dist/test/unit/fixtures/algoBackupKey.js +10 -0
  48. package/dist/test/unit/lib/keyPair.d.ts +2 -0
  49. package/dist/test/unit/lib/keyPair.d.ts.map +1 -0
  50. package/dist/test/unit/lib/keyPair.js +110 -0
  51. package/dist/test/unit/lib/seedEncoding.d.ts +2 -0
  52. package/dist/test/unit/lib/seedEncoding.d.ts.map +1 -0
  53. package/dist/test/unit/lib/seedEncoding.js +59 -0
  54. package/dist/test/unit/lib/transaction.d.ts +2 -0
  55. package/dist/test/unit/lib/transaction.d.ts.map +1 -0
  56. package/dist/test/unit/lib/transaction.js +157 -0
  57. package/dist/test/unit/lib/transactionBuilder/assetTransferBuilder.d.ts +2 -0
  58. package/dist/test/unit/lib/transactionBuilder/assetTransferBuilder.d.ts.map +1 -0
  59. package/dist/test/unit/lib/transactionBuilder/assetTransferBuilder.js +300 -0
  60. package/dist/test/unit/lib/transactionBuilder/base.d.ts +2 -0
  61. package/dist/test/unit/lib/transactionBuilder/base.d.ts.map +1 -0
  62. package/dist/test/unit/lib/transactionBuilder/base.js +310 -0
  63. package/dist/test/unit/lib/transactionBuilder/keyRegistrationBuilder.d.ts +2 -0
  64. package/dist/test/unit/lib/transactionBuilder/keyRegistrationBuilder.d.ts.map +1 -0
  65. package/dist/test/unit/lib/transactionBuilder/keyRegistrationBuilder.js +473 -0
  66. package/dist/test/unit/lib/transactionBuilder/transactionBuilderFactory.d.ts +2 -0
  67. package/dist/test/unit/lib/transactionBuilder/transactionBuilderFactory.d.ts.map +1 -0
  68. package/dist/test/unit/lib/transactionBuilder/transactionBuilderFactory.js +138 -0
  69. package/dist/test/unit/lib/transactionBuilder/transferBuilder.d.ts +2 -0
  70. package/dist/test/unit/lib/transactionBuilder/transferBuilder.d.ts.map +1 -0
  71. package/dist/test/unit/lib/transactionBuilder/transferBuilder.js +290 -0
  72. package/dist/test/unit/lib/utils.d.ts +2 -0
  73. package/dist/test/unit/lib/utils.d.ts.map +1 -0
  74. package/dist/test/unit/lib/utils.js +307 -0
  75. package/dist/test/unit/verifyTransaction.d.ts +2 -0
  76. package/dist/test/unit/verifyTransaction.d.ts.map +1 -0
  77. package/dist/test/unit/verifyTransaction.js +703 -0
  78. package/dist/tsconfig.tsbuildinfo +1 -0
  79. package/package.json +12 -10
  80. package/.eslintignore +0 -5
  81. package/.mocharc.yml +0 -8
  82. package/CHANGELOG.md +0 -160
  83. package/types/index.d.ts +0 -60
@@ -0,0 +1,1223 @@
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 src_1 = require("../../src");
40
+ const sdk_test_1 = require("@bitgo-beta/sdk-test");
41
+ const sdk_api_1 = require("@bitgo-beta/sdk-api");
42
+ const AlgoResources = __importStar(require("../fixtures/algo"));
43
+ const crypto_1 = require("crypto");
44
+ const statics_1 = require("@bitgo-beta/statics");
45
+ const sinon_1 = __importStar(require("sinon"));
46
+ const assert_1 = __importDefault(require("assert"));
47
+ const algo_1 = require("../../src/algo");
48
+ const bignumber_js_1 = __importDefault(require("bignumber.js"));
49
+ const lib_1 = require("../../src/lib");
50
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
51
+ const algoBackupKey_1 = require("./fixtures/algoBackupKey");
52
+ const nock_1 = __importDefault(require("nock"));
53
+ describe('ALGO:', function () {
54
+ let bitgo;
55
+ let basecoin;
56
+ const receiver = AlgoResources.accounts.account2;
57
+ before(function () {
58
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
59
+ bitgo.safeRegister('talgo', src_1.Talgo.createInstance);
60
+ bitgo.initializeTestVars();
61
+ basecoin = bitgo.coin('talgo');
62
+ });
63
+ describe('Should Fail: ', () => {
64
+ it('Does not have a txHex', async () => {
65
+ await basecoin
66
+ .explainTransaction({
67
+ params: {},
68
+ })
69
+ .should.be.rejectedWith('missing explain tx parameters');
70
+ });
71
+ it('Does not have a fee', async () => {
72
+ await basecoin
73
+ .explainTransaction({
74
+ params: {
75
+ txHex: 'Some Valid Hex',
76
+ },
77
+ })
78
+ .should.be.rejectedWith('missing explain tx parameters');
79
+ });
80
+ });
81
+ describe('Transfer Builder: ', () => {
82
+ const buildBaseTransferTransaction = ({ destination, amount = 10000, sender, memo = '' }) => {
83
+ const factory = new src_1.AlgoLib.TransactionBuilderFactory(statics_1.coins.get('algo'));
84
+ const txBuilder = factory.getTransferBuilder();
85
+ const lease = new Uint8Array((0, crypto_1.randomBytes)(32));
86
+ const note = new Uint8Array(Buffer.from(memo, 'utf-8'));
87
+ txBuilder
88
+ .sender({ address: sender })
89
+ .to({ address: destination })
90
+ .amount(amount)
91
+ .isFlatFee(true)
92
+ .fee({
93
+ fee: '1000',
94
+ })
95
+ .firstRound(1)
96
+ .lastRound(100)
97
+ .lease(lease)
98
+ .note(note)
99
+ .testnet();
100
+ return txBuilder;
101
+ };
102
+ /**
103
+ * Build an unsigned account-lib single-signature send transaction
104
+ * @param sender The senders address
105
+ * @param destination The destination address of the transaction
106
+ * @param amount The amount to send to the recipient
107
+ * @param memo Optional note with the transaction
108
+ */
109
+ const buildUnsignedTransaction = async function ({ sender, destination, amount = 10000, memo = '' }) {
110
+ const txBuilder = buildBaseTransferTransaction({ sender, destination, amount, memo });
111
+ return await txBuilder.build();
112
+ };
113
+ /**
114
+ * Build a signed account-lib single-signature send transaction
115
+ * @param sender The senders address
116
+ * @param destination The destination address of the transaction
117
+ * @param amount The amount to send to the recipient
118
+ * @param memo Optional note with the transaction
119
+ */
120
+ const buildSignedTransaction = async function ({ sender, destination, amount = 10000, memo = '' }) {
121
+ const txBuilder = buildBaseTransferTransaction({ sender, destination, amount, memo });
122
+ txBuilder.numberOfSigners(1);
123
+ txBuilder.sign({ key: AlgoResources.accounts.account1.prvKey });
124
+ return await txBuilder.build();
125
+ };
126
+ /**
127
+ * Build a multi-signed account-lib single-signature send transaction
128
+ * @param senders The list of senders
129
+ * @param destination The destination address of the transaction
130
+ * @param amount The amount to send to the recipient
131
+ * @param memo Optional note with the transaction
132
+ */
133
+ const buildMultiSignedTransaction = async function ({ senders, destination, amount = 10000, memo = '' }) {
134
+ const txBuilder = buildBaseTransferTransaction({ sender: senders[0], destination, amount, memo });
135
+ txBuilder.numberOfSigners(2);
136
+ txBuilder.setSigners(senders);
137
+ txBuilder.sign({ key: AlgoResources.accounts.account1.prvKey });
138
+ txBuilder.sign({ key: AlgoResources.accounts.account3.prvKey });
139
+ return await txBuilder.build();
140
+ };
141
+ it('should explain an unsigned transfer transaction hex', async function () {
142
+ const explain = await basecoin.explainTransaction({
143
+ txHex: AlgoResources.explainRawTx.transfer.unsigned,
144
+ feeInfo: { fee: '1000' },
145
+ });
146
+ explain.outputAmount.should.equal('10000');
147
+ explain.outputs[0].amount.should.equal('10000');
148
+ explain.outputs[0].address.should.equal(receiver.address);
149
+ Buffer.from(explain.outputs[0].memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
150
+ explain.fee.should.equal(1000);
151
+ explain.changeAmount.should.equal('0');
152
+ });
153
+ it('should explain a signed transfer transaction hex', async function () {
154
+ const explain = await basecoin.explainTransaction({
155
+ txHex: AlgoResources.explainRawTx.transfer.signed,
156
+ feeInfo: { fee: '1000' },
157
+ });
158
+ explain.outputAmount.should.equal('10000');
159
+ explain.outputs[0].amount.should.equal('10000');
160
+ explain.outputs[0].address.should.equal(receiver.address);
161
+ Buffer.from(explain.outputs[0].memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
162
+ explain.fee.should.equal(1000);
163
+ explain.changeAmount.should.equal('0');
164
+ });
165
+ it('should explain a multiSig transfer transaction hex', async function () {
166
+ const explain = await basecoin.explainTransaction({
167
+ txHex: AlgoResources.explainRawTx.transfer.multiSigned,
168
+ feeInfo: { fee: '1000' },
169
+ });
170
+ explain.outputAmount.should.equal('10000');
171
+ explain.outputs[0].amount.should.equal('10000');
172
+ explain.outputs[0].address.should.equal(receiver.address);
173
+ Buffer.from(explain.outputs[0].memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
174
+ explain.fee.should.equal(1000);
175
+ explain.changeAmount.should.equal('0');
176
+ });
177
+ it('should explain a half signed transfer transaction hex', async function () {
178
+ const explain = await basecoin.explainTransaction({
179
+ halfSigned: {
180
+ txHex: AlgoResources.explainRawTx.transfer.halfSigned,
181
+ },
182
+ feeInfo: { fee: '1000' },
183
+ });
184
+ explain.outputAmount.should.equal('10000');
185
+ explain.outputs[0].amount.should.equal('10000');
186
+ explain.outputs[0].address.should.equal(receiver.address);
187
+ Buffer.from(explain.outputs[0].memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
188
+ explain.fee.should.equal(1000);
189
+ explain.changeAmount.should.equal('0');
190
+ });
191
+ it('should explain an unsigned transaction', async function () {
192
+ const sender = AlgoResources.accounts.account1.address;
193
+ const destination = AlgoResources.accounts.account2.address;
194
+ const amount = 10000;
195
+ const memo = AlgoResources.explainRawTx.transfer.note;
196
+ const unsignedTransaction = await buildUnsignedTransaction({
197
+ sender,
198
+ destination,
199
+ amount,
200
+ memo,
201
+ });
202
+ const unsignedHex = Buffer.from(unsignedTransaction.toBroadcastFormat()).toString('hex');
203
+ const explain = await basecoin.explainTransaction({
204
+ txHex: unsignedHex,
205
+ feeInfo: { fee: '1000' },
206
+ });
207
+ Buffer.from(explain.outputs[0].memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
208
+ explain.outputs[0].amount.should.equal(amount.toString());
209
+ explain.outputs[0].address.should.equal(destination);
210
+ });
211
+ it('should explain a signed transaction', async function () {
212
+ const sender = AlgoResources.accounts.account1.address;
213
+ const destination = AlgoResources.accounts.account2.address;
214
+ const amount = 10000;
215
+ const memo = AlgoResources.explainRawTx.transfer.note;
216
+ const signedTransaction = await buildSignedTransaction({
217
+ sender,
218
+ destination,
219
+ amount,
220
+ memo,
221
+ });
222
+ const signedHex = Buffer.from(signedTransaction.toBroadcastFormat()).toString('hex');
223
+ const explain = await basecoin.explainTransaction({
224
+ txHex: signedHex,
225
+ feeInfo: { fee: '1000' },
226
+ });
227
+ Buffer.from(explain.outputs[0].memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
228
+ explain.outputs[0].amount.should.equal(amount.toString());
229
+ explain.outputs[0].address.should.equal(destination);
230
+ });
231
+ it('should explain a multiSigned transaction', async function () {
232
+ const senders = [AlgoResources.accounts.account1.address, AlgoResources.accounts.account3.address];
233
+ const destination = AlgoResources.accounts.account2.address;
234
+ const amount = 10000;
235
+ const memo = AlgoResources.explainRawTx.transfer.note;
236
+ const signedTransaction = await buildMultiSignedTransaction({
237
+ senders,
238
+ destination,
239
+ amount,
240
+ memo,
241
+ });
242
+ const signedHex = Buffer.from(signedTransaction.toBroadcastFormat()).toString('hex');
243
+ const explain = await basecoin.explainTransaction({
244
+ txHex: signedHex,
245
+ feeInfo: { fee: '1000' },
246
+ });
247
+ Buffer.from(explain.outputs[0].memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
248
+ explain.outputs[0].amount.should.equal(amount.toString());
249
+ explain.outputs[0].address.should.equal(destination);
250
+ });
251
+ });
252
+ describe('Asset Transfer Builder: ', () => {
253
+ const buildBaseAssetTransferTransaction = ({ destination, amount = 1000, tokenId, sender }) => {
254
+ const factory = new src_1.AlgoLib.TransactionBuilderFactory(statics_1.coins.get('algo'));
255
+ const txBuilder = factory.getAssetTransferBuilder();
256
+ const lease = new Uint8Array((0, crypto_1.randomBytes)(32));
257
+ txBuilder
258
+ .sender({ address: sender })
259
+ .isFlatFee(true)
260
+ .fee({
261
+ fee: '1000',
262
+ })
263
+ .tokenId(tokenId)
264
+ .firstRound(1)
265
+ .lastRound(100)
266
+ .lease(lease)
267
+ .to({ address: destination })
268
+ .amount(amount)
269
+ .testnet();
270
+ return txBuilder;
271
+ };
272
+ /**
273
+ * Build an unsigned account-lib single-signature asset transfer transaction
274
+ * @param sender The senders address
275
+ * @param destination The destination address of the transaction
276
+ * @param amount The amount to send to the recipient
277
+ * @param tokenId The assetIndex for the token
278
+ */
279
+ const buildUnsignedTransaction = async function ({ sender, destination, amount = 10000, tokenId }) {
280
+ const txBuilder = buildBaseAssetTransferTransaction({ sender, destination, amount, tokenId });
281
+ return await txBuilder.build();
282
+ };
283
+ /**
284
+ * Build a signed account-lib single-signature send transaction
285
+ * @param sender The senders address
286
+ * @param destination The destination address of the transaction
287
+ * @param amount The amount to send to the recipient
288
+ * @param tokenId The assetIndex for the token
289
+ */
290
+ const buildSignedTransaction = async function ({ sender, destination, amount = 10000, tokenId }) {
291
+ const txBuilder = buildBaseAssetTransferTransaction({ sender, destination, amount, tokenId });
292
+ txBuilder.numberOfSigners(1);
293
+ txBuilder.sign({ key: AlgoResources.accounts.account1.prvKey });
294
+ return await txBuilder.build();
295
+ };
296
+ it('should explain an unsigned asset transfer transaction hex', async function () {
297
+ const explain = await basecoin.explainTransaction({
298
+ txHex: AlgoResources.explainRawTx.assetTransfer.unsigned,
299
+ feeInfo: { fee: '1000' },
300
+ });
301
+ explain.outputAmount.should.equal('1000');
302
+ explain.outputs[0].amount.should.equal('1000');
303
+ explain.outputs[0].address.should.equal(receiver.address);
304
+ explain.fee.should.equal(1000);
305
+ explain.changeAmount.should.equal('0');
306
+ explain.tokenId.should.equal(1);
307
+ });
308
+ it('should explain a signed asset transfer transaction hex', async function () {
309
+ const explain = await basecoin.explainTransaction({
310
+ txHex: AlgoResources.explainRawTx.assetTransfer.signed,
311
+ feeInfo: { fee: '1000' },
312
+ });
313
+ explain.outputAmount.should.equal('10000000000000000000');
314
+ explain.outputs[0].amount.should.equal('10000000000000000000');
315
+ explain.outputs[0].address.should.equal(receiver.address);
316
+ explain.fee.should.equal(1000);
317
+ explain.changeAmount.should.equal('0');
318
+ explain.tokenId.should.equal(1);
319
+ });
320
+ it('should explain an unsigned transaction', async function () {
321
+ const sender = AlgoResources.accounts.account1.address;
322
+ const destination = AlgoResources.accounts.account2.address;
323
+ const amount = 10000;
324
+ const tokenId = 1;
325
+ const unsignedTransaction = await buildUnsignedTransaction({
326
+ sender,
327
+ destination,
328
+ amount,
329
+ tokenId,
330
+ });
331
+ const unsignedHex = Buffer.from(unsignedTransaction.toBroadcastFormat()).toString('hex');
332
+ const explain = await basecoin.explainTransaction({
333
+ txHex: unsignedHex,
334
+ feeInfo: { fee: '1000' },
335
+ });
336
+ explain.outputs[0].amount.should.equal(amount.toString());
337
+ explain.outputs[0].address.should.equal(destination);
338
+ explain.tokenId.should.equal(1);
339
+ });
340
+ it('should explain a signed transaction', async function () {
341
+ const sender = AlgoResources.accounts.account1.address;
342
+ const destination = AlgoResources.accounts.account2.address;
343
+ const amount = 10000;
344
+ const tokenId = 1;
345
+ const signedTransaction = await buildSignedTransaction({
346
+ sender,
347
+ destination,
348
+ amount,
349
+ tokenId,
350
+ });
351
+ const signedHex = Buffer.from(signedTransaction.toBroadcastFormat()).toString('hex');
352
+ const explain = await basecoin.explainTransaction({
353
+ txHex: signedHex,
354
+ feeInfo: { fee: '1000' },
355
+ });
356
+ explain.outputs[0].amount.should.equal(amount.toString());
357
+ explain.outputs[0].address.should.equal(destination);
358
+ explain.tokenId.should.equal(1);
359
+ });
360
+ });
361
+ describe('Wallet Init Builder: ', () => {
362
+ const buildBaseKeyRegTransaction = ({ sender, memo = '' }) => {
363
+ const factory = new src_1.AlgoLib.TransactionBuilderFactory(statics_1.coins.get('algo'));
364
+ const txBuilder = factory.getWalletInitializationBuilder();
365
+ const lease = new Uint8Array((0, crypto_1.randomBytes)(32));
366
+ const note = new Uint8Array(Buffer.from(memo, 'utf-8'));
367
+ txBuilder
368
+ .sender({ address: sender.address })
369
+ .isFlatFee(true)
370
+ .fee({
371
+ fee: '1000',
372
+ })
373
+ .firstRound(1)
374
+ .lastRound(100)
375
+ .lease(lease)
376
+ .note(note)
377
+ .voteKey(sender.voteKey)
378
+ .selectionKey(sender.selectionKey)
379
+ .voteFirst(1)
380
+ .voteLast(100)
381
+ .voteKeyDilution(9)
382
+ .testnet();
383
+ return txBuilder;
384
+ };
385
+ /**
386
+ * Build an unsigned account-lib single-signature send transaction
387
+ * @param sender The senders address
388
+ * @param memo Optional note with the transaction
389
+ */
390
+ const buildUnsignedTransaction = async function ({ sender, memo = '' }) {
391
+ const txBuilder = buildBaseKeyRegTransaction({ sender, memo });
392
+ return await txBuilder.build();
393
+ };
394
+ /**
395
+ * Build a signed account-lib single-signature send transaction
396
+ * @param sender The senders address
397
+ * @param memo Optional note with the transaction
398
+ */
399
+ const buildSignedTransaction = async function ({ sender, memo = '' }) {
400
+ const txBuilder = buildBaseKeyRegTransaction({ sender, memo });
401
+ txBuilder.numberOfSigners(1);
402
+ txBuilder.sign({ key: AlgoResources.accounts.account1.prvKey });
403
+ return await txBuilder.build();
404
+ };
405
+ /**
406
+ * Build a multi-signed account-lib single-signature send transaction
407
+ * @param senders The list of senders
408
+ * @param memo Optional note with the transaction
409
+ */
410
+ const buildMultiSignedTransaction = async function ({ senders, memo = '' }) {
411
+ const txBuilder = buildBaseKeyRegTransaction({ sender: senders[0], memo });
412
+ txBuilder.numberOfSigners(2);
413
+ txBuilder.setSigners(senders.map(({ address }) => address));
414
+ txBuilder.sign({ key: AlgoResources.accounts.account1.prvKey });
415
+ txBuilder.sign({ key: AlgoResources.accounts.account3.prvKey });
416
+ return await txBuilder.build();
417
+ };
418
+ it('should explain an unsigned KeyReg transfer transaction hex', async function () {
419
+ const sender = AlgoResources.accounts.account1;
420
+ const explain = await basecoin.explainTransaction({
421
+ txHex: AlgoResources.explainRawTx.keyreg.unsigned,
422
+ feeInfo: { fee: '1000' },
423
+ });
424
+ Buffer.from(explain.memo).toString().should.equal(AlgoResources.explainRawTx.keyreg.note);
425
+ explain.fee.should.equal(1000);
426
+ explain.changeAmount.should.equal('0');
427
+ explain.voteKey.should.equal(sender.voteKey);
428
+ explain.selectionKey.should.equal(sender.selectionKey);
429
+ explain.voteFirst.should.equal(1);
430
+ explain.voteLast.should.equal(100);
431
+ explain.voteKeyDilution.should.equal(9);
432
+ });
433
+ it('should explain a signed transfer transaction hex', async function () {
434
+ const sender = AlgoResources.accounts.account1;
435
+ const explain = await basecoin.explainTransaction({
436
+ txHex: AlgoResources.explainRawTx.keyreg.signed,
437
+ feeInfo: { fee: '1000' },
438
+ });
439
+ Buffer.from(explain.memo).toString().should.equal(AlgoResources.explainRawTx.keyreg.note);
440
+ explain.fee.should.equal(1000);
441
+ explain.changeAmount.should.equal('0');
442
+ explain.voteKey.should.equal(sender.voteKey);
443
+ explain.selectionKey.should.equal(sender.selectionKey);
444
+ explain.voteFirst.should.equal(1);
445
+ explain.voteLast.should.equal(100);
446
+ explain.voteKeyDilution.should.equal(9);
447
+ });
448
+ it('should explain a multiSig transfer transaction hex', async function () {
449
+ const sender = AlgoResources.accounts.account1;
450
+ const explain = await basecoin.explainTransaction({
451
+ txHex: AlgoResources.explainRawTx.keyreg.multiSigned,
452
+ feeInfo: { fee: '1000' },
453
+ });
454
+ Buffer.from(explain.memo).toString().should.equal(AlgoResources.explainRawTx.keyreg.note);
455
+ explain.fee.should.equal(1000);
456
+ explain.changeAmount.should.equal('0');
457
+ explain.voteKey.should.equal(sender.voteKey);
458
+ explain.selectionKey.should.equal(sender.selectionKey);
459
+ explain.voteFirst.should.equal(1);
460
+ explain.voteLast.should.equal(100);
461
+ explain.voteKeyDilution.should.equal(9);
462
+ });
463
+ it('should explain a half signed transfer transaction hex', async function () {
464
+ const sender = AlgoResources.accounts.account1;
465
+ const explain = await basecoin.explainTransaction({
466
+ halfSigned: {
467
+ txHex: AlgoResources.explainRawTx.keyreg.halfSigned,
468
+ },
469
+ feeInfo: { fee: '1000' },
470
+ });
471
+ Buffer.from(explain.memo).toString().should.equal(AlgoResources.explainRawTx.keyreg.note);
472
+ explain.fee.should.equal(1000);
473
+ explain.changeAmount.should.equal('0');
474
+ explain.voteKey.should.equal(sender.voteKey);
475
+ explain.selectionKey.should.equal(sender.selectionKey);
476
+ explain.voteFirst.should.equal(1);
477
+ explain.voteLast.should.equal(100);
478
+ explain.voteKeyDilution.should.equal(9);
479
+ });
480
+ it('should explain an unsigned transaction', async function () {
481
+ const sender = AlgoResources.accounts.account1;
482
+ const memo = AlgoResources.explainRawTx.transfer.note;
483
+ const unsignedTransaction = await buildUnsignedTransaction({
484
+ sender,
485
+ memo,
486
+ });
487
+ const unsignedHex = Buffer.from(unsignedTransaction.toBroadcastFormat()).toString('hex');
488
+ const explain = await basecoin.explainTransaction({
489
+ txHex: unsignedHex,
490
+ feeInfo: { fee: '1000' },
491
+ });
492
+ Buffer.from(explain.memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
493
+ explain.voteKey.should.equal(sender.voteKey);
494
+ explain.selectionKey.should.equal(sender.selectionKey);
495
+ explain.voteFirst.should.equal(1);
496
+ explain.voteLast.should.equal(100);
497
+ explain.voteKeyDilution.should.equal(9);
498
+ });
499
+ it('should explain a signed transaction', async function () {
500
+ const sender = AlgoResources.accounts.account1;
501
+ const memo = AlgoResources.explainRawTx.transfer.note;
502
+ const signedTransaction = await buildSignedTransaction({
503
+ sender,
504
+ memo,
505
+ });
506
+ const signedHex = Buffer.from(signedTransaction.toBroadcastFormat()).toString('hex');
507
+ const explain = await basecoin.explainTransaction({
508
+ txHex: signedHex,
509
+ feeInfo: { fee: '1000' },
510
+ });
511
+ Buffer.from(explain.memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
512
+ explain.voteKey.should.equal(sender.voteKey);
513
+ explain.selectionKey.should.equal(sender.selectionKey);
514
+ explain.voteFirst.should.equal(1);
515
+ explain.voteLast.should.equal(100);
516
+ explain.voteKeyDilution.should.equal(9);
517
+ });
518
+ it('should explain a multiSigned transaction', async function () {
519
+ const senders = [AlgoResources.accounts.account1, AlgoResources.accounts.account3];
520
+ const memo = AlgoResources.explainRawTx.transfer.note;
521
+ const signedTransaction = await buildMultiSignedTransaction({
522
+ senders,
523
+ memo,
524
+ });
525
+ const signedHex = Buffer.from(signedTransaction.toBroadcastFormat()).toString('hex');
526
+ const explain = await basecoin.explainTransaction({
527
+ txHex: signedHex,
528
+ feeInfo: { fee: '1000' },
529
+ });
530
+ Buffer.from(explain.memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
531
+ explain.voteKey.should.equal(AlgoResources.accounts.account1.voteKey);
532
+ explain.selectionKey.should.equal(AlgoResources.accounts.account1.selectionKey);
533
+ explain.voteFirst.should.equal(1);
534
+ explain.voteLast.should.equal(100);
535
+ explain.voteKeyDilution.should.equal(9);
536
+ });
537
+ });
538
+ describe('Sign transaction', () => {
539
+ it('should sign transaction', async function () {
540
+ const signed = await basecoin.signTransaction({
541
+ txPrebuild: {
542
+ txHex: AlgoResources.rawTx.transfer.unsigned,
543
+ keys: [AlgoResources.accounts.account1.pubKey.toString('hex')],
544
+ addressVersion: 1,
545
+ },
546
+ prv: AlgoResources.accounts.account1.prvKey,
547
+ });
548
+ signed.txHex.should.equal(AlgoResources.rawTx.transfer.signed);
549
+ });
550
+ it('should sign transaction with root key', async function () {
551
+ const keypair = basecoin.generateRootKeyPair(AlgoResources.accounts.account1.secretKey);
552
+ const signed = await basecoin.signTransaction({
553
+ txPrebuild: {
554
+ txHex: AlgoResources.rawTx.transfer.unsigned,
555
+ keys: [keypair.pub],
556
+ addressVersion: 1,
557
+ },
558
+ prv: keypair.prv,
559
+ });
560
+ signed.txHex.should.equal(AlgoResources.rawTx.transfer.signed);
561
+ });
562
+ it('should sign half signed transaction', async function () {
563
+ const signed = await basecoin.signTransaction({
564
+ txPrebuild: {
565
+ halfSigned: {
566
+ txHex: AlgoResources.rawTx.transfer.halfSigned,
567
+ },
568
+ keys: [
569
+ AlgoResources.accounts.account1.pubKey.toString('hex'),
570
+ AlgoResources.accounts.account3.pubKey.toString('hex'),
571
+ ],
572
+ addressVersion: 1,
573
+ },
574
+ prv: AlgoResources.accounts.account3.prvKey,
575
+ });
576
+ signed.txHex.should.equal(AlgoResources.rawTx.transfer.multisig);
577
+ });
578
+ it('should sign half signed transaction with root key', async function () {
579
+ const signed = await basecoin.signTransaction({
580
+ txPrebuild: {
581
+ halfSigned: {
582
+ txHex: AlgoResources.rootKeyData.unsignedTx,
583
+ },
584
+ keys: [
585
+ AlgoResources.rootKeyData.userKeyPair.pub,
586
+ AlgoResources.rootKeyData.backupPub,
587
+ AlgoResources.rootKeyData.bitgoPub,
588
+ ],
589
+ addressVersion: 1,
590
+ },
591
+ prv: AlgoResources.rootKeyData.userKeyPair.prv,
592
+ });
593
+ signed.txHex.should.deepEqual(AlgoResources.rootKeyData.halfSignedTx);
594
+ const factory = new lib_1.TransactionBuilderFactory(statics_1.coins.get('algo'));
595
+ const tx = await factory.from(signed.txHex).build();
596
+ const txJson = tx.toJson();
597
+ txJson.from.should.equal(AlgoResources.rootKeyData.senderAddress);
598
+ });
599
+ it('should verify sign params if the key array contains addresses', function () {
600
+ const keys = [
601
+ AlgoResources.accounts.account1.address,
602
+ AlgoResources.accounts.account2.address,
603
+ AlgoResources.accounts.account3.address,
604
+ ];
605
+ const verifiedParams = basecoin.verifySignTransactionParams({
606
+ txPrebuild: {
607
+ txHex: AlgoResources.rawTx.transfer.unsigned,
608
+ keys,
609
+ addressVersion: 1,
610
+ },
611
+ prv: AlgoResources.accounts.account2.secretKey.toString('hex'),
612
+ });
613
+ verifiedParams.should.have.properties([
614
+ 'txHex',
615
+ 'addressVersion',
616
+ 'signers',
617
+ 'prv',
618
+ 'isHalfSigned',
619
+ 'numberSigners',
620
+ ]);
621
+ const { txHex, signers, isHalfSigned } = verifiedParams;
622
+ txHex.should.be.equal(AlgoResources.rawTx.transfer.unsigned);
623
+ signers.should.be.deepEqual(keys);
624
+ isHalfSigned.should.be.equal(false);
625
+ });
626
+ it('should sign half signed transaction if the key array contains addresses', async function () {
627
+ const signed = await basecoin.signTransaction({
628
+ txPrebuild: {
629
+ halfSigned: {
630
+ txHex: AlgoResources.rawTx.transfer.halfSigned,
631
+ },
632
+ keys: [AlgoResources.accounts.account1.address, AlgoResources.accounts.account3.address],
633
+ addressVersion: 1,
634
+ },
635
+ prv: AlgoResources.accounts.account3.prvKey,
636
+ });
637
+ signed.txHex.should.equal(AlgoResources.rawTx.transfer.multisig);
638
+ });
639
+ });
640
+ describe('Sign message', () => {
641
+ it('should sign message', async function () {
642
+ const signed = await basecoin.signMessage({ prv: AlgoResources.accounts.account1.prvKey }, AlgoResources.message.unsigned);
643
+ signed.toString('hex').should.equal(AlgoResources.message.signed);
644
+ });
645
+ });
646
+ describe('Generate wallet key pair: ', () => {
647
+ it('should generate key pair', () => {
648
+ const kp = basecoin.generateKeyPair();
649
+ basecoin.isValidPub(kp.pub).should.equal(true);
650
+ basecoin.isValidPrv(kp.prv).should.equal(true);
651
+ });
652
+ it('should generate key pair from seed', () => {
653
+ const seed = Buffer.from('9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60', 'hex');
654
+ const kp = basecoin.generateKeyPair(seed);
655
+ basecoin.isValidPub(kp.pub).should.equal(true);
656
+ basecoin.isValidPrv(kp.prv).should.equal(true);
657
+ });
658
+ });
659
+ describe('Generate wallet Root key pair: ', () => {
660
+ it('should generate key pair', () => {
661
+ const kp = basecoin.generateRootKeyPair();
662
+ basecoin.isValidPub(kp.pub).should.equal(true);
663
+ basecoin.isValidPrv(kp.prv).should.equal(true);
664
+ });
665
+ it('should generate key pair from seed', () => {
666
+ const seed = Buffer.from('9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60', 'hex');
667
+ const kp = basecoin.generateRootKeyPair(seed);
668
+ basecoin.isValidPub(kp.pub).should.equal(true);
669
+ kp.pub.should.equal('d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a');
670
+ basecoin.isValidPrv(kp.prv).should.equal(true);
671
+ kp.prv.should.equal('9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a');
672
+ });
673
+ });
674
+ describe('Enable, disable and transfer Token ', () => {
675
+ it('should explain an enable token transaction hex', async function () {
676
+ const explain = await basecoin.explainTransaction({
677
+ txHex: AlgoResources.explainRawTx.enableToken,
678
+ feeInfo: { fee: '1000' },
679
+ });
680
+ explain.operations.length.should.equals(1);
681
+ explain.operations[0].type.should.equals('enableToken');
682
+ explain.operations[0].coin.should.equals('talgo:USON-16026728');
683
+ });
684
+ it('should explain an disable token transaction hex', async function () {
685
+ const explain = await basecoin.explainTransaction({
686
+ txHex: AlgoResources.explainRawTx.disableToken,
687
+ feeInfo: { fee: '1000' },
688
+ });
689
+ explain.operations.length.should.equals(1);
690
+ explain.operations[0].type.should.equals('disableToken');
691
+ explain.operations[0].coin.should.equals('talgo:USON-16026728');
692
+ });
693
+ it('should explain an transfer token transaction hex', async function () {
694
+ const explain = await basecoin.explainTransaction({
695
+ txHex: AlgoResources.explainRawTx.assetTransfer.signed,
696
+ feeInfo: { fee: '1000' },
697
+ });
698
+ explain.operations.length.should.equals(1);
699
+ explain.operations[0].type.should.equals('transferToken');
700
+ explain.operations[0].coin.should.equals('AlgoToken unknown');
701
+ });
702
+ it('should explain an enable USDT token transaction hex', async function () {
703
+ const explain = await basecoin.explainTransaction({
704
+ txHex: AlgoResources.explainRawTx.enableTokenUSDT,
705
+ feeInfo: { fee: '1000' },
706
+ });
707
+ explain.operations.length.should.equals(1);
708
+ explain.operations[0].type.should.equals('enableToken');
709
+ explain.operations[0].coin.should.equals('talgo:USDt-180447');
710
+ });
711
+ it('should explain an enable USDC token transaction hex', async function () {
712
+ const explain = await basecoin.explainTransaction({
713
+ txHex: AlgoResources.explainRawTx.enableTokenUSDC,
714
+ feeInfo: { fee: '1000' },
715
+ });
716
+ explain.operations.length.should.equals(1);
717
+ explain.operations[0].type.should.equals('enableToken');
718
+ explain.operations[0].coin.should.equals('talgo:USDC-10458941');
719
+ });
720
+ it('should explain an disable USDC token transaction hex', async function () {
721
+ const explain = await basecoin.explainTransaction({
722
+ txHex: AlgoResources.explainRawTx.disableTokenUSDC,
723
+ feeInfo: { fee: '1000' },
724
+ });
725
+ explain.operations.length.should.equals(1);
726
+ explain.operations[0].type.should.equals('disableToken');
727
+ explain.operations[0].coin.should.equals('talgo:USDC-10458941');
728
+ });
729
+ it('should explain an transfer USDC token transaction hex', async function () {
730
+ const explain = await basecoin.explainTransaction({
731
+ txHex: AlgoResources.explainRawTx.USDCAssetTransfer.signed,
732
+ feeInfo: { fee: '1000' },
733
+ });
734
+ explain.operations.length.should.equals(1);
735
+ explain.operations[0].type.should.equals('transferToken');
736
+ explain.operations[0].coin.should.equals('talgo:USDC-10458941');
737
+ });
738
+ });
739
+ describe('deriveKeyWithSeed', function () {
740
+ it('should derive key with seed', function () {
741
+ (() => {
742
+ basecoin.deriveKeyWithSeed('test');
743
+ }).should.throw('method deriveKeyWithSeed not supported for eddsa curve');
744
+ });
745
+ });
746
+ describe('Recovery', function () {
747
+ const fee = 1000;
748
+ const userKey = '{"iv":"ZJg0a0+zT+684MUl44Lm4A==","v":1,"iter":10000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"abQy0OL2468=","ct":"LNlSlTJED8jSwHCmUflzqFtRPL+PojzOgfd5mD2nmLVdAoyKCWHvAieKt7lJ7zg417CUi6Qj77/s3lbqmxVsfEsk"}';
749
+ const userPub = 'S4D7DDRAHWZIB2RCZICSRODFCNQXGANHGA7VCWBK5I37SQT6KVHXQNKMTE';
750
+ const backupKey = '{"iv":"mZY8XTvHxX8BPc1rdGQQww==","v":1,"iter":10000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"abQy0OL2468=","ct":"UQXo0EaPXb6TIZDYYhKYS9d/fRMNT6ptpl9BgJw3AVooSbO4nppWnTRYlQO7hpON4XY85hYDu/7hy91IX1z1bDDq"}';
751
+ const backupPub = '6FVGZUZOHZSXTTBRLWZDXGYSWVVYNN4ZESIEMZEMIBJCUBHC5C77OIE5RQ';
752
+ const rootAddress = 'FWLNDL7UXCSOPOQXA5VU2DMANZAYCCMBY377HKTGGMZ4GEPEJBFARDOGBA';
753
+ const walletPassphrase = 'Testing@43210!';
754
+ const recoveryDestination = 'GB3YETD5TSTBAIYGYHVWU3O3I7XGOB44HOZA5MOEF5M23CLLZKRQLEVAOA';
755
+ const bitgoPub = 'FJSWLLPRBXEGMWZY5BXA6673YKIK7JOURVCQEOWXC5TQPCXCOK3VHOO2VQ';
756
+ const nativeBalance = 10000000; // 10 ALGO
757
+ const MIN_ACCOUNT_BALANCE = 100000; // 1 AGLO
758
+ const nodeParams = {
759
+ token: '2810c2d168e8417c5f111d38d68327b8cfe2d0ddc02986490c22f8ddf4128bcd',
760
+ baseServer: 'http://localhost/',
761
+ port: 8443,
762
+ };
763
+ describe('Non-BitGo', async function () {
764
+ const sandBox = sinon_1.default.createSandbox();
765
+ const expectedAmount = new bignumber_js_1.default(nativeBalance).minus(fee).minus(MIN_ACCOUNT_BALANCE).toString();
766
+ afterEach(function () {
767
+ sandBox.verifyAndRestore();
768
+ });
769
+ it('should build and sign the recovery tx', async function () {
770
+ const getBalanceStub = sandBox.stub(algo_1.Algo.prototype, 'getAccountBalance').resolves(nativeBalance);
771
+ const recovery = await basecoin.recover({
772
+ userKey,
773
+ backupKey,
774
+ rootAddress,
775
+ walletPassphrase,
776
+ fee,
777
+ bitgoKey: bitgoPub,
778
+ recoveryDestination: recoveryDestination,
779
+ firstRound: 5002596,
780
+ nodeParams,
781
+ });
782
+ recovery.should.not.be.undefined();
783
+ recovery.should.have.property('id');
784
+ recovery.should.have.property('tx');
785
+ recovery.should.have.property('fee');
786
+ recovery.should.have.property('coin', 'talgo');
787
+ recovery.should.have.property('firstRound');
788
+ recovery.should.have.property('lastRound');
789
+ getBalanceStub.callCount.should.equal(1);
790
+ const factory = new src_1.AlgoLib.TransactionBuilderFactory(statics_1.coins.get('algo'));
791
+ const txBuilder = factory.from(recovery.tx);
792
+ const tx = await txBuilder.build();
793
+ const txBroadcastFormat = Buffer.from(tx.toBroadcastFormat()).toString('base64');
794
+ txBroadcastFormat.should.deepEqual(recovery.tx);
795
+ const txJson = tx.toJson();
796
+ txJson.amount.should.equal(expectedAmount);
797
+ txJson.to.should.equal(recoveryDestination);
798
+ txJson.from.should.equal(rootAddress);
799
+ txJson.fee.should.equal(fee);
800
+ });
801
+ it('should throw for invalid rootAddress', async function () {
802
+ const invalidRootAddress = 'randomstring';
803
+ await assert_1.default.rejects(async () => {
804
+ await basecoin.recover({
805
+ userKey,
806
+ backupKey,
807
+ rootAddress: invalidRootAddress,
808
+ walletPassphrase,
809
+ fee,
810
+ recoveryDestination: recoveryDestination,
811
+ firstRound: 5002596,
812
+ nodeParams,
813
+ });
814
+ }, { message: 'invalid rootAddress, got: ' + invalidRootAddress });
815
+ });
816
+ it('should throw for invalid recoveryDestination', async function () {
817
+ const invalidRecoveryDestination = 'randomstring';
818
+ await assert_1.default.rejects(async () => {
819
+ await basecoin.recover({
820
+ userKey,
821
+ backupKey,
822
+ rootAddress,
823
+ walletPassphrase,
824
+ fee,
825
+ recoveryDestination: invalidRecoveryDestination,
826
+ firstRound: 5002596,
827
+ nodeParams,
828
+ });
829
+ }, { message: 'invalid recoveryDestination, got: ' + invalidRecoveryDestination });
830
+ });
831
+ it('should throw if there is no enough balance to recover', async function () {
832
+ const getBalanceStub = sandBox.stub(algo_1.Algo.prototype, 'getAccountBalance').resolves(100500);
833
+ await assert_1.default.rejects(async () => {
834
+ await basecoin.recover({
835
+ userKey,
836
+ backupKey,
837
+ rootAddress,
838
+ fee,
839
+ walletPassphrase,
840
+ bitgoKey: bitgoPub,
841
+ recoveryDestination,
842
+ firstRound: 5003596,
843
+ nodeParams,
844
+ });
845
+ }, { message: 'Insufficient balance to recover, got balance: 100500 fee: 1000 min account balance: 100000' });
846
+ getBalanceStub.callCount.should.equal(1);
847
+ });
848
+ it('should throw if the walletPassphrase is undefined', async function () {
849
+ await assert_1.default.rejects(async () => {
850
+ await basecoin.recover({
851
+ userKey,
852
+ backupKey,
853
+ rootAddress,
854
+ fee,
855
+ recoveryDestination,
856
+ firstRound: 5003596,
857
+ nodeParams,
858
+ });
859
+ }, { message: 'walletPassphrase is required for non-bitgo recovery' });
860
+ });
861
+ it('should throw if the walletPassphrase is wrong', async function () {
862
+ await assert_1.default.rejects(async () => {
863
+ await basecoin.recover({
864
+ userKey,
865
+ backupKey,
866
+ rootAddress,
867
+ bitgoKey: bitgoPub,
868
+ walletPassphrase: 'wrongpassword',
869
+ fee,
870
+ recoveryDestination,
871
+ firstRound: 5003596,
872
+ nodeParams,
873
+ });
874
+ }, {
875
+ message: "unable to decrypt userKey or backupKey with the walletPassphrase provided, got error: password error - ccm: tag doesn't match",
876
+ });
877
+ });
878
+ it('should throw if bitgo key is not provided', async function () {
879
+ await assert_1.default.rejects(async () => {
880
+ await basecoin.recover({
881
+ userKey,
882
+ backupKey,
883
+ rootAddress,
884
+ walletPassphrase,
885
+ fee,
886
+ recoveryDestination,
887
+ firstRound: 5003596,
888
+ nodeParams,
889
+ });
890
+ }, {
891
+ message: 'bitgo public key from the keyCard is required for non-bitgo recovery',
892
+ });
893
+ });
894
+ it('should be able to pass a utf-8 encoded note', async function () {
895
+ const note = 'Non-BitGo Recovery Sweep Tx';
896
+ sandBox.stub(algo_1.Algo.prototype, 'getAccountBalance').resolves(nativeBalance);
897
+ const recovery = await basecoin.recover({
898
+ userKey,
899
+ backupKey,
900
+ rootAddress,
901
+ walletPassphrase,
902
+ fee,
903
+ bitgoKey: bitgoPub,
904
+ recoveryDestination: recoveryDestination,
905
+ firstRound: 5002596,
906
+ nodeParams,
907
+ note,
908
+ });
909
+ recovery.should.not.be.undefined();
910
+ recovery.note.should.be.equal(note);
911
+ });
912
+ });
913
+ describe('Unsigned Sweep', function () {
914
+ const sandBox = sinon_1.default.createSandbox();
915
+ const expectedAmount = new bignumber_js_1.default(nativeBalance).minus(fee).minus(MIN_ACCOUNT_BALANCE).toString();
916
+ let getBalanceStub;
917
+ beforeEach(function () {
918
+ getBalanceStub = sandBox.stub(algo_1.Algo.prototype, 'getAccountBalance').resolves(nativeBalance);
919
+ });
920
+ afterEach(function () {
921
+ sandBox.verifyAndRestore();
922
+ });
923
+ it('should build unsigned sweep tx', async function () {
924
+ const recovery = await basecoin.recover({
925
+ userKey: userPub,
926
+ backupKey: backupPub,
927
+ bitgoKey: bitgoPub,
928
+ rootAddress,
929
+ walletPassphrase,
930
+ fee,
931
+ recoveryDestination,
932
+ firstRound: 5003596,
933
+ nodeParams,
934
+ });
935
+ getBalanceStub.callCount.should.equal(1);
936
+ recovery.should.not.be.undefined();
937
+ recovery.should.have.property('txHex');
938
+ recovery.should.have.property('type');
939
+ recovery.should.have.property('amount');
940
+ recovery.should.have.property('feeInfo');
941
+ recovery.should.have.property('coin', 'talgo');
942
+ recovery.firstRound.should.not.be.undefined();
943
+ recovery.lastRound.should.not.be.undefined();
944
+ recovery.should.have.property('keys');
945
+ recovery.keys.should.deepEqual([userPub, backupPub, bitgoPub]);
946
+ recovery.addressVersion.should.equal(1);
947
+ getBalanceStub.callCount.should.equal(1);
948
+ const factory = new src_1.AlgoLib.TransactionBuilderFactory(statics_1.coins.get('algo'));
949
+ const txBuilder = factory.from(recovery.txHex);
950
+ const tx = await txBuilder.build();
951
+ Buffer.from(tx.toBroadcastFormat()).toString('hex').should.deepEqual(recovery.txHex);
952
+ const txJson = tx.toJson();
953
+ txJson.amount.should.equal(expectedAmount);
954
+ txJson.to.should.equal(recoveryDestination);
955
+ txJson.from.should.equal(rootAddress);
956
+ txJson.fee.should.equal(fee);
957
+ });
958
+ });
959
+ describe('Recovery with root keys', function () {
960
+ const sandBox = sinon_1.default.createSandbox();
961
+ let userKp;
962
+ let backupKp;
963
+ let rootAddress;
964
+ let encryptedUserPrv;
965
+ let encryptedBackupPrv;
966
+ const expectedAmount = new bignumber_js_1.default(nativeBalance).minus(fee).minus(MIN_ACCOUNT_BALANCE).toString();
967
+ let getBalanceStub;
968
+ beforeEach(function () {
969
+ const userSeed = Buffer.from('9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60', 'hex');
970
+ userKp = basecoin.generateRootKeyPair(userSeed);
971
+ encryptedUserPrv = bitgo.encrypt({
972
+ input: userKp.prv,
973
+ password: walletPassphrase,
974
+ });
975
+ (0, assert_1.default)(userKp.pub);
976
+ const backupSeed = Buffer.from('6d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60', 'hex');
977
+ backupKp = basecoin.generateRootKeyPair(backupSeed);
978
+ encryptedBackupPrv = bitgo.encrypt({
979
+ input: backupKp.prv,
980
+ password: walletPassphrase,
981
+ });
982
+ const bitgoPub = 'FJSWLLPRBXEGMWZY5BXA6673YKIK7JOURVCQEOWXC5TQPCXCOK3VHOO2VQ';
983
+ const userAddress = src_1.AlgoLib.algoUtils.privateKeyToAlgoAddress(userKp.prv);
984
+ const backupAddress = src_1.AlgoLib.algoUtils.privateKeyToAlgoAddress(backupKp.prv);
985
+ rootAddress = src_1.AlgoLib.algoUtils.multisigAddress(1, 2, [userAddress, backupAddress, bitgoPub]);
986
+ });
987
+ afterEach(function () {
988
+ sandBox.verifyAndRestore();
989
+ });
990
+ it('should build and sign non-bitgo recovery tx with root keys', async function () {
991
+ getBalanceStub = sandBox.stub(algo_1.Algo.prototype, 'getAccountBalance').resolves(nativeBalance);
992
+ const recovery = await basecoin.recover({
993
+ userKey: encryptedUserPrv,
994
+ backupKey: encryptedBackupPrv,
995
+ rootAddress,
996
+ walletPassphrase,
997
+ fee,
998
+ bitgoKey: bitgoPub,
999
+ recoveryDestination: recoveryDestination,
1000
+ firstRound: 5002596,
1001
+ nodeParams,
1002
+ });
1003
+ recovery.should.not.be.undefined();
1004
+ recovery.should.have.property('id');
1005
+ recovery.should.have.property('tx');
1006
+ recovery.should.have.property('fee');
1007
+ recovery.should.have.property('coin', 'talgo');
1008
+ recovery.should.have.property('firstRound');
1009
+ recovery.should.have.property('lastRound');
1010
+ getBalanceStub.callCount.should.equal(1);
1011
+ const factory = new src_1.AlgoLib.TransactionBuilderFactory(statics_1.coins.get('algo'));
1012
+ const txBuilder = factory.from(recovery.tx);
1013
+ const tx = await txBuilder.build();
1014
+ const txBroadcastFormat = Buffer.from(tx.toBroadcastFormat()).toString('base64');
1015
+ txBroadcastFormat.should.deepEqual(recovery.tx);
1016
+ const txJson = tx.toJson();
1017
+ txJson.amount.should.equal(expectedAmount);
1018
+ txJson.to.should.equal(recoveryDestination);
1019
+ txJson.from.should.equal(rootAddress);
1020
+ txJson.fee.should.equal(fee);
1021
+ });
1022
+ it('should build unsigned sweep tx', async function () {
1023
+ getBalanceStub = sandBox.stub(algo_1.Algo.prototype, 'getAccountBalance').resolves(nativeBalance);
1024
+ const recovery = await basecoin.recover({
1025
+ userKey: userKp.pub,
1026
+ backupKey: backupKp.pub,
1027
+ bitgoKey: bitgoPub,
1028
+ rootAddress,
1029
+ walletPassphrase,
1030
+ fee,
1031
+ recoveryDestination,
1032
+ firstRound: 5003596,
1033
+ nodeParams,
1034
+ });
1035
+ getBalanceStub.callCount.should.equal(1);
1036
+ recovery.should.not.be.undefined();
1037
+ recovery.should.have.property('txHex');
1038
+ recovery.should.have.property('type');
1039
+ recovery.should.have.property('amount');
1040
+ recovery.should.have.property('feeInfo');
1041
+ recovery.should.have.property('coin', 'talgo');
1042
+ recovery.firstRound.should.not.be.undefined();
1043
+ recovery.lastRound.should.not.be.undefined();
1044
+ recovery.should.have.property('keys');
1045
+ recovery.keys.should.deepEqual([userKp.pub, backupKp.pub, bitgoPub]);
1046
+ recovery.addressVersion.should.equal(1);
1047
+ getBalanceStub.callCount.should.equal(1);
1048
+ const factory = new src_1.AlgoLib.TransactionBuilderFactory(statics_1.coins.get('algo'));
1049
+ const txBuilder = factory.from(recovery.txHex);
1050
+ const tx = await txBuilder.build();
1051
+ Buffer.from(tx.toBroadcastFormat()).toString('hex').should.deepEqual(recovery.txHex);
1052
+ const txJson = tx.toJson();
1053
+ txJson.amount.should.equal(expectedAmount);
1054
+ txJson.to.should.equal(recoveryDestination);
1055
+ txJson.from.should.equal(rootAddress);
1056
+ txJson.fee.should.equal(fee);
1057
+ });
1058
+ });
1059
+ });
1060
+ describe('AuditKey', () => {
1061
+ const { key } = algoBackupKey_1.algoBackupKey;
1062
+ const walletPassphrase = 'ZQ8MhxT84m4P';
1063
+ it('should return for valid inputs', () => {
1064
+ basecoin.assertIsValidKey({
1065
+ encryptedPrv: key,
1066
+ walletPassphrase,
1067
+ });
1068
+ });
1069
+ it('should throw error if the walletPassphrase is incorrect', () => {
1070
+ assert_1.default.throws(() => {
1071
+ basecoin.assertIsValidKey({
1072
+ encryptedPrv: key,
1073
+ walletPassphrase: 'foo',
1074
+ });
1075
+ }, { message: "failed to decrypt prv: ccm: tag doesn't match" });
1076
+ });
1077
+ it('should throw error if the key is altered', () => {
1078
+ const alteredKey = key.replace(/[0-9]/g, '0');
1079
+ assert_1.default.throws(() => {
1080
+ basecoin.assertIsValidKey({
1081
+ encryptedPrv: alteredKey,
1082
+ walletPassphrase,
1083
+ });
1084
+ }, { message: 'failed to decrypt prv: json decrypt: invalid parameters' });
1085
+ });
1086
+ it('should throw error if the key is not a valid key', () => {
1087
+ const invalidKey = '#@)$#($*@)#($*';
1088
+ const encryptedPrv = (0, sdk_api_1.encrypt)(walletPassphrase, invalidKey);
1089
+ assert_1.default.throws(() => {
1090
+ basecoin.assertIsValidKey({
1091
+ encryptedPrv,
1092
+ walletPassphrase,
1093
+ });
1094
+ }, { message: 'Invalid private key: Invalid base32 characters' });
1095
+ });
1096
+ });
1097
+ describe('blind signing token enablement protection', () => {
1098
+ let wallet;
1099
+ const bgUrl = sdk_core_1.common.Environments['mock'].uri;
1100
+ before(() => {
1101
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
1102
+ bitgo.safeRegister('talgo', src_1.Talgo.createInstance);
1103
+ bitgo.initializeTestVars();
1104
+ basecoin = bitgo.coin('talgo');
1105
+ wallet = new sdk_core_1.Wallet(bitgo, basecoin, {
1106
+ id: '123',
1107
+ coin: 'talgo',
1108
+ keys: ['1', '2', '3'],
1109
+ coinSpecific: {
1110
+ rootAddress: '123',
1111
+ },
1112
+ type: 'hot',
1113
+ });
1114
+ });
1115
+ it('should verify a valid token enablement transaction', async function () {
1116
+ const verifyTransactionStub = (0, sinon_1.spy)(basecoin, 'verifyTransaction');
1117
+ (0, nock_1.default)(bgUrl)
1118
+ .post(`/api/v2/talgo/wallet/${wallet.id()}/tx/build`)
1119
+ .reply(200, {
1120
+ txHex: 'iaRhcmN2xCBfnMgYtbyG4RL1DspYhxQeyn9QrJ+s2ZcDTcxK+yOH+KNmZWXNA+iiZnbOA2tlJKNnZW6sdGVzdG5ldC12MS4womdoxCBIY7UYpLPITsgQ8i1PEIHLD3HwWaesIN7GL39w5Qk6IqJsds4Da2kMo3NuZMQgX5zIGLW8huES9Q7KWIcUHsp/UKyfrNmXA03MSvsjh/ikdHlwZaVheGZlcqR4YWlkzgmpOkY=',
1121
+ txHash: 'ARYMOXMKZWM372JBFBTADZNJZU7S5HK44NZDZLVX5UR5UPIWT7FA',
1122
+ txInfo: {
1123
+ id: 'ARYMOXMKZWM372JBFBTADZNJZU7S5HK44NZDZLVX5UR5UPIWT7FA',
1124
+ type: 'axfer',
1125
+ from: 'L6OMQGFVXSDOCEXVB3FFRBYUD3FH6UFMT6WNTFYDJXGEV6ZDQ74EXGF6BE',
1126
+ fee: 1000,
1127
+ firstRound: 57369892,
1128
+ lastRound: 57370892,
1129
+ note: {},
1130
+ tokenId: 162085446,
1131
+ genesisID: 'testnet-v1.0',
1132
+ genesisHash: 'SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=',
1133
+ to: 'L6OMQGFVXSDOCEXVB3FFRBYUD3FH6UFMT6WNTFYDJXGEV6ZDQ74EXGF6BE',
1134
+ amount: '0',
1135
+ txType: 'enableToken',
1136
+ tokenName: 'TALGO',
1137
+ },
1138
+ feeInfo: {
1139
+ size: 251,
1140
+ fee: 1000,
1141
+ feeRate: 4,
1142
+ feeString: '1000',
1143
+ },
1144
+ keys: [
1145
+ '42MIYL2KBISV6WJRALTTSXHBEGLNF7MMQ74FGSYUCT5YP3V2KENJGRFVVQ',
1146
+ 'MAGXZTDFW5QEXUKOUDIGHTXOKDW7TNQEDLWPBEZEL3VFU3YAA2PGYRS65M',
1147
+ 'TMEJTI7XNCACDG3BTODINW6CMR6ARYIKTCFPA2GMIXL4X5Q4BCE6VHMWAM',
1148
+ ],
1149
+ addressVersion: 1,
1150
+ coin: 'talgo',
1151
+ });
1152
+ const validatePwdStub = (0, sinon_1.stub)(wallet, 'getKeychainsAndValidatePassphrase').resolves([]);
1153
+ const signTxStub = (0, sinon_1.stub)(wallet, 'signTransaction').resolves({});
1154
+ await wallet.sendTokenEnablements({
1155
+ verification: { verifyTokenEnablement: true },
1156
+ enableTokens: [
1157
+ {
1158
+ name: 'talgo:JPT-162085446',
1159
+ address: 'L6OMQGFVXSDOCEXVB3FFRBYUD3FH6UFMT6WNTFYDJXGEV6ZDQ74EXGF6BE',
1160
+ },
1161
+ ],
1162
+ });
1163
+ verifyTransactionStub.called.should.be.true();
1164
+ verifyTransactionStub.restore();
1165
+ validatePwdStub.restore();
1166
+ signTxStub.restore();
1167
+ });
1168
+ it('should throw error when invalid token enablement transaction is returned', async () => {
1169
+ const verifyTransactionStub = (0, sinon_1.spy)(basecoin, 'verifyTransaction');
1170
+ (0, nock_1.default)(bgUrl)
1171
+ .post(`/api/v2/talgo/wallet/${wallet.id()}/tx/build`)
1172
+ .reply(200, {
1173
+ txHex: 'iaRhcmN2xCBfnMgYtbyG4RL1DspYhxQeyn9QrJ+s2ZcDTcxK+yOH+KNmZWXNA+iiZnbOA2tpeqNnZW6sdGVzdG5ldC12MS4womdoxCBIY7UYpLPITsgQ8i1PEIHLD3HwWaesIN7GL39w5Qk6IqJsds4Da21io3NuZMQgX5zIGLW8huES9Q7KWIcUHsp/UKyfrNmXA03MSvsjh/ikdHlwZaVheGZlcqR4YWlkzgACwN8=',
1174
+ txHash: 'YPQGYNBOCPXMBFTBZH2AQGCDZ3C2762T6EYQY46F7LRG2URX6DLA',
1175
+ txInfo: {
1176
+ id: 'YPQGYNBOCPXMBFTBZH2AQGCDZ3C2762T6EYQY46F7LRG2URX6DLA',
1177
+ type: 'axfer',
1178
+ from: 'L6OMQGFVXSDOCEXVB3FFRBYUD3FH6UFMT6WNTFYDJXGEV6ZDQ74EXGF6BE',
1179
+ fee: 1000,
1180
+ firstRound: 57371002,
1181
+ lastRound: 57372002,
1182
+ note: {},
1183
+ tokenId: 180447,
1184
+ genesisID: 'testnet-v1.0',
1185
+ genesisHash: 'SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=',
1186
+ to: 'L6OMQGFVXSDOCEXVB3FFRBYUD3FH6UFMT6WNTFYDJXGEV6ZDQ74EXGF6BE',
1187
+ amount: '0',
1188
+ txType: 'enableToken',
1189
+ tokenName: 'TALGO',
1190
+ },
1191
+ feeInfo: {
1192
+ size: 251,
1193
+ fee: 1000,
1194
+ feeRate: 4,
1195
+ feeString: '1000',
1196
+ },
1197
+ keys: [
1198
+ '42MIYL2KBISV6WJRALTTSXHBEGLNF7MMQ74FGSYUCT5YP3V2KENJGRFVVQ',
1199
+ 'MAGXZTDFW5QEXUKOUDIGHTXOKDW7TNQEDLWPBEZEL3VFU3YAA2PGYRS65M',
1200
+ 'TMEJTI7XNCACDG3BTODINW6CMR6ARYIKTCFPA2GMIXL4X5Q4BCE6VHMWAM',
1201
+ ],
1202
+ addressVersion: 1,
1203
+ coin: 'talgo',
1204
+ });
1205
+ (0, sinon_1.stub)(wallet, 'getKeychainsAndValidatePassphrase').resolves([]);
1206
+ (0, sinon_1.stub)(wallet, 'signTransaction').resolves({});
1207
+ const { success, failure } = await wallet.sendTokenEnablements({
1208
+ verification: { verifyTokenEnablement: true },
1209
+ enableTokens: [
1210
+ {
1211
+ name: 'talgo:JPT-162085446',
1212
+ address: 'L6OMQGFVXSDOCEXVB3FFRBYUD3FH6UFMT6WNTFYDJXGEV6ZDQ74EXGF6BE',
1213
+ },
1214
+ ],
1215
+ });
1216
+ verifyTransactionStub.called.should.be.true();
1217
+ success.length.should.equal(0);
1218
+ failure.length.should.equal(1);
1219
+ failure[0].message.should.equal('Token enablement verification failed: expected token ID 162085446 but transaction has token ID 180447');
1220
+ });
1221
+ });
1222
+ });
1223
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxnby5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvdW5pdC9hbGdvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsbUNBQTJDO0FBQzNDLG1EQUErRDtBQUMvRCxpREFBd0Q7QUFDeEQsZ0VBQWtEO0FBQ2xELG1DQUFxQztBQUNyQyxpREFBNEM7QUFDNUMsK0NBQW9EO0FBQ3BELG9EQUE0QjtBQUM1Qix5Q0FBc0M7QUFDdEMsZ0VBQXFDO0FBQ3JDLHVDQUEwRDtBQUMxRCxtREFBK0Q7QUFDL0QsNERBQXlEO0FBQ3pELGdEQUF3QjtBQUV4QixRQUFRLENBQUMsT0FBTyxFQUFFO0lBQ2hCLElBQUksS0FBbUIsQ0FBQztJQUN4QixJQUFJLFFBQVEsQ0FBQztJQUNiLE1BQU0sUUFBUSxHQUFHLGFBQWEsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO0lBRWpELE1BQU0sQ0FBQztRQUNMLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxrQkFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdEQsS0FBSyxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsV0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2xELEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzNCLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2pDLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGVBQWUsRUFBRSxHQUFHLEVBQUU7UUFDN0IsRUFBRSxDQUFDLHVCQUF1QixFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ3JDLE1BQU0sUUFBUTtpQkFDWCxrQkFBa0IsQ0FBQztnQkFDbEIsTUFBTSxFQUFFLEVBQUU7YUFDWCxDQUFDO2lCQUNELE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLCtCQUErQixD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dUcsQ0FDeEcsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFsZ29MaWIsIFRhbGdvIH0gZnJvbSAnLi4vLi4vc3JjJztcbmltcG9ydCB7IFRlc3RCaXRHbywgVGVzdEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLXRlc3QnO1xuaW1wb3J0IHsgQml0R29BUEksIGVuY3J5cHQgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstYXBpJztcbmltcG9ydCAqIGFzIEFsZ29SZXNvdXJjZXMgZnJvbSAnLi4vZml4dHVyZXMvYWxnbyc7XG5pbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBjb2lucyB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0IFNpbm9uLCB7IFNpbm9uU3R1Yiwgc3B5LCBzdHViIH0gZnJvbSAnc2lub24nO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgQWxnbyB9IGZyb20gJy4uLy4uL3NyYy9hbGdvJztcbmltcG9ydCBCaWdOdW1iZXIgZnJvbSAnYmlnbnVtYmVyLmpzJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkgfSBmcm9tICcuLi8uLi9zcmMvbGliJztcbmltcG9ydCB7IGNvbW1vbiwgS2V5UGFpciwgV2FsbGV0IH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgYWxnb0JhY2t1cEtleSB9IGZyb20gJy4vZml4dHVyZXMvYWxnb0JhY2t1cEtleSc7XG5pbXBvcnQgbm9jayBmcm9tICdub2NrJztcblxuZGVzY3JpYmUoJ0FMR086JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGJhc2Vjb2luO1xuICBjb25zdCByZWNlaXZlciA9IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDI7XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ3RhbGdvJywgVGFsZ28uY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIGJhc2Vjb2luID0gYml0Z28uY29pbigndGFsZ28nKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1Nob3VsZCBGYWlsOiAnLCAoKSA9PiB7XG4gICAgaXQoJ0RvZXMgbm90IGhhdmUgYSB0eEhleCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHBhcmFtczoge30sXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIGV4cGxhaW4gdHggcGFyYW1ldGVycycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ0RvZXMgbm90IGhhdmUgYSBmZWUnLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAuZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgIHR4SGV4OiAnU29tZSBWYWxpZCBIZXgnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIGV4cGxhaW4gdHggcGFyYW1ldGVycycpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVHJhbnNmZXIgQnVpbGRlcjogJywgKCkgPT4ge1xuICAgIGNvbnN0IGJ1aWxkQmFzZVRyYW5zZmVyVHJhbnNhY3Rpb24gPSAoeyBkZXN0aW5hdGlvbiwgYW1vdW50ID0gMTAwMDAsIHNlbmRlciwgbWVtbyA9ICcnIH0pID0+IHtcbiAgICAgIGNvbnN0IGZhY3RvcnkgPSBuZXcgQWxnb0xpYi5UcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCgnYWxnbycpKTtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICBjb25zdCBsZWFzZSA9IG5ldyBVaW50OEFycmF5KHJhbmRvbUJ5dGVzKDMyKSk7XG4gICAgICBjb25zdCBub3RlID0gbmV3IFVpbnQ4QXJyYXkoQnVmZmVyLmZyb20obWVtbywgJ3V0Zi04JykpO1xuICAgICAgdHhCdWlsZGVyXG4gICAgICAgIC5zZW5kZXIoeyBhZGRyZXNzOiBzZW5kZXIgfSlcbiAgICAgICAgLnRvKHsgYWRkcmVzczogZGVzdGluYXRpb24gfSlcbiAgICAgICAgLmFtb3VudChhbW91bnQpXG4gICAgICAgIC5pc0ZsYXRGZWUodHJ1ZSlcbiAgICAgICAgLmZlZSh7XG4gICAgICAgICAgZmVlOiAnMTAwMCcsXG4gICAgICAgIH0pXG4gICAgICAgIC5maXJzdFJvdW5kKDEpXG4gICAgICAgIC5sYXN0Um91bmQoMTAwKVxuICAgICAgICAubGVhc2UobGVhc2UpXG4gICAgICAgIC5ub3RlKG5vdGUpXG4gICAgICAgIC50ZXN0bmV0KCk7XG4gICAgICByZXR1cm4gdHhCdWlsZGVyO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBCdWlsZCBhbiB1bnNpZ25lZCBhY2NvdW50LWxpYiBzaW5nbGUtc2lnbmF0dXJlIHNlbmQgdHJhbnNhY3Rpb25cbiAgICAgKiBAcGFyYW0gc2VuZGVyIFRoZSBzZW5kZXJzIGFkZHJlc3NcbiAgICAgKiBAcGFyYW0gZGVzdGluYXRpb24gVGhlIGRlc3RpbmF0aW9uIGFkZHJlc3Mgb2YgdGhlIHRyYW5zYWN0aW9uXG4gICAgICogQHBhcmFtIGFtb3VudCBUaGUgYW1vdW50IHRvIHNlbmQgdG8gdGhlIHJlY2lwaWVudFxuICAgICAqIEBwYXJhbSBtZW1vIE9wdGlvbmFsIG5vdGUgd2l0aCB0aGUgdHJhbnNhY3Rpb25cbiAgICAgKi9cbiAgICBjb25zdCBidWlsZFVuc2lnbmVkVHJhbnNhY3Rpb24gPSBhc3luYyBmdW5jdGlvbiAoeyBzZW5kZXIsIGRlc3RpbmF0aW9uLCBhbW91bnQgPSAxMDAwMCwgbWVtbyA9ICcnIH0pIHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGJ1aWxkQmFzZVRyYW5zZmVyVHJhbnNhY3Rpb24oeyBzZW5kZXIsIGRlc3RpbmF0aW9uLCBhbW91bnQsIG1lbW8gfSk7XG4gICAgICByZXR1cm4gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEJ1aWxkIGEgc2lnbmVkIGFjY291bnQtbGliIHNpbmdsZS1zaWduYXR1cmUgc2VuZCB0cmFuc2FjdGlvblxuICAgICAqIEBwYXJhbSBzZW5kZXIgVGhlIHNlbmRlcnMgYWRkcmVzc1xuICAgICAqIEBwYXJhbSBkZXN0aW5hdGlvbiBUaGUgZGVzdGluYXRpb24gYWRkcmVzcyBvZiB0aGUgdHJhbnNhY3Rpb25cbiAgICAgKiBAcGFyYW0gYW1vdW50IFRoZSBhbW91bnQgdG8gc2VuZCB0byB0aGUgcmVjaXBpZW50XG4gICAgICogQHBhcmFtIG1lbW8gT3B0aW9uYWwgbm90ZSB3aXRoIHRoZSB0cmFuc2FjdGlvblxuICAgICAqL1xuICAgIGNvbnN0IGJ1aWxkU2lnbmVkVHJhbnNhY3Rpb24gPSBhc3luYyBmdW5jdGlvbiAoeyBzZW5kZXIsIGRlc3RpbmF0aW9uLCBhbW91bnQgPSAxMDAwMCwgbWVtbyA9ICcnIH0pIHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGJ1aWxkQmFzZVRyYW5zZmVyVHJhbnNhY3Rpb24oeyBzZW5kZXIsIGRlc3RpbmF0aW9uLCBhbW91bnQsIG1lbW8gfSk7XG4gICAgICB0eEJ1aWxkZXIubnVtYmVyT2ZTaWduZXJzKDEpO1xuICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDEucHJ2S2V5IH0pO1xuICAgICAgcmV0dXJuIGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBCdWlsZCBhIG11bHRpLXNpZ25lZCBhY2NvdW50LWxpYiBzaW5nbGUtc2lnbmF0dXJlIHNlbmQgdHJhbnNhY3Rpb25cbiAgICAgKiBAcGFyYW0gc2VuZGVycyBUaGUgbGlzdCBvZiBzZW5kZXJzXG4gICAgICogQHBhcmFtIGRlc3RpbmF0aW9uIFRoZSBkZXN0aW5hdGlvbiBhZGRyZXNzIG9mIHRoZSB0cmFuc2FjdGlvblxuICAgICAqIEBwYXJhbSBhbW91bnQgVGhlIGFtb3VudCB0byBzZW5kIHRvIHRoZSByZWNpcGllbnRcbiAgICAgKiBAcGFyYW0gbWVtbyBPcHRpb25hbCBub3RlIHdpdGggdGhlIHRyYW5zYWN0aW9uXG4gICAgICovXG4gICAgY29uc3QgYnVpbGRNdWx0aVNpZ25lZFRyYW5zYWN0aW9uID0gYXN5bmMgZnVuY3Rpb24gKHsgc2VuZGVycywgZGVzdGluYXRpb24sIGFtb3VudCA9IDEwMDAwLCBtZW1vID0gJycgfSkge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gYnVpbGRCYXNlVHJhbnNmZXJUcmFuc2FjdGlvbih7IHNlbmRlcjogc2VuZGVyc1swXSwgZGVzdGluYXRpb24sIGFtb3VudCwgbWVtbyB9KTtcbiAgICAgIHR4QnVpbGRlci5udW1iZXJPZlNpZ25lcnMoMik7XG4gICAgICB0eEJ1aWxkZXIuc2V0U2lnbmVycyhzZW5kZXJzKTtcbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxLnBydktleSB9KTtcbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQzLnBydktleSB9KTtcbiAgICAgIHJldHVybiBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICB9O1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGFuIHVuc2lnbmVkIHRyYW5zZmVyIHRyYW5zYWN0aW9uIGhleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgudHJhbnNmZXIudW5zaWduZWQsXG4gICAgICAgIGZlZUluZm86IHsgZmVlOiAnMTAwMCcgfSxcbiAgICAgIH0pO1xuICAgICAgZXhwbGFpbi5vdXRwdXRBbW91bnQuc2hvdWxkLmVxdWFsKCcxMDAwMCcpO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoJzEwMDAwJyk7XG4gICAgICBleHBsYWluLm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwocmVjZWl2ZXIuYWRkcmVzcyk7XG4gICAgICBCdWZmZXIuZnJvbShleHBsYWluLm91dHB1dHNbMF0ubWVtbykudG9TdHJpbmcoKS5zaG91bGQuZXF1YWwoQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgudHJhbnNmZXIubm90ZSk7XG4gICAgICBleHBsYWluLmZlZS5zaG91bGQuZXF1YWwoMTAwMCk7XG4gICAgICBleHBsYWluLmNoYW5nZUFtb3VudC5zaG91bGQuZXF1YWwoJzAnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIHNpZ25lZCB0cmFuc2ZlciB0cmFuc2FjdGlvbiBoZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhIZXg6IEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LnRyYW5zZmVyLnNpZ25lZCxcbiAgICAgICAgZmVlSW5mbzogeyBmZWU6ICcxMDAwJyB9LFxuICAgICAgfSk7XG4gICAgICBleHBsYWluLm91dHB1dEFtb3VudC5zaG91bGQuZXF1YWwoJzEwMDAwJyk7XG4gICAgICBleHBsYWluLm91dHB1dHNbMF0uYW1vdW50LnNob3VsZC5lcXVhbCgnMTAwMDAnKTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChyZWNlaXZlci5hZGRyZXNzKTtcbiAgICAgIEJ1ZmZlci5mcm9tKGV4cGxhaW4ub3V0cHV0c1swXS5tZW1vKS50b1N0cmluZygpLnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5ub3RlKTtcbiAgICAgIGV4cGxhaW4uZmVlLnNob3VsZC5lcXVhbCgxMDAwKTtcbiAgICAgIGV4cGxhaW4uY2hhbmdlQW1vdW50LnNob3VsZC5lcXVhbCgnMCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGEgbXVsdGlTaWcgdHJhbnNmZXIgdHJhbnNhY3Rpb24gaGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4SGV4OiBBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5tdWx0aVNpZ25lZCxcbiAgICAgICAgZmVlSW5mbzogeyBmZWU6ICcxMDAwJyB9LFxuICAgICAgfSk7XG4gICAgICBleHBsYWluLm91dHB1dEFtb3VudC5zaG91bGQuZXF1YWwoJzEwMDAwJyk7XG4gICAgICBleHBsYWluLm91dHB1dHNbMF0uYW1vdW50LnNob3VsZC5lcXVhbCgnMTAwMDAnKTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChyZWNlaXZlci5hZGRyZXNzKTtcbiAgICAgIEJ1ZmZlci5mcm9tKGV4cGxhaW4ub3V0cHV0c1swXS5tZW1vKS50b1N0cmluZygpLnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5ub3RlKTtcbiAgICAgIGV4cGxhaW4uZmVlLnNob3VsZC5lcXVhbCgxMDAwKTtcbiAgICAgIGV4cGxhaW4uY2hhbmdlQW1vdW50LnNob3VsZC5lcXVhbCgnMCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGEgaGFsZiBzaWduZWQgdHJhbnNmZXIgdHJhbnNhY3Rpb24gaGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIGhhbGZTaWduZWQ6IHtcbiAgICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgudHJhbnNmZXIuaGFsZlNpZ25lZCxcbiAgICAgICAgfSxcbiAgICAgICAgZmVlSW5mbzogeyBmZWU6ICcxMDAwJyB9LFxuICAgICAgfSk7XG4gICAgICBleHBsYWluLm91dHB1dEFtb3VudC5zaG91bGQuZXF1YWwoJzEwMDAwJyk7XG4gICAgICBleHBsYWluLm91dHB1dHNbMF0uYW1vdW50LnNob3VsZC5lcXVhbCgnMTAwMDAnKTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChyZWNlaXZlci5hZGRyZXNzKTtcbiAgICAgIEJ1ZmZlci5mcm9tKGV4cGxhaW4ub3V0cHV0c1swXS5tZW1vKS50b1N0cmluZygpLnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5ub3RlKTtcbiAgICAgIGV4cGxhaW4uZmVlLnNob3VsZC5lcXVhbCgxMDAwKTtcbiAgICAgIGV4cGxhaW4uY2hhbmdlQW1vdW50LnNob3VsZC5lcXVhbCgnMCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGFuIHVuc2lnbmVkIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZGVyID0gQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzO1xuICAgICAgY29uc3QgZGVzdGluYXRpb24gPSBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQyLmFkZHJlc3M7XG4gICAgICBjb25zdCBhbW91bnQgPSAxMDAwMDtcbiAgICAgIGNvbnN0IG1lbW8gPSBBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5ub3RlO1xuICAgICAgY29uc3QgdW5zaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJ1aWxkVW5zaWduZWRUcmFuc2FjdGlvbih7XG4gICAgICAgIHNlbmRlcixcbiAgICAgICAgZGVzdGluYXRpb24sXG4gICAgICAgIGFtb3VudCxcbiAgICAgICAgbWVtbyxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgdW5zaWduZWRIZXggPSBCdWZmZXIuZnJvbSh1bnNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogdW5zaWduZWRIZXgsXG4gICAgICAgIGZlZUluZm86IHsgZmVlOiAnMTAwMCcgfSxcbiAgICAgIH0pO1xuICAgICAgQnVmZmVyLmZyb20oZXhwbGFpbi5vdXRwdXRzWzBdLm1lbW8pLnRvU3RyaW5nKCkuc2hvdWxkLmVxdWFsKEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LnRyYW5zZmVyLm5vdGUpO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoYW1vdW50LnRvU3RyaW5nKCkpO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKGRlc3RpbmF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIHNpZ25lZCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNlbmRlciA9IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDEuYWRkcmVzcztcbiAgICAgIGNvbnN0IGRlc3RpbmF0aW9uID0gQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50Mi5hZGRyZXNzO1xuICAgICAgY29uc3QgYW1vdW50ID0gMTAwMDA7XG4gICAgICBjb25zdCBtZW1vID0gQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgudHJhbnNmZXIubm90ZTtcbiAgICAgIGNvbnN0IHNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgYnVpbGRTaWduZWRUcmFuc2FjdGlvbih7XG4gICAgICAgIHNlbmRlcixcbiAgICAgICAgZGVzdGluYXRpb24sXG4gICAgICAgIGFtb3VudCxcbiAgICAgICAgbWVtbyxcbiAgICAgIH0pO1xuICAgICAgY29uc3Qgc2lnbmVkSGV4ID0gQnVmZmVyLmZyb20oc2lnbmVkVHJhbnNhY3Rpb24udG9Ccm9hZGNhc3RGb3JtYXQoKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgY29uc3QgZXhwbGFpbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4SGV4OiBzaWduZWRIZXgsXG4gICAgICAgIGZlZUluZm86IHsgZmVlOiAnMTAwMCcgfSxcbiAgICAgIH0pO1xuICAgICAgQnVmZmVyLmZyb20oZXhwbGFpbi5vdXRwdXRzWzBdLm1lbW8pLnRvU3RyaW5nKCkuc2hvdWxkLmVxdWFsKEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LnRyYW5zZmVyLm5vdGUpO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoYW1vdW50LnRvU3RyaW5nKCkpO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKGRlc3RpbmF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIG11bHRpU2lnbmVkIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZGVycyA9IFtBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxLmFkZHJlc3MsIEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDMuYWRkcmVzc107XG4gICAgICBjb25zdCBkZXN0aW5hdGlvbiA9IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDIuYWRkcmVzcztcbiAgICAgIGNvbnN0IGFtb3VudCA9IDEwMDAwO1xuICAgICAgY29uc3QgbWVtbyA9IEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LnRyYW5zZmVyLm5vdGU7XG4gICAgICBjb25zdCBzaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJ1aWxkTXVsdGlTaWduZWRUcmFuc2FjdGlvbih7XG4gICAgICAgIHNlbmRlcnMsXG4gICAgICAgIGRlc3RpbmF0aW9uLFxuICAgICAgICBhbW91bnQsXG4gICAgICAgIG1lbW8sXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHNpZ25lZEhleCA9IEJ1ZmZlci5mcm9tKHNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogc2lnbmVkSGV4LFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIEJ1ZmZlci5mcm9tKGV4cGxhaW4ub3V0cHV0c1swXS5tZW1vKS50b1N0cmluZygpLnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5ub3RlKTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hbW91bnQuc2hvdWxkLmVxdWFsKGFtb3VudC50b1N0cmluZygpKTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChkZXN0aW5hdGlvbik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdBc3NldCBUcmFuc2ZlciBCdWlsZGVyOiAnLCAoKSA9PiB7XG4gICAgY29uc3QgYnVpbGRCYXNlQXNzZXRUcmFuc2ZlclRyYW5zYWN0aW9uID0gKHsgZGVzdGluYXRpb24sIGFtb3VudCA9IDEwMDAsIHRva2VuSWQsIHNlbmRlciB9KSA9PiB7XG4gICAgICBjb25zdCBmYWN0b3J5ID0gbmV3IEFsZ29MaWIuVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQoJ2FsZ28nKSk7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldEFzc2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICBjb25zdCBsZWFzZSA9IG5ldyBVaW50OEFycmF5KHJhbmRvbUJ5dGVzKDMyKSk7XG4gICAgICB0eEJ1aWxkZXJcbiAgICAgICAgLnNlbmRlcih7IGFkZHJlc3M6IHNlbmRlciB9KVxuICAgICAgICAuaXNGbGF0RmVlKHRydWUpXG4gICAgICAgIC5mZWUoe1xuICAgICAgICAgIGZlZTogJzEwMDAnLFxuICAgICAgICB9KVxuICAgICAgICAudG9rZW5JZCh0b2tlbklkKVxuICAgICAgICAuZmlyc3RSb3VuZCgxKVxuICAgICAgICAubGFzdFJvdW5kKDEwMClcbiAgICAgICAgLmxlYXNlKGxlYXNlKVxuICAgICAgICAudG8oeyBhZGRyZXNzOiBkZXN0aW5hdGlvbiB9KVxuICAgICAgICAuYW1vdW50KGFtb3VudClcbiAgICAgICAgLnRlc3RuZXQoKTtcbiAgICAgIHJldHVybiB0eEJ1aWxkZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEJ1aWxkIGFuIHVuc2lnbmVkIGFjY291bnQtbGliIHNpbmdsZS1zaWduYXR1cmUgYXNzZXQgdHJhbnNmZXIgdHJhbnNhY3Rpb25cbiAgICAgKiBAcGFyYW0gc2VuZGVyIFRoZSBzZW5kZXJzIGFkZHJlc3NcbiAgICAgKiBAcGFyYW0gZGVzdGluYXRpb24gVGhlIGRlc3RpbmF0aW9uIGFkZHJlc3Mgb2YgdGhlIHRyYW5zYWN0aW9uXG4gICAgICogQHBhcmFtIGFtb3VudCBUaGUgYW1vdW50IHRvIHNlbmQgdG8gdGhlIHJlY2lwaWVudFxuICAgICAqIEBwYXJhbSB0b2tlbklkIFRoZSBhc3NldEluZGV4IGZvciB0aGUgdG9rZW5cbiAgICAgKi9cbiAgICBjb25zdCBidWlsZFVuc2lnbmVkVHJhbnNhY3Rpb24gPSBhc3luYyBmdW5jdGlvbiAoeyBzZW5kZXIsIGRlc3RpbmF0aW9uLCBhbW91bnQgPSAxMDAwMCwgdG9rZW5JZCB9KSB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBidWlsZEJhc2VBc3NldFRyYW5zZmVyVHJhbnNhY3Rpb24oeyBzZW5kZXIsIGRlc3RpbmF0aW9uLCBhbW91bnQsIHRva2VuSWQgfSk7XG4gICAgICByZXR1cm4gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEJ1aWxkIGEgc2lnbmVkIGFjY291bnQtbGliIHNpbmdsZS1zaWduYXR1cmUgc2VuZCB0cmFuc2FjdGlvblxuICAgICAqIEBwYXJhbSBzZW5kZXIgVGhlIHNlbmRlcnMgYWRkcmVzc1xuICAgICAqIEBwYXJhbSBkZXN0aW5hdGlvbiBUaGUgZGVzdGluYXRpb24gYWRkcmVzcyBvZiB0aGUgdHJhbnNhY3Rpb25cbiAgICAgKiBAcGFyYW0gYW1vdW50IFRoZSBhbW91bnQgdG8gc2VuZCB0byB0aGUgcmVjaXBpZW50XG4gICAgICogQHBhcmFtIHRva2VuSWQgVGhlIGFzc2V0SW5kZXggZm9yIHRoZSB0b2tlblxuICAgICAqL1xuICAgIGNvbnN0IGJ1aWxkU2lnbmVkVHJhbnNhY3Rpb24gPSBhc3luYyBmdW5jdGlvbiAoeyBzZW5kZXIsIGRlc3RpbmF0aW9uLCBhbW91bnQgPSAxMDAwMCwgdG9rZW5JZCB9KSB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBidWlsZEJhc2VBc3NldFRyYW5zZmVyVHJhbnNhY3Rpb24oeyBzZW5kZXIsIGRlc3RpbmF0aW9uLCBhbW91bnQsIHRva2VuSWQgfSk7XG4gICAgICB0eEJ1aWxkZXIubnVtYmVyT2ZTaWduZXJzKDEpO1xuICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDEucHJ2S2V5IH0pO1xuICAgICAgcmV0dXJuIGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIH07XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYW4gdW5zaWduZWQgYXNzZXQgdHJhbnNmZXIgdHJhbnNhY3Rpb24gaGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4SGV4OiBBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC5hc3NldFRyYW5zZmVyLnVuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0QW1vdW50LnNob3VsZC5lcXVhbCgnMTAwMCcpO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoJzEwMDAnKTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChyZWNlaXZlci5hZGRyZXNzKTtcbiAgICAgIGV4cGxhaW4uZmVlLnNob3VsZC5lcXVhbCgxMDAwKTtcbiAgICAgIGV4cGxhaW4uY2hhbmdlQW1vdW50LnNob3VsZC5lcXVhbCgnMCcpO1xuICAgICAgZXhwbGFpbi50b2tlbklkLnNob3VsZC5lcXVhbCgxKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIHNpZ25lZCBhc3NldCB0cmFuc2ZlciB0cmFuc2FjdGlvbiBoZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhIZXg6IEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LmFzc2V0VHJhbnNmZXIuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0QW1vdW50LnNob3VsZC5lcXVhbCgnMTAwMDAwMDAwMDAwMDAwMDAwMDAnKTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hbW91bnQuc2hvdWxkLmVxdWFsKCcxMDAwMDAwMDAwMDAwMDAwMDAwMCcpO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHJlY2VpdmVyLmFkZHJlc3MpO1xuICAgICAgZXhwbGFpbi5mZWUuc2hvdWxkLmVxdWFsKDEwMDApO1xuICAgICAgZXhwbGFpbi5jaGFuZ2VBbW91bnQuc2hvdWxkLmVxdWFsKCcwJyk7XG4gICAgICBleHBsYWluLnRva2VuSWQuc2hvdWxkLmVxdWFsKDEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGFuIHVuc2lnbmVkIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZGVyID0gQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzO1xuICAgICAgY29uc3QgZGVzdGluYXRpb24gPSBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQyLmFkZHJlc3M7XG4gICAgICBjb25zdCBhbW91bnQgPSAxMDAwMDtcbiAgICAgIGNvbnN0IHRva2VuSWQgPSAxO1xuICAgICAgY29uc3QgdW5zaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJ1aWxkVW5zaWduZWRUcmFuc2FjdGlvbih7XG4gICAgICAgIHNlbmRlcixcbiAgICAgICAgZGVzdGluYXRpb24sXG4gICAgICAgIGFtb3VudCxcbiAgICAgICAgdG9rZW5JZCxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgdW5zaWduZWRIZXggPSBCdWZmZXIuZnJvbSh1bnNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogdW5zaWduZWRIZXgsXG4gICAgICAgIGZlZUluZm86IHsgZmVlOiAnMTAwMCcgfSxcbiAgICAgIH0pO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoYW1vdW50LnRvU3RyaW5nKCkpO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKGRlc3RpbmF0aW9uKTtcbiAgICAgIGV4cGxhaW4udG9rZW5JZC5zaG91bGQuZXF1YWwoMSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYSBzaWduZWQgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzZW5kZXIgPSBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxLmFkZHJlc3M7XG4gICAgICBjb25zdCBkZXN0aW5hdGlvbiA9IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDIuYWRkcmVzcztcbiAgICAgIGNvbnN0IGFtb3VudCA9IDEwMDAwO1xuICAgICAgY29uc3QgdG9rZW5JZCA9IDE7XG4gICAgICBjb25zdCBzaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJ1aWxkU2lnbmVkVHJhbnNhY3Rpb24oe1xuICAgICAgICBzZW5kZXIsXG4gICAgICAgIGRlc3RpbmF0aW9uLFxuICAgICAgICBhbW91bnQsXG4gICAgICAgIHRva2VuSWQsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHNpZ25lZEhleCA9IEJ1ZmZlci5mcm9tKHNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogc2lnbmVkSGV4LFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hbW91bnQuc2hvdWxkLmVxdWFsKGFtb3VudC50b1N0cmluZygpKTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChkZXN0aW5hdGlvbik7XG4gICAgICBleHBsYWluLnRva2VuSWQuc2hvdWxkLmVxdWFsKDEpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnV2FsbGV0IEluaXQgQnVpbGRlcjogJywgKCkgPT4ge1xuICAgIGNvbnN0IGJ1aWxkQmFzZUtleVJlZ1RyYW5zYWN0aW9uID0gKHsgc2VuZGVyLCBtZW1vID0gJycgfSkgPT4ge1xuICAgICAgY29uc3QgZmFjdG9yeSA9IG5ldyBBbGdvTGliLlRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCdhbGdvJykpO1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRXYWxsZXRJbml0aWFsaXphdGlvbkJ1aWxkZXIoKTtcbiAgICAgIGNvbnN0IGxlYXNlID0gbmV3IFVpbnQ4QXJyYXkocmFuZG9tQnl0ZXMoMzIpKTtcbiAgICAgIGNvbnN0IG5vdGUgPSBuZXcgVWludDhBcnJheShCdWZmZXIuZnJvbShtZW1vLCAndXRmLTgnKSk7XG4gICAgICB0eEJ1aWxkZXJcbiAgICAgICAgLnNlbmRlcih7IGFkZHJlc3M6IHNlbmRlci5hZGRyZXNzIH0pXG4gICAgICAgIC5pc0ZsYXRGZWUodHJ1ZSlcbiAgICAgICAgLmZlZSh7XG4gICAgICAgICAgZmVlOiAnMTAwMCcsXG4gICAgICAgIH0pXG4gICAgICAgIC5maXJzdFJvdW5kKDEpXG4gICAgICAgIC5sYXN0Um91bmQoMTAwKVxuICAgICAgICAubGVhc2UobGVhc2UpXG4gICAgICAgIC5ub3RlKG5vdGUpXG4gICAgICAgIC52b3RlS2V5KHNlbmRlci52b3RlS2V5KVxuICAgICAgICAuc2VsZWN0aW9uS2V5KHNlbmRlci5zZWxlY3Rpb25LZXkpXG4gICAgICAgIC52b3RlRmlyc3QoMSlcbiAgICAgICAgLnZvdGVMYXN0KDEwMClcbiAgICAgICAgLnZvdGVLZXlEaWx1dGlvbig5KVxuICAgICAgICAudGVzdG5ldCgpO1xuICAgICAgcmV0dXJuIHR4QnVpbGRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQnVpbGQgYW4gdW5zaWduZWQgYWNjb3VudC1saWIgc2luZ2xlLXNpZ25hdHVyZSBzZW5kIHRyYW5zYWN0aW9uXG4gICAgICogQHBhcmFtIHNlbmRlciBUaGUgc2VuZGVycyBhZGRyZXNzXG4gICAgICogQHBhcmFtIG1lbW8gT3B0aW9uYWwgbm90ZSB3aXRoIHRoZSB0cmFuc2FjdGlvblxuICAgICAqL1xuICAgIGNvbnN0IGJ1aWxkVW5zaWduZWRUcmFuc2FjdGlvbiA9IGFzeW5jIGZ1bmN0aW9uICh7IHNlbmRlciwgbWVtbyA9ICcnIH0pIHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGJ1aWxkQmFzZUtleVJlZ1RyYW5zYWN0aW9uKHsgc2VuZGVyLCBtZW1vIH0pO1xuICAgICAgcmV0dXJuIGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBCdWlsZCBhIHNpZ25lZCBhY2NvdW50LWxpYiBzaW5nbGUtc2lnbmF0dXJlIHNlbmQgdHJhbnNhY3Rpb25cbiAgICAgKiBAcGFyYW0gc2VuZGVyIFRoZSBzZW5kZXJzIGFkZHJlc3NcbiAgICAgKiBAcGFyYW0gbWVtbyBPcHRpb25hbCBub3RlIHdpdGggdGhlIHRyYW5zYWN0aW9uXG4gICAgICovXG4gICAgY29uc3QgYnVpbGRTaWduZWRUcmFuc2FjdGlvbiA9IGFzeW5jIGZ1bmN0aW9uICh7IHNlbmRlciwgbWVtbyA9ICcnIH0pIHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGJ1aWxkQmFzZUtleVJlZ1RyYW5zYWN0aW9uKHsgc2VuZGVyLCBtZW1vIH0pO1xuICAgICAgdHhCdWlsZGVyLm51bWJlck9mU2lnbmVycygxKTtcbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxLnBydktleSB9KTtcbiAgICAgIHJldHVybiBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQnVpbGQgYSBtdWx0aS1zaWduZWQgYWNjb3VudC1saWIgc2luZ2xlLXNpZ25hdHVyZSBzZW5kIHRyYW5zYWN0aW9uXG4gICAgICogQHBhcmFtIHNlbmRlcnMgVGhlIGxpc3Qgb2Ygc2VuZGVyc1xuICAgICAqIEBwYXJhbSBtZW1vIE9wdGlvbmFsIG5vdGUgd2l0aCB0aGUgdHJhbnNhY3Rpb25cbiAgICAgKi9cbiAgICBjb25zdCBidWlsZE11bHRpU2lnbmVkVHJhbnNhY3Rpb24gPSBhc3luYyBmdW5jdGlvbiAoeyBzZW5kZXJzLCBtZW1vID0gJycgfSkge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gYnVpbGRCYXNlS2V5UmVnVHJhbnNhY3Rpb24oeyBzZW5kZXI6IHNlbmRlcnNbMF0sIG1lbW8gfSk7XG4gICAgICB0eEJ1aWxkZXIubnVtYmVyT2ZTaWduZXJzKDIpO1xuICAgICAgdHhCdWlsZGVyLnNldFNpZ25lcnMoc2VuZGVycy5tYXAoKHsgYWRkcmVzcyB9KSA9PiBhZGRyZXNzKSk7XG4gICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MS5wcnZLZXkgfSk7XG4gICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50My5wcnZLZXkgfSk7XG4gICAgICByZXR1cm4gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgfTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiB1bnNpZ25lZCBLZXlSZWcgdHJhbnNmZXIgdHJhbnNhY3Rpb24gaGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZGVyID0gQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MTtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgua2V5cmVnLnVuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIEJ1ZmZlci5mcm9tKGV4cGxhaW4ubWVtbykudG9TdHJpbmcoKS5zaG91bGQuZXF1YWwoQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgua2V5cmVnLm5vdGUpO1xuICAgICAgZXhwbGFpbi5mZWUuc2hvdWxkLmVxdWFsKDEwMDApO1xuICAgICAgZXhwbGFpbi5jaGFuZ2VBbW91bnQuc2hvdWxkLmVxdWFsKCcwJyk7XG4gICAgICBleHBsYWluLnZvdGVLZXkuc2hvdWxkLmVxdWFsKHNlbmRlci52b3RlS2V5KTtcbiAgICAgIGV4cGxhaW4uc2VsZWN0aW9uS2V5LnNob3VsZC5lcXVhbChzZW5kZXIuc2VsZWN0aW9uS2V5KTtcbiAgICAgIGV4cGxhaW4udm90ZUZpcnN0LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIGV4cGxhaW4udm90ZUxhc3Quc2hvdWxkLmVxdWFsKDEwMCk7XG4gICAgICBleHBsYWluLnZvdGVLZXlEaWx1dGlvbi5zaG91bGQuZXF1YWwoOSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYSBzaWduZWQgdHJhbnNmZXIgdHJhbnNhY3Rpb24gaGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZGVyID0gQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MTtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgua2V5cmVnLnNpZ25lZCxcbiAgICAgICAgZmVlSW5mbzogeyBmZWU6ICcxMDAwJyB9LFxuICAgICAgfSk7XG4gICAgICBCdWZmZXIuZnJvbShleHBsYWluLm1lbW8pLnRvU3RyaW5nKCkuc2hvdWxkLmVxdWFsKEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LmtleXJlZy5ub3RlKTtcbiAgICAgIGV4cGxhaW4uZmVlLnNob3VsZC5lcXVhbCgxMDAwKTtcbiAgICAgIGV4cGxhaW4uY2hhbmdlQW1vdW50LnNob3VsZC5lcXVhbCgnMCcpO1xuICAgICAgZXhwbGFpbi52b3RlS2V5LnNob3VsZC5lcXVhbChzZW5kZXIudm90ZUtleSk7XG4gICAgICBleHBsYWluLnNlbGVjdGlvbktleS5zaG91bGQuZXF1YWwoc2VuZGVyLnNlbGVjdGlvbktleSk7XG4gICAgICBleHBsYWluLnZvdGVGaXJzdC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICBleHBsYWluLnZvdGVMYXN0LnNob3VsZC5lcXVhbCgxMDApO1xuICAgICAgZXhwbGFpbi52b3RlS2V5RGlsdXRpb24uc2hvdWxkLmVxdWFsKDkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGEgbXVsdGlTaWcgdHJhbnNmZXIgdHJhbnNhY3Rpb24gaGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZGVyID0gQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MTtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgua2V5cmVnLm11bHRpU2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIEJ1ZmZlci5mcm9tKGV4cGxhaW4ubWVtbykudG9TdHJpbmcoKS5zaG91bGQuZXF1YWwoQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgua2V5cmVnLm5vdGUpO1xuICAgICAgZXhwbGFpbi5mZWUuc2hvdWxkLmVxdWFsKDEwMDApO1xuICAgICAgZXhwbGFpbi5jaGFuZ2VBbW91bnQuc2hvdWxkLmVxdWFsKCcwJyk7XG4gICAgICBleHBsYWluLnZvdGVLZXkuc2hvdWxkLmVxdWFsKHNlbmRlci52b3RlS2V5KTtcbiAgICAgIGV4cGxhaW4uc2VsZWN0aW9uS2V5LnNob3VsZC5lcXVhbChzZW5kZXIuc2VsZWN0aW9uS2V5KTtcbiAgICAgIGV4cGxhaW4udm90ZUZpcnN0LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIGV4cGxhaW4udm90ZUxhc3Quc2hvdWxkLmVxdWFsKDEwMCk7XG4gICAgICBleHBsYWluLnZvdGVLZXlEaWx1dGlvbi5zaG91bGQuZXF1YWwoOSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYSBoYWxmIHNpZ25lZCB0cmFuc2ZlciB0cmFuc2FjdGlvbiBoZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzZW5kZXIgPSBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxO1xuICAgICAgY29uc3QgZXhwbGFpbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIGhhbGZTaWduZWQ6IHtcbiAgICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgua2V5cmVnLmhhbGZTaWduZWQsXG4gICAgICAgIH0sXG4gICAgICAgIGZlZUluZm86IHsgZmVlOiAnMTAwMCcgfSxcbiAgICAgIH0pO1xuICAgICAgQnVmZmVyLmZyb20oZXhwbGFpbi5tZW1vKS50b1N0cmluZygpLnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC5rZXlyZWcubm90ZSk7XG4gICAgICBleHBsYWluLmZlZS5zaG91bGQuZXF1YWwoMTAwMCk7XG4gICAgICBleHBsYWluLmNoYW5nZUFtb3VudC5zaG91bGQuZXF1YWwoJzAnKTtcbiAgICAgIGV4cGxhaW4udm90ZUtleS5zaG91bGQuZXF1YWwoc2VuZGVyLnZvdGVLZXkpO1xuICAgICAgZXhwbGFpbi5zZWxlY3Rpb25LZXkuc2hvdWxkLmVxdWFsKHNlbmRlci5zZWxlY3Rpb25LZXkpO1xuICAgICAgZXhwbGFpbi52b3RlRmlyc3Quc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgZXhwbGFpbi52b3RlTGFzdC5zaG91bGQuZXF1YWwoMTAwKTtcbiAgICAgIGV4cGxhaW4udm90ZUtleURpbHV0aW9uLnNob3VsZC5lcXVhbCg5KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiB1bnNpZ25lZCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNlbmRlciA9IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDE7XG4gICAgICBjb25zdCBtZW1vID0gQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgudHJhbnNmZXIubm90ZTtcbiAgICAgIGNvbnN0IHVuc2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBidWlsZFVuc2lnbmVkVHJhbnNhY3Rpb24oe1xuICAgICAgICBzZW5kZXIsXG4gICAgICAgIG1lbW8sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdW5zaWduZWRIZXggPSBCdWZmZXIuZnJvbSh1bnNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogdW5zaWduZWRIZXgsXG4gICAgICAgIGZlZUluZm86IHsgZmVlOiAnMTAwMCcgfSxcbiAgICAgIH0pO1xuICAgICAgQnVmZmVyLmZyb20oZXhwbGFpbi5tZW1vKS50b1N0cmluZygpLnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5ub3RlKTtcbiAgICAgIGV4cGxhaW4udm90ZUtleS5zaG91bGQuZXF1YWwoc2VuZGVyLnZvdGVLZXkpO1xuICAgICAgZXhwbGFpbi5zZWxlY3Rpb25LZXkuc2hvdWxkLmVxdWFsKHNlbmRlci5zZWxlY3Rpb25LZXkpO1xuICAgICAgZXhwbGFpbi52b3RlRmlyc3Quc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgZXhwbGFpbi52b3RlTGFzdC5zaG91bGQuZXF1YWwoMTAwKTtcbiAgICAgIGV4cGxhaW4udm90ZUtleURpbHV0aW9uLnNob3VsZC5lcXVhbCg5KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIHNpZ25lZCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNlbmRlciA9IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDE7XG4gICAgICBjb25zdCBtZW1vID0gQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgudHJhbnNmZXIubm90ZTtcbiAgICAgIGNvbnN0IHNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgYnVpbGRTaWduZWRUcmFuc2FjdGlvbih7XG4gICAgICAgIHNlbmRlcixcbiAgICAgICAgbWVtbyxcbiAgICAgIH0pO1xuICAgICAgY29uc3Qgc2lnbmVkSGV4ID0gQnVmZmVyLmZyb20oc2lnbmVkVHJhbnNhY3Rpb24udG9Ccm9hZGNhc3RGb3JtYXQoKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgY29uc3QgZXhwbGFpbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4SGV4OiBzaWduZWRIZXgsXG4gICAgICAgIGZlZUluZm86IHsgZmVlOiAnMTAwMCcgfSxcbiAgICAgIH0pO1xuICAgICAgQnVmZmVyLmZyb20oZXhwbGFpbi5tZW1vKS50b1N0cmluZygpLnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5ub3RlKTtcbiAgICAgIGV4cGxhaW4udm90ZUtleS5zaG91bGQuZXF1YWwoc2VuZGVyLnZvdGVLZXkpO1xuICAgICAgZXhwbGFpbi5zZWxlY3Rpb25LZXkuc2hvdWxkLmVxdWFsKHNlbmRlci5zZWxlY3Rpb25LZXkpO1xuICAgICAgZXhwbGFpbi52b3RlRmlyc3Quc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgZXhwbGFpbi52b3RlTGFzdC5zaG91bGQuZXF1YWwoMTAwKTtcbiAgICAgIGV4cGxhaW4udm90ZUtleURpbHV0aW9uLnNob3VsZC5lcXVhbCg5KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIG11bHRpU2lnbmVkIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZGVycyA9IFtBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxLCBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQzXTtcbiAgICAgIGNvbnN0IG1lbW8gPSBBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5ub3RlO1xuICAgICAgY29uc3Qgc2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBidWlsZE11bHRpU2lnbmVkVHJhbnNhY3Rpb24oe1xuICAgICAgICBzZW5kZXJzLFxuICAgICAgICBtZW1vLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBzaWduZWRIZXggPSBCdWZmZXIuZnJvbShzaWduZWRUcmFuc2FjdGlvbi50b0Jyb2FkY2FzdEZvcm1hdCgpKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICBjb25zdCBleHBsYWluID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhIZXg6IHNpZ25lZEhleCxcbiAgICAgICAgZmVlSW5mbzogeyBmZWU6ICcxMDAwJyB9LFxuICAgICAgfSk7XG4gICAgICBCdWZmZXIuZnJvbShleHBsYWluLm1lbW8pLnRvU3RyaW5nKCkuc2hvdWxkLmVxdWFsKEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LnRyYW5zZmVyLm5vdGUpO1xuICAgICAgZXhwbGFpbi52b3RlS2V5LnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxLnZvdGVLZXkpO1xuICAgICAgZXhwbGFpbi5zZWxlY3Rpb25LZXkuc2hvdWxkLmVxdWFsKEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDEuc2VsZWN0aW9uS2V5KTtcbiAgICAgIGV4cGxhaW4udm90ZUZpcnN0LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIGV4cGxhaW4udm90ZUxhc3Quc2hvdWxkLmVxdWFsKDEwMCk7XG4gICAgICBleHBsYWluLnZvdGVLZXlEaWx1dGlvbi5zaG91bGQuZXF1YWwoOSk7XG4gICAgfSk7XG4gIH0pO1xuICBkZXNjcmliZSgnU2lnbiB0cmFuc2FjdGlvbicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHNpZ24gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzaWduZWQgPSBhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgdHhIZXg6IEFsZ29SZXNvdXJjZXMucmF3VHgudHJhbnNmZXIudW5zaWduZWQsXG4gICAgICAgICAga2V5czogW0FsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDEucHViS2V5LnRvU3RyaW5nKCdoZXgnKV0sXG4gICAgICAgICAgYWRkcmVzc1ZlcnNpb246IDEsXG4gICAgICAgIH0sXG4gICAgICAgIHBydjogQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MS5wcnZLZXksXG4gICAgICB9KTtcbiAgICAgIHNpZ25lZC50eEhleC5zaG91bGQuZXF1YWwoQWxnb1Jlc291cmNlcy5yYXdUeC50cmFuc2Zlci5zaWduZWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzaWduIHRyYW5zYWN0aW9uIHdpdGggcm9vdCBrZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBrZXlwYWlyID0gYmFzZWNvaW4uZ2VuZXJhdGVSb290S2V5UGFpcihBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxLnNlY3JldEtleSk7XG5cbiAgICAgIGNvbnN0IHNpZ25lZCA9IGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5yYXdUeC50cmFuc2Zlci51bnNpZ25lZCxcbiAgICAgICAgICBrZXlzOiBba2V5cGFpci5wdWJdLFxuICAgICAgICAgIGFkZHJlc3NWZXJzaW9uOiAxLFxuICAgICAgICB9LFxuICAgICAgICBwcnY6IGtleXBhaXIucHJ2LFxuICAgICAgfSk7XG4gICAgICBzaWduZWQudHhIZXguc2hvdWxkLmVxdWFsKEFsZ29SZXNvdXJjZXMucmF3VHgudHJhbnNmZXIuc2lnbmVkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2lnbiBoYWxmIHNpZ25lZCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNpZ25lZCA9IGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICBoYWxmU2lnbmVkOiB7XG4gICAgICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5yYXdUeC50cmFuc2Zlci5oYWxmU2lnbmVkLFxuICAgICAgICAgIH0sXG4gICAgICAgICAga2V5czogW1xuICAgICAgICAgICAgQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MS5wdWJLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgICAgQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50My5wdWJLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgYWRkcmVzc1ZlcnNpb246IDEsXG4gICAgICAgIH0sXG4gICAgICAgIHBydjogQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50My5wcnZLZXksXG4gICAgICB9KTtcbiAgICAgIHNpZ25lZC50eEhleC5zaG91bGQuZXF1YWwoQWxnb1Jlc291cmNlcy5yYXdUeC50cmFuc2Zlci5tdWx0aXNpZyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNpZ24gaGFsZiBzaWduZWQgdHJhbnNhY3Rpb24gd2l0aCByb290IGtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNpZ25lZCA9IGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICBoYWxmU2lnbmVkOiB7XG4gICAgICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5yb290S2V5RGF0YS51bnNpZ25lZFR4LFxuICAgICAgICAgIH0sXG4gICAgICAgICAga2V5czogW1xuICAgICAgICAgICAgQWxnb1Jlc291cmNlcy5yb290S2V5RGF0YS51c2VyS2V5UGFpci5wdWIsXG4gICAgICAgICAgICBBbGdvUmVzb3VyY2VzLnJvb3RLZXlEYXRhLmJhY2t1cFB1YixcbiAgICAgICAgICAgIEFsZ29SZXNvdXJjZXMucm9vdEtleURhdGEuYml0Z29QdWIsXG4gICAgICAgICAgXSxcbiAgICAgICAgICBhZGRyZXNzVmVyc2lvbjogMSxcbiAgICAgICAgfSxcbiAgICAgICAgcHJ2OiBBbGdvUmVzb3VyY2VzLnJvb3RLZXlEYXRhLnVzZXJLZXlQYWlyLnBydixcbiAgICAgIH0pO1xuXG4gICAgICBzaWduZWQudHhIZXguc2hvdWxkLmRlZXBFcXVhbChBbGdvUmVzb3VyY2VzLnJvb3RLZXlEYXRhLmhhbGZTaWduZWRUeCk7XG4gICAgICBjb25zdCBmYWN0b3J5ID0gbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCdhbGdvJykpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCBmYWN0b3J5LmZyb20oc2lnbmVkLnR4SGV4KS5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgICB0eEpzb24uZnJvbS5zaG91bGQuZXF1YWwoQWxnb1Jlc291cmNlcy5yb290S2V5RGF0YS5zZW5kZXJBZGRyZXNzKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IHNpZ24gcGFyYW1zIGlmIHRoZSBrZXkgYXJyYXkgY29udGFpbnMgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qga2V5cyA9IFtcbiAgICAgICAgQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzLFxuICAgICAgICBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQyLmFkZHJlc3MsXG4gICAgICAgIEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDMuYWRkcmVzcyxcbiAgICAgIF07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWVkUGFyYW1zID0gYmFzZWNvaW4udmVyaWZ5U2lnblRyYW5zYWN0aW9uUGFyYW1zKHtcbiAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgIHR4SGV4OiBBbGdvUmVzb3VyY2VzLnJhd1R4LnRyYW5zZmVyLnVuc2lnbmVkLFxuICAgICAgICAgIGtleXMsXG4gICAgICAgICAgYWRkcmVzc1ZlcnNpb246IDEsXG4gICAgICAgIH0sXG4gICAgICAgIHBydjogQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50Mi5zZWNyZXRLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgfSk7XG4gICAgICB2ZXJpZmllZFBhcmFtcy5zaG91bGQuaGF2ZS5wcm9wZXJ0aWVzKFtcbiAgICAgICAgJ3R4SGV4JyxcbiAgICAgICAgJ2FkZHJlc3NWZXJzaW9uJyxcbiAgICAgICAgJ3NpZ25lcnMnLFxuICAgICAgICAncHJ2JyxcbiAgICAgICAgJ2lzSGFsZlNpZ25lZCcsXG4gICAgICAgICdudW1iZXJTaWduZXJzJyxcbiAgICAgIF0pO1xuICAgICAgY29uc3QgeyB0eEhleCwgc2lnbmVycywgaXNIYWxmU2lnbmVkIH0gPSB2ZXJpZmllZFBhcmFtcztcbiAgICAgIHR4SGV4LnNob3VsZC5iZS5lcXVhbChBbGdvUmVzb3VyY2VzLnJhd1R4LnRyYW5zZmVyLnVuc2lnbmVkKTtcbiAgICAgIHNpZ25lcnMuc2hvdWxkLmJlLmRlZXBFcXVhbChrZXlzKTtcbiAgICAgIGlzSGFsZlNpZ25lZC5zaG91bGQuYmUuZXF1YWwoZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzaWduIGhhbGYgc2lnbmVkIHRyYW5zYWN0aW9uIGlmIHRoZSBrZXkgYXJyYXkgY29udGFpbnMgYWRkcmVzc2VzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnbmVkID0gYXdhaXQgYmFzZWNvaW4uc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgIGhhbGZTaWduZWQ6IHtcbiAgICAgICAgICAgIHR4SGV4OiBBbGdvUmVzb3VyY2VzLnJhd1R4LnRyYW5zZmVyLmhhbGZTaWduZWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBrZXlzOiBbQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzLCBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQzLmFkZHJlc3NdLFxuICAgICAgICAgIGFkZHJlc3NWZXJzaW9uOiAxLFxuICAgICAgICB9LFxuICAgICAgICBwcnY6IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDMucHJ2S2V5LFxuICAgICAgfSk7XG4gICAgICBzaWduZWQudHhIZXguc2hvdWxkLmVxdWFsKEFsZ29SZXNvdXJjZXMucmF3VHgudHJhbnNmZXIubXVsdGlzaWcpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnU2lnbiBtZXNzYWdlJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgc2lnbiBtZXNzYWdlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnbmVkID0gYXdhaXQgYmFzZWNvaW4uc2lnbk1lc3NhZ2UoXG4gICAgICAgIHsgcHJ2OiBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxLnBydktleSB9LFxuICAgICAgICBBbGdvUmVzb3VyY2VzLm1lc3NhZ2UudW5zaWduZWRcbiAgICAgICk7XG4gICAgICBzaWduZWQudG9TdHJpbmcoJ2hleCcpLnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLm1lc3NhZ2Uuc2lnbmVkKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0dlbmVyYXRlIHdhbGxldCBrZXkgcGFpcjogJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUga2V5IHBhaXInLCAoKSA9PiB7XG4gICAgICBjb25zdCBrcCA9IGJhc2Vjb2luLmdlbmVyYXRlS2V5UGFpcigpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZFB1YihrcC5wdWIpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQcnYoa3AucHJ2KS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGtleSBwYWlyIGZyb20gc2VlZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHNlZWQgPSBCdWZmZXIuZnJvbSgnOWQ2MWIxOWRlZmZkNWE2MGJhODQ0YWY0OTJlYzJjYzQ0NDQ5YzU2OTdiMzI2OTE5NzAzYmFjMDMxY2FlN2Y2MCcsICdoZXgnKTtcbiAgICAgIGNvbnN0IGtwID0gYmFzZWNvaW4uZ2VuZXJhdGVLZXlQYWlyKHNlZWQpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZFB1YihrcC5wdWIpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQcnYoa3AucHJ2KS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdHZW5lcmF0ZSB3YWxsZXQgUm9vdCBrZXkgcGFpcjogJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUga2V5IHBhaXInLCAoKSA9PiB7XG4gICAgICBjb25zdCBrcCA9IGJhc2Vjb2luLmdlbmVyYXRlUm9vdEtleVBhaXIoKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQdWIoa3AucHViKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkUHJ2KGtwLnBydikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBrZXkgcGFpciBmcm9tIHNlZWQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBzZWVkID0gQnVmZmVyLmZyb20oJzlkNjFiMTlkZWZmZDVhNjBiYTg0NGFmNDkyZWMyY2M0NDQ0OWM1Njk3YjMyNjkxOTcwM2JhYzAzMWNhZTdmNjAnLCAnaGV4Jyk7XG4gICAgICBjb25zdCBrcCA9IGJhc2Vjb2luLmdlbmVyYXRlUm9vdEtleVBhaXIoc2VlZCk7XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkUHViKGtwLnB1Yikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAga3AucHViLnNob3VsZC5lcXVhbCgnZDc1YTk4MDE4MmIxMGFiN2Q1NGJmZWQzYzk2NDA3M2EwZWUxNzJmM2RhYTYyMzI1YWYwMjFhNjhmNzA3NTExYScpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZFBydihrcC5wcnYpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIGtwLnBydi5zaG91bGQuZXF1YWwoXG4gICAgICAgICc5ZDYxYjE5ZGVmZmQ1YTYwYmE4NDRhZjQ5MmVjMmNjNDQ0NDljNTY5N2IzMjY5MTk3MDNiYWMwMzFjYWU3ZjYwZDc1YTk4MDE4MmIxMGFiN2Q1NGJmZWQzYzk2NDA3M2EwZWUxNzJmM2RhYTYyMzI1YWYwMjFhNjhmNzA3NTExYSdcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFbmFibGUsIGRpc2FibGUgYW5kIHRyYW5zZmVyIFRva2VuICcsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYW4gZW5hYmxlIHRva2VuIHRyYW5zYWN0aW9uIGhleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHguZW5hYmxlVG9rZW4sXG4gICAgICAgIGZlZUluZm86IHsgZmVlOiAnMTAwMCcgfSxcbiAgICAgIH0pO1xuICAgICAgZXhwbGFpbi5vcGVyYXRpb25zLmxlbmd0aC5zaG91bGQuZXF1YWxzKDEpO1xuICAgICAgZXhwbGFpbi5vcGVyYXRpb25zWzBdLnR5cGUuc2hvdWxkLmVxdWFscygnZW5hYmxlVG9rZW4nKTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9uc1swXS5jb2luLnNob3VsZC5lcXVhbHMoJ3RhbGdvOlVTT04tMTYwMjY3MjgnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiBkaXNhYmxlIHRva2VuIHRyYW5zYWN0aW9uIGhleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHguZGlzYWJsZVRva2VuLFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9ucy5sZW5ndGguc2hvdWxkLmVxdWFscygxKTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9uc1swXS50eXBlLnNob3VsZC5lcXVhbHMoJ2Rpc2FibGVUb2tlbicpO1xuICAgICAgZXhwbGFpbi5vcGVyYXRpb25zWzBdLmNvaW4uc2hvdWxkLmVxdWFscygndGFsZ286VVNPTi0xNjAyNjcyOCcpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiB0cmFuc2ZlciB0b2tlbiB0cmFuc2FjdGlvbiBoZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhIZXg6IEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LmFzc2V0VHJhbnNmZXIuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9ucy5sZW5ndGguc2hvdWxkLmVxdWFscygxKTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9uc1swXS50eXBlLnNob3VsZC5lcXVhbHMoJ3RyYW5zZmVyVG9rZW4nKTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9uc1swXS5jb2luLnNob3VsZC5lcXVhbHMoJ0FsZ29Ub2tlbiB1bmtub3duJyk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGFuIGVuYWJsZSBVU0RUIHRva2VuIHRyYW5zYWN0aW9uIGhleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHguZW5hYmxlVG9rZW5VU0RULFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9ucy5sZW5ndGguc2hvdWxkLmVxdWFscygxKTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9uc1swXS50eXBlLnNob3VsZC5lcXVhbHMoJ2VuYWJsZVRva2VuJyk7XG4gICAgICBleHBsYWluLm9wZXJhdGlvbnNbMF0uY29pbi5zaG91bGQuZXF1YWxzKCd0YWxnbzpVU0R0LTE4MDQ0NycpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiBlbmFibGUgVVNEQyB0b2tlbiB0cmFuc2FjdGlvbiBoZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhIZXg6IEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LmVuYWJsZVRva2VuVVNEQyxcbiAgICAgICAgZmVlSW5mbzogeyBmZWU6ICcxMDAwJyB9LFxuICAgICAgfSk7XG4gICAgICBleHBsYWluLm9wZXJhdGlvbnMubGVuZ3RoLnNob3VsZC5lcXVhbHMoMSk7XG4gICAgICBleHBsYWluLm9wZXJhdGlvbnNbMF0udHlwZS5zaG91bGQuZXF1YWxzKCdlbmFibGVUb2tlbicpO1xuICAgICAgZXhwbGFpbi5vcGVyYXRpb25zWzBdLmNvaW4uc2hvdWxkLmVxdWFscygndGFsZ286VVNEQy0xMDQ1ODk0MScpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiBkaXNhYmxlIFVTREMgdG9rZW4gdHJhbnNhY3Rpb24gaGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4SGV4OiBBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC5kaXNhYmxlVG9rZW5VU0RDLFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9ucy5sZW5ndGguc2hvdWxkLmVxdWFscygxKTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9uc1swXS50eXBlLnNob3VsZC5lcXVhbHMoJ2Rpc2FibGVUb2tlbicpO1xuICAgICAgZXhwbGFpbi5vcGVyYXRpb25zWzBdLmNvaW4uc2hvdWxkLmVxdWFscygndGFsZ286VVNEQy0xMDQ1ODk0MScpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiB0cmFuc2ZlciBVU0RDIHRva2VuIHRyYW5zYWN0aW9uIGhleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHguVVNEQ0Fzc2V0VHJhbnNmZXIuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9ucy5sZW5ndGguc2hvdWxkLmVxdWFscygxKTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9uc1swXS50eXBlLnNob3VsZC5lcXVhbHMoJ3RyYW5zZmVyVG9rZW4nKTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9uc1swXS5jb2luLnNob3VsZC5lcXVhbHMoJ3RhbGdvOlVTREMtMTA0NTg5NDEnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2Rlcml2ZUtleVdpdGhTZWVkJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgZGVyaXZlIGtleSB3aXRoIHNlZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAoKCkgPT4ge1xuICAgICAgICBiYXNlY29pbi5kZXJpdmVLZXlXaXRoU2VlZCgndGVzdCcpO1xuICAgICAgfSkuc2hvdWxkLnRocm93KCdtZXRob2QgZGVyaXZlS2V5V2l0aFNlZWQgbm90IHN1cHBvcnRlZCBmb3IgZWRkc2EgY3VydmUnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JlY292ZXJ5JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGZlZSA9IDEwMDA7XG4gICAgY29uc3QgdXNlcktleSA9XG4gICAgICAne1wiaXZcIjpcIlpKZzBhMCt6VCs2ODRNVWw0NExtNEE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjEyOCxcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJhYlF5ME9MMjQ2OD1cIixcImN0XCI6XCJMTmxTbFRKRUQ4alN3SENtVWZsenFGdFJQTCtQb2p6T2dmZDVtRDJubUxWZEFveUtDV0h2QWllS3Q3bEo3emc0MTdDVWk2UWo3Ny9zM2xicW14VnNmRXNrXCJ9JztcbiAgICBjb25zdCB1c2VyUHViID0gJ1M0RDdERFJBSFdaSUIyUkNaSUNTUk9ERkNOUVhHQU5IR0E3VkNXQks1STM3U1FUNktWSFhRTktNVEUnO1xuICAgIGNvbnN0IGJhY2t1cEtleSA9XG4gICAgICAne1wiaXZcIjpcIm1aWThYVHZIeFg4QlBjMXJkR1FRd3c9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjEyOCxcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJhYlF5ME9MMjQ2OD1cIixcImN0XCI6XCJVUVhvMEVhUFhiNlRJWkRZWWhLWVM5ZC9mUk1OVDZwdHBsOUJnSnczQVZvb1NiTzRucHBXblRSWWxRTzdocE9ONFhZODVoWUR1LzdoeTkxSVgxejFiRERxXCJ9JztcbiAgICBjb25zdCBiYWNrdXBQdWIgPSAnNkZWR1pVWk9IWlNYVFRCUkxXWkRYR1lTV1ZWWU5ONFpFU0lFTVpFTUlCSkNVQkhDNUM3N09JRTVSUSc7XG4gICAgY29uc3Qgcm9vdEFkZHJlc3MgPSAnRldMTkRMN1VYQ1NPUE9RWEE1VlUyRE1BTlpBWUNDTUJZMzc3SEtUR0dNWjRHRVBFSkJGQVJET0dCQSc7XG4gICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdUZXN0aW5nQDQzMjEwISc7XG4gICAgY29uc3QgcmVjb3ZlcnlEZXN0aW5hdGlvbiA9ICdHQjNZRVRENVRTVEJBSVlHWUhWV1UzTzNJN1hHT0I0NEhPWkE1TU9FRjVNMjNDTExaS1JRTEVWQU9BJztcbiAgICBjb25zdCBiaXRnb1B1YiA9ICdGSlNXTExQUkJYRUdNV1pZNUJYQTY2NzNZS0lLN0pPVVJWQ1FFT1dYQzVUUVBDWENPSzNWSE9PMlZRJztcbiAgICBjb25zdCBuYXRpdmVCYWxhbmNlID0gMTAwMDAwMDA7IC8vIDEwIEFMR09cbiAgICBjb25zdCBNSU5fQUNDT1VOVF9CQUxBTkNFID0gMTAwMDAwOyAvLyAxIEFHTE9cblxuICAgIGNvbnN0IG5vZGVQYXJhbXMgPSB7XG4gICAgICB0b2tlbjogJzI4MTBjMmQxNjhlODQxN2M1ZjExMWQzOGQ2ODMyN2I4Y2ZlMmQwZGRjMDI5ODY0OTBjMjJmOGRkZjQxMjhiY2QnLFxuICAgICAgYmFzZVNlcnZlcjogJ2h0dHA6Ly9sb2NhbGhvc3QvJyxcbiAgICAgIHBvcnQ6IDg0NDMsXG4gICAgfTtcblxuICAgIGRlc2NyaWJlKCdOb24tQml0R28nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzYW5kQm94ID0gU2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgICAgY29uc3QgZXhwZWN0ZWRBbW91bnQgPSBuZXcgQmlnTnVtYmVyKG5hdGl2ZUJhbGFuY2UpLm1pbnVzKGZlZSkubWludXMoTUlOX0FDQ09VTlRfQkFMQU5DRSkudG9TdHJpbmcoKTtcblxuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZEJveC52ZXJpZnlBbmRSZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCBhbmQgc2lnbiB0aGUgcmVjb3ZlcnkgdHgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGdldEJhbGFuY2VTdHViID0gc2FuZEJveC5zdHViKEFsZ28ucHJvdG90eXBlLCAnZ2V0QWNjb3VudEJhbGFuY2UnKS5yZXNvbHZlcyhuYXRpdmVCYWxhbmNlKTtcblxuICAgICAgICBjb25zdCByZWNvdmVyeSA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5LFxuICAgICAgICAgIHJvb3RBZGRyZXNzLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgZmVlLFxuICAgICAgICAgIGJpdGdvS2V5OiBiaXRnb1B1YixcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiByZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICAgIGZpcnN0Um91bmQ6IDUwMDI1OTYsXG4gICAgICAgICAgbm9kZVBhcmFtcyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lkJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuICAgICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdjb2luJywgJ3RhbGdvJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdmaXJzdFJvdW5kJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdsYXN0Um91bmQnKTtcbiAgICAgICAgZ2V0QmFsYW5jZVN0dWIuY2FsbENvdW50LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgY29uc3QgZmFjdG9yeSA9IG5ldyBBbGdvTGliLlRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCdhbGdvJykpO1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20ocmVjb3ZlcnkudHgpO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgICBjb25zdCB0eEJyb2FkY2FzdEZvcm1hdCA9IEJ1ZmZlci5mcm9tKHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICAgICAgdHhCcm9hZGNhc3RGb3JtYXQuc2hvdWxkLmRlZXBFcXVhbChyZWNvdmVyeS50eCk7XG4gICAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgICB0eEpzb24uYW1vdW50LnNob3VsZC5lcXVhbChleHBlY3RlZEFtb3VudCk7XG4gICAgICAgIHR4SnNvbi50by5zaG91bGQuZXF1YWwocmVjb3ZlcnlEZXN0aW5hdGlvbik7XG4gICAgICAgIHR4SnNvbi5mcm9tLnNob3VsZC5lcXVhbChyb290QWRkcmVzcyk7XG4gICAgICAgIHR4SnNvbi5mZWUuc2hvdWxkLmVxdWFsKGZlZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBmb3IgaW52YWxpZCByb290QWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgaW52YWxpZFJvb3RBZGRyZXNzID0gJ3JhbmRvbXN0cmluZyc7XG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICAgICAgICB1c2VyS2V5LFxuICAgICAgICAgICAgICBiYWNrdXBLZXksXG4gICAgICAgICAgICAgIHJvb3RBZGRyZXNzOiBpbnZhbGlkUm9vdEFkZHJlc3MsXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgICAgIGZlZSxcbiAgICAgICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogcmVjb3ZlcnlEZXN0aW5hdGlvbixcbiAgICAgICAgICAgICAgZmlyc3RSb3VuZDogNTAwMjU5NixcbiAgICAgICAgICAgICAgbm9kZVBhcmFtcyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgeyBtZXNzYWdlOiAnaW52YWxpZCByb290QWRkcmVzcywgZ290OiAnICsgaW52YWxpZFJvb3RBZGRyZXNzIH1cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGZvciBpbnZhbGlkIHJlY292ZXJ5RGVzdGluYXRpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGludmFsaWRSZWNvdmVyeURlc3RpbmF0aW9uID0gJ3JhbmRvbXN0cmluZyc7XG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICAgICAgICB1c2VyS2V5LFxuICAgICAgICAgICAgICBiYWNrdXBLZXksXG4gICAgICAgICAgICAgIHJvb3RBZGRyZXNzLFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgICAgICBmZWUsXG4gICAgICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGludmFsaWRSZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICAgICAgICBmaXJzdFJvdW5kOiA1MDAyNTk2LFxuICAgICAgICAgICAgICBub2RlUGFyYW1zLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IG1lc3NhZ2U6ICdpbnZhbGlkIHJlY292ZXJ5RGVzdGluYXRpb24sIGdvdDogJyArIGludmFsaWRSZWNvdmVyeURlc3RpbmF0aW9uIH1cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGlmIHRoZXJlIGlzIG5vIGVub3VnaCBiYWxhbmNlIHRvIHJlY292ZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGdldEJhbGFuY2VTdHViID0gc2FuZEJveC5zdHViKEFsZ28ucHJvdG90eXBlLCAnZ2V0QWNjb3VudEJhbGFuY2UnKS5yZXNvbHZlcygxMDA1MDApO1xuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgICAgICAgdXNlcktleSxcbiAgICAgICAgICAgICAgYmFja3VwS2V5LFxuICAgICAgICAgICAgICByb290QWRkcmVzcyxcbiAgICAgICAgICAgICAgZmVlLFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgICAgICBiaXRnb0tleTogYml0Z29QdWIsXG4gICAgICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgICAgICAgIGZpcnN0Um91bmQ6IDUwMDM1OTYsXG4gICAgICAgICAgICAgIG5vZGVQYXJhbXMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgbWVzc2FnZTogJ0luc3VmZmljaWVudCBiYWxhbmNlIHRvIHJlY292ZXIsIGdvdCBiYWxhbmNlOiAxMDA1MDAgZmVlOiAxMDAwIG1pbiBhY2NvdW50IGJhbGFuY2U6IDEwMDAwMCcgfVxuICAgICAgICApO1xuXG4gICAgICAgIGdldEJhbGFuY2VTdHViLmNhbGxDb3VudC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiB0aGUgd2FsbGV0UGFzc3BocmFzZSBpcyB1bmRlZmluZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICAgICAgICB1c2VyS2V5LFxuICAgICAgICAgICAgICBiYWNrdXBLZXksXG4gICAgICAgICAgICAgIHJvb3RBZGRyZXNzLFxuICAgICAgICAgICAgICBmZWUsXG4gICAgICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgICAgICAgIGZpcnN0Um91bmQ6IDUwMDM1OTYsXG4gICAgICAgICAgICAgIG5vZGVQYXJhbXMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgbWVzc2FnZTogJ3dhbGxldFBhc3NwaHJhc2UgaXMgcmVxdWlyZWQgZm9yIG5vbi1iaXRnbyByZWNvdmVyeScgfVxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgdGhlIHdhbGxldFBhc3NwaHJhc2UgaXMgd3JvbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICAgICAgICB1c2VyS2V5LFxuICAgICAgICAgICAgICBiYWNrdXBLZXksXG4gICAgICAgICAgICAgIHJvb3RBZGRyZXNzLFxuICAgICAgICAgICAgICBiaXRnb0tleTogYml0Z29QdWIsXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICd3cm9uZ3Bhc3N3b3JkJyxcbiAgICAgICAgICAgICAgZmVlLFxuICAgICAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICAgICAgICBmaXJzdFJvdW5kOiA1MDAzNTk2LFxuICAgICAgICAgICAgICBub2RlUGFyYW1zLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtZXNzYWdlOlxuICAgICAgICAgICAgICBcInVuYWJsZSB0byBkZWNyeXB0IHVzZXJLZXkgb3IgYmFja3VwS2V5IHdpdGggdGhlIHdhbGxldFBhc3NwaHJhc2UgcHJvdmlkZWQsIGdvdCBlcnJvcjogcGFzc3dvcmQgZXJyb3IgLSBjY206IHRhZyBkb2Vzbid0IG1hdGNoXCIsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgYml0Z28ga2V5IGlzIG5vdCBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgICAgICAgIHVzZXJLZXksXG4gICAgICAgICAgICAgIGJhY2t1cEtleSxcbiAgICAgICAgICAgICAgcm9vdEFkZHJlc3MsXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgICAgIGZlZSxcbiAgICAgICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbixcbiAgICAgICAgICAgICAgZmlyc3RSb3VuZDogNTAwMzU5NixcbiAgICAgICAgICAgICAgbm9kZVBhcmFtcyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWVzc2FnZTogJ2JpdGdvIHB1YmxpYyBrZXkgZnJvbSB0aGUga2V5Q2FyZCBpcyByZXF1aXJlZCBmb3Igbm9uLWJpdGdvIHJlY292ZXJ5JyxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBiZSBhYmxlIHRvIHBhc3MgYSB1dGYtOCBlbmNvZGVkIG5vdGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IG5vdGUgPSAnTm9uLUJpdEdvIFJlY292ZXJ5IFN3ZWVwIFR4JztcbiAgICAgICAgc2FuZEJveC5zdHViKEFsZ28ucHJvdG90eXBlLCAnZ2V0QWNjb3VudEJhbGFuY2UnKS5yZXNvbHZlcyhuYXRpdmVCYWxhbmNlKTtcbiAgICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleSxcbiAgICAgICAgICByb290QWRkcmVzcyxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGZlZSxcbiAgICAgICAgICBiaXRnb0tleTogYml0Z29QdWIsXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogcmVjb3ZlcnlEZXN0aW5hdGlvbixcbiAgICAgICAgICBmaXJzdFJvdW5kOiA1MDAyNTk2LFxuICAgICAgICAgIG5vZGVQYXJhbXMsXG4gICAgICAgICAgbm90ZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgICAgcmVjb3Zlcnkubm90ZS5zaG91bGQuYmUuZXF1YWwobm90ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdVbnNpZ25lZCBTd2VlcCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNhbmRCb3ggPSBTaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgICBjb25zdCBleHBlY3RlZEFtb3VudCA9IG5ldyBCaWdOdW1iZXIobmF0aXZlQmFsYW5jZSkubWludXMoZmVlKS5taW51cyhNSU5fQUNDT1VOVF9CQUxBTkNFKS50b1N0cmluZygpO1xuICAgICAgbGV0IGdldEJhbGFuY2VTdHViOiBTaW5vblN0dWI7XG5cbiAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBnZXRCYWxhbmNlU3R1YiA9IHNhbmRCb3guc3R1YihBbGdvLnByb3RvdHlwZSwgJ2dldEFjY291bnRCYWxhbmNlJykucmVzb2x2ZXMobmF0aXZlQmFsYW5jZSk7XG4gICAgICB9KTtcblxuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZEJveC52ZXJpZnlBbmRSZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCB1bnNpZ25lZCBzd2VlcCB0eCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OiB1c2VyUHViLFxuICAgICAgICAgIGJhY2t1cEtleTogYmFja3VwUHViLFxuICAgICAgICAgIGJpdGdvS2V5OiBiaXRnb1B1YixcbiAgICAgICAgICByb290QWRkcmVzcyxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGZlZSxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICAgIGZpcnN0Um91bmQ6IDUwMDM1OTYsXG4gICAgICAgICAgbm9kZVBhcmFtcyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZ2V0QmFsYW5jZVN0dWIuY2FsbENvdW50LnNob3VsZC5lcXVhbCgxKTtcblxuICAgICAgICByZWNvdmVyeS5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhIZXgnKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R5cGUnKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Ftb3VudCcpO1xuICAgICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlSW5mbycpO1xuICAgICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29pbicsICd0YWxnbycpO1xuICAgICAgICByZWNvdmVyeS5maXJzdFJvdW5kLnNob3VsZC5ub3QuYmUudW5kZWZpbmVkKCk7XG4gICAgICAgIHJlY292ZXJ5Lmxhc3RSb3VuZC5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgna2V5cycpO1xuICAgICAgICByZWNvdmVyeS5rZXlzLnNob3VsZC5kZWVwRXF1YWwoW3VzZXJQdWIsIGJhY2t1cFB1YiwgYml0Z29QdWJdKTtcbiAgICAgICAgcmVjb3ZlcnkuYWRkcmVzc1ZlcnNpb24uc2hvdWxkLmVxdWFsKDEpO1xuXG4gICAgICAgIGdldEJhbGFuY2VTdHViLmNhbGxDb3VudC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgIGNvbnN0IGZhY3RvcnkgPSBuZXcgQWxnb0xpYi5UcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCgnYWxnbycpKTtcbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5mcm9tKHJlY292ZXJ5LnR4SGV4KTtcbiAgICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgQnVmZmVyLmZyb20odHgudG9Ccm9hZGNhc3RGb3JtYXQoKSkudG9TdHJpbmcoJ2hleCcpLnNob3VsZC5kZWVwRXF1YWwocmVjb3ZlcnkudHhIZXgpO1xuICAgICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgICAgdHhKc29uLmFtb3VudC5zaG91bGQuZXF1YWwoZXhwZWN0ZWRBbW91bnQpO1xuICAgICAgICB0eEpzb24udG8uc2hvdWxkLmVxdWFsKHJlY292ZXJ5RGVzdGluYXRpb24pO1xuICAgICAgICB0eEpzb24uZnJvbS5zaG91bGQuZXF1YWwocm9vdEFkZHJlc3MpO1xuICAgICAgICB0eEpzb24uZmVlLnNob3VsZC5lcXVhbChmZWUpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnUmVjb3Zlcnkgd2l0aCByb290IGtleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzYW5kQm94ID0gU2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgICAgbGV0IHVzZXJLcDogS2V5UGFpcjtcbiAgICAgIGxldCBiYWNrdXBLcDogS2V5UGFpcjtcbiAgICAgIGxldCByb290QWRkcmVzczogc3RyaW5nO1xuICAgICAgbGV0IGVuY3J5cHRlZFVzZXJQcnY6IHN0cmluZztcbiAgICAgIGxldCBlbmNyeXB0ZWRCYWNrdXBQcnY6IHN0cmluZztcblxuICAgICAgY29uc3QgZXhwZWN0ZWRBbW91bnQgPSBuZXcgQmlnTnVtYmVyKG5hdGl2ZUJhbGFuY2UpLm1pbnVzKGZlZSkubWludXMoTUlOX0FDQ09VTlRfQkFMQU5DRSkudG9TdHJpbmcoKTtcbiAgICAgIGxldCBnZXRCYWxhbmNlU3R1YjogU2lub25TdHViO1xuXG4gICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdXNlclNlZWQgPSBCdWZmZXIuZnJvbSgnOWQ2MWIxOWRlZmZkNWE2MGJhODQ0YWY0OTJlYzJjYzQ0NDQ5YzU2OTdiMzI2OTE5NzAzYmFjMDMxY2FlN2Y2MCcsICdoZXgnKTtcbiAgICAgICAgdXNlcktwID0gYmFzZWNvaW4uZ2VuZXJhdGVSb290S2V5UGFpcih1c2VyU2VlZCk7XG4gICAgICAgIGVuY3J5cHRlZFVzZXJQcnYgPSBiaXRnby5lbmNyeXB0KHtcbiAgICAgICAgICBpbnB1dDogdXNlcktwLnBydixcbiAgICAgICAgICBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydCh1c2VyS3AucHViKTtcblxuICAgICAgICBjb25zdCBiYWNrdXBTZWVkID0gQnVmZmVyLmZyb20oJzZkNjFiMTlkZWZmZDVhNjBiYTg0NGFmNDkyZWMyY2M0NDQ0OWM1Njk3YjMyNjkxOTcwM2JhYzAzMWNhZTdmNjAnLCAnaGV4Jyk7XG4gICAgICAgIGJhY2t1cEtwID0gYmFzZWNvaW4uZ2VuZXJhdGVSb290S2V5UGFpcihiYWNrdXBTZWVkKTtcbiAgICAgICAgZW5jcnlwdGVkQmFja3VwUHJ2ID0gYml0Z28uZW5jcnlwdCh7XG4gICAgICAgICAgaW5wdXQ6IGJhY2t1cEtwLnBydixcbiAgICAgICAgICBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGJpdGdvUHViID0gJ0ZKU1dMTFBSQlhFR01XWlk1QlhBNjY3M1lLSUs3Sk9VUlZDUUVPV1hDNVRRUENYQ09LM1ZIT08yVlEnO1xuICAgICAgICBjb25zdCB1c2VyQWRkcmVzcyA9IEFsZ29MaWIuYWxnb1V0aWxzLnByaXZhdGVLZXlUb0FsZ29BZGRyZXNzKHVzZXJLcC5wcnYpO1xuICAgICAgICBjb25zdCBiYWNrdXBBZGRyZXNzID0gQWxnb0xpYi5hbGdvVXRpbHMucHJpdmF0ZUtleVRvQWxnb0FkZHJlc3MoYmFja3VwS3AucHJ2KTtcblxuICAgICAgICByb290QWRkcmVzcyA9IEFsZ29MaWIuYWxnb1V0aWxzLm11bHRpc2lnQWRkcmVzcygxLCAyLCBbdXNlckFkZHJlc3MsIGJhY2t1cEFkZHJlc3MsIGJpdGdvUHViXSk7XG4gICAgICB9KTtcblxuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZEJveC52ZXJpZnlBbmRSZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCBhbmQgc2lnbiBub24tYml0Z28gcmVjb3ZlcnkgdHggd2l0aCByb290IGtleXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGdldEJhbGFuY2VTdHViID0gc2FuZEJveC5zdHViKEFsZ28ucHJvdG90eXBlLCAnZ2V0QWNjb3VudEJhbGFuY2UnKS5yZXNvbHZlcyhuYXRpdmVCYWxhbmNlKTtcbiAgICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OiBlbmNyeXB0ZWRVc2VyUHJ2LFxuICAgICAgICAgIGJhY2t1cEtleTogZW5jcnlwdGVkQmFja3VwUHJ2LFxuICAgICAgICAgIHJvb3RBZGRyZXNzLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgZmVlLFxuICAgICAgICAgIGJpdGdvS2V5OiBiaXRnb1B1YixcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiByZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICAgIGZpcnN0Um91bmQ6IDUwMDI1OTYsXG4gICAgICAgICAgbm9kZVBhcmFtcyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lkJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuICAgICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdjb2luJywgJ3RhbGdvJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdmaXJzdFJvdW5kJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdsYXN0Um91bmQnKTtcbiAgICAgICAgZ2V0QmFsYW5jZVN0dWIuY2FsbENvdW50LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgY29uc3QgZmFjdG9yeSA9IG5ldyBBbGdvTGliLlRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCdhbGdvJykpO1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20ocmVjb3ZlcnkudHgpO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgICBjb25zdCB0eEJyb2FkY2FzdEZvcm1hdCA9IEJ1ZmZlci5mcm9tKHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICAgICAgdHhCcm9hZGNhc3RGb3JtYXQuc2hvdWxkLmRlZXBFcXVhbChyZWNvdmVyeS50eCk7XG4gICAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgICB0eEpzb24uYW1vdW50LnNob3VsZC5lcXVhbChleHBlY3RlZEFtb3VudCk7XG4gICAgICAgIHR4SnNvbi50by5zaG91bGQuZXF1YWwocmVjb3ZlcnlEZXN0aW5hdGlvbik7XG4gICAgICAgIHR4SnNvbi5mcm9tLnNob3VsZC5lcXVhbChyb290QWRkcmVzcyk7XG4gICAgICAgIHR4SnNvbi5mZWUuc2hvdWxkLmVxdWFsKGZlZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCB1bnNpZ25lZCBzd2VlcCB0eCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZ2V0QmFsYW5jZVN0dWIgPSBzYW5kQm94LnN0dWIoQWxnby5wcm90b3R5cGUsICdnZXRBY2NvdW50QmFsYW5jZScpLnJlc29sdmVzKG5hdGl2ZUJhbGFuY2UpO1xuICAgICAgICBjb25zdCByZWNvdmVyeSA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6IHVzZXJLcC5wdWIhLFxuICAgICAgICAgIGJhY2t1cEtleTogYmFja3VwS3AucHViISxcbiAgICAgICAgICBiaXRnb0tleTogYml0Z29QdWIsXG4gICAgICAgICAgcm9vdEFkZHJlc3MsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBmZWUsXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbixcbiAgICAgICAgICBmaXJzdFJvdW5kOiA1MDAzNTk2LFxuICAgICAgICAgIG5vZGVQYXJhbXMsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGdldEJhbGFuY2VTdHViLmNhbGxDb3VudC5zaG91bGQuZXF1YWwoMSk7XG5cbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4SGV4Jyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eXBlJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhbW91bnQnKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZUluZm8nKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvaW4nLCAndGFsZ28nKTtcbiAgICAgICAgcmVjb3ZlcnkuZmlyc3RSb3VuZC5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgICByZWNvdmVyeS5sYXN0Um91bmQuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2tleXMnKTtcbiAgICAgICAgcmVjb3Zlcnkua2V5cy5zaG91bGQuZGVlcEVxdWFsKFt1c2VyS3AucHViLCBiYWNrdXBLcC5wdWIsIGJpdGdvUHViXSk7XG4gICAgICAgIHJlY292ZXJ5LmFkZHJlc3NWZXJzaW9uLnNob3VsZC5lcXVhbCgxKTtcblxuICAgICAgICBnZXRCYWxhbmNlU3R1Yi5jYWxsQ291bnQuc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICBjb25zdCBmYWN0b3J5ID0gbmV3IEFsZ29MaWIuVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQoJ2FsZ28nKSk7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZnJvbShyZWNvdmVyeS50eEhleCk7XG4gICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIEJ1ZmZlci5mcm9tKHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdoZXgnKS5zaG91bGQuZGVlcEVxdWFsKHJlY292ZXJ5LnR4SGV4KTtcbiAgICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgICAgIHR4SnNvbi5hbW91bnQuc2hvdWxkLmVxdWFsKGV4cGVjdGVkQW1vdW50KTtcbiAgICAgICAgdHhKc29uLnRvLnNob3VsZC5lcXVhbChyZWNvdmVyeURlc3RpbmF0aW9uKTtcbiAgICAgICAgdHhKc29uLmZyb20uc2hvdWxkLmVxdWFsKHJvb3RBZGRyZXNzKTtcbiAgICAgICAgdHhKc29uLmZlZS5zaG91bGQuZXF1YWwoZmVlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQXVkaXRLZXknLCAoKSA9PiB7XG4gICAgY29uc3QgeyBrZXkgfSA9IGFsZ29CYWNrdXBLZXk7XG4gICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdaUThNaHhUODRtNFAnO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZm9yIHZhbGlkIGlucHV0cycsICgpID0+IHtcbiAgICAgIGJhc2Vjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICBlbmNyeXB0ZWRQcnY6IGtleSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiB0aGUgd2FsbGV0UGFzc3BocmFzZSBpcyBpbmNvcnJlY3QnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgYmFzZWNvaW4uYXNzZXJ0SXNWYWxpZEtleSh7XG4gICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGtleSxcbiAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmb28nLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICB7IG1lc3NhZ2U6IFwiZmFpbGVkIHRvIGRlY3J5cHQgcHJ2OiBjY206IHRhZyBkb2Vzbid0IG1hdGNoXCIgfVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYgdGhlIGtleSBpcyBhbHRlcmVkJywgKCkgPT4ge1xuICAgICAgY29uc3QgYWx0ZXJlZEtleSA9IGtleS5yZXBsYWNlKC9bMC05XS9nLCAnMCcpO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIGJhc2Vjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBhbHRlcmVkS2V5LFxuICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgeyBtZXNzYWdlOiAnZmFpbGVkIHRvIGRlY3J5cHQgcHJ2OiBqc29uIGRlY3J5cHQ6IGludmFsaWQgcGFyYW1ldGVycycgfVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYgdGhlIGtleSBpcyBub3QgYSB2YWxpZCBrZXknLCAoKSA9PiB7XG4gICAgICBjb25zdCBpbnZhbGlkS2V5ID0gJyNAKSQjKCQqQCkjKCQqJztcbiAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGVuY3J5cHQod2FsbGV0UGFzc3BocmFzZSwgaW52YWxpZEtleSk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgYmFzZWNvaW4uYXNzZXJ0SXNWYWxpZEtleSh7XG4gICAgICAgICAgICBlbmNyeXB0ZWRQcnYsXG4gICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICB7IG1lc3NhZ2U6ICdJbnZhbGlkIHByaXZhdGUga2V5OiBJbnZhbGlkIGJhc2UzMiBjaGFyYWN0ZXJzJyB9XG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnYmxpbmQgc2lnbmluZyB0b2tlbiBlbmFibGVtZW50IHByb3RlY3Rpb24nLCAoKSA9PiB7XG4gICAgbGV0IHdhbGxldDogV2FsbGV0O1xuICAgIGNvbnN0IGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1snbW9jayddLnVyaTtcblxuICAgIGJlZm9yZSgoKSA9PiB7XG4gICAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICAgIGJpdGdvLnNhZmVSZWdpc3RlcigndGFsZ28nLCBUYWxnby5jcmVhdGVJbnN0YW5jZSk7XG4gICAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICAgIGJhc2Vjb2luID0gYml0Z28uY29pbigndGFsZ28nKTtcblxuICAgICAgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHtcbiAgICAgICAgaWQ6ICcxMjMnLFxuICAgICAgICBjb2luOiAndGFsZ28nLFxuICAgICAgICBrZXlzOiBbJzEnLCAnMicsICczJ10sXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIHJvb3RBZGRyZXNzOiAnMTIzJyxcbiAgICAgICAgfSxcbiAgICAgICAgdHlwZTogJ2hvdCcsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIHZhbGlkIHRva2VuIGVuYWJsZW1lbnQgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB2ZXJpZnlUcmFuc2FjdGlvblN0dWIgPSBzcHkoYmFzZWNvaW4sICd2ZXJpZnlUcmFuc2FjdGlvbicpO1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvdGFsZ28vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4L2J1aWxkYClcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIHR4SGV4OlxuICAgICAgICAgICAgJ2lhUmhjbU4yeENCZm5NZ1l0YnlHNFJMMURzcFloeFFleW45UXJKK3MyWmNEVGN4Syt5T0grS05tWldYTkEraWlabmJPQTJ0bEpLTm5aVzZzZEdWemRHNWxkQzEyTVM0d29tZG94Q0JJWTdVWXBMUElUc2dROGkxUEVJSExEM0h3V2Flc0lON0dMMzl3NVFrNklxSnNkczREYTJrTW8zTnVaTVFnWDV6SUdMVzhodUVTOVE3S1dJY1VIc3AvVUt5ZnJObVhBMDNNU3ZzamgvaWtkSGx3WmFWaGVHWmxjcVI0WVdsa3pnbXBPa1k9JyxcbiAgICAgICAgICB0eEhhc2g6ICdBUllNT1hNS1pXTTM3MkpCRkJUQURaTkpaVTdTNUhLNDROWkRaTFZYNVVSNVVQSVdUN0ZBJyxcbiAgICAgICAgICB0eEluZm86IHtcbiAgICAgICAgICAgIGlkOiAnQVJZTU9YTUtaV00zNzJKQkZCVEFEWk5KWlU3UzVISzQ0TlpEWkxWWDVVUjVVUElXVDdGQScsXG4gICAgICAgICAgICB0eXBlOiAnYXhmZXInLFxuICAgICAgICAgICAgZnJvbTogJ0w2T01RR0ZWWFNET0NFWFZCM0ZGUkJZVUQzRkg2VUZNVDZXTlRGWURKWEdFVjZaRFE3NEVYR0Y2QkUnLFxuICAgICAgICAgICAgZmVlOiAxMDAwLFxuICAgICAgICAgICAgZmlyc3RSb3VuZDogNTczNjk4OTIsXG4gICAgICAgICAgICBsYXN0Um91bmQ6IDU3MzcwODkyLFxuICAgICAgICAgICAgbm90ZToge30sXG4gICAgICAgICAgICB0b2tlbklkOiAxNjIwODU0NDYsXG4gICAgICAgICAgICBnZW5lc2lzSUQ6ICd0ZXN0bmV0LXYxLjAnLFxuICAgICAgICAgICAgZ2VuZXNpc0hhc2g6ICdTR08xR0tTenlFN0lFUEl0VHhDQnl3OXg4Rm1uckNEZXhpOS9jT1VKT2lJPScsXG4gICAgICAgICAgICB0bzogJ0w2T01RR0ZWWFNET0NFWFZCM0ZGUkJZVUQzRkg2VUZNVDZXTlRGWURKWEdFVjZaRFE3NEVYR0Y2QkUnLFxuICAgICAgICAgICAgYW1vdW50OiAnMCcsXG4gICAgICAgICAgICB0eFR5cGU6ICdlbmFibGVUb2tlbicsXG4gICAgICAgICAgICB0b2tlbk5hbWU6ICdUQUxHTycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgICBzaXplOiAyNTEsXG4gICAgICAgICAgICBmZWU6IDEwMDAsXG4gICAgICAgICAgICBmZWVSYXRlOiA0LFxuICAgICAgICAgICAgZmVlU3RyaW5nOiAnMTAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgICAnNDJNSVlMMktCSVNWNldKUkFMVFRTWEhCRUdMTkY3TU1RNzRGR1NZVUNUNVlQM1YyS0VOSkdSRlZWUScsXG4gICAgICAgICAgICAnTUFHWFpUREZXNVFFWFVLT1VESUdIVFhPS0RXN1ROUUVETFdQQkVaRUwzVkZVM1lBQTJQR1lSUzY1TScsXG4gICAgICAgICAgICAnVE1FSlRJN1hOQ0FDREczQlRPRElOVzZDTVI2QVJZSUtUQ0ZQQTJHTUlYTDRYNVE0QkNFNlZITVdBTScsXG4gICAgICAgICAgXSxcbiAgICAgICAgICBhZGRyZXNzVmVyc2lvbjogMSxcbiAgICAgICAgICBjb2luOiAndGFsZ28nLFxuICAgICAgICB9KTtcbiAgICAgIGNvbnN0IHZhbGlkYXRlUHdkU3R1YiA9IHN0dWIod2FsbGV0LCAnZ2V0S2V5Y2hhaW5zQW5kVmFsaWRhdGVQYXNzcGhyYXNlJyBhcyBrZXlvZiBXYWxsZXQpLnJlc29sdmVzKFtdKTtcbiAgICAgIGNvbnN0IHNpZ25UeFN0dWIgPSBzdHViKHdhbGxldCwgJ3NpZ25UcmFuc2FjdGlvbicpLnJlc29sdmVzKHt9KTtcblxuICAgICAgYXdhaXQgd2FsbGV0LnNlbmRUb2tlbkVuYWJsZW1lbnRzKHtcbiAgICAgICAgdmVyaWZpY2F0aW9uOiB7IHZlcmlmeVRva2VuRW5hYmxlbWVudDogdHJ1ZSB9LFxuICAgICAgICBlbmFibGVUb2tlbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBuYW1lOiAndGFsZ286SlBULTE2MjA4NTQ0NicsXG4gICAgICAgICAgICBhZGRyZXNzOiAnTDZPTVFHRlZYU0RPQ0VYVkIzRkZSQllVRDNGSDZVRk1UNldOVEZZREpYR0VWNlpEUTc0RVhHRjZCRScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuXG4gICAgICB2ZXJpZnlUcmFuc2FjdGlvblN0dWIuY2FsbGVkLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICB2ZXJpZnlUcmFuc2FjdGlvblN0dWIucmVzdG9yZSgpO1xuICAgICAgdmFsaWRhdGVQd2RTdHViLnJlc3RvcmUoKTtcbiAgICAgIHNpZ25UeFN0dWIucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIGludmFsaWQgdG9rZW4gZW5hYmxlbWVudCB0cmFuc2FjdGlvbiBpcyByZXR1cm5lZCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHZlcmlmeVRyYW5zYWN0aW9uU3R1YiA9IHNweShiYXNlY29pbiwgJ3ZlcmlmeVRyYW5zYWN0aW9uJyk7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi90YWxnby93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvYnVpbGRgKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgdHhIZXg6XG4gICAgICAgICAgICAnaWFSaGNtTjJ4Q0Jmbk1nWXRieUc0UkwxRHNwWWh4UWV5bjlRckorczJaY0RUY3hLK3lPSCtLTm1aV1hOQStpaVpuYk9BMnRwZXFOblpXNnNkR1Z6ZEc1bGRDMTJNUzR3b21kb3hDQklZN1VZcExQSVRzZ1E4aTFQRUlITEQzSHdXYWVzSU43R0wzOXc1UWs2SXFKc2RzNERhMjFpbzNOdVpNUWdYNXpJR0xXOGh1RVM5UTdLV0ljVUhzcC9VS3lmck5tWEEwM01TdnNqaC9pa2RIbHdaYVZoZUdabGNxUjRZV2xremdBQ3dOOD0nLFxuICAgICAgICAgIHR4SGFzaDogJ1lQUUdZTkJPQ1BYTUJGVEJaSDJBUUdDRFozQzI3NjJUNkVZUVk0NkY3TFJHMlVSWDZETEEnLFxuICAgICAgICAgIHR4SW5mbzoge1xuICAgICAgICAgICAgaWQ6ICdZUFFHWU5CT0NQWE1CRlRCWkgyQVFHQ0RaM0MyNzYyVDZFWVFZNDZGN0xSRzJVUlg2RExBJyxcbiAgICAgICAgICAgIHR5cGU6ICdheGZlcicsXG4gICAgICAgICAgICBmcm9tOiAnTDZPTVFHRlZYU0RPQ0VYVkIzRkZSQllVRDNGSDZVRk1UNldOVEZZREpYR0VWNlpEUTc0RVhHRjZCRScsXG4gICAgICAgICAgICBmZWU6IDEwMDAsXG4gICAgICAgICAgICBmaXJzdFJvdW5kOiA1NzM3MTAwMixcbiAgICAgICAgICAgIGxhc3RSb3VuZDogNTczNzIwMDIsXG4gICAgICAgICAgICBub3RlOiB7fSxcbiAgICAgICAgICAgIHRva2VuSWQ6IDE4MDQ0NyxcbiAgICAgICAgICAgIGdlbmVzaXNJRDogJ3Rlc3RuZXQtdjEuMCcsXG4gICAgICAgICAgICBnZW5lc2lzSGFzaDogJ1NHTzFHS1N6eUU3SUVQSXRUeENCeXc5eDhGbW5yQ0RleGk5L2NPVUpPaUk9JyxcbiAgICAgICAgICAgIHRvOiAnTDZPTVFHRlZYU0RPQ0VYVkIzRkZSQllVRDNGSDZVRk1UNldOVEZZREpYR0VWNlpEUTc0RVhHRjZCRScsXG4gICAgICAgICAgICBhbW91bnQ6ICcwJyxcbiAgICAgICAgICAgIHR4VHlwZTogJ2VuYWJsZVRva2VuJyxcbiAgICAgICAgICAgIHRva2VuTmFtZTogJ1RBTEdPJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICAgIHNpemU6IDI1MSxcbiAgICAgICAgICAgIGZlZTogMTAwMCxcbiAgICAgICAgICAgIGZlZVJhdGU6IDQsXG4gICAgICAgICAgICBmZWVTdHJpbmc6ICcxMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGtleXM6IFtcbiAgICAgICAgICAgICc0Mk1JWUwyS0JJU1Y2V0pSQUxUVFNYSEJFR0xORjdNTVE3NEZHU1lVQ1Q1WVAzVjJLRU5KR1JGVlZRJyxcbiAgICAgICAgICAgICdNQUdYWlRERlc1UUVYVUtPVURJR0hUWE9LRFc3VE5RRURMV1BCRVpFTDNWRlUzWUFBMlBHWVJTNjVNJyxcbiAgICAgICAgICAgICdUTUVKVEk3WE5DQUNERzNCVE9ESU5XNkNNUjZBUllJS1RDRlBBMkdNSVhMNFg1UTRCQ0U2VkhNV0FNJyxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGFkZHJlc3NWZXJzaW9uOiAxLFxuICAgICAgICAgIGNvaW46ICd0YWxnbycsXG4gICAgICAgIH0pO1xuICAgICAgc3R1Yih3YWxsZXQsICdnZXRLZXljaGFpbnNBbmRWYWxpZGF0ZVBhc3NwaHJhc2UnIGFzIGtleW9mIFdhbGxldCkucmVzb2x2ZXMoW10pO1xuICAgICAgc3R1Yih3YWxsZXQsICdzaWduVHJhbnNhY3Rpb24nKS5yZXNvbHZlcyh7fSk7XG5cbiAgICAgIGNvbnN0IHsgc3VjY2VzcywgZmFpbHVyZSB9ID0gYXdhaXQgd2FsbGV0LnNlbmRUb2tlbkVuYWJsZW1lbnRzKHtcbiAgICAgICAgdmVyaWZpY2F0aW9uOiB7IHZlcmlmeVRva2VuRW5hYmxlbWVudDogdHJ1ZSB9LFxuICAgICAgICBlbmFibGVUb2tlbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBuYW1lOiAndGFsZ286SlBULTE2MjA4NTQ0NicsXG4gICAgICAgICAgICBhZGRyZXNzOiAnTDZPTVFHRlZYU0RPQ0VYVkIzRkZSQllVRDNGSDZVRk1UNldOVEZZREpYR0VWNlpEUTc0RVhHRjZCRScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuXG4gICAgICB2ZXJpZnlUcmFuc2FjdGlvblN0dWIuY2FsbGVkLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBzdWNjZXNzLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgICBmYWlsdXJlLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICBmYWlsdXJlWzBdLm1lc3NhZ2Uuc2hvdWxkLmVxdWFsKFxuICAgICAgICAnVG9rZW4gZW5hYmxlbWVudCB2ZXJpZmljYXRpb24gZmFpbGVkOiBleHBlY3RlZCB0b2tlbiBJRCAxNjIwODU0NDYgYnV0IHRyYW5zYWN0aW9uIGhhcyB0b2tlbiBJRCAxODA0NDcnXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19