@sapui5/sap.fe.base 1.125.0 → 1.126.1
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/package.json +1 -1
- package/src/sap/fe/base/.library +1 -1
- package/src/sap/fe/base/AnnotationEnum.js +33 -0
- package/src/sap/fe/base/AnnotationEnum.ts +21 -0
- package/src/sap/fe/base/BindingToolkit.js +1822 -0
- package/src/sap/fe/base/BindingToolkit.ts +2452 -0
- package/src/sap/fe/base/ClassSupport.js +24 -4
- package/src/sap/fe/base/ClassSupport.ts +26 -3
- package/src/sap/fe/base/jsx-runtime/ViewLoader.js +1 -1
- package/src/sap/fe/base/jsx-runtime/ViewLoader.tsx +2 -1
- package/src/sap/fe/base/jsx-runtime/jsx-control.js +31 -3
- package/src/sap/fe/base/jsx-runtime/jsx-control.ts +34 -6
- package/src/sap/fe/base/jsx-runtime/jsx-renderManager.js +7 -3
- package/src/sap/fe/base/jsx-runtime/jsx-renderManager.ts +8 -3
- package/src/sap/fe/base/jsx-runtime/jsx-xml.js +73 -21
- package/src/sap/fe/base/jsx-runtime/jsx-xml.ts +90 -22
- package/src/sap/fe/base/library.js +1 -1
|
@@ -0,0 +1,1822 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* SAP UI development toolkit for HTML5 (SAPUI5)
|
|
3
|
+
* (c) Copyright 2009-2024 SAP SE. All rights reserved
|
|
4
|
+
*/
|
|
5
|
+
sap.ui.define(["sap/fe/base/AnnotationEnum"], function (AnnotationEnum) {
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
var _exports = {};
|
|
9
|
+
var resolveEnumValue = AnnotationEnum.resolveEnumValue;
|
|
10
|
+
function isProperty(serviceObject) {
|
|
11
|
+
return (serviceObject === null || serviceObject === void 0 ? void 0 : serviceObject._type) === "Property";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* An expression that evaluates to type T.
|
|
16
|
+
*
|
|
17
|
+
* @typedef BindingToolkitExpression
|
|
18
|
+
*/
|
|
19
|
+
_exports.isProperty = isProperty;
|
|
20
|
+
const EDM_TYPE_MAPPING = {
|
|
21
|
+
"Edm.Boolean": {
|
|
22
|
+
type: "sap.ui.model.odata.type.Boolean"
|
|
23
|
+
},
|
|
24
|
+
"Edm.Byte": {
|
|
25
|
+
type: "sap.ui.model.odata.type.Byte"
|
|
26
|
+
},
|
|
27
|
+
"Edm.Date": {
|
|
28
|
+
type: "sap.ui.model.odata.type.Date"
|
|
29
|
+
},
|
|
30
|
+
"Edm.DateTimeOffset": {
|
|
31
|
+
constraints: {
|
|
32
|
+
$Precision: "precision",
|
|
33
|
+
$V4: "V4"
|
|
34
|
+
},
|
|
35
|
+
type: "sap.ui.model.odata.type.DateTimeOffset"
|
|
36
|
+
},
|
|
37
|
+
"Edm.Decimal": {
|
|
38
|
+
constraints: {
|
|
39
|
+
"@Org.OData.Validation.V1.Minimum/$Decimal": "minimum",
|
|
40
|
+
"@Org.OData.Validation.V1.Minimum@Org.OData.Validation.V1.Exclusive": "minimumExclusive",
|
|
41
|
+
"@Org.OData.Validation.V1.Maximum/$Decimal": "maximum",
|
|
42
|
+
"@Org.OData.Validation.V1.Maximum@Org.OData.Validation.V1.Exclusive": "maximumExclusive",
|
|
43
|
+
$Precision: "precision",
|
|
44
|
+
$Scale: "scale"
|
|
45
|
+
},
|
|
46
|
+
type: "sap.ui.model.odata.type.Decimal"
|
|
47
|
+
},
|
|
48
|
+
"Edm.Double": {
|
|
49
|
+
type: "sap.ui.model.odata.type.Double"
|
|
50
|
+
},
|
|
51
|
+
"Edm.Guid": {
|
|
52
|
+
type: "sap.ui.model.odata.type.Guid"
|
|
53
|
+
},
|
|
54
|
+
"Edm.Int16": {
|
|
55
|
+
type: "sap.ui.model.odata.type.Int16"
|
|
56
|
+
},
|
|
57
|
+
"Edm.Int32": {
|
|
58
|
+
type: "sap.ui.model.odata.type.Int32"
|
|
59
|
+
},
|
|
60
|
+
"Edm.Int64": {
|
|
61
|
+
type: "sap.ui.model.odata.type.Int64"
|
|
62
|
+
},
|
|
63
|
+
"Edm.SByte": {
|
|
64
|
+
type: "sap.ui.model.odata.type.SByte"
|
|
65
|
+
},
|
|
66
|
+
"Edm.Single": {
|
|
67
|
+
type: "sap.ui.model.odata.type.Single"
|
|
68
|
+
},
|
|
69
|
+
"Edm.Stream": {
|
|
70
|
+
type: "sap.ui.model.odata.type.Stream"
|
|
71
|
+
},
|
|
72
|
+
"Edm.Binary": {
|
|
73
|
+
type: "sap.ui.model.odata.type.Stream"
|
|
74
|
+
},
|
|
75
|
+
"Edm.String": {
|
|
76
|
+
constraints: {
|
|
77
|
+
"@com.sap.vocabularies.Common.v1.IsDigitSequence": "isDigitSequence",
|
|
78
|
+
$MaxLength: "maxLength",
|
|
79
|
+
$Nullable: "nullable"
|
|
80
|
+
},
|
|
81
|
+
type: "sap.ui.model.odata.type.String"
|
|
82
|
+
},
|
|
83
|
+
"Edm.TimeOfDay": {
|
|
84
|
+
constraints: {
|
|
85
|
+
$Precision: "precision"
|
|
86
|
+
},
|
|
87
|
+
type: "sap.ui.model.odata.type.TimeOfDay"
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* An expression that evaluates to type T, or a constant value of type T
|
|
93
|
+
*/
|
|
94
|
+
_exports.EDM_TYPE_MAPPING = EDM_TYPE_MAPPING;
|
|
95
|
+
const unresolvableExpression = {
|
|
96
|
+
_type: "Unresolvable"
|
|
97
|
+
};
|
|
98
|
+
_exports.unresolvableExpression = unresolvableExpression;
|
|
99
|
+
function escapeXmlAttribute(inputString) {
|
|
100
|
+
return inputString.replace(/'/g, "\\'");
|
|
101
|
+
}
|
|
102
|
+
_exports.escapeXmlAttribute = escapeXmlAttribute;
|
|
103
|
+
function hasUnresolvableExpression() {
|
|
104
|
+
for (var _len = arguments.length, expressions = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
105
|
+
expressions[_key] = arguments[_key];
|
|
106
|
+
}
|
|
107
|
+
return expressions.find(expr => expr._type === "Unresolvable") !== undefined;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Check two expressions for (deep) equality.
|
|
111
|
+
*
|
|
112
|
+
* @param a
|
|
113
|
+
* @param b
|
|
114
|
+
* @returns `true` if the two expressions are equal
|
|
115
|
+
*/
|
|
116
|
+
_exports.hasUnresolvableExpression = hasUnresolvableExpression;
|
|
117
|
+
function _checkExpressionsAreEqual(a, b) {
|
|
118
|
+
if (a._type !== b._type) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
switch (a._type) {
|
|
122
|
+
case "Unresolvable":
|
|
123
|
+
return false;
|
|
124
|
+
// Unresolvable is never equal to anything even itself
|
|
125
|
+
case "Constant":
|
|
126
|
+
case "EmbeddedBinding":
|
|
127
|
+
case "EmbeddedExpressionBinding":
|
|
128
|
+
return a.value === b.value;
|
|
129
|
+
case "Not":
|
|
130
|
+
return _checkExpressionsAreEqual(a.operand, b.operand);
|
|
131
|
+
case "Truthy":
|
|
132
|
+
return _checkExpressionsAreEqual(a.operand, b.operand);
|
|
133
|
+
case "Set":
|
|
134
|
+
return a.operator === b.operator && a.operands.length === b.operands.length && a.operands.every(expression => b.operands.some(otherExpression => _checkExpressionsAreEqual(expression, otherExpression)));
|
|
135
|
+
case "IfElse":
|
|
136
|
+
return _checkExpressionsAreEqual(a.condition, b.condition) && _checkExpressionsAreEqual(a.onTrue, b.onTrue) && _checkExpressionsAreEqual(a.onFalse, b.onFalse);
|
|
137
|
+
case "Comparison":
|
|
138
|
+
return a.operator === b.operator && _checkExpressionsAreEqual(a.operand1, b.operand1) && _checkExpressionsAreEqual(a.operand2, b.operand2);
|
|
139
|
+
case "Concat":
|
|
140
|
+
const aExpressions = a.expressions;
|
|
141
|
+
const bExpressions = b.expressions;
|
|
142
|
+
if (aExpressions.length !== bExpressions.length) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
return aExpressions.every((expression, index) => {
|
|
146
|
+
return _checkExpressionsAreEqual(expression, bExpressions[index]);
|
|
147
|
+
});
|
|
148
|
+
case "Length":
|
|
149
|
+
return _checkExpressionsAreEqual(a.pathInModel, b.pathInModel);
|
|
150
|
+
case "PathInModel":
|
|
151
|
+
return a.modelName === b.modelName && a.path === b.path && a.targetEntitySet === b.targetEntitySet;
|
|
152
|
+
case "Formatter":
|
|
153
|
+
return a.fn === b.fn && a.parameters.length === b.parameters.length && a.parameters.every((value, index) => _checkExpressionsAreEqual(b.parameters[index], value));
|
|
154
|
+
case "ComplexType":
|
|
155
|
+
return a.type === b.type && a.bindingParameters.length === b.bindingParameters.length && a.bindingParameters.every((value, index) => _checkExpressionsAreEqual(b.bindingParameters[index], value));
|
|
156
|
+
case "Function":
|
|
157
|
+
const otherFunction = b;
|
|
158
|
+
if (a.obj === undefined || otherFunction.obj === undefined) {
|
|
159
|
+
return a.obj === otherFunction;
|
|
160
|
+
}
|
|
161
|
+
return a.fn === otherFunction.fn && _checkExpressionsAreEqual(a.obj, otherFunction.obj) && a.parameters.length === otherFunction.parameters.length && a.parameters.every((value, index) => _checkExpressionsAreEqual(otherFunction.parameters[index], value));
|
|
162
|
+
case "Ref":
|
|
163
|
+
return a.ref === b.ref;
|
|
164
|
+
}
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Converts a nested SetExpression by inlining operands of type SetExpression with the same operator.
|
|
170
|
+
*
|
|
171
|
+
* @param expression The expression to flatten
|
|
172
|
+
* @returns A new SetExpression with the same operator
|
|
173
|
+
*/
|
|
174
|
+
_exports._checkExpressionsAreEqual = _checkExpressionsAreEqual;
|
|
175
|
+
function flattenSetExpression(expression) {
|
|
176
|
+
return expression.operands.reduce((result, operand) => {
|
|
177
|
+
const candidatesForFlattening = operand._type === "Set" && operand.operator === expression.operator ? operand.operands : [operand];
|
|
178
|
+
candidatesForFlattening.forEach(candidate => {
|
|
179
|
+
if (result.operands.every(e => !_checkExpressionsAreEqual(e, candidate))) {
|
|
180
|
+
result.operands.push(candidate);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
return result;
|
|
184
|
+
}, {
|
|
185
|
+
_type: "Set",
|
|
186
|
+
operator: expression.operator,
|
|
187
|
+
operands: []
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Detects whether an array of boolean expressions contains an expression and its negation.
|
|
193
|
+
*
|
|
194
|
+
* @param expressions Array of expressions
|
|
195
|
+
* @returns `true` if the set of expressions contains an expression and its negation
|
|
196
|
+
*/
|
|
197
|
+
function hasOppositeExpressions(expressions) {
|
|
198
|
+
const negatedExpressions = expressions.map(not);
|
|
199
|
+
return expressions.some((expression, index) => {
|
|
200
|
+
for (let i = index + 1; i < negatedExpressions.length; i++) {
|
|
201
|
+
if (_checkExpressionsAreEqual(expression, negatedExpressions[i])) {
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return false;
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Logical `and` expression.
|
|
211
|
+
*
|
|
212
|
+
* The expression is simplified to false if this can be decided statically (that is, if one operand is a constant
|
|
213
|
+
* false or if the expression contains an operand and its negation).
|
|
214
|
+
*
|
|
215
|
+
* @param operands Expressions to connect by `and`
|
|
216
|
+
* @returns Expression evaluating to boolean
|
|
217
|
+
*/
|
|
218
|
+
function and() {
|
|
219
|
+
for (var _len2 = arguments.length, operands = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
220
|
+
operands[_key2] = arguments[_key2];
|
|
221
|
+
}
|
|
222
|
+
const expressions = flattenSetExpression({
|
|
223
|
+
_type: "Set",
|
|
224
|
+
operator: "&&",
|
|
225
|
+
operands: operands.map(wrapPrimitive)
|
|
226
|
+
}).operands;
|
|
227
|
+
if (hasUnresolvableExpression(...expressions)) {
|
|
228
|
+
return unresolvableExpression;
|
|
229
|
+
}
|
|
230
|
+
let isStaticFalse = false;
|
|
231
|
+
const nonTrivialExpression = expressions.filter(expression => {
|
|
232
|
+
if (isFalse(expression)) {
|
|
233
|
+
isStaticFalse = true;
|
|
234
|
+
}
|
|
235
|
+
return !isConstant(expression);
|
|
236
|
+
});
|
|
237
|
+
if (isStaticFalse) {
|
|
238
|
+
return constant(false);
|
|
239
|
+
} else if (nonTrivialExpression.length === 0) {
|
|
240
|
+
// Resolve the constant then
|
|
241
|
+
const isValid = expressions.reduce((result, expression) => result && isTrue(expression), true);
|
|
242
|
+
return constant(isValid);
|
|
243
|
+
} else if (nonTrivialExpression.length === 1) {
|
|
244
|
+
return nonTrivialExpression[0];
|
|
245
|
+
} else if (hasOppositeExpressions(nonTrivialExpression)) {
|
|
246
|
+
return constant(false);
|
|
247
|
+
} else {
|
|
248
|
+
return {
|
|
249
|
+
_type: "Set",
|
|
250
|
+
operator: "&&",
|
|
251
|
+
operands: nonTrivialExpression
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Logical `or` expression.
|
|
258
|
+
*
|
|
259
|
+
* The expression is simplified to true if this can be decided statically (that is, if one operand is a constant
|
|
260
|
+
* true or if the expression contains an operand and its negation).
|
|
261
|
+
*
|
|
262
|
+
* @param operands Expressions to connect by `or`
|
|
263
|
+
* @returns Expression evaluating to boolean
|
|
264
|
+
*/
|
|
265
|
+
_exports.and = and;
|
|
266
|
+
function or() {
|
|
267
|
+
for (var _len3 = arguments.length, operands = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|
268
|
+
operands[_key3] = arguments[_key3];
|
|
269
|
+
}
|
|
270
|
+
const expressions = flattenSetExpression({
|
|
271
|
+
_type: "Set",
|
|
272
|
+
operator: "||",
|
|
273
|
+
operands: operands.map(wrapPrimitive)
|
|
274
|
+
}).operands;
|
|
275
|
+
if (hasUnresolvableExpression(...expressions)) {
|
|
276
|
+
return unresolvableExpression;
|
|
277
|
+
}
|
|
278
|
+
let isStaticTrue = false;
|
|
279
|
+
const nonTrivialExpression = expressions.filter(expression => {
|
|
280
|
+
if (isTrue(expression)) {
|
|
281
|
+
isStaticTrue = true;
|
|
282
|
+
}
|
|
283
|
+
return !isConstant(expression) || expression.value;
|
|
284
|
+
});
|
|
285
|
+
if (isStaticTrue) {
|
|
286
|
+
return constant(true);
|
|
287
|
+
} else if (nonTrivialExpression.length === 0) {
|
|
288
|
+
// Resolve the constant then
|
|
289
|
+
const isValid = expressions.reduce((result, expression) => result && isTrue(expression), true);
|
|
290
|
+
return constant(isValid);
|
|
291
|
+
} else if (nonTrivialExpression.length === 1) {
|
|
292
|
+
return nonTrivialExpression[0];
|
|
293
|
+
} else if (hasOppositeExpressions(nonTrivialExpression)) {
|
|
294
|
+
return constant(true);
|
|
295
|
+
} else {
|
|
296
|
+
return {
|
|
297
|
+
_type: "Set",
|
|
298
|
+
operator: "||",
|
|
299
|
+
operands: nonTrivialExpression
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Logical `not` operator.
|
|
306
|
+
*
|
|
307
|
+
* @param operand The expression to reverse
|
|
308
|
+
* @returns The resulting expression that evaluates to boolean
|
|
309
|
+
*/
|
|
310
|
+
_exports.or = or;
|
|
311
|
+
function not(operand) {
|
|
312
|
+
operand = wrapPrimitive(operand);
|
|
313
|
+
if (hasUnresolvableExpression(operand)) {
|
|
314
|
+
return unresolvableExpression;
|
|
315
|
+
} else if (isConstant(operand)) {
|
|
316
|
+
return constant(!operand.value);
|
|
317
|
+
} else if (typeof operand === "object" && operand._type === "Set" && operand.operator === "||" && operand.operands.every(expression => isConstant(expression) || isComparison(expression))) {
|
|
318
|
+
return and(...operand.operands.map(expression => not(expression)));
|
|
319
|
+
} else if (typeof operand === "object" && operand._type === "Set" && operand.operator === "&&" && operand.operands.every(expression => isConstant(expression) || isComparison(expression))) {
|
|
320
|
+
return or(...operand.operands.map(expression => not(expression)));
|
|
321
|
+
} else if (isComparison(operand)) {
|
|
322
|
+
// Create the reverse comparison
|
|
323
|
+
switch (operand.operator) {
|
|
324
|
+
case "!==":
|
|
325
|
+
return {
|
|
326
|
+
...operand,
|
|
327
|
+
operator: "==="
|
|
328
|
+
};
|
|
329
|
+
case "<":
|
|
330
|
+
return {
|
|
331
|
+
...operand,
|
|
332
|
+
operator: ">="
|
|
333
|
+
};
|
|
334
|
+
case "<=":
|
|
335
|
+
return {
|
|
336
|
+
...operand,
|
|
337
|
+
operator: ">"
|
|
338
|
+
};
|
|
339
|
+
case "===":
|
|
340
|
+
return {
|
|
341
|
+
...operand,
|
|
342
|
+
operator: "!=="
|
|
343
|
+
};
|
|
344
|
+
case ">":
|
|
345
|
+
return {
|
|
346
|
+
...operand,
|
|
347
|
+
operator: "<="
|
|
348
|
+
};
|
|
349
|
+
case ">=":
|
|
350
|
+
return {
|
|
351
|
+
...operand,
|
|
352
|
+
operator: "<"
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
} else if (operand._type === "Not") {
|
|
356
|
+
return operand.operand;
|
|
357
|
+
}
|
|
358
|
+
return {
|
|
359
|
+
_type: "Not",
|
|
360
|
+
operand: operand
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Evaluates whether a binding expression is equal to true with a loose equality.
|
|
366
|
+
*
|
|
367
|
+
* @param operand The expression to check
|
|
368
|
+
* @returns The resulting expression that evaluates to boolean
|
|
369
|
+
*/
|
|
370
|
+
_exports.not = not;
|
|
371
|
+
function isTruthy(operand) {
|
|
372
|
+
if (isConstant(operand)) {
|
|
373
|
+
return constant(!!operand.value);
|
|
374
|
+
} else {
|
|
375
|
+
return {
|
|
376
|
+
_type: "Truthy",
|
|
377
|
+
operand: operand
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Creates a binding expression that will be evaluated by the corresponding model.
|
|
384
|
+
*
|
|
385
|
+
* @param path
|
|
386
|
+
* @param modelName
|
|
387
|
+
* @param visitedNavigationPaths
|
|
388
|
+
* @param pathVisitor
|
|
389
|
+
* @returns An expression representating that path in the model
|
|
390
|
+
* @deprecated use pathInModel instead
|
|
391
|
+
*/
|
|
392
|
+
_exports.isTruthy = isTruthy;
|
|
393
|
+
function bindingExpression(path, modelName) {
|
|
394
|
+
let visitedNavigationPaths = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
395
|
+
let pathVisitor = arguments.length > 3 ? arguments[3] : undefined;
|
|
396
|
+
return pathInModel(path, modelName, visitedNavigationPaths, pathVisitor);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Creates a binding expression that will be evaluated by the corresponding model.
|
|
401
|
+
*
|
|
402
|
+
* @template TargetType
|
|
403
|
+
* @param path The path on the model
|
|
404
|
+
* @param [modelName] The name of the model
|
|
405
|
+
* @param [visitedNavigationPaths] The paths from the root entitySet
|
|
406
|
+
* @param [pathVisitor] A function to modify the resulting path
|
|
407
|
+
* @returns An expression representating that path in the model
|
|
408
|
+
*/
|
|
409
|
+
_exports.bindingExpression = bindingExpression;
|
|
410
|
+
function pathInModel(path, modelName) {
|
|
411
|
+
let visitedNavigationPaths = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
412
|
+
let pathVisitor = arguments.length > 3 ? arguments[3] : undefined;
|
|
413
|
+
if (path === undefined) {
|
|
414
|
+
return unresolvableExpression;
|
|
415
|
+
}
|
|
416
|
+
let targetPath;
|
|
417
|
+
if (pathVisitor) {
|
|
418
|
+
targetPath = pathVisitor(path);
|
|
419
|
+
if (targetPath === undefined) {
|
|
420
|
+
return unresolvableExpression;
|
|
421
|
+
}
|
|
422
|
+
} else {
|
|
423
|
+
const localPath = visitedNavigationPaths.concat();
|
|
424
|
+
localPath.push(path);
|
|
425
|
+
targetPath = localPath.join("/");
|
|
426
|
+
}
|
|
427
|
+
return {
|
|
428
|
+
_type: "PathInModel",
|
|
429
|
+
modelName: modelName,
|
|
430
|
+
path: targetPath
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
_exports.pathInModel = pathInModel;
|
|
434
|
+
/**
|
|
435
|
+
* Creates a constant expression based on a primitive value.
|
|
436
|
+
*
|
|
437
|
+
* @template T
|
|
438
|
+
* @param value The constant to wrap in an expression
|
|
439
|
+
* @returns The constant expression
|
|
440
|
+
*/
|
|
441
|
+
function constant(value) {
|
|
442
|
+
let constantValue;
|
|
443
|
+
if (typeof value === "object" && value !== null && value !== undefined) {
|
|
444
|
+
if (Array.isArray(value)) {
|
|
445
|
+
constantValue = value.map(wrapPrimitive);
|
|
446
|
+
} else if (isPrimitiveObject(value)) {
|
|
447
|
+
constantValue = value.valueOf();
|
|
448
|
+
} else {
|
|
449
|
+
constantValue = Object.entries(value).reduce((plainExpression, _ref) => {
|
|
450
|
+
let [key, val] = _ref;
|
|
451
|
+
const wrappedValue = wrapPrimitive(val);
|
|
452
|
+
if (wrappedValue._type !== "Constant" || wrappedValue.value !== undefined) {
|
|
453
|
+
plainExpression[key] = wrappedValue;
|
|
454
|
+
}
|
|
455
|
+
return plainExpression;
|
|
456
|
+
}, {});
|
|
457
|
+
}
|
|
458
|
+
} else {
|
|
459
|
+
constantValue = value;
|
|
460
|
+
}
|
|
461
|
+
return {
|
|
462
|
+
_type: "Constant",
|
|
463
|
+
value: constantValue
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
_exports.constant = constant;
|
|
467
|
+
function resolveBindingString(value, targetType) {
|
|
468
|
+
if (value !== undefined && typeof value === "string" && value.startsWith("{")) {
|
|
469
|
+
const pathInModelRegex = /^{(.*)>(.+)}$/; // Matches model paths like "model>path" or ">path" (default model)
|
|
470
|
+
const pathInModelRegexMatch = pathInModelRegex.exec(value);
|
|
471
|
+
if (value.startsWith("{=")) {
|
|
472
|
+
// Expression binding, we can just remove the outer binding things
|
|
473
|
+
return {
|
|
474
|
+
_type: "EmbeddedExpressionBinding",
|
|
475
|
+
value: value
|
|
476
|
+
};
|
|
477
|
+
} else if (pathInModelRegexMatch) {
|
|
478
|
+
return pathInModel(pathInModelRegexMatch[2] || "", pathInModelRegexMatch[1] || undefined);
|
|
479
|
+
} else {
|
|
480
|
+
return {
|
|
481
|
+
_type: "EmbeddedBinding",
|
|
482
|
+
value: value
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
} else if (targetType === "boolean" && typeof value === "string" && (value === "true" || value === "false")) {
|
|
486
|
+
return constant(value === "true");
|
|
487
|
+
} else if (targetType === "number" && typeof value === "string" && (!isNaN(Number(value)) || value === "NaN")) {
|
|
488
|
+
return constant(Number(value));
|
|
489
|
+
} else {
|
|
490
|
+
return constant(value);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* A named reference.
|
|
496
|
+
*
|
|
497
|
+
* @see fn
|
|
498
|
+
* @param reference Reference
|
|
499
|
+
* @returns The object reference binding part
|
|
500
|
+
*/
|
|
501
|
+
_exports.resolveBindingString = resolveBindingString;
|
|
502
|
+
function ref(reference) {
|
|
503
|
+
return {
|
|
504
|
+
_type: "Ref",
|
|
505
|
+
ref: reference
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Wrap a primitive into a constant expression if it is not already an expression.
|
|
511
|
+
*
|
|
512
|
+
* @template T
|
|
513
|
+
* @param something The object to wrap in a Constant expression
|
|
514
|
+
* @returns Either the original object or the wrapped one depending on the case
|
|
515
|
+
*/
|
|
516
|
+
_exports.ref = ref;
|
|
517
|
+
function wrapPrimitive(something) {
|
|
518
|
+
if (isBindingToolkitExpression(something)) {
|
|
519
|
+
return something;
|
|
520
|
+
}
|
|
521
|
+
return constant(something);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Checks if the expression or value provided is a binding tooling expression or not.
|
|
526
|
+
*
|
|
527
|
+
* Every object having a property named `_type` of some value is considered an expression, even if there is actually
|
|
528
|
+
* no such expression type supported.
|
|
529
|
+
*
|
|
530
|
+
* @param expression
|
|
531
|
+
* @returns `true` if the expression is a binding toolkit expression
|
|
532
|
+
*/
|
|
533
|
+
_exports.wrapPrimitive = wrapPrimitive;
|
|
534
|
+
function isBindingToolkitExpression(expression) {
|
|
535
|
+
return (expression === null || expression === void 0 ? void 0 : expression._type) !== undefined;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Checks if the expression or value provided is constant or not.
|
|
540
|
+
*
|
|
541
|
+
* @template T The target type
|
|
542
|
+
* @param maybeConstant The expression or primitive value that is to be checked
|
|
543
|
+
* @returns `true` if it is constant
|
|
544
|
+
*/
|
|
545
|
+
_exports.isBindingToolkitExpression = isBindingToolkitExpression;
|
|
546
|
+
function isConstant(maybeConstant) {
|
|
547
|
+
return typeof maybeConstant !== "object" || maybeConstant._type === "Constant";
|
|
548
|
+
}
|
|
549
|
+
_exports.isConstant = isConstant;
|
|
550
|
+
function isTrue(expression) {
|
|
551
|
+
return isConstant(expression) && expression.value === true;
|
|
552
|
+
}
|
|
553
|
+
function isFalse(expression) {
|
|
554
|
+
return isConstant(expression) && expression.value === false;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Checks if the expression or value provided is a path in model expression or not.
|
|
559
|
+
*
|
|
560
|
+
* @template T The target type
|
|
561
|
+
* @param maybeBinding The expression or primitive value that is to be checked
|
|
562
|
+
* @returns `true` if it is a path in model expression
|
|
563
|
+
*/
|
|
564
|
+
function isPathInModelExpression(maybeBinding) {
|
|
565
|
+
return (maybeBinding === null || maybeBinding === void 0 ? void 0 : maybeBinding._type) === "PathInModel";
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Checks if the expression or value provided is a complex type expression.
|
|
570
|
+
*
|
|
571
|
+
* @template T The target type
|
|
572
|
+
* @param maybeBinding The expression or primitive value that is to be checked
|
|
573
|
+
* @returns `true` if it is a path in model expression
|
|
574
|
+
*/
|
|
575
|
+
_exports.isPathInModelExpression = isPathInModelExpression;
|
|
576
|
+
function isComplexTypeExpression(maybeBinding) {
|
|
577
|
+
return (maybeBinding === null || maybeBinding === void 0 ? void 0 : maybeBinding._type) === "ComplexType";
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Checks if the expression or value provided is a concat expression or not.
|
|
582
|
+
*
|
|
583
|
+
* @param expression
|
|
584
|
+
* @returns `true` if the expression is a ConcatExpression
|
|
585
|
+
*/
|
|
586
|
+
_exports.isComplexTypeExpression = isComplexTypeExpression;
|
|
587
|
+
function isConcatExpression(expression) {
|
|
588
|
+
return (expression === null || expression === void 0 ? void 0 : expression._type) === "Concat";
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* Checks if the expression or value provided is a IfElse expression or not.
|
|
593
|
+
*
|
|
594
|
+
* @param expression
|
|
595
|
+
* @returns `true` if the expression is a IfElseExpression
|
|
596
|
+
*/
|
|
597
|
+
function isIfElseExpression(expression) {
|
|
598
|
+
return (expression === null || expression === void 0 ? void 0 : expression._type) === "IfElse";
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* Checks if the expression provided is a comparison or not.
|
|
603
|
+
*
|
|
604
|
+
* @template T The target type
|
|
605
|
+
* @param expression The expression
|
|
606
|
+
* @returns `true` if the expression is a ComparisonExpression
|
|
607
|
+
*/
|
|
608
|
+
function isComparison(expression) {
|
|
609
|
+
return expression._type === "Comparison";
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Checks whether the input parameter is a constant expression of type undefined.
|
|
614
|
+
*
|
|
615
|
+
* @param expression The input expression or object in general
|
|
616
|
+
* @returns `true` if the input is constant which has undefined for value
|
|
617
|
+
*/
|
|
618
|
+
function isUndefinedExpression(expression) {
|
|
619
|
+
const expressionAsExpression = expression;
|
|
620
|
+
return (expressionAsExpression === null || expressionAsExpression === void 0 ? void 0 : expressionAsExpression._type) === "Constant" && (expressionAsExpression === null || expressionAsExpression === void 0 ? void 0 : expressionAsExpression.value) === undefined;
|
|
621
|
+
}
|
|
622
|
+
_exports.isUndefinedExpression = isUndefinedExpression;
|
|
623
|
+
function isPrimitiveObject(objectType) {
|
|
624
|
+
switch (objectType.constructor.name) {
|
|
625
|
+
case "String":
|
|
626
|
+
case "Number":
|
|
627
|
+
case "Boolean":
|
|
628
|
+
return true;
|
|
629
|
+
default:
|
|
630
|
+
return false;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Check if the passed annotation annotationValue is a ComplexAnnotationExpression.
|
|
635
|
+
*
|
|
636
|
+
* @template T The target type
|
|
637
|
+
* @param annotationValue The annotation annotationValue to evaluate
|
|
638
|
+
* @returns `true` if the object is a {ComplexAnnotationExpression}
|
|
639
|
+
*/
|
|
640
|
+
function isComplexAnnotationExpression(annotationValue) {
|
|
641
|
+
return typeof annotationValue === "object" && !isPrimitiveObject(annotationValue);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Generate the corresponding annotationValue for a given annotation annotationValue.
|
|
646
|
+
*
|
|
647
|
+
* @template T The target type
|
|
648
|
+
* @param annotationValue The source annotation annotationValue
|
|
649
|
+
* @param visitedNavigationPaths The path from the root entity set
|
|
650
|
+
* @param defaultValue Default value if the annotationValue is undefined
|
|
651
|
+
* @param pathVisitor A function to modify the resulting path
|
|
652
|
+
* @returns The annotationValue equivalent to that annotation annotationValue
|
|
653
|
+
*/
|
|
654
|
+
function getExpressionFromAnnotation(annotationValue) {
|
|
655
|
+
var _annotationValue;
|
|
656
|
+
let visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
657
|
+
let defaultValue = arguments.length > 2 ? arguments[2] : undefined;
|
|
658
|
+
let pathVisitor = arguments.length > 3 ? arguments[3] : undefined;
|
|
659
|
+
if (annotationValue === undefined) {
|
|
660
|
+
return wrapPrimitive(defaultValue);
|
|
661
|
+
}
|
|
662
|
+
annotationValue = (_annotationValue = annotationValue) === null || _annotationValue === void 0 ? void 0 : _annotationValue.valueOf();
|
|
663
|
+
if (!isComplexAnnotationExpression(annotationValue)) {
|
|
664
|
+
return constant(annotationValue);
|
|
665
|
+
}
|
|
666
|
+
switch (annotationValue.type) {
|
|
667
|
+
case "Path":
|
|
668
|
+
return pathInModel(annotationValue.path, undefined, visitedNavigationPaths, pathVisitor);
|
|
669
|
+
case "If":
|
|
670
|
+
return annotationIfExpression(annotationValue.If, visitedNavigationPaths, pathVisitor);
|
|
671
|
+
case "Not":
|
|
672
|
+
return not(parseAnnotationCondition(annotationValue.Not, visitedNavigationPaths, pathVisitor));
|
|
673
|
+
case "Eq":
|
|
674
|
+
return equal(parseAnnotationCondition(annotationValue.Eq[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Eq[1], visitedNavigationPaths, pathVisitor));
|
|
675
|
+
case "Ne":
|
|
676
|
+
return notEqual(parseAnnotationCondition(annotationValue.Ne[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Ne[1], visitedNavigationPaths, pathVisitor));
|
|
677
|
+
case "Gt":
|
|
678
|
+
return greaterThan(parseAnnotationCondition(annotationValue.Gt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Gt[1], visitedNavigationPaths, pathVisitor));
|
|
679
|
+
case "Ge":
|
|
680
|
+
return greaterOrEqual(parseAnnotationCondition(annotationValue.Ge[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Ge[1], visitedNavigationPaths, pathVisitor));
|
|
681
|
+
case "Lt":
|
|
682
|
+
return lessThan(parseAnnotationCondition(annotationValue.Lt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Lt[1], visitedNavigationPaths, pathVisitor));
|
|
683
|
+
case "Le":
|
|
684
|
+
return lessOrEqual(parseAnnotationCondition(annotationValue.Le[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Le[1], visitedNavigationPaths, pathVisitor));
|
|
685
|
+
case "Or":
|
|
686
|
+
return or(...annotationValue.Or.map(function (orCondition) {
|
|
687
|
+
return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
|
|
688
|
+
}));
|
|
689
|
+
case "And":
|
|
690
|
+
return and(...annotationValue.And.map(function (andCondition) {
|
|
691
|
+
return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
|
|
692
|
+
}));
|
|
693
|
+
case "Apply":
|
|
694
|
+
return annotationApplyExpression(annotationValue, visitedNavigationPaths, pathVisitor);
|
|
695
|
+
}
|
|
696
|
+
return unresolvableExpression;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Parse the annotation condition into an expression.
|
|
701
|
+
*
|
|
702
|
+
* @template T The target type
|
|
703
|
+
* @param annotationValue The condition or value from the annotation
|
|
704
|
+
* @param visitedNavigationPaths The path from the root entity set
|
|
705
|
+
* @param pathVisitor A function to modify the resulting path
|
|
706
|
+
* @returns An equivalent expression
|
|
707
|
+
*/
|
|
708
|
+
_exports.getExpressionFromAnnotation = getExpressionFromAnnotation;
|
|
709
|
+
function parseAnnotationCondition(annotationValue) {
|
|
710
|
+
let visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
711
|
+
let pathVisitor = arguments.length > 2 ? arguments[2] : undefined;
|
|
712
|
+
if (annotationValue === null || typeof annotationValue !== "object") {
|
|
713
|
+
return constant(annotationValue);
|
|
714
|
+
} else if (annotationValue.hasOwnProperty("$Or")) {
|
|
715
|
+
return or(...annotationValue.$Or.map(function (orCondition) {
|
|
716
|
+
return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
|
|
717
|
+
}));
|
|
718
|
+
} else if (annotationValue.hasOwnProperty("$And")) {
|
|
719
|
+
return and(...annotationValue.$And.map(function (andCondition) {
|
|
720
|
+
return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
|
|
721
|
+
}));
|
|
722
|
+
} else if (annotationValue.hasOwnProperty("$Not")) {
|
|
723
|
+
return not(parseAnnotationCondition(annotationValue.$Not, visitedNavigationPaths, pathVisitor));
|
|
724
|
+
} else if (annotationValue.hasOwnProperty("$Eq")) {
|
|
725
|
+
return equal(parseAnnotationCondition(annotationValue.$Eq[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Eq[1], visitedNavigationPaths, pathVisitor));
|
|
726
|
+
} else if (annotationValue.hasOwnProperty("$Ne")) {
|
|
727
|
+
return notEqual(parseAnnotationCondition(annotationValue.$Ne[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Ne[1], visitedNavigationPaths, pathVisitor));
|
|
728
|
+
} else if (annotationValue.hasOwnProperty("$Gt")) {
|
|
729
|
+
return greaterThan(parseAnnotationCondition(annotationValue.$Gt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Gt[1], visitedNavigationPaths, pathVisitor));
|
|
730
|
+
} else if (annotationValue.hasOwnProperty("$Ge")) {
|
|
731
|
+
return greaterOrEqual(parseAnnotationCondition(annotationValue.$Ge[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Ge[1], visitedNavigationPaths, pathVisitor));
|
|
732
|
+
} else if (annotationValue.hasOwnProperty("$Lt")) {
|
|
733
|
+
return lessThan(parseAnnotationCondition(annotationValue.$Lt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Lt[1], visitedNavigationPaths, pathVisitor));
|
|
734
|
+
} else if (annotationValue.hasOwnProperty("$Le")) {
|
|
735
|
+
return lessOrEqual(parseAnnotationCondition(annotationValue.$Le[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Le[1], visitedNavigationPaths, pathVisitor));
|
|
736
|
+
} else if (annotationValue.hasOwnProperty("$Path")) {
|
|
737
|
+
return pathInModel(annotationValue.$Path, undefined, visitedNavigationPaths, pathVisitor);
|
|
738
|
+
} else if (annotationValue.hasOwnProperty("$Apply")) {
|
|
739
|
+
return getExpressionFromAnnotation({
|
|
740
|
+
type: "Apply",
|
|
741
|
+
Function: annotationValue.$Function,
|
|
742
|
+
Apply: annotationValue.$Apply
|
|
743
|
+
}, visitedNavigationPaths, undefined, pathVisitor);
|
|
744
|
+
} else if (annotationValue.hasOwnProperty("$If")) {
|
|
745
|
+
return getExpressionFromAnnotation({
|
|
746
|
+
type: "If",
|
|
747
|
+
If: annotationValue.$If
|
|
748
|
+
}, visitedNavigationPaths, undefined, pathVisitor);
|
|
749
|
+
} else if (annotationValue.hasOwnProperty("$EnumMember")) {
|
|
750
|
+
return constant(resolveEnumValue(annotationValue.$EnumMember));
|
|
751
|
+
}
|
|
752
|
+
return constant(false);
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
/**
|
|
756
|
+
* Process the {IfAnnotationExpressionValue} into an expression.
|
|
757
|
+
*
|
|
758
|
+
* @template T The target type
|
|
759
|
+
* @param annotationValue An If expression returning the type T
|
|
760
|
+
* @param visitedNavigationPaths The path from the root entity set
|
|
761
|
+
* @param pathVisitor A function to modify the resulting path
|
|
762
|
+
* @returns The equivalent ifElse expression
|
|
763
|
+
*/
|
|
764
|
+
function annotationIfExpression(annotationValue) {
|
|
765
|
+
let visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
766
|
+
let pathVisitor = arguments.length > 2 ? arguments[2] : undefined;
|
|
767
|
+
return ifElse(parseAnnotationCondition(annotationValue[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue[1], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue[2], visitedNavigationPaths, pathVisitor));
|
|
768
|
+
}
|
|
769
|
+
// This type is not recursively transformed from the metamodel content, as such we have some ugly things there
|
|
770
|
+
_exports.annotationIfExpression = annotationIfExpression;
|
|
771
|
+
function convertSubApplyParameters(applyParam) {
|
|
772
|
+
let applyParamConverted = applyParam;
|
|
773
|
+
if (applyParam.hasOwnProperty("$Path")) {
|
|
774
|
+
applyParamConverted = {
|
|
775
|
+
type: "Path",
|
|
776
|
+
path: applyParam.$Path
|
|
777
|
+
};
|
|
778
|
+
} else if (applyParam.hasOwnProperty("$If")) {
|
|
779
|
+
applyParamConverted = {
|
|
780
|
+
type: "If",
|
|
781
|
+
If: applyParam.$If
|
|
782
|
+
};
|
|
783
|
+
} else if (applyParam.hasOwnProperty("$Apply")) {
|
|
784
|
+
applyParamConverted = {
|
|
785
|
+
type: "Apply",
|
|
786
|
+
Function: applyParam.$Function,
|
|
787
|
+
Apply: applyParam.$Apply
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
return applyParamConverted;
|
|
791
|
+
}
|
|
792
|
+
function annotationApplyExpression(applyExpression) {
|
|
793
|
+
let visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
794
|
+
let pathVisitor = arguments.length > 2 ? arguments[2] : undefined;
|
|
795
|
+
switch (applyExpression.Function) {
|
|
796
|
+
case "odata.concat":
|
|
797
|
+
return concat(...applyExpression.Apply.map(applyParam => {
|
|
798
|
+
return getExpressionFromAnnotation(convertSubApplyParameters(applyParam), visitedNavigationPaths, undefined, pathVisitor);
|
|
799
|
+
}));
|
|
800
|
+
case "odata.uriEncode":
|
|
801
|
+
const parameter = getExpressionFromAnnotation(convertSubApplyParameters(applyExpression.Apply[0]), visitedNavigationPaths, undefined, pathVisitor);
|
|
802
|
+
// The second parameter for uriEncode is always a string since the target evaluation is against a formatValue call in ODataUtils which expect the target type as second parameter
|
|
803
|
+
return fn("odata.uriEncode", [parameter, "Edm.String"], undefined, true);
|
|
804
|
+
case "odata.fillUriTemplate":
|
|
805
|
+
const template = applyExpression.Apply[0];
|
|
806
|
+
const templateParams = applyExpression.Apply.slice(1);
|
|
807
|
+
const targetObject = {};
|
|
808
|
+
templateParams.forEach(applyParam => {
|
|
809
|
+
targetObject[applyParam.$Name] = getExpressionFromAnnotation(convertSubApplyParameters(applyParam.$LabeledElement), visitedNavigationPaths, undefined, pathVisitor);
|
|
810
|
+
});
|
|
811
|
+
return fn("odata.fillUriTemplate", [template, targetObject], undefined, true);
|
|
812
|
+
}
|
|
813
|
+
return unresolvableExpression;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
/**
|
|
817
|
+
* Generic helper for the comparison operations (equal, notEqual, ...).
|
|
818
|
+
*
|
|
819
|
+
* @template T The target type
|
|
820
|
+
* @param operator The operator to apply
|
|
821
|
+
* @param leftOperand The operand on the left side of the operator
|
|
822
|
+
* @param rightOperand The operand on the right side of the operator
|
|
823
|
+
* @returns An expression representing the comparison
|
|
824
|
+
*/
|
|
825
|
+
_exports.annotationApplyExpression = annotationApplyExpression;
|
|
826
|
+
function comparison(operator, leftOperand, rightOperand) {
|
|
827
|
+
const leftExpression = wrapPrimitive(leftOperand);
|
|
828
|
+
const rightExpression = wrapPrimitive(rightOperand);
|
|
829
|
+
if (hasUnresolvableExpression(leftExpression, rightExpression)) {
|
|
830
|
+
return unresolvableExpression;
|
|
831
|
+
}
|
|
832
|
+
if (isConstant(leftExpression) && isConstant(rightExpression)) {
|
|
833
|
+
switch (operator) {
|
|
834
|
+
case "!==":
|
|
835
|
+
return constant(leftExpression.value !== rightExpression.value);
|
|
836
|
+
case "===":
|
|
837
|
+
return constant(leftExpression.value === rightExpression.value);
|
|
838
|
+
case "<":
|
|
839
|
+
if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
|
|
840
|
+
return constant(false);
|
|
841
|
+
}
|
|
842
|
+
return constant(leftExpression.value < rightExpression.value);
|
|
843
|
+
case "<=":
|
|
844
|
+
if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
|
|
845
|
+
return constant(false);
|
|
846
|
+
}
|
|
847
|
+
return constant(leftExpression.value <= rightExpression.value);
|
|
848
|
+
case ">":
|
|
849
|
+
if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
|
|
850
|
+
return constant(false);
|
|
851
|
+
}
|
|
852
|
+
return constant(leftExpression.value > rightExpression.value);
|
|
853
|
+
case ">=":
|
|
854
|
+
if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
|
|
855
|
+
return constant(false);
|
|
856
|
+
}
|
|
857
|
+
return constant(leftExpression.value >= rightExpression.value);
|
|
858
|
+
}
|
|
859
|
+
} else {
|
|
860
|
+
return {
|
|
861
|
+
_type: "Comparison",
|
|
862
|
+
operator: operator,
|
|
863
|
+
operand1: leftExpression,
|
|
864
|
+
operand2: rightExpression
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* Generic helper for the length of an expression.
|
|
871
|
+
*
|
|
872
|
+
* @param expression The input expression pointing to an array
|
|
873
|
+
* @param checkUndefined Is the array potentially undefined
|
|
874
|
+
* @returns An expression representing the length
|
|
875
|
+
*/
|
|
876
|
+
function length(expression) {
|
|
877
|
+
let checkUndefined = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
878
|
+
if (expression._type === "Unresolvable") {
|
|
879
|
+
return expression;
|
|
880
|
+
}
|
|
881
|
+
if (!checkUndefined) {
|
|
882
|
+
return {
|
|
883
|
+
_type: "Length",
|
|
884
|
+
pathInModel: expression
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
return ifElse(equal(expression, undefined), -1, length(expression));
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
/**
|
|
891
|
+
* Comparison: "equal" (===).
|
|
892
|
+
*
|
|
893
|
+
* @template T The target type
|
|
894
|
+
* @param leftOperand The operand on the left side
|
|
895
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
896
|
+
* @returns An expression representing the comparison
|
|
897
|
+
*/
|
|
898
|
+
_exports.length = length;
|
|
899
|
+
function equal(leftOperand, rightOperand) {
|
|
900
|
+
const leftExpression = wrapPrimitive(leftOperand);
|
|
901
|
+
const rightExpression = wrapPrimitive(rightOperand);
|
|
902
|
+
if (hasUnresolvableExpression(leftExpression, rightExpression)) {
|
|
903
|
+
return unresolvableExpression;
|
|
904
|
+
}
|
|
905
|
+
if (_checkExpressionsAreEqual(leftExpression, rightExpression)) {
|
|
906
|
+
return constant(true);
|
|
907
|
+
}
|
|
908
|
+
function reduce(left, right) {
|
|
909
|
+
if (left._type === "Comparison" && isTrue(right)) {
|
|
910
|
+
// compare(a, b) === true ~~> compare(a, b)
|
|
911
|
+
return left;
|
|
912
|
+
} else if (left._type === "Comparison" && isFalse(right)) {
|
|
913
|
+
// compare(a, b) === false ~~> !compare(a, b)
|
|
914
|
+
return not(left);
|
|
915
|
+
} else if (left._type === "IfElse" && _checkExpressionsAreEqual(left.onTrue, right)) {
|
|
916
|
+
// (if (x) { a } else { b }) === a ~~> x || (b === a)
|
|
917
|
+
return or(left.condition, equal(left.onFalse, right));
|
|
918
|
+
} else if (left._type === "IfElse" && _checkExpressionsAreEqual(left.onFalse, right)) {
|
|
919
|
+
// (if (x) { a } else { b }) === b ~~> !x || (a === b)
|
|
920
|
+
return or(not(left.condition), equal(left.onTrue, right));
|
|
921
|
+
} else if (left._type === "IfElse" && isConstant(left.onTrue) && isConstant(left.onFalse) && isConstant(right) && !_checkExpressionsAreEqual(left.onTrue, right) && !_checkExpressionsAreEqual(left.onFalse, right)) {
|
|
922
|
+
return constant(false);
|
|
923
|
+
}
|
|
924
|
+
return undefined;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
// exploit symmetry: a === b <~> b === a
|
|
928
|
+
const reduced = reduce(leftExpression, rightExpression) ?? reduce(rightExpression, leftExpression);
|
|
929
|
+
return reduced ?? comparison("===", leftExpression, rightExpression);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
/**
|
|
933
|
+
* Comparison: "not equal" (!==).
|
|
934
|
+
*
|
|
935
|
+
* @template T The target type
|
|
936
|
+
* @param leftOperand The operand on the left side
|
|
937
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
938
|
+
* @returns An expression representing the comparison
|
|
939
|
+
*/
|
|
940
|
+
_exports.equal = equal;
|
|
941
|
+
function notEqual(leftOperand, rightOperand) {
|
|
942
|
+
return not(equal(leftOperand, rightOperand));
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
/**
|
|
946
|
+
* Comparison: "greater or equal" (>=).
|
|
947
|
+
*
|
|
948
|
+
* @template T The target type
|
|
949
|
+
* @param leftOperand The operand on the left side
|
|
950
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
951
|
+
* @returns An expression representing the comparison
|
|
952
|
+
*/
|
|
953
|
+
_exports.notEqual = notEqual;
|
|
954
|
+
function greaterOrEqual(leftOperand, rightOperand) {
|
|
955
|
+
return comparison(">=", leftOperand, rightOperand);
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
/**
|
|
959
|
+
* Comparison: "greater than" (>).
|
|
960
|
+
*
|
|
961
|
+
* @template T The target type
|
|
962
|
+
* @param leftOperand The operand on the left side
|
|
963
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
964
|
+
* @returns An expression representing the comparison
|
|
965
|
+
*/
|
|
966
|
+
_exports.greaterOrEqual = greaterOrEqual;
|
|
967
|
+
function greaterThan(leftOperand, rightOperand) {
|
|
968
|
+
return comparison(">", leftOperand, rightOperand);
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
/**
|
|
972
|
+
* Comparison: "less or equal" (<=).
|
|
973
|
+
*
|
|
974
|
+
* @template T The target type
|
|
975
|
+
* @param leftOperand The operand on the left side
|
|
976
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
977
|
+
* @returns An expression representing the comparison
|
|
978
|
+
*/
|
|
979
|
+
_exports.greaterThan = greaterThan;
|
|
980
|
+
function lessOrEqual(leftOperand, rightOperand) {
|
|
981
|
+
return comparison("<=", leftOperand, rightOperand);
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
/**
|
|
985
|
+
* Comparison: "less than" (<).
|
|
986
|
+
*
|
|
987
|
+
* @template T The target type
|
|
988
|
+
* @param leftOperand The operand on the left side
|
|
989
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
990
|
+
* @returns An expression representing the comparison
|
|
991
|
+
*/
|
|
992
|
+
_exports.lessOrEqual = lessOrEqual;
|
|
993
|
+
function lessThan(leftOperand, rightOperand) {
|
|
994
|
+
return comparison("<", leftOperand, rightOperand);
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
/**
|
|
998
|
+
* If-then-else expression.
|
|
999
|
+
*
|
|
1000
|
+
* Evaluates to onTrue if the condition evaluates to true, else evaluates to onFalse.
|
|
1001
|
+
*
|
|
1002
|
+
* @template T The target type
|
|
1003
|
+
* @param condition The condition to evaluate
|
|
1004
|
+
* @param onTrue Expression result if the condition evaluates to true
|
|
1005
|
+
* @param onFalse Expression result if the condition evaluates to false
|
|
1006
|
+
* @returns The expression that represents this conditional check
|
|
1007
|
+
*/
|
|
1008
|
+
_exports.lessThan = lessThan;
|
|
1009
|
+
function ifElse(condition, onTrue, onFalse) {
|
|
1010
|
+
let conditionExpression = wrapPrimitive(condition);
|
|
1011
|
+
let onTrueExpression = wrapPrimitive(onTrue);
|
|
1012
|
+
let onFalseExpression = wrapPrimitive(onFalse);
|
|
1013
|
+
|
|
1014
|
+
// swap branches if the condition is a negation
|
|
1015
|
+
if (conditionExpression._type === "Not") {
|
|
1016
|
+
// ifElse(not(X), a, b) --> ifElse(X, b, a)
|
|
1017
|
+
[onTrueExpression, onFalseExpression] = [onFalseExpression, onTrueExpression];
|
|
1018
|
+
conditionExpression = not(conditionExpression);
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
// inline nested if-else expressions: onTrue branch
|
|
1022
|
+
// ifElse(X, ifElse(X, a, b), c) ==> ifElse(X, a, c)
|
|
1023
|
+
if (onTrueExpression._type === "IfElse" && _checkExpressionsAreEqual(conditionExpression, onTrueExpression.condition)) {
|
|
1024
|
+
onTrueExpression = onTrueExpression.onTrue;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
// inline nested if-else expressions: onFalse branch
|
|
1028
|
+
// ifElse(X, a, ifElse(X, b, c)) ==> ifElse(X, a, c)
|
|
1029
|
+
if (onFalseExpression._type === "IfElse" && _checkExpressionsAreEqual(conditionExpression, onFalseExpression.condition)) {
|
|
1030
|
+
onFalseExpression = onFalseExpression.onFalse;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
// (if true then a else b) ~~> a
|
|
1034
|
+
// (if false then a else b) ~~> b
|
|
1035
|
+
if (isConstant(conditionExpression)) {
|
|
1036
|
+
return conditionExpression.value ? onTrueExpression : onFalseExpression;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
// if (isConstantBoolean(onTrueExpression) || isConstantBoolean(onFalseExpression)) {
|
|
1040
|
+
// return or(and(condition, onTrueExpression as Expression<boolean>), and(not(condition), onFalseExpression as Expression<boolean>)) as Expression<T>
|
|
1041
|
+
// }
|
|
1042
|
+
|
|
1043
|
+
// (if X then a else a) ~~> a
|
|
1044
|
+
if (_checkExpressionsAreEqual(onTrueExpression, onFalseExpression)) {
|
|
1045
|
+
return onTrueExpression;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
// if X then a else false ~~> X && a
|
|
1049
|
+
if (isFalse(onFalseExpression)) {
|
|
1050
|
+
return and(conditionExpression, onTrueExpression);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
// if X then a else true ~~> !X || a
|
|
1054
|
+
if (isTrue(onFalseExpression)) {
|
|
1055
|
+
return or(not(conditionExpression), onTrueExpression);
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
// if X then false else a ~~> !X && a
|
|
1059
|
+
if (isFalse(onTrueExpression)) {
|
|
1060
|
+
return and(not(conditionExpression), onFalseExpression);
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
// if X then true else a ~~> X || a
|
|
1064
|
+
if (isTrue(onTrueExpression)) {
|
|
1065
|
+
return or(conditionExpression, onFalseExpression);
|
|
1066
|
+
}
|
|
1067
|
+
if (hasUnresolvableExpression(conditionExpression, onTrueExpression, onFalseExpression)) {
|
|
1068
|
+
return unresolvableExpression;
|
|
1069
|
+
}
|
|
1070
|
+
if (isComplexTypeExpression(condition) || isComplexTypeExpression(onTrue) || isComplexTypeExpression(onFalse)) {
|
|
1071
|
+
let pathIdx = 0;
|
|
1072
|
+
const myIfElseExpression = formatResult([condition, onTrue, onFalse], "sap.fe.core.formatters.StandardFormatter#ifElse");
|
|
1073
|
+
const allParts = [];
|
|
1074
|
+
transformRecursively(myIfElseExpression, "PathInModel", constantPath => {
|
|
1075
|
+
allParts.push(constantPath);
|
|
1076
|
+
return pathInModel(`$${pathIdx++}`, "$");
|
|
1077
|
+
}, true);
|
|
1078
|
+
allParts.unshift(constant(JSON.stringify(myIfElseExpression)));
|
|
1079
|
+
return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression", undefined, true);
|
|
1080
|
+
}
|
|
1081
|
+
return {
|
|
1082
|
+
_type: "IfElse",
|
|
1083
|
+
condition: conditionExpression,
|
|
1084
|
+
onTrue: onTrueExpression,
|
|
1085
|
+
onFalse: onFalseExpression
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
/**
|
|
1090
|
+
* Checks whether the current expression has a reference to the default model (undefined).
|
|
1091
|
+
*
|
|
1092
|
+
* @param expression The expression to evaluate
|
|
1093
|
+
* @returns `true` if there is a reference to the default context
|
|
1094
|
+
*/
|
|
1095
|
+
_exports.ifElse = ifElse;
|
|
1096
|
+
function hasReferenceToDefaultContext(expression) {
|
|
1097
|
+
switch (expression._type) {
|
|
1098
|
+
case "Constant":
|
|
1099
|
+
case "Formatter":
|
|
1100
|
+
case "ComplexType":
|
|
1101
|
+
return false;
|
|
1102
|
+
case "Set":
|
|
1103
|
+
return expression.operands.some(hasReferenceToDefaultContext);
|
|
1104
|
+
case "PathInModel":
|
|
1105
|
+
return expression.modelName === undefined;
|
|
1106
|
+
case "Comparison":
|
|
1107
|
+
return hasReferenceToDefaultContext(expression.operand1) || hasReferenceToDefaultContext(expression.operand2);
|
|
1108
|
+
case "IfElse":
|
|
1109
|
+
return hasReferenceToDefaultContext(expression.condition) || hasReferenceToDefaultContext(expression.onTrue) || hasReferenceToDefaultContext(expression.onFalse);
|
|
1110
|
+
case "Not":
|
|
1111
|
+
case "Truthy":
|
|
1112
|
+
return hasReferenceToDefaultContext(expression.operand);
|
|
1113
|
+
default:
|
|
1114
|
+
return false;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
// This is one case where any does make sense...
|
|
1119
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1120
|
+
|
|
1121
|
+
/**
|
|
1122
|
+
* Calls a formatter function to process the parameters.
|
|
1123
|
+
* If requireContext is set to true and no context is passed a default context will be added automatically.
|
|
1124
|
+
*
|
|
1125
|
+
* @template T
|
|
1126
|
+
* @template U
|
|
1127
|
+
* @param parameters The list of parameter that should match the type and number of the formatter function
|
|
1128
|
+
* @param formatterFunction The function to call
|
|
1129
|
+
* @param [contextEntityType] If no parameter refers to the context then we use this information to add a reference to the keys from the entity type.
|
|
1130
|
+
* @param [ignoreComplexType] Whether to ignore the transgformation to the StandardFormatter or not
|
|
1131
|
+
* @returns The corresponding expression
|
|
1132
|
+
*/
|
|
1133
|
+
function formatResult(parameters, formatterFunction, contextEntityType) {
|
|
1134
|
+
let ignoreComplexType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
1135
|
+
const parameterExpressions = parameters.map(wrapPrimitive);
|
|
1136
|
+
if (hasUnresolvableExpression(...parameterExpressions)) {
|
|
1137
|
+
return unresolvableExpression;
|
|
1138
|
+
}
|
|
1139
|
+
if (contextEntityType) {
|
|
1140
|
+
// Otherwise, if the context is required and no context is provided make sure to add the default binding
|
|
1141
|
+
if (!parameterExpressions.some(hasReferenceToDefaultContext)) {
|
|
1142
|
+
contextEntityType.keys.forEach(key => parameterExpressions.push(pathInModel(key.name, "")));
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
let functionName = "";
|
|
1146
|
+
if (typeof formatterFunction === "string") {
|
|
1147
|
+
functionName = formatterFunction;
|
|
1148
|
+
} else {
|
|
1149
|
+
functionName = formatterFunction.__functionName;
|
|
1150
|
+
}
|
|
1151
|
+
// FormatterName can be of format sap.fe.core.xxx#methodName to have multiple formatter in one class
|
|
1152
|
+
const [formatterClass, formatterName] = functionName.split("#");
|
|
1153
|
+
|
|
1154
|
+
// In some case we also cannot call directly a function because of too complex input, in that case we need to convert to a simpler function call
|
|
1155
|
+
if (!ignoreComplexType && (parameterExpressions.some(isComplexTypeExpression) || parameterExpressions.some(isConcatExpression) || parameterExpressions.some(isIfElseExpression))) {
|
|
1156
|
+
let pathIdx = 0;
|
|
1157
|
+
const myFormatExpression = formatResult(parameterExpressions, functionName, undefined, true);
|
|
1158
|
+
const allParts = [];
|
|
1159
|
+
transformRecursively(myFormatExpression, "PathInModel", constantPath => {
|
|
1160
|
+
allParts.push(constantPath);
|
|
1161
|
+
return pathInModel(`$${pathIdx++}`, "$");
|
|
1162
|
+
}, true);
|
|
1163
|
+
allParts.unshift(constant(JSON.stringify(myFormatExpression)));
|
|
1164
|
+
return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression", undefined, true);
|
|
1165
|
+
} else if (!!formatterName && formatterName.length > 0) {
|
|
1166
|
+
parameterExpressions.unshift(constant(formatterName));
|
|
1167
|
+
}
|
|
1168
|
+
return {
|
|
1169
|
+
_type: "Formatter",
|
|
1170
|
+
fn: formatterClass,
|
|
1171
|
+
parameters: parameterExpressions
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
_exports.formatResult = formatResult;
|
|
1175
|
+
function setUpConstraints(targetMapping, property) {
|
|
1176
|
+
var _targetMapping$constr, _targetMapping$constr2, _targetMapping$constr3, _targetMapping$constr4, _property$annotations, _property$annotations2, _targetMapping$constr5, _property$annotations5, _property$annotations6, _property$annotations9, _property$annotations10, _targetMapping$constr6, _targetMapping$constr7;
|
|
1177
|
+
const constraints = {};
|
|
1178
|
+
if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr = targetMapping.constraints) !== null && _targetMapping$constr !== void 0 && _targetMapping$constr.$Scale && property.scale !== undefined) {
|
|
1179
|
+
constraints.scale = property.scale;
|
|
1180
|
+
}
|
|
1181
|
+
if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr2 = targetMapping.constraints) !== null && _targetMapping$constr2 !== void 0 && _targetMapping$constr2.$Precision && property.precision !== undefined) {
|
|
1182
|
+
constraints.precision = property.precision;
|
|
1183
|
+
}
|
|
1184
|
+
if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr3 = targetMapping.constraints) !== null && _targetMapping$constr3 !== void 0 && _targetMapping$constr3.$MaxLength && property.maxLength !== undefined) {
|
|
1185
|
+
constraints.maxLength = property.maxLength;
|
|
1186
|
+
}
|
|
1187
|
+
if (property.nullable === false) {
|
|
1188
|
+
constraints.nullable = false;
|
|
1189
|
+
}
|
|
1190
|
+
if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr4 = targetMapping.constraints) !== null && _targetMapping$constr4 !== void 0 && _targetMapping$constr4["@Org.OData.Validation.V1.Minimum/$Decimal"] && !isNaN((_property$annotations = property.annotations) === null || _property$annotations === void 0 ? void 0 : (_property$annotations2 = _property$annotations.Validation) === null || _property$annotations2 === void 0 ? void 0 : _property$annotations2.Minimum)) {
|
|
1191
|
+
var _property$annotations3, _property$annotations4;
|
|
1192
|
+
constraints.minimum = `${(_property$annotations3 = property.annotations) === null || _property$annotations3 === void 0 ? void 0 : (_property$annotations4 = _property$annotations3.Validation) === null || _property$annotations4 === void 0 ? void 0 : _property$annotations4.Minimum}`;
|
|
1193
|
+
}
|
|
1194
|
+
if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr5 = targetMapping.constraints) !== null && _targetMapping$constr5 !== void 0 && _targetMapping$constr5["@Org.OData.Validation.V1.Maximum/$Decimal"] && !isNaN((_property$annotations5 = property.annotations) === null || _property$annotations5 === void 0 ? void 0 : (_property$annotations6 = _property$annotations5.Validation) === null || _property$annotations6 === void 0 ? void 0 : _property$annotations6.Maximum)) {
|
|
1195
|
+
var _property$annotations7, _property$annotations8;
|
|
1196
|
+
constraints.maximum = `${(_property$annotations7 = property.annotations) === null || _property$annotations7 === void 0 ? void 0 : (_property$annotations8 = _property$annotations7.Validation) === null || _property$annotations8 === void 0 ? void 0 : _property$annotations8.Maximum}`;
|
|
1197
|
+
}
|
|
1198
|
+
if ((_property$annotations9 = property.annotations) !== null && _property$annotations9 !== void 0 && (_property$annotations10 = _property$annotations9.Common) !== null && _property$annotations10 !== void 0 && _property$annotations10.IsDigitSequence && targetMapping.type === "sap.ui.model.odata.type.String" && targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr6 = targetMapping.constraints) !== null && _targetMapping$constr6 !== void 0 && _targetMapping$constr6["@com.sap.vocabularies.Common.v1.IsDigitSequence"]) {
|
|
1199
|
+
constraints.isDigitSequence = true;
|
|
1200
|
+
}
|
|
1201
|
+
if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr7 = targetMapping.constraints) !== null && _targetMapping$constr7 !== void 0 && _targetMapping$constr7.$V4) {
|
|
1202
|
+
constraints.V4 = true;
|
|
1203
|
+
}
|
|
1204
|
+
return constraints;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
/**
|
|
1208
|
+
* Generates the binding expression for the property, and sets up the formatOptions and constraints.
|
|
1209
|
+
*
|
|
1210
|
+
* @param property The Property for which we are setting up the binding
|
|
1211
|
+
* @param propertyBindingExpression The BindingExpression of the property above. Serves as the basis to which information can be added
|
|
1212
|
+
* @param ignoreConstraints Ignore constraints of the property
|
|
1213
|
+
* @returns The binding expression for the property with formatOptions and constraints
|
|
1214
|
+
*/
|
|
1215
|
+
_exports.setUpConstraints = setUpConstraints;
|
|
1216
|
+
function formatWithTypeInformation(property, propertyBindingExpression) {
|
|
1217
|
+
var _outExpression$type, _outExpression$constr3, _outExpression$constr4;
|
|
1218
|
+
let ignoreConstraints = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
1219
|
+
const outExpression = propertyBindingExpression;
|
|
1220
|
+
if (property._type !== "Property" && property._type !== "ActionParameter") {
|
|
1221
|
+
return outExpression;
|
|
1222
|
+
}
|
|
1223
|
+
const targetMapping = EDM_TYPE_MAPPING[property.type];
|
|
1224
|
+
if (!targetMapping) {
|
|
1225
|
+
return outExpression;
|
|
1226
|
+
}
|
|
1227
|
+
if (!outExpression.formatOptions) {
|
|
1228
|
+
outExpression.formatOptions = {};
|
|
1229
|
+
}
|
|
1230
|
+
outExpression.constraints = {};
|
|
1231
|
+
outExpression.type = targetMapping.type;
|
|
1232
|
+
if (!ignoreConstraints) {
|
|
1233
|
+
outExpression.constraints = setUpConstraints(targetMapping, property);
|
|
1234
|
+
}
|
|
1235
|
+
if ((outExpression === null || outExpression === void 0 ? void 0 : (_outExpression$type = outExpression.type) === null || _outExpression$type === void 0 ? void 0 : _outExpression$type.indexOf("sap.ui.model.odata.type.Int")) === 0 && (outExpression === null || outExpression === void 0 ? void 0 : outExpression.type) !== "sap.ui.model.odata.type.Int64" || (outExpression === null || outExpression === void 0 ? void 0 : outExpression.type) === "sap.ui.model.odata.type.Double") {
|
|
1236
|
+
outExpression.formatOptions = Object.assign(outExpression.formatOptions, {
|
|
1237
|
+
parseAsString: false
|
|
1238
|
+
});
|
|
1239
|
+
}
|
|
1240
|
+
if (outExpression.type === "sap.ui.model.odata.type.String" && isProperty(property)) {
|
|
1241
|
+
var _outExpression$constr, _outExpression$constr2;
|
|
1242
|
+
if (!((_outExpression$constr = outExpression.constraints) !== null && _outExpression$constr !== void 0 && _outExpression$constr.isDigitSequence) || ((_outExpression$constr2 = outExpression.constraints) === null || _outExpression$constr2 === void 0 ? void 0 : _outExpression$constr2.nullable) === false) {
|
|
1243
|
+
outExpression.formatOptions.parseKeepsEmptyString = true;
|
|
1244
|
+
}
|
|
1245
|
+
const fiscalType = getFiscalType(property);
|
|
1246
|
+
if (fiscalType) {
|
|
1247
|
+
outExpression.formatOptions.fiscalType = fiscalType;
|
|
1248
|
+
outExpression.type = "sap.fe.core.type.FiscalDate";
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
const typesSupportingParseEmptyValueToZero = ["sap.ui.model.odata.type.Int16", "sap.ui.model.odata.type.Int32", "sap.ui.model.odata.type.Int64", "sap.ui.model.odata.type.Single", "sap.ui.model.odata.type.Double", "sap.ui.model.odata.type.Decimal", "sap.ui.model.odata.type.Byte", "sap.ui.model.odata.type.SByte"];
|
|
1252
|
+
if (((_outExpression$constr3 = outExpression.constraints) === null || _outExpression$constr3 === void 0 ? void 0 : _outExpression$constr3.nullable) === false && outExpression.type && typesSupportingParseEmptyValueToZero.includes(outExpression.type)) {
|
|
1253
|
+
outExpression.formatOptions = Object.assign(outExpression.formatOptions, {
|
|
1254
|
+
parseEmptyValueToZero: true
|
|
1255
|
+
});
|
|
1256
|
+
}
|
|
1257
|
+
if (((_outExpression$constr4 = outExpression.constraints) === null || _outExpression$constr4 === void 0 ? void 0 : _outExpression$constr4.nullable) !== false && (outExpression.type === "sap.ui.model.odata.type.Int64" || outExpression.type === "sap.ui.model.odata.type.Decimal")) {
|
|
1258
|
+
outExpression.formatOptions = Object.assign(outExpression.formatOptions, {
|
|
1259
|
+
emptyString: ""
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
return outExpression;
|
|
1263
|
+
}
|
|
1264
|
+
_exports.formatWithTypeInformation = formatWithTypeInformation;
|
|
1265
|
+
const getFiscalType = function (property) {
|
|
1266
|
+
var _property$annotations11, _property$annotations12, _property$annotations13, _property$annotations14, _property$annotations15, _property$annotations16, _property$annotations17, _property$annotations18, _property$annotations19, _property$annotations20, _property$annotations21, _property$annotations22, _property$annotations23, _property$annotations24, _property$annotations25, _property$annotations26;
|
|
1267
|
+
if ((_property$annotations11 = property.annotations) !== null && _property$annotations11 !== void 0 && (_property$annotations12 = _property$annotations11.Common) !== null && _property$annotations12 !== void 0 && _property$annotations12.IsFiscalYear) {
|
|
1268
|
+
return "com.sap.vocabularies.Common.v1.IsFiscalYear";
|
|
1269
|
+
}
|
|
1270
|
+
if ((_property$annotations13 = property.annotations) !== null && _property$annotations13 !== void 0 && (_property$annotations14 = _property$annotations13.Common) !== null && _property$annotations14 !== void 0 && _property$annotations14.IsFiscalPeriod) {
|
|
1271
|
+
return "com.sap.vocabularies.Common.v1.IsFiscalPeriod";
|
|
1272
|
+
}
|
|
1273
|
+
if ((_property$annotations15 = property.annotations) !== null && _property$annotations15 !== void 0 && (_property$annotations16 = _property$annotations15.Common) !== null && _property$annotations16 !== void 0 && _property$annotations16.IsFiscalYearPeriod) {
|
|
1274
|
+
return "com.sap.vocabularies.Common.v1.IsFiscalYearPeriod";
|
|
1275
|
+
}
|
|
1276
|
+
if ((_property$annotations17 = property.annotations) !== null && _property$annotations17 !== void 0 && (_property$annotations18 = _property$annotations17.Common) !== null && _property$annotations18 !== void 0 && _property$annotations18.IsFiscalQuarter) {
|
|
1277
|
+
return "com.sap.vocabularies.Common.v1.IsFiscalQuarter";
|
|
1278
|
+
}
|
|
1279
|
+
if ((_property$annotations19 = property.annotations) !== null && _property$annotations19 !== void 0 && (_property$annotations20 = _property$annotations19.Common) !== null && _property$annotations20 !== void 0 && _property$annotations20.IsFiscalYearQuarter) {
|
|
1280
|
+
return "com.sap.vocabularies.Common.v1.IsFiscalYearQuarter";
|
|
1281
|
+
}
|
|
1282
|
+
if ((_property$annotations21 = property.annotations) !== null && _property$annotations21 !== void 0 && (_property$annotations22 = _property$annotations21.Common) !== null && _property$annotations22 !== void 0 && _property$annotations22.IsFiscalWeek) {
|
|
1283
|
+
return "com.sap.vocabularies.Common.v1.IsFiscalWeek";
|
|
1284
|
+
}
|
|
1285
|
+
if ((_property$annotations23 = property.annotations) !== null && _property$annotations23 !== void 0 && (_property$annotations24 = _property$annotations23.Common) !== null && _property$annotations24 !== void 0 && _property$annotations24.IsFiscalYearWeek) {
|
|
1286
|
+
return "com.sap.vocabularies.Common.v1.IsFiscalYearWeek";
|
|
1287
|
+
}
|
|
1288
|
+
if ((_property$annotations25 = property.annotations) !== null && _property$annotations25 !== void 0 && (_property$annotations26 = _property$annotations25.Common) !== null && _property$annotations26 !== void 0 && _property$annotations26.IsDayOfFiscalYear) {
|
|
1289
|
+
return "com.sap.vocabularies.Common.v1.IsDayOfFiscalYear";
|
|
1290
|
+
}
|
|
1291
|
+
};
|
|
1292
|
+
|
|
1293
|
+
/**
|
|
1294
|
+
* Calls a complex type to process the parameters.
|
|
1295
|
+
* If requireContext is set to true and no context is passed, a default context will be added automatically.
|
|
1296
|
+
*
|
|
1297
|
+
* @template T
|
|
1298
|
+
* @template U
|
|
1299
|
+
* @param parameters The list of parameters that should match the type for the complex type=
|
|
1300
|
+
* @param type The complex type to use
|
|
1301
|
+
* @param [contextEntityType] The context entity type to consider
|
|
1302
|
+
* @param oFormatOptions
|
|
1303
|
+
* @returns The corresponding expression
|
|
1304
|
+
*/
|
|
1305
|
+
_exports.getFiscalType = getFiscalType;
|
|
1306
|
+
function addTypeInformation(parameters, type, contextEntityType, oFormatOptions) {
|
|
1307
|
+
const parameterExpressions = parameters.map(wrapPrimitive);
|
|
1308
|
+
if (hasUnresolvableExpression(...parameterExpressions)) {
|
|
1309
|
+
return unresolvableExpression;
|
|
1310
|
+
}
|
|
1311
|
+
// If there is only one parameter and it is a constant and we don't expect the context then return the constant
|
|
1312
|
+
if (parameterExpressions.length === 1 && isConstant(parameterExpressions[0]) && !contextEntityType) {
|
|
1313
|
+
return parameterExpressions[0];
|
|
1314
|
+
} else if (contextEntityType) {
|
|
1315
|
+
// Otherwise, if the context is required and no context is provided make sure to add the default binding
|
|
1316
|
+
if (!parameterExpressions.some(hasReferenceToDefaultContext)) {
|
|
1317
|
+
contextEntityType.keys.forEach(key => parameterExpressions.push(pathInModel(key.name, "")));
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
oFormatOptions = _getComplexTypeFormatOptionsFromFirstParam(parameters[0], oFormatOptions);
|
|
1321
|
+
if (type === "sap.ui.model.odata.type.Unit") {
|
|
1322
|
+
const uomPath = pathInModel("/##@@requestUnitsOfMeasure");
|
|
1323
|
+
uomPath.targetType = "any";
|
|
1324
|
+
uomPath.mode = "OneTime";
|
|
1325
|
+
parameterExpressions.push(uomPath);
|
|
1326
|
+
} else if (type === "sap.ui.model.odata.type.Currency") {
|
|
1327
|
+
const currencyPath = pathInModel("/##@@requestCurrencyCodes");
|
|
1328
|
+
currencyPath.targetType = "any";
|
|
1329
|
+
currencyPath.mode = "OneTime";
|
|
1330
|
+
parameterExpressions.push(currencyPath);
|
|
1331
|
+
}
|
|
1332
|
+
return {
|
|
1333
|
+
_type: "ComplexType",
|
|
1334
|
+
type: type,
|
|
1335
|
+
formatOptions: oFormatOptions || {},
|
|
1336
|
+
parameters: {},
|
|
1337
|
+
bindingParameters: parameterExpressions
|
|
1338
|
+
};
|
|
1339
|
+
}
|
|
1340
|
+
_exports.addTypeInformation = addTypeInformation;
|
|
1341
|
+
/**
|
|
1342
|
+
* Process the formatOptions for a complexType based on the first parameter.
|
|
1343
|
+
*
|
|
1344
|
+
* @param param The first parameter of the complex type
|
|
1345
|
+
* @param formatOptions Initial formatOptions
|
|
1346
|
+
* @returns The modified formatOptions
|
|
1347
|
+
*/
|
|
1348
|
+
function _getComplexTypeFormatOptionsFromFirstParam(param, formatOptions) {
|
|
1349
|
+
var _param$type;
|
|
1350
|
+
// if showMeasure is set to false we want to not parse as string to see the 0
|
|
1351
|
+
// we do that also for all bindings because otherwise the mdc Field isn't editable
|
|
1352
|
+
if (!(formatOptions && formatOptions.showNumber === false) && ((param === null || param === void 0 ? void 0 : (_param$type = param.type) === null || _param$type === void 0 ? void 0 : _param$type.indexOf("sap.ui.model.odata.type.Int")) === 0 || (param === null || param === void 0 ? void 0 : param.type) === "sap.ui.model.odata.type.Decimal" || (param === null || param === void 0 ? void 0 : param.type) === "sap.ui.model.odata.type.Double")) {
|
|
1353
|
+
if ((param === null || param === void 0 ? void 0 : param.type) === "sap.ui.model.odata.type.Int64" || (param === null || param === void 0 ? void 0 : param.type) === "sap.ui.model.odata.type.Decimal") {
|
|
1354
|
+
var _formatOptions;
|
|
1355
|
+
//sap.ui.model.odata.type.Int64 do not support parseAsString false
|
|
1356
|
+
formatOptions = ((_formatOptions = formatOptions) === null || _formatOptions === void 0 ? void 0 : _formatOptions.showMeasure) === false ? {
|
|
1357
|
+
showMeasure: false
|
|
1358
|
+
} : {};
|
|
1359
|
+
} else {
|
|
1360
|
+
var _formatOptions2;
|
|
1361
|
+
formatOptions = ((_formatOptions2 = formatOptions) === null || _formatOptions2 === void 0 ? void 0 : _formatOptions2.showMeasure) === false ? {
|
|
1362
|
+
parseAsString: false,
|
|
1363
|
+
showMeasure: false
|
|
1364
|
+
} : {
|
|
1365
|
+
parseAsString: false
|
|
1366
|
+
};
|
|
1367
|
+
}
|
|
1368
|
+
formatOptions.emptyString = null;
|
|
1369
|
+
}
|
|
1370
|
+
return formatOptions;
|
|
1371
|
+
}
|
|
1372
|
+
/**
|
|
1373
|
+
* Function call, optionally with arguments.
|
|
1374
|
+
*
|
|
1375
|
+
* @param func Function name or reference to function
|
|
1376
|
+
* @param parameters Arguments
|
|
1377
|
+
* @param on Object to call the function on
|
|
1378
|
+
* @param isFormattingFn
|
|
1379
|
+
* @returns Expression representing the function call (not the result of the function call!)
|
|
1380
|
+
*/
|
|
1381
|
+
function fn(func, parameters, on) {
|
|
1382
|
+
let isFormattingFn = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
1383
|
+
const functionName = typeof func === "string" ? func : func.__functionName;
|
|
1384
|
+
return {
|
|
1385
|
+
_type: "Function",
|
|
1386
|
+
obj: on !== undefined ? wrapPrimitive(on) : undefined,
|
|
1387
|
+
fn: functionName,
|
|
1388
|
+
isFormattingFn: isFormattingFn,
|
|
1389
|
+
parameters: parameters.map(wrapPrimitive)
|
|
1390
|
+
};
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
/**
|
|
1394
|
+
* Shortcut function to determine if a binding value is null, undefined or empty.
|
|
1395
|
+
*
|
|
1396
|
+
* @param expression
|
|
1397
|
+
* @returns A Boolean expression evaluating the fact that the current element is empty
|
|
1398
|
+
*/
|
|
1399
|
+
_exports.fn = fn;
|
|
1400
|
+
function isEmpty(expression) {
|
|
1401
|
+
const aBindings = [];
|
|
1402
|
+
transformRecursively(expression, "PathInModel", expr => {
|
|
1403
|
+
aBindings.push(or(equal(expr, ""), equal(expr, undefined), equal(expr, null)));
|
|
1404
|
+
return expr;
|
|
1405
|
+
});
|
|
1406
|
+
return and(...aBindings);
|
|
1407
|
+
}
|
|
1408
|
+
_exports.isEmpty = isEmpty;
|
|
1409
|
+
function concat() {
|
|
1410
|
+
for (var _len4 = arguments.length, inExpressions = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
1411
|
+
inExpressions[_key4] = arguments[_key4];
|
|
1412
|
+
}
|
|
1413
|
+
const expressions = inExpressions.map(wrapPrimitive);
|
|
1414
|
+
if (hasUnresolvableExpression(...expressions)) {
|
|
1415
|
+
return unresolvableExpression;
|
|
1416
|
+
}
|
|
1417
|
+
if (expressions.every(isConstant)) {
|
|
1418
|
+
return constant(expressions.reduce((concatenated, value) => {
|
|
1419
|
+
if (value.value !== undefined && value.value !== null) {
|
|
1420
|
+
return concatenated + value.value.toString();
|
|
1421
|
+
}
|
|
1422
|
+
return concatenated;
|
|
1423
|
+
}, ""));
|
|
1424
|
+
} else if (expressions.some(isComplexTypeExpression)) {
|
|
1425
|
+
let pathIdx = 0;
|
|
1426
|
+
const myConcatExpression = formatResult(expressions, "sap.fe.core.formatters.StandardFormatter#concat", undefined, true);
|
|
1427
|
+
const allParts = [];
|
|
1428
|
+
transformRecursively(myConcatExpression, "PathInModel", constantPath => {
|
|
1429
|
+
allParts.push(constantPath);
|
|
1430
|
+
return pathInModel(`$${pathIdx++}`, "$");
|
|
1431
|
+
});
|
|
1432
|
+
allParts.unshift(constant(JSON.stringify(myConcatExpression)));
|
|
1433
|
+
return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression", undefined, true);
|
|
1434
|
+
}
|
|
1435
|
+
return {
|
|
1436
|
+
_type: "Concat",
|
|
1437
|
+
expressions: expressions
|
|
1438
|
+
};
|
|
1439
|
+
}
|
|
1440
|
+
_exports.concat = concat;
|
|
1441
|
+
function transformRecursively(inExpression, expressionType, transformFunction) {
|
|
1442
|
+
let includeAllExpression = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
1443
|
+
let expression = inExpression;
|
|
1444
|
+
switch (expression._type) {
|
|
1445
|
+
case "Function":
|
|
1446
|
+
case "Formatter":
|
|
1447
|
+
expression.parameters = expression.parameters.map(parameter => transformRecursively(parameter, expressionType, transformFunction, includeAllExpression));
|
|
1448
|
+
break;
|
|
1449
|
+
case "Concat":
|
|
1450
|
+
expression.expressions = expression.expressions.map(subExpression => transformRecursively(subExpression, expressionType, transformFunction, includeAllExpression));
|
|
1451
|
+
expression = concat(...expression.expressions);
|
|
1452
|
+
break;
|
|
1453
|
+
case "ComplexType":
|
|
1454
|
+
expression.bindingParameters = expression.bindingParameters.map(bindingParameter => transformRecursively(bindingParameter, expressionType, transformFunction, includeAllExpression));
|
|
1455
|
+
break;
|
|
1456
|
+
case "IfElse":
|
|
1457
|
+
const onTrue = transformRecursively(expression.onTrue, expressionType, transformFunction, includeAllExpression);
|
|
1458
|
+
const onFalse = transformRecursively(expression.onFalse, expressionType, transformFunction, includeAllExpression);
|
|
1459
|
+
let condition = expression.condition;
|
|
1460
|
+
if (includeAllExpression) {
|
|
1461
|
+
condition = transformRecursively(expression.condition, expressionType, transformFunction, includeAllExpression);
|
|
1462
|
+
}
|
|
1463
|
+
expression = ifElse(condition, onTrue, onFalse);
|
|
1464
|
+
break;
|
|
1465
|
+
case "Not":
|
|
1466
|
+
if (includeAllExpression) {
|
|
1467
|
+
const operand = transformRecursively(expression.operand, expressionType, transformFunction, includeAllExpression);
|
|
1468
|
+
expression = not(operand);
|
|
1469
|
+
}
|
|
1470
|
+
break;
|
|
1471
|
+
case "Truthy":
|
|
1472
|
+
break;
|
|
1473
|
+
case "Set":
|
|
1474
|
+
if (includeAllExpression) {
|
|
1475
|
+
const operands = expression.operands.map(operand => transformRecursively(operand, expressionType, transformFunction, includeAllExpression));
|
|
1476
|
+
expression = expression.operator === "||" ? or(...operands) : and(...operands);
|
|
1477
|
+
}
|
|
1478
|
+
break;
|
|
1479
|
+
case "Comparison":
|
|
1480
|
+
if (includeAllExpression) {
|
|
1481
|
+
const operand1 = transformRecursively(expression.operand1, expressionType, transformFunction, includeAllExpression);
|
|
1482
|
+
const operand2 = transformRecursively(expression.operand2, expressionType, transformFunction, includeAllExpression);
|
|
1483
|
+
expression = comparison(expression.operator, operand1, operand2);
|
|
1484
|
+
}
|
|
1485
|
+
break;
|
|
1486
|
+
case "Constant":
|
|
1487
|
+
const constantValue = expression.value;
|
|
1488
|
+
if (typeof constantValue === "object" && constantValue) {
|
|
1489
|
+
Object.keys(constantValue).forEach(key => {
|
|
1490
|
+
constantValue[key] = transformRecursively(constantValue[key], expressionType, transformFunction, includeAllExpression);
|
|
1491
|
+
});
|
|
1492
|
+
}
|
|
1493
|
+
break;
|
|
1494
|
+
case "Ref":
|
|
1495
|
+
case "Length":
|
|
1496
|
+
case "PathInModel":
|
|
1497
|
+
case "EmbeddedBinding":
|
|
1498
|
+
case "EmbeddedExpressionBinding":
|
|
1499
|
+
case "Unresolvable":
|
|
1500
|
+
// Do nothing
|
|
1501
|
+
break;
|
|
1502
|
+
}
|
|
1503
|
+
if (expressionType === expression._type) {
|
|
1504
|
+
expression = transformFunction(inExpression);
|
|
1505
|
+
}
|
|
1506
|
+
return expression;
|
|
1507
|
+
}
|
|
1508
|
+
_exports.transformRecursively = transformRecursively;
|
|
1509
|
+
const needParenthesis = function (expr) {
|
|
1510
|
+
return !isConstant(expr) && !isPathInModelExpression(expr) && isBindingToolkitExpression(expr) && expr._type !== "IfElse" && expr._type !== "Function";
|
|
1511
|
+
};
|
|
1512
|
+
|
|
1513
|
+
/**
|
|
1514
|
+
* Compiles a constant object to a string.
|
|
1515
|
+
*
|
|
1516
|
+
* @param expr
|
|
1517
|
+
* @param isNullable
|
|
1518
|
+
* @returns The compiled string
|
|
1519
|
+
*/
|
|
1520
|
+
function compileConstantObject(expr) {
|
|
1521
|
+
let isNullable = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
1522
|
+
if (isNullable && Object.keys(expr.value).length === 0) {
|
|
1523
|
+
return "";
|
|
1524
|
+
}
|
|
1525
|
+
const objects = expr.value;
|
|
1526
|
+
const properties = [];
|
|
1527
|
+
Object.keys(objects).forEach(key => {
|
|
1528
|
+
const value = objects[key];
|
|
1529
|
+
const childResult = compileExpression(value, true, false, isNullable);
|
|
1530
|
+
if (childResult && childResult.length > 0) {
|
|
1531
|
+
properties.push(`${key}: ${childResult}`);
|
|
1532
|
+
}
|
|
1533
|
+
});
|
|
1534
|
+
return `{${properties.join(", ")}}`;
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
/**
|
|
1538
|
+
* Compiles a Constant Binding Expression.
|
|
1539
|
+
*
|
|
1540
|
+
* @param expr
|
|
1541
|
+
* @param embeddedInBinding
|
|
1542
|
+
* @param isNullable
|
|
1543
|
+
* @param doNotStringify
|
|
1544
|
+
* @returns The compiled string
|
|
1545
|
+
*/
|
|
1546
|
+
|
|
1547
|
+
function compileConstant(expr, embeddedInBinding) {
|
|
1548
|
+
let isNullable = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
1549
|
+
let doNotStringify = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
1550
|
+
if (expr.value === null) {
|
|
1551
|
+
return doNotStringify ? null : "null";
|
|
1552
|
+
}
|
|
1553
|
+
if (expr.value === undefined) {
|
|
1554
|
+
return doNotStringify ? undefined : "undefined";
|
|
1555
|
+
}
|
|
1556
|
+
if (typeof expr.value === "object") {
|
|
1557
|
+
if (Array.isArray(expr.value)) {
|
|
1558
|
+
const entries = expr.value.map(expression => compileExpression(expression, true));
|
|
1559
|
+
return `[${entries.join(", ")}]`;
|
|
1560
|
+
} else {
|
|
1561
|
+
return compileConstantObject(expr, isNullable);
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
if (embeddedInBinding) {
|
|
1565
|
+
switch (typeof expr.value) {
|
|
1566
|
+
case "number":
|
|
1567
|
+
case "bigint":
|
|
1568
|
+
case "boolean":
|
|
1569
|
+
return expr.value.toString();
|
|
1570
|
+
case "string":
|
|
1571
|
+
return `'${escapeXmlAttribute(expr.value.toString())}'`;
|
|
1572
|
+
default:
|
|
1573
|
+
return "";
|
|
1574
|
+
}
|
|
1575
|
+
} else {
|
|
1576
|
+
return doNotStringify ? expr.value : expr.value.toString();
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
/**
|
|
1581
|
+
* Generates the binding string for a Binding expression.
|
|
1582
|
+
*
|
|
1583
|
+
* @param expressionForBinding The expression to compile
|
|
1584
|
+
* @param embeddedInBinding Whether the expression to compile is embedded into another expression
|
|
1585
|
+
* @param embeddedSeparator The binding value evaluator ($ or % depending on whether we want to force the type or not)
|
|
1586
|
+
* @returns The corresponding expression binding
|
|
1587
|
+
*/
|
|
1588
|
+
_exports.compileConstant = compileConstant;
|
|
1589
|
+
function compilePathInModelExpression(expressionForBinding, embeddedInBinding, embeddedSeparator) {
|
|
1590
|
+
if (expressionForBinding.type || expressionForBinding.parameters || expressionForBinding.targetType || expressionForBinding.formatOptions || expressionForBinding.constraints) {
|
|
1591
|
+
// This is now a complex binding definition, let's prepare for it
|
|
1592
|
+
const complexBindingDefinition = {
|
|
1593
|
+
path: compilePathInModel(expressionForBinding),
|
|
1594
|
+
type: expressionForBinding.type,
|
|
1595
|
+
targetType: expressionForBinding.targetType,
|
|
1596
|
+
parameters: expressionForBinding.parameters,
|
|
1597
|
+
formatOptions: expressionForBinding.formatOptions,
|
|
1598
|
+
constraints: expressionForBinding.constraints
|
|
1599
|
+
};
|
|
1600
|
+
const outBinding = compileExpression(complexBindingDefinition, false, false, true);
|
|
1601
|
+
if (embeddedInBinding) {
|
|
1602
|
+
return `${embeddedSeparator}${outBinding}`;
|
|
1603
|
+
}
|
|
1604
|
+
return outBinding;
|
|
1605
|
+
} else if (embeddedInBinding) {
|
|
1606
|
+
return `${embeddedSeparator}{${compilePathInModel(expressionForBinding)}}`;
|
|
1607
|
+
} else {
|
|
1608
|
+
return `{${compilePathInModel(expressionForBinding)}}`;
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
function compileComplexTypeExpression(expression) {
|
|
1612
|
+
if (expression.bindingParameters.length === 1) {
|
|
1613
|
+
return `{${compilePathParameter(expression.bindingParameters[0], true)}, type: '${expression.type}'}`;
|
|
1614
|
+
}
|
|
1615
|
+
let outputEnd = `], type: '${expression.type}'`;
|
|
1616
|
+
if (hasElements(expression.formatOptions)) {
|
|
1617
|
+
outputEnd += `, formatOptions: ${compileExpression(expression.formatOptions)}`;
|
|
1618
|
+
}
|
|
1619
|
+
if (hasElements(expression.parameters)) {
|
|
1620
|
+
outputEnd += `, parameters: ${compileExpression(expression.parameters)}`;
|
|
1621
|
+
}
|
|
1622
|
+
outputEnd += "}";
|
|
1623
|
+
return `{mode:'TwoWay', parts:[${expression.bindingParameters.map(param => compilePathParameter(param)).join(",")}${outputEnd}`;
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1626
|
+
/**
|
|
1627
|
+
* Wrap the compiled binding string as required depending on its context.
|
|
1628
|
+
*
|
|
1629
|
+
* @param expression The compiled expression
|
|
1630
|
+
* @param embeddedInBinding True if the compiled expression is to be embedded in a binding
|
|
1631
|
+
* @param parenthesisRequired True if the embedded binding needs to be wrapped in parethesis so that it is evaluated as one
|
|
1632
|
+
* @returns Finalized compiled expression
|
|
1633
|
+
*/
|
|
1634
|
+
function wrapBindingExpression(expression, embeddedInBinding) {
|
|
1635
|
+
let parenthesisRequired = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
1636
|
+
if (embeddedInBinding) {
|
|
1637
|
+
if (parenthesisRequired) {
|
|
1638
|
+
return `(${expression})`;
|
|
1639
|
+
} else {
|
|
1640
|
+
return expression;
|
|
1641
|
+
}
|
|
1642
|
+
} else {
|
|
1643
|
+
return `{= ${expression}}`;
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
/**
|
|
1648
|
+
* Compile an expression into an expression binding.
|
|
1649
|
+
*
|
|
1650
|
+
* @template T The target type
|
|
1651
|
+
* @param expression The expression to compile
|
|
1652
|
+
* @param embeddedInBinding Whether the expression to compile is embedded into another expression
|
|
1653
|
+
* @param keepTargetType Keep the target type of the embedded bindings instead of casting them to any
|
|
1654
|
+
* @param isNullable Whether binding expression can resolve to empty string or not
|
|
1655
|
+
* @returns The corresponding expression binding
|
|
1656
|
+
*/
|
|
1657
|
+
_exports.wrapBindingExpression = wrapBindingExpression;
|
|
1658
|
+
function compileExpression(expression) {
|
|
1659
|
+
let embeddedInBinding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
1660
|
+
let keepTargetType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
1661
|
+
let isNullable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
1662
|
+
const expr = wrapPrimitive(expression);
|
|
1663
|
+
const embeddedSeparator = keepTargetType ? "$" : "%";
|
|
1664
|
+
switch (expr._type) {
|
|
1665
|
+
case "Unresolvable":
|
|
1666
|
+
return undefined;
|
|
1667
|
+
case "Constant":
|
|
1668
|
+
return compileConstant(expr, embeddedInBinding, isNullable);
|
|
1669
|
+
case "Ref":
|
|
1670
|
+
return expr.ref || "null";
|
|
1671
|
+
case "Function":
|
|
1672
|
+
let hasEmbeddedFunctionCallOrBinding = false;
|
|
1673
|
+
if (expr.isFormattingFn) {
|
|
1674
|
+
transformRecursively(expr, "Function", subFn => {
|
|
1675
|
+
if (subFn !== expr && subFn.obj === undefined) {
|
|
1676
|
+
hasEmbeddedFunctionCallOrBinding = true;
|
|
1677
|
+
}
|
|
1678
|
+
return subFn;
|
|
1679
|
+
}, true);
|
|
1680
|
+
transformRecursively(expr, "Constant", subFn => {
|
|
1681
|
+
if (subFn !== expr && typeof subFn.value === "object") {
|
|
1682
|
+
transformRecursively(subFn, "PathInModel", subSubFn => {
|
|
1683
|
+
hasEmbeddedFunctionCallOrBinding = true;
|
|
1684
|
+
return subSubFn;
|
|
1685
|
+
});
|
|
1686
|
+
}
|
|
1687
|
+
return subFn;
|
|
1688
|
+
}, true);
|
|
1689
|
+
}
|
|
1690
|
+
const argumentString = `${expr.parameters.map(arg => compileExpression(arg, true)).join(", ")}`;
|
|
1691
|
+
let fnCall = expr.obj === undefined ? `${expr.fn}(${argumentString})` : `${compileExpression(expr.obj, true)}.${expr.fn}(${argumentString})`;
|
|
1692
|
+
if (!embeddedInBinding && hasEmbeddedFunctionCallOrBinding) {
|
|
1693
|
+
fnCall = `{= ${fnCall}}`;
|
|
1694
|
+
}
|
|
1695
|
+
return fnCall;
|
|
1696
|
+
case "EmbeddedExpressionBinding":
|
|
1697
|
+
return embeddedInBinding ? `(${expr.value.substring(2, expr.value.length - 1)})` : `${expr.value}`;
|
|
1698
|
+
case "EmbeddedBinding":
|
|
1699
|
+
return embeddedInBinding ? `${embeddedSeparator}${expr.value}` : `${expr.value}`;
|
|
1700
|
+
case "PathInModel":
|
|
1701
|
+
return compilePathInModelExpression(expr, embeddedInBinding, embeddedSeparator);
|
|
1702
|
+
case "Comparison":
|
|
1703
|
+
const comparisonExpression = compileComparisonExpression(expr);
|
|
1704
|
+
return wrapBindingExpression(comparisonExpression, embeddedInBinding);
|
|
1705
|
+
case "IfElse":
|
|
1706
|
+
const ifElseExpression = `${compileExpression(expr.condition, true)} ? ${compileExpression(expr.onTrue, true, keepTargetType)} : ${compileExpression(expr.onFalse, true, keepTargetType)}`;
|
|
1707
|
+
return wrapBindingExpression(ifElseExpression, embeddedInBinding, true);
|
|
1708
|
+
case "Set":
|
|
1709
|
+
const setExpression = expr.operands.map(operand => compileExpression(operand, true)).join(` ${expr.operator} `);
|
|
1710
|
+
return wrapBindingExpression(setExpression, embeddedInBinding, true);
|
|
1711
|
+
case "Concat":
|
|
1712
|
+
const concatExpression = expr.expressions.map(nestedExpression => compileExpression(nestedExpression, true, true)).join(" + ");
|
|
1713
|
+
return wrapBindingExpression(concatExpression, embeddedInBinding);
|
|
1714
|
+
case "Length":
|
|
1715
|
+
const lengthExpression = `${compileExpression(expr.pathInModel, true)}.length`;
|
|
1716
|
+
return wrapBindingExpression(lengthExpression, embeddedInBinding);
|
|
1717
|
+
case "Not":
|
|
1718
|
+
const notExpression = `!${compileExpression(expr.operand, true)}`;
|
|
1719
|
+
return wrapBindingExpression(notExpression, embeddedInBinding);
|
|
1720
|
+
case "Truthy":
|
|
1721
|
+
const truthyExpression = `!!${compileExpression(expr.operand, true)}`;
|
|
1722
|
+
return wrapBindingExpression(truthyExpression, embeddedInBinding);
|
|
1723
|
+
case "Formatter":
|
|
1724
|
+
const formatterExpression = compileFormatterExpression(expr);
|
|
1725
|
+
return embeddedInBinding ? `$${formatterExpression}` : formatterExpression;
|
|
1726
|
+
case "ComplexType":
|
|
1727
|
+
const complexTypeExpression = compileComplexTypeExpression(expr);
|
|
1728
|
+
return embeddedInBinding ? `$${complexTypeExpression}` : complexTypeExpression;
|
|
1729
|
+
default:
|
|
1730
|
+
return "";
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
/**
|
|
1735
|
+
* Compile a comparison expression.
|
|
1736
|
+
*
|
|
1737
|
+
* @param expression The comparison expression.
|
|
1738
|
+
* @returns The compiled expression. Needs wrapping before it can be used as an expression binding.
|
|
1739
|
+
*/
|
|
1740
|
+
_exports.compileExpression = compileExpression;
|
|
1741
|
+
function compileComparisonExpression(expression) {
|
|
1742
|
+
function compileOperand(operand) {
|
|
1743
|
+
const compiledOperand = compileExpression(operand, true) ?? "undefined";
|
|
1744
|
+
return wrapBindingExpression(compiledOperand, true, needParenthesis(operand));
|
|
1745
|
+
}
|
|
1746
|
+
return `${compileOperand(expression.operand1)} ${expression.operator} ${compileOperand(expression.operand2)}`;
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
/**
|
|
1750
|
+
* Compile a formatter expression.
|
|
1751
|
+
*
|
|
1752
|
+
* @param expression The formatter expression.
|
|
1753
|
+
* @returns The compiled expression.
|
|
1754
|
+
*/
|
|
1755
|
+
function compileFormatterExpression(expression) {
|
|
1756
|
+
if (expression.parameters.length === 1) {
|
|
1757
|
+
return `{${compilePathParameter(expression.parameters[0], true)}, formatter: '${expression.fn}'}`;
|
|
1758
|
+
} else {
|
|
1759
|
+
const parts = expression.parameters.map(param => {
|
|
1760
|
+
if (param._type === "ComplexType") {
|
|
1761
|
+
return compileComplexTypeExpression(param);
|
|
1762
|
+
} else {
|
|
1763
|
+
return compilePathParameter(param);
|
|
1764
|
+
}
|
|
1765
|
+
});
|
|
1766
|
+
return `{parts: [${parts.join(", ")}], formatter: '${expression.fn}'}`;
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
/**
|
|
1771
|
+
* Compile the path parameter of a formatter call.
|
|
1772
|
+
*
|
|
1773
|
+
* @param expression The binding part to evaluate
|
|
1774
|
+
* @param singlePath Whether there is one or multiple path to consider
|
|
1775
|
+
* @returns The string snippet to include in the overall binding definition
|
|
1776
|
+
*/
|
|
1777
|
+
function compilePathParameter(expression) {
|
|
1778
|
+
let singlePath = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
1779
|
+
let outValue = "";
|
|
1780
|
+
if (expression._type === "Constant") {
|
|
1781
|
+
if (expression.value === undefined) {
|
|
1782
|
+
// Special case otherwise the JSTokenizer complains about incorrect content
|
|
1783
|
+
outValue = `value: 'undefined'`;
|
|
1784
|
+
} else {
|
|
1785
|
+
outValue = `value: ${compileConstant(expression, true)}`;
|
|
1786
|
+
}
|
|
1787
|
+
} else if (expression._type === "PathInModel") {
|
|
1788
|
+
outValue = `path: '${compilePathInModel(expression)}'`;
|
|
1789
|
+
outValue += expression.type ? `, type: '${expression.type}'` : `, targetType: 'any'`;
|
|
1790
|
+
if (expression.mode) {
|
|
1791
|
+
outValue += `, mode: '${compileExpression(expression.mode)}'`;
|
|
1792
|
+
}
|
|
1793
|
+
if (hasElements(expression.constraints)) {
|
|
1794
|
+
outValue += `, constraints: ${compileExpression(expression.constraints)}`;
|
|
1795
|
+
}
|
|
1796
|
+
if (hasElements(expression.formatOptions)) {
|
|
1797
|
+
outValue += `, formatOptions: ${compileExpression(expression.formatOptions)}`;
|
|
1798
|
+
}
|
|
1799
|
+
if (hasElements(expression.parameters)) {
|
|
1800
|
+
outValue += `, parameters: ${compileExpression(expression.parameters)}`;
|
|
1801
|
+
}
|
|
1802
|
+
} else {
|
|
1803
|
+
return "";
|
|
1804
|
+
}
|
|
1805
|
+
return singlePath ? outValue : `{${outValue}}`;
|
|
1806
|
+
}
|
|
1807
|
+
function hasElements(obj) {
|
|
1808
|
+
return !!obj && Object.keys(obj).length > 0;
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
/**
|
|
1812
|
+
* Compile a binding expression path.
|
|
1813
|
+
*
|
|
1814
|
+
* @param expression The expression to compile.
|
|
1815
|
+
* @returns The compiled path.
|
|
1816
|
+
*/
|
|
1817
|
+
function compilePathInModel(expression) {
|
|
1818
|
+
return `${expression.modelName ? expression.modelName + ">" : ""}${expression.path}`;
|
|
1819
|
+
}
|
|
1820
|
+
return _exports;
|
|
1821
|
+
}, false);
|
|
1822
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJpc1Byb3BlcnR5Iiwic2VydmljZU9iamVjdCIsIl90eXBlIiwiRURNX1RZUEVfTUFQUElORyIsInR5cGUiLCJjb25zdHJhaW50cyIsIiRQcmVjaXNpb24iLCIkVjQiLCIkU2NhbGUiLCIkTWF4TGVuZ3RoIiwiJE51bGxhYmxlIiwidW5yZXNvbHZhYmxlRXhwcmVzc2lvbiIsImVzY2FwZVhtbEF0dHJpYnV0ZSIsImlucHV0U3RyaW5nIiwicmVwbGFjZSIsImhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24iLCJleHByZXNzaW9ucyIsImZpbmQiLCJleHByIiwidW5kZWZpbmVkIiwiX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbCIsImEiLCJiIiwidmFsdWUiLCJvcGVyYW5kIiwib3BlcmF0b3IiLCJvcGVyYW5kcyIsImxlbmd0aCIsImV2ZXJ5IiwiZXhwcmVzc2lvbiIsInNvbWUiLCJvdGhlckV4cHJlc3Npb24iLCJjb25kaXRpb24iLCJvblRydWUiLCJvbkZhbHNlIiwib3BlcmFuZDEiLCJvcGVyYW5kMiIsImFFeHByZXNzaW9ucyIsImJFeHByZXNzaW9ucyIsImluZGV4IiwicGF0aEluTW9kZWwiLCJtb2RlbE5hbWUiLCJwYXRoIiwidGFyZ2V0RW50aXR5U2V0IiwiZm4iLCJwYXJhbWV0ZXJzIiwiYmluZGluZ1BhcmFtZXRlcnMiLCJvdGhlckZ1bmN0aW9uIiwib2JqIiwicmVmIiwiZmxhdHRlblNldEV4cHJlc3Npb24iLCJyZWR1Y2UiLCJyZXN1bHQiLCJjYW5kaWRhdGVzRm9yRmxhdHRlbmluZyIsImZvckVhY2giLCJjYW5kaWRhdGUiLCJlIiwicHVzaCIsImhhc09wcG9zaXRlRXhwcmVzc2lvbnMiLCJuZWdhdGVkRXhwcmVzc2lvbnMiLCJtYXAiLCJub3QiLCJpIiwiYW5kIiwid3JhcFByaW1pdGl2ZSIsImlzU3RhdGljRmFsc2UiLCJub25Ucml2aWFsRXhwcmVzc2lvbiIsImZpbHRlciIsImlzRmFsc2UiLCJpc0NvbnN0YW50IiwiY29uc3RhbnQiLCJpc1ZhbGlkIiwiaXNUcnVlIiwib3IiLCJpc1N0YXRpY1RydWUiLCJpc0NvbXBhcmlzb24iLCJpc1RydXRoeSIsImJpbmRpbmdFeHByZXNzaW9uIiwidmlzaXRlZE5hdmlnYXRpb25QYXRocyIsInBhdGhWaXNpdG9yIiwidGFyZ2V0UGF0aCIsImxvY2FsUGF0aCIsImNvbmNhdCIsImpvaW4iLCJjb25zdGFudFZhbHVlIiwiQXJyYXkiLCJpc0FycmF5IiwiaXNQcmltaXRpdmVPYmplY3QiLCJ2YWx1ZU9mIiwiT2JqZWN0IiwiZW50cmllcyIsInBsYWluRXhwcmVzc2lvbiIsImtleSIsInZhbCIsIndyYXBwZWRWYWx1ZSIsInJlc29sdmVCaW5kaW5nU3RyaW5nIiwidGFyZ2V0VHlwZSIsInN0YXJ0c1dpdGgiLCJwYXRoSW5Nb2RlbFJlZ2V4IiwicGF0aEluTW9kZWxSZWdleE1hdGNoIiwiZXhlYyIsImlzTmFOIiwiTnVtYmVyIiwicmVmZXJlbmNlIiwic29tZXRoaW5nIiwiaXNCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb24iLCJtYXliZUNvbnN0YW50IiwiaXNQYXRoSW5Nb2RlbEV4cHJlc3Npb24iLCJtYXliZUJpbmRpbmciLCJpc0NvbXBsZXhUeXBlRXhwcmVzc2lvbiIsImlzQ29uY2F0RXhwcmVzc2lvbiIsImlzSWZFbHNlRXhwcmVzc2lvbiIsImlzVW5kZWZpbmVkRXhwcmVzc2lvbiIsImV4cHJlc3Npb25Bc0V4cHJlc3Npb24iLCJvYmplY3RUeXBlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiaXNDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb24iLCJhbm5vdGF0aW9uVmFsdWUiLCJnZXRFeHByZXNzaW9uRnJvbUFubm90YXRpb24iLCJkZWZhdWx0VmFsdWUiLCJhbm5vdGF0aW9uSWZFeHByZXNzaW9uIiwiSWYiLCJwYXJzZUFubm90YXRpb25Db25kaXRpb24iLCJOb3QiLCJlcXVhbCIsIkVxIiwibm90RXF1YWwiLCJOZSIsImdyZWF0ZXJUaGFuIiwiR3QiLCJncmVhdGVyT3JFcXVhbCIsIkdlIiwibGVzc1RoYW4iLCJMdCIsImxlc3NPckVxdWFsIiwiTGUiLCJPciIsIm9yQ29uZGl0aW9uIiwiQW5kIiwiYW5kQ29uZGl0aW9uIiwiYW5ub3RhdGlvbkFwcGx5RXhwcmVzc2lvbiIsImhhc093blByb3BlcnR5IiwiJE9yIiwiJEFuZCIsIiROb3QiLCIkRXEiLCIkTmUiLCIkR3QiLCIkR2UiLCIkTHQiLCIkTGUiLCIkUGF0aCIsIkZ1bmN0aW9uIiwiJEZ1bmN0aW9uIiwiQXBwbHkiLCIkQXBwbHkiLCIkSWYiLCJyZXNvbHZlRW51bVZhbHVlIiwiJEVudW1NZW1iZXIiLCJpZkVsc2UiLCJjb252ZXJ0U3ViQXBwbHlQYXJhbWV0ZXJzIiwiYXBwbHlQYXJhbSIsImFwcGx5UGFyYW1Db252ZXJ0ZWQiLCJhcHBseUV4cHJlc3Npb24iLCJwYXJhbWV0ZXIiLCJ0ZW1wbGF0ZSIsInRlbXBsYXRlUGFyYW1zIiwic2xpY2UiLCJ0YXJnZXRPYmplY3QiLCIkTmFtZSIsIiRMYWJlbGVkRWxlbWVudCIsImNvbXBhcmlzb24iLCJsZWZ0T3BlcmFuZCIsInJpZ2h0T3BlcmFuZCIsImxlZnRFeHByZXNzaW9uIiwicmlnaHRFeHByZXNzaW9uIiwiY2hlY2tVbmRlZmluZWQiLCJsZWZ0IiwicmlnaHQiLCJyZWR1Y2VkIiwiY29uZGl0aW9uRXhwcmVzc2lvbiIsIm9uVHJ1ZUV4cHJlc3Npb24iLCJvbkZhbHNlRXhwcmVzc2lvbiIsInBhdGhJZHgiLCJteUlmRWxzZUV4cHJlc3Npb24iLCJmb3JtYXRSZXN1bHQiLCJhbGxQYXJ0cyIsInRyYW5zZm9ybVJlY3Vyc2l2ZWx5IiwiY29uc3RhbnRQYXRoIiwidW5zaGlmdCIsIkpTT04iLCJzdHJpbmdpZnkiLCJoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0IiwiZm9ybWF0dGVyRnVuY3Rpb24iLCJjb250ZXh0RW50aXR5VHlwZSIsImlnbm9yZUNvbXBsZXhUeXBlIiwicGFyYW1ldGVyRXhwcmVzc2lvbnMiLCJrZXlzIiwiZnVuY3Rpb25OYW1lIiwiX19mdW5jdGlvbk5hbWUiLCJmb3JtYXR0ZXJDbGFzcyIsImZvcm1hdHRlck5hbWUiLCJzcGxpdCIsIm15Rm9ybWF0RXhwcmVzc2lvbiIsInNldFVwQ29uc3RyYWludHMiLCJ0YXJnZXRNYXBwaW5nIiwicHJvcGVydHkiLCJzY2FsZSIsInByZWNpc2lvbiIsIm1heExlbmd0aCIsIm51bGxhYmxlIiwiYW5ub3RhdGlvbnMiLCJWYWxpZGF0aW9uIiwiTWluaW11bSIsIm1pbmltdW0iLCJNYXhpbXVtIiwibWF4aW11bSIsIkNvbW1vbiIsIklzRGlnaXRTZXF1ZW5jZSIsImlzRGlnaXRTZXF1ZW5jZSIsIlY0IiwiZm9ybWF0V2l0aFR5cGVJbmZvcm1hdGlvbiIsInByb3BlcnR5QmluZGluZ0V4cHJlc3Npb24iLCJpZ25vcmVDb25zdHJhaW50cyIsIm91dEV4cHJlc3Npb24iLCJmb3JtYXRPcHRpb25zIiwiaW5kZXhPZiIsImFzc2lnbiIsInBhcnNlQXNTdHJpbmciLCJwYXJzZUtlZXBzRW1wdHlTdHJpbmciLCJmaXNjYWxUeXBlIiwiZ2V0RmlzY2FsVHlwZSIsInR5cGVzU3VwcG9ydGluZ1BhcnNlRW1wdHlWYWx1ZVRvWmVybyIsImluY2x1ZGVzIiwicGFyc2VFbXB0eVZhbHVlVG9aZXJvIiwiZW1wdHlTdHJpbmciLCJJc0Zpc2NhbFllYXIiLCJJc0Zpc2NhbFBlcmlvZCIsIklzRmlzY2FsWWVhclBlcmlvZCIsIklzRmlzY2FsUXVhcnRlciIsIklzRmlzY2FsWWVhclF1YXJ0ZXIiLCJJc0Zpc2NhbFdlZWsiLCJJc0Zpc2NhbFllYXJXZWVrIiwiSXNEYXlPZkZpc2NhbFllYXIiLCJhZGRUeXBlSW5mb3JtYXRpb24iLCJvRm9ybWF0T3B0aW9ucyIsIl9nZXRDb21wbGV4VHlwZUZvcm1hdE9wdGlvbnNGcm9tRmlyc3RQYXJhbSIsInVvbVBhdGgiLCJtb2RlIiwiY3VycmVuY3lQYXRoIiwicGFyYW0iLCJzaG93TnVtYmVyIiwic2hvd01lYXN1cmUiLCJmdW5jIiwib24iLCJpc0Zvcm1hdHRpbmdGbiIsImlzRW1wdHkiLCJhQmluZGluZ3MiLCJpbkV4cHJlc3Npb25zIiwiY29uY2F0ZW5hdGVkIiwidG9TdHJpbmciLCJteUNvbmNhdEV4cHJlc3Npb24iLCJpbkV4cHJlc3Npb24iLCJleHByZXNzaW9uVHlwZSIsInRyYW5zZm9ybUZ1bmN0aW9uIiwiaW5jbHVkZUFsbEV4cHJlc3Npb24iLCJzdWJFeHByZXNzaW9uIiwiYmluZGluZ1BhcmFtZXRlciIsIm5lZWRQYXJlbnRoZXNpcyIsImNvbXBpbGVDb25zdGFudE9iamVjdCIsImlzTnVsbGFibGUiLCJvYmplY3RzIiwicHJvcGVydGllcyIsImNoaWxkUmVzdWx0IiwiY29tcGlsZUV4cHJlc3Npb24iLCJjb21waWxlQ29uc3RhbnQiLCJlbWJlZGRlZEluQmluZGluZyIsImRvTm90U3RyaW5naWZ5IiwiY29tcGlsZVBhdGhJbk1vZGVsRXhwcmVzc2lvbiIsImV4cHJlc3Npb25Gb3JCaW5kaW5nIiwiZW1iZWRkZWRTZXBhcmF0b3IiLCJjb21wbGV4QmluZGluZ0RlZmluaXRpb24iLCJjb21waWxlUGF0aEluTW9kZWwiLCJvdXRCaW5kaW5nIiwiY29tcGlsZUNvbXBsZXhUeXBlRXhwcmVzc2lvbiIsImNvbXBpbGVQYXRoUGFyYW1ldGVyIiwib3V0cHV0RW5kIiwiaGFzRWxlbWVudHMiLCJ3cmFwQmluZGluZ0V4cHJlc3Npb24iLCJwYXJlbnRoZXNpc1JlcXVpcmVkIiwia2VlcFRhcmdldFR5cGUiLCJoYXNFbWJlZGRlZEZ1bmN0aW9uQ2FsbE9yQmluZGluZyIsInN1YkZuIiwic3ViU3ViRm4iLCJhcmd1bWVudFN0cmluZyIsImFyZyIsImZuQ2FsbCIsInN1YnN0cmluZyIsImNvbXBhcmlzb25FeHByZXNzaW9uIiwiY29tcGlsZUNvbXBhcmlzb25FeHByZXNzaW9uIiwiaWZFbHNlRXhwcmVzc2lvbiIsInNldEV4cHJlc3Npb24iLCJjb25jYXRFeHByZXNzaW9uIiwibmVzdGVkRXhwcmVzc2lvbiIsImxlbmd0aEV4cHJlc3Npb24iLCJub3RFeHByZXNzaW9uIiwidHJ1dGh5RXhwcmVzc2lvbiIsImZvcm1hdHRlckV4cHJlc3Npb24iLCJjb21waWxlRm9ybWF0dGVyRXhwcmVzc2lvbiIsImNvbXBsZXhUeXBlRXhwcmVzc2lvbiIsImNvbXBpbGVPcGVyYW5kIiwiY29tcGlsZWRPcGVyYW5kIiwicGFydHMiLCJzaW5nbGVQYXRoIiwib3V0VmFsdWUiXSwic291cmNlUm9vdCI6Ii4iLCJzb3VyY2VzIjpbIkJpbmRpbmdUb29sa2l0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHtcblx0QWN0aW9uUGFyYW1ldGVyLFxuXHRBbmRBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0QW5kQ29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHRBcHBseUFubm90YXRpb25FeHByZXNzaW9uLFxuXHRCb29sZWFuLFxuXHRDb25kaXRpb25hbENoZWNrT3JWYWx1ZSxcblx0RW50aXR5U2V0LFxuXHRFbnRpdHlUeXBlLFxuXHRFcUFubm90YXRpb25FeHByZXNzaW9uLFxuXHRFcUNvbmRpdGlvbmFsRXhwcmVzc2lvbixcblx0R2VBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0R2VDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdEd0QW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdEd0Q29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHRJZkFubm90YXRpb25FeHByZXNzaW9uLFxuXHRJZkFubm90YXRpb25FeHByZXNzaW9uVmFsdWUsXG5cdExlQW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdExlQ29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHRMdEFubm90YXRpb25FeHByZXNzaW9uLFxuXHRMdENvbmRpdGlvbmFsRXhwcmVzc2lvbixcblx0TmVBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0TmVDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdE5vdEFubm90YXRpb25FeHByZXNzaW9uLFxuXHROb3RDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdE9yQW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdE9yQ29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHRQYXRoQW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdFBhdGhDb25kaXRpb25FeHByZXNzaW9uLFxuXHRQcm9wZXJ0eSxcblx0UHJvcGVydHlBbm5vdGF0aW9uVmFsdWVcbn0gZnJvbSBcIkBzYXAtdXgvdm9jYWJ1bGFyaWVzLXR5cGVzXCI7XG5pbXBvcnQgeyBDb21tb25Bbm5vdGF0aW9uVGVybXMgfSBmcm9tIFwiQHNhcC11eC92b2NhYnVsYXJpZXMtdHlwZXMvdm9jYWJ1bGFyaWVzL0NvbW1vblwiO1xuaW1wb3J0IHsgcmVzb2x2ZUVudW1WYWx1ZSB9IGZyb20gXCJzYXAvZmUvYmFzZS9Bbm5vdGF0aW9uRW51bVwiO1xuXG5leHBvcnQgdHlwZSBQcmltaXRpdmVUeXBlID0gc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50IHwgYm9vbGVhbiB8IG9iamVjdCB8IG51bGwgfCB1bmRlZmluZWQ7XG50eXBlIERlZmluZWRQcmltaXRpdmVUeXBlID0gc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50IHwgYm9vbGVhbiB8IG9iamVjdDtcbnR5cGUgUHJpbWl0aXZlVHlwZUNhc3Q8UD4gPSBQIGV4dGVuZHMgU3RyaW5nID8gc3RyaW5nIDogUCBleHRlbmRzIEJvb2xlYW4gPyBib29sZWFuIDogUCBleHRlbmRzIE51bWJlciA/IG51bWJlciA6IFA7XG50eXBlIEJhc2VFeHByZXNzaW9uPF9UPiA9IHtcblx0X3R5cGU6IHN0cmluZztcbn07XG5cbmV4cG9ydCB0eXBlIEZvcm1hdE9wdGlvbnMgPSBQYXJ0aWFsPHtcblx0Y3VzdG9tVW5pdHM6IFJlY29yZDxzdHJpbmcsIG9iamVjdD47XG5cdGN1c3RvbUN1cnJlbmNpZXM6IFJlY29yZDxzdHJpbmcsIG9iamVjdD47XG5cdGRlY2ltYWxzOiBudW1iZXI7XG5cdGVtcHR5U3RyaW5nOiBudWxsIHwgbnVtYmVyIHwgc3RyaW5nO1xuXHRmaXNjYWxUeXBlOiBzdHJpbmc7XG5cdGdyb3VwaW5nRW5hYmxlZDogYm9vbGVhbjtcblx0bWF4RnJhY3Rpb25EaWdpdHM6IG51bWJlcjtcblx0bWF4SW50ZWdlckRpZ2l0czogbnVtYmVyO1xuXHRtaW5GcmFjdGlvbkRpZ2l0czogbnVtYmVyO1xuXHRtaW5JbnRlZ2VyRGlnaXRzOiBudW1iZXI7XG5cdHBhcnNlQXNTdHJpbmc6IGJvb2xlYW47XG5cdHBhcnNlS2VlcHNFbXB0eVN0cmluZzogYm9vbGVhbjtcblx0cGF0dGVybjogc3RyaW5nO1xuXHRwcmVjaXNpb246IG51bWJlcjtcblx0cHJlc2VydmVEZWNpbWFsczogYm9vbGVhbjtcblx0c2hvcnREZWNpbWFsczogbnVtYmVyO1xuXHRzaG9ydFJlZk51bWJlcjogbnVtYmVyO1xuXHRzaG93TWVhc3VyZTogYm9vbGVhbjtcblx0c2hvd051bWJlcjogYm9vbGVhbjtcblx0c2hvd1NjYWxlOiBib29sZWFuO1xuXHRzdHlsZTogc3RyaW5nO1xufT47XG5cbmV4cG9ydCB0eXBlIENvbnN0YW50RXhwcmVzc2lvbjxUPiA9IEJhc2VFeHByZXNzaW9uPFQ+ICYge1xuXHRfdHlwZTogXCJDb25zdGFudFwiO1xuXHR2YWx1ZTogVDtcbn07XG5cbnR5cGUgU2V0T3BlcmF0b3IgPSBcIiYmXCIgfCBcInx8XCI7XG5leHBvcnQgdHlwZSBTZXRFeHByZXNzaW9uID0gQmFzZUV4cHJlc3Npb248Ym9vbGVhbj4gJiB7XG5cdF90eXBlOiBcIlNldFwiO1xuXHRvcGVyYXRvcjogU2V0T3BlcmF0b3I7XG5cdG9wZXJhbmRzOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj5bXTtcbn07XG5cbmV4cG9ydCB0eXBlIE5vdEV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxib29sZWFuPiAmIHtcblx0X3R5cGU6IFwiTm90XCI7XG5cdG9wZXJhbmQ6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPjtcbn07XG5cbmV4cG9ydCB0eXBlIFRydXRoeUV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxib29sZWFuPiAmIHtcblx0X3R5cGU6IFwiVHJ1dGh5XCI7XG5cdG9wZXJhbmQ6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxzdHJpbmc+O1xufTtcblxuZXhwb3J0IHR5cGUgUmVmZXJlbmNlRXhwcmVzc2lvbiA9IEJhc2VFeHByZXNzaW9uPG9iamVjdD4gJiB7XG5cdF90eXBlOiBcIlJlZlwiO1xuXHRyZWY6IHN0cmluZyB8IG51bGw7XG59O1xuXG5leHBvcnQgdHlwZSBGb3JtYXR0ZXJFeHByZXNzaW9uPFQ+ID0gQmFzZUV4cHJlc3Npb248VD4gJiB7XG5cdF90eXBlOiBcIkZvcm1hdHRlclwiO1xuXHRmbjogc3RyaW5nO1xuXHRwYXJhbWV0ZXJzOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj5bXTtcbn07XG5cbnR5cGUgQ29tcGxleFR5cGVFeHByZXNzaW9uPFQ+ID0gQmFzZUV4cHJlc3Npb248VD4gJiB7XG5cdF90eXBlOiBcIkNvbXBsZXhUeXBlXCI7XG5cdHR5cGU6IHN0cmluZztcblx0Zm9ybWF0T3B0aW9uczogRm9ybWF0T3B0aW9ucztcblx0cGFyYW1ldGVyczogb2JqZWN0O1xuXHRiaW5kaW5nUGFyYW1ldGVyczogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+W107XG59O1xuXG5leHBvcnQgdHlwZSBGdW5jdGlvbkV4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiRnVuY3Rpb25cIjtcblx0b2JqPzogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPG9iamVjdD47XG5cdGZuOiBzdHJpbmc7XG5cdGlzRm9ybWF0dGluZ0ZuOiBib29sZWFuO1xuXHRwYXJhbWV0ZXJzOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj5bXTtcbn07XG5cbmV4cG9ydCB0eXBlIENvbmNhdEV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxzdHJpbmc+ICYge1xuXHRfdHlwZTogXCJDb25jYXRcIjtcblx0ZXhwcmVzc2lvbnM6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxzdHJpbmc+W107XG59O1xuXG5leHBvcnQgdHlwZSBMZW5ndGhFeHByZXNzaW9uID0gQmFzZUV4cHJlc3Npb248c3RyaW5nPiAmIHtcblx0X3R5cGU6IFwiTGVuZ3RoXCI7XG5cdHBhdGhJbk1vZGVsOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248dW5rbm93bj47XG59O1xuXG50eXBlIFVucmVzb2x2YWJsZVBhdGhFeHByZXNzaW9uID0gQmFzZUV4cHJlc3Npb248c3RyaW5nPiAmIHtcblx0X3R5cGU6IFwiVW5yZXNvbHZhYmxlXCI7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIFBhdGhJbk1vZGVsRXhwcmVzc2lvblxuICovXG5leHBvcnQgdHlwZSBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiUGF0aEluTW9kZWxcIjtcblx0bW9kZWxOYW1lPzogc3RyaW5nO1xuXHRwYXRoOiBzdHJpbmc7XG5cdHRhcmdldEVudGl0eVNldD86IEVudGl0eVNldDtcblx0dHlwZT86IHN0cmluZztcblx0Y29uc3RyYWludHM/OiBCaW5kaW5nQ29uc3RyYWludHM7XG5cdHBhcmFtZXRlcnM/OiBvYmplY3Q7XG5cdHRhcmdldFR5cGU/OiBzdHJpbmc7XG5cdG1vZGU/OiBzdHJpbmc7XG5cdGZvcm1hdE9wdGlvbnM/OiBGb3JtYXRPcHRpb25zO1xufTtcblxuZXhwb3J0IHR5cGUgRW1iZWRkZWRVSTVCaW5kaW5nRXhwcmVzc2lvbjxUPiA9IEJhc2VFeHByZXNzaW9uPFQ+ICYge1xuXHRfdHlwZTogXCJFbWJlZGRlZEJpbmRpbmdcIjtcblx0dmFsdWU6IHN0cmluZztcbn07XG5cbmV4cG9ydCB0eXBlIEVtYmVkZGVkVUk1RXhwcmVzc2lvbkJpbmRpbmdFeHByZXNzaW9uPFQ+ID0gQmFzZUV4cHJlc3Npb248VD4gJiB7XG5cdF90eXBlOiBcIkVtYmVkZGVkRXhwcmVzc2lvbkJpbmRpbmdcIjtcblx0dmFsdWU6IHN0cmluZztcbn07XG5cbmV4cG9ydCB0eXBlIENvbXBhcmlzb25PcGVyYXRvciA9IFwiPT09XCIgfCBcIiE9PVwiIHwgXCI+PVwiIHwgXCI+XCIgfCBcIjw9XCIgfCBcIjxcIjtcbmV4cG9ydCB0eXBlIENvbXBhcmlzb25FeHByZXNzaW9uID0gQmFzZUV4cHJlc3Npb248Ym9vbGVhbj4gJiB7XG5cdF90eXBlOiBcIkNvbXBhcmlzb25cIjtcblx0b3BlcmF0b3I6IENvbXBhcmlzb25PcGVyYXRvcjtcblx0b3BlcmFuZDE6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPjtcblx0b3BlcmFuZDI6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPjtcbn07XG5cbmV4cG9ydCB0eXBlIElmRWxzZUV4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiSWZFbHNlXCI7XG5cdGNvbmRpdGlvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+O1xuXHRvblRydWU6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0b25GYWxzZTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xufTtcbmV4cG9ydCBmdW5jdGlvbiBpc1Byb3BlcnR5KHNlcnZpY2VPYmplY3Q6IHVua25vd24pOiBzZXJ2aWNlT2JqZWN0IGlzIFByb3BlcnR5IHtcblx0cmV0dXJuIChzZXJ2aWNlT2JqZWN0IGFzIFByb3BlcnR5KT8uX3R5cGUgPT09IFwiUHJvcGVydHlcIjtcbn1cblxuLyoqXG4gKiBBbiBleHByZXNzaW9uIHRoYXQgZXZhbHVhdGVzIHRvIHR5cGUgVC5cbiAqXG4gKiBAdHlwZWRlZiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IHR5cGUgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+ID1cblx0fCBVbnJlc29sdmFibGVQYXRoRXhwcmVzc2lvblxuXHR8IENvbnN0YW50RXhwcmVzc2lvbjxUPlxuXHR8IFNldEV4cHJlc3Npb25cblx0fCBOb3RFeHByZXNzaW9uXG5cdHwgVHJ1dGh5RXhwcmVzc2lvblxuXHR8IENvbmNhdEV4cHJlc3Npb25cblx0fCBMZW5ndGhFeHByZXNzaW9uXG5cdHwgUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+XG5cdHwgRW1iZWRkZWRVSTVCaW5kaW5nRXhwcmVzc2lvbjxUPlxuXHR8IEVtYmVkZGVkVUk1RXhwcmVzc2lvbkJpbmRpbmdFeHByZXNzaW9uPFQ+XG5cdHwgQ29tcGFyaXNvbkV4cHJlc3Npb25cblx0fCBJZkVsc2VFeHByZXNzaW9uPFQ+XG5cdHwgRm9ybWF0dGVyRXhwcmVzc2lvbjxUPlxuXHR8IENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPlxuXHR8IFJlZmVyZW5jZUV4cHJlc3Npb25cblx0fCBGdW5jdGlvbkV4cHJlc3Npb248VD47XG5cbnR5cGUgVHlwZU1hcHBpbmdEZWZpbml0aW9uID0ge1xuXHR0eXBlOiBzdHJpbmc7XG5cdGNvbnN0cmFpbnRzPzoge1xuXHRcdCRQcmVjaXNpb24/OiBzdHJpbmc7XG5cdFx0JFY0Pzogc3RyaW5nO1xuXHRcdCRTY2FsZT86IHN0cmluZztcblx0XHQkTWF4TGVuZ3RoPzogc3RyaW5nO1xuXHRcdCROdWxsYWJsZT86IHN0cmluZztcblx0XHRcIkBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5NaW5pbXVtLyREZWNpbWFsXCI/OiBzdHJpbmc7XG5cdFx0XCJAT3JnLk9EYXRhLlZhbGlkYXRpb24uVjEuTWluaW11bUBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5FeGNsdXNpdmVcIj86IHN0cmluZztcblx0XHRcIkBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5NYXhpbXVtLyREZWNpbWFsXCI/OiBzdHJpbmc7XG5cdFx0XCJAT3JnLk9EYXRhLlZhbGlkYXRpb24uVjEuTWF4aW11bUBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5FeGNsdXNpdmVcIj86IHN0cmluZztcblx0XHRcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuSXNEaWdpdFNlcXVlbmNlXCI/OiBzdHJpbmc7XG5cdH07XG59O1xuZXhwb3J0IGNvbnN0IEVETV9UWVBFX01BUFBJTkc6IFJlY29yZDxzdHJpbmcsIFR5cGVNYXBwaW5nRGVmaW5pdGlvbj4gPSB7XG5cdFwiRWRtLkJvb2xlYW5cIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkJvb2xlYW5cIiB9LFxuXHRcIkVkbS5CeXRlXCI6IHsgdHlwZTogXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5CeXRlXCIgfSxcblx0XCJFZG0uRGF0ZVwiOiB7IHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuRGF0ZVwiIH0sXG5cdFwiRWRtLkRhdGVUaW1lT2Zmc2V0XCI6IHtcblx0XHRjb25zdHJhaW50czoge1xuXHRcdFx0JFByZWNpc2lvbjogXCJwcmVjaXNpb25cIixcblx0XHRcdCRWNDogXCJWNFwiXG5cdFx0fSxcblx0XHR0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRhdGVUaW1lT2Zmc2V0XCJcblx0fSxcblx0XCJFZG0uRGVjaW1hbFwiOiB7XG5cdFx0Y29uc3RyYWludHM6IHtcblx0XHRcdFwiQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLk1pbmltdW0vJERlY2ltYWxcIjogXCJtaW5pbXVtXCIsXG5cdFx0XHRcIkBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5NaW5pbXVtQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLkV4Y2x1c2l2ZVwiOiBcIm1pbmltdW1FeGNsdXNpdmVcIixcblx0XHRcdFwiQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLk1heGltdW0vJERlY2ltYWxcIjogXCJtYXhpbXVtXCIsXG5cdFx0XHRcIkBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5NYXhpbXVtQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLkV4Y2x1c2l2ZVwiOiBcIm1heGltdW1FeGNsdXNpdmVcIixcblx0XHRcdCRQcmVjaXNpb246IFwicHJlY2lzaW9uXCIsXG5cdFx0XHQkU2NhbGU6IFwic2NhbGVcIlxuXHRcdH0sXG5cdFx0dHlwZTogXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5EZWNpbWFsXCJcblx0fSxcblx0XCJFZG0uRG91YmxlXCI6IHsgdHlwZTogXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5Eb3VibGVcIiB9LFxuXHRcIkVkbS5HdWlkXCI6IHsgdHlwZTogXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5HdWlkXCIgfSxcblx0XCJFZG0uSW50MTZcIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludDE2XCIgfSxcblx0XCJFZG0uSW50MzJcIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludDMyXCIgfSxcblx0XCJFZG0uSW50NjRcIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludDY0XCIgfSxcblx0XCJFZG0uU0J5dGVcIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLlNCeXRlXCIgfSxcblx0XCJFZG0uU2luZ2xlXCI6IHsgdHlwZTogXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5TaW5nbGVcIiB9LFxuXHRcIkVkbS5TdHJlYW1cIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLlN0cmVhbVwiIH0sXG5cdFwiRWRtLkJpbmFyeVwiOiB7IHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuU3RyZWFtXCIgfSxcblx0XCJFZG0uU3RyaW5nXCI6IHtcblx0XHRjb25zdHJhaW50czoge1xuXHRcdFx0XCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLklzRGlnaXRTZXF1ZW5jZVwiOiBcImlzRGlnaXRTZXF1ZW5jZVwiLFxuXHRcdFx0JE1heExlbmd0aDogXCJtYXhMZW5ndGhcIixcblx0XHRcdCROdWxsYWJsZTogXCJudWxsYWJsZVwiXG5cdFx0fSxcblx0XHR0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLlN0cmluZ1wiXG5cdH0sXG5cdFwiRWRtLlRpbWVPZkRheVwiOiB7XG5cdFx0Y29uc3RyYWludHM6IHtcblx0XHRcdCRQcmVjaXNpb246IFwicHJlY2lzaW9uXCJcblx0XHR9LFxuXHRcdHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuVGltZU9mRGF5XCJcblx0fVxufTtcblxuLyoqXG4gKiBBbiBleHByZXNzaW9uIHRoYXQgZXZhbHVhdGVzIHRvIHR5cGUgVCwgb3IgYSBjb25zdGFudCB2YWx1ZSBvZiB0eXBlIFRcbiAqL1xuZXhwb3J0IHR5cGUgRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPiA9IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiB8IFQ7XG5cbmV4cG9ydCBjb25zdCB1bnJlc29sdmFibGVFeHByZXNzaW9uOiBVbnJlc29sdmFibGVQYXRoRXhwcmVzc2lvbiA9IHtcblx0X3R5cGU6IFwiVW5yZXNvbHZhYmxlXCJcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGVYbWxBdHRyaWJ1dGUoaW5wdXRTdHJpbmc6IHN0cmluZyk6IHN0cmluZyB7XG5cdHJldHVybiBpbnB1dFN0cmluZy5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKC4uLmV4cHJlc3Npb25zOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj5bXSk6IGJvb2xlYW4ge1xuXHRyZXR1cm4gZXhwcmVzc2lvbnMuZmluZCgoZXhwcikgPT4gZXhwci5fdHlwZSA9PT0gXCJVbnJlc29sdmFibGVcIikgIT09IHVuZGVmaW5lZDtcbn1cbi8qKlxuICogQ2hlY2sgdHdvIGV4cHJlc3Npb25zIGZvciAoZGVlcCkgZXF1YWxpdHkuXG4gKlxuICogQHBhcmFtIGFcbiAqIEBwYXJhbSBiXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHR3byBleHByZXNzaW9ucyBhcmUgZXF1YWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWw8VD4oYTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+LCBiOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4pOiBib29sZWFuIHtcblx0aWYgKGEuX3R5cGUgIT09IGIuX3R5cGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRzd2l0Y2ggKGEuX3R5cGUpIHtcblx0XHRjYXNlIFwiVW5yZXNvbHZhYmxlXCI6XG5cdFx0XHRyZXR1cm4gZmFsc2U7IC8vIFVucmVzb2x2YWJsZSBpcyBuZXZlciBlcXVhbCB0byBhbnl0aGluZyBldmVuIGl0c2VsZlxuXHRcdGNhc2UgXCJDb25zdGFudFwiOlxuXHRcdGNhc2UgXCJFbWJlZGRlZEJpbmRpbmdcIjpcblx0XHRjYXNlIFwiRW1iZWRkZWRFeHByZXNzaW9uQmluZGluZ1wiOlxuXHRcdFx0cmV0dXJuIGEudmFsdWUgPT09IChiIGFzIENvbnN0YW50RXhwcmVzc2lvbjxUPikudmFsdWU7XG5cblx0XHRjYXNlIFwiTm90XCI6XG5cdFx0XHRyZXR1cm4gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLm9wZXJhbmQsIChiIGFzIE5vdEV4cHJlc3Npb24pLm9wZXJhbmQpO1xuXHRcdGNhc2UgXCJUcnV0aHlcIjpcblx0XHRcdHJldHVybiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEub3BlcmFuZCwgKGIgYXMgVHJ1dGh5RXhwcmVzc2lvbikub3BlcmFuZCk7XG5cdFx0Y2FzZSBcIlNldFwiOlxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0YS5vcGVyYXRvciA9PT0gKGIgYXMgU2V0RXhwcmVzc2lvbikub3BlcmF0b3IgJiZcblx0XHRcdFx0YS5vcGVyYW5kcy5sZW5ndGggPT09IChiIGFzIFNldEV4cHJlc3Npb24pLm9wZXJhbmRzLmxlbmd0aCAmJlxuXHRcdFx0XHRhLm9wZXJhbmRzLmV2ZXJ5KChleHByZXNzaW9uKSA9PlxuXHRcdFx0XHRcdChiIGFzIFNldEV4cHJlc3Npb24pLm9wZXJhbmRzLnNvbWUoKG90aGVyRXhwcmVzc2lvbikgPT4gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChleHByZXNzaW9uLCBvdGhlckV4cHJlc3Npb24pKVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXG5cdFx0Y2FzZSBcIklmRWxzZVwiOlxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0X2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLmNvbmRpdGlvbiwgKGIgYXMgSWZFbHNlRXhwcmVzc2lvbjxUPikuY29uZGl0aW9uKSAmJlxuXHRcdFx0XHRfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEub25UcnVlLCAoYiBhcyBJZkVsc2VFeHByZXNzaW9uPFQ+KS5vblRydWUpICYmXG5cdFx0XHRcdF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoYS5vbkZhbHNlLCAoYiBhcyBJZkVsc2VFeHByZXNzaW9uPFQ+KS5vbkZhbHNlKVxuXHRcdFx0KTtcblxuXHRcdGNhc2UgXCJDb21wYXJpc29uXCI6XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRhLm9wZXJhdG9yID09PSAoYiBhcyBDb21wYXJpc29uRXhwcmVzc2lvbikub3BlcmF0b3IgJiZcblx0XHRcdFx0X2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLm9wZXJhbmQxLCAoYiBhcyBDb21wYXJpc29uRXhwcmVzc2lvbikub3BlcmFuZDEpICYmXG5cdFx0XHRcdF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoYS5vcGVyYW5kMiwgKGIgYXMgQ29tcGFyaXNvbkV4cHJlc3Npb24pLm9wZXJhbmQyKVxuXHRcdFx0KTtcblxuXHRcdGNhc2UgXCJDb25jYXRcIjpcblx0XHRcdGNvbnN0IGFFeHByZXNzaW9ucyA9IGEuZXhwcmVzc2lvbnM7XG5cdFx0XHRjb25zdCBiRXhwcmVzc2lvbnMgPSAoYiBhcyBDb25jYXRFeHByZXNzaW9uKS5leHByZXNzaW9ucztcblx0XHRcdGlmIChhRXhwcmVzc2lvbnMubGVuZ3RoICE9PSBiRXhwcmVzc2lvbnMubGVuZ3RoKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBhRXhwcmVzc2lvbnMuZXZlcnkoKGV4cHJlc3Npb24sIGluZGV4KSA9PiB7XG5cdFx0XHRcdHJldHVybiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGV4cHJlc3Npb24sIGJFeHByZXNzaW9uc1tpbmRleF0pO1xuXHRcdFx0fSk7XG5cblx0XHRjYXNlIFwiTGVuZ3RoXCI6XG5cdFx0XHRyZXR1cm4gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLnBhdGhJbk1vZGVsLCAoYiBhcyBMZW5ndGhFeHByZXNzaW9uKS5wYXRoSW5Nb2RlbCk7XG5cblx0XHRjYXNlIFwiUGF0aEluTW9kZWxcIjpcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdGEubW9kZWxOYW1lID09PSAoYiBhcyBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4pLm1vZGVsTmFtZSAmJlxuXHRcdFx0XHRhLnBhdGggPT09IChiIGFzIFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPikucGF0aCAmJlxuXHRcdFx0XHRhLnRhcmdldEVudGl0eVNldCA9PT0gKGIgYXMgUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+KS50YXJnZXRFbnRpdHlTZXRcblx0XHRcdCk7XG5cblx0XHRjYXNlIFwiRm9ybWF0dGVyXCI6XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRhLmZuID09PSAoYiBhcyBGb3JtYXR0ZXJFeHByZXNzaW9uPFQ+KS5mbiAmJlxuXHRcdFx0XHRhLnBhcmFtZXRlcnMubGVuZ3RoID09PSAoYiBhcyBGb3JtYXR0ZXJFeHByZXNzaW9uPFQ+KS5wYXJhbWV0ZXJzLmxlbmd0aCAmJlxuXHRcdFx0XHRhLnBhcmFtZXRlcnMuZXZlcnkoKHZhbHVlLCBpbmRleCkgPT4gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbCgoYiBhcyBGb3JtYXR0ZXJFeHByZXNzaW9uPFQ+KS5wYXJhbWV0ZXJzW2luZGV4XSwgdmFsdWUpKVxuXHRcdFx0KTtcblx0XHRjYXNlIFwiQ29tcGxleFR5cGVcIjpcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdGEudHlwZSA9PT0gKGIgYXMgQ29tcGxleFR5cGVFeHByZXNzaW9uPFQ+KS50eXBlICYmXG5cdFx0XHRcdGEuYmluZGluZ1BhcmFtZXRlcnMubGVuZ3RoID09PSAoYiBhcyBDb21wbGV4VHlwZUV4cHJlc3Npb248VD4pLmJpbmRpbmdQYXJhbWV0ZXJzLmxlbmd0aCAmJlxuXHRcdFx0XHRhLmJpbmRpbmdQYXJhbWV0ZXJzLmV2ZXJ5KCh2YWx1ZSwgaW5kZXgpID0+XG5cdFx0XHRcdFx0X2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbCgoYiBhcyBDb21wbGV4VHlwZUV4cHJlc3Npb248VD4pLmJpbmRpbmdQYXJhbWV0ZXJzW2luZGV4XSwgdmFsdWUpXG5cdFx0XHRcdClcblx0XHRcdCk7XG5cdFx0Y2FzZSBcIkZ1bmN0aW9uXCI6XG5cdFx0XHRjb25zdCBvdGhlckZ1bmN0aW9uID0gYiBhcyBGdW5jdGlvbkV4cHJlc3Npb248VD47XG5cdFx0XHRpZiAoYS5vYmogPT09IHVuZGVmaW5lZCB8fCBvdGhlckZ1bmN0aW9uLm9iaiA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdHJldHVybiBhLm9iaiA9PT0gb3RoZXJGdW5jdGlvbjtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0YS5mbiA9PT0gb3RoZXJGdW5jdGlvbi5mbiAmJlxuXHRcdFx0XHRfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEub2JqLCBvdGhlckZ1bmN0aW9uLm9iaikgJiZcblx0XHRcdFx0YS5wYXJhbWV0ZXJzLmxlbmd0aCA9PT0gb3RoZXJGdW5jdGlvbi5wYXJhbWV0ZXJzLmxlbmd0aCAmJlxuXHRcdFx0XHRhLnBhcmFtZXRlcnMuZXZlcnkoKHZhbHVlLCBpbmRleCkgPT4gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChvdGhlckZ1bmN0aW9uLnBhcmFtZXRlcnNbaW5kZXhdLCB2YWx1ZSkpXG5cdFx0XHQpO1xuXG5cdFx0Y2FzZSBcIlJlZlwiOlxuXHRcdFx0cmV0dXJuIGEucmVmID09PSAoYiBhcyBSZWZlcmVuY2VFeHByZXNzaW9uKS5yZWY7XG5cdH1cblx0cmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgbmVzdGVkIFNldEV4cHJlc3Npb24gYnkgaW5saW5pbmcgb3BlcmFuZHMgb2YgdHlwZSBTZXRFeHByZXNzaW9uIHdpdGggdGhlIHNhbWUgb3BlcmF0b3IuXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIGV4cHJlc3Npb24gdG8gZmxhdHRlblxuICogQHJldHVybnMgQSBuZXcgU2V0RXhwcmVzc2lvbiB3aXRoIHRoZSBzYW1lIG9wZXJhdG9yXG4gKi9cbmZ1bmN0aW9uIGZsYXR0ZW5TZXRFeHByZXNzaW9uKGV4cHJlc3Npb246IFNldEV4cHJlc3Npb24pOiBTZXRFeHByZXNzaW9uIHtcblx0cmV0dXJuIGV4cHJlc3Npb24ub3BlcmFuZHMucmVkdWNlKFxuXHRcdChyZXN1bHQ6IFNldEV4cHJlc3Npb24sIG9wZXJhbmQpID0+IHtcblx0XHRcdGNvbnN0IGNhbmRpZGF0ZXNGb3JGbGF0dGVuaW5nID1cblx0XHRcdFx0b3BlcmFuZC5fdHlwZSA9PT0gXCJTZXRcIiAmJiBvcGVyYW5kLm9wZXJhdG9yID09PSBleHByZXNzaW9uLm9wZXJhdG9yID8gb3BlcmFuZC5vcGVyYW5kcyA6IFtvcGVyYW5kXTtcblx0XHRcdGNhbmRpZGF0ZXNGb3JGbGF0dGVuaW5nLmZvckVhY2goKGNhbmRpZGF0ZSkgPT4ge1xuXHRcdFx0XHRpZiAocmVzdWx0Lm9wZXJhbmRzLmV2ZXJ5KChlKSA9PiAhX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChlLCBjYW5kaWRhdGUpKSkge1xuXHRcdFx0XHRcdHJlc3VsdC5vcGVyYW5kcy5wdXNoKGNhbmRpZGF0ZSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9LFxuXHRcdHsgX3R5cGU6IFwiU2V0XCIsIG9wZXJhdG9yOiBleHByZXNzaW9uLm9wZXJhdG9yLCBvcGVyYW5kczogW10gfVxuXHQpO1xufVxuXG4vKipcbiAqIERldGVjdHMgd2hldGhlciBhbiBhcnJheSBvZiBib29sZWFuIGV4cHJlc3Npb25zIGNvbnRhaW5zIGFuIGV4cHJlc3Npb24gYW5kIGl0cyBuZWdhdGlvbi5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbnMgQXJyYXkgb2YgZXhwcmVzc2lvbnNcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgc2V0IG9mIGV4cHJlc3Npb25zIGNvbnRhaW5zIGFuIGV4cHJlc3Npb24gYW5kIGl0cyBuZWdhdGlvblxuICovXG5mdW5jdGlvbiBoYXNPcHBvc2l0ZUV4cHJlc3Npb25zKGV4cHJlc3Npb25zOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj5bXSk6IGJvb2xlYW4ge1xuXHRjb25zdCBuZWdhdGVkRXhwcmVzc2lvbnMgPSBleHByZXNzaW9ucy5tYXAobm90KTtcblx0cmV0dXJuIGV4cHJlc3Npb25zLnNvbWUoKGV4cHJlc3Npb24sIGluZGV4KSA9PiB7XG5cdFx0Zm9yIChsZXQgaSA9IGluZGV4ICsgMTsgaSA8IG5lZ2F0ZWRFeHByZXNzaW9ucy5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoZXhwcmVzc2lvbiwgbmVnYXRlZEV4cHJlc3Npb25zW2ldKSkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9KTtcbn1cblxuLyoqXG4gKiBMb2dpY2FsIGBhbmRgIGV4cHJlc3Npb24uXG4gKlxuICogVGhlIGV4cHJlc3Npb24gaXMgc2ltcGxpZmllZCB0byBmYWxzZSBpZiB0aGlzIGNhbiBiZSBkZWNpZGVkIHN0YXRpY2FsbHkgKHRoYXQgaXMsIGlmIG9uZSBvcGVyYW5kIGlzIGEgY29uc3RhbnRcbiAqIGZhbHNlIG9yIGlmIHRoZSBleHByZXNzaW9uIGNvbnRhaW5zIGFuIG9wZXJhbmQgYW5kIGl0cyBuZWdhdGlvbikuXG4gKlxuICogQHBhcmFtIG9wZXJhbmRzIEV4cHJlc3Npb25zIHRvIGNvbm5lY3QgYnkgYGFuZGBcbiAqIEByZXR1cm5zIEV4cHJlc3Npb24gZXZhbHVhdGluZyB0byBib29sZWFuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbmQoLi4ub3BlcmFuZHM6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxib29sZWFuPltdKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0Y29uc3QgZXhwcmVzc2lvbnMgPSBmbGF0dGVuU2V0RXhwcmVzc2lvbih7XG5cdFx0X3R5cGU6IFwiU2V0XCIsXG5cdFx0b3BlcmF0b3I6IFwiJiZcIixcblx0XHRvcGVyYW5kczogb3BlcmFuZHMubWFwKHdyYXBQcmltaXRpdmUpXG5cdH0pLm9wZXJhbmRzO1xuXG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKC4uLmV4cHJlc3Npb25zKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHR9XG5cdGxldCBpc1N0YXRpY0ZhbHNlID0gZmFsc2U7XG5cdGNvbnN0IG5vblRyaXZpYWxFeHByZXNzaW9uID0gZXhwcmVzc2lvbnMuZmlsdGVyKChleHByZXNzaW9uKSA9PiB7XG5cdFx0aWYgKGlzRmFsc2UoZXhwcmVzc2lvbikpIHtcblx0XHRcdGlzU3RhdGljRmFsc2UgPSB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gIWlzQ29uc3RhbnQoZXhwcmVzc2lvbik7XG5cdH0pO1xuXHRpZiAoaXNTdGF0aWNGYWxzZSkge1xuXHRcdHJldHVybiBjb25zdGFudChmYWxzZSk7XG5cdH0gZWxzZSBpZiAobm9uVHJpdmlhbEV4cHJlc3Npb24ubGVuZ3RoID09PSAwKSB7XG5cdFx0Ly8gUmVzb2x2ZSB0aGUgY29uc3RhbnQgdGhlblxuXHRcdGNvbnN0IGlzVmFsaWQgPSBleHByZXNzaW9ucy5yZWR1Y2UoKHJlc3VsdCwgZXhwcmVzc2lvbikgPT4gcmVzdWx0ICYmIGlzVHJ1ZShleHByZXNzaW9uKSwgdHJ1ZSk7XG5cdFx0cmV0dXJuIGNvbnN0YW50KGlzVmFsaWQpO1xuXHR9IGVsc2UgaWYgKG5vblRyaXZpYWxFeHByZXNzaW9uLmxlbmd0aCA9PT0gMSkge1xuXHRcdHJldHVybiBub25Ucml2aWFsRXhwcmVzc2lvblswXTtcblx0fSBlbHNlIGlmIChoYXNPcHBvc2l0ZUV4cHJlc3Npb25zKG5vblRyaXZpYWxFeHByZXNzaW9uKSkge1xuXHRcdHJldHVybiBjb25zdGFudChmYWxzZSk7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdF90eXBlOiBcIlNldFwiLFxuXHRcdFx0b3BlcmF0b3I6IFwiJiZcIixcblx0XHRcdG9wZXJhbmRzOiBub25Ucml2aWFsRXhwcmVzc2lvblxuXHRcdH07XG5cdH1cbn1cblxuLyoqXG4gKiBMb2dpY2FsIGBvcmAgZXhwcmVzc2lvbi5cbiAqXG4gKiBUaGUgZXhwcmVzc2lvbiBpcyBzaW1wbGlmaWVkIHRvIHRydWUgaWYgdGhpcyBjYW4gYmUgZGVjaWRlZCBzdGF0aWNhbGx5ICh0aGF0IGlzLCBpZiBvbmUgb3BlcmFuZCBpcyBhIGNvbnN0YW50XG4gKiB0cnVlIG9yIGlmIHRoZSBleHByZXNzaW9uIGNvbnRhaW5zIGFuIG9wZXJhbmQgYW5kIGl0cyBuZWdhdGlvbikuXG4gKlxuICogQHBhcmFtIG9wZXJhbmRzIEV4cHJlc3Npb25zIHRvIGNvbm5lY3QgYnkgYG9yYFxuICogQHJldHVybnMgRXhwcmVzc2lvbiBldmFsdWF0aW5nIHRvIGJvb2xlYW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9yKC4uLm9wZXJhbmRzOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8Ym9vbGVhbj5bXSk6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdGNvbnN0IGV4cHJlc3Npb25zID0gZmxhdHRlblNldEV4cHJlc3Npb24oe1xuXHRcdF90eXBlOiBcIlNldFwiLFxuXHRcdG9wZXJhdG9yOiBcInx8XCIsXG5cdFx0b3BlcmFuZHM6IG9wZXJhbmRzLm1hcCh3cmFwUHJpbWl0aXZlKVxuXHR9KS5vcGVyYW5kcztcblx0aWYgKGhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24oLi4uZXhwcmVzc2lvbnMpKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdH1cblx0bGV0IGlzU3RhdGljVHJ1ZSA9IGZhbHNlO1xuXHRjb25zdCBub25Ucml2aWFsRXhwcmVzc2lvbiA9IGV4cHJlc3Npb25zLmZpbHRlcigoZXhwcmVzc2lvbikgPT4ge1xuXHRcdGlmIChpc1RydWUoZXhwcmVzc2lvbikpIHtcblx0XHRcdGlzU3RhdGljVHJ1ZSA9IHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiAhaXNDb25zdGFudChleHByZXNzaW9uKSB8fCBleHByZXNzaW9uLnZhbHVlO1xuXHR9KTtcblx0aWYgKGlzU3RhdGljVHJ1ZSkge1xuXHRcdHJldHVybiBjb25zdGFudCh0cnVlKTtcblx0fSBlbHNlIGlmIChub25Ucml2aWFsRXhwcmVzc2lvbi5sZW5ndGggPT09IDApIHtcblx0XHQvLyBSZXNvbHZlIHRoZSBjb25zdGFudCB0aGVuXG5cdFx0Y29uc3QgaXNWYWxpZCA9IGV4cHJlc3Npb25zLnJlZHVjZSgocmVzdWx0LCBleHByZXNzaW9uKSA9PiByZXN1bHQgJiYgaXNUcnVlKGV4cHJlc3Npb24pLCB0cnVlKTtcblx0XHRyZXR1cm4gY29uc3RhbnQoaXNWYWxpZCk7XG5cdH0gZWxzZSBpZiAobm9uVHJpdmlhbEV4cHJlc3Npb24ubGVuZ3RoID09PSAxKSB7XG5cdFx0cmV0dXJuIG5vblRyaXZpYWxFeHByZXNzaW9uWzBdO1xuXHR9IGVsc2UgaWYgKGhhc09wcG9zaXRlRXhwcmVzc2lvbnMobm9uVHJpdmlhbEV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KHRydWUpO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiB7XG5cdFx0XHRfdHlwZTogXCJTZXRcIixcblx0XHRcdG9wZXJhdG9yOiBcInx8XCIsXG5cdFx0XHRvcGVyYW5kczogbm9uVHJpdmlhbEV4cHJlc3Npb25cblx0XHR9O1xuXHR9XG59XG5cbi8qKlxuICogTG9naWNhbCBgbm90YCBvcGVyYXRvci5cbiAqXG4gKiBAcGFyYW0gb3BlcmFuZCBUaGUgZXhwcmVzc2lvbiB0byByZXZlcnNlXG4gKiBAcmV0dXJucyBUaGUgcmVzdWx0aW5nIGV4cHJlc3Npb24gdGhhdCBldmFsdWF0ZXMgdG8gYm9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gbm90KG9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxib29sZWFuPik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdG9wZXJhbmQgPSB3cmFwUHJpbWl0aXZlKG9wZXJhbmQpO1xuXHRpZiAoaGFzVW5yZXNvbHZhYmxlRXhwcmVzc2lvbihvcGVyYW5kKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHR9IGVsc2UgaWYgKGlzQ29uc3RhbnQob3BlcmFuZCkpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQoIW9wZXJhbmQudmFsdWUpO1xuXHR9IGVsc2UgaWYgKFxuXHRcdHR5cGVvZiBvcGVyYW5kID09PSBcIm9iamVjdFwiICYmXG5cdFx0b3BlcmFuZC5fdHlwZSA9PT0gXCJTZXRcIiAmJlxuXHRcdG9wZXJhbmQub3BlcmF0b3IgPT09IFwifHxcIiAmJlxuXHRcdG9wZXJhbmQub3BlcmFuZHMuZXZlcnkoKGV4cHJlc3Npb24pID0+IGlzQ29uc3RhbnQoZXhwcmVzc2lvbikgfHwgaXNDb21wYXJpc29uKGV4cHJlc3Npb24pKVxuXHQpIHtcblx0XHRyZXR1cm4gYW5kKC4uLm9wZXJhbmQub3BlcmFuZHMubWFwKChleHByZXNzaW9uKSA9PiBub3QoZXhwcmVzc2lvbikpKTtcblx0fSBlbHNlIGlmIChcblx0XHR0eXBlb2Ygb3BlcmFuZCA9PT0gXCJvYmplY3RcIiAmJlxuXHRcdG9wZXJhbmQuX3R5cGUgPT09IFwiU2V0XCIgJiZcblx0XHRvcGVyYW5kLm9wZXJhdG9yID09PSBcIiYmXCIgJiZcblx0XHRvcGVyYW5kLm9wZXJhbmRzLmV2ZXJ5KChleHByZXNzaW9uKSA9PiBpc0NvbnN0YW50KGV4cHJlc3Npb24pIHx8IGlzQ29tcGFyaXNvbihleHByZXNzaW9uKSlcblx0KSB7XG5cdFx0cmV0dXJuIG9yKC4uLm9wZXJhbmQub3BlcmFuZHMubWFwKChleHByZXNzaW9uKSA9PiBub3QoZXhwcmVzc2lvbikpKTtcblx0fSBlbHNlIGlmIChpc0NvbXBhcmlzb24ob3BlcmFuZCkpIHtcblx0XHQvLyBDcmVhdGUgdGhlIHJldmVyc2UgY29tcGFyaXNvblxuXHRcdHN3aXRjaCAob3BlcmFuZC5vcGVyYXRvcikge1xuXHRcdFx0Y2FzZSBcIiE9PVwiOlxuXHRcdFx0XHRyZXR1cm4geyAuLi5vcGVyYW5kLCBvcGVyYXRvcjogXCI9PT1cIiB9O1xuXHRcdFx0Y2FzZSBcIjxcIjpcblx0XHRcdFx0cmV0dXJuIHsgLi4ub3BlcmFuZCwgb3BlcmF0b3I6IFwiPj1cIiB9O1xuXHRcdFx0Y2FzZSBcIjw9XCI6XG5cdFx0XHRcdHJldHVybiB7IC4uLm9wZXJhbmQsIG9wZXJhdG9yOiBcIj5cIiB9O1xuXHRcdFx0Y2FzZSBcIj09PVwiOlxuXHRcdFx0XHRyZXR1cm4geyAuLi5vcGVyYW5kLCBvcGVyYXRvcjogXCIhPT1cIiB9O1xuXHRcdFx0Y2FzZSBcIj5cIjpcblx0XHRcdFx0cmV0dXJuIHsgLi4ub3BlcmFuZCwgb3BlcmF0b3I6IFwiPD1cIiB9O1xuXHRcdFx0Y2FzZSBcIj49XCI6XG5cdFx0XHRcdHJldHVybiB7IC4uLm9wZXJhbmQsIG9wZXJhdG9yOiBcIjxcIiB9O1xuXHRcdH1cblx0fSBlbHNlIGlmIChvcGVyYW5kLl90eXBlID09PSBcIk5vdFwiKSB7XG5cdFx0cmV0dXJuIG9wZXJhbmQub3BlcmFuZDtcblx0fVxuXG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiTm90XCIsXG5cdFx0b3BlcmFuZDogb3BlcmFuZFxuXHR9O1xufVxuXG4vKipcbiAqIEV2YWx1YXRlcyB3aGV0aGVyIGEgYmluZGluZyBleHByZXNzaW9uIGlzIGVxdWFsIHRvIHRydWUgd2l0aCBhIGxvb3NlIGVxdWFsaXR5LlxuICpcbiAqIEBwYXJhbSBvcGVyYW5kIFRoZSBleHByZXNzaW9uIHRvIGNoZWNrXG4gKiBAcmV0dXJucyBUaGUgcmVzdWx0aW5nIGV4cHJlc3Npb24gdGhhdCBldmFsdWF0ZXMgdG8gYm9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNUcnV0aHkob3BlcmFuZDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHN0cmluZz4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRpZiAoaXNDb25zdGFudChvcGVyYW5kKSkge1xuXHRcdHJldHVybiBjb25zdGFudCghIW9wZXJhbmQudmFsdWUpO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiB7XG5cdFx0XHRfdHlwZTogXCJUcnV0aHlcIixcblx0XHRcdG9wZXJhbmQ6IG9wZXJhbmRcblx0XHR9O1xuXHR9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGJpbmRpbmcgZXhwcmVzc2lvbiB0aGF0IHdpbGwgYmUgZXZhbHVhdGVkIGJ5IHRoZSBjb3JyZXNwb25kaW5nIG1vZGVsLlxuICpcbiAqIEBwYXJhbSBwYXRoXG4gKiBAcGFyYW0gbW9kZWxOYW1lXG4gKiBAcGFyYW0gdmlzaXRlZE5hdmlnYXRpb25QYXRoc1xuICogQHBhcmFtIHBhdGhWaXNpdG9yXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGF0aW5nIHRoYXQgcGF0aCBpbiB0aGUgbW9kZWxcbiAqIEBkZXByZWNhdGVkIHVzZSBwYXRoSW5Nb2RlbCBpbnN0ZWFkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiaW5kaW5nRXhwcmVzc2lvbjxUYXJnZXRUeXBlIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdHBhdGg6IHN0cmluZyxcblx0bW9kZWxOYW1lPzogc3RyaW5nLFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VGFyZ2V0VHlwZT4gfCBVbnJlc29sdmFibGVQYXRoRXhwcmVzc2lvbiB7XG5cdHJldHVybiBwYXRoSW5Nb2RlbChwYXRoLCBtb2RlbE5hbWUsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgYmluZGluZyBleHByZXNzaW9uIHRoYXQgd2lsbCBiZSBldmFsdWF0ZWQgYnkgdGhlIGNvcnJlc3BvbmRpbmcgbW9kZWwuXG4gKlxuICogQHRlbXBsYXRlIFRhcmdldFR5cGVcbiAqIEBwYXJhbSBwYXRoIFRoZSBwYXRoIG9uIHRoZSBtb2RlbFxuICogQHBhcmFtIFttb2RlbE5hbWVdIFRoZSBuYW1lIG9mIHRoZSBtb2RlbFxuICogQHBhcmFtIFt2aXNpdGVkTmF2aWdhdGlvblBhdGhzXSBUaGUgcGF0aHMgZnJvbSB0aGUgcm9vdCBlbnRpdHlTZXRcbiAqIEBwYXJhbSBbcGF0aFZpc2l0b3JdIEEgZnVuY3Rpb24gdG8gbW9kaWZ5IHRoZSByZXN1bHRpbmcgcGF0aFxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRhdGluZyB0aGF0IHBhdGggaW4gdGhlIG1vZGVsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXRoSW5Nb2RlbChcblx0cGF0aDogdW5kZWZpbmVkLFxuXHRtb2RlbE5hbWU/OiBzdHJpbmcsXG5cdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHM/OiBzdHJpbmdbXSxcblx0cGF0aFZpc2l0b3I/OiBGdW5jdGlvblxuKTogVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb247XG5leHBvcnQgZnVuY3Rpb24gcGF0aEluTW9kZWw8VGFyZ2V0VHlwZSBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRwYXRoOiBzdHJpbmcsXG5cdG1vZGVsTmFtZT86IHN0cmluZyxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRocz86IHN0cmluZ1tdLFxuXHRwYXRoVmlzaXRvcj86IHVuZGVmaW5lZFxuKTogUGF0aEluTW9kZWxFeHByZXNzaW9uPFRhcmdldFR5cGU+O1xuZXhwb3J0IGZ1bmN0aW9uIHBhdGhJbk1vZGVsPFRhcmdldFR5cGUgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0cGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuXHRtb2RlbE5hbWU/OiBzdHJpbmcsXG5cdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHM/OiBzdHJpbmdbXSxcblx0cGF0aFZpc2l0b3I/OiBGdW5jdGlvblxuKTogVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb24gfCBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VGFyZ2V0VHlwZT47XG5leHBvcnQgZnVuY3Rpb24gcGF0aEluTW9kZWw8VGFyZ2V0VHlwZSBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRwYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQsXG5cdG1vZGVsTmFtZT86IHN0cmluZyxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRoczogc3RyaW5nW10gPSBbXSxcblx0cGF0aFZpc2l0b3I/OiBGdW5jdGlvblxuKTogVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb24gfCBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VGFyZ2V0VHlwZT4ge1xuXHRpZiAocGF0aCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdH1cblx0bGV0IHRhcmdldFBhdGg7XG5cdGlmIChwYXRoVmlzaXRvcikge1xuXHRcdHRhcmdldFBhdGggPSBwYXRoVmlzaXRvcihwYXRoKTtcblx0XHRpZiAodGFyZ2V0UGF0aCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0Y29uc3QgbG9jYWxQYXRoID0gdmlzaXRlZE5hdmlnYXRpb25QYXRocy5jb25jYXQoKTtcblx0XHRsb2NhbFBhdGgucHVzaChwYXRoKTtcblx0XHR0YXJnZXRQYXRoID0gbG9jYWxQYXRoLmpvaW4oXCIvXCIpO1xuXHR9XG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiUGF0aEluTW9kZWxcIixcblx0XHRtb2RlbE5hbWU6IG1vZGVsTmFtZSxcblx0XHRwYXRoOiB0YXJnZXRQYXRoXG5cdH07XG59XG5cbnR5cGUgUGxhaW5FeHByZXNzaW9uT2JqZWN0ID0geyBbaW5kZXg6IHN0cmluZ106IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPiB9O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjb25zdGFudCBleHByZXNzaW9uIGJhc2VkIG9uIGEgcHJpbWl0aXZlIHZhbHVlLlxuICpcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAcGFyYW0gdmFsdWUgVGhlIGNvbnN0YW50IHRvIHdyYXAgaW4gYW4gZXhwcmVzc2lvblxuICogQHJldHVybnMgVGhlIGNvbnN0YW50IGV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbnN0YW50PFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPih2YWx1ZTogVCk6IENvbnN0YW50RXhwcmVzc2lvbjxUPiB7XG5cdGxldCBjb25zdGFudFZhbHVlOiBUO1xuXG5cdGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUgIT09IHVuZGVmaW5lZCkge1xuXHRcdGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuXHRcdFx0Y29uc3RhbnRWYWx1ZSA9IHZhbHVlLm1hcCh3cmFwUHJpbWl0aXZlKSBhcyBUO1xuXHRcdH0gZWxzZSBpZiAoaXNQcmltaXRpdmVPYmplY3QodmFsdWUpKSB7XG5cdFx0XHRjb25zdGFudFZhbHVlID0gdmFsdWUudmFsdWVPZigpIGFzIFQ7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0YW50VmFsdWUgPSBPYmplY3QuZW50cmllcyh2YWx1ZSkucmVkdWNlKChwbGFpbkV4cHJlc3Npb24sIFtrZXksIHZhbF0pID0+IHtcblx0XHRcdFx0Y29uc3Qgd3JhcHBlZFZhbHVlID0gd3JhcFByaW1pdGl2ZSh2YWwpO1xuXHRcdFx0XHRpZiAod3JhcHBlZFZhbHVlLl90eXBlICE9PSBcIkNvbnN0YW50XCIgfHwgd3JhcHBlZFZhbHVlLnZhbHVlICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0XHRwbGFpbkV4cHJlc3Npb25ba2V5XSA9IHdyYXBwZWRWYWx1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gcGxhaW5FeHByZXNzaW9uO1xuXHRcdFx0fSwge30gYXMgUGxhaW5FeHByZXNzaW9uT2JqZWN0KSBhcyBUO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRjb25zdGFudFZhbHVlID0gdmFsdWU7XG5cdH1cblxuXHRyZXR1cm4geyBfdHlwZTogXCJDb25zdGFudFwiLCB2YWx1ZTogY29uc3RhbnRWYWx1ZSB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUJpbmRpbmdTdHJpbmc8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHR2YWx1ZTogc3RyaW5nIHwgYm9vbGVhbiB8IG51bWJlcixcblx0dGFyZ2V0VHlwZT86IHN0cmluZ1xuKTogQ29uc3RhbnRFeHByZXNzaW9uPFQ+IHwgUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+IHwgRW1iZWRkZWRVSTVCaW5kaW5nRXhwcmVzc2lvbjxUPiB8IEVtYmVkZGVkVUk1RXhwcmVzc2lvbkJpbmRpbmdFeHByZXNzaW9uPFQ+IHtcblx0aWYgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmIHZhbHVlLnN0YXJ0c1dpdGgoXCJ7XCIpKSB7XG5cdFx0Y29uc3QgcGF0aEluTW9kZWxSZWdleCA9IC9eeyguKik+KC4rKX0kLzsgLy8gTWF0Y2hlcyBtb2RlbCBwYXRocyBsaWtlIFwibW9kZWw+cGF0aFwiIG9yIFwiPnBhdGhcIiAoZGVmYXVsdCBtb2RlbClcblx0XHRjb25zdCBwYXRoSW5Nb2RlbFJlZ2V4TWF0Y2ggPSBwYXRoSW5Nb2RlbFJlZ2V4LmV4ZWModmFsdWUpO1xuXG5cdFx0aWYgKHZhbHVlLnN0YXJ0c1dpdGgoXCJ7PVwiKSkge1xuXHRcdFx0Ly8gRXhwcmVzc2lvbiBiaW5kaW5nLCB3ZSBjYW4ganVzdCByZW1vdmUgdGhlIG91dGVyIGJpbmRpbmcgdGhpbmdzXG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRfdHlwZTogXCJFbWJlZGRlZEV4cHJlc3Npb25CaW5kaW5nXCIsXG5cdFx0XHRcdHZhbHVlOiB2YWx1ZVxuXHRcdFx0fTtcblx0XHR9IGVsc2UgaWYgKHBhdGhJbk1vZGVsUmVnZXhNYXRjaCkge1xuXHRcdFx0cmV0dXJuIHBhdGhJbk1vZGVsKHBhdGhJbk1vZGVsUmVnZXhNYXRjaFsyXSB8fCBcIlwiLCBwYXRoSW5Nb2RlbFJlZ2V4TWF0Y2hbMV0gfHwgdW5kZWZpbmVkKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0X3R5cGU6IFwiRW1iZWRkZWRCaW5kaW5nXCIsXG5cdFx0XHRcdHZhbHVlOiB2YWx1ZVxuXHRcdFx0fTtcblx0XHR9XG5cdH0gZWxzZSBpZiAodGFyZ2V0VHlwZSA9PT0gXCJib29sZWFuXCIgJiYgdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmICh2YWx1ZSA9PT0gXCJ0cnVlXCIgfHwgdmFsdWUgPT09IFwiZmFsc2VcIikpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQodmFsdWUgPT09IFwidHJ1ZVwiKSBhcyBDb25zdGFudEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAodGFyZ2V0VHlwZSA9PT0gXCJudW1iZXJcIiAmJiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiYgKCFpc05hTihOdW1iZXIodmFsdWUpKSB8fCB2YWx1ZSA9PT0gXCJOYU5cIikpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQoTnVtYmVyKHZhbHVlKSkgYXMgQ29uc3RhbnRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBjb25zdGFudCh2YWx1ZSkgYXMgQ29uc3RhbnRFeHByZXNzaW9uPFQ+O1xuXHR9XG59XG5cbi8qKlxuICogQSBuYW1lZCByZWZlcmVuY2UuXG4gKlxuICogQHNlZSBmblxuICogQHBhcmFtIHJlZmVyZW5jZSBSZWZlcmVuY2VcbiAqIEByZXR1cm5zIFRoZSBvYmplY3QgcmVmZXJlbmNlIGJpbmRpbmcgcGFydFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVmKHJlZmVyZW5jZTogc3RyaW5nIHwgbnVsbCk6IFJlZmVyZW5jZUV4cHJlc3Npb24ge1xuXHRyZXR1cm4geyBfdHlwZTogXCJSZWZcIiwgcmVmOiByZWZlcmVuY2UgfTtcbn1cblxuLyoqXG4gKiBXcmFwIGEgcHJpbWl0aXZlIGludG8gYSBjb25zdGFudCBleHByZXNzaW9uIGlmIGl0IGlzIG5vdCBhbHJlYWR5IGFuIGV4cHJlc3Npb24uXG4gKlxuICogQHRlbXBsYXRlIFRcbiAqIEBwYXJhbSBzb21ldGhpbmcgVGhlIG9iamVjdCB0byB3cmFwIGluIGEgQ29uc3RhbnQgZXhwcmVzc2lvblxuICogQHJldHVybnMgRWl0aGVyIHRoZSBvcmlnaW5hbCBvYmplY3Qgb3IgdGhlIHdyYXBwZWQgb25lIGRlcGVuZGluZyBvbiB0aGUgY2FzZVxuICovXG5leHBvcnQgZnVuY3Rpb24gd3JhcFByaW1pdGl2ZTxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oc29tZXRoaW5nOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4ge1xuXHRpZiAoaXNCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb24oc29tZXRoaW5nKSkge1xuXHRcdHJldHVybiBzb21ldGhpbmcgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9XG5cblx0cmV0dXJuIGNvbnN0YW50KHNvbWV0aGluZyk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBleHByZXNzaW9uIG9yIHZhbHVlIHByb3ZpZGVkIGlzIGEgYmluZGluZyB0b29saW5nIGV4cHJlc3Npb24gb3Igbm90LlxuICpcbiAqIEV2ZXJ5IG9iamVjdCBoYXZpbmcgYSBwcm9wZXJ0eSBuYW1lZCBgX3R5cGVgIG9mIHNvbWUgdmFsdWUgaXMgY29uc2lkZXJlZCBhbiBleHByZXNzaW9uLCBldmVuIGlmIHRoZXJlIGlzIGFjdHVhbGx5XG4gKiBubyBzdWNoIGV4cHJlc3Npb24gdHlwZSBzdXBwb3J0ZWQuXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb25cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgZXhwcmVzc2lvbiBpcyBhIGJpbmRpbmcgdG9vbGtpdCBleHByZXNzaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0JpbmRpbmdUb29sa2l0RXhwcmVzc2lvbihcblx0ZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+IHwgdW5rbm93blxuKTogZXhwcmVzc2lvbiBpcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj4ge1xuXHRyZXR1cm4gKGV4cHJlc3Npb24gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+KT8uX3R5cGUgIT09IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGV4cHJlc3Npb24gb3IgdmFsdWUgcHJvdmlkZWQgaXMgY29uc3RhbnQgb3Igbm90LlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtICBtYXliZUNvbnN0YW50IFRoZSBleHByZXNzaW9uIG9yIHByaW1pdGl2ZSB2YWx1ZSB0aGF0IGlzIHRvIGJlIGNoZWNrZWRcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiBpdCBpcyBjb25zdGFudFxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb25zdGFudDxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4obWF5YmVDb25zdGFudDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+KTogbWF5YmVDb25zdGFudCBpcyBDb25zdGFudEV4cHJlc3Npb248VD4ge1xuXHRyZXR1cm4gdHlwZW9mIG1heWJlQ29uc3RhbnQgIT09IFwib2JqZWN0XCIgfHwgKG1heWJlQ29uc3RhbnQgYXMgQmFzZUV4cHJlc3Npb248VD4pLl90eXBlID09PSBcIkNvbnN0YW50XCI7XG59XG5cbmZ1bmN0aW9uIGlzVHJ1ZShleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4pOiBib29sZWFuIHtcblx0cmV0dXJuIGlzQ29uc3RhbnQoZXhwcmVzc2lvbikgJiYgZXhwcmVzc2lvbi52YWx1ZSA9PT0gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gaXNGYWxzZShleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4pOiBib29sZWFuIHtcblx0cmV0dXJuIGlzQ29uc3RhbnQoZXhwcmVzc2lvbikgJiYgZXhwcmVzc2lvbi52YWx1ZSA9PT0gZmFsc2U7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBleHByZXNzaW9uIG9yIHZhbHVlIHByb3ZpZGVkIGlzIGEgcGF0aCBpbiBtb2RlbCBleHByZXNzaW9uIG9yIG5vdC5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSAgbWF5YmVCaW5kaW5nIFRoZSBleHByZXNzaW9uIG9yIHByaW1pdGl2ZSB2YWx1ZSB0aGF0IGlzIHRvIGJlIGNoZWNrZWRcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiBpdCBpcyBhIHBhdGggaW4gbW9kZWwgZXhwcmVzc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNQYXRoSW5Nb2RlbEV4cHJlc3Npb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRtYXliZUJpbmRpbmc6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogbWF5YmVCaW5kaW5nIGlzIFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPiB7XG5cdHJldHVybiAobWF5YmVCaW5kaW5nIGFzIEJhc2VFeHByZXNzaW9uPFQ+KT8uX3R5cGUgPT09IFwiUGF0aEluTW9kZWxcIjtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGV4cHJlc3Npb24gb3IgdmFsdWUgcHJvdmlkZWQgaXMgYSBjb21wbGV4IHR5cGUgZXhwcmVzc2lvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSAgbWF5YmVCaW5kaW5nIFRoZSBleHByZXNzaW9uIG9yIHByaW1pdGl2ZSB2YWx1ZSB0aGF0IGlzIHRvIGJlIGNoZWNrZWRcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiBpdCBpcyBhIHBhdGggaW4gbW9kZWwgZXhwcmVzc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb21wbGV4VHlwZUV4cHJlc3Npb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRtYXliZUJpbmRpbmc6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogbWF5YmVCaW5kaW5nIGlzIENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPiB7XG5cdHJldHVybiAobWF5YmVCaW5kaW5nIGFzIEJhc2VFeHByZXNzaW9uPFQ+KT8uX3R5cGUgPT09IFwiQ29tcGxleFR5cGVcIjtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGV4cHJlc3Npb24gb3IgdmFsdWUgcHJvdmlkZWQgaXMgYSBjb25jYXQgZXhwcmVzc2lvbiBvciBub3QuXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb25cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgZXhwcmVzc2lvbiBpcyBhIENvbmNhdEV4cHJlc3Npb25cbiAqL1xuZnVuY3Rpb24gaXNDb25jYXRFeHByZXNzaW9uKGV4cHJlc3Npb246IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPik6IGV4cHJlc3Npb24gaXMgQ29uY2F0RXhwcmVzc2lvbiB7XG5cdHJldHVybiAoZXhwcmVzc2lvbiBhcyBCYXNlRXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPik/Ll90eXBlID09PSBcIkNvbmNhdFwiO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZXhwcmVzc2lvbiBvciB2YWx1ZSBwcm92aWRlZCBpcyBhIElmRWxzZSBleHByZXNzaW9uIG9yIG5vdC5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvblxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBleHByZXNzaW9uIGlzIGEgSWZFbHNlRXhwcmVzc2lvblxuICovXG5mdW5jdGlvbiBpc0lmRWxzZUV4cHJlc3Npb24oZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+KTogZXhwcmVzc2lvbiBpcyBDb25jYXRFeHByZXNzaW9uIHtcblx0cmV0dXJuIChleHByZXNzaW9uIGFzIEJhc2VFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+KT8uX3R5cGUgPT09IFwiSWZFbHNlXCI7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBleHByZXNzaW9uIHByb3ZpZGVkIGlzIGEgY29tcGFyaXNvbiBvciBub3QuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgZXhwcmVzc2lvblxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBleHByZXNzaW9uIGlzIGEgQ29tcGFyaXNvbkV4cHJlc3Npb25cbiAqL1xuZnVuY3Rpb24gaXNDb21wYXJpc29uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4pOiBleHByZXNzaW9uIGlzIENvbXBhcmlzb25FeHByZXNzaW9uIHtcblx0cmV0dXJuIGV4cHJlc3Npb24uX3R5cGUgPT09IFwiQ29tcGFyaXNvblwiO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBpbnB1dCBwYXJhbWV0ZXIgaXMgYSBjb25zdGFudCBleHByZXNzaW9uIG9mIHR5cGUgdW5kZWZpbmVkLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBpbnB1dCBleHByZXNzaW9uIG9yIG9iamVjdCBpbiBnZW5lcmFsXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGlucHV0IGlzIGNvbnN0YW50IHdoaWNoIGhhcyB1bmRlZmluZWQgZm9yIHZhbHVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1VuZGVmaW5lZEV4cHJlc3Npb24oZXhwcmVzc2lvbjogdW5rbm93bik6IGV4cHJlc3Npb24gaXMgQ29uc3RhbnRFeHByZXNzaW9uPHVuZGVmaW5lZD4ge1xuXHRjb25zdCBleHByZXNzaW9uQXNFeHByZXNzaW9uID0gZXhwcmVzc2lvbiBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj47XG5cdHJldHVybiBleHByZXNzaW9uQXNFeHByZXNzaW9uPy5fdHlwZSA9PT0gXCJDb25zdGFudFwiICYmIGV4cHJlc3Npb25Bc0V4cHJlc3Npb24/LnZhbHVlID09PSB1bmRlZmluZWQ7XG59XG5cbnR5cGUgQ29tcGxleEFubm90YXRpb25FeHByZXNzaW9uPFA+ID1cblx0fCBQYXRoQW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBBcHBseUFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgSWZBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IE9yQW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBBbmRBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IE5lQW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBFcUFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgTm90QW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBHdEFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgR2VBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IExlQW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBMdEFubm90YXRpb25FeHByZXNzaW9uPFA+O1xuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZU9iamVjdChvYmplY3RUeXBlOiBvYmplY3QpOiBib29sZWFuIHtcblx0c3dpdGNoIChvYmplY3RUeXBlLmNvbnN0cnVjdG9yLm5hbWUpIHtcblx0XHRjYXNlIFwiU3RyaW5nXCI6XG5cdFx0Y2FzZSBcIk51bWJlclwiOlxuXHRcdGNhc2UgXCJCb29sZWFuXCI6XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRkZWZhdWx0OlxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59XG4vKipcbiAqIENoZWNrIGlmIHRoZSBwYXNzZWQgYW5ub3RhdGlvbiBhbm5vdGF0aW9uVmFsdWUgaXMgYSBDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb24uXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gIGFubm90YXRpb25WYWx1ZSBUaGUgYW5ub3RhdGlvbiBhbm5vdGF0aW9uVmFsdWUgdG8gZXZhbHVhdGVcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0IGlzIGEge0NvbXBsZXhBbm5vdGF0aW9uRXhwcmVzc2lvbn1cbiAqL1xuZnVuY3Rpb24gaXNDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb248VD4oYW5ub3RhdGlvblZhbHVlOiBQcm9wZXJ0eUFubm90YXRpb25WYWx1ZTxUPik6IGFubm90YXRpb25WYWx1ZSBpcyBDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb248VD4ge1xuXHRyZXR1cm4gdHlwZW9mIGFubm90YXRpb25WYWx1ZSA9PT0gXCJvYmplY3RcIiAmJiAhaXNQcmltaXRpdmVPYmplY3QoYW5ub3RhdGlvblZhbHVlIGFzIG9iamVjdCk7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgdGhlIGNvcnJlc3BvbmRpbmcgYW5ub3RhdGlvblZhbHVlIGZvciBhIGdpdmVuIGFubm90YXRpb24gYW5ub3RhdGlvblZhbHVlLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGFubm90YXRpb25WYWx1ZSBUaGUgc291cmNlIGFubm90YXRpb24gYW5ub3RhdGlvblZhbHVlXG4gKiBAcGFyYW0gdmlzaXRlZE5hdmlnYXRpb25QYXRocyBUaGUgcGF0aCBmcm9tIHRoZSByb290IGVudGl0eSBzZXRcbiAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgRGVmYXVsdCB2YWx1ZSBpZiB0aGUgYW5ub3RhdGlvblZhbHVlIGlzIHVuZGVmaW5lZFxuICogQHBhcmFtIHBhdGhWaXNpdG9yIEEgZnVuY3Rpb24gdG8gbW9kaWZ5IHRoZSByZXN1bHRpbmcgcGF0aFxuICogQHJldHVybnMgVGhlIGFubm90YXRpb25WYWx1ZSBlcXVpdmFsZW50IHRvIHRoYXQgYW5ub3RhdGlvbiBhbm5vdGF0aW9uVmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEV4cHJlc3Npb25Gcm9tQW5ub3RhdGlvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGFubm90YXRpb25WYWx1ZTogUHJvcGVydHlBbm5vdGF0aW9uVmFsdWU8VD4gfCB1bmRlZmluZWQsXG5cdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHM6IHN0cmluZ1tdID0gW10sXG5cdGRlZmF1bHRWYWx1ZT86IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cGF0aFZpc2l0b3I/OiBGdW5jdGlvblxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+PiB7XG5cdGlmIChhbm5vdGF0aW9uVmFsdWUgPT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiB3cmFwUHJpbWl0aXZlKGRlZmF1bHRWYWx1ZSBhcyBQcmltaXRpdmVUeXBlQ2FzdDxUPik7XG5cdH1cblx0YW5ub3RhdGlvblZhbHVlID0gYW5ub3RhdGlvblZhbHVlPy52YWx1ZU9mKCkgYXMgUHJvcGVydHlBbm5vdGF0aW9uVmFsdWU8VD47XG5cdGlmICghaXNDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb24oYW5ub3RhdGlvblZhbHVlKSkge1xuXHRcdHJldHVybiBjb25zdGFudChhbm5vdGF0aW9uVmFsdWUpO1xuXHR9XG5cblx0c3dpdGNoIChhbm5vdGF0aW9uVmFsdWUudHlwZSkge1xuXHRcdGNhc2UgXCJQYXRoXCI6XG5cdFx0XHRyZXR1cm4gcGF0aEluTW9kZWwoYW5ub3RhdGlvblZhbHVlLnBhdGgsIHVuZGVmaW5lZCwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpO1xuXHRcdGNhc2UgXCJJZlwiOlxuXHRcdFx0cmV0dXJuIGFubm90YXRpb25JZkV4cHJlc3Npb24oYW5ub3RhdGlvblZhbHVlLklmLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcikgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFxuXHRcdFx0XHRQcmltaXRpdmVUeXBlQ2FzdDxUPlxuXHRcdFx0Pjtcblx0XHRjYXNlIFwiTm90XCI6XG5cdFx0XHRyZXR1cm4gbm90KHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuTm90LCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcikpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxcblx0XHRcdFx0UHJpbWl0aXZlVHlwZUNhc3Q8VD5cblx0XHRcdD47XG5cdFx0Y2FzZSBcIkVxXCI6XG5cdFx0XHRyZXR1cm4gZXF1YWwoXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuRXFbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5FcVsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIk5lXCI6XG5cdFx0XHRyZXR1cm4gbm90RXF1YWwoXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuTmVbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5OZVsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIkd0XCI6XG5cdFx0XHRyZXR1cm4gZ3JlYXRlclRoYW4oXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuR3RbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5HdFsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIkdlXCI6XG5cdFx0XHRyZXR1cm4gZ3JlYXRlck9yRXF1YWwoXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuR2VbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5HZVsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIkx0XCI6XG5cdFx0XHRyZXR1cm4gbGVzc1RoYW4oXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuTHRbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5MdFsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIkxlXCI6XG5cdFx0XHRyZXR1cm4gbGVzc09yRXF1YWwoXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuTGVbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5MZVsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIk9yXCI6XG5cdFx0XHRyZXR1cm4gb3IoXG5cdFx0XHRcdC4uLmFubm90YXRpb25WYWx1ZS5Pci5tYXAoZnVuY3Rpb24gKG9yQ29uZGl0aW9uKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbjxib29sZWFuPihvckNvbmRpdGlvbiwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpO1xuXHRcdFx0XHR9KVxuXHRcdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZUNhc3Q8VD4+O1xuXHRcdGNhc2UgXCJBbmRcIjpcblx0XHRcdHJldHVybiBhbmQoXG5cdFx0XHRcdC4uLmFubm90YXRpb25WYWx1ZS5BbmQubWFwKGZ1bmN0aW9uIChhbmRDb25kaXRpb24pIHtcblx0XHRcdFx0XHRyZXR1cm4gcGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uPGJvb2xlYW4+KGFuZENvbmRpdGlvbiwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpO1xuXHRcdFx0XHR9KVxuXHRcdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZUNhc3Q8VD4+O1xuXHRcdGNhc2UgXCJBcHBseVwiOlxuXHRcdFx0cmV0dXJuIGFubm90YXRpb25BcHBseUV4cHJlc3Npb24oXG5cdFx0XHRcdGFubm90YXRpb25WYWx1ZSBhcyBBcHBseUFubm90YXRpb25FeHByZXNzaW9uPHN0cmluZz4sXG5cdFx0XHRcdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsXG5cdFx0XHRcdHBhdGhWaXNpdG9yXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdH1cblx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG59XG5cbi8qKlxuICogUGFyc2UgdGhlIGFubm90YXRpb24gY29uZGl0aW9uIGludG8gYW4gZXhwcmVzc2lvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBhbm5vdGF0aW9uVmFsdWUgVGhlIGNvbmRpdGlvbiBvciB2YWx1ZSBmcm9tIHRoZSBhbm5vdGF0aW9uXG4gKiBAcGFyYW0gdmlzaXRlZE5hdmlnYXRpb25QYXRocyBUaGUgcGF0aCBmcm9tIHRoZSByb290IGVudGl0eSBzZXRcbiAqIEBwYXJhbSBwYXRoVmlzaXRvciBBIGZ1bmN0aW9uIHRvIG1vZGlmeSB0aGUgcmVzdWx0aW5nIHBhdGhcbiAqIEByZXR1cm5zIEFuIGVxdWl2YWxlbnQgZXhwcmVzc2lvblxuICovXG5mdW5jdGlvbiBwYXJzZUFubm90YXRpb25Db25kaXRpb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRhbm5vdGF0aW9uVmFsdWU6IENvbmRpdGlvbmFsQ2hlY2tPclZhbHVlLFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4ge1xuXHRpZiAoYW5ub3RhdGlvblZhbHVlID09PSBudWxsIHx8IHR5cGVvZiBhbm5vdGF0aW9uVmFsdWUgIT09IFwib2JqZWN0XCIpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQoYW5ub3RhdGlvblZhbHVlIGFzIFQpO1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRPclwiKSkge1xuXHRcdHJldHVybiBvcihcblx0XHRcdC4uLigoYW5ub3RhdGlvblZhbHVlIGFzIE9yQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kT3IubWFwKGZ1bmN0aW9uIChvckNvbmRpdGlvbikge1xuXHRcdFx0XHRyZXR1cm4gcGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKG9yQ29uZGl0aW9uLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG5cdFx0XHR9KSBhcyB1bmtub3duIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPltdKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRBbmRcIikpIHtcblx0XHRyZXR1cm4gYW5kKFxuXHRcdFx0Li4uKChhbm5vdGF0aW9uVmFsdWUgYXMgQW5kQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kQW5kLm1hcChmdW5jdGlvbiAoYW5kQ29uZGl0aW9uKSB7XG5cdFx0XHRcdHJldHVybiBwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5kQ29uZGl0aW9uLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG5cdFx0XHR9KSBhcyB1bmtub3duIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPltdKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiROb3RcIikpIHtcblx0XHRyZXR1cm4gbm90KFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgTm90Q29uZGl0aW9uYWxFeHByZXNzaW9uKS4kTm90LCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkRXFcIikpIHtcblx0XHRyZXR1cm4gZXF1YWwoXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBFcUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEVxWzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBFcUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEVxWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkTmVcIikpIHtcblx0XHRyZXR1cm4gbm90RXF1YWwoXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBOZUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJE5lWzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBOZUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJE5lWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkR3RcIikpIHtcblx0XHRyZXR1cm4gZ3JlYXRlclRoYW4oXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBHdENvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEd0WzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBHdENvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEd0WzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkR2VcIikpIHtcblx0XHRyZXR1cm4gZ3JlYXRlck9yRXF1YWwoXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBHZUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEdlWzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBHZUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEdlWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkTHRcIikpIHtcblx0XHRyZXR1cm4gbGVzc1RoYW4oXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBMdENvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEx0WzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBMdENvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEx0WzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkTGVcIikpIHtcblx0XHRyZXR1cm4gbGVzc09yRXF1YWwoXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBMZUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJExlWzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBMZUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJExlWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkUGF0aFwiKSkge1xuXHRcdHJldHVybiBwYXRoSW5Nb2RlbCgoYW5ub3RhdGlvblZhbHVlIGFzIFBhdGhDb25kaXRpb25FeHByZXNzaW9uPFQ+KS4kUGF0aCwgdW5kZWZpbmVkLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJEFwcGx5XCIpKSB7XG5cdFx0cmV0dXJuIGdldEV4cHJlc3Npb25Gcm9tQW5ub3RhdGlvbihcblx0XHRcdHtcblx0XHRcdFx0dHlwZTogXCJBcHBseVwiLFxuXHRcdFx0XHRGdW5jdGlvbjogKGFubm90YXRpb25WYWx1ZSBhcyB7ICRGdW5jdGlvbj86IHN0cmluZyB9KS4kRnVuY3Rpb24sXG5cdFx0XHRcdEFwcGx5OiAoYW5ub3RhdGlvblZhbHVlIGFzIHsgJEFwcGx5PzogdW5rbm93biB9KS4kQXBwbHlcblx0XHRcdH0gYXMgQXBwbHlBbm5vdGF0aW9uRXhwcmVzc2lvbjxUPixcblx0XHRcdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsXG5cdFx0XHR1bmRlZmluZWQsXG5cdFx0XHRwYXRoVmlzaXRvclxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRJZlwiKSkge1xuXHRcdHJldHVybiBnZXRFeHByZXNzaW9uRnJvbUFubm90YXRpb24oXG5cdFx0XHR7XG5cdFx0XHRcdHR5cGU6IFwiSWZcIixcblx0XHRcdFx0SWY6IChhbm5vdGF0aW9uVmFsdWUgYXMgeyAkSWY/OiB1bmtub3duIH0pLiRJZlxuXHRcdFx0fSBhcyBJZkFubm90YXRpb25FeHByZXNzaW9uPFQ+LFxuXHRcdFx0dmlzaXRlZE5hdmlnYXRpb25QYXRocyxcblx0XHRcdHVuZGVmaW5lZCxcblx0XHRcdHBhdGhWaXNpdG9yXG5cdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJEVudW1NZW1iZXJcIikpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQocmVzb2x2ZUVudW1WYWx1ZSgoYW5ub3RhdGlvblZhbHVlIGFzIHsgJEVudW1NZW1iZXI/OiBzdHJpbmcgfSkuJEVudW1NZW1iZXIpIGFzIFQpO1xuXHR9XG5cdHJldHVybiBjb25zdGFudChmYWxzZSBhcyBUKTtcbn1cblxuLyoqXG4gKiBQcm9jZXNzIHRoZSB7SWZBbm5vdGF0aW9uRXhwcmVzc2lvblZhbHVlfSBpbnRvIGFuIGV4cHJlc3Npb24uXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gYW5ub3RhdGlvblZhbHVlIEFuIElmIGV4cHJlc3Npb24gcmV0dXJuaW5nIHRoZSB0eXBlIFRcbiAqIEBwYXJhbSB2aXNpdGVkTmF2aWdhdGlvblBhdGhzIFRoZSBwYXRoIGZyb20gdGhlIHJvb3QgZW50aXR5IHNldFxuICogQHBhcmFtIHBhdGhWaXNpdG9yIEEgZnVuY3Rpb24gdG8gbW9kaWZ5IHRoZSByZXN1bHRpbmcgcGF0aFxuICogQHJldHVybnMgVGhlIGVxdWl2YWxlbnQgaWZFbHNlIGV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFubm90YXRpb25JZkV4cHJlc3Npb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRhbm5vdGF0aW9uVmFsdWU6IElmQW5ub3RhdGlvbkV4cHJlc3Npb25WYWx1ZTxUPixcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRoczogc3RyaW5nW10gPSBbXSxcblx0cGF0aFZpc2l0b3I/OiBGdW5jdGlvblxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+IHtcblx0cmV0dXJuIGlmRWxzZShcblx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlWzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZVsxXSBhcyBDb25kaXRpb25hbENoZWNrT3JWYWx1ZSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWVbMl0gYXMgQ29uZGl0aW9uYWxDaGVja09yVmFsdWUsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHQpO1xufVxuLy8gVGhpcyB0eXBlIGlzIG5vdCByZWN1cnNpdmVseSB0cmFuc2Zvcm1lZCBmcm9tIHRoZSBtZXRhbW9kZWwgY29udGVudCwgYXMgc3VjaCB3ZSBoYXZlIHNvbWUgdWdseSB0aGluZ3MgdGhlcmVcbnR5cGUgU3ViQXBwbHlFeHByZXNzaW9uRnJvbU1ldGFtb2RlbCA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuZnVuY3Rpb24gY29udmVydFN1YkFwcGx5UGFyYW1ldGVycyhhcHBseVBhcmFtOiBTdWJBcHBseUV4cHJlc3Npb25Gcm9tTWV0YW1vZGVsKTogU3ViQXBwbHlFeHByZXNzaW9uRnJvbU1ldGFtb2RlbCB7XG5cdGxldCBhcHBseVBhcmFtQ29udmVydGVkID0gYXBwbHlQYXJhbTtcblx0aWYgKGFwcGx5UGFyYW0uaGFzT3duUHJvcGVydHkoXCIkUGF0aFwiKSkge1xuXHRcdGFwcGx5UGFyYW1Db252ZXJ0ZWQgPSB7XG5cdFx0XHR0eXBlOiBcIlBhdGhcIixcblx0XHRcdHBhdGg6IGFwcGx5UGFyYW0uJFBhdGhcblx0XHR9IGFzIFBhdGhBbm5vdGF0aW9uRXhwcmVzc2lvbjxzdHJpbmc+O1xuXHR9IGVsc2UgaWYgKGFwcGx5UGFyYW0uaGFzT3duUHJvcGVydHkoXCIkSWZcIikpIHtcblx0XHRhcHBseVBhcmFtQ29udmVydGVkID0ge1xuXHRcdFx0dHlwZTogXCJJZlwiLFxuXHRcdFx0SWY6IGFwcGx5UGFyYW0uJElmXG5cdFx0fSBhcyBJZkFubm90YXRpb25FeHByZXNzaW9uPHN0cmluZz47XG5cdH0gZWxzZSBpZiAoYXBwbHlQYXJhbS5oYXNPd25Qcm9wZXJ0eShcIiRBcHBseVwiKSkge1xuXHRcdGFwcGx5UGFyYW1Db252ZXJ0ZWQgPSB7XG5cdFx0XHR0eXBlOiBcIkFwcGx5XCIsXG5cdFx0XHRGdW5jdGlvbjogYXBwbHlQYXJhbS4kRnVuY3Rpb24sXG5cdFx0XHRBcHBseTogYXBwbHlQYXJhbS4kQXBwbHlcblx0XHR9IGFzIEFwcGx5QW5ub3RhdGlvbkV4cHJlc3Npb248c3RyaW5nPjtcblx0fVxuXHRyZXR1cm4gYXBwbHlQYXJhbUNvbnZlcnRlZDtcbn1cblxudHlwZSBPRGF0YUZ1bmN0aW9uID0gXCJvZGF0YS5jb25jYXRcIiB8IFwib2RhdGEuZmlsbFVyaVRlbXBsYXRlXCIgfCBcIm9kYXRhLnVyaUVuY29kZVwiO1xuZXhwb3J0IGZ1bmN0aW9uIGFubm90YXRpb25BcHBseUV4cHJlc3Npb24oXG5cdGFwcGx5RXhwcmVzc2lvbjogQXBwbHlBbm5vdGF0aW9uRXhwcmVzc2lvbjxzdHJpbmc+LFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248c3RyaW5nPiB7XG5cdHN3aXRjaCAoYXBwbHlFeHByZXNzaW9uLkZ1bmN0aW9uIGFzIE9EYXRhRnVuY3Rpb24pIHtcblx0XHRjYXNlIFwib2RhdGEuY29uY2F0XCI6XG5cdFx0XHRyZXR1cm4gY29uY2F0KFxuXHRcdFx0XHQuLi5hcHBseUV4cHJlc3Npb24uQXBwbHkubWFwKChhcHBseVBhcmFtKSA9PiB7XG5cdFx0XHRcdFx0cmV0dXJuIGdldEV4cHJlc3Npb25Gcm9tQW5ub3RhdGlvbihcblx0XHRcdFx0XHRcdGNvbnZlcnRTdWJBcHBseVBhcmFtZXRlcnMoYXBwbHlQYXJhbSkgYXMgUHJvcGVydHlBbm5vdGF0aW9uVmFsdWU8c3RyaW5nPixcblx0XHRcdFx0XHRcdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsXG5cdFx0XHRcdFx0XHR1bmRlZmluZWQsXG5cdFx0XHRcdFx0XHRwYXRoVmlzaXRvclxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH0pXG5cdFx0XHQpO1xuXHRcdGNhc2UgXCJvZGF0YS51cmlFbmNvZGVcIjpcblx0XHRcdGNvbnN0IHBhcmFtZXRlciA9IGdldEV4cHJlc3Npb25Gcm9tQW5ub3RhdGlvbihcblx0XHRcdFx0Y29udmVydFN1YkFwcGx5UGFyYW1ldGVycyhcblx0XHRcdFx0XHRhcHBseUV4cHJlc3Npb24uQXBwbHlbMF0gYXMgdW5rbm93biBhcyBTdWJBcHBseUV4cHJlc3Npb25Gcm9tTWV0YW1vZGVsXG5cdFx0XHRcdCkgYXMgUHJvcGVydHlBbm5vdGF0aW9uVmFsdWU8c3RyaW5nPixcblx0XHRcdFx0dmlzaXRlZE5hdmlnYXRpb25QYXRocyxcblx0XHRcdFx0dW5kZWZpbmVkLFxuXHRcdFx0XHRwYXRoVmlzaXRvclxuXHRcdFx0KTtcblx0XHRcdC8vIFRoZSBzZWNvbmQgcGFyYW1ldGVyIGZvciB1cmlFbmNvZGUgaXMgYWx3YXlzIGEgc3RyaW5nIHNpbmNlIHRoZSB0YXJnZXQgZXZhbHVhdGlvbiBpcyBhZ2FpbnN0IGEgZm9ybWF0VmFsdWUgY2FsbCBpbiBPRGF0YVV0aWxzIHdoaWNoIGV4cGVjdCB0aGUgdGFyZ2V0IHR5cGUgYXMgc2Vjb25kIHBhcmFtZXRlclxuXHRcdFx0cmV0dXJuIGZuKFwib2RhdGEudXJpRW5jb2RlXCIsIFtwYXJhbWV0ZXIsIFwiRWRtLlN0cmluZ1wiXSwgdW5kZWZpbmVkLCB0cnVlKTtcblx0XHRjYXNlIFwib2RhdGEuZmlsbFVyaVRlbXBsYXRlXCI6XG5cdFx0XHRjb25zdCB0ZW1wbGF0ZSA9IGFwcGx5RXhwcmVzc2lvbi5BcHBseVswXTtcblx0XHRcdGNvbnN0IHRlbXBsYXRlUGFyYW1zID0gYXBwbHlFeHByZXNzaW9uLkFwcGx5LnNsaWNlKDEpIGFzIHVua25vd24gYXMgU3ViQXBwbHlFeHByZXNzaW9uRnJvbU1ldGFtb2RlbFtdO1xuXHRcdFx0Y29uc3QgdGFyZ2V0T2JqZWN0OiBSZWNvcmQ8c3RyaW5nLCBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj4+ID0ge307XG5cdFx0XHR0ZW1wbGF0ZVBhcmFtcy5mb3JFYWNoKChhcHBseVBhcmFtKSA9PiB7XG5cdFx0XHRcdHRhcmdldE9iamVjdFthcHBseVBhcmFtLiROYW1lIGFzIHN0cmluZ10gPSBnZXRFeHByZXNzaW9uRnJvbUFubm90YXRpb24oXG5cdFx0XHRcdFx0Y29udmVydFN1YkFwcGx5UGFyYW1ldGVycyhcblx0XHRcdFx0XHRcdGFwcGx5UGFyYW0uJExhYmVsZWRFbGVtZW50IGFzIFN1YkFwcGx5RXhwcmVzc2lvbkZyb21NZXRhbW9kZWxcblx0XHRcdFx0XHQpIGFzIFByb3BlcnR5QW5ub3RhdGlvblZhbHVlPHN0cmluZz4sXG5cdFx0XHRcdFx0dmlzaXRlZE5hdmlnYXRpb25QYXRocyxcblx0XHRcdFx0XHR1bmRlZmluZWQsXG5cdFx0XHRcdFx0cGF0aFZpc2l0b3Jcblx0XHRcdFx0KTtcblx0XHRcdH0pO1xuXHRcdFx0cmV0dXJuIGZuKFwib2RhdGEuZmlsbFVyaVRlbXBsYXRlXCIsIFt0ZW1wbGF0ZSwgdGFyZ2V0T2JqZWN0XSwgdW5kZWZpbmVkLCB0cnVlKTtcblx0fVxuXHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcbn1cblxuLyoqXG4gKiBHZW5lcmljIGhlbHBlciBmb3IgdGhlIGNvbXBhcmlzb24gb3BlcmF0aW9ucyAoZXF1YWwsIG5vdEVxdWFsLCAuLi4pLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIG9wZXJhdG9yIFRoZSBvcGVyYXRvciB0byBhcHBseVxuICogQHBhcmFtIGxlZnRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSBsZWZ0IHNpZGUgb2YgdGhlIG9wZXJhdG9yXG4gKiBAcGFyYW0gcmlnaHRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBvcGVyYXRvclxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGNvbXBhcmlzb25cbiAqL1xuZnVuY3Rpb24gY29tcGFyaXNvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdG9wZXJhdG9yOiBDb21wYXJpc29uT3BlcmF0b3IsXG5cdGxlZnRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdHJpZ2h0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRjb25zdCBsZWZ0RXhwcmVzc2lvbiA9IHdyYXBQcmltaXRpdmUobGVmdE9wZXJhbmQpO1xuXHRjb25zdCByaWdodEV4cHJlc3Npb24gPSB3cmFwUHJpbWl0aXZlKHJpZ2h0T3BlcmFuZCk7XG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKGxlZnRFeHByZXNzaW9uLCByaWdodEV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdH1cblx0aWYgKGlzQ29uc3RhbnQobGVmdEV4cHJlc3Npb24pICYmIGlzQ29uc3RhbnQocmlnaHRFeHByZXNzaW9uKSkge1xuXHRcdHN3aXRjaCAob3BlcmF0b3IpIHtcblx0XHRcdGNhc2UgXCIhPT1cIjpcblx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGxlZnRFeHByZXNzaW9uLnZhbHVlICE9PSByaWdodEV4cHJlc3Npb24udmFsdWUpO1xuXHRcdFx0Y2FzZSBcIj09PVwiOlxuXHRcdFx0XHRyZXR1cm4gY29uc3RhbnQobGVmdEV4cHJlc3Npb24udmFsdWUgPT09IHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSk7XG5cdFx0XHRjYXNlIFwiPFwiOlxuXHRcdFx0XHRpZiAoXG5cdFx0XHRcdFx0bGVmdEV4cHJlc3Npb24udmFsdWUgPT09IG51bGwgfHxcblx0XHRcdFx0XHRsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gdW5kZWZpbmVkIHx8XG5cdFx0XHRcdFx0cmlnaHRFeHByZXNzaW9uLnZhbHVlID09PSBudWxsIHx8XG5cdFx0XHRcdFx0cmlnaHRFeHByZXNzaW9uLnZhbHVlID09PSB1bmRlZmluZWRcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gY29uc3RhbnQobGVmdEV4cHJlc3Npb24udmFsdWUgPCByaWdodEV4cHJlc3Npb24udmFsdWUpO1xuXHRcdFx0Y2FzZSBcIjw9XCI6XG5cdFx0XHRcdGlmIChcblx0XHRcdFx0XHRsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gbnVsbCB8fFxuXHRcdFx0XHRcdGxlZnRFeHByZXNzaW9uLnZhbHVlID09PSB1bmRlZmluZWQgfHxcblx0XHRcdFx0XHRyaWdodEV4cHJlc3Npb24udmFsdWUgPT09IG51bGwgfHxcblx0XHRcdFx0XHRyaWdodEV4cHJlc3Npb24udmFsdWUgPT09IHVuZGVmaW5lZFxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXR1cm4gY29uc3RhbnQoZmFsc2UpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBjb25zdGFudChsZWZ0RXhwcmVzc2lvbi52YWx1ZSA8PSByaWdodEV4cHJlc3Npb24udmFsdWUpO1xuXHRcdFx0Y2FzZSBcIj5cIjpcblx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdGxlZnRFeHByZXNzaW9uLnZhbHVlID09PSBudWxsIHx8XG5cdFx0XHRcdFx0bGVmdEV4cHJlc3Npb24udmFsdWUgPT09IHVuZGVmaW5lZCB8fFxuXHRcdFx0XHRcdHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSA9PT0gbnVsbCB8fFxuXHRcdFx0XHRcdHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSA9PT0gdW5kZWZpbmVkXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdHJldHVybiBjb25zdGFudChmYWxzZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGxlZnRFeHByZXNzaW9uLnZhbHVlID4gcmlnaHRFeHByZXNzaW9uLnZhbHVlKTtcblx0XHRcdGNhc2UgXCI+PVwiOlxuXHRcdFx0XHRpZiAoXG5cdFx0XHRcdFx0bGVmdEV4cHJlc3Npb24udmFsdWUgPT09IG51bGwgfHxcblx0XHRcdFx0XHRsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gdW5kZWZpbmVkIHx8XG5cdFx0XHRcdFx0cmlnaHRFeHByZXNzaW9uLnZhbHVlID09PSBudWxsIHx8XG5cdFx0XHRcdFx0cmlnaHRFeHByZXNzaW9uLnZhbHVlID09PSB1bmRlZmluZWRcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gY29uc3RhbnQobGVmdEV4cHJlc3Npb24udmFsdWUgPj0gcmlnaHRFeHByZXNzaW9uLnZhbHVlKTtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdF90eXBlOiBcIkNvbXBhcmlzb25cIixcblx0XHRcdG9wZXJhdG9yOiBvcGVyYXRvcixcblx0XHRcdG9wZXJhbmQxOiBsZWZ0RXhwcmVzc2lvbixcblx0XHRcdG9wZXJhbmQyOiByaWdodEV4cHJlc3Npb25cblx0XHR9O1xuXHR9XG59XG5cbi8qKlxuICogR2VuZXJpYyBoZWxwZXIgZm9yIHRoZSBsZW5ndGggb2YgYW4gZXhwcmVzc2lvbi5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgaW5wdXQgZXhwcmVzc2lvbiBwb2ludGluZyB0byBhbiBhcnJheVxuICogQHBhcmFtIGNoZWNrVW5kZWZpbmVkIElzIHRoZSBhcnJheSBwb3RlbnRpYWxseSB1bmRlZmluZWRcbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBsZW5ndGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxlbmd0aChcblx0ZXhwcmVzc2lvbjogUGF0aEluTW9kZWxFeHByZXNzaW9uPHVua25vd24+IHwgVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb24sXG5cdGNoZWNrVW5kZWZpbmVkID0gZmFsc2Vcbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxudW1iZXI+IHtcblx0aWYgKGV4cHJlc3Npb24uX3R5cGUgPT09IFwiVW5yZXNvbHZhYmxlXCIpIHtcblx0XHRyZXR1cm4gZXhwcmVzc2lvbjtcblx0fVxuXHRpZiAoIWNoZWNrVW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdF90eXBlOiBcIkxlbmd0aFwiLFxuXHRcdFx0cGF0aEluTW9kZWw6IGV4cHJlc3Npb25cblx0XHR9O1xuXHR9XG5cdHJldHVybiBpZkVsc2UoZXF1YWwoZXhwcmVzc2lvbiwgdW5kZWZpbmVkKSwgLTEsIGxlbmd0aChleHByZXNzaW9uKSk7XG59XG5cbi8qKlxuICogQ29tcGFyaXNvbjogXCJlcXVhbFwiICg9PT0pLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGxlZnRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSBsZWZ0IHNpZGVcbiAqIEBwYXJhbSByaWdodE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGNvbXBhcmlzb25cbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBjb21wYXJpc29uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlcXVhbDxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGxlZnRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdHJpZ2h0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRjb25zdCBsZWZ0RXhwcmVzc2lvbiA9IHdyYXBQcmltaXRpdmUobGVmdE9wZXJhbmQpO1xuXHRjb25zdCByaWdodEV4cHJlc3Npb24gPSB3cmFwUHJpbWl0aXZlKHJpZ2h0T3BlcmFuZCk7XG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKGxlZnRFeHByZXNzaW9uLCByaWdodEV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdH1cblx0aWYgKF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwobGVmdEV4cHJlc3Npb24sIHJpZ2h0RXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQodHJ1ZSk7XG5cdH1cblxuXHRmdW5jdGlvbiByZWR1Y2UobGVmdDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+LCByaWdodDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+KTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHwgdW5kZWZpbmVkIHtcblx0XHRpZiAobGVmdC5fdHlwZSA9PT0gXCJDb21wYXJpc29uXCIgJiYgaXNUcnVlKHJpZ2h0KSkge1xuXHRcdFx0Ly8gY29tcGFyZShhLCBiKSA9PT0gdHJ1ZSB+fj4gY29tcGFyZShhLCBiKVxuXHRcdFx0cmV0dXJuIGxlZnQ7XG5cdFx0fSBlbHNlIGlmIChsZWZ0Ll90eXBlID09PSBcIkNvbXBhcmlzb25cIiAmJiBpc0ZhbHNlKHJpZ2h0KSkge1xuXHRcdFx0Ly8gY29tcGFyZShhLCBiKSA9PT0gZmFsc2Ugfn4+ICFjb21wYXJlKGEsIGIpXG5cdFx0XHRyZXR1cm4gbm90KGxlZnQpO1xuXHRcdH0gZWxzZSBpZiAobGVmdC5fdHlwZSA9PT0gXCJJZkVsc2VcIiAmJiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGxlZnQub25UcnVlLCByaWdodCkpIHtcblx0XHRcdC8vIChpZiAoeCkgeyBhIH0gZWxzZSB7IGIgfSkgPT09IGEgfn4+IHggfHwgKGIgPT09IGEpXG5cdFx0XHRyZXR1cm4gb3IobGVmdC5jb25kaXRpb24sIGVxdWFsKGxlZnQub25GYWxzZSwgcmlnaHQpKTtcblx0XHR9IGVsc2UgaWYgKGxlZnQuX3R5cGUgPT09IFwiSWZFbHNlXCIgJiYgX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChsZWZ0Lm9uRmFsc2UsIHJpZ2h0KSkge1xuXHRcdFx0Ly8gKGlmICh4KSB7IGEgfSBlbHNlIHsgYiB9KSA9PT0gYiB+fj4gIXggfHwgKGEgPT09IGIpXG5cdFx0XHRyZXR1cm4gb3Iobm90KGxlZnQuY29uZGl0aW9uKSwgZXF1YWwobGVmdC5vblRydWUsIHJpZ2h0KSk7XG5cdFx0fSBlbHNlIGlmIChcblx0XHRcdGxlZnQuX3R5cGUgPT09IFwiSWZFbHNlXCIgJiZcblx0XHRcdGlzQ29uc3RhbnQobGVmdC5vblRydWUpICYmXG5cdFx0XHRpc0NvbnN0YW50KGxlZnQub25GYWxzZSkgJiZcblx0XHRcdGlzQ29uc3RhbnQocmlnaHQpICYmXG5cdFx0XHQhX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChsZWZ0Lm9uVHJ1ZSwgcmlnaHQpICYmXG5cdFx0XHQhX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChsZWZ0Lm9uRmFsc2UsIHJpZ2h0KVxuXHRcdCkge1xuXHRcdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0XHR9XG5cdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0fVxuXG5cdC8vIGV4cGxvaXQgc3ltbWV0cnk6IGEgPT09IGIgPH4+IGIgPT09IGFcblx0Y29uc3QgcmVkdWNlZCA9IHJlZHVjZShsZWZ0RXhwcmVzc2lvbiwgcmlnaHRFeHByZXNzaW9uKSA/PyByZWR1Y2UocmlnaHRFeHByZXNzaW9uLCBsZWZ0RXhwcmVzc2lvbik7XG5cdHJldHVybiByZWR1Y2VkID8/IGNvbXBhcmlzb24oXCI9PT1cIiwgbGVmdEV4cHJlc3Npb24sIHJpZ2h0RXhwcmVzc2lvbik7XG59XG5cbi8qKlxuICogQ29tcGFyaXNvbjogXCJub3QgZXF1YWxcIiAoIT09KS5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBsZWZ0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgbGVmdCBzaWRlXG4gKiBAcGFyYW0gcmlnaHRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBjb21wYXJpc29uXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgY29tcGFyaXNvblxuICovXG5leHBvcnQgZnVuY3Rpb24gbm90RXF1YWw8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRsZWZ0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRyaWdodE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0cmV0dXJuIG5vdChlcXVhbChsZWZ0T3BlcmFuZCwgcmlnaHRPcGVyYW5kKSk7XG59XG5cbi8qKlxuICogQ29tcGFyaXNvbjogXCJncmVhdGVyIG9yIGVxdWFsXCIgKD49KS5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBsZWZ0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgbGVmdCBzaWRlXG4gKiBAcGFyYW0gcmlnaHRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBjb21wYXJpc29uXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgY29tcGFyaXNvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JlYXRlck9yRXF1YWw8VCBleHRlbmRzIERlZmluZWRQcmltaXRpdmVUeXBlPihcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdHJldHVybiBjb21wYXJpc29uKFwiPj1cIiwgbGVmdE9wZXJhbmQsIHJpZ2h0T3BlcmFuZCk7XG59XG5cbi8qKlxuICogQ29tcGFyaXNvbjogXCJncmVhdGVyIHRoYW5cIiAoPikuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gbGVmdE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIGxlZnQgc2lkZVxuICogQHBhcmFtIHJpZ2h0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgY29tcGFyaXNvblxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGNvbXBhcmlzb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdyZWF0ZXJUaGFuPFQgZXh0ZW5kcyBEZWZpbmVkUHJpbWl0aXZlVHlwZT4oXG5cdGxlZnRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdHJpZ2h0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRyZXR1cm4gY29tcGFyaXNvbihcIj5cIiwgbGVmdE9wZXJhbmQsIHJpZ2h0T3BlcmFuZCk7XG59XG5cbi8qKlxuICogQ29tcGFyaXNvbjogXCJsZXNzIG9yIGVxdWFsXCIgKDw9KS5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBsZWZ0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgbGVmdCBzaWRlXG4gKiBAcGFyYW0gcmlnaHRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBjb21wYXJpc29uXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgY29tcGFyaXNvblxuICovXG5leHBvcnQgZnVuY3Rpb24gbGVzc09yRXF1YWw8VCBleHRlbmRzIERlZmluZWRQcmltaXRpdmVUeXBlPihcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdHJldHVybiBjb21wYXJpc29uKFwiPD1cIiwgbGVmdE9wZXJhbmQsIHJpZ2h0T3BlcmFuZCk7XG59XG5cbi8qKlxuICogQ29tcGFyaXNvbjogXCJsZXNzIHRoYW5cIiAoPCkuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gbGVmdE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIGxlZnQgc2lkZVxuICogQHBhcmFtIHJpZ2h0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgY29tcGFyaXNvblxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGNvbXBhcmlzb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxlc3NUaGFuPFQgZXh0ZW5kcyBEZWZpbmVkUHJpbWl0aXZlVHlwZT4oXG5cdGxlZnRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdHJpZ2h0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRyZXR1cm4gY29tcGFyaXNvbihcIjxcIiwgbGVmdE9wZXJhbmQsIHJpZ2h0T3BlcmFuZCk7XG59XG5cbi8qKlxuICogSWYtdGhlbi1lbHNlIGV4cHJlc3Npb24uXG4gKlxuICogRXZhbHVhdGVzIHRvIG9uVHJ1ZSBpZiB0aGUgY29uZGl0aW9uIGV2YWx1YXRlcyB0byB0cnVlLCBlbHNlIGV2YWx1YXRlcyB0byBvbkZhbHNlLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGNvbmRpdGlvbiBUaGUgY29uZGl0aW9uIHRvIGV2YWx1YXRlXG4gKiBAcGFyYW0gb25UcnVlIEV4cHJlc3Npb24gcmVzdWx0IGlmIHRoZSBjb25kaXRpb24gZXZhbHVhdGVzIHRvIHRydWVcbiAqIEBwYXJhbSBvbkZhbHNlIEV4cHJlc3Npb24gcmVzdWx0IGlmIHRoZSBjb25kaXRpb24gZXZhbHVhdGVzIHRvIGZhbHNlXG4gKiBAcmV0dXJucyBUaGUgZXhwcmVzc2lvbiB0aGF0IHJlcHJlc2VudHMgdGhpcyBjb25kaXRpb25hbCBjaGVja1xuICovXG5leHBvcnQgZnVuY3Rpb24gaWZFbHNlPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0Y29uZGl0aW9uOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8Ym9vbGVhbj4sXG5cdG9uVHJ1ZTogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRvbkZhbHNlOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiB7XG5cdGxldCBjb25kaXRpb25FeHByZXNzaW9uID0gd3JhcFByaW1pdGl2ZShjb25kaXRpb24pO1xuXHRsZXQgb25UcnVlRXhwcmVzc2lvbiA9IHdyYXBQcmltaXRpdmUob25UcnVlKTtcblx0bGV0IG9uRmFsc2VFeHByZXNzaW9uID0gd3JhcFByaW1pdGl2ZShvbkZhbHNlKTtcblxuXHQvLyBzd2FwIGJyYW5jaGVzIGlmIHRoZSBjb25kaXRpb24gaXMgYSBuZWdhdGlvblxuXHRpZiAoY29uZGl0aW9uRXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJOb3RcIikge1xuXHRcdC8vIGlmRWxzZShub3QoWCksIGEsIGIpIC0tPiBpZkVsc2UoWCwgYiwgYSlcblx0XHRbb25UcnVlRXhwcmVzc2lvbiwgb25GYWxzZUV4cHJlc3Npb25dID0gW29uRmFsc2VFeHByZXNzaW9uLCBvblRydWVFeHByZXNzaW9uXTtcblx0XHRjb25kaXRpb25FeHByZXNzaW9uID0gbm90KGNvbmRpdGlvbkV4cHJlc3Npb24pO1xuXHR9XG5cblx0Ly8gaW5saW5lIG5lc3RlZCBpZi1lbHNlIGV4cHJlc3Npb25zOiBvblRydWUgYnJhbmNoXG5cdC8vIGlmRWxzZShYLCBpZkVsc2UoWCwgYSwgYiksIGMpID09PiBpZkVsc2UoWCwgYSwgYylcblx0aWYgKG9uVHJ1ZUV4cHJlc3Npb24uX3R5cGUgPT09IFwiSWZFbHNlXCIgJiYgX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChjb25kaXRpb25FeHByZXNzaW9uLCBvblRydWVFeHByZXNzaW9uLmNvbmRpdGlvbikpIHtcblx0XHRvblRydWVFeHByZXNzaW9uID0gb25UcnVlRXhwcmVzc2lvbi5vblRydWU7XG5cdH1cblxuXHQvLyBpbmxpbmUgbmVzdGVkIGlmLWVsc2UgZXhwcmVzc2lvbnM6IG9uRmFsc2UgYnJhbmNoXG5cdC8vIGlmRWxzZShYLCBhLCBpZkVsc2UoWCwgYiwgYykpID09PiBpZkVsc2UoWCwgYSwgYylcblx0aWYgKG9uRmFsc2VFeHByZXNzaW9uLl90eXBlID09PSBcIklmRWxzZVwiICYmIF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoY29uZGl0aW9uRXhwcmVzc2lvbiwgb25GYWxzZUV4cHJlc3Npb24uY29uZGl0aW9uKSkge1xuXHRcdG9uRmFsc2VFeHByZXNzaW9uID0gb25GYWxzZUV4cHJlc3Npb24ub25GYWxzZTtcblx0fVxuXG5cdC8vIChpZiB0cnVlIHRoZW4gYSBlbHNlIGIpICB+fj4gYVxuXHQvLyAoaWYgZmFsc2UgdGhlbiBhIGVsc2UgYikgfn4+IGJcblx0aWYgKGlzQ29uc3RhbnQoY29uZGl0aW9uRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gY29uZGl0aW9uRXhwcmVzc2lvbi52YWx1ZSA/IG9uVHJ1ZUV4cHJlc3Npb24gOiBvbkZhbHNlRXhwcmVzc2lvbjtcblx0fVxuXG5cdC8vIGlmIChpc0NvbnN0YW50Qm9vbGVhbihvblRydWVFeHByZXNzaW9uKSB8fCBpc0NvbnN0YW50Qm9vbGVhbihvbkZhbHNlRXhwcmVzc2lvbikpIHtcblx0Ly8gXHRyZXR1cm4gb3IoYW5kKGNvbmRpdGlvbiwgb25UcnVlRXhwcmVzc2lvbiBhcyBFeHByZXNzaW9uPGJvb2xlYW4+KSwgYW5kKG5vdChjb25kaXRpb24pLCBvbkZhbHNlRXhwcmVzc2lvbiBhcyBFeHByZXNzaW9uPGJvb2xlYW4+KSkgYXMgRXhwcmVzc2lvbjxUPlxuXHQvLyB9XG5cblx0Ly8gKGlmIFggdGhlbiBhIGVsc2UgYSkgfn4+IGFcblx0aWYgKF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwob25UcnVlRXhwcmVzc2lvbiwgb25GYWxzZUV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIG9uVHJ1ZUV4cHJlc3Npb247XG5cdH1cblxuXHQvLyBpZiBYIHRoZW4gYSBlbHNlIGZhbHNlIH5+PiBYICYmIGFcblx0aWYgKGlzRmFsc2Uob25GYWxzZUV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIGFuZChjb25kaXRpb25FeHByZXNzaW9uLCBvblRydWVFeHByZXNzaW9uIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPikgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9XG5cblx0Ly8gaWYgWCB0aGVuIGEgZWxzZSB0cnVlIH5+PiAhWCB8fCBhXG5cdGlmIChpc1RydWUob25GYWxzZUV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIG9yKG5vdChjb25kaXRpb25FeHByZXNzaW9uKSwgb25UcnVlRXhwcmVzc2lvbiBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4pIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fVxuXG5cdC8vIGlmIFggdGhlbiBmYWxzZSBlbHNlIGEgfn4+ICFYICYmIGFcblx0aWYgKGlzRmFsc2Uob25UcnVlRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gYW5kKG5vdChjb25kaXRpb25FeHByZXNzaW9uKSwgb25GYWxzZUV4cHJlc3Npb24gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH1cblxuXHQvLyBpZiBYIHRoZW4gdHJ1ZSBlbHNlIGEgfn4+IFggfHwgYVxuXHRpZiAoaXNUcnVlKG9uVHJ1ZUV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIG9yKGNvbmRpdGlvbkV4cHJlc3Npb24sIG9uRmFsc2VFeHByZXNzaW9uIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPikgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9XG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKGNvbmRpdGlvbkV4cHJlc3Npb24sIG9uVHJ1ZUV4cHJlc3Npb24sIG9uRmFsc2VFeHByZXNzaW9uKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHR9XG5cdGlmIChpc0NvbXBsZXhUeXBlRXhwcmVzc2lvbihjb25kaXRpb24pIHx8IGlzQ29tcGxleFR5cGVFeHByZXNzaW9uKG9uVHJ1ZSkgfHwgaXNDb21wbGV4VHlwZUV4cHJlc3Npb24ob25GYWxzZSkpIHtcblx0XHRsZXQgcGF0aElkeCA9IDA7XG5cdFx0Y29uc3QgbXlJZkVsc2VFeHByZXNzaW9uID0gZm9ybWF0UmVzdWx0KFtjb25kaXRpb24sIG9uVHJ1ZSwgb25GYWxzZV0sIFwic2FwLmZlLmNvcmUuZm9ybWF0dGVycy5TdGFuZGFyZEZvcm1hdHRlciNpZkVsc2VcIik7XG5cdFx0Y29uc3QgYWxsUGFydHMgPSBbXTtcblx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdG15SWZFbHNlRXhwcmVzc2lvbixcblx0XHRcdFwiUGF0aEluTW9kZWxcIixcblx0XHRcdChjb25zdGFudFBhdGg6IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjx1bmtub3duPikgPT4ge1xuXHRcdFx0XHRhbGxQYXJ0cy5wdXNoKGNvbnN0YW50UGF0aCk7XG5cdFx0XHRcdHJldHVybiBwYXRoSW5Nb2RlbChgJCR7cGF0aElkeCsrfWAsIFwiJFwiKTtcblx0XHRcdH0sXG5cdFx0XHR0cnVlXG5cdFx0KTtcblx0XHRhbGxQYXJ0cy51bnNoaWZ0KGNvbnN0YW50KEpTT04uc3RyaW5naWZ5KG15SWZFbHNlRXhwcmVzc2lvbikpKTtcblx0XHRyZXR1cm4gZm9ybWF0UmVzdWx0KGFsbFBhcnRzLCBcInNhcC5mZS5jb3JlLmZvcm1hdHRlcnMuU3RhbmRhcmRGb3JtYXR0ZXIjZXZhbHVhdGVDb21wbGV4RXhwcmVzc2lvblwiLCB1bmRlZmluZWQsIHRydWUpO1xuXHR9XG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiSWZFbHNlXCIsXG5cdFx0Y29uZGl0aW9uOiBjb25kaXRpb25FeHByZXNzaW9uLFxuXHRcdG9uVHJ1ZTogb25UcnVlRXhwcmVzc2lvbixcblx0XHRvbkZhbHNlOiBvbkZhbHNlRXhwcmVzc2lvblxuXHR9O1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBjdXJyZW50IGV4cHJlc3Npb24gaGFzIGEgcmVmZXJlbmNlIHRvIHRoZSBkZWZhdWx0IG1vZGVsICh1bmRlZmluZWQpLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBleHByZXNzaW9uIHRvIGV2YWx1YXRlXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlcmUgaXMgYSByZWZlcmVuY2UgdG8gdGhlIGRlZmF1bHQgY29udGV4dFxuICovXG5mdW5jdGlvbiBoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KGV4cHJlc3Npb246IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPik6IGJvb2xlYW4ge1xuXHRzd2l0Y2ggKGV4cHJlc3Npb24uX3R5cGUpIHtcblx0XHRjYXNlIFwiQ29uc3RhbnRcIjpcblx0XHRjYXNlIFwiRm9ybWF0dGVyXCI6XG5cdFx0Y2FzZSBcIkNvbXBsZXhUeXBlXCI6XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0Y2FzZSBcIlNldFwiOlxuXHRcdFx0cmV0dXJuIGV4cHJlc3Npb24ub3BlcmFuZHMuc29tZShoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KTtcblx0XHRjYXNlIFwiUGF0aEluTW9kZWxcIjpcblx0XHRcdHJldHVybiBleHByZXNzaW9uLm1vZGVsTmFtZSA9PT0gdW5kZWZpbmVkO1xuXHRcdGNhc2UgXCJDb21wYXJpc29uXCI6XG5cdFx0XHRyZXR1cm4gaGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dChleHByZXNzaW9uLm9wZXJhbmQxKSB8fCBoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KGV4cHJlc3Npb24ub3BlcmFuZDIpO1xuXHRcdGNhc2UgXCJJZkVsc2VcIjpcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQoZXhwcmVzc2lvbi5jb25kaXRpb24pIHx8XG5cdFx0XHRcdGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQoZXhwcmVzc2lvbi5vblRydWUpIHx8XG5cdFx0XHRcdGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQoZXhwcmVzc2lvbi5vbkZhbHNlKVxuXHRcdFx0KTtcblx0XHRjYXNlIFwiTm90XCI6XG5cdFx0Y2FzZSBcIlRydXRoeVwiOlxuXHRcdFx0cmV0dXJuIGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQoZXhwcmVzc2lvbi5vcGVyYW5kKTtcblx0XHRkZWZhdWx0OlxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59XG5cbi8vIFRoaXMgaXMgb25lIGNhc2Ugd2hlcmUgYW55IGRvZXMgbWFrZSBzZW5zZS4uLlxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbmV4cG9ydCB0eXBlIEZuPFQ+ID0gKCguLi5wYXJhbXM6IGFueSkgPT4gVCB8IFByb21pc2U8VD4pICYge1xuXHRfX2Z1bmN0aW9uTmFtZTogc3RyaW5nO1xufTtcblxuLyoqXG4gKiBAdHlwZWRlZiBXcmFwcGVkVHVwbGVcbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHMtY29tbWVudFxuLy8gQHRzLWlnbm9yZVxudHlwZSBXcmFwcGVkVHVwbGU8VD4gPSB7IFtLIGluIGtleW9mIFRdOiBXcmFwcGVkVHVwbGU8VFtLXT4gfCBFeHByZXNzaW9uT3JQcmltaXRpdmU8VFtLXT4gfCB1bmRlZmluZWQgfTtcblxuLy8gU28sIHRoaXMgd29ya3MgYnV0IEkgY2Fubm90IGdldCBpdCB0byBjb21waWxlIDpELCBidXQgaXQgc3RpbGwgZG9lcyB3aGF0IGlzIGV4cGVjdGVkLi4uXG5cbi8qKlxuICogQSBmdW5jdGlvbiByZWZlcmVuY2Ugb3IgYSBmdW5jdGlvbiBuYW1lLlxuICovXG50eXBlIEZ1bmN0aW9uT3JOYW1lPFQ+ID0gRm48VD4gfCBzdHJpbmc7XG5cbi8qKlxuICogRnVuY3Rpb24gcGFyYW1ldGVycywgZWl0aGVyIGRlcml2ZWQgZnJvbSB0aGUgZnVuY3Rpb24gb3IgYW4gdW50eXBlZCBhcnJheS5cbiAqL1xudHlwZSBGdW5jdGlvblBhcmFtZXRlcnM8VCwgRiBleHRlbmRzIEZ1bmN0aW9uT3JOYW1lPFQ+PiA9IEYgZXh0ZW5kcyBGbjxUPiA/IFBhcmFtZXRlcnM8Rj4gOiB1bmtub3duW107XG5cbi8qKlxuICogQ2FsbHMgYSBmb3JtYXR0ZXIgZnVuY3Rpb24gdG8gcHJvY2VzcyB0aGUgcGFyYW1ldGVycy5cbiAqIElmIHJlcXVpcmVDb250ZXh0IGlzIHNldCB0byB0cnVlIGFuZCBubyBjb250ZXh0IGlzIHBhc3NlZCBhIGRlZmF1bHQgY29udGV4dCB3aWxsIGJlIGFkZGVkIGF1dG9tYXRpY2FsbHkuXG4gKlxuICogQHRlbXBsYXRlIFRcbiAqIEB0ZW1wbGF0ZSBVXG4gKiBAcGFyYW0gcGFyYW1ldGVycyBUaGUgbGlzdCBvZiBwYXJhbWV0ZXIgdGhhdCBzaG91bGQgbWF0Y2ggdGhlIHR5cGUgYW5kIG51bWJlciBvZiB0aGUgZm9ybWF0dGVyIGZ1bmN0aW9uXG4gKiBAcGFyYW0gZm9ybWF0dGVyRnVuY3Rpb24gVGhlIGZ1bmN0aW9uIHRvIGNhbGxcbiAqIEBwYXJhbSBbY29udGV4dEVudGl0eVR5cGVdIElmIG5vIHBhcmFtZXRlciByZWZlcnMgdG8gdGhlIGNvbnRleHQgdGhlbiB3ZSB1c2UgdGhpcyBpbmZvcm1hdGlvbiB0byBhZGQgYSByZWZlcmVuY2UgdG8gdGhlIGtleXMgZnJvbSB0aGUgZW50aXR5IHR5cGUuXG4gKiBAcGFyYW0gW2lnbm9yZUNvbXBsZXhUeXBlXSBXaGV0aGVyIHRvIGlnbm9yZSB0aGUgdHJhbnNnZm9ybWF0aW9uIHRvIHRoZSBTdGFuZGFyZEZvcm1hdHRlciBvciBub3RcbiAqIEByZXR1cm5zIFRoZSBjb3JyZXNwb25kaW5nIGV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdFJlc3VsdDxULCBVIGV4dGVuZHMgRm48VD4+KFxuXHRwYXJhbWV0ZXJzOiBXcmFwcGVkVHVwbGU8UGFyYW1ldGVyczxVPj4sXG5cdGZvcm1hdHRlckZ1bmN0aW9uOiBVIHwgc3RyaW5nLFxuXHRjb250ZXh0RW50aXR5VHlwZT86IEVudGl0eVR5cGUsXG5cdGlnbm9yZUNvbXBsZXhUeXBlID0gZmFsc2Vcbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiB7XG5cdGNvbnN0IHBhcmFtZXRlckV4cHJlc3Npb25zID0gKHBhcmFtZXRlcnMgYXMgRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFByaW1pdGl2ZVR5cGU+W10pLm1hcCh3cmFwUHJpbWl0aXZlKTtcblxuXHRpZiAoaGFzVW5yZXNvbHZhYmxlRXhwcmVzc2lvbiguLi5wYXJhbWV0ZXJFeHByZXNzaW9ucykpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRpZiAoY29udGV4dEVudGl0eVR5cGUpIHtcblx0XHQvLyBPdGhlcndpc2UsIGlmIHRoZSBjb250ZXh0IGlzIHJlcXVpcmVkIGFuZCBubyBjb250ZXh0IGlzIHByb3ZpZGVkIG1ha2Ugc3VyZSB0byBhZGQgdGhlIGRlZmF1bHQgYmluZGluZ1xuXHRcdGlmICghcGFyYW1ldGVyRXhwcmVzc2lvbnMuc29tZShoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KSkge1xuXHRcdFx0Y29udGV4dEVudGl0eVR5cGUua2V5cy5mb3JFYWNoKChrZXkpID0+IHBhcmFtZXRlckV4cHJlc3Npb25zLnB1c2gocGF0aEluTW9kZWwoa2V5Lm5hbWUsIFwiXCIpKSk7XG5cdFx0fVxuXHR9XG5cdGxldCBmdW5jdGlvbk5hbWUgPSBcIlwiO1xuXHRpZiAodHlwZW9mIGZvcm1hdHRlckZ1bmN0aW9uID09PSBcInN0cmluZ1wiKSB7XG5cdFx0ZnVuY3Rpb25OYW1lID0gZm9ybWF0dGVyRnVuY3Rpb247XG5cdH0gZWxzZSB7XG5cdFx0ZnVuY3Rpb25OYW1lID0gZm9ybWF0dGVyRnVuY3Rpb24uX19mdW5jdGlvbk5hbWU7XG5cdH1cblx0Ly8gRm9ybWF0dGVyTmFtZSBjYW4gYmUgb2YgZm9ybWF0IHNhcC5mZS5jb3JlLnh4eCNtZXRob2ROYW1lIHRvIGhhdmUgbXVsdGlwbGUgZm9ybWF0dGVyIGluIG9uZSBjbGFzc1xuXHRjb25zdCBbZm9ybWF0dGVyQ2xhc3MsIGZvcm1hdHRlck5hbWVdID0gZnVuY3Rpb25OYW1lLnNwbGl0KFwiI1wiKTtcblxuXHQvLyBJbiBzb21lIGNhc2Ugd2UgYWxzbyBjYW5ub3QgY2FsbCBkaXJlY3RseSBhIGZ1bmN0aW9uIGJlY2F1c2Ugb2YgdG9vIGNvbXBsZXggaW5wdXQsIGluIHRoYXQgY2FzZSB3ZSBuZWVkIHRvIGNvbnZlcnQgdG8gYSBzaW1wbGVyIGZ1bmN0aW9uIGNhbGxcblx0aWYgKFxuXHRcdCFpZ25vcmVDb21wbGV4VHlwZSAmJlxuXHRcdChwYXJhbWV0ZXJFeHByZXNzaW9ucy5zb21lKGlzQ29tcGxleFR5cGVFeHByZXNzaW9uKSB8fFxuXHRcdFx0cGFyYW1ldGVyRXhwcmVzc2lvbnMuc29tZShpc0NvbmNhdEV4cHJlc3Npb24pIHx8XG5cdFx0XHRwYXJhbWV0ZXJFeHByZXNzaW9ucy5zb21lKGlzSWZFbHNlRXhwcmVzc2lvbikpXG5cdCkge1xuXHRcdGxldCBwYXRoSWR4ID0gMDtcblx0XHRjb25zdCBteUZvcm1hdEV4cHJlc3Npb24gPSBmb3JtYXRSZXN1bHQocGFyYW1ldGVyRXhwcmVzc2lvbnMsIGZ1bmN0aW9uTmFtZSwgdW5kZWZpbmVkLCB0cnVlKTtcblx0XHRjb25zdCBhbGxQYXJ0cyA9IFtdO1xuXHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0bXlGb3JtYXRFeHByZXNzaW9uLFxuXHRcdFx0XCJQYXRoSW5Nb2RlbFwiLFxuXHRcdFx0KGNvbnN0YW50UGF0aDogUGF0aEluTW9kZWxFeHByZXNzaW9uPHVua25vd24+KSA9PiB7XG5cdFx0XHRcdGFsbFBhcnRzLnB1c2goY29uc3RhbnRQYXRoKTtcblx0XHRcdFx0cmV0dXJuIHBhdGhJbk1vZGVsKGAkJHtwYXRoSWR4Kyt9YCwgXCIkXCIpO1xuXHRcdFx0fSxcblx0XHRcdHRydWVcblx0XHQpO1xuXHRcdGFsbFBhcnRzLnVuc2hpZnQoY29uc3RhbnQoSlNPTi5zdHJpbmdpZnkobXlGb3JtYXRFeHByZXNzaW9uKSkpO1xuXHRcdHJldHVybiBmb3JtYXRSZXN1bHQoYWxsUGFydHMsIFwic2FwLmZlLmNvcmUuZm9ybWF0dGVycy5TdGFuZGFyZEZvcm1hdHRlciNldmFsdWF0ZUNvbXBsZXhFeHByZXNzaW9uXCIsIHVuZGVmaW5lZCwgdHJ1ZSk7XG5cdH0gZWxzZSBpZiAoISFmb3JtYXR0ZXJOYW1lICYmIGZvcm1hdHRlck5hbWUubGVuZ3RoID4gMCkge1xuXHRcdHBhcmFtZXRlckV4cHJlc3Npb25zLnVuc2hpZnQoY29uc3RhbnQoZm9ybWF0dGVyTmFtZSkpO1xuXHR9XG5cblx0cmV0dXJuIHtcblx0XHRfdHlwZTogXCJGb3JtYXR0ZXJcIixcblx0XHRmbjogZm9ybWF0dGVyQ2xhc3MsXG5cdFx0cGFyYW1ldGVyczogcGFyYW1ldGVyRXhwcmVzc2lvbnNcblx0fTtcbn1cblxudHlwZSBCaW5kaW5nQ29uc3RyYWludHMgPSB7XG5cdHNjYWxlPzogbnVtYmVyO1xuXHRwcmVjaXNpb24/OiBudW1iZXI7XG5cdG1heExlbmd0aD86IG51bWJlcjtcblx0bnVsbGFibGU/OiBib29sZWFuO1xuXHRtaW5pbXVtPzogc3RyaW5nO1xuXHRtYXhpbXVtPzogc3RyaW5nO1xuXHRpc0RpZ2l0U2VxdWVuY2U/OiBib29sZWFuO1xuXHRWND86IGJvb2xlYW47XG59O1xuZXhwb3J0IGZ1bmN0aW9uIHNldFVwQ29uc3RyYWludHModGFyZ2V0TWFwcGluZzogVHlwZU1hcHBpbmdEZWZpbml0aW9uLCBwcm9wZXJ0eTogUHJvcGVydHkgfCBBY3Rpb25QYXJhbWV0ZXIpOiBCaW5kaW5nQ29uc3RyYWludHMge1xuXHRjb25zdCBjb25zdHJhaW50czogQmluZGluZ0NvbnN0cmFpbnRzID0ge307XG5cdGlmICh0YXJnZXRNYXBwaW5nPy5jb25zdHJhaW50cz8uJFNjYWxlICYmIHByb3BlcnR5LnNjYWxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRjb25zdHJhaW50cy5zY2FsZSA9IHByb3BlcnR5LnNjYWxlO1xuXHR9XG5cdGlmICh0YXJnZXRNYXBwaW5nPy5jb25zdHJhaW50cz8uJFByZWNpc2lvbiAmJiBwcm9wZXJ0eS5wcmVjaXNpb24gIT09IHVuZGVmaW5lZCkge1xuXHRcdGNvbnN0cmFpbnRzLnByZWNpc2lvbiA9IHByb3BlcnR5LnByZWNpc2lvbjtcblx0fVxuXHRpZiAodGFyZ2V0TWFwcGluZz8uY29uc3RyYWludHM/LiRNYXhMZW5ndGggJiYgcHJvcGVydHkubWF4TGVuZ3RoICE9PSB1bmRlZmluZWQpIHtcblx0XHRjb25zdHJhaW50cy5tYXhMZW5ndGggPSBwcm9wZXJ0eS5tYXhMZW5ndGg7XG5cdH1cblx0aWYgKHByb3BlcnR5Lm51bGxhYmxlID09PSBmYWxzZSkge1xuXHRcdGNvbnN0cmFpbnRzLm51bGxhYmxlID0gZmFsc2U7XG5cdH1cblx0aWYgKHRhcmdldE1hcHBpbmc/LmNvbnN0cmFpbnRzPy5bXCJAT3JnLk9EYXRhLlZhbGlkYXRpb24uVjEuTWluaW11bS8kRGVjaW1hbFwiXSAmJiAhaXNOYU4ocHJvcGVydHkuYW5ub3RhdGlvbnM/LlZhbGlkYXRpb24/Lk1pbmltdW0pKSB7XG5cdFx0Y29uc3RyYWludHMubWluaW11bSA9IGAke3Byb3BlcnR5LmFubm90YXRpb25zPy5WYWxpZGF0aW9uPy5NaW5pbXVtfWA7XG5cdH1cblx0aWYgKHRhcmdldE1hcHBpbmc/LmNvbnN0cmFpbnRzPy5bXCJAT3JnLk9EYXRhLlZhbGlkYXRpb24uVjEuTWF4aW11bS8kRGVjaW1hbFwiXSAmJiAhaXNOYU4ocHJvcGVydHkuYW5ub3RhdGlvbnM/LlZhbGlkYXRpb24/Lk1heGltdW0pKSB7XG5cdFx0Y29uc3RyYWludHMubWF4aW11bSA9IGAke3Byb3BlcnR5LmFubm90YXRpb25zPy5WYWxpZGF0aW9uPy5NYXhpbXVtfWA7XG5cdH1cblx0aWYgKFxuXHRcdHByb3BlcnR5LmFubm90YXRpb25zPy5Db21tb24/LklzRGlnaXRTZXF1ZW5jZSAmJlxuXHRcdHRhcmdldE1hcHBpbmcudHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5TdHJpbmdcIiAmJlxuXHRcdHRhcmdldE1hcHBpbmc/LmNvbnN0cmFpbnRzPy5bXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLklzRGlnaXRTZXF1ZW5jZVwiXVxuXHQpIHtcblx0XHRjb25zdHJhaW50cy5pc0RpZ2l0U2VxdWVuY2UgPSB0cnVlO1xuXHR9XG5cdGlmICh0YXJnZXRNYXBwaW5nPy5jb25zdHJhaW50cz8uJFY0KSB7XG5cdFx0Y29uc3RyYWludHMuVjQgPSB0cnVlO1xuXHR9XG5cdHJldHVybiBjb25zdHJhaW50cztcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgdGhlIGJpbmRpbmcgZXhwcmVzc2lvbiBmb3IgdGhlIHByb3BlcnR5LCBhbmQgc2V0cyB1cCB0aGUgZm9ybWF0T3B0aW9ucyBhbmQgY29uc3RyYWludHMuXG4gKlxuICogQHBhcmFtIHByb3BlcnR5IFRoZSBQcm9wZXJ0eSBmb3Igd2hpY2ggd2UgYXJlIHNldHRpbmcgdXAgdGhlIGJpbmRpbmdcbiAqIEBwYXJhbSBwcm9wZXJ0eUJpbmRpbmdFeHByZXNzaW9uIFRoZSBCaW5kaW5nRXhwcmVzc2lvbiBvZiB0aGUgcHJvcGVydHkgYWJvdmUuIFNlcnZlcyBhcyB0aGUgYmFzaXMgdG8gd2hpY2ggaW5mb3JtYXRpb24gY2FuIGJlIGFkZGVkXG4gKiBAcGFyYW0gaWdub3JlQ29uc3RyYWludHMgSWdub3JlIGNvbnN0cmFpbnRzIG9mIHRoZSBwcm9wZXJ0eVxuICogQHJldHVybnMgVGhlIGJpbmRpbmcgZXhwcmVzc2lvbiBmb3IgdGhlIHByb3BlcnR5IHdpdGggZm9ybWF0T3B0aW9ucyBhbmQgY29uc3RyYWludHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdFdpdGhUeXBlSW5mb3JtYXRpb248VD4oXG5cdHByb3BlcnR5OiBQcm9wZXJ0eSB8IEFjdGlvblBhcmFtZXRlcixcblx0cHJvcGVydHlCaW5kaW5nRXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHN0cmluZz4sXG5cdGlnbm9yZUNvbnN0cmFpbnRzID0gZmFsc2Vcbik6IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPiB7XG5cdGNvbnN0IG91dEV4cHJlc3Npb246IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjx1bmtub3duPiA9IHByb3BlcnR5QmluZGluZ0V4cHJlc3Npb24gYXMgUGF0aEluTW9kZWxFeHByZXNzaW9uPHVua25vd24+O1xuXHRpZiAocHJvcGVydHkuX3R5cGUgIT09IFwiUHJvcGVydHlcIiAmJiBwcm9wZXJ0eS5fdHlwZSAhPT0gXCJBY3Rpb25QYXJhbWV0ZXJcIikge1xuXHRcdHJldHVybiBvdXRFeHByZXNzaW9uO1xuXHR9XG5cdGNvbnN0IHRhcmdldE1hcHBpbmcgPSBFRE1fVFlQRV9NQVBQSU5HW3Byb3BlcnR5LnR5cGVdO1xuXHRpZiAoIXRhcmdldE1hcHBpbmcpIHtcblx0XHRyZXR1cm4gb3V0RXhwcmVzc2lvbjtcblx0fVxuXHRpZiAoIW91dEV4cHJlc3Npb24uZm9ybWF0T3B0aW9ucykge1xuXHRcdG91dEV4cHJlc3Npb24uZm9ybWF0T3B0aW9ucyA9IHt9O1xuXHR9XG5cdG91dEV4cHJlc3Npb24uY29uc3RyYWludHMgPSB7fTtcblxuXHRvdXRFeHByZXNzaW9uLnR5cGUgPSB0YXJnZXRNYXBwaW5nLnR5cGU7XG5cdGlmICghaWdub3JlQ29uc3RyYWludHMpIHtcblx0XHRvdXRFeHByZXNzaW9uLmNvbnN0cmFpbnRzID0gc2V0VXBDb25zdHJhaW50cyh0YXJnZXRNYXBwaW5nLCBwcm9wZXJ0eSk7XG5cdH1cblxuXHRpZiAoXG5cdFx0KG91dEV4cHJlc3Npb24/LnR5cGU/LmluZGV4T2YoXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnRcIikgPT09IDAgJiYgb3V0RXhwcmVzc2lvbj8udHlwZSAhPT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnQ2NFwiKSB8fFxuXHRcdG91dEV4cHJlc3Npb24/LnR5cGUgPT09IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuRG91YmxlXCJcblx0KSB7XG5cdFx0b3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zID0gT2JqZWN0LmFzc2lnbihvdXRFeHByZXNzaW9uLmZvcm1hdE9wdGlvbnMsIHtcblx0XHRcdHBhcnNlQXNTdHJpbmc6IGZhbHNlXG5cdFx0fSk7XG5cdH1cblx0aWYgKG91dEV4cHJlc3Npb24udHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5TdHJpbmdcIiAmJiBpc1Byb3BlcnR5KHByb3BlcnR5KSkge1xuXHRcdGlmICghb3V0RXhwcmVzc2lvbi5jb25zdHJhaW50cz8uaXNEaWdpdFNlcXVlbmNlIHx8IG91dEV4cHJlc3Npb24uY29uc3RyYWludHM/Lm51bGxhYmxlID09PSBmYWxzZSkge1xuXHRcdFx0b3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zLnBhcnNlS2VlcHNFbXB0eVN0cmluZyA9IHRydWU7XG5cdFx0fVxuXHRcdGNvbnN0IGZpc2NhbFR5cGUgPSBnZXRGaXNjYWxUeXBlKHByb3BlcnR5KTtcblx0XHRpZiAoZmlzY2FsVHlwZSkge1xuXHRcdFx0b3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zLmZpc2NhbFR5cGUgPSBmaXNjYWxUeXBlO1xuXHRcdFx0b3V0RXhwcmVzc2lvbi50eXBlID0gXCJzYXAuZmUuY29yZS50eXBlLkZpc2NhbERhdGVcIjtcblx0XHR9XG5cdH1cblx0Y29uc3QgdHlwZXNTdXBwb3J0aW5nUGFyc2VFbXB0eVZhbHVlVG9aZXJvID0gW1xuXHRcdFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuSW50MTZcIixcblx0XHRcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludDMyXCIsXG5cdFx0XCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnQ2NFwiLFxuXHRcdFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuU2luZ2xlXCIsXG5cdFx0XCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5Eb3VibGVcIixcblx0XHRcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRlY2ltYWxcIixcblx0XHRcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkJ5dGVcIixcblx0XHRcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLlNCeXRlXCJcblx0XTtcblx0aWYgKFxuXHRcdG91dEV4cHJlc3Npb24uY29uc3RyYWludHM/Lm51bGxhYmxlID09PSBmYWxzZSAmJlxuXHRcdG91dEV4cHJlc3Npb24udHlwZSAmJlxuXHRcdHR5cGVzU3VwcG9ydGluZ1BhcnNlRW1wdHlWYWx1ZVRvWmVyby5pbmNsdWRlcyhvdXRFeHByZXNzaW9uLnR5cGUpXG5cdCkge1xuXHRcdG91dEV4cHJlc3Npb24uZm9ybWF0T3B0aW9ucyA9IE9iamVjdC5hc3NpZ24ob3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zLCB7XG5cdFx0XHRwYXJzZUVtcHR5VmFsdWVUb1plcm86IHRydWVcblx0XHR9KTtcblx0fVxuXHRpZiAoXG5cdFx0b3V0RXhwcmVzc2lvbi5jb25zdHJhaW50cz8ubnVsbGFibGUgIT09IGZhbHNlICYmXG5cdFx0KG91dEV4cHJlc3Npb24udHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnQ2NFwiIHx8IG91dEV4cHJlc3Npb24udHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5EZWNpbWFsXCIpXG5cdCkge1xuXHRcdG91dEV4cHJlc3Npb24uZm9ybWF0T3B0aW9ucyA9IE9iamVjdC5hc3NpZ24ob3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zLCB7XG5cdFx0XHRlbXB0eVN0cmluZzogXCJcIlxuXHRcdH0pO1xuXHR9XG5cblx0cmV0dXJuIG91dEV4cHJlc3Npb247XG59XG5cbmV4cG9ydCBjb25zdCBnZXRGaXNjYWxUeXBlID0gZnVuY3Rpb24gKHByb3BlcnR5OiBQcm9wZXJ0eSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG5cdGlmIChwcm9wZXJ0eS5hbm5vdGF0aW9ucz8uQ29tbW9uPy5Jc0Zpc2NhbFllYXIpIHtcblx0XHRyZXR1cm4gQ29tbW9uQW5ub3RhdGlvblRlcm1zLklzRmlzY2FsWWVhcjtcblx0fVxuXHRpZiAocHJvcGVydHkuYW5ub3RhdGlvbnM/LkNvbW1vbj8uSXNGaXNjYWxQZXJpb2QpIHtcblx0XHRyZXR1cm4gQ29tbW9uQW5ub3RhdGlvblRlcm1zLklzRmlzY2FsUGVyaW9kO1xuXHR9XG5cdGlmIChwcm9wZXJ0eS5hbm5vdGF0aW9ucz8uQ29tbW9uPy5Jc0Zpc2NhbFllYXJQZXJpb2QpIHtcblx0XHRyZXR1cm4gQ29tbW9uQW5ub3RhdGlvblRlcm1zLklzRmlzY2FsWWVhclBlcmlvZDtcblx0fVxuXHRpZiAocHJvcGVydHkuYW5ub3RhdGlvbnM/LkNvbW1vbj8uSXNGaXNjYWxRdWFydGVyKSB7XG5cdFx0cmV0dXJuIENvbW1vbkFubm90YXRpb25UZXJtcy5Jc0Zpc2NhbFF1YXJ0ZXI7XG5cdH1cblx0aWYgKHByb3BlcnR5LmFubm90YXRpb25zPy5Db21tb24/LklzRmlzY2FsWWVhclF1YXJ0ZXIpIHtcblx0XHRyZXR1cm4gQ29tbW9uQW5ub3RhdGlvblRlcm1zLklzRmlzY2FsWWVhclF1YXJ0ZXI7XG5cdH1cblx0aWYgKHByb3BlcnR5LmFubm90YXRpb25zPy5Db21tb24/LklzRmlzY2FsV2Vlaykge1xuXHRcdHJldHVybiBDb21tb25Bbm5vdGF0aW9uVGVybXMuSXNGaXNjYWxXZWVrO1xuXHR9XG5cdGlmIChwcm9wZXJ0eS5hbm5vdGF0aW9ucz8uQ29tbW9uPy5Jc0Zpc2NhbFllYXJXZWVrKSB7XG5cdFx0cmV0dXJuIENvbW1vbkFubm90YXRpb25UZXJtcy5Jc0Zpc2NhbFllYXJXZWVrO1xuXHR9XG5cdGlmIChwcm9wZXJ0eS5hbm5vdGF0aW9ucz8uQ29tbW9uPy5Jc0RheU9mRmlzY2FsWWVhcikge1xuXHRcdHJldHVybiBDb21tb25Bbm5vdGF0aW9uVGVybXMuSXNEYXlPZkZpc2NhbFllYXI7XG5cdH1cbn07XG5cbi8qKlxuICogQ2FsbHMgYSBjb21wbGV4IHR5cGUgdG8gcHJvY2VzcyB0aGUgcGFyYW1ldGVycy5cbiAqIElmIHJlcXVpcmVDb250ZXh0IGlzIHNldCB0byB0cnVlIGFuZCBubyBjb250ZXh0IGlzIHBhc3NlZCwgYSBkZWZhdWx0IGNvbnRleHQgd2lsbCBiZSBhZGRlZCBhdXRvbWF0aWNhbGx5LlxuICpcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAdGVtcGxhdGUgVVxuICogQHBhcmFtIHBhcmFtZXRlcnMgVGhlIGxpc3Qgb2YgcGFyYW1ldGVycyB0aGF0IHNob3VsZCBtYXRjaCB0aGUgdHlwZSBmb3IgdGhlIGNvbXBsZXggdHlwZT1cbiAqIEBwYXJhbSB0eXBlIFRoZSBjb21wbGV4IHR5cGUgdG8gdXNlXG4gKiBAcGFyYW0gW2NvbnRleHRFbnRpdHlUeXBlXSBUaGUgY29udGV4dCBlbnRpdHkgdHlwZSB0byBjb25zaWRlclxuICogQHBhcmFtIG9Gb3JtYXRPcHRpb25zXG4gKiBAcmV0dXJucyBUaGUgY29ycmVzcG9uZGluZyBleHByZXNzaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRUeXBlSW5mb3JtYXRpb248VCwgVSBleHRlbmRzIEZuPFQ+Pihcblx0cGFyYW1ldGVyczogV3JhcHBlZFR1cGxlPFBhcmFtZXRlcnM8VT4+LFxuXHR0eXBlOiBzdHJpbmcsXG5cdGNvbnRleHRFbnRpdHlUeXBlPzogRW50aXR5VHlwZSxcblx0b0Zvcm1hdE9wdGlvbnM/OiBDb21wbGV4VHlwZUZvcm1hdE9wdGlvbnNcbik6IFVucmVzb2x2YWJsZVBhdGhFeHByZXNzaW9uIHwgQ29tcGxleFR5cGVFeHByZXNzaW9uPFQ+IHwgQ29uc3RhbnRFeHByZXNzaW9uPFQ+IHtcblx0Y29uc3QgcGFyYW1ldGVyRXhwcmVzc2lvbnMgPSAocGFyYW1ldGVycyBhcyBFeHByZXNzaW9uT3JQcmltaXRpdmU8UHJpbWl0aXZlVHlwZT5bXSkubWFwKHdyYXBQcmltaXRpdmUpO1xuXHRpZiAoaGFzVW5yZXNvbHZhYmxlRXhwcmVzc2lvbiguLi5wYXJhbWV0ZXJFeHByZXNzaW9ucykpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHQvLyBJZiB0aGVyZSBpcyBvbmx5IG9uZSBwYXJhbWV0ZXIgYW5kIGl0IGlzIGEgY29uc3RhbnQgYW5kIHdlIGRvbid0IGV4cGVjdCB0aGUgY29udGV4dCB0aGVuIHJldHVybiB0aGUgY29uc3RhbnRcblx0aWYgKHBhcmFtZXRlckV4cHJlc3Npb25zLmxlbmd0aCA9PT0gMSAmJiBpc0NvbnN0YW50KHBhcmFtZXRlckV4cHJlc3Npb25zWzBdKSAmJiAhY29udGV4dEVudGl0eVR5cGUpIHtcblx0XHRyZXR1cm4gcGFyYW1ldGVyRXhwcmVzc2lvbnNbMF0gYXMgQ29uc3RhbnRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGNvbnRleHRFbnRpdHlUeXBlKSB7XG5cdFx0Ly8gT3RoZXJ3aXNlLCBpZiB0aGUgY29udGV4dCBpcyByZXF1aXJlZCBhbmQgbm8gY29udGV4dCBpcyBwcm92aWRlZCBtYWtlIHN1cmUgdG8gYWRkIHRoZSBkZWZhdWx0IGJpbmRpbmdcblx0XHRpZiAoIXBhcmFtZXRlckV4cHJlc3Npb25zLnNvbWUoaGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dCkpIHtcblx0XHRcdGNvbnRleHRFbnRpdHlUeXBlLmtleXMuZm9yRWFjaCgoa2V5KSA9PiBwYXJhbWV0ZXJFeHByZXNzaW9ucy5wdXNoKHBhdGhJbk1vZGVsKGtleS5uYW1lLCBcIlwiKSkpO1xuXHRcdH1cblx0fVxuXHRvRm9ybWF0T3B0aW9ucyA9IF9nZXRDb21wbGV4VHlwZUZvcm1hdE9wdGlvbnNGcm9tRmlyc3RQYXJhbShwYXJhbWV0ZXJzWzBdLCBvRm9ybWF0T3B0aW9ucyk7XG5cblx0aWYgKHR5cGUgPT09IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuVW5pdFwiKSB7XG5cdFx0Y29uc3QgdW9tUGF0aCA9IHBhdGhJbk1vZGVsKFwiLyMjQEByZXF1ZXN0VW5pdHNPZk1lYXN1cmVcIik7XG5cdFx0dW9tUGF0aC50YXJnZXRUeXBlID0gXCJhbnlcIjtcblx0XHR1b21QYXRoLm1vZGUgPSBcIk9uZVRpbWVcIjtcblx0XHRwYXJhbWV0ZXJFeHByZXNzaW9ucy5wdXNoKHVvbVBhdGgpO1xuXHR9IGVsc2UgaWYgKHR5cGUgPT09IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuQ3VycmVuY3lcIikge1xuXHRcdGNvbnN0IGN1cnJlbmN5UGF0aCA9IHBhdGhJbk1vZGVsKFwiLyMjQEByZXF1ZXN0Q3VycmVuY3lDb2Rlc1wiKTtcblx0XHRjdXJyZW5jeVBhdGgudGFyZ2V0VHlwZSA9IFwiYW55XCI7XG5cdFx0Y3VycmVuY3lQYXRoLm1vZGUgPSBcIk9uZVRpbWVcIjtcblx0XHRwYXJhbWV0ZXJFeHByZXNzaW9ucy5wdXNoKGN1cnJlbmN5UGF0aCk7XG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdF90eXBlOiBcIkNvbXBsZXhUeXBlXCIsXG5cdFx0dHlwZTogdHlwZSxcblx0XHRmb3JtYXRPcHRpb25zOiBvRm9ybWF0T3B0aW9ucyB8fCB7fSxcblx0XHRwYXJhbWV0ZXJzOiB7fSxcblx0XHRiaW5kaW5nUGFyYW1ldGVyczogcGFyYW1ldGVyRXhwcmVzc2lvbnNcblx0fTtcbn1cblxudHlwZSBDb21wbGV4VHlwZUZvcm1hdE9wdGlvbnMgPSB7XG5cdHNob3dOdW1iZXI/OiBib29sZWFuO1xuXHRzaG93TWVhc3VyZT86IGJvb2xlYW47XG5cdHBhcnNlQXNTdHJpbmc/OiBib29sZWFuO1xuXHRwYXJzZUtlZXBzRW1wdHlTdHJpbmc/OiBib29sZWFuO1xuXHRlbXB0eVN0cmluZz86IHN0cmluZyB8IG51bWJlciB8IG51bGw7XG5cdHNob3dUaW1lPzogYm9vbGVhbjtcblx0c2hvd0RhdGU/OiBib29sZWFuO1xuXHRzaG93VGltZXpvbmU/OiBib29sZWFuO1xufTtcblxuLyoqXG4gKiBQcm9jZXNzIHRoZSBmb3JtYXRPcHRpb25zIGZvciBhIGNvbXBsZXhUeXBlIGJhc2VkIG9uIHRoZSBmaXJzdCBwYXJhbWV0ZXIuXG4gKlxuICogQHBhcmFtIHBhcmFtIFRoZSBmaXJzdCBwYXJhbWV0ZXIgb2YgdGhlIGNvbXBsZXggdHlwZVxuICogQHBhcmFtIGZvcm1hdE9wdGlvbnMgSW5pdGlhbCBmb3JtYXRPcHRpb25zXG4gKiBAcmV0dXJucyBUaGUgbW9kaWZpZWQgZm9ybWF0T3B0aW9uc1xuICovXG5mdW5jdGlvbiBfZ2V0Q29tcGxleFR5cGVGb3JtYXRPcHRpb25zRnJvbUZpcnN0UGFyYW08VCwgVSBleHRlbmRzIEZuPFQ+Pihcblx0cGFyYW06IFBhcmFtZXRlcnM8VT4sXG5cdGZvcm1hdE9wdGlvbnM6IHVuZGVmaW5lZCB8IENvbXBsZXhUeXBlRm9ybWF0T3B0aW9uc1xuKTogQ29tcGxleFR5cGVGb3JtYXRPcHRpb25zIHwgdW5kZWZpbmVkIHtcblx0Ly8gaWYgc2hvd01lYXN1cmUgaXMgc2V0IHRvIGZhbHNlIHdlIHdhbnQgdG8gbm90IHBhcnNlIGFzIHN0cmluZyB0byBzZWUgdGhlIDBcblx0Ly8gd2UgZG8gdGhhdCBhbHNvIGZvciBhbGwgYmluZGluZ3MgYmVjYXVzZSBvdGhlcndpc2UgdGhlIG1kYyBGaWVsZCBpc24ndCBlZGl0YWJsZVxuXHRpZiAoXG5cdFx0IShmb3JtYXRPcHRpb25zICYmIGZvcm1hdE9wdGlvbnMuc2hvd051bWJlciA9PT0gZmFsc2UpICYmXG5cdFx0KHBhcmFtPy50eXBlPy5pbmRleE9mKFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuSW50XCIpID09PSAwIHx8XG5cdFx0XHRwYXJhbT8udHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5EZWNpbWFsXCIgfHxcblx0XHRcdHBhcmFtPy50eXBlID09PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRvdWJsZVwiKVxuXHQpIHtcblx0XHRpZiAocGFyYW0/LnR5cGUgPT09IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuSW50NjRcIiB8fCBwYXJhbT8udHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5EZWNpbWFsXCIpIHtcblx0XHRcdC8vc2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuSW50NjQgZG8gbm90IHN1cHBvcnQgcGFyc2VBc1N0cmluZyBmYWxzZVxuXHRcdFx0Zm9ybWF0T3B0aW9ucyA9IGZvcm1hdE9wdGlvbnM/LnNob3dNZWFzdXJlID09PSBmYWxzZSA/IHsgc2hvd01lYXN1cmU6IGZhbHNlIH0gOiB7fTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9ybWF0T3B0aW9ucyA9IGZvcm1hdE9wdGlvbnM/LnNob3dNZWFzdXJlID09PSBmYWxzZSA/IHsgcGFyc2VBc1N0cmluZzogZmFsc2UsIHNob3dNZWFzdXJlOiBmYWxzZSB9IDogeyBwYXJzZUFzU3RyaW5nOiBmYWxzZSB9O1xuXHRcdH1cblx0XHRmb3JtYXRPcHRpb25zLmVtcHR5U3RyaW5nID0gbnVsbDtcblx0fVxuXHRyZXR1cm4gZm9ybWF0T3B0aW9ucztcbn1cbi8qKlxuICogRnVuY3Rpb24gY2FsbCwgb3B0aW9uYWxseSB3aXRoIGFyZ3VtZW50cy5cbiAqXG4gKiBAcGFyYW0gZnVuYyBGdW5jdGlvbiBuYW1lIG9yIHJlZmVyZW5jZSB0byBmdW5jdGlvblxuICogQHBhcmFtIHBhcmFtZXRlcnMgQXJndW1lbnRzXG4gKiBAcGFyYW0gb24gT2JqZWN0IHRvIGNhbGwgdGhlIGZ1bmN0aW9uIG9uXG4gKiBAcGFyYW0gaXNGb3JtYXR0aW5nRm5cbiAqIEByZXR1cm5zIEV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBmdW5jdGlvbiBjYWxsIChub3QgdGhlIHJlc3VsdCBvZiB0aGUgZnVuY3Rpb24gY2FsbCEpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmbjxULCBVIGV4dGVuZHMgRnVuY3Rpb25Pck5hbWU8VD4+KFxuXHRmdW5jOiBVLFxuXHRwYXJhbWV0ZXJzOiBXcmFwcGVkVHVwbGU8RnVuY3Rpb25QYXJhbWV0ZXJzPFQsIFU+Pixcblx0b24/OiBFeHByZXNzaW9uT3JQcmltaXRpdmU8b2JqZWN0Pixcblx0aXNGb3JtYXR0aW5nRm4gPSBmYWxzZVxuKTogRnVuY3Rpb25FeHByZXNzaW9uPFQ+IHtcblx0Y29uc3QgZnVuY3Rpb25OYW1lID0gdHlwZW9mIGZ1bmMgPT09IFwic3RyaW5nXCIgPyBmdW5jIDogZnVuYy5fX2Z1bmN0aW9uTmFtZTtcblx0cmV0dXJuIHtcblx0XHRfdHlwZTogXCJGdW5jdGlvblwiLFxuXHRcdG9iajogb24gIT09IHVuZGVmaW5lZCA/IHdyYXBQcmltaXRpdmUob24pIDogdW5kZWZpbmVkLFxuXHRcdGZuOiBmdW5jdGlvbk5hbWUsXG5cdFx0aXNGb3JtYXR0aW5nRm46IGlzRm9ybWF0dGluZ0ZuLFxuXHRcdHBhcmFtZXRlcnM6IChwYXJhbWV0ZXJzIGFzIEV4cHJlc3Npb25PclByaW1pdGl2ZTxQcmltaXRpdmVUeXBlPltdKS5tYXAod3JhcFByaW1pdGl2ZSlcblx0fTtcbn1cblxuLyoqXG4gKiBTaG9ydGN1dCBmdW5jdGlvbiB0byBkZXRlcm1pbmUgaWYgYSBiaW5kaW5nIHZhbHVlIGlzIG51bGwsIHVuZGVmaW5lZCBvciBlbXB0eS5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvblxuICogQHJldHVybnMgQSBCb29sZWFuIGV4cHJlc3Npb24gZXZhbHVhdGluZyB0aGUgZmFjdCB0aGF0IHRoZSBjdXJyZW50IGVsZW1lbnQgaXMgZW1wdHlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRW1wdHkoZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHN0cmluZz4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRjb25zdCBhQmluZGluZ3M6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxib29sZWFuPltdID0gW107XG5cdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KGV4cHJlc3Npb24sIFwiUGF0aEluTW9kZWxcIiwgKGV4cHIpID0+IHtcblx0XHRhQmluZGluZ3MucHVzaChvcihlcXVhbChleHByLCBcIlwiKSwgZXF1YWwoZXhwciwgdW5kZWZpbmVkKSwgZXF1YWwoZXhwciwgbnVsbCkpKTtcblx0XHRyZXR1cm4gZXhwcjtcblx0fSk7XG5cdHJldHVybiBhbmQoLi4uYUJpbmRpbmdzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbmNhdCguLi5pbkV4cHJlc3Npb25zOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8c3RyaW5nPltdKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHN0cmluZz4ge1xuXHRjb25zdCBleHByZXNzaW9ucyA9IGluRXhwcmVzc2lvbnMubWFwKHdyYXBQcmltaXRpdmUpO1xuXHRpZiAoaGFzVW5yZXNvbHZhYmxlRXhwcmVzc2lvbiguLi5leHByZXNzaW9ucykpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRpZiAoZXhwcmVzc2lvbnMuZXZlcnkoaXNDb25zdGFudCkpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQoXG5cdFx0XHRleHByZXNzaW9ucy5yZWR1Y2UoKGNvbmNhdGVuYXRlZDogc3RyaW5nLCB2YWx1ZSkgPT4ge1xuXHRcdFx0XHRpZiAodmFsdWUudmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZS52YWx1ZSAhPT0gbnVsbCkge1xuXHRcdFx0XHRcdHJldHVybiBjb25jYXRlbmF0ZWQgKyB2YWx1ZS52YWx1ZS50b1N0cmluZygpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBjb25jYXRlbmF0ZWQ7XG5cdFx0XHR9LCBcIlwiKVxuXHRcdCk7XG5cdH0gZWxzZSBpZiAoZXhwcmVzc2lvbnMuc29tZShpc0NvbXBsZXhUeXBlRXhwcmVzc2lvbikpIHtcblx0XHRsZXQgcGF0aElkeCA9IDA7XG5cdFx0Y29uc3QgbXlDb25jYXRFeHByZXNzaW9uID0gZm9ybWF0UmVzdWx0KGV4cHJlc3Npb25zLCBcInNhcC5mZS5jb3JlLmZvcm1hdHRlcnMuU3RhbmRhcmRGb3JtYXR0ZXIjY29uY2F0XCIsIHVuZGVmaW5lZCwgdHJ1ZSk7XG5cdFx0Y29uc3QgYWxsUGFydHMgPSBbXTtcblx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShteUNvbmNhdEV4cHJlc3Npb24sIFwiUGF0aEluTW9kZWxcIiwgKGNvbnN0YW50UGF0aDogUGF0aEluTW9kZWxFeHByZXNzaW9uPHVua25vd24+KSA9PiB7XG5cdFx0XHRhbGxQYXJ0cy5wdXNoKGNvbnN0YW50UGF0aCk7XG5cdFx0XHRyZXR1cm4gcGF0aEluTW9kZWwoYCQke3BhdGhJZHgrK31gLCBcIiRcIik7XG5cdFx0fSk7XG5cdFx0YWxsUGFydHMudW5zaGlmdChjb25zdGFudChKU09OLnN0cmluZ2lmeShteUNvbmNhdEV4cHJlc3Npb24pKSk7XG5cdFx0cmV0dXJuIGZvcm1hdFJlc3VsdChhbGxQYXJ0cywgXCJzYXAuZmUuY29yZS5mb3JtYXR0ZXJzLlN0YW5kYXJkRm9ybWF0dGVyI2V2YWx1YXRlQ29tcGxleEV4cHJlc3Npb25cIiwgdW5kZWZpbmVkLCB0cnVlKTtcblx0fVxuXHRyZXR1cm4ge1xuXHRcdF90eXBlOiBcIkNvbmNhdFwiLFxuXHRcdGV4cHJlc3Npb25zOiBleHByZXNzaW9uc1xuXHR9O1xufVxuXG50eXBlIEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPFQgZXh0ZW5kcyBFeHByZXNzaW9uVHlwZSwgVj4gPSBUIGV4dGVuZHMgXCJDb25zdGFudFwiXG5cdD8gQ29uc3RhbnRFeHByZXNzaW9uPFY+XG5cdDogVCBleHRlbmRzIFwiUGF0aEluTW9kZWxcIlxuXHQ/IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxWPlxuXHQ6IFQgZXh0ZW5kcyBcIkZ1bmN0aW9uXCJcblx0PyBGdW5jdGlvbkV4cHJlc3Npb248Vj5cblx0OiBUIGV4dGVuZHMgXCJVbnJlc29sdmFibGVcIlxuXHQ/IFVucmVzb2x2YWJsZVBhdGhFeHByZXNzaW9uXG5cdDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFY+O1xuXG5leHBvcnQgdHlwZSBUcmFuc2Zvcm1GdW5jdGlvbjxULCBWPiA9IChleHByZXNzaW9uUGFydDogVCkgPT4gQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFY+O1xuZXhwb3J0IHR5cGUgRXhwcmVzc2lvblR5cGUgPSBQaWNrPEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPiwgXCJfdHlwZVwiPltcIl90eXBlXCJdO1xuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybVJlY3Vyc2l2ZWx5PFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlIHwgdW5rbm93biwgRVQgZXh0ZW5kcyBFeHByZXNzaW9uVHlwZT4oXG5cdGluRXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+LFxuXHRleHByZXNzaW9uVHlwZTogRVQsXG5cdHRyYW5zZm9ybUZ1bmN0aW9uOiBUcmFuc2Zvcm1GdW5jdGlvbjxFeHByZXNzaW9uVHlwZVRvRXhwcmVzc2lvbjxFVCwgVD4sIFQ+LFxuXHRpbmNsdWRlQWxsRXhwcmVzc2lvbiA9IGZhbHNlXG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4ge1xuXHRsZXQgZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+ID0gaW5FeHByZXNzaW9uO1xuXHRzd2l0Y2ggKGV4cHJlc3Npb24uX3R5cGUpIHtcblx0XHRjYXNlIFwiRnVuY3Rpb25cIjpcblx0XHRjYXNlIFwiRm9ybWF0dGVyXCI6XG5cdFx0XHRleHByZXNzaW9uLnBhcmFtZXRlcnMgPSBleHByZXNzaW9uLnBhcmFtZXRlcnMubWFwKChwYXJhbWV0ZXIpID0+XG5cdFx0XHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KHBhcmFtZXRlciBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4sIGV4cHJlc3Npb25UeXBlLCB0cmFuc2Zvcm1GdW5jdGlvbiwgaW5jbHVkZUFsbEV4cHJlc3Npb24pXG5cdFx0XHQpO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIkNvbmNhdFwiOlxuXHRcdFx0ZXhwcmVzc2lvbi5leHByZXNzaW9ucyA9IGV4cHJlc3Npb24uZXhwcmVzc2lvbnMubWFwKChzdWJFeHByZXNzaW9uKSA9PlxuXHRcdFx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0XHRzdWJFeHByZXNzaW9uLFxuXHRcdFx0XHRcdGV4cHJlc3Npb25UeXBlLFxuXHRcdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uIGFzIHVua25vd24gYXMgVHJhbnNmb3JtRnVuY3Rpb248RXhwcmVzc2lvblR5cGVUb0V4cHJlc3Npb248RVQsIHN0cmluZz4sIHN0cmluZz4sXG5cdFx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdFx0KVxuXHRcdFx0KTtcblx0XHRcdGV4cHJlc3Npb24gPSBjb25jYXQoLi4uZXhwcmVzc2lvbi5leHByZXNzaW9ucykgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIkNvbXBsZXhUeXBlXCI6XG5cdFx0XHRleHByZXNzaW9uLmJpbmRpbmdQYXJhbWV0ZXJzID0gZXhwcmVzc2lvbi5iaW5kaW5nUGFyYW1ldGVycy5tYXAoKGJpbmRpbmdQYXJhbWV0ZXIpID0+XG5cdFx0XHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdGJpbmRpbmdQYXJhbWV0ZXIgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+LFxuXHRcdFx0XHRcdGV4cHJlc3Npb25UeXBlLFxuXHRcdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uLFxuXHRcdFx0XHRcdGluY2x1ZGVBbGxFeHByZXNzaW9uXG5cdFx0XHRcdClcblx0XHRcdCk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiSWZFbHNlXCI6XG5cdFx0XHRjb25zdCBvblRydWUgPSB0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0ZXhwcmVzc2lvbi5vblRydWUsXG5cdFx0XHRcdGV4cHJlc3Npb25UeXBlLFxuXHRcdFx0XHR0cmFuc2Zvcm1GdW5jdGlvbiBhcyB1bmtub3duIGFzIFRyYW5zZm9ybUZ1bmN0aW9uPEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPEVULCB1bmtub3duPiwgdW5rbm93bj4sXG5cdFx0XHRcdGluY2x1ZGVBbGxFeHByZXNzaW9uXG5cdFx0XHQpO1xuXHRcdFx0Y29uc3Qgb25GYWxzZSA9IHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRleHByZXNzaW9uLm9uRmFsc2UsXG5cdFx0XHRcdGV4cHJlc3Npb25UeXBlLFxuXHRcdFx0XHR0cmFuc2Zvcm1GdW5jdGlvbiBhcyB1bmtub3duIGFzIFRyYW5zZm9ybUZ1bmN0aW9uPEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPEVULCB1bmtub3duPiwgdW5rbm93bj4sXG5cdFx0XHRcdGluY2x1ZGVBbGxFeHByZXNzaW9uXG5cdFx0XHQpO1xuXHRcdFx0bGV0IGNvbmRpdGlvbiA9IGV4cHJlc3Npb24uY29uZGl0aW9uO1xuXHRcdFx0aWYgKGluY2x1ZGVBbGxFeHByZXNzaW9uKSB7XG5cdFx0XHRcdGNvbmRpdGlvbiA9IHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdGV4cHJlc3Npb24uY29uZGl0aW9uLFxuXHRcdFx0XHRcdGV4cHJlc3Npb25UeXBlLFxuXHRcdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uIGFzIHVua25vd24gYXMgVHJhbnNmb3JtRnVuY3Rpb248RXhwcmVzc2lvblR5cGVUb0V4cHJlc3Npb248RVQsIGJvb2xlYW4+LCBib29sZWFuPixcblx0XHRcdFx0XHRpbmNsdWRlQWxsRXhwcmVzc2lvblxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdFx0ZXhwcmVzc2lvbiA9IGlmRWxzZShjb25kaXRpb24sIG9uVHJ1ZSwgb25GYWxzZSkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIk5vdFwiOlxuXHRcdFx0aWYgKGluY2x1ZGVBbGxFeHByZXNzaW9uKSB7XG5cdFx0XHRcdGNvbnN0IG9wZXJhbmQgPSB0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0XHRleHByZXNzaW9uLm9wZXJhbmQsXG5cdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0dHJhbnNmb3JtRnVuY3Rpb24gYXMgdW5rbm93biBhcyBUcmFuc2Zvcm1GdW5jdGlvbjxFeHByZXNzaW9uVHlwZVRvRXhwcmVzc2lvbjxFVCwgYm9vbGVhbj4sIGJvb2xlYW4+LFxuXHRcdFx0XHRcdGluY2x1ZGVBbGxFeHByZXNzaW9uXG5cdFx0XHRcdCk7XG5cdFx0XHRcdGV4cHJlc3Npb24gPSBub3Qob3BlcmFuZCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHRcdFx0fVxuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIlRydXRoeVwiOlxuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIlNldFwiOlxuXHRcdFx0aWYgKGluY2x1ZGVBbGxFeHByZXNzaW9uKSB7XG5cdFx0XHRcdGNvbnN0IG9wZXJhbmRzID0gZXhwcmVzc2lvbi5vcGVyYW5kcy5tYXAoKG9wZXJhbmQpID0+XG5cdFx0XHRcdFx0dHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRcdFx0XHRvcGVyYW5kLFxuXHRcdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0XHR0cmFuc2Zvcm1GdW5jdGlvbiBhcyB1bmtub3duIGFzIFRyYW5zZm9ybUZ1bmN0aW9uPEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPEVULCBib29sZWFuPiwgYm9vbGVhbj4sXG5cdFx0XHRcdFx0XHRpbmNsdWRlQWxsRXhwcmVzc2lvblxuXHRcdFx0XHRcdClcblx0XHRcdFx0KTtcblx0XHRcdFx0ZXhwcmVzc2lvbiA9XG5cdFx0XHRcdFx0ZXhwcmVzc2lvbi5vcGVyYXRvciA9PT0gXCJ8fFwiXG5cdFx0XHRcdFx0XHQ/IChvciguLi5vcGVyYW5kcykgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+KVxuXHRcdFx0XHRcdFx0OiAoYW5kKC4uLm9wZXJhbmRzKSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4pO1xuXHRcdFx0fVxuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIkNvbXBhcmlzb25cIjpcblx0XHRcdGlmIChpbmNsdWRlQWxsRXhwcmVzc2lvbikge1xuXHRcdFx0XHRjb25zdCBvcGVyYW5kMSA9IHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdGV4cHJlc3Npb24ub3BlcmFuZDEgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+LFxuXHRcdFx0XHRcdGV4cHJlc3Npb25UeXBlLFxuXHRcdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uLFxuXHRcdFx0XHRcdGluY2x1ZGVBbGxFeHByZXNzaW9uXG5cdFx0XHRcdCk7XG5cdFx0XHRcdGNvbnN0IG9wZXJhbmQyID0gdHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRcdFx0ZXhwcmVzc2lvbi5vcGVyYW5kMiBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4sXG5cdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0dHJhbnNmb3JtRnVuY3Rpb24sXG5cdFx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdFx0KTtcblx0XHRcdFx0ZXhwcmVzc2lvbiA9IGNvbXBhcmlzb24oZXhwcmVzc2lvbi5vcGVyYXRvciwgb3BlcmFuZDEsIG9wZXJhbmQyKSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdFx0XHR9XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiQ29uc3RhbnRcIjpcblx0XHRcdGNvbnN0IGNvbnN0YW50VmFsdWU6IFJlY29yZDxzdHJpbmcsIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPj4gPSBleHByZXNzaW9uLnZhbHVlIGFzIFJlY29yZDxcblx0XHRcdFx0c3RyaW5nLFxuXHRcdFx0XHRCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj5cblx0XHRcdD47XG5cdFx0XHRpZiAodHlwZW9mIGNvbnN0YW50VmFsdWUgPT09IFwib2JqZWN0XCIgJiYgY29uc3RhbnRWYWx1ZSkge1xuXHRcdFx0XHRPYmplY3Qua2V5cyhjb25zdGFudFZhbHVlKS5mb3JFYWNoKChrZXkpID0+IHtcblx0XHRcdFx0XHRjb25zdGFudFZhbHVlW2tleV0gPSB0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0XHRcdGNvbnN0YW50VmFsdWVba2V5XSxcblx0XHRcdFx0XHRcdGV4cHJlc3Npb25UeXBlLFxuXHRcdFx0XHRcdFx0dHJhbnNmb3JtRnVuY3Rpb24gYXMgdW5rbm93biBhcyBUcmFuc2Zvcm1GdW5jdGlvbjxFeHByZXNzaW9uVHlwZVRvRXhwcmVzc2lvbjxFVCwgdW5rbm93bj4sIHVua25vd24+LFxuXHRcdFx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgXCJSZWZcIjpcblx0XHRjYXNlIFwiTGVuZ3RoXCI6XG5cdFx0Y2FzZSBcIlBhdGhJbk1vZGVsXCI6XG5cdFx0Y2FzZSBcIkVtYmVkZGVkQmluZGluZ1wiOlxuXHRcdGNhc2UgXCJFbWJlZGRlZEV4cHJlc3Npb25CaW5kaW5nXCI6XG5cdFx0Y2FzZSBcIlVucmVzb2x2YWJsZVwiOlxuXHRcdFx0Ly8gRG8gbm90aGluZ1xuXHRcdFx0YnJlYWs7XG5cdH1cblx0aWYgKGV4cHJlc3Npb25UeXBlID09PSBleHByZXNzaW9uLl90eXBlKSB7XG5cdFx0ZXhwcmVzc2lvbiA9IHRyYW5zZm9ybUZ1bmN0aW9uKGluRXhwcmVzc2lvbiBhcyBFeHByZXNzaW9uVHlwZVRvRXhwcmVzc2lvbjxFVCwgVD4pO1xuXHR9XG5cdHJldHVybiBleHByZXNzaW9uO1xufVxuXG5leHBvcnQgdHlwZSBDb21waWxlZEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbiA9IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuY29uc3QgbmVlZFBhcmVudGhlc2lzID0gZnVuY3Rpb24gPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihleHByOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4pOiBib29sZWFuIHtcblx0cmV0dXJuIChcblx0XHQhaXNDb25zdGFudChleHByKSAmJlxuXHRcdCFpc1BhdGhJbk1vZGVsRXhwcmVzc2lvbihleHByKSAmJlxuXHRcdGlzQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uKGV4cHIpICYmXG5cdFx0ZXhwci5fdHlwZSAhPT0gXCJJZkVsc2VcIiAmJlxuXHRcdGV4cHIuX3R5cGUgIT09IFwiRnVuY3Rpb25cIlxuXHQpO1xufTtcblxuLyoqXG4gKiBDb21waWxlcyBhIGNvbnN0YW50IG9iamVjdCB0byBhIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gZXhwclxuICogQHBhcmFtIGlzTnVsbGFibGVcbiAqIEByZXR1cm5zIFRoZSBjb21waWxlZCBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gY29tcGlsZUNvbnN0YW50T2JqZWN0KGV4cHI6IENvbnN0YW50RXhwcmVzc2lvbjxvYmplY3Q+LCBpc051bGxhYmxlID0gZmFsc2UpOiBzdHJpbmcge1xuXHRpZiAoaXNOdWxsYWJsZSAmJiBPYmplY3Qua2V5cyhleHByLnZhbHVlKS5sZW5ndGggPT09IDApIHtcblx0XHRyZXR1cm4gXCJcIjtcblx0fVxuXHRjb25zdCBvYmplY3RzID0gZXhwci52YWx1ZSBhcyBQbGFpbkV4cHJlc3Npb25PYmplY3Q7XG5cdGNvbnN0IHByb3BlcnRpZXM6IHN0cmluZ1tdID0gW107XG5cdE9iamVjdC5rZXlzKG9iamVjdHMpLmZvckVhY2goKGtleSkgPT4ge1xuXHRcdGNvbnN0IHZhbHVlID0gb2JqZWN0c1trZXldO1xuXHRcdGNvbnN0IGNoaWxkUmVzdWx0ID0gY29tcGlsZUV4cHJlc3Npb24odmFsdWUsIHRydWUsIGZhbHNlLCBpc051bGxhYmxlKTtcblx0XHRpZiAoY2hpbGRSZXN1bHQgJiYgY2hpbGRSZXN1bHQubGVuZ3RoID4gMCkge1xuXHRcdFx0cHJvcGVydGllcy5wdXNoKGAke2tleX06ICR7Y2hpbGRSZXN1bHR9YCk7XG5cdFx0fVxuXHR9KTtcblx0cmV0dXJuIGB7JHtwcm9wZXJ0aWVzLmpvaW4oXCIsIFwiKX19YDtcbn1cblxuLyoqXG4gKiBDb21waWxlcyBhIENvbnN0YW50IEJpbmRpbmcgRXhwcmVzc2lvbi5cbiAqXG4gKiBAcGFyYW0gZXhwclxuICogQHBhcmFtIGVtYmVkZGVkSW5CaW5kaW5nXG4gKiBAcGFyYW0gaXNOdWxsYWJsZVxuICogQHBhcmFtIGRvTm90U3RyaW5naWZ5XG4gKiBAcmV0dXJucyBUaGUgY29tcGlsZWQgc3RyaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21waWxlQ29uc3RhbnQ8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRleHByOiBDb25zdGFudEV4cHJlc3Npb248VD4sXG5cdGVtYmVkZGVkSW5CaW5kaW5nOiBib29sZWFuLFxuXHRpc051bGxhYmxlPzogYm9vbGVhbixcblx0ZG9Ob3RTdHJpbmdpZnk/OiBmYWxzZVxuKTogQ29tcGlsZWRCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb247XG5leHBvcnQgZnVuY3Rpb24gY29tcGlsZUNvbnN0YW50PFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0ZXhwcjogQ29uc3RhbnRFeHByZXNzaW9uPFQ+LFxuXHRlbWJlZGRlZEluQmluZGluZzogYm9vbGVhbixcblx0aXNOdWxsYWJsZT86IGJvb2xlYW4sXG5cdGRvTm90U3RyaW5naWZ5PzogdHJ1ZVxuKTogUHJpbWl0aXZlVHlwZTtcbmV4cG9ydCBmdW5jdGlvbiBjb21waWxlQ29uc3RhbnQ8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRleHByOiBDb25zdGFudEV4cHJlc3Npb248VD4sXG5cdGVtYmVkZGVkSW5CaW5kaW5nOiBib29sZWFuLFxuXHRpc051bGxhYmxlID0gZmFsc2UsXG5cdGRvTm90U3RyaW5naWZ5ID0gZmFsc2Vcbik6IENvbXBpbGVkQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uIHwgUHJpbWl0aXZlVHlwZSB7XG5cdGlmIChleHByLnZhbHVlID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIGRvTm90U3RyaW5naWZ5ID8gbnVsbCA6IFwibnVsbFwiO1xuXHR9XG5cdGlmIChleHByLnZhbHVlID09PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gZG9Ob3RTdHJpbmdpZnkgPyB1bmRlZmluZWQgOiBcInVuZGVmaW5lZFwiO1xuXHR9XG5cdGlmICh0eXBlb2YgZXhwci52YWx1ZSA9PT0gXCJvYmplY3RcIikge1xuXHRcdGlmIChBcnJheS5pc0FycmF5KGV4cHIudmFsdWUpKSB7XG5cdFx0XHRjb25zdCBlbnRyaWVzID0gZXhwci52YWx1ZS5tYXAoKGV4cHJlc3Npb24pID0+IGNvbXBpbGVFeHByZXNzaW9uKGV4cHJlc3Npb24sIHRydWUpKTtcblx0XHRcdHJldHVybiBgWyR7ZW50cmllcy5qb2luKFwiLCBcIil9XWA7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBjb21waWxlQ29uc3RhbnRPYmplY3QoZXhwciBhcyBDb25zdGFudEV4cHJlc3Npb248b2JqZWN0PiwgaXNOdWxsYWJsZSk7XG5cdFx0fVxuXHR9XG5cblx0aWYgKGVtYmVkZGVkSW5CaW5kaW5nKSB7XG5cdFx0c3dpdGNoICh0eXBlb2YgZXhwci52YWx1ZSkge1xuXHRcdFx0Y2FzZSBcIm51bWJlclwiOlxuXHRcdFx0Y2FzZSBcImJpZ2ludFwiOlxuXHRcdFx0Y2FzZSBcImJvb2xlYW5cIjpcblx0XHRcdFx0cmV0dXJuIGV4cHIudmFsdWUudG9TdHJpbmcoKTtcblx0XHRcdGNhc2UgXCJzdHJpbmdcIjpcblx0XHRcdFx0cmV0dXJuIGAnJHtlc2NhcGVYbWxBdHRyaWJ1dGUoZXhwci52YWx1ZS50b1N0cmluZygpKX0nYDtcblx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdHJldHVybiBcIlwiO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gZG9Ob3RTdHJpbmdpZnkgPyBleHByLnZhbHVlIDogZXhwci52YWx1ZS50b1N0cmluZygpO1xuXHR9XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIHRoZSBiaW5kaW5nIHN0cmluZyBmb3IgYSBCaW5kaW5nIGV4cHJlc3Npb24uXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb25Gb3JCaW5kaW5nIFRoZSBleHByZXNzaW9uIHRvIGNvbXBpbGVcbiAqIEBwYXJhbSBlbWJlZGRlZEluQmluZGluZyBXaGV0aGVyIHRoZSBleHByZXNzaW9uIHRvIGNvbXBpbGUgaXMgZW1iZWRkZWQgaW50byBhbm90aGVyIGV4cHJlc3Npb25cbiAqIEBwYXJhbSBlbWJlZGRlZFNlcGFyYXRvciBUaGUgYmluZGluZyB2YWx1ZSBldmFsdWF0b3IgKCQgb3IgJSBkZXBlbmRpbmcgb24gd2hldGhlciB3ZSB3YW50IHRvIGZvcmNlIHRoZSB0eXBlIG9yIG5vdClcbiAqIEByZXR1cm5zIFRoZSBjb3JyZXNwb25kaW5nIGV4cHJlc3Npb24gYmluZGluZ1xuICovXG5mdW5jdGlvbiBjb21waWxlUGF0aEluTW9kZWxFeHByZXNzaW9uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0ZXhwcmVzc2lvbkZvckJpbmRpbmc6IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPixcblx0ZW1iZWRkZWRJbkJpbmRpbmc6IGJvb2xlYW4sXG5cdGVtYmVkZGVkU2VwYXJhdG9yOiBzdHJpbmdcbik6IENvbXBpbGVkQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uIHtcblx0aWYgKFxuXHRcdGV4cHJlc3Npb25Gb3JCaW5kaW5nLnR5cGUgfHxcblx0XHRleHByZXNzaW9uRm9yQmluZGluZy5wYXJhbWV0ZXJzIHx8XG5cdFx0ZXhwcmVzc2lvbkZvckJpbmRpbmcudGFyZ2V0VHlwZSB8fFxuXHRcdGV4cHJlc3Npb25Gb3JCaW5kaW5nLmZvcm1hdE9wdGlvbnMgfHxcblx0XHRleHByZXNzaW9uRm9yQmluZGluZy5jb25zdHJhaW50c1xuXHQpIHtcblx0XHQvLyBUaGlzIGlzIG5vdyBhIGNvbXBsZXggYmluZGluZyBkZWZpbml0aW9uLCBsZXQncyBwcmVwYXJlIGZvciBpdFxuXHRcdGNvbnN0IGNvbXBsZXhCaW5kaW5nRGVmaW5pdGlvbiA9IHtcblx0XHRcdHBhdGg6IGNvbXBpbGVQYXRoSW5Nb2RlbChleHByZXNzaW9uRm9yQmluZGluZyksXG5cdFx0XHR0eXBlOiBleHByZXNzaW9uRm9yQmluZGluZy50eXBlLFxuXHRcdFx0dGFyZ2V0VHlwZTogZXhwcmVzc2lvbkZvckJpbmRpbmcudGFyZ2V0VHlwZSxcblx0XHRcdHBhcmFtZXRlcnM6IGV4cHJlc3Npb25Gb3JCaW5kaW5nLnBhcmFtZXRlcnMsXG5cdFx0XHRmb3JtYXRPcHRpb25zOiBleHByZXNzaW9uRm9yQmluZGluZy5mb3JtYXRPcHRpb25zLFxuXHRcdFx0Y29uc3RyYWludHM6IGV4cHJlc3Npb25Gb3JCaW5kaW5nLmNvbnN0cmFpbnRzXG5cdFx0fTtcblx0XHRjb25zdCBvdXRCaW5kaW5nID0gY29tcGlsZUV4cHJlc3Npb24oY29tcGxleEJpbmRpbmdEZWZpbml0aW9uLCBmYWxzZSwgZmFsc2UsIHRydWUpO1xuXHRcdGlmIChlbWJlZGRlZEluQmluZGluZykge1xuXHRcdFx0cmV0dXJuIGAke2VtYmVkZGVkU2VwYXJhdG9yfSR7b3V0QmluZGluZ31gO1xuXHRcdH1cblx0XHRyZXR1cm4gb3V0QmluZGluZztcblx0fSBlbHNlIGlmIChlbWJlZGRlZEluQmluZGluZykge1xuXHRcdHJldHVybiBgJHtlbWJlZGRlZFNlcGFyYXRvcn17JHtjb21waWxlUGF0aEluTW9kZWwoZXhwcmVzc2lvbkZvckJpbmRpbmcpfX1gO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBgeyR7Y29tcGlsZVBhdGhJbk1vZGVsKGV4cHJlc3Npb25Gb3JCaW5kaW5nKX19YDtcblx0fVxufVxuXG5mdW5jdGlvbiBjb21waWxlQ29tcGxleFR5cGVFeHByZXNzaW9uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihleHByZXNzaW9uOiBDb21wbGV4VHlwZUV4cHJlc3Npb248VD4pOiBzdHJpbmcge1xuXHRpZiAoZXhwcmVzc2lvbi5iaW5kaW5nUGFyYW1ldGVycy5sZW5ndGggPT09IDEpIHtcblx0XHRyZXR1cm4gYHske2NvbXBpbGVQYXRoUGFyYW1ldGVyKGV4cHJlc3Npb24uYmluZGluZ1BhcmFtZXRlcnNbMF0gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+LCB0cnVlKX0sIHR5cGU6ICcke1xuXHRcdFx0ZXhwcmVzc2lvbi50eXBlXG5cdFx0fSd9YDtcblx0fVxuXG5cdGxldCBvdXRwdXRFbmQgPSBgXSwgdHlwZTogJyR7ZXhwcmVzc2lvbi50eXBlfSdgO1xuXHRpZiAoaGFzRWxlbWVudHMoZXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zKSkge1xuXHRcdG91dHB1dEVuZCArPSBgLCBmb3JtYXRPcHRpb25zOiAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHJlc3Npb24uZm9ybWF0T3B0aW9ucyl9YDtcblx0fVxuXHRpZiAoaGFzRWxlbWVudHMoZXhwcmVzc2lvbi5wYXJhbWV0ZXJzKSkge1xuXHRcdG91dHB1dEVuZCArPSBgLCBwYXJhbWV0ZXJzOiAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHJlc3Npb24ucGFyYW1ldGVycyl9YDtcblx0fVxuXHRvdXRwdXRFbmQgKz0gXCJ9XCI7XG5cblx0cmV0dXJuIGB7bW9kZTonVHdvV2F5JywgcGFydHM6WyR7ZXhwcmVzc2lvbi5iaW5kaW5nUGFyYW1ldGVyc1xuXHRcdC5tYXAoKHBhcmFtKSA9PiBjb21waWxlUGF0aFBhcmFtZXRlcihwYXJhbSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4pKVxuXHRcdC5qb2luKFwiLFwiKX0ke291dHB1dEVuZH1gO1xufVxuXG4vKipcbiAqIFdyYXAgdGhlIGNvbXBpbGVkIGJpbmRpbmcgc3RyaW5nIGFzIHJlcXVpcmVkIGRlcGVuZGluZyBvbiBpdHMgY29udGV4dC5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgY29tcGlsZWQgZXhwcmVzc2lvblxuICogQHBhcmFtIGVtYmVkZGVkSW5CaW5kaW5nIFRydWUgaWYgdGhlIGNvbXBpbGVkIGV4cHJlc3Npb24gaXMgdG8gYmUgZW1iZWRkZWQgaW4gYSBiaW5kaW5nXG4gKiBAcGFyYW0gcGFyZW50aGVzaXNSZXF1aXJlZCBUcnVlIGlmIHRoZSBlbWJlZGRlZCBiaW5kaW5nIG5lZWRzIHRvIGJlIHdyYXBwZWQgaW4gcGFyZXRoZXNpcyBzbyB0aGF0IGl0IGlzIGV2YWx1YXRlZCBhcyBvbmVcbiAqIEByZXR1cm5zIEZpbmFsaXplZCBjb21waWxlZCBleHByZXNzaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cmFwQmluZGluZ0V4cHJlc3Npb24oXG5cdGV4cHJlc3Npb246IHN0cmluZyxcblx0ZW1iZWRkZWRJbkJpbmRpbmc6IGJvb2xlYW4sXG5cdHBhcmVudGhlc2lzUmVxdWlyZWQgPSBmYWxzZVxuKTogQ29tcGlsZWRCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb24ge1xuXHRpZiAoZW1iZWRkZWRJbkJpbmRpbmcpIHtcblx0XHRpZiAocGFyZW50aGVzaXNSZXF1aXJlZCkge1xuXHRcdFx0cmV0dXJuIGAoJHtleHByZXNzaW9ufSlgO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gZXhwcmVzc2lvbjtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGB7PSAke2V4cHJlc3Npb259fWA7XG5cdH1cbn1cblxuLyoqXG4gKiBDb21waWxlIGFuIGV4cHJlc3Npb24gaW50byBhbiBleHByZXNzaW9uIGJpbmRpbmcuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgZXhwcmVzc2lvbiB0byBjb21waWxlXG4gKiBAcGFyYW0gZW1iZWRkZWRJbkJpbmRpbmcgV2hldGhlciB0aGUgZXhwcmVzc2lvbiB0byBjb21waWxlIGlzIGVtYmVkZGVkIGludG8gYW5vdGhlciBleHByZXNzaW9uXG4gKiBAcGFyYW0ga2VlcFRhcmdldFR5cGUgS2VlcCB0aGUgdGFyZ2V0IHR5cGUgb2YgdGhlIGVtYmVkZGVkIGJpbmRpbmdzIGluc3RlYWQgb2YgY2FzdGluZyB0aGVtIHRvIGFueVxuICogQHBhcmFtIGlzTnVsbGFibGUgV2hldGhlciBiaW5kaW5nIGV4cHJlc3Npb24gY2FuIHJlc29sdmUgdG8gZW1wdHkgc3RyaW5nIG9yIG5vdFxuICogQHJldHVybnMgVGhlIGNvcnJlc3BvbmRpbmcgZXhwcmVzc2lvbiBiaW5kaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21waWxlRXhwcmVzc2lvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGV4cHJlc3Npb246IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0ZW1iZWRkZWRJbkJpbmRpbmcgPSBmYWxzZSxcblx0a2VlcFRhcmdldFR5cGUgPSBmYWxzZSxcblx0aXNOdWxsYWJsZSA9IGZhbHNlXG4pOiBDb21waWxlZEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbiB7XG5cdGNvbnN0IGV4cHIgPSB3cmFwUHJpbWl0aXZlKGV4cHJlc3Npb24pO1xuXHRjb25zdCBlbWJlZGRlZFNlcGFyYXRvciA9IGtlZXBUYXJnZXRUeXBlID8gXCIkXCIgOiBcIiVcIjtcblxuXHRzd2l0Y2ggKGV4cHIuX3R5cGUpIHtcblx0XHRjYXNlIFwiVW5yZXNvbHZhYmxlXCI6XG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXG5cdFx0Y2FzZSBcIkNvbnN0YW50XCI6XG5cdFx0XHRyZXR1cm4gY29tcGlsZUNvbnN0YW50KGV4cHIsIGVtYmVkZGVkSW5CaW5kaW5nLCBpc051bGxhYmxlKTtcblxuXHRcdGNhc2UgXCJSZWZcIjpcblx0XHRcdHJldHVybiBleHByLnJlZiB8fCBcIm51bGxcIjtcblxuXHRcdGNhc2UgXCJGdW5jdGlvblwiOlxuXHRcdFx0bGV0IGhhc0VtYmVkZGVkRnVuY3Rpb25DYWxsT3JCaW5kaW5nID0gZmFsc2U7XG5cdFx0XHRpZiAoZXhwci5pc0Zvcm1hdHRpbmdGbikge1xuXHRcdFx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0XHRleHByLFxuXHRcdFx0XHRcdFwiRnVuY3Rpb25cIixcblx0XHRcdFx0XHQoc3ViRm4pID0+IHtcblx0XHRcdFx0XHRcdGlmIChzdWJGbiAhPT0gZXhwciAmJiBzdWJGbi5vYmogPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdFx0XHRoYXNFbWJlZGRlZEZ1bmN0aW9uQ2FsbE9yQmluZGluZyA9IHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRyZXR1cm4gc3ViRm47XG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHR0cnVlXG5cdFx0XHRcdCk7XG5cdFx0XHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdGV4cHIsXG5cdFx0XHRcdFx0XCJDb25zdGFudFwiLFxuXHRcdFx0XHRcdChzdWJGbjogQ29uc3RhbnRFeHByZXNzaW9uPFQ+KSA9PiB7XG5cdFx0XHRcdFx0XHRpZiAoKHN1YkZuIGFzIHVua25vd24pICE9PSBleHByICYmIHR5cGVvZiBzdWJGbi52YWx1ZSA9PT0gXCJvYmplY3RcIikge1xuXHRcdFx0XHRcdFx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShzdWJGbiwgXCJQYXRoSW5Nb2RlbFwiLCAoc3ViU3ViRm4pID0+IHtcblx0XHRcdFx0XHRcdFx0XHRoYXNFbWJlZGRlZEZ1bmN0aW9uQ2FsbE9yQmluZGluZyA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHN1YlN1YkZuO1xuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0cmV0dXJuIHN1YkZuO1xuXHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0dHJ1ZVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgYXJndW1lbnRTdHJpbmcgPSBgJHtleHByLnBhcmFtZXRlcnMubWFwKChhcmcpID0+IGNvbXBpbGVFeHByZXNzaW9uKGFyZywgdHJ1ZSkpLmpvaW4oXCIsIFwiKX1gO1xuXHRcdFx0bGV0IGZuQ2FsbCA9XG5cdFx0XHRcdGV4cHIub2JqID09PSB1bmRlZmluZWRcblx0XHRcdFx0XHQ/IGAke2V4cHIuZm59KCR7YXJndW1lbnRTdHJpbmd9KWBcblx0XHRcdFx0XHQ6IGAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHIub2JqLCB0cnVlKX0uJHtleHByLmZufSgke2FyZ3VtZW50U3RyaW5nfSlgO1xuXHRcdFx0aWYgKCFlbWJlZGRlZEluQmluZGluZyAmJiBoYXNFbWJlZGRlZEZ1bmN0aW9uQ2FsbE9yQmluZGluZykge1xuXHRcdFx0XHRmbkNhbGwgPSBgez0gJHtmbkNhbGx9fWA7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZm5DYWxsO1xuXG5cdFx0Y2FzZSBcIkVtYmVkZGVkRXhwcmVzc2lvbkJpbmRpbmdcIjpcblx0XHRcdHJldHVybiBlbWJlZGRlZEluQmluZGluZyA/IGAoJHtleHByLnZhbHVlLnN1YnN0cmluZygyLCBleHByLnZhbHVlLmxlbmd0aCAtIDEpfSlgIDogYCR7ZXhwci52YWx1ZX1gO1xuXG5cdFx0Y2FzZSBcIkVtYmVkZGVkQmluZGluZ1wiOlxuXHRcdFx0cmV0dXJuIGVtYmVkZGVkSW5CaW5kaW5nID8gYCR7ZW1iZWRkZWRTZXBhcmF0b3J9JHtleHByLnZhbHVlfWAgOiBgJHtleHByLnZhbHVlfWA7XG5cblx0XHRjYXNlIFwiUGF0aEluTW9kZWxcIjpcblx0XHRcdHJldHVybiBjb21waWxlUGF0aEluTW9kZWxFeHByZXNzaW9uKGV4cHIsIGVtYmVkZGVkSW5CaW5kaW5nLCBlbWJlZGRlZFNlcGFyYXRvcik7XG5cblx0XHRjYXNlIFwiQ29tcGFyaXNvblwiOlxuXHRcdFx0Y29uc3QgY29tcGFyaXNvbkV4cHJlc3Npb24gPSBjb21waWxlQ29tcGFyaXNvbkV4cHJlc3Npb24oZXhwcik7XG5cdFx0XHRyZXR1cm4gd3JhcEJpbmRpbmdFeHByZXNzaW9uKGNvbXBhcmlzb25FeHByZXNzaW9uLCBlbWJlZGRlZEluQmluZGluZyk7XG5cblx0XHRjYXNlIFwiSWZFbHNlXCI6XG5cdFx0XHRjb25zdCBpZkVsc2VFeHByZXNzaW9uID0gYCR7Y29tcGlsZUV4cHJlc3Npb24oZXhwci5jb25kaXRpb24sIHRydWUpfSA/ICR7Y29tcGlsZUV4cHJlc3Npb24oXG5cdFx0XHRcdGV4cHIub25UcnVlLFxuXHRcdFx0XHR0cnVlLFxuXHRcdFx0XHRrZWVwVGFyZ2V0VHlwZVxuXHRcdFx0KX0gOiAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHIub25GYWxzZSwgdHJ1ZSwga2VlcFRhcmdldFR5cGUpfWA7XG5cdFx0XHRyZXR1cm4gd3JhcEJpbmRpbmdFeHByZXNzaW9uKGlmRWxzZUV4cHJlc3Npb24sIGVtYmVkZGVkSW5CaW5kaW5nLCB0cnVlKTtcblxuXHRcdGNhc2UgXCJTZXRcIjpcblx0XHRcdGNvbnN0IHNldEV4cHJlc3Npb24gPSBleHByLm9wZXJhbmRzLm1hcCgob3BlcmFuZCkgPT4gY29tcGlsZUV4cHJlc3Npb24ob3BlcmFuZCwgdHJ1ZSkpLmpvaW4oYCAke2V4cHIub3BlcmF0b3J9IGApO1xuXHRcdFx0cmV0dXJuIHdyYXBCaW5kaW5nRXhwcmVzc2lvbihzZXRFeHByZXNzaW9uLCBlbWJlZGRlZEluQmluZGluZywgdHJ1ZSk7XG5cblx0XHRjYXNlIFwiQ29uY2F0XCI6XG5cdFx0XHRjb25zdCBjb25jYXRFeHByZXNzaW9uID0gZXhwci5leHByZXNzaW9uc1xuXHRcdFx0XHQubWFwKChuZXN0ZWRFeHByZXNzaW9uKSA9PiBjb21waWxlRXhwcmVzc2lvbihuZXN0ZWRFeHByZXNzaW9uLCB0cnVlLCB0cnVlKSlcblx0XHRcdFx0LmpvaW4oXCIgKyBcIik7XG5cdFx0XHRyZXR1cm4gd3JhcEJpbmRpbmdFeHByZXNzaW9uKGNvbmNhdEV4cHJlc3Npb24sIGVtYmVkZGVkSW5CaW5kaW5nKTtcblxuXHRcdGNhc2UgXCJMZW5ndGhcIjpcblx0XHRcdGNvbnN0IGxlbmd0aEV4cHJlc3Npb24gPSBgJHtjb21waWxlRXhwcmVzc2lvbihleHByLnBhdGhJbk1vZGVsLCB0cnVlKX0ubGVuZ3RoYDtcblx0XHRcdHJldHVybiB3cmFwQmluZGluZ0V4cHJlc3Npb24obGVuZ3RoRXhwcmVzc2lvbiwgZW1iZWRkZWRJbkJpbmRpbmcpO1xuXG5cdFx0Y2FzZSBcIk5vdFwiOlxuXHRcdFx0Y29uc3Qgbm90RXhwcmVzc2lvbiA9IGAhJHtjb21waWxlRXhwcmVzc2lvbihleHByLm9wZXJhbmQsIHRydWUpfWA7XG5cdFx0XHRyZXR1cm4gd3JhcEJpbmRpbmdFeHByZXNzaW9uKG5vdEV4cHJlc3Npb24sIGVtYmVkZGVkSW5CaW5kaW5nKTtcblxuXHRcdGNhc2UgXCJUcnV0aHlcIjpcblx0XHRcdGNvbnN0IHRydXRoeUV4cHJlc3Npb24gPSBgISEke2NvbXBpbGVFeHByZXNzaW9uKGV4cHIub3BlcmFuZCwgdHJ1ZSl9YDtcblx0XHRcdHJldHVybiB3cmFwQmluZGluZ0V4cHJlc3Npb24odHJ1dGh5RXhwcmVzc2lvbiwgZW1iZWRkZWRJbkJpbmRpbmcpO1xuXG5cdFx0Y2FzZSBcIkZvcm1hdHRlclwiOlxuXHRcdFx0Y29uc3QgZm9ybWF0dGVyRXhwcmVzc2lvbiA9IGNvbXBpbGVGb3JtYXR0ZXJFeHByZXNzaW9uKGV4cHIpO1xuXHRcdFx0cmV0dXJuIGVtYmVkZGVkSW5CaW5kaW5nID8gYCQke2Zvcm1hdHRlckV4cHJlc3Npb259YCA6IGZvcm1hdHRlckV4cHJlc3Npb247XG5cblx0XHRjYXNlIFwiQ29tcGxleFR5cGVcIjpcblx0XHRcdGNvbnN0IGNvbXBsZXhUeXBlRXhwcmVzc2lvbiA9IGNvbXBpbGVDb21wbGV4VHlwZUV4cHJlc3Npb24oZXhwcik7XG5cdFx0XHRyZXR1cm4gZW1iZWRkZWRJbkJpbmRpbmcgPyBgJCR7Y29tcGxleFR5cGVFeHByZXNzaW9ufWAgOiBjb21wbGV4VHlwZUV4cHJlc3Npb247XG5cblx0XHRkZWZhdWx0OlxuXHRcdFx0cmV0dXJuIFwiXCI7XG5cdH1cbn1cblxuLyoqXG4gKiBDb21waWxlIGEgY29tcGFyaXNvbiBleHByZXNzaW9uLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBjb21wYXJpc29uIGV4cHJlc3Npb24uXG4gKiBAcmV0dXJucyBUaGUgY29tcGlsZWQgZXhwcmVzc2lvbi4gTmVlZHMgd3JhcHBpbmcgYmVmb3JlIGl0IGNhbiBiZSB1c2VkIGFzIGFuIGV4cHJlc3Npb24gYmluZGluZy5cbiAqL1xuZnVuY3Rpb24gY29tcGlsZUNvbXBhcmlzb25FeHByZXNzaW9uKGV4cHJlc3Npb246IENvbXBhcmlzb25FeHByZXNzaW9uKTogc3RyaW5nIHtcblx0ZnVuY3Rpb24gY29tcGlsZU9wZXJhbmQob3BlcmFuZDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+KTogQ29tcGlsZWRCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb24ge1xuXHRcdGNvbnN0IGNvbXBpbGVkT3BlcmFuZCA9IGNvbXBpbGVFeHByZXNzaW9uKG9wZXJhbmQsIHRydWUpID8/IFwidW5kZWZpbmVkXCI7XG5cdFx0cmV0dXJuIHdyYXBCaW5kaW5nRXhwcmVzc2lvbihjb21waWxlZE9wZXJhbmQsIHRydWUsIG5lZWRQYXJlbnRoZXNpcyhvcGVyYW5kKSk7XG5cdH1cblxuXHRyZXR1cm4gYCR7Y29tcGlsZU9wZXJhbmQoZXhwcmVzc2lvbi5vcGVyYW5kMSl9ICR7ZXhwcmVzc2lvbi5vcGVyYXRvcn0gJHtjb21waWxlT3BlcmFuZChleHByZXNzaW9uLm9wZXJhbmQyKX1gO1xufVxuXG4vKipcbiAqIENvbXBpbGUgYSBmb3JtYXR0ZXIgZXhwcmVzc2lvbi5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgZm9ybWF0dGVyIGV4cHJlc3Npb24uXG4gKiBAcmV0dXJucyBUaGUgY29tcGlsZWQgZXhwcmVzc2lvbi5cbiAqL1xuZnVuY3Rpb24gY29tcGlsZUZvcm1hdHRlckV4cHJlc3Npb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KGV4cHJlc3Npb246IEZvcm1hdHRlckV4cHJlc3Npb248VD4pOiBzdHJpbmcge1xuXHRpZiAoZXhwcmVzc2lvbi5wYXJhbWV0ZXJzLmxlbmd0aCA9PT0gMSkge1xuXHRcdHJldHVybiBgeyR7Y29tcGlsZVBhdGhQYXJhbWV0ZXIoZXhwcmVzc2lvbi5wYXJhbWV0ZXJzWzBdIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPiwgdHJ1ZSl9LCBmb3JtYXR0ZXI6ICcke1xuXHRcdFx0ZXhwcmVzc2lvbi5mblxuXHRcdH0nfWA7XG5cdH0gZWxzZSB7XG5cdFx0Y29uc3QgcGFydHMgPSBleHByZXNzaW9uLnBhcmFtZXRlcnMubWFwKChwYXJhbSkgPT4ge1xuXHRcdFx0aWYgKHBhcmFtLl90eXBlID09PSBcIkNvbXBsZXhUeXBlXCIpIHtcblx0XHRcdFx0cmV0dXJuIGNvbXBpbGVDb21wbGV4VHlwZUV4cHJlc3Npb24ocGFyYW0pO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuIGNvbXBpbGVQYXRoUGFyYW1ldGVyKHBhcmFtIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPik7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0cmV0dXJuIGB7cGFydHM6IFske3BhcnRzLmpvaW4oXCIsIFwiKX1dLCBmb3JtYXR0ZXI6ICcke2V4cHJlc3Npb24uZm59J31gO1xuXHR9XG59XG5cbi8qKlxuICogQ29tcGlsZSB0aGUgcGF0aCBwYXJhbWV0ZXIgb2YgYSBmb3JtYXR0ZXIgY2FsbC5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgYmluZGluZyBwYXJ0IHRvIGV2YWx1YXRlXG4gKiBAcGFyYW0gc2luZ2xlUGF0aCBXaGV0aGVyIHRoZXJlIGlzIG9uZSBvciBtdWx0aXBsZSBwYXRoIHRvIGNvbnNpZGVyXG4gKiBAcmV0dXJucyBUaGUgc3RyaW5nIHNuaXBwZXQgdG8gaW5jbHVkZSBpbiB0aGUgb3ZlcmFsbCBiaW5kaW5nIGRlZmluaXRpb25cbiAqL1xuZnVuY3Rpb24gY29tcGlsZVBhdGhQYXJhbWV0ZXIoZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+LCBzaW5nbGVQYXRoID0gZmFsc2UpOiBzdHJpbmcge1xuXHRsZXQgb3V0VmFsdWUgPSBcIlwiO1xuXHRpZiAoZXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJDb25zdGFudFwiKSB7XG5cdFx0aWYgKGV4cHJlc3Npb24udmFsdWUgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0Ly8gU3BlY2lhbCBjYXNlIG90aGVyd2lzZSB0aGUgSlNUb2tlbml6ZXIgY29tcGxhaW5zIGFib3V0IGluY29ycmVjdCBjb250ZW50XG5cdFx0XHRvdXRWYWx1ZSA9IGB2YWx1ZTogJ3VuZGVmaW5lZCdgO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRvdXRWYWx1ZSA9IGB2YWx1ZTogJHtjb21waWxlQ29uc3RhbnQoZXhwcmVzc2lvbiwgdHJ1ZSl9YDtcblx0XHR9XG5cdH0gZWxzZSBpZiAoZXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJQYXRoSW5Nb2RlbFwiKSB7XG5cdFx0b3V0VmFsdWUgPSBgcGF0aDogJyR7Y29tcGlsZVBhdGhJbk1vZGVsKGV4cHJlc3Npb24pfSdgO1xuXG5cdFx0b3V0VmFsdWUgKz0gZXhwcmVzc2lvbi50eXBlID8gYCwgdHlwZTogJyR7ZXhwcmVzc2lvbi50eXBlfSdgIDogYCwgdGFyZ2V0VHlwZTogJ2FueSdgO1xuXHRcdGlmIChleHByZXNzaW9uLm1vZGUpIHtcblx0XHRcdG91dFZhbHVlICs9IGAsIG1vZGU6ICcke2NvbXBpbGVFeHByZXNzaW9uKGV4cHJlc3Npb24ubW9kZSl9J2A7XG5cdFx0fVxuXHRcdGlmIChoYXNFbGVtZW50cyhleHByZXNzaW9uLmNvbnN0cmFpbnRzKSkge1xuXHRcdFx0b3V0VmFsdWUgKz0gYCwgY29uc3RyYWludHM6ICR7Y29tcGlsZUV4cHJlc3Npb24oZXhwcmVzc2lvbi5jb25zdHJhaW50cyl9YDtcblx0XHR9XG5cdFx0aWYgKGhhc0VsZW1lbnRzKGV4cHJlc3Npb24uZm9ybWF0T3B0aW9ucykpIHtcblx0XHRcdG91dFZhbHVlICs9IGAsIGZvcm1hdE9wdGlvbnM6ICR7Y29tcGlsZUV4cHJlc3Npb24oZXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zKX1gO1xuXHRcdH1cblx0XHRpZiAoaGFzRWxlbWVudHMoZXhwcmVzc2lvbi5wYXJhbWV0ZXJzKSkge1xuXHRcdFx0b3V0VmFsdWUgKz0gYCwgcGFyYW1ldGVyczogJHtjb21waWxlRXhwcmVzc2lvbihleHByZXNzaW9uLnBhcmFtZXRlcnMpfWA7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBcIlwiO1xuXHR9XG5cdHJldHVybiBzaW5nbGVQYXRoID8gb3V0VmFsdWUgOiBgeyR7b3V0VmFsdWV9fWA7XG59XG5cbmZ1bmN0aW9uIGhhc0VsZW1lbnRzKG9iajogb2JqZWN0IHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG5cdHJldHVybiAhIW9iaiAmJiBPYmplY3Qua2V5cyhvYmopLmxlbmd0aCA+IDA7XG59XG5cbi8qKlxuICogQ29tcGlsZSBhIGJpbmRpbmcgZXhwcmVzc2lvbiBwYXRoLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBleHByZXNzaW9uIHRvIGNvbXBpbGUuXG4gKiBAcmV0dXJucyBUaGUgY29tcGlsZWQgcGF0aC5cbiAqL1xuZnVuY3Rpb24gY29tcGlsZVBhdGhJbk1vZGVsPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihleHByZXNzaW9uOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4pOiBzdHJpbmcge1xuXHRyZXR1cm4gYCR7ZXhwcmVzc2lvbi5tb2RlbE5hbWUgPyBleHByZXNzaW9uLm1vZGVsTmFtZSArIFwiPlwiIDogXCJcIn0ke2V4cHJlc3Npb24ucGF0aH1gO1xufVxuIl0sIm1hcHBpbmdzIjoiO0FBQUE7QUFBQTtBQUFBOzs7Ozs7RUF5S08sU0FBU0EsVUFBVSxDQUFDQyxhQUFzQixFQUE2QjtJQUM3RSxPQUFPLENBQUNBLGFBQWEsYUFBYkEsYUFBYSx1QkFBYkEsYUFBYSxDQUFlQyxLQUFLLE1BQUssVUFBVTtFQUN6RDs7RUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBSkE7RUFzQ08sTUFBTUMsZ0JBQXVELEdBQUc7SUFDdEUsYUFBYSxFQUFFO01BQUVDLElBQUksRUFBRTtJQUFrQyxDQUFDO0lBQzFELFVBQVUsRUFBRTtNQUFFQSxJQUFJLEVBQUU7SUFBK0IsQ0FBQztJQUNwRCxVQUFVLEVBQUU7TUFBRUEsSUFBSSxFQUFFO0lBQStCLENBQUM7SUFDcEQsb0JBQW9CLEVBQUU7TUFDckJDLFdBQVcsRUFBRTtRQUNaQyxVQUFVLEVBQUUsV0FBVztRQUN2QkMsR0FBRyxFQUFFO01BQ04sQ0FBQztNQUNESCxJQUFJLEVBQUU7SUFDUCxDQUFDO0lBQ0QsYUFBYSxFQUFFO01BQ2RDLFdBQVcsRUFBRTtRQUNaLDJDQUEyQyxFQUFFLFNBQVM7UUFDdEQsb0VBQW9FLEVBQUUsa0JBQWtCO1FBQ3hGLDJDQUEyQyxFQUFFLFNBQVM7UUFDdEQsb0VBQW9FLEVBQUUsa0JBQWtCO1FBQ3hGQyxVQUFVLEVBQUUsV0FBVztRQUN2QkUsTUFBTSxFQUFFO01BQ1QsQ0FBQztNQUNESixJQUFJLEVBQUU7SUFDUCxDQUFDO0lBQ0QsWUFBWSxFQUFFO01BQUVBLElBQUksRUFBRTtJQUFpQyxDQUFDO0lBQ3hELFVBQVUsRUFBRTtNQUFFQSxJQUFJLEVBQUU7SUFBK0IsQ0FBQztJQUNwRCxXQUFXLEVBQUU7TUFBRUEsSUFBSSxFQUFFO0lBQWdDLENBQUM7SUFDdEQsV0FBVyxFQUFFO01BQUVBLElBQUksRUFBRTtJQUFnQyxDQUFDO0lBQ3RELFdBQVcsRUFBRTtNQUFFQSxJQUFJLEVBQUU7SUFBZ0MsQ0FBQztJQUN0RCxXQUFXLEVBQUU7TUFBRUEsSUFBSSxFQUFFO0lBQWdDLENBQUM7SUFDdEQsWUFBWSxFQUFFO01BQUVBLElBQUksRUFBRTtJQUFpQyxDQUFDO0lBQ3hELFlBQVksRUFBRTtNQUFFQSxJQUFJLEVBQUU7SUFBaUMsQ0FBQztJQUN4RCxZQUFZLEVBQUU7TUFBRUEsSUFBSSxFQUFFO0lBQWlDLENBQUM7SUFDeEQsWUFBWSxFQUFFO01BQ2JDLFdBQVcsRUFBRTtRQUNaLGlEQUFpRCxFQUFFLGlCQUFpQjtRQUNwRUksVUFBVSxFQUFFLFdBQVc7UUFDdkJDLFNBQVMsRUFBRTtNQUNaLENBQUM7TUFDRE4sSUFBSSxFQUFFO0lBQ1AsQ0FBQztJQUNELGVBQWUsRUFBRTtNQUNoQkMsV0FBVyxFQUFFO1FBQ1pDLFVBQVUsRUFBRTtNQUNiLENBQUM7TUFDREYsSUFBSSxFQUFFO0lBQ1A7RUFDRCxDQUFDOztFQUVEO0FBQ0E7QUFDQTtFQUZBO0VBS08sTUFBTU8sc0JBQWtELEdBQUc7SUFDakVULEtBQUssRUFBRTtFQUNSLENBQUM7RUFBQztFQUVLLFNBQVNVLGtCQUFrQixDQUFDQyxXQUFtQixFQUFVO0lBQy9ELE9BQU9BLFdBQVcsQ0FBQ0MsT0FBTyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUM7RUFDeEM7RUFBQztFQUVNLFNBQVNDLHlCQUF5QixHQUErRDtJQUFBLGtDQUEzREMsV0FBVztNQUFYQSxXQUFXO0lBQUE7SUFDdkQsT0FBT0EsV0FBVyxDQUFDQyxJQUFJLENBQUVDLElBQUksSUFBS0EsSUFBSSxDQUFDaEIsS0FBSyxLQUFLLGNBQWMsQ0FBQyxLQUFLaUIsU0FBUztFQUMvRTtFQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBTkE7RUFPTyxTQUFTQyx5QkFBeUIsQ0FBSUMsQ0FBOEIsRUFBRUMsQ0FBOEIsRUFBVztJQUNySCxJQUFJRCxDQUFDLENBQUNuQixLQUFLLEtBQUtvQixDQUFDLENBQUNwQixLQUFLLEVBQUU7TUFDeEIsT0FBTyxLQUFLO0lBQ2I7SUFFQSxRQUFRbUIsQ0FBQyxDQUFDbkIsS0FBSztNQUNkLEtBQUssY0FBYztRQUNsQixPQUFPLEtBQUs7TUFBRTtNQUNmLEtBQUssVUFBVTtNQUNmLEtBQUssaUJBQWlCO01BQ3RCLEtBQUssMkJBQTJCO1FBQy9CLE9BQU9tQixDQUFDLENBQUNFLEtBQUssS0FBTUQsQ0FBQyxDQUEyQkMsS0FBSztNQUV0RCxLQUFLLEtBQUs7UUFDVCxPQUFPSCx5QkFBeUIsQ0FBQ0MsQ0FBQyxDQUFDRyxPQUFPLEVBQUdGLENBQUMsQ0FBbUJFLE9BQU8sQ0FBQztNQUMxRSxLQUFLLFFBQVE7UUFDWixPQUFPSix5QkFBeUIsQ0FBQ0MsQ0FBQyxDQUFDRyxPQUFPLEVBQUdGLENBQUMsQ0FBc0JFLE9BQU8sQ0FBQztNQUM3RSxLQUFLLEtBQUs7UUFDVCxPQUNDSCxDQUFDLENBQUNJLFFBQVEsS0FBTUgsQ0FBQyxDQUFtQkcsUUFBUSxJQUM1Q0osQ0FBQyxDQUFDSyxRQUFRLENBQUNDLE1BQU0sS0FBTUwsQ0FBQyxDQUFtQkksUUFBUSxDQUFDQyxNQUFNLElBQzFETixDQUFDLENBQUNLLFFBQVEsQ0FBQ0UsS0FBSyxDQUFFQyxVQUFVLElBQzFCUCxDQUFDLENBQW1CSSxRQUFRLENBQUNJLElBQUksQ0FBRUMsZUFBZSxJQUFLWCx5QkFBeUIsQ0FBQ1MsVUFBVSxFQUFFRSxlQUFlLENBQUMsQ0FBQyxDQUMvRztNQUdILEtBQUssUUFBUTtRQUNaLE9BQ0NYLHlCQUF5QixDQUFDQyxDQUFDLENBQUNXLFNBQVMsRUFBR1YsQ0FBQyxDQUF5QlUsU0FBUyxDQUFDLElBQzVFWix5QkFBeUIsQ0FBQ0MsQ0FBQyxDQUFDWSxNQUFNLEVBQUdYLENBQUMsQ0FBeUJXLE1BQU0sQ0FBQyxJQUN0RWIseUJBQXlCLENBQUNDLENBQUMsQ0FBQ2EsT0FBTyxFQUFHWixDQUFDLENBQXlCWSxPQUFPLENBQUM7TUFHMUUsS0FBSyxZQUFZO1FBQ2hCLE9BQ0NiLENBQUMsQ0FBQ0ksUUFBUSxLQUFNSCxDQUFDLENBQTBCRyxRQUFRLElBQ25ETCx5QkFBeUIsQ0FBQ0MsQ0FBQyxDQUFDYyxRQUFRLEVBQUdiLENBQUMsQ0FBMEJhLFFBQVEsQ0FBQyxJQUMzRWYseUJBQXlCLENBQUNDLENBQUMsQ0FBQ2UsUUFBUSxFQUFHZCxDQUFDLENBQTBCYyxRQUFRLENBQUM7TUFHN0UsS0FBSyxRQUFRO1FBQ1osTUFBTUMsWUFBWSxHQUFHaEIsQ0FBQyxDQUFDTCxXQUFXO1FBQ2xDLE1BQU1zQixZQUFZLEdBQUloQixDQUFDLENBQXNCTixXQUFXO1FBQ3hELElBQUlxQixZQUFZLENBQUNWLE1BQU0sS0FBS1csWUFBWSxDQUFDWCxNQUFNLEVBQUU7VUFDaEQsT0FBTyxLQUFLO1FBQ2I7UUFDQSxPQUFPVSxZQUFZLENBQUNULEtBQUssQ0FBQyxDQUFDQyxVQUFVLEVBQUVVLEtBQUssS0FBSztVQUNoRCxPQUFPbkIseUJBQXlCLENBQUNTLFVBQVUsRUFBRVMsWUFBWSxDQUFDQyxLQUFLLENBQUMsQ0FBQztRQUNsRSxDQUFDLENBQUM7TUFFSCxLQUFLLFFBQVE7UUFDWixPQUFPbkIseUJBQXlCLENBQUNDLENBQUMsQ0FBQ21CLFdBQVcsRUFBR2xCLENBQUMsQ0FBc0JrQixXQUFXLENBQUM7TUFFckYsS0FBSyxhQUFhO1FBQ2pCLE9BQ0NuQixDQUFDLENBQUNvQixTQUFTLEtBQU1uQixDQUFDLENBQThCbUIsU0FBUyxJQUN6RHBCLENBQUMsQ0FBQ3FCLElBQUksS0FBTXBCLENBQUMsQ0FBOEJvQixJQUFJLElBQy9DckIsQ0FBQyxDQUFDc0IsZUFBZSxLQUFNckIsQ0FBQyxDQUE4QnFCLGVBQWU7TUFHdkUsS0FBSyxXQUFXO1FBQ2YsT0FDQ3RCLENBQUMsQ0FBQ3VCLEVBQUUsS0FBTXRCLENBQUMsQ0FBNEJzQixFQUFFLElBQ3pDdkIsQ0FBQyxDQUFDd0IsVUFBVSxDQUFDbEIsTUFBTSxLQUFNTCxDQUFDLENBQTRCdUIsVUFBVSxDQUFDbEIsTUFBTSxJQUN2RU4sQ0FBQyxDQUFDd0IsVUFBVSxDQUFDakIsS0FBSyxDQUFDLENBQUNMLEtBQUssRUFBRWdCLEtBQUssS0FBS25CLHlCQUF5QixDQUFFRSxDQUFDLENBQTRCdUIsVUFBVSxDQUFDTixLQUFLLENBQUMsRUFBRWhCLEtBQUssQ0FBQyxDQUFDO01BRXpILEtBQUssYUFBYTtRQUNqQixPQUNDRixDQUFDLENBQUNqQixJQUFJLEtBQU1rQixDQUFDLENBQThCbEIsSUFBSSxJQUMvQ2lCLENBQUMsQ0FBQ3lCLGlCQUFpQixDQUFDbkIsTUFBTSxLQUFNTCxDQUFDLENBQThCd0IsaUJBQWlCLENBQUNuQixNQUFNLElBQ3ZGTixDQUFDLENBQUN5QixpQkFBaUIsQ0FBQ2xCLEtBQUssQ0FBQyxDQUFDTCxLQUFLLEVBQUVnQixLQUFLLEtBQ3RDbkIseUJBQXlCLENBQUVFLENBQUMsQ0FBOEJ3QixpQkFBaUIsQ0FBQ1AsS0FBSyxDQUFDLEVBQUVoQixLQUFLLENBQUMsQ0FDMUY7TUFFSCxLQUFLLFVBQVU7UUFDZCxNQUFNd0IsYUFBYSxHQUFHekIsQ0FBMEI7UUFDaEQsSUFBSUQsQ0FBQyxDQUFDMkIsR0FBRyxLQUFLN0IsU0FBUyxJQUFJNEIsYUFBYSxDQUFDQyxHQUFHLEtBQUs3QixTQUFTLEVBQUU7VUFDM0QsT0FBT0UsQ0FBQyxDQUFDMkIsR0FBRyxLQUFLRCxhQUFhO1FBQy9CO1FBRUEsT0FDQzFCLENBQUMsQ0FBQ3VCLEVBQUUsS0FBS0csYUFBYSxDQUFDSCxFQUFFLElBQ3pCeEIseUJBQXlCLENBQUNDLENBQUMsQ0FBQzJCLEdBQUcsRUFBRUQsYUFBYSxDQUFDQyxHQUFHLENBQUMsSUFDbkQzQixDQUFDLENBQUN3QixVQUFVLENBQUNsQixNQUFNLEtBQUtvQixhQUFhLENBQUNGLFVBQVUsQ0FBQ2xCLE1BQU0sSUFDdkROLENBQUMsQ0FBQ3dCLFVBQVUsQ0FBQ2pCLEtBQUssQ0FBQyxDQUFDTCxLQUFLLEVBQUVnQixLQUFLLEtBQUtuQix5QkFBeUIsQ0FBQzJCLGFBQWEsQ0FBQ0YsVUFBVSxDQUFDTixLQUFLLENBQUMsRUFBRWhCLEtBQUssQ0FBQyxDQUFDO01BR3pHLEtBQUssS0FBSztRQUNULE9BQU9GLENBQUMsQ0FBQzRCLEdBQUcsS0FBTTNCLENBQUMsQ0FBeUIyQixHQUFHO0lBQUM7SUFFbEQsT0FBTyxLQUFLO0VBQ2I7O0VBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBTEE7RUFNQSxTQUFTQyxvQkFBb0IsQ0FBQ3JCLFVBQXlCLEVBQWlCO0lBQ3ZFLE9BQU9BLFVBQVUsQ0FBQ0gsUUFBUSxDQUFDeUIsTUFBTSxDQUNoQyxDQUFDQyxNQUFxQixFQUFFNUIsT0FBTyxLQUFLO01BQ25DLE1BQU02Qix1QkFBdUIsR0FDNUI3QixPQUFPLENBQUN0QixLQUFLLEtBQUssS0FBSyxJQUFJc0IsT0FBTyxDQUFDQyxRQUFRLEtBQUtJLFVBQVUsQ0FBQ0osUUFBUSxHQUFHRCxPQUFPLENBQUNFLFFBQVEsR0FBRyxDQUFDRixPQUFPLENBQUM7TUFDbkc2Qix1QkFBdUIsQ0FBQ0MsT0FBTyxDQUFFQyxTQUFTLElBQUs7UUFDOUMsSUFBSUgsTUFBTSxDQUFDMUIsUUFBUSxDQUFDRSxLQUFLLENBQUU0QixDQUFDLElBQUssQ0FBQ3BDLHlCQUF5QixDQUFDb0MsQ0FBQyxFQUFFRCxTQUFTLENBQUMsQ0FBQyxFQUFFO1VBQzNFSCxNQUFNLENBQUMxQixRQUFRLENBQUMrQixJQUFJLENBQUNGLFNBQVMsQ0FBQztRQUNoQztNQUNELENBQUMsQ0FBQztNQUNGLE9BQU9ILE1BQU07SUFDZCxDQUFDLEVBQ0Q7TUFBRWxELEtBQUssRUFBRSxLQUFLO01BQUV1QixRQUFRLEVBQUVJLFVBQVUsQ0FBQ0osUUFBUTtNQUFFQyxRQUFRLEVBQUU7SUFBRyxDQUFDLENBQzdEO0VBQ0Y7O0VBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ0EsU0FBU2dDLHNCQUFzQixDQUFDMUMsV0FBZ0QsRUFBVztJQUMxRixNQUFNMkMsa0JBQWtCLEdBQUczQyxXQUFXLENBQUM0QyxHQUFHLENBQUNDLEdBQUcsQ0FBQztJQUMvQyxPQUFPN0MsV0FBVyxDQUFDYyxJQUFJLENBQUMsQ0FBQ0QsVUFBVSxFQUFFVSxLQUFLLEtBQUs7TUFDOUMsS0FBSyxJQUFJdUIsQ0FBQyxHQUFHdkIsS0FBSyxHQUFHLENBQUMsRUFBRXVCLENBQUMsR0FBR0gsa0JBQWtCLENBQUNoQyxNQUFNLEVBQUVtQyxDQUFDLEVBQUUsRUFBRTtRQUMzRCxJQUFJMUMseUJBQXlCLENBQUNTLFVBQVUsRUFBRThCLGtCQUFrQixDQUFDRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1VBQ2pFLE9BQU8sSUFBSTtRQUNaO01BQ0Q7TUFDQSxPQUFPLEtBQUs7SUFDYixDQUFDLENBQUM7RUFDSDs7RUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFDTyxTQUFTQyxHQUFHLEdBQW1GO0lBQUEsbUNBQS9FckMsUUFBUTtNQUFSQSxRQUFRO0lBQUE7SUFDOUIsTUFBTVYsV0FBVyxHQUFHa0Msb0JBQW9CLENBQUM7TUFDeENoRCxLQUFLLEVBQUUsS0FBSztNQUNadUIsUUFBUSxFQUFFLElBQUk7TUFDZEMsUUFBUSxFQUFFQSxRQUFRLENBQUNrQyxHQUFHLENBQUNJLGFBQWE7SUFDckMsQ0FBQyxDQUFDLENBQUN0QyxRQUFRO0lBRVgsSUFBSVgseUJBQXlCLENBQUMsR0FBR0MsV0FBVyxDQUFDLEVBQUU7TUFDOUMsT0FBT0wsc0JBQXNCO0lBQzlCO0lBQ0EsSUFBSXNELGFBQWEsR0FBRyxLQUFLO0lBQ3pCLE1BQU1DLG9CQUFvQixHQUFHbEQsV0FBVyxDQUFDbUQsTUFBTSxDQUFFdEMsVUFBVSxJQUFLO01BQy9ELElBQUl1QyxPQUFPLENBQUN2QyxVQUFVLENBQUMsRUFBRTtRQUN4Qm9DLGFBQWEsR0FBRyxJQUFJO01BQ3JCO01BQ0EsT0FBTyxDQUFDSSxVQUFVLENBQUN4QyxVQUFVLENBQUM7SUFDL0IsQ0FBQyxDQUFDO0lBQ0YsSUFBSW9DLGFBQWEsRUFBRTtNQUNsQixPQUFPSyxRQUFRLENBQUMsS0FBSyxDQUFDO0lBQ3ZCLENBQUMsTUFBTSxJQUFJSixvQkFBb0IsQ0FBQ3ZDLE1BQU0sS0FBSyxDQUFDLEVBQUU7TUFDN0M7TUFDQSxNQUFNNEMsT0FBTyxHQUFHdkQsV0FBVyxDQUFDbUMsTUFBTSxDQUFDLENBQUNDLE1BQU0sRUFBRXZCLFVBQVUsS0FBS3VCLE1BQU0sSUFBSW9CLE1BQU0sQ0FBQzNDLFVBQVUsQ0FBQyxFQUFFLElBQUksQ0FBQztNQUM5RixPQUFPeUMsUUFBUSxDQUFDQyxPQUFPLENBQUM7SUFDekIsQ0FBQyxNQUFNLElBQUlMLG9CQUFvQixDQUFDdkMsTUFBTSxLQUFLLENBQUMsRUFBRTtNQUM3QyxPQUFPdUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDO0lBQy9CLENBQUMsTUFBTSxJQUFJUixzQkFBc0IsQ0FBQ1Esb0JBQW9CLENBQUMsRUFBRTtNQUN4RCxPQUFPSSxRQUFRLENBQUMsS0FBSyxDQUFDO0lBQ3ZCLENBQUMsTUFBTTtNQUNOLE9BQU87UUFDTnBFLEtBQUssRUFBRSxLQUFLO1FBQ1p1QixRQUFRLEVBQUUsSUFBSTtRQUNkQyxRQUFRLEVBQUV3QztNQUNYLENBQUM7SUFDRjtFQUNEOztFQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQVJBO0VBU08sU0FBU08sRUFBRSxHQUFtRjtJQUFBLG1DQUEvRS9DLFFBQVE7TUFBUkEsUUFBUTtJQUFBO0lBQzdCLE1BQU1WLFdBQVcsR0FBR2tDLG9CQUFvQixDQUFDO01BQ3hDaEQsS0FBSyxFQUFFLEtBQUs7TUFDWnVCLFFBQVEsRUFBRSxJQUFJO01BQ2RDLFFBQVEsRUFBRUEsUUFBUSxDQUFDa0MsR0FBRyxDQUFDSSxhQUFhO0lBQ3JDLENBQUMsQ0FBQyxDQUFDdEMsUUFBUTtJQUNYLElBQUlYLHlCQUF5QixDQUFDLEdBQUdDLFdBQVcsQ0FBQyxFQUFFO01BQzlDLE9BQU9MLHNCQUFzQjtJQUM5QjtJQUNBLElBQUkrRCxZQUFZLEdBQUcsS0FBSztJQUN4QixNQUFNUixvQkFBb0IsR0FBR2xELFdBQVcsQ0FBQ21ELE1BQU0sQ0FBRXRDLFVBQVUsSUFBSztNQUMvRCxJQUFJMkMsTUFBTSxDQUFDM0MsVUFBVSxDQUFDLEVBQUU7UUFDdkI2QyxZQUFZLEdBQUcsSUFBSTtNQUNwQjtNQUNBLE9BQU8sQ0FBQ0wsVUFBVSxDQUFDeEMsVUFBVSxDQUFDLElBQUlBLFVBQVUsQ0FBQ04sS0FBSztJQUNuRCxDQUFDLENBQUM7SUFDRixJQUFJbUQsWUFBWSxFQUFFO01BQ2pCLE9BQU9KLFFBQVEsQ0FBQyxJQUFJLENBQUM7SUFDdEIsQ0FBQyxNQUFNLElBQUlKLG9CQUFvQixDQUFDdkMsTUFBTSxLQUFLLENBQUMsRUFBRTtNQUM3QztNQUNBLE1BQU00QyxPQUFPLEdBQUd2RCxXQUFXLENBQUNtQyxNQUFNLENBQUMsQ0FBQ0MsTUFBTSxFQUFFdkIsVUFBVSxLQUFLdUIsTUFBTSxJQUFJb0IsTUFBTSxDQUFDM0MsVUFBVSxDQUFDLEVBQUUsSUFBSSxDQUFDO01BQzlGLE9BQU95QyxRQUFRLENBQUNDLE9BQU8sQ0FBQztJQUN6QixDQUFDLE1BQU0sSUFBSUwsb0JBQW9CLENBQUN2QyxNQUFNLEtBQUssQ0FBQyxFQUFFO01BQzdDLE9BQU91QyxvQkFBb0IsQ0FBQyxDQUFDLENBQUM7SUFDL0IsQ0FBQyxNQUFNLElBQUlSLHNCQUFzQixDQUFDUSxvQkFBb0IsQ0FBQyxFQUFFO01BQ3hELE9BQU9JLFFBQVEsQ0FBQyxJQUFJLENBQUM7SUFDdEIsQ0FBQyxNQUFNO01BQ04sT0FBTztRQUNOcEUsS0FBSyxFQUFFLEtBQUs7UUFDWnVCLFFBQVEsRUFBRSxJQUFJO1FBQ2RDLFFBQVEsRUFBRXdDO01BQ1gsQ0FBQztJQUNGO0VBQ0Q7O0VBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBTEE7RUFNTyxTQUFTTCxHQUFHLENBQUNyQyxPQUF1QyxFQUFxQztJQUMvRkEsT0FBTyxHQUFHd0MsYUFBYSxDQUFDeEMsT0FBTyxDQUFDO0lBQ2hDLElBQUlULHlCQUF5QixDQUFDUyxPQUFPLENBQUMsRUFBRTtNQUN2QyxPQUFPYixzQkFBc0I7SUFDOUIsQ0FBQyxNQUFNLElBQUkwRCxVQUFVLENBQUM3QyxPQUFPLENBQUMsRUFBRTtNQUMvQixPQUFPOEMsUUFBUSxDQUFDLENBQUM5QyxPQUFPLENBQUNELEtBQUssQ0FBQztJQUNoQyxDQUFDLE1BQU0sSUFDTixPQUFPQyxPQUFPLEtBQUssUUFBUSxJQUMzQkEsT0FBTyxDQUFDdEIsS0FBSyxLQUFLLEtBQUssSUFDdkJzQixPQUFPLENBQUNDLFFBQVEsS0FBSyxJQUFJLElBQ3pCRCxPQUFPLENBQUNFLFFBQVEsQ0FBQ0UsS0FBSyxDQUFFQyxVQUFVLElBQUt3QyxVQUFVLENBQUN4QyxVQUFVLENBQUMsSUFBSThDLFlBQVksQ0FBQzlDLFVBQVUsQ0FBQyxDQUFDLEVBQ3pGO01BQ0QsT0FBT2tDLEdBQUcsQ0FBQyxHQUFHdkMsT0FBTyxDQUFDRSxRQUFRLENBQUNrQyxHQUFHLENBQUUvQixVQUFVLElBQUtnQyxHQUFHLENBQUNoQyxVQUFVLENBQUMsQ0FBQyxDQUFDO0lBQ3JFLENBQUMsTUFBTSxJQUNOLE9BQU9MLE9BQU8sS0FBSyxRQUFRLElBQzNCQSxPQUFPLENBQUN0QixLQUFLLEtBQUssS0FBSyxJQUN2QnNCLE9BQU8sQ0FBQ0MsUUFBUSxLQUFLLElBQUksSUFDekJELE9BQU8sQ0FBQ0UsUUFBUSxDQUFDRSxLQUFLLENBQUVDLFVBQVUsSUFBS3dDLFVBQVUsQ0FBQ3hDLFVBQVUsQ0FBQyxJQUFJOEMsWUFBWSxDQUFDOUMsVUFBVSxDQUFDLENBQUMsRUFDekY7TUFDRCxPQUFPNEMsRUFBRSxDQUFDLEdBQUdqRCxPQUFPLENBQUNFLFFBQVEsQ0FBQ2tDLEdBQUcsQ0FBRS9CLFVBQVUsSUFBS2dDLEdBQUcsQ0FBQ2hDLFVBQVUsQ0FBQyxDQUFDLENBQUM7SUFDcEUsQ0FBQyxNQUFNLElBQUk4QyxZQUFZLENBQUNuRCxPQUFPLENBQUMsRUFBRTtNQUNqQztNQUNBLFFBQVFBLE9BQU8sQ0FBQ0MsUUFBUTtRQUN2QixLQUFLLEtBQUs7VUFDVCxPQUFPO1lBQUUsR0FBR0QsT0FBTztZQUFFQyxRQUFRLEVBQUU7VUFBTSxDQUFDO1FBQ3ZDLEtBQUssR0FBRztVQUNQLE9BQU87WUFBRSxHQUFHRCxPQUFPO1lBQUVDLFFBQVEsRUFBRTtVQUFLLENBQUM7UUFDdEMsS0FBSyxJQUFJO1VBQ1IsT0FBTztZQUFFLEdBQUdELE9BQU87WUFBRUMsUUFBUSxFQUFFO1VBQUksQ0FBQztRQUNyQyxLQUFLLEtBQUs7VUFDVCxPQUFPO1lBQUUsR0FBR0QsT0FBTztZQUFFQyxRQUFRLEVBQUU7VUFBTSxDQUFDO1FBQ3ZDLEtBQUssR0FBRztVQUNQLE9BQU87WUFBRSxHQUFHRCxPQUFPO1lBQUVDLFFBQVEsRUFBRTtVQUFLLENBQUM7UUFDdEMsS0FBSyxJQUFJO1VBQ1IsT0FBTztZQUFFLEdBQUdELE9BQU87WUFBRUMsUUFBUSxFQUFFO1VBQUksQ0FBQztNQUFDO0lBRXhDLENBQUMsTUFBTSxJQUFJRCxPQUFPLENBQUN0QixLQUFLLEtBQUssS0FBSyxFQUFFO01BQ25DLE9BQU9zQixPQUFPLENBQUNBLE9BQU87SUFDdkI7SUFFQSxPQUFPO01BQ050QixLQUFLLEVBQUUsS0FBSztNQUNac0IsT0FBTyxFQUFFQTtJQUNWLENBQUM7RUFDRjs7RUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFMQTtFQU1PLFNBQVNvRCxRQUFRLENBQUNwRCxPQUF5QyxFQUFxQztJQUN0RyxJQUFJNkMsVUFBVSxDQUFDN0MsT0FBTyxDQUFDLEVBQUU7TUFDeEIsT0FBTzhDLFFBQVEsQ0FBQyxDQUFDLENBQUM5QyxPQUFPLENBQUNELEtBQUssQ0FBQztJQUNqQyxDQUFDLE1BQU07TUFDTixPQUFPO1FBQ05yQixLQUFLLEVBQUUsUUFBUTtRQUNmc0IsT0FBTyxFQUFFQTtNQUNWLENBQUM7SUFDRjtFQUNEOztFQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBVEE7RUFVTyxTQUFTcUQsaUJBQWlCLENBQ2hDbkMsSUFBWSxFQUNaRCxTQUFrQixFQUcrQztJQUFBLElBRmpFcUMsc0JBQWdDLHVFQUFHLEVBQUU7SUFBQSxJQUNyQ0MsV0FBc0I7SUFFdEIsT0FBT3ZDLFdBQVcsQ0FBQ0UsSUFBSSxFQUFFRCxTQUFTLEVBQUVxQyxzQkFBc0IsRUFBRUMsV0FBVyxDQUFDO0VBQ3pFOztFQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBVEE7RUE0Qk8sU0FBU3ZDLFdBQVcsQ0FDMUJFLElBQXdCLEVBQ3hCRCxTQUFrQixFQUcrQztJQUFBLElBRmpFcUMsc0JBQWdDLHVFQUFHLEVBQUU7SUFBQSxJQUNyQ0MsV0FBc0I7SUFFdEIsSUFBSXJDLElBQUksS0FBS3ZCLFNBQVMsRUFBRTtNQUN2QixPQUFPUixzQkFBc0I7SUFDOUI7SUFDQSxJQUFJcUUsVUFBVTtJQUNkLElBQUlELFdBQVcsRUFBRTtNQUNoQkMsVUFBVSxHQUFHRCxXQUFXLENBQUNyQyxJQUFJLENBQUM7TUFDOUIsSUFBSXNDLFVBQVUsS0FBSzdELFNBQVMsRUFBRTtRQUM3QixPQUFPUixzQkFBc0I7TUFDOUI7SUFDRCxDQUFDLE1BQU07TUFDTixNQUFNc0UsU0FBUyxHQUFHSCxzQkFBc0IsQ0FBQ0ksTUFBTSxFQUFFO01BQ2pERCxTQUFTLENBQUN4QixJQUFJLENBQUNmLElBQUksQ0FBQztNQUNwQnNDLFVBQVUsR0FBR0MsU0FBUyxDQUFDRSxJQUFJLENBQUMsR0FBRyxDQUFDO0lBQ2pDO0lBQ0EsT0FBTztNQUNOakYsS0FBSyxFQUFFLGFBQWE7TUFDcEJ1QyxTQUFTLEVBQUVBLFNBQVM7TUFDcEJDLElBQUksRUFBRXNDO0lBQ1AsQ0FBQztFQUNGO0VBQUM7RUFJRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNPLFNBQVNWLFFBQVEsQ0FBMEIvQyxLQUFRLEVBQXlCO0lBQ2xGLElBQUk2RCxhQUFnQjtJQUVwQixJQUFJLE9BQU83RCxLQUFLLEtBQUssUUFBUSxJQUFJQSxLQUFLLEtBQUssSUFBSSxJQUFJQSxLQUFLLEtBQUtKLFNBQVMsRUFBRTtNQUN2RSxJQUFJa0UsS0FBSyxDQUFDQyxPQUFPLENBQUMvRCxLQUFLLENBQUMsRUFBRTtRQUN6QjZELGFBQWEsR0FBRzdELEtBQUssQ0FBQ3FDLEdBQUcsQ0FBQ0ksYUFBYSxDQUFNO01BQzlDLENBQUMsTUFBTSxJQUFJdUIsaUJBQWlCLENBQUNoRSxLQUFLLENBQUMsRUFBRTtRQUNwQzZELGFBQWEsR0FBRzdELEtBQUssQ0FBQ2lFLE9BQU8sRUFBTztNQUNyQyxDQUFDLE1BQU07UUFDTkosYUFBYSxHQUFHSyxNQUFNLENBQUNDLE9BQU8sQ0FBQ25FLEtBQUssQ0FBQyxDQUFDNEIsTUFBTSxDQUFDLENBQUN3QyxlQUFlLFdBQWlCO1VBQUEsSUFBZixDQUFDQyxHQUFHLEVBQUVDLEdBQUcsQ0FBQztVQUN4RSxNQUFNQyxZQUFZLEdBQUc5QixhQUFhLENBQUM2QixHQUFHLENBQUM7VUFDdkMsSUFBSUMsWUFBWSxDQUFDNUYsS0FBSyxLQUFLLFVBQVUsSUFBSTRGLFlBQVksQ0FBQ3ZFLEtBQUssS0FBS0osU0FBUyxFQUFFO1lBQzFFd0UsZUFBZSxDQUFDQyxHQUFHLENBQUMsR0FBR0UsWUFBWTtVQUNwQztVQUNBLE9BQU9ILGVBQWU7UUFDdkIsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUErQjtNQUNyQztJQUNELENBQUMsTUFBTTtNQUNOUCxhQUFhLEdBQUc3RCxLQUFLO0lBQ3RCO0lBRUEsT0FBTztNQUFFckIsS0FBSyxFQUFFLFVBQVU7TUFBRXFCLEtBQUssRUFBRTZEO0lBQWMsQ0FBQztFQUNuRDtFQUFDO0VBRU0sU0FBU1csb0JBQW9CLENBQ25DeEUsS0FBZ0MsRUFDaEN5RSxVQUFtQixFQUM4RztJQUNqSSxJQUFJekUsS0FBSyxLQUFLSixTQUFTLElBQUksT0FBT0ksS0FBSyxLQUFLLFFBQVEsSUFBSUEsS0FBSyxDQUFDMEUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFO01BQzlFLE1BQU1DLGdCQUFnQixHQUFHLGVBQWUsQ0FBQyxDQUFDO01BQzFDLE1BQU1DLHFCQUFxQixHQUFHRCxnQkFBZ0IsQ0FBQ0UsSUFBSSxDQUFDN0UsS0FBSyxDQUFDO01BRTFELElBQUlBLEtBQUssQ0FBQzBFLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRTtRQUMzQjtRQUNBLE9BQU87VUFDTi9GLEtBQUssRUFBRSwyQkFBMkI7VUFDbENxQixLQUFLLEVBQUVBO1FBQ1IsQ0FBQztNQUNGLENBQUMsTUFBTSxJQUFJNEUscUJBQXFCLEVBQUU7UUFDakMsT0FBTzNELFdBQVcsQ0FBQzJELHFCQUFxQixDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRUEscUJBQXFCLENBQUMsQ0FBQyxDQUFDLElBQUloRixTQUFTLENBQUM7TUFDMUYsQ0FBQyxNQUFNO1FBQ04sT0FBTztVQUNOakIsS0FBSyxFQUFFLGlCQUFpQjtVQUN4QnFCLEtBQUssRUFBRUE7UUFDUixDQUFDO01BQ0Y7SUFDRCxDQUFDLE1BQU0sSUFBSXlFLFVBQVUsS0FBSyxTQUFTLElBQUksT0FBT3pFLEtBQUssS0FBSyxRQUFRLEtBQUtBLEtBQUssS0FBSyxNQUFNLElBQUlBLEtBQUssS0FBSyxPQUFPLENBQUMsRUFBRTtNQUM1RyxPQUFPK0MsUUFBUSxDQUFDL0MsS0FBSyxLQUFLLE1BQU0sQ0FBQztJQUNsQyxDQUFDLE1BQU0sSUFBSXlFLFVBQVUsS0FBSyxRQUFRLElBQUksT0FBT3pFLEtBQUssS0FBSyxRQUFRLEtBQUssQ0FBQzhFLEtBQUssQ0FBQ0MsTUFBTSxDQUFDL0UsS0FBSyxDQUFDLENBQUMsSUFBSUEsS0FBSyxLQUFLLEtBQUssQ0FBQyxFQUFFO01BQzlHLE9BQU8rQyxRQUFRLENBQUNnQyxNQUFNLENBQUMvRSxLQUFLLENBQUMsQ0FBQztJQUMvQixDQUFDLE1BQU07TUFDTixPQUFPK0MsUUFBUSxDQUFDL0MsS0FBSyxDQUFDO0lBQ3ZCO0VBQ0Q7O0VBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFOQTtFQU9PLFNBQVMwQixHQUFHLENBQUNzRCxTQUF3QixFQUF1QjtJQUNsRSxPQUFPO01BQUVyRyxLQUFLLEVBQUUsS0FBSztNQUFFK0MsR0FBRyxFQUFFc0Q7SUFBVSxDQUFDO0VBQ3hDOztFQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBTkE7RUFPTyxTQUFTdkMsYUFBYSxDQUEwQndDLFNBQW1DLEVBQStCO0lBQ3hILElBQUlDLDBCQUEwQixDQUFDRCxTQUFTLENBQUMsRUFBRTtNQUMxQyxPQUFPQSxTQUFTO0lBQ2pCO0lBRUEsT0FBT2xDLFFBQVEsQ0FBQ2tDLFNBQVMsQ0FBQztFQUMzQjs7RUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFSQTtFQVNPLFNBQVNDLDBCQUEwQixDQUN6QzVFLFVBQXVELEVBQ0w7SUFDbEQsT0FBTyxDQUFDQSxVQUFVLGFBQVZBLFVBQVUsdUJBQVZBLFVBQVUsQ0FBd0MzQixLQUFLLE1BQUtpQixTQUFTO0VBQzlFOztFQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBTkE7RUFPTyxTQUFTa0QsVUFBVSxDQUEwQnFDLGFBQXVDLEVBQTBDO0lBQ3BJLE9BQU8sT0FBT0EsYUFBYSxLQUFLLFFBQVEsSUFBS0EsYUFBYSxDQUF1QnhHLEtBQUssS0FBSyxVQUFVO0VBQ3RHO0VBQUM7RUFFRCxTQUFTc0UsTUFBTSxDQUFDM0MsVUFBbUQsRUFBVztJQUM3RSxPQUFPd0MsVUFBVSxDQUFDeEMsVUFBVSxDQUFDLElBQUlBLFVBQVUsQ0FBQ04sS0FBSyxLQUFLLElBQUk7RUFDM0Q7RUFFQSxTQUFTNkMsT0FBTyxDQUFDdkMsVUFBbUQsRUFBVztJQUM5RSxPQUFPd0MsVUFBVSxDQUFDeEMsVUFBVSxDQUFDLElBQUlBLFVBQVUsQ0FBQ04sS0FBSyxLQUFLLEtBQUs7RUFDNUQ7O0VBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFDTyxTQUFTb0YsdUJBQXVCLENBQ3RDQyxZQUFzQyxFQUNLO0lBQzNDLE9BQU8sQ0FBQ0EsWUFBWSxhQUFaQSxZQUFZLHVCQUFaQSxZQUFZLENBQXdCMUcsS0FBSyxNQUFLLGFBQWE7RUFDcEU7O0VBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFOQTtFQU9PLFNBQVMyRyx1QkFBdUIsQ0FDdENELFlBQXNDLEVBQ0s7SUFDM0MsT0FBTyxDQUFDQSxZQUFZLGFBQVpBLFlBQVksdUJBQVpBLFlBQVksQ0FBd0IxRyxLQUFLLE1BQUssYUFBYTtFQUNwRTs7RUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFMQTtFQU1BLFNBQVM0RyxrQkFBa0IsQ0FBQ2pGLFVBQW1ELEVBQWtDO0lBQ2hILE9BQU8sQ0FBQ0EsVUFBVSxhQUFWQSxVQUFVLHVCQUFWQSxVQUFVLENBQW9DM0IsS0FBSyxNQUFLLFFBQVE7RUFDekU7O0VBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ0EsU0FBUzZHLGtCQUFrQixDQUFDbEYsVUFBbUQsRUFBa0M7SUFDaEgsT0FBTyxDQUFDQSxVQUFVLGFBQVZBLFVBQVUsdUJBQVZBLFVBQVUsQ0FBb0MzQixLQUFLLE1BQUssUUFBUTtFQUN6RTs7RUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNBLFNBQVN5RSxZQUFZLENBQTBCOUMsVUFBdUMsRUFBc0M7SUFDM0gsT0FBT0EsVUFBVSxDQUFDM0IsS0FBSyxLQUFLLFlBQVk7RUFDekM7O0VBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ08sU0FBUzhHLHFCQUFxQixDQUFDbkYsVUFBbUIsRUFBK0M7SUFDdkcsTUFBTW9GLHNCQUFzQixHQUFHcEYsVUFBK0M7SUFDOUUsT0FBTyxDQUFBb0Ysc0JBQXNCLGFBQXRCQSxzQkFBc0IsdUJBQXRCQSxzQkFBc0IsQ0FBRS9HLEtBQUssTUFBSyxVQUFVLElBQUksQ0FBQStHLHNCQUFzQixhQUF0QkEsc0JBQXNCLHVCQUF0QkEsc0JBQXNCLENBQUUxRixLQUFLLE1BQUtKLFNBQVM7RUFDbkc7RUFBQztFQWdCRCxTQUFTb0UsaUJBQWlCLENBQUMyQixVQUFrQixFQUFXO0lBQ3ZELFFBQVFBLFVBQVUsQ0FBQ0MsV0FBVyxDQUFDQyxJQUFJO01BQ2xDLEtBQUssUUFBUTtNQUNiLEtBQUssUUFBUTtNQUNiLEtBQUssU0FBUztRQUNiLE9BQU8sSUFBSTtNQUNaO1FBQ0MsT0FBTyxLQUFLO0lBQUM7RUFFaEI7RUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNBLFNBQVNDLDZCQUE2QixDQUFJQyxlQUEyQyxFQUFxRDtJQUN6SSxPQUFPLE9BQU9BLGVBQWUsS0FBSyxRQUFRLElBQUksQ0FBQy9CLGlCQUFpQixDQUFDK0IsZUFBZSxDQUFXO0VBQzVGOztFQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ08sU0FBU0MsMkJBQTJCLENBQzFDRCxlQUF1RCxFQUlOO0lBQUE7SUFBQSxJQUhqRHhDLHNCQUFnQyx1RUFBRyxFQUFFO0lBQUEsSUFDckMwQyxZQUF1QztJQUFBLElBQ3ZDekMsV0FBc0I7SUFFdEIsSUFBSXVDLGVBQWUsS0FBS25HLFNBQVMsRUFBRTtNQUNsQyxPQUFPNkMsYUFBYSxDQUFDd0QsWUFBWSxDQUF5QjtJQUMzRDtJQUNBRixlQUFlLHVCQUFHQSxlQUFlLHFEQUFmLGlCQUFpQjlCLE9BQU8sRUFBZ0M7SUFDMUUsSUFBSSxDQUFDNkIsNkJBQTZCLENBQUNDLGVBQWUsQ0FBQyxFQUFFO01BQ3BELE9BQU9oRCxRQUFRLENBQUNnRCxlQUFlLENBQUM7SUFDakM7SUFFQSxRQUFRQSxlQUFlLENBQUNsSCxJQUFJO01BQzNCLEtBQUssTUFBTTtRQUNWLE9BQU9vQyxXQUFXLENBQUM4RSxlQUFlLENBQUM1RSxJQUFJLEVBQUV2QixTQUFTLEVBQUUyRCxzQkFBc0IsRUFBRUMsV0FBVyxDQUFDO01BQ3pGLEtBQUssSUFBSTtRQUNSLE9BQU8wQyxzQkFBc0IsQ0FBQ0gsZUFBZSxDQUFDSSxFQUFFLEVBQUU1QyxzQkFBc0IsRUFBRUMsV0FBVyxDQUFDO01BR3ZGLEtBQUssS0FBSztRQUNULE9BQU9sQixHQUFHLENBQUM4RCx3QkFBd0IsQ0FBQ0wsZUFBZSxDQUFDTSxHQUFHLEVBQUU5QyxzQkFBc0IsRUFBRUMsV0FBVyxDQUFDLENBQUM7TUFHL0YsS0FBSyxJQUFJO1FBQ1IsT0FBTzhDLEtBQUssQ0FDWEYsd0JBQXdCLENBQUNMLGVBQWUsQ0FBQ1EsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFaEQsc0JBQXNCLEVBQUVDLFdBQVcsQ0FBQyxFQUNwRjRDLHdCQUF3QixDQUFDTCxlQUFlLENBQUNRLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRWhELHNCQUFzQixFQUFFQyxXQUFXLENBQUMsQ0FDcEY7TUFDRixLQUFLLElBQUk7UUFDUixPQUFPZ0QsUUFBUSxDQUNkSix3QkFBd0IsQ0FBQ0wsZUFBZSxDQUFDVSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUVsRCxzQkFBc0IsRUFBRUMsV0FBVyxDQUFDLEVBQ3BGNEMsd0JBQXdCLENBQUNMLGVBQWUsQ0FBQ1UsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFbEQsc0JBQXNCLEVBQUVDLFdBQVcsQ0FBQyxDQUNwRjtNQUNGLEtBQUssSUFBSTtRQUNSLE9BQU9rRCxXQUFXLENBQ2pCTix3QkFBd0IsQ0FBQ0wsZUFBZSxDQUFDWSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUVwRCxzQkFBc0IsRUFBRUMsV0FBVyxDQUFDLEVBQ3BGNEMsd0JBQXdCLENBQUNMLGVBQWUsQ0FBQ1ksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFcEQsc0JBQXNCLEVBQUVDLFdBQVcsQ0FBQyxDQUNwRjtNQUNGLEtBQUssSUFBSTtRQUNSLE9BQU9vRCxjQUFjLENBQ3BCUix3QkFBd0IsQ0FBQ0wsZUFBZSxDQUFDYyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUV0RCxzQkFBc0IsRUFBRUMsV0FBVyxDQUFDLEVBQ3BGNEMsd0JBQXdCLENBQUNMLGVBQWUsQ0FBQ2MsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFdEQsc0JBQXNCLEVBQUVDLFdBQVcsQ0FBQyxDQUNwRjtNQUNGLEtBQUssSUFBSTtRQUNSLE9BQU9zRCxRQUFRLENBQ2RWLHdCQUF3QixDQUFDTCxlQUFlLENBQUNnQixFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUV4RCxzQkFBc0IsRUFBRUMsV0FBVyxDQUFDLEVBQ3BGNEMsd0JBQXdCLENBQUNMLGVBQWUsQ0FBQ2dCLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRXhELHNCQUFzQixFQUFFQyxXQUFXLENBQUMsQ0FDcEY7TUFDRixLQUFLLElBQUk7UUFDUixPQUFPd0QsV0FBVyxDQUNqQlosd0JBQXdCLENBQUNMLGVBQWUsQ0FBQ2tCLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRTFELHNCQUFzQixFQUFFQyxXQUFXLENBQUMsRUFDcEY0Qyx3QkFBd0IsQ0FBQ0wsZUFBZSxDQUFDa0IsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFMUQsc0JBQXNCLEVBQUVDLFdBQVcsQ0FBQyxDQUNwRjtNQUNGLEtBQUssSUFBSTtRQUNSLE9BQU9OLEVBQUUsQ0FDUixHQUFHNkMsZUFBZSxDQUFDbUIsRUFBRSxDQUFDN0UsR0FBRyxDQUFDLFVBQVU4RSxXQUFXLEVBQUU7VUFDaEQsT0FBT2Ysd0JBQXdCLENBQVVlLFdBQVcsRUFBRTVELHNCQUFzQixFQUFFQyxXQUFXLENBQUM7UUFDM0YsQ0FBQyxDQUFDLENBQ0Y7TUFDRixLQUFLLEtBQUs7UUFDVCxPQUFPaEIsR0FBRyxDQUNULEdBQUd1RCxlQUFlLENBQUNxQixHQUFHLENBQUMvRSxHQUFHLENBQUMsVUFBVWdGLFlBQVksRUFBRTtVQUNsRCxPQUFPakIsd0JBQXdCLENBQVVpQixZQUFZLEVBQUU5RCxzQkFBc0IsRUFBRUMsV0FBVyxDQUFDO1FBQzVGLENBQUMsQ0FBQyxDQUNGO01BQ0YsS0FBSyxPQUFPO1FBQ1gsT0FBTzhELHlCQUF5QixDQUMvQnZCLGVBQWUsRUFDZnhDLHNCQUFzQixFQUN0QkMsV0FBVyxDQUNYO0lBQW1EO0lBRXRELE9BQU9wRSxzQkFBc0I7RUFDOUI7O0VBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBUkE7RUFTQSxTQUFTZ0gsd0JBQXdCLENBQ2hDTCxlQUF3QyxFQUdWO0lBQUEsSUFGOUJ4QyxzQkFBZ0MsdUVBQUcsRUFBRTtJQUFBLElBQ3JDQyxXQUFzQjtJQUV0QixJQUFJdUMsZUFBZSxLQUFLLElBQUksSUFBSSxPQUFPQSxlQUFlLEtBQUssUUFBUSxFQUFFO01BQ3BFLE9BQU9oRCxRQUFRLENBQUNnRCxlQUFlLENBQU07SUFDdEMsQ0FBQyxNQUFNLElBQUlBLGVBQWUsQ0FBQ3dCLGNBQWMsQ0FBQyxLQUFLLENBQUMsRUFBRTtNQUNqRCxPQUFPckUsRUFBRSxDQUNSLEdBQUs2QyxlQUFlLENBQTZCeUIsR0FBRyxDQUFDbkYsR0FBRyxDQUFDLFVBQVU4RSxXQUFXLEVBQUU7UUFDL0UsT0FBT2Ysd0JBQXdCLENBQUNlLFdBQVcsRUFBRTVELHNCQUFzQixFQUFFQyxXQUFXLENBQUM7TUFDbEYsQ0FBQyxDQUFvRCxDQUNyRDtJQUNGLENBQUMsTUFBTSxJQUFJdUMsZUFBZSxDQUFDd0IsY0FBYyxDQUFDLE1BQU0sQ0FBQyxFQUFFO01BQ2xELE9BQU8vRSxHQUFHLENBQ1QsR0FBS3VELGVBQWUsQ0FBOEIwQixJQUFJLENBQUNwRixHQUFHLENBQUMsVUFBVWdGLFlBQVksRUFBRTtRQUNsRixPQUFPakIsd0JBQXdCLENBQUNpQixZQUFZLEVBQUU5RCxzQkFBc0IsRUFBRUMsV0FBVyxDQUFDO01BQ25GLENBQUMsQ0FBb0QsQ0FDckQ7SUFDRixDQUFDLE1BQU0sSUFBSXVDLGVBQWUsQ0FBQ3dCLGNBQWMsQ0FBQyxNQUFNLENBQUMsRUFBRTtNQUNsRCxPQUFPakYsR0FBRyxDQUNUOEQsd0JBQXdCLENBQUVMLGVBQWUsQ0FBOEIyQixJQUFJLEVBQUVuRSxzQkFBc0IsRUFBRUMsV0FBVyxDQUFDLENBQ2pIO0lBQ0YsQ0FBQyxNQUFNLElBQUl1QyxlQUFlLENBQUN3QixjQUFjLENBQUMsS0FBSyxDQUFDLEVBQUU7TUFDakQsT0FBT2pCLEtBQUssQ0FDWEYsd0JBQXdCLENBQUVMLGVBQWUsQ0FBNkI0QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUVwRSxzQkFBc0IsRUFBRUMsV0FBVyxDQUFDLEVBQ2xINEMsd0JBQXdCLENBQUVMLGVBQWUsQ0FBNkI0QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUVwRSxzQkFBc0IsRUFBRUMsV0FBVyxDQUFDLENBQ2xIO0lBQ0YsQ0FBQyxNQUFNLElBQUl1QyxlQUFlLENBQUN3QixjQUFjLENBQUMsS0FBSyxDQUFDLEVBQUU7TUFDakQsT0FBT2YsUUFBUSxDQUNkSix3QkFBd0IsQ0FBRUwsZUFBZSxDQUE2QjZCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRXJFLHNCQUFzQixFQUFFQyxXQUFXLENBQUMsRUFDbEg0Qyx3QkFBd0IsQ0FBRUwsZUFBZSxDQUE2QjZCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRXJFLHNCQUFzQixFQUFFQyxXQUFXLENBQUMsQ0FDbEg7SUFDRixDQUFDLE1BQU0sSUFBSXVDLGVBQWUsQ0FBQ3dCLGNBQWMsQ0FBQyxLQUFLLENBQUMsRUFBRTtNQUNqRCxPQUFPYixXQUFXLENBQ2pCTix3QkFBd0IsQ0FBRUwsZUFBZSxDQUE2QjhCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRXRFLHNCQUFzQixFQUFFQyxXQUFXLENBQUMsRUFDbEg0Qyx3QkFBd0IsQ0FBRUwsZUFBZSxDQUE2QjhCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRXRFLHNCQUFzQixFQUFFQyxXQUFXLENBQUMsQ0FDbEg7SUFDRixDQUFDLE1BQU0sSUFBSXVDLGVBQWUsQ0FBQ3dCLGNBQWMsQ0FBQyxLQUFLLENBQUMsRUFBRTtNQUNqRCxPQUFPWCxjQUFjLENBQ3BCUix3QkFBd0IsQ0FBRUwsZUFBZSxDQUE2QitCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRXZFLHNCQUFzQixFQUFFQyxXQUFXLENBQUMsRUFDbEg0Qyx3QkFBd0IsQ0FBRUwsZUFBZSxDQUE2QitCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRXZFLHNCQUFzQixFQUFFQyxXQUFXLENBQUMsQ0FDbEg7SUFDRixDQUFDLE1BQU0sSUFBSXVDLGVBQWUsQ0FBQ3dCLGNBQWMsQ0FBQyxLQUFLLENBQUMsRUFBRTtNQUNqRCxPQUFPVCxRQUFRLENBQ2RWLHdCQUF3QixDQUFFTCxlQUFlLENBQTZCZ0MsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFeEUsc0JBQXNCLEVBQUVDLFdBQVcsQ0FBQyxFQUNsSDRDLHdCQUF3QixDQUFFTCxlQUFlLENBQTZCZ0MsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFeEUsc0JBQXNCLEVBQUVDLFdBQVcsQ0FBQyxDQUNsSDtJQUNGLENBQUMsTUFBTSxJQUFJdUMsZUFBZSxDQUFDd0IsY0FBYyxDQUFDLEtBQUssQ0FBQyxFQUFFO01BQ2pELE9BQU9QLFdBQVcsQ0FDakJaLHdCQUF3QixDQUFFTCxlQUFlLENBQTZCaUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFekUsc0JBQXNCLEVBQUVDLFdBQVcsQ0FBQyxFQUNsSDRDLHdCQUF3QixDQUFFTCxlQUFlLENBQTZCaUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFekUsc0JBQXNCLEVBQUVDLFdBQVcsQ0FBQyxDQUNsSDtJQUNGLENBQUMsTUFBTSxJQUFJdUMsZUFBZSxDQUFDd0IsY0FBYyxDQUFDLE9BQU8sQ0FBQyxFQUFFO01BQ25ELE9BQU90RyxXQUFXLENBQUU4RSxlQUFlLENBQWdDa0MsS0FBSyxFQUFFckksU0FBUyxFQUFFMkQsc0JBQXNCLEVBQUVDLFdBQVcsQ0FBQztJQUMxSCxDQUFDLE1BQU0sSUFBSXVDLGVBQWUsQ0FBQ3dCLGNBQWMsQ0FBQyxRQUFRLENBQUMsRUFBRTtNQUNwRCxPQUFPdkIsMkJBQTJCLENBQ2pDO1FBQ0NuSCxJQUFJLEVBQUUsT0FBTztRQUNicUosUUFBUSxFQUFHbkMsZUFBZSxDQUE0Qm9DLFNBQVM7UUFDL0RDLEtBQUssRUFBR3JDLGVBQWUsQ0FBMEJzQztNQUNsRCxDQUFDLEVBQ0Q5RSxzQkFBc0IsRUFDdEIzRCxTQUFTLEVBQ1Q0RCxXQUFXLENBQ1g7SUFDRixDQUFDLE1BQU0sSUFBSXVDLGVBQWUsQ0FBQ3dCLGNBQWMsQ0FBQyxLQUFLLENBQUMsRUFBRTtNQUNqRCxPQUFPdkIsMkJBQTJCLENBQ2pDO1FBQ0NuSCxJQUFJLEVBQUUsSUFBSTtRQUNWc0gsRUFBRSxFQUFHSixlQUFlLENBQXVCdUM7TUFDNUMsQ0FBQyxFQUNEL0Usc0JBQXNCLEVBQ3RCM0QsU0FBUyxFQUNUNEQsV0FBVyxDQUNYO0lBQ0YsQ0FBQyxNQUFNLElBQUl1QyxlQUFlLENBQUN3QixjQUFjLENBQUMsYUFBYSxDQUFDLEVBQUU7TUFDekQsT0FBT3hFLFFBQVEsQ0FBQ3dGLGdCQUFnQixDQUFFeEMsZUFBZSxDQUE4QnlDLFdBQVcsQ0FBQyxDQUFNO0lBQ2xHO0lBQ0EsT0FBT3pGLFFBQVEsQ0FBQyxLQUFLLENBQU07RUFDNUI7O0VBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ08sU0FBU21ELHNCQUFzQixDQUNyQ0gsZUFBK0MsRUFHakI7SUFBQSxJQUY5QnhDLHNCQUFnQyx1RUFBRyxFQUFFO0lBQUEsSUFDckNDLFdBQXNCO0lBRXRCLE9BQU9pRixNQUFNLENBQ1pyQyx3QkFBd0IsQ0FBQ0wsZUFBZSxDQUFDLENBQUMsQ0FBQyxFQUFFeEMsc0JBQXNCLEVBQUVDLFdBQVcsQ0FBQyxFQUNqRjRDLHdCQUF3QixDQUFDTCxlQUFlLENBQUMsQ0FBQyxDQUFDLEVBQTZCeEMsc0JBQXNCLEVBQUVDLFdBQVcsQ0FBQyxFQUM1RzRDLHdCQUF3QixDQUFDTCxlQUFlLENBQUMsQ0FBQyxDQUFDLEVBQTZCeEMsc0JBQXNCLEVBQUVDLFdBQVcsQ0FBQyxDQUM1RztFQUNGO0VBQ0E7RUFBQTtFQUVBLFNBQVNrRix5QkFBeUIsQ0FBQ0MsVUFBMkMsRUFBbUM7SUFDaEgsSUFBSUMsbUJBQW1CLEdBQUdELFVBQVU7SUFDcEMsSUFBSUEsVUFBVSxDQUFDcEIsY0FBYyxDQUFDLE9BQU8sQ0FBQyxFQUFFO01BQ3ZDcUIsbUJBQW1CLEdBQUc7UUFDckIvSixJQUFJLEVBQUUsTUFBTTtRQUNac0MsSUFBSSxFQUFFd0gsVUFBVSxDQUFDVjtNQUNsQixDQUFxQztJQUN0QyxDQUFDLE1BQU0sSUFBSVUsVUFBVSxDQUFDcEIsY0FBYyxDQUFDLEtBQUssQ0FBQyxFQUFFO01BQzVDcUIsbUJBQW1CLEdBQUc7UUFDckIvSixJQUFJLEVBQUUsSUFBSTtRQUNWc0gsRUFBRSxFQUFFd0MsVUFBVSxDQUFDTDtNQUNoQixDQUFtQztJQUNwQyxDQUFDLE1BQU0sSUFBSUssVUFBVSxDQUFDcEIsY0FBYyxDQUFDLFFBQVEsQ0FBQyxFQUFFO01BQy9DcUIsbUJBQW1CLEdBQUc7UUFDckIvSixJQUFJLEVBQUUsT0FBTztRQUNicUosUUFBUSxFQUFFUyxVQUFVLENBQUNSLFNBQVM7UUFDOUJDLEtBQUssRUFBRU8sVUFBVSxDQUFDTjtNQUNuQixDQUFzQztJQUN2QztJQUNBLE9BQU9PLG1CQUFtQjtFQUMzQjtFQUdPLFNBQVN0Qix5QkFBeUIsQ0FDeEN1QixlQUFrRCxFQUdmO0lBQUEsSUFGbkN0RixzQkFBZ0MsdUVBQUcsRUFBRTtJQUFBLElBQ3JDQyxXQUFzQjtJQUV0QixRQUFRcUYsZUFBZSxDQUFDWCxRQUFRO01BQy9CLEtBQUssY0FBYztRQUNsQixPQUFPdkUsTUFBTSxDQUNaLEdBQUdrRixlQUFlLENBQUNULEtBQUssQ0FBQy9GLEdBQUcsQ0FBRXNHLFVBQVUsSUFBSztVQUM1QyxPQUFPM0MsMkJBQTJCLENBQ2pDMEMseUJBQXlCLENBQUNDLFVBQVUsQ0FBQyxFQUNyQ3BGLHNCQUFzQixFQUN0QjNELFNBQVMsRUFDVDRELFdBQVcsQ0FDWDtRQUNGLENBQUMsQ0FBQyxDQUNGO01BQ0YsS0FBSyxpQkFBaUI7UUFDckIsTUFBTXNGLFNBQVMsR0FBRzlDLDJCQUEyQixDQUM1QzBDLHlCQUF5QixDQUN4QkcsZUFBZSxDQUFDVCxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQ3hCLEVBQ0Q3RSxzQkFBc0IsRUFDdEIzRCxTQUFTLEVBQ1Q0RCxXQUFXLENBQ1g7UUFDRDtRQUNBLE9BQU9uQyxFQUFFLENBQUMsaUJBQWlCLEVBQUUsQ0FBQ3lILFNBQVMsRUFBRSxZQUFZLENBQUMsRUFBRWxKLFNBQVMsRUFBRSxJQUFJLENBQUM7TUFDekUsS0FBSyx1QkFBdUI7UUFDM0IsTUFBTW1KLFFBQVEsR0FBR0YsZUFBZSxDQUFDVCxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3pDLE1BQU1ZLGNBQWMsR0FBR0gsZUFBZSxDQUFDVCxLQUFLLENBQUNhLEtBQUssQ0FBQyxDQUFDLENBQWlEO1FBQ3JHLE1BQU1DLFlBQStELEdBQUcsQ0FBQyxDQUFDO1FBQzFFRixjQUFjLENBQUNqSCxPQUFPLENBQUU0RyxVQUFVLElBQUs7VUFDdENPLFlBQVksQ0FBQ1AsVUFBVSxDQUFDUSxLQUFLLENBQVcsR0FBR25ELDJCQUEyQixDQUNyRTBDLHlCQUF5QixDQUN4QkMsVUFBVSxDQUFDUyxlQUFlLENBQzFCLEVBQ0Q3RixzQkFBc0IsRUFDdEIzRCxTQUFTLEVBQ1Q0RCxXQUFXLENBQ1g7UUFDRixDQUFDLENBQUM7UUFDRixPQUFPbkMsRUFBRSxDQUFDLHVCQUF1QixFQUFFLENBQUMwSCxRQUFRLEVBQUVHLFlBQVksQ0FBQyxFQUFFdEosU0FBUyxFQUFFLElBQUksQ0FBQztJQUFDO0lBRWhGLE9BQU9SLHNCQUFzQjtFQUM5Qjs7RUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFSQTtFQVNBLFNBQVNpSyxVQUFVLENBQ2xCbkosUUFBNEIsRUFDNUJvSixXQUFxQyxFQUNyQ0MsWUFBc0MsRUFDRjtJQUNwQyxNQUFNQyxjQUFjLEdBQUcvRyxhQUFhLENBQUM2RyxXQUFXLENBQUM7SUFDakQsTUFBTUcsZUFBZSxHQUFHaEgsYUFBYSxDQUFDOEcsWUFBWSxDQUFDO0lBQ25ELElBQUkvSix5QkFBeUIsQ0FBQ2dLLGNBQWMsRUFBRUMsZUFBZSxDQUFDLEVBQUU7TUFDL0QsT0FBT3JLLHNCQUFzQjtJQUM5QjtJQUNBLElBQUkwRCxVQUFVLENBQUMwRyxjQUFjLENBQUMsSUFBSTFHLFVBQVUsQ0FBQzJHLGVBQWUsQ0FBQyxFQUFFO01BQzlELFFBQVF2SixRQUFRO1FBQ2YsS0FBSyxLQUFLO1VBQ1QsT0FBTzZDLFFBQVEsQ0FBQ3lHLGNBQWMsQ0FBQ3hKLEtBQUssS0FBS3lKLGVBQWUsQ0FBQ3pKLEtBQUssQ0FBQztRQUNoRSxLQUFLLEtBQUs7VUFDVCxPQUFPK0MsUUFBUSxDQUFDeUcsY0FBYyxDQUFDeEosS0FBSyxLQUFLeUosZUFBZSxDQUFDekosS0FBSyxDQUFDO1FBQ2hFLEtBQUssR0FBRztVQUNQLElBQ0N3SixjQUFjLENBQUN4SixLQUFLLEtBQUssSUFBSSxJQUM3QndKLGNBQWMsQ0FBQ3hKLEtBQUssS0FBS0osU0FBUyxJQUNsQzZKLGVBQWUsQ0FBQ3pKLEtBQUssS0FBSyxJQUFJLElBQzlCeUosZUFBZSxDQUFDekosS0FBSyxLQUFLSixTQUFTLEVBQ2xDO1lBQ0QsT0FBT21ELFFBQVEsQ0FBQyxLQUFLLENBQUM7VUFDdkI7VUFDQSxPQUFPQSxRQUFRLENBQUN5RyxjQUFjLENBQUN4SixLQUFLLEdBQUd5SixlQUFlLENBQUN6SixLQUFLLENBQUM7UUFDOUQsS0FBSyxJQUFJO1VBQ1IsSUFDQ3dKLGNBQWMsQ0FBQ3hKLEtBQUssS0FBSyxJQUFJLElBQzdCd0osY0FBYyxDQUFDeEosS0FBSyxLQUFLSixTQUFTLElBQ2xDNkosZUFBZSxDQUFDekosS0FBSyxLQUFLLElBQUksSUFDOUJ5SixlQUFlLENBQUN6SixLQUFLLEtBQUtKLFNBQVMsRUFDbEM7WUFDRCxPQUFPbUQsUUFBUSxDQUFDLEtBQUssQ0FBQztVQUN2QjtVQUNBLE9BQU9BLFFBQVEsQ0FBQ3lHLGNBQWMsQ0FBQ3hKLEtBQUssSUFBSXlKLGVBQWUsQ0FBQ3pKLEtBQUssQ0FBQztRQUMvRCxLQUFLLEdBQUc7VUFDUCxJQUNDd0osY0FBYyxDQUFDeEosS0FBSyxLQUFLLElBQUksSUFDN0J3SixjQUFjLENBQUN4SixLQUFLLEtBQUtKLFNBQVMsSUFDbEM2SixlQUFlLENBQUN6SixLQUFLLEtBQUssSUFBSSxJQUM5QnlKLGVBQWUsQ0FBQ3pKLEtBQUssS0FBS0osU0FBUyxFQUNsQztZQUNELE9BQU9tRCxRQUFRLENBQUMsS0FBSyxDQUFDO1VBQ3ZCO1VBQ0EsT0FBT0EsUUFBUSxDQUFDeUcsY0FBYyxDQUFDeEosS0FBSyxHQUFHeUosZUFBZSxDQUFDekosS0FBSyxDQUFDO1FBQzlELEtBQUssSUFBSTtVQUNSLElBQ0N3SixjQUFjLENBQUN4SixLQUFLLEtBQUssSUFBSSxJQUM3QndKLGNBQWMsQ0FBQ3hKLEtBQUssS0FBS0osU0FBUyxJQUNsQzZKLGVBQWUsQ0FBQ3pKLEtBQUssS0FBSyxJQUFJLElBQzlCeUosZUFBZSxDQUFDekosS0FBSyxLQUFLSixTQUFTLEVBQ2xDO1lBQ0QsT0FBT21ELFFBQVEsQ0FBQyxLQUFLLENBQUM7VUFDdkI7VUFDQSxPQUFPQSxRQUFRLENBQUN5RyxjQUFjLENBQUN4SixLQUFLLElBQUl5SixlQUFlLENBQUN6SixLQUFLLENBQUM7TUFBQztJQUVsRSxDQUFDLE1BQU07TUFDTixPQUFPO1FBQ05yQixLQUFLLEVBQUUsWUFBWTtRQUNuQnVCLFFBQVEsRUFBRUEsUUFBUTtRQUNsQlUsUUFBUSxFQUFFNEksY0FBYztRQUN4QjNJLFFBQVEsRUFBRTRJO01BQ1gsQ0FBQztJQUNGO0VBQ0Q7O0VBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFDTyxTQUFTckosTUFBTSxDQUNyQkUsVUFBdUUsRUFFcEM7SUFBQSxJQURuQ29KLGNBQWMsdUVBQUcsS0FBSztJQUV0QixJQUFJcEosVUFBVSxDQUFDM0IsS0FBSyxLQUFLLGNBQWMsRUFBRTtNQUN4QyxPQUFPMkIsVUFBVTtJQUNsQjtJQUNBLElBQUksQ0FBQ29KLGNBQWMsRUFBRTtNQUNwQixPQUFPO1FBQ04vSyxLQUFLLEVBQUUsUUFBUTtRQUNmc0MsV0FBVyxFQUFFWDtNQUNkLENBQUM7SUFDRjtJQUNBLE9BQU9tSSxNQUFNLENBQUNuQyxLQUFLLENBQUNoRyxVQUFVLEVBQUVWLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFUSxNQUFNLENBQUNFLFVBQVUsQ0FBQyxDQUFDO0VBQ3BFOztFQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFQQTtFQVFPLFNBQVNnRyxLQUFLLENBQ3BCZ0QsV0FBcUMsRUFDckNDLFlBQXNDLEVBQ0Y7SUFDcEMsTUFBTUMsY0FBYyxHQUFHL0csYUFBYSxDQUFDNkcsV0FBVyxDQUFDO0lBQ2pELE1BQU1HLGVBQWUsR0FBR2hILGFBQWEsQ0FBQzhHLFlBQVksQ0FBQztJQUNuRCxJQUFJL0oseUJBQXlCLENBQUNnSyxjQUFjLEVBQUVDLGVBQWUsQ0FBQyxFQUFFO01BQy9ELE9BQU9ySyxzQkFBc0I7SUFDOUI7SUFDQSxJQUFJUyx5QkFBeUIsQ0FBQzJKLGNBQWMsRUFBRUMsZUFBZSxDQUFDLEVBQUU7TUFDL0QsT0FBTzFHLFFBQVEsQ0FBQyxJQUFJLENBQUM7SUFDdEI7SUFFQSxTQUFTbkIsTUFBTSxDQUFDK0gsSUFBaUMsRUFBRUMsS0FBa0MsRUFBaUQ7TUFDckksSUFBSUQsSUFBSSxDQUFDaEwsS0FBSyxLQUFLLFlBQVksSUFBSXNFLE1BQU0sQ0FBQzJHLEtBQUssQ0FBQyxFQUFFO1FBQ2pEO1FBQ0EsT0FBT0QsSUFBSTtNQUNaLENBQUMsTUFBTSxJQUFJQSxJQUFJLENBQUNoTCxLQUFLLEtBQUssWUFBWSxJQUFJa0UsT0FBTyxDQUFDK0csS0FBSyxDQUFDLEVBQUU7UUFDekQ7UUFDQSxPQUFPdEgsR0FBRyxDQUFDcUgsSUFBSSxDQUFDO01BQ2pCLENBQUMsTUFBTSxJQUFJQSxJQUFJLENBQUNoTCxLQUFLLEtBQUssUUFBUSxJQUFJa0IseUJBQXlCLENBQUM4SixJQUFJLENBQUNqSixNQUFNLEVBQUVrSixLQUFLLENBQUMsRUFBRTtRQUNwRjtRQUNBLE9BQU8xRyxFQUFFLENBQUN5RyxJQUFJLENBQUNsSixTQUFTLEVBQUU2RixLQUFLLENBQUNxRCxJQUFJLENBQUNoSixPQUFPLEVBQUVpSixLQUFLLENBQUMsQ0FBQztNQUN0RCxDQUFDLE1BQU0sSUFBSUQsSUFBSSxDQUFDaEwsS0FBSyxLQUFLLFFBQVEsSUFBSWtCLHlCQUF5QixDQUFDOEosSUFBSSxDQUFDaEosT0FBTyxFQUFFaUosS0FBSyxDQUFDLEVBQUU7UUFDckY7UUFDQSxPQUFPMUcsRUFBRSxDQUFDWixHQUFHLENBQUNxSCxJQUFJLENBQUNsSixTQUFTLENBQUMsRUFBRTZGLEtBQUssQ0FBQ3FELElBQUksQ0FBQ2pKLE1BQU0sRUFBRWtKLEtBQUssQ0FBQyxDQUFDO01BQzFELENBQUMsTUFBTSxJQUNORCxJQUFJLENBQUNoTCxLQUFLLEtBQUssUUFBUSxJQUN2Qm1FLFVBQVUsQ0FBQzZHLElBQUksQ0FBQ2pKLE1BQU0sQ0FBQyxJQUN2Qm9DLFVBQVUsQ0FBQzZHLElBQUksQ0FBQ2hKLE9BQU8sQ0FBQyxJQUN4Qm1DLFVBQVUsQ0FBQzhHLEtBQUssQ0FBQyxJQUNqQixDQUFDL0oseUJBQXlCLENBQUM4SixJQUFJLENBQUNqSixNQUFNLEVBQUVrSixLQUFLLENBQUMsSUFDOUMsQ0FBQy9KLHlCQUF5QixDQUFDOEosSUFBSSxDQUFDaEosT0FBTyxFQUFFaUosS0FBSyxDQUFDLEVBQzlDO1FBQ0QsT0FBTzdHLFFBQVEsQ0FBQyxLQUFLLENBQUM7TUFDdkI7TUFDQSxPQUFPbkQsU0FBUztJQUNqQjs7SUFFQTtJQUNBLE1BQU1pSyxPQUFPLEdBQUdqSSxNQUFNLENBQUM0SCxjQUFjLEVBQUVDLGVBQWUsQ0FBQyxJQUFJN0gsTUFBTSxDQUFDNkgsZUFBZSxFQUFFRCxjQUFjLENBQUM7SUFDbEcsT0FBT0ssT0FBTyxJQUFJUixVQUFVLENBQUMsS0FBSyxFQUFFRyxjQUFjLEVBQUVDLGVBQWUsQ0FBQztFQUNyRTs7RUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBUEE7RUFRTyxTQUFTakQsUUFBUSxDQUN2QjhDLFdBQXFDLEVBQ3JDQyxZQUFzQyxFQUNGO0lBQ3BDLE9BQU9qSCxHQUFHLENBQUNnRSxLQUFLLENBQUNnRCxXQUFXLEVBQUVDLFlBQVksQ0FBQyxDQUFDO0VBQzdDOztFQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFQQTtFQVFPLFNBQVMzQyxjQUFjLENBQzdCMEMsV0FBcUMsRUFDckNDLFlBQXNDLEVBQ0Y7SUFDcEMsT0FBT0YsVUFBVSxDQUFDLElBQUksRUFBRUMsV0FBVyxFQUFFQyxZQUFZLENBQUM7RUFDbkQ7O0VBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQVBBO0VBUU8sU0FBUzdDLFdBQVcsQ0FDMUI0QyxXQUFxQyxFQUNyQ0MsWUFBc0MsRUFDRjtJQUNwQyxPQUFPRixVQUFVLENBQUMsR0FBRyxFQUFFQyxXQUFXLEVBQUVDLFlBQVksQ0FBQztFQUNsRDs7RUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBUEE7RUFRTyxTQUFTdkMsV0FBVyxDQUMxQnNDLFdBQXFDLEVBQ3JDQyxZQUFzQyxFQUNGO0lBQ3BDLE9BQU9GLFVBQVUsQ0FBQyxJQUFJLEVBQUVDLFdBQVcsRUFBRUMsWUFBWSxDQUFDO0VBQ25EOztFQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFQQTtFQVFPLFNBQVN6QyxRQUFRLENBQ3ZCd0MsV0FBcUMsRUFDckNDLFlBQXNDLEVBQ0Y7SUFDcEMsT0FBT0YsVUFBVSxDQUFDLEdBQUcsRUFBRUMsV0FBVyxFQUFFQyxZQUFZLENBQUM7RUFDbEQ7O0VBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQVZBO0VBV08sU0FBU2QsTUFBTSxDQUNyQmhJLFNBQXlDLEVBQ3pDQyxNQUFnQyxFQUNoQ0MsT0FBaUMsRUFDSDtJQUM5QixJQUFJbUosbUJBQW1CLEdBQUdySCxhQUFhLENBQUNoQyxTQUFTLENBQUM7SUFDbEQsSUFBSXNKLGdCQUFnQixHQUFHdEgsYUFBYSxDQUFDL0IsTUFBTSxDQUFDO0lBQzVDLElBQUlzSixpQkFBaUIsR0FBR3ZILGFBQWEsQ0FBQzlCLE9BQU8sQ0FBQzs7SUFFOUM7SUFDQSxJQUFJbUosbUJBQW1CLENBQUNuTCxLQUFLLEtBQUssS0FBSyxFQUFFO01BQ3hDO01BQ0EsQ0FBQ29MLGdCQUFnQixFQUFFQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUNBLGlCQUFpQixFQUFFRCxnQkFBZ0IsQ0FBQztNQUM3RUQsbUJBQW1CLEdBQUd4SCxHQUFHLENBQUN3SCxtQkFBbUIsQ0FBQztJQUMvQzs7SUFFQTtJQUNBO0lBQ0EsSUFBSUMsZ0JBQWdCLENBQUNwTCxLQUFLLEtBQUssUUFBUSxJQUFJa0IseUJBQXlCLENBQUNpSyxtQkFBbUIsRUFBRUMsZ0JBQWdCLENBQUN0SixTQUFTLENBQUMsRUFBRTtNQUN0SHNKLGdCQUFnQixHQUFHQSxnQkFBZ0IsQ0FBQ3JKLE1BQU07SUFDM0M7O0lBRUE7SUFDQTtJQUNBLElBQUlzSixpQkFBaUIsQ0FBQ3JMLEtBQUssS0FBSyxRQUFRLElBQUlrQix5QkFBeUIsQ0FBQ2lLLG1CQUFtQixFQUFFRSxpQkFBaUIsQ0FBQ3ZKLFNBQVMsQ0FBQyxFQUFFO01BQ3hIdUosaUJBQWlCLEdBQUdBLGlCQUFpQixDQUFDckosT0FBTztJQUM5Qzs7SUFFQTtJQUNBO0lBQ0EsSUFBSW1DLFVBQVUsQ0FBQ2dILG1CQUFtQixDQUFDLEVBQUU7TUFDcEMsT0FBT0EsbUJBQW1CLENBQUM5SixLQUFLLEdBQUcrSixnQkFBZ0IsR0FBR0MsaUJBQWlCO0lBQ3hFOztJQUVBO0lBQ0E7SUFDQTs7SUFFQTtJQUNBLElBQUluSyx5QkFBeUIsQ0FBQ2tLLGdCQUFnQixFQUFFQyxpQkFBaUIsQ0FBQyxFQUFFO01BQ25FLE9BQU9ELGdCQUFnQjtJQUN4Qjs7SUFFQTtJQUNBLElBQUlsSCxPQUFPLENBQUNtSCxpQkFBaUIsQ0FBQyxFQUFFO01BQy9CLE9BQU94SCxHQUFHLENBQUNzSCxtQkFBbUIsRUFBRUMsZ0JBQWdCLENBQXNDO0lBQ3ZGOztJQUVBO0lBQ0EsSUFBSTlHLE1BQU0sQ0FBQytHLGlCQUFpQixDQUFDLEVBQUU7TUFDOUIsT0FBTzlHLEVBQUUsQ0FBQ1osR0FBRyxDQUFDd0gsbUJBQW1CLENBQUMsRUFBRUMsZ0JBQWdCLENBQXNDO0lBQzNGOztJQUVBO0lBQ0EsSUFBSWxILE9BQU8sQ0FBQ2tILGdCQUFnQixDQUFDLEVBQUU7TUFDOUIsT0FBT3ZILEdBQUcsQ0FBQ0YsR0FBRyxDQUFDd0gsbUJBQW1CLENBQUMsRUFBRUUsaUJBQWlCLENBQXNDO0lBQzdGOztJQUVBO0lBQ0EsSUFBSS9HLE1BQU0sQ0FBQzhHLGdCQUFnQixDQUFDLEVBQUU7TUFDN0IsT0FBTzdHLEVBQUUsQ0FBQzRHLG1CQUFtQixFQUFFRSxpQkFBaUIsQ0FBc0M7SUFDdkY7SUFDQSxJQUFJeEsseUJBQXlCLENBQUNzSyxtQkFBbUIsRUFBRUMsZ0JBQWdCLEVBQUVDLGlCQUFpQixDQUFDLEVBQUU7TUFDeEYsT0FBTzVLLHNCQUFzQjtJQUM5QjtJQUNBLElBQUlrRyx1QkFBdUIsQ0FBQzdFLFNBQVMsQ0FBQyxJQUFJNkUsdUJBQXVCLENBQUM1RSxNQUFNLENBQUMsSUFBSTRFLHVCQUF1QixDQUFDM0UsT0FBTyxDQUFDLEVBQUU7TUFDOUcsSUFBSXNKLE9BQU8sR0FBRyxDQUFDO01BQ2YsTUFBTUMsa0JBQWtCLEdBQUdDLFlBQVksQ0FBQyxDQUFDMUosU0FBUyxFQUFFQyxNQUFNLEVBQUVDLE9BQU8sQ0FBQyxFQUFFLGlEQUFpRCxDQUFDO01BQ3hILE1BQU15SixRQUFRLEdBQUcsRUFBRTtNQUNuQkMsb0JBQW9CLENBQ25CSCxrQkFBa0IsRUFDbEIsYUFBYSxFQUNaSSxZQUE0QyxJQUFLO1FBQ2pERixRQUFRLENBQUNsSSxJQUFJLENBQUNvSSxZQUFZLENBQUM7UUFDM0IsT0FBT3JKLFdBQVcsQ0FBRSxJQUFHZ0osT0FBTyxFQUFHLEVBQUMsRUFBRSxHQUFHLENBQUM7TUFDekMsQ0FBQyxFQUNELElBQUksQ0FDSjtNQUNERyxRQUFRLENBQUNHLE9BQU8sQ0FBQ3hILFFBQVEsQ0FBQ3lILElBQUksQ0FBQ0MsU0FBUyxDQUFDUCxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7TUFDOUQsT0FBT0MsWUFBWSxDQUFDQyxRQUFRLEVBQUUsb0VBQW9FLEVBQUV4SyxTQUFTLEVBQUUsSUFBSSxDQUFDO0lBQ3JIO0lBQ0EsT0FBTztNQUNOakIsS0FBSyxFQUFFLFFBQVE7TUFDZjhCLFNBQVMsRUFBRXFKLG1CQUFtQjtNQUM5QnBKLE1BQU0sRUFBRXFKLGdCQUFnQjtNQUN4QnBKLE9BQU8sRUFBRXFKO0lBQ1YsQ0FBQztFQUNGOztFQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUxBO0VBTUEsU0FBU1UsNEJBQTRCLENBQUNwSyxVQUE2QyxFQUFXO0lBQzdGLFFBQVFBLFVBQVUsQ0FBQzNCLEtBQUs7TUFDdkIsS0FBSyxVQUFVO01BQ2YsS0FBSyxXQUFXO01BQ2hCLEtBQUssYUFBYTtRQUNqQixPQUFPLEtBQUs7TUFDYixLQUFLLEtBQUs7UUFDVCxPQUFPMkIsVUFBVSxDQUFDSCxRQUFRLENBQUNJLElBQUksQ0FBQ21LLDRCQUE0QixDQUFDO01BQzlELEtBQUssYUFBYTtRQUNqQixPQUFPcEssVUFBVSxDQUFDWSxTQUFTLEtBQUt0QixTQUFTO01BQzFDLEtBQUssWUFBWTtRQUNoQixPQUFPOEssNEJBQTRCLENBQUNwSyxVQUFVLENBQUNNLFFBQVEsQ0FBQyxJQUFJOEosNEJBQTRCLENBQUNwSyxVQUFVLENBQUNPLFFBQVEsQ0FBQztNQUM5RyxLQUFLLFFBQVE7UUFDWixPQUNDNkosNEJBQTRCLENBQUNwSyxVQUFVLENBQUNHLFNBQVMsQ0FBQyxJQUNsRGlLLDRCQUE0QixDQUFDcEssVUFBVSxDQUFDSSxNQUFNLENBQUMsSUFDL0NnSyw0QkFBNEIsQ0FBQ3BLLFVBQVUsQ0FBQ0ssT0FBTyxDQUFDO01BRWxELEtBQUssS0FBSztNQUNWLEtBQUssUUFBUTtRQUNaLE9BQU8rSiw0QkFBNEIsQ0FBQ3BLLFVBQVUsQ0FBQ0wsT0FBTyxDQUFDO01BQ3hEO1FBQ0MsT0FBTyxLQUFLO0lBQUM7RUFFaEI7O0VBRUE7RUFDQTs7RUF3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ08sU0FBU2tLLFlBQVksQ0FDM0I3SSxVQUF1QyxFQUN2Q3FKLGlCQUE2QixFQUM3QkMsaUJBQThCLEVBRUE7SUFBQSxJQUQ5QkMsaUJBQWlCLHVFQUFHLEtBQUs7SUFFekIsTUFBTUMsb0JBQW9CLEdBQUl4SixVQUFVLENBQTRDZSxHQUFHLENBQUNJLGFBQWEsQ0FBQztJQUV0RyxJQUFJakQseUJBQXlCLENBQUMsR0FBR3NMLG9CQUFvQixDQUFDLEVBQUU7TUFDdkQsT0FBTzFMLHNCQUFzQjtJQUM5QjtJQUNBLElBQUl3TCxpQkFBaUIsRUFBRTtNQUN0QjtNQUNBLElBQUksQ0FBQ0Usb0JBQW9CLENBQUN2SyxJQUFJLENBQUNtSyw0QkFBNEIsQ0FBQyxFQUFFO1FBQzdERSxpQkFBaUIsQ0FBQ0csSUFBSSxDQUFDaEosT0FBTyxDQUFFc0MsR0FBRyxJQUFLeUcsb0JBQW9CLENBQUM1SSxJQUFJLENBQUNqQixXQUFXLENBQUNvRCxHQUFHLENBQUN3QixJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztNQUM5RjtJQUNEO0lBQ0EsSUFBSW1GLFlBQVksR0FBRyxFQUFFO0lBQ3JCLElBQUksT0FBT0wsaUJBQWlCLEtBQUssUUFBUSxFQUFFO01BQzFDSyxZQUFZLEdBQUdMLGlCQUFpQjtJQUNqQyxDQUFDLE1BQU07TUFDTkssWUFBWSxHQUFHTCxpQkFBaUIsQ0FBQ00sY0FBYztJQUNoRDtJQUNBO0lBQ0EsTUFBTSxDQUFDQyxjQUFjLEVBQUVDLGFBQWEsQ0FBQyxHQUFHSCxZQUFZLENBQUNJLEtBQUssQ0FBQyxHQUFHLENBQUM7O0lBRS9EO0lBQ0EsSUFDQyxDQUFDUCxpQkFBaUIsS0FDakJDLG9CQUFvQixDQUFDdkssSUFBSSxDQUFDK0UsdUJBQXVCLENBQUMsSUFDbER3RixvQkFBb0IsQ0FBQ3ZLLElBQUksQ0FBQ2dGLGtCQUFrQixDQUFDLElBQzdDdUYsb0JBQW9CLENBQUN2SyxJQUFJLENBQUNpRixrQkFBa0IsQ0FBQyxDQUFDLEVBQzlDO01BQ0QsSUFBSXlFLE9BQU8sR0FBRyxDQUFDO01BQ2YsTUFBTW9CLGtCQUFrQixHQUFHbEIsWUFBWSxDQUFDVyxvQkFBb0IsRUFBRUUsWUFBWSxFQUFFcEwsU0FBUyxFQUFFLElBQUksQ0FBQztNQUM1RixNQUFNd0ssUUFBUSxHQUFHLEVBQUU7TUFDbkJDLG9CQUFvQixDQUNuQmdCLGtCQUFrQixFQUNsQixhQUFhLEVBQ1pmLFlBQTRDLElBQUs7UUFDakRGLFFBQVEsQ0FBQ2xJLElBQUksQ0FBQ29JLFlBQVksQ0FBQztRQUMzQixPQUFPckosV0FBVyxDQUFFLElBQUdnSixPQUFPLEVBQUcsRUFBQyxFQUFFLEdBQUcsQ0FBQztNQUN6QyxDQUFDLEVBQ0QsSUFBSSxDQUNKO01BQ0RHLFFBQVEsQ0FBQ0csT0FBTyxDQUFDeEgsUUFBUSxDQUFDeUgsSUFBSSxDQUFDQyxTQUFTLENBQUNZLGtCQUFrQixDQUFDLENBQUMsQ0FBQztNQUM5RCxPQUFPbEIsWUFBWSxDQUFDQyxRQUFRLEVBQUUsb0VBQW9FLEVBQUV4SyxTQUFTLEVBQUUsSUFBSSxDQUFDO0lBQ3JILENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQ3VMLGFBQWEsSUFBSUEsYUFBYSxDQUFDL0ssTUFBTSxHQUFHLENBQUMsRUFBRTtNQUN2RDBLLG9CQUFvQixDQUFDUCxPQUFPLENBQUN4SCxRQUFRLENBQUNvSSxhQUFhLENBQUMsQ0FBQztJQUN0RDtJQUVBLE9BQU87TUFDTnhNLEtBQUssRUFBRSxXQUFXO01BQ2xCMEMsRUFBRSxFQUFFNkosY0FBYztNQUNsQjVKLFVBQVUsRUFBRXdKO0lBQ2IsQ0FBQztFQUNGO0VBQUM7RUFZTSxTQUFTUSxnQkFBZ0IsQ0FBQ0MsYUFBb0MsRUFBRUMsUUFBb0MsRUFBc0I7SUFBQTtJQUNoSSxNQUFNMU0sV0FBK0IsR0FBRyxDQUFDLENBQUM7SUFDMUMsSUFBSXlNLGFBQWEsYUFBYkEsYUFBYSx3Q0FBYkEsYUFBYSxDQUFFek0sV0FBVyxrREFBMUIsc0JBQTRCRyxNQUFNLElBQUl1TSxRQUFRLENBQUNDLEtBQUssS0FBSzdMLFNBQVMsRUFBRTtNQUN2RWQsV0FBVyxDQUFDMk0sS0FBSyxHQUFHRCxRQUFRLENBQUNDLEtBQUs7SUFDbkM7SUFDQSxJQUFJRixhQUFhLGFBQWJBLGFBQWEseUNBQWJBLGFBQWEsQ0FBRXpNLFdBQVcsbURBQTFCLHVCQUE0QkMsVUFBVSxJQUFJeU0sUUFBUSxDQUFDRSxTQUFTLEtBQUs5TCxTQUFTLEVBQUU7TUFDL0VkLFdBQVcsQ0FBQzRNLFNBQVMsR0FBR0YsUUFBUSxDQUFDRSxTQUFTO0lBQzNDO0lBQ0EsSUFBSUgsYUFBYSxhQUFiQSxhQUFhLHlDQUFiQSxhQUFhLENBQUV6TSxXQUFXLG1EQUExQix1QkFBNEJJLFVBQVUsSUFBSXNNLFFBQVEsQ0FBQ0csU0FBUyxLQUFLL0wsU0FBUyxFQUFFO01BQy9FZCxXQUFXLENBQUM2TSxTQUFTLEdBQUdILFFBQVEsQ0FBQ0csU0FBUztJQUMzQztJQUNBLElBQUlILFFBQVEsQ0FBQ0ksUUFBUSxLQUFLLEtBQUssRUFBRTtNQUNoQzlNLFdBQVcsQ0FBQzhNLFFBQVEsR0FBRyxLQUFLO0lBQzdCO0lBQ0EsSUFBSUwsYUFBYSxhQUFiQSxhQUFhLHlDQUFiQSxhQUFhLENBQUV6TSxXQUFXLG1EQUExQix1QkFBNkIsMkNBQTJDLENBQUMsSUFBSSxDQUFDZ0csS0FBSywwQkFBQzBHLFFBQVEsQ0FBQ0ssV0FBVyxvRkFBcEIsc0JBQXNCQyxVQUFVLDJEQUFoQyx1QkFBa0NDLE9BQU8sQ0FBQyxFQUFFO01BQUE7TUFDbklqTixXQUFXLENBQUNrTixPQUFPLEdBQUksNkJBQUVSLFFBQVEsQ0FBQ0ssV0FBVyxxRkFBcEIsdUJBQXNCQyxVQUFVLDJEQUFoQyx1QkFBa0NDLE9BQVEsRUFBQztJQUNyRTtJQUNBLElBQUlSLGFBQWEsYUFBYkEsYUFBYSx5Q0FBYkEsYUFBYSxDQUFFek0sV0FBVyxtREFBMUIsdUJBQTZCLDJDQUEyQyxDQUFDLElBQUksQ0FBQ2dHLEtBQUssMkJBQUMwRyxRQUFRLENBQUNLLFdBQVcscUZBQXBCLHVCQUFzQkMsVUFBVSwyREFBaEMsdUJBQWtDRyxPQUFPLENBQUMsRUFBRTtNQUFBO01BQ25Jbk4sV0FBVyxDQUFDb04sT0FBTyxHQUFJLDZCQUFFVixRQUFRLENBQUNLLFdBQVcscUZBQXBCLHVCQUFzQkMsVUFBVSwyREFBaEMsdUJBQWtDRyxPQUFRLEVBQUM7SUFDckU7SUFDQSxJQUNDLDBCQUFBVCxRQUFRLENBQUNLLFdBQVcsOEVBQXBCLHVCQUFzQk0sTUFBTSxvREFBNUIsd0JBQThCQyxlQUFlLElBQzdDYixhQUFhLENBQUMxTSxJQUFJLEtBQUssZ0NBQWdDLElBQ3ZEME0sYUFBYSxhQUFiQSxhQUFhLHlDQUFiQSxhQUFhLENBQUV6TSxXQUFXLG1EQUExQix1QkFBNkIsaURBQWlELENBQUMsRUFDOUU7TUFDREEsV0FBVyxDQUFDdU4sZUFBZSxHQUFHLElBQUk7SUFDbkM7SUFDQSxJQUFJZCxhQUFhLGFBQWJBLGFBQWEseUNBQWJBLGFBQWEsQ0FBRXpNLFdBQVcsbURBQTFCLHVCQUE0QkUsR0FBRyxFQUFFO01BQ3BDRixXQUFXLENBQUN3TixFQUFFLEdBQUcsSUFBSTtJQUN0QjtJQUNBLE9BQU94TixXQUFXO0VBQ25COztFQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFQQTtFQVFPLFNBQVN5Tix5QkFBeUIsQ0FDeENmLFFBQW9DLEVBQ3BDZ0IseUJBQTJELEVBRWhDO0lBQUE7SUFBQSxJQUQzQkMsaUJBQWlCLHVFQUFHLEtBQUs7SUFFekIsTUFBTUMsYUFBNkMsR0FBR0YseUJBQTJEO0lBQ2pILElBQUloQixRQUFRLENBQUM3TSxLQUFLLEtBQUssVUFBVSxJQUFJNk0sUUFBUSxDQUFDN00sS0FBSyxLQUFLLGlCQUFpQixFQUFFO01BQzFFLE9BQU8rTixhQUFhO0lBQ3JCO0lBQ0EsTUFBTW5CLGFBQWEsR0FBRzNNLGdCQUFnQixDQUFDNE0sUUFBUSxDQUFDM00sSUFBSSxDQUFDO0lBQ3JELElBQUksQ0FBQzBNLGFBQWEsRUFBRTtNQUNuQixPQUFPbUIsYUFBYTtJQUNyQjtJQUNBLElBQUksQ0FBQ0EsYUFBYSxDQUFDQyxhQUFhLEVBQUU7TUFDakNELGFBQWEsQ0FBQ0MsYUFBYSxHQUFHLENBQUMsQ0FBQztJQUNqQztJQUNBRCxhQUFhLENBQUM1TixXQUFXLEdBQUcsQ0FBQyxDQUFDO0lBRTlCNE4sYUFBYSxDQUFDN04sSUFBSSxHQUFHME0sYUFBYSxDQUFDMU0sSUFBSTtJQUN2QyxJQUFJLENBQUM0TixpQkFBaUIsRUFBRTtNQUN2QkMsYUFBYSxDQUFDNU4sV0FBVyxHQUFHd00sZ0JBQWdCLENBQUNDLGFBQWEsRUFBRUMsUUFBUSxDQUFDO0lBQ3RFO0lBRUEsSUFDRSxDQUFBa0IsYUFBYSxhQUFiQSxhQUFhLDhDQUFiQSxhQUFhLENBQUU3TixJQUFJLHdEQUFuQixvQkFBcUIrTixPQUFPLENBQUMsNkJBQTZCLENBQUMsTUFBSyxDQUFDLElBQUksQ0FBQUYsYUFBYSxhQUFiQSxhQUFhLHVCQUFiQSxhQUFhLENBQUU3TixJQUFJLE1BQUssK0JBQStCLElBQzdILENBQUE2TixhQUFhLGFBQWJBLGFBQWEsdUJBQWJBLGFBQWEsQ0FBRTdOLElBQUksTUFBSyxnQ0FBZ0MsRUFDdkQ7TUFDRDZOLGFBQWEsQ0FBQ0MsYUFBYSxHQUFHekksTUFBTSxDQUFDMkksTUFBTSxDQUFDSCxhQUFhLENBQUNDLGFBQWEsRUFBRTtRQUN4RUcsYUFBYSxFQUFFO01BQ2hCLENBQUMsQ0FBQztJQUNIO0lBQ0EsSUFBSUosYUFBYSxDQUFDN04sSUFBSSxLQUFLLGdDQUFnQyxJQUFJSixVQUFVLENBQUMrTSxRQUFRLENBQUMsRUFBRTtNQUFBO01BQ3BGLElBQUksMkJBQUNrQixhQUFhLENBQUM1TixXQUFXLGtEQUF6QixzQkFBMkJ1TixlQUFlLEtBQUksMkJBQUFLLGFBQWEsQ0FBQzVOLFdBQVcsMkRBQXpCLHVCQUEyQjhNLFFBQVEsTUFBSyxLQUFLLEVBQUU7UUFDakdjLGFBQWEsQ0FBQ0MsYUFBYSxDQUFDSSxxQkFBcUIsR0FBRyxJQUFJO01BQ3pEO01BQ0EsTUFBTUMsVUFBVSxHQUFHQyxhQUFhLENBQUN6QixRQUFRLENBQUM7TUFDMUMsSUFBSXdCLFVBQVUsRUFBRTtRQUNmTixhQUFhLENBQUNDLGFBQWEsQ0FBQ0ssVUFBVSxHQUFHQSxVQUFVO1FBQ25ETixhQUFhLENBQUM3TixJQUFJLEdBQUcsNkJBQTZCO01BQ25EO0lBQ0Q7SUFDQSxNQUFNcU8sb0NBQW9DLEdBQUcsQ0FDNUMsK0JBQStCLEVBQy9CLCtCQUErQixFQUMvQiwrQkFBK0IsRUFDL0IsZ0NBQWdDLEVBQ2hDLGdDQUFnQyxFQUNoQyxpQ0FBaUMsRUFDakMsOEJBQThCLEVBQzlCLCtCQUErQixDQUMvQjtJQUNELElBQ0MsMkJBQUFSLGFBQWEsQ0FBQzVOLFdBQVcsMkRBQXpCLHVCQUEyQjhNLFFBQVEsTUFBSyxLQUFLLElBQzdDYyxhQUFhLENBQUM3TixJQUFJLElBQ2xCcU8sb0NBQW9DLENBQUNDLFFBQVEsQ0FBQ1QsYUFBYSxDQUFDN04sSUFBSSxDQUFDLEVBQ2hFO01BQ0Q2TixhQUFhLENBQUNDLGFBQWEsR0FBR3pJLE1BQU0sQ0FBQzJJLE1BQU0sQ0FBQ0gsYUFBYSxDQUFDQyxhQUFhLEVBQUU7UUFDeEVTLHFCQUFxQixFQUFFO01BQ3hCLENBQUMsQ0FBQztJQUNIO0lBQ0EsSUFDQywyQkFBQVYsYUFBYSxDQUFDNU4sV0FBVywyREFBekIsdUJBQTJCOE0sUUFBUSxNQUFLLEtBQUssS0FDNUNjLGFBQWEsQ0FBQzdOLElBQUksS0FBSywrQkFBK0IsSUFBSTZOLGFBQWEsQ0FBQzdOLElBQUksS0FBSyxpQ0FBaUMsQ0FBQyxFQUNuSDtNQUNENk4sYUFBYSxDQUFDQyxhQUFhLEdBQUd6SSxNQUFNLENBQUMySSxNQUFNLENBQUNILGFBQWEsQ0FBQ0MsYUFBYSxFQUFFO1FBQ3hFVSxXQUFXLEVBQUU7TUFDZCxDQUFDLENBQUM7SUFDSDtJQUVBLE9BQU9YLGFBQWE7RUFDckI7RUFBQztFQUVNLE1BQU1PLGFBQWEsR0FBRyxVQUFVekIsUUFBa0IsRUFBc0I7SUFBQTtJQUM5RSwrQkFBSUEsUUFBUSxDQUFDSyxXQUFXLCtFQUFwQix3QkFBc0JNLE1BQU0sb0RBQTVCLHdCQUE4Qm1CLFlBQVksRUFBRTtNQUMvQztJQUNEO0lBQ0EsK0JBQUk5QixRQUFRLENBQUNLLFdBQVcsK0VBQXBCLHdCQUFzQk0sTUFBTSxvREFBNUIsd0JBQThCb0IsY0FBYyxFQUFFO01BQ2pEO0lBQ0Q7SUFDQSwrQkFBSS9CLFFBQVEsQ0FBQ0ssV0FBVywrRUFBcEIsd0JBQXNCTSxNQUFNLG9EQUE1Qix3QkFBOEJxQixrQkFBa0IsRUFBRTtNQUNyRDtJQUNEO0lBQ0EsK0JBQUloQyxRQUFRLENBQUNLLFdBQVcsK0VBQXBCLHdCQUFzQk0sTUFBTSxvREFBNUIsd0JBQThCc0IsZUFBZSxFQUFFO01BQ2xEO0lBQ0Q7SUFDQSwrQkFBSWpDLFFBQVEsQ0FBQ0ssV0FBVywrRUFBcEIsd0JBQXNCTSxNQUFNLG9EQUE1Qix3QkFBOEJ1QixtQkFBbUIsRUFBRTtNQUN0RDtJQUNEO0lBQ0EsK0JBQUlsQyxRQUFRLENBQUNLLFdBQVcsK0VBQXBCLHdCQUFzQk0sTUFBTSxvREFBNUIsd0JBQThCd0IsWUFBWSxFQUFFO01BQy9DO0lBQ0Q7SUFDQSwrQkFBSW5DLFFBQVEsQ0FBQ0ssV0FBVywrRUFBcEIsd0JBQXNCTSxNQUFNLG9EQUE1Qix3QkFBOEJ5QixnQkFBZ0IsRUFBRTtNQUNuRDtJQUNEO0lBQ0EsK0JBQUlwQyxRQUFRLENBQUNLLFdBQVcsK0VBQXBCLHdCQUFzQk0sTUFBTSxvREFBNUIsd0JBQThCMEIsaUJBQWlCLEVBQUU7TUFDcEQ7SUFDRDtFQUNELENBQUM7O0VBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBWEE7RUFZTyxTQUFTQyxrQkFBa0IsQ0FDakN4TSxVQUF1QyxFQUN2Q3pDLElBQVksRUFDWitMLGlCQUE4QixFQUM5Qm1ELGNBQXlDLEVBQ3VDO0lBQ2hGLE1BQU1qRCxvQkFBb0IsR0FBSXhKLFVBQVUsQ0FBNENlLEdBQUcsQ0FBQ0ksYUFBYSxDQUFDO0lBQ3RHLElBQUlqRCx5QkFBeUIsQ0FBQyxHQUFHc0wsb0JBQW9CLENBQUMsRUFBRTtNQUN2RCxPQUFPMUwsc0JBQXNCO0lBQzlCO0lBQ0E7SUFDQSxJQUFJMEwsb0JBQW9CLENBQUMxSyxNQUFNLEtBQUssQ0FBQyxJQUFJMEMsVUFBVSxDQUFDZ0ksb0JBQW9CLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDRixpQkFBaUIsRUFBRTtNQUNuRyxPQUFPRSxvQkFBb0IsQ0FBQyxDQUFDLENBQUM7SUFDL0IsQ0FBQyxNQUFNLElBQUlGLGlCQUFpQixFQUFFO01BQzdCO01BQ0EsSUFBSSxDQUFDRSxvQkFBb0IsQ0FBQ3ZLLElBQUksQ0FBQ21LLDRCQUE0QixDQUFDLEVBQUU7UUFDN0RFLGlCQUFpQixDQUFDRyxJQUFJLENBQUNoSixPQUFPLENBQUVzQyxHQUFHLElBQUt5RyxvQkFBb0IsQ0FBQzVJLElBQUksQ0FBQ2pCLFdBQVcsQ0FBQ29ELEdBQUcsQ0FBQ3dCLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO01BQzlGO0lBQ0Q7SUFDQWtJLGNBQWMsR0FBR0MsMENBQTBDLENBQUMxTSxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUV5TSxjQUFjLENBQUM7SUFFMUYsSUFBSWxQLElBQUksS0FBSyw4QkFBOEIsRUFBRTtNQUM1QyxNQUFNb1AsT0FBTyxHQUFHaE4sV0FBVyxDQUFDLDRCQUE0QixDQUFDO01BQ3pEZ04sT0FBTyxDQUFDeEosVUFBVSxHQUFHLEtBQUs7TUFDMUJ3SixPQUFPLENBQUNDLElBQUksR0FBRyxTQUFTO01BQ3hCcEQsb0JBQW9CLENBQUM1SSxJQUFJLENBQUMrTCxPQUFPLENBQUM7SUFDbkMsQ0FBQyxNQUFNLElBQUlwUCxJQUFJLEtBQUssa0NBQWtDLEVBQUU7TUFDdkQsTUFBTXNQLFlBQVksR0FBR2xOLFdBQVcsQ0FBQywyQkFBMkIsQ0FBQztNQUM3RGtOLFlBQVksQ0FBQzFKLFVBQVUsR0FBRyxLQUFLO01BQy9CMEosWUFBWSxDQUFDRCxJQUFJLEdBQUcsU0FBUztNQUM3QnBELG9CQUFvQixDQUFDNUksSUFBSSxDQUFDaU0sWUFBWSxDQUFDO0lBQ3hDO0lBRUEsT0FBTztNQUNOeFAsS0FBSyxFQUFFLGFBQWE7TUFDcEJFLElBQUksRUFBRUEsSUFBSTtNQUNWOE4sYUFBYSxFQUFFb0IsY0FBYyxJQUFJLENBQUMsQ0FBQztNQUNuQ3pNLFVBQVUsRUFBRSxDQUFDLENBQUM7TUFDZEMsaUJBQWlCLEVBQUV1SjtJQUNwQixDQUFDO0VBQ0Y7RUFBQztFQWFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ0EsU0FBU2tELDBDQUEwQyxDQUNsREksS0FBb0IsRUFDcEJ6QixhQUFtRCxFQUNaO0lBQUE7SUFDdkM7SUFDQTtJQUNBLElBQ0MsRUFBRUEsYUFBYSxJQUFJQSxhQUFhLENBQUMwQixVQUFVLEtBQUssS0FBSyxDQUFDLEtBQ3JELENBQUFELEtBQUssYUFBTEEsS0FBSyxzQ0FBTEEsS0FBSyxDQUFFdlAsSUFBSSxnREFBWCxZQUFhK04sT0FBTyxDQUFDLDZCQUE2QixDQUFDLE1BQUssQ0FBQyxJQUN6RCxDQUFBd0IsS0FBSyxhQUFMQSxLQUFLLHVCQUFMQSxLQUFLLENBQUV2UCxJQUFJLE1BQUssaUNBQWlDLElBQ2pELENBQUF1UCxLQUFLLGFBQUxBLEtBQUssdUJBQUxBLEtBQUssQ0FBRXZQLElBQUksTUFBSyxnQ0FBZ0MsQ0FBQyxFQUNqRDtNQUNELElBQUksQ0FBQXVQLEtBQUssYUFBTEEsS0FBSyx1QkFBTEEsS0FBSyxDQUFFdlAsSUFBSSxNQUFLLCtCQUErQixJQUFJLENBQUF1UCxLQUFLLGFBQUxBLEtBQUssdUJBQUxBLEtBQUssQ0FBRXZQLElBQUksTUFBSyxpQ0FBaUMsRUFBRTtRQUFBO1FBQ3pHO1FBQ0E4TixhQUFhLEdBQUcsbUJBQUFBLGFBQWEsbURBQWIsZUFBZTJCLFdBQVcsTUFBSyxLQUFLLEdBQUc7VUFBRUEsV0FBVyxFQUFFO1FBQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztNQUNuRixDQUFDLE1BQU07UUFBQTtRQUNOM0IsYUFBYSxHQUFHLG9CQUFBQSxhQUFhLG9EQUFiLGdCQUFlMkIsV0FBVyxNQUFLLEtBQUssR0FBRztVQUFFeEIsYUFBYSxFQUFFLEtBQUs7VUFBRXdCLFdBQVcsRUFBRTtRQUFNLENBQUMsR0FBRztVQUFFeEIsYUFBYSxFQUFFO1FBQU0sQ0FBQztNQUMvSDtNQUNBSCxhQUFhLENBQUNVLFdBQVcsR0FBRyxJQUFJO0lBQ2pDO0lBQ0EsT0FBT1YsYUFBYTtFQUNyQjtFQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNPLFNBQVN0TCxFQUFFLENBQ2pCa04sSUFBTyxFQUNQak4sVUFBa0QsRUFDbERrTixFQUFrQyxFQUVWO0lBQUEsSUFEeEJDLGNBQWMsdUVBQUcsS0FBSztJQUV0QixNQUFNekQsWUFBWSxHQUFHLE9BQU91RCxJQUFJLEtBQUssUUFBUSxHQUFHQSxJQUFJLEdBQUdBLElBQUksQ0FBQ3RELGNBQWM7SUFDMUUsT0FBTztNQUNOdE0sS0FBSyxFQUFFLFVBQVU7TUFDakI4QyxHQUFHLEVBQUUrTSxFQUFFLEtBQUs1TyxTQUFTLEdBQUc2QyxhQUFhLENBQUMrTCxFQUFFLENBQUMsR0FBRzVPLFNBQVM7TUFDckR5QixFQUFFLEVBQUUySixZQUFZO01BQ2hCeUQsY0FBYyxFQUFFQSxjQUFjO01BQzlCbk4sVUFBVSxFQUFHQSxVQUFVLENBQTRDZSxHQUFHLENBQUNJLGFBQWE7SUFDckYsQ0FBQztFQUNGOztFQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUxBO0VBTU8sU0FBU2lNLE9BQU8sQ0FBQ3BPLFVBQTRDLEVBQXFDO0lBQ3hHLE1BQU1xTyxTQUEyQyxHQUFHLEVBQUU7SUFDdER0RSxvQkFBb0IsQ0FBQy9KLFVBQVUsRUFBRSxhQUFhLEVBQUdYLElBQUksSUFBSztNQUN6RGdQLFNBQVMsQ0FBQ3pNLElBQUksQ0FBQ2dCLEVBQUUsQ0FBQ29ELEtBQUssQ0FBQzNHLElBQUksRUFBRSxFQUFFLENBQUMsRUFBRTJHLEtBQUssQ0FBQzNHLElBQUksRUFBRUMsU0FBUyxDQUFDLEVBQUUwRyxLQUFLLENBQUMzRyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztNQUM5RSxPQUFPQSxJQUFJO0lBQ1osQ0FBQyxDQUFDO0lBQ0YsT0FBTzZDLEdBQUcsQ0FBQyxHQUFHbU0sU0FBUyxDQUFDO0VBQ3pCO0VBQUM7RUFFTSxTQUFTaEwsTUFBTSxHQUFzRjtJQUFBLG1DQUFsRmlMLGFBQWE7TUFBYkEsYUFBYTtJQUFBO0lBQ3RDLE1BQU1uUCxXQUFXLEdBQUdtUCxhQUFhLENBQUN2TSxHQUFHLENBQUNJLGFBQWEsQ0FBQztJQUNwRCxJQUFJakQseUJBQXlCLENBQUMsR0FBR0MsV0FBVyxDQUFDLEVBQUU7TUFDOUMsT0FBT0wsc0JBQXNCO0lBQzlCO0lBQ0EsSUFBSUssV0FBVyxDQUFDWSxLQUFLLENBQUN5QyxVQUFVLENBQUMsRUFBRTtNQUNsQyxPQUFPQyxRQUFRLENBQ2R0RCxXQUFXLENBQUNtQyxNQUFNLENBQUMsQ0FBQ2lOLFlBQW9CLEVBQUU3TyxLQUFLLEtBQUs7UUFDbkQsSUFBSUEsS0FBSyxDQUFDQSxLQUFLLEtBQUtKLFNBQVMsSUFBSUksS0FBSyxDQUFDQSxLQUFLLEtBQUssSUFBSSxFQUFFO1VBQ3RELE9BQU82TyxZQUFZLEdBQUc3TyxLQUFLLENBQUNBLEtBQUssQ0FBQzhPLFFBQVEsRUFBRTtRQUM3QztRQUNBLE9BQU9ELFlBQVk7TUFDcEIsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUNOO0lBQ0YsQ0FBQyxNQUFNLElBQUlwUCxXQUFXLENBQUNjLElBQUksQ0FBQytFLHVCQUF1QixDQUFDLEVBQUU7TUFDckQsSUFBSTJFLE9BQU8sR0FBRyxDQUFDO01BQ2YsTUFBTThFLGtCQUFrQixHQUFHNUUsWUFBWSxDQUFDMUssV0FBVyxFQUFFLGlEQUFpRCxFQUFFRyxTQUFTLEVBQUUsSUFBSSxDQUFDO01BQ3hILE1BQU13SyxRQUFRLEdBQUcsRUFBRTtNQUNuQkMsb0JBQW9CLENBQUMwRSxrQkFBa0IsRUFBRSxhQUFhLEVBQUd6RSxZQUE0QyxJQUFLO1FBQ3pHRixRQUFRLENBQUNsSSxJQUFJLENBQUNvSSxZQUFZLENBQUM7UUFDM0IsT0FBT3JKLFdBQVcsQ0FBRSxJQUFHZ0osT0FBTyxFQUFHLEVBQUMsRUFBRSxHQUFHLENBQUM7TUFDekMsQ0FBQyxDQUFDO01BQ0ZHLFFBQVEsQ0FBQ0csT0FBTyxDQUFDeEgsUUFBUSxDQUFDeUgsSUFBSSxDQUFDQyxTQUFTLENBQUNzRSxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7TUFDOUQsT0FBTzVFLFlBQVksQ0FBQ0MsUUFBUSxFQUFFLG9FQUFvRSxFQUFFeEssU0FBUyxFQUFFLElBQUksQ0FBQztJQUNySDtJQUNBLE9BQU87TUFDTmpCLEtBQUssRUFBRSxRQUFRO01BQ2ZjLFdBQVcsRUFBRUE7SUFDZCxDQUFDO0VBQ0Y7RUFBQztFQWNNLFNBQVM0SyxvQkFBb0IsQ0FDbkMyRSxZQUF5QyxFQUN6Q0MsY0FBa0IsRUFDbEJDLGlCQUEwRSxFQUU1QztJQUFBLElBRDlCQyxvQkFBb0IsdUVBQUcsS0FBSztJQUU1QixJQUFJN08sVUFBdUMsR0FBRzBPLFlBQVk7SUFDMUQsUUFBUTFPLFVBQVUsQ0FBQzNCLEtBQUs7TUFDdkIsS0FBSyxVQUFVO01BQ2YsS0FBSyxXQUFXO1FBQ2YyQixVQUFVLENBQUNnQixVQUFVLEdBQUdoQixVQUFVLENBQUNnQixVQUFVLENBQUNlLEdBQUcsQ0FBRXlHLFNBQVMsSUFDM0R1QixvQkFBb0IsQ0FBQ3ZCLFNBQVMsRUFBaUNtRyxjQUFjLEVBQUVDLGlCQUFpQixFQUFFQyxvQkFBb0IsQ0FBQyxDQUN2SDtRQUNEO01BQ0QsS0FBSyxRQUFRO1FBQ1o3TyxVQUFVLENBQUNiLFdBQVcsR0FBR2EsVUFBVSxDQUFDYixXQUFXLENBQUM0QyxHQUFHLENBQUUrTSxhQUFhLElBQ2pFL0Usb0JBQW9CLENBQ25CK0UsYUFBYSxFQUNiSCxjQUFjLEVBQ2RDLGlCQUFpQixFQUNqQkMsb0JBQW9CLENBQ3BCLENBQ0Q7UUFDRDdPLFVBQVUsR0FBR3FELE1BQU0sQ0FBQyxHQUFHckQsVUFBVSxDQUFDYixXQUFXLENBQWdDO1FBQzdFO01BQ0QsS0FBSyxhQUFhO1FBQ2pCYSxVQUFVLENBQUNpQixpQkFBaUIsR0FBR2pCLFVBQVUsQ0FBQ2lCLGlCQUFpQixDQUFDYyxHQUFHLENBQUVnTixnQkFBZ0IsSUFDaEZoRixvQkFBb0IsQ0FDbkJnRixnQkFBZ0IsRUFDaEJKLGNBQWMsRUFDZEMsaUJBQWlCLEVBQ2pCQyxvQkFBb0IsQ0FDcEIsQ0FDRDtRQUNEO01BQ0QsS0FBSyxRQUFRO1FBQ1osTUFBTXpPLE1BQU0sR0FBRzJKLG9CQUFvQixDQUNsQy9KLFVBQVUsQ0FBQ0ksTUFBTSxFQUNqQnVPLGNBQWMsRUFDZEMsaUJBQWlCLEVBQ2pCQyxvQkFBb0IsQ0FDcEI7UUFDRCxNQUFNeE8sT0FBTyxHQUFHMEosb0JBQW9CLENBQ25DL0osVUFBVSxDQUFDSyxPQUFPLEVBQ2xCc08sY0FBYyxFQUNkQyxpQkFBaUIsRUFDakJDLG9CQUFvQixDQUNwQjtRQUNELElBQUkxTyxTQUFTLEdBQUdILFVBQVUsQ0FBQ0csU0FBUztRQUNwQyxJQUFJME8sb0JBQW9CLEVBQUU7VUFDekIxTyxTQUFTLEdBQUc0SixvQkFBb0IsQ0FDL0IvSixVQUFVLENBQUNHLFNBQVMsRUFDcEJ3TyxjQUFjLEVBQ2RDLGlCQUFpQixFQUNqQkMsb0JBQW9CLENBQ3BCO1FBQ0Y7UUFDQTdPLFVBQVUsR0FBR21JLE1BQU0sQ0FBQ2hJLFNBQVMsRUFBRUMsTUFBTSxFQUFFQyxPQUFPLENBQWdDO1FBQzlFO01BQ0QsS0FBSyxLQUFLO1FBQ1QsSUFBSXdPLG9CQUFvQixFQUFFO1VBQ3pCLE1BQU1sUCxPQUFPLEdBQUdvSyxvQkFBb0IsQ0FDbkMvSixVQUFVLENBQUNMLE9BQU8sRUFDbEJnUCxjQUFjLEVBQ2RDLGlCQUFpQixFQUNqQkMsb0JBQW9CLENBQ3BCO1VBQ0Q3TyxVQUFVLEdBQUdnQyxHQUFHLENBQUNyQyxPQUFPLENBQWdDO1FBQ3pEO1FBQ0E7TUFDRCxLQUFLLFFBQVE7UUFDWjtNQUNELEtBQUssS0FBSztRQUNULElBQUlrUCxvQkFBb0IsRUFBRTtVQUN6QixNQUFNaFAsUUFBUSxHQUFHRyxVQUFVLENBQUNILFFBQVEsQ0FBQ2tDLEdBQUcsQ0FBRXBDLE9BQU8sSUFDaERvSyxvQkFBb0IsQ0FDbkJwSyxPQUFPLEVBQ1BnUCxjQUFjLEVBQ2RDLGlCQUFpQixFQUNqQkMsb0JBQW9CLENBQ3BCLENBQ0Q7VUFDRDdPLFVBQVUsR0FDVEEsVUFBVSxDQUFDSixRQUFRLEtBQUssSUFBSSxHQUN4QmdELEVBQUUsQ0FBQyxHQUFHL0MsUUFBUSxDQUFDLEdBQ2ZxQyxHQUFHLENBQUMsR0FBR3JDLFFBQVEsQ0FBaUM7UUFDdEQ7UUFDQTtNQUNELEtBQUssWUFBWTtRQUNoQixJQUFJZ1Asb0JBQW9CLEVBQUU7VUFDekIsTUFBTXZPLFFBQVEsR0FBR3lKLG9CQUFvQixDQUNwQy9KLFVBQVUsQ0FBQ00sUUFBUSxFQUNuQnFPLGNBQWMsRUFDZEMsaUJBQWlCLEVBQ2pCQyxvQkFBb0IsQ0FDcEI7VUFDRCxNQUFNdE8sUUFBUSxHQUFHd0osb0JBQW9CLENBQ3BDL0osVUFBVSxDQUFDTyxRQUFRLEVBQ25Cb08sY0FBYyxFQUNkQyxpQkFBaUIsRUFDakJDLG9CQUFvQixDQUNwQjtVQUNEN08sVUFBVSxHQUFHK0ksVUFBVSxDQUFDL0ksVUFBVSxDQUFDSixRQUFRLEVBQUVVLFFBQVEsRUFBRUMsUUFBUSxDQUFnQztRQUNoRztRQUNBO01BQ0QsS0FBSyxVQUFVO1FBQ2QsTUFBTWdELGFBQWdFLEdBQUd2RCxVQUFVLENBQUNOLEtBR25GO1FBQ0QsSUFBSSxPQUFPNkQsYUFBYSxLQUFLLFFBQVEsSUFBSUEsYUFBYSxFQUFFO1VBQ3ZESyxNQUFNLENBQUM2RyxJQUFJLENBQUNsSCxhQUFhLENBQUMsQ0FBQzlCLE9BQU8sQ0FBRXNDLEdBQUcsSUFBSztZQUMzQ1IsYUFBYSxDQUFDUSxHQUFHLENBQUMsR0FBR2dHLG9CQUFvQixDQUN4Q3hHLGFBQWEsQ0FBQ1EsR0FBRyxDQUFDLEVBQ2xCNEssY0FBYyxFQUNkQyxpQkFBaUIsRUFDakJDLG9CQUFvQixDQUNwQjtVQUNGLENBQUMsQ0FBQztRQUNIO1FBQ0E7TUFDRCxLQUFLLEtBQUs7TUFDVixLQUFLLFFBQVE7TUFDYixLQUFLLGFBQWE7TUFDbEIsS0FBSyxpQkFBaUI7TUFDdEIsS0FBSywyQkFBMkI7TUFDaEMsS0FBSyxjQUFjO1FBQ2xCO1FBQ0E7SUFBTTtJQUVSLElBQUlGLGNBQWMsS0FBSzNPLFVBQVUsQ0FBQzNCLEtBQUssRUFBRTtNQUN4QzJCLFVBQVUsR0FBRzRPLGlCQUFpQixDQUFDRixZQUFZLENBQXNDO0lBQ2xGO0lBQ0EsT0FBTzFPLFVBQVU7RUFDbEI7RUFBQztFQUlELE1BQU1nUCxlQUFlLEdBQUcsVUFBbUMzUCxJQUE4QixFQUFXO0lBQ25HLE9BQ0MsQ0FBQ21ELFVBQVUsQ0FBQ25ELElBQUksQ0FBQyxJQUNqQixDQUFDeUYsdUJBQXVCLENBQUN6RixJQUFJLENBQUMsSUFDOUJ1RiwwQkFBMEIsQ0FBQ3ZGLElBQUksQ0FBQyxJQUNoQ0EsSUFBSSxDQUFDaEIsS0FBSyxLQUFLLFFBQVEsSUFDdkJnQixJQUFJLENBQUNoQixLQUFLLEtBQUssVUFBVTtFQUUzQixDQUFDOztFQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ0EsU0FBUzRRLHFCQUFxQixDQUFDNVAsSUFBZ0MsRUFBOEI7SUFBQSxJQUE1QjZQLFVBQVUsdUVBQUcsS0FBSztJQUNsRixJQUFJQSxVQUFVLElBQUl0TCxNQUFNLENBQUM2RyxJQUFJLENBQUNwTCxJQUFJLENBQUNLLEtBQUssQ0FBQyxDQUFDSSxNQUFNLEtBQUssQ0FBQyxFQUFFO01BQ3ZELE9BQU8sRUFBRTtJQUNWO0lBQ0EsTUFBTXFQLE9BQU8sR0FBRzlQLElBQUksQ0FBQ0ssS0FBOEI7SUFDbkQsTUFBTTBQLFVBQW9CLEdBQUcsRUFBRTtJQUMvQnhMLE1BQU0sQ0FBQzZHLElBQUksQ0FBQzBFLE9BQU8sQ0FBQyxDQUFDMU4sT0FBTyxDQUFFc0MsR0FBRyxJQUFLO01BQ3JDLE1BQU1yRSxLQUFLLEdBQUd5UCxPQUFPLENBQUNwTCxHQUFHLENBQUM7TUFDMUIsTUFBTXNMLFdBQVcsR0FBR0MsaUJBQWlCLENBQUM1UCxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRXdQLFVBQVUsQ0FBQztNQUNyRSxJQUFJRyxXQUFXLElBQUlBLFdBQVcsQ0FBQ3ZQLE1BQU0sR0FBRyxDQUFDLEVBQUU7UUFDMUNzUCxVQUFVLENBQUN4TixJQUFJLENBQUUsR0FBRW1DLEdBQUksS0FBSXNMLFdBQVksRUFBQyxDQUFDO01BQzFDO0lBQ0QsQ0FBQyxDQUFDO0lBQ0YsT0FBUSxJQUFHRCxVQUFVLENBQUM5TCxJQUFJLENBQUMsSUFBSSxDQUFFLEdBQUU7RUFDcEM7O0VBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztFQWFPLFNBQVNpTSxlQUFlLENBQzlCbFEsSUFBMkIsRUFDM0JtUSxpQkFBMEIsRUFHeUI7SUFBQSxJQUZuRE4sVUFBVSx1RUFBRyxLQUFLO0lBQUEsSUFDbEJPLGNBQWMsdUVBQUcsS0FBSztJQUV0QixJQUFJcFEsSUFBSSxDQUFDSyxLQUFLLEtBQUssSUFBSSxFQUFFO01BQ3hCLE9BQU8rUCxjQUFjLEdBQUcsSUFBSSxHQUFHLE1BQU07SUFDdEM7SUFDQSxJQUFJcFEsSUFBSSxDQUFDSyxLQUFLLEtBQUtKLFNBQVMsRUFBRTtNQUM3QixPQUFPbVEsY0FBYyxHQUFHblEsU0FBUyxHQUFHLFdBQVc7SUFDaEQ7SUFDQSxJQUFJLE9BQU9ELElBQUksQ0FBQ0ssS0FBSyxLQUFLLFFBQVEsRUFBRTtNQUNuQyxJQUFJOEQsS0FBSyxDQUFDQyxPQUFPLENBQUNwRSxJQUFJLENBQUNLLEtBQUssQ0FBQyxFQUFFO1FBQzlCLE1BQU1tRSxPQUFPLEdBQUd4RSxJQUFJLENBQUNLLEtBQUssQ0FBQ3FDLEdBQUcsQ0FBRS9CLFVBQVUsSUFBS3NQLGlCQUFpQixDQUFDdFAsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ25GLE9BQVEsSUFBRzZELE9BQU8sQ0FBQ1AsSUFBSSxDQUFDLElBQUksQ0FBRSxHQUFFO01BQ2pDLENBQUMsTUFBTTtRQUNOLE9BQU8yTCxxQkFBcUIsQ0FBQzVQLElBQUksRUFBZ0M2UCxVQUFVLENBQUM7TUFDN0U7SUFDRDtJQUVBLElBQUlNLGlCQUFpQixFQUFFO01BQ3RCLFFBQVEsT0FBT25RLElBQUksQ0FBQ0ssS0FBSztRQUN4QixLQUFLLFFBQVE7UUFDYixLQUFLLFFBQVE7UUFDYixLQUFLLFNBQVM7VUFDYixPQUFPTCxJQUFJLENBQUNLLEtBQUssQ0FBQzhPLFFBQVEsRUFBRTtRQUM3QixLQUFLLFFBQVE7VUFDWixPQUFRLElBQUd6UCxrQkFBa0IsQ0FBQ00sSUFBSSxDQUFDSyxLQUFLLENBQUM4TyxRQUFRLEVBQUUsQ0FBRSxHQUFFO1FBQ3hEO1VBQ0MsT0FBTyxFQUFFO01BQUM7SUFFYixDQUFDLE1BQU07TUFDTixPQUFPaUIsY0FBYyxHQUFHcFEsSUFBSSxDQUFDSyxLQUFLLEdBQUdMLElBQUksQ0FBQ0ssS0FBSyxDQUFDOE8sUUFBUSxFQUFFO0lBQzNEO0VBQ0Q7O0VBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQVBBO0VBUUEsU0FBU2tCLDRCQUE0QixDQUNwQ0Msb0JBQThDLEVBQzlDSCxpQkFBMEIsRUFDMUJJLGlCQUF5QixFQUNVO0lBQ25DLElBQ0NELG9CQUFvQixDQUFDcFIsSUFBSSxJQUN6Qm9SLG9CQUFvQixDQUFDM08sVUFBVSxJQUMvQjJPLG9CQUFvQixDQUFDeEwsVUFBVSxJQUMvQndMLG9CQUFvQixDQUFDdEQsYUFBYSxJQUNsQ3NELG9CQUFvQixDQUFDblIsV0FBVyxFQUMvQjtNQUNEO01BQ0EsTUFBTXFSLHdCQUF3QixHQUFHO1FBQ2hDaFAsSUFBSSxFQUFFaVAsa0JBQWtCLENBQUNILG9CQUFvQixDQUFDO1FBQzlDcFIsSUFBSSxFQUFFb1Isb0JBQW9CLENBQUNwUixJQUFJO1FBQy9CNEYsVUFBVSxFQUFFd0wsb0JBQW9CLENBQUN4TCxVQUFVO1FBQzNDbkQsVUFBVSxFQUFFMk8sb0JBQW9CLENBQUMzTyxVQUFVO1FBQzNDcUwsYUFBYSxFQUFFc0Qsb0JBQW9CLENBQUN0RCxhQUFhO1FBQ2pEN04sV0FBVyxFQUFFbVIsb0JBQW9CLENBQUNuUjtNQUNuQyxDQUFDO01BQ0QsTUFBTXVSLFVBQVUsR0FBR1QsaUJBQWlCLENBQUNPLHdCQUF3QixFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDO01BQ2xGLElBQUlMLGlCQUFpQixFQUFFO1FBQ3RCLE9BQVEsR0FBRUksaUJBQWtCLEdBQUVHLFVBQVcsRUFBQztNQUMzQztNQUNBLE9BQU9BLFVBQVU7SUFDbEIsQ0FBQyxNQUFNLElBQUlQLGlCQUFpQixFQUFFO01BQzdCLE9BQVEsR0FBRUksaUJBQWtCLElBQUdFLGtCQUFrQixDQUFDSCxvQkFBb0IsQ0FBRSxHQUFFO0lBQzNFLENBQUMsTUFBTTtNQUNOLE9BQVEsSUFBR0csa0JBQWtCLENBQUNILG9CQUFvQixDQUFFLEdBQUU7SUFDdkQ7RUFDRDtFQUVBLFNBQVNLLDRCQUE0QixDQUEwQmhRLFVBQW9DLEVBQVU7SUFDNUcsSUFBSUEsVUFBVSxDQUFDaUIsaUJBQWlCLENBQUNuQixNQUFNLEtBQUssQ0FBQyxFQUFFO01BQzlDLE9BQVEsSUFBR21RLG9CQUFvQixDQUFDalEsVUFBVSxDQUFDaUIsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLEVBQTZDLElBQUksQ0FBRSxZQUNqSGpCLFVBQVUsQ0FBQ3pCLElBQ1gsSUFBRztJQUNMO0lBRUEsSUFBSTJSLFNBQVMsR0FBSSxhQUFZbFEsVUFBVSxDQUFDekIsSUFBSyxHQUFFO0lBQy9DLElBQUk0UixXQUFXLENBQUNuUSxVQUFVLENBQUNxTSxhQUFhLENBQUMsRUFBRTtNQUMxQzZELFNBQVMsSUFBSyxvQkFBbUJaLGlCQUFpQixDQUFDdFAsVUFBVSxDQUFDcU0sYUFBYSxDQUFFLEVBQUM7SUFDL0U7SUFDQSxJQUFJOEQsV0FBVyxDQUFDblEsVUFBVSxDQUFDZ0IsVUFBVSxDQUFDLEVBQUU7TUFDdkNrUCxTQUFTLElBQUssaUJBQWdCWixpQkFBaUIsQ0FBQ3RQLFVBQVUsQ0FBQ2dCLFVBQVUsQ0FBRSxFQUFDO0lBQ3pFO0lBQ0FrUCxTQUFTLElBQUksR0FBRztJQUVoQixPQUFRLDBCQUF5QmxRLFVBQVUsQ0FBQ2lCLGlCQUFpQixDQUMzRGMsR0FBRyxDQUFFK0wsS0FBSyxJQUFLbUMsb0JBQW9CLENBQUNuQyxLQUFLLENBQTRDLENBQUMsQ0FDdEZ4SyxJQUFJLENBQUMsR0FBRyxDQUFFLEdBQUU0TSxTQUFVLEVBQUM7RUFDMUI7O0VBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNPLFNBQVNFLHFCQUFxQixDQUNwQ3BRLFVBQWtCLEVBQ2xCd1AsaUJBQTBCLEVBRVM7SUFBQSxJQURuQ2EsbUJBQW1CLHVFQUFHLEtBQUs7SUFFM0IsSUFBSWIsaUJBQWlCLEVBQUU7TUFDdEIsSUFBSWEsbUJBQW1CLEVBQUU7UUFDeEIsT0FBUSxJQUFHclEsVUFBVyxHQUFFO01BQ3pCLENBQUMsTUFBTTtRQUNOLE9BQU9BLFVBQVU7TUFDbEI7SUFDRCxDQUFDLE1BQU07TUFDTixPQUFRLE1BQUtBLFVBQVcsR0FBRTtJQUMzQjtFQUNEOztFQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBVEE7RUFVTyxTQUFTc1AsaUJBQWlCLENBQ2hDdFAsVUFBb0MsRUFJRDtJQUFBLElBSG5Dd1AsaUJBQWlCLHVFQUFHLEtBQUs7SUFBQSxJQUN6QmMsY0FBYyx1RUFBRyxLQUFLO0lBQUEsSUFDdEJwQixVQUFVLHVFQUFHLEtBQUs7SUFFbEIsTUFBTTdQLElBQUksR0FBRzhDLGFBQWEsQ0FBQ25DLFVBQVUsQ0FBQztJQUN0QyxNQUFNNFAsaUJBQWlCLEdBQUdVLGNBQWMsR0FBRyxHQUFHLEdBQUcsR0FBRztJQUVwRCxRQUFRalIsSUFBSSxDQUFDaEIsS0FBSztNQUNqQixLQUFLLGNBQWM7UUFDbEIsT0FBT2lCLFNBQVM7TUFFakIsS0FBSyxVQUFVO1FBQ2QsT0FBT2lRLGVBQWUsQ0FBQ2xRLElBQUksRUFBRW1RLGlCQUFpQixFQUFFTixVQUFVLENBQUM7TUFFNUQsS0FBSyxLQUFLO1FBQ1QsT0FBTzdQLElBQUksQ0FBQytCLEdBQUcsSUFBSSxNQUFNO01BRTFCLEtBQUssVUFBVTtRQUNkLElBQUltUCxnQ0FBZ0MsR0FBRyxLQUFLO1FBQzVDLElBQUlsUixJQUFJLENBQUM4TyxjQUFjLEVBQUU7VUFDeEJwRSxvQkFBb0IsQ0FDbkIxSyxJQUFJLEVBQ0osVUFBVSxFQUNUbVIsS0FBSyxJQUFLO1lBQ1YsSUFBSUEsS0FBSyxLQUFLblIsSUFBSSxJQUFJbVIsS0FBSyxDQUFDclAsR0FBRyxLQUFLN0IsU0FBUyxFQUFFO2NBQzlDaVIsZ0NBQWdDLEdBQUcsSUFBSTtZQUN4QztZQUNBLE9BQU9DLEtBQUs7VUFDYixDQUFDLEVBQ0QsSUFBSSxDQUNKO1VBQ0R6RyxvQkFBb0IsQ0FDbkIxSyxJQUFJLEVBQ0osVUFBVSxFQUNUbVIsS0FBNEIsSUFBSztZQUNqQyxJQUFLQSxLQUFLLEtBQWlCblIsSUFBSSxJQUFJLE9BQU9tUixLQUFLLENBQUM5USxLQUFLLEtBQUssUUFBUSxFQUFFO2NBQ25FcUssb0JBQW9CLENBQUN5RyxLQUFLLEVBQUUsYUFBYSxFQUFHQyxRQUFRLElBQUs7Z0JBQ3hERixnQ0FBZ0MsR0FBRyxJQUFJO2dCQUN2QyxPQUFPRSxRQUFRO2NBQ2hCLENBQUMsQ0FBQztZQUNIO1lBRUEsT0FBT0QsS0FBSztVQUNiLENBQUMsRUFDRCxJQUFJLENBQ0o7UUFDRjtRQUNBLE1BQU1FLGNBQWMsR0FBSSxHQUFFclIsSUFBSSxDQUFDMkIsVUFBVSxDQUFDZSxHQUFHLENBQUU0TyxHQUFHLElBQUtyQixpQkFBaUIsQ0FBQ3FCLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDck4sSUFBSSxDQUFDLElBQUksQ0FBRSxFQUFDO1FBQ2pHLElBQUlzTixNQUFNLEdBQ1R2UixJQUFJLENBQUM4QixHQUFHLEtBQUs3QixTQUFTLEdBQ2xCLEdBQUVELElBQUksQ0FBQzBCLEVBQUcsSUFBRzJQLGNBQWUsR0FBRSxHQUM5QixHQUFFcEIsaUJBQWlCLENBQUNqUSxJQUFJLENBQUM4QixHQUFHLEVBQUUsSUFBSSxDQUFFLElBQUc5QixJQUFJLENBQUMwQixFQUFHLElBQUcyUCxjQUFlLEdBQUU7UUFDeEUsSUFBSSxDQUFDbEIsaUJBQWlCLElBQUllLGdDQUFnQyxFQUFFO1VBQzNESyxNQUFNLEdBQUksTUFBS0EsTUFBTyxHQUFFO1FBQ3pCO1FBQ0EsT0FBT0EsTUFBTTtNQUVkLEtBQUssMkJBQTJCO1FBQy9CLE9BQU9wQixpQkFBaUIsR0FBSSxJQUFHblEsSUFBSSxDQUFDSyxLQUFLLENBQUNtUixTQUFTLENBQUMsQ0FBQyxFQUFFeFIsSUFBSSxDQUFDSyxLQUFLLENBQUNJLE1BQU0sR0FBRyxDQUFDLENBQUUsR0FBRSxHQUFJLEdBQUVULElBQUksQ0FBQ0ssS0FBTSxFQUFDO01BRW5HLEtBQUssaUJBQWlCO1FBQ3JCLE9BQU84UCxpQkFBaUIsR0FBSSxHQUFFSSxpQkFBa0IsR0FBRXZRLElBQUksQ0FBQ0ssS0FBTSxFQUFDLEdBQUksR0FBRUwsSUFBSSxDQUFDSyxLQUFNLEVBQUM7TUFFakYsS0FBSyxhQUFhO1FBQ2pCLE9BQU9nUSw0QkFBNEIsQ0FBQ3JRLElBQUksRUFBRW1RLGlCQUFpQixFQUFFSSxpQkFBaUIsQ0FBQztNQUVoRixLQUFLLFlBQVk7UUFDaEIsTUFBTWtCLG9CQUFvQixHQUFHQywyQkFBMkIsQ0FBQzFSLElBQUksQ0FBQztRQUM5RCxPQUFPK1EscUJBQXFCLENBQUNVLG9CQUFvQixFQUFFdEIsaUJBQWlCLENBQUM7TUFFdEUsS0FBSyxRQUFRO1FBQ1osTUFBTXdCLGdCQUFnQixHQUFJLEdBQUUxQixpQkFBaUIsQ0FBQ2pRLElBQUksQ0FBQ2MsU0FBUyxFQUFFLElBQUksQ0FBRSxNQUFLbVAsaUJBQWlCLENBQ3pGalEsSUFBSSxDQUFDZSxNQUFNLEVBQ1gsSUFBSSxFQUNKa1EsY0FBYyxDQUNiLE1BQUtoQixpQkFBaUIsQ0FBQ2pRLElBQUksQ0FBQ2dCLE9BQU8sRUFBRSxJQUFJLEVBQUVpUSxjQUFjLENBQUUsRUFBQztRQUM5RCxPQUFPRixxQkFBcUIsQ0FBQ1ksZ0JBQWdCLEVBQUV4QixpQkFBaUIsRUFBRSxJQUFJLENBQUM7TUFFeEUsS0FBSyxLQUFLO1FBQ1QsTUFBTXlCLGFBQWEsR0FBRzVSLElBQUksQ0FBQ1EsUUFBUSxDQUFDa0MsR0FBRyxDQUFFcEMsT0FBTyxJQUFLMlAsaUJBQWlCLENBQUMzUCxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQzJELElBQUksQ0FBRSxJQUFHakUsSUFBSSxDQUFDTyxRQUFTLEdBQUUsQ0FBQztRQUNqSCxPQUFPd1EscUJBQXFCLENBQUNhLGFBQWEsRUFBRXpCLGlCQUFpQixFQUFFLElBQUksQ0FBQztNQUVyRSxLQUFLLFFBQVE7UUFDWixNQUFNMEIsZ0JBQWdCLEdBQUc3UixJQUFJLENBQUNGLFdBQVcsQ0FDdkM0QyxHQUFHLENBQUVvUCxnQkFBZ0IsSUFBSzdCLGlCQUFpQixDQUFDNkIsZ0JBQWdCLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQzFFN04sSUFBSSxDQUFDLEtBQUssQ0FBQztRQUNiLE9BQU84TSxxQkFBcUIsQ0FBQ2MsZ0JBQWdCLEVBQUUxQixpQkFBaUIsQ0FBQztNQUVsRSxLQUFLLFFBQVE7UUFDWixNQUFNNEIsZ0JBQWdCLEdBQUksR0FBRTlCLGlCQUFpQixDQUFDalEsSUFBSSxDQUFDc0IsV0FBVyxFQUFFLElBQUksQ0FBRSxTQUFRO1FBQzlFLE9BQU95UCxxQkFBcUIsQ0FBQ2dCLGdCQUFnQixFQUFFNUIsaUJBQWlCLENBQUM7TUFFbEUsS0FBSyxLQUFLO1FBQ1QsTUFBTTZCLGFBQWEsR0FBSSxJQUFHL0IsaUJBQWlCLENBQUNqUSxJQUFJLENBQUNNLE9BQU8sRUFBRSxJQUFJLENBQUUsRUFBQztRQUNqRSxPQUFPeVEscUJBQXFCLENBQUNpQixhQUFhLEVBQUU3QixpQkFBaUIsQ0FBQztNQUUvRCxLQUFLLFFBQVE7UUFDWixNQUFNOEIsZ0JBQWdCLEdBQUksS0FBSWhDLGlCQUFpQixDQUFDalEsSUFBSSxDQUFDTSxPQUFPLEVBQUUsSUFBSSxDQUFFLEVBQUM7UUFDckUsT0FBT3lRLHFCQUFxQixDQUFDa0IsZ0JBQWdCLEVBQUU5QixpQkFBaUIsQ0FBQztNQUVsRSxLQUFLLFdBQVc7UUFDZixNQUFNK0IsbUJBQW1CLEdBQUdDLDBCQUEwQixDQUFDblMsSUFBSSxDQUFDO1FBQzVELE9BQU9tUSxpQkFBaUIsR0FBSSxJQUFHK0IsbUJBQW9CLEVBQUMsR0FBR0EsbUJBQW1CO01BRTNFLEtBQUssYUFBYTtRQUNqQixNQUFNRSxxQkFBcUIsR0FBR3pCLDRCQUE0QixDQUFDM1EsSUFBSSxDQUFDO1FBQ2hFLE9BQU9tUSxpQkFBaUIsR0FBSSxJQUFHaUMscUJBQXNCLEVBQUMsR0FBR0EscUJBQXFCO01BRS9FO1FBQ0MsT0FBTyxFQUFFO0lBQUM7RUFFYjs7RUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFMQTtFQU1BLFNBQVNWLDJCQUEyQixDQUFDL1EsVUFBZ0MsRUFBVTtJQUM5RSxTQUFTMFIsY0FBYyxDQUFDL1IsT0FBMEMsRUFBb0M7TUFDckcsTUFBTWdTLGVBQWUsR0FBR3JDLGlCQUFpQixDQUFDM1AsT0FBTyxFQUFFLElBQUksQ0FBQyxJQUFJLFdBQVc7TUFDdkUsT0FBT3lRLHFCQUFxQixDQUFDdUIsZUFBZSxFQUFFLElBQUksRUFBRTNDLGVBQWUsQ0FBQ3JQLE9BQU8sQ0FBQyxDQUFDO0lBQzlFO0lBRUEsT0FBUSxHQUFFK1IsY0FBYyxDQUFDMVIsVUFBVSxDQUFDTSxRQUFRLENBQUUsSUFBR04sVUFBVSxDQUFDSixRQUFTLElBQUc4UixjQUFjLENBQUMxUixVQUFVLENBQUNPLFFBQVEsQ0FBRSxFQUFDO0VBQzlHOztFQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNBLFNBQVNpUiwwQkFBMEIsQ0FBMEJ4UixVQUFrQyxFQUFVO0lBQ3hHLElBQUlBLFVBQVUsQ0FBQ2dCLFVBQVUsQ0FBQ2xCLE1BQU0sS0FBSyxDQUFDLEVBQUU7TUFDdkMsT0FBUSxJQUFHbVEsb0JBQW9CLENBQUNqUSxVQUFVLENBQUNnQixVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQTZDLElBQUksQ0FBRSxpQkFDMUdoQixVQUFVLENBQUNlLEVBQ1gsSUFBRztJQUNMLENBQUMsTUFBTTtNQUNOLE1BQU02USxLQUFLLEdBQUc1UixVQUFVLENBQUNnQixVQUFVLENBQUNlLEdBQUcsQ0FBRStMLEtBQUssSUFBSztRQUNsRCxJQUFJQSxLQUFLLENBQUN6UCxLQUFLLEtBQUssYUFBYSxFQUFFO1VBQ2xDLE9BQU8yUiw0QkFBNEIsQ0FBQ2xDLEtBQUssQ0FBQztRQUMzQyxDQUFDLE1BQU07VUFDTixPQUFPbUMsb0JBQW9CLENBQUNuQyxLQUFLLENBQTRDO1FBQzlFO01BQ0QsQ0FBQyxDQUFDO01BQ0YsT0FBUSxZQUFXOEQsS0FBSyxDQUFDdE8sSUFBSSxDQUFDLElBQUksQ0FBRSxrQkFBaUJ0RCxVQUFVLENBQUNlLEVBQUcsSUFBRztJQUN2RTtFQUNEOztFQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ0EsU0FBU2tQLG9CQUFvQixDQUFDalEsVUFBbUQsRUFBOEI7SUFBQSxJQUE1QjZSLFVBQVUsdUVBQUcsS0FBSztJQUNwRyxJQUFJQyxRQUFRLEdBQUcsRUFBRTtJQUNqQixJQUFJOVIsVUFBVSxDQUFDM0IsS0FBSyxLQUFLLFVBQVUsRUFBRTtNQUNwQyxJQUFJMkIsVUFBVSxDQUFDTixLQUFLLEtBQUtKLFNBQVMsRUFBRTtRQUNuQztRQUNBd1MsUUFBUSxHQUFJLG9CQUFtQjtNQUNoQyxDQUFDLE1BQU07UUFDTkEsUUFBUSxHQUFJLFVBQVN2QyxlQUFlLENBQUN2UCxVQUFVLEVBQUUsSUFBSSxDQUFFLEVBQUM7TUFDekQ7SUFDRCxDQUFDLE1BQU0sSUFBSUEsVUFBVSxDQUFDM0IsS0FBSyxLQUFLLGFBQWEsRUFBRTtNQUM5Q3lULFFBQVEsR0FBSSxVQUFTaEMsa0JBQWtCLENBQUM5UCxVQUFVLENBQUUsR0FBRTtNQUV0RDhSLFFBQVEsSUFBSTlSLFVBQVUsQ0FBQ3pCLElBQUksR0FBSSxZQUFXeUIsVUFBVSxDQUFDekIsSUFBSyxHQUFFLEdBQUkscUJBQW9CO01BQ3BGLElBQUl5QixVQUFVLENBQUM0TixJQUFJLEVBQUU7UUFDcEJrRSxRQUFRLElBQUssWUFBV3hDLGlCQUFpQixDQUFDdFAsVUFBVSxDQUFDNE4sSUFBSSxDQUFFLEdBQUU7TUFDOUQ7TUFDQSxJQUFJdUMsV0FBVyxDQUFDblEsVUFBVSxDQUFDeEIsV0FBVyxDQUFDLEVBQUU7UUFDeENzVCxRQUFRLElBQUssa0JBQWlCeEMsaUJBQWlCLENBQUN0UCxVQUFVLENBQUN4QixXQUFXLENBQUUsRUFBQztNQUMxRTtNQUNBLElBQUkyUixXQUFXLENBQUNuUSxVQUFVLENBQUNxTSxhQUFhLENBQUMsRUFBRTtRQUMxQ3lGLFFBQVEsSUFBSyxvQkFBbUJ4QyxpQkFBaUIsQ0FBQ3RQLFVBQVUsQ0FBQ3FNLGFBQWEsQ0FBRSxFQUFDO01BQzlFO01BQ0EsSUFBSThELFdBQVcsQ0FBQ25RLFVBQVUsQ0FBQ2dCLFVBQVUsQ0FBQyxFQUFFO1FBQ3ZDOFEsUUFBUSxJQUFLLGlCQUFnQnhDLGlCQUFpQixDQUFDdFAsVUFBVSxDQUFDZ0IsVUFBVSxDQUFFLEVBQUM7TUFDeEU7SUFDRCxDQUFDLE1BQU07TUFDTixPQUFPLEVBQUU7SUFDVjtJQUNBLE9BQU82USxVQUFVLEdBQUdDLFFBQVEsR0FBSSxJQUFHQSxRQUFTLEdBQUU7RUFDL0M7RUFFQSxTQUFTM0IsV0FBVyxDQUFDaFAsR0FBdUIsRUFBVztJQUN0RCxPQUFPLENBQUMsQ0FBQ0EsR0FBRyxJQUFJeUMsTUFBTSxDQUFDNkcsSUFBSSxDQUFDdEosR0FBRyxDQUFDLENBQUNyQixNQUFNLEdBQUcsQ0FBQztFQUM1Qzs7RUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFDQSxTQUFTZ1Esa0JBQWtCLENBQTBCOVAsVUFBb0MsRUFBVTtJQUNsRyxPQUFRLEdBQUVBLFVBQVUsQ0FBQ1ksU0FBUyxHQUFHWixVQUFVLENBQUNZLFNBQVMsR0FBRyxHQUFHLEdBQUcsRUFBRyxHQUFFWixVQUFVLENBQUNhLElBQUssRUFBQztFQUNyRjtFQUFDO0FBQUEifQ==
|