@dbx-tools/appkit-mastra 0.9.61 → 0.9.64

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.
@@ -22,15 +22,18 @@ import { ConfigurationError, createWorkspaceClient } from "@databricks/appkit";
22
22
  import { DatabricksFileSystem, workspaceClient } from "@dbx-tools/databricks";
23
23
  import { errorUtils, log, object, stringUtils, token } from "@dbx-tools/shared-core";
24
24
  import { CompositeFilesystem, Workspace, } from "@mastra/core/workspace";
25
- import { MASTRA_SCOPES_KEY, MASTRA_USER_EMAIL_KEY, MASTRA_USER_KEY } from "./config.js";
26
- import { scratchFilesystem, filesystems } from "./filesystems.js";
25
+ import { MASTRA_SCOPES_KEY, MASTRA_USER_EMAIL_KEY, MASTRA_USER_KEY, resolveUserKey, } from "./config.js";
26
+ import { scratchFilesystem } from "./filesystems.js";
27
27
  import { MontySandbox } from "./monty-sandbox.js";
28
28
  import { DatabricksSandbox } from "./sandbox.js";
29
+ import { cachedWorkspaceSkillMount, DEFAULT_WORKSPACE_SKILL_CACHE_TTL_MS } from "./skill-cache.js";
29
30
  import { ASSISTANT_SHARED_SKILLS_PATH, userAssistantSkillsPath } from "./skill-paths.js";
30
31
  /* ------------------------------ constants ------------------------------ */
31
32
  /** OAuth scopes that gate Databricks workspace file mounts. */
32
33
  const WORKSPACE_FILE_SCOPES = ["workspace", "workspace.workspace", "all-apis"];
33
34
  const logger = log.logger("mastra/workspaces");
35
+ const MAX_SCOPED_WORKSPACE_FILESYSTEMS = 16;
36
+ const scopedWorkspaceFilesystems = new Map();
34
37
  /* ------------------------------- defaults ------------------------------- */
35
38
  /**
36
39
  * The skill folders every workspace starts with.
@@ -92,7 +95,7 @@ export function createWorkspace(options = {}) {
92
95
  const { id, name } = resolveWorkspaceIdentity(options);
93
96
  const skillFolders = resolveSkillFolders(options);
94
97
  const folderNames = Object.keys(skillFolders);
95
- const resolvers = buildMountResolvers(skillFolders, options.mounts);
98
+ const resolvers = buildMountResolvers(skillFolders, options.mounts, options.workspaceSkillRefreshTtlMs);
96
99
  const extraSkillPaths = options.extraSkillPaths ?? [];
97
100
  const skills = options.skills ??
98
101
  (resolvers.length > 0 || extraSkillPaths.length > 0
@@ -109,6 +112,7 @@ export function createWorkspace(options = {}) {
109
112
  customMountResolvers: options.mounts?.length ?? 0,
110
113
  customSkillsResolver: Boolean(options.skills),
111
114
  checkSkillFileMtime,
115
+ workspaceSkillRefreshTtlMs: options.workspaceSkillRefreshTtlMs ?? DEFAULT_WORKSPACE_SKILL_CACHE_TTL_MS,
112
116
  bm25,
113
117
  extraSkillPaths: extraSkillPaths.length,
114
118
  sandbox: sandbox ? sandboxName(options.sandbox) : "disabled",
@@ -215,9 +219,10 @@ function hasWorkspaceFileScope(requestContext) {
215
219
  * Gates on workspace file scope (or development mode), then mounts every
216
220
  * folder whose location resolves for this request.
217
221
  */
