@bitgo-beta/sdk-api 1.10.1-beta.203 → 1.10.1-beta.2031

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 (91) hide show
  1. package/dist/package.json +23 -27
  2. package/dist/src/api.d.ts +8 -5
  3. package/dist/src/api.d.ts.map +1 -1
  4. package/dist/src/api.js +134 -72
  5. package/dist/src/bitgoAPI.d.ts +115 -31
  6. package/dist/src/bitgoAPI.d.ts.map +1 -1
  7. package/dist/src/bitgoAPI.js +705 -342
  8. package/dist/src/decryptV1.d.ts +60 -0
  9. package/dist/src/decryptV1.d.ts.map +1 -0
  10. package/dist/src/decryptV1.js +140 -0
  11. package/dist/src/encrypt.d.ts +37 -6
  12. package/dist/src/encrypt.d.ts.map +1 -1
  13. package/dist/src/encrypt.js +171 -15
  14. package/dist/src/encryptV2.d.ts +67 -0
  15. package/dist/src/encryptV2.d.ts.map +1 -0
  16. package/dist/src/encryptV2.js +234 -0
  17. package/dist/src/encryptionSession.d.ts +63 -0
  18. package/dist/src/encryptionSession.d.ts.map +1 -0
  19. package/dist/src/encryptionSession.js +140 -0
  20. package/dist/src/index.d.ts +3 -0
  21. package/dist/src/index.d.ts.map +1 -1
  22. package/dist/src/index.js +9 -2
  23. package/dist/src/types.d.ts +70 -43
  24. package/dist/src/types.d.ts.map +1 -1
  25. package/dist/src/types.js +4 -2
  26. package/dist/src/util.d.ts +12 -0
  27. package/dist/src/util.d.ts.map +1 -1
  28. package/dist/src/util.js +57 -4
  29. package/dist/src/v1/blockchain.js +25 -12
  30. package/dist/src/v1/keychains.js +39 -26
  31. package/dist/src/v1/markets.js +10 -5
  32. package/dist/src/v1/pendingapproval.d.ts.map +1 -1
  33. package/dist/src/v1/pendingapproval.js +57 -18
  34. package/dist/src/v1/pendingapprovals.d.ts.map +1 -1
  35. package/dist/src/v1/pendingapprovals.js +41 -7
  36. package/dist/src/v1/signPsbt.d.ts +14 -0
  37. package/dist/src/v1/signPsbt.d.ts.map +1 -0
  38. package/dist/src/v1/signPsbt.js +69 -0
  39. package/dist/src/v1/transactionBuilder.js +221 -91
  40. package/dist/src/v1/travelRule.js +125 -66
  41. package/dist/src/v1/verifyAddress.d.ts +6 -0
  42. package/dist/src/v1/verifyAddress.d.ts.map +1 -0
  43. package/dist/src/v1/verifyAddress.js +50 -0
  44. package/dist/src/v1/wallet.d.ts.map +1 -1
  45. package/dist/src/v1/wallet.js +498 -230
  46. package/dist/src/v1/wallets.js +118 -53
  47. package/dist/test/unit/api.d.ts +2 -0
  48. package/dist/test/unit/api.d.ts.map +1 -0
  49. package/dist/test/unit/api.js +307 -0
  50. package/dist/test/unit/bitgoAPI.d.ts +2 -0
  51. package/dist/test/unit/bitgoAPI.d.ts.map +1 -0
  52. package/dist/test/unit/bitgoAPI.js +1117 -0
  53. package/dist/test/unit/decryptV1.browser.d.ts +2 -0
  54. package/dist/test/unit/decryptV1.browser.d.ts.map +1 -0
  55. package/dist/test/unit/decryptV1.browser.js +133 -0
  56. package/dist/test/unit/decryptV1.d.ts +2 -0
  57. package/dist/test/unit/decryptV1.d.ts.map +1 -0
  58. package/dist/test/unit/decryptV1.js +230 -0
  59. package/dist/test/unit/encrypt.d.ts +2 -0
  60. package/dist/test/unit/encrypt.d.ts.map +1 -0
  61. package/dist/test/unit/encrypt.js +544 -0
  62. package/dist/test/unit/fixtures/keycard.d.ts +25 -0
  63. package/dist/test/unit/fixtures/keycard.d.ts.map +1 -0
  64. package/dist/test/unit/fixtures/keycard.js +28 -0
  65. package/dist/test/unit/hmacStrategy.d.ts +2 -0
  66. package/dist/test/unit/hmacStrategy.d.ts.map +1 -0
  67. package/dist/test/unit/hmacStrategy.js +136 -0
  68. package/dist/test/unit/utils.d.ts +2 -0
  69. package/dist/test/unit/utils.d.ts.map +1 -0
  70. package/dist/test/unit/utils.js +65 -0
  71. package/dist/test/unit/v1/fixtures/accelerate-tx.d.ts +4 -0
  72. package/dist/test/unit/v1/fixtures/accelerate-tx.d.ts.map +1 -0
  73. package/dist/test/unit/v1/fixtures/accelerate-tx.js +53 -0
  74. package/dist/test/unit/v1/fixtures/index.d.ts +3 -0
  75. package/dist/test/unit/v1/fixtures/index.d.ts.map +1 -0
  76. package/dist/test/unit/v1/fixtures/index.js +24 -0
  77. package/dist/test/unit/v1/signPsbt.d.ts +2 -0
  78. package/dist/test/unit/v1/signPsbt.d.ts.map +1 -0
  79. package/dist/test/unit/v1/signPsbt.js +53 -0
  80. package/dist/test/unit/v1/travelRule.d.ts +2 -0
  81. package/dist/test/unit/v1/travelRule.d.ts.map +1 -0
  82. package/dist/test/unit/v1/travelRule.js +125 -0
  83. package/dist/test/unit/v1/wallet.d.ts +2 -0
  84. package/dist/test/unit/v1/wallet.d.ts.map +1 -0
  85. package/dist/test/unit/v1/wallet.js +1717 -0
  86. package/dist/tsconfig.tsbuildinfo +1 -0
  87. package/package.json +23 -27
  88. package/.eslintignore +0 -5
  89. package/CHANGELOG.md +0 -605
  90. package/dist/web/main.js +0 -2
  91. package/dist/web/main.js.LICENSE.txt +0 -110
