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