@bitgo-beta/sdk-coin-dot 1.3.3-alpha.473 → 1.3.3-alpha.475
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/dot.d.ts +0 -7
- package/dist/src/dot.d.ts.map +1 -1
- package/dist/src/dot.js +1 -1
- package/dist/src/lib/index.d.ts +2 -0
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +4 -2
- package/dist/src/lib/transaction.d.ts.map +1 -1
- package/dist/src/lib/transaction.js +15 -1
- package/dist/src/lib/wasmParser.d.ts +57 -0
- package/dist/src/lib/wasmParser.d.ts.map +1 -0
- package/dist/src/lib/wasmParser.js +351 -0
- package/dist/test/unit/dot.js +65 -2
- package/dist/test/unit/transactionBuilder/withdrawUnstakedBuilder.js +4 -4
- package/dist/test/unit/wasmBuilderByteComparison.d.ts +17 -0
- package/dist/test/unit/wasmBuilderByteComparison.d.ts.map +1 -0
- package/dist/test/unit/wasmBuilderByteComparison.js +409 -0
- package/dist/test/unit/wasmParserExplanation.d.ts +11 -0
- package/dist/test/unit/wasmParserExplanation.d.ts.map +1 -0
- package/dist/test/unit/wasmParserExplanation.js +188 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -7
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* WASM-based DOT transaction explanation.
|
|
4
|
+
*
|
|
5
|
+
* Built on @bitgo/wasm-dot's parseTransaction(). Derives transaction types,
|
|
6
|
+
* extracts outputs/inputs, and maps to BitGoJS TransactionExplanation format.
|
|
7
|
+
* This is BitGo-specific business logic that lives outside the wasm package.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.explainDotTransaction = explainDotTransaction;
|
|
11
|
+
exports.toJsonFromWasm = toJsonFromWasm;
|
|
12
|
+
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
13
|
+
const wasm_dot_1 = require("@bitgo/wasm-dot");
|
|
14
|
+
const MAX_NESTING_DEPTH = 10;
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// Main exports
|
|
17
|
+
// =============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Explain a DOT transaction using the WASM parser.
|
|
20
|
+
*
|
|
21
|
+
* Parses the transaction via WASM, derives the transaction type and
|
|
22
|
+
* outputs locally, then maps to BitGoJS TransactionExplanation format.
|
|
23
|
+
*/
|
|
24
|
+
function explainDotTransaction(params) {
|
|
25
|
+
const explained = buildExplanation(params);
|
|
26
|
+
const sender = explained.sender || params.senderAddress || '';
|
|
27
|
+
const type = mapTransactionType(explained.typeName);
|
|
28
|
+
const methodName = `${explained.method.pallet}.${explained.method.name}`;
|
|
29
|
+
const outputs = explained.outputs.map((o) => ({
|
|
30
|
+
address: o.address,
|
|
31
|
+
amount: o.amount === 'ALL' ? '0' : o.amount,
|
|
32
|
+
}));
|
|
33
|
+
const inputs = explained.inputs.map((i) => {
|
|
34
|
+
const value = i.value === 'ALL' ? 0 : parseInt(i.value || '0', 10);
|
|
35
|
+
return { address: i.address, value, valueString: i.value };
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
displayOrder: ['outputAmount', 'changeAmount', 'outputs', 'changeOutputs', 'fee', 'type', 'sequenceId', 'id'],
|
|
39
|
+
id: explained.id || '',
|
|
40
|
+
outputs,
|
|
41
|
+
outputAmount: explained.outputAmount,
|
|
42
|
+
changeOutputs: [],
|
|
43
|
+
changeAmount: '0',
|
|
44
|
+
fee: { fee: explained.tip || '0', type: 'tip' },
|
|
45
|
+
type,
|
|
46
|
+
sender,
|
|
47
|
+
nonce: explained.nonce,
|
|
48
|
+
isSigned: explained.isSigned,
|
|
49
|
+
methodName,
|
|
50
|
+
inputs,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Produce a TxData object using WASM parsing instead of the JS txwrapper.
|
|
55
|
+
*
|
|
56
|
+
* This replaces the legacy `toJson()` path for chains where WASM parsing is enabled.
|
|
57
|
+
* The WASM parser decodes the extrinsic bytes (with metadata-aware signed extension handling),
|
|
58
|
+
* and this function maps the result to the TxData interface that consumers expect.
|
|
59
|
+
*/
|
|
60
|
+
function toJsonFromWasm(params) {
|
|
61
|
+
const explained = buildExplanation(params);
|
|
62
|
+
const type = mapTransactionType(explained.typeName);
|
|
63
|
+
const method = explained.method;
|
|
64
|
+
const args = method.args;
|
|
65
|
+
const result = {
|
|
66
|
+
id: explained.id || '',
|
|
67
|
+
sender: explained.sender || params.senderAddress,
|
|
68
|
+
referenceBlock: params.referenceBlock || '',
|
|
69
|
+
blockNumber: params.blockNumber || 0,
|
|
70
|
+
genesisHash: params.material.genesisHash || '',
|
|
71
|
+
nonce: explained.nonce,
|
|
72
|
+
specVersion: params.material.specVersion || 0,
|
|
73
|
+
transactionVersion: params.material.txVersion || 0,
|
|
74
|
+
chainName: params.material.chainName || '',
|
|
75
|
+
tip: Number(explained.tip) || 0,
|
|
76
|
+
eraPeriod: explained.era.type === 'mortal' ? explained.era.period : 0,
|
|
77
|
+
};
|
|
78
|
+
if (type === sdk_core_1.TransactionType.Send) {
|
|
79
|
+
populateSendFields(result, method, args);
|
|
80
|
+
}
|
|
81
|
+
else if (type === sdk_core_1.TransactionType.StakingActivate) {
|
|
82
|
+
populateStakingActivateFields(result, method, args, params.senderAddress);
|
|
83
|
+
}
|
|
84
|
+
else if (type === sdk_core_1.TransactionType.StakingUnlock) {
|
|
85
|
+
result.amount = String(args.value ?? '');
|
|
86
|
+
}
|
|
87
|
+
else if (type === sdk_core_1.TransactionType.StakingWithdraw) {
|
|
88
|
+
result.numSlashingSpans = Number(args.numSlashingSpans ?? 0);
|
|
89
|
+
}
|
|
90
|
+
else if (type === sdk_core_1.TransactionType.StakingClaim) {
|
|
91
|
+
result.validatorStash = String(args.validatorStash ?? '');
|
|
92
|
+
result.claimEra = String(args.era ?? '');
|
|
93
|
+
}
|
|
94
|
+
else if (type === sdk_core_1.TransactionType.AddressInitialization) {
|
|
95
|
+
populateAddressInitFields(result, method, args);
|
|
96
|
+
}
|
|
97
|
+
else if (type === sdk_core_1.TransactionType.Batch) {
|
|
98
|
+
result.batchCalls = mapBatchCalls(args.calls);
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
/** Parse and explain a DOT transaction. Replaces the old wasm-dot explainTransaction. */
|
|
103
|
+
function buildExplanation(params) {
|
|
104
|
+
const tx = wasm_dot_1.DotTransaction.fromHex(params.txHex, params.material);
|
|
105
|
+
const context = {
|
|
106
|
+
material: params.material,
|
|
107
|
+
sender: params.senderAddress,
|
|
108
|
+
referenceBlock: params.referenceBlock,
|
|
109
|
+
blockNumber: params.blockNumber,
|
|
110
|
+
};
|
|
111
|
+
const parsed = (0, wasm_dot_1.parseTransaction)(tx, context);
|
|
112
|
+
const typeName = deriveTransactionType(parsed.method, 0);
|
|
113
|
+
const sender = parsed.sender ?? params.senderAddress;
|
|
114
|
+
// Check for batch patterns that need proxy deposit cost handling
|
|
115
|
+
const batchInfo = detectProxyBatch(parsed.method);
|
|
116
|
+
let outputs;
|
|
117
|
+
let inputs;
|
|
118
|
+
if (batchInfo && sender) {
|
|
119
|
+
const proxyDepositCost = (0, wasm_dot_1.getProxyDepositCost)(params.material.metadata).toString();
|
|
120
|
+
if (batchInfo.type === 'unstake') {
|
|
121
|
+
// Unstaking batch (removeProxy + chill + unbond): proxy deposit refund flows
|
|
122
|
+
// from proxy address back to sender. The unbond amount is NOT in inputs/outputs.
|
|
123
|
+
outputs = [{ address: sender, amount: proxyDepositCost }];
|
|
124
|
+
inputs = [{ address: batchInfo.proxyAddress, value: proxyDepositCost }];
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
// Staking batch (bond + addProxy): bond amount + proxy deposit cost
|
|
128
|
+
const bondOutputs = extractOutputs(parsed.method, 0).filter((o) => o.address === 'STAKING');
|
|
129
|
+
outputs = [...bondOutputs, { address: batchInfo.proxyAddress, amount: proxyDepositCost }];
|
|
130
|
+
inputs = outputs.map((o) => ({ address: sender, value: o.amount }));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
outputs = extractOutputs(parsed.method, 0);
|
|
135
|
+
inputs = sender ? outputs.map((o) => ({ address: sender, value: o.amount })) : [];
|
|
136
|
+
}
|
|
137
|
+
const outputAmount = outputs.reduce((sum, o) => {
|
|
138
|
+
if (o.amount === 'ALL')
|
|
139
|
+
return sum;
|
|
140
|
+
return (BigInt(sum) + BigInt(o.amount)).toString();
|
|
141
|
+
}, '0');
|
|
142
|
+
return {
|
|
143
|
+
typeName,
|
|
144
|
+
id: parsed.id ?? undefined,
|
|
145
|
+
sender: parsed.sender ?? undefined,
|
|
146
|
+
outputs,
|
|
147
|
+
inputs,
|
|
148
|
+
outputAmount,
|
|
149
|
+
tip: parsed.tip,
|
|
150
|
+
era: parsed.era,
|
|
151
|
+
method: parsed.method,
|
|
152
|
+
isSigned: parsed.isSigned,
|
|
153
|
+
nonce: parsed.nonce,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
// =============================================================================
|
|
157
|
+
// Transaction type derivation (moved from @bitgo/wasm-dot)
|
|
158
|
+
// =============================================================================
|
|
159
|
+
function deriveTransactionType(method, depth) {
|
|
160
|
+
const key = `${method.pallet}.${method.name}`;
|
|
161
|
+
const args = (method.args ?? {});
|
|
162
|
+
switch (key) {
|
|
163
|
+
case 'balances.transfer':
|
|
164
|
+
case 'balances.transferKeepAlive':
|
|
165
|
+
case 'balances.transferAllowDeath':
|
|
166
|
+
case 'balances.transferAll':
|
|
167
|
+
return 'Send';
|
|
168
|
+
case 'staking.bond':
|
|
169
|
+
case 'staking.bondExtra':
|
|
170
|
+
return 'StakingActivate';
|
|
171
|
+
case 'staking.unbond':
|
|
172
|
+
return 'StakingUnlock';
|
|
173
|
+
case 'staking.withdrawUnbonded':
|
|
174
|
+
return 'StakingWithdraw';
|
|
175
|
+
case 'staking.chill':
|
|
176
|
+
return 'StakingUnvote';
|
|
177
|
+
case 'staking.payoutStakers':
|
|
178
|
+
return 'StakingClaim';
|
|
179
|
+
case 'proxy.addProxy':
|
|
180
|
+
case 'proxy.removeProxy':
|
|
181
|
+
case 'proxy.createPure':
|
|
182
|
+
return 'AddressInitialization';
|
|
183
|
+
case 'utility.batch':
|
|
184
|
+
case 'utility.batchAll':
|
|
185
|
+
return 'Batch';
|
|
186
|
+
case 'proxy.proxy': {
|
|
187
|
+
if (depth >= MAX_NESTING_DEPTH)
|
|
188
|
+
return 'Unknown';
|
|
189
|
+
const call = args.call;
|
|
190
|
+
if (call?.pallet && call?.name)
|
|
191
|
+
return deriveTransactionType(call, depth + 1);
|
|
192
|
+
return 'Unknown';
|
|
193
|
+
}
|
|
194
|
+
default:
|
|
195
|
+
return 'Unknown';
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// =============================================================================
|
|
199
|
+
// Output extraction (moved from @bitgo/wasm-dot)
|
|
200
|
+
// =============================================================================
|
|
201
|
+
function extractOutputs(method, depth) {
|
|
202
|
+
const args = (method.args ?? {});
|
|
203
|
+
const key = `${method.pallet}.${method.name}`;
|
|
204
|
+
switch (key) {
|
|
205
|
+
case 'balances.transfer':
|
|
206
|
+
case 'balances.transferKeepAlive':
|
|
207
|
+
case 'balances.transferAllowDeath':
|
|
208
|
+
return [{ address: String(args.dest ?? ''), amount: String(args.value ?? '0') }];
|
|
209
|
+
case 'balances.transferAll':
|
|
210
|
+
return [{ address: String(args.dest ?? ''), amount: 'ALL' }];
|
|
211
|
+
case 'staking.bond':
|
|
212
|
+
case 'staking.bondExtra':
|
|
213
|
+
case 'staking.unbond':
|
|
214
|
+
return [{ address: 'STAKING', amount: String(args.value ?? '0') }];
|
|
215
|
+
case 'utility.batch':
|
|
216
|
+
case 'utility.batchAll': {
|
|
217
|
+
if (depth >= MAX_NESTING_DEPTH)
|
|
218
|
+
return [];
|
|
219
|
+
const calls = (args.calls ?? []);
|
|
220
|
+
return calls.filter((c) => c?.pallet && c?.name).flatMap((c) => extractOutputs(c, depth + 1));
|
|
221
|
+
}
|
|
222
|
+
case 'proxy.proxy': {
|
|
223
|
+
if (depth >= MAX_NESTING_DEPTH)
|
|
224
|
+
return [];
|
|
225
|
+
const call = args.call;
|
|
226
|
+
return call?.pallet && call?.name ? extractOutputs(call, depth + 1) : [];
|
|
227
|
+
}
|
|
228
|
+
default:
|
|
229
|
+
return [];
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Detect batch transactions involving proxy operations (stake/unstake batches).
|
|
234
|
+
*
|
|
235
|
+
* Legacy account-lib reports proxy deposit cost (ProxyDepositBase + ProxyDepositFactor)
|
|
236
|
+
* as the value for these batches instead of the bond/unbond amount.
|
|
237
|
+
*
|
|
238
|
+
* Unstaking batch: removeProxy + chill + unbond
|
|
239
|
+
* Staking batch: bond + addProxy
|
|
240
|
+
*/
|
|
241
|
+
function detectProxyBatch(method) {
|
|
242
|
+
const key = `${method.pallet}.${method.name}`;
|
|
243
|
+
if (key !== 'utility.batch' && key !== 'utility.batchAll')
|
|
244
|
+
return undefined;
|
|
245
|
+
const calls = (method.args ?? {}).calls;
|
|
246
|
+
if (!calls || calls.length === 0)
|
|
247
|
+
return undefined;
|
|
248
|
+
const callKeys = calls.map((c) => `${c.pallet}.${c.name}`);
|
|
249
|
+
// Unstaking batch: removeProxy + chill + unbond (3 calls)
|
|
250
|
+
if (calls.length === 3 &&
|
|
251
|
+
callKeys[0] === 'proxy.removeProxy' &&
|
|
252
|
+
callKeys[1] === 'staking.chill' &&
|
|
253
|
+
callKeys[2] === 'staking.unbond') {
|
|
254
|
+
const removeProxyArgs = (calls[0].args ?? {});
|
|
255
|
+
const proxyAddress = String(removeProxyArgs.delegate ?? '');
|
|
256
|
+
return { type: 'unstake', proxyAddress };
|
|
257
|
+
}
|
|
258
|
+
// Staking batch: bond + addProxy (2 calls)
|
|
259
|
+
if (calls.length === 2 && callKeys[0] === 'staking.bond' && callKeys[1] === 'proxy.addProxy') {
|
|
260
|
+
const addProxyArgs = (calls[1].args ?? {});
|
|
261
|
+
const proxyAddress = String(addProxyArgs.delegate ?? '');
|
|
262
|
+
return { type: 'stake', proxyAddress };
|
|
263
|
+
}
|
|
264
|
+
return undefined;
|
|
265
|
+
}
|
|
266
|
+
// =============================================================================
|
|
267
|
+
// Helpers
|
|
268
|
+
// =============================================================================
|
|
269
|
+
/** Map type name string to sdk-core TransactionType via name lookup */
|
|
270
|
+
function mapTransactionType(typeName) {
|
|
271
|
+
return sdk_core_1.TransactionType[typeName] ?? sdk_core_1.TransactionType.Send;
|
|
272
|
+
}
|
|
273
|
+
function populateSendFields(result, method, args) {
|
|
274
|
+
const key = `${method.pallet}.${method.name}`;
|
|
275
|
+
if (key === 'proxy.proxy') {
|
|
276
|
+
// Proxy-wrapped transfer
|
|
277
|
+
const innerCall = args.call;
|
|
278
|
+
result.owner = String(args.real ?? '');
|
|
279
|
+
result.forceProxyType = args.forceProxyType ?? undefined;
|
|
280
|
+
if (innerCall?.args) {
|
|
281
|
+
const innerArgs = innerCall.args;
|
|
282
|
+
result.to = String(innerArgs.dest ?? '');
|
|
283
|
+
result.amount = String(innerArgs.value ?? '');
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
else if (key === 'balances.transferAll') {
|
|
287
|
+
result.to = String(args.dest ?? '');
|
|
288
|
+
result.keepAlive = Boolean(args.keepAlive);
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
// transfer, transferKeepAlive, transferAllowDeath
|
|
292
|
+
result.to = String(args.dest ?? '');
|
|
293
|
+
result.amount = String(args.value ?? '');
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
function populateStakingActivateFields(result, method, args, senderAddress) {
|
|
297
|
+
if (method.name === 'bondExtra') {
|
|
298
|
+
result.amount = String(args.value ?? '');
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
// bond
|
|
302
|
+
result.controller = senderAddress;
|
|
303
|
+
result.amount = String(args.value ?? '');
|
|
304
|
+
result.payee = String(args.payee ?? '');
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
function populateAddressInitFields(result, method, args) {
|
|
308
|
+
const key = `${method.pallet}.${method.name}`;
|
|
309
|
+
result.method = key;
|
|
310
|
+
result.proxyType = String(args.proxy_type ?? '');
|
|
311
|
+
result.delay = String(args.delay ?? '');
|
|
312
|
+
if (key === 'proxy.createPure') {
|
|
313
|
+
result.index = String(args.index ?? '');
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
// addProxy, removeProxy
|
|
317
|
+
result.owner = String(args.delegate ?? '');
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
function mapBatchCalls(calls) {
|
|
321
|
+
if (!calls)
|
|
322
|
+
return [];
|
|
323
|
+
return calls.map((call) => ({
|
|
324
|
+
callIndex: `0x${call.palletIndex.toString(16).padStart(2, '0')}${call.methodIndex.toString(16).padStart(2, '0')}`,
|
|
325
|
+
args: transformBatchCallArgs((call.args ?? {})),
|
|
326
|
+
}));
|
|
327
|
+
}
|
|
328
|
+
/** Transform WASM-decoded batch call args to match the Polkadot.js format that consumers expect */
|
|
329
|
+
function transformBatchCallArgs(args) {
|
|
330
|
+
const result = {};
|
|
331
|
+
for (const [key, value] of Object.entries(args)) {
|
|
332
|
+
if (key === 'delegate' && typeof value === 'string') {
|
|
333
|
+
// MultiAddress Id variant: string → { id: string }
|
|
334
|
+
result[key] = { id: value };
|
|
335
|
+
}
|
|
336
|
+
else if (key === 'value' && typeof value === 'string') {
|
|
337
|
+
// Compact u128: string → number (matches Polkadot.js behavior)
|
|
338
|
+
result[key] = Number(value);
|
|
339
|
+
}
|
|
340
|
+
else if (key === 'payee' && typeof value === 'string') {
|
|
341
|
+
// Enum unit variant: "Staked" → { staked: null }
|
|
342
|
+
const variantName = value.charAt(0).toLowerCase() + value.slice(1);
|
|
343
|
+
result[key] = { [variantName]: null };
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
result[key] = value;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return result;
|
|
350
|
+
}
|
|
351
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FzbVBhcnNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvd2FzbVBhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7OztHQU1HOztBQTJESCxzREFnQ0M7QUFTRCx3Q0FzQ0M7QUF4SUQsbURBQXVEO0FBQ3ZELDhDQUFxSDtBQUdySCxNQUFNLGlCQUFpQixHQUFHLEVBQUUsQ0FBQztBQTJDN0IsZ0ZBQWdGO0FBQ2hGLGVBQWU7QUFDZixnRkFBZ0Y7QUFFaEY7Ozs7O0dBS0c7QUFDSCxTQUFnQixxQkFBcUIsQ0FBQyxNQUFtQztJQUN2RSxNQUFNLFNBQVMsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUUzQyxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxhQUFhLElBQUksRUFBRSxDQUFDO0lBQzlELE1BQU0sSUFBSSxHQUFHLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNwRCxNQUFNLFVBQVUsR0FBRyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxJQUFJLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7SUFFekUsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDNUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxPQUFPO1FBQ2xCLE1BQU0sRUFBRSxDQUFDLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTTtLQUM1QyxDQUFDLENBQUMsQ0FBQztJQUVKLE1BQU0sTUFBTSxHQUFlLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7UUFDcEQsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDLEtBQUssS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ25FLE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUM3RCxDQUFDLENBQUMsQ0FBQztJQUVILE9BQU87UUFDTCxZQUFZLEVBQUUsQ0FBQyxjQUFjLEVBQUUsY0FBYyxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsSUFBSSxDQUFDO1FBQzdHLEVBQUUsRUFBRSxTQUFTLENBQUMsRUFBRSxJQUFJLEVBQUU7UUFDdEIsT0FBTztRQUNQLFlBQVksRUFBRSxTQUFTLENBQUMsWUFBWTtRQUNwQyxhQUFhLEVBQUUsRUFBRTtRQUNqQixZQUFZLEVBQUUsR0FBRztRQUNqQixHQUFHLEVBQUUsRUFBRSxHQUFHLEVBQUUsU0FBUyxDQUFDLEdBQUcsSUFBSSxHQUFHLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRTtRQUMvQyxJQUFJO1FBQ0osTUFBTTtRQUNOLEtBQUssRUFBRSxTQUFTLENBQUMsS0FBSztRQUN0QixRQUFRLEVBQUUsU0FBUyxDQUFDLFFBQVE7UUFDNUIsVUFBVTtRQUNWLE1BQU07S0FDUCxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQWdCLGNBQWMsQ0FBQyxNQUE0QjtJQUN6RCxNQUFNLFNBQVMsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMzQyxNQUFNLElBQUksR0FBRyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDcEQsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQztJQUNoQyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBK0IsQ0FBQztJQUVwRCxNQUFNLE1BQU0sR0FBVztRQUNyQixFQUFFLEVBQUUsU0FBUyxDQUFDLEVBQUUsSUFBSSxFQUFFO1FBQ3RCLE1BQU0sRUFBRSxTQUFTLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxhQUFhO1FBQ2hELGNBQWMsRUFBRSxNQUFNLENBQUMsY0FBYyxJQUFJLEVBQUU7UUFDM0MsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXLElBQUksQ0FBQztRQUNwQyxXQUFXLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxXQUFXLElBQUksRUFBRTtRQUM5QyxLQUFLLEVBQUUsU0FBUyxDQUFDLEtBQUs7UUFDdEIsV0FBVyxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsV0FBVyxJQUFJLENBQUM7UUFDN0Msa0JBQWtCLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxTQUFTLElBQUksQ0FBQztRQUNsRCxTQUFTLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxTQUFTLElBQUksRUFBRTtRQUMxQyxHQUFHLEVBQUUsTUFBTSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDO1FBQy9CLFNBQVMsRUFBRSxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFFLFNBQVMsQ0FBQyxHQUEwQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUM5RixDQUFDO0lBRUYsSUFBSSxJQUFJLEtBQUssMEJBQWUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNsQyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzNDLENBQUM7U0FBTSxJQUFJLElBQUksS0FBSywwQkFBZSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3BELDZCQUE2QixDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUM1RSxDQUFDO1NBQU0sSUFBSSxJQUFJLEtBQUssMEJBQWUsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNsRCxNQUFNLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzNDLENBQUM7U0FBTSxJQUFJLElBQUksS0FBSywwQkFBZSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3BELE1BQU0sQ0FBQyxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQy9ELENBQUM7U0FBTSxJQUFJLElBQUksS0FBSywwQkFBZSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ2pELE1BQU0sQ0FBQyxjQUFjLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxjQUFjLElBQUksRUFBRSxDQUFDLENBQUM7UUFDMUQsTUFBTSxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUMzQyxDQUFDO1NBQU0sSUFBSSxJQUFJLEtBQUssMEJBQWUsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQzFELHlCQUF5QixDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDbEQsQ0FBQztTQUFNLElBQUksSUFBSSxLQUFLLDBCQUFlLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDMUMsTUFBTSxDQUFDLFVBQVUsR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQXVCLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRUQsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQW9CRCx5RkFBeUY7QUFDekYsU0FBUyxnQkFBZ0IsQ0FBQyxNQU16QjtJQUNDLE1BQU0sRUFBRSxHQUFHLHlCQUFjLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2pFLE1BQU0sT0FBTyxHQUFHO1FBQ2QsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRO1FBQ3pCLE1BQU0sRUFBRSxNQUFNLENBQUMsYUFBYTtRQUM1QixjQUFjLEVBQUUsTUFBTSxDQUFDLGNBQWM7UUFDckMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXO0tBQ2hDLENBQUM7SUFDRixNQUFNLE1BQU0sR0FBRyxJQUFBLDJCQUFnQixFQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUU3QyxNQUFNLFFBQVEsR0FBRyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3pELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLGFBQWEsQ0FBQztJQUVyRCxpRUFBaUU7SUFDakUsTUFBTSxTQUFTLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2xELElBQUksT0FBOEMsQ0FBQztJQUNuRCxJQUFJLE1BQTRDLENBQUM7SUFFakQsSUFBSSxTQUFTLElBQUksTUFBTSxFQUFFLENBQUM7UUFDeEIsTUFBTSxnQkFBZ0IsR0FBRyxJQUFBLDhCQUFtQixFQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDbEYsSUFBSSxTQUFTLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ2pDLDZFQUE2RTtZQUM3RSxpRkFBaUY7WUFDakYsT0FBTyxHQUFHLENBQUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7WUFDMUQsTUFBTSxHQUFHLENBQUMsRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFDLFlBQVksRUFBRSxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO1FBQzFFLENBQUM7YUFBTSxDQUFDO1lBQ04sb0VBQW9FO1lBQ3BFLE1BQU0sV0FBVyxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxTQUFTLENBQUMsQ0FBQztZQUM1RixPQUFPLEdBQUcsQ0FBQyxHQUFHLFdBQVcsRUFBRSxFQUFFLE9BQU8sRUFBRSxTQUFTLENBQUMsWUFBWSxFQUFFLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7WUFDMUYsTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3RFLENBQUM7SUFDSCxDQUFDO1NBQU0sQ0FBQztRQUNOLE9BQU8sR0FBRyxjQUFjLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMzQyxNQUFNLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ3BGLENBQUM7SUFFRCxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQzdDLElBQUksQ0FBQyxDQUFDLE1BQU0sS0FBSyxLQUFLO1lBQUUsT0FBTyxHQUFHLENBQUM7UUFDbkMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDckQsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBRVIsT0FBTztRQUNMLFFBQVE7UUFDUixFQUFFLEVBQUUsTUFBTSxDQUFDLEVBQUUsSUFBSSxTQUFTO1FBQzFCLE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTSxJQUFJLFNBQVM7UUFDbEMsT0FBTztRQUNQLE1BQU07UUFDTixZQUFZO1FBQ1osR0FBRyxFQUFFLE1BQU0sQ0FBQyxHQUFHO1FBQ2YsR0FBRyxFQUFFLE1BQU0sQ0FBQyxHQUFHO1FBQ2YsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNO1FBQ3JCLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtRQUN6QixLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUs7S0FDcEIsQ0FBQztBQUNKLENBQUM7QUFFRCxnRkFBZ0Y7QUFDaEYsMkRBQTJEO0FBQzNELGdGQUFnRjtBQUVoRixTQUFTLHFCQUFxQixDQUFDLE1BQW9CLEVBQUUsS0FBYTtJQUNoRSxNQUFNLEdBQUcsR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzlDLE1BQU0sSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxFQUFFLENBQTRCLENBQUM7SUFDNUQsUUFBUSxHQUFHLEVBQUUsQ0FBQztRQUNaLEtBQUssbUJBQW1CLENBQUM7UUFDekIsS0FBSyw0QkFBNEIsQ0FBQztRQUNsQyxLQUFLLDZCQUE2QixDQUFDO1FBQ25DLEtBQUssc0JBQXNCO1lBQ3pCLE9BQU8sTUFBTSxDQUFDO1FBRWhCLEtBQUssY0FBYyxDQUFDO1FBQ3BCLEtBQUssbUJBQW1CO1lBQ3RCLE9BQU8saUJBQWlCLENBQUM7UUFFM0IsS0FBSyxnQkFBZ0I7WUFDbkIsT0FBTyxlQUFlLENBQUM7UUFFekIsS0FBSywwQkFBMEI7WUFDN0IsT0FBTyxpQkFBaUIsQ0FBQztRQUUzQixLQUFLLGVBQWU7WUFDbEIsT0FBTyxlQUFlLENBQUM7UUFFekIsS0FBSyx1QkFBdUI7WUFDMUIsT0FBTyxjQUFjLENBQUM7UUFFeEIsS0FBSyxnQkFBZ0IsQ0FBQztRQUN0QixLQUFLLG1CQUFtQixDQUFDO1FBQ3pCLEtBQUssa0JBQWtCO1lBQ3JCLE9BQU8sdUJBQXVCLENBQUM7UUFFakMsS0FBSyxlQUFlLENBQUM7UUFDckIsS0FBSyxrQkFBa0I7WUFDckIsT0FBTyxPQUFPLENBQUM7UUFFakIsS0FBSyxhQUFhLENBQUMsQ0FBQyxDQUFDO1lBQ25CLElBQUksS0FBSyxJQUFJLGlCQUFpQjtnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUNqRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBZ0MsQ0FBQztZQUNuRCxJQUFJLElBQUksRUFBRSxNQUFNLElBQUksSUFBSSxFQUFFLElBQUk7Z0JBQUUsT0FBTyxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzlFLE9BQU8sU0FBUyxDQUFDO1FBQ25CLENBQUM7UUFFRDtZQUNFLE9BQU8sU0FBUyxDQUFDO0lBQ3JCLENBQUM7QUFDSCxDQUFDO0FBRUQsZ0ZBQWdGO0FBQ2hGLGlEQUFpRDtBQUNqRCxnRkFBZ0Y7QUFFaEYsU0FBUyxjQUFjLENBQUMsTUFBb0IsRUFBRSxLQUFhO0lBQ3pELE1BQU0sSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxFQUFFLENBQTRCLENBQUM7SUFDNUQsTUFBTSxHQUFHLEdBQUcsR0FBRyxNQUFNLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUU5QyxRQUFRLEdBQUcsRUFBRSxDQUFDO1FBQ1osS0FBSyxtQkFBbUIsQ0FBQztRQUN6QixLQUFLLDRCQUE0QixDQUFDO1FBQ2xDLEtBQUssNkJBQTZCO1lBQ2hDLE9BQU8sQ0FBQyxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRW5GLEtBQUssc0JBQXNCO1lBQ3pCLE9BQU8sQ0FBQyxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUUvRCxLQUFLLGNBQWMsQ0FBQztRQUNwQixLQUFLLG1CQUFtQixDQUFDO1FBQ3pCLEtBQUssZ0JBQWdCO1lBQ25CLE9BQU8sQ0FBQyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUVyRSxLQUFLLGVBQWUsQ0FBQztRQUNyQixLQUFLLGtCQUFrQixDQUFDLENBQUMsQ0FBQztZQUN4QixJQUFJLEtBQUssSUFBSSxpQkFBaUI7Z0JBQUUsT0FBTyxFQUFFLENBQUM7WUFDMUMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBbUIsQ0FBQztZQUNuRCxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsY0FBYyxDQUFDLENBQUMsRUFBRSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoRyxDQUFDO1FBRUQsS0FBSyxhQUFhLENBQUMsQ0FBQyxDQUFDO1lBQ25CLElBQUksS0FBSyxJQUFJLGlCQUFpQjtnQkFBRSxPQUFPLEVBQUUsQ0FBQztZQUMxQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBZ0MsQ0FBQztZQUNuRCxPQUFPLElBQUksRUFBRSxNQUFNLElBQUksSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUMzRSxDQUFDO1FBRUQ7WUFDRSxPQUFPLEVBQUUsQ0FBQztJQUNkLENBQUM7QUFDSCxDQUFDO0FBV0Q7Ozs7Ozs7O0dBUUc7QUFDSCxTQUFTLGdCQUFnQixDQUFDLE1BQW9CO0lBQzVDLE1BQU0sR0FBRyxHQUFHLEdBQUcsTUFBTSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDOUMsSUFBSSxHQUFHLEtBQUssZUFBZSxJQUFJLEdBQUcsS0FBSyxrQkFBa0I7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUU1RSxNQUFNLEtBQUssR0FBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksRUFBRSxDQUE2QixDQUFDLEtBQW1DLENBQUM7SUFDbkcsSUFBSSxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUVuRCxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFFM0QsMERBQTBEO0lBQzFELElBQ0UsS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQ2xCLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxtQkFBbUI7UUFDbkMsUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLGVBQWU7UUFDL0IsUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLGdCQUFnQixFQUNoQyxDQUFDO1FBQ0QsTUFBTSxlQUFlLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBNEIsQ0FBQztRQUN6RSxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUM1RCxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsQ0FBQztJQUMzQyxDQUFDO0lBRUQsMkNBQTJDO0lBQzNDLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLGNBQWMsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssZ0JBQWdCLEVBQUUsQ0FBQztRQUM3RixNQUFNLFlBQVksR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUE0QixDQUFDO1FBQ3RFLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsUUFBUSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3pELE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxDQUFDO0lBQ3pDLENBQUM7SUFFRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDO0FBRUQsZ0ZBQWdGO0FBQ2hGLFVBQVU7QUFDVixnRkFBZ0Y7QUFFaEYsdUVBQXVFO0FBQ3ZFLFNBQVMsa0JBQWtCLENBQUMsUUFBZ0I7SUFDMUMsT0FBTywwQkFBZSxDQUFDLFFBQXdDLENBQUMsSUFBSSwwQkFBZSxDQUFDLElBQUksQ0FBQztBQUMzRixDQUFDO0FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxNQUFjLEVBQUUsTUFBb0IsRUFBRSxJQUE2QjtJQUM3RixNQUFNLEdBQUcsR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO0lBRTlDLElBQUksR0FBRyxLQUFLLGFBQWEsRUFBRSxDQUFDO1FBQzFCLHlCQUF5QjtRQUN6QixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsSUFBZ0MsQ0FBQztRQUN4RCxNQUFNLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sQ0FBQyxjQUFjLEdBQUksSUFBSSxDQUFDLGNBQTRCLElBQUksU0FBUyxDQUFDO1FBQ3hFLElBQUksU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDO1lBQ3BCLE1BQU0sU0FBUyxHQUFHLFNBQVMsQ0FBQyxJQUErQixDQUFDO1lBQzVELE1BQU0sQ0FBQyxFQUFFLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUM7WUFDekMsTUFBTSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNoRCxDQUFDO0lBQ0gsQ0FBQztTQUFNLElBQUksR0FBRyxLQUFLLHNCQUFzQixFQUFFLENBQUM7UUFDMUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNwQyxNQUFNLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0MsQ0FBQztTQUFNLENBQUM7UUFDTixrREFBa0Q7UUFDbEQsTUFBTSxDQUFDLEVBQUUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNwQyxNQUFNLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzNDLENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyw2QkFBNkIsQ0FDcEMsTUFBYyxFQUNkLE1BQW9CLEVBQ3BCLElBQTZCLEVBQzdCLGFBQXFCO0lBRXJCLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxXQUFXLEVBQUUsQ0FBQztRQUNoQyxNQUFNLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzNDLENBQUM7U0FBTSxDQUFDO1FBQ04sT0FBTztRQUNQLE1BQU0sQ0FBQyxVQUFVLEdBQUcsYUFBYSxDQUFDO1FBQ2xDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLENBQUM7UUFDekMsTUFBTSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsQ0FBQztJQUMxQyxDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQVMseUJBQXlCLENBQUMsTUFBYyxFQUFFLE1BQW9CLEVBQUUsSUFBNkI7SUFDcEcsTUFBTSxHQUFHLEdBQUcsR0FBRyxNQUFNLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUM5QyxNQUFNLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQztJQUNwQixNQUFNLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ2pELE1BQU0sQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLENBQUM7SUFFeEMsSUFBSSxHQUFHLEtBQUssa0JBQWtCLEVBQUUsQ0FBQztRQUMvQixNQUFNLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzFDLENBQUM7U0FBTSxDQUFDO1FBQ04sd0JBQXdCO1FBQ3hCLE1BQU0sQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDLENBQUM7SUFDN0MsQ0FBQztBQUNILENBQUM7QUFFRCxTQUFTLGFBQWEsQ0FBQyxLQUFpQztJQUN0RCxJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ3RCLE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztRQUMxQixTQUFTLEVBQUUsS0FBSyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUU7UUFDakgsSUFBSSxFQUFFLHNCQUFzQixDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFLENBQTRCLENBQUM7S0FDM0UsQ0FBQyxDQUFDLENBQUM7QUFDTixDQUFDO0FBRUQsbUdBQW1HO0FBQ25HLFNBQVMsc0JBQXNCLENBQUMsSUFBNkI7SUFDM0QsTUFBTSxNQUFNLEdBQTRCLEVBQUUsQ0FBQztJQUMzQyxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ2hELElBQUksR0FBRyxLQUFLLFVBQVUsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUNwRCxtREFBbUQ7WUFDbkQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDO1FBQzlCLENBQUM7YUFBTSxJQUFJLEdBQUcsS0FBSyxPQUFPLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDeEQsK0RBQStEO1lBQy9ELE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDOUIsQ0FBQzthQUFNLElBQUksR0FBRyxLQUFLLE9BQU8sSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUN4RCxpREFBaUQ7WUFDakQsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ25FLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsV0FBVyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDeEMsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogV0FTTS1iYXNlZCBET1QgdHJhbnNhY3Rpb24gZXhwbGFuYXRpb24uXG4gKlxuICogQnVpbHQgb24gQGJpdGdvL3dhc20tZG90J3MgcGFyc2VUcmFuc2FjdGlvbigpLiBEZXJpdmVzIHRyYW5zYWN0aW9uIHR5cGVzLFxuICogZXh0cmFjdHMgb3V0cHV0cy9pbnB1dHMsIGFuZCBtYXBzIHRvIEJpdEdvSlMgVHJhbnNhY3Rpb25FeHBsYW5hdGlvbiBmb3JtYXQuXG4gKiBUaGlzIGlzIEJpdEdvLXNwZWNpZmljIGJ1c2luZXNzIGxvZ2ljIHRoYXQgbGl2ZXMgb3V0c2lkZSB0aGUgd2FzbSBwYWNrYWdlLlxuICovXG5cbmltcG9ydCB7IFRyYW5zYWN0aW9uVHlwZSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IERvdFRyYW5zYWN0aW9uLCBwYXJzZVRyYW5zYWN0aW9uLCBnZXRQcm94eURlcG9zaXRDb3N0LCB0eXBlIFBhcnNlZE1ldGhvZCwgdHlwZSBFcmEgfSBmcm9tICdAYml0Z28vd2FzbS1kb3QnO1xuaW1wb3J0IHR5cGUgeyBCYXRjaENhbGxPYmplY3QsIFByb3h5VHlwZSwgVHJhbnNhY3Rpb25FeHBsYW5hdGlvbiwgTWF0ZXJpYWwsIFR4RGF0YSB9IGZyb20gJy4vaWZhY2UnO1xuXG5jb25zdCBNQVhfTkVTVElOR19ERVBUSCA9IDEwO1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gUHVibGljIHR5cGVzXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIElucHV0IGVudHJ5IGZvciBhIERPVCB0cmFuc2FjdGlvbi5cbiAqIEZvciBhY2NvdW50LW1vZGVsIGNoYWlucywgdGhlcmUncyB0eXBpY2FsbHkgb25lIGlucHV0ICh0aGUgc2VuZGVyKS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEb3RJbnB1dCB7XG4gIGFkZHJlc3M6IHN0cmluZztcbiAgdmFsdWU6IG51bWJlcjtcbiAgdmFsdWVTdHJpbmc6IHN0cmluZztcbn1cblxuLyoqXG4gKiBFeHRlbmRlZCBleHBsYW5hdGlvbiByZXR1cm5lZCBieSBXQVNNLWJhc2VkIHBhcnNpbmcuXG4gKiBJbmNsdWRlcyBmaWVsZHMgbmVlZGVkIGJ5IHdhbGxldC1wbGF0Zm9ybSB0aGF0IGFyZW4ndCBpbiB0aGUgYmFzZSBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERvdFdhc21FeHBsYW5hdGlvbiBleHRlbmRzIFRyYW5zYWN0aW9uRXhwbGFuYXRpb24ge1xuICBzZW5kZXI6IHN0cmluZztcbiAgbm9uY2U6IG51bWJlcjtcbiAgaXNTaWduZWQ6IGJvb2xlYW47XG4gIG1ldGhvZE5hbWU6IHN0cmluZztcbiAgaW5wdXRzOiBEb3RJbnB1dFtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV4cGxhaW5Eb3RUcmFuc2FjdGlvblBhcmFtcyB7XG4gIHR4SGV4OiBzdHJpbmc7XG4gIG1hdGVyaWFsOiBNYXRlcmlhbDtcbiAgc2VuZGVyQWRkcmVzcz86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUb0pzb25Gcm9tV2FzbVBhcmFtcyB7XG4gIHR4SGV4OiBzdHJpbmc7XG4gIG1hdGVyaWFsOiBNYXRlcmlhbDtcbiAgc2VuZGVyQWRkcmVzczogc3RyaW5nO1xuICBjb2luQ29uZmlnTmFtZTogc3RyaW5nO1xuICByZWZlcmVuY2VCbG9jaz86IHN0cmluZztcbiAgYmxvY2tOdW1iZXI/OiBudW1iZXI7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBNYWluIGV4cG9ydHNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogRXhwbGFpbiBhIERPVCB0cmFuc2FjdGlvbiB1c2luZyB0aGUgV0FTTSBwYXJzZXIuXG4gKlxuICogUGFyc2VzIHRoZSB0cmFuc2FjdGlvbiB2aWEgV0FTTSwgZGVyaXZlcyB0aGUgdHJhbnNhY3Rpb24gdHlwZSBhbmRcbiAqIG91dHB1dHMgbG9jYWxseSwgdGhlbiBtYXBzIHRvIEJpdEdvSlMgVHJhbnNhY3Rpb25FeHBsYW5hdGlvbiBmb3JtYXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHBsYWluRG90VHJhbnNhY3Rpb24ocGFyYW1zOiBFeHBsYWluRG90VHJhbnNhY3Rpb25QYXJhbXMpOiBEb3RXYXNtRXhwbGFuYXRpb24ge1xuICBjb25zdCBleHBsYWluZWQgPSBidWlsZEV4cGxhbmF0aW9uKHBhcmFtcyk7XG5cbiAgY29uc3Qgc2VuZGVyID0gZXhwbGFpbmVkLnNlbmRlciB8fCBwYXJhbXMuc2VuZGVyQWRkcmVzcyB8fCAnJztcbiAgY29uc3QgdHlwZSA9IG1hcFRyYW5zYWN0aW9uVHlwZShleHBsYWluZWQudHlwZU5hbWUpO1xuICBjb25zdCBtZXRob2ROYW1lID0gYCR7ZXhwbGFpbmVkLm1ldGhvZC5wYWxsZXR9LiR7ZXhwbGFpbmVkLm1ldGhvZC5uYW1lfWA7XG5cbiAgY29uc3Qgb3V0cHV0cyA9IGV4cGxhaW5lZC5vdXRwdXRzLm1hcCgobykgPT4gKHtcbiAgICBhZGRyZXNzOiBvLmFkZHJlc3MsXG4gICAgYW1vdW50OiBvLmFtb3VudCA9PT0gJ0FMTCcgPyAnMCcgOiBvLmFtb3VudCxcbiAgfSkpO1xuXG4gIGNvbnN0IGlucHV0czogRG90SW5wdXRbXSA9IGV4cGxhaW5lZC5pbnB1dHMubWFwKChpKSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBpLnZhbHVlID09PSAnQUxMJyA/IDAgOiBwYXJzZUludChpLnZhbHVlIHx8ICcwJywgMTApO1xuICAgIHJldHVybiB7IGFkZHJlc3M6IGkuYWRkcmVzcywgdmFsdWUsIHZhbHVlU3RyaW5nOiBpLnZhbHVlIH07XG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgZGlzcGxheU9yZGVyOiBbJ291dHB1dEFtb3VudCcsICdjaGFuZ2VBbW91bnQnLCAnb3V0cHV0cycsICdjaGFuZ2VPdXRwdXRzJywgJ2ZlZScsICd0eXBlJywgJ3NlcXVlbmNlSWQnLCAnaWQnXSxcbiAgICBpZDogZXhwbGFpbmVkLmlkIHx8ICcnLFxuICAgIG91dHB1dHMsXG4gICAgb3V0cHV0QW1vdW50OiBleHBsYWluZWQub3V0cHV0QW1vdW50LFxuICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgIGZlZTogeyBmZWU6IGV4cGxhaW5lZC50aXAgfHwgJzAnLCB0eXBlOiAndGlwJyB9LFxuICAgIHR5cGUsXG4gICAgc2VuZGVyLFxuICAgIG5vbmNlOiBleHBsYWluZWQubm9uY2UsXG4gICAgaXNTaWduZWQ6IGV4cGxhaW5lZC5pc1NpZ25lZCxcbiAgICBtZXRob2ROYW1lLFxuICAgIGlucHV0cyxcbiAgfTtcbn1cblxuLyoqXG4gKiBQcm9kdWNlIGEgVHhEYXRhIG9iamVjdCB1c2luZyBXQVNNIHBhcnNpbmcgaW5zdGVhZCBvZiB0aGUgSlMgdHh3cmFwcGVyLlxuICpcbiAqIFRoaXMgcmVwbGFjZXMgdGhlIGxlZ2FjeSBgdG9Kc29uKClgIHBhdGggZm9yIGNoYWlucyB3aGVyZSBXQVNNIHBhcnNpbmcgaXMgZW5hYmxlZC5cbiAqIFRoZSBXQVNNIHBhcnNlciBkZWNvZGVzIHRoZSBleHRyaW5zaWMgYnl0ZXMgKHdpdGggbWV0YWRhdGEtYXdhcmUgc2lnbmVkIGV4dGVuc2lvbiBoYW5kbGluZyksXG4gKiBhbmQgdGhpcyBmdW5jdGlvbiBtYXBzIHRoZSByZXN1bHQgdG8gdGhlIFR4RGF0YSBpbnRlcmZhY2UgdGhhdCBjb25zdW1lcnMgZXhwZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9Kc29uRnJvbVdhc20ocGFyYW1zOiBUb0pzb25Gcm9tV2FzbVBhcmFtcyk6IFR4RGF0YSB7XG4gIGNvbnN0IGV4cGxhaW5lZCA9IGJ1aWxkRXhwbGFuYXRpb24ocGFyYW1zKTtcbiAgY29uc3QgdHlwZSA9IG1hcFRyYW5zYWN0aW9uVHlwZShleHBsYWluZWQudHlwZU5hbWUpO1xuICBjb25zdCBtZXRob2QgPSBleHBsYWluZWQubWV0aG9kO1xuICBjb25zdCBhcmdzID0gbWV0aG9kLmFyZ3MgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG5cbiAgY29uc3QgcmVzdWx0OiBUeERhdGEgPSB7XG4gICAgaWQ6IGV4cGxhaW5lZC5pZCB8fCAnJyxcbiAgICBzZW5kZXI6IGV4cGxhaW5lZC5zZW5kZXIgfHwgcGFyYW1zLnNlbmRlckFkZHJlc3MsXG4gICAgcmVmZXJlbmNlQmxvY2s6IHBhcmFtcy5yZWZlcmVuY2VCbG9jayB8fCAnJyxcbiAgICBibG9ja051bWJlcjogcGFyYW1zLmJsb2NrTnVtYmVyIHx8IDAsXG4gICAgZ2VuZXNpc0hhc2g6IHBhcmFtcy5tYXRlcmlhbC5nZW5lc2lzSGFzaCB8fCAnJyxcbiAgICBub25jZTogZXhwbGFpbmVkLm5vbmNlLFxuICAgIHNwZWNWZXJzaW9uOiBwYXJhbXMubWF0ZXJpYWwuc3BlY1ZlcnNpb24gfHwgMCxcbiAgICB0cmFuc2FjdGlvblZlcnNpb246IHBhcmFtcy5tYXRlcmlhbC50eFZlcnNpb24gfHwgMCxcbiAgICBjaGFpbk5hbWU6IHBhcmFtcy5tYXRlcmlhbC5jaGFpbk5hbWUgfHwgJycsXG4gICAgdGlwOiBOdW1iZXIoZXhwbGFpbmVkLnRpcCkgfHwgMCxcbiAgICBlcmFQZXJpb2Q6IGV4cGxhaW5lZC5lcmEudHlwZSA9PT0gJ21vcnRhbCcgPyAoZXhwbGFpbmVkLmVyYSBhcyB7IHBlcmlvZDogbnVtYmVyIH0pLnBlcmlvZCA6IDAsXG4gIH07XG5cbiAgaWYgKHR5cGUgPT09IFRyYW5zYWN0aW9uVHlwZS5TZW5kKSB7XG4gICAgcG9wdWxhdGVTZW5kRmllbGRzKHJlc3VsdCwgbWV0aG9kLCBhcmdzKTtcbiAgfSBlbHNlIGlmICh0eXBlID09PSBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0FjdGl2YXRlKSB7XG4gICAgcG9wdWxhdGVTdGFraW5nQWN0aXZhdGVGaWVsZHMocmVzdWx0LCBtZXRob2QsIGFyZ3MsIHBhcmFtcy5zZW5kZXJBZGRyZXNzKTtcbiAgfSBlbHNlIGlmICh0eXBlID09PSBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ1VubG9jaykge1xuICAgIHJlc3VsdC5hbW91bnQgPSBTdHJpbmcoYXJncy52YWx1ZSA/PyAnJyk7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdXaXRoZHJhdykge1xuICAgIHJlc3VsdC5udW1TbGFzaGluZ1NwYW5zID0gTnVtYmVyKGFyZ3MubnVtU2xhc2hpbmdTcGFucyA/PyAwKTtcbiAgfSBlbHNlIGlmICh0eXBlID09PSBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0NsYWltKSB7XG4gICAgcmVzdWx0LnZhbGlkYXRvclN0YXNoID0gU3RyaW5nKGFyZ3MudmFsaWRhdG9yU3Rhc2ggPz8gJycpO1xuICAgIHJlc3VsdC5jbGFpbUVyYSA9IFN0cmluZyhhcmdzLmVyYSA/PyAnJyk7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gVHJhbnNhY3Rpb25UeXBlLkFkZHJlc3NJbml0aWFsaXphdGlvbikge1xuICAgIHBvcHVsYXRlQWRkcmVzc0luaXRGaWVsZHMocmVzdWx0LCBtZXRob2QsIGFyZ3MpO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09IFRyYW5zYWN0aW9uVHlwZS5CYXRjaCkge1xuICAgIHJlc3VsdC5iYXRjaENhbGxzID0gbWFwQmF0Y2hDYWxscyhhcmdzLmNhbGxzIGFzIFBhcnNlZE1ldGhvZFtdKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBDb3JlIGV4cGxhaW4gbG9naWMgKG1vdmVkIGZyb20gQGJpdGdvL3dhc20tZG90KVxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuaW50ZXJmYWNlIEludGVybmFsRXhwbGFpbmVkIHtcbiAgdHlwZU5hbWU6IHN0cmluZztcbiAgaWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgc2VuZGVyOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIG91dHB1dHM6IHsgYWRkcmVzczogc3RyaW5nOyBhbW91bnQ6IHN0cmluZyB9W107XG4gIGlucHV0czogeyBhZGRyZXNzOiBzdHJpbmc7IHZhbHVlOiBzdHJpbmcgfVtdO1xuICBvdXRwdXRBbW91bnQ6IHN0cmluZztcbiAgdGlwOiBzdHJpbmc7XG4gIGVyYTogRXJhO1xuICBtZXRob2Q6IFBhcnNlZE1ldGhvZDtcbiAgaXNTaWduZWQ6IGJvb2xlYW47XG4gIG5vbmNlOiBudW1iZXI7XG59XG5cbi8qKiBQYXJzZSBhbmQgZXhwbGFpbiBhIERPVCB0cmFuc2FjdGlvbi4gUmVwbGFjZXMgdGhlIG9sZCB3YXNtLWRvdCBleHBsYWluVHJhbnNhY3Rpb24uICovXG5mdW5jdGlvbiBidWlsZEV4cGxhbmF0aW9uKHBhcmFtczoge1xuICB0eEhleDogc3RyaW5nO1xuICBtYXRlcmlhbDogTWF0ZXJpYWw7XG4gIHNlbmRlckFkZHJlc3M/OiBzdHJpbmc7XG4gIHJlZmVyZW5jZUJsb2NrPzogc3RyaW5nO1xuICBibG9ja051bWJlcj86IG51bWJlcjtcbn0pOiBJbnRlcm5hbEV4cGxhaW5lZCB7XG4gIGNvbnN0IHR4ID0gRG90VHJhbnNhY3Rpb24uZnJvbUhleChwYXJhbXMudHhIZXgsIHBhcmFtcy5tYXRlcmlhbCk7XG4gIGNvbnN0IGNvbnRleHQgPSB7XG4gICAgbWF0ZXJpYWw6IHBhcmFtcy5tYXRlcmlhbCxcbiAgICBzZW5kZXI6IHBhcmFtcy5zZW5kZXJBZGRyZXNzLFxuICAgIHJlZmVyZW5jZUJsb2NrOiBwYXJhbXMucmVmZXJlbmNlQmxvY2ssXG4gICAgYmxvY2tOdW1iZXI6IHBhcmFtcy5ibG9ja051bWJlcixcbiAgfTtcbiAgY29uc3QgcGFyc2VkID0gcGFyc2VUcmFuc2FjdGlvbih0eCwgY29udGV4dCk7XG5cbiAgY29uc3QgdHlwZU5hbWUgPSBkZXJpdmVUcmFuc2FjdGlvblR5cGUocGFyc2VkLm1ldGhvZCwgMCk7XG4gIGNvbnN0IHNlbmRlciA9IHBhcnNlZC5zZW5kZXIgPz8gcGFyYW1zLnNlbmRlckFkZHJlc3M7XG5cbiAgLy8gQ2hlY2sgZm9yIGJhdGNoIHBhdHRlcm5zIHRoYXQgbmVlZCBwcm94eSBkZXBvc2l0IGNvc3QgaGFuZGxpbmdcbiAgY29uc3QgYmF0Y2hJbmZvID0gZGV0ZWN0UHJveHlCYXRjaChwYXJzZWQubWV0aG9kKTtcbiAgbGV0IG91dHB1dHM6IHsgYWRkcmVzczogc3RyaW5nOyBhbW91bnQ6IHN0cmluZyB9W107XG4gIGxldCBpbnB1dHM6IHsgYWRkcmVzczogc3RyaW5nOyB2YWx1ZTogc3RyaW5nIH1bXTtcblxuICBpZiAoYmF0Y2hJbmZvICYmIHNlbmRlcikge1xuICAgIGNvbnN0IHByb3h5RGVwb3NpdENvc3QgPSBnZXRQcm94eURlcG9zaXRDb3N0KHBhcmFtcy5tYXRlcmlhbC5tZXRhZGF0YSkudG9TdHJpbmcoKTtcbiAgICBpZiAoYmF0Y2hJbmZvLnR5cGUgPT09ICd1bnN0YWtlJykge1xuICAgICAgLy8gVW5zdGFraW5nIGJhdGNoIChyZW1vdmVQcm94eSArIGNoaWxsICsgdW5ib25kKTogcHJveHkgZGVwb3NpdCByZWZ1bmQgZmxvd3NcbiAgICAgIC8vIGZyb20gcHJveHkgYWRkcmVzcyBiYWNrIHRvIHNlbmRlci4gVGhlIHVuYm9uZCBhbW91bnQgaXMgTk9UIGluIGlucHV0cy9vdXRwdXRzLlxuICAgICAgb3V0cHV0cyA9IFt7IGFkZHJlc3M6IHNlbmRlciwgYW1vdW50OiBwcm94eURlcG9zaXRDb3N0IH1dO1xuICAgICAgaW5wdXRzID0gW3sgYWRkcmVzczogYmF0Y2hJbmZvLnByb3h5QWRkcmVzcywgdmFsdWU6IHByb3h5RGVwb3NpdENvc3QgfV07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFN0YWtpbmcgYmF0Y2ggKGJvbmQgKyBhZGRQcm94eSk6IGJvbmQgYW1vdW50ICsgcHJveHkgZGVwb3NpdCBjb3N0XG4gICAgICBjb25zdCBib25kT3V0cHV0cyA9IGV4dHJhY3RPdXRwdXRzKHBhcnNlZC5tZXRob2QsIDApLmZpbHRlcigobykgPT4gby5hZGRyZXNzID09PSAnU1RBS0lORycpO1xuICAgICAgb3V0cHV0cyA9IFsuLi5ib25kT3V0cHV0cywgeyBhZGRyZXNzOiBiYXRjaEluZm8ucHJveHlBZGRyZXNzLCBhbW91bnQ6IHByb3h5RGVwb3NpdENvc3QgfV07XG4gICAgICBpbnB1dHMgPSBvdXRwdXRzLm1hcCgobykgPT4gKHsgYWRkcmVzczogc2VuZGVyLCB2YWx1ZTogby5hbW91bnQgfSkpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBvdXRwdXRzID0gZXh0cmFjdE91dHB1dHMocGFyc2VkLm1ldGhvZCwgMCk7XG4gICAgaW5wdXRzID0gc2VuZGVyID8gb3V0cHV0cy5tYXAoKG8pID0+ICh7IGFkZHJlc3M6IHNlbmRlciwgdmFsdWU6IG8uYW1vdW50IH0pKSA6IFtdO1xuICB9XG5cbiAgY29uc3Qgb3V0cHV0QW1vdW50ID0gb3V0cHV0cy5yZWR1Y2UoKHN1bSwgbykgPT4ge1xuICAgIGlmIChvLmFtb3VudCA9PT0gJ0FMTCcpIHJldHVybiBzdW07XG4gICAgcmV0dXJuIChCaWdJbnQoc3VtKSArIEJpZ0ludChvLmFtb3VudCkpLnRvU3RyaW5nKCk7XG4gIH0sICcwJyk7XG5cbiAgcmV0dXJuIHtcbiAgICB0eXBlTmFtZSxcbiAgICBpZDogcGFyc2VkLmlkID8/IHVuZGVmaW5lZCxcbiAgICBzZW5kZXI6IHBhcnNlZC5zZW5kZXIgPz8gdW5kZWZpbmVkLFxuICAgIG91dHB1dHMsXG4gICAgaW5wdXRzLFxuICAgIG91dHB1dEFtb3VudCxcbiAgICB0aXA6IHBhcnNlZC50aXAsXG4gICAgZXJhOiBwYXJzZWQuZXJhLFxuICAgIG1ldGhvZDogcGFyc2VkLm1ldGhvZCxcbiAgICBpc1NpZ25lZDogcGFyc2VkLmlzU2lnbmVkLFxuICAgIG5vbmNlOiBwYXJzZWQubm9uY2UsXG4gIH07XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBUcmFuc2FjdGlvbiB0eXBlIGRlcml2YXRpb24gKG1vdmVkIGZyb20gQGJpdGdvL3dhc20tZG90KVxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZnVuY3Rpb24gZGVyaXZlVHJhbnNhY3Rpb25UeXBlKG1ldGhvZDogUGFyc2VkTWV0aG9kLCBkZXB0aDogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3Qga2V5ID0gYCR7bWV0aG9kLnBhbGxldH0uJHttZXRob2QubmFtZX1gO1xuICBjb25zdCBhcmdzID0gKG1ldGhvZC5hcmdzID8/IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgc3dpdGNoIChrZXkpIHtcbiAgICBjYXNlICdiYWxhbmNlcy50cmFuc2Zlcic6XG4gICAgY2FzZSAnYmFsYW5jZXMudHJhbnNmZXJLZWVwQWxpdmUnOlxuICAgIGNhc2UgJ2JhbGFuY2VzLnRyYW5zZmVyQWxsb3dEZWF0aCc6XG4gICAgY2FzZSAnYmFsYW5jZXMudHJhbnNmZXJBbGwnOlxuICAgICAgcmV0dXJuICdTZW5kJztcblxuICAgIGNhc2UgJ3N0YWtpbmcuYm9uZCc6XG4gICAgY2FzZSAnc3Rha2luZy5ib25kRXh0cmEnOlxuICAgICAgcmV0dXJuICdTdGFraW5nQWN0aXZhdGUnO1xuXG4gICAgY2FzZSAnc3Rha2luZy51bmJvbmQnOlxuICAgICAgcmV0dXJuICdTdGFraW5nVW5sb2NrJztcblxuICAgIGNhc2UgJ3N0YWtpbmcud2l0aGRyYXdVbmJvbmRlZCc6XG4gICAgICByZXR1cm4gJ1N0YWtpbmdXaXRoZHJhdyc7XG5cbiAgICBjYXNlICdzdGFraW5nLmNoaWxsJzpcbiAgICAgIHJldHVybiAnU3Rha2luZ1Vudm90ZSc7XG5cbiAgICBjYXNlICdzdGFraW5nLnBheW91dFN0YWtlcnMnOlxuICAgICAgcmV0dXJuICdTdGFraW5nQ2xhaW0nO1xuXG4gICAgY2FzZSAncHJveHkuYWRkUHJveHknOlxuICAgIGNhc2UgJ3Byb3h5LnJlbW92ZVByb3h5JzpcbiAgICBjYXNlICdwcm94eS5jcmVhdGVQdXJlJzpcbiAgICAgIHJldHVybiAnQWRkcmVzc0luaXRpYWxpemF0aW9uJztcblxuICAgIGNhc2UgJ3V0aWxpdHkuYmF0Y2gnOlxuICAgIGNhc2UgJ3V0aWxpdHkuYmF0Y2hBbGwnOlxuICAgICAgcmV0dXJuICdCYXRjaCc7XG5cbiAgICBjYXNlICdwcm94eS5wcm94eSc6IHtcbiAgICAgIGlmIChkZXB0aCA+PSBNQVhfTkVTVElOR19ERVBUSCkgcmV0dXJuICdVbmtub3duJztcbiAgICAgIGNvbnN0IGNhbGwgPSBhcmdzLmNhbGwgYXMgUGFyc2VkTWV0aG9kIHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKGNhbGw/LnBhbGxldCAmJiBjYWxsPy5uYW1lKSByZXR1cm4gZGVyaXZlVHJhbnNhY3Rpb25UeXBlKGNhbGwsIGRlcHRoICsgMSk7XG4gICAgICByZXR1cm4gJ1Vua25vd24nO1xuICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gJ1Vua25vd24nO1xuICB9XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBPdXRwdXQgZXh0cmFjdGlvbiAobW92ZWQgZnJvbSBAYml0Z28vd2FzbS1kb3QpXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5mdW5jdGlvbiBleHRyYWN0T3V0cHV0cyhtZXRob2Q6IFBhcnNlZE1ldGhvZCwgZGVwdGg6IG51bWJlcik6IHsgYWRkcmVzczogc3RyaW5nOyBhbW91bnQ6IHN0cmluZyB9W10ge1xuICBjb25zdCBhcmdzID0gKG1ldGhvZC5hcmdzID8/IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgY29uc3Qga2V5ID0gYCR7bWV0aG9kLnBhbGxldH0uJHttZXRob2QubmFtZX1gO1xuXG4gIHN3aXRjaCAoa2V5KSB7XG4gICAgY2FzZSAnYmFsYW5jZXMudHJhbnNmZXInOlxuICAgIGNhc2UgJ2JhbGFuY2VzLnRyYW5zZmVyS2VlcEFsaXZlJzpcbiAgICBjYXNlICdiYWxhbmNlcy50cmFuc2ZlckFsbG93RGVhdGgnOlxuICAgICAgcmV0dXJuIFt7IGFkZHJlc3M6IFN0cmluZyhhcmdzLmRlc3QgPz8gJycpLCBhbW91bnQ6IFN0cmluZyhhcmdzLnZhbHVlID8/ICcwJykgfV07XG5cbiAgICBjYXNlICdiYWxhbmNlcy50cmFuc2ZlckFsbCc6XG4gICAgICByZXR1cm4gW3sgYWRkcmVzczogU3RyaW5nKGFyZ3MuZGVzdCA/PyAnJyksIGFtb3VudDogJ0FMTCcgfV07XG5cbiAgICBjYXNlICdzdGFraW5nLmJvbmQnOlxuICAgIGNhc2UgJ3N0YWtpbmcuYm9uZEV4dHJhJzpcbiAgICBjYXNlICdzdGFraW5nLnVuYm9uZCc6XG4gICAgICByZXR1cm4gW3sgYWRkcmVzczogJ1NUQUtJTkcnLCBhbW91bnQ6IFN0cmluZyhhcmdzLnZhbHVlID8/ICcwJykgfV07XG5cbiAgICBjYXNlICd1dGlsaXR5LmJhdGNoJzpcbiAgICBjYXNlICd1dGlsaXR5LmJhdGNoQWxsJzoge1xuICAgICAgaWYgKGRlcHRoID49IE1BWF9ORVNUSU5HX0RFUFRIKSByZXR1cm4gW107XG4gICAgICBjb25zdCBjYWxscyA9IChhcmdzLmNhbGxzID8/IFtdKSBhcyBQYXJzZWRNZXRob2RbXTtcbiAgICAgIHJldHVybiBjYWxscy5maWx0ZXIoKGMpID0+IGM/LnBhbGxldCAmJiBjPy5uYW1lKS5mbGF0TWFwKChjKSA9PiBleHRyYWN0T3V0cHV0cyhjLCBkZXB0aCArIDEpKTtcbiAgICB9XG5cbiAgICBjYXNlICdwcm94eS5wcm94eSc6IHtcbiAgICAgIGlmIChkZXB0aCA+PSBNQVhfTkVTVElOR19ERVBUSCkgcmV0dXJuIFtdO1xuICAgICAgY29uc3QgY2FsbCA9IGFyZ3MuY2FsbCBhcyBQYXJzZWRNZXRob2QgfCB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gY2FsbD8ucGFsbGV0ICYmIGNhbGw/Lm5hbWUgPyBleHRyYWN0T3V0cHV0cyhjYWxsLCBkZXB0aCArIDEpIDogW107XG4gICAgfVxuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBbXTtcbiAgfVxufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gQmF0Y2ggcHJveHkgZGV0ZWN0aW9uXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5pbnRlcmZhY2UgUHJveHlCYXRjaEluZm8ge1xuICB0eXBlOiAnc3Rha2UnIHwgJ3Vuc3Rha2UnO1xuICBwcm94eUFkZHJlc3M6IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZXRlY3QgYmF0Y2ggdHJhbnNhY3Rpb25zIGludm9sdmluZyBwcm94eSBvcGVyYXRpb25zIChzdGFrZS91bnN0YWtlIGJhdGNoZXMpLlxuICpcbiAqIExlZ2FjeSBhY2NvdW50LWxpYiByZXBvcnRzIHByb3h5IGRlcG9zaXQgY29zdCAoUHJveHlEZXBvc2l0QmFzZSArIFByb3h5RGVwb3NpdEZhY3RvcilcbiAqIGFzIHRoZSB2YWx1ZSBmb3IgdGhlc2UgYmF0Y2hlcyBpbnN0ZWFkIG9mIHRoZSBib25kL3VuYm9uZCBhbW91bnQuXG4gKlxuICogVW5zdGFraW5nIGJhdGNoOiByZW1vdmVQcm94eSArIGNoaWxsICsgdW5ib25kXG4gKiBTdGFraW5nIGJhdGNoOiBib25kICsgYWRkUHJveHlcbiAqL1xuZnVuY3Rpb24gZGV0ZWN0UHJveHlCYXRjaChtZXRob2Q6IFBhcnNlZE1ldGhvZCk6IFByb3h5QmF0Y2hJbmZvIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qga2V5ID0gYCR7bWV0aG9kLnBhbGxldH0uJHttZXRob2QubmFtZX1gO1xuICBpZiAoa2V5ICE9PSAndXRpbGl0eS5iYXRjaCcgJiYga2V5ICE9PSAndXRpbGl0eS5iYXRjaEFsbCcpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgY29uc3QgY2FsbHMgPSAoKG1ldGhvZC5hcmdzID8/IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikuY2FsbHMgYXMgUGFyc2VkTWV0aG9kW10gfCB1bmRlZmluZWQ7XG4gIGlmICghY2FsbHMgfHwgY2FsbHMubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGNhbGxLZXlzID0gY2FsbHMubWFwKChjKSA9PiBgJHtjLnBhbGxldH0uJHtjLm5hbWV9YCk7XG5cbiAgLy8gVW5zdGFraW5nIGJhdGNoOiByZW1vdmVQcm94eSArIGNoaWxsICsgdW5ib25kICgzIGNhbGxzKVxuICBpZiAoXG4gICAgY2FsbHMubGVuZ3RoID09PSAzICYmXG4gICAgY2FsbEtleXNbMF0gPT09ICdwcm94eS5yZW1vdmVQcm94eScgJiZcbiAgICBjYWxsS2V5c1sxXSA9PT0gJ3N0YWtpbmcuY2hpbGwnICYmXG4gICAgY2FsbEtleXNbMl0gPT09ICdzdGFraW5nLnVuYm9uZCdcbiAgKSB7XG4gICAgY29uc3QgcmVtb3ZlUHJveHlBcmdzID0gKGNhbGxzWzBdLmFyZ3MgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgIGNvbnN0IHByb3h5QWRkcmVzcyA9IFN0cmluZyhyZW1vdmVQcm94eUFyZ3MuZGVsZWdhdGUgPz8gJycpO1xuICAgIHJldHVybiB7IHR5cGU6ICd1bnN0YWtlJywgcHJveHlBZGRyZXNzIH07XG4gIH1cblxuICAvLyBTdGFraW5nIGJhdGNoOiBib25kICsgYWRkUHJveHkgKDIgY2FsbHMpXG4gIGlmIChjYWxscy5sZW5ndGggPT09IDIgJiYgY2FsbEtleXNbMF0gPT09ICdzdGFraW5nLmJvbmQnICYmIGNhbGxLZXlzWzFdID09PSAncHJveHkuYWRkUHJveHknKSB7XG4gICAgY29uc3QgYWRkUHJveHlBcmdzID0gKGNhbGxzWzFdLmFyZ3MgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgIGNvbnN0IHByb3h5QWRkcmVzcyA9IFN0cmluZyhhZGRQcm94eUFyZ3MuZGVsZWdhdGUgPz8gJycpO1xuICAgIHJldHVybiB7IHR5cGU6ICdzdGFrZScsIHByb3h5QWRkcmVzcyB9O1xuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEhlbHBlcnNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKiBNYXAgdHlwZSBuYW1lIHN0cmluZyB0byBzZGstY29yZSBUcmFuc2FjdGlvblR5cGUgdmlhIG5hbWUgbG9va3VwICovXG5mdW5jdGlvbiBtYXBUcmFuc2FjdGlvblR5cGUodHlwZU5hbWU6IHN0cmluZyk6IFRyYW5zYWN0aW9uVHlwZSB7XG4gIHJldHVybiBUcmFuc2FjdGlvblR5cGVbdHlwZU5hbWUgYXMga2V5b2YgdHlwZW9mIFRyYW5zYWN0aW9uVHlwZV0gPz8gVHJhbnNhY3Rpb25UeXBlLlNlbmQ7XG59XG5cbmZ1bmN0aW9uIHBvcHVsYXRlU2VuZEZpZWxkcyhyZXN1bHQ6IFR4RGF0YSwgbWV0aG9kOiBQYXJzZWRNZXRob2QsIGFyZ3M6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogdm9pZCB7XG4gIGNvbnN0IGtleSA9IGAke21ldGhvZC5wYWxsZXR9LiR7bWV0aG9kLm5hbWV9YDtcblxuICBpZiAoa2V5ID09PSAncHJveHkucHJveHknKSB7XG4gICAgLy8gUHJveHktd3JhcHBlZCB0cmFuc2ZlclxuICAgIGNvbnN0IGlubmVyQ2FsbCA9IGFyZ3MuY2FsbCBhcyBQYXJzZWRNZXRob2QgfCB1bmRlZmluZWQ7XG4gICAgcmVzdWx0Lm93bmVyID0gU3RyaW5nKGFyZ3MucmVhbCA/PyAnJyk7XG4gICAgcmVzdWx0LmZvcmNlUHJveHlUeXBlID0gKGFyZ3MuZm9yY2VQcm94eVR5cGUgYXMgUHJveHlUeXBlKSA/PyB1bmRlZmluZWQ7XG4gICAgaWYgKGlubmVyQ2FsbD8uYXJncykge1xuICAgICAgY29uc3QgaW5uZXJBcmdzID0gaW5uZXJDYWxsLmFyZ3MgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICByZXN1bHQudG8gPSBTdHJpbmcoaW5uZXJBcmdzLmRlc3QgPz8gJycpO1xuICAgICAgcmVzdWx0LmFtb3VudCA9IFN0cmluZyhpbm5lckFyZ3MudmFsdWUgPz8gJycpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChrZXkgPT09ICdiYWxhbmNlcy50cmFuc2ZlckFsbCcpIHtcbiAgICByZXN1bHQudG8gPSBTdHJpbmcoYXJncy5kZXN0ID8/ICcnKTtcbiAgICByZXN1bHQua2VlcEFsaXZlID0gQm9vbGVhbihhcmdzLmtlZXBBbGl2ZSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gdHJhbnNmZXIsIHRyYW5zZmVyS2VlcEFsaXZlLCB0cmFuc2ZlckFsbG93RGVhdGhcbiAgICByZXN1bHQudG8gPSBTdHJpbmcoYXJncy5kZXN0ID8/ICcnKTtcbiAgICByZXN1bHQuYW1vdW50ID0gU3RyaW5nKGFyZ3MudmFsdWUgPz8gJycpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBvcHVsYXRlU3Rha2luZ0FjdGl2YXRlRmllbGRzKFxuICByZXN1bHQ6IFR4RGF0YSxcbiAgbWV0aG9kOiBQYXJzZWRNZXRob2QsXG4gIGFyZ3M6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICBzZW5kZXJBZGRyZXNzOiBzdHJpbmdcbik6IHZvaWQge1xuICBpZiAobWV0aG9kLm5hbWUgPT09ICdib25kRXh0cmEnKSB7XG4gICAgcmVzdWx0LmFtb3VudCA9IFN0cmluZyhhcmdzLnZhbHVlID8/ICcnKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBib25kXG4gICAgcmVzdWx0LmNvbnRyb2xsZXIgPSBzZW5kZXJBZGRyZXNzO1xuICAgIHJlc3VsdC5hbW91bnQgPSBTdHJpbmcoYXJncy52YWx1ZSA/PyAnJyk7XG4gICAgcmVzdWx0LnBheWVlID0gU3RyaW5nKGFyZ3MucGF5ZWUgPz8gJycpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBvcHVsYXRlQWRkcmVzc0luaXRGaWVsZHMocmVzdWx0OiBUeERhdGEsIG1ldGhvZDogUGFyc2VkTWV0aG9kLCBhcmdzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IHZvaWQge1xuICBjb25zdCBrZXkgPSBgJHttZXRob2QucGFsbGV0fS4ke21ldGhvZC5uYW1lfWA7XG4gIHJlc3VsdC5tZXRob2QgPSBrZXk7XG4gIHJlc3VsdC5wcm94eVR5cGUgPSBTdHJpbmcoYXJncy5wcm94eV90eXBlID8/ICcnKTtcbiAgcmVzdWx0LmRlbGF5ID0gU3RyaW5nKGFyZ3MuZGVsYXkgPz8gJycpO1xuXG4gIGlmIChrZXkgPT09ICdwcm94eS5jcmVhdGVQdXJlJykge1xuICAgIHJlc3VsdC5pbmRleCA9IFN0cmluZyhhcmdzLmluZGV4ID8/ICcnKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBhZGRQcm94eSwgcmVtb3ZlUHJveHlcbiAgICByZXN1bHQub3duZXIgPSBTdHJpbmcoYXJncy5kZWxlZ2F0ZSA/PyAnJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWFwQmF0Y2hDYWxscyhjYWxsczogUGFyc2VkTWV0aG9kW10gfCB1bmRlZmluZWQpOiBCYXRjaENhbGxPYmplY3RbXSB7XG4gIGlmICghY2FsbHMpIHJldHVybiBbXTtcbiAgcmV0dXJuIGNhbGxzLm1hcCgoY2FsbCkgPT4gKHtcbiAgICBjYWxsSW5kZXg6IGAweCR7Y2FsbC5wYWxsZXRJbmRleC50b1N0cmluZygxNikucGFkU3RhcnQoMiwgJzAnKX0ke2NhbGwubWV0aG9kSW5kZXgudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsICcwJyl9YCxcbiAgICBhcmdzOiB0cmFuc2Zvcm1CYXRjaENhbGxBcmdzKChjYWxsLmFyZ3MgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KSxcbiAgfSkpO1xufVxuXG4vKiogVHJhbnNmb3JtIFdBU00tZGVjb2RlZCBiYXRjaCBjYWxsIGFyZ3MgdG8gbWF0Y2ggdGhlIFBvbGthZG90LmpzIGZvcm1hdCB0aGF0IGNvbnN1bWVycyBleHBlY3QgKi9cbmZ1bmN0aW9uIHRyYW5zZm9ybUJhdGNoQ2FsbEFyZ3MoYXJnczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoYXJncykpIHtcbiAgICBpZiAoa2V5ID09PSAnZGVsZWdhdGUnICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIE11bHRpQWRkcmVzcyBJZCB2YXJpYW50OiBzdHJpbmcg4oaSIHsgaWQ6IHN0cmluZyB9XG4gICAgICByZXN1bHRba2V5XSA9IHsgaWQ6IHZhbHVlIH07XG4gICAgfSBlbHNlIGlmIChrZXkgPT09ICd2YWx1ZScgJiYgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gQ29tcGFjdCB1MTI4OiBzdHJpbmcg4oaSIG51bWJlciAobWF0Y2hlcyBQb2xrYWRvdC5qcyBiZWhhdmlvcilcbiAgICAgIHJlc3VsdFtrZXldID0gTnVtYmVyKHZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKGtleSA9PT0gJ3BheWVlJyAmJiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAvLyBFbnVtIHVuaXQgdmFyaWFudDogXCJTdGFrZWRcIiDihpIgeyBzdGFrZWQ6IG51bGwgfVxuICAgICAgY29uc3QgdmFyaWFudE5hbWUgPSB2YWx1ZS5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKSArIHZhbHVlLnNsaWNlKDEpO1xuICAgICAgcmVzdWx0W2tleV0gPSB7IFt2YXJpYW50TmFtZV06IG51bGwgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0W2tleV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiJdfQ==
|