@bitgo/sdk-coin-atom 2.1.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/src/atom.d.ts +36 -10
  3. package/dist/src/atom.d.ts.map +1 -1
  4. package/dist/src/atom.js +161 -23
  5. package/dist/src/lib/StakingActivateBuilder.d.ts +11 -0
  6. package/dist/src/lib/StakingActivateBuilder.d.ts.map +1 -0
  7. package/dist/src/lib/StakingActivateBuilder.js +31 -0
  8. package/dist/src/lib/StakingDeactivateBuilder.d.ts +11 -0
  9. package/dist/src/lib/StakingDeactivateBuilder.d.ts.map +1 -0
  10. package/dist/src/lib/StakingDeactivateBuilder.js +31 -0
  11. package/dist/src/lib/StakingWithdrawRewardsBuilder.d.ts +11 -0
  12. package/dist/src/lib/StakingWithdrawRewardsBuilder.d.ts.map +1 -0
  13. package/dist/src/lib/StakingWithdrawRewardsBuilder.js +31 -0
  14. package/dist/src/lib/constants.d.ts +7 -4
  15. package/dist/src/lib/constants.d.ts.map +1 -1
  16. package/dist/src/lib/constants.js +9 -7
  17. package/dist/src/lib/iface.d.ts +27 -12
  18. package/dist/src/lib/iface.d.ts.map +1 -1
  19. package/dist/src/lib/iface.js +1 -1
  20. package/dist/src/lib/index.d.ts +3 -0
  21. package/dist/src/lib/index.d.ts.map +1 -1
  22. package/dist/src/lib/index.js +8 -2
  23. package/dist/src/lib/keyPair.d.ts +0 -2
  24. package/dist/src/lib/keyPair.d.ts.map +1 -1
  25. package/dist/src/lib/keyPair.js +4 -12
  26. package/dist/src/lib/transaction.d.ts +24 -12
  27. package/dist/src/lib/transaction.d.ts.map +1 -1
  28. package/dist/src/lib/transaction.js +181 -71
  29. package/dist/src/lib/transactionBuilder.d.ts +36 -34
  30. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  31. package/dist/src/lib/transactionBuilder.js +97 -129
  32. package/dist/src/lib/transactionBuilderFactory.d.ts +9 -6
  33. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
  34. package/dist/src/lib/transactionBuilderFactory.js +25 -13
  35. package/dist/src/lib/transferBuilder.d.ts +5 -2
  36. package/dist/src/lib/transferBuilder.d.ts.map +1 -1
  37. package/dist/src/lib/transferBuilder.js +18 -2
  38. package/dist/src/lib/utils.d.ts +117 -40
  39. package/dist/src/lib/utils.d.ts.map +1 -1
  40. package/dist/src/lib/utils.js +421 -97
  41. package/package.json +12 -8
@@ -1,37 +1,77 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
2
21
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
22
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
23
  };
5
24
  Object.defineProperty(exports, "__esModule", { value: true });
6
25
  exports.Utils = void 0;
7
26
  const sdk_core_1 = require("@bitgo/sdk-core");
8
- const bignumber_js_1 = __importDefault(require("bignumber.js"));
27
+ const amino_1 = require("@cosmjs/amino");
9
28
  const encoding_1 = require("@cosmjs/encoding");
10
29
  const proto_signing_1 = require("@cosmjs/proto-signing");
11
30
  const stargate_1 = require("@cosmjs/stargate");
12
- const amino_1 = require("@cosmjs/amino");
31
+ const bignumber_js_1 = __importDefault(require("bignumber.js"));
13
32
  const tx_1 = require("cosmjs-types/cosmos/tx/v1beta1/tx");
