@bitgo/sdk-coin-atom 3.18.0 → 4.0.0

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 (44) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/src/atom.d.ts +7 -115
  3. package/dist/src/atom.d.ts.map +1 -1
  4. package/dist/src/atom.js +12 -491
  5. package/dist/src/lib/constants.d.ts +0 -6
  6. package/dist/src/lib/constants.d.ts.map +1 -1
  7. package/dist/src/lib/constants.js +2 -8
  8. package/dist/src/lib/index.d.ts +3 -8
  9. package/dist/src/lib/index.d.ts.map +1 -1
  10. package/dist/src/lib/index.js +11 -16
  11. package/dist/src/lib/keyPair.d.ts +3 -12
  12. package/dist/src/lib/keyPair.d.ts.map +1 -1
  13. package/dist/src/lib/keyPair.js +4 -42
  14. package/dist/src/lib/transactionBuilderFactory.d.ts +7 -11
  15. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
  16. package/dist/src/lib/transactionBuilderFactory.js +16 -11
  17. package/dist/src/lib/utils.d.ts +5 -181
  18. package/dist/src/lib/utils.d.ts.map +1 -1
  19. package/dist/src/lib/utils.js +8 -537
  20. package/dist/src/tatom.d.ts +0 -8
  21. package/dist/src/tatom.d.ts.map +1 -1
  22. package/dist/src/tatom.js +1 -13
  23. package/package.json +9 -14
  24. package/dist/src/lib/StakingActivateBuilder.d.ts +0 -11
  25. package/dist/src/lib/StakingActivateBuilder.d.ts.map +0 -1
  26. package/dist/src/lib/StakingActivateBuilder.js +0 -31
  27. package/dist/src/lib/StakingDeactivateBuilder.d.ts +0 -11
  28. package/dist/src/lib/StakingDeactivateBuilder.d.ts.map +0 -1
  29. package/dist/src/lib/StakingDeactivateBuilder.js +0 -31
  30. package/dist/src/lib/StakingWithdrawRewardsBuilder.d.ts +0 -11
  31. package/dist/src/lib/StakingWithdrawRewardsBuilder.d.ts.map +0 -1
  32. package/dist/src/lib/StakingWithdrawRewardsBuilder.js +0 -31
  33. package/dist/src/lib/iface.d.ts +0 -46
  34. package/dist/src/lib/iface.d.ts.map +0 -1
  35. package/dist/src/lib/iface.js +0 -3
  36. package/dist/src/lib/transaction.d.ts +0 -58
  37. package/dist/src/lib/transaction.d.ts.map +0 -1
  38. package/dist/src/lib/transaction.js +0 -279
  39. package/dist/src/lib/transactionBuilder.d.ts +0 -78
  40. package/dist/src/lib/transactionBuilder.d.ts.map +0 -1
  41. package/dist/src/lib/transactionBuilder.js +0 -179
  42. package/dist/src/lib/transferBuilder.d.ts +0 -11
  43. package/dist/src/lib/transferBuilder.d.ts.map +0 -1
  44. package/dist/src/lib/transferBuilder.js +0 -31
package/dist/src/atom.js CHANGED
@@ -1,45 +1,18 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
- Object.defineProperty(o, "default", { enumerable: true, value: v });
11
- }) : function(o, v) {
12
- o["default"] = v;
13
- });
14
- var __importStar = (this && this.__importStar) || function (mod) {
15
- if (mod && mod.__esModule) return mod;
16
- var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
- __setModuleDefault(result, mod);
19
- return result;
20
- };
21
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
22
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
4
  };
24
5
  Object.defineProperty(exports, "__esModule", { value: true });
25
6
  exports.Atom = void 0;
7
+ const abstract_cosmos_1 = require("@bitgo/abstract-cosmos");
26
8
  const sdk_core_1 = require("@bitgo/sdk-core");
27
- const sdk_lib_mpc_1 = require("@bitgo/sdk-lib-mpc");
28
9
  const statics_1 = require("@bitgo/statics");
29
- const utxo_lib_1 = require("@bitgo/utxo-lib");
30
- const bignumber_js_1 = require("bignumber.js");
31
- const crypto_1 = require("crypto");
32
- const _ = __importStar(require("lodash"));
33
- const utils_1 = __importDefault(require("./lib/utils"));
34
- const url_1 = __importDefault(require("url"));
35
- const querystring_1 = __importDefault(require("querystring"));
36
10
  const lib_1 = require("./lib");
37
- const request = __importStar(require("superagent"));
38
- const buffer_1 = require("buffer");
39
11
  const constants_1 = require("./lib/constants");