@@ -0,0 +1,1117 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const assert = __importStar(require("assert"));
40
+ require("should");
41
+ const bitgoAPI_1 = require("../../src/bitgoAPI");
42
+ const proxy_agent_1 = require("proxy-agent");
43
+ const sinon = __importStar(require("sinon"));
44
+ const nock_1 = __importDefault(require("nock"));
45
+ describe('Constructor', function () {
46
+ describe('cookiesPropagationEnabled argument', function () {
47
+ it('cookiesPropagationEnabled is enabled explicitly', function () {
48
+ const bitgo = new bitgoAPI_1.BitGoAPI({
49
+ env: 'custom',
50
+ customRootURI: 'https://app.example.local',
51
+ cookiesPropagationEnabled: true,
52
+ });
53
+ bitgo.should.have.property('cookiesPropagationEnabled');
54
+ bitgo.cookiesPropagationEnabled.should.equal(true);
55
+ });
56
+ it('cookiesPropagationEnabled is disabled explicitly', function () {
57
+ const bitgo = new bitgoAPI_1.BitGoAPI({
58
+ env: 'custom',
59
+ customRootURI: 'https://app.example.local',
60
+ cookiesPropagationEnabled: false,
61
+ });
62
+ bitgo.should.have.property('cookiesPropagationEnabled');
63
+ bitgo.cookiesPropagationEnabled.should.equal(false);
64
+ });
65
+ it('cookiesPropagationEnabled is disabled by default', function () {
66
+ const bitgo = new bitgoAPI_1.BitGoAPI({
67
+ env: 'custom',
68
+ customRootURI: 'https://app.example.local',
69
+ });
70
+ bitgo.should.have.property('cookiesPropagationEnabled');
71
+ bitgo.cookiesPropagationEnabled.should.equal(false);
72
+ });
73
+ });
74
+ describe('requestIdPrefix argument', function () {
75
+ afterEach(function () {
76
+ nock_1.default.cleanAll();
77
+ });
78
+ it('should prepend requestIdPrefix to Request-ID header when set', async function () {
79
+ const bitgo = new bitgoAPI_1.BitGoAPI({
80
+ env: 'custom',
81
+ customRootURI: 'https://app.example.local',
82
+ requestIdPrefix: 'test-prefix-',
83
+ });
84
+ const scope = (0, nock_1.default)('https://app.example.local')
85
+ .get('/api/v1/ping')
86
+ .matchHeader('Request-ID', /^test-prefix-/)
87
+ .reply(200, { status: 'ok' });
88
+ await bitgo.ping({
89
+ reqId: {
90
+ toString: () => '12345',
91
+ inc: () => {
92
+ /* mock */
93
+ },
94
+ },
95
+ });
96
+ scope.isDone().should.be.true();
97
+ });
98
+ it('should not modify Request-ID header when requestIdPrefix is not set', async function () {
99
+ const bitgo = new bitgoAPI_1.BitGoAPI({
100
+ env: 'custom',
101
+ customRootURI: 'https://app.example.local',
102
+ });
103
+ const scope = (0, nock_1.default)('https://app.example.local')
104
+ .get('/api/v1/ping')
105
+ .matchHeader('Request-ID', /^12345$/)
106
+ .reply(200, { status: 'ok' });
107
+ await bitgo.ping({
108
+ reqId: {
109
+ toString: () => '12345',
110
+ inc: () => {
111
+ /* mock */
112
+ },
113
+ },
114
+ });
115
+ scope.isDone().should.be.true();
116
+ });
117
+ it('should correctly format Request-ID with prefix and numeric sequence', async function () {
118
+ const bitgo = new bitgoAPI_1.BitGoAPI({
119
+ env: 'custom',
120
+ customRootURI: 'https://app.example.local',
121
+ requestIdPrefix: 'myapp-v1-',
122
+ });
123
+ const scope = (0, nock_1.default)('https://app.example.local')
124
+ .get('/api/v1/ping')
125
+ .matchHeader('Request-ID', 'myapp-v1-trace-123')
126
+ .reply(200, { status: 'ok' });
127
+ await bitgo.ping({
128
+ reqId: {
129
+ toString: () => 'trace-123',
130
+ inc: () => {
131
+ /* mock */
132
+ },
133
+ },
134
+ });
135
+ scope.isDone().should.be.true();
136
+ });
137
+ it('should work with empty string prefix', async function () {
138
+ const bitgo = new bitgoAPI_1.BitGoAPI({
139
+ env: 'custom',
140
+ customRootURI: 'https://app.example.local',
141
+ requestIdPrefix: '',
142
+ });
143
+ const scope = (0, nock_1.default)('https://app.example.local')
144
+ .get('/api/v1/ping')
145
+ .matchHeader('Request-ID', 'abc-123')
146
+ .reply(200, { status: 'ok' });
147
+ await bitgo.ping({
148
+ reqId: {
149
+ toString: () => 'abc-123',
150
+ inc: () => {
151
+ /* mock */
152
+ },
153
+ },
154
+ });
155
+ scope.isDone().should.be.true();
156
+ });
157
+ });
158
+ describe('http proxy agent', function () {
159
+ it('http proxy agent shall be created when proxy(customProxyagent) is set', function () {
160
+ const customProxyAgent = new proxy_agent_1.ProxyAgent({
161
+ getProxyForUrl: () => 'http://localhost:3000',
162
+ });
163
+ const bitgo = new bitgoAPI_1.BitGoAPI({
164
+ env: 'custom',
165
+ customRootURI: 'https://app.example.local',
166
+ customProxyAgent,
167
+ });
168
+ bitgo.should.have.property('_customProxyAgent', customProxyAgent);
169
+ });
170
+ it('bitgo api is still initiated when proxy(customProxyAgent) is not set', function () {
171
+ const bitgo = new bitgoAPI_1.BitGoAPI({
172
+ env: 'custom',
173
+ customRootURI: 'https://app.example.local',
174
+ });
175
+ bitgo.should.have.property('_customProxyAgent', undefined);
176
+ });
177
+ });
178
+ describe('verifyAddress', function () {
179
+ it('should successfully verify a base58 address', function () {
180
+ const bitgo = new bitgoAPI_1.BitGoAPI({
181
+ env: 'test',
182
+ });
183
+ bitgo.verifyAddress({ address: '2N6paT2TU4N1XpaZjJiApWJXoeyrL3UWpkZ' }).should.be.true();
184
+ });
185
+ it('should successfully verify a bech32 address', function () {
186
+ const bitgo = new bitgoAPI_1.BitGoAPI({
187
+ env: 'test',
188
+ });
189
+ bitgo
190
+ .verifyAddress({ address: 'tb1qguzyk4w6kaqtpsczs5aj0w8r7598jq36egm8e98wqph3rwmex68seslgsg' })
191
+ .should.be.true();
192
+ });
193
+ });
194
+ describe('url', function () {
195
+ it('should return the correct URL for version 1', function () {
196
+ const bitgo = new bitgoAPI_1.BitGoAPI({
197
+ env: 'test',
198
+ customRootURI: 'https://test.bitgo.com',
199
+ });
200
+ const path = '/test-path';
201
+ const expectedUrl = 'https://test.bitgo.com/api/v1/test-path';
202
+ const result = bitgo.url(path, 1);
203
+ result.should.equal(expectedUrl);
204
+ });
205
+ it('should return the correct URL for version 2', function () {
206
+ const bitgo = new bitgoAPI_1.BitGoAPI({
207
+ env: 'test',
208
+ customRootURI: 'https://test.bitgo.com',
209
+ });
210
+ const path = '/test-path';
211
+ const expectedUrl = 'https://test.bitgo.com/api/v2/test-path';
212
+ const result = bitgo.url(path, 2);
213
+ result.should.equal(expectedUrl);
214
+ });
215
+ it('should return the correct URL for version 3', function () {
216
+ const bitgo = new bitgoAPI_1.BitGoAPI({
217
+ env: 'test',
218
+ customRootURI: 'https://test.bitgo.com',
219
+ });
220
+ const path = '/test-path';
221
+ const expectedUrl = 'https://test.bitgo.com/api/v3/test-path';
222
+ const result = bitgo.url(path, 3);
223
+ result.should.equal(expectedUrl);
224
+ });
225
+ it('should default to version 1 if no version is provided', function () {
226
+ const bitgo = new bitgoAPI_1.BitGoAPI({
227
+ env: 'test',
228
+ customRootURI: 'https://test.bitgo.com',
229
+ });
230
+ const path = '/test-path';
231
+ const expectedUrl = 'https://test.bitgo.com/api/v1/test-path';
232
+ const result = bitgo.url(path);
233
+ result.should.equal(expectedUrl);
234
+ });
235
+ });
236
+ describe('decryptKeys', function () {
237
+ let bitgo;
238
+ beforeEach(function () {
239
+ bitgo = new bitgoAPI_1.BitGoAPI({ env: 'test' });
240
+ });
241
+ afterEach(function () {
242
+ sinon.restore();
243
+ });
244
+ it('should throw if no params are provided', async function () {
245
+ // @ts-expect-error - intentionally calling with no params for test
246
+ await bitgo.decryptKeys().should.be.rejectedWith('Missing parameter: walletIdEncryptedKeyPairs');
247
+ });
248
+ it('should throw if walletIdEncryptedKeyPairs is missing', async function () {
249
+ await bitgo
250
+ // @ts-expect-error - intentionally missing required param
251
+ .decryptKeys({ password: 'password123' })
252
+ .should.be.rejectedWith('Missing parameter: walletIdEncryptedKeyPairs');
253
+ });
254
+ it('should throw if password is missing', async function () {
255
+ // @ts-expect-error - intentionally missing required param
256
+ await bitgo.decryptKeys({ walletIdEncryptedKeyPairs: [] }).should.be.rejectedWith('Missing parameter: password');
257
+ });
258
+ it('should throw if walletIdEncryptedKeyPairs is not an array', async function () {
259
+ await bitgo
260
+ // @ts-expect-error - intentionally providing wrong type
261
+ .decryptKeys({ walletIdEncryptedKeyPairs: 'not an array', password: 'password123' })
262
+ .should.be.rejectedWith('walletIdEncryptedKeyPairs must be an array');
263
+ });
264
+ it('should return empty array for empty walletIdEncryptedKeyPairs', async function () {
265
+ const result = await bitgo.decryptKeys({ walletIdEncryptedKeyPairs: [], password: 'password123' });
266
+ result.should.be.an.Array();
267
+ result.should.be.empty();
268
+ });
269
+ it('should throw if any walletId is missing or not a string', async function () {
270
+ await bitgo
271
+ .decryptKeys({
272
+ walletIdEncryptedKeyPairs: [
273
+ // @ts-expect-error - intentionally missing walletId
274
+ { encryptedPrv: 'encrypted-data' },
275
+ ],
276
+ password: 'password123',
277
+ })
278
+ .should.be.rejectedWith('each key pair must have a string walletId');
279
+ await bitgo
280
+ .decryptKeys({
281
+ walletIdEncryptedKeyPairs: [
282
+ // @ts-expect-error - intentionally providing wrong type
283
+ { walletId: 123, encryptedPrv: 'encrypted-data' },
284
+ ],
285
+ password: 'password123',
286
+ })
287
+ .should.be.rejectedWith('each key pair must have a string walletId');
288
+ });
289
+ it('should throw if any encryptedPrv is missing or not a string', async function () {
290
+ await bitgo
291
+ .decryptKeys({
292
+ walletIdEncryptedKeyPairs: [
293
+ // @ts-expect-error - intentionally missing encryptedPrv
294
+ { walletId: 'wallet-id-1' },
295
+ ],
296
+ password: 'password123',
297
+ })
298
+ .should.be.rejectedWith('each key pair must have a string encryptedPrv');
299
+ await bitgo
300
+ .decryptKeys({
301
+ walletIdEncryptedKeyPairs: [
302
+ // @ts-expect-error - intentionally providing wrong type
303
+ { walletId: 'wallet-id-1', encryptedPrv: 123 },
304
+ ],
305
+ password: 'password123',
306
+ })
307
+ .should.be.rejectedWith('each key pair must have a string encryptedPrv');
308
+ });
309
+ });
310
+ describe('decryptKeys', function () {
311
+ let bitgo;
312
+ beforeEach(function () {
313
+ bitgo = new bitgoAPI_1.BitGoAPI({ env: 'test' });
314
+ });
315
+ afterEach(function () {
316
+ sinon.restore();
317
+ });
318
+ it('should return walletIds of keys that failed to decrypt', async function () {
319
+ const decryptAsyncStub = sinon.stub(bitgo, 'decrypt');
320
+ decryptAsyncStub.onFirstCall().resolves('decrypted-key-1');
321
+ decryptAsyncStub.onSecondCall().rejects(new Error('decryption failed'));
322
+ const result = await bitgo.decryptKeys({
323
+ walletIdEncryptedKeyPairs: [
324
+ { walletId: 'wallet-id-1', encryptedPrv: 'encrypted-data-1' },
325
+ { walletId: 'wallet-id-2', encryptedPrv: 'encrypted-data-2' },
326
+ ],
327
+ password: 'password123',
328
+ });
329
+ result.should.be.an.Array();
330
+ result.should.have.length(1);
331
+ result[0].should.equal('wallet-id-2');
332
+ });
333
+ it('should correctly process multiple wallet keys', async function () {
334
+ const decryptAsyncStub = sinon.stub(bitgo, 'decrypt');
335
+ decryptAsyncStub
336
+ .withArgs({ input: 'encrypted-data-2', password: 'password123' })
337
+ .rejects(new Error('decryption failed'));
338
+ decryptAsyncStub
339
+ .withArgs({ input: 'encrypted-data-4', password: 'password123' })
340
+ .rejects(new Error('decryption failed'));
341
+ decryptAsyncStub.resolves('success');
342
+ const result = await bitgo.decryptKeys({
343
+ walletIdEncryptedKeyPairs: [
344
+ { walletId: 'wallet-id-1', encryptedPrv: 'encrypted-data-1' },
345
+ { walletId: 'wallet-id-2', encryptedPrv: 'encrypted-data-2' },
346
+ { walletId: 'wallet-id-3', encryptedPrv: 'encrypted-data-3' },
347
+ { walletId: 'wallet-id-4', encryptedPrv: 'encrypted-data-4' },
348
+ ],
349
+ password: 'password123',
350
+ });
351
+ decryptAsyncStub.callCount.should.equal(4);
352
+ result.should.be.an.Array();
353
+ result.should.have.length(2);
354
+ result.should.containDeep(['wallet-id-2', 'wallet-id-4']);
355
+ });
356
+ });
357
+ describe('User-Agent header based on environment', function () {
358
+ afterEach(function () {
359
+ nock_1.default.cleanAll();
360
+ sinon.restore();
361
+ });
362
+ it('should set User-Agent header when running in Node.js (typeof window === undefined)', async function () {
363
+ const bitgo = new bitgoAPI_1.BitGoAPI({
364
+ env: 'custom',
365
+ customRootURI: 'https://app.example.local',
366
+ userAgent: 'TestAgent/1.0',
367
+ });
368
+ // Ensure we're in a Node.js environment by verifying window is undefined
369
+ (typeof window).should.equal('undefined');
370
+ const scope = (0, nock_1.default)('https://app.example.local')
371
+ .get('/api/v1/ping')
372
+ .matchHeader('User-Agent', 'TestAgent/1.0')
373
+ .reply(200, { status: 'ok' });
374
+ await bitgo.ping({
375
+ reqId: {
376
+ toString: () => 'test-123',
377
+ inc: () => {
378
+ /* mock */
379
+ },
380
+ },
381
+ });
382
+ scope.isDone().should.be.true();
383
+ });
384
+ it('should not set User-Agent header when running in browser (typeof window !== undefined)', async function () {
385
+ // Mock the window object to simulate browser environment
386
+ const windowStub = { location: 'mock' };
387
+ global.window = windowStub;
388
+ try {
389
+ const bitgo = new bitgoAPI_1.BitGoAPI({
390
+ env: 'custom',
391
+ customRootURI: 'https://app.example.local',
392
+ userAgent: 'TestAgent/1.0',
393
+ });
394
+ const scope = (0, nock_1.default)('https://app.example.local')
395
+ .get('/api/v1/ping')
396
+ .reply(function () {
397
+ // Verify User-Agent header is NOT set to our custom value
398
+ const userAgent = this.req.headers['user-agent'];
399
+ if (userAgent && userAgent.includes('TestAgent/1.0')) {
400
+ throw new Error('User-Agent should not be set in browser environment');
401
+ }
402
+ return [200, { status: 'ok' }];
403
+ });
404
+ await bitgo.ping({
405
+ reqId: {
406
+ toString: () => 'test-123',
407
+ inc: () => {
408
+ /* mock */
409
+ },
410
+ },
411
+ });
412
+ scope.isDone().should.be.true();
413
+ }
414
+ finally {
415
+ // Clean up the global window mock
416
+ delete global.window;
417
+ }
418
+ });
419
+ });
420
+ describe('hmacAuthStrategy token lifecycle', function () {
421
+ const ROOT = 'https://app.example.local';
422
+ // Builds a mock strategy whose setToken / clearToken are sinon stubs.
423
+ function makeStrategy(overrides = {}) {
424
+ const setTokenStub = sinon.stub().resolves();
425
+ const clearTokenStub = sinon.stub().resolves();
426
+ const strategy = {
427
+ calculateRequestHeaders: sinon.stub().resolves({ hmac: 'hmac', timestamp: 1, tokenHash: 'hash' }),
428
+ verifyResponse: sinon.stub().resolves({
429
+ isValid: true,
430
+ expectedHmac: 'hmac',
431
+ signatureSubject: '',
432
+ isInResponseValidityWindow: true,
433
+ verificationTime: Date.now(),
434
+ }),
435
+ calculateHMAC: sinon.stub().resolves('hashed-pw'),
436
+ setToken: setTokenStub,
437
+ clearToken: clearTokenStub,
438
+ ...overrides,
439
+ };
440
+ return { strategy, setTokenStub, clearTokenStub };
441
+ }
442
+ afterEach(function () {
443
+ nock_1.default.cleanAll();
444
+ sinon.restore();
445
+ });
446
+ describe('authenticate()', function () {
447
+ it('calls setToken with the access_token received from the server', async function () {
448
+ const { strategy, setTokenStub } = makeStrategy();
449
+ const bitgo = new bitgoAPI_1.BitGoAPI({ env: 'custom', customRootURI: ROOT, hmacAuthStrategy: strategy });
450
+ (0, nock_1.default)(ROOT)
451
+ .post('/api/v2/user/login')
452
+ .reply(200, {
453
+ user: { username: 'test@example.com' },
454
+ access_token: 'v2xmyaccesstoken',
455
+ });
456
+ await bitgo.authenticate({ username: 'test@example.com', password: 'hunter2' });
457
+ setTokenStub.calledOnce.should.be.true();
458
+ setTokenStub.firstCall.args[0].should.equal('v2xmyaccesstoken');
459
+ });
460
+ it('awaits setToken before making ensureEcdhKeychain requests', async function () {
461
+ // This is the core regression test: if setToken is not awaited, the
462
+ // strategy's key material won't be ready before calculateRequestHeaders
463
+ // is called for the GET /user/settings request, and it would throw.
464
+ let keyReady = false;
465
+ const { strategy } = makeStrategy({
466
+ setToken: sinon.stub().callsFake(async () => {
467
+ // Simulate non-trivial async key derivation (like crypto.subtle.importKey).
468
+ await new Promise((resolve) => setImmediate(resolve));
469
+ keyReady = true;
470
+ }),
471
+ calculateRequestHeaders: sinon.stub().callsFake(async () => {
472
+ if (!keyReady) {
473
+ throw new Error('No token available. Call setToken() or restoreToken() first.');
474
+ }
475
+ return { hmac: 'hmac', timestamp: Date.now(), tokenHash: 'hash' };
476
+ }),
477
+ });
478
+ const bitgo = new bitgoAPI_1.BitGoAPI({ env: 'custom', customRootURI: ROOT, hmacAuthStrategy: strategy });
479
+ (0, nock_1.default)(ROOT)
480
+ .post('/api/v2/user/login')
481
+ .reply(200, {
482
+ user: { username: 'test@example.com' },
483
+ access_token: 'v2xmytoken',
484
+ });
485
+ // The GET /user/settings request made by ensureUserEcdhKeychainIsCreated
486
+ // must succeed — it would throw if setToken wasn't awaited first.
487
+ (0, nock_1.default)(ROOT)
488
+ .get('/api/v1/user/settings')
489
+ .reply(200, {
490
+ settings: { ecdhKeychain: 'xpub123' },
491
+ });
492
+ await bitgo.authenticate({
493
+ username: 'test@example.com',
494
+ password: 'hunter2',
495
+ ensureEcdhKeychain: true,
496
+ });
497
+ keyReady.should.be.true();
498
+ });
499
+ it('handles an ECDH-encrypted token response (no access_token) through the v2 login flow', async function () {
500
+ const { strategy, setTokenStub } = makeStrategy();
501
+ const bitgo = new bitgoAPI_1.BitGoAPI({ env: 'custom', customRootURI: ROOT, hmacAuthStrategy: strategy });
502
+ // Stub token issuance so the test does not depend on real crypto. The point is
503
+ // to assert the v2 login response with encryptedToken reaches handleTokenIssuance
504
+ // and that the decrypted token is then synced to the strategy.
505
+ const handleTokenIssuanceStub = sinon
506
+ .stub(bitgo, 'handleTokenIssuance')
507
+ .resolves({ token: 'v2xdecryptedtoken' });
508
+ (0, nock_1.default)(ROOT)
509
+ .post('/api/v2/user/login')
510
+ .reply(200, {
511
+ user: { username: 'test@example.com' },
512
+ encryptedToken: 'encrypted-token-value',
513
+ encryptedECDHXprv: 'encrypted-ecdh-xprv',
514
+ derivationPath: 'm/999999/0/1',
515
+ });
516
+ await bitgo.authenticate({ username: 'test@example.com', password: 'hunter2' });
517
+ // The SDK must have taken the ECDH path (not the plain access_token path).
518
+ handleTokenIssuanceStub.calledOnce.should.be.true();
519
+ handleTokenIssuanceStub.firstCall.args[0].encryptedToken.should.equal('encrypted-token-value');
520
+ // The decrypted token must be synced to the strategy.
521
+ setTokenStub.calledOnce.should.be.true();
522
+ setTokenStub.firstCall.args[0].should.equal('v2xdecryptedtoken');
523
+ });
524
+ });
525
+ describe('authenticateWithPasskey()', function () {
526
+ const validPasskey = JSON.stringify({
527
+ id: 'credential-id',
528
+ rawId: 'raw-id',
529
+ type: 'public-key',
530
+ response: {
531
+ authenticatorData: 'auth-data',
532
+ clientDataJSON: 'client-data',
533
+ signature: 'sig',
534
+ userHandle: 'user-handle-123',
535
+ },
536
+ });
537
+ it('calls setToken with the access_token received from the server', async function () {
538
+ const { strategy, setTokenStub } = makeStrategy();
539
+ const bitgo = new bitgoAPI_1.BitGoAPI({ env: 'custom', customRootURI: ROOT, hmacAuthStrategy: strategy });
540
+ (0, nock_1.default)(ROOT)
541
+ .post('/api/auth/v1/session')
542
+ .reply(200, {
543
+ user: { username: 'test@example.com' },
544
+ access_token: 'v2xpasskeytoken',
545
+ });
546
+ await bitgo.authenticateWithPasskey(validPasskey);
547
+ setTokenStub.calledOnce.should.be.true();
548
+ setTokenStub.firstCall.args[0].should.equal('v2xpasskeytoken');
549
+ });
550
+ });
551
+ describe('clearAsync()', function () {
552
+ it('clears _token and calls clearToken on the strategy', async function () {
553
+ const { strategy, clearTokenStub } = makeStrategy();
554
+ const bitgo = new bitgoAPI_1.BitGoAPI({ env: 'custom', customRootURI: ROOT, hmacAuthStrategy: strategy });
555
+ await bitgo.authenticateWithAccessToken({ accessToken: 'v2xsometoken' });
556
+ bitgo._token.should.equal('v2xsometoken');
557
+ await bitgo.clearAsync();
558
+ (bitgo._token === undefined).should.be.true();
559
+ clearTokenStub.calledOnce.should.be.true();
560
+ });
561
+ });
562
+ describe('refreshToken()', function () {
563
+ it('calls setToken with the new access_token from the OAuth response', async function () {
564
+ const { strategy, setTokenStub } = makeStrategy();
565
+ const bitgo = new bitgoAPI_1.BitGoAPI({
566
+ env: 'custom',
567
+ customRootURI: ROOT,
568
+ hmacAuthStrategy: strategy,
569
+ clientId: 'client-id',
570
+ clientSecret: 'client-secret',
571
+ });
572
+ bitgo._refreshToken = 'old-refresh-token';
573
+ (0, nock_1.default)(ROOT).post('/oauth/token').reply(200, {
574
+ access_token: 'v2xnewtoken',
575
+ refresh_token: 'new-refresh-token',
576
+ });
577
+ await bitgo.refreshToken();
578
+ setTokenStub.calledOnce.should.be.true();
579
+ setTokenStub.firstCall.args[0].should.equal('v2xnewtoken');
580
+ });
581
+ });
582
+ describe('authenticateWithAuthCode()', function () {
583
+ it('calls setToken with the access_token from the OAuth response', async function () {
584
+ const { strategy, setTokenStub } = makeStrategy();
585
+ const bitgo = new bitgoAPI_1.BitGoAPI({
586
+ env: 'custom',
587
+ customRootURI: ROOT,
588
+ hmacAuthStrategy: strategy,
589
+ clientId: 'client-id',
590
+ clientSecret: 'client-secret',
591
+ });
592
+ (0, nock_1.default)(ROOT).post('/oauth/token').reply(200, {
593
+ access_token: 'v2xauthcodetoken',
594
+ refresh_token: 'refresh-token',
595
+ });
596
+ // authenticateWithAuthCode calls this.me() after setting the token
597
+ (0, nock_1.default)(ROOT)
598
+ .get('/api/v1/user/me')
599
+ .reply(200, {
600
+ user: { username: 'test@example.com' },
601
+ });
602
+ await bitgo.authenticateWithAuthCode({ authCode: 'my-auth-code' });
603
+ setTokenStub.calledOnce.should.be.true();
604
+ setTokenStub.firstCall.args[0].should.equal('v2xauthcodetoken');
605
+ });
606
+ });
607
+ describe('sync token-setting methods', function () {
608
+ it('authenticateWithAccessToken calls setToken (HMAC strategy must be kept in sync for v2/v3 signing)', async function () {
609
+ const { strategy, setTokenStub } = makeStrategy();
610
+ const bitgo = new bitgoAPI_1.BitGoAPI({ env: 'custom', customRootURI: ROOT, hmacAuthStrategy: strategy });
611
+ await bitgo.authenticateWithAccessToken({ accessToken: 'v2xsynctoken' });
612
+ setTokenStub.calledOnce.should.be.true();
613
+ setTokenStub.firstCall.args[0].should.equal('v2xsynctoken');
614
+ });
615
+ it('fromJSON does not call setToken (synchronous — caller must invoke setToken on the strategy manually)', function () {
616
+ const { strategy, setTokenStub } = makeStrategy();
617
+ const bitgo = new bitgoAPI_1.BitGoAPI({ env: 'custom', customRootURI: ROOT, hmacAuthStrategy: strategy });
618
+ bitgo.fromJSON({ user: { username: 'test@example.com' }, token: 'v2xjsontoken' });
619
+ setTokenStub.called.should.be.false();
620
+ });
621
+ });
622
+ describe('addAccessToken()', function () {
623
+ const validParams = {
624
+ label: 'test-token',
625
+ scope: ['wallet_view_all'],
626
+ duration: 3600,
627
+ };
628
+ it('should force V1 auth and return plain token when ecdhXprv is absent, even if hmacAuthStrategy is authenticated (SSO/enterprise users)', async function () {
629
+ // Regression test for WCN-1790 / ANT-963: HMAC request signing and ECDH response
630
+ // encryption are orthogonal. forceV1Auth tells the server to return a plaintext token
631
+ // instead of ECDH-encrypting it. It must be set whenever ecdhXprv is absent,
632
+ // regardless of whether the HMAC strategy is active.
633
+ const { strategy } = makeStrategy({
634
+ isAuthenticated: sinon.stub().returns(true),
635
+ });
636
+ const bitgo = new bitgoAPI_1.BitGoAPI({ env: 'custom', customRootURI: ROOT, hmacAuthStrategy: strategy });
637
+ // Do NOT set _ecdhXprv — simulates SSO/enterprise session (Okta, Entra, etc.)
638
+ await bitgo.authenticateWithAccessToken({ accessToken: 'v2xstrategytoken' });
639
+ const scope = (0, nock_1.default)(ROOT).post('/api/auth/v1/accesstoken').reply(200, {
640
+ token: 'v2xnewplaintoken',
641
+ label: 'test-token',
642
+ });
643
+ const result = await bitgo.addAccessToken(validParams);
644
+ scope.isDone().should.be.true();
645
+ // forceV1Auth MUST be set — server returns plaintext token since we have no decryption key
646
+ result.warning.should.match(/protocol downgrade/);
647
+ result.token.should.equal('v2xnewplaintoken');
648
+ });
649
+ it('should not call handleTokenIssuance when ecdhXprv is present but the server returned a plaintext token', async function () {
650
+ const handleTokenSpy = sinon.spy(bitgoAPI_1.BitGoAPI.prototype, 'handleTokenIssuance');
651
+ const { strategy } = makeStrategy({
652
+ isAuthenticated: sinon.stub().returns(true),
653
+ });
654
+ const bitgo = new bitgoAPI_1.BitGoAPI({ env: 'custom', customRootURI: ROOT, hmacAuthStrategy: strategy });
655
+ bitgo.fromJSON({
656
+ user: { username: 'test@example.com' },
657
+ token: 'a'.repeat(40),
658
+ ecdhXprv: 'xprv-test-key',
659
+ });
660
+ (0, nock_1.default)(ROOT).post('/api/auth/v1/accesstoken').reply(200, {
661
+ token: 'v2xplaintextfromv1',
662
+ label: 'test-token',
663
+ });
664
+ try {
665
+ const result = await bitgo.addAccessToken(validParams);
666
+ handleTokenSpy.called.should.be.false();
667
+ result.token.should.equal('v2xplaintextfromv1');
668
+ }
669
+ finally {
670
+ handleTokenSpy.restore();
671
+ }
672
+ });
673
+ it('should not call handleTokenIssuance when ecdhXprv is absent', async function () {
674
+ const handleTokenSpy = sinon.spy(bitgoAPI_1.BitGoAPI.prototype, 'handleTokenIssuance');
675
+ const { strategy } = makeStrategy({
676
+ isAuthenticated: sinon.stub().returns(true),
677
+ });
678
+ const bitgo = new bitgoAPI_1.BitGoAPI({ env: 'custom', customRootURI: ROOT, hmacAuthStrategy: strategy });
679
+ await bitgo.authenticateWithAccessToken({ accessToken: 'v2xstrategytoken' });
680
+ (0, nock_1.default)(ROOT).post('/api/auth/v1/accesstoken').reply(200, {
681
+ token: 'v2xplaintoken',
682
+ label: 'test-token',
683
+ });
684
+ const result = await bitgo.addAccessToken(validParams);
685
+ // handleTokenIssuance must not be called — no ecdhXprv to decrypt with
686
+ handleTokenSpy.called.should.be.false();
687
+ result.token.should.equal('v2xplaintoken');
688
+ handleTokenSpy.restore();
689
+ });
690
+ it('should force V1 auth when ecdhXprv is absent and strategy is not authenticated', async function () {
691
+ const { strategy } = makeStrategy({
692
+ isAuthenticated: sinon.stub().returns(false),
693
+ });
694
+ const bitgo = new bitgoAPI_1.BitGoAPI({ env: 'custom', customRootURI: ROOT, hmacAuthStrategy: strategy });
695
+ await bitgo.authenticateWithAccessToken({ accessToken: 'v2xlegacytoken' });
696
+ (0, nock_1.default)(ROOT).post('/api/auth/v1/accesstoken').reply(200, {
697
+ token: 'v2xlegacyresult',
698
+ label: 'test-token',
699
+ });
700
+ const result = await bitgo.addAccessToken(validParams);
701
+ result.warning.should.match(/protocol downgrade/);
702
+ });
703
+ it('should force V1 auth when isAuthenticated is not defined on strategy', async function () {
704
+ const { strategy } = makeStrategy();
705
+ const bitgo = new bitgoAPI_1.BitGoAPI({ env: 'custom', customRootURI: ROOT, hmacAuthStrategy: strategy });
706
+ await bitgo.authenticateWithAccessToken({ accessToken: 'v2xnoauthmethod' });
707
+ (0, nock_1.default)(ROOT).post('/api/auth/v1/accesstoken').reply(200, {
708
+ token: 'v2xresult',
709
+ label: 'test-token',
710
+ });
711
+ const result = await bitgo.addAccessToken(validParams);
712
+ // Without isAuthenticated, should fall back to V1 auth
713
+ result.warning.should.match(/protocol downgrade/);
714
+ });
715
+ });
716
+ });
717
+ describe('constants parameter', function () {
718
+ it('should allow passing constants via options and expose via fetchConstants', async function () {
719
+ const bitgo = new bitgoAPI_1.BitGoAPI({
720
+ env: 'custom',
721
+ customRootURI: 'https://app.example.local',
722
+ clientConstants: { maxFeeRate: '123123123123123' },
723
+ });
724
+ const constants = await bitgo.fetchConstants();
725
+ constants.should.have.property('maxFeeRate', '123123123123123');
726
+ });
727
+ it('should refresh constants when cache has expired', async function () {
728
+ const bitgo = new bitgoAPI_1.BitGoAPI({
729
+ env: 'custom',
730
+ customRootURI: 'https://app.example.local',
731
+ });
732
+ // Set up cached constants with an expired cache
733
+ bitgoAPI_1.BitGoAPI._constants = bitgoAPI_1.BitGoAPI._constants || {};
734
+ bitgoAPI_1.BitGoAPI._constantsExpire = bitgoAPI_1.BitGoAPI._constantsExpire || {};
735
+ bitgoAPI_1.BitGoAPI._constants['custom'] = { maxFeeRate: 'old-value' };
736
+ bitgoAPI_1.BitGoAPI._constantsExpire['custom'] = new Date(Date.now() - 1000); // Expired 1 second ago
737
+ const scope = (0, nock_1.default)('https://app.example.local')
738
+ .get('/api/v1/client/constants')
739
+ .reply(200, {
740
+ constants: { maxFeeRate: 'new-value', newConstant: 'added' },
741
+ });
742
+ const constants = await bitgo.fetchConstants();
743
+ // Should return the new constants from the server
744
+ constants.should.have.property('maxFeeRate', 'new-value');
745
+ constants.should.have.property('newConstant', 'added');
746
+ scope.isDone().should.be.true();
747
+ nock_1.default.cleanAll();
748
+ });
749
+ it('should use cached constants when cache is still valid', async function () {
750
+ const bitgo = new bitgoAPI_1.BitGoAPI({
751
+ env: 'custom',
752
+ customRootURI: 'https://app.example.local',
753
+ });
754
+ // Set up cached constants with a future expiry
755
+ const cachedConstants = { maxFeeRate: 'cached-value', anotherSetting: 'cached-setting' };
756
+ bitgoAPI_1.BitGoAPI._constants = bitgoAPI_1.BitGoAPI._constants || {};
757
+ bitgoAPI_1.BitGoAPI._constantsExpire = bitgoAPI_1.BitGoAPI._constantsExpire || {};
758
+ bitgoAPI_1.BitGoAPI._constants['custom'] = cachedConstants;
759
+ bitgoAPI_1.BitGoAPI._constantsExpire['custom'] = new Date(Date.now() + 5 * 60 * 1000); // Valid for 5 more minutes
760
+ const scope = (0, nock_1.default)('https://app.example.local')
761
+ .get('/api/v1/client/constants')
762
+ .reply(200, { constants: { shouldNotBeUsed: true } });
763
+ const constants = await bitgo.fetchConstants();
764
+ // Should return the cached constants
765
+ constants.should.deepEqual(cachedConstants);
766
+ // Verify that no HTTP request was made (since cache was valid)
767
+ scope.isDone().should.be.false();
768
+ nock_1.default.cleanAll();
769
+ });
770
+ it('should use cached constants when no cache expiry is set', async function () {
771
+ const bitgo = new bitgoAPI_1.BitGoAPI({
772
+ env: 'custom',
773
+ customRootURI: 'https://app.example.local',
774
+ });
775
+ // Set up cached constants with no expiry
776
+ const cachedConstants = { maxFeeRate: 'no-expiry-value' };
777
+ bitgoAPI_1.BitGoAPI._constants = bitgoAPI_1.BitGoAPI._constants || {};
778
+ bitgoAPI_1.BitGoAPI._constantsExpire = bitgoAPI_1.BitGoAPI._constantsExpire || {};
779
+ bitgoAPI_1.BitGoAPI._constants['custom'] = cachedConstants;
780
+ bitgoAPI_1.BitGoAPI._constantsExpire['custom'] = undefined;
781
+ const scope = (0, nock_1.default)('https://app.example.local')
782
+ .get('/api/v1/client/constants')
783
+ .reply(200, { constants: { shouldNotBeUsed: true } });
784
+ const constants = await bitgo.fetchConstants();
785
+ // Should return the cached constants
786
+ constants.should.deepEqual(cachedConstants);
787
+ // Verify that no HTTP request was made (since no expiry means cache is always valid)
788
+ scope.isDone().should.be.false();
789
+ nock_1.default.cleanAll();
790
+ });
791
+ });
792
+ describe('packKeychainsFFD', function () {
793
+ let bitgo;
794
+ before(function () {
795
+ bitgo = new bitgoAPI_1.BitGoAPI({ env: 'custom', customRootURI: 'https://app.example.local' });
796
+ });
797
+ function ffd(keychains, v2Keychains, maxBatchSizeBytes) {
798
+ return bitgo.packKeychainsFFD(keychains, v2Keychains, maxBatchSizeBytes);
799
+ }
800
+ it('returns an empty array when both inputs are empty', function () {
801
+ const bins = ffd({}, {}, 1024);
802
+ bins.should.be.an.Array();
803
+ bins.should.have.length(0);
804
+ });
805
+ it('packs all items into a single bin when they fit within the limit', function () {
806
+ // Each entry: 2-byte id + 10-byte value = 12 bytes; 5 entries = 60 bytes < 200 limit
807
+ const keychains = { k1: 'aaaaaaaaaa', k2: 'bbbbbbbbbb', k3: 'cccccccccc' };
808
+ const v2Keychains = { v1: 'dddddddddd', v2: 'eeeeeeeeee' };
809
+ const bins = ffd(keychains, v2Keychains, 200);
810
+ bins.should.have.length(1);
811
+ Object.keys(bins[0].v1Batch).should.have.length(3);
812
+ Object.keys(bins[0].v2Batch).should.have.length(2);
813
+ });
814
+ it('splits into multiple bins when a single bin cannot fit all items', function () {
815
+ // id='k1' (2 bytes) + 600-char value = 602 bytes; 2 entries exceed 700-byte limit
816
+ const keychains = { k1: 'x'.repeat(600), k2: 'y'.repeat(600) };
817
+ const bins = ffd(keychains, {}, 700);
818
+ bins.should.have.length(2);
819
+ });
820
+ it('throws when a single item exceeds maxBatchSizeBytes', function () {
821
+ // id='k1' (2 bytes) + 200-char value = 202 bytes > 100-byte limit
822
+ const keychains = { k1: 'x'.repeat(200) };
823
+ try {
824
+ ffd(keychains, {}, 100);
825
+ throw new Error('Expected error not thrown');
826
+ }
827
+ catch (e) {
828
+ e.message.should.match(/exceeds the maximum batch size/);
829
+ }
830
+ });
831
+ it('places V1 keychains in v1Batch and V2 keychains in v2Batch', function () {
832
+ const keychains = { k1: 'v1value' };
833
+ const v2Keychains = { k2: 'v2value' };
834
+ const bins = ffd(keychains, v2Keychains, 10000);
835
+ bins.should.have.length(1);
836
+ bins[0].v1Batch.should.have.property('k1', 'v1value');
837
+ bins[0].v2Batch.should.have.property('k2', 'v2value');
838
+ bins[0].v1Batch.should.not.have.property('k2');
839
+ bins[0].v2Batch.should.not.have.property('k1');
840
+ });
841
+ it('uses FFD ordering so the largest item is packed first', function () {
842
+ // 'big': id(3) + 497 bytes = 500 bytes; 's1','s2': id(2) + 98 bytes = 100 bytes each
843
+ // maxBatchSizeBytes = 600
844
+ // FFD order (descending): big(500), s1(100), s2(100)
845
+ // bin0: big(500). s1: 500+100=600 <=600, fits. s2: 600+100=700 > 600, new bin1.
846
+ // Result: bin0={big,s1}, bin1={s2}
847
+ const keychains = { big: 'x'.repeat(497), s1: 'y'.repeat(98), s2: 'z'.repeat(98) };
848
+ const bins = ffd(keychains, {}, 600);
849
+ bins.should.have.length(2);
850
+ // 'big' should share its bin with one small item (FFD packs the largest first)
851
+ const binWithBig = bins.find((b) => 'big' in b.v1Batch);
852
+ Object.keys(binWithBig.v1Batch).should.have.length(2);
853
+ });
854
+ });
855
+ describe('processKeychainPasswordUpdatesInBatches', function () {
856
+ const ROOT = 'https://app.example.local';
857
+ let bitgo;
858
+ beforeEach(function () {
859
+ const strategy = {
860
+ calculateRequestHeaders: sinon.stub().resolves({ hmac: 'hmac', timestamp: Date.now(), tokenHash: 'hash' }),
861
+ verifyResponse: sinon.stub().resolves({
862
+ isValid: true,
863
+ expectedHmac: 'hmac',
864
+ signatureSubject: '',
865
+ isInResponseValidityWindow: true,
866
+ verificationTime: Date.now(),
867
+ }),
868
+ calculateHMAC: sinon.stub().resolves('hashed-pw'),
869
+ setToken: sinon.stub().resolves(),
870
+ clearToken: sinon.stub().resolves(),
871
+ };
872
+ bitgo = new bitgoAPI_1.BitGoAPI({ env: 'custom', customRootURI: ROOT, hmacAuthStrategy: strategy });
873
+ });
874
+ afterEach(function () {
875
+ nock_1.default.cleanAll();
876
+ sinon.restore();
877
+ });
878
+ async function runBatches(keychains, v2Keychains, maxBatchSizeKB, maxRetries = 3) {
879
+ return bitgo.processKeychainPasswordUpdatesInBatches(keychains, v2Keychains, maxBatchSizeKB, maxRetries);
880
+ }
881
+ it('makes a single PUT request for a small payload', async function () {
882
+ const scope = (0, nock_1.default)(ROOT).put('/api/v2/user/keychains').reply(200, {});
883
+ await runBatches({ k1: 'small' }, {}, 1024);
884
+ scope.isDone().should.be.true();
885
+ });
886
+ it('makes two PUT requests when the payload spans two bins', async function () {
887
+ // id='k1'(2) + 600 = 602 bytes each; 2 entries exceed 1 KB limit => 2 bins
888
+ const keychains = { k1: 'x'.repeat(600), k2: 'y'.repeat(600) };
889
+ const scope = (0, nock_1.default)(ROOT).put('/api/v2/user/keychains').twice().reply(200, {});
890
+ await runBatches(keychains, {}, 1);
891
+ scope.isDone().should.be.true();
892
+ });
893
+ it('retries a failed batch and succeeds on the second attempt', async function () {
894
+ (0, nock_1.default)(ROOT).put('/api/v2/user/keychains').reply(500, { error: 'internal error' });
895
+ (0, nock_1.default)(ROOT).put('/api/v2/user/keychains').reply(200, {});
896
+ // Should not throw
897
+ await runBatches({ k1: 'value' }, {}, 1024, 3);
898
+ });
899
+ it('throws after exhausting all retries on persistent HTTP errors', async function () {
900
+ (0, nock_1.default)(ROOT).put('/api/v2/user/keychains').times(3).reply(500, { error: 'internal error' });
901
+ let thrownError;
902
+ try {
903
+ await runBatches({ k1: 'value' }, {}, 1024, 3);
904
+ }
905
+ catch (e) {
906
+ thrownError = e;
907
+ }
908
+ thrownError.message.should.match(/failed after 3 retries/);
909
+ });
910
+ it('throws after exhausting all retries when the server reports failed keychains', async function () {
911
+ (0, nock_1.default)(ROOT)
912
+ .put('/api/v2/user/keychains')
913
+ .times(3)
914
+ .reply(200, { failed: { v1: { k1: 'encryption error' } } });
915
+ let thrownError;
916
+ try {
917
+ await runBatches({ k1: 'value' }, {}, 1024, 3);
918
+ }
919
+ catch (e) {
920
+ thrownError = e;
921
+ }
922
+ thrownError.message.should.match(/had failed keychains/);
923
+ });
924
+ });
925
+ describe('changePassword batching flow', function () {
926
+ const ROOT = 'https://app.example.local';
927
+ let bitgo;
928
+ let sandbox;
929
+ let v1UpdatePasswordStub;
930
+ let v2UpdatePasswordStub;
931
+ beforeEach(function () {
932
+ sandbox = sinon.createSandbox();
933
+ const strategy = {
934
+ calculateRequestHeaders: sandbox.stub().resolves({ hmac: 'hmac', timestamp: Date.now(), tokenHash: 'hash' }),
935
+ verifyResponse: sandbox.stub().resolves({
936
+ isValid: true,
937
+ expectedHmac: 'hmac',
938
+ signatureSubject: '',
939
+ isInResponseValidityWindow: true,
940
+ verificationTime: Date.now(),
941
+ }),
942
+ calculateHMAC: sandbox.stub().resolves('hashed-pw'),
943
+ setToken: sandbox.stub().resolves(),
944
+ clearToken: sandbox.stub().resolves(),
945
+ };
946
+ bitgo = new bitgoAPI_1.BitGoAPI({ env: 'custom', customRootURI: ROOT, hmacAuthStrategy: strategy });
947
+ bitgo._user = { username: 'test@bitgo.com' };
948
+ sandbox.stub(bitgo, 'verifyPassword').resolves(true);
949
+ v1UpdatePasswordStub = sandbox.stub().resolves({ keychains: { k1: 'v1enc' }, version: 25 });
950
+ sandbox.stub(bitgo, 'keychains').returns({
951
+ updatePassword: v1UpdatePasswordStub,
952
+ });
953
+ v2UpdatePasswordStub = sandbox.stub().resolves({ v2k1: 'v2enc' });
954
+ sandbox.stub(bitgo, 'coin').returns({
955
+ keychains: () => ({
956
+ updatePassword: v2UpdatePasswordStub,
957
+ }),
958
+ });
959
+ });
960
+ afterEach(function () {
961
+ nock_1.default.cleanAll();
962
+ sandbox.restore();
963
+ });
964
+ it('calls PUT /user/keychains and POST /user/changepassword without keychains when batching is enabled', async function () {
965
+ (0, nock_1.default)(ROOT)
966
+ .get('/api/v2/user/checkBatchingPasswordFlow')
967
+ .query(true)
968
+ .reply(200, { isBatchingFlowEnabled: true, maxBatchSizeKB: 900 });
969
+ const batchPutScope = (0, nock_1.default)(ROOT).put('/api/v2/user/keychains').reply(200, {});
970
+ const changePassScope = (0, nock_1.default)(ROOT)
971
+ .post('/api/v1/user/changepassword', (body) => !body.keychains && !body.v2_keychains)
972
+ .reply(200, {});
973
+ await bitgo.changePassword({ oldPassword: 'oldpw', newPassword: 'newpw' });
974
+ batchPutScope.isDone().should.be.true();
975
+ changePassScope.isDone().should.be.true();
976
+ });
977
+ it('sends keychains in the POST body (legacy flow) when the server disables batching', async function () {
978
+ (0, nock_1.default)(ROOT).get('/api/v2/user/checkBatchingPasswordFlow').query(true).reply(200, { isBatchingFlowEnabled: false });
979
+ const legacyScope = (0, nock_1.default)(ROOT)
980
+ .post('/api/v1/user/changepassword', (body) => !!body.keychains && !!body.v2_keychains)
981
+ .reply(200, {});
982
+ await bitgo.changePassword({ oldPassword: 'oldpw', newPassword: 'newpw' });
983
+ legacyScope.isDone().should.be.true();
984
+ });
985
+ it('falls back to legacy flow when the batching check request fails', async function () {
986
+ (0, nock_1.default)(ROOT).get('/api/v2/user/checkBatchingPasswordFlow').query(true).reply(503, { error: 'service unavailable' });
987
+ const legacyScope = (0, nock_1.default)(ROOT)
988
+ .post('/api/v1/user/changepassword', (body) => !!body.keychains && !!body.v2_keychains)
989
+ .reply(200, {});
990
+ await bitgo.changePassword({ oldPassword: 'oldpw', newPassword: 'newpw' });
991
+ legacyScope.isDone().should.be.true();
992
+ });
993
+ it('forwards encryptionVersion to both v1 and v2 keychains().updatePassword calls', async function () {
994
+ (0, nock_1.default)(ROOT).get('/api/v2/user/checkBatchingPasswordFlow').query(true).reply(200, { isBatchingFlowEnabled: false });
995
+ (0, nock_1.default)(ROOT)
996
+ .post('/api/v1/user/changepassword', (body) => !!body.keychains && !!body.v2_keychains)
997
+ .reply(200, {});
998
+ await bitgo.changePassword({ oldPassword: 'oldpw', newPassword: 'newpw', encryptionVersion: 2 });
999
+ sinon.assert.calledWithMatch(v1UpdatePasswordStub, { encryptionVersion: 2 });
1000
+ sinon.assert.calledWithMatch(v2UpdatePasswordStub, { encryptionVersion: 2 });
1001
+ });
1002
+ it('shares one encryption session across keychain password updates', async function () {
1003
+ (0, nock_1.default)(ROOT).get('/api/v2/user/checkBatchingPasswordFlow').query(true).reply(200, { isBatchingFlowEnabled: false });
1004
+ (0, nock_1.default)(ROOT)
1005
+ .post('/api/v1/user/changepassword', (body) => {
1006
+ if (!body || typeof body !== 'object') {
1007
+ return false;
1008
+ }
1009
+ return 'keychains' in body && 'v2_keychains' in body;
1010
+ })
1011
+ .reply(200, {});
1012
+ const destroy = sandbox.stub();
1013
+ const session = {
1014
+ encrypt: sandbox.stub().resolves('session-encrypted'),
1015
+ decrypt: sandbox.stub().resolves('session-decrypted'),
1016
+ destroy,
1017
+ };
1018
+ const createSession = sandbox.stub(bitgo, 'createEncryptionSession').resolves(session);
1019
+ await bitgo.changePassword({ oldPassword: 'oldpw', newPassword: 'newpw', encryptionVersion: 2 });
1020
+ sinon.assert.calledOnce(createSession);
1021
+ sinon.assert.calledWithExactly(createSession, 'newpw', 2);
1022
+ sinon.assert.calledWithMatch(v1UpdatePasswordStub, {
1023
+ encryptionVersion: 2,
1024
+ encryptionSession: session,
1025
+ });
1026
+ sinon.assert.calledWithMatch(v2UpdatePasswordStub, {
1027
+ encryptionVersion: 2,
1028
+ encryptionSession: session,
1029
+ });
1030
+ sinon.assert.calledOnce(destroy);
1031
+ });
1032
+ });
1033
+ describe('createUserEcdhKeychain - encryptionVersion threading', function () {
1034
+ const ROOT = 'https://app.bitgo-test.com';
1035
+ let bitgo;
1036
+ beforeEach(function () {
1037
+ bitgo = new bitgoAPI_1.BitGoAPI({ env: 'test' });
1038
+ });
1039
+ afterEach(function () {
1040
+ nock_1.default.cleanAll();
1041
+ sinon.restore();
1042
+ });
1043
+ it('passes encryptionVersion: 2 to encrypt', async function () {
1044
+ const encryptAsyncSpy = sinon.spy(bitgo, 'encrypt');
1045
+ (0, nock_1.default)(ROOT).post('/api/v1/keychain').reply(200, { xpub: 'xpub123', id: 'key-id' });
1046
+ await bitgo.createUserEcdhKeychain('loginPassword', 2);
1047
+ assert.ok(encryptAsyncSpy.calledOnce);
1048
+ assert.strictEqual(encryptAsyncSpy.firstCall.args[0].encryptionVersion, 2);
1049
+ });
1050
+ it('passes encryptionVersion: undefined when not set (defaults to v1)', async function () {
1051
+ const encryptAsyncSpy = sinon.spy(bitgo, 'encrypt');
1052
+ (0, nock_1.default)(ROOT).post('/api/v1/keychain').reply(200, { xpub: 'xpub123', id: 'key-id' });
1053
+ await bitgo.createUserEcdhKeychain('loginPassword');
1054
+ assert.ok(encryptAsyncSpy.calledOnce);
1055
+ assert.strictEqual(encryptAsyncSpy.firstCall.args[0].encryptionVersion, undefined);
1056
+ });
1057
+ });
1058
+ describe('splitSecret - encryptionVersion threading', function () {
1059
+ let bitgo;
1060
+ beforeEach(function () {
1061
+ bitgo = new bitgoAPI_1.BitGoAPI({ env: 'test' });
1062
+ });
1063
+ afterEach(function () {
1064
+ sinon.restore();
1065
+ });
1066
+ it('passes encryptionVersion: 2 to every encrypt shard call', async function () {
1067
+ const encryptAsyncSpy = sinon.spy(bitgo, 'encrypt');
1068
+ const passwords = ['pw1', 'pw2', 'pw3'];
1069
+ await bitgo.splitSecret({
1070
+ seed: 'a'.repeat(64),
1071
+ passwords,
1072
+ m: 2,
1073
+ encryptionVersion: 2,
1074
+ });
1075
+ assert.strictEqual(encryptAsyncSpy.callCount, 3, 'should encrypt each shard');
1076
+ for (const call of encryptAsyncSpy.getCalls()) {
1077
+ assert.strictEqual(call.args[0].encryptionVersion, 2);
1078
+ }
1079
+ });
1080
+ it('passes encryptionVersion: undefined when not set', async function () {
1081
+ const encryptAsyncSpy = sinon.spy(bitgo, 'encrypt');
1082
+ await bitgo.splitSecret({
1083
+ seed: 'b'.repeat(64),
1084
+ passwords: ['pw1', 'pw2'],
1085
+ m: 2,
1086
+ });
1087
+ assert.strictEqual(encryptAsyncSpy.callCount, 2);
1088
+ for (const call of encryptAsyncSpy.getCalls()) {
1089
+ assert.strictEqual(call.args[0].encryptionVersion, undefined);
1090
+ }
1091
+ });
1092
+ });
1093
+ });
1094
+ describe('wallets() v1 facade', function () {
1095
+ it('returns BitGoApiV1Wallets with bitgo reference and all prototype methods', function () {
1096
+ const bitgo = new bitgoAPI_1.BitGoAPI({ env: 'test' });
1097
+ const wallets = bitgo.wallets();
1098
+ wallets.bitgo.should.equal(bitgo);
1099
+ wallets.list.should.be.a.Function();
1100
+ wallets.get.should.be.a.Function();
1101
+ wallets.getWallet.should.be.a.Function();
1102
+ wallets.add.should.be.a.Function();
1103
+ wallets.remove.should.be.a.Function();
1104
+ wallets.acceptShare.should.be.a.Function();
1105
+ wallets.createWalletWithKeychains.should.be.a.Function();
1106
+ wallets.createForwardWallet.should.be.a.Function();
1107
+ wallets.createKey.should.be.a.Function();
1108
+ wallets.listInvites.should.be.a.Function();
1109
+ wallets.cancelInvite.should.be.a.Function();
1110
+ wallets.listShares.should.be.a.Function();
1111
+ wallets.getShare.should.be.a.Function();
1112
+ wallets.updateShare.should.be.a.Function();
1113
+ wallets.cancelShare.should.be.a.Function();
1114
+ wallets.resendShareInvite.should.be.a.Function();
1115
+ });
1116
+ });
1117
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYml0Z29BUEkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQvYml0Z29BUEkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQ0FBaUM7QUFDakMsa0JBQWdCO0FBQ2hCLGlEQUE4QztBQUM5Qyw2Q0FBeUM7QUFDekMsNkNBQStCO0FBQy9CLGdEQUF3QjtBQUl4QixRQUFRLENBQUMsYUFBYSxFQUFFO0lBQ3RCLFFBQVEsQ0FBQyxvQ0FBb0MsRUFBRTtRQUM3QyxFQUFFLENBQUMsaURBQWlELEVBQUU7WUFDcEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxtQkFBUSxDQUFDO2dCQUN6QixHQUFHLEVBQUUsUUFBUTtnQkFDYixhQUFhLEVBQUUsMkJBQTJCO2dCQUMxQyx5QkFBeUIsRUFBRSxJQUFJO2FBQ2hDLENBQUMsQ0FBQztZQUVILEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO1lBQ3hELEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3JELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGtEQUFrRCxFQUFFO1lBQ3JELE1BQU0sS0FBSyxHQUFHLElBQUksbUJBQVEsQ0FBQztnQkFDekIsR0FBRyxFQUFFLFFBQVE7Z0JBQ2IsYUFBYSxFQUFFLDJCQUEyQjtnQkFDMUMseUJBQXlCLEVBQUUsS0FBSzthQUNqQyxDQUFDLENBQUM7WUFFSCxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsMkJBQTJCLENBQUMsQ0FBQztZQUN4RCxLQUFLLENBQUMseUJBQXlCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN0RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxrREFBa0Qs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QyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ25ELE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDekMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMzQyxPQUFPLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzVDLE9BQU8sQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDMUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUN4QyxPQUFPLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzNDLE9BQU8sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDM0MsT0FBTyxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ25ELENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCAnc2hvdWxkJztcbmltcG9ydCB7IEJpdEdvQVBJIH0gZnJvbSAnLi4vLi4vc3JjL2JpdGdvQVBJJztcbmltcG9ydCB7IFByb3h5QWdlbnQgfSBmcm9tICdwcm94eS1hZ2VudCc7XG5pbXBvcnQgKiBhcyBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgbm9jayBmcm9tICdub2NrJztcbmltcG9ydCB0eXBlIHsgSUhtYWNBdXRoU3RyYXRlZ3kgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstaG1hYyc7XG5pbXBvcnQgdHlwZSB7IElFbmNyeXB0aW9uU2Vzc2lvbiB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcblxuZGVzY3JpYmUoJ0NvbnN0cnVjdG9yJywgZnVuY3Rpb24gKCkge1xuICBkZXNjcmliZSgnY29va2llc1Byb3BhZ2F0aW9uRW5hYmxlZCBhcmd1bWVudCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnY29va2llc1Byb3BhZ2F0aW9uRW5hYmxlZCBpcyBlbmFibGVkIGV4cGxpY2l0bHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiaXRnbyA9IG5ldyBCaXRHb0FQSSh7XG4gICAgICAgIGVudjogJ2N1c3RvbScsXG4gICAgICAgIGN1c3RvbVJvb3RVUkk6ICdodHRwczovL2FwcC5leGFtcGxlLmxvY2FsJyxcbiAgICAgICAgY29va2llc1Byb3BhZ2F0aW9uRW5hYmxlZDogdHJ1ZSxcbiAgICAgIH0pO1xuXG4gICAgICBiaXRnby5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29va2llc1Byb3BhZ2F0aW9uRW5hYmxlZCcpO1xuICAgICAgYml0Z28uY29va2llc1Byb3BhZ2F0aW9uRW5hYmxlZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnY29va2llc1Byb3BhZ2F0aW9uRW5hYmxlZCBpcyBkaXNhYmxlZCBleHBsaWNpdGx5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoe1xuICAgICAgICBlbnY6ICdjdXN0b20nLFxuICAgICAgICBjdXN0b21Sb290VVJJOiAnaHR0cHM6Ly9hcHAuZXhhbXBsZS5sb2NhbCcsXG4gICAgICAgIGNvb2tpZXNQcm9wYWdhdGlvbkVuYWJsZWQ6IGZhbHNlLFxuICAgICAgfSk7XG5cbiAgICAgIGJpdGdvLnNob3VsZC5oYXZlLnByb3BlcnR5KCdjb29raWVzUHJvcGFnYXRpb25FbmFibGVkJyk7XG4gICAgICBiaXRnby5jb29raWVzUHJvcGFnYXRpb25FbmFibGVkLnNob3VsZC5lcXVhbChmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnY29va2llc1Byb3BhZ2F0aW9uRW5hYmxlZCBpcyBkaXNhYmxlZCBieSBkZWZhdWx0JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoe1xuICAgICAgICBlbnY6ICdjdXN0b20nLFxuICAgICAgICBjdXN0b21Sb290VVJJOiAnaHR0cHM6Ly9hcHAuZXhhbXBsZS5sb2NhbCcsXG4gICAgICB9KTtcblxuICAgICAgYml0Z28uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Nvb2tpZXNQcm9wYWdhdGlvbkVuYWJsZWQnKTtcbiAgICAgIGJpdGdvLmNvb2tpZXNQcm9wYWdhdGlvbkVuYWJsZWQuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3JlcXVlc3RJZFByZWZpeCBhcmd1bWVudCcsIGZ1bmN0aW9uICgpIHtcbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcmVwZW5kIHJlcXVlc3RJZFByZWZpeCB0byBSZXF1ZXN0LUlEIGhlYWRlciB3aGVuIHNldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJpdGdvID0gbmV3IEJpdEdvQVBJKHtcbiAgICAgICAgZW52OiAnY3VzdG9tJyxcbiAgICAgICAgY3VzdG9tUm9vdFVSSTogJ2h0dHBzOi8vYXBwLmV4YW1wbGUubG9jYWwnLFxuICAgICAgICByZXF1ZXN0SWRQcmVmaXg6ICd0ZXN0LXByZWZpeC0nLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHNjb3BlID0gbm9jaygnaHR0cHM6Ly9hcHAuZXhhbXBsZS5sb2NhbCcpXG4gICAgICAgIC5nZXQoJy9hcGkvdjEvcGluZycpXG4gICAgICAgIC5tYXRjaEhlYWRlcignUmVxdWVzdC1JRCcsIC9edGVzdC1wcmVmaXgtLylcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBzdGF0dXM6ICdvaycgfSk7XG5cbiAgICAgIGF3YWl0IGJpdGdvLnBpbmcoe1xuICAgICAgICByZXFJZDoge1xuICAgICAgICAgIHRvU3RyaW5nOiAoKSA9PiAnMTIzNDUnLFxuICAgICAgICAgIGluYzogKCkgPT4ge1xuICAgICAgICAgICAgLyogbW9jayAqL1xuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgYW55LFxuICAgICAgfSk7XG5cbiAgICAgIHNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBtb2RpZnkgUmVxdWVzdC1JRCBoZWFkZXIgd2hlbiByZXF1ZXN0SWRQcmVmaXggaXMgbm90IHNldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJpdGdvID0gbmV3IEJpdEdvQVBJKHtcbiAgICAgICAgZW52OiAnY3VzdG9tJyxcbiAgICAgICAgY3VzdG9tUm9vdFVSSTogJ2h0dHBzOi8vYXBwLmV4YW1wbGUubG9jYWwnLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHNjb3BlID0gbm9jaygnaHR0cHM6Ly9hcHAuZXhhbXBsZS5sb2NhbCcpXG4gICAgICAgIC5nZXQoJy9hcGkvdjEvcGluZycpXG4gICAgICAgIC5tYXRjaEhlYWRlcignUmVxdWVzdC1JRCcsIC9eMTIzNDUkLylcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBzdGF0dXM6ICdvaycgfSk7XG5cbiAgICAgIGF3YWl0IGJpdGdvLnBpbmcoe1xuICAgICAgICByZXFJZDoge1xuICAgICAgICAgIHRvU3RyaW5nOiAoKSA9PiAnMTIzNDUnLFxuICAgICAgICAgIGluYzogKCkgPT4ge1xuICAgICAgICAgICAgLyogbW9jayAqL1xuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgYW55LFxuICAgICAgfSk7XG5cbiAgICAgIHNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNvcnJlY3RseSBmb3JtYXQgUmVxdWVzdC1JRCB3aXRoIHByZWZpeCBhbmQgbnVtZXJpYyBzZXF1ZW5jZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJpdGdvID0gbmV3IEJpdEdvQVBJKHtcbiAgICAgICAgZW52OiAnY3VzdG9tJyxcbiAgICAgICAgY3VzdG9tUm9vdFVSSTogJ2h0dHBzOi8vYXBwLmV4YW1wbGUubG9jYWwnLFxuICAgICAgICByZXF1ZXN0SWRQcmVmaXg6ICdteWFwcC12MS0nLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHNjb3BlID0gbm9jaygnaHR0cHM6Ly9hcHAuZXhhbXBsZS5sb2NhbCcpXG4gICAgICAgIC5nZXQoJy9hcGkvdjEvcGluZycpXG4gICAgICAgIC5tYXRjaEhlYWRlcignUmVxdWVzdC1JRCcsICdteWFwcC12MS10cmFjZS0xMjMnKVxuICAgICAgICAucmVwbHkoMjAwLCB7IHN0YXR1czogJ29rJyB9KTtcblxuICAgICAgYXdhaXQgYml0Z28ucGluZyh7XG4gICAgICAgIHJlcUlkOiB7XG4gICAgICAgICAgdG9TdHJpbmc6ICgpID0+ICd0cmFjZS0xMjMnLFxuICAgICAgICAgIGluYzogKCkgPT4ge1xuICAgICAgICAgICAgLyogbW9jayAqL1xuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgYW55LFxuICAgICAgfSk7XG5cbiAgICAgIHNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHdvcmsgd2l0aCBlbXB0eSBzdHJpbmcgcHJlZml4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoe1xuICAgICAgICBlbnY6ICdjdXN0b20nLFxuICAgICAgICBjdXN0b21Sb290VVJJOiAnaHR0cHM6Ly9hcHAuZXhhbXBsZS5sb2NhbCcsXG4gICAgICAgIHJlcXVlc3RJZFByZWZpeDogJycsXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKCdodHRwczovL2FwcC5leGFtcGxlLmxvY2FsJylcbiAgICAgICAgLmdldCgnL2FwaS92MS9waW5nJylcbiAgICAgICAgLm1hdGNoSGVhZGVyKCdSZXF1ZXN0LUlEJywgJ2FiYy0xMjMnKVxuICAgICAgICAucmVwbHkoMjAwLCB7IHN0YXR1czogJ29rJyB9KTtcblxuICAgICAgYXdhaXQgYml0Z28ucGluZyh7XG4gICAgICAgIHJlcUlkOiB7XG4gICAgICAgICAgdG9TdHJpbmc6ICgpID0+ICdhYmMtMTIzJyxcbiAgICAgICAgICBpbmM6ICgpID0+IHtcbiAgICAgICAgICAgIC8qIG1vY2sgKi9cbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIGFueSxcbiAgICAgIH0pO1xuXG4gICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuICB9KTtcbiAgZGVzY3JpYmUoJ2h0dHAgcHJveHkgYWdlbnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ2h0dHAgcHJveHkgYWdlbnQgc2hhbGwgYmUgY3JlYXRlZCB3aGVuIHByb3h5KGN1c3RvbVByb3h5YWdlbnQpIGlzIHNldCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGN1c3RvbVByb3h5QWdlbnQgPSBuZXcgUHJveHlBZ2VudCh7XG4gICAgICAgIGdldFByb3h5Rm9yVXJsOiAoKSA9PiAnaHR0cDovL2xvY2FsaG9zdDozMDAwJyxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoe1xuICAgICAgICBlbnY6ICdjdXN0b20nLFxuICAgICAgICBjdXN0b21Sb290VVJJOiAnaHR0cHM6Ly9hcHAuZXhhbXBsZS5sb2NhbCcsXG4gICAgICAgIGN1c3RvbVByb3h5QWdlbnQsXG4gICAgICB9KTtcblxuICAgICAgYml0Z28uc2hvdWxkLmhhdmUucHJvcGVydHkoJ19jdXN0b21Qcm94eUFnZW50JywgY3VzdG9tUHJveHlBZ2VudCk7XG4gICAgfSk7XG5cbiAgICBpdCgnYml0Z28gYXBpIGlzIHN0aWxsIGluaXRpYXRlZCB3aGVuIHByb3h5KGN1c3RvbVByb3h5QWdlbnQpIGlzIG5vdCBzZXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiaXRnbyA9IG5ldyBCaXRHb0FQSSh7XG4gICAgICAgIGVudjogJ2N1c3RvbScsXG4gICAgICAgIGN1c3RvbVJvb3RVUkk6ICdodHRwczovL2FwcC5leGFtcGxlLmxvY2FsJyxcbiAgICAgIH0pO1xuXG4gICAgICBiaXRnby5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnX2N1c3RvbVByb3h5QWdlbnQnLCB1bmRlZmluZWQpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndmVyaWZ5QWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHN1Y2Nlc3NmdWxseSB2ZXJpZnkgYSBiYXNlNTggYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJpdGdvID0gbmV3IEJpdEdvQVBJKHtcbiAgICAgICAgZW52OiAndGVzdCcsXG4gICAgICB9KTtcblxuICAgICAgYml0Z28udmVyaWZ5QWRkcmVzcyh7IGFkZHJlc3M6ICcyTjZwYVQyVFU0TjFYcGFaakppQXBXSlhvZXlyTDNVV3BrWicgfSkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc3VjY2Vzc2Z1bGx5IHZlcmlmeSBhIGJlY2gzMiBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoe1xuICAgICAgICBlbnY6ICd0ZXN0JyxcbiAgICAgIH0pO1xuXG4gICAgICBiaXRnb1xuICAgICAgICAudmVyaWZ5QWRkcmVzcyh7IGFkZHJlc3M6ICd0YjFxZ3V6eWs0dzZrYXF0cHNjenM1YWowdzhyNzU5OGpxMzZlZ204ZTk4d3FwaDNyd21leDY4c2VzbGdzZycgfSlcbiAgICAgICAgLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd1cmwnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIGNvcnJlY3QgVVJMIGZvciB2ZXJzaW9uIDEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiaXRnbyA9IG5ldyBCaXRHb0FQSSh7XG4gICAgICAgIGVudjogJ3Rlc3QnLFxuICAgICAgICBjdXN0b21Sb290VVJJOiAnaHR0cHM6Ly90ZXN0LmJpdGdvLmNvbScsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHBhdGggPSAnL3Rlc3QtcGF0aCc7XG4gICAgICBjb25zdCBleHBlY3RlZFVybCA9ICdodHRwczovL3Rlc3QuYml0Z28uY29tL2FwaS92MS90ZXN0LXBhdGgnO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYml0Z28udXJsKHBhdGgsIDEpO1xuICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbChleHBlY3RlZFVybCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgY29ycmVjdCBVUkwgZm9yIHZlcnNpb24gMicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJpdGdvID0gbmV3IEJpdEdvQVBJKHtcbiAgICAgICAgZW52OiAndGVzdCcsXG4gICAgICAgIGN1c3RvbVJvb3RVUkk6ICdodHRwczovL3Rlc3QuYml0Z28uY29tJyxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgcGF0aCA9ICcvdGVzdC1wYXRoJztcbiAgICAgIGNvbnN0IGV4cGVjdGVkVXJsID0gJ2h0dHBzOi8vdGVzdC5iaXRnby5jb20vYXBpL3YyL3Rlc3QtcGF0aCc7XG4gICAgICBjb25zdCByZXN1bHQgPSBiaXRnby51cmwocGF0aCwgMik7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKGV4cGVjdGVkVXJsKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRoZSBjb3JyZWN0IFVSTCBmb3IgdmVyc2lvbiAzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoe1xuICAgICAgICBlbnY6ICd0ZXN0JyxcbiAgICAgICAgY3VzdG9tUm9vdFVSSTogJ2h0dHBzOi8vdGVzdC5iaXRnby5jb20nLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBwYXRoID0gJy90ZXN0LXBhdGgnO1xuICAgICAgY29uc3QgZXhwZWN0ZWRVcmwgPSAnaHR0cHM6Ly90ZXN0LmJpdGdvLmNvbS9hcGkvdjMvdGVzdC1wYXRoJztcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGJpdGdvLnVybChwYXRoLCAzKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwoZXhwZWN0ZWRVcmwpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBkZWZhdWx0IHRvIHZlcnNpb24gMSBpZiBubyB2ZXJzaW9uIGlzIHByb3ZpZGVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoe1xuICAgICAgICBlbnY6ICd0ZXN0JyxcbiAgICAgICAgY3VzdG9tUm9vdFVSSTogJ2h0dHBzOi8vdGVzdC5iaXRnby5jb20nLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBwYXRoID0gJy90ZXN0LXBhdGgnO1xuICAgICAgY29uc3QgZXhwZWN0ZWRVcmwgPSAnaHR0cHM6Ly90ZXN0LmJpdGdvLmNvbS9hcGkvdjEvdGVzdC1wYXRoJztcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGJpdGdvLnVybChwYXRoKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwoZXhwZWN0ZWRVcmwpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZGVjcnlwdEtleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGJpdGdvOiBCaXRHb0FQSTtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgYml0Z28gPSBuZXcgQml0R29BUEkoeyBlbnY6ICd0ZXN0JyB9KTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIG5vIHBhcmFtcyBhcmUgcHJvdmlkZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIC0gaW50ZW50aW9uYWxseSBjYWxsaW5nIHdpdGggbm8gcGFyYW1zIGZvciB0ZXN0XG4gICAgICBhd2FpdCBiaXRnby5kZWNyeXB0S2V5cygpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ01pc3NpbmcgcGFyYW1ldGVyOiB3YWxsZXRJZEVuY3J5cHRlZEtleVBhaXJzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIHdhbGxldElkRW5jcnlwdGVkS2V5UGFpcnMgaXMgbWlzc2luZycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJpdGdvXG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBpbnRlbnRpb25hbGx5IG1pc3NpbmcgcmVxdWlyZWQgcGFyYW1cbiAgICAgICAgLmRlY3J5cHRLZXlzKHsgcGFzc3dvcmQ6ICdwYXNzd29yZDEyMycgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ01pc3NpbmcgcGFyYW1ldGVyOiB3YWxsZXRJZEVuY3J5cHRlZEtleVBhaXJzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIHBhc3N3b3JkIGlzIG1pc3NpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIC0gaW50ZW50aW9uYWxseSBtaXNzaW5nIHJlcXVpcmVkIHBhcmFtXG4gICAgICBhd2FpdCBiaXRnby5kZWNyeXB0S2V5cyh7IHdhbGxldElkRW5jcnlwdGVkS2V5UGFpcnM6IFtdIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ01pc3NpbmcgcGFyYW1ldGVyOiBwYXNzd29yZCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiB3YWxsZXRJZEVuY3J5cHRlZEtleVBhaXJzIGlzIG5vdCBhbiBhcnJheScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJpdGdvXG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBpbnRlbnRpb25hbGx5IHByb3ZpZGluZyB3cm9uZyB0eXBlXG4gICAgICAgIC5kZWNyeXB0S2V5cyh7IHdhbGxldElkRW5jcnlwdGVkS2V5UGFpcnM6ICdub3QgYW4gYXJyYXknLCBwYXNzd29yZDogJ3Bhc3N3b3JkMTIzJyB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnd2FsbGV0SWRFbmNyeXB0ZWRLZXlQYWlycyBtdXN0IGJlIGFuIGFycmF5Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBlbXB0eSBhcnJheSBmb3IgZW1wdHkgd2FsbGV0SWRFbmNyeXB0ZWRLZXlQYWlycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJpdGdvLmRlY3J5cHRLZXlzKHsgd2FsbGV0SWRFbmNyeXB0ZWRLZXlQYWlyczogW10sIHBhc3N3b3JkOiAncGFzc3dvcmQxMjMnIH0pO1xuICAgICAgcmVzdWx0LnNob3VsZC5iZS5hbi5BcnJheSgpO1xuICAgICAgcmVzdWx0LnNob3VsZC5iZS5lbXB0eSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiBhbnkgd2FsbGV0SWQgaXMgbWlzc2luZyBvciBub3QgYSBzdHJpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiaXRnb1xuICAgICAgICAuZGVjcnlwdEtleXMoe1xuICAgICAgICAgIHdhbGxldElkRW5jcnlwdGVkS2V5UGFpcnM6IFtcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBpbnRlbnRpb25hbGx5IG1pc3Npbmcgd2FsbGV0SWRcbiAgICAgICAgICAgIHsgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkLWRhdGEnIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBwYXNzd29yZDogJ3Bhc3N3b3JkMTIzJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2VhY2gga2V5IHBhaXIgbXVzdCBoYXZlIGEgc3RyaW5nIHdhbGxldElkJyk7XG5cbiAgICAgIGF3YWl0IGJpdGdvXG4gICAgICAgIC5kZWNyeXB0S2V5cyh7XG4gICAgICAgICAgd2FsbGV0SWRFbmNyeXB0ZWRLZXlQYWlyczogW1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciAtIGludGVudGlvbmFsbHkgcHJvdmlkaW5nIHdyb25nIHR5cGVcbiAgICAgICAgICAgIHsgd2FsbGV0SWQ6IDEyMywgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkLWRhdGEnIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBwYXNzd29yZDogJ3Bhc3N3b3JkMTIzJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2VhY2gga2V5IHBhaXIgbXVzdCBoYXZlIGEgc3RyaW5nIHdhbGxldElkJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIGFueSBlbmNyeXB0ZWRQcnYgaXMgbWlzc2luZyBvciBub3QgYSBzdHJpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiaXRnb1xuICAgICAgICAuZGVjcnlwdEtleXMoe1xuICAgICAgICAgIHdhbGxldElkRW5jcnlwdGVkS2V5UGFpcnM6IFtcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBpbnRlbnRpb25hbGx5IG1pc3NpbmcgZW5jcnlwdGVkUHJ2XG4gICAgICAgICAgICB7IHdhbGxldElkOiAnd2FsbGV0LWlkLTEnIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBwYXNzd29yZDogJ3Bhc3N3b3JkMTIzJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2VhY2gga2V5IHBhaXIgbXVzdCBoYXZlIGEgc3RyaW5nIGVuY3J5cHRlZFBydicpO1xuXG4gICAgICBhd2FpdCBiaXRnb1xuICAgICAgICAuZGVjcnlwdEtleXMoe1xuICAgICAgICAgIHdhbGxldElkRW5jcnlwdGVkS2V5UGFpcnM6IFtcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLSBpbnRlbnRpb25hbGx5IHByb3ZpZGluZyB3cm9uZyB0eXBlXG4gICAgICAgICAgICB7IHdhbGxldElkOiAnd2FsbGV0LWlkLTEnLCBlbmNyeXB0ZWRQcnY6IDEyMyB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgcGFzc3dvcmQ6ICdwYXNzd29yZDEyMycsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdlYWNoIGtleSBwYWlyIG11c3QgaGF2ZSBhIHN0cmluZyBlbmNyeXB0ZWRQcnYnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2RlY3J5cHRLZXlzJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBiaXRnbzogQml0R29BUEk7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGJpdGdvID0gbmV3IEJpdEdvQVBJKHsgZW52OiAndGVzdCcgfSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgc2lub24ucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gd2FsbGV0SWRzIG9mIGtleXMgdGhhdCBmYWlsZWQgdG8gZGVjcnlwdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGRlY3J5cHRBc3luY1N0dWIgPSBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpO1xuICAgICAgZGVjcnlwdEFzeW5jU3R1Yi5vbkZpcnN0Q2FsbCgpLnJlc29sdmVzKCdkZWNyeXB0ZWQta2V5LTEnKTtcbiAgICAgIGRlY3J5cHRBc3luY1N0dWIub25TZWNvbmRDYWxsKCkucmVqZWN0cyhuZXcgRXJyb3IoJ2RlY3J5cHRpb24gZmFpbGVkJykpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiaXRnby5kZWNyeXB0S2V5cyh7XG4gICAgICAgIHdhbGxldElkRW5jcnlwdGVkS2V5UGFpcnM6IFtcbiAgICAgICAgICB7IHdhbGxldElkOiAnd2FsbGV0LWlkLTEnLCBlbmNyeXB0ZWRQcnY6ICdlbmNyeXB0ZWQtZGF0YS0xJyB9LFxuICAgICAgICAgIHsgd2FsbGV0SWQ6ICd3YWxsZXQtaWQtMicsIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZC1kYXRhLTInIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHBhc3N3b3JkOiAncGFzc3dvcmQxMjMnLFxuICAgICAgfSk7XG5cbiAgICAgIHJlc3VsdC5zaG91bGQuYmUuYW4uQXJyYXkoKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICByZXN1bHRbMF0uc2hvdWxkLmVxdWFsKCd3YWxsZXQtaWQtMicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb3JyZWN0bHkgcHJvY2VzcyBtdWx0aXBsZSB3YWxsZXQga2V5cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGRlY3J5cHRBc3luY1N0dWIgPSBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpO1xuICAgICAgZGVjcnlwdEFzeW5jU3R1YlxuICAgICAgICAud2l0aEFyZ3MoeyBpbnB1dDogJ2VuY3J5cHRlZC1kYXRhLTInLCBwYXNzd29yZDogJ3Bhc3N3b3JkMTIzJyB9KVxuICAgICAgICAucmVqZWN0cyhuZXcgRXJyb3IoJ2RlY3J5cHRpb24gZmFpbGVkJykpO1xuICAgICAgZGVjcnlwdEFzeW5jU3R1YlxuICAgICAgICAud2l0aEFyZ3MoeyBpbnB1dDogJ2VuY3J5cHRlZC1kYXRhLTQnLCBwYXNzd29yZDogJ3Bhc3N3b3JkMTIzJyB9KVxuICAgICAgICAucmVqZWN0cyhuZXcgRXJyb3IoJ2RlY3J5cHRpb24gZmFpbGVkJykpO1xuICAgICAgZGVjcnlwdEFzeW5jU3R1Yi5yZXNvbHZlcygnc3VjY2VzcycpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiaXRnby5kZWNyeXB0S2V5cyh7XG4gICAgICAgIHdhbGxldElkRW5jcnlwdGVkS2V5UGFpcnM6IFtcbiAgICAgICAgICB7IHdhbGxldElkOiAnd2FsbGV0LWlkLTEnLCBlbmNyeXB0ZWRQcnY6ICdlbmNyeXB0ZWQtZGF0YS0xJyB9LFxuICAgICAgICAgIHsgd2FsbGV0SWQ6ICd3YWxsZXQtaWQtMicsIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZC1kYXRhLTInIH0sXG4gICAgICAgICAgeyB3YWxsZXRJZDogJ3dhbGxldC1pZC0zJywgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkLWRhdGEtMycgfSxcbiAgICAgICAgICB7IHdhbGxldElkOiAnd2FsbGV0LWlkLTQnLCBlbmNyeXB0ZWRQcnY6ICdlbmNyeXB0ZWQtZGF0YS00JyB9LFxuICAgICAgICBdLFxuICAgICAgICBwYXNzd29yZDogJ3Bhc3N3b3JkMTIzJyxcbiAgICAgIH0pO1xuXG4gICAgICBkZWNyeXB0QXN5bmNTdHViLmNhbGxDb3VudC5zaG91bGQuZXF1YWwoNCk7XG4gICAgICByZXN1bHQuc2hvdWxkLmJlLmFuLkFycmF5KCk7XG4gICAgICByZXN1bHQuc2hvdWxkLmhhdmUubGVuZ3RoKDIpO1xuICAgICAgcmVzdWx0LnNob3VsZC5jb250YWluRGVlcChbJ3dhbGxldC1pZC0yJywgJ3dhbGxldC1pZC00J10pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVXNlci1BZ2VudCBoZWFkZXIgYmFzZWQgb24gZW52aXJvbm1lbnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2V0IFVzZXItQWdlbnQgaGVhZGVyIHdoZW4gcnVubmluZyBpbiBOb2RlLmpzICh0eXBlb2Ygd2luZG93ID09PSB1bmRlZmluZWQpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoe1xuICAgICAgICBlbnY6ICdjdXN0b20nLFxuICAgICAgICBjdXN0b21Sb290VVJJOiAnaHR0cHM6Ly9hcHAuZXhhbXBsZS5sb2NhbCcsXG4gICAgICAgIHVzZXJBZ2VudDogJ1Rlc3RBZ2VudC8xLjAnLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIEVuc3VyZSB3ZSdyZSBpbiBhIE5vZGUuanMgZW52aXJvbm1lbnQgYnkgdmVyaWZ5aW5nIHdpbmRvdyBpcyB1bmRlZmluZWRcbiAgICAgICh0eXBlb2Ygd2luZG93KS5zaG91bGQuZXF1YWwoJ3VuZGVmaW5lZCcpO1xuXG4gICAgICBjb25zdCBzY29wZSA9IG5vY2soJ2h0dHBzOi8vYXBwLmV4YW1wbGUubG9jYWwnKVxuICAgICAgICAuZ2V0KCcvYXBpL3YxL3BpbmcnKVxuICAgICAgICAubWF0Y2hIZWFkZXIoJ1VzZXItQWdlbnQnLCAnVGVzdEFnZW50LzEuMCcpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgc3RhdHVzOiAnb2snIH0pO1xuXG4gICAgICBhd2FpdCBiaXRnby5waW5nKHtcbiAgICAgICAgcmVxSWQ6IHtcbiAgICAgICAgICB0b1N0cmluZzogKCkgPT4gJ3Rlc3QtMTIzJyxcbiAgICAgICAgICBpbmM6ICgpID0+IHtcbiAgICAgICAgICAgIC8qIG1vY2sgKi9cbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIGFueSxcbiAgICAgIH0pO1xuXG4gICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3Qgc2V0IFVzZXItQWdlbnQgaGVhZGVyIHdoZW4gcnVubmluZyBpbiBicm93c2VyICh0eXBlb2Ygd2luZG93ICE9PSB1bmRlZmluZWQpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gTW9jayB0aGUgd2luZG93IG9iamVjdCB0byBzaW11bGF0ZSBicm93c2VyIGVudmlyb25tZW50XG4gICAgICBjb25zdCB3aW5kb3dTdHViID0geyBsb2NhdGlvbjogJ21vY2snIH07XG4gICAgICAoZ2xvYmFsIGFzIGFueSkud2luZG93ID0gd2luZG93U3R1YjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoe1xuICAgICAgICAgIGVudjogJ2N1c3RvbScsXG4gICAgICAgICAgY3VzdG9tUm9vdFVSSTogJ2h0dHBzOi8vYXBwLmV4YW1wbGUubG9jYWwnLFxuICAgICAgICAgIHVzZXJBZ2VudDogJ1Rlc3RBZ2VudC8xLjAnLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBzY29wZSA9IG5vY2soJ2h0dHBzOi8vYXBwLmV4YW1wbGUubG9jYWwnKVxuICAgICAgICAgIC5nZXQoJy9hcGkvdjEvcGluZycpXG4gICAgICAgICAgLnJlcGx5KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIC8vIFZlcmlmeSBVc2VyLUFnZW50IGhlYWRlciBpcyBOT1Qgc2V0IHRvIG91ciBjdXN0b20gdmFsdWVcbiAgICAgICAgICAgIGNvbnN0IHVzZXJBZ2VudCA9IHRoaXMucmVxLmhlYWRlcnNbJ3VzZXItYWdlbnQnXTtcbiAgICAgICAgICAgIGlmICh1c2VyQWdlbnQgJiYgdXNlckFnZW50LmluY2x1ZGVzKCdUZXN0QWdlbnQvMS4wJykpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVc2VyLUFnZW50IHNob3VsZCBub3QgYmUgc2V0IGluIGJyb3dzZXIgZW52aXJvbm1lbnQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBbMjAwLCB7IHN0YXR1czogJ29rJyB9XTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCBiaXRnby5waW5nKHtcbiAgICAgICAgICByZXFJZDoge1xuICAgICAgICAgICAgdG9TdHJpbmc6ICgpID0+ICd0ZXN0LTEyMycsXG4gICAgICAgICAgICBpbmM6ICgpID0+IHtcbiAgICAgICAgICAgICAgLyogbW9jayAqL1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9IGFzIGFueSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIC8vIENsZWFuIHVwIHRoZSBnbG9iYWwgd2luZG93IG1vY2tcbiAgICAgICAgZGVsZXRlIChnbG9iYWwgYXMgYW55KS53aW5kb3c7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdobWFjQXV0aFN0cmF0ZWd5IHRva2VuIGxpZmVjeWNsZScsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBST09UID0gJ2h0dHBzOi8vYXBwLmV4YW1wbGUubG9jYWwnO1xuXG4gICAgLy8gQnVpbGRzIGEgbW9jayBzdHJhdGVneSB3aG9zZSBzZXRUb2tlbiAvIGNsZWFyVG9rZW4gYXJlIHNpbm9uIHN0dWJzLlxuICAgIGZ1bmN0aW9uIG1ha2VTdHJhdGVneShvdmVycmlkZXM6IFBhcnRpYWw8SUhtYWNBdXRoU3RyYXRlZ3k+ID0ge30pOiB7XG4gICAgICBzdHJhdGVneTogSUhtYWNBdXRoU3RyYXRlZ3k7XG4gICAgICBzZXRUb2tlblN0dWI6IHNpbm9uLlNpbm9uU3R1YjtcbiAgICAgIGNsZWFyVG9rZW5TdHViOiBzaW5vbi5TaW5vblN0dWI7XG4gICAgfSB7XG4gICAgICBjb25zdCBzZXRUb2tlblN0dWIgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoKTtcbiAgICAgIGNvbnN0IGNsZWFyVG9rZW5TdHViID0gc2lub24uc3R1YigpLnJlc29sdmVzKCk7XG4gICAgICBjb25zdCBzdHJhdGVneTogSUhtYWNBdXRoU3RyYXRlZ3kgPSB7XG4gICAgICAgIGNhbGN1bGF0ZVJlcXVlc3RIZWFkZXJzOiBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBobWFjOiAnaG1hYycsIHRpbWVzdGFtcDogMSwgdG9rZW5IYXNoOiAnaGFzaCcgfSksXG4gICAgICAgIHZlcmlmeVJlc3BvbnNlOiBzaW5vbi5zdHViKCkucmVzb2x2ZXMoe1xuICAgICAgICAgIGlzVmFsaWQ6IHRydWUsXG4gICAgICAgICAgZXhwZWN0ZWRIbWFjOiAnaG1hYycsXG4gICAgICAgICAgc2lnbmF0dXJlU3ViamVjdDogJycsXG4gICAgICAgICAgaXNJblJlc3BvbnNlVmFsaWRpdHlXaW5kb3c6IHRydWUsXG4gICAgICAgICAgdmVyaWZpY2F0aW9uVGltZTogRGF0ZS5ub3coKSxcbiAgICAgICAgfSksXG4gICAgICAgIGNhbGN1bGF0ZUhNQUM6IHNpbm9uLnN0dWIoKS5yZXNvbHZlcygnaGFzaGVkLXB3JyksXG4gICAgICAgIHNldFRva2VuOiBzZXRUb2tlblN0dWIsXG4gICAgICAgIGNsZWFyVG9rZW46IGNsZWFyVG9rZW5TdHViLFxuICAgICAgICAuLi5vdmVycmlkZXMsXG4gICAgICB9O1xuICAgICAgcmV0dXJuIHsgc3RyYXRlZ3ksIHNldFRva2VuU3R1YiwgY2xlYXJUb2tlblN0dWIgfTtcbiAgICB9XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgICAgc2lub24ucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2F1dGhlbnRpY2F0ZSgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ2NhbGxzIHNldFRva2VuIHdpdGggdGhlIGFjY2Vzc190b2tlbiByZWNlaXZlZCBmcm9tIHRoZSBzZXJ2ZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHsgc3RyYXRlZ3ksIHNldFRva2VuU3R1YiB9ID0gbWFrZVN0cmF0ZWd5KCk7XG4gICAgICAgIGNvbnN0IGJpdGdvID0gbmV3IEJpdEdvQVBJKHsgZW52OiAnY3VzdG9tJywgY3VzdG9tUm9vdFVSSTogUk9PVCwgaG1hY0F1dGhTdHJhdGVneTogc3RyYXRlZ3kgfSk7XG5cbiAgICAgICAgbm9jayhST09UKVxuICAgICAgICAgIC5wb3N0KCcvYXBpL3YyL3VzZXIvbG9naW4nKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVzZXI6IHsgdXNlcm5hbWU6ICd0ZXN0QGV4YW1wbGUuY29tJyB9LFxuICAgICAgICAgICAgYWNjZXNzX3Rva2VuOiAndjJ4bXlhY2Nlc3N0b2tlbicsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgYml0Z28uYXV0aGVudGljYXRlKHsgdXNlcm5hbWU6ICd0ZXN0QGV4YW1wbGUuY29tJywgcGFzc3dvcmQ6ICdodW50ZXIyJyB9KTtcblxuICAgICAgICBzZXRUb2tlblN0dWIuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICBzZXRUb2tlblN0dWIuZmlyc3RDYWxsLmFyZ3NbMF0uc2hvdWxkLmVxdWFsKCd2MnhteWFjY2Vzc3Rva2VuJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2F3YWl0cyBzZXRUb2tlbiBiZWZvcmUgbWFraW5nIGVuc3VyZUVjZGhLZXljaGFpbiByZXF1ZXN0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gVGhpcyBpcyB0aGUgY29yZSByZWdyZXNzaW9uIHRlc3Q6IGlmIHNldFRva2VuIGlzIG5vdCBhd2FpdGVkLCB0aGVcbiAgICAgICAgLy8gc3RyYXRlZ3kncyBrZXkgbWF0ZXJpYWwgd29uJ3QgYmUgcmVhZHkgYmVmb3JlIGNhbGN1bGF0ZVJlcXVlc3RIZWFkZXJzXG4gICAgICAgIC8vIGlzIGNhbGxlZCBmb3IgdGhlIEdFVCAvdXNlci9zZXR0aW5ncyByZXF1ZXN0LCBhbmQgaXQgd291bGQgdGhyb3cuXG4gICAgICAgIGxldCBrZXlSZWFkeSA9IGZhbHNlO1xuICAgICAgICBjb25zdCB7IHN0cmF0ZWd5IH0gPSBtYWtlU3RyYXRlZ3koe1xuICAgICAgICAgIHNldFRva2VuOiBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIC8vIFNpbXVsYXRlIG5vbi10cml2aWFsIGFzeW5jIGtleSBkZXJpdmF0aW9uIChsaWtlIGNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KS5cbiAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiBzZXRJbW1lZGlhdGUocmVzb2x2ZSkpO1xuICAgICAgICAgICAga2V5UmVhZHkgPSB0cnVlO1xuICAgICAgICAgIH0pLFxuICAgICAgICAgIGNhbGN1bGF0ZVJlcXVlc3RIZWFkZXJzOiBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGlmICgha2V5UmVhZHkpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyB0b2tlbiBhdmFpbGFibGUuIENhbGwgc2V0VG9rZW4oKSBvciByZXN0b3JlVG9rZW4oKSBmaXJzdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7IGhtYWM6ICdobWFjJywgdGltZXN0YW1wOiBEYXRlLm5vdygpLCB0b2tlbkhhc2g6ICdoYXNoJyB9O1xuICAgICAgICAgIH0pLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoeyBlbnY6ICdjdXN0b20nLCBjdXN0b21Sb290VVJJOiBST09ULCBobWFjQXV0aFN0cmF0ZWd5OiBzdHJhdGVneSB9KTtcblxuICAgICAgICBub2NrKFJPT1QpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjIvdXNlci9sb2dpbicpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdXNlcjogeyB1c2VybmFtZTogJ3Rlc3RAZXhhbXBsZS5jb20nIH0sXG4gICAgICAgICAgICBhY2Nlc3NfdG9rZW46ICd2MnhteXRva2VuJyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgLy8gVGhlIEdFVCAvdXNlci9zZXR0aW5ncyByZXF1ZXN0IG1hZGUgYnkgZW5zdXJlVXNlckVjZGhLZXljaGFpbklzQ3JlYXRlZFxuICAgICAgICAvLyBtdXN0IHN1Y2NlZWQg4oCUIGl0IHdvdWxkIHRocm93IGlmIHNldFRva2VuIHdhc24ndCBhd2FpdGVkIGZpcnN0LlxuICAgICAgICBub2NrKFJPT1QpXG4gICAgICAgICAgLmdldCgnL2FwaS92MS91c2VyL3NldHRpbmdzJylcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBzZXR0aW5nczogeyBlY2RoS2V5Y2hhaW46ICd4cHViMTIzJyB9LFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IGJpdGdvLmF1dGhlbnRpY2F0ZSh7XG4gICAgICAgICAgdXNlcm5hbWU6ICd0ZXN0QGV4YW1wbGUuY29tJyxcbiAgICAgICAgICBwYXNzd29yZDogJ2h1bnRlcjInLFxuICAgICAgICAgIGVuc3VyZUVjZGhLZXljaGFpbjogdHJ1ZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAga2V5UmVhZHkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnaGFuZGxlcyBhbiBFQ0RILWVuY3J5cHRlZCB0b2tlbiByZXNwb25zZSAobm8gYWNjZXNzX3Rva2VuKSB0aHJvdWdoIHRoZSB2MiBsb2dpbiBmbG93JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB7IHN0cmF0ZWd5LCBzZXRUb2tlblN0dWIgfSA9IG1ha2VTdHJhdGVneSgpO1xuICAgICAgICBjb25zdCBiaXRnbyA9IG5ldyBCaXRHb0FQSSh7IGVudjogJ2N1c3RvbScsIGN1c3RvbVJvb3RVUkk6IFJPT1QsIGhtYWNBdXRoU3RyYXRlZ3k6IHN0cmF0ZWd5IH0pO1xuXG4gICAgICAgIC8vIFN0dWIgdG9rZW4gaXNzdWFuY2Ugc28gdGhlIHRlc3QgZG9lcyBub3QgZGVwZW5kIG9uIHJlYWwgY3J5cHRvLiBUaGUgcG9pbnQgaXNcbiAgICAgICAgLy8gdG8gYXNzZXJ0IHRoZSB2MiBsb2dpbiByZXNwb25zZSB3aXRoIGVuY3J5cHRlZFRva2VuIHJlYWNoZXMgaGFuZGxlVG9rZW5Jc3N1YW5jZVxuICAgICAgICAvLyBhbmQgdGhhdCB0aGUgZGVjcnlwdGVkIHRva2VuIGlzIHRoZW4gc3luY2VkIHRvIHRoZSBzdHJhdGVneS5cbiAgICAgICAgY29uc3QgaGFuZGxlVG9rZW5Jc3N1YW5jZVN0dWIgPSBzaW5vblxuICAgICAgICAgIC5zdHViKGJpdGdvLCAnaGFuZGxlVG9rZW5Jc3N1YW5jZScpXG4gICAgICAgICAgLnJlc29sdmVzKHsgdG9rZW46ICd2MnhkZWNyeXB0ZWR0b2tlbicgfSk7XG5cbiAgICAgICAgbm9jayhST09UKVxuICAgICAgICAgIC5wb3N0KCcvYXBpL3YyL3VzZXIvbG9naW4nKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVzZXI6IHsgdXNlcm5hbWU6ICd0ZXN0QGV4YW1wbGUuY29tJyB9LFxuICAgICAgICAgICAgZW5jcnlwdGVkVG9rZW46ICdlbmNyeXB0ZWQtdG9rZW4tdmFsdWUnLFxuICAgICAgICAgICAgZW5jcnlwdGVkRUNESFhwcnY6ICdlbmNyeXB0ZWQtZWNkaC14cHJ2JyxcbiAgICAgICAgICAgIGRlcml2YXRpb25QYXRoOiAnbS85OTk5OTkvMC8xJyxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCBiaXRnby5hdXRoZW50aWNhdGUoeyB1c2VybmFtZTogJ3Rlc3RAZXhhbXBsZS5jb20nLCBwYXNzd29yZDogJ2h1bnRlcjInIH0pO1xuXG4gICAgICAgIC8vIFRoZSBTREsgbXVzdCBoYXZlIHRha2VuIHRoZSBFQ0RIIHBhdGggKG5vdCB0aGUgcGxhaW4gYWNjZXNzX3Rva2VuIHBhdGgpLlxuICAgICAgICBoYW5kbGVUb2tlbklzc3VhbmNlU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIGhhbmRsZVRva2VuSXNzdWFuY2VTdHViLmZpcnN0Q2FsbC5hcmdzWzBdLmVuY3J5cHRlZFRva2VuLnNob3VsZC5lcXVhbCgnZW5jcnlwdGVkLXRva2VuLXZhbHVlJyk7XG4gICAgICAgIC8vIFRoZSBkZWNyeXB0ZWQgdG9rZW4gbXVzdCBiZSBzeW5jZWQgdG8gdGhlIHN0cmF0ZWd5LlxuICAgICAgICBzZXRUb2tlblN0dWIuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICBzZXRUb2tlblN0dWIuZmlyc3RDYWxsLmFyZ3NbMF0uc2hvdWxkLmVxdWFsKCd2MnhkZWNyeXB0ZWR0b2tlbicpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnYXV0aGVudGljYXRlV2l0aFBhc3NrZXkoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHZhbGlkUGFzc2tleSA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgaWQ6ICdjcmVkZW50aWFsLWlkJyxcbiAgICAgICAgcmF3SWQ6ICdyYXctaWQnLFxuICAgICAgICB0eXBlOiAncHVibGljLWtleScsXG4gICAgICAgIHJlc3BvbnNlOiB7XG4gICAgICAgICAgYXV0aGVudGljYXRvckRhdGE6ICdhdXRoLWRhdGEnLFxuICAgICAgICAgIGNsaWVudERhdGFKU09OOiAnY2xpZW50LWRhdGEnLFxuICAgICAgICAgIHNpZ25hdHVyZTogJ3NpZycsXG4gICAgICAgICAgdXNlckhhbmRsZTogJ3VzZXItaGFuZGxlLTEyMycsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgaXQoJ2NhbGxzIHNldFRva2VuIHdpdGggdGhlIGFjY2Vzc190b2tlbiByZWNlaXZlZCBmcm9tIHRoZSBzZXJ2ZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHsgc3RyYXRlZ3ksIHNldFRva2VuU3R1YiB9ID0gbWFrZVN0cmF0ZWd5KCk7XG4gICAgICAgIGNvbnN0IGJpdGdvID0gbmV3IEJpdEdvQVBJKHsgZW52OiAnY3VzdG9tJywgY3VzdG9tUm9vdFVSSTogUk9PVCwgaG1hY0F1dGhTdHJhdGVneTogc3RyYXRlZ3kgfSk7XG5cbiAgICAgICAgbm9jayhST09UKVxuICAgICAgICAgIC5wb3N0KCcvYXBpL2F1dGgvdjEvc2Vzc2lvbicpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdXNlcjogeyB1c2VybmFtZTogJ3Rlc3RAZXhhbXBsZS5jb20nIH0sXG4gICAgICAgICAgICBhY2Nlc3NfdG9rZW46ICd2MnhwYXNza2V5dG9rZW4nLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IGJpdGdvLmF1dGhlbnRpY2F0ZVdpdGhQYXNza2V5KHZhbGlkUGFzc2tleSk7XG5cbiAgICAgICAgc2V0VG9rZW5TdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgc2V0VG9rZW5TdHViLmZpcnN0Q2FsbC5hcmdzWzBdLnNob3VsZC5lcXVhbCgndjJ4cGFzc2tleXRva2VuJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdjbGVhckFzeW5jKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnY2xlYXJzIF90b2tlbiBhbmQgY2FsbHMgY2xlYXJUb2tlbiBvbiB0aGUgc3RyYXRlZ3knLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHsgc3RyYXRlZ3ksIGNsZWFyVG9rZW5TdHViIH0gPSBtYWtlU3RyYXRlZ3koKTtcbiAgICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoeyBlbnY6ICdjdXN0b20nLCBjdXN0b21Sb290VVJJOiBST09ULCBobWFjQXV0aFN0cmF0ZWd5OiBzdHJhdGVneSB9KTtcblxuICAgICAgICBhd2FpdCBiaXRnby5hdXRoZW50aWNhdGVXaXRoQWNjZXNzVG9rZW4oeyBhY2Nlc3NUb2tlbjogJ3YyeHNvbWV0b2tlbicgfSk7XG4gICAgICAgIChiaXRnbyBhcyBhbnkpLl90b2tlbi5zaG91bGQuZXF1YWwoJ3YyeHNvbWV0b2tlbicpO1xuXG4gICAgICAgIGF3YWl0IGJpdGdvLmNsZWFyQXN5bmMoKTtcblxuICAgICAgICAoKGJpdGdvIGFzIGFueSkuX3Rva2VuID09PSB1bmRlZmluZWQpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIGNsZWFyVG9rZW5TdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3JlZnJlc2hUb2tlbigpJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ2NhbGxzIHNldFRva2VuIHdpdGggdGhlIG5ldyBhY2Nlc3NfdG9rZW4gZnJvbSB0aGUgT0F1dGggcmVzcG9uc2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHsgc3RyYXRlZ3ksIHNldFRva2VuU3R1YiB9ID0gbWFrZVN0cmF0ZWd5KCk7XG4gICAgICAgIGNvbnN0IGJpdGdvID0gbmV3IEJpdEdvQVBJKHtcbiAgICAgICAgICBlbnY6ICdjdXN0b20nLFxuICAgICAgICAgIGN1c3RvbVJvb3RVUkk6IFJPT1QsXG4gICAgICAgICAgaG1hY0F1dGhTdHJhdGVneTogc3RyYXRlZ3ksXG4gICAgICAgICAgY2xpZW50SWQ6ICdjbGllbnQtaWQnLFxuICAgICAgICAgIGNsaWVudFNlY3JldDogJ2NsaWVudC1zZWNyZXQnLFxuICAgICAgICB9KTtcbiAgICAgICAgKGJpdGdvIGFzIGFueSkuX3JlZnJlc2hUb2tlbiA9ICdvbGQtcmVmcmVzaC10b2tlbic7XG5cbiAgICAgICAgbm9jayhST09UKS5wb3N0KCcvb2F1dGgvdG9rZW4nKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICBhY2Nlc3NfdG9rZW46ICd2MnhuZXd0b2tlbicsXG4gICAgICAgICAgcmVmcmVzaF90b2tlbjogJ25ldy1yZWZyZXNoLXRva2VuJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgYml0Z28ucmVmcmVzaFRva2VuKCk7XG5cbiAgICAgICAgc2V0VG9rZW5TdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgc2V0VG9rZW5TdHViLmZpcnN0Q2FsbC5hcmdzWzBdLnNob3VsZC5lcXVhbCgndjJ4bmV3dG9rZW4nKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2F1dGhlbnRpY2F0ZVdpdGhBdXRoQ29kZSgpJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ2NhbGxzIHNldFRva2VuIHdpdGggdGhlIGFjY2Vzc190b2tlbiBmcm9tIHRoZSBPQXV0aCByZXNwb25zZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgeyBzdHJhdGVneSwgc2V0VG9rZW5TdHViIH0gPSBtYWtlU3RyYXRlZ3koKTtcbiAgICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoe1xuICAgICAgICAgIGVudjogJ2N1c3RvbScsXG4gICAgICAgICAgY3VzdG9tUm9vdFVSSTogUk9PVCxcbiAgICAgICAgICBobWFjQXV0aFN0cmF0ZWd5OiBzdHJhdGVneSxcbiAgICAgICAgICBjbGllbnRJZDogJ2NsaWVudC1pZCcsXG4gICAgICAgICAgY2xpZW50U2VjcmV0OiAnY2xpZW50LXNlY3JldCcsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soUk9PVCkucG9zdCgnL29hdXRoL3Rva2VuJykucmVwbHkoMjAwLCB7XG4gICAgICAgICAgYWNjZXNzX3Rva2VuOiAndjJ4YXV0aGNvZGV0b2tlbicsXG4gICAgICAgICAgcmVmcmVzaF90b2tlbjogJ3JlZnJlc2gtdG9rZW4nLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gYXV0aGVudGljYXRlV2l0aEF1dGhDb2RlIGNhbGxzIHRoaXMubWUoKSBhZnRlciBzZXR0aW5nIHRoZSB0b2tlblxuICAgICAgICBub2NrKFJPT1QpXG4gICAgICAgICAgLmdldCgnL2FwaS92MS91c2VyL21lJylcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1c2VyOiB7IHVzZXJuYW1lOiAndGVzdEBleGFtcGxlLmNvbScgfSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCBiaXRnby5hdXRoZW50aWNhdGVXaXRoQXV0aENvZGUoeyBhdXRoQ29kZTogJ215LWF1dGgtY29kZScgfSk7XG5cbiAgICAgICAgc2V0VG9rZW5TdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgc2V0VG9rZW5TdHViLmZpcnN0Q2FsbC5hcmdzWzBdLnNob3VsZC5lcXVhbCgndjJ4YXV0aGNvZGV0b2tlbicpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc3luYyB0b2tlbi1zZXR0aW5nIG1ldGhvZHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnYXV0aGVudGljYXRlV2l0aEFjY2Vzc1Rva2VuIGNhbGxzIHNldFRva2VuIChITUFDIHN0cmF0ZWd5IG11c3QgYmUga2VwdCBpbiBzeW5jIGZvciB2Mi92MyBzaWduaW5nKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgeyBzdHJhdGVneSwgc2V0VG9rZW5TdHViIH0gPSBtYWtlU3RyYXRlZ3koKTtcbiAgICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoeyBlbnY6ICdjdXN0b20nLCBjdXN0b21Sb290VVJJOiBST09ULCBobWFjQXV0aFN0cmF0ZWd5OiBzdHJhdGVneSB9KTtcblxuICAgICAgICBhd2FpdCBiaXRnby5hdXRoZW50aWNhdGVXaXRoQWNjZXNzVG9rZW4oeyBhY2Nlc3NUb2tlbjogJ3YyeHN5bmN0b2tlbicgfSk7XG5cbiAgICAgICAgc2V0VG9rZW5TdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgc2V0VG9rZW5TdHViLmZpcnN0Q2FsbC5hcmdzWzBdLnNob3VsZC5lcXVhbCgndjJ4c3luY3Rva2VuJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2Zyb21KU09OIGRvZXMgbm90IGNhbGwgc2V0VG9rZW4gKHN5bmNocm9ub3VzIOKAlCBjYWxsZXIgbXVzdCBpbnZva2Ugc2V0VG9rZW4gb24gdGhlIHN0cmF0ZWd5IG1hbnVhbGx5KScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgeyBzdHJhdGVneSwgc2V0VG9rZW5TdHViIH0gPSBtYWtlU3RyYXRlZ3koKTtcbiAgICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoeyBlbnY6ICdjdXN0b20nLCBjdXN0b21Sb290VVJJOiBST09ULCBobWFjQXV0aFN0cmF0ZWd5OiBzdHJhdGVneSB9KTtcblxuICAgICAgICAoYml0Z28gYXMgYW55KS5mcm9tSlNPTih7IHVzZXI6IHsgdXNlcm5hbWU6ICd0ZXN0QGV4YW1wbGUuY29tJyB9LCB0b2tlbjogJ3YyeGpzb250b2tlbicgfSk7XG5cbiAgICAgICAgc2V0VG9rZW5TdHViLmNhbGxlZC5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2FkZEFjY2Vzc1Rva2VuKCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB2YWxpZFBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgc2NvcGU6IFsnd2FsbGV0X3ZpZXdfYWxsJ10sXG4gICAgICAgIGR1cmF0aW9uOiAzNjAwLFxuICAgICAgfTtcblxuICAgICAgaXQoJ3Nob3VsZCBmb3JjZSBWMSBhdXRoIGFuZCByZXR1cm4gcGxhaW4gdG9rZW4gd2hlbiBlY2RoWHBydiBpcyBhYnNlbnQsIGV2ZW4gaWYgaG1hY0F1dGhTdHJhdGVneSBpcyBhdXRoZW50aWNhdGVkIChTU08vZW50ZXJwcmlzZSB1c2VycyknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIFJlZ3Jlc3Npb24gdGVzdCBmb3IgV0NOLTE3OTAgLyBBTlQtOTYzOiBITUFDIHJlcXVlc3Qgc2lnbmluZyBhbmQgRUNESCByZXNwb25zZVxuICAgICAgICAvLyBlbmNyeXB0aW9uIGFyZSBvcnRob2dvbmFsLiBmb3JjZVYxQXV0aCB0ZWxscyB0aGUgc2VydmVyIHRvIHJldHVybiBhIHBsYWludGV4dCB0b2tlblxuICAgICAgICAvLyBpbnN0ZWFkIG9mIEVDREgtZW5jcnlwdGluZyBpdC4gSXQgbXVzdCBiZSBzZXQgd2hlbmV2ZXIgZWNkaFhwcnYgaXMgYWJzZW50LFxuICAgICAgICAvLyByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdGhlIEhNQUMgc3RyYXRlZ3kgaXMgYWN0aXZlLlxuICAgICAgICBjb25zdCB7IHN0cmF0ZWd5IH0gPSBtYWtlU3RyYXRlZ3koe1xuICAgICAgICAgIGlzQXV0aGVudGljYXRlZDogc2lub24uc3R1YigpLnJldHVybnModHJ1ZSksXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBiaXRnbyA9IG5ldyBCaXRHb0FQSSh7IGVudjogJ2N1c3RvbScsIGN1c3RvbVJvb3RVUkk6IFJPT1QsIGhtYWNBdXRoU3RyYXRlZ3k6IHN0cmF0ZWd5IH0pO1xuICAgICAgICAvLyBEbyBOT1Qgc2V0IF9lY2RoWHBydiDigJQgc2ltdWxhdGVzIFNTTy9lbnRlcnByaXNlIHNlc3Npb24gKE9rdGEsIEVudHJhLCBldGMuKVxuICAgICAgICBhd2FpdCBiaXRnby5hdXRoZW50aWNhdGVXaXRoQWNjZXNzVG9rZW4oeyBhY2Nlc3NUb2tlbjogJ3YyeHN0cmF0ZWd5dG9rZW4nIH0pO1xuXG4gICAgICAgIGNvbnN0IHNjb3BlID0gbm9jayhST09UKS5wb3N0KCcvYXBpL2F1dGgvdjEvYWNjZXNzdG9rZW4nKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICB0b2tlbjogJ3YyeG5ld3BsYWludG9rZW4nLFxuICAgICAgICAgIGxhYmVsOiAndGVzdC10b2tlbicsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJpdGdvLmFkZEFjY2Vzc1Rva2VuKHZhbGlkUGFyYW1zKTtcblxuICAgICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICAvLyBmb3JjZVYxQXV0aCBNVVNUIGJlIHNldCDigJQgc2VydmVyIHJldHVybnMgcGxhaW50ZXh0IHRva2VuIHNpbmNlIHdlIGhhdmUgbm8gZGVjcnlwdGlvbiBrZXlcbiAgICAgICAgKHJlc3VsdCBhcyBhbnkpLndhcm5pbmcuc2hvdWxkLm1hdGNoKC9wcm90b2NvbCBkb3duZ3JhZGUvKTtcbiAgICAgICAgcmVzdWx0LnRva2VuLnNob3VsZC5lcXVhbCgndjJ4bmV3cGxhaW50b2tlbicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgbm90IGNhbGwgaGFuZGxlVG9rZW5Jc3N1YW5jZSB3aGVuIGVjZGhYcHJ2IGlzIHByZXNlbnQgYnV0IHRoZSBzZXJ2ZXIgcmV0dXJuZWQgYSBwbGFpbnRleHQgdG9rZW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGhhbmRsZVRva2VuU3B5ID0gc2lub24uc3B5KEJpdEdvQVBJLnByb3RvdHlwZSwgJ2hhbmRsZVRva2VuSXNzdWFuY2UnKTtcbiAgICAgICAgY29uc3QgeyBzdHJhdGVneSB9ID0gbWFrZVN0cmF0ZWd5KHtcbiAgICAgICAgICBpc0F1dGhlbnRpY2F0ZWQ6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKHRydWUpLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoeyBlbnY6ICdjdXN0b20nLCBjdXN0b21Sb290VVJJOiBST09ULCBobWFjQXV0aFN0cmF0ZWd5OiBzdHJhdGVneSB9KTtcbiAgICAgICAgYml0Z28uZnJvbUpTT04oe1xuICAgICAgICAgIHVzZXI6IHsgdXNlcm5hbWU6ICd0ZXN0QGV4YW1wbGUuY29tJyB9LFxuICAgICAgICAgIHRva2VuOiAnYScucmVwZWF0KDQwKSxcbiAgICAgICAgICBlY2RoWHBydjogJ3hwcnYtdGVzdC1rZXknLFxuICAgICAgICB9KTtcblxuICAgICAgICBub2NrKFJPT1QpLnBvc3QoJy9hcGkvYXV0aC92MS9hY2Nlc3N0b2tlbicpLnJlcGx5KDIwMCwge1xuICAgICAgICAgIHRva2VuOiAndjJ4cGxhaW50ZXh0ZnJvbXYxJyxcbiAgICAgICAgICBsYWJlbDogJ3Rlc3QtdG9rZW4nLFxuICAgICAgICB9KTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJpdGdvLmFkZEFjY2Vzc1Rva2VuKHZhbGlkUGFyYW1zKTtcblxuICAgICAgICAgIGhhbmRsZVRva2VuU3B5LmNhbGxlZC5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICAgICAgICByZXN1bHQudG9rZW4uc2hvdWxkLmVxdWFsKCd2MnhwbGFpbnRleHRmcm9tdjEnKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBoYW5kbGVUb2tlblNweS5yZXN0b3JlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIG5vdCBjYWxsIGhhbmRsZVRva2VuSXNzdWFuY2Ugd2hlbiBlY2RoWHBydiBpcyBhYnNlbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGhhbmRsZVRva2VuU3B5ID0gc2lub24uc3B5KEJpdEdvQVBJLnByb3RvdHlwZSwgJ2hhbmRsZVRva2VuSXNzdWFuY2UnKTtcbiAgICAgICAgY29uc3QgeyBzdHJhdGVneSB9ID0gbWFrZVN0cmF0ZWd5KHtcbiAgICAgICAgICBpc0F1dGhlbnRpY2F0ZWQ6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKHRydWUpLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoeyBlbnY6ICdjdXN0b20nLCBjdXN0b21Sb290VVJJOiBST09ULCBobWFjQXV0aFN0cmF0ZWd5OiBzdHJhdGVneSB9KTtcbiAgICAgICAgYXdhaXQgYml0Z28uYXV0aGVudGljYXRlV2l0aEFjY2Vzc1Rva2VuKHsgYWNjZXNzVG9rZW46ICd2MnhzdHJhdGVneXRva2VuJyB9KTtcblxuICAgICAgICBub2NrKFJPT1QpLnBvc3QoJy9hcGkvYXV0aC92MS9hY2Nlc3N0b2tlbicpLnJlcGx5KDIwMCwge1xuICAgICAgICAgIHRva2VuOiAndjJ4cGxhaW50b2tlbicsXG4gICAgICAgICAgbGFiZWw6ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYml0Z28uYWRkQWNjZXNzVG9rZW4odmFsaWRQYXJhbXMpO1xuXG4gICAgICAgIC8vIGhhbmRsZVRva2VuSXNzdWFuY2UgbXVzdCBub3QgYmUgY2FsbGVkIOKAlCBubyBlY2RoWHBydiB0byBkZWNyeXB0IHdpdGhcbiAgICAgICAgaGFuZGxlVG9rZW5TcHkuY2FsbGVkLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgICAgICByZXN1bHQudG9rZW4uc2hvdWxkLmVxdWFsKCd2MnhwbGFpbnRva2VuJyk7XG5cbiAgICAgICAgaGFuZGxlVG9rZW5TcHkucmVzdG9yZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZm9yY2UgVjEgYXV0aCB3aGVuIGVjZGhYcHJ2IGlzIGFic2VudCBhbmQgc3RyYXRlZ3kgaXMgbm90IGF1dGhlbnRpY2F0ZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHsgc3RyYXRlZ3kgfSA9IG1ha2VTdHJhdGVneSh7XG4gICAgICAgICAgaXNBdXRoZW50aWNhdGVkOiBzaW5vbi5zdHViKCkucmV0dXJucyhmYWxzZSksXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBiaXRnbyA9IG5ldyBCaXRHb0FQSSh7IGVudjogJ2N1c3RvbScsIGN1c3RvbVJvb3RVUkk6IFJPT1QsIGhtYWNBdXRoU3RyYXRlZ3k6IHN0cmF0ZWd5IH0pO1xuICAgICAgICBhd2FpdCBiaXRnby5hdXRoZW50aWNhdGVXaXRoQWNjZXNzVG9rZW4oeyBhY2Nlc3NUb2tlbjogJ3YyeGxlZ2FjeXRva2VuJyB9KTtcblxuICAgICAgICBub2NrKFJPT1QpLnBvc3QoJy9hcGkvYXV0aC92MS9hY2Nlc3N0b2tlbicpLnJlcGx5KDIwMCwge1xuICAgICAgICAgIHRva2VuOiAndjJ4bGVnYWN5cmVzdWx0JyxcbiAgICAgICAgICBsYWJlbDogJ3Rlc3QtdG9rZW4nLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiaXRnby5hZGRBY2Nlc3NUb2tlbih2YWxpZFBhcmFtcyk7XG5cbiAgICAgICAgKHJlc3VsdCBhcyBhbnkpLndhcm5pbmcuc2hvdWxkLm1hdGNoKC9wcm90b2NvbCBkb3duZ3JhZGUvKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZvcmNlIFYxIGF1dGggd2hlbiBpc0F1dGhlbnRpY2F0ZWQgaXMgbm90IGRlZmluZWQgb24gc3RyYXRlZ3knLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHsgc3RyYXRlZ3kgfSA9IG1ha2VTdHJhdGVneSgpO1xuICAgICAgICBjb25zdCBiaXRnbyA9IG5ldyBCaXRHb0FQSSh7IGVudjogJ2N1c3RvbScsIGN1c3RvbVJvb3RVUkk6IFJPT1QsIGhtYWNBdXRoU3RyYXRlZ3k6IHN0cmF0ZWd5IH0pO1xuICAgICAgICBhd2FpdCBiaXRnby5hdXRoZW50aWNhdGVXaXRoQWNjZXNzVG9rZW4oeyBhY2Nlc3NUb2tlbjogJ3YyeG5vYXV0aG1ldGhvZCcgfSk7XG5cbiAgICAgICAgbm9jayhST09UKS5wb3N0KCcvYXBpL2F1dGgvdjEvYWNjZXNzdG9rZW4nKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICB0b2tlbjogJ3YyeHJlc3VsdCcsXG4gICAgICAgICAgbGFiZWw6ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYml0Z28uYWRkQWNjZXNzVG9rZW4odmFsaWRQYXJhbXMpO1xuXG4gICAgICAgIC8vIFdpdGhvdXQgaXNBdXRoZW50aWNhdGVkLCBzaG91bGQgZmFsbCBiYWNrIHRvIFYxIGF1dGhcbiAgICAgICAgKHJlc3VsdCBhcyBhbnkpLndhcm5pbmcuc2hvdWxkLm1hdGNoKC9wcm90b2NvbCBkb3duZ3JhZGUvKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY29uc3RhbnRzIHBhcmFtZXRlcicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGFsbG93IHBhc3NpbmcgY29uc3RhbnRzIHZpYSBvcHRpb25zIGFuZCBleHBvc2UgdmlhIGZldGNoQ29uc3RhbnRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoe1xuICAgICAgICBlbnY6ICdjdXN0b20nLFxuICAgICAgICBjdXN0b21Sb290VVJJOiAnaHR0cHM6Ly9hcHAuZXhhbXBsZS5sb2NhbCcsXG4gICAgICAgIGNsaWVudENvbnN0YW50czogeyBtYXhGZWVSYXRlOiAnMTIzMTIzMTIzMTIzMTIzJyB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGNvbnN0YW50cyA9IGF3YWl0IGJpdGdvLmZldGNoQ29uc3RhbnRzKCk7XG4gICAgICBjb25zdGFudHMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ21heEZlZVJhdGUnLCAnMTIzMTIzMTIzMTIzMTIzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlZnJlc2ggY29uc3RhbnRzIHdoZW4gY2FjaGUgaGFzIGV4cGlyZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiaXRnbyA9IG5ldyBCaXRHb0FQSSh7XG4gICAgICAgIGVudjogJ2N1c3RvbScsXG4gICAgICAgIGN1c3RvbVJvb3RVUkk6ICdodHRwczovL2FwcC5leGFtcGxlLmxvY2FsJyxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBTZXQgdXAgY2FjaGVkIGNvbnN0YW50cyB3aXRoIGFuIGV4cGlyZWQgY2FjaGVcbiAgICAgIChCaXRHb0FQSSBhcyBhbnkpLl9jb25zdGFudHMgPSAoQml0R29BUEkgYXMgYW55KS5fY29uc3RhbnRzIHx8IHt9O1xuICAgICAgKEJpdEdvQVBJIGFzIGFueSkuX2NvbnN0YW50c0V4cGlyZSA9IChCaXRHb0FQSSBhcyBhbnkpLl9jb25zdGFudHNFeHBpcmUgfHwge307XG4gICAgICAoQml0R29BUEkgYXMgYW55KS5fY29uc3RhbnRzWydjdXN0b20nXSA9IHsgbWF4RmVlUmF0ZTogJ29sZC12YWx1ZScgfTtcbiAgICAgIChCaXRHb0FQSSBhcyBhbnkpLl9jb25zdGFudHNFeHBpcmVbJ2N1c3RvbSddID0gbmV3IERhdGUoRGF0ZS5ub3coKSAtIDEwMDApOyAvLyBFeHBpcmVkIDEgc2Vjb25kIGFnb1xuXG4gICAgICBjb25zdCBzY29wZSA9IG5vY2soJ2h0dHBzOi8vYXBwLmV4YW1wbGUubG9jYWwnKVxuICAgICAgICAuZ2V0KCcvYXBpL3YxL2NsaWVudC9jb25zdGFudHMnKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgY29uc3RhbnRzOiB7IG1heEZlZVJhdGU6ICduZXctdmFsdWUnLCBuZXdDb25zdGFudDogJ2FkZGVkJyB9LFxuICAgICAgICB9KTtcblxuICAgICAgY29uc3QgY29uc3RhbnRzID0gYXdhaXQgYml0Z28uZmV0Y2hDb25zdGFudHMoKTtcblxuICAgICAgLy8gU2hvdWxkIHJldHVybiB0aGUgbmV3IGNvbnN0YW50cyBmcm9tIHRoZSBzZXJ2ZXJcbiAgICAgIGNvbnN0YW50cy5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnbWF4RmVlUmF0ZScsICduZXctdmFsdWUnKTtcbiAgICAgIGNvbnN0YW50cy5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnbmV3Q29uc3RhbnQnLCAnYWRkZWQnKTtcblxuICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2UgY2FjaGVkIGNvbnN0YW50cyB3aGVuIGNhY2hlIGlzIHN0aWxsIHZhbGlkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoe1xuICAgICAgICBlbnY6ICdjdXN0b20nLFxuICAgICAgICBjdXN0b21Sb290VVJJOiAnaHR0cHM6Ly9hcHAuZXhhbXBsZS5sb2NhbCcsXG4gICAgICB9KTtcblxuICAgICAgLy8gU2V0IHVwIGNhY2hlZCBjb25zdGFudHMgd2l0aCBhIGZ1dHVyZSBleHBpcnlcbiAgICAgIGNvbnN0IGNhY2hlZENvbnN0YW50cyA9IHsgbWF4RmVlUmF0ZTogJ2NhY2hlZC12YWx1ZScsIGFub3RoZXJTZXR0aW5nOiAnY2FjaGVkLXNldHRpbmcnIH07XG4gICAgICAoQml0R29BUEkgYXMgYW55KS5fY29uc3RhbnRzID0gKEJpdEdvQVBJIGFzIGFueSkuX2NvbnN0YW50cyB8fCB7fTtcbiAgICAgIChCaXRHb0FQSSBhcyBhbnkpLl9jb25zdGFudHNFeHBpcmUgPSAoQml0R29BUEkgYXMgYW55KS5fY29uc3RhbnRzRXhwaXJlIHx8IHt9O1xuICAgICAgKEJpdEdvQVBJIGFzIGFueSkuX2NvbnN0YW50c1snY3VzdG9tJ10gPSBjYWNoZWRDb25zdGFudHM7XG4gICAgICAoQml0R29BUEkgYXMgYW55KS5fY29uc3RhbnRzRXhwaXJlWydjdXN0b20nXSA9IG5ldyBEYXRlKERhdGUubm93KCkgKyA1ICogNjAgKiAxMDAwKTsgLy8gVmFsaWQgZm9yIDUgbW9yZSBtaW51dGVzXG5cbiAgICAgIGNvbnN0IHNjb3BlID0gbm9jaygnaHR0cHM6Ly9hcHAuZXhhbXBsZS5sb2NhbCcpXG4gICAgICAgIC5nZXQoJy9hcGkvdjEvY2xpZW50L2NvbnN0YW50cycpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgY29uc3RhbnRzOiB7IHNob3VsZE5vdEJlVXNlZDogdHJ1ZSB9IH0pO1xuXG4gICAgICBjb25zdCBjb25zdGFudHMgPSBhd2FpdCBiaXRnby5mZXRjaENvbnN0YW50cygpO1xuXG4gICAgICAvLyBTaG91bGQgcmV0dXJuIHRoZSBjYWNoZWQgY29uc3RhbnRzXG4gICAgICBjb25zdGFudHMuc2hvdWxkLmRlZXBFcXVhbChjYWNoZWRDb25zdGFudHMpO1xuXG4gICAgICAvLyBWZXJpZnkgdGhhdCBubyBIVFRQIHJlcXVlc3Qgd2FzIG1hZGUgKHNpbmNlIGNhY2hlIHdhcyB2YWxpZClcbiAgICAgIHNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5mYWxzZSgpO1xuXG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHVzZSBjYWNoZWQgY29uc3RhbnRzIHdoZW4gbm8gY2FjaGUgZXhwaXJ5IGlzIHNldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJpdGdvID0gbmV3IEJpdEdvQVBJKHtcbiAgICAgICAgZW52OiAnY3VzdG9tJyxcbiAgICAgICAgY3VzdG9tUm9vdFVSSTogJ2h0dHBzOi8vYXBwLmV4YW1wbGUubG9jYWwnLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFNldCB1cCBjYWNoZWQgY29uc3RhbnRzIHdpdGggbm8gZXhwaXJ5XG4gICAgICBjb25zdCBjYWNoZWRDb25zdGFudHMgPSB7IG1heEZlZVJhdGU6ICduby1leHBpcnktdmFsdWUnIH07XG4gICAgICAoQml0R29BUEkgYXMgYW55KS5fY29uc3RhbnRzID0gKEJpdEdvQVBJIGFzIGFueSkuX2NvbnN0YW50cyB8fCB7fTtcbiAgICAgIChCaXRHb0FQSSBhcyBhbnkpLl9jb25zdGFudHNFeHBpcmUgPSAoQml0R29BUEkgYXMgYW55KS5fY29uc3RhbnRzRXhwaXJlIHx8IHt9O1xuICAgICAgKEJpdEdvQVBJIGFzIGFueSkuX2NvbnN0YW50c1snY3VzdG9tJ10gPSBjYWNoZWRDb25zdGFudHM7XG4gICAgICAoQml0R29BUEkgYXMgYW55KS5fY29uc3RhbnRzRXhwaXJlWydjdXN0b20nXSA9IHVuZGVmaW5lZDtcblxuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKCdodHRwczovL2FwcC5leGFtcGxlLmxvY2FsJylcbiAgICAgICAgLmdldCgnL2FwaS92MS9jbGllbnQvY29uc3RhbnRzJylcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBjb25zdGFudHM6IHsgc2hvdWxkTm90QmVVc2VkOiB0cnVlIH0gfSk7XG5cbiAgICAgIGNvbnN0IGNvbnN0YW50cyA9IGF3YWl0IGJpdGdvLmZldGNoQ29uc3RhbnRzKCk7XG5cbiAgICAgIC8vIFNob3VsZCByZXR1cm4gdGhlIGNhY2hlZCBjb25zdGFudHNcbiAgICAgIGNvbnN0YW50cy5zaG91bGQuZGVlcEVxdWFsKGNhY2hlZENvbnN0YW50cyk7XG5cbiAgICAgIC8vIFZlcmlmeSB0aGF0IG5vIEhUVFAgcmVxdWVzdCB3YXMgbWFkZSAoc2luY2Ugbm8gZXhwaXJ5IG1lYW5zIGNhY2hlIGlzIGFsd2F5cyB2YWxpZClcbiAgICAgIHNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5mYWxzZSgpO1xuXG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdwYWNrS2V5Y2hhaW5zRkZEJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBiaXRnbzogQml0R29BUEk7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgYml0Z28gPSBuZXcgQml0R29BUEkoeyBlbnY6ICdjdXN0b20nLCBjdXN0b21Sb290VVJJOiAnaHR0cHM6Ly9hcHAuZXhhbXBsZS5sb2NhbCcgfSk7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBmZmQoXG4gICAgICBrZXljaGFpbnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4sXG4gICAgICB2MktleWNoYWluczogUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbiAgICAgIG1heEJhdGNoU2l6ZUJ5dGVzOiBudW1iZXJcbiAgICApOiBBcnJheTx7IHYxQmF0Y2g6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47IHYyQmF0Y2g6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47IHNpemVCeXRlczogbnVtYmVyIH0+IHtcbiAgICAgIHJldHVybiAoYml0Z28gYXMgYW55KS5wYWNrS2V5Y2hhaW5zRkZEKGtleWNoYWlucywgdjJLZXljaGFpbnMsIG1heEJhdGNoU2l6ZUJ5dGVzKTtcbiAgICB9XG5cbiAgICBpdCgncmV0dXJucyBhbiBlbXB0eSBhcnJheSB3aGVuIGJvdGggaW5wdXRzIGFyZSBlbXB0eScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJpbnMgPSBmZmQoe30sIHt9LCAxMDI0KTtcbiAgICAgIGJpbnMuc2hvdWxkLmJlLmFuLkFycmF5KCk7XG4gICAgICBiaW5zLnNob3VsZC5oYXZlLmxlbmd0aCgwKTtcbiAgICB9KTtcblxuICAgIGl0KCdwYWNrcyBhbGwgaXRlbXMgaW50byBhIHNpbmdsZSBiaW4gd2hlbiB0aGV5IGZpdCB3aXRoaW4gdGhlIGxpbWl0JywgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gRWFjaCBlbnRyeTogMi1ieXRlIGlkICsgMTAtYnl0ZSB2YWx1ZSA9IDEyIGJ5dGVzOyA1IGVudHJpZXMgPSA2MCBieXRlcyA8IDIwMCBsaW1pdFxuICAgICAgY29uc3Qga2V5Y2hhaW5zID0geyBrMTogJ2FhYWFhYWFhYWEnLCBrMjogJ2JiYmJiYmJiYmInLCBrMzogJ2NjY2NjY2NjY2MnIH07XG4gICAgICBjb25zdCB2MktleWNoYWlucyA9IHsgdjE6ICdkZGRkZGRkZGRkJywgdjI6ICdlZWVlZWVlZWVlJyB9O1xuICAgICAgY29uc3QgYmlucyA9IGZmZChrZXljaGFpbnMsIHYyS2V5Y2hhaW5zLCAyMDApO1xuICAgICAgYmlucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICBPYmplY3Qua2V5cyhiaW5zWzBdLnYxQmF0Y2gpLnNob3VsZC5oYXZlLmxlbmd0aCgzKTtcbiAgICAgIE9iamVjdC5rZXlzKGJpbnNbMF0udjJCYXRjaCkuc2hvdWxkLmhhdmUubGVuZ3RoKDIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3NwbGl0cyBpbnRvIG11bHRpcGxlIGJpbnMgd2hlbiBhIHNpbmdsZSBiaW4gY2Fubm90IGZpdCBhbGwgaXRlbXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBpZD0nazEnICgyIGJ5dGVzKSArIDYwMC1jaGFyIHZhbHVlID0gNjAyIGJ5dGVzOyAyIGVudHJpZXMgZXhjZWVkIDcwMC1ieXRlIGxpbWl0XG4gICAgICBjb25zdCBrZXljaGFpbnMgPSB7IGsxOiAneCcucmVwZWF0KDYwMCksIGsyOiAneScucmVwZWF0KDYwMCkgfTtcbiAgICAgIGNvbnN0IGJpbnMgPSBmZmQoa2V5Y2hhaW5zLCB7fSwgNzAwKTtcbiAgICAgIGJpbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Rocm93cyB3aGVuIGEgc2luZ2xlIGl0ZW0gZXhjZWVkcyBtYXhCYXRjaFNpemVCeXRlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGlkPSdrMScgKDIgYnl0ZXMpICsgMjAwLWNoYXIgdmFsdWUgPSAyMDIgYnl0ZXMgPiAxMDAtYnl0ZSBsaW1pdFxuICAgICAgY29uc3Qga2V5Y2hhaW5zID0geyBrMTogJ3gnLnJlcGVhdCgyMDApIH07XG4gICAgICB0cnkge1xuICAgICAgICBmZmQoa2V5Y2hhaW5zLCB7fSwgMTAwKTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCBlcnJvciBub3QgdGhyb3duJyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGUubWVzc2FnZS5zaG91bGQubWF0Y2goL2V4Y2VlZHMgdGhlIG1heGltdW0gYmF0Y2ggc2l6ZS8pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3BsYWNlcyBWMSBrZXljaGFpbnMgaW4gdjFCYXRjaCBhbmQgVjIga2V5Y2hhaW5zIGluIHYyQmF0Y2gnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBrZXljaGFpbnMgPSB7IGsxOiAndjF2YWx1ZScgfTtcbiAgICAgIGNvbnN0IHYyS2V5Y2hhaW5zID0geyBrMjogJ3YydmFsdWUnIH07XG4gICAgICBjb25zdCBiaW5zID0gZmZkKGtleWNoYWlucywgdjJLZXljaGFpbnMsIDEwMDAwKTtcbiAgICAgIGJpbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgYmluc1swXS52MUJhdGNoLnNob3VsZC5oYXZlLnByb3BlcnR5KCdrMScsICd2MXZhbHVlJyk7XG4gICAgICBiaW5zWzBdLnYyQmF0Y2guc2hvdWxkLmhhdmUucHJvcGVydHkoJ2syJywgJ3YydmFsdWUnKTtcbiAgICAgIGJpbnNbMF0udjFCYXRjaC5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ2syJyk7XG4gICAgICBiaW5zWzBdLnYyQmF0Y2guc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCdrMScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3VzZXMgRkZEIG9yZGVyaW5nIHNvIHRoZSBsYXJnZXN0IGl0ZW0gaXMgcGFja2VkIGZpcnN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gJ2JpZyc6IGlkKDMpICsgNDk3IGJ5dGVzID0gNTAwIGJ5dGVzOyAnczEnLCdzMic6IGlkKDIpICsgOTggYnl0ZXMgPSAxMDAgYnl0ZXMgZWFjaFxuICAgICAgLy8gbWF4QmF0Y2hTaXplQnl0ZXMgPSA2MDBcbiAgICAgIC8vIEZGRCBvcmRlciAoZGVzY2VuZGluZyk6IGJpZyg1MDApLCBzMSgxMDApLCBzMigxMDApXG4gICAgICAvLyAgIGJpbjA6IGJpZyg1MDApLiBzMTogNTAwKzEwMD02MDAgPD02MDAsIGZpdHMuIHMyOiA2MDArMTAwPTcwMCA+IDYwMCwgbmV3IGJpbjEuXG4gICAgICAvLyAgIFJlc3VsdDogYmluMD17YmlnLHMxfSwgYmluMT17czJ9XG4gICAgICBjb25zdCBrZXljaGFpbnMgPSB7IGJpZzogJ3gnLnJlcGVhdCg0OTcpLCBzMTogJ3knLnJlcGVhdCg5OCksIHMyOiAneicucmVwZWF0KDk4KSB9O1xuICAgICAgY29uc3QgYmlucyA9IGZmZChrZXljaGFpbnMsIHt9LCA2MDApO1xuICAgICAgYmlucy5zaG91bGQuaGF2ZS5sZW5ndGgoMik7XG4gICAgICAvLyAnYmlnJyBzaG91bGQgc2hhcmUgaXRzIGJpbiB3aXRoIG9uZSBzbWFsbCBpdGVtIChGRkQgcGFja3MgdGhlIGxhcmdlc3QgZmlyc3QpXG4gICAgICBjb25zdCBiaW5XaXRoQmlnID0gYmlucy5maW5kKChiKSA9PiAnYmlnJyBpbiBiLnYxQmF0Y2gpITtcbiAgICAgIE9iamVjdC5rZXlzKGJpbldpdGhCaWcudjFCYXRjaCkuc2hvdWxkLmhhdmUubGVuZ3RoKDIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncHJvY2Vzc0tleWNoYWluUGFzc3dvcmRVcGRhdGVzSW5CYXRjaGVzJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IFJPT1QgPSAnaHR0cHM6Ly9hcHAuZXhhbXBsZS5sb2NhbCc7XG4gICAgbGV0IGJpdGdvOiBCaXRHb0FQSTtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc3RyYXRlZ3k6IElIbWFjQXV0aFN0cmF0ZWd5ID0ge1xuICAgICAgICBjYWxjdWxhdGVSZXF1ZXN0SGVhZGVyczogc2lub24uc3R1YigpLnJlc29sdmVzKHsgaG1hYzogJ2htYWMnLCB0aW1lc3RhbXA6IERhdGUubm93KCksIHRva2VuSGFzaDogJ2hhc2gnIH0pLFxuICAgICAgICB2ZXJpZnlSZXNwb25zZTogc2lub24uc3R1YigpLnJlc29sdmVzKHtcbiAgICAgICAgICBpc1ZhbGlkOiB0cnVlLFxuICAgICAgICAgIGV4cGVjdGVkSG1hYzogJ2htYWMnLFxuICAgICAgICAgIHNpZ25hdHVyZVN1YmplY3Q6ICcnLFxuICAgICAgICAgIGlzSW5SZXNwb25zZVZhbGlkaXR5V2luZG93OiB0cnVlLFxuICAgICAgICAgIHZlcmlmaWNhdGlvblRpbWU6IERhdGUubm93KCksXG4gICAgICAgIH0pLFxuICAgICAgICBjYWxjdWxhdGVITUFDOiBzaW5vbi5zdHViKCkucmVzb2x2ZXMoJ2hhc2hlZC1wdycpLFxuICAgICAgICBzZXRUb2tlbjogc2lub24uc3R1YigpLnJlc29sdmVzKCksXG4gICAgICAgIGNsZWFyVG9rZW46IHNpbm9uLnN0dWIoKS5yZXNvbHZlcygpLFxuICAgICAgfTtcbiAgICAgIGJpdGdvID0gbmV3IEJpdEdvQVBJKHsgZW52OiAnY3VzdG9tJywgY3VzdG9tUm9vdFVSSTogUk9PVCwgaG1hY0F1dGhTdHJhdGVneTogc3RyYXRlZ3kgfSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgICAgc2lub24ucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgYXN5bmMgZnVuY3Rpb24gcnVuQmF0Y2hlcyhcbiAgICAgIGtleWNoYWluczogUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbiAgICAgIHYyS2V5Y2hhaW5zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+LFxuICAgICAgbWF4QmF0Y2hTaXplS0I6IG51bWJlcixcbiAgICAgIG1heFJldHJpZXMgPSAzXG4gICAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICByZXR1cm4gKGJpdGdvIGFzIGFueSkucHJvY2Vzc0tleWNoYWluUGFzc3dvcmRVcGRhdGVzSW5CYXRjaGVzKGtleWNoYWlucywgdjJLZXljaGFpbnMsIG1heEJhdGNoU2l6ZUtCLCBtYXhSZXRyaWVzKTtcbiAgICB9XG5cbiAgICBpdCgnbWFrZXMgYSBzaW5nbGUgUFVUIHJlcXVlc3QgZm9yIGEgc21hbGwgcGF5bG9hZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNjb3BlID0gbm9jayhST09UKS5wdXQoJy9hcGkvdjIvdXNlci9rZXljaGFpbnMnKS5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGF3YWl0IHJ1bkJhdGNoZXMoeyBrMTogJ3NtYWxsJyB9LCB7fSwgMTAyNCk7XG4gICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ21ha2VzIHR3byBQVVQgcmVxdWVzdHMgd2hlbiB0aGUgcGF5bG9hZCBzcGFucyB0d28gYmlucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGlkPSdrMScoMikgKyA2MDAgPSA2MDIgYnl0ZXMgZWFjaDsgMiBlbnRyaWVzIGV4Y2VlZCAxIEtCIGxpbWl0ID0+IDIgYmluc1xuICAgICAgY29uc3Qga2V5Y2hhaW5zID0geyBrMTogJ3gnLnJlcGVhdCg2MDApLCBrMjogJ3knLnJlcGVhdCg2MDApIH07XG4gICAgICBjb25zdCBzY29wZSA9IG5vY2soUk9PVCkucHV0KCcvYXBpL3YyL3VzZXIva2V5Y2hhaW5zJykudHdpY2UoKS5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGF3YWl0IHJ1bkJhdGNoZXMoa2V5Y2hhaW5zLCB7fSwgMSk7XG4gICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3JldHJpZXMgYSBmYWlsZWQgYmF0Y2ggYW5kIHN1Y2NlZWRzIG9uIHRoZSBzZWNvbmQgYXR0ZW1wdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soUk9PVCkucHV0KCcvYXBpL3YyL3VzZXIva2V5Y2hhaW5zJykucmVwbHkoNTAwLCB7IGVycm9yOiAnaW50ZXJuYWwgZXJyb3InIH0pO1xuICAgICAgbm9jayhST09UKS5wdXQoJy9hcGkvdjIvdXNlci9rZXljaGFpbnMnKS5yZXBseSgyMDAsIHt9KTtcbiAgICAgIC8vIFNob3VsZCBub3QgdGhyb3dcbiAgICAgIGF3YWl0IHJ1bkJhdGNoZXMoeyBrMTogJ3ZhbHVlJyB9LCB7fSwgMTAyNCwgMyk7XG4gICAgfSk7XG5cbiAgICBpdCgndGhyb3dzIGFmdGVyIGV4aGF1c3RpbmcgYWxsIHJldHJpZXMgb24gcGVyc2lzdGVudCBIVFRQIGVycm9ycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soUk9PVCkucHV0KCcvYXBpL3YyL3VzZXIva2V5Y2hhaW5zJykudGltZXMoMykucmVwbHkoNTAwLCB7IGVycm9yOiAnaW50ZXJuYWwgZXJyb3InIH0pO1xuICAgICAgbGV0IHRocm93bkVycm9yOiBFcnJvciB8IHVuZGVmaW5lZDtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHJ1bkJhdGNoZXMoeyBrMTogJ3ZhbHVlJyB9LCB7fSwgMTAyNCwgMyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93bkVycm9yID0gZTtcbiAgICAgIH1cbiAgICAgIHRocm93bkVycm9yIS5tZXNzYWdlLnNob3VsZC5tYXRjaCgvZmFpbGVkIGFmdGVyIDMgcmV0cmllcy8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Rocm93cyBhZnRlciBleGhhdXN0aW5nIGFsbCByZXRyaWVzIHdoZW4gdGhlIHNlcnZlciByZXBvcnRzIGZhaWxlZCBrZXljaGFpbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrKFJPT1QpXG4gICAgICAgIC5wdXQoJy9hcGkvdjIvdXNlci9rZXljaGFpbnMnKVxuICAgICAgICAudGltZXMoMylcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBmYWlsZWQ6IHsgdjE6IHsgazE6ICdlbmNyeXB0aW9uIGVycm9yJyB9IH0gfSk7XG4gICAgICBsZXQgdGhyb3duRXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgcnVuQmF0Y2hlcyh7IGsxOiAndmFsdWUnIH0sIHt9LCAxMDI0LCAzKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3duRXJyb3IgPSBlO1xuICAgICAgfVxuICAgICAgdGhyb3duRXJyb3IhLm1lc3NhZ2Uuc2hvdWxkLm1hdGNoKC9oYWQgZmFpbGVkIGtleWNoYWlucy8pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY2hhbmdlUGFzc3dvcmQgYmF0Y2hpbmcgZmxvdycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBST09UID0gJ2h0dHBzOi8vYXBwLmV4YW1wbGUubG9jYWwnO1xuICAgIGxldCBiaXRnbzogQml0R29BUEk7XG4gICAgbGV0IHNhbmRib3g6IHNpbm9uLlNpbm9uU2FuZGJveDtcbiAgICBsZXQgdjFVcGRhdGVQYXNzd29yZFN0dWI6IHNpbm9uLlNpbm9uU3R1YjtcbiAgICBsZXQgdjJVcGRhdGVQYXNzd29yZFN0dWI6IHNpbm9uLlNpbm9uU3R1YjtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgICAgY29uc3Qgc3RyYXRlZ3k6IElIbWFjQXV0aFN0cmF0ZWd5ID0ge1xuICAgICAgICBjYWxjdWxhdGVSZXF1ZXN0SGVhZGVyczogc2FuZGJveC5zdHViKCkucmVzb2x2ZXMoeyBobWFjOiAnaG1hYycsIHRpbWVzdGFtcDogRGF0ZS5ub3coKSwgdG9rZW5IYXNoOiAnaGFzaCcgfSksXG4gICAgICAgIHZlcmlmeVJlc3BvbnNlOiBzYW5kYm94LnN0dWIoKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaXNWYWxpZDogdHJ1ZSxcbiAgICAgICAgICBleHBlY3RlZEhtYWM6ICdobWFjJyxcbiAgICAgICAgICBzaWduYXR1cmVTdWJqZWN0OiAnJyxcbiAgICAgICAgICBpc0luUmVzcG9uc2VWYWxpZGl0eVdpbmRvdzogdHJ1ZSxcbiAgICAgICAgICB2ZXJpZmljYXRpb25UaW1lOiBEYXRlLm5vdygpLFxuICAgICAgICB9KSxcbiAgICAgICAgY2FsY3VsYXRlSE1BQzogc2FuZGJveC5zdHViKCkucmVzb2x2ZXMoJ2hhc2hlZC1wdycpLFxuICAgICAgICBzZXRUb2tlbjogc2FuZGJveC5zdHViKCkucmVzb2x2ZXMoKSxcbiAgICAgICAgY2xlYXJUb2tlbjogc2FuZGJveC5zdHViKCkucmVzb2x2ZXMoKSxcbiAgICAgIH07XG5cbiAgICAgIGJpdGdvID0gbmV3IEJpdEdvQVBJKHsgZW52OiAnY3VzdG9tJywgY3VzdG9tUm9vdFVSSTogUk9PVCwgaG1hY0F1dGhTdHJhdGVneTogc3RyYXRlZ3kgfSk7XG4gICAgICAoYml0Z28gYXMgYW55KS5fdXNlciA9IHsgdXNlcm5hbWU6ICd0ZXN0QGJpdGdvLmNvbScgfTtcblxuICAgICAgc2FuZGJveC5zdHViKGJpdGdvLCAndmVyaWZ5UGFzc3dvcmQnKS5yZXNvbHZlcyh0cnVlKTtcblxuICAgICAgdjFVcGRhdGVQYXNzd29yZFN0dWIgPSBzYW5kYm94LnN0dWIoKS5yZXNvbHZlcyh7IGtleWNoYWluczogeyBrMTogJ3YxZW5jJyB9LCB2ZXJzaW9uOiAyNSB9KTtcbiAgICAgIHNhbmRib3guc3R1YihiaXRnbywgJ2tleWNoYWlucycpLnJldHVybnMoe1xuICAgICAgICB1cGRhdGVQYXNzd29yZDogdjFVcGRhdGVQYXNzd29yZFN0dWIsXG4gICAgICB9IGFzIGFueSk7XG5cbiAgICAgIHYyVXBkYXRlUGFzc3dvcmRTdHViID0gc2FuZGJveC5zdHViKCkucmVzb2x2ZXMoeyB2MmsxOiAndjJlbmMnIH0pO1xuICAgICAgc2FuZGJveC5zdHViKGJpdGdvLCAnY29pbicpLnJldHVybnMoe1xuICAgICAgICBrZXljaGFpbnM6ICgpID0+ICh7XG4gICAgICAgICAgdXBkYXRlUGFzc3dvcmQ6IHYyVXBkYXRlUGFzc3dvcmRTdHViLFxuICAgICAgICB9KSxcbiAgICAgIH0gYXMgYW55KTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICBzYW5kYm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdjYWxscyBQVVQgL3VzZXIva2V5Y2hhaW5zIGFuZCBQT1NUIC91c2VyL2NoYW5nZXBhc3N3b3JkIHdpdGhvdXQga2V5Y2hhaW5zIHdoZW4gYmF0Y2hpbmcgaXMgZW5hYmxlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soUk9PVClcbiAgICAgICAgLmdldCgnL2FwaS92Mi91c2VyL2NoZWNrQmF0Y2hpbmdQYXNzd29yZEZsb3cnKVxuICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBpc0JhdGNoaW5nRmxvd0VuYWJsZWQ6IHRydWUsIG1heEJhdGNoU2l6ZUtCOiA5MDAgfSk7XG5cbiAgICAgIGNvbnN0IGJhdGNoUHV0U2NvcGUgPSBub2NrKFJPT1QpLnB1dCgnL2FwaS92Mi91c2VyL2tleWNoYWlucycpLnJlcGx5KDIwMCwge30pO1xuXG4gICAgICBjb25zdCBjaGFuZ2VQYXNzU2NvcGUgPSBub2NrKFJPT1QpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YxL3VzZXIvY2hhbmdlcGFzc3dvcmQnLCAoYm9keTogYW55KSA9PiAhYm9keS5rZXljaGFpbnMgJiYgIWJvZHkudjJfa2V5Y2hhaW5zKVxuICAgICAgICAucmVwbHkoMjAwLCB7fSk7XG5cbiAgICAgIGF3YWl0IGJpdGdvLmNoYW5nZVBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6ICdvbGRwdycsIG5ld1Bhc3N3b3JkOiAnbmV3cHcnIH0pO1xuXG4gICAgICBiYXRjaFB1dFNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBjaGFuZ2VQYXNzU2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzZW5kcyBrZXljaGFpbnMgaW4gdGhlIFBPU1QgYm9keSAobGVnYWN5IGZsb3cpIHdoZW4gdGhlIHNlcnZlciBkaXNhYmxlcyBiYXRjaGluZycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soUk9PVCkuZ2V0KCcvYXBpL3YyL3VzZXIvY2hlY2tCYXRjaGluZ1Bhc3N3b3JkRmxvdycpLnF1ZXJ5KHRydWUpLnJlcGx5KDIwMCwgeyBpc0JhdGNoaW5nRmxvd0VuYWJsZWQ6IGZhbHNlIH0pO1xuXG4gICAgICBjb25zdCBsZWdhY3lTY29wZSA9IG5vY2soUk9PVClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjEvdXNlci9jaGFuZ2VwYXNzd29yZCcsIChib2R5OiBhbnkpID0+ICEhYm9keS5rZXljaGFpbnMgJiYgISFib2R5LnYyX2tleWNoYWlucylcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuXG4gICAgICBhd2FpdCBiaXRnby5jaGFuZ2VQYXNzd29yZCh7IG9sZFBhc3N3b3JkOiAnb2xkcHcnLCBuZXdQYXNzd29yZDogJ25ld3B3JyB9KTtcblxuICAgICAgbGVnYWN5U2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdmYWxscyBiYWNrIHRvIGxlZ2FjeSBmbG93IHdoZW4gdGhlIGJhdGNoaW5nIGNoZWNrIHJlcXVlc3QgZmFpbHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrKFJPT1QpLmdldCgnL2FwaS92Mi91c2VyL2NoZWNrQmF0Y2hpbmdQYXNzd29yZEZsb3cnKS5xdWVyeSh0cnVlKS5yZXBseSg1MDMsIHsgZXJyb3I6ICdzZXJ2aWNlIHVuYXZhaWxhYmxlJyB9KTtcblxuICAgICAgY29uc3QgbGVnYWN5U2NvcGUgPSBub2NrKFJPT1QpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YxL3VzZXIvY2hhbmdlcGFzc3dvcmQnLCAoYm9keTogYW55KSA9PiAhIWJvZHkua2V5Y2hhaW5zICYmICEhYm9keS52Ml9rZXljaGFpbnMpXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KTtcblxuICAgICAgYXdhaXQgYml0Z28uY2hhbmdlUGFzc3dvcmQoeyBvbGRQYXNzd29yZDogJ29sZHB3JywgbmV3UGFzc3dvcmQ6ICduZXdwdycgfSk7XG5cbiAgICAgIGxlZ2FjeVNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnZm9yd2FyZHMgZW5jcnlwdGlvblZlcnNpb24gdG8gYm90aCB2MSBhbmQgdjIga2V5Y2hhaW5zKCkudXBkYXRlUGFzc3dvcmQgY2FsbHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrKFJPT1QpLmdldCgnL2FwaS92Mi91c2VyL2NoZWNrQmF0Y2hpbmdQYXNzd29yZEZsb3cnKS5xdWVyeSh0cnVlKS5yZXBseSgyMDAsIHsgaXNCYXRjaGluZ0Zsb3dFbmFibGVkOiBmYWxzZSB9KTtcbiAgICAgIG5vY2soUk9PVClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjEvdXNlci9jaGFuZ2VwYXNzd29yZCcsIChib2R5OiBhbnkpID0+ICEhYm9keS5rZXljaGFpbnMgJiYgISFib2R5LnYyX2tleWNoYWlucylcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuXG4gICAgICBhd2FpdCBiaXRnby5jaGFuZ2VQYXNzd29yZCh7IG9sZFBhc3N3b3JkOiAnb2xkcHcnLCBuZXdQYXNzd29yZDogJ25ld3B3JywgZW5jcnlwdGlvblZlcnNpb246IDIgfSk7XG5cbiAgICAgIHNpbm9uLmFzc2VydC5jYWxsZWRXaXRoTWF0Y2godjFVcGRhdGVQYXNzd29yZFN0dWIsIHsgZW5jcnlwdGlvblZlcnNpb246IDIgfSk7XG4gICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkV2l0aE1hdGNoKHYyVXBkYXRlUGFzc3dvcmRTdHViLCB7IGVuY3J5cHRpb25WZXJzaW9uOiAyIH0pO1xuICAgIH0pO1xuICAgIGl0KCdzaGFyZXMgb25lIGVuY3J5cHRpb24gc2Vzc2lvbiBhY3Jvc3Mga2V5Y2hhaW4gcGFzc3dvcmQgdXBkYXRlcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soUk9PVCkuZ2V0KCcvYXBpL3YyL3VzZXIvY2hlY2tCYXRjaGluZ1Bhc3N3b3JkRmxvdycpLnF1ZXJ5KHRydWUpLnJlcGx5KDIwMCwgeyBpc0JhdGNoaW5nRmxvd0VuYWJsZWQ6IGZhbHNlIH0pO1xuICAgICAgbm9jayhST09UKVxuICAgICAgICAucG9zdCgnL2FwaS92MS91c2VyL2NoYW5nZXBhc3N3b3JkJywgKGJvZHk6IHVua25vd24pID0+IHtcbiAgICAgICAgICBpZiAoIWJvZHkgfHwgdHlwZW9mIGJvZHkgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiAna2V5Y2hhaW5zJyBpbiBib2R5ICYmICd2Ml9rZXljaGFpbnMnIGluIGJvZHk7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KTtcblxuICAgICAgY29uc3QgZGVzdHJveSA9IHNhbmRib3guc3R1YigpO1xuICAgICAgY29uc3Qgc2Vzc2lvbjogSUVuY3J5cHRpb25TZXNzaW9uID0ge1xuICAgICAgICBlbmNyeXB0OiBzYW5kYm94LnN0dWIoKS5yZXNvbHZlcygnc2Vzc2lvbi1lbmNyeXB0ZWQnKSxcbiAgICAgICAgZGVjcnlwdDogc2FuZGJveC5zdHViKCkucmVzb2x2ZXMoJ3Nlc3Npb24tZGVjcnlwdGVkJyksXG4gICAgICAgIGRlc3Ryb3ksXG4gICAgICB9O1xuICAgICAgY29uc3QgY3JlYXRlU2Vzc2lvbiA9IHNhbmRib3guc3R1YihiaXRnbywgJ2NyZWF0ZUVuY3J5cHRpb25TZXNzaW9uJykucmVzb2x2ZXMoc2Vzc2lvbik7XG5cbiAgICAgIGF3YWl0IGJpdGdvLmNoYW5nZVBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6ICdvbGRwdycsIG5ld1Bhc3N3b3JkOiAnbmV3cHcnLCBlbmNyeXB0aW9uVmVyc2lvbjogMiB9KTtcblxuICAgICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2UoY3JlYXRlU2Vzc2lvbik7XG4gICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkV2l0aEV4YWN0bHkoY3JlYXRlU2Vzc2lvbiwgJ25ld3B3JywgMik7XG4gICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkV2l0aE1hdGNoKHYxVXBkYXRlUGFzc3dvcmRTdHViLCB7XG4gICAgICAgIGVuY3J5cHRpb25WZXJzaW9uOiAyLFxuICAgICAgICBlbmNyeXB0aW9uU2Vzc2lvbjogc2Vzc2lvbixcbiAgICAgIH0pO1xuICAgICAgc2lub24uYXNzZXJ0LmNhbGxlZFdpdGhNYXRjaCh2MlVwZGF0ZVBhc3N3b3JkU3R1Yiwge1xuICAgICAgICBlbmNyeXB0aW9uVmVyc2lvbjogMixcbiAgICAgICAgZW5jcnlwdGlvblNlc3Npb246IHNlc3Npb24sXG4gICAgICB9KTtcbiAgICAgIHNpbm9uLmFzc2VydC5jYWxsZWRPbmNlKGRlc3Ryb3kpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY3JlYXRlVXNlckVjZGhLZXljaGFpbiAtIGVuY3J5cHRpb25WZXJzaW9uIHRocmVhZGluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBST09UID0gJ2h0dHBzOi8vYXBwLmJpdGdvLXRlc3QuY29tJztcbiAgICBsZXQgYml0Z286IEJpdEdvQVBJO1xuXG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBiaXRnbyA9IG5ldyBCaXRHb0FQSSh7IGVudjogJ3Rlc3QnIH0pO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdwYXNzZXMgZW5jcnlwdGlvblZlcnNpb246IDIgdG8gZW5jcnlwdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGVuY3J5cHRBc3luY1NweSA9IHNpbm9uLnNweShiaXRnbywgJ2VuY3J5cHQnKTtcbiAgICAgIG5vY2soUk9PVCkucG9zdCgnL2FwaS92MS9rZXljaGFpbicpLnJlcGx5KDIwMCwgeyB4cHViOiAneHB1YjEyMycsIGlkOiAna2V5LWlkJyB9KTtcblxuICAgICAgYXdhaXQgYml0Z28uY3JlYXRlVXNlckVjZGhLZXljaGFpbignbG9naW5QYXNzd29yZCcsIDIpO1xuXG4gICAgICBhc3NlcnQub2soZW5jcnlwdEFzeW5jU3B5LmNhbGxlZE9uY2UpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGVuY3J5cHRBc3luY1NweS5maXJzdENhbGwuYXJnc1swXS5lbmNyeXB0aW9uVmVyc2lvbiwgMik7XG4gICAgfSk7XG5cbiAgICBpdCgncGFzc2VzIGVuY3J5cHRpb25WZXJzaW9uOiB1bmRlZmluZWQgd2hlbiBub3Qgc2V0IChkZWZhdWx0cyB0byB2MSknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBlbmNyeXB0QXN5bmNTcHkgPSBzaW5vbi5zcHkoYml0Z28sICdlbmNyeXB0Jyk7XG4gICAgICBub2NrKFJPT1QpLnBvc3QoJy9hcGkvdjEva2V5Y2hhaW4nKS5yZXBseSgyMDAsIHsgeHB1YjogJ3hwdWIxMjMnLCBpZDogJ2tleS1pZCcgfSk7XG5cbiAgICAgIGF3YWl0IGJpdGdvLmNyZWF0ZVVzZXJFY2RoS2V5Y2hhaW4oJ2xvZ2luUGFzc3dvcmQnKTtcblxuICAgICAgYXNzZXJ0Lm9rKGVuY3J5cHRBc3luY1NweS5jYWxsZWRPbmNlKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChlbmNyeXB0QXN5bmNTcHkuZmlyc3RDYWxsLmFyZ3NbMF0uZW5jcnlwdGlvblZlcnNpb24sIHVuZGVmaW5lZCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzcGxpdFNlY3JldCAtIGVuY3J5cHRpb25WZXJzaW9uIHRocmVhZGluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgYml0Z286IEJpdEdvQVBJO1xuXG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBiaXRnbyA9IG5ldyBCaXRHb0FQSSh7IGVudjogJ3Rlc3QnIH0pO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdwYXNzZXMgZW5jcnlwdGlvblZlcnNpb246IDIgdG8gZXZlcnkgZW5jcnlwdCBzaGFyZCBjYWxsJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZW5jcnlwdEFzeW5jU3B5ID0gc2lub24uc3B5KGJpdGdvLCAnZW5jcnlwdCcpO1xuICAgICAgY29uc3QgcGFzc3dvcmRzID0gWydwdzEnLCAncHcyJywgJ3B3MyddO1xuXG4gICAgICBhd2FpdCBiaXRnby5zcGxpdFNlY3JldCh7XG4gICAgICAgIHNlZWQ6ICdhJy5yZXBlYXQoNjQpLFxuICAgICAgICBwYXNzd29yZHMsXG4gICAgICAgIG06IDIsXG4gICAgICAgIGVuY3J5cHRpb25WZXJzaW9uOiAyLFxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChlbmNyeXB0QXN5bmNTcHkuY2FsbENvdW50LCAzLCAnc2hvdWxkIGVuY3J5cHQgZWFjaCBzaGFyZCcpO1xuICAgICAgZm9yIChjb25zdCBjYWxsIG9mIGVuY3J5cHRBc3luY1NweS5nZXRDYWxscygpKSB7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChjYWxsLmFyZ3NbMF0uZW5jcnlwdGlvblZlcnNpb24sIDIpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Bhc3NlcyBlbmNyeXB0aW9uVmVyc2lvbjogdW5kZWZpbmVkIHdoZW4gbm90IHNldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGVuY3J5cHRBc3luY1NweSA9IHNpbm9uLnNweShiaXRnbywgJ2VuY3J5cHQnKTtcblxuICAgICAgYXdhaXQgYml0Z28uc3BsaXRTZWNyZXQoe1xuICAgICAgICBzZWVkOiAnYicucmVwZWF0KDY0KSxcbiAgICAgICAgcGFzc3dvcmRzOiBbJ3B3MScsICdwdzInXSxcbiAgICAgICAgbTogMixcbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZW5jcnlwdEFzeW5jU3B5LmNhbGxDb3VudCwgMik7XG4gICAgICBmb3IgKGNvbnN0IGNhbGwgb2YgZW5jcnlwdEFzeW5jU3B5LmdldENhbGxzKCkpIHtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGNhbGwuYXJnc1swXS5lbmNyeXB0aW9uVmVyc2lvbiwgdW5kZWZpbmVkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ3dhbGxldHMoKSB2MSBmYWNhZGUnLCBmdW5jdGlvbiAoKSB7XG4gIGl0KCdyZXR1cm5zIEJpdEdvQXBpVjFXYWxsZXRzIHdpdGggYml0Z28gcmVmZXJlbmNlIGFuZCBhbGwgcHJvdG90eXBlIG1ldGhvZHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgYml0Z28gPSBuZXcgQml0R29BUEkoeyBlbnY6ICd0ZXN0JyB9KTtcbiAgICBjb25zdCB3YWxsZXRzID0gYml0Z28ud2FsbGV0cygpO1xuICAgIHdhbGxldHMuYml0Z28uc2hvdWxkLmVxdWFsKGJpdGdvKTtcbiAgICB3YWxsZXRzLmxpc3Quc2hvdWxkLmJlLmEuRnVuY3Rpb24oKTtcbiAgICB3YWxsZXRzLmdldC5zaG91bGQuYmUuYS5GdW5jdGlvbigpO1xuICAgIHdhbGxldHMuZ2V0V2FsbGV0LnNob3VsZC5iZS5hLkZ1bmN0aW9uKCk7XG4gICAgd2FsbGV0cy5hZGQuc2hvdWxkLmJlLmEuRnVuY3Rpb24oKTtcbiAgICB3YWxsZXRzLnJlbW92ZS5zaG91bGQuYmUuYS5GdW5jdGlvbigpO1xuICAgIHdhbGxldHMuYWNjZXB0U2hhcmUuc2hvdWxkLmJlLmEuRnVuY3Rpb24oKTtcbiAgICB3YWxsZXRzLmNyZWF0ZVdhbGxldFdpdGhLZXljaGFpbnMuc2hvdWxkLmJlLmEuRnVuY3Rpb24oKTtcbiAgICB3YWxsZXRzLmNyZWF0ZUZvcndhcmRXYWxsZXQuc2hvdWxkLmJlLmEuRnVuY3Rpb24oKTtcbiAgICB3YWxsZXRzLmNyZWF0ZUtleS5zaG91bGQuYmUuYS5GdW5jdGlvbigpO1xuICAgIHdhbGxldHMubGlzdEludml0ZXMuc2hvdWxkLmJlLmEuRnVuY3Rpb24oKTtcbiAgICB3YWxsZXRzLmNhbmNlbEludml0ZS5zaG91bGQuYmUuYS5GdW5jdGlvbigpO1xuICAgIHdhbGxldHMubGlzdFNoYXJlcy5zaG91bGQuYmUuYS5GdW5jdGlvbigpO1xuICAgIHdhbGxldHMuZ2V0U2hhcmUuc2hvdWxkLmJlLmEuRnVuY3Rpb24oKTtcbiAgICB3YWxsZXRzLnVwZGF0ZVNoYXJlLnNob3VsZC5iZS5hLkZ1bmN0aW9uKCk7XG4gICAgd2FsbGV0cy5jYW5jZWxTaGFyZS5zaG91bGQuYmUuYS5GdW5jdGlvbigpO1xuICAgIHdhbGxldHMucmVzZW5kU2hhcmVJbnZpdGUuc2hvdWxkLmJlLmEuRnVuY3Rpb24oKTtcbiAgfSk7XG59KTtcbiJdfQ==