33
+ const crypto = __importStar(require("crypto"));
34
+ const constants = __importStar(require("./constants"));
35
+ const keyPair_1 = require("./keyPair");
14
36
  class Utils {
37
+ constructor() {
38
+ this.registry = new proto_signing_1.Registry([...stargate_1.defaultRegistryTypes]);
39
+ }
15
40
  /** @inheritdoc */
16
41
  isValidBlockId(hash) {
17
42
  return this.validateBlake2b(hash);
18
43
  }
19
44
  /** @inheritdoc */
20
45
  isValidPrivateKey(key) {
21
- throw new Error('Method not implemented.');
46
+ try {
47
+ new keyPair_1.KeyPair({ prv: key });
48
+ return true;
49
+ }
50
+ catch {
51
+ return false;
52
+ }
22
53
  }
23
54
  /** @inheritdoc */
24
55
  isValidPublicKey(key) {
25
- throw new Error('Method not implemented.');
56
+ try {
57
+ new keyPair_1.KeyPair({ pub: key });
58
+ return true;
59
+ }
60
+ catch {
61
+ return false;
62
+ }
26
63
  }
27
64
  /** @inheritdoc */
28
65
  isValidSignature(signature) {
29
- throw new Error('Method not implemented.');
66
+ throw new sdk_core_1.NotImplementedError('isValidSignature not implemented');
30
67
  }
31
68
  /** @inheritdoc */
32
69
  isValidTransactionId(txId) {
33
70
  return this.validateBlake2b(txId);
34
71
  }
72
+ /**
73
+ * Checks if transaction hash is in valid black2b format
74
+ */
35
75
  validateBlake2b(hash) {
36
76
  if ((hash === null || hash === void 0 ? void 0 : hash.length) !== 64) {
37
77
  return false;
@@ -39,35 +79,25 @@ class Utils {
39
79
  return hash.match(/^[a-zA-Z0-9]+$/) !== null;
40
80
  }
41
81
  /**
42
- * Checks if raw transaction can be deserialized
82
+ * Validates if the address matches with regex @see accountAddressRegex
43
83
  *
44
- * @param {string} rawTransaction - transaction in base64 string format
84
+ * @param {string} address
45
85
  * @returns {boolean} - the validation result
46
86
  */
47
- isValidRawTransaction(rawTransaction) {
48
- throw new Error('Method not implemented.');
87
+ isValidAddress(address) {
88
+ return constants.accountAddressRegex.test(address);
49
89
  }
50
90
  /**
51
- * Check the raw transaction has a valid format in the blockchain context, throw otherwise.
91
+ * Validates if the address matches with regex @see accountAddressRegex
52
92
  *
53
- * @param {string} rawTransaction - Transaction in base64 string format
93
+ * @param {string} address
94
+ * @returns {boolean} - the validation result
54
95
  */
55
- validateRawTransaction(rawTransaction) {
56
- if (!rawTransaction) {
57
- throw new sdk_core_1.ParseTransactionError('Invalid raw transaction: Undefined');
58
- }
59
- if (!this.isValidRawTransaction(rawTransaction)) {
60
- throw new sdk_core_1.ParseTransactionError('Invalid raw transaction');
61
- }
62
- }
63
- isValidAddress(address) {
64
- const allowed_chars = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';
65
- const atomRegex = '^(cosmos)1([' + allowed_chars + ']+)$';
66
- const re = new RegExp(atomRegex);
67
- return re.test(address);
96
+ isValidValidatorAddress(address) {
97
+ return constants.validatorAddressRegex.test(address);
68
98
  }
69
99
  /**
70
- * Returns whether or not the string is a valid amount
100
+ * Validates whether amounts are in range
71
101
  *
72
102
  * @param {number[]} amounts - the amounts to validate
73
103
  * @returns {boolean} - the validation result
@@ -80,6 +110,11 @@ class Utils {
80
110
  }
81
111
  return true;
82
112
  }
113
+ /**
114
+ * Validates whether amount is in range
115
+ * @param {number} amount
116
+ * @returns {boolean} the validation result
117
+ */
83
118
  isValidAmount(amount) {
84
119
  const bigNumberAmount = new bignumber_js_1.default(amount);
85
120
  if (!bigNumberAmount.isInteger() || bigNumberAmount.isLessThanOrEqualTo(0)) {
@@ -89,125 +124,414 @@ class Utils {
89
124
  }
90
125
  /**
91
126
  * Decodes raw tx data into messages, signing info, and fee data
92
- * @param txHex - raw base64 tx
127
+ * @param {string} txHex - raw base64 tx
128
+ * @returns {DecodedTxRaw} Decoded transaction
93
129
  */
94
130
  getDecodedTxFromRawBase64(txRaw) {
95
- return proto_signing_1.decodeTxRaw(encoding_1.fromBase64(txRaw));
131
+ try {
132
+ return proto_signing_1.decodeTxRaw(encoding_1.fromBase64(txRaw));
133
+ }
134
+ catch (e) {
135
+ throw new sdk_core_1.ParseTransactionError('Error decoding TxRaw base64 encoded string: ' + e.message);
136
+ }
96
137
  }
97
138
  /**
98
139
  * Returns the array of messages in the body of the decoded transaction
99
- * @param decodedTx
140
+ * @param {DecodedTxRaw} decodedTx
141
+ * @returns {EncodeObject[]} messages along with type url
100
142
  */
101
143
  getEncodedMessagesFromDecodedTx(decodedTx) {
102
144
  return decodedTx.body.messages;
103
145
  }
104
- /**
105
- * Arranges a decoded message into our MessageData value interface
106
- * @param decodedMessage
107
- * @private
108
- */
109
- getMessageValueDataFromDecodedMessage(decodedMessage) {
110
- return {
111
- fromAddress: decodedMessage.fromAddress,
112
- toAddress: decodedMessage.toAddress,
113
- amount: decodedMessage.amount,
114
- };
115
- }
116
- /**
117
- * Returns an array of MessageData[] from an encoded messages array
118
- * @param encodedMessages
119
- * @private
120
- */
121
- getMessageDataFromEncodedMessages(encodedMessages) {
122
- const registry = new proto_signing_1.Registry(stargate_1.defaultRegistryTypes);
123
- const messageData = [];
124
- for (const message of encodedMessages) {
125
- messageData.push({
126
- value: this.getMessageValueDataFromDecodedMessage(registry.decode(message)),
127
- typeUrl: message.typeUrl,
128
- });
129
- }
130
- return messageData;
131
- }
132
146
  /**
133
147
  * Pulls the sequence number from a DecodedTxRaw AuthInfo property
134
- * @param decodedTx
135
- * @private
148
+ * @param {DecodedTxRaw} decodedTx
149
+ * @returns {number} sequence
136
150
  */
137
151
  getSequenceFromDecodedTx(decodedTx) {
138
152
  return Number(decodedTx.authInfo.signerInfos[0].sequence);
139
153
  }
140
154
  /**
141
155
  * Pulls the typeUrl from the encoded message of a DecodedTxRaw
142
- * @param decodedTx
156
+ * @param {DecodedTxRaw} decodedTx
157
+ * @returns {string} cosmos proto type url
143
158
  */
144
159
  getTypeUrlFromDecodedTx(decodedTx) {
145
160
  const encodedMessage = this.getEncodedMessagesFromDecodedTx(decodedTx)[0];
146
161
  return encodedMessage.typeUrl;
147
162
  }
163
+ /**
164
+ * Returns the fee data from the decoded transaction
165
+ * @param {DecodedTxRaw} decodedTx
166
+ * @returns {FeeData} fee data
167
+ */
148
168
  getGasBudgetFromDecodedTx(decodedTx) {
149
169
  var _a, _b;
150
170
  return {
151
171
  amount: (_a = decodedTx.authInfo.fee) === null || _a === void 0 ? void 0 : _a.amount,
152
- gas: Number((_b = decodedTx.authInfo.fee) === null || _b === void 0 ? void 0 : _b.gasLimit),
172
+ gasLimit: Number((_b = decodedTx.authInfo.fee) === null || _b === void 0 ? void 0 : _b.gasLimit),
153
173
  };
154
174
  }
175
+ /**
176
+ * Returns the publicKey from the decoded transaction
177
+ * @param {DecodedTxRaw} decodedTx
178
+ * @returns {string | undefined} publicKey in hex format if it exists, undefined otherwise
179
+ */
180
+ getPublicKeyFromDecodedTx(decodedTx) {
181
+ var _a, _b, _c, _d;
182
+ const publicKeyUInt8Array = (_b = (_a = decodedTx.authInfo.signerInfos) === null || _a === void 0 ? void 0 : _a[0].publicKey) === null || _b === void 0 ? void 0 : _b.value;
183
+ if (publicKeyUInt8Array) {
184
+ return encoding_1.toHex(encoding_1.fromBase64((_d = proto_signing_1.decodePubkey((_c = decodedTx.authInfo.signerInfos) === null || _c === void 0 ? void 0 : _c[0].publicKey)) === null || _d === void 0 ? void 0 : _d.value));
185
+ }
186
+ return undefined;
187
+ }
155
188
  /**
156
189
  * Returns the array of MessageData[] from the decoded transaction
157
- * @param decodedTx
190
+ * @param {DecodedTxRaw} decodedTx
191
+ * @returns {MessageData[]} Send transaction message data
158
192
  */
159
- getMessageDataFromDecodedTx(decodedTx) {
160
- const encodedMessages = this.getEncodedMessagesFromDecodedTx(decodedTx);
161
- return this.getMessageDataFromEncodedMessages(encodedMessages);
193
+ getSendMessageDataFromDecodedTx(decodedTx) {
194
+ return decodedTx.body.messages.map((message) => {
195
+ const value = this.registry.decode(message);
196
+ return {
197
+ value: {
198
+ fromAddress: value.fromAddress,
199
+ toAddress: value.toAddress,
200
+ amount: value.amount,
201
+ },
202
+ typeUrl: message.typeUrl,
203
+ };
204
+ });
162
205
  }
163
- createSignDocFromAtomTransaction(pubkey, atomTransaction) {
164
- const register = new proto_signing_1.Registry(stargate_1.defaultRegistryTypes);
165
- const txBodyValue = {
166
- messages: atomTransaction.sendMessages,
167
- };
168
- const txBodyBytes = register.encodeTxBody(txBodyValue);
206
+ /**
207
+ * Returns the array of MessageData[] from the decoded transaction
208
+ * @param {DecodedTxRaw} decodedTx
209
+ * @returns {MessageData[]} Delegate of undelegate transaction message data
210
+ */
211
+ getDelegateOrUndelegateMessageDataFromDecodedTx(decodedTx) {
212
+ return decodedTx.body.messages.map((message) => {
213
+ const value = this.registry.decode(message);
214
+ return {
215
+ value: {
216
+ delegatorAddress: value.delegatorAddress,
217
+ validatorAddress: value.validatorAddress,
218
+ amount: value.amount,
219
+ },
220
+ typeUrl: message.typeUrl,
221
+ };
222
+ });
223
+ }
224
+ /**
225
+ * Returns the array of MessageData[] from the decoded transaction
226
+ * @param {DecodedTxRaw} decodedTx
227
+ * @returns {MessageData[]} WithdrawDelegatorRewards transaction message data
228
+ */
229
+ getWithdrawRewardsMessageDataFromDecodedTx(decodedTx) {
230
+ return decodedTx.body.messages.map((message) => {
231
+ const value = this.registry.decode(message);
232
+ return {
233
+ value: {
234
+ delegatorAddress: value.delegatorAddress,
235
+ validatorAddress: value.validatorAddress,
236
+ },
237
+ typeUrl: message.typeUrl,
238
+ };
239
+ });
240
+ }
241
+ /**
242
+ * Returns the array of MessageData[] from the decoded transaction
243
+ * @param {DecodedTxRaw} decodedTx
244
+ * @returns {MessageData[]} Delegate of undelegate transaction message data
245
+ */
246
+ getWithdrawDelegatorRewardsMessageDataFromDecodedTx(decodedTx) {
247
+ return decodedTx.body.messages.map((message) => {
248
+ const value = this.registry.decode(message);
249
+ return {
250
+ value: {
251
+ delegatorAddress: value.delegatorAddress,
252
+ validatorAddress: value.validatorAddress,
253
+ },
254
+ typeUrl: message.typeUrl,
255
+ };
256
+ });
257
+ }
258
+ /**
259
+ * Determines bitgo transaction type based on cosmos proto type url
260
+ * @param {string} typeUrl
261
+ * @returns {TransactionType | undefined} TransactionType if url is supported else undefined
262
+ */
263
+ getTransactionTypeFromTypeUrl(typeUrl) {
264
+ switch (typeUrl) {
265
+ case constants.sendMsgTypeUrl:
266
+ return sdk_core_1.TransactionType.Send;
267
+ case constants.delegateMsgTypeUrl:
268
+ return sdk_core_1.TransactionType.StakingActivate;
269
+ case constants.undelegateMsgTypeUrl:
270
+ return sdk_core_1.TransactionType.StakingDeactivate;
271
+ case constants.withdrawDelegatorRewardMsgTypeUrl:
272
+ return sdk_core_1.TransactionType.StakingWithdraw;
273
+ default:
274
+ return undefined;
275
+ }
276
+ }
277
+ /**
278
+ * Creates a txRaw from an atom transaction @see AtomTransaction
279
+ * @Precondition atomTransaction.publicKey must be defined
280
+ * @param {AtomTransaction} atomTransaction
281
+ * @returns {TxRaw} Unsigned raw transaction
282
+ */
283
+ createTxRawFromAtomTransaction(atomTransaction) {
284
+ if (!atomTransaction.publicKey) {
285
+ throw new Error('publicKey is required to create a txRaw');
286
+ }
287
+ const encodedPublicKey = proto_signing_1.encodePubkey(amino_1.encodeSecp256k1Pubkey(encoding_1.fromHex(atomTransaction.publicKey)));
288
+ const messages = atomTransaction.sendMessages;
289
+ let txBodyValue;
290
+ if (atomTransaction.memo) {
291
+ txBodyValue = {
292
+ memo: atomTransaction.memo,
293
+ messages: messages,
294
+ };
295
+ }
296
+ else {
297
+ txBodyValue = {
298
+ messages: messages,
299
+ };
300
+ }
301
+ const txBodyBytes = this.registry.encodeTxBody(txBodyValue);
169
302
  const sequence = atomTransaction.sequence;
170
- const authInfoBytes = proto_signing_1.makeAuthInfoBytes([{ pubkey, sequence }], atomTransaction.gasBudget.amount, atomTransaction.gasBudget.gas, undefined, undefined, undefined);
171
- // Ignoring linting because makeSignDoc expects string/number inputs but are null for our purposes
172
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
173
- // @ts-ignore
174
- return proto_signing_1.makeSignDoc(txBodyBytes, authInfoBytes, null, null);
175
- }
176
- createSignedTxRaw(atomSignature, signDoc) {
177
- const stdSignature = amino_1.encodeSecp256k1Signature(encoding_1.fromHex(atomSignature.publicKey.pub), atomSignature.signature);
303
+ const authInfoBytes = proto_signing_1.makeAuthInfoBytes([{ pubkey: encodedPublicKey, sequence }], atomTransaction.gasBudget.amount, atomTransaction.gasBudget.gasLimit, undefined, undefined, undefined);
178
304
  return tx_1.TxRaw.fromPartial({
179
- bodyBytes: signDoc.bodyBytes,
180
- authInfoBytes: signDoc.authInfoBytes,
181
- signatures: [encoding_1.fromBase64(stdSignature.signature)],
305
+ bodyBytes: txBodyBytes,
306
+ authInfoBytes: authInfoBytes,
182
307
  });
183
308
  }
184
- createBase64SignedTxBytesFromSignedTxRaw(signedTxRaw) {
185
- const signedTxBytes = tx_1.TxRaw.encode(signedTxRaw).finish();
186
- return encoding_1.toBase64(signedTxBytes);
309
+ /**
310
+ * Encodes a signature into a txRaw
311
+ * @param {string} publicKeyHex publicKey in hex encoded string format
312
+ * @param {string} signatureHex signature in hex encoded string format
313
+ * @param {TxRaw} unsignedTx raw transaction
314
+ * @returns {TxRaw} Signed raw transaction
315
+ */
316
+ createSignedTxRaw(publicKeyHex, signatureHex, unsignedTx) {
317
+ const stdSignature = amino_1.encodeSecp256k1Signature(encoding_1.fromHex(publicKeyHex), encoding_1.fromHex(signatureHex));
318
+ return tx_1.TxRaw.fromPartial({
319
+ bodyBytes: unsignedTx.bodyBytes,
320
+ authInfoBytes: unsignedTx.authInfoBytes,
321
+ signatures: [encoding_1.fromBase64(stdSignature.signature)],
322
+ });
187
323
  }
324
+ /**
325
+ * Decodes a raw transaction into a DecodedTxRaw and checks if it has non empty signatures
326
+ * @param {string} rawTransaction
327
+ * @returns {boolean} true if transaction is signed else false
328
+ */
188
329
  isSignedRawTx(rawTransaction) {
189
330
  const decodedTx = this.getDecodedTxFromRawBase64(rawTransaction);
190
- if (decodedTx.authInfo.signerInfos.length > 0) {
331
+ if (decodedTx.signatures.length > 0) {
191
332
  return true;
192
333
  }
193
334
  return false;
194
335
  }
195
- getSignerInfoFromRawSignedTx(rawTransaction) {
196
- var _a;
197
- if (!this.isSignedRawTx(rawTransaction)) {
198
- throw new Error('getSignerInfoFromRawTx failed, raw tx is not signed');
336
+ /**
337
+ * Deserializes base64 enocded raw transaction string into @see AtomTransaction
338
+ * @param {string} rawTx base64 enocded raw transaction string
339
+ * @returns {AtomTransaction} Deserialized atomTransaction
340
+ */
341
+ deserializeAtomTransaction(rawTx) {
342
+ var _a, _b;
343
+ const decodedTx = utils.getDecodedTxFromRawBase64(rawTx);
344
+ const typeUrl = utils.getTypeUrlFromDecodedTx(decodedTx);
345
+ const type = utils.getTransactionTypeFromTypeUrl(typeUrl);
346
+ let sendMessageData;
347
+ if (type === sdk_core_1.TransactionType.Send) {
348
+ sendMessageData = utils.getSendMessageDataFromDecodedTx(decodedTx);
199
349
  }
200
- const decodedTx = this.getDecodedTxFromRawBase64(rawTransaction);
201
- const aminoPubKey = decodedTx.authInfo.signerInfos[0].publicKey;
202
- const decodedPubKeyHex = encoding_1.toHex(encoding_1.fromBase64((_a = proto_signing_1.decodePubkey(aminoPubKey)) === null || _a === void 0 ? void 0 : _a.value));
203
- const pubKey = {
204
- pub: decodedPubKeyHex,
350
+ else if (type === sdk_core_1.TransactionType.StakingActivate || type === sdk_core_1.TransactionType.StakingDeactivate) {
351
+ sendMessageData = utils.getDelegateOrUndelegateMessageDataFromDecodedTx(decodedTx);
352
+ }
353
+ else if (type === sdk_core_1.TransactionType.StakingWithdraw) {
354
+ sendMessageData = utils.getWithdrawRewardsMessageDataFromDecodedTx(decodedTx);
355
+ }
356
+ else {
357
+ throw new Error('Transaction type not supported: ' + typeUrl);
358
+ }
359
+ const sequence = utils.getSequenceFromDecodedTx(decodedTx);
360
+ const gasBudget = utils.getGasBudgetFromDecodedTx(decodedTx);
361
+ const publicKey = utils.getPublicKeyFromDecodedTx(decodedTx);
362
+ const signature = ((_a = decodedTx.signatures) === null || _a === void 0 ? void 0 : _a[0]) !== undefined ? Buffer.from(decodedTx.signatures[0]) : undefined;
363
+ return this.createAtomTransactionWithHash(sequence, sendMessageData, gasBudget, publicKey, signature, (_b = decodedTx.body) === null || _b === void 0 ? void 0 : _b.memo);
364
+ }
365
+ createAtomTransaction(sequence, messages, gasBudget, publicKey, memo) {
366
+ const atomTxn = {
367
+ sequence: sequence,
368
+ sendMessages: messages,
369
+ gasBudget: gasBudget,
370
+ publicKey: publicKey,
371
+ memo: memo,
205
372
  };
206
- const signature = Buffer.from(decodedTx.signatures[0]);
207
- return { pubKey, signature };
373
+ this.validateAtomTransaction(atomTxn);
374
+ return atomTxn;
375
+ }
376
+ createAtomTransactionWithHash(sequence, messages, gasBudget, publicKey, signature, memo) {
377
+ const atomTxn = this.createAtomTransaction(sequence, messages, gasBudget, publicKey, memo);
378
+ let hash = constants.UNAVAILABLE_TEXT;
379
+ if (signature !== undefined) {
380
+ const unsignedTx = this.createTxRawFromAtomTransaction(atomTxn);
381
+ const signedTx = tx_1.TxRaw.fromPartial({
382
+ bodyBytes: unsignedTx.bodyBytes,
383
+ authInfoBytes: unsignedTx.authInfoBytes,
384
+ signatures: [signature],
385
+ });
386
+ hash = crypto
387
+ .createHash('sha256')
388
+ .update(tx_1.TxRaw.encode(signedTx).finish())
389
+ .digest()
390
+ .toString('hex')
391
+ .toLocaleUpperCase('en-US');
392
+ return { ...atomTxn, hash: hash, signature: signature };
393
+ }
394
+ return { ...atomTxn, hash: hash };
395
+ }
396
+ validateAtomTransaction(tx) {
397
+ this.validateSequence(tx.sequence);
398
+ this.validateGasBudget(tx.gasBudget);
399
+ this.validatePublicKey(tx.publicKey);
400
+ if (tx.sendMessages === undefined || tx.sendMessages.length === 0) {
401
+ throw new sdk_core_1.InvalidTransactionError('Invalid transaction: messages is required');
402
+ }
403
+ else {
404
+ tx.sendMessages.forEach((message) => this.validateMessageData(message));
405
+ }
406
+ }
407
+ validateMessageData(messageData) {
408
+ if (messageData == null) {
409
+ throw new sdk_core_1.InvalidTransactionError(`Invalid MessageData: undefined`);
410
+ }
411
+ if (messageData.typeUrl == null || utils.getTransactionTypeFromTypeUrl(messageData.typeUrl) == null) {
412
+ throw new sdk_core_1.InvalidTransactionError(`Invalid MessageData typeurl: ` + messageData.typeUrl);
413
+ }
414
+ const type = utils.getTransactionTypeFromTypeUrl(messageData.typeUrl);
415
+ if (type === sdk_core_1.TransactionType.Send) {
416
+ const value = messageData.value;
417
+ if (value.toAddress == null) {
418
+ throw new sdk_core_1.InvalidTransactionError(`Invalid MessageData value.toAddress: ` + value.toAddress);
419
+ }
420
+ if (value.fromAddress == null) {
421
+ throw new sdk_core_1.InvalidTransactionError(`Invalid MessageData value.fromAddress: ` + value.fromAddress);
422
+ }
423
+ }
424
+ else if (type === sdk_core_1.TransactionType.StakingActivate || type === sdk_core_1.TransactionType.StakingDeactivate) {
425
+ const value = messageData.value;
426
+ if (value.validatorAddress == null) {
427
+ throw new sdk_core_1.InvalidTransactionError(`Invalid MessageData value.validatorAddress: ` + value.validatorAddress);
428
+ }
429
+ if (value.delegatorAddress == null) {
430
+ throw new sdk_core_1.InvalidTransactionError(`Invalid MessageData value.delegatorAddress: ` + value.delegatorAddress);
431
+ }
432
+ this.validateAmount(messageData.value.amount);
433
+ }
434
+ else if (type === sdk_core_1.TransactionType.StakingWithdraw) {
435
+ const value = messageData.value;
436
+ if (value.validatorAddress == null) {
437
+ throw new sdk_core_1.InvalidTransactionError(`Invalid MessageData value.validatorAddress: ` + value.validatorAddress);
438
+ }
439
+ if (value.delegatorAddress == null) {
440
+ throw new sdk_core_1.InvalidTransactionError(`Invalid MessageData value.delegatorAddress: ` + value.delegatorAddress);
441
+ }
442
+ }
443
+ else {
444
+ throw new sdk_core_1.InvalidTransactionError(`Invalid MessageData TypeUrl is not supported: ` + messageData.typeUrl);
445
+ }
446
+ if (type !== sdk_core_1.TransactionType.StakingWithdraw) {
447
+ }
448
+ }
449
+ validateAmountData(amountArray) {
450
+ amountArray.forEach((coinAmount) => {
451
+ this.validateAmount(coinAmount);
452
+ });
453
+ }
454
+ validateAmount(amount) {
455
+ const amountBig = bignumber_js_1.default(amount.amount);
456
+ if (amountBig.isLessThanOrEqualTo(0)) {
457
+ throw new sdk_core_1.InvalidTransactionError('transactionBuilder: validateAmount: Invalid amount: ' + amount.amount);
458
+ }
459
+ if (!constants.validDenoms.find((denom) => denom === amount.denom)) {
460
+ throw new sdk_core_1.InvalidTransactionError('transactionBuilder: validateAmount: Invalid denom: ' + amount.denom);
461
+ }
462
+ }
463
+ validateGasBudget(gasBudget) {
464
+ if (gasBudget.gasLimit <= 0) {
465
+ throw new sdk_core_1.InvalidTransactionError('Invalid gas limit ' + gasBudget.gasLimit);
466
+ }
467
+ this.validateAmountData(gasBudget.amount);
468
+ }
469
+ validateSequence(sequence) {
470
+ if (sequence < 0) {
471
+ throw new sdk_core_1.InvalidTransactionError('Invalid sequence: less than zero');
472
+ }
473
+ }
474
+ validatePublicKey(publicKey) {
475
+ if (publicKey !== undefined) {
476
+ try {
477
+ new keyPair_1.KeyPair({ pub: publicKey });
478
+ }
479
+ catch {
480
+ throw new sdk_core_1.InvalidTransactionError(`Key validation failed`);
481
+ }
482
+ }
483
+ }
484
+ /**
485
+ * Creates a sign doc from an atom transaction @see AtomTransaction
486
+ * @Precondition atomTransaction.accountNumber and atomTransaction.chainId must be defined
487
+ * @param {AtomTransaction} atomTransaction
488
+ * @returns {SignDoc} sign doc
489
+ */
490
+ createSignDoc(atomTransaction, accountNumber, chainId) {
491
+ if (!accountNumber) {
492
+ throw new Error('accountNumber is required to create a sign doc');
493
+ }
494
+ if (!chainId) {
495
+ throw new Error('chainId is required to create a sign doc');
496
+ }
497
+ if (!atomTransaction) {
498
+ throw new Error('atomTransaction is required to create a sign doc');
499
+ }
500
+ const txRaw = utils.createTxRawFromAtomTransaction(atomTransaction);
501
+ return proto_signing_1.makeSignDoc(txRaw.bodyBytes, txRaw.authInfoBytes, chainId, accountNumber);
502
+ }
503
+ validateDelegateOrUndelegateMessage(delegateMessage) {
504
+ if (!delegateMessage.validatorAddress || !utils.isValidValidatorAddress(delegateMessage.validatorAddress)) {
505
+ throw new sdk_core_1.InvalidTransactionError(`Invalid DelegateOrUndelegeteMessage validatorAddress: ` + delegateMessage.validatorAddress);
506
+ }
507
+ if (!delegateMessage.delegatorAddress || !utils.isValidAddress(delegateMessage.delegatorAddress)) {
508
+ throw new sdk_core_1.InvalidTransactionError(`Invalid DelegateOrUndelegeteMessage delegatorAddress: ` + delegateMessage.delegatorAddress);
509
+ }
510
+ this.validateAmount(delegateMessage.amount);
511
+ }
512
+ validateWithdrawRewardsMessage(withdrawRewardsMessage) {
513
+ if (!withdrawRewardsMessage.validatorAddress ||
514
+ !utils.isValidValidatorAddress(withdrawRewardsMessage.validatorAddress)) {
515
+ throw new sdk_core_1.InvalidTransactionError(`Invalid WithdrawDelegatorRewardsMessage validatorAddress: ` + withdrawRewardsMessage.validatorAddress);
516
+ }
517
+ if (!withdrawRewardsMessage.delegatorAddress || !utils.isValidAddress(withdrawRewardsMessage.delegatorAddress)) {
518
+ throw new sdk_core_1.InvalidTransactionError(`Invalid WithdrawDelegatorRewardsMessage delegatorAddress: ` + withdrawRewardsMessage.delegatorAddress);
519
+ }
520
+ }
521
+ validateSendMessage(sendMessage) {
522
+ if (!sendMessage.toAddress || !utils.isValidAddress(sendMessage.toAddress)) {
523
+ throw new sdk_core_1.InvalidTransactionError(`Invalid SendMessage toAddress: ` + sendMessage.toAddress);
524
+ }
525
+ if (!sendMessage.fromAddress || !utils.isValidAddress(sendMessage.fromAddress)) {
526
+ throw new sdk_core_1.InvalidTransactionError(`Invalid SendMessage fromAddress: ` + sendMessage.fromAddress);
527
+ }
528
+ this.validateAmountData(sendMessage.amount);
529
+ }
530
+ isValidHexString(hexString) {
531
+ return /^[0-9A-Fa-f]*$/.test(hexString);
208
532
  }
209
533
  }
210
534
  exports.Utils = Utils;
211
535
  const utils = new Utils();
212
536
  exports.default = utils;
213
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLDhDQUE4RTtBQUM5RSxnRUFBcUM7QUFDckMsK0NBQXdFO0FBQ3hFLHlEQVErQjtBQUUvQiwrQ0FBOEQ7QUFDOUQseUNBQXlEO0FBQ3pELDBEQUFtRTtBQUduRSxNQUFhLEtBQUs7SUFDaEIsa0JBQWtCO0lBQ2xCLGNBQWMsQ0FBQyxJQUFZO1FBQ3pCLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLGlCQUFpQixDQUFDLEdBQVc7UUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRCxrQkFBa0I7SUFDbEIsZ0JBQWdCLENBQUMsR0FBVztRQUMxQixNQUFNLElBQUksS0FBSyxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVELGtCQUFrQjtJQUNsQixnQkFBZ0IsQ0FBQyxTQUFpQjtRQUNoQyxNQUFNLElBQUksS0FBSyxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVELGtCQUFrQjtJQUNsQixvQkFBb0IsQ0FBQyxJQUFZO1FBQy9CLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQsZUFBZSxDQUFDLElBQVk7UUFDMUIsSUFBSSxDQUFBLElBQUksYUFBSixJQUFJLHVCQUFKLElBQUksQ0FBRSxNQUFNLE1BQUssRUFBRSxFQUFFO1lBQ3ZCLE9BQU8sS0FBSyxDQUFDO1NBQ2Q7UUFDRCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxJQUFJLENBQUM7SUFDL0MsQ0FBQztJQUNEOzs7OztPQUtHO0lBQ0gscUJBQXFCLENBQUMsY0FBc0I7UUFDMUMsTUFB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Q0FBQyxTQUFnQixDQUFDO1FBQ3ZFLE1BQU0sZ0JBQWdCLEdBQUcsZ0JBQUssQ0FBQyxxQkFBVSxDQUFDLE1BQUEsNEJBQVksQ0FBQyxXQUFXLENBQUMsMENBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUM3RSxNQUFNLE1BQU0sR0FBRztZQUNiLEdBQUcsRUFBRSxnQkFBZ0I7U0FDdEIsQ0FBQztRQUNGLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZELE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLENBQUM7SUFDL0IsQ0FBQztDQUNGO0FBOU5ELHNCQThOQztBQUVELE1BQU0sS0FBSyxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7QUFFMUIsa0JBQWUsS0FBSyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQmFzZVV0aWxzLCBQYXJzZVRyYW5zYWN0aW9uRXJyb3IsIFNpZ25hdHVyZSB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgQmlnTnVtYmVyIGZyb20gJ2JpZ251bWJlci5qcyc7XG5pbXBvcnQgeyBmcm9tQmFzZTY0LCBmcm9tSGV4LCB0b0Jhc2U2NCwgdG9IZXggfSBmcm9tICdAY29zbWpzL2VuY29kaW5nJztcbmltcG9ydCB7XG4gIERlY29kZWRUeFJhdyxcbiAgZGVjb2RlUHVia2V5LFxuICBkZWNvZGVUeFJhdyxcbiAgRW5jb2RlT2JqZWN0LFxuICBtYWtlQXV0aEluZm9CeXRlcyxcbiAgbWFrZVNpZ25Eb2MsXG4gIFJlZ2lzdHJ5LFxufSBmcm9tICdAY29zbWpzL3Byb3RvLXNpZ25pbmcnO1xuaW1wb3J0IHsgQXRvbVRyYW5zYWN0aW9uLCBHYXNGZWVMaW1pdERhdGEsIE1lc3NhZ2VEYXRhIH0gZnJvbSAnLi9pZmFjZSc7XG5pbXBvcnQgeyBDb2luLCBkZWZhdWx0UmVnaXN0cnlUeXBlcyB9IGZyb20gJ0Bjb3NtanMvc3RhcmdhdGUnO1xuaW1wb3J0IHsgZW5jb2RlU2VjcDI1NmsxU2lnbmF0dXJlIH0gZnJvbSAnQGNvc21qcy9hbWlubyc7XG5pbXBvcnQgeyBUeFJhdywgU2lnbkRvYyB9IGZyb20gJ2Nvc21qcy10eXBlcy9jb3Ntb3MvdHgvdjFiZXRhMS90eCc7XG5pbXBvcnQgeyBBbnkgfSBmcm9tICdjb3NtanMtdHlwZXMvZ29vZ2xlL3Byb3RvYnVmL2FueSc7XG5cbmV4cG9ydCBjbGFzcyBVdGlscyBpbXBsZW1lbnRzIEJhc2VVdGlscyB7XG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBpc1ZhbGlkQmxvY2tJZChoYXNoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUJsYWtlMmIoaGFzaCk7XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgaXNWYWxpZFByaXZhdGVLZXkoa2V5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBub3QgaW1wbGVtZW50ZWQuJyk7XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgaXNWYWxpZFB1YmxpY0tleShrZXk6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHRocm93IG5ldyBFcnJvcignTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC4nKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBpc1ZhbGlkU2lnbmF0dXJlKHNpZ25hdHVyZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNZXRob2Qgbm90IGltcGxlbWVudGVkLicpO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIGlzVmFsaWRUcmFuc2FjdGlvbklkKHR4SWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnZhbGlkYXRlQmxha2UyYih0eElkKTtcbiAgfVxuXG4gIHZhbGlkYXRlQmxha2UyYihoYXNoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoaGFzaD8ubGVuZ3RoICE9PSA2NCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gaGFzaC5tYXRjaCgvXlthLXpBLVowLTldKyQvKSAhPT0gbnVsbDtcbiAgfVxuICAvKipcbiAgICogQ2hlY2tzIGlmIHJhdyB0cmFuc2FjdGlvbiBjYW4gYmUgZGVzZXJpYWxpemVkXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByYXdUcmFuc2FjdGlvbiAtIHRyYW5zYWN0aW9uIGluIGJhc2U2NCBzdHJpbmcgZm9ybWF0XG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIHRoZSB2YWxpZGF0aW9uIHJlc3VsdFxuICAgKi9cbiAgaXNWYWxpZFJhd1RyYW5zYWN0aW9uKHJhd1RyYW5zYWN0aW9uOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBub3QgaW1wbGVtZW50ZWQuJyk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgdGhlIHJhdyB0cmFuc2FjdGlvbiBoYXMgYSB2YWxpZCBmb3JtYXQgaW4gdGhlIGJsb2NrY2hhaW4gY29udGV4dCwgdGhyb3cgb3RoZXJ3aXNlLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmF3VHJhbnNhY3Rpb24gLSBUcmFuc2FjdGlvbiBpbiBiYXNlNjQgc3RyaW5nICBmb3JtYXRcbiAgICovXG4gIHZhbGlkYXRlUmF3VHJhbnNhY3Rpb24ocmF3VHJhbnNhY3Rpb246IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghcmF3VHJhbnNhY3Rpb24pIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZVRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgcmF3IHRyYW5zYWN0aW9uOiBVbmRlZmluZWQnKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmlzVmFsaWRSYXdUcmFuc2FjdGlvbihyYXdUcmFuc2FjdGlvbikpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZVRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgcmF3IHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuICB9XG5cbiAgaXNWYWxpZEFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYWxsb3dlZF9jaGFycyA9ICdxcHpyeTl4OGdmMnR2ZHcwczNqbjU0a2hjZTZtdWE3bCc7XG4gICAgY29uc3QgYXRvbVJlZ2V4ID0gJ14oY29zbW9zKTEoWycgKyBhbGxvd2VkX2NoYXJzICsgJ10rKSQnO1xuICAgIGNvbnN0IHJlID0gbmV3IFJlZ0V4cChhdG9tUmVnZXgpO1xuICAgIHJldHVybiByZS50ZXN0KGFkZHJlc3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIHN0cmluZyBpcyBhIHZhbGlkIGFtb3VudFxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcltdfSBhbW91bnRzIC0gdGhlIGFtb3VudHMgdG8gdmFsaWRhdGVcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gdGhlIHZhbGlkYXRpb24gcmVzdWx0XG4gICAqL1xuICBpc1ZhbGlkQW1vdW50cyhhbW91bnRzOiBudW1iZXJbXSk6IGJvb2xlYW4ge1xuICAgIGZvciAoY29uc3QgYW1vdW50IG9mIGFtb3VudHMpIHtcbiAgICAgIGlmICghdGhpcy5pc1ZhbGlkQW1vdW50KGFtb3VudCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlzVmFsaWRBbW91bnQoYW1vdW50OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBjb25zdCBiaWdOdW1iZXJBbW91bnQgPSBuZXcgQmlnTnVtYmVyKGFtb3VudCk7XG4gICAgaWYgKCFiaWdOdW1iZXJBbW91bnQuaXNJbnRlZ2VyKCkgfHwgYmlnTnVtYmVyQW1vdW50LmlzTGVzc1RoYW5PckVxdWFsVG8oMCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogRGVjb2RlcyByYXcgdHggZGF0YSBpbnRvIG1lc3NhZ2VzLCBzaWduaW5nIGluZm8sIGFuZCBmZWUgZGF0YVxuICAgKiBAcGFyYW0gdHhIZXggLSByYXcgYmFzZTY0IHR4XG4gICAqL1xuICBnZXREZWNvZGVkVHhGcm9tUmF3QmFzZTY0KHR4UmF3OiBzdHJpbmcpOiBEZWNvZGVkVHhSYXcge1xuICAgIHJldHVybiBkZWNvZGVUeFJhdyhmcm9tQmFzZTY0KHR4UmF3KSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgYXJyYXkgb2YgbWVzc2FnZXMgaW4gdGhlIGJvZHkgb2YgdGhlIGRlY29kZWQgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIGRlY29kZWRUeFxuICAgKi9cbiAgcHJpdmF0ZSBnZXRFbmNvZGVkTWVzc2FnZXNGcm9tRGVjb2RlZFR4KGRlY29kZWRUeDogRGVjb2RlZFR4UmF3KTogRW5jb2RlT2JqZWN0W10ge1xuICAgIHJldHVybiBkZWNvZGVkVHguYm9keS5tZXNzYWdlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBcnJhbmdlcyBhIGRlY29kZWQgbWVzc2FnZSBpbnRvIG91ciBNZXNzYWdlRGF0YSB2YWx1ZSBpbnRlcmZhY2VcbiAgICogQHBhcmFtIGRlY29kZWRNZXNzYWdlXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGdldE1lc3NhZ2VWYWx1ZURhdGFGcm9tRGVjb2RlZE1lc3NhZ2UoZGVjb2RlZE1lc3NhZ2U6IGFueSk6IGFueSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGZyb21BZGRyZXNzOiBkZWNvZGVkTWVzc2FnZS5mcm9tQWRkcmVzcyxcbiAgICAgIHRvQWRkcmVzczogZGVjb2RlZE1lc3NhZ2UudG9BZGRyZXNzLFxuICAgICAgYW1vdW50OiBkZWNvZGVkTWVzc2FnZS5hbW91bnQsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIE1lc3NhZ2VEYXRhW10gZnJvbSBhbiBlbmNvZGVkIG1lc3NhZ2VzIGFycmF5XG4gICAqIEBwYXJhbSBlbmNvZGVkTWVzc2FnZXNcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgZ2V0TWVzc2FnZURhdGFGcm9tRW5jb2RlZE1lc3NhZ2VzKGVuY29kZWRNZXNzYWdlczogRW5jb2RlT2JqZWN0W10pOiBNZXNzYWdlRGF0YVtdIHtcbiAgICBjb25zdCByZWdpc3RyeSA9IG5ldyBSZWdpc3RyeShkZWZhdWx0UmVnaXN0cnlUeXBlcyk7XG4gICAgY29uc3QgbWVzc2FnZURhdGE6IE1lc3NhZ2VEYXRhW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IG1lc3NhZ2Ugb2YgZW5jb2RlZE1lc3NhZ2VzKSB7XG4gICAgICBtZXNzYWdlRGF0YS5wdXNoKHtcbiAgICAgICAgdmFsdWU6IHRoaXMuZ2V0TWVzc2FnZVZhbHVlRGF0YUZyb21EZWNvZGVkTWVzc2FnZShyZWdpc3RyeS5kZWNvZGUobWVzc2FnZSkpLFxuICAgICAgICB0eXBlVXJsOiBtZXNzYWdlLnR5cGVVcmwsXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIG1lc3NhZ2VEYXRhO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1bGxzIHRoZSBzZXF1ZW5jZSBudW1iZXIgZnJvbSBhIERlY29kZWRUeFJhdyBBdXRoSW5mbyBwcm9wZXJ0eVxuICAgKiBAcGFyYW0gZGVjb2RlZFR4XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBnZXRTZXF1ZW5jZUZyb21EZWNvZGVkVHgoZGVjb2RlZFR4OiBEZWNvZGVkVHhSYXcpOiBudW1iZXIge1xuICAgIHJldHVybiBOdW1iZXIoZGVjb2RlZFR4LmF1dGhJbmZvLnNpZ25lckluZm9zWzBdLnNlcXVlbmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWxscyB0aGUgdHlwZVVybCBmcm9tIHRoZSBlbmNvZGVkIG1lc3NhZ2Ugb2YgYSBEZWNvZGVkVHhSYXdcbiAgICogQHBhcmFtIGRlY29kZWRUeFxuICAgKi9cbiAgZ2V0VHlwZVVybEZyb21EZWNvZGVkVHgoZGVjb2RlZFR4OiBEZWNvZGVkVHhSYXcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGVuY29kZWRNZXNzYWdlID0gdGhpcy5nZXRFbmNvZGVkTWVzc2FnZXNGcm9tRGVjb2RlZFR4KGRlY29kZWRUeClbMF07XG4gICAgcmV0dXJuIGVuY29kZWRNZXNzYWdlLnR5cGVVcmw7XG4gIH1cblxuICBnZXRHYXNCdWRnZXRGcm9tRGVjb2RlZFR4KGRlY29kZWRUeDogRGVjb2RlZFR4UmF3KTogR2FzRmVlTGltaXREYXRhIHtcbiAgICByZXR1cm4ge1xuICAgICAgYW1vdW50OiBkZWNvZGVkVHguYXV0aEluZm8uZmVlPy5hbW91bnQgYXMgQ29pbltdLFxuICAgICAgZ2FzOiBOdW1iZXIoZGVjb2RlZFR4LmF1dGhJbmZvLmZlZT8uZ2FzTGltaXQpLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgYXJyYXkgb2YgTWVzc2FnZURhdGFbXSBmcm9tIHRoZSBkZWNvZGVkIHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSBkZWNvZGVkVHhcbiAgICovXG4gIGdldE1lc3NhZ2VEYXRhRnJvbURlY29kZWRUeChkZWNvZGVkVHg6IERlY29kZWRUeFJhdyk6IE1lc3NhZ2VEYXRhW10ge1xuICAgIGNvbnN0IGVuY29kZWRNZXNzYWdlcyA9IHRoaXMuZ2V0RW5jb2RlZE1lc3NhZ2VzRnJvbURlY29kZWRUeChkZWNvZGVkVHgpO1xuICAgIHJldHVybiB0aGlzLmdldE1lc3NhZ2VEYXRhRnJvbUVuY29kZWRNZXNzYWdlcyhlbmNvZGVkTWVzc2FnZXMpO1xuICB9XG5cbiAgY3JlYXRlU2lnbkRvY0Zyb21BdG9tVHJhbnNhY3Rpb24ocHVia2V5OiBhbnksIGF0b21UcmFuc2FjdGlvbjogQXRvbVRyYW5zYWN0aW9uKSB7XG4gICAgY29uc3QgcmVnaXN0ZXIgPSBuZXcgUmVnaXN0cnkoZGVmYXVsdFJlZ2lzdHJ5VHlwZXMpO1xuICAgIGNvbnN0IHR4Qm9keVZhbHVlID0ge1xuICAgICAgbWVzc2FnZXM6IGF0b21UcmFuc2FjdGlvbi5zZW5kTWVzc2FnZXMgYXMgdW5rbm93biBhcyBBbnlbXSxcbiAgICB9O1xuICAgIGNvbnN0IHR4Qm9keUJ5dGVzID0gcmVnaXN0ZXIuZW5jb2RlVHhCb2R5KHR4Qm9keVZhbHVlKTtcbiAgICBjb25zdCBzZXF1ZW5jZSA9IGF0b21UcmFuc2FjdGlvbi5zZXF1ZW5jZTtcbiAgICBjb25zdCBhdXRoSW5mb0J5dGVzID0gbWFrZUF1dGhJbmZvQnl0ZXMoXG4gICAgICBbeyBwdWJrZXksIHNlcXVlbmNlIH1dLFxuICAgICAgYXRvbVRyYW5zYWN0aW9uLmdhc0J1ZGdldC5hbW91bnQsXG4gICAgICBhdG9tVHJhbnNhY3Rpb24uZ2FzQnVkZ2V0LmdhcyxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZFxuICAgICk7XG4gICAgLy8gSWdub3JpbmcgbGludGluZyBiZWNhdXNlIG1ha2VTaWduRG9jIGV4cGVjdHMgc3RyaW5nL251bWJlciBpbnB1dHMgYnV0IGFyZSBudWxsIGZvciBvdXIgcHVycG9zZXNcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10cy1jb21tZW50XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHJldHVybiBtYWtlU2lnbkRvYyh0eEJvZHlCeXRlcywgYXV0aEluZm9CeXRlcywgbnVsbCwgbnVsbCk7XG4gIH1cblxuICBjcmVhdGVTaWduZWRUeFJhdyhhdG9tU2lnbmF0dXJlOiBTaWduYXR1cmUsIHNpZ25Eb2M6IFNpZ25Eb2MpOiBUeFJhdyB7XG4gICAgY29uc3Qgc3RkU2lnbmF0dXJlID0gZW5jb2RlU2VjcDI1NmsxU2lnbmF0dXJlKGZyb21IZXgoYXRvbVNpZ25hdHVyZS5wdWJsaWNLZXkucHViKSwgYXRvbVNpZ25hdHVyZS5zaWduYXR1cmUpO1xuICAgIHJldHVybiBUeFJhdy5mcm9tUGFydGlhbCh7XG4gICAgICBib2R5Qnl0ZXM6IHNpZ25Eb2MuYm9keUJ5dGVzLFxuICAgICAgYXV0aEluZm9CeXRlczogc2lnbkRvYy5hdXRoSW5mb0J5dGVzLFxuICAgICAgc2lnbmF0dXJlczogW2Zyb21CYXNlNjQoc3RkU2lnbmF0dXJlLnNpZ25hdHVyZSldLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlQmFzZTY0U2lnbmVkVHhCeXRlc0Zyb21TaWduZWRUeFJhdyhzaWduZWRUeFJhdzogVHhSYXcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHNpZ25lZFR4Qnl0ZXMgPSBUeFJhdy5lbmNvZGUoc2lnbmVkVHhSYXcpLmZpbmlzaCgpO1xuICAgIHJldHVybiB0b0Jhc2U2NChzaWduZWRUeEJ5dGVzKTtcbiAgfVxuXG4gIGlzU2lnbmVkUmF3VHgocmF3VHJhbnNhY3Rpb246IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGRlY29kZWRUeCA9IHRoaXMuZ2V0RGVjb2RlZFR4RnJvbVJhd0Jhc2U2NChyYXdUcmFuc2FjdGlvbik7XG4gICAgaWYgKGRlY29kZWRUeC5hdXRoSW5mby5zaWduZXJJbmZvcy5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZ2V0U2lnbmVySW5mb0Zyb21SYXdTaWduZWRUeChyYXdUcmFuc2FjdGlvbjogc3RyaW5nKSB7XG4gICAgaWYgKCF0aGlzLmlzU2lnbmVkUmF3VHgocmF3VHJhbnNhY3Rpb24pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dldFNpZ25lckluZm9Gcm9tUmF3VHggZmFpbGVkLCByYXcgdHggaXMgbm90IHNpZ25lZCcpO1xuICAgIH1cbiAgICBjb25zdCBkZWNvZGVkVHggPSB0aGlzLmdldERlY29kZWRUeEZyb21SYXdCYXNlNjQocmF3VHJhbnNhY3Rpb24pO1xuICAgIGNvbnN0IGFtaW5vUHViS2V5ID0gZGVjb2RlZFR4LmF1dGhJbmZvLnNpZ25lckluZm9zWzBdLnB1YmxpY0tleSBhcyBBbnk7XG4gICAgY29uc3QgZGVjb2RlZFB1YktleUhleCA9IHRvSGV4KGZyb21CYXNlNjQoZGVjb2RlUHVia2V5KGFtaW5vUHViS2V5KT8udmFsdWUpKTtcbiAgICBjb25zdCBwdWJLZXkgPSB7XG4gICAgICBwdWI6IGRlY29kZWRQdWJLZXlIZXgsXG4gICAgfTtcbiAgICBjb25zdCBzaWduYXR1cmUgPSBCdWZmZXIuZnJvbShkZWNvZGVkVHguc2lnbmF0dXJlc1swXSk7XG4gICAgcmV0dXJuIHsgcHViS2V5LCBzaWduYXR1cmUgfTtcbiAgfVxufVxuXG5jb25zdCB1dGlscyA9IG5ldyBVdGlscygpO1xuXG5leHBvcnQgZGVmYXVsdCB1dGlscztcbiJdfQ==
537
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw4Q0FNeUI7QUFDekIseUNBQWdGO0FBQ2hGLCtDQUE4RDtBQUM5RCx5REFTK0I7QUFDL0IsK0NBQThEO0FBQzlELGdFQUFxQztBQUNyQywwREFBbUU7QUFFbkUsK0NBQWlDO0FBRWpDLHVEQUF5QztBQVN6Qyx1Q0FBb0M7QUFFcEMsTUFBYSxLQUFLO0lBQWxCO1FBQ1UsYUFBUSxHQUFHLElBQUksd0JBQVEsQ0FBQyxDQUFDLEdBQUcsK0JBQW9CLENBQUMsQ0FBQyxDQUFDO0lBb2pCN0QsQ0FBQztJQWxqQkMsa0JBQWtCO0lBQ2xCLGNBQWMsQ0FBQyxJQUFZO1FBQ3pCLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLGlCQUFpQixDQUFDLEdBQVc7UUFDM0IsSUFBSTtZQUNGLElBQUksaUJBQU8sQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQzFCLE9BQU8sSUFBSSxDQUFDO1NBQ2I7UUFBQyxNQUFNO1lBQ04sT0FBTyxLQUFLLENBQUM7U0FDZDtJQUNILENBQUM7SUFFRCxrQkFBa0I7SUFDbEIsZ0JBQWdCLENBQUMsR0FBVztRQUMxQixJQUFJO1lBQ0YsSUFBSSxpQkFBTyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFDMUIsT0FBTyxJQUFJLENBQUM7U0FDYjtRQUFDLE1BQU07WUFDTixPQUFPLEtBQUssQ0FBQztTQUNkO0lBQ0gsQ0FBQztJQUVELGtCQUFrQjtJQUNsQixnQkFBZ0IsQ0FBQyxTQUFpQjtRQUNoQyxNQUFNLElBQUksOEJBQW1CLENBQUMsa0NBQWtDLENBQUMsQ0FBQztJQUNwRSxDQUFDO0lBRUQsa0JB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RyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDOUY7UUFDRCxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQzlFLE1BQU0sSUFBSSxrQ0FBdUIsQ0FBQyxtQ0FBbUMsR0FBRyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7U0FDbEc7UUFDRCxJQUFJLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxTQUFpQjtRQUNoQyxPQUFPLGdCQUFnQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMxQyxDQUFDO0NBQ0Y7QUFyakJELHNCQXFqQkM7QUFFRCxNQUFNLEtBQUssR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO0FBRTFCLGtCQUFlLEtBQUssQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEJhc2VVdGlscyxcbiAgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IsXG4gIE5vdEltcGxlbWVudGVkRXJyb3IsXG4gIFBhcnNlVHJhbnNhY3Rpb25FcnJvcixcbiAgVHJhbnNhY3Rpb25UeXBlLFxufSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuaW1wb3J0IHsgZW5jb2RlU2VjcDI1NmsxUHVia2V5LCBlbmNvZGVTZWNwMjU2azFTaWduYXR1cmUgfSBmcm9tICdAY29zbWpzL2FtaW5vJztcbmltcG9ydCB7IGZyb21CYXNlNjQsIGZyb21IZXgsIHRvSGV4IH0gZnJvbSAnQGNvc21qcy9lbmNvZGluZyc7XG5pbXBvcnQge1xuICBEZWNvZGVkVHhSYXcsXG4gIGRlY29kZVB1YmtleSxcbiAgZGVjb2RlVHhSYXcsXG4gIEVuY29kZU9iamVjdCxcbiAgZW5jb2RlUHVia2V5LFxuICBtYWtlQXV0aEluZm9CeXRlcyxcbiAgbWFrZVNpZ25Eb2MsXG4gIFJlZ2lzdHJ5LFxufSBmcm9tICdAY29zbWpzL3Byb3RvLXNpZ25pbmcnO1xuaW1wb3J0IHsgQ29pbiwgZGVmYXVsdFJlZ2lzdHJ5VHlwZXMgfSBmcm9tICdAY29zbWpzL3N0YXJnYXRlJztcbmltcG9ydCBCaWdOdW1iZXIgZnJvbSAnYmlnbnVtYmVyLmpzJztcbmltcG9ydCB7IFNpZ25Eb2MsIFR4UmF3IH0gZnJvbSAnY29zbWpzLXR5cGVzL2Nvc21vcy90eC92MWJldGExL3R4JztcbmltcG9ydCB7IEFueSB9IGZyb20gJ2Nvc21qcy10eXBlcy9nb29nbGUvcHJvdG9idWYvYW55JztcbmltcG9ydCAqIGFzIGNyeXB0byBmcm9tICdjcnlwdG8nO1xuXG5pbXBvcnQgKiBhcyBjb25zdGFudHMgZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IHtcbiAgQXRvbVRyYW5zYWN0aW9uLFxuICBEZWxlZ2F0ZU9yVW5kZWxlZ2V0ZU1lc3NhZ2UsXG4gIEZlZURhdGEsXG4gIE1lc3NhZ2VEYXRhLFxuICBTZW5kTWVzc2FnZSxcbiAgV2l0aGRyYXdEZWxlZ2F0b3JSZXdhcmRzTWVzc2FnZSxcbn0gZnJvbSAnLi9pZmFjZSc7XG5pbXBvcnQgeyBLZXlQYWlyIH0gZnJvbSAnLi9rZXlQYWlyJztcblxuZXhwb3J0IGNsYXNzIFV0aWxzIGltcGxlbWVudHMgQmFzZVV0aWxzIHtcbiAgcHJpdmF0ZSByZWdpc3RyeSA9IG5ldyBSZWdpc3RyeShbLi4uZGVmYXVsdFJlZ2lzdHJ5VHlwZXNdKTtcblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgaXNWYWxpZEJsb2NrSWQoaGFzaDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMudmFsaWRhdGVCbGFrZTJiKGhhc2gpO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIGlzVmFsaWRQcml2YXRlS2V5KGtleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgIG5ldyBLZXlQYWlyKHsgcHJ2OiBrZXkgfSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgaXNWYWxpZFB1YmxpY0tleShrZXk6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHRyeSB7XG4gICAgICBuZXcgS2V5UGFpcih7IHB1Yjoga2V5IH0pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIGlzVmFsaWRTaWduYXR1cmUoc2lnbmF0dXJlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFcnJvcignaXNWYWxpZFNpZ25hdHVyZSBub3QgaW1wbGVtZW50ZWQnKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBpc1ZhbGlkVHJhbnNhY3Rpb25JZCh0eElkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUJsYWtlMmIodHhJZCk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRyYW5zYWN0aW9uIGhhc2ggaXMgaW4gdmFsaWQgYmxhY2syYiBmb3JtYXRcbiAgICovXG4gIHZhbGlkYXRlQmxha2UyYihoYXNoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoaGFzaD8ubGVuZ3RoICE9PSA2NCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gaGFzaC5tYXRjaCgvXlthLXpBLVowLTldKyQvKSAhPT0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgaWYgdGhlIGFkZHJlc3MgbWF0Y2hlcyB3aXRoIHJlZ2V4IEBzZWUgYWNjb3VudEFkZHJlc3NSZWdleFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYWRkcmVzc1xuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSB0aGUgdmFsaWRhdGlvbiByZXN1bHRcbiAgICovXG4gIGlzVmFsaWRBZGRyZXNzKGFkZHJlc3M6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBjb25zdGFudHMuYWNjb3VudEFkZHJlc3NSZWdleC50ZXN0KGFkZHJlc3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBpZiB0aGUgYWRkcmVzcyBtYXRjaGVzIHdpdGggcmVnZXggQHNlZSBhY2NvdW50QWRkcmVzc1JlZ2V4XG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhZGRyZXNzXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIHRoZSB2YWxpZGF0aW9uIHJlc3VsdFxuICAgKi9cbiAgaXNWYWxpZFZhbGlkYXRvckFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGNvbnN0YW50cy52YWxpZGF0b3JBZGRyZXNzUmVnZXgudGVzdChhZGRyZXNzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgd2hldGhlciBhbW91bnRzIGFyZSBpbiByYW5nZVxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcltdfSBhbW91bnRzIC0gdGhlIGFtb3VudHMgdG8gdmFsaWRhdGVcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gdGhlIHZhbGlkYXRpb24gcmVzdWx0XG4gICAqL1xuICBpc1ZhbGlkQW1vdW50cyhhbW91bnRzOiBudW1iZXJbXSk6IGJvb2xlYW4ge1xuICAgIGZvciAoY29uc3QgYW1vdW50IG9mIGFtb3VudHMpIHtcbiAgICAgIGlmICghdGhpcy5pc1ZhbGlkQW1vdW50KGFtb3VudCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgd2hldGhlciBhbW91bnQgaXMgaW4gcmFuZ2VcbiAgICogQHBhcmFtIHtudW1iZXJ9IGFtb3VudFxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdGhlIHZhbGlkYXRpb24gcmVzdWx0XG4gICAqL1xuICBpc1ZhbGlkQW1vdW50KGFtb3VudDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYmlnTnVtYmVyQW1vdW50ID0gbmV3IEJpZ051bWJlcihhbW91bnQpO1xuICAgIGlmICghYmlnTnVtYmVyQW1vdW50LmlzSW50ZWdlcigpIHx8IGJpZ051bWJlckFtb3VudC5pc0xlc3NUaGFuT3JFcXVhbFRvKDApKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIERlY29kZXMgcmF3IHR4IGRhdGEgaW50byBtZXNzYWdlcywgc2lnbmluZyBpbmZvLCBhbmQgZmVlIGRhdGFcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR4SGV4IC0gcmF3IGJhc2U2NCB0eFxuICAgKiBAcmV0dXJucyB7RGVjb2RlZFR4UmF3fSBEZWNvZGVkIHRyYW5zYWN0aW9uXG4gICAqL1xuICBnZXREZWNvZGVkVHhGcm9tUmF3QmFzZTY0KHR4UmF3OiBzdHJpbmcpOiBEZWNvZGVkVHhSYXcge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gZGVjb2RlVHhSYXcoZnJvbUJhc2U2NCh0eFJhdykpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZVRyYW5zYWN0aW9uRXJyb3IoJ0Vycm9yIGRlY29kaW5nIFR4UmF3IGJhc2U2NCBlbmNvZGVkIHN0cmluZzogJyArIGUubWVzc2FnZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGFycmF5IG9mIG1lc3NhZ2VzIGluIHRoZSBib2R5IG9mIHRoZSBkZWNvZGVkIHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7RGVjb2RlZFR4UmF3fSBkZWNvZGVkVHhcbiAgICogQHJldHVybnMge0VuY29kZU9iamVjdFtdfSBtZXNzYWdlcyBhbG9uZyB3aXRoIHR5cGUgdXJsXG4gICAqL1xuICBwcml2YXRlIGdldEVuY29kZWRNZXNzYWdlc0Zyb21EZWNvZGVkVHgoZGVjb2RlZFR4OiBEZWNvZGVkVHhSYXcpOiBFbmNvZGVPYmplY3RbXSB7XG4gICAgcmV0dXJuIGRlY29kZWRUeC5ib2R5Lm1lc3NhZ2VzO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1bGxzIHRoZSBzZXF1ZW5jZSBudW1iZXIgZnJvbSBhIERlY29kZWRUeFJhdyBBdXRoSW5mbyBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge0RlY29kZWRUeFJhd30gZGVjb2RlZFR4XG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IHNlcXVlbmNlXG4gICAqL1xuICBnZXRTZXF1ZW5jZUZyb21EZWNvZGVkVHgoZGVjb2RlZFR4OiBEZWNvZGVkVHhSYXcpOiBudW1iZXIge1xuICAgIHJldHVybiBOdW1iZXIoZGVjb2RlZFR4LmF1dGhJbmZvLnNpZ25lckluZm9zWzBdLnNlcXVlbmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWxscyB0aGUgdHlwZVVybCBmcm9tIHRoZSBlbmNvZGVkIG1lc3NhZ2Ugb2YgYSBEZWNvZGVkVHhSYXdcbiAgICogQHBhcmFtIHtEZWNvZGVkVHhSYXd9IGRlY29kZWRUeFxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBjb3Ntb3MgcHJvdG8gdHlwZSB1cmxcbiAgICovXG4gIGdldFR5cGVVcmxGcm9tRGVjb2RlZFR4KGRlY29kZWRUeDogRGVjb2RlZFR4UmF3KTogc3RyaW5nIHtcbiAgICBjb25zdCBlbmNvZGVkTWVzc2FnZSA9IHRoaXMuZ2V0RW5jb2RlZE1lc3NhZ2VzRnJvbURlY29kZWRUeChkZWNvZGVkVHgpWzBdO1xuICAgIHJldHVybiBlbmNvZGVkTWVzc2FnZS50eXBlVXJsO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGZlZSBkYXRhIGZyb20gdGhlIGRlY29kZWQgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtEZWNvZGVkVHhSYXd9IGRlY29kZWRUeFxuICAgKiBAcmV0dXJucyB7RmVlRGF0YX0gZmVlIGRhdGFcbiAgICovXG4gIGdldEdhc0J1ZGdldEZyb21EZWNvZGVkVHgoZGVjb2RlZFR4OiBEZWNvZGVkVHhSYXcpOiBGZWVEYXRhIHtcbiAgICByZXR1cm4ge1xuICAgICAgYW1vdW50OiBkZWNvZGVkVHguYXV0aEluZm8uZmVlPy5hbW91bnQgYXMgQ29pbltdLFxuICAgICAgZ2FzTGltaXQ6IE51bWJlcihkZWNvZGVkVHguYXV0aEluZm8uZmVlPy5nYXNMaW1pdCksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBwdWJsaWNLZXkgZnJvbSB0aGUgZGVjb2RlZCB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge0RlY29kZWRUeFJhd30gZGVjb2RlZFR4XG4gICAqIEByZXR1cm5zIHtzdHJpbmcgfCB1bmRlZmluZWR9IHB1YmxpY0tleSBpbiBoZXggZm9ybWF0IGlmIGl0IGV4aXN0cywgdW5kZWZpbmVkIG90aGVyd2lzZVxuICAgKi9cbiAgZ2V0UHVibGljS2V5RnJvbURlY29kZWRUeChkZWNvZGVkVHg6IERlY29kZWRUeFJhdyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgcHVibGljS2V5VUludDhBcnJheSA9IGRlY29kZWRUeC5hdXRoSW5mby5zaWduZXJJbmZvcz8uWzBdLnB1YmxpY0tleT8udmFsdWU7XG4gICAgaWYgKHB1YmxpY0tleVVJbnQ4QXJyYXkpIHtcbiAgICAgIHJldHVybiB0b0hleChmcm9tQmFzZTY0KGRlY29kZVB1YmtleShkZWNvZGVkVHguYXV0aEluZm8uc2lnbmVySW5mb3M/LlswXS5wdWJsaWNLZXkpPy52YWx1ZSkpO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGFycmF5IG9mIE1lc3NhZ2VEYXRhW10gZnJvbSB0aGUgZGVjb2RlZCB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge0RlY29kZWRUeFJhd30gZGVjb2RlZFR4XG4gICAqIEByZXR1cm5zIHtNZXNzYWdlRGF0YVtdfSBTZW5kIHRyYW5zYWN0aW9uIG1lc3NhZ2UgZGF0YVxuICAgKi9cbiAgZ2V0U2VuZE1lc3NhZ2VEYXRhRnJvbURlY29kZWRUeChkZWNvZGVkVHg6IERlY29kZWRUeFJhdyk6IE1lc3NhZ2VEYXRhW10ge1xuICAgIHJldHVybiBkZWNvZGVkVHguYm9keS5tZXNzYWdlcy5tYXAoKG1lc3NhZ2UpID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5yZWdpc3RyeS5kZWNvZGUobWVzc2FnZSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWx1ZToge1xuICAgICAgICAgIGZyb21BZGRyZXNzOiB2YWx1ZS5mcm9tQWRkcmVzcyxcbiAgICAgICAgICB0b0FkZHJlc3M6IHZhbHVlLnRvQWRkcmVzcyxcbiAgICAgICAgICBhbW91bnQ6IHZhbHVlLmFtb3VudCxcbiAgICAgICAgfSxcbiAgICAgICAgdHlwZVVybDogbWVzc2FnZS50eXBlVXJsLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBhcnJheSBvZiBNZXNzYWdlRGF0YVtdIGZyb20gdGhlIGRlY29kZWQgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtEZWNvZGVkVHhSYXd9IGRlY29kZWRUeFxuICAgKiBAcmV0dXJucyB7TWVzc2FnZURhdGFbXX0gRGVsZWdhdGUgb2YgdW5kZWxlZ2F0ZSB0cmFuc2FjdGlvbiBtZXNzYWdlIGRhdGFcbiAgICovXG4gIGdldERlbGVnYXRlT3JVbmRlbGVnYXRlTWVzc2FnZURhdGFGcm9tRGVjb2RlZFR4KGRlY29kZWRUeDogRGVjb2RlZFR4UmF3KTogTWVzc2FnZURhdGFbXSB7XG4gICAgcmV0dXJuIGRlY29kZWRUeC5ib2R5Lm1lc3NhZ2VzLm1hcCgobWVzc2FnZSkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLnJlZ2lzdHJ5LmRlY29kZShtZXNzYWdlKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgZGVsZWdhdG9yQWRkcmVzczogdmFsdWUuZGVsZWdhdG9yQWRkcmVzcyxcbiAgICAgICAgICB2YWxpZGF0b3JBZGRyZXNzOiB2YWx1ZS52YWxpZGF0b3JBZGRyZXNzLFxuICAgICAgICAgIGFtb3VudDogdmFsdWUuYW1vdW50LFxuICAgICAgICB9LFxuICAgICAgICB0eXBlVXJsOiBtZXNzYWdlLnR5cGVVcmwsXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGFycmF5IG9mIE1lc3NhZ2VEYXRhW10gZnJvbSB0aGUgZGVjb2RlZCB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge0RlY29kZWRUeFJhd30gZGVjb2RlZFR4XG4gICAqIEByZXR1cm5zIHtNZXNzYWdlRGF0YVtdfSBXaXRoZHJhd0RlbGVnYXRvclJld2FyZHMgdHJhbnNhY3Rpb24gbWVzc2FnZSBkYXRhXG4gICAqL1xuICBnZXRXaXRoZHJhd1Jld2FyZHNNZXNzYWdlRGF0YUZyb21EZWNvZGVkVHgoZGVjb2RlZFR4OiBEZWNvZGVkVHhSYXcpOiBNZXNzYWdlRGF0YVtdIHtcbiAgICByZXR1cm4gZGVjb2RlZFR4LmJvZHkubWVzc2FnZXMubWFwKChtZXNzYWdlKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMucmVnaXN0cnkuZGVjb2RlKG1lc3NhZ2UpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICBkZWxlZ2F0b3JBZGRyZXNzOiB2YWx1ZS5kZWxlZ2F0b3JBZGRyZXNzLFxuICAgICAgICAgIHZhbGlkYXRvckFkZHJlc3M6IHZhbHVlLnZhbGlkYXRvckFkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICAgIHR5cGVVcmw6IG1lc3NhZ2UudHlwZVVybCxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgYXJyYXkgb2YgTWVzc2FnZURhdGFbXSBmcm9tIHRoZSBkZWNvZGVkIHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7RGVjb2RlZFR4UmF3fSBkZWNvZGVkVHhcbiAgICogQHJldHVybnMge01lc3NhZ2VEYXRhW119IERlbGVnYXRlIG9mIHVuZGVsZWdhdGUgdHJhbnNhY3Rpb24gbWVzc2FnZSBkYXRhXG4gICAqL1xuICBnZXRXaXRoZHJhd0RlbGVnYXRvclJld2FyZHNNZXNzYWdlRGF0YUZyb21EZWNvZGVkVHgoZGVjb2RlZFR4OiBEZWNvZGVkVHhSYXcpOiBNZXNzYWdlRGF0YVtdIHtcbiAgICByZXR1cm4gZGVjb2RlZFR4LmJvZHkubWVzc2FnZXMubWFwKChtZXNzYWdlKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMucmVnaXN0cnkuZGVjb2RlKG1lc3NhZ2UpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICBkZWxlZ2F0b3JBZGRyZXNzOiB2YWx1ZS5kZWxlZ2F0b3JBZGRyZXNzLFxuICAgICAgICAgIHZhbGlkYXRvckFkZHJlc3M6IHZhbHVlLnZhbGlkYXRvckFkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICAgIHR5cGVVcmw6IG1lc3NhZ2UudHlwZVVybCxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lcyBiaXRnbyB0cmFuc2FjdGlvbiB0eXBlIGJhc2VkIG9uIGNvc21vcyBwcm90byB0eXBlIHVybFxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZVVybFxuICAgKiBAcmV0dXJucyB7VHJhbnNhY3Rpb25UeXBlIHwgdW5kZWZpbmVkfSBUcmFuc2FjdGlvblR5cGUgaWYgdXJsIGlzIHN1cHBvcnRlZCBlbHNlIHVuZGVmaW5lZFxuICAgKi9cbiAgZ2V0VHJhbnNhY3Rpb25UeXBlRnJvbVR5cGVVcmwodHlwZVVybDogc3RyaW5nKTogVHJhbnNhY3Rpb25UeXBlIHwgdW5kZWZpbmVkIHtcbiAgICBzd2l0Y2ggKHR5cGVVcmwpIHtcbiAgICAgIGNhc2UgY29uc3RhbnRzLnNlbmRNc2dUeXBlVXJsOlxuICAgICAgICByZXR1cm4gVHJhbnNhY3Rpb25UeXBlLlNlbmQ7XG4gICAgICBjYXNlIGNvbnN0YW50cy5kZWxlZ2F0ZU1zZ1R5cGVVcmw6XG4gICAgICAgIHJldHVybiBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0FjdGl2YXRlO1xuICAgICAgY2FzZSBjb25zdGFudHMudW5kZWxlZ2F0ZU1zZ1R5cGVVcmw6XG4gICAgICAgIHJldHVybiBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0RlYWN0aXZhdGU7XG4gICAgICBjYXNlIGNvbnN0YW50cy53aXRoZHJhd0RlbGVnYXRvclJld2FyZE1zZ1R5cGVVcmw6XG4gICAgICAgIHJldHVybiBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ1dpdGhkcmF3O1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHR4UmF3IGZyb20gYW4gYXRvbSB0cmFuc2FjdGlvbiBAc2VlIEF0b21UcmFuc2FjdGlvblxuICAgKiBAUHJlY29uZGl0aW9uIGF0b21UcmFuc2FjdGlvbi5wdWJsaWNLZXkgbXVzdCBiZSBkZWZpbmVkXG4gICAqIEBwYXJhbSB7QXRvbVRyYW5zYWN0aW9ufSBhdG9tVHJhbnNhY3Rpb25cbiAgICogQHJldHVybnMge1R4UmF3fSBVbnNpZ25lZCByYXcgdHJhbnNhY3Rpb25cbiAgICovXG4gIGNyZWF0ZVR4UmF3RnJvbUF0b21UcmFuc2FjdGlvbihhdG9tVHJhbnNhY3Rpb246IEF0b21UcmFuc2FjdGlvbik6IFR4UmF3IHtcbiAgICBpZiAoIWF0b21UcmFuc2FjdGlvbi5wdWJsaWNLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigncHVibGljS2V5IGlzIHJlcXVpcmVkIHRvIGNyZWF0ZSBhIHR4UmF3Jyk7XG4gICAgfVxuICAgIGNvbnN0IGVuY29kZWRQdWJsaWNLZXk6IEFueSA9IGVuY29kZVB1YmtleShlbmNvZGVTZWNwMjU2azFQdWJrZXkoZnJvbUhleChhdG9tVHJhbnNhY3Rpb24ucHVibGljS2V5KSkpO1xuICAgIGNvbnN0IG1lc3NhZ2VzID0gYXRvbVRyYW5zYWN0aW9uLnNlbmRNZXNzYWdlcyBhcyB1bmtub3duIGFzIEFueVtdO1xuICAgIGxldCB0eEJvZHlWYWx1ZTtcbiAgICBpZiAoYXRvbVRyYW5zYWN0aW9uLm1lbW8pIHtcbiAgICAgIHR4Qm9keVZhbHVlID0ge1xuICAgICAgICBtZW1vOiBhdG9tVHJhbnNhY3Rpb24ubWVtbyxcbiAgICAgICAgbWVzc2FnZXM6IG1lc3NhZ2VzLFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgdHhCb2R5VmFsdWUgPSB7XG4gICAgICAgIG1lc3NhZ2VzOiBtZXNzYWdlcyxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgdHhCb2R5Qnl0ZXMgPSB0aGlzLnJlZ2lzdHJ5LmVuY29kZVR4Qm9keSh0eEJvZHlWYWx1ZSk7XG4gICAgY29uc3Qgc2VxdWVuY2UgPSBhdG9tVHJhbnNhY3Rpb24uc2VxdWVuY2U7XG4gICAgY29uc3QgYXV0aEluZm9CeXRlcyA9IG1ha2VBdXRoSW5mb0J5dGVzKFxuICAgICAgW3sgcHVia2V5OiBlbmNvZGVkUHVibGljS2V5LCBzZXF1ZW5jZSB9XSxcbiAgICAgIGF0b21UcmFuc2FjdGlvbi5nYXNCdWRnZXQuYW1vdW50LFxuICAgICAgYXRvbVRyYW5zYWN0aW9uLmdhc0J1ZGdldC5nYXNMaW1pdCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHVuZGVmaW5lZFxuICAgICk7XG4gICAgcmV0dXJuIFR4UmF3LmZyb21QYXJ0aWFsKHtcbiAgICAgIGJvZHlCeXRlczogdHhCb2R5Qnl0ZXMsXG4gICAgICBhdXRoSW5mb0J5dGVzOiBhdXRoSW5mb0J5dGVzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuY29kZXMgYSBzaWduYXR1cmUgaW50byBhIHR4UmF3XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwdWJsaWNLZXlIZXggcHVibGljS2V5IGluIGhleCBlbmNvZGVkIHN0cmluZyBmb3JtYXRcbiAgICogQHBhcmFtIHtzdHJpbmd9IHNpZ25hdHVyZUhleCBzaWduYXR1cmUgaW4gaGV4IGVuY29kZWQgc3RyaW5nIGZvcm1hdFxuICAgKiBAcGFyYW0ge1R4UmF3fSB1bnNpZ25lZFR4IHJhdyB0cmFuc2FjdGlvblxuICAgKiBAcmV0dXJucyB7VHhSYXd9IFNpZ25lZCByYXcgdHJhbnNhY3Rpb25cbiAgICovXG4gIGNyZWF0ZVNpZ25lZFR4UmF3KFxuICAgIHB1YmxpY0tleUhleDogc3RyaW5nLFxuICAgIHNpZ25hdHVyZUhleDogc3RyaW5nLFxuICAgIHVuc2lnbmVkVHg6IHsgYm9keUJ5dGVzOiBVaW50OEFycmF5OyBhdXRoSW5mb0J5dGVzOiBVaW50OEFycmF5IH1cbiAgKTogVHhSYXcge1xuICAgIGNvbnN0IHN0ZFNpZ25hdHVyZSA9IGVuY29kZVNlY3AyNTZrMVNpZ25hdHVyZShmcm9tSGV4KHB1YmxpY0tleUhleCksIGZyb21IZXgoc2lnbmF0dXJlSGV4KSk7XG4gICAgcmV0dXJuIFR4UmF3LmZyb21QYXJ0aWFsKHtcbiAgICAgIGJvZHlCeXRlczogdW5zaWduZWRUeC5ib2R5Qnl0ZXMsXG4gICAgICBhdXRoSW5mb0J5dGVzOiB1bnNpZ25lZFR4LmF1dGhJbmZvQnl0ZXMsXG4gICAgICBzaWduYXR1cmVzOiBbZnJvbUJhc2U2NChzdGRTaWduYXR1cmUuc2lnbmF0dXJlKV0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGVjb2RlcyBhIHJhdyB0cmFuc2FjdGlvbiBpbnRvIGEgRGVjb2RlZFR4UmF3IGFuZCBjaGVja3MgaWYgaXQgaGFzIG5vbiBlbXB0eSBzaWduYXR1cmVzXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByYXdUcmFuc2FjdGlvblxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiB0cmFuc2FjdGlvbiBpcyBzaWduZWQgZWxzZSBmYWxzZVxuICAgKi9cbiAgaXNTaWduZWRSYXdUeChyYXdUcmFuc2FjdGlvbjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZGVjb2RlZFR4ID0gdGhpcy5nZXREZWNvZGVkVHhGcm9tUmF3QmFzZTY0KHJhd1RyYW5zYWN0aW9uKTtcbiAgICBpZiAoZGVjb2RlZFR4LnNpZ25hdHVyZXMubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXNlcmlhbGl6ZXMgYmFzZTY0IGVub2NkZWQgcmF3IHRyYW5zYWN0aW9uIHN0cmluZyBpbnRvIEBzZWUgQXRvbVRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByYXdUeCBiYXNlNjQgZW5vY2RlZCByYXcgdHJhbnNhY3Rpb24gc3RyaW5nXG4gICAqIEByZXR1cm5zIHtBdG9tVHJhbnNhY3Rpb259IERlc2VyaWFsaXplZCBhdG9tVHJhbnNhY3Rpb25cbiAgICovXG4gIGRlc2VyaWFsaXplQXRvbVRyYW5zYWN0aW9uKHJhd1R4OiBzdHJpbmcpOiBBdG9tVHJhbnNhY3Rpb24ge1xuICAgIGNvbnN0IGRlY29kZWRUeCA9IHV0aWxzLmdldERlY29kZWRUeEZyb21SYXdCYXNlNjQocmF3VHgpO1xuICAgIGNvbnN0IHR5cGVVcmwgPSB1dGlscy5nZXRUeXBlVXJsRnJvbURlY29kZWRUeChkZWNvZGVkVHgpO1xuICAgIGNvbnN0IHR5cGU6IFRyYW5zYWN0aW9uVHlwZSB8IHVuZGVmaW5lZCA9IHV0aWxzLmdldFRyYW5zYWN0aW9uVHlwZUZyb21UeXBlVXJsKHR5cGVVcmwpO1xuICAgIGxldCBzZW5kTWVzc2FnZURhdGE6IE1lc3NhZ2VEYXRhW107XG4gICAgaWYgKHR5cGUgPT09IFRyYW5zYWN0aW9uVHlwZS5TZW5kKSB7XG4gICAgICBzZW5kTWVzc2FnZURhdGEgPSB1dGlscy5nZXRTZW5kTWVzc2FnZURhdGFGcm9tRGVjb2RlZFR4KGRlY29kZWRUeCk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0FjdGl2YXRlIHx8IHR5cGUgPT09IFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nRGVhY3RpdmF0ZSkge1xuICAgICAgc2VuZE1lc3NhZ2VEYXRhID0gdXRpbHMuZ2V0RGVsZWdhdGVPclVuZGVsZWdhdGVNZXNzYWdlRGF0YUZyb21EZWNvZGVkVHgoZGVjb2RlZFR4KTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nV2l0aGRyYXcpIHtcbiAgICAgIHNlbmRNZXNzYWdlRGF0YSA9IHV0aWxzLmdldFdpdGhkcmF3UmV3YXJkc01lc3NhZ2VEYXRhRnJvbURlY29kZWRUeChkZWNvZGVkVHgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zYWN0aW9uIHR5cGUgbm90IHN1cHBvcnRlZDogJyArIHR5cGVVcmwpO1xuICAgIH1cbiAgICBjb25zdCBzZXF1ZW5jZSA9IHV0aWxzLmdldFNlcXVlbmNlRnJvbURlY29kZWRUeChkZWNvZGVkVHgpO1xuICAgIGNvbnN0IGdhc0J1ZGdldCA9IHV0aWxzLmdldEdhc0J1ZGdldEZyb21EZWNvZGVkVHgoZGVjb2RlZFR4KTtcbiAgICBjb25zdCBwdWJsaWNLZXkgPSB1dGlscy5nZXRQdWJsaWNLZXlGcm9tRGVjb2RlZFR4KGRlY29kZWRUeCk7XG4gICAgY29uc3Qgc2lnbmF0dXJlID0gZGVjb2RlZFR4LnNpZ25hdHVyZXM/LlswXSAhPT0gdW5kZWZpbmVkID8gQnVmZmVyLmZyb20oZGVjb2RlZFR4LnNpZ25hdHVyZXNbMF0pIDogdW5kZWZpbmVkO1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZUF0b21UcmFuc2FjdGlvbldpdGhIYXNoKFxuICAgICAgc2VxdWVuY2UsXG4gICAgICBzZW5kTWVzc2FnZURhdGEsXG4gICAgICBnYXNCdWRnZXQsXG4gICAgICBwdWJsaWNLZXksXG4gICAgICBzaWduYXR1cmUsXG4gICAgICBkZWNvZGVkVHguYm9keT8ubWVtb1xuICAgICk7XG4gIH1cblxuICBjcmVhdGVBdG9tVHJhbnNhY3Rpb24oXG4gICAgc2VxdWVuY2U6IG51bWJlcixcbiAgICBtZXNzYWdlczogTWVzc2FnZURhdGFbXSxcbiAgICBnYXNCdWRnZXQ6IEZlZURhdGEsXG4gICAgcHVibGljS2V5Pzogc3RyaW5nLFxuICAgIG1lbW8/OiBzdHJpbmdcbiAgKTogQXRvbVRyYW5zYWN0aW9uIHtcbiAgICBjb25zdCBhdG9tVHhuID0ge1xuICAgICAgc2VxdWVuY2U6IHNlcXVlbmNlLFxuICAgICAgc2VuZE1lc3NhZ2VzOiBtZXNzYWdlcyxcbiAgICAgIGdhc0J1ZGdldDogZ2FzQnVkZ2V0LFxuICAgICAgcHVibGljS2V5OiBwdWJsaWNLZXksXG4gICAgICBtZW1vOiBtZW1vLFxuICAgIH07XG4gICAgdGhpcy52YWxpZGF0ZUF0b21UcmFuc2FjdGlvbihhdG9tVHhuKTtcbiAgICByZXR1cm4gYXRvbVR4bjtcbiAgfVxuXG4gIGNyZWF0ZUF0b21UcmFuc2FjdGlvbldpdGhIYXNoKFxuICAgIHNlcXVlbmNlOiBudW1iZXIsXG4gICAgbWVzc2FnZXM6IE1lc3NhZ2VEYXRhW10sXG4gICAgZ2FzQnVkZ2V0OiBGZWVEYXRhLFxuICAgIHB1YmxpY0tleT86IHN0cmluZyxcbiAgICBzaWduYXR1cmU/OiBCdWZmZXIsXG4gICAgbWVtbz86IHN0cmluZ1xuICApOiBBdG9tVHJhbnNhY3Rpb24ge1xuICAgIGNvbnN0IGF0b21UeG4gPSB0aGlzLmNyZWF0ZUF0b21UcmFuc2FjdGlvbihzZXF1ZW5jZSwgbWVzc2FnZXMsIGdhc0J1ZGdldCwgcHVibGljS2V5LCBtZW1vKTtcbiAgICBsZXQgaGFzaCA9IGNvbnN0YW50cy5VTkFWQUlMQUJMRV9URVhUO1xuICAgIGlmIChzaWduYXR1cmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgdW5zaWduZWRUeCA9IHRoaXMuY3JlYXRlVHhSYXdGcm9tQXRvbVRyYW5zYWN0aW9uKGF0b21UeG4pO1xuICAgICAgY29uc3Qgc2lnbmVkVHggPSBUeFJhdy5mcm9tUGFydGlhbCh7XG4gICAgICAgIGJvZHlCeXRlczogdW5zaWduZWRUeC5ib2R5Qnl0ZXMsXG4gICAgICAgIGF1dGhJbmZvQnl0ZXM6IHVuc2lnbmVkVHguYXV0aEluZm9CeXRlcyxcbiAgICAgICAgc2lnbmF0dXJlczogW3NpZ25hdHVyZV0sXG4gICAgICB9KTtcbiAgICAgIGhhc2ggPSBjcnlwdG9cbiAgICAgICAgLmNyZWF0ZUhhc2goJ3NoYTI1NicpXG4gICAgICAgIC51cGRhdGUoVHhSYXcuZW5jb2RlKHNpZ25lZFR4KS5maW5pc2goKSlcbiAgICAgICAgLmRpZ2VzdCgpXG4gICAgICAgIC50b1N0cmluZygnaGV4JylcbiAgICAgICAgLnRvTG9jYWxlVXBwZXJDYXNlKCdlbi1VUycpO1xuICAgICAgcmV0dXJuIHsgLi4uYXRvbVR4biwgaGFzaDogaGFzaCwgc2lnbmF0dXJlOiBzaWduYXR1cmUgfTtcbiAgICB9XG4gICAgcmV0dXJuIHsgLi4uYXRvbVR4biwgaGFzaDogaGFzaCB9O1xuICB9XG5cbiAgdmFsaWRhdGVBdG9tVHJhbnNhY3Rpb24odHg6IEF0b21UcmFuc2FjdGlvbik6IHZvaWQge1xuICAgIHRoaXMudmFsaWRhdGVTZXF1ZW5jZSh0eC5zZXF1ZW5jZSk7XG4gICAgdGhpcy52YWxpZGF0ZUdhc0J1ZGdldCh0eC5nYXNCdWRnZXQpO1xuICAgIHRoaXMudmFsaWRhdGVQdWJsaWNLZXkodHgucHVibGljS2V5KTtcbiAgICBpZiAodHguc2VuZE1lc3NhZ2VzID09PSB1bmRlZmluZWQgfHwgdHguc2VuZE1lc3NhZ2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdJbnZhbGlkIHRyYW5zYWN0aW9uOiBtZXNzYWdlcyBpcyByZXF1aXJlZCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0eC5zZW5kTWVzc2FnZXMuZm9yRWFjaCgobWVzc2FnZSkgPT4gdGhpcy52YWxpZGF0ZU1lc3NhZ2VEYXRhKG1lc3NhZ2UpKTtcbiAgICB9XG4gIH1cblxuICB2YWxpZGF0ZU1lc3NhZ2VEYXRhKG1lc3NhZ2VEYXRhOiBNZXNzYWdlRGF0YSk6IHZvaWQge1xuICAgIGlmIChtZXNzYWdlRGF0YSA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoYEludmFsaWQgTWVzc2FnZURhdGE6IHVuZGVmaW5lZGApO1xuICAgIH1cbiAgICBpZiAobWVzc2FnZURhdGEudHlwZVVybCA9PSBudWxsIHx8IHV0aWxzLmdldFRyYW5zYWN0aW9uVHlwZUZyb21UeXBlVXJsKG1lc3NhZ2VEYXRhLnR5cGVVcmwpID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcihgSW52YWxpZCBNZXNzYWdlRGF0YSB0eXBldXJsOiBgICsgbWVzc2FnZURhdGEudHlwZVVybCk7XG4gICAgfVxuICAgIGNvbnN0IHR5cGUgPSB1dGlscy5nZXRUcmFuc2FjdGlvblR5cGVGcm9tVHlwZVVybChtZXNzYWdlRGF0YS50eXBlVXJsKTtcbiAgICBpZiAodHlwZSA9PT0gVHJhbnNhY3Rpb25UeXBlLlNlbmQpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gbWVzc2FnZURhdGEudmFsdWUgYXMgU2VuZE1lc3NhZ2U7XG4gICAgICBpZiAodmFsdWUudG9BZGRyZXNzID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKGBJbnZhbGlkIE1lc3NhZ2VEYXRhIHZhbHVlLnRvQWRkcmVzczogYCArIHZhbHVlLnRvQWRkcmVzcyk7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUuZnJvbUFkZHJlc3MgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoYEludmFsaWQgTWVzc2FnZURhdGEgdmFsdWUuZnJvbUFkZHJlc3M6IGAgKyB2YWx1ZS5mcm9tQWRkcmVzcyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0FjdGl2YXRlIHx8IHR5cGUgPT09IFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nRGVhY3RpdmF0ZSkge1xuICAgICAgY29uc3QgdmFsdWUgPSBtZXNzYWdlRGF0YS52YWx1ZSBhcyBEZWxlZ2F0ZU9yVW5kZWxlZ2V0ZU1lc3NhZ2U7XG4gICAgICBpZiAodmFsdWUudmFsaWRhdG9yQWRkcmVzcyA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcihgSW52YWxpZCBNZXNzYWdlRGF0YSB2YWx1ZS52YWxpZGF0b3JBZGRyZXNzOiBgICsgdmFsdWUudmFsaWRhdG9yQWRkcmVzcyk7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUuZGVsZWdhdG9yQWRkcmVzcyA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcihgSW52YWxpZCBNZXNzYWdlRGF0YSB2YWx1ZS5kZWxlZ2F0b3JBZGRyZXNzOiBgICsgdmFsdWUuZGVsZWdhdG9yQWRkcmVzcyk7XG4gICAgICB9XG4gICAgICB0aGlzLnZhbGlkYXRlQW1vdW50KChtZXNzYWdlRGF0YS52YWx1ZSBhcyBEZWxlZ2F0ZU9yVW5kZWxlZ2V0ZU1lc3NhZ2UpLmFtb3VudCk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ1dpdGhkcmF3KSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IG1lc3NhZ2VEYXRhLnZhbHVlIGFzIFdpdGhkcmF3RGVsZWdhdG9yUmV3YXJkc01lc3NhZ2U7XG4gICAgICBpZiAodmFsdWUudmFsaWRhdG9yQWRkcmVzcyA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcihgSW52YWxpZCBNZXNzYWdlRGF0YSB2YWx1ZS52YWxpZGF0b3JBZGRyZXNzOiBgICsgdmFsdWUudmFsaWRhdG9yQWRkcmVzcyk7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUuZGVsZWdhdG9yQWRkcmVzcyA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcihgSW52YWxpZCBNZXNzYWdlRGF0YSB2YWx1ZS5kZWxlZ2F0b3JBZGRyZXNzOiBgICsgdmFsdWUuZGVsZWdhdG9yQWRkcmVzcyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcihgSW52YWxpZCBNZXNzYWdlRGF0YSBUeXBlVXJsIGlzIG5vdCBzdXBwb3J0ZWQ6IGAgKyBtZXNzYWdlRGF0YS50eXBlVXJsKTtcbiAgICB9XG4gICAgaWYgKHR5cGUgIT09IFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nV2l0aGRyYXcpIHtcbiAgICB9XG4gIH1cblxuICB2YWxpZGF0ZUFtb3VudERhdGEoYW1vdW50QXJyYXk6IENvaW5bXSk6IHZvaWQge1xuICAgIGFtb3VudEFycmF5LmZvckVhY2goKGNvaW5BbW91bnQpID0+IHtcbiAgICAgIHRoaXMudmFsaWRhdGVBbW91bnQoY29pbkFtb3VudCk7XG4gICAgfSk7XG4gIH1cblxuICB2YWxpZGF0ZUFtb3VudChhbW91bnQ6IENvaW4pOiB2b2lkIHtcbiAgICBjb25zdCBhbW91bnRCaWcgPSBCaWdOdW1iZXIoYW1vdW50LmFtb3VudCk7XG4gICAgaWYgKGFtb3VudEJpZy5pc0xlc3NUaGFuT3JFcXVhbFRvKDApKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ3RyYW5zYWN0aW9uQnVpbGRlcjogdmFsaWRhdGVBbW91bnQ6IEludmFsaWQgYW1vdW50OiAnICsgYW1vdW50LmFtb3VudCk7XG4gICAgfVxuICAgIGlmICghY29uc3RhbnRzLnZhbGlkRGVub21zLmZpbmQoKGRlbm9tKSA9PiBkZW5vbSA9PT0gYW1vdW50LmRlbm9tKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCd0cmFuc2FjdGlvbkJ1aWxkZXI6IHZhbGlkYXRlQW1vdW50OiBJbnZhbGlkIGRlbm9tOiAnICsgYW1vdW50LmRlbm9tKTtcbiAgICB9XG4gIH1cblxuICB2YWxpZGF0ZUdhc0J1ZGdldChnYXNCdWRnZXQ6IEZlZURhdGEpOiB2b2lkIHtcbiAgICBpZiAoZ2FzQnVkZ2V0Lmdhc0xpbWl0IDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcignSW52YWxpZCBnYXMgbGltaXQgJyArIGdhc0J1ZGdldC5nYXNMaW1pdCk7XG4gICAgfVxuICAgIHRoaXMudmFsaWRhdGVBbW91bnREYXRhKGdhc0J1ZGdldC5hbW91bnQpO1xuICB9XG5cbiAgdmFsaWRhdGVTZXF1ZW5jZShzZXF1ZW5jZTogbnVtYmVyKSB7XG4gICAgaWYgKHNlcXVlbmNlIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdJbnZhbGlkIHNlcXVlbmNlOiBsZXNzIHRoYW4gemVybycpO1xuICAgIH1cbiAgfVxuXG4gIHZhbGlkYXRlUHVibGljS2V5KHB1YmxpY0tleTogc3RyaW5nIHwgdW5kZWZpbmVkKSB7XG4gICAgaWYgKHB1YmxpY0tleSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0cnkge1xuICAgICAgICBuZXcgS2V5UGFpcih7IHB1YjogcHVibGljS2V5IH0pO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcihgS2V5IHZhbGlkYXRpb24gZmFpbGVkYCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBzaWduIGRvYyBmcm9tIGFuIGF0b20gdHJhbnNhY3Rpb24gQHNlZSBBdG9tVHJhbnNhY3Rpb25cbiAgICogQFByZWNvbmRpdGlvbiBhdG9tVHJhbnNhY3Rpb24uYWNjb3VudE51bWJlciBhbmQgYXRvbVRyYW5zYWN0aW9uLmNoYWluSWQgbXVzdCBiZSBkZWZpbmVkXG4gICAqIEBwYXJhbSB7QXRvbVRyYW5zYWN0aW9ufSBhdG9tVHJhbnNhY3Rpb25cbiAgICogQHJldHVybnMge1NpZ25Eb2N9IHNpZ24gZG9jXG4gICAqL1xuICBjcmVhdGVTaWduRG9jKFxuICAgIGF0b21UcmFuc2FjdGlvbjogQXRvbVRyYW5zYWN0aW9uLFxuICAgIGFjY291bnROdW1iZXI6IG51bWJlciB8IHVuZGVmaW5lZCxcbiAgICBjaGFpbklkOiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgKTogU2lnbkRvYyB7XG4gICAgaWYgKCFhY2NvdW50TnVtYmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FjY291bnROdW1iZXIgaXMgcmVxdWlyZWQgdG8gY3JlYXRlIGEgc2lnbiBkb2MnKTtcbiAgICB9XG4gICAgaWYgKCFjaGFpbklkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NoYWluSWQgaXMgcmVxdWlyZWQgdG8gY3JlYXRlIGEgc2lnbiBkb2MnKTtcbiAgICB9XG4gICAgaWYgKCFhdG9tVHJhbnNhY3Rpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYXRvbVRyYW5zYWN0aW9uIGlzIHJlcXVpcmVkIHRvIGNyZWF0ZSBhIHNpZ24gZG9jJyk7XG4gICAgfVxuICAgIGNvbnN0IHR4UmF3ID0gdXRpbHMuY3JlYXRlVHhSYXdGcm9tQXRvbVRyYW5zYWN0aW9uKGF0b21UcmFuc2FjdGlvbik7XG4gICAgcmV0dXJuIG1ha2VTaWduRG9jKHR4UmF3LmJvZHlCeXRlcywgdHhSYXcuYXV0aEluZm9CeXRlcywgY2hhaW5JZCwgYWNjb3VudE51bWJlcik7XG4gIH1cblxuICB2YWxpZGF0ZURlbGVnYXRlT3JVbmRlbGVnYXRlTWVzc2FnZShkZWxlZ2F0ZU1lc3NhZ2U6IERlbGVnYXRlT3JVbmRlbGVnZXRlTWVzc2FnZSkge1xuICAgIGlmICghZGVsZWdhdGVNZXNzYWdlLnZhbGlkYXRvckFkZHJlc3MgfHwgIXV0aWxzLmlzVmFsaWRWYWxpZGF0b3JBZGRyZXNzKGRlbGVnYXRlTWVzc2FnZS52YWxpZGF0b3JBZGRyZXNzKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKFxuICAgICAgICBgSW52YWxpZCBEZWxlZ2F0ZU9yVW5kZWxlZ2V0ZU1lc3NhZ2UgdmFsaWRhdG9yQWRkcmVzczogYCArIGRlbGVnYXRlTWVzc2FnZS52YWxpZGF0b3JBZGRyZXNzXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoIWRlbGVnYXRlTWVzc2FnZS5kZWxlZ2F0b3JBZGRyZXNzIHx8ICF1dGlscy5pc1ZhbGlkQWRkcmVzcyhkZWxlZ2F0ZU1lc3NhZ2UuZGVsZWdhdG9yQWRkcmVzcykpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcihcbiAgICAgICAgYEludmFsaWQgRGVsZWdhdGVPclVuZGVsZWdldGVNZXNzYWdlIGRlbGVnYXRvckFkZHJlc3M6IGAgKyBkZWxlZ2F0ZU1lc3NhZ2UuZGVsZWdhdG9yQWRkcmVzc1xuICAgICAgKTtcbiAgICB9XG4gICAgdGhpcy52YWxpZGF0ZUFtb3VudChkZWxlZ2F0ZU1lc3NhZ2UuYW1vdW50KTtcbiAgfVxuXG4gIHZhbGlkYXRlV2l0aGRyYXdSZXdhcmRzTWVzc2FnZSh3aXRoZHJhd1Jld2FyZHNNZXNzYWdlOiBXaXRoZHJhd0RlbGVnYXRvclJld2FyZHNNZXNzYWdlKSB7XG4gICAgaWYgKFxuICAgICAgIXdpdGhkcmF3UmV3YXJkc01lc3NhZ2UudmFsaWRhdG9yQWRkcmVzcyB8fFxuICAgICAgIXV0aWxzLmlzVmFsaWRWYWxpZGF0b3JBZGRyZXNzKHdpdGhkcmF3UmV3YXJkc01lc3NhZ2UudmFsaWRhdG9yQWRkcmVzcylcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcihcbiAgICAgICAgYEludmFsaWQgV2l0aGRyYXdEZWxlZ2F0b3JSZXdhcmRzTWVzc2FnZSB2YWxpZGF0b3JBZGRyZXNzOiBgICsgd2l0aGRyYXdSZXdhcmRzTWVzc2FnZS52YWxpZGF0b3JBZGRyZXNzXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoIXdpdGhkcmF3UmV3YXJkc01lc3NhZ2UuZGVsZWdhdG9yQWRkcmVzcyB8fCAhdXRpbHMuaXNWYWxpZEFkZHJlc3Mod2l0aGRyYXdSZXdhcmRzTWVzc2FnZS5kZWxlZ2F0b3JBZGRyZXNzKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKFxuICAgICAgICBgSW52YWxpZCBXaXRoZHJhd0RlbGVnYXRvclJld2FyZHNNZXNzYWdlIGRlbGVnYXRvckFkZHJlc3M6IGAgKyB3aXRoZHJhd1Jld2FyZHNNZXNzYWdlLmRlbGVnYXRvckFkZHJlc3NcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgdmFsaWRhdGVTZW5kTWVzc2FnZShzZW5kTWVzc2FnZTogU2VuZE1lc3NhZ2UpIHtcbiAgICBpZiAoIXNlbmRNZXNzYWdlLnRvQWRkcmVzcyB8fCAhdXRpbHMuaXNWYWxpZEFkZHJlc3Moc2VuZE1lc3NhZ2UudG9BZGRyZXNzKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKGBJbnZhbGlkIFNlbmRNZXNzYWdlIHRvQWRkcmVzczogYCArIHNlbmRNZXNzYWdlLnRvQWRkcmVzcyk7XG4gICAgfVxuICAgIGlmICghc2VuZE1lc3NhZ2UuZnJvbUFkZHJlc3MgfHwgIXV0aWxzLmlzVmFsaWRBZGRyZXNzKHNlbmRNZXNzYWdlLmZyb21BZGRyZXNzKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKGBJbnZhbGlkIFNlbmRNZXNzYWdlIGZyb21BZGRyZXNzOiBgICsgc2VuZE1lc3NhZ2UuZnJvbUFkZHJlc3MpO1xuICAgIH1cbiAgICB0aGlzLnZhbGlkYXRlQW1vdW50RGF0YShzZW5kTWVzc2FnZS5hbW91bnQpO1xuICB9XG5cbiAgaXNWYWxpZEhleFN0cmluZyhoZXhTdHJpbmc6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAvXlswLTlBLUZhLWZdKiQvLnRlc3QoaGV4U3RyaW5nKTtcbiAgfVxufVxuXG5jb25zdCB1dGlscyA9IG5ldyBVdGlscygpO1xuXG5leHBvcnQgZGVmYXVsdCB1dGlscztcbiJdfQ==