@discordeno/rest 21.0.1-next.fca0b40 → 22.0.0-beta.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/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/invalidBucket.d.ts.map +1 -0
- package/dist/invalidBucket.js +82 -0
- package/dist/manager.d.ts.map +1 -0
- package/dist/manager.js +1844 -0
- package/dist/{types/queue.d.ts → queue.d.ts} +2 -2
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +190 -0
- package/dist/routes.d.ts +9 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +674 -0
- package/dist/{types/types.d.ts → types.d.ts} +462 -193
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/{types/typings → typings}/routes.d.ts +19 -1
- package/dist/typings/routes.d.ts.map +1 -0
- package/dist/typings/routes.js +3 -0
- package/package.json +27 -37
- package/dist/cjs/index.cjs +0 -25
- package/dist/cjs/invalidBucket.cjs +0 -86
- package/dist/cjs/manager.cjs +0 -1665
- package/dist/cjs/queue.cjs +0 -164
- package/dist/cjs/routes.cjs +0 -631
- package/dist/cjs/types.cjs +0 -6
- package/dist/cjs/typings/routes.cjs +0 -6
- package/dist/esm/index.js +0 -8
- package/dist/esm/invalidBucket.js +0 -82
- package/dist/esm/manager.js +0 -1623
- package/dist/esm/queue.js +0 -154
- package/dist/esm/routes.js +0 -621
- package/dist/esm/types.js +0 -3
- package/dist/esm/typings/routes.js +0 -3
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/invalidBucket.d.ts.map +0 -1
- package/dist/types/manager.d.ts.map +0 -1
- package/dist/types/queue.d.ts.map +0 -1
- package/dist/types/routes.d.ts +0 -3
- package/dist/types/routes.d.ts.map +0 -1
- package/dist/types/types.d.ts.map +0 -1
- package/dist/types/typings/routes.d.ts.map +0 -1
- /package/dist/{types/index.d.ts → index.d.ts} +0 -0
- /package/dist/{types/invalidBucket.d.ts → invalidBucket.d.ts} +0 -0
- /package/dist/{types/manager.d.ts → manager.d.ts} +0 -0
package/dist/manager.js
ADDED
|
@@ -0,0 +1,1844 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
import { inspect } from 'node:util';
|
|
3
|
+
import { camelize, camelToSnakeCase, DISCORDENO_VERSION, delay, getBotIdFromToken, hasProperty, logger, processReactionString, snowflakeToTimestamp } from '@discordeno/utils';
|
|
4
|
+
import { createInvalidRequestBucket } from './invalidBucket.js';
|
|
5
|
+
import { Queue } from './queue.js';
|
|
6
|
+
import { createRoutes } from './routes.js';
|
|
7
|
+
export const DISCORD_API_VERSION = 10;
|
|
8
|
+
export const DISCORD_API_URL = 'https://discord.com/api';
|
|
9
|
+
export const AUDIT_LOG_REASON_HEADER = 'x-audit-log-reason';
|
|
10
|
+
export const RATE_LIMIT_REMAINING_HEADER = 'x-ratelimit-remaining';
|
|
11
|
+
export const RATE_LIMIT_RESET_AFTER_HEADER = 'x-ratelimit-reset-after';
|
|
12
|
+
export const RATE_LIMIT_GLOBAL_HEADER = 'x-ratelimit-global';
|
|
13
|
+
export const RATE_LIMIT_BUCKET_HEADER = 'x-ratelimit-bucket';
|
|
14
|
+
export const RATE_LIMIT_LIMIT_HEADER = 'x-ratelimit-limit';
|
|
15
|
+
export const RATE_LIMIT_SCOPE_HEADER = 'x-ratelimit-scope';
|
|
16
|
+
export function createRestManager(options) {
|
|
17
|
+
const applicationId = options.applicationId ? BigInt(options.applicationId) : getBotIdFromToken(options.token);
|
|
18
|
+
const baseUrl = (options.proxy?.baseUrl ?? DISCORD_API_URL).replace(/\/$/, '');
|
|
19
|
+
// Discord error can get nested a lot, so we use a custom inspect to change the depth to Infinity
|
|
20
|
+
const baseErrorPrototype = {
|
|
21
|
+
[inspect.custom] (_depth, options, _inspect) {
|
|
22
|
+
return _inspect(this, {
|
|
23
|
+
...options,
|
|
24
|
+
depth: Infinity,
|
|
25
|
+
// Since we call inspect on ourself, we need to disable the calls to the inspect.custom symbol or else it will cause an infinite loop.
|
|
26
|
+
customInspect: false
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const rest = {
|
|
31
|
+
applicationId,
|
|
32
|
+
authorization: options.proxy?.authorization,
|
|
33
|
+
authorizationHeader: options.proxy?.authorizationHeader ?? 'authorization',
|
|
34
|
+
baseUrl,
|
|
35
|
+
deleteQueueDelay: 60000,
|
|
36
|
+
globallyRateLimited: false,
|
|
37
|
+
invalidBucket: createInvalidRequestBucket({
|
|
38
|
+
logger: options.logger
|
|
39
|
+
}),
|
|
40
|
+
isProxied: !baseUrl.startsWith(DISCORD_API_URL),
|
|
41
|
+
updateBearerTokenEndpoint: options.proxy?.updateBearerTokenEndpoint,
|
|
42
|
+
retryProxiedRequests: options.proxy?.retryRequests ?? false,
|
|
43
|
+
maxRetryCount: Infinity,
|
|
44
|
+
maxProxyRetryCount: 15,
|
|
45
|
+
proxyRetryDelayStep: 250,
|
|
46
|
+
requestTimeout: options.requestTimeout ?? 30000,
|
|
47
|
+
processingRateLimitedPaths: false,
|
|
48
|
+
queues: new Map(),
|
|
49
|
+
rateLimitedPaths: new Map(),
|
|
50
|
+
token: options.token,
|
|
51
|
+
version: options.version ?? DISCORD_API_VERSION,
|
|
52
|
+
logger: options.logger ?? logger,
|
|
53
|
+
events: {
|
|
54
|
+
request: ()=>{},
|
|
55
|
+
response: ()=>{},
|
|
56
|
+
requestError: ()=>{},
|
|
57
|
+
...options.events
|
|
58
|
+
},
|
|
59
|
+
routes: createRoutes(),
|
|
60
|
+
createBaseHeaders () {
|
|
61
|
+
return {
|
|
62
|
+
'user-agent': `DiscordBot (https://github.com/discordeno/discordeno, v${DISCORDENO_VERSION})`
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
checkRateLimits (url, identifier) {
|
|
66
|
+
const ratelimited = rest.rateLimitedPaths.get(`${identifier}${url}`);
|
|
67
|
+
const global = rest.rateLimitedPaths.get('global');
|
|
68
|
+
const now = Date.now();
|
|
69
|
+
if (ratelimited && now < ratelimited.resetTimestamp) {
|
|
70
|
+
return ratelimited.resetTimestamp - now;
|
|
71
|
+
}
|
|
72
|
+
if (global && now < global.resetTimestamp) {
|
|
73
|
+
return global.resetTimestamp - now;
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
},
|
|
77
|
+
async updateTokenQueues (oldToken, newToken) {
|
|
78
|
+
if (rest.isProxied) {
|
|
79
|
+
if (!rest.updateBearerTokenEndpoint) {
|
|
80
|
+
throw new Error("The 'proxy.updateBearerTokenEndpoint' option needs to be set when using a rest proxy and needed to call 'updateTokenQueues'");
|
|
81
|
+
}
|
|
82
|
+
const headers = {
|
|
83
|
+
'content-type': 'application/json'
|
|
84
|
+
};
|
|
85
|
+
if (rest.authorization !== undefined) {
|
|
86
|
+
headers[rest.authorizationHeader] = rest.authorization;
|
|
87
|
+
}
|
|
88
|
+
await fetch(`${rest.baseUrl}/${rest.updateBearerTokenEndpoint}`, {
|
|
89
|
+
method: 'POST',
|
|
90
|
+
body: JSON.stringify({
|
|
91
|
+
oldToken,
|
|
92
|
+
newToken
|
|
93
|
+
}),
|
|
94
|
+
headers
|
|
95
|
+
});
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const newIdentifier = `Bearer ${newToken}`;
|
|
99
|
+
// Update all the queues
|
|
100
|
+
for (const [key, queue] of rest.queues.entries()){
|
|
101
|
+
if (!key.startsWith(`Bearer ${oldToken}`)) continue;
|
|
102
|
+
rest.queues.delete(key);
|
|
103
|
+
queue.identifier = newIdentifier;
|
|
104
|
+
const newKey = `${newIdentifier}${queue.url}`;
|
|
105
|
+
const newQueue = rest.queues.get(newKey);
|
|
106
|
+
// Merge the queues
|
|
107
|
+
if (newQueue) {
|
|
108
|
+
newQueue.waiting.unshift(...queue.waiting);
|
|
109
|
+
newQueue.pending.unshift(...queue.pending);
|
|
110
|
+
queue.waiting = [];
|
|
111
|
+
queue.pending = [];
|
|
112
|
+
queue.cleanup();
|
|
113
|
+
} else {
|
|
114
|
+
rest.queues.set(newKey, queue);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
for (const [key, ratelimitPath] of rest.rateLimitedPaths.entries()){
|
|
118
|
+
if (!key.startsWith(`Bearer ${oldToken}`)) continue;
|
|
119
|
+
rest.rateLimitedPaths.set(`${newIdentifier}${ratelimitPath.url}`, ratelimitPath);
|
|
120
|
+
if (ratelimitPath.bucketId) {
|
|
121
|
+
rest.rateLimitedPaths.set(`${newIdentifier}${ratelimitPath.bucketId}`, ratelimitPath);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
changeToDiscordFormat (obj) {
|
|
126
|
+
if (obj === null) return null;
|
|
127
|
+
if (typeof obj === 'object') {
|
|
128
|
+
if (Array.isArray(obj)) {
|
|
129
|
+
return obj.map((item)=>rest.changeToDiscordFormat(item));
|
|
130
|
+
}
|
|
131
|
+
const newObj = {};
|
|
132
|
+
for (const key of Object.keys(obj)){
|
|
133
|
+
const value = obj[key];
|
|
134
|
+
// If the key is already in snake_case we can assume it is already in the discord format.
|
|
135
|
+
if (key.includes('_')) {
|
|
136
|
+
newObj[key] = value;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (value !== undefined) {
|
|
140
|
+
switch(key){
|
|
141
|
+
case 'nameLocalizations':
|
|
142
|
+
newObj.name_localizations = value;
|
|
143
|
+
continue;
|
|
144
|
+
case 'descriptionLocalizations':
|
|
145
|
+
newObj.description_localizations = value;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
newObj[camelToSnakeCase(key)] = rest.changeToDiscordFormat(value);
|
|
150
|
+
}
|
|
151
|
+
return newObj;
|
|
152
|
+
}
|
|
153
|
+
if (typeof obj === 'bigint') return obj.toString();
|
|
154
|
+
return obj;
|
|
155
|
+
},
|
|
156
|
+
createRequestBody (method, options) {
|
|
157
|
+
const headers = this.createBaseHeaders();
|
|
158
|
+
if (options?.unauthorized !== true) headers.authorization = `Bot ${rest.token}`;
|
|
159
|
+
// IF A REASON IS PROVIDED ENCODE IT IN HEADERS
|
|
160
|
+
if (options?.reason !== undefined) {
|
|
161
|
+
headers[AUDIT_LOG_REASON_HEADER] = encodeURIComponent(options?.reason);
|
|
162
|
+
}
|
|
163
|
+
let body;
|
|
164
|
+
// Have to check for attachments first, since body then has to be send in a different way.
|
|
165
|
+
if (options?.files !== undefined) {
|
|
166
|
+
const form = new FormData();
|
|
167
|
+
for(let i = 0; i < options.files.length; ++i){
|
|
168
|
+
form.append(`files[${i}]`, options.files[i].blob, options.files[i].name);
|
|
169
|
+
}
|
|
170
|
+
// Have to use changeToDiscordFormat or else JSON.stringify may throw an error for the presence of BigInt(s) in the json
|
|
171
|
+
form.append('payload_json', JSON.stringify(rest.changeToDiscordFormat({
|
|
172
|
+
...options.body,
|
|
173
|
+
files: undefined
|
|
174
|
+
})));
|
|
175
|
+
// No need to set the `content-type` header since `fetch` does that automatically for us when we use a `FormData` object.
|
|
176
|
+
body = form;
|
|
177
|
+
} else if (options?.body && options.headers && options.headers['content-type'] === 'application/x-www-form-urlencoded') {
|
|
178
|
+
// OAuth2 body handling
|
|
179
|
+
const formBody = [];
|
|
180
|
+
const discordBody = rest.changeToDiscordFormat(options.body);
|
|
181
|
+
for(const prop in discordBody){
|
|
182
|
+
formBody.push(`${encodeURIComponent(prop)}=${encodeURIComponent(discordBody[prop])}`);
|
|
183
|
+
}
|
|
184
|
+
body = formBody.join('&');
|
|
185
|
+
} else if (options?.body !== undefined) {
|
|
186
|
+
if (options.body instanceof FormData) {
|
|
187
|
+
body = options.body;
|
|
188
|
+
// No need to set the `content-type` header since `fetch` does that automatically for us when we use a `FormData` object.
|
|
189
|
+
} else {
|
|
190
|
+
body = JSON.stringify(rest.changeToDiscordFormat(options.body));
|
|
191
|
+
headers['content-type'] = `application/json`;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// SOMETIMES SPECIAL HEADERS (E.G. CUSTOM AUTHORIZATION) NEED TO BE USED
|
|
195
|
+
if (options?.headers) {
|
|
196
|
+
Object.assign(headers, options.headers);
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
body,
|
|
200
|
+
headers,
|
|
201
|
+
method
|
|
202
|
+
};
|
|
203
|
+
},
|
|
204
|
+
createRequestError (error, reason) {
|
|
205
|
+
let errorText;
|
|
206
|
+
switch(reason.status){
|
|
207
|
+
case 400:
|
|
208
|
+
errorText = "The options was improperly formatted, or the server couldn't understand it.";
|
|
209
|
+
break;
|
|
210
|
+
case 401:
|
|
211
|
+
errorText = 'The Authorization header was missing or invalid.';
|
|
212
|
+
break;
|
|
213
|
+
case 403:
|
|
214
|
+
errorText = 'The Authorization token you passed did not have permission to the resource.';
|
|
215
|
+
break;
|
|
216
|
+
case 404:
|
|
217
|
+
errorText = "The resource at the location specified doesn't exist.";
|
|
218
|
+
break;
|
|
219
|
+
case 405:
|
|
220
|
+
errorText = 'The HTTP method used is not valid for the location specified.';
|
|
221
|
+
break;
|
|
222
|
+
case 429:
|
|
223
|
+
errorText = "You're being ratelimited.";
|
|
224
|
+
break;
|
|
225
|
+
case 502:
|
|
226
|
+
errorText = 'There was not a gateway available to process your options. Wait a bit and retry.';
|
|
227
|
+
break;
|
|
228
|
+
default:
|
|
229
|
+
errorText = reason.statusText ?? reason.error ?? 'Unknown error';
|
|
230
|
+
}
|
|
231
|
+
error.message = `[${reason.status}] ${errorText}`;
|
|
232
|
+
// If discord sent us JSON, it is probably going to be an error message from which we can get and add some information about the error to the error message, the full body will be in the error.cause
|
|
233
|
+
// https://docs.discord.com/developers/reference#error-messages
|
|
234
|
+
if (typeof reason.body === 'object' && hasProperty(reason.body, 'code') && hasProperty(reason.body, 'message')) {
|
|
235
|
+
error.message += `\nDiscord error: [${reason.body.code}] ${reason.body.message}`;
|
|
236
|
+
}
|
|
237
|
+
error.cause = Object.assign(Object.create(baseErrorPrototype), reason);
|
|
238
|
+
return error;
|
|
239
|
+
},
|
|
240
|
+
processRateLimitedPaths () {
|
|
241
|
+
const now = Date.now();
|
|
242
|
+
for (const [key, value] of rest.rateLimitedPaths.entries()){
|
|
243
|
+
// rest.debug(
|
|
244
|
+
// `[REST - processRateLimitedPaths] Running for of loop. ${
|
|
245
|
+
// value.resetTimestamp - now
|
|
246
|
+
// }`
|
|
247
|
+
// )
|
|
248
|
+
// If the time has not reached cancel
|
|
249
|
+
if (value.resetTimestamp > now) continue;
|
|
250
|
+
// Rate limit is over, delete the rate limiter
|
|
251
|
+
rest.rateLimitedPaths.delete(key);
|
|
252
|
+
// If it was global, also mark the global value as false
|
|
253
|
+
if (key === 'global') rest.globallyRateLimited = false;
|
|
254
|
+
}
|
|
255
|
+
// ALL PATHS ARE CLEARED CAN CANCEL OUT!
|
|
256
|
+
if (rest.rateLimitedPaths.size === 0) {
|
|
257
|
+
rest.processingRateLimitedPaths = false;
|
|
258
|
+
} else {
|
|
259
|
+
rest.processingRateLimitedPaths = true;
|
|
260
|
+
// RECHECK IN 1 SECOND
|
|
261
|
+
setTimeout(()=>{
|
|
262
|
+
// rest.debug('[REST - processRateLimitedPaths] Running setTimeout.')
|
|
263
|
+
rest.processRateLimitedPaths();
|
|
264
|
+
}, 1000);
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
/** Processes the rate limit headers and determines if it needs to be rate limited and returns the bucket id if available */ processHeaders (url, headers, identifier) {
|
|
268
|
+
let rateLimited = false;
|
|
269
|
+
// GET ALL NECESSARY HEADERS
|
|
270
|
+
const remaining = headers.get(RATE_LIMIT_REMAINING_HEADER);
|
|
271
|
+
const retryAfter = headers.get('Retry-After') ?? headers.get(RATE_LIMIT_RESET_AFTER_HEADER);
|
|
272
|
+
const reset = Date.now() + Number(retryAfter) * 1000;
|
|
273
|
+
const global = headers.get(RATE_LIMIT_GLOBAL_HEADER);
|
|
274
|
+
// undefined override null needed for typings
|
|
275
|
+
const bucketId = headers.get(RATE_LIMIT_BUCKET_HEADER) ?? undefined;
|
|
276
|
+
const limit = headers.get(RATE_LIMIT_LIMIT_HEADER);
|
|
277
|
+
// If we didn't received the identifier, fallback to the bot token
|
|
278
|
+
identifier ??= `Bot ${rest.token}`;
|
|
279
|
+
rest.queues.get(`${identifier}${url}`)?.handleCompletedRequest({
|
|
280
|
+
remaining: remaining ? Number(remaining) : undefined,
|
|
281
|
+
interval: retryAfter ? Number(retryAfter) * 1000 : undefined,
|
|
282
|
+
max: limit ? Number(limit) : undefined
|
|
283
|
+
});
|
|
284
|
+
// IF THERE IS NO REMAINING RATE LIMIT, MARK IT AS RATE LIMITED
|
|
285
|
+
if (remaining === '0') {
|
|
286
|
+
rateLimited = true;
|
|
287
|
+
// SAVE THE URL AS LIMITED, IMPORTANT FOR NEW REQUESTS BY USER WITHOUT BUCKET
|
|
288
|
+
rest.rateLimitedPaths.set(`${identifier}${url}`, {
|
|
289
|
+
url,
|
|
290
|
+
resetTimestamp: reset,
|
|
291
|
+
bucketId
|
|
292
|
+
});
|
|
293
|
+
// SAVE THE BUCKET AS LIMITED SINCE DIFFERENT URLS MAY SHARE A BUCKET
|
|
294
|
+
if (bucketId) {
|
|
295
|
+
rest.rateLimitedPaths.set(`${identifier}${bucketId}`, {
|
|
296
|
+
url,
|
|
297
|
+
resetTimestamp: reset,
|
|
298
|
+
bucketId
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// IF THERE IS NO REMAINING GLOBAL LIMIT, MARK IT RATE LIMITED GLOBALLY
|
|
303
|
+
if (global) {
|
|
304
|
+
const retryAfter = Number(headers.get('retry-after')) * 1000;
|
|
305
|
+
const globalReset = Date.now() + retryAfter;
|
|
306
|
+
// rest.debug(
|
|
307
|
+
// `[REST = Globally Rate Limited] URL: ${url} | Global Rest: ${globalReset}`
|
|
308
|
+
// )
|
|
309
|
+
rest.globallyRateLimited = true;
|
|
310
|
+
rateLimited = true;
|
|
311
|
+
setTimeout(()=>{
|
|
312
|
+
rest.globallyRateLimited = false;
|
|
313
|
+
}, retryAfter);
|
|
314
|
+
rest.rateLimitedPaths.set('global', {
|
|
315
|
+
url: 'global',
|
|
316
|
+
resetTimestamp: globalReset,
|
|
317
|
+
bucketId
|
|
318
|
+
});
|
|
319
|
+
if (bucketId) {
|
|
320
|
+
rest.rateLimitedPaths.set(identifier, {
|
|
321
|
+
url: 'global',
|
|
322
|
+
resetTimestamp: globalReset,
|
|
323
|
+
bucketId
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (rateLimited && !rest.processingRateLimitedPaths) {
|
|
328
|
+
rest.processRateLimitedPaths();
|
|
329
|
+
}
|
|
330
|
+
return rateLimited ? bucketId : undefined;
|
|
331
|
+
},
|
|
332
|
+
async sendRequest (options) {
|
|
333
|
+
const url = `${rest.baseUrl}/v${rest.version}${options.route}`;
|
|
334
|
+
const payload = rest.createRequestBody(options.method, options.requestBodyOptions);
|
|
335
|
+
// Retries a request that was aborted because it hit `rest.requestTimeout`, or rejects it once the retry
|
|
336
|
+
// budget is exhausted. The caller is responsible for the `invalidBucket`/event bookkeeping beforehand.
|
|
337
|
+
const handleTimeout = async (options, error)=>{
|
|
338
|
+
if (options.retryCount >= rest.maxRetryCount) {
|
|
339
|
+
rest.logger.debug(`request to ${url} timed out and exceeded the maximum allowed retries.`);
|
|
340
|
+
options.reject({
|
|
341
|
+
ok: false,
|
|
342
|
+
status: 999,
|
|
343
|
+
error: 'The request timed out and it maxed out the retries limit.',
|
|
344
|
+
errorObject: error
|
|
345
|
+
});
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
rest.logger.debug(`request to ${url} timed out after ${rest.requestTimeout}ms, retrying.`, error);
|
|
349
|
+
options.retryCount += 1;
|
|
350
|
+
await options.retryRequest?.(options);
|
|
351
|
+
};
|
|
352
|
+
const loggingHeaders = {
|
|
353
|
+
...payload.headers
|
|
354
|
+
};
|
|
355
|
+
if (payload.headers.authorization) {
|
|
356
|
+
const authorizationScheme = payload.headers.authorization?.split(' ')[0];
|
|
357
|
+
loggingHeaders.authorization = `${authorizationScheme} tokenhere`;
|
|
358
|
+
}
|
|
359
|
+
// Give this attempt a hard deadline. `AbortSignal.timeout` aborts the fetch (and any in-progress body
|
|
360
|
+
// read) once it fires, which makes the awaited fetch reject so a stalled connection can never keep this
|
|
361
|
+
// queue's `processPending` loop (and therefore the whole queue) wedged forever. Omitted when disabled.
|
|
362
|
+
// The caller's signal is handed to fetch too: fetch refuses to send a request whose signal is already aborted, so a queue entry that got
|
|
363
|
+
// aborted while waiting never goes out, and aborting mid-request tears down the connection.
|
|
364
|
+
const signals = [];
|
|
365
|
+
if (options.requestBodyOptions?.signal) signals.push(options.requestBodyOptions.signal);
|
|
366
|
+
if (rest.requestTimeout > 0) signals.push(AbortSignal.timeout(rest.requestTimeout));
|
|
367
|
+
const request = new Request(url, {
|
|
368
|
+
...payload,
|
|
369
|
+
signal: signals.length > 0 ? AbortSignal.any(signals) : undefined
|
|
370
|
+
});
|
|
371
|
+
rest.events.request(request, {
|
|
372
|
+
body: options.requestBodyOptions?.body
|
|
373
|
+
});
|
|
374
|
+
rest.logger.debug(`sending request to ${url}`, 'with payload:', {
|
|
375
|
+
...payload,
|
|
376
|
+
headers: loggingHeaders
|
|
377
|
+
});
|
|
378
|
+
const response = await fetch(request).catch(async (error)=>{
|
|
379
|
+
rest.events.requestError(request, error, {
|
|
380
|
+
body: options.requestBodyOptions?.body
|
|
381
|
+
});
|
|
382
|
+
// Mark request as completed
|
|
383
|
+
rest.invalidBucket.handleCompletedRequest(999, false);
|
|
384
|
+
// The caller aborted the request, never re-send it, Discord may have received it already. The caller was rejected the moment the signal fired.
|
|
385
|
+
if (options.requestBodyOptions?.signal?.aborted) {
|
|
386
|
+
options.reject({
|
|
387
|
+
ok: false,
|
|
388
|
+
status: 999,
|
|
389
|
+
error: 'The request was aborted.',
|
|
390
|
+
errorObject: error
|
|
391
|
+
});
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
// The attempt hit `rest.requestTimeout` and was aborted. Treat it like a transient failure and retry
|
|
395
|
+
// it through the queue, so a single stalled connection doesn't permanently fail the request.
|
|
396
|
+
if (isTimeoutError(error)) return await handleTimeout(options, error);
|
|
397
|
+
rest.logger.debug(`request fetch to ${url} failed.`, error);
|
|
398
|
+
options.reject({
|
|
399
|
+
ok: false,
|
|
400
|
+
status: 999,
|
|
401
|
+
error: 'Possible network or request shape issue occurred. If this is rare, its a network glitch. If it occurs a lot something is wrong.',
|
|
402
|
+
errorObject: error
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
// If response is undefined, the error has been handled in the catch block above
|
|
406
|
+
if (!response) return;
|
|
407
|
+
rest.logger.debug(`request fetched from ${url} with status ${response.status} & ${response.statusText}`);
|
|
408
|
+
// Sometimes the Content-Type may be "application/json; charset=utf-8", for this reason, we need to check the start of the header
|
|
409
|
+
const body = await (response.headers.get('Content-Type')?.startsWith('application/json') ? response.json() : response.text()).catch(()=>null);
|
|
410
|
+
rest.events.response(request, response, {
|
|
411
|
+
requestBody: options.requestBodyOptions?.body,
|
|
412
|
+
responseBody: body
|
|
413
|
+
});
|
|
414
|
+
// Mark request as completed
|
|
415
|
+
rest.invalidBucket.handleCompletedRequest(response.status, response.headers.get(RATE_LIMIT_SCOPE_HEADER) === 'shared');
|
|
416
|
+
// Set the bucket id if it was available on the headers
|
|
417
|
+
const bucketId = rest.processHeaders(rest.simplifyUrl(options.route, options.method), response.headers, payload.headers.authorization);
|
|
418
|
+
if (bucketId) options.bucketId = bucketId;
|
|
419
|
+
if (response.status < 200 || response.status >= 400) {
|
|
420
|
+
rest.logger.debug(`Request to ${url} failed.`);
|
|
421
|
+
if (response.status !== 429) {
|
|
422
|
+
options.reject({
|
|
423
|
+
ok: false,
|
|
424
|
+
status: response.status,
|
|
425
|
+
statusText: response.statusText,
|
|
426
|
+
body
|
|
427
|
+
});
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
rest.logger.debug(`Request to ${url} was ratelimited.`);
|
|
431
|
+
// Too many attempts, get rid of request from queue.
|
|
432
|
+
if (options.retryCount >= rest.maxRetryCount) {
|
|
433
|
+
rest.logger.debug(`Request to ${url} exceeded the maximum allowed retries.`, 'with payload:', payload);
|
|
434
|
+
// rest.debug(`[REST - RetriesMaxed] ${JSON.stringify(options)}`)
|
|
435
|
+
options.reject({
|
|
436
|
+
ok: false,
|
|
437
|
+
status: response.status,
|
|
438
|
+
statusText: response.statusText,
|
|
439
|
+
error: 'The request was rate limited and it maxed out the retries limit.'
|
|
440
|
+
});
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
options.retryCount += 1;
|
|
444
|
+
const resetAfter = response.headers.get('retry-after');
|
|
445
|
+
if (resetAfter) await delay(Number(resetAfter) * 1000);
|
|
446
|
+
return await options.retryRequest?.(options);
|
|
447
|
+
}
|
|
448
|
+
// Discord sometimes sends a response with no content
|
|
449
|
+
options.resolve({
|
|
450
|
+
ok: true,
|
|
451
|
+
status: response.status,
|
|
452
|
+
body: response.status === 204 ? undefined : body
|
|
453
|
+
});
|
|
454
|
+
},
|
|
455
|
+
simplifyUrl (url, method) {
|
|
456
|
+
const routeInformationKey = [
|
|
457
|
+
method
|
|
458
|
+
];
|
|
459
|
+
const queryParamIndex = url.indexOf('?');
|
|
460
|
+
const route = queryParamIndex !== -1 ? url.slice(0, queryParamIndex) : url;
|
|
461
|
+
// Since the urls start with / the first part will always be empty
|
|
462
|
+
const splittedRoute = route.split('/');
|
|
463
|
+
// 1) Strip the minor params
|
|
464
|
+
// The only majors are channels, guilds, webhooks and webhooks with their token
|
|
465
|
+
const strippedRoute = splittedRoute.map((part, index, array)=>{
|
|
466
|
+
// While parseInt will truncate the snowflake id, it will still tell us if it is a number
|
|
467
|
+
const isNumber = Number.isFinite(parseInt(part, 10));
|
|
468
|
+
if (!isNumber) {
|
|
469
|
+
// Reactions emoji need to be stripped as it is a minor parameter
|
|
470
|
+
if (index >= 1 && array[index - 1] === 'reactions') return 'x';
|
|
471
|
+
// If we are on a webhook or if it is part of the route, keep it as it is a major parameter
|
|
472
|
+
return part;
|
|
473
|
+
}
|
|
474
|
+
// Check if we are on a channel id, a guild id or a webhook id
|
|
475
|
+
const isMajor = index >= 1 && (array[index - 1] === 'channels' || array[index - 1] === 'guilds' || array[index - 1] === 'webhooks');
|
|
476
|
+
if (isMajor) return part;
|
|
477
|
+
return 'x';
|
|
478
|
+
}).join('/');
|
|
479
|
+
routeInformationKey.push(strippedRoute);
|
|
480
|
+
// 2) Account for exceptions
|
|
481
|
+
// - https://github.com/discord/discord-api-docs/issues/1092
|
|
482
|
+
// - https://github.com/discord/discord-api-docs/issues/1295
|
|
483
|
+
// The 2 exceptions are for message delete, so we need to check if we are in that route
|
|
484
|
+
if (method === 'DELETE' && splittedRoute.length === 5 && splittedRoute[1] === 'channels' && strippedRoute.endsWith('/messages/x')) {
|
|
485
|
+
const messageId = splittedRoute[4];
|
|
486
|
+
const timestamp = snowflakeToTimestamp(messageId);
|
|
487
|
+
const now = Date.now();
|
|
488
|
+
// https://github.com/discord/discord-api-docs/issues/1092
|
|
489
|
+
if (now - timestamp < 10_000) {
|
|
490
|
+
routeInformationKey.push('message-delete-10s');
|
|
491
|
+
}
|
|
492
|
+
// https://github.com/discord/discord-api-docs/issues/1295
|
|
493
|
+
// 2 weeks = 2 * 7 * 24 * 60 * 60 * 1000 = 1209600000
|
|
494
|
+
if (now - timestamp > 1209600000) {
|
|
495
|
+
routeInformationKey.push('message-delete-2w');
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
return routeInformationKey.join(':');
|
|
499
|
+
},
|
|
500
|
+
async processRequest (request) {
|
|
501
|
+
const url = rest.simplifyUrl(request.route, request.method);
|
|
502
|
+
if (request.runThroughQueue === false) {
|
|
503
|
+
await rest.sendRequest(request);
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
// If the request has a token, use it
|
|
507
|
+
// Else fallback to prefix with the bot token
|
|
508
|
+
const queueIdentifier = request.requestBodyOptions?.headers?.authorization ?? `Bot ${rest.token}`;
|
|
509
|
+
const queue = rest.queues.get(`${queueIdentifier}${url}`);
|
|
510
|
+
if (queue !== undefined) {
|
|
511
|
+
queue.makeRequest(request);
|
|
512
|
+
} else {
|
|
513
|
+
// CREATES A NEW QUEUE
|
|
514
|
+
const bucketQueue = new Queue(rest, {
|
|
515
|
+
url,
|
|
516
|
+
deleteQueueDelay: rest.deleteQueueDelay,
|
|
517
|
+
identifier: queueIdentifier
|
|
518
|
+
});
|
|
519
|
+
// Save queue
|
|
520
|
+
rest.queues.set(`${queueIdentifier}${url}`, bucketQueue);
|
|
521
|
+
// Add request to queue
|
|
522
|
+
bucketQueue.makeRequest(request);
|
|
523
|
+
}
|
|
524
|
+
},
|
|
525
|
+
async makeRequest (method, route, options) {
|
|
526
|
+
// This error needs to be created here because of how stack traces get calculated
|
|
527
|
+
const error = new Error();
|
|
528
|
+
if (rest.isProxied) {
|
|
529
|
+
if (rest.authorization) {
|
|
530
|
+
options ??= {};
|
|
531
|
+
options.headers ??= {};
|
|
532
|
+
options.headers[rest.authorizationHeader] = rest.authorization;
|
|
533
|
+
}
|
|
534
|
+
const url = `${rest.baseUrl}/v${rest.version}${route}`;
|
|
535
|
+
// An attempt that failed without a response is not re-sent by default. Whatever it failed on, the proxy may already have the request
|
|
536
|
+
// (a timeout only aborts our side of the connection, and a socket that dies once the request is on the wire may still have delivered
|
|
537
|
+
// it), so re-sending it would execute non-idempotent requests twice. `fetch` gives no way to tell the two apart, so the caller is the
|
|
538
|
+
// one who decides: `proxy.retryRequests` says re-sending against this proxy is safe. Retrying towards Discord is the proxy's job, it
|
|
539
|
+
// is the one talking to Discord.
|
|
540
|
+
let retryCount = 0;
|
|
541
|
+
for(;;){
|
|
542
|
+
// The request may have been aborted while the previous attempt was timing out, never send it in that case.
|
|
543
|
+
if (options?.signal?.aborted) {
|
|
544
|
+
throw rest.createRequestError(error, {
|
|
545
|
+
ok: false,
|
|
546
|
+
status: 999,
|
|
547
|
+
error: 'The request was aborted.',
|
|
548
|
+
errorObject: options.signal.reason
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
// Give the attempt a deadline (omitted when disabled) so a stalled connection can't hang the caller forever, and hand the caller's
|
|
552
|
+
// signal to fetch so aborting tears down a request that is already on the wire.
|
|
553
|
+
const signals = [];
|
|
554
|
+
if (options?.signal) signals.push(options.signal);
|
|
555
|
+
if (rest.requestTimeout > 0) signals.push(AbortSignal.timeout(rest.requestTimeout));
|
|
556
|
+
const request = new Request(url, {
|
|
557
|
+
...rest.createRequestBody(method, options),
|
|
558
|
+
signal: signals.length > 0 ? AbortSignal.any(signals) : undefined
|
|
559
|
+
});
|
|
560
|
+
rest.events.request(request, {
|
|
561
|
+
body: options?.body
|
|
562
|
+
});
|
|
563
|
+
const result = await fetch(request).catch(async (fetchError)=>{
|
|
564
|
+
rest.events.requestError(request, fetchError, {
|
|
565
|
+
body: options?.body
|
|
566
|
+
});
|
|
567
|
+
// The caller aborted the request, never re-send it, the proxy may have received it already.
|
|
568
|
+
if (options?.signal?.aborted) {
|
|
569
|
+
throw rest.createRequestError(error, {
|
|
570
|
+
ok: false,
|
|
571
|
+
status: 999,
|
|
572
|
+
error: 'The request was aborted.',
|
|
573
|
+
errorObject: fetchError
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
const timedOut = isTimeoutError(fetchError);
|
|
577
|
+
if (rest.retryProxiedRequests && retryCount < rest.maxRetryCount && retryCount < rest.maxProxyRetryCount) {
|
|
578
|
+
retryCount++;
|
|
579
|
+
rest.logger.debug(`request to proxy ${url} failed without a response, retrying.`, fetchError);
|
|
580
|
+
// Wait a little longer before each further attempt so a proxy that is down isn't hammered in a tight loop, while staying
|
|
581
|
+
// frequent enough to notice it coming back. A timed out attempt already sat out `requestTimeout`, so it goes again right away.
|
|
582
|
+
if (!timedOut) await delay(rest.proxyRetryDelayStep * retryCount);
|
|
583
|
+
return undefined;
|
|
584
|
+
}
|
|
585
|
+
if (timedOut) {
|
|
586
|
+
rest.logger.debug(`request to proxy ${url} timed out after ${rest.requestTimeout}ms.`);
|
|
587
|
+
throw rest.createRequestError(error, {
|
|
588
|
+
ok: false,
|
|
589
|
+
status: 999,
|
|
590
|
+
error: 'The request timed out and it maxed out the retries limit.',
|
|
591
|
+
errorObject: fetchError
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
rest.logger.debug(`request fetch to proxy ${url} failed.`, fetchError);
|
|
595
|
+
throw rest.createRequestError(error, {
|
|
596
|
+
ok: false,
|
|
597
|
+
status: 999,
|
|
598
|
+
error: 'Possible network or request shape issue occurred. If this is rare, its a network glitch. If it occurs a lot something is wrong.',
|
|
599
|
+
errorObject: fetchError
|
|
600
|
+
});
|
|
601
|
+
});
|
|
602
|
+
// If result is undefined, the attempt failed in a way that is safe to re-send and is being retried.
|
|
603
|
+
if (!result) continue;
|
|
604
|
+
// Sometimes the Content-Type may be "application/json; charset=utf-8", for this reason, we need to check the start of the header
|
|
605
|
+
let bodyReadFailed = false;
|
|
606
|
+
const body = await (result.headers.get('Content-Type')?.startsWith('application/json') ? result.json() : result.text()).catch(()=>{
|
|
607
|
+
bodyReadFailed = true;
|
|
608
|
+
return null;
|
|
609
|
+
});
|
|
610
|
+
rest.events.response(request, result, {
|
|
611
|
+
requestBody: options?.body,
|
|
612
|
+
responseBody: body
|
|
613
|
+
});
|
|
614
|
+
// `fetch` resolves once the headers are in, so an abort can land while the body above is still being read. That read rejects, the
|
|
615
|
+
// fallback turns it into a `null` body and the caller gets it back as a successful empty response. A read that did finish is kept,
|
|
616
|
+
// the same way the queued path hands back a result that arrived before the signal fired.
|
|
617
|
+
if (bodyReadFailed && options?.signal?.aborted) {
|
|
618
|
+
throw rest.createRequestError(error, {
|
|
619
|
+
ok: false,
|
|
620
|
+
status: 999,
|
|
621
|
+
error: 'The request was aborted.',
|
|
622
|
+
errorObject: options.signal.reason
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
if (!result.ok) {
|
|
626
|
+
throw rest.createRequestError(error, {
|
|
627
|
+
ok: false,
|
|
628
|
+
status: result.status,
|
|
629
|
+
statusText: result.statusText,
|
|
630
|
+
body
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
return result.status !== 204 ? typeof body === 'string' ? JSON.parse(body) : body : undefined;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
return await new Promise(async (resolve, reject)=>{
|
|
637
|
+
const signal = options?.signal;
|
|
638
|
+
const abortListener = ()=>{
|
|
639
|
+
// Reject right away instead of waiting for the queue to reach the request. The signal is attached to the fetch itself as well, so an
|
|
640
|
+
// attempt that is already in flight gets its connection torn down too.
|
|
641
|
+
payload.reject({
|
|
642
|
+
ok: false,
|
|
643
|
+
status: 999,
|
|
644
|
+
error: 'The request was aborted.',
|
|
645
|
+
errorObject: signal?.reason
|
|
646
|
+
});
|
|
647
|
+
};
|
|
648
|
+
const payload = {
|
|
649
|
+
route,
|
|
650
|
+
method,
|
|
651
|
+
requestBodyOptions: options,
|
|
652
|
+
retryCount: 0,
|
|
653
|
+
retryRequest: async (payload)=>{
|
|
654
|
+
await rest.processRequest(payload);
|
|
655
|
+
},
|
|
656
|
+
resolve: (data)=>{
|
|
657
|
+
signal?.removeEventListener('abort', abortListener);
|
|
658
|
+
resolve(data.status !== 204 ? data.body : undefined);
|
|
659
|
+
},
|
|
660
|
+
reject: (reason)=>{
|
|
661
|
+
signal?.removeEventListener('abort', abortListener);
|
|
662
|
+
reject(rest.createRequestError(error, reason));
|
|
663
|
+
},
|
|
664
|
+
runThroughQueue: options?.runThroughQueue
|
|
665
|
+
};
|
|
666
|
+
// Reject a queued request as soon as its signal aborts instead of when the queue reaches it, so a caller enforcing a deadline gets its
|
|
667
|
+
// answer right away. Fetch refusing to send an already aborted request is what guarantees the stale queue entry never goes out.
|
|
668
|
+
if (signal?.aborted) {
|
|
669
|
+
abortListener();
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
signal?.addEventListener('abort', abortListener, {
|
|
673
|
+
once: true
|
|
674
|
+
});
|
|
675
|
+
await rest.processRequest(payload);
|
|
676
|
+
});
|
|
677
|
+
},
|
|
678
|
+
async get (url, options) {
|
|
679
|
+
return camelize(await rest.makeRequest('GET', url, options));
|
|
680
|
+
},
|
|
681
|
+
async post (url, options) {
|
|
682
|
+
return camelize(await rest.makeRequest('POST', url, options));
|
|
683
|
+
},
|
|
684
|
+
async delete (url, options) {
|
|
685
|
+
camelize(await rest.makeRequest('DELETE', url, options));
|
|
686
|
+
},
|
|
687
|
+
async patch (url, options) {
|
|
688
|
+
return camelize(await rest.makeRequest('PATCH', url, options));
|
|
689
|
+
},
|
|
690
|
+
async put (url, options) {
|
|
691
|
+
return camelize(await rest.makeRequest('PUT', url, options));
|
|
692
|
+
},
|
|
693
|
+
async addReaction (channelId, messageId, reaction) {
|
|
694
|
+
reaction = processReactionString(reaction);
|
|
695
|
+
await rest.put(rest.routes.channels.reactions.bot(channelId, messageId, reaction));
|
|
696
|
+
},
|
|
697
|
+
async addReactions (channelId, messageId, reactions, ordered = false) {
|
|
698
|
+
if (!ordered) {
|
|
699
|
+
await Promise.all(reactions.map(async (reaction)=>{
|
|
700
|
+
await rest.addReaction(channelId, messageId, reaction);
|
|
701
|
+
}));
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
for (const reaction of reactions){
|
|
705
|
+
await rest.addReaction(channelId, messageId, reaction);
|
|
706
|
+
}
|
|
707
|
+
},
|
|
708
|
+
async addRole (guildId, userId, roleId, reason) {
|
|
709
|
+
await rest.put(rest.routes.guilds.roles.member(guildId, userId, roleId), {
|
|
710
|
+
reason
|
|
711
|
+
});
|
|
712
|
+
},
|
|
713
|
+
async addThreadMember (channelId, userId) {
|
|
714
|
+
await rest.put(rest.routes.channels.threads.user(channelId, userId));
|
|
715
|
+
},
|
|
716
|
+
async addDmRecipient (channelId, userId, body) {
|
|
717
|
+
await rest.put(rest.routes.channels.dmRecipient(channelId, userId), {
|
|
718
|
+
body
|
|
719
|
+
});
|
|
720
|
+
},
|
|
721
|
+
async createAutomodRule (guildId, body, reason) {
|
|
722
|
+
return await rest.post(rest.routes.guilds.automod.rules(guildId), {
|
|
723
|
+
body,
|
|
724
|
+
reason
|
|
725
|
+
});
|
|
726
|
+
},
|
|
727
|
+
async createChannel (guildId, body, reason) {
|
|
728
|
+
return await rest.post(rest.routes.guilds.channels(guildId), {
|
|
729
|
+
body,
|
|
730
|
+
reason
|
|
731
|
+
});
|
|
732
|
+
},
|
|
733
|
+
async createEmoji (guildId, body, reason) {
|
|
734
|
+
return await rest.post(rest.routes.guilds.emojis(guildId), {
|
|
735
|
+
body,
|
|
736
|
+
reason
|
|
737
|
+
});
|
|
738
|
+
},
|
|
739
|
+
async createApplicationEmoji (body) {
|
|
740
|
+
return await rest.post(rest.routes.applicationEmojis(rest.applicationId), {
|
|
741
|
+
body
|
|
742
|
+
});
|
|
743
|
+
},
|
|
744
|
+
async createGlobalApplicationCommand (body, options) {
|
|
745
|
+
const restOptions = {
|
|
746
|
+
body
|
|
747
|
+
};
|
|
748
|
+
if (options?.bearerToken) {
|
|
749
|
+
restOptions.unauthorized = true;
|
|
750
|
+
restOptions.headers = {
|
|
751
|
+
authorization: `Bearer ${options.bearerToken}`
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
return await rest.post(rest.routes.interactions.commands.commands(rest.applicationId), restOptions);
|
|
755
|
+
},
|
|
756
|
+
async createGuildApplicationCommand (body, guildId, options) {
|
|
757
|
+
const restOptions = {
|
|
758
|
+
body
|
|
759
|
+
};
|
|
760
|
+
if (options?.bearerToken) {
|
|
761
|
+
restOptions.unauthorized = true;
|
|
762
|
+
restOptions.headers = {
|
|
763
|
+
authorization: `Bearer ${options.bearerToken}`
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
return await rest.post(rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId), restOptions);
|
|
767
|
+
},
|
|
768
|
+
async createGuildSticker (guildId, options, reason) {
|
|
769
|
+
const form = new FormData();
|
|
770
|
+
form.append('file', options.file.blob, options.file.name);
|
|
771
|
+
form.append('name', options.name);
|
|
772
|
+
form.append('description', options.description);
|
|
773
|
+
form.append('tags', options.tags);
|
|
774
|
+
return await rest.post(rest.routes.guilds.stickers(guildId), {
|
|
775
|
+
body: form,
|
|
776
|
+
reason
|
|
777
|
+
});
|
|
778
|
+
},
|
|
779
|
+
async createGuildTemplate (guildId, body) {
|
|
780
|
+
return await rest.post(rest.routes.guilds.templates.all(guildId), {
|
|
781
|
+
body
|
|
782
|
+
});
|
|
783
|
+
},
|
|
784
|
+
async createForumThread (channelId, body, reason) {
|
|
785
|
+
return await rest.post(rest.routes.channels.forum(channelId), {
|
|
786
|
+
body,
|
|
787
|
+
files: body.files,
|
|
788
|
+
reason
|
|
789
|
+
});
|
|
790
|
+
},
|
|
791
|
+
async createInvite (channelId, body = {}, reason) {
|
|
792
|
+
if (!body.targetUsersFile) {
|
|
793
|
+
return await rest.post(rest.routes.channels.invites(channelId), {
|
|
794
|
+
body,
|
|
795
|
+
reason
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
// When we have to upload a file, we need to use FormData, and all other fields need to be part of the payload_json field.
|
|
799
|
+
const form = new FormData();
|
|
800
|
+
form.append('payload_json', JSON.stringify(rest.changeToDiscordFormat({
|
|
801
|
+
...body,
|
|
802
|
+
targetUsersFile: undefined
|
|
803
|
+
})));
|
|
804
|
+
form.append('target_users_file', body.targetUsersFile);
|
|
805
|
+
return await rest.post(rest.routes.channels.invites(channelId), {
|
|
806
|
+
body: form,
|
|
807
|
+
reason
|
|
808
|
+
});
|
|
809
|
+
},
|
|
810
|
+
async getGuildRoleMemberCounts (guildId) {
|
|
811
|
+
return await rest.get(rest.routes.guilds.roles.memberCounts(guildId));
|
|
812
|
+
},
|
|
813
|
+
async createRole (guildId, body, reason) {
|
|
814
|
+
return await rest.post(rest.routes.guilds.roles.all(guildId), {
|
|
815
|
+
body,
|
|
816
|
+
reason
|
|
817
|
+
});
|
|
818
|
+
},
|
|
819
|
+
async createScheduledEvent (guildId, body, reason) {
|
|
820
|
+
return await rest.post(rest.routes.guilds.events.events(guildId), {
|
|
821
|
+
body,
|
|
822
|
+
reason
|
|
823
|
+
});
|
|
824
|
+
},
|
|
825
|
+
async createStageInstance (body, reason) {
|
|
826
|
+
return await rest.post(rest.routes.channels.stages(), {
|
|
827
|
+
body,
|
|
828
|
+
reason
|
|
829
|
+
});
|
|
830
|
+
},
|
|
831
|
+
async createWebhook (channelId, options, reason) {
|
|
832
|
+
return await rest.post(rest.routes.channels.webhooks(channelId), {
|
|
833
|
+
body: options,
|
|
834
|
+
reason
|
|
835
|
+
});
|
|
836
|
+
},
|
|
837
|
+
async deleteAutomodRule (guildId, ruleId, reason) {
|
|
838
|
+
await rest.delete(rest.routes.guilds.automod.rule(guildId, ruleId), {
|
|
839
|
+
reason
|
|
840
|
+
});
|
|
841
|
+
},
|
|
842
|
+
async deleteChannel (channelId, reason) {
|
|
843
|
+
await rest.delete(rest.routes.channels.channel(channelId), {
|
|
844
|
+
reason
|
|
845
|
+
});
|
|
846
|
+
},
|
|
847
|
+
async deleteChannelPermissionOverride (channelId, overwriteId, reason) {
|
|
848
|
+
await rest.delete(rest.routes.channels.overwrite(channelId, overwriteId), {
|
|
849
|
+
reason
|
|
850
|
+
});
|
|
851
|
+
},
|
|
852
|
+
async deleteEmoji (guildId, id, reason) {
|
|
853
|
+
await rest.delete(rest.routes.guilds.emoji(guildId, id), {
|
|
854
|
+
reason
|
|
855
|
+
});
|
|
856
|
+
},
|
|
857
|
+
async deleteApplicationEmoji (id) {
|
|
858
|
+
await rest.delete(rest.routes.applicationEmoji(rest.applicationId, id));
|
|
859
|
+
},
|
|
860
|
+
async deleteFollowupMessage (token, messageId) {
|
|
861
|
+
await rest.delete(rest.routes.interactions.responses.message(rest.applicationId, token, messageId), {
|
|
862
|
+
unauthorized: true
|
|
863
|
+
});
|
|
864
|
+
},
|
|
865
|
+
async deleteGlobalApplicationCommand (commandId) {
|
|
866
|
+
await rest.delete(rest.routes.interactions.commands.command(rest.applicationId, commandId));
|
|
867
|
+
},
|
|
868
|
+
async deleteGuildApplicationCommand (commandId, guildId) {
|
|
869
|
+
await rest.delete(rest.routes.interactions.commands.guilds.one(rest.applicationId, guildId, commandId));
|
|
870
|
+
},
|
|
871
|
+
async deleteGuildSticker (guildId, stickerId, reason) {
|
|
872
|
+
await rest.delete(rest.routes.guilds.sticker(guildId, stickerId), {
|
|
873
|
+
reason
|
|
874
|
+
});
|
|
875
|
+
},
|
|
876
|
+
async deleteGuildTemplate (guildId, templateCode) {
|
|
877
|
+
await rest.delete(rest.routes.guilds.templates.guild(guildId, templateCode));
|
|
878
|
+
},
|
|
879
|
+
async deleteIntegration (guildId, integrationId, reason) {
|
|
880
|
+
await rest.delete(rest.routes.guilds.integration(guildId, integrationId), {
|
|
881
|
+
reason
|
|
882
|
+
});
|
|
883
|
+
},
|
|
884
|
+
async deleteInvite (inviteCode, reason) {
|
|
885
|
+
await rest.delete(rest.routes.guilds.invite(inviteCode), {
|
|
886
|
+
reason
|
|
887
|
+
});
|
|
888
|
+
},
|
|
889
|
+
async getTargetUsers (inviteCode) {
|
|
890
|
+
return await rest.get(rest.routes.guilds.inviteTargetUsers(inviteCode));
|
|
891
|
+
},
|
|
892
|
+
async updateTargetUsers (inviteCode, targetUsersFile) {
|
|
893
|
+
const form = new FormData();
|
|
894
|
+
form.append('target_users_file', targetUsersFile);
|
|
895
|
+
await rest.put(rest.routes.guilds.inviteTargetUsers(inviteCode), {
|
|
896
|
+
body: form
|
|
897
|
+
});
|
|
898
|
+
},
|
|
899
|
+
async getTargetUsersJobStatus (inviteCode) {
|
|
900
|
+
return await rest.get(rest.routes.guilds.inviteTargetUsersJobStatus(inviteCode));
|
|
901
|
+
},
|
|
902
|
+
async deleteMessage (channelId, messageId, reason) {
|
|
903
|
+
await rest.delete(rest.routes.channels.message(channelId, messageId), {
|
|
904
|
+
reason
|
|
905
|
+
});
|
|
906
|
+
},
|
|
907
|
+
async deleteMessages (channelId, messageIds, reason) {
|
|
908
|
+
await rest.post(rest.routes.channels.bulk(channelId), {
|
|
909
|
+
body: {
|
|
910
|
+
messages: messageIds.slice(0, 100).map((id)=>id.toString())
|
|
911
|
+
},
|
|
912
|
+
reason
|
|
913
|
+
});
|
|
914
|
+
},
|
|
915
|
+
async deleteOriginalInteractionResponse (token) {
|
|
916
|
+
await rest.delete(rest.routes.interactions.responses.original(rest.applicationId, token), {
|
|
917
|
+
unauthorized: true
|
|
918
|
+
});
|
|
919
|
+
},
|
|
920
|
+
async deleteOwnReaction (channelId, messageId, reaction) {
|
|
921
|
+
reaction = processReactionString(reaction);
|
|
922
|
+
await rest.delete(rest.routes.channels.reactions.bot(channelId, messageId, reaction));
|
|
923
|
+
},
|
|
924
|
+
async deleteReactionsAll (channelId, messageId) {
|
|
925
|
+
await rest.delete(rest.routes.channels.reactions.all(channelId, messageId));
|
|
926
|
+
},
|
|
927
|
+
async deleteReactionsEmoji (channelId, messageId, reaction) {
|
|
928
|
+
reaction = processReactionString(reaction);
|
|
929
|
+
await rest.delete(rest.routes.channels.reactions.emoji(channelId, messageId, reaction));
|
|
930
|
+
},
|
|
931
|
+
async deleteRole (guildId, roleId, reason) {
|
|
932
|
+
await rest.delete(rest.routes.guilds.roles.one(guildId, roleId), {
|
|
933
|
+
reason
|
|
934
|
+
});
|
|
935
|
+
},
|
|
936
|
+
async deleteScheduledEvent (guildId, eventId) {
|
|
937
|
+
await rest.delete(rest.routes.guilds.events.event(guildId, eventId));
|
|
938
|
+
},
|
|
939
|
+
async deleteStageInstance (channelId, reason) {
|
|
940
|
+
await rest.delete(rest.routes.channels.stage(channelId), {
|
|
941
|
+
reason
|
|
942
|
+
});
|
|
943
|
+
},
|
|
944
|
+
async deleteUserReaction (channelId, messageId, userId, reaction) {
|
|
945
|
+
reaction = processReactionString(reaction);
|
|
946
|
+
await rest.delete(rest.routes.channels.reactions.user(channelId, messageId, reaction, userId));
|
|
947
|
+
},
|
|
948
|
+
async deleteWebhook (webhookId, reason) {
|
|
949
|
+
await rest.delete(rest.routes.webhooks.id(webhookId), {
|
|
950
|
+
reason
|
|
951
|
+
});
|
|
952
|
+
},
|
|
953
|
+
async deleteWebhookMessage (webhookId, token, messageId, options) {
|
|
954
|
+
await rest.delete(rest.routes.webhooks.message(webhookId, token, messageId, options), {
|
|
955
|
+
unauthorized: true
|
|
956
|
+
});
|
|
957
|
+
},
|
|
958
|
+
async deleteWebhookWithToken (webhookId, token) {
|
|
959
|
+
await rest.delete(rest.routes.webhooks.webhook(webhookId, token), {
|
|
960
|
+
unauthorized: true
|
|
961
|
+
});
|
|
962
|
+
},
|
|
963
|
+
async editApplicationCommandPermissions (guildId, commandId, bearerToken, permissions) {
|
|
964
|
+
return await rest.put(rest.routes.interactions.commands.permission(rest.applicationId, guildId, commandId), {
|
|
965
|
+
body: {
|
|
966
|
+
permissions
|
|
967
|
+
},
|
|
968
|
+
headers: {
|
|
969
|
+
authorization: `Bearer ${bearerToken}`
|
|
970
|
+
}
|
|
971
|
+
});
|
|
972
|
+
},
|
|
973
|
+
async editAutomodRule (guildId, ruleId, body, reason) {
|
|
974
|
+
return await rest.patch(rest.routes.guilds.automod.rule(guildId, ruleId), {
|
|
975
|
+
body,
|
|
976
|
+
reason
|
|
977
|
+
});
|
|
978
|
+
},
|
|
979
|
+
async editBotProfile (options) {
|
|
980
|
+
return await rest.patch(rest.routes.currentUser(), {
|
|
981
|
+
body: options
|
|
982
|
+
});
|
|
983
|
+
},
|
|
984
|
+
async editChannel (channelId, body, reason) {
|
|
985
|
+
return await rest.patch(rest.routes.channels.channel(channelId), {
|
|
986
|
+
body,
|
|
987
|
+
reason
|
|
988
|
+
});
|
|
989
|
+
},
|
|
990
|
+
async editChannelPermissionOverrides (channelId, body, reason) {
|
|
991
|
+
await rest.put(rest.routes.channels.overwrite(channelId, body.id), {
|
|
992
|
+
body,
|
|
993
|
+
reason
|
|
994
|
+
});
|
|
995
|
+
},
|
|
996
|
+
async editChannelPositions (guildId, body) {
|
|
997
|
+
await rest.patch(rest.routes.guilds.channels(guildId), {
|
|
998
|
+
body
|
|
999
|
+
});
|
|
1000
|
+
},
|
|
1001
|
+
async editEmoji (guildId, id, body, reason) {
|
|
1002
|
+
return await rest.patch(rest.routes.guilds.emoji(guildId, id), {
|
|
1003
|
+
body,
|
|
1004
|
+
reason
|
|
1005
|
+
});
|
|
1006
|
+
},
|
|
1007
|
+
async editApplicationEmoji (id, body) {
|
|
1008
|
+
return await rest.patch(rest.routes.applicationEmoji(rest.applicationId, id), {
|
|
1009
|
+
body
|
|
1010
|
+
});
|
|
1011
|
+
},
|
|
1012
|
+
async editFollowupMessage (token, messageId, body) {
|
|
1013
|
+
return await rest.patch(rest.routes.interactions.responses.message(rest.applicationId, token, messageId), {
|
|
1014
|
+
body,
|
|
1015
|
+
files: body.files,
|
|
1016
|
+
unauthorized: true
|
|
1017
|
+
});
|
|
1018
|
+
},
|
|
1019
|
+
async editGlobalApplicationCommand (commandId, body) {
|
|
1020
|
+
return await rest.patch(rest.routes.interactions.commands.command(rest.applicationId, commandId), {
|
|
1021
|
+
body
|
|
1022
|
+
});
|
|
1023
|
+
},
|
|
1024
|
+
async editGuild (guildId, body, reason) {
|
|
1025
|
+
return await rest.patch(rest.routes.guilds.guild(guildId), {
|
|
1026
|
+
body,
|
|
1027
|
+
reason
|
|
1028
|
+
});
|
|
1029
|
+
},
|
|
1030
|
+
async editGuildApplicationCommand (commandId, guildId, body) {
|
|
1031
|
+
return await rest.patch(rest.routes.interactions.commands.guilds.one(rest.applicationId, guildId, commandId), {
|
|
1032
|
+
body
|
|
1033
|
+
});
|
|
1034
|
+
},
|
|
1035
|
+
async editGuildSticker (guildId, stickerId, body, reason) {
|
|
1036
|
+
return await rest.patch(rest.routes.guilds.sticker(guildId, stickerId), {
|
|
1037
|
+
body,
|
|
1038
|
+
reason
|
|
1039
|
+
});
|
|
1040
|
+
},
|
|
1041
|
+
async editGuildTemplate (guildId, templateCode, body) {
|
|
1042
|
+
return await rest.patch(rest.routes.guilds.templates.guild(guildId, templateCode), {
|
|
1043
|
+
body
|
|
1044
|
+
});
|
|
1045
|
+
},
|
|
1046
|
+
async editMessage (channelId, messageId, body) {
|
|
1047
|
+
return await rest.patch(rest.routes.channels.message(channelId, messageId), {
|
|
1048
|
+
body,
|
|
1049
|
+
files: body.files
|
|
1050
|
+
});
|
|
1051
|
+
},
|
|
1052
|
+
async editOriginalInteractionResponse (token, body) {
|
|
1053
|
+
return await rest.patch(rest.routes.interactions.responses.original(rest.applicationId, token), {
|
|
1054
|
+
body,
|
|
1055
|
+
files: body.files,
|
|
1056
|
+
unauthorized: true
|
|
1057
|
+
});
|
|
1058
|
+
},
|
|
1059
|
+
async editOwnVoiceState (guildId, options) {
|
|
1060
|
+
await rest.patch(rest.routes.guilds.voice(guildId), {
|
|
1061
|
+
body: {
|
|
1062
|
+
...options,
|
|
1063
|
+
requestToSpeakTimestamp: options.requestToSpeakTimestamp ? new Date(options.requestToSpeakTimestamp).toISOString() : options.requestToSpeakTimestamp
|
|
1064
|
+
}
|
|
1065
|
+
});
|
|
1066
|
+
},
|
|
1067
|
+
async editScheduledEvent (guildId, eventId, body, reason) {
|
|
1068
|
+
return await rest.patch(rest.routes.guilds.events.event(guildId, eventId), {
|
|
1069
|
+
body,
|
|
1070
|
+
reason
|
|
1071
|
+
});
|
|
1072
|
+
},
|
|
1073
|
+
async editRole (guildId, roleId, body, reason) {
|
|
1074
|
+
return await rest.patch(rest.routes.guilds.roles.one(guildId, roleId), {
|
|
1075
|
+
body,
|
|
1076
|
+
reason
|
|
1077
|
+
});
|
|
1078
|
+
},
|
|
1079
|
+
async editRolePositions (guildId, body, reason) {
|
|
1080
|
+
return await rest.patch(rest.routes.guilds.roles.all(guildId), {
|
|
1081
|
+
body,
|
|
1082
|
+
reason
|
|
1083
|
+
});
|
|
1084
|
+
},
|
|
1085
|
+
async editStageInstance (channelId, topic, reason) {
|
|
1086
|
+
return await rest.patch(rest.routes.channels.stage(channelId), {
|
|
1087
|
+
body: {
|
|
1088
|
+
topic
|
|
1089
|
+
},
|
|
1090
|
+
reason
|
|
1091
|
+
});
|
|
1092
|
+
},
|
|
1093
|
+
async editUserVoiceState (guildId, options) {
|
|
1094
|
+
await rest.patch(rest.routes.guilds.voice(guildId, options.userId), {
|
|
1095
|
+
body: options
|
|
1096
|
+
});
|
|
1097
|
+
},
|
|
1098
|
+
async editWebhook (webhookId, body, reason) {
|
|
1099
|
+
return await rest.patch(rest.routes.webhooks.id(webhookId), {
|
|
1100
|
+
body,
|
|
1101
|
+
reason
|
|
1102
|
+
});
|
|
1103
|
+
},
|
|
1104
|
+
async editWebhookMessage (webhookId, token, messageId, options) {
|
|
1105
|
+
return await rest.patch(rest.routes.webhooks.message(webhookId, token, messageId, options), {
|
|
1106
|
+
body: options,
|
|
1107
|
+
files: options.files,
|
|
1108
|
+
unauthorized: true
|
|
1109
|
+
});
|
|
1110
|
+
},
|
|
1111
|
+
async editWebhookWithToken (webhookId, token, body) {
|
|
1112
|
+
return await rest.patch(rest.routes.webhooks.webhook(webhookId, token), {
|
|
1113
|
+
body,
|
|
1114
|
+
unauthorized: true
|
|
1115
|
+
});
|
|
1116
|
+
},
|
|
1117
|
+
async editWelcomeScreen (guildId, body, reason) {
|
|
1118
|
+
return await rest.patch(rest.routes.guilds.welcome(guildId), {
|
|
1119
|
+
body,
|
|
1120
|
+
reason
|
|
1121
|
+
});
|
|
1122
|
+
},
|
|
1123
|
+
async editWidgetSettings (guildId, body, reason) {
|
|
1124
|
+
return await rest.patch(rest.routes.guilds.widget(guildId), {
|
|
1125
|
+
body,
|
|
1126
|
+
reason
|
|
1127
|
+
});
|
|
1128
|
+
},
|
|
1129
|
+
async executeWebhook (webhookId, token, options) {
|
|
1130
|
+
return await rest.post(rest.routes.webhooks.webhook(webhookId, token, options), {
|
|
1131
|
+
body: options,
|
|
1132
|
+
unauthorized: true
|
|
1133
|
+
});
|
|
1134
|
+
},
|
|
1135
|
+
async followAnnouncement (sourceChannelId, targetChannelId, reason) {
|
|
1136
|
+
return await rest.post(rest.routes.channels.follow(sourceChannelId), {
|
|
1137
|
+
body: {
|
|
1138
|
+
webhookChannelId: targetChannelId
|
|
1139
|
+
},
|
|
1140
|
+
reason
|
|
1141
|
+
});
|
|
1142
|
+
},
|
|
1143
|
+
async getActiveThreads (guildId) {
|
|
1144
|
+
return await rest.get(rest.routes.channels.threads.active(guildId));
|
|
1145
|
+
},
|
|
1146
|
+
async getApplicationCommandPermission (guildId, commandId, options) {
|
|
1147
|
+
const restOptions = {};
|
|
1148
|
+
if (options?.accessToken) {
|
|
1149
|
+
restOptions.unauthorized = true;
|
|
1150
|
+
restOptions.headers = {
|
|
1151
|
+
authorization: `Bearer ${options.accessToken}`
|
|
1152
|
+
};
|
|
1153
|
+
}
|
|
1154
|
+
return await rest.get(rest.routes.interactions.commands.permission(options?.applicationId ?? rest.applicationId, guildId, commandId), restOptions);
|
|
1155
|
+
},
|
|
1156
|
+
async getApplicationCommandPermissions (guildId, options) {
|
|
1157
|
+
const restOptions = {};
|
|
1158
|
+
if (options?.accessToken) {
|
|
1159
|
+
restOptions.unauthorized = true;
|
|
1160
|
+
restOptions.headers = {
|
|
1161
|
+
authorization: `Bearer ${options.accessToken}`
|
|
1162
|
+
};
|
|
1163
|
+
}
|
|
1164
|
+
return await rest.get(rest.routes.interactions.commands.permissions(options?.applicationId ?? rest.applicationId, guildId), restOptions);
|
|
1165
|
+
},
|
|
1166
|
+
async getApplicationInfo () {
|
|
1167
|
+
return await rest.get(rest.routes.oauth2.application());
|
|
1168
|
+
},
|
|
1169
|
+
async editApplicationInfo (body) {
|
|
1170
|
+
return await rest.patch(rest.routes.application(), {
|
|
1171
|
+
body
|
|
1172
|
+
});
|
|
1173
|
+
},
|
|
1174
|
+
async getCurrentAuthenticationInfo (token) {
|
|
1175
|
+
return await rest.get(rest.routes.oauth2.currentAuthorization(), {
|
|
1176
|
+
headers: {
|
|
1177
|
+
authorization: `Bearer ${token}`
|
|
1178
|
+
},
|
|
1179
|
+
unauthorized: true
|
|
1180
|
+
});
|
|
1181
|
+
},
|
|
1182
|
+
async exchangeToken (clientId, clientSecret, body) {
|
|
1183
|
+
const basicCredentials = Buffer.from(`${clientId}:${clientSecret}`);
|
|
1184
|
+
const restOptions = {
|
|
1185
|
+
body,
|
|
1186
|
+
headers: {
|
|
1187
|
+
'content-type': 'application/x-www-form-urlencoded',
|
|
1188
|
+
authorization: `Basic ${basicCredentials.toString('base64')}`
|
|
1189
|
+
},
|
|
1190
|
+
runThroughQueue: false,
|
|
1191
|
+
unauthorized: true
|
|
1192
|
+
};
|
|
1193
|
+
if (body.grantType === 'client_credentials') {
|
|
1194
|
+
restOptions.body.scope = body.scope.join(' ');
|
|
1195
|
+
}
|
|
1196
|
+
return await rest.post(rest.routes.oauth2.tokenExchange(), restOptions);
|
|
1197
|
+
},
|
|
1198
|
+
async revokeToken (clientId, clientSecret, body) {
|
|
1199
|
+
const basicCredentials = Buffer.from(`${clientId}:${clientSecret}`);
|
|
1200
|
+
await rest.post(rest.routes.oauth2.tokenRevoke(), {
|
|
1201
|
+
body,
|
|
1202
|
+
headers: {
|
|
1203
|
+
'content-type': 'application/x-www-form-urlencoded',
|
|
1204
|
+
authorization: `Basic ${basicCredentials.toString('base64')}`
|
|
1205
|
+
},
|
|
1206
|
+
unauthorized: true
|
|
1207
|
+
});
|
|
1208
|
+
},
|
|
1209
|
+
async getAuditLog (guildId, options) {
|
|
1210
|
+
return await rest.get(rest.routes.guilds.auditlogs(guildId, options));
|
|
1211
|
+
},
|
|
1212
|
+
async getAutomodRule (guildId, ruleId) {
|
|
1213
|
+
return await rest.get(rest.routes.guilds.automod.rule(guildId, ruleId));
|
|
1214
|
+
},
|
|
1215
|
+
async getAutomodRules (guildId) {
|
|
1216
|
+
return await rest.get(rest.routes.guilds.automod.rules(guildId));
|
|
1217
|
+
},
|
|
1218
|
+
async getAvailableVoiceRegions () {
|
|
1219
|
+
return await rest.get(rest.routes.regions());
|
|
1220
|
+
},
|
|
1221
|
+
async getBan (guildId, userId) {
|
|
1222
|
+
return await rest.get(rest.routes.guilds.members.ban(guildId, userId));
|
|
1223
|
+
},
|
|
1224
|
+
async getBans (guildId, options) {
|
|
1225
|
+
return await rest.get(rest.routes.guilds.members.bans(guildId, options));
|
|
1226
|
+
},
|
|
1227
|
+
async getChannel (id) {
|
|
1228
|
+
return await rest.get(rest.routes.channels.channel(id));
|
|
1229
|
+
},
|
|
1230
|
+
async getChannelInvites (channelId) {
|
|
1231
|
+
return await rest.get(rest.routes.channels.invites(channelId));
|
|
1232
|
+
},
|
|
1233
|
+
async getChannels (guildId) {
|
|
1234
|
+
return await rest.get(rest.routes.guilds.channels(guildId));
|
|
1235
|
+
},
|
|
1236
|
+
async getChannelWebhooks (channelId) {
|
|
1237
|
+
return await rest.get(rest.routes.channels.webhooks(channelId));
|
|
1238
|
+
},
|
|
1239
|
+
async getDmChannel (userId) {
|
|
1240
|
+
return await rest.post(rest.routes.channels.dm(), {
|
|
1241
|
+
body: {
|
|
1242
|
+
recipientId: userId
|
|
1243
|
+
}
|
|
1244
|
+
});
|
|
1245
|
+
},
|
|
1246
|
+
async getGroupDmChannel (body) {
|
|
1247
|
+
return await rest.post(rest.routes.channels.dm(), {
|
|
1248
|
+
body
|
|
1249
|
+
});
|
|
1250
|
+
},
|
|
1251
|
+
async getEmoji (guildId, emojiId) {
|
|
1252
|
+
return await rest.get(rest.routes.guilds.emoji(guildId, emojiId));
|
|
1253
|
+
},
|
|
1254
|
+
async getApplicationEmoji (emojiId) {
|
|
1255
|
+
return await rest.get(rest.routes.applicationEmoji(rest.applicationId, emojiId));
|
|
1256
|
+
},
|
|
1257
|
+
async getEmojis (guildId) {
|
|
1258
|
+
return await rest.get(rest.routes.guilds.emojis(guildId));
|
|
1259
|
+
},
|
|
1260
|
+
async getApplicationEmojis () {
|
|
1261
|
+
return await rest.get(rest.routes.applicationEmojis(rest.applicationId));
|
|
1262
|
+
},
|
|
1263
|
+
async getFollowupMessage (token, messageId) {
|
|
1264
|
+
return await rest.get(rest.routes.interactions.responses.message(rest.applicationId, token, messageId), {
|
|
1265
|
+
unauthorized: true
|
|
1266
|
+
});
|
|
1267
|
+
},
|
|
1268
|
+
async getGatewayBot () {
|
|
1269
|
+
return await rest.get(rest.routes.gatewayBot());
|
|
1270
|
+
},
|
|
1271
|
+
async getGlobalApplicationCommand (commandId) {
|
|
1272
|
+
return await rest.get(rest.routes.interactions.commands.command(rest.applicationId, commandId));
|
|
1273
|
+
},
|
|
1274
|
+
async getGlobalApplicationCommands (options) {
|
|
1275
|
+
return await rest.get(rest.routes.interactions.commands.commands(rest.applicationId, options?.withLocalizations));
|
|
1276
|
+
},
|
|
1277
|
+
async getGuild (guildId, options = {
|
|
1278
|
+
counts: true
|
|
1279
|
+
}) {
|
|
1280
|
+
return await rest.get(rest.routes.guilds.guild(guildId, options.counts));
|
|
1281
|
+
},
|
|
1282
|
+
async getGuilds (token, options) {
|
|
1283
|
+
const makeRequestOptions = token ? {
|
|
1284
|
+
headers: {
|
|
1285
|
+
authorization: `Bearer ${token}`
|
|
1286
|
+
},
|
|
1287
|
+
unauthorized: true
|
|
1288
|
+
} : undefined;
|
|
1289
|
+
return await rest.get(rest.routes.guilds.userGuilds(options), makeRequestOptions);
|
|
1290
|
+
},
|
|
1291
|
+
async getGuildApplicationCommand (commandId, guildId) {
|
|
1292
|
+
return await rest.get(rest.routes.interactions.commands.guilds.one(rest.applicationId, guildId, commandId));
|
|
1293
|
+
},
|
|
1294
|
+
async getGuildApplicationCommands (guildId, options) {
|
|
1295
|
+
return await rest.get(rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId, options?.withLocalizations));
|
|
1296
|
+
},
|
|
1297
|
+
async getGuildPreview (guildId) {
|
|
1298
|
+
return await rest.get(rest.routes.guilds.preview(guildId));
|
|
1299
|
+
},
|
|
1300
|
+
async getGuildTemplate (templateCode) {
|
|
1301
|
+
return await rest.get(rest.routes.guilds.templates.code(templateCode));
|
|
1302
|
+
},
|
|
1303
|
+
async getGuildTemplates (guildId) {
|
|
1304
|
+
return await rest.get(rest.routes.guilds.templates.all(guildId));
|
|
1305
|
+
},
|
|
1306
|
+
async getGuildWebhooks (guildId) {
|
|
1307
|
+
return await rest.get(rest.routes.guilds.webhooks(guildId));
|
|
1308
|
+
},
|
|
1309
|
+
async getIntegrations (guildId) {
|
|
1310
|
+
return await rest.get(rest.routes.guilds.integrations(guildId));
|
|
1311
|
+
},
|
|
1312
|
+
async getInvite (inviteCode, options) {
|
|
1313
|
+
return await rest.get(rest.routes.guilds.invite(inviteCode, options));
|
|
1314
|
+
},
|
|
1315
|
+
async getInvites (guildId) {
|
|
1316
|
+
return await rest.get(rest.routes.guilds.invites(guildId));
|
|
1317
|
+
},
|
|
1318
|
+
async getMessage (channelId, messageId) {
|
|
1319
|
+
return await rest.get(rest.routes.channels.message(channelId, messageId));
|
|
1320
|
+
},
|
|
1321
|
+
async getMessages (channelId, options) {
|
|
1322
|
+
return await rest.get(rest.routes.channels.messages(channelId, options));
|
|
1323
|
+
},
|
|
1324
|
+
async searchGuildMessages (guildId, options) {
|
|
1325
|
+
return await rest.get(rest.routes.guilds.messagesSearch(guildId, options));
|
|
1326
|
+
},
|
|
1327
|
+
async getStickerPack (stickerPackId) {
|
|
1328
|
+
return await rest.get(rest.routes.stickerPack(stickerPackId));
|
|
1329
|
+
},
|
|
1330
|
+
async getStickerPacks () {
|
|
1331
|
+
return await rest.get(rest.routes.stickerPacks());
|
|
1332
|
+
},
|
|
1333
|
+
async getOriginalInteractionResponse (token) {
|
|
1334
|
+
return await rest.get(rest.routes.interactions.responses.original(rest.applicationId, token), {
|
|
1335
|
+
unauthorized: true
|
|
1336
|
+
});
|
|
1337
|
+
},
|
|
1338
|
+
async getChannelPins (channelId, options) {
|
|
1339
|
+
return await rest.get(rest.routes.channels.messagePins(channelId, options));
|
|
1340
|
+
},
|
|
1341
|
+
async getPinnedMessages (channelId) {
|
|
1342
|
+
return await rest.get(rest.routes.channels.pins(channelId));
|
|
1343
|
+
},
|
|
1344
|
+
async getPrivateArchivedThreads (channelId, options) {
|
|
1345
|
+
return await rest.get(rest.routes.channels.threads.private(channelId, options));
|
|
1346
|
+
},
|
|
1347
|
+
async getPrivateJoinedArchivedThreads (channelId, options) {
|
|
1348
|
+
return await rest.get(rest.routes.channels.threads.joined(channelId, options));
|
|
1349
|
+
},
|
|
1350
|
+
async getPruneCount (guildId, options) {
|
|
1351
|
+
return await rest.get(rest.routes.guilds.prune(guildId, options));
|
|
1352
|
+
},
|
|
1353
|
+
async getPublicArchivedThreads (channelId, options) {
|
|
1354
|
+
return await rest.get(rest.routes.channels.threads.public(channelId, options));
|
|
1355
|
+
},
|
|
1356
|
+
async getRoles (guildId) {
|
|
1357
|
+
return await rest.get(rest.routes.guilds.roles.all(guildId));
|
|
1358
|
+
},
|
|
1359
|
+
async getRole (guildId, roleId) {
|
|
1360
|
+
return await rest.get(rest.routes.guilds.roles.one(guildId, roleId));
|
|
1361
|
+
},
|
|
1362
|
+
async getScheduledEvent (guildId, eventId, options) {
|
|
1363
|
+
return await rest.get(rest.routes.guilds.events.event(guildId, eventId, options?.withUserCount));
|
|
1364
|
+
},
|
|
1365
|
+
async getScheduledEvents (guildId, options) {
|
|
1366
|
+
return await rest.get(rest.routes.guilds.events.events(guildId, options?.withUserCount));
|
|
1367
|
+
},
|
|
1368
|
+
async getScheduledEventUsers (guildId, eventId, options) {
|
|
1369
|
+
return await rest.get(rest.routes.guilds.events.users(guildId, eventId, options));
|
|
1370
|
+
},
|
|
1371
|
+
async getSessionInfo () {
|
|
1372
|
+
return await rest.getGatewayBot();
|
|
1373
|
+
},
|
|
1374
|
+
async getStageInstance (channelId) {
|
|
1375
|
+
return await rest.get(rest.routes.channels.stage(channelId));
|
|
1376
|
+
},
|
|
1377
|
+
async getOwnVoiceState (guildId) {
|
|
1378
|
+
return await rest.get(rest.routes.guilds.voice(guildId));
|
|
1379
|
+
},
|
|
1380
|
+
async getUserVoiceState (guildId, userId) {
|
|
1381
|
+
return await rest.get(rest.routes.guilds.voice(guildId, userId));
|
|
1382
|
+
},
|
|
1383
|
+
async getSticker (stickerId) {
|
|
1384
|
+
return await rest.get(rest.routes.sticker(stickerId));
|
|
1385
|
+
},
|
|
1386
|
+
async getGuildSticker (guildId, stickerId) {
|
|
1387
|
+
return await rest.get(rest.routes.guilds.sticker(guildId, stickerId));
|
|
1388
|
+
},
|
|
1389
|
+
async getGuildStickers (guildId) {
|
|
1390
|
+
return await rest.get(rest.routes.guilds.stickers(guildId));
|
|
1391
|
+
},
|
|
1392
|
+
async getThreadMember (channelId, userId, options) {
|
|
1393
|
+
return await rest.get(rest.routes.channels.threads.getUser(channelId, userId, options));
|
|
1394
|
+
},
|
|
1395
|
+
async getThreadMembers (channelId, options) {
|
|
1396
|
+
return await rest.get(rest.routes.channels.threads.members(channelId, options));
|
|
1397
|
+
},
|
|
1398
|
+
async getReactions (channelId, messageId, reaction, options) {
|
|
1399
|
+
return await rest.get(rest.routes.channels.reactions.message(channelId, messageId, reaction, options));
|
|
1400
|
+
},
|
|
1401
|
+
async getUser (id) {
|
|
1402
|
+
return await rest.get(rest.routes.user(id));
|
|
1403
|
+
},
|
|
1404
|
+
async getCurrentUser (token) {
|
|
1405
|
+
return await rest.get(rest.routes.currentUser(), {
|
|
1406
|
+
headers: {
|
|
1407
|
+
authorization: `Bearer ${token}`
|
|
1408
|
+
},
|
|
1409
|
+
unauthorized: true
|
|
1410
|
+
});
|
|
1411
|
+
},
|
|
1412
|
+
async getUserConnections (token) {
|
|
1413
|
+
return await rest.get(rest.routes.oauth2.connections(), {
|
|
1414
|
+
headers: {
|
|
1415
|
+
authorization: `Bearer ${token}`
|
|
1416
|
+
},
|
|
1417
|
+
unauthorized: true
|
|
1418
|
+
});
|
|
1419
|
+
},
|
|
1420
|
+
async getUserApplicationRoleConnection (token, applicationId) {
|
|
1421
|
+
return await rest.get(rest.routes.oauth2.roleConnections(applicationId), {
|
|
1422
|
+
headers: {
|
|
1423
|
+
authorization: `Bearer ${token}`
|
|
1424
|
+
},
|
|
1425
|
+
unauthorized: true
|
|
1426
|
+
});
|
|
1427
|
+
},
|
|
1428
|
+
async getVanityUrl (guildId) {
|
|
1429
|
+
return await rest.get(rest.routes.guilds.vanity(guildId));
|
|
1430
|
+
},
|
|
1431
|
+
async getVoiceRegions (guildId) {
|
|
1432
|
+
return await rest.get(rest.routes.guilds.regions(guildId));
|
|
1433
|
+
},
|
|
1434
|
+
async getWebhook (webhookId) {
|
|
1435
|
+
return await rest.get(rest.routes.webhooks.id(webhookId));
|
|
1436
|
+
},
|
|
1437
|
+
async getWebhookMessage (webhookId, token, messageId, options) {
|
|
1438
|
+
return await rest.get(rest.routes.webhooks.message(webhookId, token, messageId, options), {
|
|
1439
|
+
unauthorized: true
|
|
1440
|
+
});
|
|
1441
|
+
},
|
|
1442
|
+
async getWebhookWithToken (webhookId, token) {
|
|
1443
|
+
return await rest.get(rest.routes.webhooks.webhook(webhookId, token), {
|
|
1444
|
+
unauthorized: true
|
|
1445
|
+
});
|
|
1446
|
+
},
|
|
1447
|
+
async getWelcomeScreen (guildId) {
|
|
1448
|
+
return await rest.get(rest.routes.guilds.welcome(guildId));
|
|
1449
|
+
},
|
|
1450
|
+
async getWidget (guildId) {
|
|
1451
|
+
return await rest.get(rest.routes.guilds.widgetJson(guildId));
|
|
1452
|
+
},
|
|
1453
|
+
async getWidgetSettings (guildId) {
|
|
1454
|
+
return await rest.get(rest.routes.guilds.widget(guildId));
|
|
1455
|
+
},
|
|
1456
|
+
async joinThread (channelId) {
|
|
1457
|
+
await rest.put(rest.routes.channels.threads.me(channelId));
|
|
1458
|
+
},
|
|
1459
|
+
async leaveGuild (guildId) {
|
|
1460
|
+
await rest.delete(rest.routes.guilds.leave(guildId));
|
|
1461
|
+
},
|
|
1462
|
+
async leaveThread (channelId) {
|
|
1463
|
+
await rest.delete(rest.routes.channels.threads.me(channelId));
|
|
1464
|
+
},
|
|
1465
|
+
async publishMessage (channelId, messageId) {
|
|
1466
|
+
return await rest.post(rest.routes.channels.crosspost(channelId, messageId));
|
|
1467
|
+
},
|
|
1468
|
+
async removeRole (guildId, userId, roleId, reason) {
|
|
1469
|
+
await rest.delete(rest.routes.guilds.roles.member(guildId, userId, roleId), {
|
|
1470
|
+
reason
|
|
1471
|
+
});
|
|
1472
|
+
},
|
|
1473
|
+
async removeThreadMember (channelId, userId) {
|
|
1474
|
+
await rest.delete(rest.routes.channels.threads.user(channelId, userId));
|
|
1475
|
+
},
|
|
1476
|
+
async removeDmRecipient (channelId, userId) {
|
|
1477
|
+
await rest.delete(rest.routes.channels.dmRecipient(channelId, userId));
|
|
1478
|
+
},
|
|
1479
|
+
async sendFollowupMessage (token, options) {
|
|
1480
|
+
return await rest.post(rest.routes.webhooks.webhook(rest.applicationId, token), {
|
|
1481
|
+
body: options,
|
|
1482
|
+
files: options.files,
|
|
1483
|
+
unauthorized: true
|
|
1484
|
+
});
|
|
1485
|
+
},
|
|
1486
|
+
async sendInteractionResponse (interactionId, token, options, params) {
|
|
1487
|
+
return await rest.post(rest.routes.interactions.responses.callback(interactionId, token, params), {
|
|
1488
|
+
body: options,
|
|
1489
|
+
files: options.data?.files,
|
|
1490
|
+
runThroughQueue: false,
|
|
1491
|
+
unauthorized: true
|
|
1492
|
+
});
|
|
1493
|
+
},
|
|
1494
|
+
async sendMessage (channelId, body) {
|
|
1495
|
+
return await rest.post(rest.routes.channels.messages(channelId), {
|
|
1496
|
+
body,
|
|
1497
|
+
files: body.files
|
|
1498
|
+
});
|
|
1499
|
+
},
|
|
1500
|
+
async startThreadWithMessage (channelId, messageId, body, reason) {
|
|
1501
|
+
return await rest.post(rest.routes.channels.threads.message(channelId, messageId), {
|
|
1502
|
+
body,
|
|
1503
|
+
reason
|
|
1504
|
+
});
|
|
1505
|
+
},
|
|
1506
|
+
async startThreadWithoutMessage (channelId, body, reason) {
|
|
1507
|
+
return await rest.post(rest.routes.channels.threads.all(channelId), {
|
|
1508
|
+
body,
|
|
1509
|
+
reason
|
|
1510
|
+
});
|
|
1511
|
+
},
|
|
1512
|
+
async getPollAnswerVoters (channelId, messageId, answerId, options) {
|
|
1513
|
+
return await rest.get(rest.routes.channels.polls.votes(channelId, messageId, answerId, options));
|
|
1514
|
+
},
|
|
1515
|
+
async endPoll (channelId, messageId) {
|
|
1516
|
+
return await rest.post(rest.routes.channels.polls.expire(channelId, messageId));
|
|
1517
|
+
},
|
|
1518
|
+
async syncGuildTemplate (guildId) {
|
|
1519
|
+
return await rest.put(rest.routes.guilds.templates.all(guildId));
|
|
1520
|
+
},
|
|
1521
|
+
async banMember (guildId, userId, body, reason) {
|
|
1522
|
+
await rest.put(rest.routes.guilds.members.ban(guildId, userId), {
|
|
1523
|
+
body,
|
|
1524
|
+
reason
|
|
1525
|
+
});
|
|
1526
|
+
},
|
|
1527
|
+
async bulkBanMembers (guildId, options, reason) {
|
|
1528
|
+
return await rest.post(rest.routes.guilds.members.bulkBan(guildId), {
|
|
1529
|
+
body: options,
|
|
1530
|
+
reason
|
|
1531
|
+
});
|
|
1532
|
+
},
|
|
1533
|
+
async editCurrentMember (guildId, body, reason) {
|
|
1534
|
+
return await rest.patch(rest.routes.guilds.members.bot(guildId), {
|
|
1535
|
+
body,
|
|
1536
|
+
reason
|
|
1537
|
+
});
|
|
1538
|
+
},
|
|
1539
|
+
async editMember (guildId, userId, body, reason) {
|
|
1540
|
+
return await rest.patch(rest.routes.guilds.members.member(guildId, userId), {
|
|
1541
|
+
body,
|
|
1542
|
+
reason
|
|
1543
|
+
});
|
|
1544
|
+
},
|
|
1545
|
+
async getCurrentMember (guildId, token) {
|
|
1546
|
+
return await rest.get(rest.routes.guilds.members.currentMember(guildId), {
|
|
1547
|
+
headers: {
|
|
1548
|
+
authorization: `Bearer ${token}`
|
|
1549
|
+
},
|
|
1550
|
+
unauthorized: true
|
|
1551
|
+
});
|
|
1552
|
+
},
|
|
1553
|
+
async getMember (guildId, userId) {
|
|
1554
|
+
return await rest.get(rest.routes.guilds.members.member(guildId, userId));
|
|
1555
|
+
},
|
|
1556
|
+
async getMembers (guildId, options) {
|
|
1557
|
+
return await rest.get(rest.routes.guilds.members.members(guildId, options));
|
|
1558
|
+
},
|
|
1559
|
+
async getApplicationActivityInstance (applicationId, instanceId) {
|
|
1560
|
+
return await rest.get(rest.routes.applicationActivityInstance(applicationId, instanceId));
|
|
1561
|
+
},
|
|
1562
|
+
async kickMember (guildId, userId, reason) {
|
|
1563
|
+
await rest.delete(rest.routes.guilds.members.member(guildId, userId), {
|
|
1564
|
+
reason
|
|
1565
|
+
});
|
|
1566
|
+
},
|
|
1567
|
+
async pinMessage (channelId, messageId, reason) {
|
|
1568
|
+
await rest.put(rest.routes.channels.messagePin(channelId, messageId), {
|
|
1569
|
+
reason
|
|
1570
|
+
});
|
|
1571
|
+
},
|
|
1572
|
+
async pruneMembers (guildId, body, reason) {
|
|
1573
|
+
return await rest.post(rest.routes.guilds.members.prune(guildId), {
|
|
1574
|
+
body,
|
|
1575
|
+
reason
|
|
1576
|
+
});
|
|
1577
|
+
},
|
|
1578
|
+
async searchMembers (guildId, query, options) {
|
|
1579
|
+
return await rest.get(rest.routes.guilds.members.search(guildId, query, options));
|
|
1580
|
+
},
|
|
1581
|
+
async getGuildOnboarding (guildId) {
|
|
1582
|
+
return await rest.get(rest.routes.guilds.onboarding(guildId));
|
|
1583
|
+
},
|
|
1584
|
+
async editGuildOnboarding (guildId, options, reason) {
|
|
1585
|
+
return await rest.put(rest.routes.guilds.onboarding(guildId), {
|
|
1586
|
+
body: options,
|
|
1587
|
+
reason
|
|
1588
|
+
});
|
|
1589
|
+
},
|
|
1590
|
+
async modifyGuildIncidentActions (guildId, options) {
|
|
1591
|
+
return await rest.put(rest.routes.guilds.incidentActions(guildId), {
|
|
1592
|
+
body: options
|
|
1593
|
+
});
|
|
1594
|
+
},
|
|
1595
|
+
async unbanMember (guildId, userId, reason) {
|
|
1596
|
+
await rest.delete(rest.routes.guilds.members.ban(guildId, userId), {
|
|
1597
|
+
reason
|
|
1598
|
+
});
|
|
1599
|
+
},
|
|
1600
|
+
async unpinMessage (channelId, messageId, reason) {
|
|
1601
|
+
await rest.delete(rest.routes.channels.messagePin(channelId, messageId), {
|
|
1602
|
+
reason
|
|
1603
|
+
});
|
|
1604
|
+
},
|
|
1605
|
+
async triggerTypingIndicator (channelId) {
|
|
1606
|
+
await rest.post(rest.routes.channels.typing(channelId));
|
|
1607
|
+
},
|
|
1608
|
+
async upsertGlobalApplicationCommands (body, options) {
|
|
1609
|
+
const restOptions = {
|
|
1610
|
+
body
|
|
1611
|
+
};
|
|
1612
|
+
if (options?.bearerToken) {
|
|
1613
|
+
restOptions.unauthorized = true;
|
|
1614
|
+
restOptions.headers = {
|
|
1615
|
+
authorization: `Bearer ${options.bearerToken}`
|
|
1616
|
+
};
|
|
1617
|
+
}
|
|
1618
|
+
return await rest.put(rest.routes.interactions.commands.commands(rest.applicationId), restOptions);
|
|
1619
|
+
},
|
|
1620
|
+
async upsertGuildApplicationCommands (guildId, body, options) {
|
|
1621
|
+
const restOptions = {
|
|
1622
|
+
body
|
|
1623
|
+
};
|
|
1624
|
+
if (options?.bearerToken) {
|
|
1625
|
+
restOptions.unauthorized = true;
|
|
1626
|
+
restOptions.headers = {
|
|
1627
|
+
authorization: `Bearer ${options.bearerToken}`
|
|
1628
|
+
};
|
|
1629
|
+
}
|
|
1630
|
+
return await rest.put(rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId), restOptions);
|
|
1631
|
+
},
|
|
1632
|
+
async editUserApplicationRoleConnection (token, applicationId, body) {
|
|
1633
|
+
return await rest.put(rest.routes.oauth2.roleConnections(applicationId), {
|
|
1634
|
+
body,
|
|
1635
|
+
headers: {
|
|
1636
|
+
authorization: `Bearer ${token}`
|
|
1637
|
+
},
|
|
1638
|
+
unauthorized: true
|
|
1639
|
+
});
|
|
1640
|
+
},
|
|
1641
|
+
async deleteCurrentUserApplicationRoleConnection (bearerToken, applicationId) {
|
|
1642
|
+
return await rest.delete(rest.routes.oauth2.roleConnections(applicationId), {
|
|
1643
|
+
headers: {
|
|
1644
|
+
authorization: `Bearer ${bearerToken}`
|
|
1645
|
+
},
|
|
1646
|
+
unauthorized: true
|
|
1647
|
+
});
|
|
1648
|
+
},
|
|
1649
|
+
async addGuildMember (guildId, userId, body) {
|
|
1650
|
+
return await rest.put(rest.routes.guilds.members.member(guildId, userId), {
|
|
1651
|
+
body
|
|
1652
|
+
});
|
|
1653
|
+
},
|
|
1654
|
+
async createTestEntitlement (applicationId, body) {
|
|
1655
|
+
return await rest.post(rest.routes.monetization.entitlements(applicationId), {
|
|
1656
|
+
body
|
|
1657
|
+
});
|
|
1658
|
+
},
|
|
1659
|
+
async listEntitlements (applicationId, options) {
|
|
1660
|
+
return await rest.get(rest.routes.monetization.entitlements(applicationId, options));
|
|
1661
|
+
},
|
|
1662
|
+
async getEntitlement (applicationId, entitlementId) {
|
|
1663
|
+
return await rest.get(rest.routes.monetization.entitlement(applicationId, entitlementId));
|
|
1664
|
+
},
|
|
1665
|
+
async deleteTestEntitlement (applicationId, entitlementId) {
|
|
1666
|
+
await rest.delete(rest.routes.monetization.entitlement(applicationId, entitlementId));
|
|
1667
|
+
},
|
|
1668
|
+
async consumeEntitlement (applicationId, entitlementId) {
|
|
1669
|
+
await rest.post(rest.routes.monetization.consumeEntitlement(applicationId, entitlementId));
|
|
1670
|
+
},
|
|
1671
|
+
async listSkus (applicationId) {
|
|
1672
|
+
return await rest.get(rest.routes.monetization.skus(applicationId));
|
|
1673
|
+
},
|
|
1674
|
+
async listSubscriptions (skuId, options) {
|
|
1675
|
+
return await rest.get(rest.routes.monetization.subscriptions(skuId, options));
|
|
1676
|
+
},
|
|
1677
|
+
async getSubscription (skuId, subscriptionId) {
|
|
1678
|
+
return await rest.get(rest.routes.monetization.subscription(skuId, subscriptionId));
|
|
1679
|
+
},
|
|
1680
|
+
async sendSoundboardSound (channelId, options) {
|
|
1681
|
+
await rest.post(rest.routes.soundboard.sendSound(channelId), {
|
|
1682
|
+
body: options
|
|
1683
|
+
});
|
|
1684
|
+
},
|
|
1685
|
+
async listDefaultSoundboardSounds () {
|
|
1686
|
+
return await rest.get(rest.routes.soundboard.listDefault());
|
|
1687
|
+
},
|
|
1688
|
+
async listGuildSoundboardSounds (guildId) {
|
|
1689
|
+
return await rest.get(rest.routes.soundboard.guildSounds(guildId));
|
|
1690
|
+
},
|
|
1691
|
+
async getGuildSoundboardSound (guildId, soundId) {
|
|
1692
|
+
return await rest.get(rest.routes.soundboard.guildSound(guildId, soundId));
|
|
1693
|
+
},
|
|
1694
|
+
async createGuildSoundboardSound (guildId, options, reason) {
|
|
1695
|
+
return await rest.post(rest.routes.soundboard.guildSounds(guildId), {
|
|
1696
|
+
body: options,
|
|
1697
|
+
reason
|
|
1698
|
+
});
|
|
1699
|
+
},
|
|
1700
|
+
async modifyGuildSoundboardSound (guildId, soundId, options, reason) {
|
|
1701
|
+
return await rest.post(rest.routes.soundboard.guildSound(guildId, soundId), {
|
|
1702
|
+
body: options,
|
|
1703
|
+
reason
|
|
1704
|
+
});
|
|
1705
|
+
},
|
|
1706
|
+
async deleteGuildSoundboardSound (guildId, soundId, reason) {
|
|
1707
|
+
return await rest.delete(rest.routes.soundboard.guildSound(guildId, soundId), {
|
|
1708
|
+
reason
|
|
1709
|
+
});
|
|
1710
|
+
},
|
|
1711
|
+
async listApplicationRoleConnectionsMetadataRecords (applicationId) {
|
|
1712
|
+
return await rest.get(rest.routes.applicationRoleConnectionMetadata(applicationId));
|
|
1713
|
+
},
|
|
1714
|
+
async updateApplicationRoleConnectionsMetadataRecords (applicationId, options) {
|
|
1715
|
+
return await rest.put(rest.routes.applicationRoleConnectionMetadata(applicationId), {
|
|
1716
|
+
body: options
|
|
1717
|
+
});
|
|
1718
|
+
},
|
|
1719
|
+
async createLobby (options) {
|
|
1720
|
+
return await rest.post(rest.routes.lobby.create(), {
|
|
1721
|
+
body: options
|
|
1722
|
+
});
|
|
1723
|
+
},
|
|
1724
|
+
async getLobby (lobbyId) {
|
|
1725
|
+
return await rest.get(rest.routes.lobby.lobby(lobbyId));
|
|
1726
|
+
},
|
|
1727
|
+
async modifyLobby (lobbyId, options) {
|
|
1728
|
+
return await rest.patch(rest.routes.lobby.lobby(lobbyId), {
|
|
1729
|
+
body: options
|
|
1730
|
+
});
|
|
1731
|
+
},
|
|
1732
|
+
async deleteLobby (lobbyId) {
|
|
1733
|
+
return await rest.delete(rest.routes.lobby.lobby(lobbyId));
|
|
1734
|
+
},
|
|
1735
|
+
async addMemberToLobby (lobbyId, userId, options) {
|
|
1736
|
+
return await rest.put(rest.routes.lobby.member(lobbyId, userId), {
|
|
1737
|
+
body: options
|
|
1738
|
+
});
|
|
1739
|
+
},
|
|
1740
|
+
async bulkUpdateLobbyMembers (lobbyId, options) {
|
|
1741
|
+
return await rest.post(rest.routes.lobby.membersBulk(lobbyId), {
|
|
1742
|
+
body: options
|
|
1743
|
+
});
|
|
1744
|
+
},
|
|
1745
|
+
async removeMemberFromLobby (lobbyId, userId) {
|
|
1746
|
+
return await rest.delete(rest.routes.lobby.member(lobbyId, userId));
|
|
1747
|
+
},
|
|
1748
|
+
async leaveLobby (lobbyId, bearerToken) {
|
|
1749
|
+
return await rest.delete(rest.routes.lobby.leave(lobbyId), {
|
|
1750
|
+
headers: {
|
|
1751
|
+
authorization: `Bearer ${bearerToken}`
|
|
1752
|
+
},
|
|
1753
|
+
unauthorized: true
|
|
1754
|
+
});
|
|
1755
|
+
},
|
|
1756
|
+
async linkChannelToLobby (lobbyId, bearerToken, options) {
|
|
1757
|
+
return await rest.patch(rest.routes.lobby.link(lobbyId), {
|
|
1758
|
+
body: options,
|
|
1759
|
+
headers: {
|
|
1760
|
+
authorization: `Bearer ${bearerToken}`
|
|
1761
|
+
},
|
|
1762
|
+
unauthorized: true
|
|
1763
|
+
});
|
|
1764
|
+
},
|
|
1765
|
+
async unlinkChannelToLobby (lobbyId, bearerToken) {
|
|
1766
|
+
return await rest.patch(rest.routes.lobby.link(lobbyId), {
|
|
1767
|
+
headers: {
|
|
1768
|
+
authorization: `Bearer ${bearerToken}`
|
|
1769
|
+
},
|
|
1770
|
+
unauthorized: true
|
|
1771
|
+
});
|
|
1772
|
+
},
|
|
1773
|
+
async updateLobbyMessageModerationMetadata (lobbyId, messageId, options) {
|
|
1774
|
+
await rest.put(rest.routes.lobby.moderationMetadata(lobbyId, messageId), {
|
|
1775
|
+
body: options
|
|
1776
|
+
});
|
|
1777
|
+
},
|
|
1778
|
+
createOrJoinLobby (options) {
|
|
1779
|
+
return rest.put(rest.routes.lobby.create(), {
|
|
1780
|
+
body: options
|
|
1781
|
+
});
|
|
1782
|
+
},
|
|
1783
|
+
sendLobbyMessage (bearerToken, lobbyId, options) {
|
|
1784
|
+
return rest.post(rest.routes.lobby.messages(lobbyId), {
|
|
1785
|
+
body: options,
|
|
1786
|
+
headers: {
|
|
1787
|
+
authorization: `Bearer ${bearerToken}`
|
|
1788
|
+
},
|
|
1789
|
+
unauthorized: true
|
|
1790
|
+
});
|
|
1791
|
+
},
|
|
1792
|
+
getLobbyMessages (bearerToken, lobbyId, options) {
|
|
1793
|
+
return rest.get(rest.routes.lobby.messages(lobbyId, options), {
|
|
1794
|
+
headers: {
|
|
1795
|
+
authorization: `Bearer ${bearerToken}`
|
|
1796
|
+
},
|
|
1797
|
+
unauthorized: true
|
|
1798
|
+
});
|
|
1799
|
+
},
|
|
1800
|
+
createLobbyChannelInviteForSelf (bearerToken, lobbyId) {
|
|
1801
|
+
return rest.post(rest.routes.lobby.inviteSelf(lobbyId), {
|
|
1802
|
+
headers: {
|
|
1803
|
+
authorization: `Bearer ${bearerToken}`
|
|
1804
|
+
},
|
|
1805
|
+
unauthorized: true
|
|
1806
|
+
});
|
|
1807
|
+
},
|
|
1808
|
+
createLobbyChannelInviteForUser (lobbyId, userId) {
|
|
1809
|
+
return rest.post(rest.routes.lobby.inviteUser(lobbyId, userId));
|
|
1810
|
+
},
|
|
1811
|
+
preferSnakeCase (enabled) {
|
|
1812
|
+
const camelizer = enabled ? (x)=>x : camelize;
|
|
1813
|
+
rest.get = async (url, options)=>{
|
|
1814
|
+
return camelizer(await rest.makeRequest('GET', url, options));
|
|
1815
|
+
};
|
|
1816
|
+
rest.post = async (url, options)=>{
|
|
1817
|
+
return camelizer(await rest.makeRequest('POST', url, options));
|
|
1818
|
+
};
|
|
1819
|
+
rest.delete = async (url, options)=>{
|
|
1820
|
+
camelizer(await rest.makeRequest('DELETE', url, options));
|
|
1821
|
+
};
|
|
1822
|
+
rest.patch = async (url, options)=>{
|
|
1823
|
+
return camelizer(await rest.makeRequest('PATCH', url, options));
|
|
1824
|
+
};
|
|
1825
|
+
rest.put = async (url, options)=>{
|
|
1826
|
+
return camelizer(await rest.makeRequest('PUT', url, options));
|
|
1827
|
+
};
|
|
1828
|
+
return rest;
|
|
1829
|
+
}
|
|
1830
|
+
};
|
|
1831
|
+
return rest;
|
|
1832
|
+
}
|
|
1833
|
+
var HttpResponseCode = /*#__PURE__*/ function(HttpResponseCode) {
|
|
1834
|
+
/** Minimum value of a code in oder to consider that it was successful. */ HttpResponseCode[HttpResponseCode["Success"] = 200] = "Success";
|
|
1835
|
+
/** Request completed successfully, but Discord returned an empty body. */ HttpResponseCode[HttpResponseCode["NoContent"] = 204] = "NoContent";
|
|
1836
|
+
/** Minimum value of a code in order to consider that something went wrong. */ HttpResponseCode[HttpResponseCode["Error"] = 400] = "Error";
|
|
1837
|
+
/** This request got rate limited. */ HttpResponseCode[HttpResponseCode["TooManyRequests"] = 429] = "TooManyRequests";
|
|
1838
|
+
return HttpResponseCode;
|
|
1839
|
+
}(HttpResponseCode || {});
|
|
1840
|
+
/** Whether an error is the `TimeoutError` thrown by `AbortSignal.timeout()`. */ function isTimeoutError(error) {
|
|
1841
|
+
return error instanceof DOMException && error.name === 'TimeoutError';
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9tYW5hZ2VyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJ1ZmZlciB9IGZyb20gJ25vZGU6YnVmZmVyJztcbmltcG9ydCB7IHR5cGUgSW5zcGVjdE9wdGlvbnMsIGluc3BlY3QgfSBmcm9tICdub2RlOnV0aWwnO1xuaW1wb3J0IHR5cGUge1xuICBCaWdTdHJpbmcsXG4gIENhbWVsaXplLFxuICBEaXNjb3JkQWNjZXNzVG9rZW5SZXNwb25zZSxcbiAgRGlzY29yZEFjdGl2aXR5SW5zdGFuY2UsXG4gIERpc2NvcmRBcHBsaWNhdGlvbixcbiAgRGlzY29yZEFwcGxpY2F0aW9uQ29tbWFuZCxcbiAgRGlzY29yZEFwcGxpY2F0aW9uUm9sZUNvbm5lY3Rpb24sXG4gIERpc2NvcmRBcHBsaWNhdGlvblJvbGVDb25uZWN0aW9uTWV0YWRhdGEsXG4gIERpc2NvcmRBdWRpdExvZyxcbiAgRGlzY29yZEF1dG9Nb2RlcmF0aW9uUnVsZSxcbiAgRGlzY29yZEJhbixcbiAgRGlzY29yZEJ1bGtCYW4sXG4gIERpc2NvcmRDaGFubmVsLFxuICBEaXNjb3JkQ29ubmVjdGlvbixcbiAgRGlzY29yZEN1cnJlbnRBdXRob3JpemF0aW9uLFxuICBEaXNjb3JkRW1vamksXG4gIERpc2NvcmRFbnRpdGxlbWVudCxcbiAgRGlzY29yZEZvbGxvd2VkQ2hhbm5lbCxcbiAgRGlzY29yZEdldEFuc3dlclZvdGVzUmVzcG9uc2UsXG4gIERpc2NvcmRHZXRHYXRld2F5Qm90LFxuICBEaXNjb3JkR3VpbGQsXG4gIERpc2NvcmRHdWlsZEFwcGxpY2F0aW9uQ29tbWFuZFBlcm1pc3Npb25zLFxuICBEaXNjb3JkR3VpbGRPbmJvYXJkaW5nLFxuICBEaXNjb3JkR3VpbGRQcmV2aWV3LFxuICBEaXNjb3JkR3VpbGRXaWRnZXQsXG4gIERpc2NvcmRHdWlsZFdpZGdldFNldHRpbmdzLFxuICBEaXNjb3JkSW5jaWRlbnRzRGF0YSxcbiAgRGlzY29yZEludGVncmF0aW9uLFxuICBEaXNjb3JkSW50ZXJhY3Rpb25DYWxsYmFja1Jlc3BvbnNlLFxuICBEaXNjb3JkSW52aXRlLFxuICBEaXNjb3JkSW52aXRlTWV0YWRhdGEsXG4gIERpc2NvcmRMaXN0QWN0aXZlVGhyZWFkcyxcbiAgRGlzY29yZExpc3RBcmNoaXZlZFRocmVhZHMsXG4gIERpc2NvcmRMb2JieSxcbiAgRGlzY29yZExvYmJ5SW52aXRlLFxuICBEaXNjb3JkTG9iYnlNZW1iZXIsXG4gIERpc2NvcmRMb2JieU1lc3NhZ2UsXG4gIERpc2NvcmRNZW1iZXIsXG4gIERpc2NvcmRNZW1iZXJXaXRoVXNlcixcbiAgRGlzY29yZE1lc3NhZ2UsXG4gIERpc2NvcmRQcnVuZWRDb3VudCxcbiAgRGlzY29yZFJvbGUsXG4gIERpc2NvcmRTY2hlZHVsZWRFdmVudCxcbiAgRGlzY29yZFNlYXJjaEd1aWxkTWVzc2FnZXMsXG4gIERpc2NvcmRTZWFyY2hHdWlsZE1lc3NhZ2VzSW5kZXhpbmcsXG4gIERpc2NvcmRTa3UsXG4gIERpc2NvcmRTb3VuZGJvYXJkU291bmQsXG4gIERpc2NvcmRTdGFnZUluc3RhbmNlLFxuICBEaXNjb3JkU3RpY2tlcixcbiAgRGlzY29yZFN0aWNrZXJQYWNrLFxuICBEaXNjb3JkU3Vic2NyaXB0aW9uLFxuICBEaXNjb3JkVGFyZ2V0VXNlcnNKb2JTdGF0dXMsXG4gIERpc2NvcmRUZW1wbGF0ZSxcbiAgRGlzY29yZFRocmVhZE1lbWJlcixcbiAgRGlzY29yZFVzZXIsXG4gIERpc2NvcmRWYW5pdHlVcmwsXG4gIERpc2NvcmRWb2ljZVJlZ2lvbixcbiAgRGlzY29yZFZvaWNlU3RhdGUsXG4gIERpc2NvcmRXZWJob29rLFxuICBEaXNjb3JkV2VsY29tZVNjcmVlbixcbiAgTW9kaWZ5R3VpbGRUZW1wbGF0ZSxcbn0gZnJvbSAnQGRpc2NvcmRlbm8vdHlwZXMnO1xuaW1wb3J0IHtcbiAgY2FtZWxpemUsXG4gIGNhbWVsVG9TbmFrZUNhc2UsXG4gIERJU0NPUkRFTk9fVkVSU0lPTixcbiAgZGVsYXksXG4gIGdldEJvdElkRnJvbVRva2VuLFxuICBoYXNQcm9wZXJ0eSxcbiAgbG9nZ2VyLFxuICBwcm9jZXNzUmVhY3Rpb25TdHJpbmcsXG4gIHNub3dmbGFrZVRvVGltZXN0YW1wLFxufSBmcm9tICdAZGlzY29yZGVuby91dGlscyc7XG5pbXBvcnQgeyBjcmVhdGVJbnZhbGlkUmVxdWVzdEJ1Y2tldCB9IGZyb20gJy4vaW52YWxpZEJ1Y2tldC5qcyc7XG5pbXBvcnQgeyBRdWV1ZSB9IGZyb20gJy4vcXVldWUuanMnO1xuaW1wb3J0IHsgY3JlYXRlUm91dGVzIH0gZnJvbSAnLi9yb3V0ZXMuanMnO1xuaW1wb3J0IHR5cGUgeyBDcmVhdGVSZXF1ZXN0Qm9keU9wdGlvbnMsIENyZWF0ZVJlc3RNYW5hZ2VyT3B0aW9ucywgTWFrZVJlcXVlc3RPcHRpb25zLCBSZXN0TWFuYWdlciwgU2VuZFJlcXVlc3RPcHRpb25zIH0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbmV4cG9ydCBjb25zdCBESVNDT1JEX0FQSV9WRVJTSU9OID0gMTA7XG5leHBvcnQgY29uc3QgRElTQ09SRF9BUElfVVJMID0gJ2h0dHBzOi8vZGlzY29yZC5jb20vYXBpJztcblxuZXhwb3J0IGNvbnN0IEFVRElUX0xPR19SRUFTT05fSEVBREVSID0gJ3gtYXVkaXQtbG9nLXJlYXNvbic7XG5leHBvcnQgY29uc3QgUkFURV9MSU1JVF9SRU1BSU5JTkdfSEVBREVSID0gJ3gtcmF0ZWxpbWl0LXJlbWFpbmluZyc7XG5leHBvcnQgY29uc3QgUkFURV9MSU1JVF9SRVNFVF9BRlRFUl9IRUFERVIgPSAneC1yYXRlbGltaXQtcmVzZXQtYWZ0ZXInO1xuZXhwb3J0IGNvbnN0IFJBVEVfTElNSVRfR0xPQkFMX0hFQURFUiA9ICd4LXJhdGVsaW1pdC1nbG9iYWwnO1xuZXhwb3J0IGNvbnN0IFJBVEVfTElNSVRfQlVDS0VUX0hFQURFUiA9ICd4LXJhdGVsaW1pdC1idWNrZXQnO1xuZXhwb3J0IGNvbnN0IFJBVEVfTElNSVRfTElNSVRfSEVBREVSID0gJ3gtcmF0ZWxpbWl0LWxpbWl0JztcbmV4cG9ydCBjb25zdCBSQVRFX0xJTUlUX1NDT1BFX0hFQURFUiA9ICd4LXJhdGVsaW1pdC1zY29wZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVSZXN0TWFuYWdlcihvcHRpb25zOiBDcmVhdGVSZXN0TWFuYWdlck9wdGlvbnMpOiBSZXN0TWFuYWdlciB7XG4gIGNvbnN0IGFwcGxpY2F0aW9uSWQgPSBvcHRpb25zLmFwcGxpY2F0aW9uSWQgPyBCaWdJbnQob3B0aW9ucy5hcHBsaWNhdGlvbklkKSA6IGdldEJvdElkRnJvbVRva2VuKG9wdGlvbnMudG9rZW4pO1xuXG4gIGNvbnN0IGJhc2VVcmwgPSAob3B0aW9ucy5wcm94eT8uYmFzZVVybCA/PyBESVNDT1JEX0FQSV9VUkwpLnJlcGxhY2UoL1xcLyQvLCAnJyk7XG4gIC8vIERpc2NvcmQgZXJyb3IgY2FuIGdldCBuZXN0ZWQgYSBsb3QsIHNvIHdlIHVzZSBhIGN1c3RvbSBpbnNwZWN0IHRvIGNoYW5nZSB0aGUgZGVwdGggdG8gSW5maW5pdHlcbiAgY29uc3QgYmFzZUVycm9yUHJvdG90eXBlID0ge1xuICAgIFtpbnNwZWN0LmN1c3RvbV0oX2RlcHRoOiBudW1iZXIsIG9wdGlvbnM6IEluc3BlY3RPcHRpb25zLCBfaW5zcGVjdDogdHlwZW9mIGluc3BlY3QpIHtcbiAgICAgIHJldHVybiBfaW5zcGVjdCh0aGlzLCB7XG4gICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgIGRlcHRoOiBJbmZpbml0eSxcbiAgICAgICAgLy8gU2luY2Ugd2UgY2FsbCBpbnNwZWN0IG9uIG91cnNlbGYsIHdlIG5lZWQgdG8gZGlzYWJsZSB0aGUgY2FsbHMgdG8gdGhlIGluc3BlY3QuY3VzdG9tIHN5bWJvbCBvciBlbHNlIGl0IHdpbGwgY2F1c2UgYW4gaW5maW5pdGUgbG9vcC5cbiAgICAgICAgY3VzdG9tSW5zcGVjdDogZmFsc2UsXG4gICAgICB9KTtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IHJlc3Q6IFJlc3RNYW5hZ2VyID0ge1xuICAgIGFwcGxpY2F0aW9uSWQsXG4gICAgYXV0aG9yaXphdGlvbjogb3B0aW9ucy5wcm94eT8uYXV0aG9yaXphdGlvbixcbiAgICBhdXRob3JpemF0aW9uSGVhZGVyOiBvcHRpb25zLnByb3h5Py5hdXRob3JpemF0aW9uSGVhZGVyID8/ICdhdXRob3JpemF0aW9uJyxcbiAgICBiYXNlVXJsLFxuICAgIGRlbGV0ZVF1ZXVlRGVsYXk6IDYwMDAwLFxuICAgIGdsb2JhbGx5UmF0ZUxpbWl0ZWQ6IGZhbHNlLFxuICAgIGludmFsaWRCdWNrZXQ6IGNyZWF0ZUludmFsaWRSZXF1ZXN0QnVja2V0KHsgbG9nZ2VyOiBvcHRpb25zLmxvZ2dlciB9KSxcbiAgICBpc1Byb3hpZWQ6ICFiYXNlVXJsLnN0YXJ0c1dpdGgoRElTQ09SRF9BUElfVVJMKSxcbiAgICB1cGRhdGVCZWFyZXJUb2tlbkVuZHBvaW50OiBvcHRpb25zLnByb3h5Py51cGRhdGVCZWFyZXJUb2tlbkVuZHBvaW50LFxuICAgIHJldHJ5UHJveGllZFJlcXVlc3RzOiBvcHRpb25zLnByb3h5Py5yZXRyeVJlcXVlc3RzID8/IGZhbHNlLFxuICAgIG1heFJldHJ5Q291bnQ6IEluZmluaXR5LFxuICAgIG1heFByb3h5UmV0cnlDb3VudDogMTUsXG4gICAgcHJveHlSZXRyeURlbGF5U3RlcDogMjUwLFxuICAgIHJlcXVlc3RUaW1lb3V0OiBvcHRpb25zLnJlcXVlc3RUaW1lb3V0ID8/IDMwMDAwLFxuICAgIHByb2Nlc3NpbmdSYXRlTGltaXRlZFBhdGhzOiBmYWxzZSxcbiAgICBxdWV1ZXM6IG5ldyBNYXAoKSxcbiAgICByYXRlTGltaXRlZFBhdGhzOiBuZXcgTWFwKCksXG4gICAgdG9rZW46IG9wdGlvbnMudG9rZW4sXG4gICAgdmVyc2lvbjogb3B0aW9ucy52ZXJzaW9uID8/IERJU0NPUkRfQVBJX1ZFUlNJT04sXG4gICAgbG9nZ2VyOiBvcHRpb25zLmxvZ2dlciA/PyBsb2dnZXIsXG4gICAgZXZlbnRzOiB7XG4gICAgICByZXF1ZXN0OiAoKSA9PiB7fSxcbiAgICAgIHJlc3BvbnNlOiAoKSA9PiB7fSxcbiAgICAgIHJlcXVlc3RFcnJvcjogKCkgPT4ge30sXG4gICAgICAuLi5vcHRpb25zLmV2ZW50cyxcbiAgICB9LFxuXG4gICAgcm91dGVzOiBjcmVhdGVSb3V0ZXMoKSxcblxuICAgIGNyZWF0ZUJhc2VIZWFkZXJzKCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgJ3VzZXItYWdlbnQnOiBgRGlzY29yZEJvdCAoaHR0cHM6Ly9naXRodWIuY29tL2Rpc2NvcmRlbm8vZGlzY29yZGVubywgdiR7RElTQ09SREVOT19WRVJTSU9OfSlgLFxuICAgICAgfTtcbiAgICB9LFxuXG4gICAgY2hlY2tSYXRlTGltaXRzKHVybCwgaWRlbnRpZmllcikge1xuICAgICAgY29uc3QgcmF0ZWxpbWl0ZWQgPSByZXN0LnJhdGVMaW1pdGVkUGF0aHMuZ2V0KGAke2lkZW50aWZpZXJ9JHt1cmx9YCk7XG5cbiAgICAgIGNvbnN0IGdsb2JhbCA9IHJlc3QucmF0ZUxpbWl0ZWRQYXRocy5nZXQoJ2dsb2JhbCcpO1xuICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcblxuICAgICAgaWYgKHJhdGVsaW1pdGVkICYmIG5vdyA8IHJhdGVsaW1pdGVkLnJlc2V0VGltZXN0YW1wKSB7XG4gICAgICAgIHJldHVybiByYXRlbGltaXRlZC5yZXNldFRpbWVzdGFtcCAtIG5vdztcbiAgICAgIH1cblxuICAgICAgaWYgKGdsb2JhbCAmJiBub3cgPCBnbG9iYWwucmVzZXRUaW1lc3RhbXApIHtcbiAgICAgICAgcmV0dXJuIGdsb2JhbC5yZXNldFRpbWVzdGFtcCAtIG5vdztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG5cbiAgICBhc3luYyB1cGRhdGVUb2tlblF1ZXVlcyhvbGRUb2tlbiwgbmV3VG9rZW4pIHtcbiAgICAgIGlmIChyZXN0LmlzUHJveGllZCkge1xuICAgICAgICBpZiAoIXJlc3QudXBkYXRlQmVhcmVyVG9rZW5FbmRwb2ludCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIFwiVGhlICdwcm94eS51cGRhdGVCZWFyZXJUb2tlbkVuZHBvaW50JyBvcHRpb24gbmVlZHMgdG8gYmUgc2V0IHdoZW4gdXNpbmcgYSByZXN0IHByb3h5IGFuZCBuZWVkZWQgdG8gY2FsbCAndXBkYXRlVG9rZW5RdWV1ZXMnXCIsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGhlYWRlcnMgPSB7XG4gICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfSBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gICAgICAgIGlmIChyZXN0LmF1dGhvcml6YXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGhlYWRlcnNbcmVzdC5hdXRob3JpemF0aW9uSGVhZGVyXSA9IHJlc3QuYXV0aG9yaXphdGlvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IGZldGNoKGAke3Jlc3QuYmFzZVVybH0vJHtyZXN0LnVwZGF0ZUJlYXJlclRva2VuRW5kcG9pbnR9YCwge1xuICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgIG9sZFRva2VuLFxuICAgICAgICAgICAgbmV3VG9rZW4sXG4gICAgICAgICAgfSksXG4gICAgICAgICAgaGVhZGVycyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBuZXdJZGVudGlmaWVyID0gYEJlYXJlciAke25ld1Rva2VufWA7XG5cbiAgICAgIC8vIFVwZGF0ZSBhbGwgdGhlIHF1ZXVlc1xuICAgICAgZm9yIChjb25zdCBba2V5LCBxdWV1ZV0gb2YgcmVzdC5xdWV1ZXMuZW50cmllcygpKSB7XG4gICAgICAgIGlmICgha2V5LnN0YXJ0c1dpdGgoYEJlYXJlciAke29sZFRva2VufWApKSBjb250aW51ZTtcblxuICAgICAgICByZXN0LnF1ZXVlcy5kZWxldGUoa2V5KTtcbiAgICAgICAgcXVldWUuaWRlbnRpZmllciA9IG5ld0lkZW50aWZpZXI7XG5cbiAgICAgICAgY29uc3QgbmV3S2V5ID0gYCR7bmV3SWRlbnRpZmllcn0ke3F1ZXVlLnVybH1gO1xuICAgICAgICBjb25zdCBuZXdRdWV1ZSA9IHJlc3QucXVldWVzLmdldChuZXdLZXkpO1xuXG4gICAgICAgIC8vIE1lcmdlIHRoZSBxdWV1ZXNcbiAgICAgICAgaWYgKG5ld1F1ZXVlKSB7XG4gICAgICAgICAgbmV3UXVldWUud2FpdGluZy51bnNoaWZ0KC4uLnF1ZXVlLndhaXRpbmcpO1xuICAgICAgICAgIG5ld1F1ZXVlLnBlbmRpbmcudW5zaGlmdCguLi5xdWV1ZS5wZW5kaW5nKTtcblxuICAgICAgICAgIHF1ZXVlLndhaXRpbmcgPSBbXTtcbiAgICAgICAgICBxdWV1ZS5wZW5kaW5nID0gW107XG5cbiAgICAgICAgICBxdWV1ZS5jbGVhbnVwKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdC5xdWV1ZXMuc2V0KG5ld0tleSwgcXVldWUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgW2tleSwgcmF0ZWxpbWl0UGF0aF0gb2YgcmVzdC5yYXRlTGltaXRlZFBhdGhzLmVudHJpZXMoKSkge1xuICAgICAgICBpZiAoIWtleS5zdGFydHNXaXRoKGBCZWFyZXIgJHtvbGRUb2tlbn1gKSkgY29udGludWU7XG5cbiAgICAgICAgcmVzdC5yYXRlTGltaXRlZFBhdGhzLnNldChgJHtuZXdJZGVudGlmaWVyfSR7cmF0ZWxpbWl0UGF0aC51cmx9YCwgcmF0ZWxpbWl0UGF0aCk7XG5cbiAgICAgICAgaWYgKHJhdGVsaW1pdFBhdGguYnVja2V0SWQpIHtcbiAgICAgICAgICByZXN0LnJhdGVMaW1pdGVkUGF0aHMuc2V0KGAke25ld0lkZW50aWZpZXJ9JHtyYXRlbGltaXRQYXRoLmJ1Y2tldElkfWAsIHJhdGVsaW1pdFBhdGgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIGNoYW5nZVRvRGlzY29yZEZvcm1hdChvYmo6IGFueSk6IGFueSB7XG4gICAgICBpZiAob2JqID09PSBudWxsKSByZXR1cm4gbnVsbDtcblxuICAgICAgaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICAgICAgICByZXR1cm4gb2JqLm1hcCgoaXRlbSkgPT4gcmVzdC5jaGFuZ2VUb0Rpc2NvcmRGb3JtYXQoaXRlbSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmV3T2JqOiBhbnkgPSB7fTtcblxuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhvYmopKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBvYmpba2V5XTtcblxuICAgICAgICAgIC8vIElmIHRoZSBrZXkgaXMgYWxyZWFkeSBpbiBzbmFrZV9jYXNlIHdlIGNhbiBhc3N1bWUgaXQgaXMgYWxyZWFkeSBpbiB0aGUgZGlzY29yZCBmb3JtYXQuXG4gICAgICAgICAgaWYgKGtleS5pbmNsdWRlcygnXycpKSB7XG4gICAgICAgICAgICBuZXdPYmpba2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICAgICAgICAgIGNhc2UgJ25hbWVMb2NhbGl6YXRpb25zJzpcbiAgICAgICAgICAgICAgICBuZXdPYmoubmFtZV9sb2NhbGl6YXRpb25zID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgIGNhc2UgJ2Rlc2NyaXB0aW9uTG9jYWxpemF0aW9ucyc6XG4gICAgICAgICAgICAgICAgbmV3T2JqLmRlc2NyaXB0aW9uX2xvY2FsaXphdGlvbnMgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBuZXdPYmpbY2FtZWxUb1NuYWtlQ2FzZShrZXkpXSA9IHJlc3QuY2hhbmdlVG9EaXNjb3JkRm9ybWF0KHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXdPYmo7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2Ygb2JqID09PSAnYmlnaW50JykgcmV0dXJuIG9iai50b1N0cmluZygpO1xuXG4gICAgICByZXR1cm4gb2JqO1xuICAgIH0sXG5cbiAgICBjcmVhdGVSZXF1ZXN0Qm9keShtZXRob2QsIG9wdGlvbnMpIHtcbiAgICAgIGNvbnN0IGhlYWRlcnMgPSB0aGlzLmNyZWF0ZUJhc2VIZWFkZXJzKCk7XG5cbiAgICAgIGlmIChvcHRpb25zPy51bmF1dGhvcml6ZWQgIT09IHRydWUpIGhlYWRlcnMuYXV0aG9yaXphdGlvbiA9IGBCb3QgJHtyZXN0LnRva2VufWA7XG5cbiAgICAgIC8vIElGIEEgUkVBU09OIElTIFBST1ZJREVEIEVOQ09ERSBJVCBJTiBIRUFERVJTXG4gICAgICBpZiAob3B0aW9ucz8ucmVhc29uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaGVhZGVyc1tBVURJVF9MT0dfUkVBU09OX0hFQURFUl0gPSBlbmNvZGVVUklDb21wb25lbnQob3B0aW9ucz8ucmVhc29uKTtcbiAgICAgIH1cblxuICAgICAgbGV0IGJvZHk6IHN0cmluZyB8IEZvcm1EYXRhIHwgdW5kZWZpbmVkO1xuXG4gICAgICAvLyBIYXZlIHRvIGNoZWNrIGZvciBhdHRhY2htZW50cyBmaXJzdCwgc2luY2UgYm9keSB0aGVuIGhhcyB0byBiZSBzZW5kIGluIGEgZGlmZmVyZW50IHdheS5cbiAgICAgIGlmIChvcHRpb25zPy5maWxlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IGZvcm0gPSBuZXcgRm9ybURhdGEoKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcHRpb25zLmZpbGVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgZm9ybS5hcHBlbmQoYGZpbGVzWyR7aX1dYCwgb3B0aW9ucy5maWxlc1tpXS5ibG9iLCBvcHRpb25zLmZpbGVzW2ldLm5hbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSGF2ZSB0byB1c2UgY2hhbmdlVG9EaXNjb3JkRm9ybWF0IG9yIGVsc2UgSlNPTi5zdHJpbmdpZnkgbWF5IHRocm93IGFuIGVycm9yIGZvciB0aGUgcHJlc2VuY2Ugb2YgQmlnSW50KHMpIGluIHRoZSBqc29uXG4gICAgICAgIGZvcm0uYXBwZW5kKCdwYXlsb2FkX2pzb24nLCBKU09OLnN0cmluZ2lmeShyZXN0LmNoYW5nZVRvRGlzY29yZEZvcm1hdCh7IC4uLm9wdGlvbnMuYm9keSwgZmlsZXM6IHVuZGVmaW5lZCB9KSkpO1xuXG4gICAgICAgIC8vIE5vIG5lZWQgdG8gc2V0IHRoZSBgY29udGVudC10eXBlYCBoZWFkZXIgc2luY2UgYGZldGNoYCBkb2VzIHRoYXQgYXV0b21hdGljYWxseSBmb3IgdXMgd2hlbiB3ZSB1c2UgYSBgRm9ybURhdGFgIG9iamVjdC5cbiAgICAgICAgYm9keSA9IGZvcm07XG4gICAgICB9IGVsc2UgaWYgKG9wdGlvbnM/LmJvZHkgJiYgb3B0aW9ucy5oZWFkZXJzICYmIG9wdGlvbnMuaGVhZGVyc1snY29udGVudC10eXBlJ10gPT09ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKSB7XG4gICAgICAgIC8vIE9BdXRoMiBib2R5IGhhbmRsaW5nXG4gICAgICAgIGNvbnN0IGZvcm1Cb2R5OiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICAgIGNvbnN0IGRpc2NvcmRCb2R5ID0gcmVzdC5jaGFuZ2VUb0Rpc2NvcmRGb3JtYXQob3B0aW9ucy5ib2R5KTtcblxuICAgICAgICBmb3IgKGNvbnN0IHByb3AgaW4gZGlzY29yZEJvZHkpIHtcbiAgICAgICAgICBmb3JtQm9keS5wdXNoKGAke2VuY29kZVVSSUNvbXBvbmVudChwcm9wKX09JHtlbmNvZGVVUklDb21wb25lbnQoZGlzY29yZEJvZHlbcHJvcF0pfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgYm9keSA9IGZvcm1Cb2R5LmpvaW4oJyYnKTtcbiAgICAgIH0gZWxzZSBpZiAob3B0aW9ucz8uYm9keSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChvcHRpb25zLmJvZHkgaW5zdGFuY2VvZiBGb3JtRGF0YSkge1xuICAgICAgICAgIGJvZHkgPSBvcHRpb25zLmJvZHk7XG4gICAgICAgICAgLy8gTm8gbmVlZCB0byBzZXQgdGhlIGBjb250ZW50LXR5cGVgIGhlYWRlciBzaW5jZSBgZmV0Y2hgIGRvZXMgdGhhdCBhdXRvbWF0aWNhbGx5IGZvciB1cyB3aGVuIHdlIHVzZSBhIGBGb3JtRGF0YWAgb2JqZWN0LlxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJvZHkgPSBKU09OLnN0cmluZ2lmeShyZXN0LmNoYW5nZVRvRGlzY29yZEZvcm1hdChvcHRpb25zLmJvZHkpKTtcbiAgICAgICAgICBoZWFkZXJzWydjb250ZW50LXR5cGUnXSA9IGBhcHBsaWNhdGlvbi9qc29uYDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBTT01FVElNRVMgU1BFQ0lBTCBIRUFERVJTIChFLkcuIENVU1RPTSBBVVRIT1JJWkFUSU9OKSBORUVEIFRPIEJFIFVTRURcbiAgICAgIGlmIChvcHRpb25zPy5oZWFkZXJzKSB7XG4gICAgICAgIE9iamVjdC5hc3NpZ24oaGVhZGVycywgb3B0aW9ucy5oZWFkZXJzKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYm9keSxcbiAgICAgICAgaGVhZGVycyxcbiAgICAgICAgbWV0aG9kLFxuICAgICAgfTtcbiAgICB9LFxuXG4gICAgY3JlYXRlUmVxdWVzdEVycm9yKGVycm9yLCByZWFzb24pIHtcbiAgICAgIGxldCBlcnJvclRleHQ6IHN0cmluZztcblxuICAgICAgc3dpdGNoIChyZWFzb24uc3RhdHVzKSB7XG4gICAgICAgIGNhc2UgNDAwOlxuICAgICAgICAgIGVycm9yVGV4dCA9IFwiVGhlIG9wdGlvbnMgd2FzIGltcHJvcGVybHkgZm9ybWF0dGVkLCBvciB0aGUgc2VydmVyIGNvdWxkbid0IHVuZGVyc3RhbmQgaXQuXCI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgNDAxOlxuICAgICAgICAgIGVycm9yVGV4dCA9ICdUaGUgQXV0aG9yaXphdGlvbiBoZWFkZXIgd2FzIG1pc3Npbmcgb3IgaW52YWxpZC4nO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDQwMzpcbiAgICAgICAgICBlcnJvclRleHQgPSAnVGhlIEF1dGhvcml6YXRpb24gdG9rZW4geW91IHBhc3NlZCBkaWQgbm90IGhhdmUgcGVybWlzc2lvbiB0byB0aGUgcmVzb3VyY2UuJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSA0MDQ6XG4gICAgICAgICAgZXJyb3JUZXh0ID0gXCJUaGUgcmVzb3VyY2UgYXQgdGhlIGxvY2F0aW9uIHNwZWNpZmllZCBkb2Vzbid0IGV4aXN0LlwiO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDQwNTpcbiAgICAgICAgICBlcnJvclRleHQgPSAnVGhlIEhUVFAgbWV0aG9kIHVzZWQgaXMgbm90IHZhbGlkIGZvciB0aGUgbG9jYXRpb24gc3BlY2lmaWVkLic7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgNDI5OlxuICAgICAgICAgIGVycm9yVGV4dCA9IFwiWW91J3JlIGJlaW5nIHJhdGVsaW1pdGVkLlwiO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDUwMjpcbiAgICAgICAgICBlcnJvclRleHQgPSAnVGhlcmUgd2FzIG5vdCBhIGdhdGV3YXkgYXZhaWxhYmxlIHRvIHByb2Nlc3MgeW91ciBvcHRpb25zLiBXYWl0IGEgYml0IGFuZCByZXRyeS4nO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGVycm9yVGV4dCA9IHJlYXNvbi5zdGF0dXNUZXh0ID8/IHJlYXNvbi5lcnJvciA/PyAnVW5rbm93biBlcnJvcic7XG4gICAgICB9XG5cbiAgICAgIGVycm9yLm1lc3NhZ2UgPSBgWyR7cmVhc29uLnN0YXR1c31dICR7ZXJyb3JUZXh0fWA7XG5cbiAgICAgIC8vIElmIGRpc2NvcmQgc2VudCB1cyBKU09OLCBpdCBpcyBwcm9iYWJseSBnb2luZyB0byBiZSBhbiBlcnJvciBtZXNzYWdlIGZyb20gd2hpY2ggd2UgY2FuIGdldCBhbmQgYWRkIHNvbWUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGVycm9yIHRvIHRoZSBlcnJvciBtZXNzYWdlLCB0aGUgZnVsbCBib2R5IHdpbGwgYmUgaW4gdGhlIGVycm9yLmNhdXNlXG4gICAgICAvLyBodHRwczovL2RvY3MuZGlzY29yZC5jb20vZGV2ZWxvcGVycy9yZWZlcmVuY2UjZXJyb3ItbWVzc2FnZXNcbiAgICAgIGlmICh0eXBlb2YgcmVhc29uLmJvZHkgPT09ICdvYmplY3QnICYmIGhhc1Byb3BlcnR5KHJlYXNvbi5ib2R5LCAnY29kZScpICYmIGhhc1Byb3BlcnR5KHJlYXNvbi5ib2R5LCAnbWVzc2FnZScpKSB7XG4gICAgICAgIGVycm9yLm1lc3NhZ2UgKz0gYFxcbkRpc2NvcmQgZXJyb3I6IFske3JlYXNvbi5ib2R5LmNvZGV9XSAke3JlYXNvbi5ib2R5Lm1lc3NhZ2V9YDtcbiAgICAgIH1cblxuICAgICAgZXJyb3IuY2F1c2UgPSBPYmplY3QuYXNzaWduKE9iamVjdC5jcmVhdGUoYmFzZUVycm9yUHJvdG90eXBlKSwgcmVhc29uKTtcblxuICAgICAgcmV0dXJuIGVycm9yO1xuICAgIH0sXG5cbiAgICBwcm9jZXNzUmF0ZUxpbWl0ZWRQYXRocygpIHtcbiAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG5cbiAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIHJlc3QucmF0ZUxpbWl0ZWRQYXRocy5lbnRyaWVzKCkpIHtcbiAgICAgICAgLy8gICByZXN0LmRlYnVnKFxuICAgICAgICAvLyBgW1JFU1QgLSBwcm9jZXNzUmF0ZUxpbWl0ZWRQYXRoc10gUnVubmluZyBmb3Igb2YgbG9vcC4gJHtcbiAgICAgICAgLy8gICB2YWx1ZS5yZXNldFRpbWVzdGFtcCAtIG5vd1xuICAgICAgICAvLyB9YFxuICAgICAgICAvLyAgIClcbiAgICAgICAgLy8gSWYgdGhlIHRpbWUgaGFzIG5vdCByZWFjaGVkIGNhbmNlbFxuICAgICAgICBpZiAodmFsdWUucmVzZXRUaW1lc3RhbXAgPiBub3cpIGNvbnRpbnVlO1xuXG4gICAgICAgIC8vIFJhdGUgbGltaXQgaXMgb3ZlciwgZGVsZXRlIHRoZSByYXRlIGxpbWl0ZXJcbiAgICAgICAgcmVzdC5yYXRlTGltaXRlZFBhdGhzLmRlbGV0ZShrZXkpO1xuICAgICAgICAvLyBJZiBpdCB3YXMgZ2xvYmFsLCBhbHNvIG1hcmsgdGhlIGdsb2JhbCB2YWx1ZSBhcyBmYWxzZVxuICAgICAgICBpZiAoa2V5ID09PSAnZ2xvYmFsJykgcmVzdC5nbG9iYWxseVJhdGVMaW1pdGVkID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIC8vIEFMTCBQQVRIUyBBUkUgQ0xFQVJFRCBDQU4gQ0FOQ0VMIE9VVCFcbiAgICAgIGlmIChyZXN0LnJhdGVMaW1pdGVkUGF0aHMuc2l6ZSA9PT0gMCkge1xuICAgICAgICByZXN0LnByb2Nlc3NpbmdSYXRlTGltaXRlZFBhdGhzID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN0LnByb2Nlc3NpbmdSYXRlTGltaXRlZFBhdGhzID0gdHJ1ZTtcbiAgICAgICAgLy8gUkVDSEVDSyBJTiAxIFNFQ09ORFxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAvLyByZXN0LmRlYnVnKCdbUkVTVCAtIHByb2Nlc3NSYXRlTGltaXRlZFBhdGhzXSBSdW5uaW5nIHNldFRpbWVvdXQuJylcbiAgICAgICAgICByZXN0LnByb2Nlc3NSYXRlTGltaXRlZFBhdGhzKCk7XG4gICAgICAgIH0sIDEwMDApO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICAvKiogUHJvY2Vzc2VzIHRoZSByYXRlIGxpbWl0IGhlYWRlcnMgYW5kIGRldGVybWluZXMgaWYgaXQgbmVlZHMgdG8gYmUgcmF0ZSBsaW1pdGVkIGFuZCByZXR1cm5zIHRoZSBidWNrZXQgaWQgaWYgYXZhaWxhYmxlICovXG4gICAgcHJvY2Vzc0hlYWRlcnModXJsLCBoZWFkZXJzLCBpZGVudGlmaWVyKSB7XG4gICAgICBsZXQgcmF0ZUxpbWl0ZWQgPSBmYWxzZTtcblxuICAgICAgLy8gR0VUIEFMTCBORUNFU1NBUlkgSEVBREVSU1xuICAgICAgY29uc3QgcmVtYWluaW5nID0gaGVhZGVycy5nZXQoUkFURV9MSU1JVF9SRU1BSU5JTkdfSEVBREVSKTtcbiAgICAgIGNvbnN0IHJldHJ5QWZ0ZXIgPSBoZWFkZXJzLmdldCgnUmV0cnktQWZ0ZXInKSA/PyBoZWFkZXJzLmdldChSQVRFX0xJTUlUX1JFU0VUX0FGVEVSX0hFQURFUik7XG4gICAgICBjb25zdCByZXNldCA9IERhdGUubm93KCkgKyBOdW1iZXIocmV0cnlBZnRlcikgKiAxMDAwO1xuICAgICAgY29uc3QgZ2xvYmFsID0gaGVhZGVycy5nZXQoUkFURV9MSU1JVF9HTE9CQUxfSEVBREVSKTtcbiAgICAgIC8vIHVuZGVmaW5lZCBvdmVycmlkZSBudWxsIG5lZWRlZCBmb3IgdHlwaW5nc1xuICAgICAgY29uc3QgYnVja2V0SWQgPSBoZWFkZXJzLmdldChSQVRFX0xJTUlUX0JVQ0tFVF9IRUFERVIpID8/IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IGxpbWl0ID0gaGVhZGVycy5nZXQoUkFURV9MSU1JVF9MSU1JVF9IRUFERVIpO1xuXG4gICAgICAvLyBJZiB3ZSBkaWRuJ3QgcmVjZWl2ZWQgdGhlIGlkZW50aWZpZXIsIGZhbGxiYWNrIHRvIHRoZSBib3QgdG9rZW5cbiAgICAgIGlkZW50aWZpZXIgPz89IGBCb3QgJHtyZXN0LnRva2VufWA7XG5cbiAgICAgIHJlc3QucXVldWVzLmdldChgJHtpZGVudGlmaWVyfSR7dXJsfWApPy5oYW5kbGVDb21wbGV0ZWRSZXF1ZXN0KHtcbiAgICAgICAgcmVtYWluaW5nOiByZW1haW5pbmcgPyBOdW1iZXIocmVtYWluaW5nKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgaW50ZXJ2YWw6IHJldHJ5QWZ0ZXIgPyBOdW1iZXIocmV0cnlBZnRlcikgKiAxMDAwIDogdW5kZWZpbmVkLFxuICAgICAgICBtYXg6IGxpbWl0ID8gTnVtYmVyKGxpbWl0KSA6IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBJRiBUSEVSRSBJUyBOTyBSRU1BSU5JTkcgUkFURSBMSU1JVCwgTUFSSyBJVCBBUyBSQVRFIExJTUlURURcbiAgICAgIGlmIChyZW1haW5pbmcgPT09ICcwJykge1xuICAgICAgICByYXRlTGltaXRlZCA9IHRydWU7XG5cbiAgICAgICAgLy8gU0FWRSBUSEUgVVJMIEFTIExJTUlURUQsIElNUE9SVEFOVCBGT1IgTkVXIFJFUVVFU1RTIEJZIFVTRVIgV0lUSE9VVCBCVUNLRVRcbiAgICAgICAgcmVzdC5yYXRlTGltaXRlZFBhdGhzLnNldChgJHtpZGVudGlmaWVyfSR7dXJsfWAsIHtcbiAgICAgICAgICB1cmwsXG4gICAgICAgICAgcmVzZXRUaW1lc3RhbXA6IHJlc2V0LFxuICAgICAgICAgIGJ1Y2tldElkLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTQVZFIFRIRSBCVUNLRVQgQVMgTElNSVRFRCBTSU5DRSBESUZGRVJFTlQgVVJMUyBNQVkgU0hBUkUgQSBCVUNLRVRcbiAgICAgICAgaWYgKGJ1Y2tldElkKSB7XG4gICAgICAgICAgcmVzdC5yYXRlTGltaXRlZFBhdGhzLnNldChgJHtpZGVudGlmaWVyfSR7YnVja2V0SWR9YCwge1xuICAgICAgICAgICAgdXJsLFxuICAgICAgICAgICAgcmVzZXRUaW1lc3RhbXA6IHJlc2V0LFxuICAgICAgICAgICAgYnVja2V0SWQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gSUYgVEhFUkUgSVMgTk8gUkVNQUlOSU5HIEdMT0JBTCBMSU1JVCwgTUFSSyBJVCBSQVRFIExJTUlURUQgR0xPQkFMTFlcbiAgICAgIGlmIChnbG9iYWwpIHtcbiAgICAgICAgY29uc3QgcmV0cnlBZnRlciA9IE51bWJlcihoZWFkZXJzLmdldCgncmV0cnktYWZ0ZXInKSkgKiAxMDAwO1xuICAgICAgICBjb25zdCBnbG9iYWxSZXNldCA9IERhdGUubm93KCkgKyByZXRyeUFmdGVyO1xuICAgICAgICAvLyAgIHJlc3QuZGVidWcoXG4gICAgICAgIC8vIGBbUkVTVCA9IEdsb2JhbGx5IFJhdGUgTGltaXRlZF0gVVJMOiAke3VybH0gfCBHbG9iYWwgUmVzdDogJHtnbG9iYWxSZXNldH1gXG4gICAgICAgIC8vICAgKVxuICAgICAgICByZXN0Lmdsb2JhbGx5UmF0ZUxpbWl0ZWQgPSB0cnVlO1xuICAgICAgICByYXRlTGltaXRlZCA9IHRydWU7XG5cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgcmVzdC5nbG9iYWxseVJhdGVMaW1pdGVkID0gZmFsc2U7XG4gICAgICAgIH0sIHJldHJ5QWZ0ZXIpO1xuXG4gICAgICAgIHJlc3QucmF0ZUxpbWl0ZWRQYXRocy5zZXQoJ2dsb2JhbCcsIHtcbiAgICAgICAgICB1cmw6ICdnbG9iYWwnLFxuICAgICAgICAgIHJlc2V0VGltZXN0YW1wOiBnbG9iYWxSZXNldCxcbiAgICAgICAgICBidWNrZXRJZCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKGJ1Y2tldElkKSB7XG4gICAgICAgICAgcmVzdC5yYXRlTGltaXRlZFBhdGhzLnNldChpZGVudGlmaWVyLCB7XG4gICAgICAgICAgICB1cmw6ICdnbG9iYWwnLFxuICAgICAgICAgICAgcmVzZXRUaW1lc3RhbXA6IGdsb2JhbFJlc2V0LFxuICAgICAgICAgICAgYnVja2V0SWQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHJhdGVMaW1pdGVkICYmICFyZXN0LnByb2Nlc3NpbmdSYXRlTGltaXRlZFBhdGhzKSB7XG4gICAgICAgIHJlc3QucHJvY2Vzc1JhdGVMaW1pdGVkUGF0aHMoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByYXRlTGltaXRlZCA/IGJ1Y2tldElkIDogdW5kZWZpbmVkO1xuICAgIH0sXG5cbiAgICBhc3luYyBzZW5kUmVxdWVzdChvcHRpb25zKSB7XG4gICAgICBjb25zdCB1cmwgPSBgJHtyZXN0LmJhc2VVcmx9L3Yke3Jlc3QudmVyc2lvbn0ke29wdGlvbnMucm91dGV9YDtcbiAgICAgIGNvbnN0IHBheWxvYWQgPSByZXN0LmNyZWF0ZVJlcXVlc3RCb2R5KG9wdGlvbnMubWV0aG9kLCBvcHRpb25zLnJlcXVlc3RCb2R5T3B0aW9ucyk7XG5cbiAgICAgIC8vIFJldHJpZXMgYSByZXF1ZXN0IHRoYXQgd2FzIGFib3J0ZWQgYmVjYXVzZSBpdCBoaXQgYHJlc3QucmVxdWVzdFRpbWVvdXRgLCBvciByZWplY3RzIGl0IG9uY2UgdGhlIHJldHJ5XG4gICAgICAvLyBidWRnZXQgaXMgZXhoYXVzdGVkLiBUaGUgY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciB0aGUgYGludmFsaWRCdWNrZXRgL2V2ZW50IGJvb2trZWVwaW5nIGJlZm9yZWhhbmQuXG4gICAgICBjb25zdCBoYW5kbGVUaW1lb3V0ID0gYXN5bmMgKG9wdGlvbnM6IFNlbmRSZXF1ZXN0T3B0aW9ucywgZXJyb3I6IEVycm9yKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgIGlmIChvcHRpb25zLnJldHJ5Q291bnQgPj0gcmVzdC5tYXhSZXRyeUNvdW50KSB7XG4gICAgICAgICAgcmVzdC5sb2dnZXIuZGVidWcoYHJlcXVlc3QgdG8gJHt1cmx9IHRpbWVkIG91dCBhbmQgZXhjZWVkZWQgdGhlIG1heGltdW0gYWxsb3dlZCByZXRyaWVzLmApO1xuICAgICAgICAgIG9wdGlvbnMucmVqZWN0KHtcbiAgICAgICAgICAgIG9rOiBmYWxzZSxcbiAgICAgICAgICAgIHN0YXR1czogOTk5LFxuICAgICAgICAgICAgZXJyb3I6ICdUaGUgcmVxdWVzdCB0aW1lZCBvdXQgYW5kIGl0IG1heGVkIG91dCB0aGUgcmV0cmllcyBsaW1pdC4nLFxuICAgICAgICAgICAgZXJyb3JPYmplY3Q6IGVycm9yLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlc3QubG9nZ2VyLmRlYnVnKGByZXF1ZXN0IHRvICR7dXJsfSB0aW1lZCBvdXQgYWZ0ZXIgJHtyZXN0LnJlcXVlc3RUaW1lb3V0fW1zLCByZXRyeWluZy5gLCBlcnJvcik7XG4gICAgICAgIG9wdGlvbnMucmV0cnlDb3VudCArPSAxO1xuICAgICAgICBhd2FpdCBvcHRpb25zLnJldHJ5UmVxdWVzdD8uKG9wdGlvbnMpO1xuICAgICAgfTtcblxuICAgICAgY29uc3QgbG9nZ2luZ0hlYWRlcnMgPSB7IC4uLnBheWxvYWQuaGVhZGVycyB9O1xuXG4gICAgICBpZiAocGF5bG9hZC5oZWFkZXJzLmF1dGhvcml6YXRpb24pIHtcbiAgICAgICAgY29uc3QgYXV0aG9yaXphdGlvblNjaGVtZSA9IHBheWxvYWQuaGVhZGVycy5hdXRob3JpemF0aW9uPy5zcGxpdCgnICcpWzBdO1xuICAgICAgICBsb2dnaW5nSGVhZGVycy5hdXRob3JpemF0aW9uID0gYCR7YXV0aG9yaXphdGlvblNjaGVtZX0gdG9rZW5oZXJlYDtcbiAgICAgIH1cblxuICAgICAgLy8gR2l2ZSB0aGlzIGF0dGVtcHQgYSBoYXJkIGRlYWRsaW5lLiBgQWJvcnRTaWduYWwudGltZW91dGAgYWJvcnRzIHRoZSBmZXRjaCAoYW5kIGFueSBpbi1wcm9ncmVzcyBib2R5XG4gICAgICAvLyByZWFkKSBvbmNlIGl0IGZpcmVzLCB3aGljaCBtYWtlcyB0aGUgYXdhaXRlZCBmZXRjaCByZWplY3Qgc28gYSBzdGFsbGVkIGNvbm5lY3Rpb24gY2FuIG5ldmVyIGtlZXAgdGhpc1xuICAgICAgLy8gcXVldWUncyBgcHJvY2Vzc1BlbmRpbmdgIGxvb3AgKGFuZCB0aGVyZWZvcmUgdGhlIHdob2xlIHF1ZXVlKSB3ZWRnZWQgZm9yZXZlci4gT21pdHRlZCB3aGVuIGRpc2FibGVkLlxuICAgICAgLy8gVGhlIGNhbGxlcidzIHNpZ25hbCBpcyBoYW5kZWQgdG8gZmV0Y2ggdG9vOiBmZXRjaCByZWZ1c2VzIHRvIHNlbmQgYSByZXF1ZXN0IHdob3NlIHNpZ25hbCBpcyBhbHJlYWR5IGFib3J0ZWQsIHNvIGEgcXVldWUgZW50cnkgdGhhdCBnb3RcbiAgICAgIC8vIGFib3J0ZWQgd2hpbGUgd2FpdGluZyBuZXZlciBnb2VzIG91dCwgYW5kIGFib3J0aW5nIG1pZC1yZXF1ZXN0IHRlYXJzIGRvd24gdGhlIGNvbm5lY3Rpb24uXG4gICAgICBjb25zdCBzaWduYWxzOiBBYm9ydFNpZ25hbFtdID0gW107XG4gICAgICBpZiAob3B0aW9ucy5yZXF1ZXN0Qm9keU9wdGlvbnM/LnNpZ25hbCkgc2lnbmFscy5wdXNoKG9wdGlvbnMucmVxdWVzdEJvZHlPcHRpb25zLnNpZ25hbCk7XG4gICAgICBpZiAocmVzdC5yZXF1ZXN0VGltZW91dCA+IDApIHNpZ25hbHMucHVzaChBYm9ydFNpZ25hbC50aW1lb3V0KHJlc3QucmVxdWVzdFRpbWVvdXQpKTtcblxuICAgICAgY29uc3QgcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KHVybCwgeyAuLi5wYXlsb2FkLCBzaWduYWw6IHNpZ25hbHMubGVuZ3RoID4gMCA/IEFib3J0U2lnbmFsLmFueShzaWduYWxzKSA6IHVuZGVmaW5lZCB9KTtcbiAgICAgIHJlc3QuZXZlbnRzLnJlcXVlc3QocmVxdWVzdCwge1xuICAgICAgICBib2R5OiBvcHRpb25zLnJlcXVlc3RCb2R5T3B0aW9ucz8uYm9keSxcbiAgICAgIH0pO1xuXG4gICAgICByZXN0LmxvZ2dlci5kZWJ1Zyhgc2VuZGluZyByZXF1ZXN0IHRvICR7dXJsfWAsICd3aXRoIHBheWxvYWQ6JywgeyAuLi5wYXlsb2FkLCBoZWFkZXJzOiBsb2dnaW5nSGVhZGVycyB9KTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2gocmVxdWVzdCkuY2F0Y2goYXN5bmMgKGVycm9yKSA9PiB7XG4gICAgICAgIHJlc3QuZXZlbnRzLnJlcXVlc3RFcnJvcihyZXF1ZXN0LCBlcnJvciwgeyBib2R5OiBvcHRpb25zLnJlcXVlc3RCb2R5T3B0aW9ucz8uYm9keSB9KTtcbiAgICAgICAgLy8gTWFyayByZXF1ZXN0IGFzIGNvbXBsZXRlZFxuICAgICAgICByZXN0LmludmFsaWRCdWNrZXQuaGFuZGxlQ29tcGxldGVkUmVxdWVzdCg5OTksIGZhbHNlKTtcblxuICAgICAgICAvLyBUaGUgY2FsbGVyIGFib3J0ZWQgdGhlIHJlcXVlc3QsIG5ldmVyIHJlLXNlbmQgaXQsIERpc2NvcmQgbWF5IGhhdmUgcmVjZWl2ZWQgaXQgYWxyZWFkeS4gVGhlIGNhbGxlciB3YXMgcmVqZWN0ZWQgdGhlIG1vbWVudCB0aGUgc2lnbmFsIGZpcmVkLlxuICAgICAgICBpZiAob3B0aW9ucy5yZXF1ZXN0Qm9keU9wdGlvbnM/LnNpZ25hbD8uYWJvcnRlZCkge1xuICAgICAgICAgIG9wdGlvbnMucmVqZWN0KHtcbiAgICAgICAgICAgIG9rOiBmYWxzZSxcbiAgICAgICAgICAgIHN0YXR1czogOTk5LFxuICAgICAgICAgICAgZXJyb3I6ICdUaGUgcmVxdWVzdCB3YXMgYWJvcnRlZC4nLFxuICAgICAgICAgICAgZXJyb3JPYmplY3Q6IGVycm9yLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoZSBhdHRlbXB0IGhpdCBgcmVzdC5yZXF1ZXN0VGltZW91dGAgYW5kIHdhcyBhYm9ydGVkLiBUcmVhdCBpdCBsaWtlIGEgdHJhbnNpZW50IGZhaWx1cmUgYW5kIHJldHJ5XG4gICAgICAgIC8vIGl0IHRocm91Z2ggdGhlIHF1ZXVlLCBzbyBhIHNpbmdsZSBzdGFsbGVkIGNvbm5lY3Rpb24gZG9lc24ndCBwZXJtYW5lbnRseSBmYWlsIHRoZSByZXF1ZXN0LlxuICAgICAgICBpZiAoaXNUaW1lb3V0RXJyb3IoZXJyb3IpKSByZXR1cm4gYXdhaXQgaGFuZGxlVGltZW91dChvcHRpb25zLCBlcnJvcik7XG5cbiAgICAgICAgcmVzdC5sb2dnZXIuZGVidWcoYHJlcXVlc3QgZmV0Y2ggdG8gJHt1cmx9IGZhaWxlZC5gLCBlcnJvcik7XG4gICAgICAgIG9wdGlvbnMucmVqZWN0KHtcbiAgICAgICAgICBvazogZmFsc2UsXG4gICAgICAgICAgc3RhdHVzOiA5OTksXG4gICAgICAgICAgZXJyb3I6ICdQb3NzaWJsZSBuZXR3b3JrIG9yIHJlcXVlc3Qgc2hhcGUgaXNzdWUgb2NjdXJyZWQuIElmIHRoaXMgaXMgcmFyZSwgaXRzIGEgbmV0d29yayBnbGl0Y2guIElmIGl0IG9jY3VycyBhIGxvdCBzb21ldGhpbmcgaXMgd3JvbmcuJyxcbiAgICAgICAgICBlcnJvck9iamVjdDogZXJyb3IsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIElmIHJlc3BvbnNlIGlzIHVuZGVmaW5lZCwgdGhlIGVycm9yIGhhcyBiZWVuIGhhbmRsZWQgaW4gdGhlIGNhdGNoIGJsb2NrIGFib3ZlXG4gICAgICBpZiAoIXJlc3BvbnNlKSByZXR1cm47XG5cbiAgICAgIHJlc3QubG9nZ2VyLmRlYnVnKGByZXF1ZXN0IGZldGNoZWQgZnJvbSAke3VybH0gd2l0aCBzdGF0dXMgJHtyZXNwb25zZS5zdGF0dXN9ICYgJHtyZXNwb25zZS5zdGF0dXNUZXh0fWApO1xuXG4gICAgICAvLyBTb21ldGltZXMgdGhlIENvbnRlbnQtVHlwZSBtYXkgYmUgXCJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04XCIsIGZvciB0aGlzIHJlYXNvbiwgd2UgbmVlZCB0byBjaGVjayB0aGUgc3RhcnQgb2YgdGhlIGhlYWRlclxuICAgICAgY29uc3QgYm9keSA9IGF3YWl0IChyZXNwb25zZS5oZWFkZXJzLmdldCgnQ29udGVudC1UeXBlJyk/LnN0YXJ0c1dpdGgoJ2FwcGxpY2F0aW9uL2pzb24nKSA/IHJlc3BvbnNlLmpzb24oKSA6IHJlc3BvbnNlLnRleHQoKSkuY2F0Y2goKCkgPT4gbnVsbCk7XG5cbiAgICAgIHJlc3QuZXZlbnRzLnJlc3BvbnNlKHJlcXVlc3QsIHJlc3BvbnNlLCB7XG4gICAgICAgIHJlcXVlc3RCb2R5OiBvcHRpb25zLnJlcXVlc3RCb2R5T3B0aW9ucz8uYm9keSxcbiAgICAgICAgcmVzcG9uc2VCb2R5OiBib2R5LFxuICAgICAgfSk7XG5cbiAgICAgIC8vIE1hcmsgcmVxdWVzdCBhcyBjb21wbGV0ZWRcbiAgICAgIHJlc3QuaW52YWxpZEJ1Y2tldC5oYW5kbGVDb21wbGV0ZWRSZXF1ZXN0KHJlc3BvbnNlLnN0YXR1cywgcmVzcG9uc2UuaGVhZGVycy5nZXQoUkFURV9MSU1JVF9TQ09QRV9IRUFERVIpID09PSAnc2hhcmVkJyk7XG5cbiAgICAgIC8vIFNldCB0aGUgYnVja2V0IGlkIGlmIGl0IHdhcyBhdmFpbGFibGUgb24gdGhlIGhlYWRlcnNcbiAgICAgIGNvbnN0IGJ1Y2tldElkID0gcmVzdC5wcm9jZXNzSGVhZGVycyhyZXN0LnNpbXBsaWZ5VXJsKG9wdGlvbnMucm91dGUsIG9wdGlvbnMubWV0aG9kKSwgcmVzcG9uc2UuaGVhZGVycywgcGF5bG9hZC5oZWFkZXJzLmF1dGhvcml6YXRpb24pO1xuXG4gICAgICBpZiAoYnVja2V0SWQpIG9wdGlvbnMuYnVja2V0SWQgPSBidWNrZXRJZDtcblxuICAgICAgaWYgKHJlc3BvbnNlLnN0YXR1cyA8IEh0dHBSZXNwb25zZUNvZGUuU3VjY2VzcyB8fCByZXNwb25zZS5zdGF0dXMgPj0gSHR0cFJlc3BvbnNlQ29kZS5FcnJvcikge1xuICAgICAgICByZXN0LmxvZ2dlci5kZWJ1ZyhgUmVxdWVzdCB0byAke3VybH0gZmFpbGVkLmApO1xuXG4gICAgICAgIGlmIChyZXNwb25zZS5zdGF0dXMgIT09IEh0dHBSZXNwb25zZUNvZGUuVG9vTWFueVJlcXVlc3RzKSB7XG4gICAgICAgICAgb3B0aW9ucy5yZWplY3QoeyBvazogZmFsc2UsIHN0YXR1czogcmVzcG9uc2Uuc3RhdHVzLCBzdGF0dXNUZXh0OiByZXNwb25zZS5zdGF0dXNUZXh0LCBib2R5IH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlc3QubG9nZ2VyLmRlYnVnKGBSZXF1ZXN0IHRvICR7dXJsfSB3YXMgcmF0ZWxpbWl0ZWQuYCk7XG4gICAgICAgIC8vIFRvbyBtYW55IGF0dGVtcHRzLCBnZXQgcmlkIG9mIHJlcXVlc3QgZnJvbSBxdWV1ZS5cbiAgICAgICAgaWYgKG9wdGlvbnMucmV0cnlDb3VudCA+PSByZXN0Lm1heFJldHJ5Q291bnQpIHtcbiAgICAgICAgICByZXN0LmxvZ2dlci5kZWJ1ZyhgUmVxdWVzdCB0byAke3VybH0gZXhjZWVkZWQgdGhlIG1heGltdW0gYWxsb3dlZCByZXRyaWVzLmAsICd3aXRoIHBheWxvYWQ6JywgcGF5bG9hZCk7XG4gICAgICAgICAgLy8gcmVzdC5kZWJ1ZyhgW1JFU1QgLSBSZXRyaWVzTWF4ZWRdICR7SlNPTi5zdHJpbmdpZnkob3B0aW9ucyl9YClcbiAgICAgICAgICBvcHRpb25zLnJlamVjdCh7XG4gICAgICAgICAgICBvazogZmFsc2UsXG4gICAgICAgICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgICAgICAgIHN0YXR1c1RleHQ6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICAgICAgICBlcnJvcjogJ1RoZSByZXF1ZXN0IHdhcyByYXRlIGxpbWl0ZWQgYW5kIGl0IG1heGVkIG91dCB0aGUgcmV0cmllcyBsaW1pdC4nLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgb3B0aW9ucy5yZXRyeUNvdW50ICs9IDE7XG5cbiAgICAgICAgY29uc3QgcmVzZXRBZnRlciA9IHJlc3BvbnNlLmhlYWRlcnMuZ2V0KCdyZXRyeS1hZnRlcicpO1xuICAgICAgICBpZiAocmVzZXRBZnRlcikgYXdhaXQgZGVsYXkoTnVtYmVyKHJlc2V0QWZ0ZXIpICogMTAwMCk7XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IG9wdGlvbnMucmV0cnlSZXF1ZXN0Py4ob3B0aW9ucyk7XG4gICAgICB9XG5cbiAgICAgIC8vIERpc2NvcmQgc29tZXRpbWVzIHNlbmRzIGEgcmVzcG9uc2Ugd2l0aCBubyBjb250ZW50XG4gICAgICBvcHRpb25zLnJlc29sdmUoeyBvazogdHJ1ZSwgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMsIGJvZHk6IHJlc3BvbnNlLnN0YXR1cyA9PT0gSHR0cFJlc3BvbnNlQ29kZS5Ob0NvbnRlbnQgPyB1bmRlZmluZWQgOiBib2R5IH0pO1xuICAgIH0sXG5cbiAgICBzaW1wbGlmeVVybCh1cmwsIG1ldGhvZCkge1xuICAgICAgY29uc3Qgcm91dGVJbmZvcm1hdGlvbktleTogc3RyaW5nW10gPSBbbWV0aG9kXTtcblxuICAgICAgY29uc3QgcXVlcnlQYXJhbUluZGV4ID0gdXJsLmluZGV4T2YoJz8nKTtcbiAgICAgIGNvbnN0IHJvdXRlID0gcXVlcnlQYXJhbUluZGV4ICE9PSAtMSA/IHVybC5zbGljZSgwLCBxdWVyeVBhcmFtSW5kZXgpIDogdXJsO1xuXG4gICAgICAvLyBTaW5jZSB0aGUgdXJscyBzdGFydCB3aXRoIC8gdGhlIGZpcnN0IHBhcnQgd2lsbCBhbHdheXMgYmUgZW1wdHlcbiAgICAgIGNvbnN0IHNwbGl0dGVkUm91dGUgPSByb3V0ZS5zcGxpdCgnLycpO1xuXG4gICAgICAvLyAxKSBTdHJpcCB0aGUgbWlub3IgcGFyYW1zXG4gICAgICAvLyAgICBUaGUgb25seSBtYWpvcnMgYXJlIGNoYW5uZWxzLCBndWlsZHMsIHdlYmhvb2tzIGFuZCB3ZWJob29rcyB3aXRoIHRoZWlyIHRva2VuXG5cbiAgICAgIGNvbnN0IHN0cmlwcGVkUm91dGUgPSBzcGxpdHRlZFJvdXRlXG4gICAgICAgIC5tYXAoKHBhcnQsIGluZGV4LCBhcnJheSkgPT4ge1xuICAgICAgICAgIC8vIFdoaWxlIHBhcnNlSW50IHdpbGwgdHJ1bmNhdGUgdGhlIHNub3dmbGFrZSBpZCwgaXQgd2lsbCBzdGlsbCB0ZWxsIHVzIGlmIGl0IGlzIGEgbnVtYmVyXG4gICAgICAgICAgY29uc3QgaXNOdW1iZXIgPSBOdW1iZXIuaXNGaW5pdGUocGFyc2VJbnQocGFydCwgMTApKTtcblxuICAgICAgICAgIGlmICghaXNOdW1iZXIpIHtcbiAgICAgICAgICAgIC8vIFJlYWN0aW9ucyBlbW9qaSBuZWVkIHRvIGJlIHN0cmlwcGVkIGFzIGl0IGlzIGEgbWlub3IgcGFyYW1ldGVyXG4gICAgICAgICAgICBpZiAoaW5kZXggPj0gMSAmJiBhcnJheVtpbmRleCAtIDFdID09PSAncmVhY3Rpb25zJykgcmV0dXJuICd4JztcbiAgICAgICAgICAgIC8vIElmIHdlIGFyZSBvbiBhIHdlYmhvb2sgb3IgaWYgaXQgaXMgcGFydCBvZiB0aGUgcm91dGUsIGtlZXAgaXQgYXMgaXQgaXMgYSBtYWpvciBwYXJhbWV0ZXJcbiAgICAgICAgICAgIHJldHVybiBwYXJ0O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIENoZWNrIGlmIHdlIGFyZSBvbiBhIGNoYW5uZWwgaWQsIGEgZ3VpbGQgaWQgb3IgYSB3ZWJob29rIGlkXG4gICAgICAgICAgY29uc3QgaXNNYWpvciA9IGluZGV4ID49IDEgJiYgKGFycmF5W2luZGV4IC0gMV0gPT09ICdjaGFubmVscycgfHwgYXJyYXlbaW5kZXggLSAxXSA9PT0gJ2d1aWxkcycgfHwgYXJyYXlbaW5kZXggLSAxXSA9PT0gJ3dlYmhvb2tzJyk7XG5cbiAgICAgICAgICBpZiAoaXNNYWpvcikgcmV0dXJuIHBhcnQ7XG5cbiAgICAgICAgICByZXR1cm4gJ3gnO1xuICAgICAgICB9KVxuICAgICAgICAuam9pbignLycpO1xuXG4gICAgICByb3V0ZUluZm9ybWF0aW9uS2V5LnB1c2goc3RyaXBwZWRSb3V0ZSk7XG5cbiAgICAgIC8vIDIpIEFjY291bnQgZm9yIGV4Y2VwdGlvbnNcbiAgICAgIC8vICAgIC0gaHR0cHM6Ly9naXRodWIuY29tL2Rpc2NvcmQvZGlzY29yZC1hcGktZG9jcy9pc3N1ZXMvMTA5MlxuICAgICAgLy8gICAgLSBodHRwczovL2dpdGh1Yi5jb20vZGlzY29yZC9kaXNjb3JkLWFwaS1kb2NzL2lzc3Vlcy8xMjk1XG5cbiAgICAgIC8vIFRoZSAyIGV4Y2VwdGlvbnMgYXJlIGZvciBtZXNzYWdlIGRlbGV0ZSwgc28gd2UgbmVlZCB0byBjaGVjayBpZiB3ZSBhcmUgaW4gdGhhdCByb3V0ZVxuICAgICAgaWYgKG1ldGhvZCA9PT0gJ0RFTEVURScgJiYgc3BsaXR0ZWRSb3V0ZS5sZW5ndGggPT09IDUgJiYgc3BsaXR0ZWRSb3V0ZVsxXSA9PT0gJ2NoYW5uZWxzJyAmJiBzdHJpcHBlZFJvdXRlLmVuZHNXaXRoKCcvbWVzc2FnZXMveCcpKSB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2VJZCA9IHNwbGl0dGVkUm91dGVbNF07XG4gICAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IHNub3dmbGFrZVRvVGltZXN0YW1wKG1lc3NhZ2VJZCk7XG4gICAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2Rpc2NvcmQvZGlzY29yZC1hcGktZG9jcy9pc3N1ZXMvMTA5MlxuICAgICAgICBpZiAobm93IC0gdGltZXN0YW1wIDwgMTBfMDAwKSB7XG4gICAgICAgICAgcm91dGVJbmZvcm1hdGlvbktleS5wdXNoKCdtZXNzYWdlLWRlbGV0ZS0xMHMnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9kaXNjb3JkL2Rpc2NvcmQtYXBpLWRvY3MvaXNzdWVzLzEyOTVcbiAgICAgICAgLy8gMiB3ZWVrcyA9IDIgKiA3ICogMjQgKiA2MCAqIDYwICogMTAwMCA9IDEyMDk2MDAwMDBcbiAgICAgICAgaWYgKG5vdyAtIHRpbWVzdGFtcCA+IDEyMDk2MDAwMDApIHtcbiAgICAgICAgICByb3V0ZUluZm9ybWF0aW9uS2V5LnB1c2goJ21lc3NhZ2UtZGVsZXRlLTJ3Jyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJvdXRlSW5mb3JtYXRpb25LZXkuam9pbignOicpO1xuICAgIH0sXG5cbiAgICBhc3luYyBwcm9jZXNzUmVxdWVzdChyZXF1ZXN0OiBTZW5kUmVxdWVzdE9wdGlvbnMpIHtcbiAgICAgIGNvbnN0IHVybCA9IHJlc3Quc2ltcGxpZnlVcmwocmVxdWVzdC5yb3V0ZSwgcmVxdWVzdC5tZXRob2QpO1xuXG4gICAgICBpZiAocmVxdWVzdC5ydW5UaHJvdWdoUXVldWUgPT09IGZhbHNlKSB7XG4gICAgICAgIGF3YWl0IHJlc3Quc2VuZFJlcXVlc3QocmVxdWVzdCk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiB0aGUgcmVxdWVzdCBoYXMgYSB0b2tlbiwgdXNlIGl0XG4gICAgICAvLyBFbHNlIGZhbGxiYWNrIHRvIHByZWZpeCB3aXRoIHRoZSBib3QgdG9rZW5cbiAgICAgIGNvbnN0IHF1ZXVlSWRlbnRpZmllciA9IHJlcXVlc3QucmVxdWVzdEJvZHlPcHRpb25zPy5oZWFkZXJzPy5hdXRob3JpemF0aW9uID8/IGBCb3QgJHtyZXN0LnRva2VufWA7XG5cbiAgICAgIGNvbnN0IHF1ZXVlID0gcmVzdC5xdWV1ZXMuZ2V0KGAke3F1ZXVlSWRlbnRpZmllcn0ke3VybH1gKTtcblxuICAgICAgaWYgKHF1ZXVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcXVldWUubWFrZVJlcXVlc3QocmVxdWVzdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDUkVBVEVTIEEgTkVXIFFVRVVFXG4gICAgICAgIGNvbnN0IGJ1Y2tldFF1ZXVlID0gbmV3IFF1ZXVlKHJlc3QsIHsgdXJsLCBkZWxldGVRdWV1ZURlbGF5OiByZXN0LmRlbGV0ZVF1ZXVlRGVsYXksIGlkZW50aWZpZXI6IHF1ZXVlSWRlbnRpZmllciB9KTtcblxuICAgICAgICAvLyBTYXZlIHF1ZXVlXG4gICAgICAgIHJlc3QucXVldWVzLnNldChgJHtxdWV1ZUlkZW50aWZpZXJ9JHt1cmx9YCwgYnVja2V0UXVldWUpO1xuXG4gICAgICAgIC8vIEFkZCByZXF1ZXN0IHRvIHF1ZXVlXG4gICAgICAgIGJ1Y2tldFF1ZXVlLm1ha2VSZXF1ZXN0KHJlcXVlc3QpO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICBhc3luYyBtYWtlUmVxdWVzdChtZXRob2QsIHJvdXRlLCBvcHRpb25zKSB7XG4gICAgICAvLyBUaGlzIGVycm9yIG5lZWRzIHRvIGJlIGNyZWF0ZWQgaGVyZSBiZWNhdXNlIG9mIGhvdyBzdGFjayB0cmFjZXMgZ2V0IGNhbGN1bGF0ZWRcbiAgICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCk7XG5cbiAgICAgIGlmIChyZXN0LmlzUHJveGllZCkge1xuICAgICAgICBpZiAocmVzdC5hdXRob3JpemF0aW9uKSB7XG4gICAgICAgICAgb3B0aW9ucyA/Pz0ge307XG4gICAgICAgICAgb3B0aW9ucy5oZWFkZXJzID8/PSB7fTtcbiAgICAgICAgICBvcHRpb25zLmhlYWRlcnNbcmVzdC5hdXRob3JpemF0aW9uSGVhZGVyXSA9IHJlc3QuYXV0aG9yaXphdGlvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHVybCA9IGAke3Jlc3QuYmFzZVVybH0vdiR7cmVzdC52ZXJzaW9ufSR7cm91dGV9YDtcblxuICAgICAgICAvLyBBbiBhdHRlbXB0IHRoYXQgZmFpbGVkIHdpdGhvdXQgYSByZXNwb25zZSBpcyBub3QgcmUtc2VudCBieSBkZWZhdWx0LiBXaGF0ZXZlciBpdCBmYWlsZWQgb24sIHRoZSBwcm94eSBtYXkgYWxyZWFkeSBoYXZlIHRoZSByZXF1ZXN0XG4gICAgICAgIC8vIChhIHRpbWVvdXQgb25seSBhYm9ydHMgb3VyIHNpZGUgb2YgdGhlIGNvbm5lY3Rpb24sIGFuZCBhIHNvY2tldCB0aGF0IGRpZXMgb25jZSB0aGUgcmVxdWVzdCBpcyBvbiB0aGUgd2lyZSBtYXkgc3RpbGwgaGF2ZSBkZWxpdmVyZWRcbiAgICAgICAgLy8gaXQpLCBzbyByZS1zZW5kaW5nIGl0IHdvdWxkIGV4ZWN1dGUgbm9uLWlkZW1wb3RlbnQgcmVxdWVzdHMgdHdpY2UuIGBmZXRjaGAgZ2l2ZXMgbm8gd2F5IHRvIHRlbGwgdGhlIHR3byBhcGFydCwgc28gdGhlIGNhbGxlciBpcyB0aGVcbiAgICAgICAgLy8gb25lIHdobyBkZWNpZGVzOiBgcHJveHkucmV0cnlSZXF1ZXN0c2Agc2F5cyByZS1zZW5kaW5nIGFnYWluc3QgdGhpcyBwcm94eSBpcyBzYWZlLiBSZXRyeWluZyB0b3dhcmRzIERpc2NvcmQgaXMgdGhlIHByb3h5J3Mgam9iLCBpdFxuICAgICAgICAvLyBpcyB0aGUgb25lIHRhbGtpbmcgdG8gRGlzY29yZC5cbiAgICAgICAgbGV0IHJldHJ5Q291bnQgPSAwO1xuXG4gICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICAvLyBUaGUgcmVxdWVzdCBtYXkgaGF2ZSBiZWVuIGFib3J0ZWQgd2hpbGUgdGhlIHByZXZpb3VzIGF0dGVtcHQgd2FzIHRpbWluZyBvdXQsIG5ldmVyIHNlbmQgaXQgaW4gdGhhdCBjYXNlLlxuICAgICAgICAgIGlmIChvcHRpb25zPy5zaWduYWw/LmFib3J0ZWQpIHtcbiAgICAgICAgICAgIHRocm93IHJlc3QuY3JlYXRlUmVxdWVzdEVycm9yKGVycm9yLCB7IG9rOiBmYWxzZSwgc3RhdHVzOiA5OTksIGVycm9yOiAnVGhlIHJlcXVlc3Qgd2FzIGFib3J0ZWQuJywgZXJyb3JPYmplY3Q6IG9wdGlvbnMuc2lnbmFsLnJlYXNvbiB9KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBHaXZlIHRoZSBhdHRlbXB0IGEgZGVhZGxpbmUgKG9taXR0ZWQgd2hlbiBkaXNhYmxlZCkgc28gYSBzdGFsbGVkIGNvbm5lY3Rpb24gY2FuJ3QgaGFuZyB0aGUgY2FsbGVyIGZvcmV2ZXIsIGFuZCBoYW5kIHRoZSBjYWxsZXInc1xuICAgICAgICAgIC8vIHNpZ25hbCB0byBmZXRjaCBzbyBhYm9ydGluZyB0ZWFycyBkb3duIGEgcmVxdWVzdCB0aGF0IGlzIGFscmVhZHkgb24gdGhlIHdpcmUuXG4gICAgICAgICAgY29uc3Qgc2lnbmFsczogQWJvcnRTaWduYWxbXSA9IFtdO1xuICAgICAgICAgIGlmIChvcHRpb25zPy5zaWduYWwpIHNpZ25hbHMucHVzaChvcHRpb25zLnNpZ25hbCk7XG4gICAgICAgICAgaWYgKHJlc3QucmVxdWVzdFRpbWVvdXQgPiAwKSBzaWduYWxzLnB1c2goQWJvcnRTaWduYWwudGltZW91dChyZXN0LnJlcXVlc3RUaW1lb3V0KSk7XG5cbiAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gbmV3IFJlcXVlc3QodXJsLCB7XG4gICAgICAgICAgICAuLi5yZXN0LmNyZWF0ZVJlcXVlc3RCb2R5KG1ldGhvZCwgb3B0aW9ucyksXG4gICAgICAgICAgICBzaWduYWw6IHNpZ25hbHMubGVuZ3RoID4gMCA/IEFib3J0U2lnbmFsLmFueShzaWduYWxzKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXN0LmV2ZW50cy5yZXF1ZXN0KHJlcXVlc3QsIHtcbiAgICAgICAgICAgIGJvZHk6IG9wdGlvbnM/LmJvZHksXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmZXRjaChyZXF1ZXN0KS5jYXRjaChhc3luYyAoZmV0Y2hFcnJvcikgPT4ge1xuICAgICAgICAgICAgcmVzdC5ldmVudHMucmVxdWVzdEVycm9yKHJlcXVlc3QsIGZldGNoRXJyb3IsIHsgYm9keTogb3B0aW9ucz8uYm9keSB9KTtcblxuICAgICAgICAgICAgLy8gVGhlIGNhbGxlciBhYm9ydGVkIHRoZSByZXF1ZXN0LCBuZXZlciByZS1zZW5kIGl0LCB0aGUgcHJveHkgbWF5IGhhdmUgcmVjZWl2ZWQgaXQgYWxyZWFkeS5cbiAgICAgICAgICAgIGlmIChvcHRpb25zPy5zaWduYWw/LmFib3J0ZWQpIHtcbiAgICAgICAgICAgICAgdGhyb3cgcmVzdC5jcmVhdGVSZXF1ZXN0RXJyb3IoZXJyb3IsIHsgb2s6IGZhbHNlLCBzdGF0dXM6IDk5OSwgZXJyb3I6ICdUaGUgcmVxdWVzdCB3YXMgYWJvcnRlZC4nLCBlcnJvck9iamVjdDogZmV0Y2hFcnJvciB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdGltZWRPdXQgPSBpc1RpbWVvdXRFcnJvcihmZXRjaEVycm9yKTtcblxuICAgICAgICAgICAgaWYgKHJlc3QucmV0cnlQcm94aWVkUmVxdWVzdHMgJiYgcmV0cnlDb3VudCA8IHJlc3QubWF4UmV0cnlDb3VudCAmJiByZXRyeUNvdW50IDwgcmVzdC5tYXhQcm94eVJldHJ5Q291bnQpIHtcbiAgICAgICAgICAgICAgcmV0cnlDb3VudCsrO1xuICAgICAgICAgICAgICByZXN0LmxvZ2dlci5kZWJ1ZyhgcmVxdWVzdCB0byBwcm94eSAke3VybH0gZmFpbGVkIHdpdGhvdXQgYSByZXNwb25zZSwgcmV0cnlpbmcuYCwgZmV0Y2hFcnJvcik7XG4gICAgICAgICAgICAgIC8vIFdhaXQgYSBsaXR0bGUgbG9uZ2VyIGJlZm9yZSBlYWNoIGZ1cnRoZXIgYXR0ZW1wdCBzbyBhIHByb3h5IHRoYXQgaXMgZG93biBpc24ndCBoYW1tZXJlZCBpbiBhIHRpZ2h0IGxvb3AsIHdoaWxlIHN0YXlpbmdcbiAgICAgICAgICAgICAgLy8gZnJlcXVlbnQgZW5vdWdoIHRvIG5vdGljZSBpdCBjb21pbmcgYmFjay4gQSB0aW1lZCBvdXQgYXR0ZW1wdCBhbHJlYWR5IHNhdCBvdXQgYHJlcXVlc3RUaW1lb3V0YCwgc28gaXQgZ29lcyBhZ2FpbiByaWdodCBhd2F5LlxuICAgICAgICAgICAgICBpZiAoIXRpbWVkT3V0KSBhd2FpdCBkZWxheShyZXN0LnByb3h5UmV0cnlEZWxheVN0ZXAgKiByZXRyeUNvdW50KTtcbiAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRpbWVkT3V0KSB7XG4gICAgICAgICAgICAgIHJlc3QubG9nZ2VyLmRlYnVnKGByZXF1ZXN0IHRvIHByb3h5ICR7dXJsfSB0aW1lZCBvdXQgYWZ0ZXIgJHtyZXN0LnJlcXVlc3RUaW1lb3V0fW1zLmApO1xuICAgICAgICAgICAgICB0aHJvdyByZXN0LmNyZWF0ZVJlcXVlc3RFcnJvcihlcnJvciwge1xuICAgICAgICAgICAgICAgIG9rOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzdGF0dXM6IDk5OSxcbiAgICAgICAgICAgICAgICBlcnJvcjogJ1RoZSByZXF1ZXN0IHRpbWVkIG91dCBhbmQgaXQgbWF4ZWQgb3V0IHRoZSByZXRyaWVzIGxpbWl0LicsXG4gICAgICAgICAgICAgICAgZXJyb3JPYmplY3Q6IGZldGNoRXJyb3IsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXN0LmxvZ2dlci5kZWJ1ZyhgcmVxdWVzdCBmZXRjaCB0byBwcm94eSAke3VybH0gZmFpbGVkLmAsIGZldGNoRXJyb3IpO1xuICAgICAgICAgICAgdGhyb3cgcmVzdC5jcmVhdGVSZXF1ZXN0RXJyb3IoZXJyb3IsIHtcbiAgICAgICAgICAgICAgb2s6IGZhbHNlLFxuICAgICAgICAgICAgICBzdGF0dXM6IDk5OSxcbiAgICAgICAgICAgICAgZXJyb3I6XG4gICAgICAgICAgICAgICAgJ1Bvc3NpYmxlIG5ldHdvcmsgb3IgcmVxdWVzdCBzaGFwZSBpc3N1ZSBvY2N1cnJlZC4gSWYgdGhpcyBpcyByYXJlLCBpdHMgYSBuZXR3b3JrIGdsaXRjaC4gSWYgaXQgb2NjdXJzIGEgbG90IHNvbWV0aGluZyBpcyB3cm9uZy4nLFxuICAgICAgICAgICAgICBlcnJvck9iamVjdDogZmV0Y2hFcnJvcixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8gSWYgcmVzdWx0IGlzIHVuZGVmaW5lZCwgdGhlIGF0dGVtcHQgZmFpbGVkIGluIGEgd2F5IHRoYXQgaXMgc2FmZSB0byByZS1zZW5kIGFuZCBpcyBiZWluZyByZXRyaWVkLlxuICAgICAgICAgIGlmICghcmVzdWx0KSBjb250aW51ZTtcblxuICAgICAgICAgIC8vIFNvbWV0aW1lcyB0aGUgQ29udGVudC1UeXBlIG1heSBiZSBcImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9dXRmLThcIiwgZm9yIHRoaXMgcmVhc29uLCB3ZSBuZWVkIHRvIGNoZWNrIHRoZSBzdGFydCBvZiB0aGUgaGVhZGVyXG4gICAgICAgICAgbGV0IGJvZHlSZWFkRmFpbGVkID0gZmFsc2U7XG4gICAgICAgICAgY29uc3QgYm9keSA9IGF3YWl0IChyZXN1bHQuaGVhZGVycy5nZXQoJ0NvbnRlbnQtVHlwZScpPy5zdGFydHNXaXRoKCdhcHBsaWNhdGlvbi9qc29uJykgPyByZXN1bHQuanNvbigpIDogcmVzdWx0LnRleHQoKSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgYm9keVJlYWRGYWlsZWQgPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICByZXN0LmV2ZW50cy5yZXNwb25zZShyZXF1ZXN0LCByZXN1bHQsIHtcbiAgICAgICAgICAgIHJlcXVlc3RCb2R5OiBvcHRpb25zPy5ib2R5LFxuICAgICAgICAgICAgcmVzcG9uc2VCb2R5OiBib2R5LFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8gYGZldGNoYCByZXNvbHZlcyBvbmNlIHRoZSBoZWFkZXJzIGFyZSBpbiwgc28gYW4gYWJvcnQgY2FuIGxhbmQgd2hpbGUgdGhlIGJvZHkgYWJvdmUgaXMgc3RpbGwgYmVpbmcgcmVhZC4gVGhhdCByZWFkIHJlamVjdHMsIHRoZVxuICAgICAgICAgIC8vIGZhbGxiYWNrIHR1cm5zIGl0IGludG8gYSBgbnVsbGAgYm9keSBhbmQgdGhlIGNhbGxlciBnZXRzIGl0IGJhY2sgYXMgYSBzdWNjZXNzZnVsIGVtcHR5IHJlc3BvbnNlLiBBIHJlYWQgdGhhdCBkaWQgZmluaXNoIGlzIGtlcHQsXG4gICAgICAgICAgLy8gdGhlIHNhbWUgd2F5IHRoZSBxdWV1ZWQgcGF0aCBoYW5kcyBiYWNrIGEgcmVzdWx0IHRoYXQgYXJyaXZlZCBiZWZvcmUgdGhlIHNpZ25hbCBmaXJlZC5cbiAgICAgICAgICBpZiAoYm9keVJlYWRGYWlsZWQgJiYgb3B0aW9ucz8uc2lnbmFsPy5hYm9ydGVkKSB7XG4gICAgICAgICAgICB0aHJvdyByZXN0LmNyZWF0ZVJlcXVlc3RFcnJvcihlcnJvciwgeyBvazogZmFsc2UsIHN0YXR1czogOTk5LCBlcnJvcjogJ1RoZSByZXF1ZXN0IHdhcyBhYm9ydGVkLicsIGVycm9yT2JqZWN0OiBvcHRpb25zLnNpZ25hbC5yZWFzb24gfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFyZXN1bHQub2spIHtcbiAgICAgICAgICAgIHRocm93IHJlc3QuY3JlYXRlUmVxdWVzdEVycm9yKGVycm9yLCB7IG9rOiBmYWxzZSwgc3RhdHVzOiByZXN1bHQuc3RhdHVzLCBzdGF0dXNUZXh0OiByZXN1bHQuc3RhdHVzVGV4dCwgYm9keSB9KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcmVzdWx0LnN0YXR1cyAhPT0gMjA0ID8gKHR5cGVvZiBib2R5ID09PSAnc3RyaW5nJyA/IEpTT04ucGFyc2UoYm9keSkgOiBib2R5KSA6IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCBzaWduYWwgPSBvcHRpb25zPy5zaWduYWw7XG4gICAgICAgIGNvbnN0IGFib3J0TGlzdGVuZXIgPSAoKSA9PiB7XG4gICAgICAgICAgLy8gUmVqZWN0IHJpZ2h0IGF3YXkgaW5zdGVhZCBvZiB3YWl0aW5nIGZvciB0aGUgcXVldWUgdG8gcmVhY2ggdGhlIHJlcXVlc3QuIFRoZSBzaWduYWwgaXMgYXR0YWNoZWQgdG8gdGhlIGZldGNoIGl0c2VsZiBhcyB3ZWxsLCBzbyBhblxuICAgICAgICAgIC8vIGF0dGVtcHQgdGhhdCBpcyBhbHJlYWR5IGluIGZsaWdodCBnZXRzIGl0cyBjb25uZWN0aW9uIHRvcm4gZG93biB0b28uXG4gICAgICAgICAgcGF5bG9hZC5yZWplY3Qoe1xuICAgICAgICAgICAgb2s6IGZhbHNlLFxuICAgICAgICAgICAgc3RhdHVzOiA5OTksXG4gICAgICAgICAgICBlcnJvcjogJ1RoZSByZXF1ZXN0IHdhcyBhYm9ydGVkLicsXG4gICAgICAgICAgICBlcnJvck9iamVjdDogc2lnbmFsPy5yZWFzb24sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcGF5bG9hZDogU2VuZFJlcXVlc3RPcHRpb25zID0ge1xuICAgICAgICAgIHJvdXRlLFxuICAgICAgICAgIG1ldGhvZCxcbiAgICAgICAgICByZXF1ZXN0Qm9keU9wdGlvbnM6IG9wdGlvbnMsXG4gICAgICAgICAgcmV0cnlDb3VudDogMCxcbiAgICAgICAgICByZXRyeVJlcXVlc3Q6IGFzeW5jIChwYXlsb2FkOiBTZW5kUmVxdWVzdE9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IHJlc3QucHJvY2Vzc1JlcXVlc3QocGF5bG9hZCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXNvbHZlOiAoZGF0YSkgPT4ge1xuICAgICAgICAgICAgc2lnbmFsPy5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIGFib3J0TGlzdGVuZXIpO1xuICAgICAgICAgICAgcmVzb2x2ZShkYXRhLnN0YXR1cyAhPT0gMjA0ID8gKGRhdGEuYm9keSBhcyBQYXJhbWV0ZXJzPHR5cGVvZiByZXNvbHZlPlswXSkgOiB1bmRlZmluZWQhKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlamVjdDogKHJlYXNvbikgPT4ge1xuICAgICAgICAgICAgc2lnbmFsPy5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIGFib3J0TGlzdGVuZXIpO1xuICAgICAgICAgICAgcmVqZWN0KHJlc3QuY3JlYXRlUmVxdWVzdEVycm9yKGVycm9yLCByZWFzb24pKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJ1blRocm91Z2hRdWV1ZTogb3B0aW9ucz8ucnVuVGhyb3VnaFF1ZXVlLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFJlamVjdCBhIHF1ZXVlZCByZXF1ZXN0IGFzIHNvb24gYXMgaXRzIHNpZ25hbCBhYm9ydHMgaW5zdGVhZCBvZiB3aGVuIHRoZSBxdWV1ZSByZWFjaGVzIGl0LCBzbyBhIGNhbGxlciBlbmZvcmNpbmcgYSBkZWFkbGluZSBnZXRzIGl0c1xuICAgICAgICAvLyBhbnN3ZXIgcmlnaHQgYXdheS4gRmV0Y2ggcmVmdXNpbmcgdG8gc2VuZCBhbiBhbHJlYWR5IGFib3J0ZWQgcmVxdWVzdCBpcyB3aGF0IGd1YXJhbnRlZXMgdGhlIHN0YWxlIHF1ZXVlIGVudHJ5IG5ldmVyIGdvZXMgb3V0LlxuICAgICAgICBpZiAoc2lnbmFsPy5hYm9ydGVkKSB7XG4gICAgICAgICAgYWJvcnRMaXN0ZW5lcigpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHNpZ25hbD8uYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBhYm9ydExpc3RlbmVyLCB7IG9uY2U6IHRydWUgfSk7XG5cbiAgICAgICAgYXdhaXQgcmVzdC5wcm9jZXNzUmVxdWVzdChwYXlsb2FkKTtcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXQ8VCA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+Pih1cmw6IHN0cmluZywgb3B0aW9ucz86IE9taXQ8Q3JlYXRlUmVxdWVzdEJvZHlPcHRpb25zLCAnYm9keScgfCAnbWV0aG9kJz4pIHtcbiAgICAgIHJldHVybiBjYW1lbGl6ZShhd2FpdCByZXN0Lm1ha2VSZXF1ZXN0KCdHRVQnLCB1cmwsIG9wdGlvbnMpKSBhcyBDYW1lbGl6ZTxUPjtcbiAgICB9LFxuXG4gICAgYXN5bmMgcG9zdDxUID0gUmVjb3JkPHN0cmluZywgdW5rbm93bj4+KHVybDogc3RyaW5nLCBvcHRpb25zPzogT21pdDxDcmVhdGVSZXF1ZXN0Qm9keU9wdGlvbnMsICdib2R5JyB8ICdtZXRob2QnPikge1xuICAgICAgcmV0dXJuIGNhbWVsaXplKGF3YWl0IHJlc3QubWFrZVJlcXVlc3QoJ1BPU1QnLCB1cmwsIG9wdGlvbnMpKSBhcyBDYW1lbGl6ZTxUPjtcbiAgICB9LFxuXG4gICAgYXN5bmMgZGVsZXRlKHVybDogc3RyaW5nLCBvcHRpb25zPzogT21pdDxDcmVhdGVSZXF1ZXN0Qm9keU9wdGlvbnMsICdib2R5JyB8ICdtZXRob2QnPikge1xuICAgICAgY2FtZWxpemUoYXdhaXQgcmVzdC5tYWtlUmVxdWVzdCgnREVMRVRFJywgdXJsLCBvcHRpb25zKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIHBhdGNoPFQgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4odXJsOiBzdHJpbmcsIG9wdGlvbnM/OiBPbWl0PENyZWF0ZVJlcXVlc3RCb2R5T3B0aW9ucywgJ2JvZHknIHwgJ21ldGhvZCc+KSB7XG4gICAgICByZXR1cm4gY2FtZWxpemUoYXdhaXQgcmVzdC5tYWtlUmVxdWVzdCgnUEFUQ0gnLCB1cmwsIG9wdGlvbnMpKSBhcyBDYW1lbGl6ZTxUPjtcbiAgICB9LFxuXG4gICAgYXN5bmMgcHV0PFQgPSB2b2lkPih1cmw6IHN0cmluZywgb3B0aW9ucz86IE9taXQ8Q3JlYXRlUmVxdWVzdEJvZHlPcHRpb25zLCAnYm9keScgfCAnbWV0aG9kJz4pIHtcbiAgICAgIHJldHVybiBjYW1lbGl6ZShhd2FpdCByZXN0Lm1ha2VSZXF1ZXN0KCdQVVQnLCB1cmwsIG9wdGlvbnMpKSBhcyBDYW1lbGl6ZTxUPjtcbiAgICB9LFxuXG4gICAgYXN5bmMgYWRkUmVhY3Rpb24oY2hhbm5lbElkLCBtZXNzYWdlSWQsIHJlYWN0aW9uKSB7XG4gICAgICByZWFjdGlvbiA9IHByb2Nlc3NSZWFjdGlvblN0cmluZyhyZWFjdGlvbik7XG5cbiAgICAgIGF3YWl0IHJlc3QucHV0KHJlc3Qucm91dGVzLmNoYW5uZWxzLnJlYWN0aW9ucy5ib3QoY2hhbm5lbElkLCBtZXNzYWdlSWQsIHJlYWN0aW9uKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGFkZFJlYWN0aW9ucyhjaGFubmVsSWQsIG1lc3NhZ2VJZCwgcmVhY3Rpb25zLCBvcmRlcmVkID0gZmFsc2UpIHtcbiAgICAgIGlmICghb3JkZXJlZCkge1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICByZWFjdGlvbnMubWFwKGFzeW5jIChyZWFjdGlvbikgPT4ge1xuICAgICAgICAgICAgYXdhaXQgcmVzdC5hZGRSZWFjdGlvbihjaGFubmVsSWQsIG1lc3NhZ2VJZCwgcmVhY3Rpb24pO1xuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgcmVhY3Rpb24gb2YgcmVhY3Rpb25zKSB7XG4gICAgICAgIGF3YWl0IHJlc3QuYWRkUmVhY3Rpb24oY2hhbm5lbElkLCBtZXNzYWdlSWQsIHJlYWN0aW9uKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYXN5bmMgYWRkUm9sZShndWlsZElkLCB1c2VySWQsIHJvbGVJZCwgcmVhc29uKSB7XG4gICAgICBhd2FpdCByZXN0LnB1dChyZXN0LnJvdXRlcy5ndWlsZHMucm9sZXMubWVtYmVyKGd1aWxkSWQsIHVzZXJJZCwgcm9sZUlkKSwgeyByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGFkZFRocmVhZE1lbWJlcihjaGFubmVsSWQsIHVzZXJJZCkge1xuICAgICAgYXdhaXQgcmVzdC5wdXQocmVzdC5yb3V0ZXMuY2hhbm5lbHMudGhyZWFkcy51c2VyKGNoYW5uZWxJZCwgdXNlcklkKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGFkZERtUmVjaXBpZW50KGNoYW5uZWxJZCwgdXNlcklkLCBib2R5KSB7XG4gICAgICBhd2FpdCByZXN0LnB1dChyZXN0LnJvdXRlcy5jaGFubmVscy5kbVJlY2lwaWVudChjaGFubmVsSWQsIHVzZXJJZCksIHsgYm9keSB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgY3JlYXRlQXV0b21vZFJ1bGUoZ3VpbGRJZCwgYm9keSwgcmVhc29uKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wb3N0PERpc2NvcmRBdXRvTW9kZXJhdGlvblJ1bGU+KHJlc3Qucm91dGVzLmd1aWxkcy5hdXRvbW9kLnJ1bGVzKGd1aWxkSWQpLCB7IGJvZHksIHJlYXNvbiB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgY3JlYXRlQ2hhbm5lbChndWlsZElkLCBib2R5LCByZWFzb24pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBvc3Q8RGlzY29yZENoYW5uZWw+KHJlc3Qucm91dGVzLmd1aWxkcy5jaGFubmVscyhndWlsZElkKSwgeyBib2R5LCByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGNyZWF0ZUVtb2ppKGd1aWxkSWQsIGJvZHksIHJlYXNvbikge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucG9zdDxEaXNjb3JkRW1vamk+KHJlc3Qucm91dGVzLmd1aWxkcy5lbW9qaXMoZ3VpbGRJZCksIHsgYm9keSwgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBjcmVhdGVBcHBsaWNhdGlvbkVtb2ppKGJvZHkpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBvc3Q8RGlzY29yZEVtb2ppPihyZXN0LnJvdXRlcy5hcHBsaWNhdGlvbkVtb2ppcyhyZXN0LmFwcGxpY2F0aW9uSWQpLCB7IGJvZHkgfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGNyZWF0ZUdsb2JhbEFwcGxpY2F0aW9uQ29tbWFuZChib2R5LCBvcHRpb25zKSB7XG4gICAgICBjb25zdCByZXN0T3B0aW9uczogTWFrZVJlcXVlc3RPcHRpb25zID0geyBib2R5IH07XG5cbiAgICAgIGlmIChvcHRpb25zPy5iZWFyZXJUb2tlbikge1xuICAgICAgICByZXN0T3B0aW9ucy51bmF1dGhvcml6ZWQgPSB0cnVlO1xuICAgICAgICByZXN0T3B0aW9ucy5oZWFkZXJzID0ge1xuICAgICAgICAgIGF1dGhvcml6YXRpb246IGBCZWFyZXIgJHtvcHRpb25zLmJlYXJlclRva2VufWAsXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBvc3Q8RGlzY29yZEFwcGxpY2F0aW9uQ29tbWFuZD4ocmVzdC5yb3V0ZXMuaW50ZXJhY3Rpb25zLmNvbW1hbmRzLmNvbW1hbmRzKHJlc3QuYXBwbGljYXRpb25JZCksIHJlc3RPcHRpb25zKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgY3JlYXRlR3VpbGRBcHBsaWNhdGlvbkNvbW1hbmQoYm9keSwgZ3VpbGRJZCwgb3B0aW9ucykge1xuICAgICAgY29uc3QgcmVzdE9wdGlvbnM6IE1ha2VSZXF1ZXN0T3B0aW9ucyA9IHsgYm9keSB9O1xuXG4gICAgICBpZiAob3B0aW9ucz8uYmVhcmVyVG9rZW4pIHtcbiAgICAgICAgcmVzdE9wdGlvbnMudW5hdXRob3JpemVkID0gdHJ1ZTtcbiAgICAgICAgcmVzdE9wdGlvbnMuaGVhZGVycyA9IHtcbiAgICAgICAgICBhdXRob3JpemF0aW9uOiBgQmVhcmVyICR7b3B0aW9ucy5iZWFyZXJUb2tlbn1gLFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wb3N0PERpc2NvcmRBcHBsaWNhdGlvbkNvbW1hbmQ+KHJlc3Qucm91dGVzLmludGVyYWN0aW9ucy5jb21tYW5kcy5ndWlsZHMuYWxsKHJlc3QuYXBwbGljYXRpb25JZCwgZ3VpbGRJZCksIHJlc3RPcHRpb25zKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgY3JlYXRlR3VpbGRTdGlja2VyKGd1aWxkSWQsIG9wdGlvbnMsIHJlYXNvbikge1xuICAgICAgY29uc3QgZm9ybSA9IG5ldyBGb3JtRGF0YSgpO1xuICAgICAgZm9ybS5hcHBlbmQoJ2ZpbGUnLCBvcHRpb25zLmZpbGUuYmxvYiwgb3B0aW9ucy5maWxlLm5hbWUpO1xuICAgICAgZm9ybS5hcHBlbmQoJ25hbWUnLCBvcHRpb25zLm5hbWUpO1xuICAgICAgZm9ybS5hcHBlbmQoJ2Rlc2NyaXB0aW9uJywgb3B0aW9ucy5kZXNjcmlwdGlvbik7XG4gICAgICBmb3JtLmFwcGVuZCgndGFncycsIG9wdGlvbnMudGFncyk7XG5cbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBvc3Q8RGlzY29yZFN0aWNrZXI+KHJlc3Qucm91dGVzLmd1aWxkcy5zdGlja2VycyhndWlsZElkKSwgeyBib2R5OiBmb3JtLCByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGNyZWF0ZUd1aWxkVGVtcGxhdGUoZ3VpbGRJZCwgYm9keSkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucG9zdDxEaXNjb3JkVGVtcGxhdGU+KHJlc3Qucm91dGVzLmd1aWxkcy50ZW1wbGF0ZXMuYWxsKGd1aWxkSWQpLCB7IGJvZHkgfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGNyZWF0ZUZvcnVtVGhyZWFkKGNoYW5uZWxJZCwgYm9keSwgcmVhc29uKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wb3N0PERpc2NvcmRDaGFubmVsPihyZXN0LnJvdXRlcy5jaGFubmVscy5mb3J1bShjaGFubmVsSWQpLCB7IGJvZHksIGZpbGVzOiBib2R5LmZpbGVzLCByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGNyZWF0ZUludml0ZShjaGFubmVsSWQsIGJvZHkgPSB7fSwgcmVhc29uKSB7XG4gICAgICBpZiAoIWJvZHkudGFyZ2V0VXNlcnNGaWxlKSB7XG4gICAgICAgIHJldHVybiBhd2FpdCByZXN0LnBvc3Q8RGlzY29yZEludml0ZT4ocmVzdC5yb3V0ZXMuY2hhbm5lbHMuaW52aXRlcyhjaGFubmVsSWQpLCB7IGJvZHksIHJlYXNvbiB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gV2hlbiB3ZSBoYXZlIHRvIHVwbG9hZCBhIGZpbGUsIHdlIG5lZWQgdG8gdXNlIEZvcm1EYXRhLCBhbmQgYWxsIG90aGVyIGZpZWxkcyBuZWVkIHRvIGJlIHBhcnQgb2YgdGhlIHBheWxvYWRfanNvbiBmaWVsZC5cbiAgICAgIGNvbnN0IGZvcm0gPSBuZXcgRm9ybURhdGEoKTtcblxuICAgICAgZm9ybS5hcHBlbmQoJ3BheWxvYWRfanNvbicsIEpTT04uc3RyaW5naWZ5KHJlc3QuY2hhbmdlVG9EaXNjb3JkRm9ybWF0KHsgLi4uYm9keSwgdGFyZ2V0VXNlcnNGaWxlOiB1bmRlZmluZWQgfSkpKTtcbiAgICAgIGZvcm0uYXBwZW5kKCd0YXJnZXRfdXNlcnNfZmlsZScsIGJvZHkudGFyZ2V0VXNlcnNGaWxlKTtcblxuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucG9zdDxEaXNjb3JkSW52aXRlPihyZXN0LnJvdXRlcy5jaGFubmVscy5pbnZpdGVzKGNoYW5uZWxJZCksIHsgYm9keTogZm9ybSwgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRHdWlsZFJvbGVNZW1iZXJDb3VudHMoZ3VpbGRJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PFJlY29yZDxzdHJpbmcsIG51bWJlcj4+KHJlc3Qucm91dGVzLmd1aWxkcy5yb2xlcy5tZW1iZXJDb3VudHMoZ3VpbGRJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBjcmVhdGVSb2xlKGd1aWxkSWQsIGJvZHksIHJlYXNvbikge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucG9zdDxEaXNjb3JkUm9sZT4ocmVzdC5yb3V0ZXMuZ3VpbGRzLnJvbGVzLmFsbChndWlsZElkKSwgeyBib2R5LCByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGNyZWF0ZVNjaGVkdWxlZEV2ZW50KGd1aWxkSWQsIGJvZHksIHJlYXNvbikge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucG9zdDxEaXNjb3JkU2NoZWR1bGVkRXZlbnQ+KHJlc3Qucm91dGVzLmd1aWxkcy5ldmVudHMuZXZlbnRzKGd1aWxkSWQpLCB7IGJvZHksIHJlYXNvbiB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgY3JlYXRlU3RhZ2VJbnN0YW5jZShib2R5LCByZWFzb24pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBvc3Q8RGlzY29yZFN0YWdlSW5zdGFuY2U+KHJlc3Qucm91dGVzLmNoYW5uZWxzLnN0YWdlcygpLCB7IGJvZHksIHJlYXNvbiB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgY3JlYXRlV2ViaG9vayhjaGFubmVsSWQsIG9wdGlvbnMsIHJlYXNvbikge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucG9zdDxEaXNjb3JkV2ViaG9vaz4ocmVzdC5yb3V0ZXMuY2hhbm5lbHMud2ViaG9va3MoY2hhbm5lbElkKSwge1xuICAgICAgICBib2R5OiBvcHRpb25zLFxuICAgICAgICByZWFzb24sXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZGVsZXRlQXV0b21vZFJ1bGUoZ3VpbGRJZCwgcnVsZUlkLCByZWFzb24pIHtcbiAgICAgIGF3YWl0IHJlc3QuZGVsZXRlKHJlc3Qucm91dGVzLmd1aWxkcy5hdXRvbW9kLnJ1bGUoZ3VpbGRJZCwgcnVsZUlkKSwgeyByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGRlbGV0ZUNoYW5uZWwoY2hhbm5lbElkLCByZWFzb24pIHtcbiAgICAgIGF3YWl0IHJlc3QuZGVsZXRlKHJlc3Qucm91dGVzLmNoYW5uZWxzLmNoYW5uZWwoY2hhbm5lbElkKSwge1xuICAgICAgICByZWFzb24sXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZGVsZXRlQ2hhbm5lbFBlcm1pc3Npb25PdmVycmlkZShjaGFubmVsSWQsIG92ZXJ3cml0ZUlkLCByZWFzb24pIHtcbiAgICAgIGF3YWl0IHJlc3QuZGVsZXRlKHJlc3Qucm91dGVzLmNoYW5uZWxzLm92ZXJ3cml0ZShjaGFubmVsSWQsIG92ZXJ3cml0ZUlkKSwgeyByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGRlbGV0ZUVtb2ppKGd1aWxkSWQsIGlkLCByZWFzb24pIHtcbiAgICAgIGF3YWl0IHJlc3QuZGVsZXRlKHJlc3Qucm91dGVzLmd1aWxkcy5lbW9qaShndWlsZElkLCBpZCksIHsgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGVBcHBsaWNhdGlvbkVtb2ppKGlkKSB7XG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5hcHBsaWNhdGlvbkVtb2ppKHJlc3QuYXBwbGljYXRpb25JZCwgaWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZGVsZXRlRm9sbG93dXBNZXNzYWdlKHRva2VuLCBtZXNzYWdlSWQpIHtcbiAgICAgIGF3YWl0IHJlc3QuZGVsZXRlKHJlc3Qucm91dGVzLmludGVyYWN0aW9ucy5yZXNwb25zZXMubWVzc2FnZShyZXN0LmFwcGxpY2F0aW9uSWQsIHRva2VuLCBtZXNzYWdlSWQpLCB7IHVuYXV0aG9yaXplZDogdHJ1ZSB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZGVsZXRlR2xvYmFsQXBwbGljYXRpb25Db21tYW5kKGNvbW1hbmRJZCkge1xuICAgICAgYXdhaXQgcmVzdC5kZWxldGUocmVzdC5yb3V0ZXMuaW50ZXJhY3Rpb25zLmNvbW1hbmRzLmNvbW1hbmQocmVzdC5hcHBsaWNhdGlvbklkLCBjb21tYW5kSWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZGVsZXRlR3VpbGRBcHBsaWNhdGlvbkNvbW1hbmQoY29tbWFuZElkLCBndWlsZElkKSB7XG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5pbnRlcmFjdGlvbnMuY29tbWFuZHMuZ3VpbGRzLm9uZShyZXN0LmFwcGxpY2F0aW9uSWQsIGd1aWxkSWQsIGNvbW1hbmRJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGVHdWlsZFN0aWNrZXIoZ3VpbGRJZCwgc3RpY2tlcklkLCByZWFzb24pIHtcbiAgICAgIGF3YWl0IHJlc3QuZGVsZXRlKHJlc3Qucm91dGVzLmd1aWxkcy5zdGlja2VyKGd1aWxkSWQsIHN0aWNrZXJJZCksIHsgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGVHdWlsZFRlbXBsYXRlKGd1aWxkSWQsIHRlbXBsYXRlQ29kZSkge1xuICAgICAgYXdhaXQgcmVzdC5kZWxldGUocmVzdC5yb3V0ZXMuZ3VpbGRzLnRlbXBsYXRlcy5ndWlsZChndWlsZElkLCB0ZW1wbGF0ZUNvZGUpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZGVsZXRlSW50ZWdyYXRpb24oZ3VpbGRJZCwgaW50ZWdyYXRpb25JZCwgcmVhc29uKSB7XG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5ndWlsZHMuaW50ZWdyYXRpb24oZ3VpbGRJZCwgaW50ZWdyYXRpb25JZCksIHsgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGVJbnZpdGUoaW52aXRlQ29kZSwgcmVhc29uKSB7XG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5ndWlsZHMuaW52aXRlKGludml0ZUNvZGUpLCB7IHJlYXNvbiB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0VGFyZ2V0VXNlcnMoaW52aXRlQ29kZSkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PHN0cmluZz4ocmVzdC5yb3V0ZXMuZ3VpbGRzLmludml0ZVRhcmdldFVzZXJzKGludml0ZUNvZGUpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgdXBkYXRlVGFyZ2V0VXNlcnMoaW52aXRlQ29kZSwgdGFyZ2V0VXNlcnNGaWxlKSB7XG4gICAgICBjb25zdCBmb3JtID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICBmb3JtLmFwcGVuZCgndGFyZ2V0X3VzZXJzX2ZpbGUnLCB0YXJnZXRVc2Vyc0ZpbGUpO1xuXG4gICAgICBhd2FpdCByZXN0LnB1dChyZXN0LnJvdXRlcy5ndWlsZHMuaW52aXRlVGFyZ2V0VXNlcnMoaW52aXRlQ29kZSksIHsgYm9keTogZm9ybSB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0VGFyZ2V0VXNlcnNKb2JTdGF0dXMoaW52aXRlQ29kZSkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRUYXJnZXRVc2Vyc0pvYlN0YXR1cz4ocmVzdC5yb3V0ZXMuZ3VpbGRzLmludml0ZVRhcmdldFVzZXJzSm9iU3RhdHVzKGludml0ZUNvZGUpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZGVsZXRlTWVzc2FnZShjaGFubmVsSWQsIG1lc3NhZ2VJZCwgcmVhc29uKSB7XG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5jaGFubmVscy5tZXNzYWdlKGNoYW5uZWxJZCwgbWVzc2FnZUlkKSwgeyByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGRlbGV0ZU1lc3NhZ2VzKGNoYW5uZWxJZCwgbWVzc2FnZUlkcywgcmVhc29uKSB7XG4gICAgICBhd2FpdCByZXN0LnBvc3QocmVzdC5yb3V0ZXMuY2hhbm5lbHMuYnVsayhjaGFubmVsSWQpLCB7XG4gICAgICAgIGJvZHk6IHtcbiAgICAgICAgICBtZXNzYWdlczogbWVzc2FnZUlkcy5zbGljZSgwLCAxMDApLm1hcCgoaWQpID0+IGlkLnRvU3RyaW5nKCkpLFxuICAgICAgICB9LFxuICAgICAgICByZWFzb24sXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZGVsZXRlT3JpZ2luYWxJbnRlcmFjdGlvblJlc3BvbnNlKHRva2VuKSB7XG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5pbnRlcmFjdGlvbnMucmVzcG9uc2VzLm9yaWdpbmFsKHJlc3QuYXBwbGljYXRpb25JZCwgdG9rZW4pLCB7IHVuYXV0aG9yaXplZDogdHJ1ZSB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZGVsZXRlT3duUmVhY3Rpb24oY2hhbm5lbElkLCBtZXNzYWdlSWQsIHJlYWN0aW9uKSB7XG4gICAgICByZWFjdGlvbiA9IHByb2Nlc3NSZWFjdGlvblN0cmluZyhyZWFjdGlvbik7XG5cbiAgICAgIGF3YWl0IHJlc3QuZGVsZXRlKHJlc3Qucm91dGVzLmNoYW5uZWxzLnJlYWN0aW9ucy5ib3QoY2hhbm5lbElkLCBtZXNzYWdlSWQsIHJlYWN0aW9uKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGRlbGV0ZVJlYWN0aW9uc0FsbChjaGFubmVsSWQsIG1lc3NhZ2VJZCkge1xuICAgICAgYXdhaXQgcmVzdC5kZWxldGUocmVzdC5yb3V0ZXMuY2hhbm5lbHMucmVhY3Rpb25zLmFsbChjaGFubmVsSWQsIG1lc3NhZ2VJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGVSZWFjdGlvbnNFbW9qaShjaGFubmVsSWQsIG1lc3NhZ2VJZCwgcmVhY3Rpb24pIHtcbiAgICAgIHJlYWN0aW9uID0gcHJvY2Vzc1JlYWN0aW9uU3RyaW5nKHJlYWN0aW9uKTtcblxuICAgICAgYXdhaXQgcmVzdC5kZWxldGUocmVzdC5yb3V0ZXMuY2hhbm5lbHMucmVhY3Rpb25zLmVtb2ppKGNoYW5uZWxJZCwgbWVzc2FnZUlkLCByZWFjdGlvbikpO1xuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGVSb2xlKGd1aWxkSWQsIHJvbGVJZCwgcmVhc29uKSB7XG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5ndWlsZHMucm9sZXMub25lKGd1aWxkSWQsIHJvbGVJZCksIHsgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGVTY2hlZHVsZWRFdmVudChndWlsZElkLCBldmVudElkKSB7XG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5ndWlsZHMuZXZlbnRzLmV2ZW50KGd1aWxkSWQsIGV2ZW50SWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZGVsZXRlU3RhZ2VJbnN0YW5jZShjaGFubmVsSWQsIHJlYXNvbikge1xuICAgICAgYXdhaXQgcmVzdC5kZWxldGUocmVzdC5yb3V0ZXMuY2hhbm5lbHMuc3RhZ2UoY2hhbm5lbElkKSwgeyByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGRlbGV0ZVVzZXJSZWFjdGlvbihjaGFubmVsSWQsIG1lc3NhZ2VJZCwgdXNlcklkLCByZWFjdGlvbikge1xuICAgICAgcmVhY3Rpb24gPSBwcm9jZXNzUmVhY3Rpb25TdHJpbmcocmVhY3Rpb24pO1xuXG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5jaGFubmVscy5yZWFjdGlvbnMudXNlcihjaGFubmVsSWQsIG1lc3NhZ2VJZCwgcmVhY3Rpb24sIHVzZXJJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGVXZWJob29rKHdlYmhvb2tJZCwgcmVhc29uKSB7XG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy53ZWJob29rcy5pZCh3ZWJob29rSWQpLCB7IHJlYXNvbiB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZGVsZXRlV2ViaG9va01lc3NhZ2Uod2ViaG9va0lkLCB0b2tlbiwgbWVzc2FnZUlkLCBvcHRpb25zKSB7XG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy53ZWJob29rcy5tZXNzYWdlKHdlYmhvb2tJZCwgdG9rZW4sIG1lc3NhZ2VJZCwgb3B0aW9ucyksIHsgdW5hdXRob3JpemVkOiB0cnVlIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGVXZWJob29rV2l0aFRva2VuKHdlYmhvb2tJZCwgdG9rZW4pIHtcbiAgICAgIGF3YWl0IHJlc3QuZGVsZXRlKHJlc3Qucm91dGVzLndlYmhvb2tzLndlYmhvb2sod2ViaG9va0lkLCB0b2tlbiksIHtcbiAgICAgICAgdW5hdXRob3JpemVkOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGVkaXRBcHBsaWNhdGlvbkNvbW1hbmRQZXJtaXNzaW9ucyhndWlsZElkLCBjb21tYW5kSWQsIGJlYXJlclRva2VuLCBwZXJtaXNzaW9ucykge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucHV0PERpc2NvcmRHdWlsZEFwcGxpY2F0aW9uQ29tbWFuZFBlcm1pc3Npb25zPihcbiAgICAgICAgcmVzdC5yb3V0ZXMuaW50ZXJhY3Rpb25zLmNvbW1hbmRzLnBlcm1pc3Npb24ocmVzdC5hcHBsaWNhdGlvbklkLCBndWlsZElkLCBjb21tYW5kSWQpLFxuICAgICAgICB7XG4gICAgICAgICAgYm9keToge1xuICAgICAgICAgICAgcGVybWlzc2lvbnMsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBoZWFkZXJzOiB7IGF1dGhvcml6YXRpb246IGBCZWFyZXIgJHtiZWFyZXJUb2tlbn1gIH0sXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH0sXG5cbiAgICBhc3luYyBlZGl0QXV0b21vZFJ1bGUoZ3VpbGRJZCwgcnVsZUlkLCBib2R5LCByZWFzb24pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBhdGNoPERpc2NvcmRBdXRvTW9kZXJhdGlvblJ1bGU+KHJlc3Qucm91dGVzLmd1aWxkcy5hdXRvbW9kLnJ1bGUoZ3VpbGRJZCwgcnVsZUlkKSwgeyBib2R5LCByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGVkaXRCb3RQcm9maWxlKG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBhdGNoPERpc2NvcmRVc2VyPihyZXN0LnJvdXRlcy5jdXJyZW50VXNlcigpLCB7XG4gICAgICAgIGJvZHk6IG9wdGlvbnMsXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZWRpdENoYW5uZWwoY2hhbm5lbElkLCBib2R5LCByZWFzb24pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBhdGNoPERpc2NvcmRDaGFubmVsPihyZXN0LnJvdXRlcy5jaGFubmVscy5jaGFubmVsKGNoYW5uZWxJZCksIHsgYm9keSwgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBlZGl0Q2hhbm5lbFBlcm1pc3Npb25PdmVycmlkZXMoY2hhbm5lbElkLCBib2R5LCByZWFzb24pIHtcbiAgICAgIGF3YWl0IHJlc3QucHV0KHJlc3Qucm91dGVzLmNoYW5uZWxzLm92ZXJ3cml0ZShjaGFubmVsSWQsIGJvZHkuaWQpLCB7IGJvZHksIHJlYXNvbiB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZWRpdENoYW5uZWxQb3NpdGlvbnMoZ3VpbGRJZCwgYm9keSkge1xuICAgICAgYXdhaXQgcmVzdC5wYXRjaChyZXN0LnJvdXRlcy5ndWlsZHMuY2hhbm5lbHMoZ3VpbGRJZCksIHsgYm9keSB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZWRpdEVtb2ppKGd1aWxkSWQsIGlkLCBib2R5LCByZWFzb24pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBhdGNoPERpc2NvcmRFbW9qaT4ocmVzdC5yb3V0ZXMuZ3VpbGRzLmVtb2ppKGd1aWxkSWQsIGlkKSwgeyBib2R5LCByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGVkaXRBcHBsaWNhdGlvbkVtb2ppKGlkLCBib2R5KSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wYXRjaDxEaXNjb3JkRW1vamk+KHJlc3Qucm91dGVzLmFwcGxpY2F0aW9uRW1vamkocmVzdC5hcHBsaWNhdGlvbklkLCBpZCksIHsgYm9keSB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZWRpdEZvbGxvd3VwTWVzc2FnZSh0b2tlbiwgbWVzc2FnZUlkLCBib2R5KSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wYXRjaDxEaXNjb3JkTWVzc2FnZT4ocmVzdC5yb3V0ZXMuaW50ZXJhY3Rpb25zLnJlc3BvbnNlcy5tZXNzYWdlKHJlc3QuYXBwbGljYXRpb25JZCwgdG9rZW4sIG1lc3NhZ2VJZCksIHtcbiAgICAgICAgYm9keSxcbiAgICAgICAgZmlsZXM6IGJvZHkuZmlsZXMsXG4gICAgICAgIHVuYXV0aG9yaXplZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBlZGl0R2xvYmFsQXBwbGljYXRpb25Db21tYW5kKGNvbW1hbmRJZCwgYm9keSkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucGF0Y2g8RGlzY29yZEFwcGxpY2F0aW9uQ29tbWFuZD4ocmVzdC5yb3V0ZXMuaW50ZXJhY3Rpb25zLmNvbW1hbmRzLmNvbW1hbmQocmVzdC5hcHBsaWNhdGlvbklkLCBjb21tYW5kSWQpLCB7IGJvZHkgfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGVkaXRHdWlsZChndWlsZElkLCBib2R5LCByZWFzb24pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBhdGNoPERpc2NvcmRHdWlsZD4ocmVzdC5yb3V0ZXMuZ3VpbGRzLmd1aWxkKGd1aWxkSWQpLCB7IGJvZHksIHJlYXNvbiB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZWRpdEd1aWxkQXBwbGljYXRpb25Db21tYW5kKGNvbW1hbmRJZCwgZ3VpbGRJZCwgYm9keSkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucGF0Y2g8RGlzY29yZEFwcGxpY2F0aW9uQ29tbWFuZD4ocmVzdC5yb3V0ZXMuaW50ZXJhY3Rpb25zLmNvbW1hbmRzLmd1aWxkcy5vbmUocmVzdC5hcHBsaWNhdGlvbklkLCBndWlsZElkLCBjb21tYW5kSWQpLCB7XG4gICAgICAgIGJvZHksXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZWRpdEd1aWxkU3RpY2tlcihndWlsZElkLCBzdGlja2VySWQsIGJvZHksIHJlYXNvbikge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucGF0Y2g8RGlzY29yZFN0aWNrZXI+KHJlc3Qucm91dGVzLmd1aWxkcy5zdGlja2VyKGd1aWxkSWQsIHN0aWNrZXJJZCksIHsgYm9keSwgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBlZGl0R3VpbGRUZW1wbGF0ZShndWlsZElkLCB0ZW1wbGF0ZUNvZGU6IHN0cmluZywgYm9keTogTW9kaWZ5R3VpbGRUZW1wbGF0ZSk6IFByb21pc2U8Q2FtZWxpemU8RGlzY29yZFRlbXBsYXRlPj4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucGF0Y2g8RGlzY29yZFRlbXBsYXRlPihyZXN0LnJvdXRlcy5ndWlsZHMudGVtcGxhdGVzLmd1aWxkKGd1aWxkSWQsIHRlbXBsYXRlQ29kZSksIHsgYm9keSB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZWRpdE1lc3NhZ2UoY2hhbm5lbElkLCBtZXNzYWdlSWQsIGJvZHkpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBhdGNoPERpc2NvcmRNZXNzYWdlPihyZXN0LnJvdXRlcy5jaGFubmVscy5tZXNzYWdlKGNoYW5uZWxJZCwgbWVzc2FnZUlkKSwgeyBib2R5LCBmaWxlczogYm9keS5maWxlcyB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZWRpdE9yaWdpbmFsSW50ZXJhY3Rpb25SZXNwb25zZSh0b2tlbiwgYm9keSkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucGF0Y2g8RGlzY29yZE1lc3NhZ2U+KHJlc3Qucm91dGVzLmludGVyYWN0aW9ucy5yZXNwb25zZXMub3JpZ2luYWwocmVzdC5hcHBsaWNhdGlvbklkLCB0b2tlbiksIHtcbiAgICAgICAgYm9keSxcbiAgICAgICAgZmlsZXM6IGJvZHkuZmlsZXMsXG4gICAgICAgIHVuYXV0aG9yaXplZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBlZGl0T3duVm9pY2VTdGF0ZShndWlsZElkLCBvcHRpb25zKSB7XG4gICAgICBhd2FpdCByZXN0LnBhdGNoKHJlc3Qucm91dGVzLmd1aWxkcy52b2ljZShndWlsZElkKSwge1xuICAgICAgICBib2R5OiB7XG4gICAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgICByZXF1ZXN0VG9TcGVha1RpbWVzdGFtcDogb3B0aW9ucy5yZXF1ZXN0VG9TcGVha1RpbWVzdGFtcFxuICAgICAgICAgICAgPyBuZXcgRGF0ZShvcHRpb25zLnJlcXVlc3RUb1NwZWFrVGltZXN0YW1wKS50b0lTT1N0cmluZygpXG4gICAgICAgICAgICA6IG9wdGlvbnMucmVxdWVzdFRvU3BlYWtUaW1lc3RhbXAsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZWRpdFNjaGVkdWxlZEV2ZW50KGd1aWxkSWQsIGV2ZW50SWQsIGJvZHksIHJlYXNvbikge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucGF0Y2g8RGlzY29yZFNjaGVkdWxlZEV2ZW50PihyZXN0LnJvdXRlcy5ndWlsZHMuZXZlbnRzLmV2ZW50KGd1aWxkSWQsIGV2ZW50SWQpLCB7IGJvZHksIHJlYXNvbiB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZWRpdFJvbGUoZ3VpbGRJZCwgcm9sZUlkLCBib2R5LCByZWFzb24pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBhdGNoPERpc2NvcmRSb2xlPihyZXN0LnJvdXRlcy5ndWlsZHMucm9sZXMub25lKGd1aWxkSWQsIHJvbGVJZCksIHsgYm9keSwgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBlZGl0Um9sZVBvc2l0aW9ucyhndWlsZElkLCBib2R5LCByZWFzb24pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBhdGNoPERpc2NvcmRSb2xlW10+KHJlc3Qucm91dGVzLmd1aWxkcy5yb2xlcy5hbGwoZ3VpbGRJZCksIHsgYm9keSwgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBlZGl0U3RhZ2VJbnN0YW5jZShjaGFubmVsSWQsIHRvcGljLCByZWFzb24/OiBzdHJpbmcpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBhdGNoPERpc2NvcmRTdGFnZUluc3RhbmNlPihyZXN0LnJvdXRlcy5jaGFubmVscy5zdGFnZShjaGFubmVsSWQpLCB7IGJvZHk6IHsgdG9waWMgfSwgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBlZGl0VXNlclZvaWNlU3RhdGUoZ3VpbGRJZCwgb3B0aW9ucykge1xuICAgICAgYXdhaXQgcmVzdC5wYXRjaChyZXN0LnJvdXRlcy5ndWlsZHMudm9pY2UoZ3VpbGRJZCwgb3B0aW9ucy51c2VySWQpLCB7IGJvZHk6IG9wdGlvbnMgfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGVkaXRXZWJob29rKHdlYmhvb2tJZCwgYm9keSwgcmVhc29uKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wYXRjaDxEaXNjb3JkV2ViaG9vaz4ocmVzdC5yb3V0ZXMud2ViaG9va3MuaWQod2ViaG9va0lkKSwgeyBib2R5LCByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGVkaXRXZWJob29rTWVzc2FnZSh3ZWJob29rSWQsIHRva2VuLCBtZXNzYWdlSWQsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBhdGNoPERpc2NvcmRNZXNzYWdlPihyZXN0LnJvdXRlcy53ZWJob29rcy5tZXNzYWdlKHdlYmhvb2tJZCwgdG9rZW4sIG1lc3NhZ2VJZCwgb3B0aW9ucyksIHtcbiAgICAgICAgYm9keTogb3B0aW9ucyxcbiAgICAgICAgZmlsZXM6IG9wdGlvbnMuZmlsZXMsXG4gICAgICAgIHVuYXV0aG9yaXplZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBlZGl0V2ViaG9va1dpdGhUb2tlbih3ZWJob29rSWQsIHRva2VuLCBib2R5KSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wYXRjaDxEaXNjb3JkV2ViaG9vaz4ocmVzdC5yb3V0ZXMud2ViaG9va3Mud2ViaG9vayh3ZWJob29rSWQsIHRva2VuKSwge1xuICAgICAgICBib2R5LFxuICAgICAgICB1bmF1dGhvcml6ZWQ6IHRydWUsXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZWRpdFdlbGNvbWVTY3JlZW4oZ3VpbGRJZCwgYm9keSwgcmVhc29uKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wYXRjaDxEaXNjb3JkV2VsY29tZVNjcmVlbj4ocmVzdC5yb3V0ZXMuZ3VpbGRzLndlbGNvbWUoZ3VpbGRJZCksIHsgYm9keSwgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBlZGl0V2lkZ2V0U2V0dGluZ3MoZ3VpbGRJZCwgYm9keSwgcmVhc29uKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wYXRjaDxEaXNjb3JkR3VpbGRXaWRnZXRTZXR0aW5ncz4ocmVzdC5yb3V0ZXMuZ3VpbGRzLndpZGdldChndWlsZElkKSwgeyBib2R5LCByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGV4ZWN1dGVXZWJob29rKHdlYmhvb2tJZCwgdG9rZW4sIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBvc3Q8RGlzY29yZE1lc3NhZ2U+KHJlc3Qucm91dGVzLndlYmhvb2tzLndlYmhvb2sod2ViaG9va0lkLCB0b2tlbiwgb3B0aW9ucyksIHtcbiAgICAgICAgYm9keTogb3B0aW9ucyxcbiAgICAgICAgdW5hdXRob3JpemVkOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGZvbGxvd0Fubm91bmNlbWVudChzb3VyY2VDaGFubmVsSWQsIHRhcmdldENoYW5uZWxJZCwgcmVhc29uKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wb3N0PERpc2NvcmRGb2xsb3dlZENoYW5uZWw+KHJlc3Qucm91dGVzLmNoYW5uZWxzLmZvbGxvdyhzb3VyY2VDaGFubmVsSWQpLCB7XG4gICAgICAgIGJvZHk6IHtcbiAgICAgICAgICB3ZWJob29rQ2hhbm5lbElkOiB0YXJnZXRDaGFubmVsSWQsXG4gICAgICAgIH0sXG4gICAgICAgIHJlYXNvbixcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRBY3RpdmVUaHJlYWRzKGd1aWxkSWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkTGlzdEFjdGl2ZVRocmVhZHM+KHJlc3Qucm91dGVzLmNoYW5uZWxzLnRocmVhZHMuYWN0aXZlKGd1aWxkSWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0QXBwbGljYXRpb25Db21tYW5kUGVybWlzc2lvbihndWlsZElkLCBjb21tYW5kSWQsIG9wdGlvbnMpIHtcbiAgICAgIGNvbnN0IHJlc3RPcHRpb25zOiBPbWl0PE1ha2VSZXF1ZXN0T3B0aW9ucywgJ2JvZHknPiA9IHt9O1xuXG4gICAgICBpZiAob3B0aW9ucz8uYWNjZXNzVG9rZW4pIHtcbiAgICAgICAgcmVzdE9wdGlvbnMudW5hdXRob3JpemVkID0gdHJ1ZTtcbiAgICAgICAgcmVzdE9wdGlvbnMuaGVhZGVycyA9IHtcbiAgICAgICAgICBhdXRob3JpemF0aW9uOiBgQmVhcmVyICR7b3B0aW9ucy5hY2Nlc3NUb2tlbn1gLFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZEd1aWxkQXBwbGljYXRpb25Db21tYW5kUGVybWlzc2lvbnM+KFxuICAgICAgICByZXN0LnJvdXRlcy5pbnRlcmFjdGlvbnMuY29tbWFuZHMucGVybWlzc2lvbihvcHRpb25zPy5hcHBsaWNhdGlvbklkID8/IHJlc3QuYXBwbGljYXRpb25JZCwgZ3VpbGRJZCwgY29tbWFuZElkKSxcbiAgICAgICAgcmVzdE9wdGlvbnMsXG4gICAgICApO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRBcHBsaWNhdGlvbkNvbW1hbmRQZXJtaXNzaW9ucyhndWlsZElkLCBvcHRpb25zKSB7XG4gICAgICBjb25zdCByZXN0T3B0aW9uczogT21pdDxNYWtlUmVxdWVzdE9wdGlvbnMsICdib2R5Jz4gPSB7fTtcblxuICAgICAgaWYgKG9wdGlvbnM/LmFjY2Vzc1Rva2VuKSB7XG4gICAgICAgIHJlc3RPcHRpb25zLnVuYXV0aG9yaXplZCA9IHRydWU7XG4gICAgICAgIHJlc3RPcHRpb25zLmhlYWRlcnMgPSB7XG4gICAgICAgICAgYXV0aG9yaXphdGlvbjogYEJlYXJlciAke29wdGlvbnMuYWNjZXNzVG9rZW59YCxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRHdWlsZEFwcGxpY2F0aW9uQ29tbWFuZFBlcm1pc3Npb25zW10+KFxuICAgICAgICByZXN0LnJvdXRlcy5pbnRlcmFjdGlvbnMuY29tbWFuZHMucGVybWlzc2lvbnMob3B0aW9ucz8uYXBwbGljYXRpb25JZCA/PyByZXN0LmFwcGxpY2F0aW9uSWQsIGd1aWxkSWQpLFxuICAgICAgICByZXN0T3B0aW9ucyxcbiAgICAgICk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldEFwcGxpY2F0aW9uSW5mbygpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkQXBwbGljYXRpb24+KHJlc3Qucm91dGVzLm9hdXRoMi5hcHBsaWNhdGlvbigpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZWRpdEFwcGxpY2F0aW9uSW5mbyhib2R5KSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wYXRjaDxEaXNjb3JkQXBwbGljYXRpb24+KHJlc3Qucm91dGVzLmFwcGxpY2F0aW9uKCksIHtcbiAgICAgICAgYm9keSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRDdXJyZW50QXV0aGVudGljYXRpb25JbmZvKHRva2VuKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZEN1cnJlbnRBdXRob3JpemF0aW9uPihyZXN0LnJvdXRlcy5vYXV0aDIuY3VycmVudEF1dGhvcml6YXRpb24oKSwge1xuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgYXV0aG9yaXphdGlvbjogYEJlYXJlciAke3Rva2VufWAsXG4gICAgICAgIH0sXG4gICAgICAgIHVuYXV0aG9yaXplZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBleGNoYW5nZVRva2VuKGNsaWVudElkLCBjbGllbnRTZWNyZXQsIGJvZHkpIHtcbiAgICAgIGNvbnN0IGJhc2ljQ3JlZGVudGlhbHMgPSBCdWZmZXIuZnJvbShgJHtjbGllbnRJZH06JHtjbGllbnRTZWNyZXR9YCk7XG5cbiAgICAgIGNvbnN0IHJlc3RPcHRpb25zOiBNYWtlUmVxdWVzdE9wdGlvbnMgPSB7XG4gICAgICAgIGJvZHksXG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcsXG4gICAgICAgICAgYXV0aG9yaXphdGlvbjogYEJhc2ljICR7YmFzaWNDcmVkZW50aWFscy50b1N0cmluZygnYmFzZTY0Jyl9YCxcbiAgICAgICAgfSxcbiAgICAgICAgcnVuVGhyb3VnaFF1ZXVlOiBmYWxzZSxcbiAgICAgICAgdW5hdXRob3JpemVkOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgaWYgKGJvZHkuZ3JhbnRUeXBlID09PSAnY2xpZW50X2NyZWRlbnRpYWxzJykge1xuICAgICAgICByZXN0T3B0aW9ucy5ib2R5LnNjb3BlID0gYm9keS5zY29wZS5qb2luKCcgJyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBvc3Q8RGlzY29yZEFjY2Vzc1Rva2VuUmVzcG9uc2U+KHJlc3Qucm91dGVzLm9hdXRoMi50b2tlbkV4Y2hhbmdlKCksIHJlc3RPcHRpb25zKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgcmV2b2tlVG9rZW4oY2xpZW50SWQsIGNsaWVudFNlY3JldCwgYm9keSkge1xuICAgICAgY29uc3QgYmFzaWNDcmVkZW50aWFscyA9IEJ1ZmZlci5mcm9tKGAke2NsaWVudElkfToke2NsaWVudFNlY3JldH1gKTtcblxuICAgICAgYXdhaXQgcmVzdC5wb3N0KHJlc3Qucm91dGVzLm9hdXRoMi50b2tlblJldm9rZSgpLCB7XG4gICAgICAgIGJvZHksXG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcsXG4gICAgICAgICAgYXV0aG9yaXphdGlvbjogYEJhc2ljICR7YmFzaWNDcmVkZW50aWFscy50b1N0cmluZygnYmFzZTY0Jyl9YCxcbiAgICAgICAgfSxcbiAgICAgICAgdW5hdXRob3JpemVkOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldEF1ZGl0TG9nKGd1aWxkSWQsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkQXVkaXRMb2c+KHJlc3Qucm91dGVzLmd1aWxkcy5hdWRpdGxvZ3MoZ3VpbGRJZCwgb3B0aW9ucykpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRBdXRvbW9kUnVsZShndWlsZElkLCBydWxlSWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkQXV0b01vZGVyYXRpb25SdWxlPihyZXN0LnJvdXRlcy5ndWlsZHMuYXV0b21vZC5ydWxlKGd1aWxkSWQsIHJ1bGVJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRBdXRvbW9kUnVsZXMoZ3VpbGRJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRBdXRvTW9kZXJhdGlvblJ1bGVbXT4ocmVzdC5yb3V0ZXMuZ3VpbGRzLmF1dG9tb2QucnVsZXMoZ3VpbGRJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRBdmFpbGFibGVWb2ljZVJlZ2lvbnMoKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZFZvaWNlUmVnaW9uW10+KHJlc3Qucm91dGVzLnJlZ2lvbnMoKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldEJhbihndWlsZElkLCB1c2VySWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkQmFuPihyZXN0LnJvdXRlcy5ndWlsZHMubWVtYmVycy5iYW4oZ3VpbGRJZCwgdXNlcklkKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldEJhbnMoZ3VpbGRJZCwgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRCYW5bXT4ocmVzdC5yb3V0ZXMuZ3VpbGRzLm1lbWJlcnMuYmFucyhndWlsZElkLCBvcHRpb25zKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldENoYW5uZWwoaWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkQ2hhbm5lbD4ocmVzdC5yb3V0ZXMuY2hhbm5lbHMuY2hhbm5lbChpZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRDaGFubmVsSW52aXRlcyhjaGFubmVsSWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkSW52aXRlTWV0YWRhdGFbXT4ocmVzdC5yb3V0ZXMuY2hhbm5lbHMuaW52aXRlcyhjaGFubmVsSWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0Q2hhbm5lbHMoZ3VpbGRJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRDaGFubmVsW10+KHJlc3Qucm91dGVzLmd1aWxkcy5jaGFubmVscyhndWlsZElkKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldENoYW5uZWxXZWJob29rcyhjaGFubmVsSWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkV2ViaG9va1tdPihyZXN0LnJvdXRlcy5jaGFubmVscy53ZWJob29rcyhjaGFubmVsSWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0RG1DaGFubmVsKHVzZXJJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucG9zdDxEaXNjb3JkQ2hhbm5lbD4ocmVzdC5yb3V0ZXMuY2hhbm5lbHMuZG0oKSwge1xuICAgICAgICBib2R5OiB7IHJlY2lwaWVudElkOiB1c2VySWQgfSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRHcm91cERtQ2hhbm5lbChib2R5KSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wb3N0PERpc2NvcmRDaGFubmVsPihyZXN0LnJvdXRlcy5jaGFubmVscy5kbSgpLCB7XG4gICAgICAgIGJvZHksXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0RW1vamkoZ3VpbGRJZCwgZW1vamlJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRFbW9qaT4ocmVzdC5yb3V0ZXMuZ3VpbGRzLmVtb2ppKGd1aWxkSWQsIGVtb2ppSWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0QXBwbGljYXRpb25FbW9qaShlbW9qaUlkKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZEVtb2ppPihyZXN0LnJvdXRlcy5hcHBsaWNhdGlvbkVtb2ppKHJlc3QuYXBwbGljYXRpb25JZCwgZW1vamlJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRFbW9qaXMoZ3VpbGRJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRFbW9qaVtdPihyZXN0LnJvdXRlcy5ndWlsZHMuZW1vamlzKGd1aWxkSWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0QXBwbGljYXRpb25FbW9qaXMoKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8eyBpdGVtczogRGlzY29yZEVtb2ppW10gfT4ocmVzdC5yb3V0ZXMuYXBwbGljYXRpb25FbW9qaXMocmVzdC5hcHBsaWNhdGlvbklkKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldEZvbGxvd3VwTWVzc2FnZSh0b2tlbiwgbWVzc2FnZUlkKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZE1lc3NhZ2U+KHJlc3Qucm91dGVzLmludGVyYWN0aW9ucy5yZXNwb25zZXMubWVzc2FnZShyZXN0LmFwcGxpY2F0aW9uSWQsIHRva2VuLCBtZXNzYWdlSWQpLCB7IHVuYXV0aG9yaXplZDogdHJ1ZSB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0R2F0ZXdheUJvdCgpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkR2V0R2F0ZXdheUJvdD4ocmVzdC5yb3V0ZXMuZ2F0ZXdheUJvdCgpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0R2xvYmFsQXBwbGljYXRpb25Db21tYW5kKGNvbW1hbmRJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRBcHBsaWNhdGlvbkNvbW1hbmQ+KHJlc3Qucm91dGVzLmludGVyYWN0aW9ucy5jb21tYW5kcy5jb21tYW5kKHJlc3QuYXBwbGljYXRpb25JZCwgY29tbWFuZElkKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldEdsb2JhbEFwcGxpY2F0aW9uQ29tbWFuZHMob3B0aW9ucykge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRBcHBsaWNhdGlvbkNvbW1hbmRbXT4ocmVzdC5yb3V0ZXMuaW50ZXJhY3Rpb25zLmNvbW1hbmRzLmNvbW1hbmRzKHJlc3QuYXBwbGljYXRpb25JZCwgb3B0aW9ucz8ud2l0aExvY2FsaXphdGlvbnMpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0R3VpbGQoZ3VpbGRJZCwgb3B0aW9ucyA9IHsgY291bnRzOiB0cnVlIH0pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkR3VpbGQ+KHJlc3Qucm91dGVzLmd1aWxkcy5ndWlsZChndWlsZElkLCBvcHRpb25zLmNvdW50cykpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRHdWlsZHModG9rZW4sIG9wdGlvbnMpIHtcbiAgICAgIGNvbnN0IG1ha2VSZXF1ZXN0T3B0aW9uczogTWFrZVJlcXVlc3RPcHRpb25zIHwgdW5kZWZpbmVkID0gdG9rZW5cbiAgICAgICAgPyB7XG4gICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgIGF1dGhvcml6YXRpb246IGBCZWFyZXIgJHt0b2tlbn1gLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHVuYXV0aG9yaXplZDogdHJ1ZSxcbiAgICAgICAgICB9XG4gICAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8UGFydGlhbDxEaXNjb3JkR3VpbGQ+W10+KHJlc3Qucm91dGVzLmd1aWxkcy51c2VyR3VpbGRzKG9wdGlvbnMpLCBtYWtlUmVxdWVzdE9wdGlvbnMpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRHdWlsZEFwcGxpY2F0aW9uQ29tbWFuZChjb21tYW5kSWQsIGd1aWxkSWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkQXBwbGljYXRpb25Db21tYW5kPihyZXN0LnJvdXRlcy5pbnRlcmFjdGlvbnMuY29tbWFuZHMuZ3VpbGRzLm9uZShyZXN0LmFwcGxpY2F0aW9uSWQsIGd1aWxkSWQsIGNvbW1hbmRJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRHdWlsZEFwcGxpY2F0aW9uQ29tbWFuZHMoZ3VpbGRJZCwgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRBcHBsaWNhdGlvbkNvbW1hbmRbXT4oXG4gICAgICAgIHJlc3Qucm91dGVzLmludGVyYWN0aW9ucy5jb21tYW5kcy5ndWlsZHMuYWxsKHJlc3QuYXBwbGljYXRpb25JZCwgZ3VpbGRJZCwgb3B0aW9ucz8ud2l0aExvY2FsaXphdGlvbnMpLFxuICAgICAgKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0R3VpbGRQcmV2aWV3KGd1aWxkSWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkR3VpbGRQcmV2aWV3PihyZXN0LnJvdXRlcy5ndWlsZHMucHJldmlldyhndWlsZElkKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldEd1aWxkVGVtcGxhdGUodGVtcGxhdGVDb2RlKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZFRlbXBsYXRlPihyZXN0LnJvdXRlcy5ndWlsZHMudGVtcGxhdGVzLmNvZGUodGVtcGxhdGVDb2RlKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldEd1aWxkVGVtcGxhdGVzKGd1aWxkSWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkVGVtcGxhdGVbXT4ocmVzdC5yb3V0ZXMuZ3VpbGRzLnRlbXBsYXRlcy5hbGwoZ3VpbGRJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRHdWlsZFdlYmhvb2tzKGd1aWxkSWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkV2ViaG9va1tdPihyZXN0LnJvdXRlcy5ndWlsZHMud2ViaG9va3MoZ3VpbGRJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRJbnRlZ3JhdGlvbnMoZ3VpbGRJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRJbnRlZ3JhdGlvbltdPihyZXN0LnJvdXRlcy5ndWlsZHMuaW50ZWdyYXRpb25zKGd1aWxkSWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0SW52aXRlKGludml0ZUNvZGUsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkSW52aXRlTWV0YWRhdGE+KHJlc3Qucm91dGVzLmd1aWxkcy5pbnZpdGUoaW52aXRlQ29kZSwgb3B0aW9ucykpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRJbnZpdGVzKGd1aWxkSWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkSW52aXRlTWV0YWRhdGFbXT4ocmVzdC5yb3V0ZXMuZ3VpbGRzLmludml0ZXMoZ3VpbGRJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRNZXNzYWdlKGNoYW5uZWxJZCwgbWVzc2FnZUlkKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZE1lc3NhZ2U+KHJlc3Qucm91dGVzLmNoYW5uZWxzLm1lc3NhZ2UoY2hhbm5lbElkLCBtZXNzYWdlSWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0TWVzc2FnZXMoY2hhbm5lbElkLCBvcHRpb25zKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZE1lc3NhZ2VbXT4ocmVzdC5yb3V0ZXMuY2hhbm5lbHMubWVzc2FnZXMoY2hhbm5lbElkLCBvcHRpb25zKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIHNlYXJjaEd1aWxkTWVzc2FnZXMoZ3VpbGRJZCwgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRTZWFyY2hHdWlsZE1lc3NhZ2VzIHwgRGlzY29yZFNlYXJjaEd1aWxkTWVzc2FnZXNJbmRleGluZz4ocmVzdC5yb3V0ZXMuZ3VpbGRzLm1lc3NhZ2VzU2VhcmNoKGd1aWxkSWQsIG9wdGlvbnMpKTtcbiAgICB9LFxuICAgIGFzeW5jIGdldFN0aWNrZXJQYWNrKHN0aWNrZXJQYWNrSWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkU3RpY2tlclBhY2s+KHJlc3Qucm91dGVzLnN0aWNrZXJQYWNrKHN0aWNrZXJQYWNrSWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0U3RpY2tlclBhY2tzKCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRTdGlja2VyUGFja1tdPihyZXN0LnJvdXRlcy5zdGlja2VyUGFja3MoKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldE9yaWdpbmFsSW50ZXJhY3Rpb25SZXNwb25zZSh0b2tlbikge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRNZXNzYWdlPihyZXN0LnJvdXRlcy5pbnRlcmFjdGlvbnMucmVzcG9uc2VzLm9yaWdpbmFsKHJlc3QuYXBwbGljYXRpb25JZCwgdG9rZW4pLCB7IHVuYXV0aG9yaXplZDogdHJ1ZSB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0Q2hhbm5lbFBpbnMoY2hhbm5lbElkLCBvcHRpb25zKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQocmVzdC5yb3V0ZXMuY2hhbm5lbHMubWVzc2FnZVBpbnMoY2hhbm5lbElkLCBvcHRpb25zKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldFBpbm5lZE1lc3NhZ2VzKGNoYW5uZWxJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRNZXNzYWdlW10+KHJlc3Qucm91dGVzLmNoYW5uZWxzLnBpbnMoY2hhbm5lbElkKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldFByaXZhdGVBcmNoaXZlZFRocmVhZHMoY2hhbm5lbElkLCBvcHRpb25zKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZExpc3RBcmNoaXZlZFRocmVhZHM+KHJlc3Qucm91dGVzLmNoYW5uZWxzLnRocmVhZHMucHJpdmF0ZShjaGFubmVsSWQsIG9wdGlvbnMpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0UHJpdmF0ZUpvaW5lZEFyY2hpdmVkVGhyZWFkcyhjaGFubmVsSWQsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkTGlzdEFyY2hpdmVkVGhyZWFkcz4ocmVzdC5yb3V0ZXMuY2hhbm5lbHMudGhyZWFkcy5qb2luZWQoY2hhbm5lbElkLCBvcHRpb25zKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldFBydW5lQ291bnQoZ3VpbGRJZCwgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRQcnVuZWRDb3VudD4ocmVzdC5yb3V0ZXMuZ3VpbGRzLnBydW5lKGd1aWxkSWQsIG9wdGlvbnMpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0UHVibGljQXJjaGl2ZWRUaHJlYWRzKGNoYW5uZWxJZCwgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRMaXN0QXJjaGl2ZWRUaHJlYWRzPihyZXN0LnJvdXRlcy5jaGFubmVscy50aHJlYWRzLnB1YmxpYyhjaGFubmVsSWQsIG9wdGlvbnMpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0Um9sZXMoZ3VpbGRJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRSb2xlW10+KHJlc3Qucm91dGVzLmd1aWxkcy5yb2xlcy5hbGwoZ3VpbGRJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRSb2xlKGd1aWxkSWQsIHJvbGVJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRSb2xlPihyZXN0LnJvdXRlcy5ndWlsZHMucm9sZXMub25lKGd1aWxkSWQsIHJvbGVJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRTY2hlZHVsZWRFdmVudChndWlsZElkLCBldmVudElkLCBvcHRpb25zKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZFNjaGVkdWxlZEV2ZW50PihyZXN0LnJvdXRlcy5ndWlsZHMuZXZlbnRzLmV2ZW50KGd1aWxkSWQsIGV2ZW50SWQsIG9wdGlvbnM/LndpdGhVc2VyQ291bnQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0U2NoZWR1bGVkRXZlbnRzKGd1aWxkSWQsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkU2NoZWR1bGVkRXZlbnRbXT4ocmVzdC5yb3V0ZXMuZ3VpbGRzLmV2ZW50cy5ldmVudHMoZ3VpbGRJZCwgb3B0aW9ucz8ud2l0aFVzZXJDb3VudCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRTY2hlZHVsZWRFdmVudFVzZXJzKGd1aWxkSWQsIGV2ZW50SWQsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxBcnJheTx7IHVzZXI6IERpc2NvcmRVc2VyOyBtZW1iZXI/OiBEaXNjb3JkTWVtYmVyIH0+PihyZXN0LnJvdXRlcy5ndWlsZHMuZXZlbnRzLnVzZXJzKGd1aWxkSWQsIGV2ZW50SWQsIG9wdGlvbnMpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0U2Vzc2lvbkluZm8oKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXRHYXRld2F5Qm90KCk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldFN0YWdlSW5zdGFuY2UoY2hhbm5lbElkKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZFN0YWdlSW5zdGFuY2U+KHJlc3Qucm91dGVzLmNoYW5uZWxzLnN0YWdlKGNoYW5uZWxJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRPd25Wb2ljZVN0YXRlKGd1aWxkSWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkVm9pY2VTdGF0ZT4ocmVzdC5yb3V0ZXMuZ3VpbGRzLnZvaWNlKGd1aWxkSWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0VXNlclZvaWNlU3RhdGUoZ3VpbGRJZCwgdXNlcklkKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZFZvaWNlU3RhdGU+KHJlc3Qucm91dGVzLmd1aWxkcy52b2ljZShndWlsZElkLCB1c2VySWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0U3RpY2tlcihzdGlja2VySWQ6IEJpZ1N0cmluZykge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRTdGlja2VyPihyZXN0LnJvdXRlcy5zdGlja2VyKHN0aWNrZXJJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRHdWlsZFN0aWNrZXIoZ3VpbGRJZCwgc3RpY2tlcklkKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZFN0aWNrZXI+KHJlc3Qucm91dGVzLmd1aWxkcy5zdGlja2VyKGd1aWxkSWQsIHN0aWNrZXJJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRHdWlsZFN0aWNrZXJzKGd1aWxkSWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkU3RpY2tlcltdPihyZXN0LnJvdXRlcy5ndWlsZHMuc3RpY2tlcnMoZ3VpbGRJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRUaHJlYWRNZW1iZXIoY2hhbm5lbElkLCB1c2VySWQsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkVGhyZWFkTWVtYmVyPihyZXN0LnJvdXRlcy5jaGFubmVscy50aHJlYWRzLmdldFVzZXIoY2hhbm5lbElkLCB1c2VySWQsIG9wdGlvbnMpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0VGhyZWFkTWVtYmVycyhjaGFubmVsSWQsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkVGhyZWFkTWVtYmVyW10+KHJlc3Qucm91dGVzLmNoYW5uZWxzLnRocmVhZHMubWVtYmVycyhjaGFubmVsSWQsIG9wdGlvbnMpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0UmVhY3Rpb25zKGNoYW5uZWxJZCwgbWVzc2FnZUlkLCByZWFjdGlvbiwgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRVc2VyW10+KHJlc3Qucm91dGVzLmNoYW5uZWxzLnJlYWN0aW9ucy5tZXNzYWdlKGNoYW5uZWxJZCwgbWVzc2FnZUlkLCByZWFjdGlvbiwgb3B0aW9ucykpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRVc2VyKGlkKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZFVzZXI+KHJlc3Qucm91dGVzLnVzZXIoaWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0Q3VycmVudFVzZXIodG9rZW4pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkVXNlcj4ocmVzdC5yb3V0ZXMuY3VycmVudFVzZXIoKSwge1xuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgYXV0aG9yaXphdGlvbjogYEJlYXJlciAke3Rva2VufWAsXG4gICAgICAgIH0sXG4gICAgICAgIHVuYXV0aG9yaXplZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRVc2VyQ29ubmVjdGlvbnModG9rZW4pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkQ29ubmVjdGlvbltdPihyZXN0LnJvdXRlcy5vYXV0aDIuY29ubmVjdGlvbnMoKSwge1xuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgYXV0aG9yaXphdGlvbjogYEJlYXJlciAke3Rva2VufWAsXG4gICAgICAgIH0sXG4gICAgICAgIHVuYXV0aG9yaXplZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRVc2VyQXBwbGljYXRpb25Sb2xlQ29ubmVjdGlvbih0b2tlbiwgYXBwbGljYXRpb25JZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRBcHBsaWNhdGlvblJvbGVDb25uZWN0aW9uPihyZXN0LnJvdXRlcy5vYXV0aDIucm9sZUNvbm5lY3Rpb25zKGFwcGxpY2F0aW9uSWQpLCB7XG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICBhdXRob3JpemF0aW9uOiBgQmVhcmVyICR7dG9rZW59YCxcbiAgICAgICAgfSxcbiAgICAgICAgdW5hdXRob3JpemVkOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldFZhbml0eVVybChndWlsZElkKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZFZhbml0eVVybD4ocmVzdC5yb3V0ZXMuZ3VpbGRzLnZhbml0eShndWlsZElkKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldFZvaWNlUmVnaW9ucyhndWlsZElkKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZFZvaWNlUmVnaW9uW10+KHJlc3Qucm91dGVzLmd1aWxkcy5yZWdpb25zKGd1aWxkSWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0V2ViaG9vayh3ZWJob29rSWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkV2ViaG9vaz4ocmVzdC5yb3V0ZXMud2ViaG9va3MuaWQod2ViaG9va0lkKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldFdlYmhvb2tNZXNzYWdlKHdlYmhvb2tJZCwgdG9rZW4sIG1lc3NhZ2VJZCwgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRNZXNzYWdlPihyZXN0LnJvdXRlcy53ZWJob29rcy5tZXNzYWdlKHdlYmhvb2tJZCwgdG9rZW4sIG1lc3NhZ2VJZCwgb3B0aW9ucyksIHtcbiAgICAgICAgdW5hdXRob3JpemVkOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldFdlYmhvb2tXaXRoVG9rZW4od2ViaG9va0lkLCB0b2tlbikge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRXZWJob29rPihyZXN0LnJvdXRlcy53ZWJob29rcy53ZWJob29rKHdlYmhvb2tJZCwgdG9rZW4pLCB7XG4gICAgICAgIHVuYXV0aG9yaXplZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRXZWxjb21lU2NyZWVuKGd1aWxkSWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkV2VsY29tZVNjcmVlbj4ocmVzdC5yb3V0ZXMuZ3VpbGRzLndlbGNvbWUoZ3VpbGRJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRXaWRnZXQoZ3VpbGRJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRHdWlsZFdpZGdldD4ocmVzdC5yb3V0ZXMuZ3VpbGRzLndpZGdldEpzb24oZ3VpbGRJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRXaWRnZXRTZXR0aW5ncyhndWlsZElkKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZEd1aWxkV2lkZ2V0U2V0dGluZ3M+KHJlc3Qucm91dGVzLmd1aWxkcy53aWRnZXQoZ3VpbGRJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBqb2luVGhyZWFkKGNoYW5uZWxJZCkge1xuICAgICAgYXdhaXQgcmVzdC5wdXQocmVzdC5yb3V0ZXMuY2hhbm5lbHMudGhyZWFkcy5tZShjaGFubmVsSWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgbGVhdmVHdWlsZChndWlsZElkKSB7XG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5ndWlsZHMubGVhdmUoZ3VpbGRJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBsZWF2ZVRocmVhZChjaGFubmVsSWQpIHtcbiAgICAgIGF3YWl0IHJlc3QuZGVsZXRlKHJlc3Qucm91dGVzLmNoYW5uZWxzLnRocmVhZHMubWUoY2hhbm5lbElkKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIHB1Ymxpc2hNZXNzYWdlKGNoYW5uZWxJZCwgbWVzc2FnZUlkKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wb3N0PERpc2NvcmRNZXNzYWdlPihyZXN0LnJvdXRlcy5jaGFubmVscy5jcm9zc3Bvc3QoY2hhbm5lbElkLCBtZXNzYWdlSWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgcmVtb3ZlUm9sZShndWlsZElkLCB1c2VySWQsIHJvbGVJZCwgcmVhc29uKSB7XG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5ndWlsZHMucm9sZXMubWVtYmVyKGd1aWxkSWQsIHVzZXJJZCwgcm9sZUlkKSwgeyByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIHJlbW92ZVRocmVhZE1lbWJlcihjaGFubmVsSWQsIHVzZXJJZCkge1xuICAgICAgYXdhaXQgcmVzdC5kZWxldGUocmVzdC5yb3V0ZXMuY2hhbm5lbHMudGhyZWFkcy51c2VyKGNoYW5uZWxJZCwgdXNlcklkKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIHJlbW92ZURtUmVjaXBpZW50KGNoYW5uZWxJZCwgdXNlcklkKSB7XG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5jaGFubmVscy5kbVJlY2lwaWVudChjaGFubmVsSWQsIHVzZXJJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBzZW5kRm9sbG93dXBNZXNzYWdlKHRva2VuLCBvcHRpb25zKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wb3N0KHJlc3Qucm91dGVzLndlYmhvb2tzLndlYmhvb2socmVzdC5hcHBsaWNhdGlvbklkLCB0b2tlbiksIHtcbiAgICAgICAgYm9keTogb3B0aW9ucyxcbiAgICAgICAgZmlsZXM6IG9wdGlvbnMuZmlsZXMsXG4gICAgICAgIHVuYXV0aG9yaXplZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBzZW5kSW50ZXJhY3Rpb25SZXNwb25zZShpbnRlcmFjdGlvbklkLCB0b2tlbiwgb3B0aW9ucywgcGFyYW1zKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wb3N0PHZvaWQgfCBEaXNjb3JkSW50ZXJhY3Rpb25DYWxsYmFja1Jlc3BvbnNlPihyZXN0LnJvdXRlcy5pbnRlcmFjdGlvbnMucmVzcG9uc2VzLmNhbGxiYWNrKGludGVyYWN0aW9uSWQsIHRva2VuLCBwYXJhbXMpLCB7XG4gICAgICAgIGJvZHk6IG9wdGlvbnMsXG4gICAgICAgIGZpbGVzOiBvcHRpb25zLmRhdGE/LmZpbGVzLFxuICAgICAgICBydW5UaHJvdWdoUXVldWU6IGZhbHNlLFxuICAgICAgICB1bmF1dGhvcml6ZWQ6IHRydWUsXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgc2VuZE1lc3NhZ2UoY2hhbm5lbElkLCBib2R5KSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wb3N0PERpc2NvcmRNZXNzYWdlPihyZXN0LnJvdXRlcy5jaGFubmVscy5tZXNzYWdlcyhjaGFubmVsSWQpLCB7IGJvZHksIGZpbGVzOiBib2R5LmZpbGVzIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBzdGFydFRocmVhZFdpdGhNZXNzYWdlKGNoYW5uZWxJZCwgbWVzc2FnZUlkLCBib2R5LCByZWFzb24pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBvc3Q8RGlzY29yZENoYW5uZWw+KHJlc3Qucm91dGVzLmNoYW5uZWxzLnRocmVhZHMubWVzc2FnZShjaGFubmVsSWQsIG1lc3NhZ2VJZCksIHsgYm9keSwgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBzdGFydFRocmVhZFdpdGhvdXRNZXNzYWdlKGNoYW5uZWxJZCwgYm9keSwgcmVhc29uKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wb3N0PERpc2NvcmRDaGFubmVsPihyZXN0LnJvdXRlcy5jaGFubmVscy50aHJlYWRzLmFsbChjaGFubmVsSWQpLCB7IGJvZHksIHJlYXNvbiB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0UG9sbEFuc3dlclZvdGVycyhjaGFubmVsSWQsIG1lc3NhZ2VJZCwgYW5zd2VySWQsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkR2V0QW5zd2VyVm90ZXNSZXNwb25zZT4ocmVzdC5yb3V0ZXMuY2hhbm5lbHMucG9sbHMudm90ZXMoY2hhbm5lbElkLCBtZXNzYWdlSWQsIGFuc3dlcklkLCBvcHRpb25zKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGVuZFBvbGwoY2hhbm5lbElkLCBtZXNzYWdlSWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBvc3Q8RGlzY29yZE1lc3NhZ2U+KHJlc3Qucm91dGVzLmNoYW5uZWxzLnBvbGxzLmV4cGlyZShjaGFubmVsSWQsIG1lc3NhZ2VJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBzeW5jR3VpbGRUZW1wbGF0ZShndWlsZElkKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wdXQ8RGlzY29yZFRlbXBsYXRlPihyZXN0LnJvdXRlcy5ndWlsZHMudGVtcGxhdGVzLmFsbChndWlsZElkKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGJhbk1lbWJlcihndWlsZElkLCB1c2VySWQsIGJvZHksIHJlYXNvbikge1xuICAgICAgYXdhaXQgcmVzdC5wdXQ8dm9pZD4ocmVzdC5yb3V0ZXMuZ3VpbGRzLm1lbWJlcnMuYmFuKGd1aWxkSWQsIHVzZXJJZCksIHsgYm9keSwgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBidWxrQmFuTWVtYmVycyhndWlsZElkLCBvcHRpb25zLCByZWFzb24pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBvc3Q8RGlzY29yZEJ1bGtCYW4+KHJlc3Qucm91dGVzLmd1aWxkcy5tZW1iZXJzLmJ1bGtCYW4oZ3VpbGRJZCksIHsgYm9keTogb3B0aW9ucywgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBlZGl0Q3VycmVudE1lbWJlcihndWlsZElkLCBib2R5LCByZWFzb24pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBhdGNoPERpc2NvcmRNZW1iZXI+KHJlc3Qucm91dGVzLmd1aWxkcy5tZW1iZXJzLmJvdChndWlsZElkKSwgeyBib2R5LCByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGVkaXRNZW1iZXIoZ3VpbGRJZCwgdXNlcklkLCBib2R5LCByZWFzb24pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBhdGNoPERpc2NvcmRNZW1iZXJXaXRoVXNlcj4ocmVzdC5yb3V0ZXMuZ3VpbGRzLm1lbWJlcnMubWVtYmVyKGd1aWxkSWQsIHVzZXJJZCksIHsgYm9keSwgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRDdXJyZW50TWVtYmVyKGd1aWxkSWQsIHRva2VuKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZE1lbWJlcldpdGhVc2VyPihyZXN0LnJvdXRlcy5ndWlsZHMubWVtYmVycy5jdXJyZW50TWVtYmVyKGd1aWxkSWQpLCB7XG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICBhdXRob3JpemF0aW9uOiBgQmVhcmVyICR7dG9rZW59YCxcbiAgICAgICAgfSxcbiAgICAgICAgdW5hdXRob3JpemVkOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldE1lbWJlcihndWlsZElkLCB1c2VySWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkTWVtYmVyV2l0aFVzZXI+KHJlc3Qucm91dGVzLmd1aWxkcy5tZW1iZXJzLm1lbWJlcihndWlsZElkLCB1c2VySWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0TWVtYmVycyhndWlsZElkLCBvcHRpb25zKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZE1lbWJlcldpdGhVc2VyW10+KHJlc3Qucm91dGVzLmd1aWxkcy5tZW1iZXJzLm1lbWJlcnMoZ3VpbGRJZCwgb3B0aW9ucykpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRBcHBsaWNhdGlvbkFjdGl2aXR5SW5zdGFuY2UoYXBwbGljYXRpb25JZCwgaW5zdGFuY2VJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRBY3Rpdml0eUluc3RhbmNlPihyZXN0LnJvdXRlcy5hcHBsaWNhdGlvbkFjdGl2aXR5SW5zdGFuY2UoYXBwbGljYXRpb25JZCwgaW5zdGFuY2VJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBraWNrTWVtYmVyKGd1aWxkSWQsIHVzZXJJZCwgcmVhc29uKSB7XG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5ndWlsZHMubWVtYmVycy5tZW1iZXIoZ3VpbGRJZCwgdXNlcklkKSwge1xuICAgICAgICByZWFzb24sXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgcGluTWVzc2FnZShjaGFubmVsSWQsIG1lc3NhZ2VJZCwgcmVhc29uKSB7XG4gICAgICBhd2FpdCByZXN0LnB1dChyZXN0LnJvdXRlcy5jaGFubmVscy5tZXNzYWdlUGluKGNoYW5uZWxJZCwgbWVzc2FnZUlkKSwgeyByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIHBydW5lTWVtYmVycyhndWlsZElkLCBib2R5LCByZWFzb24pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBvc3Q8eyBwcnVuZWQ6IG51bWJlciB8IG51bGwgfT4ocmVzdC5yb3V0ZXMuZ3VpbGRzLm1lbWJlcnMucHJ1bmUoZ3VpbGRJZCksIHsgYm9keSwgcmVhc29uIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBzZWFyY2hNZW1iZXJzKGd1aWxkSWQsIHF1ZXJ5LCBvcHRpb25zKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZE1lbWJlcldpdGhVc2VyW10+KHJlc3Qucm91dGVzLmd1aWxkcy5tZW1iZXJzLnNlYXJjaChndWlsZElkLCBxdWVyeSwgb3B0aW9ucykpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRHdWlsZE9uYm9hcmRpbmcoZ3VpbGRJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRHdWlsZE9uYm9hcmRpbmc+KHJlc3Qucm91dGVzLmd1aWxkcy5vbmJvYXJkaW5nKGd1aWxkSWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZWRpdEd1aWxkT25ib2FyZGluZyhndWlsZElkLCBvcHRpb25zLCByZWFzb24pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnB1dDxEaXNjb3JkR3VpbGRPbmJvYXJkaW5nPihyZXN0LnJvdXRlcy5ndWlsZHMub25ib2FyZGluZyhndWlsZElkKSwge1xuICAgICAgICBib2R5OiBvcHRpb25zLFxuICAgICAgICByZWFzb24sXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgbW9kaWZ5R3VpbGRJbmNpZGVudEFjdGlvbnMoZ3VpbGRJZCwgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucHV0PERpc2NvcmRJbmNpZGVudHNEYXRhPihyZXN0LnJvdXRlcy5ndWlsZHMuaW5jaWRlbnRBY3Rpb25zKGd1aWxkSWQpLCB7IGJvZHk6IG9wdGlvbnMgfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIHVuYmFuTWVtYmVyKGd1aWxkSWQsIHVzZXJJZCwgcmVhc29uKSB7XG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5ndWlsZHMubWVtYmVycy5iYW4oZ3VpbGRJZCwgdXNlcklkKSwgeyByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIHVucGluTWVzc2FnZShjaGFubmVsSWQsIG1lc3NhZ2VJZCwgcmVhc29uKSB7XG4gICAgICBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5jaGFubmVscy5tZXNzYWdlUGluKGNoYW5uZWxJZCwgbWVzc2FnZUlkKSwgeyByZWFzb24gfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIHRyaWdnZXJUeXBpbmdJbmRpY2F0b3IoY2hhbm5lbElkKSB7XG4gICAgICBhd2FpdCByZXN0LnBvc3QocmVzdC5yb3V0ZXMuY2hhbm5lbHMudHlwaW5nKGNoYW5uZWxJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyB1cHNlcnRHbG9iYWxBcHBsaWNhdGlvbkNvbW1hbmRzKGJvZHksIG9wdGlvbnMpIHtcbiAgICAgIGNvbnN0IHJlc3RPcHRpb25zOiBNYWtlUmVxdWVzdE9wdGlvbnMgPSB7IGJvZHkgfTtcblxuICAgICAgaWYgKG9wdGlvbnM/LmJlYXJlclRva2VuKSB7XG4gICAgICAgIHJlc3RPcHRpb25zLnVuYXV0aG9yaXplZCA9IHRydWU7XG4gICAgICAgIHJlc3RPcHRpb25zLmhlYWRlcnMgPSB7XG4gICAgICAgICAgYXV0aG9yaXphdGlvbjogYEJlYXJlciAke29wdGlvbnMuYmVhcmVyVG9rZW59YCxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucHV0PERpc2NvcmRBcHBsaWNhdGlvbkNvbW1hbmRbXT4ocmVzdC5yb3V0ZXMuaW50ZXJhY3Rpb25zLmNvbW1hbmRzLmNvbW1hbmRzKHJlc3QuYXBwbGljYXRpb25JZCksIHJlc3RPcHRpb25zKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgdXBzZXJ0R3VpbGRBcHBsaWNhdGlvbkNvbW1hbmRzKGd1aWxkSWQsIGJvZHksIG9wdGlvbnMpIHtcbiAgICAgIGNvbnN0IHJlc3RPcHRpb25zOiBNYWtlUmVxdWVzdE9wdGlvbnMgPSB7IGJvZHkgfTtcblxuICAgICAgaWYgKG9wdGlvbnM/LmJlYXJlclRva2VuKSB7XG4gICAgICAgIHJlc3RPcHRpb25zLnVuYXV0aG9yaXplZCA9IHRydWU7XG4gICAgICAgIHJlc3RPcHRpb25zLmhlYWRlcnMgPSB7XG4gICAgICAgICAgYXV0aG9yaXphdGlvbjogYEJlYXJlciAke29wdGlvbnMuYmVhcmVyVG9rZW59YCxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucHV0PERpc2NvcmRBcHBsaWNhdGlvbkNvbW1hbmRbXT4ocmVzdC5yb3V0ZXMuaW50ZXJhY3Rpb25zLmNvbW1hbmRzLmd1aWxkcy5hbGwocmVzdC5hcHBsaWNhdGlvbklkLCBndWlsZElkKSwgcmVzdE9wdGlvbnMpO1xuICAgIH0sXG5cbiAgICBhc3luYyBlZGl0VXNlckFwcGxpY2F0aW9uUm9sZUNvbm5lY3Rpb24odG9rZW4sIGFwcGxpY2F0aW9uSWQsIGJvZHkpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnB1dDxEaXNjb3JkQXBwbGljYXRpb25Sb2xlQ29ubmVjdGlvbj4ocmVzdC5yb3V0ZXMub2F1dGgyLnJvbGVDb25uZWN0aW9ucyhhcHBsaWNhdGlvbklkKSwge1xuICAgICAgICBib2R5LFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgYXV0aG9yaXphdGlvbjogYEJlYXJlciAke3Rva2VufWAsXG4gICAgICAgIH0sXG4gICAgICAgIHVuYXV0aG9yaXplZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGVDdXJyZW50VXNlckFwcGxpY2F0aW9uUm9sZUNvbm5lY3Rpb24oYmVhcmVyVG9rZW4sIGFwcGxpY2F0aW9uSWQpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5vYXV0aDIucm9sZUNvbm5lY3Rpb25zKGFwcGxpY2F0aW9uSWQpLCB7XG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICBhdXRob3JpemF0aW9uOiBgQmVhcmVyICR7YmVhcmVyVG9rZW59YCxcbiAgICAgICAgfSxcbiAgICAgICAgdW5hdXRob3JpemVkOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGFkZEd1aWxkTWVtYmVyKGd1aWxkSWQsIHVzZXJJZCwgYm9keSkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucHV0KHJlc3Qucm91dGVzLmd1aWxkcy5tZW1iZXJzLm1lbWJlcihndWlsZElkLCB1c2VySWQpLCB7XG4gICAgICAgIGJvZHksXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgY3JlYXRlVGVzdEVudGl0bGVtZW50KGFwcGxpY2F0aW9uSWQsIGJvZHkpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBvc3Q8RGlzY29yZEVudGl0bGVtZW50PihyZXN0LnJvdXRlcy5tb25ldGl6YXRpb24uZW50aXRsZW1lbnRzKGFwcGxpY2F0aW9uSWQpLCB7XG4gICAgICAgIGJvZHksXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgbGlzdEVudGl0bGVtZW50cyhhcHBsaWNhdGlvbklkLCBvcHRpb25zKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZEVudGl0bGVtZW50W10+KHJlc3Qucm91dGVzLm1vbmV0aXphdGlvbi5lbnRpdGxlbWVudHMoYXBwbGljYXRpb25JZCwgb3B0aW9ucykpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRFbnRpdGxlbWVudChhcHBsaWNhdGlvbklkLCBlbnRpdGxlbWVudElkKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZEVudGl0bGVtZW50PihyZXN0LnJvdXRlcy5tb25ldGl6YXRpb24uZW50aXRsZW1lbnQoYXBwbGljYXRpb25JZCwgZW50aXRsZW1lbnRJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGVUZXN0RW50aXRsZW1lbnQoYXBwbGljYXRpb25JZCwgZW50aXRsZW1lbnRJZCkge1xuICAgICAgYXdhaXQgcmVzdC5kZWxldGUocmVzdC5yb3V0ZXMubW9uZXRpemF0aW9uLmVudGl0bGVtZW50KGFwcGxpY2F0aW9uSWQsIGVudGl0bGVtZW50SWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgY29uc3VtZUVudGl0bGVtZW50KGFwcGxpY2F0aW9uSWQsIGVudGl0bGVtZW50SWQpIHtcbiAgICAgIGF3YWl0IHJlc3QucG9zdChyZXN0LnJvdXRlcy5tb25ldGl6YXRpb24uY29uc3VtZUVudGl0bGVtZW50KGFwcGxpY2F0aW9uSWQsIGVudGl0bGVtZW50SWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgbGlzdFNrdXMoYXBwbGljYXRpb25JZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRTa3VbXT4ocmVzdC5yb3V0ZXMubW9uZXRpemF0aW9uLnNrdXMoYXBwbGljYXRpb25JZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBsaXN0U3Vic2NyaXB0aW9ucyhza3VJZCwgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRTdWJzY3JpcHRpb25bXT4ocmVzdC5yb3V0ZXMubW9uZXRpemF0aW9uLnN1YnNjcmlwdGlvbnMoc2t1SWQsIG9wdGlvbnMpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0U3Vic2NyaXB0aW9uKHNrdUlkLCBzdWJzY3JpcHRpb25JZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRTdWJzY3JpcHRpb24+KHJlc3Qucm91dGVzLm1vbmV0aXphdGlvbi5zdWJzY3JpcHRpb24oc2t1SWQsIHN1YnNjcmlwdGlvbklkKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIHNlbmRTb3VuZGJvYXJkU291bmQoY2hhbm5lbElkLCBvcHRpb25zKSB7XG4gICAgICBhd2FpdCByZXN0LnBvc3QocmVzdC5yb3V0ZXMuc291bmRib2FyZC5zZW5kU291bmQoY2hhbm5lbElkKSwge1xuICAgICAgICBib2R5OiBvcHRpb25zLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGxpc3REZWZhdWx0U291bmRib2FyZFNvdW5kcygpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmdldDxEaXNjb3JkU291bmRib2FyZFNvdW5kW10+KHJlc3Qucm91dGVzLnNvdW5kYm9hcmQubGlzdERlZmF1bHQoKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGxpc3RHdWlsZFNvdW5kYm9hcmRTb3VuZHMoZ3VpbGRJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PHsgaXRlbXM6IERpc2NvcmRTb3VuZGJvYXJkU291bmRbXSB9PihyZXN0LnJvdXRlcy5zb3VuZGJvYXJkLmd1aWxkU291bmRzKGd1aWxkSWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0R3VpbGRTb3VuZGJvYXJkU291bmQoZ3VpbGRJZCwgc291bmRJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZ2V0PERpc2NvcmRTb3VuZGJvYXJkU291bmQ+KHJlc3Qucm91dGVzLnNvdW5kYm9hcmQuZ3VpbGRTb3VuZChndWlsZElkLCBzb3VuZElkKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGNyZWF0ZUd1aWxkU291bmRib2FyZFNvdW5kKGd1aWxkSWQsIG9wdGlvbnMsIHJlYXNvbikge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucG9zdDxEaXNjb3JkU291bmRib2FyZFNvdW5kPihyZXN0LnJvdXRlcy5zb3VuZGJvYXJkLmd1aWxkU291bmRzKGd1aWxkSWQpLCB7XG4gICAgICAgIGJvZHk6IG9wdGlvbnMsXG4gICAgICAgIHJlYXNvbixcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBtb2RpZnlHdWlsZFNvdW5kYm9hcmRTb3VuZChndWlsZElkLCBzb3VuZElkLCBvcHRpb25zLCByZWFzb24pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBvc3Q8RGlzY29yZFNvdW5kYm9hcmRTb3VuZD4ocmVzdC5yb3V0ZXMuc291bmRib2FyZC5ndWlsZFNvdW5kKGd1aWxkSWQsIHNvdW5kSWQpLCB7XG4gICAgICAgIGJvZHk6IG9wdGlvbnMsXG4gICAgICAgIHJlYXNvbixcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGVHdWlsZFNvdW5kYm9hcmRTb3VuZChndWlsZElkLCBzb3VuZElkLCByZWFzb24pIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LmRlbGV0ZShyZXN0LnJvdXRlcy5zb3VuZGJvYXJkLmd1aWxkU291bmQoZ3VpbGRJZCwgc291bmRJZCksIHtcbiAgICAgICAgcmVhc29uLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGxpc3RBcHBsaWNhdGlvblJvbGVDb25uZWN0aW9uc01ldGFkYXRhUmVjb3JkcyhhcHBsaWNhdGlvbklkKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZEFwcGxpY2F0aW9uUm9sZUNvbm5lY3Rpb25NZXRhZGF0YVtdPihyZXN0LnJvdXRlcy5hcHBsaWNhdGlvblJvbGVDb25uZWN0aW9uTWV0YWRhdGEoYXBwbGljYXRpb25JZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyB1cGRhdGVBcHBsaWNhdGlvblJvbGVDb25uZWN0aW9uc01ldGFkYXRhUmVjb3JkcyhhcHBsaWNhdGlvbklkLCBvcHRpb25zKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wdXQ8RGlzY29yZEFwcGxpY2F0aW9uUm9sZUNvbm5lY3Rpb25NZXRhZGF0YVtdPihyZXN0LnJvdXRlcy5hcHBsaWNhdGlvblJvbGVDb25uZWN0aW9uTWV0YWRhdGEoYXBwbGljYXRpb25JZCksIHtcbiAgICAgICAgYm9keTogb3B0aW9ucyxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBjcmVhdGVMb2JieShvcHRpb25zKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wb3N0PERpc2NvcmRMb2JieT4ocmVzdC5yb3V0ZXMubG9iYnkuY3JlYXRlKCksIHtcbiAgICAgICAgYm9keTogb3B0aW9ucyxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRMb2JieShsb2JieUlkKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5nZXQ8RGlzY29yZExvYmJ5PihyZXN0LnJvdXRlcy5sb2JieS5sb2JieShsb2JieUlkKSk7XG4gICAgfSxcblxuICAgIGFzeW5jIG1vZGlmeUxvYmJ5KGxvYmJ5SWQsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBhdGNoPERpc2NvcmRMb2JieT4ocmVzdC5yb3V0ZXMubG9iYnkubG9iYnkobG9iYnlJZCksIHtcbiAgICAgICAgYm9keTogb3B0aW9ucyxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGVMb2JieShsb2JieUlkKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5kZWxldGUocmVzdC5yb3V0ZXMubG9iYnkubG9iYnkobG9iYnlJZCkpO1xuICAgIH0sXG5cbiAgICBhc3luYyBhZGRNZW1iZXJUb0xvYmJ5KGxvYmJ5SWQsIHVzZXJJZCwgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucHV0PERpc2NvcmRMb2JieU1lbWJlcj4ocmVzdC5yb3V0ZXMubG9iYnkubWVtYmVyKGxvYmJ5SWQsIHVzZXJJZCksIHtcbiAgICAgICAgYm9keTogb3B0aW9ucyxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBhc3luYyBidWxrVXBkYXRlTG9iYnlNZW1iZXJzKGxvYmJ5SWQsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBhd2FpdCByZXN0LnBvc3Q8RGlzY29yZExvYmJ5TWVtYmVyW10+KHJlc3Qucm91dGVzLmxvYmJ5Lm1lbWJlcnNCdWxrKGxvYmJ5SWQpLCB7XG4gICAgICAgIGJvZHk6IG9wdGlvbnMsXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgcmVtb3ZlTWVtYmVyRnJvbUxvYmJ5KGxvYmJ5SWQsIHVzZXJJZCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZGVsZXRlKHJlc3Qucm91dGVzLmxvYmJ5Lm1lbWJlcihsb2JieUlkLCB1c2VySWQpKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgbGVhdmVMb2JieShsb2JieUlkLCBiZWFyZXJUb2tlbikge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QuZGVsZXRlKHJlc3Qucm91dGVzLmxvYmJ5LmxlYXZlKGxvYmJ5SWQpLCB7XG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICBhdXRob3JpemF0aW9uOiBgQmVhcmVyICR7YmVhcmVyVG9rZW59YCxcbiAgICAgICAgfSxcbiAgICAgICAgdW5hdXRob3JpemVkOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGxpbmtDaGFubmVsVG9Mb2JieShsb2JieUlkLCBiZWFyZXJUb2tlbiwgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlc3QucGF0Y2g8RGlzY29yZExvYmJ5PihyZXN0LnJvdXRlcy5sb2JieS5saW5rKGxvYmJ5SWQpLCB7XG4gICAgICAgIGJvZHk6IG9wdGlvbnMsXG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICBhdXRob3JpemF0aW9uOiBgQmVhcmVyICR7YmVhcmVyVG9rZW59YCxcbiAgICAgICAgfSxcbiAgICAgICAgdW5hdXRob3JpemVkOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIHVubGlua0NoYW5uZWxUb0xvYmJ5KGxvYmJ5SWQsIGJlYXJlclRva2VuKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVzdC5wYXRjaDxEaXNjb3JkTG9iYnk+KHJlc3Qucm91dGVzLmxvYmJ5LmxpbmsobG9iYnlJZCksIHtcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgIGF1dGhvcml6YXRpb246IGBCZWFyZXIgJHtiZWFyZXJUb2tlbn1gLFxuICAgICAgICB9LFxuICAgICAgICB1bmF1dGhvcml6ZWQ6IHRydWUsXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgdXBkYXRlTG9iYnlNZXNzYWdlTW9kZXJhdGlvbk1ldGFkYXRhKGxvYmJ5SWQsIG1lc3NhZ2VJZCwgb3B0aW9ucykge1xuICAgICAgYXdhaXQgcmVzdC5wdXQocmVzdC5yb3V0ZXMubG9iYnkubW9kZXJhdGlvbk1ldGFkYXRhKGxvYmJ5SWQsIG1lc3NhZ2VJZCksIHtcbiAgICAgICAgYm9keTogb3B0aW9ucyxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBjcmVhdGVPckpvaW5Mb2JieShvcHRpb25zKSB7XG4gICAgICByZXR1cm4gcmVzdC5wdXQ8RGlzY29yZExvYmJ5PihyZXN0LnJvdXRlcy5sb2JieS5jcmVhdGUoKSwge1xuICAgICAgICBib2R5OiBvcHRpb25zLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIHNlbmRMb2JieU1lc3NhZ2UoYmVhcmVyVG9rZW4sIGxvYmJ5SWQsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiByZXN0LnBvc3Q8RGlzY29yZExvYmJ5TWVzc2FnZT4ocmVzdC5yb3V0ZXMubG9iYnkubWVzc2FnZXMobG9iYnlJZCksIHtcbiAgICAgICAgYm9keTogb3B0aW9ucyxcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgIGF1dGhvcml6YXRpb246IGBCZWFyZXIgJHtiZWFyZXJUb2tlbn1gLFxuICAgICAgICB9LFxuICAgICAgICB1bmF1dGhvcml6ZWQ6IHRydWUsXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgZ2V0TG9iYnlNZXNzYWdlcyhiZWFyZXJUb2tlbiwgbG9iYnlJZCwgb3B0aW9ucykge1xuICAgICAgcmV0dXJuIHJlc3QuZ2V0PERpc2NvcmRMb2JieU1lc3NhZ2VbXT4ocmVzdC5yb3V0ZXMubG9iYnkubWVzc2FnZXMobG9iYnlJZCwgb3B0aW9ucyksIHtcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgIGF1dGhvcml6YXRpb246IGBCZWFyZXIgJHtiZWFyZXJUb2tlbn1gLFxuICAgICAgICB9LFxuICAgICAgICB1bmF1dGhvcml6ZWQ6IHRydWUsXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgY3JlYXRlTG9iYnlDaGFubmVsSW52aXRlRm9yU2VsZihiZWFyZXJUb2tlbiwgbG9iYnlJZCkge1xuICAgICAgcmV0dXJuIHJlc3QucG9zdDxEaXNjb3JkTG9iYnlJbnZpdGU+KHJlc3Qucm91dGVzLmxvYmJ5Lmludml0ZVNlbGYobG9iYnlJZCksIHtcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgIGF1dGhvcml6YXRpb246IGBCZWFyZXIgJHtiZWFyZXJUb2tlbn1gLFxuICAgICAgICB9LFxuICAgICAgICB1bmF1dGhvcml6ZWQ6IHRydWUsXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgY3JlYXRlTG9iYnlDaGFubmVsSW52aXRlRm9yVXNlcihsb2JieUlkLCB1c2VySWQpIHtcbiAgICAgIHJldHVybiByZXN0LnBvc3Q8RGlzY29yZExvYmJ5SW52aXRlPihyZXN0LnJvdXRlcy5sb2JieS5pbnZpdGVVc2VyKGxvYmJ5SWQsIHVzZXJJZCkpO1xuICAgIH0sXG5cbiAgICBwcmVmZXJTbmFrZUNhc2UoZW5hYmxlZDogYm9vbGVhbikge1xuICAgICAgY29uc3QgY2FtZWxpemVyID0gZW5hYmxlZCA/ICh4OiBhbnkpID0+IHggOiBjYW1lbGl6ZTtcblxuICAgICAgcmVzdC5nZXQgPSBhc3luYyAodXJsLCBvcHRpb25zKSA9PiB7XG4gICAgICAgIHJldHVybiBjYW1lbGl6ZXIoYXdhaXQgcmVzdC5tYWtlUmVxdWVzdCgnR0VUJywgdXJsLCBvcHRpb25zKSk7XG4gICAgICB9O1xuXG4gICAgICByZXN0LnBvc3QgPSBhc3luYyAodXJsOiBzdHJpbmcsIG9wdGlvbnM/OiBPbWl0PENyZWF0ZVJlcXVlc3RCb2R5T3B0aW9ucywgJ2JvZHknIHwgJ21ldGhvZCc+KSA9PiB7XG4gICAgICAgIHJldHVybiBjYW1lbGl6ZXIoYXdhaXQgcmVzdC5tYWtlUmVxdWVzdCgnUE9TVCcsIHVybCwgb3B0aW9ucykpO1xuICAgICAgfTtcblxuICAgICAgcmVzdC5kZWxldGUgPSBhc3luYyAodXJsOiBzdHJpbmcsIG9wdGlvbnM/OiBPbWl0PENyZWF0ZVJlcXVlc3RCb2R5T3B0aW9ucywgJ2JvZHknIHwgJ21ldGhvZCc+KSA9PiB7XG4gICAgICAgIGNhbWVsaXplcihhd2FpdCByZXN0Lm1ha2VSZXF1ZXN0KCdERUxFVEUnLCB1cmwsIG9wdGlvbnMpKTtcbiAgICAgIH07XG5cbiAgICAgIHJlc3QucGF0Y2ggPSBhc3luYyAodXJsOiBzdHJpbmcsIG9wdGlvbnM/OiBPbWl0PENyZWF0ZVJlcXVlc3RCb2R5T3B0aW9ucywgJ2JvZHknIHwgJ21ldGhvZCc+KSA9PiB7XG4gICAgICAgIHJldHVybiBjYW1lbGl6ZXIoYXdhaXQgcmVzdC5tYWtlUmVxdWVzdCgnUEFUQ0gnLCB1cmwsIG9wdGlvbnMpKTtcbiAgICAgIH07XG5cbiAgICAgIHJlc3QucHV0ID0gYXN5bmMgKHVybDogc3RyaW5nLCBvcHRpb25zPzogT21pdDxDcmVhdGVSZXF1ZXN0Qm9keU9wdGlvbnMsICdib2R5JyB8ICdtZXRob2QnPikgPT4ge1xuICAgICAgICByZXR1cm4gY2FtZWxpemVyKGF3YWl0IHJlc3QubWFrZVJlcXVlc3QoJ1BVVCcsIHVybCwgb3B0aW9ucykpO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHJlc3Q7XG4gICAgfSxcbiAgfTtcblxuICByZXR1cm4gcmVzdDtcbn1cblxuZW51bSBIdHRwUmVzcG9uc2VDb2RlIHtcbiAgLyoqIE1pbmltdW0gdmFsdWUgb2YgYSBjb2RlIGluIG9kZXIgdG8gY29uc2lkZXIgdGhhdCBpdCB3YXMgc3VjY2Vzc2Z1bC4gKi9cbiAgU3VjY2VzcyA9IDIwMCxcbiAgLyoqIFJlcXVlc3QgY29tcGxldGVkIHN1Y2Nlc3NmdWxseSwgYnV0IERpc2NvcmQgcmV0dXJuZWQgYW4gZW1wdHkgYm9keS4gKi9cbiAgTm9Db250ZW50ID0gMjA0LFxuICAvKiogTWluaW11bSB2YWx1ZSBvZiBhIGNvZGUgaW4gb3JkZXIgdG8gY29uc2lkZXIgdGhhdCBzb21ldGhpbmcgd2VudCB3cm9uZy4gKi9cbiAgRXJyb3IgPSA0MDAsXG4gIC8qKiBUaGlzIHJlcXVlc3QgZ290IHJhdGUgbGltaXRlZC4gKi9cbiAgVG9vTWFueVJlcXVlc3RzID0gNDI5LFxufVxuXG4vKiogV2hldGhlciBhbiBlcnJvciBpcyB0aGUgYFRpbWVvdXRFcnJvcmAgdGhyb3duIGJ5IGBBYm9ydFNpZ25hbC50aW1lb3V0KClgLiAqL1xuZnVuY3Rpb24gaXNUaW1lb3V0RXJyb3IoZXJyb3I6IHVua25vd24pOiBib29sZWFuIHtcbiAgcmV0dXJuIGVycm9yIGluc3RhbmNlb2YgRE9NRXhjZXB0aW9uICYmIGVycm9yLm5hbWUgPT09ICdUaW1lb3V0RXJyb3InO1xufVxuIl0sIm5hbWVzIjpbIkJ1ZmZlciIsImluc3BlY3QiLCJjYW1lbGl6ZSIsImNhbWVsVG9TbmFrZUNhc2UiLCJESVNDT1JERU5PX1ZFUlNJT04iLCJkZWxheSIsImdldEJvdElkRnJvbVRva2VuIiwiaGFzUHJvcGVydHkiLCJsb2dnZXIiLCJwcm9jZXNzUmVhY3Rpb25TdHJpbmciLCJzbm93Zmxha2VUb1RpbWVzdGFtcCIsImNyZWF0ZUludmFsaWRSZXF1ZXN0QnVja2V0IiwiUXVldWUiLCJjcmVhdGVSb3V0ZXMiLCJESVNDT1JEX0FQSV9WRVJTSU9OIiwiRElTQ09SRF9BUElfVVJMIiwiQVVESVRfTE9HX1JFQVNPTl9IRUFERVIiLCJSQVRFX0xJTUlUX1JFTUFJTklOR19IRUFERVIiLCJSQVRFX0xJTUlUX1JFU0VUX0FGVEVSX0hFQURFUiIsIlJBVEVfTElNSVRfR0xPQkFMX0hFQURFUiIsIlJBVEVfTElNSVRfQlVDS0VUX0hFQURFUiIsIlJBVEVfTElNSVRfTElNSVRfSEVBREVSIiwiUkFURV9MSU1JVF9TQ09QRV9IRUFERVIiLCJjcmVhdGVSZXN0TWFuYWdlciIsIm9wdGlvbnMiLCJhcHBsaWNhdGlvbklkIiwiQmlnSW50IiwidG9rZW4iLCJiYXNlVXJsIiwicHJveHkiLCJyZXBsYWNlIiwiYmFzZUVycm9yUHJvdG90eXBlIiwiY3VzdG9tIiwiX2RlcHRoIiwiX2luc3BlY3QiLCJkZXB0aCIsIkluZmluaXR5IiwiY3VzdG9tSW5zcGVjdCIsInJlc3QiLCJhdXRob3JpemF0aW9uIiwiYXV0aG9yaXphdGlvbkhlYWRlciIsImRlbGV0ZVF1ZXVlRGVsYXkiLCJnbG9iYWxseVJhdGVMaW1pdGVkIiwiaW52YWxpZEJ1Y2tldCIsImlzUHJveGllZCIsInN0YXJ0c1dpdGgiLCJ1cGRhdGVCZWFyZXJUb2tlbkVuZHBvaW50IiwicmV0cnlQcm94aWVkUmVxdWVzdHMiLCJyZXRyeVJlcXVlc3RzIiwibWF4UmV0cnlDb3VudCIsIm1heFByb3h5UmV0cnlDb3VudCIsInByb3h5UmV0cnlEZWxheVN0ZXAiLCJyZXF1ZXN0VGltZW91dCIsInByb2Nlc3NpbmdSYXRlTGltaXRlZFBhdGhzIiwicXVldWVzIiwiTWFwIiwicmF0ZUxpbWl0ZWRQYXRocyIsInZlcnNpb24iLCJldmVudHMiLCJyZXF1ZXN0IiwicmVzcG9uc2UiLCJyZXF1ZXN0RXJyb3IiLCJyb3V0ZXMiLCJjcmVhdGVCYXNlSGVhZGVycyIsImNoZWNrUmF0ZUxpbWl0cyIsInVybCIsImlkZW50aWZpZXIiLCJyYXRlbGltaXRlZCIsImdldCIsImdsb2JhbCIsIm5vdyIsIkRhdGUiLCJyZXNldFRpbWVzdGFtcCIsInVwZGF0ZVRva2VuUXVldWVzIiwib2xkVG9rZW4iLCJuZXdUb2tlbiIsIkVycm9yIiwiaGVhZGVycyIsInVuZGVmaW5lZCIsImZldGNoIiwibWV0aG9kIiwiYm9keSIsIkpTT04iLCJzdHJpbmdpZnkiLCJuZXdJZGVudGlmaWVyIiwia2V5IiwicXVldWUiLCJlbnRyaWVzIiwiZGVsZXRlIiwibmV3S2V5IiwibmV3UXVldWUiLCJ3YWl0aW5nIiwidW5zaGlmdCIsInBlbmRpbmciLCJjbGVhbnVwIiwic2V0IiwicmF0ZWxpbWl0UGF0aCIsImJ1Y2tldElkIiwiY2hhbmdlVG9EaXNjb3JkRm9ybWF0Iiwib2JqIiwiQXJyYXkiLCJpc0FycmF5IiwibWFwIiwiaXRlbSIsIm5ld09iaiIsIk9iamVjdCIsImtleXMiLCJ2YWx1ZSIsImluY2x1ZGVzIiwibmFtZV9sb2NhbGl6YXRpb25zIiwiZGVzY3JpcHRpb25fbG9jYWxpemF0aW9ucyIsInRvU3RyaW5nIiwiY3JlYXRlUmVxdWVzdEJvZHkiLCJ1bmF1dGhvcml6ZWQiLCJyZWFzb24iLCJlbmNvZGVVUklDb21wb25lbnQiLCJmaWxlcyIsImZvcm0iLCJGb3JtRGF0YSIsImkiLCJsZW5ndGgiLCJhcHBlbmQiLCJibG9iIiwibmFtZSIsImZvcm1Cb2R5IiwiZGlzY29yZEJvZHkiLCJwcm9wIiwicHVzaCIsImpvaW4iLCJhc3NpZ24iLCJjcmVhdGVSZXF1ZXN0RXJyb3IiLCJlcnJvciIsImVycm9yVGV4dCIsInN0YXR1cyIsInN0YXR1c1RleHQiLCJtZXNzYWdlIiwiY29kZSIsImNhdXNlIiwiY3JlYXRlIiwicHJvY2Vzc1JhdGVMaW1pdGVkUGF0aHMiLCJzaXplIiwic2V0VGltZW91dCIsInByb2Nlc3NIZWFkZXJzIiwicmF0ZUxpbWl0ZWQiLCJyZW1haW5pbmciLCJyZXRyeUFmdGVyIiwicmVzZXQiLCJOdW1iZXIiLCJsaW1pdCIsImhhbmRsZUNvbXBsZXRlZFJlcXVlc3QiLCJpbnRlcnZhbCIsIm1heCIsImdsb2JhbFJlc2V0Iiwic2VuZFJlcXVlc3QiLCJyb3V0ZSIsInBheWxvYWQiLCJyZXF1ZXN0Qm9keU9wdGlvbnMiLCJoYW5kbGVUaW1lb3V0IiwicmV0cnlDb3VudCIsImRlYnVnIiwicmVqZWN0Iiwib2siLCJlcnJvck9iamVjdCIsInJldHJ5UmVxdWVzdCIsImxvZ2dpbmdIZWFkZXJzIiwiYXV0aG9yaXphdGlvblNjaGVtZSIsInNwbGl0Iiwic2lnbmFscyIsInNpZ25hbCIsIkFib3J0U2lnbmFsIiwidGltZW91dCIsIlJlcXVlc3QiLCJhbnkiLCJjYXRjaCIsImFib3J0ZWQiLCJpc1RpbWVvdXRFcnJvciIsImpzb24iLCJ0ZXh0IiwicmVxdWVzdEJvZHkiLCJyZXNwb25zZUJvZHkiLCJzaW1wbGlmeVVybCIsInJlc2V0QWZ0ZXIiLCJyZXNvbHZlIiwicm91dGVJbmZvcm1hdGlvbktleSIsInF1ZXJ5UGFyYW1JbmRleCIsImluZGV4T2YiLCJzbGljZSIsInNwbGl0dGVkUm91dGUiLCJzdHJpcHBlZFJvdXRlIiwicGFydCIsImluZGV4IiwiYXJyYXkiLCJpc051bWJlciIsImlzRmluaXRlIiwicGFyc2VJbnQiLCJpc01ham9yIiwiZW5kc1dpdGgiLCJtZXNzYWdlSWQiLCJ0aW1lc3RhbXAiLCJwcm9jZXNzUmVxdWVzdCIsInJ1blRocm91Z2hRdWV1ZSIsInF1ZXVlSWRlbnRpZmllciIsIm1ha2VSZXF1ZXN0IiwiYnVja2V0UXVldWUiLCJyZXN1bHQiLCJmZXRjaEVycm9yIiwidGltZWRPdXQiLCJib2R5UmVhZEZhaWxlZCIsInBhcnNlIiwiUHJvbWlzZSIsImFib3J0TGlzdGVuZXIiLCJkYXRhIiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsImFkZEV2ZW50TGlzdGVuZXIiLCJvbmNlIiwicG9zdCIsInBhdGNoIiwicHV0IiwiYWRkUmVhY3Rpb24iLCJjaGFubmVsSWQiLCJyZWFjdGlvbiIsImNoYW5uZWxzIiwicmVhY3Rpb25zIiwiYm90IiwiYWRkUmVhY3Rpb25zIiwib3JkZXJlZCIsImFsbCIsImFkZFJvbGUiLCJndWlsZElkIiwidXNlcklkIiwicm9sZUlkIiwiZ3VpbGRzIiwicm9sZXMiLCJtZW1iZXIiLCJhZGRUaHJlYWRNZW1iZXIiLCJ0aHJlYWRzIiwidXNlciIsImFkZERtUmVjaXBpZW50IiwiZG1SZWNpcGllbnQiLCJjcmVhdGVBdXRvbW9kUnVsZSIsImF1dG9tb2QiLCJydWxlcyIsImNyZWF0ZUNoYW5uZWwiLCJjcmVhdGVFbW9qaSIsImVtb2ppcyIsImNyZWF0ZUFwcGxpY2F0aW9uRW1vamkiLCJhcHBsaWNhdGlvbkVtb2ppcyIsImNyZWF0ZUdsb2JhbEFwcGxpY2F0aW9uQ29tbWFuZCIsInJlc3RPcHRpb25zIiwiYmVhcmVyVG9rZW4iLCJpbnRlcmFjdGlvbnMiLCJjb21tYW5kcyIsImNyZWF0ZUd1aWxkQXBwbGljYXRpb25Db21tYW5kIiwiY3JlYXRlR3VpbGRTdGlja2VyIiwiZmlsZSIsImRlc2NyaXB0aW9uIiwidGFncyIsInN0aWNrZXJzIiwiY3JlYXRlR3VpbGRUZW1wbGF0ZSIsInRlbXBsYXRlcyIsImNyZWF0ZUZvcnVtVGhyZWFkIiwiZm9ydW0iLCJjcmVhdGVJbnZpdGUiLCJ0YXJnZXRVc2Vyc0ZpbGUiLCJpbnZpdGVzIiwiZ2V0R3VpbGRSb2xlTWVtYmVyQ291bnRzIiwibWVtYmVyQ291bnRzIiwiY3JlYXRlUm9sZSIsImNyZWF0ZVNjaGVkdWxlZEV2ZW50IiwiY3JlYXRlU3RhZ2VJbnN0YW5jZSIsInN0YWdlcyIsImNyZWF0ZVdlYmhvb2siLCJ3ZWJob29rcyIsImRlbGV0ZUF1dG9tb2RSdWxlIiwicnVsZUlkIiwicnVsZSIsImRlbGV0ZUNoYW5uZWwiLCJjaGFubmVsIiwiZGVsZXRlQ2hhbm5lbFBlcm1pc3Npb25PdmVycmlkZSIsIm92ZXJ3cml0ZUlkIiwib3ZlcndyaXRlIiwiZGVsZXRlRW1vamkiLCJpZCIsImVtb2ppIiwiZGVsZXRlQXBwbGljYXRpb25FbW9qaSIsImFwcGxpY2F0aW9uRW1vamkiLCJkZWxldGVGb2xsb3d1cE1lc3NhZ2UiLCJyZXNwb25zZXMiLCJkZWxldGVHbG9iYWxBcHBsaWNhdGlvbkNvbW1hbmQiLCJjb21tYW5kSWQiLCJjb21tYW5kIiwiZGVsZXRlR3VpbGRBcHBsaWNhdGlvbkNvbW1hbmQiLCJvbmUiLCJkZWxldGVHdWlsZFN0aWNrZXIiLCJzdGlja2VySWQiLCJzdGlja2VyIiwiZGVsZXRlR3VpbGRUZW1wbGF0ZSIsInRlbXBsYXRlQ29kZSIsImd1aWxkIiwiZGVsZXRlSW50ZWdyYXRpb24iLCJpbnRlZ3JhdGlvbklkIiwiaW50ZWdyYXRpb24iLCJkZWxldGVJbnZpdGUiLCJpbnZpdGVDb2RlIiwiaW52aXRlIiwiZ2V0VGFyZ2V0VXNlcnMiLCJpbnZpdGVUYXJnZXRVc2VycyIsInVwZGF0ZVRhcmdldFVzZXJzIiwiZ2V0VGFyZ2V0VXNlcnNKb2JTdGF0dXMiLCJpbnZpdGVUYXJnZXRVc2Vyc0pvYlN0YXR1cyIsImRlbGV0ZU1lc3NhZ2UiLCJkZWxldGVNZXNzYWdlcyIsIm1lc3NhZ2VJZHMiLCJidWxrIiwibWVzc2FnZXMiLCJkZWxldGVPcmlnaW5hbEludGVyYWN0aW9uUmVzcG9uc2UiLCJvcmlnaW5hbCIsImRlbGV0ZU93blJlYWN0aW9uIiwiZGVsZXRlUmVhY3Rpb25zQWxsIiwiZGVsZXRlUmVhY3Rpb25zRW1vamkiLCJkZWxldGVSb2xlIiwiZGVsZXRlU2NoZWR1bGVkRXZlbnQiLCJldmVudElkIiwiZXZlbnQiLCJkZWxldGVTdGFnZUluc3RhbmNlIiwic3RhZ2UiLCJkZWxldGVVc2VyUmVhY3Rpb24iLCJkZWxldGVXZWJob29rIiwid2ViaG9va0lkIiwiZGVsZXRlV2ViaG9va01lc3NhZ2UiLCJkZWxldGVXZWJob29rV2l0aFRva2VuIiwid2ViaG9vayIsImVkaXRBcHBsaWNhdGlvbkNvbW1hbmRQZXJtaXNzaW9ucyIsInBlcm1pc3Npb25zIiwicGVybWlzc2lvbiIsImVkaXRBdXRvbW9kUnVsZSIsImVkaXRCb3RQcm9maWxlIiwiY3VycmVudFVzZXIiLCJlZGl0Q2hhbm5lbCIsImVkaXRDaGFubmVsUGVybWlzc2lvbk92ZXJyaWRlcyIsImVkaXRDaGFubmVsUG9zaXRpb25zIiwiZWRpdEVtb2ppIiwiZWRpdEFwcGxpY2F0aW9uRW1vamkiLCJlZGl0Rm9sbG93dXBNZXNzYWdlIiwiZWRpdEdsb2JhbEFwcGxpY2F0aW9uQ29tbWFuZCIsImVkaXRHdWlsZCIsImVkaXRHdWlsZEFwcGxpY2F0aW9uQ29tbWFuZCIsImVkaXRHdWlsZFN0aWNrZXIiLCJlZGl0R3VpbGRUZW1wbGF0ZSIsImVkaXRNZXNzYWdlIiwiZWRpdE9yaWdpbmFsSW50ZXJhY3Rpb25SZXNwb25zZSIsImVkaXRPd25Wb2ljZVN0YXRlIiwidm9pY2UiLCJyZXF1ZXN0VG9TcGVha1RpbWVzdGFtcCIsInRvSVNPU3RyaW5nIiwiZWRpdFNjaGVkdWxlZEV2ZW50IiwiZWRpdFJvbGUiLCJlZGl0Um9sZVBvc2l0aW9ucyIsImVkaXRTdGFnZUluc3RhbmNlIiwidG9waWMiLCJlZGl0VXNlclZvaWNlU3RhdGUiLCJlZGl0V2ViaG9vayIsImVkaXRXZWJob29rTWVzc2FnZSIsImVkaXRXZWJob29rV2l0aFRva2VuIiwiZWRpdFdlbGNvbWVTY3JlZW4iLCJ3ZWxjb21lIiwiZWRpdFdpZGdldFNldHRpbmdzIiwid2lkZ2V0IiwiZXhlY3V0ZVdlYmhvb2siLCJmb2xsb3dBbm5vdW5jZW1lbnQiLCJzb3VyY2VDaGFubmVsSWQiLCJ0YXJnZXRDaGFubmVsSWQiLCJmb2xsb3ciLCJ3ZWJob29rQ2hhbm5lbElkIiwiZ2V0QWN0aXZlVGhyZWFkcyIsImFjdGl2ZSIsImdldEFwcGxpY2F0aW9uQ29tbWFuZFBlcm1pc3Npb24iLCJhY2Nlc3NUb2tlbiIsImdldEFwcGxpY2F0aW9uQ29tbWFuZFBlcm1pc3Npb25zIiwiZ2V0QXBwbGljYXRpb25JbmZvIiwib2F1dGgyIiwiYXBwbGljYXRpb24iLCJlZGl0QXBwbGljYXRpb25JbmZvIiwiZ2V0Q3VycmVudEF1dGhlbnRpY2F0aW9uSW5mbyIsImN1cnJlbnRBdXRob3JpemF0aW9uIiwiZXhjaGFuZ2VUb2tlbiIsImNsaWVudElkIiwiY2xpZW50U2VjcmV0IiwiYmFzaWNDcmVkZW50aWFscyIsImZyb20iLCJncmFudFR5cGUiLCJzY29wZSIsInRva2VuRXhjaGFuZ2UiLCJyZXZva2VUb2tlbiIsInRva2VuUmV2b2tlIiwiZ2V0QXVkaXRMb2ciLCJhdWRpdGxvZ3MiLCJnZXRBdXRvbW9kUnVsZSIsImdldEF1dG9tb2RSdWxlcyIsImdldEF2YWlsYWJsZVZvaWNlUmVnaW9ucyIsInJlZ2lvbnMiLCJnZXRCYW4iLCJtZW1iZXJzIiwiYmFuIiwiZ2V0QmFucyIsImJhbnMiLCJnZXRDaGFubmVsIiwiZ2V0Q2hhbm5lbEludml0ZXMiLCJnZXRDaGFubmVscyIsImdldENoYW5uZWxXZWJob29rcyIsImdldERtQ2hhbm5lbCIsImRtIiwicmVjaXBpZW50SWQiLCJnZXRHcm91cERtQ2hhbm5lbCIsImdldEVtb2ppIiwiZW1vamlJZCIsImdldEFwcGxpY2F0aW9uRW1vamkiLCJnZXRFbW9qaXMiLCJnZXRBcHBsaWNhdGlvbkVtb2ppcyIsImdldEZvbGxvd3VwTWVzc2FnZSIsImdldEdhdGV3YXlCb3QiLCJnYXRld2F5Qm90IiwiZ2V0R2xvYmFsQXBwbGljYXRpb25Db21tYW5kIiwiZ2V0R2xvYmFsQXBwbGljYXRpb25Db21tYW5kcyIsIndpdGhMb2NhbGl6YXRpb25zIiwiZ2V0R3VpbGQiLCJjb3VudHMiLCJnZXRHdWlsZHMiLCJtYWtlUmVxdWVzdE9wdGlvbnMiLCJ1c2VyR3VpbGRzIiwiZ2V0R3VpbGRBcHBsaWNhdGlvbkNvbW1hbmQiLCJnZXRHdWlsZEFwcGxpY2F0aW9uQ29tbWFuZHMiLCJnZXRHdWlsZFByZXZpZXciLCJwcmV2aWV3IiwiZ2V0R3VpbGRUZW1wbGF0ZSIsImdldEd1aWxkVGVtcGxhdGVzIiwiZ2V0R3VpbGRXZWJob29rcyIsImdldEludGVncmF0aW9ucyIsImludGVncmF0aW9ucyIsImdldEludml0ZSIsImdldEludml0ZXMiLCJnZXRNZXNzYWdlIiwiZ2V0TWVzc2FnZXMiLCJzZWFyY2hHdWlsZE1lc3NhZ2VzIiwibWVzc2FnZXNTZWFyY2giLCJnZXRTdGlja2VyUGFjayIsInN0aWNrZXJQYWNrSWQiLCJzdGlja2VyUGFjayIsImdldFN0aWNrZXJQYWNrcyIsInN0aWNrZXJQYWNrcyIsImdldE9yaWdpbmFsSW50ZXJhY3Rpb25SZXNwb25zZSIsImdldENoYW5uZWxQaW5zIiwibWVzc2FnZVBpbnMiLCJnZXRQaW5uZWRNZXNzYWdlcyIsInBpbnMiLCJnZXRQcml2YXRlQXJjaGl2ZWRUaHJlYWRzIiwicHJpdmF0ZSIsImdldFByaXZhdGVKb2luZWRBcmNoaXZlZFRocmVhZHMiLCJqb2luZWQiLCJnZXRQcnVuZUNvdW50IiwicHJ1bmUiLCJnZXRQdWJsaWNBcmNoaXZlZFRocmVhZHMiLCJwdWJsaWMiLCJnZXRSb2xlcyIsImdldFJvbGUiLCJnZXRTY2hlZHVsZWRFdmVudCIsIndpdGhVc2VyQ291bnQiLCJnZXRTY2hlZHVsZWRFdmVudHMiLCJnZXRTY2hlZHVsZWRFdmVudFVzZXJzIiwidXNlcnMiLCJnZXRTZXNzaW9uSW5mbyIsImdldFN0YWdlSW5zdGFuY2UiLCJnZXRPd25Wb2ljZVN0YXRlIiwiZ2V0VXNlclZvaWNlU3RhdGUiLCJnZXRTdGlja2VyIiwiZ2V0R3VpbGRTdGlja2VyIiwiZ2V0R3VpbGRTdGlja2VycyIsImdldFRocmVhZE1lbWJlciIsImdldFVzZXIiLCJnZXRUaHJlYWRNZW1iZXJzIiwiZ2V0UmVhY3Rpb25zIiwiZ2V0Q3VycmVudFVzZXIiLCJnZXRVc2VyQ29ubmVjdGlvbnMiLCJjb25uZWN0aW9ucyIsImdldFVzZXJBcHBsaWNhdGlvblJvbGVDb25uZWN0aW9uIiwicm9sZUNvbm5lY3Rpb25zIiwiZ2V0VmFuaXR5VXJsIiwidmFuaXR5IiwiZ2V0Vm9pY2VSZWdpb25zIiwiZ2V0V2ViaG9vayIsImdldFdlYmhvb2tNZXNzYWdlIiwiZ2V0V2ViaG9va1dpdGhUb2tlbiIsImdldFdlbGNvbWVTY3JlZW4iLCJnZXRXaWRnZXQiLCJ3aWRnZXRKc29uIiwiZ2V0V2lkZ2V0U2V0dGluZ3MiLCJqb2luVGhyZWFkIiwibWUiLCJsZWF2ZUd1aWxkIiwibGVhdmUiLCJsZWF2ZVRocmVhZCIsInB1Ymxpc2hNZXNzYWdlIiwiY3Jvc3Nwb3N0IiwicmVtb3ZlUm9sZSIsInJlbW92ZVRocmVhZE1lbWJlciIsInJlbW92ZURtUmVjaXBpZW50Iiwic2VuZEZvbGxvd3VwTWVzc2FnZSIsInNlbmRJbnRlcmFjdGlvblJlc3BvbnNlIiwiaW50ZXJhY3Rpb25JZCIsInBhcmFtcyIsImNhbGxiYWNrIiwic2VuZE1lc3NhZ2UiLCJzdGFydFRocmVhZFdpdGhNZXNzYWdlIiwic3RhcnRUaHJlYWRXaXRob3V0TWVzc2FnZSIsImdldFBvbGxBbnN3ZXJWb3RlcnMiLCJhbnN3ZXJJZCIsInBvbGxzIiwidm90ZXMiLCJlbmRQb2xsIiwiZXhwaXJlIiwic3luY0d1aWxkVGVtcGxhdGUiLCJiYW5NZW1iZXIiLCJidWxrQmFuTWVtYmVycyIsImJ1bGtCYW4iLCJlZGl0Q3VycmVudE1lbWJlciIsImVkaXRNZW1iZXIiLCJnZXRDdXJyZW50TWVtYmVyIiwiY3VycmVudE1lbWJlciIsImdldE1lbWJlciIsImdldE1lbWJlcnMiLCJnZXRBcHBsaWNhdGlvbkFjdGl2aXR5SW5zdGFuY2UiLCJpbnN0YW5jZUlkIiwiYXBwbGljYXRpb25BY3Rpdml0eUluc3RhbmNlIiwia2lja01lbWJlciIsInBpbk1lc3NhZ2UiLCJtZXNzYWdlUGluIiwicHJ1bmVNZW1iZXJzIiwic2VhcmNoTWVtYmVycyIsInF1ZXJ5Iiwic2VhcmNoIiwiZ2V0R3VpbGRPbmJvYXJkaW5nIiwib25ib2FyZGluZyIsImVkaXRHdWlsZE9uYm9hcmRpbmciLCJtb2RpZnlHdWlsZEluY2lkZW50QWN0aW9ucyIsImluY2lkZW50QWN0aW9ucyIsInVuYmFuTWVtYmVyIiwidW5waW5NZXNzYWdlIiwidHJpZ2dlclR5cGluZ0luZGljYXRvciIsInR5cGluZyIsInVwc2VydEdsb2JhbEFwcGxpY2F0aW9uQ29tbWFuZHMiLCJ1cHNlcnRHdWlsZEFwcGxpY2F0aW9uQ29tbWFuZHMiLCJlZGl0VXNlckFwcGxpY2F0aW9uUm9sZUNvbm5lY3Rpb24iLCJkZWxldGVDdXJyZW50VXNlckFwcGxpY2F0aW9uUm9sZUNvbm5lY3Rpb24iLCJhZGRHdWlsZE1lbWJlciIsImNyZWF0ZVRlc3RFbnRpdGxlbWVudCIsIm1vbmV0aXphdGlvbiIsImVudGl0bGVtZW50cyIsImxpc3RFbnRpdGxlbWVudHMiLCJnZXRFbnRpdGxlbWVudCIsImVudGl0bGVtZW50SWQiLCJlbnRpdGxlbWVudCIsImRlbGV0ZVRlc3RFbnRpdGxlbWVudCIsImNvbnN1bWVFbnRpdGxlbWVudCIsImxpc3RTa3VzIiwic2t1cyIsImxpc3RTdWJzY3JpcHRpb25zIiwic2t1SWQiLCJzdWJzY3JpcHRpb25zIiwiZ2V0U3Vic2NyaXB0aW9uIiwic3Vic2NyaXB0aW9uSWQiLCJzdWJzY3JpcHRpb24iLCJzZW5kU291bmRib2FyZFNvdW5kIiwic291bmRib2FyZCIsInNlbmRTb3VuZCIsImxpc3REZWZhdWx0U291bmRib2FyZFNvdW5kcyIsImxpc3REZWZhdWx0IiwibGlzdEd1aWxkU291bmRib2FyZFNvdW5kcyIsImd1aWxkU291bmRzIiwiZ2V0R3VpbGRTb3VuZGJvYXJkU291bmQiLCJzb3VuZElkIiwiZ3VpbGRTb3VuZCIsImNyZWF0ZUd1aWxkU291bmRib2FyZFNvdW5kIiwibW9kaWZ5R3VpbGRTb3VuZGJvYXJkU291bmQiLCJkZWxldGVHdWlsZFNvdW5kYm9hcmRTb3VuZCIsImxpc3RBcHBsaWNhdGlvblJvbGVDb25uZWN0aW9uc01ldGFkYXRhUmVjb3JkcyIsImFwcGxpY2F0aW9uUm9sZUNvbm5lY3Rpb25NZXRhZGF0YSIsInVwZGF0ZUFwcGxpY2F0aW9uUm9sZUNvbm5lY3Rpb25zTWV0YWRhdGFSZWNvcmRzIiwiY3JlYXRlTG9iYnkiLCJsb2JieSIsImdldExvYmJ5IiwibG9iYnlJZCIsIm1vZGlmeUxvYmJ5IiwiZGVsZXRlTG9iYnkiLCJhZGRNZW1iZXJUb0xvYmJ5IiwiYnVsa1VwZGF0ZUxvYmJ5TWVtYmVycyIsIm1lbWJlcnNCdWxrIiwicmVtb3ZlTWVtYmVyRnJvbUxvYmJ5IiwibGVhdmVMb2JieSIsImxpbmtDaGFubmVsVG9Mb2JieSIsImxpbmsiLCJ1bmxpbmtDaGFubmVsVG9Mb2JieSIsInVwZGF0ZUxvYmJ5TWVzc2FnZU1vZGVyYXRpb25NZXRhZGF0YSIsIm1vZGVyYXRpb25NZXRhZGF0YSIsImNyZWF0ZU9ySm9pbkxvYmJ5Iiwic2VuZExvYmJ5TWVzc2FnZSIsImdldExvYmJ5TWVzc2FnZXMiLCJjcmVhdGVMb2JieUNoYW5uZWxJbnZpdGVGb3JTZWxmIiwiaW52aXRlU2VsZiIsImNyZWF0ZUxvYmJ5Q2hhbm5lbEludml0ZUZvclVzZXIiLCJpbnZpdGVVc2VyIiwicHJlZmVyU25ha2VDYXNlIiwiZW5hYmxlZCIsImNhbWVsaXplciIsIngiLCJIdHRwUmVzcG9uc2VDb2RlIiwiRE9NRXhjZXB0aW9uIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxNQUFNLFFBQVEsY0FBYztBQUNyQyxTQUE4QkMsT0FBTyxRQUFRLFlBQVk7QUFnRXpELFNBQ0VDLFFBQVEsRUFDUkMsZ0JBQWdCLEVBQ2hCQyxrQkFBa0IsRUFDbEJDLEtBQUssRUFDTEMsaUJBQWlCLEVBQ2pCQyxXQUFXLEVBQ1hDLE1BQU0sRUFDTkMscUJBQXFCLEVBQ3JCQyxvQkFBb0IsUUFDZixvQkFBb0I7QUFDM0IsU0FBU0MsMEJBQTBCLFFBQVEscUJBQXFCO0FBQ2hFLFNBQVNDLEtBQUssUUFBUSxhQUFhO0FBQ25DLFNBQVNDLFlBQVksUUFBUSxjQUFjO0FBRzNDLE9BQU8sTUFBTUMsc0JBQXNCLEdBQUc7QUFDdEMsT0FBTyxNQUFNQyxrQkFBa0IsMEJBQTBCO0FBRXpELE9BQU8sTUFBTUMsMEJBQTBCLHFCQUFxQjtBQUM1RCxPQUFP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
|