@ukwhatn/wikidot 1.0.9 → 4.0.2
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/README.md +227 -79
- package/dist/errors.cjs +114 -0
- package/dist/errors.d.cts +94 -0
- package/dist/errors.d.ts +94 -0
- package/dist/errors.js +81 -0
- package/dist/index.cjs +4624 -0
- package/dist/index.d.cts +2106 -0
- package/dist/index.d.ts +2106 -1
- package/dist/index.js +2651 -6
- package/dist/shared/index-7dqqxq7x.js +105 -0
- package/dist/shared/index-f2eh3ykk.js +172 -0
- package/dist/shared/index-kka6e8cb.js +627 -0
- package/dist/shared/index-ytknx2hn.js +980 -0
- package/package.json +64 -26
- package/Makefile +0 -13
- package/dist/common/exceptions.d.ts +0 -95
- package/dist/common/exceptions.js +0 -146
- package/dist/common/exceptions.js.map +0 -1
- package/dist/common/index.d.ts +0 -1
- package/dist/common/index.js +0 -6
- package/dist/common/index.js.map +0 -1
- package/dist/common/logger.d.ts +0 -2
- package/dist/common/logger.js +0 -19
- package/dist/common/logger.js.map +0 -1
- package/dist/connector/ajax.d.ts +0 -142
- package/dist/connector/ajax.js +0 -259
- package/dist/connector/ajax.js.map +0 -1
- package/dist/connector/api.d.ts +0 -11
- package/dist/connector/api.js +0 -17
- package/dist/connector/api.js.map +0 -1
- package/dist/connector/index.d.ts +0 -0
- package/dist/connector/index.js +0 -2
- package/dist/connector/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/module/auth.d.ts +0 -8
- package/dist/module/auth.js +0 -77
- package/dist/module/auth.js.map +0 -1
- package/dist/module/client.d.ts +0 -39
- package/dist/module/client.js +0 -97
- package/dist/module/client.js.map +0 -1
- package/dist/module/index.d.ts +0 -0
- package/dist/module/index.js +0 -2
- package/dist/module/index.js.map +0 -1
- package/dist/module/page.d.ts +0 -102
- package/dist/module/page.js +0 -395
- package/dist/module/page.js.map +0 -1
- package/dist/module/pageRevision.d.ts +0 -29
- package/dist/module/pageRevision.js +0 -114
- package/dist/module/pageRevision.js.map +0 -1
- package/dist/module/pageSource.d.ts +0 -7
- package/dist/module/pageSource.js +0 -11
- package/dist/module/pageSource.js.map +0 -1
- package/dist/module/pageVote.d.ts +0 -14
- package/dist/module/pageVote.js +0 -20
- package/dist/module/pageVote.js.map +0 -1
- package/dist/module/privateMessage.d.ts +0 -29
- package/dist/module/privateMessage.js +0 -128
- package/dist/module/privateMessage.js.map +0 -1
- package/dist/module/site.d.ts +0 -32
- package/dist/module/site.js +0 -115
- package/dist/module/site.js.map +0 -1
- package/dist/module/siteApplication.d.ts +0 -14
- package/dist/module/siteApplication.js +0 -96
- package/dist/module/siteApplication.js.map +0 -1
- package/dist/module/user.d.ts +0 -56
- package/dist/module/user.js +0 -115
- package/dist/module/user.js.map +0 -1
- package/dist/util/index.d.ts +0 -3
- package/dist/util/index.js +0 -10
- package/dist/util/index.js.map +0 -1
- package/dist/util/parser/index.d.ts +0 -1
- package/dist/util/parser/index.js +0 -18
- package/dist/util/parser/index.js.map +0 -1
- package/dist/util/parser/odate.d.ts +0 -12
- package/dist/util/parser/odate.js +0 -25
- package/dist/util/parser/odate.js.map +0 -1
- package/dist/util/parser/user.d.ts +0 -16
- package/dist/util/parser/user.js +0 -36
- package/dist/util/parser/user.js.map +0 -1
- package/dist/util/quickModule.d.ts +0 -96
- package/dist/util/quickModule.js +0 -137
- package/dist/util/quickModule.js.map +0 -1
- package/dist/util/requestUtil.d.ts +0 -26
- package/dist/util/requestUtil.js +0 -69
- package/dist/util/requestUtil.js.map +0 -1
- package/dist/util/stringUtil.d.ts +0 -21
- package/dist/util/stringUtil.js +0 -64
- package/dist/util/stringUtil.js.map +0 -1
- package/dist/util/table/charTable.d.ts +0 -3
- package/dist/util/table/charTable.js +0 -472
- package/dist/util/table/charTable.js.map +0 -1
- package/dist/util/table/index.d.ts +0 -1
- package/dist/util/table/index.js +0 -18
- package/dist/util/table/index.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,2651 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import {
|
|
2
|
+
AnonymousUser,
|
|
3
|
+
DeletedUser,
|
|
4
|
+
ForumCategory,
|
|
5
|
+
ForumCategoryCollection,
|
|
6
|
+
ForumPost,
|
|
7
|
+
ForumPostCollection,
|
|
8
|
+
ForumThread,
|
|
9
|
+
ForumThreadCollection,
|
|
10
|
+
GuestUser,
|
|
11
|
+
Logger,
|
|
12
|
+
RequireLogin,
|
|
13
|
+
WikidotUser,
|
|
14
|
+
consoleHandler,
|
|
15
|
+
getLogger,
|
|
16
|
+
logger,
|
|
17
|
+
nullHandler,
|
|
18
|
+
parseOdate,
|
|
19
|
+
parseUser,
|
|
20
|
+
setupConsoleHandler
|
|
21
|
+
} from "./shared/index-ytknx2hn.js";
|
|
22
|
+
import {
|
|
23
|
+
PageRevision,
|
|
24
|
+
PageRevisionCollection
|
|
25
|
+
} from "./shared/index-f2eh3ykk.js";
|
|
26
|
+
import {
|
|
27
|
+
User,
|
|
28
|
+
UserCollection
|
|
29
|
+
} from "./shared/index-kka6e8cb.js";
|
|
30
|
+
import {
|
|
31
|
+
AMCError,
|
|
32
|
+
AMCHttpError,
|
|
33
|
+
ForbiddenError,
|
|
34
|
+
LoginRequiredError,
|
|
35
|
+
NoElementError,
|
|
36
|
+
NotFoundException,
|
|
37
|
+
ResponseDataError,
|
|
38
|
+
SessionCreateError,
|
|
39
|
+
SessionError,
|
|
40
|
+
TargetError,
|
|
41
|
+
TargetExistsError,
|
|
42
|
+
UnexpectedError,
|
|
43
|
+
WikidotError,
|
|
44
|
+
WikidotStatusError,
|
|
45
|
+
__legacyDecorateClassTS,
|
|
46
|
+
__require,
|
|
47
|
+
__toESM,
|
|
48
|
+
combineResults,
|
|
49
|
+
fromPromise,
|
|
50
|
+
wdErr,
|
|
51
|
+
wdErrAsync,
|
|
52
|
+
wdOk,
|
|
53
|
+
wdOkAsync
|
|
54
|
+
} from "./shared/index-7dqqxq7x.js";
|
|
55
|
+
// src/connector/amc-client.ts
|
|
56
|
+
import ky from "ky";
|
|
57
|
+
import pLimit from "p-limit";
|
|
58
|
+
|
|
59
|
+
// src/connector/amc-config.ts
|
|
60
|
+
var DEFAULT_AMC_CONFIG = {
|
|
61
|
+
timeout: 20000,
|
|
62
|
+
retryLimit: 3,
|
|
63
|
+
retryInterval: 1000,
|
|
64
|
+
maxBackoff: 60000,
|
|
65
|
+
backoffFactor: 2,
|
|
66
|
+
semaphoreLimit: 10
|
|
67
|
+
};
|
|
68
|
+
var WIKIDOT_TOKEN7 = "123456";
|
|
69
|
+
var DEFAULT_HTTP_STATUS_CODE = 999;
|
|
70
|
+
|
|
71
|
+
// src/connector/amc-header.ts
|
|
72
|
+
class AMCHeader {
|
|
73
|
+
cookies;
|
|
74
|
+
contentType;
|
|
75
|
+
userAgent;
|
|
76
|
+
referer;
|
|
77
|
+
constructor(options) {
|
|
78
|
+
this.contentType = options?.contentType ?? "application/x-www-form-urlencoded; charset=UTF-8";
|
|
79
|
+
this.userAgent = options?.userAgent ?? "WikidotTS";
|
|
80
|
+
this.referer = options?.referer ?? "https://www.wikidot.com/";
|
|
81
|
+
this.cookies = new Map([["wikidot_token7", "123456"]]);
|
|
82
|
+
}
|
|
83
|
+
setCookie(name, value) {
|
|
84
|
+
this.cookies.set(name, value);
|
|
85
|
+
}
|
|
86
|
+
deleteCookie(name) {
|
|
87
|
+
this.cookies.delete(name);
|
|
88
|
+
}
|
|
89
|
+
getCookie(name) {
|
|
90
|
+
return this.cookies.get(name);
|
|
91
|
+
}
|
|
92
|
+
getHeaders() {
|
|
93
|
+
const cookieString = Array.from(this.cookies.entries()).map(([name, value]) => `${name}=${value}`).join("; ");
|
|
94
|
+
return {
|
|
95
|
+
"Content-Type": this.contentType,
|
|
96
|
+
"User-Agent": this.userAgent,
|
|
97
|
+
Referer: this.referer,
|
|
98
|
+
Cookie: cookieString
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// src/connector/amc-types.ts
|
|
104
|
+
import { z } from "zod";
|
|
105
|
+
var baseSchema = z.object({
|
|
106
|
+
status: z.string(),
|
|
107
|
+
body: z.string().optional(),
|
|
108
|
+
message: z.string().optional()
|
|
109
|
+
});
|
|
110
|
+
var amcResponseSchema = baseSchema.passthrough();
|
|
111
|
+
function isSuccessResponse(response) {
|
|
112
|
+
return response.status === "ok";
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// src/connector/amc-client.ts
|
|
116
|
+
function maskSensitiveData(body) {
|
|
117
|
+
const masked = { ...body };
|
|
118
|
+
const sensitiveKeys = ["password", "login", "WIKIDOT_SESSION_ID", "wikidot_token7"];
|
|
119
|
+
for (const key of sensitiveKeys) {
|
|
120
|
+
if (key in masked) {
|
|
121
|
+
masked[key] = "***MASKED***";
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return masked;
|
|
125
|
+
}
|
|
126
|
+
function calculateBackoff(retryCount, baseInterval, backoffFactor, maxBackoff) {
|
|
127
|
+
const backoff = baseInterval * backoffFactor ** (retryCount - 1);
|
|
128
|
+
const jitter = Math.random() * backoff * 0.1;
|
|
129
|
+
return Math.min(backoff + jitter, maxBackoff);
|
|
130
|
+
}
|
|
131
|
+
function sleep(ms) {
|
|
132
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
class AMCClient {
|
|
136
|
+
ky;
|
|
137
|
+
limit;
|
|
138
|
+
header;
|
|
139
|
+
config;
|
|
140
|
+
domain;
|
|
141
|
+
sslCache = new Map;
|
|
142
|
+
constructor(config = {}, domain = "wikidot.com") {
|
|
143
|
+
this.config = { ...DEFAULT_AMC_CONFIG, ...config };
|
|
144
|
+
this.domain = domain;
|
|
145
|
+
this.header = new AMCHeader;
|
|
146
|
+
this.limit = pLimit(this.config.semaphoreLimit);
|
|
147
|
+
this.ky = ky.create({
|
|
148
|
+
timeout: this.config.timeout,
|
|
149
|
+
retry: 0
|
|
150
|
+
});
|
|
151
|
+
this.sslCache.set("www", true);
|
|
152
|
+
}
|
|
153
|
+
checkSiteSSL(siteName) {
|
|
154
|
+
const cached = this.sslCache.get(siteName);
|
|
155
|
+
if (cached !== undefined) {
|
|
156
|
+
return wdOkAsync(cached);
|
|
157
|
+
}
|
|
158
|
+
if (siteName === "www") {
|
|
159
|
+
return wdOkAsync(true);
|
|
160
|
+
}
|
|
161
|
+
return fromPromise((async () => {
|
|
162
|
+
const response = await fetch(`http://${siteName}.${this.domain}`, {
|
|
163
|
+
method: "GET",
|
|
164
|
+
redirect: "manual"
|
|
165
|
+
});
|
|
166
|
+
if (response.status === 404) {
|
|
167
|
+
throw new NotFoundException(`Site is not found: ${siteName}.${this.domain}`);
|
|
168
|
+
}
|
|
169
|
+
const isSSL = response.status === 301 && response.headers.get("Location")?.startsWith("https") === true;
|
|
170
|
+
this.sslCache.set(siteName, isSSL);
|
|
171
|
+
return isSSL;
|
|
172
|
+
})(), (error) => {
|
|
173
|
+
if (error instanceof WikidotError) {
|
|
174
|
+
return error;
|
|
175
|
+
}
|
|
176
|
+
return new UnexpectedError(`Failed to check SSL for ${siteName}: ${String(error)}`);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
request(bodies, siteName = "www", sslSupported) {
|
|
180
|
+
return this.requestWithOptions(bodies, {
|
|
181
|
+
siteName,
|
|
182
|
+
sslSupported,
|
|
183
|
+
returnExceptions: false
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
requestWithOptions(bodies, options = {}) {
|
|
187
|
+
const { siteName = "www", sslSupported, returnExceptions = false } = options;
|
|
188
|
+
return fromPromise((async () => {
|
|
189
|
+
let ssl = sslSupported;
|
|
190
|
+
if (ssl === undefined) {
|
|
191
|
+
const sslResult = await this.checkSiteSSL(siteName);
|
|
192
|
+
if (sslResult.isErr()) {
|
|
193
|
+
throw sslResult.error;
|
|
194
|
+
}
|
|
195
|
+
ssl = sslResult.value;
|
|
196
|
+
}
|
|
197
|
+
const protocol = ssl ? "https" : "http";
|
|
198
|
+
const url = `${protocol}://${siteName}.${this.domain}/ajax-module-connector.php`;
|
|
199
|
+
const results = await Promise.all(bodies.map((body) => this.limit(() => this.singleRequest(body, url))));
|
|
200
|
+
if (returnExceptions) {
|
|
201
|
+
return results.map((r) => {
|
|
202
|
+
if (r.isOk()) {
|
|
203
|
+
return r.value;
|
|
204
|
+
}
|
|
205
|
+
return r.error;
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
const firstError = results.find((r) => r.isErr());
|
|
209
|
+
if (firstError?.isErr()) {
|
|
210
|
+
throw firstError.error;
|
|
211
|
+
}
|
|
212
|
+
return results.map((r) => {
|
|
213
|
+
if (r.isOk()) {
|
|
214
|
+
return r.value;
|
|
215
|
+
}
|
|
216
|
+
throw new UnexpectedError("Unexpected error in result processing");
|
|
217
|
+
});
|
|
218
|
+
})(), (error) => {
|
|
219
|
+
if (error instanceof WikidotError) {
|
|
220
|
+
return error;
|
|
221
|
+
}
|
|
222
|
+
return new UnexpectedError(`AMC request failed: ${String(error)}`);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
async singleRequest(body, url) {
|
|
226
|
+
let retryCount = 0;
|
|
227
|
+
while (true) {
|
|
228
|
+
try {
|
|
229
|
+
const requestBody = { ...body, wikidot_token7: WIKIDOT_TOKEN7 };
|
|
230
|
+
const formData = new URLSearchParams;
|
|
231
|
+
for (const [key, value] of Object.entries(requestBody)) {
|
|
232
|
+
if (value !== undefined) {
|
|
233
|
+
formData.append(key, String(value));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const response = await this.ky.post(url, {
|
|
237
|
+
headers: this.header.getHeaders(),
|
|
238
|
+
body: formData.toString()
|
|
239
|
+
});
|
|
240
|
+
let responseData;
|
|
241
|
+
try {
|
|
242
|
+
responseData = await response.json();
|
|
243
|
+
} catch {
|
|
244
|
+
return wdErrAsync(new ResponseDataError(`AMC responded with non-JSON data: ${await response.text()}`));
|
|
245
|
+
}
|
|
246
|
+
const parseResult = amcResponseSchema.safeParse(responseData);
|
|
247
|
+
if (!parseResult.success) {
|
|
248
|
+
return wdErrAsync(new ResponseDataError(`Invalid AMC response format: ${parseResult.error.message}`));
|
|
249
|
+
}
|
|
250
|
+
const amcResponse = parseResult.data;
|
|
251
|
+
if (amcResponse.status === "try_again") {
|
|
252
|
+
retryCount++;
|
|
253
|
+
if (retryCount >= this.config.retryLimit) {
|
|
254
|
+
return wdErrAsync(new WikidotStatusError("AMC responded with try_again", "try_again"));
|
|
255
|
+
}
|
|
256
|
+
const backoff = calculateBackoff(retryCount, this.config.retryInterval, this.config.backoffFactor, this.config.maxBackoff);
|
|
257
|
+
await sleep(backoff);
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
if (amcResponse.status === "no_permission") {
|
|
261
|
+
const targetStr = body.moduleName ? `moduleName: ${body.moduleName}` : body.action ? `action: ${body.action}/${body.event ?? ""}` : "unknown";
|
|
262
|
+
return wdErrAsync(new ForbiddenError(`Your account has no permission to perform this action: ${targetStr}`));
|
|
263
|
+
}
|
|
264
|
+
if (amcResponse.status !== "ok") {
|
|
265
|
+
return wdErrAsync(new WikidotStatusError(`AMC responded with error status: "${amcResponse.status}"`, amcResponse.status));
|
|
266
|
+
}
|
|
267
|
+
return wdOkAsync(amcResponse);
|
|
268
|
+
} catch (error) {
|
|
269
|
+
retryCount++;
|
|
270
|
+
if (retryCount >= this.config.retryLimit) {
|
|
271
|
+
const statusCode = error instanceof Error && "response" in error ? error.response?.status ?? DEFAULT_HTTP_STATUS_CODE : DEFAULT_HTTP_STATUS_CODE;
|
|
272
|
+
return wdErrAsync(new AMCHttpError(`AMC HTTP request failed: ${String(error)}`, statusCode));
|
|
273
|
+
}
|
|
274
|
+
const backoff = calculateBackoff(retryCount, this.config.retryInterval, this.config.backoffFactor, this.config.maxBackoff);
|
|
275
|
+
await sleep(backoff);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// src/connector/auth.ts
|
|
281
|
+
var LOGIN_URL = "https://www.wikidot.com/default--flow/login__LoginPopupScreen";
|
|
282
|
+
function login(client, username, password) {
|
|
283
|
+
return fromPromise((async () => {
|
|
284
|
+
const formData = new URLSearchParams({
|
|
285
|
+
login: username,
|
|
286
|
+
password,
|
|
287
|
+
action: "Login2Action",
|
|
288
|
+
event: "login"
|
|
289
|
+
});
|
|
290
|
+
const response = await fetch(LOGIN_URL, {
|
|
291
|
+
method: "POST",
|
|
292
|
+
headers: client.amcClient.header.getHeaders(),
|
|
293
|
+
body: formData.toString()
|
|
294
|
+
});
|
|
295
|
+
if (!response.ok) {
|
|
296
|
+
throw new SessionCreateError(`Login attempt failed due to HTTP status code: ${response.status}`);
|
|
297
|
+
}
|
|
298
|
+
const body = await response.text();
|
|
299
|
+
if (body.includes("The login and password do not match")) {
|
|
300
|
+
throw new SessionCreateError("Login attempt failed due to invalid username or password");
|
|
301
|
+
}
|
|
302
|
+
const cookies = response.headers.get("Set-Cookie");
|
|
303
|
+
if (!cookies) {
|
|
304
|
+
throw new SessionCreateError("Login attempt failed due to missing cookies");
|
|
305
|
+
}
|
|
306
|
+
const sessionIdMatch = cookies.match(/WIKIDOT_SESSION_ID=([^;]+)/);
|
|
307
|
+
if (!sessionIdMatch?.[1]) {
|
|
308
|
+
throw new SessionCreateError("Login attempt failed due to missing WIKIDOT_SESSION_ID cookie");
|
|
309
|
+
}
|
|
310
|
+
client.amcClient.header.setCookie("WIKIDOT_SESSION_ID", sessionIdMatch[1]);
|
|
311
|
+
})(), (error) => {
|
|
312
|
+
if (error instanceof SessionCreateError) {
|
|
313
|
+
return error;
|
|
314
|
+
}
|
|
315
|
+
return new SessionCreateError(`Login failed: ${String(error)}`);
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
function logout(client) {
|
|
319
|
+
return client.amcClient.request([
|
|
320
|
+
{
|
|
321
|
+
moduleName: "Empty",
|
|
322
|
+
action: "Login2Action",
|
|
323
|
+
event: "logout"
|
|
324
|
+
}
|
|
325
|
+
]).map(() => {
|
|
326
|
+
client.amcClient.header.deleteCookie("WIKIDOT_SESSION_ID");
|
|
327
|
+
return;
|
|
328
|
+
}).orElse(() => {
|
|
329
|
+
client.amcClient.header.deleteCookie("WIKIDOT_SESSION_ID");
|
|
330
|
+
return wdOkAsync(undefined);
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
// src/module/private-message/private-message.ts
|
|
334
|
+
import * as cheerio from "cheerio";
|
|
335
|
+
class PrivateMessage {
|
|
336
|
+
client;
|
|
337
|
+
id;
|
|
338
|
+
sender;
|
|
339
|
+
recipient;
|
|
340
|
+
subject;
|
|
341
|
+
body;
|
|
342
|
+
createdAt;
|
|
343
|
+
constructor(data) {
|
|
344
|
+
this.client = data.client;
|
|
345
|
+
this.id = data.id;
|
|
346
|
+
this.sender = data.sender;
|
|
347
|
+
this.recipient = data.recipient;
|
|
348
|
+
this.subject = data.subject;
|
|
349
|
+
this.body = data.body;
|
|
350
|
+
this.createdAt = data.createdAt;
|
|
351
|
+
}
|
|
352
|
+
static fromId(client, messageId) {
|
|
353
|
+
return fromPromise((async () => {
|
|
354
|
+
const result = await PrivateMessageCollection.fromIds(client, [messageId]);
|
|
355
|
+
if (result.isErr()) {
|
|
356
|
+
throw result.error;
|
|
357
|
+
}
|
|
358
|
+
const message = result.value[0];
|
|
359
|
+
if (!message) {
|
|
360
|
+
throw new NoElementError(`Message not found: ${messageId}`);
|
|
361
|
+
}
|
|
362
|
+
return message;
|
|
363
|
+
})(), (error) => {
|
|
364
|
+
if (error instanceof ForbiddenError || error instanceof NoElementError) {
|
|
365
|
+
return error;
|
|
366
|
+
}
|
|
367
|
+
return new UnexpectedError(`Failed to get message: ${String(error)}`);
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
static send(client, recipient, subject, body) {
|
|
371
|
+
const loginResult = client.requireLogin();
|
|
372
|
+
if (loginResult.isErr()) {
|
|
373
|
+
return fromPromise(Promise.reject(loginResult.error), () => new LoginRequiredError("Login required to send message"));
|
|
374
|
+
}
|
|
375
|
+
return fromPromise((async () => {
|
|
376
|
+
const result = await client.amcClient.request([
|
|
377
|
+
{
|
|
378
|
+
source: body,
|
|
379
|
+
subject,
|
|
380
|
+
to_user_id: recipient.id,
|
|
381
|
+
action: "DashboardMessageAction",
|
|
382
|
+
event: "send",
|
|
383
|
+
moduleName: "Empty"
|
|
384
|
+
}
|
|
385
|
+
]);
|
|
386
|
+
if (result.isErr()) {
|
|
387
|
+
throw result.error;
|
|
388
|
+
}
|
|
389
|
+
})(), (error) => new UnexpectedError(`Failed to send message: ${String(error)}`));
|
|
390
|
+
}
|
|
391
|
+
toString() {
|
|
392
|
+
return `PrivateMessage(id=${this.id}, sender=${this.sender}, recipient=${this.recipient}, subject=${this.subject})`;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
class PrivateMessageCollection extends Array {
|
|
397
|
+
client;
|
|
398
|
+
constructor(client, messages) {
|
|
399
|
+
super();
|
|
400
|
+
this.client = client;
|
|
401
|
+
if (messages) {
|
|
402
|
+
this.push(...messages);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
findById(id) {
|
|
406
|
+
return this.find((message) => message.id === id);
|
|
407
|
+
}
|
|
408
|
+
static fromIds(client, messageIds) {
|
|
409
|
+
const loginResult = client.requireLogin();
|
|
410
|
+
if (loginResult.isErr()) {
|
|
411
|
+
return fromPromise(Promise.reject(loginResult.error), () => new LoginRequiredError("Login required to get messages"));
|
|
412
|
+
}
|
|
413
|
+
return fromPromise((async () => {
|
|
414
|
+
const bodies = messageIds.map((messageId) => ({
|
|
415
|
+
item: messageId,
|
|
416
|
+
moduleName: "dashboard/messages/DMViewMessageModule"
|
|
417
|
+
}));
|
|
418
|
+
const result = await client.amcClient.request(bodies);
|
|
419
|
+
if (result.isErr()) {
|
|
420
|
+
throw result.error;
|
|
421
|
+
}
|
|
422
|
+
const messages = [];
|
|
423
|
+
for (let i = 0;i < messageIds.length; i++) {
|
|
424
|
+
const response = result.value[i];
|
|
425
|
+
const messageId = messageIds[i];
|
|
426
|
+
if (!response || messageId === undefined)
|
|
427
|
+
continue;
|
|
428
|
+
const html = String(response.body ?? "");
|
|
429
|
+
const $ = cheerio.load(html);
|
|
430
|
+
const printuserElems = $("div.pmessage div.header span.printuser");
|
|
431
|
+
if (printuserElems.length < 2) {
|
|
432
|
+
throw new ForbiddenError(`Failed to get message: ${messageId}`);
|
|
433
|
+
}
|
|
434
|
+
const senderElem = $(printuserElems[0]);
|
|
435
|
+
const recipientElem = $(printuserElems[1]);
|
|
436
|
+
const sender = parseUser(client, senderElem);
|
|
437
|
+
const recipient = parseUser(client, recipientElem);
|
|
438
|
+
const subjectElem = $("div.pmessage div.header span.subject");
|
|
439
|
+
const subject = subjectElem.text().trim();
|
|
440
|
+
const bodyElem = $("div.pmessage div.body");
|
|
441
|
+
const body = bodyElem.text().trim();
|
|
442
|
+
const odateElem = $("div.header span.odate");
|
|
443
|
+
const createdAt = odateElem.length > 0 ? parseOdate(odateElem) ?? new Date(0) : new Date(0);
|
|
444
|
+
messages.push(new PrivateMessage({
|
|
445
|
+
client,
|
|
446
|
+
id: messageId,
|
|
447
|
+
sender,
|
|
448
|
+
recipient,
|
|
449
|
+
subject,
|
|
450
|
+
body,
|
|
451
|
+
createdAt
|
|
452
|
+
}));
|
|
453
|
+
}
|
|
454
|
+
return new PrivateMessageCollection(client, messages);
|
|
455
|
+
})(), (error) => {
|
|
456
|
+
if (error instanceof ForbiddenError || error instanceof LoginRequiredError) {
|
|
457
|
+
return error;
|
|
458
|
+
}
|
|
459
|
+
return new UnexpectedError(`Failed to get messages: ${String(error)}`);
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
static acquireFromModule(client, moduleName) {
|
|
463
|
+
const loginResult = client.requireLogin();
|
|
464
|
+
if (loginResult.isErr()) {
|
|
465
|
+
return fromPromise(Promise.reject(loginResult.error), () => new LoginRequiredError("Login required to get messages"));
|
|
466
|
+
}
|
|
467
|
+
return fromPromise((async () => {
|
|
468
|
+
const firstResult = await client.amcClient.request([{ moduleName }]);
|
|
469
|
+
if (firstResult.isErr()) {
|
|
470
|
+
throw firstResult.error;
|
|
471
|
+
}
|
|
472
|
+
const firstResponse = firstResult.value[0];
|
|
473
|
+
if (!firstResponse) {
|
|
474
|
+
throw new NoElementError("Empty response");
|
|
475
|
+
}
|
|
476
|
+
const firstHtml = String(firstResponse.body ?? "");
|
|
477
|
+
const $first = cheerio.load(firstHtml);
|
|
478
|
+
const pagerTargets = $first("div.pager span.target");
|
|
479
|
+
let maxPage = 1;
|
|
480
|
+
if (pagerTargets.length > 2) {
|
|
481
|
+
const lastPageText = $first(pagerTargets[pagerTargets.length - 2]).text().trim();
|
|
482
|
+
maxPage = Number.parseInt(lastPageText, 10) || 1;
|
|
483
|
+
}
|
|
484
|
+
const messageIds = [];
|
|
485
|
+
if (maxPage > 1) {
|
|
486
|
+
const bodies = [];
|
|
487
|
+
for (let page = 1;page <= maxPage; page++) {
|
|
488
|
+
bodies.push({ page, moduleName });
|
|
489
|
+
}
|
|
490
|
+
const additionalResults = await client.amcClient.request(bodies);
|
|
491
|
+
if (additionalResults.isErr()) {
|
|
492
|
+
throw additionalResults.error;
|
|
493
|
+
}
|
|
494
|
+
for (const response of additionalResults.value) {
|
|
495
|
+
const html = String(response?.body ?? "");
|
|
496
|
+
const $ = cheerio.load(html);
|
|
497
|
+
$("tr.message").each((_i, elem) => {
|
|
498
|
+
const dataHref = $(elem).attr("data-href") ?? "";
|
|
499
|
+
const idMatch = dataHref.match(/\/(\d+)$/);
|
|
500
|
+
if (idMatch?.[1]) {
|
|
501
|
+
messageIds.push(Number.parseInt(idMatch[1], 10));
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
} else {
|
|
506
|
+
$first("tr.message").each((_i, elem) => {
|
|
507
|
+
const dataHref = $first(elem).attr("data-href") ?? "";
|
|
508
|
+
const idMatch = dataHref.match(/\/(\d+)$/);
|
|
509
|
+
if (idMatch?.[1]) {
|
|
510
|
+
messageIds.push(Number.parseInt(idMatch[1], 10));
|
|
511
|
+
}
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
const messagesResult = await PrivateMessageCollection.fromIds(client, messageIds);
|
|
515
|
+
if (messagesResult.isErr()) {
|
|
516
|
+
throw messagesResult.error;
|
|
517
|
+
}
|
|
518
|
+
return messagesResult.value;
|
|
519
|
+
})(), (error) => {
|
|
520
|
+
if (error instanceof ForbiddenError || error instanceof LoginRequiredError || error instanceof NoElementError) {
|
|
521
|
+
return error;
|
|
522
|
+
}
|
|
523
|
+
return new UnexpectedError(`Failed to acquire messages: ${String(error)}`);
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
class PrivateMessageInbox extends PrivateMessageCollection {
|
|
529
|
+
static acquire(client) {
|
|
530
|
+
return fromPromise((async () => {
|
|
531
|
+
const result = await PrivateMessageCollection.acquireFromModule(client, "dashboard/messages/DMInboxModule");
|
|
532
|
+
if (result.isErr()) {
|
|
533
|
+
throw result.error;
|
|
534
|
+
}
|
|
535
|
+
const inbox = new PrivateMessageInbox(client);
|
|
536
|
+
inbox.push(...result.value);
|
|
537
|
+
return inbox;
|
|
538
|
+
})(), (error) => {
|
|
539
|
+
if (error instanceof ForbiddenError || error instanceof LoginRequiredError) {
|
|
540
|
+
return error;
|
|
541
|
+
}
|
|
542
|
+
return new UnexpectedError(`Failed to acquire inbox: ${String(error)}`);
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
class PrivateMessageSentBox extends PrivateMessageCollection {
|
|
548
|
+
static acquire(client) {
|
|
549
|
+
return fromPromise((async () => {
|
|
550
|
+
const result = await PrivateMessageCollection.acquireFromModule(client, "dashboard/messages/DMSentModule");
|
|
551
|
+
if (result.isErr()) {
|
|
552
|
+
throw result.error;
|
|
553
|
+
}
|
|
554
|
+
const sentBox = new PrivateMessageSentBox(client);
|
|
555
|
+
sentBox.push(...result.value);
|
|
556
|
+
return sentBox;
|
|
557
|
+
})(), (error) => {
|
|
558
|
+
if (error instanceof ForbiddenError || error instanceof LoginRequiredError) {
|
|
559
|
+
return error;
|
|
560
|
+
}
|
|
561
|
+
return new UnexpectedError(`Failed to acquire sent box: ${String(error)}`);
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
// src/module/client/accessors/pm-accessor.ts
|
|
566
|
+
class PrivateMessageAccessor {
|
|
567
|
+
client;
|
|
568
|
+
constructor(client) {
|
|
569
|
+
this.client = client;
|
|
570
|
+
}
|
|
571
|
+
get(id) {
|
|
572
|
+
return PrivateMessage.fromId(this.client, id);
|
|
573
|
+
}
|
|
574
|
+
getMessages(ids) {
|
|
575
|
+
return PrivateMessageCollection.fromIds(this.client, ids);
|
|
576
|
+
}
|
|
577
|
+
inbox() {
|
|
578
|
+
return PrivateMessageInbox.acquire(this.client);
|
|
579
|
+
}
|
|
580
|
+
sentBox() {
|
|
581
|
+
return PrivateMessageSentBox.acquire(this.client);
|
|
582
|
+
}
|
|
583
|
+
send(recipient, subject, body) {
|
|
584
|
+
return PrivateMessage.send(this.client, recipient, subject, body);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
// src/module/site/accessors/forum-accessor.ts
|
|
588
|
+
class ForumAccessor {
|
|
589
|
+
site;
|
|
590
|
+
constructor(site) {
|
|
591
|
+
this.site = site;
|
|
592
|
+
}
|
|
593
|
+
getCategories() {
|
|
594
|
+
return ForumCategoryCollection.acquireAll(this.site);
|
|
595
|
+
}
|
|
596
|
+
getThread(threadId) {
|
|
597
|
+
return ForumThread.getFromId(this.site, threadId);
|
|
598
|
+
}
|
|
599
|
+
getThreads(threadIds) {
|
|
600
|
+
return ForumThreadCollection.acquireFromThreadIds(this.site, threadIds);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
// src/util/quick-module.ts
|
|
604
|
+
import { z as z2 } from "zod";
|
|
605
|
+
var quickModuleUserResponseSchema = z2.object({
|
|
606
|
+
users: z2.union([
|
|
607
|
+
z2.array(z2.object({
|
|
608
|
+
user_id: z2.union([z2.string(), z2.number()]),
|
|
609
|
+
name: z2.string()
|
|
610
|
+
})),
|
|
611
|
+
z2.literal(false)
|
|
612
|
+
])
|
|
613
|
+
});
|
|
614
|
+
var quickModulePageResponseSchema = z2.object({
|
|
615
|
+
pages: z2.union([
|
|
616
|
+
z2.array(z2.object({
|
|
617
|
+
title: z2.string(),
|
|
618
|
+
unix_name: z2.string()
|
|
619
|
+
})),
|
|
620
|
+
z2.literal(false)
|
|
621
|
+
])
|
|
622
|
+
});
|
|
623
|
+
async function requestQuickModule(moduleName, siteId, query) {
|
|
624
|
+
const url = `https://www.wikidot.com/quickmodule.php?module=${moduleName}&s=${siteId}&q=${encodeURIComponent(query)}`;
|
|
625
|
+
const response = await fetch(url, {
|
|
626
|
+
method: "GET",
|
|
627
|
+
headers: {
|
|
628
|
+
Accept: "application/json"
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
if (response.status === 500) {
|
|
632
|
+
throw new NotFoundException(`Site not found: siteId=${siteId}`);
|
|
633
|
+
}
|
|
634
|
+
if (!response.ok) {
|
|
635
|
+
throw new UnexpectedError(`QuickModule request failed: ${response.status}`);
|
|
636
|
+
}
|
|
637
|
+
return response.json();
|
|
638
|
+
}
|
|
639
|
+
function memberLookup(siteId, query) {
|
|
640
|
+
return fromPromise((async () => {
|
|
641
|
+
const data = await requestQuickModule("MemberLookupQModule", siteId, query);
|
|
642
|
+
const parsed = quickModuleUserResponseSchema.parse(data);
|
|
643
|
+
if (parsed.users === false) {
|
|
644
|
+
return [];
|
|
645
|
+
}
|
|
646
|
+
return parsed.users.map((user) => ({
|
|
647
|
+
id: typeof user.user_id === "string" ? Number.parseInt(user.user_id, 10) : user.user_id,
|
|
648
|
+
name: user.name
|
|
649
|
+
}));
|
|
650
|
+
})(), (error) => {
|
|
651
|
+
if (error instanceof NotFoundException)
|
|
652
|
+
return error;
|
|
653
|
+
return new UnexpectedError(`Member lookup failed: ${String(error)}`);
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
function userLookup(siteId, query) {
|
|
657
|
+
return fromPromise((async () => {
|
|
658
|
+
const data = await requestQuickModule("UserLookupQModule", siteId, query);
|
|
659
|
+
const parsed = quickModuleUserResponseSchema.parse(data);
|
|
660
|
+
if (parsed.users === false) {
|
|
661
|
+
return [];
|
|
662
|
+
}
|
|
663
|
+
return parsed.users.map((user) => ({
|
|
664
|
+
id: typeof user.user_id === "string" ? Number.parseInt(user.user_id, 10) : user.user_id,
|
|
665
|
+
name: user.name
|
|
666
|
+
}));
|
|
667
|
+
})(), (error) => {
|
|
668
|
+
if (error instanceof NotFoundException)
|
|
669
|
+
return error;
|
|
670
|
+
return new UnexpectedError(`User lookup failed: ${String(error)}`);
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
function pageLookup(siteId, query) {
|
|
674
|
+
return fromPromise((async () => {
|
|
675
|
+
const data = await requestQuickModule("PageLookupQModule", siteId, query);
|
|
676
|
+
const parsed = quickModulePageResponseSchema.parse(data);
|
|
677
|
+
if (parsed.pages === false) {
|
|
678
|
+
return [];
|
|
679
|
+
}
|
|
680
|
+
return parsed.pages.map((page) => ({
|
|
681
|
+
title: page.title,
|
|
682
|
+
unixName: page.unix_name
|
|
683
|
+
}));
|
|
684
|
+
})(), (error) => {
|
|
685
|
+
if (error instanceof NotFoundException)
|
|
686
|
+
return error;
|
|
687
|
+
return new UnexpectedError(`Page lookup failed: ${String(error)}`);
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
var QuickModule = {
|
|
691
|
+
memberLookup,
|
|
692
|
+
userLookup,
|
|
693
|
+
pageLookup
|
|
694
|
+
};
|
|
695
|
+
|
|
696
|
+
// src/module/site/site-application.ts
|
|
697
|
+
import * as cheerio2 from "cheerio";
|
|
698
|
+
class SiteApplication {
|
|
699
|
+
site;
|
|
700
|
+
user;
|
|
701
|
+
text;
|
|
702
|
+
constructor(data) {
|
|
703
|
+
this.site = data.site;
|
|
704
|
+
this.user = data.user;
|
|
705
|
+
this.text = data.text;
|
|
706
|
+
}
|
|
707
|
+
static acquireAll(site) {
|
|
708
|
+
const loginResult = site.client.requireLogin();
|
|
709
|
+
if (loginResult.isErr()) {
|
|
710
|
+
return fromPromise(Promise.reject(loginResult.error), () => new LoginRequiredError("Login required to get applications"));
|
|
711
|
+
}
|
|
712
|
+
return fromPromise((async () => {
|
|
713
|
+
const result = await site.amcRequest([
|
|
714
|
+
{ moduleName: "managesite/ManageSiteMembersApplicationsModule" }
|
|
715
|
+
]);
|
|
716
|
+
if (result.isErr()) {
|
|
717
|
+
throw result.error;
|
|
718
|
+
}
|
|
719
|
+
const response = result.value[0];
|
|
720
|
+
if (!response) {
|
|
721
|
+
throw new UnexpectedError("Empty response");
|
|
722
|
+
}
|
|
723
|
+
const html = String(response.body ?? "");
|
|
724
|
+
if (html.includes("WIKIDOT.page.listeners.loginClick(event)")) {
|
|
725
|
+
throw new ForbiddenError("You are not allowed to access this page");
|
|
726
|
+
}
|
|
727
|
+
const $ = cheerio2.load(html);
|
|
728
|
+
const applications = [];
|
|
729
|
+
const userElements = $("h3 span.printuser").toArray();
|
|
730
|
+
const textWrapperElements = $("table").toArray();
|
|
731
|
+
if (userElements.length !== textWrapperElements.length) {
|
|
732
|
+
throw new UnexpectedError("Length of user_elements and text_wrapper_elements are different");
|
|
733
|
+
}
|
|
734
|
+
for (let i = 0;i < userElements.length; i++) {
|
|
735
|
+
const userElement = userElements[i];
|
|
736
|
+
const textWrapperElement = textWrapperElements[i];
|
|
737
|
+
if (!userElement || !textWrapperElement)
|
|
738
|
+
continue;
|
|
739
|
+
const user = parseUser(site.client, $(userElement));
|
|
740
|
+
const textElement = $(textWrapperElement).find("td").eq(1);
|
|
741
|
+
const text = textElement.text().trim();
|
|
742
|
+
applications.push(new SiteApplication({ site, user, text }));
|
|
743
|
+
}
|
|
744
|
+
return applications;
|
|
745
|
+
})(), (error) => {
|
|
746
|
+
if (error instanceof ForbiddenError || error instanceof LoginRequiredError) {
|
|
747
|
+
return error;
|
|
748
|
+
}
|
|
749
|
+
return new UnexpectedError(`Failed to get applications: ${String(error)}`);
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
process(action) {
|
|
753
|
+
return fromPromise((async () => {
|
|
754
|
+
const result = await this.site.amcRequest([
|
|
755
|
+
{
|
|
756
|
+
action: "ManageSiteMembershipAction",
|
|
757
|
+
event: "acceptApplication",
|
|
758
|
+
user_id: this.user.id,
|
|
759
|
+
text: `your application has been ${action}ed`,
|
|
760
|
+
type: action,
|
|
761
|
+
moduleName: "Empty"
|
|
762
|
+
}
|
|
763
|
+
]);
|
|
764
|
+
if (result.isErr()) {
|
|
765
|
+
const error = result.error;
|
|
766
|
+
if (error instanceof WikidotStatusError && error.statusCode === "no_application") {
|
|
767
|
+
throw new NotFoundException(`Application not found: ${this.user.name}`);
|
|
768
|
+
}
|
|
769
|
+
throw error;
|
|
770
|
+
}
|
|
771
|
+
})(), (error) => {
|
|
772
|
+
if (error instanceof NotFoundException || error instanceof LoginRequiredError) {
|
|
773
|
+
return error;
|
|
774
|
+
}
|
|
775
|
+
return new UnexpectedError(`Failed to process application: ${String(error)}`);
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
accept() {
|
|
779
|
+
return this.process("accept");
|
|
780
|
+
}
|
|
781
|
+
decline() {
|
|
782
|
+
return this.process("decline");
|
|
783
|
+
}
|
|
784
|
+
toString() {
|
|
785
|
+
return `SiteApplication(user=${this.user.name}, site=${this.site.unixName}, text=${this.text})`;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
__legacyDecorateClassTS([
|
|
789
|
+
RequireLogin
|
|
790
|
+
], SiteApplication.prototype, "process", null);
|
|
791
|
+
|
|
792
|
+
// src/module/site/site-member.ts
|
|
793
|
+
import * as cheerio3 from "cheerio";
|
|
794
|
+
class SiteMember {
|
|
795
|
+
site;
|
|
796
|
+
user;
|
|
797
|
+
joinedAt;
|
|
798
|
+
constructor(data) {
|
|
799
|
+
this.site = data.site;
|
|
800
|
+
this.user = data.user;
|
|
801
|
+
this.joinedAt = data.joinedAt;
|
|
802
|
+
}
|
|
803
|
+
static parse(site, html) {
|
|
804
|
+
const $ = cheerio3.load(html);
|
|
805
|
+
const members = [];
|
|
806
|
+
$("table tr").each((_i, row) => {
|
|
807
|
+
const tds = $(row).find("td");
|
|
808
|
+
const userElem = $(tds[0]).find(".printuser");
|
|
809
|
+
if (userElem.length === 0) {
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
const user = parseUser(site.client, userElem);
|
|
813
|
+
let joinedAt = null;
|
|
814
|
+
if (tds.length >= 2) {
|
|
815
|
+
const odateElem = $(tds[1]).find(".odate");
|
|
816
|
+
if (odateElem.length > 0) {
|
|
817
|
+
joinedAt = parseOdate(odateElem);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
members.push(new SiteMember({ site, user, joinedAt }));
|
|
821
|
+
});
|
|
822
|
+
return members;
|
|
823
|
+
}
|
|
824
|
+
static getMembers(site, group = "") {
|
|
825
|
+
return fromPromise((async () => {
|
|
826
|
+
const members = [];
|
|
827
|
+
const firstResult = await site.amcRequest([
|
|
828
|
+
{
|
|
829
|
+
moduleName: "membership/MembersListModule",
|
|
830
|
+
page: 1,
|
|
831
|
+
group
|
|
832
|
+
}
|
|
833
|
+
]);
|
|
834
|
+
if (firstResult.isErr()) {
|
|
835
|
+
throw firstResult.error;
|
|
836
|
+
}
|
|
837
|
+
const firstResponse = firstResult.value[0];
|
|
838
|
+
if (!firstResponse) {
|
|
839
|
+
throw new UnexpectedError("Empty response");
|
|
840
|
+
}
|
|
841
|
+
const firstHtml = String(firstResponse.body ?? "");
|
|
842
|
+
members.push(...SiteMember.parse(site, firstHtml));
|
|
843
|
+
const $first = cheerio3.load(firstHtml);
|
|
844
|
+
const pagerLinks = $first("div.pager a");
|
|
845
|
+
if (pagerLinks.length < 2) {
|
|
846
|
+
return members;
|
|
847
|
+
}
|
|
848
|
+
const lastPageText = $first(pagerLinks[pagerLinks.length - 2]).text().trim();
|
|
849
|
+
const lastPage = Number.parseInt(lastPageText, 10) || 1;
|
|
850
|
+
if (lastPage <= 1) {
|
|
851
|
+
return members;
|
|
852
|
+
}
|
|
853
|
+
const bodies = [];
|
|
854
|
+
for (let page = 2;page <= lastPage; page++) {
|
|
855
|
+
bodies.push({
|
|
856
|
+
moduleName: "membership/MembersListModule",
|
|
857
|
+
page,
|
|
858
|
+
group
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
const additionalResults = await site.amcRequest(bodies);
|
|
862
|
+
if (additionalResults.isErr()) {
|
|
863
|
+
throw additionalResults.error;
|
|
864
|
+
}
|
|
865
|
+
for (const response of additionalResults.value) {
|
|
866
|
+
const html = String(response?.body ?? "");
|
|
867
|
+
members.push(...SiteMember.parse(site, html));
|
|
868
|
+
}
|
|
869
|
+
return members;
|
|
870
|
+
})(), (error) => new UnexpectedError(`Failed to get members: ${String(error)}`));
|
|
871
|
+
}
|
|
872
|
+
changeGroup(event) {
|
|
873
|
+
return fromPromise((async () => {
|
|
874
|
+
const result = await this.site.amcRequest([
|
|
875
|
+
{
|
|
876
|
+
action: "ManageSiteMembershipAction",
|
|
877
|
+
event,
|
|
878
|
+
user_id: this.user.id,
|
|
879
|
+
moduleName: ""
|
|
880
|
+
}
|
|
881
|
+
]);
|
|
882
|
+
if (result.isErr()) {
|
|
883
|
+
const error = result.error;
|
|
884
|
+
if (error instanceof WikidotStatusError) {
|
|
885
|
+
if (error.statusCode === "not_already") {
|
|
886
|
+
throw new TargetError(`User is not moderator/admin: ${this.user.name}`);
|
|
887
|
+
}
|
|
888
|
+
if (error.statusCode === "already_admin" || error.statusCode === "already_moderator") {
|
|
889
|
+
throw new TargetError(`User is already ${error.statusCode.replace("already_", "")}: ${this.user.name}`);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
throw error;
|
|
893
|
+
}
|
|
894
|
+
})(), (error) => {
|
|
895
|
+
if (error instanceof TargetError || error instanceof LoginRequiredError) {
|
|
896
|
+
return error;
|
|
897
|
+
}
|
|
898
|
+
return new UnexpectedError(`Failed to change member group: ${String(error)}`);
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
toModerator() {
|
|
902
|
+
return this.changeGroup("toModerators");
|
|
903
|
+
}
|
|
904
|
+
removeModerator() {
|
|
905
|
+
return this.changeGroup("removeModerator");
|
|
906
|
+
}
|
|
907
|
+
toAdmin() {
|
|
908
|
+
return this.changeGroup("toAdmins");
|
|
909
|
+
}
|
|
910
|
+
removeAdmin() {
|
|
911
|
+
return this.changeGroup("removeAdmin");
|
|
912
|
+
}
|
|
913
|
+
toString() {
|
|
914
|
+
return `SiteMember(user=${this.user.name}, site=${this.site.unixName})`;
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
__legacyDecorateClassTS([
|
|
918
|
+
RequireLogin
|
|
919
|
+
], SiteMember.prototype, "changeGroup", null);
|
|
920
|
+
|
|
921
|
+
// src/module/site/accessors/member-accessor.ts
|
|
922
|
+
class MemberAccessor {
|
|
923
|
+
site;
|
|
924
|
+
constructor(site) {
|
|
925
|
+
this.site = site;
|
|
926
|
+
}
|
|
927
|
+
getAll() {
|
|
928
|
+
return SiteMember.getMembers(this.site, "");
|
|
929
|
+
}
|
|
930
|
+
getModerators() {
|
|
931
|
+
return SiteMember.getMembers(this.site, "moderators");
|
|
932
|
+
}
|
|
933
|
+
getAdmins() {
|
|
934
|
+
return SiteMember.getMembers(this.site, "admins");
|
|
935
|
+
}
|
|
936
|
+
getApplications() {
|
|
937
|
+
return SiteApplication.acquireAll(this.site);
|
|
938
|
+
}
|
|
939
|
+
lookup(query) {
|
|
940
|
+
return QuickModule.memberLookup(this.site.id, query);
|
|
941
|
+
}
|
|
942
|
+
invite(user, text) {
|
|
943
|
+
return fromPromise((async () => {
|
|
944
|
+
const result = await this.site.amcRequest([
|
|
945
|
+
{
|
|
946
|
+
action: "ManageSiteMembershipAction",
|
|
947
|
+
event: "inviteMember",
|
|
948
|
+
user_id: user.id,
|
|
949
|
+
text,
|
|
950
|
+
moduleName: "Empty"
|
|
951
|
+
}
|
|
952
|
+
]);
|
|
953
|
+
if (result.isErr()) {
|
|
954
|
+
const error = result.error;
|
|
955
|
+
if (error instanceof WikidotStatusError) {
|
|
956
|
+
if (error.statusCode === "already_invited") {
|
|
957
|
+
throw new TargetError(`User is already invited to ${this.site.unixName}: ${user.name}`);
|
|
958
|
+
}
|
|
959
|
+
if (error.statusCode === "already_member") {
|
|
960
|
+
throw new TargetError(`User is already a member of ${this.site.unixName}: ${user.name}`);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
throw error;
|
|
964
|
+
}
|
|
965
|
+
})(), (error) => {
|
|
966
|
+
if (error instanceof TargetError || error instanceof LoginRequiredError) {
|
|
967
|
+
return error;
|
|
968
|
+
}
|
|
969
|
+
return new UnexpectedError(`Failed to invite user: ${String(error)}`);
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
__legacyDecorateClassTS([
|
|
974
|
+
RequireLogin
|
|
975
|
+
], MemberAccessor.prototype, "invite", null);
|
|
976
|
+
// src/module/page/page.ts
|
|
977
|
+
import * as cheerio6 from "cheerio";
|
|
978
|
+
import { z as z3 } from "zod";
|
|
979
|
+
|
|
980
|
+
// src/module/page/page-file.ts
|
|
981
|
+
import * as cheerio4 from "cheerio";
|
|
982
|
+
class PageFile {
|
|
983
|
+
page;
|
|
984
|
+
id;
|
|
985
|
+
name;
|
|
986
|
+
url;
|
|
987
|
+
mimeType;
|
|
988
|
+
size;
|
|
989
|
+
constructor(data) {
|
|
990
|
+
this.page = data.page;
|
|
991
|
+
this.id = data.id;
|
|
992
|
+
this.name = data.name;
|
|
993
|
+
this.url = data.url;
|
|
994
|
+
this.mimeType = data.mimeType;
|
|
995
|
+
this.size = data.size;
|
|
996
|
+
}
|
|
997
|
+
toString() {
|
|
998
|
+
return `PageFile(id=${this.id}, name=${this.name}, size=${this.size})`;
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
class PageFileCollection extends Array {
|
|
1003
|
+
page;
|
|
1004
|
+
constructor(page, files) {
|
|
1005
|
+
super();
|
|
1006
|
+
this.page = page;
|
|
1007
|
+
if (files) {
|
|
1008
|
+
this.push(...files);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
findById(id) {
|
|
1012
|
+
return this.find((file) => file.id === id);
|
|
1013
|
+
}
|
|
1014
|
+
findByName(name) {
|
|
1015
|
+
return this.find((file) => file.name === name);
|
|
1016
|
+
}
|
|
1017
|
+
static parseSize(sizeText) {
|
|
1018
|
+
const text = sizeText.trim();
|
|
1019
|
+
if (text.includes("Bytes")) {
|
|
1020
|
+
return Math.floor(Number.parseFloat(text.replace("Bytes", "").trim()));
|
|
1021
|
+
}
|
|
1022
|
+
if (text.includes("kB")) {
|
|
1023
|
+
return Math.floor(Number.parseFloat(text.replace("kB", "").trim()) * 1000);
|
|
1024
|
+
}
|
|
1025
|
+
if (text.includes("MB")) {
|
|
1026
|
+
return Math.floor(Number.parseFloat(text.replace("MB", "").trim()) * 1e6);
|
|
1027
|
+
}
|
|
1028
|
+
if (text.includes("GB")) {
|
|
1029
|
+
return Math.floor(Number.parseFloat(text.replace("GB", "").trim()) * 1e9);
|
|
1030
|
+
}
|
|
1031
|
+
return 0;
|
|
1032
|
+
}
|
|
1033
|
+
static acquire(page) {
|
|
1034
|
+
if (page.id === null) {
|
|
1035
|
+
return fromPromise(Promise.reject(new Error("Page ID not acquired")), () => new UnexpectedError("Page ID must be acquired before getting files"));
|
|
1036
|
+
}
|
|
1037
|
+
const pageId = page.id;
|
|
1038
|
+
return fromPromise((async () => {
|
|
1039
|
+
const result = await page.site.amcRequest([
|
|
1040
|
+
{
|
|
1041
|
+
moduleName: "files/PageFilesModule",
|
|
1042
|
+
page_id: pageId
|
|
1043
|
+
}
|
|
1044
|
+
]);
|
|
1045
|
+
if (result.isErr()) {
|
|
1046
|
+
throw result.error;
|
|
1047
|
+
}
|
|
1048
|
+
const response = result.value[0];
|
|
1049
|
+
if (!response) {
|
|
1050
|
+
throw new UnexpectedError("Empty response");
|
|
1051
|
+
}
|
|
1052
|
+
const html = String(response.body ?? "");
|
|
1053
|
+
const $ = cheerio4.load(html);
|
|
1054
|
+
const filesTable = $("table.page-files");
|
|
1055
|
+
if (filesTable.length === 0) {
|
|
1056
|
+
return new PageFileCollection(page, []);
|
|
1057
|
+
}
|
|
1058
|
+
const files = [];
|
|
1059
|
+
filesTable.find("tbody tr[id^='file-row-']").each((_i, row) => {
|
|
1060
|
+
const rowId = $(row).attr("id");
|
|
1061
|
+
if (!rowId)
|
|
1062
|
+
return;
|
|
1063
|
+
const fileId = Number.parseInt(rowId.replace("file-row-", ""), 10);
|
|
1064
|
+
const tds = $(row).find("td");
|
|
1065
|
+
if (tds.length < 3)
|
|
1066
|
+
return;
|
|
1067
|
+
const linkElem = $(tds[0]).find("a");
|
|
1068
|
+
if (linkElem.length === 0)
|
|
1069
|
+
return;
|
|
1070
|
+
const name = linkElem.text().trim();
|
|
1071
|
+
const href = linkElem.attr("href") ?? "";
|
|
1072
|
+
const url = `${page.site.getBaseUrl()}${href}`;
|
|
1073
|
+
const mimeElem = $(tds[1]).find("span");
|
|
1074
|
+
const mimeType = mimeElem.attr("title") ?? "";
|
|
1075
|
+
const sizeText = $(tds[2]).text().trim();
|
|
1076
|
+
const size = PageFileCollection.parseSize(sizeText);
|
|
1077
|
+
files.push(new PageFile({
|
|
1078
|
+
page,
|
|
1079
|
+
id: fileId,
|
|
1080
|
+
name,
|
|
1081
|
+
url,
|
|
1082
|
+
mimeType,
|
|
1083
|
+
size
|
|
1084
|
+
}));
|
|
1085
|
+
});
|
|
1086
|
+
return new PageFileCollection(page, files);
|
|
1087
|
+
})(), (error) => new UnexpectedError(`Failed to acquire files: ${String(error)}`));
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
// src/module/page/page-meta.ts
|
|
1092
|
+
import * as cheerio5 from "cheerio";
|
|
1093
|
+
class PageMeta {
|
|
1094
|
+
page;
|
|
1095
|
+
name;
|
|
1096
|
+
content;
|
|
1097
|
+
constructor(data) {
|
|
1098
|
+
this.page = data.page;
|
|
1099
|
+
this.name = data.name;
|
|
1100
|
+
this.content = data.content;
|
|
1101
|
+
}
|
|
1102
|
+
update(content) {
|
|
1103
|
+
return PageMetaCollection.setMeta(this.page, this.name, content);
|
|
1104
|
+
}
|
|
1105
|
+
delete() {
|
|
1106
|
+
return PageMetaCollection.deleteMeta(this.page, this.name);
|
|
1107
|
+
}
|
|
1108
|
+
toString() {
|
|
1109
|
+
return `PageMeta(name=${this.name}, content=${this.content})`;
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
class PageMetaCollection extends Array {
|
|
1114
|
+
page;
|
|
1115
|
+
constructor(page, metas) {
|
|
1116
|
+
super();
|
|
1117
|
+
this.page = page;
|
|
1118
|
+
if (metas) {
|
|
1119
|
+
this.push(...metas);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
findByName(name) {
|
|
1123
|
+
return this.find((meta) => meta.name === name);
|
|
1124
|
+
}
|
|
1125
|
+
static acquire(page) {
|
|
1126
|
+
return fromPromise((async () => {
|
|
1127
|
+
const result = await page.site.amcRequest([
|
|
1128
|
+
{
|
|
1129
|
+
moduleName: "edit/EditMetaModule",
|
|
1130
|
+
page_id: page.id
|
|
1131
|
+
}
|
|
1132
|
+
]);
|
|
1133
|
+
if (result.isErr()) {
|
|
1134
|
+
throw result.error;
|
|
1135
|
+
}
|
|
1136
|
+
const response = result.value[0];
|
|
1137
|
+
if (!response) {
|
|
1138
|
+
throw new NoElementError("Empty response");
|
|
1139
|
+
}
|
|
1140
|
+
const html = String(response.body ?? "");
|
|
1141
|
+
const $ = cheerio5.load(html);
|
|
1142
|
+
const metas = [];
|
|
1143
|
+
$("table.meta-table tr").each((_i, elem) => {
|
|
1144
|
+
const $row = $(elem);
|
|
1145
|
+
const $cells = $row.find("td");
|
|
1146
|
+
if ($cells.length < 2)
|
|
1147
|
+
return;
|
|
1148
|
+
const name = $($cells[0]).text().trim();
|
|
1149
|
+
const content = $($cells[1]).text().trim();
|
|
1150
|
+
if (name) {
|
|
1151
|
+
metas.push(new PageMeta({
|
|
1152
|
+
page,
|
|
1153
|
+
name,
|
|
1154
|
+
content
|
|
1155
|
+
}));
|
|
1156
|
+
}
|
|
1157
|
+
});
|
|
1158
|
+
return new PageMetaCollection(page, metas);
|
|
1159
|
+
})(), (error) => {
|
|
1160
|
+
if (error instanceof NoElementError) {
|
|
1161
|
+
return error;
|
|
1162
|
+
}
|
|
1163
|
+
return new UnexpectedError(`Failed to acquire page metas: ${String(error)}`);
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1166
|
+
static setMeta(page, name, content) {
|
|
1167
|
+
const loginResult = page.site.client.requireLogin();
|
|
1168
|
+
if (loginResult.isErr()) {
|
|
1169
|
+
return fromPromise(Promise.reject(loginResult.error), () => new LoginRequiredError("Login required to set meta tag"));
|
|
1170
|
+
}
|
|
1171
|
+
return fromPromise((async () => {
|
|
1172
|
+
const result = await page.site.amcRequest([
|
|
1173
|
+
{
|
|
1174
|
+
action: "WikiPageAction",
|
|
1175
|
+
event: "saveMetaTag",
|
|
1176
|
+
moduleName: "Empty",
|
|
1177
|
+
page_id: page.id,
|
|
1178
|
+
meta_name: name,
|
|
1179
|
+
meta_content: content
|
|
1180
|
+
}
|
|
1181
|
+
]);
|
|
1182
|
+
if (result.isErr()) {
|
|
1183
|
+
throw result.error;
|
|
1184
|
+
}
|
|
1185
|
+
})(), (error) => {
|
|
1186
|
+
if (error instanceof LoginRequiredError) {
|
|
1187
|
+
return error;
|
|
1188
|
+
}
|
|
1189
|
+
return new UnexpectedError(`Failed to set meta tag: ${String(error)}`);
|
|
1190
|
+
});
|
|
1191
|
+
}
|
|
1192
|
+
static deleteMeta(page, name) {
|
|
1193
|
+
const loginResult = page.site.client.requireLogin();
|
|
1194
|
+
if (loginResult.isErr()) {
|
|
1195
|
+
return fromPromise(Promise.reject(loginResult.error), () => new LoginRequiredError("Login required to delete meta tag"));
|
|
1196
|
+
}
|
|
1197
|
+
return fromPromise((async () => {
|
|
1198
|
+
const result = await page.site.amcRequest([
|
|
1199
|
+
{
|
|
1200
|
+
action: "WikiPageAction",
|
|
1201
|
+
event: "deleteMetaTag",
|
|
1202
|
+
moduleName: "Empty",
|
|
1203
|
+
page_id: page.id,
|
|
1204
|
+
meta_name: name
|
|
1205
|
+
}
|
|
1206
|
+
]);
|
|
1207
|
+
if (result.isErr()) {
|
|
1208
|
+
throw result.error;
|
|
1209
|
+
}
|
|
1210
|
+
})(), (error) => {
|
|
1211
|
+
if (error instanceof LoginRequiredError) {
|
|
1212
|
+
return error;
|
|
1213
|
+
}
|
|
1214
|
+
return new UnexpectedError(`Failed to delete meta tag: ${String(error)}`);
|
|
1215
|
+
});
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
// src/module/page/page-source.ts
|
|
1220
|
+
class PageSource {
|
|
1221
|
+
page;
|
|
1222
|
+
wikiText;
|
|
1223
|
+
constructor(data) {
|
|
1224
|
+
this.page = data.page;
|
|
1225
|
+
this.wikiText = data.wikiText;
|
|
1226
|
+
}
|
|
1227
|
+
toString() {
|
|
1228
|
+
return `PageSource(page=${this.page.fullname}, length=${this.wikiText.length})`;
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
// src/module/page/page-vote.ts
|
|
1233
|
+
class PageVote {
|
|
1234
|
+
page;
|
|
1235
|
+
user;
|
|
1236
|
+
value;
|
|
1237
|
+
constructor(data) {
|
|
1238
|
+
this.page = data.page;
|
|
1239
|
+
this.user = data.user;
|
|
1240
|
+
this.value = data.value;
|
|
1241
|
+
}
|
|
1242
|
+
toString() {
|
|
1243
|
+
return `PageVote(user=${this.user.name}, value=${this.value})`;
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
class PageVoteCollection extends Array {
|
|
1248
|
+
page;
|
|
1249
|
+
constructor(page, votes) {
|
|
1250
|
+
super();
|
|
1251
|
+
this.page = page;
|
|
1252
|
+
if (votes) {
|
|
1253
|
+
this.push(...votes);
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
findByUser(user) {
|
|
1257
|
+
return this.find((vote) => vote.user.id === user.id);
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
// src/module/page/search-query.ts
|
|
1262
|
+
var DEFAULT_PER_PAGE = 250;
|
|
1263
|
+
var DEFAULT_MODULE_BODY = [
|
|
1264
|
+
"fullname",
|
|
1265
|
+
"category",
|
|
1266
|
+
"name",
|
|
1267
|
+
"title",
|
|
1268
|
+
"created_at",
|
|
1269
|
+
"created_by_linked",
|
|
1270
|
+
"updated_at",
|
|
1271
|
+
"updated_by_linked",
|
|
1272
|
+
"commented_at",
|
|
1273
|
+
"commented_by_linked",
|
|
1274
|
+
"parent_fullname",
|
|
1275
|
+
"comments",
|
|
1276
|
+
"size",
|
|
1277
|
+
"children",
|
|
1278
|
+
"rating_votes",
|
|
1279
|
+
"rating",
|
|
1280
|
+
"rating_percent",
|
|
1281
|
+
"revisions",
|
|
1282
|
+
"tags",
|
|
1283
|
+
"_tags"
|
|
1284
|
+
];
|
|
1285
|
+
|
|
1286
|
+
class SearchPagesQuery {
|
|
1287
|
+
pagetype;
|
|
1288
|
+
category;
|
|
1289
|
+
tags;
|
|
1290
|
+
parent;
|
|
1291
|
+
linkTo;
|
|
1292
|
+
createdAt;
|
|
1293
|
+
updatedAt;
|
|
1294
|
+
createdBy;
|
|
1295
|
+
rating;
|
|
1296
|
+
votes;
|
|
1297
|
+
name;
|
|
1298
|
+
fullname;
|
|
1299
|
+
range;
|
|
1300
|
+
order;
|
|
1301
|
+
offset;
|
|
1302
|
+
limit;
|
|
1303
|
+
perPage;
|
|
1304
|
+
separate;
|
|
1305
|
+
wrapper;
|
|
1306
|
+
constructor(params = {}) {
|
|
1307
|
+
this.pagetype = params.pagetype ?? "*";
|
|
1308
|
+
this.category = params.category ?? "*";
|
|
1309
|
+
this.tags = params.tags ?? null;
|
|
1310
|
+
this.parent = params.parent ?? null;
|
|
1311
|
+
this.linkTo = params.linkTo ?? null;
|
|
1312
|
+
this.createdAt = params.createdAt ?? null;
|
|
1313
|
+
this.updatedAt = params.updatedAt ?? null;
|
|
1314
|
+
this.createdBy = params.createdBy ?? null;
|
|
1315
|
+
this.rating = params.rating ?? null;
|
|
1316
|
+
this.votes = params.votes ?? null;
|
|
1317
|
+
this.name = params.name ?? null;
|
|
1318
|
+
this.fullname = params.fullname ?? null;
|
|
1319
|
+
this.range = params.range ?? null;
|
|
1320
|
+
this.order = params.order ?? "created_at desc";
|
|
1321
|
+
this.offset = params.offset ?? 0;
|
|
1322
|
+
this.limit = params.limit ?? null;
|
|
1323
|
+
this.perPage = params.perPage ?? DEFAULT_PER_PAGE;
|
|
1324
|
+
this.separate = params.separate ?? "no";
|
|
1325
|
+
this.wrapper = params.wrapper ?? "no";
|
|
1326
|
+
}
|
|
1327
|
+
asDict() {
|
|
1328
|
+
const result = {};
|
|
1329
|
+
if (this.pagetype !== "*")
|
|
1330
|
+
result.pagetype = this.pagetype;
|
|
1331
|
+
if (this.category !== "*")
|
|
1332
|
+
result.category = this.category;
|
|
1333
|
+
if (this.tags !== null) {
|
|
1334
|
+
result.tags = Array.isArray(this.tags) ? this.tags.join(" ") : this.tags;
|
|
1335
|
+
}
|
|
1336
|
+
if (this.parent !== null)
|
|
1337
|
+
result.parent = this.parent;
|
|
1338
|
+
if (this.linkTo !== null)
|
|
1339
|
+
result.link_to = this.linkTo;
|
|
1340
|
+
if (this.createdAt !== null)
|
|
1341
|
+
result.created_at = this.createdAt;
|
|
1342
|
+
if (this.updatedAt !== null)
|
|
1343
|
+
result.updated_at = this.updatedAt;
|
|
1344
|
+
if (this.createdBy !== null) {
|
|
1345
|
+
result.created_by = typeof this.createdBy === "string" ? this.createdBy : this.createdBy.name;
|
|
1346
|
+
}
|
|
1347
|
+
if (this.rating !== null)
|
|
1348
|
+
result.rating = this.rating;
|
|
1349
|
+
if (this.votes !== null)
|
|
1350
|
+
result.votes = this.votes;
|
|
1351
|
+
if (this.name !== null)
|
|
1352
|
+
result.name = this.name;
|
|
1353
|
+
if (this.fullname !== null)
|
|
1354
|
+
result.fullname = this.fullname;
|
|
1355
|
+
if (this.range !== null)
|
|
1356
|
+
result.range = this.range;
|
|
1357
|
+
result.order = this.order;
|
|
1358
|
+
result.offset = this.offset;
|
|
1359
|
+
if (this.limit !== null)
|
|
1360
|
+
result.limit = this.limit;
|
|
1361
|
+
result.perPage = this.perPage;
|
|
1362
|
+
result.separate = this.separate;
|
|
1363
|
+
result.wrapper = this.wrapper;
|
|
1364
|
+
return result;
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
// src/module/page/page.ts
|
|
1369
|
+
var pageParamsSchema = z3.object({
|
|
1370
|
+
fullname: z3.string().default(""),
|
|
1371
|
+
name: z3.string().default(""),
|
|
1372
|
+
category: z3.string().default(""),
|
|
1373
|
+
title: z3.string().default(""),
|
|
1374
|
+
children_count: z3.number().default(0),
|
|
1375
|
+
comments_count: z3.number().default(0),
|
|
1376
|
+
size: z3.number().default(0),
|
|
1377
|
+
rating: z3.number().default(0),
|
|
1378
|
+
votes_count: z3.number().default(0),
|
|
1379
|
+
rating_percent: z3.number().nullable().default(null),
|
|
1380
|
+
revisions_count: z3.number().default(0),
|
|
1381
|
+
parent_fullname: z3.string().nullable().default(null),
|
|
1382
|
+
tags: z3.array(z3.string()).default([]),
|
|
1383
|
+
created_by: z3.custom().nullable().default(null),
|
|
1384
|
+
created_at: z3.date().nullable().default(null),
|
|
1385
|
+
updated_by: z3.custom().nullable().default(null),
|
|
1386
|
+
updated_at: z3.date().nullable().default(null),
|
|
1387
|
+
commented_by: z3.custom().nullable().default(null),
|
|
1388
|
+
commented_at: z3.date().nullable().default(null)
|
|
1389
|
+
});
|
|
1390
|
+
|
|
1391
|
+
class Page {
|
|
1392
|
+
site;
|
|
1393
|
+
fullname;
|
|
1394
|
+
name;
|
|
1395
|
+
category;
|
|
1396
|
+
title;
|
|
1397
|
+
childrenCount;
|
|
1398
|
+
commentsCount;
|
|
1399
|
+
size;
|
|
1400
|
+
rating;
|
|
1401
|
+
votesCount;
|
|
1402
|
+
ratingPercent;
|
|
1403
|
+
revisionsCount;
|
|
1404
|
+
parentFullname;
|
|
1405
|
+
tags;
|
|
1406
|
+
createdBy;
|
|
1407
|
+
createdAt;
|
|
1408
|
+
updatedBy;
|
|
1409
|
+
updatedAt;
|
|
1410
|
+
commentedBy;
|
|
1411
|
+
commentedAt;
|
|
1412
|
+
_id = null;
|
|
1413
|
+
_source = null;
|
|
1414
|
+
_revisions = null;
|
|
1415
|
+
_votes = null;
|
|
1416
|
+
constructor(data) {
|
|
1417
|
+
this.site = data.site;
|
|
1418
|
+
this.fullname = data.fullname;
|
|
1419
|
+
this.name = data.name;
|
|
1420
|
+
this.category = data.category;
|
|
1421
|
+
this.title = data.title;
|
|
1422
|
+
this.childrenCount = data.childrenCount;
|
|
1423
|
+
this.commentsCount = data.commentsCount;
|
|
1424
|
+
this.size = data.size;
|
|
1425
|
+
this.rating = data.rating;
|
|
1426
|
+
this.votesCount = data.votesCount;
|
|
1427
|
+
this.ratingPercent = data.ratingPercent;
|
|
1428
|
+
this.revisionsCount = data.revisionsCount;
|
|
1429
|
+
this.parentFullname = data.parentFullname;
|
|
1430
|
+
this.tags = data.tags;
|
|
1431
|
+
this.createdBy = data.createdBy;
|
|
1432
|
+
this.createdAt = data.createdAt;
|
|
1433
|
+
this.updatedBy = data.updatedBy;
|
|
1434
|
+
this.updatedAt = data.updatedAt;
|
|
1435
|
+
this.commentedBy = data.commentedBy;
|
|
1436
|
+
this.commentedAt = data.commentedAt;
|
|
1437
|
+
}
|
|
1438
|
+
getUrl() {
|
|
1439
|
+
return `${this.site.getBaseUrl()}/${this.fullname}`;
|
|
1440
|
+
}
|
|
1441
|
+
isIdAcquired() {
|
|
1442
|
+
return this._id !== null;
|
|
1443
|
+
}
|
|
1444
|
+
get id() {
|
|
1445
|
+
return this._id;
|
|
1446
|
+
}
|
|
1447
|
+
set id(value) {
|
|
1448
|
+
this._id = value;
|
|
1449
|
+
}
|
|
1450
|
+
get source() {
|
|
1451
|
+
return this._source;
|
|
1452
|
+
}
|
|
1453
|
+
set source(value) {
|
|
1454
|
+
this._source = value;
|
|
1455
|
+
}
|
|
1456
|
+
get revisions() {
|
|
1457
|
+
return this._revisions;
|
|
1458
|
+
}
|
|
1459
|
+
set revisions(value) {
|
|
1460
|
+
this._revisions = value;
|
|
1461
|
+
}
|
|
1462
|
+
get votes() {
|
|
1463
|
+
return this._votes;
|
|
1464
|
+
}
|
|
1465
|
+
set votes(value) {
|
|
1466
|
+
this._votes = value;
|
|
1467
|
+
}
|
|
1468
|
+
get latestRevision() {
|
|
1469
|
+
if (!this._revisions || this._revisions.length === 0)
|
|
1470
|
+
return;
|
|
1471
|
+
return this._revisions.reduce((max, rev) => rev.revNo > max.revNo ? rev : max);
|
|
1472
|
+
}
|
|
1473
|
+
requireId(operation) {
|
|
1474
|
+
if (this._id === null) {
|
|
1475
|
+
return {
|
|
1476
|
+
ok: false,
|
|
1477
|
+
error: fromPromise(Promise.reject(new Error("Page ID not acquired")), () => new UnexpectedError(`Page ID must be acquired before ${operation}`))
|
|
1478
|
+
};
|
|
1479
|
+
}
|
|
1480
|
+
return { ok: true, id: this._id };
|
|
1481
|
+
}
|
|
1482
|
+
destroy() {
|
|
1483
|
+
const idCheck = this.requireId("deletion");
|
|
1484
|
+
if (!idCheck.ok)
|
|
1485
|
+
return idCheck.error;
|
|
1486
|
+
return fromPromise((async () => {
|
|
1487
|
+
const result = await this.site.amcRequest([
|
|
1488
|
+
{
|
|
1489
|
+
action: "WikiPageAction",
|
|
1490
|
+
event: "deletePage",
|
|
1491
|
+
page_id: this._id,
|
|
1492
|
+
moduleName: "Empty"
|
|
1493
|
+
}
|
|
1494
|
+
]);
|
|
1495
|
+
if (result.isErr()) {
|
|
1496
|
+
throw result.error;
|
|
1497
|
+
}
|
|
1498
|
+
})(), (error) => new UnexpectedError(`Failed to delete page: ${String(error)}`));
|
|
1499
|
+
}
|
|
1500
|
+
commitTags() {
|
|
1501
|
+
const idCheck = this.requireId("saving tags");
|
|
1502
|
+
if (!idCheck.ok)
|
|
1503
|
+
return idCheck.error;
|
|
1504
|
+
return fromPromise((async () => {
|
|
1505
|
+
const result = await this.site.amcRequest([
|
|
1506
|
+
{
|
|
1507
|
+
tags: this.tags.join(" "),
|
|
1508
|
+
action: "WikiPageAction",
|
|
1509
|
+
event: "saveTags",
|
|
1510
|
+
pageId: this._id,
|
|
1511
|
+
moduleName: "Empty"
|
|
1512
|
+
}
|
|
1513
|
+
]);
|
|
1514
|
+
if (result.isErr()) {
|
|
1515
|
+
throw result.error;
|
|
1516
|
+
}
|
|
1517
|
+
})(), (error) => new UnexpectedError(`Failed to save tags: ${String(error)}`));
|
|
1518
|
+
}
|
|
1519
|
+
setParent(parentFullname) {
|
|
1520
|
+
const idCheck = this.requireId("setting parent");
|
|
1521
|
+
if (!idCheck.ok)
|
|
1522
|
+
return idCheck.error;
|
|
1523
|
+
return fromPromise((async () => {
|
|
1524
|
+
const result = await this.site.amcRequest([
|
|
1525
|
+
{
|
|
1526
|
+
action: "WikiPageAction",
|
|
1527
|
+
event: "setParentPage",
|
|
1528
|
+
moduleName: "Empty",
|
|
1529
|
+
pageId: String(this._id),
|
|
1530
|
+
parentName: parentFullname ?? ""
|
|
1531
|
+
}
|
|
1532
|
+
]);
|
|
1533
|
+
if (result.isErr()) {
|
|
1534
|
+
throw result.error;
|
|
1535
|
+
}
|
|
1536
|
+
this.parentFullname = parentFullname;
|
|
1537
|
+
})(), (error) => new UnexpectedError(`Failed to set parent: ${String(error)}`));
|
|
1538
|
+
}
|
|
1539
|
+
vote(value) {
|
|
1540
|
+
const idCheck = this.requireId("voting");
|
|
1541
|
+
if (!idCheck.ok)
|
|
1542
|
+
return idCheck.error;
|
|
1543
|
+
return fromPromise((async () => {
|
|
1544
|
+
const result = await this.site.amcRequest([
|
|
1545
|
+
{
|
|
1546
|
+
action: "RateAction",
|
|
1547
|
+
event: "ratePage",
|
|
1548
|
+
moduleName: "Empty",
|
|
1549
|
+
pageId: this._id,
|
|
1550
|
+
points: value,
|
|
1551
|
+
force: "yes"
|
|
1552
|
+
}
|
|
1553
|
+
]);
|
|
1554
|
+
if (result.isErr()) {
|
|
1555
|
+
throw result.error;
|
|
1556
|
+
}
|
|
1557
|
+
const response = result.value[0];
|
|
1558
|
+
if (!response) {
|
|
1559
|
+
throw new UnexpectedError("Empty response from vote request");
|
|
1560
|
+
}
|
|
1561
|
+
const newRating = Number.parseInt(String(response.points ?? this.rating), 10);
|
|
1562
|
+
this.rating = newRating;
|
|
1563
|
+
return newRating;
|
|
1564
|
+
})(), (error) => new UnexpectedError(`Failed to vote: ${String(error)}`));
|
|
1565
|
+
}
|
|
1566
|
+
cancelVote() {
|
|
1567
|
+
const idCheck = this.requireId("canceling vote");
|
|
1568
|
+
if (!idCheck.ok)
|
|
1569
|
+
return idCheck.error;
|
|
1570
|
+
return fromPromise((async () => {
|
|
1571
|
+
const result = await this.site.amcRequest([
|
|
1572
|
+
{
|
|
1573
|
+
action: "RateAction",
|
|
1574
|
+
event: "cancelVote",
|
|
1575
|
+
moduleName: "Empty",
|
|
1576
|
+
pageId: this._id
|
|
1577
|
+
}
|
|
1578
|
+
]);
|
|
1579
|
+
if (result.isErr()) {
|
|
1580
|
+
throw result.error;
|
|
1581
|
+
}
|
|
1582
|
+
const response = result.value[0];
|
|
1583
|
+
if (!response) {
|
|
1584
|
+
throw new UnexpectedError("Empty response from cancel vote request");
|
|
1585
|
+
}
|
|
1586
|
+
const newRating = Number.parseInt(String(response.points ?? this.rating), 10);
|
|
1587
|
+
this.rating = newRating;
|
|
1588
|
+
return newRating;
|
|
1589
|
+
})(), (error) => new UnexpectedError(`Failed to cancel vote: ${String(error)}`));
|
|
1590
|
+
}
|
|
1591
|
+
edit(options) {
|
|
1592
|
+
const idCheck = this.requireId("editing");
|
|
1593
|
+
if (!idCheck.ok)
|
|
1594
|
+
return idCheck.error;
|
|
1595
|
+
const pageId = idCheck.id;
|
|
1596
|
+
return fromPromise((async () => {
|
|
1597
|
+
let currentSource = options.source;
|
|
1598
|
+
if (currentSource === undefined) {
|
|
1599
|
+
const existingSource = this._source;
|
|
1600
|
+
if (existingSource !== null) {
|
|
1601
|
+
currentSource = existingSource.wikiText;
|
|
1602
|
+
} else {
|
|
1603
|
+
const sourceResult = await PageCollection.acquirePageSources(this.site, [this]);
|
|
1604
|
+
if (sourceResult.isErr()) {
|
|
1605
|
+
throw sourceResult.error;
|
|
1606
|
+
}
|
|
1607
|
+
currentSource = this._source?.wikiText ?? "";
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
const result = await PageCollection.createOrEdit(this.site, this.fullname, {
|
|
1611
|
+
pageId,
|
|
1612
|
+
title: options.title ?? this.title,
|
|
1613
|
+
source: currentSource,
|
|
1614
|
+
comment: options.comment ?? "",
|
|
1615
|
+
forceEdit: options.forceEdit ?? false
|
|
1616
|
+
});
|
|
1617
|
+
if (result.isErr()) {
|
|
1618
|
+
throw result.error;
|
|
1619
|
+
}
|
|
1620
|
+
})(), (error) => {
|
|
1621
|
+
if (error instanceof LoginRequiredError || error instanceof ForbiddenError) {
|
|
1622
|
+
return error;
|
|
1623
|
+
}
|
|
1624
|
+
return new UnexpectedError(`Failed to edit page: ${String(error)}`);
|
|
1625
|
+
});
|
|
1626
|
+
}
|
|
1627
|
+
rename(newFullname) {
|
|
1628
|
+
const idCheck = this.requireId("renaming");
|
|
1629
|
+
if (!idCheck.ok)
|
|
1630
|
+
return idCheck.error;
|
|
1631
|
+
return fromPromise((async () => {
|
|
1632
|
+
const result = await this.site.amcRequest([
|
|
1633
|
+
{
|
|
1634
|
+
action: "WikiPageAction",
|
|
1635
|
+
event: "renamePage",
|
|
1636
|
+
moduleName: "Empty",
|
|
1637
|
+
page_id: this._id,
|
|
1638
|
+
new_name: newFullname
|
|
1639
|
+
}
|
|
1640
|
+
]);
|
|
1641
|
+
if (result.isErr()) {
|
|
1642
|
+
throw result.error;
|
|
1643
|
+
}
|
|
1644
|
+
Object.assign(this, {
|
|
1645
|
+
fullname: newFullname,
|
|
1646
|
+
category: newFullname.includes(":") ? newFullname.split(":")[0] : "_default",
|
|
1647
|
+
name: newFullname.includes(":") ? newFullname.split(":")[1] : newFullname
|
|
1648
|
+
});
|
|
1649
|
+
})(), (error) => new UnexpectedError(`Failed to rename page: ${String(error)}`));
|
|
1650
|
+
}
|
|
1651
|
+
getFiles() {
|
|
1652
|
+
return PageFileCollection.acquire(this);
|
|
1653
|
+
}
|
|
1654
|
+
getDiscussion() {
|
|
1655
|
+
const idCheck = this.requireId("getting discussion");
|
|
1656
|
+
if (!idCheck.ok)
|
|
1657
|
+
return idCheck.error;
|
|
1658
|
+
const pageId = idCheck.id;
|
|
1659
|
+
return fromPromise((async () => {
|
|
1660
|
+
const result = await this.site.amcRequest([
|
|
1661
|
+
{
|
|
1662
|
+
moduleName: "forum/ForumCommentsListModule",
|
|
1663
|
+
pageId
|
|
1664
|
+
}
|
|
1665
|
+
]);
|
|
1666
|
+
if (result.isErr()) {
|
|
1667
|
+
throw result.error;
|
|
1668
|
+
}
|
|
1669
|
+
const response = result.value[0];
|
|
1670
|
+
if (!response) {
|
|
1671
|
+
return null;
|
|
1672
|
+
}
|
|
1673
|
+
const html = String(response.body ?? "");
|
|
1674
|
+
const match = html.match(/WIKIDOT\.modules\.ForumViewThreadModule\.vars\.threadId\s*=\s*(\d+)/);
|
|
1675
|
+
if (!match?.[1]) {
|
|
1676
|
+
return null;
|
|
1677
|
+
}
|
|
1678
|
+
const threadId = Number.parseInt(match[1], 10);
|
|
1679
|
+
const { ForumThread: ForumThread2 } = await import("./shared/index-ytknx2hn.js");
|
|
1680
|
+
const threadResult = await ForumThread2.getFromId(this.site, threadId);
|
|
1681
|
+
if (threadResult.isErr()) {
|
|
1682
|
+
throw threadResult.error;
|
|
1683
|
+
}
|
|
1684
|
+
return threadResult.value;
|
|
1685
|
+
})(), (error) => new UnexpectedError(`Failed to get discussion: ${String(error)}`));
|
|
1686
|
+
}
|
|
1687
|
+
getMetas() {
|
|
1688
|
+
const idCheck = this.requireId("getting metas");
|
|
1689
|
+
if (!idCheck.ok) {
|
|
1690
|
+
return idCheck.error;
|
|
1691
|
+
}
|
|
1692
|
+
return PageMetaCollection.acquire(this);
|
|
1693
|
+
}
|
|
1694
|
+
setMeta(name, content) {
|
|
1695
|
+
const idCheck = this.requireId("setting meta");
|
|
1696
|
+
if (!idCheck.ok) {
|
|
1697
|
+
return idCheck.error;
|
|
1698
|
+
}
|
|
1699
|
+
return PageMetaCollection.setMeta(this, name, content);
|
|
1700
|
+
}
|
|
1701
|
+
deleteMeta(name) {
|
|
1702
|
+
const idCheck = this.requireId("deleting meta");
|
|
1703
|
+
if (!idCheck.ok) {
|
|
1704
|
+
return idCheck.error;
|
|
1705
|
+
}
|
|
1706
|
+
return PageMetaCollection.deleteMeta(this, name);
|
|
1707
|
+
}
|
|
1708
|
+
toString() {
|
|
1709
|
+
return `Page(fullname=${this.fullname}, title=${this.title})`;
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
__legacyDecorateClassTS([
|
|
1713
|
+
RequireLogin
|
|
1714
|
+
], Page.prototype, "destroy", null);
|
|
1715
|
+
__legacyDecorateClassTS([
|
|
1716
|
+
RequireLogin
|
|
1717
|
+
], Page.prototype, "commitTags", null);
|
|
1718
|
+
__legacyDecorateClassTS([
|
|
1719
|
+
RequireLogin
|
|
1720
|
+
], Page.prototype, "setParent", null);
|
|
1721
|
+
__legacyDecorateClassTS([
|
|
1722
|
+
RequireLogin
|
|
1723
|
+
], Page.prototype, "vote", null);
|
|
1724
|
+
__legacyDecorateClassTS([
|
|
1725
|
+
RequireLogin
|
|
1726
|
+
], Page.prototype, "cancelVote", null);
|
|
1727
|
+
__legacyDecorateClassTS([
|
|
1728
|
+
RequireLogin
|
|
1729
|
+
], Page.prototype, "edit", null);
|
|
1730
|
+
__legacyDecorateClassTS([
|
|
1731
|
+
RequireLogin
|
|
1732
|
+
], Page.prototype, "rename", null);
|
|
1733
|
+
|
|
1734
|
+
class PageCollection extends Array {
|
|
1735
|
+
site;
|
|
1736
|
+
constructor(site, pages) {
|
|
1737
|
+
super();
|
|
1738
|
+
this.site = site;
|
|
1739
|
+
if (pages) {
|
|
1740
|
+
this.push(...pages);
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
findByFullname(fullname) {
|
|
1744
|
+
return this.find((page) => page.fullname === fullname);
|
|
1745
|
+
}
|
|
1746
|
+
getPageIds() {
|
|
1747
|
+
return PageCollection.acquirePageIds(this.site, this);
|
|
1748
|
+
}
|
|
1749
|
+
getPageSources() {
|
|
1750
|
+
return PageCollection.acquirePageSources(this.site, this);
|
|
1751
|
+
}
|
|
1752
|
+
getPageRevisions() {
|
|
1753
|
+
return PageCollection.acquirePageRevisions(this.site, this);
|
|
1754
|
+
}
|
|
1755
|
+
getPageVotes() {
|
|
1756
|
+
return PageCollection.acquirePageVotes(this.site, this);
|
|
1757
|
+
}
|
|
1758
|
+
static acquirePageIds(site, pages) {
|
|
1759
|
+
return fromPromise((async () => {
|
|
1760
|
+
const targetPages = pages.filter((page) => !page.isIdAcquired());
|
|
1761
|
+
if (targetPages.length === 0) {
|
|
1762
|
+
return new PageCollection(site, pages);
|
|
1763
|
+
}
|
|
1764
|
+
const responses = await Promise.all(targetPages.map(async (page) => {
|
|
1765
|
+
const url = `${page.getUrl()}/norender/true/noredirect/true`;
|
|
1766
|
+
const response = await fetch(url, {
|
|
1767
|
+
headers: site.client.amcClient.header.getHeaders()
|
|
1768
|
+
});
|
|
1769
|
+
return { page, response };
|
|
1770
|
+
}));
|
|
1771
|
+
for (const { page, response } of responses) {
|
|
1772
|
+
const text = await response.text();
|
|
1773
|
+
const match = text.match(/WIKIREQUEST\.info\.pageId\s*=\s*(\d+);/);
|
|
1774
|
+
if (!match?.[1]) {
|
|
1775
|
+
throw new NoElementError(`Cannot find page id: ${page.fullname}`);
|
|
1776
|
+
}
|
|
1777
|
+
page.id = Number.parseInt(match[1], 10);
|
|
1778
|
+
}
|
|
1779
|
+
return new PageCollection(site, pages);
|
|
1780
|
+
})(), (error) => {
|
|
1781
|
+
if (error instanceof NoElementError)
|
|
1782
|
+
return error;
|
|
1783
|
+
return new UnexpectedError(`Failed to acquire page IDs: ${String(error)}`);
|
|
1784
|
+
});
|
|
1785
|
+
}
|
|
1786
|
+
static acquirePageSources(site, pages) {
|
|
1787
|
+
return fromPromise((async () => {
|
|
1788
|
+
const targetPages = pages.filter((page) => page.source === null && page.id !== null);
|
|
1789
|
+
if (targetPages.length === 0) {
|
|
1790
|
+
return new PageCollection(site, pages);
|
|
1791
|
+
}
|
|
1792
|
+
const result = await site.amcRequest(targetPages.map((page) => ({
|
|
1793
|
+
moduleName: "viewsource/ViewSourceModule",
|
|
1794
|
+
page_id: page.id
|
|
1795
|
+
})));
|
|
1796
|
+
if (result.isErr()) {
|
|
1797
|
+
throw result.error;
|
|
1798
|
+
}
|
|
1799
|
+
for (let i = 0;i < targetPages.length; i++) {
|
|
1800
|
+
const page = targetPages[i];
|
|
1801
|
+
const response = result.value[i];
|
|
1802
|
+
if (!page || !response)
|
|
1803
|
+
continue;
|
|
1804
|
+
const body = String(response.body ?? "").replace(/ /g, " ");
|
|
1805
|
+
const $ = cheerio6.load(body);
|
|
1806
|
+
const sourceElement = $("div.page-source");
|
|
1807
|
+
if (sourceElement.length === 0) {
|
|
1808
|
+
throw new NoElementError(`Cannot find source element for page: ${page.fullname}`);
|
|
1809
|
+
}
|
|
1810
|
+
const wikiText = sourceElement.text().trim().replace(/^\t/, "");
|
|
1811
|
+
page.source = new PageSource({ page, wikiText });
|
|
1812
|
+
}
|
|
1813
|
+
return new PageCollection(site, pages);
|
|
1814
|
+
})(), (error) => {
|
|
1815
|
+
if (error instanceof NoElementError)
|
|
1816
|
+
return error;
|
|
1817
|
+
return new UnexpectedError(`Failed to acquire page sources: ${String(error)}`);
|
|
1818
|
+
});
|
|
1819
|
+
}
|
|
1820
|
+
static acquirePageRevisions(site, pages) {
|
|
1821
|
+
return fromPromise((async () => {
|
|
1822
|
+
const targetPages = pages.filter((page) => page.revisions === null && page.id !== null);
|
|
1823
|
+
if (targetPages.length === 0) {
|
|
1824
|
+
return new PageCollection(site, pages);
|
|
1825
|
+
}
|
|
1826
|
+
const result = await site.amcRequest(targetPages.map((page) => ({
|
|
1827
|
+
moduleName: "history/PageRevisionListModule",
|
|
1828
|
+
page_id: page.id,
|
|
1829
|
+
options: { all: true },
|
|
1830
|
+
perpage: 1e8
|
|
1831
|
+
})));
|
|
1832
|
+
if (result.isErr()) {
|
|
1833
|
+
throw result.error;
|
|
1834
|
+
}
|
|
1835
|
+
const { PageRevision: PageRevision2 } = await import("./shared/index-f2eh3ykk.js");
|
|
1836
|
+
for (let i = 0;i < targetPages.length; i++) {
|
|
1837
|
+
const page = targetPages[i];
|
|
1838
|
+
const response = result.value[i];
|
|
1839
|
+
if (!page || !response)
|
|
1840
|
+
continue;
|
|
1841
|
+
const body = String(response.body ?? "");
|
|
1842
|
+
const $ = cheerio6.load(body);
|
|
1843
|
+
const revisions = [];
|
|
1844
|
+
$("table.page-history > tr[id^=revision-row-]").each((_j, revElement) => {
|
|
1845
|
+
const $rev = $(revElement);
|
|
1846
|
+
const revIdAttr = $rev.attr("id");
|
|
1847
|
+
if (!revIdAttr)
|
|
1848
|
+
return;
|
|
1849
|
+
const revId = Number.parseInt(revIdAttr.replace("revision-row-", ""), 10);
|
|
1850
|
+
if (Number.isNaN(revId))
|
|
1851
|
+
return;
|
|
1852
|
+
const $tds = $rev.find("td");
|
|
1853
|
+
if ($tds.length < 7)
|
|
1854
|
+
return;
|
|
1855
|
+
const revNoText = $tds.eq(0).text().trim().replace(/\.$/, "");
|
|
1856
|
+
const revNo = Number.parseInt(revNoText, 10);
|
|
1857
|
+
if (Number.isNaN(revNo))
|
|
1858
|
+
return;
|
|
1859
|
+
const $createdByElem = $tds.eq(4).find("span.printuser");
|
|
1860
|
+
if ($createdByElem.length === 0)
|
|
1861
|
+
return;
|
|
1862
|
+
const createdBy = parseUser(site.client, $createdByElem);
|
|
1863
|
+
const $createdAtElem = $tds.eq(5).find("span.odate");
|
|
1864
|
+
if ($createdAtElem.length === 0)
|
|
1865
|
+
return;
|
|
1866
|
+
const createdAt = parseOdate($createdAtElem) ?? new Date;
|
|
1867
|
+
const comment = $tds.eq(6).text().trim();
|
|
1868
|
+
revisions.push(new PageRevision2({
|
|
1869
|
+
page,
|
|
1870
|
+
id: revId,
|
|
1871
|
+
revNo,
|
|
1872
|
+
createdBy,
|
|
1873
|
+
createdAt,
|
|
1874
|
+
comment
|
|
1875
|
+
}));
|
|
1876
|
+
});
|
|
1877
|
+
page.revisions = new PageRevisionCollection(page, revisions);
|
|
1878
|
+
}
|
|
1879
|
+
return new PageCollection(site, pages);
|
|
1880
|
+
})(), (error) => new UnexpectedError(`Failed to acquire page revisions: ${String(error)}`));
|
|
1881
|
+
}
|
|
1882
|
+
static acquirePageVotes(site, pages) {
|
|
1883
|
+
return fromPromise((async () => {
|
|
1884
|
+
const targetPages = pages.filter((page) => page.votes === null && page.id !== null);
|
|
1885
|
+
if (targetPages.length === 0) {
|
|
1886
|
+
return new PageCollection(site, pages);
|
|
1887
|
+
}
|
|
1888
|
+
const result = await site.amcRequest(targetPages.map((page) => ({
|
|
1889
|
+
moduleName: "pagerate/WhoRatedPageModule",
|
|
1890
|
+
pageId: page.id
|
|
1891
|
+
})));
|
|
1892
|
+
if (result.isErr()) {
|
|
1893
|
+
throw result.error;
|
|
1894
|
+
}
|
|
1895
|
+
for (let i = 0;i < targetPages.length; i++) {
|
|
1896
|
+
const page = targetPages[i];
|
|
1897
|
+
const response = result.value[i];
|
|
1898
|
+
if (!page || !response)
|
|
1899
|
+
continue;
|
|
1900
|
+
const body = String(response.body ?? "");
|
|
1901
|
+
const $ = cheerio6.load(body);
|
|
1902
|
+
const $userElems = $("span.printuser");
|
|
1903
|
+
const $valueElems = $("span[style^='color']");
|
|
1904
|
+
if ($userElems.length !== $valueElems.length) {
|
|
1905
|
+
throw new UnexpectedError("User and value count mismatch in votes");
|
|
1906
|
+
}
|
|
1907
|
+
const votes = [];
|
|
1908
|
+
$userElems.each((j, userElem) => {
|
|
1909
|
+
const $user = $(userElem);
|
|
1910
|
+
const $value = $valueElems.eq(j);
|
|
1911
|
+
const user = parseUser(site.client, $user);
|
|
1912
|
+
const valueText = $value.text().trim();
|
|
1913
|
+
let value;
|
|
1914
|
+
if (valueText === "+") {
|
|
1915
|
+
value = 1;
|
|
1916
|
+
} else if (valueText === "-") {
|
|
1917
|
+
value = -1;
|
|
1918
|
+
} else {
|
|
1919
|
+
value = Number.parseInt(valueText, 10) || 0;
|
|
1920
|
+
}
|
|
1921
|
+
votes.push(new PageVote({ page, user, value }));
|
|
1922
|
+
});
|
|
1923
|
+
page.votes = new PageVoteCollection(page, votes);
|
|
1924
|
+
}
|
|
1925
|
+
return new PageCollection(site, pages);
|
|
1926
|
+
})(), (error) => new UnexpectedError(`Failed to acquire page votes: ${String(error)}`));
|
|
1927
|
+
}
|
|
1928
|
+
static parse(site, htmlBody, _parseUser) {
|
|
1929
|
+
const pages = [];
|
|
1930
|
+
htmlBody("div.page").each((_i, pageElement) => {
|
|
1931
|
+
const $page = htmlBody(pageElement);
|
|
1932
|
+
const pageParams = {};
|
|
1933
|
+
const is5StarRating = $page.find("span.rating span.page-rate-list-pages-start").length > 0;
|
|
1934
|
+
$page.find("span.set").each((_j, setElement) => {
|
|
1935
|
+
const $set = htmlBody(setElement);
|
|
1936
|
+
const keyElement = $set.find("span.name");
|
|
1937
|
+
if (keyElement.length === 0)
|
|
1938
|
+
return;
|
|
1939
|
+
let key = keyElement.text().trim();
|
|
1940
|
+
const valueElement = $set.find("span.value");
|
|
1941
|
+
let value = null;
|
|
1942
|
+
if (valueElement.length === 0) {
|
|
1943
|
+
value = null;
|
|
1944
|
+
} else if (["created_at", "updated_at", "commented_at"].includes(key)) {
|
|
1945
|
+
const odateElement = valueElement.find("span.odate");
|
|
1946
|
+
if (odateElement.length > 0) {
|
|
1947
|
+
const timestamp = odateElement.attr("class")?.match(/time_(\d+)/)?.[1];
|
|
1948
|
+
value = timestamp ? new Date(Number.parseInt(timestamp, 10) * 1000) : null;
|
|
1949
|
+
}
|
|
1950
|
+
} else if (["created_by_linked", "updated_by_linked", "commented_by_linked"].includes(key)) {
|
|
1951
|
+
const printuserElement = valueElement.find("span.printuser");
|
|
1952
|
+
if (printuserElement.length > 0) {
|
|
1953
|
+
value = _parseUser(printuserElement);
|
|
1954
|
+
}
|
|
1955
|
+
} else if (["tags", "_tags"].includes(key)) {
|
|
1956
|
+
value = valueElement.text().split(/\s+/).filter(Boolean);
|
|
1957
|
+
} else if (["rating_votes", "comments", "size", "revisions"].includes(key)) {
|
|
1958
|
+
value = Number.parseInt(valueElement.text().trim(), 10) || 0;
|
|
1959
|
+
} else if (key === "rating") {
|
|
1960
|
+
const ratingText = valueElement.text().trim();
|
|
1961
|
+
value = is5StarRating ? Number.parseFloat(ratingText) || 0 : Number.parseInt(ratingText, 10) || 0;
|
|
1962
|
+
} else if (key === "rating_percent") {
|
|
1963
|
+
if (is5StarRating) {
|
|
1964
|
+
value = (Number.parseFloat(valueElement.text().trim()) || 0) / 100;
|
|
1965
|
+
} else {
|
|
1966
|
+
value = null;
|
|
1967
|
+
}
|
|
1968
|
+
} else {
|
|
1969
|
+
value = valueElement.text().trim();
|
|
1970
|
+
}
|
|
1971
|
+
if (key.includes("_linked")) {
|
|
1972
|
+
key = key.replace("_linked", "");
|
|
1973
|
+
} else if (["comments", "children", "revisions"].includes(key)) {
|
|
1974
|
+
key = `${key}_count`;
|
|
1975
|
+
} else if (key === "rating_votes") {
|
|
1976
|
+
key = "votes_count";
|
|
1977
|
+
}
|
|
1978
|
+
pageParams[key] = value;
|
|
1979
|
+
});
|
|
1980
|
+
const tags = Array.isArray(pageParams.tags) ? pageParams.tags : [];
|
|
1981
|
+
const hiddenTags = Array.isArray(pageParams._tags) ? pageParams._tags : [];
|
|
1982
|
+
pageParams.tags = [...tags, ...hiddenTags];
|
|
1983
|
+
const parsed = pageParamsSchema.parse(pageParams);
|
|
1984
|
+
pages.push(new Page({
|
|
1985
|
+
site,
|
|
1986
|
+
fullname: parsed.fullname,
|
|
1987
|
+
name: parsed.name,
|
|
1988
|
+
category: parsed.category,
|
|
1989
|
+
title: parsed.title,
|
|
1990
|
+
childrenCount: parsed.children_count,
|
|
1991
|
+
commentsCount: parsed.comments_count,
|
|
1992
|
+
size: parsed.size,
|
|
1993
|
+
rating: parsed.rating,
|
|
1994
|
+
votesCount: parsed.votes_count,
|
|
1995
|
+
ratingPercent: parsed.rating_percent,
|
|
1996
|
+
revisionsCount: parsed.revisions_count,
|
|
1997
|
+
parentFullname: parsed.parent_fullname,
|
|
1998
|
+
tags: parsed.tags,
|
|
1999
|
+
createdBy: parsed.created_by,
|
|
2000
|
+
createdAt: parsed.created_at ?? new Date,
|
|
2001
|
+
updatedBy: parsed.updated_by,
|
|
2002
|
+
updatedAt: parsed.updated_at ?? new Date,
|
|
2003
|
+
commentedBy: parsed.commented_by,
|
|
2004
|
+
commentedAt: parsed.commented_at
|
|
2005
|
+
}));
|
|
2006
|
+
});
|
|
2007
|
+
return new PageCollection(site, pages);
|
|
2008
|
+
}
|
|
2009
|
+
static searchPages(site, parseUser2, query = null) {
|
|
2010
|
+
return fromPromise((async () => {
|
|
2011
|
+
const q = query ?? new SearchPagesQuery;
|
|
2012
|
+
const queryDict = q.asDict();
|
|
2013
|
+
const moduleBody = `[[div class="page"]]
|
|
2014
|
+
${DEFAULT_MODULE_BODY.map((key) => `[[span class="set ${key}"]][[span class="name"]] ${key} [[/span]][[span class="value"]] %%${key}%% [[/span]][[/span]]`).join("")}
|
|
2015
|
+
[[/div]]`;
|
|
2016
|
+
const requestBody = {
|
|
2017
|
+
...queryDict,
|
|
2018
|
+
moduleName: "list/ListPagesModule",
|
|
2019
|
+
module_body: moduleBody
|
|
2020
|
+
};
|
|
2021
|
+
const result = await site.amcRequest([requestBody]);
|
|
2022
|
+
if (result.isErr()) {
|
|
2023
|
+
if (result.error.message.includes("not_ok")) {
|
|
2024
|
+
throw new ForbiddenError("Failed to get pages, target site may be private");
|
|
2025
|
+
}
|
|
2026
|
+
throw result.error;
|
|
2027
|
+
}
|
|
2028
|
+
const firstResponse = result.value[0];
|
|
2029
|
+
const body = String(firstResponse?.body ?? "");
|
|
2030
|
+
const $first = cheerio6.load(body);
|
|
2031
|
+
let total = 1;
|
|
2032
|
+
const htmlBodies = [$first];
|
|
2033
|
+
const pagerElement = $first("div.pager");
|
|
2034
|
+
if (pagerElement.length > 0) {
|
|
2035
|
+
const lastPagerElements = $first("div.pager span.target");
|
|
2036
|
+
if (lastPagerElements.length >= 2) {
|
|
2037
|
+
const secondLastPager = $first(lastPagerElements[lastPagerElements.length - 2]);
|
|
2038
|
+
const lastPagerLink = secondLastPager.find("a");
|
|
2039
|
+
if (lastPagerLink.length > 0) {
|
|
2040
|
+
total = Number.parseInt(lastPagerLink.text().trim(), 10) || 1;
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
if (total > 1) {
|
|
2045
|
+
const additionalBodies = [];
|
|
2046
|
+
for (let i = 1;i < total; i++) {
|
|
2047
|
+
additionalBodies.push({
|
|
2048
|
+
...queryDict,
|
|
2049
|
+
moduleName: "list/ListPagesModule",
|
|
2050
|
+
module_body: moduleBody,
|
|
2051
|
+
offset: i * (q.perPage ?? DEFAULT_PER_PAGE)
|
|
2052
|
+
});
|
|
2053
|
+
}
|
|
2054
|
+
const additionalResults = await site.amcRequest(additionalBodies);
|
|
2055
|
+
if (additionalResults.isErr()) {
|
|
2056
|
+
throw additionalResults.error;
|
|
2057
|
+
}
|
|
2058
|
+
for (const response of additionalResults.value) {
|
|
2059
|
+
const respBody = String(response?.body ?? "");
|
|
2060
|
+
htmlBodies.push(cheerio6.load(respBody));
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
const pages = [];
|
|
2064
|
+
for (const $html of htmlBodies) {
|
|
2065
|
+
const parsed = PageCollection.parse(site, $html, parseUser2);
|
|
2066
|
+
pages.push(...parsed);
|
|
2067
|
+
}
|
|
2068
|
+
return new PageCollection(site, pages);
|
|
2069
|
+
})(), (error) => {
|
|
2070
|
+
if (error instanceof ForbiddenError || error instanceof NotFoundException) {
|
|
2071
|
+
return error;
|
|
2072
|
+
}
|
|
2073
|
+
return new UnexpectedError(`Failed to search pages: ${String(error)}`);
|
|
2074
|
+
});
|
|
2075
|
+
}
|
|
2076
|
+
static createOrEdit(site, fullname, options = {}) {
|
|
2077
|
+
const loginResult = site.client.requireLogin();
|
|
2078
|
+
if (loginResult.isErr()) {
|
|
2079
|
+
return fromPromise(Promise.reject(loginResult.error), () => new LoginRequiredError("Login required to create/edit page"));
|
|
2080
|
+
}
|
|
2081
|
+
return fromPromise((async () => {
|
|
2082
|
+
const {
|
|
2083
|
+
pageId = null,
|
|
2084
|
+
title = "",
|
|
2085
|
+
source = "",
|
|
2086
|
+
comment = "",
|
|
2087
|
+
forceEdit = false,
|
|
2088
|
+
raiseOnExists = false
|
|
2089
|
+
} = options;
|
|
2090
|
+
const lockRequestBody = {
|
|
2091
|
+
mode: "page",
|
|
2092
|
+
wiki_page: fullname,
|
|
2093
|
+
moduleName: "edit/PageEditModule"
|
|
2094
|
+
};
|
|
2095
|
+
if (forceEdit) {
|
|
2096
|
+
lockRequestBody.force_lock = "yes";
|
|
2097
|
+
}
|
|
2098
|
+
const lockResult = await site.amcRequest([lockRequestBody]);
|
|
2099
|
+
if (lockResult.isErr()) {
|
|
2100
|
+
throw lockResult.error;
|
|
2101
|
+
}
|
|
2102
|
+
const lockResponse = lockResult.value[0];
|
|
2103
|
+
if (lockResponse?.locked || lockResponse?.other_locks) {
|
|
2104
|
+
throw new UnexpectedError(`Page ${fullname} is locked or other locks exist`);
|
|
2105
|
+
}
|
|
2106
|
+
const isExist = "page_revision_id" in (lockResponse ?? {});
|
|
2107
|
+
if (raiseOnExists && isExist) {
|
|
2108
|
+
throw new TargetExistsError(`Page ${fullname} already exists`);
|
|
2109
|
+
}
|
|
2110
|
+
if (isExist && pageId === null) {
|
|
2111
|
+
throw new UnexpectedError("page_id must be specified when editing existing page");
|
|
2112
|
+
}
|
|
2113
|
+
const lockId = String(lockResponse?.lock_id ?? "");
|
|
2114
|
+
const lockSecret = String(lockResponse?.lock_secret ?? "");
|
|
2115
|
+
const pageRevisionId = String(lockResponse?.page_revision_id ?? "");
|
|
2116
|
+
const editRequestBody = {
|
|
2117
|
+
action: "WikiPageAction",
|
|
2118
|
+
event: "savePage",
|
|
2119
|
+
moduleName: "Empty",
|
|
2120
|
+
mode: "page",
|
|
2121
|
+
lock_id: lockId,
|
|
2122
|
+
lock_secret: lockSecret,
|
|
2123
|
+
revision_id: pageRevisionId,
|
|
2124
|
+
wiki_page: fullname,
|
|
2125
|
+
page_id: pageId ?? "",
|
|
2126
|
+
title,
|
|
2127
|
+
source,
|
|
2128
|
+
comments: comment
|
|
2129
|
+
};
|
|
2130
|
+
const editResult = await site.amcRequest([editRequestBody]);
|
|
2131
|
+
if (editResult.isErr()) {
|
|
2132
|
+
throw editResult.error;
|
|
2133
|
+
}
|
|
2134
|
+
})(), (error) => {
|
|
2135
|
+
if (error instanceof TargetExistsError || error instanceof LoginRequiredError) {
|
|
2136
|
+
return error;
|
|
2137
|
+
}
|
|
2138
|
+
return new UnexpectedError(`Failed to create/edit page: ${String(error)}`);
|
|
2139
|
+
});
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
// src/module/page/site-change.ts
|
|
2143
|
+
import * as cheerio7 from "cheerio";
|
|
2144
|
+
class SiteChange {
|
|
2145
|
+
site;
|
|
2146
|
+
pageFullname;
|
|
2147
|
+
pageTitle;
|
|
2148
|
+
revisionNo;
|
|
2149
|
+
changedBy;
|
|
2150
|
+
changedAt;
|
|
2151
|
+
flags;
|
|
2152
|
+
comment;
|
|
2153
|
+
constructor(data) {
|
|
2154
|
+
this.site = data.site;
|
|
2155
|
+
this.pageFullname = data.pageFullname;
|
|
2156
|
+
this.pageTitle = data.pageTitle;
|
|
2157
|
+
this.revisionNo = data.revisionNo;
|
|
2158
|
+
this.changedBy = data.changedBy;
|
|
2159
|
+
this.changedAt = data.changedAt;
|
|
2160
|
+
this.flags = data.flags;
|
|
2161
|
+
this.comment = data.comment;
|
|
2162
|
+
}
|
|
2163
|
+
getPageUrl() {
|
|
2164
|
+
return `${this.site.getBaseUrl()}/${this.pageFullname}`;
|
|
2165
|
+
}
|
|
2166
|
+
toString() {
|
|
2167
|
+
return `SiteChange(page=${this.pageFullname}, rev=${this.revisionNo}, by=${this.changedBy})`;
|
|
2168
|
+
}
|
|
2169
|
+
}
|
|
2170
|
+
|
|
2171
|
+
class SiteChangeCollection extends Array {
|
|
2172
|
+
site;
|
|
2173
|
+
constructor(site, changes) {
|
|
2174
|
+
super();
|
|
2175
|
+
this.site = site;
|
|
2176
|
+
if (changes) {
|
|
2177
|
+
this.push(...changes);
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
static acquire(site, options) {
|
|
2181
|
+
const perPage = options?.perPage ?? 20;
|
|
2182
|
+
const page = options?.page ?? 1;
|
|
2183
|
+
const limit = options?.limit;
|
|
2184
|
+
return fromPromise((async () => {
|
|
2185
|
+
const result = await site.amcRequest([
|
|
2186
|
+
{
|
|
2187
|
+
moduleName: "changes/SiteChangesListModule",
|
|
2188
|
+
perpage: perPage,
|
|
2189
|
+
page
|
|
2190
|
+
}
|
|
2191
|
+
]);
|
|
2192
|
+
if (result.isErr()) {
|
|
2193
|
+
throw result.error;
|
|
2194
|
+
}
|
|
2195
|
+
const response = result.value[0];
|
|
2196
|
+
if (!response) {
|
|
2197
|
+
throw new NoElementError("Empty response");
|
|
2198
|
+
}
|
|
2199
|
+
const html = String(response.body ?? "");
|
|
2200
|
+
const $ = cheerio7.load(html);
|
|
2201
|
+
const changes = [];
|
|
2202
|
+
$("table.wiki-content-table tr").each((_i, elem) => {
|
|
2203
|
+
const $row = $(elem);
|
|
2204
|
+
const $cells = $row.find("td");
|
|
2205
|
+
if ($cells.length < 4)
|
|
2206
|
+
return;
|
|
2207
|
+
const pageLink = $($cells[0]).find("a");
|
|
2208
|
+
const href = pageLink.attr("href") ?? "";
|
|
2209
|
+
const pageFullname = href.replace(/^\//, "").split("/")[0] ?? "";
|
|
2210
|
+
const pageTitle = pageLink.text().trim();
|
|
2211
|
+
const revText = $($cells[1]).text().trim();
|
|
2212
|
+
const revMatch = revText.match(/(\d+)/);
|
|
2213
|
+
const revisionNo = revMatch?.[1] ? Number.parseInt(revMatch[1], 10) : 0;
|
|
2214
|
+
const flagsCell = $($cells[2]);
|
|
2215
|
+
const flags = [];
|
|
2216
|
+
flagsCell.find("span").each((_j, flagElem) => {
|
|
2217
|
+
const flagClass = $(flagElem).attr("class") ?? "";
|
|
2218
|
+
if (flagClass.includes("spantip")) {
|
|
2219
|
+
const title = $(flagElem).attr("title") ?? "";
|
|
2220
|
+
if (title)
|
|
2221
|
+
flags.push(title);
|
|
2222
|
+
}
|
|
2223
|
+
});
|
|
2224
|
+
const infoCell = $($cells[3]);
|
|
2225
|
+
const userElem = infoCell.find("span.printuser");
|
|
2226
|
+
const changedBy = userElem.length > 0 ? parseUser(site.client, userElem) : null;
|
|
2227
|
+
const odateElem = infoCell.find("span.odate");
|
|
2228
|
+
const changedAt = odateElem.length > 0 ? parseOdate(odateElem) : null;
|
|
2229
|
+
const commentElem = infoCell.find("span.comments");
|
|
2230
|
+
const comment = commentElem.text().trim().replace(/^[""]|[""]$/g, "");
|
|
2231
|
+
changes.push(new SiteChange({
|
|
2232
|
+
site,
|
|
2233
|
+
pageFullname,
|
|
2234
|
+
pageTitle,
|
|
2235
|
+
revisionNo,
|
|
2236
|
+
changedBy,
|
|
2237
|
+
changedAt,
|
|
2238
|
+
flags,
|
|
2239
|
+
comment
|
|
2240
|
+
}));
|
|
2241
|
+
});
|
|
2242
|
+
const limitedChanges = limit !== undefined ? changes.slice(0, limit) : changes;
|
|
2243
|
+
return new SiteChangeCollection(site, limitedChanges);
|
|
2244
|
+
})(), (error) => {
|
|
2245
|
+
if (error instanceof NoElementError) {
|
|
2246
|
+
return error;
|
|
2247
|
+
}
|
|
2248
|
+
return new UnexpectedError(`Failed to acquire site changes: ${String(error)}`);
|
|
2249
|
+
});
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
// src/module/site/accessors/page-accessor.ts
|
|
2253
|
+
class PageAccessor {
|
|
2254
|
+
site;
|
|
2255
|
+
constructor(site) {
|
|
2256
|
+
this.site = site;
|
|
2257
|
+
}
|
|
2258
|
+
get(unixName) {
|
|
2259
|
+
return fromPromise((async () => {
|
|
2260
|
+
const query = new SearchPagesQuery({ fullname: unixName });
|
|
2261
|
+
const userParser = parseUser.bind(null, this.site.client);
|
|
2262
|
+
const result = await PageCollection.searchPages(this.site, userParser, query);
|
|
2263
|
+
if (result.isErr()) {
|
|
2264
|
+
throw result.error;
|
|
2265
|
+
}
|
|
2266
|
+
return result.value.length > 0 ? result.value[0] ?? null : null;
|
|
2267
|
+
})(), (error) => {
|
|
2268
|
+
if (error instanceof NoElementError)
|
|
2269
|
+
return error;
|
|
2270
|
+
return new UnexpectedError(`Failed to get page: ${String(error)}`);
|
|
2271
|
+
});
|
|
2272
|
+
}
|
|
2273
|
+
create(fullname, options = {}) {
|
|
2274
|
+
return PageCollection.createOrEdit(this.site, fullname, {
|
|
2275
|
+
title: options.title,
|
|
2276
|
+
source: options.source,
|
|
2277
|
+
comment: options.comment,
|
|
2278
|
+
forceEdit: options.forceEdit
|
|
2279
|
+
});
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2282
|
+
// src/module/site/accessors/pages-accessor.ts
|
|
2283
|
+
class PagesAccessor {
|
|
2284
|
+
site;
|
|
2285
|
+
constructor(site) {
|
|
2286
|
+
this.site = site;
|
|
2287
|
+
}
|
|
2288
|
+
search(params) {
|
|
2289
|
+
return fromPromise((async () => {
|
|
2290
|
+
const query = new SearchPagesQuery(params);
|
|
2291
|
+
const userParser = parseUser.bind(null, this.site.client);
|
|
2292
|
+
const result = await PageCollection.searchPages(this.site, userParser, query);
|
|
2293
|
+
if (result.isErr()) {
|
|
2294
|
+
throw result.error;
|
|
2295
|
+
}
|
|
2296
|
+
return result.value;
|
|
2297
|
+
})(), (error) => new UnexpectedError(`Failed to search pages: ${String(error)}`));
|
|
2298
|
+
}
|
|
2299
|
+
all() {
|
|
2300
|
+
return this.search({});
|
|
2301
|
+
}
|
|
2302
|
+
getRecentChanges(options) {
|
|
2303
|
+
return SiteChangeCollection.acquire(this.site, options);
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
// src/module/site/site.ts
|
|
2307
|
+
import * as cheerio8 from "cheerio";
|
|
2308
|
+
class Site {
|
|
2309
|
+
client;
|
|
2310
|
+
id;
|
|
2311
|
+
title;
|
|
2312
|
+
unixName;
|
|
2313
|
+
domain;
|
|
2314
|
+
sslSupported;
|
|
2315
|
+
_page = null;
|
|
2316
|
+
_pages = null;
|
|
2317
|
+
_forum = null;
|
|
2318
|
+
_member = null;
|
|
2319
|
+
constructor(client, data) {
|
|
2320
|
+
this.client = client;
|
|
2321
|
+
this.id = data.id;
|
|
2322
|
+
this.title = data.title;
|
|
2323
|
+
this.unixName = data.unixName;
|
|
2324
|
+
this.domain = data.domain;
|
|
2325
|
+
this.sslSupported = data.sslSupported;
|
|
2326
|
+
}
|
|
2327
|
+
get page() {
|
|
2328
|
+
if (!this._page) {
|
|
2329
|
+
this._page = new PageAccessor(this);
|
|
2330
|
+
}
|
|
2331
|
+
return this._page;
|
|
2332
|
+
}
|
|
2333
|
+
get pages() {
|
|
2334
|
+
if (!this._pages) {
|
|
2335
|
+
this._pages = new PagesAccessor(this);
|
|
2336
|
+
}
|
|
2337
|
+
return this._pages;
|
|
2338
|
+
}
|
|
2339
|
+
get forum() {
|
|
2340
|
+
if (!this._forum) {
|
|
2341
|
+
this._forum = new ForumAccessor(this);
|
|
2342
|
+
}
|
|
2343
|
+
return this._forum;
|
|
2344
|
+
}
|
|
2345
|
+
get member() {
|
|
2346
|
+
if (!this._member) {
|
|
2347
|
+
this._member = new MemberAccessor(this);
|
|
2348
|
+
}
|
|
2349
|
+
return this._member;
|
|
2350
|
+
}
|
|
2351
|
+
getBaseUrl() {
|
|
2352
|
+
const protocol = this.sslSupported ? "https" : "http";
|
|
2353
|
+
return `${protocol}://${this.domain}`;
|
|
2354
|
+
}
|
|
2355
|
+
amcRequest(bodies) {
|
|
2356
|
+
return this.client.amcClient.request(bodies, this.unixName, this.sslSupported);
|
|
2357
|
+
}
|
|
2358
|
+
amcRequestSingle(body) {
|
|
2359
|
+
return fromPromise((async () => {
|
|
2360
|
+
const result = await this.amcRequest([body]);
|
|
2361
|
+
if (result.isErr()) {
|
|
2362
|
+
throw result.error;
|
|
2363
|
+
}
|
|
2364
|
+
const response = result.value[0];
|
|
2365
|
+
if (!response) {
|
|
2366
|
+
throw new UnexpectedError("AMC request returned empty response");
|
|
2367
|
+
}
|
|
2368
|
+
return response;
|
|
2369
|
+
})(), (error) => {
|
|
2370
|
+
if (error instanceof UnexpectedError) {
|
|
2371
|
+
return error;
|
|
2372
|
+
}
|
|
2373
|
+
return new UnexpectedError(`AMC request failed: ${String(error)}`);
|
|
2374
|
+
});
|
|
2375
|
+
}
|
|
2376
|
+
static fromUnixName(client, unixName) {
|
|
2377
|
+
return fromPromise((async () => {
|
|
2378
|
+
const url = `https://${unixName}.wikidot.com`;
|
|
2379
|
+
const response = await fetch(url, {
|
|
2380
|
+
headers: client.amcClient.header.getHeaders()
|
|
2381
|
+
});
|
|
2382
|
+
if (!response.ok) {
|
|
2383
|
+
if (response.status === 404) {
|
|
2384
|
+
throw new NotFoundException(`Site not found: ${unixName}`);
|
|
2385
|
+
}
|
|
2386
|
+
throw new UnexpectedError(`Failed to fetch site: ${response.status}`);
|
|
2387
|
+
}
|
|
2388
|
+
const html = await response.text();
|
|
2389
|
+
const $ = cheerio8.load(html);
|
|
2390
|
+
const scripts = $("script").toArray();
|
|
2391
|
+
let siteId = null;
|
|
2392
|
+
let siteUnixName = null;
|
|
2393
|
+
let domain = null;
|
|
2394
|
+
let title = null;
|
|
2395
|
+
for (const script of scripts) {
|
|
2396
|
+
const content = $(script).html();
|
|
2397
|
+
if (!content || !content.includes("WIKIREQUEST")) {
|
|
2398
|
+
continue;
|
|
2399
|
+
}
|
|
2400
|
+
const siteIdMatch = content.match(/WIKIREQUEST\.info\.siteId\s*=\s*(\d+)/);
|
|
2401
|
+
if (siteIdMatch?.[1]) {
|
|
2402
|
+
siteId = Number.parseInt(siteIdMatch[1], 10);
|
|
2403
|
+
}
|
|
2404
|
+
const siteUnixNameMatch = content.match(/WIKIREQUEST\.info\.siteUnixName\s*=\s*["']([^"']+)["']/);
|
|
2405
|
+
if (siteUnixNameMatch?.[1]) {
|
|
2406
|
+
siteUnixName = siteUnixNameMatch[1];
|
|
2407
|
+
}
|
|
2408
|
+
const domainMatch = content.match(/WIKIREQUEST\.info\.domain\s*=\s*["']([^"']+)["']/);
|
|
2409
|
+
if (domainMatch?.[1]) {
|
|
2410
|
+
domain = domainMatch[1];
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
title = $("title").text().trim() || null;
|
|
2414
|
+
if (title?.endsWith(" - Wikidot")) {
|
|
2415
|
+
title = title.slice(0, -10).trim();
|
|
2416
|
+
}
|
|
2417
|
+
if (siteId === null) {
|
|
2418
|
+
throw new NoElementError("Site ID not found in WIKIREQUEST");
|
|
2419
|
+
}
|
|
2420
|
+
if (siteUnixName === null) {
|
|
2421
|
+
siteUnixName = unixName;
|
|
2422
|
+
}
|
|
2423
|
+
if (domain === null) {
|
|
2424
|
+
domain = `${unixName}.wikidot.com`;
|
|
2425
|
+
}
|
|
2426
|
+
if (title === null) {
|
|
2427
|
+
title = unixName;
|
|
2428
|
+
}
|
|
2429
|
+
const sslSupported = true;
|
|
2430
|
+
return new Site(client, {
|
|
2431
|
+
id: siteId,
|
|
2432
|
+
title,
|
|
2433
|
+
unixName: siteUnixName,
|
|
2434
|
+
domain,
|
|
2435
|
+
sslSupported
|
|
2436
|
+
});
|
|
2437
|
+
})(), (error) => {
|
|
2438
|
+
if (error instanceof NotFoundException || error instanceof NoElementError) {
|
|
2439
|
+
return error;
|
|
2440
|
+
}
|
|
2441
|
+
return new UnexpectedError(`Failed to get site: ${String(error)}`);
|
|
2442
|
+
});
|
|
2443
|
+
}
|
|
2444
|
+
toString() {
|
|
2445
|
+
return `Site(id=${this.id}, unixName=${this.unixName}, title=${this.title})`;
|
|
2446
|
+
}
|
|
2447
|
+
}
|
|
2448
|
+
// src/module/client/accessors/site-accessor.ts
|
|
2449
|
+
class SiteAccessor {
|
|
2450
|
+
client;
|
|
2451
|
+
constructor(client) {
|
|
2452
|
+
this.client = client;
|
|
2453
|
+
}
|
|
2454
|
+
get(unixName) {
|
|
2455
|
+
return Site.fromUnixName(this.client, unixName);
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2458
|
+
// src/module/client/accessors/user-accessor.ts
|
|
2459
|
+
class UserAccessor {
|
|
2460
|
+
client;
|
|
2461
|
+
constructor(client) {
|
|
2462
|
+
this.client = client;
|
|
2463
|
+
}
|
|
2464
|
+
get(name, options = {}) {
|
|
2465
|
+
const { raiseWhenNotFound = false } = options;
|
|
2466
|
+
return User.fromName(this.client, name).andThen((user) => {
|
|
2467
|
+
if (user === null && raiseWhenNotFound) {
|
|
2468
|
+
return wdErrAsync(new NotFoundException(`User not found: ${name}`));
|
|
2469
|
+
}
|
|
2470
|
+
return wdOkAsync(user);
|
|
2471
|
+
});
|
|
2472
|
+
}
|
|
2473
|
+
getMany(names, options = {}) {
|
|
2474
|
+
const { raiseWhenNotFound = false } = options;
|
|
2475
|
+
return User.fromNames(this.client, names).andThen((collection) => {
|
|
2476
|
+
if (raiseWhenNotFound) {
|
|
2477
|
+
const notFoundNames = [];
|
|
2478
|
+
for (let i = 0;i < names.length; i++) {
|
|
2479
|
+
const name = names[i];
|
|
2480
|
+
if (collection[i] === null && name !== undefined) {
|
|
2481
|
+
notFoundNames.push(name);
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
if (notFoundNames.length > 0) {
|
|
2485
|
+
return wdErrAsync(new NotFoundException(`Users not found: ${notFoundNames.join(", ")}`));
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
return wdOkAsync(collection);
|
|
2489
|
+
});
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
// src/module/client/client.ts
|
|
2493
|
+
class Client {
|
|
2494
|
+
amcClient;
|
|
2495
|
+
domain;
|
|
2496
|
+
user;
|
|
2497
|
+
site;
|
|
2498
|
+
privateMessage;
|
|
2499
|
+
_username;
|
|
2500
|
+
_me = null;
|
|
2501
|
+
constructor(amcClient, domain, username = null) {
|
|
2502
|
+
this.amcClient = amcClient;
|
|
2503
|
+
this.domain = domain;
|
|
2504
|
+
this._username = username;
|
|
2505
|
+
this.user = new UserAccessor(this);
|
|
2506
|
+
this.site = new SiteAccessor(this);
|
|
2507
|
+
this.privateMessage = new PrivateMessageAccessor(this);
|
|
2508
|
+
}
|
|
2509
|
+
get username() {
|
|
2510
|
+
return this._username;
|
|
2511
|
+
}
|
|
2512
|
+
get me() {
|
|
2513
|
+
return this._me;
|
|
2514
|
+
}
|
|
2515
|
+
static create(options = {}) {
|
|
2516
|
+
const { username, password, domain = "wikidot.com", amcConfig = {} } = options;
|
|
2517
|
+
const amcClient = new AMCClient(amcConfig, domain);
|
|
2518
|
+
if (username && password) {
|
|
2519
|
+
return fromPromise((async () => {
|
|
2520
|
+
const client = new Client(amcClient, domain, username);
|
|
2521
|
+
const loginResult = await login(client, username, password);
|
|
2522
|
+
if (loginResult.isErr()) {
|
|
2523
|
+
throw loginResult.error;
|
|
2524
|
+
}
|
|
2525
|
+
const { User: User2 } = await import("./shared/index-kka6e8cb.js");
|
|
2526
|
+
const userResult = await User2.fromName(client, username);
|
|
2527
|
+
if (userResult.isOk() && userResult.value) {
|
|
2528
|
+
client._me = userResult.value;
|
|
2529
|
+
}
|
|
2530
|
+
return client;
|
|
2531
|
+
})(), (error) => {
|
|
2532
|
+
if (error instanceof LoginRequiredError) {
|
|
2533
|
+
return error;
|
|
2534
|
+
}
|
|
2535
|
+
return new LoginRequiredError(`Failed to create client: ${String(error)}`);
|
|
2536
|
+
});
|
|
2537
|
+
}
|
|
2538
|
+
return wdOkAsync(new Client(amcClient, domain));
|
|
2539
|
+
}
|
|
2540
|
+
static createAnonymous(options = {}) {
|
|
2541
|
+
const { domain = "wikidot.com", amcConfig = {} } = options;
|
|
2542
|
+
const amcClient = new AMCClient(amcConfig, domain);
|
|
2543
|
+
return new Client(amcClient, domain);
|
|
2544
|
+
}
|
|
2545
|
+
isLoggedIn() {
|
|
2546
|
+
return this._username !== null;
|
|
2547
|
+
}
|
|
2548
|
+
requireLogin() {
|
|
2549
|
+
if (!this.isLoggedIn()) {
|
|
2550
|
+
return wdErr(new LoginRequiredError);
|
|
2551
|
+
}
|
|
2552
|
+
return wdOk(undefined);
|
|
2553
|
+
}
|
|
2554
|
+
close() {
|
|
2555
|
+
if (this.isLoggedIn()) {
|
|
2556
|
+
return logout(this).map(() => {
|
|
2557
|
+
this._username = null;
|
|
2558
|
+
return;
|
|
2559
|
+
});
|
|
2560
|
+
}
|
|
2561
|
+
return wdOkAsync(undefined);
|
|
2562
|
+
}
|
|
2563
|
+
}
|
|
2564
|
+
export {
|
|
2565
|
+
wdOkAsync,
|
|
2566
|
+
wdOk,
|
|
2567
|
+
wdErrAsync,
|
|
2568
|
+
wdErr,
|
|
2569
|
+
userLookup,
|
|
2570
|
+
setupConsoleHandler,
|
|
2571
|
+
parseUser,
|
|
2572
|
+
parseOdate,
|
|
2573
|
+
pageLookup,
|
|
2574
|
+
nullHandler,
|
|
2575
|
+
memberLookup,
|
|
2576
|
+
maskSensitiveData,
|
|
2577
|
+
logout,
|
|
2578
|
+
login,
|
|
2579
|
+
logger,
|
|
2580
|
+
isSuccessResponse,
|
|
2581
|
+
getLogger,
|
|
2582
|
+
fromPromise,
|
|
2583
|
+
consoleHandler,
|
|
2584
|
+
combineResults,
|
|
2585
|
+
amcResponseSchema,
|
|
2586
|
+
WikidotUser,
|
|
2587
|
+
WikidotStatusError,
|
|
2588
|
+
WikidotError,
|
|
2589
|
+
UserCollection,
|
|
2590
|
+
UserAccessor,
|
|
2591
|
+
User,
|
|
2592
|
+
UnexpectedError,
|
|
2593
|
+
TargetExistsError,
|
|
2594
|
+
TargetError,
|
|
2595
|
+
SiteMember,
|
|
2596
|
+
SiteChangeCollection,
|
|
2597
|
+
SiteChange,
|
|
2598
|
+
SiteApplication,
|
|
2599
|
+
SiteAccessor,
|
|
2600
|
+
Site,
|
|
2601
|
+
SessionError,
|
|
2602
|
+
SessionCreateError,
|
|
2603
|
+
SearchPagesQuery,
|
|
2604
|
+
ResponseDataError,
|
|
2605
|
+
QuickModule,
|
|
2606
|
+
PrivateMessageSentBox,
|
|
2607
|
+
PrivateMessageInbox,
|
|
2608
|
+
PrivateMessageCollection,
|
|
2609
|
+
PrivateMessageAccessor,
|
|
2610
|
+
PrivateMessage,
|
|
2611
|
+
PagesAccessor,
|
|
2612
|
+
PageVoteCollection,
|
|
2613
|
+
PageVote,
|
|
2614
|
+
PageSource,
|
|
2615
|
+
PageRevisionCollection,
|
|
2616
|
+
PageRevision,
|
|
2617
|
+
PageMetaCollection,
|
|
2618
|
+
PageMeta,
|
|
2619
|
+
PageFileCollection,
|
|
2620
|
+
PageFile,
|
|
2621
|
+
PageCollection,
|
|
2622
|
+
PageAccessor,
|
|
2623
|
+
Page,
|
|
2624
|
+
NotFoundException,
|
|
2625
|
+
NoElementError,
|
|
2626
|
+
MemberAccessor,
|
|
2627
|
+
LoginRequiredError,
|
|
2628
|
+
Logger,
|
|
2629
|
+
GuestUser,
|
|
2630
|
+
ForumThreadCollection,
|
|
2631
|
+
ForumThread,
|
|
2632
|
+
ForumPostCollection,
|
|
2633
|
+
ForumPost,
|
|
2634
|
+
ForumCategoryCollection,
|
|
2635
|
+
ForumCategory,
|
|
2636
|
+
ForumAccessor,
|
|
2637
|
+
ForbiddenError,
|
|
2638
|
+
DeletedUser,
|
|
2639
|
+
DEFAULT_PER_PAGE,
|
|
2640
|
+
DEFAULT_MODULE_BODY,
|
|
2641
|
+
DEFAULT_AMC_CONFIG,
|
|
2642
|
+
Client,
|
|
2643
|
+
AnonymousUser,
|
|
2644
|
+
AMCHttpError,
|
|
2645
|
+
AMCHeader,
|
|
2646
|
+
AMCError,
|
|
2647
|
+
AMCClient
|
|
2648
|
+
};
|
|
2649
|
+
|
|
2650
|
+
//# debugId=1A0AF3AA4D5CAB4D64756E2164756E21
|
|
2651
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL2Nvbm5lY3Rvci9hbWMtY2xpZW50LnRzIiwgInNyYy9jb25uZWN0b3IvYW1jLWNvbmZpZy50cyIsICJzcmMvY29ubmVjdG9yL2FtYy1oZWFkZXIudHMiLCAic3JjL2Nvbm5lY3Rvci9hbWMtdHlwZXMudHMiLCAic3JjL2Nvbm5lY3Rvci9hdXRoLnRzIiwgInNyYy9tb2R1bGUvcHJpdmF0ZS1tZXNzYWdlL3ByaXZhdGUtbWVzc2FnZS50cyIsICJzcmMvbW9kdWxlL2NsaWVudC9hY2Nlc3NvcnMvcG0tYWNjZXNzb3IudHMiLCAic3JjL21vZHVsZS9zaXRlL2FjY2Vzc29ycy9mb3J1bS1hY2Nlc3Nvci50cyIsICJzcmMvdXRpbC9xdWljay1tb2R1bGUudHMiLCAic3JjL21vZHVsZS9zaXRlL3NpdGUtYXBwbGljYXRpb24udHMiLCAic3JjL21vZHVsZS9zaXRlL3NpdGUtbWVtYmVyLnRzIiwgInNyYy9tb2R1bGUvc2l0ZS9hY2Nlc3NvcnMvbWVtYmVyLWFjY2Vzc29yLnRzIiwgInNyYy9tb2R1bGUvcGFnZS9wYWdlLnRzIiwgInNyYy9tb2R1bGUvcGFnZS9wYWdlLWZpbGUudHMiLCAic3JjL21vZHVsZS9wYWdlL3BhZ2UtbWV0YS50cyIsICJzcmMvbW9kdWxlL3BhZ2UvcGFnZS1zb3VyY2UudHMiLCAic3JjL21vZHVsZS9wYWdlL3BhZ2Utdm90ZS50cyIsICJzcmMvbW9kdWxlL3BhZ2Uvc2VhcmNoLXF1ZXJ5LnRzIiwgInNyYy9tb2R1bGUvcGFnZS9zaXRlLWNoYW5nZS50cyIsICJzcmMvbW9kdWxlL3NpdGUvYWNjZXNzb3JzL3BhZ2UtYWNjZXNzb3IudHMiLCAic3JjL21vZHVsZS9zaXRlL2FjY2Vzc29ycy9wYWdlcy1hY2Nlc3Nvci50cyIsICJzcmMvbW9kdWxlL3NpdGUvc2l0ZS50cyIsICJzcmMvbW9kdWxlL2NsaWVudC9hY2Nlc3NvcnMvc2l0ZS1hY2Nlc3Nvci50cyIsICJzcmMvbW9kdWxlL2NsaWVudC9hY2Nlc3NvcnMvdXNlci1hY2Nlc3Nvci50cyIsICJzcmMvbW9kdWxlL2NsaWVudC9jbGllbnQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiaW1wb3J0IGt5LCB7IHR5cGUgS3lJbnN0YW5jZSB9IGZyb20gJ2t5JztcbmltcG9ydCBwTGltaXQsIHsgdHlwZSBMaW1pdEZ1bmN0aW9uIH0gZnJvbSAncC1saW1pdCc7XG5pbXBvcnQge1xuICBBTUNIdHRwRXJyb3IsXG4gIEZvcmJpZGRlbkVycm9yLFxuICBOb3RGb3VuZEV4Y2VwdGlvbixcbiAgUmVzcG9uc2VEYXRhRXJyb3IsXG4gIFVuZXhwZWN0ZWRFcnJvcixcbiAgV2lraWRvdEVycm9yLFxuICBXaWtpZG90U3RhdHVzRXJyb3IsXG59IGZyb20gJy4uL2NvbW1vbi9lcnJvcnMnO1xuaW1wb3J0IHsgZnJvbVByb21pc2UsIHR5cGUgV2lraWRvdFJlc3VsdEFzeW5jLCB3ZEVyckFzeW5jLCB3ZE9rQXN5bmMgfSBmcm9tICcuLi9jb21tb24vdHlwZXMnO1xuaW1wb3J0IHtcbiAgdHlwZSBBTUNDb25maWcsXG4gIERFRkFVTFRfQU1DX0NPTkZJRyxcbiAgREVGQVVMVF9IVFRQX1NUQVRVU19DT0RFLFxuICBXSUtJRE9UX1RPS0VONyxcbn0gZnJvbSAnLi9hbWMtY29uZmlnJztcbmltcG9ydCB7IEFNQ0hlYWRlciB9IGZyb20gJy4vYW1jLWhlYWRlcic7XG5pbXBvcnQgeyB0eXBlIEFNQ1JlcXVlc3RCb2R5LCB0eXBlIEFNQ1Jlc3BvbnNlLCBhbWNSZXNwb25zZVNjaGVtYSB9IGZyb20gJy4vYW1jLXR5cGVzJztcblxuLyoqXG4gKiDmqZ/lr4bmg4XloLHjgpLjg57jgrnjgq/jgZnjgovvvIjjg63jgrDlh7rlipvnlKjvvIlcbiAqIEBwYXJhbSBib2R5IC0g44Oe44K544Kv5a++6LGh44Gu44Oq44Kv44Ko44K544OI44Oc44OH44KjXG4gKiBAcmV0dXJucyDjg57jgrnjgq/jgZXjgozjgZ/jg5zjg4fjgqNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hc2tTZW5zaXRpdmVEYXRhKGJvZHk6IEFNQ1JlcXVlc3RCb2R5KTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICBjb25zdCBtYXNrZWQgPSB7IC4uLmJvZHkgfTtcbiAgY29uc3Qgc2Vuc2l0aXZlS2V5cyA9IFsncGFzc3dvcmQnLCAnbG9naW4nLCAnV0lLSURPVF9TRVNTSU9OX0lEJywgJ3dpa2lkb3RfdG9rZW43J107XG4gIGZvciAoY29uc3Qga2V5IG9mIHNlbnNpdGl2ZUtleXMpIHtcbiAgICBpZiAoa2V5IGluIG1hc2tlZCkge1xuICAgICAgbWFza2VkW2tleV0gPSAnKioqTUFTS0VEKioqJztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG1hc2tlZDtcbn1cblxuLyoqXG4gKiDmjIfmlbDjg5Djg4Pjgq/jgqrjg5XplpPpmpTjgpLoqIjnrpfjgZnjgovvvIjjgrjjg4Pjgr/jg7zku5jjgY3vvIlcbiAqIEBwYXJhbSByZXRyeUNvdW50IC0g54++5Zyo44Gu44Oq44OI44Op44Kk5Zue5pWw77yIMeOBi+OCiemWi+Wni++8iVxuICogQHBhcmFtIGJhc2VJbnRlcnZhbCAtIOWfuuacrOmWk+malO+8iOODn+ODquenku+8iVxuICogQHBhcmFtIGJhY2tvZmZGYWN0b3IgLSDjg5Djg4Pjgq/jgqrjg5Xkv4LmlbBcbiAqIEBwYXJhbSBtYXhCYWNrb2ZmIC0g5pyA5aSn44OQ44OD44Kv44Kq44OV6ZaT6ZqU77yI44Of44Oq56eS77yJXG4gKiBAcmV0dXJucyDoqIjnrpfjgZXjgozjgZ/jg5Djg4Pjgq/jgqrjg5XplpPpmpTvvIjjg5/jg6rnp5LvvIlcbiAqL1xuZnVuY3Rpb24gY2FsY3VsYXRlQmFja29mZihcbiAgcmV0cnlDb3VudDogbnVtYmVyLFxuICBiYXNlSW50ZXJ2YWw6IG51bWJlcixcbiAgYmFja29mZkZhY3RvcjogbnVtYmVyLFxuICBtYXhCYWNrb2ZmOiBudW1iZXJcbik6IG51bWJlciB7XG4gIGNvbnN0IGJhY2tvZmYgPSBiYXNlSW50ZXJ2YWwgKiBiYWNrb2ZmRmFjdG9yICoqIChyZXRyeUNvdW50IC0gMSk7XG4gIGNvbnN0IGppdHRlciA9IE1hdGgucmFuZG9tKCkgKiBiYWNrb2ZmICogMC4xO1xuICByZXR1cm4gTWF0aC5taW4oYmFja29mZiArIGppdHRlciwgbWF4QmFja29mZik7XG59XG5cbi8qKlxuICog5oyH5a6a5pmC6ZaT5b6F5qmf44GZ44KLXG4gKiBAcGFyYW0gbXMgLSDlvoXmqZ/mmYLplpPvvIjjg5/jg6rnp5LvvIlcbiAqL1xuZnVuY3Rpb24gc2xlZXAobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcbn1cblxuLyoqXG4gKiBBTUPjg6rjgq/jgqjjgrnjg4jjgqrjg5fjgrfjg6fjg7NcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBTUNSZXF1ZXN0T3B0aW9ucyB7XG4gIC8qKiDjgrXjgqTjg4jlkI3vvIjjg4fjg5Xjgqnjg6vjg4g6IHd3d++8iSAqL1xuICBzaXRlTmFtZT86IHN0cmluZztcbiAgLyoqIFNTTOWvvuW/nO+8iOecgeeVpeaZguOBr+iHquWLleaknOWHuu+8iSAqL1xuICBzc2xTdXBwb3J0ZWQ/OiBib29sZWFuO1xuICAvKiog44Ko44Op44O844KS5L6L5aSW44Go44GX44Gm5oqV44GS44Ga44Gr57WQ5p6c44Gr5ZCr44KB44KL77yI44OH44OV44Kp44Or44OIOiBmYWxzZe+8iSAqL1xuICByZXR1cm5FeGNlcHRpb25zPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBBamF4IE1vZHVsZSBDb25uZWN0b3Ljgq/jg6njgqTjgqLjg7Pjg4hcbiAqIFdpa2lkb3QgQU1D44Ko44Oz44OJ44Od44Kk44Oz44OI44G444Gu44Oq44Kv44Ko44K544OI44KS566h55CG44GZ44KLXG4gKi9cbmV4cG9ydCBjbGFzcyBBTUNDbGllbnQge1xuICAvKioga3njgqTjg7Pjgrnjgr/jg7PjgrkgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBreTogS3lJbnN0YW5jZTtcblxuICAvKiog5Lim5YiX44Oq44Kv44Ko44K544OI5Yi26ZmQICovXG4gIHByaXZhdGUgcmVhZG9ubHkgbGltaXQ6IExpbWl0RnVuY3Rpb247XG5cbiAgLyoqIOODmOODg+ODgOODvOeuoeeQhiAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaGVhZGVyOiBBTUNIZWFkZXI7XG5cbiAgLyoqIOioreWumiAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY29uZmlnOiBBTUNDb25maWc7XG5cbiAgLyoqIOODmeODvOOCueODieODoeOCpOODsyAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZG9tYWluOiBzdHJpbmc7XG5cbiAgLyoqIFNTTOWvvuW/nOeKtuazgeOBruOCreODo+ODg+OCt+ODpSAqL1xuICBwcml2YXRlIHNzbENhY2hlOiBNYXA8c3RyaW5nLCBib29sZWFuPiA9IG5ldyBNYXAoKTtcblxuICAvKipcbiAgICogQHBhcmFtIGNvbmZpZyAtIEFNQ+ioreWumu+8iOecgeeVpeaZguOBr+ODh+ODleOCqeODq+ODiOWApO+8iVxuICAgKiBAcGFyYW0gZG9tYWluIC0g44OZ44O844K544OJ44Oh44Kk44Oz77yI44OH44OV44Kp44Or44OIOiB3aWtpZG90LmNvbe+8iVxuICAgKi9cbiAgY29uc3RydWN0b3IoY29uZmlnOiBQYXJ0aWFsPEFNQ0NvbmZpZz4gPSB7fSwgZG9tYWluID0gJ3dpa2lkb3QuY29tJykge1xuICAgIHRoaXMuY29uZmlnID0geyAuLi5ERUZBVUxUX0FNQ19DT05GSUcsIC4uLmNvbmZpZyB9O1xuICAgIHRoaXMuZG9tYWluID0gZG9tYWluO1xuICAgIHRoaXMuaGVhZGVyID0gbmV3IEFNQ0hlYWRlcigpO1xuICAgIHRoaXMubGltaXQgPSBwTGltaXQodGhpcy5jb25maWcuc2VtYXBob3JlTGltaXQpO1xuXG4gICAgdGhpcy5reSA9IGt5LmNyZWF0ZSh7XG4gICAgICB0aW1lb3V0OiB0aGlzLmNvbmZpZy50aW1lb3V0LFxuICAgICAgcmV0cnk6IDAsIC8vIOaJi+WLleOBp+ODquODiOODqeOCpOOCkuWItuW+oVxuICAgIH0pO1xuXG4gICAgLy8gd3d344Gv5bi444GrU1NM5a++5b+cXG4gICAgdGhpcy5zc2xDYWNoZS5zZXQoJ3d3dycsIHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIOOCteOCpOODiOOBruWtmOWcqOOBqFNTTOWvvuW/nOeKtuazgeOCkueiuuiqjeOBmeOCi1xuICAgKiBAcGFyYW0gc2l0ZU5hbWUgLSDjgrXjgqTjg4jlkI1cbiAgICogQHJldHVybnMgU1NM5a++5b+c54q25rOB77yIdHJ1ZTogSFRUUFPjgIFmYWxzZTogSFRUUO+8iVxuICAgKi9cbiAgY2hlY2tTaXRlU1NMKHNpdGVOYW1lOiBzdHJpbmcpOiBXaWtpZG90UmVzdWx0QXN5bmM8Ym9vbGVhbj4ge1xuICAgIC8vIOOCreODo+ODg+OCt+ODpeOBq+WtmOWcqOOBmeOCjOOBsOOBneOCjOOCkui/lOOBmVxuICAgIGNvbnN0IGNhY2hlZCA9IHRoaXMuc3NsQ2FjaGUuZ2V0KHNpdGVOYW1lKTtcbiAgICBpZiAoY2FjaGVkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB3ZE9rQXN5bmMoY2FjaGVkKTtcbiAgICB9XG5cbiAgICAvLyB3d3fjga/luLjjgatTU0zlr77lv5xcbiAgICBpZiAoc2l0ZU5hbWUgPT09ICd3d3cnKSB7XG4gICAgICByZXR1cm4gd2RPa0FzeW5jKHRydWUpO1xuICAgIH1cblxuICAgIHJldHVybiBmcm9tUHJvbWlzZShcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYGh0dHA6Ly8ke3NpdGVOYW1lfS4ke3RoaXMuZG9tYWlufWAsIHtcbiAgICAgICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgICAgIHJlZGlyZWN0OiAnbWFudWFsJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gNDA044Gu5aC05ZCI44Gv44K144Kk44OI44GM5a2Y5Zyo44GX44Gq44GEXG4gICAgICAgIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDQwNCkge1xuICAgICAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbihgU2l0ZSBpcyBub3QgZm91bmQ6ICR7c2l0ZU5hbWV9LiR7dGhpcy5kb21haW59YCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyAzMDHjg6rjg4DjgqTjg6zjgq/jg4jjgadodHRwc+OBq+WQkeOBi+OBhuWgtOWQiOOBr1NTTOWvvuW/nFxuICAgICAgICBjb25zdCBpc1NTTCA9XG4gICAgICAgICAgcmVzcG9uc2Uuc3RhdHVzID09PSAzMDEgJiYgcmVzcG9uc2UuaGVhZGVycy5nZXQoJ0xvY2F0aW9uJyk/LnN0YXJ0c1dpdGgoJ2h0dHBzJykgPT09IHRydWU7XG5cbiAgICAgICAgLy8g44Kt44Oj44OD44K344Ol44Gr5L+d5a2YXG4gICAgICAgIHRoaXMuc3NsQ2FjaGUuc2V0KHNpdGVOYW1lLCBpc1NTTCk7XG4gICAgICAgIHJldHVybiBpc1NTTDtcbiAgICAgIH0pKCksXG4gICAgICAoZXJyb3IpID0+IHtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgV2lraWRvdEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gY2hlY2sgU1NMIGZvciAke3NpdGVOYW1lfTogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQU1D44Oq44Kv44Ko44K544OI44KS5a6f6KGM44GZ44KLXG4gICAqIEBwYXJhbSBib2RpZXMgLSDjg6rjgq/jgqjjgrnjg4jjg5zjg4fjgqPphY3liJdcbiAgICogQHBhcmFtIHNpdGVOYW1lIC0g44K144Kk44OI5ZCN77yI55yB55Wl5pmC44Gvd3d377yJXG4gICAqIEBwYXJhbSBzc2xTdXBwb3J0ZWQgLSBTU0zlr77lv5zvvIjnnIHnlaXmmYLjga/oh6rli5XmpJzlh7rvvIlcbiAgICogQHJldHVybnMg44Os44K544Od44Oz44K56YWN5YiXXG4gICAqL1xuICByZXF1ZXN0KFxuICAgIGJvZGllczogQU1DUmVxdWVzdEJvZHlbXSxcbiAgICBzaXRlTmFtZSA9ICd3d3cnLFxuICAgIHNzbFN1cHBvcnRlZD86IGJvb2xlYW5cbiAgKTogV2lraWRvdFJlc3VsdEFzeW5jPEFNQ1Jlc3BvbnNlW10+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0V2l0aE9wdGlvbnMoYm9kaWVzLCB7XG4gICAgICBzaXRlTmFtZSxcbiAgICAgIHNzbFN1cHBvcnRlZCxcbiAgICAgIHJldHVybkV4Y2VwdGlvbnM6IGZhbHNlLFxuICAgIH0pIGFzIFdpa2lkb3RSZXN1bHRBc3luYzxBTUNSZXNwb25zZVtdPjtcbiAgfVxuXG4gIC8qKlxuICAgKiBBTUPjg6rjgq/jgqjjgrnjg4jjgpLlrp/ooYzjgZnjgovvvIjjgqrjg5fjgrfjg6fjg7PmjIflrprniYjvvIlcbiAgICogQHBhcmFtIGJvZGllcyAtIOODquOCr+OCqOOCueODiOODnOODh+OCo+mFjeWIl1xuICAgKiBAcGFyYW0gb3B0aW9ucyAtIOODquOCr+OCqOOCueODiOOCquODl+OCt+ODp+ODs1xuICAgKiBAcmV0dXJucyDjg6zjgrnjg53jg7PjgrnphY3liJfvvIhyZXR1cm5FeGNlcHRpb25z44GMdHJ1ZeOBruWgtOWQiOOBr+OCqOODqeODvOOCguWQq+OCgO+8iVxuICAgKi9cbiAgcmVxdWVzdFdpdGhPcHRpb25zKFxuICAgIGJvZGllczogQU1DUmVxdWVzdEJvZHlbXSxcbiAgICBvcHRpb25zOiBBTUNSZXF1ZXN0T3B0aW9ucyA9IHt9XG4gICk6IFdpa2lkb3RSZXN1bHRBc3luYzwoQU1DUmVzcG9uc2UgfCBXaWtpZG90RXJyb3IpW10+IHtcbiAgICBjb25zdCB7IHNpdGVOYW1lID0gJ3d3dycsIHNzbFN1cHBvcnRlZCwgcmV0dXJuRXhjZXB0aW9ucyA9IGZhbHNlIH0gPSBvcHRpb25zO1xuXG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gU1NM5a++5b+c54q25rOB44KS5Y+W5b6XXG4gICAgICAgIGxldCBzc2wgPSBzc2xTdXBwb3J0ZWQ7XG4gICAgICAgIGlmIChzc2wgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNvbnN0IHNzbFJlc3VsdCA9IGF3YWl0IHRoaXMuY2hlY2tTaXRlU1NMKHNpdGVOYW1lKTtcbiAgICAgICAgICBpZiAoc3NsUmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICAgIHRocm93IHNzbFJlc3VsdC5lcnJvcjtcbiAgICAgICAgICB9XG4gICAgICAgICAgc3NsID0gc3NsUmVzdWx0LnZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcHJvdG9jb2wgPSBzc2wgPyAnaHR0cHMnIDogJ2h0dHAnO1xuICAgICAgICBjb25zdCB1cmwgPSBgJHtwcm90b2NvbH06Ly8ke3NpdGVOYW1lfS4ke3RoaXMuZG9tYWlufS9hamF4LW1vZHVsZS1jb25uZWN0b3IucGhwYDtcblxuICAgICAgICAvLyDkuKbliJfjgafjg6rjgq/jgqjjgrnjg4jjgpLlrp/ooYxcbiAgICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgIGJvZGllcy5tYXAoKGJvZHkpID0+IHRoaXMubGltaXQoKCkgPT4gdGhpcy5zaW5nbGVSZXF1ZXN0KGJvZHksIHVybCkpKVxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChyZXR1cm5FeGNlcHRpb25zKSB7XG4gICAgICAgICAgLy8g44Ko44Op44O844KC5ZCr44KB44Gm44GZ44G544Gm44Gu57WQ5p6c44KS6L+U44GZXG4gICAgICAgICAgcmV0dXJuIHJlc3VsdHMubWFwKChyKSA9PiB7XG4gICAgICAgICAgICBpZiAoci5pc09rKCkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHIudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gci5lcnJvcjtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOOCqOODqeODvOOBjOOBguOCjOOBsOacgOWIneOBruOCqOODqeODvOOCkuOCueODreODvFxuICAgICAgICBjb25zdCBmaXJzdEVycm9yID0gcmVzdWx0cy5maW5kKChyKSA9PiByLmlzRXJyKCkpO1xuICAgICAgICBpZiAoZmlyc3RFcnJvcj8uaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IGZpcnN0RXJyb3IuZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0cy5tYXAoKHIpID0+IHtcbiAgICAgICAgICBpZiAoci5pc09rKCkpIHtcbiAgICAgICAgICAgIHJldHVybiByLnZhbHVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBuZXcgVW5leHBlY3RlZEVycm9yKCdVbmV4cGVjdGVkIGVycm9yIGluIHJlc3VsdCBwcm9jZXNzaW5nJyk7XG4gICAgICAgIH0pO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBXaWtpZG90RXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBVbmV4cGVjdGVkRXJyb3IoYEFNQyByZXF1ZXN0IGZhaWxlZDogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICog5Y2Y5LiA44Oq44Kv44Ko44K544OI44KS5a6f6KGM44GZ44KL5YaF6YOo44Oh44K944OD44OJXG4gICAqIEBwYXJhbSBib2R5IC0g44Oq44Kv44Ko44K544OI44Oc44OH44KjXG4gICAqIEBwYXJhbSB1cmwgLSDjg6rjgq/jgqjjgrnjg4hVUkxcbiAgICogQHJldHVybnMg44Os44K544Od44Oz44K5XG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHNpbmdsZVJlcXVlc3QoXG4gICAgYm9keTogQU1DUmVxdWVzdEJvZHksXG4gICAgdXJsOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxXaWtpZG90UmVzdWx0QXN5bmM8QU1DUmVzcG9uc2U+PiB7XG4gICAgbGV0IHJldHJ5Q291bnQgPSAwO1xuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIHdpa2lkb3RfdG9rZW4344KS6L+95YqgXG4gICAgICAgIGNvbnN0IHJlcXVlc3RCb2R5ID0geyAuLi5ib2R5LCB3aWtpZG90X3Rva2VuNzogV0lLSURPVF9UT0tFTjcgfTtcblxuICAgICAgICAvLyBVUkzjgqjjg7PjgrPjg7zjg4njgZXjgozjgZ/jg5zjg4fjgqPjgpLkvZzmiJBcbiAgICAgICAgY29uc3QgZm9ybURhdGEgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKCk7XG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHJlcXVlc3RCb2R5KSkge1xuICAgICAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBmb3JtRGF0YS5hcHBlbmQoa2V5LCBTdHJpbmcodmFsdWUpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMua3kucG9zdCh1cmwsIHtcbiAgICAgICAgICBoZWFkZXJzOiB0aGlzLmhlYWRlci5nZXRIZWFkZXJzKCksXG4gICAgICAgICAgYm9keTogZm9ybURhdGEudG9TdHJpbmcoKSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSlNPTuOBqOOBl+OBpuODkeODvOOCuVxuICAgICAgICBsZXQgcmVzcG9uc2VEYXRhOiB1bmtub3duO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJlc3BvbnNlRGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgcmV0dXJuIHdkRXJyQXN5bmMoXG4gICAgICAgICAgICBuZXcgUmVzcG9uc2VEYXRhRXJyb3IoYEFNQyByZXNwb25kZWQgd2l0aCBub24tSlNPTiBkYXRhOiAke2F3YWl0IHJlc3BvbnNlLnRleHQoKX1gKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB6b2Tjgafjg5Djg6rjg4fjg7zjgrfjg6fjg7NcbiAgICAgICAgY29uc3QgcGFyc2VSZXN1bHQgPSBhbWNSZXNwb25zZVNjaGVtYS5zYWZlUGFyc2UocmVzcG9uc2VEYXRhKTtcbiAgICAgICAgaWYgKCFwYXJzZVJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgICAgcmV0dXJuIHdkRXJyQXN5bmMoXG4gICAgICAgICAgICBuZXcgUmVzcG9uc2VEYXRhRXJyb3IoYEludmFsaWQgQU1DIHJlc3BvbnNlIGZvcm1hdDogJHtwYXJzZVJlc3VsdC5lcnJvci5tZXNzYWdlfWApXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFtY1Jlc3BvbnNlID0gcGFyc2VSZXN1bHQuZGF0YTtcblxuICAgICAgICAvLyB0cnlfYWdhaW7jga7loLTlkIjjga/jg6rjg4jjg6njgqRcbiAgICAgICAgaWYgKGFtY1Jlc3BvbnNlLnN0YXR1cyA9PT0gJ3RyeV9hZ2FpbicpIHtcbiAgICAgICAgICByZXRyeUNvdW50Kys7XG4gICAgICAgICAgaWYgKHJldHJ5Q291bnQgPj0gdGhpcy5jb25maWcucmV0cnlMaW1pdCkge1xuICAgICAgICAgICAgcmV0dXJuIHdkRXJyQXN5bmMobmV3IFdpa2lkb3RTdGF0dXNFcnJvcignQU1DIHJlc3BvbmRlZCB3aXRoIHRyeV9hZ2FpbicsICd0cnlfYWdhaW4nKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGJhY2tvZmYgPSBjYWxjdWxhdGVCYWNrb2ZmKFxuICAgICAgICAgICAgcmV0cnlDb3VudCxcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLnJldHJ5SW50ZXJ2YWwsXG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5iYWNrb2ZmRmFjdG9yLFxuICAgICAgICAgICAgdGhpcy5jb25maWcubWF4QmFja29mZlxuICAgICAgICAgICk7XG4gICAgICAgICAgYXdhaXQgc2xlZXAoYmFja29mZik7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBub19wZXJtaXNzaW9u44Gu5aC05ZCI44GvRm9yYmlkZGVuRXJyb3JcbiAgICAgICAgaWYgKGFtY1Jlc3BvbnNlLnN0YXR1cyA9PT0gJ25vX3Blcm1pc3Npb24nKSB7XG4gICAgICAgICAgY29uc3QgdGFyZ2V0U3RyID0gYm9keS5tb2R1bGVOYW1lXG4gICAgICAgICAgICA/IGBtb2R1bGVOYW1lOiAke2JvZHkubW9kdWxlTmFtZX1gXG4gICAgICAgICAgICA6IGJvZHkuYWN0aW9uXG4gICAgICAgICAgICAgID8gYGFjdGlvbjogJHtib2R5LmFjdGlvbn0vJHtib2R5LmV2ZW50ID8/ICcnfWBcbiAgICAgICAgICAgICAgOiAndW5rbm93bic7XG4gICAgICAgICAgcmV0dXJuIHdkRXJyQXN5bmMoXG4gICAgICAgICAgICBuZXcgRm9yYmlkZGVuRXJyb3IoXG4gICAgICAgICAgICAgIGBZb3VyIGFjY291bnQgaGFzIG5vIHBlcm1pc3Npb24gdG8gcGVyZm9ybSB0aGlzIGFjdGlvbjogJHt0YXJnZXRTdHJ9YFxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBva+OBp+OBquOBhOWgtOWQiOOBr+OCqOODqeODvFxuICAgICAgICBpZiAoYW1jUmVzcG9uc2Uuc3RhdHVzICE9PSAnb2snKSB7XG4gICAgICAgICAgcmV0dXJuIHdkRXJyQXN5bmMoXG4gICAgICAgICAgICBuZXcgV2lraWRvdFN0YXR1c0Vycm9yKFxuICAgICAgICAgICAgICBgQU1DIHJlc3BvbmRlZCB3aXRoIGVycm9yIHN0YXR1czogXCIke2FtY1Jlc3BvbnNlLnN0YXR1c31cImAsXG4gICAgICAgICAgICAgIGFtY1Jlc3BvbnNlLnN0YXR1c1xuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gd2RPa0FzeW5jKGFtY1Jlc3BvbnNlKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIEhUVFDjgqjjg6njg7zjga7loLTlkIjjga/jg6rjg4jjg6njgqRcbiAgICAgICAgcmV0cnlDb3VudCsrO1xuICAgICAgICBpZiAocmV0cnlDb3VudCA+PSB0aGlzLmNvbmZpZy5yZXRyeUxpbWl0KSB7XG4gICAgICAgICAgY29uc3Qgc3RhdHVzQ29kZSA9XG4gICAgICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmICdyZXNwb25zZScgaW4gZXJyb3JcbiAgICAgICAgICAgICAgPyAoKGVycm9yIGFzIHsgcmVzcG9uc2U/OiB7IHN0YXR1cz86IG51bWJlciB9IH0pLnJlc3BvbnNlPy5zdGF0dXMgPz9cbiAgICAgICAgICAgICAgICBERUZBVUxUX0hUVFBfU1RBVFVTX0NPREUpXG4gICAgICAgICAgICAgIDogREVGQVVMVF9IVFRQX1NUQVRVU19DT0RFO1xuICAgICAgICAgIHJldHVybiB3ZEVyckFzeW5jKFxuICAgICAgICAgICAgbmV3IEFNQ0h0dHBFcnJvcihgQU1DIEhUVFAgcmVxdWVzdCBmYWlsZWQ6ICR7U3RyaW5nKGVycm9yKX1gLCBzdGF0dXNDb2RlKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBiYWNrb2ZmID0gY2FsY3VsYXRlQmFja29mZihcbiAgICAgICAgICByZXRyeUNvdW50LFxuICAgICAgICAgIHRoaXMuY29uZmlnLnJldHJ5SW50ZXJ2YWwsXG4gICAgICAgICAgdGhpcy5jb25maWcuYmFja29mZkZhY3RvcixcbiAgICAgICAgICB0aGlzLmNvbmZpZy5tYXhCYWNrb2ZmXG4gICAgICAgICk7XG4gICAgICAgIGF3YWl0IHNsZWVwKGJhY2tvZmYpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIiwKICAgICIvKipcbiAqIEFqYXggTW9kdWxlIENvbm5lY3RvcuioreWumlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFNQ0NvbmZpZyB7XG4gIC8qKiDjg6rjgq/jgqjjgrnjg4jjgr/jgqTjg6DjgqLjgqbjg4jvvIjjg5/jg6rnp5LvvIkgKi9cbiAgdGltZW91dDogbnVtYmVyO1xuXG4gIC8qKiDjg6rjg4jjg6njgqTkuIrpmZDlm57mlbAgKi9cbiAgcmV0cnlMaW1pdDogbnVtYmVyO1xuXG4gIC8qKiDjg6rjg4jjg6njgqTln7rmnKzplpPpmpTvvIjjg5/jg6rnp5LvvIkgKi9cbiAgcmV0cnlJbnRlcnZhbDogbnVtYmVyO1xuXG4gIC8qKiDmnIDlpKfjg5Djg4Pjgq/jgqrjg5XvvIjjg5/jg6rnp5LvvIkgKi9cbiAgbWF4QmFja29mZjogbnVtYmVyO1xuXG4gIC8qKiDjg5Djg4Pjgq/jgqrjg5Xkv4LmlbAgKi9cbiAgYmFja29mZkZhY3RvcjogbnVtYmVyO1xuXG4gIC8qKiDmnIDlpKfkuKbliJfjg6rjgq/jgqjjgrnjg4jmlbAgKi9cbiAgc2VtYXBob3JlTGltaXQ6IG51bWJlcjtcbn1cblxuLyoqIOODh+ODleOCqeODq+ODiEFNQ+ioreWumiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfQU1DX0NPTkZJRzogQU1DQ29uZmlnID0ge1xuICB0aW1lb3V0OiAyMDAwMCxcbiAgcmV0cnlMaW1pdDogMyxcbiAgcmV0cnlJbnRlcnZhbDogMTAwMCxcbiAgbWF4QmFja29mZjogNjAwMDAsXG4gIGJhY2tvZmZGYWN0b3I6IDIuMCxcbiAgc2VtYXBob3JlTGltaXQ6IDEwLFxufTtcblxuLyoqXG4gKiBXaWtpZG9044GM6KaB5rGC44GZ44KL5Zu65a6a44OI44O844Kv44Oz5YCkXG4gKiDjgZPjgozjga9XaWtpZG9044Gu44OV44Ot44Oz44OI44Ko44Oz44OJ44GL44KJ5Y+W5b6X44GV44KM44KL5Zu65a6a5YCk44Gn44CBXG4gKiDjgrvjgq3jg6Xjg6rjg4bjgqPjg4jjg7zjgq/jg7Pjgafjga/jgarjgY/ljZjjgarjgovorZjliKXlrZDjgajjgZfjgabkvb/nlKjjgZXjgozjgotcbiAqL1xuZXhwb3J0IGNvbnN0IFdJS0lET1RfVE9LRU43ID0gJzEyMzQ1Nic7XG5cbi8qKlxuICogSFRUUOOCqOODqeODvOaZguOBruODleOCqeODvOODq+ODkOODg+OCr+OCueODhuODvOOCv+OCueOCs+ODvOODiVxuICog44Os44K544Od44Oz44K544GL44KJ44K544OG44O844K/44K544Kz44O844OJ44KS5Y+W5b6X44Gn44GN44Gq44GE5aC05ZCI44Gr5L2/55SoXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0hUVFBfU1RBVFVTX0NPREUgPSA5OTk7XG4iLAogICAgIi8qKlxuICogQU1D44Oq44Kv44Ko44K544OI44OY44OD44OA44O844KS566h55CG44GZ44KL44Kv44Op44K5XG4gKi9cbmV4cG9ydCBjbGFzcyBBTUNIZWFkZXIge1xuICBwcml2YXRlIGNvb2tpZXM6IE1hcDxzdHJpbmcsIHN0cmluZz47XG4gIHByaXZhdGUgY29udGVudFR5cGU6IHN0cmluZztcbiAgcHJpdmF0ZSB1c2VyQWdlbnQ6IHN0cmluZztcbiAgcHJpdmF0ZSByZWZlcmVyOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBvcHRpb25zIC0g44OY44OD44OA44O85Yid5pyf5YyW44Kq44OX44K344On44OzXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRpb25zPzogeyBjb250ZW50VHlwZT86IHN0cmluZzsgdXNlckFnZW50Pzogc3RyaW5nOyByZWZlcmVyPzogc3RyaW5nIH0pIHtcbiAgICB0aGlzLmNvbnRlbnRUeXBlID0gb3B0aW9ucz8uY29udGVudFR5cGUgPz8gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZDsgY2hhcnNldD1VVEYtOCc7XG4gICAgdGhpcy51c2VyQWdlbnQgPSBvcHRpb25zPy51c2VyQWdlbnQgPz8gJ1dpa2lkb3RUUyc7XG4gICAgdGhpcy5yZWZlcmVyID0gb3B0aW9ucz8ucmVmZXJlciA/PyAnaHR0cHM6Ly93d3cud2lraWRvdC5jb20vJztcbiAgICB0aGlzLmNvb2tpZXMgPSBuZXcgTWFwKFtbJ3dpa2lkb3RfdG9rZW43JywgJzEyMzQ1NiddXSk7XG4gIH1cblxuICAvKipcbiAgICogQ29va2ll44KS6Kit5a6a44GZ44KLXG4gICAqIEBwYXJhbSBuYW1lIC0gQ29va2ll5ZCNXG4gICAqIEBwYXJhbSB2YWx1ZSAtIENvb2tpZeWApFxuICAgKi9cbiAgc2V0Q29va2llKG5hbWU6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY29va2llcy5zZXQobmFtZSwgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvb2tpZeOCkuWJiumZpOOBmeOCi1xuICAgKiBAcGFyYW0gbmFtZSAtIENvb2tpZeWQjVxuICAgKi9cbiAgZGVsZXRlQ29va2llKG5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY29va2llcy5kZWxldGUobmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogQ29va2ll44KS5Y+W5b6X44GZ44KLXG4gICAqIEBwYXJhbSBuYW1lIC0gQ29va2ll5ZCNXG4gICAqIEByZXR1cm5zIENvb2tpZeWApOOAgeWtmOWcqOOBl+OBquOBhOWgtOWQiOOBr3VuZGVmaW5lZFxuICAgKi9cbiAgZ2V0Q29va2llKG5hbWU6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuY29va2llcy5nZXQobmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogSFRUUOODmOODg+ODgOODvOOCquODluOCuOOCp+OCr+ODiOOCkuWPluW+l+OBmeOCi1xuICAgKiBAcmV0dXJucyDjg5jjg4Pjg4Djg7zovp7mm7hcbiAgICovXG4gIGdldEhlYWRlcnMoKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gICAgY29uc3QgY29va2llU3RyaW5nID0gQXJyYXkuZnJvbSh0aGlzLmNvb2tpZXMuZW50cmllcygpKVxuICAgICAgLm1hcCgoW25hbWUsIHZhbHVlXSkgPT4gYCR7bmFtZX09JHt2YWx1ZX1gKVxuICAgICAgLmpvaW4oJzsgJyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgJ0NvbnRlbnQtVHlwZSc6IHRoaXMuY29udGVudFR5cGUsXG4gICAgICAnVXNlci1BZ2VudCc6IHRoaXMudXNlckFnZW50LFxuICAgICAgUmVmZXJlcjogdGhpcy5yZWZlcmVyLFxuICAgICAgQ29va2llOiBjb29raWVTdHJpbmcsXG4gICAgfTtcbiAgfVxufVxuIiwKICAgICJpbXBvcnQgeyB6IH0gZnJvbSAnem9kJztcblxuLyoqXG4gKiBBTUPjg6rjgq/jgqjjgrnjg4jjg5zjg4fjgqPjga7lgKTlnotcbiAqL1xuZXhwb3J0IHR5cGUgQU1DUmVxdWVzdEJvZHlWYWx1ZSA9XG4gIHwgc3RyaW5nXG4gIHwgbnVtYmVyXG4gIHwgYm9vbGVhblxuICB8IG51bGxcbiAgfCB1bmRlZmluZWRcbiAgfCBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuICB8IEFNQ1JlcXVlc3RCb2R5VmFsdWVbXTtcblxuLyoqXG4gKiBBTUPjg6rjgq/jgqjjgrnjg4jjg5zjg4fjgqPjga7lnovlrprnvqlcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBTUNSZXF1ZXN0Qm9keSB7XG4gIG1vZHVsZU5hbWU/OiBzdHJpbmc7XG4gIGFjdGlvbj86IHN0cmluZztcbiAgZXZlbnQ/OiBzdHJpbmc7XG4gIFtrZXk6IHN0cmluZ106IEFNQ1JlcXVlc3RCb2R5VmFsdWU7XG59XG5cbi8qKlxuICogQU1D44Os44K544Od44Oz44K544Gu44OZ44O844K544K544Kt44O844OeXG4gKi9cbmNvbnN0IGJhc2VTY2hlbWE6IHouWm9kT2JqZWN0PHtcbiAgc3RhdHVzOiB6LlpvZFN0cmluZztcbiAgYm9keTogei5ab2RPcHRpb25hbDx6LlpvZFN0cmluZz47XG4gIG1lc3NhZ2U6IHouWm9kT3B0aW9uYWw8ei5ab2RTdHJpbmc+O1xufT4gPSB6Lm9iamVjdCh7XG4gIHN0YXR1czogei5zdHJpbmcoKSxcbiAgYm9keTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICBtZXNzYWdlOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG59KTtcblxuLyoqXG4gKiBBTUPjg6zjgrnjg53jg7Pjgrnjgrnjgq3jg7zjg55cbiAqL1xuZXhwb3J0IGNvbnN0IGFtY1Jlc3BvbnNlU2NoZW1hOiB6LlpvZFR5cGU8ei5pbmZlcjx0eXBlb2YgYmFzZVNjaGVtYT4gJiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4gPVxuICBiYXNlU2NoZW1hLnBhc3N0aHJvdWdoKCk7XG5cbi8qKlxuICogQU1D44Os44K544Od44Oz44K55Z6LXG4gKi9cbmV4cG9ydCB0eXBlIEFNQ1Jlc3BvbnNlID0gei5pbmZlcjx0eXBlb2YgYW1jUmVzcG9uc2VTY2hlbWE+O1xuXG4vKipcbiAqIOaIkOWKn+OBl+OBn0FNQ+ODrOOCueODneODs+OCuVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFNQ1N1Y2Nlc3NSZXNwb25zZSB7XG4gIHN0YXR1czogJ29rJztcbiAgYm9keTogc3RyaW5nO1xuICBba2V5OiBzdHJpbmddOiB1bmtub3duO1xufVxuXG4vKipcbiAqIEFNQ+ODrOOCueODneODs+OCueOBjOaIkOWKn+OBi+OBqeOBhuOBi+OCkuWIpOWumuOBmeOCi+Wei+OCrOODvOODiVxuICogQHBhcmFtIHJlc3BvbnNlIC0gQU1D44Os44K544Od44Oz44K5XG4gKiBAcmV0dXJucyDmiJDlip/jg6zjgrnjg53jg7Pjgrnjga7loLTlkIh0cnVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1N1Y2Nlc3NSZXNwb25zZShyZXNwb25zZTogQU1DUmVzcG9uc2UpOiByZXNwb25zZSBpcyBBTUNTdWNjZXNzUmVzcG9uc2Uge1xuICByZXR1cm4gcmVzcG9uc2Uuc3RhdHVzID09PSAnb2snO1xufVxuIiwKICAgICJpbXBvcnQgeyBTZXNzaW9uQ3JlYXRlRXJyb3IgfSBmcm9tICcuLi9jb21tb24vZXJyb3JzJztcbmltcG9ydCB7IGZyb21Qcm9taXNlLCB0eXBlIFdpa2lkb3RSZXN1bHRBc3luYywgd2RPa0FzeW5jIH0gZnJvbSAnLi4vY29tbW9uL3R5cGVzJztcbmltcG9ydCB0eXBlIHsgQXV0aENsaWVudENvbnRleHQgfSBmcm9tICcuLi9tb2R1bGUvdHlwZXMnO1xuXG5jb25zdCBMT0dJTl9VUkwgPSAnaHR0cHM6Ly93d3cud2lraWRvdC5jb20vZGVmYXVsdC0tZmxvdy9sb2dpbl9fTG9naW5Qb3B1cFNjcmVlbic7XG5cbi8qKlxuICog44Om44O844K244O85ZCN44Go44OR44K544Ov44O844OJ44GnV2lraWRvdOOBq+ODreOCsOOCpOODs+OBmeOCi1xuICogQHBhcmFtIGNsaWVudCAtIOOCr+ODqeOCpOOCouODs+ODiOOCs+ODs+ODhuOCreOCueODiO+8iEFNQ0NsaWVudOOCkuaMgeOBpOOCquODluOCuOOCp+OCr+ODiO+8iVxuICogQHBhcmFtIHVzZXJuYW1lIC0g44Om44O844K244O85ZCNXG4gKiBAcGFyYW0gcGFzc3dvcmQgLSDjg5Hjgrnjg6/jg7zjg4lcbiAqIEByZXR1cm5zIOaIkOWKn+aZguOBr3ZvaWTjgIHlpLHmlZfmmYLjga9TZXNzaW9uQ3JlYXRlRXJyb3JcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvZ2luKFxuICBjbGllbnQ6IEF1dGhDbGllbnRDb250ZXh0LFxuICB1c2VybmFtZTogc3RyaW5nLFxuICBwYXNzd29yZDogc3RyaW5nXG4pOiBXaWtpZG90UmVzdWx0QXN5bmM8dm9pZD4ge1xuICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGZvcm1EYXRhID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh7XG4gICAgICAgIGxvZ2luOiB1c2VybmFtZSxcbiAgICAgICAgcGFzc3dvcmQ6IHBhc3N3b3JkLFxuICAgICAgICBhY3Rpb246ICdMb2dpbjJBY3Rpb24nLFxuICAgICAgICBldmVudDogJ2xvZ2luJyxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKExPR0lOX1VSTCwge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgaGVhZGVyczogY2xpZW50LmFtY0NsaWVudC5oZWFkZXIuZ2V0SGVhZGVycygpLFxuICAgICAgICBib2R5OiBmb3JtRGF0YS50b1N0cmluZygpLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIENoZWNrIHN0YXR1cyBjb2RlXG4gICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgIHRocm93IG5ldyBTZXNzaW9uQ3JlYXRlRXJyb3IoXG4gICAgICAgICAgYExvZ2luIGF0dGVtcHQgZmFpbGVkIGR1ZSB0byBIVFRQIHN0YXR1cyBjb2RlOiAke3Jlc3BvbnNlLnN0YXR1c31gXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGJvZHkgZm9yIGVycm9yIG1lc3NhZ2VcbiAgICAgIGNvbnN0IGJvZHkgPSBhd2FpdCByZXNwb25zZS50ZXh0KCk7XG4gICAgICBpZiAoYm9keS5pbmNsdWRlcygnVGhlIGxvZ2luIGFuZCBwYXNzd29yZCBkbyBub3QgbWF0Y2gnKSkge1xuICAgICAgICB0aHJvdyBuZXcgU2Vzc2lvbkNyZWF0ZUVycm9yKCdMb2dpbiBhdHRlbXB0IGZhaWxlZCBkdWUgdG8gaW52YWxpZCB1c2VybmFtZSBvciBwYXNzd29yZCcpO1xuICAgICAgfVxuXG4gICAgICAvLyBDaGVjayBjb29raWVzXG4gICAgICBjb25zdCBjb29raWVzID0gcmVzcG9uc2UuaGVhZGVycy5nZXQoJ1NldC1Db29raWUnKTtcbiAgICAgIGlmICghY29va2llcykge1xuICAgICAgICB0aHJvdyBuZXcgU2Vzc2lvbkNyZWF0ZUVycm9yKCdMb2dpbiBhdHRlbXB0IGZhaWxlZCBkdWUgdG8gbWlzc2luZyBjb29raWVzJyk7XG4gICAgICB9XG5cbiAgICAgIC8vIEV4dHJhY3QgV0lLSURPVF9TRVNTSU9OX0lEIGZyb20gY29va2llc1xuICAgICAgY29uc3Qgc2Vzc2lvbklkTWF0Y2ggPSBjb29raWVzLm1hdGNoKC9XSUtJRE9UX1NFU1NJT05fSUQ9KFteO10rKS8pO1xuICAgICAgaWYgKCFzZXNzaW9uSWRNYXRjaD8uWzFdKSB7XG4gICAgICAgIHRocm93IG5ldyBTZXNzaW9uQ3JlYXRlRXJyb3IoXG4gICAgICAgICAgJ0xvZ2luIGF0dGVtcHQgZmFpbGVkIGR1ZSB0byBtaXNzaW5nIFdJS0lET1RfU0VTU0lPTl9JRCBjb29raWUnXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIFNldCBzZXNzaW9uIGNvb2tpZVxuICAgICAgY2xpZW50LmFtY0NsaWVudC5oZWFkZXIuc2V0Q29va2llKCdXSUtJRE9UX1NFU1NJT05fSUQnLCBzZXNzaW9uSWRNYXRjaFsxXSk7XG4gICAgfSkoKSxcbiAgICAoZXJyb3IpID0+IHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFNlc3Npb25DcmVhdGVFcnJvcikge1xuICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IFNlc3Npb25DcmVhdGVFcnJvcihgTG9naW4gZmFpbGVkOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgfVxuICApO1xufVxuXG4vKipcbiAqIOODreOCsOOCouOCpuODiOOBmeOCi1xuICogQHBhcmFtIGNsaWVudCAtIOOCr+ODqeOCpOOCouODs+ODiOOCs+ODs+ODhuOCreOCueODiO+8iEFNQ0NsaWVudOOCkuaMgeOBpOOCquODluOCuOOCp+OCr+ODiO+8iVxuICogQHJldHVybnMg5oiQ5Yqf5pmC44Gvdm9pZFxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9nb3V0KGNsaWVudDogQXV0aENsaWVudENvbnRleHQpOiBXaWtpZG90UmVzdWx0QXN5bmM8dm9pZD4ge1xuICAvLyBUcnkgdG8gbG9nb3V0IHZpYSBBTUMsIHRoZW4gYWx3YXlzIHJlbW92ZSBzZXNzaW9uIGNvb2tpZVxuICByZXR1cm4gY2xpZW50LmFtY0NsaWVudFxuICAgIC5yZXF1ZXN0KFtcbiAgICAgIHtcbiAgICAgICAgbW9kdWxlTmFtZTogJ0VtcHR5JyxcbiAgICAgICAgYWN0aW9uOiAnTG9naW4yQWN0aW9uJyxcbiAgICAgICAgZXZlbnQ6ICdsb2dvdXQnLFxuICAgICAgfSxcbiAgICBdKVxuICAgIC5tYXAoKCkgPT4ge1xuICAgICAgLy8gTG9nb3V0IHN1Y2NlZWRlZCwgcmVtb3ZlIHNlc3Npb24gY29va2llXG4gICAgICBjbGllbnQuYW1jQ2xpZW50LmhlYWRlci5kZWxldGVDb29raWUoJ1dJS0lET1RfU0VTU0lPTl9JRCcpO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9KVxuICAgIC5vckVsc2UoKCkgPT4ge1xuICAgICAgLy8gRXZlbiBpZiBsb2dvdXQgcmVxdWVzdCBmYWlscywgd2Ugc3RpbGwgd2FudCB0byBjbGVhciB0aGUgc2Vzc2lvbiBsb2NhbGx5XG4gICAgICBjbGllbnQuYW1jQ2xpZW50LmhlYWRlci5kZWxldGVDb29raWUoJ1dJS0lET1RfU0VTU0lPTl9JRCcpO1xuICAgICAgcmV0dXJuIHdkT2tBc3luYyh1bmRlZmluZWQpO1xuICAgIH0pO1xufVxuIiwKICAgICJpbXBvcnQgKiBhcyBjaGVlcmlvIGZyb20gJ2NoZWVyaW8nO1xuaW1wb3J0IHtcbiAgRm9yYmlkZGVuRXJyb3IsXG4gIExvZ2luUmVxdWlyZWRFcnJvcixcbiAgTm9FbGVtZW50RXJyb3IsXG4gIFVuZXhwZWN0ZWRFcnJvcixcbn0gZnJvbSAnLi4vLi4vY29tbW9uL2Vycm9ycyc7XG5pbXBvcnQgeyBmcm9tUHJvbWlzZSwgdHlwZSBXaWtpZG90UmVzdWx0QXN5bmMgfSBmcm9tICcuLi8uLi9jb21tb24vdHlwZXMnO1xuaW1wb3J0IHsgcGFyc2VPZGF0ZSwgcGFyc2VVc2VyIH0gZnJvbSAnLi4vLi4vdXRpbC9wYXJzZXInO1xuaW1wb3J0IHR5cGUgeyBDbGllbnQgfSBmcm9tICcuLi9jbGllbnQnO1xuaW1wb3J0IHR5cGUgeyBBYnN0cmFjdFVzZXIgfSBmcm9tICcuLi91c2VyJztcbmltcG9ydCB0eXBlIHsgVXNlciB9IGZyb20gJy4uL3VzZXIvdXNlcic7XG5cbi8qKlxuICog44OX44Op44Kk44OZ44O844OI44Oh44OD44K744O844K444OH44O844K/XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJpdmF0ZU1lc3NhZ2VEYXRhIHtcbiAgY2xpZW50OiBDbGllbnQ7XG4gIGlkOiBudW1iZXI7XG4gIHNlbmRlcjogQWJzdHJhY3RVc2VyO1xuICByZWNpcGllbnQ6IEFic3RyYWN0VXNlcjtcbiAgc3ViamVjdDogc3RyaW5nO1xuICBib2R5OiBzdHJpbmc7XG4gIGNyZWF0ZWRBdDogRGF0ZTtcbn1cblxuLyoqXG4gKiDjg5fjg6njgqTjg5njg7zjg4jjg6Hjg4Pjgrvjg7zjgrhcbiAqL1xuZXhwb3J0IGNsYXNzIFByaXZhdGVNZXNzYWdlIHtcbiAgcHVibGljIHJlYWRvbmx5IGNsaWVudDogQ2xpZW50O1xuICBwdWJsaWMgcmVhZG9ubHkgaWQ6IG51bWJlcjtcbiAgcHVibGljIHJlYWRvbmx5IHNlbmRlcjogQWJzdHJhY3RVc2VyO1xuICBwdWJsaWMgcmVhZG9ubHkgcmVjaXBpZW50OiBBYnN0cmFjdFVzZXI7XG4gIHB1YmxpYyByZWFkb25seSBzdWJqZWN0OiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBib2R5OiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBjcmVhdGVkQXQ6IERhdGU7XG5cbiAgY29uc3RydWN0b3IoZGF0YTogUHJpdmF0ZU1lc3NhZ2VEYXRhKSB7XG4gICAgdGhpcy5jbGllbnQgPSBkYXRhLmNsaWVudDtcbiAgICB0aGlzLmlkID0gZGF0YS5pZDtcbiAgICB0aGlzLnNlbmRlciA9IGRhdGEuc2VuZGVyO1xuICAgIHRoaXMucmVjaXBpZW50ID0gZGF0YS5yZWNpcGllbnQ7XG4gICAgdGhpcy5zdWJqZWN0ID0gZGF0YS5zdWJqZWN0O1xuICAgIHRoaXMuYm9keSA9IGRhdGEuYm9keTtcbiAgICB0aGlzLmNyZWF0ZWRBdCA9IGRhdGEuY3JlYXRlZEF0O1xuICB9XG5cbiAgLyoqXG4gICAqIOODoeODg+OCu+ODvOOCuElE44GL44KJ44Oh44OD44K744O844K444KS5Y+W5b6X44GZ44KLXG4gICAqIEBwYXJhbSBjbGllbnQgLSDjgq/jg6njgqTjgqLjg7Pjg4hcbiAgICogQHBhcmFtIG1lc3NhZ2VJZCAtIOODoeODg+OCu+ODvOOCuElEXG4gICAqIEByZXR1cm5zIOODl+ODqeOCpOODmeODvOODiOODoeODg+OCu+ODvOOCuFxuICAgKi9cbiAgc3RhdGljIGZyb21JZChjbGllbnQ6IENsaWVudCwgbWVzc2FnZUlkOiBudW1iZXIpOiBXaWtpZG90UmVzdWx0QXN5bmM8UHJpdmF0ZU1lc3NhZ2U+IHtcbiAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBQcml2YXRlTWVzc2FnZUNvbGxlY3Rpb24uZnJvbUlkcyhjbGllbnQsIFttZXNzYWdlSWRdKTtcbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSByZXN1bHQudmFsdWVbMF07XG4gICAgICAgIGlmICghbWVzc2FnZSkge1xuICAgICAgICAgIHRocm93IG5ldyBOb0VsZW1lbnRFcnJvcihgTWVzc2FnZSBub3QgZm91bmQ6ICR7bWVzc2FnZUlkfWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBGb3JiaWRkZW5FcnJvciB8fCBlcnJvciBpbnN0YW5jZW9mIE5vRWxlbWVudEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gZ2V0IG1lc3NhZ2U6ICR7U3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIOODl+ODqeOCpOODmeODvOODiOODoeODg+OCu+ODvOOCuOOCkumAgeS/oeOBmeOCi1xuICAgKiBAcGFyYW0gY2xpZW50IC0g44Kv44Op44Kk44Ki44Oz44OIXG4gICAqIEBwYXJhbSByZWNpcGllbnQgLSDlj5fkv6HogIVcbiAgICogQHBhcmFtIHN1YmplY3QgLSDku7blkI1cbiAgICogQHBhcmFtIGJvZHkgLSDmnKzmlodcbiAgICovXG4gIHN0YXRpYyBzZW5kKFxuICAgIGNsaWVudDogQ2xpZW50LFxuICAgIHJlY2lwaWVudDogVXNlcixcbiAgICBzdWJqZWN0OiBzdHJpbmcsXG4gICAgYm9keTogc3RyaW5nXG4gICk6IFdpa2lkb3RSZXN1bHRBc3luYzx2b2lkPiB7XG4gICAgY29uc3QgbG9naW5SZXN1bHQgPSBjbGllbnQucmVxdWlyZUxvZ2luKCk7XG4gICAgaWYgKGxvZ2luUmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgIHJldHVybiBmcm9tUHJvbWlzZShcbiAgICAgICAgUHJvbWlzZS5yZWplY3QobG9naW5SZXN1bHQuZXJyb3IpLFxuICAgICAgICAoKSA9PiBuZXcgTG9naW5SZXF1aXJlZEVycm9yKCdMb2dpbiByZXF1aXJlZCB0byBzZW5kIG1lc3NhZ2UnKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjbGllbnQuYW1jQ2xpZW50LnJlcXVlc3QoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNvdXJjZTogYm9keSxcbiAgICAgICAgICAgIHN1YmplY3QsXG4gICAgICAgICAgICB0b191c2VyX2lkOiByZWNpcGllbnQuaWQsXG4gICAgICAgICAgICBhY3Rpb246ICdEYXNoYm9hcmRNZXNzYWdlQWN0aW9uJyxcbiAgICAgICAgICAgIGV2ZW50OiAnc2VuZCcsXG4gICAgICAgICAgICBtb2R1bGVOYW1lOiAnRW1wdHknLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0pO1xuICAgICAgICBpZiAocmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0pKCksXG4gICAgICAoZXJyb3IpID0+IG5ldyBVbmV4cGVjdGVkRXJyb3IoYEZhaWxlZCB0byBzZW5kIG1lc3NhZ2U6ICR7U3RyaW5nKGVycm9yKX1gKVxuICAgICk7XG4gIH1cblxuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBgUHJpdmF0ZU1lc3NhZ2UoaWQ9JHt0aGlzLmlkfSwgc2VuZGVyPSR7dGhpcy5zZW5kZXJ9LCByZWNpcGllbnQ9JHt0aGlzLnJlY2lwaWVudH0sIHN1YmplY3Q9JHt0aGlzLnN1YmplY3R9KWA7XG4gIH1cbn1cblxuLyoqXG4gKiDjg5fjg6njgqTjg5njg7zjg4jjg6Hjg4Pjgrvjg7zjgrjjgrPjg6zjgq/jgrfjg6fjg7NcbiAqL1xuZXhwb3J0IGNsYXNzIFByaXZhdGVNZXNzYWdlQ29sbGVjdGlvbiBleHRlbmRzIEFycmF5PFByaXZhdGVNZXNzYWdlPiB7XG4gIHB1YmxpYyByZWFkb25seSBjbGllbnQ6IENsaWVudDtcblxuICBjb25zdHJ1Y3RvcihjbGllbnQ6IENsaWVudCwgbWVzc2FnZXM/OiBQcml2YXRlTWVzc2FnZVtdKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmNsaWVudCA9IGNsaWVudDtcbiAgICBpZiAobWVzc2FnZXMpIHtcbiAgICAgIHRoaXMucHVzaCguLi5tZXNzYWdlcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIElE44Gn5qSc57SiXG4gICAqL1xuICBmaW5kQnlJZChpZDogbnVtYmVyKTogUHJpdmF0ZU1lc3NhZ2UgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmZpbmQoKG1lc3NhZ2UpID0+IG1lc3NhZ2UuaWQgPT09IGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg6Hjg4Pjgrvjg7zjgrhJROOBruODquOCueODiOOBi+OCieODoeODg+OCu+ODvOOCuOOCkuWPluW+l+OBmeOCi1xuICAgKi9cbiAgc3RhdGljIGZyb21JZHMoXG4gICAgY2xpZW50OiBDbGllbnQsXG4gICAgbWVzc2FnZUlkczogbnVtYmVyW11cbiAgKTogV2lraWRvdFJlc3VsdEFzeW5jPFByaXZhdGVNZXNzYWdlQ29sbGVjdGlvbj4ge1xuICAgIGNvbnN0IGxvZ2luUmVzdWx0ID0gY2xpZW50LnJlcXVpcmVMb2dpbigpO1xuICAgIGlmIChsb2dpblJlc3VsdC5pc0VycigpKSB7XG4gICAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAgIFByb21pc2UucmVqZWN0KGxvZ2luUmVzdWx0LmVycm9yKSxcbiAgICAgICAgKCkgPT4gbmV3IExvZ2luUmVxdWlyZWRFcnJvcignTG9naW4gcmVxdWlyZWQgdG8gZ2V0IG1lc3NhZ2VzJylcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgYm9kaWVzID0gbWVzc2FnZUlkcy5tYXAoKG1lc3NhZ2VJZCkgPT4gKHtcbiAgICAgICAgICBpdGVtOiBtZXNzYWdlSWQsXG4gICAgICAgICAgbW9kdWxlTmFtZTogJ2Rhc2hib2FyZC9tZXNzYWdlcy9ETVZpZXdNZXNzYWdlTW9kdWxlJyxcbiAgICAgICAgfSkpO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNsaWVudC5hbWNDbGllbnQucmVxdWVzdChib2RpZXMpO1xuICAgICAgICBpZiAocmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBtZXNzYWdlczogUHJpdmF0ZU1lc3NhZ2VbXSA9IFtdO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWVzc2FnZUlkcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gcmVzdWx0LnZhbHVlW2ldO1xuICAgICAgICAgIGNvbnN0IG1lc3NhZ2VJZCA9IG1lc3NhZ2VJZHNbaV07XG4gICAgICAgICAgaWYgKCFyZXNwb25zZSB8fCBtZXNzYWdlSWQgPT09IHVuZGVmaW5lZCkgY29udGludWU7XG5cbiAgICAgICAgICBjb25zdCBodG1sID0gU3RyaW5nKHJlc3BvbnNlLmJvZHkgPz8gJycpO1xuICAgICAgICAgIGNvbnN0ICQgPSBjaGVlcmlvLmxvYWQoaHRtbCk7XG5cbiAgICAgICAgICAvLyDjg6bjg7zjgrbjg7zmg4XloLHjgpLlj5blvpdcbiAgICAgICAgICBjb25zdCBwcmludHVzZXJFbGVtcyA9ICQoJ2Rpdi5wbWVzc2FnZSBkaXYuaGVhZGVyIHNwYW4ucHJpbnR1c2VyJyk7XG4gICAgICAgICAgaWYgKHByaW50dXNlckVsZW1zLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBGb3JiaWRkZW5FcnJvcihgRmFpbGVkIHRvIGdldCBtZXNzYWdlOiAke21lc3NhZ2VJZH1gKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBzZW5kZXJFbGVtID0gJChwcmludHVzZXJFbGVtc1swXSk7XG4gICAgICAgICAgY29uc3QgcmVjaXBpZW50RWxlbSA9ICQocHJpbnR1c2VyRWxlbXNbMV0pO1xuXG4gICAgICAgICAgY29uc3Qgc2VuZGVyID0gcGFyc2VVc2VyKGNsaWVudCwgc2VuZGVyRWxlbSk7XG4gICAgICAgICAgY29uc3QgcmVjaXBpZW50ID0gcGFyc2VVc2VyKGNsaWVudCwgcmVjaXBpZW50RWxlbSk7XG5cbiAgICAgICAgICAvLyDku7blkI1cbiAgICAgICAgICBjb25zdCBzdWJqZWN0RWxlbSA9ICQoJ2Rpdi5wbWVzc2FnZSBkaXYuaGVhZGVyIHNwYW4uc3ViamVjdCcpO1xuICAgICAgICAgIGNvbnN0IHN1YmplY3QgPSBzdWJqZWN0RWxlbS50ZXh0KCkudHJpbSgpO1xuXG4gICAgICAgICAgLy8g5pys5paHXG4gICAgICAgICAgY29uc3QgYm9keUVsZW0gPSAkKCdkaXYucG1lc3NhZ2UgZGl2LmJvZHknKTtcbiAgICAgICAgICBjb25zdCBib2R5ID0gYm9keUVsZW0udGV4dCgpLnRyaW0oKTtcblxuICAgICAgICAgIC8vIOaXpeaZglxuICAgICAgICAgIGNvbnN0IG9kYXRlRWxlbSA9ICQoJ2Rpdi5oZWFkZXIgc3Bhbi5vZGF0ZScpO1xuICAgICAgICAgIGNvbnN0IGNyZWF0ZWRBdCA9XG4gICAgICAgICAgICBvZGF0ZUVsZW0ubGVuZ3RoID4gMCA/IChwYXJzZU9kYXRlKG9kYXRlRWxlbSkgPz8gbmV3IERhdGUoMCkpIDogbmV3IERhdGUoMCk7XG5cbiAgICAgICAgICBtZXNzYWdlcy5wdXNoKFxuICAgICAgICAgICAgbmV3IFByaXZhdGVNZXNzYWdlKHtcbiAgICAgICAgICAgICAgY2xpZW50LFxuICAgICAgICAgICAgICBpZDogbWVzc2FnZUlkLFxuICAgICAgICAgICAgICBzZW5kZXIsXG4gICAgICAgICAgICAgIHJlY2lwaWVudCxcbiAgICAgICAgICAgICAgc3ViamVjdCxcbiAgICAgICAgICAgICAgYm9keSxcbiAgICAgICAgICAgICAgY3JlYXRlZEF0LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcml2YXRlTWVzc2FnZUNvbGxlY3Rpb24oY2xpZW50LCBtZXNzYWdlcyk7XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEZvcmJpZGRlbkVycm9yIHx8IGVycm9yIGluc3RhbmNlb2YgTG9naW5SZXF1aXJlZEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gZ2V0IG1lc3NhZ2VzOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg6Ljgrjjg6Xjg7zjg6vjgYvjgonjg6Hjg4Pjgrvjg7zjgrjjgpLlj5blvpfjgZnjgovlhoXpg6jjg6Hjgr3jg4Pjg4lcbiAgICovXG4gIHByb3RlY3RlZCBzdGF0aWMgYWNxdWlyZUZyb21Nb2R1bGUoXG4gICAgY2xpZW50OiBDbGllbnQsXG4gICAgbW9kdWxlTmFtZTogc3RyaW5nXG4gICk6IFdpa2lkb3RSZXN1bHRBc3luYzxQcml2YXRlTWVzc2FnZUNvbGxlY3Rpb24+IHtcbiAgICBjb25zdCBsb2dpblJlc3VsdCA9IGNsaWVudC5yZXF1aXJlTG9naW4oKTtcbiAgICBpZiAobG9naW5SZXN1bHQuaXNFcnIoKSkge1xuICAgICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgICBQcm9taXNlLnJlamVjdChsb2dpblJlc3VsdC5lcnJvciksXG4gICAgICAgICgpID0+IG5ldyBMb2dpblJlcXVpcmVkRXJyb3IoJ0xvZ2luIHJlcXVpcmVkIHRvIGdldCBtZXNzYWdlcycpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBmcm9tUHJvbWlzZShcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIC8vIOODmuODvOOCuOODo+ODvOWPluW+l1xuICAgICAgICBjb25zdCBmaXJzdFJlc3VsdCA9IGF3YWl0IGNsaWVudC5hbWNDbGllbnQucmVxdWVzdChbeyBtb2R1bGVOYW1lIH1dKTtcbiAgICAgICAgaWYgKGZpcnN0UmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyBmaXJzdFJlc3VsdC5lcnJvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZpcnN0UmVzcG9uc2UgPSBmaXJzdFJlc3VsdC52YWx1ZVswXTtcbiAgICAgICAgaWYgKCFmaXJzdFJlc3BvbnNlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE5vRWxlbWVudEVycm9yKCdFbXB0eSByZXNwb25zZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmlyc3RIdG1sID0gU3RyaW5nKGZpcnN0UmVzcG9uc2UuYm9keSA/PyAnJyk7XG4gICAgICAgIGNvbnN0ICRmaXJzdCA9IGNoZWVyaW8ubG9hZChmaXJzdEh0bWwpO1xuXG4gICAgICAgIC8vIOODmuODvOOCuOaVsOOCkuWPluW+l1xuICAgICAgICBjb25zdCBwYWdlclRhcmdldHMgPSAkZmlyc3QoJ2Rpdi5wYWdlciBzcGFuLnRhcmdldCcpO1xuICAgICAgICBsZXQgbWF4UGFnZSA9IDE7XG4gICAgICAgIGlmIChwYWdlclRhcmdldHMubGVuZ3RoID4gMikge1xuICAgICAgICAgIGNvbnN0IGxhc3RQYWdlVGV4dCA9ICRmaXJzdChwYWdlclRhcmdldHNbcGFnZXJUYXJnZXRzLmxlbmd0aCAtIDJdKVxuICAgICAgICAgICAgLnRleHQoKVxuICAgICAgICAgICAgLnRyaW0oKTtcbiAgICAgICAgICBtYXhQYWdlID0gTnVtYmVyLnBhcnNlSW50KGxhc3RQYWdlVGV4dCwgMTApIHx8IDE7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDlhajjg5rjg7zjgrjjgYvjgonjg6Hjg4Pjgrvjg7zjgrhJROOCkuWPluW+l1xuICAgICAgICBjb25zdCBtZXNzYWdlSWRzOiBudW1iZXJbXSA9IFtdO1xuXG4gICAgICAgIGlmIChtYXhQYWdlID4gMSkge1xuICAgICAgICAgIGNvbnN0IGJvZGllcyA9IFtdO1xuICAgICAgICAgIGZvciAobGV0IHBhZ2UgPSAxOyBwYWdlIDw9IG1heFBhZ2U7IHBhZ2UrKykge1xuICAgICAgICAgICAgYm9kaWVzLnB1c2goeyBwYWdlLCBtb2R1bGVOYW1lIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBhZGRpdGlvbmFsUmVzdWx0cyA9IGF3YWl0IGNsaWVudC5hbWNDbGllbnQucmVxdWVzdChib2RpZXMpO1xuICAgICAgICAgIGlmIChhZGRpdGlvbmFsUmVzdWx0cy5pc0VycigpKSB7XG4gICAgICAgICAgICB0aHJvdyBhZGRpdGlvbmFsUmVzdWx0cy5lcnJvcjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IHJlc3BvbnNlIG9mIGFkZGl0aW9uYWxSZXN1bHRzLnZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCBodG1sID0gU3RyaW5nKHJlc3BvbnNlPy5ib2R5ID8/ICcnKTtcbiAgICAgICAgICAgIGNvbnN0ICQgPSBjaGVlcmlvLmxvYWQoaHRtbCk7XG4gICAgICAgICAgICAkKCd0ci5tZXNzYWdlJykuZWFjaCgoX2ksIGVsZW0pID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgZGF0YUhyZWYgPSAkKGVsZW0pLmF0dHIoJ2RhdGEtaHJlZicpID8/ICcnO1xuICAgICAgICAgICAgICBjb25zdCBpZE1hdGNoID0gZGF0YUhyZWYubWF0Y2goL1xcLyhcXGQrKSQvKTtcbiAgICAgICAgICAgICAgaWYgKGlkTWF0Y2g/LlsxXSkge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2VJZHMucHVzaChOdW1iZXIucGFyc2VJbnQoaWRNYXRjaFsxXSwgMTApKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICRmaXJzdCgndHIubWVzc2FnZScpLmVhY2goKF9pLCBlbGVtKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBkYXRhSHJlZiA9ICRmaXJzdChlbGVtKS5hdHRyKCdkYXRhLWhyZWYnKSA/PyAnJztcbiAgICAgICAgICAgIGNvbnN0IGlkTWF0Y2ggPSBkYXRhSHJlZi5tYXRjaCgvXFwvKFxcZCspJC8pO1xuICAgICAgICAgICAgaWYgKGlkTWF0Y2g/LlsxXSkge1xuICAgICAgICAgICAgICBtZXNzYWdlSWRzLnB1c2goTnVtYmVyLnBhcnNlSW50KGlkTWF0Y2hbMV0sIDEwKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDjg6Hjg4Pjgrvjg7zjgrjjgpLlj5blvpdcbiAgICAgICAgY29uc3QgbWVzc2FnZXNSZXN1bHQgPSBhd2FpdCBQcml2YXRlTWVzc2FnZUNvbGxlY3Rpb24uZnJvbUlkcyhjbGllbnQsIG1lc3NhZ2VJZHMpO1xuICAgICAgICBpZiAobWVzc2FnZXNSZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IG1lc3NhZ2VzUmVzdWx0LmVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2VzUmVzdWx0LnZhbHVlO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBGb3JiaWRkZW5FcnJvciB8fFxuICAgICAgICAgIGVycm9yIGluc3RhbmNlb2YgTG9naW5SZXF1aXJlZEVycm9yIHx8XG4gICAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvclxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBVbmV4cGVjdGVkRXJyb3IoYEZhaWxlZCB0byBhY3F1aXJlIG1lc3NhZ2VzOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIOWPl+S/oeeusVxuICovXG5leHBvcnQgY2xhc3MgUHJpdmF0ZU1lc3NhZ2VJbmJveCBleHRlbmRzIFByaXZhdGVNZXNzYWdlQ29sbGVjdGlvbiB7XG4gIC8qKlxuICAgKiDlj5fkv6HnrrHjga7jg6Hjg4Pjgrvjg7zjgrjjgpLjgZnjgbnjgablj5blvpfjgZnjgotcbiAgICovXG4gIHN0YXRpYyBhY3F1aXJlKGNsaWVudDogQ2xpZW50KTogV2lraWRvdFJlc3VsdEFzeW5jPFByaXZhdGVNZXNzYWdlSW5ib3g+IHtcbiAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBQcml2YXRlTWVzc2FnZUNvbGxlY3Rpb24uYWNxdWlyZUZyb21Nb2R1bGUoXG4gICAgICAgICAgY2xpZW50LFxuICAgICAgICAgICdkYXNoYm9hcmQvbWVzc2FnZXMvRE1JbmJveE1vZHVsZSdcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGluYm94ID0gbmV3IFByaXZhdGVNZXNzYWdlSW5ib3goY2xpZW50KTtcbiAgICAgICAgaW5ib3gucHVzaCguLi5yZXN1bHQudmFsdWUpO1xuICAgICAgICByZXR1cm4gaW5ib3g7XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEZvcmJpZGRlbkVycm9yIHx8IGVycm9yIGluc3RhbmNlb2YgTG9naW5SZXF1aXJlZEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gYWNxdWlyZSBpbmJveDogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiDpgIHkv6HnrrFcbiAqL1xuZXhwb3J0IGNsYXNzIFByaXZhdGVNZXNzYWdlU2VudEJveCBleHRlbmRzIFByaXZhdGVNZXNzYWdlQ29sbGVjdGlvbiB7XG4gIC8qKlxuICAgKiDpgIHkv6HnrrHjga7jg6Hjg4Pjgrvjg7zjgrjjgpLjgZnjgbnjgablj5blvpfjgZnjgotcbiAgICovXG4gIHN0YXRpYyBhY3F1aXJlKGNsaWVudDogQ2xpZW50KTogV2lraWRvdFJlc3VsdEFzeW5jPFByaXZhdGVNZXNzYWdlU2VudEJveD4ge1xuICAgIHJldHVybiBmcm9tUHJvbWlzZShcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IFByaXZhdGVNZXNzYWdlQ29sbGVjdGlvbi5hY3F1aXJlRnJvbU1vZHVsZShcbiAgICAgICAgICBjbGllbnQsXG4gICAgICAgICAgJ2Rhc2hib2FyZC9tZXNzYWdlcy9ETVNlbnRNb2R1bGUnXG4gICAgICAgICk7XG4gICAgICAgIGlmIChyZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IHJlc3VsdC5lcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzZW50Qm94ID0gbmV3IFByaXZhdGVNZXNzYWdlU2VudEJveChjbGllbnQpO1xuICAgICAgICBzZW50Qm94LnB1c2goLi4ucmVzdWx0LnZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHNlbnRCb3g7XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEZvcmJpZGRlbkVycm9yIHx8IGVycm9yIGluc3RhbmNlb2YgTG9naW5SZXF1aXJlZEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gYWNxdWlyZSBzZW50IGJveDogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cbn1cbiIsCiAgICAiaW1wb3J0IHR5cGUgeyBXaWtpZG90UmVzdWx0QXN5bmMgfSBmcm9tICcuLi8uLi8uLi9jb21tb24vdHlwZXMnO1xuaW1wb3J0IHtcbiAgUHJpdmF0ZU1lc3NhZ2UsXG4gIFByaXZhdGVNZXNzYWdlQ29sbGVjdGlvbixcbiAgUHJpdmF0ZU1lc3NhZ2VJbmJveCxcbiAgUHJpdmF0ZU1lc3NhZ2VTZW50Qm94LFxufSBmcm9tICcuLi8uLi9wcml2YXRlLW1lc3NhZ2UnO1xuaW1wb3J0IHR5cGUgeyBVc2VyIH0gZnJvbSAnLi4vLi4vdXNlci91c2VyJztcbmltcG9ydCB0eXBlIHsgQ2xpZW50IH0gZnJvbSAnLi4vY2xpZW50JztcblxuLyoqXG4gKiDjg5fjg6njgqTjg5njg7zjg4jjg6Hjg4Pjgrvjg7zjgrjmk43kvZzjgqLjgq/jgrvjgrVcbiAqL1xuZXhwb3J0IGNsYXNzIFByaXZhdGVNZXNzYWdlQWNjZXNzb3Ige1xuICBwdWJsaWMgcmVhZG9ubHkgY2xpZW50OiBDbGllbnQ7XG5cbiAgY29uc3RydWN0b3IoY2xpZW50OiBDbGllbnQpIHtcbiAgICB0aGlzLmNsaWVudCA9IGNsaWVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg6Hjg4Pjgrvjg7zjgrhJROOBi+OCieODoeODg+OCu+ODvOOCuOOCkuWPluW+l+OBmeOCi1xuICAgKiBAcGFyYW0gaWQgLSDjg6Hjg4Pjgrvjg7zjgrhJRFxuICAgKiBAcmV0dXJucyDjg6Hjg4Pjgrvjg7zjgrjjgqrjg5bjgrjjgqfjgq/jg4hcbiAgICovXG4gIGdldChpZDogbnVtYmVyKTogV2lraWRvdFJlc3VsdEFzeW5jPFByaXZhdGVNZXNzYWdlPiB7XG4gICAgcmV0dXJuIFByaXZhdGVNZXNzYWdlLmZyb21JZCh0aGlzLmNsaWVudCwgaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOikh+aVsOOBruODoeODg+OCu+ODvOOCuElE44GL44KJ44Oh44OD44K744O844K444KS5Y+W5b6X44GZ44KLXG4gICAqIEBwYXJhbSBpZHMgLSDjg6Hjg4Pjgrvjg7zjgrhJROmFjeWIl1xuICAgKiBAcmV0dXJucyDjg6Hjg4Pjgrvjg7zjgrjjgrPjg6zjgq/jgrfjg6fjg7NcbiAgICovXG4gIGdldE1lc3NhZ2VzKGlkczogbnVtYmVyW10pOiBXaWtpZG90UmVzdWx0QXN5bmM8UHJpdmF0ZU1lc3NhZ2VDb2xsZWN0aW9uPiB7XG4gICAgcmV0dXJuIFByaXZhdGVNZXNzYWdlQ29sbGVjdGlvbi5mcm9tSWRzKHRoaXMuY2xpZW50LCBpZHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIOWPl+S/oeeuseOBruODoeODg+OCu+ODvOOCuOS4gOimp+OCkuWPluW+l+OBmeOCi1xuICAgKiBAcmV0dXJucyDlj5fkv6HnrrFcbiAgICovXG4gIGluYm94KCk6IFdpa2lkb3RSZXN1bHRBc3luYzxQcml2YXRlTWVzc2FnZUluYm94PiB7XG4gICAgcmV0dXJuIFByaXZhdGVNZXNzYWdlSW5ib3guYWNxdWlyZSh0aGlzLmNsaWVudCk7XG4gIH1cblxuICAvKipcbiAgICog6YCB5L+h566x44Gu44Oh44OD44K744O844K45LiA6Kan44KS5Y+W5b6X44GZ44KLXG4gICAqIEByZXR1cm5zIOmAgeS/oeeusVxuICAgKi9cbiAgc2VudEJveCgpOiBXaWtpZG90UmVzdWx0QXN5bmM8UHJpdmF0ZU1lc3NhZ2VTZW50Qm94PiB7XG4gICAgcmV0dXJuIFByaXZhdGVNZXNzYWdlU2VudEJveC5hY3F1aXJlKHRoaXMuY2xpZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg5fjg6njgqTjg5njg7zjg4jjg6Hjg4Pjgrvjg7zjgrjjgpLpgIHkv6HjgZnjgotcbiAgICogQHBhcmFtIHJlY2lwaWVudCAtIOWPl+S/oeiAhVxuICAgKiBAcGFyYW0gc3ViamVjdCAtIOS7tuWQjVxuICAgKiBAcGFyYW0gYm9keSAtIOacrOaWh1xuICAgKi9cbiAgc2VuZChyZWNpcGllbnQ6IFVzZXIsIHN1YmplY3Q6IHN0cmluZywgYm9keTogc3RyaW5nKTogV2lraWRvdFJlc3VsdEFzeW5jPHZvaWQ+IHtcbiAgICByZXR1cm4gUHJpdmF0ZU1lc3NhZ2Uuc2VuZCh0aGlzLmNsaWVudCwgcmVjaXBpZW50LCBzdWJqZWN0LCBib2R5KTtcbiAgfVxufVxuXG5leHBvcnQgeyBQcml2YXRlTWVzc2FnZSwgUHJpdmF0ZU1lc3NhZ2VDb2xsZWN0aW9uLCBQcml2YXRlTWVzc2FnZUluYm94LCBQcml2YXRlTWVzc2FnZVNlbnRCb3ggfTtcbiIsCiAgICAiaW1wb3J0IHR5cGUgeyBXaWtpZG90UmVzdWx0QXN5bmMgfSBmcm9tICcuLi8uLi8uLi9jb21tb24vdHlwZXMnO1xuaW1wb3J0IHtcbiAgRm9ydW1DYXRlZ29yeSxcbiAgRm9ydW1DYXRlZ29yeUNvbGxlY3Rpb24sXG4gIEZvcnVtUG9zdCxcbiAgRm9ydW1UaHJlYWQsXG4gIEZvcnVtVGhyZWFkQ29sbGVjdGlvbixcbn0gZnJvbSAnLi4vLi4vZm9ydW0nO1xuaW1wb3J0IHR5cGUgeyBTaXRlIH0gZnJvbSAnLi4vc2l0ZSc7XG5cbi8qKlxuICog44OV44Kp44O844Op44Og5pON5L2c44Ki44Kv44K744K1XG4gKi9cbmV4cG9ydCBjbGFzcyBGb3J1bUFjY2Vzc29yIHtcbiAgcHVibGljIHJlYWRvbmx5IHNpdGU6IFNpdGU7XG5cbiAgY29uc3RydWN0b3Ioc2l0ZTogU2l0ZSkge1xuICAgIHRoaXMuc2l0ZSA9IHNpdGU7XG4gIH1cblxuICAvKipcbiAgICog44OV44Kp44O844Op44Og44Kr44OG44K044Oq5LiA6Kan44KS5Y+W5b6XXG4gICAqIEByZXR1cm5zIOOCq+ODhuOCtOODquS4gOimp1xuICAgKi9cbiAgZ2V0Q2F0ZWdvcmllcygpOiBXaWtpZG90UmVzdWx0QXN5bmM8Rm9ydW1DYXRlZ29yeUNvbGxlY3Rpb24+IHtcbiAgICByZXR1cm4gRm9ydW1DYXRlZ29yeUNvbGxlY3Rpb24uYWNxdWlyZUFsbCh0aGlzLnNpdGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIOOCueODrOODg+ODieOCkuWPluW+l1xuICAgKiBAcGFyYW0gdGhyZWFkSWQgLSDjgrnjg6zjg4Pjg4lJRFxuICAgKiBAcmV0dXJucyDjgrnjg6zjg4Pjg4lcbiAgICovXG4gIGdldFRocmVhZCh0aHJlYWRJZDogbnVtYmVyKTogV2lraWRvdFJlc3VsdEFzeW5jPEZvcnVtVGhyZWFkPiB7XG4gICAgcmV0dXJuIEZvcnVtVGhyZWFkLmdldEZyb21JZCh0aGlzLnNpdGUsIHRocmVhZElkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDopIfmlbDjgrnjg6zjg4Pjg4njgpLlj5blvpdcbiAgICogQHBhcmFtIHRocmVhZElkcyAtIOOCueODrOODg+ODiUlE6YWN5YiXXG4gICAqIEByZXR1cm5zIOOCueODrOODg+ODieOCs+ODrOOCr+OCt+ODp+ODs1xuICAgKi9cbiAgZ2V0VGhyZWFkcyh0aHJlYWRJZHM6IG51bWJlcltdKTogV2lraWRvdFJlc3VsdEFzeW5jPEZvcnVtVGhyZWFkQ29sbGVjdGlvbj4ge1xuICAgIHJldHVybiBGb3J1bVRocmVhZENvbGxlY3Rpb24uYWNxdWlyZUZyb21UaHJlYWRJZHModGhpcy5zaXRlLCB0aHJlYWRJZHMpO1xuICB9XG59XG5cbmV4cG9ydCB7IEZvcnVtQ2F0ZWdvcnksIEZvcnVtQ2F0ZWdvcnlDb2xsZWN0aW9uLCBGb3J1bVRocmVhZCwgRm9ydW1UaHJlYWRDb2xsZWN0aW9uLCBGb3J1bVBvc3QgfTtcbiIsCiAgICAiLyoqXG4gKiBRdWlja01vZHVsZSAtIFdpa2lkb3Tou73ph49BUElcbiAqXG4gKiBxdWlja21vZHVsZS5waHDjgqjjg7Pjg4njg53jgqTjg7Pjg4jjgpLkvb/nlKjjgZfjgZ/mpJzntKLmqZ/og71cbiAqL1xuXG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kJztcbmltcG9ydCB7IE5vdEZvdW5kRXhjZXB0aW9uLCBVbmV4cGVjdGVkRXJyb3IgfSBmcm9tICcuLi9jb21tb24vZXJyb3JzJztcbmltcG9ydCB7IGZyb21Qcm9taXNlLCB0eXBlIFdpa2lkb3RSZXN1bHRBc3luYyB9IGZyb20gJy4uL2NvbW1vbi90eXBlcyc7XG5cbi8qKlxuICogUXVpY2tNb2R1bGXjg6Ljgrjjg6Xjg7zjg6vlkI1cbiAqL1xuZXhwb3J0IHR5cGUgUXVpY2tNb2R1bGVOYW1lID0gJ01lbWJlckxvb2t1cFFNb2R1bGUnIHwgJ1VzZXJMb29rdXBRTW9kdWxlJyB8ICdQYWdlTG9va3VwUU1vZHVsZSc7XG5cbi8qKlxuICogUXVpY2tNb2R1bGXjg6bjg7zjgrbjg7zmg4XloLFcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBRTUNVc2VyIHtcbiAgaWQ6IG51bWJlcjtcbiAgbmFtZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIFF1aWNrTW9kdWxl44Oa44O844K45oOF5aCxXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUU1DUGFnZSB7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIHVuaXhOYW1lOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUXVpY2tNb2R1bGXjg6zjgrnjg53jg7Pjgrnjgrnjgq3jg7zjg55cbiAqL1xuY29uc3QgcXVpY2tNb2R1bGVVc2VyUmVzcG9uc2VTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIHVzZXJzOiB6LnVuaW9uKFtcbiAgICB6LmFycmF5KFxuICAgICAgei5vYmplY3Qoe1xuICAgICAgICB1c2VyX2lkOiB6LnVuaW9uKFt6LnN0cmluZygpLCB6Lm51bWJlcigpXSksXG4gICAgICAgIG5hbWU6IHouc3RyaW5nKCksXG4gICAgICB9KVxuICAgICksXG4gICAgei5saXRlcmFsKGZhbHNlKSxcbiAgXSksXG59KTtcblxuY29uc3QgcXVpY2tNb2R1bGVQYWdlUmVzcG9uc2VTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIHBhZ2VzOiB6LnVuaW9uKFtcbiAgICB6LmFycmF5KFxuICAgICAgei5vYmplY3Qoe1xuICAgICAgICB0aXRsZTogei5zdHJpbmcoKSxcbiAgICAgICAgdW5peF9uYW1lOiB6LnN0cmluZygpLFxuICAgICAgfSlcbiAgICApLFxuICAgIHoubGl0ZXJhbChmYWxzZSksXG4gIF0pLFxufSk7XG5cbi8qKlxuICogUXVpY2tNb2R1bGXjgqjjg7Pjg4njg53jgqTjg7Pjg4jjgavjg6rjgq/jgqjjgrnjg4jjgpLpgIHkv6FcbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVxdWVzdFF1aWNrTW9kdWxlKFxuICBtb2R1bGVOYW1lOiBRdWlja01vZHVsZU5hbWUsXG4gIHNpdGVJZDogbnVtYmVyLFxuICBxdWVyeTogc3RyaW5nXG4pOiBQcm9taXNlPHVua25vd24+IHtcbiAgY29uc3QgdXJsID0gYGh0dHBzOi8vd3d3Lndpa2lkb3QuY29tL3F1aWNrbW9kdWxlLnBocD9tb2R1bGU9JHttb2R1bGVOYW1lfSZzPSR7c2l0ZUlkfSZxPSR7ZW5jb2RlVVJJQ29tcG9uZW50KHF1ZXJ5KX1gO1xuXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsLCB7XG4gICAgbWV0aG9kOiAnR0VUJyxcbiAgICBoZWFkZXJzOiB7XG4gICAgICBBY2NlcHQ6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICB9LFxuICB9KTtcblxuICBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSA1MDApIHtcbiAgICB0aHJvdyBuZXcgTm90Rm91bmRFeGNlcHRpb24oYFNpdGUgbm90IGZvdW5kOiBzaXRlSWQ9JHtzaXRlSWR9YCk7XG4gIH1cblxuICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRFcnJvcihgUXVpY2tNb2R1bGUgcmVxdWVzdCBmYWlsZWQ6ICR7cmVzcG9uc2Uuc3RhdHVzfWApO1xuICB9XG5cbiAgcmV0dXJuIHJlc3BvbnNlLmpzb24oKTtcbn1cblxuLyoqXG4gKiDjgrXjgqTjg4jjg6Hjg7Pjg5Djg7zjgpLmpJzntKJcbiAqIEBwYXJhbSBzaXRlSWQgLSDjgrXjgqTjg4hJRFxuICogQHBhcmFtIHF1ZXJ5IC0g5qSc57Si44Kv44Ko44Oq77yI44Om44O844K244O85ZCN44Gu5LiA6YOo77yJXG4gKiBAcmV0dXJucyDjg57jg4Pjg4HjgZfjgZ/jg6bjg7zjgrbjg7zkuIDopqdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lbWJlckxvb2t1cChzaXRlSWQ6IG51bWJlciwgcXVlcnk6IHN0cmluZyk6IFdpa2lkb3RSZXN1bHRBc3luYzxRTUNVc2VyW10+IHtcbiAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgIChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVxdWVzdFF1aWNrTW9kdWxlKCdNZW1iZXJMb29rdXBRTW9kdWxlJywgc2l0ZUlkLCBxdWVyeSk7XG4gICAgICBjb25zdCBwYXJzZWQgPSBxdWlja01vZHVsZVVzZXJSZXNwb25zZVNjaGVtYS5wYXJzZShkYXRhKTtcblxuICAgICAgaWYgKHBhcnNlZC51c2VycyA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcGFyc2VkLnVzZXJzLm1hcCgodXNlcikgPT4gKHtcbiAgICAgICAgaWQ6IHR5cGVvZiB1c2VyLnVzZXJfaWQgPT09ICdzdHJpbmcnID8gTnVtYmVyLnBhcnNlSW50KHVzZXIudXNlcl9pZCwgMTApIDogdXNlci51c2VyX2lkLFxuICAgICAgICBuYW1lOiB1c2VyLm5hbWUsXG4gICAgICB9KSk7XG4gICAgfSkoKSxcbiAgICAoZXJyb3IpID0+IHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIE5vdEZvdW5kRXhjZXB0aW9uKSByZXR1cm4gZXJyb3I7XG4gICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgTWVtYmVyIGxvb2t1cCBmYWlsZWQ6ICR7U3RyaW5nKGVycm9yKX1gKTtcbiAgICB9XG4gICk7XG59XG5cbi8qKlxuICogV2lraWRvdOWFqOS9k+OBi+OCieODpuODvOOCtuODvOOCkuaknOe0olxuICogQHBhcmFtIHNpdGVJZCAtIOOCteOCpOODiElE77yI5Lu75oSP44Gu44K144Kk44OISUTjgaflj6/vvIlcbiAqIEBwYXJhbSBxdWVyeSAtIOaknOe0ouOCr+OCqOODqu+8iOODpuODvOOCtuODvOWQjeOBruS4gOmDqO+8iVxuICogQHJldHVybnMg44Oe44OD44OB44GX44Gf44Om44O844K244O85LiA6KanXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VyTG9va3VwKHNpdGVJZDogbnVtYmVyLCBxdWVyeTogc3RyaW5nKTogV2lraWRvdFJlc3VsdEFzeW5jPFFNQ1VzZXJbXT4ge1xuICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXF1ZXN0UXVpY2tNb2R1bGUoJ1VzZXJMb29rdXBRTW9kdWxlJywgc2l0ZUlkLCBxdWVyeSk7XG4gICAgICBjb25zdCBwYXJzZWQgPSBxdWlja01vZHVsZVVzZXJSZXNwb25zZVNjaGVtYS5wYXJzZShkYXRhKTtcblxuICAgICAgaWYgKHBhcnNlZC51c2VycyA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcGFyc2VkLnVzZXJzLm1hcCgodXNlcikgPT4gKHtcbiAgICAgICAgaWQ6IHR5cGVvZiB1c2VyLnVzZXJfaWQgPT09ICdzdHJpbmcnID8gTnVtYmVyLnBhcnNlSW50KHVzZXIudXNlcl9pZCwgMTApIDogdXNlci51c2VyX2lkLFxuICAgICAgICBuYW1lOiB1c2VyLm5hbWUsXG4gICAgICB9KSk7XG4gICAgfSkoKSxcbiAgICAoZXJyb3IpID0+IHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIE5vdEZvdW5kRXhjZXB0aW9uKSByZXR1cm4gZXJyb3I7XG4gICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgVXNlciBsb29rdXAgZmFpbGVkOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgfVxuICApO1xufVxuXG4vKipcbiAqIOOCteOCpOODiOWGheOBruODmuODvOOCuOOCkuaknOe0olxuICogQHBhcmFtIHNpdGVJZCAtIOOCteOCpOODiElEXG4gKiBAcGFyYW0gcXVlcnkgLSDmpJzntKLjgq/jgqjjg6rvvIjjg5rjg7zjgrjlkI3jga7kuIDpg6jvvIlcbiAqIEByZXR1cm5zIOODnuODg+ODgeOBl+OBn+ODmuODvOOCuOS4gOimp1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGFnZUxvb2t1cChzaXRlSWQ6IG51bWJlciwgcXVlcnk6IHN0cmluZyk6IFdpa2lkb3RSZXN1bHRBc3luYzxRTUNQYWdlW10+IHtcbiAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgIChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVxdWVzdFF1aWNrTW9kdWxlKCdQYWdlTG9va3VwUU1vZHVsZScsIHNpdGVJZCwgcXVlcnkpO1xuICAgICAgY29uc3QgcGFyc2VkID0gcXVpY2tNb2R1bGVQYWdlUmVzcG9uc2VTY2hlbWEucGFyc2UoZGF0YSk7XG5cbiAgICAgIGlmIChwYXJzZWQucGFnZXMgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHBhcnNlZC5wYWdlcy5tYXAoKHBhZ2UpID0+ICh7XG4gICAgICAgIHRpdGxlOiBwYWdlLnRpdGxlLFxuICAgICAgICB1bml4TmFtZTogcGFnZS51bml4X25hbWUsXG4gICAgICB9KSk7XG4gICAgfSkoKSxcbiAgICAoZXJyb3IpID0+IHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIE5vdEZvdW5kRXhjZXB0aW9uKSByZXR1cm4gZXJyb3I7XG4gICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgUGFnZSBsb29rdXAgZmFpbGVkOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgfVxuICApO1xufVxuXG4vKipcbiAqIFF1aWNrTW9kdWxlIEFQSe+8iOW+jOaWueS6kuaPm+aAp+OBruOBn+OCgee2reaMge+8iVxuICogQGRlcHJlY2F0ZWQg5Luj44KP44KK44Gr5YCL5Yil44Gu6Zai5pWw77yIbWVtYmVyTG9va3VwLCB1c2VyTG9va3VwLCBwYWdlTG9va3Vw77yJ44KS5L2/55So44GX44Gm44GP44Gg44GV44GEXG4gKi9cbmV4cG9ydCBjb25zdCBRdWlja01vZHVsZToge1xuICBtZW1iZXJMb29rdXA6IHR5cGVvZiBtZW1iZXJMb29rdXA7XG4gIHVzZXJMb29rdXA6IHR5cGVvZiB1c2VyTG9va3VwO1xuICBwYWdlTG9va3VwOiB0eXBlb2YgcGFnZUxvb2t1cDtcbn0gPSB7XG4gIG1lbWJlckxvb2t1cDogbWVtYmVyTG9va3VwLFxuICB1c2VyTG9va3VwOiB1c2VyTG9va3VwLFxuICBwYWdlTG9va3VwOiBwYWdlTG9va3VwLFxufTtcbiIsCiAgICAiaW1wb3J0ICogYXMgY2hlZXJpbyBmcm9tICdjaGVlcmlvJztcbmltcG9ydCB7IFJlcXVpcmVMb2dpbiB9IGZyb20gJy4uLy4uL2NvbW1vbi9kZWNvcmF0b3JzJztcbmltcG9ydCB7XG4gIEZvcmJpZGRlbkVycm9yLFxuICBMb2dpblJlcXVpcmVkRXJyb3IsXG4gIE5vdEZvdW5kRXhjZXB0aW9uLFxuICBVbmV4cGVjdGVkRXJyb3IsXG4gIFdpa2lkb3RTdGF0dXNFcnJvcixcbn0gZnJvbSAnLi4vLi4vY29tbW9uL2Vycm9ycyc7XG5pbXBvcnQgeyBmcm9tUHJvbWlzZSwgdHlwZSBXaWtpZG90UmVzdWx0QXN5bmMgfSBmcm9tICcuLi8uLi9jb21tb24vdHlwZXMnO1xuaW1wb3J0IHsgcGFyc2VVc2VyIH0gZnJvbSAnLi4vLi4vdXRpbC9wYXJzZXInO1xuaW1wb3J0IHR5cGUgeyBBYnN0cmFjdFVzZXIgfSBmcm9tICcuLi91c2VyJztcbmltcG9ydCB0eXBlIHsgU2l0ZSB9IGZyb20gJy4vc2l0ZSc7XG5cbi8qKlxuICog44K144Kk44OI5Y+C5Yqg55Sz6KuL44OH44O844K/XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2l0ZUFwcGxpY2F0aW9uRGF0YSB7XG4gIHNpdGU6IFNpdGU7XG4gIHVzZXI6IEFic3RyYWN0VXNlcjtcbiAgdGV4dDogc3RyaW5nO1xufVxuXG4vKipcbiAqIOOCteOCpOODiOWPguWKoOeUs+iri1xuICovXG5leHBvcnQgY2xhc3MgU2l0ZUFwcGxpY2F0aW9uIHtcbiAgcHVibGljIHJlYWRvbmx5IHNpdGU6IFNpdGU7XG4gIHB1YmxpYyByZWFkb25seSB1c2VyOiBBYnN0cmFjdFVzZXI7XG4gIHB1YmxpYyByZWFkb25seSB0ZXh0OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoZGF0YTogU2l0ZUFwcGxpY2F0aW9uRGF0YSkge1xuICAgIHRoaXMuc2l0ZSA9IGRhdGEuc2l0ZTtcbiAgICB0aGlzLnVzZXIgPSBkYXRhLnVzZXI7XG4gICAgdGhpcy50ZXh0ID0gZGF0YS50ZXh0O1xuICB9XG5cbiAgLyoqXG4gICAqIOacquWHpueQhuOBruWPguWKoOeUs+iri+OCkuOBmeOBueOBpuWPluW+l+OBmeOCi1xuICAgKiBAcGFyYW0gc2l0ZSAtIOWvvuixoeOCteOCpOODiFxuICAgKi9cbiAgc3RhdGljIGFjcXVpcmVBbGwoc2l0ZTogU2l0ZSk6IFdpa2lkb3RSZXN1bHRBc3luYzxTaXRlQXBwbGljYXRpb25bXT4ge1xuICAgIGNvbnN0IGxvZ2luUmVzdWx0ID0gc2l0ZS5jbGllbnQucmVxdWlyZUxvZ2luKCk7XG4gICAgaWYgKGxvZ2luUmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgIHJldHVybiBmcm9tUHJvbWlzZShcbiAgICAgICAgUHJvbWlzZS5yZWplY3QobG9naW5SZXN1bHQuZXJyb3IpLFxuICAgICAgICAoKSA9PiBuZXcgTG9naW5SZXF1aXJlZEVycm9yKCdMb2dpbiByZXF1aXJlZCB0byBnZXQgYXBwbGljYXRpb25zJylcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2l0ZS5hbWNSZXF1ZXN0KFtcbiAgICAgICAgICB7IG1vZHVsZU5hbWU6ICdtYW5hZ2VzaXRlL01hbmFnZVNpdGVNZW1iZXJzQXBwbGljYXRpb25zTW9kdWxlJyB9LFxuICAgICAgICBdKTtcblxuICAgICAgICBpZiAocmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IHJlc3VsdC52YWx1ZVswXTtcbiAgICAgICAgaWYgKCFyZXNwb25zZSkge1xuICAgICAgICAgIHRocm93IG5ldyBVbmV4cGVjdGVkRXJyb3IoJ0VtcHR5IHJlc3BvbnNlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBodG1sID0gU3RyaW5nKHJlc3BvbnNlLmJvZHkgPz8gJycpO1xuXG4gICAgICAgIC8vIOaoqemZkOODgeOCp+ODg+OCr1xuICAgICAgICBpZiAoaHRtbC5pbmNsdWRlcygnV0lLSURPVC5wYWdlLmxpc3RlbmVycy5sb2dpbkNsaWNrKGV2ZW50KScpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEZvcmJpZGRlbkVycm9yKCdZb3UgYXJlIG5vdCBhbGxvd2VkIHRvIGFjY2VzcyB0aGlzIHBhZ2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0ICQgPSBjaGVlcmlvLmxvYWQoaHRtbCk7XG4gICAgICAgIGNvbnN0IGFwcGxpY2F0aW9uczogU2l0ZUFwcGxpY2F0aW9uW10gPSBbXTtcblxuICAgICAgICBjb25zdCB1c2VyRWxlbWVudHMgPSAkKCdoMyBzcGFuLnByaW50dXNlcicpLnRvQXJyYXkoKTtcbiAgICAgICAgY29uc3QgdGV4dFdyYXBwZXJFbGVtZW50cyA9ICQoJ3RhYmxlJykudG9BcnJheSgpO1xuXG4gICAgICAgIGlmICh1c2VyRWxlbWVudHMubGVuZ3RoICE9PSB0ZXh0V3JhcHBlckVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBVbmV4cGVjdGVkRXJyb3IoXG4gICAgICAgICAgICAnTGVuZ3RoIG9mIHVzZXJfZWxlbWVudHMgYW5kIHRleHRfd3JhcHBlcl9lbGVtZW50cyBhcmUgZGlmZmVyZW50J1xuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHVzZXJFbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IHVzZXJFbGVtZW50ID0gdXNlckVsZW1lbnRzW2ldO1xuICAgICAgICAgIGNvbnN0IHRleHRXcmFwcGVyRWxlbWVudCA9IHRleHRXcmFwcGVyRWxlbWVudHNbaV07XG5cbiAgICAgICAgICBpZiAoIXVzZXJFbGVtZW50IHx8ICF0ZXh0V3JhcHBlckVsZW1lbnQpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgY29uc3QgdXNlciA9IHBhcnNlVXNlcihzaXRlLmNsaWVudCwgJCh1c2VyRWxlbWVudCkpO1xuICAgICAgICAgIGNvbnN0IHRleHRFbGVtZW50ID0gJCh0ZXh0V3JhcHBlckVsZW1lbnQpLmZpbmQoJ3RkJykuZXEoMSk7XG4gICAgICAgICAgY29uc3QgdGV4dCA9IHRleHRFbGVtZW50LnRleHQoKS50cmltKCk7XG5cbiAgICAgICAgICBhcHBsaWNhdGlvbnMucHVzaChuZXcgU2l0ZUFwcGxpY2F0aW9uKHsgc2l0ZSwgdXNlciwgdGV4dCB9KSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXBwbGljYXRpb25zO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBGb3JiaWRkZW5FcnJvciB8fCBlcnJvciBpbnN0YW5jZW9mIExvZ2luUmVxdWlyZWRFcnJvcikge1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGdldCBhcHBsaWNhdGlvbnM6ICR7U3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIOeUs+iri+OCkuWHpueQhuOBmeOCi+WGhemDqOODoeOCveODg+ODiVxuICAgKi9cbiAgQFJlcXVpcmVMb2dpblxuICBwcml2YXRlIHByb2Nlc3MoYWN0aW9uOiAnYWNjZXB0JyB8ICdkZWNsaW5lJyk6IFdpa2lkb3RSZXN1bHRBc3luYzx2b2lkPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5zaXRlLmFtY1JlcXVlc3QoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFjdGlvbjogJ01hbmFnZVNpdGVNZW1iZXJzaGlwQWN0aW9uJyxcbiAgICAgICAgICAgIGV2ZW50OiAnYWNjZXB0QXBwbGljYXRpb24nLFxuICAgICAgICAgICAgdXNlcl9pZDogdGhpcy51c2VyLmlkLFxuICAgICAgICAgICAgdGV4dDogYHlvdXIgYXBwbGljYXRpb24gaGFzIGJlZW4gJHthY3Rpb259ZWRgLFxuICAgICAgICAgICAgdHlwZTogYWN0aW9uLFxuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ0VtcHR5JyxcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgY29uc3QgZXJyb3IgPSByZXN1bHQuZXJyb3I7XG4gICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgV2lraWRvdFN0YXR1c0Vycm9yICYmIGVycm9yLnN0YXR1c0NvZGUgPT09ICdub19hcHBsaWNhdGlvbicpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbihgQXBwbGljYXRpb24gbm90IGZvdW5kOiAke3RoaXMudXNlci5uYW1lfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb3RGb3VuZEV4Y2VwdGlvbiB8fCBlcnJvciBpbnN0YW5jZW9mIExvZ2luUmVxdWlyZWRFcnJvcikge1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIHByb2Nlc3MgYXBwbGljYXRpb246ICR7U3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIOWPguWKoOeUs+iri+OCkuaJv+iqjeOBmeOCi1xuICAgKi9cbiAgYWNjZXB0KCk6IFdpa2lkb3RSZXN1bHRBc3luYzx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMucHJvY2VzcygnYWNjZXB0Jyk7XG4gIH1cblxuICAvKipcbiAgICog5Y+C5Yqg55Sz6KuL44KS5ouS5ZCm44GZ44KLXG4gICAqL1xuICBkZWNsaW5lKCk6IFdpa2lkb3RSZXN1bHRBc3luYzx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMucHJvY2VzcygnZGVjbGluZScpO1xuICB9XG5cbiAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYFNpdGVBcHBsaWNhdGlvbih1c2VyPSR7dGhpcy51c2VyLm5hbWV9LCBzaXRlPSR7dGhpcy5zaXRlLnVuaXhOYW1lfSwgdGV4dD0ke3RoaXMudGV4dH0pYDtcbiAgfVxufVxuIiwKICAgICJpbXBvcnQgKiBhcyBjaGVlcmlvIGZyb20gJ2NoZWVyaW8nO1xuaW1wb3J0IHsgUmVxdWlyZUxvZ2luIH0gZnJvbSAnLi4vLi4vY29tbW9uL2RlY29yYXRvcnMnO1xuaW1wb3J0IHtcbiAgTG9naW5SZXF1aXJlZEVycm9yLFxuICBUYXJnZXRFcnJvcixcbiAgVW5leHBlY3RlZEVycm9yLFxuICBXaWtpZG90U3RhdHVzRXJyb3IsXG59IGZyb20gJy4uLy4uL2NvbW1vbi9lcnJvcnMnO1xuaW1wb3J0IHsgZnJvbVByb21pc2UsIHR5cGUgV2lraWRvdFJlc3VsdEFzeW5jIH0gZnJvbSAnLi4vLi4vY29tbW9uL3R5cGVzJztcbmltcG9ydCB7IHBhcnNlT2RhdGUsIHBhcnNlVXNlciB9IGZyb20gJy4uLy4uL3V0aWwvcGFyc2VyJztcbmltcG9ydCB0eXBlIHsgQWJzdHJhY3RVc2VyIH0gZnJvbSAnLi4vdXNlcic7XG5pbXBvcnQgdHlwZSB7IFNpdGUgfSBmcm9tICcuL3NpdGUnO1xuXG4vKipcbiAqIOOCteOCpOODiOODoeODs+ODkOODvOODh+ODvOOCv1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNpdGVNZW1iZXJEYXRhIHtcbiAgc2l0ZTogU2l0ZTtcbiAgdXNlcjogQWJzdHJhY3RVc2VyO1xuICBqb2luZWRBdDogRGF0ZSB8IG51bGw7XG59XG5cbi8qKlxuICog44K144Kk44OI44Oh44Oz44OQ44O8XG4gKi9cbmV4cG9ydCBjbGFzcyBTaXRlTWVtYmVyIHtcbiAgcHVibGljIHJlYWRvbmx5IHNpdGU6IFNpdGU7XG4gIHB1YmxpYyByZWFkb25seSB1c2VyOiBBYnN0cmFjdFVzZXI7XG4gIHB1YmxpYyByZWFkb25seSBqb2luZWRBdDogRGF0ZSB8IG51bGw7XG5cbiAgY29uc3RydWN0b3IoZGF0YTogU2l0ZU1lbWJlckRhdGEpIHtcbiAgICB0aGlzLnNpdGUgPSBkYXRhLnNpdGU7XG4gICAgdGhpcy51c2VyID0gZGF0YS51c2VyO1xuICAgIHRoaXMuam9pbmVkQXQgPSBkYXRhLmpvaW5lZEF0O1xuICB9XG5cbiAgLyoqXG4gICAqIEhUTUzjgYvjgonjg6Hjg7Pjg5Djg7zmg4XloLHjgpLjg5Hjg7zjgrnjgZnjgotcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHBhcnNlKHNpdGU6IFNpdGUsIGh0bWw6IHN0cmluZyk6IFNpdGVNZW1iZXJbXSB7XG4gICAgY29uc3QgJCA9IGNoZWVyaW8ubG9hZChodG1sKTtcbiAgICBjb25zdCBtZW1iZXJzOiBTaXRlTWVtYmVyW10gPSBbXTtcblxuICAgICQoJ3RhYmxlIHRyJykuZWFjaCgoX2ksIHJvdykgPT4ge1xuICAgICAgY29uc3QgdGRzID0gJChyb3cpLmZpbmQoJ3RkJyk7XG4gICAgICBjb25zdCB1c2VyRWxlbSA9ICQodGRzWzBdKS5maW5kKCcucHJpbnR1c2VyJyk7XG5cbiAgICAgIGlmICh1c2VyRWxlbS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB1c2VyID0gcGFyc2VVc2VyKHNpdGUuY2xpZW50LCB1c2VyRWxlbSk7XG5cbiAgICAgIC8vIDLjgaTnm67jga50ZOOBjOOBguOCjOOBsOWKoOWFpeaXpeaZglxuICAgICAgbGV0IGpvaW5lZEF0OiBEYXRlIHwgbnVsbCA9IG51bGw7XG4gICAgICBpZiAodGRzLmxlbmd0aCA+PSAyKSB7XG4gICAgICAgIGNvbnN0IG9kYXRlRWxlbSA9ICQodGRzWzFdKS5maW5kKCcub2RhdGUnKTtcbiAgICAgICAgaWYgKG9kYXRlRWxlbS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgam9pbmVkQXQgPSBwYXJzZU9kYXRlKG9kYXRlRWxlbSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbWVtYmVycy5wdXNoKG5ldyBTaXRlTWVtYmVyKHsgc2l0ZSwgdXNlciwgam9pbmVkQXQgfSkpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIG1lbWJlcnM7XG4gIH1cblxuICAvKipcbiAgICog44K144Kk44OI44Oh44Oz44OQ44O85LiA6Kan44KS5Y+W5b6X44GZ44KLXG4gICAqIEBwYXJhbSBzaXRlIC0g5a++6LGh44K144Kk44OIXG4gICAqIEBwYXJhbSBncm91cCAtIOOCsOODq+ODvOODl++8iFwiYWRtaW5zXCIsIFwibW9kZXJhdG9yc1wiLCDjgb7jgZ/jga/nqbrmloflrZfjgaflhajjg6Hjg7Pjg5Djg7zvvIlcbiAgICovXG4gIHN0YXRpYyBnZXRNZW1iZXJzKFxuICAgIHNpdGU6IFNpdGUsXG4gICAgZ3JvdXA6ICdhZG1pbnMnIHwgJ21vZGVyYXRvcnMnIHwgJycgPSAnJ1xuICApOiBXaWtpZG90UmVzdWx0QXN5bmM8U2l0ZU1lbWJlcltdPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgbWVtYmVyczogU2l0ZU1lbWJlcltdID0gW107XG5cbiAgICAgICAgLy8g5pyA5Yid44Gu44Oa44O844K444KS5Y+W5b6XXG4gICAgICAgIGNvbnN0IGZpcnN0UmVzdWx0ID0gYXdhaXQgc2l0ZS5hbWNSZXF1ZXN0KFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtb2R1bGVOYW1lOiAnbWVtYmVyc2hpcC9NZW1iZXJzTGlzdE1vZHVsZScsXG4gICAgICAgICAgICBwYWdlOiAxLFxuICAgICAgICAgICAgZ3JvdXAsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKGZpcnN0UmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyBmaXJzdFJlc3VsdC5lcnJvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZpcnN0UmVzcG9uc2UgPSBmaXJzdFJlc3VsdC52YWx1ZVswXTtcbiAgICAgICAgaWYgKCFmaXJzdFJlc3BvbnNlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRFcnJvcignRW1wdHkgcmVzcG9uc2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZpcnN0SHRtbCA9IFN0cmluZyhmaXJzdFJlc3BvbnNlLmJvZHkgPz8gJycpO1xuICAgICAgICBtZW1iZXJzLnB1c2goLi4uU2l0ZU1lbWJlci5wYXJzZShzaXRlLCBmaXJzdEh0bWwpKTtcblxuICAgICAgICAvLyDjg5rjg7zjgrjjg6Pjg7zjgpLnorroqo1cbiAgICAgICAgY29uc3QgJGZpcnN0ID0gY2hlZXJpby5sb2FkKGZpcnN0SHRtbCk7XG4gICAgICAgIGNvbnN0IHBhZ2VyTGlua3MgPSAkZmlyc3QoJ2Rpdi5wYWdlciBhJyk7XG4gICAgICAgIGlmIChwYWdlckxpbmtzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICByZXR1cm4gbWVtYmVycztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxhc3RQYWdlVGV4dCA9ICRmaXJzdChwYWdlckxpbmtzW3BhZ2VyTGlua3MubGVuZ3RoIC0gMl0pXG4gICAgICAgICAgLnRleHQoKVxuICAgICAgICAgIC50cmltKCk7XG4gICAgICAgIGNvbnN0IGxhc3RQYWdlID0gTnVtYmVyLnBhcnNlSW50KGxhc3RQYWdlVGV4dCwgMTApIHx8IDE7XG4gICAgICAgIGlmIChsYXN0UGFnZSA8PSAxKSB7XG4gICAgICAgICAgcmV0dXJuIG1lbWJlcnM7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDmrovjgorjga7jg5rjg7zjgrjjgpLlj5blvpdcbiAgICAgICAgY29uc3QgYm9kaWVzID0gW107XG4gICAgICAgIGZvciAobGV0IHBhZ2UgPSAyOyBwYWdlIDw9IGxhc3RQYWdlOyBwYWdlKyspIHtcbiAgICAgICAgICBib2RpZXMucHVzaCh7XG4gICAgICAgICAgICBtb2R1bGVOYW1lOiAnbWVtYmVyc2hpcC9NZW1iZXJzTGlzdE1vZHVsZScsXG4gICAgICAgICAgICBwYWdlLFxuICAgICAgICAgICAgZ3JvdXAsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhZGRpdGlvbmFsUmVzdWx0cyA9IGF3YWl0IHNpdGUuYW1jUmVxdWVzdChib2RpZXMpO1xuICAgICAgICBpZiAoYWRkaXRpb25hbFJlc3VsdHMuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IGFkZGl0aW9uYWxSZXN1bHRzLmVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCByZXNwb25zZSBvZiBhZGRpdGlvbmFsUmVzdWx0cy52YWx1ZSkge1xuICAgICAgICAgIGNvbnN0IGh0bWwgPSBTdHJpbmcocmVzcG9uc2U/LmJvZHkgPz8gJycpO1xuICAgICAgICAgIG1lbWJlcnMucHVzaCguLi5TaXRlTWVtYmVyLnBhcnNlKHNpdGUsIGh0bWwpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtZW1iZXJzO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGdldCBtZW1iZXJzOiAke1N0cmluZyhlcnJvcil9YClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIOOCsOODq+ODvOODl+WkieabtOOBruWGhemDqOODoeOCveODg+ODiVxuICAgKi9cbiAgQFJlcXVpcmVMb2dpblxuICBwcml2YXRlIGNoYW5nZUdyb3VwKFxuICAgIGV2ZW50OiAndG9Nb2RlcmF0b3JzJyB8ICdyZW1vdmVNb2RlcmF0b3InIHwgJ3RvQWRtaW5zJyB8ICdyZW1vdmVBZG1pbidcbiAgKTogV2lraWRvdFJlc3VsdEFzeW5jPHZvaWQ+IHtcbiAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnNpdGUuYW1jUmVxdWVzdChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWN0aW9uOiAnTWFuYWdlU2l0ZU1lbWJlcnNoaXBBY3Rpb24nLFxuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICB1c2VyX2lkOiB0aGlzLnVzZXIuaWQsXG4gICAgICAgICAgICBtb2R1bGVOYW1lOiAnJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgY29uc3QgZXJyb3IgPSByZXN1bHQuZXJyb3I7XG4gICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgV2lraWRvdFN0YXR1c0Vycm9yKSB7XG4gICAgICAgICAgICBpZiAoZXJyb3Iuc3RhdHVzQ29kZSA9PT0gJ25vdF9hbHJlYWR5Jykge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgVGFyZ2V0RXJyb3IoYFVzZXIgaXMgbm90IG1vZGVyYXRvci9hZG1pbjogJHt0aGlzLnVzZXIubmFtZX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChlcnJvci5zdGF0dXNDb2RlID09PSAnYWxyZWFkeV9hZG1pbicgfHwgZXJyb3Iuc3RhdHVzQ29kZSA9PT0gJ2FscmVhZHlfbW9kZXJhdG9yJykge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgVGFyZ2V0RXJyb3IoXG4gICAgICAgICAgICAgICAgYFVzZXIgaXMgYWxyZWFkeSAke2Vycm9yLnN0YXR1c0NvZGUucmVwbGFjZSgnYWxyZWFkeV8nLCAnJyl9OiAke3RoaXMudXNlci5uYW1lfWBcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0pKCksXG4gICAgICAoZXJyb3IpID0+IHtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgVGFyZ2V0RXJyb3IgfHwgZXJyb3IgaW5zdGFuY2VvZiBMb2dpblJlcXVpcmVkRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBVbmV4cGVjdGVkRXJyb3IoYEZhaWxlZCB0byBjaGFuZ2UgbWVtYmVyIGdyb3VwOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg6Ljg4fjg6zjg7zjgr/jg7zjgavmmIfmoLxcbiAgICovXG4gIHRvTW9kZXJhdG9yKCk6IFdpa2lkb3RSZXN1bHRBc3luYzx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuY2hhbmdlR3JvdXAoJ3RvTW9kZXJhdG9ycycpO1xuICB9XG5cbiAgLyoqXG4gICAqIOODouODh+ODrOODvOOCv+ODvOaoqemZkOOCkuWJiumZpFxuICAgKi9cbiAgcmVtb3ZlTW9kZXJhdG9yKCk6IFdpa2lkb3RSZXN1bHRBc3luYzx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuY2hhbmdlR3JvdXAoJ3JlbW92ZU1vZGVyYXRvcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIOeuoeeQhuiAheOBq+aYh+agvFxuICAgKi9cbiAgdG9BZG1pbigpOiBXaWtpZG90UmVzdWx0QXN5bmM8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmNoYW5nZUdyb3VwKCd0b0FkbWlucycpO1xuICB9XG5cbiAgLyoqXG4gICAqIOeuoeeQhuiAheaoqemZkOOCkuWJiumZpFxuICAgKi9cbiAgcmVtb3ZlQWRtaW4oKTogV2lraWRvdFJlc3VsdEFzeW5jPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5jaGFuZ2VHcm91cCgncmVtb3ZlQWRtaW4nKTtcbiAgfVxuXG4gIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGBTaXRlTWVtYmVyKHVzZXI9JHt0aGlzLnVzZXIubmFtZX0sIHNpdGU9JHt0aGlzLnNpdGUudW5peE5hbWV9KWA7XG4gIH1cbn1cbiIsCiAgICAiaW1wb3J0IHsgUmVxdWlyZUxvZ2luIH0gZnJvbSAnLi4vLi4vLi4vY29tbW9uL2RlY29yYXRvcnMnO1xuaW1wb3J0IHtcbiAgTG9naW5SZXF1aXJlZEVycm9yLFxuICBUYXJnZXRFcnJvcixcbiAgVW5leHBlY3RlZEVycm9yLFxuICBXaWtpZG90U3RhdHVzRXJyb3IsXG59IGZyb20gJy4uLy4uLy4uL2NvbW1vbi9lcnJvcnMnO1xuaW1wb3J0IHsgZnJvbVByb21pc2UsIHR5cGUgV2lraWRvdFJlc3VsdEFzeW5jIH0gZnJvbSAnLi4vLi4vLi4vY29tbW9uL3R5cGVzJztcbmltcG9ydCB7IHR5cGUgUU1DVXNlciwgUXVpY2tNb2R1bGUgfSBmcm9tICcuLi8uLi8uLi91dGlsL3F1aWNrLW1vZHVsZSc7XG5pbXBvcnQgdHlwZSB7IFVzZXIgfSBmcm9tICcuLi8uLi91c2VyL3VzZXInO1xuaW1wb3J0IHR5cGUgeyBTaXRlIH0gZnJvbSAnLi4vc2l0ZSc7XG5pbXBvcnQgeyBTaXRlQXBwbGljYXRpb24gfSBmcm9tICcuLi9zaXRlLWFwcGxpY2F0aW9uJztcbmltcG9ydCB7IFNpdGVNZW1iZXIgfSBmcm9tICcuLi9zaXRlLW1lbWJlcic7XG5cbi8qKlxuICog44K144Kk44OI44Oh44Oz44OQ44O85pON5L2c44Ki44Kv44K744K1XG4gKi9cbmV4cG9ydCBjbGFzcyBNZW1iZXJBY2Nlc3NvciB7XG4gIHB1YmxpYyByZWFkb25seSBzaXRlOiBTaXRlO1xuXG4gIGNvbnN0cnVjdG9yKHNpdGU6IFNpdGUpIHtcbiAgICB0aGlzLnNpdGUgPSBzaXRlO1xuICB9XG5cbiAgLyoqXG4gICAqIOWFqOODoeODs+ODkOODvOOCkuWPluW+l+OBmeOCi1xuICAgKiBAcmV0dXJucyDjg6Hjg7Pjg5Djg7zkuIDopqdcbiAgICovXG4gIGdldEFsbCgpOiBXaWtpZG90UmVzdWx0QXN5bmM8U2l0ZU1lbWJlcltdPiB7XG4gICAgcmV0dXJuIFNpdGVNZW1iZXIuZ2V0TWVtYmVycyh0aGlzLnNpdGUsICcnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg6Ljg4fjg6zjg7zjgr/jg7zkuIDopqfjgpLlj5blvpfjgZnjgotcbiAgICogQHJldHVybnMg44Oi44OH44Os44O844K/44O85LiA6KanXG4gICAqL1xuICBnZXRNb2RlcmF0b3JzKCk6IFdpa2lkb3RSZXN1bHRBc3luYzxTaXRlTWVtYmVyW10+IHtcbiAgICByZXR1cm4gU2l0ZU1lbWJlci5nZXRNZW1iZXJzKHRoaXMuc2l0ZSwgJ21vZGVyYXRvcnMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDnrqHnkIbogIXkuIDopqfjgpLlj5blvpfjgZnjgotcbiAgICogQHJldHVybnMg566h55CG6ICF5LiA6KanXG4gICAqL1xuICBnZXRBZG1pbnMoKTogV2lraWRvdFJlc3VsdEFzeW5jPFNpdGVNZW1iZXJbXT4ge1xuICAgIHJldHVybiBTaXRlTWVtYmVyLmdldE1lbWJlcnModGhpcy5zaXRlLCAnYWRtaW5zJyk7XG4gIH1cblxuICAvKipcbiAgICog5pyq5Yem55CG44Gu5Y+C5Yqg55Sz6KuL44KS5Y+W5b6X44GZ44KLXG4gICAqIEByZXR1cm5zIOWPguWKoOeUs+iri+S4gOimp1xuICAgKi9cbiAgZ2V0QXBwbGljYXRpb25zKCk6IFdpa2lkb3RSZXN1bHRBc3luYzxTaXRlQXBwbGljYXRpb25bXT4ge1xuICAgIHJldHVybiBTaXRlQXBwbGljYXRpb24uYWNxdWlyZUFsbCh0aGlzLnNpdGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIOODoeODs+ODkOODvOOCkuaknOe0ouOBmeOCi1xuICAgKiBAcGFyYW0gcXVlcnkgLSDmpJzntKLjgq/jgqjjg6rvvIjjg6bjg7zjgrbjg7zlkI3jga7kuIDpg6jvvIlcbiAgICogQHJldHVybnMg44Oe44OD44OB44GX44Gf44Om44O844K244O85LiA6Kan77yIUU1DVXNlcuW9ouW8j++8iVxuICAgKi9cbiAgbG9va3VwKHF1ZXJ5OiBzdHJpbmcpOiBXaWtpZG90UmVzdWx0QXN5bmM8UU1DVXNlcltdPiB7XG4gICAgcmV0dXJuIFF1aWNrTW9kdWxlLm1lbWJlckxvb2t1cCh0aGlzLnNpdGUuaWQsIHF1ZXJ5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg6bjg7zjgrbjg7zjgpLjgrXjgqTjg4jjgavmi5vlvoXjgZnjgotcbiAgICogQHBhcmFtIHVzZXIgLSDmi5vlvoXjgZnjgovjg6bjg7zjgrbjg7xcbiAgICogQHBhcmFtIHRleHQgLSDmi5vlvoXjg6Hjg4Pjgrvjg7zjgrhcbiAgICovXG4gIEBSZXF1aXJlTG9naW5cbiAgaW52aXRlKHVzZXI6IFVzZXIsIHRleHQ6IHN0cmluZyk6IFdpa2lkb3RSZXN1bHRBc3luYzx2b2lkPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5zaXRlLmFtY1JlcXVlc3QoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFjdGlvbjogJ01hbmFnZVNpdGVNZW1iZXJzaGlwQWN0aW9uJyxcbiAgICAgICAgICAgIGV2ZW50OiAnaW52aXRlTWVtYmVyJyxcbiAgICAgICAgICAgIHVzZXJfaWQ6IHVzZXIuaWQsXG4gICAgICAgICAgICB0ZXh0LFxuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ0VtcHR5JyxcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgY29uc3QgZXJyb3IgPSByZXN1bHQuZXJyb3I7XG4gICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgV2lraWRvdFN0YXR1c0Vycm9yKSB7XG4gICAgICAgICAgICBpZiAoZXJyb3Iuc3RhdHVzQ29kZSA9PT0gJ2FscmVhZHlfaW52aXRlZCcpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFRhcmdldEVycm9yKFxuICAgICAgICAgICAgICAgIGBVc2VyIGlzIGFscmVhZHkgaW52aXRlZCB0byAke3RoaXMuc2l0ZS51bml4TmFtZX06ICR7dXNlci5uYW1lfWBcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChlcnJvci5zdGF0dXNDb2RlID09PSAnYWxyZWFkeV9tZW1iZXInKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBUYXJnZXRFcnJvcihcbiAgICAgICAgICAgICAgICBgVXNlciBpcyBhbHJlYWR5IGEgbWVtYmVyIG9mICR7dGhpcy5zaXRlLnVuaXhOYW1lfTogJHt1c2VyLm5hbWV9YFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBUYXJnZXRFcnJvciB8fCBlcnJvciBpbnN0YW5jZW9mIExvZ2luUmVxdWlyZWRFcnJvcikge1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGludml0ZSB1c2VyOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgeyBTaXRlTWVtYmVyLCBTaXRlQXBwbGljYXRpb24gfTtcbiIsCiAgICAiaW1wb3J0IHR5cGUgeyBDaGVlcmlvIH0gZnJvbSAnY2hlZXJpbyc7XG5pbXBvcnQgKiBhcyBjaGVlcmlvIGZyb20gJ2NoZWVyaW8nO1xuaW1wb3J0IHR5cGUgeyBBbnlOb2RlIH0gZnJvbSAnZG9taGFuZGxlcic7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kJztcbmltcG9ydCB7IFJlcXVpcmVMb2dpbiB9IGZyb20gJy4uLy4uL2NvbW1vbi9kZWNvcmF0b3JzJztcbmltcG9ydCB7XG4gIEZvcmJpZGRlbkVycm9yLFxuICBMb2dpblJlcXVpcmVkRXJyb3IsXG4gIE5vRWxlbWVudEVycm9yLFxuICBOb3RGb3VuZEV4Y2VwdGlvbixcbiAgVGFyZ2V0RXhpc3RzRXJyb3IsXG4gIFVuZXhwZWN0ZWRFcnJvcixcbn0gZnJvbSAnLi4vLi4vY29tbW9uL2Vycm9ycyc7XG5pbXBvcnQgeyBmcm9tUHJvbWlzZSwgdHlwZSBXaWtpZG90UmVzdWx0QXN5bmMgfSBmcm9tICcuLi8uLi9jb21tb24vdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBBTUNSZXF1ZXN0Qm9keSB9IGZyb20gJy4uLy4uL2Nvbm5lY3Rvcic7XG5pbXBvcnQgeyBwYXJzZU9kYXRlLCBwYXJzZVVzZXIgfSBmcm9tICcuLi8uLi91dGlsL3BhcnNlcic7XG5pbXBvcnQgdHlwZSB7IFNpdGUgfSBmcm9tICcuLi9zaXRlJztcbmltcG9ydCB0eXBlIHsgQWJzdHJhY3RVc2VyIH0gZnJvbSAnLi4vdXNlcic7XG5pbXBvcnQgeyBQYWdlRmlsZUNvbGxlY3Rpb24gfSBmcm9tICcuL3BhZ2UtZmlsZSc7XG5pbXBvcnQgeyBQYWdlTWV0YUNvbGxlY3Rpb24gfSBmcm9tICcuL3BhZ2UtbWV0YSc7XG5pbXBvcnQgeyB0eXBlIFBhZ2VSZXZpc2lvbiwgUGFnZVJldmlzaW9uQ29sbGVjdGlvbiB9IGZyb20gJy4vcGFnZS1yZXZpc2lvbic7XG5pbXBvcnQgeyBQYWdlU291cmNlIH0gZnJvbSAnLi9wYWdlLXNvdXJjZSc7XG5pbXBvcnQgeyBQYWdlVm90ZSwgUGFnZVZvdGVDb2xsZWN0aW9uIH0gZnJvbSAnLi9wYWdlLXZvdGUnO1xuaW1wb3J0IHsgREVGQVVMVF9NT0RVTEVfQk9EWSwgREVGQVVMVF9QRVJfUEFHRSwgU2VhcmNoUGFnZXNRdWVyeSB9IGZyb20gJy4vc2VhcmNoLXF1ZXJ5JztcblxuLyoqXG4gKiBMaXN0UGFnZXNNb2R1bGXjg5Hjg7zjgrnntZDmnpzjga7jgrnjgq3jg7zjg55cbiAqIOWei+WuieWFqOaAp+OBruOBn+OCgeOBq1pvZOOCkuS9v+eUqOOBl+OBpuODkeODvOOCuee1kOaenOOCkuaknOiovFxuICovXG5jb25zdCBwYWdlUGFyYW1zU2NoZW1hID0gei5vYmplY3Qoe1xuICBmdWxsbmFtZTogei5zdHJpbmcoKS5kZWZhdWx0KCcnKSxcbiAgbmFtZTogei5zdHJpbmcoKS5kZWZhdWx0KCcnKSxcbiAgY2F0ZWdvcnk6IHouc3RyaW5nKCkuZGVmYXVsdCgnJyksXG4gIHRpdGxlOiB6LnN0cmluZygpLmRlZmF1bHQoJycpLFxuICBjaGlsZHJlbl9jb3VudDogei5udW1iZXIoKS5kZWZhdWx0KDApLFxuICBjb21tZW50c19jb3VudDogei5udW1iZXIoKS5kZWZhdWx0KDApLFxuICBzaXplOiB6Lm51bWJlcigpLmRlZmF1bHQoMCksXG4gIHJhdGluZzogei5udW1iZXIoKS5kZWZhdWx0KDApLFxuICB2b3Rlc19jb3VudDogei5udW1iZXIoKS5kZWZhdWx0KDApLFxuICByYXRpbmdfcGVyY2VudDogei5udW1iZXIoKS5udWxsYWJsZSgpLmRlZmF1bHQobnVsbCksXG4gIHJldmlzaW9uc19jb3VudDogei5udW1iZXIoKS5kZWZhdWx0KDApLFxuICBwYXJlbnRfZnVsbG5hbWU6IHouc3RyaW5nKCkubnVsbGFibGUoKS5kZWZhdWx0KG51bGwpLFxuICB0YWdzOiB6LmFycmF5KHouc3RyaW5nKCkpLmRlZmF1bHQoW10pLFxuICBjcmVhdGVkX2J5OiB6LmN1c3RvbTxBYnN0cmFjdFVzZXI+KCkubnVsbGFibGUoKS5kZWZhdWx0KG51bGwpLFxuICBjcmVhdGVkX2F0OiB6LmRhdGUoKS5udWxsYWJsZSgpLmRlZmF1bHQobnVsbCksXG4gIHVwZGF0ZWRfYnk6IHouY3VzdG9tPEFic3RyYWN0VXNlcj4oKS5udWxsYWJsZSgpLmRlZmF1bHQobnVsbCksXG4gIHVwZGF0ZWRfYXQ6IHouZGF0ZSgpLm51bGxhYmxlKCkuZGVmYXVsdChudWxsKSxcbiAgY29tbWVudGVkX2J5OiB6LmN1c3RvbTxBYnN0cmFjdFVzZXI+KCkubnVsbGFibGUoKS5kZWZhdWx0KG51bGwpLFxuICBjb21tZW50ZWRfYXQ6IHouZGF0ZSgpLm51bGxhYmxlKCkuZGVmYXVsdChudWxsKSxcbn0pO1xuXG4vKipcbiAqIOODmuODvOOCuOODh+ODvOOCv1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFBhZ2VEYXRhIHtcbiAgc2l0ZTogU2l0ZTtcbiAgZnVsbG5hbWU6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICBjYXRlZ29yeTogc3RyaW5nO1xuICB0aXRsZTogc3RyaW5nO1xuICBjaGlsZHJlbkNvdW50OiBudW1iZXI7XG4gIGNvbW1lbnRzQ291bnQ6IG51bWJlcjtcbiAgc2l6ZTogbnVtYmVyO1xuICByYXRpbmc6IG51bWJlcjtcbiAgdm90ZXNDb3VudDogbnVtYmVyO1xuICByYXRpbmdQZXJjZW50OiBudW1iZXIgfCBudWxsO1xuICByZXZpc2lvbnNDb3VudDogbnVtYmVyO1xuICBwYXJlbnRGdWxsbmFtZTogc3RyaW5nIHwgbnVsbDtcbiAgdGFnczogc3RyaW5nW107XG4gIGNyZWF0ZWRCeTogQWJzdHJhY3RVc2VyIHwgbnVsbDtcbiAgY3JlYXRlZEF0OiBEYXRlO1xuICB1cGRhdGVkQnk6IEFic3RyYWN0VXNlciB8IG51bGw7XG4gIHVwZGF0ZWRBdDogRGF0ZTtcbiAgY29tbWVudGVkQnk6IEFic3RyYWN0VXNlciB8IG51bGw7XG4gIGNvbW1lbnRlZEF0OiBEYXRlIHwgbnVsbDtcbn1cblxuLyoqXG4gKiBXaWtpZG9044Oa44O844K4XG4gKi9cbmV4cG9ydCBjbGFzcyBQYWdlIHtcbiAgcHVibGljIHJlYWRvbmx5IHNpdGU6IFNpdGU7XG4gIHB1YmxpYyByZWFkb25seSBmdWxsbmFtZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgY2F0ZWdvcnk6IHN0cmluZztcbiAgcHVibGljIHRpdGxlOiBzdHJpbmc7XG4gIHB1YmxpYyBjaGlsZHJlbkNvdW50OiBudW1iZXI7XG4gIHB1YmxpYyBjb21tZW50c0NvdW50OiBudW1iZXI7XG4gIHB1YmxpYyBzaXplOiBudW1iZXI7XG4gIHB1YmxpYyByYXRpbmc6IG51bWJlcjtcbiAgcHVibGljIHZvdGVzQ291bnQ6IG51bWJlcjtcbiAgcHVibGljIHJhdGluZ1BlcmNlbnQ6IG51bWJlciB8IG51bGw7XG4gIHB1YmxpYyByZXZpc2lvbnNDb3VudDogbnVtYmVyO1xuICBwdWJsaWMgcGFyZW50RnVsbG5hbWU6IHN0cmluZyB8IG51bGw7XG4gIHB1YmxpYyB0YWdzOiBzdHJpbmdbXTtcbiAgcHVibGljIHJlYWRvbmx5IGNyZWF0ZWRCeTogQWJzdHJhY3RVc2VyIHwgbnVsbDtcbiAgcHVibGljIHJlYWRvbmx5IGNyZWF0ZWRBdDogRGF0ZTtcbiAgcHVibGljIHVwZGF0ZWRCeTogQWJzdHJhY3RVc2VyIHwgbnVsbDtcbiAgcHVibGljIHVwZGF0ZWRBdDogRGF0ZTtcbiAgcHVibGljIGNvbW1lbnRlZEJ5OiBBYnN0cmFjdFVzZXIgfCBudWxsO1xuICBwdWJsaWMgY29tbWVudGVkQXQ6IERhdGUgfCBudWxsO1xuXG4gIHByaXZhdGUgX2lkOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfc291cmNlOiBQYWdlU291cmNlIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX3JldmlzaW9uczogUGFnZVJldmlzaW9uQ29sbGVjdGlvbiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIF92b3RlczogUGFnZVZvdGVDb2xsZWN0aW9uIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoZGF0YTogUGFnZURhdGEpIHtcbiAgICB0aGlzLnNpdGUgPSBkYXRhLnNpdGU7XG4gICAgdGhpcy5mdWxsbmFtZSA9IGRhdGEuZnVsbG5hbWU7XG4gICAgdGhpcy5uYW1lID0gZGF0YS5uYW1lO1xuICAgIHRoaXMuY2F0ZWdvcnkgPSBkYXRhLmNhdGVnb3J5O1xuICAgIHRoaXMudGl0bGUgPSBkYXRhLnRpdGxlO1xuICAgIHRoaXMuY2hpbGRyZW5Db3VudCA9IGRhdGEuY2hpbGRyZW5Db3VudDtcbiAgICB0aGlzLmNvbW1lbnRzQ291bnQgPSBkYXRhLmNvbW1lbnRzQ291bnQ7XG4gICAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xuICAgIHRoaXMucmF0aW5nID0gZGF0YS5yYXRpbmc7XG4gICAgdGhpcy52b3Rlc0NvdW50ID0gZGF0YS52b3Rlc0NvdW50O1xuICAgIHRoaXMucmF0aW5nUGVyY2VudCA9IGRhdGEucmF0aW5nUGVyY2VudDtcbiAgICB0aGlzLnJldmlzaW9uc0NvdW50ID0gZGF0YS5yZXZpc2lvbnNDb3VudDtcbiAgICB0aGlzLnBhcmVudEZ1bGxuYW1lID0gZGF0YS5wYXJlbnRGdWxsbmFtZTtcbiAgICB0aGlzLnRhZ3MgPSBkYXRhLnRhZ3M7XG4gICAgdGhpcy5jcmVhdGVkQnkgPSBkYXRhLmNyZWF0ZWRCeTtcbiAgICB0aGlzLmNyZWF0ZWRBdCA9IGRhdGEuY3JlYXRlZEF0O1xuICAgIHRoaXMudXBkYXRlZEJ5ID0gZGF0YS51cGRhdGVkQnk7XG4gICAgdGhpcy51cGRhdGVkQXQgPSBkYXRhLnVwZGF0ZWRBdDtcbiAgICB0aGlzLmNvbW1lbnRlZEJ5ID0gZGF0YS5jb21tZW50ZWRCeTtcbiAgICB0aGlzLmNvbW1lbnRlZEF0ID0gZGF0YS5jb21tZW50ZWRBdDtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg5rjg7zjgrhVUkzjgpLlj5blvpdcbiAgICovXG4gIGdldFVybCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHt0aGlzLnNpdGUuZ2V0QmFzZVVybCgpfS8ke3RoaXMuZnVsbG5hbWV9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg5rjg7zjgrhJROOBjOWPluW+l+a4iOOBv+OBi+OBqeOBhuOBi1xuICAgKi9cbiAgaXNJZEFjcXVpcmVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9pZCAhPT0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg5rjg7zjgrhJROOCkuWPluW+l1xuICAgKi9cbiAgZ2V0IGlkKCk6IG51bWJlciB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9pZDtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg5rjg7zjgrhJROOCkuioreWumlxuICAgKi9cbiAgc2V0IGlkKHZhbHVlOiBudW1iZXIgfCBudWxsKSB7XG4gICAgdGhpcy5faWQgPSB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjgr3jg7zjgrnjgrPjg7zjg4njgpLlj5blvpdcbiAgICovXG4gIGdldCBzb3VyY2UoKTogUGFnZVNvdXJjZSB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9zb3VyY2U7XG4gIH1cblxuICAvKipcbiAgICog44K944O844K544Kz44O844OJ44KS6Kit5a6aXG4gICAqL1xuICBzZXQgc291cmNlKHZhbHVlOiBQYWdlU291cmNlIHwgbnVsbCkge1xuICAgIHRoaXMuX3NvdXJjZSA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIOODquODk+OCuOODp+ODs+WxpeattOOCkuWPluW+l1xuICAgKi9cbiAgZ2V0IHJldmlzaW9ucygpOiBQYWdlUmV2aXNpb25Db2xsZWN0aW9uIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX3JldmlzaW9ucztcbiAgfVxuXG4gIC8qKlxuICAgKiDjg6rjg5Pjgrjjg6fjg7PlsaXmrbTjgpLoqK3lrppcbiAgICovXG4gIHNldCByZXZpc2lvbnModmFsdWU6IFBhZ2VSZXZpc2lvbkNvbGxlY3Rpb24gfCBudWxsKSB7XG4gICAgdGhpcy5fcmV2aXNpb25zID0gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICog5oqV56Wo5oOF5aCx44KS5Y+W5b6XXG4gICAqL1xuICBnZXQgdm90ZXMoKTogUGFnZVZvdGVDb2xsZWN0aW9uIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX3ZvdGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIOaKleelqOaDheWgseOCkuioreWumlxuICAgKi9cbiAgc2V0IHZvdGVzKHZhbHVlOiBQYWdlVm90ZUNvbGxlY3Rpb24gfCBudWxsKSB7XG4gICAgdGhpcy5fdm90ZXMgPSB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmnIDmlrDjg6rjg5Pjgrjjg6fjg7PjgpLlj5blvpdcbiAgICovXG4gIGdldCBsYXRlc3RSZXZpc2lvbigpOiBQYWdlUmV2aXNpb24gfCB1bmRlZmluZWQge1xuICAgIGlmICghdGhpcy5fcmV2aXNpb25zIHx8IHRoaXMuX3JldmlzaW9ucy5sZW5ndGggPT09IDApIHJldHVybiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHRoaXMuX3JldmlzaW9ucy5yZWR1Y2UoKG1heCwgcmV2KSA9PiAocmV2LnJldk5vID4gbWF4LnJldk5vID8gcmV2IDogbWF4KSk7XG4gIH1cblxuICAvKipcbiAgICog44Oa44O844K4SUTjgYzlv4XpoIjjga7mk43kvZzjgafjgIFJROOBjOOBquOBhOWgtOWQiOOBq+OCqOODqeODvOOCkui/lOOBmeODmOODq+ODkeODvFxuICAgKiBAcGFyYW0gb3BlcmF0aW9uIC0g5pON5L2c5ZCN77yI44Ko44Op44O844Oh44OD44K744O844K455So77yJXG4gICAqIEByZXR1cm5zIOODmuODvOOCuElE44G+44Gf44Gv44Ko44Op44O8UmVzdWx0XG4gICAqL1xuICBwcml2YXRlIHJlcXVpcmVJZChcbiAgICBvcGVyYXRpb246IHN0cmluZ1xuICApOiB7IG9rOiB0cnVlOyBpZDogbnVtYmVyIH0gfCB7IG9rOiBmYWxzZTsgZXJyb3I6IFdpa2lkb3RSZXN1bHRBc3luYzxuZXZlcj4gfSB7XG4gICAgaWYgKHRoaXMuX2lkID09PSBudWxsKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvazogZmFsc2UsXG4gICAgICAgIGVycm9yOiBmcm9tUHJvbWlzZShcbiAgICAgICAgICBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ1BhZ2UgSUQgbm90IGFjcXVpcmVkJykpLFxuICAgICAgICAgICgpID0+IG5ldyBVbmV4cGVjdGVkRXJyb3IoYFBhZ2UgSUQgbXVzdCBiZSBhY3F1aXJlZCBiZWZvcmUgJHtvcGVyYXRpb259YClcbiAgICAgICAgKSxcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7IG9rOiB0cnVlLCBpZDogdGhpcy5faWQgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg5rjg7zjgrjjgpLliYrpmaTjgZnjgotcbiAgICovXG4gIEBSZXF1aXJlTG9naW5cbiAgZGVzdHJveSgpOiBXaWtpZG90UmVzdWx0QXN5bmM8dm9pZD4ge1xuICAgIGNvbnN0IGlkQ2hlY2sgPSB0aGlzLnJlcXVpcmVJZCgnZGVsZXRpb24nKTtcbiAgICBpZiAoIWlkQ2hlY2sub2spIHJldHVybiBpZENoZWNrLmVycm9yO1xuXG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5zaXRlLmFtY1JlcXVlc3QoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFjdGlvbjogJ1dpa2lQYWdlQWN0aW9uJyxcbiAgICAgICAgICAgIGV2ZW50OiAnZGVsZXRlUGFnZScsXG4gICAgICAgICAgICBwYWdlX2lkOiB0aGlzLl9pZCxcbiAgICAgICAgICAgIG1vZHVsZU5hbWU6ICdFbXB0eScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG4gICAgICAgIGlmIChyZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IHJlc3VsdC5lcnJvcjtcbiAgICAgICAgfVxuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGRlbGV0ZSBwYWdlOiAke1N0cmluZyhlcnJvcil9YClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIOOCv+OCsOOCkuS/neWtmOOBmeOCi1xuICAgKi9cbiAgQFJlcXVpcmVMb2dpblxuICBjb21taXRUYWdzKCk6IFdpa2lkb3RSZXN1bHRBc3luYzx2b2lkPiB7XG4gICAgY29uc3QgaWRDaGVjayA9IHRoaXMucmVxdWlyZUlkKCdzYXZpbmcgdGFncycpO1xuICAgIGlmICghaWRDaGVjay5vaykgcmV0dXJuIGlkQ2hlY2suZXJyb3I7XG5cbiAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnNpdGUuYW1jUmVxdWVzdChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdGFnczogdGhpcy50YWdzLmpvaW4oJyAnKSxcbiAgICAgICAgICAgIGFjdGlvbjogJ1dpa2lQYWdlQWN0aW9uJyxcbiAgICAgICAgICAgIGV2ZW50OiAnc2F2ZVRhZ3MnLFxuICAgICAgICAgICAgcGFnZUlkOiB0aGlzLl9pZCxcbiAgICAgICAgICAgIG1vZHVsZU5hbWU6ICdFbXB0eScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG4gICAgICAgIGlmIChyZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IHJlc3VsdC5lcnJvcjtcbiAgICAgICAgfVxuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIHNhdmUgdGFnczogJHtTdHJpbmcoZXJyb3IpfWApXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDopqrjg5rjg7zjgrjjgpLoqK3lrprjgZnjgotcbiAgICogQHBhcmFtIHBhcmVudEZ1bGxuYW1lIC0g6Kaq44Oa44O844K444Gu44OV44Or44ON44O844Og77yIbnVsbOOBp+ino+mZpO+8iVxuICAgKi9cbiAgQFJlcXVpcmVMb2dpblxuICBzZXRQYXJlbnQocGFyZW50RnVsbG5hbWU6IHN0cmluZyB8IG51bGwpOiBXaWtpZG90UmVzdWx0QXN5bmM8dm9pZD4ge1xuICAgIGNvbnN0IGlkQ2hlY2sgPSB0aGlzLnJlcXVpcmVJZCgnc2V0dGluZyBwYXJlbnQnKTtcbiAgICBpZiAoIWlkQ2hlY2sub2spIHJldHVybiBpZENoZWNrLmVycm9yO1xuXG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5zaXRlLmFtY1JlcXVlc3QoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFjdGlvbjogJ1dpa2lQYWdlQWN0aW9uJyxcbiAgICAgICAgICAgIGV2ZW50OiAnc2V0UGFyZW50UGFnZScsXG4gICAgICAgICAgICBtb2R1bGVOYW1lOiAnRW1wdHknLFxuICAgICAgICAgICAgcGFnZUlkOiBTdHJpbmcodGhpcy5faWQpLFxuICAgICAgICAgICAgcGFyZW50TmFtZTogcGFyZW50RnVsbG5hbWUgPz8gJycsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG4gICAgICAgIGlmIChyZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IHJlc3VsdC5lcnJvcjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBhcmVudEZ1bGxuYW1lID0gcGFyZW50RnVsbG5hbWU7XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gc2V0IHBhcmVudDogJHtTdHJpbmcoZXJyb3IpfWApXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg5rjg7zjgrjjgavmipXnpajjgZnjgotcbiAgICogQHBhcmFtIHZhbHVlIC0g5oqV56Wo5YCkXG4gICAqIEByZXR1cm5zIOaWsOOBl+OBhOODrOODvOODhuOCo+ODs+OCsFxuICAgKi9cbiAgQFJlcXVpcmVMb2dpblxuICB2b3RlKHZhbHVlOiBudW1iZXIpOiBXaWtpZG90UmVzdWx0QXN5bmM8bnVtYmVyPiB7XG4gICAgY29uc3QgaWRDaGVjayA9IHRoaXMucmVxdWlyZUlkKCd2b3RpbmcnKTtcbiAgICBpZiAoIWlkQ2hlY2sub2spIHJldHVybiBpZENoZWNrLmVycm9yO1xuXG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5zaXRlLmFtY1JlcXVlc3QoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFjdGlvbjogJ1JhdGVBY3Rpb24nLFxuICAgICAgICAgICAgZXZlbnQ6ICdyYXRlUGFnZScsXG4gICAgICAgICAgICBtb2R1bGVOYW1lOiAnRW1wdHknLFxuICAgICAgICAgICAgcGFnZUlkOiB0aGlzLl9pZCxcbiAgICAgICAgICAgIHBvaW50czogdmFsdWUsXG4gICAgICAgICAgICBmb3JjZTogJ3llcycsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG4gICAgICAgIGlmIChyZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IHJlc3VsdC5lcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZXNwb25zZSA9IHJlc3VsdC52YWx1ZVswXTtcbiAgICAgICAgaWYgKCFyZXNwb25zZSkge1xuICAgICAgICAgIHRocm93IG5ldyBVbmV4cGVjdGVkRXJyb3IoJ0VtcHR5IHJlc3BvbnNlIGZyb20gdm90ZSByZXF1ZXN0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3UmF0aW5nID0gTnVtYmVyLnBhcnNlSW50KFN0cmluZyhyZXNwb25zZS5wb2ludHMgPz8gdGhpcy5yYXRpbmcpLCAxMCk7XG4gICAgICAgIHRoaXMucmF0aW5nID0gbmV3UmF0aW5nO1xuICAgICAgICByZXR1cm4gbmV3UmF0aW5nO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIHZvdGU6ICR7U3RyaW5nKGVycm9yKX1gKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICog5oqV56Wo44KS44Kt44Oj44Oz44K744Or44GZ44KLXG4gICAqIEByZXR1cm5zIOaWsOOBl+OBhOODrOODvOODhuOCo+ODs+OCsFxuICAgKi9cbiAgQFJlcXVpcmVMb2dpblxuICBjYW5jZWxWb3RlKCk6IFdpa2lkb3RSZXN1bHRBc3luYzxudW1iZXI+IHtcbiAgICBjb25zdCBpZENoZWNrID0gdGhpcy5yZXF1aXJlSWQoJ2NhbmNlbGluZyB2b3RlJyk7XG4gICAgaWYgKCFpZENoZWNrLm9rKSByZXR1cm4gaWRDaGVjay5lcnJvcjtcblxuICAgIHJldHVybiBmcm9tUHJvbWlzZShcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuc2l0ZS5hbWNSZXF1ZXN0KFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhY3Rpb246ICdSYXRlQWN0aW9uJyxcbiAgICAgICAgICAgIGV2ZW50OiAnY2FuY2VsVm90ZScsXG4gICAgICAgICAgICBtb2R1bGVOYW1lOiAnRW1wdHknLFxuICAgICAgICAgICAgcGFnZUlkOiB0aGlzLl9pZCxcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gcmVzdWx0LnZhbHVlWzBdO1xuICAgICAgICBpZiAoIXJlc3BvbnNlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRFcnJvcignRW1wdHkgcmVzcG9uc2UgZnJvbSBjYW5jZWwgdm90ZSByZXF1ZXN0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3UmF0aW5nID0gTnVtYmVyLnBhcnNlSW50KFN0cmluZyhyZXNwb25zZS5wb2ludHMgPz8gdGhpcy5yYXRpbmcpLCAxMCk7XG4gICAgICAgIHRoaXMucmF0aW5nID0gbmV3UmF0aW5nO1xuICAgICAgICByZXR1cm4gbmV3UmF0aW5nO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGNhbmNlbCB2b3RlOiAke1N0cmluZyhlcnJvcil9YClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIOODmuODvOOCuOOCkue3qOmbhuOBmeOCi1xuICAgKiBAcGFyYW0gb3B0aW9ucyAtIOe3qOmbhuOCquODl+OCt+ODp+ODs1xuICAgKi9cbiAgQFJlcXVpcmVMb2dpblxuICBlZGl0KG9wdGlvbnM6IHtcbiAgICB0aXRsZT86IHN0cmluZztcbiAgICBzb3VyY2U/OiBzdHJpbmc7XG4gICAgY29tbWVudD86IHN0cmluZztcbiAgICBmb3JjZUVkaXQ/OiBib29sZWFuO1xuICB9KTogV2lraWRvdFJlc3VsdEFzeW5jPHZvaWQ+IHtcbiAgICBjb25zdCBpZENoZWNrID0gdGhpcy5yZXF1aXJlSWQoJ2VkaXRpbmcnKTtcbiAgICBpZiAoIWlkQ2hlY2sub2spIHJldHVybiBpZENoZWNrLmVycm9yO1xuXG4gICAgY29uc3QgcGFnZUlkID0gaWRDaGVjay5pZDtcblxuICAgIHJldHVybiBmcm9tUHJvbWlzZShcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIC8vIOePvuWcqOOBruOCveODvOOCueOCkuWPluW+l++8iOaMh+WumuOBjOOBquOBhOWgtOWQiO+8iVxuICAgICAgICBsZXQgY3VycmVudFNvdXJjZSA9IG9wdGlvbnMuc291cmNlO1xuICAgICAgICBpZiAoY3VycmVudFNvdXJjZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgY29uc3QgZXhpc3RpbmdTb3VyY2UgPSB0aGlzLl9zb3VyY2U7XG4gICAgICAgICAgaWYgKGV4aXN0aW5nU291cmNlICE9PSBudWxsKSB7XG4gICAgICAgICAgICBjdXJyZW50U291cmNlID0gZXhpc3RpbmdTb3VyY2Uud2lraVRleHQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIOOCveODvOOCueOCkuWPluW+l1xuICAgICAgICAgICAgY29uc3Qgc291cmNlUmVzdWx0ID0gYXdhaXQgUGFnZUNvbGxlY3Rpb24uYWNxdWlyZVBhZ2VTb3VyY2VzKHRoaXMuc2l0ZSwgW3RoaXNdKTtcbiAgICAgICAgICAgIGlmIChzb3VyY2VSZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgICAgICB0aHJvdyBzb3VyY2VSZXN1bHQuZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBhY3F1aXJlUGFnZVNvdXJjZXPlvozjgIF0aGlzLl9zb3VyY2Xjgavjgrvjg4Pjg4jjgZXjgozjgotcbiAgICAgICAgICAgIGN1cnJlbnRTb3VyY2UgPSB0aGlzLl9zb3VyY2U/Lndpa2lUZXh0ID8/ICcnO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IFBhZ2VDb2xsZWN0aW9uLmNyZWF0ZU9yRWRpdCh0aGlzLnNpdGUsIHRoaXMuZnVsbG5hbWUsIHtcbiAgICAgICAgICBwYWdlSWQsXG4gICAgICAgICAgdGl0bGU6IG9wdGlvbnMudGl0bGUgPz8gdGhpcy50aXRsZSxcbiAgICAgICAgICBzb3VyY2U6IGN1cnJlbnRTb3VyY2UsXG4gICAgICAgICAgY29tbWVudDogb3B0aW9ucy5jb21tZW50ID8/ICcnLFxuICAgICAgICAgIGZvcmNlRWRpdDogb3B0aW9ucy5mb3JjZUVkaXQgPz8gZmFsc2UsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0pKCksXG4gICAgICAoZXJyb3IpID0+IHtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgTG9naW5SZXF1aXJlZEVycm9yIHx8IGVycm9yIGluc3RhbmNlb2YgRm9yYmlkZGVuRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBVbmV4cGVjdGVkRXJyb3IoYEZhaWxlZCB0byBlZGl0IHBhZ2U6ICR7U3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIOODmuODvOOCuOWQjeOCkuWkieabtOOBmeOCi1xuICAgKiBAcGFyYW0gbmV3RnVsbG5hbWUgLSDmlrDjgZfjgYTjg5Xjg6vjg43jg7zjg6BcbiAgICovXG4gIEBSZXF1aXJlTG9naW5cbiAgcmVuYW1lKG5ld0Z1bGxuYW1lOiBzdHJpbmcpOiBXaWtpZG90UmVzdWx0QXN5bmM8dm9pZD4ge1xuICAgIGNvbnN0IGlkQ2hlY2sgPSB0aGlzLnJlcXVpcmVJZCgncmVuYW1pbmcnKTtcbiAgICBpZiAoIWlkQ2hlY2sub2spIHJldHVybiBpZENoZWNrLmVycm9yO1xuXG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5zaXRlLmFtY1JlcXVlc3QoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFjdGlvbjogJ1dpa2lQYWdlQWN0aW9uJyxcbiAgICAgICAgICAgIGV2ZW50OiAncmVuYW1lUGFnZScsXG4gICAgICAgICAgICBtb2R1bGVOYW1lOiAnRW1wdHknLFxuICAgICAgICAgICAgcGFnZV9pZDogdGhpcy5faWQsXG4gICAgICAgICAgICBuZXdfbmFtZTogbmV3RnVsbG5hbWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG4gICAgICAgIGlmIChyZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IHJlc3VsdC5lcnJvcjtcbiAgICAgICAgfVxuICAgICAgICAvLyDjg5fjg63jg5Hjg4bjgqPjgpLmm7TmlrDvvIhyZWFkb25seeOBquOBruOBp09iamVjdC5hc3NpZ27jgafvvIlcbiAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLCB7XG4gICAgICAgICAgZnVsbG5hbWU6IG5ld0Z1bGxuYW1lLFxuICAgICAgICAgIGNhdGVnb3J5OiBuZXdGdWxsbmFtZS5pbmNsdWRlcygnOicpID8gbmV3RnVsbG5hbWUuc3BsaXQoJzonKVswXSA6ICdfZGVmYXVsdCcsXG4gICAgICAgICAgbmFtZTogbmV3RnVsbG5hbWUuaW5jbHVkZXMoJzonKSA/IG5ld0Z1bGxuYW1lLnNwbGl0KCc6JylbMV0gOiBuZXdGdWxsbmFtZSxcbiAgICAgICAgfSk7XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gcmVuYW1lIHBhZ2U6ICR7U3RyaW5nKGVycm9yKX1gKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICog44Oa44O844K444Gr5re75LuY44GV44KM44Gf44OV44Kh44Kk44Or5LiA6Kan44KS5Y+W5b6X44GZ44KLXG4gICAqL1xuICBnZXRGaWxlcygpOiBXaWtpZG90UmVzdWx0QXN5bmM8UGFnZUZpbGVDb2xsZWN0aW9uPiB7XG4gICAgcmV0dXJuIFBhZ2VGaWxlQ29sbGVjdGlvbi5hY3F1aXJlKHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIOODmuODvOOCuOOBruODh+OCo+OCueOCq+ODg+OCt+ODp+ODs+OCueODrOODg+ODieOCkuWPluW+l+OBmeOCi1xuICAgKi9cbiAgZ2V0RGlzY3Vzc2lvbigpOiBXaWtpZG90UmVzdWx0QXN5bmM8aW1wb3J0KCcuLi9mb3J1bScpLkZvcnVtVGhyZWFkIHwgbnVsbD4ge1xuICAgIGNvbnN0IGlkQ2hlY2sgPSB0aGlzLnJlcXVpcmVJZCgnZ2V0dGluZyBkaXNjdXNzaW9uJyk7XG4gICAgaWYgKCFpZENoZWNrLm9rKSByZXR1cm4gaWRDaGVjay5lcnJvcjtcblxuICAgIGNvbnN0IHBhZ2VJZCA9IGlkQ2hlY2suaWQ7XG5cbiAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnNpdGUuYW1jUmVxdWVzdChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ2ZvcnVtL0ZvcnVtQ29tbWVudHNMaXN0TW9kdWxlJyxcbiAgICAgICAgICAgIHBhZ2VJZCxcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcblxuICAgICAgICBpZiAocmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IHJlc3VsdC52YWx1ZVswXTtcbiAgICAgICAgaWYgKCFyZXNwb25zZSkge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaHRtbCA9IFN0cmluZyhyZXNwb25zZS5ib2R5ID8/ICcnKTtcbiAgICAgICAgLy8g44K544Os44OD44OJSUTjgpLmir3lh7pcbiAgICAgICAgY29uc3QgbWF0Y2ggPSBodG1sLm1hdGNoKFxuICAgICAgICAgIC9XSUtJRE9UXFwubW9kdWxlc1xcLkZvcnVtVmlld1RocmVhZE1vZHVsZVxcLnZhcnNcXC50aHJlYWRJZFxccyo9XFxzKihcXGQrKS9cbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCFtYXRjaD8uWzFdKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0aHJlYWRJZCA9IE51bWJlci5wYXJzZUludChtYXRjaFsxXSwgMTApO1xuXG4gICAgICAgIC8vIEZvcnVtVGhyZWFk44KS5Y+W5b6XXG4gICAgICAgIGNvbnN0IHsgRm9ydW1UaHJlYWQgfSA9IGF3YWl0IGltcG9ydCgnLi4vZm9ydW0nKTtcbiAgICAgICAgY29uc3QgdGhyZWFkUmVzdWx0ID0gYXdhaXQgRm9ydW1UaHJlYWQuZ2V0RnJvbUlkKHRoaXMuc2l0ZSwgdGhyZWFkSWQpO1xuICAgICAgICBpZiAodGhyZWFkUmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyB0aHJlYWRSZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRocmVhZFJlc3VsdC52YWx1ZTtcbiAgICAgIH0pKCksXG4gICAgICAoZXJyb3IpID0+IG5ldyBVbmV4cGVjdGVkRXJyb3IoYEZhaWxlZCB0byBnZXQgZGlzY3Vzc2lvbjogJHtTdHJpbmcoZXJyb3IpfWApXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg5rjg7zjgrjjga7jg6Hjgr/jgr/jgrDkuIDopqfjgpLlj5blvpfjgZnjgotcbiAgICogQHJldHVybnMg44Oh44K/44K/44Kw44Kz44Os44Kv44K344On44OzXG4gICAqL1xuICBnZXRNZXRhcygpOiBXaWtpZG90UmVzdWx0QXN5bmM8UGFnZU1ldGFDb2xsZWN0aW9uPiB7XG4gICAgY29uc3QgaWRDaGVjayA9IHRoaXMucmVxdWlyZUlkKCdnZXR0aW5nIG1ldGFzJyk7XG4gICAgaWYgKCFpZENoZWNrLm9rKSB7XG4gICAgICByZXR1cm4gaWRDaGVjay5lcnJvcjtcbiAgICB9XG5cbiAgICByZXR1cm4gUGFnZU1ldGFDb2xsZWN0aW9uLmFjcXVpcmUodGhpcyk7XG4gIH1cblxuICAvKipcbiAgICog44Oh44K/44K/44Kw44KS6Kit5a6a44GZ44KLXG4gICAqIEBwYXJhbSBuYW1lIC0g44Oh44K/44K/44Kw5ZCNXG4gICAqIEBwYXJhbSBjb250ZW50IC0g44Oh44K/44K/44Kw44Gu5YCkXG4gICAqL1xuICBzZXRNZXRhKG5hbWU6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogV2lraWRvdFJlc3VsdEFzeW5jPHZvaWQ+IHtcbiAgICBjb25zdCBpZENoZWNrID0gdGhpcy5yZXF1aXJlSWQoJ3NldHRpbmcgbWV0YScpO1xuICAgIGlmICghaWRDaGVjay5vaykge1xuICAgICAgcmV0dXJuIGlkQ2hlY2suZXJyb3I7XG4gICAgfVxuXG4gICAgcmV0dXJuIFBhZ2VNZXRhQ29sbGVjdGlvbi5zZXRNZXRhKHRoaXMsIG5hbWUsIGNvbnRlbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOODoeOCv+OCv+OCsOOCkuWJiumZpOOBmeOCi1xuICAgKiBAcGFyYW0gbmFtZSAtIOODoeOCv+OCv+OCsOWQjVxuICAgKi9cbiAgZGVsZXRlTWV0YShuYW1lOiBzdHJpbmcpOiBXaWtpZG90UmVzdWx0QXN5bmM8dm9pZD4ge1xuICAgIGNvbnN0IGlkQ2hlY2sgPSB0aGlzLnJlcXVpcmVJZCgnZGVsZXRpbmcgbWV0YScpO1xuICAgIGlmICghaWRDaGVjay5vaykge1xuICAgICAgcmV0dXJuIGlkQ2hlY2suZXJyb3I7XG4gICAgfVxuXG4gICAgcmV0dXJuIFBhZ2VNZXRhQ29sbGVjdGlvbi5kZWxldGVNZXRhKHRoaXMsIG5hbWUpO1xuICB9XG5cbiAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYFBhZ2UoZnVsbG5hbWU9JHt0aGlzLmZ1bGxuYW1lfSwgdGl0bGU9JHt0aGlzLnRpdGxlfSlgO1xuICB9XG59XG5cbi8qKlxuICog44Oa44O844K444Kz44Os44Kv44K344On44OzXG4gKi9cbmV4cG9ydCBjbGFzcyBQYWdlQ29sbGVjdGlvbiBleHRlbmRzIEFycmF5PFBhZ2U+IHtcbiAgcHVibGljIHJlYWRvbmx5IHNpdGU6IFNpdGU7XG5cbiAgY29uc3RydWN0b3Ioc2l0ZTogU2l0ZSwgcGFnZXM/OiBQYWdlW10pIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuc2l0ZSA9IHNpdGU7XG4gICAgaWYgKHBhZ2VzKSB7XG4gICAgICB0aGlzLnB1c2goLi4ucGFnZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDjg5Xjg6vjg43jg7zjg6DjgafmpJzntKJcbiAgICogQHBhcmFtIGZ1bGxuYW1lIC0g44Oa44O844K444Gu44OV44Or44ON44O844OgXG4gICAqIEByZXR1cm5zIOODmuODvOOCuO+8iOWtmOWcqOOBl+OBquOBhOWgtOWQiOOBr3VuZGVmaW5lZO+8iVxuICAgKi9cbiAgZmluZEJ5RnVsbG5hbWUoZnVsbG5hbWU6IHN0cmluZyk6IFBhZ2UgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmZpbmQoKHBhZ2UpID0+IHBhZ2UuZnVsbG5hbWUgPT09IGZ1bGxuYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg5rjg7zjgrhJROOCkuS4gOaLrOWPluW+l1xuICAgKi9cbiAgZ2V0UGFnZUlkcygpOiBXaWtpZG90UmVzdWx0QXN5bmM8UGFnZUNvbGxlY3Rpb24+IHtcbiAgICByZXR1cm4gUGFnZUNvbGxlY3Rpb24uYWNxdWlyZVBhZ2VJZHModGhpcy5zaXRlLCB0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg5rjg7zjgrjjgr3jg7zjgrnjgpLkuIDmi6zlj5blvpdcbiAgICovXG4gIGdldFBhZ2VTb3VyY2VzKCk6IFdpa2lkb3RSZXN1bHRBc3luYzxQYWdlQ29sbGVjdGlvbj4ge1xuICAgIHJldHVybiBQYWdlQ29sbGVjdGlvbi5hY3F1aXJlUGFnZVNvdXJjZXModGhpcy5zaXRlLCB0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg5rjg7zjgrjjg6rjg5Pjgrjjg6fjg7PjgpLkuIDmi6zlj5blvpdcbiAgICovXG4gIGdldFBhZ2VSZXZpc2lvbnMoKTogV2lraWRvdFJlc3VsdEFzeW5jPFBhZ2VDb2xsZWN0aW9uPiB7XG4gICAgcmV0dXJuIFBhZ2VDb2xsZWN0aW9uLmFjcXVpcmVQYWdlUmV2aXNpb25zKHRoaXMuc2l0ZSwgdGhpcyk7XG4gIH1cblxuICAvKipcbiAgICog44Oa44O844K45oqV56Wo44KS5LiA5ous5Y+W5b6XXG4gICAqL1xuICBnZXRQYWdlVm90ZXMoKTogV2lraWRvdFJlc3VsdEFzeW5jPFBhZ2VDb2xsZWN0aW9uPiB7XG4gICAgcmV0dXJuIFBhZ2VDb2xsZWN0aW9uLmFjcXVpcmVQYWdlVm90ZXModGhpcy5zaXRlLCB0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg5rjg7zjgrhJROOCkuS4gOaLrOWPluW+l+OBmeOCi+WGhemDqOODoeOCveODg+ODiVxuICAgKi9cbiAgc3RhdGljIGFjcXVpcmVQYWdlSWRzKHNpdGU6IFNpdGUsIHBhZ2VzOiBQYWdlW10pOiBXaWtpZG90UmVzdWx0QXN5bmM8UGFnZUNvbGxlY3Rpb24+IHtcbiAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB0YXJnZXRQYWdlcyA9IHBhZ2VzLmZpbHRlcigocGFnZSkgPT4gIXBhZ2UuaXNJZEFjcXVpcmVkKCkpO1xuXG4gICAgICAgIGlmICh0YXJnZXRQYWdlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFBhZ2VDb2xsZWN0aW9uKHNpdGUsIHBhZ2VzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIG5vcmVuZGVyLCBub3JlZGlyZWN044Gn44Ki44Kv44K744K5XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlcyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgIHRhcmdldFBhZ2VzLm1hcChhc3luYyAocGFnZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdXJsID0gYCR7cGFnZS5nZXRVcmwoKX0vbm9yZW5kZXIvdHJ1ZS9ub3JlZGlyZWN0L3RydWVgO1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwsIHtcbiAgICAgICAgICAgICAgaGVhZGVyczogc2l0ZS5jbGllbnQuYW1jQ2xpZW50LmhlYWRlci5nZXRIZWFkZXJzKCksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiB7IHBhZ2UsIHJlc3BvbnNlIH07XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcblxuICAgICAgICBmb3IgKGNvbnN0IHsgcGFnZSwgcmVzcG9uc2UgfSBvZiByZXNwb25zZXMpIHtcbiAgICAgICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVzcG9uc2UudGV4dCgpO1xuICAgICAgICAgIGNvbnN0IG1hdGNoID0gdGV4dC5tYXRjaCgvV0lLSVJFUVVFU1RcXC5pbmZvXFwucGFnZUlkXFxzKj1cXHMqKFxcZCspOy8pO1xuICAgICAgICAgIGlmICghbWF0Y2g/LlsxXSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IE5vRWxlbWVudEVycm9yKGBDYW5ub3QgZmluZCBwYWdlIGlkOiAke3BhZ2UuZnVsbG5hbWV9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHBhZ2UuaWQgPSBOdW1iZXIucGFyc2VJbnQobWF0Y2hbMV0sIDEwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgUGFnZUNvbGxlY3Rpb24oc2l0ZSwgcGFnZXMpO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvcikgcmV0dXJuIGVycm9yO1xuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGFjcXVpcmUgcGFnZSBJRHM6ICR7U3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIOODmuODvOOCuOOCveODvOOCueOCkuS4gOaLrOWPluW+l+OBmeOCi+WGhemDqOODoeOCveODg+ODiVxuICAgKi9cbiAgc3RhdGljIGFjcXVpcmVQYWdlU291cmNlcyhzaXRlOiBTaXRlLCBwYWdlczogUGFnZVtdKTogV2lraWRvdFJlc3VsdEFzeW5jPFBhZ2VDb2xsZWN0aW9uPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgdGFyZ2V0UGFnZXMgPSBwYWdlcy5maWx0ZXIoKHBhZ2UpID0+IHBhZ2Uuc291cmNlID09PSBudWxsICYmIHBhZ2UuaWQgIT09IG51bGwpO1xuXG4gICAgICAgIGlmICh0YXJnZXRQYWdlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFBhZ2VDb2xsZWN0aW9uKHNpdGUsIHBhZ2VzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNpdGUuYW1jUmVxdWVzdChcbiAgICAgICAgICB0YXJnZXRQYWdlcy5tYXAoKHBhZ2UpID0+ICh7XG4gICAgICAgICAgICBtb2R1bGVOYW1lOiAndmlld3NvdXJjZS9WaWV3U291cmNlTW9kdWxlJyxcbiAgICAgICAgICAgIHBhZ2VfaWQ6IHBhZ2UuaWQsXG4gICAgICAgICAgfSkpXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0YXJnZXRQYWdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IHBhZ2UgPSB0YXJnZXRQYWdlc1tpXTtcbiAgICAgICAgICBjb25zdCByZXNwb25zZSA9IHJlc3VsdC52YWx1ZVtpXTtcbiAgICAgICAgICBpZiAoIXBhZ2UgfHwgIXJlc3BvbnNlKSBjb250aW51ZTtcbiAgICAgICAgICBjb25zdCBib2R5ID0gU3RyaW5nKHJlc3BvbnNlLmJvZHkgPz8gJycpLnJlcGxhY2UoLyZuYnNwOy9nLCAnICcpO1xuICAgICAgICAgIGNvbnN0ICQgPSBjaGVlcmlvLmxvYWQoYm9keSk7XG4gICAgICAgICAgY29uc3Qgc291cmNlRWxlbWVudCA9ICQoJ2Rpdi5wYWdlLXNvdXJjZScpO1xuICAgICAgICAgIGlmIChzb3VyY2VFbGVtZW50Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IE5vRWxlbWVudEVycm9yKGBDYW5ub3QgZmluZCBzb3VyY2UgZWxlbWVudCBmb3IgcGFnZTogJHtwYWdlLmZ1bGxuYW1lfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCB3aWtpVGV4dCA9IHNvdXJjZUVsZW1lbnQudGV4dCgpLnRyaW0oKS5yZXBsYWNlKC9eXFx0LywgJycpO1xuICAgICAgICAgIHBhZ2Uuc291cmNlID0gbmV3IFBhZ2VTb3VyY2UoeyBwYWdlLCB3aWtpVGV4dCB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgUGFnZUNvbGxlY3Rpb24oc2l0ZSwgcGFnZXMpO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvcikgcmV0dXJuIGVycm9yO1xuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGFjcXVpcmUgcGFnZSBzb3VyY2VzOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg5rjg7zjgrjjg6rjg5Pjgrjjg6fjg7PjgpLkuIDmi6zlj5blvpfjgZnjgovlhoXpg6jjg6Hjgr3jg4Pjg4lcbiAgICovXG4gIHN0YXRpYyBhY3F1aXJlUGFnZVJldmlzaW9ucyhzaXRlOiBTaXRlLCBwYWdlczogUGFnZVtdKTogV2lraWRvdFJlc3VsdEFzeW5jPFBhZ2VDb2xsZWN0aW9uPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgdGFyZ2V0UGFnZXMgPSBwYWdlcy5maWx0ZXIoKHBhZ2UpID0+IHBhZ2UucmV2aXNpb25zID09PSBudWxsICYmIHBhZ2UuaWQgIT09IG51bGwpO1xuXG4gICAgICAgIGlmICh0YXJnZXRQYWdlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFBhZ2VDb2xsZWN0aW9uKHNpdGUsIHBhZ2VzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNpdGUuYW1jUmVxdWVzdChcbiAgICAgICAgICB0YXJnZXRQYWdlcy5tYXAoKHBhZ2UpID0+ICh7XG4gICAgICAgICAgICBtb2R1bGVOYW1lOiAnaGlzdG9yeS9QYWdlUmV2aXNpb25MaXN0TW9kdWxlJyxcbiAgICAgICAgICAgIHBhZ2VfaWQ6IHBhZ2UuaWQsXG4gICAgICAgICAgICBvcHRpb25zOiB7IGFsbDogdHJ1ZSB9LFxuICAgICAgICAgICAgcGVycGFnZTogMTAwMDAwMDAwLFxuICAgICAgICAgIH0pKVxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChyZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IHJlc3VsdC5lcnJvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOODquODk+OCuOODp+ODs+OCkuODkeODvOOCuVxuICAgICAgICBjb25zdCB7IFBhZ2VSZXZpc2lvbiB9ID0gYXdhaXQgaW1wb3J0KCcuL3BhZ2UtcmV2aXNpb24nKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0YXJnZXRQYWdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IHBhZ2UgPSB0YXJnZXRQYWdlc1tpXTtcbiAgICAgICAgICBjb25zdCByZXNwb25zZSA9IHJlc3VsdC52YWx1ZVtpXTtcbiAgICAgICAgICBpZiAoIXBhZ2UgfHwgIXJlc3BvbnNlKSBjb250aW51ZTtcblxuICAgICAgICAgIGNvbnN0IGJvZHkgPSBTdHJpbmcocmVzcG9uc2UuYm9keSA/PyAnJyk7XG4gICAgICAgICAgY29uc3QgJCA9IGNoZWVyaW8ubG9hZChib2R5KTtcbiAgICAgICAgICBjb25zdCByZXZpc2lvbnM6IFBhZ2VSZXZpc2lvbltdID0gW107XG5cbiAgICAgICAgICAkKCd0YWJsZS5wYWdlLWhpc3RvcnkgPiB0cltpZF49cmV2aXNpb24tcm93LV0nKS5lYWNoKChfaiwgcmV2RWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgJHJldiA9ICQocmV2RWxlbWVudCk7XG4gICAgICAgICAgICBjb25zdCByZXZJZEF0dHIgPSAkcmV2LmF0dHIoJ2lkJyk7XG4gICAgICAgICAgICBpZiAoIXJldklkQXR0cikgcmV0dXJuO1xuXG4gICAgICAgICAgICBjb25zdCByZXZJZCA9IE51bWJlci5wYXJzZUludChyZXZJZEF0dHIucmVwbGFjZSgncmV2aXNpb24tcm93LScsICcnKSwgMTApO1xuICAgICAgICAgICAgaWYgKE51bWJlci5pc05hTihyZXZJZCkpIHJldHVybjtcblxuICAgICAgICAgICAgY29uc3QgJHRkcyA9ICRyZXYuZmluZCgndGQnKTtcbiAgICAgICAgICAgIGlmICgkdGRzLmxlbmd0aCA8IDcpIHJldHVybjtcblxuICAgICAgICAgICAgY29uc3QgcmV2Tm9UZXh0ID0gJHRkcy5lcSgwKS50ZXh0KCkudHJpbSgpLnJlcGxhY2UoL1xcLiQvLCAnJyk7XG4gICAgICAgICAgICBjb25zdCByZXZObyA9IE51bWJlci5wYXJzZUludChyZXZOb1RleHQsIDEwKTtcbiAgICAgICAgICAgIGlmIChOdW1iZXIuaXNOYU4ocmV2Tm8pKSByZXR1cm47XG5cbiAgICAgICAgICAgIGNvbnN0ICRjcmVhdGVkQnlFbGVtID0gJHRkcy5lcSg0KS5maW5kKCdzcGFuLnByaW50dXNlcicpO1xuICAgICAgICAgICAgaWYgKCRjcmVhdGVkQnlFbGVtLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgICAgICAgY29uc3QgY3JlYXRlZEJ5ID0gcGFyc2VVc2VyKHNpdGUuY2xpZW50LCAkY3JlYXRlZEJ5RWxlbSBhcyBDaGVlcmlvPEFueU5vZGU+KTtcblxuICAgICAgICAgICAgY29uc3QgJGNyZWF0ZWRBdEVsZW0gPSAkdGRzLmVxKDUpLmZpbmQoJ3NwYW4ub2RhdGUnKTtcbiAgICAgICAgICAgIGlmICgkY3JlYXRlZEF0RWxlbS5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICAgICAgICAgIGNvbnN0IGNyZWF0ZWRBdCA9IHBhcnNlT2RhdGUoJGNyZWF0ZWRBdEVsZW0gYXMgQ2hlZXJpbzxBbnlOb2RlPikgPz8gbmV3IERhdGUoKTtcblxuICAgICAgICAgICAgY29uc3QgY29tbWVudCA9ICR0ZHMuZXEoNikudGV4dCgpLnRyaW0oKTtcblxuICAgICAgICAgICAgcmV2aXNpb25zLnB1c2goXG4gICAgICAgICAgICAgIG5ldyBQYWdlUmV2aXNpb24oe1xuICAgICAgICAgICAgICAgIHBhZ2UsXG4gICAgICAgICAgICAgICAgaWQ6IHJldklkLFxuICAgICAgICAgICAgICAgIHJldk5vLFxuICAgICAgICAgICAgICAgIGNyZWF0ZWRCeSxcbiAgICAgICAgICAgICAgICBjcmVhdGVkQXQsXG4gICAgICAgICAgICAgICAgY29tbWVudCxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBwYWdlLnJldmlzaW9ucyA9IG5ldyBQYWdlUmV2aXNpb25Db2xsZWN0aW9uKHBhZ2UsIHJldmlzaW9ucyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IFBhZ2VDb2xsZWN0aW9uKHNpdGUsIHBhZ2VzKTtcbiAgICAgIH0pKCksXG4gICAgICAoZXJyb3IpID0+IG5ldyBVbmV4cGVjdGVkRXJyb3IoYEZhaWxlZCB0byBhY3F1aXJlIHBhZ2UgcmV2aXNpb25zOiAke1N0cmluZyhlcnJvcil9YClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIOODmuODvOOCuOaKleelqOOCkuS4gOaLrOWPluW+l+OBmeOCi+WGhemDqOODoeOCveODg+ODiVxuICAgKi9cbiAgc3RhdGljIGFjcXVpcmVQYWdlVm90ZXMoc2l0ZTogU2l0ZSwgcGFnZXM6IFBhZ2VbXSk6IFdpa2lkb3RSZXN1bHRBc3luYzxQYWdlQ29sbGVjdGlvbj4ge1xuICAgIHJldHVybiBmcm9tUHJvbWlzZShcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHRhcmdldFBhZ2VzID0gcGFnZXMuZmlsdGVyKChwYWdlKSA9PiBwYWdlLnZvdGVzID09PSBudWxsICYmIHBhZ2UuaWQgIT09IG51bGwpO1xuXG4gICAgICAgIGlmICh0YXJnZXRQYWdlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFBhZ2VDb2xsZWN0aW9uKHNpdGUsIHBhZ2VzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNpdGUuYW1jUmVxdWVzdChcbiAgICAgICAgICB0YXJnZXRQYWdlcy5tYXAoKHBhZ2UpID0+ICh7XG4gICAgICAgICAgICBtb2R1bGVOYW1lOiAncGFnZXJhdGUvV2hvUmF0ZWRQYWdlTW9kdWxlJyxcbiAgICAgICAgICAgIHBhZ2VJZDogcGFnZS5pZCxcbiAgICAgICAgICB9KSlcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAocmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDmipXnpajjgpLjg5Hjg7zjgrlcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0YXJnZXRQYWdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IHBhZ2UgPSB0YXJnZXRQYWdlc1tpXTtcbiAgICAgICAgICBjb25zdCByZXNwb25zZSA9IHJlc3VsdC52YWx1ZVtpXTtcbiAgICAgICAgICBpZiAoIXBhZ2UgfHwgIXJlc3BvbnNlKSBjb250aW51ZTtcblxuICAgICAgICAgIGNvbnN0IGJvZHkgPSBTdHJpbmcocmVzcG9uc2UuYm9keSA/PyAnJyk7XG4gICAgICAgICAgY29uc3QgJCA9IGNoZWVyaW8ubG9hZChib2R5KTtcblxuICAgICAgICAgIGNvbnN0ICR1c2VyRWxlbXMgPSAkKCdzcGFuLnByaW50dXNlcicpO1xuICAgICAgICAgIGNvbnN0ICR2YWx1ZUVsZW1zID0gJChcInNwYW5bc3R5bGVePSdjb2xvciddXCIpO1xuXG4gICAgICAgICAgaWYgKCR1c2VyRWxlbXMubGVuZ3RoICE9PSAkdmFsdWVFbGVtcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBVbmV4cGVjdGVkRXJyb3IoJ1VzZXIgYW5kIHZhbHVlIGNvdW50IG1pc21hdGNoIGluIHZvdGVzJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3Qgdm90ZXM6IFBhZ2VWb3RlW10gPSBbXTtcbiAgICAgICAgICAkdXNlckVsZW1zLmVhY2goKGosIHVzZXJFbGVtKSA9PiB7XG4gICAgICAgICAgICBjb25zdCAkdXNlciA9ICQodXNlckVsZW0pO1xuICAgICAgICAgICAgY29uc3QgJHZhbHVlID0gJHZhbHVlRWxlbXMuZXEoaik7XG5cbiAgICAgICAgICAgIGNvbnN0IHVzZXIgPSBwYXJzZVVzZXIoc2l0ZS5jbGllbnQsICR1c2VyIGFzIENoZWVyaW88QW55Tm9kZT4pO1xuICAgICAgICAgICAgY29uc3QgdmFsdWVUZXh0ID0gJHZhbHVlLnRleHQoKS50cmltKCk7XG5cbiAgICAgICAgICAgIGxldCB2YWx1ZTogbnVtYmVyO1xuICAgICAgICAgICAgaWYgKHZhbHVlVGV4dCA9PT0gJysnKSB7XG4gICAgICAgICAgICAgIHZhbHVlID0gMTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWVUZXh0ID09PSAnLScpIHtcbiAgICAgICAgICAgICAgdmFsdWUgPSAtMTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHZhbHVlID0gTnVtYmVyLnBhcnNlSW50KHZhbHVlVGV4dCwgMTApIHx8IDA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZvdGVzLnB1c2gobmV3IFBhZ2VWb3RlKHsgcGFnZSwgdXNlciwgdmFsdWUgfSkpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgcGFnZS52b3RlcyA9IG5ldyBQYWdlVm90ZUNvbGxlY3Rpb24ocGFnZSwgdm90ZXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQYWdlQ29sbGVjdGlvbihzaXRlLCBwYWdlcyk7XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gYWNxdWlyZSBwYWdlIHZvdGVzOiAke1N0cmluZyhlcnJvcil9YClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIExpc3RQYWdlc01vZHVsZeODrOOCueODneODs+OCueOCkuODkeODvOOCuVxuICAgKi9cbiAgc3RhdGljIHBhcnNlKFxuICAgIHNpdGU6IFNpdGUsXG4gICAgaHRtbEJvZHk6IGNoZWVyaW8uQ2hlZXJpb0FQSSxcbiAgICBfcGFyc2VVc2VyOiAoZWxlbWVudDogY2hlZXJpby5DaGVlcmlvPEFueU5vZGU+KSA9PiBBYnN0cmFjdFVzZXJcbiAgKTogUGFnZUNvbGxlY3Rpb24ge1xuICAgIGNvbnN0IHBhZ2VzOiBQYWdlW10gPSBbXTtcblxuICAgIGh0bWxCb2R5KCdkaXYucGFnZScpLmVhY2goKF9pLCBwYWdlRWxlbWVudCkgPT4ge1xuICAgICAgY29uc3QgJHBhZ2UgPSBodG1sQm9keShwYWdlRWxlbWVudCk7XG4gICAgICBjb25zdCBwYWdlUGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuXG4gICAgICAvLyA144Gk5pif44Os44O844OG44Kj44Oz44Kw5Yik5a6aXG4gICAgICBjb25zdCBpczVTdGFyUmF0aW5nID0gJHBhZ2UuZmluZCgnc3Bhbi5yYXRpbmcgc3Bhbi5wYWdlLXJhdGUtbGlzdC1wYWdlcy1zdGFydCcpLmxlbmd0aCA+IDA7XG5cbiAgICAgIC8vIOWQhOWApOOCkuWPluW+l1xuICAgICAgJHBhZ2UuZmluZCgnc3Bhbi5zZXQnKS5lYWNoKChfaiwgc2V0RWxlbWVudCkgPT4ge1xuICAgICAgICBjb25zdCAkc2V0ID0gaHRtbEJvZHkoc2V0RWxlbWVudCk7XG4gICAgICAgIGNvbnN0IGtleUVsZW1lbnQgPSAkc2V0LmZpbmQoJ3NwYW4ubmFtZScpO1xuICAgICAgICBpZiAoa2V5RWxlbWVudC5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgICAgICBsZXQga2V5ID0ga2V5RWxlbWVudC50ZXh0KCkudHJpbSgpO1xuICAgICAgICBjb25zdCB2YWx1ZUVsZW1lbnQgPSAkc2V0LmZpbmQoJ3NwYW4udmFsdWUnKTtcblxuICAgICAgICBsZXQgdmFsdWU6IHVua25vd24gPSBudWxsO1xuXG4gICAgICAgIGlmICh2YWx1ZUVsZW1lbnQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdmFsdWUgPSBudWxsO1xuICAgICAgICB9IGVsc2UgaWYgKFsnY3JlYXRlZF9hdCcsICd1cGRhdGVkX2F0JywgJ2NvbW1lbnRlZF9hdCddLmluY2x1ZGVzKGtleSkpIHtcbiAgICAgICAgICBjb25zdCBvZGF0ZUVsZW1lbnQgPSB2YWx1ZUVsZW1lbnQuZmluZCgnc3Bhbi5vZGF0ZScpO1xuICAgICAgICAgIGlmIChvZGF0ZUVsZW1lbnQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgdGltZXN0YW1wID0gb2RhdGVFbGVtZW50LmF0dHIoJ2NsYXNzJyk/Lm1hdGNoKC90aW1lXyhcXGQrKS8pPy5bMV07XG4gICAgICAgICAgICB2YWx1ZSA9IHRpbWVzdGFtcCA/IG5ldyBEYXRlKE51bWJlci5wYXJzZUludCh0aW1lc3RhbXAsIDEwKSAqIDEwMDApIDogbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgWydjcmVhdGVkX2J5X2xpbmtlZCcsICd1cGRhdGVkX2J5X2xpbmtlZCcsICdjb21tZW50ZWRfYnlfbGlua2VkJ10uaW5jbHVkZXMoa2V5KVxuICAgICAgICApIHtcbiAgICAgICAgICBjb25zdCBwcmludHVzZXJFbGVtZW50ID0gdmFsdWVFbGVtZW50LmZpbmQoJ3NwYW4ucHJpbnR1c2VyJyk7XG4gICAgICAgICAgaWYgKHByaW50dXNlckVsZW1lbnQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdmFsdWUgPSBfcGFyc2VVc2VyKHByaW50dXNlckVsZW1lbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChbJ3RhZ3MnLCAnX3RhZ3MnXS5pbmNsdWRlcyhrZXkpKSB7XG4gICAgICAgICAgdmFsdWUgPSB2YWx1ZUVsZW1lbnQudGV4dCgpLnNwbGl0KC9cXHMrLykuZmlsdGVyKEJvb2xlYW4pO1xuICAgICAgICB9IGVsc2UgaWYgKFsncmF0aW5nX3ZvdGVzJywgJ2NvbW1lbnRzJywgJ3NpemUnLCAncmV2aXNpb25zJ10uaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICAgIHZhbHVlID0gTnVtYmVyLnBhcnNlSW50KHZhbHVlRWxlbWVudC50ZXh0KCkudHJpbSgpLCAxMCkgfHwgMDtcbiAgICAgICAgfSBlbHNlIGlmIChrZXkgPT09ICdyYXRpbmcnKSB7XG4gICAgICAgICAgY29uc3QgcmF0aW5nVGV4dCA9IHZhbHVlRWxlbWVudC50ZXh0KCkudHJpbSgpO1xuICAgICAgICAgIHZhbHVlID0gaXM1U3RhclJhdGluZ1xuICAgICAgICAgICAgPyBOdW1iZXIucGFyc2VGbG9hdChyYXRpbmdUZXh0KSB8fCAwXG4gICAgICAgICAgICA6IE51bWJlci5wYXJzZUludChyYXRpbmdUZXh0LCAxMCkgfHwgMDtcbiAgICAgICAgfSBlbHNlIGlmIChrZXkgPT09ICdyYXRpbmdfcGVyY2VudCcpIHtcbiAgICAgICAgICBpZiAoaXM1U3RhclJhdGluZykge1xuICAgICAgICAgICAgdmFsdWUgPSAoTnVtYmVyLnBhcnNlRmxvYXQodmFsdWVFbGVtZW50LnRleHQoKS50cmltKCkpIHx8IDApIC8gMTAwO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZSA9IG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlID0gdmFsdWVFbGVtZW50LnRleHQoKS50cmltKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDjgq3jg7zlpInmj5tcbiAgICAgICAgaWYgKGtleS5pbmNsdWRlcygnX2xpbmtlZCcpKSB7XG4gICAgICAgICAga2V5ID0ga2V5LnJlcGxhY2UoJ19saW5rZWQnLCAnJyk7XG4gICAgICAgIH0gZWxzZSBpZiAoWydjb21tZW50cycsICdjaGlsZHJlbicsICdyZXZpc2lvbnMnXS5pbmNsdWRlcyhrZXkpKSB7XG4gICAgICAgICAga2V5ID0gYCR7a2V5fV9jb3VudGA7XG4gICAgICAgIH0gZWxzZSBpZiAoa2V5ID09PSAncmF0aW5nX3ZvdGVzJykge1xuICAgICAgICAgIGtleSA9ICd2b3Rlc19jb3VudCc7XG4gICAgICAgIH1cblxuICAgICAgICBwYWdlUGFyYW1zW2tleV0gPSB2YWx1ZTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyDjgr/jgrDntbHlkIhcbiAgICAgIGNvbnN0IHRhZ3MgPSBBcnJheS5pc0FycmF5KHBhZ2VQYXJhbXMudGFncykgPyBwYWdlUGFyYW1zLnRhZ3MgOiBbXTtcbiAgICAgIGNvbnN0IGhpZGRlblRhZ3MgPSBBcnJheS5pc0FycmF5KHBhZ2VQYXJhbXMuX3RhZ3MpID8gcGFnZVBhcmFtcy5fdGFncyA6IFtdO1xuICAgICAgcGFnZVBhcmFtcy50YWdzID0gWy4uLnRhZ3MsIC4uLmhpZGRlblRhZ3NdO1xuXG4gICAgICAvLyBab2Tjgrnjgq3jg7zjg57jgafmpJzoqLzjg7vjg4fjg5Xjgqnjg6vjg4jlgKTpgannlKhcbiAgICAgIGNvbnN0IHBhcnNlZCA9IHBhZ2VQYXJhbXNTY2hlbWEucGFyc2UocGFnZVBhcmFtcyk7XG5cbiAgICAgIC8vIFBhZ2Xjgqrjg5bjgrjjgqfjgq/jg4jkvZzmiJBcbiAgICAgIHBhZ2VzLnB1c2goXG4gICAgICAgIG5ldyBQYWdlKHtcbiAgICAgICAgICBzaXRlLFxuICAgICAgICAgIGZ1bGxuYW1lOiBwYXJzZWQuZnVsbG5hbWUsXG4gICAgICAgICAgbmFtZTogcGFyc2VkLm5hbWUsXG4gICAgICAgICAgY2F0ZWdvcnk6IHBhcnNlZC5jYXRlZ29yeSxcbiAgICAgICAgICB0aXRsZTogcGFyc2VkLnRpdGxlLFxuICAgICAgICAgIGNoaWxkcmVuQ291bnQ6IHBhcnNlZC5jaGlsZHJlbl9jb3VudCxcbiAgICAgICAgICBjb21tZW50c0NvdW50OiBwYXJzZWQuY29tbWVudHNfY291bnQsXG4gICAgICAgICAgc2l6ZTogcGFyc2VkLnNpemUsXG4gICAgICAgICAgcmF0aW5nOiBwYXJzZWQucmF0aW5nLFxuICAgICAgICAgIHZvdGVzQ291bnQ6IHBhcnNlZC52b3Rlc19jb3VudCxcbiAgICAgICAgICByYXRpbmdQZXJjZW50OiBwYXJzZWQucmF0aW5nX3BlcmNlbnQsXG4gICAgICAgICAgcmV2aXNpb25zQ291bnQ6IHBhcnNlZC5yZXZpc2lvbnNfY291bnQsXG4gICAgICAgICAgcGFyZW50RnVsbG5hbWU6IHBhcnNlZC5wYXJlbnRfZnVsbG5hbWUsXG4gICAgICAgICAgdGFnczogcGFyc2VkLnRhZ3MsXG4gICAgICAgICAgY3JlYXRlZEJ5OiBwYXJzZWQuY3JlYXRlZF9ieSxcbiAgICAgICAgICBjcmVhdGVkQXQ6IHBhcnNlZC5jcmVhdGVkX2F0ID8/IG5ldyBEYXRlKCksXG4gICAgICAgICAgdXBkYXRlZEJ5OiBwYXJzZWQudXBkYXRlZF9ieSxcbiAgICAgICAgICB1cGRhdGVkQXQ6IHBhcnNlZC51cGRhdGVkX2F0ID8/IG5ldyBEYXRlKCksXG4gICAgICAgICAgY29tbWVudGVkQnk6IHBhcnNlZC5jb21tZW50ZWRfYnksXG4gICAgICAgICAgY29tbWVudGVkQXQ6IHBhcnNlZC5jb21tZW50ZWRfYXQsXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIG5ldyBQYWdlQ29sbGVjdGlvbihzaXRlLCBwYWdlcyk7XG4gIH1cblxuICAvKipcbiAgICog44Oa44O844K45qSc57SiXG4gICAqL1xuICBzdGF0aWMgc2VhcmNoUGFnZXMoXG4gICAgc2l0ZTogU2l0ZSxcbiAgICBwYXJzZVVzZXI6IChlbGVtZW50OiBjaGVlcmlvLkNoZWVyaW88QW55Tm9kZT4pID0+IEFic3RyYWN0VXNlcixcbiAgICBxdWVyeTogU2VhcmNoUGFnZXNRdWVyeSB8IG51bGwgPSBudWxsXG4gICk6IFdpa2lkb3RSZXN1bHRBc3luYzxQYWdlQ29sbGVjdGlvbj4ge1xuICAgIHJldHVybiBmcm9tUHJvbWlzZShcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHEgPSBxdWVyeSA/PyBuZXcgU2VhcmNoUGFnZXNRdWVyeSgpO1xuICAgICAgICBjb25zdCBxdWVyeURpY3QgPSBxLmFzRGljdCgpO1xuXG4gICAgICAgIC8vIOODouOCuOODpeODvOODq+ODnOODh+OCo+eUn+aIkFxuICAgICAgICBjb25zdCBtb2R1bGVCb2R5ID0gYFtbZGl2IGNsYXNzPVwicGFnZVwiXV1cXG4ke0RFRkFVTFRfTU9EVUxFX0JPRFkubWFwKFxuICAgICAgICAgIChrZXkpID0+XG4gICAgICAgICAgICBgW1tzcGFuIGNsYXNzPVwic2V0ICR7a2V5fVwiXV1bW3NwYW4gY2xhc3M9XCJuYW1lXCJdXSAke2tleX0gW1svc3Bhbl1dW1tzcGFuIGNsYXNzPVwidmFsdWVcIl1dICUlJHtrZXl9JSUgW1svc3Bhbl1dW1svc3Bhbl1dYFxuICAgICAgICApLmpvaW4oJycpfVxcbltbL2Rpdl1dYDtcblxuICAgICAgICBjb25zdCByZXF1ZXN0Qm9keSA9IHtcbiAgICAgICAgICAuLi5xdWVyeURpY3QsXG4gICAgICAgICAgbW9kdWxlTmFtZTogJ2xpc3QvTGlzdFBhZ2VzTW9kdWxlJyxcbiAgICAgICAgICBtb2R1bGVfYm9keTogbW9kdWxlQm9keSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzaXRlLmFtY1JlcXVlc3QoW3JlcXVlc3RCb2R5XSk7XG4gICAgICAgIGlmIChyZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIGlmIChyZXN1bHQuZXJyb3IubWVzc2FnZS5pbmNsdWRlcygnbm90X29rJykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBGb3JiaWRkZW5FcnJvcignRmFpbGVkIHRvIGdldCBwYWdlcywgdGFyZ2V0IHNpdGUgbWF5IGJlIHByaXZhdGUnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmlyc3RSZXNwb25zZSA9IHJlc3VsdC52YWx1ZVswXTtcbiAgICAgICAgY29uc3QgYm9keSA9IFN0cmluZyhmaXJzdFJlc3BvbnNlPy5ib2R5ID8/ICcnKTtcbiAgICAgICAgY29uc3QgJGZpcnN0ID0gY2hlZXJpby5sb2FkKGJvZHkpO1xuXG4gICAgICAgIGxldCB0b3RhbCA9IDE7XG4gICAgICAgIGNvbnN0IGh0bWxCb2RpZXM6IGNoZWVyaW8uQ2hlZXJpb0FQSVtdID0gWyRmaXJzdF07XG5cbiAgICAgICAgLy8g44Oa44O844K444ON44O844K344On44Oz56K66KqNXG4gICAgICAgIGNvbnN0IHBhZ2VyRWxlbWVudCA9ICRmaXJzdCgnZGl2LnBhZ2VyJyk7XG4gICAgICAgIGlmIChwYWdlckVsZW1lbnQubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGNvbnN0IGxhc3RQYWdlckVsZW1lbnRzID0gJGZpcnN0KCdkaXYucGFnZXIgc3Bhbi50YXJnZXQnKTtcbiAgICAgICAgICBpZiAobGFzdFBhZ2VyRWxlbWVudHMubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICAgIGNvbnN0IHNlY29uZExhc3RQYWdlciA9ICRmaXJzdChsYXN0UGFnZXJFbGVtZW50c1tsYXN0UGFnZXJFbGVtZW50cy5sZW5ndGggLSAyXSk7XG4gICAgICAgICAgICBjb25zdCBsYXN0UGFnZXJMaW5rID0gc2Vjb25kTGFzdFBhZ2VyLmZpbmQoJ2EnKTtcbiAgICAgICAgICAgIGlmIChsYXN0UGFnZXJMaW5rLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgdG90YWwgPSBOdW1iZXIucGFyc2VJbnQobGFzdFBhZ2VyTGluay50ZXh0KCkudHJpbSgpLCAxMCkgfHwgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyDov73liqDjg5rjg7zjgrjlj5blvpdcbiAgICAgICAgaWYgKHRvdGFsID4gMSkge1xuICAgICAgICAgIGNvbnN0IGFkZGl0aW9uYWxCb2RpZXM6IEFNQ1JlcXVlc3RCb2R5W10gPSBbXTtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHRvdGFsOyBpKyspIHtcbiAgICAgICAgICAgIGFkZGl0aW9uYWxCb2RpZXMucHVzaCh7XG4gICAgICAgICAgICAgIC4uLnF1ZXJ5RGljdCxcbiAgICAgICAgICAgICAgbW9kdWxlTmFtZTogJ2xpc3QvTGlzdFBhZ2VzTW9kdWxlJyxcbiAgICAgICAgICAgICAgbW9kdWxlX2JvZHk6IG1vZHVsZUJvZHksXG4gICAgICAgICAgICAgIG9mZnNldDogaSAqIChxLnBlclBhZ2UgPz8gREVGQVVMVF9QRVJfUEFHRSksXG4gICAgICAgICAgICB9IGFzIEFNQ1JlcXVlc3RCb2R5KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBhZGRpdGlvbmFsUmVzdWx0cyA9IGF3YWl0IHNpdGUuYW1jUmVxdWVzdChhZGRpdGlvbmFsQm9kaWVzKTtcbiAgICAgICAgICBpZiAoYWRkaXRpb25hbFJlc3VsdHMuaXNFcnIoKSkge1xuICAgICAgICAgICAgdGhyb3cgYWRkaXRpb25hbFJlc3VsdHMuZXJyb3I7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZm9yIChjb25zdCByZXNwb25zZSBvZiBhZGRpdGlvbmFsUmVzdWx0cy52YWx1ZSkge1xuICAgICAgICAgICAgY29uc3QgcmVzcEJvZHkgPSBTdHJpbmcocmVzcG9uc2U/LmJvZHkgPz8gJycpO1xuICAgICAgICAgICAgaHRtbEJvZGllcy5wdXNoKGNoZWVyaW8ubG9hZChyZXNwQm9keSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOODkeODvOOCuVxuICAgICAgICBjb25zdCBwYWdlczogUGFnZVtdID0gW107XG4gICAgICAgIGZvciAoY29uc3QgJGh0bWwgb2YgaHRtbEJvZGllcykge1xuICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IFBhZ2VDb2xsZWN0aW9uLnBhcnNlKHNpdGUsICRodG1sLCBwYXJzZVVzZXIpO1xuICAgICAgICAgIHBhZ2VzLnB1c2goLi4ucGFyc2VkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgUGFnZUNvbGxlY3Rpb24oc2l0ZSwgcGFnZXMpO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBGb3JiaWRkZW5FcnJvciB8fCBlcnJvciBpbnN0YW5jZW9mIE5vdEZvdW5kRXhjZXB0aW9uKSB7XG4gICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gc2VhcmNoIHBhZ2VzOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg5rjg7zjgrjjgpLkvZzmiJDjgb7jgZ/jga/nt6jpm4ZcbiAgICovXG4gIHN0YXRpYyBjcmVhdGVPckVkaXQoXG4gICAgc2l0ZTogU2l0ZSxcbiAgICBmdWxsbmFtZTogc3RyaW5nLFxuICAgIG9wdGlvbnM6IHtcbiAgICAgIHBhZ2VJZD86IG51bWJlciB8IG51bGw7XG4gICAgICB0aXRsZT86IHN0cmluZztcbiAgICAgIHNvdXJjZT86IHN0cmluZztcbiAgICAgIGNvbW1lbnQ/OiBzdHJpbmc7XG4gICAgICBmb3JjZUVkaXQ/OiBib29sZWFuO1xuICAgICAgcmFpc2VPbkV4aXN0cz86IGJvb2xlYW47XG4gICAgfSA9IHt9XG4gICk6IFdpa2lkb3RSZXN1bHRBc3luYzx2b2lkPiB7XG4gICAgY29uc3QgbG9naW5SZXN1bHQgPSBzaXRlLmNsaWVudC5yZXF1aXJlTG9naW4oKTtcbiAgICBpZiAobG9naW5SZXN1bHQuaXNFcnIoKSkge1xuICAgICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgICBQcm9taXNlLnJlamVjdChsb2dpblJlc3VsdC5lcnJvciksXG4gICAgICAgICgpID0+IG5ldyBMb2dpblJlcXVpcmVkRXJyb3IoJ0xvZ2luIHJlcXVpcmVkIHRvIGNyZWF0ZS9lZGl0IHBhZ2UnKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgcGFnZUlkID0gbnVsbCxcbiAgICAgICAgICB0aXRsZSA9ICcnLFxuICAgICAgICAgIHNvdXJjZSA9ICcnLFxuICAgICAgICAgIGNvbW1lbnQgPSAnJyxcbiAgICAgICAgICBmb3JjZUVkaXQgPSBmYWxzZSxcbiAgICAgICAgICByYWlzZU9uRXhpc3RzID0gZmFsc2UsXG4gICAgICAgIH0gPSBvcHRpb25zO1xuXG4gICAgICAgIC8vIOODmuODvOOCuOODreODg+OCr+WPluW+l1xuICAgICAgICBjb25zdCBsb2NrUmVxdWVzdEJvZHk6IEFNQ1JlcXVlc3RCb2R5ID0ge1xuICAgICAgICAgIG1vZGU6ICdwYWdlJyxcbiAgICAgICAgICB3aWtpX3BhZ2U6IGZ1bGxuYW1lLFxuICAgICAgICAgIG1vZHVsZU5hbWU6ICdlZGl0L1BhZ2VFZGl0TW9kdWxlJyxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGZvcmNlRWRpdCkge1xuICAgICAgICAgIGxvY2tSZXF1ZXN0Qm9keS5mb3JjZV9sb2NrID0gJ3llcyc7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBsb2NrUmVzdWx0ID0gYXdhaXQgc2l0ZS5hbWNSZXF1ZXN0KFtsb2NrUmVxdWVzdEJvZHldKTtcbiAgICAgICAgaWYgKGxvY2tSZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IGxvY2tSZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBsb2NrUmVzcG9uc2UgPSBsb2NrUmVzdWx0LnZhbHVlWzBdO1xuICAgICAgICBpZiAobG9ja1Jlc3BvbnNlPy5sb2NrZWQgfHwgbG9ja1Jlc3BvbnNlPy5vdGhlcl9sb2Nrcykge1xuICAgICAgICAgIHRocm93IG5ldyBVbmV4cGVjdGVkRXJyb3IoYFBhZ2UgJHtmdWxsbmFtZX0gaXMgbG9ja2VkIG9yIG90aGVyIGxvY2tzIGV4aXN0YCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpc0V4aXN0ID0gJ3BhZ2VfcmV2aXNpb25faWQnIGluIChsb2NrUmVzcG9uc2UgPz8ge30pO1xuXG4gICAgICAgIGlmIChyYWlzZU9uRXhpc3RzICYmIGlzRXhpc3QpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVGFyZ2V0RXhpc3RzRXJyb3IoYFBhZ2UgJHtmdWxsbmFtZX0gYWxyZWFkeSBleGlzdHNgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0V4aXN0ICYmIHBhZ2VJZCA9PT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IG5ldyBVbmV4cGVjdGVkRXJyb3IoJ3BhZ2VfaWQgbXVzdCBiZSBzcGVjaWZpZWQgd2hlbiBlZGl0aW5nIGV4aXN0aW5nIHBhZ2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxvY2tJZCA9IFN0cmluZyhsb2NrUmVzcG9uc2U/LmxvY2tfaWQgPz8gJycpO1xuICAgICAgICBjb25zdCBsb2NrU2VjcmV0ID0gU3RyaW5nKGxvY2tSZXNwb25zZT8ubG9ja19zZWNyZXQgPz8gJycpO1xuICAgICAgICBjb25zdCBwYWdlUmV2aXNpb25JZCA9IFN0cmluZyhsb2NrUmVzcG9uc2U/LnBhZ2VfcmV2aXNpb25faWQgPz8gJycpO1xuXG4gICAgICAgIC8vIOODmuODvOOCuOS/neWtmFxuICAgICAgICBjb25zdCBlZGl0UmVxdWVzdEJvZHk6IEFNQ1JlcXVlc3RCb2R5ID0ge1xuICAgICAgICAgIGFjdGlvbjogJ1dpa2lQYWdlQWN0aW9uJyxcbiAgICAgICAgICBldmVudDogJ3NhdmVQYWdlJyxcbiAgICAgICAgICBtb2R1bGVOYW1lOiAnRW1wdHknLFxuICAgICAgICAgIG1vZGU6ICdwYWdlJyxcbiAgICAgICAgICBsb2NrX2lkOiBsb2NrSWQsXG4gICAgICAgICAgbG9ja19zZWNyZXQ6IGxvY2tTZWNyZXQsXG4gICAgICAgICAgcmV2aXNpb25faWQ6IHBhZ2VSZXZpc2lvbklkLFxuICAgICAgICAgIHdpa2lfcGFnZTogZnVsbG5hbWUsXG4gICAgICAgICAgcGFnZV9pZDogcGFnZUlkID8/ICcnLFxuICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgIHNvdXJjZSxcbiAgICAgICAgICBjb21tZW50czogY29tbWVudCxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBlZGl0UmVzdWx0ID0gYXdhaXQgc2l0ZS5hbWNSZXF1ZXN0KFtlZGl0UmVxdWVzdEJvZHldKTtcbiAgICAgICAgaWYgKGVkaXRSZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IGVkaXRSZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0pKCksXG4gICAgICAoZXJyb3IpID0+IHtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgVGFyZ2V0RXhpc3RzRXJyb3IgfHwgZXJyb3IgaW5zdGFuY2VvZiBMb2dpblJlcXVpcmVkRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBVbmV4cGVjdGVkRXJyb3IoYEZhaWxlZCB0byBjcmVhdGUvZWRpdCBwYWdlOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgeyBTZWFyY2hQYWdlc1F1ZXJ5IH07XG4iLAogICAgImltcG9ydCAqIGFzIGNoZWVyaW8gZnJvbSAnY2hlZXJpbyc7XG5pbXBvcnQgeyBVbmV4cGVjdGVkRXJyb3IgfSBmcm9tICcuLi8uLi9jb21tb24vZXJyb3JzJztcbmltcG9ydCB7IGZyb21Qcm9taXNlLCB0eXBlIFdpa2lkb3RSZXN1bHRBc3luYyB9IGZyb20gJy4uLy4uL2NvbW1vbi90eXBlcyc7XG5pbXBvcnQgdHlwZSB7IFBhZ2UgfSBmcm9tICcuL3BhZ2UnO1xuXG4vKipcbiAqIOODmuODvOOCuOODleOCoeOCpOODq+ODh+ODvOOCv1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFBhZ2VGaWxlRGF0YSB7XG4gIHBhZ2U6IFBhZ2U7XG4gIGlkOiBudW1iZXI7XG4gIG5hbWU6IHN0cmluZztcbiAgdXJsOiBzdHJpbmc7XG4gIG1pbWVUeXBlOiBzdHJpbmc7XG4gIHNpemU6IG51bWJlcjtcbn1cblxuLyoqXG4gKiDjg5rjg7zjgrjmt7vku5jjg5XjgqHjgqTjg6tcbiAqL1xuZXhwb3J0IGNsYXNzIFBhZ2VGaWxlIHtcbiAgcHVibGljIHJlYWRvbmx5IHBhZ2U6IFBhZ2U7XG4gIHB1YmxpYyByZWFkb25seSBpZDogbnVtYmVyO1xuICBwdWJsaWMgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgdXJsOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBtaW1lVHlwZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgc2l6ZTogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE6IFBhZ2VGaWxlRGF0YSkge1xuICAgIHRoaXMucGFnZSA9IGRhdGEucGFnZTtcbiAgICB0aGlzLmlkID0gZGF0YS5pZDtcbiAgICB0aGlzLm5hbWUgPSBkYXRhLm5hbWU7XG4gICAgdGhpcy51cmwgPSBkYXRhLnVybDtcbiAgICB0aGlzLm1pbWVUeXBlID0gZGF0YS5taW1lVHlwZTtcbiAgICB0aGlzLnNpemUgPSBkYXRhLnNpemU7XG4gIH1cblxuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBgUGFnZUZpbGUoaWQ9JHt0aGlzLmlkfSwgbmFtZT0ke3RoaXMubmFtZX0sIHNpemU9JHt0aGlzLnNpemV9KWA7XG4gIH1cbn1cblxuLyoqXG4gKiDjg5rjg7zjgrjjg5XjgqHjgqTjg6vjgrPjg6zjgq/jgrfjg6fjg7NcbiAqL1xuZXhwb3J0IGNsYXNzIFBhZ2VGaWxlQ29sbGVjdGlvbiBleHRlbmRzIEFycmF5PFBhZ2VGaWxlPiB7XG4gIHB1YmxpYyByZWFkb25seSBwYWdlOiBQYWdlO1xuXG4gIGNvbnN0cnVjdG9yKHBhZ2U6IFBhZ2UsIGZpbGVzPzogUGFnZUZpbGVbXSkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5wYWdlID0gcGFnZTtcbiAgICBpZiAoZmlsZXMpIHtcbiAgICAgIHRoaXMucHVzaCguLi5maWxlcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIElE44Gn5qSc57SiXG4gICAqL1xuICBmaW5kQnlJZChpZDogbnVtYmVyKTogUGFnZUZpbGUgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmZpbmQoKGZpbGUpID0+IGZpbGUuaWQgPT09IGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDlkI3liY3jgafmpJzntKJcbiAgICovXG4gIGZpbmRCeU5hbWUobmFtZTogc3RyaW5nKTogUGFnZUZpbGUgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmZpbmQoKGZpbGUpID0+IGZpbGUubmFtZSA9PT0gbmFtZSk7XG4gIH1cblxuICAvKipcbiAgICog44K144Kk44K65paH5a2X5YiX44KS44OQ44Kk44OI5pWw44Gr5aSJ5o+bXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBwYXJzZVNpemUoc2l6ZVRleHQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgY29uc3QgdGV4dCA9IHNpemVUZXh0LnRyaW0oKTtcbiAgICBpZiAodGV4dC5pbmNsdWRlcygnQnl0ZXMnKSkge1xuICAgICAgcmV0dXJuIE1hdGguZmxvb3IoTnVtYmVyLnBhcnNlRmxvYXQodGV4dC5yZXBsYWNlKCdCeXRlcycsICcnKS50cmltKCkpKTtcbiAgICB9XG4gICAgaWYgKHRleHQuaW5jbHVkZXMoJ2tCJykpIHtcbiAgICAgIHJldHVybiBNYXRoLmZsb29yKE51bWJlci5wYXJzZUZsb2F0KHRleHQucmVwbGFjZSgna0InLCAnJykudHJpbSgpKSAqIDEwMDApO1xuICAgIH1cbiAgICBpZiAodGV4dC5pbmNsdWRlcygnTUInKSkge1xuICAgICAgcmV0dXJuIE1hdGguZmxvb3IoTnVtYmVyLnBhcnNlRmxvYXQodGV4dC5yZXBsYWNlKCdNQicsICcnKS50cmltKCkpICogMTAwMDAwMCk7XG4gICAgfVxuICAgIGlmICh0ZXh0LmluY2x1ZGVzKCdHQicpKSB7XG4gICAgICByZXR1cm4gTWF0aC5mbG9vcihOdW1iZXIucGFyc2VGbG9hdCh0ZXh0LnJlcGxhY2UoJ0dCJywgJycpLnRyaW0oKSkgKiAxMDAwMDAwMDAwKTtcbiAgICB9XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICAvKipcbiAgICog44Oa44O844K444Gr5re75LuY44GV44KM44Gf44OV44Kh44Kk44Or5LiA6Kan44KS5Y+W5b6X44GZ44KLXG4gICAqL1xuICBzdGF0aWMgYWNxdWlyZShwYWdlOiBQYWdlKTogV2lraWRvdFJlc3VsdEFzeW5jPFBhZ2VGaWxlQ29sbGVjdGlvbj4ge1xuICAgIGlmIChwYWdlLmlkID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAgIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcignUGFnZSBJRCBub3QgYWNxdWlyZWQnKSksXG4gICAgICAgICgpID0+IG5ldyBVbmV4cGVjdGVkRXJyb3IoJ1BhZ2UgSUQgbXVzdCBiZSBhY3F1aXJlZCBiZWZvcmUgZ2V0dGluZyBmaWxlcycpXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHBhZ2VJZCA9IHBhZ2UuaWQ7XG5cbiAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwYWdlLnNpdGUuYW1jUmVxdWVzdChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ2ZpbGVzL1BhZ2VGaWxlc01vZHVsZScsXG4gICAgICAgICAgICBwYWdlX2lkOiBwYWdlSWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSByZXN1bHQudmFsdWVbMF07XG4gICAgICAgIGlmICghcmVzcG9uc2UpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVW5leHBlY3RlZEVycm9yKCdFbXB0eSByZXNwb25zZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaHRtbCA9IFN0cmluZyhyZXNwb25zZS5ib2R5ID8/ICcnKTtcbiAgICAgICAgY29uc3QgJCA9IGNoZWVyaW8ubG9hZChodG1sKTtcblxuICAgICAgICBjb25zdCBmaWxlc1RhYmxlID0gJCgndGFibGUucGFnZS1maWxlcycpO1xuICAgICAgICBpZiAoZmlsZXNUYWJsZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFBhZ2VGaWxlQ29sbGVjdGlvbihwYWdlLCBbXSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmaWxlczogUGFnZUZpbGVbXSA9IFtdO1xuXG4gICAgICAgIGZpbGVzVGFibGUuZmluZChcInRib2R5IHRyW2lkXj0nZmlsZS1yb3ctJ11cIikuZWFjaCgoX2ksIHJvdykgPT4ge1xuICAgICAgICAgIGNvbnN0IHJvd0lkID0gJChyb3cpLmF0dHIoJ2lkJyk7XG4gICAgICAgICAgaWYgKCFyb3dJZCkgcmV0dXJuO1xuXG4gICAgICAgICAgY29uc3QgZmlsZUlkID0gTnVtYmVyLnBhcnNlSW50KHJvd0lkLnJlcGxhY2UoJ2ZpbGUtcm93LScsICcnKSwgMTApO1xuICAgICAgICAgIGNvbnN0IHRkcyA9ICQocm93KS5maW5kKCd0ZCcpO1xuICAgICAgICAgIGlmICh0ZHMubGVuZ3RoIDwgMykgcmV0dXJuO1xuXG4gICAgICAgICAgY29uc3QgbGlua0VsZW0gPSAkKHRkc1swXSkuZmluZCgnYScpO1xuICAgICAgICAgIGlmIChsaW5rRWxlbS5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgICAgICAgIGNvbnN0IG5hbWUgPSBsaW5rRWxlbS50ZXh0KCkudHJpbSgpO1xuICAgICAgICAgIGNvbnN0IGhyZWYgPSBsaW5rRWxlbS5hdHRyKCdocmVmJykgPz8gJyc7XG4gICAgICAgICAgY29uc3QgdXJsID0gYCR7cGFnZS5zaXRlLmdldEJhc2VVcmwoKX0ke2hyZWZ9YDtcblxuICAgICAgICAgIGNvbnN0IG1pbWVFbGVtID0gJCh0ZHNbMV0pLmZpbmQoJ3NwYW4nKTtcbiAgICAgICAgICBjb25zdCBtaW1lVHlwZSA9IG1pbWVFbGVtLmF0dHIoJ3RpdGxlJykgPz8gJyc7XG5cbiAgICAgICAgICBjb25zdCBzaXplVGV4dCA9ICQodGRzWzJdKS50ZXh0KCkudHJpbSgpO1xuICAgICAgICAgIGNvbnN0IHNpemUgPSBQYWdlRmlsZUNvbGxlY3Rpb24ucGFyc2VTaXplKHNpemVUZXh0KTtcblxuICAgICAgICAgIGZpbGVzLnB1c2goXG4gICAgICAgICAgICBuZXcgUGFnZUZpbGUoe1xuICAgICAgICAgICAgICBwYWdlLFxuICAgICAgICAgICAgICBpZDogZmlsZUlkLFxuICAgICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgICB1cmwsXG4gICAgICAgICAgICAgIG1pbWVUeXBlLFxuICAgICAgICAgICAgICBzaXplLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gbmV3IFBhZ2VGaWxlQ29sbGVjdGlvbihwYWdlLCBmaWxlcyk7XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gYWNxdWlyZSBmaWxlczogJHtTdHJpbmcoZXJyb3IpfWApXG4gICAgKTtcbiAgfVxufVxuIiwKICAgICJpbXBvcnQgKiBhcyBjaGVlcmlvIGZyb20gJ2NoZWVyaW8nO1xuaW1wb3J0IHsgTG9naW5SZXF1aXJlZEVycm9yLCBOb0VsZW1lbnRFcnJvciwgVW5leHBlY3RlZEVycm9yIH0gZnJvbSAnLi4vLi4vY29tbW9uL2Vycm9ycyc7XG5pbXBvcnQgeyBmcm9tUHJvbWlzZSwgdHlwZSBXaWtpZG90UmVzdWx0QXN5bmMgfSBmcm9tICcuLi8uLi9jb21tb24vdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBQYWdlUmVmIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG4vKipcbiAqIOODmuODvOOCuOODoeOCv+OCv+OCsOODh+ODvOOCv1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFBhZ2VNZXRhRGF0YSB7XG4gIHBhZ2U6IFBhZ2VSZWY7XG4gIG5hbWU6IHN0cmluZztcbiAgY29udGVudDogc3RyaW5nO1xufVxuXG4vKipcbiAqIOODmuODvOOCuOODoeOCv+OCv+OCsFxuICovXG5leHBvcnQgY2xhc3MgUGFnZU1ldGEge1xuICBwdWJsaWMgcmVhZG9ubHkgcGFnZTogUGFnZVJlZjtcbiAgcHVibGljIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgcHVibGljIGNvbnRlbnQ6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihkYXRhOiBQYWdlTWV0YURhdGEpIHtcbiAgICB0aGlzLnBhZ2UgPSBkYXRhLnBhZ2U7XG4gICAgdGhpcy5uYW1lID0gZGF0YS5uYW1lO1xuICAgIHRoaXMuY29udGVudCA9IGRhdGEuY29udGVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg6Hjgr/jgr/jgrDjga7lgKTjgpLmm7TmlrDjgZnjgotcbiAgICogQHBhcmFtIGNvbnRlbnQgLSDmlrDjgZfjgYTlgKRcbiAgICovXG4gIHVwZGF0ZShjb250ZW50OiBzdHJpbmcpOiBXaWtpZG90UmVzdWx0QXN5bmM8dm9pZD4ge1xuICAgIHJldHVybiBQYWdlTWV0YUNvbGxlY3Rpb24uc2V0TWV0YSh0aGlzLnBhZ2UsIHRoaXMubmFtZSwgY29udGVudCk7XG4gIH1cblxuICAvKipcbiAgICog44Oh44K/44K/44Kw44KS5YmK6Zmk44GZ44KLXG4gICAqL1xuICBkZWxldGUoKTogV2lraWRvdFJlc3VsdEFzeW5jPHZvaWQ+IHtcbiAgICByZXR1cm4gUGFnZU1ldGFDb2xsZWN0aW9uLmRlbGV0ZU1ldGEodGhpcy5wYWdlLCB0aGlzLm5hbWUpO1xuICB9XG5cbiAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYFBhZ2VNZXRhKG5hbWU9JHt0aGlzLm5hbWV9LCBjb250ZW50PSR7dGhpcy5jb250ZW50fSlgO1xuICB9XG59XG5cbi8qKlxuICog44Oa44O844K444Oh44K/44K/44Kw44Kz44Os44Kv44K344On44OzXG4gKi9cbmV4cG9ydCBjbGFzcyBQYWdlTWV0YUNvbGxlY3Rpb24gZXh0ZW5kcyBBcnJheTxQYWdlTWV0YT4ge1xuICBwdWJsaWMgcmVhZG9ubHkgcGFnZTogUGFnZVJlZjtcblxuICBjb25zdHJ1Y3RvcihwYWdlOiBQYWdlUmVmLCBtZXRhcz86IFBhZ2VNZXRhW10pIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMucGFnZSA9IHBhZ2U7XG4gICAgaWYgKG1ldGFzKSB7XG4gICAgICB0aGlzLnB1c2goLi4ubWV0YXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDlkI3liY3jgafmpJzntKJcbiAgICogQHBhcmFtIG5hbWUgLSDjg6Hjgr/jgr/jgrDlkI1cbiAgICogQHJldHVybnMg44Oh44K/44K/44Kw77yI5a2Y5Zyo44GX44Gq44GE5aC05ZCI44GvdW5kZWZpbmVk77yJXG4gICAqL1xuICBmaW5kQnlOYW1lKG5hbWU6IHN0cmluZyk6IFBhZ2VNZXRhIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5maW5kKChtZXRhKSA9PiBtZXRhLm5hbWUgPT09IG5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIOODmuODvOOCuOOBruODoeOCv+OCv+OCsOOCkuWPluW+l+OBmeOCi1xuICAgKiBAcGFyYW0gcGFnZSAtIOODmuODvOOCuOWPgueFp1xuICAgKiBAcmV0dXJucyDjg6Hjgr/jgr/jgrDjgrPjg6zjgq/jgrfjg6fjg7NcbiAgICovXG4gIHN0YXRpYyBhY3F1aXJlKHBhZ2U6IFBhZ2VSZWYpOiBXaWtpZG90UmVzdWx0QXN5bmM8UGFnZU1ldGFDb2xsZWN0aW9uPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGFnZS5zaXRlLmFtY1JlcXVlc3QoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1vZHVsZU5hbWU6ICdlZGl0L0VkaXRNZXRhTW9kdWxlJyxcbiAgICAgICAgICAgIHBhZ2VfaWQ6IHBhZ2UuaWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSByZXN1bHQudmFsdWVbMF07XG4gICAgICAgIGlmICghcmVzcG9uc2UpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTm9FbGVtZW50RXJyb3IoJ0VtcHR5IHJlc3BvbnNlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBodG1sID0gU3RyaW5nKHJlc3BvbnNlLmJvZHkgPz8gJycpO1xuICAgICAgICBjb25zdCAkID0gY2hlZXJpby5sb2FkKGh0bWwpO1xuICAgICAgICBjb25zdCBtZXRhczogUGFnZU1ldGFbXSA9IFtdO1xuXG4gICAgICAgIC8vIOODoeOCv+OCv+OCsOODhuODvOODluODq+OCkuODkeODvOOCuVxuICAgICAgICAkKCd0YWJsZS5tZXRhLXRhYmxlIHRyJykuZWFjaCgoX2ksIGVsZW0pID0+IHtcbiAgICAgICAgICBjb25zdCAkcm93ID0gJChlbGVtKTtcbiAgICAgICAgICBjb25zdCAkY2VsbHMgPSAkcm93LmZpbmQoJ3RkJyk7XG4gICAgICAgICAgaWYgKCRjZWxscy5sZW5ndGggPCAyKSByZXR1cm47XG5cbiAgICAgICAgICBjb25zdCBuYW1lID0gJCgkY2VsbHNbMF0pLnRleHQoKS50cmltKCk7XG4gICAgICAgICAgY29uc3QgY29udGVudCA9ICQoJGNlbGxzWzFdKS50ZXh0KCkudHJpbSgpO1xuXG4gICAgICAgICAgaWYgKG5hbWUpIHtcbiAgICAgICAgICAgIG1ldGFzLnB1c2goXG4gICAgICAgICAgICAgIG5ldyBQYWdlTWV0YSh7XG4gICAgICAgICAgICAgICAgcGFnZSxcbiAgICAgICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgICAgIGNvbnRlbnQsXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQYWdlTWV0YUNvbGxlY3Rpb24ocGFnZSwgbWV0YXMpO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvcikge1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGFjcXVpcmUgcGFnZSBtZXRhczogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICog44Oh44K/44K/44Kw44KS6Kit5a6a44GZ44KLXG4gICAqIEBwYXJhbSBwYWdlIC0g44Oa44O844K45Y+C54WnXG4gICAqIEBwYXJhbSBuYW1lIC0g44Oh44K/44K/44Kw5ZCNXG4gICAqIEBwYXJhbSBjb250ZW50IC0g44Oh44K/44K/44Kw44Gu5YCkXG4gICAqL1xuICBzdGF0aWMgc2V0TWV0YShwYWdlOiBQYWdlUmVmLCBuYW1lOiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IFdpa2lkb3RSZXN1bHRBc3luYzx2b2lkPiB7XG4gICAgY29uc3QgbG9naW5SZXN1bHQgPSBwYWdlLnNpdGUuY2xpZW50LnJlcXVpcmVMb2dpbigpO1xuICAgIGlmIChsb2dpblJlc3VsdC5pc0VycigpKSB7XG4gICAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAgIFByb21pc2UucmVqZWN0KGxvZ2luUmVzdWx0LmVycm9yKSxcbiAgICAgICAgKCkgPT4gbmV3IExvZ2luUmVxdWlyZWRFcnJvcignTG9naW4gcmVxdWlyZWQgdG8gc2V0IG1ldGEgdGFnJylcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGFnZS5zaXRlLmFtY1JlcXVlc3QoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFjdGlvbjogJ1dpa2lQYWdlQWN0aW9uJyxcbiAgICAgICAgICAgIGV2ZW50OiAnc2F2ZU1ldGFUYWcnLFxuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ0VtcHR5JyxcbiAgICAgICAgICAgIHBhZ2VfaWQ6IHBhZ2UuaWQsXG4gICAgICAgICAgICBtZXRhX25hbWU6IG5hbWUsXG4gICAgICAgICAgICBtZXRhX2NvbnRlbnQ6IGNvbnRlbnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIExvZ2luUmVxdWlyZWRFcnJvcikge1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIHNldCBtZXRhIHRhZzogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICog44Oh44K/44K/44Kw44KS5YmK6Zmk44GZ44KLXG4gICAqIEBwYXJhbSBwYWdlIC0g44Oa44O844K45Y+C54WnXG4gICAqIEBwYXJhbSBuYW1lIC0g44Oh44K/44K/44Kw5ZCNXG4gICAqL1xuICBzdGF0aWMgZGVsZXRlTWV0YShwYWdlOiBQYWdlUmVmLCBuYW1lOiBzdHJpbmcpOiBXaWtpZG90UmVzdWx0QXN5bmM8dm9pZD4ge1xuICAgIGNvbnN0IGxvZ2luUmVzdWx0ID0gcGFnZS5zaXRlLmNsaWVudC5yZXF1aXJlTG9naW4oKTtcbiAgICBpZiAobG9naW5SZXN1bHQuaXNFcnIoKSkge1xuICAgICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgICBQcm9taXNlLnJlamVjdChsb2dpblJlc3VsdC5lcnJvciksXG4gICAgICAgICgpID0+IG5ldyBMb2dpblJlcXVpcmVkRXJyb3IoJ0xvZ2luIHJlcXVpcmVkIHRvIGRlbGV0ZSBtZXRhIHRhZycpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBmcm9tUHJvbWlzZShcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBhZ2Uuc2l0ZS5hbWNSZXF1ZXN0KFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhY3Rpb246ICdXaWtpUGFnZUFjdGlvbicsXG4gICAgICAgICAgICBldmVudDogJ2RlbGV0ZU1ldGFUYWcnLFxuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ0VtcHR5JyxcbiAgICAgICAgICAgIHBhZ2VfaWQ6IHBhZ2UuaWQsXG4gICAgICAgICAgICBtZXRhX25hbWU6IG5hbWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIExvZ2luUmVxdWlyZWRFcnJvcikge1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGRlbGV0ZSBtZXRhIHRhZzogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cbn1cbiIsCiAgICAiaW1wb3J0IHR5cGUgeyBQYWdlIH0gZnJvbSAnLi9wYWdlJztcblxuLyoqXG4gKiDjg5rjg7zjgrjjgr3jg7zjgrnjg4fjg7zjgr9cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYWdlU291cmNlRGF0YSB7XG4gIHBhZ2U6IFBhZ2U7XG4gIHdpa2lUZXh0OiBzdHJpbmc7XG59XG5cbi8qKlxuICog44Oa44O844K444Gu44K944O844K544Kz44O844OJ77yIV2lraWRvdOiomOazle+8iVxuICovXG5leHBvcnQgY2xhc3MgUGFnZVNvdXJjZSB7XG4gIC8qKiDjgr3jg7zjgrnjgYzlsZ7jgZnjgovjg5rjg7zjgrggKi9cbiAgcHVibGljIHJlYWRvbmx5IHBhZ2U6IFBhZ2U7XG5cbiAgLyoqIOOCveODvOOCueOCs+ODvOODie+8iFdpa2lkb3ToqJjms5XvvIkgKi9cbiAgcHVibGljIHJlYWRvbmx5IHdpa2lUZXh0OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoZGF0YTogUGFnZVNvdXJjZURhdGEpIHtcbiAgICB0aGlzLnBhZ2UgPSBkYXRhLnBhZ2U7XG4gICAgdGhpcy53aWtpVGV4dCA9IGRhdGEud2lraVRleHQ7XG4gIH1cblxuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBgUGFnZVNvdXJjZShwYWdlPSR7dGhpcy5wYWdlLmZ1bGxuYW1lfSwgbGVuZ3RoPSR7dGhpcy53aWtpVGV4dC5sZW5ndGh9KWA7XG4gIH1cbn1cbiIsCiAgICAiaW1wb3J0IHR5cGUgeyBBYnN0cmFjdFVzZXIgfSBmcm9tICcuLi91c2VyJztcbmltcG9ydCB0eXBlIHsgUGFnZSB9IGZyb20gJy4vcGFnZSc7XG5cbi8qKlxuICog44Oa44O844K45oqV56Wo44OH44O844K/XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGFnZVZvdGVEYXRhIHtcbiAgcGFnZTogUGFnZTtcbiAgdXNlcjogQWJzdHJhY3RVc2VyO1xuICB2YWx1ZTogbnVtYmVyO1xufVxuXG4vKipcbiAqIOODmuODvOOCuOOBuOOBruaKleelqO+8iOODrOODvOODhuOCo+ODs+OCsO+8iVxuICovXG5leHBvcnQgY2xhc3MgUGFnZVZvdGUge1xuICAvKiog5oqV56Wo44GM5bGe44GZ44KL44Oa44O844K4ICovXG4gIHB1YmxpYyByZWFkb25seSBwYWdlOiBQYWdlO1xuXG4gIC8qKiDmipXnpajjgZfjgZ/jg6bjg7zjgrbjg7wgKi9cbiAgcHVibGljIHJlYWRvbmx5IHVzZXI6IEFic3RyYWN0VXNlcjtcblxuICAvKiog5oqV56Wo5YCk77yIKzEvLTEg44G+44Gf44GvIOaVsOWApO+8iSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdmFsdWU6IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihkYXRhOiBQYWdlVm90ZURhdGEpIHtcbiAgICB0aGlzLnBhZ2UgPSBkYXRhLnBhZ2U7XG4gICAgdGhpcy51c2VyID0gZGF0YS51c2VyO1xuICAgIHRoaXMudmFsdWUgPSBkYXRhLnZhbHVlO1xuICB9XG5cbiAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYFBhZ2VWb3RlKHVzZXI9JHt0aGlzLnVzZXIubmFtZX0sIHZhbHVlPSR7dGhpcy52YWx1ZX0pYDtcbiAgfVxufVxuXG4vKipcbiAqIOODmuODvOOCuOaKleelqOOCs+ODrOOCr+OCt+ODp+ODs1xuICovXG5leHBvcnQgY2xhc3MgUGFnZVZvdGVDb2xsZWN0aW9uIGV4dGVuZHMgQXJyYXk8UGFnZVZvdGU+IHtcbiAgcHVibGljIHJlYWRvbmx5IHBhZ2U6IFBhZ2U7XG5cbiAgY29uc3RydWN0b3IocGFnZTogUGFnZSwgdm90ZXM/OiBQYWdlVm90ZVtdKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLnBhZ2UgPSBwYWdlO1xuICAgIGlmICh2b3Rlcykge1xuICAgICAgdGhpcy5wdXNoKC4uLnZvdGVzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog44Om44O844K244O844Gn5qSc57SiXG4gICAqIEBwYXJhbSB1c2VyIC0g5qSc57Si44GZ44KL44Om44O844K244O8XG4gICAqIEByZXR1cm5zIOaKleelqO+8iOWtmOWcqOOBl+OBquOBhOWgtOWQiOOBr3VuZGVmaW5lZO+8iVxuICAgKi9cbiAgZmluZEJ5VXNlcih1c2VyOiBBYnN0cmFjdFVzZXIpOiBQYWdlVm90ZSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZmluZCgodm90ZSkgPT4gdm90ZS51c2VyLmlkID09PSB1c2VyLmlkKTtcbiAgfVxufVxuIiwKICAgICJpbXBvcnQgdHlwZSB7IEFic3RyYWN0VXNlciB9IGZyb20gJy4uL3VzZXInO1xuXG4vKipcbiAqIOODmuODvOOCuOaknOe0ouOCr+OCqOODquOBruODkeODqeODoeODvOOCv1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNlYXJjaFBhZ2VzUXVlcnlQYXJhbXMge1xuICAvKiog44Oa44O844K444K/44Kk44OX77yI5L6LOiAnbm9ybWFsJywgJ2FkbWluJ++8iSAqL1xuICBwYWdldHlwZT86IHN0cmluZztcbiAgLyoqIOOCq+ODhuOCtOODquWQjSAqL1xuICBjYXRlZ29yeT86IHN0cmluZztcbiAgLyoqIOaknOe0ouWvvuixoeOCv+OCsO+8iEFOROadoeS7tu+8iSAqL1xuICB0YWdzPzogc3RyaW5nIHwgc3RyaW5nW107XG4gIC8qKiDopqrjg5rjg7zjgrjlkI0gKi9cbiAgcGFyZW50Pzogc3RyaW5nO1xuICAvKiog44Oq44Oz44Kv5YWI44Oa44O844K45ZCNICovXG4gIGxpbmtUbz86IHN0cmluZztcbiAgLyoqIOS9nOaIkOaXpeaZguadoeS7tiAqL1xuICBjcmVhdGVkQXQ/OiBzdHJpbmc7XG4gIC8qKiDmm7TmlrDml6XmmYLmnaHku7YgKi9cbiAgdXBkYXRlZEF0Pzogc3RyaW5nO1xuICAvKiog5L2c5oiQ6ICFICovXG4gIGNyZWF0ZWRCeT86IEFic3RyYWN0VXNlciB8IHN0cmluZztcbiAgLyoqIOODrOODvOODhuOCo+ODs+OCsOadoeS7tiAqL1xuICByYXRpbmc/OiBzdHJpbmc7XG4gIC8qKiDmipXnpajmlbDmnaHku7YgKi9cbiAgdm90ZXM/OiBzdHJpbmc7XG4gIC8qKiDjg5rjg7zjgrjlkI3mnaHku7YgKi9cbiAgbmFtZT86IHN0cmluZztcbiAgLyoqIOODleODq+ODjeODvOODoO+8iOWujOWFqOS4gOiHtO+8iSAqL1xuICBmdWxsbmFtZT86IHN0cmluZztcbiAgLyoqIOevhOWbsuaMh+WumiAqL1xuICByYW5nZT86IHN0cmluZztcbiAgLyoqIOOCveODvOODiOmghu+8iOS+izogJ2NyZWF0ZWRfYXQgZGVzYyfvvIkgKi9cbiAgb3JkZXI/OiBzdHJpbmc7XG4gIC8qKiDlj5blvpfplovlp4vkvY3nva4gKi9cbiAgb2Zmc2V0PzogbnVtYmVyO1xuICAvKiog5Y+W5b6X5Lu25pWw5Yi26ZmQICovXG4gIGxpbWl0PzogbnVtYmVyO1xuICAvKiogMeODmuODvOOCuOOBguOBn+OCiuS7tuaVsCAqL1xuICBwZXJQYWdlPzogbnVtYmVyO1xuICAvKiog5YCL5Yil6KGo56S6ICovXG4gIHNlcGFyYXRlPzogc3RyaW5nO1xuICAvKiog44Op44OD44OR44O86KGo56S6ICovXG4gIHdyYXBwZXI/OiBzdHJpbmc7XG59XG5cbi8qKlxuICog44OH44OV44Kp44Or44OI44GuMeODmuODvOOCuOOBguOBn+OCiuS7tuaVsFxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9QRVJfUEFHRSA9IDI1MDtcblxuLyoqXG4gKiDjg4fjg5Xjgqnjg6vjg4jjga7jg6Ljgrjjg6Xjg7zjg6vjg5zjg4fjgqPjg5XjgqPjg7zjg6vjg4lcbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfTU9EVUxFX0JPRFkgPSBbXG4gICdmdWxsbmFtZScsXG4gICdjYXRlZ29yeScsXG4gICduYW1lJyxcbiAgJ3RpdGxlJyxcbiAgJ2NyZWF0ZWRfYXQnLFxuICAnY3JlYXRlZF9ieV9saW5rZWQnLFxuICAndXBkYXRlZF9hdCcsXG4gICd1cGRhdGVkX2J5X2xpbmtlZCcsXG4gICdjb21tZW50ZWRfYXQnLFxuICAnY29tbWVudGVkX2J5X2xpbmtlZCcsXG4gICdwYXJlbnRfZnVsbG5hbWUnLFxuICAnY29tbWVudHMnLFxuICAnc2l6ZScsXG4gICdjaGlsZHJlbicsXG4gICdyYXRpbmdfdm90ZXMnLFxuICAncmF0aW5nJyxcbiAgJ3JhdGluZ19wZXJjZW50JyxcbiAgJ3JldmlzaW9ucycsXG4gICd0YWdzJyxcbiAgJ190YWdzJyxcbl0gYXMgY29uc3Q7XG5cbi8qKlxuICog44Oa44O844K45qSc57Si44Kv44Ko44OqXG4gKi9cbmV4cG9ydCBjbGFzcyBTZWFyY2hQYWdlc1F1ZXJ5IHtcbiAgLyoqIOODmuODvOOCuOOCv+OCpOODlyAqL1xuICBwYWdldHlwZTogc3RyaW5nO1xuICAvKiog44Kr44OG44K044OqICovXG4gIGNhdGVnb3J5OiBzdHJpbmc7XG4gIC8qKiDjgr/jgrAgKi9cbiAgdGFnczogc3RyaW5nIHwgc3RyaW5nW10gfCBudWxsO1xuICAvKiog6Kaq44Oa44O844K4ICovXG4gIHBhcmVudDogc3RyaW5nIHwgbnVsbDtcbiAgLyoqIOODquODs+OCr+WFiCAqL1xuICBsaW5rVG86IHN0cmluZyB8IG51bGw7XG4gIC8qKiDkvZzmiJDml6XmmYLmnaHku7YgKi9cbiAgY3JlYXRlZEF0OiBzdHJpbmcgfCBudWxsO1xuICAvKiog5pu05paw5pel5pmC5p2h5Lu2ICovXG4gIHVwZGF0ZWRBdDogc3RyaW5nIHwgbnVsbDtcbiAgLyoqIOS9nOaIkOiAhSAqL1xuICBjcmVhdGVkQnk6IEFic3RyYWN0VXNlciB8IHN0cmluZyB8IG51bGw7XG4gIC8qKiDjg6zjg7zjg4bjgqPjg7PjgrDmnaHku7YgKi9cbiAgcmF0aW5nOiBzdHJpbmcgfCBudWxsO1xuICAvKiog5oqV56Wo5pWw5p2h5Lu2ICovXG4gIHZvdGVzOiBzdHJpbmcgfCBudWxsO1xuICAvKiog44Oa44O844K45ZCN5p2h5Lu2ICovXG4gIG5hbWU6IHN0cmluZyB8IG51bGw7XG4gIC8qKiDjg5Xjg6vjg43jg7zjg6DmnaHku7YgKi9cbiAgZnVsbG5hbWU6IHN0cmluZyB8IG51bGw7XG4gIC8qKiDnr4Tlm7IgKi9cbiAgcmFuZ2U6IHN0cmluZyB8IG51bGw7XG4gIC8qKiDjgr3jg7zjg4jpoIYgKi9cbiAgb3JkZXI6IHN0cmluZztcbiAgLyoqIOOCquODleOCu+ODg+ODiCAqL1xuICBvZmZzZXQ6IG51bWJlcjtcbiAgLyoqIOWPluW+l+S7tuaVsOWItumZkCAqL1xuICBsaW1pdDogbnVtYmVyIHwgbnVsbDtcbiAgLyoqIDHjg5rjg7zjgrjjgYLjgZ/jgorku7bmlbAgKi9cbiAgcGVyUGFnZTogbnVtYmVyO1xuICAvKiog5YCL5Yil6KGo56S6ICovXG4gIHNlcGFyYXRlOiBzdHJpbmc7XG4gIC8qKiDjg6njg4Pjg5Hjg7zooajnpLogKi9cbiAgd3JhcHBlcjogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHBhcmFtczogU2VhcmNoUGFnZXNRdWVyeVBhcmFtcyA9IHt9KSB7XG4gICAgdGhpcy5wYWdldHlwZSA9IHBhcmFtcy5wYWdldHlwZSA/PyAnKic7XG4gICAgdGhpcy5jYXRlZ29yeSA9IHBhcmFtcy5jYXRlZ29yeSA/PyAnKic7XG4gICAgdGhpcy50YWdzID0gcGFyYW1zLnRhZ3MgPz8gbnVsbDtcbiAgICB0aGlzLnBhcmVudCA9IHBhcmFtcy5wYXJlbnQgPz8gbnVsbDtcbiAgICB0aGlzLmxpbmtUbyA9IHBhcmFtcy5saW5rVG8gPz8gbnVsbDtcbiAgICB0aGlzLmNyZWF0ZWRBdCA9IHBhcmFtcy5jcmVhdGVkQXQgPz8gbnVsbDtcbiAgICB0aGlzLnVwZGF0ZWRBdCA9IHBhcmFtcy51cGRhdGVkQXQgPz8gbnVsbDtcbiAgICB0aGlzLmNyZWF0ZWRCeSA9IHBhcmFtcy5jcmVhdGVkQnkgPz8gbnVsbDtcbiAgICB0aGlzLnJhdGluZyA9IHBhcmFtcy5yYXRpbmcgPz8gbnVsbDtcbiAgICB0aGlzLnZvdGVzID0gcGFyYW1zLnZvdGVzID8/IG51bGw7XG4gICAgdGhpcy5uYW1lID0gcGFyYW1zLm5hbWUgPz8gbnVsbDtcbiAgICB0aGlzLmZ1bGxuYW1lID0gcGFyYW1zLmZ1bGxuYW1lID8/IG51bGw7XG4gICAgdGhpcy5yYW5nZSA9IHBhcmFtcy5yYW5nZSA/PyBudWxsO1xuICAgIHRoaXMub3JkZXIgPSBwYXJhbXMub3JkZXIgPz8gJ2NyZWF0ZWRfYXQgZGVzYyc7XG4gICAgdGhpcy5vZmZzZXQgPSBwYXJhbXMub2Zmc2V0ID8/IDA7XG4gICAgdGhpcy5saW1pdCA9IHBhcmFtcy5saW1pdCA/PyBudWxsO1xuICAgIHRoaXMucGVyUGFnZSA9IHBhcmFtcy5wZXJQYWdlID8/IERFRkFVTFRfUEVSX1BBR0U7XG4gICAgdGhpcy5zZXBhcmF0ZSA9IHBhcmFtcy5zZXBhcmF0ZSA/PyAnbm8nO1xuICAgIHRoaXMud3JhcHBlciA9IHBhcmFtcy53cmFwcGVyID8/ICdubyc7XG4gIH1cblxuICAvKipcbiAgICog6L6e5pu45b2i5byP44Gr5aSJ5o+bXG4gICAqL1xuICBhc0RpY3QoKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICAgIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcblxuICAgIGlmICh0aGlzLnBhZ2V0eXBlICE9PSAnKicpIHJlc3VsdC5wYWdldHlwZSA9IHRoaXMucGFnZXR5cGU7XG4gICAgaWYgKHRoaXMuY2F0ZWdvcnkgIT09ICcqJykgcmVzdWx0LmNhdGVnb3J5ID0gdGhpcy5jYXRlZ29yeTtcbiAgICBpZiAodGhpcy50YWdzICE9PSBudWxsKSB7XG4gICAgICByZXN1bHQudGFncyA9IEFycmF5LmlzQXJyYXkodGhpcy50YWdzKSA/IHRoaXMudGFncy5qb2luKCcgJykgOiB0aGlzLnRhZ3M7XG4gICAgfVxuICAgIGlmICh0aGlzLnBhcmVudCAhPT0gbnVsbCkgcmVzdWx0LnBhcmVudCA9IHRoaXMucGFyZW50O1xuICAgIGlmICh0aGlzLmxpbmtUbyAhPT0gbnVsbCkgcmVzdWx0LmxpbmtfdG8gPSB0aGlzLmxpbmtUbztcbiAgICBpZiAodGhpcy5jcmVhdGVkQXQgIT09IG51bGwpIHJlc3VsdC5jcmVhdGVkX2F0ID0gdGhpcy5jcmVhdGVkQXQ7XG4gICAgaWYgKHRoaXMudXBkYXRlZEF0ICE9PSBudWxsKSByZXN1bHQudXBkYXRlZF9hdCA9IHRoaXMudXBkYXRlZEF0O1xuICAgIGlmICh0aGlzLmNyZWF0ZWRCeSAhPT0gbnVsbCkge1xuICAgICAgcmVzdWx0LmNyZWF0ZWRfYnkgPSB0eXBlb2YgdGhpcy5jcmVhdGVkQnkgPT09ICdzdHJpbmcnID8gdGhpcy5jcmVhdGVkQnkgOiB0aGlzLmNyZWF0ZWRCeS5uYW1lO1xuICAgIH1cbiAgICBpZiAodGhpcy5yYXRpbmcgIT09IG51bGwpIHJlc3VsdC5yYXRpbmcgPSB0aGlzLnJhdGluZztcbiAgICBpZiAodGhpcy52b3RlcyAhPT0gbnVsbCkgcmVzdWx0LnZvdGVzID0gdGhpcy52b3RlcztcbiAgICBpZiAodGhpcy5uYW1lICE9PSBudWxsKSByZXN1bHQubmFtZSA9IHRoaXMubmFtZTtcbiAgICBpZiAodGhpcy5mdWxsbmFtZSAhPT0gbnVsbCkgcmVzdWx0LmZ1bGxuYW1lID0gdGhpcy5mdWxsbmFtZTtcbiAgICBpZiAodGhpcy5yYW5nZSAhPT0gbnVsbCkgcmVzdWx0LnJhbmdlID0gdGhpcy5yYW5nZTtcblxuICAgIHJlc3VsdC5vcmRlciA9IHRoaXMub3JkZXI7XG4gICAgcmVzdWx0Lm9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgIGlmICh0aGlzLmxpbWl0ICE9PSBudWxsKSByZXN1bHQubGltaXQgPSB0aGlzLmxpbWl0O1xuICAgIHJlc3VsdC5wZXJQYWdlID0gdGhpcy5wZXJQYWdlO1xuICAgIHJlc3VsdC5zZXBhcmF0ZSA9IHRoaXMuc2VwYXJhdGU7XG4gICAgcmVzdWx0LndyYXBwZXIgPSB0aGlzLndyYXBwZXI7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG4iLAogICAgImltcG9ydCAqIGFzIGNoZWVyaW8gZnJvbSAnY2hlZXJpbyc7XG5pbXBvcnQgeyBOb0VsZW1lbnRFcnJvciwgVW5leHBlY3RlZEVycm9yIH0gZnJvbSAnLi4vLi4vY29tbW9uL2Vycm9ycyc7XG5pbXBvcnQgeyBmcm9tUHJvbWlzZSwgdHlwZSBXaWtpZG90UmVzdWx0QXN5bmMgfSBmcm9tICcuLi8uLi9jb21tb24vdHlwZXMnO1xuaW1wb3J0IHsgcGFyc2VPZGF0ZSwgcGFyc2VVc2VyIH0gZnJvbSAnLi4vLi4vdXRpbC9wYXJzZXInO1xuaW1wb3J0IHR5cGUgeyBTaXRlIH0gZnJvbSAnLi4vc2l0ZSc7XG5pbXBvcnQgdHlwZSB7IEFic3RyYWN0VXNlciB9IGZyb20gJy4uL3VzZXInO1xuXG4vKipcbiAqIOOCteOCpOODiOWkieabtOWxpeattOODh+ODvOOCv1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNpdGVDaGFuZ2VEYXRhIHtcbiAgc2l0ZTogU2l0ZTtcbiAgcGFnZUZ1bGxuYW1lOiBzdHJpbmc7XG4gIHBhZ2VUaXRsZTogc3RyaW5nO1xuICByZXZpc2lvbk5vOiBudW1iZXI7XG4gIGNoYW5nZWRCeTogQWJzdHJhY3RVc2VyIHwgbnVsbDtcbiAgY2hhbmdlZEF0OiBEYXRlIHwgbnVsbDtcbiAgZmxhZ3M6IHN0cmluZ1tdO1xuICBjb21tZW50OiBzdHJpbmc7XG59XG5cbi8qKlxuICog44K144Kk44OI5aSJ5pu05bGl5q20XG4gKi9cbmV4cG9ydCBjbGFzcyBTaXRlQ2hhbmdlIHtcbiAgcHVibGljIHJlYWRvbmx5IHNpdGU6IFNpdGU7XG4gIHB1YmxpYyByZWFkb25seSBwYWdlRnVsbG5hbWU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHBhZ2VUaXRsZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgcmV2aXNpb25ObzogbnVtYmVyO1xuICBwdWJsaWMgcmVhZG9ubHkgY2hhbmdlZEJ5OiBBYnN0cmFjdFVzZXIgfCBudWxsO1xuICBwdWJsaWMgcmVhZG9ubHkgY2hhbmdlZEF0OiBEYXRlIHwgbnVsbDtcbiAgcHVibGljIHJlYWRvbmx5IGZsYWdzOiBzdHJpbmdbXTtcbiAgcHVibGljIHJlYWRvbmx5IGNvbW1lbnQ6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihkYXRhOiBTaXRlQ2hhbmdlRGF0YSkge1xuICAgIHRoaXMuc2l0ZSA9IGRhdGEuc2l0ZTtcbiAgICB0aGlzLnBhZ2VGdWxsbmFtZSA9IGRhdGEucGFnZUZ1bGxuYW1lO1xuICAgIHRoaXMucGFnZVRpdGxlID0gZGF0YS5wYWdlVGl0bGU7XG4gICAgdGhpcy5yZXZpc2lvbk5vID0gZGF0YS5yZXZpc2lvbk5vO1xuICAgIHRoaXMuY2hhbmdlZEJ5ID0gZGF0YS5jaGFuZ2VkQnk7XG4gICAgdGhpcy5jaGFuZ2VkQXQgPSBkYXRhLmNoYW5nZWRBdDtcbiAgICB0aGlzLmZsYWdzID0gZGF0YS5mbGFncztcbiAgICB0aGlzLmNvbW1lbnQgPSBkYXRhLmNvbW1lbnQ7XG4gIH1cblxuICAvKipcbiAgICog44Oa44O844K4VVJMXG4gICAqL1xuICBnZXRQYWdlVXJsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke3RoaXMuc2l0ZS5nZXRCYXNlVXJsKCl9LyR7dGhpcy5wYWdlRnVsbG5hbWV9YDtcbiAgfVxuXG4gIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGBTaXRlQ2hhbmdlKHBhZ2U9JHt0aGlzLnBhZ2VGdWxsbmFtZX0sIHJldj0ke3RoaXMucmV2aXNpb25Ob30sIGJ5PSR7dGhpcy5jaGFuZ2VkQnl9KWA7XG4gIH1cbn1cblxuLyoqXG4gKiDjgrXjgqTjg4jlpInmm7TlsaXmrbTjgrPjg6zjgq/jgrfjg6fjg7NcbiAqL1xuZXhwb3J0IGNsYXNzIFNpdGVDaGFuZ2VDb2xsZWN0aW9uIGV4dGVuZHMgQXJyYXk8U2l0ZUNoYW5nZT4ge1xuICBwdWJsaWMgcmVhZG9ubHkgc2l0ZTogU2l0ZTtcblxuICBjb25zdHJ1Y3RvcihzaXRlOiBTaXRlLCBjaGFuZ2VzPzogU2l0ZUNoYW5nZVtdKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLnNpdGUgPSBzaXRlO1xuICAgIGlmIChjaGFuZ2VzKSB7XG4gICAgICB0aGlzLnB1c2goLi4uY2hhbmdlcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOacgOi/keOBruWkieabtOWxpeattOOCkuWPluW+l+OBmeOCi1xuICAgKiBAcGFyYW0gc2l0ZSAtIOOCteOCpOODiFxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIOOCquODl+OCt+ODp+ODs1xuICAgKiBAcmV0dXJucyDlpInmm7TlsaXmrbTjgrPjg6zjgq/jgrfjg6fjg7NcbiAgICovXG4gIHN0YXRpYyBhY3F1aXJlKFxuICAgIHNpdGU6IFNpdGUsXG4gICAgb3B0aW9ucz86IHsgcGVyUGFnZT86IG51bWJlcjsgcGFnZT86IG51bWJlcjsgbGltaXQ/OiBudW1iZXIgfVxuICApOiBXaWtpZG90UmVzdWx0QXN5bmM8U2l0ZUNoYW5nZUNvbGxlY3Rpb24+IHtcbiAgICBjb25zdCBwZXJQYWdlID0gb3B0aW9ucz8ucGVyUGFnZSA/PyAyMDtcbiAgICBjb25zdCBwYWdlID0gb3B0aW9ucz8ucGFnZSA/PyAxO1xuICAgIGNvbnN0IGxpbWl0ID0gb3B0aW9ucz8ubGltaXQ7XG5cbiAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzaXRlLmFtY1JlcXVlc3QoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1vZHVsZU5hbWU6ICdjaGFuZ2VzL1NpdGVDaGFuZ2VzTGlzdE1vZHVsZScsXG4gICAgICAgICAgICBwZXJwYWdlOiBwZXJQYWdlLFxuICAgICAgICAgICAgcGFnZTogcGFnZSxcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcblxuICAgICAgICBpZiAocmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IHJlc3VsdC52YWx1ZVswXTtcbiAgICAgICAgaWYgKCFyZXNwb25zZSkge1xuICAgICAgICAgIHRocm93IG5ldyBOb0VsZW1lbnRFcnJvcignRW1wdHkgcmVzcG9uc2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGh0bWwgPSBTdHJpbmcocmVzcG9uc2UuYm9keSA/PyAnJyk7XG4gICAgICAgIGNvbnN0ICQgPSBjaGVlcmlvLmxvYWQoaHRtbCk7XG4gICAgICAgIGNvbnN0IGNoYW5nZXM6IFNpdGVDaGFuZ2VbXSA9IFtdO1xuXG4gICAgICAgIC8vIOODhuODvOODluODq+ihjOOCkuODkeODvOOCuVxuICAgICAgICAkKCd0YWJsZS53aWtpLWNvbnRlbnQtdGFibGUgdHInKS5lYWNoKChfaSwgZWxlbSkgPT4ge1xuICAgICAgICAgIGNvbnN0ICRyb3cgPSAkKGVsZW0pO1xuICAgICAgICAgIGNvbnN0ICRjZWxscyA9ICRyb3cuZmluZCgndGQnKTtcbiAgICAgICAgICBpZiAoJGNlbGxzLmxlbmd0aCA8IDQpIHJldHVybjtcblxuICAgICAgICAgIC8vIOODmuODvOOCuOODquODs+OCr1xuICAgICAgICAgIGNvbnN0IHBhZ2VMaW5rID0gJCgkY2VsbHNbMF0pLmZpbmQoJ2EnKTtcbiAgICAgICAgICBjb25zdCBocmVmID0gcGFnZUxpbmsuYXR0cignaHJlZicpID8/ICcnO1xuICAgICAgICAgIGNvbnN0IHBhZ2VGdWxsbmFtZSA9IGhyZWYucmVwbGFjZSgvXlxcLy8sICcnKS5zcGxpdCgnLycpWzBdID8/ICcnO1xuICAgICAgICAgIGNvbnN0IHBhZ2VUaXRsZSA9IHBhZ2VMaW5rLnRleHQoKS50cmltKCk7XG5cbiAgICAgICAgICAvLyDjg6rjg5Pjgrjjg6fjg7Pnlarlj7dcbiAgICAgICAgICBjb25zdCByZXZUZXh0ID0gJCgkY2VsbHNbMV0pLnRleHQoKS50cmltKCk7XG4gICAgICAgICAgY29uc3QgcmV2TWF0Y2ggPSByZXZUZXh0Lm1hdGNoKC8oXFxkKykvKTtcbiAgICAgICAgICBjb25zdCByZXZpc2lvbk5vID0gcmV2TWF0Y2g/LlsxXSA/IE51bWJlci5wYXJzZUludChyZXZNYXRjaFsxXSwgMTApIDogMDtcblxuICAgICAgICAgIC8vIOODleODqeOCsFxuICAgICAgICAgIGNvbnN0IGZsYWdzQ2VsbCA9ICQoJGNlbGxzWzJdKTtcbiAgICAgICAgICBjb25zdCBmbGFnczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgICBmbGFnc0NlbGwuZmluZCgnc3BhbicpLmVhY2goKF9qLCBmbGFnRWxlbSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZmxhZ0NsYXNzID0gJChmbGFnRWxlbSkuYXR0cignY2xhc3MnKSA/PyAnJztcbiAgICAgICAgICAgIGlmIChmbGFnQ2xhc3MuaW5jbHVkZXMoJ3NwYW50aXAnKSkge1xuICAgICAgICAgICAgICBjb25zdCB0aXRsZSA9ICQoZmxhZ0VsZW0pLmF0dHIoJ3RpdGxlJykgPz8gJyc7XG4gICAgICAgICAgICAgIGlmICh0aXRsZSkgZmxhZ3MucHVzaCh0aXRsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyDjg6bjg7zjgrbjg7zjgajml6XmmYJcbiAgICAgICAgICBjb25zdCBpbmZvQ2VsbCA9ICQoJGNlbGxzWzNdKTtcbiAgICAgICAgICBjb25zdCB1c2VyRWxlbSA9IGluZm9DZWxsLmZpbmQoJ3NwYW4ucHJpbnR1c2VyJyk7XG4gICAgICAgICAgY29uc3QgY2hhbmdlZEJ5ID0gdXNlckVsZW0ubGVuZ3RoID4gMCA/IHBhcnNlVXNlcihzaXRlLmNsaWVudCwgdXNlckVsZW0pIDogbnVsbDtcblxuICAgICAgICAgIGNvbnN0IG9kYXRlRWxlbSA9IGluZm9DZWxsLmZpbmQoJ3NwYW4ub2RhdGUnKTtcbiAgICAgICAgICBjb25zdCBjaGFuZ2VkQXQgPSBvZGF0ZUVsZW0ubGVuZ3RoID4gMCA/IHBhcnNlT2RhdGUob2RhdGVFbGVtKSA6IG51bGw7XG5cbiAgICAgICAgICAvLyDjgrPjg6Hjg7Pjg4hcbiAgICAgICAgICBjb25zdCBjb21tZW50RWxlbSA9IGluZm9DZWxsLmZpbmQoJ3NwYW4uY29tbWVudHMnKTtcbiAgICAgICAgICBjb25zdCBjb21tZW50ID0gY29tbWVudEVsZW1cbiAgICAgICAgICAgIC50ZXh0KClcbiAgICAgICAgICAgIC50cmltKClcbiAgICAgICAgICAgIC5yZXBsYWNlKC9eW1wiXCJdfFtcIlwiXSQvZywgJycpO1xuXG4gICAgICAgICAgY2hhbmdlcy5wdXNoKFxuICAgICAgICAgICAgbmV3IFNpdGVDaGFuZ2Uoe1xuICAgICAgICAgICAgICBzaXRlLFxuICAgICAgICAgICAgICBwYWdlRnVsbG5hbWUsXG4gICAgICAgICAgICAgIHBhZ2VUaXRsZSxcbiAgICAgICAgICAgICAgcmV2aXNpb25ObyxcbiAgICAgICAgICAgICAgY2hhbmdlZEJ5LFxuICAgICAgICAgICAgICBjaGFuZ2VkQXQsXG4gICAgICAgICAgICAgIGZsYWdzLFxuICAgICAgICAgICAgICBjb21tZW50LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBsaW1pdOOBjOaMh+WumuOBleOCjOOBpuOBhOOCi+WgtOWQiOOBr+e1kOaenOOCkuWItumZkFxuICAgICAgICBjb25zdCBsaW1pdGVkQ2hhbmdlcyA9IGxpbWl0ICE9PSB1bmRlZmluZWQgPyBjaGFuZ2VzLnNsaWNlKDAsIGxpbWl0KSA6IGNoYW5nZXM7XG4gICAgICAgIHJldHVybiBuZXcgU2l0ZUNoYW5nZUNvbGxlY3Rpb24oc2l0ZSwgbGltaXRlZENoYW5nZXMpO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvcikge1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGFjcXVpcmUgc2l0ZSBjaGFuZ2VzOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuIiwKICAgICJpbXBvcnQgeyBOb0VsZW1lbnRFcnJvciwgVW5leHBlY3RlZEVycm9yIH0gZnJvbSAnLi4vLi4vLi4vY29tbW9uL2Vycm9ycyc7XG5pbXBvcnQgeyBmcm9tUHJvbWlzZSwgdHlwZSBXaWtpZG90UmVzdWx0QXN5bmMgfSBmcm9tICcuLi8uLi8uLi9jb21tb24vdHlwZXMnO1xuaW1wb3J0IHsgcGFyc2VVc2VyIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9wYXJzZXInO1xuaW1wb3J0IHsgUGFnZSwgUGFnZUNvbGxlY3Rpb24sIFNlYXJjaFBhZ2VzUXVlcnkgfSBmcm9tICcuLi8uLi9wYWdlJztcbmltcG9ydCB0eXBlIHsgU2l0ZSB9IGZyb20gJy4uL3NpdGUnO1xuXG4vKipcbiAqIOWNmOS4gOODmuODvOOCuOaTjeS9nOOCouOCr+OCu+OCtVxuICovXG5leHBvcnQgY2xhc3MgUGFnZUFjY2Vzc29yIHtcbiAgcHVibGljIHJlYWRvbmx5IHNpdGU6IFNpdGU7XG5cbiAgY29uc3RydWN0b3Ioc2l0ZTogU2l0ZSkge1xuICAgIHRoaXMuc2l0ZSA9IHNpdGU7XG4gIH1cblxuICAvKipcbiAgICogVU5JWOWQjeOBi+OCieODmuODvOOCuOOCkuWPluW+l+OBmeOCi1xuICAgKiBAcGFyYW0gdW5peE5hbWUgLSDjg5rjg7zjgrjjga5VTklY5ZCN77yI5L6LOiAnc2NwLTE3MyfvvIlcbiAgICogQHJldHVybnMg44Oa44O844K477yI5a2Y5Zyo44GX44Gq44GE5aC05ZCI44GvbnVsbO+8iVxuICAgKi9cbiAgZ2V0KHVuaXhOYW1lOiBzdHJpbmcpOiBXaWtpZG90UmVzdWx0QXN5bmM8UGFnZSB8IG51bGw+IHtcbiAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBxdWVyeSA9IG5ldyBTZWFyY2hQYWdlc1F1ZXJ5KHsgZnVsbG5hbWU6IHVuaXhOYW1lIH0pO1xuICAgICAgICBjb25zdCB1c2VyUGFyc2VyID0gcGFyc2VVc2VyLmJpbmQobnVsbCwgdGhpcy5zaXRlLmNsaWVudCk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgUGFnZUNvbGxlY3Rpb24uc2VhcmNoUGFnZXModGhpcy5zaXRlLCB1c2VyUGFyc2VyLCBxdWVyeSk7XG4gICAgICAgIGlmIChyZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IHJlc3VsdC5lcnJvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXN1bHQudmFsdWUubGVuZ3RoID4gMCA/IChyZXN1bHQudmFsdWVbMF0gPz8gbnVsbCkgOiBudWxsO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvcikgcmV0dXJuIGVycm9yO1xuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGdldCBwYWdlOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg5rjg7zjgrjjgpLkvZzmiJDjgZnjgotcbiAgICogQHBhcmFtIGZ1bGxuYW1lIC0g44Oa44O844K444Gu44OV44Or44ON44O844Og77yI5L6LOiAnc2NwLTE3MyfvvIlcbiAgICogQHBhcmFtIG9wdGlvbnMgLSDkvZzmiJDjgqrjg5fjgrfjg6fjg7NcbiAgICogQHJldHVybnMgdm9pZFxuICAgKi9cbiAgY3JlYXRlKFxuICAgIGZ1bGxuYW1lOiBzdHJpbmcsXG4gICAgb3B0aW9uczoge1xuICAgICAgdGl0bGU/OiBzdHJpbmc7XG4gICAgICBzb3VyY2U/OiBzdHJpbmc7XG4gICAgICBjb21tZW50Pzogc3RyaW5nO1xuICAgICAgZm9yY2VFZGl0PzogYm9vbGVhbjtcbiAgICB9ID0ge31cbiAgKTogV2lraWRvdFJlc3VsdEFzeW5jPHZvaWQ+IHtcbiAgICByZXR1cm4gUGFnZUNvbGxlY3Rpb24uY3JlYXRlT3JFZGl0KHRoaXMuc2l0ZSwgZnVsbG5hbWUsIHtcbiAgICAgIHRpdGxlOiBvcHRpb25zLnRpdGxlLFxuICAgICAgc291cmNlOiBvcHRpb25zLnNvdXJjZSxcbiAgICAgIGNvbW1lbnQ6IG9wdGlvbnMuY29tbWVudCxcbiAgICAgIGZvcmNlRWRpdDogb3B0aW9ucy5mb3JjZUVkaXQsXG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IHsgUGFnZSB9O1xuIiwKICAgICJpbXBvcnQgeyBVbmV4cGVjdGVkRXJyb3IgfSBmcm9tICcuLi8uLi8uLi9jb21tb24vZXJyb3JzJztcbmltcG9ydCB7IGZyb21Qcm9taXNlLCB0eXBlIFdpa2lkb3RSZXN1bHRBc3luYyB9IGZyb20gJy4uLy4uLy4uL2NvbW1vbi90eXBlcyc7XG5pbXBvcnQgeyBwYXJzZVVzZXIgfSBmcm9tICcuLi8uLi8uLi91dGlsL3BhcnNlcic7XG5pbXBvcnQge1xuICBQYWdlLFxuICBQYWdlQ29sbGVjdGlvbixcbiAgU2VhcmNoUGFnZXNRdWVyeSxcbiAgdHlwZSBTZWFyY2hQYWdlc1F1ZXJ5UGFyYW1zLFxuICBTaXRlQ2hhbmdlQ29sbGVjdGlvbixcbn0gZnJvbSAnLi4vLi4vcGFnZSc7XG5pbXBvcnQgdHlwZSB7IFNpdGUgfSBmcm9tICcuLi9zaXRlJztcblxuLyoqXG4gKiDjg5rjg7zjgrjkuIDopqfmk43kvZzjgqLjgq/jgrvjgrVcbiAqL1xuZXhwb3J0IGNsYXNzIFBhZ2VzQWNjZXNzb3Ige1xuICBwdWJsaWMgcmVhZG9ubHkgc2l0ZTogU2l0ZTtcblxuICBjb25zdHJ1Y3RvcihzaXRlOiBTaXRlKSB7XG4gICAgdGhpcy5zaXRlID0gc2l0ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmnaHku7bjgavlkIjjgYbjg5rjg7zjgrjjgpLmpJzntKLjgZnjgotcbiAgICogQHBhcmFtIHBhcmFtcyAtIOaknOe0ouadoeS7tlxuICAgKiBAcmV0dXJucyDjg5rjg7zjgrjjgrPjg6zjgq/jgrfjg6fjg7NcbiAgICovXG4gIHNlYXJjaChwYXJhbXM/OiBTZWFyY2hQYWdlc1F1ZXJ5UGFyYW1zKTogV2lraWRvdFJlc3VsdEFzeW5jPFBhZ2VDb2xsZWN0aW9uPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcXVlcnkgPSBuZXcgU2VhcmNoUGFnZXNRdWVyeShwYXJhbXMpO1xuICAgICAgICBjb25zdCB1c2VyUGFyc2VyID0gcGFyc2VVc2VyLmJpbmQobnVsbCwgdGhpcy5zaXRlLmNsaWVudCk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgUGFnZUNvbGxlY3Rpb24uc2VhcmNoUGFnZXModGhpcy5zaXRlLCB1c2VyUGFyc2VyLCBxdWVyeSk7XG4gICAgICAgIGlmIChyZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IHJlc3VsdC5lcnJvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXN1bHQudmFsdWU7XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gc2VhcmNoIHBhZ2VzOiAke1N0cmluZyhlcnJvcil9YClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIOWFqOODmuODvOOCuOOCkuWPluW+l+OBmeOCi1xuICAgKiBAcmV0dXJucyDjg5rjg7zjgrjjgrPjg6zjgq/jgrfjg6fjg7NcbiAgICovXG4gIGFsbCgpOiBXaWtpZG90UmVzdWx0QXN5bmM8UGFnZUNvbGxlY3Rpb24+IHtcbiAgICByZXR1cm4gdGhpcy5zZWFyY2goe30pO1xuICB9XG5cbiAgLyoqXG4gICAqIOacgOi/keOBruWkieabtOWxpeattOOCkuWPluW+l+OBmeOCi1xuICAgKiBAcGFyYW0gb3B0aW9ucyAtIOOCquODl+OCt+ODp+ODs1xuICAgKiBAcGFyYW0gb3B0aW9ucy5wZXJQYWdlIC0gMeODmuODvOOCuOOBguOBn+OCiuOBruS7tuaVsO+8iOODh+ODleOCqeODq+ODiDogMjDvvIlcbiAgICogQHBhcmFtIG9wdGlvbnMucGFnZSAtIOODmuODvOOCuOeVquWPt++8iOODh+ODleOCqeODq+ODiDogMe+8iVxuICAgKiBAcmV0dXJucyDlpInmm7TlsaXmrbTjgrPjg6zjgq/jgrfjg6fjg7NcbiAgICovXG4gIGdldFJlY2VudENoYW5nZXMob3B0aW9ucz86IHtcbiAgICBwZXJQYWdlPzogbnVtYmVyO1xuICAgIHBhZ2U/OiBudW1iZXI7XG4gIH0pOiBXaWtpZG90UmVzdWx0QXN5bmM8U2l0ZUNoYW5nZUNvbGxlY3Rpb24+IHtcbiAgICByZXR1cm4gU2l0ZUNoYW5nZUNvbGxlY3Rpb24uYWNxdWlyZSh0aGlzLnNpdGUsIG9wdGlvbnMpO1xuICB9XG59XG5cbmV4cG9ydCB7XG4gIFBhZ2UsXG4gIFBhZ2VDb2xsZWN0aW9uLFxuICBTZWFyY2hQYWdlc1F1ZXJ5LFxuICBTaXRlQ2hhbmdlQ29sbGVjdGlvbixcbiAgdHlwZSBTZWFyY2hQYWdlc1F1ZXJ5UGFyYW1zLFxufTtcbiIsCiAgICAiaW1wb3J0ICogYXMgY2hlZXJpbyBmcm9tICdjaGVlcmlvJztcbmltcG9ydCB7IE5vRWxlbWVudEVycm9yLCBOb3RGb3VuZEV4Y2VwdGlvbiwgVW5leHBlY3RlZEVycm9yIH0gZnJvbSAnLi4vLi4vY29tbW9uL2Vycm9ycyc7XG5pbXBvcnQgeyBmcm9tUHJvbWlzZSwgdHlwZSBXaWtpZG90UmVzdWx0QXN5bmMgfSBmcm9tICcuLi8uLi9jb21tb24vdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBBTUNSZXF1ZXN0Qm9keSwgQU1DUmVzcG9uc2UgfSBmcm9tICcuLi8uLi9jb25uZWN0b3InO1xuaW1wb3J0IHR5cGUgeyBDbGllbnQgfSBmcm9tICcuLi9jbGllbnQvY2xpZW50JztcbmltcG9ydCB7IEZvcnVtQWNjZXNzb3IgfSBmcm9tICcuL2FjY2Vzc29ycy9mb3J1bS1hY2Nlc3Nvcic7XG5pbXBvcnQgeyBNZW1iZXJBY2Nlc3NvciB9IGZyb20gJy4vYWNjZXNzb3JzL21lbWJlci1hY2Nlc3Nvcic7XG5pbXBvcnQgeyBQYWdlQWNjZXNzb3IgfSBmcm9tICcuL2FjY2Vzc29ycy9wYWdlLWFjY2Vzc29yJztcbmltcG9ydCB7IFBhZ2VzQWNjZXNzb3IgfSBmcm9tICcuL2FjY2Vzc29ycy9wYWdlcy1hY2Nlc3Nvcic7XG5cbi8qKlxuICog44K144Kk44OI44OH44O844K/XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2l0ZURhdGEge1xuICBpZDogbnVtYmVyO1xuICB0aXRsZTogc3RyaW5nO1xuICB1bml4TmFtZTogc3RyaW5nO1xuICBkb21haW46IHN0cmluZztcbiAgc3NsU3VwcG9ydGVkOiBib29sZWFuO1xufVxuXG4vKipcbiAqIOOCteOCpOODiOOCr+ODqeOCuVxuICovXG5leHBvcnQgY2xhc3MgU2l0ZSB7XG4gIHB1YmxpYyByZWFkb25seSBjbGllbnQ6IENsaWVudDtcblxuICAvKiog44K144Kk44OISUQgKi9cbiAgcHVibGljIHJlYWRvbmx5IGlkOiBudW1iZXI7XG5cbiAgLyoqIOOCteOCpOODiOOCv+OCpOODiOODqyAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcblxuICAvKiogVU5JWOWQje+8iOS+izogc2NwLWpw77yJICovXG4gIHB1YmxpYyByZWFkb25seSB1bml4TmFtZTogc3RyaW5nO1xuXG4gIC8qKiDjg4njg6HjgqTjg7MgKi9cbiAgcHVibGljIHJlYWRvbmx5IGRvbWFpbjogc3RyaW5nO1xuXG4gIC8qKiBTU0zlr77lv5zjg5Xjg6njgrAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHNzbFN1cHBvcnRlZDogYm9vbGVhbjtcblxuICAvKiog44Oa44O844K444Ki44Kv44K744K1ICovXG4gIHByaXZhdGUgX3BhZ2U6IFBhZ2VBY2Nlc3NvciB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiDjg5rjg7zjgrjkuIDopqfjgqLjgq/jgrvjgrUgKi9cbiAgcHJpdmF0ZSBfcGFnZXM6IFBhZ2VzQWNjZXNzb3IgfCBudWxsID0gbnVsbDtcblxuICAvKiog44OV44Kp44O844Op44Og44Ki44Kv44K744K1ICovXG4gIHByaXZhdGUgX2ZvcnVtOiBGb3J1bUFjY2Vzc29yIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIOODoeODs+ODkOODvOOCouOCr+OCu+OCtSAqL1xuICBwcml2YXRlIF9tZW1iZXI6IE1lbWJlckFjY2Vzc29yIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoY2xpZW50OiBDbGllbnQsIGRhdGE6IFNpdGVEYXRhKSB7XG4gICAgdGhpcy5jbGllbnQgPSBjbGllbnQ7XG4gICAgdGhpcy5pZCA9IGRhdGEuaWQ7XG4gICAgdGhpcy50aXRsZSA9IGRhdGEudGl0bGU7XG4gICAgdGhpcy51bml4TmFtZSA9IGRhdGEudW5peE5hbWU7XG4gICAgdGhpcy5kb21haW4gPSBkYXRhLmRvbWFpbjtcbiAgICB0aGlzLnNzbFN1cHBvcnRlZCA9IGRhdGEuc3NsU3VwcG9ydGVkO1xuICB9XG5cbiAgLyoqXG4gICAqIOODmuODvOOCuOOCouOCr+OCu+OCteOCkuWPluW+l1xuICAgKi9cbiAgZ2V0IHBhZ2UoKTogUGFnZUFjY2Vzc29yIHtcbiAgICBpZiAoIXRoaXMuX3BhZ2UpIHtcbiAgICAgIHRoaXMuX3BhZ2UgPSBuZXcgUGFnZUFjY2Vzc29yKHRoaXMpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fcGFnZTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg5rjg7zjgrjkuIDopqfjgqLjgq/jgrvjgrXjgpLlj5blvpdcbiAgICovXG4gIGdldCBwYWdlcygpOiBQYWdlc0FjY2Vzc29yIHtcbiAgICBpZiAoIXRoaXMuX3BhZ2VzKSB7XG4gICAgICB0aGlzLl9wYWdlcyA9IG5ldyBQYWdlc0FjY2Vzc29yKHRoaXMpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fcGFnZXM7XG4gIH1cblxuICAvKipcbiAgICog44OV44Kp44O844Op44Og44Ki44Kv44K744K144KS5Y+W5b6XXG4gICAqL1xuICBnZXQgZm9ydW0oKTogRm9ydW1BY2Nlc3NvciB7XG4gICAgaWYgKCF0aGlzLl9mb3J1bSkge1xuICAgICAgdGhpcy5fZm9ydW0gPSBuZXcgRm9ydW1BY2Nlc3Nvcih0aGlzKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2ZvcnVtO1xuICB9XG5cbiAgLyoqXG4gICAqIOODoeODs+ODkOODvOOCouOCr+OCu+OCteOCkuWPluW+l1xuICAgKi9cbiAgZ2V0IG1lbWJlcigpOiBNZW1iZXJBY2Nlc3NvciB7XG4gICAgaWYgKCF0aGlzLl9tZW1iZXIpIHtcbiAgICAgIHRoaXMuX21lbWJlciA9IG5ldyBNZW1iZXJBY2Nlc3Nvcih0aGlzKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX21lbWJlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiDjgrXjgqTjg4jjga7jg5njg7zjgrlVUkzjgpLlj5blvpdcbiAgICovXG4gIGdldEJhc2VVcmwoKTogc3RyaW5nIHtcbiAgICBjb25zdCBwcm90b2NvbCA9IHRoaXMuc3NsU3VwcG9ydGVkID8gJ2h0dHBzJyA6ICdodHRwJztcbiAgICByZXR1cm4gYCR7cHJvdG9jb2x9Oi8vJHt0aGlzLmRvbWFpbn1gO1xuICB9XG5cbiAgLyoqXG4gICAqIOOCteOCpOODiOOBuOOBrkFNQ+ODquOCr+OCqOOCueODiOOCkuWun+ihjFxuICAgKiBAcGFyYW0gYm9kaWVzIC0g44Oq44Kv44Ko44K544OI44Oc44OH44Kj6YWN5YiXXG4gICAqIEByZXR1cm5zIEFNQ+ODrOOCueODneODs+OCuemFjeWIl1xuICAgKi9cbiAgYW1jUmVxdWVzdChib2RpZXM6IEFNQ1JlcXVlc3RCb2R5W10pOiBXaWtpZG90UmVzdWx0QXN5bmM8QU1DUmVzcG9uc2VbXT4ge1xuICAgIHJldHVybiB0aGlzLmNsaWVudC5hbWNDbGllbnQucmVxdWVzdChib2RpZXMsIHRoaXMudW5peE5hbWUsIHRoaXMuc3NsU3VwcG9ydGVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDljZjkuIDjga5BTUPjg6rjgq/jgqjjgrnjg4jjgpLlrp/ooYxcbiAgICogQHBhcmFtIGJvZHkgLSDjg6rjgq/jgqjjgrnjg4jjg5zjg4fjgqNcbiAgICogQHJldHVybnMgQU1D44Os44K544Od44Oz44K5XG4gICAqL1xuICBhbWNSZXF1ZXN0U2luZ2xlKGJvZHk6IEFNQ1JlcXVlc3RCb2R5KTogV2lraWRvdFJlc3VsdEFzeW5jPEFNQ1Jlc3BvbnNlPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5hbWNSZXF1ZXN0KFtib2R5XSk7XG4gICAgICAgIGlmIChyZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IHJlc3VsdC5lcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZXNwb25zZSA9IHJlc3VsdC52YWx1ZVswXTtcbiAgICAgICAgaWYgKCFyZXNwb25zZSkge1xuICAgICAgICAgIHRocm93IG5ldyBVbmV4cGVjdGVkRXJyb3IoJ0FNQyByZXF1ZXN0IHJldHVybmVkIGVtcHR5IHJlc3BvbnNlJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBVbmV4cGVjdGVkRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBVbmV4cGVjdGVkRXJyb3IoYEFNQyByZXF1ZXN0IGZhaWxlZDogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogVU5JWOWQjeOBi+OCieOCteOCpOODiOOCkuWPluW+l+OBmeOCi1xuICAgKiBAcGFyYW0gY2xpZW50IC0g44Kv44Op44Kk44Ki44Oz44OIXG4gICAqIEBwYXJhbSB1bml4TmFtZSAtIOOCteOCpOODiOOBrlVOSVjlkI3vvIjkvos6ICdzY3AtanAn77yJXG4gICAqIEByZXR1cm5zIOOCteOCpOODiFxuICAgKi9cbiAgc3RhdGljIGZyb21Vbml4TmFtZShjbGllbnQ6IENsaWVudCwgdW5peE5hbWU6IHN0cmluZyk6IFdpa2lkb3RSZXN1bHRBc3luYzxTaXRlPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8g44K144Kk44OI44Oa44O844K444KS5Y+W5b6XXG4gICAgICAgIGNvbnN0IHVybCA9IGBodHRwczovLyR7dW5peE5hbWV9Lndpa2lkb3QuY29tYDtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwsIHtcbiAgICAgICAgICBoZWFkZXJzOiBjbGllbnQuYW1jQ2xpZW50LmhlYWRlci5nZXRIZWFkZXJzKCksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSA0MDQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbihgU2l0ZSBub3QgZm91bmQ6ICR7dW5peE5hbWV9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IG5ldyBVbmV4cGVjdGVkRXJyb3IoYEZhaWxlZCB0byBmZXRjaCBzaXRlOiAke3Jlc3BvbnNlLnN0YXR1c31gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGh0bWwgPSBhd2FpdCByZXNwb25zZS50ZXh0KCk7XG4gICAgICAgIGNvbnN0ICQgPSBjaGVlcmlvLmxvYWQoaHRtbCk7XG5cbiAgICAgICAgLy8gV0lLSVJFUVVFU1QuaW5mbyDjgpLop6PmnpBcbiAgICAgICAgY29uc3Qgc2NyaXB0cyA9ICQoJ3NjcmlwdCcpLnRvQXJyYXkoKTtcbiAgICAgICAgbGV0IHNpdGVJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gICAgICAgIGxldCBzaXRlVW5peE5hbWU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAgICAgICBsZXQgZG9tYWluOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgICAgICAgbGV0IHRpdGxlOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAgICAgICBmb3IgKGNvbnN0IHNjcmlwdCBvZiBzY3JpcHRzKSB7XG4gICAgICAgICAgY29uc3QgY29udGVudCA9ICQoc2NyaXB0KS5odG1sKCk7XG4gICAgICAgICAgaWYgKCFjb250ZW50IHx8ICFjb250ZW50LmluY2x1ZGVzKCdXSUtJUkVRVUVTVCcpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBzaXRlSWRcbiAgICAgICAgICBjb25zdCBzaXRlSWRNYXRjaCA9IGNvbnRlbnQubWF0Y2goL1dJS0lSRVFVRVNUXFwuaW5mb1xcLnNpdGVJZFxccyo9XFxzKihcXGQrKS8pO1xuICAgICAgICAgIGlmIChzaXRlSWRNYXRjaD8uWzFdKSB7XG4gICAgICAgICAgICBzaXRlSWQgPSBOdW1iZXIucGFyc2VJbnQoc2l0ZUlkTWF0Y2hbMV0sIDEwKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBzaXRlVW5peE5hbWVcbiAgICAgICAgICBjb25zdCBzaXRlVW5peE5hbWVNYXRjaCA9IGNvbnRlbnQubWF0Y2goXG4gICAgICAgICAgICAvV0lLSVJFUVVFU1RcXC5pbmZvXFwuc2l0ZVVuaXhOYW1lXFxzKj1cXHMqW1wiJ10oW15cIiddKylbXCInXS9cbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChzaXRlVW5peE5hbWVNYXRjaD8uWzFdKSB7XG4gICAgICAgICAgICBzaXRlVW5peE5hbWUgPSBzaXRlVW5peE5hbWVNYXRjaFsxXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBkb21haW5cbiAgICAgICAgICBjb25zdCBkb21haW5NYXRjaCA9IGNvbnRlbnQubWF0Y2goL1dJS0lSRVFVRVNUXFwuaW5mb1xcLmRvbWFpblxccyo9XFxzKltcIiddKFteXCInXSspW1wiJ10vKTtcbiAgICAgICAgICBpZiAoZG9tYWluTWF0Y2g/LlsxXSkge1xuICAgICAgICAgICAgZG9tYWluID0gZG9tYWluTWF0Y2hbMV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdGl0bGUgZnJvbSA8dGl0bGU+IHRhZ1xuICAgICAgICB0aXRsZSA9ICQoJ3RpdGxlJykudGV4dCgpLnRyaW0oKSB8fCBudWxsO1xuICAgICAgICAvLyBSZW1vdmUgXCIgLSBXaWtpZG90XCIgc3VmZml4IGlmIHByZXNlbnRcbiAgICAgICAgaWYgKHRpdGxlPy5lbmRzV2l0aCgnIC0gV2lraWRvdCcpKSB7XG4gICAgICAgICAgdGl0bGUgPSB0aXRsZS5zbGljZSgwLCAtMTApLnRyaW0oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzaXRlSWQgPT09IG51bGwpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTm9FbGVtZW50RXJyb3IoJ1NpdGUgSUQgbm90IGZvdW5kIGluIFdJS0lSRVFVRVNUJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNpdGVVbml4TmFtZSA9PT0gbnVsbCkge1xuICAgICAgICAgIHNpdGVVbml4TmFtZSA9IHVuaXhOYW1lOyAvLyBGYWxsYmFja1xuICAgICAgICB9XG4gICAgICAgIGlmIChkb21haW4gPT09IG51bGwpIHtcbiAgICAgICAgICBkb21haW4gPSBgJHt1bml4TmFtZX0ud2lraWRvdC5jb21gOyAvLyBGYWxsYmFja1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aXRsZSA9PT0gbnVsbCkge1xuICAgICAgICAgIHRpdGxlID0gdW5peE5hbWU7IC8vIEZhbGxiYWNrXG4gICAgICAgIH1cblxuICAgICAgICAvLyBTU0zlr77lv5zjg4Hjgqfjg4Pjgq/vvIjml6LjgatodHRwc+OBp+OCouOCr+OCu+OCueOBp+OBjeOBpuOBhOOCi+OBruOBpyB0cnVl77yJXG4gICAgICAgIGNvbnN0IHNzbFN1cHBvcnRlZCA9IHRydWU7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBTaXRlKGNsaWVudCwge1xuICAgICAgICAgIGlkOiBzaXRlSWQsXG4gICAgICAgICAgdGl0bGUsXG4gICAgICAgICAgdW5peE5hbWU6IHNpdGVVbml4TmFtZSxcbiAgICAgICAgICBkb21haW4sXG4gICAgICAgICAgc3NsU3VwcG9ydGVkLFxuICAgICAgICB9KTtcbiAgICAgIH0pKCksXG4gICAgICAoZXJyb3IpID0+IHtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgTm90Rm91bmRFeGNlcHRpb24gfHwgZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvcikge1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGdldCBzaXRlOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGBTaXRlKGlkPSR7dGhpcy5pZH0sIHVuaXhOYW1lPSR7dGhpcy51bml4TmFtZX0sIHRpdGxlPSR7dGhpcy50aXRsZX0pYDtcbiAgfVxufVxuIiwKICAgICJpbXBvcnQgdHlwZSB7IFdpa2lkb3RSZXN1bHRBc3luYyB9IGZyb20gJy4uLy4uLy4uL2NvbW1vbi90eXBlcyc7XG5pbXBvcnQgeyBTaXRlIH0gZnJvbSAnLi4vLi4vc2l0ZSc7XG5pbXBvcnQgdHlwZSB7IENsaWVudCB9IGZyb20gJy4uL2NsaWVudCc7XG5cbi8qKlxuICog44K144Kk44OI5pON5L2c44Ki44Kv44K744K1XG4gKi9cbmV4cG9ydCBjbGFzcyBTaXRlQWNjZXNzb3Ige1xuICBwdWJsaWMgcmVhZG9ubHkgY2xpZW50OiBDbGllbnQ7XG5cbiAgY29uc3RydWN0b3IoY2xpZW50OiBDbGllbnQpIHtcbiAgICB0aGlzLmNsaWVudCA9IGNsaWVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBVTklY5ZCN44GL44KJ44K144Kk44OI44KS5Y+W5b6X44GZ44KLXG4gICAqIEBwYXJhbSB1bml4TmFtZSAtIOOCteOCpOODiOOBrlVOSVjlkI3vvIjkvos6ICdzY3AtanAn77yJXG4gICAqIEByZXR1cm5zIOOCteOCpOODiOOCquODluOCuOOCp+OCr+ODiFxuICAgKi9cbiAgZ2V0KHVuaXhOYW1lOiBzdHJpbmcpOiBXaWtpZG90UmVzdWx0QXN5bmM8U2l0ZT4ge1xuICAgIHJldHVybiBTaXRlLmZyb21Vbml4TmFtZSh0aGlzLmNsaWVudCwgdW5peE5hbWUpO1xuICB9XG59XG5cbmV4cG9ydCB7IFNpdGUgfTtcbiIsCiAgICAiaW1wb3J0IHsgTm90Rm91bmRFeGNlcHRpb24gfSBmcm9tICcuLi8uLi8uLi9jb21tb24vZXJyb3JzJztcbmltcG9ydCB7IHR5cGUgV2lraWRvdFJlc3VsdEFzeW5jLCB3ZEVyckFzeW5jLCB3ZE9rQXN5bmMgfSBmcm9tICcuLi8uLi8uLi9jb21tb24vdHlwZXMnO1xuaW1wb3J0IHsgVXNlciwgdHlwZSBVc2VyQ29sbGVjdGlvbiB9IGZyb20gJy4uLy4uL3VzZXInO1xuaW1wb3J0IHR5cGUgeyBDbGllbnQgfSBmcm9tICcuLi9jbGllbnQnO1xuXG4vKipcbiAqIOODpuODvOOCtuODvOWPluW+l+OCquODl+OCt+ODp+ODs1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEdldFVzZXJPcHRpb25zIHtcbiAgLyoqIOODpuODvOOCtuODvOOBjOimi+OBpOOBi+OCieOBquOBhOWgtOWQiOOBq+OCqOODqeODvOOCkueZuueUn+OBleOBm+OCi++8iOODh+ODleOCqeODq+ODiDogZmFsc2XvvIkgKi9cbiAgcmFpc2VXaGVuTm90Rm91bmQ/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIOODpuODvOOCtuODvOaTjeS9nOOCouOCr+OCu+OCtVxuICovXG5leHBvcnQgY2xhc3MgVXNlckFjY2Vzc29yIHtcbiAgcHVibGljIHJlYWRvbmx5IGNsaWVudDogQ2xpZW50O1xuXG4gIGNvbnN0cnVjdG9yKGNsaWVudDogQ2xpZW50KSB7XG4gICAgdGhpcy5jbGllbnQgPSBjbGllbnQ7XG4gIH1cblxuICAvKipcbiAgICog44Om44O844K244O85ZCN44GL44KJ44Om44O844K244O844KS5Y+W5b6X44GZ44KLXG4gICAqIEBwYXJhbSBuYW1lIC0g44Om44O844K244O85ZCNXG4gICAqIEBwYXJhbSBvcHRpb25zIC0g5Y+W5b6X44Kq44OX44K344On44OzXG4gICAqIEByZXR1cm5zIOODpuODvOOCtuODvO+8iOWtmOWcqOOBl+OBquOBhOWgtOWQiOOBr251bGzjgIFyYWlzZVdoZW5Ob3RGb3VuZOOBjHRydWXjga7loLTlkIjjga/jgqjjg6njg7zvvIlcbiAgICovXG4gIGdldChuYW1lOiBzdHJpbmcsIG9wdGlvbnM6IEdldFVzZXJPcHRpb25zID0ge30pOiBXaWtpZG90UmVzdWx0QXN5bmM8VXNlciB8IG51bGw+IHtcbiAgICBjb25zdCB7IHJhaXNlV2hlbk5vdEZvdW5kID0gZmFsc2UgfSA9IG9wdGlvbnM7XG5cbiAgICByZXR1cm4gVXNlci5mcm9tTmFtZSh0aGlzLmNsaWVudCwgbmFtZSkuYW5kVGhlbigodXNlcikgPT4ge1xuICAgICAgaWYgKHVzZXIgPT09IG51bGwgJiYgcmFpc2VXaGVuTm90Rm91bmQpIHtcbiAgICAgICAgcmV0dXJuIHdkRXJyQXN5bmMobmV3IE5vdEZvdW5kRXhjZXB0aW9uKGBVc2VyIG5vdCBmb3VuZDogJHtuYW1lfWApKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3ZE9rQXN5bmModXNlcik7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICog6KSH5pWw44Om44O844K244O85ZCN44GL44KJ44Om44O844K244O844KS5Y+W5b6X44GZ44KLXG4gICAqIEBwYXJhbSBuYW1lcyAtIOODpuODvOOCtuODvOWQjemFjeWIl1xuICAgKiBAcGFyYW0gb3B0aW9ucyAtIOWPluW+l+OCquODl+OCt+ODp+ODs1xuICAgKiBAcmV0dXJucyDjg6bjg7zjgrbjg7zjgrPjg6zjgq/jgrfjg6fjg7PvvIjlrZjlnKjjgZfjgarjgYTjg6bjg7zjgrbjg7zjga9udWxs44CBcmFpc2VXaGVuTm90Rm91bmTjgYx0cnVl44Gu5aC05ZCI44Gv44Ko44Op44O877yJXG4gICAqL1xuICBnZXRNYW55KG5hbWVzOiBzdHJpbmdbXSwgb3B0aW9uczogR2V0VXNlck9wdGlvbnMgPSB7fSk6IFdpa2lkb3RSZXN1bHRBc3luYzxVc2VyQ29sbGVjdGlvbj4ge1xuICAgIGNvbnN0IHsgcmFpc2VXaGVuTm90Rm91bmQgPSBmYWxzZSB9ID0gb3B0aW9ucztcblxuICAgIHJldHVybiBVc2VyLmZyb21OYW1lcyh0aGlzLmNsaWVudCwgbmFtZXMpLmFuZFRoZW4oKGNvbGxlY3Rpb24pID0+IHtcbiAgICAgIGlmIChyYWlzZVdoZW5Ob3RGb3VuZCkge1xuICAgICAgICBjb25zdCBub3RGb3VuZE5hbWVzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5hbWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgY29uc3QgbmFtZSA9IG5hbWVzW2ldO1xuICAgICAgICAgIGlmIChjb2xsZWN0aW9uW2ldID09PSBudWxsICYmIG5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbm90Rm91bmROYW1lcy5wdXNoKG5hbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobm90Rm91bmROYW1lcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgcmV0dXJuIHdkRXJyQXN5bmMobmV3IE5vdEZvdW5kRXhjZXB0aW9uKGBVc2VycyBub3QgZm91bmQ6ICR7bm90Rm91bmROYW1lcy5qb2luKCcsICcpfWApKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHdkT2tBc3luYyhjb2xsZWN0aW9uKTtcbiAgICB9KTtcbiAgfVxufVxuIiwKICAgICJpbXBvcnQgeyBMb2dpblJlcXVpcmVkRXJyb3IgfSBmcm9tICcuLi8uLi9jb21tb24vZXJyb3JzJztcbmltcG9ydCB7XG4gIGZyb21Qcm9taXNlLFxuICB0eXBlIFdpa2lkb3RSZXN1bHQsXG4gIHR5cGUgV2lraWRvdFJlc3VsdEFzeW5jLFxuICB3ZEVycixcbiAgd2RPayxcbiAgd2RPa0FzeW5jLFxufSBmcm9tICcuLi8uLi9jb21tb24vdHlwZXMnO1xuaW1wb3J0IHsgQU1DQ2xpZW50LCB0eXBlIEFNQ0NvbmZpZywgbG9naW4sIGxvZ291dCB9IGZyb20gJy4uLy4uL2Nvbm5lY3Rvcic7XG5pbXBvcnQgdHlwZSB7IFVzZXIgfSBmcm9tICcuLi91c2VyL3VzZXInO1xuaW1wb3J0IHsgUHJpdmF0ZU1lc3NhZ2VBY2Nlc3NvciB9IGZyb20gJy4vYWNjZXNzb3JzL3BtLWFjY2Vzc29yJztcbmltcG9ydCB7IFNpdGVBY2Nlc3NvciB9IGZyb20gJy4vYWNjZXNzb3JzL3NpdGUtYWNjZXNzb3InO1xuaW1wb3J0IHsgVXNlckFjY2Vzc29yIH0gZnJvbSAnLi9hY2Nlc3NvcnMvdXNlci1hY2Nlc3Nvcic7XG5cbi8qKlxuICog44Kv44Op44Kk44Ki44Oz44OI5L2c5oiQ44Kq44OX44K344On44OzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2xpZW50T3B0aW9ucyB7XG4gIC8qKiBXaWtpZG9044Om44O844K244O85ZCNICovXG4gIHVzZXJuYW1lPzogc3RyaW5nO1xuXG4gIC8qKiBXaWtpZG9044OR44K544Ov44O844OJICovXG4gIHBhc3N3b3JkPzogc3RyaW5nO1xuXG4gIC8qKiDjg5njg7zjgrnjg4njg6HjgqTjg7PvvIjjg4fjg5Xjgqnjg6vjg4g6IHdpa2lkb3QuY29t77yJICovXG4gIGRvbWFpbj86IHN0cmluZztcblxuICAvKiogQU1D6Kit5a6a44Kq44O844OQ44O844Op44Kk44OJICovXG4gIGFtY0NvbmZpZz86IFBhcnRpYWw8QU1DQ29uZmlnPjtcbn1cblxuLyoqXG4gKiBXaWtpZG9044Kv44Op44Kk44Ki44Oz44OIXG4gKiDjg6njgqTjg5bjg6njg6rjga7jg6HjgqTjg7Pjgqjjg7Pjg4jjg6rjg53jgqTjg7Pjg4hcbiAqL1xuZXhwb3J0IGNsYXNzIENsaWVudCB7XG4gIC8qKiBBTUPjgq/jg6njgqTjgqLjg7Pjg4ggKi9cbiAgcHVibGljIHJlYWRvbmx5IGFtY0NsaWVudDogQU1DQ2xpZW50O1xuXG4gIC8qKiDjg5njg7zjgrnjg4njg6HjgqTjg7MgKi9cbiAgcHVibGljIHJlYWRvbmx5IGRvbWFpbjogc3RyaW5nO1xuXG4gIC8qKiDjg6bjg7zjgrbjg7zmk43kvZzjgqLjgq/jgrvjgrUgKi9cbiAgcHVibGljIHJlYWRvbmx5IHVzZXI6IFVzZXJBY2Nlc3NvcjtcblxuICAvKiog44K144Kk44OI5pON5L2c44Ki44Kv44K744K1ICovXG4gIHB1YmxpYyByZWFkb25seSBzaXRlOiBTaXRlQWNjZXNzb3I7XG5cbiAgLyoqIOODl+ODqeOCpOODmeODvOODiOODoeODg+OCu+ODvOOCuOaTjeS9nOOCouOCr+OCu+OCtSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcHJpdmF0ZU1lc3NhZ2U6IFByaXZhdGVNZXNzYWdlQWNjZXNzb3I7XG5cbiAgLyoqIOODreOCsOOCpOODs+S4reOBruODpuODvOOCtuODvOWQjSAqL1xuICBwcml2YXRlIF91c2VybmFtZTogc3RyaW5nIHwgbnVsbDtcblxuICAvKiog44Ot44Kw44Kk44Oz5Lit44Gu44Om44O844K244O8ICovXG4gIHByaXZhdGUgX21lOiBVc2VyIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIOODl+ODqeOCpOODmeODvOODiOOCs+ODs+OCueODiOODqeOCr+OCv1xuICAgKiBjcmVhdGXjg6Hjgr3jg4Pjg4njgpLkvb/nlKjjgZfjgabjgqTjg7Pjgrnjgr/jg7PjgrnjgpLkvZzmiJDjgZnjgotcbiAgICovXG4gIHByaXZhdGUgY29uc3RydWN0b3IoYW1jQ2xpZW50OiBBTUNDbGllbnQsIGRvbWFpbjogc3RyaW5nLCB1c2VybmFtZTogc3RyaW5nIHwgbnVsbCA9IG51bGwpIHtcbiAgICB0aGlzLmFtY0NsaWVudCA9IGFtY0NsaWVudDtcbiAgICB0aGlzLmRvbWFpbiA9IGRvbWFpbjtcbiAgICB0aGlzLl91c2VybmFtZSA9IHVzZXJuYW1lO1xuXG4gICAgLy8g44Ki44Kv44K744K144KS5Yid5pyf5YyWXG4gICAgdGhpcy51c2VyID0gbmV3IFVzZXJBY2Nlc3Nvcih0aGlzKTtcbiAgICB0aGlzLnNpdGUgPSBuZXcgU2l0ZUFjY2Vzc29yKHRoaXMpO1xuICAgIHRoaXMucHJpdmF0ZU1lc3NhZ2UgPSBuZXcgUHJpdmF0ZU1lc3NhZ2VBY2Nlc3Nvcih0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg63jgrDjgqTjg7PkuK3jga7jg6bjg7zjgrbjg7zlkI3jgpLlj5blvpdcbiAgICovXG4gIGdldCB1c2VybmFtZSgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fdXNlcm5hbWU7XG4gIH1cblxuICAvKipcbiAgICog44Ot44Kw44Kk44Oz5Lit44Gu44Om44O844K244O844KS5Y+W5b6XXG4gICAqIOODreOCsOOCpOODs+OBl+OBpuOBhOOBquOBhOWgtOWQiOOBr251bGxcbiAgICovXG4gIGdldCBtZSgpOiBVc2VyIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX21lO1xuICB9XG5cbiAgLyoqXG4gICAqIOOCr+ODqeOCpOOCouODs+ODiOOCkuS9nOaIkOOBmeOCi1xuICAgKiBAcGFyYW0gb3B0aW9ucyAtIOOCr+ODqeOCpOOCouODs+ODiOOCquODl+OCt+ODp+ODs1xuICAgKiBAcmV0dXJucyDjgq/jg6njgqTjgqLjg7Pjg4jjgqTjg7Pjgrnjgr/jg7PjgrlcbiAgICovXG4gIHN0YXRpYyBjcmVhdGUob3B0aW9uczogQ2xpZW50T3B0aW9ucyA9IHt9KTogV2lraWRvdFJlc3VsdEFzeW5jPENsaWVudD4ge1xuICAgIGNvbnN0IHsgdXNlcm5hbWUsIHBhc3N3b3JkLCBkb21haW4gPSAnd2lraWRvdC5jb20nLCBhbWNDb25maWcgPSB7fSB9ID0gb3B0aW9ucztcblxuICAgIC8vIEFNQ+OCr+ODqeOCpOOCouODs+ODiOOCkuS9nOaIkFxuICAgIGNvbnN0IGFtY0NsaWVudCA9IG5ldyBBTUNDbGllbnQoYW1jQ29uZmlnLCBkb21haW4pO1xuXG4gICAgLy8g6KqN6Ki85oOF5aCx44GM44GC44KL5aC05ZCI44Gv44Ot44Kw44Kk44OzXG4gICAgaWYgKHVzZXJuYW1lICYmIHBhc3N3b3JkKSB7XG4gICAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgY2xpZW50ID0gbmV3IENsaWVudChhbWNDbGllbnQsIGRvbWFpbiwgdXNlcm5hbWUpO1xuICAgICAgICAgIGNvbnN0IGxvZ2luUmVzdWx0ID0gYXdhaXQgbG9naW4oY2xpZW50LCB1c2VybmFtZSwgcGFzc3dvcmQpO1xuICAgICAgICAgIGlmIChsb2dpblJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgICB0aHJvdyBsb2dpblJlc3VsdC5lcnJvcjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyDjg63jgrDjgqTjg7PkuK3jga7jg6bjg7zjgrbjg7zmg4XloLHjgpLlj5blvpdcbiAgICAgICAgICBjb25zdCB7IFVzZXIgfSA9IGF3YWl0IGltcG9ydCgnLi4vdXNlci91c2VyJyk7XG4gICAgICAgICAgY29uc3QgdXNlclJlc3VsdCA9IGF3YWl0IFVzZXIuZnJvbU5hbWUoY2xpZW50LCB1c2VybmFtZSk7XG4gICAgICAgICAgaWYgKHVzZXJSZXN1bHQuaXNPaygpICYmIHVzZXJSZXN1bHQudmFsdWUpIHtcbiAgICAgICAgICAgIGNsaWVudC5fbWUgPSB1c2VyUmVzdWx0LnZhbHVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBjbGllbnQ7XG4gICAgICAgIH0pKCksXG4gICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIExvZ2luUmVxdWlyZWRFcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbmV3IExvZ2luUmVxdWlyZWRFcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBjbGllbnQ6ICR7U3RyaW5nKGVycm9yKX1gKTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyDoqo3oqLzjgarjgZfjga7jgq/jg6njgqTjgqLjg7Pjg4jjgpLov5TjgZlcbiAgICByZXR1cm4gd2RPa0FzeW5jKG5ldyBDbGllbnQoYW1jQ2xpZW50LCBkb21haW4pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmnKroqo3oqLzjgq/jg6njgqTjgqLjg7Pjg4jjgpLkvZzmiJDjgZnjgotcbiAgICogQHBhcmFtIG9wdGlvbnMgLSDjgq/jg6njgqTjgqLjg7Pjg4jjgqrjg5fjgrfjg6fjg7PvvIjoqo3oqLzmg4XloLHku6XlpJbvvIlcbiAgICogQHJldHVybnMg44Kv44Op44Kk44Ki44Oz44OI44Kk44Oz44K544K/44Oz44K5XG4gICAqL1xuICBzdGF0aWMgY3JlYXRlQW5vbnltb3VzKG9wdGlvbnM6IE9taXQ8Q2xpZW50T3B0aW9ucywgJ3VzZXJuYW1lJyB8ICdwYXNzd29yZCc+ID0ge30pOiBDbGllbnQge1xuICAgIGNvbnN0IHsgZG9tYWluID0gJ3dpa2lkb3QuY29tJywgYW1jQ29uZmlnID0ge30gfSA9IG9wdGlvbnM7XG4gICAgY29uc3QgYW1jQ2xpZW50ID0gbmV3IEFNQ0NsaWVudChhbWNDb25maWcsIGRvbWFpbik7XG4gICAgcmV0dXJuIG5ldyBDbGllbnQoYW1jQ2xpZW50LCBkb21haW4pO1xuICB9XG5cbiAgLyoqXG4gICAqIOODreOCsOOCpOODs+eKtuaFi+OCkueiuuiqjeOBmeOCi1xuICAgKiBAcmV0dXJucyDjg63jgrDjgqTjg7PmuIjjgb/jgarjgol0cnVlXG4gICAqL1xuICBpc0xvZ2dlZEluKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl91c2VybmFtZSAhPT0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg63jgrDjgqTjg7PjgpLopoHmsYLjgZnjgotcbiAgICog44Ot44Kw44Kk44Oz5riI44G/44Gn44Gq44GE5aC05ZCI44GvTG9naW5SZXF1aXJlZEVycm9y44KS6L+U44GZXG4gICAqIEByZXR1cm5zIOaIkOWKn+aZguOBr3ZvaWRcbiAgICovXG4gIHJlcXVpcmVMb2dpbigpOiBXaWtpZG90UmVzdWx0PHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuaXNMb2dnZWRJbigpKSB7XG4gICAgICByZXR1cm4gd2RFcnIobmV3IExvZ2luUmVxdWlyZWRFcnJvcigpKTtcbiAgICB9XG4gICAgcmV0dXJuIHdkT2sodW5kZWZpbmVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjgq/jg6njgqTjgqLjg7Pjg4jjgpLjgq/jg63jg7zjgrrjgZnjgotcbiAgICog44K744OD44K344On44Oz44GM44GC44KL5aC05ZCI44Gv44Ot44Kw44Ki44Km44OI44KS6Kmm44G/44KLXG4gICAqL1xuICBjbG9zZSgpOiBXaWtpZG90UmVzdWx0QXN5bmM8dm9pZD4ge1xuICAgIGlmICh0aGlzLmlzTG9nZ2VkSW4oKSkge1xuICAgICAgcmV0dXJuIGxvZ291dCh0aGlzKS5tYXAoKCkgPT4ge1xuICAgICAgICB0aGlzLl91c2VybmFtZSA9IG51bGw7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9KTtcbiAgICB9XG4g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UyxJQUFJLE9BQU8sV0FBVyxRQUFRLFFBQVE7QUFBQSxRQUNyRCxNQUFNLGNBQWMsTUFBTSxNQUFNLFFBQVEsVUFBVSxRQUFRO0FBQUEsUUFDMUQsSUFBSSxZQUFZLE1BQU0sR0FBRztBQUFBLFVBQ3ZCLE1BQU0sWUFBWTtBQUFBLFFBQ3BCO0FBQUEsUUFHQSxRQUFRLGdCQUFTLE1BQWE7QUFBQSxRQUM5QixNQUFNLGFBQWEsTUFBTSxNQUFLLFNBQVMsUUFBUSxRQUFRO0FBQUEsUUFDdkQsSUFBSSxXQUFXLEtBQUssS0FBSyxXQUFXLE9BQU87QUFBQSxVQUN6QyxPQUFPLE1BQU0sV0FBVztBQUFBLFFBQzFCO0FBQUEsUUFFQSxPQUFPO0FBQUEsU0FDTixHQUNILENBQUMsVUFBVTtBQUFBLFFBQ1QsSUFBSSxpQkFBaUIsb0JBQW9CO0FBQUEsVUFDdkMsT0FBTztBQUFBLFFBQ1Q7QUFBQSxRQUNBLE9BQU8sSUFBSSxtQkFBbUIsNEJBQTRCLE9BQU8sS0FBSyxHQUFHO0FBQUEsT0FFN0U7QUFBQSxJQUNGO0FBQUEsSUFHQSxPQUFPLFVBQVUsSUFBSSxPQUFPLFdBQVcsTUFBTSxDQUFDO0FBQUE7QUFBQSxTQVF6QyxlQUFlLENBQUMsVUFBd0QsQ0FBQyxHQUFXO0FBQUEsSUFDekYsUUFBUSxTQUFTLGVBQWUsWUFBWSxDQUFDLE1BQU07QUFBQSxJQUNuRCxNQUFNLFlBQVksSUFBSSxVQUFVLFdBQVcsTUFBTTtBQUFBLElBQ2pELE9BQU8sSUFBSSxPQUFPLFdBQVcsTUFBTTtBQUFBO0FBQUEsRUFPckMsVUFBVSxHQUFZO0FBQUEsSUFDcEIsT0FBTyxLQUFLLGNBQWM7QUFBQTtBQUFBLEVBUTVCLFlBQVksR0FBd0I7QUFBQSxJQUNsQyxJQUFJLENBQUMsS0FBSyxXQUFXLEdBQUc7QUFBQSxNQUN0QixPQUFPLE1BQU0sSUFBSSxrQkFBb0I7QUFBQSxJQUN2QztBQUFBLElBQ0EsT0FBTyxLQUFLLFNBQVM7QUFBQTtBQUFBLEVBT3ZCLEtBQUssR0FBNkI7QUFBQSxJQUNoQyxJQUFJLEtBQUssV0FBVyxHQUFHO0FBQUEsTUFDckIsT0FBTyxPQUFPLElBQUksRUFBRSxJQUFJLE1BQU07QUFBQSxRQUM1QixLQUFLLFlBQVk7QUFBQSxRQUNqQjtBQUFBLE9BQ0Q7QUFBQSxJQUNIO0FBQUEsSUFDQSxPQUFPLFVBQVUsU0FBUztBQUFBO0FBRTlCOyIsCiAgImRlYnVnSWQiOiAiMUEwQUYzQUE0RDVDQUI0RDY0NzU2RTIxNjQ3NTZFMjEiLAogICJuYW1lcyI6IFtdCn0=
|