xdbc 1.0.211 → 1.0.213
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/.gitattributes +8 -0
- package/.github/workflows/ci.yml +51 -0
- package/.vscode/tasks.json +23 -23
- package/CODE_OF_CONDUCT.md +1 -1
- package/README.md +1 -0
- package/__tests__/DBC/AE.test.ts +1 -1
- package/__tests__/DBC/DEFINED.test.ts +49 -49
- package/__tests__/DBC/Decorators.test.ts +334 -332
- package/__tests__/DBC/HasAttribute.test.ts +56 -52
- package/__tests__/DBC/IF.test.ts +57 -57
- package/__tests__/DBC/OR.test.ts +1 -1
- package/__tests__/DBC/UNDEFINED.test.ts +41 -41
- package/__tests__/DBC/ZOD.test.ts +50 -50
- package/biome.json +40 -33
- package/dist/DBC/AE.d.ts +117 -0
- package/dist/DBC/COMPARISON/GREATER.d.ts +13 -0
- package/dist/DBC/COMPARISON/GREATER_OR_EQUAL.d.ts +13 -0
- package/dist/DBC/COMPARISON/LESS.d.ts +13 -0
- package/dist/DBC/COMPARISON/LESS_OR_EQUAL.d.ts +13 -0
- package/dist/DBC/COMPARISON.d.ts +70 -0
- package/dist/DBC/DEFINED.d.ts +62 -0
- package/dist/DBC/EQ/DIFFERENT.d.ts +26 -0
- package/dist/DBC/EQ.d.ts +70 -0
- package/dist/DBC/HasAttribute.d.ts +72 -0
- package/dist/DBC/IF.d.ts +90 -0
- package/dist/DBC/INSTANCE.d.ts +84 -0
- package/dist/DBC/JSON.OP.d.ts +94 -0
- package/dist/DBC/JSON.Parse.d.ts +69 -0
- package/dist/DBC/OR.d.ts +104 -0
- package/dist/DBC/REGEX.d.ts +96 -0
- package/dist/DBC/TYPE.d.ts +75 -0
- package/dist/DBC/UNDEFINED.d.ts +62 -0
- package/dist/DBC/ZOD.d.ts +72 -0
- package/dist/DBC.d.ts +244 -0
- package/dist/Demo.d.ts +20 -0
- package/dist/bundle.js +2297 -0
- package/docs/assets/highlight.css +22 -22
- package/docs/assets/icons.js +17 -17
- package/docs/assets/main.js +60 -60
- package/docs/assets/style.css +1640 -1640
- package/docs/classes/DBC.DBC.html +98 -98
- package/docs/classes/DBC_AE.AE.html +160 -160
- package/docs/classes/DBC_EQ.EQ.html +131 -131
- package/docs/classes/DBC_GREATER.GREATER.html +139 -139
- package/docs/classes/DBC_INSTANCE.INSTANCE.html +130 -130
- package/docs/classes/DBC_JSON.OP.JSON_OP.html +138 -138
- package/docs/classes/DBC_JSON.Parse.JSON_Parse.html +129 -129
- package/docs/classes/DBC_OR.OR.html +137 -137
- package/docs/classes/DBC_REGEX.REGEX.html +136 -136
- package/docs/classes/DBC_TYPE.TYPE.html +130 -130
- package/docs/classes/Demo.Demo.html +14 -14
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +1 -1
- package/docs/modules/DBC.html +1 -1
- package/docs/modules/DBC_AE.html +1 -1
- package/docs/modules/DBC_EQ.html +1 -1
- package/docs/modules/DBC_GREATER.html +1 -1
- package/docs/modules/DBC_INSTANCE.html +1 -1
- package/docs/modules/DBC_JSON.OP.html +1 -1
- package/docs/modules/DBC_JSON.Parse.html +1 -1
- package/docs/modules/DBC_OR.html +1 -1
- package/docs/modules/DBC_REGEX.html +1 -1
- package/docs/modules/DBC_TYPE.html +1 -1
- package/docs/modules/Demo.html +1 -1
- package/jest.config.js +29 -18
- package/package.json +6 -2
- package/src/DBC/AE.ts +14 -9
- package/src/DBC/COMPARISON/GREATER.ts +2 -2
- package/src/DBC/COMPARISON.ts +159 -136
- package/src/DBC/DEFINED.ts +10 -10
- package/src/DBC/EQ/DIFFERENT.ts +3 -3
- package/src/DBC/EQ.ts +25 -9
- package/src/DBC/HasAttribute.ts +17 -3
- package/src/DBC/IF.ts +63 -19
- package/src/DBC/INSTANCE.ts +29 -14
- package/src/DBC/JSON.OP.ts +18 -3
- package/src/DBC/JSON.Parse.ts +21 -4
- package/src/DBC/OR.ts +12 -7
- package/src/DBC/REGEX.ts +30 -21
- package/src/DBC/TYPE.ts +15 -11
- package/src/DBC/UNDEFINED.ts +7 -10
- package/src/DBC/ZOD.ts +14 -9
- package/src/DBC.ts +165 -69
- package/src/Demo.ts +21 -18
- package/test.drawio +0 -0
- package/tsconfig.json +3 -5
- package/tsconfig.test.json +6 -11
- package/webpack.config.js +1 -1
package/dist/bundle.js
ADDED
|
@@ -0,0 +1,2297 @@
|
|
|
1
|
+
/******/ (() => { // webpackBootstrap
|
|
2
|
+
/******/ "use strict";
|
|
3
|
+
/******/ var __webpack_modules__ = ({
|
|
4
|
+
|
|
5
|
+
/***/ "./src/DBC.ts"
|
|
6
|
+
/*!********************!*\
|
|
7
|
+
!*** ./src/DBC.ts ***!
|
|
8
|
+
\********************/
|
|
9
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
10
|
+
|
|
11
|
+
__webpack_require__.r(__webpack_exports__);
|
|
12
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
13
|
+
/* harmony export */ DBC: () => (/* binding */ DBC)
|
|
14
|
+
/* harmony export */ });
|
|
15
|
+
/**
|
|
16
|
+
* Provides a **D**esign **B**y **C**ontract Framework using decorators.
|
|
17
|
+
*
|
|
18
|
+
* @remarks
|
|
19
|
+
* Maintainer: Callari, Salvatore (XDBC@WaXCode.net) */
|
|
20
|
+
class DBC {
|
|
21
|
+
/** Evicts the oldest entry if the cache exceeds the maximum size. */
|
|
22
|
+
static evictIfNeeded(cache) {
|
|
23
|
+
if (cache.size > DBC.MAX_CACHE_SIZE) {
|
|
24
|
+
const oldest = cache.keys().next().value;
|
|
25
|
+
if (oldest !== undefined)
|
|
26
|
+
cache.delete(oldest);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
static getHost() {
|
|
30
|
+
return typeof window !== "undefined" ? window : globalThis;
|
|
31
|
+
}
|
|
32
|
+
static getDBC(dbc) {
|
|
33
|
+
if (dbc instanceof DBC)
|
|
34
|
+
return dbc;
|
|
35
|
+
const path = dbc !== null && dbc !== void 0 ? dbc : "WaXCode.DBC";
|
|
36
|
+
if (DBC.dbcCache.has(path)) {
|
|
37
|
+
return DBC.dbcCache.get(path);
|
|
38
|
+
}
|
|
39
|
+
const resolved = DBC.resolveDBCPath(DBC.getHost(), path);
|
|
40
|
+
if (resolved) {
|
|
41
|
+
DBC.evictIfNeeded(DBC.dbcCache);
|
|
42
|
+
DBC.dbcCache.set(path, resolved);
|
|
43
|
+
return resolved;
|
|
44
|
+
}
|
|
45
|
+
throw new Error(`[XDBC] DBC instance not found at path "${path}". Ensure a DBC instance is registered there.`);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Generate a unique key for storing parameter value requests.
|
|
49
|
+
* Format: "ClassName:methodName"
|
|
50
|
+
*/
|
|
51
|
+
static getRequestKey(target, methodName) {
|
|
52
|
+
var _a;
|
|
53
|
+
const className = typeof target === "function"
|
|
54
|
+
? target.name
|
|
55
|
+
: ((_a = target.constructor) === null || _a === void 0 ? void 0 : _a.name) || "Unknown";
|
|
56
|
+
return `${className}:${String(methodName)}`;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Make a request to get the value of a certain parameter of specific method in a specific {@link object }.
|
|
60
|
+
* That request gets enlisted in {@link paramValueRequests } which is used by {@link ParamvalueProvider} to invoke the
|
|
61
|
+
* given "receptor" with the parameter value stored in there. Thus a parameter decorator using this method will
|
|
62
|
+
* not receive any value of the top method is not tagged with {@link ParamvalueProvider}.
|
|
63
|
+
*
|
|
64
|
+
* @param target The {@link object } containing the method with the parameter which's value is requested.
|
|
65
|
+
* @param methodName The name of the method with the parameter which's value is requested.
|
|
66
|
+
* @param index The index of the parameter which's value is requested.
|
|
67
|
+
* @param receptor The method the requested parameter-value shall be passed to when it becomes available. */
|
|
68
|
+
static requestParamValue(target, methodName, index,
|
|
69
|
+
// biome-ignore lint/suspicious/noExplicitAny: Gotta be any since parameter-values may be undefined.
|
|
70
|
+
receptor) {
|
|
71
|
+
var _a;
|
|
72
|
+
const key = DBC.getRequestKey(target, methodName);
|
|
73
|
+
if (DBC.paramValueRequests.has(key)) {
|
|
74
|
+
const paramMap = DBC.paramValueRequests.get(key);
|
|
75
|
+
if (paramMap.has(index)) {
|
|
76
|
+
(_a = paramMap.get(index)) === null || _a === void 0 ? void 0 : _a.push(receptor);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
paramMap.set(index, new Array(receptor));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
DBC.paramValueRequests.set(key, new Map([
|
|
84
|
+
[index, new Array(receptor)],
|
|
85
|
+
]));
|
|
86
|
+
}
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
// biome-ignore lint/suspicious/noExplicitAny: Must handle both method and class decorator signatures
|
|
90
|
+
static ParamvalueProvider(...args) {
|
|
91
|
+
if (args.length === 1 && typeof args[0] === "function") {
|
|
92
|
+
// #region Class decorator path
|
|
93
|
+
// biome-ignore lint/suspicious/noExplicitAny: Must accept any constructor signature
|
|
94
|
+
const constructor = args[0];
|
|
95
|
+
const key = `${constructor.name}:undefined`;
|
|
96
|
+
// biome-ignore lint/suspicious/noExplicitAny: Must accept any constructor signature
|
|
97
|
+
const WrappedClass = class extends constructor {
|
|
98
|
+
// biome-ignore lint/suspicious/noExplicitAny: Must accept any constructor signature
|
|
99
|
+
constructor(...ctorArgs) {
|
|
100
|
+
if (DBC.paramValueRequests.has(key)) {
|
|
101
|
+
const paramMap = DBC.paramValueRequests.get(key);
|
|
102
|
+
for (const index of paramMap.keys()) {
|
|
103
|
+
if (index < ctorArgs.length) {
|
|
104
|
+
for (const receptor of paramMap.get(index)) {
|
|
105
|
+
receptor(ctorArgs[index]);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
super(...ctorArgs);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
Object.defineProperty(WrappedClass, "name", { value: constructor.name });
|
|
114
|
+
return WrappedClass;
|
|
115
|
+
// #endregion Class decorator path
|
|
116
|
+
}
|
|
117
|
+
// #region Method decorator path
|
|
118
|
+
const [target, propertyKey, descriptor] = args;
|
|
119
|
+
const originalMethod = descriptor.value;
|
|
120
|
+
const isStatic = typeof target === "function";
|
|
121
|
+
// biome-ignore lint/suspicious/noExplicitAny: Gotta be any since parameter-values may be undefined.
|
|
122
|
+
descriptor.value = function (...methodArgs) {
|
|
123
|
+
// #region Check if a value of one of the method's parameter has been requested and pass it to the
|
|
124
|
+
// receptor, if so.
|
|
125
|
+
const actualTarget = isStatic ? this : this.constructor;
|
|
126
|
+
const key = DBC.getRequestKey(actualTarget, propertyKey);
|
|
127
|
+
if (DBC.paramValueRequests.has(key)) {
|
|
128
|
+
const paramMap = DBC.paramValueRequests.get(key);
|
|
129
|
+
for (const index of paramMap.keys()) {
|
|
130
|
+
if (index < methodArgs.length) {
|
|
131
|
+
for (const receptor of paramMap.get(index)) {
|
|
132
|
+
receptor(methodArgs[index]);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
console.warn("No parameter value requests found for key:", key);
|
|
139
|
+
}
|
|
140
|
+
// #endregion Check if a value of one of the method's parameter has been requested and pass it to the
|
|
141
|
+
// receptor, if so.
|
|
142
|
+
return originalMethod.apply(this, methodArgs);
|
|
143
|
+
};
|
|
144
|
+
return descriptor;
|
|
145
|
+
// #endregion Method decorator path
|
|
146
|
+
}
|
|
147
|
+
// #endregion Parameter-value requests.
|
|
148
|
+
// #region Class
|
|
149
|
+
/**
|
|
150
|
+
* A property-decorator factory serving as a **D**esign **B**y **C**ontract Invariant.
|
|
151
|
+
* This invariant aims to check the instance of the class not the value to be get or set.
|
|
152
|
+
*
|
|
153
|
+
* @param contracts The {@link DBC }-Contracts the value shall uphold.
|
|
154
|
+
*
|
|
155
|
+
* @throws A {@link DBC.Infringement } whenever the property is tried to be get or set without the instance of it's class
|
|
156
|
+
* fulfilling the specified **contracts**. */
|
|
157
|
+
static decClassInvariant(contracts, path = undefined, dbc = "WaXCode.DBC") {
|
|
158
|
+
let dbcInstance;
|
|
159
|
+
return (target, propertyKey, descriptor) => {
|
|
160
|
+
if (!dbcInstance)
|
|
161
|
+
dbcInstance = DBC.getDBC(dbc);
|
|
162
|
+
if (!dbcInstance.executionSettings.checkInvariants) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const originalSetter = descriptor.set;
|
|
166
|
+
const originalGetter = descriptor.get;
|
|
167
|
+
// biome-ignore lint/suspicious/noExplicitAny: Necessary to intercept UNDEFINED and NULL.
|
|
168
|
+
let value;
|
|
169
|
+
// #region Replace original property.
|
|
170
|
+
Object.defineProperty(target, propertyKey, {
|
|
171
|
+
get() {
|
|
172
|
+
if (!(dbcInstance === null || dbcInstance === void 0 ? void 0 : dbcInstance.executionSettings.checkInvariants)) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const realValue = path ? DBC.resolve(this, path) : this;
|
|
176
|
+
// #region Check if all "contracts" are fulfilled.
|
|
177
|
+
for (const contract of contracts) {
|
|
178
|
+
const result = contract.check(realValue);
|
|
179
|
+
if (typeof result === "string") {
|
|
180
|
+
dbcInstance === null || dbcInstance === void 0 ? void 0 : dbcInstance.reportFieldInfringement(result, target, path, propertyKey, realValue);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// #endregion Check if all "contracts" are fulfilled.
|
|
184
|
+
return originalGetter ? originalGetter[propertyKey] : value;
|
|
185
|
+
},
|
|
186
|
+
set(newValue) {
|
|
187
|
+
if (!(dbcInstance === null || dbcInstance === void 0 ? void 0 : dbcInstance.executionSettings.checkInvariants)) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const realValue = path ? DBC.resolve(this, path) : this;
|
|
191
|
+
// #region Check if all "contracts" are fulfilled.
|
|
192
|
+
for (const contract of contracts) {
|
|
193
|
+
const result = contract.check(realValue);
|
|
194
|
+
if (typeof result === "string") {
|
|
195
|
+
dbcInstance === null || dbcInstance === void 0 ? void 0 : dbcInstance.reportFieldInfringement(result, target, path, propertyKey, realValue);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// #endregion Check if all "contracts" are fulfilled.
|
|
199
|
+
value = newValue;
|
|
200
|
+
},
|
|
201
|
+
enumerable: true,
|
|
202
|
+
configurable: true,
|
|
203
|
+
});
|
|
204
|
+
// #endregion Replace original property.
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
// #endregion Class
|
|
208
|
+
// #region Invariant
|
|
209
|
+
/**
|
|
210
|
+
* A property-decorator factory serving as a **D**esign **B**y **C**ontract Invariant.
|
|
211
|
+
* Since the value must be initialized or set according to the specified **contracts** the value will only be checked
|
|
212
|
+
* when assigning it.
|
|
213
|
+
*
|
|
214
|
+
* @param contracts The {@link DBC }-Contracts the value shall uphold.
|
|
215
|
+
*
|
|
216
|
+
* @throws A {@link DBC.Infringement } whenever the property is tried to be set to a value that does not comply to the
|
|
217
|
+
* specified **contracts**, by the returned method.*/
|
|
218
|
+
static decInvariant(contracts, path = undefined, dbc = undefined, hint = undefined) {
|
|
219
|
+
let dbcInstance;
|
|
220
|
+
return (target, propertyKey) => {
|
|
221
|
+
if (!dbcInstance)
|
|
222
|
+
dbcInstance = DBC.getDBC(dbc);
|
|
223
|
+
if (!dbcInstance.executionSettings.checkInvariants) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
// biome-ignore lint/suspicious/noExplicitAny: Necessary to intercept UNDEFINED and NULL.
|
|
227
|
+
let value;
|
|
228
|
+
// #region Replace original property.
|
|
229
|
+
Object.defineProperty(target, propertyKey, {
|
|
230
|
+
set(newValue) {
|
|
231
|
+
if (!(dbcInstance === null || dbcInstance === void 0 ? void 0 : dbcInstance.executionSettings.checkInvariants)) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const realValue = path ? DBC.resolve(newValue, path) : newValue;
|
|
235
|
+
// #region Check if all "contracts" are fulfilled.
|
|
236
|
+
for (const contract of contracts) {
|
|
237
|
+
const result = contract.check(realValue);
|
|
238
|
+
if (typeof result === "string") {
|
|
239
|
+
dbcInstance === null || dbcInstance === void 0 ? void 0 : dbcInstance.reportFieldInfringement(result, target, path, propertyKey, realValue, hint);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// #endregion Check if all "contracts" are fulfilled.
|
|
243
|
+
value = newValue;
|
|
244
|
+
},
|
|
245
|
+
enumerable: true,
|
|
246
|
+
configurable: true,
|
|
247
|
+
});
|
|
248
|
+
// #endregion Replace original property.
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
// #endregion Invariant
|
|
252
|
+
// #region Postcondition
|
|
253
|
+
/**
|
|
254
|
+
* A method decorator factory checking the result of a method whenever it is invoked thus also usable on getters.
|
|
255
|
+
*
|
|
256
|
+
* @param check The **(toCheck: any, object, string) => boolean | string** to use for checking.
|
|
257
|
+
* @param dbc See {@link DBC.resolveDBCPath }.
|
|
258
|
+
* @param path The dotted path referring to the actual value to check, starting form the specified one.
|
|
259
|
+
*
|
|
260
|
+
* @returns The **( target : object, propertyKey : string, descriptor : PropertyDescriptor ) : PropertyDescriptor**
|
|
261
|
+
* invoked by Typescript.
|
|
262
|
+
*/
|
|
263
|
+
// biome-ignore lint/suspicious/noExplicitAny: Necessary to intercept UNDEFINED and NULL.
|
|
264
|
+
static decPostcondition(
|
|
265
|
+
// biome-ignore lint/suspicious/noExplicitAny: Necessary to intercept UNDEFINED and NULL.
|
|
266
|
+
check, dbc = undefined, path = undefined, hint = undefined) {
|
|
267
|
+
let dbcInstance;
|
|
268
|
+
return (target, propertyKey, descriptor) => {
|
|
269
|
+
const originalMethod = descriptor.value;
|
|
270
|
+
// biome-ignore lint/suspicious/noExplicitAny: Necessary to intercept UNDEFINED and NULL.
|
|
271
|
+
descriptor.value = (...args) => {
|
|
272
|
+
if (!dbcInstance)
|
|
273
|
+
dbcInstance = DBC.getDBC(dbc);
|
|
274
|
+
if (!dbcInstance.executionSettings.checkPostconditions) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
// biome-ignore lint/complexity/noThisInStatic: <explanation>
|
|
278
|
+
const result = originalMethod.apply(this, args);
|
|
279
|
+
const realValue = path ? DBC.resolve(result, path) : result;
|
|
280
|
+
const checkResult = check(realValue, target, propertyKey);
|
|
281
|
+
if (typeof checkResult === "string") {
|
|
282
|
+
dbcInstance.reportReturnvalueInfringement(checkResult, target, path, propertyKey, realValue, hint);
|
|
283
|
+
}
|
|
284
|
+
return result;
|
|
285
|
+
};
|
|
286
|
+
return descriptor;
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
// #endregion Postcondition
|
|
290
|
+
// #region Decorator
|
|
291
|
+
// #region Precondition
|
|
292
|
+
/**
|
|
293
|
+
* A parameter-decorator factory that requests the tagged parameter's value passing it to the provided
|
|
294
|
+
* "check"-method when the value becomes available.
|
|
295
|
+
*
|
|
296
|
+
* @param check The "( unknown ) => void" to be invoked along with the tagged parameter's value as soon
|
|
297
|
+
* as it becomes available.
|
|
298
|
+
* @param dbc See {@link DBC.resolveDBCPath }.
|
|
299
|
+
* @param path The dotted path referring to the actual value to check, starting form the specified one.
|
|
300
|
+
* May contain :: to separate multiple paths.
|
|
301
|
+
*
|
|
302
|
+
* @returns The **(target: object, methodName: string | symbol, parameterIndex: number ) => void** invoked by Typescript- */
|
|
303
|
+
static decPrecondition(
|
|
304
|
+
// biome-ignore lint/suspicious/noExplicitAny: Necessary to check any parameter value
|
|
305
|
+
check, dbc = undefined, path = undefined, hint = undefined) {
|
|
306
|
+
const paths = path ? path.replace(/ /g, "").split("::") : [undefined];
|
|
307
|
+
let dbcInstance;
|
|
308
|
+
return (target, methodName, parameterIndex) => {
|
|
309
|
+
DBC.requestParamValue(target, methodName, parameterIndex, (value) => {
|
|
310
|
+
if (!dbcInstance)
|
|
311
|
+
dbcInstance = DBC.getDBC(dbc);
|
|
312
|
+
if (!dbcInstance.executionSettings.checkPreconditions) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
for (const singlePath of paths) {
|
|
316
|
+
const realValue = singlePath
|
|
317
|
+
? DBC.resolve(value, singlePath)
|
|
318
|
+
: value;
|
|
319
|
+
const result = check(realValue, target, methodName, parameterIndex);
|
|
320
|
+
if (typeof result === "string") {
|
|
321
|
+
dbcInstance.reportParameterInfringement(result, target, singlePath, methodName, parameterIndex, realValue, hint);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
// #endregion Precondition
|
|
328
|
+
// #endregion Decorator
|
|
329
|
+
// #region Contract Factory Helpers
|
|
330
|
+
/**
|
|
331
|
+
* Creates a PRE decorator from a checkAlgorithm function and its bound arguments.
|
|
332
|
+
* Reduces boilerplate across contract classes.
|
|
333
|
+
*
|
|
334
|
+
* @param checkFn A function that takes (value, ...boundArgs) and returns true or an error string.
|
|
335
|
+
* @param boundArgs The arguments to bind to the check function after the value.
|
|
336
|
+
* @param dbc See {@link DBC.decPrecondition}.
|
|
337
|
+
* @param path See {@link DBC.decPrecondition}.
|
|
338
|
+
* @param hint See {@link DBC.decPrecondition}.
|
|
339
|
+
*/
|
|
340
|
+
static createPRE(
|
|
341
|
+
// biome-ignore lint/suspicious/noExplicitAny: Must accept any checkAlgorithm signature
|
|
342
|
+
checkFn,
|
|
343
|
+
// biome-ignore lint/suspicious/noExplicitAny: Arguments vary per contract
|
|
344
|
+
boundArgs, dbc, path, hint) {
|
|
345
|
+
return DBC.decPrecondition((value, _target, _methodName, _parameterIndex) => {
|
|
346
|
+
return checkFn(value, ...boundArgs);
|
|
347
|
+
}, dbc, path, hint);
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Creates a POST decorator from a checkAlgorithm function and its bound arguments.
|
|
351
|
+
*
|
|
352
|
+
* @param checkFn A function that takes (value, ...boundArgs) and returns true or an error string.
|
|
353
|
+
* @param boundArgs The arguments to bind to the check function after the value.
|
|
354
|
+
* @param dbc See {@link DBC.decPostcondition}.
|
|
355
|
+
* @param path See {@link DBC.decPostcondition}.
|
|
356
|
+
* @param hint See {@link DBC.decPostcondition}.
|
|
357
|
+
*/
|
|
358
|
+
static createPOST(
|
|
359
|
+
// biome-ignore lint/suspicious/noExplicitAny: Must accept any checkAlgorithm signature
|
|
360
|
+
checkFn,
|
|
361
|
+
// biome-ignore lint/suspicious/noExplicitAny: Arguments vary per contract
|
|
362
|
+
boundArgs, dbc, path, hint) {
|
|
363
|
+
return DBC.decPostcondition((value, _target, _propertyKey) => {
|
|
364
|
+
return checkFn(value, ...boundArgs);
|
|
365
|
+
}, dbc, path, hint);
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Creates an INVARIANT decorator from a contract constructor and its bound arguments.
|
|
369
|
+
*
|
|
370
|
+
* @param ContractClass A class with a constructor that produces an object with a `check` method.
|
|
371
|
+
* @param ctorArgs The arguments to pass to the contract constructor.
|
|
372
|
+
* @param dbc See {@link DBC.decInvariant}.
|
|
373
|
+
* @param path See {@link DBC.decInvariant}.
|
|
374
|
+
* @param hint See {@link DBC.decInvariant}.
|
|
375
|
+
*/
|
|
376
|
+
static createINVARIANT(
|
|
377
|
+
// biome-ignore lint/suspicious/noExplicitAny: Must accept any contract constructor
|
|
378
|
+
ContractClass,
|
|
379
|
+
// biome-ignore lint/suspicious/noExplicitAny: Arguments vary per contract
|
|
380
|
+
ctorArgs, dbc, path, hint) {
|
|
381
|
+
return DBC.decInvariant([new ContractClass(...ctorArgs)], path, dbc, hint);
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Reports a warning.
|
|
385
|
+
*
|
|
386
|
+
* @param message The message containing the warning. */
|
|
387
|
+
reportWarning(message) {
|
|
388
|
+
if (this.warningSettings.logToConsole) {
|
|
389
|
+
console.warn(message);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
/** Sanitizes a value for safe inclusion in error messages. */
|
|
393
|
+
static sanitize(value) {
|
|
394
|
+
const str = typeof value === "string" ? value : String(value);
|
|
395
|
+
return str.replace(/[<>&"']/g, (ch) => {
|
|
396
|
+
switch (ch) {
|
|
397
|
+
case "<":
|
|
398
|
+
return "<";
|
|
399
|
+
case ">":
|
|
400
|
+
return ">";
|
|
401
|
+
case "&":
|
|
402
|
+
return "&";
|
|
403
|
+
case '"':
|
|
404
|
+
return """;
|
|
405
|
+
case "'":
|
|
406
|
+
return "'";
|
|
407
|
+
default:
|
|
408
|
+
return ch;
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Reports an infringement according to the {@link infringementSettings } also generating a proper {@link string }-wrapper
|
|
414
|
+
* for the given "message" & violator.
|
|
415
|
+
*
|
|
416
|
+
* @param message The {@link string } describing the infringement and it's provenience.
|
|
417
|
+
* @param violator The {@link string } describing or naming the violator. */
|
|
418
|
+
reportInfringement(message, violator, target, value, path, hint = undefined) {
|
|
419
|
+
const safeViolator = DBC.sanitize(violator);
|
|
420
|
+
const targetName = typeof target === "function"
|
|
421
|
+
? DBC.sanitize(target.name)
|
|
422
|
+
: typeof target === "object" &&
|
|
423
|
+
target !== null &&
|
|
424
|
+
typeof target.constructor === "function"
|
|
425
|
+
? DBC.sanitize(target.constructor.name)
|
|
426
|
+
: DBC.sanitize(target);
|
|
427
|
+
const finalMessage = `[ From "${safeViolator}" in "${targetName}"${path ? ` > "${DBC.sanitize(path)}"` : ""}: ${message} ${hint ? `✨ ${hint} ✨` : ""}]`;
|
|
428
|
+
if (this.infringementSettings.throwException) {
|
|
429
|
+
throw new DBC.Infringement(finalMessage);
|
|
430
|
+
}
|
|
431
|
+
if (this.infringementSettings.logToConsole) {
|
|
432
|
+
console.log(finalMessage);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Reports a parameter-infringement via {@link reportInfringement } also generating a proper {@link string }-wrapper
|
|
437
|
+
* for the given "message","method", parameter-"index" & value.
|
|
438
|
+
*
|
|
439
|
+
* @param message The {@link string } describing the infringement and it's provenience.
|
|
440
|
+
* @param method The {@link string } describing or naming the violator.
|
|
441
|
+
* @param index The index of the parameter within the argument listing.
|
|
442
|
+
* @param value The parameter's value. */
|
|
443
|
+
reportParameterInfringement(message, target, path, method, index, value, hint = undefined) {
|
|
444
|
+
const properIndex = index + 1;
|
|
445
|
+
this.reportInfringement(`[ Parameter-value "${value}" of the ${properIndex}${properIndex === 1 ? "st" : properIndex === 2 ? "nd" : properIndex === 3 ? "rd" : "th"} parameter did not fulfill one of it's contracts: ${message} ]`, method, target, value, path, hint);
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Reports a field-infringement via {@link reportInfringement } also generating a proper {@link string }-wrapper
|
|
449
|
+
* for the given **message** & **name**.
|
|
450
|
+
*
|
|
451
|
+
* @param message A {@link string } describing the infringement and it's provenience.
|
|
452
|
+
* @param key The property key.
|
|
453
|
+
* @param path The dotted-path {@link string } that leads to the value not fulfilling the contract starting from
|
|
454
|
+
* the tagged one.
|
|
455
|
+
* @param value The value not fulfilling a contract. */
|
|
456
|
+
reportFieldInfringement(message, target, path, key, value, hint = undefined) {
|
|
457
|
+
this.reportInfringement(`[ New value for "${key}"${path === undefined ? "" : `.${path}`} with value "${value}" did not fulfill one of it's contracts: ${message} ]`, key, target, value, path);
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Reports a returnvalue-infringement according via {@link reportInfringement } also generating a proper {@link string }-wrapper
|
|
461
|
+
* for the given "message","method" & value.
|
|
462
|
+
*
|
|
463
|
+
* @param message The {@link string } describing the infringement and it's provenience.
|
|
464
|
+
* @param method The {@link string } describing or naming the violator.
|
|
465
|
+
* @param value The parameter's value. */
|
|
466
|
+
reportReturnvalueInfringement(message, target, path, method,
|
|
467
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
468
|
+
value, hint = undefined) {
|
|
469
|
+
this.reportInfringement(`[ Return-value "${value}" did not fulfill one of it's contracts: ${message} ]`, method, target, value, path, hint);
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Constructs this {@link DBC } without mounting it on the global namespace.
|
|
473
|
+
* Use {@link DBC.register } to make the instance available at a specific path on globalThis.
|
|
474
|
+
*
|
|
475
|
+
* @param infringementSettings See {@link DBC.infringementSettings }.
|
|
476
|
+
* @param executionSettings See {@link DBC.executionSettings }. */
|
|
477
|
+
constructor(infringementSettings = { throwException: true, logToConsole: false }, executionSettings = {
|
|
478
|
+
checkPreconditions: true,
|
|
479
|
+
checkPostconditions: true,
|
|
480
|
+
checkInvariants: true,
|
|
481
|
+
}) {
|
|
482
|
+
// #endregion Contract Factory Helpers
|
|
483
|
+
// #region Execution Handling
|
|
484
|
+
/** Stores settings concerning the execution of checks. */
|
|
485
|
+
this.executionSettings = {
|
|
486
|
+
checkPreconditions: true,
|
|
487
|
+
checkPostconditions: true,
|
|
488
|
+
checkInvariants: true,
|
|
489
|
+
};
|
|
490
|
+
// #endregion Execution Handling
|
|
491
|
+
// #region Warning handling.
|
|
492
|
+
/** Stores settings concerning warnings. */
|
|
493
|
+
this.warningSettings = { logToConsole: true };
|
|
494
|
+
// #endregion Warning handling.
|
|
495
|
+
// #region infringement handling.
|
|
496
|
+
/** Stores the settings concerning infringements */
|
|
497
|
+
this.infringementSettings = { throwException: true, logToConsole: false };
|
|
498
|
+
this.infringementSettings = infringementSettings;
|
|
499
|
+
this.executionSettings = executionSettings;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Registers a {@link DBC } instance at the specified dotted path on globalThis (or window),
|
|
503
|
+
* making it available for decorator resolution via string paths.
|
|
504
|
+
*
|
|
505
|
+
* @param instance The {@link DBC } instance to register.
|
|
506
|
+
* @param path The dotted path to register at (default: `"WaXCode.DBC"`). */
|
|
507
|
+
static register(instance, path = "WaXCode.DBC") {
|
|
508
|
+
const segments = path.split(".");
|
|
509
|
+
// biome-ignore lint/suspicious/noExplicitAny: Must walk dynamic global namespace.
|
|
510
|
+
let obj = DBC.getHost();
|
|
511
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
512
|
+
if (obj[segments[i]] === undefined)
|
|
513
|
+
obj[segments[i]] = {};
|
|
514
|
+
obj = obj[segments[i]];
|
|
515
|
+
}
|
|
516
|
+
obj[segments[segments.length - 1]] = instance;
|
|
517
|
+
DBC.dbcCache.set(path, instance);
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Executes a callback with an isolated {@link DBC } instance temporarily registered at the default path.
|
|
521
|
+
* The previous instance (if any) is restored after the callback completes — even if it throws.
|
|
522
|
+
* Useful for test isolation.
|
|
523
|
+
*
|
|
524
|
+
* @param fn The callback receiving the isolated {@link DBC } instance. */
|
|
525
|
+
static isolated(fn) {
|
|
526
|
+
const saved = DBC.dbcCache.get("WaXCode.DBC");
|
|
527
|
+
const testDbc = new DBC();
|
|
528
|
+
DBC.register(testDbc);
|
|
529
|
+
try {
|
|
530
|
+
fn(testDbc);
|
|
531
|
+
}
|
|
532
|
+
finally {
|
|
533
|
+
if (saved) {
|
|
534
|
+
DBC.register(saved);
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
DBC.dbcCache.delete("WaXCode.DBC");
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Resolves the desired {@link object } out a given one **toResolveFrom** using the specified **path**.
|
|
543
|
+
*
|
|
544
|
+
* @param toResolveFrom The {@link object } starting to resolve from.
|
|
545
|
+
* @param path The dotted path-{@link string }.
|
|
546
|
+
* This string uses ., [...], and () to represent accessing nested properties,
|
|
547
|
+
* array elements/object keys, and calling methods, respectively, mimicking JavaScript syntax to navigate
|
|
548
|
+
* an object's structure. Code, e.g. something like a.b( 1 as number ).c, will not be executed and
|
|
549
|
+
* thus make the retrieval fail.
|
|
550
|
+
*
|
|
551
|
+
* @returns The requested {@link object }, NULL or UNDEFINED. */
|
|
552
|
+
static resolve(toResolveFrom, path) {
|
|
553
|
+
if (!toResolveFrom || typeof path !== "string") {
|
|
554
|
+
return undefined;
|
|
555
|
+
}
|
|
556
|
+
// Security: block prototype pollution paths
|
|
557
|
+
const dangerousTokens = ["__proto__", "constructor", "prototype"];
|
|
558
|
+
const cachedParts = DBC.pathTokenCache.get(path);
|
|
559
|
+
const parts = cachedParts !== null && cachedParts !== void 0 ? cachedParts : path.replace(/\[(['"]?)(.*?)\1\]/g, ".$2").split(".");
|
|
560
|
+
if (!cachedParts) {
|
|
561
|
+
// Validate tokens before caching
|
|
562
|
+
for (const part of parts) {
|
|
563
|
+
const tokenName = part.replace(/\(.*\)$/, "");
|
|
564
|
+
if (dangerousTokens.indexOf(tokenName) >= 0) {
|
|
565
|
+
throw new Error(`[XDBC] Path "${path}" contains forbidden token "${tokenName}".`);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
DBC.evictIfNeeded(DBC.pathTokenCache);
|
|
569
|
+
DBC.pathTokenCache.set(path, parts);
|
|
570
|
+
}
|
|
571
|
+
// biome-ignore lint/suspicious/noExplicitAny: Must traverse arbitrary object graphs
|
|
572
|
+
let current = toResolveFrom;
|
|
573
|
+
for (const part of parts) {
|
|
574
|
+
if (current === null || typeof current === "undefined") {
|
|
575
|
+
return undefined;
|
|
576
|
+
}
|
|
577
|
+
const methodMatch = part.match(/(\w+)\((.*)\)/);
|
|
578
|
+
if (methodMatch) {
|
|
579
|
+
const methodName = methodMatch[1];
|
|
580
|
+
const argsStr = methodMatch[2];
|
|
581
|
+
const args = argsStr.split(",").map((arg) => arg.trim());
|
|
582
|
+
if (typeof current[methodName] === "function") {
|
|
583
|
+
current = current[methodName].apply(current, args);
|
|
584
|
+
}
|
|
585
|
+
else {
|
|
586
|
+
return undefined;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
if (typeof window !== "undefined" &&
|
|
591
|
+
typeof HTMLElement !== "undefined" &&
|
|
592
|
+
current instanceof HTMLElement &&
|
|
593
|
+
part.startsWith("@")) {
|
|
594
|
+
current = current.getAttribute(part.slice(1));
|
|
595
|
+
}
|
|
596
|
+
else if (typeof current === "object" &&
|
|
597
|
+
current !== null &&
|
|
598
|
+
part in current) {
|
|
599
|
+
current = current[part];
|
|
600
|
+
}
|
|
601
|
+
else if (typeof window !== "undefined" &&
|
|
602
|
+
typeof HTMLElement !== "undefined" &&
|
|
603
|
+
current instanceof HTMLElement) {
|
|
604
|
+
current = undefined;
|
|
605
|
+
}
|
|
606
|
+
else {
|
|
607
|
+
current = undefined;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
return current;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
// #region Internal caches.
|
|
615
|
+
DBC.MAX_CACHE_SIZE = 1000;
|
|
616
|
+
DBC.dbcCache = new Map();
|
|
617
|
+
DBC.pathTokenCache = new Map();
|
|
618
|
+
// #endregion Internal caches.
|
|
619
|
+
// #region Parameter-value requests.
|
|
620
|
+
/** Stores all request for parameter values registered by {@link decPrecondition }. */
|
|
621
|
+
DBC.paramValueRequests = new Map();
|
|
622
|
+
// #region Classes
|
|
623
|
+
// #region Errors
|
|
624
|
+
/** An {@link Error } to be thrown whenever an infringement is detected. */
|
|
625
|
+
DBC.Infringement = class extends Error {
|
|
626
|
+
/**
|
|
627
|
+
* Constructs this {@link Error } by tagging the specified message-{@link string } as an XDBC-Infringement.
|
|
628
|
+
*
|
|
629
|
+
* @param message The {@link string } describing the infringement. */
|
|
630
|
+
constructor(message) {
|
|
631
|
+
super(`[ XDBC Infringement ${message}]`);
|
|
632
|
+
}
|
|
633
|
+
};
|
|
634
|
+
// #endregion Errors
|
|
635
|
+
// #endregion Classes
|
|
636
|
+
// #endregion infringement handling.
|
|
637
|
+
/**
|
|
638
|
+
* Resolves the specified dotted {@link string }-path to a {@link DBC }.
|
|
639
|
+
*
|
|
640
|
+
* @param obj The {@link object } to start resolving from.
|
|
641
|
+
* @param path The dotted {@link string }-path leading to the {@link DBC }.
|
|
642
|
+
*
|
|
643
|
+
* @returns The requested {@link DBC }.
|
|
644
|
+
*/
|
|
645
|
+
// biome-ignore lint/suspicious/noExplicitAny: Must traverse arbitrary object graphs
|
|
646
|
+
DBC.resolveDBCPath = (obj, path) => path === null || path === void 0 ? void 0 : path.split(".").reduce((accumulator, current) => accumulator[current], obj);
|
|
647
|
+
// Register the default instance with standard settings.
|
|
648
|
+
DBC.register(new DBC());
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
/***/ },
|
|
652
|
+
|
|
653
|
+
/***/ "./src/DBC/AE.ts"
|
|
654
|
+
/*!***********************!*\
|
|
655
|
+
!*** ./src/DBC/AE.ts ***!
|
|
656
|
+
\***********************/
|
|
657
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
658
|
+
|
|
659
|
+
__webpack_require__.r(__webpack_exports__);
|
|
660
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
661
|
+
/* harmony export */ AE: () => (/* binding */ AE)
|
|
662
|
+
/* harmony export */ });
|
|
663
|
+
/* harmony import */ var _DBC__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../DBC */ "./src/DBC.ts");
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* A {@link DBC } defining that all elements of an {@link object }s have to fulfill
|
|
667
|
+
* a given {@link object }'s check-method (**( toCheck : any ) => boolean | string**).
|
|
668
|
+
*
|
|
669
|
+
* @remarks
|
|
670
|
+
* Maintainer: Callari, Salvatore (XDBC@WaXCode.net) */
|
|
671
|
+
class AE extends _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC {
|
|
672
|
+
// #region Condition checking.
|
|
673
|
+
/**
|
|
674
|
+
* Checks each element of the **value**-{@link Array < any >} against the given **condition**, if it is one. If it is not
|
|
675
|
+
* the **value** itself will be checked.
|
|
676
|
+
*
|
|
677
|
+
* @param condition The { check: (toCheck: any) => boolean | string } to check the **value** against.
|
|
678
|
+
* @param value Either **value**-{@link Array < any >}, which's elements will be checked, or the value to be
|
|
679
|
+
* checked itself.
|
|
680
|
+
* @param index If specified with **idxEnd** being undefined, this {@link Number } will be seen as the index of
|
|
681
|
+
* the value-{@link Array }'s element to check. If value isn't an {@link Array } this parameter
|
|
682
|
+
* will not have any effect.
|
|
683
|
+
* With **idxEnd** not undefined this parameter indicates the beginning of the span of elements to
|
|
684
|
+
* check within the value-{@link Array }.
|
|
685
|
+
* @param idxEnd Indicates the last element's index (including) of the span of value-{@link Array } elements to check.
|
|
686
|
+
* Setting this parameter to -1 specifies that all value-{@link Array }'s elements beginning from the
|
|
687
|
+
* specified **index** shall be checked.
|
|
688
|
+
*
|
|
689
|
+
* @returns As soon as the **condition** returns a {@link string }, instead of TRUE, the returned string. TRUE if the
|
|
690
|
+
* **condition** never returns a {@link string}. */
|
|
691
|
+
static checkAlgorithm(condition, value, index, idxEnd) {
|
|
692
|
+
if (Array.isArray(value)) {
|
|
693
|
+
if (index !== undefined && idxEnd === undefined) {
|
|
694
|
+
if (index > -1 && index < value.length) {
|
|
695
|
+
const result = condition.check(value[index]);
|
|
696
|
+
if (typeof result === "string") {
|
|
697
|
+
return `Violating-Arrayelement at index "${index}" with value "${value[index]}". ${result}`;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
return true; // In order for optional parameter to not cause an error if they are omitted.
|
|
701
|
+
}
|
|
702
|
+
const ending = idxEnd !== undefined
|
|
703
|
+
? idxEnd !== -1
|
|
704
|
+
? idxEnd + 1
|
|
705
|
+
: value.length
|
|
706
|
+
: value.length;
|
|
707
|
+
for (let i = index ? index : 0; i < ending; i++) {
|
|
708
|
+
const result = condition.check(value[i]);
|
|
709
|
+
if (result !== true) {
|
|
710
|
+
return `Violating-Arrayelement at index ${i}. ${result}`;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
else {
|
|
715
|
+
return condition.check(value);
|
|
716
|
+
}
|
|
717
|
+
return true;
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* A parameter-decorator factory using the {@link AE.checkAlgorithm } with either multiple or a single one
|
|
721
|
+
* of the **realConditions** to check the tagged parameter-value against with.
|
|
722
|
+
* When specifying an **index** and the tagged parameter's **value** is an {@link Array }, the **realConditions** apply to the
|
|
723
|
+
* element at the specified **index**.
|
|
724
|
+
* If the {@link Array } is too short the currently processed { check: (toCheck: any) => boolean | string } of
|
|
725
|
+
* **realConditions** will be verified to TRUE automatically, considering optional parameters.
|
|
726
|
+
* If an **index** is specified but the tagged parameter's value isn't an array, the **index** is treated as being undefined.
|
|
727
|
+
* If **index** is undefined and the tagged parameter's value is an {@link Array } each element of it will be checked
|
|
728
|
+
* against the **realConditions**.
|
|
729
|
+
*
|
|
730
|
+
* @param realConditions Either one or more { check: (toCheck: any) => boolean | string } to check the tagged parameter-value
|
|
731
|
+
* against with.
|
|
732
|
+
* @param index See the {@link AE.checkAlgorithm }.
|
|
733
|
+
* @param idxEnd See the {@link AE.checkAlgorithm }.
|
|
734
|
+
* @param path See {@link DBC.decPrecondition }.
|
|
735
|
+
* @param hint See {@link DBC.decPrecondition }.
|
|
736
|
+
* @param dbc See {@link DBC.decPrecondition }.
|
|
737
|
+
*
|
|
738
|
+
* @returns A {@link string } as soon as one { check: (toCheck: any) => boolean | string } of **realConditions** returns one.
|
|
739
|
+
* Otherwise TRUE. */
|
|
740
|
+
static PRE(realConditions, index = undefined, idxEnd = undefined, path = undefined, hint = undefined, dbc = undefined) {
|
|
741
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.decPrecondition((
|
|
742
|
+
// biome-ignore lint/suspicious/noExplicitAny: Must match DBC.decPrecondition signature
|
|
743
|
+
value, target, methodName, parameterIndex) => {
|
|
744
|
+
if (Array.isArray(realConditions)) {
|
|
745
|
+
for (const currentCondition of realConditions) {
|
|
746
|
+
const result = AE.checkAlgorithm(currentCondition, value, index, idxEnd);
|
|
747
|
+
if (typeof result !== "boolean")
|
|
748
|
+
return result;
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
else {
|
|
752
|
+
return AE.checkAlgorithm(realConditions, value, index, idxEnd);
|
|
753
|
+
}
|
|
754
|
+
return true;
|
|
755
|
+
}, dbc, path, hint);
|
|
756
|
+
}
|
|
757
|
+
/**
|
|
758
|
+
* A method-decorator factory using the {@link AE.checkAlgorithm } with either multiple or a single one
|
|
759
|
+
* of the **realConditions** to check the tagged method's return-value against with.
|
|
760
|
+
*
|
|
761
|
+
* @param realConditions Either one or more { check: (toCheck: any) => boolean | string } to check the tagged parameter-value
|
|
762
|
+
* against with.
|
|
763
|
+
* @param index See the {@link AE.checkAlgorithm }.
|
|
764
|
+
* @param idxEnd See the {@link AE.checkAlgorithm }.
|
|
765
|
+
* @param path See {@link DBC.decPrecondition }.
|
|
766
|
+
* @param hint See {@link DBC.decPrecondition }.
|
|
767
|
+
* @param dbc See {@link DBC.decPrecondition }.
|
|
768
|
+
*
|
|
769
|
+
* @returns A {@link string } as soon as one { check: (toCheck: any) => boolean | string } of **realConditions** return one.
|
|
770
|
+
* Otherwise TRUE. */
|
|
771
|
+
static POST(realConditions, index = undefined, idxEnd = undefined, path = undefined, hint = undefined, dbc = undefined) {
|
|
772
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.decPostcondition((value, target, propertyKey) => {
|
|
773
|
+
if (Array.isArray(realConditions)) {
|
|
774
|
+
for (const currentCondition of realConditions) {
|
|
775
|
+
const result = AE.checkAlgorithm(currentCondition, value, index, idxEnd);
|
|
776
|
+
if (typeof result !== "boolean")
|
|
777
|
+
return result;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
else {
|
|
781
|
+
return AE.checkAlgorithm(
|
|
782
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
783
|
+
realConditions, value, index, idxEnd);
|
|
784
|
+
}
|
|
785
|
+
return true;
|
|
786
|
+
}, dbc, path, hint);
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* A field-decorator factory using the {@link AE.checkAlgorithm } with either multiple or a single one
|
|
790
|
+
* of the **realConditions** to check the tagged field.
|
|
791
|
+
*
|
|
792
|
+
* @param realConditions Either one or more { check: (toCheck: any) => boolean | string } to check the tagged parameter-value
|
|
793
|
+
* against with.
|
|
794
|
+
* @param index See the {@link AE.checkAlgorithm }.
|
|
795
|
+
* @param idxEnd See the {@link AE.checkAlgorithm }.
|
|
796
|
+
* @param path See {@link DBC.decInvariant }.
|
|
797
|
+
* @param hint See {@link DBC.decInvariant }.
|
|
798
|
+
* @param dbc See {@link DBC.decInvariant }.
|
|
799
|
+
*
|
|
800
|
+
* @returns See {@link DBC.decInvariant }. */
|
|
801
|
+
static INVARIANT(realConditions, index = undefined, idxEnd = undefined, path = undefined, hint = undefined, dbc = undefined) {
|
|
802
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.createINVARIANT(AE, [realConditions, index, idxEnd], dbc, path, hint);
|
|
803
|
+
}
|
|
804
|
+
// #endregion Condition checking.
|
|
805
|
+
// #region Referenced Condition checking.
|
|
806
|
+
//
|
|
807
|
+
// For usage in dynamic scenarios (like global functions).
|
|
808
|
+
//
|
|
809
|
+
/**
|
|
810
|
+
* Invokes the {@link AE.checkAlgorithm } with all {@link AE.conditions } and the {@link object } {@link toCheck },
|
|
811
|
+
* {@link AE.index } & {@link AE.idxEnd }.
|
|
812
|
+
*
|
|
813
|
+
* @param toCheck See {@link AE.checkAlgorithm }.
|
|
814
|
+
*
|
|
815
|
+
* @returns See {@link EQ.checkAlgorithm}. */
|
|
816
|
+
// biome-ignore lint/suspicious/noExplicitAny: Must match DBC factory signature
|
|
817
|
+
check(toCheck) {
|
|
818
|
+
if (Array.isArray(this.conditions)) {
|
|
819
|
+
for (const currentCondition of this.conditions) {
|
|
820
|
+
const result = AE.checkAlgorithm(currentCondition, toCheck, this.index, this.idxEnd);
|
|
821
|
+
if (typeof result !== "boolean")
|
|
822
|
+
return result;
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
else {
|
|
826
|
+
return AE.checkAlgorithm(
|
|
827
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
828
|
+
this.conditions, toCheck, this.index, this.idxEnd);
|
|
829
|
+
}
|
|
830
|
+
return true;
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Creates this {@link AE } by setting the protected property {@link AE.conditions }, {@link AE.index } and {@link AE.idxEnd } used by {@link AE.check }.
|
|
834
|
+
*
|
|
835
|
+
* @param equivalent See {@link EQ.check }. */
|
|
836
|
+
constructor(conditions, index = undefined, idxEnd = undefined) {
|
|
837
|
+
super();
|
|
838
|
+
this.conditions = conditions;
|
|
839
|
+
this.index = index;
|
|
840
|
+
this.idxEnd = idxEnd;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
|
|
845
|
+
/***/ },
|
|
846
|
+
|
|
847
|
+
/***/ "./src/DBC/COMPARISON.ts"
|
|
848
|
+
/*!*******************************!*\
|
|
849
|
+
!*** ./src/DBC/COMPARISON.ts ***!
|
|
850
|
+
\*******************************/
|
|
851
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
852
|
+
|
|
853
|
+
__webpack_require__.r(__webpack_exports__);
|
|
854
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
855
|
+
/* harmony export */ COMPARISON: () => (/* binding */ COMPARISON)
|
|
856
|
+
/* harmony export */ });
|
|
857
|
+
/* harmony import */ var _DBC__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../DBC */ "./src/DBC.ts");
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* A {@link DBC } defining a comparison between two {@link object }s.
|
|
861
|
+
*
|
|
862
|
+
* @remarks
|
|
863
|
+
* Maintainer: Callari, Salvatore (XDBC@WaXCode.net) */
|
|
864
|
+
class COMPARISON extends _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC {
|
|
865
|
+
// #region Condition checking.
|
|
866
|
+
/**
|
|
867
|
+
* Does a comparison between the {@link object } **toCheck** and the **equivalent**.
|
|
868
|
+
*
|
|
869
|
+
* @param toCheck The value that has to be equal to it's possible **equivalent** for this {@link DBC } to be fulfilled.
|
|
870
|
+
* @param equivalent The {@link object } the one **toCheck** has to be equal to in order for this {@link DBC } to be
|
|
871
|
+
* fulfilled.
|
|
872
|
+
*
|
|
873
|
+
* @returns TRUE if the value **toCheck** and the **equivalent** are equal to each other, otherwise FALSE. */
|
|
874
|
+
// biome-ignore lint/suspicious/noExplicitAny: Necessary for dynamic comparison
|
|
875
|
+
static checkAlgorithm(toCheck, equivalent, equalityPermitted, invert) {
|
|
876
|
+
if (equalityPermitted && !invert && toCheck < equivalent) {
|
|
877
|
+
return `Value has to be greater than or equal to "${equivalent}"`;
|
|
878
|
+
}
|
|
879
|
+
if (equalityPermitted && invert && toCheck > equivalent) {
|
|
880
|
+
return `Value has to be less than or equal to "${equivalent}"`;
|
|
881
|
+
}
|
|
882
|
+
if (!equalityPermitted && !invert && toCheck <= equivalent) {
|
|
883
|
+
return `Value has to be greater than "${equivalent}"`;
|
|
884
|
+
}
|
|
885
|
+
if (!equalityPermitted && invert && toCheck >= equivalent) {
|
|
886
|
+
return `Value has to be less than "${equivalent}"`;
|
|
887
|
+
}
|
|
888
|
+
return true;
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* A parameter-decorator factory using the {@link COMPARISON.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
892
|
+
* by the tagged parameter.
|
|
893
|
+
*
|
|
894
|
+
* @param equivalent See {@link COMPARISON.checkAlgorithm }.
|
|
895
|
+
* @param equalityPermitted See {@link COMPARISON.checkAlgorithm }.
|
|
896
|
+
* @param path See {@link DBC.decPrecondition }.
|
|
897
|
+
* @param hint See {@link DBC.decPrecondition }.
|
|
898
|
+
* @param dbc See {@link DBC.decPrecondition }.
|
|
899
|
+
*
|
|
900
|
+
* @returns See {@link DBC.decPrecondition }. */
|
|
901
|
+
static PRE(
|
|
902
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
903
|
+
equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
904
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.createPRE(COMPARISON.checkAlgorithm, [equivalent, equalityPermitted, invert], dbc, path, hint);
|
|
905
|
+
}
|
|
906
|
+
/**
|
|
907
|
+
* A method-decorator factory using the {@link COMPARISON.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
908
|
+
* by the tagged method's returnvalue.
|
|
909
|
+
*
|
|
910
|
+
* @param equivalent See {@link COMPARISON.checkAlgorithm }.
|
|
911
|
+
* @param equalityPermitted See {@link COMPARISON.checkAlgorithm }.
|
|
912
|
+
* @param path See {@link DBC.Postcondition }.
|
|
913
|
+
* @param hint See {@link DBC.decPostcondition }.
|
|
914
|
+
* @param dbc See {@link DBC.decPostcondition }.
|
|
915
|
+
*
|
|
916
|
+
* @returns See {@link DBC.decPostcondition }. */
|
|
917
|
+
static POST(
|
|
918
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
919
|
+
equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
920
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.createPOST(COMPARISON.checkAlgorithm, [equivalent, equalityPermitted, invert], dbc, path, hint);
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* A field-decorator factory using the {@link COMPARISON.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
924
|
+
* by the tagged field.
|
|
925
|
+
*
|
|
926
|
+
* @param equivalent See {@link COMPARISON.checkAlgorithm }.
|
|
927
|
+
* @param equalityPermitted See {@link COMPARISON.checkAlgorithm }.
|
|
928
|
+
* @param path See {@link DBC.decInvariant }.
|
|
929
|
+
* @param hint See {@link DBC.decInvariant }.
|
|
930
|
+
* @param dbc See {@link DBC.decInvariant }.
|
|
931
|
+
*
|
|
932
|
+
* @returns See {@link DBC.decInvariant }. */
|
|
933
|
+
static INVARIANT(
|
|
934
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
935
|
+
equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
936
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.createINVARIANT(COMPARISON, [equivalent, equalityPermitted, invert], dbc, path, hint);
|
|
937
|
+
}
|
|
938
|
+
// #endregion Condition checking.
|
|
939
|
+
// #region Referenced Condition checking.
|
|
940
|
+
// #region Dynamic usage.
|
|
941
|
+
/**
|
|
942
|
+
* Invokes the {@link COMPARISON.checkAlgorithm } passing the value **toCheck**, {@link COMPARISON.equivalent } and {@link COMPARISON.invert }.
|
|
943
|
+
*
|
|
944
|
+
* @param toCheck See {@link COMPARISON.checkAlgorithm }.
|
|
945
|
+
*
|
|
946
|
+
* @returns See {@link COMPARISON.checkAlgorithm}. */
|
|
947
|
+
// biome-ignore lint/suspicious/noExplicitAny: Necessary for dynamic comparison
|
|
948
|
+
check(toCheck) {
|
|
949
|
+
return COMPARISON.checkAlgorithm(toCheck, this.equivalent, this.equalityPermitted, this.invert);
|
|
950
|
+
}
|
|
951
|
+
/**
|
|
952
|
+
* Creates this {@link COMPARISON } by setting the protected property {@link COMPARISON.equivalent }, {@link COMPARISON.equalityPermitted } and {@link COMPARISON.invert } used by {@link COMPARISON.check }.
|
|
953
|
+
*
|
|
954
|
+
* @param equivalent See {@link COMPARISON.check }.
|
|
955
|
+
* @param equalityPermitted See {@link COMPARISON.check }.
|
|
956
|
+
* @param invert See {@link COMPARISON.check }. */
|
|
957
|
+
constructor(
|
|
958
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
959
|
+
equivalent, equalityPermitted = false, invert = false) {
|
|
960
|
+
super();
|
|
961
|
+
this.equivalent = equivalent;
|
|
962
|
+
this.equalityPermitted = equalityPermitted;
|
|
963
|
+
this.invert = invert;
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
|
|
968
|
+
/***/ },
|
|
969
|
+
|
|
970
|
+
/***/ "./src/DBC/COMPARISON/GREATER.ts"
|
|
971
|
+
/*!***************************************!*\
|
|
972
|
+
!*** ./src/DBC/COMPARISON/GREATER.ts ***!
|
|
973
|
+
\***************************************/
|
|
974
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
975
|
+
|
|
976
|
+
__webpack_require__.r(__webpack_exports__);
|
|
977
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
978
|
+
/* harmony export */ GREATER: () => (/* binding */ GREATER)
|
|
979
|
+
/* harmony export */ });
|
|
980
|
+
/* harmony import */ var _COMPARISON__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../COMPARISON */ "./src/DBC/COMPARISON.ts");
|
|
981
|
+
|
|
982
|
+
/** See {@link COMPARISON }. */
|
|
983
|
+
class GREATER extends _COMPARISON__WEBPACK_IMPORTED_MODULE_0__.COMPARISON {
|
|
984
|
+
/** See {@link COMPARISON.PRE }. */
|
|
985
|
+
static PRE(
|
|
986
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
987
|
+
equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
988
|
+
return _COMPARISON__WEBPACK_IMPORTED_MODULE_0__.COMPARISON.PRE(equivalent, false, false, path, hint, dbc);
|
|
989
|
+
}
|
|
990
|
+
/** See {@link COMPARISON.POST }. */
|
|
991
|
+
static POST(
|
|
992
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
993
|
+
equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
994
|
+
return _COMPARISON__WEBPACK_IMPORTED_MODULE_0__.COMPARISON.POST(equivalent, false, false, path, hint, dbc);
|
|
995
|
+
}
|
|
996
|
+
/** See {@link COMPARISON.INVARIANT }. */
|
|
997
|
+
static INVARIANT(
|
|
998
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
999
|
+
equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
1000
|
+
return _COMPARISON__WEBPACK_IMPORTED_MODULE_0__.COMPARISON.INVARIANT(equivalent, false, false, path, hint, dbc);
|
|
1001
|
+
}
|
|
1002
|
+
/** See {@link COMPARISON.constructor }. */
|
|
1003
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
1004
|
+
constructor(equivalent) {
|
|
1005
|
+
super(equivalent, false, false);
|
|
1006
|
+
this.equivalent = equivalent;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
|
|
1011
|
+
/***/ },
|
|
1012
|
+
|
|
1013
|
+
/***/ "./src/DBC/COMPARISON/GREATER_OR_EQUAL.ts"
|
|
1014
|
+
/*!************************************************!*\
|
|
1015
|
+
!*** ./src/DBC/COMPARISON/GREATER_OR_EQUAL.ts ***!
|
|
1016
|
+
\************************************************/
|
|
1017
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
1018
|
+
|
|
1019
|
+
__webpack_require__.r(__webpack_exports__);
|
|
1020
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
1021
|
+
/* harmony export */ GREATER_OR_EQUAL: () => (/* binding */ GREATER_OR_EQUAL)
|
|
1022
|
+
/* harmony export */ });
|
|
1023
|
+
/* harmony import */ var _COMPARISON__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../COMPARISON */ "./src/DBC/COMPARISON.ts");
|
|
1024
|
+
|
|
1025
|
+
/** See {@link COMPARISON }. */
|
|
1026
|
+
class GREATER_OR_EQUAL extends _COMPARISON__WEBPACK_IMPORTED_MODULE_0__.COMPARISON {
|
|
1027
|
+
/** See {@link COMPARISON.PRE }. */
|
|
1028
|
+
static PRE(
|
|
1029
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
1030
|
+
equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
1031
|
+
return _COMPARISON__WEBPACK_IMPORTED_MODULE_0__.COMPARISON.PRE(equivalent, true, false, path, hint, dbc);
|
|
1032
|
+
}
|
|
1033
|
+
/** See {@link COMPARISON.POST }. */
|
|
1034
|
+
static POST(
|
|
1035
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
1036
|
+
equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
1037
|
+
return _COMPARISON__WEBPACK_IMPORTED_MODULE_0__.COMPARISON.POST(equivalent, true, false, path, hint, dbc);
|
|
1038
|
+
}
|
|
1039
|
+
/** See {@link COMPARISON.INVARIANT }. */
|
|
1040
|
+
static INVARIANT(
|
|
1041
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
1042
|
+
equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
1043
|
+
return _COMPARISON__WEBPACK_IMPORTED_MODULE_0__.COMPARISON.INVARIANT(equivalent, true, false, path, hint, dbc);
|
|
1044
|
+
}
|
|
1045
|
+
/** See {@link COMPARISON.constructor }. */
|
|
1046
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
1047
|
+
constructor(equivalent) {
|
|
1048
|
+
super(equivalent, true, false);
|
|
1049
|
+
this.equivalent = equivalent;
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
|
|
1054
|
+
/***/ },
|
|
1055
|
+
|
|
1056
|
+
/***/ "./src/DBC/COMPARISON/LESS.ts"
|
|
1057
|
+
/*!************************************!*\
|
|
1058
|
+
!*** ./src/DBC/COMPARISON/LESS.ts ***!
|
|
1059
|
+
\************************************/
|
|
1060
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
1061
|
+
|
|
1062
|
+
__webpack_require__.r(__webpack_exports__);
|
|
1063
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
1064
|
+
/* harmony export */ LESS: () => (/* binding */ LESS)
|
|
1065
|
+
/* harmony export */ });
|
|
1066
|
+
/* harmony import */ var _COMPARISON__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../COMPARISON */ "./src/DBC/COMPARISON.ts");
|
|
1067
|
+
|
|
1068
|
+
/** See {@link COMPARISON }. */
|
|
1069
|
+
class LESS extends _COMPARISON__WEBPACK_IMPORTED_MODULE_0__.COMPARISON {
|
|
1070
|
+
/** See {@link COMPARISON.PRE }. */
|
|
1071
|
+
static PRE(
|
|
1072
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
1073
|
+
equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
1074
|
+
return _COMPARISON__WEBPACK_IMPORTED_MODULE_0__.COMPARISON.PRE(equivalent, false, true, path, hint, dbc);
|
|
1075
|
+
}
|
|
1076
|
+
/** See {@link COMPARISON.POST }. */
|
|
1077
|
+
static POST(
|
|
1078
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
1079
|
+
equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
1080
|
+
return _COMPARISON__WEBPACK_IMPORTED_MODULE_0__.COMPARISON.POST(equivalent, false, true, path, hint, dbc);
|
|
1081
|
+
}
|
|
1082
|
+
/** See {@link COMPARISON.INVARIANT }. */
|
|
1083
|
+
static INVARIANT(
|
|
1084
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
1085
|
+
equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
1086
|
+
return _COMPARISON__WEBPACK_IMPORTED_MODULE_0__.COMPARISON.INVARIANT(equivalent, false, true, path, hint, dbc);
|
|
1087
|
+
}
|
|
1088
|
+
/** See {@link COMPARISON.constructor }. */
|
|
1089
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
1090
|
+
constructor(equivalent) {
|
|
1091
|
+
super(equivalent, false, true);
|
|
1092
|
+
this.equivalent = equivalent;
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
/***/ },
|
|
1098
|
+
|
|
1099
|
+
/***/ "./src/DBC/COMPARISON/LESS_OR_EQUAL.ts"
|
|
1100
|
+
/*!*********************************************!*\
|
|
1101
|
+
!*** ./src/DBC/COMPARISON/LESS_OR_EQUAL.ts ***!
|
|
1102
|
+
\*********************************************/
|
|
1103
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
1104
|
+
|
|
1105
|
+
__webpack_require__.r(__webpack_exports__);
|
|
1106
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
1107
|
+
/* harmony export */ LESS_OR_EQUAL: () => (/* binding */ LESS_OR_EQUAL)
|
|
1108
|
+
/* harmony export */ });
|
|
1109
|
+
/* harmony import */ var _COMPARISON__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../COMPARISON */ "./src/DBC/COMPARISON.ts");
|
|
1110
|
+
|
|
1111
|
+
/** See {@link COMPARISON }. */
|
|
1112
|
+
class LESS_OR_EQUAL extends _COMPARISON__WEBPACK_IMPORTED_MODULE_0__.COMPARISON {
|
|
1113
|
+
/** See {@link COMPARISON.PRE }. */
|
|
1114
|
+
static PRE(
|
|
1115
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
1116
|
+
equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
1117
|
+
return _COMPARISON__WEBPACK_IMPORTED_MODULE_0__.COMPARISON.PRE(equivalent, true, true, path, hint, dbc);
|
|
1118
|
+
}
|
|
1119
|
+
/** See {@link COMPARISON.POST }. */
|
|
1120
|
+
static POST(
|
|
1121
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
1122
|
+
equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
1123
|
+
return _COMPARISON__WEBPACK_IMPORTED_MODULE_0__.COMPARISON.POST(equivalent, true, true, path, hint, dbc);
|
|
1124
|
+
}
|
|
1125
|
+
/** See {@link COMPARISON.INVARIANT }. */
|
|
1126
|
+
static INVARIANT(
|
|
1127
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
1128
|
+
equivalent, equalityPermitted = false, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
1129
|
+
return _COMPARISON__WEBPACK_IMPORTED_MODULE_0__.COMPARISON.INVARIANT(equivalent, true, true, path, hint, dbc);
|
|
1130
|
+
}
|
|
1131
|
+
/** See {@link COMPARISON.constructor }. */
|
|
1132
|
+
// biome-ignore lint/suspicious/noExplicitAny: Comparison target can be any numeric value
|
|
1133
|
+
constructor(equivalent) {
|
|
1134
|
+
super(equivalent, true, true);
|
|
1135
|
+
this.equivalent = equivalent;
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
/***/ },
|
|
1141
|
+
|
|
1142
|
+
/***/ "./src/DBC/EQ.ts"
|
|
1143
|
+
/*!***********************!*\
|
|
1144
|
+
!*** ./src/DBC/EQ.ts ***!
|
|
1145
|
+
\***********************/
|
|
1146
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
1147
|
+
|
|
1148
|
+
__webpack_require__.r(__webpack_exports__);
|
|
1149
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
1150
|
+
/* harmony export */ EQ: () => (/* binding */ EQ)
|
|
1151
|
+
/* harmony export */ });
|
|
1152
|
+
/* harmony import */ var _DBC__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../DBC */ "./src/DBC.ts");
|
|
1153
|
+
|
|
1154
|
+
/**
|
|
1155
|
+
* A {@link DBC } defining that two {@link object }s gotta be equal.
|
|
1156
|
+
*
|
|
1157
|
+
* @remarks
|
|
1158
|
+
* Maintainer: Callari, Salvatore (XDBC@WaXCode.net) */
|
|
1159
|
+
class EQ extends _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC {
|
|
1160
|
+
// #region Condition checking.
|
|
1161
|
+
/**
|
|
1162
|
+
* Checks if the value **toCheck** is equal to the specified **equivalent**.
|
|
1163
|
+
*
|
|
1164
|
+
* @param toCheck The value that has to be equal to it's possible **equivalent** for this {@link DBC } to be fulfilled.
|
|
1165
|
+
* @param equivalent The {@link object } the one **toCheck** has to be equal to in order for this {@link DBC } to be
|
|
1166
|
+
* fulfilled.
|
|
1167
|
+
*
|
|
1168
|
+
* @returns TRUE if the value **toCheck** and the **equivalent** are equal to each other, otherwise FALSE. */
|
|
1169
|
+
static checkAlgorithm(
|
|
1170
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
1171
|
+
toCheck, equivalent, invert) {
|
|
1172
|
+
if (!invert && equivalent !== toCheck) {
|
|
1173
|
+
return `Value has to be equal to "${equivalent}"`;
|
|
1174
|
+
}
|
|
1175
|
+
if (invert && equivalent === toCheck) {
|
|
1176
|
+
return `Value must not be equal to "${equivalent}"`;
|
|
1177
|
+
}
|
|
1178
|
+
return true;
|
|
1179
|
+
}
|
|
1180
|
+
/**
|
|
1181
|
+
* A parameter-decorator factory using the {@link EQ.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
1182
|
+
* by the tagged parameter.
|
|
1183
|
+
*
|
|
1184
|
+
* @param equivalent See {@link EQ.checkAlgorithm }.
|
|
1185
|
+
* @param path See {@link DBC.decPrecondition }.
|
|
1186
|
+
* @param dbc See {@link DBC.decPrecondition }.
|
|
1187
|
+
*
|
|
1188
|
+
* @returns See {@link DBC.decPrecondition }. */
|
|
1189
|
+
static PRE(
|
|
1190
|
+
// biome-ignore lint/suspicious/noExplicitAny: To check for UNDEFINED and NULL.
|
|
1191
|
+
equivalent, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
1192
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.createPRE(EQ.checkAlgorithm, [equivalent, invert], dbc, path, hint);
|
|
1193
|
+
}
|
|
1194
|
+
/**
|
|
1195
|
+
* A method-decorator factory using the {@link EQ.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
1196
|
+
* by the tagged method's returnvalue.
|
|
1197
|
+
*
|
|
1198
|
+
* @param equivalent See {@link EQ.checkAlgorithm }.
|
|
1199
|
+
* @param path See {@link DBC.Postcondition }.
|
|
1200
|
+
* @param dbc See {@link DBC.decPostcondition }.
|
|
1201
|
+
*
|
|
1202
|
+
* @returns See {@link DBC.decPostcondition }. */
|
|
1203
|
+
static POST(
|
|
1204
|
+
// biome-ignore lint/suspicious/noExplicitAny: To check for UNDEFINED and NULL.
|
|
1205
|
+
equivalent, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
1206
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.createPOST(EQ.checkAlgorithm, [equivalent, invert], dbc, path, hint);
|
|
1207
|
+
}
|
|
1208
|
+
/**
|
|
1209
|
+
* A field-decorator factory using the {@link EQ.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
1210
|
+
* by the tagged field.
|
|
1211
|
+
*
|
|
1212
|
+
* @param equivalent See {@link EQ.checkAlgorithm }.
|
|
1213
|
+
* @param path See {@link DBC.decInvariant }.
|
|
1214
|
+
* @param dbc See {@link DBC.decInvariant }.
|
|
1215
|
+
*
|
|
1216
|
+
* @returns See {@link DBC.decInvariant }. */
|
|
1217
|
+
static INVARIANT(
|
|
1218
|
+
// biome-ignore lint/suspicious/noExplicitAny: To check for UNDEFINED and NULL.
|
|
1219
|
+
equivalent, invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
1220
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.createINVARIANT(EQ, [equivalent, invert], dbc, path, hint);
|
|
1221
|
+
}
|
|
1222
|
+
// #endregion Condition checking.
|
|
1223
|
+
// #region Referenced Condition checking.
|
|
1224
|
+
//
|
|
1225
|
+
// For usage in dynamic scenarios (like with AE-DBC).
|
|
1226
|
+
//
|
|
1227
|
+
/**
|
|
1228
|
+
* Invokes the {@link EQ.checkAlgorithm } passing the value **toCheck**, {@link EQ.equivalent } and {@link EQ.invert }.
|
|
1229
|
+
*
|
|
1230
|
+
* @param toCheck See {@link EQ.checkAlgorithm }.
|
|
1231
|
+
*
|
|
1232
|
+
* @returns See {@link EQ.checkAlgorithm}. */
|
|
1233
|
+
// biome-ignore lint/suspicious/noExplicitAny: Necessary to check against NULL & UNDEFINED.
|
|
1234
|
+
check(toCheck) {
|
|
1235
|
+
return EQ.checkAlgorithm(toCheck, this.equivalent, this.invert);
|
|
1236
|
+
}
|
|
1237
|
+
/**
|
|
1238
|
+
* Invokes the {@link EQ.checkAlgorithm } passing the value **toCheck** and the specified **type** .
|
|
1239
|
+
*
|
|
1240
|
+
* @param toCheck See {@link EQ.checkAlgorithm }.
|
|
1241
|
+
*
|
|
1242
|
+
* @returns The **CANDIDATE** **toCheck** doesn't fulfill this {@link EQ }.
|
|
1243
|
+
*
|
|
1244
|
+
* @throws A {@link DBC.Infringement } if the **CANDIDATE** **toCheck** does not fulfill this {@link EQ }.*/
|
|
1245
|
+
static tsCheck(toCheck, equivalent, hint = undefined, id = undefined) {
|
|
1246
|
+
const result = EQ.checkAlgorithm(toCheck, equivalent, false);
|
|
1247
|
+
if (result) {
|
|
1248
|
+
return toCheck;
|
|
1249
|
+
}
|
|
1250
|
+
throw new _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.Infringement(`${id ? `(${id}) ` : ""}${result} ${hint ? `✨ ${hint} ✨` : ""}`);
|
|
1251
|
+
}
|
|
1252
|
+
/**
|
|
1253
|
+
* Creates this {@link EQ } by setting the protected property {@link EQ.equivalent } used by {@link EQ.check }.
|
|
1254
|
+
*
|
|
1255
|
+
* @param equivalent See {@link EQ.check }. */
|
|
1256
|
+
constructor(
|
|
1257
|
+
// biome-ignore lint/suspicious/noExplicitAny: To be able to match UNDEFINED and NULL.
|
|
1258
|
+
equivalent, invert = false) {
|
|
1259
|
+
super();
|
|
1260
|
+
this.equivalent = equivalent;
|
|
1261
|
+
this.invert = invert;
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
/***/ },
|
|
1267
|
+
|
|
1268
|
+
/***/ "./src/DBC/EQ/DIFFERENT.ts"
|
|
1269
|
+
/*!*********************************!*\
|
|
1270
|
+
!*** ./src/DBC/EQ/DIFFERENT.ts ***!
|
|
1271
|
+
\*********************************/
|
|
1272
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
1273
|
+
|
|
1274
|
+
__webpack_require__.r(__webpack_exports__);
|
|
1275
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
1276
|
+
/* harmony export */ DIFFERENT: () => (/* binding */ DIFFERENT)
|
|
1277
|
+
/* harmony export */ });
|
|
1278
|
+
/* harmony import */ var _EQ__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../EQ */ "./src/DBC/EQ.ts");
|
|
1279
|
+
|
|
1280
|
+
/**
|
|
1281
|
+
* DIFFERENT class for inequality comparisons.
|
|
1282
|
+
*
|
|
1283
|
+
* This class extends EQ and provides methods to check if a value is different (not equal)
|
|
1284
|
+
* from a specified equivalent value. It inverts the equality check by always passing
|
|
1285
|
+
* `true` for the invert parameter to the parent EQ class methods.
|
|
1286
|
+
*
|
|
1287
|
+
* @remarks
|
|
1288
|
+
* The class provides precondition (PRE), postcondition (POST), and invariant (INVARIANT)
|
|
1289
|
+
* checks for Design by Contract programming patterns.
|
|
1290
|
+
*
|
|
1291
|
+
* @see {@link COMPARISON}
|
|
1292
|
+
* @see {@link EQ}
|
|
1293
|
+
*/
|
|
1294
|
+
class DIFFERENT extends _EQ__WEBPACK_IMPORTED_MODULE_0__.EQ {
|
|
1295
|
+
/** See {@link EQ.PRE }. Always inverts equality check. */
|
|
1296
|
+
// biome-ignore lint/suspicious/noExplicitAny: Must match parent signature
|
|
1297
|
+
static PRE(equivalent, _invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
1298
|
+
return _EQ__WEBPACK_IMPORTED_MODULE_0__.EQ.PRE(equivalent, true, path, hint, dbc);
|
|
1299
|
+
}
|
|
1300
|
+
/** See {@link EQ.POST }. Always inverts equality check. */
|
|
1301
|
+
// biome-ignore lint/suspicious/noExplicitAny: Must match parent signature
|
|
1302
|
+
static POST(equivalent, _invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
1303
|
+
return _EQ__WEBPACK_IMPORTED_MODULE_0__.EQ.POST(equivalent, true, path, hint, dbc);
|
|
1304
|
+
}
|
|
1305
|
+
/** See {@link EQ.INVARIANT }. Always inverts equality check. */
|
|
1306
|
+
// biome-ignore lint/suspicious/noExplicitAny: Must match parent signature
|
|
1307
|
+
static INVARIANT(equivalent, _invert = false, path = undefined, hint = undefined, dbc = undefined) {
|
|
1308
|
+
return _EQ__WEBPACK_IMPORTED_MODULE_0__.EQ.INVARIANT(equivalent, true, path, hint, dbc);
|
|
1309
|
+
}
|
|
1310
|
+
/** See {@link EQ.constructor }. */
|
|
1311
|
+
// biome-ignore lint/suspicious/noExplicitAny: Must match parent signature
|
|
1312
|
+
constructor(equivalent) {
|
|
1313
|
+
super(equivalent, true);
|
|
1314
|
+
this.equivalent = equivalent;
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
/***/ },
|
|
1320
|
+
|
|
1321
|
+
/***/ "./src/DBC/INSTANCE.ts"
|
|
1322
|
+
/*!*****************************!*\
|
|
1323
|
+
!*** ./src/DBC/INSTANCE.ts ***!
|
|
1324
|
+
\*****************************/
|
|
1325
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
1326
|
+
|
|
1327
|
+
__webpack_require__.r(__webpack_exports__);
|
|
1328
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
1329
|
+
/* harmony export */ INSTANCE: () => (/* binding */ INSTANCE)
|
|
1330
|
+
/* harmony export */ });
|
|
1331
|
+
/* harmony import */ var _DBC__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../DBC */ "./src/DBC.ts");
|
|
1332
|
+
|
|
1333
|
+
/**
|
|
1334
|
+
* A {@link DBC } defining that the an {@link object }s gotta be an instance of a certain {@link INSTANCE.reference }.
|
|
1335
|
+
*
|
|
1336
|
+
* @remarks
|
|
1337
|
+
* Maintainer: Salvatore Callari (XDBC@WaXCode.net) */
|
|
1338
|
+
class INSTANCE extends _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC {
|
|
1339
|
+
/**
|
|
1340
|
+
* Checks if the value **toCheck** is an instance of the specified **reference**.
|
|
1341
|
+
*
|
|
1342
|
+
* @param toCheck The value that has to be an instance of the **reference** in order for this {@link DBC }
|
|
1343
|
+
* to be fulfilled.
|
|
1344
|
+
* @param reference The {@link object } the one **toCheck** has to be an instance of.
|
|
1345
|
+
*
|
|
1346
|
+
* @returns TRUE if the value **toCheck** is is an instance of the *reference**, **undefined** or **null**, otherwise FALSE. */
|
|
1347
|
+
// biome-ignore lint/suspicious/noExplicitAny: In order to perform an "instanceof" check.
|
|
1348
|
+
static checkAlgorithm(toCheck, ...references) {
|
|
1349
|
+
if (toCheck === null || toCheck === undefined) {
|
|
1350
|
+
return true;
|
|
1351
|
+
}
|
|
1352
|
+
for (const ref of references) {
|
|
1353
|
+
if (toCheck instanceof ref) {
|
|
1354
|
+
return true;
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
return `Value has to be an instance of "${references.map((ref) => ref.name || ref).join(", ")}" but is of type "${typeof toCheck}"`;
|
|
1358
|
+
}
|
|
1359
|
+
/**
|
|
1360
|
+
* A parameter-decorator factory using the {@link INSTANCE.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
1361
|
+
* by the tagged parameter.
|
|
1362
|
+
*
|
|
1363
|
+
* @param reference See {@link INSTANCE.checkAlgorithm }.
|
|
1364
|
+
* @param path See {@link DBC.decPrecondition }.
|
|
1365
|
+
* @param dbc See {@link DBC.decPrecondition }.
|
|
1366
|
+
*
|
|
1367
|
+
* @returns See {@link DBC.decPrecondition }. */
|
|
1368
|
+
static PRE(
|
|
1369
|
+
// biome-ignore lint/suspicious/noExplicitAny: In order to perform an "instanceof" check.
|
|
1370
|
+
reference, path = undefined, hint = undefined, dbc = undefined) {
|
|
1371
|
+
const refs = Array.isArray(reference) ? reference : [reference];
|
|
1372
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.createPRE(INSTANCE.checkAlgorithm, refs, dbc, path, hint);
|
|
1373
|
+
}
|
|
1374
|
+
/**
|
|
1375
|
+
* A method-decorator factory using the {@link INSTANCE.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
1376
|
+
* by the tagged method's returnvalue.
|
|
1377
|
+
*
|
|
1378
|
+
* @param reference See {@link INSTANCE.checkAlgorithm }.
|
|
1379
|
+
* @param path See {@link DBC.Postcondition }.
|
|
1380
|
+
* @param dbc See {@link DBC.decPostcondition }.
|
|
1381
|
+
*
|
|
1382
|
+
* @returns See {@link DBC.decPostcondition }. */
|
|
1383
|
+
static POST(
|
|
1384
|
+
// biome-ignore lint/suspicious/noExplicitAny: In order to perform an "instanceof" check.
|
|
1385
|
+
reference, path = undefined, hint = undefined, dbc = undefined) {
|
|
1386
|
+
const refs = Array.isArray(reference) ? reference : [reference];
|
|
1387
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.createPOST(INSTANCE.checkAlgorithm, refs, dbc, path, hint);
|
|
1388
|
+
}
|
|
1389
|
+
/**
|
|
1390
|
+
* A field-decorator factory using the {@link INSTANCE.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
1391
|
+
* by the tagged method's returnvalue.
|
|
1392
|
+
*
|
|
1393
|
+
* @param reference See {@link INSTANCE.checkAlgorithm }.
|
|
1394
|
+
* @param path See {@link DBC.decInvariant }.
|
|
1395
|
+
* @param dbc See {@link DBC.decInvariant }.
|
|
1396
|
+
*
|
|
1397
|
+
* @returns See {@link DBC.decInvariant }. */
|
|
1398
|
+
static INVARIANT(
|
|
1399
|
+
// biome-ignore lint/suspicious/noExplicitAny: In order to perform an "instanceof" check.
|
|
1400
|
+
reference, path = undefined, hint = undefined, dbc = undefined) {
|
|
1401
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.createINVARIANT(INSTANCE, [reference], dbc, path, hint);
|
|
1402
|
+
}
|
|
1403
|
+
// #endregion Condition checking.
|
|
1404
|
+
// #region Referenced Condition checking.
|
|
1405
|
+
//
|
|
1406
|
+
// For usage in dynamic scenarios (like with AE-DBC).
|
|
1407
|
+
//
|
|
1408
|
+
/**
|
|
1409
|
+
* Invokes the {@link INSTANCE.checkAlgorithm } passing the value **toCheck** and the {@link INSTANCE.reference } .
|
|
1410
|
+
*
|
|
1411
|
+
* @param toCheck See {@link INSTANCE.checkAlgorithm }.
|
|
1412
|
+
*
|
|
1413
|
+
* @returns See {@link INSTANCE.checkAlgorithm}. */
|
|
1414
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
1415
|
+
check(toCheck) {
|
|
1416
|
+
return Array.isArray(this.reference)
|
|
1417
|
+
? INSTANCE.checkAlgorithm(toCheck, ...this.reference)
|
|
1418
|
+
: INSTANCE.checkAlgorithm(toCheck, this.reference);
|
|
1419
|
+
}
|
|
1420
|
+
/**
|
|
1421
|
+
* Type-safe check that validates if a value is an instance of a specified reference.
|
|
1422
|
+
*
|
|
1423
|
+
* @param toCheck The value to check for instance validity.
|
|
1424
|
+
* @param reference The {@link object } the one **toCheck** has to be an instance of.
|
|
1425
|
+
* @param hint An optional {@link string } providing extra information in case of an infringement.
|
|
1426
|
+
* @param id A {@link string } identifying this {@link INSTANCE } via the {@link DBC.Infringement }-Message.
|
|
1427
|
+
*
|
|
1428
|
+
* @returns The **CANDIDATE** **toCheck** if it fulfills this {@link INSTANCE }.
|
|
1429
|
+
*
|
|
1430
|
+
* @throws A {@link DBC.Infringement } if the **CANDIDATE** **toCheck** does not fulfill this {@link INSTANCE }. */
|
|
1431
|
+
static tsCheck(toCheck, reference, hint = undefined, id = undefined) {
|
|
1432
|
+
return INSTANCE.tsCheckMulti(toCheck, [reference], hint, id);
|
|
1433
|
+
}
|
|
1434
|
+
/**
|
|
1435
|
+
* Invokes the {@link INSTANCE.checkAlgorithm } passing the value **toCheck** and the {@link INSTANCE.reference } .
|
|
1436
|
+
*
|
|
1437
|
+
* @param toCheck See {@link INSTANCE.checkAlgorithm }.
|
|
1438
|
+
* @param reference See {@link INSTANCE.checkAlgorithm }.
|
|
1439
|
+
* @param hint An optional {@link string } providing extra information in case of an infringement.
|
|
1440
|
+
* @param id A {@link string } identifying this {@link INSTANCE } via the {@link DBC.Infringement }-Message.
|
|
1441
|
+
*
|
|
1442
|
+
* @returns The **CANDIDATE** **toCheck** doesn't fulfill this {@link INSTANCE }.
|
|
1443
|
+
*
|
|
1444
|
+
* @throws A {@link DBC.Infringement } if the **CANDIDATE** **toCheck** does not fulfill this {@link DEFINED }. */
|
|
1445
|
+
static tsCheckMulti(toCheck, references, hint = undefined, id = undefined) {
|
|
1446
|
+
const result = INSTANCE.checkAlgorithm(toCheck, ...references);
|
|
1447
|
+
if (result === true) {
|
|
1448
|
+
return toCheck;
|
|
1449
|
+
}
|
|
1450
|
+
throw new _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.Infringement(`${id ? `(${id}) ` : ""}${result} ${hint ? `✨ ${hint} ✨` : ""}`);
|
|
1451
|
+
}
|
|
1452
|
+
/**
|
|
1453
|
+
* Creates this {@link INSTANCE } by setting the protected property {@link INSTANCE.reference } used by {@link INSTANCE.check }.
|
|
1454
|
+
*
|
|
1455
|
+
* @param reference See {@link INSTANCE.check }. */
|
|
1456
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
1457
|
+
constructor(reference) {
|
|
1458
|
+
super();
|
|
1459
|
+
this.reference = reference;
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
|
|
1464
|
+
/***/ },
|
|
1465
|
+
|
|
1466
|
+
/***/ "./src/DBC/REGEX.ts"
|
|
1467
|
+
/*!**************************!*\
|
|
1468
|
+
!*** ./src/DBC/REGEX.ts ***!
|
|
1469
|
+
\**************************/
|
|
1470
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
1471
|
+
|
|
1472
|
+
__webpack_require__.r(__webpack_exports__);
|
|
1473
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
1474
|
+
/* harmony export */ REGEX: () => (/* binding */ REGEX)
|
|
1475
|
+
/* harmony export */ });
|
|
1476
|
+
/* harmony import */ var _DBC__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../DBC */ "./src/DBC.ts");
|
|
1477
|
+
|
|
1478
|
+
/**
|
|
1479
|
+
* A {@link DBC } providing {@link REGEX }-contracts and standard {@link RegExp } for common use cases in {@link REGEX.stdExp }.
|
|
1480
|
+
*
|
|
1481
|
+
* @remarks
|
|
1482
|
+
* Maintainer: Callari, Salvatore (XDBC@WaXCode.net) */
|
|
1483
|
+
class REGEX extends _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC {
|
|
1484
|
+
static get stdExp() {
|
|
1485
|
+
if (!REGEX._stdExp) {
|
|
1486
|
+
REGEX._stdExp = {
|
|
1487
|
+
htmlAttributeName: /^[a-zA-Z_:][a-zA-Z0-9_.:-]*$/,
|
|
1488
|
+
eMail: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/i,
|
|
1489
|
+
property: /^[$_A-Za-z][$_A-Za-z0-9]*$/,
|
|
1490
|
+
url: /^(?:https?|ftp):\/\/[^\s/$.?#].[^\s]*$/i,
|
|
1491
|
+
keyPath: /^([a-zA-Z_$][a-zA-Z0-9_$]*\.)*[a-zA-Z_$][a-zA-Z0-9_$]*$/,
|
|
1492
|
+
date: /^\d{1,4}[.\/-]\d{1,2}[.\/-]\d{1,4}$/i,
|
|
1493
|
+
dateFormat: /^((D{1,2}[./-]M{1,2}[./-]Y{1,4})|(M{1,2}[./-]D{1,2}[./-]Y{1,4})|Y{1,4}[./-]D{1,2}[./-]M{1,2}|(Y{1,4}[./-]M{1,2}[./-]D{1,2}))$/i,
|
|
1494
|
+
cssSelector: /^(?:\*|#[\w-]+|\.[\w-]+|(?:[\w-]+|\*)(?::(?:[\w-]+(?:\([\w-]+\))?)+)?(?:\[(?:[\w-]+(?:(?:=|~=|\|=|\*=|\$=|\^=)\s*(?:"[^"]*"|'[^']*'|[\w-]+)\s*)?)?\])+|\[\s*[\w-]+\s*=\s*(?:"[^"]*"|'[^']*'|[\w-]+)\s*\])(?:,\s*(?:\*|#[\w-]+|\.[\w-]+|(?:[\w-]+|\*)(?::(?:[\w-]+(?:\([\w-]+\))?)+)?(?:\[(?:[\w-]+(?:(?:=|~=|\|=|\*=|\$=|\^=)\s*(?:"[^"]*"|'[^']*'|[\w-]+)\s*)?)?\])+|\[\s*[\w-]+\s*=\s*(?:"[^"]*"|'[^']*'|[\w-]+)\s*\]))*$/,
|
|
1495
|
+
boolean: /^(TRUE|FALSE)$/i,
|
|
1496
|
+
colorCodeHEX: /^#([A-Fa-f\d]{3,4}|[A-Fa-f\d]{6}|[A-Fa-f\d]{8})$/i,
|
|
1497
|
+
simpleHotkey: /^((Alt|Ctrl|Shift|Meta)\+)+[a-z\d]$/i,
|
|
1498
|
+
bcp47: /^(?:[a-z]{2,3}(?:-[a-z]{3}){0,3}|[a-z]{4}|[a-z]{5,8})(?:-[a-z]{4})?(?:-[a-z]{2}|-[0-9]{3})?(?:-[a-z0-9]{5,8}|-[0-9][a-z0-9]{3})*(?:-[0-9a-wy-z](?:-[a-z0-9]{2,8})+)*(?:-x(?:-[a-z0-9]{1,8})+)?$|^x(?:-[a-z0-9]{1,8})+$/i,
|
|
1499
|
+
};
|
|
1500
|
+
}
|
|
1501
|
+
return REGEX._stdExp;
|
|
1502
|
+
}
|
|
1503
|
+
// #region Condition checking.
|
|
1504
|
+
/**
|
|
1505
|
+
* Checks if the value **toCheck** is complies to the {@link RegExp } **expression**.
|
|
1506
|
+
*
|
|
1507
|
+
* @param toCheck The value that has comply to the {@link RegExp } **expression** for this {@link DBC } to be fulfilled.
|
|
1508
|
+
* @param expression The {@link RegExp } the one **toCheck** has comply to in order for this {@link DBC } to be
|
|
1509
|
+
* fulfilled.
|
|
1510
|
+
*
|
|
1511
|
+
* @returns TRUE if the value **toCheck** complies with the {@link RegExp } **expression**, otherwise FALSE. */
|
|
1512
|
+
static checkAlgorithm(toCheck, expression) {
|
|
1513
|
+
if (toCheck === undefined || toCheck === null || toCheck === "")
|
|
1514
|
+
return true;
|
|
1515
|
+
if (!expression.test(toCheck)) {
|
|
1516
|
+
return `Value has to comply to regular expression "${expression}"`;
|
|
1517
|
+
}
|
|
1518
|
+
return true;
|
|
1519
|
+
}
|
|
1520
|
+
/**
|
|
1521
|
+
* A parameter-decorator factory using the {@link REGEX.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
1522
|
+
* by the tagged parameter.
|
|
1523
|
+
*
|
|
1524
|
+
* @param expression See {@link REGEX.checkAlgorithm }.
|
|
1525
|
+
* @param path See {@link DBC.decPrecondition }.
|
|
1526
|
+
* @param dbc See {@link DBC.decPrecondition }.
|
|
1527
|
+
*
|
|
1528
|
+
* @returns See {@link DBC.decPrecondition }. */
|
|
1529
|
+
static PRE(expression, path = undefined, hint = undefined, dbc = undefined) {
|
|
1530
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.createPRE(REGEX.checkAlgorithm, [expression], dbc, path, hint);
|
|
1531
|
+
}
|
|
1532
|
+
/**
|
|
1533
|
+
* A method-decorator factory using the {@link REGEX.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
1534
|
+
* by the tagged method's returnvalue.
|
|
1535
|
+
*
|
|
1536
|
+
* @param expression See {@link REGEX.checkAlgorithm }.
|
|
1537
|
+
* @param path See {@link DBC.Postcondition }.
|
|
1538
|
+
* @param dbc See {@link DBC.decPostcondition }.
|
|
1539
|
+
* @param hint See {@link DBC.decPostcondition }.
|
|
1540
|
+
*
|
|
1541
|
+
* @returns See {@link DBC.decPostcondition }. */
|
|
1542
|
+
static POST(expression, path = undefined, hint = undefined, dbc = undefined) {
|
|
1543
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.createPOST(REGEX.checkAlgorithm, [expression], dbc, path, hint);
|
|
1544
|
+
}
|
|
1545
|
+
/**
|
|
1546
|
+
* A field-decorator factory using the {@link REGEX.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
1547
|
+
* by the tagged field.
|
|
1548
|
+
*
|
|
1549
|
+
* @param expression See {@link REGEX.checkAlgorithm }.
|
|
1550
|
+
* @param path See {@link DBC.decInvariant }.
|
|
1551
|
+
* @param dbc See {@link DBC.decInvariant }.
|
|
1552
|
+
* @param hint See {@link DBC.decInvariant }.
|
|
1553
|
+
* @returns See {@link DBC.decInvariant }. */
|
|
1554
|
+
static INVARIANT(expression, path = undefined, hint = undefined, dbc = undefined) {
|
|
1555
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.createINVARIANT(REGEX, [expression], dbc, path, hint);
|
|
1556
|
+
}
|
|
1557
|
+
// #endregion Condition checking.
|
|
1558
|
+
// #region Referenced Condition checking.
|
|
1559
|
+
//
|
|
1560
|
+
// For usage in dynamic scenarios (like with AE-DBC).
|
|
1561
|
+
//
|
|
1562
|
+
/**
|
|
1563
|
+
* Invokes the {@link REGEX.checkAlgorithm } passing the value **toCheck** and {@link REGEX.equivalent }.
|
|
1564
|
+
*
|
|
1565
|
+
* @param toCheck See {@link REGEX.checkAlgorithm }.
|
|
1566
|
+
*
|
|
1567
|
+
* @returns See {@link EQ.checkAlgorithm}. */
|
|
1568
|
+
check(toCheck) {
|
|
1569
|
+
return REGEX.checkAlgorithm(toCheck, this.expression);
|
|
1570
|
+
}
|
|
1571
|
+
/**
|
|
1572
|
+
* Type-safe check that validates a value against a regular expression and returns it as the specified type.
|
|
1573
|
+
*
|
|
1574
|
+
* @param toCheck The value to check against the regular expression.
|
|
1575
|
+
* @param expression The regular expression to validate against.
|
|
1576
|
+
* @param hint Optional hint message to include in the error if validation fails.
|
|
1577
|
+
* @param id Optional identifier to include in the error message.
|
|
1578
|
+
*
|
|
1579
|
+
* @returns The validated value cast to the CANDIDATE type.
|
|
1580
|
+
*
|
|
1581
|
+
* @throws {@link DBC.Infringement} if the value does not match the regular expression. */
|
|
1582
|
+
static tsCheck(toCheck, expression, hint = undefined, id = undefined) {
|
|
1583
|
+
const result = REGEX.checkAlgorithm(toCheck, expression);
|
|
1584
|
+
if (result) {
|
|
1585
|
+
return toCheck;
|
|
1586
|
+
}
|
|
1587
|
+
throw new _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.Infringement(`${id ? `(${id}) ` : ""}${result}${hint ? ` ✨ ${hint} ✨` : ""}`);
|
|
1588
|
+
}
|
|
1589
|
+
/**
|
|
1590
|
+
* Creates this {@link REGEX } by setting the protected property {@link REGEX.expression } used by {@link REGEX.check }.
|
|
1591
|
+
*
|
|
1592
|
+
* @param expression See {@link REGEX.check }. */
|
|
1593
|
+
constructor(expression) {
|
|
1594
|
+
super();
|
|
1595
|
+
this.expression = expression;
|
|
1596
|
+
}
|
|
1597
|
+
// #endregion Referenced Condition checking.
|
|
1598
|
+
// #region In-Method checking.
|
|
1599
|
+
/**
|
|
1600
|
+
* Invokes the {@link REGEX.checkAlgorithm } passing the value **toCheck** and {@link REGEX.expression }.
|
|
1601
|
+
*
|
|
1602
|
+
* @param toCheck See {@link REGEX.checkAlgorithm}.
|
|
1603
|
+
* @param expression See {@link REGEX.checkAlgorithm}.
|
|
1604
|
+
*/
|
|
1605
|
+
static check(toCheck, expression) {
|
|
1606
|
+
const checkResult = REGEX.checkAlgorithm(toCheck, expression);
|
|
1607
|
+
if (typeof checkResult === "string") {
|
|
1608
|
+
throw new _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.Infringement(checkResult);
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
|
|
1614
|
+
/***/ },
|
|
1615
|
+
|
|
1616
|
+
/***/ "./src/DBC/TYPE.ts"
|
|
1617
|
+
/*!*************************!*\
|
|
1618
|
+
!*** ./src/DBC/TYPE.ts ***!
|
|
1619
|
+
\*************************/
|
|
1620
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
1621
|
+
|
|
1622
|
+
__webpack_require__.r(__webpack_exports__);
|
|
1623
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
1624
|
+
/* harmony export */ TYPE: () => (/* binding */ TYPE)
|
|
1625
|
+
/* harmony export */ });
|
|
1626
|
+
/* harmony import */ var _DBC__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../DBC */ "./src/DBC.ts");
|
|
1627
|
+
|
|
1628
|
+
/**
|
|
1629
|
+
* A {@link DBC } defining that an {@link object }s gotta be of certain {@link TYPE.type }.
|
|
1630
|
+
*
|
|
1631
|
+
* @remarks
|
|
1632
|
+
* Author: Salvatore Callari (Callari@WaXCode.net) / 2025
|
|
1633
|
+
* Maintainer: Salvatore Callari (XDBC@WaXCode.net) */
|
|
1634
|
+
class TYPE extends _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC {
|
|
1635
|
+
/**
|
|
1636
|
+
* Checks if the value **toCheck** is of the **type** specified.
|
|
1637
|
+
*
|
|
1638
|
+
* @param toCheck The {@link Object } which's **type** to check.
|
|
1639
|
+
* @param type The type the {@link object} **toCheck** has to be of. Can be a single type or multiple types separated by "|".
|
|
1640
|
+
*
|
|
1641
|
+
* @returns TRUE if the value **toCheck** is of the specified **type**, otherwise FALSE. */
|
|
1642
|
+
// biome-ignore lint/suspicious/noExplicitAny: Necessary for dynamic type checking of also UNDEFINED.
|
|
1643
|
+
static checkAlgorithm(toCheck, type) {
|
|
1644
|
+
if (toCheck === undefined || toCheck === null)
|
|
1645
|
+
return true;
|
|
1646
|
+
const types = type.split("|").map((t) => t.trim());
|
|
1647
|
+
const actualType = typeof toCheck;
|
|
1648
|
+
// #region Check if the actual type matches at least one of the specified types
|
|
1649
|
+
// biome-ignore lint/suspicious/useValidTypeof: Necessary
|
|
1650
|
+
const isValid = types.some((t) => actualType === t);
|
|
1651
|
+
if (!isValid) {
|
|
1652
|
+
if (types.length === 1) {
|
|
1653
|
+
return `Value has to be of type "${type}" but is of type "${actualType}"`;
|
|
1654
|
+
}
|
|
1655
|
+
return `Value has to be of type "${types.join(" | ")}" but is of type "${actualType}"`;
|
|
1656
|
+
}
|
|
1657
|
+
// #endregion Check if the actual type matches at least one of the specified types
|
|
1658
|
+
return true;
|
|
1659
|
+
}
|
|
1660
|
+
/**
|
|
1661
|
+
* A parameter-decorator factory using the {@link TYPE.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
1662
|
+
* by the tagged parameter.
|
|
1663
|
+
*
|
|
1664
|
+
* @param type See {@link TYPE.checkAlgorithm }.
|
|
1665
|
+
* @param path A ::-separated list of dotted paths to check. Each path points to a property within the parameter value.
|
|
1666
|
+
* Undefined properties are skipped. See {@link DBC.decPrecondition }.
|
|
1667
|
+
* @param dbc See {@link DBC.decPrecondition }.
|
|
1668
|
+
*
|
|
1669
|
+
* @returns See {@link DBC.decPrecondition }. */
|
|
1670
|
+
static PRE(type, path = undefined, hint = undefined, dbc = undefined) {
|
|
1671
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.createPRE(TYPE.checkAlgorithm, [type], dbc, path, hint);
|
|
1672
|
+
}
|
|
1673
|
+
/**
|
|
1674
|
+
* A method-decorator factory using the {@link TYPE.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
1675
|
+
* by the tagged method's returnvalue.
|
|
1676
|
+
*
|
|
1677
|
+
* @param type See {@link TYPE.checkAlgorithm }.
|
|
1678
|
+
* @param path A ::-separated list of dotted paths to check. Each path points to a property within the parameter value.
|
|
1679
|
+
* Undefined properties are skipped. See {@link DBC.decPrecondition }.
|
|
1680
|
+
* @param dbc See {@link DBC.decPostcondition }.
|
|
1681
|
+
*
|
|
1682
|
+
* @returns See {@link DBC.decPostcondition }. */
|
|
1683
|
+
static POST(type, path = undefined, hint = undefined, dbc = undefined) {
|
|
1684
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.createPOST(TYPE.checkAlgorithm, [type], dbc, path, hint);
|
|
1685
|
+
}
|
|
1686
|
+
/**
|
|
1687
|
+
* A field-decorator factory using the {@link TYPE.checkAlgorithm } to determine whether this {@link DBC } is fulfilled
|
|
1688
|
+
* by the tagged field.
|
|
1689
|
+
*
|
|
1690
|
+
* @param type See {@link TYPE.checkAlgorithm }.
|
|
1691
|
+
* @param path A ::-separated list of dotted paths to check. Each path points to a property within the parameter value.
|
|
1692
|
+
* Undefined properties are skipped. See {@link DBC.decPrecondition }.
|
|
1693
|
+
* @param dbc See {@link DBC.decInvariant }.
|
|
1694
|
+
*
|
|
1695
|
+
* @returns See {@link DBC.decInvariant }. */
|
|
1696
|
+
static INVARIANT(type, path = undefined, hint = undefined, dbc = undefined) {
|
|
1697
|
+
return _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.createINVARIANT(TYPE, [type], dbc, path, hint);
|
|
1698
|
+
}
|
|
1699
|
+
// #endregion Condition checking.
|
|
1700
|
+
// #region Referenced Condition checking.
|
|
1701
|
+
//
|
|
1702
|
+
// For usage in dynamic scenarios (like with AE-DBC).
|
|
1703
|
+
//
|
|
1704
|
+
/**
|
|
1705
|
+
* Invokes the {@link TYPE.checkAlgorithm } passing the value **toCheck** and the {@link TYPE.type } .
|
|
1706
|
+
*
|
|
1707
|
+
* @param toCheck See {@link TYPE.checkAlgorithm }.
|
|
1708
|
+
*
|
|
1709
|
+
* @returns See {@link TYPE.checkAlgorithm}. */
|
|
1710
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
1711
|
+
check(toCheck) {
|
|
1712
|
+
return TYPE.checkAlgorithm(toCheck, this.type);
|
|
1713
|
+
}
|
|
1714
|
+
/**
|
|
1715
|
+
* Invokes the {@link TYPE.checkAlgorithm } passing the value **toCheck** and the {@link TYPE.type } .
|
|
1716
|
+
*
|
|
1717
|
+
* @param toCheck See {@link TYPE.checkAlgorithm }.
|
|
1718
|
+
* @param type See {@link TYPE.checkAlgorithm }.
|
|
1719
|
+
* @param hint An optional {@link string } providing extra information in case of an infringement.
|
|
1720
|
+
* @param id A {@link string } identifying this {@link TYPE } via the {@link DBC.Infringement }-Message.
|
|
1721
|
+
*
|
|
1722
|
+
* @returns The **CANDIDATE** **toCheck** doesn't fulfill this {@link TYPE }.
|
|
1723
|
+
*
|
|
1724
|
+
* @throws A {@link DBC.Infringement } if the **CANDIDATE** **toCheck** does not fulfill this {@link DEFINED }. */
|
|
1725
|
+
static tsCheck(toCheck, type, hint = undefined, id = undefined) {
|
|
1726
|
+
const result = TYPE.checkAlgorithm(toCheck, type);
|
|
1727
|
+
if (result === true) {
|
|
1728
|
+
return toCheck;
|
|
1729
|
+
}
|
|
1730
|
+
throw new _DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.Infringement(`${id ? `(${id}) ` : ""}${result}${hint ? ` ✨ ${hint} ✨` : ""}`);
|
|
1731
|
+
}
|
|
1732
|
+
/**
|
|
1733
|
+
* Creates this {@link TYPE } by setting the protected property {@link TYPE.type } used by {@link TYPE.check }.
|
|
1734
|
+
*
|
|
1735
|
+
* @param type See {@link TYPE.check }. */
|
|
1736
|
+
constructor(type) {
|
|
1737
|
+
super();
|
|
1738
|
+
this.type = type;
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
|
|
1743
|
+
/***/ }
|
|
1744
|
+
|
|
1745
|
+
/******/ });
|
|
1746
|
+
/************************************************************************/
|
|
1747
|
+
/******/ // The module cache
|
|
1748
|
+
/******/ var __webpack_module_cache__ = {};
|
|
1749
|
+
/******/
|
|
1750
|
+
/******/ // The require function
|
|
1751
|
+
/******/ function __webpack_require__(moduleId) {
|
|
1752
|
+
/******/ // Check if module is in cache
|
|
1753
|
+
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
|
1754
|
+
/******/ if (cachedModule !== undefined) {
|
|
1755
|
+
/******/ return cachedModule.exports;
|
|
1756
|
+
/******/ }
|
|
1757
|
+
/******/ // Create a new module (and put it into the cache)
|
|
1758
|
+
/******/ var module = __webpack_module_cache__[moduleId] = {
|
|
1759
|
+
/******/ // no module.id needed
|
|
1760
|
+
/******/ // no module.loaded needed
|
|
1761
|
+
/******/ exports: {}
|
|
1762
|
+
/******/ };
|
|
1763
|
+
/******/
|
|
1764
|
+
/******/ // Execute the module function
|
|
1765
|
+
/******/ if (!(moduleId in __webpack_modules__)) {
|
|
1766
|
+
/******/ delete __webpack_module_cache__[moduleId];
|
|
1767
|
+
/******/ var e = new Error("Cannot find module '" + moduleId + "'");
|
|
1768
|
+
/******/ e.code = 'MODULE_NOT_FOUND';
|
|
1769
|
+
/******/ throw e;
|
|
1770
|
+
/******/ }
|
|
1771
|
+
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
1772
|
+
/******/
|
|
1773
|
+
/******/ // Return the exports of the module
|
|
1774
|
+
/******/ return module.exports;
|
|
1775
|
+
/******/ }
|
|
1776
|
+
/******/
|
|
1777
|
+
/************************************************************************/
|
|
1778
|
+
/******/ /* webpack/runtime/define property getters */
|
|
1779
|
+
/******/ (() => {
|
|
1780
|
+
/******/ // define getter functions for harmony exports
|
|
1781
|
+
/******/ __webpack_require__.d = (exports, definition) => {
|
|
1782
|
+
/******/ for(var key in definition) {
|
|
1783
|
+
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
|
1784
|
+
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
|
1785
|
+
/******/ }
|
|
1786
|
+
/******/ }
|
|
1787
|
+
/******/ };
|
|
1788
|
+
/******/ })();
|
|
1789
|
+
/******/
|
|
1790
|
+
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
1791
|
+
/******/ (() => {
|
|
1792
|
+
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
1793
|
+
/******/ })();
|
|
1794
|
+
/******/
|
|
1795
|
+
/******/ /* webpack/runtime/make namespace object */
|
|
1796
|
+
/******/ (() => {
|
|
1797
|
+
/******/ // define __esModule on exports
|
|
1798
|
+
/******/ __webpack_require__.r = (exports) => {
|
|
1799
|
+
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
|
1800
|
+
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
1801
|
+
/******/ }
|
|
1802
|
+
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
|
1803
|
+
/******/ };
|
|
1804
|
+
/******/ })();
|
|
1805
|
+
/******/
|
|
1806
|
+
/************************************************************************/
|
|
1807
|
+
var __webpack_exports__ = {};
|
|
1808
|
+
// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
|
|
1809
|
+
(() => {
|
|
1810
|
+
/*!*********************!*\
|
|
1811
|
+
!*** ./src/Demo.ts ***!
|
|
1812
|
+
\*********************/
|
|
1813
|
+
__webpack_require__.r(__webpack_exports__);
|
|
1814
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
1815
|
+
/* harmony export */ Demo: () => (/* binding */ Demo)
|
|
1816
|
+
/* harmony export */ });
|
|
1817
|
+
/* harmony import */ var _DBC__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./DBC */ "./src/DBC.ts");
|
|
1818
|
+
/* harmony import */ var _DBC_AE__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./DBC/AE */ "./src/DBC/AE.ts");
|
|
1819
|
+
/* harmony import */ var _DBC_COMPARISON_GREATER__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./DBC/COMPARISON/GREATER */ "./src/DBC/COMPARISON/GREATER.ts");
|
|
1820
|
+
/* harmony import */ var _DBC_COMPARISON_GREATER_OR_EQUAL__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./DBC/COMPARISON/GREATER_OR_EQUAL */ "./src/DBC/COMPARISON/GREATER_OR_EQUAL.ts");
|
|
1821
|
+
/* harmony import */ var _DBC_COMPARISON_LESS__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./DBC/COMPARISON/LESS */ "./src/DBC/COMPARISON/LESS.ts");
|
|
1822
|
+
/* harmony import */ var _DBC_COMPARISON_LESS_OR_EQUAL__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./DBC/COMPARISON/LESS_OR_EQUAL */ "./src/DBC/COMPARISON/LESS_OR_EQUAL.ts");
|
|
1823
|
+
/* harmony import */ var _DBC_EQ__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./DBC/EQ */ "./src/DBC/EQ.ts");
|
|
1824
|
+
/* harmony import */ var _DBC_EQ_DIFFERENT__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./DBC/EQ/DIFFERENT */ "./src/DBC/EQ/DIFFERENT.ts");
|
|
1825
|
+
/* harmony import */ var _DBC_INSTANCE__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./DBC/INSTANCE */ "./src/DBC/INSTANCE.ts");
|
|
1826
|
+
/* harmony import */ var _DBC_REGEX__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./DBC/REGEX */ "./src/DBC/REGEX.ts");
|
|
1827
|
+
/* harmony import */ var _DBC_TYPE__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./DBC/TYPE */ "./src/DBC/TYPE.ts");
|
|
1828
|
+
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
1829
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1830
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1831
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1832
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1833
|
+
};
|
|
1834
|
+
var __metadata = (undefined && undefined.__metadata) || function (k, v) {
|
|
1835
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1836
|
+
};
|
|
1837
|
+
var __param = (undefined && undefined.__param) || function (paramIndex, decorator) {
|
|
1838
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
1839
|
+
};
|
|
1840
|
+
|
|
1841
|
+
|
|
1842
|
+
|
|
1843
|
+
|
|
1844
|
+
|
|
1845
|
+
|
|
1846
|
+
|
|
1847
|
+
|
|
1848
|
+
|
|
1849
|
+
|
|
1850
|
+
|
|
1851
|
+
/** Demonstrative use of **D**esign **B**y **C**ontract Decorators */
|
|
1852
|
+
class Demo {
|
|
1853
|
+
constructor() {
|
|
1854
|
+
// #region Check Property Decorator
|
|
1855
|
+
this.testProperty = "a";
|
|
1856
|
+
// #endregion Check Static Method with ParamvalueProvider
|
|
1857
|
+
}
|
|
1858
|
+
// #endregion Check Property Decorator
|
|
1859
|
+
// #region Check Parameter. & Returnvalue Decorator
|
|
1860
|
+
testParamvalueAndReturnvalue(a) {
|
|
1861
|
+
return `xxxx${a}`;
|
|
1862
|
+
}
|
|
1863
|
+
// #endregion Check Parameter. & Returnvalue Decorator
|
|
1864
|
+
// #region Check Returnvalue Decorator
|
|
1865
|
+
testReturnvalue(a) {
|
|
1866
|
+
return a;
|
|
1867
|
+
}
|
|
1868
|
+
// #endregion Check Returnvalue Decorator
|
|
1869
|
+
// #region Check EQ-DBC & Path to property of Parameter-value
|
|
1870
|
+
testEQAndPath(o) { }
|
|
1871
|
+
// #endregion Check EQ-DBC & Path to property of Parameter-value
|
|
1872
|
+
// #region Check EQ-DBC & Path to property of Parameter-value with Inversion
|
|
1873
|
+
testEQAndPathWithInversion(o) { }
|
|
1874
|
+
// #endregion Check EQ-DBC & Path to property of Parameter-value with Inversion
|
|
1875
|
+
// #region Check TYPE
|
|
1876
|
+
testTYPE(o) { }
|
|
1877
|
+
// #endregion Check TYPE
|
|
1878
|
+
// #region Check AE
|
|
1879
|
+
testAE(x) { }
|
|
1880
|
+
// #endregion Check AE
|
|
1881
|
+
// #region Check REGEX with AE
|
|
1882
|
+
testREGEXWithAE(x) { }
|
|
1883
|
+
// #endregion Check REGEX with AE
|
|
1884
|
+
// #region Check INSTANCE
|
|
1885
|
+
testINSTANCE(candidate) { }
|
|
1886
|
+
// #endregion Check INSTANCE
|
|
1887
|
+
// #region Check AE Range
|
|
1888
|
+
testAERange(x) { }
|
|
1889
|
+
// #endregion Check AE Range
|
|
1890
|
+
// #region Check AE Index
|
|
1891
|
+
testAEIndex(x) { }
|
|
1892
|
+
// #endregion Check AE Index
|
|
1893
|
+
// #region Check Comparison
|
|
1894
|
+
testGREATER(input) { }
|
|
1895
|
+
testGREATER_OR_EQUAL(input) { }
|
|
1896
|
+
testLESS(input) { }
|
|
1897
|
+
testLESS_OR_EQUAL(input) { }
|
|
1898
|
+
testDIFFERENT(input) { }
|
|
1899
|
+
// #endregion Check Comparison
|
|
1900
|
+
// #region Check Static Method with ParamvalueProvider
|
|
1901
|
+
static testStaticMethod(message, count) {
|
|
1902
|
+
return `${message} repeated ${count} times`;
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
__decorate([
|
|
1906
|
+
_DBC_REGEX__WEBPACK_IMPORTED_MODULE_9__.REGEX.INVARIANT(/^a$/),
|
|
1907
|
+
__metadata("design:type", Object)
|
|
1908
|
+
], Demo.prototype, "testProperty", void 0);
|
|
1909
|
+
__decorate([
|
|
1910
|
+
_DBC_REGEX__WEBPACK_IMPORTED_MODULE_9__.REGEX.POST(/^xxxx.*$/),
|
|
1911
|
+
_DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.ParamvalueProvider,
|
|
1912
|
+
__param(0, _DBC_REGEX__WEBPACK_IMPORTED_MODULE_9__.REGEX.PRE(/holla*/g)),
|
|
1913
|
+
__metadata("design:type", Function),
|
|
1914
|
+
__metadata("design:paramtypes", [String]),
|
|
1915
|
+
__metadata("design:returntype", String)
|
|
1916
|
+
], Demo.prototype, "testParamvalueAndReturnvalue", null);
|
|
1917
|
+
__decorate([
|
|
1918
|
+
_DBC_REGEX__WEBPACK_IMPORTED_MODULE_9__.REGEX.POST(/^xxxx.*$/),
|
|
1919
|
+
__metadata("design:type", Function),
|
|
1920
|
+
__metadata("design:paramtypes", [String]),
|
|
1921
|
+
__metadata("design:returntype", String)
|
|
1922
|
+
], Demo.prototype, "testReturnvalue", null);
|
|
1923
|
+
__decorate([
|
|
1924
|
+
_DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.ParamvalueProvider,
|
|
1925
|
+
__param(0, _DBC_EQ__WEBPACK_IMPORTED_MODULE_6__.EQ.PRE("SELECT", false, "tagName")),
|
|
1926
|
+
__metadata("design:type", Function),
|
|
1927
|
+
__metadata("design:paramtypes", [HTMLElement]),
|
|
1928
|
+
__metadata("design:returntype", void 0)
|
|
1929
|
+
], Demo.prototype, "testEQAndPath", null);
|
|
1930
|
+
__decorate([
|
|
1931
|
+
_DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.ParamvalueProvider,
|
|
1932
|
+
__param(0, _DBC_EQ__WEBPACK_IMPORTED_MODULE_6__.EQ.PRE("SELECT", true, "tagName")),
|
|
1933
|
+
__metadata("design:type", Function),
|
|
1934
|
+
__metadata("design:paramtypes", [HTMLElement]),
|
|
1935
|
+
__metadata("design:returntype", void 0)
|
|
1936
|
+
], Demo.prototype, "testEQAndPathWithInversion", null);
|
|
1937
|
+
__decorate([
|
|
1938
|
+
_DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.ParamvalueProvider,
|
|
1939
|
+
__param(0, _DBC_TYPE__WEBPACK_IMPORTED_MODULE_10__.TYPE.PRE("string")),
|
|
1940
|
+
__metadata("design:type", Function),
|
|
1941
|
+
__metadata("design:paramtypes", [Object]),
|
|
1942
|
+
__metadata("design:returntype", void 0)
|
|
1943
|
+
], Demo.prototype, "testTYPE", null);
|
|
1944
|
+
__decorate([
|
|
1945
|
+
_DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.ParamvalueProvider,
|
|
1946
|
+
__param(0, _DBC_AE__WEBPACK_IMPORTED_MODULE_1__.AE.PRE([new _DBC_TYPE__WEBPACK_IMPORTED_MODULE_10__.TYPE("string")])),
|
|
1947
|
+
__metadata("design:type", Function),
|
|
1948
|
+
__metadata("design:paramtypes", [Array]),
|
|
1949
|
+
__metadata("design:returntype", void 0)
|
|
1950
|
+
], Demo.prototype, "testAE", null);
|
|
1951
|
+
__decorate([
|
|
1952
|
+
_DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.ParamvalueProvider,
|
|
1953
|
+
__param(0, _DBC_AE__WEBPACK_IMPORTED_MODULE_1__.AE.PRE(new _DBC_REGEX__WEBPACK_IMPORTED_MODULE_9__.REGEX(/^(?i:(NOW)|([+-]\d+[dmy]))$/i))),
|
|
1954
|
+
__metadata("design:type", Function),
|
|
1955
|
+
__metadata("design:paramtypes", [Array]),
|
|
1956
|
+
__metadata("design:returntype", void 0)
|
|
1957
|
+
], Demo.prototype, "testREGEXWithAE", null);
|
|
1958
|
+
__decorate([
|
|
1959
|
+
_DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.ParamvalueProvider
|
|
1960
|
+
// biome-ignore lint/suspicious/noExplicitAny: Test
|
|
1961
|
+
,
|
|
1962
|
+
__param(0, _DBC_INSTANCE__WEBPACK_IMPORTED_MODULE_8__.INSTANCE.PRE(Date)),
|
|
1963
|
+
__metadata("design:type", Function),
|
|
1964
|
+
__metadata("design:paramtypes", [Object]),
|
|
1965
|
+
__metadata("design:returntype", void 0)
|
|
1966
|
+
], Demo.prototype, "testINSTANCE", null);
|
|
1967
|
+
__decorate([
|
|
1968
|
+
_DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.ParamvalueProvider,
|
|
1969
|
+
__param(0, _DBC_AE__WEBPACK_IMPORTED_MODULE_1__.AE.PRE([new _DBC_TYPE__WEBPACK_IMPORTED_MODULE_10__.TYPE("string"), new _DBC_REGEX__WEBPACK_IMPORTED_MODULE_9__.REGEX(/^abc$/)], 1, 2)),
|
|
1970
|
+
__metadata("design:type", Function),
|
|
1971
|
+
__metadata("design:paramtypes", [Array]),
|
|
1972
|
+
__metadata("design:returntype", void 0)
|
|
1973
|
+
], Demo.prototype, "testAERange", null);
|
|
1974
|
+
__decorate([
|
|
1975
|
+
_DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.ParamvalueProvider,
|
|
1976
|
+
__param(0, _DBC_AE__WEBPACK_IMPORTED_MODULE_1__.AE.PRE([new _DBC_TYPE__WEBPACK_IMPORTED_MODULE_10__.TYPE("string"), new _DBC_REGEX__WEBPACK_IMPORTED_MODULE_9__.REGEX(/^abc$/)], 1)),
|
|
1977
|
+
__metadata("design:type", Function),
|
|
1978
|
+
__metadata("design:paramtypes", [Array]),
|
|
1979
|
+
__metadata("design:returntype", void 0)
|
|
1980
|
+
], Demo.prototype, "testAEIndex", null);
|
|
1981
|
+
__decorate([
|
|
1982
|
+
_DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.ParamvalueProvider,
|
|
1983
|
+
__param(0, _DBC_COMPARISON_GREATER__WEBPACK_IMPORTED_MODULE_2__.GREATER.PRE(2)),
|
|
1984
|
+
__metadata("design:type", Function),
|
|
1985
|
+
__metadata("design:paramtypes", [Number]),
|
|
1986
|
+
__metadata("design:returntype", void 0)
|
|
1987
|
+
], Demo.prototype, "testGREATER", null);
|
|
1988
|
+
__decorate([
|
|
1989
|
+
_DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.ParamvalueProvider,
|
|
1990
|
+
__param(0, _DBC_COMPARISON_GREATER_OR_EQUAL__WEBPACK_IMPORTED_MODULE_3__.GREATER_OR_EQUAL.PRE(2)),
|
|
1991
|
+
__metadata("design:type", Function),
|
|
1992
|
+
__metadata("design:paramtypes", [Number]),
|
|
1993
|
+
__metadata("design:returntype", void 0)
|
|
1994
|
+
], Demo.prototype, "testGREATER_OR_EQUAL", null);
|
|
1995
|
+
__decorate([
|
|
1996
|
+
_DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.ParamvalueProvider,
|
|
1997
|
+
__param(0, _DBC_COMPARISON_LESS__WEBPACK_IMPORTED_MODULE_4__.LESS.PRE(20)),
|
|
1998
|
+
__metadata("design:type", Function),
|
|
1999
|
+
__metadata("design:paramtypes", [Number]),
|
|
2000
|
+
__metadata("design:returntype", void 0)
|
|
2001
|
+
], Demo.prototype, "testLESS", null);
|
|
2002
|
+
__decorate([
|
|
2003
|
+
_DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.ParamvalueProvider,
|
|
2004
|
+
__param(0, _DBC_COMPARISON_LESS_OR_EQUAL__WEBPACK_IMPORTED_MODULE_5__.LESS_OR_EQUAL.PRE(20)),
|
|
2005
|
+
__metadata("design:type", Function),
|
|
2006
|
+
__metadata("design:paramtypes", [Number]),
|
|
2007
|
+
__metadata("design:returntype", void 0)
|
|
2008
|
+
], Demo.prototype, "testLESS_OR_EQUAL", null);
|
|
2009
|
+
__decorate([
|
|
2010
|
+
_DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.ParamvalueProvider,
|
|
2011
|
+
__param(0, _DBC_EQ_DIFFERENT__WEBPACK_IMPORTED_MODULE_7__.DIFFERENT.PRE(20)),
|
|
2012
|
+
__metadata("design:type", Function),
|
|
2013
|
+
__metadata("design:paramtypes", [Number]),
|
|
2014
|
+
__metadata("design:returntype", void 0)
|
|
2015
|
+
], Demo.prototype, "testDIFFERENT", null);
|
|
2016
|
+
__decorate([
|
|
2017
|
+
_DBC__WEBPACK_IMPORTED_MODULE_0__.DBC.ParamvalueProvider,
|
|
2018
|
+
__param(0, _DBC_TYPE__WEBPACK_IMPORTED_MODULE_10__.TYPE.PRE("string")),
|
|
2019
|
+
__param(1, _DBC_TYPE__WEBPACK_IMPORTED_MODULE_10__.TYPE.PRE("number")),
|
|
2020
|
+
__metadata("design:type", Function),
|
|
2021
|
+
__metadata("design:paramtypes", [String, Number]),
|
|
2022
|
+
__metadata("design:returntype", String)
|
|
2023
|
+
], Demo, "testStaticMethod", null);
|
|
2024
|
+
const demo = new Demo();
|
|
2025
|
+
try {
|
|
2026
|
+
demo.testProperty = "abd";
|
|
2027
|
+
}
|
|
2028
|
+
catch (X) {
|
|
2029
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2030
|
+
console.log("INVARIANT Infringement", "OK");
|
|
2031
|
+
console.log(X);
|
|
2032
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2033
|
+
}
|
|
2034
|
+
demo.testProperty = "a";
|
|
2035
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2036
|
+
console.log("INVARIANT OK");
|
|
2037
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2038
|
+
demo.testParamvalueAndReturnvalue("holla");
|
|
2039
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2040
|
+
console.log("PARAMETER- & RETURNVALUE OK");
|
|
2041
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2042
|
+
try {
|
|
2043
|
+
demo.testParamvalueAndReturnvalue("yyyy");
|
|
2044
|
+
}
|
|
2045
|
+
catch (X) {
|
|
2046
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2047
|
+
console.log("PARAMETER- & RETURNVALUE Infringement", "OK");
|
|
2048
|
+
console.log(X);
|
|
2049
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2050
|
+
}
|
|
2051
|
+
demo.testReturnvalue("xxxx");
|
|
2052
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2053
|
+
console.log("RETURNVALUE OK");
|
|
2054
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2055
|
+
try {
|
|
2056
|
+
demo.testReturnvalue("yyyy");
|
|
2057
|
+
}
|
|
2058
|
+
catch (X) {
|
|
2059
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2060
|
+
console.log("RETURNVALUE Infringement", "OK");
|
|
2061
|
+
console.log(X);
|
|
2062
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2063
|
+
}
|
|
2064
|
+
demo.testEQAndPath(document.createElement("select"));
|
|
2065
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2066
|
+
console.log("EQ with Path Infringement OK");
|
|
2067
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2068
|
+
try {
|
|
2069
|
+
demo.testEQAndPathWithInversion(document.createElement("select"));
|
|
2070
|
+
}
|
|
2071
|
+
catch (X) {
|
|
2072
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2073
|
+
console.log("EQ with Path and Inversion Infringement OK");
|
|
2074
|
+
console.log(X);
|
|
2075
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2076
|
+
}
|
|
2077
|
+
demo.testTYPE("x");
|
|
2078
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2079
|
+
console.log("TYPE OK");
|
|
2080
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2081
|
+
try {
|
|
2082
|
+
demo.testTYPE(0);
|
|
2083
|
+
}
|
|
2084
|
+
catch (X) {
|
|
2085
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2086
|
+
console.log("TYPE Infringement OK");
|
|
2087
|
+
console.log(X);
|
|
2088
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2089
|
+
}
|
|
2090
|
+
demo.testAE(["11", "10", "b"]);
|
|
2091
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2092
|
+
console.log("AE OK");
|
|
2093
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2094
|
+
try {
|
|
2095
|
+
demo.testAE(["11", 11, "b"]);
|
|
2096
|
+
}
|
|
2097
|
+
catch (X) {
|
|
2098
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2099
|
+
console.log("AE Infringement OK");
|
|
2100
|
+
console.log(X);
|
|
2101
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2102
|
+
}
|
|
2103
|
+
demo.testREGEXWithAE(["+1d", "NOW", "-10y"]);
|
|
2104
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2105
|
+
console.log("REGEX with AE OK");
|
|
2106
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2107
|
+
try {
|
|
2108
|
+
demo.testREGEXWithAE(["+1d", "+5d", "-x10y"]);
|
|
2109
|
+
}
|
|
2110
|
+
catch (X) {
|
|
2111
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2112
|
+
console.log("REGEX with AE Infringement OK");
|
|
2113
|
+
console.log(X);
|
|
2114
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2115
|
+
}
|
|
2116
|
+
demo.testINSTANCE(new Date());
|
|
2117
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2118
|
+
console.log("INSTANCE OK");
|
|
2119
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2120
|
+
try {
|
|
2121
|
+
demo.testINSTANCE(demo);
|
|
2122
|
+
}
|
|
2123
|
+
catch (X) {
|
|
2124
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2125
|
+
console.log("INSTANCE Infringement OK");
|
|
2126
|
+
console.log(X);
|
|
2127
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2128
|
+
}
|
|
2129
|
+
demo.testAERange([11, "abc", "abc"]);
|
|
2130
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2131
|
+
console.log("AE Range OK");
|
|
2132
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2133
|
+
try {
|
|
2134
|
+
demo.testAERange([11, "abc", /a/g]);
|
|
2135
|
+
}
|
|
2136
|
+
catch (X) {
|
|
2137
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2138
|
+
console.log("AE Range Infringement OK");
|
|
2139
|
+
console.log(X);
|
|
2140
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2141
|
+
}
|
|
2142
|
+
demo.testAEIndex([11, "abc", "abc"]);
|
|
2143
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2144
|
+
console.log("AE Index OK");
|
|
2145
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2146
|
+
try {
|
|
2147
|
+
demo.testAEIndex(["11", 12, "/a/g"]);
|
|
2148
|
+
}
|
|
2149
|
+
catch (X) {
|
|
2150
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2151
|
+
console.log("AE Index Infringement OK");
|
|
2152
|
+
console.log(X);
|
|
2153
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2154
|
+
}
|
|
2155
|
+
demo.testGREATER(11);
|
|
2156
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2157
|
+
console.log("GREATER OK");
|
|
2158
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2159
|
+
try {
|
|
2160
|
+
demo.testGREATER(2);
|
|
2161
|
+
}
|
|
2162
|
+
catch (X) {
|
|
2163
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2164
|
+
console.log("GREATER Infringement OK");
|
|
2165
|
+
console.log(X);
|
|
2166
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2167
|
+
}
|
|
2168
|
+
demo.testGREATER_OR_EQUAL(2);
|
|
2169
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2170
|
+
console.log("GREATER_OR_EQUAL OK");
|
|
2171
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2172
|
+
try {
|
|
2173
|
+
demo.testGREATER_OR_EQUAL(1);
|
|
2174
|
+
}
|
|
2175
|
+
catch (X) {
|
|
2176
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2177
|
+
console.log("GREATER_OR_EQUAL Infringement OK");
|
|
2178
|
+
console.log(X);
|
|
2179
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2180
|
+
}
|
|
2181
|
+
demo.testLESS(10);
|
|
2182
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2183
|
+
console.log("LESS OK");
|
|
2184
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2185
|
+
try {
|
|
2186
|
+
demo.testLESS(20);
|
|
2187
|
+
}
|
|
2188
|
+
catch (X) {
|
|
2189
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2190
|
+
console.log("LESS Infringement OK");
|
|
2191
|
+
console.log(X);
|
|
2192
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2193
|
+
}
|
|
2194
|
+
demo.testLESS_OR_EQUAL(20);
|
|
2195
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2196
|
+
console.log("LESS OK");
|
|
2197
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2198
|
+
try {
|
|
2199
|
+
demo.testLESS_OR_EQUAL(21);
|
|
2200
|
+
}
|
|
2201
|
+
catch (X) {
|
|
2202
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2203
|
+
console.log("LESS_OR_EQUAL Infringement OK");
|
|
2204
|
+
console.log(X);
|
|
2205
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2206
|
+
}
|
|
2207
|
+
demo.testDIFFERENT(21);
|
|
2208
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2209
|
+
console.log("DIFFERENT OK");
|
|
2210
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2211
|
+
try {
|
|
2212
|
+
demo.testDIFFERENT(20);
|
|
2213
|
+
}
|
|
2214
|
+
catch (X) {
|
|
2215
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2216
|
+
console.log("DIFFERENT Infringement OK");
|
|
2217
|
+
console.log(X);
|
|
2218
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2219
|
+
}
|
|
2220
|
+
// #region Inactivity Checks
|
|
2221
|
+
window.WaXCode.DBC.executionSettings.checkPreconditions = false;
|
|
2222
|
+
try {
|
|
2223
|
+
demo.testLESS_OR_EQUAL(21);
|
|
2224
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2225
|
+
console.log("INACTIVE PRECONDITIONS OK");
|
|
2226
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2227
|
+
}
|
|
2228
|
+
catch (X) {
|
|
2229
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2230
|
+
console.log("INACTIVE PRECONDITIONS FAILED");
|
|
2231
|
+
console.log(X);
|
|
2232
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2233
|
+
}
|
|
2234
|
+
window.WaXCode.DBC.executionSettings.checkPostconditions = false;
|
|
2235
|
+
try {
|
|
2236
|
+
demo.testReturnvalue("qqqqq");
|
|
2237
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2238
|
+
console.log("INACTIVE POSTCONDITIONS OK");
|
|
2239
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2240
|
+
}
|
|
2241
|
+
catch (X) {
|
|
2242
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2243
|
+
console.log("INACTIVE POSTCONDITIONS FAILED");
|
|
2244
|
+
console.log(X);
|
|
2245
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2246
|
+
}
|
|
2247
|
+
window.WaXCode.DBC.executionSettings.checkInvariants = false;
|
|
2248
|
+
try {
|
|
2249
|
+
demo.testProperty = "b";
|
|
2250
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2251
|
+
console.log("INACTIVE INVARIANTS OK");
|
|
2252
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2253
|
+
}
|
|
2254
|
+
catch (X) {
|
|
2255
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2256
|
+
console.log("INACTIVE INVARIANTS FAILED");
|
|
2257
|
+
console.log(X);
|
|
2258
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2259
|
+
}
|
|
2260
|
+
// #endregion Inactivity Checks
|
|
2261
|
+
// Re-enable all checks for subsequent tests
|
|
2262
|
+
window.WaXCode.DBC.executionSettings.checkPreconditions = true;
|
|
2263
|
+
window.WaXCode.DBC.executionSettings.checkPostconditions = true;
|
|
2264
|
+
window.WaXCode.DBC.executionSettings.checkInvariants = true;
|
|
2265
|
+
// #region Static Method Test
|
|
2266
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2267
|
+
console.log("TESTING STATIC METHOD WITH PARAMVALUEPROVIDER");
|
|
2268
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2269
|
+
Demo.testStaticMethod("Hello", 3);
|
|
2270
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2271
|
+
console.log("STATIC METHOD OK");
|
|
2272
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2273
|
+
try {
|
|
2274
|
+
Demo.testStaticMethod("Hello", "not a number");
|
|
2275
|
+
}
|
|
2276
|
+
catch (X) {
|
|
2277
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2278
|
+
console.log("STATIC METHOD Infringement OK");
|
|
2279
|
+
console.log(X);
|
|
2280
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2281
|
+
}
|
|
2282
|
+
try {
|
|
2283
|
+
Demo.testStaticMethod(123, 5);
|
|
2284
|
+
}
|
|
2285
|
+
catch (X) {
|
|
2286
|
+
console.log("⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄");
|
|
2287
|
+
console.log("STATIC METHOD Infringement (first param) OK");
|
|
2288
|
+
console.log(X);
|
|
2289
|
+
console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
|
|
2290
|
+
}
|
|
2291
|
+
// #endregion Static Method Test
|
|
2292
|
+
|
|
2293
|
+
})();
|
|
2294
|
+
|
|
2295
|
+
/******/ })()
|
|
2296
|
+
;
|
|
2297
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3hkYmMvLi9zcmMvREJDLnRzIiwid2VicGFjazovL3hkYmMvLi9zcmMvREJDL0FFLnRzIiwid2VicGFjazovL3hkYmMvLi9zcmMvREJDL0NPTVBBUklTT04udHMiLCJ3ZWJwYWNrOi8veGRiYy8uL3NyYy9EQkMvQ09NUEFSSVNPTi9HUkVBVEVSLnRzIiwid2VicGFjazovL3hkYmMvLi9zcmMvREJDL0NPTVBBUklTT04vR1JFQVRFUl9PUl9FUVVBTC50cyIsIndlYnBhY2s6Ly94ZGJjLy4vc3JjL0RCQy9DT01QQVJJU09OL0xFU1MudHMiLCJ3ZWJwYWNrOi8veGRiYy8uL3NyYy9EQkMvQ09NUEFSSVNPTi9MRVNTX09SX0VRVUFMLnRzIiwid2VicGFjazovL3hkYmMvLi9zcmMvREJDL0VRLnRzIiwid2VicGFjazovL3hkYmMvLi9zcmMvREJDL0VRL0RJRkZFUkVOVC50cyIsIndlYnBhY2s6Ly94ZGJjLy4vc3JjL0RCQy9JTlNUQU5DRS50cyIsIndlYnBhY2s6Ly94ZGJjLy4vc3JjL0RCQy9SRUdFWC50cyIsIndlYnBhY2s6Ly94ZGJjLy4vc3JjL0RCQy9UWVBFLnRzIiwid2VicGFjazovL3hkYmMvd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8veGRiYy93ZWJwYWNrL3J1bnRpbWUvZGVmaW5lIHByb3BlcnR5IGdldHRlcnMiLCJ3ZWJwYWNrOi8veGRiYy93ZWJwYWNrL3J1bnRpbWUvaGFzT3duUHJvcGVydHkgc2hvcnRoYW5kIiwid2VicGFjazovL3hkYmMvd2VicGFjay9ydW50aW1lL21ha2UgbmFtZXNwYWNlIG9iamVjdCIsIndlYnBhY2s6Ly94ZGJjLy4vc3JjL0RlbW8udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQcm92aWRlcyBhICoqRCoqZXNpZ24gKipCKip5ICoqQyoqb250cmFjdCBGcmFtZXdvcmsgdXNpbmcgZGVjb3JhdG9ycy5cbiAqXG4gKiBAcmVtYXJrc1xuICogTWFpbnRhaW5lcjogQ2FsbGFyaSwgU2FsdmF0b3JlIChYREJDQFdhWENvZGUubmV0KSAqL1xuZXhwb3J0IGNsYXNzIERCQyB7XG4gICAgLyoqIEV2aWN0cyB0aGUgb2xkZXN0IGVudHJ5IGlmIHRoZSBjYWNoZSBleGNlZWRzIHRoZSBtYXhpbXVtIHNpemUuICovXG4gICAgc3RhdGljIGV2aWN0SWZOZWVkZWQoY2FjaGUpIHtcbiAgICAgICAgaWYgKGNhY2hlLnNpemUgPiBEQkMuTUFYX0NBQ0hFX1NJWkUpIHtcbiAgICAgICAgICAgIGNvbnN0IG9sZGVzdCA9IGNhY2hlLmtleXMoKS5uZXh0KCkudmFsdWU7XG4gICAgICAgICAgICBpZiAob2xkZXN0ICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgICAgICAgY2FjaGUuZGVsZXRlKG9sZGVzdCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGdldEhvc3QoKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDogZ2xvYmFsVGhpcztcbiAgICB9XG4gICAgc3RhdGljIGdldERCQyhkYmMpIHtcbiAgICAgICAgaWYgKGRiYyBpbnN0YW5jZW9mIERCQylcbiAgICAgICAgICAgIHJldHVybiBkYmM7XG4gICAgICAgIGNvbnN0IHBhdGggPSBkYmMgIT09IG51bGwgJiYgZGJjICE9PSB2b2lkIDAgPyBkYmMgOiBcIldhWENvZGUuREJDXCI7XG4gICAgICAgIGlmIChEQkMuZGJjQ2FjaGUuaGFzKHBhdGgpKSB7XG4gICAgICAgICAgICByZXR1cm4gREJDLmRiY0NhY2hlLmdldChwYXRoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZXNvbHZlZCA9IERCQy5yZXNvbHZlREJDUGF0aChEQkMuZ2V0SG9zdCgpLCBwYXRoKTtcbiAgICAgICAgaWYgKHJlc29sdmVkKSB7XG4gICAgICAgICAgICBEQkMuZXZpY3RJZk5lZWRlZChEQkMuZGJjQ2FjaGUpO1xuICAgICAgICAgICAgREJDLmRiY0NhY2hlLnNldChwYXRoLCByZXNvbHZlZCk7XG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZWQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBbWERCQ10gREJDIGluc3RhbmNlIG5vdCBmb3VuZCBhdCBwYXRoIFwiJHtwYXRofVwiLiBFbnN1cmUgYSBEQkMgaW5zdGFuY2UgaXMgcmVnaXN0ZXJlZCB0aGVyZS5gKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2VuZXJhdGUgYSB1bmlxdWUga2V5IGZvciBzdG9yaW5nIHBhcmFtZXRlciB2YWx1ZSByZXF1ZXN0cy5cbiAgICAgKiBGb3JtYXQ6IFwiQ2xhc3NOYW1lOm1ldGhvZE5hbWVcIlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRSZXF1ZXN0S2V5KHRhcmdldCwgbWV0aG9kTmFtZSkge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIGNvbnN0IGNsYXNzTmFtZSA9IHR5cGVvZiB0YXJnZXQgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICAgICAgPyB0YXJnZXQubmFtZVxuICAgICAgICAgICAgOiAoKF9hID0gdGFyZ2V0LmNvbnN0cnVjdG9yKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2EubmFtZSkgfHwgXCJVbmtub3duXCI7XG4gICAgICAgIHJldHVybiBgJHtjbGFzc05hbWV9OiR7U3RyaW5nKG1ldGhvZE5hbWUpfWA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE1ha2UgYSByZXF1ZXN0IHRvIGdldCB0aGUgdmFsdWUgb2YgYSBjZXJ0YWluIHBhcmFtZXRlciBvZiBzcGVjaWZpYyBtZXRob2QgaW4gYSBzcGVjaWZpYyB7QGxpbmsgb2JqZWN0IH0uXG4gICAgICogVGhhdCByZXF1ZXN0IGdldHMgZW5saXN0ZWQgaW4ge0BsaW5rIHBhcmFtVmFsdWVSZXF1ZXN0cyB9IHdoaWNoIGlzIHVzZWQgYnkge0BsaW5rIFBhcmFtdmFsdWVQcm92aWRlcn0gdG8gaW52b2tlIHRoZVxuICAgICAqIGdpdmVuIFwicmVjZXB0b3JcIiB3aXRoIHRoZSBwYXJhbWV0ZXIgdmFsdWUgc3RvcmVkIGluIHRoZXJlLiBUaHVzIGEgcGFyYW1ldGVyIGRlY29yYXRvciB1c2luZyB0aGlzIG1ldGhvZCB3aWxsXG4gICAgICogbm90IHJlY2VpdmUgYW55IHZhbHVlIG9mIHRoZSB0b3AgbWV0aG9kIGlzIG5vdCB0YWdnZWQgd2l0aCB7QGxpbmsgUGFyYW12YWx1ZVByb3ZpZGVyfS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0YXJnZXRcdFx0VGhlIHtAbGluayBvYmplY3QgfSBjb250YWluaW5nIHRoZSBtZXRob2Qgd2l0aCB0aGUgcGFyYW1ldGVyIHdoaWNoJ3MgdmFsdWUgaXMgcmVxdWVzdGVkLlxuICAgICAqIEBwYXJhbSBtZXRob2ROYW1lXHRUaGUgbmFtZSBvZiB0aGUgbWV0aG9kIHdpdGggdGhlIHBhcmFtZXRlciB3aGljaCdzIHZhbHVlIGlzIHJlcXVlc3RlZC5cbiAgICAgKiBAcGFyYW0gaW5kZXhcdFx0XHRUaGUgaW5kZXggb2YgdGhlIHBhcmFtZXRlciB3aGljaCdzIHZhbHVlIGlzIHJlcXVlc3RlZC5cbiAgICAgKiBAcGFyYW0gcmVjZXB0b3JcdFx0VGhlIG1ldGhvZCB0aGUgcmVxdWVzdGVkIHBhcmFtZXRlci12YWx1ZSBzaGFsbCBiZSBwYXNzZWQgdG8gd2hlbiBpdCBiZWNvbWVzIGF2YWlsYWJsZS4gKi9cbiAgICBzdGF0aWMgcmVxdWVzdFBhcmFtVmFsdWUodGFyZ2V0LCBtZXRob2ROYW1lLCBpbmRleCwgXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBHb3R0YSBiZSBhbnkgc2luY2UgcGFyYW1ldGVyLXZhbHVlcyBtYXkgYmUgdW5kZWZpbmVkLlxuICAgIHJlY2VwdG9yKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgY29uc3Qga2V5ID0gREJDLmdldFJlcXVlc3RLZXkodGFyZ2V0LCBtZXRob2ROYW1lKTtcbiAgICAgICAgaWYgKERCQy5wYXJhbVZhbHVlUmVxdWVzdHMuaGFzKGtleSkpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtTWFwID0gREJDLnBhcmFtVmFsdWVSZXF1ZXN0cy5nZXQoa2V5KTtcbiAgICAgICAgICAgIGlmIChwYXJhbU1hcC5oYXMoaW5kZXgpKSB7XG4gICAgICAgICAgICAgICAgKF9hID0gcGFyYW1NYXAuZ2V0KGluZGV4KSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLnB1c2gocmVjZXB0b3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcGFyYW1NYXAuc2V0KGluZGV4LCBuZXcgQXJyYXkocmVjZXB0b3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIERCQy5wYXJhbVZhbHVlUmVxdWVzdHMuc2V0KGtleSwgbmV3IE1hcChbXG4gICAgICAgICAgICAgICAgW2luZGV4LCBuZXcgQXJyYXkocmVjZXB0b3IpXSxcbiAgICAgICAgICAgIF0pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE11c3QgaGFuZGxlIGJvdGggbWV0aG9kIGFuZCBjbGFzcyBkZWNvcmF0b3Igc2lnbmF0dXJlc1xuICAgIHN0YXRpYyBQYXJhbXZhbHVlUHJvdmlkZXIoLi4uYXJncykge1xuICAgICAgICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGFyZ3NbMF0gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgLy8gI3JlZ2lvbiBDbGFzcyBkZWNvcmF0b3IgcGF0aFxuICAgICAgICAgICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBNdXN0IGFjY2VwdCBhbnkgY29uc3RydWN0b3Igc2lnbmF0dXJlXG4gICAgICAgICAgICBjb25zdCBjb25zdHJ1Y3RvciA9IGFyZ3NbMF07XG4gICAgICAgICAgICBjb25zdCBrZXkgPSBgJHtjb25zdHJ1Y3Rvci5uYW1lfTp1bmRlZmluZWRgO1xuICAgICAgICAgICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBNdXN0IGFjY2VwdCBhbnkgY29uc3RydWN0b3Igc2lnbmF0dXJlXG4gICAgICAgICAgICBjb25zdCBXcmFwcGVkQ2xhc3MgPSBjbGFzcyBleHRlbmRzIGNvbnN0cnVjdG9yIHtcbiAgICAgICAgICAgICAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE11c3QgYWNjZXB0IGFueSBjb25zdHJ1Y3RvciBzaWduYXR1cmVcbiAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciguLi5jdG9yQXJncykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoREJDLnBhcmFtVmFsdWVSZXF1ZXN0cy5oYXMoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFyYW1NYXAgPSBEQkMucGFyYW1WYWx1ZVJlcXVlc3RzLmdldChrZXkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBpbmRleCBvZiBwYXJhbU1hcC5rZXlzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPCBjdG9yQXJncy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWNlcHRvciBvZiBwYXJhbU1hcC5nZXQoaW5kZXgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlcHRvcihjdG9yQXJnc1tpbmRleF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHN1cGVyKC4uLmN0b3JBcmdzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFdyYXBwZWRDbGFzcywgXCJuYW1lXCIsIHsgdmFsdWU6IGNvbnN0cnVjdG9yLm5hbWUgfSk7XG4gICAgICAgICAgICByZXR1cm4gV3JhcHBlZENsYXNzO1xuICAgICAgICAgICAgLy8gI2VuZHJlZ2lvbiBDbGFzcyBkZWNvcmF0b3IgcGF0aFxuICAgICAgICB9XG4gICAgICAgIC8vICNyZWdpb24gTWV0aG9kIGRlY29yYXRvciBwYXRoXG4gICAgICAgIGNvbnN0IFt0YXJnZXQsIHByb3BlcnR5S2V5LCBkZXNjcmlwdG9yXSA9IGFyZ3M7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsTWV0aG9kID0gZGVzY3JpcHRvci52YWx1ZTtcbiAgICAgICAgY29uc3QgaXNTdGF0aWMgPSB0eXBlb2YgdGFyZ2V0ID09PSBcImZ1bmN0aW9uXCI7XG4gICAgICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogR290dGEgYmUgYW55IHNpbmNlIHBhcmFtZXRlci12YWx1ZXMgbWF5IGJlIHVuZGVmaW5lZC5cbiAgICAgICAgZGVzY3JpcHRvci52YWx1ZSA9IGZ1bmN0aW9uICguLi5tZXRob2RBcmdzKSB7XG4gICAgICAgICAgICAvLyAjcmVnaW9uICAgQ2hlY2sgaWYgYSB2YWx1ZSBvZiBvbmUgb2YgdGhlIG1ldGhvZCdzIHBhcmFtZXRlciBoYXMgYmVlbiByZXF1ZXN0ZWQgYW5kIHBhc3MgaXQgdG8gdGhlXG4gICAgICAgICAgICAvLyAgICAgICAgICAgcmVjZXB0b3IsIGlmIHNvLlxuICAgICAgICAgICAgY29uc3QgYWN0dWFsVGFyZ2V0ID0gaXNTdGF0aWMgPyB0aGlzIDogdGhpcy5jb25zdHJ1Y3RvcjtcbiAgICAgICAgICAgIGNvbnN0IGtleSA9IERCQy5nZXRSZXF1ZXN0S2V5KGFjdHVhbFRhcmdldCwgcHJvcGVydHlLZXkpO1xuICAgICAgICAgICAgaWYgKERCQy5wYXJhbVZhbHVlUmVxdWVzdHMuaGFzKGtleSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJhbU1hcCA9IERCQy5wYXJhbVZhbHVlUmVxdWVzdHMuZ2V0KGtleSk7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBpbmRleCBvZiBwYXJhbU1hcC5rZXlzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4IDwgbWV0aG9kQXJncy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcmVjZXB0b3Igb2YgcGFyYW1NYXAuZ2V0KGluZGV4KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VwdG9yKG1ldGhvZEFyZ3NbaW5kZXhdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcIk5vIHBhcmFtZXRlciB2YWx1ZSByZXF1ZXN0cyBmb3VuZCBmb3Iga2V5OlwiLCBrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gI2VuZHJlZ2lvblx0Q2hlY2sgaWYgYSB2YWx1ZSBvZiBvbmUgb2YgdGhlIG1ldGhvZCdzIHBhcmFtZXRlciBoYXMgYmVlbiByZXF1ZXN0ZWQgYW5kIHBhc3MgaXQgdG8gdGhlXG4gICAgICAgICAgICAvLyAgICAgICAgICAgICAgcmVjZXB0b3IsIGlmIHNvLlxuICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsTWV0aG9kLmFwcGx5KHRoaXMsIG1ldGhvZEFyZ3MpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgICAgICAgLy8gI2VuZHJlZ2lvbiBNZXRob2QgZGVjb3JhdG9yIHBhdGhcbiAgICB9XG4gICAgLy8gI2VuZHJlZ2lvbiBQYXJhbWV0ZXItdmFsdWUgcmVxdWVzdHMuXG4gICAgLy8gI3JlZ2lvbiBDbGFzc1xuICAgIC8qKlxuICAgICAqIEEgcHJvcGVydHktZGVjb3JhdG9yIGZhY3Rvcnkgc2VydmluZyBhcyBhICoqRCoqZXNpZ24gKipCKip5ICoqQyoqb250cmFjdCBJbnZhcmlhbnQuXG4gICAgICogVGhpcyBpbnZhcmlhbnQgYWltcyB0byBjaGVjayB0aGUgaW5zdGFuY2Ugb2YgdGhlIGNsYXNzIG5vdCB0aGUgdmFsdWUgdG8gYmUgZ2V0IG9yIHNldC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBjb250cmFjdHMgVGhlIHtAbGluayBEQkMgfS1Db250cmFjdHMgdGhlIHZhbHVlIHNoYWxsIHVwaG9sZC5cbiAgICAgKlxuICAgICAqIEB0aHJvd3MgXHRBIHtAbGluayBEQkMuSW5mcmluZ2VtZW50IH0gd2hlbmV2ZXIgdGhlIHByb3BlcnR5IGlzIHRyaWVkIHRvIGJlIGdldCBvciBzZXQgd2l0aG91dCB0aGUgaW5zdGFuY2Ugb2YgaXQncyBjbGFzc1xuICAgICAqIFx0XHRcdGZ1bGZpbGxpbmcgdGhlIHNwZWNpZmllZCAqKmNvbnRyYWN0cyoqLiAqL1xuICAgIHN0YXRpYyBkZWNDbGFzc0ludmFyaWFudChjb250cmFjdHMsIHBhdGggPSB1bmRlZmluZWQsIGRiYyA9IFwiV2FYQ29kZS5EQkNcIikge1xuICAgICAgICBsZXQgZGJjSW5zdGFuY2U7XG4gICAgICAgIHJldHVybiAodGFyZ2V0LCBwcm9wZXJ0eUtleSwgZGVzY3JpcHRvcikgPT4ge1xuICAgICAgICAgICAgaWYgKCFkYmNJbnN0YW5jZSlcbiAgICAgICAgICAgICAgICBkYmNJbnN0YW5jZSA9IERCQy5nZXREQkMoZGJjKTtcbiAgICAgICAgICAgIGlmICghZGJjSW5zdGFuY2UuZXhlY3V0aW9uU2V0dGluZ3MuY2hlY2tJbnZhcmlhbnRzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxTZXR0ZXIgPSBkZXNjcmlwdG9yLnNldDtcbiAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsR2V0dGVyID0gZGVzY3JpcHRvci5nZXQ7XG4gICAgICAgICAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE5lY2Vzc2FyeSB0byBpbnRlcmNlcHQgVU5ERUZJTkVEIGFuZCBOVUxMLlxuICAgICAgICAgICAgbGV0IHZhbHVlO1xuICAgICAgICAgICAgLy8gI3JlZ2lvbiBSZXBsYWNlIG9yaWdpbmFsIHByb3BlcnR5LlxuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIHtcbiAgICAgICAgICAgICAgICBnZXQoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghKGRiY0luc3RhbmNlID09PSBudWxsIHx8IGRiY0luc3RhbmNlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBkYmNJbnN0YW5jZS5leGVjdXRpb25TZXR0aW5ncy5jaGVja0ludmFyaWFudHMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVhbFZhbHVlID0gcGF0aCA/IERCQy5yZXNvbHZlKHRoaXMsIHBhdGgpIDogdGhpcztcbiAgICAgICAgICAgICAgICAgICAgLy8gI3JlZ2lvbiBDaGVjayBpZiBhbGwgXCJjb250cmFjdHNcIiBhcmUgZnVsZmlsbGVkLlxuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNvbnRyYWN0IG9mIGNvbnRyYWN0cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gY29udHJhY3QuY2hlY2socmVhbFZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzdWx0ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGJjSW5zdGFuY2UgPT09IG51bGwgfHwgZGJjSW5zdGFuY2UgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGRiY0luc3RhbmNlLnJlcG9ydEZpZWxkSW5mcmluZ2VtZW50KHJlc3VsdCwgdGFyZ2V0LCBwYXRoLCBwcm9wZXJ0eUtleSwgcmVhbFZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyAjZW5kcmVnaW9uIENoZWNrIGlmIGFsbCBcImNvbnRyYWN0c1wiIGFyZSBmdWxmaWxsZWQuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbEdldHRlciA/IG9yaWdpbmFsR2V0dGVyW3Byb3BlcnR5S2V5XSA6IHZhbHVlO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc2V0KG5ld1ZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghKGRiY0luc3RhbmNlID09PSBudWxsIHx8IGRiY0luc3RhbmNlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBkYmNJbnN0YW5jZS5leGVjdXRpb25TZXR0aW5ncy5jaGVja0ludmFyaWFudHMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVhbFZhbHVlID0gcGF0aCA/IERCQy5yZXNvbHZlKHRoaXMsIHBhdGgpIDogdGhpcztcbiAgICAgICAgICAgICAgICAgICAgLy8gI3JlZ2lvbiBDaGVjayBpZiBhbGwgXCJjb250cmFjdHNcIiBhcmUgZnVsZmlsbGVkLlxuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNvbnRyYWN0IG9mIGNvbnRyYWN0cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gY29udHJhY3QuY2hlY2socmVhbFZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzdWx0ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGJjSW5zdGFuY2UgPT09IG51bGwgfHwgZGJjSW5zdGFuY2UgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGRiY0luc3RhbmNlLnJlcG9ydEZpZWxkSW5mcmluZ2VtZW50KHJlc3VsdCwgdGFyZ2V0LCBwYXRoLCBwcm9wZXJ0eUtleSwgcmVhbFZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyAjZW5kcmVnaW9uIENoZWNrIGlmIGFsbCBcImNvbnRyYWN0c1wiIGFyZSBmdWxmaWxsZWQuXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gbmV3VmFsdWU7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gI2VuZHJlZ2lvbiBSZXBsYWNlIG9yaWdpbmFsIHByb3BlcnR5LlxuICAgICAgICB9O1xuICAgIH1cbiAgICAvLyAjZW5kcmVnaW9uIENsYXNzXG4gICAgLy8gI3JlZ2lvbiBJbnZhcmlhbnRcbiAgICAvKipcbiAgICAgKiBBIHByb3BlcnR5LWRlY29yYXRvciBmYWN0b3J5IHNlcnZpbmcgYXMgYSAqKkQqKmVzaWduICoqQioqeSAqKkMqKm9udHJhY3QgSW52YXJpYW50LlxuICAgICAqIFNpbmNlIHRoZSB2YWx1ZSBtdXN0IGJlIGluaXRpYWxpemVkIG9yIHNldCBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCAqKmNvbnRyYWN0cyoqIHRoZSB2YWx1ZSB3aWxsIG9ubHkgYmUgY2hlY2tlZFxuICAgICAqIHdoZW4gYXNzaWduaW5nIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIGNvbnRyYWN0cyBUaGUge0BsaW5rIERCQyB9LUNvbnRyYWN0cyB0aGUgdmFsdWUgc2hhbGwgdXBob2xkLlxuICAgICAqXG4gICAgICogQHRocm93cyBcdEEge0BsaW5rIERCQy5JbmZyaW5nZW1lbnQgfSB3aGVuZXZlciB0aGUgcHJvcGVydHkgaXMgdHJpZWQgdG8gYmUgc2V0IHRvIGEgdmFsdWUgdGhhdCBkb2VzIG5vdCBjb21wbHkgdG8gdGhlXG4gICAgICogXHRcdFx0c3BlY2lmaWVkICoqY29udHJhY3RzKiosIGJ5IHRoZSByZXR1cm5lZCBtZXRob2QuKi9cbiAgICBzdGF0aWMgZGVjSW52YXJpYW50KGNvbnRyYWN0cywgcGF0aCA9IHVuZGVmaW5lZCwgZGJjID0gdW5kZWZpbmVkLCBoaW50ID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGxldCBkYmNJbnN0YW5jZTtcbiAgICAgICAgcmV0dXJuICh0YXJnZXQsIHByb3BlcnR5S2V5KSA9PiB7XG4gICAgICAgICAgICBpZiAoIWRiY0luc3RhbmNlKVxuICAgICAgICAgICAgICAgIGRiY0luc3RhbmNlID0gREJDLmdldERCQyhkYmMpO1xuICAgICAgICAgICAgaWYgKCFkYmNJbnN0YW5jZS5leGVjdXRpb25TZXR0aW5ncy5jaGVja0ludmFyaWFudHMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE5lY2Vzc2FyeSB0byBpbnRlcmNlcHQgVU5ERUZJTkVEIGFuZCBOVUxMLlxuICAgICAgICAgICAgbGV0IHZhbHVlO1xuICAgICAgICAgICAgLy8gI3JlZ2lvbiBSZXBsYWNlIG9yaWdpbmFsIHByb3BlcnR5LlxuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIHtcbiAgICAgICAgICAgICAgICBzZXQobmV3VmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEoZGJjSW5zdGFuY2UgPT09IG51bGwgfHwgZGJjSW5zdGFuY2UgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGRiY0luc3RhbmNlLmV4ZWN1dGlvblNldHRpbmdzLmNoZWNrSW52YXJpYW50cykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCByZWFsVmFsdWUgPSBwYXRoID8gREJDLnJlc29sdmUobmV3VmFsdWUsIHBhdGgpIDogbmV3VmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIC8vICNyZWdpb24gQ2hlY2sgaWYgYWxsIFwiY29udHJhY3RzXCIgYXJlIGZ1bGZpbGxlZC5cbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBjb250cmFjdCBvZiBjb250cmFjdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnRyYWN0LmNoZWNrKHJlYWxWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHJlc3VsdCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRiY0luc3RhbmNlID09PSBudWxsIHx8IGRiY0luc3RhbmNlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBkYmNJbnN0YW5jZS5yZXBvcnRGaWVsZEluZnJpbmdlbWVudChyZXN1bHQsIHRhcmdldCwgcGF0aCwgcHJvcGVydHlLZXksIHJlYWxWYWx1ZSwgaGludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gI2VuZHJlZ2lvbiBDaGVjayBpZiBhbGwgXCJjb250cmFjdHNcIiBhcmUgZnVsZmlsbGVkLlxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vICNlbmRyZWdpb24gUmVwbGFjZSBvcmlnaW5hbCBwcm9wZXJ0eS5cbiAgICAgICAgfTtcbiAgICB9XG4gICAgLy8gI2VuZHJlZ2lvbiBJbnZhcmlhbnRcbiAgICAvLyAjcmVnaW9uIFBvc3Rjb25kaXRpb25cbiAgICAvKipcbiAgICAgKiBBIG1ldGhvZCBkZWNvcmF0b3IgZmFjdG9yeSBjaGVja2luZyB0aGUgcmVzdWx0IG9mIGEgbWV0aG9kIHdoZW5ldmVyIGl0IGlzIGludm9rZWQgdGh1cyBhbHNvIHVzYWJsZSBvbiBnZXR0ZXJzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGNoZWNrXHRUaGUgKioodG9DaGVjazogYW55LCBvYmplY3QsIHN0cmluZykgPT4gYm9vbGVhbiB8IHN0cmluZyoqIHRvIHVzZSBmb3IgY2hlY2tpbmcuXG4gICAgICogQHBhcmFtIGRiY1x0U2VlIHtAbGluayBEQkMucmVzb2x2ZURCQ1BhdGggfS5cbiAgICAgKiBAcGFyYW0gcGF0aFx0VGhlIGRvdHRlZCBwYXRoIHJlZmVycmluZyB0byB0aGUgYWN0dWFsIHZhbHVlIHRvIGNoZWNrLCBzdGFydGluZyBmb3JtIHRoZSBzcGVjaWZpZWQgb25lLlxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlICoqKCB0YXJnZXQgOiBvYmplY3QsIHByb3BlcnR5S2V5IDogc3RyaW5nLCBkZXNjcmlwdG9yIDogUHJvcGVydHlEZXNjcmlwdG9yICkgOiBQcm9wZXJ0eURlc2NyaXB0b3IqKlxuICAgICAqIFx0XHRcdGludm9rZWQgYnkgVHlwZXNjcmlwdC5cbiAgICAgKi9cbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE5lY2Vzc2FyeSB0byBpbnRlcmNlcHQgVU5ERUZJTkVEIGFuZCBOVUxMLlxuICAgIHN0YXRpYyBkZWNQb3N0Y29uZGl0aW9uKFxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogTmVjZXNzYXJ5IHRvIGludGVyY2VwdCBVTkRFRklORUQgYW5kIE5VTEwuXG4gICAgY2hlY2ssIGRiYyA9IHVuZGVmaW5lZCwgcGF0aCA9IHVuZGVmaW5lZCwgaGludCA9IHVuZGVmaW5lZCkge1xuICAgICAgICBsZXQgZGJjSW5zdGFuY2U7XG4gICAgICAgIHJldHVybiAodGFyZ2V0LCBwcm9wZXJ0eUtleSwgZGVzY3JpcHRvcikgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxNZXRob2QgPSBkZXNjcmlwdG9yLnZhbHVlO1xuICAgICAgICAgICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBOZWNlc3NhcnkgdG8gaW50ZXJjZXB0IFVOREVGSU5FRCBhbmQgTlVMTC5cbiAgICAgICAgICAgIGRlc2NyaXB0b3IudmFsdWUgPSAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghZGJjSW5zdGFuY2UpXG4gICAgICAgICAgICAgICAgICAgIGRiY0luc3RhbmNlID0gREJDLmdldERCQyhkYmMpO1xuICAgICAgICAgICAgICAgIGlmICghZGJjSW5zdGFuY2UuZXhlY3V0aW9uU2V0dGluZ3MuY2hlY2tQb3N0Y29uZGl0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L2NvbXBsZXhpdHkvbm9UaGlzSW5TdGF0aWM6IDxleHBsYW5hdGlvbj5cbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBvcmlnaW5hbE1ldGhvZC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgICAgICBjb25zdCByZWFsVmFsdWUgPSBwYXRoID8gREJDLnJlc29sdmUocmVzdWx0LCBwYXRoKSA6IHJlc3VsdDtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGVja1Jlc3VsdCA9IGNoZWNrKHJlYWxWYWx1ZSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjaGVja1Jlc3VsdCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgICAgICBkYmNJbnN0YW5jZS5yZXBvcnRSZXR1cm52YWx1ZUluZnJpbmdlbWVudChjaGVja1Jlc3VsdCwgdGFyZ2V0LCBwYXRoLCBwcm9wZXJ0eUtleSwgcmVhbFZhbHVlLCBoaW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLy8gI2VuZHJlZ2lvbiBQb3N0Y29uZGl0aW9uXG4gICAgLy8gI3JlZ2lvbiBEZWNvcmF0b3JcbiAgICAvLyAjcmVnaW9uIFByZWNvbmRpdGlvblxuICAgIC8qKlxuICAgICAqIEEgcGFyYW1ldGVyLWRlY29yYXRvciBmYWN0b3J5IHRoYXQgcmVxdWVzdHMgdGhlIHRhZ2dlZCBwYXJhbWV0ZXIncyB2YWx1ZSBwYXNzaW5nIGl0IHRvIHRoZSBwcm92aWRlZFxuICAgICAqIFwiY2hlY2tcIi1tZXRob2Qgd2hlbiB0aGUgdmFsdWUgYmVjb21lcyBhdmFpbGFibGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2hlY2tcdFRoZSBcIiggdW5rbm93biApID0+IHZvaWRcIiB0byBiZSBpbnZva2VkIGFsb25nIHdpdGggdGhlIHRhZ2dlZCBwYXJhbWV0ZXIncyB2YWx1ZSBhcyBzb29uXG4gICAgICogXHRcdFx0XHRhcyBpdCBiZWNvbWVzIGF2YWlsYWJsZS5cbiAgICAgKiBAcGFyYW0gZGJjICBcdFNlZSB7QGxpbmsgREJDLnJlc29sdmVEQkNQYXRoIH0uXG4gICAgICogQHBhcmFtIHBhdGhcdFRoZSBkb3R0ZWQgcGF0aCByZWZlcnJpbmcgdG8gdGhlIGFjdHVhbCB2YWx1ZSB0byBjaGVjaywgc3RhcnRpbmcgZm9ybSB0aGUgc3BlY2lmaWVkIG9uZS5cbiAgICAgKiBcdFx0XHRcdE1heSBjb250YWluIDo6IHRvIHNlcGFyYXRlIG11bHRpcGxlIHBhdGhzLlxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlICoqKHRhcmdldDogb2JqZWN0LCBtZXRob2ROYW1lOiBzdHJpbmcgfCBzeW1ib2wsIHBhcmFtZXRlckluZGV4OiBudW1iZXIgKSA9PiB2b2lkKiogaW52b2tlZCBieSBUeXBlc2NyaXB0LSAqL1xuICAgIHN0YXRpYyBkZWNQcmVjb25kaXRpb24oXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBOZWNlc3NhcnkgdG8gY2hlY2sgYW55IHBhcmFtZXRlciB2YWx1ZVxuICAgIGNoZWNrLCBkYmMgPSB1bmRlZmluZWQsIHBhdGggPSB1bmRlZmluZWQsIGhpbnQgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgcGF0aHMgPSBwYXRoID8gcGF0aC5yZXBsYWNlKC8gL2csIFwiXCIpLnNwbGl0KFwiOjpcIikgOiBbdW5kZWZpbmVkXTtcbiAgICAgICAgbGV0IGRiY0luc3RhbmNlO1xuICAgICAgICByZXR1cm4gKHRhcmdldCwgbWV0aG9kTmFtZSwgcGFyYW1ldGVySW5kZXgpID0+IHtcbiAgICAgICAgICAgIERCQy5yZXF1ZXN0UGFyYW1WYWx1ZSh0YXJnZXQsIG1ldGhvZE5hbWUsIHBhcmFtZXRlckluZGV4LCAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIWRiY0luc3RhbmNlKVxuICAgICAgICAgICAgICAgICAgICBkYmNJbnN0YW5jZSA9IERCQy5nZXREQkMoZGJjKTtcbiAgICAgICAgICAgICAgICBpZiAoIWRiY0luc3RhbmNlLmV4ZWN1dGlvblNldHRpbmdzLmNoZWNrUHJlY29uZGl0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgc2luZ2xlUGF0aCBvZiBwYXRocykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZWFsVmFsdWUgPSBzaW5nbGVQYXRoXG4gICAgICAgICAgICAgICAgICAgICAgICA/IERCQy5yZXNvbHZlKHZhbHVlLCBzaW5nbGVQYXRoKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gY2hlY2socmVhbFZhbHVlLCB0YXJnZXQsIG1ldGhvZE5hbWUsIHBhcmFtZXRlckluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRiY0luc3RhbmNlLnJlcG9ydFBhcmFtZXRlckluZnJpbmdlbWVudChyZXN1bHQsIHRhcmdldCwgc2luZ2xlUGF0aCwgbWV0aG9kTmFtZSwgcGFyYW1ldGVySW5kZXgsIHJlYWxWYWx1ZSwgaGludCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLy8gI2VuZHJlZ2lvbiBQcmVjb25kaXRpb25cbiAgICAvLyAjZW5kcmVnaW9uIERlY29yYXRvclxuICAgIC8vICNyZWdpb24gQ29udHJhY3QgRmFjdG9yeSBIZWxwZXJzXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIFBSRSBkZWNvcmF0b3IgZnJvbSBhIGNoZWNrQWxnb3JpdGhtIGZ1bmN0aW9uIGFuZCBpdHMgYm91bmQgYXJndW1lbnRzLlxuICAgICAqIFJlZHVjZXMgYm9pbGVycGxhdGUgYWNyb3NzIGNvbnRyYWN0IGNsYXNzZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2hlY2tGbiAgQSBmdW5jdGlvbiB0aGF0IHRha2VzICh2YWx1ZSwgLi4uYm91bmRBcmdzKSBhbmQgcmV0dXJucyB0cnVlIG9yIGFuIGVycm9yIHN0cmluZy5cbiAgICAgKiBAcGFyYW0gYm91bmRBcmdzIFRoZSBhcmd1bWVudHMgdG8gYmluZCB0byB0aGUgY2hlY2sgZnVuY3Rpb24gYWZ0ZXIgdGhlIHZhbHVlLlxuICAgICAqIEBwYXJhbSBkYmMgICAgICBTZWUge0BsaW5rIERCQy5kZWNQcmVjb25kaXRpb259LlxuICAgICAqIEBwYXJhbSBwYXRoICAgICBTZWUge0BsaW5rIERCQy5kZWNQcmVjb25kaXRpb259LlxuICAgICAqIEBwYXJhbSBoaW50ICAgICBTZWUge0BsaW5rIERCQy5kZWNQcmVjb25kaXRpb259LlxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVQUkUoXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBNdXN0IGFjY2VwdCBhbnkgY2hlY2tBbGdvcml0aG0gc2lnbmF0dXJlXG4gICAgY2hlY2tGbiwgXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBBcmd1bWVudHMgdmFyeSBwZXIgY29udHJhY3RcbiAgICBib3VuZEFyZ3MsIGRiYywgcGF0aCwgaGludCkge1xuICAgICAgICByZXR1cm4gREJDLmRlY1ByZWNvbmRpdGlvbigodmFsdWUsIF90YXJnZXQsIF9tZXRob2ROYW1lLCBfcGFyYW1ldGVySW5kZXgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBjaGVja0ZuKHZhbHVlLCAuLi5ib3VuZEFyZ3MpO1xuICAgICAgICB9LCBkYmMsIHBhdGgsIGhpbnQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgUE9TVCBkZWNvcmF0b3IgZnJvbSBhIGNoZWNrQWxnb3JpdGhtIGZ1bmN0aW9uIGFuZCBpdHMgYm91bmQgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGNoZWNrRm4gIEEgZnVuY3Rpb24gdGhhdCB0YWtlcyAodmFsdWUsIC4uLmJvdW5kQXJncykgYW5kIHJldHVybnMgdHJ1ZSBvciBhbiBlcnJvciBzdHJpbmcuXG4gICAgICogQHBhcmFtIGJvdW5kQXJncyBUaGUgYXJndW1lbnRzIHRvIGJpbmQgdG8gdGhlIGNoZWNrIGZ1bmN0aW9uIGFmdGVyIHRoZSB2YWx1ZS5cbiAgICAgKiBAcGFyYW0gZGJjICAgICAgU2VlIHtAbGluayBEQkMuZGVjUG9zdGNvbmRpdGlvbn0uXG4gICAgICogQHBhcmFtIHBhdGggICAgIFNlZSB7QGxpbmsgREJDLmRlY1Bvc3Rjb25kaXRpb259LlxuICAgICAqIEBwYXJhbSBoaW50ICAgICBTZWUge0BsaW5rIERCQy5kZWNQb3N0Y29uZGl0aW9ufS5cbiAgICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlUE9TVChcbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE11c3QgYWNjZXB0IGFueSBjaGVja0FsZ29yaXRobSBzaWduYXR1cmVcbiAgICBjaGVja0ZuLCBcbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IEFyZ3VtZW50cyB2YXJ5IHBlciBjb250cmFjdFxuICAgIGJvdW5kQXJncywgZGJjLCBwYXRoLCBoaW50KSB7XG4gICAgICAgIHJldHVybiBEQkMuZGVjUG9zdGNvbmRpdGlvbigodmFsdWUsIF90YXJnZXQsIF9wcm9wZXJ0eUtleSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGNoZWNrRm4odmFsdWUsIC4uLmJvdW5kQXJncyk7XG4gICAgICAgIH0sIGRiYywgcGF0aCwgaGludCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gSU5WQVJJQU5UIGRlY29yYXRvciBmcm9tIGEgY29udHJhY3QgY29uc3RydWN0b3IgYW5kIGl0cyBib3VuZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gQ29udHJhY3RDbGFzcyBBIGNsYXNzIHdpdGggYSBjb25zdHJ1Y3RvciB0aGF0IHByb2R1Y2VzIGFuIG9iamVjdCB3aXRoIGEgYGNoZWNrYCBtZXRob2QuXG4gICAgICogQHBhcmFtIGN0b3JBcmdzICAgICAgVGhlIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBjb250cmFjdCBjb25zdHJ1Y3Rvci5cbiAgICAgKiBAcGFyYW0gZGJjICAgICAgICAgICBTZWUge0BsaW5rIERCQy5kZWNJbnZhcmlhbnR9LlxuICAgICAqIEBwYXJhbSBwYXRoICAgICAgICAgIFNlZSB7QGxpbmsgREJDLmRlY0ludmFyaWFudH0uXG4gICAgICogQHBhcmFtIGhpbnQgICAgICAgICAgU2VlIHtAbGluayBEQkMuZGVjSW52YXJpYW50fS5cbiAgICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlSU5WQVJJQU5UKFxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogTXVzdCBhY2NlcHQgYW55IGNvbnRyYWN0IGNvbnN0cnVjdG9yXG4gICAgQ29udHJhY3RDbGFzcywgXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBBcmd1bWVudHMgdmFyeSBwZXIgY29udHJhY3RcbiAgICBjdG9yQXJncywgZGJjLCBwYXRoLCBoaW50KSB7XG4gICAgICAgIHJldHVybiBEQkMuZGVjSW52YXJpYW50KFtuZXcgQ29udHJhY3RDbGFzcyguLi5jdG9yQXJncyldLCBwYXRoLCBkYmMsIGhpbnQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXBvcnRzIGEgd2FybmluZy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBtZXNzYWdlIGNvbnRhaW5pbmcgdGhlIHdhcm5pbmcuICovXG4gICAgcmVwb3J0V2FybmluZyhtZXNzYWdlKSB7XG4gICAgICAgIGlmICh0aGlzLndhcm5pbmdTZXR0aW5ncy5sb2dUb0NvbnNvbGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKiogU2FuaXRpemVzIGEgdmFsdWUgZm9yIHNhZmUgaW5jbHVzaW9uIGluIGVycm9yIG1lc3NhZ2VzLiAqL1xuICAgIHN0YXRpYyBzYW5pdGl6ZSh2YWx1ZSkge1xuICAgICAgICBjb25zdCBzdHIgPSB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgPyB2YWx1ZSA6IFN0cmluZyh2YWx1ZSk7XG4gICAgICAgIHJldHVybiBzdHIucmVwbGFjZSgvWzw+JlwiJ10vZywgKGNoKSA9PiB7XG4gICAgICAgICAgICBzd2l0Y2ggKGNoKSB7XG4gICAgICAgICAgICAgICAgY2FzZSBcIjxcIjpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiJmx0O1wiO1xuICAgICAgICAgICAgICAgIGNhc2UgXCI+XCI6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIiZndDtcIjtcbiAgICAgICAgICAgICAgICBjYXNlIFwiJlwiOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCImYW1wO1wiO1xuICAgICAgICAgICAgICAgIGNhc2UgJ1wiJzpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiJnF1b3Q7XCI7XG4gICAgICAgICAgICAgICAgY2FzZSBcIidcIjpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiJiMzOTtcIjtcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2g7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXBvcnRzIGFuIGluZnJpbmdlbWVudCBhY2NvcmRpbmcgdG8gdGhlIHtAbGluayBpbmZyaW5nZW1lbnRTZXR0aW5ncyB9IGFsc28gZ2VuZXJhdGluZyBhIHByb3BlciB7QGxpbmsgc3RyaW5nIH0td3JhcHBlclxuICAgICAqIGZvciB0aGUgZ2l2ZW4gXCJtZXNzYWdlXCIgJiB2aW9sYXRvci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXNzYWdlXHRUaGUge0BsaW5rIHN0cmluZyB9IGRlc2NyaWJpbmcgdGhlIGluZnJpbmdlbWVudCBhbmQgaXQncyBwcm92ZW5pZW5jZS5cbiAgICAgKiBAcGFyYW0gdmlvbGF0b3IgXHRUaGUge0BsaW5rIHN0cmluZyB9IGRlc2NyaWJpbmcgb3IgbmFtaW5nIHRoZSB2aW9sYXRvci4gKi9cbiAgICByZXBvcnRJbmZyaW5nZW1lbnQobWVzc2FnZSwgdmlvbGF0b3IsIHRhcmdldCwgdmFsdWUsIHBhdGgsIGhpbnQgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3Qgc2FmZVZpb2xhdG9yID0gREJDLnNhbml0aXplKHZpb2xhdG9yKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0TmFtZSA9IHR5cGVvZiB0YXJnZXQgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICAgICAgPyBEQkMuc2FuaXRpemUodGFyZ2V0Lm5hbWUpXG4gICAgICAgICAgICA6IHR5cGVvZiB0YXJnZXQgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgICAgICAgICB0YXJnZXQgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICB0eXBlb2YgdGFyZ2V0LmNvbnN0cnVjdG9yID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICAgICAgICA/IERCQy5zYW5pdGl6ZSh0YXJnZXQuY29uc3RydWN0b3IubmFtZSlcbiAgICAgICAgICAgICAgICA6IERCQy5zYW5pdGl6ZSh0YXJnZXQpO1xuICAgICAgICBjb25zdCBmaW5hbE1lc3NhZ2UgPSBgWyBGcm9tIFwiJHtzYWZlVmlvbGF0b3J9XCIgaW4gXCIke3RhcmdldE5hbWV9XCIke3BhdGggPyBgID4gXCIke0RCQy5zYW5pdGl6ZShwYXRoKX1cImAgOiBcIlwifTogJHttZXNzYWdlfSAke2hpbnQgPyBg4pyoICR7aGludH0g4pyoYCA6IFwiXCJ9XWA7XG4gICAgICAgIGlmICh0aGlzLmluZnJpbmdlbWVudFNldHRpbmdzLnRocm93RXhjZXB0aW9uKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgREJDLkluZnJpbmdlbWVudChmaW5hbE1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmluZnJpbmdlbWVudFNldHRpbmdzLmxvZ1RvQ29uc29sZSkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coZmluYWxNZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXBvcnRzIGEgcGFyYW1ldGVyLWluZnJpbmdlbWVudCB2aWEge0BsaW5rIHJlcG9ydEluZnJpbmdlbWVudCB9IGFsc28gZ2VuZXJhdGluZyBhIHByb3BlciB7QGxpbmsgc3RyaW5nIH0td3JhcHBlclxuICAgICAqIGZvciB0aGUgZ2l2ZW4gXCJtZXNzYWdlXCIsXCJtZXRob2RcIiwgcGFyYW1ldGVyLVwiaW5kZXhcIiAmIHZhbHVlLlxuICAgICAqXG4gICAgICogQHBhcmFtIG1lc3NhZ2VcdFRoZSB7QGxpbmsgc3RyaW5nIH0gZGVzY3JpYmluZyB0aGUgaW5mcmluZ2VtZW50IGFuZCBpdCdzIHByb3ZlbmllbmNlLlxuICAgICAqIEBwYXJhbSBtZXRob2QgXHRUaGUge0BsaW5rIHN0cmluZyB9IGRlc2NyaWJpbmcgb3IgbmFtaW5nIHRoZSB2aW9sYXRvci5cbiAgICAgKiBAcGFyYW0gaW5kZXhcdFx0VGhlIGluZGV4IG9mIHRoZSBwYXJhbWV0ZXIgd2l0aGluIHRoZSBhcmd1bWVudCBsaXN0aW5nLlxuICAgICAqIEBwYXJhbSB2YWx1ZSBcdFRoZSBwYXJhbWV0ZXIncyB2YWx1ZS4gKi9cbiAgICByZXBvcnRQYXJhbWV0ZXJJbmZyaW5nZW1lbnQobWVzc2FnZSwgdGFyZ2V0LCBwYXRoLCBtZXRob2QsIGluZGV4LCB2YWx1ZSwgaGludCA9IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCBwcm9wZXJJbmRleCA9IGluZGV4ICsgMTtcbiAgICAgICAgdGhpcy5yZXBvcnRJbmZyaW5nZW1lbnQoYFsgUGFyYW1ldGVyLXZhbHVlIFwiJHt2YWx1ZX1cIiBvZiB0aGUgJHtwcm9wZXJJbmRleH0ke3Byb3BlckluZGV4ID09PSAxID8gXCJzdFwiIDogcHJvcGVySW5kZXggPT09IDIgPyBcIm5kXCIgOiBwcm9wZXJJbmRleCA9PT0gMyA/IFwicmRcIiA6IFwidGhcIn0gcGFyYW1ldGVyIGRpZCBub3QgZnVsZmlsbCBvbmUgb2YgaXQncyBjb250cmFjdHM6ICR7bWVzc2FnZX0gXWAsIG1ldGhvZCwgdGFyZ2V0LCB2YWx1ZSwgcGF0aCwgaGludCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlcG9ydHMgYSBmaWVsZC1pbmZyaW5nZW1lbnQgdmlhIHtAbGluayByZXBvcnRJbmZyaW5nZW1lbnQgfSBhbHNvIGdlbmVyYXRpbmcgYSBwcm9wZXIge0BsaW5rIHN0cmluZyB9LXdyYXBwZXJcbiAgICAgKiBmb3IgdGhlIGdpdmVuICoqbWVzc2FnZSoqICYgKipuYW1lKiouXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbWVzc2FnZVx0QSB7QGxpbmsgc3RyaW5nIH0gZGVzY3JpYmluZyB0aGUgaW5mcmluZ2VtZW50IGFuZCBpdCdzIHByb3ZlbmllbmNlLlxuICAgICAqIEBwYXJhbSBrZXkgXHRcdFRoZSBwcm9wZXJ0eSBrZXkuXG4gICAgICogQHBhcmFtIHBhdGhcdFx0VGhlIGRvdHRlZC1wYXRoIHtAbGluayBzdHJpbmcgfSB0aGF0IGxlYWRzIHRvIHRoZSB2YWx1ZSBub3QgZnVsZmlsbGluZyB0aGUgY29udHJhY3Qgc3RhcnRpbmcgZnJvbVxuICAgICAqIFx0XHRcdFx0XHR0aGUgdGFnZ2VkIG9uZS5cbiAgICAgKiBAcGFyYW0gdmFsdWVcdFx0VGhlIHZhbHVlIG5vdCBmdWxmaWxsaW5nIGEgY29udHJhY3QuICovXG4gICAgcmVwb3J0RmllbGRJbmZyaW5nZW1lbnQobWVzc2FnZSwgdGFyZ2V0LCBwYXRoLCBrZXksIHZhbHVlLCBoaW50ID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMucmVwb3J0SW5mcmluZ2VtZW50KGBbIE5ldyB2YWx1ZSBmb3IgXCIke2tleX1cIiR7cGF0aCA9PT0gdW5kZWZpbmVkID8gXCJcIiA6IGAuJHtwYXRofWB9IHdpdGggdmFsdWUgXCIke3ZhbHVlfVwiIGRpZCBub3QgZnVsZmlsbCBvbmUgb2YgaXQncyBjb250cmFjdHM6ICR7bWVzc2FnZX0gXWAsIGtleSwgdGFyZ2V0LCB2YWx1ZSwgcGF0aCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlcG9ydHMgYSByZXR1cm52YWx1ZS1pbmZyaW5nZW1lbnQgYWNjb3JkaW5nIHZpYSB7QGxpbmsgcmVwb3J0SW5mcmluZ2VtZW50IH0gYWxzbyBnZW5lcmF0aW5nIGEgcHJvcGVyIHtAbGluayBzdHJpbmcgfS13cmFwcGVyXG4gICAgICogZm9yIHRoZSBnaXZlbiBcIm1lc3NhZ2VcIixcIm1ldGhvZFwiICYgdmFsdWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbWVzc2FnZVx0VGhlIHtAbGluayBzdHJpbmcgfSBkZXNjcmliaW5nIHRoZSBpbmZyaW5nZW1lbnQgYW5kIGl0J3MgcHJvdmVuaWVuY2UuXG4gICAgICogQHBhcmFtIG1ldGhvZCBcdFRoZSB7QGxpbmsgc3RyaW5nIH0gZGVzY3JpYmluZyBvciBuYW1pbmcgdGhlIHZpb2xhdG9yLlxuICAgICAqIEBwYXJhbSB2YWx1ZVx0XHRUaGUgcGFyYW1ldGVyJ3MgdmFsdWUuICovXG4gICAgcmVwb3J0UmV0dXJudmFsdWVJbmZyaW5nZW1lbnQobWVzc2FnZSwgdGFyZ2V0LCBwYXRoLCBtZXRob2QsIFxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogPGV4cGxhbmF0aW9uPlxuICAgIHZhbHVlLCBoaW50ID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMucmVwb3J0SW5mcmluZ2VtZW50KGBbIFJldHVybi12YWx1ZSBcIiR7dmFsdWV9XCIgZGlkIG5vdCBmdWxmaWxsIG9uZSBvZiBpdCdzIGNvbnRyYWN0czogJHttZXNzYWdlfSBdYCwgbWV0aG9kLCB0YXJnZXQsIHZhbHVlLCBwYXRoLCBoaW50KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0cyB0aGlzIHtAbGluayBEQkMgfSB3aXRob3V0IG1vdW50aW5nIGl0IG9uIHRoZSBnbG9iYWwgbmFtZXNwYWNlLlxuICAgICAqIFVzZSB7QGxpbmsgREJDLnJlZ2lzdGVyIH0gdG8gbWFrZSB0aGUgaW5zdGFuY2UgYXZhaWxhYmxlIGF0IGEgc3BlY2lmaWMgcGF0aCBvbiBnbG9iYWxUaGlzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluZnJpbmdlbWVudFNldHRpbmdzIFx0U2VlIHtAbGluayBEQkMuaW5mcmluZ2VtZW50U2V0dGluZ3MgfS5cbiAgICAgKiBAcGFyYW0gZXhlY3V0aW9uU2V0dGluZ3NcdFx0U2VlIHtAbGluayBEQkMuZXhlY3V0aW9uU2V0dGluZ3MgfS4gKi9cbiAgICBjb25zdHJ1Y3RvcihpbmZyaW5nZW1lbnRTZXR0aW5ncyA9IHsgdGhyb3dFeGNlcHRpb246IHRydWUsIGxvZ1RvQ29uc29sZTogZmFsc2UgfSwgZXhlY3V0aW9uU2V0dGluZ3MgPSB7XG4gICAgICAgIGNoZWNrUHJlY29uZGl0aW9uczogdHJ1ZSxcbiAgICAgICAgY2hlY2tQb3N0Y29uZGl0aW9uczogdHJ1ZSxcbiAgICAgICAgY2hlY2tJbnZhcmlhbnRzOiB0cnVlLFxuICAgIH0pIHtcbiAgICAgICAgLy8gI2VuZHJlZ2lvbiBDb250cmFjdCBGYWN0b3J5IEhlbHBlcnNcbiAgICAgICAgLy8gI3JlZ2lvbiBFeGVjdXRpb24gSGFuZGxpbmdcbiAgICAgICAgLyoqIFN0b3JlcyBzZXR0aW5ncyBjb25jZXJuaW5nIHRoZSBleGVjdXRpb24gb2YgY2hlY2tzLiAqL1xuICAgICAgICB0aGlzLmV4ZWN1dGlvblNldHRpbmdzID0ge1xuICAgICAgICAgICAgY2hlY2tQcmVjb25kaXRpb25zOiB0cnVlLFxuICAgICAgICAgICAgY2hlY2tQb3N0Y29uZGl0aW9uczogdHJ1ZSxcbiAgICAgICAgICAgIGNoZWNrSW52YXJpYW50czogdHJ1ZSxcbiAgICAgICAgfTtcbiAgICAgICAgLy8gI2VuZHJlZ2lvbiBFeGVjdXRpb24gSGFuZGxpbmdcbiAgICAgICAgLy8gI3JlZ2lvbiBXYXJuaW5nIGhhbmRsaW5nLlxuICAgICAgICAvKiogU3RvcmVzIHNldHRpbmdzIGNvbmNlcm5pbmcgd2FybmluZ3MuICovXG4gICAgICAgIHRoaXMud2FybmluZ1NldHRpbmdzID0geyBsb2dUb0NvbnNvbGU6IHRydWUgfTtcbiAgICAgICAgLy8gI2VuZHJlZ2lvbiBXYXJuaW5nIGhhbmRsaW5nLlxuICAgICAgICAvLyAjcmVnaW9uIGluZnJpbmdlbWVudCBoYW5kbGluZy5cbiAgICAgICAgLyoqIFN0b3JlcyB0aGUgc2V0dGluZ3MgY29uY2VybmluZyBpbmZyaW5nZW1lbnRzICovXG4gICAgICAgIHRoaXMuaW5mcmluZ2VtZW50U2V0dGluZ3MgPSB7IHRocm93RXhjZXB0aW9uOiB0cnVlLCBsb2dUb0NvbnNvbGU6IGZhbHNlIH07XG4gICAgICAgIHRoaXMuaW5mcmluZ2VtZW50U2V0dGluZ3MgPSBpbmZyaW5nZW1lbnRTZXR0aW5ncztcbiAgICAgICAgdGhpcy5leGVjdXRpb25TZXR0aW5ncyA9IGV4ZWN1dGlvblNldHRpbmdzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlcnMgYSB7QGxpbmsgREJDIH0gaW5zdGFuY2UgYXQgdGhlIHNwZWNpZmllZCBkb3R0ZWQgcGF0aCBvbiBnbG9iYWxUaGlzIChvciB3aW5kb3cpLFxuICAgICAqIG1ha2luZyBpdCBhdmFpbGFibGUgZm9yIGRlY29yYXRvciByZXNvbHV0aW9uIHZpYSBzdHJpbmcgcGF0aHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zdGFuY2VcdFRoZSB7QGxpbmsgREJDIH0gaW5zdGFuY2UgdG8gcmVnaXN0ZXIuXG4gICAgICogQHBhcmFtIHBhdGhcdFx0VGhlIGRvdHRlZCBwYXRoIHRvIHJlZ2lzdGVyIGF0IChkZWZhdWx0OiBgXCJXYVhDb2RlLkRCQ1wiYCkuICovXG4gICAgc3RhdGljIHJlZ2lzdGVyKGluc3RhbmNlLCBwYXRoID0gXCJXYVhDb2RlLkRCQ1wiKSB7XG4gICAgICAgIGNvbnN0IHNlZ21lbnRzID0gcGF0aC5zcGxpdChcIi5cIik7XG4gICAgICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogTXVzdCB3YWxrIGR5bmFtaWMgZ2xvYmFsIG5hbWVzcGFjZS5cbiAgICAgICAgbGV0IG9iaiA9IERCQy5nZXRIb3N0KCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VnbWVudHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgICBpZiAob2JqW3NlZ21lbnRzW2ldXSA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgICAgIG9ialtzZWdtZW50c1tpXV0gPSB7fTtcbiAgICAgICAgICAgIG9iaiA9IG9ialtzZWdtZW50c1tpXV07XG4gICAgICAgIH1cbiAgICAgICAgb2JqW3NlZ21lbnRzW3NlZ21lbnRzLmxlbmd0aCAtIDFdXSA9IGluc3RhbmNlO1xuICAgICAgICBEQkMuZGJjQ2FjaGUuc2V0KHBhdGgsIGluc3RhbmNlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRXhlY3V0ZXMgYSBjYWxsYmFjayB3aXRoIGFuIGlzb2xhdGVkIHtAbGluayBEQkMgfSBpbnN0YW5jZSB0ZW1wb3JhcmlseSByZWdpc3RlcmVkIGF0IHRoZSBkZWZhdWx0IHBhdGguXG4gICAgICogVGhlIHByZXZpb3VzIGluc3RhbmNlIChpZiBhbnkpIGlzIHJlc3RvcmVkIGFmdGVyIHRoZSBjYWxsYmFjayBjb21wbGV0ZXMg4oCUIGV2ZW4gaWYgaXQgdGhyb3dzLlxuICAgICAqIFVzZWZ1bCBmb3IgdGVzdCBpc29sYXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZm4gVGhlIGNhbGxiYWNrIHJlY2VpdmluZyB0aGUgaXNvbGF0ZWQge0BsaW5rIERCQyB9IGluc3RhbmNlLiAqL1xuICAgIHN0YXRpYyBpc29sYXRlZChmbikge1xuICAgICAgICBjb25zdCBzYXZlZCA9IERCQy5kYmNDYWNoZS5nZXQoXCJXYVhDb2RlLkRCQ1wiKTtcbiAgICAgICAgY29uc3QgdGVzdERiYyA9IG5ldyBEQkMoKTtcbiAgICAgICAgREJDLnJlZ2lzdGVyKHRlc3REYmMpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZm4odGVzdERiYyk7XG4gICAgICAgIH1cbiAgICAgICAgZmluYWxseSB7XG4gICAgICAgICAgICBpZiAoc2F2ZWQpIHtcbiAgICAgICAgICAgICAgICBEQkMucmVnaXN0ZXIoc2F2ZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgREJDLmRiY0NhY2hlLmRlbGV0ZShcIldhWENvZGUuREJDXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc29sdmVzIHRoZSBkZXNpcmVkIHtAbGluayBvYmplY3QgfSBvdXQgYSBnaXZlbiBvbmUgKip0b1Jlc29sdmVGcm9tKiogdXNpbmcgdGhlIHNwZWNpZmllZCAqKnBhdGgqKi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b1Jlc29sdmVGcm9tIFRoZSB7QGxpbmsgb2JqZWN0IH0gc3RhcnRpbmcgdG8gcmVzb2x2ZSBmcm9tLlxuICAgICAqIEBwYXJhbSBwYXRoXHRcdFx0VGhlIGRvdHRlZCBwYXRoLXtAbGluayBzdHJpbmcgfS5cbiAgICAgKiBcdFx0XHRcdFx0XHRUaGlzIHN0cmluZyB1c2VzIC4sIFsuLi5dLCBhbmQgKCkgdG8gcmVwcmVzZW50IGFjY2Vzc2luZyBuZXN0ZWQgcHJvcGVydGllcyxcbiAgICAgKiBcdFx0XHRcdFx0XHRhcnJheSBlbGVtZW50cy9vYmplY3Qga2V5cywgYW5kIGNhbGxpbmcgbWV0aG9kcywgcmVzcGVjdGl2ZWx5LCBtaW1pY2tpbmcgSmF2YVNjcmlwdCBzeW50YXggdG8gbmF2aWdhdGVcbiAgICAgKiBcdFx0XHRcdFx0XHRhbiBvYmplY3QncyBzdHJ1Y3R1cmUuIENvZGUsIGUuZy4gc29tZXRoaW5nIGxpa2UgYS5iKCAxIGFzIG51bWJlciApLmMsIHdpbGwgbm90IGJlIGV4ZWN1dGVkIGFuZFxuICAgICAqIFx0XHRcdFx0XHRcdHRodXMgbWFrZSB0aGUgcmV0cmlldmFsIGZhaWwuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGUgcmVxdWVzdGVkIHtAbGluayBvYmplY3QgfSwgTlVMTCBvciBVTkRFRklORUQuICovXG4gICAgc3RhdGljIHJlc29sdmUodG9SZXNvbHZlRnJvbSwgcGF0aCkge1xuICAgICAgICBpZiAoIXRvUmVzb2x2ZUZyb20gfHwgdHlwZW9mIHBhdGggIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU2VjdXJpdHk6IGJsb2NrIHByb3RvdHlwZSBwb2xsdXRpb24gcGF0aHNcbiAgICAgICAgY29uc3QgZGFuZ2Vyb3VzVG9rZW5zID0gW1wiX19wcm90b19fXCIsIFwiY29uc3RydWN0b3JcIiwgXCJwcm90b3R5cGVcIl07XG4gICAgICAgIGNvbnN0IGNhY2hlZFBhcnRzID0gREJDLnBhdGhUb2tlbkNhY2hlLmdldChwYXRoKTtcbiAgICAgICAgY29uc3QgcGFydHMgPSBjYWNoZWRQYXJ0cyAhPT0gbnVsbCAmJiBjYWNoZWRQYXJ0cyAhPT0gdm9pZCAwID8gY2FjaGVkUGFydHMgOiBwYXRoLnJlcGxhY2UoL1xcWyhbJ1wiXT8pKC4qPylcXDFcXF0vZywgXCIuJDJcIikuc3BsaXQoXCIuXCIpO1xuICAgICAgICBpZiAoIWNhY2hlZFBhcnRzKSB7XG4gICAgICAgICAgICAvLyBWYWxpZGF0ZSB0b2tlbnMgYmVmb3JlIGNhY2hpbmdcbiAgICAgICAgICAgIGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRva2VuTmFtZSA9IHBhcnQucmVwbGFjZSgvXFwoLipcXCkkLywgXCJcIik7XG4gICAgICAgICAgICAgICAgaWYgKGRhbmdlcm91c1Rva2Vucy5pbmRleE9mKHRva2VuTmFtZSkgPj0gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFtYREJDXSBQYXRoIFwiJHtwYXRofVwiIGNvbnRhaW5zIGZvcmJpZGRlbiB0b2tlbiBcIiR7dG9rZW5OYW1lfVwiLmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIERCQy5ldmljdElmTmVlZGVkKERCQy5wYXRoVG9rZW5DYWNoZSk7XG4gICAgICAgICAgICBEQkMucGF0aFRva2VuQ2FjaGUuc2V0KHBhdGgsIHBhcnRzKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE11c3QgdHJhdmVyc2UgYXJiaXRyYXJ5IG9iamVjdCBncmFwaHNcbiAgICAgICAgbGV0IGN1cnJlbnQgPSB0b1Jlc29sdmVGcm9tO1xuICAgICAgICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50ID09PSBudWxsIHx8IHR5cGVvZiBjdXJyZW50ID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG1ldGhvZE1hdGNoID0gcGFydC5tYXRjaCgvKFxcdyspXFwoKC4qKVxcKS8pO1xuICAgICAgICAgICAgaWYgKG1ldGhvZE1hdGNoKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWV0aG9kTmFtZSA9IG1ldGhvZE1hdGNoWzFdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFyZ3NTdHIgPSBtZXRob2RNYXRjaFsyXTtcbiAgICAgICAgICAgICAgICBjb25zdCBhcmdzID0gYXJnc1N0ci5zcGxpdChcIixcIikubWFwKChhcmcpID0+IGFyZy50cmltKCkpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY3VycmVudFttZXRob2ROYW1lXSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnQgPSBjdXJyZW50W21ldGhvZE5hbWVdLmFwcGx5KGN1cnJlbnQsIGFyZ3MpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICAgICAgICB0eXBlb2YgSFRNTEVsZW1lbnQgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ICYmXG4gICAgICAgICAgICAgICAgICAgIHBhcnQuc3RhcnRzV2l0aChcIkBcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudCA9IGN1cnJlbnQuZ2V0QXR0cmlidXRlKHBhcnQuc2xpY2UoMSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgY3VycmVudCA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50ICE9PSBudWxsICYmXG4gICAgICAgICAgICAgICAgICAgIHBhcnQgaW4gY3VycmVudCkge1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gY3VycmVudFtwYXJ0XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICAgICAgICB0eXBlb2YgSFRNTEVsZW1lbnQgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY3VycmVudDtcbiAgICB9XG59XG4vLyAjcmVnaW9uIEludGVybmFsIGNhY2hlcy5cbkRCQy5NQVhfQ0FDSEVfU0laRSA9IDEwMDA7XG5EQkMuZGJjQ2FjaGUgPSBuZXcgTWFwKCk7XG5EQkMucGF0aFRva2VuQ2FjaGUgPSBuZXcgTWFwKCk7XG4vLyAjZW5kcmVnaW9uIEludGVybmFsIGNhY2hlcy5cbi8vICNyZWdpb24gUGFyYW1ldGVyLXZhbHVlIHJlcXVlc3RzLlxuLyoqIFN0b3JlcyBhbGwgcmVxdWVzdCBmb3IgcGFyYW1ldGVyIHZhbHVlcyByZWdpc3RlcmVkIGJ5IHtAbGluayBkZWNQcmVjb25kaXRpb24gfS4gKi9cbkRCQy5wYXJhbVZhbHVlUmVxdWVzdHMgPSBuZXcgTWFwKCk7XG4vLyAjcmVnaW9uIENsYXNzZXNcbi8vICNyZWdpb24gRXJyb3JzXG4vKiogQW4ge0BsaW5rIEVycm9yIH0gdG8gYmUgdGhyb3duIHdoZW5ldmVyIGFuIGluZnJpbmdlbWVudCBpcyBkZXRlY3RlZC4gKi9cbkRCQy5JbmZyaW5nZW1lbnQgPSBjbGFzcyBleHRlbmRzIEVycm9yIHtcbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RzIHRoaXMge0BsaW5rIEVycm9yIH0gYnkgdGFnZ2luZyB0aGUgc3BlY2lmaWVkIG1lc3NhZ2Ute0BsaW5rIHN0cmluZyB9IGFzIGFuIFhEQkMtSW5mcmluZ2VtZW50LlxuICAgICAqXG4gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIHtAbGluayBzdHJpbmcgfSBkZXNjcmliaW5nIHRoZSBpbmZyaW5nZW1lbnQuICovXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSkge1xuICAgICAgICBzdXBlcihgWyBYREJDIEluZnJpbmdlbWVudCAke21lc3NhZ2V9XWApO1xuICAgIH1cbn07XG4vLyAjZW5kcmVnaW9uIEVycm9yc1xuLy8gI2VuZHJlZ2lvbiBDbGFzc2VzXG4vLyAjZW5kcmVnaW9uIGluZnJpbmdlbWVudCBoYW5kbGluZy5cbi8qKlxuICogUmVzb2x2ZXMgdGhlIHNwZWNpZmllZCBkb3R0ZWQge0BsaW5rIHN0cmluZyB9LXBhdGggdG8gYSB7QGxpbmsgREJDIH0uXG4gKlxuICogQHBhcmFtIG9iaiBcdFRoZSB7QGxpbmsgb2JqZWN0IH0gdG8gc3RhcnQgcmVzb2x2aW5nIGZyb20uXG4gKiBAcGFyYW0gcGF0aCBcdFRoZSBkb3R0ZWQge0BsaW5rIHN0cmluZyB9LXBhdGggbGVhZGluZyB0byB0aGUge0BsaW5rIERCQyB9LlxuICpcbiAqIEByZXR1cm5zIFRoZSByZXF1ZXN0ZWQge0BsaW5rIERCQyB9LlxuICovXG4vLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE11c3QgdHJhdmVyc2UgYXJiaXRyYXJ5IG9iamVjdCBncmFwaHNcbkRCQy5yZXNvbHZlREJDUGF0aCA9IChvYmosIHBhdGgpID0+IHBhdGggPT09IG51bGwgfHwgcGF0aCA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGF0aC5zcGxpdChcIi5cIikucmVkdWNlKChhY2N1bXVsYXRvciwgY3VycmVudCkgPT4gYWNjdW11bGF0b3JbY3VycmVudF0sIG9iaik7XG4vLyBSZWdpc3RlciB0aGUgZGVmYXVsdCBpbnN0YW5jZSB3aXRoIHN0YW5kYXJkIHNldHRpbmdzLlxuREJDLnJlZ2lzdGVyKG5ldyBEQkMoKSk7XG4iLCJpbXBvcnQgeyBEQkMgfSBmcm9tIFwiLi4vREJDXCI7XG4vKipcbiAqIEEge0BsaW5rIERCQyB9IGRlZmluaW5nIHRoYXQgYWxsIGVsZW1lbnRzIG9mIGFuIHtAbGluayBvYmplY3QgfXMgaGF2ZSB0byBmdWxmaWxsXG4gKiBhIGdpdmVuIHtAbGluayBvYmplY3QgfSdzIGNoZWNrLW1ldGhvZCAoKiooIHRvQ2hlY2sgOiBhbnkgKSA9PiBib29sZWFuIHwgc3RyaW5nKiopLlxuICpcbiAqIEByZW1hcmtzXG4gKiBNYWludGFpbmVyOiBDYWxsYXJpLCBTYWx2YXRvcmUgKFhEQkNAV2FYQ29kZS5uZXQpICovXG5leHBvcnQgY2xhc3MgQUUgZXh0ZW5kcyBEQkMge1xuICAgIC8vICNyZWdpb24gQ29uZGl0aW9uIGNoZWNraW5nLlxuICAgIC8qKlxuICAgICAqIENoZWNrcyBlYWNoIGVsZW1lbnQgb2YgdGhlICoqdmFsdWUqKi17QGxpbmsgQXJyYXkgPCBhbnkgPn0gYWdhaW5zdCB0aGUgZ2l2ZW4gKipjb25kaXRpb24qKiwgaWYgaXQgaXMgb25lLiBJZiBpdCBpcyBub3RcbiAgICAgKiB0aGUgKip2YWx1ZSoqIGl0c2VsZiB3aWxsIGJlIGNoZWNrZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY29uZGl0aW9uXHRUaGUgeyBjaGVjazogKHRvQ2hlY2s6IGFueSkgPT4gYm9vbGVhbiB8IHN0cmluZyB9IHRvIGNoZWNrIHRoZSAqKnZhbHVlKiogYWdhaW5zdC5cbiAgICAgKiBAcGFyYW0gdmFsdWVcdFx0RWl0aGVyICoqdmFsdWUqKi17QGxpbmsgQXJyYXkgPCBhbnkgPn0sIHdoaWNoJ3MgZWxlbWVudHMgd2lsbCBiZSBjaGVja2VkLCBvciB0aGUgdmFsdWUgdG8gYmVcbiAgICAgKiBcdFx0XHRcdFx0Y2hlY2tlZCBpdHNlbGYuXG4gICAgICogQHBhcmFtIGluZGV4XHRcdElmIHNwZWNpZmllZCB3aXRoICoqaWR4RW5kKiogYmVpbmcgdW5kZWZpbmVkLCB0aGlzIHtAbGluayBOdW1iZXIgfSB3aWxsIGJlIHNlZW4gYXMgdGhlIGluZGV4IG9mXG4gICAgICogXHRcdFx0XHRcdHRoZSB2YWx1ZS17QGxpbmsgQXJyYXkgfSdzIGVsZW1lbnQgdG8gY2hlY2suIElmIHZhbHVlIGlzbid0IGFuIHtAbGluayBBcnJheSB9IHRoaXMgcGFyYW1ldGVyXG4gICAgICogXHRcdFx0XHRcdHdpbGwgbm90IGhhdmUgYW55IGVmZmVjdC5cbiAgICAgKiBcdFx0XHRcdFx0V2l0aCAqKmlkeEVuZCoqIG5vdCB1bmRlZmluZWQgdGhpcyBwYXJhbWV0ZXIgaW5kaWNhdGVzIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNwYW4gb2YgZWxlbWVudHMgdG9cbiAgICAgKiBcdFx0XHRcdFx0Y2hlY2sgd2l0aGluIHRoZSB2YWx1ZS17QGxpbmsgQXJyYXkgfS5cbiAgICAgKiBAcGFyYW0gaWR4RW5kXHRJbmRpY2F0ZXMgdGhlIGxhc3QgZWxlbWVudCdzIGluZGV4IChpbmNsdWRpbmcpIG9mIHRoZSBzcGFuIG9mIHZhbHVlLXtAbGluayBBcnJheSB9IGVsZW1lbnRzIHRvIGNoZWNrLlxuICAgICAqIFx0XHRcdFx0XHRTZXR0aW5nIHRoaXMgcGFyYW1ldGVyIHRvIC0xIHNwZWNpZmllcyB0aGF0IGFsbCB2YWx1ZS17QGxpbmsgQXJyYXkgfSdzIGVsZW1lbnRzIGJlZ2lubmluZyBmcm9tIHRoZVxuICAgICAqIFx0XHRcdFx0XHRzcGVjaWZpZWQgKippbmRleCoqIHNoYWxsIGJlIGNoZWNrZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBcyBzb29uIGFzIHRoZSAqKmNvbmRpdGlvbioqIHJldHVybnMgYSB7QGxpbmsgc3RyaW5nIH0sIGluc3RlYWQgb2YgVFJVRSwgdGhlIHJldHVybmVkIHN0cmluZy4gVFJVRSBpZiB0aGVcbiAgICAgKiBcdFx0XHQqKmNvbmRpdGlvbioqIG5ldmVyIHJldHVybnMgYSB7QGxpbmsgc3RyaW5nfS4gKi9cbiAgICBzdGF0aWMgY2hlY2tBbGdvcml0aG0oY29uZGl0aW9uLCB2YWx1ZSwgaW5kZXgsIGlkeEVuZCkge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIGlmIChpbmRleCAhPT0gdW5kZWZpbmVkICYmIGlkeEVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEgJiYgaW5kZXggPCB2YWx1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gY29uZGl0aW9uLmNoZWNrKHZhbHVlW2luZGV4XSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzdWx0ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYFZpb2xhdGluZy1BcnJheWVsZW1lbnQgYXQgaW5kZXggXCIke2luZGV4fVwiIHdpdGggdmFsdWUgXCIke3ZhbHVlW2luZGV4XX1cIi4gJHtyZXN1bHR9YDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gSW4gb3JkZXIgZm9yIG9wdGlvbmFsIHBhcmFtZXRlciB0byBub3QgY2F1c2UgYW4gZXJyb3IgaWYgdGhleSBhcmUgb21pdHRlZC5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGVuZGluZyA9IGlkeEVuZCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgPyBpZHhFbmQgIT09IC0xXG4gICAgICAgICAgICAgICAgICAgID8gaWR4RW5kICsgMVxuICAgICAgICAgICAgICAgICAgICA6IHZhbHVlLmxlbmd0aFxuICAgICAgICAgICAgICAgIDogdmFsdWUubGVuZ3RoO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IGluZGV4ID8gaW5kZXggOiAwOyBpIDwgZW5kaW5nOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBjb25kaXRpb24uY2hlY2sodmFsdWVbaV0pO1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBWaW9sYXRpbmctQXJyYXllbGVtZW50IGF0IGluZGV4ICR7aX0uICR7cmVzdWx0fWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGNvbmRpdGlvbi5jaGVjayh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgcGFyYW1ldGVyLWRlY29yYXRvciBmYWN0b3J5IHVzaW5nIHRoZSB7QGxpbmsgQUUuY2hlY2tBbGdvcml0aG0gfSB3aXRoIGVpdGhlciBtdWx0aXBsZSBvciBhIHNpbmdsZSBvbmVcbiAgICAgKiBvZiB0aGUgKipyZWFsQ29uZGl0aW9ucyoqIHRvIGNoZWNrIHRoZSB0YWdnZWQgcGFyYW1ldGVyLXZhbHVlIGFnYWluc3Qgd2l0aC5cbiAgICAgKiBXaGVuIHNwZWNpZnlpbmcgYW4gKippbmRleCoqIGFuZCB0aGUgdGFnZ2VkIHBhcmFtZXRlcidzICoqdmFsdWUqKiBpcyBhbiB7QGxpbmsgQXJyYXkgfSwgdGhlICoqcmVhbENvbmRpdGlvbnMqKiBhcHBseSB0byB0aGVcbiAgICAgKiBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgKippbmRleCoqLlxuICAgICAqIElmIHRoZSB7QGxpbmsgQXJyYXkgfSBpcyB0b28gc2hvcnQgdGhlIGN1cnJlbnRseSBwcm9jZXNzZWQgeyBjaGVjazogKHRvQ2hlY2s6IGFueSkgPT4gYm9vbGVhbiB8IHN0cmluZyB9IG9mXG4gICAgICogKipyZWFsQ29uZGl0aW9ucyoqIHdpbGwgYmUgdmVyaWZpZWQgdG8gVFJVRSBhdXRvbWF0aWNhbGx5LCBjb25zaWRlcmluZyBvcHRpb25hbCBwYXJhbWV0ZXJzLlxuICAgICAqIElmIGFuICoqaW5kZXgqKiBpcyBzcGVjaWZpZWQgYnV0IHRoZSB0YWdnZWQgcGFyYW1ldGVyJ3MgdmFsdWUgaXNuJ3QgYW4gYXJyYXksIHRoZSAqKmluZGV4KiogaXMgdHJlYXRlZCBhcyBiZWluZyB1bmRlZmluZWQuXG4gICAgICogSWYgKippbmRleCoqIGlzIHVuZGVmaW5lZCBhbmQgdGhlIHRhZ2dlZCBwYXJhbWV0ZXIncyB2YWx1ZSBpcyBhbiB7QGxpbmsgQXJyYXkgfSBlYWNoIGVsZW1lbnQgb2YgaXQgd2lsbCBiZSBjaGVja2VkXG4gICAgICogYWdhaW5zdCB0aGUgKipyZWFsQ29uZGl0aW9ucyoqLlxuICAgICAqXG4gICAgICogQHBhcmFtIHJlYWxDb25kaXRpb25zXHRFaXRoZXIgb25lIG9yIG1vcmUgeyBjaGVjazogKHRvQ2hlY2s6IGFueSkgPT4gYm9vbGVhbiB8IHN0cmluZyB9IHRvIGNoZWNrIHRoZSB0YWdnZWQgcGFyYW1ldGVyLXZhbHVlXG4gICAgICogXHRcdFx0XHRcdFx0XHRhZ2FpbnN0IHdpdGguXG4gICAgICogQHBhcmFtIGluZGV4XHRcdFx0XHRTZWUgdGhlIHtAbGluayBBRS5jaGVja0FsZ29yaXRobSB9LlxuICAgICAqIEBwYXJhbSBpZHhFbmRcdFx0XHRTZWUgdGhlIHtAbGluayBBRS5jaGVja0FsZ29yaXRobSB9LlxuICAgICAqIEBwYXJhbSBwYXRoXHRcdFx0XHRTZWUge0BsaW5rIERCQy5kZWNQcmVjb25kaXRpb24gfS5cbiAgICAgKiBAcGFyYW0gaGludFx0XHRcdFx0U2VlIHtAbGluayBEQkMuZGVjUHJlY29uZGl0aW9uIH0uXG4gICAgICogQHBhcmFtIGRiY1x0XHRcdFx0U2VlIHtAbGluayBEQkMuZGVjUHJlY29uZGl0aW9uIH0uXG4gICAgICpcbiAgICAgKiBAcmV0dXJuc1x0QSB7QGxpbmsgc3RyaW5nIH0gYXMgc29vbiBhcyBvbmUgeyBjaGVjazogKHRvQ2hlY2s6IGFueSkgPT4gYm9vbGVhbiB8IHN0cmluZyB9IG9mICoqcmVhbENvbmRpdGlvbnMqKiByZXR1cm5zIG9uZS5cbiAgICAgKiBcdFx0XHRPdGhlcndpc2UgVFJVRS4gKi9cbiAgICBzdGF0aWMgUFJFKHJlYWxDb25kaXRpb25zLCBpbmRleCA9IHVuZGVmaW5lZCwgaWR4RW5kID0gdW5kZWZpbmVkLCBwYXRoID0gdW5kZWZpbmVkLCBoaW50ID0gdW5kZWZpbmVkLCBkYmMgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIERCQy5kZWNQcmVjb25kaXRpb24oKFxuICAgICAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE11c3QgbWF0Y2ggREJDLmRlY1ByZWNvbmRpdGlvbiBzaWduYXR1cmVcbiAgICAgICAgdmFsdWUsIHRhcmdldCwgbWV0aG9kTmFtZSwgcGFyYW1ldGVySW5kZXgpID0+IHtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlYWxDb25kaXRpb25zKSkge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgY3VycmVudENvbmRpdGlvbiBvZiByZWFsQ29uZGl0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBBRS5jaGVja0FsZ29yaXRobShjdXJyZW50Q29uZGl0aW9uLCB2YWx1ZSwgaW5kZXgsIGlkeEVuZCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzdWx0ICE9PSBcImJvb2xlYW5cIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEFFLmNoZWNrQWxnb3JpdGhtKHJlYWxDb25kaXRpb25zLCB2YWx1ZSwgaW5kZXgsIGlkeEVuZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSwgZGJjLCBwYXRoLCBoaW50KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBtZXRob2QtZGVjb3JhdG9yIGZhY3RvcnkgdXNpbmcgdGhlIHtAbGluayBBRS5jaGVja0FsZ29yaXRobSB9IHdpdGggZWl0aGVyIG11bHRpcGxlIG9yIGEgc2luZ2xlIG9uZVxuICAgICAqIG9mIHRoZSAqKnJlYWxDb25kaXRpb25zKiogdG8gY2hlY2sgdGhlIHRhZ2dlZCBtZXRob2QncyByZXR1cm4tdmFsdWUgYWdhaW5zdCB3aXRoLlxuICAgICAqXG4gICAgICogQHBhcmFtIHJlYWxDb25kaXRpb25zXHRFaXRoZXIgb25lIG9yIG1vcmUgeyBjaGVjazogKHRvQ2hlY2s6IGFueSkgPT4gYm9vbGVhbiB8IHN0cmluZyB9IHRvIGNoZWNrIHRoZSB0YWdnZWQgcGFyYW1ldGVyLXZhbHVlXG4gICAgICogXHRcdFx0XHRcdFx0XHRhZ2FpbnN0IHdpdGguXG4gICAgICogQHBhcmFtIGluZGV4XHRcdFx0XHRTZWUgdGhlIHtAbGluayBBRS5jaGVja0FsZ29yaXRobSB9LlxuICAgICAqIEBwYXJhbSBpZHhFbmRcdFx0XHRTZWUgdGhlIHtAbGluayBBRS5jaGVja0FsZ29yaXRobSB9LlxuICAgICAqIEBwYXJhbSBwYXRoXHRcdFx0XHRTZWUge0BsaW5rIERCQy5kZWNQcmVjb25kaXRpb24gfS5cbiAgICAgKiBAcGFyYW0gaGludFx0XHRcdFx0U2VlIHtAbGluayBEQkMuZGVjUHJlY29uZGl0aW9uIH0uXG4gICAgICogQHBhcmFtIGRiY1x0XHRcdFx0U2VlIHtAbGluayBEQkMuZGVjUHJlY29uZGl0aW9uIH0uXG4gICAgICpcbiAgICAgKiBAcmV0dXJuc1x0QSB7QGxpbmsgc3RyaW5nIH0gYXMgc29vbiBhcyBvbmUgeyBjaGVjazogKHRvQ2hlY2s6IGFueSkgPT4gYm9vbGVhbiB8IHN0cmluZyB9IG9mICoqcmVhbENvbmRpdGlvbnMqKiByZXR1cm4gb25lLlxuICAgICAqIFx0XHRcdE90aGVyd2lzZSBUUlVFLiAqL1xuICAgIHN0YXRpYyBQT1NUKHJlYWxDb25kaXRpb25zLCBpbmRleCA9IHVuZGVmaW5lZCwgaWR4RW5kID0gdW5kZWZpbmVkLCBwYXRoID0gdW5kZWZpbmVkLCBoaW50ID0gdW5kZWZpbmVkLCBkYmMgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIERCQy5kZWNQb3N0Y29uZGl0aW9uKCh2YWx1ZSwgdGFyZ2V0LCBwcm9wZXJ0eUtleSkgPT4ge1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmVhbENvbmRpdGlvbnMpKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBjdXJyZW50Q29uZGl0aW9uIG9mIHJlYWxDb25kaXRpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IEFFLmNoZWNrQWxnb3JpdGhtKGN1cnJlbnRDb25kaXRpb24sIHZhbHVlLCBpbmRleCwgaWR4RW5kKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQgIT09IFwiYm9vbGVhblwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gQUUuY2hlY2tBbGdvcml0aG0oXG4gICAgICAgICAgICAgICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiA8ZXhwbGFuYXRpb24+XG4gICAgICAgICAgICAgICAgcmVhbENvbmRpdGlvbnMsIHZhbHVlLCBpbmRleCwgaWR4RW5kKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9LCBkYmMsIHBhdGgsIGhpbnQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIGZpZWxkLWRlY29yYXRvciBmYWN0b3J5IHVzaW5nIHRoZSB7QGxpbmsgQUUuY2hlY2tBbGdvcml0aG0gfSB3aXRoIGVpdGhlciBtdWx0aXBsZSBvciBhIHNpbmdsZSBvbmVcbiAgICAgKiBvZiB0aGUgKipyZWFsQ29uZGl0aW9ucyoqIHRvIGNoZWNrIHRoZSB0YWdnZWQgZmllbGQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcmVhbENvbmRpdGlvbnNcdEVpdGhlciBvbmUgb3IgbW9yZSB7IGNoZWNrOiAodG9DaGVjazogYW55KSA9PiBib29sZWFuIHwgc3RyaW5nIH0gdG8gY2hlY2sgdGhlIHRhZ2dlZCBwYXJhbWV0ZXItdmFsdWVcbiAgICAgKiBcdFx0XHRcdFx0XHRcdGFnYWluc3Qgd2l0aC5cbiAgICAgKiBAcGFyYW0gaW5kZXhcdFx0XHRcdFNlZSB0aGUge0BsaW5rIEFFLmNoZWNrQWxnb3JpdGhtIH0uXG4gICAgICogQHBhcmFtIGlkeEVuZFx0XHRcdFNlZSB0aGUge0BsaW5rIEFFLmNoZWNrQWxnb3JpdGhtIH0uXG4gICAgICogQHBhcmFtIHBhdGhcdFx0XHRcdFNlZSB7QGxpbmsgREJDLmRlY0ludmFyaWFudCB9LlxuICAgICAqIEBwYXJhbSBoaW50XHRcdFx0XHRTZWUge0BsaW5rIERCQy5kZWNJbnZhcmlhbnQgfS5cbiAgICAgKiBAcGFyYW0gZGJjXHRcdFx0XHRTZWUge0BsaW5rIERCQy5kZWNJbnZhcmlhbnQgfS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zXHRTZWUge0BsaW5rIERCQy5kZWNJbnZhcmlhbnQgfS4gKi9cbiAgICBzdGF0aWMgSU5WQVJJQU5UKHJlYWxDb25kaXRpb25zLCBpbmRleCA9IHVuZGVmaW5lZCwgaWR4RW5kID0gdW5kZWZpbmVkLCBwYXRoID0gdW5kZWZpbmVkLCBoaW50ID0gdW5kZWZpbmVkLCBkYmMgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIERCQy5jcmVhdGVJTlZBUklBTlQoQUUsIFtyZWFsQ29uZGl0aW9ucywgaW5kZXgsIGlkeEVuZF0sIGRiYywgcGF0aCwgaGludCk7XG4gICAgfVxuICAgIC8vICNlbmRyZWdpb24gQ29uZGl0aW9uIGNoZWNraW5nLlxuICAgIC8vICNyZWdpb24gUmVmZXJlbmNlZCBDb25kaXRpb24gY2hlY2tpbmcuXG4gICAgLy9cbiAgICAvLyBGb3IgdXNhZ2UgaW4gZHluYW1pYyBzY2VuYXJpb3MgKGxpa2UgZ2xvYmFsIGZ1bmN0aW9ucykuXG4gICAgLy9cbiAgICAvKipcbiAgICAgKiBJbnZva2VzIHRoZSB7QGxpbmsgQUUuY2hlY2tBbGdvcml0aG0gfSB3aXRoIGFsbCB7QGxpbmsgQUUuY29uZGl0aW9ucyB9IGFuZCB0aGUge0BsaW5rIG9iamVjdCB9IHtAbGluayB0b0NoZWNrIH0sXG4gICAgICoge0BsaW5rIEFFLmluZGV4IH0gJiB7QGxpbmsgQUUuaWR4RW5kIH0uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9DaGVjayBTZWUge0BsaW5rIEFFLmNoZWNrQWxnb3JpdGhtIH0uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBTZWUge0BsaW5rIEVRLmNoZWNrQWxnb3JpdGhtfS4gKi9cbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE11c3QgbWF0Y2ggREJDIGZhY3Rvcnkgc2lnbmF0dXJlXG4gICAgY2hlY2sodG9DaGVjaykge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLmNvbmRpdGlvbnMpKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGN1cnJlbnRDb25kaXRpb24gb2YgdGhpcy5jb25kaXRpb25zKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gQUUuY2hlY2tBbGdvcml0aG0oY3VycmVudENvbmRpdGlvbiwgdG9DaGVjaywgdGhpcy5pbmRleCwgdGhpcy5pZHhFbmQpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzdWx0ICE9PSBcImJvb2xlYW5cIilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBBRS5jaGVja0FsZ29yaXRobShcbiAgICAgICAgICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogPGV4cGxhbmF0aW9uPlxuICAgICAgICAgICAgdGhpcy5jb25kaXRpb25zLCB0b0NoZWNrLCB0aGlzLmluZGV4LCB0aGlzLmlkeEVuZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgdGhpcyB7QGxpbmsgQUUgfSBieSBzZXR0aW5nIHRoZSBwcm90ZWN0ZWQgcHJvcGVydHkge0BsaW5rIEFFLmNvbmRpdGlvbnMgfSwge0BsaW5rIEFFLmluZGV4IH0gYW5kIHtAbGluayBBRS5pZHhFbmQgfSB1c2VkIGJ5IHtAbGluayBBRS5jaGVjayB9LlxuICAgICAqXG4gICAgICogQHBhcmFtIGVxdWl2YWxlbnQgU2VlIHtAbGluayBFUS5jaGVjayB9LiAqL1xuICAgIGNvbnN0cnVjdG9yKGNvbmRpdGlvbnMsIGluZGV4ID0gdW5kZWZpbmVkLCBpZHhFbmQgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5jb25kaXRpb25zID0gY29uZGl0aW9ucztcbiAgICAgICAgdGhpcy5pbmRleCA9IGluZGV4O1xuICAgICAgICB0aGlzLmlkeEVuZCA9IGlkeEVuZDtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBEQkMgfSBmcm9tIFwiLi4vREJDXCI7XG4vKipcbiAqIEEge0BsaW5rIERCQyB9IGRlZmluaW5nIGEgY29tcGFyaXNvbiBiZXR3ZWVuIHR3byB7QGxpbmsgb2JqZWN0IH1zLlxuICpcbiAqIEByZW1hcmtzXG4gKiBNYWludGFpbmVyOiBDYWxsYXJpLCBTYWx2YXRvcmUgKFhEQkNAV2FYQ29kZS5uZXQpICovXG5leHBvcnQgY2xhc3MgQ09NUEFSSVNPTiBleHRlbmRzIERCQyB7XG4gICAgLy8gI3JlZ2lvbiBDb25kaXRpb24gY2hlY2tpbmcuXG4gICAgLyoqXG4gICAgICogRG9lcyBhIGNvbXBhcmlzb24gYmV0d2VlbiB0aGUge0BsaW5rIG9iamVjdCB9ICoqdG9DaGVjayoqIGFuZCB0aGUgKiplcXVpdmFsZW50KiouXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9DaGVja1x0XHRUaGUgdmFsdWUgdGhhdCBoYXMgdG8gYmUgZXF1YWwgdG8gaXQncyBwb3NzaWJsZSAqKmVxdWl2YWxlbnQqKiBmb3IgdGhpcyB7QGxpbmsgREJDIH0gdG8gYmUgZnVsZmlsbGVkLlxuICAgICAqIEBwYXJhbSBlcXVpdmFsZW50XHRUaGUge0BsaW5rIG9iamVjdCB9IHRoZSBvbmUgKip0b0NoZWNrKiogaGFzIHRvIGJlIGVxdWFsIHRvIGluIG9yZGVyIGZvciB0aGlzIHtAbGluayBEQkMgfSB0byBiZVxuICAgICAqIFx0XHRcdFx0XHRcdGZ1bGZpbGxlZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRSVUUgaWYgdGhlIHZhbHVlICoqdG9DaGVjayoqIGFuZCB0aGUgKiplcXVpdmFsZW50KiogYXJlIGVxdWFsIHRvIGVhY2ggb3RoZXIsIG90aGVyd2lzZSBGQUxTRS4gKi9cbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE5lY2Vzc2FyeSBmb3IgZHluYW1pYyBjb21wYXJpc29uXG4gICAgc3RhdGljIGNoZWNrQWxnb3JpdGhtKHRvQ2hlY2ssIGVxdWl2YWxlbnQsIGVxdWFsaXR5UGVybWl0dGVkLCBpbnZlcnQpIHtcbiAgICAgICAgaWYgKGVxdWFsaXR5UGVybWl0dGVkICYmICFpbnZlcnQgJiYgdG9DaGVjayA8IGVxdWl2YWxlbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBgVmFsdWUgaGFzIHRvIGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBcIiR7ZXF1aXZhbGVudH1cImA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVxdWFsaXR5UGVybWl0dGVkICYmIGludmVydCAmJiB0b0NoZWNrID4gZXF1aXZhbGVudCkge1xuICAgICAgICAgICAgcmV0dXJuIGBWYWx1ZSBoYXMgdG8gYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIFwiJHtlcXVpdmFsZW50fVwiYDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWVxdWFsaXR5UGVybWl0dGVkICYmICFpbnZlcnQgJiYgdG9DaGVjayA8PSBlcXVpdmFsZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gYFZhbHVlIGhhcyB0byBiZSBncmVhdGVyIHRoYW4gXCIke2VxdWl2YWxlbnR9XCJgO1xuICAgICAgICB9XG4gICAgICAgIGlmICghZXF1YWxpdHlQZXJtaXR0ZWQgJiYgaW52ZXJ0ICYmIHRvQ2hlY2sgPj0gZXF1aXZhbGVudCkge1xuICAgICAgICAgICAgcmV0dXJuIGBWYWx1ZSBoYXMgdG8gYmUgbGVzcyB0aGFuIFwiJHtlcXVpdmFsZW50fVwiYDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBwYXJhbWV0ZXItZGVjb3JhdG9yIGZhY3RvcnkgdXNpbmcgdGhlIHtAbGluayBDT01QQVJJU09OLmNoZWNrQWxnb3JpdGhtIH0gdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyB7QGxpbmsgREJDIH0gaXMgZnVsZmlsbGVkXG4gICAgICogYnkgdGhlIHRhZ2dlZCBwYXJhbWV0ZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXF1aXZhbGVudFx0ICAgIFNlZSB7QGxpbmsgQ09NUEFSSVNPTi5jaGVja0FsZ29yaXRobSB9LlxuICAgICAqIEBwYXJhbSBlcXVhbGl0eVBlcm1pdHRlZCBTZWUge0BsaW5rIENPTVBBUklTT04uY2hlY2tBbGdvcml0aG0gfS5cbiAgICAgKiBAcGFyYW0gcGF0aFx0XHRcdCAgICBTZWUge0BsaW5rIERCQy5kZWNQcmVjb25kaXRpb24gfS5cbiAgICAgKiBAcGFyYW0gaGludFx0XHRcdFx0U2VlIHtAbGluayBEQkMuZGVjUHJlY29uZGl0aW9uIH0uXG4gICAgICogQHBhcmFtIGRiY1x0XHRcdCAgICBTZWUge0BsaW5rIERCQy5kZWNQcmVjb25kaXRpb24gfS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFNlZSB7QGxpbmsgREJDLmRlY1ByZWNvbmRpdGlvbiB9LiAqL1xuICAgIHN0YXRpYyBQUkUoXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBDb21wYXJpc29uIHRhcmdldCBjYW4gYmUgYW55IG51bWVyaWMgdmFsdWVcbiAgICBlcXVpdmFsZW50LCBlcXVhbGl0eVBlcm1pdHRlZCA9IGZhbHNlLCBpbnZlcnQgPSBmYWxzZSwgcGF0aCA9IHVuZGVmaW5lZCwgaGludCA9IHVuZGVmaW5lZCwgZGJjID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBEQkMuY3JlYXRlUFJFKENPTVBBUklTT04uY2hlY2tBbGdvcml0aG0sIFtlcXVpdmFsZW50LCBlcXVhbGl0eVBlcm1pdHRlZCwgaW52ZXJ0XSwgZGJjLCBwYXRoLCBoaW50KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBtZXRob2QtZGVjb3JhdG9yIGZhY3RvcnkgdXNpbmcgdGhlIHtAbGluayBDT01QQVJJU09OLmNoZWNrQWxnb3JpdGhtIH0gdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyB7QGxpbmsgREJDIH0gaXMgZnVsZmlsbGVkXG4gICAgICogYnkgdGhlIHRhZ2dlZCBtZXRob2QncyByZXR1cm52YWx1ZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBlcXVpdmFsZW50XHQgICAgU2VlIHtAbGluayBDT01QQVJJU09OLmNoZWNrQWxnb3JpdGhtIH0uXG4gICAgICogQHBhcmFtIGVxdWFsaXR5UGVybWl0dGVkIFNlZSB7QGxpbmsgQ09NUEFSSVNPTi5jaGVja0FsZ29yaXRobSB9LlxuICAgICAqIEBwYXJhbSBwYXRoXHRcdFx0ICAgIFNlZSB7QGxpbmsgREJDLlBvc3Rjb25kaXRpb24gfS5cbiAgICAgKiBAcGFyYW0gaGludFx0XHRcdFx0U2VlIHtAbGluayBEQkMuZGVjUG9zdGNvbmRpdGlvbiB9LlxuICAgICAqIEBwYXJhbSBkYmNcdFx0XHQgICAgU2VlIHtAbGluayBEQkMuZGVjUG9zdGNvbmRpdGlvbiB9LlxuICAgICAqXG4gICAgICogQHJldHVybnMgU2VlIHtAbGluayBEQkMuZGVjUG9zdGNvbmRpdGlvbiB9LiAqL1xuICAgIHN0YXRpYyBQT1NUKFxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogQ29tcGFyaXNvbiB0YXJnZXQgY2FuIGJlIGFueSBudW1lcmljIHZhbHVlXG4gICAgZXF1aXZhbGVudCwgZXF1YWxpdHlQZXJtaXR0ZWQgPSBmYWxzZSwgaW52ZXJ0ID0gZmFsc2UsIHBhdGggPSB1bmRlZmluZWQsIGhpbnQgPSB1bmRlZmluZWQsIGRiYyA9IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gREJDLmNyZWF0ZVBPU1QoQ09NUEFSSVNPTi5jaGVja0FsZ29yaXRobSwgW2VxdWl2YWxlbnQsIGVxdWFsaXR5UGVybWl0dGVkLCBpbnZlcnRdLCBkYmMsIHBhdGgsIGhpbnQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIGZpZWxkLWRlY29yYXRvciBmYWN0b3J5IHVzaW5nIHRoZSB7QGxpbmsgQ09NUEFSSVNPTi5jaGVja0FsZ29yaXRobSB9IHRvIGRldGVybWluZSB3aGV0aGVyIHRoaXMge0BsaW5rIERCQyB9IGlzIGZ1bGZpbGxlZFxuICAgICAqIGJ5IHRoZSB0YWdnZWQgZmllbGQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXF1aXZhbGVudFx0ICAgIFNlZSB7QGxpbmsgQ09NUEFSSVNPTi5jaGVja0FsZ29yaXRobSB9LlxuICAgICAqIEBwYXJhbSBlcXVhbGl0eVBlcm1pdHRlZCBTZWUge0BsaW5rIENPTVBBUklTT04uY2hlY2tBbGdvcml0aG0gfS5cbiAgICAgKiBAcGFyYW0gcGF0aFx0XHRcdCAgICBTZWUge0BsaW5rIERCQy5kZWNJbnZhcmlhbnQgfS5cbiAgICAgKiBAcGFyYW0gaGludFx0XHRcdFx0U2VlIHtAbGluayBEQkMuZGVjSW52YXJpYW50IH0uXG4gICAgICogQHBhcmFtIGRiY1x0XHRcdCAgICBTZWUge0BsaW5rIERCQy5kZWNJbnZhcmlhbnQgfS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFNlZSB7QGxpbmsgREJDLmRlY0ludmFyaWFudCB9LiAqL1xuICAgIHN0YXRpYyBJTlZBUklBTlQoXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBDb21wYXJpc29uIHRhcmdldCBjYW4gYmUgYW55IG51bWVyaWMgdmFsdWVcbiAgICBlcXVpdmFsZW50LCBlcXVhbGl0eVBlcm1pdHRlZCA9IGZhbHNlLCBpbnZlcnQgPSBmYWxzZSwgcGF0aCA9IHVuZGVmaW5lZCwgaGludCA9IHVuZGVmaW5lZCwgZGJjID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBEQkMuY3JlYXRlSU5WQVJJQU5UKENPTVBBUklTT04sIFtlcXVpdmFsZW50LCBlcXVhbGl0eVBlcm1pdHRlZCwgaW52ZXJ0XSwgZGJjLCBwYXRoLCBoaW50KTtcbiAgICB9XG4gICAgLy8gI2VuZHJlZ2lvbiBDb25kaXRpb24gY2hlY2tpbmcuXG4gICAgLy8gI3JlZ2lvbiBSZWZlcmVuY2VkIENvbmRpdGlvbiBjaGVja2luZy5cbiAgICAvLyAjcmVnaW9uIER5bmFtaWMgdXNhZ2UuXG4gICAgLyoqXG4gICAgICogSW52b2tlcyB0aGUge0BsaW5rIENPTVBBUklTT04uY2hlY2tBbGdvcml0aG0gfSBwYXNzaW5nIHRoZSB2YWx1ZSAqKnRvQ2hlY2sqKiwge0BsaW5rIENPTVBBUklTT04uZXF1aXZhbGVudCB9IGFuZCB7QGxpbmsgQ09NUEFSSVNPTi5pbnZlcnQgfS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b0NoZWNrIFNlZSB7QGxpbmsgQ09NUEFSSVNPTi5jaGVja0FsZ29yaXRobSB9LlxuICAgICAqXG4gICAgICogQHJldHVybnMgU2VlIHtAbGluayBDT01QQVJJU09OLmNoZWNrQWxnb3JpdGhtfS4gKi9cbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE5lY2Vzc2FyeSBmb3IgZHluYW1pYyBjb21wYXJpc29uXG4gICAgY2hlY2sodG9DaGVjaykge1xuICAgICAgICByZXR1cm4gQ09NUEFSSVNPTi5jaGVja0FsZ29yaXRobSh0b0NoZWNrLCB0aGlzLmVxdWl2YWxlbnQsIHRoaXMuZXF1YWxpdHlQZXJtaXR0ZWQsIHRoaXMuaW52ZXJ0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyB0aGlzIHtAbGluayBDT01QQVJJU09OIH0gYnkgc2V0dGluZyB0aGUgcHJvdGVjdGVkIHByb3BlcnR5IHtAbGluayBDT01QQVJJU09OLmVxdWl2YWxlbnQgfSwge0BsaW5rIENPTVBBUklTT04uZXF1YWxpdHlQZXJtaXR0ZWQgfSBhbmQge0BsaW5rIENPTVBBUklTT04uaW52ZXJ0IH0gdXNlZCBieSB7QGxpbmsgQ09NUEFSSVNPTi5jaGVjayB9LlxuICAgICAqXG4gICAgICogQHBhcmFtIGVxdWl2YWxlbnQgICAgICAgIFNlZSB7QGxpbmsgQ09NUEFSSVNPTi5jaGVjayB9LlxuICAgICAqIEBwYXJhbSBlcXVhbGl0eVBlcm1pdHRlZCBTZWUge0BsaW5rIENPTVBBUklTT04uY2hlY2sgfS5cbiAgICAgKiBAcGFyYW0gaW52ZXJ0ICAgICAgICAgICAgU2VlIHtAbGluayBDT01QQVJJU09OLmNoZWNrIH0uICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBDb21wYXJpc29uIHRhcmdldCBjYW4gYmUgYW55IG51bWVyaWMgdmFsdWVcbiAgICBlcXVpdmFsZW50LCBlcXVhbGl0eVBlcm1pdHRlZCA9IGZhbHNlLCBpbnZlcnQgPSBmYWxzZSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmVxdWl2YWxlbnQgPSBlcXVpdmFsZW50O1xuICAgICAgICB0aGlzLmVxdWFsaXR5UGVybWl0dGVkID0gZXF1YWxpdHlQZXJtaXR0ZWQ7XG4gICAgICAgIHRoaXMuaW52ZXJ0ID0gaW52ZXJ0O1xuICAgIH1cbn1cbiIsImltcG9ydCB7IENPTVBBUklTT04gfSBmcm9tIFwiLi4vQ09NUEFSSVNPTlwiO1xuLyoqIFNlZSB7QGxpbmsgQ09NUEFSSVNPTiB9LiAqL1xuZXhwb3J0IGNsYXNzIEdSRUFURVIgZXh0ZW5kcyBDT01QQVJJU09OIHtcbiAgICAvKiogU2VlIHtAbGluayBDT01QQVJJU09OLlBSRSB9LiAqL1xuICAgIHN0YXRpYyBQUkUoXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBDb21wYXJpc29uIHRhcmdldCBjYW4gYmUgYW55IG51bWVyaWMgdmFsdWVcbiAgICBlcXVpdmFsZW50LCBlcXVhbGl0eVBlcm1pdHRlZCA9IGZhbHNlLCBpbnZlcnQgPSBmYWxzZSwgcGF0aCA9IHVuZGVmaW5lZCwgaGludCA9IHVuZGVmaW5lZCwgZGJjID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBDT01QQVJJU09OLlBSRShlcXVpdmFsZW50LCBmYWxzZSwgZmFsc2UsIHBhdGgsIGhpbnQsIGRiYyk7XG4gICAgfVxuICAgIC8qKiBTZWUge0BsaW5rIENPTVBBUklTT04uUE9TVCB9LiAqL1xuICAgIHN0YXRpYyBQT1NUKFxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogQ29tcGFyaXNvbiB0YXJnZXQgY2FuIGJlIGFueSBudW1lcmljIHZhbHVlXG4gICAgZXF1aXZhbGVudCwgZXF1YWxpdHlQZXJtaXR0ZWQgPSBmYWxzZSwgaW52ZXJ0ID0gZmFsc2UsIHBhdGggPSB1bmRlZmluZWQsIGhpbnQgPSB1bmRlZmluZWQsIGRiYyA9IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gQ09NUEFSSVNPTi5QT1NUKGVxdWl2YWxlbnQsIGZhbHNlLCBmYWxzZSwgcGF0aCwgaGludCwgZGJjKTtcbiAgICB9XG4gICAgLyoqIFNlZSB7QGxpbmsgQ09NUEFSSVNPTi5JTlZBUklBTlQgfS4gKi9cbiAgICBzdGF0aWMgSU5WQVJJQU5UKFxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogQ29tcGFyaXNvbiB0YXJnZXQgY2FuIGJlIGFueSBudW1lcmljIHZhbHVlXG4gICAgZXF1aXZhbGVudCwgZXF1YWxpdHlQZXJtaXR0ZWQgPSBmYWxzZSwgaW52ZXJ0ID0gZmFsc2UsIHBhdGggPSB1bmRlZmluZWQsIGhpbnQgPSB1bmRlZmluZWQsIGRiYyA9IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gQ09NUEFSSVNPTi5JTlZBUklBTlQoZXF1aXZhbGVudCwgZmFsc2UsIGZhbHNlLCBwYXRoLCBoaW50LCBkYmMpO1xuICAgIH1cbiAgICAvKiogU2VlIHtAbGluayBDT01QQVJJU09OLmNvbnN0cnVjdG9yIH0uICovXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBDb21wYXJpc29uIHRhcmdldCBjYW4gYmUgYW55IG51bWVyaWMgdmFsdWVcbiAgICBjb25zdHJ1Y3RvcihlcXVpdmFsZW50KSB7XG4gICAgICAgIHN1cGVyKGVxdWl2YWxlbnQsIGZhbHNlLCBmYWxzZSk7XG4gICAgICAgIHRoaXMuZXF1aXZhbGVudCA9IGVxdWl2YWxlbnQ7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgQ09NUEFSSVNPTiB9IGZyb20gXCIuLi9DT01QQVJJU09OXCI7XG4vKiogU2VlIHtAbGluayBDT01QQVJJU09OIH0uICovXG5leHBvcnQgY2xhc3MgR1JFQVRFUl9PUl9FUVVBTCBleHRlbmRzIENPTVBBUklTT04ge1xuICAgIC8qKiBTZWUge0BsaW5rIENPTVBBUklTT04uUFJFIH0uICovXG4gICAgc3RhdGljIFBSRShcbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IENvbXBhcmlzb24gdGFyZ2V0IGNhbiBiZSBhbnkgbnVtZXJpYyB2YWx1ZVxuICAgIGVxdWl2YWxlbnQsIGVxdWFsaXR5UGVybWl0dGVkID0gZmFsc2UsIGludmVydCA9IGZhbHNlLCBwYXRoID0gdW5kZWZpbmVkLCBoaW50ID0gdW5kZWZpbmVkLCBkYmMgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIENPTVBBUklTT04uUFJFKGVxdWl2YWxlbnQsIHRydWUsIGZhbHNlLCBwYXRoLCBoaW50LCBkYmMpO1xuICAgIH1cbiAgICAvKiogU2VlIHtAbGluayBDT01QQVJJU09OLlBPU1QgfS4gKi9cbiAgICBzdGF0aWMgUE9TVChcbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IENvbXBhcmlzb24gdGFyZ2V0IGNhbiBiZSBhbnkgbnVtZXJpYyB2YWx1ZVxuICAgIGVxdWl2YWxlbnQsIGVxdWFsaXR5UGVybWl0dGVkID0gZmFsc2UsIGludmVydCA9IGZhbHNlLCBwYXRoID0gdW5kZWZpbmVkLCBoaW50ID0gdW5kZWZpbmVkLCBkYmMgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIENPTVBBUklTT04uUE9TVChlcXVpdmFsZW50LCB0cnVlLCBmYWxzZSwgcGF0aCwgaGludCwgZGJjKTtcbiAgICB9XG4gICAgLyoqIFNlZSB7QGxpbmsgQ09NUEFSSVNPTi5JTlZBUklBTlQgfS4gKi9cbiAgICBzdGF0aWMgSU5WQVJJQU5UKFxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogQ29tcGFyaXNvbiB0YXJnZXQgY2FuIGJlIGFueSBudW1lcmljIHZhbHVlXG4gICAgZXF1aXZhbGVudCwgZXF1YWxpdHlQZXJtaXR0ZWQgPSBmYWxzZSwgaW52ZXJ0ID0gZmFsc2UsIHBhdGggPSB1bmRlZmluZWQsIGhpbnQgPSB1bmRlZmluZWQsIGRiYyA9IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gQ09NUEFSSVNPTi5JTlZBUklBTlQoZXF1aXZhbGVudCwgdHJ1ZSwgZmFsc2UsIHBhdGgsIGhpbnQsIGRiYyk7XG4gICAgfVxuICAgIC8qKiBTZWUge0BsaW5rIENPTVBBUklTT04uY29uc3RydWN0b3IgfS4gKi9cbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IENvbXBhcmlzb24gdGFyZ2V0IGNhbiBiZSBhbnkgbnVtZXJpYyB2YWx1ZVxuICAgIGNvbnN0cnVjdG9yKGVxdWl2YWxlbnQpIHtcbiAgICAgICAgc3VwZXIoZXF1aXZhbGVudCwgdHJ1ZSwgZmFsc2UpO1xuICAgICAgICB0aGlzLmVxdWl2YWxlbnQgPSBlcXVpdmFsZW50O1xuICAgIH1cbn1cbiIsImltcG9ydCB7IENPTVBBUklTT04gfSBmcm9tIFwiLi4vQ09NUEFSSVNPTlwiO1xuLyoqIFNlZSB7QGxpbmsgQ09NUEFSSVNPTiB9LiAqL1xuZXhwb3J0IGNsYXNzIExFU1MgZXh0ZW5kcyBDT01QQVJJU09OIHtcbiAgICAvKiogU2VlIHtAbGluayBDT01QQVJJU09OLlBSRSB9LiAqL1xuICAgIHN0YXRpYyBQUkUoXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBDb21wYXJpc29uIHRhcmdldCBjYW4gYmUgYW55IG51bWVyaWMgdmFsdWVcbiAgICBlcXVpdmFsZW50LCBlcXVhbGl0eVBlcm1pdHRlZCA9IGZhbHNlLCBpbnZlcnQgPSBmYWxzZSwgcGF0aCA9IHVuZGVmaW5lZCwgaGludCA9IHVuZGVmaW5lZCwgZGJjID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBDT01QQVJJU09OLlBSRShlcXVpdmFsZW50LCBmYWxzZSwgdHJ1ZSwgcGF0aCwgaGludCwgZGJjKTtcbiAgICB9XG4gICAgLyoqIFNlZSB7QGxpbmsgQ09NUEFSSVNPTi5QT1NUIH0uICovXG4gICAgc3RhdGljIFBPU1QoXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBDb21wYXJpc29uIHRhcmdldCBjYW4gYmUgYW55IG51bWVyaWMgdmFsdWVcbiAgICBlcXVpdmFsZW50LCBlcXVhbGl0eVBlcm1pdHRlZCA9IGZhbHNlLCBpbnZlcnQgPSBmYWxzZSwgcGF0aCA9IHVuZGVmaW5lZCwgaGludCA9IHVuZGVmaW5lZCwgZGJjID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBDT01QQVJJU09OLlBPU1QoZXF1aXZhbGVudCwgZmFsc2UsIHRydWUsIHBhdGgsIGhpbnQsIGRiYyk7XG4gICAgfVxuICAgIC8qKiBTZWUge0BsaW5rIENPTVBBUklTT04uSU5WQVJJQU5UIH0uICovXG4gICAgc3RhdGljIElOVkFSSUFOVChcbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IENvbXBhcmlzb24gdGFyZ2V0IGNhbiBiZSBhbnkgbnVtZXJpYyB2YWx1ZVxuICAgIGVxdWl2YWxlbnQsIGVxdWFsaXR5UGVybWl0dGVkID0gZmFsc2UsIGludmVydCA9IGZhbHNlLCBwYXRoID0gdW5kZWZpbmVkLCBoaW50ID0gdW5kZWZpbmVkLCBkYmMgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIENPTVBBUklTT04uSU5WQVJJQU5UKGVxdWl2YWxlbnQsIGZhbHNlLCB0cnVlLCBwYXRoLCBoaW50LCBkYmMpO1xuICAgIH1cbiAgICAvKiogU2VlIHtAbGluayBDT01QQVJJU09OLmNvbnN0cnVjdG9yIH0uICovXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBDb21wYXJpc29uIHRhcmdldCBjYW4gYmUgYW55IG51bWVyaWMgdmFsdWVcbiAgICBjb25zdHJ1Y3RvcihlcXVpdmFsZW50KSB7XG4gICAgICAgIHN1cGVyKGVxdWl2YWxlbnQsIGZhbHNlLCB0cnVlKTtcbiAgICAgICAgdGhpcy5lcXVpdmFsZW50ID0gZXF1aXZhbGVudDtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBDT01QQVJJU09OIH0gZnJvbSBcIi4uL0NPTVBBUklTT05cIjtcbi8qKiBTZWUge0BsaW5rIENPTVBBUklTT04gfS4gKi9cbmV4cG9ydCBjbGFzcyBMRVNTX09SX0VRVUFMIGV4dGVuZHMgQ09NUEFSSVNPTiB7XG4gICAgLyoqIFNlZSB7QGxpbmsgQ09NUEFSSVNPTi5QUkUgfS4gKi9cbiAgICBzdGF0aWMgUFJFKFxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogQ29tcGFyaXNvbiB0YXJnZXQgY2FuIGJlIGFueSBudW1lcmljIHZhbHVlXG4gICAgZXF1aXZhbGVudCwgZXF1YWxpdHlQZXJtaXR0ZWQgPSBmYWxzZSwgaW52ZXJ0ID0gZmFsc2UsIHBhdGggPSB1bmRlZmluZWQsIGhpbnQgPSB1bmRlZmluZWQsIGRiYyA9IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gQ09NUEFSSVNPTi5QUkUoZXF1aXZhbGVudCwgdHJ1ZSwgdHJ1ZSwgcGF0aCwgaGludCwgZGJjKTtcbiAgICB9XG4gICAgLyoqIFNlZSB7QGxpbmsgQ09NUEFSSVNPTi5QT1NUIH0uICovXG4gICAgc3RhdGljIFBPU1QoXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBDb21wYXJpc29uIHRhcmdldCBjYW4gYmUgYW55IG51bWVyaWMgdmFsdWVcbiAgICBlcXVpdmFsZW50LCBlcXVhbGl0eVBlcm1pdHRlZCA9IGZhbHNlLCBpbnZlcnQgPSBmYWxzZSwgcGF0aCA9IHVuZGVmaW5lZCwgaGludCA9IHVuZGVmaW5lZCwgZGJjID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBDT01QQVJJU09OLlBPU1QoZXF1aXZhbGVudCwgdHJ1ZSwgdHJ1ZSwgcGF0aCwgaGludCwgZGJjKTtcbiAgICB9XG4gICAgLyoqIFNlZSB7QGxpbmsgQ09NUEFSSVNPTi5JTlZBUklBTlQgfS4gKi9cbiAgICBzdGF0aWMgSU5WQVJJQU5UKFxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogQ29tcGFyaXNvbiB0YXJnZXQgY2FuIGJlIGFueSBudW1lcmljIHZhbHVlXG4gICAgZXF1aXZhbGVudCwgZXF1YWxpdHlQZXJtaXR0ZWQgPSBmYWxzZSwgaW52ZXJ0ID0gZmFsc2UsIHBhdGggPSB1bmRlZmluZWQsIGhpbnQgPSB1bmRlZmluZWQsIGRiYyA9IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gQ09NUEFSSVNPTi5JTlZBUklBTlQoZXF1aXZhbGVudCwgdHJ1ZSwgdHJ1ZSwgcGF0aCwgaGludCwgZGJjKTtcbiAgICB9XG4gICAgLyoqIFNlZSB7QGxpbmsgQ09NUEFSSVNPTi5jb25zdHJ1Y3RvciB9LiAqL1xuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogQ29tcGFyaXNvbiB0YXJnZXQgY2FuIGJlIGFueSBudW1lcmljIHZhbHVlXG4gICAgY29uc3RydWN0b3IoZXF1aXZhbGVudCkge1xuICAgICAgICBzdXBlcihlcXVpdmFsZW50LCB0cnVlLCB0cnVlKTtcbiAgICAgICAgdGhpcy5lcXVpdmFsZW50ID0gZXF1aXZhbGVudDtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBEQkMgfSBmcm9tIFwiLi4vREJDXCI7XG4vKipcbiAqIEEge0BsaW5rIERCQyB9IGRlZmluaW5nIHRoYXQgdHdvIHtAbGluayBvYmplY3QgfXMgZ290dGEgYmUgZXF1YWwuXG4gKlxuICogQHJlbWFya3NcbiAqIE1haW50YWluZXI6IENhbGxhcmksIFNhbHZhdG9yZSAoWERCQ0BXYVhDb2RlLm5ldCkgKi9cbmV4cG9ydCBjbGFzcyBFUSBleHRlbmRzIERCQyB7XG4gICAgLy8gI3JlZ2lvbiBDb25kaXRpb24gY2hlY2tpbmcuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHRoZSB2YWx1ZSAqKnRvQ2hlY2sqKiBpcyBlcXVhbCB0byB0aGUgc3BlY2lmaWVkICoqZXF1aXZhbGVudCoqLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRvQ2hlY2tcdFx0VGhlIHZhbHVlIHRoYXQgaGFzIHRvIGJlIGVxdWFsIHRvIGl0J3MgcG9zc2libGUgKiplcXVpdmFsZW50KiogZm9yIHRoaXMge0BsaW5rIERCQyB9IHRvIGJlIGZ1bGZpbGxlZC5cbiAgICAgKiBAcGFyYW0gZXF1aXZhbGVudFx0VGhlIHtAbGluayBvYmplY3QgfSB0aGUgb25lICoqdG9DaGVjayoqIGhhcyB0byBiZSBlcXVhbCB0byBpbiBvcmRlciBmb3IgdGhpcyB7QGxpbmsgREJDIH0gdG8gYmVcbiAgICAgKiBcdFx0XHRcdFx0XHRmdWxmaWxsZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUUlVFIGlmIHRoZSB2YWx1ZSAqKnRvQ2hlY2sqKiBhbmQgdGhlICoqZXF1aXZhbGVudCoqIGFyZSBlcXVhbCB0byBlYWNoIG90aGVyLCBvdGhlcndpc2UgRkFMU0UuICovXG4gICAgc3RhdGljIGNoZWNrQWxnb3JpdGhtKFxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogPGV4cGxhbmF0aW9uPlxuICAgIHRvQ2hlY2ssIGVxdWl2YWxlbnQsIGludmVydCkge1xuICAgICAgICBpZiAoIWludmVydCAmJiBlcXVpdmFsZW50ICE9PSB0b0NoZWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gYFZhbHVlIGhhcyB0byBiZSBlcXVhbCB0byBcIiR7ZXF1aXZhbGVudH1cImA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGludmVydCAmJiBlcXVpdmFsZW50ID09PSB0b0NoZWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gYFZhbHVlIG11c3Qgbm90IGJlIGVxdWFsIHRvIFwiJHtlcXVpdmFsZW50fVwiYDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBwYXJhbWV0ZXItZGVjb3JhdG9yIGZhY3RvcnkgdXNpbmcgdGhlIHtAbGluayBFUS5jaGVja0FsZ29yaXRobSB9IHRvIGRldGVybWluZSB3aGV0aGVyIHRoaXMge0BsaW5rIERCQyB9IGlzIGZ1bGZpbGxlZFxuICAgICAqIGJ5IHRoZSB0YWdnZWQgcGFyYW1ldGVyLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVxdWl2YWxlbnRcdFNlZSB7QGxpbmsgRVEuY2hlY2tBbGdvcml0aG0gfS5cbiAgICAgKiBAcGFyYW0gcGF0aFx0XHRcdFNlZSB7QGxpbmsgREJDLmRlY1ByZWNvbmRpdGlvbiB9LlxuICAgICAqIEBwYXJhbSBkYmNcdFx0XHRTZWUge0BsaW5rIERCQy5kZWNQcmVjb25kaXRpb24gfS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFNlZSB7QGxpbmsgREJDLmRlY1ByZWNvbmRpdGlvbiB9LiAqL1xuICAgIHN0YXRpYyBQUkUoXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBUbyBjaGVjayBmb3IgVU5ERUZJTkVEIGFuZCBOVUxMLlxuICAgIGVxdWl2YWxlbnQsIGludmVydCA9IGZhbHNlLCBwYXRoID0gdW5kZWZpbmVkLCBoaW50ID0gdW5kZWZpbmVkLCBkYmMgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIERCQy5jcmVhdGVQUkUoRVEuY2hlY2tBbGdvcml0aG0sIFtlcXVpdmFsZW50LCBpbnZlcnRdLCBkYmMsIHBhdGgsIGhpbnQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIG1ldGhvZC1kZWNvcmF0b3IgZmFjdG9yeSB1c2luZyB0aGUge0BsaW5rIEVRLmNoZWNrQWxnb3JpdGhtIH0gdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyB7QGxpbmsgREJDIH0gaXMgZnVsZmlsbGVkXG4gICAgICogYnkgdGhlIHRhZ2dlZCBtZXRob2QncyByZXR1cm52YWx1ZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBlcXVpdmFsZW50XHRTZWUge0BsaW5rIEVRLmNoZWNrQWxnb3JpdGhtIH0uXG4gICAgICogQHBhcmFtIHBhdGhcdFx0XHRTZWUge0BsaW5rIERCQy5Qb3N0Y29uZGl0aW9uIH0uXG4gICAgICogQHBhcmFtIGRiY1x0XHRcdFNlZSB7QGxpbmsgREJDLmRlY1Bvc3Rjb25kaXRpb24gfS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFNlZSB7QGxpbmsgREJDLmRlY1Bvc3Rjb25kaXRpb24gfS4gKi9cbiAgICBzdGF0aWMgUE9TVChcbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IFRvIGNoZWNrIGZvciBVTkRFRklORUQgYW5kIE5VTEwuXG4gICAgZXF1aXZhbGVudCwgaW52ZXJ0ID0gZmFsc2UsIHBhdGggPSB1bmRlZmluZWQsIGhpbnQgPSB1bmRlZmluZWQsIGRiYyA9IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gREJDLmNyZWF0ZVBPU1QoRVEuY2hlY2tBbGdvcml0aG0sIFtlcXVpdmFsZW50LCBpbnZlcnRdLCBkYmMsIHBhdGgsIGhpbnQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIGZpZWxkLWRlY29yYXRvciBmYWN0b3J5IHVzaW5nIHRoZSB7QGxpbmsgRVEuY2hlY2tBbGdvcml0aG0gfSB0byBkZXRlcm1pbmUgd2hldGhlciB0aGlzIHtAbGluayBEQkMgfSBpcyBmdWxmaWxsZWRcbiAgICAgKiBieSB0aGUgdGFnZ2VkIGZpZWxkLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVxdWl2YWxlbnRcdFNlZSB7QGxpbmsgRVEuY2hlY2tBbGdvcml0aG0gfS5cbiAgICAgKiBAcGFyYW0gcGF0aFx0XHRcdFNlZSB7QGxpbmsgREJDLmRlY0ludmFyaWFudCB9LlxuICAgICAqIEBwYXJhbSBkYmNcdFx0XHRTZWUge0BsaW5rIERCQy5kZWNJbnZhcmlhbnQgfS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFNlZSB7QGxpbmsgREJDLmRlY0ludmFyaWFudCB9LiAqL1xuICAgIHN0YXRpYyBJTlZBUklBTlQoXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBUbyBjaGVjayBmb3IgVU5ERUZJTkVEIGFuZCBOVUxMLlxuICAgIGVxdWl2YWxlbnQsIGludmVydCA9IGZhbHNlLCBwYXRoID0gdW5kZWZpbmVkLCBoaW50ID0gdW5kZWZpbmVkLCBkYmMgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIERCQy5jcmVhdGVJTlZBUklBTlQoRVEsIFtlcXVpdmFsZW50LCBpbnZlcnRdLCBkYmMsIHBhdGgsIGhpbnQpO1xuICAgIH1cbiAgICAvLyAjZW5kcmVnaW9uIENvbmRpdGlvbiBjaGVja2luZy5cbiAgICAvLyAjcmVnaW9uIFJlZmVyZW5jZWQgQ29uZGl0aW9uIGNoZWNraW5nLlxuICAgIC8vXG4gICAgLy8gRm9yIHVzYWdlIGluIGR5bmFtaWMgc2NlbmFyaW9zIChsaWtlIHdpdGggQUUtREJDKS5cbiAgICAvL1xuICAgIC8qKlxuICAgICAqIEludm9rZXMgdGhlIHtAbGluayBFUS5jaGVja0FsZ29yaXRobSB9IHBhc3NpbmcgdGhlIHZhbHVlICoqdG9DaGVjayoqLCB7QGxpbmsgRVEuZXF1aXZhbGVudCB9IGFuZCB7QGxpbmsgRVEuaW52ZXJ0IH0uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9DaGVjayBTZWUge0BsaW5rIEVRLmNoZWNrQWxnb3JpdGhtIH0uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBTZWUge0BsaW5rIEVRLmNoZWNrQWxnb3JpdGhtfS4gKi9cbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE5lY2Vzc2FyeSB0byBjaGVjayBhZ2FpbnN0IE5VTEwgJiBVTkRFRklORUQuXG4gICAgY2hlY2sodG9DaGVjaykge1xuICAgICAgICByZXR1cm4gRVEuY2hlY2tBbGdvcml0aG0odG9DaGVjaywgdGhpcy5lcXVpdmFsZW50LCB0aGlzLmludmVydCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZXMgdGhlIHtAbGluayBFUS5jaGVja0FsZ29yaXRobSB9IHBhc3NpbmcgdGhlIHZhbHVlICoqdG9DaGVjayoqIGFuZCB0aGUgc3BlY2lmaWVkICoqdHlwZSoqIC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b0NoZWNrIFNlZSB7QGxpbmsgRVEuY2hlY2tBbGdvcml0aG0gfS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSAqKkNBTkRJREFURSoqICoqdG9DaGVjayoqIGRvZXNuJ3QgZnVsZmlsbCB0aGlzIHtAbGluayBFUSB9LlxuICAgICAqXG4gICAgICogQHRocm93cyBBIHtAbGluayBEQkMuSW5mcmluZ2VtZW50IH0gaWYgdGhlICoqQ0FORElEQVRFKiogKip0b0NoZWNrKiogZG9lcyBub3QgZnVsZmlsbCB0aGlzIHtAbGluayBFUSB9LiovXG4gICAgc3RhdGljIHRzQ2hlY2sodG9DaGVjaywgZXF1aXZhbGVudCwgaGludCA9IHVuZGVmaW5lZCwgaWQgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gRVEuY2hlY2tBbGdvcml0aG0odG9DaGVjaywgZXF1aXZhbGVudCwgZmFsc2UpO1xuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgICByZXR1cm4gdG9DaGVjaztcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgREJDLkluZnJpbmdlbWVudChgJHtpZCA/IGAoJHtpZH0pIGAgOiBcIlwifSR7cmVzdWx0fSAke2hpbnQgPyBg4pyoICR7aGludH0g4pyoYCA6IFwiXCJ9YCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgdGhpcyB7QGxpbmsgRVEgfSBieSBzZXR0aW5nIHRoZSBwcm90ZWN0ZWQgcHJvcGVydHkge0BsaW5rIEVRLmVxdWl2YWxlbnQgfSB1c2VkIGJ5IHtAbGluayBFUS5jaGVjayB9LlxuICAgICAqXG4gICAgICogQHBhcmFtIGVxdWl2YWxlbnQgU2VlIHtAbGluayBFUS5jaGVjayB9LiAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogVG8gYmUgYWJsZSB0byBtYXRjaCBVTkRFRklORUQgYW5kIE5VTEwuXG4gICAgZXF1aXZhbGVudCwgaW52ZXJ0ID0gZmFsc2UpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5lcXVpdmFsZW50ID0gZXF1aXZhbGVudDtcbiAgICAgICAgdGhpcy5pbnZlcnQgPSBpbnZlcnQ7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgRVEgfSBmcm9tIFwiLi4vRVFcIjtcbi8qKlxuICogRElGRkVSRU5UIGNsYXNzIGZvciBpbmVxdWFsaXR5IGNvbXBhcmlzb25zLlxuICpcbiAqIFRoaXMgY2xhc3MgZXh0ZW5kcyBFUSBhbmQgcHJvdmlkZXMgbWV0aG9kcyB0byBjaGVjayBpZiBhIHZhbHVlIGlzIGRpZmZlcmVudCAobm90IGVxdWFsKVxuICogZnJvbSBhIHNwZWNpZmllZCBlcXVpdmFsZW50IHZhbHVlLiBJdCBpbnZlcnRzIHRoZSBlcXVhbGl0eSBjaGVjayBieSBhbHdheXMgcGFzc2luZ1xuICogYHRydWVgIGZvciB0aGUgaW52ZXJ0IHBhcmFtZXRlciB0byB0aGUgcGFyZW50IEVRIGNsYXNzIG1ldGhvZHMuXG4gKlxuICogQHJlbWFya3NcbiAqIFRoZSBjbGFzcyBwcm92aWRlcyBwcmVjb25kaXRpb24gKFBSRSksIHBvc3Rjb25kaXRpb24gKFBPU1QpLCBhbmQgaW52YXJpYW50IChJTlZBUklBTlQpXG4gKiBjaGVja3MgZm9yIERlc2lnbiBieSBDb250cmFjdCBwcm9ncmFtbWluZyBwYXR0ZXJucy5cbiAqXG4gKiBAc2VlIHtAbGluayBDT01QQVJJU09OfVxuICogQHNlZSB7QGxpbmsgRVF9XG4gKi9cbmV4cG9ydCBjbGFzcyBESUZGRVJFTlQgZXh0ZW5kcyBFUSB7XG4gICAgLyoqIFNlZSB7QGxpbmsgRVEuUFJFIH0uIEFsd2F5cyBpbnZlcnRzIGVxdWFsaXR5IGNoZWNrLiAqL1xuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogTXVzdCBtYXRjaCBwYXJlbnQgc2lnbmF0dXJlXG4gICAgc3RhdGljIFBSRShlcXVpdmFsZW50LCBfaW52ZXJ0ID0gZmFsc2UsIHBhdGggPSB1bmRlZmluZWQsIGhpbnQgPSB1bmRlZmluZWQsIGRiYyA9IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gRVEuUFJFKGVxdWl2YWxlbnQsIHRydWUsIHBhdGgsIGhpbnQsIGRiYyk7XG4gICAgfVxuICAgIC8qKiBTZWUge0BsaW5rIEVRLlBPU1QgfS4gQWx3YXlzIGludmVydHMgZXF1YWxpdHkgY2hlY2suICovXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBNdXN0IG1hdGNoIHBhcmVudCBzaWduYXR1cmVcbiAgICBzdGF0aWMgUE9TVChlcXVpdmFsZW50LCBfaW52ZXJ0ID0gZmFsc2UsIHBhdGggPSB1bmRlZmluZWQsIGhpbnQgPSB1bmRlZmluZWQsIGRiYyA9IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gRVEuUE9TVChlcXVpdmFsZW50LCB0cnVlLCBwYXRoLCBoaW50LCBkYmMpO1xuICAgIH1cbiAgICAvKiogU2VlIHtAbGluayBFUS5JTlZBUklBTlQgfS4gQWx3YXlzIGludmVydHMgZXF1YWxpdHkgY2hlY2suICovXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiBNdXN0IG1hdGNoIHBhcmVudCBzaWduYXR1cmVcbiAgICBzdGF0aWMgSU5WQVJJQU5UKGVxdWl2YWxlbnQsIF9pbnZlcnQgPSBmYWxzZSwgcGF0aCA9IHVuZGVmaW5lZCwgaGludCA9IHVuZGVmaW5lZCwgZGJjID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBFUS5JTlZBUklBTlQoZXF1aXZhbGVudCwgdHJ1ZSwgcGF0aCwgaGludCwgZGJjKTtcbiAgICB9XG4gICAgLyoqIFNlZSB7QGxpbmsgRVEuY29uc3RydWN0b3IgfS4gKi9cbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE11c3QgbWF0Y2ggcGFyZW50IHNpZ25hdHVyZVxuICAgIGNvbnN0cnVjdG9yKGVxdWl2YWxlbnQpIHtcbiAgICAgICAgc3VwZXIoZXF1aXZhbGVudCwgdHJ1ZSk7XG4gICAgICAgIHRoaXMuZXF1aXZhbGVudCA9IGVxdWl2YWxlbnQ7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgREJDIH0gZnJvbSBcIi4uL0RCQ1wiO1xuLyoqXG4gKiBBIHtAbGluayBEQkMgfSBkZWZpbmluZyB0aGF0IHRoZSBhbiB7QGxpbmsgb2JqZWN0IH1zIGdvdHRhIGJlIGFuIGluc3RhbmNlIG9mIGEgY2VydGFpbiB7QGxpbmsgSU5TVEFOQ0UucmVmZXJlbmNlIH0uXG4gKlxuICogQHJlbWFya3NcbiAqIE1haW50YWluZXI6IFNhbHZhdG9yZSBDYWxsYXJpIChYREJDQFdhWENvZGUubmV0KSAqL1xuZXhwb3J0IGNsYXNzIElOU1RBTkNFIGV4dGVuZHMgREJDIHtcbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdGhlIHZhbHVlICoqdG9DaGVjayoqIGlzIGFuIGluc3RhbmNlIG9mIHRoZSBzcGVjaWZpZWQgKipyZWZlcmVuY2UqKi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b0NoZWNrXHRUaGUgdmFsdWUgdGhhdCBoYXMgdG8gYmUgYW4gaW5zdGFuY2Ugb2YgdGhlICoqcmVmZXJlbmNlKiogaW4gb3JkZXIgZm9yIHRoaXMge0BsaW5rIERCQyB9XG4gICAgICogXHRcdFx0XHRcdHRvIGJlIGZ1bGZpbGxlZC5cbiAgICAgKiBAcGFyYW0gcmVmZXJlbmNlXHRUaGUge0BsaW5rIG9iamVjdCB9IHRoZSBvbmUgKip0b0NoZWNrKiogaGFzIHRvIGJlIGFuIGluc3RhbmNlIG9mLlxuICAgICAqXG4gICAgICogQHJldHVybnMgVFJVRSBpZiB0aGUgdmFsdWUgKip0b0NoZWNrKiogaXMgaXMgYW4gaW5zdGFuY2Ugb2YgdGhlICpyZWZlcmVuY2UqKiwgKip1bmRlZmluZWQqKiBvciAqKm51bGwqKiwgb3RoZXJ3aXNlIEZBTFNFLiAqL1xuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogSW4gb3JkZXIgdG8gcGVyZm9ybSBhbiBcImluc3RhbmNlb2ZcIiBjaGVjay5cbiAgICBzdGF0aWMgY2hlY2tBbGdvcml0aG0odG9DaGVjaywgLi4ucmVmZXJlbmNlcykge1xuICAgICAgICBpZiAodG9DaGVjayA9PT0gbnVsbCB8fCB0b0NoZWNrID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgcmVmIG9mIHJlZmVyZW5jZXMpIHtcbiAgICAgICAgICAgIGlmICh0b0NoZWNrIGluc3RhbmNlb2YgcmVmKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGBWYWx1ZSBoYXMgdG8gYmUgYW4gaW5zdGFuY2Ugb2YgXCIke3JlZmVyZW5jZXMubWFwKChyZWYpID0+IHJlZi5uYW1lIHx8IHJlZikuam9pbihcIiwgXCIpfVwiIGJ1dCBpcyBvZiB0eXBlIFwiJHt0eXBlb2YgdG9DaGVja31cImA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgcGFyYW1ldGVyLWRlY29yYXRvciBmYWN0b3J5IHVzaW5nIHRoZSB7QGxpbmsgSU5TVEFOQ0UuY2hlY2tBbGdvcml0aG0gfSB0byBkZXRlcm1pbmUgd2hldGhlciB0aGlzIHtAbGluayBEQkMgfSBpcyBmdWxmaWxsZWRcbiAgICAgKiBieSB0aGUgdGFnZ2VkIHBhcmFtZXRlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSByZWZlcmVuY2VcdFNlZSB7QGxpbmsgSU5TVEFOQ0UuY2hlY2tBbGdvcml0aG0gfS5cbiAgICAgKiBAcGFyYW0gcGF0aFx0U2VlIHtAbGluayBEQkMuZGVjUHJlY29uZGl0aW9uIH0uXG4gICAgICogQHBhcmFtIGRiY1x0U2VlIHtAbGluayBEQkMuZGVjUHJlY29uZGl0aW9uIH0uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBTZWUge0BsaW5rIERCQy5kZWNQcmVjb25kaXRpb24gfS4gKi9cbiAgICBzdGF0aWMgUFJFKFxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogSW4gb3JkZXIgdG8gcGVyZm9ybSBhbiBcImluc3RhbmNlb2ZcIiBjaGVjay5cbiAgICByZWZlcmVuY2UsIHBhdGggPSB1bmRlZmluZWQsIGhpbnQgPSB1bmRlZmluZWQsIGRiYyA9IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCByZWZzID0gQXJyYXkuaXNBcnJheShyZWZlcmVuY2UpID8gcmVmZXJlbmNlIDogW3JlZmVyZW5jZV07XG4gICAgICAgIHJldHVybiBEQkMuY3JlYXRlUFJFKElOU1RBTkNFLmNoZWNrQWxnb3JpdGhtLCByZWZzLCBkYmMsIHBhdGgsIGhpbnQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIG1ldGhvZC1kZWNvcmF0b3IgZmFjdG9yeSB1c2luZyB0aGUge0BsaW5rIElOU1RBTkNFLmNoZWNrQWxnb3JpdGhtIH0gdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyB7QGxpbmsgREJDIH0gaXMgZnVsZmlsbGVkXG4gICAgICogYnkgdGhlIHRhZ2dlZCBtZXRob2QncyByZXR1cm52YWx1ZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSByZWZlcmVuY2VcdFNlZSB7QGxpbmsgSU5TVEFOQ0UuY2hlY2tBbGdvcml0aG0gfS5cbiAgICAgKiBAcGFyYW0gcGF0aFx0U2VlIHtAbGluayBEQkMuUG9zdGNvbmRpdGlvbiB9LlxuICAgICAqIEBwYXJhbSBkYmNcdFNlZSB7QGxpbmsgREJDLmRlY1Bvc3Rjb25kaXRpb24gfS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFNlZSB7QGxpbmsgREJDLmRlY1Bvc3Rjb25kaXRpb24gfS4gKi9cbiAgICBzdGF0aWMgUE9TVChcbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IEluIG9yZGVyIHRvIHBlcmZvcm0gYW4gXCJpbnN0YW5jZW9mXCIgY2hlY2suXG4gICAgcmVmZXJlbmNlLCBwYXRoID0gdW5kZWZpbmVkLCBoaW50ID0gdW5kZWZpbmVkLCBkYmMgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgcmVmcyA9IEFycmF5LmlzQXJyYXkocmVmZXJlbmNlKSA/IHJlZmVyZW5jZSA6IFtyZWZlcmVuY2VdO1xuICAgICAgICByZXR1cm4gREJDLmNyZWF0ZVBPU1QoSU5TVEFOQ0UuY2hlY2tBbGdvcml0aG0sIHJlZnMsIGRiYywgcGF0aCwgaGludCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgZmllbGQtZGVjb3JhdG9yIGZhY3RvcnkgdXNpbmcgdGhlIHtAbGluayBJTlNUQU5DRS5jaGVja0FsZ29yaXRobSB9IHRvIGRldGVybWluZSB3aGV0aGVyIHRoaXMge0BsaW5rIERCQyB9IGlzIGZ1bGZpbGxlZFxuICAgICAqIGJ5IHRoZSB0YWdnZWQgbWV0aG9kJ3MgcmV0dXJudmFsdWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcmVmZXJlbmNlXHRTZWUge0BsaW5rIElOU1RBTkNFLmNoZWNrQWxnb3JpdGhtIH0uXG4gICAgICogQHBhcmFtIHBhdGhcdFNlZSB7QGxpbmsgREJDLmRlY0ludmFyaWFudCB9LlxuICAgICAqIEBwYXJhbSBkYmNcdFNlZSB7QGxpbmsgREJDLmRlY0ludmFyaWFudCB9LlxuICAgICAqXG4gICAgICogQHJldHVybnMgU2VlIHtAbGluayBEQkMuZGVjSW52YXJpYW50IH0uICovXG4gICAgc3RhdGljIElOVkFSSUFOVChcbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IEluIG9yZGVyIHRvIHBlcmZvcm0gYW4gXCJpbnN0YW5jZW9mXCIgY2hlY2suXG4gICAgcmVmZXJlbmNlLCBwYXRoID0gdW5kZWZpbmVkLCBoaW50ID0gdW5kZWZpbmVkLCBkYmMgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIERCQy5jcmVhdGVJTlZBUklBTlQoSU5TVEFOQ0UsIFtyZWZlcmVuY2VdLCBkYmMsIHBhdGgsIGhpbnQpO1xuICAgIH1cbiAgICAvLyAjZW5kcmVnaW9uIENvbmRpdGlvbiBjaGVja2luZy5cbiAgICAvLyAjcmVnaW9uIFJlZmVyZW5jZWQgQ29uZGl0aW9uIGNoZWNraW5nLlxuICAgIC8vXG4gICAgLy8gRm9yIHVzYWdlIGluIGR5bmFtaWMgc2NlbmFyaW9zIChsaWtlIHdpdGggQUUtREJDKS5cbiAgICAvL1xuICAgIC8qKlxuICAgICAqIEludm9rZXMgdGhlIHtAbGluayBJTlNUQU5DRS5jaGVja0FsZ29yaXRobSB9IHBhc3NpbmcgdGhlIHZhbHVlICoqdG9DaGVjayoqIGFuZCB0aGUge0BsaW5rIElOU1RBTkNFLnJlZmVyZW5jZSB9IC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b0NoZWNrIFNlZSB7QGxpbmsgSU5TVEFOQ0UuY2hlY2tBbGdvcml0aG0gfS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFNlZSB7QGxpbmsgSU5TVEFOQ0UuY2hlY2tBbGdvcml0aG19LiAqL1xuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogPGV4cGxhbmF0aW9uPlxuICAgIGNoZWNrKHRvQ2hlY2spIHtcbiAgICAgICAgcmV0dXJuIEFycmF5LmlzQXJyYXkodGhpcy5yZWZlcmVuY2UpXG4gICAgICAgICAgICA/IElOU1RBTkNFLmNoZWNrQWxnb3JpdGhtKHRvQ2hlY2ssIC4uLnRoaXMucmVmZXJlbmNlKVxuICAgICAgICAgICAgOiBJTlNUQU5DRS5jaGVja0FsZ29yaXRobSh0b0NoZWNrLCB0aGlzLnJlZmVyZW5jZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFR5cGUtc2FmZSBjaGVjayB0aGF0IHZhbGlkYXRlcyBpZiBhIHZhbHVlIGlzIGFuIGluc3RhbmNlIG9mIGEgc3BlY2lmaWVkIHJlZmVyZW5jZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b0NoZWNrIFx0VGhlIHZhbHVlIHRvIGNoZWNrIGZvciBpbnN0YW5jZSB2YWxpZGl0eS5cbiAgICAgKiBAcGFyYW0gcmVmZXJlbmNlXHRUaGUge0BsaW5rIG9iamVjdCB9IHRoZSBvbmUgKip0b0NoZWNrKiogaGFzIHRvIGJlIGFuIGluc3RhbmNlIG9mLlxuICAgICAqIEBwYXJhbSBoaW50XHRcdEFuIG9wdGlvbmFsIHtAbGluayBzdHJpbmcgfSBwcm92aWRpbmcgZXh0cmEgaW5mb3JtYXRpb24gaW4gY2FzZSBvZiBhbiBpbmZyaW5nZW1lbnQuXG4gICAgICogQHBhcmFtIGlkXHRcdEEge0BsaW5rIHN0cmluZyB9IGlkZW50aWZ5aW5nIHRoaXMge0BsaW5rIElOU1RBTkNFIH0gdmlhIHRoZSB7QGxpbmsgREJDLkluZnJpbmdlbWVudCB9LU1lc3NhZ2UuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGUgKipDQU5ESURBVEUqKiAqKnRvQ2hlY2sqKiBpZiBpdCBmdWxmaWxscyB0aGlzIHtAbGluayBJTlNUQU5DRSB9LlxuICAgICAqXG4gICAgICogQHRocm93cyBBIHtAbGluayBEQkMuSW5mcmluZ2VtZW50IH0gaWYgdGhlICoqQ0FORElEQVRFKiogKip0b0NoZWNrKiogZG9lcyBub3QgZnVsZmlsbCB0aGlzIHtAbGluayBJTlNUQU5DRSB9LiAqL1xuICAgIHN0YXRpYyB0c0NoZWNrKHRvQ2hlY2ssIHJlZmVyZW5jZSwgaGludCA9IHVuZGVmaW5lZCwgaWQgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIElOU1RBTkNFLnRzQ2hlY2tNdWx0aSh0b0NoZWNrLCBbcmVmZXJlbmNlXSwgaGludCwgaWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2VzIHRoZSB7QGxpbmsgSU5TVEFOQ0UuY2hlY2tBbGdvcml0aG0gfSBwYXNzaW5nIHRoZSB2YWx1ZSAqKnRvQ2hlY2sqKiBhbmQgdGhlIHtAbGluayBJTlNUQU5DRS5yZWZlcmVuY2UgfSAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9DaGVjayBcdFNlZSB7QGxpbmsgSU5TVEFOQ0UuY2hlY2tBbGdvcml0aG0gfS5cbiAgICAgKiBAcGFyYW0gcmVmZXJlbmNlXHRTZWUge0BsaW5rIElOU1RBTkNFLmNoZWNrQWxnb3JpdGhtIH0uXG4gICAgICogQHBhcmFtIGhpbnRcdFx0QW4gb3B0aW9uYWwge0BsaW5rIHN0cmluZyB9IHByb3ZpZGluZyBleHRyYSBpbmZvcm1hdGlvbiBpbiBjYXNlIG9mIGFuIGluZnJpbmdlbWVudC5cbiAgICAgKiBAcGFyYW0gaWRcdFx0QSB7QGxpbmsgc3RyaW5nIH0gaWRlbnRpZnlpbmcgdGhpcyB7QGxpbmsgSU5TVEFOQ0UgfSB2aWEgdGhlIHtAbGluayBEQkMuSW5mcmluZ2VtZW50IH0tTWVzc2FnZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSAqKkNBTkRJREFURSoqICoqdG9DaGVjayoqIGRvZXNuJ3QgZnVsZmlsbCB0aGlzIHtAbGluayBJTlNUQU5DRSB9LlxuICAgICAqXG4gICAgICogQHRocm93cyBBIHtAbGluayBEQkMuSW5mcmluZ2VtZW50IH0gaWYgdGhlICoqQ0FORElEQVRFKiogKip0b0NoZWNrKiogZG9lcyBub3QgZnVsZmlsbCB0aGlzIHtAbGluayBERUZJTkVEIH0uICovXG4gICAgc3RhdGljIHRzQ2hlY2tNdWx0aSh0b0NoZWNrLCByZWZlcmVuY2VzLCBoaW50ID0gdW5kZWZpbmVkLCBpZCA9IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBJTlNUQU5DRS5jaGVja0FsZ29yaXRobSh0b0NoZWNrLCAuLi5yZWZlcmVuY2VzKTtcbiAgICAgICAgaWYgKHJlc3VsdCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRvQ2hlY2s7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IERCQy5JbmZyaW5nZW1lbnQoYCR7aWQgPyBgKCR7aWR9KSBgIDogXCJcIn0ke3Jlc3VsdH0gJHtoaW50ID8gYOKcqCAke2hpbnR9IOKcqGAgOiBcIlwifWApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIHRoaXMge0BsaW5rIElOU1RBTkNFIH0gYnkgc2V0dGluZyB0aGUgcHJvdGVjdGVkIHByb3BlcnR5IHtAbGluayBJTlNUQU5DRS5yZWZlcmVuY2UgfSB1c2VkIGJ5IHtAbGluayBJTlNUQU5DRS5jaGVjayB9LlxuICAgICAqXG4gICAgICogQHBhcmFtIHJlZmVyZW5jZSBTZWUge0BsaW5rIElOU1RBTkNFLmNoZWNrIH0uICovXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0V4cGxpY2l0QW55OiA8ZXhwbGFuYXRpb24+XG4gICAgY29uc3RydWN0b3IocmVmZXJlbmNlKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMucmVmZXJlbmNlID0gcmVmZXJlbmNlO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IERCQyB9IGZyb20gXCIuLi9EQkNcIjtcbi8qKlxuICogQSB7QGxpbmsgREJDIH0gcHJvdmlkaW5nIHtAbGluayBSRUdFWCB9LWNvbnRyYWN0cyBhbmQgc3RhbmRhcmQge0BsaW5rIFJlZ0V4cCB9IGZvciBjb21tb24gdXNlIGNhc2VzIGluIHtAbGluayBSRUdFWC5zdGRFeHAgfS5cbiAqXG4gKiBAcmVtYXJrc1xuICogTWFpbnRhaW5lcjogQ2FsbGFyaSwgU2FsdmF0b3JlIChYREJDQFdhWENvZGUubmV0KSAqL1xuZXhwb3J0IGNsYXNzIFJFR0VYIGV4dGVuZHMgREJDIHtcbiAgICBzdGF0aWMgZ2V0IHN0ZEV4cCgpIHtcbiAgICAgICAgaWYgKCFSRUdFWC5fc3RkRXhwKSB7XG4gICAgICAgICAgICBSRUdFWC5fc3RkRXhwID0ge1xuICAgICAgICAgICAgICAgIGh0bWxBdHRyaWJ1dGVOYW1lOiAvXlthLXpBLVpfOl1bYS16QS1aMC05Xy46LV0qJC8sXG4gICAgICAgICAgICAgICAgZU1haWw6IC9eW2EtekEtWjAtOS5fJSstXStAW2EtekEtWjAtOS4tXStcXC5bYS16QS1aXXsyLH0kL2ksXG4gICAgICAgICAgICAgICAgcHJvcGVydHk6IC9eWyRfQS1aYS16XVskX0EtWmEtejAtOV0qJC8sXG4gICAgICAgICAgICAgICAgdXJsOiAvXig/Omh0dHBzP3xmdHApOlxcL1xcL1teXFxzLyQuPyNdLlteXFxzXSokL2ksXG4gICAgICAgICAgICAgICAga2V5UGF0aDogL14oW2EtekEtWl8kXVthLXpBLVowLTlfJF0qXFwuKSpbYS16QS1aXyRdW2EtekEtWjAtOV8kXSokLyxcbiAgICAgICAgICAgICAgICBkYXRlOiAvXlxcZHsxLDR9Wy5cXC8tXVxcZHsxLDJ9Wy5cXC8tXVxcZHsxLDR9JC9pLFxuICAgICAgICAgICAgICAgIGRhdGVGb3JtYXQ6IC9eKChEezEsMn1bLi8tXU17MSwyfVsuLy1dWXsxLDR9KXwoTXsxLDJ9Wy4vLV1EezEsMn1bLi8tXVl7MSw0fSl8WXsxLDR9Wy4vLV1EezEsMn1bLi8tXU17MSwyfXwoWXsxLDR9Wy4vLV1NezEsMn1bLi8tXUR7MSwyfSkpJC9pLFxuICAgICAgICAgICAgICAgIGNzc1NlbGVjdG9yOiAvXig/OlxcKnwjW1xcdy1dK3xcXC5bXFx3LV0rfCg/OltcXHctXSt8XFwqKSg/OjooPzpbXFx3LV0rKD86XFwoW1xcdy1dK1xcKSk/KSspPyg/OlxcWyg/OltcXHctXSsoPzooPzo9fH49fFxcfD18XFwqPXxcXCQ9fFxcXj0pXFxzKig/OlwiW15cIl0qXCJ8J1teJ10qJ3xbXFx3LV0rKVxccyopPyk/XFxdKSt8XFxbXFxzKltcXHctXStcXHMqPVxccyooPzpcIlteXCJdKlwifCdbXiddKid8W1xcdy1dKylcXHMqXFxdKSg/OixcXHMqKD86XFwqfCNbXFx3LV0rfFxcLltcXHctXSt8KD86W1xcdy1dK3xcXCopKD86Oig/OltcXHctXSsoPzpcXChbXFx3LV0rXFwpKT8pKyk/KD86XFxbKD86W1xcdy1dKyg/Oig/Oj18fj18XFx8PXxcXCo9fFxcJD18XFxePSlcXHMqKD86XCJbXlwiXSpcInwnW14nXSonfFtcXHctXSspXFxzKik/KT9cXF0pK3xcXFtcXHMqW1xcdy1dK1xccyo9XFxzKig/OlwiW15cIl0qXCJ8J1teJ10qJ3xbXFx3LV0rKVxccypcXF0pKSokLyxcbiAgICAgICAgICAgICAgICBib29sZWFuOiAvXihUUlVFfEZBTFNFKSQvaSxcbiAgICAgICAgICAgICAgICBjb2xvckNvZGVIRVg6IC9eIyhbQS1GYS1mXFxkXXszLDR9fFtBLUZhLWZcXGRdezZ9fFtBLUZhLWZcXGRdezh9KSQvaSxcbiAgICAgICAgICAgICAgICBzaW1wbGVIb3RrZXk6IC9eKChBbHR8Q3RybHxTaGlmdHxNZXRhKVxcKykrW2EtelxcZF0kL2ksXG4gICAgICAgICAgICAgICAgYmNwNDc6IC9eKD86W2Etel17MiwzfSg/Oi1bYS16XXszfSl7MCwzfXxbYS16XXs0fXxbYS16XXs1LDh9KSg/Oi1bYS16XXs0fSk/KD86LVthLXpdezJ9fC1bMC05XXszfSk/KD86LVthLXowLTldezUsOH18LVswLTldW2EtejAtOV17M30pKig/Oi1bMC05YS13eS16XSg/Oi1bYS16MC05XXsyLDh9KSspKig/Oi14KD86LVthLXowLTldezEsOH0pKyk/JHxeeCg/Oi1bYS16MC05XXsxLDh9KSskL2ksXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSRUdFWC5fc3RkRXhwO1xuICAgIH1cbiAgICAvLyAjcmVnaW9uIENvbmRpdGlvbiBjaGVja2luZy5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdGhlIHZhbHVlICoqdG9DaGVjayoqIGlzIGNvbXBsaWVzIHRvIHRoZSB7QGxpbmsgUmVnRXhwIH0gKipleHByZXNzaW9uKiouXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9DaGVja1x0XHRUaGUgdmFsdWUgdGhhdCBoYXMgY29tcGx5IHRvIHRoZSB7QGxpbmsgUmVnRXhwIH0gKipleHByZXNzaW9uKiogZm9yIHRoaXMge0BsaW5rIERCQyB9IHRvIGJlIGZ1bGZpbGxlZC5cbiAgICAgKiBAcGFyYW0gZXhwcmVzc2lvblx0VGhlIHtAbGluayBSZWdFeHAgfSB0aGUgb25lICoqdG9DaGVjayoqIGhhcyBjb21wbHkgdG8gaW4gb3JkZXIgZm9yIHRoaXMge0BsaW5rIERCQyB9IHRvIGJlXG4gICAgICogXHRcdFx0XHRcdFx0ZnVsZmlsbGVkLlxuICAgICAqXG4gICAgICogQHJldHVybnMgVFJVRSBpZiB0aGUgdmFsdWUgKip0b0NoZWNrKiogY29tcGxpZXMgd2l0aCB0aGUge0BsaW5rIFJlZ0V4cCB9ICoqZXhwcmVzc2lvbioqLCBvdGhlcndpc2UgRkFMU0UuICovXG4gICAgc3RhdGljIGNoZWNrQWxnb3JpdGhtKHRvQ2hlY2ssIGV4cHJlc3Npb24pIHtcbiAgICAgICAgaWYgKHRvQ2hlY2sgPT09IHVuZGVmaW5lZCB8fCB0b0NoZWNrID09PSBudWxsIHx8IHRvQ2hlY2sgPT09IFwiXCIpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgaWYgKCFleHByZXNzaW9uLnRlc3QodG9DaGVjaykpIHtcbiAgICAgICAgICAgIHJldHVybiBgVmFsdWUgaGFzIHRvIGNvbXBseSB0byByZWd1bGFyIGV4cHJlc3Npb24gXCIke2V4cHJlc3Npb259XCJgO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIHBhcmFtZXRlci1kZWNvcmF0b3IgZmFjdG9yeSB1c2luZyB0aGUge0BsaW5rIFJFR0VYLmNoZWNrQWxnb3JpdGhtIH0gdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyB7QGxpbmsgREJDIH0gaXMgZnVsZmlsbGVkXG4gICAgICogYnkgdGhlIHRhZ2dlZCBwYXJhbWV0ZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXhwcmVzc2lvblx0U2VlIHtAbGluayBSRUdFWC5jaGVja0FsZ29yaXRobSB9LlxuICAgICAqIEBwYXJhbSBwYXRoXHRcdFx0U2VlIHtAbGluayBEQkMuZGVjUHJlY29uZGl0aW9uIH0uXG4gICAgICogQHBhcmFtIGRiY1x0XHRcdFNlZSB7QGxpbmsgREJDLmRlY1ByZWNvbmRpdGlvbiB9LlxuICAgICAqXG4gICAgICogQHJldHVybnMgU2VlIHtAbGluayBEQkMuZGVjUHJlY29uZGl0aW9uIH0uICovXG4gICAgc3RhdGljIFBSRShleHByZXNzaW9uLCBwYXRoID0gdW5kZWZpbmVkLCBoaW50ID0gdW5kZWZpbmVkLCBkYmMgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIERCQy5jcmVhdGVQUkUoUkVHRVguY2hlY2tBbGdvcml0aG0sIFtleHByZXNzaW9uXSwgZGJjLCBwYXRoLCBoaW50KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBtZXRob2QtZGVjb3JhdG9yIGZhY3RvcnkgdXNpbmcgdGhlIHtAbGluayBSRUdFWC5jaGVja0FsZ29yaXRobSB9IHRvIGRldGVybWluZSB3aGV0aGVyIHRoaXMge0BsaW5rIERCQyB9IGlzIGZ1bGZpbGxlZFxuICAgICAqIGJ5IHRoZSB0YWdnZWQgbWV0aG9kJ3MgcmV0dXJudmFsdWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXhwcmVzc2lvblx0U2VlIHtAbGluayBSRUdFWC5jaGVja0FsZ29yaXRobSB9LlxuICAgICAqIEBwYXJhbSBwYXRoXHRcdFx0U2VlIHtAbGluayBEQkMuUG9zdGNvbmRpdGlvbiB9LlxuICAgICAqIEBwYXJhbSBkYmNcdFx0XHRTZWUge0BsaW5rIERCQy5kZWNQb3N0Y29uZGl0aW9uIH0uXG4gICAgICogQHBhcmFtIGhpbnRcdFx0XHRTZWUge0BsaW5rIERCQy5kZWNQb3N0Y29uZGl0aW9uIH0uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBTZWUge0BsaW5rIERCQy5kZWNQb3N0Y29uZGl0aW9uIH0uICovXG4gICAgc3RhdGljIFBPU1QoZXhwcmVzc2lvbiwgcGF0aCA9IHVuZGVmaW5lZCwgaGludCA9IHVuZGVmaW5lZCwgZGJjID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBEQkMuY3JlYXRlUE9TVChSRUdFWC5jaGVja0FsZ29yaXRobSwgW2V4cHJlc3Npb25dLCBkYmMsIHBhdGgsIGhpbnQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIGZpZWxkLWRlY29yYXRvciBmYWN0b3J5IHVzaW5nIHRoZSB7QGxpbmsgUkVHRVguY2hlY2tBbGdvcml0aG0gfSB0byBkZXRlcm1pbmUgd2hldGhlciB0aGlzIHtAbGluayBEQkMgfSBpcyBmdWxmaWxsZWRcbiAgICAgKiBieSB0aGUgdGFnZ2VkIGZpZWxkLlxuICAgICAqXG4gICAgICogQHBhcmFtIGV4cHJlc3Npb25cdFNlZSB7QGxpbmsgUkVHRVguY2hlY2tBbGdvcml0aG0gfS5cbiAgICAgKiBAcGFyYW0gcGF0aFx0XHRcdFNlZSB7QGxpbmsgREJDLmRlY0ludmFyaWFudCB9LlxuICAgICAqIEBwYXJhbSBkYmNcdFx0XHRTZWUge0BsaW5rIERCQy5kZWNJbnZhcmlhbnQgfS5cbiAgICAgKiBAcGFyYW0gaGludFx0XHRcdFNlZSB7QGxpbmsgREJDLmRlY0ludmFyaWFudCB9LlxuICAgICAqIEByZXR1cm5zIFNlZSB7QGxpbmsgREJDLmRlY0ludmFyaWFudCB9LiAqL1xuICAgIHN0YXRpYyBJTlZBUklBTlQoZXhwcmVzc2lvbiwgcGF0aCA9IHVuZGVmaW5lZCwgaGludCA9IHVuZGVmaW5lZCwgZGJjID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBEQkMuY3JlYXRlSU5WQVJJQU5UKFJFR0VYLCBbZXhwcmVzc2lvbl0sIGRiYywgcGF0aCwgaGludCk7XG4gICAgfVxuICAgIC8vICNlbmRyZWdpb24gQ29uZGl0aW9uIGNoZWNraW5nLlxuICAgIC8vICNyZWdpb24gUmVmZXJlbmNlZCBDb25kaXRpb24gY2hlY2tpbmcuXG4gICAgLy9cbiAgICAvLyBGb3IgdXNhZ2UgaW4gZHluYW1pYyBzY2VuYXJpb3MgKGxpa2Ugd2l0aCBBRS1EQkMpLlxuICAgIC8vXG4gICAgLyoqXG4gICAgICogSW52b2tlcyB0aGUge0BsaW5rIFJFR0VYLmNoZWNrQWxnb3JpdGhtIH0gcGFzc2luZyB0aGUgdmFsdWUgKip0b0NoZWNrKiogYW5kIHtAbGluayBSRUdFWC5lcXVpdmFsZW50IH0uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9DaGVjayBTZWUge0BsaW5rIFJFR0VYLmNoZWNrQWxnb3JpdGhtIH0uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBTZWUge0BsaW5rIEVRLmNoZWNrQWxnb3JpdGhtfS4gKi9cbiAgICBjaGVjayh0b0NoZWNrKSB7XG4gICAgICAgIHJldHVybiBSRUdFWC5jaGVja0FsZ29yaXRobSh0b0NoZWNrLCB0aGlzLmV4cHJlc3Npb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUeXBlLXNhZmUgY2hlY2sgdGhhdCB2YWxpZGF0ZXMgYSB2YWx1ZSBhZ2FpbnN0IGEgcmVndWxhciBleHByZXNzaW9uIGFuZCByZXR1cm5zIGl0IGFzIHRoZSBzcGVjaWZpZWQgdHlwZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b0NoZWNrXHRcdFRoZSB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHRoZSByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAgICogQHBhcmFtIGV4cHJlc3Npb25cdFRoZSByZWd1bGFyIGV4cHJlc3Npb24gdG8gdmFsaWRhdGUgYWdhaW5zdC5cbiAgICAgKiBAcGFyYW0gaGludFx0XHRcdE9wdGlvbmFsIGhpbnQgbWVzc2FnZSB0byBpbmNsdWRlIGluIHRoZSBlcnJvciBpZiB2YWxpZGF0aW9uIGZhaWxzLlxuICAgICAqIEBwYXJhbSBpZFx0XHRcdE9wdGlvbmFsIGlkZW50aWZpZXIgdG8gaW5jbHVkZSBpbiB0aGUgZXJyb3IgbWVzc2FnZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSB2YWxpZGF0ZWQgdmFsdWUgY2FzdCB0byB0aGUgQ0FORElEQVRFIHR5cGUuXG4gICAgICpcbiAgICAgKiBAdGhyb3dzIHtAbGluayBEQkMuSW5mcmluZ2VtZW50fSBpZiB0aGUgdmFsdWUgZG9lcyBub3QgbWF0Y2ggdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbi4gKi9cbiAgICBzdGF0aWMgdHNDaGVjayh0b0NoZWNrLCBleHByZXNzaW9uLCBoaW50ID0gdW5kZWZpbmVkLCBpZCA9IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBSRUdFWC5jaGVja0FsZ29yaXRobSh0b0NoZWNrLCBleHByZXNzaW9uKTtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgcmV0dXJuIHRvQ2hlY2s7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IERCQy5JbmZyaW5nZW1lbnQoYCR7aWQgPyBgKCR7aWR9KSBgIDogXCJcIn0ke3Jlc3VsdH0ke2hpbnQgPyBgIOKcqCAke2hpbnR9IOKcqGAgOiBcIlwifWApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIHRoaXMge0BsaW5rIFJFR0VYIH0gYnkgc2V0dGluZyB0aGUgcHJvdGVjdGVkIHByb3BlcnR5IHtAbGluayBSRUdFWC5leHByZXNzaW9uIH0gdXNlZCBieSB7QGxpbmsgUkVHRVguY2hlY2sgfS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBleHByZXNzaW9uIFNlZSB7QGxpbmsgUkVHRVguY2hlY2sgfS4gKi9cbiAgICBjb25zdHJ1Y3RvcihleHByZXNzaW9uKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuZXhwcmVzc2lvbiA9IGV4cHJlc3Npb247XG4gICAgfVxuICAgIC8vICNlbmRyZWdpb24gUmVmZXJlbmNlZCBDb25kaXRpb24gY2hlY2tpbmcuXG4gICAgLy8gI3JlZ2lvbiBJbi1NZXRob2QgY2hlY2tpbmcuXG4gICAgLyoqXG4gICAgICogSW52b2tlcyB0aGUge0BsaW5rIFJFR0VYLmNoZWNrQWxnb3JpdGhtIH0gcGFzc2luZyB0aGUgdmFsdWUgKip0b0NoZWNrKiogYW5kIHtAbGluayBSRUdFWC5leHByZXNzaW9uIH0uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9DaGVja1x0XHRTZWUge0BsaW5rIFJFR0VYLmNoZWNrQWxnb3JpdGhtfS5cbiAgICAgKiBAcGFyYW0gZXhwcmVzc2lvblx0U2VlIHtAbGluayBSRUdFWC5jaGVja0FsZ29yaXRobX0uXG4gICAgICovXG4gICAgc3RhdGljIGNoZWNrKHRvQ2hlY2ssIGV4cHJlc3Npb24pIHtcbiAgICAgICAgY29uc3QgY2hlY2tSZXN1bHQgPSBSRUdFWC5jaGVja0FsZ29yaXRobSh0b0NoZWNrLCBleHByZXNzaW9uKTtcbiAgICAgICAgaWYgKHR5cGVvZiBjaGVja1Jlc3VsdCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IERCQy5JbmZyaW5nZW1lbnQoY2hlY2tSZXN1bHQpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgREJDIH0gZnJvbSBcIi4uL0RCQ1wiO1xuLyoqXG4gKiBBIHtAbGluayBEQkMgfSBkZWZpbmluZyB0aGF0IGFuIHtAbGluayBvYmplY3QgfXMgZ290dGEgYmUgb2YgY2VydGFpbiB7QGxpbmsgVFlQRS50eXBlIH0uXG4gKlxuICogQHJlbWFya3NcbiAqIEF1dGhvcjogXHRcdFNhbHZhdG9yZSBDYWxsYXJpIChDYWxsYXJpQFdhWENvZGUubmV0KSAvIDIwMjVcbiAqIE1haW50YWluZXI6XHRTYWx2YXRvcmUgQ2FsbGFyaSAoWERCQ0BXYVhDb2RlLm5ldCkgKi9cbmV4cG9ydCBjbGFzcyBUWVBFIGV4dGVuZHMgREJDIHtcbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdGhlIHZhbHVlICoqdG9DaGVjayoqIGlzIG9mIHRoZSAqKnR5cGUqKiBzcGVjaWZpZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG9DaGVja1x0VGhlIHtAbGluayBPYmplY3QgfSB3aGljaCdzICoqdHlwZSoqIHRvIGNoZWNrLlxuICAgICAqIEBwYXJhbSB0eXBlXHRcdFRoZSB0eXBlIHRoZSB7QGxpbmsgb2JqZWN0fSAqKnRvQ2hlY2sqKiBoYXMgdG8gYmUgb2YuIENhbiBiZSBhIHNpbmdsZSB0eXBlIG9yIG11bHRpcGxlIHR5cGVzIHNlcGFyYXRlZCBieSBcInxcIi5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRSVUUgaWYgdGhlIHZhbHVlICoqdG9DaGVjayoqIGlzIG9mIHRoZSBzcGVjaWZpZWQgKip0eXBlKiosIG90aGVyd2lzZSBGQUxTRS4gKi9cbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IE5lY2Vzc2FyeSBmb3IgZHluYW1pYyB0eXBlIGNoZWNraW5nIG9mIGFsc28gVU5ERUZJTkVELlxuICAgIHN0YXRpYyBjaGVja0FsZ29yaXRobSh0b0NoZWNrLCB0eXBlKSB7XG4gICAgICAgIGlmICh0b0NoZWNrID09PSB1bmRlZmluZWQgfHwgdG9DaGVjayA9PT0gbnVsbClcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBjb25zdCB0eXBlcyA9IHR5cGUuc3BsaXQoXCJ8XCIpLm1hcCgodCkgPT4gdC50cmltKCkpO1xuICAgICAgICBjb25zdCBhY3R1YWxUeXBlID0gdHlwZW9mIHRvQ2hlY2s7XG4gICAgICAgIC8vICNyZWdpb24gQ2hlY2sgaWYgdGhlIGFjdHVhbCB0eXBlIG1hdGNoZXMgYXQgbGVhc3Qgb25lIG9mIHRoZSBzcGVjaWZpZWQgdHlwZXNcbiAgICAgICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy91c2VWYWxpZFR5cGVvZjogTmVjZXNzYXJ5XG4gICAgICAgIGNvbnN0IGlzVmFsaWQgPSB0eXBlcy5zb21lKCh0KSA9PiBhY3R1YWxUeXBlID09PSB0KTtcbiAgICAgICAgaWYgKCFpc1ZhbGlkKSB7XG4gICAgICAgICAgICBpZiAodHlwZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGBWYWx1ZSBoYXMgdG8gYmUgb2YgdHlwZSBcIiR7dHlwZX1cIiBidXQgaXMgb2YgdHlwZSBcIiR7YWN0dWFsVHlwZX1cImA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gYFZhbHVlIGhhcyB0byBiZSBvZiB0eXBlIFwiJHt0eXBlcy5qb2luKFwiIHwgXCIpfVwiIGJ1dCBpcyBvZiB0eXBlIFwiJHthY3R1YWxUeXBlfVwiYDtcbiAgICAgICAgfVxuICAgICAgICAvLyAjZW5kcmVnaW9uIENoZWNrIGlmIHRoZSBhY3R1YWwgdHlwZSBtYXRjaGVzIGF0IGxlYXN0IG9uZSBvZiB0aGUgc3BlY2lmaWVkIHR5cGVzXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIHBhcmFtZXRlci1kZWNvcmF0b3IgZmFjdG9yeSB1c2luZyB0aGUge0BsaW5rIFRZUEUuY2hlY2tBbGdvcml0aG0gfSB0byBkZXRlcm1pbmUgd2hldGhlciB0aGlzIHtAbGluayBEQkMgfSBpcyBmdWxmaWxsZWRcbiAgICAgKiBieSB0aGUgdGFnZ2VkIHBhcmFtZXRlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0eXBlXHRTZWUge0BsaW5rIFRZUEUuY2hlY2tBbGdvcml0aG0gfS5cbiAgICAgKiBAcGFyYW0gcGF0aFx0QSA6Oi1zZXBhcmF0ZWQgbGlzdCBvZiBkb3R0ZWQgcGF0aHMgdG8gY2hlY2suIEVhY2ggcGF0aCBwb2ludHMgdG8gYSBwcm9wZXJ0eSB3aXRoaW4gdGhlIHBhcmFtZXRlciB2YWx1ZS5cbiAgICAgKiBcdFx0XHRcdFVuZGVmaW5lZCBwcm9wZXJ0aWVzIGFyZSBza2lwcGVkLiBTZWUge0BsaW5rIERCQy5kZWNQcmVjb25kaXRpb24gfS5cbiAgICAgKiBAcGFyYW0gZGJjXHRTZWUge0BsaW5rIERCQy5kZWNQcmVjb25kaXRpb24gfS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFNlZSB7QGxpbmsgREJDLmRlY1ByZWNvbmRpdGlvbiB9LiAqL1xuICAgIHN0YXRpYyBQUkUodHlwZSwgcGF0aCA9IHVuZGVmaW5lZCwgaGludCA9IHVuZGVmaW5lZCwgZGJjID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBEQkMuY3JlYXRlUFJFKFRZUEUuY2hlY2tBbGdvcml0aG0sIFt0eXBlXSwgZGJjLCBwYXRoLCBoaW50KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBtZXRob2QtZGVjb3JhdG9yIGZhY3RvcnkgdXNpbmcgdGhlIHtAbGluayBUWVBFLmNoZWNrQWxnb3JpdGhtIH0gdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyB7QGxpbmsgREJDIH0gaXMgZnVsZmlsbGVkXG4gICAgICogYnkgdGhlIHRhZ2dlZCBtZXRob2QncyByZXR1cm52YWx1ZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0eXBlXHRTZWUge0BsaW5rIFRZUEUuY2hlY2tBbGdvcml0aG0gfS5cbiAgICAgKiBAcGFyYW0gcGF0aFx0QSA6Oi1zZXBhcmF0ZWQgbGlzdCBvZiBkb3R0ZWQgcGF0aHMgdG8gY2hlY2suIEVhY2ggcGF0aCBwb2ludHMgdG8gYSBwcm9wZXJ0eSB3aXRoaW4gdGhlIHBhcmFtZXRlciB2YWx1ZS5cbiAgICAgKiBcdFx0XHRcdFVuZGVmaW5lZCBwcm9wZXJ0aWVzIGFyZSBza2lwcGVkLiBTZWUge0BsaW5rIERCQy5kZWNQcmVjb25kaXRpb24gfS5cbiAgICAgKiBAcGFyYW0gZGJjXHRTZWUge0BsaW5rIERCQy5kZWNQb3N0Y29uZGl0aW9uIH0uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBTZWUge0BsaW5rIERCQy5kZWNQb3N0Y29uZGl0aW9uIH0uICovXG4gICAgc3RhdGljIFBPU1QodHlwZSwgcGF0aCA9IHVuZGVmaW5lZCwgaGludCA9IHVuZGVmaW5lZCwgZGJjID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBEQkMuY3JlYXRlUE9TVChUWVBFLmNoZWNrQWxnb3JpdGhtLCBbdHlwZV0sIGRiYywgcGF0aCwgaGludCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgZmllbGQtZGVjb3JhdG9yIGZhY3RvcnkgdXNpbmcgdGhlIHtAbGluayBUWVBFLmNoZWNrQWxnb3JpdGhtIH0gdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyB7QGxpbmsgREJDIH0gaXMgZnVsZmlsbGVkXG4gICAgICogYnkgdGhlIHRhZ2dlZCBmaWVsZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0eXBlXHRTZWUge0BsaW5rIFRZUEUuY2hlY2tBbGdvcml0aG0gfS5cbiAgICAgKiBAcGFyYW0gcGF0aFx0QSA6Oi1zZXBhcmF0ZWQgbGlzdCBvZiBkb3R0ZWQgcGF0aHMgdG8gY2hlY2suIEVhY2ggcGF0aCBwb2ludHMgdG8gYSBwcm9wZXJ0eSB3aXRoaW4gdGhlIHBhcmFtZXRlciB2YWx1ZS5cbiAgICAgKiBcdFx0XHRcdFVuZGVmaW5lZCBwcm9wZXJ0aWVzIGFyZSBza2lwcGVkLiBTZWUge0BsaW5rIERCQy5kZWNQcmVjb25kaXRpb24gfS5cbiAgICAgKiBAcGFyYW0gZGJjXHRTZWUge0BsaW5rIERCQy5kZWNJbnZhcmlhbnQgfS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFNlZSB7QGxpbmsgREJDLmRlY0ludmFyaWFudCB9LiAqL1xuICAgIHN0YXRpYyBJTlZBUklBTlQodHlwZSwgcGF0aCA9IHVuZGVmaW5lZCwgaGludCA9IHVuZGVmaW5lZCwgZGJjID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBEQkMuY3JlYXRlSU5WQVJJQU5UKFRZUEUsIFt0eXBlXSwgZGJjLCBwYXRoLCBoaW50KTtcbiAgICB9XG4gICAgLy8gI2VuZHJlZ2lvbiBDb25kaXRpb24gY2hlY2tpbmcuXG4gICAgLy8gI3JlZ2lvbiBSZWZlcmVuY2VkIENvbmRpdGlvbiBjaGVja2luZy5cbiAgICAvL1xuICAgIC8vIEZvciB1c2FnZSBpbiBkeW5hbWljIHNjZW5hcmlvcyAobGlrZSB3aXRoIEFFLURCQykuXG4gICAgLy9cbiAgICAvKipcbiAgICAgKiBJbnZva2VzIHRoZSB7QGxpbmsgVFlQRS5jaGVja0FsZ29yaXRobSB9IHBhc3NpbmcgdGhlIHZhbHVlICoqdG9DaGVjayoqIGFuZCB0aGUge0BsaW5rIFRZUEUudHlwZSB9IC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b0NoZWNrIFNlZSB7QGxpbmsgVFlQRS5jaGVja0FsZ29yaXRobSB9LlxuICAgICAqXG4gICAgICogQHJldHVybnMgU2VlIHtAbGluayBUWVBFLmNoZWNrQWxnb3JpdGhtfS4gKi9cbiAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IDxleHBsYW5hdGlvbj5cbiAgICBjaGVjayh0b0NoZWNrKSB7XG4gICAgICAgIHJldHVybiBUWVBFLmNoZWNrQWxnb3JpdGhtKHRvQ2hlY2ssIHRoaXMudHlwZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZXMgdGhlIHtAbGluayBUWVBFLmNoZWNrQWxnb3JpdGhtIH0gcGFzc2luZyB0aGUgdmFsdWUgKip0b0NoZWNrKiogYW5kIHRoZSB7QGxpbmsgVFlQRS50eXBlIH0gLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRvQ2hlY2tcdFNlZSB7QGxpbmsgVFlQRS5jaGVja0FsZ29yaXRobSB9LlxuICAgICAqIEBwYXJhbSB0eXBlXHRcdFNlZSB7QGxpbmsgVFlQRS5jaGVja0FsZ29yaXRobSB9LlxuICAgICAqIEBwYXJhbSBoaW50XHRcdEFuIG9wdGlvbmFsIHtAbGluayBzdHJpbmcgfSBwcm92aWRpbmcgZXh0cmEgaW5mb3JtYXRpb24gaW4gY2FzZSBvZiBhbiBpbmZyaW5nZW1lbnQuXG4gICAgICogQHBhcmFtIGlkXHRcdEEge0BsaW5rIHN0cmluZyB9IGlkZW50aWZ5aW5nIHRoaXMge0BsaW5rIFRZUEUgfSB2aWEgdGhlIHtAbGluayBEQkMuSW5mcmluZ2VtZW50IH0tTWVzc2FnZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSAqKkNBTkRJREFURSoqICoqdG9DaGVjayoqIGRvZXNuJ3QgZnVsZmlsbCB0aGlzIHtAbGluayBUWVBFIH0uXG4gICAgICpcbiAgICAgKiBAdGhyb3dzIEEge0BsaW5rIERCQy5JbmZyaW5nZW1lbnQgfSBpZiB0aGUgKipDQU5ESURBVEUqKiAqKnRvQ2hlY2sqKiBkb2VzIG5vdCBmdWxmaWxsIHRoaXMge0BsaW5rIERFRklORUQgfS4gKi9cbiAgICBzdGF0aWMgdHNDaGVjayh0b0NoZWNrLCB0eXBlLCBoaW50ID0gdW5kZWZpbmVkLCBpZCA9IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBUWVBFLmNoZWNrQWxnb3JpdGhtKHRvQ2hlY2ssIHR5cGUpO1xuICAgICAgICBpZiAocmVzdWx0ID09PSB0cnVlKSB7XG4gICAgICAgICAgICByZXR1cm4gdG9DaGVjaztcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgREJDLkluZnJpbmdlbWVudChgJHtpZCA/IGAoJHtpZH0pIGAgOiBcIlwifSR7cmVzdWx0fSR7aGludCA/IGAg4pyoICR7aGludH0g4pyoYCA6IFwiXCJ9YCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgdGhpcyB7QGxpbmsgVFlQRSB9IGJ5IHNldHRpbmcgdGhlIHByb3RlY3RlZCBwcm9wZXJ0eSB7QGxpbmsgVFlQRS50eXBlIH0gdXNlZCBieSB7QGxpbmsgVFlQRS5jaGVjayB9LlxuICAgICAqXG4gICAgICogQHBhcmFtIHR5cGUgU2VlIHtAbGluayBUWVBFLmNoZWNrIH0uICovXG4gICAgY29uc3RydWN0b3IodHlwZSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIH1cbn1cbiIsIi8vIFRoZSBtb2R1bGUgY2FjaGVcbnZhciBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX18gPSB7fTtcblxuLy8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbmZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG5cdHZhciBjYWNoZWRNb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuXHRpZiAoY2FjaGVkTW9kdWxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gY2FjaGVkTW9kdWxlLmV4cG9ydHM7XG5cdH1cblx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcblx0dmFyIG1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0gPSB7XG5cdFx0Ly8gbm8gbW9kdWxlLmlkIG5lZWRlZFxuXHRcdC8vIG5vIG1vZHVsZS5sb2FkZWQgbmVlZGVkXG5cdFx0ZXhwb3J0czoge31cblx0fTtcblxuXHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cblx0aWYgKCEobW9kdWxlSWQgaW4gX193ZWJwYWNrX21vZHVsZXNfXykpIHtcblx0XHRkZWxldGUgX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXTtcblx0XHR2YXIgZSA9IG5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIgKyBtb2R1bGVJZCArIFwiJ1wiKTtcblx0XHRlLmNvZGUgPSAnTU9EVUxFX05PVF9GT1VORCc7XG5cdFx0dGhyb3cgZTtcblx0fVxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXShtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbiIsIi8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb25zIGZvciBoYXJtb255IGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uZCA9IChleHBvcnRzLCBkZWZpbml0aW9uKSA9PiB7XG5cdGZvcih2YXIga2V5IGluIGRlZmluaXRpb24pIHtcblx0XHRpZihfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZGVmaW5pdGlvbiwga2V5KSAmJiAhX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIGtleSkpIHtcblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBrZXksIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBkZWZpbml0aW9uW2tleV0gfSk7XG5cdFx0fVxuXHR9XG59OyIsIl9fd2VicGFja19yZXF1aXJlX18ubyA9IChvYmosIHByb3ApID0+IChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKSkiLCIvLyBkZWZpbmUgX19lc01vZHVsZSBvbiBleHBvcnRzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLnIgPSAoZXhwb3J0cykgPT4ge1xuXHRpZih0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wudG9TdHJpbmdUYWcpIHtcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgU3ltYm9sLnRvU3RyaW5nVGFnLCB7IHZhbHVlOiAnTW9kdWxlJyB9KTtcblx0fVxuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xufTsiLCJ2YXIgX19kZWNvcmF0ZSA9ICh0aGlzICYmIHRoaXMuX19kZWNvcmF0ZSkgfHwgZnVuY3Rpb24gKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKSB7XG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xuICAgIGVsc2UgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGlmIChkID0gZGVjb3JhdG9yc1tpXSkgciA9IChjIDwgMyA/IGQocikgOiBjID4gMyA/IGQodGFyZ2V0LCBrZXksIHIpIDogZCh0YXJnZXQsIGtleSkpIHx8IHI7XG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcbn07XG52YXIgX19tZXRhZGF0YSA9ICh0aGlzICYmIHRoaXMuX19tZXRhZGF0YSkgfHwgZnVuY3Rpb24gKGssIHYpIHtcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEoaywgdik7XG59O1xudmFyIF9fcGFyYW0gPSAodGhpcyAmJiB0aGlzLl9fcGFyYW0pIHx8IGZ1bmN0aW9uIChwYXJhbUluZGV4LCBkZWNvcmF0b3IpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cbn07XG5pbXBvcnQgeyBEQkMgfSBmcm9tIFwiLi9EQkNcIjtcbmltcG9ydCB7IEFFIH0gZnJvbSBcIi4vREJDL0FFXCI7XG5pbXBvcnQgeyBHUkVBVEVSIH0gZnJvbSBcIi4vREJDL0NPTVBBUklTT04vR1JFQVRFUlwiO1xuaW1wb3J0IHsgR1JFQVRFUl9PUl9FUVVBTCB9IGZyb20gXCIuL0RCQy9DT01QQVJJU09OL0dSRUFURVJfT1JfRVFVQUxcIjtcbmltcG9ydCB7IExFU1MgfSBmcm9tIFwiLi9EQkMvQ09NUEFSSVNPTi9MRVNTXCI7XG5pbXBvcnQgeyBMRVNTX09SX0VRVUFMIH0gZnJvbSBcIi4vREJDL0NPTVBBUklTT04vTEVTU19PUl9FUVVBTFwiO1xuaW1wb3J0IHsgRVEgfSBmcm9tIFwiLi9EQkMvRVFcIjtcbmltcG9ydCB7IERJRkZFUkVOVCB9IGZyb20gXCIuL0RCQy9FUS9ESUZGRVJFTlRcIjtcbmltcG9ydCB7IElOU1RBTkNFIH0gZnJvbSBcIi4vREJDL0lOU1RBTkNFXCI7XG5pbXBvcnQgeyBSRUdFWCB9IGZyb20gXCIuL0RCQy9SRUdFWFwiO1xuaW1wb3J0IHsgVFlQRSB9IGZyb20gXCIuL0RCQy9UWVBFXCI7XG4vKiogRGVtb25zdHJhdGl2ZSB1c2Ugb2YgKipEKiplc2lnbiAqKkIqKnkgKipDKipvbnRyYWN0IERlY29yYXRvcnMgKi9cbmV4cG9ydCBjbGFzcyBEZW1vIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgLy8gI3JlZ2lvbiBDaGVjayBQcm9wZXJ0eSBEZWNvcmF0b3JcbiAgICAgICAgdGhpcy50ZXN0UHJvcGVydHkgPSBcImFcIjtcbiAgICAgICAgLy8gI2VuZHJlZ2lvbiBDaGVjayBTdGF0aWMgTWV0aG9kIHdpdGggUGFyYW12YWx1ZVByb3ZpZGVyXG4gICAgfVxuICAgIC8vICNlbmRyZWdpb24gQ2hlY2sgUHJvcGVydHkgRGVjb3JhdG9yXG4gICAgLy8gI3JlZ2lvbiBDaGVjayBQYXJhbWV0ZXIuICYgUmV0dXJudmFsdWUgRGVjb3JhdG9yXG4gICAgdGVzdFBhcmFtdmFsdWVBbmRSZXR1cm52YWx1ZShhKSB7XG4gICAgICAgIHJldHVybiBgeHh4eCR7YX1gO1xuICAgIH1cbiAgICAvLyAjZW5kcmVnaW9uIENoZWNrIFBhcmFtZXRlci4gJiBSZXR1cm52YWx1ZSBEZWNvcmF0b3JcbiAgICAvLyAjcmVnaW9uIENoZWNrIFJldHVybnZhbHVlIERlY29yYXRvclxuICAgIHRlc3RSZXR1cm52YWx1ZShhKSB7XG4gICAgICAgIHJldHVybiBhO1xuICAgIH1cbiAgICAvLyAjZW5kcmVnaW9uIENoZWNrIFJldHVybnZhbHVlIERlY29yYXRvclxuICAgIC8vICNyZWdpb24gQ2hlY2sgRVEtREJDICYgUGF0aCB0byBwcm9wZXJ0eSBvZiBQYXJhbWV0ZXItdmFsdWVcbiAgICB0ZXN0RVFBbmRQYXRoKG8pIHsgfVxuICAgIC8vICNlbmRyZWdpb24gQ2hlY2sgRVEtREJDICYgUGF0aCB0byBwcm9wZXJ0eSBvZiBQYXJhbWV0ZXItdmFsdWVcbiAgICAvLyAjcmVnaW9uIENoZWNrIEVRLURCQyAmIFBhdGggdG8gcHJvcGVydHkgb2YgUGFyYW1ldGVyLXZhbHVlIHdpdGggSW52ZXJzaW9uXG4gICAgdGVzdEVRQW5kUGF0aFdpdGhJbnZlcnNpb24obykgeyB9XG4gICAgLy8gI2VuZHJlZ2lvbiBDaGVjayBFUS1EQkMgJiBQYXRoIHRvIHByb3BlcnR5IG9mIFBhcmFtZXRlci12YWx1ZSB3aXRoIEludmVyc2lvblxuICAgIC8vICNyZWdpb24gQ2hlY2sgVFlQRVxuICAgIHRlc3RUWVBFKG8pIHsgfVxuICAgIC8vICNlbmRyZWdpb24gQ2hlY2sgVFlQRVxuICAgIC8vICNyZWdpb24gQ2hlY2sgQUVcbiAgICB0ZXN0QUUoeCkgeyB9XG4gICAgLy8gI2VuZHJlZ2lvbiBDaGVjayBBRVxuICAgIC8vICNyZWdpb24gQ2hlY2sgUkVHRVggd2l0aCBBRVxuICAgIHRlc3RSRUdFWFdpdGhBRSh4KSB7IH1cbiAgICAvLyAjZW5kcmVnaW9uIENoZWNrIFJFR0VYIHdpdGggQUVcbiAgICAvLyAjcmVnaW9uIENoZWNrIElOU1RBTkNFXG4gICAgdGVzdElOU1RBTkNFKGNhbmRpZGF0ZSkgeyB9XG4gICAgLy8gI2VuZHJlZ2lvbiBDaGVjayBJTlNUQU5DRVxuICAgIC8vICNyZWdpb24gQ2hlY2sgQUUgUmFuZ2VcbiAgICB0ZXN0QUVSYW5nZSh4KSB7IH1cbiAgICAvLyAjZW5kcmVnaW9uIENoZWNrIEFFIFJhbmdlXG4gICAgLy8gI3JlZ2lvbiBDaGVjayBBRSBJbmRleFxuICAgIHRlc3RBRUluZGV4KHgpIHsgfVxuICAgIC8vICNlbmRyZWdpb24gQ2hlY2sgQUUgSW5kZXhcbiAgICAvLyAjcmVnaW9uIENoZWNrIENvbXBhcmlzb25cbiAgICB0ZXN0R1JFQVRFUihpbnB1dCkgeyB9XG4gICAgdGVzdEdSRUFURVJfT1JfRVFVQUwoaW5wdXQpIHsgfVxuICAgIHRlc3RMRVNTKGlucHV0KSB7IH1cbiAgICB0ZXN0TEVTU19PUl9FUVVBTChpbnB1dCkgeyB9XG4gICAgdGVzdERJRkZFUkVOVChpbnB1dCkgeyB9XG4gICAgLy8gI2VuZHJlZ2lvbiBDaGVjayBDb21wYXJpc29uXG4gICAgLy8gI3JlZ2lvbiBDaGVjayBTdGF0aWMgTWV0aG9kIHdpdGggUGFyYW12YWx1ZVByb3ZpZGVyXG4gICAgc3RhdGljIHRlc3RTdGF0aWNNZXRob2QobWVzc2FnZSwgY291bnQpIHtcbiAgICAgICAgcmV0dXJuIGAke21lc3NhZ2V9IHJlcGVhdGVkICR7Y291bnR9IHRpbWVzYDtcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICBSRUdFWC5JTlZBUklBTlQoL15hJC8pLFxuICAgIF9fbWV0YWRhdGEoXCJkZXNpZ246dHlwZVwiLCBPYmplY3QpXG5dLCBEZW1vLnByb3RvdHlwZSwgXCJ0ZXN0UHJvcGVydHlcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIFJFR0VYLlBPU1QoL154eHh4LiokLyksXG4gICAgREJDLlBhcmFtdmFsdWVQcm92aWRlcixcbiAgICBfX3BhcmFtKDAsIFJFR0VYLlBSRSgvaG9sbGEqL2cpKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnR5cGVcIiwgRnVuY3Rpb24pLFxuICAgIF9fbWV0YWRhdGEoXCJkZXNpZ246cGFyYW10eXBlc1wiLCBbU3RyaW5nXSksXG4gICAgX19tZXRhZGF0YShcImRlc2lnbjpyZXR1cm50eXBlXCIsIFN0cmluZylcbl0sIERlbW8ucHJvdG90eXBlLCBcInRlc3RQYXJhbXZhbHVlQW5kUmV0dXJudmFsdWVcIiwgbnVsbCk7XG5fX2RlY29yYXRlKFtcbiAgICBSRUdFWC5QT1NUKC9eeHh4eC4qJC8pLFxuICAgIF9fbWV0YWRhdGEoXCJkZXNpZ246dHlwZVwiLCBGdW5jdGlvbiksXG4gICAgX19tZXRhZGF0YShcImRlc2lnbjpwYXJhbXR5cGVzXCIsIFtTdHJpbmddKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnJldHVybnR5cGVcIiwgU3RyaW5nKVxuXSwgRGVtby5wcm90b3R5cGUsIFwidGVzdFJldHVybnZhbHVlXCIsIG51bGwpO1xuX19kZWNvcmF0ZShbXG4gICAgREJDLlBhcmFtdmFsdWVQcm92aWRlcixcbiAgICBfX3BhcmFtKDAsIEVRLlBSRShcIlNFTEVDVFwiLCBmYWxzZSwgXCJ0YWdOYW1lXCIpKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnR5cGVcIiwgRnVuY3Rpb24pLFxuICAgIF9fbWV0YWRhdGEoXCJkZXNpZ246cGFyYW10eXBlc1wiLCBbSFRNTEVsZW1lbnRdKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnJldHVybnR5cGVcIiwgdm9pZCAwKVxuXSwgRGVtby5wcm90b3R5cGUsIFwidGVzdEVRQW5kUGF0aFwiLCBudWxsKTtcbl9fZGVjb3JhdGUoW1xuICAgIERCQy5QYXJhbXZhbHVlUHJvdmlkZXIsXG4gICAgX19wYXJhbSgwLCBFUS5QUkUoXCJTRUxFQ1RcIiwgdHJ1ZSwgXCJ0YWdOYW1lXCIpKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnR5cGVcIiwgRnVuY3Rpb24pLFxuICAgIF9fbWV0YWRhdGEoXCJkZXNpZ246cGFyYW10eXBlc1wiLCBbSFRNTEVsZW1lbnRdKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnJldHVybnR5cGVcIiwgdm9pZCAwKVxuXSwgRGVtby5wcm90b3R5cGUsIFwidGVzdEVRQW5kUGF0aFdpdGhJbnZlcnNpb25cIiwgbnVsbCk7XG5fX2RlY29yYXRlKFtcbiAgICBEQkMuUGFyYW12YWx1ZVByb3ZpZGVyLFxuICAgIF9fcGFyYW0oMCwgVFlQRS5QUkUoXCJzdHJpbmdcIikpLFxuICAgIF9fbWV0YWRhdGEoXCJkZXNpZ246dHlwZVwiLCBGdW5jdGlvbiksXG4gICAgX19tZXRhZGF0YShcImRlc2lnbjpwYXJhbXR5cGVzXCIsIFtPYmplY3RdKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnJldHVybnR5cGVcIiwgdm9pZCAwKVxuXSwgRGVtby5wcm90b3R5cGUsIFwidGVzdFRZUEVcIiwgbnVsbCk7XG5fX2RlY29yYXRlKFtcbiAgICBEQkMuUGFyYW12YWx1ZVByb3ZpZGVyLFxuICAgIF9fcGFyYW0oMCwgQUUuUFJFKFtuZXcgVFlQRShcInN0cmluZ1wiKV0pKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnR5cGVcIiwgRnVuY3Rpb24pLFxuICAgIF9fbWV0YWRhdGEoXCJkZXNpZ246cGFyYW10eXBlc1wiLCBbQXJyYXldKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnJldHVybnR5cGVcIiwgdm9pZCAwKVxuXSwgRGVtby5wcm90b3R5cGUsIFwidGVzdEFFXCIsIG51bGwpO1xuX19kZWNvcmF0ZShbXG4gICAgREJDLlBhcmFtdmFsdWVQcm92aWRlcixcbiAgICBfX3BhcmFtKDAsIEFFLlBSRShuZXcgUkVHRVgoL14oP2k6KE5PVyl8KFsrLV1cXGQrW2RteV0pKSQvaSkpKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnR5cGVcIiwgRnVuY3Rpb24pLFxuICAgIF9fbWV0YWRhdGEoXCJkZXNpZ246cGFyYW10eXBlc1wiLCBbQXJyYXldKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnJldHVybnR5cGVcIiwgdm9pZCAwKVxuXSwgRGVtby5wcm90b3R5cGUsIFwidGVzdFJFR0VYV2l0aEFFXCIsIG51bGwpO1xuX19kZWNvcmF0ZShbXG4gICAgREJDLlBhcmFtdmFsdWVQcm92aWRlclxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogVGVzdFxuICAgICxcbiAgICBfX3BhcmFtKDAsIElOU1RBTkNFLlBSRShEYXRlKSksXG4gICAgX19tZXRhZGF0YShcImRlc2lnbjp0eXBlXCIsIEZ1bmN0aW9uKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnBhcmFtdHlwZXNcIiwgW09iamVjdF0pLFxuICAgIF9fbWV0YWRhdGEoXCJkZXNpZ246cmV0dXJudHlwZVwiLCB2b2lkIDApXG5dLCBEZW1vLnByb3RvdHlwZSwgXCJ0ZXN0SU5TVEFOQ0VcIiwgbnVsbCk7XG5fX2RlY29yYXRlKFtcbiAgICBEQkMuUGFyYW12YWx1ZVByb3ZpZGVyLFxuICAgIF9fcGFyYW0oMCwgQUUuUFJFKFtuZXcgVFlQRShcInN0cmluZ1wiKSwgbmV3IFJFR0VYKC9eYWJjJC8pXSwgMSwgMikpLFxuICAgIF9fbWV0YWRhdGEoXCJkZXNpZ246dHlwZVwiLCBGdW5jdGlvbiksXG4gICAgX19tZXRhZGF0YShcImRlc2lnbjpwYXJhbXR5cGVzXCIsIFtBcnJheV0pLFxuICAgIF9fbWV0YWRhdGEoXCJkZXNpZ246cmV0dXJudHlwZVwiLCB2b2lkIDApXG5dLCBEZW1vLnByb3RvdHlwZSwgXCJ0ZXN0QUVSYW5nZVwiLCBudWxsKTtcbl9fZGVjb3JhdGUoW1xuICAgIERCQy5QYXJhbXZhbHVlUHJvdmlkZXIsXG4gICAgX19wYXJhbSgwLCBBRS5QUkUoW25ldyBUWVBFKFwic3RyaW5nXCIpLCBuZXcgUkVHRVgoL15hYmMkLyldLCAxKSksXG4gICAgX19tZXRhZGF0YShcImRlc2lnbjp0eXBlXCIsIEZ1bmN0aW9uKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnBhcmFtdHlwZXNcIiwgW0FycmF5XSksXG4gICAgX19tZXRhZGF0YShcImRlc2lnbjpyZXR1cm50eXBlXCIsIHZvaWQgMClcbl0sIERlbW8ucHJvdG90eXBlLCBcInRlc3RBRUluZGV4XCIsIG51bGwpO1xuX19kZWNvcmF0ZShbXG4gICAgREJDLlBhcmFtdmFsdWVQcm92aWRlcixcbiAgICBfX3BhcmFtKDAsIEdSRUFURVIuUFJFKDIpKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnR5cGVcIiwgRnVuY3Rpb24pLFxuICAgIF9fbWV0YWRhdGEoXCJkZXNpZ246cGFyYW10eXBlc1wiLCBbTnVtYmVyXSksXG4gICAgX19tZXRhZGF0YShcImRlc2lnbjpyZXR1cm50eXBlXCIsIHZvaWQgMClcbl0sIERlbW8ucHJvdG90eXBlLCBcInRlc3RHUkVBVEVSXCIsIG51bGwpO1xuX19kZWNvcmF0ZShbXG4gICAgREJDLlBhcmFtdmFsdWVQcm92aWRlcixcbiAgICBfX3BhcmFtKDAsIEdSRUFURVJfT1JfRVFVQUwuUFJFKDIpKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnR5cGVcIiwgRnVuY3Rpb24pLFxuICAgIF9fbWV0YWRhdGEoXCJkZXNpZ246cGFyYW10eXBlc1wiLCBbTnVtYmVyXSksXG4gICAgX19tZXRhZGF0YShcImRlc2lnbjpyZXR1cm50eXBlXCIsIHZvaWQgMClcbl0sIERlbW8ucHJvdG90eXBlLCBcInRlc3RHUkVBVEVSX09SX0VRVUFMXCIsIG51bGwpO1xuX19kZWNvcmF0ZShbXG4gICAgREJDLlBhcmFtdmFsdWVQcm92aWRlcixcbiAgICBfX3BhcmFtKDAsIExFU1MuUFJFKDIwKSksXG4gICAgX19tZXRhZGF0YShcImRlc2lnbjp0eXBlXCIsIEZ1bmN0aW9uKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnBhcmFtdHlwZXNcIiwgW051bWJlcl0pLFxuICAgIF9fbWV0YWRhdGEoXCJkZXNpZ246cmV0dXJudHlwZVwiLCB2b2lkIDApXG5dLCBEZW1vLnByb3RvdHlwZSwgXCJ0ZXN0TEVTU1wiLCBudWxsKTtcbl9fZGVjb3JhdGUoW1xuICAgIERCQy5QYXJhbXZhbHVlUHJvdmlkZXIsXG4gICAgX19wYXJhbSgwLCBMRVNTX09SX0VRVUFMLlBSRSgyMCkpLFxuICAgIF9fbWV0YWRhdGEoXCJkZXNpZ246dHlwZVwiLCBGdW5jdGlvbiksXG4gICAgX19tZXRhZGF0YShcImRlc2lnbjpwYXJhbXR5cGVzXCIsIFtOdW1iZXJdKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnJldHVybnR5cGVcIiwgdm9pZCAwKVxuXSwgRGVtby5wcm90b3R5cGUsIFwidGVzdExFU1NfT1JfRVFVQUxcIiwgbnVsbCk7XG5fX2RlY29yYXRlKFtcbiAgICBEQkMuUGFyYW12YWx1ZVByb3ZpZGVyLFxuICAgIF9fcGFyYW0oMCwgRElGRkVSRU5ULlBSRSgyMCkpLFxuICAgIF9fbWV0YWRhdGEoXCJkZXNpZ246dHlwZVwiLCBGdW5jdGlvbiksXG4gICAgX19tZXRhZGF0YShcImRlc2lnbjpwYXJhbXR5cGVzXCIsIFtOdW1iZXJdKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnJldHVybnR5cGVcIiwgdm9pZCAwKVxuXSwgRGVtby5wcm90b3R5cGUsIFwidGVzdERJRkZFUkVOVFwiLCBudWxsKTtcbl9fZGVjb3JhdGUoW1xuICAgIERCQy5QYXJhbXZhbHVlUHJvdmlkZXIsXG4gICAgX19wYXJhbSgwLCBUWVBFLlBSRShcInN0cmluZ1wiKSksXG4gICAgX19wYXJhbSgxLCBUWVBFLlBSRShcIm51bWJlclwiKSksXG4gICAgX19tZXRhZGF0YShcImRlc2lnbjp0eXBlXCIsIEZ1bmN0aW9uKSxcbiAgICBfX21ldGFkYXRhKFwiZGVzaWduOnBhcmFtdHlwZXNcIiwgW1N0cmluZywgTnVtYmVyXSksXG4gICAgX19tZXRhZGF0YShcImRlc2lnbjpyZXR1cm50eXBlXCIsIFN0cmluZylcbl0sIERlbW8sIFwidGVzdFN0YXRpY01ldGhvZFwiLCBudWxsKTtcbmNvbnN0IGRlbW8gPSBuZXcgRGVtbygpO1xudHJ5IHtcbiAgICBkZW1vLnRlc3RQcm9wZXJ0eSA9IFwiYWJkXCI7XG59XG5jYXRjaCAoWCkge1xuICAgIGNvbnNvbGUubG9nKFwi4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyEXCIpO1xuICAgIGNvbnNvbGUubG9nKFwiSU5WQVJJQU5UIEluZnJpbmdlbWVudFwiLCBcIk9LXCIpO1xuICAgIGNvbnNvbGUubG9nKFgpO1xuICAgIGNvbnNvbGUubG9nKFwiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXCIpO1xufVxuZGVtby50ZXN0UHJvcGVydHkgPSBcImFcIjtcbmNvbnNvbGUubG9nKFwi4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyEXCIpO1xuY29uc29sZS5sb2coXCJJTlZBUklBTlQgT0tcIik7XG5jb25zb2xlLmxvZyhcIl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXlwiKTtcbmRlbW8udGVzdFBhcmFtdmFsdWVBbmRSZXR1cm52YWx1ZShcImhvbGxhXCIpO1xuY29uc29sZS5sb2coXCLijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijIRcIik7XG5jb25zb2xlLmxvZyhcIlBBUkFNRVRFUi0gJiBSRVRVUk5WQUxVRSBPS1wiKTtcbmNvbnNvbGUubG9nKFwiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXCIpO1xudHJ5IHtcbiAgICBkZW1vLnRlc3RQYXJhbXZhbHVlQW5kUmV0dXJudmFsdWUoXCJ5eXl5XCIpO1xufVxuY2F0Y2ggKFgpIHtcbiAgICBjb25zb2xlLmxvZyhcIuKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhFwiKTtcbiAgICBjb25zb2xlLmxvZyhcIlBBUkFNRVRFUi0gJiBSRVRVUk5WQUxVRSBJbmZyaW5nZW1lbnRcIiwgXCJPS1wiKTtcbiAgICBjb25zb2xlLmxvZyhYKTtcbiAgICBjb25zb2xlLmxvZyhcIl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXlwiKTtcbn1cbmRlbW8udGVzdFJldHVybnZhbHVlKFwieHh4eFwiKTtcbmNvbnNvbGUubG9nKFwi4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyEXCIpO1xuY29uc29sZS5sb2coXCJSRVRVUk5WQUxVRSBPS1wiKTtcbmNvbnNvbGUubG9nKFwiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXCIpO1xudHJ5IHtcbiAgICBkZW1vLnRlc3RSZXR1cm52YWx1ZShcInl5eXlcIik7XG59XG5jYXRjaCAoWCkge1xuICAgIGNvbnNvbGUubG9nKFwi4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyEXCIpO1xuICAgIGNvbnNvbGUubG9nKFwiUkVUVVJOVkFMVUUgSW5mcmluZ2VtZW50XCIsIFwiT0tcIik7XG4gICAgY29uc29sZS5sb2coWCk7XG4gICAgY29uc29sZS5sb2coXCJeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5cIik7XG59XG5kZW1vLnRlc3RFUUFuZFBhdGgoZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNlbGVjdFwiKSk7XG5jb25zb2xlLmxvZyhcIuKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhFwiKTtcbmNvbnNvbGUubG9nKFwiRVEgd2l0aCBQYXRoIEluZnJpbmdlbWVudCBPS1wiKTtcbmNvbnNvbGUubG9nKFwiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXCIpO1xudHJ5IHtcbiAgICBkZW1vLnRlc3RFUUFuZFBhdGhXaXRoSW52ZXJzaW9uKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzZWxlY3RcIikpO1xufVxuY2F0Y2ggKFgpIHtcbiAgICBjb25zb2xlLmxvZyhcIuKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhFwiKTtcbiAgICBjb25zb2xlLmxvZyhcIkVRIHdpdGggUGF0aCBhbmQgSW52ZXJzaW9uIEluZnJpbmdlbWVudCBPS1wiKTtcbiAgICBjb25zb2xlLmxvZyhYKTtcbiAgICBjb25zb2xlLmxvZyhcIl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXlwiKTtcbn1cbmRlbW8udGVzdFRZUEUoXCJ4XCIpO1xuY29uc29sZS5sb2coXCLijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijIRcIik7XG5jb25zb2xlLmxvZyhcIlRZUEUgT0tcIik7XG5jb25zb2xlLmxvZyhcIl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXlwiKTtcbnRyeSB7XG4gICAgZGVtby50ZXN0VFlQRSgwKTtcbn1cbmNhdGNoIChYKSB7XG4gICAgY29uc29sZS5sb2coXCLijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijIRcIik7XG4gICAgY29uc29sZS5sb2coXCJUWVBFIEluZnJpbmdlbWVudCBPS1wiKTtcbiAgICBjb25zb2xlLmxvZyhYKTtcbiAgICBjb25zb2xlLmxvZyhcIl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXlwiKTtcbn1cbmRlbW8udGVzdEFFKFtcIjExXCIsIFwiMTBcIiwgXCJiXCJdKTtcbmNvbnNvbGUubG9nKFwi4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyEXCIpO1xuY29uc29sZS5sb2coXCJBRSBPS1wiKTtcbmNvbnNvbGUubG9nKFwiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXCIpO1xudHJ5IHtcbiAgICBkZW1vLnRlc3RBRShbXCIxMVwiLCAxMSwgXCJiXCJdKTtcbn1cbmNhdGNoIChYKSB7XG4gICAgY29uc29sZS5sb2coXCLijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijIRcIik7XG4gICAgY29uc29sZS5sb2coXCJBRSBJbmZyaW5nZW1lbnQgT0tcIik7XG4gICAgY29uc29sZS5sb2coWCk7XG4gICAgY29uc29sZS5sb2coXCJeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5cIik7XG59XG5kZW1vLnRlc3RSRUdFWFdpdGhBRShbXCIrMWRcIiwgXCJOT1dcIiwgXCItMTB5XCJdKTtcbmNvbnNvbGUubG9nKFwi4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyEXCIpO1xuY29uc29sZS5sb2coXCJSRUdFWCB3aXRoIEFFIE9LXCIpO1xuY29uc29sZS5sb2coXCJeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5cIik7XG50cnkge1xuICAgIGRlbW8udGVzdFJFR0VYV2l0aEFFKFtcIisxZFwiLCBcIis1ZFwiLCBcIi14MTB5XCJdKTtcbn1cbmNhdGNoIChYKSB7XG4gICAgY29uc29sZS5sb2coXCLijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijIRcIik7XG4gICAgY29uc29sZS5sb2coXCJSRUdFWCB3aXRoIEFFIEluZnJpbmdlbWVudCBPS1wiKTtcbiAgICBjb25zb2xlLmxvZyhYKTtcbiAgICBjb25zb2xlLmxvZyhcIl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXlwiKTtcbn1cbmRlbW8udGVzdElOU1RBTkNFKG5ldyBEYXRlKCkpO1xuY29uc29sZS5sb2coXCLijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijIRcIik7XG5jb25zb2xlLmxvZyhcIklOU1RBTkNFIE9LXCIpO1xuY29uc29sZS5sb2coXCJeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5cIik7XG50cnkge1xuICAgIGRlbW8udGVzdElOU1RBTkNFKGRlbW8pO1xufVxuY2F0Y2ggKFgpIHtcbiAgICBjb25zb2xlLmxvZyhcIuKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhFwiKTtcbiAgICBjb25zb2xlLmxvZyhcIklOU1RBTkNFIEluZnJpbmdlbWVudCBPS1wiKTtcbiAgICBjb25zb2xlLmxvZyhYKTtcbiAgICBjb25zb2xlLmxvZyhcIl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXlwiKTtcbn1cbmRlbW8udGVzdEFFUmFuZ2UoWzExLCBcImFiY1wiLCBcImFiY1wiXSk7XG5jb25zb2xlLmxvZyhcIuKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhFwiKTtcbmNvbnNvbGUubG9nKFwiQUUgUmFuZ2UgT0tcIik7XG5jb25zb2xlLmxvZyhcIl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXlwiKTtcbnRyeSB7XG4gICAgZGVtby50ZXN0QUVSYW5nZShbMTEsIFwiYWJjXCIsIC9hL2ddKTtcbn1cbmNhdGNoIChYKSB7XG4gICAgY29uc29sZS5sb2coXCLijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijIRcIik7XG4gICAgY29uc29sZS5sb2coXCJBRSBSYW5nZSBJbmZyaW5nZW1lbnQgT0tcIik7XG4gICAgY29uc29sZS5sb2coWCk7XG4gICAgY29uc29sZS5sb2coXCJeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5cIik7XG59XG5kZW1vLnRlc3RBRUluZGV4KFsxMSwgXCJhYmNcIiwgXCJhYmNcIl0pO1xuY29uc29sZS5sb2coXCLijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijIRcIik7XG5jb25zb2xlLmxvZyhcIkFFIEluZGV4IE9LXCIpO1xuY29uc29sZS5sb2coXCJeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5cIik7XG50cnkge1xuICAgIGRlbW8udGVzdEFFSW5kZXgoW1wiMTFcIiwgMTIsIFwiL2EvZ1wiXSk7XG59XG5jYXRjaCAoWCkge1xuICAgIGNvbnNvbGUubG9nKFwi4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyEXCIpO1xuICAgIGNvbnNvbGUubG9nKFwiQUUgSW5kZXggSW5mcmluZ2VtZW50IE9LXCIpO1xuICAgIGNvbnNvbGUubG9nKFgpO1xuICAgIGNvbnNvbGUubG9nKFwiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXCIpO1xufVxuZGVtby50ZXN0R1JFQVRFUigxMSk7XG5jb25zb2xlLmxvZyhcIuKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhFwiKTtcbmNvbnNvbGUubG9nKFwiR1JFQVRFUiBPS1wiKTtcbmNvbnNvbGUubG9nKFwiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXCIpO1xudHJ5IHtcbiAgICBkZW1vLnRlc3RHUkVBVEVSKDIpO1xufVxuY2F0Y2ggKFgpIHtcbiAgICBjb25zb2xlLmxvZyhcIuKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhFwiKTtcbiAgICBjb25zb2xlLmxvZyhcIkdSRUFURVIgSW5mcmluZ2VtZW50IE9LXCIpO1xuICAgIGNvbnNvbGUubG9nKFgpO1xuICAgIGNvbnNvbGUubG9nKFwiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXCIpO1xufVxuZGVtby50ZXN0R1JFQVRFUl9PUl9FUVVBTCgyKTtcbmNvbnNvbGUubG9nKFwi4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyEXCIpO1xuY29uc29sZS5sb2coXCJHUkVBVEVSX09SX0VRVUFMIE9LXCIpO1xuY29uc29sZS5sb2coXCJeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5cIik7XG50cnkge1xuICAgIGRlbW8udGVzdEdSRUFURVJfT1JfRVFVQUwoMSk7XG59XG5jYXRjaCAoWCkge1xuICAgIGNvbnNvbGUubG9nKFwi4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyEXCIpO1xuICAgIGNvbnNvbGUubG9nKFwiR1JFQVRFUl9PUl9FUVVBTCBJbmZyaW5nZW1lbnQgT0tcIik7XG4gICAgY29uc29sZS5sb2coWCk7XG4gICAgY29uc29sZS5sb2coXCJeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5cIik7XG59XG5kZW1vLnRlc3RMRVNTKDEwKTtcbmNvbnNvbGUubG9nKFwi4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyEXCIpO1xuY29uc29sZS5sb2coXCJMRVNTIE9LXCIpO1xuY29uc29sZS5sb2coXCJeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5cIik7XG50cnkge1xuICAgIGRlbW8udGVzdExFU1MoMjApO1xufVxuY2F0Y2ggKFgpIHtcbiAgICBjb25zb2xlLmxvZyhcIuKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhFwiKTtcbiAgICBjb25zb2xlLmxvZyhcIkxFU1MgSW5mcmluZ2VtZW50IE9LXCIpO1xuICAgIGNvbnNvbGUubG9nKFgpO1xuICAgIGNvbnNvbGUubG9nKFwiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXCIpO1xufVxuZGVtby50ZXN0TEVTU19PUl9FUVVBTCgyMCk7XG5jb25zb2xlLmxvZyhcIuKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhFwiKTtcbmNvbnNvbGUubG9nKFwiTEVTUyBPS1wiKTtcbmNvbnNvbGUubG9nKFwiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXCIpO1xudHJ5IHtcbiAgICBkZW1vLnRlc3RMRVNTX09SX0VRVUFMKDIxKTtcbn1cbmNhdGNoIChYKSB7XG4gICAgY29uc29sZS5sb2coXCLijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijIRcIik7XG4gICAgY29uc29sZS5sb2coXCJMRVNTX09SX0VRVUFMIEluZnJpbmdlbWVudCBPS1wiKTtcbiAgICBjb25zb2xlLmxvZyhYKTtcbiAgICBjb25zb2xlLmxvZyhcIl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXlwiKTtcbn1cbmRlbW8udGVzdERJRkZFUkVOVCgyMSk7XG5jb25zb2xlLmxvZyhcIuKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhFwiKTtcbmNvbnNvbGUubG9nKFwiRElGRkVSRU5UIE9LXCIpO1xuY29uc29sZS5sb2coXCJeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5cIik7XG50cnkge1xuICAgIGRlbW8udGVzdERJRkZFUkVOVCgyMCk7XG59XG5jYXRjaCAoWCkge1xuICAgIGNvbnNvbGUubG9nKFwi4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyEXCIpO1xuICAgIGNvbnNvbGUubG9nKFwiRElGRkVSRU5UIEluZnJpbmdlbWVudCBPS1wiKTtcbiAgICBjb25zb2xlLmxvZyhYKTtcbiAgICBjb25zb2xlLmxvZyhcIl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXlwiKTtcbn1cbi8vICNyZWdpb24gSW5hY3Rpdml0eSBDaGVja3NcbndpbmRvdy5XYVhDb2RlLkRCQy5leGVjdXRpb25TZXR0aW5ncy5jaGVja1ByZWNvbmRpdGlvbnMgPSBmYWxzZTtcbnRyeSB7XG4gICAgZGVtby50ZXN0TEVTU19PUl9FUVVBTCgyMSk7XG4gICAgY29uc29sZS5sb2coXCLijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijIRcIik7XG4gICAgY29uc29sZS5sb2coXCJJTkFDVElWRSBQUkVDT05ESVRJT05TIE9LXCIpO1xuICAgIGNvbnNvbGUubG9nKFwiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXCIpO1xufVxuY2F0Y2ggKFgpIHtcbiAgICBjb25zb2xlLmxvZyhcIuKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhFwiKTtcbiAgICBjb25zb2xlLmxvZyhcIklOQUNUSVZFIFBSRUNPTkRJVElPTlMgRkFJTEVEXCIpO1xuICAgIGNvbnNvbGUubG9nKFgpO1xuICAgIGNvbnNvbGUubG9nKFwiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXCIpO1xufVxud2luZG93LldhWENvZGUuREJDLmV4ZWN1dGlvblNldHRpbmdzLmNoZWNrUG9zdGNvbmRpdGlvbnMgPSBmYWxzZTtcbnRyeSB7XG4gICAgZGVtby50ZXN0UmV0dXJudmFsdWUoXCJxcXFxcVwiKTtcbiAgICBjb25zb2xlLmxvZyhcIuKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhFwiKTtcbiAgICBjb25zb2xlLmxvZyhcIklOQUNUSVZFIFBPU1RDT05ESVRJT05TIE9LXCIpO1xuICAgIGNvbnNvbGUubG9nKFwiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXCIpO1xufVxuY2F0Y2ggKFgpIHtcbiAgICBjb25zb2xlLmxvZyhcIuKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhFwiKTtcbiAgICBjb25zb2xlLmxvZyhcIklOQUNUSVZFIFBPU1RDT05ESVRJT05TIEZBSUxFRFwiKTtcbiAgICBjb25zb2xlLmxvZyhYKTtcbiAgICBjb25zb2xlLmxvZyhcIl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXlwiKTtcbn1cbndpbmRvdy5XYVhDb2RlLkRCQy5leGVjdXRpb25TZXR0aW5ncy5jaGVja0ludmFyaWFudHMgPSBmYWxzZTtcbnRyeSB7XG4gICAgZGVtby50ZXN0UHJvcGVydHkgPSBcImJcIjtcbiAgICBjb25zb2xlLmxvZyhcIuKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhFwiKTtcbiAgICBjb25zb2xlLmxvZyhcIklOQUNUSVZFIElOVkFSSUFOVFMgT0tcIik7XG4gICAgY29uc29sZS5sb2coXCJeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5cIik7XG59XG5jYXRjaCAoWCkge1xuICAgIGNvbnNvbGUubG9nKFwi4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyEXCIpO1xuICAgIGNvbnNvbGUubG9nKFwiSU5BQ1RJVkUgSU5WQVJJQU5UUyBGQUlMRURcIik7XG4gICAgY29uc29sZS5sb2coWCk7XG4gICAgY29uc29sZS5sb2coXCJeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5cIik7XG59XG4vLyAjZW5kcmVnaW9uIEluYWN0aXZpdHkgQ2hlY2tzXG4vLyBSZS1lbmFibGUgYWxsIGNoZWNrcyBmb3Igc3Vic2VxdWVudCB0ZXN0c1xud2luZG93LldhWENvZGUuREJDLmV4ZWN1dGlvblNldHRpbmdzLmNoZWNrUHJlY29uZGl0aW9ucyA9IHRydWU7XG53aW5kb3cuV2FYQ29kZS5EQkMuZXhlY3V0aW9uU2V0dGluZ3MuY2hlY2tQb3N0Y29uZGl0aW9ucyA9IHRydWU7XG53aW5kb3cuV2FYQ29kZS5EQkMuZXhlY3V0aW9uU2V0dGluZ3MuY2hlY2tJbnZhcmlhbnRzID0gdHJ1ZTtcbi8vICNyZWdpb24gU3RhdGljIE1ldGhvZCBUZXN0XG5jb25zb2xlLmxvZyhcIuKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhFwiKTtcbmNvbnNvbGUubG9nKFwiVEVTVElORyBTVEFUSUMgTUVUSE9EIFdJVEggUEFSQU1WQUxVRVBST1ZJREVSXCIpO1xuY29uc29sZS5sb2coXCJeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5cIik7XG5EZW1vLnRlc3RTdGF0aWNNZXRob2QoXCJIZWxsb1wiLCAzKTtcbmNvbnNvbGUubG9nKFwi4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyE4oyEXCIpO1xuY29uc29sZS5sb2coXCJTVEFUSUMgTUVUSE9EIE9LXCIpO1xuY29uc29sZS5sb2coXCJeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5cIik7XG50cnkge1xuICAgIERlbW8udGVzdFN0YXRpY01ldGhvZChcIkhlbGxvXCIsIFwibm90IGEgbnVtYmVyXCIpO1xufVxuY2F0Y2ggKFgpIHtcbiAgICBjb25zb2xlLmxvZyhcIuKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhOKMhFwiKTtcbiAgICBjb25zb2xlLmxvZyhcIlNUQVRJQyBNRVRIT0QgSW5mcmluZ2VtZW50IE9LXCIpO1xuICAgIGNvbnNvbGUubG9nKFgpO1xuICAgIGNvbnNvbGUubG9nKFwiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXCIpO1xufVxudHJ5IHtcbiAgICBEZW1vLnRlc3RTdGF0aWNNZXRob2QoMTIzLCA1KTtcbn1cbmNhdGNoIChYKSB7XG4gICAgY29uc29sZS5sb2coXCLijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijITijIRcIik7XG4gICAgY29uc29sZS5sb2coXCJTVEFUSUMgTUVUSE9EIEluZnJpbmdlbWVudCAoZmlyc3QgcGFyYW0pIE9LXCIpO1xuICAgIGNvbnNvbGUubG9nKFgpO1xuICAgIGNvbnNvbGUubG9nKFwiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXCIpO1xufVxuLy8gI2VuZHJlZ2lvbiBTdGF0aWMgTWV0aG9kIFRlc3RcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==
|