@bitgo-beta/sdk-coin-trx 1.2.3-alpha.42 → 1.2.3-alpha.421

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 (132) hide show
  1. package/dist/resources/protobuf/Contract.proto +32 -0
  2. package/dist/resources/protobuf/tron.d.ts +1478 -214
  3. package/dist/resources/protobuf/tron.js +6312 -2600
  4. package/dist/resources/protobuf/tron.proto +6 -0
  5. package/dist/src/index.js +6 -2
  6. package/dist/src/lib/constants.d.ts +3 -0
  7. package/dist/src/lib/constants.d.ts.map +1 -0
  8. package/dist/src/lib/constants.js +6 -0
  9. package/dist/src/lib/contractCallBuilder.d.ts +1 -35
  10. package/dist/src/lib/contractCallBuilder.d.ts.map +1 -1
  11. package/dist/src/lib/contractCallBuilder.js +12 -75
  12. package/dist/src/lib/delegateResourceTxBuilder.d.ts +27 -0
  13. package/dist/src/lib/delegateResourceTxBuilder.d.ts.map +1 -0
  14. package/dist/src/lib/delegateResourceTxBuilder.js +98 -0
  15. package/dist/src/lib/enum.d.ts +36 -1
  16. package/dist/src/lib/enum.d.ts.map +1 -1
  17. package/dist/src/lib/enum.js +40 -4
  18. package/dist/src/lib/freezeBalanceTxBuilder.d.ts +71 -0
  19. package/dist/src/lib/freezeBalanceTxBuilder.d.ts.map +1 -0
  20. package/dist/src/lib/freezeBalanceTxBuilder.js +211 -0
  21. package/dist/src/lib/iface.d.ts +220 -2
  22. package/dist/src/lib/iface.d.ts.map +1 -1
  23. package/dist/src/lib/iface.js +1 -1
  24. package/dist/src/lib/index.js +23 -9
  25. package/dist/src/lib/keyPair.d.ts +0 -1
  26. package/dist/src/lib/keyPair.d.ts.map +1 -1
  27. package/dist/src/lib/keyPair.js +31 -18
  28. package/dist/src/lib/resourceManagementTxBuilder.d.ts +72 -0
  29. package/dist/src/lib/resourceManagementTxBuilder.d.ts.map +1 -0
  30. package/dist/src/lib/resourceManagementTxBuilder.js +150 -0
  31. package/dist/src/lib/tokenTransferBuilder.d.ts +1 -1
  32. package/dist/src/lib/tokenTransferBuilder.js +3 -3
  33. package/dist/src/lib/transaction.d.ts.map +1 -1
  34. package/dist/src/lib/transaction.js +92 -6
  35. package/dist/src/lib/transactionBuilder.d.ts +50 -5
  36. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  37. package/dist/src/lib/transactionBuilder.js +110 -21
  38. package/dist/src/lib/undelegateResourceTxBuilder.d.ts +27 -0
  39. package/dist/src/lib/undelegateResourceTxBuilder.d.ts.map +1 -0
  40. package/dist/src/lib/undelegateResourceTxBuilder.js +98 -0
  41. package/dist/src/lib/unfreezeBalanceTxBuilder.d.ts +65 -0
  42. package/dist/src/lib/unfreezeBalanceTxBuilder.d.ts.map +1 -0
  43. package/dist/src/lib/unfreezeBalanceTxBuilder.js +204 -0
  44. package/dist/src/lib/utils.d.ts +85 -4
  45. package/dist/src/lib/utils.d.ts.map +1 -1
  46. package/dist/src/lib/utils.js +445 -47
  47. package/dist/src/lib/voteWitnessTxBuilder.d.ts +62 -0
  48. package/dist/src/lib/voteWitnessTxBuilder.d.ts.map +1 -0
  49. package/dist/src/lib/voteWitnessTxBuilder.js +219 -0
  50. package/dist/src/lib/withdrawBuilder.d.ts +49 -0
  51. package/dist/src/lib/withdrawBuilder.d.ts.map +1 -0
  52. package/dist/src/lib/withdrawBuilder.js +167 -0
  53. package/dist/src/lib/withdrawExpireUnfreezeTxBuilder.d.ts +49 -0
  54. package/dist/src/lib/withdrawExpireUnfreezeTxBuilder.d.ts.map +1 -0
  55. package/dist/src/lib/withdrawExpireUnfreezeTxBuilder.js +167 -0
  56. package/dist/src/lib/wrappedBuilder.d.ts +56 -0
  57. package/dist/src/lib/wrappedBuilder.d.ts.map +1 -1
  58. package/dist/src/lib/wrappedBuilder.js +86 -2
  59. package/dist/src/trx.d.ts +62 -4
  60. package/dist/src/trx.d.ts.map +1 -1
  61. package/dist/src/trx.js +371 -146
  62. package/dist/src/trxToken.d.ts +2 -2
  63. package/dist/src/trxToken.d.ts.map +1 -1
  64. package/dist/src/trxToken.js +5 -5
  65. package/dist/test/fixtures.d.ts +40 -0
  66. package/dist/test/fixtures.d.ts.map +1 -0
  67. package/dist/test/fixtures.js +46 -0
  68. package/dist/test/resources.d.ts +586 -0
  69. package/dist/test/resources.d.ts.map +1 -0
  70. package/dist/test/resources.js +746 -0
  71. package/dist/test/unit/index.d.ts +2 -0
  72. package/dist/test/unit/index.d.ts.map +1 -0
  73. package/dist/test/unit/index.js +19 -0
  74. package/dist/test/unit/keyPair.d.ts +2 -0
  75. package/dist/test/unit/keyPair.d.ts.map +1 -0
  76. package/dist/test/unit/keyPair.js +163 -0
  77. package/dist/test/unit/transaction.d.ts +2 -0
  78. package/dist/test/unit/transaction.d.ts.map +1 -0
  79. package/dist/test/unit/transaction.js +38 -0
  80. package/dist/test/unit/transactionBuilder/contractCallBuilder.d.ts +2 -0
  81. package/dist/test/unit/transactionBuilder/contractCallBuilder.d.ts.map +1 -0
  82. package/dist/test/unit/transactionBuilder/contractCallBuilder.js +315 -0
  83. package/dist/test/unit/transactionBuilder/delegateResourceTxBuilder.d.ts +2 -0
  84. package/dist/test/unit/transactionBuilder/delegateResourceTxBuilder.d.ts.map +1 -0
  85. package/dist/test/unit/transactionBuilder/delegateResourceTxBuilder.js +255 -0
  86. package/dist/test/unit/transactionBuilder/freezeBalanceTxBuilder.d.ts +2 -0
  87. package/dist/test/unit/transactionBuilder/freezeBalanceTxBuilder.d.ts.map +1 -0
  88. package/dist/test/unit/transactionBuilder/freezeBalanceTxBuilder.js +285 -0
  89. package/dist/test/unit/transactionBuilder/tokenTransferBuilder.d.ts +2 -0
  90. package/dist/test/unit/transactionBuilder/tokenTransferBuilder.d.ts.map +1 -0
  91. package/dist/test/unit/transactionBuilder/tokenTransferBuilder.js +42 -0
  92. package/dist/test/unit/transactionBuilder/undelegateResourceTxBuilder.d.ts +2 -0
  93. package/dist/test/unit/transactionBuilder/undelegateResourceTxBuilder.d.ts.map +1 -0
  94. package/dist/test/unit/transactionBuilder/undelegateResourceTxBuilder.js +255 -0
  95. package/dist/test/unit/transactionBuilder/unfreezeBalanceTxBuilder.d.ts +2 -0
  96. package/dist/test/unit/transactionBuilder/unfreezeBalanceTxBuilder.d.ts.map +1 -0
  97. package/dist/test/unit/transactionBuilder/unfreezeBalanceTxBuilder.js +256 -0
  98. package/dist/test/unit/transactionBuilder/voteWitnessTxBuilder.d.ts +2 -0
  99. package/dist/test/unit/transactionBuilder/voteWitnessTxBuilder.d.ts.map +1 -0
  100. package/dist/test/unit/transactionBuilder/voteWitnessTxBuilder.js +277 -0
  101. package/dist/test/unit/transactionBuilder/withdrawBalanceBuilder.d.ts +2 -0
  102. package/dist/test/unit/transactionBuilder/withdrawBalanceBuilder.d.ts.map +1 -0
  103. package/dist/test/unit/transactionBuilder/withdrawBalanceBuilder.js +213 -0
  104. package/dist/test/unit/transactionBuilder/withdrawExpireUnfreezeTxBuilder.d.ts +2 -0
  105. package/dist/test/unit/transactionBuilder/withdrawExpireUnfreezeTxBuilder.d.ts.map +1 -0
  106. package/dist/test/unit/transactionBuilder/withdrawExpireUnfreezeTxBuilder.js +213 -0
  107. package/dist/test/unit/transactionBuilder/wrappedBuilder.d.ts +2 -0
  108. package/dist/test/unit/transactionBuilder/wrappedBuilder.d.ts.map +1 -0
  109. package/dist/test/unit/transactionBuilder/wrappedBuilder.js +50 -0
  110. package/dist/test/unit/transactionBuilder.d.ts +2 -0
  111. package/dist/test/unit/transactionBuilder.d.ts.map +1 -0
  112. package/dist/test/unit/transactionBuilder.js +178 -0
  113. package/dist/test/unit/trx.d.ts +2 -0
  114. package/dist/test/unit/trx.d.ts.map +1 -0
  115. package/dist/test/unit/trx.js +532 -0
  116. package/dist/test/unit/util.d.ts +2 -0
  117. package/dist/test/unit/util.d.ts.map +1 -0
  118. package/dist/test/unit/util.js +141 -0
  119. package/dist/test/unit/verifyTransaction.d.ts +2 -0
  120. package/dist/test/unit/verifyTransaction.d.ts.map +1 -0
  121. package/dist/test/unit/verifyTransaction.js +378 -0
  122. package/dist/tsconfig.tsbuildinfo +1 -0
  123. package/package.json +20 -15
  124. package/.eslintignore +0 -5
  125. package/.mocharc.yml +0 -8
  126. package/CHANGELOG.md +0 -104
  127. package/resources/README.md +0 -31
  128. package/resources/protobuf/Contract.proto +0 -256
  129. package/resources/protobuf/Discover.proto +0 -44
  130. package/resources/protobuf/tron.d.ts +0 -11205
  131. package/resources/protobuf/tron.js +0 -33480
  132. package/resources/protobuf/tron.proto +0 -677
package/dist/src/trx.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,31 +15,46 @@ 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
  Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.Trx = exports.NodeTypes = exports.MINIMUM_TRON_MSIG_TRANSACTION_FEE = void 0;
36
+ exports.Trx = exports.NodeTypes = exports.DEFAULT_SCAN_FACTOR = exports.RECOVER_TRANSACTION_EXPIRY = exports.SAFE_TRON_TOKEN_TRANSACTION_FEE = exports.SAFE_TRON_TRANSACTION_FEE = exports.MINIMUM_TRON_MSIG_TRANSACTION_FEE = void 0;
23
37
  /**
24
38
  * @prettier
25
39
  */
26
40
  const secp256k1 = __importStar(require("secp256k1"));
27
41
  const crypto_1 = require("crypto");
28
- const utxo_lib_1 = require("@bitgo-beta/utxo-lib");
42
+ const secp256k1_1 = require("@bitgo-beta/secp256k1");
29
43
  const request = __importStar(require("superagent"));
30
44
  const sdk_core_1 = require("@bitgo-beta/sdk-core");
31
45
  const lib_1 = require("./lib");
32
46
  const builder_1 = require("./lib/builder");
47
+ const lodash_1 = require("lodash");
33
48
  exports.MINIMUM_TRON_MSIG_TRANSACTION_FEE = 1e6;
49
+ exports.SAFE_TRON_TRANSACTION_FEE = 2.1 * 1e6; // TRON foundation recommends 2.1 TRX as fees for guaranteed transaction
50
+ exports.SAFE_TRON_TOKEN_TRANSACTION_FEE = 100 * 1e6; // TRON foundation recommends 100 TRX as fees for guaranteed transaction
51
+ exports.RECOVER_TRANSACTION_EXPIRY = 86400000; // 24 hour
52
+ exports.DEFAULT_SCAN_FACTOR = 20; // default number of receive addresses to scan for funds
34
53
  var NodeTypes;