40
- class Atom extends sdk_core_1.BaseCoin {
12
+ const utils_1 = __importDefault(require("./lib/utils"));
13
+ class Atom extends abstract_cosmos_1.CosmosCoin {
41
14
  constructor(bitgo, staticsCoin) {
42
- super(bitgo);
15
+ super(bitgo, staticsCoin);
43
16
  if (!staticsCoin) {
44
17
  throw new Error('missing required constructor parameter staticsCoin');
45
18
  }
@@ -52,34 +25,6 @@ class Atom extends sdk_core_1.BaseCoin {
52
25
  getBaseFactor() {
53
26
  return 1e6;
54
27
  }
55
- /** @inheritDoc **/
56
- getChain() {
57
- return this._staticsCoin.name;
58
- }
59
- /** @inheritDoc **/
60
- getFamily() {
61
- return this._staticsCoin.family;
62
- }
63
- /** @inheritDoc **/
64
- getFullName() {
65
- return this._staticsCoin.fullName;
66
- }
67
- /** @inheritDoc */
68
- supportsTss() {
69
- return true;
70
- }
71
- /** @inheritDoc **/
72
- getMPCAlgorithm() {
73
- return 'ecdsa';
74
- }
75
- /** @inheritDoc **/
76
- isValidPub(pub) {
77
- return utils_1.default.isValidPublicKey(pub);
78
- }
79
- /** @inheritDoc **/
80
- isValidPrv(prv) {
81
- return utils_1.default.isValidPrivateKey(prv);
82
- }
83
28
  getBuilder() {
84
29
  return new lib_1.TransactionBuilderFactory(statics_1.coins.get(this.getChain()));
85
30
  }
@@ -88,284 +33,19 @@ class Atom extends sdk_core_1.BaseCoin {
88
33
  return utils_1.default.isValidAddress(address) || utils_1.default.isValidValidatorAddress(address);
89
34
  }
90
35
  /** @inheritDoc **/
91
- async verifyTransaction(params) {
92
- var _a;
93
- let totalAmount = new bignumber_js_1.BigNumber(0);
94
- const coinConfig = statics_1.coins.get(this.getChain());
95
- const { txPrebuild, txParams } = params;
96
- const rawTx = txPrebuild.txHex;
97
- if (!rawTx) {
98
- throw new Error('missing required tx prebuild property txHex');
99
- }
100
- const transaction = await new lib_1.TransactionBuilderFactory(coinConfig).from(rawTx).build();
101
- const explainedTx = transaction.explainTransaction();
102
- if (txParams.recipients && txParams.recipients.length > 0) {
103
- const filteredRecipients = (_a = txParams.recipients) === null || _a === void 0 ? void 0 : _a.map((recipient) => _.pick(recipient, ['address', 'amount']));
104
- const filteredOutputs = explainedTx.outputs.map((output) => _.pick(output, ['address', 'amount']));
105
- if (!_.isEqual(filteredOutputs, filteredRecipients)) {
106
- throw new Error('Tx outputs does not match with expected txParams recipients');
107
- }
108
- // WithdrawDelegatorRewards transaction doesn't have amount
109
- if (transaction.type !== sdk_core_1.TransactionType.StakingWithdraw) {
110
- for (const recipients of txParams.recipients) {
111
- totalAmount = totalAmount.plus(recipients.amount);
112
- }
113
- if (!totalAmount.isEqualTo(explainedTx.outputAmount)) {
114
- throw new Error('Tx total amount does not match with expected total amount field');
115
- }
116
- }
117
- }
118
- return true;
119
- }
120
- /** @inheritDoc **/
121
- async parseTransaction(params) {
122
- const transactionExplanation = await this.explainTransaction({ txHex: params.txHex });
123
- if (!transactionExplanation) {
124
- throw new Error('Invalid transaction');
125
- }
126
- if (transactionExplanation.outputs.length <= 0) {
127
- return {
128
- inputs: [],
129
- outputs: [],
130
- };
131
- }
132
- const senderAddress = transactionExplanation.outputs[0].address;
133
- const feeAmount = new bignumber_js_1.BigNumber(transactionExplanation.fee.fee === '' ? '0' : transactionExplanation.fee.fee);
134
- const inputs = [
135
- {
136
- address: senderAddress,
137
- amount: new bignumber_js_1.BigNumber(transactionExplanation.outputAmount).plus(feeAmount).toFixed(),
138
- },
139
- ];
140
- const outputs = transactionExplanation.outputs.map((output) => {
141
- return {
142
- address: output.address,
143
- amount: new bignumber_js_1.BigNumber(output.amount).toFixed(),
144
- };
145
- });
146
- return {
147
- inputs,
148
- outputs,
149
- };
150
- }
151
- /** @inheritDoc **/
152
- async explainTransaction(options) {
153
- if (!options.txHex) {
154
- throw new Error('missing required txHex parameter');
155
- }
156
- try {
157
- const transactionBuilder = new lib_1.TransactionBuilderFactory(statics_1.coins.get(this.getChain())).from(options.txHex);
158
- const transaction = await transactionBuilder.build();
159
- return transaction.explainTransaction();
160
- }
161
- catch (e) {
162
- throw new Error('Invalid transaction: ' + e.message);
163
- }
36
+ getDenomination() {
37
+ return statics_1.BaseUnit.ATOM;
164
38
  }
165
39
  /** @inheritDoc **/
166
- generateKeyPair(seed) {
167
- if (!seed) {
168
- // An extended private key has both a normal 256 bit private key and a 256
169
- // bit chain code, both of which must be random. 512 bits is therefore the
170
- // maximum entropy and gives us maximum security against cracking.
171
- seed = crypto_1.randomBytes(512 / 8);
172
- }
173
- const extendedKey = utxo_lib_1.bip32.fromSeed(seed);
40
+ getGasAmountDetails() {
174
41
  return {
175
- pub: extendedKey.neutered().toBase58(),
176
- prv: extendedKey.toBase58(),
177
- };
178
- }
179
- /**
180
- * Sign a transaction with a single private key
181
- * @param params parameters in the form of { txPrebuild: {txHex}, prv }
182
- * @returns signed transaction in the form of { txHex }
183
- */
184
- async signTransaction(params) {
185
- var _a;
186
- const txHex = (_a = params === null || params === void 0 ? void 0 : params.txPrebuild) === null || _a === void 0 ? void 0 : _a.txHex;
187
- const privateKey = params === null || params === void 0 ? void 0 : params.prv;
188
- if (!txHex) {
189
- throw new sdk_core_1.SigningError('missing required txPrebuild parameter: params.txPrebuild.txHex');
190
- }
191
- if (!privateKey) {
192
- throw new sdk_core_1.SigningError('missing required prv parameter: params.prv');
193
- }
194
- const txBuilder = new lib_1.TransactionBuilderFactory(statics_1.coins.get(this.getChain())).from(params.txPrebuild.txHex);
195
- txBuilder.sign({ key: params.prv });
196
- const transaction = await txBuilder.build();
197
- if (!transaction) {
198
- throw new sdk_core_1.SigningError('Failed to build signed transaction');
199
- }
200
- const serializedTx = transaction.toBroadcastFormat();
201
- return {
202
- txHex: serializedTx,
203
- };
204
- }
205
- /**
206
- * Builds a funds recovery transaction without BitGo
207
- * @param {RecoveryOptions} params parameters needed to construct and
208
- * (maybe) sign the transaction
209
- *
210
- * @returns {AtomTx} the serialized transaction hex string and index
211
- * of the address being swept
212
- */
213
- async recover(params) {
214
- // Step 1: Check if params contains the required parameters
215
- if (!params.bitgoKey) {
216
- throw new Error('missing bitgoKey');
217
- }
218
- if (!params.recoveryDestination || !this.isValidAddress(params.recoveryDestination)) {
219
- throw new Error('invalid recoveryDestination');
220
- }
221
- if (!params.userKey) {
222
- throw new Error('missing userKey');
223
- }
224
- if (!params.backupKey) {
225
- throw new Error('missing backupKey');
226
- }
227
- if (!params.walletPassphrase) {
228
- throw new Error('missing wallet passphrase');
229
- }
230
- // Step 2: Fetch the bitgo key from params
231
- const bitgoKey = params.bitgoKey.replace(/\s/g, '');
232
- // Step 3: Instantiate the ECDSA signer and fetch the address details
233
- const MPC = new sdk_core_1.Ecdsa();
234
- const chainId = await this.getChainId();
235
- const currPath = 'm/0';
236
- const publicKey = MPC.deriveUnhardened(bitgoKey, currPath).slice(0, 66);
237
- const senderAddress = this.getAddressFromPublicKey(publicKey);
238
- // Step 4: Fetch account details such as accountNo, balance and check for sufficient funds once gasAmount has been deducted
239
- const [accountNumber, sequenceNo] = await this.getAccountDetails(senderAddress);
240
- const balance = new bignumber_js_1.BigNumber(await this.getAccountBalance(senderAddress));
241
- const gasBudget = {
242
- amount: [{ denom: 'uatom', amount: constants_1.GAS_AMOUNT }],
42
+ gasAmount: constants_1.GAS_AMOUNT,
243
43
  gasLimit: constants_1.GAS_LIMIT,
244
44
  };
245
- const gasAmount = new bignumber_js_1.BigNumber(gasBudget.amount[0].amount);
246
- const actualBalance = balance.minus(gasAmount);
247
- if (actualBalance.isLessThanOrEqualTo(0)) {
248
- throw new Error('Did not have enough funds to recover');
249
- }
250
- // Step 5: Once sufficient funds are present, construct the recover tx messsage
251
- const amount = [
252
- {
253
- denom: 'uatom',
254
- amount: actualBalance.toFixed(),
255
- },
256
- ];
257
- const sendMessage = [
258
- {
259
- fromAddress: senderAddress,
260
- toAddress: params.recoveryDestination,
261
- amount: amount,
262
- },
263
- ];
264
- // Step 6: Build the unsigned tx using the constructed message
265
- const txnBuilder = this.getBuilder().getTransferBuilder();
266
- txnBuilder
267
- .messages(sendMessage)
268
- .gasBudget(gasBudget)
269
- .publicKey(publicKey)
270
- .sequence(Number(sequenceNo))
271
- .accountNumber(Number(accountNumber))
272
- .chainId(chainId);
273
- const unsignedTransaction = (await txnBuilder.build());
274
- let serializedTx = unsignedTransaction.toBroadcastFormat();
275
- const signableHex = unsignedTransaction.signablePayload.toString('hex');
276
- const userKey = params.userKey.replace(/\s/g, '');
277
- const backupKey = params.backupKey.replace(/\s/g, '');
278
- const [userKeyCombined, backupKeyCombined] = (() => {
279
- const [userKeyCombined, backupKeyCombined] = this.getKeyCombinedFromTssKeyShares(userKey, backupKey, params.walletPassphrase);
280
- return [userKeyCombined, backupKeyCombined];
281
- })();
282
- if (!userKeyCombined || !backupKeyCombined) {
283
- throw new Error('Missing combined key shares for user or backup');
284
- }
285
- // Step 7: Sign the tx
286
- const signature = await this.signRecoveryTSS(userKeyCombined, backupKeyCombined, signableHex);
287
- const signableBuffer = buffer_1.Buffer.from(signableHex, 'hex');
288
- MPC.verify(signableBuffer, signature, crypto_1.createHash('sha256'));
289
- const atomKeyPair = new lib_1.KeyPair({ pub: publicKey });
290
- txnBuilder.addSignature({ pub: atomKeyPair.getKeys().pub }, buffer_1.Buffer.from(signature.r + signature.s, 'hex'));
291
- const signedTransaction = await txnBuilder.build();
292
- serializedTx = signedTransaction.toBroadcastFormat();
293
- return { serializedTx: serializedTx, scanIndex: 0 };
294
45
  }
295
- /**
296
- * Get balance from public node
297
- */
298
- async getBalanceFromNode(senderAddress) {
299
- const nodeUrl = this.getPublicNodeUrl();
300
- const getBalancePath = 'cosmos/bank/v1beta1/balances/';
301
- const fullEndpoint = nodeUrl + getBalancePath + senderAddress;
302
- try {
303
- return await request.get(fullEndpoint).send();
304
- }
305
- catch (e) {
306
- console.debug(e);
307
- }
308
- throw new Error(`Unable to call endpoint ${getBalancePath + senderAddress} from node: ${nodeUrl}`);
309
- }
310
- /**
311
- * Helper to fetch chainId
312
- */
313
- async getChainId() {
314
- const response = await this.getChainIdFromNode();
315
- if (response.status !== 200) {
316
- throw new Error('Account not found');
317
- }
318
- return response.body.block.header.chain_id;
319
- }
320
- /**
321
- * Get chain id from public node
322
- */
323
- async getChainIdFromNode() {
324
- const nodeUrl = this.getPublicNodeUrl();
325
- const getLatestBlockPath = 'cosmos/base/tendermint/v1beta1/blocks/latest';
326
- const fullEndpoint = nodeUrl + getLatestBlockPath;
327
- try {
328
- return await request.get(fullEndpoint).send();
329
- }
330
- catch (e) {
331
- console.debug(e);
332
- }
333
- throw new Error(`Unable to call endpoint ${getLatestBlockPath} from node: ${nodeUrl}`);
334
- }
335
- /**
336
- * Helper to fetch account number
337
- */
338
- async getAccountDetails(senderAddress) {
339
- const response = await this.getAccountFromNode(senderAddress);
340
- if (response.status !== 200) {
341
- throw new Error('Account not found');
342
- }
343
- return [response.body.account.account_number, response.body.account.sequence];
344
- }
345
- /**
346
- * Get account number from public node
347
- */
348
- async getAccountFromNode(senderAddress) {
349
- const nodeUrl = this.getPublicNodeUrl();
350
- const getAccountPath = 'cosmos/auth/v1beta1/accounts/';
351
- const fullEndpoint = nodeUrl + getAccountPath + senderAddress;
352
- try {
353
- return await request.get(fullEndpoint).send();
354
- }
355
- catch (e) {
356
- console.debug(e);
357
- }
358
- throw new Error(`Unable to call endpoint ${getAccountPath + senderAddress} from node: ${nodeUrl}`);
359
- }
360
- /**
361
- * Helper to fetch account balance
362
- */
363
- async getAccountBalance(senderAddress) {
364
- const response = await this.getBalanceFromNode(senderAddress);
365
- if (response.status !== 200) {
366
- throw new Error('Account not found');
367
- }
368
- return response.body.balances[0].amount;
46
+ /** @inheritDoc **/
47
+ getKeyPair(publicKey) {
48
+ return new lib_1.KeyPair({ pub: publicKey });
369
49
  }
370
50
  /**
371
51
  * Get the public node url from the Environments constant we have defined
@@ -376,165 +56,6 @@ class Atom extends sdk_core_1.BaseCoin {
376
56
  getAddressFromPublicKey(pubKey) {
377
57
  return new lib_1.KeyPair({ pub: pubKey }).getAddress();
378
58
  }
379
- /** @inheritDoc **/
380
- async isWalletAddress(params) {
381
- const addressDetails = this.getAddressDetails(params.address);
382
- if (!this.isValidAddress(addressDetails.address)) {
383
- throw new sdk_core_1.InvalidAddressError(`invalid address: ${addressDetails.address}`);
384
- }
385
- const rootAddress = params.coinSpecific.rootAddress;
386
- if (addressDetails.address !== rootAddress) {
387
- throw new sdk_core_1.UnexpectedAddressError(`address validation failure: ${addressDetails.address} vs ${rootAddress}`);
388
- }
389
- return true;
390
- }
391
- getHashFunction() {
392
- return crypto_1.createHash('sha256');
393
- }
394
- /**
395
- * Process address into address and memo id
396
- *
397
- * @param address the address
398
- * @returns object containing address and memo id
399
- */
400
- getAddressDetails(address) {
401
- const destinationDetails = url_1.default.parse(address);
402
- const destinationAddress = destinationDetails.pathname || '';
403
- // address doesn't have a memo id
404
- if (destinationDetails.pathname === address) {
405
- return {
406
- address: address,
407
- memoId: undefined,
408
- };
409
- }
410
- if (!destinationDetails.query) {
411
- throw new sdk_core_1.InvalidAddressError(`invalid address: ${address}`);
412
- }
413
- const queryDetails = querystring_1.default.parse(destinationDetails.query);
414
- if (!queryDetails.memoId) {
415
- // if there are more properties, the query details need to contain the memo id property
416
- throw new sdk_core_1.InvalidAddressError(`invalid address: ${address}`);
417
- }
418
- if (Array.isArray(queryDetails.memoId)) {
419
- throw new sdk_core_1.InvalidAddressError(`memoId may only be given at most once, but found ${queryDetails.memoId.length} instances in address ${address}`);
420
- }
421
- if (Array.isArray(queryDetails.memoId) && queryDetails.memoId.length !== 1) {
422
- // valid addresses can only contain one memo id
423
- throw new sdk_core_1.InvalidAddressError(`invalid address '${address}', must contain exactly one memoId`);
424
- }
425
- const [memoId] = _.castArray(queryDetails.memoId) || undefined;
426
- if (!this.isValidMemoId(memoId)) {
427
- throw new sdk_core_1.InvalidMemoIdError(`invalid address: '${address}', memoId is not valid`);
428
- }
429
- return {
430
- address: destinationAddress,
431
- memoId,
432
- };
433
- }
434
- /**
435
- * Return boolean indicating whether a memo id is valid
436
- *
437
- * @param memoId memo id
438
- * @returns true if memo id is valid
439
- */
440
- isValidMemoId(memoId) {
441
- return utils_1.default.isValidMemoId(memoId);
442
- }
443
- getKeyCombinedFromTssKeyShares(userPublicOrPrivateKeyShare, backupPrivateOrPublicKeyShare, walletPassphrase) {
444
- let backupPrv;
445
- let userPrv;
446
- try {
447
- backupPrv = this.bitgo.decrypt({
448
- input: backupPrivateOrPublicKeyShare,
449
- password: walletPassphrase,
450
- });
451
- userPrv = this.bitgo.decrypt({
452
- input: userPublicOrPrivateKeyShare,
453
- password: walletPassphrase,
454
- });
455
- }
456
- catch (e) {
457
- throw new Error(`Error decrypting backup keychain: ${e.message}`);
458
- }
459
- const userSigningMaterial = JSON.parse(userPrv);
460
- const backupSigningMaterial = JSON.parse(backupPrv);
461
- if (!userSigningMaterial.backupNShare) {
462
- throw new Error('Invalid user key - missing backupNShare');
463
- }
464
- if (!backupSigningMaterial.userNShare) {
465
- throw new Error('Invalid backup key - missing userNShare');
466
- }
467
- const MPC = new sdk_core_1.Ecdsa();
468
- const userKeyCombined = MPC.keyCombine(userSigningMaterial.pShare, [
469
- userSigningMaterial.bitgoNShare,
470
- userSigningMaterial.backupNShare,
471
- ]);
472
- const userSigningKeyDerived = MPC.keyDerive(userSigningMaterial.pShare, [userSigningMaterial.bitgoNShare, userSigningMaterial.backupNShare], 'm/0');
473
- const userKeyDerivedCombined = {
474
- xShare: userSigningKeyDerived.xShare,
475
- yShares: userKeyCombined.yShares,
476
- };
477
- const backupKeyCombined = MPC.keyCombine(backupSigningMaterial.pShare, [
478
- userSigningKeyDerived.nShares[2],
479
- backupSigningMaterial.bitgoNShare,
480
- ]);
481
- if (userKeyDerivedCombined.xShare.y !== backupKeyCombined.xShare.y ||
482
- userKeyDerivedCombined.xShare.chaincode !== backupKeyCombined.xShare.chaincode) {
483
- throw new Error('Common keychains do not match');
484
- }
485
- return [userKeyDerivedCombined, backupKeyCombined];
486
- }
487
- // TODO(BG-78714): Reduce code duplication between this and eth.ts
488
- async signRecoveryTSS(userKeyCombined, backupKeyCombined, txHex, { rangeProofChallenge, } = {}) {
489
- const MPC = new sdk_core_1.Ecdsa();
490
- const signerOneIndex = userKeyCombined.xShare.i;
491
- const signerTwoIndex = backupKeyCombined.xShare.i;
492
- // Since this is a user <> backup signing, we will reuse the same range proof challenge
493
- rangeProofChallenge =
494
- rangeProofChallenge !== null && rangeProofChallenge !== void 0 ? rangeProofChallenge : sdk_lib_mpc_1.EcdsaTypes.serializeNtildeWithProofs(await sdk_lib_mpc_1.EcdsaRangeProof.generateNtilde());
495
- const userToBackupPaillierChallenge = await sdk_lib_mpc_1.EcdsaPaillierProof.generateP(sdk_core_1.hexToBigInt(userKeyCombined.yShares[signerTwoIndex].n));
496
- const backupToUserPaillierChallenge = await sdk_lib_mpc_1.EcdsaPaillierProof.generateP(sdk_core_1.hexToBigInt(backupKeyCombined.yShares[signerOneIndex].n));
497
- const userXShare = MPC.appendChallenge(userKeyCombined.xShare, rangeProofChallenge, sdk_lib_mpc_1.EcdsaTypes.serializePaillierChallenge({ p: userToBackupPaillierChallenge }));
498
- const userYShare = MPC.appendChallenge(userKeyCombined.yShares[signerTwoIndex], rangeProofChallenge, sdk_lib_mpc_1.EcdsaTypes.serializePaillierChallenge({ p: backupToUserPaillierChallenge }));
499
- const backupXShare = MPC.appendChallenge(backupKeyCombined.xShare, rangeProofChallenge, sdk_lib_mpc_1.EcdsaTypes.serializePaillierChallenge({ p: backupToUserPaillierChallenge }));
500
- const backupYShare = MPC.appendChallenge(backupKeyCombined.yShares[signerOneIndex], rangeProofChallenge, sdk_lib_mpc_1.EcdsaTypes.serializePaillierChallenge({ p: userToBackupPaillierChallenge }));
501
- const signShares = await MPC.signShare(userXShare, userYShare);
502
- const signConvertS21 = await MPC.signConvertStep1({
503
- xShare: backupXShare,
504
- yShare: backupYShare,
505
- kShare: signShares.kShare,
506
- });
507
- const signConvertS12 = await MPC.signConvertStep2({
508
- aShare: signConvertS21.aShare,
509
- wShare: signShares.wShare,
510
- });
511
- const signConvertS21_2 = await MPC.signConvertStep3({
512
- muShare: signConvertS12.muShare,
513
- bShare: signConvertS21.bShare,
514
- });
515
- const [signCombineOne, signCombineTwo] = [
516
- MPC.signCombine({
517
- gShare: signConvertS12.gShare,
518
- signIndex: {
519
- i: signConvertS12.muShare.i,
520
- j: signConvertS12.muShare.j,
521
- },
522
- }),
523
- MPC.signCombine({
524
- gShare: signConvertS21_2.gShare,
525
- signIndex: {
526
- i: signConvertS21_2.signIndex.i,
527
- j: signConvertS21_2.signIndex.j,
528
- },
529
- }),
530
- ];
531
- const MESSAGE = buffer_1.Buffer.from(txHex, 'hex');
532
- const [signA, signB] = [
533
- MPC.sign(MESSAGE, signCombineOne.oShare, signCombineTwo.dShare, crypto_1.createHash('sha256')),
534
- MPC.sign(MESSAGE, signCombineTwo.oShare, signCombineOne.dShare, crypto_1.createHash('sha256')),
535
- ];
536
- return MPC.constructSignature([signA, signB]);
537
- }
538
59
  }
539
60
  exports.Atom = Atom;
540
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRvbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hdG9tLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw4Q0F1QnlCO0FBQ3pCLG9EQUFxRjtBQUNyRiw0Q0FBZ0Y7QUFDaEYsOENBQXdDO0FBQ3hDLCtDQUF5QztBQUN6QyxtQ0FBdUQ7QUFDdkQsMENBQTRCO0FBQzVCLHdEQUFnQztBQUNoQyw4Q0FBc0I7QUFDdEIsOERBQXNDO0FBQ3RDLCtCQUF1RjtBQUN2RixvREFBc0M7QUFDdEMsbUNBQWdDO0FBR2hDLCtDQUF3RDtBQWlDeEQsTUFBYSxJQUFLLFNBQVEsbUJBQVE7SUFFaEMsWUFBc0IsS0FBZ0IsRUFBRSxXQUF1QztRQUM3RSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFYixJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ2hCLE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztTQUN2RTtRQUVELElBQUksQ0FBQyxZQUFZLEdBQUcsV0FBVyxDQUFDO0lBQ2xDLENBQUM7SUFFRCxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQWdCLEVBQUUsV0FBdUM7UUFDN0UsT0FBTyxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVELG1CQUFtQjtJQUNuQixhQUFhO1FBQ1gsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRUQsbUJBQW1CO0lBQ25CLFFBQVE7UUFDTixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxtQkFBbUI7SUFDbkIsU0FBUztRQUNQLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUM7SUFDbEMsQ0FBQztJQUVELG1CQUFtQjtJQUNuQixXQUFXO1FBQ1QsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQztJQUNwQyxDQUFDO0lBRUQs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LE1BQU0sRUFBRSxjQUFjLENBQUMsTUFBTSxFQUFFLG1CQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDckYsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsY0FBYyxDQUFDLE1BQU0sRUFBRSxjQUFjLENBQUMsTUFBTSxFQUFFLG1CQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDdEYsQ0FBQztRQUVGLE9BQU8sR0FBRyxDQUFDLGtCQUFrQixDQUFDLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDaEQsQ0FBQztDQUNGO0FBMW1CRCxvQkEwbUJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQmFzZUNvaW4sXG4gIEJhc2VUcmFuc2FjdGlvbixcbiAgQml0R29CYXNlLFxuICBFY2RzYSxcbiAgRUNEU0EsXG4gIEVDRFNBTWV0aG9kVHlwZXMsXG4gIEVudmlyb25tZW50cyxcbiAgRXhwbGFuYXRpb25SZXN1bHQsXG4gIGhleFRvQmlnSW50LFxuICBJbnZhbGlkQWRkcmVzc0Vycm9yLFxuICBJbnZhbGlkTWVtb0lkRXJyb3IsXG4gIEtleVBhaXIsXG4gIE1QQ0FsZ29yaXRobSxcbiAgUGFyc2VkVHJhbnNhY3Rpb24sXG4gIFBhcnNlVHJhbnNhY3Rpb25PcHRpb25zLFxuICBTaWduZWRUcmFuc2FjdGlvbixcbiAgU2lnbmluZ0Vycm9yLFxuICBTaWduVHJhbnNhY3Rpb25PcHRpb25zLFxuICBUcmFuc2FjdGlvblR5cGUsXG4gIFVuZXhwZWN0ZWRBZGRyZXNzRXJyb3IsXG4gIFZlcmlmeUFkZHJlc3NPcHRpb25zLFxuICBWZXJpZnlUcmFuc2FjdGlvbk9wdGlvbnMsXG59IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgeyBFY2RzYVBhaWxsaWVyUHJvb2YsIEVjZHNhUmFuZ2VQcm9vZiwgRWNkc2FUeXBlcyB9IGZyb20gJ0BiaXRnby9zZGstbGliLW1wYyc7XG5pbXBvcnQgeyBCYXNlQ29pbiBhcyBTdGF0aWNzQmFzZUNvaW4sIENvaW5GYW1pbHksIGNvaW5zIH0gZnJvbSAnQGJpdGdvL3N0YXRpY3MnO1xuaW1wb3J0IHsgYmlwMzIgfSBmcm9tICdAYml0Z28vdXR4by1saWInO1xuaW1wb3J0IHsgQmlnTnVtYmVyIH0gZnJvbSAnYmlnbnVtYmVyLmpzJztcbmltcG9ydCB7IGNyZWF0ZUhhc2gsIEhhc2gsIHJhbmRvbUJ5dGVzIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB1dGlscyBmcm9tICcuL2xpYi91dGlscyc7XG5pbXBvcnQgdXJsIGZyb20gJ3VybCc7XG5pbXBvcnQgcXVlcnlzdHJpbmcgZnJvbSAncXVlcnlzdHJpbmcnO1xuaW1wb3J0IHsgS2V5UGFpciBhcyBBdG9tS2V5UGFpciwgVHJhbnNhY3Rpb24sIFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkgfSBmcm9tICcuL2xpYic7XG5pbXBvcnQgKiBhcyByZXF1ZXN0IGZyb20gJ3N1cGVyYWdlbnQnO1xuaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSAnYnVmZmVyJztcbmltcG9ydCB7IEZlZURhdGEsIFNlbmRNZXNzYWdlIH0gZnJvbSAnLi9saWIvaWZhY2UnO1xuaW1wb3J0IHsgQ29pbiB9IGZyb20gJ0Bjb3NtanMvc3RhcmdhdGUnO1xuaW1wb3J0IHsgR0FTX0FNT1VOVCwgR0FTX0xJTUlUIH0gZnJvbSAnLi9saWIvY29uc3RhbnRzJztcblxuLyoqXG4gKiBBdG9tIGFjY291bnRzIHN1cHBvcnQgbWVtbyBJZCBiYXNlZCBhZGRyZXNzZXNcbiAqL1xuaW50ZXJmYWNlIEFkZHJlc3NEZXRhaWxzIHtcbiAgYWRkcmVzczogc3RyaW5nO1xuICBtZW1vSWQ/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQXRvbSBhY2NvdW50cyBzdXBwb3J0IG1lbW8gSWQgYmFzZWQgYWRkcmVzc2VzXG4gKi9cbmludGVyZmFjZSBBdG9tQ29pblNwZWNpZmljIHtcbiAgcm9vdEFkZHJlc3M6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFJlY292ZXJ5T3B0aW9ucyB7XG4gIHVzZXJLZXk/OiBzdHJpbmc7IC8vIEJveCBBXG4gIGJhY2t1cEtleT86IHN0cmluZzsgLy8gQm94IEJcbiAgYml0Z29LZXk6IHN0cmluZzsgLy8gQm94IENcbiAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogc3RyaW5nO1xuICBrcnNQcm92aWRlcj86IHN0cmluZztcbiAgd2FsbGV0UGFzc3BocmFzZT86IHN0cmluZztcbiAgc3RhcnRpbmdTY2FuSW5kZXg/OiBudW1iZXI7XG4gIHNjYW4/OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBBdG9tVHgge1xuICBzZXJpYWxpemVkVHg6IHN0cmluZztcbiAgc2NhbkluZGV4OiBudW1iZXI7XG59XG5cbmV4cG9ydCBjbGFzcyBBdG9tIGV4dGVuZHMgQmFzZUNvaW4ge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgX3N0YXRpY3NDb2luOiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+O1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoYml0Z286IEJpdEdvQmFzZSwgc3RhdGljc0NvaW4/OiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+KSB7XG4gICAgc3VwZXIoYml0Z28pO1xuXG4gICAgaWYgKCFzdGF0aWNzQ29pbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHJlcXVpcmVkIGNvbnN0cnVjdG9yIHBhcmFtZXRlciBzdGF0aWNzQ29pbicpO1xuICAgIH1cblxuICAgIHRoaXMuX3N0YXRpY3NDb2luID0gc3RhdGljc0NvaW47XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlSW5zdGFuY2UoYml0Z286IEJpdEdvQmFzZSwgc3RhdGljc0NvaW4/OiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+KTogQmFzZUNvaW4ge1xuICAgIHJldHVybiBuZXcgQXRvbShiaXRnbywgc3RhdGljc0NvaW4pO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICoqL1xuICBnZXRCYXNlRmFjdG9yKCk6IHN0cmluZyB8IG51bWJlciB7XG4gICAgcmV0dXJuIDFlNjtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgZ2V0Q2hhaW4oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGljc0NvaW4ubmFtZTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgZ2V0RmFtaWx5KCk6IENvaW5GYW1pbHkge1xuICAgIHJldHVybiB0aGlzLl9zdGF0aWNzQ29pbi5mYW1pbHk7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKiovXG4gIGdldEZ1bGxOYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLmZ1bGxOYW1lO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIHN1cHBvcnRzVHNzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICoqL1xuICBnZXRNUENBbGdvcml0aG0oKTogTVBDQWxnb3JpdGhtIHtcbiAgICByZXR1cm4gJ2VjZHNhJztcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgaXNWYWxpZFB1YihwdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB1dGlscy5pc1ZhbGlkUHVibGljS2V5KHB1Yik7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKiovXG4gIGlzVmFsaWRQcnYocHJ2OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdXRpbHMuaXNWYWxpZFByaXZhdGVLZXkocHJ2KTtcbiAgfVxuXG4gIGdldEJ1aWxkZXIoKTogVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSB7XG4gICAgcmV0dXJuIG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCh0aGlzLmdldENoYWluKCkpKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgaXNWYWxpZEFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHV0aWxzLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpIHx8IHV0aWxzLmlzVmFsaWRWYWxpZGF0b3JBZGRyZXNzKGFkZHJlc3MpO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICoqL1xuICBhc3luYyB2ZXJpZnlUcmFuc2FjdGlvbihwYXJhbXM6IFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGxldCB0b3RhbEFtb3VudCA9IG5ldyBCaWdOdW1iZXIoMCk7XG4gICAgY29uc3QgY29pbkNvbmZpZyA9IGNvaW5zLmdldCh0aGlzLmdldENoYWluKCkpO1xuICAgIGNvbnN0IHsgdHhQcmVidWlsZCwgdHhQYXJhbXMgfSA9IHBhcmFtcztcbiAgICBjb25zdCByYXdUeCA9IHR4UHJlYnVpbGQudHhIZXg7XG4gICAgaWYgKCFyYXdUeCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHJlcXVpcmVkIHR4IHByZWJ1aWxkIHByb3BlcnR5IHR4SGV4Jyk7XG4gICAgfVxuICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gYXdhaXQgbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbkNvbmZpZykuZnJvbShyYXdUeCkuYnVpbGQoKTtcbiAgICBjb25zdCBleHBsYWluZWRUeCA9IHRyYW5zYWN0aW9uLmV4cGxhaW5UcmFuc2FjdGlvbigpO1xuXG4gICAgaWYgKHR4UGFyYW1zLnJlY2lwaWVudHMgJiYgdHhQYXJhbXMucmVjaXBpZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBmaWx0ZXJlZFJlY2lwaWVudHMgPSB0eFBhcmFtcy5yZWNpcGllbnRzPy5tYXAoKHJlY2lwaWVudCkgPT4gXy5waWNrKHJlY2lwaWVudCwgWydhZGRyZXNzJywgJ2Ftb3VudCddKSk7XG4gICAgICBjb25zdCBmaWx0ZXJlZE91dHB1dHMgPSBleHBsYWluZWRUeC5vdXRwdXRzLm1hcCgob3V0cHV0KSA9PiBfLnBpY2sob3V0cHV0LCBbJ2FkZHJlc3MnLCAnYW1vdW50J10pKTtcblxuICAgICAgaWYgKCFfLmlzRXF1YWwoZmlsdGVyZWRPdXRwdXRzLCBmaWx0ZXJlZFJlY2lwaWVudHMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVHggb3V0cHV0cyBkb2VzIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIHR4UGFyYW1zIHJlY2lwaWVudHMnKTtcbiAgICAgIH1cbiAgICAgIC8vIFdpdGhkcmF3RGVsZWdhdG9yUmV3YXJkcyB0cmFuc2FjdGlvbiBkb2Vzbid0IGhhdmUgYW1vdW50XG4gICAgICBpZiAodHJhbnNhY3Rpb24udHlwZSAhPT0gVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdXaXRoZHJhdykge1xuICAgICAgICBmb3IgKGNvbnN0IHJlY2lwaWVudHMgb2YgdHhQYXJhbXMucmVjaXBpZW50cykge1xuICAgICAgICAgIHRvdGFsQW1vdW50ID0gdG90YWxBbW91bnQucGx1cyhyZWNpcGllbnRzLmFtb3VudCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0b3RhbEFtb3VudC5pc0VxdWFsVG8oZXhwbGFpbmVkVHgub3V0cHV0QW1vdW50KSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVHggdG90YWwgYW1vdW50IGRvZXMgbm90IG1hdGNoIHdpdGggZXhwZWN0ZWQgdG90YWwgYW1vdW50IGZpZWxkJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKiovXG4gIGFzeW5jIHBhcnNlVHJhbnNhY3Rpb24ocGFyYW1zOiBQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyAmIHsgdHhIZXg6IHN0cmluZyB9KTogUHJvbWlzZTxQYXJzZWRUcmFuc2FjdGlvbj4ge1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uRXhwbGFuYXRpb24gPSBhd2FpdCB0aGlzLmV4cGxhaW5UcmFuc2FjdGlvbih7IHR4SGV4OiBwYXJhbXMudHhIZXggfSk7XG4gICAgaWYgKCF0cmFuc2FjdGlvbkV4cGxhbmF0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb24nKTtcbiAgICB9XG5cbiAgICBpZiAodHJhbnNhY3Rpb25FeHBsYW5hdGlvbi5vdXRwdXRzLmxlbmd0aCA8PSAwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBpbnB1dHM6IFtdLFxuICAgICAgICBvdXRwdXRzOiBbXSxcbiAgICAgIH07XG4gICAgfVxuICAgIGNvbnN0IHNlbmRlckFkZHJlc3MgPSB0cmFuc2FjdGlvbkV4cGxhbmF0aW9uLm91dHB1dHNbMF0uYWRkcmVzcztcbiAgICBjb25zdCBmZWVBbW91bnQgPSBuZXcgQmlnTnVtYmVyKHRyYW5zYWN0aW9uRXhwbGFuYXRpb24uZmVlLmZlZSA9PT0gJycgPyAnMCcgOiB0cmFuc2FjdGlvbkV4cGxhbmF0aW9uLmZlZS5mZWUpO1xuICAgIGNvbnN0IGlucHV0cyA9IFtcbiAgICAgIHtcbiAgICAgICAgYWRkcmVzczogc2VuZGVyQWRkcmVzcyxcbiAgICAgICAgYW1vdW50OiBuZXcgQmlnTnVtYmVyKHRyYW5zYWN0aW9uRXhwbGFuYXRpb24ub3V0cHV0QW1vdW50KS5wbHVzKGZlZUFtb3VudCkudG9GaXhlZCgpLFxuICAgICAgfSxcbiAgICBdO1xuICAgIGNvbnN0IG91dHB1dHMgPSB0cmFuc2FjdGlvbkV4cGxhbmF0aW9uLm91dHB1dHMubWFwKChvdXRwdXQpID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGFkZHJlc3M6IG91dHB1dC5hZGRyZXNzLFxuICAgICAgICBhbW91bnQ6IG5ldyBCaWdOdW1iZXIob3V0cHV0LmFtb3VudCkudG9GaXhlZCgpLFxuICAgICAgfTtcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgaW5wdXRzLFxuICAgICAgb3V0cHV0cyxcbiAgICB9O1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICoqL1xuICBhc3luYyBleHBsYWluVHJhbnNhY3Rpb24ob3B0aW9uczogeyB0eEhleDogc3RyaW5nIH0pOiBQcm9taXNlPEV4cGxhbmF0aW9uUmVzdWx0PiB7XG4gICAgaWYgKCFvcHRpb25zLnR4SGV4KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgcmVxdWlyZWQgdHhIZXggcGFyYW1ldGVyJyk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbkJ1aWxkZXIgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQodGhpcy5nZXRDaGFpbigpKSkuZnJvbShvcHRpb25zLnR4SGV4KTtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gYXdhaXQgdHJhbnNhY3Rpb25CdWlsZGVyLmJ1aWxkKCk7XG4gICAgICByZXR1cm4gdHJhbnNhY3Rpb24uZXhwbGFpblRyYW5zYWN0aW9uKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHRyYW5zYWN0aW9uOiAnICsgZS5tZXNzYWdlKTtcbiAgICB9XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKiovXG4gIGdlbmVyYXRlS2V5UGFpcihzZWVkPzogQnVmZmVyKTogS2V5UGFpciB7XG4gICAgaWYgKCFzZWVkKSB7XG4gICAgICAvLyBBbiBleHRlbmRlZCBwcml2YXRlIGtleSBoYXMgYm90aCBhIG5vcm1hbCAyNTYgYml0IHByaXZhdGUga2V5IGFuZCBhIDI1NlxuICAgICAgLy8gYml0IGNoYWluIGNvZGUsIGJvdGggb2Ygd2hpY2ggbXVzdCBiZSByYW5kb20uIDUxMiBiaXRzIGlzIHRoZXJlZm9yZSB0aGVcbiAgICAgIC8vIG1heGltdW0gZW50cm9weSBhbmQgZ2l2ZXMgdXMgbWF4aW11bSBzZWN1cml0eSBhZ2FpbnN0IGNyYWNraW5nLlxuICAgICAgc2VlZCA9IHJhbmRvbUJ5dGVzKDUxMiAvIDgpO1xuICAgIH1cbiAgICBjb25zdCBleHRlbmRlZEtleSA9IGJpcDMyLmZyb21TZWVkKHNlZWQpO1xuICAgIHJldHVybiB7XG4gICAgICBwdWI6IGV4dGVuZGVkS2V5Lm5ldXRlcmVkKCkudG9CYXNlNTgoKSxcbiAgICAgIHBydjogZXh0ZW5kZWRLZXkudG9CYXNlNTgoKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFNpZ24gYSB0cmFuc2FjdGlvbiB3aXRoIGEgc2luZ2xlIHByaXZhdGUga2V5XG4gICAqIEBwYXJhbSBwYXJhbXMgcGFyYW1ldGVycyBpbiB0aGUgZm9ybSBvZiB7IHR4UHJlYnVpbGQ6IHt0eEhleH0sIHBydiB9XG4gICAqIEByZXR1cm5zIHNpZ25lZCB0cmFuc2FjdGlvbiBpbiB0aGUgZm9ybSBvZiB7IHR4SGV4IH1cbiAgICovXG4gIGFzeW5jIHNpZ25UcmFuc2FjdGlvbihcbiAgICBwYXJhbXM6IFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMgJiB7IHR4UHJlYnVpbGQ6IHsgdHhIZXg6IHN0cmluZyB9OyBwcnY6IHN0cmluZyB9XG4gICk6IFByb21pc2U8U2lnbmVkVHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCB0eEhleCA9IHBhcmFtcz8udHhQcmVidWlsZD8udHhIZXg7XG4gICAgY29uc3QgcHJpdmF0ZUtleSA9IHBhcmFtcz8ucHJ2O1xuICAgIGlmICghdHhIZXgpIHtcbiAgICAgIHRocm93IG5ldyBTaWduaW5nRXJyb3IoJ21pc3NpbmcgcmVxdWlyZWQgdHhQcmVidWlsZCBwYXJhbWV0ZXI6IHBhcmFtcy50eFByZWJ1aWxkLnR4SGV4Jyk7XG4gICAgfVxuICAgIGlmICghcHJpdmF0ZUtleSkge1xuICAgICAgdGhyb3cgbmV3IFNpZ25pbmdFcnJvcignbWlzc2luZyByZXF1aXJlZCBwcnYgcGFyYW1ldGVyOiBwYXJhbXMucHJ2Jyk7XG4gICAgfVxuICAgIGNvbnN0IHR4QnVpbGRlciA9IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCh0aGlzLmdldENoYWluKCkpKS5mcm9tKHBhcmFtcy50eFByZWJ1aWxkLnR4SGV4KTtcbiAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogcGFyYW1zLnBydiB9KTtcbiAgICBjb25zdCB0cmFuc2FjdGlvbjogQmFzZVRyYW5zYWN0aW9uID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgaWYgKCF0cmFuc2FjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IFNpZ25pbmdFcnJvcignRmFpbGVkIHRvIGJ1aWxkIHNpZ25lZCB0cmFuc2FjdGlvbicpO1xuICAgIH1cbiAgICBjb25zdCBzZXJpYWxpemVkVHggPSB0cmFuc2FjdGlvbi50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgIHJldHVybiB7XG4gICAgICB0eEhleDogc2VyaWFsaXplZFR4LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIGEgZnVuZHMgcmVjb3ZlcnkgdHJhbnNhY3Rpb24gd2l0aG91dCBCaXRHb1xuICAgKiBAcGFyYW0ge1JlY292ZXJ5T3B0aW9uc30gcGFyYW1zIHBhcmFtZXRlcnMgbmVlZGVkIHRvIGNvbnN0cnVjdCBhbmRcbiAgICogKG1heWJlKSBzaWduIHRoZSB0cmFuc2FjdGlvblxuICAgKlxuICAgKiBAcmV0dXJucyB7QXRvbVR4fSB0aGUgc2VyaWFsaXplZCB0cmFuc2FjdGlvbiBoZXggc3RyaW5nIGFuZCBpbmRleFxuICAgKiBvZiB0aGUgYWRkcmVzcyBiZWluZyBzd2VwdFxuICAgKi9cbiAgYXN5bmMgcmVjb3ZlcihwYXJhbXM6IFJlY292ZXJ5T3B0aW9ucyk6IFByb21pc2U8QXRvbVR4PiB7XG4gICAgLy8gU3RlcCAxOiBDaGVjayBpZiBwYXJhbXMgY29udGFpbnMgdGhlIHJlcXVpcmVkIHBhcmFtZXRlcnNcbiAgICBpZiAoIXBhcmFtcy5iaXRnb0tleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGJpdGdvS2V5Jyk7XG4gICAgfVxuXG4gICAgaWYgKCFwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiB8fCAhdGhpcy5pc1ZhbGlkQWRkcmVzcyhwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCByZWNvdmVyeURlc3RpbmF0aW9uJyk7XG4gICAgfVxuXG4gICAgaWYgKCFwYXJhbXMudXNlcktleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHVzZXJLZXknKTtcbiAgICB9XG5cbiAgICBpZiAoIXBhcmFtcy5iYWNrdXBLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBiYWNrdXBLZXknKTtcbiAgICB9XG5cbiAgICBpZiAoIXBhcmFtcy53YWxsZXRQYXNzcGhyYXNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3Npbmcgd2FsbGV0IHBhc3NwaHJhc2UnKTtcbiAgICB9XG5cbiAgICAvLyBTdGVwIDI6IEZldGNoIHRoZSBiaXRnbyBrZXkgZnJvbSBwYXJhbXNcbiAgICBjb25zdCBiaXRnb0tleSA9IHBhcmFtcy5iaXRnb0tleS5yZXBsYWNlKC9cXHMvZywgJycpO1xuXG4gICAgLy8gU3RlcCAzOiBJbnN0YW50aWF0ZSB0aGUgRUNEU0Egc2lnbmVyIGFuZCBmZXRjaCB0aGUgYWRkcmVzcyBkZXRhaWxzXG4gICAgY29uc3QgTVBDID0gbmV3IEVjZHNhKCk7XG4gICAgY29uc3QgY2hhaW5JZCA9IGF3YWl0IHRoaXMuZ2V0Q2hhaW5JZCgpO1xuICAgIGNvbnN0IGN1cnJQYXRoID0gJ20vMCc7XG4gICAgY29uc3QgcHVibGljS2V5ID0gTVBDLmRlcml2ZVVuaGFyZGVuZWQoYml0Z29LZXksIGN1cnJQYXRoKS5zbGljZSgwLCA2Nik7XG4gICAgY29uc3Qgc2VuZGVyQWRkcmVzcyA9IHRoaXMuZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkocHVibGljS2V5KTtcblxuICAgIC8vIFN0ZXAgNDogRmV0Y2ggYWNjb3VudCBkZXRhaWxzIHN1Y2ggYXMgYWNjb3VudE5vLCBiYWxhbmNlIGFuZCBjaGVjayBmb3Igc3VmZmljaWVudCBmdW5kcyBvbmNlIGdhc0Ftb3VudCBoYXMgYmVlbiBkZWR1Y3RlZFxuICAgIGNvbnN0IFthY2NvdW50TnVtYmVyLCBzZXF1ZW5jZU5vXSA9IGF3YWl0IHRoaXMuZ2V0QWNjb3VudERldGFpbHMoc2VuZGVyQWRkcmVzcyk7XG4gICAgY29uc3QgYmFsYW5jZSA9IG5ldyBCaWdOdW1iZXIoYXdhaXQgdGhpcy5nZXRBY2NvdW50QmFsYW5jZShzZW5kZXJBZGRyZXNzKSk7XG4gICAgY29uc3QgZ2FzQnVkZ2V0OiBGZWVEYXRhID0ge1xuICAgICAgYW1vdW50OiBbeyBkZW5vbTogJ3VhdG9tJywgYW1vdW50OiBHQVNfQU1PVU5UIH1dLFxuICAgICAgZ2FzTGltaXQ6IEdBU19MSU1JVCxcbiAgICB9O1xuICAgIGNvbnN0IGdhc0Ftb3VudCA9IG5ldyBCaWdOdW1iZXIoZ2FzQnVkZ2V0LmFtb3VudFswXS5hbW91bnQpO1xuICAgIGNvbnN0IGFjdHVhbEJhbGFuY2UgPSBiYWxhbmNlLm1pbnVzKGdhc0Ftb3VudCk7XG5cbiAgICBpZiAoYWN0dWFsQmFsYW5jZS5pc0xlc3NUaGFuT3JFcXVhbFRvKDApKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpZCBub3QgaGF2ZSBlbm91Z2ggZnVuZHMgdG8gcmVjb3ZlcicpO1xuICAgIH1cblxuICAgIC8vIFN0ZXAgNTogT25jZSBzdWZmaWNpZW50IGZ1bmRzIGFyZSBwcmVzZW50LCBjb25zdHJ1Y3QgdGhlIHJlY292ZXIgdHggbWVzc3NhZ2VcbiAgICBjb25zdCBhbW91bnQ6IENvaW5bXSA9IFtcbiAgICAgIHtcbiAgICAgICAgZGVub206ICd1YXRvbScsXG4gICAgICAgIGFtb3VudDogYWN0dWFsQmFsYW5jZS50b0ZpeGVkKCksXG4gICAgICB9LFxuICAgIF07XG4gICAgY29uc3Qgc2VuZE1lc3NhZ2U6IFNlbmRNZXNzYWdlW10gPSBbXG4gICAgICB7XG4gICAgICAgIGZyb21BZGRyZXNzOiBzZW5kZXJBZGRyZXNzLFxuICAgICAgICB0b0FkZHJlc3M6IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICBhbW91bnQ6IGFtb3VudCxcbiAgICAgIH0sXG4gICAgXTtcblxuICAgIC8vIFN0ZXAgNjogQnVpbGQgdGhlIHVuc2lnbmVkIHR4IHVzaW5nIHRoZSBjb25zdHJ1Y3RlZCBtZXNzYWdlXG4gICAgY29uc3QgdHhuQnVpbGRlciA9IHRoaXMuZ2V0QnVpbGRlcigpLmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgIHR4bkJ1aWxkZXJcbiAgICAgIC5tZXNzYWdlcyhzZW5kTWVzc2FnZSlcbiAgICAgIC5nYXNCdWRnZXQoZ2FzQnVkZ2V0KVxuICAgICAgLnB1YmxpY0tleShwdWJsaWNLZXkpXG4gICAgICAuc2VxdWVuY2UoTnVtYmVyKHNlcXVlbmNlTm8pKVxuICAgICAgLmFjY291bnROdW1iZXIoTnVtYmVyKGFjY291bnROdW1iZXIpKVxuICAgICAgLmNoYWluSWQoY2hhaW5JZCk7XG4gICAgY29uc3QgdW5zaWduZWRUcmFuc2FjdGlvbiA9IChhd2FpdCB0eG5CdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgIGxldCBzZXJpYWxpemVkVHggPSB1bnNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgY29uc3Qgc2lnbmFibGVIZXggPSB1bnNpZ25lZFRyYW5zYWN0aW9uLnNpZ25hYmxlUGF5bG9hZC50b1N0cmluZygnaGV4Jyk7XG4gICAgY29uc3QgdXNlcktleSA9IHBhcmFtcy51c2VyS2V5LnJlcGxhY2UoL1xccy9nLCAnJyk7XG4gICAgY29uc3QgYmFja3VwS2V5ID0gcGFyYW1zLmJhY2t1cEtleS5yZXBsYWNlKC9cXHMvZywgJycpO1xuICAgIGNvbnN0IFt1c2VyS2V5Q29tYmluZWQsIGJhY2t1cEtleUNvbWJpbmVkXSA9ICgoKTogW1xuICAgICAgRUNEU0FNZXRob2RUeXBlcy5LZXlDb21iaW5lZCB8IHVuZGVmaW5lZCxcbiAgICAgIEVDRFNBTWV0aG9kVHlwZXMuS2V5Q29tYmluZWQgfCB1bmRlZmluZWRcbiAgICBdID0+IHtcbiAgICAgIGNvbnN0IFt1c2VyS2V5Q29tYmluZWQsIGJhY2t1cEtleUNvbWJpbmVkXSA9IHRoaXMuZ2V0S2V5Q29tYmluZWRGcm9tVHNzS2V5U2hhcmVzKFxuICAgICAgICB1c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXksXG4gICAgICAgIHBhcmFtcy53YWxsZXRQYXNzcGhyYXNlXG4gICAgICApO1xuICAgICAgcmV0dXJuIFt1c2VyS2V5Q29tYmluZWQsIGJhY2t1cEtleUNvbWJpbmVkXTtcbiAgICB9KSgpO1xuXG4gICAgaWYgKCF1c2VyS2V5Q29tYmluZWQgfHwgIWJhY2t1cEtleUNvbWJpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgY29tYmluZWQga2V5IHNoYXJlcyBmb3IgdXNlciBvciBiYWNrdXAnKTtcbiAgICB9XG5cbiAgICAvLyBTdGVwIDc6IFNpZ24gdGhlIHR4XG4gICAgY29uc3Qgc2lnbmF0dXJlID0gYXdhaXQgdGhpcy5zaWduUmVjb3ZlcnlUU1ModXNlcktleUNvbWJpbmVkLCBiYWNrdXBLZXlDb21iaW5lZCwgc2lnbmFibGVIZXgpO1xuICAgIGNvbnN0IHNpZ25hYmxlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBNUEMudmVyaWZ5KHNpZ25hYmxlQnVmZmVyLCBzaWduYXR1cmUsIGNyZWF0ZUhhc2goJ3NoYTI1NicpKTtcbiAgICBjb25zdCBhdG9tS2V5UGFpciA9IG5ldyBBdG9tS2V5UGFpcih7IHB1YjogcHVibGljS2V5IH0pO1xuICAgIHR4bkJ1aWxkZXIuYWRkU2lnbmF0dXJlKHsgcHViOiBhdG9tS2V5UGFpci5nZXRLZXlzKCkucHViIH0sIEJ1ZmZlci5mcm9tKHNpZ25hdHVyZS5yICsgc2lnbmF0dXJlLnMsICdoZXgnKSk7XG4gICAgY29uc3Qgc2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCB0eG5CdWlsZGVyLmJ1aWxkKCk7XG4gICAgc2VyaWFsaXplZFR4ID0gc2lnbmVkVHJhbnNhY3Rpb24udG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgIHJldHVybiB7IHNlcmlhbGl6ZWRUeDogc2VyaWFsaXplZFR4LCBzY2FuSW5kZXg6IDAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYmFsYW5jZSBmcm9tIHB1YmxpYyBub2RlXG4gICAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0QmFsYW5jZUZyb21Ob2RlKHNlbmRlckFkZHJlc3M6IHN0cmluZyk6IFByb21pc2U8cmVxdWVzdC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IG5vZGVVcmwgPSB0aGlzLmdldFB1YmxpY05vZGVVcmwoKTtcbiAgICBjb25zdCBnZXRCYWxhbmNlUGF0aCA9ICdjb3Ntb3MvYmFuay92MWJldGExL2JhbGFuY2VzLyc7XG4gICAgY29uc3QgZnVsbEVuZHBvaW50ID0gbm9kZVVybCArIGdldEJhbGFuY2VQYXRoICsgc2VuZGVyQWRkcmVzcztcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlcXVlc3QuZ2V0KGZ1bGxFbmRwb2ludCkuc2VuZCgpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUuZGVidWcoZSk7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGNhbGwgZW5kcG9pbnQgJHtnZXRCYWxhbmNlUGF0aCArIHNlbmRlckFkZHJlc3N9IGZyb20gbm9kZTogJHtub2RlVXJsfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEhlbHBlciB0byBmZXRjaCBjaGFpbklkXG4gICAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0Q2hhaW5JZCgpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5nZXRDaGFpbklkRnJvbU5vZGUoKTtcbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzICE9PSAyMDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQWNjb3VudCBub3QgZm91bmQnKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHkuYmxvY2suaGVhZGVyLmNoYWluX2lkO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjaGFpbiBpZCBmcm9tIHB1YmxpYyBub2RlXG4gICAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0Q2hhaW5JZEZyb21Ob2RlKCk6IFByb21pc2U8cmVxdWVzdC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IG5vZGVVcmwgPSB0aGlzLmdldFB1YmxpY05vZGVVcmwoKTtcbiAgICBjb25zdCBnZXRMYXRlc3RCbG9ja1BhdGggPSAnY29zbW9zL2Jhc2UvdGVuZGVybWludC92MWJldGExL2Jsb2Nrcy9sYXRlc3QnO1xuICAgIGNvbnN0IGZ1bGxFbmRwb2ludCA9IG5vZGVVcmwgKyBnZXRMYXRlc3RCbG9ja1BhdGg7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCByZXF1ZXN0LmdldChmdWxsRW5kcG9pbnQpLnNlbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLmRlYnVnKGUpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBjYWxsIGVuZHBvaW50ICR7Z2V0TGF0ZXN0QmxvY2tQYXRofSBmcm9tIG5vZGU6ICR7bm9kZVVybH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIZWxwZXIgdG8gZmV0Y2ggYWNjb3VudCBudW1iZXJcbiAgICovXG4gIHByb3RlY3RlZCBhc3luYyBnZXRBY2NvdW50RGV0YWlscyhzZW5kZXJBZGRyZXNzOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmdldEFjY291bnRGcm9tTm9kZShzZW5kZXJBZGRyZXNzKTtcbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzICE9PSAyMDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQWNjb3VudCBub3QgZm91bmQnKTtcbiAgICB9XG4gICAgcmV0dXJuIFtyZXNwb25zZS5ib2R5LmFjY291bnQuYWNjb3VudF9udW1iZXIsIHJlc3BvbnNlLmJvZHkuYWNjb3VudC5zZXF1ZW5jZV07XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFjY291bnQgbnVtYmVyIGZyb20gcHVibGljIG5vZGVcbiAgICovXG4gIHByb3RlY3RlZCBhc3luYyBnZXRBY2NvdW50RnJvbU5vZGUoc2VuZGVyQWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTxyZXF1ZXN0LlJlc3BvbnNlPiB7XG4gICAgY29uc3Qgbm9kZVVybCA9IHRoaXMuZ2V0UHVibGljTm9kZVVybCgpO1xuICAgIGNvbnN0IGdldEFjY291bnRQYXRoID0gJ2Nvc21vcy9hdXRoL3YxYmV0YTEvYWNjb3VudHMvJztcbiAgICBjb25zdCBmdWxsRW5kcG9pbnQgPSBub2RlVXJsICsgZ2V0QWNjb3VudFBhdGggKyBzZW5kZXJBZGRyZXNzO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVxdWVzdC5nZXQoZnVsbEVuZHBvaW50KS5zZW5kKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5kZWJ1ZyhlKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gY2FsbCBlbmRwb2ludCAke2dldEFjY291bnRQYXRoICsgc2VuZGVyQWRkcmVzc30gZnJvbSBub2RlOiAke25vZGVVcmx9YCk7XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIHRvIGZldGNoIGFjY291bnQgYmFsYW5jZVxuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGdldEFjY291bnRCYWxhbmNlKHNlbmRlckFkZHJlc3M6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmdldEJhbGFuY2VGcm9tTm9kZShzZW5kZXJBZGRyZXNzKTtcbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzICE9PSAyMDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQWNjb3VudCBub3QgZm91bmQnKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHkuYmFsYW5jZXNbMF0uYW1vdW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgcHVibGljIG5vZGUgdXJsIGZyb20gdGhlIEVudmlyb25tZW50cyBjb25zdGFudCB3ZSBoYXZlIGRlZmluZWRcbiAgICovXG4gIHByb3RlY3RlZCBnZXRQdWJsaWNOb2RlVXJsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIEVudmlyb25tZW50c1t0aGlzLmJpdGdvLmdldEVudigpXS5hdG9tTm9kZVVybDtcbiAgfVxuXG4gIGdldEFkZHJlc3NGcm9tUHVibGljS2V5KHB1YktleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gbmV3IEF0b21LZXlQYWlyKHsgcHViOiBwdWJLZXkgfSkuZ2V0QWRkcmVzcygpO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICoqL1xuICBhc3luYyBpc1dhbGxldEFkZHJlc3MocGFyYW1zOiBWZXJpZnlBZGRyZXNzT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGFkZHJlc3NEZXRhaWxzID0gdGhpcy5nZXRBZGRyZXNzRGV0YWlscyhwYXJhbXMuYWRkcmVzcyk7XG5cbiAgICBpZiAoIXRoaXMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzc0RldGFpbHMuYWRkcmVzcykpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQWRkcmVzc0Vycm9yKGBpbnZhbGlkIGFkZHJlc3M6ICR7YWRkcmVzc0RldGFpbHMuYWRkcmVzc31gKTtcbiAgICB9XG4gICAgY29uc3Qgcm9vdEFkZHJlc3MgPSAocGFyYW1zLmNvaW5TcGVjaWZpYyBhcyBBdG9tQ29pblNwZWNpZmljKS5yb290QWRkcmVzcztcbiAgICBpZiAoYWRkcmVzc0RldGFpbHMuYWRkcmVzcyAhPT0gcm9vdEFkZHJlc3MpIHtcbiAgICAgIHRocm93IG5ldyBVbmV4cGVjdGVkQWRkcmVzc0Vycm9yKGBhZGRyZXNzIHZhbGlkYXRpb24gZmFpbHVyZTogJHthZGRyZXNzRGV0YWlscy5hZGRyZXNzfSB2cyAke3Jvb3RBZGRyZXNzfWApO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGdldEhhc2hGdW5jdGlvbigpOiBIYXNoIHtcbiAgICByZXR1cm4gY3JlYXRlSGFzaCgnc2hhMjU2Jyk7XG4gIH1cblxuICAvKipcbiAgICogUHJvY2VzcyBhZGRyZXNzIGludG8gYWRkcmVzcyBhbmQgbWVtbyBpZFxuICAgKlxuICAgKiBAcGFyYW0gYWRkcmVzcyB0aGUgYWRkcmVzc1xuICAgKiBAcmV0dXJucyBvYmplY3QgY29udGFpbmluZyBhZGRyZXNzIGFuZCBtZW1vIGlkXG4gICAqL1xuICBnZXRBZGRyZXNzRGV0YWlscyhhZGRyZXNzOiBzdHJpbmcpOiBBZGRyZXNzRGV0YWlscyB7XG4gICAgY29uc3QgZGVzdGluYXRpb25EZXRhaWxzID0gdXJsLnBhcnNlKGFkZHJlc3MpO1xuICAgIGNvbnN0IGRlc3RpbmF0aW9uQWRkcmVzcyA9IGRlc3RpbmF0aW9uRGV0YWlscy5wYXRobmFtZSB8fCAnJztcblxuICAgIC8vIGFkZHJlc3MgZG9lc24ndCBoYXZlIGEgbWVtbyBpZFxuICAgIGlmIChkZXN0aW5hdGlvbkRldGFpbHMucGF0aG5hbWUgPT09IGFkZHJlc3MpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGFkZHJlc3M6IGFkZHJlc3MsXG4gICAgICAgIG1lbW9JZDogdW5kZWZpbmVkLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoIWRlc3RpbmF0aW9uRGV0YWlscy5xdWVyeSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBZGRyZXNzRXJyb3IoYGludmFsaWQgYWRkcmVzczogJHthZGRyZXNzfWApO1xuICAgIH1cblxuICAgIGNvbnN0IHF1ZXJ5RGV0YWlscyA9IHF1ZXJ5c3RyaW5nLnBhcnNlKGRlc3RpbmF0aW9uRGV0YWlscy5xdWVyeSk7XG4gICAgaWYgKCFxdWVyeURldGFpbHMubWVtb0lkKSB7XG4gICAgICAvLyBpZiB0aGVyZSBhcmUgbW9yZSBwcm9wZXJ0aWVzLCB0aGUgcXVlcnkgZGV0YWlscyBuZWVkIHRvIGNvbnRhaW4gdGhlIG1lbW8gaWQgcHJvcGVydHlcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQWRkcmVzc0Vycm9yKGBpbnZhbGlkIGFkZHJlc3M6ICR7YWRkcmVzc31gKTtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShxdWVyeURldGFpbHMubWVtb0lkKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBZGRyZXNzRXJyb3IoXG4gICAgICAgIGBtZW1vSWQgbWF5IG9ubHkgYmUgZ2l2ZW4gYXQgbW9zdCBvbmNlLCBidXQgZm91bmQgJHtxdWVyeURldGFpbHMubWVtb0lkLmxlbmd0aH0gaW5zdGFuY2VzIGluIGFkZHJlc3MgJHthZGRyZXNzfWBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkocXVlcnlEZXRhaWxzLm1lbW9JZCkgJiYgcXVlcnlEZXRhaWxzLm1lbW9JZC5sZW5ndGggIT09IDEpIHtcbiAgICAgIC8vIHZhbGlkIGFkZHJlc3NlcyBjYW4gb25seSBjb250YWluIG9uZSBtZW1vIGlkXG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFkZHJlc3NFcnJvcihgaW52YWxpZCBhZGRyZXNzICcke2FkZHJlc3N9JywgbXVzdCBjb250YWluIGV4YWN0bHkgb25lIG1lbW9JZGApO1xuICAgIH1cblxuICAgIGNvbnN0IFttZW1vSWRdID0gXy5jYXN0QXJyYXkocXVlcnlEZXRhaWxzLm1lbW9JZCkgfHwgdW5kZWZpbmVkO1xuICAgIGlmICghdGhpcy5pc1ZhbGlkTWVtb0lkKG1lbW9JZCkpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkTWVtb0lkRXJyb3IoYGludmFsaWQgYWRkcmVzczogJyR7YWRkcmVzc30nLCBtZW1vSWQgaXMgbm90IHZhbGlkYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFkZHJlc3M6IGRlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgIG1lbW9JZCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciBhIG1lbW8gaWQgaXMgdmFsaWRcbiAgICpcbiAgICogQHBhcmFtIG1lbW9JZCBtZW1vIGlkXG4gICAqIEByZXR1cm5zIHRydWUgaWYgbWVtbyBpZCBpcyB2YWxpZFxuICAgKi9cbiAgaXNWYWxpZE1lbW9JZChtZW1vSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB1dGlscy5pc1ZhbGlkTWVtb0lkKG1lbW9JZCk7XG4gIH1cblxuICBwcml2YXRlIGdldEtleUNvbWJpbmVkRnJvbVRzc0tleVNoYXJlcyhcbiAgICB1c2VyUHVibGljT3JQcml2YXRlS2V5U2hhcmU6IHN0cmluZyxcbiAgICBiYWNrdXBQcml2YXRlT3JQdWJsaWNLZXlTaGFyZTogc3RyaW5nLFxuICAgIHdhbGxldFBhc3NwaHJhc2U/OiBzdHJpbmdcbiAgKTogW0VDRFNBTWV0aG9kVHlwZXMuS2V5Q29tYmluZWQsIEVDRFNBTWV0aG9kVHlwZXMuS2V5Q29tYmluZWRdIHtcbiAgICBsZXQgYmFja3VwUHJ2O1xuICAgIGxldCB1c2VyUHJ2O1xuICAgIHRyeSB7XG4gICAgICBiYWNrdXBQcnYgPSB0aGlzLmJpdGdvLmRlY3J5cHQoe1xuICAgICAgICBpbnB1dDogYmFja3VwUHJpdmF0ZU9yUHVibGljS2V5U2hhcmUsXG4gICAgICAgIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgfSk7XG4gICAgICB1c2VyUHJ2ID0gdGhpcy5iaXRnby5kZWNyeXB0KHtcbiAgICAgICAgaW5wdXQ6IHVzZXJQdWJsaWNPclByaXZhdGVLZXlTaGFyZSxcbiAgICAgICAgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIGRlY3J5cHRpbmcgYmFja3VwIGtleWNoYWluOiAke2UubWVzc2FnZX1gKTtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VyU2lnbmluZ01hdGVyaWFsID0gSlNPTi5wYXJzZSh1c2VyUHJ2KSBhcyBFQ0RTQU1ldGhvZFR5cGVzLlNpZ25pbmdNYXRlcmlhbDtcbiAgICBjb25zdCBiYWNrdXBTaWduaW5nTWF0ZXJpYWwgPSBKU09OLnBhcnNlKGJhY2t1cFBydikgYXMgRUNEU0FNZXRob2RUeXBlcy5TaWduaW5nTWF0ZXJpYWw7XG5cbiAgICBpZiAoIXVzZXJTaWduaW5nTWF0ZXJpYWwuYmFja3VwTlNoYXJlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdXNlciBrZXkgLSBtaXNzaW5nIGJhY2t1cE5TaGFyZScpO1xuICAgIH1cblxuICAgIGlmICghYmFja3VwU2lnbmluZ01hdGVyaWFsLnVzZXJOU2hhcmUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBiYWNrdXAga2V5IC0gbWlzc2luZyB1c2VyTlNoYXJlJyk7XG4gICAgfVxuXG4gICAgY29uc3QgTVBDID0gbmV3IEVjZHNhKCk7XG5cbiAgICBjb25zdCB1c2VyS2V5Q29tYmluZWQgPSBNUEMua2V5Q29tYmluZSh1c2VyU2lnbmluZ01hdGVyaWFsLnBTaGFyZSwgW1xuICAgICAgdXNlclNpZ25pbmdNYXRlcmlhbC5iaXRnb05TaGFyZSxcbiAgICAgIHVzZXJTaWduaW5nTWF0ZXJpYWwuYmFja3VwTlNoYXJlLFxuICAgIF0pO1xuXG4gICAgY29uc3QgdXNlclNpZ25pbmdLZXlEZXJpdmVkID0gTVBDLmtleURlcml2ZShcbiAgICAgIHVzZXJTaWduaW5nTWF0ZXJpYWwucFNoYXJlLFxuICAgICAgW3VzZXJTaWduaW5nTWF0ZXJpYWwuYml0Z29OU2hhcmUsIHVzZXJTaWduaW5nTWF0ZXJpYWwuYmFja3VwTlNoYXJlXSxcbiAgICAgICdtLzAnXG4gICAgKTtcblxuICAgIGNvbnN0IHVzZXJLZXlEZXJpdmVkQ29tYmluZWQgPSB7XG4gICAgICB4U2hhcmU6IHVzZXJTaWduaW5nS2V5RGVyaXZlZC54U2hhcmUsXG4gICAgICB5U2hhcmVzOiB1c2VyS2V5Q29tYmluZWQueVNoYXJlcyxcbiAgICB9O1xuXG4gICAgY29uc3QgYmFja3VwS2V5Q29tYmluZWQgPSBNUEMua2V5Q29tYmluZShiYWNrdXBTaWduaW5nTWF0ZXJpYWwucFNoYXJlLCBbXG4gICAgICB1c2VyU2lnbmluZ0tleURlcml2ZWQublNoYXJlc1syXSxcbiAgICAgIGJhY2t1cFNpZ25pbmdNYXRlcmlhbC5iaXRnb05TaGFyZSxcbiAgICBdKTtcblxuICAgIGlmIChcbiAgICAgIHVzZXJLZXlEZXJpdmVkQ29tYmluZWQueFNoYXJlLnkgIT09IGJhY2t1cEtleUNvbWJpbmVkLnhTaGFyZS55IHx8XG4gICAgICB1c2VyS2V5RGVyaXZlZENvbWJpbmVkLnhTaGFyZS5jaGFpbmNvZGUgIT09IGJhY2t1cEtleUNvbWJpbmVkLnhTaGFyZS5jaGFpbmNvZGVcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ29tbW9uIGtleWNoYWlucyBkbyBub3QgbWF0Y2gnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gW3VzZXJLZXlEZXJpdmVkQ29tYmluZWQsIGJhY2t1cEtleUNvbWJpbmVkXTtcbiAgfVxuXG4gIC8vIFRPRE8oQkctNzg3MTQpOiBSZWR1Y2UgY29kZSBkdXBsaWNhdGlvbiBiZXR3ZWVuIHRoaXMgYW5kIGV0aC50c1xuICBwcml2YXRlIGFzeW5jIHNpZ25SZWNvdmVyeVRTUyhcbiAgICB1c2VyS2V5Q29tYmluZWQ6IEVDRFNBLktleUNvbWJpbmVkLFxuICAgIGJhY2t1cEtleUNvbWJpbmVkOiBFQ0RTQS5LZXlDb21iaW5lZCxcbiAgICB0eEhleDogc3RyaW5nLFxuICAgIHtcbiAgICAgIHJhbmdlUHJvb2ZDaGFsbGVuZ2UsXG4gICAgfToge1xuICAgICAgcmFuZ2VQcm9vZkNoYWxsZW5nZT86IEVjZHNhVHlwZXMuU2VyaWFsaXplZE50aWxkZTtcbiAgICB9ID0ge31cbiAgKTogUHJvbWlzZTxFQ0RTQU1ldGhvZFR5cGVzLlNpZ25hdHVyZT4ge1xuICAgIGNvbnN0IE1QQyA9IG5ldyBFY2RzYSgpO1xuICAgIGNvbnN0IHNpZ25lck9uZUluZGV4ID0gdXNlcktleUNvbWJpbmVkLnhTaGFyZS5pO1xuICAgIGNvbnN0IHNpZ25lclR3b0luZGV4ID0gYmFja3VwS2V5Q29tYmluZWQueFNoYXJlLmk7XG5cbiAgICAvLyBTaW5jZSB0aGlzIGlzIGEgdXNlciA8PiBiYWNrdXAgc2lnbmluZywgd2Ugd2lsbCByZXVzZSB0aGUgc2FtZSByYW5nZSBwcm9vZiBjaGFsbGVuZ2VcbiAgICByYW5nZVByb29mQ2hhbGxlbmdlID1cbiAgICAgIHJhbmdlUHJvb2ZDaGFsbGVuZ2UgPz8gRWNkc2FUeXBlcy5zZXJpYWxpemVOdGlsZGVXaXRoUHJvb2ZzKGF3YWl0IEVjZHNhUmFuZ2VQcm9vZi5nZW5lcmF0ZU50aWxkZSgpKTtcblxuICAgIGNvbnN0IHVzZXJUb0JhY2t1cFBhaWxsaWVyQ2hhbGxlbmdlID0gYXdhaXQgRWNkc2FQYWlsbGllclByb29mLmdlbmVyYXRlUChcbiAgICAgIGhleFRvQmlnSW50KHVzZXJLZXlDb21iaW5lZC55U2hhcmVzW3NpZ25lclR3b0luZGV4XS5uKVxuICAgICk7XG4gICAgY29uc3QgYmFja3VwVG9Vc2VyUGFpbGxpZXJDaGFsbGVuZ2UgPSBhd2FpdCBFY2RzYVBhaWxsaWVyUHJvb2YuZ2VuZXJhdGVQKFxuICAgICAgaGV4VG9CaWdJbnQoYmFja3VwS2V5Q29tYmluZWQueVNoYXJlc1tzaWduZXJPbmVJbmRleF0ubilcbiAgICApO1xuXG4gICAgY29uc3QgdXNlclhTaGFyZSA9IE1QQy5hcHBlbmRDaGFsbGVuZ2UoXG4gICAgICB1c2VyS2V5Q29tYmluZWQueFNoYXJlLFxuICAgICAgcmFuZ2VQcm9vZkNoYWxsZW5nZSxcbiAgICAgIEVjZHNhVHlwZXMuc2VyaWFsaXplUGFpbGxpZXJDaGFsbGVuZ2UoeyBwOiB1c2VyVG9CYWNrdXBQYWlsbGllckNoYWxsZW5nZSB9KVxuICAgICk7XG4gICAgY29uc3QgdXNlcllTaGFyZSA9IE1QQy5hcHBlbmRDaGFsbGVuZ2UoXG4gICAgICB1c2VyS2V5Q29tYmluZWQueVNoYXJlc1tzaWduZXJUd29JbmRleF0sXG4gICAgICByYW5nZVByb29mQ2hhbGxlbmdlLFxuICAgICAgRWNkc2FUeXBlcy5zZXJpYWxpemVQYWlsbGllckNoYWxsZW5nZSh7IHA6IGJhY2t1cFRvVXNlclBhaWxsaWVyQ2hhbGxlbmdlIH0pXG4gICAgKTtcbiAgICBjb25zdCBiYWNrdXBYU2hhcmUgPSBNUEMuYXBwZW5kQ2hhbGxlbmdlKFxuICAgICAgYmFja3VwS2V5Q29tYmluZWQueFNoYXJlLFxuICAgICAgcmFuZ2VQcm9vZkNoYWxsZW5nZSxcbiAgICAgIEVjZHNhVHlwZXMuc2VyaWFsaXplUGFpbGxpZXJDaGFsbGVuZ2UoeyBwOiBiYWNrdXBUb1VzZXJQYWlsbGllckNoYWxsZW5nZSB9KVxuICAgICk7XG4gICAgY29uc3QgYmFja3VwWVNoYXJlID0gTVBDLmFwcGVuZENoYWxsZW5nZShcbiAgICAgIGJhY2t1cEtleUNvbWJpbmVkLnlTaGFyZXNbc2lnbmVyT25lSW5kZXhdLFxuICAgICAgcmFuZ2VQcm9vZkNoYWxsZW5nZSxcbiAgICAgIEVjZHNhVHlwZXMuc2VyaWFsaXplUGFpbGxpZXJDaGFsbGVuZ2UoeyBwOiB1c2VyVG9CYWNrdXBQYWlsbGllckNoYWxsZW5nZSB9KVxuICAgICk7XG5cbiAgICBjb25zdCBzaWduU2hhcmVzOiBFQ0RTQS5TaWduU2hhcmVSVCA9IGF3YWl0IE1QQy5zaWduU2hhcmUodXNlclhTaGFyZSwgdXNlcllTaGFyZSk7XG5cbiAgICBjb25zdCBzaWduQ29udmVydFMyMSA9IGF3YWl0IE1QQy5zaWduQ29udmVydFN0ZXAxKHtcbiAgICAgIHhTaGFyZTogYmFja3VwWFNoYXJlLFxuICAgICAgeVNoYXJlOiBiYWNrdXBZU2hhcmUsIC8vIFlTaGFyZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBvdGhlciBwYXJ0aWNpcGFudCBzaWduZXJPbmVcbiAgICAgIGtTaGFyZTogc2lnblNoYXJlcy5rU2hhcmUsXG4gICAgfSk7XG4gICAgY29uc3Qgc2lnbkNvbnZlcnRTMTIgPSBhd2FpdCBNUEMuc2lnbkNvbnZlcnRTdGVwMih7XG4gICAgICBhU2hhcmU6IHNpZ25Db252ZXJ0UzIxLmFTaGFyZSxcbiAgICAgIHdTaGFyZTogc2lnblNoYXJlcy53U2hhcmUsXG4gICAgfSk7XG4gICAgY29uc3Qgc2lnbkNvbnZlcnRTMjFfMiA9IGF3YWl0IE1QQy5zaWduQ29udmVydFN0ZXAzKHtcbiAgICAgIG11U2hhcmU6IHNpZ25Db252ZXJ0UzEyLm11U2hhcmUsXG4gICAgICBiU2hhcmU6IHNpZ25Db252ZXJ0UzIxLmJTaGFyZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IFtzaWduQ29tYmluZU9uZSwgc2lnbkNvbWJpbmVUd29dID0gW1xuICAgICAgTVBDLnNpZ25Db21iaW5lKHtcbiAgICAgICAgZ1NoYXJlOiBzaWduQ29udmVydFMxMi5nU2hhcmUsXG4gICAgICAgIHNpZ25JbmRleDoge1xuICAgICAgICAgIGk6IHNpZ25Db252ZXJ0UzEyLm11U2hhcmUuaSxcbiAgICAgICAgICBqOiBzaWduQ29udmVydFMxMi5tdVNoYXJlLmosXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICAgIE1QQy5zaWduQ29tYmluZSh7XG4gICAgICAgIGdTaGFyZTogc2lnbkNvbnZlcnRTMjFfMi5nU2hhcmUsXG4gICAgICAgIHNpZ25JbmRleDoge1xuICAgICAgICAgIGk6IHNpZ25Db252ZXJ0UzIxXzIuc2lnbkluZGV4LmksXG4gICAgICAgICAgajogc2lnbkNvbnZlcnRTMjFfMi5zaWduSW5kZXguaixcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF07XG5cbiAgICBjb25zdCBNRVNTQUdFID0gQnVmZmVyLmZyb20odHhIZXgsICdoZXgnKTtcblxuICAgIGNvbnN0IFtzaWduQSwgc2lnbkJdID0gW1xuICAgICAgTVBDLnNpZ24oTUVTU0FHRSwgc2lnbkNvbWJpbmVPbmUub1NoYXJlLCBzaWduQ29tYmluZVR3by5kU2hhcmUsIGNyZWF0ZUhhc2goJ3NoYTI1NicpKSxcbiAgICAgIE1QQy5zaWduKE1FU1NBR0UsIHNpZ25Db21iaW5lVHdvLm9TaGFyZSwgc2lnbkNvbWJpbmVPbmUuZFNoYXJlLCBjcmVhdGVIYXNoKCdzaGEyNTYnKSksXG4gICAgXTtcblxuICAgIHJldHVybiBNUEMuY29uc3RydWN0U2lnbmF0dXJlKFtzaWduQSwgc2lnbkJdKTtcbiAgfVxufVxuIl19
61
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRvbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hdG9tLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLDREQUFxRjtBQUNyRiw4Q0FBb0U7QUFDcEUsNENBQThFO0FBQzlFLCtCQUEyRDtBQUMzRCwrQ0FBd0Q7QUFDeEQsd0RBQWdDO0FBRWhDLE1BQWEsSUFBSyxTQUFRLDRCQUFVO0lBRWxDLFlBQXNCLEtBQWdCLEVBQUUsV0FBdUM7UUFDN0UsS0FBSyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztRQUUxQixJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ2hCLE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztTQUN2RTtRQUVELElBQUksQ0FBQyxZQUFZLEdBQUcsV0FBVyxDQUFDO0lBQ2xDLENBQUM7SUFFRCxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQWdCLEVBQUUsV0FBdUM7UUFDN0UsT0FBTyxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVELG1CQUFtQjtJQUNuQixhQUFhO1FBQ1gsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRUQsVUFBVTtRQUNSLE9BQU8sSUFBSSwrQkFBeUIsQ0FBQyxlQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDbkUsQ0FBQztJQUVELG1CQUFtQjtJQUNuQixjQUFjLENBQUMsT0FBZTtRQUM1QixPQUFPLGVBQUssQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLElBQUksZUFBSyxDQUFDLHVCQUF1QixDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2pGLENBQUM7SUFFRCxtQkFBbUI7SUFDbkIsZUFBZTtRQUNiLE9BQU8sa0JBQVEsQ0FBQyxJQUFJLENBQUM7SUFDdkIsQ0FBQztJQUVELG1CQUFtQjtJQUNuQixtQkFBbUI7UUFDakIsT0FBTztZQUNMLFNBQVMsRUFBRSxzQkFBVTtZQUNyQixRQUFRLEVBQUUscUJBQVM7U0FDcEIsQ0FBQztJQUNKLENBQUM7SUFFRCxtQkFBbUI7SUFDbkIsVUFBVSxDQUFDLFNBQWlCO1FBQzFCLE9BQU8sSUFBSSxhQUFPLENBQUMsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7O09BRUc7SUFDTyxnQkFBZ0I7UUFDeEIsT0FBTyx1QkFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxXQUFXLENBQUM7SUFDdkQsQ0FBQztJQUVELHVCQUF1QixDQUFDLE1BQWM7UUFDcEMsT0FBTyxJQUFJLGFBQU8sQ0FBQyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ25ELENBQUM7Q0FDRjtBQTFERCxvQkEwREMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb3Ntb3NDb2luLCBDb3Ntb3NLZXlQYWlyLCBHYXNBbW91bnREZXRhaWxzIH0gZnJvbSAnQGJpdGdvL2Fic3RyYWN0LWNvc21vcyc7XG5pbXBvcnQgeyBCYXNlQ29pbiwgQml0R29CYXNlLCBFbnZpcm9ubWVudHMgfSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuaW1wb3J0IHsgQmFzZVVuaXQsIEJhc2VDb2luIGFzIFN0YXRpY3NCYXNlQ29pbiwgY29pbnMgfSBmcm9tICdAYml0Z28vc3RhdGljcyc7XG5pbXBvcnQgeyBLZXlQYWlyLCBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5IH0gZnJvbSAnLi9saWInO1xuaW1wb3J0IHsgR0FTX0FNT1VOVCwgR0FTX0xJTUlUIH0gZnJvbSAnLi9saWIvY29uc3RhbnRzJztcbmltcG9ydCB1dGlscyBmcm9tICcuL2xpYi91dGlscyc7XG5cbmV4cG9ydCBjbGFzcyBBdG9tIGV4dGVuZHMgQ29zbW9zQ29pbiB7XG4gIHByb3RlY3RlZCByZWFkb25seSBfc3RhdGljc0NvaW46IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj47XG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pIHtcbiAgICBzdXBlcihiaXRnbywgc3RhdGljc0NvaW4pO1xuXG4gICAgaWYgKCFzdGF0aWNzQ29pbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHJlcXVpcmVkIGNvbnN0cnVjdG9yIHBhcmFtZXRlciBzdGF0aWNzQ29pbicpO1xuICAgIH1cblxuICAgIHRoaXMuX3N0YXRpY3NDb2luID0gc3RhdGljc0NvaW47XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlSW5zdGFuY2UoYml0Z286IEJpdEdvQmFzZSwgc3RhdGljc0NvaW4/OiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+KTogQmFzZUNvaW4ge1xuICAgIHJldHVybiBuZXcgQXRvbShiaXRnbywgc3RhdGljc0NvaW4pO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICoqL1xuICBnZXRCYXNlRmFjdG9yKCk6IHN0cmluZyB8IG51bWJlciB7XG4gICAgcmV0dXJuIDFlNjtcbiAgfVxuXG4gIGdldEJ1aWxkZXIoKTogVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSB7XG4gICAgcmV0dXJuIG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCh0aGlzLmdldENoYWluKCkpKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgaXNWYWxpZEFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHV0aWxzLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpIHx8IHV0aWxzLmlzVmFsaWRWYWxpZGF0b3JBZGRyZXNzKGFkZHJlc3MpO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICoqL1xuICBnZXREZW5vbWluYXRpb24oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gQmFzZVVuaXQuQVRPTTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgZ2V0R2FzQW1vdW50RGV0YWlscygpOiBHYXNBbW91bnREZXRhaWxzIHtcbiAgICByZXR1cm4ge1xuICAgICAgZ2FzQW1vdW50OiBHQVNfQU1PVU5ULFxuICAgICAgZ2FzTGltaXQ6IEdBU19MSU1JVCxcbiAgICB9O1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICoqL1xuICBnZXRLZXlQYWlyKHB1YmxpY0tleTogc3RyaW5nKTogQ29zbW9zS2V5UGFpciB7XG4gICAgcmV0dXJuIG5ldyBLZXlQYWlyKHsgcHViOiBwdWJsaWNLZXkgfSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBwdWJsaWMgbm9kZSB1cmwgZnJvbSB0aGUgRW52aXJvbm1lbnRzIGNvbnN0YW50IHdlIGhhdmUgZGVmaW5lZFxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFB1YmxpY05vZGVVcmwoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gRW52aXJvbm1lbnRzW3RoaXMuYml0Z28uZ2V0RW52KCldLmF0b21Ob2RlVXJsO1xuICB9XG5cbiAgZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkocHViS2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBuZXcgS2V5UGFpcih7IHB1YjogcHViS2V5IH0pLmdldEFkZHJlc3MoKTtcbiAgfVxufVxuIl19