@bitgo-beta/sdk-coin-ada 2.2.3-alpha.48 → 2.2.3-alpha.481

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 (127) hide show
  1. package/dist/src/ada.d.ts +43 -20
  2. package/dist/src/ada.d.ts.map +1 -1
  3. package/dist/src/ada.js +354 -99
  4. package/dist/src/adaToken.d.ts +16 -11
  5. package/dist/src/adaToken.d.ts.map +1 -1
  6. package/dist/src/adaToken.js +108 -3
  7. package/dist/src/index.js +6 -2
  8. package/dist/src/lib/index.d.ts +5 -1
  9. package/dist/src/lib/index.d.ts.map +1 -1
  10. package/dist/src/lib/index.js +35 -11
  11. package/dist/src/lib/keyPair.js +29 -16
  12. package/dist/src/lib/messages/cip8/cip8Message.d.ts +25 -0
  13. package/dist/src/lib/messages/cip8/cip8Message.d.ts.map +1 -0
  14. package/dist/src/lib/messages/cip8/cip8Message.js +140 -0
  15. package/dist/src/lib/messages/cip8/cip8MessageBuilder.d.ts +19 -0
  16. package/dist/src/lib/messages/cip8/cip8MessageBuilder.d.ts.map +1 -0
  17. package/dist/src/lib/messages/cip8/cip8MessageBuilder.js +27 -0
  18. package/dist/src/lib/messages/cip8/index.d.ts +4 -0
  19. package/dist/src/lib/messages/cip8/index.d.ts.map +1 -0
  20. package/dist/src/lib/messages/cip8/index.js +20 -0
  21. package/dist/src/lib/messages/cip8/utils.d.ts +24 -0
  22. package/dist/src/lib/messages/cip8/utils.d.ts.map +1 -0
  23. package/dist/src/lib/messages/cip8/utils.js +73 -0
  24. package/dist/src/lib/messages/index.d.ts +3 -0
  25. package/dist/src/lib/messages/index.d.ts.map +1 -0
  26. package/dist/src/lib/messages/index.js +19 -0
  27. package/dist/src/lib/messages/messageBuilderFactory.d.ts +7 -0
  28. package/dist/src/lib/messages/messageBuilderFactory.d.ts.map +1 -0
  29. package/dist/src/lib/messages/messageBuilderFactory.js +20 -0
  30. package/dist/src/lib/stakingActivateBuilder.d.ts +1 -1
  31. package/dist/src/lib/stakingActivateBuilder.d.ts.map +1 -1
  32. package/dist/src/lib/stakingActivateBuilder.js +30 -10
  33. package/dist/src/lib/{stakingWithdrawRewardsBuilder.d.ts → stakingBaseClaimBuilder.d.ts} +6 -7
  34. package/dist/src/lib/stakingBaseClaimBuilder.d.ts.map +1 -0
  35. package/dist/src/lib/stakingBaseClaimBuilder.js +35 -0
  36. package/dist/src/lib/stakingClaimRewardsBuilder.d.ts +10 -0
  37. package/dist/src/lib/stakingClaimRewardsBuilder.d.ts.map +1 -0
  38. package/dist/src/lib/stakingClaimRewardsBuilder.js +22 -0
  39. package/dist/src/lib/stakingDeactivateBuilder.js +24 -10
  40. package/dist/src/lib/stakingPledgeBuilder.d.ts +23 -0
  41. package/dist/src/lib/stakingPledgeBuilder.d.ts.map +1 -0
  42. package/dist/src/lib/stakingPledgeBuilder.js +43 -0
  43. package/dist/src/lib/stakingWithdrawBuilder.d.ts +12 -0
  44. package/dist/src/lib/stakingWithdrawBuilder.d.ts.map +1 -0
  45. package/dist/src/lib/stakingWithdrawBuilder.js +22 -0
  46. package/dist/src/lib/transaction.d.ts +41 -5
  47. package/dist/src/lib/transaction.d.ts.map +1 -1
  48. package/dist/src/lib/transaction.js +144 -21
  49. package/dist/src/lib/transactionBuilder.d.ts +86 -3
  50. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  51. package/dist/src/lib/transactionBuilder.js +512 -25
  52. package/dist/src/lib/transactionBuilderFactory.d.ts +8 -2
  53. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
  54. package/dist/src/lib/transactionBuilderFactory.js +21 -3
  55. package/dist/src/lib/utils.d.ts +29 -0
  56. package/dist/src/lib/utils.d.ts.map +1 -1
  57. package/dist/src/lib/utils.js +170 -17
  58. package/dist/src/lib/voteDelegationBuilder.d.ts +24 -0
  59. package/dist/src/lib/voteDelegationBuilder.d.ts.map +1 -0
  60. package/dist/src/lib/voteDelegationBuilder.js +84 -0
  61. package/dist/test/resources/cip8Resources.d.ts +25 -0
  62. package/dist/test/resources/cip8Resources.d.ts.map +1 -0
  63. package/dist/test/resources/cip8Resources.js +76 -0
  64. package/dist/test/resources/index.d.ts +458 -0
  65. package/dist/test/resources/index.d.ts.map +1 -0
  66. package/dist/test/resources/index.js +659 -0
  67. package/dist/test/unit/StakingActivateBuilder.d.ts +2 -0
  68. package/dist/test/unit/StakingActivateBuilder.d.ts.map +1 -0
  69. package/dist/test/unit/StakingActivateBuilder.js +213 -0
  70. package/dist/test/unit/StakingDeactivateBuilder.d.ts +2 -0
  71. package/dist/test/unit/StakingDeactivateBuilder.d.ts.map +1 -0
  72. package/dist/test/unit/StakingDeactivateBuilder.js +158 -0
  73. package/dist/test/unit/ada.d.ts +5 -0
  74. package/dist/test/unit/ada.d.ts.map +1 -0
  75. package/dist/test/unit/ada.js +1246 -0
  76. package/dist/test/unit/getBuilderFactory.d.ts +3 -0
  77. package/dist/test/unit/getBuilderFactory.d.ts.map +1 -0
  78. package/dist/test/unit/getBuilderFactory.js +10 -0
  79. package/dist/test/unit/index.d.ts +2 -0
  80. package/dist/test/unit/index.d.ts.map +1 -0
  81. package/dist/test/unit/index.js +32 -0
  82. package/dist/test/unit/keyPair.d.ts +2 -0
  83. package/dist/test/unit/keyPair.d.ts.map +1 -0
  84. package/dist/test/unit/keyPair.js +88 -0
  85. package/dist/test/unit/messages/cip8/cip8Message.d.ts +2 -0
  86. package/dist/test/unit/messages/cip8/cip8Message.d.ts.map +1 -0
  87. package/dist/test/unit/messages/cip8/cip8Message.js +131 -0
  88. package/dist/test/unit/messages/cip8/cip8MessageBuilder.d.ts +2 -0
  89. package/dist/test/unit/messages/cip8/cip8MessageBuilder.d.ts.map +1 -0
  90. package/dist/test/unit/messages/cip8/cip8MessageBuilder.js +132 -0
  91. package/dist/test/unit/messages/cip8/utils.d.ts +2 -0
  92. package/dist/test/unit/messages/cip8/utils.d.ts.map +1 -0
  93. package/dist/test/unit/messages/cip8/utils.js +127 -0
  94. package/dist/test/unit/messages/messageBuilderFactory.d.ts +2 -0
  95. package/dist/test/unit/messages/messageBuilderFactory.d.ts.map +1 -0
  96. package/dist/test/unit/messages/messageBuilderFactory.js +35 -0
  97. package/dist/test/unit/stakingClaimRewardsBuilder.d.ts +2 -0
  98. package/dist/test/unit/stakingClaimRewardsBuilder.d.ts.map +1 -0
  99. package/dist/test/unit/stakingClaimRewardsBuilder.js +70 -0
  100. package/dist/test/unit/stakingPledgeBuilder.d.ts +2 -0
  101. package/dist/test/unit/stakingPledgeBuilder.d.ts.map +1 -0
  102. package/dist/test/unit/stakingPledgeBuilder.js +141 -0
  103. package/dist/test/unit/stakingWithdrawBuilder.d.ts +2 -0
  104. package/dist/test/unit/stakingWithdrawBuilder.d.ts.map +1 -0
  105. package/dist/test/unit/stakingWithdrawBuilder.js +167 -0
  106. package/dist/test/unit/tokenWithdrawal.d.ts +2 -0
  107. package/dist/test/unit/tokenWithdrawal.d.ts.map +1 -0
  108. package/dist/test/unit/tokenWithdrawal.js +842 -0
  109. package/dist/test/unit/transaction.d.ts +2 -0
  110. package/dist/test/unit/transaction.d.ts.map +1 -0
  111. package/dist/test/unit/transaction.js +100 -0
  112. package/dist/test/unit/transactionBuilder.d.ts +2 -0
  113. package/dist/test/unit/transactionBuilder.d.ts.map +1 -0
  114. package/dist/test/unit/transactionBuilder.js +454 -0
  115. package/dist/test/unit/utils.d.ts +2 -0
  116. package/dist/test/unit/utils.d.ts.map +1 -0
  117. package/dist/test/unit/utils.js +138 -0
  118. package/dist/test/unit/voteDelegationBuilder.d.ts +2 -0
  119. package/dist/test/unit/voteDelegationBuilder.d.ts.map +1 -0
  120. package/dist/test/unit/voteDelegationBuilder.js +96 -0
  121. package/dist/tsconfig.tsbuildinfo +1 -0
  122. package/package.json +17 -11
  123. package/.eslintignore +0 -5
  124. package/.mocharc.yml +0 -8
  125. package/CHANGELOG.md +0 -152
  126. package/dist/src/lib/stakingWithdrawRewardsBuilder.d.ts.map +0 -1
  127. package/dist/src/lib/stakingWithdrawRewardsBuilder.js +0 -43
package/dist/src/ada.js CHANGED
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -11,24 +15,37 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
11
15
  }) : function(o, v) {
12
16
  o["default"] = v;
13
17
  });
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
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
21
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
22
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
37
  };
24
38
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.Ada = void 0;
39
+ exports.Ada = exports.DEFAULT_SCAN_FACTOR = void 0;
26
40
  const assert_1 = __importDefault(require("assert"));
27
41
  const sdk_core_1 = require("@bitgo-beta/sdk-core");
28
42
  const lib_1 = require("./lib");
29
43
  const statics_1 = require("@bitgo-beta/statics");
30
44
  const utils_1 = __importDefault(require("./lib/utils"));
31
45
  const request = __importStar(require("superagent"));
