utxo-lib 1.1.1 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. package/README.md +16 -19
  2. package/dist/src/bitgo/PsbtUtil.d.ts +0 -5
  3. package/dist/src/bitgo/PsbtUtil.d.ts.map +1 -1
  4. package/dist/src/bitgo/PsbtUtil.js +2 -15
  5. package/dist/src/bitgo/UtxoPsbt.d.ts +0 -9
  6. package/dist/src/bitgo/UtxoPsbt.d.ts.map +1 -1
  7. package/dist/src/bitgo/UtxoPsbt.js +12 -42
  8. package/dist/src/bitgo/index.d.ts +0 -1
  9. package/dist/src/bitgo/index.d.ts.map +1 -1
  10. package/dist/src/bitgo/index.js +2 -3
  11. package/dist/src/bitgo/parseInput.js +2 -2
  12. package/dist/src/bitgo/wallet/Psbt.d.ts +0 -14
  13. package/dist/src/bitgo/wallet/Psbt.d.ts.map +1 -1
  14. package/dist/src/bitgo/wallet/Psbt.js +3 -71
  15. package/dist/src/bitgo/wallet/WalletOutput.d.ts +1 -17
  16. package/dist/src/bitgo/wallet/WalletOutput.d.ts.map +1 -1
  17. package/dist/src/bitgo/wallet/WalletOutput.js +23 -64
  18. package/dist/src/bitgo/wallet/chains.d.ts +1 -1
  19. package/dist/src/bitgo/zcash/ZcashPsbt.d.ts +1 -0
  20. package/dist/src/bitgo/zcash/ZcashPsbt.d.ts.map +1 -1
  21. package/dist/src/bitgo/zcash/ZcashPsbt.js +12 -3
  22. package/dist/src/testutil/keys.d.ts +0 -3
  23. package/dist/src/testutil/keys.d.ts.map +1 -1
  24. package/dist/src/testutil/keys.js +2 -17
  25. package/dist/src/testutil/psbt.d.ts +5 -23
  26. package/dist/src/testutil/psbt.d.ts.map +1 -1
  27. package/dist/src/testutil/psbt.js +13 -16
  28. package/dist/src/testutil/transaction.d.ts +5 -14
  29. package/dist/src/testutil/transaction.d.ts.map +1 -1
  30. package/dist/src/testutil/transaction.js +9 -9
  31. package/package.json +5 -5
  32. package/dist/src/base_crypto.d.ts +0 -14
  33. package/dist/src/base_crypto.d.ts.map +0 -1
  34. package/dist/src/base_crypto.js +0 -215
  35. package/dist/src/bitgo/legacysafe/index.d.ts +0 -15
  36. package/dist/src/bitgo/legacysafe/index.d.ts.map +0 -1
  37. package/dist/src/bitgo/legacysafe/index.js +0 -61
  38. package/dist/src/musig.d.ts +0 -390
  39. package/dist/src/musig.d.ts.map +0 -1
  40. package/dist/src/musig.js +0 -447