218
- async function resolveSkillFolderMounts(skillFolders, context) {
222
+ async function resolveSkillFolderMounts(skillFolders, context, workspaceSkillRefreshTtlMs) {
219
223
  const mounts = {};
220
224
  const skillPaths = [];
225
+ const cacheKeys = [];
221
226
  const requestContext = context.requestContext;
222
227
  if (!requestContext || !shouldMountSkillFolders(requestContext)) {
223
228
  logger.debug("skill-folders:skipped", {
@@ -229,12 +234,21 @@ async function resolveSkillFolderMounts(skillFolders, context) {
229
234
  }
230
235
  const user = requestContext.get(MASTRA_USER_KEY);
231
236
  const client = user?.executionContext.client;
237
+ const userKey = user ? resolveUserKey(requestContext) : undefined;
238
+ const host = client ? (await client.config.getHost()).toString() : undefined;
232
239
  for (const [name, folder] of Object.entries(skillFolders)) {
233
- const filesystem = await resolveSkillFolderFilesystem(name, folder, context, client);
234
- if (!filesystem)
240
+ const resolved = await resolveSkillFolderFilesystem(name, folder, context, {
241
+ client,
242
+ host,
243
+ userKey,
244
+ workspaceSkillRefreshTtlMs,
245
+ });
246
+ if (!resolved)
235
247
  continue;
236
248
  const mount = folder.mount ?? `/${name}`;
237
- mounts[mount] = filesystem;
249
+ mounts[mount] = resolved.filesystem;
250
+ if (resolved.cacheKey)
251
+ cacheKeys.push(resolved.cacheKey);
238
252
  if (folder.readable !== false)
239
253
  skillPaths.push(mount);
240
254
  }
@@ -242,18 +256,25 @@ async function resolveSkillFolderMounts(skillFolders, context) {
242
256
  mountKeys: Object.keys(mounts),
243
257
  skillPaths,
244
258
  });
245
- return { mounts, skillPaths };
259
+ return {
260
+ mounts,
261
+ skillPaths,
262
+ ...(cacheKeys.length === Object.keys(mounts).length && cacheKeys.length > 0
263
+ ? { cacheKey: object.toStableKey(cacheKeys.sort()) }
264
+ : {}),
265
+ };
246
266
  }
247
267
  /**
248
268
  * Resolve one skill folder to a Mastra filesystem, or `undefined` to skip it
249
269
  * for this request.
250
270
  */
251
- async function resolveSkillFolderFilesystem(name, folder, context, client) {
271
+ async function resolveSkillFolderFilesystem(name, folder, context, cache) {
252
272
  if (folder.filesystem !== undefined) {
253
- return resolveSkillFolderValue(folder.filesystem, context);
273
+ const filesystem = await resolveSkillFolderValue(folder.filesystem, context);
274
+ return filesystem ? { filesystem } : undefined;
254
275
  }
255
276
  // A path mount needs the request's OBO client to reach the workspace.
256
- if (folder.path === undefined || !client) {
277
+ if (folder.path === undefined || !cache.client || !cache.host || !cache.userKey) {
257
278
  logger.debug("skill-folder:skipped", {
258
279
  name,
259
280
  reason: folder.path === undefined ? "no-location" : "missing-obo-client",
@@ -263,7 +284,11 @@ async function resolveSkillFolderFilesystem(name, folder, context, client) {
263
284
  const root = stringUtils.trimToNull(await resolveSkillFolderValue(folder.path, context));
264
285
  if (!root)
265
286
  return undefined;
266
- return databricksFilesystem(client, root, folder.writable !== true);
287
+ return databricksFilesystem(cache.client, root, folder.writable !== true, {
288
+ host: cache.host,
289
+ ttlMs: cache.workspaceSkillRefreshTtlMs,
290
+ userKey: cache.userKey,
291
+ });
267
292
  }
268
293
  /** Read a {@link SkillFolderValue}, calling it when it is a per-request resolver. */
269
294
  function resolveSkillFolderValue(value, context) {
@@ -287,11 +312,11 @@ function resolveWorkspaceIdentity(options) {
287
312
  return { id, name };
288
313
  }
289
314
  /** Collect the skill-folder resolver and any caller-supplied ones. */
290
- function buildMountResolvers(skillFolders, mounts) {
315
+ function buildMountResolvers(skillFolders, mounts, workspaceSkillRefreshTtlMs = DEFAULT_WORKSPACE_SKILL_CACHE_TTL_MS) {
291
316
  const resolvers = [];
292
317
  const folderCount = Object.keys(skillFolders).length;
293
318
  if (folderCount > 0) {
294
- resolvers.push((context) => resolveSkillFolderMounts(skillFolders, context));
319
+ resolvers.push((context) => resolveSkillFolderMounts(skillFolders, context, workspaceSkillRefreshTtlMs));
295
320
  }
296
321
  if (mounts?.length) {
297
322
  resolvers.push(...mounts);
@@ -323,18 +348,23 @@ function resolveScopedEmail(requestContext) {
323
348
  * missing (and {@link readOnly} so we will not create it), fall back to
324
349
  * {@link scratchFilesystem} so skill scans still have a writable local mount.
325
350
  */
326
- async function databricksFilesystem(client, root, readOnly = true) {
351
+ async function databricksFilesystem(client, root, readOnly = true, cache) {
327
352
  const fs = new DatabricksFileSystem({
328
353
  client: workspaceClient.toLegacyWorkspaceClient(client),
329
354
  root,
330
355
  readOnly,
331
356
  createRoot: !readOnly,
332
357
  });
358
+ const cached = cachedWorkspaceSkillMount({
359
+ host: cache.host,
360
+ source: fs,
361
+ ttlMs: cache.ttlMs,
362
+ userKey: cache.userKey,
363
+ });
333
364
  try {
334
- await fs.init();
335
- if (await fs.exists(".")) {
336
- return filesystems(fs, { readOnly });
337
- }
365
+ await cached.filesystem.init();
366
+ if (await cached.filesystem.exists("."))
367
+ return cached;
338
368
  }
339
369
  catch (err) {
340
370
  logger.debug("databricks-mount:scratch-fallback", {
@@ -343,7 +373,7 @@ async function databricksFilesystem(client, root, readOnly = true) {
343
373
  error: errorUtils.errorMessage(err),
344
374
  });
345
375
  }
346
- return scratchFilesystem();
376
+ return undefined;
347
377
  }
348
378
  /**
349
379
  * Run every mount resolver for one request and merge mounts plus skill paths.
@@ -352,6 +382,8 @@ async function databricksFilesystem(client, root, readOnly = true) {
352
382
  async function resolveWorkspaceContribution(resolvers, context) {
353
383
  const mounts = {};
354
384
  const skillPaths = [];
385
+ const cacheKeys = [];
386
+ let cacheable = true;
355
387
  for (const [index, resolver] of resolvers.entries()) {
356
388
  const contribution = await resolver(context);
357
389
  logger.debug("mounts:resolver", {
@@ -360,6 +392,12 @@ async function resolveWorkspaceContribution(resolvers, context) {
360
392
  skillPaths: contribution.skillPaths ?? [],
361
393
  });
362
394
  Object.assign(mounts, contribution.mounts);
395
+ if (Object.keys(contribution.mounts).length > 0) {
396
+ if (contribution.cacheKey)
397
+ cacheKeys.push(contribution.cacheKey);
398
+ else
399
+ cacheable = false;
400
+ }
363
401
  if (contribution.skillPaths?.length) {
364
402
  skillPaths.push(...contribution.skillPaths);
365
403
  }
@@ -368,7 +406,13 @@ async function resolveWorkspaceContribution(resolvers, context) {
368
406
  mountKeys: Object.keys(mounts),
369
407
  skillPaths,
370
408
  });
371
- return { mounts, skillPaths };
409
+ return {
410
+ mounts,
411
+ skillPaths,
412
+ ...(cacheable && cacheKeys.length > 0
413
+ ? { cacheKey: object.toStableKey(cacheKeys.sort()) }
414
+ : {}),
415
+ };
372
416
  }
373
417
  /**
374
418
  * Dynamic filesystem resolver passed to Mastra {@link Workspace}.
@@ -377,7 +421,7 @@ async function resolveWorkspaceContribution(resolvers, context) {
377
421
  * fresh {@link scratchFilesystem} so Mastra always has a writable local root.
378
422
  */
379
423
  async function resolveWorkspaceFilesystem(resolvers, context) {
380
- const { mounts } = await resolveWorkspaceContribution(resolvers, context);
424
+ const { cacheKey, mounts } = await resolveWorkspaceContribution(resolvers, context);
381
425
  const mountKeys = Object.keys(mounts);
382
426
  if (mountKeys.length === 0) {
383
427
  logger.debug("filesystem:scratch", {
@@ -386,7 +430,23 @@ async function resolveWorkspaceFilesystem(resolvers, context) {
386
430
  return scratchFilesystem();
387
431
  }
388
432
  logger.debug("filesystem:composite", { mountKeys });
389
- return new CompositeFilesystem({ mounts });
433
+ if (!cacheKey)
434
+ return new CompositeFilesystem({ mounts });
435
+ const existing = scopedWorkspaceFilesystems.get(cacheKey);
436
+ if (existing) {
437
+ scopedWorkspaceFilesystems.delete(cacheKey);
438
+ scopedWorkspaceFilesystems.set(cacheKey, existing);
439
+ return existing;
440
+ }
441
+ const filesystem = new CompositeFilesystem({ mounts });
442
+ scopedWorkspaceFilesystems.set(cacheKey, filesystem);
443
+ while (scopedWorkspaceFilesystems.size > MAX_SCOPED_WORKSPACE_FILESYSTEMS) {
444
+ const oldest = scopedWorkspaceFilesystems.keys().next().value;
445
+ if (oldest === undefined)
446
+ break;
447
+ scopedWorkspaceFilesystems.delete(oldest);
448
+ }
449
+ return filesystem;
390
450
  }
391
451
  /**
392
452
  * Build the dynamic {@link SkillsResolver} that collects `skillPaths` from
@@ -400,4 +460,4 @@ function buildWorkspaceSkillsResolver(resolvers, extraSkillPaths = []) {
400
460
  return merged;
401
461
  };
402
462
  }
403
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya3NwYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93b3Jrc3BhY2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRS9FLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM5RSxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRXJGLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsU0FBUyxHQU1WLE1BQU0sd0JBQXdCLENBQUM7QUFFaEMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLHFCQUFxQixFQUFFLGVBQWUsRUFBYSxNQUFNLGFBQWEsQ0FBQztBQUNuRyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxpQkFBaUIsRUFBMEMsTUFBTSxjQUFjLENBQUM7QUFDekYsT0FBTyxFQUFFLDRCQUE0QixFQUFFLHVCQUF1QixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFekYsNkVBQTZFO0FBRTdFLCtEQUErRDtBQUMvRCxNQUFNLHFCQUFxQixHQUFHLENBQUMsV0FBVyxFQUFFLHFCQUFxQixFQUFFLFVBQVUsQ0FBVSxDQUFDO0FBRXhGLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQztBQWdIL0MsOEVBQThFO0FBRTlFOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLE1BQU0scUJB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QyxDQUFDO1FBQ2pFLE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1hc3RyYSB3b3Jrc3BhY2UgZmFjdG9yeSBmb3IgRGF0YWJyaWNrcyBBcHBzLlxuICpcbiAqIEJ1aWxkcyBhIHBlci1yZXF1ZXN0IHtAbGluayBXb3Jrc3BhY2V9IHdpdGggRGF0YWJyaWNrcyBTYW5kYm94IGNvbW1hbmRcbiAqIGV4ZWN1dGlvbiBwbHVzIGEge0BsaW5rIENvbXBvc2l0ZUZpbGVzeXN0ZW19IG92ZXIgdGhlIE5BTUVEIHNraWxsIGZvbGRlcnNcbiAqIHJlc29sdmVkIGZvciB0aGF0IHJlcXVlc3QuIEEgc2tpbGwgZm9sZGVyIG1hcHMgYSBuYW1lIHRvIGEgbG9jYXRpb24gcGx1cyBpdHNcbiAqIHJlYWRhYmxlIC8gd3JpdGFibGUgcG9saWN5OiBhIERhdGFicmlja3MgcGF0aCBtb3VudGVkIHRocm91Z2ggdGhlIE9CTyBjbGllbnRcbiAqIG9uIHtAbGluayBNQVNUUkFfVVNFUl9LRVl9LCBvciBhbnkge0BsaW5rIFdvcmtzcGFjZUZpbGVzeXN0ZW19IGEgY29uc3VtaW5nXG4gKiBsaWJyYXJ5IGFscmVhZHkgb3ducy4ge0BsaW5rIERFRkFVTFRfU0tJTExfRk9MREVSU30gc3VwcGxpZXMgdGhlIEFzc2lzdGFudFxuICogdHJlZXMsIGFuZCBgc2tpbGxGb2xkZXJzYCBtZXJnZXMgb3ZlciBpdCAtIHNhbWUgbmFtZSBvdmVycmlkZXMsIGBmYWxzZWBcbiAqIGRpc2FibGVzLCBhIG5ldyBuYW1lIGFkZHMuIE9wdGlvbmFsIG1vdW50IHJlc29sdmVycyBjb250cmlidXRlIGZ1cnRoZXJcbiAqIGZpbGVzeXN0ZW1zIGFuZCBza2lsbCBzY2FuIHJvb3RzIG9uIHRvcC5cbiAqXG4gKiBEYXRhYnJpY2tzIG1vdW50cyB1c2UgYEBkYngtdG9vbHMvZGF0YWJyaWNrc2Age0BsaW5rIERhdGFicmlja3NGaWxlU3lzdGVtfVxuICogd3JhcHBlZCBieSB7QGxpbmsgZmlsZXN5c3RlbXN9OyBtaXNzaW5nIHJvb3RzIGZhbGwgYmFjayB0b1xuICoge0BsaW5rIHNjcmF0Y2hGaWxlc3lzdGVtfS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gXCJub2RlOmNyeXB0b1wiO1xuaW1wb3J0IHsgQ29uZmlndXJhdGlvbkVycm9yLCBjcmVhdGVXb3Jrc3BhY2VDbGllbnQgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgdHlwZSB7IFdvcmtzcGFjZUNsaWVudCB9IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7IERhdGFicmlja3NGaWxlU3lzdGVtLCB3b3Jrc3BhY2VDbGllbnQgfSBmcm9tIFwiQGRieC10b29scy9kYXRhYnJpY2tzXCI7XG5pbXBvcnQgeyBlcnJvclV0aWxzLCBsb2csIG9iamVjdCwgc3RyaW5nVXRpbHMsIHRva2VuIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB0eXBlIHsgUmVxdWVzdENvbnRleHQgfSBmcm9tIFwiQG1hc3RyYS9jb3JlL3JlcXVlc3QtY29udGV4dFwiO1xuaW1wb3J0IHtcbiAgQ29tcG9zaXRlRmlsZXN5c3RlbSxcbiAgV29ya3NwYWNlLFxuICB0eXBlIFNraWxsc0NvbnRleHQsXG4gIHR5cGUgU2tpbGxzUmVzb2x2ZXIsXG4gIHR5cGUgV29ya3NwYWNlRmlsZXN5c3RlbSxcbiAgdHlwZSBXb3Jrc3BhY2VTYW5kYm94LFxuICB0eXBlIFdvcmtzcGFjZVNhbmRib3hSZXNvbHZlcixcbn0gZnJvbSBcIkBtYXN0cmEvY29yZS93b3Jrc3BhY2VcIjtcblxuaW1wb3J0IHsgTUFTVFJBX1NDT1BFU19LRVksIE1BU1RSQV9VU0VSX0VNQUlMX0tFWSwgTUFTVFJBX1VTRVJfS0VZLCB0eXBlIFVzZXIgfSBmcm9tIFwiLi9jb25maWcudHNcIjtcbmltcG9ydCB7IHNjcmF0Y2hGaWxlc3lzdGVtLCBmaWxlc3lzdGVtcyB9IGZyb20gXCIuL2ZpbGVzeXN0ZW1zLnRzXCI7XG5pbXBvcnQgeyBNb250eVNhbmRib3ggfSBmcm9tIFwiLi9tb250eS1zYW5kYm94LnRzXCI7XG5pbXBvcnQgeyBEYXRhYnJpY2tzU2FuZGJveCwgdHlwZSBEYXRhYnJpY2tzV29ya3NwYWNlU2FuZGJveE9wdGlvbnMgfSBmcm9tIFwiLi9zYW5kYm94LnRzXCI7XG5pbXBvcnQgeyBBU1NJU1RBTlRfU0hBUkVEX1NLSUxMU19QQVRILCB1c2VyQXNzaXN0YW50U2tpbGxzUGF0aCB9IGZyb20gXCIuL3NraWxsLXBhdGhzLnRzXCI7XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBjb25zdGFudHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8qKiBPQXV0aCBzY29wZXMgdGhhdCBnYXRlIERhdGFicmlja3Mgd29ya3NwYWNlIGZpbGUgbW91bnRzLiAqL1xuY29uc3QgV09SS1NQQUNFX0ZJTEVfU0NPUEVTID0gW1wid29ya3NwYWNlXCIsIFwid29ya3NwYWNlLndvcmtzcGFjZVwiLCBcImFsbC1hcGlzXCJdIGFzIGNvbnN0O1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwibWFzdHJhL3dvcmtzcGFjZXNcIik7XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8qKiBQZXItcmVxdWVzdCBjb250ZXh0IGZvciBtb3VudCBhbmQgc2tpbGwtZm9sZGVyIHJlc29sdmVycy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV29ya3NwYWNlTW91bnRDb250ZXh0IHtcbiAgcmVxdWVzdENvbnRleHQ/OiBSZXF1ZXN0Q29udGV4dDtcbn1cblxuLyoqXG4gKiBBIHNraWxsLWZvbGRlciBmaWVsZCBnaXZlbiBlaXRoZXIgZGlyZWN0bHkgb3IgYXMgYSBwZXItcmVxdWVzdCByZXNvbHZlci5cbiAqIEEgcmVzb2x2ZXIgcmV0dXJuaW5nIGB1bmRlZmluZWRgIHNraXBzIHRoZSBmb2xkZXIgZm9yIHRoYXQgcmVxdWVzdC5cbiAqL1xuZXhwb3J0IHR5cGUgU2tpbGxGb2xkZXJWYWx1ZTxUPiA9XG4gIFQgfCAoKGNvbnRleHQ6IFdvcmtzcGFjZU1vdW50Q29udGV4dCkgPT4gVCB8IHVuZGVmaW5lZCB8IFByb21pc2U8VCB8IHVuZGVmaW5lZD4pO1xuXG4vKipcbiAqIE9uZSBuYW1lZCBza2lsbC1mb2xkZXIgbG9jYXRpb24gYW5kIGl0cyByZWFkIC8gd3JpdGUgcG9saWN5LlxuICpcbiAqIEdpdmUge0BsaW5rIHBhdGh9IGZvciBhIERhdGFicmlja3Mgd29ya3NwYWNlIHRyZWUgKG1vdW50ZWQgdGhyb3VnaCB0aGVcbiAqIHJlcXVlc3QncyBPQk8gY2xpZW50KSwgb3Ige0BsaW5rIGZpbGVzeXN0ZW19IGZvciBhIG1vdW50IHRoZSBjb25zdW1lciBidWlsZHNcbiAqIGl0c2VsZi4ge0BsaW5rIGZpbGVzeXN0ZW19IHdpbnMgd2hlbiBib3RoIGFyZSBzZXQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2tpbGxGb2xkZXJPcHRpb25zIHtcbiAgLyoqIEFic29sdXRlIERhdGFicmlja3Mgd29ya3NwYWNlIHBhdGggZm9yIHRoaXMgZm9sZGVyLiAqL1xuICBwYXRoPzogU2tpbGxGb2xkZXJWYWx1ZTxzdHJpbmc+O1xuICAvKiogUmVhZHktbWFkZSBtb3VudCwgZm9yIGxvY2F0aW9ucyB0aGUgT0JPIGNsaWVudCBjYW5ub3QgcmVhY2guICovXG4gIGZpbGVzeXN0ZW0/OiBTa2lsbEZvbGRlclZhbHVlPFdvcmtzcGFjZUZpbGVzeXN0ZW0+O1xuICAvKipcbiAgICogU2NhbiB0aGlzIG1vdW50IGZvciBgU0tJTEwubWRgIGZpbGVzLiBEZWZhdWx0cyB0byBgdHJ1ZWA7IGBmYWxzZWAgbW91bnRzXG4gICAqIHRoZSBsb2NhdGlvbiBmb3IgZmlsZSB0b29scyB3aXRob3V0IGFkZGluZyBpdCB0byBza2lsbCBkaXNjb3ZlcnkuXG4gICAqL1xuICByZWFkYWJsZT86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBBbGxvdyB3cml0ZXMgdG8gYSB7QGxpbmsgcGF0aH0gbW91bnQgKGFuZCBjcmVhdGUgdGhlIHJvb3Qgd2hlbiBtaXNzaW5nKS5cbiAgICogRGVmYXVsdHMgdG8gYGZhbHNlYC4gQSBzdXBwbGllZCB7QGxpbmsgZmlsZXN5c3RlbX0gY2FycmllcyBpdHMgb3duXG4gICAqIHJlYWQtb25seSBmbGFnIGluc3RlYWQuXG4gICAqL1xuICB3cml0YWJsZT86IGJvb2xlYW47XG4gIC8qKiBNb3VudCBwb2ludCBpbiB0aGUgY29tcG9zaXRlIG5hbWVzcGFjZS4gRGVmYXVsdHMgdG8gYC88bmFtZT5gLiAqL1xuICBtb3VudD86IHN0cmluZztcbn1cblxuLyoqIE1vdW50IG1hcCBwbHVzIG9wdGlvbmFsIE1hc3RyYSBza2lsbCBzY2FuIHJvb3RzIGZvciBvbmUgcmVzb2x2ZXIuICovXG5leHBvcnQgaW50ZXJmYWNlIFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uIHtcbiAgbW91bnRzOiBSZWNvcmQ8c3RyaW5nLCBXb3Jrc3BhY2VGaWxlc3lzdGVtPjtcbiAgLyoqIFBhdGhzIHdpdGhpbiB0aGUgY29tcG9zaXRlIG5hbWVzcGFjZSB3aGVyZSBgU0tJTEwubWRgIGZpbGVzIGFyZSBzY2FubmVkLiAqL1xuICBza2lsbFBhdGhzPzogc3RyaW5nW107XG59XG5cbi8qKiBDb250cmlidXRlcyBmaWxlc3lzdGVtIG1vdW50cyAoYW5kIG9wdGlvbmFsIHNraWxsIHBhdGhzKSBmb3Igb25lIHJlcXVlc3QuICovXG5leHBvcnQgdHlwZSBXb3Jrc3BhY2VNb3VudFJlc29sdmVyID0gKFxuICBjb250ZXh0OiBXb3Jrc3BhY2VNb3VudENvbnRleHQsXG4pID0+IFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uIHwgUHJvbWlzZTxXb3Jrc3BhY2VNb3VudENvbnRyaWJ1dGlvbj47XG5cbi8qKiBOYW1lcyBjYXJyaWVkIGJ5IHtAbGluayBERUZBVUxUX1NLSUxMX0ZPTERFUlN9LiAqL1xuZXhwb3J0IHR5cGUgRGVmYXVsdFNraWxsRm9sZGVyTmFtZSA9IFwid29ya3NwYWNlLXRlYW1cIiB8IFwid29ya3NwYWNlLXRlYW0tYXBwXCI7XG5cbi8qKlxuICogU2FuZGJveCBzZWxlY3Rpb24gZm9yIHtAbGluayBjcmVhdGVXb3Jrc3BhY2V9LiBEYXRhYnJpY2tzIGlzIHRoZSBkZWZhdWx0O1xuICogYGZhbHNlYCBkaXNhYmxlcyBjb21tYW5kIGV4ZWN1dGlvbiwgYW5kIGEgTWFzdHJhIHByb3ZpZGVyIG9yIHJlc29sdmVyIGlzIGFuXG4gKiBleHBsaWNpdCByZXBsYWNlbWVudC5cbiAqL1xuZXhwb3J0IHR5cGUgV29ya3NwYWNlU2FuZGJveFNlbGVjdGlvbiA9XG4gIHwgZmFsc2VcbiAgfCBcImRhdGFicmlja3NcIlxuICB8IFwibW9udHlcIlxuICB8IERhdGFicmlja3NXb3Jrc3BhY2VTYW5kYm94T3B0aW9uc1xuICB8IFdvcmtzcGFjZVNhbmRib3hcbiAgfCBXb3Jrc3BhY2VTYW5kYm94UmVzb2x2ZXI7XG5cbi8qKiBPcHRpb25zIGZvciB7QGxpbmsgY3JlYXRlV29ya3NwYWNlfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlV29ya3NwYWNlT3B0aW9ucyB7XG4gIC8qKiBXb3Jrc3BhY2UgaWQ7IGRlcml2ZWQgZnJvbSBgbmFtZWAgb3IgYFwid29ya3NwYWNlXCJgIHdoZW4gb21pdHRlZC4gKi9cbiAgaWQ/OiBzdHJpbmc7XG4gIC8qKiBEaXNwbGF5IG5hbWU7IGRlcml2ZWQgZnJvbSBgaWRgIHdoZW4gb21pdHRlZC4gKi9cbiAgbmFtZT86IHN0cmluZztcbiAgLyoqXG4gICAqIFN0YXJ0IGZyb20ge0BsaW5rIERFRkFVTFRfU0tJTExfRk9MREVSU30uIERlZmF1bHRzIHRvIGB0cnVlYDsgYGZhbHNlYFxuICAgKiBzdGFydHMgZnJvbSBhbiBlbXB0eSBtYXAsIGxlYXZpbmcgb25seSB0aGUge0BsaW5rIHNraWxsRm9sZGVyc30gZ2l2ZW4gaGVyZS5cbiAgICovXG4gIGFzc2lzdGFudFNraWxscz86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBOYW1lZCBza2lsbCBmb2xkZXJzIG1lcmdlZCBvdmVyIHtAbGluayBERUZBVUxUX1NLSUxMX0ZPTERFUlN9OiBhIG1hdGNoaW5nXG4gICAqIG5hbWUgb3ZlcnJpZGVzIHRoYXQgZGVmYXVsdCwgYGZhbHNlYCBkaXNhYmxlcyBpdCwgYW5kIGFueSBvdGhlciBuYW1lIGFkZHNcbiAgICogYSBmb2xkZXIuXG4gICAqL1xuICBza2lsbEZvbGRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBTa2lsbEZvbGRlck9wdGlvbnMgfCBmYWxzZT47XG4gIC8qKiBFeHRyYSBwZXItcmVxdWVzdCBtb3VudCByZXNvbHZlcnMgKHJ1biBhZnRlciB0aGUgc2tpbGwtZm9sZGVyIG1vdW50cykuICovXG4gIG1vdW50cz86IFdvcmtzcGFjZU1vdW50UmVzb2x2ZXJbXTtcbiAgLyoqIFJlcGxhY2UgdGhlIGF1dG8tYnVpbHQgZHluYW1pYyBza2lsbHMgcmVzb2x2ZXIuICovXG4gIHNraWxscz86IFNraWxsc1Jlc29sdmVyO1xuICAvKiogRm9yd2FyZGVkIHRvIE1hc3RyYSB3aGVuIHNraWxsIGRpc2NvdmVyeSBpcyBlbmFibGVkLiAqL1xuICBjaGVja1NraWxsRmlsZU10aW1lPzogYm9vbGVhbjtcbiAgLyoqIEVuYWJsZSBCTTI1IGtleXdvcmQgc2VhcmNoIG92ZXIgaW5kZXhlZCB3b3Jrc3BhY2UgY29udGVudC4gKi9cbiAgYm0yNT86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBDb21tYW5kIHNhbmRib3guIERlZmF1bHRzIHRvIERhdGFicmlja3MgU2FuZGJveC4gUGFzcyBgZmFsc2VgIHRvIGRpc2FibGVcbiAgICogY29tbWFuZCBleGVjdXRpb24sIG9yIGFuIGV4cGxpY2l0IE1hc3RyYSBzYW5kYm94L3Byb3ZpZGVyIHJlc29sdmVyIHRvXG4gICAqIHJlcGxhY2UgRGF0YWJyaWNrcyBmb3IgdGhpcyB3b3Jrc3BhY2UuXG4gICAqL1xuICBzYW5kYm94PzogV29ya3NwYWNlU2FuZGJveFNlbGVjdGlvbjtcbiAgLyoqXG4gICAqIEV4dHJhIExPQ0FMIHNraWxsIHNjYW4gcGF0aHMgYWRkZWQgdG8gZXZlcnkgcmVxdWVzdCdzIHNraWxsIGRpc2NvdmVyeS5cbiAgICogVXNlZCBieSB0aGUgcGx1Z2luIHRvIHN1cmZhY2UgcmVtb3RlIHNraWxscyBwcm92aXNpb25lZCB0byBhIGxvY2FsIHRlbXBcbiAgICogZGlyIGF0IHN0YXJ0dXAgKHNlZSBgcmVtb3RlLXNraWxscy50c2ApLiBEYXRhYnJpY2tzLWhvc3RlZCByZW1vdGUgc2tpbGxzXG4gICAqIG5lZWQgbm8gZW50cnkgaGVyZSAtIHRoZXkgbGFuZCBpbiB0aGUgQXNzaXN0YW50IHRyZWUgdGhlIGJ1aWx0LWluIG1vdW50XG4gICAqIGFscmVhZHkgc2NhbnMuXG4gICAqL1xuICBleHRyYVNraWxsUGF0aHM/OiBzdHJpbmdbXTtcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBkZWZhdWx0cyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8qKlxuICogVGhlIHNraWxsIGZvbGRlcnMgZXZlcnkgd29ya3NwYWNlIHN0YXJ0cyB3aXRoLlxuICpcbiAqIC0gYHdvcmtzcGFjZS10ZWFtYCAtIHRoZSBzaGFyZWQgd29ya3NwYWNlIEFzc2lzdGFudCB0cmVlLCByZWFkLW9ubHkgYmVjYXVzZVxuICogICB3cml0aW5nIGl0IGlzIGEgd29ya3NwYWNlLWFkbWluIGFjdGlvbi5cbiAqIC0gYHdvcmtzcGFjZS10ZWFtLWFwcGAgLSB0aGUgcmVxdWVzdGluZyB1c2VyJ3Mgb3duIEFzc2lzdGFudCB0cmVlLCB3cml0YWJsZVxuICogICBzbyB0aGUgYXBwIGNhbiBzYXZlIHNraWxscyBiYWNrIHRvIGl0LiBTa2lwcGVkIHdoZW4gdGhlIHJlcXVlc3QgY2FycmllcyBub1xuICogICB1c2VyIGVtYWlsLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9TS0lMTF9GT0xERVJTOiBSZWFkb25seTxSZWNvcmQ8RGVmYXVsdFNraWxsRm9sZGVyTmFtZSwgU2tpbGxGb2xkZXJPcHRpb25zPj4gPSB7XG4gIFwid29ya3NwYWNlLXRlYW1cIjoge1xuICAgIHBhdGg6IEFTU0lTVEFOVF9TSEFSRURfU0tJTExTX1BBVEgsXG4gICAgcmVhZGFibGU6IHRydWUsXG4gICAgd3JpdGFibGU6IGZhbHNlLFxuICB9LFxuICBcIndvcmtzcGFjZS10ZWFtLWFwcFwiOiB7XG4gICAgcGF0aDogKHsgcmVxdWVzdENvbnRleHQgfSkgPT4ge1xuICAgICAgY29uc3QgZW1haWwgPSByZXNvbHZlU2NvcGVkRW1haWwocmVxdWVzdENvbnRleHQpO1xuICAgICAgcmV0dXJuIGVtYWlsID8gdXNlckFzc2lzdGFudFNraWxsc1BhdGgoZW1haWwpIDogdW5kZWZpbmVkO1xuICAgIH0sXG4gICAgcmVhZGFibGU6IHRydWUsXG4gICAgd3JpdGFibGU6IHRydWUsXG4gIH0sXG59O1xuXG4vKipcbiAqIENyZWF0ZSBhIE1hc3RyYSB7QGxpbmsgV29ya3NwYWNlfSB3aXRoIHBlci1yZXF1ZXN0IERhdGFicmlja3MgbW91bnRzLlxuICpcbiAqIEBleGFtcGxlIERlZmF1bHQgc2tpbGwgZm9sZGVycyBvbmx5XG4gKiBgYGB0c1xuICogY3JlYXRlV29ya3NwYWNlKClcbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlIE92ZXJyaWRlIGEgZGVmYXVsdCwgZHJvcCBhbm90aGVyLCBhbmQgYWRkIGEgbG9jYXRpb24gb2YgeW91ciBvd25cbiAqIGBgYHRzXG4gKiBjcmVhdGVXb3Jrc3BhY2Uoe1xuICogICBza2lsbEZvbGRlcnM6IHtcbiAqICAgICBcIndvcmtzcGFjZS10ZWFtXCI6IHsgcGF0aDogXCIvV29ya3NwYWNlL1NoYXJlZC90ZWFtLXNraWxsc1wiIH0sXG4gKiAgICAgXCJ3b3Jrc3BhY2UtdGVhbS1hcHBcIjogZmFsc2UsXG4gKiAgICAgcnVuYm9va3M6IHsgcGF0aDogXCIvV29ya3NwYWNlL1NoYXJlZC9ydW5ib29rcy9za2lsbHNcIiwgd3JpdGFibGU6IHRydWUgfSxcbiAqICAgICB2b2x1bWU6IHsgZmlsZXN5c3RlbTogbXlWb2x1bWVGaWxlc3lzdGVtIH0sXG4gKiAgIH0sXG4gKiB9KVxuICogYGBgXG4gKlxuICogQGV4YW1wbGUgU2tpbGwgZm9sZGVycyBwbHVzIGEgY3VzdG9tIG1vdW50IHJlc29sdmVyXG4gKiBgYGB0c1xuICogY3JlYXRlV29ya3NwYWNlKHtcbiAqICAgbW91bnRzOiBbXG4gKiAgICAgYXN5bmMgKHsgcmVxdWVzdENvbnRleHQgfSkgPT4gKHtcbiAqICAgICAgIG1vdW50czogeyBcIi9kYXRhXCI6IG15RmlsZXN5c3RlbSB9LFxuICogICAgICAgc2tpbGxQYXRoczogW10sXG4gKiAgICAgfSksXG4gKiAgIF0sXG4gKiB9KVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVXb3Jrc3BhY2Uob3B0aW9uczogQ3JlYXRlV29ya3NwYWNlT3B0aW9ucyA9IHt9KTogV29ya3NwYWNlIHtcbiAgY29uc3QgeyBpZCwgbmFtZSB9ID0gcmVzb2x2ZVdvcmtzcGFjZUlkZW50aXR5KG9wdGlvbnMpO1xuICBjb25zdCBza2lsbEZvbGRlcnMgPSByZXNvbHZlU2tpbGxGb2xkZXJzKG9wdGlvbnMpO1xuICBjb25zdCBmb2xkZXJOYW1lcyA9IE9iamVjdC5rZXlzKHNraWxsRm9sZGVycyk7XG4gIGNvbnN0IHJlc29sdmVycyA9IGJ1aWxkTW91bnRSZXNvbHZlcnMoc2tpbGxGb2xkZXJzLCBvcHRpb25zLm1vdW50cyk7XG4gIGNvbnN0IGV4dHJhU2tpbGxQYXRocyA9IG9wdGlvbnMuZXh0cmFTa2lsbFBhdGhzID8/IFtdO1xuICBjb25zdCBza2lsbHMgPVxuICAgIG9wdGlvbnMuc2tpbGxzID8/XG4gICAgKHJlc29sdmVycy5sZW5ndGggPiAwIHx8IGV4dHJhU2tpbGxQYXRocy5sZW5ndGggPiAwXG4gICAgICA/IGJ1aWxkV29ya3NwYWNlU2tpbGxzUmVzb2x2ZXIocmVzb2x2ZXJzLCBleHRyYVNraWxsUGF0aHMpXG4gICAgICA6IHVuZGVmaW5lZCk7XG4gIGNvbnN0IGNoZWNrU2tpbGxGaWxlTXRpbWUgPSBvcHRpb25zLmNoZWNrU2tpbGxGaWxlTXRpbWUgPz8gZm9sZGVyTmFtZXMubGVuZ3RoID4gMDtcbiAgY29uc3QgYm0yNSA9IG9wdGlvbnMuYm0yNSAhPT0gZmFsc2U7XG4gIGNvbnN0IHNhbmRib3ggPSByZXNvbHZlV29ya3NwYWNlU2FuZGJveChvcHRpb25zLnNhbmRib3gsIGlkLCBuYW1lKTtcbiAgbG9nZ2VyLmRlYnVnKFwid29ya3NwYWNlOmNyZWF0ZVwiLCB7XG4gICAgaWQsXG4gICAgbmFtZSxcbiAgICByZXNvbHZlckNvdW50OiByZXNvbHZlcnMubGVuZ3RoLFxuICAgIHNraWxsRm9sZGVyczogZm9sZGVyTmFtZXMsXG4gICAgY3VzdG9tTW91bnRSZXNvbHZlcnM6IG9wdGlvbnMubW91bnRzPy5sZW5ndGggPz8gMCxcbiAgICBjdXN0b21Ta2lsbHNSZXNvbHZlcjogQm9vbGVhbihvcHRpb25zLnNraWxscyksXG4gICAgY2hlY2tTa2lsbEZpbGVNdGltZSxcbiAgICBibTI1LFxuICAgIGV4dHJhU2tpbGxQYXRoczogZXh0cmFTa2lsbFBhdGhzLmxlbmd0aCxcbiAgICBzYW5kYm94OiBzYW5kYm94ID8gc2FuZGJveE5hbWUob3B0aW9ucy5zYW5kYm94KSA6IFwiZGlzYWJsZWRcIixcbiAgfSk7XG5cbiAgcmV0dXJuIG5ldyBXb3Jrc3BhY2Uoe1xuICAgIGlkLFxuICAgIG5hbWUsXG4gICAgZmlsZXN5c3RlbTogKGNvbnRleHQpID0+IHJlc29sdmVXb3Jrc3BhY2VGaWxlc3lzdGVtKHJlc29sdmVycywgY29udGV4dCksXG4gICAgLi4uKHNraWxsc1xuICAgICAgPyB7XG4gICAgICAgICAgc2tpbGxzLFxuICAgICAgICAgIGNoZWNrU2tpbGxGaWxlTXRpbWUsXG4gICAgICAgIH1cbiAgICAgIDoge30pLFxuICAgIC4uLihzYW5kYm94XG4gICAgICA/IHtcbiAgICAgICAgICBzYW5kYm94LFxuICAgICAgICAgIGluc3RydWN0aW9uczogeyBkeW5hbWljU2FuZGJveDogXCJyZXNvbHZlXCIgYXMgY29uc3QgfSxcbiAgICAgICAgfVxuICAgICAgOiB7fSksXG4gICAgYm0yNSxcbiAgfSk7XG59XG5cbi8qKlxuICogTWVyZ2UgdGhlIGNvbmZpZ3VyZWQgc2tpbGwgZm9sZGVycyBvdmVyIHtAbGluayBERUZBVUxUX1NLSUxMX0ZPTERFUlN9LlxuICpcbiAqIGBhc3Npc3RhbnRTa2lsbHM6IGZhbHNlYCBkcm9wcyB0aGUgZGVmYXVsdHMsIGFuZCBhIGBmYWxzZWAgdmFsdWUgcmVtb3ZlcyBvbmVcbiAqIGVudHJ5IGJ5IG5hbWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlU2tpbGxGb2xkZXJzKFxuICBvcHRpb25zOiBQaWNrPENyZWF0ZVdvcmtzcGFjZU9wdGlvbnMsIFwiYXNzaXN0YW50U2tpbGxzXCIgfCBcInNraWxsRm9sZGVyc1wiPiA9IHt9LFxuKTogUmVjb3JkPHN0cmluZywgU2tpbGxGb2xkZXJPcHRpb25zPiB7XG4gIGNvbnN0IG1lcmdlZDogUmVjb3JkPHN0cmluZywgU2tpbGxGb2xkZXJPcHRpb25zPiA9XG4gICAgb3B0aW9ucy5hc3Npc3RhbnRTa2lsbHMgPT09IGZhbHNlID8ge30gOiB7IC4uLkRFRkFVTFRfU0tJTExfRk9MREVSUyB9O1xuICBmb3IgKGNvbnN0IFtuYW1lLCBmb2xkZXJdIG9mIE9iamVjdC5lbnRyaWVzKG9wdGlvbnMuc2tpbGxGb2xkZXJzID8/IHt9KSkge1xuICAgIGlmIChmb2xkZXIgPT09IGZhbHNlKSB7XG4gICAgICBkZWxldGUgbWVyZ2VkW25hbWVdO1xuICAgIH0gZWxzZSB7XG4gICAgICBtZXJnZWRbbmFtZV0gPSBmb2xkZXI7XG4gICAgfVxuICB9XG4gIHJldHVybiBtZXJnZWQ7XG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gcHJpdmF0ZSBoZWxwZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuZnVuY3Rpb24gcmVzb2x2ZVdvcmtzcGFjZVNhbmRib3goXG4gIHNlbGVjdGlvbjogV29ya3NwYWNlU2FuZGJveFNlbGVjdGlvbiB8IHVuZGVmaW5lZCxcbiAgd29ya3NwYWNlSWQ6IHN0cmluZyxcbiAgd29ya3NwYWNlTmFtZTogc3RyaW5nLFxuKTogV29ya3NwYWNlU2FuZGJveCB8IFdvcmtzcGFjZVNhbmRib3hSZXNvbHZlciB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGNvbmZpZ3VyZWQgPSBzZWxlY3Rpb24gPz8gXCJkYXRhYnJpY2tzXCI7XG4gIGlmIChjb25maWd1cmVkID09PSBmYWxzZSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgaWYgKGNvbmZpZ3VyZWQgPT09IFwibW9udHlcIikgcmV0dXJuIG5ldyBNb250eVNhbmRib3goKTtcbiAgaWYgKHR5cGVvZiBjb25maWd1cmVkID09PSBcImZ1bmN0aW9uXCIgfHwgaXNTYW5kYm94KGNvbmZpZ3VyZWQpKSByZXR1cm4gY29uZmlndXJlZDtcblxuICBjb25zdCBvcHRpb25zOiBEYXRhYnJpY2tzV29ya3NwYWNlU2FuZGJveE9wdGlvbnMgPVxuICAgIGNvbmZpZ3VyZWQgPT09IFwiZGF0YWJyaWNrc1wiID8geyBwcm92aWRlcjogXCJkYXRhYnJpY2tzXCIgfSA6IGNvbmZpZ3VyZWQ7XG4gIHJldHVybiAoeyByZXF1ZXN0Q29udGV4dCB9KSA9PiB7XG4gICAgY29uc3QgdXNlciA9IHJlcXVlc3RDb250ZXh0LmdldChNQVNUUkFfVVNFUl9LRVkpIGFzIFVzZXIgfCB1bmRlZmluZWQ7XG4gICAgaWYgKCF1c2VyKSB7XG4gICAgICB0aHJvdyBDb25maWd1cmF0aW9uRXJyb3IucmVzb3VyY2VOb3RGb3VuZChcbiAgICAgICAgXCJEYXRhYnJpY2tzIHNhbmRib3ggdXNlciBjb250ZXh0XCIsXG4gICAgICAgIFwiSW52b2tlIGNvbW1hbmQgdG9vbHMgZnJvbSBhbiBhZ2VudCB0dXJuIHNlcnZlZCBieSB0aGUgTWFzdHJhIHBsdWdpbi5cIixcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IGNvbmZpZ3VyZWRJZCA9XG4gICAgICB0eXBlb2Ygb3B0aW9ucy5zYW5kYm94SWQgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICA/IG9wdGlvbnMuc2FuZGJveElkKHsgcmVxdWVzdENvbnRleHQgfSlcbiAgICAgICAgOiBvcHRpb25zLnNhbmRib3hJZDtcbiAgICBjb25zdCBzYW5kYm94SWQgPSBjb25maWd1cmVkSWQgPz8gZGVmYXVsdFNhbmRib3hJZCh3b3Jrc3BhY2VJZCwgdXNlci5pZCk7XG4gICAgY29uc3QgY2xpZW50ID1cbiAgICAgIHR5cGVvZiBvcHRpb25zLmNsaWVudCA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgID8gb3B0aW9ucy5jbGllbnQoeyByZXF1ZXN0Q29udGV4dCB9KVxuICAgICAgICA6IChvcHRpb25zLmNsaWVudCA/PyBjcmVhdGVXb3Jrc3BhY2VDbGllbnQoKSk7XG4gICAgY29uc3Qge1xuICAgICAgcHJvdmlkZXI6IF9wcm92aWRlcixcbiAgICAgIHNhbmRib3hJZDogX3NhbmRib3hJZCxcbiAgICAgIGNsaWVudDogX2NsaWVudCxcbiAgICAgIC4uLnNhbmRib3hPcHRpb25zXG4gICAgfSA9IG9wdGlvbnM7XG4gICAgcmV0dXJuIG5ldyBEYXRhYnJpY2tzU2FuZGJveCh7XG4gICAgICAuLi5zYW5kYm94T3B0aW9ucyxcbiAgICAgIGNsaWVudCxcbiAgICAgIHNhbmRib3hJZCxcbiAgICAgIGRpc3BsYXlOYW1lOiBvcHRpb25zLmRpc3BsYXlOYW1lID8/IGBNYXN0cmEgJHt3b3Jrc3BhY2VOYW1lfWAsXG4gICAgfSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRTYW5kYm94SWQod29ya3NwYWNlSWQ6IHN0cmluZywgdXNlcklkOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBkaWdlc3QgPSBjcmVhdGVIYXNoKFwic2hhMjU2XCIpXG4gICAgLnVwZGF0ZShvYmplY3QudG9TdGFibGVLZXkoeyB3b3Jrc3BhY2VJZCwgdXNlcklkIH0pKVxuICAgIC5kaWdlc3QoXCJoZXhcIilcbiAgICAuc2xpY2UoMCwgMzIpO1xuICByZXR1cm4gYG1hc3RyYS0ke2RpZ2VzdH1gO1xufVxuXG5mdW5jdGlvbiBpc1NhbmRib3godmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBXb3Jrc3BhY2VTYW5kYm94IHtcbiAgcmV0dXJuIEJvb2xlYW4oXG4gICAgdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIFwiaWRcIiBpbiB2YWx1ZSAmJiBcInByb3ZpZGVyXCIgaW4gdmFsdWUgJiYgXCJzdGF0dXNcIiBpbiB2YWx1ZSxcbiAgKTtcbn1cblxuZnVuY3Rpb24gc2FuZGJveE5hbWUoc2VsZWN0aW9uOiBXb3Jrc3BhY2VTYW5kYm94U2VsZWN0aW9uIHwgdW5kZWZpbmVkKTogc3RyaW5nIHtcbiAgaWYgKHNlbGVjdGlvbiA9PT0gdW5kZWZpbmVkIHx8IHNlbGVjdGlvbiA9PT0gXCJkYXRhYnJpY2tzXCIpIHJldHVybiBcImRhdGFicmlja3NcIjtcbiAgaWYgKHNlbGVjdGlvbiA9PT0gXCJtb250eVwiKSByZXR1cm4gXCJtb250eVwiO1xuICBpZiAoc2VsZWN0aW9uID09PSBmYWxzZSkgcmV0dXJuIFwiZGlzYWJsZWRcIjtcbiAgaWYgKHR5cGVvZiBzZWxlY3Rpb24gPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFwicmVzb2x2ZXJcIjtcbiAgcmV0dXJuIGlzU2FuZGJveChzZWxlY3Rpb24pID8gc2VsZWN0aW9uLnByb3ZpZGVyIDogKHNlbGVjdGlvbi5wcm92aWRlciA/PyBcImRhdGFicmlja3NcIik7XG59XG5cbi8qKlxuICogUmV0dXJuIHdoZXRoZXIgdGhlIHJlcXVlc3QgdG9rZW4gY2FycmllcyBhIHNjb3BlIHRoYXQgYWxsb3dzIHdvcmtzcGFjZVxuICogZmlsZSBBUEkgYWNjZXNzIChgd29ya3NwYWNlYCBvciBgYWxsLWFwaXNgIG9uIHtAbGluayBNQVNUUkFfU0NPUEVTX0tFWX0pLlxuICovXG5mdW5jdGlvbiBoYXNXb3Jrc3BhY2VGaWxlU2NvcGUocmVxdWVzdENvbnRleHQ6IFJlcXVlc3RDb250ZXh0IHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gIHJldHVybiB0b2tlbi5pbmNsdWRlc0FjY2Vzc1Rva2VuU2NvcGUoXG4gICAgcmVxdWVzdENvbnRleHQ/LmdldChNQVNUUkFfU0NPUEVTX0tFWSksXG4gICAgV09SS1NQQUNFX0ZJTEVfU0NPUEVTLFxuICApO1xufVxuXG4vKipcbiAqIE1vdW50IHJlc29sdmVyIGZvciB0aGUgbmFtZWQgc2tpbGwgZm9sZGVycy5cbiAqXG4gKiBHYXRlcyBvbiB3b3Jrc3BhY2UgZmlsZSBzY29wZSAob3IgZGV2ZWxvcG1lbnQgbW9kZSksIHRoZW4gbW91bnRzIGV2ZXJ5XG4gKiBmb2xkZXIgd2hvc2UgbG9jYXRpb24gcmVzb2x2ZXMgZm9yIHRoaXMgcmVxdWVzdC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZVNraWxsRm9sZGVyTW91bnRzKFxuICBza2lsbEZvbGRlcnM6IFJlY29yZDxzdHJpbmcsIFNraWxsRm9sZGVyT3B0aW9ucz4sXG4gIGNvbnRleHQ6IFdvcmtzcGFjZU1vdW50Q29udGV4dCxcbik6IFByb21pc2U8V29ya3NwYWNlTW91bnRDb250cmlidXRpb24+IHtcbiAgY29uc3QgbW91bnRzOiBSZWNvcmQ8c3RyaW5nLCBXb3Jrc3BhY2VGaWxlc3lzdGVtPiA9IHt9O1xuICBjb25zdCBza2lsbFBhdGhzOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCByZXF1ZXN0Q29udGV4dCA9IGNvbnRleHQucmVxdWVzdENvbnRleHQ7XG5cbiAgaWYgKCFyZXF1ZXN0Q29udGV4dCB8fCAhc2hvdWxkTW91bnRTa2lsbEZvbGRlcnMocmVxdWVzdENvbnRleHQpKSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwic2tpbGwtZm9sZGVyczpza2lwcGVkXCIsIHtcbiAgICAgIHJlYXNvbjogIXJlcXVlc3RDb250ZXh0ID8gXCJuby1yZXF1ZXN0LWNvbnRleHRcIiA6IFwibWlzc2luZy13b3Jrc3BhY2Utc2NvcGVcIixcbiAgICAgIG5vZGVFbnY6IHByb2Nlc3MuZW52Lk5PREVfRU5WLFxuICAgICAgc2NvcGVzOiByZXF1ZXN0Q29udGV4dD8uZ2V0KE1BU1RSQV9TQ09QRVNfS0VZKSxcbiAgICB9KTtcbiAgICByZXR1cm4geyBtb3VudHMsIHNraWxsUGF0aHMgfTtcbiAgfVxuXG4gIGNvbnN0IHVzZXIgPSByZXF1ZXN0Q29udGV4dC5nZXQoTUFTVFJBX1VTRVJfS0VZKSBhcyBVc2VyIHwgdW5kZWZpbmVkO1xuICBjb25zdCBjbGllbnQgPSB1c2VyPy5leGVjdXRpb25Db250ZXh0LmNsaWVudCBhcyBXb3Jrc3BhY2VDbGllbnQgfCB1bmRlZmluZWQ7XG5cbiAgZm9yIChjb25zdCBbbmFtZSwgZm9sZGVyXSBvZiBPYmplY3QuZW50cmllcyhza2lsbEZvbGRlcnMpKSB7XG4gICAgY29uc3QgZmlsZXN5c3RlbSA9IGF3YWl0IHJlc29sdmVTa2lsbEZvbGRlckZpbGVzeXN0ZW0obmFtZSwgZm9sZGVyLCBjb250ZXh0LCBjbGllbnQpO1xuICAgIGlmICghZmlsZXN5c3RlbSkgY29udGludWU7XG4gICAgY29uc3QgbW91bnQgPSBmb2xkZXIubW91bnQgPz8gYC8ke25hbWV9YDtcbiAgICBtb3VudHNbbW91bnRdID0gZmlsZXN5c3RlbTtcbiAgICBpZiAoZm9sZGVyLnJlYWRhYmxlICE9PSBmYWxzZSkgc2tpbGxQYXRocy5wdXNoKG1vdW50KTtcbiAgfVxuXG4gIGxvZ2dlci5kZWJ1ZyhcInNraWxsLWZvbGRlcnM6bW91bnRlZFwiLCB7XG4gICAgbW91bnRLZXlzOiBPYmplY3Qua2V5cyhtb3VudHMpLFxuICAgIHNraWxsUGF0aHMsXG4gIH0pO1xuXG4gIHJldHVybiB7IG1vdW50cywgc2tpbGxQYXRocyB9O1xufVxuXG4vKipcbiAqIFJlc29sdmUgb25lIHNraWxsIGZvbGRlciB0byBhIE1hc3RyYSBmaWxlc3lzdGVtLCBvciBgdW5kZWZpbmVkYCB0byBza2lwIGl0XG4gKiBmb3IgdGhpcyByZXF1ZXN0LlxuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlU2tpbGxGb2xkZXJGaWxlc3lzdGVtKFxuICBuYW1lOiBzdHJpbmcsXG4gIGZvbGRlcjogU2tpbGxGb2xkZXJPcHRpb25zLFxuICBjb250ZXh0OiBXb3Jrc3BhY2VNb3VudENvbnRleHQsXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50IHwgdW5kZWZpbmVkLFxuKTogUHJvbWlzZTxXb3Jrc3BhY2VGaWxlc3lzdGVtIHwgdW5kZWZpbmVkPiB7XG4gIGlmIChmb2xkZXIuZmlsZXN5c3RlbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHJlc29sdmVTa2lsbEZvbGRlclZhbHVlKGZvbGRlci5maWxlc3lzdGVtLCBjb250ZXh0KTtcbiAgfVxuICAvLyBBIHBhdGggbW91bnQgbmVlZHMgdGhlIHJlcXVlc3QncyBPQk8gY2xpZW50IHRvIHJlYWNoIHRoZSB3b3Jrc3BhY2UuXG4gIGlmIChmb2xkZXIucGF0aCA9PT0gdW5kZWZpbmVkIHx8ICFjbGllbnQpIHtcbiAgICBsb2dnZXIuZGVidWcoXCJza2lsbC1mb2xkZXI6c2tpcHBlZFwiLCB7XG4gICAgICBuYW1lLFxuICAgICAgcmVhc29uOiBmb2xkZXIucGF0aCA9PT0gdW5kZWZpbmVkID8gXCJuby1sb2NhdGlvblwiIDogXCJtaXNzaW5nLW9iby1jbGllbnRcIixcbiAgICB9KTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IHJvb3QgPSBzdHJpbmdVdGlscy50cmltVG9OdWxsKGF3YWl0IHJlc29sdmVTa2lsbEZvbGRlclZhbHVlKGZvbGRlci5wYXRoLCBjb250ZXh0KSk7XG4gIGlmICghcm9vdCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgcmV0dXJuIGRhdGFicmlja3NGaWxlc3lzdGVtKGNsaWVudCwgcm9vdCwgZm9sZGVyLndyaXRhYmxlICE9PSB0cnVlKTtcbn1cblxuLyoqIFJlYWQgYSB7QGxpbmsgU2tpbGxGb2xkZXJWYWx1ZX0sIGNhbGxpbmcgaXQgd2hlbiBpdCBpcyBhIHBlci1yZXF1ZXN0IHJlc29sdmVyLiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVNraWxsRm9sZGVyVmFsdWU8VD4oXG4gIHZhbHVlOiBTa2lsbEZvbGRlclZhbHVlPFQ+LFxuICBjb250ZXh0OiBXb3Jrc3BhY2VNb3VudENvbnRleHQsXG4pOiBUIHwgdW5kZWZpbmVkIHwgUHJvbWlzZTxUIHwgdW5kZWZpbmVkPiB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIlxuICAgID8gKHZhbHVlIGFzIChjb250ZXh0OiBXb3Jrc3BhY2VNb3VudENvbnRleHQpID0+IFQgfCB1bmRlZmluZWQgfCBQcm9taXNlPFQgfCB1bmRlZmluZWQ+KShjb250ZXh0KVxuICAgIDogdmFsdWU7XG59XG5cbi8qKlxuICogRmlsbCBpbiBgaWRgIGFuZCBgbmFtZWAgd2hlbiBlaXRoZXIgaXMgb21pdHRlZCBvbiB7QGxpbmsgQ3JlYXRlV29ya3NwYWNlT3B0aW9uc30uXG4gKiBTbHVnaWZpZXMgYG5hbWVgIGludG8gYGlkYDsgdG9rZW5pemVzIGBpZGAgaW50byBhIGRpc3BsYXkgYG5hbWVgLlxuICovXG5mdW5jdGlvbiByZXNvbHZlV29ya3NwYWNlSWRlbnRpdHkob3B0aW9uczogQ3JlYXRlV29ya3NwYWNlT3B0aW9ucyk6IHtcbiAgaWQ6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xufSB7XG4gIGxldCBpZCA9IG9wdGlvbnMuaWQ7XG4gIGxldCBuYW1lID0gb3B0aW9ucy5uYW1lO1xuICBpZiAoIWlkKSB7XG4gICAgaWQgPSBuYW1lID8gc3RyaW5nVXRpbHMudG9TbHVnKG5hbWUpIDogXCJ3b3Jrc3BhY2VcIjtcbiAgfVxuICBpZiAoIW5hbWUpIHtcbiAgICBuYW1lID0gQXJyYXkuZnJvbShzdHJpbmdVdGlscy50b2tlbml6ZShpZCkpLmpvaW4oXCIgXCIpO1xuICB9XG4gIHJldHVybiB7IGlkLCBuYW1lIH07XG59XG5cbi8qKiBDb2xsZWN0IHRoZSBza2lsbC1mb2xkZXIgcmVzb2x2ZXIgYW5kIGFueSBjYWxsZXItc3VwcGxpZWQgb25lcy4gKi9cbmZ1bmN0aW9uIGJ1aWxkTW91bnRSZXNvbHZlcnMoXG4gIHNraWxsRm9sZGVyczogUmVjb3JkPHN0cmluZywgU2tpbGxGb2xkZXJPcHRpb25zPixcbiAgbW91bnRzOiBXb3Jrc3BhY2VNb3VudFJlc29sdmVyW10gfCB1bmRlZmluZWQsXG4pOiBXb3Jrc3BhY2VNb3VudFJlc29sdmVyW10ge1xuICBjb25zdCByZXNvbHZlcnM6IFdvcmtzcGFjZU1vdW50UmVzb2x2ZXJbXSA9IFtdO1xuICBjb25zdCBmb2xkZXJDb3VudCA9IE9iamVjdC5rZXlzKHNraWxsRm9sZGVycykubGVuZ3RoO1xuICBpZiAoZm9sZGVyQ291bnQgPiAwKSB7XG4gICAgcmVzb2x2ZXJzLnB1c2goKGNvbnRleHQpID0+IHJlc29sdmVTa2lsbEZvbGRlck1vdW50cyhza2lsbEZvbGRlcnMsIGNvbnRleHQpKTtcbiAgfVxuICBpZiAobW91bnRzPy5sZW5ndGgpIHtcbiAgICByZXNvbHZlcnMucHVzaCguLi5tb3VudHMpO1xuICB9XG4gIGxvZ2dlci5kZWJ1ZyhcIm1vdW50czpyZXNvbHZlcnNcIiwge1xuICAgIHNraWxsRm9sZGVyQ291bnQ6IGZvbGRlckNvdW50LFxuICAgIGN1c3RvbVJlc29sdmVyQ291bnQ6IG1vdW50cz8ubGVuZ3RoID8/IDAsXG4gICAgdG90YWxSZXNvbHZlckNvdW50OiByZXNvbHZlcnMubGVuZ3RoLFxuICB9KTtcbiAgcmV0dXJuIHJlc29sdmVycztcbn1cblxuLyoqXG4gKiBHYXRlIHNraWxsLWZvbGRlciBtb3VudHMgb24gdGhlIHJlcXVlc3QncyB0b2tlbi5cbiAqXG4gKiBBbHdheXMgYWxsb3dzIG1vdW50cyBpbiBkZXZlbG9wbWVudDsgaW4gb3RoZXIgZW52aXJvbm1lbnRzIHJlcXVpcmVzXG4gKiB7QGxpbmsgaGFzV29ya3NwYWNlRmlsZVNjb3BlfS5cbiAqL1xuZnVuY3Rpb24gc2hvdWxkTW91bnRTa2lsbEZvbGRlcnMocmVxdWVzdENvbnRleHQ6IFJlcXVlc3RDb250ZXh0KTogYm9vbGVhbiB7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJkZXZlbG9wbWVudFwiKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuIGhhc1dvcmtzcGFjZUZpbGVTY29wZShyZXF1ZXN0Q29udGV4dCk7XG59XG5cbi8qKiBSZWFkIHRoZSB0cmltbWVkIE9CTyB1c2VyIGVtYWlsIHN0YW1wZWQgb24ge0BsaW5rIE1BU1RSQV9VU0VSX0VNQUlMX0tFWX0uICovXG5mdW5jdGlvbiByZXNvbHZlU2NvcGVkRW1haWwocmVxdWVzdENvbnRleHQ6IFJlcXVlc3RDb250ZXh0IHwgdW5kZWZpbmVkKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHN0cmluZ1V0aWxzLnRyaW1Ub051bGwocmVxdWVzdENvbnRleHQ/LmdldChNQVNUUkFfVVNFUl9FTUFJTF9LRVkpKSA/PyB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogV3JhcCBhIHtAbGluayBEYXRhYnJpY2tzRmlsZVN5c3RlbX0gYXMgYSBNYXN0cmEgZmlsZXN5c3RlbS4gV2hlbiB0aGUgcm9vdCBpc1xuICogbWlzc2luZyAoYW5kIHtAbGluayByZWFkT25seX0gc28gd2Ugd2lsbCBub3QgY3JlYXRlIGl0KSwgZmFsbCBiYWNrIHRvXG4gKiB7QGxpbmsgc2NyYXRjaEZpbGVzeXN0ZW19IHNvIHNraWxsIHNjYW5zIHN0aWxsIGhhdmUgYSB3cml0YWJsZSBsb2NhbCBtb3VudC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZGF0YWJyaWNrc0ZpbGVzeXN0ZW0oXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50LFxuICByb290OiBzdHJpbmcsXG4gIHJlYWRPbmx5OiBib29sZWFuID0gdHJ1ZSxcbik6IFByb21pc2U8V29ya3NwYWNlRmlsZXN5c3RlbT4ge1xuICBjb25zdCBmcyA9IG5ldyBEYXRhYnJpY2tzRmlsZVN5c3RlbSh7XG4gICAgY2xpZW50OiB3b3Jrc3BhY2VDbGllbnQudG9MZWdhY3lXb3Jrc3BhY2VDbGllbnQoY2xpZW50KSxcbiAgICByb290LFxuICAgIHJlYWRPbmx5LFxuICAgIGNyZWF0ZVJvb3Q6ICFyZWFkT25seSxcbiAgfSk7XG4gIHRyeSB7XG4gICAgYXdhaXQgZnMuaW5pdCgpO1xuICAgIGlmIChhd2FpdCBmcy5leGlzdHMoXCIuXCIpKSB7XG4gICAgICByZXR1cm4gZmlsZXN5c3RlbXMoZnMsIHsgcmVhZE9ubHkgfSk7XG4gICAgfVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2dnZXIuZGVidWcoXCJkYXRhYnJpY2tzLW1vdW50OnNjcmF0Y2gtZmFsbGJhY2tcIiwge1xuICAgICAgcm9vdCxcbiAgICAgIHJlYWRPbmx5LFxuICAgICAgZXJyb3I6IGVycm9yVXRpbHMuZXJyb3JNZXNzYWdlKGVyciksXG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIHNjcmF0Y2hGaWxlc3lzdGVtKCk7XG59XG5cbi8qKlxuICogUnVuIGV2ZXJ5IG1vdW50IHJlc29sdmVyIGZvciBvbmUgcmVxdWVzdCBhbmQgbWVyZ2UgbW91bnRzIHBsdXMgc2tpbGwgcGF0aHMuXG4gKiBMYXRlciByZXNvbHZlcnMgb3ZlcndyaXRlIG1vdW50IGtleXMgZnJvbSBlYXJsaWVyIG9uZXMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVXb3Jrc3BhY2VDb250cmlidXRpb24oXG4gIHJlc29sdmVyczogV29ya3NwYWNlTW91bnRSZXNvbHZlcltdLFxuICBjb250ZXh0OiBXb3Jrc3BhY2VNb3VudENvbnRleHQsXG4pOiBQcm9taXNlPFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uPiB7XG4gIGNvbnN0IG1vdW50czogUmVjb3JkPHN0cmluZywgV29ya3NwYWNlRmlsZXN5c3RlbT4gPSB7fTtcbiAgY29uc3Qgc2tpbGxQYXRoczogc3RyaW5nW10gPSBbXTtcblxuICBmb3IgKGNvbnN0IFtpbmRleCwgcmVzb2x2ZXJdIG9mIHJlc29sdmVycy5lbnRyaWVzKCkpIHtcbiAgICBjb25zdCBjb250cmlidXRpb24gPSBhd2FpdCByZXNvbHZlcihjb250ZXh0KTtcbiAgICBsb2dnZXIuZGVidWcoXCJtb3VudHM6cmVzb2x2ZXJcIiwge1xuICAgICAgaW5kZXgsXG4gICAgICBtb3VudEtleXM6IE9iamVjdC5rZXlzKGNvbnRyaWJ1dGlvbi5tb3VudHMpLFxuICAgICAgc2tpbGxQYXRoczogY29udHJpYnV0aW9uLnNraWxsUGF0aHMgPz8gW10sXG4gICAgfSk7XG4gICAgT2JqZWN0LmFzc2lnbihtb3VudHMsIGNvbnRyaWJ1dGlvbi5tb3VudHMpO1xuICAgIGlmIChjb250cmlidXRpb24uc2tpbGxQYXRocz8ubGVuZ3RoKSB7XG4gICAgICBza2lsbFBhdGhzLnB1c2goLi4uY29udHJpYnV0aW9uLnNraWxsUGF0aHMpO1xuICAgIH1cbiAgfVxuXG4gIGxvZ2dlci5kZWJ1ZyhcIm1vdW50czptZXJnZWRcIiwge1xuICAgIG1vdW50S2V5czogT2JqZWN0LmtleXMobW91bnRzKSxcbiAgICBza2lsbFBhdGhzLFxuICB9KTtcblxuICByZXR1cm4geyBtb3VudHMsIHNraWxsUGF0aHMgfTtcbn1cblxuLyoqXG4gKiBEeW5hbWljIGZpbGVzeXN0ZW0gcmVzb2x2ZXIgcGFzc2VkIHRvIE1hc3RyYSB7QGxpbmsgV29ya3NwYWNlfS5cbiAqXG4gKiBSZXR1cm5zIGEge0BsaW5rIENvbXBvc2l0ZUZpbGVzeXN0ZW19IHdoZW4gYW55IG1vdW50IHJlc29sdmVkOyBvdGhlcndpc2UgYVxuICogZnJlc2gge0BsaW5rIHNjcmF0Y2hGaWxlc3lzdGVtfSBzbyBNYXN0cmEgYWx3YXlzIGhhcyBhIHdyaXRhYmxlIGxvY2FsIHJvb3QuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVXb3Jrc3BhY2VGaWxlc3lzdGVtKFxuICByZXNvbHZlcnM6IFdvcmtzcGFjZU1vdW50UmVzb2x2ZXJbXSxcbiAgY29udGV4dDogV29ya3NwYWNlTW91bnRDb250ZXh0LFxuKTogUHJvbWlzZTxXb3Jrc3BhY2VGaWxlc3lzdGVtPiB7XG4gIGNvbnN0IHsgbW91bnRzIH0gPSBhd2FpdCByZXNvbHZlV29ya3NwYWNlQ29udHJpYnV0aW9uKHJlc29sdmVycywgY29udGV4dCk7XG4gIGNvbnN0IG1vdW50S2V5cyA9IE9iamVjdC5rZXlzKG1vdW50cyk7XG4gIGlmIChtb3VudEtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwiZmlsZXN5c3RlbTpzY3JhdGNoXCIsIHtcbiAgICAgIGhhc1JlcXVlc3RDb250ZXh0OiBCb29sZWFuKGNvbnRleHQucmVxdWVzdENvbnRleHQpLFxuICAgIH0pO1xuICAgIHJldHVybiBzY3JhdGNoRmlsZXN5c3RlbSgpO1xuICB9XG4gIGxvZ2dlci5kZWJ1ZyhcImZpbGVzeXN0ZW06Y29tcG9zaXRlXCIsIHsgbW91bnRLZXlzIH0pO1xuICByZXR1cm4gbmV3IENvbXBvc2l0ZUZpbGVzeXN0ZW0oeyBtb3VudHMgfSk7XG59XG5cbi8qKlxuICogQnVpbGQgdGhlIGR5bmFtaWMge0BsaW5rIFNraWxsc1Jlc29sdmVyfSB0aGF0IGNvbGxlY3RzIGBza2lsbFBhdGhzYCBmcm9tXG4gKiBldmVyeSBtb3VudCByZXNvbHZlciBvbiBlYWNoIHJlcXVlc3QuXG4gKi9cbmZ1bmN0aW9uIGJ1aWxkV29ya3NwYWNlU2tpbGxzUmVzb2x2ZXIoXG4gIHJlc29sdmVyczogV29ya3NwYWNlTW91bnRSZXNvbHZlcltdLFxuICBleHRyYVNraWxsUGF0aHM6IHN0cmluZ1tdID0gW10sXG4pOiBTa2lsbHNSZXNvbHZlciB7XG4gIHJldHVybiBhc3luYyAoY29udGV4dDogU2tpbGxzQ29udGV4dCkgPT4ge1xuICAgIGNvbnN0IHsgc2tpbGxQYXRocyB9ID0gYXdhaXQgcmVzb2x2ZVdvcmtzcGFjZUNvbnRyaWJ1dGlvbihyZXNvbHZlcnMsIGNvbnRleHQpO1xuICAgIGNvbnN0IG1lcmdlZCA9IFsuLi4oc2tpbGxQYXRocyA/PyBbXSksIC4uLmV4dHJhU2tpbGxQYXRoc107XG4gICAgbG9nZ2VyLmRlYnVnKFwic2tpbGxzOnJlc29sdmVkXCIsIHsgc2tpbGxQYXRocywgZXh0cmFTa2lsbFBhdGhzIH0pO1xuICAgIHJldHVybiBtZXJnZWQ7XG4gIH07XG59XG4iXX0=
463
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya3NwYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93b3Jrc3BhY2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRS9FLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM5RSxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRXJGLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsU0FBUyxHQU1WLE1BQU0sd0JBQXdCLENBQUM7QUFFaEMsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixxQkFBcUIsRUFDckIsZUFBZSxFQUNmLGNBQWMsR0FFZixNQUFNLGFBQWEsQ0FBQztBQUNyQixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLGlCQUFpQixFQUEwQyxNQUFNLGNBQWMsQ0FBQztBQUN6RixPQUFPLEVBQUUseUJBQXlCLEVBQUUsb0NBQW9DLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNuRyxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUV6Riw2RUFBNkU7QUFFN0UsK0RBQStEO0FBQy9ELE1BQU0scUJBQXFCLEdBQUcsQ0FBQyxXQUFXLEVBQUUscUJBQXFCLEVBQUUsVUFBVSxDQUFVLENBQUM7QUFFeEYsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxD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RCxJQUFJLE1BQU0sS0FBSyxTQUFTO1lBQUUsTUFBTTtRQUNoQywwQkFBMEIsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUNELE9BQU8sVUFBVSxDQUFDO0FBQ3BCLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFTLDRCQUE0QixDQUNuQyxTQUFtQyxFQUNuQyxrQkFBNEIsRUFBRTtJQUU5QixPQUFPLEtBQUssRUFBRSxPQUFzQixFQUFFLEVBQUU7UUFDdEMsTUFBTSxFQUFFLFVBQVUsRUFBRSxHQUFHLE1BQU0sNEJBQTRCLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzlFLE1BQU0sTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSxFQUFFLENBQUMsRUFBRSxHQUFHLGVBQWUsQ0FBQyxDQUFDO1FBQzNELE1BQU0sQ0FBQyxLQUFLLENBQUMsaUJBQWlCLEVBQUUsRUFBRSxVQUFVLEVBQUUsZUFBZSxFQUFFLENBQUMsQ0FBQztRQUNqRSxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNYXN0cmEgd29ya3NwYWNlIGZhY3RvcnkgZm9yIERhdGFicmlja3MgQXBwcy5cbiAqXG4gKiBCdWlsZHMgYSBwZXItcmVxdWVzdCB7QGxpbmsgV29ya3NwYWNlfSB3aXRoIERhdGFicmlja3MgU2FuZGJveCBjb21tYW5kXG4gKiBleGVjdXRpb24gcGx1cyBhIHtAbGluayBDb21wb3NpdGVGaWxlc3lzdGVtfSBvdmVyIHRoZSBOQU1FRCBza2lsbCBmb2xkZXJzXG4gKiByZXNvbHZlZCBmb3IgdGhhdCByZXF1ZXN0LiBBIHNraWxsIGZvbGRlciBtYXBzIGEgbmFtZSB0byBhIGxvY2F0aW9uIHBsdXMgaXRzXG4gKiByZWFkYWJsZSAvIHdyaXRhYmxlIHBvbGljeTogYSBEYXRhYnJpY2tzIHBhdGggbW91bnRlZCB0aHJvdWdoIHRoZSBPQk8gY2xpZW50XG4gKiBvbiB7QGxpbmsgTUFTVFJBX1VTRVJfS0VZfSwgb3IgYW55IHtAbGluayBXb3Jrc3BhY2VGaWxlc3lzdGVtfSBhIGNvbnN1bWluZ1xuICogbGlicmFyeSBhbHJlYWR5IG93bnMuIHtAbGluayBERUZBVUxUX1NLSUxMX0ZPTERFUlN9IHN1cHBsaWVzIHRoZSBBc3Npc3RhbnRcbiAqIHRyZWVzLCBhbmQgYHNraWxsRm9sZGVyc2AgbWVyZ2VzIG92ZXIgaXQgLSBzYW1lIG5hbWUgb3ZlcnJpZGVzLCBgZmFsc2VgXG4gKiBkaXNhYmxlcywgYSBuZXcgbmFtZSBhZGRzLiBPcHRpb25hbCBtb3VudCByZXNvbHZlcnMgY29udHJpYnV0ZSBmdXJ0aGVyXG4gKiBmaWxlc3lzdGVtcyBhbmQgc2tpbGwgc2NhbiByb290cyBvbiB0b3AuXG4gKlxuICogRGF0YWJyaWNrcyBtb3VudHMgdXNlIGBAZGJ4LXRvb2xzL2RhdGFicmlja3NgIHtAbGluayBEYXRhYnJpY2tzRmlsZVN5c3RlbX1cbiAqIHdyYXBwZWQgYnkge0BsaW5rIGZpbGVzeXN0ZW1zfTsgbWlzc2luZyByb290cyBmYWxsIGJhY2sgdG9cbiAqIHtAbGluayBzY3JhdGNoRmlsZXN5c3RlbX0uXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGNyZWF0ZUhhc2ggfSBmcm9tIFwibm9kZTpjcnlwdG9cIjtcbmltcG9ydCB7IENvbmZpZ3VyYXRpb25FcnJvciwgY3JlYXRlV29ya3NwYWNlQ2xpZW50IH0gZnJvbSBcIkBkYXRhYnJpY2tzL2FwcGtpdFwiO1xuaW1wb3J0IHR5cGUgeyBXb3Jrc3BhY2VDbGllbnQgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBEYXRhYnJpY2tzRmlsZVN5c3RlbSwgd29ya3NwYWNlQ2xpZW50IH0gZnJvbSBcIkBkYngtdG9vbHMvZGF0YWJyaWNrc1wiO1xuaW1wb3J0IHsgZXJyb3JVdGlscywgbG9nLCBvYmplY3QsIHN0cmluZ1V0aWxzLCB0b2tlbiB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgdHlwZSB7IFJlcXVlc3RDb250ZXh0IH0gZnJvbSBcIkBtYXN0cmEvY29yZS9yZXF1ZXN0LWNvbnRleHRcIjtcbmltcG9ydCB7XG4gIENvbXBvc2l0ZUZpbGVzeXN0ZW0sXG4gIFdvcmtzcGFjZSxcbiAgdHlwZSBTa2lsbHNDb250ZXh0LFxuICB0eXBlIFNraWxsc1Jlc29sdmVyLFxuICB0eXBlIFdvcmtzcGFjZUZpbGVzeXN0ZW0sXG4gIHR5cGUgV29ya3NwYWNlU2FuZGJveCxcbiAgdHlwZSBXb3Jrc3BhY2VTYW5kYm94UmVzb2x2ZXIsXG59IGZyb20gXCJAbWFzdHJhL2NvcmUvd29ya3NwYWNlXCI7XG5cbmltcG9ydCB7XG4gIE1BU1RSQV9TQ09QRVNfS0VZLFxuICBNQVNUUkFfVVNFUl9FTUFJTF9LRVksXG4gIE1BU1RSQV9VU0VSX0tFWSxcbiAgcmVzb2x2ZVVzZXJLZXksXG4gIHR5cGUgVXNlcixcbn0gZnJvbSBcIi4vY29uZmlnLnRzXCI7XG5pbXBvcnQgeyBzY3JhdGNoRmlsZXN5c3RlbSB9IGZyb20gXCIuL2ZpbGVzeXN0ZW1zLnRzXCI7XG5pbXBvcnQgeyBNb250eVNhbmRib3ggfSBmcm9tIFwiLi9tb250eS1zYW5kYm94LnRzXCI7XG5pbXBvcnQgeyBEYXRhYnJpY2tzU2FuZGJveCwgdHlwZSBEYXRhYnJpY2tzV29ya3NwYWNlU2FuZGJveE9wdGlvbnMgfSBmcm9tIFwiLi9zYW5kYm94LnRzXCI7XG5pbXBvcnQgeyBjYWNoZWRXb3Jrc3BhY2VTa2lsbE1vdW50LCBERUZBVUxUX1dPUktTUEFDRV9TS0lMTF9DQUNIRV9UVExfTVMgfSBmcm9tIFwiLi9za2lsbC1jYWNoZS50c1wiO1xuaW1wb3J0IHsgQVNTSVNUQU5UX1NIQVJFRF9TS0lMTFNfUEFUSCwgdXNlckFzc2lzdGFudFNraWxsc1BhdGggfSBmcm9tIFwiLi9za2lsbC1wYXRocy50c1wiO1xuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gY29uc3RhbnRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKiogT0F1dGggc2NvcGVzIHRoYXQgZ2F0ZSBEYXRhYnJpY2tzIHdvcmtzcGFjZSBmaWxlIG1vdW50cy4gKi9cbmNvbnN0IFdPUktTUEFDRV9GSUxFX1NDT1BFUyA9IFtcIndvcmtzcGFjZVwiLCBcIndvcmtzcGFjZS53b3Jrc3BhY2VcIiwgXCJhbGwtYXBpc1wiXSBhcyBjb25zdDtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcIm1hc3RyYS93b3Jrc3BhY2VzXCIpO1xuY29uc3QgTUFYX1NDT1BFRF9XT1JLU1BBQ0VfRklMRVNZU1RFTVMgPSAxNjtcbmNvbnN0IHNjb3BlZFdvcmtzcGFjZUZpbGVzeXN0ZW1zID0gbmV3IE1hcDxzdHJpbmcsIFdvcmtzcGFjZUZpbGVzeXN0ZW0+KCk7XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHR5cGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8qKiBQZXItcmVxdWVzdCBjb250ZXh0IGZvciBtb3VudCBhbmQgc2tpbGwtZm9sZGVyIHJlc29sdmVycy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV29ya3NwYWNlTW91bnRDb250ZXh0IHtcbiAgcmVxdWVzdENvbnRleHQ/OiBSZXF1ZXN0Q29udGV4dDtcbn1cblxuLyoqXG4gKiBBIHNraWxsLWZvbGRlciBmaWVsZCBnaXZlbiBlaXRoZXIgZGlyZWN0bHkgb3IgYXMgYSBwZXItcmVxdWVzdCByZXNvbHZlci5cbiAqIEEgcmVzb2x2ZXIgcmV0dXJuaW5nIGB1bmRlZmluZWRgIHNraXBzIHRoZSBmb2xkZXIgZm9yIHRoYXQgcmVxdWVzdC5cbiAqL1xuZXhwb3J0IHR5cGUgU2tpbGxGb2xkZXJWYWx1ZTxUPiA9XG4gIFQgfCAoKGNvbnRleHQ6IFdvcmtzcGFjZU1vdW50Q29udGV4dCkgPT4gVCB8IHVuZGVmaW5lZCB8IFByb21pc2U8VCB8IHVuZGVmaW5lZD4pO1xuXG4vKipcbiAqIE9uZSBuYW1lZCBza2lsbC1mb2xkZXIgbG9jYXRpb24gYW5kIGl0cyByZWFkIC8gd3JpdGUgcG9saWN5LlxuICpcbiAqIEdpdmUge0BsaW5rIHBhdGh9IGZvciBhIERhdGFicmlja3Mgd29ya3NwYWNlIHRyZWUgKG1vdW50ZWQgdGhyb3VnaCB0aGVcbiAqIHJlcXVlc3QncyBPQk8gY2xpZW50KSwgb3Ige0BsaW5rIGZpbGVzeXN0ZW19IGZvciBhIG1vdW50IHRoZSBjb25zdW1lciBidWlsZHNcbiAqIGl0c2VsZi4ge0BsaW5rIGZpbGVzeXN0ZW19IHdpbnMgd2hlbiBib3RoIGFyZSBzZXQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2tpbGxGb2xkZXJPcHRpb25zIHtcbiAgLyoqIEFic29sdXRlIERhdGFicmlja3Mgd29ya3NwYWNlIHBhdGggZm9yIHRoaXMgZm9sZGVyLiAqL1xuICBwYXRoPzogU2tpbGxGb2xkZXJWYWx1ZTxzdHJpbmc+O1xuICAvKiogUmVhZHktbWFkZSBtb3VudCwgZm9yIGxvY2F0aW9ucyB0aGUgT0JPIGNsaWVudCBjYW5ub3QgcmVhY2guICovXG4gIGZpbGVzeXN0ZW0/OiBTa2lsbEZvbGRlclZhbHVlPFdvcmtzcGFjZUZpbGVzeXN0ZW0+O1xuICAvKipcbiAgICogU2NhbiB0aGlzIG1vdW50IGZvciBgU0tJTEwubWRgIGZpbGVzLiBEZWZhdWx0cyB0byBgdHJ1ZWA7IGBmYWxzZWAgbW91bnRzXG4gICAqIHRoZSBsb2NhdGlvbiBmb3IgZmlsZSB0b29scyB3aXRob3V0IGFkZGluZyBpdCB0byBza2lsbCBkaXNjb3ZlcnkuXG4gICAqL1xuICByZWFkYWJsZT86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBBbGxvdyB3cml0ZXMgdG8gYSB7QGxpbmsgcGF0aH0gbW91bnQgKGFuZCBjcmVhdGUgdGhlIHJvb3Qgd2hlbiBtaXNzaW5nKS5cbiAgICogRGVmYXVsdHMgdG8gYGZhbHNlYC4gQSBzdXBwbGllZCB7QGxpbmsgZmlsZXN5c3RlbX0gY2FycmllcyBpdHMgb3duXG4gICAqIHJlYWQtb25seSBmbGFnIGluc3RlYWQuXG4gICAqL1xuICB3cml0YWJsZT86IGJvb2xlYW47XG4gIC8qKiBNb3VudCBwb2ludCBpbiB0aGUgY29tcG9zaXRlIG5hbWVzcGFjZS4gRGVmYXVsdHMgdG8gYC88bmFtZT5gLiAqL1xuICBtb3VudD86IHN0cmluZztcbn1cblxuLyoqIE1vdW50IG1hcCBwbHVzIG9wdGlvbmFsIE1hc3RyYSBza2lsbCBzY2FuIHJvb3RzIGZvciBvbmUgcmVzb2x2ZXIuICovXG5leHBvcnQgaW50ZXJmYWNlIFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uIHtcbiAgbW91bnRzOiBSZWNvcmQ8c3RyaW5nLCBXb3Jrc3BhY2VGaWxlc3lzdGVtPjtcbiAgLyoqIFBhdGhzIHdpdGhpbiB0aGUgY29tcG9zaXRlIG5hbWVzcGFjZSB3aGVyZSBgU0tJTEwubWRgIGZpbGVzIGFyZSBzY2FubmVkLiAqL1xuICBza2lsbFBhdGhzPzogc3RyaW5nW107XG4gIC8qKlxuICAgKiBTdGFibGUgaWRlbnRpdHkgZm9yIHRoaXMgY29udHJpYnV0aW9uLiBXaGVuIGV2ZXJ5IG5vbi1lbXB0eSBjb250cmlidXRpb25cbiAgICogc3VwcGxpZXMgb25lLCBNYXN0cmEgcmV1c2VzIHRoZSByZXNvbHZlZCBzb3VyY2UgYWNyb3NzIHJlcXVlc3RzLlxuICAgKi9cbiAgY2FjaGVLZXk/OiBzdHJpbmc7XG59XG5cbi8qKiBDb250cmlidXRlcyBmaWxlc3lzdGVtIG1vdW50cyAoYW5kIG9wdGlvbmFsIHNraWxsIHBhdGhzKSBmb3Igb25lIHJlcXVlc3QuICovXG5leHBvcnQgdHlwZSBXb3Jrc3BhY2VNb3VudFJlc29sdmVyID0gKFxuICBjb250ZXh0OiBXb3Jrc3BhY2VNb3VudENvbnRleHQsXG4pID0+IFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uIHwgUHJvbWlzZTxXb3Jrc3BhY2VNb3VudENvbnRyaWJ1dGlvbj47XG5cbi8qKiBOYW1lcyBjYXJyaWVkIGJ5IHtAbGluayBERUZBVUxUX1NLSUxMX0ZPTERFUlN9LiAqL1xuZXhwb3J0IHR5cGUgRGVmYXVsdFNraWxsRm9sZGVyTmFtZSA9IFwid29ya3NwYWNlLXRlYW1cIiB8IFwid29ya3NwYWNlLXRlYW0tYXBwXCI7XG5cbi8qKlxuICogU2FuZGJveCBzZWxlY3Rpb24gZm9yIHtAbGluayBjcmVhdGVXb3Jrc3BhY2V9LiBEYXRhYnJpY2tzIGlzIHRoZSBkZWZhdWx0O1xuICogYGZhbHNlYCBkaXNhYmxlcyBjb21tYW5kIGV4ZWN1dGlvbiwgYW5kIGEgTWFzdHJhIHByb3ZpZGVyIG9yIHJlc29sdmVyIGlzIGFuXG4gKiBleHBsaWNpdCByZXBsYWNlbWVudC5cbiAqL1xuZXhwb3J0IHR5cGUgV29ya3NwYWNlU2FuZGJveFNlbGVjdGlvbiA9XG4gIHwgZmFsc2VcbiAgfCBcImRhdGFicmlja3NcIlxuICB8IFwibW9udHlcIlxuICB8IERhdGFicmlja3NXb3Jrc3BhY2VTYW5kYm94T3B0aW9uc1xuICB8IFdvcmtzcGFjZVNhbmRib3hcbiAgfCBXb3Jrc3BhY2VTYW5kYm94UmVzb2x2ZXI7XG5cbi8qKiBPcHRpb25zIGZvciB7QGxpbmsgY3JlYXRlV29ya3NwYWNlfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlV29ya3NwYWNlT3B0aW9ucyB7XG4gIC8qKiBXb3Jrc3BhY2UgaWQ7IGRlcml2ZWQgZnJvbSBgbmFtZWAgb3IgYFwid29ya3NwYWNlXCJgIHdoZW4gb21pdHRlZC4gKi9cbiAgaWQ/OiBzdHJpbmc7XG4gIC8qKiBEaXNwbGF5IG5hbWU7IGRlcml2ZWQgZnJvbSBgaWRgIHdoZW4gb21pdHRlZC4gKi9cbiAgbmFtZT86IHN0cmluZztcbiAgLyoqXG4gICAqIFN0YXJ0IGZyb20ge0BsaW5rIERFRkFVTFRfU0tJTExfRk9MREVSU30uIERlZmF1bHRzIHRvIGB0cnVlYDsgYGZhbHNlYFxuICAgKiBzdGFydHMgZnJvbSBhbiBlbXB0eSBtYXAsIGxlYXZpbmcgb25seSB0aGUge0BsaW5rIHNraWxsRm9sZGVyc30gZ2l2ZW4gaGVyZS5cbiAgICovXG4gIGFzc2lzdGFudFNraWxscz86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBOYW1lZCBza2lsbCBmb2xkZXJzIG1lcmdlZCBvdmVyIHtAbGluayBERUZBVUxUX1NLSUxMX0ZPTERFUlN9OiBhIG1hdGNoaW5nXG4gICAqIG5hbWUgb3ZlcnJpZGVzIHRoYXQgZGVmYXVsdCwgYGZhbHNlYCBkaXNhYmxlcyBpdCwgYW5kIGFueSBvdGhlciBuYW1lIGFkZHNcbiAgICogYSBmb2xkZXIuXG4gICAqL1xuICBza2lsbEZvbGRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBTa2lsbEZvbGRlck9wdGlvbnMgfCBmYWxzZT47XG4gIC8qKiBFeHRyYSBwZXItcmVxdWVzdCBtb3VudCByZXNvbHZlcnMgKHJ1biBhZnRlciB0aGUgc2tpbGwtZm9sZGVyIG1vdW50cykuICovXG4gIG1vdW50cz86IFdvcmtzcGFjZU1vdW50UmVzb2x2ZXJbXTtcbiAgLyoqIFJlcGxhY2UgdGhlIGF1dG8tYnVpbHQgZHluYW1pYyBza2lsbHMgcmVzb2x2ZXIuICovXG4gIHNraWxscz86IFNraWxsc1Jlc29sdmVyO1xuICAvKiogRm9yd2FyZGVkIHRvIE1hc3RyYSB3aGVuIHNraWxsIGRpc2NvdmVyeSBpcyBlbmFibGVkLiAqL1xuICBjaGVja1NraWxsRmlsZU10aW1lPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIEFwcEtpdCBjYWNoZSBUVEwgZm9yIERhdGFicmlja3Mgc2tpbGwgbWV0YWRhdGEgYW5kIGNvbnRlbnQuXG4gICAqIERlZmF1bHRzIHRvIGZpdmUgbWludXRlcy5cbiAgICovXG4gIHdvcmtzcGFjZVNraWxsUmVmcmVzaFR0bE1zPzogbnVtYmVyO1xuICAvKiogRW5hYmxlIEJNMjUga2V5d29yZCBzZWFyY2ggb3ZlciBpbmRleGVkIHdvcmtzcGFjZSBjb250ZW50LiAqL1xuICBibTI1PzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIENvbW1hbmQgc2FuZGJveC4gRGVmYXVsdHMgdG8gRGF0YWJyaWNrcyBTYW5kYm94LiBQYXNzIGBmYWxzZWAgdG8gZGlzYWJsZVxuICAgKiBjb21tYW5kIGV4ZWN1dGlvbiwgb3IgYW4gZXhwbGljaXQgTWFzdHJhIHNhbmRib3gvcHJvdmlkZXIgcmVzb2x2ZXIgdG9cbiAgICogcmVwbGFjZSBEYXRhYnJpY2tzIGZvciB0aGlzIHdvcmtzcGFjZS5cbiAgICovXG4gIHNhbmRib3g/OiBXb3Jrc3BhY2VTYW5kYm94U2VsZWN0aW9uO1xuICAvKipcbiAgICogRXh0cmEgTE9DQUwgc2tpbGwgc2NhbiBwYXRocyBhZGRlZCB0byBldmVyeSByZXF1ZXN0J3Mgc2tpbGwgZGlzY292ZXJ5LlxuICAgKiBVc2VkIGJ5IHRoZSBwbHVnaW4gdG8gc3VyZmFjZSByZW1vdGUgc2tpbGxzIHByb3Zpc2lvbmVkIHRvIGEgbG9jYWwgdGVtcFxuICAgKiBkaXIgYXQgc3RhcnR1cCAoc2VlIGByZW1vdGUtc2tpbGxzLnRzYCkuIERhdGFicmlja3MtaG9zdGVkIHJlbW90ZSBza2lsbHNcbiAgICogbmVlZCBubyBlbnRyeSBoZXJlIC0gdGhleSBsYW5kIGluIHRoZSBBc3Npc3RhbnQgdHJlZSB0aGUgYnVpbHQtaW4gbW91bnRcbiAgICogYWxyZWFkeSBzY2Fucy5cbiAgICovXG4gIGV4dHJhU2tpbGxQYXRocz86IHN0cmluZ1tdO1xufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGRlZmF1bHRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuLyoqXG4gKiBUaGUgc2tpbGwgZm9sZGVycyBldmVyeSB3b3Jrc3BhY2Ugc3RhcnRzIHdpdGguXG4gKlxuICogLSBgd29ya3NwYWNlLXRlYW1gIC0gdGhlIHNoYXJlZCB3b3Jrc3BhY2UgQXNzaXN0YW50IHRyZWUsIHJlYWQtb25seSBiZWNhdXNlXG4gKiAgIHdyaXRpbmcgaXQgaXMgYSB3b3Jrc3BhY2UtYWRtaW4gYWN0aW9uLlxuICogLSBgd29ya3NwYWNlLXRlYW0tYXBwYCAtIHRoZSByZXF1ZXN0aW5nIHVzZXIncyBvd24gQXNzaXN0YW50IHRyZWUsIHdyaXRhYmxlXG4gKiAgIHNvIHRoZSBhcHAgY2FuIHNhdmUgc2tpbGxzIGJhY2sgdG8gaXQuIFNraXBwZWQgd2hlbiB0aGUgcmVxdWVzdCBjYXJyaWVzIG5vXG4gKiAgIHVzZXIgZW1haWwuXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX1NLSUxMX0ZPTERFUlM6IFJlYWRvbmx5PFJlY29yZDxEZWZhdWx0U2tpbGxGb2xkZXJOYW1lLCBTa2lsbEZvbGRlck9wdGlvbnM+PiA9IHtcbiAgXCJ3b3Jrc3BhY2UtdGVhbVwiOiB7XG4gICAgcGF0aDogQVNTSVNUQU5UX1NIQVJFRF9TS0lMTFNfUEFUSCxcbiAgICByZWFkYWJsZTogdHJ1ZSxcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gIH0sXG4gIFwid29ya3NwYWNlLXRlYW0tYXBwXCI6IHtcbiAgICBwYXRoOiAoeyByZXF1ZXN0Q29udGV4dCB9KSA9PiB7XG4gICAgICBjb25zdCBlbWFpbCA9IHJlc29sdmVTY29wZWRFbWFpbChyZXF1ZXN0Q29udGV4dCk7XG4gICAgICByZXR1cm4gZW1haWwgPyB1c2VyQXNzaXN0YW50U2tpbGxzUGF0aChlbWFpbCkgOiB1bmRlZmluZWQ7XG4gICAgfSxcbiAgICByZWFkYWJsZTogdHJ1ZSxcbiAgICB3cml0YWJsZTogdHJ1ZSxcbiAgfSxcbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgTWFzdHJhIHtAbGluayBXb3Jrc3BhY2V9IHdpdGggcGVyLXJlcXVlc3QgRGF0YWJyaWNrcyBtb3VudHMuXG4gKlxuICogQGV4YW1wbGUgRGVmYXVsdCBza2lsbCBmb2xkZXJzIG9ubHlcbiAqIGBgYHRzXG4gKiBjcmVhdGVXb3Jrc3BhY2UoKVxuICogYGBgXG4gKlxuICogQGV4YW1wbGUgT3ZlcnJpZGUgYSBkZWZhdWx0LCBkcm9wIGFub3RoZXIsIGFuZCBhZGQgYSBsb2NhdGlvbiBvZiB5b3VyIG93blxuICogYGBgdHNcbiAqIGNyZWF0ZVdvcmtzcGFjZSh7XG4gKiAgIHNraWxsRm9sZGVyczoge1xuICogICAgIFwid29ya3NwYWNlLXRlYW1cIjogeyBwYXRoOiBcIi9Xb3Jrc3BhY2UvU2hhcmVkL3RlYW0tc2tpbGxzXCIgfSxcbiAqICAgICBcIndvcmtzcGFjZS10ZWFtLWFwcFwiOiBmYWxzZSxcbiAqICAgICBydW5ib29rczogeyBwYXRoOiBcIi9Xb3Jrc3BhY2UvU2hhcmVkL3J1bmJvb2tzL3NraWxsc1wiLCB3cml0YWJsZTogdHJ1ZSB9LFxuICogICAgIHZvbHVtZTogeyBmaWxlc3lzdGVtOiBteVZvbHVtZUZpbGVzeXN0ZW0gfSxcbiAqICAgfSxcbiAqIH0pXG4gKiBgYGBcbiAqXG4gKiBAZXhhbXBsZSBTa2lsbCBmb2xkZXJzIHBsdXMgYSBjdXN0b20gbW91bnQgcmVzb2x2ZXJcbiAqIGBgYHRzXG4gKiBjcmVhdGVXb3Jrc3BhY2Uoe1xuICogICBtb3VudHM6IFtcbiAqICAgICBhc3luYyAoeyByZXF1ZXN0Q29udGV4dCB9KSA9PiAoe1xuICogICAgICAgbW91bnRzOiB7IFwiL2RhdGFcIjogbXlGaWxlc3lzdGVtIH0sXG4gKiAgICAgICBza2lsbFBhdGhzOiBbXSxcbiAqICAgICB9KSxcbiAqICAgXSxcbiAqIH0pXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVdvcmtzcGFjZShvcHRpb25zOiBDcmVhdGVXb3Jrc3BhY2VPcHRpb25zID0ge30pOiBXb3Jrc3BhY2Uge1xuICBjb25zdCB7IGlkLCBuYW1lIH0gPSByZXNvbHZlV29ya3NwYWNlSWRlbnRpdHkob3B0aW9ucyk7XG4gIGNvbnN0IHNraWxsRm9sZGVycyA9IHJlc29sdmVTa2lsbEZvbGRlcnMob3B0aW9ucyk7XG4gIGNvbnN0IGZvbGRlck5hbWVzID0gT2JqZWN0LmtleXMoc2tpbGxGb2xkZXJzKTtcbiAgY29uc3QgcmVzb2x2ZXJzID0gYnVpbGRNb3VudFJlc29sdmVycyhcbiAgICBza2lsbEZvbGRlcnMsXG4gICAgb3B0aW9ucy5tb3VudHMsXG4gICAgb3B0aW9ucy53b3Jrc3BhY2VTa2lsbFJlZnJlc2hUdGxNcyxcbiAgKTtcbiAgY29uc3QgZXh0cmFTa2lsbFBhdGhzID0gb3B0aW9ucy5leHRyYVNraWxsUGF0aHMgPz8gW107XG4gIGNvbnN0IHNraWxscyA9XG4gICAgb3B0aW9ucy5za2lsbHMgPz9cbiAgICAocmVzb2x2ZXJzLmxlbmd0aCA+IDAgfHwgZXh0cmFTa2lsbFBhdGhzLmxlbmd0aCA+IDBcbiAgICAgID8gYnVpbGRXb3Jrc3BhY2VTa2lsbHNSZXNvbHZlcihyZXNvbHZlcnMsIGV4dHJhU2tpbGxQYXRocylcbiAgICAgIDogdW5kZWZpbmVkKTtcbiAgY29uc3QgY2hlY2tTa2lsbEZpbGVNdGltZSA9IG9wdGlvbnMuY2hlY2tTa2lsbEZpbGVNdGltZSA/PyBmb2xkZXJOYW1lcy5sZW5ndGggPiAwO1xuICBjb25zdCBibTI1ID0gb3B0aW9ucy5ibTI1ICE9PSBmYWxzZTtcbiAgY29uc3Qgc2FuZGJveCA9IHJlc29sdmVXb3Jrc3BhY2VTYW5kYm94KG9wdGlvbnMuc2FuZGJveCwgaWQsIG5hbWUpO1xuICBsb2dnZXIuZGVidWcoXCJ3b3Jrc3BhY2U6Y3JlYXRlXCIsIHtcbiAgICBpZCxcbiAgICBuYW1lLFxuICAgIHJlc29sdmVyQ291bnQ6IHJlc29sdmVycy5sZW5ndGgsXG4gICAgc2tpbGxGb2xkZXJzOiBmb2xkZXJOYW1lcyxcbiAgICBjdXN0b21Nb3VudFJlc29sdmVyczogb3B0aW9ucy5tb3VudHM/Lmxlbmd0aCA/PyAwLFxuICAgIGN1c3RvbVNraWxsc1Jlc29sdmVyOiBCb29sZWFuKG9wdGlvbnMuc2tpbGxzKSxcbiAgICBjaGVja1NraWxsRmlsZU10aW1lLFxuICAgIHdvcmtzcGFjZVNraWxsUmVmcmVzaFR0bE1zOlxuICAgICAgb3B0aW9ucy53b3Jrc3BhY2VTa2lsbFJlZnJlc2hUdGxNcyA/PyBERUZBVUxUX1dPUktTUEFDRV9TS0lMTF9DQUNIRV9UVExfTVMsXG4gICAgYm0yNSxcbiAgICBleHRyYVNraWxsUGF0aHM6IGV4dHJhU2tpbGxQYXRocy5sZW5ndGgsXG4gICAgc2FuZGJveDogc2FuZGJveCA/IHNhbmRib3hOYW1lKG9wdGlvbnMuc2FuZGJveCkgOiBcImRpc2FibGVkXCIsXG4gIH0pO1xuXG4gIHJldHVybiBuZXcgV29ya3NwYWNlKHtcbiAgICBpZCxcbiAgICBuYW1lLFxuICAgIGZpbGVzeXN0ZW06IChjb250ZXh0KSA9PiByZXNvbHZlV29ya3NwYWNlRmlsZXN5c3RlbShyZXNvbHZlcnMsIGNvbnRleHQpLFxuICAgIC4uLihza2lsbHNcbiAgICAgID8ge1xuICAgICAgICAgIHNraWxscyxcbiAgICAgICAgICBjaGVja1NraWxsRmlsZU10aW1lLFxuICAgICAgICB9XG4gICAgICA6IHt9KSxcbiAgICAuLi4oc2FuZGJveFxuICAgICAgPyB7XG4gICAgICAgICAgc2FuZGJveCxcbiAgICAgICAgICBpbnN0cnVjdGlvbnM6IHsgZHluYW1pY1NhbmRib3g6IFwicmVzb2x2ZVwiIGFzIGNvbnN0IH0sXG4gICAgICAgIH1cbiAgICAgIDoge30pLFxuICAgIGJtMjUsXG4gIH0pO1xufVxuXG4vKipcbiAqIE1lcmdlIHRoZSBjb25maWd1cmVkIHNraWxsIGZvbGRlcnMgb3ZlciB7QGxpbmsgREVGQVVMVF9TS0lMTF9GT0xERVJTfS5cbiAqXG4gKiBgYXNzaXN0YW50U2tpbGxzOiBmYWxzZWAgZHJvcHMgdGhlIGRlZmF1bHRzLCBhbmQgYSBgZmFsc2VgIHZhbHVlIHJlbW92ZXMgb25lXG4gKiBlbnRyeSBieSBuYW1lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVNraWxsRm9sZGVycyhcbiAgb3B0aW9uczogUGljazxDcmVhdGVXb3Jrc3BhY2VPcHRpb25zLCBcImFzc2lzdGFudFNraWxsc1wiIHwgXCJza2lsbEZvbGRlcnNcIj4gPSB7fSxcbik6IFJlY29yZDxzdHJpbmcsIFNraWxsRm9sZGVyT3B0aW9ucz4ge1xuICBjb25zdCBtZXJnZWQ6IFJlY29yZDxzdHJpbmcsIFNraWxsRm9sZGVyT3B0aW9ucz4gPVxuICAgIG9wdGlvbnMuYXNzaXN0YW50U2tpbGxzID09PSBmYWxzZSA/IHt9IDogeyAuLi5ERUZBVUxUX1NLSUxMX0ZPTERFUlMgfTtcbiAgZm9yIChjb25zdCBbbmFtZSwgZm9sZGVyXSBvZiBPYmplY3QuZW50cmllcyhvcHRpb25zLnNraWxsRm9sZGVycyA/PyB7fSkpIHtcbiAgICBpZiAoZm9sZGVyID09PSBmYWxzZSkge1xuICAgICAgZGVsZXRlIG1lcmdlZFtuYW1lXTtcbiAgICB9IGVsc2Uge1xuICAgICAgbWVyZ2VkW25hbWVdID0gZm9sZGVyO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbWVyZ2VkO1xufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHByaXZhdGUgaGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbmZ1bmN0aW9uIHJlc29sdmVXb3Jrc3BhY2VTYW5kYm94KFxuICBzZWxlY3Rpb246IFdvcmtzcGFjZVNhbmRib3hTZWxlY3Rpb24gfCB1bmRlZmluZWQsXG4gIHdvcmtzcGFjZUlkOiBzdHJpbmcsXG4gIHdvcmtzcGFjZU5hbWU6IHN0cmluZyxcbik6IFdvcmtzcGFjZVNhbmRib3ggfCBXb3Jrc3BhY2VTYW5kYm94UmVzb2x2ZXIgfCB1bmRlZmluZWQge1xuICBjb25zdCBjb25maWd1cmVkID0gc2VsZWN0aW9uID8/IFwiZGF0YWJyaWNrc1wiO1xuICBpZiAoY29uZmlndXJlZCA9PT0gZmFsc2UpIHJldHVybiB1bmRlZmluZWQ7XG4gIGlmIChjb25maWd1cmVkID09PSBcIm1vbnR5XCIpIHJldHVybiBuZXcgTW9udHlTYW5kYm94KCk7XG4gIGlmICh0eXBlb2YgY29uZmlndXJlZCA9PT0gXCJmdW5jdGlvblwiIHx8IGlzU2FuZGJveChjb25maWd1cmVkKSkgcmV0dXJuIGNvbmZpZ3VyZWQ7XG5cbiAgY29uc3Qgb3B0aW9uczogRGF0YWJyaWNrc1dvcmtzcGFjZVNhbmRib3hPcHRpb25zID1cbiAgICBjb25maWd1cmVkID09PSBcImRhdGFicmlja3NcIiA/IHsgcHJvdmlkZXI6IFwiZGF0YWJyaWNrc1wiIH0gOiBjb25maWd1cmVkO1xuICByZXR1cm4gKHsgcmVxdWVzdENvbnRleHQgfSkgPT4ge1xuICAgIGNvbnN0IHVzZXIgPSByZXF1ZXN0Q29udGV4dC5nZXQoTUFTVFJBX1VTRVJfS0VZKSBhcyBVc2VyIHwgdW5kZWZpbmVkO1xuICAgIGlmICghdXNlcikge1xuICAgICAgdGhyb3cgQ29uZmlndXJhdGlvbkVycm9yLnJlc291cmNlTm90Rm91bmQoXG4gICAgICAgIFwiRGF0YWJyaWNrcyBzYW5kYm94IHVzZXIgY29udGV4dFwiLFxuICAgICAgICBcIkludm9rZSBjb21tYW5kIHRvb2xzIGZyb20gYW4gYWdlbnQgdHVybiBzZXJ2ZWQgYnkgdGhlIE1hc3RyYSBwbHVnaW4uXCIsXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBjb25maWd1cmVkSWQgPVxuICAgICAgdHlwZW9mIG9wdGlvbnMuc2FuZGJveElkID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgPyBvcHRpb25zLnNhbmRib3hJZCh7IHJlcXVlc3RDb250ZXh0IH0pXG4gICAgICAgIDogb3B0aW9ucy5zYW5kYm94SWQ7XG4gICAgY29uc3Qgc2FuZGJveElkID0gY29uZmlndXJlZElkID8/IGRlZmF1bHRTYW5kYm94SWQod29ya3NwYWNlSWQsIHVzZXIuaWQpO1xuICAgIGNvbnN0IGNsaWVudCA9XG4gICAgICB0eXBlb2Ygb3B0aW9ucy5jbGllbnQgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICA/IG9wdGlvbnMuY2xpZW50KHsgcmVxdWVzdENvbnRleHQgfSlcbiAgICAgICAgOiAob3B0aW9ucy5jbGllbnQgPz8gY3JlYXRlV29ya3NwYWNlQ2xpZW50KCkpO1xuICAgIGNvbnN0IHtcbiAgICAgIHByb3ZpZGVyOiBfcHJvdmlkZXIsXG4gICAgICBzYW5kYm94SWQ6IF9zYW5kYm94SWQsXG4gICAgICBjbGllbnQ6IF9jbGllbnQsXG4gICAgICAuLi5zYW5kYm94T3B0aW9uc1xuICAgIH0gPSBvcHRpb25zO1xuICAgIHJldHVybiBuZXcgRGF0YWJyaWNrc1NhbmRib3goe1xuICAgICAgLi4uc2FuZGJveE9wdGlvbnMsXG4gICAgICBjbGllbnQsXG4gICAgICBzYW5kYm94SWQsXG4gICAgICBkaXNwbGF5TmFtZTogb3B0aW9ucy5kaXNwbGF5TmFtZSA/PyBgTWFzdHJhICR7d29ya3NwYWNlTmFtZX1gLFxuICAgIH0pO1xuICB9O1xufVxuXG5mdW5jdGlvbiBkZWZhdWx0U2FuZGJveElkKHdvcmtzcGFjZUlkOiBzdHJpbmcsIHVzZXJJZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgZGlnZXN0ID0gY3JlYXRlSGFzaChcInNoYTI1NlwiKVxuICAgIC51cGRhdGUob2JqZWN0LnRvU3RhYmxlS2V5KHsgd29ya3NwYWNlSWQsIHVzZXJJZCB9KSlcbiAgICAuZGlnZXN0KFwiaGV4XCIpXG4gICAgLnNsaWNlKDAsIDMyKTtcbiAgcmV0dXJuIGBtYXN0cmEtJHtkaWdlc3R9YDtcbn1cblxuZnVuY3Rpb24gaXNTYW5kYm94KHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgV29ya3NwYWNlU2FuZGJveCB7XG4gIHJldHVybiBCb29sZWFuKFxuICAgIHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiBcImlkXCIgaW4gdmFsdWUgJiYgXCJwcm92aWRlclwiIGluIHZhbHVlICYmIFwic3RhdHVzXCIgaW4gdmFsdWUsXG4gICk7XG59XG5cbmZ1bmN0aW9uIHNhbmRib3hOYW1lKHNlbGVjdGlvbjogV29ya3NwYWNlU2FuZGJveFNlbGVjdGlvbiB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XG4gIGlmIChzZWxlY3Rpb24gPT09IHVuZGVmaW5lZCB8fCBzZWxlY3Rpb24gPT09IFwiZGF0YWJyaWNrc1wiKSByZXR1cm4gXCJkYXRhYnJpY2tzXCI7XG4gIGlmIChzZWxlY3Rpb24gPT09IFwibW9udHlcIikgcmV0dXJuIFwibW9udHlcIjtcbiAgaWYgKHNlbGVjdGlvbiA9PT0gZmFsc2UpIHJldHVybiBcImRpc2FibGVkXCI7XG4gIGlmICh0eXBlb2Ygc2VsZWN0aW9uID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBcInJlc29sdmVyXCI7XG4gIHJldHVybiBpc1NhbmRib3goc2VsZWN0aW9uKSA/IHNlbGVjdGlvbi5wcm92aWRlciA6IChzZWxlY3Rpb24ucHJvdmlkZXIgPz8gXCJkYXRhYnJpY2tzXCIpO1xufVxuXG4vKipcbiAqIFJldHVybiB3aGV0aGVyIHRoZSByZXF1ZXN0IHRva2VuIGNhcnJpZXMgYSBzY29wZSB0aGF0IGFsbG93cyB3b3Jrc3BhY2VcbiAqIGZpbGUgQVBJIGFjY2VzcyAoYHdvcmtzcGFjZWAgb3IgYGFsbC1hcGlzYCBvbiB7QGxpbmsgTUFTVFJBX1NDT1BFU19LRVl9KS5cbiAqL1xuZnVuY3Rpb24gaGFzV29ya3NwYWNlRmlsZVNjb3BlKHJlcXVlc3RDb250ZXh0OiBSZXF1ZXN0Q29udGV4dCB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICByZXR1cm4gdG9rZW4uaW5jbHVkZXNBY2Nlc3NUb2tlblNjb3BlKFxuICAgIHJlcXVlc3RDb250ZXh0Py5nZXQoTUFTVFJBX1NDT1BFU19LRVkpLFxuICAgIFdPUktTUEFDRV9GSUxFX1NDT1BFUyxcbiAgKTtcbn1cblxuLyoqXG4gKiBNb3VudCByZXNvbHZlciBmb3IgdGhlIG5hbWVkIHNraWxsIGZvbGRlcnMuXG4gKlxuICogR2F0ZXMgb24gd29ya3NwYWNlIGZpbGUgc2NvcGUgKG9yIGRldmVsb3BtZW50IG1vZGUpLCB0aGVuIG1vdW50cyBldmVyeVxuICogZm9sZGVyIHdob3NlIGxvY2F0aW9uIHJlc29sdmVzIGZvciB0aGlzIHJlcXVlc3QuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVTa2lsbEZvbGRlck1vdW50cyhcbiAgc2tpbGxGb2xkZXJzOiBSZWNvcmQ8c3RyaW5nLCBTa2lsbEZvbGRlck9wdGlvbnM+LFxuICBjb250ZXh0OiBXb3Jrc3BhY2VNb3VudENvbnRleHQsXG4gIHdvcmtzcGFjZVNraWxsUmVmcmVzaFR0bE1zOiBudW1iZXIsXG4pOiBQcm9taXNlPFdvcmtzcGFjZU1vdW50Q29udHJpYnV0aW9uPiB7XG4gIGNvbnN0IG1vdW50czogUmVjb3JkPHN0cmluZywgV29ya3NwYWNlRmlsZXN5c3RlbT4gPSB7fTtcbiAgY29uc3Qgc2tpbGxQYXRoczogc3RyaW5nW10gPSBbXTtcbiAgY29uc3QgY2FjaGVLZXlzOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCByZXF1ZXN0Q29udGV4dCA9IGNvbnRleHQucmVxdWVzdENvbnRleHQ7XG5cbiAgaWYgKCFyZXF1ZXN0Q29udGV4dCB8fCAhc2hvdWxkTW91bnRTa2lsbEZvbGRlcnMocmVxdWVzdENvbnRleHQpKSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwic2tpbGwtZm9sZGVyczpza2lwcGVkXCIsIHtcbiAgICAgIHJlYXNvbjogIXJlcXVlc3RDb250ZXh0ID8gXCJuby1yZXF1ZXN0LWNvbnRleHRcIiA6IFwibWlzc2luZy13b3Jrc3BhY2Utc2NvcGVcIixcbiAgICAgIG5vZGVFbnY6IHByb2Nlc3MuZW52Lk5PREVfRU5WLFxuICAgICAgc2NvcGVzOiByZXF1ZXN0Q29udGV4dD8uZ2V0KE1BU1RSQV9TQ09QRVNfS0VZKSxcbiAgICB9KTtcbiAgICByZXR1cm4geyBtb3VudHMsIHNraWxsUGF0aHMgfTtcbiAgfVxuXG4gIGNvbnN0IHVzZXIgPSByZXF1ZXN0Q29udGV4dC5nZXQoTUFTVFJBX1VTRVJfS0VZKSBhcyBVc2VyIHwgdW5kZWZpbmVkO1xuICBjb25zdCBjbGllbnQgPSB1c2VyPy5leGVjdXRpb25Db250ZXh0LmNsaWVudCBhcyBXb3Jrc3BhY2VDbGllbnQgfCB1bmRlZmluZWQ7XG4gIGNvbnN0IHVzZXJLZXkgPSB1c2VyID8gcmVzb2x2ZVVzZXJLZXkocmVxdWVzdENvbnRleHQpIDogdW5kZWZpbmVkO1xuICBjb25zdCBob3N0ID0gY2xpZW50ID8gKGF3YWl0IGNsaWVudC5jb25maWcuZ2V0SG9zdCgpKS50b1N0cmluZygpIDogdW5kZWZpbmVkO1xuXG4gIGZvciAoY29uc3QgW25hbWUsIGZvbGRlcl0gb2YgT2JqZWN0LmVudHJpZXMoc2tpbGxGb2xkZXJzKSkge1xuICAgIGNvbnN0IHJlc29sdmVkID0gYXdhaXQgcmVzb2x2ZVNraWxsRm9sZGVyRmlsZXN5c3RlbShuYW1lLCBmb2xkZXIsIGNvbnRleHQsIHtcbiAgICAgIGNsaWVudCxcbiAgICAgIGhvc3QsXG4gICAgICB1c2VyS2V5LFxuICAgICAgd29ya3NwYWNlU2tpbGxSZWZyZXNoVHRsTXMsXG4gICAgfSk7XG4gICAgaWYgKCFyZXNvbHZlZCkgY29udGludWU7XG4gICAgY29uc3QgbW91bnQgPSBmb2xkZXIubW91bnQgPz8gYC8ke25hbWV9YDtcbiAgICBtb3VudHNbbW91bnRdID0gcmVzb2x2ZWQuZmlsZXN5c3RlbTtcbiAgICBpZiAocmVzb2x2ZWQuY2FjaGVLZXkpIGNhY2hlS2V5cy5wdXNoKHJlc29sdmVkLmNhY2hlS2V5KTtcbiAgICBpZiAoZm9sZGVyLnJlYWRhYmxlICE9PSBmYWxzZSkgc2tpbGxQYXRocy5wdXNoKG1vdW50KTtcbiAgfVxuXG4gIGxvZ2dlci5kZWJ1ZyhcInNraWxsLWZvbGRlcnM6bW91bnRlZFwiLCB7XG4gICAgbW91bnRLZXlzOiBPYmplY3Qua2V5cyhtb3VudHMpLFxuICAgIHNraWxsUGF0aHMsXG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgbW91bnRzLFxuICAgIHNraWxsUGF0aHMsXG4gICAgLi4uKGNhY2hlS2V5cy5sZW5ndGggPT09IE9iamVjdC5rZXlzKG1vdW50cykubGVuZ3RoICYmIGNhY2hlS2V5cy5sZW5ndGggPiAwXG4gICAgICA/IHsgY2FjaGVLZXk6IG9iamVjdC50b1N0YWJsZUtleShjYWNoZUtleXMuc29ydCgpKSB9XG4gICAgICA6IHt9KSxcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIG9uZSBza2lsbCBmb2xkZXIgdG8gYSBNYXN0cmEgZmlsZXN5c3RlbSwgb3IgYHVuZGVmaW5lZGAgdG8gc2tpcCBpdFxuICogZm9yIHRoaXMgcmVxdWVzdC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZVNraWxsRm9sZGVyRmlsZXN5c3RlbShcbiAgbmFtZTogc3RyaW5nLFxuICBmb2xkZXI6IFNraWxsRm9sZGVyT3B0aW9ucyxcbiAgY29udGV4dDogV29ya3NwYWNlTW91bnRDb250ZXh0LFxuICBjYWNoZToge1xuICAgIGNsaWVudDogV29ya3NwYWNlQ2xpZW50IHwgdW5kZWZpbmVkO1xuICAgIGhvc3Q6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICB1c2VyS2V5OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgd29ya3NwYWNlU2tpbGxSZWZyZXNoVHRsTXM6IG51bWJlcjtcbiAgfSxcbik6IFByb21pc2U8eyBjYWNoZUtleT86IHN0cmluZzsgZmlsZXN5c3RlbTogV29ya3NwYWNlRmlsZXN5c3RlbSB9IHwgdW5kZWZpbmVkPiB7XG4gIGlmIChmb2xkZXIuZmlsZXN5c3RlbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgZmlsZXN5c3RlbSA9IGF3YWl0IHJlc29sdmVTa2lsbEZvbGRlclZhbHVlKGZvbGRlci5maWxlc3lzdGVtLCBjb250ZXh0KTtcbiAgICByZXR1cm4gZmlsZXN5c3RlbSA/IHsgZmlsZXN5c3RlbSB9IDogdW5kZWZpbmVkO1xuICB9XG4gIC8vIEEgcGF0aCBtb3VudCBuZWVkcyB0aGUgcmVxdWVzdCdzIE9CTyBjbGllbnQgdG8gcmVhY2ggdGhlIHdvcmtzcGFjZS5cbiAgaWYgKGZvbGRlci5wYXRoID09PSB1bmRlZmluZWQgfHwgIWNhY2hlLmNsaWVudCB8fCAhY2FjaGUuaG9zdCB8fCAhY2FjaGUudXNlcktleSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhcInNraWxsLWZvbGRlcjpza2lwcGVkXCIsIHtcbiAgICAgIG5hbWUsXG4gICAgICByZWFzb246IGZvbGRlci5wYXRoID09PSB1bmRlZmluZWQgPyBcIm5vLWxvY2F0aW9uXCIgOiBcIm1pc3Npbmctb2JvLWNsaWVudFwiLFxuICAgIH0pO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3Qgcm9vdCA9IHN0cmluZ1V0aWxzLnRyaW1Ub051bGwoYXdhaXQgcmVzb2x2ZVNraWxsRm9sZGVyVmFsdWUoZm9sZGVyLnBhdGgsIGNvbnRleHQpKTtcbiAgaWYgKCFyb290KSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4gZGF0YWJyaWNrc0ZpbGVzeXN0ZW0oY2FjaGUuY2xpZW50LCByb290LCBmb2xkZXIud3JpdGFibGUgIT09IHRydWUsIHtcbiAgICBob3N0OiBjYWNoZS5ob3N0LFxuICAgIHR0bE1zOiBjYWNoZS53b3Jrc3BhY2VTa2lsbFJlZnJlc2hUdGxNcyxcbiAgICB1c2VyS2V5OiBjYWNoZS51c2VyS2V5LFxuICB9KTtcbn1cblxuLyoqIFJlYWQgYSB7QGxpbmsgU2tpbGxGb2xkZXJWYWx1ZX0sIGNhbGxpbmcgaXQgd2hlbiBpdCBpcyBhIHBlci1yZXF1ZXN0IHJlc29sdmVyLiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVNraWxsRm9sZGVyVmFsdWU8VD4oXG4gIHZhbHVlOiBTa2lsbEZvbGRlclZhbHVlPFQ+LFxuICBjb250ZXh0OiBXb3Jrc3BhY2VNb3VudENvbnRleHQsXG4pOiBUIHwgdW5kZWZpbmVkIHwgUHJvbWlzZTxUIHwgdW5kZWZpbmVkPiB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIlxuICAgID8gKHZhbHVlIGFzIChjb250ZXh0OiBXb3Jrc3BhY2VNb3VudENvbnRleHQpID0+IFQgfCB1bmRlZmluZWQgfCBQcm9taXNlPFQgfCB1bmRlZmluZWQ+KShjb250ZXh0KVxuICAgIDogdmFsdWU7XG59XG5cbi8qKlxuICogRmlsbCBpbiBgaWRgIGFuZCBgbmFtZWAgd2hlbiBlaXRoZXIgaXMgb21pdHRlZCBvbiB7QGxpbmsgQ3JlYXRlV29ya3NwYWNlT3B0aW9uc30uXG4gKiBTbHVnaWZpZXMgYG5hbWVgIGludG8gYGlkYDsgdG9rZW5pemVzIGBpZGAgaW50byBhIGRpc3BsYXkgYG5hbWVgLlxuICovXG5mdW5jdGlvbiByZXNvbHZlV29ya3NwYWNlSWRlbnRpdHkob3B0aW9uczogQ3JlYXRlV29ya3NwYWNlT3B0aW9ucyk6IHtcbiAgaWQ6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xufSB7XG4gIGxldCBpZCA9IG9wdGlvbnMuaWQ7XG4gIGxldCBuYW1lID0gb3B0aW9ucy5uYW1lO1xuICBpZiAoIWlkKSB7XG4gICAgaWQgPSBuYW1lID8gc3RyaW5nVXRpbHMudG9TbHVnKG5hbWUpIDogXCJ3b3Jrc3BhY2VcIjtcbiAgfVxuICBpZiAoIW5hbWUpIHtcbiAgICBuYW1lID0gQXJyYXkuZnJvbShzdHJpbmdVdGlscy50b2tlbml6ZShpZCkpLmpvaW4oXCIgXCIpO1xuICB9XG4gIHJldHVybiB7IGlkLCBuYW1lIH07XG59XG5cbi8qKiBDb2xsZWN0IHRoZSBza2lsbC1mb2xkZXIgcmVzb2x2ZXIgYW5kIGFueSBjYWxsZXItc3VwcGxpZWQgb25lcy4gKi9cbmZ1bmN0aW9uIGJ1aWxkTW91bnRSZXNvbHZlcnMoXG4gIHNraWxsRm9sZGVyczogUmVjb3JkPHN0cmluZywgU2tpbGxGb2xkZXJPcHRpb25zPixcbiAgbW91bnRzOiBXb3Jrc3BhY2VNb3VudFJlc29sdmVyW10gfCB1bmRlZmluZWQsXG4gIHdvcmtzcGFjZVNraWxsUmVmcmVzaFR0bE1zID0gREVGQVVMVF9XT1JLU1BBQ0VfU0tJTExfQ0FDSEVfVFRMX01TLFxuKTogV29ya3NwYWNlTW91bnRSZXNvbHZlcltdIHtcbiAgY29uc3QgcmVzb2x2ZXJzOiBXb3Jrc3BhY2VNb3VudFJlc29sdmVyW10gPSBbXTtcbiAgY29uc3QgZm9sZGVyQ291bnQgPSBPYmplY3Qua2V5cyhza2lsbEZvbGRlcnMpLmxlbmd0aDtcbiAgaWYgKGZvbGRlckNvdW50ID4gMCkge1xuICAgIHJlc29sdmVycy5wdXNoKChjb250ZXh0KSA9PlxuICAgICAgcmVzb2x2ZVNraWxsRm9sZGVyTW91bnRzKHNraWxsRm9sZGVycywgY29udGV4dCwgd29ya3NwYWNlU2tpbGxSZWZyZXNoVHRsTXMpLFxuICAgICk7XG4gIH1cbiAgaWYgKG1vdW50cz8ubGVuZ3RoKSB7XG4gICAgcmVzb2x2ZXJzLnB1c2goLi4ubW91bnRzKTtcbiAgfVxuICBsb2dnZXIuZGVidWcoXCJtb3VudHM6cmVzb2x2ZXJzXCIsIHtcbiAgICBza2lsbEZvbGRlckNvdW50OiBmb2xkZXJDb3VudCxcbiAgICBjdXN0b21SZXNvbHZlckNvdW50OiBtb3VudHM/Lmxlbmd0aCA/PyAwLFxuICAgIHRvdGFsUmVzb2x2ZXJDb3VudDogcmVzb2x2ZXJzLmxlbmd0aCxcbiAgfSk7XG4gIHJldHVybiByZXNvbHZlcnM7XG59XG5cbi8qKlxuICogR2F0ZSBza2lsbC1mb2xkZXIgbW91bnRzIG9uIHRoZSByZXF1ZXN0J3MgdG9rZW4uXG4gKlxuICogQWx3YXlzIGFsbG93cyBtb3VudHMgaW4gZGV2ZWxvcG1lbnQ7IGluIG90aGVyIGVudmlyb25tZW50cyByZXF1aXJlc1xuICoge0BsaW5rIGhhc1dvcmtzcGFjZUZpbGVTY29wZX0uXG4gKi9cbmZ1bmN0aW9uIHNob3VsZE1vdW50U2tpbGxGb2xkZXJzKHJlcXVlc3RDb250ZXh0OiBSZXF1ZXN0Q29udGV4dCk6IGJvb2xlYW4ge1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwiZGV2ZWxvcG1lbnRcIikgcmV0dXJuIHRydWU7XG4gIHJldHVybiBoYXNXb3Jrc3BhY2VGaWxlU2NvcGUocmVxdWVzdENvbnRleHQpO1xufVxuXG4vKiogUmVhZCB0aGUgdHJpbW1lZCBPQk8gdXNlciBlbWFpbCBzdGFtcGVkIG9uIHtAbGluayBNQVNUUkFfVVNFUl9FTUFJTF9LRVl9LiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVNjb3BlZEVtYWlsKHJlcXVlc3RDb250ZXh0OiBSZXF1ZXN0Q29udGV4dCB8IHVuZGVmaW5lZCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBzdHJpbmdVdGlscy50cmltVG9OdWxsKHJlcXVlc3RDb250ZXh0Py5nZXQoTUFTVFJBX1VTRVJfRU1BSUxfS0VZKSkgPz8gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFdyYXAgYSB7QGxpbmsgRGF0YWJyaWNrc0ZpbGVTeXN0ZW19IGFzIGEgTWFzdHJhIGZpbGVzeXN0ZW0uIFdoZW4gdGhlIHJvb3QgaXNcbiAqIG1pc3NpbmcgKGFuZCB7QGxpbmsgcmVhZE9ubHl9IHNvIHdlIHdpbGwgbm90IGNyZWF0ZSBpdCksIGZhbGwgYmFjayB0b1xuICoge0BsaW5rIHNjcmF0Y2hGaWxlc3lzdGVtfSBzbyBza2lsbCBzY2FucyBzdGlsbCBoYXZlIGEgd3JpdGFibGUgbG9jYWwgbW91bnQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGRhdGFicmlja3NGaWxlc3lzdGVtKFxuICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudCxcbiAgcm9vdDogc3RyaW5nLFxuICByZWFkT25seTogYm9vbGVhbiA9IHRydWUsXG4gIGNhY2hlOiB7IGhvc3Q6IHN0cmluZzsgdHRsTXM6IG51bWJlcjsgdXNlcktleTogc3RyaW5nIH0sXG4pOiBQcm9taXNlPHsgY2FjaGVLZXk6IHN0cmluZzsgZmlsZXN5c3RlbTogV29ya3NwYWNlRmlsZXN5c3RlbSB9IHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IGZzID0gbmV3IERhdGFicmlja3NGaWxlU3lzdGVtKHtcbiAgICBjbGllbnQ6IHdvcmtzcGFjZUNsaWVudC50b0xlZ2FjeVdvcmtzcGFjZUNsaWVudChjbGllbnQpLFxuICAgIHJvb3QsXG4gICAgcmVhZE9ubHksXG4gICAgY3JlYXRlUm9vdDogIXJlYWRPbmx5LFxuICB9KTtcbiAgY29uc3QgY2FjaGVkID0gY2FjaGVkV29ya3NwYWNlU2tpbGxNb3VudCh7XG4gICAgaG9zdDogY2FjaGUuaG9zdCxcbiAgICBzb3VyY2U6IGZzLFxuICAgIHR0bE1zOiBjYWNoZS50dGxNcyxcbiAgICB1c2VyS2V5OiBjYWNoZS51c2VyS2V5LFxuICB9KTtcbiAgdHJ5IHtcbiAgICBhd2FpdCBjYWNoZWQuZmlsZXN5c3RlbS5pbml0KCk7XG4gICAgaWYgKGF3YWl0IGNhY2hlZC5maWxlc3lzdGVtLmV4aXN0cyhcIi5cIikpIHJldHVybiBjYWNoZWQ7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci5kZWJ1ZyhcImRhdGFicmlja3MtbW91bnQ6c2NyYXRjaC1mYWxsYmFja1wiLCB7XG4gICAgICByb290LFxuICAgICAgcmVhZE9ubHksXG4gICAgICBlcnJvcjogZXJyb3JVdGlscy5lcnJvck1lc3NhZ2UoZXJyKSxcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFJ1biBldmVyeSBtb3VudCByZXNvbHZlciBmb3Igb25lIHJlcXVlc3QgYW5kIG1lcmdlIG1vdW50cyBwbHVzIHNraWxsIHBhdGhzLlxuICogTGF0ZXIgcmVzb2x2ZXJzIG92ZXJ3cml0ZSBtb3VudCBrZXlzIGZyb20gZWFybGllciBvbmVzLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlV29ya3NwYWNlQ29udHJpYnV0aW9uKFxuICByZXNvbHZlcnM6IFdvcmtzcGFjZU1vdW50UmVzb2x2ZXJbXSxcbiAgY29udGV4dDogV29ya3NwYWNlTW91bnRDb250ZXh0LFxuKTogUHJvbWlzZTxXb3Jrc3BhY2VNb3VudENvbnRyaWJ1dGlvbj4ge1xuICBjb25zdCBtb3VudHM6IFJlY29yZDxzdHJpbmcsIFdvcmtzcGFjZUZpbGVzeXN0ZW0+ID0ge307XG4gIGNvbnN0IHNraWxsUGF0aHM6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IGNhY2hlS2V5czogc3RyaW5nW10gPSBbXTtcbiAgbGV0IGNhY2hlYWJsZSA9IHRydWU7XG5cbiAgZm9yIChjb25zdCBbaW5kZXgsIHJlc29sdmVyXSBvZiByZXNvbHZlcnMuZW50cmllcygpKSB7XG4gICAgY29uc3QgY29udHJpYnV0aW9uID0gYXdhaXQgcmVzb2x2ZXIoY29udGV4dCk7XG4gICAgbG9nZ2VyLmRlYnVnKFwibW91bnRzOnJlc29sdmVyXCIsIHtcbiAgICAgIGluZGV4LFxuICAgICAgbW91bnRLZXlzOiBPYmplY3Qua2V5cyhjb250cmlidXRpb24ubW91bnRzKSxcbiAgICAgIHNraWxsUGF0aHM6IGNvbnRyaWJ1dGlvbi5za2lsbFBhdGhzID8/IFtdLFxuICAgIH0pO1xuICAgIE9iamVjdC5hc3NpZ24obW91bnRzLCBjb250cmlidXRpb24ubW91bnRzKTtcbiAgICBpZiAoT2JqZWN0LmtleXMoY29udHJpYnV0aW9uLm1vdW50cykubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKGNvbnRyaWJ1dGlvbi5jYWNoZUtleSkgY2FjaGVLZXlzLnB1c2goY29udHJpYnV0aW9uLmNhY2hlS2V5KTtcbiAgICAgIGVsc2UgY2FjaGVhYmxlID0gZmFsc2U7XG4gICAgfVxuICAgIGlmIChjb250cmlidXRpb24uc2tpbGxQYXRocz8ubGVuZ3RoKSB7XG4gICAgICBza2lsbFBhdGhzLnB1c2goLi4uY29udHJpYnV0aW9uLnNraWxsUGF0aHMpO1xuICAgIH1cbiAgfVxuXG4gIGxvZ2dlci5kZWJ1ZyhcIm1vdW50czptZXJnZWRcIiwge1xuICAgIG1vdW50S2V5czogT2JqZWN0LmtleXMobW91bnRzKSxcbiAgICBza2lsbFBhdGhzLFxuICB9KTtcblxuICByZXR1cm4ge1xuICAgIG1vdW50cyxcbiAgICBza2lsbFBhdGhzLFxuICAgIC4uLihjYWNoZWFibGUgJiYgY2FjaGVLZXlzLmxlbmd0aCA+IDBcbiAgICAgID8geyBjYWNoZUtleTogb2JqZWN0LnRvU3RhYmxlS2V5KGNhY2hlS2V5cy5zb3J0KCkpIH1cbiAgICAgIDoge30pLFxuICB9O1xufVxuXG4vKipcbiAqIER5bmFtaWMgZmlsZXN5c3RlbSByZXNvbHZlciBwYXNzZWQgdG8gTWFzdHJhIHtAbGluayBXb3Jrc3BhY2V9LlxuICpcbiAqIFJldHVybnMgYSB7QGxpbmsgQ29tcG9zaXRlRmlsZXN5c3RlbX0gd2hlbiBhbnkgbW91bnQgcmVzb2x2ZWQ7IG90aGVyd2lzZSBhXG4gKiBmcmVzaCB7QGxpbmsgc2NyYXRjaEZpbGVzeXN0ZW19IHNvIE1hc3RyYSBhbHdheXMgaGFzIGEgd3JpdGFibGUgbG9jYWwgcm9vdC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZVdvcmtzcGFjZUZpbGVzeXN0ZW0oXG4gIHJlc29sdmVyczogV29ya3NwYWNlTW91bnRSZXNvbHZlcltdLFxuICBjb250ZXh0OiBXb3Jrc3BhY2VNb3VudENvbnRleHQsXG4pOiBQcm9taXNlPFdvcmtzcGFjZUZpbGVzeXN0ZW0+IHtcbiAgY29uc3QgeyBjYWNoZUtleSwgbW91bnRzIH0gPSBhd2FpdCByZXNvbHZlV29ya3NwYWNlQ29udHJpYnV0aW9uKHJlc29sdmVycywgY29udGV4dCk7XG4gIGNvbnN0IG1vdW50S2V5cyA9IE9iamVjdC5rZXlzKG1vdW50cyk7XG4gIGlmIChtb3VudEtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwiZmlsZXN5c3RlbTpzY3JhdGNoXCIsIHtcbiAgICAgIGhhc1JlcXVlc3RDb250ZXh0OiBCb29sZWFuKGNvbnRleHQucmVxdWVzdENvbnRleHQpLFxuICAgIH0pO1xuICAgIHJldHVybiBzY3JhdGNoRmlsZXN5c3RlbSgpO1xuICB9XG4gIGxvZ2dlci5kZWJ1ZyhcImZpbGVzeXN0ZW06Y29tcG9zaXRlXCIsIHsgbW91bnRLZXlzIH0pO1xuICBpZiAoIWNhY2hlS2V5KSByZXR1cm4gbmV3IENvbXBvc2l0ZUZpbGVzeXN0ZW0oeyBtb3VudHMgfSk7XG4gIGNvbnN0IGV4aXN0aW5nID0gc2NvcGVkV29ya3NwYWNlRmlsZXN5c3RlbXMuZ2V0KGNhY2hlS2V5KTtcbiAgaWYgKGV4aXN0aW5nKSB7XG4gICAgc2NvcGVkV29ya3NwYWNlRmlsZXN5c3RlbXMuZGVsZXRlKGNhY2hlS2V5KTtcbiAgICBzY29wZWRXb3Jrc3BhY2VGaWxlc3lzdGVtcy5zZXQoY2FjaGVLZXksIGV4aXN0aW5nKTtcbiAgICByZXR1cm4gZXhpc3Rpbmc7XG4gIH1cbiAgY29uc3QgZmlsZXN5c3RlbSA9IG5ldyBDb21wb3NpdGVGaWxlc3lzdGVtKHsgbW91bnRzIH0pO1xuICBzY29wZWRXb3Jrc3BhY2VGaWxlc3lzdGVtcy5zZXQoY2FjaGVLZXksIGZpbGVzeXN0ZW0pO1xuICB3aGlsZSAoc2NvcGVkV29ya3NwYWNlRmlsZXN5c3RlbXMuc2l6ZSA+IE1BWF9TQ09QRURfV09SS1NQQUNFX0ZJTEVTWVNURU1TKSB7XG4gICAgY29uc3Qgb2xkZXN0ID0gc2NvcGVkV29ya3NwYWNlRmlsZXN5c3RlbXMua2V5cygpLm5leHQoKS52YWx1ZTtcbiAgICBpZiAob2xkZXN0ID09PSB1bmRlZmluZWQpIGJyZWFrO1xuICAgIHNjb3BlZFdvcmtzcGFjZUZpbGVzeXN0ZW1zLmRlbGV0ZShvbGRlc3QpO1xuICB9XG4gIHJldHVybiBmaWxlc3lzdGVtO1xufVxuXG4vKipcbiAqIEJ1aWxkIHRoZSBkeW5hbWljIHtAbGluayBTa2lsbHNSZXNvbHZlcn0gdGhhdCBjb2xsZWN0cyBgc2tpbGxQYXRoc2AgZnJvbVxuICogZXZlcnkgbW91bnQgcmVzb2x2ZXIgb24gZWFjaCByZXF1ZXN0LlxuICovXG5mdW5jdGlvbiBidWlsZFdvcmtzcGFjZVNraWxsc1Jlc29sdmVyKFxuICByZXNvbHZlcnM6IFdvcmtzcGFjZU1vdW50UmVzb2x2ZXJbXSxcbiAgZXh0cmFTa2lsbFBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuKTogU2tpbGxzUmVzb2x2ZXIge1xuICByZXR1cm4gYXN5bmMgKGNvbnRleHQ6IFNraWxsc0NvbnRleHQpID0+IHtcbiAgICBjb25zdCB7IHNraWxsUGF0aHMgfSA9IGF3YWl0IHJlc29sdmVXb3Jrc3BhY2VDb250cmlidXRpb24ocmVzb2x2ZXJzLCBjb250ZXh0KTtcbiAgICBjb25zdCBtZXJnZWQgPSBbLi4uKHNraWxsUGF0aHMgPz8gW10pLCAuLi5leHRyYVNraWxsUGF0aHNdO1xuICAgIGxvZ2dlci5kZWJ1ZyhcInNraWxsczpyZXNvbHZlZFwiLCB7IHNraWxsUGF0aHMsIGV4dHJhU2tpbGxQYXRocyB9KTtcbiAgICByZXR1cm4gbWVyZ2VkO1xuICB9O1xufVxuIl19
@@ -1 +1 @@
1
- {"root":["../src/agents.ts","../src/chart.ts","../src/chat.ts","../src/config.ts","../src/defaults.ts","../src/evaluation.ts","../src/filesystems.ts","../src/genie.ts","../src/identity.ts","../src/mcp.ts","../src/memory.ts","../src/mlflow.ts","../src/model.ts","../src/monty-sandbox.ts","../src/observability.ts","../src/plugin.ts","../src/processors.ts","../src/remote-skills.ts","../src/rest.ts","../src/sandbox.ts","../src/server.ts","../src/serving-sanitize.ts","../src/serving.ts","../src/skill-paths.ts","../src/statement.ts","../src/storage-schema.ts","../src/style.ts","../src/summarize.ts","../src/telemetry.ts","../src/validation.ts","../src/workspaces.ts","../src/writer.ts","../index.ts"],"version":"5.9.3"}
1
+ {"root":["../src/agents.ts","../src/chart.ts","../src/chat.ts","../src/config.ts","../src/defaults.ts","../src/evaluation.ts","../src/filesystems.ts","../src/genie.ts","../src/identity.ts","../src/mcp.ts","../src/memory.ts","../src/mlflow.ts","../src/model.ts","../src/monty-sandbox.ts","../src/observability.ts","../src/plugin.ts","../src/processors.ts","../src/remote-skills.ts","../src/rest.ts","../src/sandbox.ts","../src/server.ts","../src/serving-sanitize.ts","../src/serving.ts","../src/skill-cache.ts","../src/skill-paths.ts","../src/statement.ts","../src/storage-schema.ts","../src/style.ts","../src/summarize.ts","../src/telemetry.ts","../src/validation.ts","../src/workspaces.ts","../src/writer.ts","../index.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -33,19 +33,19 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@databricks/appkit": "0.81.0",
36
- "@dbx-tools/appkit": "^0.9.61",
37
- "@dbx-tools/core": "^0.9.61",
38
- "@dbx-tools/databricks": "^0.9.61",
39
- "@dbx-tools/fs": "^0.9.61",
40
- "@dbx-tools/genie": "^0.9.61",
41
- "@dbx-tools/model": "^0.9.61",
42
- "@dbx-tools/path": "^0.9.61",
43
- "@dbx-tools/postgres": "^0.9.61",
44
- "@dbx-tools/shared-core": "^0.9.61",
45
- "@dbx-tools/shared-fs": "^0.9.61",
46
- "@dbx-tools/shared-genie": "^0.9.61",
47
- "@dbx-tools/shared-mastra": "^0.9.61",
48
- "@dbx-tools/shared-model": "^0.9.61",
36
+ "@dbx-tools/appkit": "^0.9.64",
37
+ "@dbx-tools/core": "^0.9.64",
38
+ "@dbx-tools/databricks": "^0.9.64",
39
+ "@dbx-tools/fs": "^0.9.64",
40
+ "@dbx-tools/genie": "^0.9.64",
41
+ "@dbx-tools/model": "^0.9.64",
42
+ "@dbx-tools/path": "^0.9.64",
43
+ "@dbx-tools/postgres": "^0.9.64",
44
+ "@dbx-tools/shared-core": "^0.9.64",
45
+ "@dbx-tools/shared-fs": "^0.9.64",
46
+ "@dbx-tools/shared-genie": "^0.9.64",
47
+ "@dbx-tools/shared-mastra": "^0.9.64",
48
+ "@dbx-tools/shared-model": "^0.9.64",
49
49
  "@mastra/ai-sdk": "1.10.5",
50
50
  "@mastra/core": "1.71.0",
51
51
  "@mastra/express": "1.5.15",
@@ -166,6 +166,10 @@
166
166
  "types": "./lib/src/serving.d.ts",
167
167
  "default": "./lib/src/serving.js"
168
168
  },
169
+ "./skill-cache": {
170
+ "types": "./lib/src/skill-cache.d.ts",
171
+ "default": "./lib/src/skill-cache.js"
172
+ },
169
173
  "./skill-paths": {
170
174
  "types": "./lib/src/skill-paths.d.ts",
171
175
  "default": "./lib/src/skill-paths.js"
@@ -205,7 +209,7 @@
205
209
  "./package.json": "./package.json"
206
210
  }
207
211
  },
208
- "version": "0.9.61",
212
+ "version": "0.9.64",
209
213
  "types": "./lib/index.d.ts",
210
214
  "dbxToolsConfig": {
211
215
  "tags": [
@@ -310,6 +314,10 @@
310
314
  "types": "./lib/src/serving.d.ts",
311
315
  "default": "./lib/src/serving.js"
312
316
  },
317
+ "./skill-cache": {
318
+ "types": "./lib/src/skill-cache.d.ts",
319
+ "default": "./lib/src/skill-cache.js"
320
+ },
313
321
  "./skill-paths": {
314
322
  "types": "./lib/src/skill-paths.d.ts",
315
323
  "default": "./lib/src/skill-paths.js"
package/src/agents.ts CHANGED
@@ -32,6 +32,7 @@ import type {
32
32
  ToolsInput,
33
33
  } from "@mastra/core/agent";
34
34
  import { Agent } from "@mastra/core/agent";
35
+ import { SkillSearchProcessor } from "@mastra/core/processors";
35
36
  import { MASTRA_RESOURCE_ID_KEY } from "@mastra/core/request-context";
36
37
  import type { Tool } from "@mastra/core/tools";
37
38
  import { createTool } from "@mastra/core/tools";
@@ -569,10 +570,16 @@ export async function buildAgents(opts: {
569
570
  let workspace = resolveAgentWorkspace(def.workspace);
570
571
  if (
571
572
  (def.workspace === undefined && !workspace) ||
572
- ((extraSkillPaths?.length || config.sandbox !== undefined) && isDefaultWorkspace(workspace))
573
+ ((extraSkillPaths?.length ||
574
+ config.sandbox !== undefined ||
575
+ config.workspaceSkillRefreshTtlMs !== undefined) &&
576
+ isDefaultWorkspace(workspace))
573
577
  ) {
574
578
  workspace = createWorkspace({
575
579
  extraSkillPaths,
580
+ ...(config.workspaceSkillRefreshTtlMs !== undefined
581
+ ? { workspaceSkillRefreshTtlMs: config.workspaceSkillRefreshTtlMs }
582
+ : {}),
576
583
  sandbox:
577
584
  config.sandbox === undefined || config.sandbox === true ? "databricks" : config.sandbox,
578
585
  });
@@ -602,7 +609,7 @@ export async function buildAgents(opts: {
602
609
  tools,
603
610
  ...(memory ? { memory } : {}),
604
611
  ...(workspace ? { workspace } : {}),
605
- inputProcessors,
612
+ inputProcessors: [...inputProcessors, ...workspaceSkillInputProcessors(workspace, config)],
606
613
  });
607
614
  // Surface the effective default model per agent so operators can
608
615
  // see at a glance which endpoint each agent points at without
@@ -634,6 +641,26 @@ export async function buildAgents(opts: {
634
641
  return { agents, defaultAgentId, defaultModels, ambientTools };
635
642
  }
636
643
 
644
+ function workspaceSkillInputProcessors(
645
+ workspace: Workspace | undefined,
646
+ config: MastraPluginConfig,
647
+ ): SkillSearchProcessor[] {
648
+ if (!workspace?.skills || config.workspaceSkillSearch === false) return [];
649
+ const options =
650
+ typeof config.workspaceSkillSearch === "object" ? config.workspaceSkillSearch : undefined;
651
+ return [
652
+ new SkillSearchProcessor({
653
+ workspace,
654
+ search: {
655
+ topK: options?.topK ?? 5,
656
+ minScore: options?.minScore ?? 0.1,
657
+ },
658
+ ...(options?.ttlMs !== undefined ? { ttl: options.ttlMs } : {}),
659
+ blockingRefresh: false,
660
+ }),
661
+ ];
662
+ }
663
+
637
664
  /**
638
665
  * Tool ids on `tools` that are approval-gated (`requireApproval: true`).
639
666
  * Keys are used as a fallback when a tool omits an explicit `id`.
package/src/config.ts CHANGED
@@ -147,6 +147,16 @@ export type MastraMemoryConfig = PgVectorConfig & {
147
147
  id?: string;
148
148
  };
149
149
 
150
+ /** On-demand workspace skill search configuration. */
151
+ export interface MastraSkillSearchConfig {
152
+ /** Maximum skill matches returned by one search. Defaults to 5. */
153
+ topK?: number;
154
+ /** Minimum BM25 relevance score. Defaults to 0.1. */
155
+ minScore?: number;
156
+ /** Loaded-skill thread-state TTL in milliseconds. Defaults to one hour. */
157
+ ttlMs?: number;
158
+ }
159
+
150
160
  /**
151
161
  * Fine-grained control for the optional MCP server exposure
152
162
  * ({@link MastraPluginConfig.mcp}). Every field is optional; the object
@@ -207,6 +217,16 @@ export interface MastraPluginConfig extends BasePluginConfig {
207
217
  * custom `workspace` keeps that workspace and its sandbox.
208
218
  */
209
219
  sandbox?: boolean | "databricks" | "monty" | DatabricksWorkspaceSandboxOptions;
220
+ /**
221
+ * AppKit cache TTL for user-scoped Databricks workspace skill files.
222
+ * Defaults to five minutes.
223
+ */
224
+ workspaceSkillRefreshTtlMs?: number;
225
+ /**
226
+ * Use Mastra's on-demand skill search instead of injecting the full skill
227
+ * catalogue. Defaults to true. Pass an object to tune search.
228
+ */
229
+ workspaceSkillSearch?: boolean | MastraSkillSearchConfig;
210
230
  /**
211
231
  * Code-defined agents. Accepts three shapes for convenience:
212
232
  *
@@ -647,6 +667,16 @@ export const MASTRA_CONFIG_SCHEMA: ConfigSchema = {
647
667
  description:
648
668
  'Command sandbox for auto-created agent workspaces. Defaults to Databricks Sandbox with Monty fallback; false disables command execution, "monty" selects Monty directly, and an object configures Databricks lifecycle/fallback settings.',
649
669
  },
670
+ workspaceSkillRefreshTtlMs: {
671
+ type: "number",
672
+ description:
673
+ "AppKit cache TTL in milliseconds for user-scoped Databricks workspace skill files. Defaults to 5 minutes.",
674
+ },
675
+ workspaceSkillSearch: {
676
+ type: ["boolean", "object"],
677
+ description:
678
+ "Use Mastra on-demand skill search instead of injecting every skill description. Defaults to true.",
679
+ },
650
680
  defaultAgent: {
651
681
  type: "string",
652
682
  description: