@bitgo-beta/sdk-coin-tempo 1.0.1-beta.31 → 1.0.1-beta.310
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/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -1
- package/dist/src/lib/constants.d.ts +21 -1
- package/dist/src/lib/constants.d.ts.map +1 -1
- package/dist/src/lib/constants.js +25 -5
- package/dist/src/lib/index.d.ts +4 -0
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +5 -1
- package/dist/src/lib/keyPair.d.ts +5 -25
- package/dist/src/lib/keyPair.d.ts.map +1 -1
- package/dist/src/lib/keyPair.js +9 -97
- package/dist/src/lib/tip20Abi.d.ts +98 -0
- package/dist/src/lib/tip20Abi.d.ts.map +1 -0
- package/dist/src/lib/tip20Abi.js +62 -0
- package/dist/src/lib/transaction.d.ts +144 -0
- package/dist/src/lib/transaction.d.ts.map +1 -0
- package/dist/src/lib/transaction.js +216 -0
- package/dist/src/lib/transactionBuilder.d.ts +139 -0
- package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
- package/dist/src/lib/transactionBuilder.js +408 -0
- package/dist/src/lib/types.d.ts +27 -0
- package/dist/src/lib/types.d.ts.map +1 -0
- package/dist/src/lib/types.js +3 -0
- package/dist/src/lib/utils.d.ts +70 -7
- package/dist/src/lib/utils.d.ts.map +1 -1
- package/dist/src/lib/utils.js +148 -16
- package/dist/src/register.d.ts.map +1 -1
- package/dist/src/register.js +5 -1
- package/dist/src/tempo.d.ts +95 -41
- package/dist/src/tempo.d.ts.map +1 -1
- package/dist/src/tempo.js +447 -76
- package/dist/src/tip20Token.d.ts +83 -0
- package/dist/src/tip20Token.d.ts.map +1 -0
- package/dist/src/tip20Token.js +202 -0
- package/dist/test/integration/tip20.d.ts +7 -0
- package/dist/test/integration/tip20.d.ts.map +1 -0
- package/dist/test/integration/tip20.js +178 -0
- package/dist/test/resources/tempo.d.ts +61 -0
- package/dist/test/resources/tempo.d.ts.map +1 -0
- package/dist/test/resources/tempo.js +79 -0
- package/dist/test/unit/index.js +172 -3
- package/dist/test/unit/tempo.d.ts +2 -0
- package/dist/test/unit/tempo.d.ts.map +1 -0
- package/dist/test/unit/tempo.js +207 -0
- package/dist/test/unit/transactionBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder.js +858 -0
- package/dist/test/unit/utils.js +6 -5
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -7
package/dist/src/tempo.js
CHANGED
|
@@ -1,130 +1,501 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
5
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
36
|
exports.Tempo = void 0;
|
|
37
|
+
/**
|
|
38
|
+
* @prettier
|
|
39
|
+
*/
|
|
40
|
+
const abstract_eth_1 = require("@bitgo-beta/abstract-eth");
|
|
7
41
|
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
|
|
42
|
+
const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
|
|
43
|
+
const statics_1 = require("@bitgo-beta/statics");
|
|
44
|
+
const ethers_1 = require("ethers");
|
|
45
|
+
const lib_1 = require("./lib");
|
|
46
|
+
const utils_1 = require("./lib/utils");
|
|
47
|
+
const constants_1 = require("./lib/constants");
|
|
48
|
+
const url = __importStar(require("url"));
|
|
49
|
+
const querystring = __importStar(require("querystring"));
|
|
50
|
+
class Tempo extends abstract_eth_1.AbstractEthLikeNewCoins {
|
|
11
51
|
constructor(bitgo, staticsCoin) {
|
|
12
|
-
super(bitgo);
|
|
13
|
-
if (!staticsCoin) {
|
|
14
|
-
throw new Error('missing required constructor parameter staticsCoin');
|
|
15
|
-
}
|
|
16
|
-
this._staticsCoin = staticsCoin;
|
|
52
|
+
super(bitgo, staticsCoin);
|
|
17
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Factory method to create Tempo instance
|
|
56
|
+
*/
|
|
18
57
|
static createInstance(bitgo, staticsCoin) {
|
|
19
58
|
return new Tempo(bitgo, staticsCoin);
|
|
20
59
|
}
|
|
21
60
|
/**
|
|
22
|
-
*
|
|
61
|
+
* Get the chain identifier
|
|
23
62
|
*/
|
|
24
|
-
getBaseFactor() {
|
|
25
|
-
return 1e18;
|
|
26
|
-
}
|
|
27
63
|
getChain() {
|
|
28
|
-
return 'tempo';
|
|
29
|
-
}
|
|
30
|
-
getFamily() {
|
|
31
|
-
return 'tempo';
|
|
64
|
+
return this._staticsCoin?.name || 'tempo';
|
|
32
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Get the full chain name
|
|
68
|
+
*/
|
|
33
69
|
getFullName() {
|
|
34
70
|
return 'Tempo';
|
|
35
71
|
}
|
|
72
|
+
/** @inheritdoc */
|
|
73
|
+
getBaseFactor() {
|
|
74
|
+
return 1e6;
|
|
75
|
+
}
|
|
36
76
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
77
|
+
* Check if value-less transfers are allowed
|
|
78
|
+
* EVM-based chains allow zero-value transfers for smart contract interactions
|
|
39
79
|
*/
|
|
40
80
|
valuelessTransferAllowed() {
|
|
41
|
-
return
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Check if TSS is supported
|
|
85
|
+
*/
|
|
86
|
+
supportsTss() {
|
|
87
|
+
return true;
|
|
42
88
|
}
|
|
43
89
|
/**
|
|
44
|
-
*
|
|
45
|
-
|
|
90
|
+
* Get the MPC algorithm (ECDSA for EVM chains)
|
|
91
|
+
*/
|
|
92
|
+
getMPCAlgorithm() {
|
|
93
|
+
return 'ecdsa';
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Evaluates whether an address string is valid for Tempo
|
|
97
|
+
* Supports addresses with optional memoId query parameter (e.g., 0x...?memoId=123)
|
|
98
|
+
* @param address - The address to validate
|
|
99
|
+
* @returns true if address is valid
|
|
46
100
|
*/
|
|
47
101
|
isValidAddress(address) {
|
|
48
|
-
|
|
102
|
+
if (typeof address !== 'string') {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
const { baseAddress } = this.getAddressDetails(address);
|
|
107
|
+
return abstract_eth_1.optionalDeps.ethUtil.isValidAddress(abstract_eth_1.optionalDeps.ethUtil.addHexPrefix(baseAddress));
|
|
108
|
+
}
|
|
109
|
+
catch (e) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
49
112
|
}
|
|
50
113
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* @param
|
|
54
|
-
* @returns
|
|
114
|
+
* Parse address into base address and optional memoId
|
|
115
|
+
* Throws InvalidAddressError for invalid address formats
|
|
116
|
+
* @param address - Address string, potentially with ?memoId=X suffix
|
|
117
|
+
* @returns Object containing address, baseAddress, and memoId (null if not present)
|
|
118
|
+
* @throws InvalidAddressError if address format is invalid
|
|
55
119
|
*/
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
120
|
+
getAddressDetails(address) {
|
|
121
|
+
if (typeof address !== 'string') {
|
|
122
|
+
throw new sdk_core_1.InvalidAddressError(`invalid address: ${address}`);
|
|
123
|
+
}
|
|
124
|
+
const destinationDetails = url.parse(address);
|
|
125
|
+
const baseAddress = destinationDetails.pathname || '';
|
|
126
|
+
// No query string - just a plain address
|
|
127
|
+
if (destinationDetails.pathname === address) {
|
|
128
|
+
return {
|
|
129
|
+
address,
|
|
130
|
+
baseAddress: address,
|
|
131
|
+
memoId: null,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
// Has query string - must contain memoId
|
|
135
|
+
if (!destinationDetails.query) {
|
|
136
|
+
throw new sdk_core_1.InvalidAddressError(`invalid address: ${address}`);
|
|
137
|
+
}
|
|
138
|
+
const queryDetails = querystring.parse(destinationDetails.query);
|
|
139
|
+
// Query string must contain memoId
|
|
140
|
+
if (!queryDetails.memoId) {
|
|
141
|
+
throw new sdk_core_1.InvalidAddressError(`invalid address: ${address}, unknown query parameters`);
|
|
142
|
+
}
|
|
143
|
+
// Only one memoId allowed
|
|
144
|
+
if (Array.isArray(queryDetails.memoId)) {
|
|
145
|
+
throw new sdk_core_1.InvalidAddressError(`memoId may only be given at most once, but found ${queryDetails.memoId.length} instances in address ${address}`);
|
|
146
|
+
}
|
|
147
|
+
// Reject if there are other query parameters besides memoId
|
|
148
|
+
const queryKeys = Object.keys(queryDetails);
|
|
149
|
+
if (queryKeys.length !== 1) {
|
|
150
|
+
throw new sdk_core_1.InvalidAddressError(`invalid address: ${address}, only memoId query parameter is allowed`);
|
|
151
|
+
}
|
|
152
|
+
// Validate memoId format
|
|
153
|
+
if (!this.isValidMemoId(queryDetails.memoId)) {
|
|
154
|
+
throw new sdk_core_1.InvalidMemoIdError(`invalid address: '${address}', memoId is not valid`);
|
|
61
155
|
}
|
|
62
156
|
return {
|
|
63
|
-
|
|
64
|
-
|
|
157
|
+
address,
|
|
158
|
+
baseAddress,
|
|
159
|
+
memoId: queryDetails.memoId,
|
|
65
160
|
};
|
|
66
161
|
}
|
|
67
162
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* @
|
|
71
|
-
|
|
163
|
+
* Validate that a memoId is a valid non-negative integer string
|
|
164
|
+
* @param memoId - The memoId to validate
|
|
165
|
+
* @returns true if valid
|
|
166
|
+
*/
|
|
167
|
+
isValidMemoId(memoId) {
|
|
168
|
+
return (0, utils_1.isValidMemoId)(memoId);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Tempo uses memoId-based addresses rather than forwarder contracts.
|
|
172
|
+
* Verify that the address belongs to this wallet by checking that the
|
|
173
|
+
* base (EVM) portion matches the wallet's base address.
|
|
174
|
+
*/
|
|
175
|
+
async isWalletAddress(params) {
|
|
176
|
+
const { address, baseAddress } = params;
|
|
177
|
+
const rootAddress = params.rootAddress;
|
|
178
|
+
if (!address) {
|
|
179
|
+
throw new sdk_core_1.InvalidAddressError('address is required');
|
|
180
|
+
}
|
|
181
|
+
if (!this.isValidAddress(address)) {
|
|
182
|
+
throw new sdk_core_1.InvalidAddressError(`invalid address: ${address}`);
|
|
183
|
+
}
|
|
184
|
+
const { baseAddress: addressBase } = this.getAddressDetails(address);
|
|
185
|
+
const walletBaseAddress = baseAddress || rootAddress;
|
|
186
|
+
if (!walletBaseAddress) {
|
|
187
|
+
throw new sdk_core_1.InvalidAddressError('baseAddress or rootAddress is required for verification');
|
|
188
|
+
}
|
|
189
|
+
const { baseAddress: walletBase } = this.getAddressDetails(walletBaseAddress);
|
|
190
|
+
if (addressBase.toLowerCase() !== walletBase.toLowerCase()) {
|
|
191
|
+
throw new sdk_core_1.UnexpectedAddressError(`address validation failure: expected ${walletBase} but got ${addressBase}`);
|
|
192
|
+
}
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Parse a serialised Tempo transaction and return its operations as SDK outputs.
|
|
197
|
+
* @inheritdoc
|
|
72
198
|
*/
|
|
73
|
-
|
|
74
|
-
|
|
199
|
+
async parseTransaction(params) {
|
|
200
|
+
const txHex = (params.txHex || params.halfSigned?.txHex);
|
|
201
|
+
if (!txHex) {
|
|
202
|
+
return {};
|
|
203
|
+
}
|
|
204
|
+
if (!(0, utils_1.isTip20Transaction)(txHex)) {
|
|
205
|
+
return {};
|
|
206
|
+
}
|
|
207
|
+
const txBuilder = this.getTransactionBuilder();
|
|
208
|
+
txBuilder.from(txHex);
|
|
209
|
+
const tx = (await txBuilder.build());
|
|
210
|
+
return {
|
|
211
|
+
inputs: tx.inputs.map((input) => ({
|
|
212
|
+
address: input.address,
|
|
213
|
+
amount: input.value,
|
|
214
|
+
coin: this.getChain(),
|
|
215
|
+
})),
|
|
216
|
+
outputs: tx.outputs.map((output) => ({
|
|
217
|
+
address: output.address,
|
|
218
|
+
amount: output.value,
|
|
219
|
+
coin: this.getChain(),
|
|
220
|
+
})),
|
|
221
|
+
};
|
|
75
222
|
}
|
|
76
223
|
/**
|
|
77
|
-
* Verify that a transaction
|
|
78
|
-
* @
|
|
79
|
-
* @param params.txPrebuild
|
|
80
|
-
* @param params.txParams
|
|
81
|
-
* @returns {boolean}
|
|
224
|
+
* Verify that a Tempo transaction matches the intended recipients and amounts.
|
|
225
|
+
* @inheritdoc
|
|
82
226
|
*/
|
|
83
227
|
async verifyTransaction(params) {
|
|
84
|
-
|
|
85
|
-
|
|
228
|
+
const { txParams, txPrebuild } = params;
|
|
229
|
+
if (!txPrebuild?.txHex) {
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
// signableHex may arrive without the 0x prefix (e.g. from the TSS signing flow).
|
|
233
|
+
const txHex = txPrebuild.txHex.startsWith('0x') ? txPrebuild.txHex : '0x' + txPrebuild.txHex;
|
|
234
|
+
if (!(0, utils_1.isTip20Transaction)(txHex)) {
|
|
235
|
+
throw new Error(`Invalid Tempo transaction hex: expected a 0x76 TIP-20 transaction`);
|
|
236
|
+
}
|
|
237
|
+
const txBuilder = this.getTransactionBuilder();
|
|
238
|
+
txBuilder.from(txHex);
|
|
239
|
+
const tx = (await txBuilder.build());
|
|
240
|
+
const operations = tx.getOperations();
|
|
241
|
+
const rawCalls = tx.getRawCalls();
|
|
242
|
+
// If the caller specified explicit recipients, verify they match the transaction.
|
|
243
|
+
// A transaction is either all token transfer operations OR a single raw contract call — never mixed.
|
|
244
|
+
const recipients = txParams?.recipients;
|
|
245
|
+
if (recipients && recipients.length > 0) {
|
|
246
|
+
if (rawCalls.length > 0) {
|
|
247
|
+
// Contract call transaction — single raw call, single recipient with data
|
|
248
|
+
if (rawCalls.length !== recipients.length) {
|
|
249
|
+
throw new Error(`Transaction has ${rawCalls.length} call(s) but ${recipients.length} recipient(s) were requested`);
|
|
250
|
+
}
|
|
251
|
+
for (let i = 0; i < rawCalls.length; i++) {
|
|
252
|
+
const rawCall = rawCalls[i];
|
|
253
|
+
const recipient = recipients[i];
|
|
254
|
+
if (rawCall.to.toLowerCase() !== recipient.address.split('?')[0].toLowerCase()) {
|
|
255
|
+
throw new Error(`Raw call ${i} address mismatch: expected ${recipient.address}, got ${rawCall.to}`);
|
|
256
|
+
}
|
|
257
|
+
if (!recipient.data || rawCall.data.toLowerCase() !== recipient.data.toLowerCase()) {
|
|
258
|
+
throw new Error(`Raw call ${i} calldata mismatch`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
// Token transfer transaction — operations matched 1-to-1 against recipients
|
|
264
|
+
if (operations.length !== recipients.length) {
|
|
265
|
+
throw new Error(`Transaction has ${operations.length} operation(s) but ${recipients.length} recipient(s) were requested`);
|
|
266
|
+
}
|
|
267
|
+
for (let i = 0; i < operations.length; i++) {
|
|
268
|
+
const op = operations[i];
|
|
269
|
+
const recipient = recipients[i];
|
|
270
|
+
const recipientBaseAddress = recipient.address.split('?')[0];
|
|
271
|
+
if (op.to.toLowerCase() !== recipientBaseAddress.toLowerCase()) {
|
|
272
|
+
throw new Error(`Operation ${i} recipient mismatch: expected ${recipient.address}, got ${op.to}`);
|
|
273
|
+
}
|
|
274
|
+
const opAmountBaseUnits = (0, utils_1.amountToTip20Units)(op.amount).toString();
|
|
275
|
+
if (opAmountBaseUnits !== recipient.amount.toString()) {
|
|
276
|
+
throw new Error(`Operation ${i} amount mismatch: expected ${recipient.amount}, got ${opAmountBaseUnits}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
// Verify fee token if specified
|
|
282
|
+
if (txParams?.feeToken) {
|
|
283
|
+
const txFeeToken = tx.getFeeToken();
|
|
284
|
+
if (txFeeToken?.toLowerCase() !== txParams.feeToken.toLowerCase()) {
|
|
285
|
+
throw new Error(`Fee token mismatch: expected ${txParams.feeToken}, got ${txFeeToken || 'none'}`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return true;
|
|
86
289
|
}
|
|
87
290
|
/**
|
|
88
|
-
*
|
|
89
|
-
*
|
|
291
|
+
* Set coin-specific fields in the intent for Tempo TSS transactions.
|
|
292
|
+
* Ensures feeToken is properly wired through the intent for Tempo transactions.
|
|
293
|
+
* @param intent - The populated intent to modify
|
|
294
|
+
* @param params - The parameters containing feeToken
|
|
90
295
|
*/
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
296
|
+
setCoinSpecificFieldsInIntent(intent, params) {
|
|
297
|
+
if (params.feeToken) {
|
|
298
|
+
intent.feeOptions = intent.feeOptions
|
|
299
|
+
? { ...intent.feeOptions, feeToken: params.feeToken }
|
|
300
|
+
: { feeToken: params.feeToken };
|
|
301
|
+
}
|
|
94
302
|
}
|
|
95
303
|
/**
|
|
96
|
-
*
|
|
97
|
-
*
|
|
304
|
+
* Query the Tempo Alchemy RPC for recovery balance/nonce information.
|
|
305
|
+
* Routes through queryTempoRpc using the URL from environments.ts.
|
|
98
306
|
*/
|
|
99
|
-
async
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
307
|
+
async recoveryBlockchainExplorerQuery(query, apiKey) {
|
|
308
|
+
const evmConfig = sdk_core_1.common.Environments[this.bitgo.getEnv()].evm;
|
|
309
|
+
const coinFamily = this.getFamily();
|
|
310
|
+
if (!evmConfig || !(coinFamily in evmConfig)) {
|
|
311
|
+
throw new Error(`env config missing for ${coinFamily} in ${this.bitgo.getEnv()}`);
|
|
312
|
+
}
|
|
313
|
+
const token = apiKey || evmConfig[coinFamily].apiToken;
|
|
314
|
+
const rpcUrl = evmConfig[coinFamily].baseUrl;
|
|
315
|
+
return this.queryTempoRpc(query, rpcUrl, token);
|
|
103
316
|
}
|
|
104
317
|
/**
|
|
105
|
-
*
|
|
106
|
-
*
|
|
318
|
+
* Translates Etherscan-style recovery queries into Tempo Alchemy JSON-RPC calls.
|
|
319
|
+
*
|
|
320
|
+
* Supported:
|
|
321
|
+
* account/balance → returns { result: '0' } (no native coin on Tempo)
|
|
322
|
+
* account/tokenbalance → eth_call (balanceOf selector 0x70a08231) → { result: decimalString }
|
|
323
|
+
* account/txlist → eth_getTransactionCount → { nonce: number }
|
|
107
324
|
*/
|
|
108
|
-
async
|
|
109
|
-
|
|
110
|
-
|
|
325
|
+
async queryTempoRpc(query, rpcUrl, apiKey) {
|
|
326
|
+
const endpoint = apiKey ? `${rpcUrl}${apiKey}` : rpcUrl;
|
|
327
|
+
const { module, action, address, contractaddress, tag } = query;
|
|
328
|
+
let method;
|
|
329
|
+
let params;
|
|
330
|
+
if (module === 'account' && action === 'balance') {
|
|
331
|
+
return { result: '0' };
|
|
332
|
+
}
|
|
333
|
+
else if (module === 'account' && action === 'tokenbalance') {
|
|
334
|
+
const paddedAddr = (address ?? '').replace(/^0x/, '').padStart(64, '0');
|
|
335
|
+
method = 'eth_call';
|
|
336
|
+
params = [{ to: contractaddress, data: '0x70a08231' + paddedAddr }, tag ?? 'latest'];
|
|
337
|
+
}
|
|
338
|
+
else if (module === 'account' && action === 'txlist') {
|
|
339
|
+
method = 'eth_getTransactionCount';
|
|
340
|
+
params = [address, 'latest'];
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
throw new Error(`queryTempoRpc: unsupported module=${module} action=${action}`);
|
|
344
|
+
}
|
|
345
|
+
const res = await fetch(endpoint, {
|
|
346
|
+
method: 'POST',
|
|
347
|
+
headers: { 'Content-Type': 'application/json' },
|
|
348
|
+
body: JSON.stringify({ jsonrpc: '2.0', method, params, id: 1 }),
|
|
349
|
+
});
|
|
350
|
+
if (!res.ok) {
|
|
351
|
+
throw new Error(`Could not reach Tempo RPC endpoint (HTTP ${res.status})`);
|
|
352
|
+
}
|
|
353
|
+
const body = (await res.json());
|
|
354
|
+
if (body.error) {
|
|
355
|
+
throw new Error(`Tempo RPC error: ${body.error.message}`);
|
|
356
|
+
}
|
|
357
|
+
if (module === 'account' && action === 'txlist') {
|
|
358
|
+
return { nonce: parseInt(body.result, 16) };
|
|
359
|
+
}
|
|
360
|
+
try {
|
|
361
|
+
return { result: BigInt(body.result).toString() };
|
|
362
|
+
}
|
|
363
|
+
catch {
|
|
364
|
+
return { result: '0' };
|
|
365
|
+
}
|
|
111
366
|
}
|
|
112
367
|
/**
|
|
113
|
-
*
|
|
114
|
-
*
|
|
368
|
+
* Shared helper: queries the token balance, computes sweep amount, and builds
|
|
369
|
+
* an unsigned TIP-20 transfer transaction. Used by both recovery paths.
|
|
370
|
+
*
|
|
371
|
+
* - tokenContractAddress: the token to sweep (defaults to pathUSD)
|
|
372
|
+
* - feeToken: always pathUSD
|
|
373
|
+
* - If sweeping pathUSD itself, reserves gasLimit × maxFeePerGas / 10^12 pathUSD units for fees.
|
|
115
374
|
*/
|
|
116
|
-
async
|
|
117
|
-
|
|
118
|
-
|
|
375
|
+
async buildTempoSweepTx(walletAddress, params) {
|
|
376
|
+
if (!params.tokenContractAddress) {
|
|
377
|
+
throw new Error('tokenContractAddress is required for sweep');
|
|
378
|
+
}
|
|
379
|
+
const tokenAddress = params.tokenContractAddress;
|
|
380
|
+
const pathUsdTokenName = this.getChain() === constants_1.MAINNET_COIN ? constants_1.PATH_USD_TOKEN_MAINNET : constants_1.PATH_USD_TOKEN_TESTNET;
|
|
381
|
+
const pathUsdAddress = statics_1.coins.get(pathUsdTokenName).contractAddress;
|
|
382
|
+
const rawBalance = await this.queryAddressTokenBalance(tokenAddress, walletAddress, params.apiKey);
|
|
383
|
+
const balance = BigInt(rawBalance.toString());
|
|
384
|
+
const isPathUsd = tokenAddress.toLowerCase() === pathUsdAddress.toLowerCase();
|
|
385
|
+
const gasLimitBig = BigInt(params.gasLimit ?? 700000);
|
|
386
|
+
const maxFeePerGasBig = BigInt(params.eip1559?.maxFeePerGas ?? 20000000000);
|
|
387
|
+
// 75% buffer on top of gasLimit × maxFeePerGas to cover actual on-chain gas variance
|
|
388
|
+
const gasMarginUnits = (gasLimitBig * maxFeePerGasBig * 175n) / (10n ** 12n * 100n);
|
|
389
|
+
const sweepAmount = isPathUsd ? balance - gasMarginUnits : balance;
|
|
390
|
+
if (sweepAmount <= 0n) {
|
|
391
|
+
throw new Error(`Insufficient balance in ${tokenAddress}: ${balance} units (minimum required: ${isPathUsd ? gasMarginUnits + 1n : 1n})`);
|
|
392
|
+
}
|
|
393
|
+
const sweepAmountHuman = (0, utils_1.tip20UnitsToAmount)(sweepAmount);
|
|
394
|
+
const nonce = await this.getAddressNonce(walletAddress, params.apiKey);
|
|
395
|
+
const txBuilder = this.getTransactionBuilder();
|
|
396
|
+
txBuilder
|
|
397
|
+
.addOperation({ token: tokenAddress, to: params.recoveryDestination, amount: sweepAmountHuman })
|
|
398
|
+
.feeToken(pathUsdAddress)
|
|
399
|
+
.nonce(nonce)
|
|
400
|
+
.gas(gasLimitBig)
|
|
401
|
+
.maxFeePerGas(maxFeePerGasBig)
|
|
402
|
+
.maxPriorityFeePerGas(BigInt(params.eip1559?.maxPriorityFeePerGas ?? 10000000000));
|
|
403
|
+
const tx = (await txBuilder.build());
|
|
404
|
+
return { tx, nonce, sweepAmount, gasMarginUnits };
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Overrides the base-class recoverTSS to use TIP-20 transactions instead of standard ETH.
|
|
408
|
+
*
|
|
409
|
+
* Two paths:
|
|
410
|
+
* - Unsigned sweep (plain public key shares): delegates to buildUnsignedSweepTxnTSS
|
|
411
|
+
* - Signed sweep (encrypted keys + passphrase): builds and signs a TIP-20 tx via MPC
|
|
412
|
+
*/
|
|
413
|
+
async recoverTSS(params) {
|
|
414
|
+
this.validateRecoveryParams(params);
|
|
415
|
+
const userKey = params.userKey.replace(/\s/g, '');
|
|
416
|
+
const backupKey = params.backupKey.replace(/\s/g, '');
|
|
417
|
+
if ((0, sdk_core_1.getIsUnsignedSweep)({ userKey, backupKey, isTss: params.isTss })) {
|
|
418
|
+
return this.buildUnsignedSweepTxnTSS(params);
|
|
419
|
+
}
|
|
420
|
+
// Signed sweep: decrypt MPC v2 key shares
|
|
421
|
+
const { userKeyShare, backupKeyShare, commonKeyChain } = await sdk_core_1.ECDSAUtils.getMpcV2RecoveryKeyShares(userKey, backupKey, params.walletPassphrase);
|
|
422
|
+
const MPC = new sdk_core_1.Ecdsa();
|
|
423
|
+
const derivedCommonKeyChain = MPC.deriveUnhardened(commonKeyChain, 'm/0');
|
|
424
|
+
const backupKeyPair = new abstract_eth_1.KeyPair({ pub: derivedCommonKeyChain.slice(0, 66) });
|
|
425
|
+
const baseAddress = backupKeyPair.getAddress();
|
|
426
|
+
const { tx: unsignedTx } = await this.buildTempoSweepTx(baseAddress, params);
|
|
427
|
+
const serializedHex = await unsignedTx.serialize();
|
|
428
|
+
// Hash the unsigned 0x76 tx — matches Tip20TransactionBuilder's own signing logic
|
|
429
|
+
const msgHashHex = ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.arrayify(serializedHex));
|
|
430
|
+
const messageHash = Buffer.from(msgHashHex.replace('0x', ''), 'hex');
|
|
431
|
+
const signature = await sdk_core_1.ECDSAUtils.signRecoveryMpcV2(messageHash, userKeyShare, backupKeyShare, commonKeyChain);
|
|
432
|
+
// ECDSAMethodTypes.Signature.r/s are 64-char hex WITHOUT 0x prefix
|
|
433
|
+
unsignedTx.setSignature({
|
|
434
|
+
r: `0x${signature.r}`,
|
|
435
|
+
s: `0x${signature.s}`,
|
|
436
|
+
yParity: signature.recid,
|
|
437
|
+
});
|
|
438
|
+
const signedHex = await unsignedTx.serialize();
|
|
439
|
+
const txId = ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.arrayify(signedHex));
|
|
440
|
+
return { id: txId, tx: signedHex };
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Builds an unsigned TIP-20 sweep transaction for the offline vault (unsigned sweep path).
|
|
444
|
+
* Called by recoverTSS when plain public key shares are provided.
|
|
445
|
+
*/
|
|
446
|
+
async buildUnsignedSweepTxnTSS(params) {
|
|
447
|
+
const backupKey = params.backupKey.replace(/\s/g, '');
|
|
448
|
+
const derivationPath = params.derivationSeed ? (0, sdk_lib_mpc_1.getDerivationPath)(params.derivationSeed) : 'm/0';
|
|
449
|
+
const MPC = new sdk_core_1.Ecdsa();
|
|
450
|
+
const derivedCommonKeyChain = MPC.deriveUnhardened(backupKey, derivationPath);
|
|
451
|
+
const backupKeyPair = new abstract_eth_1.KeyPair({ pub: derivedCommonKeyChain.slice(0, 66) });
|
|
452
|
+
const baseAddress = backupKeyPair.getAddress();
|
|
453
|
+
const { tx, nonce, sweepAmount, gasMarginUnits } = await this.buildTempoSweepTx(baseAddress, params);
|
|
454
|
+
const serializedHex = await tx.serialize();
|
|
455
|
+
const serializedTxHex = serializedHex.replace('0x', '');
|
|
456
|
+
const signableHex = ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.arrayify(serializedHex)).replace('0x', '');
|
|
457
|
+
return {
|
|
458
|
+
txRequests: [
|
|
459
|
+
{
|
|
460
|
+
walletCoin: this.getChain(),
|
|
461
|
+
transactions: [
|
|
462
|
+
{
|
|
463
|
+
unsignedTx: {
|
|
464
|
+
serializedTxHex,
|
|
465
|
+
signableHex,
|
|
466
|
+
derivationPath,
|
|
467
|
+
feeInfo: {
|
|
468
|
+
fee: Number(gasMarginUnits),
|
|
469
|
+
feeString: (0, utils_1.tip20UnitsToAmount)(gasMarginUnits),
|
|
470
|
+
},
|
|
471
|
+
parsedTx: {
|
|
472
|
+
spendAmount: (0, utils_1.tip20UnitsToAmount)(sweepAmount),
|
|
473
|
+
outputs: [
|
|
474
|
+
{
|
|
475
|
+
coinName: this.getChain(),
|
|
476
|
+
address: params.recoveryDestination,
|
|
477
|
+
valueString: (0, utils_1.tip20UnitsToAmount)(sweepAmount),
|
|
478
|
+
},
|
|
479
|
+
],
|
|
480
|
+
},
|
|
481
|
+
coinSpecific: { commonKeyChain: backupKey },
|
|
482
|
+
eip1559: params.eip1559,
|
|
483
|
+
replayProtectionOptions: params.replayProtectionOptions,
|
|
484
|
+
},
|
|
485
|
+
nonce,
|
|
486
|
+
signatureShares: [],
|
|
487
|
+
},
|
|
488
|
+
],
|
|
489
|
+
},
|
|
490
|
+
],
|
|
491
|
+
};
|
|
119
492
|
}
|
|
120
493
|
/**
|
|
121
|
-
*
|
|
122
|
-
* @param params
|
|
494
|
+
* Get transaction builder for Tempo.
|
|
123
495
|
*/
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return {};
|
|
496
|
+
getTransactionBuilder(common) {
|
|
497
|
+
return new lib_1.Tip20TransactionBuilder(statics_1.coins.get(this.getBaseChain()));
|
|
127
498
|
}
|
|
128
499
|
}
|
|
129
500
|
exports.Tempo = Tempo;
|
|
130
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVtcG8uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVtcG8udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsbURBWThCO0FBRTlCLDJDQUF3RDtBQUN4RCx3REFBZ0M7QUFFaEMsTUFBYSxLQUFNLFNBQVEsbUJBQVE7SUFHakMsWUFBc0IsS0FBZ0IsRUFBRSxXQUF1QztRQUM3RSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFYixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFFRCxJQUFJLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQztJQUNsQyxDQUFDO0lBRUQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFnQixFQUFFLFdBQXVDO1FBQzdFLE9BQU8sSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7T0FFRztJQUNJLGFBQWE7UUFDbEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRU0sUUFBUTtRQUNiLE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFTSxTQUFTO1FBQ2QsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVNLFdBQVc7UUFDaEIsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVEOzs7T0FHRztJQUNILHdCQUF3QjtRQUN0QixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRDs7O09BR0c7SUFDSCxjQUFjLENBQUMsT0FBZTtRQUM1QixPQUFPLGVBQUssQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsZUFBZSxDQUFDLElBQWE7UUFDM0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLGlCQUFZLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLGlCQUFZLEVBQUUsQ0FBQztRQUN2RSxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNkLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztRQUNwRCxDQUFDO1FBRUQsT0FBTztZQUNMLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRztZQUNiLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRztTQUNkLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxVQUFVLENBQUMsR0FBVztRQUNwQixPQUFPLGVBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsS0FBSyxDQUFDLGlCQUFpQixDQUFDLE1BQWdDO1FBQ3RELDJDQUEyQztRQUMzQyxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLLENBQUMsZUFBZSxDQUFDLE1BQTRCO1FBQ2hELHVDQUF1QztRQUN2QyxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLLENBQUMsaUJBQWlCLENBQUMsTUFBK0I7UUFDckQsK0NBQStDO1FBQy9DLHdEQUF3RDtRQUN4RCxPQUFPLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLGdCQUFnQixDQUFDLE1BQStCO1FBQ3BELHNDQUFzQztRQUN0QyxPQUFPLEVBQXVCLENBQUM7SUFDakMsQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUErQjtRQUN0RCwwQ0FBMEM7UUFDMUMsT0FBTyxFQUE0QixDQUFDO0lBQ3RDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLLENBQUMsZUFBZSxDQUFDLE1BQThCO1FBQ2xELHNDQUFzQztRQUN0QyxPQUFPLEVBQXVCLENBQUM7SUFDakMsQ0FBQztDQUNGO0FBM0lELHNCQTJJQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEF1ZGl0RGVjcnlwdGVkS2V5UGFyYW1zLFxuICBCYXNlQ29pbixcbiAgQml0R29CYXNlLFxuICBLZXlQYWlyLFxuICBQYXJzZWRUcmFuc2FjdGlvbixcbiAgUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFNpZ25lZFRyYW5zYWN0aW9uLFxuICBTaWduVHJhbnNhY3Rpb25PcHRpb25zLFxuICBWZXJpZnlBZGRyZXNzT3B0aW9ucyxcbiAgVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zLFxuICBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uLFxufSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBCYXNlQ29pbiBhcyBTdGF0aWNzQmFzZUNvaW4gfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCB7IEtleVBhaXIgYXMgVGVtcG9LZXlQYWlyIH0gZnJvbSAnLi9saWIva2V5UGFpcic7XG5pbXBvcnQgdXRpbHMgZnJvbSAnLi9saWIvdXRpbHMnO1xuXG5leHBvcnQgY2xhc3MgVGVtcG8gZXh0ZW5kcyBCYXNlQ29pbiB7XG4gIHByb3RlY3RlZCByZWFkb25seSBfc3RhdGljc0NvaW46IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj47XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKGJpdGdvOiBCaXRHb0Jhc2UsIHN0YXRpY3NDb2luPzogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPikge1xuICAgIHN1cGVyKGJpdGdvKTtcblxuICAgIGlmICghc3RhdGljc0NvaW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCBjb25zdHJ1Y3RvciBwYXJhbWV0ZXIgc3RhdGljc0NvaW4nKTtcbiAgICB9XG5cbiAgICB0aGlzLl9zdGF0aWNzQ29pbiA9IHN0YXRpY3NDb2luO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUluc3RhbmNlKGJpdGdvOiBCaXRHb0Jhc2UsIHN0YXRpY3NDb2luPzogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPik6IEJhc2VDb2luIHtcbiAgICByZXR1cm4gbmV3IFRlbXBvKGJpdGdvLCBzdGF0aWNzQ29pbik7XG4gIH1cblxuICAvKipcbiAgICogRmFjdG9yIGJldHdlZW4gdGhlIGNvaW4ncyBiYXNlIHVuaXQgYW5kIGl0cyBzbWFsbGVzdCBzdWJkaXZpc2lvblxuICAgKi9cbiAgcHVibGljIGdldEJhc2VGYWN0b3IoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gMWUxODtcbiAgfVxuXG4gIHB1YmxpYyBnZXRDaGFpbigpOiBzdHJpbmcge1xuICAgIHJldHVybiAndGVtcG8nO1xuICB9XG5cbiAgcHVibGljIGdldEZhbWlseSgpOiBzdHJpbmcge1xuICAgIHJldHVybiAndGVtcG8nO1xuICB9XG5cbiAgcHVibGljIGdldEZ1bGxOYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICdUZW1wbyc7XG4gIH1cblxuICAvKipcbiAgICogRmxhZyBmb3Igc2VuZGluZyB2YWx1ZSBvZiAwXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIG9rYXkgdG8gc2VuZCAwIHZhbHVlLCBmYWxzZSBvdGhlcndpc2VcbiAgICovXG4gIHZhbHVlbGVzc1RyYW5zZmVyQWxsb3dlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoaXMgaXMgYSB2YWxpZCBiYXNlNTggb3IgaGV4IGFkZHJlc3NcbiAgICogQHBhcmFtIGFkZHJlc3NcbiAgICovXG4gIGlzVmFsaWRBZGRyZXNzKGFkZHJlc3M6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB1dGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBlZDI1NTE5IGtleSBwYWlyXG4gICAqXG4gICAqIEBwYXJhbSBzZWVkXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IG9iamVjdCB3aXRoIGdlbmVyYXRlZCBwdWIsIHBydlxuICAgKi9cbiAgZ2VuZXJhdGVLZXlQYWlyKHNlZWQ/OiBCdWZmZXIpOiBLZXlQYWlyIHtcbiAgICBjb25zdCBrZXlQYWlyID0gc2VlZCA/IG5ldyBUZW1wb0tleVBhaXIoeyBzZWVkIH0pIDogbmV3IFRlbXBvS2V5UGFpcigpO1xuICAgIGNvbnN0IGtleXMgPSBrZXlQYWlyLmdldEtleXMoKTtcblxuICAgIGlmICgha2V5cy5wcnYpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBwcnYgaW4ga2V5IGdlbmVyYXRpb24uJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHB1Yjoga2V5cy5wdWIsXG4gICAgICBwcnY6IGtleXMucHJ2LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGlucHV0IGlzIHZhbGlkIHB1YmxpYyBrZXkgZm9yIHRoZSBjb2luLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHViIHRoZSBwdWIgdG8gYmUgY2hlY2tlZFxuICAgKiBAcmV0dXJucyB7Qm9vbGVhbn0gaXMgaXQgdmFsaWQ/XG4gICAqL1xuICBpc1ZhbGlkUHViKHB1Yjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkocHViKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZnkgdGhhdCBhIHRyYW5zYWN0aW9uIHByZWJ1aWxkIGNvbXBsaWVzIHdpdGggdGhlIG9yaWdpbmFsIGludGVudGlvblxuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqIEBwYXJhbSBwYXJhbXMudHhQcmVidWlsZFxuICAgKiBAcGFyYW0gcGFyYW1zLnR4UGFyYW1zXG4gICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgKi9cbiAgYXN5bmMgdmVyaWZ5VHJhbnNhY3Rpb24ocGFyYW1zOiBWZXJpZnlUcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgdHJhbnNhY3Rpb24gdmVyaWZpY2F0aW9uXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGFkZHJlc3MgaXMgYSB3YWxsZXQgYWRkcmVzc1xuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqL1xuICBhc3luYyBpc1dhbGxldEFkZHJlc3MocGFyYW1zOiBWZXJpZnlBZGRyZXNzT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIC8vIFRPRE86IEltcGxlbWVudCBhZGRyZXNzIHZlcmlmaWNhdGlvblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBdWRpdCBhIGRlY3J5cHRlZCBwcml2YXRlIGtleSBmb3Igc2VjdXJpdHkgcHVycG9zZXNcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgYXVkaXREZWNyeXB0ZWRLZXkocGFyYW1zOiBBdWRpdERlY3J5cHRlZEtleVBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIFRPRE86IEltcGxlbWVudCBrZXkgYXVkaXRpbmcgbG9naWMgaWYgbmVlZGVkXG4gICAgLy8gVGhpcyBtZXRob2QgaXMgdHlwaWNhbGx5IHVzZWQgZm9yIHNlY3VyaXR5IGNvbXBsaWFuY2VcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2UgYSB0cmFuc2FjdGlvbiBmcm9tIHRoZSByYXcgdHJhbnNhY3Rpb24gaGV4XG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICovXG4gIGFzeW5jIHBhcnNlVHJhbnNhY3Rpb24ocGFyYW1zOiBQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8UGFyc2VkVHJhbnNhY3Rpb24+IHtcbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgdHJhbnNhY3Rpb24gcGFyc2luZ1xuICAgIHJldHVybiB7fSBhcyBQYXJzZWRUcmFuc2FjdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBsYWluIGEgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgZXhwbGFpblRyYW5zYWN0aW9uKHBhcmFtczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBQcm9taXNlPFRyYW5zYWN0aW9uRXhwbGFuYXRpb24+IHtcbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgdHJhbnNhY3Rpb24gZXhwbGFuYXRpb25cbiAgICByZXR1cm4ge30gYXMgVHJhbnNhY3Rpb25FeHBsYW5hdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBTaWduIGEgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgc2lnblRyYW5zYWN0aW9uKHBhcmFtczogU2lnblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8U2lnbmVkVHJhbnNhY3Rpb24+IHtcbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgdHJhbnNhY3Rpb24gc2lnbmluZ1xuICAgIHJldHVybiB7fSBhcyBTaWduZWRUcmFuc2FjdGlvbjtcbiAgfVxufVxuIl19
|
|
501
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVtcG8uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVtcG8udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0dBRUc7QUFDSCwyREFZa0M7QUFFbEMsbURBZThCO0FBQzlCLHlEQUE0RDtBQUM1RCxpREFBeUU7QUFDekUsbUNBQWdDO0FBQ2hDLCtCQUFrRTtBQUNsRSx1Q0FLcUI7QUFDckIsK0NBQStGO0FBQy9GLHlDQUEyQjtBQUMzQix5REFBMkM7QUFFM0MsTUFBYSxLQUFNLFNBQVEsc0NBQXVCO0lBQ2hELFlBQXNCLEtBQWdCLEVBQUUsV0FBdUM7UUFDN0UsS0FBSyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQWdCLEVBQUUsV0FBdUM7UUFDN0UsT0FBTyxJQUFJLEtBQUssQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsUUFBUTtRQUNOLE9BQU8sSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLElBQUksT0FBTyxDQUFDO0lBQzVDLENBQUM7SUFFRDs7T0FFRztJQUNILFdBQVc7UUFDVCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLGFBQWE7UUFDWCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7SUFFRDs7O09BR0c7SUFDSCx3QkFBd0I7UUFDdEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxXQUFXO1FBQ1QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxlQUFlO1FBQ2IsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsY0FBYyxDQUFDLE9BQWU7UUFDNUIsSUFBSSxPQUFPLE9B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Z0NBQzNDLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztnQ0FDdkIsdUJBQXVCLEVBQUUsTUFBTSxDQUFDLHVCQUF1Qjs2QkFDeEQ7NEJBQ0QsS0FBSzs0QkFDTCxlQUFlLEVBQUUsRUFBRTt5QkFDcEI7cUJBQ0Y7aUJBQ0Y7YUFDRjtTQUNGLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDTyxxQkFBcUIsQ0FBQyxNQUE4QjtRQUM1RCxPQUFPLElBQUksNkJBQXVCLENBQUMsZUFBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBa0MsQ0FBQztJQUN0RyxDQUFDO0NBQ0Y7QUF4aEJELHNCQXdoQkMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBwcmV0dGllclxuICovXG5pbXBvcnQge1xuICBBYnN0cmFjdEV0aExpa2VOZXdDb2lucyxcbiAgUmVjb3Zlck9wdGlvbnMsXG4gIE9mZmxpbmVWYXVsdFR4SW5mbyxcbiAgVW5zaWduZWRTd2VlcFR4TVBDdjIsXG4gIFJlY292ZXJ5SW5mbyxcbiAgVHJhbnNhY3Rpb25CdWlsZGVyLFxuICBWZXJpZnlFdGhUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFZlcmlmeUV0aEFkZHJlc3NPcHRpb25zLFxuICBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucyxcbiAgb3B0aW9uYWxEZXBzLFxuICBLZXlQYWlyLFxufSBmcm9tICdAYml0Z28tYmV0YS9hYnN0cmFjdC1ldGgnO1xuaW1wb3J0IHR5cGUgKiBhcyBFdGhMaWtlQ29tbW9uIGZyb20gJ0BldGhlcmV1bWpzL2NvbW1vbic7XG5pbXBvcnQge1xuICBCYXNlQ29pbixcbiAgQml0R29CYXNlLFxuICBJbnZhbGlkQWRkcmVzc0Vycm9yLFxuICBJbnZhbGlkTWVtb0lkRXJyb3IsXG4gIE1QQ0FsZ29yaXRobSxcbiAgUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFBhcnNlZFRyYW5zYWN0aW9uLFxuICBVbmV4cGVjdGVkQWRkcmVzc0Vycm9yLFxuICBQb3B1bGF0ZWRJbnRlbnQsXG4gIFByZWJ1aWxkVHJhbnNhY3Rpb25XaXRoSW50ZW50T3B0aW9ucyxcbiAgY29tbW9uLFxuICBFY2RzYSxcbiAgRUNEU0FVdGlscyxcbiAgZ2V0SXNVbnNpZ25lZFN3ZWVwLFxufSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBnZXREZXJpdmF0aW9uUGF0aCB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1saWItbXBjJztcbmltcG9ydCB7IEJhc2VDb2luIGFzIFN0YXRpY3NCYXNlQ29pbiwgY29pbnMgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCB7IGV0aGVycyB9IGZyb20gJ2V0aGVycyc7XG5pbXBvcnQgeyBUaXAyMFRyYW5zYWN0aW9uLCBUaXAyMFRyYW5zYWN0aW9uQnVpbGRlciB9IGZyb20gJy4vbGliJztcbmltcG9ydCB7XG4gIGFtb3VudFRvVGlwMjBVbml0cyxcbiAgdGlwMjBVbml0c1RvQW1vdW50LFxuICBpc1RpcDIwVHJhbnNhY3Rpb24sXG4gIGlzVmFsaWRNZW1vSWQgYXMgaXNWYWxpZE1lbW9JZFV0aWwsXG59IGZyb20gJy4vbGliL3V0aWxzJztcbmltcG9ydCB7IE1BSU5ORVRfQ09JTiwgUEFUSF9VU0RfVE9LRU5fTUFJTk5FVCwgUEFUSF9VU0RfVE9LRU5fVEVTVE5FVCB9IGZyb20gJy4vbGliL2NvbnN0YW50cyc7XG5pbXBvcnQgKiBhcyB1cmwgZnJvbSAndXJsJztcbmltcG9ydCAqIGFzIHF1ZXJ5c3RyaW5nIGZyb20gJ3F1ZXJ5c3RyaW5nJztcblxuZXhwb3J0IGNsYXNzIFRlbXBvIGV4dGVuZHMgQWJzdHJhY3RFdGhMaWtlTmV3Q29pbnMge1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoYml0Z286IEJpdEdvQmFzZSwgc3RhdGljc0NvaW4/OiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+KSB7XG4gICAgc3VwZXIoYml0Z28sIHN0YXRpY3NDb2luKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGYWN0b3J5IG1ldGhvZCB0byBjcmVhdGUgVGVtcG8gaW5zdGFuY2VcbiAgICovXG4gIHN0YXRpYyBjcmVhdGVJbnN0YW5jZShiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pOiBCYXNlQ29pbiB7XG4gICAgcmV0dXJuIG5ldyBUZW1wbyhiaXRnbywgc3RhdGljc0NvaW4pO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgY2hhaW4gaWRlbnRpZmllclxuICAgKi9cbiAgZ2V0Q2hhaW4oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGljc0NvaW4/Lm5hbWUgfHwgJ3RlbXBvJztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGZ1bGwgY2hhaW4gbmFtZVxuICAgKi9cbiAgZ2V0RnVsbE5hbWUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gJ1RlbXBvJztcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBnZXRCYXNlRmFjdG9yKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIDFlNjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB2YWx1ZS1sZXNzIHRyYW5zZmVycyBhcmUgYWxsb3dlZFxuICAgKiBFVk0tYmFzZWQgY2hhaW5zIGFsbG93IHplcm8tdmFsdWUgdHJhbnNmZXJzIGZvciBzbWFydCBjb250cmFjdCBpbnRlcmFjdGlvbnNcbiAgICovXG4gIHZhbHVlbGVzc1RyYW5zZmVyQWxsb3dlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBUU1MgaXMgc3VwcG9ydGVkXG4gICAqL1xuICBzdXBwb3J0c1RzcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIE1QQyBhbGdvcml0aG0gKEVDRFNBIGZvciBFVk0gY2hhaW5zKVxuICAgKi9cbiAgZ2V0TVBDQWxnb3JpdGhtKCk6IE1QQ0FsZ29yaXRobSB7XG4gICAgcmV0dXJuICdlY2RzYSc7XG4gIH1cblxuICAvKipcbiAgICogRXZhbHVhdGVzIHdoZXRoZXIgYW4gYWRkcmVzcyBzdHJpbmcgaXMgdmFsaWQgZm9yIFRlbXBvXG4gICAqIFN1cHBvcnRzIGFkZHJlc3NlcyB3aXRoIG9wdGlvbmFsIG1lbW9JZCBxdWVyeSBwYXJhbWV0ZXIgKGUuZy4sIDB4Li4uP21lbW9JZD0xMjMpXG4gICAqIEBwYXJhbSBhZGRyZXNzIC0gVGhlIGFkZHJlc3MgdG8gdmFsaWRhdGVcbiAgICogQHJldHVybnMgdHJ1ZSBpZiBhZGRyZXNzIGlzIHZhbGlkXG4gICAqL1xuICBpc1ZhbGlkQWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAodHlwZW9mIGFkZHJlc3MgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgYmFzZUFkZHJlc3MgfSA9IHRoaXMuZ2V0QWRkcmVzc0RldGFpbHMoYWRkcmVzcyk7XG4gICAgICByZXR1cm4gb3B0aW9uYWxEZXBzLmV0aFV0aWwuaXNWYWxpZEFkZHJlc3Mob3B0aW9uYWxEZXBzLmV0aFV0aWwuYWRkSGV4UHJlZml4KGJhc2VBZGRyZXNzKSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZSBhZGRyZXNzIGludG8gYmFzZSBhZGRyZXNzIGFuZCBvcHRpb25hbCBtZW1vSWRcbiAgICogVGhyb3dzIEludmFsaWRBZGRyZXNzRXJyb3IgZm9yIGludmFsaWQgYWRkcmVzcyBmb3JtYXRzXG4gICAqIEBwYXJhbSBhZGRyZXNzIC0gQWRkcmVzcyBzdHJpbmcsIHBvdGVudGlhbGx5IHdpdGggP21lbW9JZD1YIHN1ZmZpeFxuICAgKiBAcmV0dXJucyBPYmplY3QgY29udGFpbmluZyBhZGRyZXNzLCBiYXNlQWRkcmVzcywgYW5kIG1lbW9JZCAobnVsbCBpZiBub3QgcHJlc2VudClcbiAgICogQHRocm93cyBJbnZhbGlkQWRkcmVzc0Vycm9yIGlmIGFkZHJlc3MgZm9ybWF0IGlzIGludmFsaWRcbiAgICovXG4gIGdldEFkZHJlc3NEZXRhaWxzKGFkZHJlc3M6IHN0cmluZyk6IHsgYWRkcmVzczogc3RyaW5nOyBiYXNlQWRkcmVzczogc3RyaW5nOyBtZW1vSWQ6IHN0cmluZyB8IG51bGwgfSB7XG4gICAgaWYgKHR5cGVvZiBhZGRyZXNzICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBZGRyZXNzRXJyb3IoYGludmFsaWQgYWRkcmVzczogJHthZGRyZXNzfWApO1xuICAgIH1cblxuICAgIGNvbnN0IGRlc3RpbmF0aW9uRGV0YWlscyA9IHVybC5wYXJzZShhZGRyZXNzKTtcbiAgICBjb25zdCBiYXNlQWRkcmVzcyA9IGRlc3RpbmF0aW9uRGV0YWlscy5wYXRobmFtZSB8fCAnJztcblxuICAgIC8vIE5vIHF1ZXJ5IHN0cmluZyAtIGp1c3QgYSBwbGFpbiBhZGRyZXNzXG4gICAgaWYgKGRlc3RpbmF0aW9uRGV0YWlscy5wYXRobmFtZSA9PT0gYWRkcmVzcykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYWRkcmVzcyxcbiAgICAgICAgYmFzZUFkZHJlc3M6IGFkZHJlc3MsXG4gICAgICAgIG1lbW9JZDogbnVsbCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gSGFzIHF1ZXJ5IHN0cmluZyAtIG11c3QgY29udGFpbiBtZW1vSWRcbiAgICBpZiAoIWRlc3RpbmF0aW9uRGV0YWlscy5xdWVyeSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBZGRyZXNzRXJyb3IoYGludmFsaWQgYWRkcmVzczogJHthZGRyZXNzfWApO1xuICAgIH1cblxuICAgIGNvbnN0IHF1ZXJ5RGV0YWlscyA9IHF1ZXJ5c3RyaW5nLnBhcnNlKGRlc3RpbmF0aW9uRGV0YWlscy5xdWVyeSk7XG5cbiAgICAvLyBRdWVyeSBzdHJpbmcgbXVzdCBjb250YWluIG1lbW9JZFxuICAgIGlmICghcXVlcnlEZXRhaWxzLm1lbW9JZCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBZGRyZXNzRXJyb3IoYGludmFsaWQgYWRkcmVzczogJHthZGRyZXNzfSwgdW5rbm93biBxdWVyeSBwYXJhbWV0ZXJzYCk7XG4gICAgfVxuXG4gICAgLy8gT25seSBvbmUgbWVtb0lkIGFsbG93ZWRcbiAgICBpZiAoQXJyYXkuaXNBcnJheShxdWVyeURldGFpbHMubWVtb0lkKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBZGRyZXNzRXJyb3IoXG4gICAgICAgIGBtZW1vSWQgbWF5IG9ubHkgYmUgZ2l2ZW4gYXQgbW9zdCBvbmNlLCBidXQgZm91bmQgJHtxdWVyeURldGFpbHMubWVtb0lkLmxlbmd0aH0gaW5zdGFuY2VzIGluIGFkZHJlc3MgJHthZGRyZXNzfWBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gUmVqZWN0IGlmIHRoZXJlIGFyZSBvdGhlciBxdWVyeSBwYXJhbWV0ZXJzIGJlc2lkZXMgbWVtb0lkXG4gICAgY29uc3QgcXVlcnlLZXlzID0gT2JqZWN0LmtleXMocXVlcnlEZXRhaWxzKTtcbiAgICBpZiAocXVlcnlLZXlzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBZGRyZXNzRXJyb3IoYGludmFsaWQgYWRkcmVzczogJHthZGRyZXNzfSwgb25seSBtZW1vSWQgcXVlcnkgcGFyYW1ldGVyIGlzIGFsbG93ZWRgKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSBtZW1vSWQgZm9ybWF0XG4gICAgaWYgKCF0aGlzLmlzVmFsaWRNZW1vSWQocXVlcnlEZXRhaWxzLm1lbW9JZCkpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkTWVtb0lkRXJyb3IoYGludmFsaWQgYWRkcmVzczogJyR7YWRkcmVzc30nLCBtZW1vSWQgaXMgbm90IHZhbGlkYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFkZHJlc3MsXG4gICAgICBiYXNlQWRkcmVzcyxcbiAgICAgIG1lbW9JZDogcXVlcnlEZXRhaWxzLm1lbW9JZCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIHRoYXQgYSBtZW1vSWQgaXMgYSB2YWxpZCBub24tbmVnYXRpdmUgaW50ZWdlciBzdHJpbmdcbiAgICogQHBhcmFtIG1lbW9JZCAtIFRoZSBtZW1vSWQgdG8gdmFsaWRhdGVcbiAgICogQHJldHVybnMgdHJ1ZSBpZiB2YWxpZFxuICAgKi9cbiAgaXNWYWxpZE1lbW9JZChtZW1vSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc1ZhbGlkTWVtb0lkVXRpbChtZW1vSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRlbXBvIHVzZXMgbWVtb0lkLWJhc2VkIGFkZHJlc3NlcyByYXRoZXIgdGhhbiBmb3J3YXJkZXIgY29udHJhY3RzLlxuICAgKiBWZXJpZnkgdGhhdCB0aGUgYWRkcmVzcyBiZWxvbmdzIHRvIHRoaXMgd2FsbGV0IGJ5IGNoZWNraW5nIHRoYXQgdGhlXG4gICAqIGJhc2UgKEVWTSkgcG9ydGlvbiBtYXRjaGVzIHRoZSB3YWxsZXQncyBiYXNlIGFkZHJlc3MuXG4gICAqL1xuICBhc3luYyBpc1dhbGxldEFkZHJlc3MocGFyYW1zOiBWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucyB8IFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgeyBhZGRyZXNzLCBiYXNlQWRkcmVzcyB9ID0gcGFyYW1zO1xuICAgIGNvbnN0IHJvb3RBZGRyZXNzID0gKHBhcmFtcyBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5yb290QWRkcmVzcyBhcyBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICBpZiAoIWFkZHJlc3MpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQWRkcmVzc0Vycm9yKCdhZGRyZXNzIGlzIHJlcXVpcmVkJyk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFkZHJlc3NFcnJvcihgaW52YWxpZCBhZGRyZXNzOiAke2FkZHJlc3N9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBiYXNlQWRkcmVzczogYWRkcmVzc0Jhc2UgfSA9IHRoaXMuZ2V0QWRkcmVzc0RldGFpbHMoYWRkcmVzcyk7XG5cbiAgICBjb25zdCB3YWxsZXRCYXNlQWRkcmVzcyA9IGJhc2VBZGRyZXNzIHx8IHJvb3RBZGRyZXNzO1xuICAgIGlmICghd2FsbGV0QmFzZUFkZHJlc3MpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQWRkcmVzc0Vycm9yKCdiYXNlQWRkcmVzcyBvciByb290QWRkcmVzcyBpcyByZXF1aXJlZCBmb3IgdmVyaWZpY2F0aW9uJyk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBiYXNlQWRkcmVzczogd2FsbGV0QmFzZSB9ID0gdGhpcy5nZXRBZGRyZXNzRGV0YWlscyh3YWxsZXRCYXNlQWRkcmVzcyk7XG5cbiAgICBpZiAoYWRkcmVzc0Jhc2UudG9Mb3dlckNhc2UoKSAhPT0gd2FsbGV0QmFzZS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICB0aHJvdyBuZXcgVW5leHBlY3RlZEFkZHJlc3NFcnJvcihgYWRkcmVzcyB2YWxpZGF0aW9uIGZhaWx1cmU6IGV4cGVjdGVkICR7d2FsbGV0QmFzZX0gYnV0IGdvdCAke2FkZHJlc3NCYXNlfWApO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNlIGEgc2VyaWFsaXNlZCBUZW1wbyB0cmFuc2FjdGlvbiBhbmQgcmV0dXJuIGl0cyBvcGVyYXRpb25zIGFzIFNESyBvdXRwdXRzLlxuICAgKiBAaW5oZXJpdGRvY1xuICAgKi9cbiAgYXN5bmMgcGFyc2VUcmFuc2FjdGlvbihwYXJhbXM6IFBhcnNlVHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxQYXJzZWRUcmFuc2FjdGlvbj4ge1xuICAgIGNvbnN0IHR4SGV4ID0gKHBhcmFtcy50eEhleCB8fCAocGFyYW1zIGFzIGFueSkuaGFsZlNpZ25lZD8udHhIZXgpIGFzIHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBpZiAoIXR4SGV4KSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGlmICghaXNUaXAyMFRyYW5zYWN0aW9uKHR4SGV4KSkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjb25zdCB0eEJ1aWxkZXIgPSB0aGlzLmdldFRyYW5zYWN0aW9uQnVpbGRlcigpO1xuICAgIHR4QnVpbGRlci5mcm9tKHR4SGV4KTtcbiAgICBjb25zdCB0eCA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVGlwMjBUcmFuc2FjdGlvbjtcbiAgICByZXR1cm4ge1xuICAgICAgaW5wdXRzOiB0eC5pbnB1dHMubWFwKChpbnB1dCkgPT4gKHtcbiAgICAgICAgYWRkcmVzczogaW5wdXQuYWRkcmVzcyxcbiAgICAgICAgYW1vdW50OiBpbnB1dC52YWx1ZSxcbiAgICAgICAgY29pbjogdGhpcy5nZXRDaGFpbigpLFxuICAgICAgfSkpLFxuICAgICAgb3V0cHV0czogdHgub3V0cHV0cy5tYXAoKG91dHB1dCkgPT4gKHtcbiAgICAgICAgYWRkcmVzczogb3V0cHV0LmFkZHJlc3MsXG4gICAgICAgIGFtb3VudDogb3V0cHV0LnZhbHVlLFxuICAgICAgICBjb2luOiB0aGlzLmdldENoYWluKCksXG4gICAgICB9KSksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZnkgdGhhdCBhIFRlbXBvIHRyYW5zYWN0aW9uIG1hdGNoZXMgdGhlIGludGVuZGVkIHJlY2lwaWVudHMgYW5kIGFtb3VudHMuXG4gICAqIEBpbmhlcml0ZG9jXG4gICAqL1xuICBhc3luYyB2ZXJpZnlUcmFuc2FjdGlvbihwYXJhbXM6IFZlcmlmeUV0aFRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQgfSA9IHBhcmFtcztcblxuICAgIGlmICghdHhQcmVidWlsZD8udHhIZXgpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIHNpZ25hYmxlSGV4IG1heSBhcnJpdmUgd2l0aG91dCB0aGUgMHggcHJlZml4IChlLmcuIGZyb20gdGhlIFRTUyBzaWduaW5nIGZsb3cpLlxuICAgIGNvbnN0IHR4SGV4ID0gdHhQcmVidWlsZC50eEhleC5zdGFydHNXaXRoKCcweCcpID8gdHhQcmVidWlsZC50eEhleCA6ICcweCcgKyB0eFByZWJ1aWxkLnR4SGV4O1xuICAgIGlmICghaXNUaXAyMFRyYW5zYWN0aW9uKHR4SGV4KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIFRlbXBvIHRyYW5zYWN0aW9uIGhleDogZXhwZWN0ZWQgYSAweDc2IFRJUC0yMCB0cmFuc2FjdGlvbmApO1xuICAgIH1cblxuICAgIGNvbnN0IHR4QnVpbGRlciA9IHRoaXMuZ2V0VHJhbnNhY3Rpb25CdWlsZGVyKCk7XG4gICAgdHhCdWlsZGVyLmZyb20odHhIZXgpO1xuICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUaXAyMFRyYW5zYWN0aW9uO1xuICAgIGNvbnN0IG9wZXJhdGlvbnMgPSB0eC5nZXRPcGVyYXRpb25zKCk7XG4gICAgY29uc3QgcmF3Q2FsbHMgPSB0eC5nZXRSYXdDYWxscygpO1xuXG4gICAgLy8gSWYgdGhlIGNhbGxlciBzcGVjaWZpZWQgZXhwbGljaXQgcmVjaXBpZW50cywgdmVyaWZ5IHRoZXkgbWF0Y2ggdGhlIHRyYW5zYWN0aW9uLlxuICAgIC8vIEEgdHJhbnNhY3Rpb24gaXMgZWl0aGVyIGFsbCB0b2tlbiB0cmFuc2ZlciBvcGVyYXRpb25zIE9SIGEgc2luZ2xlIHJhdyBjb250cmFjdCBjYWxsIOKAlCBuZXZlciBtaXhlZC5cbiAgICBjb25zdCByZWNpcGllbnRzID0gdHhQYXJhbXM/LnJlY2lwaWVudHM7XG4gICAgaWYgKHJlY2lwaWVudHMgJiYgcmVjaXBpZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAocmF3Q2FsbHMubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyBDb250cmFjdCBjYWxsIHRyYW5zYWN0aW9uIOKAlCBzaW5nbGUgcmF3IGNhbGwsIHNpbmdsZSByZWNpcGllbnQgd2l0aCBkYXRhXG4gICAgICAgIGlmIChyYXdDYWxscy5sZW5ndGggIT09IHJlY2lwaWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYFRyYW5zYWN0aW9uIGhhcyAke3Jhd0NhbGxzLmxlbmd0aH0gY2FsbChzKSBidXQgJHtyZWNpcGllbnRzLmxlbmd0aH0gcmVjaXBpZW50KHMpIHdlcmUgcmVxdWVzdGVkYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYXdDYWxscy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IHJhd0NhbGwgPSByYXdDYWxsc1tpXTtcbiAgICAgICAgICBjb25zdCByZWNpcGllbnQgPSByZWNpcGllbnRzW2ldO1xuICAgICAgICAgIGlmIChyYXdDYWxsLnRvLnRvTG93ZXJDYXNlKCkgIT09IHJlY2lwaWVudC5hZGRyZXNzLnNwbGl0KCc/JylbMF0udG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBSYXcgY2FsbCAke2l9IGFkZHJlc3MgbWlzbWF0Y2g6IGV4cGVjdGVkICR7cmVjaXBpZW50LmFkZHJlc3N9LCBnb3QgJHtyYXdDYWxsLnRvfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIXJlY2lwaWVudC5kYXRhIHx8IHJhd0NhbGwuZGF0YS50b0xvd2VyQ2FzZSgpICE9PSByZWNpcGllbnQuZGF0YS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFJhdyBjYWxsICR7aX0gY2FsbGRhdGEgbWlzbWF0Y2hgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRva2VuIHRyYW5zZmVyIHRyYW5zYWN0aW9uIOKAlCBvcGVyYXRpb25zIG1hdGNoZWQgMS10by0xIGFnYWluc3QgcmVjaXBpZW50c1xuICAgICAgICBpZiAob3BlcmF0aW9ucy5sZW5ndGggIT09IHJlY2lwaWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYFRyYW5zYWN0aW9uIGhhcyAke29wZXJhdGlvbnMubGVuZ3RofSBvcGVyYXRpb24ocykgYnV0ICR7cmVjaXBpZW50cy5sZW5ndGh9IHJlY2lwaWVudChzKSB3ZXJlIHJlcXVlc3RlZGBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3BlcmF0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IG9wID0gb3BlcmF0aW9uc1tpXTtcbiAgICAgICAgICBjb25zdCByZWNpcGllbnQgPSByZWNpcGllbnRzW2ldO1xuICAgICAgICAgIGNvbnN0IHJlY2lwaWVudEJhc2VBZGRyZXNzID0gcmVjaXBpZW50LmFkZHJlc3Muc3BsaXQoJz8nKVswXTtcbiAgICAgICAgICBpZiAob3AudG8udG9Mb3dlckNhc2UoKSAhPT0gcmVjaXBpZW50QmFzZUFkZHJlc3MudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBPcGVyYXRpb24gJHtpfSByZWNpcGllbnQgbWlzbWF0Y2g6IGV4cGVjdGVkICR7cmVjaXBpZW50LmFkZHJlc3N9LCBnb3QgJHtvcC50b31gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3Qgb3BBbW91bnRCYXNlVW5pdHMgPSBhbW91bnRUb1RpcDIwVW5pdHMob3AuYW1vdW50KS50b1N0cmluZygpO1xuICAgICAgICAgIGlmIChvcEFtb3VudEJhc2VVbml0cyAhPT0gcmVjaXBpZW50LmFtb3VudC50b1N0cmluZygpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE9wZXJhdGlvbiAke2l9IGFtb3VudCBtaXNtYXRjaDogZXhwZWN0ZWQgJHtyZWNpcGllbnQuYW1vdW50fSwgZ290ICR7b3BBbW91bnRCYXNlVW5pdHN9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVmVyaWZ5IGZlZSB0b2tlbiBpZiBzcGVjaWZpZWRcbiAgICBpZiAodHhQYXJhbXM/LmZlZVRva2VuKSB7XG4gICAgICBjb25zdCB0eEZlZVRva2VuID0gdHguZ2V0RmVlVG9rZW4oKTtcbiAgICAgIGlmICh0eEZlZVRva2VuPy50b0xvd2VyQ2FzZSgpICE9PSB0eFBhcmFtcy5mZWVUb2tlbi50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRmVlIHRva2VuIG1pc21hdGNoOiBleHBlY3RlZCAke3R4UGFyYW1zLmZlZVRva2VufSwgZ290ICR7dHhGZWVUb2tlbiB8fCAnbm9uZSd9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogU2V0IGNvaW4tc3BlY2lmaWMgZmllbGRzIGluIHRoZSBpbnRlbnQgZm9yIFRlbXBvIFRTUyB0cmFuc2FjdGlvbnMuXG4gICAqIEVuc3VyZXMgZmVlVG9rZW4gaXMgcHJvcGVybHkgd2lyZWQgdGhyb3VnaCB0aGUgaW50ZW50IGZvciBUZW1wbyB0cmFuc2FjdGlvbnMuXG4gICAqIEBwYXJhbSBpbnRlbnQgLSBUaGUgcG9wdWxhdGVkIGludGVudCB0byBtb2RpZnlcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGNvbnRhaW5pbmcgZmVlVG9rZW5cbiAgICovXG4gIHNldENvaW5TcGVjaWZpY0ZpZWxkc0luSW50ZW50KGludGVudDogUG9wdWxhdGVkSW50ZW50LCBwYXJhbXM6IFByZWJ1aWxkVHJhbnNhY3Rpb25XaXRoSW50ZW50T3B0aW9ucyk6IHZvaWQge1xuICAgIGlmIChwYXJhbXMuZmVlVG9rZW4pIHtcbiAgICAgIGludGVudC5mZWVPcHRpb25zID0gaW50ZW50LmZlZU9wdGlvbnNcbiAgICAgICAgPyB7IC4uLmludGVudC5mZWVPcHRpb25zLCBmZWVUb2tlbjogcGFyYW1zLmZlZVRva2VuIH1cbiAgICAgICAgOiB7IGZlZVRva2VuOiBwYXJhbXMuZmVlVG9rZW4gfTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUXVlcnkgdGhlIFRlbXBvIEFsY2hlbXkgUlBDIGZvciByZWNvdmVyeSBiYWxhbmNlL25vbmNlIGluZm9ybWF0aW9uLlxuICAgKiBSb3V0ZXMgdGhyb3VnaCBxdWVyeVRlbXBvUnBjIHVzaW5nIHRoZSBVUkwgZnJvbSBlbnZpcm9ubWVudHMudHMuXG4gICAqL1xuICBhc3luYyByZWNvdmVyeUJsb2NrY2hhaW5FeHBsb3JlclF1ZXJ5KFxuICAgIHF1ZXJ5OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+LFxuICAgIGFwaUtleT86IHN0cmluZ1xuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHVua25vd24+PiB7XG4gICAgY29uc3QgZXZtQ29uZmlnID0gY29tbW9uLkVudmlyb25tZW50c1t0aGlzLmJpdGdvLmdldEVudigpXS5ldm07XG4gICAgY29uc3QgY29pbkZhbWlseSA9IHRoaXMuZ2V0RmFtaWx5KCk7XG4gICAgaWYgKCFldm1Db25maWcgfHwgIShjb2luRmFtaWx5IGluIGV2bUNvbmZpZykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgZW52IGNvbmZpZyBtaXNzaW5nIGZvciAke2NvaW5GYW1pbHl9IGluICR7dGhpcy5iaXRnby5nZXRFbnYoKX1gKTtcbiAgICB9XG4gICAgY29uc3QgdG9rZW4gPSBhcGlLZXkgfHwgZXZtQ29uZmlnW2NvaW5GYW1pbHldLmFwaVRva2VuO1xuICAgIGNvbnN0IHJwY1VybCA9IGV2bUNvbmZpZ1tjb2luRmFtaWx5XS5iYXNlVXJsO1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5VGVtcG9ScGMocXVlcnksIHJwY1VybCwgdG9rZW4pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zbGF0ZXMgRXRoZXJzY2FuLXN0eWxlIHJlY292ZXJ5IHF1ZXJpZXMgaW50byBUZW1wbyBBbGNoZW15IEpTT04tUlBDIGNhbGxzLlxuICAgKlxuICAgKiBTdXBwb3J0ZWQ6XG4gICAqICAgYWNjb3VudC9iYWxhbmNlICAgICAg4oaSIHJldHVybnMgeyByZXN1bHQ6ICcwJyB9IChubyBuYXRpdmUgY29pbiBvbiBUZW1wbylcbiAgICogICBhY2NvdW50L3Rva2VuYmFsYW5jZSDihpIgZXRoX2NhbGwgKGJhbGFuY2VPZiBzZWxlY3RvciAweDcwYTA4MjMxKSDihpIgeyByZXN1bHQ6IGRlY2ltYWxTdHJpbmcgfVxuICAgKiAgIGFjY291bnQvdHhsaXN0ICAgICAgIOKGkiBldGhfZ2V0VHJhbnNhY3Rpb25Db3VudCDihpIgeyBub25jZTogbnVtYmVyIH1cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcXVlcnlUZW1wb1JwYyhcbiAgICBxdWVyeTogUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbiAgICBycGNVcmw6IHN0cmluZyxcbiAgICBhcGlLZXk/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4ge1xuICAgIGNvbnN0IGVuZHBvaW50ID0gYXBpS2V5ID8gYCR7cnBjVXJsfSR7YXBpS2V5fWAgOiBycGNVcmw7XG4gICAgY29uc3QgeyBtb2R1bGUsIGFjdGlvbiwgYWRkcmVzcywgY29udHJhY3RhZGRyZXNzLCB0YWcgfSA9IHF1ZXJ5O1xuXG4gICAgbGV0IG1ldGhvZDogc3RyaW5nO1xuICAgIGxldCBwYXJhbXM6IHVua25vd25bXTtcblxuICAgIGlmIChtb2R1bGUgPT09ICdhY2NvdW50JyAmJiBhY3Rpb24gPT09ICdiYWxhbmNlJykge1xuICAgICAgcmV0dXJuIHsgcmVzdWx0OiAnMCcgfTtcbiAgICB9IGVsc2UgaWYgKG1vZHVsZSA9PT0gJ2FjY291bnQnICYmIGFjdGlvbiA9PT0gJ3Rva2VuYmFsYW5jZScpIHtcbiAgICAgIGNvbnN0IHBhZGRlZEFkZHIgPSAoYWRkcmVzcyA/PyAnJykucmVwbGFjZSgvXjB4LywgJycpLnBhZFN0YXJ0KDY0LCAnMCcpO1xuICAgICAgbWV0aG9kID0gJ2V0aF9jYWxsJztcbiAgICAgIHBhcmFtcyA9IFt7IHRvOiBjb250cmFjdGFkZHJlc3MsIGRhdGE6ICcweDcwYTA4MjMxJyArIHBhZGRlZEFkZHIgfSwgdGFnID8/ICdsYXRlc3QnXTtcbiAgICB9IGVsc2UgaWYgKG1vZHVsZSA9PT0gJ2FjY291bnQnICYmIGFjdGlvbiA9PT0gJ3R4bGlzdCcpIHtcbiAgICAgIG1ldGhvZCA9ICdldGhfZ2V0VHJhbnNhY3Rpb25Db3VudCc7XG4gICAgICBwYXJhbXMgPSBbYWRkcmVzcywgJ2xhdGVzdCddO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHF1ZXJ5VGVtcG9ScGM6IHVuc3VwcG9ydGVkIG1vZHVsZT0ke21vZHVsZX0gYWN0aW9uPSR7YWN0aW9ufWApO1xuICAgIH1cblxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKGVuZHBvaW50LCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBqc29ucnBjOiAnMi4wJywgbWV0aG9kLCBwYXJhbXMsIGlkOiAxIH0pLFxuICAgIH0pO1xuXG4gICAgaWYgKCFyZXMub2spIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ291bGQgbm90IHJlYWNoIFRlbXBvIFJQQyBlbmRwb2ludCAoSFRUUCAke3Jlcy5zdGF0dXN9KWApO1xuICAgIH1cblxuICAgIGNvbnN0IGJvZHkgPSAoYXdhaXQgcmVzLmpzb24oKSkgYXMgeyByZXN1bHQ/OiB1bmtub3duOyBlcnJvcj86IHsgbWVzc2FnZTogc3RyaW5nIH0gfTtcbiAgICBpZiAoYm9keS5lcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUZW1wbyBSUEMgZXJyb3I6ICR7Ym9keS5lcnJvci5tZXNzYWdlfWApO1xuICAgIH1cblxuICAgIGlmIChtb2R1bGUgPT09ICdhY2NvdW50JyAmJiBhY3Rpb24gPT09ICd0eGxpc3QnKSB7XG4gICAgICByZXR1cm4geyBub25jZTogcGFyc2VJbnQoYm9keS5yZXN1bHQgYXMgc3RyaW5nLCAxNikgfTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHsgcmVzdWx0OiBCaWdJbnQoYm9keS5yZXN1bHQgYXMgc3RyaW5nKS50b1N0cmluZygpIH07XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4geyByZXN1bHQ6ICcwJyB9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTaGFyZWQgaGVscGVyOiBxdWVyaWVzIHRoZSB0b2tlbiBiYWxhbmNlLCBjb21wdXRlcyBzd2VlcCBhbW91bnQsIGFuZCBidWlsZHNcbiAgICogYW4gdW5zaWduZWQgVElQLTIwIHRyYW5zZmVyIHRyYW5zYWN0aW9uLiBVc2VkIGJ5IGJvdGggcmVjb3ZlcnkgcGF0aHMuXG4gICAqXG4gICAqIC0gdG9rZW5Db250cmFjdEFkZHJlc3M6IHRoZSB0b2tlbiB0byBzd2VlcCAoZGVmYXVsdHMgdG8gcGF0aFVTRClcbiAgICogLSBmZWVUb2tlbjogYWx3YXlzIHBhdGhVU0RcbiAgICogLSBJZiBzd2VlcGluZyBwYXRoVVNEIGl0c2VsZiwgcmVzZXJ2ZXMgZ2FzTGltaXQgw5cgbWF4RmVlUGVyR2FzIC8gMTBeMTIgcGF0aFVTRCB1bml0cyBmb3IgZmVlcy5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgYnVpbGRUZW1wb1N3ZWVwVHgoXG4gICAgd2FsbGV0QWRkcmVzczogc3RyaW5nLFxuICAgIHBhcmFtczogUmVjb3Zlck9wdGlvbnNcbiAgKTogUHJvbWlzZTx7IHR4OiBUaXAyMFRyYW5zYWN0aW9uOyBub25jZTogbnVtYmVyOyBzd2VlcEFtb3VudDogYmlnaW50OyBnYXNNYXJnaW5Vbml0czogYmlnaW50IH0+IHtcbiAgICBpZiAoIXBhcmFtcy50b2tlbkNvbnRyYWN0QWRkcmVzcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0b2tlbkNvbnRyYWN0QWRkcmVzcyBpcyByZXF1aXJlZCBmb3Igc3dlZXAnKTtcbiAgICB9XG4gICAgY29uc3QgdG9rZW5BZGRyZXNzID0gcGFyYW1zLnRva2VuQ29udHJhY3RBZGRyZXNzO1xuXG4gICAgY29uc3QgcGF0aFVzZFRva2VuTmFtZSA9IHRoaXMuZ2V0Q2hhaW4oKSA9PT0gTUFJTk5FVF9DT0lOID8gUEFUSF9VU0RfVE9LRU5fTUFJTk5FVCA6IFBBVEhfVVNEX1RPS0VOX1RFU1RORVQ7XG4gICAgY29uc3QgcGF0aFVzZEFkZHJlc3MgPSAoY29pbnMuZ2V0KHBhdGhVc2RUb2tlbk5hbWUpIGFzIHVua25vd24gYXMgeyBjb250cmFjdEFkZHJlc3M6IHN0cmluZyB9KS5jb250cmFjdEFkZHJlc3M7XG5cbiAgICBjb25zdCByYXdCYWxhbmNlID0gYXdhaXQgdGhpcy5xdWVyeUFkZHJlc3NUb2tlbkJhbGFuY2UodG9rZW5BZGRyZXNzLCB3YWxsZXRBZGRyZXNzLCBwYXJhbXMuYXBpS2V5KTtcbiAgICBjb25zdCBiYWxhbmNlID0gQmlnSW50KHJhd0JhbGFuY2UudG9TdHJpbmcoKSk7XG5cbiAgICBjb25zdCBpc1BhdGhVc2QgPSB0b2tlbkFkZHJlc3MudG9Mb3dlckNhc2UoKSA9PT0gcGF0aFVzZEFkZHJlc3MudG9Mb3dlckNhc2UoKTtcbiAgICBjb25zdCBnYXNMaW1pdEJpZyA9IEJpZ0ludChwYXJhbXMuZ2FzTGltaXQgPz8gNzAwXzAwMCk7XG4gICAgY29uc3QgbWF4RmVlUGVyR2FzQmlnID0gQmlnSW50KHBhcmFtcy5laXAxNTU5Py5tYXhGZWVQZXJHYXMgPz8gMjBfMDAwXzAwMF8wMDApO1xuICAgIC8vIDc1JSBidWZmZXIgb24gdG9wIG9mIGdhc0xpbWl0IMOXIG1heEZlZVBlckdhcyB0byBjb3ZlciBhY3R1YWwgb24tY2hhaW4gZ2FzIHZhcmlhbmNlXG4gICAgY29uc3QgZ2FzTWFyZ2luVW5pdHMgPSAoZ2FzTGltaXRCaWcgKiBtYXhGZWVQZXJHYXNCaWcgKiAxNzVuKSAvICgxMG4gKiogMTJuICogMTAwbik7XG4gICAgY29uc3Qgc3dlZXBBbW91bnQgPSBpc1BhdGhVc2QgPyBiYWxhbmNlIC0gZ2FzTWFyZ2luVW5pdHMgOiBiYWxhbmNlO1xuXG4gICAgaWYgKHN3ZWVwQW1vdW50IDw9IDBuKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBJbnN1ZmZpY2llbnQgYmFsYW5jZSBpbiAke3Rva2VuQWRkcmVzc306ICR7YmFsYW5jZX0gdW5pdHMgKG1pbmltdW0gcmVxdWlyZWQ6ICR7XG4gICAgICAgICAgaXNQYXRoVXNkID8gZ2FzTWFyZ2luVW5pdHMgKyAxbiA6IDFuXG4gICAgICAgIH0pYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBzd2VlcEFtb3VudEh1bWFuID0gdGlwMjBVbml0c1RvQW1vdW50KHN3ZWVwQW1vdW50KTtcbiAgICBjb25zdCBub25jZSA9IGF3YWl0IHRoaXMuZ2V0QWRkcmVzc05vbmNlKHdhbGxldEFkZHJlc3MsIHBhcmFtcy5hcGlLZXkpO1xuXG4gICAgY29uc3QgdHhCdWlsZGVyID0gdGhpcy5nZXRUcmFuc2FjdGlvbkJ1aWxkZXIoKSBhcyB1bmtub3duIGFzIFRpcDIwVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgIHR4QnVpbGRlclxuICAgICAgLmFkZE9wZXJhdGlvbih7IHRva2VuOiB0b2tlbkFkZHJlc3MsIHRvOiBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiwgYW1vdW50OiBzd2VlcEFtb3VudEh1bWFuIH0pXG4gICAgICAuZmVlVG9rZW4ocGF0aFVzZEFkZHJlc3MpXG4gICAgICAubm9uY2Uobm9uY2UpXG4gICAgICAuZ2FzKGdhc0xpbWl0QmlnKVxuICAgICAgLm1heEZlZVBlckdhcyhtYXhGZWVQZXJHYXNCaWcpXG4gICAgICAubWF4UHJpb3JpdHlGZWVQZXJHYXMoQmlnSW50KHBhcmFtcy5laXAxNTU5Py5tYXhQcmlvcml0eUZlZVBlckdhcyA/PyAxMF8wMDBfMDAwXzAwMCkpO1xuXG4gICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRpcDIwVHJhbnNhY3Rpb247XG4gICAgcmV0dXJuIHsgdHgsIG5vbmNlLCBzd2VlcEFtb3VudCwgZ2FzTWFyZ2luVW5pdHMgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPdmVycmlkZXMgdGhlIGJhc2UtY2xhc3MgcmVjb3ZlclRTUyB0byB1c2UgVElQLTIwIHRyYW5zYWN0aW9ucyBpbnN0ZWFkIG9mIHN0YW5kYXJkIEVUSC5cbiAgICpcbiAgICogVHdvIHBhdGhzOlxuICAgKiAgIC0gVW5zaWduZWQgc3dlZXAgKHBsYWluIHB1YmxpYyBrZXkgc2hhcmVzKTogZGVsZWdhdGVzIHRvIGJ1aWxkVW5zaWduZWRTd2VlcFR4blRTU1xuICAgKiAgIC0gU2lnbmVkIHN3ZWVwIChlbmNyeXB0ZWQga2V5cyArIHBhc3NwaHJhc2UpOiBidWlsZHMgYW5kIHNpZ25zIGEgVElQLTIwIHR4IHZpYSBNUENcbiAgICovXG4gIHByb3RlY3RlZCBhc3luYyByZWNvdmVyVFNTKFxuICAgIHBhcmFtczogUmVjb3Zlck9wdGlvbnNcbiAgKTogUHJvbWlzZTxSZWNvdmVyeUluZm8gfCBPZmZsaW5lVmF1bHRUeEluZm8gfCBVbnNpZ25lZFN3ZWVwVHhNUEN2Mj4ge1xuICAgIHRoaXMudmFsaWRhdGVSZWNvdmVyeVBhcmFtcyhwYXJhbXMpO1xuICAgIGNvbnN0IHVzZXJLZXkgPSBwYXJhbXMudXNlcktleS5yZXBsYWNlKC9cXHMvZywgJycpO1xuICAgIGNvbnN0IGJhY2t1cEtleSA9IHBhcmFtcy5iYWNrdXBLZXkucmVwbGFjZSgvXFxzL2csICcnKTtcblxuICAgIGlmIChnZXRJc1Vuc2lnbmVkU3dlZXAoeyB1c2VyS2V5LCBiYWNrdXBLZXksIGlzVHNzOiBwYXJhbXMuaXNUc3MgfSkpIHtcbiAgICAgIHJldHVybiB0aGlzLmJ1aWxkVW5zaWduZWRTd2VlcFR4blRTUyhwYXJhbXMpO1xuICAgIH1cblxuICAgIC8vIFNpZ25lZCBzd2VlcDogZGVjcnlwdCBNUEMgdjIga2V5IHNoYXJlc1xuICAgIGNvbnN0IHsgdXNlcktleVNoYXJlLCBiYWNrdXBLZXlTaGFyZSwgY29tbW9uS2V5Q2hhaW4gfSA9IGF3YWl0IEVDRFNBVXRpbHMuZ2V0TXBjVjJSZWNvdmVyeUtleVNoYXJlcyhcbiAgICAgIHVzZXJLZXksXG4gICAgICBiYWNrdXBLZXksXG4gICAgICBwYXJhbXMud2FsbGV0UGFzc3BocmFzZVxuICAgICk7XG5cbiAgICBjb25zdCBNUEMgPSBuZXcgRWNkc2EoKTtcbiAgICBjb25zdCBkZXJpdmVkQ29tbW9uS2V5Q2hhaW4gPSBNUEMuZGVyaXZlVW5oYXJkZW5lZChjb21tb25LZXlDaGFpbiwgJ20vMCcpO1xuICAgIGNvbnN0IGJhY2t1cEtleVBhaXIgPSBuZXcgS2V5UGFpcih7IHB1YjogZGVyaXZlZENvbW1vbktleUNoYWluLnNsaWNlKDAsIDY2KSB9KTtcbiAgICBjb25zdCBiYXNlQWRkcmVzcyA9IGJhY2t1cEtleVBhaXIuZ2V0QWRkcmVzcygpO1xuXG4gICAgY29uc3QgeyB0eDogdW5zaWduZWRUeCB9ID0gYXdhaXQgdGhpcy5idWlsZFRlbXBvU3dlZXBUeChiYXNlQWRkcmVzcywgcGFyYW1zKTtcbiAgICBjb25zdCBzZXJpYWxpemVkSGV4ID0gYXdhaXQgdW5zaWduZWRUeC5zZXJpYWxpemUoKTtcblxuICAgIC8vIEhhc2ggdGhlIHVuc2lnbmVkIDB4NzYgdHgg4oCUIG1hdGNoZXMgVGlwMjBUcmFuc2FjdGlvbkJ1aWxkZXIncyBvd24gc2lnbmluZyBsb2dpY1xuICAgIGNvbnN0IG1zZ0hhc2hIZXggPSBldGhlcnMudXRpbHMua2VjY2FrMjU2KGV0aGVycy51dGlscy5hcnJheWlmeShzZXJpYWxpemVkSGV4KSk7XG4gICAgY29uc3QgbWVzc2FnZUhhc2ggPSBCdWZmZXIuZnJvbShtc2dIYXNoSGV4LnJlcGxhY2UoJzB4JywgJycpLCAnaGV4Jyk7XG5cbiAgICBjb25zdCBzaWduYXR1cmUgPSBhd2FpdCBFQ0RTQVV0aWxzLnNpZ25SZWNvdmVyeU1wY1YyKG1lc3NhZ2VIYXNoLCB1c2VyS2V5U2hhcmUsIGJhY2t1cEtleVNoYXJlLCBjb21tb25LZXlDaGFpbik7XG5cbiAgICAvLyBFQ0RTQU1ldGhvZFR5cGVzLlNpZ25hdHVyZS5yL3MgYXJlIDY0LWNoYXIgaGV4IFdJVEhPVVQgMHggcHJlZml4XG4gICAgdW5zaWduZWRUeC5zZXRTaWduYXR1cmUoe1xuICAgICAgcjogYDB4JHtzaWduYXR1cmUucn1gLFxuICAgICAgczogYDB4JHtzaWduYXR1cmUuc31gLFxuICAgICAgeVBhcml0eTogc2lnbmF0dXJlLnJlY2lkLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgc2lnbmVkSGV4ID0gYXdhaXQgdW5zaWduZWRUeC5zZXJpYWxpemUoKTtcbiAgICBjb25zdCB0eElkID0gZXRoZXJzLnV0aWxzLmtlY2NhazI1NihldGhlcnMudXRpbHMuYXJyYXlpZnkoc2lnbmVkSGV4KSk7XG4gICAgcmV0dXJuIHsgaWQ6IHR4SWQsIHR4OiBzaWduZWRIZXggfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYW4gdW5zaWduZWQgVElQLTIwIHN3ZWVwIHRyYW5zYWN0aW9uIGZvciB0aGUgb2ZmbGluZSB2YXVsdCAodW5zaWduZWQgc3dlZXAgcGF0aCkuXG4gICAqIENhbGxlZCBieSByZWNvdmVyVFNTIHdoZW4gcGxhaW4gcHVibGljIGtleSBzaGFyZXMgYXJlIHByb3ZpZGVkLlxuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGJ1aWxkVW5zaWduZWRTd2VlcFR4blRTUyhwYXJhbXM6IFJlY292ZXJPcHRpb25zKTogUHJvbWlzZTxPZmZsaW5lVmF1bHRUeEluZm8gfCBVbnNpZ25lZFN3ZWVwVHhNUEN2Mj4ge1xuICAgIGNvbnN0IGJhY2t1cEtleSA9IHBhcmFtcy5iYWNrdXBLZXkucmVwbGFjZSgvXFxzL2csICcnKTtcbiAgICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9IHBhcmFtcy5kZXJpdmF0aW9uU2VlZCA/IGdldERlcml2YXRpb25QYXRoKHBhcmFtcy5kZXJpdmF0aW9uU2VlZCkgOiAnbS8wJztcbiAgICBjb25zdCBNUEMgPSBuZXcgRWNkc2EoKTtcbiAgICBjb25zdCBkZXJpdmVkQ29tbW9uS2V5Q2hhaW4gPSBNUEMuZGVyaXZlVW5oYXJkZW5lZChiYWNrdXBLZXksIGRlcml2YXRpb25QYXRoKTtcbiAgICBjb25zdCBiYWNrdXBLZXlQYWlyID0gbmV3IEtleVBhaXIoeyBwdWI6IGRlcml2ZWRDb21tb25LZXlDaGFpbi5zbGljZSgwLCA2NikgfSk7XG4gICAgY29uc3QgYmFzZUFkZHJlc3MgPSBiYWNrdXBLZXlQYWlyLmdldEFkZHJlc3MoKTtcblxuICAgIGNvbnN0IHsgdHgsIG5vbmNlLCBzd2VlcEFtb3VudCwgZ2FzTWFyZ2luVW5pdHMgfSA9IGF3YWl0IHRoaXMuYnVpbGRUZW1wb1N3ZWVwVHgoYmFzZUFkZHJlc3MsIHBhcmFtcyk7XG4gICAgY29uc3Qgc2VyaWFsaXplZEhleCA9IGF3YWl0IHR4LnNlcmlhbGl6ZSgpO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRUeEhleCA9IHNlcmlhbGl6ZWRIZXgucmVwbGFjZSgnMHgnLCAnJyk7XG4gICAgY29uc3Qgc2lnbmFibGVIZXggPSBldGhlcnMudXRpbHMua2VjY2FrMjU2KGV0aGVycy51dGlscy5hcnJheWlmeShzZXJpYWxpemVkSGV4KSkucmVwbGFjZSgnMHgnLCAnJyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHhSZXF1ZXN0czogW1xuICAgICAgICB7XG4gICAgICAgICAgd2FsbGV0Q29pbjogdGhpcy5nZXRDaGFpbigpLFxuICAgICAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgICAgICAgc2VyaWFsaXplZFR4SGV4LFxuICAgICAgICAgICAgICAgIHNpZ25hYmxlSGV4LFxuICAgICAgICAgICAgICAgIGRlcml2YXRpb25QYXRoLFxuICAgICAgICAgICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICAgICAgICAgIGZlZTogTnVtYmVyKGdhc01hcmdpblVuaXRzKSxcbiAgICAgICAgICAgICAgICAgIGZlZVN0cmluZzogdGlwMjBVbml0c1RvQW1vdW50KGdhc01hcmdpblVuaXRzKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHBhcnNlZFR4OiB7XG4gICAgICAgICAgICAgICAgICBzcGVuZEFtb3VudDogdGlwMjBVbml0c1RvQW1vdW50KHN3ZWVwQW1vdW50KSxcbiAgICAgICAgICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgIGNvaW5OYW1lOiB0aGlzLmdldENoYWluKCksXG4gICAgICAgICAgICAgICAgICAgICAgYWRkcmVzczogcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgICAgICAgICAgICAgICAgdmFsdWVTdHJpbmc6IHRpcDIwVW5pdHNUb0Ftb3VudChzd2VlcEFtb3VudCksXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgY29pblNwZWNpZmljOiB7IGNvbW1vbktleUNoYWluOiBiYWNrdXBLZXkgfSxcbiAgICAgICAgICAgICAgICBlaXAxNTU5OiBwYXJhbXMuZWlwMTU1OSxcbiAgICAgICAgICAgICAgICByZXBsYXlQcm90ZWN0aW9uT3B0aW9uczogcGFyYW1zLnJlcGxheVByb3RlY3Rpb25PcHRpb25zLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBub25jZSxcbiAgICAgICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdHJhbnNhY3Rpb24gYnVpbGRlciBmb3IgVGVtcG8uXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VHJhbnNhY3Rpb25CdWlsZGVyKGNvbW1vbj86IEV0aExpa2VDb21tb24uZGVmYXVsdCk6IFRyYW5zYWN0aW9uQnVpbGRlciB7XG4gICAgcmV0dXJuIG5ldyBUaXAyMFRyYW5zYWN0aW9uQnVpbGRlcihjb2lucy5nZXQodGhpcy5nZXRCYXNlQ2hhaW4oKSkpIGFzIHVua25vd24gYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICB9XG59XG4iXX0=
|