46
+ const bignumber_js_1 = __importDefault(require("bignumber.js"));
47
+ const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
48
+ exports.DEFAULT_SCAN_FACTOR = 20; // default number of receive addresses to scan for funds
32
49
  class Ada extends sdk_core_1.BaseCoin {
33
50
  constructor(bitgo, staticsCoin) {
34
51
  super(bitgo);
@@ -71,9 +88,9 @@ class Ada extends sdk_core_1.BaseCoin {
71
88
  async verifyTransaction(params) {
72
89
  try {
73
90
  const coinConfig = statics_1.coins.get(this.getChain());
74
- const { txPrebuild: txPrebuild, txParams: txParams } = params;
91
+ const { txPrebuild: txPrebuild, txParams: txParams, verification, wallet } = params;
75
92
  const transaction = new lib_1.Transaction(coinConfig);
76
- assert_1.default(txPrebuild.txHex, new Error('missing required tx prebuild property txHex'));
93
+ (0, assert_1.default)(txPrebuild.txHex, new Error('missing required tx prebuild property txHex'));
77
94
  const rawTx = txPrebuild.txHex;
78
95
  transaction.fromRawTransaction(rawTx);
79
96
  const explainedTx = transaction.explainTransaction();
@@ -90,6 +107,15 @@ class Ada extends sdk_core_1.BaseCoin {
90
107
  }
91
108
  }
92
109
  }
110
+ else if (verification?.consolidationToBaseAddress) {
111
+ const baseAddress = wallet.coinSpecific()?.baseAddress || wallet.coinSpecific()?.rootAddress;
112
+ const feeAddress = txPrebuild.txInfo?.feeAddress;
113
+ for (const output of explainedTx.outputs) {
114
+ if (output.address !== baseAddress && output.address !== feeAddress) {
115
+ throw new Error('tx outputs does not match with expected address');
116
+ }
117
+ }
118
+ }
93
119
  }
94
120
  catch (e) {
95
121
  if (e instanceof sdk_core_1.NodeEnvironmentError) {
@@ -102,16 +128,27 @@ class Ada extends sdk_core_1.BaseCoin {
102
128
  return true;
103
129
  }
104
130
  async isWalletAddress(params) {
105
- const { address } = params;
131
+ const { address, keychains, index } = params;
106
132
  if (!this.isValidAddress(address)) {
107
133
  throw new sdk_core_1.InvalidAddressError(`Invalid Cardano Address: ${address}`);
108
134
  }
109
- return true;
135
+ const indexNumber = Number(index);
136
+ if (isNaN(indexNumber)) {
137
+ throw new Error('Invalid index. index must be a number.');
138
+ }
139
+ const commonKeychain = (0, sdk_core_1.extractCommonKeychain)(keychains);
140
+ const derivationSeed = keychains[0]?.derivedFromParentWithSeed;
141
+ const { address: derivedAddress } = await this.getAdaAddressAndAccountId({
142
+ bitgoKey: commonKeychain,
143
+ index: indexNumber,
144
+ seed: derivationSeed,
145
+ });
146
+ return address === derivedAddress;
110
147
  }
111
148
  /** @inheritDoc */
112
149
  async signMessage(key, message) {
113
150
  const adaKeypair = new lib_1.KeyPair({ prv: key.prv });
114
- const messageHex = message instanceof Buffer ? message.toString('hex') : message;
151
+ const messageHex = typeof message === 'string' ? message : message.toString('hex');
115
152
  return Buffer.from(adaKeypair.signMessage(messageHex));
116
153
  }
117
154
  /**
@@ -207,14 +244,60 @@ class Ada extends sdk_core_1.BaseCoin {
207
244
  const body = res.body[0];
208
245
  return body;
209
246
  }
247
+ /** inherited doc */
248
+ async createBroadcastableSweepTransaction(params) {
249
+ const req = params.signatureShares;
250
+ const broadcastableTransactions = [];
251
+ let lastScanIndex = 0;
252
+ for (let i = 0; i < req.length; i++) {
253
+ const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
254
+ const transaction = req[i].txRequest.transactions[0].unsignedTx;
255
+ if (!req[i].ovc || !req[i].ovc[0].eddsaSignature) {
256
+ throw new Error('Missing signature(s)');
257
+ }
258
+ const signature = req[i].ovc[0].eddsaSignature;
259
+ if (!transaction.signableHex) {
260
+ throw new Error('Missing signable hex');
261
+ }
262
+ const messageBuffer = Buffer.from(transaction.signableHex, 'hex');
263
+ const result = MPC.verify(messageBuffer, signature);
264
+ if (!result) {
265
+ throw new Error('Invalid signature');
266
+ }
267
+ const signatureHex = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]);
268
+ const txBuilder = this.getBuilder().from(transaction.serializedTx);
269
+ if (!transaction.coinSpecific?.commonKeychain) {
270
+ throw new Error('Missing common keychain');
271
+ }
272
+ const commonKeychain = transaction.coinSpecific.commonKeychain;
273
+ if (!transaction.derivationPath) {
274
+ throw new Error('Missing derivation path');
275
+ }
276
+ const derivationPath = transaction.derivationPath;
277
+ const accountId = MPC.deriveUnhardened(commonKeychain, derivationPath).slice(0, 64);
278
+ const adaKeyPair = new lib_1.KeyPair({ pub: accountId });
279
+ // add combined signature from ovc
280
+ txBuilder.addSignature({ pub: adaKeyPair.getKeys().pub }, signatureHex);
281
+ const signedTransaction = await txBuilder.build();
282
+ const serializedTx = signedTransaction.toBroadcastFormat();
283
+ broadcastableTransactions.push({
284
+ serializedTx: serializedTx,
285
+ scanIndex: transaction.scanIndex,
286
+ });
287
+ if (i === req.length - 1 && transaction.coinSpecific.lastScanIndex) {
288
+ lastScanIndex = transaction.coinSpecific.lastScanIndex;
289
+ }
290
+ }
291
+ return { transactions: broadcastableTransactions, lastScanIndex };
292
+ }
210
293
  /**
211
- * Builds a funds recovery transaction without BitGo
294
+ * Builds funds recovery transaction(s) without BitGo
212
295
  *
213
- * @param {RecoveryOptions} params parameters needed to construct and
296
+ * @param {MPCRecoveryOptions} params parameters needed to construct and
214
297
  * (maybe) sign the transaction
215
298
  *
216
- * @returns {AdaTx} the serialized transaction hex string and index
217
- * of the address being swept
299
+ * @returns {MPCTx | MPCSweepTxs} array of the serialized transaction hex strings and indices
300
+ * of the addresses being swept
218
301
  */
219
302
  async recover(params) {
220
303
  if (!params.bitgoKey) {
@@ -223,101 +306,261 @@ class Ada extends sdk_core_1.BaseCoin {
223
306
  if (!params.recoveryDestination || !this.isValidAddress(params.recoveryDestination)) {
224
307
  throw new Error('invalid recoveryDestination');
225
308
  }
226
- let addrFormat = sdk_core_1.AddressFormat.testnet;
227
- if (this.getChain() === 'ada') {
228
- addrFormat = sdk_core_1.AddressFormat.mainnet;
309
+ const index = params.index || 0;
310
+ const currPath = params.seed ? (0, sdk_lib_mpc_1.getDerivationPath)(params.seed) + `/${index}` : `m/${index}`;
311
+ const bitgoKey = params.bitgoKey.replace(/\s/g, '');
312
+ const addressParams = {
313
+ bitgoKey: params.bitgoKey,
314
+ index: index,
315
+ seed: params.seed,
316
+ };
317
+ const { address: senderAddr, accountId } = await this.getAdaAddressAndAccountId(addressParams);
318
+ const isUnsignedSweep = !params.walletPassphrase;
319
+ const { balance, utxoSet } = await this.getAddressInfo(senderAddr);
320
+ if (balance <= 0) {
321
+ throw new Error('Did not find address with funds to recover.');
229
322
  }
230
- let startIdx = params.startingScanIndex;
231
- if (startIdx === undefined) {
232
- startIdx = 0;
323
+ // Aggregate token assets from all UTxOs into a fingerprint-keyed map for the builder
324
+ const aggregatedAssetList = {};
325
+ for (const utxo of utxoSet) {
326
+ for (const asset of utxo.asset_list ?? []) {
327
+ const fp = asset.fingerprint;
328
+ if (aggregatedAssetList[fp]) {
329
+ aggregatedAssetList[fp].quantity = (BigInt(aggregatedAssetList[fp].quantity) + BigInt(asset.quantity)).toString();
330
+ }
331
+ else {
332
+ aggregatedAssetList[fp] = {
333
+ policy_id: asset.policy_id,
334
+ asset_name: asset.encoded_asset_name ?? asset.asset_name,
335
+ quantity: asset.quantity,
336
+ };
337
+ }
338
+ }
233
339
  }
234
- else if (!Number.isInteger(startIdx) || startIdx < 0) {
235
- throw new Error('Invalid starting index to scan for addresses');
340
+ // first build the unsigned txn
341
+ const tipAbsSlot = await this.getChainTipInfo();
342
+ const txBuilder = this.getBuilder().getTransferBuilder();
343
+ txBuilder.changeAddress(params.recoveryDestination, balance.toString(), aggregatedAssetList);
344
+ if (Object.keys(aggregatedAssetList).length > 0) {
345
+ txBuilder.isTokenTransaction();
236
346
  }
237
- let numIteration = params.scan;
238
- if (numIteration === undefined) {
239
- numIteration = 20;
347
+ for (const utxo of utxoSet) {
348
+ txBuilder.input({ transaction_id: utxo.tx_hash, transaction_index: utxo.tx_index });
240
349
  }
241
- else if (!Number.isInteger(numIteration) || numIteration <= 0) {
242
- throw new Error('Invalid scanning factor');
350
+ // each slot is about 1 second, so this transaction should be valid for
351
+ // 7 * 86,400 seconds (7 days) after creation
352
+ txBuilder.ttl(Number(tipAbsSlot.abs_slot) + 7 * 86400);
353
+ const unsignedTransaction = (await txBuilder.build());
354
+ // sum up every output
355
+ const amount = unsignedTransaction
356
+ .toJson()
357
+ .outputs.reduce((acc, output) => new bignumber_js_1.default(acc).plus(output.amount), new bignumber_js_1.default(0));
358
+ if (amount.isLessThan(1000000)) {
359
+ throw new Error('Insufficient funds to recover, minimum required is 1 ADA plus fees, got ' +
360
+ amount.toString() +
361
+ ' fees: ' +
362
+ unsignedTransaction.getFee);
243
363
  }
244
- const bitgoKey = params.bitgoKey.replace(/\s/g, '');
245
- const isUnsignedSweep = !params.userKey && !params.backupKey && !params.walletPassphrase;
246
- const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
247
- const stakeKeyPair = new lib_1.KeyPair({ pub: MPC.deriveUnhardened(bitgoKey, 'm/0').slice(0, 64) });
248
- for (let i = startIdx; i < numIteration + startIdx; i++) {
249
- const currPath = `m/${i}`;
250
- const accountId = MPC.deriveUnhardened(bitgoKey, currPath).slice(0, 64);
251
- const paymentKeyPair = new lib_1.KeyPair({ pub: accountId });
252
- const senderAddr = lib_1.Utils.default.createBaseAddressWithStakeAndPaymentKey(stakeKeyPair, paymentKeyPair, addrFormat);
253
- const { balance, utxoSet } = await this.getAddressInfo(senderAddr);
254
- if (balance <= 0) {
255
- continue;
364
+ let serializedTx = unsignedTransaction.toBroadcastFormat();
365
+ if (!isUnsignedSweep) {
366
+ if (!params.userKey) {
367
+ throw new Error('missing userKey');
256
368
  }
257
- // first build the unsigned txn
258
- const tipAbsSlot = await this.getChainTipInfo();
259
- const txBuilder = this.getBuilder().getTransferBuilder();
260
- txBuilder.changeAddress(params.recoveryDestination, balance.toString());
261
- for (const utxo of utxoSet) {
262
- txBuilder.input({ transaction_id: utxo.tx_hash, transaction_index: utxo.tx_index });
369
+ if (!params.backupKey) {
370
+ throw new Error('missing backupKey');
263
371
  }
264
- // each slot is about 1 second, so this transaction should be valid for
265
- // 7 * 86,400 seconds (7 days) after creation
266
- txBuilder.ttl(Number(tipAbsSlot.abs_slot) + 7 * 86400);
267
- const unsignedTransaction = (await txBuilder.build());
268
- let serializedTx = unsignedTransaction.toBroadcastFormat();
269
- if (!isUnsignedSweep) {
270
- if (!params.userKey) {
271
- throw new Error('missing userKey');
272
- }
273
- if (!params.backupKey) {
274
- throw new Error('missing backupKey');
275
- }
276
- if (!params.walletPassphrase) {
277
- throw new Error('missing wallet passphrase');
278
- }
279
- // Clean up whitespace from entered values
280
- const userKey = params.userKey.replace(/\s/g, '');
281
- const backupKey = params.backupKey.replace(/\s/g, '');
282
- // Decrypt private keys from KeyCard values
283
- let userPrv;
284
- try {
285
- userPrv = this.bitgo.decrypt({
286
- input: userKey,
287
- password: params.walletPassphrase,
288
- });
289
- }
290
- catch (e) {
291
- throw new Error(`Error decrypting user keychain: ${e.message}`);
292
- }
293
- /** TODO BG-52419 Implement Codec for parsing */
294
- const userSigningMaterial = JSON.parse(userPrv);
295
- let backupPrv;
296
- try {
297
- backupPrv = this.bitgo.decrypt({
298
- input: backupKey,
299
- password: params.walletPassphrase,
300
- });
301
- }
302
- catch (e) {
303
- throw new Error(`Error decrypting backup keychain: ${e.message}`);
372
+ if (!params.walletPassphrase) {
373
+ throw new Error('missing wallet passphrase');
374
+ }
375
+ // Clean up whitespace from entered values
376
+ const userKey = params.userKey.replace(/\s/g, '');
377
+ const backupKey = params.backupKey.replace(/\s/g, '');
378
+ // Decrypt private keys from KeyCard values
379
+ let userPrv;
380
+ try {
381
+ userPrv = this.bitgo.decrypt({
382
+ input: userKey,
383
+ password: params.walletPassphrase,
384
+ });
385
+ }
386
+ catch (e) {
387
+ throw new Error(`Error decrypting user keychain: ${e.message}`);
388
+ }
389
+ /** TODO BG-52419 Implement Codec for parsing */
390
+ const userSigningMaterial = JSON.parse(userPrv);
391
+ let backupPrv;
392
+ try {
393
+ backupPrv = this.bitgo.decrypt({
394
+ input: backupKey,
395
+ password: params.walletPassphrase,
396
+ });
397
+ }
398
+ catch (e) {
399
+ throw new Error(`Error decrypting backup keychain: ${e.message}`);
400
+ }
401
+ const backupSigningMaterial = JSON.parse(backupPrv);
402
+ // add signature
403
+ const signatureHex = await sdk_core_1.EDDSAMethods.getTSSSignature(userSigningMaterial, backupSigningMaterial, currPath, unsignedTransaction);
404
+ const adaKeyPair = new lib_1.KeyPair({ pub: accountId });
405
+ txBuilder.addSignature({ pub: adaKeyPair.getKeys().pub }, signatureHex);
406
+ const signedTransaction = await txBuilder.build();
407
+ serializedTx = signedTransaction.toBroadcastFormat();
408
+ }
409
+ else {
410
+ const transactionPrebuild = { txHex: serializedTx };
411
+ const parsedTx = await this.parseTransaction({ txPrebuild: transactionPrebuild });
412
+ const walletCoin = this.getChain();
413
+ const output = parsedTx.outputs[0];
414
+ const inputs = [
415
+ {
416
+ address: senderAddr,
417
+ valueString: output.amount,
418
+ value: new bignumber_js_1.default(output.amount).toNumber(),
419
+ },
420
+ ];
421
+ const outputs = [
422
+ {
423
+ address: output.address,
424
+ valueString: output.amount,
425
+ coinName: walletCoin,
426
+ },
427
+ ];
428
+ const spendAmount = output.amount;
429
+ const completedParsedTx = { inputs: inputs, outputs: outputs, spendAmount: spendAmount, type: '' };
430
+ const fee = new bignumber_js_1.default(parsedTx.fee.fee);
431
+ const feeInfo = { fee: fee.toNumber(), feeString: fee.toString() };
432
+ const coinSpecific = { commonKeychain: bitgoKey };
433
+ const transaction = {
434
+ serializedTx: serializedTx,
435
+ scanIndex: index,
436
+ coin: walletCoin,
437
+ signableHex: unsignedTransaction.signablePayload.toString('hex'),
438
+ derivationPath: currPath,
439
+ parsedTx: completedParsedTx,
440
+ feeInfo: feeInfo,
441
+ coinSpecific: coinSpecific,
442
+ };
443
+ const unsignedTx = { unsignedTx: transaction, signatureShares: [] };
444
+ const transactions = [unsignedTx];
445
+ const txRequest = {
446
+ transactions: transactions,
447
+ walletCoin: walletCoin,
448
+ };
449
+ const txRequests = { txRequests: [txRequest] };
450
+ return txRequests;
451
+ }
452
+ const transaction = { serializedTx: serializedTx, scanIndex: index };
453
+ return transaction;
454
+ }
455
+ /**
456
+ * Builds native ADA recoveries of receive addresses in batch without BitGo.
457
+ * Funds will be recovered to base address first. You need to initiate another sweep txn after that.
458
+ *
459
+ * @param {MPCConsolidationRecoveryOptions} params - options for consolidation recovery.
460
+ * @param {string} [params.startingScanIndex] - receive address index to start scanning from. default to 1 (inclusive).
461
+ * @param {string} [params.endingScanIndex] - receive address index to end scanning at. default to startingScanIndex + 20 (exclusive).
462
+ */
463
+ async recoverConsolidations(params) {
464
+ const isUnsignedSweep = !params.userKey && !params.backupKey && !params.walletPassphrase;
465
+ const startIdx = params.startingScanIndex || 1;
466
+ const endIdx = params.endingScanIndex || startIdx + exports.DEFAULT_SCAN_FACTOR;
467
+ if (startIdx < 1 || endIdx <= startIdx || endIdx - startIdx > 10 * exports.DEFAULT_SCAN_FACTOR) {
468
+ throw new Error(`Invalid starting or ending index to scan for addresses. startingScanIndex: ${startIdx}, endingScanIndex: ${endIdx}.`);
469
+ }
470
+ const addressParams = {
471
+ bitgoKey: params.bitgoKey,
472
+ index: 0,
473
+ seed: params.seed,
474
+ };
475
+ const { address: baseAddress } = await this.getAdaAddressAndAccountId(addressParams);
476
+ const consolidationTransactions = [];
477
+ let lastScanIndex = startIdx;
478
+ for (let i = startIdx; i < endIdx; i++) {
479
+ const recoverParams = {
480
+ userKey: params.userKey,
481
+ backupKey: params.backupKey,
482
+ bitgoKey: params.bitgoKey,
483
+ walletPassphrase: params.walletPassphrase,
484
+ recoveryDestination: baseAddress,
485
+ seed: params.seed,
486
+ index: i,
487
+ };
488
+ let recoveryTransaction;
489
+ try {
490
+ recoveryTransaction = await this.recover(recoverParams);
491
+ }
492
+ catch (e) {
493
+ if (e.message === 'Did not find address with funds to recover.' ||
494
+ e.message.startsWith('Insufficient funds to recover')) {
495
+ lastScanIndex = i;
496
+ continue;
304
497
  }
305
- const backupSigningMaterial = JSON.parse(backupPrv);
306
- // add signature
307
- const signatureHex = await sdk_core_1.EDDSAMethods.getTSSSignature(userSigningMaterial, backupSigningMaterial, currPath, unsignedTransaction);
308
- const adaKeyPair = new lib_1.KeyPair({ pub: accountId });
309
- txBuilder.addSignature({ pub: adaKeyPair.getKeys().pub }, signatureHex);
310
- const signedTransaction = await txBuilder.build();
311
- serializedTx = signedTransaction.toBroadcastFormat();
498
+ throw e;
499
+ }
500
+ if (isUnsignedSweep) {
501
+ consolidationTransactions.push(recoveryTransaction.txRequests[0]);
312
502
  }
313
- return { serializedTx: serializedTx, scanIndex: i };
503
+ else {
504
+ consolidationTransactions.push(recoveryTransaction);
505
+ }
506
+ lastScanIndex = i;
507
+ }
508
+ if (consolidationTransactions.length == 0) {
509
+ throw new Error('Did not find an address with funds to recover.');
510
+ }
511
+ if (isUnsignedSweep) {
512
+ // lastScanIndex will be used to inform user the last address index scanned for available funds (so they can
513
+ // appropriately adjust the scan range on the next iteration of consolidation recoveries). In the case of unsigned
514
+ // sweep consolidations, this lastScanIndex will be provided in the coinSpecific of the last txn made.
515
+ const lastTransactionCoinSpecific = {
516
+ commonKeychain: consolidationTransactions[consolidationTransactions.length - 1].transactions[0].unsignedTx.coinSpecific
517
+ .commonKeychain,
518
+ lastScanIndex: lastScanIndex,
519
+ };
520
+ consolidationTransactions[consolidationTransactions.length - 1].transactions[0].unsignedTx.coinSpecific =
521
+ lastTransactionCoinSpecific;
522
+ const consolidationSweepTransactions = { txRequests: consolidationTransactions };
523
+ return consolidationSweepTransactions;
524
+ }
525
+ return { transactions: consolidationTransactions, lastScanIndex };
526
+ }
527
+ /**
528
+ * Obtains ADA address and account id from provided bitgo key for the given index and seed (optional).
529
+ *
530
+ * @param {AdaAddressParams} params - params to obtain ada address and account id
531
+ */
532
+ async getAdaAddressAndAccountId(params) {
533
+ if (!params.bitgoKey) {
534
+ throw new Error('missing bitgoKey');
535
+ }
536
+ let addrFormat = sdk_core_1.AddressFormat.testnet;
537
+ if (this.getChain() === 'ada') {
538
+ addrFormat = sdk_core_1.AddressFormat.mainnet;
314
539
  }
315
- throw new Error('Did not find an address with funds to recover');
540
+ const bitgoKey = params.bitgoKey.replace(/\s/g, '');
541
+ const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
542
+ const derivationPathPrefix = params.seed ? (0, sdk_lib_mpc_1.getDerivationPath)(params.seed) : 'm';
543
+ const stakeKeyPair = new lib_1.KeyPair({
544
+ pub: MPC.deriveUnhardened(bitgoKey, derivationPathPrefix + '/0').slice(0, 64),
545
+ });
546
+ const currPath = derivationPathPrefix + `/${params.index}`;
547
+ const accountId = MPC.deriveUnhardened(bitgoKey, currPath).slice(0, 64);
548
+ const paymentKeyPair = new lib_1.KeyPair({ pub: accountId });
549
+ const address = lib_1.Utils.default.createBaseAddressWithStakeAndPaymentKey(stakeKeyPair, paymentKeyPair, addrFormat);
550
+ return { address, accountId };
316
551
  }
317
552
  /** inherited doc */
318
553
  supportsTss() {
319
554
  return true;
320
555
  }
556
+ /** @inheritDoc */
557
+ supportsMessageSigning() {
558
+ return true;
559
+ }
560
+ /** inherited doc */
561
+ getDefaultMultisigType() {
562
+ return sdk_core_1.multisigTypes.tss;
563
+ }
321
564
  /** inherited doc */
322
565
  getMPCAlgorithm() {
323
566
  return 'eddsa';
@@ -329,6 +572,18 @@ class Ada extends sdk_core_1.BaseCoin {
329
572
  getBuilder() {
330
573
  return new lib_1.TransactionBuilderFactory(statics_1.coins.get(this.getBaseChain()));
331
574
  }
575
+ /** inherited doc */
576
+ setCoinSpecificFieldsInIntent(intent, params) {
577
+ intent.unspents = params.unspents;
578
+ intent.senderAddress = params.senderAddress;
579
+ }
580
+ /** inherited doc */
581
+ auditDecryptedKey({ publicKey, prv, multiSigType }) {
582
+ if (multiSigType !== 'tss') {
583
+ throw new Error('Unsupported multiSigType');
584
+ }
585
+ (0, sdk_lib_mpc_1.auditEddsaPrivateKey)(prv, publicKey ?? '');
586
+ }
332
587
  }
333
588
  exports.Ada = Ada;
334
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsb0RBQTRCO0FBQzVCLG1EQW1COEI7QUFDOUIsK0JBQTZGO0FBQzdGLGlEQUFxRjtBQUNyRix3REFBbUM7QUFDbkMsb0RBQXNDO0FBcUN0QyxNQUFhLEdBQUksU0FBUSxtQkFBUTtJQUUvQixZQUFzQixLQUFnQixFQUFFLFdBQXVDO1FBQzdFLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNiLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1NBQ3ZFO1FBRUQsSUFBSSxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUM7SUFDbEMsQ0FBQztJQUVELE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBZ0IsRUFBRSxXQUF1QztRQUM3RSxPQUFPLElBQUksR0FBRyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7O09BRUc7SUFDSSxhQUFhO1FBQ2xCLE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUVNLFFBQVE7UUFDYixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDO0lBQ2hDLENBQUM7SUFFTSxTQUFTO1FBQ2QsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQztJQUNsQyxDQUFDO0lBRU0sV0FBVztRQUNoQixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDO0lBQ3BDLENBQUM7SUFFRCxZQUFZO1FBQ1YsT0FBTyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDekIsQ0FBQztJQUNEOzs7Ozs7Ozs7T0FTRztJQUNILEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxNQUFnQztRQUN0RCxJQUFJO1lBQ0YsTUFBTSxVQUFVLEdBQUcsZUFBSyxDQUFDLEdB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Q0FBQyxpQkFBaUIsRUFBRSxDQUFDO2FBQ3REO1lBQ0QsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBRSxDQUFDO1NBQ3JEO1FBQ0QsTUFBTSxJQUFJLEtBQUssQ0FBQywrQ0FBK0MsQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFFRCxvQkFBb0I7SUFDcEIsV0FBVztRQUNULE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELG9CQUFvQjtJQUNwQixlQUFlO1FBQ2IsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVELG9CQUFvQjtJQUNwQiwyQkFBMkI7UUFDekIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRU8sVUFBVTtRQUNoQixPQUFPLElBQUksK0JBQXlCLENBQUMsZUFBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7Q0FDRjtBQTFWRCxrQkEwVkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQge1xuICBCYXNlQ29pbixcbiAgQmFzZVRyYW5zYWN0aW9uLFxuICBCaXRHb0Jhc2UsXG4gIEludmFsaWRBZGRyZXNzRXJyb3IsXG4gIEtleVBhaXIsXG4gIE1QQ0FsZ29yaXRobSxcbiAgTm9kZUVudmlyb25tZW50RXJyb3IsXG4gIFBhcnNlZFRyYW5zYWN0aW9uLFxuICBQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyBhcyBCYXNlUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFNpZ25lZFRyYW5zYWN0aW9uLFxuICBTaWduVHJhbnNhY3Rpb25PcHRpb25zIGFzIEJhc2VTaWduVHJhbnNhY3Rpb25PcHRpb25zLFxuICBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uLFxuICBWZXJpZnlBZGRyZXNzT3B0aW9ucyxcbiAgVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zLFxuICBFRERTQU1ldGhvZHMsXG4gIEVERFNBTWV0aG9kVHlwZXMsXG4gIEFkZHJlc3NGb3JtYXQsXG4gIEVudmlyb25tZW50cyxcbn0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgS2V5UGFpciBhcyBBZGFLZXlQYWlyLCBUcmFuc2FjdGlvbiwgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSwgVXRpbHMgfSBmcm9tICcuL2xpYic7XG5pbXBvcnQgeyBCYXNlQ29pbiBhcyBTdGF0aWNzQmFzZUNvaW4sIENvaW5GYW1pbHksIGNvaW5zIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQgYWRhVXRpbHMgZnJvbSAnLi9saWIvdXRpbHMnO1xuaW1wb3J0ICogYXMgcmVxdWVzdCBmcm9tICdzdXBlcmFnZW50JztcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2FjdGlvblByZWJ1aWxkIHtcbiAgdHhIZXg6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBFeHBsYWluVHJhbnNhY3Rpb25PcHRpb25zIHtcbiAgdHhQcmVidWlsZDogVHJhbnNhY3Rpb25QcmVidWlsZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBZGFQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyBleHRlbmRzIEJhc2VQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyB7XG4gIHR4UHJlYnVpbGQ6IFRyYW5zYWN0aW9uUHJlYnVpbGQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2lnblRyYW5zYWN0aW9uT3B0aW9ucyBleHRlbmRzIEJhc2VTaWduVHJhbnNhY3Rpb25PcHRpb25zIHtcbiAgdHhQcmVidWlsZDogVHJhbnNhY3Rpb25QcmVidWlsZDtcbiAgcHJ2OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBSZWNvdmVyeU9wdGlvbnMge1xuICB1c2VyS2V5Pzogc3RyaW5nOyAvLyBCb3ggQVxuICBiYWNrdXBLZXk/OiBzdHJpbmc7IC8vIEJveCBCXG4gIGJpdGdvS2V5OiBzdHJpbmc7IC8vIEJveCBDXG4gIHJlY292ZXJ5RGVzdGluYXRpb246IHN0cmluZztcbiAga3JzUHJvdmlkZXI/OiBzdHJpbmc7XG4gIHdhbGxldFBhc3NwaHJhc2U/OiBzdHJpbmc7XG4gIHN0YXJ0aW5nU2NhbkluZGV4PzogbnVtYmVyO1xuICBzY2FuPzogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgQWRhVHgge1xuICBzZXJpYWxpemVkVHg6IHN0cmluZztcbiAgc2NhbkluZGV4OiBudW1iZXI7XG59XG5cbmV4cG9ydCB0eXBlIEFkYVRyYW5zYWN0aW9uRXhwbGFuYXRpb24gPSBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uO1xuXG5leHBvcnQgY2xhc3MgQWRhIGV4dGVuZHMgQmFzZUNvaW4ge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgX3N0YXRpY3NDb2luOiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+O1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoYml0Z286IEJpdEdvQmFzZSwgc3RhdGljc0NvaW4/OiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+KSB7XG4gICAgc3VwZXIoYml0Z28pO1xuICAgIGlmICghc3RhdGljc0NvaW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCBjb25zdHJ1Y3RvciBwYXJhbWV0ZXIgc3RhdGljc0NvaW4nKTtcbiAgICB9XG5cbiAgICB0aGlzLl9zdGF0aWNzQ29pbiA9IHN0YXRpY3NDb2luO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUluc3RhbmNlKGJpdGdvOiBCaXRHb0Jhc2UsIHN0YXRpY3NDb2luPzogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPik6IEJhc2VDb2luIHtcbiAgICByZXR1cm4gbmV3IEFkYShiaXRnbywgc3RhdGljc0NvaW4pO1xuICB9XG5cbiAgLyoqXG4gICAqIEZhY3RvciBiZXR3ZWVuIHRoZSBjb2luJ3MgYmFzZSB1bml0IGFuZCBpdHMgc21hbGxlc3Qgc3ViZGl2aXNvblxuICAgKi9cbiAgcHVibGljIGdldEJhc2VGYWN0b3IoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gMWU2O1xuICB9XG5cbiAgcHVibGljIGdldENoYWluKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLm5hbWU7XG4gIH1cblxuICBwdWJsaWMgZ2V0RmFtaWx5KCk6IENvaW5GYW1pbHkge1xuICAgIHJldHVybiB0aGlzLl9zdGF0aWNzQ29pbi5mYW1pbHk7XG4gIH1cblxuICBwdWJsaWMgZ2V0RnVsbE5hbWUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGljc0NvaW4uZnVsbE5hbWU7XG4gIH1cblxuICBnZXRCYXNlQ2hhaW4oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5nZXRDaGFpbigpO1xuICB9XG4gIC8qKlxuICAgKiBWZXJpZnkgdGhhdCBhIHRyYW5zYWN0aW9uIHByZWJ1aWxkIGNvbXBsaWVzIHdpdGggdGhlIG9yaWdpbmFsIGludGVudGlvblxuICAgKiAgQSBwcmVidWlsZCB0cmFuc2FjdGlvbiBoYXMgdG8gYmUgcGFyc2VkIGNvcnJlY3RseSBhbmQgaW50ZW5kZWQgcmVjaXBpZW50cyBoYXMgdG8gYmVcbiAgICogIGluIHRoZSB0cmFuc2FjdGlvbiBvdXRwdXRcbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcy50eFByZWJ1aWxkIHByZWJ1aWxkIHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMudHhQYXJhbXMgdHJhbnNhY3Rpb24gcGFyYW1ldGVyc1xuICAgKiBAcmV0dXJuIHRydWUgaWYgdmVyaWZpY2F0aW9uIHN1Y2Nlc3NcbiAgICpcbiAgICovXG4gIGFzeW5jIHZlcmlmeVRyYW5zYWN0aW9uKHBhcmFtczogVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvaW5Db25maWcgPSBjb2lucy5nZXQodGhpcy5nZXRDaGFpbigpKTtcbiAgICAgIGNvbnN0IHsgdHhQcmVidWlsZDogdHhQcmVidWlsZCwgdHhQYXJhbXM6IHR4UGFyYW1zIH0gPSBwYXJhbXM7XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbihjb2luQ29uZmlnKTtcbiAgICAgIGFzc2VydCh0eFByZWJ1aWxkLnR4SGV4LCBuZXcgRXJyb3IoJ21pc3NpbmcgcmVxdWlyZWQgdHggcHJlYnVpbGQgcHJvcGVydHkgdHhIZXgnKSk7XG4gICAgICBjb25zdCByYXdUeCA9IHR4UHJlYnVpbGQudHhIZXg7XG5cbiAgICAgIHRyYW5zYWN0aW9uLmZyb21SYXdUcmFuc2FjdGlvbihyYXdUeCk7XG4gICAgICBjb25zdCBleHBsYWluZWRUeCA9IHRyYW5zYWN0aW9uLmV4cGxhaW5UcmFuc2FjdGlvbigpO1xuXG4gICAgICBpZiAodHhQYXJhbXMucmVjaXBpZW50cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGZvciAoY29uc3QgcmVjaXBpZW50IG9mIHR4UGFyYW1zLnJlY2lwaWVudHMpIHtcbiAgICAgICAgICBsZXQgZmluZCA9IGZhbHNlO1xuICAgICAgICAgIGZvciAoY29uc3Qgb3V0cHV0IG9mIGV4cGxhaW5lZFR4Lm91dHB1dHMpIHtcbiAgICAgICAgICAgIGlmIChyZWNpcGllbnQuYWRkcmVzcyA9PT0gb3V0cHV0LmFkZHJlc3MgJiYgcmVjaXBpZW50LmFtb3VudCA9PT0gb3V0cHV0LmFtb3VudCkge1xuICAgICAgICAgICAgICBmaW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFmaW5kKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBmaW5kIHJlY2lwaWVudCBpbiBleHBlY3RlZCBvdXRwdXQnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoZSBpbnN0YW5jZW9mIE5vZGVFbnZpcm9ubWVudEVycm9yKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBhc3luYyBpc1dhbGxldEFkZHJlc3MocGFyYW1zOiBWZXJpZnlBZGRyZXNzT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IHsgYWRkcmVzcyB9ID0gcGFyYW1zO1xuICAgIGlmICghdGhpcy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBZGRyZXNzRXJyb3IoYEludmFsaWQgQ2FyZGFubyBBZGRyZXNzOiAke2FkZHJlc3N9YCk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIGFzeW5jIHNpZ25NZXNzYWdlKGtleTogS2V5UGFpciwgbWVzc2FnZTogc3RyaW5nIHwgQnVmZmVyKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICBjb25zdCBhZGFLZXlwYWlyID0gbmV3IEFkYUtleVBhaXIoeyBwcnY6IGtleS5wcnYgfSk7XG4gICAgY29uc3QgbWVzc2FnZUhleCA9IG1lc3NhZ2UgaW5zdGFuY2VvZiBCdWZmZXIgPyBtZXNzYWdlLnRvU3RyaW5nKCdoZXgnKSA6IG1lc3NhZ2U7XG5cbiAgICByZXR1cm4gQnVmZmVyLmZyb20oYWRhS2V5cGFpci5zaWduTWVzc2FnZShtZXNzYWdlSGV4KSk7XG4gIH1cblxuICAvKipcbiAgICogRXhwbGFpbi9wYXJzZSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqL1xuICBhc3luYyBleHBsYWluVHJhbnNhY3Rpb24ocGFyYW1zOiBFeHBsYWluVHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxBZGFUcmFuc2FjdGlvbkV4cGxhbmF0aW9uPiB7XG4gICAgY29uc3QgZmFjdG9yeSA9IHRoaXMuZ2V0QnVpbGRlcigpO1xuICAgIGxldCByZWJ1aWx0VHJhbnNhY3Rpb246IEJhc2VUcmFuc2FjdGlvbjtcbiAgICBjb25zdCB0eFJhdyA9IHBhcmFtcy50eFByZWJ1aWxkLnR4SGV4O1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uQnVpbGRlciA9IGZhY3RvcnkuZnJvbSh0eFJhdyk7XG4gICAgICByZWJ1aWx0VHJhbnNhY3Rpb24gPSBhd2FpdCB0cmFuc2FjdGlvbkJ1aWxkZXIuYnVpbGQoKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCB0cmFuc2FjdGlvbicpO1xuICAgIH1cblxuICAgIHJldHVybiByZWJ1aWx0VHJhbnNhY3Rpb24uZXhwbGFpblRyYW5zYWN0aW9uKCk7XG4gIH1cblxuICBhc3luYyBwYXJzZVRyYW5zYWN0aW9uKHBhcmFtczogQWRhUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPFBhcnNlZFRyYW5zYWN0aW9uPiB7XG4gICAgY29uc3QgdHJhbnNhY3Rpb25FeHBsYW5hdGlvbiA9IGF3YWl0IHRoaXMuZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgIHR4UHJlYnVpbGQ6IHBhcmFtcy50eFByZWJ1aWxkLFxuICAgIH0pO1xuXG4gICAgaWYgKCF0cmFuc2FjdGlvbkV4cGxhbmF0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb24nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJhbnNhY3Rpb25FeHBsYW5hdGlvbiBhcyB1bmtub3duIGFzIFBhcnNlZFRyYW5zYWN0aW9uO1xuICB9XG5cbiAgZ2VuZXJhdGVLZXlQYWlyKHNlZWQ/OiBCdWZmZXIpOiBLZXlQYWlyIHtcbiAgICBjb25zdCBrZXlQYWlyID0gc2VlZCA/IG5ldyBBZGFLZXlQYWlyKHsgc2VlZCB9KSA6IG5ldyBBZGFLZXlQYWlyKCk7XG4gICAgY29uc3Qga2V5cyA9IGtleVBhaXIuZ2V0S2V5cygpO1xuICAgIGlmICgha2V5cy5wcnYpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBwcnYgaW4ga2V5IGdlbmVyYXRpb24uJyk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBwdWI6IGtleXMucHViLFxuICAgICAgcHJ2OiBrZXlzLnBydixcbiAgICB9O1xuICB9XG5cbiAgaXNWYWxpZFB1YihwdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBhZGFVdGlscy5pc1ZhbGlkUHVibGljS2V5KHB1Yik7XG4gIH1cblxuICBpc1ZhbGlkUHJ2KHBydjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGFkYVV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KHBydik7XG4gIH1cblxuICBpc1ZhbGlkQWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gYWRhVXRpbHMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzcyk7XG4gIH1cblxuICBhc3luYyBzaWduVHJhbnNhY3Rpb24ocGFyYW1zOiBTaWduVHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxTaWduZWRUcmFuc2FjdGlvbj4ge1xuICAgIGNvbnN0IGZhY3RvcnkgPSB0aGlzLmdldEJ1aWxkZXIoKTtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20ocGFyYW1zLnR4UHJlYnVpbGQudHhIZXgpO1xuICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBwYXJhbXMucHJ2IH0pO1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uOiBCYXNlVHJhbnNhY3Rpb24gPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcblxuICAgIGlmICghdHJhbnNhY3Rpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCB0cmFuc2FjdGlvbicpO1xuICAgIH1cblxuICAgIGNvbnN0IHNlcmlhbGl6ZWRUeCA9IHRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHhIZXg6IHNlcmlhbGl6ZWRUeCxcbiAgICB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldFB1YmxpY05vZGVVcmwoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gRW52aXJvbm1lbnRzW3RoaXMuYml0Z28uZ2V0RW52KCldLmFkYU5vZGVVcmw7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0RGF0YUZyb21Ob2RlKGVuZHBvaW50OiBzdHJpbmcsIHJlcXVlc3RCb2R5PzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBQcm9taXNlPHJlcXVlc3QuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXN0RW5kcG9pbnQgPSB0aGlzLmdldFB1YmxpY05vZGVVcmwoKSArICcvJyArIGVuZHBvaW50O1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCByZXF1ZXN0LnBvc3QocmVzdEVuZHBvaW50KS5zZW5kKHJlcXVlc3RCb2R5KTtcbiAgICAgIHJldHVybiByZXM7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5kZWJ1ZyhlKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gY2FsbCBlbmRwb2ludCAke3Jlc3RFbmRwb2ludH1gKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBnZXRBZGRyZXNzSW5mbyhcbiAgICB3YWxsZXRBZGRyOiBzdHJpbmdcbiAgKTogUHJvbWlzZTx7IGJhbGFuY2U6IG51bWJlcjsgdXR4b1NldDogQXJyYXk8UmVjb3JkPHN0cmluZywgYW55Pj4gfT4ge1xuICAgIGNvbnN0IHJlcXVlc3RCb2R5ID0geyBfYWRkcmVzc2VzOiBbd2FsbGV0QWRkcl0gfTtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmdldERhdGFGcm9tTm9kZSgnYWRkcmVzc19pbmZvJywgcmVxdWVzdEJvZHkpO1xuICAgIGlmIChyZXMuc3RhdHVzICE9IDIwMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gcmV0cmlldmUgYWRkcmVzcyBpbmZvIGZvciBhZGRyZXNzICR7d2FsbGV0QWRkcn1gKTtcbiAgICB9XG4gICAgY29uc3QgYm9keSA9IHJlcy5ib2R5WzBdO1xuICAgIGlmIChib2R5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB7IGJhbGFuY2U6IDAsIHV0eG9TZXQ6IFtdIH07XG4gICAgfVxuICAgIHJldHVybiB7IGJhbGFuY2U6IGJvZHkuYmFsYW5jZSwgdXR4b1NldDogYm9keS51dHhvX3NldCB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGdldENoYWluVGlwSW5mbygpOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHN0cmluZz4+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmdldERhdGFGcm9tTm9kZSgndGlwJyk7XG4gICAgaWYgKHJlcy5zdGF0dXMgIT0gMjAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byByZXRyaWV2ZSBjaGFpbiB0aXAgaW5mbycpO1xuICAgIH1cbiAgICBjb25zdCBib2R5ID0gcmVzLmJvZHlbMF07XG4gICAgcmV0dXJuIGJvZHk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIGEgZnVuZHMgcmVjb3ZlcnkgdHJhbnNhY3Rpb24gd2l0aG91dCBCaXRHb1xuICAgKlxuICAgKiBAcGFyYW0ge1JlY292ZXJ5T3B0aW9uc30gcGFyYW1zIHBhcmFtZXRlcnMgbmVlZGVkIHRvIGNvbnN0cnVjdCBhbmRcbiAgICogKG1heWJlKSBzaWduIHRoZSB0cmFuc2FjdGlvblxuICAgKlxuICAgKiBAcmV0dXJucyB7QWRhVHh9IHRoZSBzZXJpYWxpemVkIHRyYW5zYWN0aW9uIGhleCBzdHJpbmcgYW5kIGluZGV4XG4gICAqIG9mIHRoZSBhZGRyZXNzIGJlaW5nIHN3ZXB0XG4gICAqL1xuICBhc3luYyByZWNvdmVyKHBhcmFtczogUmVjb3ZlcnlPcHRpb25zKTogUHJvbWlzZTxBZGFUeD4ge1xuICAgIGlmICghcGFyYW1zLmJpdGdvS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgYml0Z29LZXknKTtcbiAgICB9XG4gICAgaWYgKCFwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiB8fCAhdGhpcy5pc1ZhbGlkQWRkcmVzcyhwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCByZWNvdmVyeURlc3RpbmF0aW9uJyk7XG4gICAgfVxuICAgIGxldCBhZGRyRm9ybWF0ID0gQWRkcmVzc0Zvcm1hdC50ZXN0bmV0O1xuICAgIGlmICh0aGlzLmdldENoYWluKCkgPT09ICdhZGEnKSB7XG4gICAgICBhZGRyRm9ybWF0ID0gQWRkcmVzc0Zvcm1hdC5tYWlubmV0O1xuICAgIH1cbiAgICBsZXQgc3RhcnRJZHggPSBwYXJhbXMuc3RhcnRpbmdTY2FuSW5kZXg7XG4gICAgaWYgKHN0YXJ0SWR4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHN0YXJ0SWR4ID0gMDtcbiAgICB9IGVsc2UgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHN0YXJ0SWR4KSB8fCBzdGFydElkeCA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdGFydGluZyBpbmRleCB0byBzY2FuIGZvciBhZGRyZXNzZXMnKTtcbiAgICB9XG4gICAgbGV0IG51bUl0ZXJhdGlvbiA9IHBhcmFtcy5zY2FuO1xuICAgIGlmIChudW1JdGVyYXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgbnVtSXRlcmF0aW9uID0gMjA7XG4gICAgfSBlbHNlIGlmICghTnVtYmVyLmlzSW50ZWdlcihudW1JdGVyYXRpb24pIHx8IG51bUl0ZXJhdGlvbiA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc2Nhbm5pbmcgZmFjdG9yJyk7XG4gICAgfVxuICAgIGNvbnN0IGJpdGdvS2V5ID0gcGFyYW1zLmJpdGdvS2V5LnJlcGxhY2UoL1xccy9nLCAnJyk7XG4gICAgY29uc3QgaXNVbnNpZ25lZFN3ZWVwID0gIXBhcmFtcy51c2VyS2V5ICYmICFwYXJhbXMuYmFja3VwS2V5ICYmICFwYXJhbXMud2FsbGV0UGFzc3BocmFzZTtcbiAgICBjb25zdCBNUEMgPSBhd2FpdCBFRERTQU1ldGhvZHMuZ2V0SW5pdGlhbGl6ZWRNcGNJbnN0YW5jZSgpO1xuICAgIGNvbnN0IHN0YWtlS2V5UGFpciA9IG5ldyBBZGFLZXlQYWlyKHsgcHViOiBNUEMuZGVyaXZlVW5oYXJkZW5lZChiaXRnb0tleSwgJ20vMCcpLnNsaWNlKDAsIDY0KSB9KTtcblxuICAgIGZvciAobGV0IGkgPSBzdGFydElkeDsgaSA8IG51bUl0ZXJhdGlvbiArIHN0YXJ0SWR4OyBpKyspIHtcbiAgICAgIGNvbnN0IGN1cnJQYXRoID0gYG0vJHtpfWA7XG4gICAgICBjb25zdCBhY2NvdW50SWQgPSBNUEMuZGVyaXZlVW5oYXJkZW5lZChiaXRnb0tleSwgY3VyclBhdGgpLnNsaWNlKDAsIDY0KTtcbiAgICAgIGNvbnN0IHBheW1lbnRLZXlQYWlyID0gbmV3IEFkYUtleVBhaXIoeyBwdWI6IGFjY291bnRJZCB9KTtcbiAgICAgIGNvbnN0IHNlbmRlckFkZHIgPSBVdGlscy5kZWZhdWx0LmNyZWF0ZUJhc2VBZGRyZXNzV2l0aFN0YWtlQW5kUGF5bWVudEtleShcbiAgICAgICAgc3Rha2VLZXlQYWlyLFxuICAgICAgICBwYXltZW50S2V5UGFpcixcbiAgICAgICAgYWRkckZvcm1hdFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHsgYmFsYW5jZSwgdXR4b1NldCB9ID0gYXdhaXQgdGhpcy5nZXRBZGRyZXNzSW5mbyhzZW5kZXJBZGRyKTtcbiAgICAgIGlmIChiYWxhbmNlIDw9IDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGZpcnN0IGJ1aWxkIHRoZSB1bnNpZ25lZCB0eG5cbiAgICAgIGNvbnN0IHRpcEFic1Nsb3QgPSBhd2FpdCB0aGlzLmdldENoYWluVGlwSW5mbygpO1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gdGhpcy5nZXRCdWlsZGVyKCkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICB0eEJ1aWxkZXIuY2hhbmdlQWRkcmVzcyhwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiwgYmFsYW5jZS50b1N0cmluZygpKTtcbiAgICAgIGZvciAoY29uc3QgdXR4byBvZiB1dHhvU2V0KSB7XG4gICAgICAgIHR4QnVpbGRlci5pbnB1dCh7IHRyYW5zYWN0aW9uX2lkOiB1dHhvLnR4X2hhc2gsIHRyYW5zYWN0aW9uX2luZGV4OiB1dHhvLnR4X2luZGV4IH0pO1xuICAgICAgfVxuICAgICAgLy8gZWFjaCBzbG90IGlzIGFib3V0IDEgc2Vjb25kLCBzbyB0aGlzIHRyYW5zYWN0aW9uIHNob3VsZCBiZSB2YWxpZCBmb3JcbiAgICAgIC8vIDcgKiA4Niw0MDAgc2Vjb25kcyAoNyBkYXlzKSBhZnRlciBjcmVhdGlvblxuICAgICAgdHhCdWlsZGVyLnR0bChOdW1iZXIodGlwQWJzU2xvdC5hYnNfc2xvdCkgKyA3ICogODY0MDApO1xuICAgICAgY29uc3QgdW5zaWduZWRUcmFuc2FjdGlvbiA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG5cbiAgICAgIGxldCBzZXJpYWxpemVkVHggPSB1bnNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBpZiAoIWlzVW5zaWduZWRTd2VlcCkge1xuICAgICAgICBpZiAoIXBhcmFtcy51c2VyS2V5KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHVzZXJLZXknKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXBhcmFtcy5iYWNrdXBLZXkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgYmFja3VwS2V5Jyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFwYXJhbXMud2FsbGV0UGFzc3BocmFzZSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyB3YWxsZXQgcGFzc3BocmFzZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2xlYW4gdXAgd2hpdGVzcGFjZSBmcm9tIGVudGVyZWQgdmFsdWVzXG4gICAgICAgIGNvbnN0IHVzZXJLZXkgPSBwYXJhbXMudXNlcktleS5yZXBsYWNlKC9cXHMvZywgJycpO1xuICAgICAgICBjb25zdCBiYWNrdXBLZXkgPSBwYXJhbXMuYmFja3VwS2V5LnJlcGxhY2UoL1xccy9nLCAnJyk7XG5cbiAgICAgICAgLy8gRGVjcnlwdCBwcml2YXRlIGtleXMgZnJvbSBLZXlDYXJkIHZhbHVlc1xuICAgICAgICBsZXQgdXNlclBydjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB1c2VyUHJ2ID0gdGhpcy5iaXRnby5kZWNyeXB0KHtcbiAgICAgICAgICAgIGlucHV0OiB1c2VyS2V5LFxuICAgICAgICAgICAgcGFzc3dvcmQ6IHBhcmFtcy53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFcnJvciBkZWNyeXB0aW5nIHVzZXIga2V5Y2hhaW46ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgICB9XG4gICAgICAgIC8qKiBUT0RPIEJHLTUyNDE5IEltcGxlbWVudCBDb2RlYyBmb3IgcGFyc2luZyAqL1xuICAgICAgICBjb25zdCB1c2VyU2lnbmluZ01hdGVyaWFsID0gSlNPTi5wYXJzZSh1c2VyUHJ2KSBhcyBFRERTQU1ldGhvZFR5cGVzLlVzZXJTaWduaW5nTWF0ZXJpYWw7XG5cbiAgICAgICAgbGV0IGJhY2t1cFBydjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBiYWNrdXBQcnYgPSB0aGlzLmJpdGdvLmRlY3J5cHQoe1xuICAgICAgICAgICAgaW5wdXQ6IGJhY2t1cEtleSxcbiAgICAgICAgICAgIHBhc3N3b3JkOiBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3IgZGVjcnlwdGluZyBiYWNrdXAga2V5Y2hhaW46ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJhY2t1cFNpZ25pbmdNYXRlcmlhbCA9IEpTT04ucGFyc2UoYmFja3VwUHJ2KSBhcyBFRERTQU1ldGhvZFR5cGVzLkJhY2t1cFNpZ25pbmdNYXRlcmlhbDtcblxuICAgICAgICAvLyBhZGQgc2lnbmF0dXJlXG4gICAgICAgIGNvbnN0IHNpZ25hdHVyZUhleCA9IGF3YWl0IEVERFNBTWV0aG9kcy5nZXRUU1NTaWduYXR1cmUoXG4gICAgICAgICAgdXNlclNpZ25pbmdNYXRlcmlhbCxcbiAgICAgICAgICBiYWNrdXBTaWduaW5nTWF0ZXJpYWwsXG4gICAgICAgICAgY3VyclBhdGgsXG4gICAgICAgICAgdW5zaWduZWRUcmFuc2FjdGlvblxuICAgICAgICApO1xuICAgICAgICBjb25zdCBhZGFLZXlQYWlyID0gbmV3IEFkYUtleVBhaXIoeyBwdWI6IGFjY291bnRJZCB9KTtcbiAgICAgICAgdHhCdWlsZGVyLmFkZFNpZ25hdHVyZSh7IHB1YjogYWRhS2V5UGFpci5nZXRLZXlzKCkucHViIH0sIHNpZ25hdHVyZUhleCk7XG4gICAgICAgIGNvbnN0IHNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIHNlcmlhbGl6ZWRUeCA9IHNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICB9XG4gICAgICByZXR1cm4geyBzZXJpYWxpemVkVHg6IHNlcmlhbGl6ZWRUeCwgc2NhbkluZGV4OiBpIH07XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcignRGlkIG5vdCBmaW5kIGFuIGFkZHJlc3Mgd2l0aCBmdW5kcyB0byByZWNvdmVyJyk7XG4gIH1cblxuICAvKiogaW5oZXJpdGVkIGRvYyAqL1xuICBzdXBwb3J0c1RzcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBpbmhlcml0ZWQgZG9jICovXG4gIGdldE1QQ0FsZ29yaXRobSgpOiBNUENBbGdvcml0aG0ge1xuICAgIHJldHVybiAnZWRkc2EnO1xuICB9XG5cbiAgLyoqIGluaGVyaXRlZCBkb2MgKi9cbiAgYWxsb3dzQWNjb3VudENvbnNvbGlkYXRpb25zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRCdWlsZGVyKCk6IFRyYW5zYWN0aW9uQnVpbGRlckZhY3Rvcnkge1xuICAgIHJldHVybiBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQodGhpcy5nZXRCYXNlQ2hhaW4oKSkpO1xuICB9XG59XG4iXX0=
589
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsbURBa0M4QjtBQUM5QiwrQkFBNkY7QUFDN0YsaURBQXFGO0FBQ3JGLHdEQUFtQztBQUNuQyxvREFBc0M7QUFDdEMsZ0VBQXFDO0FBQ3JDLHlEQUFrRjtBQUVyRSxRQUFBLG1CQUFtQixHQUFHLEVBQUUsQ0FBQyxDQUFDLHdEQUF3RDtBQW9DL0YsTUFBYSxHQUFJLFNBQVEsbUJBQVE7SUFFL0IsWUFBc0IsS0FBZ0IsRUFBRSxXQUF1QztRQUM3RSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDYixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFFRCxJQUFJLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQztJQUNsQyxDQUFDO0lBRUQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFnQixFQUFFLFdBQXVDO1FBQzdFLE9BQU8sSUFBSSxHQUFHLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7T0FFRztJQUNJLGFBQWE7UUFDbEIsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRU0sUUFBUTtRQUNiLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7SUFDaEMsQ0FBQztJQUVNLFNBQVM7UUFDZCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDO0lBQ2xDLENBQUM7SUFFTSxXQUFXO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUM7SUFDcEMsQ0FBQztJQUVELFlBQVk7UUFDVixPQUFPLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUN6QixDQUFD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UUFDakcsTUFBTSxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDO1FBQ2xDLE1BQU0sQ0FBQyxhQUFhLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQztJQUM5QyxDQUFDO0lBRUQsb0JBQW9CO0lBQ3BCLGlCQUFpQixDQUFDLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxZQUFZLEVBQTJCO1FBQ3pFLElBQUksWUFBWSxLQUFLLEtBQUssRUFBRSxDQUFDO1lBQzNCLE1BQU0sSUFBSSxLQUFLLENBQUMsMEJBQTBCLENBQUMsQ0FBQztRQUM5QyxDQUFDO1FBRUQsSUFBQSxrQ0FBb0IsRUFBQyxHQUFHLEVBQUUsU0FBUyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzdDLENBQUM7Q0FDRjtBQTVtQkQsa0JBNG1CQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7XG4gIEJhc2VDb2luLFxuICBCYXNlVHJhbnNhY3Rpb24sXG4gIEJpdEdvQmFzZSxcbiAgSW52YWxpZEFkZHJlc3NFcnJvcixcbiAgS2V5UGFpcixcbiAgTVBDQWxnb3JpdGhtLFxuICBOb2RlRW52aXJvbm1lbnRFcnJvcixcbiAgUGFyc2VkVHJhbnNhY3Rpb24sXG4gIFBhcnNlVHJhbnNhY3Rpb25PcHRpb25zIGFzIEJhc2VQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgU2lnbmVkVHJhbnNhY3Rpb24sXG4gIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMgYXMgQmFzZVNpZ25UcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFRyYW5zYWN0aW9uRXhwbGFuYXRpb24sXG4gIFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgRUREU0FNZXRob2RzLFxuICBFRERTQU1ldGhvZFR5cGVzLFxuICBBZGRyZXNzRm9ybWF0LFxuICBFbnZpcm9ubWVudHMsXG4gIElUcmFuc2FjdGlvblJlY2lwaWVudCxcbiAgTVBDVHgsXG4gIE1QQ1JlY292ZXJ5T3B0aW9ucyxcbiAgTVBDQ29uc29saWRhdGlvblJlY292ZXJ5T3B0aW9ucyxcbiAgTVBDU3dlZXBUeHMsXG4gIFJlY292ZXJ5VHhSZXF1ZXN0LFxuICBNUENVbnNpZ25lZFR4LFxuICBNUENTd2VlcFJlY292ZXJ5T3B0aW9ucyxcbiAgTVBDVHhzLFxuICBQb3B1bGF0ZWRJbnRlbnQsXG4gIFByZWJ1aWxkVHJhbnNhY3Rpb25XaXRoSW50ZW50T3B0aW9ucyxcbiAgTXVsdGlzaWdUeXBlLFxuICBtdWx0aXNpZ1R5cGVzLFxuICBBdWRpdERlY3J5cHRlZEtleVBhcmFtcyxcbiAgZXh0cmFjdENvbW1vbktleWNoYWluLFxuICBUc3NWZXJpZnlBZGRyZXNzT3B0aW9ucyxcbn0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgS2V5UGFpciBhcyBBZGFLZXlQYWlyLCBUcmFuc2FjdGlvbiwgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSwgVXRpbHMgfSBmcm9tICcuL2xpYic7XG5pbXBvcnQgeyBCYXNlQ29pbiBhcyBTdGF0aWNzQmFzZUNvaW4sIENvaW5GYW1pbHksIGNvaW5zIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQgYWRhVXRpbHMgZnJvbSAnLi9saWIvdXRpbHMnO1xuaW1wb3J0ICogYXMgcmVxdWVzdCBmcm9tICdzdXBlcmFnZW50JztcbmltcG9ydCBCaWdOdW1iZXIgZnJvbSAnYmlnbnVtYmVyLmpzJztcbmltcG9ydCB7IGF1ZGl0RWRkc2FQcml2YXRlS2V5LCBnZXREZXJpdmF0aW9uUGF0aCB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1saWItbXBjJztcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfU0NBTl9GQUNUT1IgPSAyMDsgLy8gZGVmYXVsdCBudW1iZXIgb2YgcmVjZWl2ZSBhZGRyZXNzZXMgdG8gc2NhbiBmb3IgZnVuZHNcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2FjdGlvblByZWJ1aWxkIHtcbiAgdHhIZXg6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBZGFUeEluZm8ge1xuICBmZWVBZGRyZXNzPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV4cGxhaW5UcmFuc2FjdGlvbk9wdGlvbnMge1xuICB0eFByZWJ1aWxkOiBUcmFuc2FjdGlvblByZWJ1aWxkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFkYVBhcnNlVHJhbnNhY3Rpb25PcHRpb25zIGV4dGVuZHMgQmFzZVBhcnNlVHJhbnNhY3Rpb25PcHRpb25zIHtcbiAgdHhQcmVidWlsZDogVHJhbnNhY3Rpb25QcmVidWlsZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTaWduVHJhbnNhY3Rpb25PcHRpb25zIGV4dGVuZHMgQmFzZVNpZ25UcmFuc2FjdGlvbk9wdGlvbnMge1xuICB0eFByZWJ1aWxkOiBUcmFuc2FjdGlvblByZWJ1aWxkO1xuICBwcnY6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIEFkYUFkZHJlc3NQYXJhbXMge1xuICBiaXRnb0tleTogc3RyaW5nO1xuICBpbmRleDogbnVtYmVyO1xuICBzZWVkPzogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgQWRhQWRkcmVzc0FuZEFjY291bnRJZCB7XG4gIGFkZHJlc3M6IHN0cmluZztcbiAgYWNjb3VudElkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCB0eXBlIEFkYVRyYW5zYWN0aW9uRXhwbGFuYXRpb24gPSBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uO1xuXG5leHBvcnQgY2xhc3MgQWRhIGV4dGVuZHMgQmFzZUNvaW4ge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgX3N0YXRpY3NDb2luOiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+O1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoYml0Z286IEJpdEdvQmFzZSwgc3RhdGljc0NvaW4/OiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+KSB7XG4gICAgc3VwZXIoYml0Z28pO1xuICAgIGlmICghc3RhdGljc0NvaW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCBjb25zdHJ1Y3RvciBwYXJhbWV0ZXIgc3RhdGljc0NvaW4nKTtcbiAgICB9XG5cbiAgICB0aGlzLl9zdGF0aWNzQ29pbiA9IHN0YXRpY3NDb2luO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUluc3RhbmNlKGJpdGdvOiBCaXRHb0Jhc2UsIHN0YXRpY3NDb2luPzogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPik6IEJhc2VDb2luIHtcbiAgICByZXR1cm4gbmV3IEFkYShiaXRnbywgc3RhdGljc0NvaW4pO1xuICB9XG5cbiAgLyoqXG4gICAqIEZhY3RvciBiZXR3ZWVuIHRoZSBjb2luJ3MgYmFzZSB1bml0IGFuZCBpdHMgc21hbGxlc3Qgc3ViZGl2aXNvblxuICAgKi9cbiAgcHVibGljIGdldEJhc2VGYWN0b3IoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gMWU2O1xuICB9XG5cbiAgcHVibGljIGdldENoYWluKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLm5hbWU7XG4gIH1cblxuICBwdWJsaWMgZ2V0RmFtaWx5KCk6IENvaW5GYW1pbHkge1xuICAgIHJldHVybiB0aGlzLl9zdGF0aWNzQ29pbi5mYW1pbHk7XG4gIH1cblxuICBwdWJsaWMgZ2V0RnVsbE5hbWUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGljc0NvaW4uZnVsbE5hbWU7XG4gIH1cblxuICBnZXRCYXNlQ2hhaW4oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5nZXRDaGFpbigpO1xuICB9XG4gIC8qKlxuICAgKiBWZXJpZnkgdGhhdCBhIHRyYW5zYWN0aW9uIHByZWJ1aWxkIGNvbXBsaWVzIHdpdGggdGhlIG9yaWdpbmFsIGludGVudGlvblxuICAgKiAgQSBwcmVidWlsZCB0cmFuc2FjdGlvbiBoYXMgdG8gYmUgcGFyc2VkIGNvcnJlY3RseSBhbmQgaW50ZW5kZWQgcmVjaXBpZW50cyBoYXMgdG8gYmVcbiAgICogIGluIHRoZSB0cmFuc2FjdGlvbiBvdXRwdXRcbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcy50eFByZWJ1aWxkIHByZWJ1aWxkIHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMudHhQYXJhbXMgdHJhbnNhY3Rpb24gcGFyYW1ldGVyc1xuICAgKiBAcmV0dXJuIHRydWUgaWYgdmVyaWZpY2F0aW9uIHN1Y2Nlc3NcbiAgICpcbiAgICovXG4gIGFzeW5jIHZlcmlmeVRyYW5zYWN0aW9uKHBhcmFtczogVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvaW5Db25maWcgPSBjb2lucy5nZXQodGhpcy5nZXRDaGFpbigpKTtcbiAgICAgIGNvbnN0IHsgdHhQcmVidWlsZDogdHhQcmVidWlsZCwgdHhQYXJhbXM6IHR4UGFyYW1zLCB2ZXJpZmljYXRpb24sIHdhbGxldCB9ID0gcGFyYW1zO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSBuZXcgVHJhbnNhY3Rpb24oY29pbkNvbmZpZyk7XG4gICAgICBhc3NlcnQodHhQcmVidWlsZC50eEhleCwgbmV3IEVycm9yKCdtaXNzaW5nIHJlcXVpcmVkIHR4IHByZWJ1aWxkIHByb3BlcnR5IHR4SGV4JykpO1xuICAgICAgY29uc3QgcmF3VHggPSB0eFByZWJ1aWxkLnR4SGV4O1xuXG4gICAgICB0cmFuc2FjdGlvbi5mcm9tUmF3VHJhbnNhY3Rpb24ocmF3VHgpO1xuICAgICAgY29uc3QgZXhwbGFpbmVkVHggPSB0cmFuc2FjdGlvbi5leHBsYWluVHJhbnNhY3Rpb24oKTtcblxuICAgICAgaWYgKHR4UGFyYW1zLnJlY2lwaWVudHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBmb3IgKGNvbnN0IHJlY2lwaWVudCBvZiB0eFBhcmFtcy5yZWNpcGllbnRzKSB7XG4gICAgICAgICAgbGV0IGZpbmQgPSBmYWxzZTtcbiAgICAgICAgICBmb3IgKGNvbnN0IG91dHB1dCBvZiBleHBsYWluZWRUeC5vdXRwdXRzKSB7XG4gICAgICAgICAgICBpZiAocmVjaXBpZW50LmFkZHJlc3MgPT09IG91dHB1dC5hZGRyZXNzICYmIHJlY2lwaWVudC5hbW91bnQgPT09IG91dHB1dC5hbW91bnQpIHtcbiAgICAgICAgICAgICAgZmluZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghZmluZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjYW5ub3QgZmluZCByZWNpcGllbnQgaW4gZXhwZWN0ZWQgb3V0cHV0Jyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHZlcmlmaWNhdGlvbj8uY29uc29saWRhdGlvblRvQmFzZUFkZHJlc3MpIHtcbiAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSB3YWxsZXQuY29pblNwZWNpZmljKCk/LmJhc2VBZGRyZXNzIHx8IHdhbGxldC5jb2luU3BlY2lmaWMoKT8ucm9vdEFkZHJlc3M7XG4gICAgICAgIGNvbnN0IGZlZUFkZHJlc3MgPSAodHhQcmVidWlsZC50eEluZm8gYXMgQWRhVHhJbmZvKT8uZmVlQWRkcmVzcztcblxuICAgICAgICBmb3IgKGNvbnN0IG91dHB1dCBvZiBleHBsYWluZWRUeC5vdXRwdXRzKSB7XG4gICAgICAgICAgaWYgKG91dHB1dC5hZGRyZXNzICE9PSBiYXNlQWRkcmVzcyAmJiBvdXRwdXQuYWRkcmVzcyAhPT0gZmVlQWRkcmVzcykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0eCBvdXRwdXRzIGRvZXMgbm90IG1hdGNoIHdpdGggZXhwZWN0ZWQgYWRkcmVzcycpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChlIGluc3RhbmNlb2YgTm9kZUVudmlyb25tZW50RXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGFzeW5jIGlzV2FsbGV0QWRkcmVzcyhwYXJhbXM6IFRzc1ZlcmlmeUFkZHJlc3NPcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgeyBhZGRyZXNzLCBrZXljaGFpbnMsIGluZGV4IH0gPSBwYXJhbXM7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFkZHJlc3NFcnJvcihgSW52YWxpZCBDYXJkYW5vIEFkZHJlc3M6ICR7YWRkcmVzc31gKTtcbiAgICB9XG5cbiAgICBjb25zdCBpbmRleE51bWJlciA9IE51bWJlcihpbmRleCk7XG4gICAgaWYgKGlzTmFOKGluZGV4TnVtYmVyKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGluZGV4LiBpbmRleCBtdXN0IGJlIGEgbnVtYmVyLicpO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbW1vbktleWNoYWluID0gZXh0cmFjdENvbW1vbktleWNoYWluKGtleWNoYWlucyk7XG4gICAgY29uc3QgZGVyaXZhdGlvblNlZWQgPSAoa2V5Y2hhaW5zWzBdIGFzIHsgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZD86IHN0cmluZyB9KT8uZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZDtcbiAgICBjb25zdCB7IGFkZHJlc3M6IGRlcml2ZWRBZGRyZXNzIH0gPSBhd2FpdCB0aGlzLmdldEFkYUFkZHJlc3NBbmRBY2NvdW50SWQoe1xuICAgICAgYml0Z29LZXk6IGNvbW1vbktleWNoYWluLFxuICAgICAgaW5kZXg6IGluZGV4TnVtYmVyLFxuICAgICAgc2VlZDogZGVyaXZhdGlvblNlZWQsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gYWRkcmVzcyA9PT0gZGVyaXZlZEFkZHJlc3M7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKi9cbiAgYXN5bmMgc2lnbk1lc3NhZ2Uoa2V5OiBLZXlQYWlyLCBtZXNzYWdlOiBzdHJpbmcgfCBCdWZmZXIpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICAgIGNvbnN0IGFkYUtleXBhaXIgPSBuZXcgQWRhS2V5UGFpcih7IHBydjoga2V5LnBydiB9KTtcbiAgICBjb25zdCBtZXNzYWdlSGV4ID0gdHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnID8gbWVzc2FnZSA6IG1lc3NhZ2UudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGFkYUtleXBhaXIuc2lnbk1lc3NhZ2UobWVzc2FnZUhleCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGxhaW4vcGFyc2UgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgZXhwbGFpblRyYW5zYWN0aW9uKHBhcmFtczogRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8QWRhVHJhbnNhY3Rpb25FeHBsYW5hdGlvbj4ge1xuICAgIGNvbnN0IGZhY3RvcnkgPSB0aGlzLmdldEJ1aWxkZXIoKTtcbiAgICBsZXQgcmVidWlsdFRyYW5zYWN0aW9uOiBCYXNlVHJhbnNhY3Rpb247XG4gICAgY29uc3QgdHhSYXcgPSBwYXJhbXMudHhQcmVidWlsZC50eEhleDtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbkJ1aWxkZXIgPSBmYWN0b3J5LmZyb20odHhSYXcpO1xuICAgICAgcmVidWlsdFRyYW5zYWN0aW9uID0gYXdhaXQgdHJhbnNhY3Rpb25CdWlsZGVyLmJ1aWxkKCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb24nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVidWlsdFRyYW5zYWN0aW9uLmV4cGxhaW5UcmFuc2FjdGlvbigpO1xuICB9XG5cbiAgYXN5bmMgcGFyc2VUcmFuc2FjdGlvbihwYXJhbXM6IEFkYVBhcnNlVHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxQYXJzZWRUcmFuc2FjdGlvbj4ge1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uRXhwbGFuYXRpb24gPSBhd2FpdCB0aGlzLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICB0eFByZWJ1aWxkOiBwYXJhbXMudHhQcmVidWlsZCxcbiAgICB9KTtcblxuICAgIGlmICghdHJhbnNhY3Rpb25FeHBsYW5hdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRyYW5zYWN0aW9uRXhwbGFuYXRpb24gYXMgdW5rbm93biBhcyBQYXJzZWRUcmFuc2FjdGlvbjtcbiAgfVxuXG4gIGdlbmVyYXRlS2V5UGFpcihzZWVkPzogQnVmZmVyKTogS2V5UGFpciB7XG4gICAgY29uc3Qga2V5UGFpciA9IHNlZWQgPyBuZXcgQWRhS2V5UGFpcih7IHNlZWQgfSkgOiBuZXcgQWRhS2V5UGFpcigpO1xuICAgIGNvbnN0IGtleXMgPSBrZXlQYWlyLmdldEtleXMoKTtcbiAgICBpZiAoIWtleXMucHJ2KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgcHJ2IGluIGtleSBnZW5lcmF0aW9uLicpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgcHViOiBrZXlzLnB1YixcbiAgICAgIHBydjoga2V5cy5wcnYsXG4gICAgfTtcbiAgfVxuXG4gIGlzVmFsaWRQdWIocHViOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gYWRhVXRpbHMuaXNWYWxpZFB1YmxpY0tleShwdWIpO1xuICB9XG5cbiAgaXNWYWxpZFBydihwcnY6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBhZGFVdGlscy5pc1ZhbGlkUHJpdmF0ZUtleShwcnYpO1xuICB9XG5cbiAgaXNWYWxpZEFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGFkYVV0aWxzLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpO1xuICB9XG5cbiAgYXN5bmMgc2lnblRyYW5zYWN0aW9uKHBhcmFtczogU2lnblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8U2lnbmVkVHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCBmYWN0b3J5ID0gdGhpcy5nZXRCdWlsZGVyKCk7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5mcm9tKHBhcmFtcy50eFByZWJ1aWxkLnR4SGV4KTtcbiAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogcGFyYW1zLnBydiB9KTtcbiAgICBjb25zdCB0cmFuc2FjdGlvbjogQmFzZVRyYW5zYWN0aW9uID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG5cbiAgICBpZiAoIXRyYW5zYWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb24nKTtcbiAgICB9XG5cbiAgICBjb25zdCBzZXJpYWxpemVkVHggPSB0cmFuc2FjdGlvbi50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR4SGV4OiBzZXJpYWxpemVkVHgsXG4gICAgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRQdWJsaWNOb2RlVXJsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIEVudmlyb25tZW50c1t0aGlzLmJpdGdvLmdldEVudigpXS5hZGFOb2RlVXJsO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGdldERhdGFGcm9tTm9kZShlbmRwb2ludDogc3RyaW5nLCByZXF1ZXN0Qm9keT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogUHJvbWlzZTxyZXF1ZXN0LlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVzdEVuZHBvaW50ID0gdGhpcy5nZXRQdWJsaWNOb2RlVXJsKCkgKyAnLycgKyBlbmRwb2ludDtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgcmVxdWVzdC5wb3N0KHJlc3RFbmRwb2ludCkuc2VuZChyZXF1ZXN0Qm9keSk7XG4gICAgICByZXR1cm4gcmVzO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUuZGVidWcoZSk7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGNhbGwgZW5kcG9pbnQgJHtyZXN0RW5kcG9pbnR9YCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0QWRkcmVzc0luZm8oXG4gICAgd2FsbGV0QWRkcjogc3RyaW5nXG4gICk6IFByb21pc2U8eyBiYWxhbmNlOiBudW1iZXI7IHV0eG9TZXQ6IEFycmF5PFJlY29yZDxzdHJpbmcsIGFueT4+IH0+IHtcbiAgICBjb25zdCByZXF1ZXN0Qm9keSA9IHsgX2FkZHJlc3NlczogW3dhbGxldEFkZHJdIH07XG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5nZXREYXRhRnJvbU5vZGUoJ2FkZHJlc3NfaW5mbycsIHJlcXVlc3RCb2R5KTtcbiAgICBpZiAocmVzLnN0YXR1cyAhPSAyMDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIHJldHJpZXZlIGFkZHJlc3MgaW5mbyBmb3IgYWRkcmVzcyAke3dhbGxldEFkZHJ9YCk7XG4gICAgfVxuICAgIGNvbnN0IGJvZHkgPSByZXMuYm9keVswXTtcbiAgICBpZiAoYm9keSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4geyBiYWxhbmNlOiAwLCB1dHhvU2V0OiBbXSB9O1xuICAgIH1cbiAgICByZXR1cm4geyBiYWxhbmNlOiBib2R5LmJhbGFuY2UsIHV0eG9TZXQ6IGJvZHkudXR4b19zZXQgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBnZXRDaGFpblRpcEluZm8oKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5nZXREYXRhRnJvbU5vZGUoJ3RpcCcpO1xuICAgIGlmIChyZXMuc3RhdHVzICE9IDIwMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gcmV0cmlldmUgY2hhaW4gdGlwIGluZm8nKTtcbiAgICB9XG4gICAgY29uc3QgYm9keSA9IHJlcy5ib2R5WzBdO1xuICAgIHJldHVybiBib2R5O1xuICB9XG5cbiAgLyoqIGluaGVyaXRlZCBkb2MgKi9cbiAgYXN5bmMgY3JlYXRlQnJvYWRjYXN0YWJsZVN3ZWVwVHJhbnNhY3Rpb24ocGFyYW1zOiBNUENTd2VlcFJlY292ZXJ5T3B0aW9ucyk6IFByb21pc2U8TVBDVHhzPiB7XG4gICAgY29uc3QgcmVxID0gcGFyYW1zLnNpZ25hdHVyZVNoYXJlcztcbiAgICBjb25zdCBicm9hZGNhc3RhYmxlVHJhbnNhY3Rpb25zOiBNUENUeFtdID0gW107XG4gICAgbGV0IGxhc3RTY2FuSW5kZXggPSAwO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IE1QQyA9IGF3YWl0IEVERFNBTWV0aG9kcy5nZXRJbml0aWFsaXplZE1wY0luc3RhbmNlKCk7XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHJlcVtpXS50eFJlcXVlc3QudHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHg7XG4gICAgICBpZiAoIXJlcVtpXS5vdmMgfHwgIXJlcVtpXS5vdmNbMF0uZWRkc2FTaWduYXR1cmUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHNpZ25hdHVyZShzKScpO1xuICAgICAgfVxuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gcmVxW2ldLm92Y1swXS5lZGRzYVNpZ25hdHVyZTtcbiAgICAgIGlmICghdHJhbnNhY3Rpb24uc2lnbmFibGVIZXgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHNpZ25hYmxlIGhleCcpO1xuICAgICAgfVxuICAgICAgY29uc3QgbWVzc2FnZUJ1ZmZlciA9IEJ1ZmZlci5mcm9tKHRyYW5zYWN0aW9uLnNpZ25hYmxlSGV4ISwgJ2hleCcpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gTVBDLnZlcmlmeShtZXNzYWdlQnVmZmVyLCBzaWduYXR1cmUpO1xuICAgICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNpZ25hdHVyZScpO1xuICAgICAgfVxuICAgICAgY29uc3Qgc2lnbmF0dXJlSGV4ID0gQnVmZmVyLmNvbmNhdChbQnVmZmVyLmZyb20oc2lnbmF0dXJlLlIsICdoZXgnKSwgQnVmZmVyLmZyb20oc2lnbmF0dXJlLnNpZ21hLCAnaGV4JyldKTtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IHRoaXMuZ2V0QnVpbGRlcigpLmZyb20odHJhbnNhY3Rpb24uc2VyaWFsaXplZFR4IGFzIHN0cmluZyk7XG4gICAgICBpZiAoIXRyYW5zYWN0aW9uLmNvaW5TcGVjaWZpYz8uY29tbW9uS2V5Y2hhaW4pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIGNvbW1vbiBrZXljaGFpbicpO1xuICAgICAgfVxuICAgICAgY29uc3QgY29tbW9uS2V5Y2hhaW4gPSB0cmFuc2FjdGlvbi5jb2luU3BlY2lmaWMhLmNvbW1vbktleWNoYWluISBhcyBzdHJpbmc7XG4gICAgICBpZiAoIXRyYW5zYWN0aW9uLmRlcml2YXRpb25QYXRoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBkZXJpdmF0aW9uIHBhdGgnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRlcml2YXRpb25QYXRoID0gdHJhbnNhY3Rpb24uZGVyaXZhdGlvblBhdGggYXMgc3RyaW5nO1xuICAgICAgY29uc3QgYWNjb3VudElkID0gTVBDLmRlcml2ZVVuaGFyZGVuZWQoY29tbW9uS2V5Y2hhaW4sIGRlcml2YXRpb25QYXRoKS5zbGljZSgwLCA2NCk7XG4gICAgICBjb25zdCBhZGFLZXlQYWlyID0gbmV3IEFkYUtleVBhaXIoeyBwdWI6IGFjY291bnRJZCB9KTtcblxuICAgICAgLy8gYWRkIGNvbWJpbmVkIHNpZ25hdHVyZSBmcm9tIG92Y1xuICAgICAgdHhCdWlsZGVyLmFkZFNpZ25hdHVyZSh7IHB1YjogYWRhS2V5UGFpci5nZXRLZXlzKCkucHViIH0sIHNpZ25hdHVyZUhleCk7XG4gICAgICBjb25zdCBzaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3Qgc2VyaWFsaXplZFR4ID0gc2lnbmVkVHJhbnNhY3Rpb24udG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgYnJvYWRjYXN0YWJsZVRyYW5zYWN0aW9ucy5wdXNoKHtcbiAgICAgICAgc2VyaWFsaXplZFR4OiBzZXJpYWxpemVkVHgsXG4gICAgICAgIHNjYW5JbmRleDogdHJhbnNhY3Rpb24uc2NhbkluZGV4LFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChpID09PSByZXEubGVuZ3RoIC0gMSAmJiB0cmFuc2FjdGlvbi5jb2luU3BlY2lmaWMhLmxhc3RTY2FuSW5kZXgpIHtcbiAgICAgICAgbGFzdFNjYW5JbmRleCA9IHRyYW5zYWN0aW9uLmNvaW5TcGVjaWZpYyEubGFzdFNjYW5JbmRleCBhcyBudW1iZXI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdHJhbnNhY3Rpb25zOiBicm9hZGNhc3RhYmxlVHJhbnNhY3Rpb25zLCBsYXN0U2NhbkluZGV4IH07XG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIGZ1bmRzIHJlY292ZXJ5IHRyYW5zYWN0aW9uKHMpIHdpdGhvdXQgQml0R29cbiAgICpcbiAgICogQHBhcmFtIHtNUENSZWNvdmVyeU9wdGlvbnN9IHBhcmFtcyBwYXJhbWV0ZXJzIG5lZWRlZCB0byBjb25zdHJ1Y3QgYW5kXG4gICAqIChtYXliZSkgc2lnbiB0aGUgdHJhbnNhY3Rpb25cbiAgICpcbiAgICogQHJldHVybnMge01QQ1R4IHwgTVBDU3dlZXBUeHN9IGFycmF5IG9mIHRoZSBzZXJpYWxpemVkIHRyYW5zYWN0aW9uIGhleCBzdHJpbmdzIGFuZCBpbmRpY2VzXG4gICAqIG9mIHRoZSBhZGRyZXNzZXMgYmVpbmcgc3dlcHRcbiAgICovXG4gIGFzeW5jIHJlY292ZXIocGFyYW1zOiBNUENSZWNvdmVyeU9wdGlvbnMpOiBQcm9taXNlPE1QQ1R4IHwgTVBDU3dlZXBUeHM+IHtcbiAgICBpZiAoIXBhcmFtcy5iaXRnb0tleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGJpdGdvS2V5Jyk7XG4gICAgfVxuICAgIGlmICghcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24gfHwgIXRoaXMuaXNWYWxpZEFkZHJlc3MocGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgcmVjb3ZlcnlEZXN0aW5hdGlvbicpO1xuICAgIH1cblxuICAgIGNvbnN0IGluZGV4ID0gcGFyYW1zLmluZGV4IHx8IDA7XG4gICAgY29uc3QgY3VyclBhdGggPSBwYXJhbXMuc2VlZCA/IGdldERlcml2YXRpb25QYXRoKHBhcmFtcy5zZWVkKSArIGAvJHtpbmRleH1gIDogYG0vJHtpbmRleH1gO1xuICAgIGNvbnN0IGJpdGdvS2V5ID0gcGFyYW1zLmJpdGdvS2V5LnJlcGxhY2UoL1xccy9nLCAnJyk7XG5cbiAgICBjb25zdCBhZGRyZXNzUGFyYW1zID0ge1xuICAgICAgYml0Z29LZXk6IHBhcmFtcy5iaXRnb0tleSxcbiAgICAgIGluZGV4OiBpbmRleCxcbiAgICAgIHNlZWQ6IHBhcmFtcy5zZWVkLFxuICAgIH07XG4gICAgY29uc3QgeyBhZGRyZXNzOiBzZW5kZXJBZGRyLCBhY2NvdW50SWQgfSA9IGF3YWl0IHRoaXMuZ2V0QWRhQWRkcmVzc0FuZEFjY291bnRJZChhZGRyZXNzUGFyYW1zKTtcbiAgICBjb25zdCBpc1Vuc2lnbmVkU3dlZXAgPSAhcGFyYW1zLndhbGxldFBhc3NwaHJhc2U7XG4gICAgY29uc3QgeyBiYWxhbmNlLCB1dHhvU2V0IH0gPSBhd2FpdCB0aGlzLmdldEFkZHJlc3NJbmZvKHNlbmRlckFkZHIpO1xuICAgIGlmIChiYWxhbmNlIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRGlkIG5vdCBmaW5kIGFkZHJlc3Mgd2l0aCBmdW5kcyB0byByZWNvdmVyLicpO1xuICAgIH1cblxuICAgIC8vIEFnZ3JlZ2F0ZSB0b2tlbiBhc3NldHMgZnJvbSBhbGwgVVR4T3MgaW50byBhIGZpbmdlcnByaW50LWtleWVkIG1hcCBmb3IgdGhlIGJ1aWxkZXJcbiAgICBjb25zdCBhZ2dyZWdhdGVkQXNzZXRMaXN0OiBSZWNvcmQ8c3RyaW5nLCB7IHBvbGljeV9pZDogc3RyaW5nOyBhc3NldF9uYW1lOiBzdHJpbmc7IHF1YW50aXR5OiBzdHJpbmcgfT4gPSB7fTtcbiAgICBmb3IgKGNvbnN0IHV0eG8gb2YgdXR4b1NldCkge1xuICAgICAgZm9yIChjb25zdCBhc3NldCBvZiB1dHhvLmFzc2V0X2xpc3QgPz8gW10pIHtcbiAgICAgICAgY29uc3QgZnAgPSBhc3NldC5maW5nZXJwcmludCBhcyBzdHJpbmc7XG4gICAgICAgIGlmIChhZ2dyZWdhdGVkQXNzZXRMaXN0W2ZwXSkge1xuICAgICAgICAgIGFnZ3JlZ2F0ZWRBc3NldExpc3RbZnBdLnF1YW50aXR5ID0gKFxuICAgICAgICAgICAgQmlnSW50KGFnZ3JlZ2F0ZWRBc3NldExpc3RbZnBdLnF1YW50aXR5KSArIEJpZ0ludChhc3NldC5xdWFudGl0eSlcbiAgICAgICAgICApLnRvU3RyaW5nKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYWdncmVnYXRlZEFzc2V0TGlzdFtmcF0gPSB7XG4gICAgICAgICAgICBwb2xpY3lfaWQ6IGFzc2V0LnBvbGljeV9pZCxcbiAgICAgICAgICAgIGFzc2V0X25hbWU6IGFzc2V0LmVuY29kZWRfYXNzZXRfbmFtZSA/PyBhc3NldC5hc3NldF9uYW1lLFxuICAgICAgICAgICAgcXVhbnRpdHk6IGFzc2V0LnF1YW50aXR5LFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBmaXJzdCBidWlsZCB0aGUgdW5zaWduZWQgdHhuXG4gICAgY29uc3QgdGlwQWJzU2xvdCA9IGF3YWl0IHRoaXMuZ2V0Q2hhaW5UaXBJbmZvKCk7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gdGhpcy5nZXRCdWlsZGVyKCkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgdHhCdWlsZGVyLmNoYW5nZUFkZHJlc3MocGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sIGJhbGFuY2UudG9TdHJpbmcoKSwgYWdncmVnYXRlZEFzc2V0TGlzdCk7XG4gICAgaWYgKE9iamVjdC5rZXlzKGFnZ3JlZ2F0ZWRBc3NldExpc3QpLmxlbmd0aCA+IDApIHtcbiAgICAgIHR4QnVpbGRlci5pc1Rva2VuVHJhbnNhY3Rpb24oKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCB1dHhvIG9mIHV0eG9TZXQpIHtcbiAgICAgIHR4QnVpbGRlci5pbnB1dCh7IHRyYW5zYWN0aW9uX2lkOiB1dHhvLnR4X2hhc2gsIHRyYW5zYWN0aW9uX2luZGV4OiB1dHhvLnR4X2luZGV4IH0pO1xuICAgIH1cbiAgICAvLyBlYWNoIHNsb3QgaXMgYWJvdXQgMSBzZWNvbmQsIHNvIHRoaXMgdHJhbnNhY3Rpb24gc2hvdWxkIGJlIHZhbGlkIGZvclxuICAgIC8vIDcgKiA4Niw0MDAgc2Vjb25kcyAoNyBkYXlzKSBhZnRlciBjcmVhdGlvblxuICAgIHR4QnVpbGRlci50dGwoTnVtYmVyKHRpcEFic1Nsb3QuYWJzX3Nsb3QpICsgNyAqIDg2NDAwKTtcbiAgICBjb25zdCB1bnNpZ25lZFRyYW5zYWN0aW9uID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcblxuICAgIC8vIHN1bSB1cCBldmVyeSBvdXRwdXRcbiAgICBjb25zdCBhbW91bnQgPSB1bnNpZ25lZFRyYW5zYWN0aW9uXG4gICAgICAudG9Kc29uKClcbiAgICAgIC5vdXRwdXRzLnJlZHVjZShcbiAgICAgICAgKGFjYzogQmlnTnVtYmVyLCBvdXRwdXQ6IHsgYW1vdW50OiBzdHJpbmcgfSkgPT4gbmV3IEJpZ051bWJlcihhY2MpLnBsdXMob3V0cHV0LmFtb3VudCksXG4gICAgICAgIG5ldyBCaWdOdW1iZXIoMClcbiAgICAgICk7XG5cbiAgICBpZiAoYW1vdW50LmlzTGVzc1RoYW4oMTAwMDAwMCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0luc3VmZmljaWVudCBmdW5kcyB0byByZWNvdmVyLCBtaW5pbXVtIHJlcXVpcmVkIGlzIDEgQURBIHBsdXMgZmVlcywgZ290ICcgK1xuICAgICAgICAgIGFtb3VudC50b1N0cmluZygpICtcbiAgICAgICAgICAnIGZlZXM6ICcgK1xuICAgICAgICAgIHVuc2lnbmVkVHJhbnNhY3Rpb24uZ2V0RmVlXG4gICAgICApO1xuICAgIH1cblxuICAgIGxldCBzZXJpYWxpemVkVHggPSB1bnNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgaWYgKCFpc1Vuc2lnbmVkU3dlZXApIHtcbiAgICAgIGlmICghcGFyYW1zLnVzZXJLZXkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHVzZXJLZXknKTtcbiAgICAgIH1cbiAgICAgIGlmICghcGFyYW1zLmJhY2t1cEtleSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgYmFja3VwS2V5Jyk7XG4gICAgICB9XG4gICAgICBpZiAoIXBhcmFtcy53YWxsZXRQYXNzcGhyYXNlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyB3YWxsZXQgcGFzc3BocmFzZScpO1xuICAgICAgfVxuXG4gICAgICAvLyBDbGVhbiB1cCB3aGl0ZXNwYWNlIGZyb20gZW50ZXJlZCB2YWx1ZXNcbiAgICAgIGNvbnN0IHVzZXJLZXkgPSBwYXJhbXMudXNlcktleS5yZXBsYWNlKC9cXHMvZywgJycpO1xuICAgICAgY29uc3QgYmFja3VwS2V5ID0gcGFyYW1zLmJhY2t1cEtleS5yZXBsYWNlKC9cXHMvZywgJycpO1xuXG4gICAgICAvLyBEZWNyeXB0IHByaXZhdGUga2V5cyBmcm9tIEtleUNhcmQgdmFsdWVzXG4gICAgICBsZXQgdXNlclBydjtcbiAgICAgIHRyeSB7XG4gICAgICAgIHVzZXJQcnYgPSB0aGlzLmJpdGdvLmRlY3J5cHQoe1xuICAgICAgICAgIGlucHV0OiB1c2VyS2V5LFxuICAgICAgICAgIHBhc3N3b3JkOiBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3IgZGVjcnlwdGluZyB1c2VyIGtleWNoYWluOiAke2UubWVzc2FnZX1gKTtcbiAgICAgIH1cbiAgICAgIC8qKiBUT0RPIEJHLTUyNDE5IEltcGxlbWVudCBDb2RlYyBmb3IgcGFyc2luZyAqL1xuICAgICAgY29uc3QgdXNlclNpZ25pbmdNYXRlcmlhbCA9IEpTT04ucGFyc2UodXNlclBydikgYXMgRUREU0FNZXRob2RUeXBlcy5Vc2VyU2lnbmluZ01hdGVyaWFsO1xuXG4gICAgICBsZXQgYmFja3VwUHJ2O1xuICAgICAgdHJ5IHtcbiAgICAgICAgYmFja3VwUHJ2ID0gdGhpcy5iaXRnby5kZWNyeXB0KHtcbiAgICAgICAgICBpbnB1dDogYmFja3VwS2V5LFxuICAgICAgICAgIHBhc3N3b3JkOiBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3IgZGVjcnlwdGluZyBiYWNrdXAga2V5Y2hhaW46ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgYmFja3VwU2lnbmluZ01hdGVyaWFsID0gSlNPTi5wYXJzZShiYWNrdXBQcnYpIGFzIEVERFNBTWV0aG9kVHlwZXMuQmFja3VwU2lnbmluZ01hdGVyaWFsO1xuXG4gICAgICAvLyBhZGQgc2lnbmF0dXJlXG4gICAgICBjb25zdCBzaWduYXR1cmVIZXggPSBhd2FpdCBFRERTQU1ldGhvZHMuZ2V0VFNTU2lnbmF0dXJlKFxuICAgICAgICB1c2VyU2lnbmluZ01hdGVyaWFsLFxuICAgICAgICBiYWNrdXBTaWduaW5nTWF0ZXJpYWwsXG4gICAgICAgIGN1cnJQYXRoLFxuICAgICAgICB1bnNpZ25lZFRyYW5zYWN0aW9uXG4gICAgICApO1xuICAgICAgY29uc3QgYWRhS2V5UGFpciA9IG5ldyBBZGFLZXlQYWlyKHsgcHViOiBhY2NvdW50SWQgfSk7XG4gICAgICB0eEJ1aWxkZXIuYWRkU2lnbmF0dXJlKHsgcHViOiBhZGFLZXlQYWlyLmdldEtleXMoKS5wdWIgfSwgc2lnbmF0dXJlSGV4KTtcbiAgICAgIGNvbnN0IHNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBzZXJpYWxpemVkVHggPSBzaWduZWRUcmFuc2FjdGlvbi50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0cmFuc2FjdGlvblByZWJ1aWxkID0geyB0eEhleDogc2VyaWFsaXplZFR4IH07XG4gICAgICBjb25zdCBwYXJzZWRUeCA9IGF3YWl0IHRoaXMucGFyc2VUcmFuc2FjdGlvbih7IHR4UHJlYnVpbGQ6IHRyYW5zYWN0aW9uUHJlYnVpbGQgfSk7XG4gICAgICBjb25zdCB3YWxsZXRDb2luID0gdGhpcy5nZXRDaGFpbigpO1xuICAgICAgY29uc3Qgb3V0cHV0ID0gKHBhcnNlZFR4Lm91dHB1dHMgYXMgSVRyYW5zYWN0aW9uUmVjaXBpZW50KVswXTtcbiAgICAgIGNvbnN0IGlucHV0cyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGFkZHJlc3M6IHNlbmRlckFkZHIsXG4gICAgICAgICAgdmFsdWVTdHJpbmc6IG91dHB1dC5hbW91bnQsXG4gICAgICAgICAgdmFsdWU6IG5ldyBCaWdOdW1iZXIob3V0cHV0LmFtb3VudCkudG9OdW1iZXIoKSxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgICBjb25zdCBvdXRwdXRzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogb3V0cHV0LmFkZHJlc3MsXG4gICAgICAgICAgdmFsdWVTdHJpbmc6IG91dHB1dC5hbW91bnQsXG4gICAgICAgICAgY29pbk5hbWU6IHdhbGxldENvaW4sXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgY29uc3Qgc3BlbmRBbW91bnQgPSBvdXRwdXQuYW1vdW50O1xuICAgICAgY29uc3QgY29tcGxldGVkUGFyc2VkVHggPSB7IGlucHV0czogaW5wdXRzLCBvdXRwdXRzOiBvdXRwdXRzLCBzcGVuZEFtb3VudDogc3BlbmRBbW91bnQsIHR5cGU6ICcnIH07XG4gICAgICBjb25zdCBmZWUgPSBuZXcgQmlnTnVtYmVyKChwYXJzZWRUeC5mZWUgYXMgeyBmZWU6IHN0cmluZyB9KS5mZWUpO1xuICAgICAgY29uc3QgZmVlSW5mbyA9IHsgZmVlOiBmZWUudG9OdW1iZXIoKSwgZmVlU3RyaW5nOiBmZWUudG9TdHJpbmcoKSB9O1xuICAgICAgY29uc3QgY29pblNwZWNpZmljID0geyBjb21tb25LZXljaGFpbjogYml0Z29LZXkgfTtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uOiBNUENUeCA9IHtcbiAgICAgICAgc2VyaWFsaXplZFR4OiBzZXJpYWxpemVkVHgsXG4gICAgICAgIHNjYW5JbmRleDogaW5kZXgsXG4gICAgICAgIGNvaW46IHdhbGxldENvaW4sXG4gICAgICAgIHNpZ25hYmxlSGV4OiB1bnNpZ25lZFRyYW5zYWN0aW9uLnNpZ25hYmxlUGF5bG9hZC50b1N0cmluZygnaGV4JyksXG4gICAgICAgIGRlcml2YXRpb25QYXRoOiBjdXJyUGF0aCxcbiAgICAgICAgcGFyc2VkVHg6IGNvbXBsZXRlZFBhcnNlZFR4LFxuICAgICAgICBmZWVJbmZvOiBmZWVJbmZvLFxuICAgICAgICBjb2luU3BlY2lmaWM6IGNvaW5TcGVjaWZpYyxcbiAgICAgIH07XG4gICAgICBjb25zdCB1bnNpZ25lZFR4OiBNUENVbnNpZ25lZFR4ID0geyB1bnNpZ25lZFR4OiB0cmFuc2FjdGlvbiwgc2lnbmF0dXJlU2hhcmVzOiBbXSB9O1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb25zOiBNUENVbnNpZ25lZFR4W10gPSBbdW5zaWduZWRUeF07XG4gICAgICBjb25zdCB0eFJlcXVlc3Q6IFJlY292ZXJ5VHhSZXF1ZXN0ID0ge1xuICAgICAgICB0cmFuc2FjdGlvbnM6IHRyYW5zYWN0aW9ucyxcbiAgICAgICAgd2FsbGV0Q29pbjogd2FsbGV0Q29pbixcbiAgICAgIH07XG4gICAgICBjb25zdCB0eFJlcXVlc3RzOiBNUENTd2VlcFR4cyA9IHsgdHhSZXF1ZXN0czogW3R4UmVxdWVzdF0gfTtcbiAgICAgIHJldHVybiB0eFJlcXVlc3RzO1xuICAgIH1cbiAgICBjb25zdCB0cmFuc2FjdGlvbjogTVBDVHggPSB7IHNlcmlhbGl6ZWRUeDogc2VyaWFsaXplZFR4LCBzY2FuSW5kZXg6IGluZGV4IH07XG4gICAgcmV0dXJuIHRyYW5zYWN0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBuYXRpdmUgQURBIHJlY292ZXJpZXMgb2YgcmVjZWl2ZSBhZGRyZXNzZXMgaW4gYmF0Y2ggd2l0aG91dCBCaXRHby5cbiAgICogRnVuZHMgd2lsbCBiZSByZWNvdmVyZWQgdG8gYmFzZSBhZGRyZXNzIGZpcnN0LiBZb3UgbmVlZCB0byBpbml0aWF0ZSBhbm90aGVyIHN3ZWVwIHR4biBhZnRlciB0aGF0LlxuICAgKlxuICAgKiBAcGFyYW0ge01QQ0NvbnNvbGlkYXRpb25SZWNvdmVyeU9wdGlvbnN9IHBhcmFtcyAtIG9wdGlvbnMgZm9yIGNvbnNvbGlkYXRpb24gcmVjb3ZlcnkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGFyYW1zLnN0YXJ0aW5nU2NhbkluZGV4XSAtIHJlY2VpdmUgYWRkcmVzcyBpbmRleCB0byBzdGFydCBzY2FubmluZyBmcm9tLiBkZWZhdWx0IHRvIDEgKGluY2x1c2l2ZSkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGFyYW1zLmVuZGluZ1NjYW5JbmRleF0gLSByZWNlaXZlIGFkZHJlc3MgaW5kZXggdG8gZW5kIHNjYW5uaW5nIGF0LiBkZWZhdWx0IHRvIHN0YXJ0aW5nU2NhbkluZGV4ICsgMjAgKGV4Y2x1c2l2ZSkuXG4gICAqL1xuICBhc3luYyByZWNvdmVyQ29uc29saWRhdGlvbnMocGFyYW1zOiBNUENDb25zb2xpZGF0aW9uUmVjb3ZlcnlPcHRpb25zKTogUHJvbWlzZTxNUENUeHMgfCBNUENTd2VlcFR4cz4ge1xuICAgIGNvbnN0IGlzVW5zaWduZWRTd2VlcCA9ICFwYXJhbXMudXNlcktleSAmJiAhcGFyYW1zLmJhY2t1cEtleSAmJiAhcGFyYW1zLndhbGxldFBhc3NwaHJhc2U7XG4gICAgY29uc3Qgc3RhcnRJZHggPSBwYXJhbXMuc3RhcnRpbmdTY2FuSW5kZXggfHwgMTtcbiAgICBjb25zdCBlbmRJZHggPSBwYXJhbXMuZW5kaW5nU2NhbkluZGV4IHx8IHN0YXJ0SWR4ICsgREVGQVVMVF9TQ0FOX0ZBQ1RPUjtcblxuICAgIGlmIChzdGFydElkeCA8IDEgfHwgZW5kSWR4IDw9IHN0YXJ0SWR4IHx8IGVuZElkeCAtIHN0YXJ0SWR4ID4gMTAgKiBERUZBVUxUX1NDQU5fRkFDVE9SKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIHN0YXJ0aW5nIG9yIGVuZGluZyBpbmRleCB0byBzY2FuIGZvciBhZGRyZXNzZXMuIHN0YXJ0aW5nU2NhbkluZGV4OiAke3N0YXJ0SWR4fSwgZW5kaW5nU2NhbkluZGV4OiAke2VuZElkeH0uYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBhZGRyZXNzUGFyYW1zID0ge1xuICAgICAgYml0Z29LZXk6IHBhcmFtcy5iaXRnb0tleSxcbiAgICAgIGluZGV4OiAwLFxuICAgICAgc2VlZDogcGFyYW1zLnNlZWQsXG4gICAgfTtcbiAgICBjb25zdCB7IGFkZHJlc3M6IGJhc2VBZGRyZXNzIH0gPSBhd2FpdCB0aGlzLmdldEFkYUFkZHJlc3NBbmRBY2NvdW50SWQoYWRkcmVzc1BhcmFtcyk7XG4gICAgY29uc3QgY29uc29saWRhdGlvblRyYW5zYWN0aW9uczogYW55W10gPSBbXTtcbiAgICBsZXQgbGFzdFNjYW5JbmRleCA9IHN0YXJ0SWR4O1xuICAgIGZvciAobGV0IGkgPSBzdGFydElkeDsgaSA8IGVuZElkeDsgaSsrKSB7XG4gICAgICBjb25zdCByZWNvdmVyUGFyYW1zID0ge1xuICAgICAgICB1c2VyS2V5OiBwYXJhbXMudXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiBwYXJhbXMuYmFja3VwS2V5LFxuICAgICAgICBiaXRnb0tleTogcGFyYW1zLmJpdGdvS2V5LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogYmFzZUFkZHJlc3MsXG4gICAgICAgIHNlZWQ6IHBhcmFtcy5zZWVkLFxuICAgICAgICBpbmRleDogaSxcbiAgICAgIH07XG5cbiAgICAgIGxldCByZWNvdmVyeVRyYW5zYWN0aW9uO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmVjb3ZlcnlUcmFuc2FjdGlvbiA9IGF3YWl0IHRoaXMucmVjb3ZlcihyZWNvdmVyUGFyYW1zKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGUubWVzc2FnZSA9PT0gJ0RpZCBub3QgZmluZCBhZGRyZXNzIHdpdGggZnVuZHMgdG8gcmVjb3Zlci4nIHx8XG4gICAgICAgICAgZS5tZXNzYWdlLnN0YXJ0c1dpdGgoJ0luc3VmZmljaWVudCBmdW5kcyB0byByZWNvdmVyJylcbiAgICAgICAgKSB7XG4gICAgICAgICAgbGFzdFNjYW5JbmRleCA9IGk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzVW5zaWduZWRTd2VlcCkge1xuICAgICAgICBjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zLnB1c2goKHJlY292ZXJ5VHJhbnNhY3Rpb24gYXMgTVBDU3dlZXBUeHMpLnR4UmVxdWVzdHNbMF0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29saWRhdGlvblRyYW5zYWN0aW9ucy5wdXNoKHJlY292ZXJ5VHJhbnNhY3Rpb24pO1xuICAgICAgfVxuICAgICAgbGFzdFNjYW5JbmRleCA9IGk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnMubGVuZ3RoID09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRGlkIG5vdCBmaW5kIGFuIGFkZHJlc3Mgd2l0aCBmdW5kcyB0byByZWNvdmVyLicpO1xuICAgIH1cblxuICAgIGlmIChpc1Vuc2lnbmVkU3dlZXApIHtcbiAgICAgIC8vIGxhc3RTY2FuSW5kZXggd2lsbCBiZSB1c2VkIHRvIGluZm9ybSB1c2VyIHRoZSBsYXN0IGFkZHJlc3MgaW5kZXggc2Nhbm5lZCBmb3IgYXZhaWxhYmxlIGZ1bmRzIChzbyB0aGV5IGNhblxuICAgICAgLy8gYXBwcm9wcmlhdGVseSBhZGp1c3QgdGhlIHNjYW4gcmFuZ2Ugb24gdGhlIG5leHQgaXRlcmF0aW9uIG9mIGNvbnNvbGlkYXRpb24gcmVjb3ZlcmllcykuIEluIHRoZSBjYXNlIG9mIHVuc2lnbmVkXG4gICAgICAvLyBzd2VlcCBjb25zb2xpZGF0aW9ucywgdGhpcyBsYXN0U2NhbkluZGV4IHdpbGwgYmUgcHJvdmlkZWQgaW4gdGhlIGNvaW5TcGVjaWZpYyBvZiB0aGUgbGFzdCB0eG4gbWFkZS5cbiAgICAgIGNvbnN0IGxhc3RUcmFuc2FjdGlvbkNvaW5TcGVjaWZpYyA9IHtcbiAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgY29uc29saWRhdGlvblRyYW5zYWN0aW9uc1tjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zLmxlbmd0aCAtIDFdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpY1xuICAgICAgICAgICAgLmNvbW1vbktleWNoYWluLFxuICAgICAgICBsYXN0U2NhbkluZGV4OiBsYXN0U2NhbkluZGV4LFxuICAgICAgfTtcbiAgICAgIGNvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnNbY29uc29saWRhdGlvblRyYW5zYWN0aW9ucy5sZW5ndGggLSAxXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5jb2luU3BlY2lmaWMgPVxuICAgICAgICBsYXN0VHJhbnNhY3Rpb25Db2luU3BlY2lmaWM7XG4gICAgICBjb25zdCBjb25zb2xpZGF0aW9uU3dlZXBUcmFuc2FjdGlvbnM6IE1QQ1N3ZWVwVHhzID0geyB0eFJlcXVlc3RzOiBjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zIH07XG4gICAgICByZXR1cm4gY29uc29saWRhdGlvblN3ZWVwVHJhbnNhY3Rpb25zO1xuICAgIH1cblxuICAgIHJldHVybiB7IHRyYW5zYWN0aW9uczogY29uc29saWRhdGlvblRyYW5zYWN0aW9ucywgbGFzdFNjYW5JbmRleCB9O1xuICB9XG5cbiAgLyoqXG4gICAqIE9idGFpbnMgQURBIGFkZHJlc3MgYW5kIGFjY291bnQgaWQgZnJvbSBwcm92aWRlZCBiaXRnbyBrZXkgZm9yIHRoZSBnaXZlbiBpbmRleCBhbmQgc2VlZCAob3B0aW9uYWwpLlxuICAgKlxuICAgKiBAcGFyYW0ge0FkYUFkZHJlc3NQYXJhbXN9IHBhcmFtcyAtIHBhcmFtcyB0byBvYnRhaW4gYWRhIGFkZHJlc3MgYW5kIGFjY291bnQgaWRcbiAgICovXG4gIGFzeW5jIGdldEFkYUFkZHJlc3NBbmRBY2NvdW50SWQocGFyYW1zOiBBZGFBZGRyZXNzUGFyYW1zKTogUHJvbWlzZTxBZGFBZGRyZXNzQW5kQWNjb3VudElkPiB7XG4gICAgaWYgKCFwYXJhbXMuYml0Z29LZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBiaXRnb0tleScpO1xuICAgIH1cblxuICAgIGxldCBhZGRyRm9ybWF0ID0gQWRkcmVzc0Zvcm1hdC50ZXN0bmV0O1xuICAgIGlmICh0aGlzLmdldENoYWluKCkgPT09ICdhZGEnKSB7XG4gICAgICBhZGRyRm9ybWF0ID0gQWRkcmVzc0Zvcm1hdC5tYWlubmV0O1xuICAgIH1cblxuICAgIGNvbnN0IGJpdGdvS2V5ID0gcGFyYW1zLmJpdGdvS2V5LnJlcGxhY2UoL1xccy9nLCAnJyk7XG4gICAgY29uc3QgTVBDID0gYXdhaXQgRUREU0FNZXRob2RzLmdldEluaXRpYWxpemVkTXBjSW5zdGFuY2UoKTtcbiAgICBjb25zdCBkZXJpdmF0aW9uUGF0aFByZWZpeCA9IHBhcmFtcy5zZWVkID8gZ2V0RGVyaXZhdGlvblBhdGgocGFyYW1zLnNlZWQpIDogJ20nO1xuICAgIGNvbnN0IHN0YWtlS2V5UGFpciA9IG5ldyBBZGFLZXlQYWlyKHtcbiAgICAgIHB1YjogTVBDLmRlcml2ZVVuaGFyZGVuZWQoYml0Z29LZXksIGRlcml2YXRpb25QYXRoUHJlZml4ICsgJy8wJykuc2xpY2UoMCwgNjQpLFxuICAgIH0pO1xuXG4gICAgY29uc3QgY3VyclBhdGggPSBkZXJpdmF0aW9uUGF0aFByZWZpeCArIGAvJHtwYXJhbXMuaW5kZXh9YDtcbiAgICBjb25zdCBhY2NvdW50SWQgPSBNUEMuZGVyaXZlVW5oYXJkZW5lZChiaXRnb0tleSwgY3VyclBhdGgpLnNsaWNlKDAsIDY0KTtcbiAgICBjb25zdCBwYXltZW50S2V5UGFpciA9IG5ldyBBZGFLZXlQYWlyKHsgcHViOiBhY2NvdW50SWQgfSk7XG4gICAgY29uc3QgYWRkcmVzcyA9IFV0aWxzLmRlZmF1bHQuY3JlYXRlQmFzZUFkZHJlc3NXaXRoU3Rha2VBbmRQYXltZW50S2V5KHN0YWtlS2V5UGFpciwgcGF5bWVudEtleVBhaXIsIGFkZHJGb3JtYXQpO1xuICAgIHJldHVybiB7IGFkZHJlc3MsIGFjY291bnRJZCB9O1xuICB9XG5cbiAgLyoqIGluaGVyaXRlZCBkb2MgKi9cbiAgc3VwcG9ydHNUc3MoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKi9cbiAgc3VwcG9ydHNNZXNzYWdlU2lnbmluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBpbmhlcml0ZWQgZG9jICovXG4gIGdldERlZmF1bHRNdWx0aXNpZ1R5cGUoKTogTXVsdGlzaWdUeXBlIHtcbiAgICByZXR1cm4gbXVsdGlzaWdUeXBlcy50c3M7XG4gIH1cblxuICAvKiogaW5oZXJpdGVkIGRvYyAqL1xuICBnZXRNUENBbGdvcml0aG0oKTogTVBDQWxnb3JpdGhtIHtcbiAgICByZXR1cm4gJ2VkZHNhJztcbiAgfVxuXG4gIC8qKiBpbmhlcml0ZWQgZG9jICovXG4gIGFsbG93c0FjY291bnRDb25zb2xpZGF0aW9ucygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0QnVpbGRlcigpOiBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5IHtcbiAgICByZXR1cm4gbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KHRoaXMuZ2V0QmFzZUNoYWluKCkpKTtcbiAgfVxuXG4gIC8qKiBpbmhlcml0ZWQgZG9jICovXG4gIHNldENvaW5TcGVjaWZpY0ZpZWxkc0luSW50ZW50KGludGVudDogUG9wdWxhdGVkSW50ZW50LCBwYXJhbXM6IFByZWJ1aWxkVHJhbnNhY3Rpb25XaXRoSW50ZW50T3B0aW9ucyk6IHZvaWQge1xuICAgIGludGVudC51bnNwZW50cyA9IHBhcmFtcy51bnNwZW50cztcbiAgICBpbnRlbnQuc2VuZGVyQWRkcmVzcyA9IHBhcmFtcy5zZW5kZXJBZGRyZXNzO1xuICB9XG5cbiAgLyoqIGluaGVyaXRlZCBkb2MgKi9cbiAgYXVkaXREZWNyeXB0ZWRLZXkoeyBwdWJsaWNLZXksIHBydiwgbXVsdGlTaWdUeXBlIH06IEF1ZGl0RGVjcnlwdGVkS2V5UGFyYW1zKSB7XG4gICAgaWYgKG11bHRpU2lnVHlwZSAhPT0gJ3RzcycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgbXVsdGlTaWdUeXBlJyk7XG4gICAgfVxuXG4gICAgYXVkaXRFZGRzYVByaXZhdGVLZXkocHJ2LCBwdWJsaWNLZXkgPz8gJycpO1xuICB9XG59XG4iXX0=