@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.
Files changed (44) hide show
  1. package/dist/index.d.ts.map +1 -0
  2. package/dist/index.js +8 -0
  3. package/dist/invalidBucket.d.ts.map +1 -0
  4. package/dist/invalidBucket.js +82 -0
  5. package/dist/manager.d.ts.map +1 -0
  6. package/dist/manager.js +1844 -0
  7. package/dist/{types/queue.d.ts → queue.d.ts} +2 -2
  8. package/dist/queue.d.ts.map +1 -0
  9. package/dist/queue.js +190 -0
  10. package/dist/routes.d.ts +9 -0
  11. package/dist/routes.d.ts.map +1 -0
  12. package/dist/routes.js +674 -0
  13. package/dist/{types/types.d.ts → types.d.ts} +462 -193
  14. package/dist/types.d.ts.map +1 -0
  15. package/dist/types.js +3 -0
  16. package/dist/{types/typings → typings}/routes.d.ts +19 -1
  17. package/dist/typings/routes.d.ts.map +1 -0
  18. package/dist/typings/routes.js +3 -0
  19. package/package.json +27 -37
  20. package/dist/cjs/index.cjs +0 -25
  21. package/dist/cjs/invalidBucket.cjs +0 -86
  22. package/dist/cjs/manager.cjs +0 -1665
  23. package/dist/cjs/queue.cjs +0 -164
  24. package/dist/cjs/routes.cjs +0 -631
  25. package/dist/cjs/types.cjs +0 -6
  26. package/dist/cjs/typings/routes.cjs +0 -6
  27. package/dist/esm/index.js +0 -8
  28. package/dist/esm/invalidBucket.js +0 -82
  29. package/dist/esm/manager.js +0 -1623
  30. package/dist/esm/queue.js +0 -154
  31. package/dist/esm/routes.js +0 -621
  32. package/dist/esm/types.js +0 -3
  33. package/dist/esm/typings/routes.js +0 -3
  34. package/dist/types/index.d.ts.map +0 -1
  35. package/dist/types/invalidBucket.d.ts.map +0 -1
  36. package/dist/types/manager.d.ts.map +0 -1
  37. package/dist/types/queue.d.ts.map +0 -1
  38. package/dist/types/routes.d.ts +0 -3
  39. package/dist/types/routes.d.ts.map +0 -1
  40. package/dist/types/types.d.ts.map +0 -1
  41. package/dist/types/typings/routes.d.ts.map +0 -1
  42. /package/dist/{types/index.d.ts → index.d.ts} +0 -0
  43. /package/dist/{types/invalidBucket.d.ts → invalidBucket.d.ts} +0 -0
  44. /package/dist/{types/manager.d.ts → manager.d.ts} +0 -0
@@ -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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