package/dist/src/musig.js DELETED
@@ -1,447 +0,0 @@
1
- "use strict";
2
- /* ! musig-js - MIT License (c) 2022 Brandon Black */
3
- // https://github.com/ElementsProject/secp256k1-zkp/blob/master/doc/musig-spec.mediawiki
4
- // Roughly based on the secp256k1-zkp implementation
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.MuSigFactory = void 0;
7
- const TAGS = {
8
- challenge: 'BIP0340/challenge',
9
- keyagg_list: 'KeyAgg list',
10
- keyagg_coef: 'KeyAgg coefficient',
11
- musig_aux: 'MuSig/aux',
12
- musig_nonce: 'MuSig/nonce',
13
- musig_deterministic_nonce: 'MuSig/deterministic/nonce',
14
- musig_noncecoef: 'MuSig/noncecoef',
15
- };
16
- /**
17
- * Compares two 32-byte Uint8Arrays in byte order.
18
- * @returns < 0, 0, > 0 if a is < b, === b or > b respectively
19
- */
20
- function compare32b(a, b) {
21
- if (a.length !== 32 || b.length !== 32)
22
- throw new Error('Invalid array');
23
- const aD = new DataView(a.buffer, a.byteOffset, a.length);
24
- const bD = new DataView(b.buffer, b.byteOffset, b.length);
25
- for (let i = 0; i < 8; i++) {
26
- const cmp = aD.getUint32(i * 4) - bD.getUint32(i * 4);
27
- if (cmp !== 0)
28
- return cmp;
29
- }
30
- return 0;
31
- }
32
- /**
33
- * Compares two 33-byte Uint8Arrays in byte order.
34
- * @returns < 0, 0, > 0 if a is < b, === b or > b respectively
35
- */
36
- function compare33b(a, b) {
37
- if (a.length !== 33 || b.length !== 33)
38
- throw new Error('Invalid array');
39
- const cmp = a[0] - b[0];
40
- if (cmp !== 0)
41
- return cmp;
42
- return compare32b(a.subarray(1), b.subarray(1));
43
- }
44
- const makeSessionId = typeof self === 'object' && (self.crypto || self.msCrypto)
45
- ? () => (self.crypto || self.msCrypto).getRandomValues(new Uint8Array(32)) // Browsers
46
- : () => require('crypto').randomBytes(32); // Node
47
- const _keyAggCache = new WeakMap();
48
- // Caches coefficients associated with an array of public keys
49
- const _coefCache = new WeakMap();
50
- // Caches secret nonces. We do this internally to help users ensure that they
51
- // do not reuse a secret nonce.
52
- const _nonceCache = new WeakMap();
53
- // Caches signing sessions. We do this internally to help users ensure that
54
- // these session values were generated on the signer, and are not accepted from
55
- // an untrusted third party.
56
- const _sessionCache = new WeakMap();
57
- function MuSigFactory(ecc) {
58
- const CPOINT_INF = new Uint8Array(33);
59
- const SCALAR_0 = new Uint8Array(32);
60
- const SCALAR_1 = new Uint8Array(32);
61
- SCALAR_1[31] = 1;
62
- const SCALAR_MINUS_1 = ecc.scalarNegate(SCALAR_1);
63
- function keyAggCoeff(publicKeys, publicKey) {
64
- let coefCache = _coefCache.get(publicKeys);
65
- if (coefCache === undefined) {
66
- coefCache = new Map();
67
- _coefCache.set(publicKeys, coefCache);
68
- }
69
- let coefficient = coefCache.get(publicKey);
70
- if (coefficient)
71
- return coefficient;
72
- coefficient = SCALAR_1;
73
- let secondPublicKey;
74
- let publicKeyHash;
75
- let keyAggCache = _keyAggCache.get(publicKeys);
76
- if (keyAggCache === undefined) {
77
- // Index of the first occurrence of the second unique public key.
78
- const pkIdx2 = publicKeys.findIndex((pk) => compare33b(pk, publicKeys[0]) !== 0);
79
- secondPublicKey = publicKeys[pkIdx2]; // undefined if pkIdx2 === -1
80
- publicKeyHash = ecc.taggedHash(TAGS.keyagg_list, ...publicKeys);
81
- keyAggCache = { publicKeyHash, secondPublicKey };
82
- _keyAggCache.set(publicKeys, keyAggCache);
83
- }
84
- else {
85
- ({ publicKeyHash, secondPublicKey } = keyAggCache);
86
- }
87
- if (secondPublicKey === undefined || compare33b(publicKey, secondPublicKey) !== 0) {
88
- coefficient = ecc.taggedHash(TAGS.keyagg_coef, publicKeyHash, publicKey);
89
- }
90
- coefCache.set(publicKey, coefficient);
91
- return coefficient;
92
- }
93
- function addTweak(ctx, t) {
94
- const tweak = 'tweak' in t ? t : { tweak: t };
95
- if (!ecc.isScalar(tweak.tweak))
96
- throw new TypeError('Expected tweak to be a valid scalar with curve order');
97
- let { gacc, tacc } = ctx;
98
- let aggPublicKey = ctx.aggPublicKey;
99
- if (!ecc.hasEvenY(aggPublicKey) && tweak.xOnly) {
100
- // g = -1
101
- gacc = ecc.scalarNegate(gacc); // g * gacc mod n
102
- tacc = ecc.scalarNegate(tacc); // g * tacc mod n
103
- aggPublicKey = ecc.pointNegate(aggPublicKey); // g * Q
104
- }
105
- aggPublicKey = ecc.pointAddTweak(aggPublicKey, tweak.tweak, false); // g * Q + t * G
106
- if (aggPublicKey === null)
107
- throw new Error('Unexpected point at infinity during tweaking');
108
- tacc = ecc.scalarAdd(tweak.tweak, tacc); // t + g * tacc mod n
109
- return { aggPublicKey, gacc, tacc };
110
- }
111
- function keyAgg(publicKeys, ...tweaks) {
112
- checkArgs({ publicKeys });
113
- const multipliedPublicKeys = publicKeys.map((publicKey) => {
114
- const coefficient = keyAggCoeff(publicKeys, publicKey);
115
- let multipliedPublicKey;
116
- if (compare32b(coefficient, SCALAR_1) === 0) {
117
- multipliedPublicKey = publicKey;
118
- }
119
- else {
120
- multipliedPublicKey = ecc.pointMultiplyUnsafe(publicKey, coefficient, false);
121
- }
122
- if (multipliedPublicKey === null)
123
- throw new Error('Point at infinity during aggregation');
124
- return multipliedPublicKey;
125
- });
126
- const aggPublicKey = multipliedPublicKeys.reduce((a, b) => {
127
- const next = ecc.pointAdd(a, b, false);
128
- if (next === null)
129
- throw new Error('Point at infinity during aggregation');
130
- return next;
131
- });
132
- return tweaks.reduce((ctx, tweak) => addTweak(ctx, tweak), {
133
- aggPublicKey,
134
- gacc: SCALAR_1,
135
- tacc: SCALAR_0,
136
- });
137
- }
138
- function getSessionValues(sessionKey) {
139
- const sessionValues = _sessionCache.get(sessionKey);
140
- if (!sessionValues)
141
- throw new Error('Invalid session key, please call `startSigningSession`');
142
- return sessionValues;
143
- }
144
- function nonceAgg(publicNonces) {
145
- checkArgs({ publicNonces });
146
- const aggNonces = [publicNonces[0].subarray(0, 33), publicNonces[0].subarray(33)];
147
- for (let i = 1; i < publicNonces.length; i++) {
148
- if (aggNonces[0] !== null)
149
- aggNonces[0] = ecc.pointAdd(aggNonces[0], publicNonces[i].subarray(0, 33), false);
150
- if (aggNonces[1] !== null)
151
- aggNonces[1] = ecc.pointAdd(aggNonces[1], publicNonces[i].subarray(33), false);
152
- }
153
- const aggNonce = new Uint8Array(66);
154
- if (aggNonces[0] !== null)
155
- aggNonce.set(ecc.pointCompress(aggNonces[0]), 0);
156
- if (aggNonces[1] !== null)
157
- aggNonce.set(ecc.pointCompress(aggNonces[1]), 33);
158
- return aggNonce;
159
- }
160
- function startSigningSessionInner(aggNonce, msg, publicKeys, ctx) {
161
- const pubKeyX = ecc.pointX(ctx.aggPublicKey);
162
- const coefficient = ecc.taggedHash(TAGS.musig_noncecoef, aggNonce, pubKeyX, msg);
163
- const aggNonces = [aggNonce.subarray(0, 33), aggNonce.subarray(33)];
164
- // This is kinda ugly, but crypto.pointAdd doesn't work on 0-coded infinity
165
- let r = null;
166
- if (compare33b(aggNonces[1], CPOINT_INF) !== 0 && compare33b(aggNonces[0], CPOINT_INF) !== 0) {
167
- r = ecc.pointMultiplyAndAddUnsafe(aggNonces[1], coefficient, aggNonces[0], false);
168
- }
169
- else if (compare33b(aggNonces[0], CPOINT_INF) !== 0) {
170
- r = ecc.pointCompress(aggNonces[0], false);
171
- }
172
- else if (compare33b(aggNonces[1], CPOINT_INF) !== 0) {
173
- r = ecc.pointMultiplyUnsafe(aggNonces[1], coefficient, false);
174
- }
175
- if (r === null)
176
- r = ecc.getPublicKey(SCALAR_1, false);
177
- if (r === null)
178
- throw new Error('Failed to get G');
179
- const challenge = ecc.scalarMod(ecc.taggedHash(TAGS.challenge, ecc.pointX(r), pubKeyX, msg));
180
- const key = { publicKey: ctx.aggPublicKey, aggNonce, msg };
181
- _sessionCache.set(key, { ...ctx, coefficient, challenge, finalNonce: r, publicKeys });
182
- return key;
183
- }
184
- function partialVerifyInner({ sig, publicKey, publicNonces, sessionKey, }) {
185
- const { msg } = sessionKey;
186
- const { aggPublicKey, gacc, challenge, coefficient, finalNonce, publicKeys } = getSessionValues(sessionKey);
187
- const rePrime = ecc.pointMultiplyAndAddUnsafe(publicNonces[1], coefficient, publicNonces[0], false);
188
- if (rePrime === null)
189
- throw new Error('Unexpected public nonce at infinity');
190
- const re = ecc.hasEvenY(finalNonce) ? rePrime : ecc.pointNegate(rePrime);
191
- const a = keyAggCoeff(publicKeys, publicKey);
192
- const g = ecc.hasEvenY(aggPublicKey) ? gacc : ecc.scalarNegate(gacc);
193
- const ea = ecc.scalarMultiply(challenge, a);
194
- const eag = ecc.scalarMultiply(ea, g);
195
- const ver = ecc.pointMultiplyAndAddUnsafe(publicKey, eag, re, true);
196
- if (ver === null)
197
- throw new Error('Unexpected verification point at infinity');
198
- const sG = ecc.getPublicKey(sig, true);
199
- if (sG === null)
200
- throw new Error('Unexpected signature point at infinity');
201
- return compare33b(ver, sG) === 0;
202
- }
203
- function partialSignInner({ secretKey, publicKey, secretNonces, sessionKey, }) {
204
- const { msg } = sessionKey;
205
- const { aggPublicKey, gacc, challenge, coefficient, finalNonce, publicKeys } = getSessionValues(sessionKey);
206
- const [k1, k2] = secretNonces.map((k) => (ecc.hasEvenY(finalNonce) ? k : ecc.scalarNegate(k)));
207
- const a = keyAggCoeff(publicKeys, publicKey);
208
- const g = ecc.hasEvenY(aggPublicKey) ? gacc : ecc.scalarNegate(gacc);
209
- const d = ecc.scalarMultiply(g, secretKey);
210
- const bk2 = ecc.scalarMultiply(coefficient, k2);
211
- const k1bk2 = ecc.scalarAdd(k1, bk2);
212
- const ea = ecc.scalarMultiply(challenge, a);
213
- const ead = ecc.scalarMultiply(ea, d);
214
- const sig = ecc.scalarAdd(k1bk2, ead);
215
- return sig;
216
- }
217
- function partialSign({ secretKey, publicNonce, sessionKey, verify = true, }) {
218
- checkArgs({ publicNonce, secretKey });
219
- const secretNonce = _nonceCache.get(publicNonce);
220
- if (secretNonce === undefined)
221
- throw new Error('No secret nonce found for specified public nonce');
222
- _nonceCache.delete(publicNonce);
223
- const publicKey = ecc.getPublicKey(secretKey, true);
224
- if (publicKey === null)
225
- throw new Error('Invalid secret key, no corresponding public key');
226
- if (compare33b(publicKey, secretNonce.subarray(64)) !== 0)
227
- throw new Error('Secret nonce pubkey mismatch');
228
- const secretNonces = [secretNonce.subarray(0, 32), secretNonce.subarray(32, 64)];
229
- const sig = partialSignInner({
230
- secretKey,
231
- publicKey,
232
- secretNonces,
233
- sessionKey,
234
- });
235
- if (verify) {
236
- const publicNonces = [publicNonce.subarray(0, 33), publicNonce.subarray(33)];
237
- const valid = partialVerifyInner({
238
- sig,
239
- publicKey,
240
- publicNonces,
241
- sessionKey,
242
- });
243
- if (!valid)
244
- throw new Error('Partial signature failed verification');
245
- }
246
- return sig;
247
- }
248
- function deterministicSign({ secretKey, aggOtherNonce, publicKeys, tweaks = [], msg, rand, verify = true, nonceOnly = false, }) {
249
- // No need to check msg, its max size is larger than JS typed array limit
250
- checkArgs({ rand, secretKey, aggOtherNonce });
251
- const publicKey = ecc.getPublicKey(secretKey, true);
252
- if (publicKey === null)
253
- throw new Error('Secret key has no corresponding public key');
254
- let secretKeyPrime;
255
- if (rand !== undefined) {
256
- secretKeyPrime = ecc.taggedHash(TAGS.musig_aux, rand);
257
- for (let i = 0; i < 32; i++) {
258
- secretKeyPrime[i] = secretKeyPrime[i] ^ secretKey[i];
259
- }
260
- }
261
- else {
262
- secretKeyPrime = secretKey;
263
- }
264
- const ctx = keyAgg(publicKeys, ...tweaks);
265
- const aggPublicKey = ecc.pointX(ctx.aggPublicKey);
266
- const mLength = new Uint8Array(8);
267
- new DataView(mLength.buffer).setBigUint64(0, BigInt(msg.length));
268
- const secretNonce = new Uint8Array(97);
269
- const publicNonce = new Uint8Array(66);
270
- for (let i = 0; i < 2; i++) {
271
- const kH = ecc.taggedHash(TAGS.musig_deterministic_nonce, ...[secretKeyPrime, aggOtherNonce, aggPublicKey, mLength, msg, Uint8Array.of(i)]);
272
- const k = ecc.scalarMod(kH);
273
- if (compare32b(SCALAR_0, k) === 0)
274
- throw new Error('0 secret nonce');
275
- const pub = ecc.getPublicKey(k, true);
276
- if (pub === null)
277
- throw new Error('Secret nonce has no corresponding public nonce');
278
- secretNonce.set(k, i * 32);
279
- publicNonce.set(pub, i * 33);
280
- }
281
- secretNonce.set(publicKey, 64);
282
- if (nonceOnly)
283
- return { publicNonce };
284
- _nonceCache.set(publicNonce, secretNonce);
285
- const aggNonce = nonceAgg([aggOtherNonce, publicNonce]);
286
- const sessionKey = startSigningSessionInner(aggNonce, msg, publicKeys, ctx);
287
- const sig = partialSign({
288
- secretKey,
289
- publicNonce,
290
- sessionKey,
291
- verify,
292
- });
293
- return { sig, sessionKey, publicNonce };
294
- }
295
- // TODO: Improve arg checking now that we have startSigningSession
296
- const pubKeyArgs = ['publicKey', 'publicKeys'];
297
- const scalarArgs = ['tweak', 'sig', 'sigs', 'tacc', 'gacc'];
298
- const otherArgs32b = ['xOnlyPublicKey', 'rand', 'sessionId'];
299
- const args32b = ['secretKey', ...scalarArgs, ...otherArgs32b];
300
- const pubNonceArgs = ['publicNonce', 'publicNonces', 'aggNonce', 'aggOtherNonce', 'finalNonce'];
301
- const otherArgs = ['aggPublicKey', 'secretNonce'];
302
- const argLengths = new Map();
303
- args32b.forEach((a) => argLengths.set(a, 32));
304
- pubKeyArgs.forEach((a) => argLengths.set(a, 33));
305
- pubNonceArgs.forEach((a) => argLengths.set(a, 66));
306
- argLengths.set('secretNonce', 97);
307
- argLengths.set('aggPublicKey', 65);
308
- const scalarNames = new Set();
309
- scalarArgs.forEach((n) => scalarNames.add(n));
310
- function checkArgs(args) {
311
- for (let [name, values] of Object.entries(args)) {
312
- if (values === undefined)
313
- continue;
314
- values = Array.isArray(values) ? values : [values];
315
- if (values.length === 0)
316
- throw new TypeError(`0-length ${name}s not supported`);
317
- for (const value of values) {
318
- if (argLengths.get(name) !== value.length)
319
- throw new TypeError(`Invalid ${name} length (${value.length})`);
320
- if (name === 'secretKey') {
321
- if (!ecc.isSecret(value))
322
- throw new TypeError(`Invalid secretKey`);
323
- }
324
- else if (name === 'secretNonce') {
325
- for (let i = 0; i < 64; i += 32) {
326
- if (!ecc.isSecret(value.subarray(i, i + 32)))
327
- throw new TypeError(`Invalid secretNonce`);
328
- }
329
- }
330
- else if (scalarNames.has(name)) {
331
- for (let i = 0; i < value.length; i += 32) {
332
- if (!ecc.isScalar(value.subarray(i, i + 32)))
333
- throw new TypeError(`Invalid ${name}`);
334
- }
335
- }
336
- // No need for a public key x-to-curve check. They're liftX'd for use any way.
337
- }
338
- }
339
- }
340
- return {
341
- getXOnlyPubkey: (ctx) => {
342
- if ('aggPublicKey' in ctx)
343
- return ecc.pointX(ctx.aggPublicKey);
344
- return ecc.pointX(getSessionValues(ctx).aggPublicKey);
345
- },
346
- getPlainPubkey: (ctx) => {
347
- if ('aggPublicKey' in ctx)
348
- return ecc.pointCompress(ctx.aggPublicKey);
349
- return ecc.pointCompress(getSessionValues(ctx).aggPublicKey);
350
- },
351
- keySort: (publicKeys) => {
352
- checkArgs({ publicKeys });
353
- // do not modify the original array
354
- return [...publicKeys].sort((a, b) => compare33b(a, b));
355
- },
356
- keyAgg,
357
- addTweaks: (ctx, ...tweaks) => {
358
- checkArgs(ctx);
359
- return tweaks.reduce((c, tweak) => addTweak(c, tweak), ctx);
360
- },
361
- nonceGen: ({ sessionId = makeSessionId(), secretKey, publicKey, xOnlyPublicKey, msg, extraInput, }) => {
362
- if (extraInput !== undefined && extraInput.length > Math.pow(2, 32) - 1) {
363
- throw new TypeError('extraInput is limited to 2^32-1 bytes');
364
- }
365
- // No need to check msg, its max size is larger than JS typed array limit
366
- checkArgs({ sessionId, secretKey, publicKey, xOnlyPublicKey });
367
- let rand;
368
- if (secretKey !== undefined) {
369
- rand = ecc.taggedHash(TAGS.musig_aux, sessionId);
370
- for (let i = 0; i < 32; i++) {
371
- rand[i] = rand[i] ^ secretKey[i];
372
- }
373
- }
374
- else {
375
- rand = sessionId;
376
- }
377
- if (xOnlyPublicKey === undefined)
378
- xOnlyPublicKey = new Uint8Array();
379
- const mPrefixed = [Uint8Array.of(0)];
380
- if (msg !== undefined) {
381
- mPrefixed[0][0] = 1;
382
- mPrefixed.push(new Uint8Array(8));
383
- new DataView(mPrefixed[1].buffer).setBigUint64(0, BigInt(msg.length));
384
- mPrefixed.push(msg);
385
- }
386
- if (extraInput === undefined)
387
- extraInput = new Uint8Array();
388
- const eLength = new Uint8Array(4);
389
- new DataView(eLength.buffer).setUint32(0, extraInput.length);
390
- const secretNonce = new Uint8Array(97);
391
- const publicNonce = new Uint8Array(66);
392
- for (let i = 0; i < 2; i++) {
393
- const kH = ecc.taggedHash(TAGS.musig_nonce, rand, Uint8Array.of(publicKey.length), publicKey, Uint8Array.of(xOnlyPublicKey.length), xOnlyPublicKey, ...mPrefixed, eLength, extraInput, Uint8Array.of(i));
394
- const k = ecc.scalarMod(kH);
395
- if (compare32b(SCALAR_0, k) === 0)
396
- throw new Error('0 secret nonce');
397
- const pub = ecc.getPublicKey(k, true);
398
- if (pub === null)
399
- throw new Error('Secret nonce has no corresponding public nonce');
400
- secretNonce.set(k, i * 32);
401
- publicNonce.set(pub, i * 33);
402
- }
403
- secretNonce.set(publicKey, 64);
404
- _nonceCache.set(publicNonce, secretNonce);
405
- return publicNonce;
406
- },
407
- addExternalNonce: (publicNonce, secretNonce) => {
408
- checkArgs({ publicNonce, secretNonce });
409
- _nonceCache.set(publicNonce, secretNonce);
410
- },
411
- deterministicNonceGen: (args) => deterministicSign({ ...args, nonceOnly: true }),
412
- deterministicSign,
413
- nonceAgg,
414
- startSigningSession: (aggNonce, msg, publicKeys, ...tweaks) => {
415
- checkArgs({ aggNonce });
416
- const ctx = keyAgg(publicKeys, ...tweaks);
417
- return startSigningSessionInner(aggNonce, msg, publicKeys, ctx);
418
- },
419
- partialSign,
420
- partialVerify: ({ sig, publicKey, publicNonce, sessionKey, }) => {
421
- checkArgs({ sig, publicKey, publicNonce });
422
- const publicNonces = [publicNonce.subarray(0, 33), publicNonce.subarray(33)];
423
- const valid = partialVerifyInner({
424
- sig,
425
- publicKey,
426
- publicNonces,
427
- sessionKey,
428
- });
429
- return valid;
430
- },
431
- signAgg: (sigs, sessionKey) => {
432
- checkArgs({ sigs });
433
- const { aggPublicKey, tacc, challenge, finalNonce } = getSessionValues(sessionKey);
434
- let sPart = ecc.scalarMultiply(challenge, tacc);
435
- if (!ecc.hasEvenY(aggPublicKey)) {
436
- sPart = ecc.scalarNegate(sPart);
437
- }
438
- const aggS = sigs.reduce((a, b) => ecc.scalarAdd(a, b), sPart);
439
- const sig = new Uint8Array(64);
440
- sig.set(ecc.pointX(finalNonce), 0);
441
- sig.set(aggS, 32);
442
- return sig;
443
- },
444
- };
445
- }
446
- exports.MuSigFactory = MuSigFactory;
447
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVzaWcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbXVzaWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHFEQUFxRDtBQUNyRCx3RkFBd0Y7QUFDeEYsb0RBQW9EOzs7QUFrYnBELE1BQU0sSUFBSSxHQUFHO0lBQ1gsU0FBUyxFQUFFLG1CQUFtQjtJQUM5QixXQUFXLEVBQUUsYUFBYTtJQUMxQixXQUFXLEVBQUUsb0JBQW9CO0lBQ2pDLFNBQVMsRUFBRSxXQUFXO0lBQ3RCLFdBQVcsRUFBRSxhQUFhO0lBQzFCLHlCQUF5QixFQUFFLDJCQUEyQjtJQUN0RCxlQUFlLEVBQUUsaUJBQWlCO0NBQzFCLENBQUM7QUFFWDs7O0dBR0c7QUFDSCxTQUFTLFVBQVUsQ0FBQyxDQUFhLEVBQUUsQ0FBYTtJQUM5QyxJQUFJLENBQUMsQ0FBQyxNQUFNLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxNQUFNLEtBQUssRUFBRTtRQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDekUsTUFBTSxFQUFFLEdBQUcsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxRCxNQUFNLEVBQUUsR0FBRyxJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzFELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDMUIsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDdEQsSUFBSSxHQUFHLEtBQUssQ0FBQztZQUFF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QUFZLEVBQUUsQ0FBQyxDQUFDO1FBRTVCLE1BQU0sU0FBUyxHQUE2QixDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1RyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUM1QyxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO2dCQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUM3RyxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO2dCQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQzNHO1FBQ0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDcEMsSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSTtZQUFFLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1RSxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQUUsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxD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SSxDQUFDLENBQUM7WUFDNUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLEVBQUU7Z0JBQy9CLEtBQUssR0FBRyxHQUFHLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQ2pDO1lBQ0QsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQy9ELE1BQU0sR0FBRyxHQUFHLElBQUksVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQy9CLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNuQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNsQixPQUFPLEdBQUcsQ0FBQztRQUNiLENBQUM7S0FDRixDQUFDO0FBQ0osQ0FBQztBQXBoQkQsb0NBb2hCQyIsInNvdXJjZXNDb250ZW50IjpbIi8qICEgbXVzaWctanMgLSBNSVQgTGljZW5zZSAoYykgMjAyMiBCcmFuZG9uIEJsYWNrICovXG4vLyBodHRwczovL2dpdGh1Yi5jb20vRWxlbWVudHNQcm9qZWN0L3NlY3AyNTZrMS16a3AvYmxvYi9tYXN0ZXIvZG9jL211c2lnLXNwZWMubWVkaWF3aWtpXG4vLyBSb3VnaGx5IGJhc2VkIG9uIHRoZSBzZWNwMjU2azEtemtwIGltcGxlbWVudGF0aW9uXG5cbmV4cG9ydCBpbnRlcmZhY2UgTXVTaWcge1xuICAvKipcbiAgICogR2V0cyB0aGUgWC1vbmx5IHB1YmxpYyBrZXkgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29udGV4dC5cbiAgICpcbiAgICogQHBhcmFtIGN0eCB0aGUga2V5IGdlbiBjb250ZXh0IG9yIGEgc2lnbmluZyBzZXNzaW9uIGtleVxuICAgKiBAcmV0dXJucyB0aGUgWC1vbmx5IHB1YmxpYyBrZXkgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29udGV4dFxuICAgKi9cbiAgZ2V0WE9ubHlQdWJrZXkoY3R4OiBLZXlHZW5Db250ZXh0IHwgU2Vzc2lvbktleSk6IFVpbnQ4QXJyYXk7XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHBsYWluIHB1YmxpYyBrZXkgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29udGV4dC5cbiAgICpcbiAgICogQHBhcmFtIGN0eCB0aGUga2V5IGdlbiBjb250ZXh0IG9yIGEgc2lnbmluZyBzZXNzaW9uIGtleVxuICAgKiBAcmV0dXJucyBwbGFpbiBwdWJsaWMga2V5IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGNvbnRleHQgaW4gY29tcHJlc3NlZCBERVIgZm9ybWF0XG4gICAqL1xuICBnZXRQbGFpblB1YmtleShjdHg6IEtleUdlbkNvbnRleHQgfCBTZXNzaW9uS2V5KTogVWludDhBcnJheTtcblxuICAvKipcbiAgICogU29ydHMgY29tcHJlc3NlZCBERVIgZm9ybWF0IHB1YmxpYyBrZXlzIGxleGljb2dyYXBoaWNhbGx5LlxuICAgKlxuICAgKiBAcGFyYW0gcHVibGljS2V5cyBhcnJheSBvZiBjb21wcmVzc2VkIERFUiBlbmNvZGVkIHB1YmxpYyBrZXlzIHRvIGFnZ3JlZ2F0ZVxuICAgKiBAcmV0dXJucyBzb3J0ZWQgcHVibGljIGtleXMgKGluIGEgbmV3IGFycmF5KVxuICAgKi9cbiAga2V5U29ydChwdWJsaWNLZXlzOiBVaW50OEFycmF5W10pOiBVaW50OEFycmF5W107XG5cbiAgLyoqXG4gICAqIFBlcmZvcm1zIE11U2lnIGtleSBhZ2dyZWdhdGlvbiBvbiAxKyB4LW9ubHkgcHVibGljIGtleXMuXG4gICAqXG4gICAqIEBwYXJhbSBwdWJsaWNLZXlzIGFycmF5IG9mIGNvbXByZXNzZWQgREVSIGVuY29kZWQgcHVibGljIGtleXMgdG8gYWdncmVnYXRlXG4gICAqIEBwYXJhbSB0d2Vha3MgdHdlYWtzICgwIDwgdHdlYWsgPCBuKSB0byBhcHBseSB0byB0aGUgYWdncmVnYXRlIGtleSxcbiAgICogYW5kIG9wdGlvbmFsbHkgYm9vbGVhbnMgdG8gaW5kaWNhdGUgeC1vbmx5IHR3ZWFraW5nXG4gICAqIEByZXR1cm5zIGFuIG9wYXF1ZSBrZXkgZ2VuIGNvbnRleHQgZm9yIHVzZSB3aXRoIG90aGVyIE11U2lnIG9wZXJhdGlvbnNcbiAgICovXG4gIGtleUFnZyhwdWJsaWNLZXlzOiBVaW50OEFycmF5W10sIC4uLnR3ZWFrczogVHdlYWtbXSk6IEtleUdlbkNvbnRleHQ7XG5cbiAgLyoqXG4gICAqIEFwcGx5IG9uZSBvciBtb3JlIHgtb25seSBvciBvcmRpbmFyeSB0d2Vha3MgdG8gYW4gYWdncmVnYXRlIHB1YmxpYyBrZXkuXG4gICAqXG4gICAqIEBwYXJhbSBjdHggdGhlIGtleSBnZW5lcmF0aW9uIGNvbnRleHQsIGFzIHJldHVybmVkIGZyb20gYGtleUFnZ2AuXG4gICAqIEBwYXJhbSB0d2Vha3MgdHdlYWtzICgwIDwgdHdlYWsgPCBuKSB0byBhcHBseSB0byB0aGUgYWdncmVnYXRlIGtleSxcbiAgICogYW5kIG9wdGlvbmFsbHkgYm9vbGVhbnMgdG8gaW5kaWNhdGUgeC1vbmx5IHR3ZWFraW5nXG4gICAqIEByZXR1cm5zIGFuIG9wYXF1ZSBrZXkgZ2VuIGNvbnRleHQgZm9yIHVzZSB3aXRoIG90aGVyIE11U2lnIG9wZXJhdGlvbnNcbiAgICovXG4gIGFkZFR3ZWFrcyhjdHg6IEtleUdlbkNvbnRleHQsIC4uLnR3ZWFrczogVHdlYWtbXSk6IEtleUdlbkNvbnRleHQ7XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIGEgTXVTaWcgbm9uY2UgcGFpciBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgdmFsdWVzLlxuICAgKlxuICAgKiBUaGUgY2FsbGVyIG11c3Qgbm90IHVzZSB0aGUgc2FtZSBzZXNzaW9uSWQgZm9yIG11bHRpcGxlIGNhbGxzIHRvIG5vbmNlR2VuXG4gICAqIHdpdGggb3RoZXIgcGFyYW1ldGVycyBoZWxkIGNvbnN0YW50LlxuICAgKlxuICAgKiBUaGUgc2VjcmV0IG5vbmNlICg5NyBieXRlcykgaXMgY2FjaGVkIGludGVybmFsbHksIGFuZCB3aWxsIGJlIGRlbGV0ZWRcbiAgICogZnJvbSB0aGUgY2FjaGUgcHJpb3IgdG8gdXNlIGluIGEgc2lnbmF0dXJlLiBUaGUgc2VjcmV0IG5vbmNlIHdpbGwgYWxzbyBiZVxuICAgKiBkZWxldGVkIGlmIHRoZSByZXR1cm5lZCBwdWJsaWMgbm9uY2UgaXMgZGVsZXRlZC5cbiAgICpcbiAgICogQHBhcmFtIHNlc3Npb25JZCBpZiBubyBzZWNyZXQga2V5IGlzIHByb3ZpZGVkLCB1bmlmb3JtbHkgMzItYnl0ZXMgb2ZcbiAgICogcmFuZG9tIGRhdGEsIG90aGVyd2lzZSBhIHZhbHVlIGd1YXJhbnRlZWQgbm90IHRvIHJlcGVhdCBmb3IgdGhlIHNlY3JldFxuICAgKiBrZXkuIElmIG5vIHNlc3Npb25JZCBpcyBwcm92aWRlZCBhIHJlYXNvbmFibHkgaGlnaCBxdWFsaXR5IHJhbmRvbSBvbmUgd2lsbFxuICAgKiBiZSBnZW5lcmF0ZWQuXG4gICAqIEBwYXJhbSBzZWNyZXRLZXkgdGhlIHNlY3JldCBrZXkgd2hpY2ggd2lsbCBldmVudHVhbGx5IHNpZ24gd2l0aCB0aGlzIG5vbmNlXG4gICAqIEBwYXJhbSBwdWJsaWNLZXkgdGhlIHB1YmxpYyBrZXkgZm9yIHdoaWNoIHRoaXMgbm9uY2Ugd2lsbCBiZSBzaWduZWQgKHJlcXVpcmVkKVxuICAgKiBAcGFyYW0geE9ubHlQdWJsaWNLZXkgdGhlIHgtY29vcmRpbmF0ZSBvZiB0aGUgYWdncmVnYXRlIHB1YmxpYyBrZXkgdGhhdCB0aGlzXG4gICAqIG5vbmNlIHdpbGwgYmUgc2lnbmluZyBhIHBhcnQgb2ZcbiAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSB3aGljaCB3aWxsIGV2ZW50dWFsbHkgYmUgc2lnbmVkIHdpdGggdGhpcyBub25jZVxuICAgKiAoYW55IHBvc3NpYmxlIFVpbnQ4QXJyYXkgbGVuZ3RoKVxuICAgKiBAcGFyYW0gZXh0cmFJbnB1dCBhZGRpdGlvbmFsIGlucHV0IHdoaWNoIHdpbGwgY29udHJpYnV0ZSB0byB0aGUgZ2VuZXJhdGVkXG4gICAqIG5vbmNlICgwIDw9IGV4dHJhSW5wdXQubGVuZ3RoIDw9IDJeMzItMSlcbiAgICogQHJldHVybiB0aGUgZ2VuZXJhdGVkIHB1YmxpYyBub25jZSAoNjYgYnl0ZXMpXG4gICAqL1xuICBub25jZUdlbihhcmdzOiB7XG4gICAgc2Vzc2lvbklkPzogVWludDhBcnJheTtcbiAgICBzZWNyZXRLZXk/OiBVaW50OEFycmF5O1xuICAgIHB1YmxpY0tleTogVWludDhBcnJheTtcbiAgICB4T25seVB1YmxpY0tleT86IFVpbnQ4QXJyYXk7XG4gICAgbXNnPzogVWludDhBcnJheTtcbiAgICBleHRyYUlucHV0PzogVWludDhBcnJheTtcbiAgfSk6IFVpbnQ4QXJyYXk7XG5cbiAgLyoqXG4gICAqIEFkZCBhbiBleHRlcm5hbGx5IGdlbmVyYXRlZCBub25jZSB0byB0aGUgY2FjaGUuXG4gICAqXG4gICAqIE5PVCBSRUNPTU1FTkRFRCwgYnV0IHVzZWZ1bCBpbiB0ZXN0aW5nIGF0IGxlYXN0LlxuICAgKiBAcGFyYW0gcHVibGljTm9uY2UgNjYtYnl0ZSBwdWJsaWMgbm9uY2UgKDIgcG9pbnRzIGluIGNvbXByZXNzZWQgREVSKVxuICAgKiBAcGFyYW0gc2VjcmV0Tm9uY2UgOTctYnl0ZSBzZWNyZXQgbm9uY2UgKDIgMzItYnl0ZSBzY2FsYXJzLCBhbmQgdGhlIHB1YmxpY1xuICAgKiBrZXkgd2hpY2ggd2lsbCBzaWduIGZvciB0aGlzIG5vbmNlIGluIGNvbXByZXNzZWQgREVSKVxuICAgKi9cbiAgYWRkRXh0ZXJuYWxOb25jZShwdWJsaWNOb25jZTogVWludDhBcnJheSwgc2VjcmV0Tm9uY2U6IFVpbnQ4QXJyYXkpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBDb21iaW5lIHB1YmxpYyBub25jZXMgZnJvbSBhbGwgc2lnbmVycyBpbnRvIGEgc2luZ2xlIGFnZ3JlZ2F0ZSBwdWJsaWMgbm9uY2UuXG4gICAqXG4gICAqIFBlciB0aGUgc3BlYywgdGhpcyBmdW5jdGlvbiBwcmVmZXJzIHRvIHN1Y2NlZWQgd2l0aCBhbiBpbnZhbGlkIG5vbmNlIGF0XG4gICAqIGluZmluaXR5IHRoYW4gdG8gZmFpbCwgdG8gZW5hYmxlIGEgZGlzaG9uZXN0IHNpZ25lciB0byBiZSBkZXRlY3RlZCBsYXRlci5cbiAgICpcbiAgICogVGhpcyBjYW4gYmUgcnVuIGJ5IGFuIHVudHJ1c3RlZCBub2RlIHdpdGhvdXQgYnJlYWtpbmcgdGhlIHNlY3VyaXR5IG9mIHRoZVxuICAgKiBwcm90b2NvbC4gQW4gdW50cnVzdGVkIGFnZ3JlZ2F0b3IgY2FuIGNhdXNlIHRoZSBwcm90b2NvbCB0byBmYWlsLCBidXQgbm90XG4gICAqIGZvcmdlIGEgc2lnbmF0dXJlLlxuICAgKlxuICAgKiBAcGFyYW0gbm9uY2VzIG4tc2lnbmVycyBwdWJsaWMgbm9uY2VzICg2Ni1ieXRlcyBlYWNoKVxuICAgKiBAcmV0dXJuIHRoZSBhZ2dyZWdhdGUgcHVibGljIG5vbmNlICg2Ni1ieXRlcylcbiAgICovXG4gIG5vbmNlQWdnKG5vbmNlczogVWludDhBcnJheVtdKTogVWludDhBcnJheTtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBvcGFxdWUgc2lnbmluZyBzZXNzaW9uIGZvciB1c2VkIGluIHBhcnRpYWwgc2lnbmluZywgcGFydGlhbFxuICAgKiB2ZXJpZmljYXRpb24sIG9yIHNpZ25hdHVyZSBhZ2dyZWdhdGlvbi4gVGhpcyBtYXkgYmUgc2F2ZWQgYnkgYVxuICAgKiBwYXJ0aWNpcGFudCwgYnV0IG1heSBub3QgYmUgcHJvdmlkZWQgYnkgYW4gdW50cnVzdGVkIHBhcnR5LlxuICAgKlxuICAgKiBAcGFyYW0gYWdnTm9uY2UgdGhpcyBzaWduaW5nIHNlc3Npb24ncyBhZ2dyZWdhdGUgbm9uY2VcbiAgICogQHBhcmFtIG1zZyB0aGUgMzItYnl0ZSBtZXNzYWdlIHRvIHNpZ24gZm9yLCBtb3N0IGNvbW1vbmx5IGEgdHJhbnNhY3Rpb24gaGFzaC5cbiAgICogQHBhcmFtIHB1YmxpY0tleXMgYXJyYXkgb2YgY29tcHJlc3NlZCBERVIgZW5jb2RlZCBwdWJsaWMga2V5cyB0byBhZ2dyZWdhdGVcbiAgICogQHBhcmFtIHR3ZWFrcyB0d2Vha3MgKDAgPCB0d2VhayA8IG4pIHRvIGFwcGx5IHRvIHRoZSBhZ2dyZWdhdGUga2V5LFxuICAgKiBhbmQgb3B0aW9uYWxseSBib29sZWFucyB0byBpbmRpY2F0ZSB4LW9ubHkgdHdlYWtpbmdcbiAgICogQHJldHVybiBzZXNzaW9uIGtleSBmb3IgYHBhcnRpYWxTaWduYCwgYHBhcnRpYWxWZXJpZnlgIGFuZCBgc2lnbkFnZ2BcbiAgICovXG4gIHN0YXJ0U2lnbmluZ1Nlc3Npb24oYWdnTm9uY2U6IFVpbnQ4QXJyYXksIG1zZzogVWludDhBcnJheSwgcHVibGljS2V5czogVWludDhBcnJheVtdLCAuLi50d2Vha3M6IFR3ZWFrW10pOiBTZXNzaW9uS2V5O1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgTXVTaWcgcGFydGlhbCBzaWduYXR1cmUgZm9yIHRoZSBnaXZlbiB2YWx1ZXMuXG4gICAqXG4gICAqIFZlcmlmaWVzIHRoZSByZXN1bHRpbmcgcGFydGlhbCBzaWduYXR1cmUgYnkgZGVmYXVsdCwgYXMgcmVjb21tZW5kZWQgaW4gdGhlXG4gICAqIHNwZWNpZmljYXRpb24uXG4gICAqXG4gICAqIE5vdGU6IENhbGxpbmcgYHBhcnRpYWxTaWduYCB3aXRoIHRoZSBzYW1lIGBwdWJsaWNOb25jZWAgbW9yZSB0aGFuIG9uY2VcbiAgICogd2lsbCBub3Qgd29yaywgYXMgdGhlIGNvcnJlc3BvbmRpbmcgc2VjcmV0IG5vbmNlIGlzIGRlbGV0ZWQuIEdlbmVyYXRlIGFcbiAgICogbmV3IHB1YmxpYyBub25jZSBhbmQgdHJ5IGFnYWluLlxuICAgKlxuICAgKiBAcGFyYW0gc2VjcmV0S2V5IHNpZ25lcidzIHNlY3JldCBrZXlcbiAgICogQHBhcmFtIHB1YmxpY05vbmNlIHNpZ25lcidzIHB1YmxpYyBub25jZVxuICAgKiBAcGFyYW0gc2Vzc2lvbktleSBzaWduaW5nIHNlc3Npb24ga2V5IChmcm9tIHN0YXJ0U2lnbmluZ1Nlc3Npb24pXG4gICAqIEBwYXJhbSB2ZXJpZnkgaWYgZmFsc2UsIGRvbid0IHZlcmlmeSBwYXJ0aWFsIHNpZ25hdHVyZVxuICAgKiBAcmV0dXJuIHJlc3VsdGluZyBzaWduYXR1cmVcbiAgICovXG4gIHBhcnRpYWxTaWduKGFyZ3M6IHtcbiAgICBzZWNyZXRLZXk6IFVpbnQ4QXJyYXk7XG4gICAgcHVibGljTm9uY2U6IFVpbnQ4QXJyYXk7XG4gICAgc2Vzc2lvbktleTogU2Vzc2lvbktleTtcbiAgICB2ZXJpZnk/OiBib29sZWFuO1xuICB9KTogVWludDhBcnJheTtcblxuICAvKipcbiAgICogVmVyaWZpZXMgYSBNdVNpZyBwYXJ0aWFsIHNpZ25hdHVyZSBmb3IgdGhlIGdpdmVuIHZhbHVlcy5cbiAgICpcbiAgICogQHBhcmFtIHNpZyB0aGUgMzItYnl0ZSBNdVNpZyBwYXJ0aWFsIHNpZ25hdHVyZSB0byB2ZXJpZnlcbiAgICogQHBhcmFtIG1zZyB0aGUgMzItYnl0ZSBtZXNzYWdlIHRvIHNpZ24gZm9yLCBtb3N0IGNvbW1vbmx5IGEgdHJhbnNhY3Rpb24gaGFzaFxuICAgKiBAcGFyYW0gcHVibGljS2V5IHNpZ25lcidzIHB1YmxpYyBrZXlcbiAgICogQHBhcmFtIHB1YmxpY05vbmNlIHNpZ25lcidzIHB1YmxpYyBub25jZVxuICAgKiBAcGFyYW0gYWdnTm9uY2UgdGhpcyBzaWduaW5nIHNlc3Npb24ncyBhZ2dyZWdhdGUgbm9uY2VcbiAgICogQHBhcmFtIHNlc3Npb25LZXkgc2lnbmluZyBzZXNzaW9uIGtleSAoZnJvbSBzdGFydFNpZ25pbmdTZXNzaW9uKVxuICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHBhcnRpYWwgc2lnbmF0dXJlIGlzIHZhbGlkLCBvdGhlcndpc2UgZmFsc2VcbiAgICovXG4gIHBhcnRpYWxWZXJpZnkoYXJnczoge1xuICAgIHNpZzogVWludDhBcnJheTtcbiAgICBwdWJsaWNLZXk6IFVpbnQ4QXJyYXk7XG4gICAgcHVibGljTm9uY2U6IFVpbnQ4QXJyYXk7XG4gICAgc2Vzc2lvbktleTogU2Vzc2lvbktleTtcbiAgfSk6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEFnZ3JlZ2F0ZXMgTXVTaWcgcGFydGlhbCBzaWduYXR1cmVzLiBNYXkgYmUgcnVuIGJ5IGFuIHVudHJ1c3RlZCBwYXJ0eS5cbiAgICpcbiAgICogQHBhcmFtIHNpZ3MgYXJyYXkgb2YgMzItYnl0ZXMgTXVTaWcgcGFydGlhbCBzaWduYXR1cmVzLlxuICAgKiBAcGFyYW0gc2Vzc2lvbktleSBzaWduaW5nIHNlc3Npb24ga2V5IChmcm9tIHN0YXJ0U2lnbmluZ1Nlc3Npb24pXG4gICAqIEByZXR1cm4gdGhlIHJlc3VsdGluZyBhZ2dyZWdhdGUgc2lnbmF0dXJlLlxuICAgKi9cbiAgc2lnbkFnZyhzaWdzOiBVaW50OEFycmF5W10sIHNlc3Npb25LZXk6IFNlc3Npb25LZXkpOiBVaW50OEFycmF5O1xuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmlzdGljYWxseSBnZW5lcmF0ZSBub25jZXMgYW5kIHBhcnRpYWxseSBzaWduIGZvciBhIE11U2lnIGtleS5cbiAgICogVGhlIHNlY3VyaXR5IG9mIHRoaXMgbWV0aG9kIGRlcGVuZHMgb24gaXRzIGJlaW5nIHJ1biBhZnRlciBhbGwgb3RoZXJcbiAgICogcGFydGllcyBoYXZlIHByb3ZpZGVkIHRoZWlyIG5vbmNlcy5cbiAgICpcbiAgICogQHBhcmFtIHNlY3JldEtleSBzaWduZXIncyBzZWNyZXQga2V5XG4gICAqIEBwYXJhbSBhZ2dPdGhlck5vbmNlIHRoZSByZXN1bHQgb2YgY2FsbGluZyBgbm9uY2VBZ2dgIG9uIGFsbCBvdGhlciBzaWduaW5nXG4gICAqIHBhcnRpZXMnIG5vbmNlc1xuICAgKiBAcGFyYW0gcHVibGljS2V5cyBhcnJheSBvZiBjb21wcmVzc2VkIERFUiBlbmNvZGVkIHB1YmxpYyBrZXlzIHRvIGFnZ3JlZ2F0ZVxuICAgKiBAcGFyYW0gdHdlYWtzIHR3ZWFrcyAoMCA8IHR3ZWFrIDwgbikgdG8gYXBwbHkgdG8gdGhlIGFnZ3JlZ2F0ZSBrZXksXG4gICAqIGFuZCBvcHRpb25hbGx5IGJvb2xlYW5zIHRvIGluZGljYXRlIHgtb25seSB0d2Vha2luZ1xuICAgKiBAcGFyYW0gbXNnIHRoZSAzMi1ieXRlIG1lc3NhZ2UgdG8gc2lnbiBmb3IsIG1vc3QgY29tbW9ubHkgYSB0cmFuc2FjdGlvbiBoYXNoLlxuICAgKiBAcGFyYW0gcmFuZCBvcHRpb25hbCBhZGRpdGlvbmFsIHJhbmRvbW5lc3MgZm9yIG5vbmNlIGdlbmVyYXRpb25cbiAgICogQHBhcmFtIHZlcmlmeSBpZiBmYWxzZSwgZG9uJ3QgdmVyaWZ5IHBhcnRpYWwgc2lnbmF0dXJlXG4gICAqIEByZXR1cm4gcmVzdWx0aW5nIHNpZ25hdHVyZSwgc2Vzc2lvbiBrZXkgKGZvciBzaWduYXR1cmUgYWdncmVnYXRpb24pLCBhbmRcbiAgICogcHVibGljIG5vbmNlIChmb3IgcGFydGlhbCB2ZXJpZmljYXRpb24pXG4gICAqL1xuICBkZXRlcm1pbmlzdGljU2lnbihhcmdzOiB7XG4gICAgc2VjcmV0S2V5OiBVaW50OEFycmF5O1xuICAgIGFnZ090aGVyTm9uY2U6IFVpbnQ4QXJyYXk7XG4gICAgcHVibGljS2V5czogVWludDhBcnJheVtdO1xuICAgIHR3ZWFrcz86IFR3ZWFrW107XG4gICAgbXNnOiBVaW50OEFycmF5O1xuICAgIHJhbmQ/OiBVaW50OEFycmF5O1xuICAgIHZlcmlmeT86IGJvb2xlYW47XG4gIH0pOiB7XG4gICAgc2lnOiBVaW50OEFycmF5O1xuICAgIHNlc3Npb25LZXk6IFNlc3Npb25LZXk7XG4gICAgcHVibGljTm9uY2U6IFVpbnQ4QXJyYXk7XG4gIH07XG5cbiAgLyoqXG4gICAqIERldGVybWluaXN0aWNhbGx5IGdlbmVyYXRlIG5vbmNlcy4gVGhpcyBpcyBpZGVudGljYWwgdG8gZGV0ZXJtaW5pc3RpY1NpZ24sXG4gICAqIGV4Y2VwdCB0aGF0IGl0IGFib3J0cyBhZnRlciBub25jZSBnZW5lcmF0aW9uIGFuZCBiZWZvcmUgc2lnbmluZywgYW5kXG4gICAqIHJldHVybnMgb25seSB0aGUgcHVibGljIG5vbmNlLiBUaGlzIHNlY3VyaXR5IG9mIHRoaXMgbWV0aG9kIG9mIG5vbmNlXG4gICAqIGdlbmVyYXRpb24gZGVwZW5kcyBvbiBpdHMgYmVpbmcgcnVuIGFmdGVyIGFsbCBvdGhlciBwYXJ0aWVzIGhhdmUgcHJvdmlkZWRcbiAgICogdGhlaXIgbm9uY2VzLlxuICAgKlxuICAgKiBBIHB1YmxpYyBub25jZSBnZW5lcmF0ZWQgaW4gdGhpcyB3YXkgY2Fubm90IGJlIGRpcmVjdGx5IHVzZWQgZm9yIHNpZ25pbmdcbiAgICogKG5vIHNlY3JldCBub25jZSBpcyBzYXZlZCksIGJ1dCBhIG1hdGNoaW5nIHBhcnRpYWwgc2lnbmF0dXJlIGNhbiBiZVxuICAgKiBnZW5lcmF0ZWQgYnkgc3Vic2VxdWVudGx5IGNhbGxpbmcgZGV0ZXJtaW5pc3RpY1NpZ24gd2l0aCB0aGUgc2FtZVxuICAgKiBhcmd1bWVudHMgYXMgdGhlIGNhbGwgdG8gZGV0ZXJtaW5pc3RpY05vbmNlR2VuLlxuICAgKlxuICAgKiBUaGlzIGNhbiBiZSB1c2VmdWwgaW4gYSBjYXNlIHdoZXJlIGEgc3RhdGVsZXNzIHNpZ25lciBvbmx5IHdhbnRzIHRvXG4gICAqIHByb3ZpZGUgaXRzIHBhcnRpYWwgc2lnbmF0dXJlIGFmdGVyIHNlZWluZyB2YWxpZCBwYXJ0aWFsIHNpZ25hdHVyZXMgZnJvbVxuICAgKiBvdGhlciBwYXJ0aWVzLlxuICAgKlxuICAgKiBAcGFyYW0gc2VjcmV0S2V5IHNpZ25lcidzIHNlY3JldCBrZXlcbiAgICogQHBhcmFtIGFnZ090aGVyTm9uY2UgdGhlIHJlc3VsdCBvZiBjYWxsaW5nIGBub25jZUFnZ2Agb24gYWxsIG90aGVyIHNpZ25pbmdcbiAgICogcGFydGllcycgbm9uY2VzXG4gICAqIEBwYXJhbSBwdWJsaWNLZXlzIGFycmF5IG9mIGNvbXByZXNzZWQgREVSIGVuY29kZWQgcHVibGljIGtleXMgdG8gYWdncmVnYXRlXG4gICAqIEBwYXJhbSB0d2Vha3MgdHdlYWtzICgwIDwgdHdlYWsgPCBuKSB0byBhcHBseSB0byB0aGUgYWdncmVnYXRlIGtleSxcbiAgICogYW5kIG9wdGlvbmFsbHkgYm9vbGVhbnMgdG8gaW5kaWNhdGUgeC1vbmx5IHR3ZWFraW5nXG4gICAqIEBwYXJhbSBtc2cgdGhlIDMyLWJ5dGUgbWVzc2FnZSB0byBzaWduIGZvciwgbW9zdCBjb21tb25seSBhIHRyYW5zYWN0aW9uIGhhc2guXG4gICAqIEBwYXJhbSByYW5kIG9wdGlvbmFsIGFkZGl0aW9uYWwgcmFuZG9tbmVzcyBmb3Igbm9uY2UgZ2VuZXJhdGlvblxuICAgKiBAcGFyYW0gdmVyaWZ5IGlmIGZhbHNlLCBkb24ndCB2ZXJpZnkgcGFydGlhbCBzaWduYXR1cmVcbiAgICogQHJldHVybiBwdWJsaWMgbm9uY2VcbiAgICovXG4gIGRldGVybWluaXN0aWNOb25jZUdlbihhcmdzOiB7XG4gICAgc2VjcmV0S2V5OiBVaW50OEFycmF5O1xuICAgIGFnZ090aGVyTm9uY2U6IFVpbnQ4QXJyYXk7XG4gICAgcHVibGljS2V5czogVWludDhBcnJheVtdO1xuICAgIHR3ZWFrcz86IFR3ZWFrW107XG4gICAgbXNnOiBVaW50OEFycmF5O1xuICAgIHJhbmQ/OiBVaW50OEFycmF5O1xuICB9KTogeyBwdWJsaWNOb25jZTogVWludDhBcnJheSB9O1xuICAvLyBUT0RPOiBEaXNjdXNzIHdpdGggSFNNIHRlYW0gdGhlIGdlbmVyYXRpb24gb2YgYWxsIHRoZSBub25jZXMgYW5kIGFueVxuICAvLyBwb3RlbnRpYWwgc2NhbGluZyBjb25jZXJucyAoM3ggdGhlIHRvdGFsIGNvc3Qgb2Ygc2Nobm9yciBzaWduaW5nKVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENyeXB0byB7XG4gIC8qKlxuICAgKiBBZGRzIGEgdHdlYWsgdG8gYSBwb2ludC5cbiAgICpcbiAgICogQHBhcmFtIHAgQSBwb2ludCwgY29tcHJlc3NlZCBvciB1bmNvbXByZXNzZWRcbiAgICogQHBhcmFtIHQgQSB0d2VhaywgMCA8IHQgPCBuXG4gICAqIEBwYXJhbSBjb21wcmVzc2VkIFdoZXRoZXIgdGhlIHJlc3VsdGluZyBwb2ludCBzaG91bGQgYmUgY29tcHJlc3NlZC5cbiAgICogQHJldHVybnMgVGhlIHR3ZWFrZWQgcG9pbnQsIGNvbXByZXNzZWQgb3IgdW5jb21wcmVzc2VkLCBudWxsIGlmIHRoZSByZXN1bHRcbiAgICogaXMgdGhlIHBvaW50IGF0IGluZmluaXR5LlxuICAgKi9cbiAgcG9pbnRBZGRUd2VhayhwOiBVaW50OEFycmF5LCB0OiBVaW50OEFycmF5LCBjb21wcmVzc2VkOiBib29sZWFuKTogVWludDhBcnJheSB8IG51bGw7XG5cbiAgLyoqXG4gICAqIEFkZHMgdHdvIHBvaW50cy5cbiAgICpcbiAgICogQHBhcmFtIGEgQW4gYWRkZW5kIHBvaW50LCBjb21wcmVzc2VkIG9yIHVuY29tcHJlc3NlZFxuICAgKiBAcGFyYW0gYiBBbiBhZGRlbmQgcG9pbnQsIGNvbXByZXNzZWQgb3IgdW5jb21wcmVzc2VkXG4gICAqIEBwYXJhbSBjb21wcmVzc2VkIFdoZXRoZXIgdGhlIHJlc3VsdGluZyBwb2ludCBzaG91bGQgYmUgY29tcHJlc3NlZC5cbiAgICogQHJldHVybnMgVGhlIHN1bSBwb2ludCwgY29tcHJlc3NlZCBvciB1bmNvbXByZXNzZWQsIG51bGwgaWYgdGhlIHJlc3VsdCBpc1xuICAgKiB0aGUgcG9pbnQgYXQgaW5maW5pdHkuXG4gICAqL1xuICBwb2ludEFkZChhOiBVaW50OEFycmF5LCBiOiBVaW50OEFycmF5LCBjb21wcmVzc2VkOiBib29sZWFuKTogVWludDhBcnJheSB8IG51bGw7XG5cbiAgLyoqXG4gICAqIE11bHRpcGxpZXMgYSBwb2ludCBieSBhIHNjYWxhci5cbiAgICogVGhpcyBmdW5jdGlvbiBtYXkgdXNlIG5vbi1jb25zdGFudCB0aW1lIG9wZXJhdGlvbnMsIGFzIG5vIHNlY3JldFxuICAgKiBpbmZvcm1hdGlvbiBpcyBwcm9jZXNzZWQuXG4gICAqXG4gICAqIEBwYXJhbSBwIEEgcG9pbnQgbXVsdGlwbGljYW5kLCBjb21wcmVzc2VkIG9yIHVuY29tcHJlc3NlZFxuICAgKiBAcGFyYW0gYSBUaGUgbXVsdGlwbGllciwgMCA8IGEgPCBuXG4gICAqIEBwYXJhbSBjb21wcmVzc2VkIFdoZXRoZXIgdGhlIHJlc3VsdGluZyBwb2ludCBzaG91bGQgYmUgY29tcHJlc3NlZC5cbiAgICogQHJldHVybnMgVGhlIHByb2R1Y3QgcG9pbnQsIGNvbXByZXNzZWQgb3IgdW5jb21wcmVzc2VkLCBudWxsIGlmIHRoZSByZXN1bHRcbiAgICogaXMgdGhlIHBvaW50IGF0IGluZmluaXR5LlxuICAgKi9cbiAgcG9pbnRNdWx0aXBseVVuc2FmZShwOiBVaW50OEFycmF5LCBhOiBVaW50OEFycmF5LCBjb21wcmVzc2VkOiBib29sZWFuKTogVWludDhBcnJheSB8IG51bGw7XG5cbiAgLyoqXG4gICAqIE11bHRpcGxpZXMgcG9pbnQgMSBieSBhIHNjYWxhciBhbmQgYWRkcyBpdCB0byBwb2ludCAyLlxuICAgKiBUaGlzIGZ1bmN0aW9uIG1heSB1c2Ugbm9uLWNvbnN0YW50IHRpbWUgb3BlcmF0aW9ucywgYXMgbm8gc2VjcmV0XG4gICAqIGluZm9ybWF0aW9uIGlzIHByb2Nlc3NlZC5cbiAgICpcbiAgICogQHBhcmFtIHAxIHBvaW50IG11bHRpcGxpY2FuZCwgY29tcHJlc3NlZCBvciB1bmNvbXByZXNzZWRcbiAgICogQHBhcmFtIGEgVGhlIG11bHRpcGxpZXIsIDAgPCBhIDwgblxuICAgKiBAcGFyYW0gcDIgcG9pbnQgYWRkZW5kLCBjb21wcmVzc2VkIG9yIHVuY29tcHJlc3NlZFxuICAgKiBAcGFyYW0gY29tcHJlc3NlZCBXaGV0aGVyIHRoZSByZXN1bHRpbmcgcG9pbnQgc2hvdWxkIGJlIGNvbXByZXNzZWQuXG4gICAqIEByZXR1cm5zIFRoZSBwcm9kdWN0L3N1bSBwb2ludCwgY29tcHJlc3NlZCBvciB1bmNvbXByZXNzZWQsIG51bGwgaWYgdGhlXG4gICAqIHJlc3VsdCBpcyB0aGUgcG9pbnQgYXQgaW5maW5pdHkuXG4gICAqL1xuICBwb2ludE11bHRpcGx5QW5kQWRkVW5zYWZlKHAxOiBVaW50OEFycmF5LCBhOiBVaW50OEFycmF5LCBwMjogVWludDhBcnJheSwgY29tcHJlc3NlZDogYm9vbGVhbik6IFVpbnQ4QXJyYXkgfCBudWxsO1xuXG4gIC8qKlxuICAgKiBOZWdhdGVzIGEgcG9pbnQsIGllLiByZXR1cm5zIHRoZSBwb2ludCB3aXRoIHRoZSBvcHBvc2l0ZSBwYXJpdHkuXG4gICAqXG4gICAqIEBwYXJhbSBwIEEgcG9pbnQgdG8gbmVnYXRlLCBjb21wcmVzc2VkIG9yIHVuY29tcHJlc3NlZFxuICAgKiBAcmV0dXJucyBUaGUgbmVnYXRlZCBwb2ludCwgd2l0aCBzYW1lIGNvbXByZXNzaW9uIGFzIGlucHV0LlxuICAgKi9cbiAgcG9pbnROZWdhdGUocDogVWludDhBcnJheSk6IFVpbnQ4QXJyYXk7XG5cbiAgLyoqXG4gICAqIENvbXByZXNzZXMgYSBwb2ludC5cbiAgICpcbiAgICogQHBhcmFtIHAgQSBwb2ludCwgY29tcHJlc3NlZCBvciB1bmNvbXByZXNzZWRcbiAgICogQHBhcmFtIGNvbXByZXNzIFtkZWZhdWx0PXRydWVdIGlmIGZhbHNlLCB1bmNvbXByZXNzIHRoZSBwb2ludFxuICAgKiBAcmV0dXJucyBUaGUgcG9pbnQsIGNvbXByZXNzZWQgaWYgY29tcHJlc3MgaXMgdHJ1ZSwgb3IgdW5jb21wcmVzc2VkIGlmIGZhbHNlLlxuICAgKi9cbiAgcG9pbnRDb21wcmVzcyhwOiBVaW50OEFycmF5LCBjb21wcmVzcz86IGJvb2xlYW4pOiBVaW50OEFycmF5O1xuXG4gIC8qKlxuICAgKiBBZGRzIG9uZSB2YWx1ZSB0byBhbm90aGVyLCBtb2Qgbi5cbiAgICpcbiAgICogQHBhcmFtIGEgQW4gYWRkZW5kLCAwIDw9IGEgPCBuXG4gICAqIEBwYXJhbSBiIEFuIGFkZGVuZCwgMCA8PSBiIDwgblxuICAgKiBAcmV0dXJucyBUaGUgc3VtLCAwIDw9IHN1bSA8IG5cbiAgICovXG4gIHNjYWxhckFkZChhOiBVaW50OEFycmF5LCBiOiBVaW50OEFycmF5KTogVWludDhBcnJheTtcblxuICAvKipcbiAgICogTXVsdGlwbHkgb25lIHZhbHVlIGJ5IGFub3RoZXIsIG1vZCBuLlxuICAgKlxuICAgKiBAcGFyYW0gYSBUaGUgbXVsdGlwbGljYW5kLCAwIDw9IGEgPCBuXG4gICAqIEBwYXJhbSBiIFRoZSBtdWx0aXBsaWVyLCAwIDw9IGIgPCBuXG4gICAqIEByZXR1cm5zIFRoZSBwcm9kdWN0LCAwIDw9IHByb2R1Y3QgPCBuXG4gICAqL1xuICBzY2FsYXJNdWx0aXBseShhOiBVaW50OEFycmF5LCBiOiBVaW50OEFycmF5KTogVWludDhBcnJheTtcblxuICAvKipcbiAgICogTmVnYXRlcyBhIHZhbHVlLCBtb2Qgbi5cbiAgICpcbiAgICogQHBhcmFtIGEgVGhlIHZhbHVlIHRvIG5lZ2F0ZSwgMCA8PSBhIDwgblxuICAgKiBAcmV0dXJucyBUaGUgbmVnYXRlZCB2YWx1ZSwgMCA8PSBuZWdhdGVkIDwgblxuICAgKi9cbiAgc2NhbGFyTmVnYXRlKGE6IFVpbnQ4QXJyYXkpOiBVaW50OEFycmF5O1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gYSBUaGUgdmFsdWUgdG8gcmVkdWNlXG4gICAqIEByZXR1cm5zIGEgbW9kIG5cbiAgICovXG4gIHNjYWxhck1vZChhOiBVaW50OEFycmF5KTogVWludDhBcnJheTtcblxuICAvKipcbiAgICogQHBhcmFtIHMgQSBidWZmZXIgdG8gY2hlY2sgYWdhaW5zdCB0aGUgY3VydmUgb3JkZXJcbiAgICogQHJldHVybnMgdHJ1ZSBpZiBzIGlzIGEgMzItYnl0ZSBhcnJheSAwIDw9IHMgPCBuXG4gICAqL1xuICBpc1NjYWxhcihzOiBVaW50OEFycmF5KTogYm9vbGVhbjtcblxuICAvKipcbiAgICogQHBhcmFtIHMgQSBidWZmZXIgdG8gY2hlY2sgYWdhaW5zdCB0aGUgY3VydmUgb3JkZXJcbiAgICogQHJldHVybnMgdHJ1ZSBpZiBzIGlzIGEgMzItYnl0ZSBhcnJheSAwIDwgcyA8IG5cbiAgICovXG4gIGlzU2VjcmV0KHM6IFVpbnQ4QXJyYXkpOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gcCBBIGJ1ZmZlciB0byBjaGVjayBhZ2FpbnN0IHRoZSBjdXJ2ZSBlcXVhdGlvbiwgY29tcHJlc3NlZCBvclxuICAgKiB1bmNvbXByZXNzZWQuXG4gICAqIEByZXR1cm5zIHRydWUgaWYgcCBpcyBhIHZhbGlkIHBvaW50IG9uIHNlY3AyNTZrMSwgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqL1xuICBpc1BvaW50KHA6IFVpbnQ4QXJyYXkpOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gcCBBIGJ1ZmZlciB0byBjaGVjayBhZ2FpbnN0IHRoZSBjdXJ2ZSBlcXVhdGlvbi5cbiAgICogQHJldHVybnMgdHJ1ZSBpZiBwIGlzIHRoZSB4IGNvb3JkaW5hdGUgb2YgYSB2YWxpZCBwb2ludCBvbiBzZWNwMjU2azEsXG4gICAqIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgaXNYT25seVBvaW50KHA6IFVpbnQ4QXJyYXkpOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gcCBhbiB4IGNvb3JkaW5hdGVcbiAgICogQHJldHVybnMgdGhlIHh5LCB1bmNvbXByZXNzZWQgcG9pbnQgaWYgcCBpcyBvbiB0aGUgY3VydmUsIG90aGVyd2lzZSBudWxsLlxuICAgKi9cbiAgbGlmdFgocDogVWludDhBcnJheSk6IFVpbnQ4QXJyYXkgfCBudWxsO1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gcCB4LW9ubHksIGNvbXByZXNzZWQgb3IgdW5jb21wcmVzc2VkXG4gICAqIEByZXR1cm5zIHRoZSB4IGNvb3JkaW5hdGUgb2YgcFxuICAgKi9cbiAgcG9pbnRYKHA6IFVpbnQ4QXJyYXkpOiBVaW50OEFycmF5O1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gcCBhIHBvaW50LCBjb21wcmVzc2VkIG9yIHVuY29tcHJlc3NlZFxuICAgKiBAcmV0dXJucyB0cnVlIGlmIHAgaGFzIGFuIGV2ZW4geSBjb29yZGluYXRlLCBmYWxzZSBvdGhlcndpc2VcbiAgICovXG4gIGhhc0V2ZW5ZKHA6IFVpbnQ4QXJyYXkpOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBHZXRzIGEgcHVibGljIGtleSBmb3Igc2VjcmV0IGtleS5cbiAgICpcbiAgICogQHBhcmFtIHMgU2VjcmV0IGtleVxuICAgKiBAcGFyYW0gY29tcHJlc3NlZCBXaGV0aGVyIHRoZSByZXN1bHRpbmcgcG9pbnQgc2hvdWxkIGJlIGNvbXByZXNzZWQuXG4gICAqIEByZXR1cm5zIFRoZSBwdWJsaWMga2V5LCBjb21wcmVzc2VkIG9yIHVuY29tcHJlc3NlZFxuICAgKi9cbiAgZ2V0UHVibGljS2V5KHM6IFVpbnQ4QXJyYXksIGNvbXByZXNzZWQ6IGJvb2xlYW4pOiBVaW50OEFycmF5IHwgbnVsbDtcblxuICAvKipcbiAgICogUGVyZm9ybXMgYSBCSVAzNDAtc3R5bGUgdGFnZ2VkIGhhc2guXG4gICAqXG4gICAqIEBwYXJhbSB0YWdcbiAgICogQHBhcmFtIG1lc3NhZ2VzIEFycmF5IG9mIGRhdGEgdG8gaGFzaC5cbiAgICogQHJldHVybiBUaGUgMzItYnl0ZSBCSVAzNDAtc3R5bGUgdGFnZ2VkIGhhc2guXG4gICAqL1xuICB0YWdnZWRIYXNoKHRhZzogc3RyaW5nLCAuLi5tZXNzYWdlczogVWludDhBcnJheVtdKTogVWludDhBcnJheTtcblxuICAvKipcbiAgICogU0hBMjU2IGhhc2guXG4gICAqXG4gICAqIEBwYXJhbSBtZXNzYWdlcyBBcnJheSBvZiBkYXRhIHRvIGhhc2guXG4gICAqIEByZXR1cm4gVGhlIDMyLWJ5dGUgU0hBMjU2IGRpZ2VzdC5cbiAgICovXG4gIHNoYTI1NiguLi5tZXNzYWdlczogVWludDhBcnJheVtdKTogVWludDhBcnJheTtcbn1cblxuZXhwb3J0IHR5cGUgVHdlYWsgPSBUeXBlZFR3ZWFrIHwgVWludDhBcnJheTtcbmV4cG9ydCBpbnRlcmZhY2UgVHlwZWRUd2VhayB7XG4gIHR3ZWFrOiBVaW50OEFycmF5O1xuICB4T25seT86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgS2V5R2VuQ29udGV4dCB7XG4gIGFnZ1B1YmxpY0tleTogVWludDhBcnJheTsgLy8gYSBwb2ludCBvbiB0aGUgY3VydmVcbiAgZ2FjYzogVWludDhBcnJheTsgLy8gYWNjdW11bGF0ZWQgbmVnYXRpb24gZmFjdG9yIGZyb20gWC1vbmx5IHR3ZWFraW5nXG4gIHRhY2M6IFVpbnQ4QXJyYXk7IC8vIDMyLWJ5dGUgYWNjdW11bGF0ZWQgdHdlYWsgKG1vZCBuKVxufVxuXG5pbnRlcmZhY2UgU2Vzc2lvblZhbHVlcyBleHRlbmRzIEtleUdlbkNvbnRleHQge1xuICBjb2VmZmljaWVudDogVWludDhBcnJheTsgLy8gMzItYnl0ZSBub25jZSBjb2VmZmljaWVudCAobW9kIG4pXG4gIGZpbmFsTm9uY2U6IFVpbnQ4QXJyYXk7IC8vIGEgcG9pbnQgb24gdGhlIGN1cnZlXG4gIGNoYWxsZW5nZTogVWludDhBcnJheTsgLy8gMzItYnl0ZSBjaGFsbGVuZ2UgKG1vZCBuKVxuICBwdWJsaWNLZXlzOiBVaW50OEFycmF5W107IC8vIGluZGl2aWR1YWwgcHVibGljIGtleXMgaW4gY29tcHJlc3NlZCBERVIgZm9ybWF0XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2Vzc2lvbktleSB7XG4gIHB1YmxpY0tleTogVWludDhBcnJheTtcbiAgYWdnTm9uY2U6IFVpbnQ4QXJyYXk7XG4gIG1zZzogVWludDhBcnJheTtcbn1cblxuY29uc3QgVEFHUyA9IHtcbiAgY2hhbGxlbmdlOiAnQklQMDM0MC9jaGFsbGVuZ2UnLFxuICBrZXlhZ2dfbGlzdDogJ0tleUFnZyBsaXN0JyxcbiAga2V5YWdnX2NvZWY6ICdLZXlBZ2cgY29lZmZpY2llbnQnLFxuICBtdXNpZ19hdXg6ICdNdVNpZy9hdXgnLFxuICBtdXNpZ19ub25jZTogJ011U2lnL25vbmNlJyxcbiAgbXVzaWdfZGV0ZXJtaW5pc3RpY19ub25jZTogJ011U2lnL2RldGVybWluaXN0aWMvbm9uY2UnLFxuICBtdXNpZ19ub25jZWNvZWY6ICdNdVNpZy9ub25jZWNvZWYnLFxufSBhcyBjb25zdDtcblxuLyoqXG4gKiBDb21wYXJlcyB0d28gMzItYnl0ZSBVaW50OEFycmF5cyBpbiBieXRlIG9yZGVyLlxuICogQHJldHVybnMgPCAwLCAwLCA+IDAgaWYgYSBpcyA8IGIsID09PSBiIG9yID4gYiByZXNwZWN0aXZlbHlcbiAqL1xuZnVuY3Rpb24gY29tcGFyZTMyYihhOiBVaW50OEFycmF5LCBiOiBVaW50OEFycmF5KTogbnVtYmVyIHtcbiAgaWYgKGEubGVuZ3RoICE9PSAzMiB8fCBiLmxlbmd0aCAhPT0gMzIpIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBhcnJheScpO1xuICBjb25zdCBhRCA9IG5ldyBEYXRhVmlldyhhLmJ1ZmZlciwgYS5ieXRlT2Zmc2V0LCBhLmxlbmd0aCk7XG4gIGNvbnN0IGJEID0gbmV3IERhdGFWaWV3KGIuYnVmZmVyLCBiLmJ5dGVPZmZzZXQsIGIubGVuZ3RoKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCA4OyBpKyspIHtcbiAgICBjb25zdCBjbXAgPSBhRC5nZXRVaW50MzIoaSAqIDQpIC0gYkQuZ2V0VWludDMyKGkgKiA0KTtcbiAgICBpZiAoY21wICE9PSAwKSByZXR1cm4gY21wO1xuICB9XG4gIHJldHVybiAwO1xufVxuXG4vKipcbiAqIENvbXBhcmVzIHR3byAzMy1ieXRlIFVpbnQ4QXJyYXlzIGluIGJ5dGUgb3JkZXIuXG4gKiBAcmV0dXJucyA8IDAsIDAsID4gMCBpZiBhIGlzIDwgYiwgPT09IGIgb3IgPiBiIHJlc3BlY3RpdmVseVxuICovXG5mdW5jdGlvbiBjb21wYXJlMzNiKGE6IFVpbnQ4QXJyYXksIGI6IFVpbnQ4QXJyYXkpOiBudW1iZXIge1xuICBpZiAoYS5sZW5ndGggIT09IDMzIHx8IGIubGVuZ3RoICE9PSAzMykgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGFycmF5Jyk7XG4gIGNvbnN0IGNtcCA9IGFbMF0gLSBiWzBdO1xuICBpZiAoY21wICE9PSAwKSByZXR1cm4gY21wO1xuICByZXR1cm4gY29tcGFyZTMyYihhLnN1YmFycmF5KDEpLCBiLnN1YmFycmF5KDEpKTtcbn1cblxuZGVjbGFyZSBjb25zdCBzZWxmOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgdW5kZWZpbmVkO1xuY29uc3QgbWFrZVNlc3Npb25JZCA9XG4gIHR5cGVvZiBzZWxmID09PSAnb2JqZWN0JyAmJiAoc2VsZi5jcnlwdG8gfHwgc2VsZi5tc0NyeXB0bylcbiAgICA/ICgpID0+IChzZWxmLmNyeXB0byB8fCBzZWxmLm1zQ3J5cHRvKS5nZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQ4QXJyYXkoMzIpKSAvLyBCcm93c2Vyc1xuICAgIDogKCkgPT4gcmVxdWlyZSgnY3J5cHRvJykucmFuZG9tQnl0ZXMoMzIpOyAvLyBOb2RlXG5cbi8vIENhY2hlcyB2YWx1ZXMgbmVlZGVkIHRvIGNvbXB1dGUga2V5IGFnZyBjb2VmZmljaWVudHMgZm9yIGFuIGFycmF5IG9mIHB1YmxpYyBrZXlzXG5pbnRlcmZhY2UgS2V5QWdnQ2FjaGUge1xuICBwdWJsaWNLZXlIYXNoOiBVaW50OEFycmF5O1xuICBzZWNvbmRQdWJsaWNLZXk/OiBVaW50OEFycmF5O1xufVxuY29uc3QgX2tleUFnZ0NhY2hlID0gbmV3IFdlYWtNYXA8VWludDhBcnJheVtdLCBLZXlBZ2dDYWNoZT4oKTtcblxuLy8gQ2FjaGVzIGNvZWZmaWNpZW50cyBhc3NvY2lhdGVkIHdpdGggYW4gYXJyYXkgb2YgcHVibGljIGtleXNcbmNvbnN0IF9jb2VmQ2FjaGUgPSBuZXcgV2Vha01hcDxVaW50OEFycmF5W10sIE1hcDxVaW50OEFycmF5LCBVaW50OEFycmF5Pj4oKTtcblxuLy8gQ2FjaGVzIHNlY3JldCBub25jZXMuIFdlIGRvIHRoaXMgaW50ZXJuYWxseSB0byBoZWxwIHVzZXJzIGVuc3VyZSB0aGF0IHRoZXlcbi8vIGRvIG5vdCByZXVzZSBhIHNlY3JldCBub25jZS5cbmNvbnN0IF9ub25jZUNhY2hlID0gbmV3IFdlYWtNYXA8VWludDhBcnJheSwgVWludDhBcnJheT4oKTtcblxuLy8gQ2FjaGVzIHNpZ25pbmcgc2Vzc2lvbnMuIFdlIGRvIHRoaXMgaW50ZXJuYWxseSB0byBoZWxwIHVzZXJzIGVuc3VyZSB0aGF0XG4vLyB0aGVzZSBzZXNzaW9uIHZhbHVlcyB3ZXJlIGdlbmVyYXRlZCBvbiB0aGUgc2lnbmVyLCBhbmQgYXJlIG5vdCBhY2NlcHRlZCBmcm9tXG4vLyBhbiB1bnRydXN0ZWQgdGhpcmQgcGFydHkuXG5jb25zdCBfc2Vzc2lvbkNhY2hlID0gbmV3IFdlYWtNYXA8U2Vzc2lvbktleSwgU2Vzc2lvblZhbHVlcz4oKTtcblxuZXhwb3J0IGZ1bmN0aW9uIE11U2lnRmFjdG9yeShlY2M6IENyeXB0byk6IE11U2lnIHtcbiAgY29uc3QgQ1BPSU5UX0lORiA9IG5ldyBVaW50OEFycmF5KDMzKTtcbiAgY29uc3QgU0NBTEFSXzAgPSBuZXcgVWludDhBcnJheSgzMik7XG4gIGNvbnN0IFNDQUxBUl8xID0gbmV3IFVpbnQ4QXJyYXkoMzIpO1xuICBTQ0FMQVJfMVszMV0gPSAxO1xuICBjb25zdCBTQ0FMQVJfTUlOVVNfMSA9IGVjYy5zY2FsYXJOZWdhdGUoU0NBTEFSXzEpO1xuXG4gIGZ1bmN0aW9uIGtleUFnZ0NvZWZmKHB1YmxpY0tleXM6IFVpbnQ4QXJyYXlbXSwgcHVibGljS2V5OiBVaW50OEFycmF5KTogVWludDhBcnJheSB7XG4gICAgbGV0IGNvZWZDYWNoZSA9IF9jb2VmQ2FjaGUuZ2V0KHB1YmxpY0tleXMpO1xuICAgIGlmIChjb2VmQ2FjaGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29lZkNhY2hlID0gbmV3IE1hcDxVaW50OEFycmF5LCBVaW50OEFycmF5PigpO1xuICAgICAgX2NvZWZDYWNoZS5zZXQocHVibGljS2V5cywgY29lZkNhY2hlKTtcbiAgICB9XG4gICAgbGV0IGNvZWZmaWNpZW50ID0gY29lZkNhY2hlLmdldChwdWJsaWNLZXkpO1xuICAgIGlmIChjb2VmZmljaWVudCkgcmV0dXJuIGNvZWZmaWNpZW50O1xuXG4gICAgY29lZmZpY2llbnQgPSBTQ0FMQVJfMTtcbiAgICBsZXQgc2Vjb25kUHVibGljS2V5O1xuICAgIGxldCBwdWJsaWNLZXlIYXNoO1xuICAgIGxldCBrZXlBZ2dDYWNoZSA9IF9rZXlBZ2dDYWNoZS5nZXQocHVibGljS2V5cyk7XG4gICAgaWYgKGtleUFnZ0NhY2hlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIEluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBzZWNvbmQgdW5pcXVlIHB1YmxpYyBrZXkuXG4gICAgICBjb25zdCBwa0lkeDIgPSBwdWJsaWNLZXlzLmZpbmRJbmRleCgocGspID0+IGNvbXBhcmUzM2IocGssIHB1YmxpY0tleXNbMF0pICE9PSAwKTtcbiAgICAgIHNlY29uZFB1YmxpY0tleSA9IHB1YmxpY0tleXNbcGtJZHgyXTsgLy8gdW5kZWZpbmVkIGlmIHBrSWR4MiA9PT0gLTFcbiAgICAgIHB1YmxpY0tleUhhc2ggPSBlY2MudGFnZ2VkSGFzaChUQUdTLmtleWFnZ19saXN0LCAuLi5wdWJsaWNLZXlzKTtcbiAgICAgIGtleUFnZ0NhY2hlID0geyBwdWJsaWNLZXlIYXNoLCBzZWNvbmRQdWJsaWNLZXkgfTtcbiAgICAgIF9rZXlBZ2dDYWNoZS5zZXQocHVibGljS2V5cywga2V5QWdnQ2FjaGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAoeyBwdWJsaWNLZXlIYXNoLCBzZWNvbmRQdWJsaWNLZXkgfSA9IGtleUFnZ0NhY2hlKTtcbiAgICB9XG4gICAgaWYgKHNlY29uZFB1YmxpY0tleSA9PT0gdW5kZWZpbmVkIHx8IGNvbXBhcmUzM2IocHVibGljS2V5LCBzZWNvbmRQdWJsaWNLZXkpICE9PSAwKSB7XG4gICAgICBjb2VmZmljaWVudCA9IGVjYy50YWdnZWRIYXNoKFRBR1Mua2V5YWdnX2NvZWYsIHB1YmxpY0tleUhhc2gsIHB1YmxpY0tleSk7XG4gICAgfVxuICAgIGNvZWZDYWNoZS5zZXQocHVibGljS2V5LCBjb2VmZmljaWVudCk7XG4gICAgcmV0dXJuIGNvZWZmaWNpZW50O1xuICB9XG5cbiAgZnVuY3Rpb24gYWRkVHdlYWsoY3R4OiBLZXlHZW5Db250ZXh0LCB0OiBUd2Vhayk6IEtleUdlbkNvbnRleHQge1xuICAgIGNvbnN0IHR3ZWFrID0gJ3R3ZWFrJyBpbiB0ID8gdCA6IHsgdHdlYWs6IHQgfTtcbiAgICBpZiAoIWVjYy5pc1NjYWxhcih0d2Vhay50d2VhaykpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0V4cGVjdGVkIHR3ZWFrIHRvIGJlIGEgdmFsaWQgc2NhbGFyIHdpdGggY3VydmUgb3JkZXInKTtcbiAgICBsZXQgeyBnYWNjLCB0YWNjIH0gPSBjdHg7XG4gICAgbGV0IGFnZ1B1YmxpY0tleTogVWludDhBcnJheSB8IG51bGwgPSBjdHguYWdnUHVibGljS2V5O1xuXG4gICAgaWYgKCFlY2MuaGFzRXZlblkoYWdnUHVibGljS2V5KSAmJiB0d2Vhay54T25seSkge1xuICAgICAgLy8gZyA9IC0xXG4gICAgICBnYWNjID0gZWNjLnNjYWxhck5lZ2F0ZShnYWNjKTsgLy8gZyAqIGdhY2MgbW9kIG5cbiAgICAgIHRhY2MgPSBlY2Muc2NhbGFyTmVnYXRlKHRhY2MpOyAvLyBnICogdGFjYyBtb2QgblxuICAgICAgYWdnUHVibGljS2V5ID0gZWNjLnBvaW50TmVnYXRlKGFnZ1B1YmxpY0tleSk7IC8vIGcgKiBRXG4gICAgfVxuICAgIGFnZ1B1YmxpY0tleSA9IGVjYy5wb2ludEFkZFR3ZWFrKGFnZ1B1YmxpY0tleSwgdHdlYWsudHdlYWssIGZhbHNlKTsgLy8gZyAqIFEgKyB0ICogR1xuICAgIGlmIChhZ2dQdWJsaWNLZXkgPT09IG51bGwpIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBwb2ludCBhdCBpbmZpbml0eSBkdXJpbmcgdHdlYWtpbmcnKTtcbiAgICB0YWNjID0gZWNjLnNjYWxhckFkZCh0d2Vhay50d2VhaywgdGFjYyk7IC8vIHQgKyBnICogdGFjYyBtb2QgblxuXG4gICAgcmV0dXJuIHsgYWdnUHVibGljS2V5LCBnYWNjLCB0YWNjIH07XG4gIH1cblxuICBmdW5jdGlvbiBrZXlBZ2cocHVibGljS2V5czogVWludDhBcnJheVtdLCAuLi50d2Vha3M6IFR3ZWFrW10pOiBLZXlHZW5Db250ZXh0IHtcbiAgICBjaGVja0FyZ3MoeyBwdWJsaWNLZXlzIH0pO1xuICAgIGNvbnN0IG11bHRpcGxpZWRQdWJsaWNLZXlzID0gcHVibGljS2V5cy5tYXAoKHB1YmxpY0tleSkgPT4ge1xuICAgICAgY29uc3QgY29lZmZpY2llbnQgPSBrZXlBZ2dDb2VmZihwdWJsaWNLZXlzLCBwdWJsaWNLZXkpO1xuICAgICAgbGV0IG11bHRpcGxpZWRQdWJsaWNLZXk6IFVpbnQ4QXJyYXkgfCBudWxsO1xuICAgICAgaWYgKGNvbXBhcmUzMmIoY29lZmZpY2llbnQsIFNDQUxBUl8xKSA9PT0gMCkge1xuICAgICAgICBtdWx0aXBsaWVkUHVibGljS2V5ID0gcHVibGljS2V5O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbXVsdGlwbGllZFB1YmxpY0tleSA9IGVjYy5wb2ludE11bHRpcGx5VW5zYWZlKHB1YmxpY0tleSwgY29lZmZpY2llbnQsIGZhbHNlKTtcbiAgICAgIH1cbiAgICAgIGlmIChtdWx0aXBsaWVkUHVibGljS2V5ID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoJ1BvaW50IGF0IGluZmluaXR5IGR1cmluZyBhZ2dyZWdhdGlvbicpO1xuICAgICAgcmV0dXJuIG11bHRpcGxpZWRQdWJsaWNLZXk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBhZ2dQdWJsaWNLZXkgPSBtdWx0aXBsaWVkUHVibGljS2V5cy5yZWR1Y2UoKGEsIGIpID0+IHtcbiAgICAgIGNvbnN0IG5leHQgPSBlY2MucG9pbnRBZGQoYSwgYiwgZmFsc2UpO1xuICAgICAgaWYgKG5leHQgPT09IG51bGwpIHRocm93IG5ldyBFcnJvcignUG9pbnQgYXQgaW5maW5pdHkgZHVyaW5nIGFnZ3JlZ2F0aW9uJyk7XG4gICAgICByZXR1cm4gbmV4dDtcbiAgICB9KTtcblxuICAgIHJldHVybiB0d2Vha3MucmVkdWNlKChjdHgsIHR3ZWFrKSA9PiBhZGRUd2VhayhjdHgsIHR3ZWFrKSwge1xuICAgICAgYWdnUHVibGljS2V5LFxuICAgICAgZ2FjYzogU0NBTEFSXzEsXG4gICAgICB0YWNjOiBTQ0FMQVJfMCxcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldFNlc3Npb25WYWx1ZXMoc2Vzc2lvbktleTogU2Vzc2lvbktleSk6IFNlc3Npb25WYWx1ZXMge1xuICAgIGNvbnN0IHNlc3Npb25WYWx1ZXMgPSBfc2Vzc2lvbkNhY2hlLmdldChzZXNzaW9uS2V5KTtcbiAgICBpZiAoIXNlc3Npb25WYWx1ZXMpIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzZXNzaW9uIGtleSwgcGxlYXNlIGNhbGwgYHN0YXJ0U2lnbmluZ1Nlc3Npb25gJyk7XG4gICAgcmV0dXJuIHNlc3Npb25WYWx1ZXM7XG4gIH1cblxuICBmdW5jdGlvbiBub25jZUFnZyhwdWJsaWNOb25jZXM6IFVpbnQ4QXJyYXlbXSk6IFVpbnQ4QXJyYXkge1xuICAgIGNoZWNrQXJncyh7IHB1YmxpY05vbmNlcyB9KTtcblxuICAgIGNvbnN0IGFnZ05vbmNlczogQXJyYXk8VWludDhBcnJheSB8IG51bGw+ID0gW3B1YmxpY05vbmNlc1swXS5zdWJhcnJheSgwLCAzMyksIHB1YmxpY05vbmNlc1swXS5zdWJhcnJheSgzMyldO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcHVibGljTm9uY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYWdnTm9uY2VzWzBdICE9PSBudWxsKSBhZ2dOb25jZXNbMF0gPSBlY2MucG9pbnRBZGQoYWdnTm9uY2VzWzBdLCBwdWJsaWNOb25jZXNbaV0uc3ViYXJyYXkoMCwgMzMpLCBmYWxzZSk7XG4gICAgICBpZiAoYWdnTm9uY2VzWzFdICE9PSBudWxsKSBhZ2dOb25jZXNbMV0gPSBlY2MucG9pbnRBZGQoYWdnTm9uY2VzWzFdLCBwdWJsaWNOb25jZXNbaV0uc3ViYXJyYXkoMzMpLCBmYWxzZSk7XG4gICAgfVxuICAgIGNvbnN0IGFnZ05vbmNlID0gbmV3IFVpbnQ4QXJyYXkoNjYpO1xuICAgIGlmIChhZ2dOb25jZXNbMF0gIT09IG51bGwpIGFnZ05vbmNlLnNldChlY2MucG9pbnRDb21wcmVzcyhhZ2dOb25jZXNbMF0pLCAwKTtcbiAgICBpZiAoYWdnTm9uY2VzWzFdICE9PSBudWxsKSBhZ2dOb25jZS5zZXQoZWNjLnBvaW50Q29tcHJlc3MoYWdnTm9uY2VzWzFdKSwgMzMpO1xuICAgIHJldHVybiBhZ2dOb25jZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHN0YXJ0U2lnbmluZ1Nlc3Npb25Jbm5lcihcbiAgICBhZ2dOb25jZTogVWludDhBcnJheSxcbiAgICBtc2c6IFVpbnQ4QXJyYXksXG4gICAgcHVibGljS2V5czogVWludDhBcnJheVtdLFxuICAgIGN0eDogS2V5R2VuQ29udGV4dFxuICApOiBTZXNzaW9uS2V5IHtcbiAgICBjb25zdCBwdWJLZXlYID0gZWNjLnBvaW50WChjdHguYWdnUHVibGljS2V5KTtcblxuICAgIGNvbnN0IGNvZWZmaWNpZW50ID0gZWNjLnRhZ2dlZEhhc2goVEFHUy5tdXNpZ19ub25jZWNvZWYsIGFnZ05vbmNlLCBwdWJLZXlYLCBtc2cpO1xuXG4gICAgY29uc3QgYWdnTm9uY2VzID0gW2FnZ05vbmNlLnN1YmFycmF5KDAsIDMzKSwgYWdnTm9uY2Uuc3ViYXJyYXkoMzMpXTtcblxuICAgIC8vIFRoaXMgaXMga2luZGEgdWdseSwgYnV0IGNyeXB0by5wb2ludEFkZCBkb2Vzbid0IHdvcmsgb24gMC1jb2RlZCBpbmZpbml0eVxuICAgIGxldCByOiBVaW50OEFycmF5IHwgbnVsbCA9IG51bGw7XG4gICAgaWYgKGNvbXBhcmUzM2IoYWdnTm9uY2VzWzFdLCBDUE9JTlRfSU5GKSAhPT0gMCAmJiBjb21wYXJlMzNiKGFnZ05vbmNlc1swXSwgQ1BPSU5UX0lORikgIT09IDApIHtcbiAgICAgIHIgPSBlY2MucG9pbnRNdWx0aXBseUFuZEFkZFVuc2FmZShhZ2dOb25jZXNbMV0sIGNvZWZmaWNpZW50LCBhZ2dOb25jZXNbMF0sIGZhbHNlKTtcbiAgICB9IGVsc2UgaWYgKGNvbXBhcmUzM2IoYWdnTm9uY2VzWzBdLCBDUE9JTlRfSU5GKSAhPT0gMCkge1xuICAgICAgciA9IGVjYy5wb2ludENvbXByZXNzKGFnZ05vbmNlc1swXSwgZmFsc2UpO1xuICAgIH0gZWxzZSBpZiAoY29tcGFyZTMzYihhZ2dOb25jZXNbMV0sIENQT0lOVF9JTkYpICE9PSAwKSB7XG4gICAgICByID0gZWNjLnBvaW50TXVsdGlwbHlVbnNhZmUoYWdnTm9uY2VzWzFdLCBjb2VmZmljaWVudCwgZmFsc2UpO1xuICAgIH1cbiAgICBpZiAociA9PT0gbnVsbCkgciA9IGVjYy5nZXRQdWJsaWNLZXkoU0NBTEFSXzEsIGZhbHNlKTtcbiAgICBpZiAociA9PT0gbnVsbCkgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gZ2V0IEcnKTtcblxuICAgIGNvbnN0IGNoYWxsZW5nZSA9IGVjYy5zY2FsYXJNb2QoZWNjLnRhZ2dlZEhhc2goVEFHUy5jaGFsbGVuZ2UsIGVjYy5wb2ludFgociksIHB1YktleVgsIG1zZykpO1xuXG4gICAgY29uc3Qga2V5ID0geyBwdWJsaWNLZXk6IGN0eC5hZ2dQdWJsaWNLZXksIGFnZ05vbmNlLCBtc2cgfTtcbiAgICBfc2Vzc2lvbkNhY2hlLnNldChrZXksIHsgLi4uY3R4LCBjb2VmZmljaWVudCwgY2hhbGxlbmdlLCBmaW5hbE5vbmNlOiByLCBwdWJsaWNLZXlzIH0pO1xuICAgIHJldHVybiBrZXk7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJ0aWFsVmVyaWZ5SW5uZXIoe1xuICAgIHNpZyxcbiAgICBwdWJsaWNLZXksXG4gICAgcHVibGljTm9uY2VzLFxuICAgIHNlc3Npb25LZXksXG4gIH06IHtcbiAgICBzaWc6IFVpbnQ4QXJyYXk7XG4gICAgcHVibGljS2V5OiBVaW50OEFycmF5O1xuICAgIHB1YmxpY05vbmNlczogW1VpbnQ4QXJyYXksIFVpbnQ4QXJyYXldO1xuICAgIHNlc3Npb25LZXk6IFNlc3Npb25LZXk7XG4gIH0pOiBib29sZWFuIHtcbiAgICBjb25zdCB7IG1zZyB9ID0gc2Vzc2lvbktleTtcbiAgICBjb25zdCB7IGFnZ1B1YmxpY0tleSwgZ2FjYywgY2hhbGxlbmdlLCBjb2VmZmljaWVudCwgZmluYWxOb25jZSwgcHVibGljS2V5cyB9ID0gZ2V0U2Vzc2lvblZhbHVlcyhzZXNzaW9uS2V5KTtcblxuICAgIGNvbnN0IHJlUHJpbWUgPSBlY2MucG9pbnRNdWx0aXBseUFuZEFkZFVuc2FmZShwdWJsaWNOb25jZXNbMV0sIGNvZWZmaWNpZW50LCBwdWJsaWNOb25jZXNbMF0sIGZhbHNlKTtcbiAgICBpZiAocmVQcmltZSA9PT0gbnVsbCkgdGhyb3cgbmV3IEVycm9yKCdVbmV4cGVjdGVkIHB1YmxpYyBub25jZSBhdCBpbmZpbml0eScpO1xuICAgIGNvbnN0IHJlID0gZWNjLmhhc0V2ZW5ZKGZpbmFsTm9uY2UpID8gcmVQcmltZSA6IGVjYy5wb2ludE5lZ2F0ZShyZVByaW1lKTtcblxuICAgIGNvbnN0IGEgPSBrZXlBZ2dDb2VmZihwdWJsaWNLZXlzLCBwdWJsaWNLZXkpO1xuXG4gICAgY29uc3QgZyA9IGVjYy5oYXNFdmVuWShhZ2dQdWJsaWNLZXkpID8gZ2FjYyA6IGVjYy5zY2FsYXJOZWdhdGUoZ2FjYyk7XG5cbiAgICBjb25zdCBlYSA9IGVjYy5zY2FsYXJNdWx0aXBseShjaGFsbGVuZ2UsIGEpO1xuICAgIGNvbnN0IGVhZyA9IGVjYy5zY2FsYXJNdWx0aXBseShlYSwgZyk7XG4gICAgY29uc3QgdmVyID0gZWNjLnBvaW50TXVsdGlwbHlBbmRBZGRVbnNhZmUocHVibGljS2V5LCBlYWcsIHJlLCB0cnVlKTtcbiAgICBpZiAodmVyID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgdmVyaWZpY2F0aW9uIHBvaW50IGF0IGluZmluaXR5Jyk7XG5cbiAgICBjb25zdCBzRyA9IGVjYy5nZXRQdWJsaWNLZXkoc2lnLCB0cnVlKTtcbiAgICBpZiAoc0cgPT09IG51bGwpIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBzaWduYXR1cmUgcG9pbnQgYXQgaW5maW5pdHknKTtcblxuICAgIHJldHVybiBjb21wYXJlMzNiKHZlciwgc0cpID09PSAwO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFydGlhbFNpZ25Jbm5lcih7XG4gICAgc2VjcmV0S2V5LFxuICAgIHB1YmxpY0tleSxcbiAgICBzZWNyZXROb25jZXMsXG4gICAgc2Vzc2lvbktleSxcbiAgfToge1xuICAgIHNlY3JldEtleTogVWludDhBcnJheTtcbiAgICBwdWJsaWNLZXk6IFVpbnQ4QXJyYXk7XG4gICAgc2VjcmV0Tm9uY2VzOiBbVWludDhBcnJheSwgVWludDhBcnJheV07XG4gICAgc2Vzc2lvbktleTogU2Vzc2lvbktleTtcbiAgfSk6IFVpbnQ4QXJyYXkge1xuICAgIGNvbnN0IHsgbXNnIH0gPSBzZXNzaW9uS2V5O1xuICAgIGNvbnN0IHsgYWdnUHVibGljS2V5LCBnYWNjLCBjaGFsbGVuZ2UsIGNvZWZmaWNpZW50LCBmaW5hbE5vbmNlLCBwdWJsaWNLZXlzIH0gPSBnZXRTZXNzaW9uVmFsdWVzKHNlc3Npb25LZXkpO1xuXG4gICAgY29uc3QgW2sxLCBrMl0gPSBzZWNyZXROb25jZXMubWFwKChrKSA9PiAoZWNjLmhhc0V2ZW5ZKGZpbmFsTm9uY2UpID8gayA6IGVjYy5zY2FsYXJOZWdhdGUoaykpKTtcblxuICAgIGNvbnN0IGEgPSBrZXlBZ2dDb2VmZihwdWJsaWNLZXlzLCBwdWJsaWNLZXkpO1xuXG4gICAgY29uc3QgZyA9IGVjYy5oYXNFdmVuWShhZ2dQdWJsaWNLZXkpID8gZ2FjYyA6IGVjYy5zY2FsYXJOZWdhdGUoZ2FjYyk7XG4gICAgY29uc3QgZCA9IGVjYy5zY2FsYXJNdWx0aXBseShnLCBzZWNyZXRLZXkpO1xuXG4gICAgY29uc3QgYmsyID0gZWNjLnNjYWxhck11bHRpcGx5KGNvZWZmaWNpZW50LCBrMik7XG4gICAgY29uc3QgazFiazIgPSBlY2Muc2NhbGFyQWRkKGsxLCBiazIpO1xuXG4gICAgY29uc3QgZWEgPSBlY2Muc2NhbGFyTXVsdGlwbHkoY2hhbGxlbmdlLCBhKTtcbiAgICBjb25zdCBlYWQgPSBlY2Muc2NhbGFyTXVsdGlwbHkoZWEsIGQpO1xuXG4gICAgY29uc3Qgc2lnID0gZWNjLnNjYWxhckFkZChrMWJrMiwgZWFkKTtcblxuICAgIHJldHVybiBzaWc7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJ0aWFsU2lnbih7XG4gICAgc2VjcmV0S2V5LFxuICAgIHB1YmxpY05vbmNlLFxuICAgIHNlc3Npb25LZXksXG4gICAgdmVyaWZ5ID0gdHJ1ZSxcbiAgfToge1xuICAgIHNlY3JldEtleTogVWludDhBcnJheTtcbiAgICBwdWJsaWNOb25jZTogVWludDhBcnJheTtcbiAgICBzZXNzaW9uS2V5OiBTZXNzaW9uS2V5O1xuICAgIHZlcmlmeTogYm9vbGVhbjtcbiAgfSk6IFVpbnQ4QXJyYXkge1xuICAgIGNoZWNrQXJncyh7IHB1YmxpY05vbmNlLCBzZWNyZXRLZXkgfSk7XG5cbiAgICBjb25zdCBzZWNyZXROb25jZSA9IF9ub25jZUNhY2hlLmdldChwdWJsaWNOb25jZSk7XG4gICAgaWYgKHNlY3JldE5vbmNlID09PSB1bmRlZmluZWQpIHRocm93IG5ldyBFcnJvcignTm8gc2VjcmV0IG5vbmNlIGZvdW5kIGZvciBzcGVjaWZpZWQgcHVibGljIG5vbmNlJyk7XG4gICAgX25vbmNlQ2FjaGUuZGVsZXRlKHB1YmxpY05vbmNlKTtcblxuICAgIGNvbnN0IHB1YmxpY0tleSA9IGVjYy5nZXRQdWJsaWNLZXkoc2VjcmV0S2V5LCB0cnVlKTtcbiAgICBpZiAocHVibGljS2V5ID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc2VjcmV0IGtleSwgbm8gY29ycmVzcG9uZGluZyBwdWJsaWMga2V5Jyk7XG4gICAgaWYgKGNvbXBhcmUzM2IocHVibGljS2V5LCBzZWNyZXROb25jZS5zdWJhcnJheSg2NCkpICE9PSAwKSB0aHJvdyBuZXcgRXJyb3IoJ1NlY3JldCBub25jZSBwdWJrZXkgbWlzbWF0Y2gnKTtcbiAgICBjb25zdCBzZWNyZXROb25jZXM6IFtVaW50OEFycmF5LCBVaW50OEFycmF5XSA9IFtzZWNyZXROb25jZS5zdWJhcnJheSgwLCAzMiksIHNlY3JldE5vbmNlLnN1YmFycmF5KDMyLCA2NCldO1xuICAgIGNvbnN0IHNpZyA9IHBhcnRpYWxTaWduSW5uZXIoe1xuICAgICAgc2VjcmV0S2V5LFxuICAgICAgcHVibGljS2V5LFxuICAgICAgc2VjcmV0Tm9uY2VzLFxuICAgICAgc2Vzc2lvbktleSxcbiAgICB9KTtcblxuICAgIGlmICh2ZXJpZnkpIHtcbiAgICAgIGNvbnN0IHB1YmxpY05vbmNlczogW1VpbnQ4QXJyYXksIFVpbnQ4QXJyYXldID0gW3B1YmxpY05vbmNlLnN1YmFycmF5KDAsIDMzKSwgcHVibGljTm9uY2Uuc3ViYXJyYXkoMzMpXTtcbiAgICAgIGNvbnN0IHZhbGlkID0gcGFydGlhbFZlcmlmeUlubmVyKHtcbiAgICAgICAgc2lnLFxuICAgICAgICBwdWJsaWNLZXksXG4gICAgICAgIHB1YmxpY05vbmNlcyxcbiAgICAgICAgc2Vzc2lvbktleSxcbiAgICAgIH0pO1xuICAgICAgaWYgKCF2YWxpZCkgdGhyb3cgbmV3IEVycm9yKCdQYXJ0aWFsIHNpZ25hdHVyZSBmYWlsZWQgdmVyaWZpY2F0aW9uJyk7XG4gICAgfVxuICAgIHJldHVybiBzaWc7XG4gIH1cblxuICBpbnRlcmZhY2UgRGV0ZXJtaW5pc3RpY1NpZ25BcmdzQmFzZSB7XG4gICAgc2VjcmV0S2V5OiBVaW50OEFycmF5O1xuICAgIGFnZ090aGVyTm9uY2U6IFVpbnQ4QXJyYXk7XG4gICAgcHVibGljS2V5czogVWludDhBcnJheVtdO1xuICAgIHR3ZWFrcz86IFR3ZWFrW107XG4gICAgbXNnOiBVaW50OEFycmF5O1xuICAgIHJhbmQ/OiBVaW50OEFycmF5O1xuICB9XG4gIGludGVyZmFjZSBEZXRlcm1pbmlzdGljU2lnbkFyZ3MgZXh0ZW5kcyBEZXRlcm1pbmlzdGljU2lnbkFyZ3NCYXNlIHtcbiAgICB2ZXJpZnk/OiBib29sZWFuO1xuICAgIG5vbmNlT25seT86IGJvb2xlYW47XG4gIH1cbiAgaW50ZXJmYWNlIERldGVybWluaXN0aWNTaWduQXJnc1NpZ24gZXh0ZW5kcyBEZXRlcm1pbmlzdGljU2lnbkFyZ3NCYXNlIHtcbiAgICB2ZXJpZnk6IGJvb2xlYW47XG4gIH1cbiAgaW50ZXJmYWNlIERldGVybWluaXN0aWNTaWduQXJnc05vbmNlT25seSBleHRlbmRzIERldGVybWluaXN0aWNTaWduQXJnc0Jhc2Uge1xuICAgIG5vbmNlT25seTogdHJ1ZTtcbiAgfVxuICBmdW5jdGlvbiBkZXRlcm1pbmlzdGljU2lnbihhcmdzOiBEZXRlcm1pbmlzdGljU2lnbkFyZ3NTaWduKToge1xuICAgIHNpZzogVWludDhBcnJheTtcbiAgICBzZXNzaW9uS2V5OiBTZXNzaW9uS2V5O1xuICAgIHB1YmxpY05vbmNlOiBVaW50OEFycmF5O1xuICB9O1xuICBmdW5jdGlvbiBkZXRlcm1pbmlzdGljU2lnbihhcmdzOiBEZXRlcm1pbmlzdGljU2lnbkFyZ3NOb25jZU9ubHkpOiB7IHB1YmxpY05vbmNlOiBVaW50OEFycmF5IH07XG4gIGZ1bmN0aW9uIGRldGVybWluaXN0aWNTaWduKHtcbiAgICBzZWNyZXRLZXksXG4gICAgYWdnT3RoZXJOb25jZSxcbiAgICBwdWJsaWNLZXlzLFxuICAgIHR3ZWFrcyA9IFtdLFxuICAgIG1zZyxcbiAgICByYW5kLFxuICAgIHZlcmlmeSA9IHRydWUsXG4gICAgbm9uY2VPbmx5ID0gZmFsc2UsXG4gIH06IERldGVybWluaXN0aWNTaWduQXJncyk6IHtcbiAgICBzaWc/OiBVaW50OEFycmF5O1xuICAgIHNlc3Npb25LZXk/OiBTZXNzaW9uS2V5O1xuICAgIHB1YmxpY05vbmNlOiBVaW50OEFycmF5O1xuICB9IHtcbiAgICAvLyBObyBuZWVkIHRvIGNoZWNrIG1zZywgaXRzIG1heCBzaXplIGlzIGxhcmdlciB0aGFuIEpTIHR5cGVkIGFycmF5IGxpbWl0XG4gICAgY2hlY2tBcmdzKHsgcmFuZCwgc2VjcmV0S2V5LCBhZ2dPdGhlck5vbmNlIH0pO1xuICAgIGNvbnN0IHB1YmxpY0tleSA9IGVjYy5nZXRQdWJsaWNLZXkoc2VjcmV0S2V5LCB0cnVlKTtcbiAgICBpZiAocHVibGljS2V5ID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoJ1NlY3JldCBrZXkgaGFzIG5vIGNvcnJlc3BvbmRpbmcgcHVibGljIGtleScpO1xuXG4gICAgbGV0IHNlY3JldEtleVByaW1lO1xuICAgIGlmIChyYW5kICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHNlY3JldEtleVByaW1lID0gZWNjLnRhZ2dlZEhhc2goVEFHUy5tdXNpZ19hdXgsIHJhbmQpO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAzMjsgaSsrKSB7XG4gICAgICAgIHNlY3JldEtleVByaW1lW2ldID0gc2VjcmV0S2V5UHJpbWVbaV0gXiBzZWNyZXRLZXlbaV07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlY3JldEtleVByaW1lID0gc2VjcmV0S2V5O1xuICAgIH1cbiAgICBjb25zdCBjdHggPSBrZXlBZ2cocHVibGljS2V5cywgLi4udHdlYWtzKTtcbiAgICBjb25zdCBhZ2dQdWJsaWNLZXkgPSBlY2MucG9pbnRYKGN0eC5hZ2dQdWJsaWNLZXkpO1xuXG4gICAgY29uc3QgbUxlbmd0aCA9IG5ldyBVaW50OEFycmF5KDgpO1xuICAgIG5ldyBEYXRhVmlldyhtTGVuZ3RoLmJ1ZmZlcikuc2V0QmlnVWludDY0KDAsIEJpZ0ludChtc2cubGVuZ3RoKSk7XG5cbiAgICBjb25zdCBzZWNyZXROb25jZSA9IG5ldyBVaW50OEFycmF5KDk3KTtcbiAgICBjb25zdCBwdWJsaWNOb25jZSA9IG5ldyBVaW50OEFycmF5KDY2KTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDI7IGkrKykge1xuICAgICAgY29uc3Qga0ggPSBlY2MudGFnZ2VkSGFzaChcbiAgICAgICAgVEFHUy5tdXNpZ19kZXRlcm1pbmlzdGljX25vbmNlLFxuICAgICAgICAuLi5bc2VjcmV0S2V5UHJpbWUsIGFnZ090aGVyTm9uY2UsIGFnZ1B1YmxpY0tleSwgbUxlbmd0aCwgbXNnLCBVaW50OEFycmF5Lm9mKGkpXVxuICAgICAgKTtcbiAgICAgIGNvbnN0IGsgPSBlY2Muc2NhbGFyTW9kKGtIKTtcbiAgICAgIGlmIChjb21wYXJlMzJiKFNDQUxBUl8wLCBrKSA9PT0gMCkgdGhyb3cgbmV3IEVycm9yKCcwIHNlY3JldCBub25jZScpO1xuICAgICAgY29uc3QgcHViID0gZWNjLmdldFB1YmxpY0tleShrLCB0cnVlKTtcbiAgICAgIGlmIChwdWIgPT09IG51bGwpIHRocm93IG5ldyBFcnJvcignU2VjcmV0IG5vbmNlIGhhcyBubyBjb3JyZXNwb25kaW5nIHB1YmxpYyBub25jZScpO1xuXG4gICAgICBzZWNyZXROb25jZS5zZXQoaywgaSAqIDMyKTtcbiAgICAgIHB1YmxpY05vbmNlLnNldChwdWIsIGkgKiAzMyk7XG4gICAgfVxuICAgIHNlY3JldE5vbmNlLnNldChwdWJsaWNLZXksIDY0KTtcblxuICAgIGlmIChub25jZU9ubHkpIHJldHVybiB7IHB1YmxpY05vbmNlIH07XG5cbiAgICBfbm9uY2VDYWNoZS5zZXQocHVibGljTm9uY2UsIHNlY3JldE5vbmNlKTtcbiAgICBjb25zdCBhZ2dOb25jZSA9IG5vbmNlQWdnKFthZ2dPdGhlck5vbmNlLCBwdWJsaWNOb25jZV0pO1xuICAgIGNvbnN0IHNlc3Npb25LZXkgPSBzdGFydFNpZ25pbmdTZXNzaW9uSW5uZXIoYWdnTm9uY2UsIG1zZywgcHVibGljS2V5cywgY3R4KTtcbiAgICBjb25zdCBzaWcgPSBwYXJ0aWFsU2lnbih7XG4gICAgICBzZWNyZXRLZXksXG4gICAgICBwdWJsaWNOb25jZSxcbiAgICAgIHNlc3Npb25LZXksXG4gICAgICB2ZXJpZnksXG4gICAgfSk7XG5cbiAgICByZXR1cm4geyBzaWcsIHNlc3Npb25LZXksIHB1YmxpY05vbmNlIH07XG4gIH1cblxuICAvLyBUT0RPOiBJbXByb3ZlIGFyZyBjaGVja2luZyBub3cgdGhhdCB3ZSBoYXZlIHN0YXJ0U2lnbmluZ1Nlc3Npb25cbiAgY29uc3QgcHViS2V5QXJncyA9IFsncHVibGljS2V5JywgJ3B1YmxpY0tleXMnXSBhcyBjb25zdDtcbiAgY29uc3Qgc2NhbGFyQXJncyA9IFsndHdlYWsnLCAnc2lnJywgJ3NpZ3MnLCAndGFjYycsICdnYWNjJ10gYXMgY29uc3Q7XG4gIGNvbnN0IG90aGVyQXJnczMyYiA9IFsneE9ubHlQdWJsaWNLZXknLCAncmFuZCcsICdzZXNzaW9uSWQnXSBhcyBjb25zdDtcbiAgY29uc3QgYXJnczMyYiA9IFsnc2VjcmV0S2V5JywgLi4uc2NhbGFyQXJncywgLi4ub3RoZXJBcmdzMzJiXSBhcyBjb25zdDtcbiAgY29uc3QgcHViTm9uY2VBcmdzID0gWydwdWJsaWNOb25jZScsICdwdWJsaWNOb25jZXMnLCAnYWdnTm9uY2UnLCAnYWdnT3RoZXJOb25jZScsICdmaW5hbE5vbmNlJ10gYXMgY29uc3Q7XG4gIGNvbnN0IG90aGVyQXJncyA9IFsnYWdnUHVibGljS2V5JywgJ3NlY3JldE5vbmNlJ10gYXMgY29uc3Q7XG4gIHR5cGUgQXJnTmFtZSA9XG4gICAgfCB0eXBlb2YgcHViS2V5QXJnc1tudW1iZXJdXG4gICAgfCB0eXBlb2YgYXJnczMyYltudW1iZXJdXG4gICAgfCB0eXBlb2YgcHViTm9uY2VBcmdzW251bWJlcl1cbiAgICB8IHR5cGVvZiBvdGhlckFyZ3NbbnVtYmVyXTtcbiAgdHlwZSBBcmdzID0geyBbQSBpbiBBcmdOYW1lXT86IFVpbnQ4QXJyYXkgfCBVaW50OEFycmF5W10gfTtcblxuICBjb25zdCBhcmdMZW5ndGhzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgYXJnczMyYi5mb3JFYWNoKChhKSA9PiBhcmdMZW5ndGhzLnNldChhLCAzMikpO1xuICBwdWJLZXlBcmdzLmZvckVhY2goKGEpID0+IGFyZ0xlbmd0aHMuc2V0KGEsIDMzKSk7XG4gIHB1Yk5vbmNlQXJncy5mb3JFYWNoKChhKSA9PiBhcmdMZW5ndGhzLnNldChhLCA2NikpO1xuICBhcmdMZW5ndGhzLnNldCgnc2VjcmV0Tm9uY2UnLCA5Nyk7XG4gIGFyZ0xlbmd0aHMuc2V0KCdhZ2dQdWJsaWNLZXknLCA2NSk7XG4gIGNvbnN0IHNjYWxhck5hbWVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIHNjYWxhckFyZ3MuZm9yRWFjaCgobikgPT4gc2NhbGFyTmFtZXMuYWRkKG4pKTtcblxuICBmdW5jdGlvbiBjaGVja0FyZ3MoYXJnczogQXJncyk6IHZvaWQge1xuICAgIGZvciAobGV0IFtuYW1lLCB2YWx1ZXNdIG9mIE9iamVjdC5lbnRyaWVzKGFyZ3MpKSB7XG4gICAgICBpZiAodmFsdWVzID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgICAgdmFsdWVzID0gQXJyYXkuaXNBcnJheSh2YWx1ZXMpID8gdmFsdWVzIDogW3ZhbHVlc107XG4gICAgICBpZiAodmFsdWVzLmxlbmd0aCA9PT0gMCkgdGhyb3cgbmV3IFR5cGVFcnJvcihgMC1sZW5ndGggJHtuYW1lfXMgbm90IHN1cHBvcnRlZGApO1xuICAgICAgZm9yIChjb25zdCB2YWx1ZSBvZiB2YWx1ZXMpIHtcbiAgICAgICAgaWYgKGFyZ0xlbmd0aHMuZ2V0KG5hbWUpICE9PSB2YWx1ZS5sZW5ndGgpIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgJHtuYW1lfSBsZW5ndGggKCR7dmFsdWUubGVuZ3RofSlgKTtcbiAgICAgICAgaWYgKG5hbWUgPT09ICdzZWNyZXRLZXknKSB7XG4gICAgICAgICAgaWYgKCFlY2MuaXNTZWNyZXQodmFsdWUpKSB0aHJvdyBuZXcgVHlwZUVycm9yKGBJbnZhbGlkIHNlY3JldEtleWApO1xuICAgICAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdzZWNyZXROb25jZScpIHtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDY0OyBpICs9IDMyKSB7XG4gICAgICAgICAgICBpZiAoIWVjYy5pc1NlY3JldCh2YWx1ZS5zdWJhcnJheShpLCBpICsgMzIpKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihgSW52YWxpZCBzZWNyZXROb25jZWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChzY2FsYXJOYW1lcy5oYXMobmFtZSkpIHtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSArPSAzMikge1xuICAgICAgICAgICAgaWYgKCFlY2MuaXNTY2FsYXIodmFsdWUuc3ViYXJyYXkoaSwgaSArIDMyKSkpIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgJHtuYW1lfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBObyBuZWVkIGZvciBhIHB1YmxpYyBrZXkgeC10by1jdXJ2ZSBjaGVjay4gVGhleSdyZSBsaWZ0WCdkIGZvciB1c2UgYW55IHdheS5cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGdldFhPbmx5UHVia2V5OiAoY3R4OiBLZXlHZW5Db250ZXh0IHwgU2Vzc2lvbktleSk6IFVpbnQ4QXJyYXkgPT4ge1xuICAgICAgaWYgKCdhZ2dQdWJsaWNLZXknIGluIGN0eCkgcmV0dXJuIGVjYy5wb2ludFgoY3R4LmFnZ1B1YmxpY0tleSk7XG4gICAgICByZXR1cm4gZWNjLnBvaW50WChnZXRTZXNzaW9uVmFsdWVzKGN0eCkuYWdnUHVibGljS2V5KTtcbiAgICB9LFxuICAgIGdldFBsYWluUHVia2V5OiAoY3R4OiBLZXlHZW5Db250ZXh0IHwgU2Vzc2lvbktleSk6IFVpbnQ4QXJyYXkgPT4ge1xuICAgICAgaWYgKCdhZ2dQdWJsaWNLZXknIGluIGN0eCkgcmV0dXJuIGVjYy5wb2ludENvbXByZXNzKGN0eC5hZ2dQdWJsaWNLZXkpO1xuICAgICAgcmV0dXJuIGVjYy5wb2ludENvbXByZXNzKGdldFNlc3Npb25WYWx1ZXMoY3R4KS5hZ2dQdWJsaWNLZXkpO1xuICAgIH0sXG4gICAga2V5U29ydDogKHB1YmxpY0tleXM6IFVpbnQ4QXJyYXlbXSk6IFVpbnQ4QXJyYXlbXSA9PiB7XG4gICAgICBjaGVja0FyZ3MoeyBwdWJsaWNLZXlzIH0pO1xuICAgICAgLy8gZG8gbm90IG1vZGlmeSB0aGUgb3JpZ2luYWwgYXJyYXlcbiAgICAgIHJldHVybiBbLi4ucHVibGljS2V5c10uc29ydCgoYSwgYikgPT4gY29tcGFyZTMzYihhLCBiKSk7XG4gICAgfSxcbiAgICBrZXlBZ2csXG4gICAgYWRkVHdlYWtzOiAoY3R4OiBLZXlHZW5Db250ZXh0LCAuLi50d2Vha3M6IFR3ZWFrW10pOiBLZXlHZW5Db250ZXh0ID0+IHtcbiAgICAgIGNoZWNrQXJncyhjdHgpO1xuICAgICAgcmV0dXJuIHR3ZWFrcy5yZWR1Y2UoKGMsIHR3ZWFrKSA9PiBhZGRUd2VhayhjLCB0d2VhayksIGN0eCk7XG4gICAgfSxcblxuICAgIG5vbmNlR2VuOiAoe1xuICAgICAgc2Vzc2lvbklkID0gbWFrZVNlc3Npb25JZCgpLFxuICAgICAgc2VjcmV0S2V5LFxuICAgICAgcHVibGljS2V5LFxuICAgICAgeE9ubHlQdWJsaWNLZXksXG4gICAgICBtc2csXG4gICAgICBleHRyYUlucHV0LFxuICAgIH06IHtcbiAgICAgIHNlc3Npb25JZDogVWludDhBcnJheTtcbiAgICAgIHNlY3JldEtleT86IFVpbnQ4QXJyYXk7XG4gICAgICBwdWJsaWNLZXk6IFVpbnQ4QXJyYXk7XG4gICAgICB4T25seVB1YmxpY0tleT86IFVpbnQ4QXJyYXk7XG4gICAgICBtc2c/OiBVaW50OEFycmF5O1xuICAgICAgZXh0cmFJbnB1dD86IFVpbnQ4QXJyYXk7XG4gICAgfSk6IFVpbnQ4QXJyYXkgPT4ge1xuICAgICAgaWYgKGV4dHJhSW5wdXQgIT09IHVuZGVmaW5lZCAmJiBleHRyYUlucHV0Lmxlbmd0aCA+IE1hdGgucG93KDIsIDMyKSAtIDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZXh0cmFJbnB1dCBpcyBsaW1pdGVkIHRvIDJeMzItMSBieXRlcycpO1xuICAgICAgfVxuICAgICAgLy8gTm8gbmVlZCB0byBjaGVjayBtc2csIGl0cyBtYXggc2l6ZSBpcyBsYXJnZXIgdGhhbiBKUyB0eXBlZCBhcnJheSBsaW1pdFxuICAgICAgY2hlY2tBcmdzKHsgc2Vzc2lvbklkLCBzZWNyZXRLZXksIHB1YmxpY0tleSwgeE9ubHlQdWJsaWNLZXkgfSk7XG4gICAgICBsZXQgcmFuZDogVWludDhBcnJheTtcbiAgICAgIGlmIChzZWNyZXRLZXkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByYW5kID0gZWNjLnRhZ2dlZEhhc2goVEFHUy5tdXNpZ19hdXgsIHNlc3Npb25JZCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMzI7IGkrKykge1xuICAgICAgICAgIHJhbmRbaV0gPSByYW5kW2ldIF4gc2VjcmV0S2V5W2ldO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByYW5kID0gc2Vzc2lvbklkO1xuICAgICAgfVxuXG4gICAgICBpZiAoeE9ubHlQdWJsaWNLZXkgPT09IHVuZGVmaW5lZCkgeE9ubHlQdWJsaWNLZXkgPSBuZXcgVWludDhBcnJheSgpO1xuXG4gICAgICBjb25zdCBtUHJlZml4ZWQgPSBbVWludDhBcnJheS5vZigwKV07XG4gICAgICBpZiAobXNnICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbVByZWZpeGVkWzBdWzBdID0gMTtcbiAgICAgICAgbVByZWZpeGVkLnB1c2gobmV3IFVpbnQ4QXJyYXkoOCkpO1xuICAgICAgICBuZXcgRGF0YVZpZXcobVByZWZpeGVkWzFdLmJ1ZmZlcikuc2V0QmlnVWludDY0KDAsIEJpZ0ludChtc2cubGVuZ3RoKSk7XG4gICAgICAgIG1QcmVmaXhlZC5wdXNoKG1zZyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChleHRyYUlucHV0ID09PSB1bmRlZmluZWQpIGV4dHJhSW5wdXQgPSBuZXcgVWludDhBcnJheSgpO1xuICAgICAgY29uc3QgZUxlbmd0aCA9IG5ldyBVaW50OEFycmF5KDQpO1xuICAgICAgbmV3IERhdGFWaWV3KGVMZW5ndGguYnVmZmVyKS5zZXRVaW50MzIoMCwgZXh0cmFJbnB1dC5sZW5ndGgpO1xuXG4gICAgICBjb25zdCBzZWNyZXROb25jZSA9IG5ldyBVaW50OEFycmF5KDk3KTtcbiAgICAgIGNvbnN0IHB1YmxpY05vbmNlID0gbmV3IFVpbnQ4QXJyYXkoNjYpO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAyOyBpKyspIHtcbiAgICAgICAgY29uc3Qga0ggPSBlY2MudGFnZ2VkSGFzaChcbiAgICAgICAgICBUQUdTLm11c2lnX25vbmNlLFxuICAgICAgICAgIHJhbmQsXG4gICAgICAgICAgVWludDhBcnJheS5vZihwdWJsaWNLZXkubGVuZ3RoKSxcbiAgICAgICAgICBwdWJsaWNLZXksXG4gICAgICAgICAgVWludDhBcnJheS5vZih4T25seVB1YmxpY0tleS5sZW5ndGgpLFxuICAgICAgICAgIHhPbmx5UHVibGljS2V5LFxuICAgICAgICAgIC4uLm1QcmVmaXhlZCxcbiAgICAgICAgICBlTGVuZ3RoLFxuICAgICAgICAgIGV4dHJhSW5wdXQsXG4gICAgICAgICAgVWludDhBcnJheS5vZihpKVxuICAgICAgICApO1xuICAgICAgICBjb25zdCBrID0gZWNjLnNjYWxhck1vZChrSCk7XG4gICAgICAgIGlmIChjb21wYXJlMzJiKFNDQUxBUl8wLCBrKSA9PT0gMCkgdGhyb3cgbmV3IEVycm9yKCcwIHNlY3JldCBub25jZScpO1xuICAgICAgICBjb25zdCBwdWIgPSBlY2MuZ2V0UHVibGljS2V5KGssIHRydWUpO1xuICAgICAgICBpZiAocHViID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoJ1NlY3JldCBub25jZSBoYXMgbm8gY29ycmVzcG9uZGluZyBwdWJsaWMgbm9uY2UnKTtcblxuICAgICAgICBzZWNyZXROb25jZS5zZXQoaywgaSAqIDMyKTtcbiAgICAgICAgcHVibGljTm9uY2Uuc2V0KHB1YiwgaSAqIDMzKTtcbiAgICAgIH1cbiAgICAgIHNlY3JldE5vbmNlLnNldChwdWJsaWNLZXksIDY0KTtcbiAgICAgIF9ub25jZUNhY2hlLnNldChwdWJsaWNOb25jZSwgc2VjcmV0Tm9uY2UpO1xuICAgICAgcmV0dXJuIHB1YmxpY05vbmNlO1xuICAgIH0sXG5cbiAgICBhZGRFeHRlcm5hbE5vbmNlOiAocHVibGljTm9uY2U6IFVpbnQ4QXJyYXksIHNlY3JldE5vbmNlOiBVaW50OEFycmF5KTogdm9pZCA9PiB7XG4gICAgICBjaGVja0FyZ3MoeyBwdWJsaWNOb25jZSwgc2VjcmV0Tm9uY2UgfSk7XG4gICAgICBfbm9uY2VDYWNoZS5zZXQocHVibGljTm9uY2UsIHNlY3JldE5vbmNlKTtcbiAgICB9LFxuXG4gICAgZGV0ZXJtaW5pc3RpY05vbmNlR2VuOiAoYXJnczogRGV0ZXJtaW5pc3RpY1NpZ25BcmdzQmFzZSk6IHsgcHVibGljTm9uY2U6IFVpbnQ4QXJyYXkgfSA9PlxuICAgICAgZGV0ZXJtaW5pc3RpY1NpZ24oeyAuLi5hcmdzLCBub25jZU9ubHk6IHRydWUgfSksXG5cbiAgICBkZXRlcm1pbmlzdGljU2lnbixcblxuICAgIG5vbmNlQWdnLFxuXG4gICAgc3RhcnRTaWduaW5nU2Vzc2lvbjogKFxuICAgICAgYWdnTm9uY2U6IFVpbnQ4QXJyYXksXG4gICAgICBtc2c6IFVpbnQ4QXJyYXksXG4gICAgICBwdWJsaWNLZXlzOiBVaW50OEFycmF5W10sXG4gICAgICAuLi50d2Vha3M6IFR3ZWFrW11cbiAgICApOiBTZXNzaW9uS2V5ID0+IHtcbiAgICAgIGNoZWNrQXJncyh7IGFnZ05vbmNlIH0pO1xuICAgICAgY29uc3QgY3R4ID0ga2V5QWdnKHB1YmxpY0tleXMsIC4uLnR3ZWFrcyk7XG4gICAgICByZXR1cm4gc3RhcnRTaWduaW5nU2Vzc2lvbklubmVyKGFnZ05vbmNlLCBtc2csIHB1YmxpY0tleXMsIGN0eCk7XG4gICAgfSxcblxuICAgIHBhcnRpYWxTaWduLFxuXG4gICAgcGFydGlhbFZlcmlmeTogKHtcbiAgICAgIHNpZyxcbiAgICAgIHB1YmxpY0tleSxcbiAgICAgIHB1YmxpY05vbmNlLFxuICAgICAgc2Vzc2lvbktleSxcbiAgICB9OiB7XG4gICAgICBzaWc6IFVpbnQ4QXJyYXk7XG4gICAgICBwdWJsaWNLZXk6IFVpbnQ4QXJyYXk7XG4gICAgICBwdWJsaWNOb25jZTogVWludDhBcnJheTtcbiAgICAgIHNlc3Npb25LZXk6IFNlc3Npb25LZXk7XG4gICAgfSk6IGJvb2xlYW4gPT4ge1xuICAgICAgY2hlY2tBcmdzKHsgc2lnLCBwdWJsaWNLZXksIHB1YmxpY05vbmNlIH0pO1xuXG4gICAgICBjb25zdCBwdWJsaWNOb25jZXM6IFtVaW50OEFycmF5LCBVaW50OEFycmF5XSA9IFtwdWJsaWNOb25jZS5zdWJhcnJheSgwLCAzMyksIHB1YmxpY05vbmNlLnN1YmFycmF5KDMzKV07XG5cbiAgICAgIGNvbnN0IHZhbGlkID0gcGFydGlhbFZlcmlmeUlubmVyKHtcbiAgICAgICAgc2lnLFxuICAgICAgICBwdWJsaWNLZXksXG4gICAgICAgIHB1YmxpY05vbmNlcyxcbiAgICAgICAgc2Vzc2lvbktleSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHZhbGlkO1xuICAgIH0sXG5cbiAgICBzaWduQWdnOiAoc2lnczogVWludDhBcnJheVtdLCBzZXNzaW9uS2V5OiBTZXNzaW9uS2V5KTogVWludDhBcnJheSA9PiB7XG4gICAgICBjaGVja0FyZ3MoeyBzaWdzIH0pO1xuXG4gICAgICBjb25zdCB7IGFnZ1B1YmxpY0tleSwgdGFjYywgY2hhbGxlbmdlLCBmaW5hbE5vbmNlIH0gPSBnZXRTZXNzaW9uVmFsdWVzKHNlc3Npb25LZXkpO1xuICAgICAgbGV0IHNQYXJ0OiBVaW50OEFycmF5ID0gZWNjLnNjYWxhck11bHRpcGx5KGNoYWxsZW5nZSwgdGFjYyk7XG4gICAgICBpZiAoIWVjYy5oYXNFdmVuWShhZ2dQdWJsaWNLZXkpKSB7XG4gICAgICAgIHNQYXJ0ID0gZWNjLnNjYWxhck5lZ2F0ZShzUGFydCk7XG4gICAgICB9XG4gICAgICBjb25zdCBhZ2dTID0gc2lncy5yZWR1Y2UoKGEsIGIpID0+IGVjYy5zY2FsYXJBZGQoYSwgYiksIHNQYXJ0KTtcbiAgICAgIGNvbnN0IHNpZyA9IG5ldyBVaW50OEFycmF5KDY0KTtcbiAgICAgIHNpZy5zZXQoZWNjLnBvaW50WChmaW5hbE5vbmNlKSwgMCk7XG4gICAgICBzaWcuc2V0KGFnZ1MsIDMyKTtcbiAgICAgIHJldHVybiBzaWc7XG4gICAgfSxcbiAgfTtcbn1cbiJdfQ==