35
54
  (function (NodeTypes) {
36
55
  NodeTypes[NodeTypes["Full"] = 0] = "Full";
37
56
  NodeTypes[NodeTypes["Solidity"] = 1] = "Solidity";
38
- })(NodeTypes = exports.NodeTypes || (exports.NodeTypes = {}));
57
+ })(NodeTypes || (exports.NodeTypes = NodeTypes = {}));
39
58
  class Trx extends sdk_core_1.BaseCoin {
40
59
  constructor(bitgo, staticsCoin) {
41
60
  super(bitgo);
@@ -60,6 +79,10 @@ class Trx extends sdk_core_1.BaseCoin {
60
79
  transactionDataAllowed() {
61
80
  return true;
62
81
  }
82
+ /** inherited doc */
83
+ getDefaultMultisigType() {
84
+ return sdk_core_1.multisigTypes.onchain;
85
+ }
63
86
  static createInstance(bitgo, staticsCoin) {
64
87
  return new Trx(bitgo, staticsCoin);
65
88
  }
@@ -75,21 +98,21 @@ class Trx extends sdk_core_1.BaseCoin {
75
98
  return true;
76
99
  }
77
100
  /**
78
- * Checks if this is a valid base58 or hex address
101
+ * Checks if this is a valid base58
79
102
  * @param address
80
103
  */
81
104
  isValidAddress(address) {
82
105
  if (!address) {
83
106
  return false;
84
107
  }
85
- return this.isValidHexAddress(address) || lib_1.Utils.isBase58Address(address);
108
+ return lib_1.Utils.isBase58Address(address);
86
109
  }
87
110
  /**
88
111
  * Checks if this is a valid hex address
89
112
  * @param address hex address
90
113
  */
91
114
  isValidHexAddress(address) {
92
- return address.length === 42 && /^(0x)?([0-9a-f]{2})+$/i.test(address);
115
+ return /^41[0-9a-f]{40}$/i.test(address);
93
116
  }
94
117
  /**
95
118
  * Generate ed25519 key pair
@@ -102,9 +125,9 @@ class Trx extends sdk_core_1.BaseCoin {
102
125
  if (!seed) {
103
126
  // An extended private key has both a normal 256 bit private key and a 256 bit chain code, both of which must be
104
127
  // random. 512 bits is therefore the maximum entropy and gives us maximum security against cracking.
105
- seed = crypto_1.randomBytes(512 / 8);
128
+ seed = (0, crypto_1.randomBytes)(512 / 8);
106
129
  }
107
- const hd = utxo_lib_1.bip32.fromSeed(seed);
130
+ const hd = secp256k1_1.bip32.fromSeed(seed);
108
131
  return {
109
132
  pub: hd.neutered().toBase58(),
110
133
  prv: hd.toBase58(),
@@ -112,7 +135,7 @@ class Trx extends sdk_core_1.BaseCoin {
112
135
  }
113
136
  isValidXpub(xpub) {
114
137
  try {
115
- return utxo_lib_1.bip32.fromBase58(xpub).isNeutered();
138
+ return secp256k1_1.bip32.fromBase58(xpub).isNeutered();
116
139
  }
117
140
  catch (e) {
118
141
  return false;
@@ -132,6 +155,57 @@ class Trx extends sdk_core_1.BaseCoin {
132
155
  throw new sdk_core_1.MethodNotImplementedError();
133
156
  }
134
157
  async verifyTransaction(params) {
158
+ const { txParams, txPrebuild } = params;
159
+ if (!txParams) {
160
+ throw new Error('missing txParams');
161
+ }
162
+ if (!txPrebuild) {
163
+ throw new Error('missing txPrebuild');
164
+ }
165
+ if (!txPrebuild.txHex) {
166
+ throw new Error('missing txHex in txPrebuild');
167
+ }
168
+ const rawTx = txPrebuild.txHex;
169
+ const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(rawTx);
170
+ const tx = await txBuilder.build();
171
+ const txJson = tx.toJson();
172
+ if (!txJson.raw_data || !txJson.raw_data.contract || txJson.raw_data.contract.length !== 1) {
173
+ throw new Error('Number of contracts is greater than 1.');
174
+ }
175
+ const contract = txJson.raw_data.contract[0];
176
+ if (contract.type === 'TransferContract') {
177
+ return this.validateTransferContract(contract, txParams);
178
+ }
179
+ else {
180
+ return true;
181
+ }
182
+ }
183
+ /**
184
+ * Validate Transfer contract (native TRX transfer)
185
+ */
186
+ validateTransferContract(contract, txParams) {
187
+ if (!('parameter' in contract) || !contract.parameter?.value) {
188
+ throw new Error('Invalid Transfer contract structure');
189
+ }
190
+ const value = contract.parameter.value;
191
+ // Validate amount
192
+ if (!value.amount || value.amount < 0) {
193
+ throw new Error('Invalid transfer amount');
194
+ }
195
+ // If txParams has recipients, validate against expected values
196
+ if (txParams.recipients && txParams.recipients.length === 1) {
197
+ const recipient = txParams.recipients[0];
198
+ const expectedAmount = recipient.amount.toString();
199
+ const expectedDestination = recipient.address;
200
+ const actualAmount = value.amount.toString();
201
+ const actualDestination = lib_1.Utils.getBase58AddressFromHex(value.to_address);
202
+ if (expectedAmount !== actualAmount) {
203
+ throw new Error('transaction amount in txPrebuild does not match the value given by client');
204
+ }
205
+ if (expectedDestination.toLowerCase() !== actualDestination.toLowerCase()) {
206
+ throw new Error('destination address does not match with the recipient address');
207
+ }
208
+ }
135
209
  return true;
136
210
  }
137
211
  /**
@@ -141,7 +215,7 @@ class Trx extends sdk_core_1.BaseCoin {
141
215
  * @returns {string} derived private key
142
216
  */
143
217
  deriveKeyWithPath({ key, path }) {
144
- const keychain = utxo_lib_1.bip32.fromBase58(key);
218
+ const keychain = secp256k1_1.bip32.fromBase58(key);
145
219
  const derivedKeyNode = keychain.derivePath(path);
146
220
  return derivedKeyNode.toBase58();
147
221
  }
@@ -151,14 +225,12 @@ class Trx extends sdk_core_1.BaseCoin {
151
225
  * @param params
152
226
  * @param params.txPrebuild {Object} prebuild object returned by platform
153
227
  * @param params.prv {String} user prv
154
- * @param params.wallet.addressVersion {String} this is the version of the Algorand multisig address generation format
155
228
  * @returns Bluebird<SignedTransaction>
156
229
  */
157
230
  async signTransaction(params) {
158
- var _a, _b;
159
- const txBuilder = builder_1.getBuilder(this.getChain()).from(params.txPrebuild.txHex);
231
+ const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(params.txPrebuild.txHex);
160
232
  let key;
161
- const { chain, index } = (_b = (_a = params.txPrebuild) === null || _a === void 0 ? void 0 : _a.addressInfo) !== null && _b !== void 0 ? _b : { chain: 0, index: 0 };
233
+ const { chain, index } = params.txPrebuild?.addressInfo ?? { chain: 0, index: 0 };
162
234
  if (chain === 0 && index === 0) {
163
235
  key = params.prv;
164
236
  }
@@ -186,7 +258,7 @@ class Trx extends sdk_core_1.BaseCoin {
186
258
  */
187
259
  isValidXprv(prv) {
188
260
  try {
189
- return !utxo_lib_1.bip32.fromBase58(prv).isNeutered();
261
+ return !secp256k1_1.bip32.fromBase58(prv).isNeutered();
190
262
  }
191
263
  catch {
192
264
  return false;
@@ -216,11 +288,10 @@ class Trx extends sdk_core_1.BaseCoin {
216
288
  * @param message
217
289
  */
218
290
  async signMessage(key, message) {
219
- var _a;
220
291
  const toSign = this.toHexString(message);
221
292
  let prv = key.prv;
222
293
  if (this.isValidXprv(prv)) {
223
- prv = (_a = utxo_lib_1.bip32.fromBase58(prv).privateKey) === null || _a === void 0 ? void 0 : _a.toString('hex');
294
+ prv = secp256k1_1.bip32.fromBase58(prv).privateKey?.toString('hex');
224
295
  }
225
296
  if (!prv) {
226
297
  throw new Error('no privateKey');
@@ -238,7 +309,7 @@ class Trx extends sdk_core_1.BaseCoin {
238
309
  if (!this.isValidXpub(xpub)) {
239
310
  throw new Error('invalid xpub');
240
311
  }
241
- const publicKey = utxo_lib_1.bip32.fromBase58(xpub, utxo_lib_1.networks.bitcoin).publicKey;
312
+ const publicKey = secp256k1_1.bip32.fromBase58(xpub).publicKey;
242
313
  return Buffer.from(secp256k1.publicKeyConvert(publicKey, false /* compressed */)).toString('hex');
243
314
  }
244
315
  /**
@@ -259,29 +330,29 @@ class Trx extends sdk_core_1.BaseCoin {
259
330
  if (!this.isValidXprv(xprv)) {
260
331
  throw new Error('invalid xprv');
261
332
  }
262
- const hdNode = utxo_lib_1.bip32.fromBase58(xprv, utxo_lib_1.networks.bitcoin);
333
+ const hdNode = secp256k1_1.bip32.fromBase58(xprv);
263
334
  if (!hdNode.privateKey) {
264
335
  throw new Error('no privateKey');
265
336
  }
266
337
  return hdNode.privateKey.toString('hex');
267
338
  }
339
+ getNodeUrl(node) {
340
+ switch (node) {
341
+ case NodeTypes.Full:
342
+ return sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.full;
343
+ case NodeTypes.Solidity:
344
+ return sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.solidity;
345
+ default:
346
+ throw new Error('node type not found');
347
+ }
348
+ }
268
349
  /**
269
350
  * Make a query to Trongrid for information such as balance, token balance, solidity calls
270
351
  * @param query {Object} key-value pairs of parameters to append after /api
271
352
  * @returns {Object} response from Trongrid
272
353
  */
273
354
  async recoveryPost(query) {
274
- let nodeUri = '';
275
- switch (query.node) {
276
- case NodeTypes.Full:
277
- nodeUri = sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.full;
278
- break;
279
- case NodeTypes.Solidity:
280
- nodeUri = sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.solidity;
281
- break;
282
- default:
283
- throw new Error('node type not found');
284
- }
355
+ const nodeUri = this.getNodeUrl(query.node);
285
356
  const response = await request
286
357
  .post(nodeUri + query.path)
287
358
  .type('json')
@@ -298,17 +369,7 @@ class Trx extends sdk_core_1.BaseCoin {
298
369
  * @returns {Object} response from Trongrid
299
370
  */
300
371
  async recoveryGet(query) {
301
- let nodeUri = '';
302
- switch (query.node) {
303
- case NodeTypes.Full:
304
- nodeUri = sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.full;
305
- break;
306
- case NodeTypes.Solidity:
307
- nodeUri = sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.solidity;
308
- break;
309
- default:
310
- throw new Error('node type not found');
311
- }
372
+ const nodeUri = this.getNodeUrl(query.node);
312
373
  const response = await request
313
374
  .get(nodeUri + query.path)
314
375
  .type('json')
@@ -389,134 +450,294 @@ class Trx extends sdk_core_1.BaseCoin {
389
450
  }
390
451
  });
391
452
  }
453
+ /**
454
+ * Format for offline vault signing
455
+ * @param {BaseTransaction} tx
456
+ * @param {number} fee
457
+ * @param {number} recoveryAmount
458
+ * @returns {RecoveryTransaction}
459
+ */
460
+ formatForOfflineVault(tx, fee, recoveryAmount, addressInfo) {
461
+ const txJSON = tx.toJson();
462
+ const format = {
463
+ txHex: JSON.stringify(txJSON),
464
+ recoveryAmount,
465
+ feeInfo: {
466
+ fee: `${fee}`,
467
+ },
468
+ tx: txJSON, // Leaving it as txJSON for backwards compatibility
469
+ coin: this.getChain(),
470
+ };
471
+ return addressInfo ? { ...format, addressInfo } : format;
472
+ }
392
473
  /**
393
474
  * Builds a funds recovery transaction without BitGo.
394
475
  * We need to do three queries during this:
395
476
  * 1) Node query - how much money is in the account
396
477
  * 2) Build transaction - build our transaction for the amount
397
478
  * 3) Send signed build - send our signed build to a public node
479
+ *
480
+ * Note 1: for base address recoveries, fund will be recovered to recovery destination if base address balance is
481
+ * more than 2.1 TRX for native TRX recovery and 100 TRX for token recover. For receive addresses, fund will be
482
+ * recovered to base address first then swept to base address(decided as the universal pattern in team meeting).
483
+ *
484
+ * Note 2: the function supports token sweep from base address.
485
+ * TODO: support token sweep from receive address.
486
+ *
398
487
  * @param params
399
488
  */
400
489
  async recover(params) {
401
- const isKrsRecovery = sdk_core_1.getIsKrsRecovery(params);
402
- const isUnsignedSweep = sdk_core_1.getIsUnsignedSweep(params);
490
+ const isKrsRecovery = (0, sdk_core_1.getIsKrsRecovery)(params);
491
+ const isUnsignedSweep = (0, sdk_core_1.getIsUnsignedSweep)(params);
403
492
  if (!this.isValidAddress(params.recoveryDestination)) {
404
493
  throw new Error('Invalid destination address!');
405
494
  }
495
+ let startIdx = params.startingScanIndex;
496
+ if ((0, lodash_1.isUndefined)(startIdx)) {
497
+ startIdx = 1;
498
+ }
499
+ else if (!(0, lodash_1.isInteger)(startIdx) || startIdx < 0) {
500
+ throw new Error('Invalid starting index to scan for addresses');
501
+ }
502
+ let numIteration = params.scan;
503
+ if ((0, lodash_1.isUndefined)(numIteration)) {
504
+ numIteration = 20;
505
+ }
506
+ else if (typeof numIteration === 'string') {
507
+ numIteration = parseInt(numIteration, 10);
508
+ }
509
+ if (!(0, lodash_1.isInteger)(numIteration) || numIteration <= 0) {
510
+ throw new Error('Invalid scanning factor');
511
+ }
406
512
  // get our user, backup keys
407
- const keys = sdk_core_1.getBip32Keys(this.bitgo, params, { requireBitGoXpub: false });
513
+ const keys = (0, sdk_core_1.getBip32Keys)(this.bitgo, params, { requireBitGoXpub: false });
408
514
  // we need to decode our bitgoKey to a base58 address
409
515
  const bitgoHexAddr = this.pubToHexAddress(this.xpubToUncompressedPub(params.bitgoKey));
410
- const recoveryAddressHex = lib_1.Utils.getHexAddressFromBase58Address(params.recoveryDestination);
411
- // call the node to get our account balance
412
- const account = await this.getAccountBalancesFromNode(lib_1.Utils.getBase58AddressFromHex(bitgoHexAddr));
413
- const recoveryAmount = account.data[0].balance;
414
- const userXPub = keys[0].neutered().toBase58();
415
- const userXPrv = keys[0].toBase58();
416
- const backupXPub = keys[1].neutered().toBase58();
417
- // first construct token txns
418
- const tokenTxns = [];
419
- for (const token of account.data[0].trc20) {
420
- // mainnet tokens
421
- if (token.TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8) {
422
- const amount = token.TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8;
423
- const contractAddr = lib_1.Utils.getHexAddressFromBase58Address('TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8');
424
- tokenTxns.push((await this.getTriggerSmartContractTransaction(recoveryAddressHex, bitgoHexAddr, amount, contractAddr))
425
- .transaction);
426
- }
427
- else if (token.TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t) {
428
- const amount = token.TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t;
429
- const contractAddr = lib_1.Utils.getHexAddressFromBase58Address('TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t');
430
- tokenTxns.push((await this.getTriggerSmartContractTransaction(recoveryAddressHex, bitgoHexAddr, amount, contractAddr))
431
- .transaction);
432
- // testnet tokens
516
+ let recoveryFromAddrHex = bitgoHexAddr;
517
+ let recoveryToAddressHex = lib_1.Utils.getHexAddressFromBase58Address(params.recoveryDestination);
518
+ // call the node to get our account balance for base address
519
+ let account = await this.getAccountBalancesFromNode(lib_1.Utils.getBase58AddressFromHex(recoveryFromAddrHex));
520
+ let recoveryAmount = account.data[0].balance;
521
+ let userXPrv = keys[0].toBase58();
522
+ let isReceiveAddress = false;
523
+ let addressInfo;
524
+ const tokenContractAddr = params.tokenContractAddress;
525
+ // check for possible token recovery, recover the token provide by user
526
+ if (tokenContractAddr) {
527
+ let rawTokenTxn;
528
+ for (const token of account.data[0].trc20) {
529
+ if (token[tokenContractAddr]) {
530
+ const amount = token[tokenContractAddr];
531
+ const tokenContractAddrHex = lib_1.Utils.getHexAddressFromBase58Address(tokenContractAddr);
532
+ rawTokenTxn = (await this.getTriggerSmartContractTransaction(recoveryToAddressHex, recoveryFromAddrHex, amount, tokenContractAddrHex)).transaction;
533
+ recoveryAmount = parseInt(amount, 10);
534
+ break;
535
+ }
433
536
  }
434
- else if (token.TSdZwNqpHofzP6BsBKGQUWdBeJphLmF6id) {
435
- const amount = token.TSdZwNqpHofzP6BsBKGQUWdBeJphLmF6id;
436
- const contractAddr = lib_1.Utils.getHexAddressFromBase58Address('TSdZwNqpHofzP6BsBKGQUWdBeJphLmF6id');
437
- tokenTxns.push((await this.getTriggerSmartContractTransaction(recoveryAddressHex, bitgoHexAddr, amount, contractAddr))
438
- .transaction);
537
+ // build and sign token txns
538
+ if (rawTokenTxn) {
539
+ // Check there is sufficient of the native asset to cover fees
540
+ const trxBalance = account.data[0].balance;
541
+ if (trxBalance < exports.SAFE_TRON_TOKEN_TRANSACTION_FEE) {
542
+ throw new Error(`Amount of funds to recover ${trxBalance} is less than ${exports.SAFE_TRON_TOKEN_TRANSACTION_FEE} and wouldn't be able to fund a trc20 send`);
543
+ }
544
+ const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(rawTokenTxn);
545
+ // Default expiry is 1 minute which is too short for recovery purposes
546
+ // extend the expiry to 1 day
547
+ txBuilder.extendValidTo(exports.RECOVER_TRANSACTION_EXPIRY);
548
+ // this tx should be enough to drop into a node
549
+ if (isUnsignedSweep) {
550
+ return this.formatForOfflineVault(await txBuilder.build(), exports.SAFE_TRON_TOKEN_TRANSACTION_FEE, recoveryAmount);
551
+ }
552
+ const userPrv = this.xprvToCompressedPrv(userXPrv);
553
+ txBuilder.sign({ key: userPrv });
554
+ // krs recoveries don't get signed
555
+ if (!isKrsRecovery && !isReceiveAddress) {
556
+ const backupXPrv = keys[1].toBase58();
557
+ const backupPrv = this.xprvToCompressedPrv(backupXPrv);
558
+ txBuilder.sign({ key: backupPrv });
559
+ }
560
+ return this.formatForOfflineVault(await txBuilder.build(), exports.SAFE_TRON_TOKEN_TRANSACTION_FEE, recoveryAmount);
439
561
  }
440
- else if (token.TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs) {
441
- const amount = token.TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs;
442
- const contractAddr = lib_1.Utils.getHexAddressFromBase58Address('TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs');
443
- tokenTxns.push((await this.getTriggerSmartContractTransaction(recoveryAddressHex, bitgoHexAddr, amount, contractAddr))
444
- .transaction);
562
+ else {
563
+ throw Error('Not found token to recover, please check token balance');
445
564
  }
446
565
  }
447
- // construct the tx -
448
- // there's an assumption here being made about fees: for a wallet that hasn't been used in awhile, the implication is
449
- // it has maximum bandwidth. thus, a recovery should cost the minimum amount (1e6 sun or 1 Tron)
450
- if (exports.MINIMUM_TRON_MSIG_TRANSACTION_FEE > recoveryAmount) {
451
- throw new Error('Amount of funds to recover wouldnt be able to fund a send');
452
- }
453
- const keyHexAddresses = [
454
- this.pubToHexAddress(this.xpubToUncompressedPub(userXPub)),
455
- this.pubToHexAddress(this.xpubToUncompressedPub(backupXPub)),
456
- bitgoHexAddr,
457
- ];
458
- // run checks to ensure this is a valid tx - permissions match our signer keys
459
- const ownerKeys = [];
460
- for (const key of account.data[0].owner_permission.keys) {
461
- const address = lib_1.Utils.getHexAddressFromBase58Address(key.address);
462
- const weight = key.weight;
463
- ownerKeys.push({ address, weight });
464
- }
465
- const activePermissionKeys = [];
466
- for (const key of account.data[0].active_permission[0].keys) {
467
- const address = lib_1.Utils.getHexAddressFromBase58Address(key.address);
468
- const weight = key.weight;
469
- activePermissionKeys.push({ address, weight });
470
- }
471
- this.checkPermissions(ownerKeys, keyHexAddresses);
472
- this.checkPermissions(activePermissionKeys, keyHexAddresses);
473
- // build and sign token txns
474
- const finalTokenTxs = [];
475
- for (const tokenTxn of tokenTxns) {
476
- const txBuilder = builder_1.getBuilder(this.getChain()).from(tokenTxn);
477
- // this tx should be enough to drop into a node
478
- if (isUnsignedSweep) {
479
- finalTokenTxs.push((await txBuilder.build()).toJson());
480
- continue;
566
+ // let us recover the native Tron
567
+ if (recoveryAmount > exports.SAFE_TRON_TRANSACTION_FEE) {
568
+ const userXPub = keys[0].neutered().toBase58();
569
+ const backupXPub = keys[1].neutered().toBase58();
570
+ // check multisig permissions
571
+ const keyHexAddresses = [
572
+ this.pubToHexAddress(this.xpubToUncompressedPub(userXPub)),
573
+ this.pubToHexAddress(this.xpubToUncompressedPub(backupXPub)),
574
+ bitgoHexAddr,
575
+ ];
576
+ // run checks to ensure this is a valid tx - permissions match our signer keys
577
+ const ownerKeys = [];
578
+ for (const key of account.data[0].owner_permission.keys) {
579
+ const address = lib_1.Utils.getHexAddressFromBase58Address(key.address);
580
+ const weight = key.weight;
581
+ ownerKeys.push({ address, weight });
481
582
  }
482
- const userPrv = this.xprvToCompressedPrv(userXPrv);
483
- txBuilder.sign({ key: userPrv });
484
- // krs recoveries don't get signed
485
- if (!isKrsRecovery) {
486
- const backupXPrv = keys[1].toBase58();
487
- const backupPrv = this.xprvToCompressedPrv(backupXPrv);
488
- txBuilder.sign({ key: backupPrv });
583
+ const activePermissionKeys = [];
584
+ for (const key of account.data[0].active_permission[0].keys) {
585
+ const address = lib_1.Utils.getHexAddressFromBase58Address(key.address);
586
+ const weight = key.weight;
587
+ activePermissionKeys.push({ address, weight });
588
+ }
589
+ this.checkPermissions(ownerKeys, keyHexAddresses);
590
+ this.checkPermissions(activePermissionKeys, keyHexAddresses);
591
+ }
592
+ else {
593
+ // Check receive addresses for funds
594
+ // Check for first derived wallet with funds
595
+ // Receive addresses are derived from the user key
596
+ for (let i = startIdx; i < numIteration + startIdx; i++) {
597
+ const derivationPath = `0/0/0/${i}`;
598
+ const userKey = keys[0].derivePath(derivationPath);
599
+ const xpub = userKey.neutered();
600
+ const receiveAddress = this.pubToHexAddress(this.xpubToUncompressedPub(xpub.toBase58()));
601
+ const address = lib_1.Utils.getBase58AddressFromHex(receiveAddress);
602
+ // call the node to get our account balance
603
+ const accountInfo = await this.getAccountBalancesFromNode(address);
604
+ if (accountInfo.data[0] && accountInfo.data[0].balance > exports.SAFE_TRON_TRANSACTION_FEE) {
605
+ account = accountInfo;
606
+ recoveryAmount = accountInfo.data[0].balance;
607
+ userXPrv = userKey.toBase58(); // assign derived userXPrx
608
+ isReceiveAddress = true;
609
+ recoveryFromAddrHex = receiveAddress;
610
+ recoveryToAddressHex = bitgoHexAddr;
611
+ addressInfo = {
612
+ address,
613
+ chain: 0,
614
+ index: i,
615
+ };
616
+ break;
617
+ }
489
618
  }
490
- finalTokenTxs.push((await txBuilder.build()).toJson());
491
619
  }
492
- // tokens must be recovered before the native asset, so that there is sufficient of the native asset to cover fees
493
- if (finalTokenTxs.length > 0) {
494
- return {
495
- tokenTxs: finalTokenTxs,
496
- };
620
+ // a sweep potentially needs to pay for multi-sig transfer, destination account activation and bandwidth
621
+ // TRON foundation recommends 2.1 TRX for guaranteed confirmation
622
+ if (!recoveryAmount || exports.SAFE_TRON_TRANSACTION_FEE >= recoveryAmount) {
623
+ throw new Error(`Amount of funds to recover ${recoveryAmount} is less than ${exports.SAFE_TRON_TRANSACTION_FEE} and wouldn't be able to fund a send`);
497
624
  }
498
- const recoveryAmountMinusFees = recoveryAmount - exports.MINIMUM_TRON_MSIG_TRANSACTION_FEE;
499
- const buildTx = await this.getBuildTransaction(recoveryAddressHex, bitgoHexAddr, recoveryAmountMinusFees);
625
+ const recoveryAmountMinusFees = recoveryAmount - exports.SAFE_TRON_TRANSACTION_FEE;
626
+ const buildTx = await this.getBuildTransaction(recoveryToAddressHex, recoveryFromAddrHex, recoveryAmountMinusFees);
500
627
  // construct our tx
501
- const txBuilder = builder_1.getBuilder(this.getChain()).from(buildTx);
628
+ const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(buildTx);
629
+ // Default expiry is 1 minute which is too short for recovery purposes
630
+ // extend the expiry to 1 day
631
+ txBuilder.extendValidTo(exports.RECOVER_TRANSACTION_EXPIRY);
632
+ const tx = await txBuilder.build();
502
633
  // this tx should be enough to drop into a node
503
634
  if (isUnsignedSweep) {
504
- return {
505
- tx: (await txBuilder.build()).toJson(),
506
- recoveryAmount: recoveryAmountMinusFees,
507
- };
635
+ return this.formatForOfflineVault(tx, exports.SAFE_TRON_TRANSACTION_FEE, recoveryAmountMinusFees, addressInfo);
508
636
  }
509
637
  const userPrv = this.xprvToCompressedPrv(userXPrv);
510
638
  txBuilder.sign({ key: userPrv });
511
639
  // krs recoveries don't get signed
512
- if (!isKrsRecovery) {
640
+ if (!isKrsRecovery && !isReceiveAddress) {
513
641
  const backupXPrv = keys[1].toBase58();
514
642
  const backupPrv = this.xprvToCompressedPrv(backupXPrv);
515
643
  txBuilder.sign({ key: backupPrv });
516
644
  }
645
+ const txSigned = await txBuilder.build();
646
+ return this.formatForOfflineVault(txSigned, exports.SAFE_TRON_TRANSACTION_FEE, recoveryAmountMinusFees, addressInfo);
647
+ }
648
+ /**
649
+ * Builds native TRX recoveries of receive addresses in batch without BitGo.
650
+ * Funds will be recovered to base address first. You need to initiate another sweep txn after that.
651
+ * Note: there will be another recoverTokenConsolidations function to support token recover from receive addresses.
652
+ *
653
+ * @param {ConsolidationRecoveryOptions} params - options for consolidation recovery.
654
+ * @param {string} [params.startingScanIndex] - receive address index to start scanning from. default to 1 (inclusive).
655
+ * @param {string} [params.endingScanIndex] - receive address index to end scanning at. default to startingScanIndex + 20 (exclusive).
656
+ */
657
+ async recoverConsolidations(params) {
658
+ const isUnsignedConsolidations = (0, sdk_core_1.getIsUnsignedSweep)(params);
659
+ const startIdx = params.startingScanIndex || 1;
660
+ const endIdx = params.endingScanIndex || startIdx + exports.DEFAULT_SCAN_FACTOR;
661
+ if (startIdx < 1 || endIdx <= startIdx || endIdx - startIdx > 10 * exports.DEFAULT_SCAN_FACTOR) {
662
+ throw new Error(`Invalid starting or ending index to scan for addresses. startingScanIndex: ${startIdx}, endingScanIndex: ${endIdx}.`);
663
+ }
664
+ const keys = (0, sdk_core_1.getBip32Keys)(this.bitgo, params, { requireBitGoXpub: false });
665
+ const baseAddrHex = this.pubToHexAddress(this.xpubToUncompressedPub(params.bitgoKey));
666
+ const txnsBatch = [];
667
+ for (let i = startIdx; i < endIdx; i++) {
668
+ const derivationPath = `0/0/0/${i}`;
669
+ const userKey = keys[0].derivePath(derivationPath);
670
+ const userKeyXPub = userKey.neutered();
671
+ const receiveAddressHex = this.pubToHexAddress(this.xpubToUncompressedPub(userKeyXPub.toBase58()));
672
+ const receiveAddress = lib_1.Utils.getBase58AddressFromHex(receiveAddressHex);
673
+ // call the node to get our account balance
674
+ const accountInfo = await this.getAccountBalancesFromNode(receiveAddress);
675
+ if (accountInfo.data[0] && accountInfo.data[0].balance > exports.SAFE_TRON_TRANSACTION_FEE) {
676
+ let recoveryAmount = 0;
677
+ // Tokens must be consolidate before the native asset. First construct token txns
678
+ let rawTokenTxn;
679
+ // check for possible token recovery, recover the token provide by user
680
+ if (params.tokenContractAddress) {
681
+ if (accountInfo.data[0].balance > exports.SAFE_TRON_TOKEN_TRANSACTION_FEE && accountInfo.data[0].trc20[0]) {
682
+ const tokenDataArray = accountInfo.data[0].trc20;
683
+ for (const tokenData of tokenDataArray) {
684
+ const contractAddress = Object.keys(tokenData);
685
+ if (params.tokenContractAddress === contractAddress[0]) {
686
+ const amount = tokenData[contractAddress[0]];
687
+ const tokenContractAddrHex = lib_1.Utils.getHexAddressFromBase58Address(contractAddress[0]);
688
+ rawTokenTxn = (await this.getTriggerSmartContractTransaction(baseAddrHex, receiveAddressHex, amount, tokenContractAddrHex)).transaction;
689
+ recoveryAmount = parseInt(amount, 10);
690
+ break;
691
+ }
692
+ }
693
+ }
694
+ // build and sign token txns
695
+ if (rawTokenTxn) {
696
+ const addressInfo = {
697
+ address: receiveAddress,
698
+ chain: 0,
699
+ index: i,
700
+ };
701
+ const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(rawTokenTxn);
702
+ // Default expiry is 1 minute which is too short for recovery purposes
703
+ // extend the expiry to 1 day
704
+ txBuilder.extendValidTo(exports.RECOVER_TRANSACTION_EXPIRY);
705
+ // this tx should be enough to drop into a node
706
+ if (!isUnsignedConsolidations) {
707
+ const userPrv = this.xprvToCompressedPrv(userKey.toBase58());
708
+ // receive address only needs to be signed by user key
709
+ txBuilder.sign({ key: userPrv });
710
+ }
711
+ const tx = await txBuilder.build();
712
+ txnsBatch.push(this.formatForOfflineVault(tx, exports.SAFE_TRON_TOKEN_TRANSACTION_FEE, recoveryAmount, addressInfo));
713
+ }
714
+ }
715
+ else {
716
+ const addressBalance = accountInfo.data[0].balance;
717
+ const addressInfo = {
718
+ address: receiveAddress,
719
+ chain: 0,
720
+ index: i,
721
+ };
722
+ const recoveryAmount = addressBalance - exports.SAFE_TRON_TRANSACTION_FEE;
723
+ const buildTx = await this.getBuildTransaction(baseAddrHex, receiveAddressHex, recoveryAmount);
724
+ // construct our tx
725
+ const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(buildTx);
726
+ // Default expiry is 1 minute which is too short for recovery purposes
727
+ // extend the expiry to 1 day
728
+ txBuilder.extendValidTo(exports.RECOVER_TRANSACTION_EXPIRY);
729
+ if (!isUnsignedConsolidations) {
730
+ const userPrv = this.xprvToCompressedPrv(userKey.toBase58());
731
+ // receive address only needs to be signed by user key
732
+ txBuilder.sign({ key: userPrv });
733
+ }
734
+ const tx = await txBuilder.build();
735
+ txnsBatch.push(this.formatForOfflineVault(tx, exports.SAFE_TRON_TRANSACTION_FEE, recoveryAmount, addressInfo));
736
+ }
737
+ }
738
+ }
517
739
  return {
518
- tx: (await txBuilder.build()).toJson(),
519
- recoveryAmount: recoveryAmountMinusFees,
740
+ transactions: txnsBatch,
520
741
  };
521
742
  }
522
743
  /**
@@ -528,7 +749,7 @@ class Trx extends sdk_core_1.BaseCoin {
528
749
  if (!txHex || !params.feeInfo) {
529
750
  throw new Error('missing explain tx parameters');
530
751
  }
531
- const txBuilder = builder_1.getBuilder(this.getChain()).from(txHex);
752
+ const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(txHex);
532
753
  const tx = await txBuilder.build();
533
754
  const outputs = [
534
755
  {
@@ -551,13 +772,17 @@ class Trx extends sdk_core_1.BaseCoin {
551
772
  id: tx.id,
552
773
  outputs,
553
774
  outputAmount: outputs[0].amount,
554
- changeOutputs: [],
555
- changeAmount: '0',
775
+ changeOutputs: [], // account based does not use change outputs
776
+ changeAmount: '0', // account base does not make change
556
777
  fee: params.feeInfo,
557
778
  timestamp: tx.validFrom,
558
779
  expiration: tx.validTo,
559
780
  };
560
781
  }
782
+ /** @inheritDoc */
783
+ auditDecryptedKey(params) {
784
+ throw new sdk_core_1.MethodNotImplementedError();
785
+ }
561
786
  }
562
787
  exports.Trx = Trx;
563
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJ4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RyeC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0dBRUc7QUFDSCxxREFBdUM7QUFDdkMsbUNBQXFDO0FBRXJDLG1EQUF1RDtBQUN2RCxvREFBc0M7QUFDdEMsbURBbUI4QjtBQUM5QiwrQkFBeUQ7QUFDekQsMkNBQTJDO0FBRzlCLFFBQUEsaUNBQWlDLEdBQUcsR0FBRyxDQUFDO0FBc0RyRCxJQUFZLFNBR1g7QUFIRCxXQUFZLFNBQVM7SUFDbkIseUNBQUksQ0FBQTtJQUNKLGlEQUFRLENBQUE7QUFDVixDQUFDLEVBSFcsU0FBUyxHQUFULGlCQUFTLEtBQVQsaUJBQVMsUUFHcEI7QUFTRCxNQUFhLEdBQUksU0FBUSxtQkFBUTtJQUcvQixZQUFZLEtBQWdCLEVBQUUsV0FBdUM7UUFDbkUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWIsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUM7U0FDdkU7UUFFRCxJQUFJLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQztJQUNsQyxDQUFDO0lBRUQsUUFBUTtRQUNOLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7SUFDaEMsQ0FBQztJQUVELFNBQVM7UUFDUCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDO0lBQ2xDLENBQUM7SUFFRCxXQUFXO1FBQ1QsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQztJQUNwQyxDQUFDO0lBRUQsYUFBYTtRQUNYLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLHNCQUFzQjtRQUNwQixPQUFPLElBQUksQ0FBQztJ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NmsxIGZyb20gJ3NlY3AyNTZrMSc7XG5pbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBDb2luRmFtaWx5LCBCYXNlQ29pbiBhcyBTdGF0aWNzQmFzZUNvaW4gfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCB7IGJpcDMyLCBuZXR3b3JrcyB9IGZyb20gJ0BiaXRnby1iZXRhL3V0eG8tbGliJztcbmltcG9ydCAqIGFzIHJlcXVlc3QgZnJvbSAnc3VwZXJhZ2VudCc7XG5pbXBvcnQge1xuICBCYXNlQ29pbixcbiAgQml0R29CYXNlLFxuICBjb21tb24sXG4gIGdldEJpcDMyS2V5cyxcbiAgZ2V0SXNLcnNSZWNvdmVyeSxcbiAgZ2V0SXNVbnNpZ25lZFN3ZWVwLFxuICBLZXlQYWlyLFxuICBNZXRob2ROb3RJbXBsZW1lbnRlZEVycm9yLFxuICBQYXJzZWRUcmFuc2FjdGlvbixcbiAgUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFNpZ25lZFRyYW5zYWN0aW9uLFxuICBTaWduVHJhbnNhY3Rpb25PcHRpb25zLFxuICBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uLFxuICBUcmFuc2FjdGlvbkZlZSxcbiAgVHJhbnNhY3Rpb25QcmVidWlsZCBhcyBCYXNlVHJhbnNhY3Rpb25QcmVidWlsZCxcbiAgVHJhbnNhY3Rpb25SZWNpcGllbnQgYXMgUmVjaXBpZW50LFxuICBWZXJpZnlBZGRyZXNzT3B0aW9ucyxcbiAgVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zLFxufSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBJbnRlcmZhY2UsIFV0aWxzLCBXcmFwcGVkQnVpbGRlciB9IGZyb20gJy4vbGliJztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuL2xpYi9idWlsZGVyJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uUmVjZWlwdCB9IGZyb20gJy4vbGliL2lmYWNlJztcblxuZXhwb3J0IGNvbnN0IE1JTklNVU1fVFJPTl9NU0lHX1RSQU5TQUNUSU9OX0ZFRSA9IDFlNjtcblxuZXhwb3J0IGludGVyZmFjZSBUcm9uU2lnblRyYW5zYWN0aW9uT3B0aW9ucyBleHRlbmRzIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMge1xuICB0eFByZWJ1aWxkOiBUcmFuc2FjdGlvblByZWJ1aWxkO1xuICBwcnY6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUeEluZm8ge1xuICByZWNpcGllbnRzOiBSZWNpcGllbnRbXTtcbiAgZnJvbTogc3RyaW5nO1xuICB0eGlkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWRkcmVzc0luZm8ge1xuICBhZGRyZXNzOiBzdHJpbmc7XG4gIGNoYWluOiBudW1iZXI7XG4gIGluZGV4OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJvblRyYW5zYWN0aW9uRXhwbGFuYXRpb24gZXh0ZW5kcyBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uIHtcbiAgZXhwaXJhdGlvbjogbnVtYmVyO1xuICB0aW1lc3RhbXA6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2FjdGlvblByZWJ1aWxkIGV4dGVuZHMgQmFzZVRyYW5zYWN0aW9uUHJlYnVpbGQge1xuICB0eEhleDogc3RyaW5nO1xuICB0eEluZm86IFR4SW5mbztcbiAgYWRkcmVzc0luZm8/OiBBZGRyZXNzSW5mbztcbiAgZmVlSW5mbzogVHJhbnNhY3Rpb25GZWU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9ucyB7XG4gIHR4SGV4Pzogc3RyaW5nOyAvLyB0eEhleCBpcyBwb29ybHkgbmFtZWQgaGVyZTsgaXQgaXMganVzdCBhIHdyYXBwZWQgSlNPTiBvYmplY3RcbiAgaGFsZlNpZ25lZD86IHtcbiAgICB0eEhleDogc3RyaW5nOyAvLyB0eEhleCBpcyBwb29ybHkgbmFtZWQgaGVyZTsgaXQgaXMganVzdCBhIHdyYXBwZWQgSlNPTiBvYmplY3RcbiAgfTtcbiAgZmVlSW5mbzogVHJhbnNhY3Rpb25GZWU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVjb3ZlcnlPcHRpb25zIHtcbiAgdXNlcktleTogc3RyaW5nOyAvLyBCb3ggQVxuICBiYWNrdXBLZXk6IHN0cmluZzsgLy8gQm94IEJcbiAgYml0Z29LZXk6IHN0cmluZzsgLy8gQm94IEMgLSB0aGlzIGlzIGJpdGdvJ3MgeHB1YiBhbmQgd2lsbCBiZSB1c2VkIHRvIGRlcml2ZSB0aGVpciByb290IGFkZHJlc3NcbiAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogc3RyaW5nOyAvLyBiYXNlNTggYWRkcmVzc1xuICBrcnNQcm92aWRlcj86IHN0cmluZztcbiAgd2FsbGV0UGFzc3BocmFzZT86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWNvdmVyeVRyYW5zYWN0aW9uIHtcbiAgdHg/OiBUcmFuc2FjdGlvblByZWJ1aWxkO1xuICByZWNvdmVyeUFtb3VudD86IG51bWJlcjtcbiAgdG9rZW5UeHM/OiBUcmFuc2FjdGlvblJlY2VpcHRbXTtcbn1cblxuZXhwb3J0IGVudW0gTm9kZVR5cGVzIHtcbiAgRnVsbCxcbiAgU29saWRpdHksXG59XG5cbi8qKlxuICogVGhpcyBzdHJ1Y3R1cmUgaXMgbm90IGEgY29tcGxldGUgbW9kZWwgb2YgdGhlIEFjY291bnRSZXNwb25zZSBmcm9tIGEgbm9kZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBY2NvdW50UmVzcG9uc2Uge1xuICBkYXRhOiBbSW50ZXJmYWNlLkFjY291bnRJbmZvXTtcbn1cblxuZXhwb3J0IGNsYXNzIFRyeCBleHRlbmRzIEJhc2VDb2luIHtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IF9zdGF0aWNzQ29pbjogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPjtcblxuICBjb25zdHJ1Y3RvcihiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pIHtcbiAgICBzdXBlcihiaXRnbyk7XG5cbiAgICBpZiAoIXN0YXRpY3NDb2luKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgcmVxdWlyZWQgY29uc3RydWN0b3IgcGFyYW1ldGVyIHN0YXRpY3NDb2luJyk7XG4gICAgfVxuXG4gICAgdGhpcy5fc3RhdGljc0NvaW4gPSBzdGF0aWNzQ29pbjtcbiAgfVxuXG4gIGdldENoYWluKCkge1xuICAgIHJldHVybiB0aGlzLl9zdGF0aWNzQ29pbi5uYW1lO1xuICB9XG5cbiAgZ2V0RmFtaWx5KCk6IENvaW5GYW1pbHkge1xuICAgIHJldHVybiB0aGlzLl9zdGF0aWNzQ29pbi5mYW1pbHk7XG4gIH1cblxuICBnZXRGdWxsTmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGljc0NvaW4uZnVsbE5hbWU7XG4gIH1cblxuICBnZXRCYXNlRmFjdG9yKCkge1xuICAgIHJldHVybiBNYXRoLnBvdygxMCwgdGhpcy5fc3RhdGljc0NvaW4uZGVjaW1hbFBsYWNlcyk7XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgdHJhbnNhY3Rpb25EYXRhQWxsb3dlZCgpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVJbnN0YW5jZShiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pOiBCYXNlQ29pbiB7XG4gICAgcmV0dXJuIG5ldyBUcngoYml0Z28sIHN0YXRpY3NDb2luKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGbGFnIGZvciBzZW5kaW5nIHZhbHVlIG9mIDBcbiAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgb2theSB0byBzZW5kIDAgdmFsdWUsIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgdmFsdWVsZXNzVHJhbnNmZXJBbGxvd2VkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIGFsbG93c0FjY291bnRDb25zb2xpZGF0aW9ucygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhpcyBpcyBhIHZhbGlkIGJhc2U1OCBvciBoZXggYWRkcmVzc1xuICAgKiBAcGFyYW0gYWRkcmVzc1xuICAgKi9cbiAgaXNWYWxpZEFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKCFhZGRyZXNzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmlzVmFsaWRIZXhBZGRyZXNzKGFkZHJlc3MpIHx8IFV0aWxzLmlzQmFzZTU4QWRkcmVzcyhhZGRyZXNzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhpcyBpcyBhIHZhbGlkIGhleCBhZGRyZXNzXG4gICAqIEBwYXJhbSBhZGRyZXNzIGhleCBhZGRyZXNzXG4gICAqL1xuICBpc1ZhbGlkSGV4QWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gYWRkcmVzcy5sZW5ndGggPT09IDQyICYmIC9eKDB4KT8oWzAtOWEtZl17Mn0pKyQvaS50ZXN0KGFkZHJlc3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIGVkMjU1MTkga2V5IHBhaXJcbiAgICpcbiAgICogQHBhcmFtIHNlZWRcbiAgICogQHJldHVybnMge09iamVjdH0gb2JqZWN0IHdpdGggZ2VuZXJhdGVkIHB1YiwgcHJ2XG4gICAqL1xuICBnZW5lcmF0ZUtleVBhaXIoc2VlZD86IEJ1ZmZlcik6IEtleVBhaXIge1xuICAgIC8vIFRPRE86IG1vdmUgdGhpcyBhbmQgYWRkcmVzcyBjcmVhdGlvbiBsb2dpYyB0byBhY2NvdW50LWxpYlxuICAgIGlmICghc2VlZCkge1xuICAgICAgLy8gQW4gZXh0ZW5kZWQgcHJpdmF0ZSBrZXkgaGFzIGJvdGggYSBub3JtYWwgMjU2IGJpdCBwcml2YXRlIGtleSBhbmQgYSAyNTYgYml0IGNoYWluIGNvZGUsIGJvdGggb2Ygd2hpY2ggbXVzdCBiZVxuICAgICAgLy8gcmFuZG9tLiA1MTIgYml0cyBpcyB0aGVyZWZvcmUgdGhlIG1heGltdW0gZW50cm9weSBhbmQgZ2l2ZXMgdXMgbWF4aW11bSBzZWN1cml0eSBhZ2FpbnN0IGNyYWNraW5nLlxuICAgICAgc2VlZCA9IHJhbmRvbUJ5dGVzKDUxMiAvIDgpO1xuICAgIH1cbiAgICBjb25zdCBoZCA9IGJpcDMyLmZyb21TZWVkKHNlZWQpO1xuICAgIHJldHVybiB7XG4gICAgICBwdWI6IGhkLm5ldXRlcmVkKCkudG9CYXNlNTgoKSxcbiAgICAgIHBydjogaGQudG9CYXNlNTgoKSxcbiAgICB9O1xuICB9XG5cbiAgaXNWYWxpZFhwdWIoeHB1Yjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBiaXAzMi5mcm9tQmFzZTU4KHhwdWIpLmlzTmV1dGVyZWQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgaXNWYWxpZFB1YihwdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmlzVmFsaWRYcHViKHB1YikpIHtcbiAgICAgIC8vIHhwdWJzIGNhbiBiZSBjb252ZXJ0ZWQgaW50byByZWd1bGFyIHB1YnMsIHNvIHRlY2huaWNhbGx5IGl0IGlzIGEgdmFsaWQgcHViXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoJ14wNFthLXpBLVowLTldezEyOH0kJykudGVzdChwdWIpO1xuICB9XG5cbiAgYXN5bmMgcGFyc2VUcmFuc2FjdGlvbihwYXJhbXM6IFBhcnNlVHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxQYXJzZWRUcmFuc2FjdGlvbj4ge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGFzeW5jIGlzV2FsbGV0QWRkcmVzcyhwYXJhbXM6IFZlcmlmeUFkZHJlc3NPcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdGhyb3cgbmV3IE1ldGhvZE5vdEltcGxlbWVudGVkRXJyb3IoKTtcbiAgfVxuXG4gIGFzeW5jIHZlcmlmeVRyYW5zYWN0aW9uKHBhcmFtczogVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogRGVyaXZlIGEgdXNlciBrZXkgdXNpbmcgdGhlIGNoYWluIHBhdGggb2YgdGhlIGFkZHJlc3NcbiAgICogQHBhcmFtIGtleVxuICAgKiBAcGFyYW0gcGF0aFxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBkZXJpdmVkIHByaXZhdGUga2V5XG4gICAqL1xuICBkZXJpdmVLZXlXaXRoUGF0aCh7IGtleSwgcGF0aCB9OiB7IGtleTogc3RyaW5nOyBwYXRoOiBzdHJpbmcgfSk6IHN0cmluZyB7XG4gICAgY29uc3Qga2V5Y2hhaW4gPSBiaXAzMi5mcm9tQmFzZTU4KGtleSk7XG4gICAgY29uc3QgZGVyaXZlZEtleU5vZGUgPSBrZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpO1xuICAgIHJldHVybiBkZXJpdmVkS2V5Tm9kZS50b0Jhc2U1OCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFzc2VtYmxlIGtleWNoYWluIGFuZCBoYWxmLXNpZ24gcHJlYnVpbHQgdHJhbnNhY3Rpb25cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcGFyYW0gcGFyYW1zLnR4UHJlYnVpbGQge09iamVjdH0gcHJlYnVpbGQgb2JqZWN0IHJldHVybmVkIGJ5IHBsYXRmb3JtXG4gICAqIEBwYXJhbSBwYXJhbXMucHJ2IHtTdHJpbmd9IHVzZXIgcHJ2XG4gICAqIEBwYXJhbSBwYXJhbXMud2FsbGV0LmFkZHJlc3NWZXJzaW9uIHtTdHJpbmd9IHRoaXMgaXMgdGhlIHZlcnNpb24gb2YgdGhlIEFsZ29yYW5kIG11bHRpc2lnIGFkZHJlc3MgZ2VuZXJhdGlvbiBmb3JtYXRcbiAgICogQHJldHVybnMgQmx1ZWJpcmQ8U2lnbmVkVHJhbnNhY3Rpb24+XG4gICAqL1xuICBhc3luYyBzaWduVHJhbnNhY3Rpb24ocGFyYW1zOiBUcm9uU2lnblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8U2lnbmVkVHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKHRoaXMuZ2V0Q2hhaW4oKSkuZnJvbShwYXJhbXMudHhQcmVidWlsZC50eEhleCk7XG5cbiAgICBsZXQga2V5O1xuICAgIGNvbnN0IHsgY2hhaW4sIGluZGV4IH0gPSBwYXJhbXMudHhQcmVidWlsZD8uYWRkcmVzc0luZm8gPz8geyBjaGFpbjogMCwgaW5kZXg6IDAgfTtcbiAgICBpZiAoY2hhaW4gPT09IDAgJiYgaW5kZXggPT09IDApIHtcbiAgICAgIGtleSA9IHBhcmFtcy5wcnY7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGRlcml2YXRpb25QYXRoID0gYDAvMC8ke2NoYWlufS8ke2luZGV4fWA7XG4gICAgICBrZXkgPSB0aGlzLmRlcml2ZUtleVdpdGhQYXRoKHsga2V5OiBwYXJhbXMucHJ2LCBwYXRoOiBkZXJpdmF0aW9uUGF0aCB9KTtcbiAgICB9XG4gICAgdHhCdWlsZGVyLnNpZ24oeyBrZXkgfSk7XG5cbiAgICBjb25zdCB0cmFuc2FjdGlvbiA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIGNvbnN0IHJlc3BvbnNlID0ge1xuICAgICAgdHhIZXg6IEpTT04uc3RyaW5naWZ5KHRyYW5zYWN0aW9uLnRvSnNvbigpKSxcbiAgICB9O1xuICAgIGlmICh0cmFuc2FjdGlvbi50b0pzb24oKS5zaWduYXR1cmUubGVuZ3RoID49IDIpIHtcbiAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9XG4gICAgLy8gSGFsZiBzaWduZWQgdHJhbnNhY3Rpb25cbiAgICByZXR1cm4ge1xuICAgICAgaGFsZlNpZ25lZDogcmVzcG9uc2UsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgaW5wdXQgaXMgdmFsaWQgc2VlZCBmb3IgdGhlIGNvaW5cbiAgICpcbiAgICogQHBhcmFtIHBydiAtIHRoZSBwcnYgdG8gYmUgY2hlY2tlZFxuICAgKi9cbiAgaXNWYWxpZFhwcnYocHJ2OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuICFiaXAzMi5mcm9tQmFzZTU4KHBydikuaXNOZXV0ZXJlZCgpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgbWVzc2FnZSB0byBzdHJpbmcgaW4gaGV4YWRlY2ltYWwgZm9ybWF0LlxuICAgKlxuICAgKiBAcGFyYW0gbWVzc2FnZSB7QnVmZmVyfFN0cmluZ30gbWVzc2FnZSB0byBzaWduXG4gICAqIEByZXR1cm4gdGhlIG1lc3NhZ2UgYXMgYSBoZXhhZGVjaW1hbCBzdHJpbmdcbiAgICovXG4gIHRvSGV4U3RyaW5nKG1lc3NhZ2U6IHN0cmluZyB8IEJ1ZmZlcik6IHN0cmluZyB7XG4gICAgaWYgKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKG1lc3NhZ2UpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICB9IGVsc2UgaWYgKEJ1ZmZlci5pc0J1ZmZlcihtZXNzYWdlKSkge1xuICAgICAgcmV0dXJuIG1lc3NhZ2UudG9TdHJpbmcoJ2hleCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgbWVzc2FnZWQgcGFzc2VkIHRvIHNpZ25NZXNzYWdlJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNpZ24gbWVzc2FnZSB3aXRoIHByaXZhdGUga2V5XG4gICAqXG4gICAqIEBwYXJhbSBrZXlcbiAgICogQHBhcmFtIG1lc3NhZ2VcbiAgICovXG4gIGFzeW5jIHNpZ25NZXNzYWdlKGtleTogS2V5UGFpciwgbWVzc2FnZTogc3RyaW5nIHwgQnVmZmVyKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICBjb25zdCB0b1NpZ24gPSB0aGlzLnRvSGV4U3RyaW5nKG1lc3NhZ2UpO1xuXG4gICAgbGV0IHBydjogc3RyaW5nIHwgdW5kZWZpbmVkID0ga2V5LnBydjtcbiAgICBpZiAodGhpcy5pc1ZhbGlkWHBydihwcnYpKSB7XG4gICAgICBwcnYgPSBiaXAzMi5mcm9tQmFzZTU4KHBydikucHJpdmF0ZUtleT8udG9TdHJpbmcoJ2hleCcpO1xuICAgIH1cblxuICAgIGlmICghcHJ2KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIHByaXZhdGVLZXknKTtcbiAgICB9XG4gICAgbGV0IHNpZyA9IFV0aWxzLnNpZ25TdHJpbmcodG9TaWduLCBwcnYsIHRydWUpO1xuXG4gICAgLy8gcmVtb3ZlIHRoZSBwcmVjZWRpbmcgMHhcbiAgICBzaWcgPSBzaWcucmVwbGFjZSgvXjB4LywgJycpO1xuXG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHNpZywgJ2hleCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGFuIHhwdWIgdG8gYSB1bmNvbXByZXNzZWQgcHViXG4gICAqIEBwYXJhbSB4cHViXG4gICAqL1xuICB4cHViVG9VbmNvbXByZXNzZWRQdWIoeHB1Yjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZFhwdWIoeHB1YikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCB4cHViJyk7XG4gICAgfVxuXG4gICAgY29uc3QgcHVibGljS2V5ID0gYmlwMzIuZnJvbUJhc2U1OCh4cHViLCBuZXR3b3Jrcy5iaXRjb2luKS5wdWJsaWNLZXk7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHNlY3AyNTZrMS5wdWJsaWNLZXlDb252ZXJ0KHB1YmxpY0tleSwgZmFsc2UgLyogY29tcHJlc3NlZCAqLykpLnRvU3RyaW5nKCdoZXgnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb2RpZnkgcHJlYnVpbGQgYmVmb3JlIHNlbmRpbmcgaXQgdG8gdGhlIHNlcnZlci5cbiAgICogQHBhcmFtIGJ1aWxkUGFyYW1zIFRoZSB3aGl0ZWxpc3RlZCBwYXJhbWV0ZXJzIGZvciB0aGlzIHByZWJ1aWxkXG4gICAqL1xuICBhc3luYyBnZXRFeHRyYVByZWJ1aWxkUGFyYW1zKGJ1aWxkUGFyYW1zOiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgIGlmIChidWlsZFBhcmFtcy5yZWNpcGllbnRzWzBdLmRhdGEgJiYgYnVpbGRQYXJhbXMuZmVlTGltaXQpIHtcbiAgICAgIGJ1aWxkUGFyYW1zLnJlY2lwaWVudHNbMF0uZmVlTGltaXQgPSBidWlsZFBhcmFtcy5mZWVMaW1pdDtcbiAgICB9XG4gIH1cblxuICBwdWJUb0hleEFkZHJlc3MocHViOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGJ5dGVBcnJheUFkZHIgPSBVdGlscy5nZXRCeXRlQXJyYXlGcm9tSGV4QWRkcmVzcyhwdWIpO1xuICAgIGNvbnN0IHJhd0FkZHJlc3MgPSBVdGlscy5nZXRSYXdBZGRyZXNzRnJvbVB1YktleShieXRlQXJyYXlBZGRyKTtcbiAgICByZXR1cm4gVXRpbHMuZ2V0SGV4QWRkcmVzc0Zyb21CeXRlQXJyYXkocmF3QWRkcmVzcyk7XG4gIH1cblxuICB4cHJ2VG9Db21wcmVzc2VkUHJ2KHhwcnY6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWRYcHJ2KHhwcnYpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgeHBydicpO1xuICAgIH1cblxuICAgIGNvbnN0IGhkTm9kZSA9IGJpcDMyLmZyb21CYXNlNTgoeHBydiwgbmV0d29ya3MuYml0Y29pbik7XG4gICAgaWYgKCFoZE5vZGUucHJpdmF0ZUtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBwcml2YXRlS2V5Jyk7XG4gICAgfVxuICAgIHJldHVybiBoZE5vZGUucHJpdmF0ZUtleS50b1N0cmluZygnaGV4Jyk7XG4gIH1cblxuICAvKipcbiAgICogTWFrZSBhIHF1ZXJ5IHRvIFRyb25ncmlkIGZvciBpbmZvcm1hdGlvbiBzdWNoIGFzIGJhbGFuY2UsIHRva2VuIGJhbGFuY2UsIHNvbGlkaXR5IGNhbGxzXG4gICAqIEBwYXJhbSBxdWVyeSB7T2JqZWN0fSBrZXktdmFsdWUgcGFpcnMgb2YgcGFyYW1ldGVycyB0byBhcHBlbmQgYWZ0ZXIgL2FwaVxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSByZXNwb25zZSBmcm9tIFRyb25ncmlkXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlY292ZXJ5UG9zdChxdWVyeTogeyBwYXRoOiBzdHJpbmc7IGpzb25PYmo6IGFueTsgbm9kZTogTm9kZVR5cGVzIH0pOiBQcm9taXNlPGFueT4ge1xuICAgIGxldCBub2RlVXJpID0gJyc7XG4gICAgc3dpdGNoIChxdWVyeS5ub2RlKSB7XG4gICAgICBjYXNlIE5vZGVUeXBlcy5GdWxsOlxuICAgICAgICBub2RlVXJpID0gY29tbW9uLkVudmlyb25tZW50c1t0aGlzLmJpdGdvLmdldEVudigpXS50cm9uTm9kZXMuZnVsbDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIE5vZGVUeXBlcy5Tb2xpZGl0eTpcbiAgICAgICAgbm9kZVVyaSA9IGNvbW1vbi5FbnZpcm9ubWVudHNbdGhpcy5iaXRnby5nZXRFbnYoKV0udHJvbk5vZGVzLnNvbGlkaXR5O1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbm9kZSB0eXBlIG5vdCBmb3VuZCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgcmVxdWVzdFxuICAgICAgLnBvc3Qobm9kZVVyaSArIHF1ZXJ5LnBhdGgpXG4gICAgICAudHlwZSgnanNvbicpXG4gICAgICAuc2VuZChxdWVyeS5qc29uT2JqKTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY291bGQgbm90IHJlYWNoIFRyb24gbm9kZScpO1xuICAgIH1cblxuICAgIC8vIHVuZm9ydHVuYXRlbHksIGl0IGRvZXNuJ3QgbG9vayBsaWtlIG1vc3QgVFJPTiBub2RlcyByZXR1cm4gdmFsaWQganNvbiBhcyBib2R5XG4gICAgcmV0dXJuIEpTT04ucGFyc2UocmVzcG9uc2UudGV4dCk7XG4gIH1cblxuICAvKipcbiAgICogTWFrZSBhIHF1ZXJ5IHRvIFRyb25ncmlkIGZvciBpbmZvcm1hdGlvbiBzdWNoIGFzIGJhbGFuY2UsIHRva2VuIGJhbGFuY2UsIHNvbGlkaXR5IGNhbGxzXG4gICAqIEBwYXJhbSBxdWVyeSB7T2JqZWN0fSBrZXktdmFsdWUgcGFpcnMgb2YgcGFyYW1ldGVycyB0byBhcHBlbmQgYWZ0ZXIgL2FwaVxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSByZXNwb25zZSBmcm9tIFRyb25ncmlkXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlY292ZXJ5R2V0KHF1ZXJ5OiB7IHBhdGg6IHN0cmluZzsganNvbk9iajogYW55OyBub2RlOiBOb2RlVHlwZXMgfSk6IFByb21pc2U8YW55PiB7XG4gICAgbGV0IG5vZGVVcmkgPSAnJztcbiAgICBzd2l0Y2ggKHF1ZXJ5Lm5vZGUpIHtcbiAgICAgIGNhc2UgTm9kZVR5cGVzLkZ1bGw6XG4gICAgICAgIG5vZGVVcmkgPSBjb21tb24uRW52aXJvbm1lbnRzW3RoaXMuYml0Z28uZ2V0RW52KCldLnRyb25Ob2Rlcy5mdWxsO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTm9kZVR5cGVzLlNvbGlkaXR5OlxuICAgICAgICBub2RlVXJpID0gY29tbW9uLkVudmlyb25tZW50c1t0aGlzLmJpdGdvLmdldEVudigpXS50cm9uTm9kZXMuc29saWRpdHk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub2RlIHR5cGUgbm90IGZvdW5kJyk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCByZXF1ZXN0XG4gICAgICAuZ2V0KG5vZGVVcmkgKyBxdWVyeS5wYXRoKVxuICAgICAgLnR5cGUoJ2pzb24nKVxuICAgICAgLnNlbmQocXVlcnkuanNvbk9iaik7XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvdWxkIG5vdCByZWFjaCBUcm9uIG5vZGUnKTtcbiAgICB9XG5cbiAgICAvLyB1bmZvcnR1bmF0ZWx5LCBpdCBkb2Vzbid0IGxvb2sgbGlrZSBtb3N0IFRST04gbm9kZXMgcmV0dXJuIHZhbGlkIGpzb24gYXMgYm9keVxuICAgIHJldHVybiBKU09OLnBhcnNlKHJlc3BvbnNlLnRleHQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFF1ZXJ5IG91ciBleHBsb3JlciBmb3IgdGhlIGJhbGFuY2Ugb2YgYW4gYWRkcmVzc1xuICAgKiBAcGFyYW0gYWRkcmVzcyB7U3RyaW5nfSB0aGUgYWRkcmVzcyBlbmNvZGVkIGluIGhleFxuICAgKiBAcmV0dXJucyB7QmlnTnVtYmVyfSBhZGRyZXNzIGJhbGFuY2VcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0QWNjb3VudEJhbGFuY2VzRnJvbU5vZGUoYWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTxBY2NvdW50UmVzcG9uc2U+IHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yZWNvdmVyeUdldCh7XG4gICAgICBwYXRoOiAnL3YxL2FjY291bnRzLycgKyBhZGRyZXNzLFxuICAgICAganNvbk9iajoge30sXG4gICAgICBub2RlOiBOb2RlVHlwZXMuRnVsbCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgb3VyIGJ1aWxkIHRyYW5zYWN0aW9uIGZyb20gYSBub2RlLlxuICAgKiBAcGFyYW0gdG9BZGRyIGhleC1lbmNvZGVkIGFkZHJlc3NcbiAgICogQHBhcmFtIGZyb21BZGRyIGhleC1lbmNvZGVkIGFkZHJlc3NcbiAgICogQHBhcmFtIGFtb3VudFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZXRCdWlsZFRyYW5zYWN0aW9uKFxuICAgIHRvQWRkcjogc3RyaW5nLFxuICAgIGZyb21BZGRyOiBzdHJpbmcsXG4gICAgYW1vdW50OiBudW1iZXJcbiAgKTogUHJvbWlzZTxJbnRlcmZhY2UuVHJhbnNhY3Rpb25SZWNlaXB0PiB7XG4gICAgLy8gb3VyIGFkZHJlc3NlcyBzaG91bGQgYmUgYmFzZTU4LCB3ZSdsbCBoYXZlIHRvIGVuY29kZSB0byBoZXhcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yZWNvdmVyeVBvc3Qoe1xuICAgICAgcGF0aDogJy93YWxsZXQvY3JlYXRldHJhbnNhY3Rpb24nLFxuICAgICAganNvbk9iajoge1xuICAgICAgICB0b19hZGRyZXNzOiB0b0FkZHIsXG4gICAgICAgIG93bmVyX2FkZHJlc3M6IGZyb21BZGRyLFxuICAgICAgICBhbW91bnQsXG4gICAgICB9LFxuICAgICAgbm9kZTogTm9kZVR5cGVzLkZ1bGwsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIG91ciBidWlsZCB0cmFuc2FjdGlvbiBmcm9tIGEgbm9kZS5cbiAgICogQHBhcmFtIHRvQWRkciBoZXgtZW5jb2RlZCBhZGRyZXNzXG4gICAqIEBwYXJhbSBmcm9tQWRkciBoZXgtZW5jb2RlZCBhZGRyZXNzXG4gICAqIEBwYXJhbSBhbW91bnRcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0VHJpZ2dlclNtYXJ0Q29udHJhY3RUcmFuc2FjdGlvbihcbiAgICB0b0FkZHI6IHN0cmluZyxcbiAgICBmcm9tQWRkcjogc3RyaW5nLFxuICAgIGFtb3VudDogc3RyaW5nLFxuICAgIGNvbnRyYWN0QWRkcjogc3RyaW5nXG4gICk6IFByb21pc2U8eyB0cmFuc2FjdGlvbjogSW50ZXJmYWNlLlRyYW5zYWN0aW9uUmVjZWlwdCB9PiB7XG4gICAgY29uc3QgZnVuY3Rpb25TZWxlY3RvciA9ICd0cmFuc2ZlcihhZGRyZXNzLHVpbnQyNTYpJztcbiAgICBjb25zdCB0eXBlcyA9IFsnYWRkcmVzcycsICd1aW50MjU2J107XG4gICAgY29uc3QgdmFsdWVzID0gW3RvQWRkciwgYW1vdW50XTtcbiAgICBjb25zdCBwYXJhbWV0ZXIgPSBVdGlscy5lbmNvZGVEYXRhUGFyYW1zKHR5cGVzLCB2YWx1ZXMsICcnKTtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yZWNvdmVyeVBvc3Qoe1xuICAgICAgcGF0aDogJy93YWxsZXQvdHJpZ2dlcnNtYXJ0Y29udHJhY3QnLFxuICAgICAganNvbk9iajoge1xuICAgICAgICBvd25lcl9hZGRyZXNzOiBmcm9tQWRkcixcbiAgICAgICAgY29udHJhY3RfYWRkcmVzczogY29udHJhY3RBZGRyLFxuICAgICAgICBmdW5jdGlvbl9zZWxlY3RvcjogZnVuY3Rpb25TZWxlY3RvcixcbiAgICAgICAgcGFyYW1ldGVyOiBwYXJhbWV0ZXIsXG4gICAgICAgIGZlZV9saW1pdDogMTAwMDAwMDAwLFxuICAgICAgfSxcbiAgICAgIG5vZGU6IE5vZGVUeXBlcy5GdWxsLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRocm93cyBhbiBlcnJvciBpZiBhbnkga2V5cyBpbiB0aGUgb3duZXJLZXlzIGNvbGxlY3Rpb24gZG9uJ3QgbWF0Y2ggdGhlIGtleXMgYXJyYXkgd2UgcGFzc1xuICAgKiBAcGFyYW0gb3duZXJLZXlzXG4gICAqIEBwYXJhbSBrZXlzXG4gICAqL1xuICBjaGVja1Blcm1pc3Npb25zKG93bmVyS2V5czogeyBhZGRyZXNzOiBzdHJpbmc7IHdlaWdodDogbnVtYmVyIH1bXSwga2V5czogc3RyaW5nW10pIHtcbiAgICBrZXlzID0ga2V5cy5tYXAoKGspID0+IGsudG9VcHBlckNhc2UoKSk7XG5cbiAgICBvd25lcktleXMubWFwKChrZXkpID0+IHtcbiAgICAgIGNvbnN0IGhleEtleSA9IGtleS5hZGRyZXNzLnRvVXBwZXJDYXNlKCk7XG4gICAgICBpZiAoIWtleXMuaW5jbHVkZXMoaGV4S2V5KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHB1YiBhZGRyZXNzICR7aGV4S2V5fSBub3QgZm91bmQgaW4gYWNjb3VudGApO1xuICAgICAgfVxuXG4gICAgICBpZiAoa2V5LndlaWdodCAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ293bmVyIHBlcm1pc3Npb24gaXMgaW52YWxpZCBmb3IgdGhpcyBzdHJ1Y3R1cmUnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYSBmdW5kcyByZWNvdmVyeSB0cmFuc2FjdGlvbiB3aXRob3V0IEJpdEdvLlxuICAgKiBXZSBuZWVkIHRvIGRvIHRocmVlIHF1ZXJpZXMgZHVyaW5nIHRoaXM6XG4gICAqIDEpIE5vZGUgcXVlcnkgLSBob3cgbXVjaCBtb25leSBpcyBpbiB0aGUgYWNjb3VudFxuICAgKiAyKSBCdWlsZCB0cmFuc2FjdGlvbiAtIGJ1aWxkIG91ciB0cmFuc2FjdGlvbiBmb3IgdGhlIGFtb3VudFxuICAgKiAzKSBTZW5kIHNpZ25lZCBidWlsZCAtIHNlbmQgb3VyIHNpZ25lZCBidWlsZCB0byBhIHB1YmxpYyBub2RlXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICovXG4gIGFzeW5jIHJlY292ZXIocGFyYW1zOiBSZWNvdmVyeU9wdGlvbnMpOiBQcm9taXNlPFJlY292ZXJ5VHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCBpc0tyc1JlY292ZXJ5ID0gZ2V0SXNLcnNSZWNvdmVyeShwYXJhbXMpO1xuICAgIGNvbnN0IGlzVW5zaWduZWRTd2VlcCA9IGdldElzVW5zaWduZWRTd2VlcChwYXJhbXMpO1xuXG4gICAgaWYgKCF0aGlzLmlzVmFsaWRBZGRyZXNzKHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRlc3RpbmF0aW9uIGFkZHJlc3MhJyk7XG4gICAgfVxuXG4gICAgLy8gZ2V0IG91ciB1c2VyLCBiYWNrdXAga2V5c1xuICAgIGNvbnN0IGtleXMgPSBnZXRCaXAzMktleXModGhpcy5iaXRnbywgcGFyYW1zLCB7IHJlcXVpcmVCaXRHb1hwdWI6IGZhbHNlIH0pO1xuXG4gICAgLy8gd2UgbmVlZCB0byBkZWNvZGUgb3VyIGJpdGdvS2V5IHRvIGEgYmFzZTU4IGFkZHJlc3NcbiAgICBjb25zdCBiaXRnb0hleEFkZHIgPSB0aGlzLnB1YlRvSGV4QWRkcmVzcyh0aGlzLnhwdWJUb1VuY29tcHJlc3NlZFB1YihwYXJhbXMuYml0Z29LZXkpKTtcbiAgICBjb25zdCByZWNvdmVyeUFkZHJlc3NIZXggPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3MocGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24pO1xuXG4gICAgLy8gY2FsbCB0aGUgbm9kZSB0byBnZXQgb3VyIGFjY291bnQgYmFsYW5jZVxuICAgIGNvbnN0IGFjY291bnQgPSBhd2FpdCB0aGlzLmdldEFjY291bnRCYWxhbmNlc0Zyb21Ob2RlKFV0aWxzLmdldEJhc2U1OEFkZHJlc3NGcm9tSGV4KGJpdGdvSGV4QWRkcikpO1xuICAgIGNvbnN0IHJlY292ZXJ5QW1vdW50ID0gYWNjb3VudC5kYXRhWzBdLmJhbGFuY2U7XG5cbiAgICBjb25zdCB1c2VyWFB1YiA9IGtleXNbMF0ubmV1dGVyZWQoKS50b0Jhc2U1OCgpO1xuICAgIGNvbnN0IHVzZXJYUHJ2ID0ga2V5c1swXS50b0Jhc2U1OCgpO1xuICAgIGNvbnN0IGJhY2t1cFhQdWIgPSBrZXlzWzFdLm5ldXRlcmVkKCkudG9CYXNlNTgoKTtcblxuICAgIC8vIGZpcnN0IGNvbnN0cnVjdCB0b2tlbiB0eG5zXG4gICAgY29uc3QgdG9rZW5UeG5zOiBhbnkgPSBbXTtcbiAgICBmb3IgKGNvbnN0IHRva2VuIG9mIGFjY291bnQuZGF0YVswXS50cmMyMCkge1xuICAgICAgLy8gbWFpbm5ldCB0b2tlbnNcbiAgICAgIGlmICh0b2tlbi5URWt4aVRlaG56U21TZTJYcXJCajR3MzJSVU45NjZyZHo4KSB7XG4gICAgICAgIGNvbnN0IGFtb3VudCA9IHRva2VuLlRFa3hpVGVobnpTbVNlMlhxckJqNHczMlJVTjk2NnJkejg7XG4gICAgICAgIGNvbnN0IGNvbnRyYWN0QWRkciA9IFV0aWxzLmdldEhleEFkZHJlc3NGcm9tQmFzZTU4QWRkcmVzcygnVEVreGlUZWhuelNtU2UyWHFyQmo0dzMyUlVOOTY2cmR6OCcpO1xuICAgICAgICB0b2tlblR4bnMucHVzaChcbiAgICAgICAgICAoYXdhaXQgdGhpcy5nZXRUcmlnZ2VyU21hcnRDb250cmFjdFRyYW5zYWN0aW9uKHJlY292ZXJ5QWRkcmVzc0hleCwgYml0Z29IZXhBZGRyLCBhbW91bnQsIGNvbnRyYWN0QWRkcikpXG4gICAgICAgICAgICAudHJhbnNhY3Rpb25cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAodG9rZW4uVFI3TkhxamVLUXhHVENpOHE4Wlk0cEw4b3RTemdqTGo2dCkge1xuICAgICAgICBjb25zdCBhbW91bnQgPSB0b2tlbi5UUjdOSHFqZUtReEdUQ2k4cThaWTRwTDhvdFN6Z2pMajZ0O1xuICAgICAgICBjb25zdCBjb250cmFjdEFkZHIgPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3MoJ1RSN05IcWplS1F4R1RDaThxOFpZNHBMOG90U3pnakxqNnQnKTtcbiAgICAgICAgdG9rZW5UeG5zLnB1c2goXG4gICAgICAgICAgKGF3YWl0IHRoaXMuZ2V0VHJpZ2dlclNtYXJ0Q29udHJhY3RUcmFuc2FjdGlvbihyZWNvdmVyeUFkZHJlc3NIZXgsIGJpdGdvSGV4QWRkciwgYW1vdW50LCBjb250cmFjdEFkZHIpKVxuICAgICAgICAgICAgLnRyYW5zYWN0aW9uXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gdGVzdG5ldCB0b2tlbnNcbiAgICAgIH0gZWxzZSBpZiAodG9rZW4uVFNkWndOcXBIb2Z6UDZCc0JLR1FVV2RCZUpwaExtRjZpZCkge1xuICAgICAgICBjb25zdCBhbW91bnQgPSB0b2tlbi5UU2Rad05xcEhvZnpQNkJzQktHUVVXZEJlSnBoTG1GNmlkO1xuICAgICAgICBjb25zdCBjb250cmFjdEFkZHIgPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3MoJ1RTZFp3TnFwSG9melA2QnNCS0dRVVdkQmVKcGhMbUY2aWQnKTtcbiAgICAgICAgdG9rZW5UeG5zLnB1c2goXG4gICAgICAgICAgKGF3YWl0IHRoaXMuZ2V0VHJpZ2dlclNtYXJ0Q29udHJhY3RUcmFuc2FjdGlvbihyZWNvdmVyeUFkZHJlc3NIZXgsIGJpdGdvSGV4QWRkciwgYW1vdW50LCBjb250cmFjdEFkZHIpKVxuICAgICAgICAgICAgLnRyYW5zYWN0aW9uXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKHRva2VuLlRHM1hYeUV4QmtQcDluemRhakRac296RXU0QmthU0pvenMpIHtcbiAgICAgICAgY29uc3QgYW1vdW50ID0gdG9rZW4uVEczWFh5RXhCa1BwOW56ZGFqRFpzb3pFdTRCa2FTSm96cztcbiAgICAgICAgY29uc3QgY29udHJhY3RBZGRyID0gVXRpbHMuZ2V0SGV4QWRkcmVzc0Zyb21CYXNlNThBZGRyZXNzKCdURzNYWHlFeEJrUHA5bnpkYWpEWnNvekV1NEJrYVNKb3pzJyk7XG4gICAgICAgIHRva2VuVHhucy5wdXNoKFxuICAgICAgICAgIChhd2FpdCB0aGlzLmdldFRyaWdnZXJTbWFydENvbnRyYWN0VHJhbnNhY3Rpb24ocmVjb3ZlcnlBZGRyZXNzSGV4LCBiaXRnb0hleEFkZHIsIGFtb3VudCwgY29udHJhY3RBZGRyKSlcbiAgICAgICAgICAgIC50cmFuc2FjdGlvblxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBjb25zdHJ1Y3QgdGhlIHR4IC1cbiAgICAvLyB0aGVyZSdzIGFuIGFzc3VtcHRpb24gaGVyZSBiZWluZyBtYWRlIGFib3V0IGZlZXM6IGZvciBhIHdhbGxldCB0aGF0IGhhc24ndCBiZWVuIHVzZWQgaW4gYXdoaWxlLCB0aGUgaW1wbGljYXRpb24gaXNcbiAgICAvLyBpdCBoYXMgbWF4aW11bSBiYW5kd2lkdGguIHRodXMsIGEgcmVjb3Zlcnkgc2hvdWxkIGNvc3QgdGhlIG1pbmltdW0gYW1vdW50ICgxZTYgc3VuIG9yIDEgVHJvbilcbiAgICBpZiAoTUlOSU1VTV9UUk9OX01TSUdfVFJBTlNBQ1RJT05fRkVFID4gcmVjb3ZlcnlBbW91bnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQW1vdW50IG9mIGZ1bmRzIHRvIHJlY292ZXIgd291bGRudCBiZSBhYmxlIHRvIGZ1bmQgYSBzZW5kJyk7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5SGV4QWRkcmVzc2VzID0gW1xuICAgICAgdGhpcy5wdWJUb0hleEFkZHJlc3ModGhpcy54cHViVG9VbmNvbXByZXNzZWRQdWIodXNlclhQdWIpKSxcbiAgICAgIHRoaXMucHViVG9IZXhBZGRyZXNzKHRoaXMueHB1YlRvVW5jb21wcmVzc2VkUHViKGJhY2t1cFhQdWIpKSxcbiAgICAgIGJpdGdvSGV4QWRkcixcbiAgICBdO1xuXG4gICAgLy8gcnVuIGNoZWNrcyB0byBlbnN1cmUgdGhpcyBpcyBhIHZhbGlkIHR4IC0gcGVybWlzc2lvbnMgbWF0Y2ggb3VyIHNpZ25lciBrZXlzXG4gICAgY29uc3Qgb3duZXJLZXlzOiB7IGFkZHJlc3M6IHN0cmluZzsgd2VpZ2h0OiBudW1iZXIgfVtdID0gW107XG4gICAgZm9yIChjb25zdCBrZXkgb2YgYWNjb3VudC5kYXRhWzBdLm93bmVyX3Blcm1pc3Npb24ua2V5cykge1xuICAgICAgY29uc3QgYWRkcmVzcyA9IFV0aWxzLmdldEhleEFkZHJlc3NGcm9tQmFzZTU4QWRkcmVzcyhrZXkuYWRkcmVzcyk7XG4gICAgICBjb25zdCB3ZWlnaHQgPSBrZXkud2VpZ2h0O1xuICAgICAgb3duZXJLZXlzLnB1c2goeyBhZGRyZXNzLCB3ZWlnaHQgfSk7XG4gICAgfVxuICAgIGNvbnN0IGFjdGl2ZVBlcm1pc3Npb25LZXlzOiB7IGFkZHJlc3M6IHN0cmluZzsgd2VpZ2h0OiBudW1iZXIgfVtdID0gW107XG4gICAgZm9yIChjb25zdCBrZXkgb2YgYWNjb3VudC5kYXRhWzBdLmFjdGl2ZV9wZXJtaXNzaW9uWzBdLmtleXMpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3Moa2V5LmFkZHJlc3MpO1xuICAgICAgY29uc3Qgd2VpZ2h0ID0ga2V5LndlaWdodDtcbiAgICAgIGFjdGl2ZVBlcm1pc3Npb25LZXlzLnB1c2goeyBhZGRyZXNzLCB3ZWlnaHQgfSk7XG4gICAgfVxuICAgIHRoaXMuY2hlY2tQZXJtaXNzaW9ucyhvd25lcktleXMsIGtleUhleEFkZHJlc3Nlcyk7XG4gICAgdGhpcy5jaGVja1Blcm1pc3Npb25zKGFjdGl2ZVBlcm1pc3Npb25LZXlzLCBrZXlIZXhBZGRyZXNzZXMpO1xuXG4gICAgLy8gYnVpbGQgYW5kIHNpZ24gdG9rZW4gdHhuc1xuICAgIGNvbnN0IGZpbmFsVG9rZW5UeHM6IGFueSA9IFtdO1xuICAgIGZvciAoY29uc3QgdG9rZW5UeG4gb2YgdG9rZW5UeG5zKSB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKHRoaXMuZ2V0Q2hhaW4oKSkuZnJvbSh0b2tlblR4bik7XG5cbiAgICAgIC8vIHRoaXMgdHggc2hvdWxkIGJlIGVub3VnaCB0byBkcm9wIGludG8gYSBub2RlXG4gICAgICBpZiAoaXNVbnNpZ25lZFN3ZWVwKSB7XG4gICAgICAgIGZpbmFsVG9rZW5UeHMucHVzaCgoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpLnRvSnNvbigpKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHVzZXJQcnYgPSB0aGlzLnhwcnZUb0NvbXByZXNzZWRQcnYodXNlclhQcnYpO1xuXG4gICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdXNlclBydiB9KTtcblxuICAgICAgLy8ga3JzIHJlY292ZXJpZXMgZG9uJ3QgZ2V0IHNpZ25lZFxuICAgICAgaWYgKCFpc0tyc1JlY292ZXJ5KSB7XG4gICAgICAgIGNvbnN0IGJhY2t1cFhQcnYgPSBrZXlzWzFdLnRvQmFzZTU4KCk7XG4gICAgICAgIGNvbnN0IGJhY2t1cFBydiA9IHRoaXMueHBydlRvQ29tcHJlc3NlZFBydihiYWNrdXBYUHJ2KTtcblxuICAgICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogYmFja3VwUHJ2IH0pO1xuICAgICAgfVxuICAgICAgZmluYWxUb2tlblR4cy5wdXNoKChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkudG9Kc29uKCkpO1xuICAgIH1cblxuICAgIC8vIHRva2VucyBtdXN0IGJlIHJlY292ZXJlZCBiZWZvcmUgdGhlIG5hdGl2ZSBhc3NldCwgc28gdGhhdCB0aGVyZSBpcyBzdWZmaWNpZW50IG9mIHRoZSBuYXRpdmUgYXNzZXQgdG8gY292ZXIgZmVlc1xuICAgIGlmIChmaW5hbFRva2VuVHhzLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRva2VuVHhzOiBmaW5hbFRva2VuVHhzLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCByZWNvdmVyeUFtb3VudE1pbnVzRmVlcyA9IHJlY292ZXJ5QW1vdW50IC0gTUlOSU1VTV9UUk9OX01TSUdfVFJBTlNBQ1RJT05fRkVFO1xuICAgIGNvbnN0IGJ1aWxkVHggPSBhd2FpdCB0aGlzLmdldEJ1aWxkVHJhbnNhY3Rpb24ocmVjb3ZlcnlBZGRyZXNzSGV4LCBiaXRnb0hleEFkZHIsIHJlY292ZXJ5QW1vdW50TWludXNGZWVzKTtcblxuICAgIC8vIGNvbnN0cnVjdCBvdXIgdHhcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSAoZ2V0QnVpbGRlcih0aGlzLmdldENoYWluKCkpIGFzIFdyYXBwZWRCdWlsZGVyKS5mcm9tKGJ1aWxkVHgpO1xuXG4gICAgLy8gdGhpcyB0eCBzaG91bGQgYmUgZW5vdWdoIHRvIGRyb3AgaW50byBhIG5vZGVcbiAgICBpZiAoaXNVbnNpZ25lZFN3ZWVwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eDogKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKS50b0pzb24oKSxcbiAgICAgICAgcmVjb3ZlcnlBbW91bnQ6IHJlY292ZXJ5QW1vdW50TWludXNGZWVzLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VyUHJ2ID0gdGhpcy54cHJ2VG9Db21wcmVzc2VkUHJ2KHVzZXJYUHJ2KTtcblxuICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB1c2VyUHJ2IH0pO1xuXG4gICAgLy8ga3JzIHJlY292ZXJpZXMgZG9uJ3QgZ2V0IHNpZ25lZFxuICAgIGlmICghaXNLcnNSZWNvdmVyeSkge1xuICAgICAgY29uc3QgYmFja3VwWFBydiA9IGtleXNbMV0udG9CYXNlNTgoKTtcbiAgICAgIGNvbnN0IGJhY2t1cFBydiA9IHRoaXMueHBydlRvQ29tcHJlc3NlZFBydihiYWNrdXBYUHJ2KTtcblxuICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IGJhY2t1cFBydiB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHg6IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkudG9Kc29uKCksXG4gICAgICByZWNvdmVyeUFtb3VudDogcmVjb3ZlcnlBbW91bnRNaW51c0ZlZXMsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBsYWluIGEgVHJvbiB0cmFuc2FjdGlvbiBmcm9tIHR4SGV4XG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICovXG4gIGFzeW5jIGV4cGxhaW5UcmFuc2FjdGlvbihwYXJhbXM6IEV4cGxhaW5UcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPFRyb25UcmFuc2FjdGlvbkV4cGxhbmF0aW9uPiB7XG4gICAgY29uc3QgdHhIZXggPSBwYXJhbXMudHhIZXggfHwgKHBhcmFtcy5oYWxmU2lnbmVkICYmIHBhcmFtcy5oYWxmU2lnbmVkLnR4SGV4KTtcbiAgICBpZiAoIXR4SGV4IHx8ICFwYXJhbXMuZmVlSW5mbykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGV4cGxhaW4gdHggcGFyYW1ldGVycycpO1xuICAgIH1cbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKHRoaXMuZ2V0Q2hhaW4oKSkuZnJvbSh0eEhleCk7XG4gICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICBjb25zdCBvdXRwdXRzID0gW1xuICAgICAge1xuICAgICAgICBhbW91bnQ6IHR4Lm91dHB1dHNbMF0udmFsdWUudG9TdHJpbmcoKSxcbiAgICAgICAgYWRkcmVzczogdHgub3V0cHV0c1swXS5hZGRyZXNzLCAvLyBTaG91bGQgdHVybiBpdCBpbnRvIGEgcmVhZGFibGUgZm9ybWF0LCBha2EgYmFzZTU4XG4gICAgICB9LFxuICAgIF07XG5cbiAgICBjb25zdCBkaXNwbGF5T3JkZXIgPSBbXG4gICAgICAnaWQnLFxuICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICdvdXRwdXRzJyxcbiAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICdmZWUnLFxuICAgICAgJ3RpbWVzdGFtcCcsXG4gICAgICAnZXhwaXJhdGlvbicsXG4gICAgXTtcblxuICAgIHJldHVybiB7XG4gICAgICBkaXNwbGF5T3JkZXIsXG4gICAgICBpZDogdHguaWQsXG4gICAgICBvdXRwdXRzLFxuICAgICAgb3V0cHV0QW1vdW50OiBvdXRwdXRzWzBdLmFtb3VudCxcbiAgICAgIGNoYW5nZU91dHB1dHM6IFtdLCAvLyBhY2NvdW50IGJhc2VkIGRvZXMgbm90IHVzZSBjaGFuZ2Ugb3V0cHV0c1xuICAgICAgY2hhbmdlQW1vdW50OiAnMCcsIC8vIGFjY291bnQgYmFzZSBkb2VzIG5vdCBtYWtlIGNoYW5nZVxuICAgICAgZmVlOiBwYXJhbXMuZmVlSW5mbyxcbiAgICAgIHRpbWVzdGFtcDogdHgudmFsaWRGcm9tLFxuICAgICAgZXhwaXJhdGlvbjogdHgudmFsaWRUbyxcbiAgICB9O1xuICB9XG59XG4iXX0=
788
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJ4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RyeC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7R0FFRztBQUNILHFEQUF1QztBQUN2QyxtQ0FBcUM7QUFFckMscURBQThDO0FBQzlDLG9EQUFzQztBQUN0QyxtREF1QjhCO0FBQzlCLCtCQUF5RDtBQUV6RCwyQ0FBMkM7QUFDM0MsbUNBQWdEO0FBRW5DLFFBQUEsaUNBQWlDLEdBQUcsR0FBRyxDQUFDO0FBQ3hDLFFBQUEseUJBQXlCLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLHdFQUF3RTtBQUMvRyxRQUFBLCtCQUErQixHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyx3RUFBd0U7QUFDckgsUUFBQSwwQkFBMEIsR0FBRyxRQUFRLENBQUMsQ0FBQyxVQUFVO0FBQ2pELFFBQUEsbUJBQW1CLEdBQUcsRUFBRSxDQUFDLENBQUMsd0RBQXdEO0FBOEUvRixJQUFZLFNBR1g7QUFIRCxXQUFZLFNBQVM7SUFDbkIseUNBQUksQ0FBQTtJQUNKLGlEQUFRLENBQUE7QUFDVixDQUFDLEVBSFcsU0FBUyx5QkFBVCxTQUFTLFFBR3BCO0FBU0QsTUFBYSxHQUFJLFNBQVEsbUJBQVE7SUFHL0IsWUFBWSxLQUFnQixFQUFFLFdBQXVDO1FBQ25FLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUViLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNqQixNQUFNLElBQUksS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUVELElBQUksQ0FBQyxZQUFZLEdBQUcsV0FBVyxDQUFDO0lBQ2xDLENBQUM7SUFFRCxRQUFRO1FBQ04sT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQztJQUNoQyxDQUFDO0lBRUQsU0FBUztRQUNQLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxN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QUMsQ0FBQyxPQUFPLEVBQUUsb0RBQW9EO2FBQ3JGO1NBQ0YsQ0FBQztRQUVGLE1BQU0sWUFBWSxHQUFHO1lBQ25CLElBQUk7WUFDSixjQUFjO1lBQ2QsY0FBYztZQUNkLFNBQVM7WUFDVCxlQUFlO1lBQ2YsS0FBSztZQUNMLFdBQVc7WUFDWCxZQUFZO1NBQ2IsQ0FBQztRQUVGLE9BQU87WUFDTCxZQUFZO1lBQ1osRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFO1lBQ1QsT0FBTztZQUNQLFlBQVksRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTTtZQUMvQixhQUFhLEVBQUUsRUFBRSxFQUFFLDRDQUE0QztZQUMvRCxZQUFZLEVBQUUsR0FBRyxFQUFFLG9DQUFvQztZQUN2RCxHQUFHLEVBQUUsTUFBTSxDQUFDLE9BQU87WUFDbkIsU0FBUyxFQUFFLEVBQUUsQ0FBQyxTQUFTO1lBQ3ZCLFVBQVUsRUFBRSxFQUFFLENBQUMsT0FBTztTQUN2QixDQUFDO0lBQ0osQ0FBQztJQUVELGtCQUFrQjtJQUNsQixpQkFBaUIsQ0FBQyxNQUErQjtRQUMvQyxNQUFNLElBQUksb0NBQXlCLEVBQUUsQ0FBQztJQUN4QyxDQUFDO0NBQ0Y7QUExMUJELGtCQTAxQkMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBwcmV0dGllclxuICovXG5pbXBvcnQgKiBhcyBzZWNwMjU2azEgZnJvbSAnc2VjcDI1NmsxJztcbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCB7IENvaW5GYW1pbHksIEJhc2VDb2luIGFzIFN0YXRpY3NCYXNlQ29pbiB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0IHsgYmlwMzIgfSBmcm9tICdAYml0Z28tYmV0YS9zZWNwMjU2azEnO1xuaW1wb3J0ICogYXMgcmVxdWVzdCBmcm9tICdzdXBlcmFnZW50JztcbmltcG9ydCB7XG4gIEJhc2VDb2luLFxuICBCaXRHb0Jhc2UsXG4gIGNvbW1vbixcbiAgZ2V0QmlwMzJLZXlzLFxuICBnZXRJc0tyc1JlY292ZXJ5LFxuICBnZXRJc1Vuc2lnbmVkU3dlZXAsXG4gIEtleVBhaXIsXG4gIE1ldGhvZE5vdEltcGxlbWVudGVkRXJyb3IsXG4gIFBhcnNlZFRyYW5zYWN0aW9uLFxuICBQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgU2lnbmVkVHJhbnNhY3Rpb24sXG4gIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFRyYW5zYWN0aW9uRXhwbGFuYXRpb24sXG4gIFRyYW5zYWN0aW9uRmVlLFxuICBUcmFuc2FjdGlvblByZWJ1aWxkIGFzIEJhc2VUcmFuc2FjdGlvblByZWJ1aWxkLFxuICBUcmFuc2FjdGlvblJlY2lwaWVudCBhcyBSZWNpcGllbnQsXG4gIFZlcmlmeUFkZHJlc3NPcHRpb25zLFxuICBWZXJpZnlUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIEJhc2VUcmFuc2FjdGlvbixcbiAgTXVsdGlzaWdUeXBlLFxuICBtdWx0aXNpZ1R5cGVzLFxuICBBdWRpdERlY3J5cHRlZEtleVBhcmFtcyxcbn0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgSW50ZXJmYWNlLCBVdGlscywgV3JhcHBlZEJ1aWxkZXIgfSBmcm9tICcuL2xpYic7XG5pbXBvcnQgeyBWYWx1ZUZpZWxkcywgVHJhbnNhY3Rpb25SZWNlaXB0IH0gZnJvbSAnLi9saWIvaWZhY2UnO1xuaW1wb3J0IHsgZ2V0QnVpbGRlciB9IGZyb20gJy4vbGliL2J1aWxkZXInO1xuaW1wb3J0IHsgaXNJbnRlZ2VyLCBpc1VuZGVmaW5lZCB9IGZyb20gJ2xvZGFzaCc7XG5cbmV4cG9ydCBjb25zdCBNSU5JTVVNX1RST05fTVNJR19UUkFOU0FDVElPTl9GRUUgPSAxZTY7XG5leHBvcnQgY29uc3QgU0FGRV9UUk9OX1RSQU5TQUNUSU9OX0ZFRSA9IDIuMSAqIDFlNjsgLy8gVFJPTiBmb3VuZGF0aW9uIHJlY29tbWVuZHMgMi4xIFRSWCBhcyBmZWVzIGZvciBndWFyYW50ZWVkIHRyYW5zYWN0aW9uXG5leHBvcnQgY29uc3QgU0FGRV9UUk9OX1RPS0VOX1RSQU5TQUNUSU9OX0ZFRSA9IDEwMCAqIDFlNjsgLy8gVFJPTiBmb3VuZGF0aW9uIHJlY29tbWVuZHMgMTAwIFRSWCBhcyBmZWVzIGZvciBndWFyYW50ZWVkIHRyYW5zYWN0aW9uXG5leHBvcnQgY29uc3QgUkVDT1ZFUl9UUkFOU0FDVElPTl9FWFBJUlkgPSA4NjQwMDAwMDsgLy8gMjQgaG91clxuZXhwb3J0IGNvbnN0IERFRkFVTFRfU0NBTl9GQUNUT1IgPSAyMDsgLy8gZGVmYXVsdCBudW1iZXIgb2YgcmVjZWl2ZSBhZGRyZXNzZXMgdG8gc2NhbiBmb3IgZnVuZHNcblxuZXhwb3J0IGludGVyZmFjZSBUcm9uU2lnblRyYW5zYWN0aW9uT3B0aW9ucyBleHRlbmRzIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMge1xuICB0eFByZWJ1aWxkOiBUcmFuc2FjdGlvblByZWJ1aWxkO1xuICBwcnY6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUeEluZm8ge1xuICByZWNpcGllbnRzOiBSZWNpcGllbnRbXTtcbiAgZnJvbTogc3RyaW5nO1xuICB0eGlkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWRkcmVzc0luZm8ge1xuICBhZGRyZXNzOiBzdHJpbmc7XG4gIGNoYWluOiBudW1iZXI7XG4gIGluZGV4OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJvblRyYW5zYWN0aW9uRXhwbGFuYXRpb24gZXh0ZW5kcyBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uIHtcbiAgZXhwaXJhdGlvbjogbnVtYmVyO1xuICB0aW1lc3RhbXA6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2FjdGlvblByZWJ1aWxkIGV4dGVuZHMgQmFzZVRyYW5zYWN0aW9uUHJlYnVpbGQge1xuICB0eEhleDogc3RyaW5nO1xuICB0eEluZm86IFR4SW5mbztcbiAgYWRkcmVzc0luZm8/OiBBZGRyZXNzSW5mbztcbiAgZmVlSW5mbzogVHJhbnNhY3Rpb25GZWU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9ucyB7XG4gIHR4SGV4Pzogc3RyaW5nOyAvLyB0eEhleCBpcyBwb29ybHkgbmFtZWQgaGVyZTsgaXQgaXMganVzdCBhIHdyYXBwZWQgSlNPTiBvYmplY3RcbiAgaGFsZlNpZ25lZD86IHtcbiAgICB0eEhleDogc3RyaW5nOyAvLyB0eEhleCBpcyBwb29ybHkgbmFtZWQgaGVyZTsgaXQgaXMganVzdCBhIHdyYXBwZWQgSlNPTiBvYmplY3RcbiAgfTtcbiAgZmVlSW5mbzogVHJhbnNhY3Rpb25GZWU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVjb3ZlcnlPcHRpb25zIHtcbiAgdXNlcktleTogc3RyaW5nOyAvLyBCb3ggQVxuICBiYWNrdXBLZXk6IHN0cmluZzsgLy8gQm94IEJcbiAgYml0Z29LZXk6IHN0cmluZzsgLy8gQm94IEMgLSB0aGlzIGlzIGJpdGdvJ3MgeHB1YiBhbmQgd2lsbCBiZSB1c2VkIHRvIGRlcml2ZSB0aGVpciByb290IGFkZHJlc3NcbiAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogc3RyaW5nOyAvLyBiYXNlNTggYWRkcmVzc1xuICBrcnNQcm92aWRlcj86IHN0cmluZztcbiAgdG9rZW5Db250cmFjdEFkZHJlc3M/OiBzdHJpbmc7XG4gIHdhbGxldFBhc3NwaHJhc2U/OiBzdHJpbmc7XG4gIHN0YXJ0aW5nU2NhbkluZGV4PzogbnVtYmVyO1xuICBzY2FuPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbnNvbGlkYXRpb25SZWNvdmVyeU9wdGlvbnMge1xuICB1c2VyS2V5OiBzdHJpbmc7XG4gIGJhY2t1cEtleTogc3RyaW5nO1xuICBiaXRnb0tleTogc3RyaW5nO1xuICB0b2tlbkNvbnRyYWN0QWRkcmVzcz86IHN0cmluZztcbiAgc3RhcnRpbmdTY2FuSW5kZXg/OiBudW1iZXI7IC8vIGRlZmF1bHQgdG8gMSAoaW5jbHVzaXZlKVxuICBlbmRpbmdTY2FuSW5kZXg/OiBudW1iZXI7IC8vIGRlZmF1bHQgdG8gc3RhcnRpbmdTY2FuSW5kZXggKyAyMCAoZXhjbHVzaXZlKVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbnNvbGlkYXRpb25SZWNvdmVyeUJhdGNoIHtcbiAgdHJhbnNhY3Rpb25zOiBSZWNvdmVyeVRyYW5zYWN0aW9uW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmVlSW5mbyB7XG4gIGZlZTogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlY292ZXJ5VHJhbnNhY3Rpb24ge1xuICB0eEhleD86IHN0cmluZztcbiAgZmVlSW5mbz86IEZlZUluZm87XG4gIGNvaW4/OiBzdHJpbmc7XG4gIHR4PzogVHJhbnNhY3Rpb25QcmVidWlsZDtcbiAgcmVjb3ZlcnlBbW91bnQ/OiBudW1iZXI7XG4gIHRva2VuVHhzPzogVHJhbnNhY3Rpb25SZWNlaXB0W107XG4gIGFkZHJlc3NJbmZvPzogQWRkcmVzc0luZm87XG59XG5cbmV4cG9ydCBlbnVtIE5vZGVUeXBlcyB7XG4gIEZ1bGwsXG4gIFNvbGlkaXR5LFxufVxuXG4vKipcbiAqIFRoaXMgc3RydWN0dXJlIGlzIG5vdCBhIGNvbXBsZXRlIG1vZGVsIG9mIHRoZSBBY2NvdW50UmVzcG9uc2UgZnJvbSBhIG5vZGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWNjb3VudFJlc3BvbnNlIHtcbiAgZGF0YTogW0ludGVyZmFjZS5BY2NvdW50SW5mb107XG59XG5cbmV4cG9ydCBjbGFzcyBUcnggZXh0ZW5kcyBCYXNlQ29pbiB7XG4gIHByb3RlY3RlZCByZWFkb25seSBfc3RhdGljc0NvaW46IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj47XG5cbiAgY29uc3RydWN0b3IoYml0Z286IEJpdEdvQmFzZSwgc3RhdGljc0NvaW4/OiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+KSB7XG4gICAgc3VwZXIoYml0Z28pO1xuXG4gICAgaWYgKCFzdGF0aWNzQ29pbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHJlcXVpcmVkIGNvbnN0cnVjdG9yIHBhcmFtZXRlciBzdGF0aWNzQ29pbicpO1xuICAgIH1cblxuICAgIHRoaXMuX3N0YXRpY3NDb2luID0gc3RhdGljc0NvaW47XG4gIH1cblxuICBnZXRDaGFpbigpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGljc0NvaW4ubmFtZTtcbiAgfVxuXG4gIGdldEZhbWlseSgpOiBDb2luRmFtaWx5IHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGljc0NvaW4uZmFtaWx5O1xuICB9XG5cbiAgZ2V0RnVsbE5hbWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLmZ1bGxOYW1lO1xuICB9XG5cbiAgZ2V0QmFzZUZhY3RvcigpIHtcbiAgICByZXR1cm4gTWF0aC5wb3coMTAsIHRoaXMuX3N0YXRpY3NDb2luLmRlY2ltYWxQbGFjZXMpO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIHRyYW5zYWN0aW9uRGF0YUFsbG93ZWQoKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKiogaW5oZXJpdGVkIGRvYyAqL1xuICBnZXREZWZhdWx0TXVsdGlzaWdUeXBlKCk6IE11bHRpc2lnVHlwZSB7XG4gICAgcmV0dXJuIG11bHRpc2lnVHlwZXMub25jaGFpbjtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVJbnN0YW5jZShiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pOiBCYXNlQ29pbiB7XG4gICAgcmV0dXJuIG5ldyBUcngoYml0Z28sIHN0YXRpY3NDb2luKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGbGFnIGZvciBzZW5kaW5nIHZhbHVlIG9mIDBcbiAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgb2theSB0byBzZW5kIDAgdmFsdWUsIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgdmFsdWVsZXNzVHJhbnNmZXJBbGxvd2VkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIGFsbG93c0FjY291bnRDb25zb2xpZGF0aW9ucygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhpcyBpcyBhIHZhbGlkIGJhc2U1OFxuICAgKiBAcGFyYW0gYWRkcmVzc1xuICAgKi9cbiAgaXNWYWxpZEFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKCFhZGRyZXNzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIFV0aWxzLmlzQmFzZTU4QWRkcmVzcyhhZGRyZXNzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhpcyBpcyBhIHZhbGlkIGhleCBhZGRyZXNzXG4gICAqIEBwYXJhbSBhZGRyZXNzIGhleCBhZGRyZXNzXG4gICAqL1xuICBpc1ZhbGlkSGV4QWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gL140MVswLTlhLWZdezQwfSQvaS50ZXN0KGFkZHJlc3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIGVkMjU1MTkga2V5IHBhaXJcbiAgICpcbiAgICogQHBhcmFtIHNlZWRcbiAgICogQHJldHVybnMge09iamVjdH0gb2JqZWN0IHdpdGggZ2VuZXJhdGVkIHB1YiwgcHJ2XG4gICAqL1xuICBnZW5lcmF0ZUtleVBhaXIoc2VlZD86IEJ1ZmZlcik6IEtleVBhaXIge1xuICAgIC8vIFRPRE86IG1vdmUgdGhpcyBhbmQgYWRkcmVzcyBjcmVhdGlvbiBsb2dpYyB0byBhY2NvdW50LWxpYlxuICAgIGlmICghc2VlZCkge1xuICAgICAgLy8gQW4gZXh0ZW5kZWQgcHJpdmF0ZSBrZXkgaGFzIGJvdGggYSBub3JtYWwgMjU2IGJpdCBwcml2YXRlIGtleSBhbmQgYSAyNTYgYml0IGNoYWluIGNvZGUsIGJvdGggb2Ygd2hpY2ggbXVzdCBiZVxuICAgICAgLy8gcmFuZG9tLiA1MTIgYml0cyBpcyB0aGVyZWZvcmUgdGhlIG1heGltdW0gZW50cm9weSBhbmQgZ2l2ZXMgdXMgbWF4aW11bSBzZWN1cml0eSBhZ2FpbnN0IGNyYWNraW5nLlxuICAgICAgc2VlZCA9IHJhbmRvbUJ5dGVzKDUxMiAvIDgpO1xuICAgIH1cbiAgICBjb25zdCBoZCA9IGJpcDMyLmZyb21TZWVkKHNlZWQpO1xuICAgIHJldHVybiB7XG4gICAgICBwdWI6IGhkLm5ldXRlcmVkKCkudG9CYXNlNTgoKSxcbiAgICAgIHBydjogaGQudG9CYXNlNTgoKSxcbiAgICB9O1xuICB9XG5cbiAgaXNWYWxpZFhwdWIoeHB1Yjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBiaXAzMi5mcm9tQmFzZTU4KHhwdWIpLmlzTmV1dGVyZWQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgaXNWYWxpZFB1YihwdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmlzVmFsaWRYcHViKHB1YikpIHtcbiAgICAgIC8vIHhwdWJzIGNhbiBiZSBjb252ZXJ0ZWQgaW50byByZWd1bGFyIHB1YnMsIHNvIHRlY2huaWNhbGx5IGl0IGlzIGEgdmFsaWQgcHViXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoJ14wNFthLXpBLVowLTldezEyOH0kJykudGVzdChwdWIpO1xuICB9XG5cbiAgYXN5bmMgcGFyc2VUcmFuc2FjdGlvbihwYXJhbXM6IFBhcnNlVHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxQYXJzZWRUcmFuc2FjdGlvbj4ge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGFzeW5jIGlzV2FsbGV0QWRkcmVzcyhwYXJhbXM6IFZlcmlmeUFkZHJlc3NPcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdGhyb3cgbmV3IE1ldGhvZE5vdEltcGxlbWVudGVkRXJyb3IoKTtcbiAgfVxuXG4gIGFzeW5jIHZlcmlmeVRyYW5zYWN0aW9uKHBhcmFtczogVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgeyB0eFBhcmFtcywgdHhQcmVidWlsZCB9ID0gcGFyYW1zO1xuXG4gICAgaWYgKCF0eFBhcmFtcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHR4UGFyYW1zJyk7XG4gICAgfVxuXG4gICAgaWYgKCF0eFByZWJ1aWxkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgdHhQcmVidWlsZCcpO1xuICAgIH1cblxuICAgIGlmICghdHhQcmVidWlsZC50eEhleCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHR4SGV4IGluIHR4UHJlYnVpbGQnKTtcbiAgICB9XG5cbiAgICBjb25zdCByYXdUeCA9IHR4UHJlYnVpbGQudHhIZXg7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcih0aGlzLmdldENoYWluKCkpLmZyb20ocmF3VHgpO1xuICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG5cbiAgICBpZiAoIXR4SnNvbi5yYXdfZGF0YSB8fCAhdHhKc29uLnJhd19kYXRhLmNvbnRyYWN0IHx8IHR4SnNvbi5yYXdfZGF0YS5jb250cmFjdC5sZW5ndGggIT09IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTnVtYmVyIG9mIGNvbnRyYWN0cyBpcyBncmVhdGVyIHRoYW4gMS4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb250cmFjdCA9IHR4SnNvbi5yYXdfZGF0YS5jb250cmFjdFswXTtcblxuICAgIGlmIChjb250cmFjdC50eXBlID09PSAnVHJhbnNmZXJDb250cmFjdCcpIHtcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlVHJhbnNmZXJDb250cmFjdChjb250cmFjdCwgdHhQYXJhbXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgVHJhbnNmZXIgY29udHJhY3QgKG5hdGl2ZSBUUlggdHJhbnNmZXIpXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlVHJhbnNmZXJDb250cmFjdChjb250cmFjdDogYW55LCB0eFBhcmFtczogYW55KTogYm9vbGVhbiB7XG4gICAgaWYgKCEoJ3BhcmFtZXRlcicgaW4gY29udHJhY3QpIHx8ICFjb250cmFjdC5wYXJhbWV0ZXI/LnZhbHVlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgVHJhbnNmZXIgY29udHJhY3Qgc3RydWN0dXJlJyk7XG4gICAgfVxuXG4gICAgY29uc3QgdmFsdWUgPSBjb250cmFjdC5wYXJhbWV0ZXIudmFsdWUgYXMgVmFsdWVGaWVsZHM7XG5cbiAgICAvLyBWYWxpZGF0ZSBhbW91bnRcbiAgICBpZiAoIXZhbHVlLmFtb3VudCB8fCB2YWx1ZS5hbW91bnQgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdHJhbnNmZXIgYW1vdW50Jyk7XG4gICAgfVxuXG4gICAgLy8gSWYgdHhQYXJhbXMgaGFzIHJlY2lwaWVudHMsIHZhbGlkYXRlIGFnYWluc3QgZXhwZWN0ZWQgdmFsdWVzXG4gICAgaWYgKHR4UGFyYW1zLnJlY2lwaWVudHMgJiYgdHhQYXJhbXMucmVjaXBpZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIGNvbnN0IHJlY2lwaWVudCA9IHR4UGFyYW1zLnJlY2lwaWVudHNbMF07XG4gICAgICBjb25zdCBleHBlY3RlZEFtb3VudCA9IHJlY2lwaWVudC5hbW91bnQudG9TdHJpbmcoKTtcbiAgICAgIGNvbnN0IGV4cGVjdGVkRGVzdGluYXRpb24gPSByZWNpcGllbnQuYWRkcmVzcztcbiAgICAgIGNvbnN0IGFjdHVhbEFtb3VudCA9IHZhbHVlLmFtb3VudC50b1N0cmluZygpO1xuICAgICAgY29uc3QgYWN0dWFsRGVzdGluYXRpb24gPSBVdGlscy5nZXRCYXNlNThBZGRyZXNzRnJvbUhleCh2YWx1ZS50b19hZGRyZXNzKTtcblxuICAgICAgaWYgKGV4cGVjdGVkQW1vdW50ICE9PSBhY3R1YWxBbW91bnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0cmFuc2FjdGlvbiBhbW91bnQgaW4gdHhQcmVidWlsZCBkb2VzIG5vdCBtYXRjaCB0aGUgdmFsdWUgZ2l2ZW4gYnkgY2xpZW50Jyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChleHBlY3RlZERlc3RpbmF0aW9uLnRvTG93ZXJDYXNlKCkgIT09IGFjdHVhbERlc3RpbmF0aW9uLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkZXN0aW5hdGlvbiBhZGRyZXNzIGRvZXMgbm90IG1hdGNoIHdpdGggdGhlIHJlY2lwaWVudCBhZGRyZXNzJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogRGVyaXZlIGEgdXNlciBrZXkgdXNpbmcgdGhlIGNoYWluIHBhdGggb2YgdGhlIGFkZHJlc3NcbiAgICogQHBhcmFtIGtleVxuICAgKiBAcGFyYW0gcGF0aFxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBkZXJpdmVkIHByaXZhdGUga2V5XG4gICAqL1xuICBkZXJpdmVLZXlXaXRoUGF0aCh7IGtleSwgcGF0aCB9OiB7IGtleTogc3RyaW5nOyBwYXRoOiBzdHJpbmcgfSk6IHN0cmluZyB7XG4gICAgY29uc3Qga2V5Y2hhaW4gPSBiaXAzMi5mcm9tQmFzZTU4KGtleSk7XG4gICAgY29uc3QgZGVyaXZlZEtleU5vZGUgPSBrZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpO1xuICAgIHJldHVybiBkZXJpdmVkS2V5Tm9kZS50b0Jhc2U1OCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFzc2VtYmxlIGtleWNoYWluIGFuZCBoYWxmLXNpZ24gcHJlYnVpbHQgdHJhbnNhY3Rpb25cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcGFyYW0gcGFyYW1zLnR4UHJlYnVpbGQge09iamVjdH0gcHJlYnVpbGQgb2JqZWN0IHJldHVybmVkIGJ5IHBsYXRmb3JtXG4gICAqIEBwYXJhbSBwYXJhbXMucHJ2IHtTdHJpbmd9IHVzZXIgcHJ2XG4gICAqIEByZXR1cm5zIEJsdWViaXJkPFNpZ25lZFRyYW5zYWN0aW9uPlxuICAgKi9cbiAgYXN5bmMgc2lnblRyYW5zYWN0aW9uKHBhcmFtczogVHJvblNpZ25UcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPFNpZ25lZFRyYW5zYWN0aW9uPiB7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcih0aGlzLmdldENoYWluKCkpLmZyb20ocGFyYW1zLnR4UHJlYnVpbGQudHhIZXgpO1xuXG4gICAgbGV0IGtleTtcbiAgICBjb25zdCB7IGNoYWluLCBpbmRleCB9ID0gcGFyYW1zLnR4UHJlYnVpbGQ/LmFkZHJlc3NJbmZvID8/IHsgY2hhaW46IDAsIGluZGV4OiAwIH07XG4gICAgaWYgKGNoYWluID09PSAwICYmIGluZGV4ID09PSAwKSB7XG4gICAgICBrZXkgPSBwYXJhbXMucHJ2O1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9IGAwLzAvJHtjaGFpbn0vJHtpbmRleH1gO1xuICAgICAga2V5ID0gdGhpcy5kZXJpdmVLZXlXaXRoUGF0aCh7IGtleTogcGFyYW1zLnBydiwgcGF0aDogZGVyaXZhdGlvblBhdGggfSk7XG4gICAgfVxuICAgIHR4QnVpbGRlci5zaWduKHsga2V5IH0pO1xuXG4gICAgY29uc3QgdHJhbnNhY3Rpb24gPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICBjb25zdCByZXNwb25zZSA9IHtcbiAgICAgIHR4SGV4OiBKU09OLnN0cmluZ2lmeSh0cmFuc2FjdGlvbi50b0pzb24oKSksXG4gICAgfTtcbiAgICBpZiAodHJhbnNhY3Rpb24udG9Kc29uKCkuc2lnbmF0dXJlLmxlbmd0aCA+PSAyKSB7XG4gICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfVxuICAgIC8vIEhhbGYgc2lnbmVkIHRyYW5zYWN0aW9uXG4gICAgcmV0dXJuIHtcbiAgICAgIGhhbGZTaWduZWQ6IHJlc3BvbnNlLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGlucHV0IGlzIHZhbGlkIHNlZWQgZm9yIHRoZSBjb2luXG4gICAqXG4gICAqIEBwYXJhbSBwcnYgLSB0aGUgcHJ2IHRvIGJlIGNoZWNrZWRcbiAgICovXG4gIGlzVmFsaWRYcHJ2KHBydjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiAhYmlwMzIuZnJvbUJhc2U1OChwcnYpLmlzTmV1dGVyZWQoKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydCBhIG1lc3NhZ2UgdG8gc3RyaW5nIGluIGhleGFkZWNpbWFsIGZvcm1hdC5cbiAgICpcbiAgICogQHBhcmFtIG1lc3NhZ2Uge0J1ZmZlcnxTdHJpbmd9IG1lc3NhZ2UgdG8gc2lnblxuICAgKiBAcmV0dXJuIHRoZSBtZXNzYWdlIGFzIGEgaGV4YWRlY2ltYWwgc3RyaW5nXG4gICAqL1xuICB0b0hleFN0cmluZyhtZXNzYWdlOiBzdHJpbmcgfCBCdWZmZXIpOiBzdHJpbmcge1xuICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBCdWZmZXIuZnJvbShtZXNzYWdlKS50b1N0cmluZygnaGV4Jyk7XG4gICAgfSBlbHNlIGlmIChCdWZmZXIuaXNCdWZmZXIobWVzc2FnZSkpIHtcbiAgICAgIHJldHVybiBtZXNzYWdlLnRvU3RyaW5nKCdoZXgnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG1lc3NhZ2VkIHBhc3NlZCB0byBzaWduTWVzc2FnZScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTaWduIG1lc3NhZ2Ugd2l0aCBwcml2YXRlIGtleVxuICAgKlxuICAgKiBAcGFyYW0ga2V5XG4gICAqIEBwYXJhbSBtZXNzYWdlXG4gICAqL1xuICBhc3luYyBzaWduTWVzc2FnZShrZXk6IEtleVBhaXIsIG1lc3NhZ2U6IHN0cmluZyB8IEJ1ZmZlcik6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgY29uc3QgdG9TaWduID0gdGhpcy50b0hleFN0cmluZyhtZXNzYWdlKTtcblxuICAgIGxldCBwcnY6IHN0cmluZyB8IHVuZGVmaW5lZCA9IGtleS5wcnY7XG4gICAgaWYgKHRoaXMuaXNWYWxpZFhwcnYocHJ2KSkge1xuICAgICAgcHJ2ID0gYmlwMzIuZnJvbUJhc2U1OChwcnYpLnByaXZhdGVLZXk/LnRvU3RyaW5nKCdoZXgnKTtcbiAgICB9XG5cbiAgICBpZiAoIXBydikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBwcml2YXRlS2V5Jyk7XG4gICAgfVxuICAgIGxldCBzaWcgPSBVdGlscy5zaWduU3RyaW5nKHRvU2lnbiwgcHJ2LCB0cnVlKTtcblxuICAgIC8vIHJlbW92ZSB0aGUgcHJlY2VkaW5nIDB4XG4gICAgc2lnID0gc2lnLnJlcGxhY2UoL14weC8sICcnKTtcblxuICAgIHJldHVybiBCdWZmZXIuZnJvbShzaWcsICdoZXgnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhbiB4cHViIHRvIGEgdW5jb21wcmVzc2VkIHB1YlxuICAgKiBAcGFyYW0geHB1YlxuICAgKi9cbiAgeHB1YlRvVW5jb21wcmVzc2VkUHViKHhwdWI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWRYcHViKHhwdWIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgeHB1YicpO1xuICAgIH1cblxuICAgIGNvbnN0IHB1YmxpY0tleSA9IGJpcDMyLmZyb21CYXNlNTgoeHB1YikucHVibGljS2V5O1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShzZWNwMjU2azEucHVibGljS2V5Q29udmVydChwdWJsaWNLZXksIGZhbHNlIC8qIGNvbXByZXNzZWQgKi8pKS50b1N0cmluZygnaGV4Jyk7XG4gIH1cblxuICAvKipcbiAgICogTW9kaWZ5IHByZWJ1aWxkIGJlZm9yZSBzZW5kaW5nIGl0IHRvIHRoZSBzZXJ2ZXIuXG4gICAqIEBwYXJhbSBidWlsZFBhcmFtcyBUaGUgd2hpdGVsaXN0ZWQgcGFyYW1ldGVycyBmb3IgdGhpcyBwcmVidWlsZFxuICAgKi9cbiAgYXN5bmMgZ2V0RXh0cmFQcmVidWlsZFBhcmFtcyhidWlsZFBhcmFtczogYW55KTogUHJvbWlzZTxhbnk+IHtcbiAgICBpZiAoYnVpbGRQYXJhbXMucmVjaXBpZW50c1swXS5kYXRhICYmIGJ1aWxkUGFyYW1zLmZlZUxpbWl0KSB7XG4gICAgICBidWlsZFBhcmFtcy5yZWNpcGllbnRzWzBdLmZlZUxpbWl0ID0gYnVpbGRQYXJhbXMuZmVlTGltaXQ7XG4gICAgfVxuICB9XG5cbiAgcHViVG9IZXhBZGRyZXNzKHB1Yjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBieXRlQXJyYXlBZGRyID0gVXRpbHMuZ2V0Qnl0ZUFycmF5RnJvbUhleEFkZHJlc3MocHViKTtcbiAgICBjb25zdCByYXdBZGRyZXNzID0gVXRpbHMuZ2V0UmF3QWRkcmVzc0Zyb21QdWJLZXkoYnl0ZUFycmF5QWRkcik7XG4gICAgcmV0dXJuIFV0aWxzLmdldEhleEFkZHJlc3NGcm9tQnl0ZUFycmF5KHJhd0FkZHJlc3MpO1xuICB9XG5cbiAgeHBydlRvQ29tcHJlc3NlZFBydih4cHJ2OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5pc1ZhbGlkWHBydih4cHJ2KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHhwcnYnKTtcbiAgICB9XG5cbiAgICBjb25zdCBoZE5vZGUgPSBiaXAzMi5mcm9tQmFzZTU4KHhwcnYpO1xuICAgIGlmICghaGROb2RlLnByaXZhdGVLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbm8gcHJpdmF0ZUtleScpO1xuICAgIH1cbiAgICByZXR1cm4gaGROb2RlLnByaXZhdGVLZXkudG9TdHJpbmcoJ2hleCcpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXROb2RlVXJsKG5vZGU6IE5vZGVUeXBlcyk6IHN0cmluZyB7XG4gICAgc3dpdGNoIChub2RlKSB7XG4gICAgICBjYXNlIE5vZGVUeXBlcy5GdWxsOlxuICAgICAgICByZXR1cm4gY29tbW9uLkVudmlyb25tZW50c1t0aGlzLmJpdGdvLmdldEVudigpXS50cm9uTm9kZXMuZnVsbDtcbiAgICAgIGNhc2UgTm9kZVR5cGVzLlNvbGlkaXR5OlxuICAgICAgICByZXR1cm4gY29tbW9uLkVudmlyb25tZW50c1t0aGlzLmJpdGdvLmdldEVudigpXS50cm9uTm9kZXMuc29saWRpdHk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vZGUgdHlwZSBub3QgZm91bmQnKTtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIE1ha2UgYSBxdWVyeSB0byBUcm9uZ3JpZCBmb3IgaW5mb3JtYXRpb24gc3VjaCBhcyBiYWxhbmNlLCB0b2tlbiBiYWxhbmNlLCBzb2xpZGl0eSBjYWxsc1xuICAgKiBAcGFyYW0gcXVlcnkge09iamVjdH0ga2V5LXZhbHVlIHBhaXJzIG9mIHBhcmFtZXRlcnMgdG8gYXBwZW5kIGFmdGVyIC9hcGlcbiAgICogQHJldHVybnMge09iamVjdH0gcmVzcG9uc2UgZnJvbSBUcm9uZ3JpZFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZWNvdmVyeVBvc3QocXVlcnk6IHsgcGF0aDogc3RyaW5nOyBqc29uT2JqOiBhbnk7IG5vZGU6IE5vZGVUeXBlcyB9KTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBub2RlVXJpID0gdGhpcy5nZXROb2RlVXJsKHF1ZXJ5Lm5vZGUpO1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCByZXF1ZXN0XG4gICAgICAucG9zdChub2RlVXJpICsgcXVlcnkucGF0aClcbiAgICAgIC50eXBlKCdqc29uJylcbiAgICAgIC5zZW5kKHF1ZXJ5Lmpzb25PYmopO1xuXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb3VsZCBub3QgcmVhY2ggVHJvbiBub2RlJyk7XG4gICAgfVxuXG4gICAgLy8gdW5mb3J0dW5hdGVseSwgaXQgZG9lc24ndCBsb29rIGxpa2UgbW9zdCBUUk9OIG5vZGVzIHJldHVybiB2YWxpZCBqc29uIGFzIGJvZHlcbiAgICByZXR1cm4gSlNPTi5wYXJzZShyZXNwb25zZS50ZXh0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYWtlIGEgcXVlcnkgdG8gVHJvbmdyaWQgZm9yIGluZm9ybWF0aW9uIHN1Y2ggYXMgYmFsYW5jZSwgdG9rZW4gYmFsYW5jZSwgc29saWRpdHkgY2FsbHNcbiAgICogQHBhcmFtIHF1ZXJ5IHtPYmplY3R9IGtleS12YWx1ZSBwYWlycyBvZiBwYXJhbWV0ZXJzIHRvIGFwcGVuZCBhZnRlciAvYXBpXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IHJlc3BvbnNlIGZyb20gVHJvbmdyaWRcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVjb3ZlcnlHZXQocXVlcnk6IHsgcGF0aDogc3RyaW5nOyBqc29uT2JqOiBhbnk7IG5vZGU6IE5vZGVUeXBlcyB9KTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBub2RlVXJpID0gdGhpcy5nZXROb2RlVXJsKHF1ZXJ5Lm5vZGUpO1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCByZXF1ZXN0XG4gICAgICAuZ2V0KG5vZGVVcmkgKyBxdWVyeS5wYXRoKVxuICAgICAgLnR5cGUoJ2pzb24nKVxuICAgICAgLnNlbmQocXVlcnkuanNvbk9iaik7XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvdWxkIG5vdCByZWFjaCBUcm9uIG5vZGUnKTtcbiAgICB9XG5cbiAgICAvLyB1bmZvcnR1bmF0ZWx5LCBpdCBkb2Vzbid0IGxvb2sgbGlrZSBtb3N0IFRST04gbm9kZXMgcmV0dXJuIHZhbGlkIGpzb24gYXMgYm9keVxuICAgIHJldHVybiBKU09OLnBhcnNlKHJlc3BvbnNlLnRleHQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFF1ZXJ5IG91ciBleHBsb3JlciBmb3IgdGhlIGJhbGFuY2Ugb2YgYW4gYWRkcmVzc1xuICAgKiBAcGFyYW0gYWRkcmVzcyB7U3RyaW5nfSB0aGUgYWRkcmVzcyBlbmNvZGVkIGluIGhleFxuICAgKiBAcmV0dXJucyB7QmlnTnVtYmVyfSBhZGRyZXNzIGJhbGFuY2VcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0QWNjb3VudEJhbGFuY2VzRnJvbU5vZGUoYWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTxBY2NvdW50UmVzcG9uc2U+IHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yZWNvdmVyeUdldCh7XG4gICAgICBwYXRoOiAnL3YxL2FjY291bnRzLycgKyBhZGRyZXNzLFxuICAgICAganNvbk9iajoge30sXG4gICAgICBub2RlOiBOb2RlVHlwZXMuRnVsbCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgb3VyIGJ1aWxkIHRyYW5zYWN0aW9uIGZyb20gYSBub2RlLlxuICAgKiBAcGFyYW0gdG9BZGRyIGhleC1lbmNvZGVkIGFkZHJlc3NcbiAgICogQHBhcmFtIGZyb21BZGRyIGhleC1lbmNvZGVkIGFkZHJlc3NcbiAgICogQHBhcmFtIGFtb3VudFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZXRCdWlsZFRyYW5zYWN0aW9uKFxuICAgIHRvQWRkcjogc3RyaW5nLFxuICAgIGZyb21BZGRyOiBzdHJpbmcsXG4gICAgYW1vdW50OiBudW1iZXJcbiAgKTogUHJvbWlzZTxJbnRlcmZhY2UuVHJhbnNhY3Rpb25SZWNlaXB0PiB7XG4gICAgLy8gb3VyIGFkZHJlc3NlcyBzaG91bGQgYmUgYmFzZTU4LCB3ZSdsbCBoYXZlIHRvIGVuY29kZSB0byBoZXhcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yZWNvdmVyeVBvc3Qoe1xuICAgICAgcGF0aDogJy93YWxsZXQvY3JlYXRldHJhbnNhY3Rpb24nLFxuICAgICAganNvbk9iajoge1xuICAgICAgICB0b19hZGRyZXNzOiB0b0FkZHIsXG4gICAgICAgIG93bmVyX2FkZHJlc3M6IGZyb21BZGRyLFxuICAgICAgICBhbW91bnQsXG4gICAgICB9LFxuICAgICAgbm9kZTogTm9kZVR5cGVzLkZ1bGwsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIG91ciBidWlsZCB0cmFuc2FjdGlvbiBmcm9tIGEgbm9kZS5cbiAgICogQHBhcmFtIHRvQWRkciBoZXgtZW5jb2RlZCBhZGRyZXNzXG4gICAqIEBwYXJhbSBmcm9tQWRkciBoZXgtZW5jb2RlZCBhZGRyZXNzXG4gICAqIEBwYXJhbSBhbW91bnRcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0VHJpZ2dlclNtYXJ0Q29udHJhY3RUcmFuc2FjdGlvbihcbiAgICB0b0FkZHI6IHN0cmluZyxcbiAgICBmcm9tQWRkcjogc3RyaW5nLFxuICAgIGFtb3VudDogc3RyaW5nLFxuICAgIGNvbnRyYWN0QWRkcjogc3RyaW5nXG4gICk6IFByb21pc2U8eyB0cmFuc2FjdGlvbjogSW50ZXJmYWNlLlRyYW5zYWN0aW9uUmVjZWlwdCB9PiB7XG4gICAgY29uc3QgZnVuY3Rpb25TZWxlY3RvciA9ICd0cmFuc2ZlcihhZGRyZXNzLHVpbnQyNTYpJztcbiAgICBjb25zdCB0eXBlcyA9IFsnYWRkcmVzcycsICd1aW50MjU2J107XG4gICAgY29uc3QgdmFsdWVzID0gW3RvQWRkciwgYW1vdW50XTtcbiAgICBjb25zdCBwYXJhbWV0ZXIgPSBVdGlscy5lbmNvZGVEYXRhUGFyYW1zKHR5cGVzLCB2YWx1ZXMsICcnKTtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yZWNvdmVyeVBvc3Qoe1xuICAgICAgcGF0aDogJy93YWxsZXQvdHJpZ2dlcnNtYXJ0Y29udHJhY3QnLFxuICAgICAganNvbk9iajoge1xuICAgICAgICBvd25lcl9hZGRyZXNzOiBmcm9tQWRkcixcbiAgICAgICAgY29udHJhY3RfYWRkcmVzczogY29udHJhY3RBZGRyLFxuICAgICAgICBmdW5jdGlvbl9zZWxlY3RvcjogZnVuY3Rpb25TZWxlY3RvcixcbiAgICAgICAgcGFyYW1ldGVyOiBwYXJhbWV0ZXIsXG4gICAgICAgIGZlZV9saW1pdDogMTAwMDAwMDAwLFxuICAgICAgfSxcbiAgICAgIG5vZGU6IE5vZGVUeXBlcy5GdWxsLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRocm93cyBhbiBlcnJvciBpZiBhbnkga2V5cyBpbiB0aGUgb3duZXJLZXlzIGNvbGxlY3Rpb24gZG9uJ3QgbWF0Y2ggdGhlIGtleXMgYXJyYXkgd2UgcGFzc1xuICAgKiBAcGFyYW0gb3duZXJLZXlzXG4gICAqIEBwYXJhbSBrZXlzXG4gICAqL1xuICBjaGVja1Blcm1pc3Npb25zKG93bmVyS2V5czogeyBhZGRyZXNzOiBzdHJpbmc7IHdlaWdodDogbnVtYmVyIH1bXSwga2V5czogc3RyaW5nW10pIHtcbiAgICBrZXlzID0ga2V5cy5tYXAoKGspID0+IGsudG9VcHBlckNhc2UoKSk7XG5cbiAgICBvd25lcktleXMubWFwKChrZXkpID0+IHtcbiAgICAgIGNvbnN0IGhleEtleSA9IGtleS5hZGRyZXNzLnRvVXBwZXJDYXNlKCk7XG4gICAgICBpZiAoIWtleXMuaW5jbHVkZXMoaGV4S2V5KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHB1YiBhZGRyZXNzICR7aGV4S2V5fSBub3QgZm91bmQgaW4gYWNjb3VudGApO1xuICAgICAgfVxuXG4gICAgICBpZiAoa2V5LndlaWdodCAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ293bmVyIHBlcm1pc3Npb24gaXMgaW52YWxpZCBmb3IgdGhpcyBzdHJ1Y3R1cmUnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGb3JtYXQgZm9yIG9mZmxpbmUgdmF1bHQgc2lnbmluZ1xuICAgKiBAcGFyYW0ge0Jhc2VUcmFuc2FjdGlvbn0gdHhcbiAgICogQHBhcmFtIHtudW1iZXJ9IGZlZVxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVjb3ZlcnlBbW91bnRcbiAgICogQHJldHVybnMge1JlY292ZXJ5VHJhbnNhY3Rpb259XG4gICAqL1xuICBmb3JtYXRGb3JPZmZsaW5lVmF1bHQoXG4gICAgdHg6IEJhc2VUcmFuc2FjdGlvbixcbiAgICBmZWU6IG51bWJlcixcbiAgICByZWNvdmVyeUFtb3VudDogbnVtYmVyLFxuICAgIGFkZHJlc3NJbmZvPzogQWRkcmVzc0luZm9cbiAgKTogUmVjb3ZlcnlUcmFuc2FjdGlvbiB7XG4gICAgY29uc3QgdHhKU09OID0gdHgudG9Kc29uKCk7XG4gICAgY29uc3QgZm9ybWF0ID0ge1xuICAgICAgdHhIZXg6IEpTT04uc3RyaW5naWZ5KHR4SlNPTiksXG4gICAgICByZWNvdmVyeUFtb3VudCxcbiAgICAgIGZlZUluZm86IHtcbiAgICAgICAgZmVlOiBgJHtmZWV9YCxcbiAgICAgIH0sXG4gICAgICB0eDogdHhKU09OLCAvLyBMZWF2aW5nIGl0IGFzIHR4SlNPTiBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHlcbiAgICAgIGNvaW46IHRoaXMuZ2V0Q2hhaW4oKSxcbiAgICB9O1xuICAgIHJldHVybiBhZGRyZXNzSW5mbyA/IHsgLi4uZm9ybWF0LCBhZGRyZXNzSW5mbyB9IDogZm9ybWF0O1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhIGZ1bmRzIHJlY292ZXJ5IHRyYW5zYWN0aW9uIHdpdGhvdXQgQml0R28uXG4gICAqIFdlIG5lZWQgdG8gZG8gdGhyZWUgcXVlcmllcyBkdXJpbmcgdGhpczpcbiAgICogMSkgTm9kZSBxdWVyeSAtIGhvdyBtdWNoIG1vbmV5IGlzIGluIHRoZSBhY2NvdW50XG4gICAqIDIpIEJ1aWxkIHRyYW5zYWN0aW9uIC0gYnVpbGQgb3VyIHRyYW5zYWN0aW9uIGZvciB0aGUgYW1vdW50XG4gICAqIDMpIFNlbmQgc2lnbmVkIGJ1aWxkIC0gc2VuZCBvdXIgc2lnbmVkIGJ1aWxkIHRvIGEgcHVibGljIG5vZGVcbiAgICpcbiAgICogTm90ZSAxOiBmb3IgYmFzZSBhZGRyZXNzIHJlY292ZXJpZXMsIGZ1bmQgd2lsbCBiZSByZWNvdmVyZWQgdG8gcmVjb3ZlcnkgZGVzdGluYXRpb24gaWYgYmFzZSBhZGRyZXNzIGJhbGFuY2UgaXNcbiAgICogbW9yZSB0aGFuIDIuMSBUUlggZm9yIG5hdGl2ZSBUUlggcmVjb3ZlcnkgYW5kIDEwMCBUUlggZm9yIHRva2VuIHJlY292ZXIuIEZvciByZWNlaXZlIGFkZHJlc3NlcywgZnVuZCB3aWxsIGJlXG4gICAqIHJlY292ZXJlZCB0byBiYXNlIGFkZHJlc3MgZmlyc3QgdGhlbiBzd2VwdCB0byBiYXNlIGFkZHJlc3MoZGVjaWRlZCBhcyB0aGUgdW5pdmVyc2FsIHBhdHRlcm4gaW4gdGVhbSBtZWV0aW5nKS5cbiAgICpcbiAgICogTm90ZSAyOiB0aGUgZnVuY3Rpb24gc3VwcG9ydHMgdG9rZW4gc3dlZXAgZnJvbSBiYXNlIGFkZHJlc3MuXG4gICAqIFRPRE86IHN1cHBvcnQgdG9rZW4gc3dlZXAgZnJvbSByZWNlaXZlIGFkZHJlc3MuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICovXG4gIGFzeW5jIHJlY292ZXIocGFyYW1zOiBSZWNvdmVyeU9wdGlvbnMpOiBQcm9taXNlPFJlY292ZXJ5VHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCBpc0tyc1JlY292ZXJ5ID0gZ2V0SXNLcnNSZWNvdmVyeShwYXJhbXMpO1xuICAgIGNvbnN0IGlzVW5zaWduZWRTd2VlcCA9IGdldElzVW5zaWduZWRTd2VlcChwYXJhbXMpO1xuXG4gICAgaWYgKCF0aGlzLmlzVmFsaWRBZGRyZXNzKHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRlc3RpbmF0aW9uIGFkZHJlc3MhJyk7XG4gICAgfVxuXG4gICAgbGV0IHN0YXJ0SWR4ID0gcGFyYW1zLnN0YXJ0aW5nU2NhbkluZGV4O1xuICAgIGlmIChpc1VuZGVmaW5lZChzdGFydElkeCkpIHtcbiAgICAgIHN0YXJ0SWR4ID0gMTtcbiAgICB9IGVsc2UgaWYgKCFpc0ludGVnZXIoc3RhcnRJZHgpIHx8IHN0YXJ0SWR4IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN0YXJ0aW5nIGluZGV4IHRvIHNjYW4gZm9yIGFkZHJlc3NlcycpO1xuICAgIH1cblxuICAgIGxldCBudW1JdGVyYXRpb24gPSBwYXJhbXMuc2NhbjtcbiAgICBpZiAoaXNVbmRlZmluZWQobnVtSXRlcmF0aW9uKSkge1xuICAgICAgbnVtSXRlcmF0aW9uID0gMjA7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgbnVtSXRlcmF0aW9uID09PSAnc3RyaW5nJykge1xuICAgICAgbnVtSXRlcmF0aW9uID0gcGFyc2VJbnQobnVtSXRlcmF0aW9uLCAxMCk7XG4gICAgfVxuXG4gICAgaWYgKCFpc0ludGVnZXIobnVtSXRlcmF0aW9uKSB8fCBudW1JdGVyYXRpb24gPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNjYW5uaW5nIGZhY3RvcicpO1xuICAgIH1cblxuICAgIC8vIGdldCBvdXIgdXNlciwgYmFja3VwIGtleXNcbiAgICBjb25zdCBrZXlzID0gZ2V0QmlwMzJLZXlzKHRoaXMuYml0Z28sIHBhcmFtcywgeyByZXF1aXJlQml0R29YcHViOiBmYWxzZSB9KTtcblxuICAgIC8vIHdlIG5lZWQgdG8gZGVjb2RlIG91ciBiaXRnb0tleSB0byBhIGJhc2U1OCBhZGRyZXNzXG4gICAgY29uc3QgYml0Z29IZXhBZGRyID0gdGhpcy5wdWJUb0hleEFkZHJlc3ModGhpcy54cHViVG9VbmNvbXByZXNzZWRQdWIocGFyYW1zLmJpdGdvS2V5KSk7XG4gICAgbGV0IHJlY292ZXJ5RnJvbUFkZHJIZXggPSBiaXRnb0hleEFkZHI7XG4gICAgbGV0IHJlY292ZXJ5VG9BZGRyZXNzSGV4ID0gVXRpbHMuZ2V0SGV4QWRkcmVzc0Zyb21CYXNlNThBZGRyZXNzKHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKTtcblxuICAgIC8vIGNhbGwgdGhlIG5vZGUgdG8gZ2V0IG91ciBhY2NvdW50IGJhbGFuY2UgZm9yIGJhc2UgYWRkcmVzc1xuICAgIGxldCBhY2NvdW50ID0gYXdhaXQgdGhpcy5nZXRBY2NvdW50QmFsYW5jZXNGcm9tTm9kZShVdGlscy5nZXRCYXNlNThBZGRyZXNzRnJvbUhleChyZWNvdmVyeUZyb21BZGRySGV4KSk7XG4gICAgbGV0IHJlY292ZXJ5QW1vdW50ID0gYWNjb3VudC5kYXRhWzBdLmJhbGFuY2U7XG5cbiAgICBsZXQgdXNlclhQcnYgPSBrZXlzWzBdLnRvQmFzZTU4KCk7XG4gICAgbGV0IGlzUmVjZWl2ZUFkZHJlc3MgPSBmYWxzZTtcbiAgICBsZXQgYWRkcmVzc0luZm86IEFkZHJlc3NJbmZvIHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IHRva2VuQ29udHJhY3RBZGRyID0gcGFyYW1zLnRva2VuQ29udHJhY3RBZGRyZXNzO1xuICAgIC8vIGNoZWNrIGZvciBwb3NzaWJsZSB0b2tlbiByZWNvdmVyeSwgcmVjb3ZlciB0aGUgdG9rZW4gcHJvdmlkZSBieSB1c2VyXG4gICAgaWYgKHRva2VuQ29udHJhY3RBZGRyKSB7XG4gICAgICBsZXQgcmF3VG9rZW5UeG46IGFueSB8IHVuZGVmaW5lZDtcbiAgICAgIGZvciAoY29uc3QgdG9rZW4gb2YgYWNjb3VudC5kYXRhWzBdLnRyYzIwKSB7XG4gICAgICAgIGlmICh0b2tlblt0b2tlbkNvbnRyYWN0QWRkcl0pIHtcbiAgICAgICAgICBjb25zdCBhbW91bnQgPSB0b2tlblt0b2tlbkNvbnRyYWN0QWRkcl07XG4gICAgICAgICAgY29uc3QgdG9rZW5Db250cmFjdEFkZHJIZXggPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3ModG9rZW5Db250cmFjdEFkZHIpO1xuICAgICAgICAgIHJhd1Rva2VuVHhuID0gKFxuICAgICAgICAgICAgYXdhaXQgdGhpcy5nZXRUcmlnZ2VyU21hcnRDb250cmFjdFRyYW5zYWN0aW9uKFxuICAgICAgICAgICAgICByZWNvdmVyeVRvQWRkcmVzc0hleCxcbiAgICAgICAgICAgICAgcmVjb3ZlcnlGcm9tQWRkckhleCxcbiAgICAgICAgICAgICAgYW1vdW50LFxuICAgICAgICAgICAgICB0b2tlbkNvbnRyYWN0QWRkckhleFxuICAgICAgICAgICAgKVxuICAgICAgICAgICkudHJhbnNhY3Rpb247XG4gICAgICAgICAgcmVjb3ZlcnlBbW91bnQgPSBwYXJzZUludChhbW91bnQsIDEwKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBidWlsZCBhbmQgc2lnbiB0b2tlbiB0eG5zXG4gICAgICBpZiAocmF3VG9rZW5UeG4pIHtcbiAgICAgICAgLy8gQ2hlY2sgdGhlcmUgaXMgc3VmZmljaWVudCBvZiB0aGUgbmF0aXZlIGFzc2V0IHRvIGNvdmVyIGZlZXNcbiAgICAgICAgY29uc3QgdHJ4QmFsYW5jZSA9IGFjY291bnQuZGF0YVswXS5iYWxhbmNlO1xuICAgICAgICBpZiAodHJ4QmFsYW5jZSA8IFNBRkVfVFJPTl9UT0tFTl9UUkFOU0FDVElPTl9GRUUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgQW1vdW50IG9mIGZ1bmRzIHRvIHJlY292ZXIgJHt0cnhCYWxhbmNlfSBpcyBsZXNzIHRoYW4gJHtTQUZFX1RST05fVE9LRU5fVFJBTlNBQ1RJT05fRkVFfSBhbmQgd291bGRuJ3QgYmUgYWJsZSB0byBmdW5kIGEgdHJjMjAgc2VuZGBcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcih0aGlzLmdldENoYWluKCkpLmZyb20ocmF3VG9rZW5UeG4pO1xuICAgICAgICAvLyBEZWZhdWx0IGV4cGlyeSBpcyAxIG1pbnV0ZSB3aGljaCBpcyB0b28gc2hvcnQgZm9yIHJlY292ZXJ5IHB1cnBvc2VzXG4gICAgICAgIC8vIGV4dGVuZCB0aGUgZXhwaXJ5IHRvIDEgZGF5XG4gICAgICAgIHR4QnVpbGRlci5leHRlbmRWYWxpZFRvKFJFQ09WRVJfVFJBTlNBQ1RJT05fRVhQSVJZKTtcbiAgICAgICAgLy8gdGhpcyB0eCBzaG91bGQgYmUgZW5vdWdoIHRvIGRyb3AgaW50byBhIG5vZGVcbiAgICAgICAgaWYgKGlzVW5zaWduZWRTd2VlcCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmZvcm1hdEZvck9mZmxpbmVWYXVsdChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSwgU0FGRV9UUk9OX1RPS0VOX1RSQU5TQUNUSU9OX0ZFRSwgcmVjb3ZlcnlBbW91bnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdXNlclBydiA9IHRoaXMueHBydlRvQ29tcHJlc3NlZFBydih1c2VyWFBydik7XG5cbiAgICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IHVzZXJQcnYgfSk7XG5cbiAgICAgICAgLy8ga3JzIHJlY292ZXJpZXMgZG9uJ3QgZ2V0IHNpZ25lZFxuICAgICAgICBpZiAoIWlzS3JzUmVjb3ZlcnkgJiYgIWlzUmVjZWl2ZUFkZHJlc3MpIHtcbiAgICAgICAgICBjb25zdCBiYWNrdXBYUHJ2ID0ga2V5c1sxXS50b0Jhc2U1OCgpO1xuICAgICAgICAgIGNvbnN0IGJhY2t1cFBydiA9IHRoaXMueHBydlRvQ29tcHJlc3NlZFBydihiYWNrdXBYUHJ2KTtcblxuICAgICAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBiYWNrdXBQcnYgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0Rm9yT2ZmbGluZVZhdWx0KGF3YWl0IHR4QnVpbGRlci5idWlsZCgpLCBTQUZFX1RST05fVE9LRU5fVFJBTlNBQ1RJT05fRkVFLCByZWNvdmVyeUFtb3VudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBFcnJvcignTm90IGZvdW5kIHRva2VuIHRvIHJlY292ZXIsIHBsZWFzZSBjaGVjayB0b2tlbiBiYWxhbmNlJyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIGxldCB1cyByZWNvdmVyIHRoZSBuYXRpdmUgVHJvblxuICAgIGlmIChyZWNvdmVyeUFtb3VudCA+IFNBRkVfVFJPTl9UUkFOU0FDVElPTl9GRUUpIHtcbiAgICAgIGNvbnN0IHVzZXJYUHViID0ga2V5c1swXS5uZXV0ZXJlZCgpLnRvQmFzZTU4KCk7XG4gICAgICBjb25zdCBiYWNrdXBYUHViID0ga2V5c1sxXS5uZXV0ZXJlZCgpLnRvQmFzZTU4KCk7XG5cbiAgICAgIC8vIGNoZWNrIG11bHRpc2lnIHBlcm1pc3Npb25zXG4gICAgICBjb25zdCBrZXlIZXhBZGRyZXNzZXMgPSBbXG4gICAgICAgIHRoaXMucHViVG9IZXhBZGRyZXNzKHRoaXMueHB1YlRvVW5jb21wcmVzc2VkUHViKHVzZXJYUHViKSksXG4gICAgICAgIHRoaXMucHViVG9IZXhBZGRyZXNzKHRoaXMueHB1YlRvVW5jb21wcmVzc2VkUHViKGJhY2t1cFhQdWIpKSxcbiAgICAgICAgYml0Z29IZXhBZGRyLFxuICAgICAgXTtcbiAgICAgIC8vIHJ1biBjaGVja3MgdG8gZW5zdXJlIHRoaXMgaXMgYSB2YWxpZCB0eCAtIHBlcm1pc3Npb25zIG1hdGNoIG91ciBzaWduZXIga2V5c1xuICAgICAgY29uc3Qgb3duZXJLZXlzOiB7IGFkZHJlc3M6IHN0cmluZzsgd2VpZ2h0OiBudW1iZXIgfVtdID0gW107XG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBhY2NvdW50LmRhdGFbMF0ub3duZXJfcGVybWlzc2lvbi5rZXlzKSB7XG4gICAgICAgIGNvbnN0IGFkZHJlc3MgPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3Moa2V5LmFkZHJlc3MpO1xuICAgICAgICBjb25zdCB3ZWlnaHQgPSBrZXkud2VpZ2h0O1xuICAgICAgICBvd25lcktleXMucHVzaCh7IGFkZHJlc3MsIHdlaWdodCB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGFjdGl2ZVBlcm1pc3Npb25LZXlzOiB7IGFkZHJlc3M6IHN0cmluZzsgd2VpZ2h0OiBudW1iZXIgfVtdID0gW107XG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBhY2NvdW50LmRhdGFbMF0uYWN0aXZlX3Blcm1pc3Npb25bMF0ua2V5cykge1xuICAgICAgICBjb25zdCBhZGRyZXNzID0gVXRpbHMuZ2V0SGV4QWRkcmVzc0Zyb21CYXNlNThBZGRyZXNzKGtleS5hZGRyZXNzKTtcbiAgICAgICAgY29uc3Qgd2VpZ2h0ID0ga2V5LndlaWdodDtcbiAgICAgICAgYWN0aXZlUGVybWlzc2lvbktleXMucHVzaCh7IGFkZHJlc3MsIHdlaWdodCB9KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2hlY2tQZXJtaXNzaW9ucyhvd25lcktleXMsIGtleUhleEFkZHJlc3Nlcyk7XG4gICAgICB0aGlzLmNoZWNrUGVybWlzc2lvbnMoYWN0aXZlUGVybWlzc2lvbktleXMsIGtleUhleEFkZHJlc3Nlcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIENoZWNrIHJlY2VpdmUgYWRkcmVzc2VzIGZvciBmdW5kc1xuICAgICAgLy8gQ2hlY2sgZm9yIGZpcnN0IGRlcml2ZWQgd2FsbGV0IHdpdGggZnVuZHNcbiAgICAgIC8vIFJlY2VpdmUgYWRkcmVzc2VzIGFyZSBkZXJpdmVkIGZyb20gdGhlIHVzZXIga2V5XG4gICAgICBmb3IgKGxldCBpID0gc3RhcnRJZHg7IGkgPCBudW1JdGVyYXRpb24gKyBzdGFydElkeDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGRlcml2YXRpb25QYXRoID0gYDAvMC8wLyR7aX1gO1xuICAgICAgICBjb25zdCB1c2VyS2V5ID0ga2V5c1swXS5kZXJpdmVQYXRoKGRlcml2YXRpb25QYXRoKTtcbiAgICAgICAgY29uc3QgeHB1YiA9IHVzZXJLZXkubmV1dGVyZWQoKTtcbiAgICAgICAgY29uc3QgcmVjZWl2ZUFkZHJlc3MgPSB0aGlzLnB1YlRvSGV4QWRkcmVzcyh0aGlzLnhwdWJUb1VuY29tcHJlc3NlZFB1Yih4cHViLnRvQmFzZTU4KCkpKTtcbiAgICAgICAgY29uc3QgYWRkcmVzcyA9IFV0aWxzLmdldEJhc2U1OEFkZHJlc3NGcm9tSGV4KHJlY2VpdmVBZGRyZXNzKTtcbiAgICAgICAgLy8gY2FsbCB0aGUgbm9kZSB0byBnZXQgb3VyIGFjY291bnQgYmFsYW5jZVxuICAgICAgICBjb25zdCBhY2NvdW50SW5mbyA9IGF3YWl0IHRoaXMuZ2V0QWNjb3VudEJhbGFuY2VzRnJvbU5vZGUoYWRkcmVzcyk7XG5cbiAgICAgICAgaWYgKGFjY291bnRJbmZvLmRhdGFbMF0gJiYgYWNjb3VudEluZm8uZGF0YVswXS5iYWxhbmNlID4gU0FGRV9UUk9OX1RSQU5TQUNUSU9OX0ZFRSkge1xuICAgICAgICAgIGFjY291bnQgPSBhY2NvdW50SW5mbztcbiAgICAgICAgICByZWNvdmVyeUFtb3VudCA9IGFjY291bnRJbmZvLmRhdGFbMF0uYmFsYW5jZTtcbiAgICAgICAgICB1c2VyWFBydiA9IHVzZXJLZXkudG9CYXNlNTgoKTsgLy8gYXNzaWduIGRlcml2ZWQgdXNlclhQcnhcbiAgICAgICAgICBpc1JlY2VpdmVBZGRyZXNzID0gdHJ1ZTtcbiAgICAgICAgICByZWNvdmVyeUZyb21BZGRySGV4ID0gcmVjZWl2ZUFkZHJlc3M7XG4gICAgICAgICAgcmVjb3ZlcnlUb0FkZHJlc3NIZXggPSBiaXRnb0hleEFkZHI7XG4gICAgICAgICAgYWRkcmVzc0luZm8gPSB7XG4gICAgICAgICAgICBhZGRyZXNzLFxuICAgICAgICAgICAgY2hhaW46IDAsXG4gICAgICAgICAgICBpbmRleDogaSxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gYSBzd2VlcCBwb3RlbnRpYWxseSBuZWVkcyB0byBwYXkgZm9yIG11bHRpLXNpZyB0cmFuc2ZlciwgZGVzdGluYXRpb24gYWNjb3VudCBhY3RpdmF0aW9uIGFuZCBiYW5kd2lkdGhcbiAgICAvLyBUUk9OIGZvdW5kYXRpb24gcmVjb21tZW5kcyAyLjEgVFJYIGZvciBndWFyYW50ZWVkIGNvbmZpcm1hdGlvblxuICAgIGlmICghcmVjb3ZlcnlBbW91bnQgfHwgU0FGRV9UUk9OX1RSQU5TQUNUSU9OX0ZFRSA+PSByZWNvdmVyeUFtb3VudCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgQW1vdW50IG9mIGZ1bmRzIHRvIHJlY292ZXIgJHtyZWNvdmVyeUFtb3VudH0gaXMgbGVzcyB0aGFuICR7U0FGRV9UUk9OX1RSQU5TQUNUSU9OX0ZFRX0gYW5kIHdvdWxkbid0IGJlIGFibGUgdG8gZnVuZCBhIHNlbmRgXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHJlY292ZXJ5QW1vdW50TWludXNGZWVzID0gcmVjb3ZlcnlBbW91bnQgLSBTQUZFX1RST05fVFJBTlNBQ1RJT05fRkVFO1xuICAgIGNvbnN0IGJ1aWxkVHggPSBhd2FpdCB0aGlzLmdldEJ1aWxkVHJhbnNhY3Rpb24ocmVjb3ZlcnlUb0FkZHJlc3NIZXgsIHJlY292ZXJ5RnJvbUFkZHJIZXgsIHJlY292ZXJ5QW1vdW50TWludXNGZWVzKTtcblxuICAgIC8vIGNvbnN0cnVjdCBvdXIgdHhcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSAoZ2V0QnVpbGRlcih0aGlzLmdldENoYWluKCkpIGFzIFdyYXBwZWRCdWlsZGVyKS5mcm9tKGJ1aWxkVHgpO1xuICAgIC8vIERlZmF1bHQgZXhwaXJ5IGlzIDEgbWludXRlIHdoaWNoIGlzIHRvbyBzaG9ydCBmb3IgcmVjb3ZlcnkgcHVycG9zZXNcbiAgICAvLyBleHRlbmQgdGhlIGV4cGlyeSB0byAxIGRheVxuICAgIHR4QnVpbGRlci5leHRlbmRWYWxpZFRvKFJFQ09WRVJfVFJBTlNBQ1RJT05fRVhQSVJZKTtcbiAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuXG4gICAgLy8gdGhpcyB0eCBzaG91bGQgYmUgZW5vdWdoIHRvIGRyb3AgaW50byBhIG5vZGVcbiAgICBpZiAoaXNVbnNpZ25lZFN3ZWVwKSB7XG4gICAgICByZXR1cm4gdGhpcy5mb3JtYXRGb3JPZmZsaW5lVmF1bHQodHgsIFNBRkVfVFJPTl9UUkFOU0FDVElPTl9GRUUsIHJlY292ZXJ5QW1vdW50TWludXNGZWVzLCBhZGRyZXNzSW5mbyk7XG4gICAgfVxuXG4gICAgY29uc3QgdXNlclBydiA9IHRoaXMueHBydlRvQ29tcHJlc3NlZFBydih1c2VyWFBydik7XG5cbiAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdXNlclBydiB9KTtcblxuICAgIC8vIGtycyByZWNvdmVyaWVzIGRvbid0IGdldCBzaWduZWRcbiAgICBpZiAoIWlzS3JzUmVjb3ZlcnkgJiYgIWlzUmVjZWl2ZUFkZHJlc3MpIHtcbiAgICAgIGNvbnN0IGJhY2t1cFhQcnYgPSBrZXlzWzFdLnRvQmFzZTU4KCk7XG4gICAgICBjb25zdCBiYWNrdXBQcnYgPSB0aGlzLnhwcnZUb0NvbXByZXNzZWRQcnYoYmFja3VwWFBydik7XG5cbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBiYWNrdXBQcnYgfSk7XG4gICAgfVxuICAgIGNvbnN0IHR4U2lnbmVkID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgcmV0dXJuIHRoaXMuZm9ybWF0Rm9yT2ZmbGluZVZhdWx0KHR4U2lnbmVkLCBTQUZFX1RST05fVFJBTlNBQ1RJT05fRkVFLCByZWNvdmVyeUFtb3VudE1pbnVzRmVlcywgYWRkcmVzc0luZm8pO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBuYXRpdmUgVFJYIHJlY292ZXJpZXMgb2YgcmVjZWl2ZSBhZGRyZXNzZXMgaW4gYmF0Y2ggd2l0aG91dCBCaXRHby5cbiAgICogRnVuZHMgd2lsbCBiZSByZWNvdmVyZWQgdG8gYmFzZSBhZGRyZXNzIGZpcnN0LiBZb3UgbmVlZCB0byBpbml0aWF0ZSBhbm90aGVyIHN3ZWVwIHR4biBhZnRlciB0aGF0LlxuICAgKiBOb3RlOiB0aGVyZSB3aWxsIGJlIGFub3RoZXIgcmVjb3ZlclRva2VuQ29uc29saWRhdGlvbnMgZnVuY3Rpb24gdG8gc3VwcG9ydCB0b2tlbiByZWNvdmVyIGZyb20gcmVjZWl2ZSBhZGRyZXNzZXMuXG4gICAqXG4gICAqIEBwYXJhbSB7Q29uc29saWRhdGlvblJlY292ZXJ5T3B0aW9uc30gcGFyYW1zIC0gb3B0aW9ucyBmb3IgY29uc29saWRhdGlvbiByZWNvdmVyeS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtwYXJhbXMuc3RhcnRpbmdTY2FuSW5kZXhdIC0gcmVjZWl2ZSBhZGRyZXNzIGluZGV4IHRvIHN0YXJ0IHNjYW5uaW5nIGZyb20uIGRlZmF1bHQgdG8gMSAoaW5jbHVzaXZlKS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtwYXJhbXMuZW5kaW5nU2NhbkluZGV4XSAtIHJlY2VpdmUgYWRkcmVzcyBpbmRleCB0byBlbmQgc2Nhbm5pbmcgYXQuIGRlZmF1bHQgdG8gc3RhcnRpbmdTY2FuSW5kZXggKyAyMCAoZXhjbHVzaXZlKS5cbiAgICovXG4gIGFzeW5jIHJlY292ZXJDb25zb2xpZGF0aW9ucyhwYXJhbXM6IENvbnNvbGlkYXRpb25SZWNvdmVyeU9wdGlvbnMpOiBQcm9taXNlPENvbnNvbGlkYXRpb25SZWNvdmVyeUJhdGNoPiB7XG4gICAgY29uc3QgaXNVbnNpZ25lZENvbnNvbGlkYXRpb25zID0gZ2V0SXNVbnNpZ25lZFN3ZWVwKHBhcmFtcyk7XG4gICAgY29uc3Qgc3RhcnRJZHggPSBwYXJhbXMuc3RhcnRpbmdTY2FuSW5kZXggfHwgMTtcbiAgICBjb25zdCBlbmRJZHggPSBwYXJhbXMuZW5kaW5nU2NhbkluZGV4IHx8IHN0YXJ0SWR4ICsgREVGQVVMVF9TQ0FOX0ZBQ1RPUjtcblxuICAgIGlmIChzdGFydElkeCA8IDEgfHwgZW5kSWR4IDw9IHN0YXJ0SWR4IHx8IGVuZElkeCAtIHN0YXJ0SWR4ID4gMTAgKiBERUZBVUxUX1NDQU5fRkFDVE9SKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIHN0YXJ0aW5nIG9yIGVuZGluZyBpbmRleCB0byBzY2FuIGZvciBhZGRyZXNzZXMuIHN0YXJ0aW5nU2NhbkluZGV4OiAke3N0YXJ0SWR4fSwgZW5kaW5nU2NhbkluZGV4OiAke2VuZElkeH0uYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBrZXlzID0gZ2V0QmlwMzJLZXlzKHRoaXMuYml0Z28sIHBhcmFtcywgeyByZXF1aXJlQml0R29YcHViOiBmYWxzZSB9KTtcbiAgICBjb25zdCBiYXNlQWRkckhleCA9IHRoaXMucHViVG9IZXhBZGRyZXNzKHRoaXMueHB1YlRvVW5jb21wcmVzc2VkUHViKHBhcmFtcy5iaXRnb0tleSkpO1xuXG4gICAgY29uc3QgdHhuc0JhdGNoOiBSZWNvdmVyeVRyYW5zYWN0aW9uW10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gc3RhcnRJZHg7IGkgPCBlbmRJZHg7IGkrKykge1xuICAgICAgY29uc3QgZGVyaXZhdGlvblBhdGggPSBgMC8wLzAvJHtpfWA7XG4gICAgICBjb25zdCB1c2VyS2V5ID0ga2V5c1swXS5kZXJpdmVQYXRoKGRlcml2YXRpb25QYXRoKTtcbiAgICAgIGNvbnN0IHVzZXJLZXlYUHViID0gdXNlcktleS5uZXV0ZXJlZCgpO1xuICAgICAgY29uc3QgcmVjZWl2ZUFkZHJlc3NIZXggPSB0aGlzLnB1YlRvSGV4QWRkcmVzcyh0aGlzLnhwdWJUb1VuY29tcHJlc3NlZFB1Yih1c2VyS2V5WFB1Yi50b0Jhc2U1OCgpKSk7XG4gICAgICBjb25zdCByZWNlaXZlQWRkcmVzcyA9IFV0aWxzLmdldEJhc2U1OEFkZHJlc3NGcm9tSGV4KHJlY2VpdmVBZGRyZXNzSGV4KTtcbiAgICAgIC8vIGNhbGwgdGhlIG5vZGUgdG8gZ2V0IG91ciBhY2NvdW50IGJhbGFuY2VcbiAgICAgIGNvbnN0IGFjY291bnRJbmZvID0gYXdhaXQgdGhpcy5nZXRBY2NvdW50QmFsYW5jZXNGcm9tTm9kZShyZWNlaXZlQWRkcmVzcyk7XG5cbiAgICAgIGlmIChhY2NvdW50SW5mby5kYXRhWzBdICYmIGFjY291bnRJbmZvLmRhdGFbMF0uYmFsYW5jZSA+IFNBRkVfVFJPTl9UUkFOU0FDVElPTl9GRUUpIHtcbiAgICAgICAgbGV0IHJlY292ZXJ5QW1vdW50ID0gMDtcbiAgICAgICAgLy8gVG9rZW5zIG11c3QgYmUgY29uc29saWRhdGUgYmVmb3JlIHRoZSBuYXRpdmUgYXNzZXQuIEZpcnN0IGNvbnN0cnVjdCB0b2tlbiB0eG5zXG4gICAgICAgIGxldCByYXdUb2tlblR4bjogYW55IHwgdW5kZWZpbmVkO1xuXG4gICAgICAgIC8vIGNoZWNrIGZvciBwb3NzaWJsZSB0b2tlbiByZWNvdmVyeSwgcmVjb3ZlciB0aGUgdG9rZW4gcHJvdmlkZSBieSB1c2VyXG4gICAgICAgIGlmIChwYXJhbXMudG9rZW5Db250cmFjdEFkZHJlc3MpIHtcbiAgICAgICAgICBpZiAoYWNjb3VudEluZm8uZGF0YVswXS5iYWxhbmNlID4gU0FGRV9UUk9OX1RPS0VOX1RSQU5TQUNUSU9OX0ZFRSAmJiBhY2NvdW50SW5mby5kYXRhWzBdLnRyYzIwWzBdKSB7XG4gICAgICAgICAgICBjb25zdCB0b2tlbkRhdGFBcnJheSA9IGFjY291bnRJbmZvLmRhdGFbMF0udHJjMjA7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHRva2VuRGF0YSBvZiB0b2tlbkRhdGFBcnJheSkge1xuICAgICAgICAgICAgICBjb25zdCBjb250cmFjdEFkZHJlc3MgPSBPYmplY3Qua2V5cyh0b2tlbkRhdGEpIGFzIEFycmF5PHN0cmluZz47XG4gICAgICAgICAgICAgIGlmIChwYXJhbXMudG9rZW5Db250cmFjdEFkZHJlc3MgPT09IGNvbnRyYWN0QWRkcmVzc1swXSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFtb3VudCA9IHRva2VuRGF0YVtjb250cmFjdEFkZHJlc3NbMF1dO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRva2VuQ29udHJhY3RBZGRySGV4ID0gVXRpbHMuZ2V0SGV4QWRkcmVzc0Zyb21CYXNlNThBZGRyZXNzKGNvbnRyYWN0QWRkcmVzc1swXSk7XG4gICAgICAgICAgICAgICAgcmF3VG9rZW5UeG4gPSAoXG4gICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmdldFRyaWdnZXJTbWFydENvbnRyYWN0VHJhbnNhY3Rpb24oXG4gICAgICAgICAgICAgICAgICAgIGJhc2VBZGRySGV4LFxuICAgICAgICAgICAgICAgICAgICByZWNlaXZlQWRkcmVzc0hleCxcbiAgICAgICAgICAgICAgICAgICAgYW1vdW50LFxuICAgICAgICAgICAgICAgICAgICB0b2tlbkNvbnRyYWN0QWRkckhleFxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICkudHJhbnNhY3Rpb247XG4gICAgICAgICAgICAgICAgcmVjb3ZlcnlBbW91bnQgPSBwYXJzZUludChhbW91bnQsIDEwKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBidWlsZCBhbmQgc2lnbiB0b2tlbiB0eG5zXG4gICAgICAgICAgaWYgKHJhd1Rva2VuVHhuKSB7XG4gICAgICAgICAgICBjb25zdCBhZGRyZXNzSW5mbyA9IHtcbiAgICAgICAgICAgICAgYWRkcmVzczogcmVjZWl2ZUFkZHJlc3MsXG4gICAgICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgICAgICBpbmRleDogaSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKHRoaXMuZ2V0Q2hhaW4oKSkuZnJvbShyYXdUb2tlblR4bik7XG4gICAgICAgICAgICAvLyBEZWZhdWx0IGV4cGlyeSBpcyAxIG1pbnV0ZSB3aGljaCBpcyB0b28gc2hvcnQgZm9yIHJlY292ZXJ5IHB1cnBvc2VzXG4gICAgICAgICAgICAvLyBleHRlbmQgdGhlIGV4cGlyeSB0byAxIGRheVxuICAgICAgICAgICAgdHhCdWlsZGVyLmV4dGVuZFZhbGlkVG8oUkVDT1ZFUl9UUkFOU0FDVElPTl9FWFBJUlkpO1xuICAgICAgICAgICAgLy8gdGhpcyB0eCBzaG91bGQgYmUgZW5vdWdoIHRvIGRyb3AgaW50byBhIG5vZGVcbiAgICAgICAgICAgIGlmICghaXNVbnNpZ25lZENvbnNvbGlkYXRpb25zKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHVzZXJQcnYgPSB0aGlzLnhwcnZUb0NvbXByZXNzZWRQcnYodXNlcktleS50b0Jhc2U1OCgpKTtcbiAgICAgICAgICAgICAgLy8gcmVjZWl2ZSBhZGRyZXNzIG9ubHkgbmVlZHMgdG8gYmUgc2lnbmVkIGJ5IHVzZXIga2V5XG4gICAgICAgICAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB1c2VyUHJ2IH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgICAgIHR4bnNCYXRjaC5wdXNoKFxuICAgICAgICAgICAgICB0aGlzLmZvcm1hdEZvck9mZmxpbmVWYXVsdCh0eCwgU0FGRV9UUk9OX1RPS0VOX1RSQU5TQUNUSU9OX0ZFRSwgcmVjb3ZlcnlBbW91bnQsIGFkZHJlc3NJbmZvKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgYWRkcmVzc0JhbGFuY2UgPSBhY2NvdW50SW5mby5kYXRhWzBdLmJhbGFuY2U7XG4gICAgICAgICAgY29uc3QgYWRkcmVzc0luZm8gPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiByZWNlaXZlQWRkcmVzcyxcbiAgICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgICAgaW5kZXg6IGksXG4gICAgICAgICAgfTtcbiAgICAgICAgICBjb25zdCByZWNvdmVyeUFtb3VudCA9IGFkZHJlc3NCYWxhbmNlIC0gU0FGRV9UUk9OX1RSQU5TQUNUSU9OX0ZFRTtcbiAgICAgICAgICBjb25zdCBidWlsZFR4ID0gYXdhaXQgdGhpcy5nZXRCdWlsZFRyYW5zYWN0aW9uKGJhc2VBZGRySGV4LCByZWNlaXZlQWRkcmVzc0hleCwgcmVjb3ZlcnlBbW91bnQpO1xuICAgICAgICAgIC8vIGNvbnN0cnVjdCBvdXIgdHhcbiAgICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSAoZ2V0QnVpbGRlcih0aGlzLmdldENoYWluKCkpIGFzIFdyYXBwZWRCdWlsZGVyKS5mcm9tKGJ1aWxkVHgpO1xuICAgICAgICAgIC8vIERlZmF1bHQgZXhwaXJ5IGlzIDEgbWludXRlIHdoaWNoIGlzIHRvbyBzaG9ydCBmb3IgcmVjb3ZlcnkgcHVycG9zZXNcbiAgICAgICAgICAvLyBleHRlbmQgdGhlIGV4cGlyeSB0byAxIGRheVxuICAgICAgICAgIHR4QnVpbGRlci5leHRlbmRWYWxpZFRvKFJFQ09WRVJfVFJBTlNBQ1RJT05fRVhQSVJZKTtcblxuICAgICAgICAgIGlmICghaXNVbnNpZ25lZENvbnNvbGlkYXRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCB1c2VyUHJ2ID0gdGhpcy54cHJ2VG9Db21wcmVzc2VkUHJ2KHVzZXJLZXkudG9CYXNlNTgoKSk7XG4gICAgICAgICAgICAvLyByZWNlaXZlIGFkZHJlc3Mgb25seSBuZWVkcyB0byBiZSBzaWduZWQgYnkgdXNlciBrZXlcbiAgICAgICAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB1c2VyUHJ2IH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgICAgIHR4bnNCYXRjaC5wdXNoKHRoaXMuZm9ybWF0Rm9yT2ZmbGluZVZhdWx0KHR4LCBTQUZFX1RST05fVFJBTlNBQ1RJT05fRkVFLCByZWNvdmVyeUFtb3VudCwgYWRkcmVzc0luZm8pKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0cmFuc2FjdGlvbnM6IHR4bnNCYXRjaCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGxhaW4gYSBUcm9uIHRyYW5zYWN0aW9uIGZyb20gdHhIZXhcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgZXhwbGFpblRyYW5zYWN0aW9uKHBhcmFtczogRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8VHJvblRyYW5zYWN0aW9uRXhwbGFuYXRpb24+IHtcbiAgICBjb25zdCB0eEhleCA9IHBhcmFtcy50eEhleCB8fCAocGFyYW1zLmhhbGZTaWduZWQgJiYgcGFyYW1zLmhhbGZTaWduZWQudHhIZXgpO1xuICAgIGlmICghdHhIZXggfHwgIXBhcmFtcy5mZWVJbmZvKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgZXhwbGFpbiB0eCBwYXJhbWV0ZXJzJyk7XG4gICAgfVxuICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIodGhpcy5nZXRDaGFpbigpKS5mcm9tKHR4SGV4KTtcbiAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIGNvbnN0IG91dHB1dHMgPSBbXG4gICAgICB7XG4gICAgICAgIGFtb3VudDogdHgub3V0cHV0c1swXS52YWx1ZS50b1N0cmluZygpLFxuICAgICAgICBhZGRyZXNzOiB0eC5vdXRwdXRzWzBdLmFkZHJlc3MsIC8vIFNob3VsZCB0dXJuIGl0IGludG8gYSByZWFkYWJsZSBmb3JtYXQsIGFrYSBiYXNlNThcbiAgICAgIH0sXG4gICAgXTtcblxuICAgIGNvbnN0IGRpc3BsYXlPcmRlciA9IFtcbiAgICAgICdpZCcsXG4gICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICdjaGFuZ2VBbW91bnQnLFxuICAgICAgJ291dHB1dHMnLFxuICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgJ2ZlZScsXG4gICAgICAndGltZXN0YW1wJyxcbiAgICAgICdleHBpcmF0aW9uJyxcbiAgICBdO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRpc3BsYXlPcmRlcixcbiAgICAgIGlkOiB0eC5pZCxcbiAgICAgIG91dHB1dHMsXG4gICAgICBvdXRwdXRBbW91bnQ6IG91dHB1dHNbMF0uYW1vdW50LFxuICAgICAgY2hhbmdlT3V0cHV0czogW10sIC8vIGFjY291bnQgYmFzZWQgZG9lcyBub3QgdXNlIGNoYW5nZSBvdXRwdXRzXG4gICAgICBjaGFuZ2VBbW91bnQ6ICcwJywgLy8gYWNjb3VudCBiYXNlIGRvZXMgbm90IG1ha2UgY2hhbmdlXG4gICAgICBmZWU6IHBhcmFtcy5mZWVJbmZvLFxuICAgICAgdGltZXN0YW1wOiB0eC52YWxpZEZyb20sXG4gICAgICBleHBpcmF0aW9uOiB0eC52YWxpZFRvLFxuICAgIH07XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKi9cbiAgYXVkaXREZWNyeXB0ZWRLZXkocGFyYW1zOiBBdWRpdERlY3J5cHRlZEtleVBhcmFtcykge1xuICAgIHRocm93IG5ldyBNZXRob2ROb3RJbXBsZW1lbnRlZEVycm9yKCk7XG4gIH1cbn1cbiJdfQ==