obsidian-integration-testing 14.1.0 → 15.0.0

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 (114) hide show
  1. package/README.md +2 -0
  2. package/dist/lib/cjs/appium-dependencies.cjs +2 -5
  3. package/dist/lib/cjs/appium-server-marker.cjs +3 -9
  4. package/dist/lib/cjs/asar-fallback-detection.cjs +2 -5
  5. package/dist/lib/cjs/avd-probe-verdict.cjs +3 -9
  6. package/dist/lib/cjs/capture-obsidian-screenshot.cjs +9 -1
  7. package/dist/lib/cjs/capture-obsidian-screenshot.d.cts +21 -0
  8. package/dist/lib/cjs/capture-screenshot.cjs +2 -5
  9. package/dist/lib/cjs/cli.cjs +2 -5
  10. package/dist/lib/cjs/demo-vault-populate.cjs +7 -9
  11. package/dist/lib/cjs/device-setting-restore.cjs +2 -5
  12. package/dist/lib/cjs/electron-compatibility.cjs +8 -11
  13. package/dist/lib/cjs/emulator-arguments.cjs +14 -14
  14. package/dist/lib/cjs/emulator-marker.cjs +4 -13
  15. package/dist/lib/cjs/emulator-reaper.cjs +2 -5
  16. package/dist/lib/cjs/emulator-snapshot.cjs +3 -9
  17. package/dist/lib/cjs/eval-cap-exceeded-error.cjs +2 -5
  18. package/dist/lib/cjs/exec.cjs +12 -24
  19. package/dist/lib/cjs/function-expression.cjs +2 -5
  20. package/dist/lib/cjs/global-setup-core.cjs +53 -18
  21. package/dist/lib/cjs/hide-vault-name.cjs +45 -0
  22. package/dist/lib/cjs/hide-vault-name.d.cts +67 -0
  23. package/dist/lib/cjs/index.cjs +9 -1
  24. package/dist/lib/cjs/index.d.cts +6 -2
  25. package/dist/lib/cjs/installer-asset.cjs +3 -9
  26. package/dist/lib/cjs/installer-compatibility.cjs +9 -12
  27. package/dist/lib/cjs/label-screenshot.cjs +63 -4
  28. package/dist/lib/cjs/label-screenshot.d.cts +66 -2
  29. package/dist/lib/cjs/leftover-cleanup.cjs +2 -5
  30. package/dist/lib/cjs/library.cjs +1 -1
  31. package/dist/lib/cjs/mobile-input.cjs +17 -31
  32. package/dist/lib/cjs/namespace-bootstrap.cjs +3 -9
  33. package/dist/lib/cjs/obsidian-executable.cjs +2 -5
  34. package/dist/lib/cjs/obsidian-installer.cjs +3 -9
  35. package/dist/lib/cjs/obsidian-instance.cjs +1 -1
  36. package/dist/lib/cjs/obsidian-instance.d.cts +8 -0
  37. package/dist/lib/cjs/owned-instance-exit-marker.cjs +2 -5
  38. package/dist/lib/cjs/owned-instance-exited-error.cjs +13 -17
  39. package/dist/lib/cjs/process-exit-message.cjs +3 -9
  40. package/dist/lib/cjs/renderer-boot-detection.cjs +3 -9
  41. package/dist/lib/cjs/setup-lock.cjs +3 -9
  42. package/dist/lib/cjs/sharp-loader.cjs +1 -1
  43. package/dist/lib/cjs/sharp-loader.d.cts +11 -0
  44. package/dist/lib/cjs/soft-keyboard-geometry.cjs +4 -9
  45. package/dist/lib/cjs/stale-build-detection.cjs +115 -0
  46. package/dist/lib/cjs/stale-build-detection.d.cts +108 -0
  47. package/dist/lib/cjs/stale-build-error.cjs +74 -0
  48. package/dist/lib/cjs/stale-build-error.d.cts +81 -0
  49. package/dist/lib/cjs/strict-proxy.cjs +3 -9
  50. package/dist/lib/cjs/transport-appium.cjs +3 -9
  51. package/dist/lib/cjs/transport-desktop-cdp.cjs +18 -32
  52. package/dist/lib/cjs/transport-factory.cjs +20 -25
  53. package/dist/lib/cjs/transport-options.cjs +2 -5
  54. package/dist/lib/cjs/transport-options.d.cts +36 -0
  55. package/dist/lib/cjs/vault-teardown-verdict.cjs +2 -5
  56. package/dist/lib/cjs/version-matrix.cjs +4 -13
  57. package/dist/lib/cjs/wedged-appium-server.cjs +3 -9
  58. package/dist/lib/esm/appium-dependencies.mjs +2 -5
  59. package/dist/lib/esm/appium-server-marker.mjs +3 -9
  60. package/dist/lib/esm/asar-fallback-detection.mjs +2 -5
  61. package/dist/lib/esm/avd-probe-verdict.mjs +3 -9
  62. package/dist/lib/esm/capture-obsidian-screenshot.d.mts +21 -0
  63. package/dist/lib/esm/capture-obsidian-screenshot.mjs +9 -1
  64. package/dist/lib/esm/capture-screenshot.mjs +2 -5
  65. package/dist/lib/esm/cli.mjs +2 -5
  66. package/dist/lib/esm/demo-vault-populate.mjs +7 -9
  67. package/dist/lib/esm/device-setting-restore.mjs +2 -5
  68. package/dist/lib/esm/electron-compatibility.mjs +8 -11
  69. package/dist/lib/esm/emulator-arguments.mjs +14 -14
  70. package/dist/lib/esm/emulator-marker.mjs +4 -13
  71. package/dist/lib/esm/emulator-reaper.mjs +2 -5
  72. package/dist/lib/esm/emulator-snapshot.mjs +3 -9
  73. package/dist/lib/esm/eval-cap-exceeded-error.mjs +2 -5
  74. package/dist/lib/esm/exec.mjs +12 -24
  75. package/dist/lib/esm/function-expression.mjs +2 -5
  76. package/dist/lib/esm/global-setup-core.mjs +60 -19
  77. package/dist/lib/esm/hide-vault-name.d.mts +67 -0
  78. package/dist/lib/esm/hide-vault-name.mjs +21 -0
  79. package/dist/lib/esm/index.d.mts +6 -2
  80. package/dist/lib/esm/index.mjs +8 -2
  81. package/dist/lib/esm/installer-asset.mjs +3 -9
  82. package/dist/lib/esm/installer-compatibility.mjs +9 -12
  83. package/dist/lib/esm/label-screenshot.d.mts +66 -2
  84. package/dist/lib/esm/label-screenshot.mjs +61 -3
  85. package/dist/lib/esm/leftover-cleanup.mjs +2 -5
  86. package/dist/lib/esm/library.mjs +1 -1
  87. package/dist/lib/esm/mobile-input.mjs +17 -31
  88. package/dist/lib/esm/namespace-bootstrap.mjs +3 -9
  89. package/dist/lib/esm/obsidian-executable.mjs +2 -5
  90. package/dist/lib/esm/obsidian-installer.mjs +3 -9
  91. package/dist/lib/esm/obsidian-instance.d.mts +8 -0
  92. package/dist/lib/esm/obsidian-instance.mjs +1 -1
  93. package/dist/lib/esm/owned-instance-exit-marker.mjs +2 -5
  94. package/dist/lib/esm/owned-instance-exited-error.mjs +13 -17
  95. package/dist/lib/esm/process-exit-message.mjs +3 -9
  96. package/dist/lib/esm/renderer-boot-detection.mjs +3 -9
  97. package/dist/lib/esm/setup-lock.mjs +3 -9
  98. package/dist/lib/esm/sharp-loader.d.mts +11 -0
  99. package/dist/lib/esm/sharp-loader.mjs +1 -1
  100. package/dist/lib/esm/soft-keyboard-geometry.mjs +4 -9
  101. package/dist/lib/esm/stale-build-detection.d.mts +108 -0
  102. package/dist/lib/esm/stale-build-detection.mjs +84 -0
  103. package/dist/lib/esm/stale-build-error.d.mts +81 -0
  104. package/dist/lib/esm/stale-build-error.mjs +50 -0
  105. package/dist/lib/esm/strict-proxy.mjs +3 -9
  106. package/dist/lib/esm/transport-appium.mjs +3 -9
  107. package/dist/lib/esm/transport-desktop-cdp.mjs +18 -32
  108. package/dist/lib/esm/transport-factory.mjs +20 -25
  109. package/dist/lib/esm/transport-options.d.mts +36 -0
  110. package/dist/lib/esm/transport-options.mjs +2 -5
  111. package/dist/lib/esm/vault-teardown-verdict.mjs +2 -5
  112. package/dist/lib/esm/version-matrix.mjs +4 -13
  113. package/dist/lib/esm/wedged-appium-server.mjs +3 -9
  114. package/package.json +20 -19
@@ -8,7 +8,9 @@ import {
8
8
  } from "node:fs/promises";
9
9
  import {
10
10
  basename,
11
- join
11
+ join,
12
+ relative,
13
+ sep
12
14
  } from "node:path";
13
15
  import process, { loadEnvFile } from "node:process";
14
16
  import { setTimeout as sleep } from "node:timers/promises";
@@ -37,6 +39,12 @@ import {
37
39
  acquireSetupLock,
38
40
  ANDROID_SETUP_LOCK_SCOPE
39
41
  } from "./setup-lock.mjs";
42
+ import {
43
+ checkIsBuildStale,
44
+ findNewestSourceModification,
45
+ willFailOnStaleBuild
46
+ } from "./stale-build-detection.mjs";
47
+ import { StaleBuildError } from "./stale-build-error.mjs";
40
48
  import { TemporaryVault } from "./temporary-vault.mjs";
41
49
  import { AppiumTransport } from "./transport-appium.mjs";
42
50
  import { DesktopCdpTransport } from "./transport-desktop-cdp.mjs";
@@ -64,6 +72,7 @@ async function coreSetup(params) {
64
72
  const label = transportOptions.type;
65
73
  const shouldInstallPlugin = params?.installPlugin !== false;
66
74
  await skipIfDesktopOnly({ label, projectRoot, shouldInstallPlugin, transportOptions });
75
+ await assertBuildIsFresh({ label, projectRoot, shouldInstallPlugin, transportOptions });
67
76
  const lockScope = getLockScope(transportOptions);
68
77
  let lock;
69
78
  if (lockScope !== void 0) {
@@ -172,15 +181,45 @@ function remapConfigDirectoryKeys(populate, configDirectory) {
172
181
  return remapped;
173
182
  }
174
183
  function resolveIntegrationTransportOptions(options) {
175
- if (options?.type === "obsidian-android-appium") {
176
- return options;
177
- }
178
- return {
184
+ return options?.type === "obsidian-android-appium" ? options : {
179
185
  ...options,
180
186
  isObsidianAppVisible: options?.isObsidianAppVisible ?? false,
181
187
  type: "obsidian-cdp"
182
188
  };
183
189
  }
190
+ async function assertBuildIsFresh(params) {
191
+ const { label, projectRoot, shouldInstallPlugin, transportOptions } = params;
192
+ if (!shouldInstallPlugin) {
193
+ return;
194
+ }
195
+ let distPath;
196
+ let buildModifiedAtInMilliseconds;
197
+ try {
198
+ distPath = await resolveDistPath(projectRoot);
199
+ const buildStat = await stat(join(distPath, MAIN_JS));
200
+ buildModifiedAtInMilliseconds = buildStat.mtimeMs;
201
+ } catch {
202
+ return;
203
+ }
204
+ const newestSource = await findNewestSourceModification(projectRoot);
205
+ const relativeDistPath = relative(projectRoot, distPath).split(sep).join("/");
206
+ if (!newestSource || !checkIsBuildStale({ buildModifiedAtInMilliseconds, newestSource })) {
207
+ log(
208
+ `[integration-setup:${label}] Build is fresh: ${relativeDistPath}/${MAIN_JS} (${new Date(buildModifiedAtInMilliseconds).toISOString()}) is not older than ${newestSource ? `${newestSource.path} (${new Date(newestSource.modifiedAtInMilliseconds).toISOString()}).` : "any source \u2014 this project has none under src/, so freshness was not provable."}`
209
+ );
210
+ return;
211
+ }
212
+ const error = new StaleBuildError({
213
+ buildModifiedAtInMilliseconds,
214
+ distPath: relativeDistPath,
215
+ sourceModifiedAtInMilliseconds: newestSource.modifiedAtInMilliseconds,
216
+ sourcePath: newestSource.path
217
+ });
218
+ if (willFailOnStaleBuild(transportOptions)) {
219
+ throw error;
220
+ }
221
+ log(`[integration-setup:${label}] WARNING: ${error.description} Continuing anyway \u2014 the stale-build failure is switched off.`);
222
+ }
184
223
  function augmentTransportOptions(options, transport) {
185
224
  if (options?.type === "obsidian-android-appium" && transport instanceof AppiumTransport) {
186
225
  const sessionInfo = transport.getSessionInfo();
@@ -216,7 +255,7 @@ async function copyPluginIntoVault(params) {
216
255
  }
217
256
  const mainJs = join(distPath, MAIN_JS);
218
257
  const buildStat = await stat(mainJs);
219
- log(`[integration-setup:${label}] Using ${distPath} (${buildStat.mtime.toISOString()}). If outdated, rebuild.`);
258
+ log(`[integration-setup:${label}] Using ${distPath} (${buildStat.mtime.toISOString()}).`);
220
259
  await installPluginIntoVault({ configDirectory, distPath, pluginId, vaultPath: temporaryVault.path });
221
260
  log(`[integration-setup:${label}] Installed "${pluginId}" into ${configDirectory ?? DEFAULT_CONFIG_DIRECTORY}/plugins (and enabled it there).`);
222
261
  return pluginId;
@@ -246,11 +285,11 @@ async function enablePluginInVault(params) {
246
285
  });
247
286
  } catch (error) {
248
287
  if (attempt < maxAttempts) {
249
- const delayInMilliseconds = computeBackoffDelayInMilliseconds(baseDelayInMilliseconds, attempt - 1);
288
+ const delayInMilliseconds2 = computeBackoffDelayInMilliseconds(baseDelayInMilliseconds, attempt - 1);
250
289
  log(
251
- `[integration-setup:${label}] Enable attempt ${String(attempt)}/${String(maxAttempts)} threw (${errorToString(error)}); retrying in ${String(delayInMilliseconds)}ms...`
290
+ `[integration-setup:${label}] Enable attempt ${String(attempt)}/${String(maxAttempts)} threw (${errorToString(error)}); retrying in ${String(delayInMilliseconds2)}ms...`
252
291
  );
253
- await sleep(delayInMilliseconds);
292
+ await sleep(delayInMilliseconds2);
254
293
  continue;
255
294
  }
256
295
  throw error;
@@ -264,13 +303,14 @@ async function enablePluginInVault(params) {
264
303
  if (!shouldRetryPluginEnable(result)) {
265
304
  throw new Error(`Plugin "${pluginId}" failed to load: ${realError ?? getGenericPluginLoadFailureMessage(pluginId)}`);
266
305
  }
267
- if (attempt < maxAttempts) {
268
- const delayInMilliseconds = computeBackoffDelayInMilliseconds(baseDelayInMilliseconds, attempt - 1);
269
- log(
270
- `[integration-setup:${label}] Plugin "${pluginId}" enabled but not loaded (attempt ${String(attempt)}/${String(maxAttempts)}); retrying in ${String(delayInMilliseconds)}ms...`
271
- );
272
- await sleep(delayInMilliseconds);
306
+ if (attempt >= maxAttempts) {
307
+ continue;
273
308
  }
309
+ const delayInMilliseconds = computeBackoffDelayInMilliseconds(baseDelayInMilliseconds, attempt - 1);
310
+ log(
311
+ `[integration-setup:${label}] Plugin "${pluginId}" enabled but not loaded (attempt ${String(attempt)}/${String(maxAttempts)}); retrying in ${String(delayInMilliseconds)}ms...`
312
+ );
313
+ await sleep(delayInMilliseconds);
274
314
  }
275
315
  const logcatTail = await transport.readConsoleCaptureSince?.(captureHandle);
276
316
  const detail = logcatTail ?? getGenericPluginLoadFailureMessage(pluginId);
@@ -342,10 +382,11 @@ function registerProcessCleanupHandler() {
342
382
  }
343
383
  function releaseSetupLock(result) {
344
384
  const lock = setupLocks.get(result);
345
- if (lock) {
346
- lock.release();
347
- setupLocks.delete(result);
385
+ if (!lock) {
386
+ return;
348
387
  }
388
+ lock.release();
389
+ setupLocks.delete(result);
349
390
  }
350
391
  async function resolveDistPath(projectRoot) {
351
392
  const devPath = join(projectRoot, DIST_DEV);
@@ -422,4 +463,4 @@ export {
422
463
  remapConfigDirectoryKeys,
423
464
  resolveIntegrationTransportOptions
424
465
  };
425
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2dsb2JhbC1zZXR1cC1jb3JlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogRnJhbWV3b3JrLWFnbm9zdGljIGNvcmUgbG9naWMgZm9yIGludGVncmF0aW9uIHRlc3QgZ2xvYmFsIHNldHVwIGFuZCB0ZWFyZG93bi5cbiAqXG4gKiBWaXRlc3QgYW5kIEplc3QgYWRhcHRlcnMgZGVsZWdhdGUgdG8gdGhlc2UgZnVuY3Rpb25zLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIHNldHVwIGNvdmVyZWQgYnkgaW50ZWdyYXRpb24gdGVzdHMsIG5vdCB1bml0IHRlc3RzLiAqL1xuXG5pbXBvcnQgdHlwZSB7IFBsdWdpbk1hbmlmZXN0IH0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQge1xuICBleGlzdHNTeW5jLFxuICBybVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICByZWFkRmlsZSxcbiAgc3RhdFxufSBmcm9tICdub2RlOmZzL3Byb21pc2VzJztcbmltcG9ydCB7XG4gIGJhc2VuYW1lLFxuICBqb2luXG59IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgcHJvY2VzcywgeyBsb2FkRW52RmlsZSB9IGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5pbXBvcnQgeyBzZXRUaW1lb3V0IGFzIHNsZWVwIH0gZnJvbSAnbm9kZTp0aW1lcnMvcHJvbWlzZXMnO1xuXG5pbXBvcnQgdHlwZSB7IEVuYWJsZVBsdWdpblJlc3VsdCB9IGZyb20gJy4vZW5hYmxlLXBsdWdpbi5tanMnO1xuaW1wb3J0IHR5cGUgeyBTZXR1cExvY2sgfSBmcm9tICcuL3NldHVwLWxvY2subWpzJztcbmltcG9ydCB0eXBlIHsgUG9wdWxhdGVGaWxlc1BhcmFtcyB9IGZyb20gJy4vdGVtcG9yYXJ5LXZhdWx0Lm1qcyc7XG5pbXBvcnQgdHlwZSB7IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB9IGZyb20gJy4vdHJhbnNwb3J0LW9wdGlvbnMubWpzJztcbmltcG9ydCB0eXBlIHsgT2JzaWRpYW5UcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydC5tanMnO1xuXG5pbXBvcnQgeyBERUZBVUxUX0NPTkZJR19ESVJFQ1RPUlkgfSBmcm9tICcuL2NvbmZpZy1kaXJlY3RvcnkubWpzJztcbmltcG9ydCB7IERlc2t0b3BPbmx5UGx1Z2luU2tpcEVycm9yIH0gZnJvbSAnLi9kZXNrdG9wLW9ubHktcGx1Z2luLXNraXAtZXJyb3IubWpzJztcbmltcG9ydCB7XG4gIGVuYWJsZVBsdWdpbldpdGhFcnJvckNhcHR1cmUsXG4gIGdldEdlbmVyaWNQbHVnaW5Mb2FkRmFpbHVyZU1lc3NhZ2Vcbn0gZnJvbSAnLi9lbmFibGUtcGx1Z2luLm1qcyc7XG5pbXBvcnQgeyBlcnJvclRvU3RyaW5nIH0gZnJvbSAnLi9lcnJvci10by1zdHJpbmcubWpzJztcbmltcG9ydCB7IGV2YWxJbk9ic2lkaWFuIH0gZnJvbSAnLi9ldmFsLWluLW9ic2lkaWFuLm1qcyc7XG5pbXBvcnQgeyBlbnN1cmVIZWFkbGVzc1ZhdWx0Q29uZmlnIH0gZnJvbSAnLi9oZWFkbGVzcy12YXVsdC1jb25maWcubWpzJztcbmltcG9ydCB7XG4gIHJlc29sdmVMZWZ0b3Zlck1heEFnZUluTWlsbGlzZWNvbmRzLFxuICBzd2VlcEhvc3RMZWZ0b3ZlcnMsXG4gIHdpbGxTd2VlcExlZnRvdmVyc1xufSBmcm9tICcuL2xlZnRvdmVyLWNsZWFudXAubWpzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLm1qcyc7XG5pbXBvcnQge1xuICBjb21wdXRlQmFja29mZkRlbGF5SW5NaWxsaXNlY29uZHMsXG4gIHJlc29sdmVQbHVnaW5FbmFibGVSZXRyeUNvdW50LFxuICByZXNvbHZlUGx1Z2luRW5hYmxlUmV0cnlEZWxheUluTWlsbGlzZWNvbmRzLFxuICBzaG91bGRSZXRyeVBsdWdpbkVuYWJsZVxufSBmcm9tICcuL3BsdWdpbi1lbmFibGUtcmV0cnkubWpzJztcbmltcG9ydCB7XG4gIGFjcXVpcmVTZXR1cExvY2ssXG4gIEFORFJPSURfU0VUVVBfTE9DS19TQ09QRVxufSBmcm9tICcuL3NldHVwLWxvY2subWpzJztcbmltcG9ydCB7IFRlbXBvcmFyeVZhdWx0IH0gZnJvbSAnLi90ZW1wb3JhcnktdmF1bHQubWpzJztcbmltcG9ydCB7IEFwcGl1bVRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWFwcGl1bS5tanMnO1xuaW1wb3J0IHsgRGVza3RvcENkcFRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWRlc2t0b3AtY2RwLm1qcyc7XG5pbXBvcnQgeyBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9ucyB9IGZyb20gJy4vdHJhbnNwb3J0LWZhY3RvcnkubWpzJztcbmltcG9ydCB7XG4gIGNoZWNrSXNNb2JpbGVUcmFuc3BvcnQsXG4gIHJlc29sdmVPd25lZENvbmZpZ0RpcmVjdG9yeVxufSBmcm9tICcuL3RyYW5zcG9ydC1vcHRpb25zLm1qcyc7XG5pbXBvcnQgeyBpbnN0YWxsUGx1Z2luSW50b1ZhdWx0IH0gZnJvbSAnLi92YXVsdC1wbHVnaW4taW5zdGFsbC5tanMnO1xuXG5jb25zdCBERUZBVUxUX1RSQU5TUE9SVF9UWVBFID0gJ29ic2lkaWFuLWNkcCc7XG5jb25zdCBESVNUX0RFViA9ICdkaXN0L2Rldic7XG5jb25zdCBESVNUX0JVSUxEID0gJ2Rpc3QvYnVpbGQnO1xuY29uc3QgTUFJTl9KUyA9ICdtYWluLmpzJztcblxuLyoqXG4gKiBUcmFja3Mgc2V0dXBzIHRoYXQgY29tcGxldGVkIHN1Y2Nlc3NmdWxseSBidXQgaGF2ZW4ndCBiZWVuIHRvcm4gZG93biB5ZXQuXG4gKiBVc2VkIGJ5IHRoZSBgYmVmb3JlRXhpdGAgaGFuZGxlciB0byBjbGVhbiB1cCB3aGVuIGEgdGVzdCBydW5uZXIgZXhpdHNcbiAqIHdpdGhvdXQgY2FsbGluZyB0ZWFyZG93biAoZS5nLiwgd2hlbiBvbmUgcHJvamVjdCdzIHNldHVwIGZhaWxzIGFuZCB0aGVcbiAqIHJ1bm5lciBhYm9ydHMgYmVmb3JlIHRlYXJpbmcgZG93biBhbHJlYWR5LWluaXRpYWxpemVkIHByb2plY3RzKS5cbiAqL1xuY29uc3QgYWN0aXZlU2V0dXBzID0gbmV3IFNldDxDb3JlU2V0dXBSZXN1bHQ+KCk7XG5jb25zdCBkaXNwb3NlZFJlc3VsdHMgPSBuZXcgV2Vha1NldDxDb3JlU2V0dXBSZXN1bHQ+KCk7XG5sZXQgaXNDbGVhbnVwSGFuZGxlclJlZ2lzdGVyZWQgPSBmYWxzZTtcblxuLyoqXG4gKiBUaGUgY3Jvc3MtcHJvY2VzcyBzZXR1cCBsb2NrIGhlbGQgYnkgZWFjaCBhY3RpdmUgc2V0dXAuIFJlbGVhc2VkIHdoZW4gdGhlXG4gKiBzZXR1cCBpcyB0b3JuIGRvd24gKG9yIGJ5IHRoZSBwcm9jZXNzIGNsZWFudXAgaGFuZGxlcnMpLCBhbGxvd2luZyBhIGNvbXBldGluZ1xuICogcnVuIHRvIHByb2NlZWQuIFNlZSB7QGxpbmsgYWNxdWlyZVNldHVwTG9ja30uXG4gKi9cbmNvbnN0IHNldHVwTG9ja3MgPSBuZXcgTWFwPENvcmVTZXR1cFJlc3VsdCwgU2V0dXBMb2NrPigpO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBjb3JlU2V0dXB9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvcmVTZXR1cE9wdGlvbnMge1xuICAvKipcbiAgICogQ29tbXVuaXR5LXBsdWdpbiBpZHMgdG8gZW5hYmxlIGluIHRoZSB2YXVsdCAqKmluIGFkZGl0aW9uIHRvKiogdGhlXG4gICAqIHBsdWdpbi11bmRlci10ZXN0LCBhZnRlciBpdCBpcyBlbmFibGVkLiBFYWNoIGlkJ3MgYnVpbHQgZmlsZXMgbXVzdCBhbHJlYWR5IGJlXG4gICAqIHByZXNlbnQgdW5kZXIgYC5vYnNpZGlhbi9wbHVnaW5zLzxpZD4vYCBcdTIwMTQgc2VlZCB0aGVtIHZpYSB7QGxpbmsgQ29yZVNldHVwT3B0aW9ucy5wb3B1bGF0ZX1cbiAgICogKGUuZy4gd2l0aCBgYnVpbGREZW1vVmF1bHRQb3B1bGF0ZWApLiBFbmFibGluZyBnb2VzIHRocm91Z2ggdGhlIHNhbWVcbiAgICogcmV0cnkvbG9hZC12ZXJpZnkgcGF0aCBhcyB0aGUgcGx1Z2luLXVuZGVyLXRlc3QuIENvbXBvc2VzIHdpdGhcbiAgICogYGluc3RhbGxQbHVnaW46IGZhbHNlYCAoZW5hYmxlIGV4dHJhcyBpbnRvIGFuIG90aGVyd2lzZSBwbHVnaW4tbGVzcyB2YXVsdCkuXG4gICAqL1xuICByZWFkb25seSBlbmFibGVDb21tdW5pdHlQbHVnaW5zPzogcmVhZG9ubHkgc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gaW5zdGFsbCBhbmQgZW5hYmxlIHRoZSBidWlsdCBwbHVnaW4gaW4gdGhlIHRlbXAgdmF1bHQuIERlZmF1bHRzXG4gICAqIHRvIGB0cnVlYC4gU2V0IHRvIGBmYWxzZWAgZm9yIGEgKipub24tcGx1Z2luKiogY29uc3VtZXIgKGUuZy4gYSB0eXBpbmdzXG4gICAqIGNyYXdsZXIpIHRoYXQgb25seSBuZWVkcyBhIHJlZ2lzdGVyZWQsIGVtcHR5IHZhdWx0IHRvIGBldmFsSW5PYnNpZGlhbmBcbiAgICogYWdhaW5zdDogdGhlIHBsdWdpbiBgZGlzdGAvYG1hbmlmZXN0Lmpzb25gIHJlYWQsIHRoZSBjb3B5IGludG8gdGhlIGNvbmZpZ1xuICAgKiBmb2xkZXIncyBgcGx1Z2lucy9gLCB0aGUgYGNvbW11bml0eS1wbHVnaW5zLmpzb25gIHdyaXRlLCBhbmQgdGhlIGVuYWJsZSBzdGVwXG4gICAqIGFyZSBhbGwgc2tpcHBlZCwgd2hpbGUgdGhlIHRyYW5zcG9ydCwgdGVtcCB2YXVsdCwgcmVnaXN0cmF0aW9uLCBhbmRcbiAgICogd29ya2VyLWZhY2luZyBlbmRwb2ludCBwcm92aXNpb25pbmcgc3RpbGwgcnVuIHVuY2hhbmdlZC5cbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbGxQbHVnaW4/OiBib29sZWFuIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBGaWxlcyBhbmQgZm9sZGVycyB0byB3cml0ZSBpbnRvIHRoZSB2YXVsdCAqKmJlZm9yZSoqIE9ic2lkaWFuIG9wZW5zIGl0LCBzb1xuICAgKiBpdHMgc3RhcnR1cCBzY2FuIGluZGV4ZXMgdGhlbSBpbiBvbmUgcGFzcyAoc2VlIHtAbGluayBUZW1wb3JhcnlWYXVsdC5wb3B1bGF0ZX0pLlxuICAgKiBVc2UgdGhpcyBmb3IgbGFyZ2UgZml4dHVyZXMgXHUyMDE0IHdyaXRpbmcgdGhvdXNhbmRzIG9mIG5vdGVzIGFmdGVyIG9wZW4gYW5kXG4gICAqIGZvcmNpbmcgYSByZS1zY2FuIGlzIGZhciBzbG93ZXIgYW5kIGxlc3MgcmVsaWFibGUuXG4gICAqXG4gICAqIEtleXMgbmFtaW5nIHRoZSBjb25maWcgZm9sZGVyIGFyZSB3cml0dGVuIGFzIGAub2JzaWRpYW4vXHUyMDI2YDsgdW5kZXIgYVxuICAgKiBgY29uZmlnRGlyZWN0b3J5YCBvdmVycmlkZSB7QGxpbmsgcmVtYXBDb25maWdEaXJlY3RvcnlLZXlzfSByZWRpcmVjdHMgdGhlbSB0b1xuICAgKiB0aGUgZm9sZGVyIHRoZSB2YXVsdCB3aWxsIGFjdHVhbGx5IHJlYWQsIHNvIGEgbWFwIGRvZXMgbm90IGhhdmUgdG8gY2FycnkgYVxuICAgKiBzZWNvbmQgY29weSBvZiB0aGUgb3ZlcnJpZGUuXG4gICAqL1xuICByZWFkb25seSBwb3B1bGF0ZT86IFBvcHVsYXRlRmlsZXNQYXJhbXMgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRyYW5zcG9ydCBvcHRpb25zLiBXaGVuIG9taXR0ZWQsIHVzZXMgYW4gb2ZmLXNjcmVlbiBvd25lZCBkZXNrdG9wIGluc3RhbmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0T3B0aW9ucz86IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZXN1bHQgcmV0dXJuZWQgYnkge0BsaW5rIGNvcmVTZXR1cH0sIHVzZWQgYnkgZnJhbWV3b3JrIGFkYXB0ZXJzXG4gKiB0byBwYXNzIGNvbnRleHQgdG8gdGVzdCB3b3JrZXJzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvcmVTZXR1cFJlc3VsdCB7XG4gIC8qKlxuICBUaGUgdGVtcG9yYXJ5IHZhdWx0IGNyZWF0ZWQgZHVyaW5nIHNldHVwLlxuICAgKi9cbiAgcmVhZG9ubHkgdGVtcG9yYXJ5VmF1bHQ6IFRlbXBvcmFyeVZhdWx0O1xuXG4gIC8qKlxuICBUaGUgdHJhbnNwb3J0IGluc3RhbmNlIHVzZWQgZHVyaW5nIHNldHVwLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydDtcblxuICAvKipcbiAgU2hvcnQgbGFiZWwgZm9yIGxvZyBtZXNzYWdlcyAoZS5nLiBgXCJvYnNpZGlhbi1jZHBcImApLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0TGFiZWw6IHN0cmluZztcblxuICAvKipcbiAgVGhlIHRyYW5zcG9ydCBvcHRpb25zIHRoYXQgd2VyZSByZXNvbHZlZC5cbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydE9wdGlvbnM6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgY29weVBsdWdpbkludG9WYXVsdH0uXG4gKi9cbmludGVyZmFjZSBDb3B5UGx1Z2luSW50b1ZhdWx0UGFyYW1zIHtcbiAgLyoqXG4gIFRoZSBjb25maWcgZm9sZGVyIHRoZSB2YXVsdCB3aWxsIHJlYWQsIHdoZW4gb3ZlcnJpZGRlbiBhd2F5IGZyb20gYC5vYnNpZGlhbmAgXHUyMDE0IHRoZSByZXNvbHZlZFxuICB7QGxpbmsgcmVzb2x2ZU93bmVkQ29uZmlnRGlyZWN0b3J5fSB2YWx1ZSwgd2hpY2ggaXMgYHVuZGVmaW5lZGAgZm9yIE9ic2lkaWFuJ3Mgb3duIGRlZmF1bHQuXG4gICAqL1xuICByZWFkb25seSBjb25maWdEaXJlY3Rvcnk6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgU2hvcnQgbGFiZWwgZm9yIGxvZyBtZXNzYWdlcy5cbiAgICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBwcm9qZWN0IHJvb3QgdG8gcmVzb2x2ZSB0aGUgYnVpbHQgcGx1Z2luIGZyb20uXG4gICAqL1xuICByZWFkb25seSBwcm9qZWN0Um9vdDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgdGVtcCB2YXVsdCB0byBjb3B5IHRoZSBwbHVnaW4gaW50by5cbiAgICovXG4gIHJlYWRvbmx5IHRlbXBvcmFyeVZhdWx0OiBUZW1wb3JhcnlWYXVsdDtcblxuICAvKipcbiAgVGhlIHRyYW5zcG9ydCAodXNlZCBmb3IgdGhlIG1vYmlsZS9kZXNrdG9wLW9ubHkgY29tcGF0aWJpbGl0eSBjaGVjaykuXG4gICAqL1xuICByZWFkb25seSB0cmFuc3BvcnQ6IE9ic2lkaWFuVHJhbnNwb3J0O1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBlbmFibGVFeHRyYUNvbW11bml0eVBsdWdpbnN9LlxuICovXG5pbnRlcmZhY2UgRW5hYmxlRXh0cmFDb21tdW5pdHlQbHVnaW5zUGFyYW1zIHtcbiAgLyoqXG4gIFNob3J0IGxhYmVsIGZvciBsb2cgbWVzc2FnZXMuXG4gICAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgaWRzIG9mIHRoZSBleHRyYSBjb21tdW5pdHkgcGx1Z2lucyB0byBlbmFibGUgKHRoZWlyIGJpbmFyaWVzIG11c3QgYWxyZWFkeSBiZSBpbiB0aGUgdmF1bHQpLlxuICAgKi9cbiAgcmVhZG9ubHkgcGx1Z2luSWRzOiByZWFkb25seSBzdHJpbmdbXTtcblxuICAvKipcbiAgVGhlIHRlbXAgdmF1bHQgdGhlIHBsdWdpbnMgd2VyZSBzZWVkZWQgaW50by5cbiAgICovXG4gIHJlYWRvbmx5IHRlbXBvcmFyeVZhdWx0OiBUZW1wb3JhcnlWYXVsdDtcblxuICAvKipcbiAgVGhlIHRyYW5zcG9ydCB0byBldmFsdWF0ZSBhZ2FpbnN0LlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydDtcblxuICAvKipcbiAgVGhlIHJlc29sdmVkIHRyYW5zcG9ydCBvcHRpb25zIChzb3VyY2Ugb2YgdGhlIHBsdWdpbi1lbmFibGUgcmV0cnkga25vYnMpLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0T3B0aW9uczogbnVsbCB8IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgZW5hYmxlUGx1Z2luSW5WYXVsdH0uXG4gKi9cbmludGVyZmFjZSBFbmFibGVQbHVnaW5JblZhdWx0UGFyYW1zIHtcbiAgLyoqXG4gIFNob3J0IGxhYmVsIGZvciBsb2cgbWVzc2FnZXMuXG4gICAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgaWQgb2YgdGhlIHBsdWdpbiB0byBlbmFibGUuXG4gICAqL1xuICByZWFkb25seSBwbHVnaW5JZDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgdGVtcCB2YXVsdCB0aGUgcGx1Z2luIHdhcyBjb3BpZWQgaW50by5cbiAgICovXG4gIHJlYWRvbmx5IHRlbXBvcmFyeVZhdWx0OiBUZW1wb3JhcnlWYXVsdDtcblxuICAvKipcbiAgVGhlIHRyYW5zcG9ydCB0byBldmFsdWF0ZSBhZ2FpbnN0LlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydDtcblxuICAvKipcbiAgVGhlIHJlc29sdmVkIHRyYW5zcG9ydCBvcHRpb25zIChzb3VyY2Ugb2YgdGhlIHBsdWdpbi1lbmFibGUgcmV0cnkga25vYnMpLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0T3B0aW9uczogbnVsbCB8IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgc2tpcElmRGVza3RvcE9ubHl9LlxuICovXG5pbnRlcmZhY2UgU2tpcElmRGVza3RvcE9ubHlQYXJhbXMge1xuICAvKipcbiAgU2hvcnQgbGFiZWwgZm9yIGxvZyBtZXNzYWdlcy5cbiAgICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBwcm9qZWN0IHJvb3QgdG8gcmVzb2x2ZSB0aGUgYnVpbHQgcGx1Z2luJ3MgbWFuaWZlc3QgZnJvbS5cbiAgICovXG4gIHJlYWRvbmx5IHByb2plY3RSb290OiBzdHJpbmc7XG5cbiAgLyoqXG4gIFdoZXRoZXIgYSBwbHVnaW4gaXMgYmVpbmcgaW5zdGFsbGVkIGF0IGFsbCAtLSB0aGVyZSBpcyBub3RoaW5nIHRvIGNoZWNrIHdoZW4gdGhlIHZhdWx0IHN0YXlzIGVtcHR5LlxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkSW5zdGFsbFBsdWdpbjogYm9vbGVhbjtcblxuICAvKipcbiAgVGhlIHJlc29sdmVkIHRyYW5zcG9ydCBvcHRpb25zLCB3aG9zZSBkaXNjcmltaW5hbnQgc2F5cyB3aGV0aGVyIHRoaXMgcnVuIGlzIG1vYmlsZS5cbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydE9wdGlvbnM6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgc3dlZXBMZWZ0b3ZlcnN9LlxuICovXG5pbnRlcmZhY2UgU3dlZXBMZWZ0b3ZlcnNQYXJhbXMge1xuICAvKipcbiAgRGlyZWN0b3J5IG5hbWVzIHRvIGtlZXAgcmVnYXJkbGVzcyBvZiBhZ2UgKGUuZy4gYSBjb25jdXJyZW50IHNldHVwJ3MgdmF1bHQpLlxuICAgKi9cbiAgcmVhZG9ubHkgZXhjbHVkZWROYW1lcz86IHJlYWRvbmx5IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBTaG9ydCBsYWJlbCBmb3IgbG9nIG1lc3NhZ2VzLlxuICAgKi9cbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblxuICAvKipcbiAgV2hpY2ggZW5kIG9mIHRoZSBydW4gaXMgc3dlZXBpbmcsIGZvciB0aGUgbG9nIHByZWZpeC5cbiAgICovXG4gIHJlYWRvbmx5IHBoYXNlOiAnc2V0dXAnIHwgJ3RlYXJkb3duJztcblxuICAvKipcbiAgVGhlIHJlc29sdmVkIHRyYW5zcG9ydCBvcHRpb25zIChzb3VyY2Ugb2YgdGhlIHN3ZWVwIGtub2JzKS5cbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydE9wdGlvbnM6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBGcmFtZXdvcmstYWdub3N0aWMgZ2xvYmFsIHNldHVwIGxvZ2ljLlxuICpcbiAqIExvYWRzIGAuZW52YCBmcm9tIHRoZSBwcm9qZWN0IHJvb3QsIGNyZWF0ZXMgYSB0cmFuc3BvcnQsIGNyZWF0ZXMgYW5kIHJlZ2lzdGVyc1xuICogYSB0ZW1wb3JhcnkgdmF1bHQgd2l0aCBPYnNpZGlhbiwgYW5kIFx1MjAxNCB1bmxlc3Mge0BsaW5rIENvcmVTZXR1cE9wdGlvbnMuaW5zdGFsbFBsdWdpbn1cbiAqIGlzIGBmYWxzZWAgXHUyMDE0IGNvcGllcyB0aGUgYnVpbHQgcGx1Z2luIGludG8gdGhlIHZhdWx0IGFuZCBlbmFibGVzIGl0LiBUaGVcbiAqIHBsdWdpbi1sZXNzIG1vZGUgc3RpbGwgbGF1bmNoZXMgdGhlIG93bmVkIGluc3RhbmNlIGFuZCBwdWJsaXNoZXMgaXRzXG4gKiB3b3JrZXItZmFjaW5nIGVuZHBvaW50LCBzbyBhIG5vbi1wbHVnaW4gY29uc3VtZXIgcmV1c2VzIHRoZSBzYW1lIGF0dGFjaCB3aXJpbmcuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFNldHVwIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyBUaGUgc2V0dXAgcmVzdWx0IGNvbnRhaW5pbmcgdGhlIHRlbXAgdmF1bHQsIHRyYW5zcG9ydCwgYW5kIHJlc29sdmVkIG9wdGlvbnMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb3JlU2V0dXAocGFyYW1zPzogQ29yZVNldHVwT3B0aW9ucyk6IFByb21pc2U8Q29yZVNldHVwUmVzdWx0PiB7XG4gIGNvbnN0IHByb2plY3RSb290ID0gZmluZFByb2plY3RSb290KCk7XG4gIGNvbnN0IGVudkZpbGVQYXRoID0gam9pbihwcm9qZWN0Um9vdCwgJy5lbnYnKTtcbiAgaWYgKGV4aXN0c1N5bmMoZW52RmlsZVBhdGgpKSB7XG4gICAgbG9hZEVudkZpbGUoZW52RmlsZVBhdGgpO1xuICB9XG5cbiAgY29uc3QgdHJhbnNwb3J0T3B0aW9ucyA9IHJlc29sdmVJbnRlZ3JhdGlvblRyYW5zcG9ydE9wdGlvbnMocGFyYW1zPy50cmFuc3BvcnRPcHRpb25zKTtcbiAgY29uc3QgbGFiZWwgPSB0cmFuc3BvcnRPcHRpb25zLnR5cGU7XG4gIGNvbnN0IHNob3VsZEluc3RhbGxQbHVnaW4gPSBwYXJhbXM/Lmluc3RhbGxQbHVnaW4gIT09IGZhbHNlO1xuXG4gIC8vIEJlZm9yZSB0aGUgbG9jaywgdGhlIHN3ZWVwIGFuZCBhYm92ZSBhbGwgdGhlIHRyYW5zcG9ydDogY3JlYXRpbmcgYSBtb2JpbGUgdHJhbnNwb3J0IGJvb3RzIHRoZSBBVkQgYW5kXG4gIC8vIGF1dG8tc3RhcnRzIEFwcGl1bSAofjcwIHMpIG9ubHkgdG8gcmVhY2ggdGhlIHNhbWUgY29uY2x1c2lvbiBmcm9tIGB0cmFuc3BvcnQuaXNNb2JpbGVgIGZ1cnRoZXIgZG93bi5cbiAgLy8gTmVpdGhlciBpbnB1dCBuZWVkcyBhIGRldmljZSAtLSB0aGUgbWFuaWZlc3QgaXMgb24gZGlzayBhbmQgdGhlIGRpc2NyaW1pbmFudCBhbHJlYWR5IHNheXMgbW9iaWxlLlxuICBhd2FpdCBza2lwSWZEZXNrdG9wT25seSh7IGxhYmVsLCBwcm9qZWN0Um9vdCwgc2hvdWxkSW5zdGFsbFBsdWdpbiwgdHJhbnNwb3J0T3B0aW9ucyB9KTtcblxuICBjb25zdCBsb2NrU2NvcGUgPSBnZXRMb2NrU2NvcGUodHJhbnNwb3J0T3B0aW9ucyk7XG5cbiAgbGV0IGxvY2s6IFNldHVwTG9jayB8IHVuZGVmaW5lZDtcbiAgaWYgKGxvY2tTY29wZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIEFjcXVpcmluZyAnJHtsb2NrU2NvcGV9JyBzZXR1cCBsb2NrIChzZXJpYWxpemVzIGFnYWluc3QgYW55IGNvbmN1cnJlbnQgaW50ZWdyYXRpb24tdGVzdCBydW4pLi4uYCk7XG4gICAgbG9jayA9IGF3YWl0IGFjcXVpcmVTZXR1cExvY2soeyBsYWJlbCwgc2NvcGU6IGxvY2tTY29wZSB9KTtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gU2V0dXAgbG9jayBhY3F1aXJlZC5gKTtcbiAgfVxuXG4gIGF3YWl0IHN3ZWVwTGVmdG92ZXJzKHsgbGFiZWwsIHBoYXNlOiAnc2V0dXAnLCB0cmFuc3BvcnRPcHRpb25zIH0pO1xuXG4gIGxldCB0cmFuc3BvcnQ6IE9ic2lkaWFuVHJhbnNwb3J0IHwgdW5kZWZpbmVkO1xuICBsZXQgdGVtcG9yYXJ5VmF1bHQ6IFRlbXBvcmFyeVZhdWx0IHwgdW5kZWZpbmVkO1xuXG4gIHRyeSB7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIENyZWF0aW5nIHRyYW5zcG9ydC4uLmApO1xuICAgIHRyYW5zcG9ydCA9IGF3YWl0IGNyZWF0ZVRyYW5zcG9ydEZyb21PcHRpb25zKHRyYW5zcG9ydE9wdGlvbnMpO1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBUcmFuc3BvcnQgY3JlYXRlZDogJHt0cmFuc3BvcnQuY29uc3RydWN0b3IubmFtZX1gKTtcblxuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBQcm9qZWN0IHJvb3Q6ICR7cHJvamVjdFJvb3R9YCk7XG5cbiAgICB0ZW1wb3JhcnlWYXVsdCA9IG5ldyBUZW1wb3JhcnlWYXVsdCgpO1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBDcmVhdGVkIHRlbXAgdmF1bHQ6ICR7dGVtcG9yYXJ5VmF1bHQucGF0aH1gKTtcblxuICAgIC8qXG4gICAgICogV2hpY2ggZm9sZGVyIHRoaXMgdmF1bHQgd2lsbCBhY3R1YWxseSByZWFkLCByZXNvbHZlZCBvbmNlIGFuZCBoYW5kZWQgdG8gZXZlcnkgd3JpdGVyIGJlbG93LlxuICAgICAqIEV2ZXJ5IHByZS1vcGVuIHdyaXRlIGhhcyB0byBhZ3JlZSBvbiBpdDogb25lIHRoYXQgaGFyZGNvZGVzIGAub2JzaWRpYW5gIHVuZGVyIGFuIG92ZXJyaWRlIHdyaXRlc1xuICAgICAqIHNvbWV3aGVyZSBub3RoaW5nIGxvb2tzLCBhbmQgbm90aGluZyB0aHJvd3MgdG8gc2F5IHNvLlxuICAgICAqL1xuICAgIGNvbnN0IGNvbmZpZ0RpcmVjdG9yeSA9IHJlc29sdmVPd25lZENvbmZpZ0RpcmVjdG9yeSh0cmFuc3BvcnRPcHRpb25zKTtcblxuICAgIGxldCBwbHVnaW5JZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgaWYgKHNob3VsZEluc3RhbGxQbHVnaW4pIHtcbiAgICAgIHBsdWdpbklkID0gYXdhaXQgY29weVBsdWdpbkludG9WYXVsdCh7IGNvbmZpZ0RpcmVjdG9yeSwgbGFiZWwsIHByb2plY3RSb290LCB0ZW1wb3JhcnlWYXVsdCwgdHJhbnNwb3J0IH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gU2tpcHBpbmcgcGx1Z2luIGluc3RhbGwgKGluc3RhbGxQbHVnaW46IGZhbHNlKSBcdTIwMTQgcmVnaXN0ZXJpbmcgYW4gZW1wdHkgdmF1bHQuYCk7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcz8ucG9wdWxhdGUpIHtcbiAgICAgIGNvbnN0IHBvcHVsYXRlID0gcmVtYXBDb25maWdEaXJlY3RvcnlLZXlzKHBhcmFtcy5wb3B1bGF0ZSwgY29uZmlnRGlyZWN0b3J5KTtcbiAgICAgIGNvbnN0IGVudHJ5Q291bnQgPSBPYmplY3Qua2V5cyhwb3B1bGF0ZSkubGVuZ3RoO1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFBvcHVsYXRpbmcgdmF1bHQgd2l0aCAke1N0cmluZyhlbnRyeUNvdW50KX0gZW50cmllcyBiZWZvcmUgb3Blbi4uLmApO1xuICAgICAgdGVtcG9yYXJ5VmF1bHQucG9wdWxhdGUocG9wdWxhdGUpO1xuICAgIH1cblxuICAgIGF3YWl0IGVuc3VyZUhlYWRsZXNzVmF1bHRDb25maWcoe1xuICAgICAgY29uZmlnRGlyZWN0b3J5LFxuICAgICAgbGFiZWwsXG4gICAgICB2YXVsdFBhdGg6IHRlbXBvcmFyeVZhdWx0LnBhdGhcbiAgICB9KTtcblxuICAgIC8vIGByZWdpc3RlcmAgcHVzaGVzIHRoZSBkaXJlY3RvcnkgdG8gdGhlIGRldmljZSBiZWZvcmUgcmVnaXN0ZXJpbmcgaXQsIHNvIGV2ZXJ5IHdyaXRlIGFib3ZlIFx1MjAxNFxuICAgIC8vIHRoZSBwbHVnaW4gY29weSwgdGhlIHBvcHVsYXRlIG1hcCwgYW5kIHRoZSBoZWFkbGVzcyBjb25maWcganVzdCB3cml0dGVuIFx1MjAxNCByZWFjaGVzIHRoZSBhcHAuXG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFJlZ2lzdGVyaW5nIHZhdWx0Li4uYCk7XG4gICAgYXdhaXQgdGVtcG9yYXJ5VmF1bHQucmVnaXN0ZXIodHJhbnNwb3J0KTtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gVmF1bHQgcmVnaXN0ZXJlZC5gKTtcblxuICAgIGlmIChwbHVnaW5JZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBhd2FpdCBlbmFibGVQbHVnaW5JblZhdWx0KHsgbGFiZWwsIHBsdWdpbklkLCB0ZW1wb3JhcnlWYXVsdCwgdHJhbnNwb3J0LCB0cmFuc3BvcnRPcHRpb25zIH0pO1xuICAgIH1cblxuICAgIGF3YWl0IGVuYWJsZUV4dHJhQ29tbXVuaXR5UGx1Z2lucyh7XG4gICAgICBsYWJlbCxcbiAgICAgIHBsdWdpbklkczogcGFyYW1zPy5lbmFibGVDb21tdW5pdHlQbHVnaW5zID8/IFtdLFxuICAgICAgdGVtcG9yYXJ5VmF1bHQsXG4gICAgICB0cmFuc3BvcnQsXG4gICAgICB0cmFuc3BvcnRPcHRpb25zXG4gICAgfSk7XG5cbiAgICBjb25zdCBhdWdtZW50ZWRPcHRpb25zID0gYXVnbWVudFRyYW5zcG9ydE9wdGlvbnModHJhbnNwb3J0T3B0aW9ucywgdHJhbnNwb3J0KTtcbiAgICBjb25zdCByZXN1bHQ6IENvcmVTZXR1cFJlc3VsdCA9IHsgdGVtcG9yYXJ5VmF1bHQsIHRyYW5zcG9ydCwgdHJhbnNwb3J0TGFiZWw6IGxhYmVsLCB0cmFuc3BvcnRPcHRpb25zOiBhdWdtZW50ZWRPcHRpb25zIH07XG4gICAgYWN0aXZlU2V0dXBzLmFkZChyZXN1bHQpO1xuICAgIGlmIChsb2NrKSB7XG4gICAgICBzZXR1cExvY2tzLnNldChyZXN1bHQsIGxvY2spO1xuICAgIH1cbiAgICByZWdpc3RlclByb2Nlc3NDbGVhbnVwSGFuZGxlcigpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFNldHVwIGZhaWxlZCwgY2xlYW5pbmcgdXAuLi5gKTtcbiAgICB0cnkge1xuICAgICAgaWYgKHRlbXBvcmFyeVZhdWx0ICYmIHRyYW5zcG9ydCkge1xuICAgICAgICBhd2FpdCB0ZW1wb3JhcnlWYXVsdC5kaXNwb3NlKHRyYW5zcG9ydCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoY2xlYW51cEVycm9yOiB1bmtub3duKSB7XG4gICAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gVmF1bHQgY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGNsZWFudXBFcnJvcil9YCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0cmFuc3BvcnQ/LmRpc3Bvc2U/LigpO1xuICAgIH0gY2F0Y2ggKGNsZWFudXBFcnJvcjogdW5rbm93bikge1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFRyYW5zcG9ydCBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoY2xlYW51cEVycm9yKX1gKTtcbiAgICB9XG5cbiAgICAvLyBSZWxlYXNlIHRoZSBsb2NrIHNvIGEgd2FpdGluZyBydW4gY2FuIHByb2NlZWQgZXZlbiB0aG91Z2ggdGhpcyBydW4gZmFpbGVkLlxuICAgIGxvY2s/LnJlbGVhc2UoKTtcblxuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBOT1RFOiBJZiB0aGUgdGVzdCBydW5uZXIgcmVwb3J0cyBcIk5vIHRlc3QgZmlsZXMgZm91bmRcIiwgaWdub3JlIGl0IFx1MjAxNCBpdCBpcyBhIHNpZGUgZWZmZWN0IG9mIHRoZSBzZXR1cCBmYWlsdXJlIGFib3ZlLmApO1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbi8qKlxuICogRnJhbWV3b3JrLWFnbm9zdGljIGdsb2JhbCB0ZWFyZG93biBsb2dpYy5cbiAqXG4gKiBEaXNwb3NlcyBvZiB0aGUgdGVtcG9yYXJ5IHZhdWx0IGFuZCB0cmFuc3BvcnQgY3JlYXRlZCBkdXJpbmcgc2V0dXAuXG4gKlxuICogQHBhcmFtIHJlc3VsdCAtIFRoZSByZXN1bHQgZnJvbSB7QGxpbmsgY29yZVNldHVwfS4gV2hlbiBgdW5kZWZpbmVkYCwgZG9lcyBub3RoaW5nLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29yZVRlYXJkb3duKHJlc3VsdD86IENvcmVTZXR1cFJlc3VsdCk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoIXJlc3VsdCB8fCBkaXNwb3NlZFJlc3VsdHMuaGFzKHJlc3VsdCkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgZGlzcG9zZWRSZXN1bHRzLmFkZChyZXN1bHQpO1xuXG4gIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gVGVhcmluZyBkb3duLi4uYCk7XG5cbiAgdHJ5IHtcbiAgICBhd2FpdCB0ZWFyZG93bkFzeW5jKHJlc3VsdCk7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd246JHtyZXN1bHQudHJhbnNwb3J0TGFiZWx9XSBDbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICB9IGZpbmFsbHkge1xuICAgIGFjdGl2ZVNldHVwcy5kZWxldGUocmVzdWx0KTtcbiAgICByZWxlYXNlU2V0dXBMb2NrKHJlc3VsdCk7XG4gIH1cblxuICBhd2FpdCBzd2VlcExlZnRvdmVycyh7XG4gICAgZXhjbHVkZWROYW1lczogWy4uLmFjdGl2ZVNldHVwc10ubWFwKChhY3RpdmVTZXR1cCkgPT4gYmFzZW5hbWUoYWN0aXZlU2V0dXAudGVtcG9yYXJ5VmF1bHQucGF0aCkpLFxuICAgIGxhYmVsOiByZXN1bHQudHJhbnNwb3J0TGFiZWwsXG4gICAgcGhhc2U6ICd0ZWFyZG93bicsXG4gICAgdHJhbnNwb3J0T3B0aW9uczogcmVzdWx0LnRyYW5zcG9ydE9wdGlvbnNcbiAgfSk7XG59XG5cbi8qKlxuICogUmVkaXJlY3RzIGEgcG9wdWxhdGUgbWFwJ3MgY29uZmlnLWZvbGRlciBlbnRyaWVzIHRvIHRoZSBmb2xkZXIgdGhlIHZhdWx0IHdpbGwgYWN0dWFsbHkgcmVhZC5cbiAqXG4gKiBBIHBvcHVsYXRlIG1hcCBuYW1lcyBpdHMgZGVzdGluYXRpb25zIHZhdWx0LXJlbGF0aXZlLCBhbmQgZXZlcnl0aGluZyB0aGF0IGJ1aWxkcyBvbmUgXHUyMDE0IGluY2x1ZGluZ1xuICogYGJ1aWxkRGVtb1ZhdWx0UG9wdWxhdGVgLCB3aGljaCBzZWVkcyBgLm9ic2lkaWFuLypgIGNvbmZpZyBmaWxlcyBhbmQgaW5qZWN0ZWQgY29tbXVuaXR5IHBsdWdpbnMnXG4gKiBiaW5hcmllcyBcdTIwMTQgd3JpdGVzIHRoZW0gdW5kZXIgYSBsaXRlcmFsIGAub2JzaWRpYW4vYCwgYmVjYXVzZSB0aGF0IGlzIHRoZSBmb2xkZXIgT2JzaWRpYW4gdXNlcyB3aGVuIG5vdGhpbmdcbiAqIG92ZXJyaWRlcyBpdC4gVW5kZXIgYSBgY29uZmlnRGlyZWN0b3J5YCBvdmVycmlkZSB0aG9zZSBlbnRyaWVzIGxhbmQgaW4gYSBmb2xkZXIgdGhlIHZhdWx0IG5ldmVyIG9wZW5zLCBhbmRcbiAqIHRoZSBwbHVnaW5zIHNlZWRlZCB0aGF0IHdheSBjb21lIGJhY2sgYXMgdGhlIGdlbmVyaWMgXCJlbmFibGVkIGJ1dCBub3QgbG9hZGVkXCIgd2l0aCBub3RoaW5nIG5hbWluZyBhIGNvbmZpZ1xuICogZm9sZGVyLiBSZXdyaXRpbmcgdGhlIGtleSBoZXJlIGZpeGVzIGV2ZXJ5IGNvbnN1bWVyIGF0IG9uY2UgXHUyMDE0IGEgaGFuZC13cml0dGVuIG1hcCBhcyBtdWNoIGFzIGEgZGVtbyB2YXVsdCdzXG4gKiBcdTIwMTQgYW5kIG5lZWRzIG5vIHNlY29uZCBjb3B5IG9mIHRoZSBvdmVycmlkZSBmb3IgYSBjYWxsZXIgdG8ga2VlcCBpbiBzeW5jIHdpdGggdGhlaXIgdHJhbnNwb3J0IG9wdGlvbnMuXG4gKlxuICogU2FmZSByYXRoZXIgdGhhbiBtYWdpYzogdGhlIHZhdWx0IGlzIG9uZSB0aGUgaGFybmVzcyBtYWRlIGZvciB0aGlzIHJ1biBhbmQgaGFzIGV4YWN0bHkgb25lIGNvbmZpZyBmb2xkZXIsXG4gKiBzbyB1bmRlciBhbiBvdmVycmlkZSBhIGAub2JzaWRpYW4vYCBlbnRyeSBpcyBkZWFkIHdlaWdodCBub3RoaW5nIHJlYWRzLiBPbmx5IGEgbGVhZGluZyBgLm9ic2lkaWFuYCBwYXRoXG4gKiBTRUdNRU5UIG1vdmVzOyBhIG5vdGUgd2hvc2UgbmFtZSBtZXJlbHkgY29udGFpbnMgdGhlIHN0cmluZyBkb2VzIG5vdC5cbiAqXG4gKiBAcGFyYW0gcG9wdWxhdGUgLSBUaGUgY29uc3VtZXIncyBwb3B1bGF0ZSBtYXAuXG4gKiBAcGFyYW0gY29uZmlnRGlyZWN0b3J5IC0gVGhlIHJlc29sdmVkIG92ZXJyaWRlLCBvciBgdW5kZWZpbmVkYCBmb3IgT2JzaWRpYW4ncyBkZWZhdWx0IChhIG5vLW9wKS5cbiAqIEByZXR1cm5zIFRoZSBtYXAgd2l0aCBpdHMgY29uZmlnLWZvbGRlciBrZXlzIHJlZGlyZWN0ZWQsIG9yIHRoZSBvcmlnaW5hbCBtYXAgd2hlbiB0aGVyZSBpcyBub3RoaW5nIHRvIG1vdmUuXG4gKi9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBvYnNpZGlhbi1kZXYtdXRpbHMvcGFyYW1zLW9wdGlvbnMtbmFtZS1tYXRjaCAtLSBQZXJtYW5lbnQ6IGBQb3B1bGF0ZUZpbGVzUGFyYW1zYCBpcyBvbmUgYmFnIHNoYXJlZCBieSBgVGVtcG9yYXJ5VmF1bHQucG9wdWxhdGVgIGFuZCB0aGlzIHJlbWFwLCBzbyBubyBwZXItb3duZXIgbmFtZSBjYW4gc2F0aXNmeSBib3RoLlxuZXhwb3J0IGZ1bmN0aW9uIHJlbWFwQ29uZmlnRGlyZWN0b3J5S2V5cyhwb3B1bGF0ZTogUG9wdWxhdGVGaWxlc1BhcmFtcywgY29uZmlnRGlyZWN0b3J5OiBzdHJpbmcgfCB1bmRlZmluZWQpOiBQb3B1bGF0ZUZpbGVzUGFyYW1zIHtcbiAgaWYgKGNvbmZpZ0RpcmVjdG9yeSA9PT0gdW5kZWZpbmVkIHx8IGNvbmZpZ0RpcmVjdG9yeSA9PT0gREVGQVVMVF9DT05GSUdfRElSRUNUT1JZKSB7XG4gICAgcmV0dXJuIHBvcHVsYXRlO1xuICB9XG5cbiAgY29uc3QgcHJlZml4ID0gYCR7REVGQVVMVF9DT05GSUdfRElSRUNUT1JZfS9gO1xuICBjb25zdCByZW1hcHBlZDogUG9wdWxhdGVGaWxlc1BhcmFtcyA9IHt9O1xuICBmb3IgKGNvbnN0IFtwYXRoLCBjb250ZW50XSBvZiBPYmplY3QuZW50cmllcyhwb3B1bGF0ZSkpIHtcbiAgICByZW1hcHBlZFtwYXRoLnN0YXJ0c1dpdGgocHJlZml4KSA/IGAke2NvbmZpZ0RpcmVjdG9yeX0vJHtwYXRoLnNsaWNlKHByZWZpeC5sZW5ndGgpfWAgOiBwYXRoXSA9IGNvbnRlbnQ7XG4gIH1cblxuICByZXR1cm4gcmVtYXBwZWQ7XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgdHJhbnNwb3J0IG9wdGlvbnMgZm9yIGFuIGludGVncmF0aW9uIHJ1bi5cbiAqXG4gKiBEZXNrdG9wIGxhdW5jaGVzIGFyZSBub3JtYWxseSB2aXNpYmxlLCBidXQgdGVzdCBzZXR1cCBleHBsaWNpdGx5IGtlZXBzIGl0c1xuICogb3duZWQgaW5zdGFuY2Ugb2ZmLXNjcmVlbiBzbyBpdCBkb2VzIG5vdCBpbnRlcnJ1cHQgdGhlIGRldmVsb3Blci5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIENvbnN1bWVyLXByb3ZpZGVkIHRyYW5zcG9ydCBvcHRpb25zLlxuICogQHJldHVybnMgT3B0aW9ucyB3aXRoIHRoZSBkZXNrdG9wIGludGVncmF0aW9uIHZpc2liaWxpdHkgZGVmYXVsdCBhcHBsaWVkLlxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgb2JzaWRpYW4tZGV2LXV0aWxzL3BhcmFtcy1vcHRpb25zLW5hbWUtbWF0Y2ggLS0gUGVybWFuZW50OiBgT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zYCBpcyBvbmUgdHJhbnNwb3J0IG9wdGlvbnMgYmFnIHJlYWQgYnkgZml2ZSBoZWxwZXJzLCBzbyBubyBwZXItb3duZXIgbmFtZSBjYW4gc2F0aXNmeSB0aGVtIGFsbC5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlSW50ZWdyYXRpb25UcmFuc3BvcnRPcHRpb25zKG9wdGlvbnM/OiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMpOiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMge1xuICBpZiAob3B0aW9ucz8udHlwZSA9PT0gJ29ic2lkaWFuLWFuZHJvaWQtYXBwaXVtJykge1xuICAgIHJldHVybiBvcHRpb25zO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5vcHRpb25zLFxuICAgIGlzT2JzaWRpYW5BcHBWaXNpYmxlOiBvcHRpb25zPy5pc09ic2lkaWFuQXBwVmlzaWJsZSA/PyBmYWxzZSxcbiAgICB0eXBlOiAnb2JzaWRpYW4tY2RwJ1xuICB9O1xufVxuXG4vKipcbiAqIEF1Z21lbnRzIHRyYW5zcG9ydCBvcHRpb25zIHdpdGggcmV1c2UgaW5mbyBzbyB0ZXN0IHdvcmtlcnMgY2FuIHJlYXR0YWNoIHRvIHRoZVxuICogaW5zdGFuY2UgdGhlIGdsb2JhbCBzZXR1cCBhbHJlYWR5IGxhdW5jaGVkIGluc3RlYWQgb2YgY3JlYXRpbmcgdGhlaXIgb3duOlxuICpcbiAqIC0gKipBcHBpdW0qKiBcdTIwMTQgaW5qZWN0cyB0aGUgZXN0YWJsaXNoZWQgYHNlc3Npb25JZGAvYGRldmljZUlkYC5cbiAqIC0gKipPd25lZCBkZXNrdG9wIENEUCoqIFx1MjAxNCBpbmplY3RzIHRoZSBvd25lZCBpbnN0YW5jZSdzIGBob3N0YC9gcG9ydGAgKGNob3NlblxuICogICBhdCBsYXVuY2gpIHBsdXMgdGhlIGludGVybmFsIGBpc0hhcm5lc3NPd25lZEluc3RhbmNlYCBmbGFnLCBzbyBlYWNoIHdvcmtlclxuICogICAqKmF0dGFjaGVzKiogdG8gdGhhdCBpbnN0YW5jZSBvdmVyIENEUCByYXRoZXIgdGhhbiBsYXVuY2hpbmcgKGFuZCBuZXZlclxuICogICByZWdpc3RlcmluZykgaXRzIG93biBcdTIwMTQgdGhlIGJ1ZyB0aGF0IG90aGVyd2lzZSBsZWF2ZXMgYSB3b3JrZXIncyB0cmFuc3BvcnRcbiAqICAgd2l0aCBubyBDRFAgZW5kcG9pbnQuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgb3JpZ2luYWwgdHJhbnNwb3J0IG9wdGlvbnMuXG4gKiBAcGFyYW0gdHJhbnNwb3J0IC0gVGhlIHRyYW5zcG9ydCBpbnN0YW5jZSBjcmVhdGVkIGR1cmluZyBzZXR1cC5cbiAqIEByZXR1cm5zIFRoZSBhdWdtZW50ZWQgb3B0aW9ucywgb3IgdGhlIG9yaWdpbmFsIG9wdGlvbnMgaWYgbm90IGFwcGxpY2FibGUuXG4gKi9cbmZ1bmN0aW9uIGF1Z21lbnRUcmFuc3BvcnRPcHRpb25zKFxuICBvcHRpb25zOiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfCB1bmRlZmluZWQsXG4gIHRyYW5zcG9ydDogT2JzaWRpYW5UcmFuc3BvcnRcbik6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZCB7XG4gIGlmIChvcHRpb25zPy50eXBlID09PSAnb2JzaWRpYW4tYW5kcm9pZC1hcHBpdW0nICYmIHRyYW5zcG9ydCBpbnN0YW5jZW9mIEFwcGl1bVRyYW5zcG9ydCkge1xuICAgIGNvbnN0IHNlc3Npb25JbmZvID0gdHJhbnNwb3J0LmdldFNlc3Npb25JbmZvKCk7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtvcHRpb25zLnR5cGV9XSBTZXNzaW9uIHJldXNlIGluZm86IHNlc3Npb25JZD0ke3Nlc3Npb25JbmZvLnNlc3Npb25JZH0sIGRldmljZUlkPSR7c2Vzc2lvbkluZm8uZGV2aWNlSWR9YCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBkZXZpY2VJZDogc2Vzc2lvbkluZm8uZGV2aWNlSWQsXG4gICAgICBzZXNzaW9uSWQ6IHNlc3Npb25JbmZvLnNlc3Npb25JZFxuICAgIH07XG4gIH1cblxuICBpZiAoKG9wdGlvbnMgPT09IHVuZGVmaW5lZCB8fCBvcHRpb25zLnR5cGUgPT09ICdvYnNpZGlhbi1jZHAnKSAmJiB0cmFuc3BvcnQgaW5zdGFuY2VvZiBEZXNrdG9wQ2RwVHJhbnNwb3J0KSB7XG4gICAgY29uc3QgZW5kcG9pbnQgPSB0cmFuc3BvcnQuZ2V0T3duZWRJbnN0YW5jZUVuZHBvaW50KCk7XG4gICAgaWYgKGVuZHBvaW50KSB7XG4gICAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke0RFRkFVTFRfVFJBTlNQT1JUX1RZUEV9XSBPd25lZCBpbnN0YW5jZSByZXVzZSBpbmZvOiBob3N0PSR7ZW5kcG9pbnQuaG9zdH0sIHBvcnQ9JHtTdHJpbmcoZW5kcG9pbnQucG9ydCl9YCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICBob3N0OiBlbmRwb2ludC5ob3N0LFxuICAgICAgICBpc0hhcm5lc3NPd25lZEluc3RhbmNlOiB0cnVlLFxuICAgICAgICBwb3J0OiBlbmRwb2ludC5wb3J0LFxuICAgICAgICB0eXBlOiAnb2JzaWRpYW4tY2RwJ1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3B0aW9ucztcbn1cblxuLyoqXG4gKiBDb3BpZXMgdGhlIGJ1aWx0IHBsdWdpbiBpbnRvIHRoZSB0ZW1wIHZhdWx0IGFuZCBtYXJrcyBpdCBhcyBhIGNvbW11bml0eSBwbHVnaW4uXG4gKlxuICogUmVhZHMgYG1hbmlmZXN0Lmpzb25gIGZyb20gdGhlIG5ld2VyIG9mIGBkaXN0L2RldmAvYGRpc3QvYnVpbGRgLCByZWplY3RzIGFcbiAqIGRlc2t0b3Atb25seSBwbHVnaW4gb24gYSBtb2JpbGUgdHJhbnNwb3J0LCB0aGVuIGhhbmRzIHRoZSB3cml0ZSBpdHNlbGYgdG9cbiAqIHtAbGluayBpbnN0YWxsUGx1Z2luSW50b1ZhdWx0fSBcdTIwMTQgd2hpY2ggcHV0cyB0aGUgYnVpbGQgaW5cbiAqIGA8Y29uZmlnRGlyZWN0b3J5Pi9wbHVnaW5zLzxpZD5gIGFuZCB3cml0ZXNcbiAqIGA8Y29uZmlnRGlyZWN0b3J5Pi9jb21tdW5pdHktcGx1Z2lucy5qc29uYCwgaG9ub3VyaW5nIGEgYGNvbmZpZ0RpcmVjdG9yeWBcbiAqIG92ZXJyaWRlIHNvIHRoZSBwbHVnaW4gbGFuZHMgd2hlcmUgdGhlIHZhdWx0IHdpbGwgYWN0dWFsbHkgbG9vayBmb3IgaXQuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBjb3B5IHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyBUaGUgcGx1Z2luIGlkIHJlYWQgZnJvbSB0aGUgbWFuaWZlc3QuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNvcHlQbHVnaW5JbnRvVmF1bHQocGFyYW1zOiBDb3B5UGx1Z2luSW50b1ZhdWx0UGFyYW1zKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgeyBjb25maWdEaXJlY3RvcnksIGxhYmVsLCBwcm9qZWN0Um9vdCwgdGVtcG9yYXJ5VmF1bHQsIHRyYW5zcG9ydCB9ID0gcGFyYW1zO1xuICBjb25zdCBkaXN0UGF0aCA9IGF3YWl0IHJlc29sdmVEaXN0UGF0aChwcm9qZWN0Um9vdCk7XG4gIGNvbnN0IG1hbmlmZXN0SnNvbiA9IEpTT04ucGFyc2UoYXdhaXQgcmVhZEZpbGUoam9pbihkaXN0UGF0aCwgJ21hbmlmZXN0Lmpzb24nKSwgJ3V0Zi04JykpIGFzIFBsdWdpbk1hbmlmZXN0O1xuICBjb25zdCBwbHVnaW5JZCA9IG1hbmlmZXN0SnNvbi5pZDtcblxuICAvLyBUaGUgc2FtZSByZWZ1c2FsIHtAbGluayBza2lwSWZEZXNrdG9wT25seX0gYWxyZWFkeSBtYWRlIGJlZm9yZSB0aGUgdHJhbnNwb3J0IGV4aXN0ZWQuIEtlcHQgYXMgdGhlXG4gIC8vIGJhY2tzdG9wIGZvciBhbnkgY2FsbGVyIHRoYXQgcmVhY2hlcyBoZXJlIGFub3RoZXIgd2F5LCBhbmQgdGhyb3dpbmcgdGhlIHNhbWUgdHlwZSBzbyBib3RoIHBhdGhzIHJlYWRcbiAgLy8gaWRlbnRpY2FsbHkgaW4gdGhlIGxvZy5cbiAgaWYgKHRyYW5zcG9ydC5pc01vYmlsZSAmJiBtYW5pZmVzdEpzb24uaXNEZXNrdG9wT25seSkge1xuICAgIHRocm93IG5ldyBEZXNrdG9wT25seVBsdWdpblNraXBFcnJvcihwbHVnaW5JZCk7XG4gIH1cblxuICBjb25zdCBtYWluSnMgPSBqb2luKGRpc3RQYXRoLCBNQUlOX0pTKTtcbiAgY29uc3QgYnVpbGRTdGF0ID0gYXdhaXQgc3RhdChtYWluSnMpO1xuICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gVXNpbmcgJHtkaXN0UGF0aH0gKCR7YnVpbGRTdGF0Lm10aW1lLnRvSVNPU3RyaW5nKCl9KS4gSWYgb3V0ZGF0ZWQsIHJlYnVpbGQuYCk7XG5cbiAgYXdhaXQgaW5zdGFsbFBsdWdpbkludG9WYXVsdCh7IGNvbmZpZ0RpcmVjdG9yeSwgZGlzdFBhdGgsIHBsdWdpbklkLCB2YXVsdFBhdGg6IHRlbXBvcmFyeVZhdWx0LnBhdGggfSk7XG4gIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBJbnN0YWxsZWQgXCIke3BsdWdpbklkfVwiIGludG8gJHtjb25maWdEaXJlY3RvcnkgPz8gREVGQVVMVF9DT05GSUdfRElSRUNUT1JZfS9wbHVnaW5zIChhbmQgZW5hYmxlZCBpdCB0aGVyZSkuYCk7XG5cbiAgcmV0dXJuIHBsdWdpbklkO1xufVxuXG4vKipcbiAqIEVuYWJsZXMgZXh0cmEgY29tbXVuaXR5IHBsdWdpbnMgKGJleW9uZCB0aGUgcGx1Z2luLXVuZGVyLXRlc3QpIGluIHRoZSByZWdpc3RlcmVkIHZhdWx0LCBlYWNoIHRocm91Z2ggdGhlXG4gKiBzYW1lIHtAbGluayBlbmFibGVQbHVnaW5JblZhdWx0fSBwYXRoLiBFYWNoIHBsdWdpbidzIGJ1aWx0IGZpbGVzIG11c3QgYWxyZWFkeSBiZSBwcmVzZW50IGluIHRoZSB2YXVsdCAoc2VlZFxuICogdGhlbSB2aWEge0BsaW5rIENvcmVTZXR1cE9wdGlvbnMucG9wdWxhdGV9KS4gQSBuby1vcCB3aGVuIHRoZSBsaXN0IGlzIGVtcHR5LlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZW5hYmxlIHBhcmFtZXRlcnMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGVuYWJsZUV4dHJhQ29tbXVuaXR5UGx1Z2lucyhwYXJhbXM6IEVuYWJsZUV4dHJhQ29tbXVuaXR5UGx1Z2luc1BhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7IGxhYmVsLCBwbHVnaW5JZHMsIHRlbXBvcmFyeVZhdWx0LCB0cmFuc3BvcnQsIHRyYW5zcG9ydE9wdGlvbnMgfSA9IHBhcmFtcztcbiAgZm9yIChjb25zdCBwbHVnaW5JZCBvZiBwbHVnaW5JZHMpIHtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gRW5hYmxpbmcgZXh0cmEgY29tbXVuaXR5IHBsdWdpbiBcIiR7cGx1Z2luSWR9XCIuLi5gKTtcbiAgICBhd2FpdCBlbmFibGVQbHVnaW5JblZhdWx0KHsgbGFiZWwsIHBsdWdpbklkLCB0ZW1wb3JhcnlWYXVsdCwgdHJhbnNwb3J0LCB0cmFuc3BvcnRPcHRpb25zIH0pO1xuICB9XG59XG5cbi8qKlxuICogRW5hYmxlcyB0aGUgcGx1Z2luIGluIHRoZSByZWdpc3RlcmVkIHZhdWx0IGFuZCB2ZXJpZmllcyBpdCBsb2FkZWQuXG4gKlxuICogT2JzaWRpYW4ncyBgZW5hYmxlUGx1Z2luKClgIHdyYXBzIGBsb2FkUGx1Z2luKClgIGluIGEgdHJ5LWNhdGNoIHRoYXQgc3dhbGxvd3NcbiAqIGVycm9ycyBhbmQgcmV0dXJucyBmYWxzZSwgc28ge0BsaW5rIGVuYWJsZVBsdWdpbldpdGhFcnJvckNhcHR1cmV9IG1vbmtleS1wYXRjaGVzXG4gKiBgbG9hZFBsdWdpbigpYCB0byBjYXB0dXJlIHRoZSBlcnJvciBiZWZvcmUgaXQncyBzd2FsbG93ZWQuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBlbmFibGUgcGFyYW1ldGVycy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZW5hYmxlUGx1Z2luSW5WYXVsdChwYXJhbXM6IEVuYWJsZVBsdWdpbkluVmF1bHRQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBsYWJlbCwgcGx1Z2luSWQsIHRlbXBvcmFyeVZhdWx0LCB0cmFuc3BvcnQsIHRyYW5zcG9ydE9wdGlvbnMgfSA9IHBhcmFtcztcbiAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIEVuYWJsaW5nIHBsdWdpbiBcIiR7cGx1Z2luSWR9XCIuLi5gKTtcblxuICAvKlxuICAgKiBPcGVuIGEgbmF0aXZlIGNvbnNvbGUtY2FwdHVyZSB3aW5kb3cgKExheWVyIDIsIEFuZHJvaWQgb25seSkgYXJvdW5kIHRoZVxuICAgKiBlbmFibGUgc28gdGhhdCBpZiBPYnNpZGlhbiBzd2FsbG93cyB0aGUgbG9hZCBlcnJvciBiZWZvcmUgdGhlIG1vbmtleS1wYXRjaFxuICAgKiBhbmQgdGhlIHJlbmRlcmVyIGNvbnNvbGUgKExheWVyIDEpIGNhbWUgdXAgZW1wdHksIHdlIGNhbiBzdGlsbCByZWNvdmVyIHRoZVxuICAgKiByZWFsIGNhdXNlIGZyb20gYGFkYiBsb2djYXRgLiBOby1vcCAodW5kZWZpbmVkKSBvbiB0cmFuc3BvcnRzIHRoYXQgZG9uJ3RcbiAgICogaW1wbGVtZW50IGl0IChlLmcuIGRlc2t0b3ApLlxuICAgKi9cbiAgY29uc3QgY2FwdHVyZUhhbmRsZSA9IGF3YWl0IHRyYW5zcG9ydC5iZWdpbkNvbnNvbGVDYXB0dXJlPy4oKTtcblxuICAvKlxuICAgKiBPbiBhIGZyZXNobHkgY29sZC1ib290ZWQgZW11bGF0b3IgdGhlIHBsdWdpbiBzdWJzeXN0ZW0gY2FuIHN0aWxsIGJlIHNldHRsaW5nXG4gICAqIHdoZW4gd2UgZW5hYmxlIHRoZSBwbHVnaW4sIHNvIGEgc2luZ2xlLXNob3QgZW5hYmxlIHJhY2VzIHRoZSBsb2FkIGFuZCBsb3Nlc1xuICAgKiAodGhlIHBsdWdpbiBsYW5kcyBpbiB0aGUgZW5hYmxlZCBzZXQgYnV0IG5ldmVyIGxvYWRzKS4gUmV0cnkgdGhlIGVuYWJsZSArXG4gICAqIGxvYWQtdmVyaWZpY2F0aW9uIGEgZmV3IHRpbWVzIHdpdGggZXhwb25lbnRpYWwgYmFja29mZiwgd2hpY2ggcmVjb3ZlcnMgdGhlXG4gICAqIHRyYW5zaWVudCByYWNlLiBBIGNhcHR1cmVkIGxvYWQgZXJyb3IgKGByZWFsRXJyb3JgKSBpcyBhIGRldGVybWluaXN0aWMgYnVnIFx1MjAxNFxuICAgKiByZXRyeWluZyBjYW5ub3QgZml4IGl0LCBzbyB3ZSBmYWlsIGZhc3QuIE5vbi1BbmRyb2lkIHRyYW5zcG9ydHMgcmVzb2x2ZSB0b1xuICAgKiB0aGUgc2FtZSBkZWZhdWx0cyBidXQgbmV2ZXIgZW50ZXIgdGhlIHJldHJ5IHBhdGg6IHRoZWlyIGxvYWQgZWl0aGVyIHN1Y2NlZWRzXG4gICAqIG9uIHRoZSBmaXJzdCBhdHRlbXB0IG9yIHRocm93cyBhIGNhcHR1cmVkIGVycm9yLlxuICAgKi9cbiAgY29uc3QgbWF4QXR0ZW1wdHMgPSAxICsgcmVzb2x2ZVBsdWdpbkVuYWJsZVJldHJ5Q291bnQodHJhbnNwb3J0T3B0aW9ucyk7XG4gIGNvbnN0IGJhc2VEZWxheUluTWlsbGlzZWNvbmRzID0gcmVzb2x2ZVBsdWdpbkVuYWJsZVJldHJ5RGVsYXlJbk1pbGxpc2Vjb25kcyh0cmFuc3BvcnRPcHRpb25zKTtcblxuICBmb3IgKGxldCBhdHRlbXB0ID0gMTsgYXR0ZW1wdCA8PSBtYXhBdHRlbXB0czsgYXR0ZW1wdCsrKSB7XG4gICAgbGV0IHJlc3VsdDogRW5hYmxlUGx1Z2luUmVzdWx0O1xuICAgIHRyeSB7XG4gICAgICByZXN1bHQgPSBhd2FpdCBldmFsSW5PYnNpZGlhbih7XG4gICAgICAgIGNhbGxiYWNrOiBlbmFibGVQbHVnaW5XaXRoRXJyb3JDYXB0dXJlLFxuICAgICAgICBpbnB1dDogeyBwbHVnaW5JZCB9LFxuICAgICAgICBzaG91bGRTa2lwUHJlZmxpZ2h0Q2hlY2tzOiB0cnVlLFxuICAgICAgICB0cmFuc3BvcnQsXG4gICAgICAgIHZhdWx0UGF0aDogdGVtcG9yYXJ5VmF1bHQucGF0aFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8qXG4gICAgICAgKiBUaGUgZXZhbCBpdHNlbGYgdGhyZXcgKGUuZy4gdGhlIFdlYlZpZXcgY29udGV4dCB3YXMgbG9zdCBtaWQtZXhlY3V0aW9uIG9uXG4gICAgICAgKiBhIGNodXJuaW5nIGd1ZXN0KSBcdTIwMTQgYSB0cmFuc3BvcnQtbGV2ZWwgdHJhbnNpZW50LiBSZXRyeSBpZiBhdHRlbXB0cyByZW1haW4uXG4gICAgICAgKi9cbiAgICAgIGlmIChhdHRlbXB0IDwgbWF4QXR0ZW1wdHMpIHtcbiAgICAgICAgY29uc3QgZGVsYXlJbk1pbGxpc2Vjb25kcyA9IGNvbXB1dGVCYWNrb2ZmRGVsYXlJbk1pbGxpc2Vjb25kcyhiYXNlRGVsYXlJbk1pbGxpc2Vjb25kcywgYXR0ZW1wdCAtIDEpO1xuICAgICAgICBsb2coXG4gICAgICAgICAgYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gRW5hYmxlIGF0dGVtcHQgJHtTdHJpbmcoYXR0ZW1wdCl9LyR7U3RyaW5nKG1heEF0dGVtcHRzKX0gdGhyZXcgYFxuICAgICAgICAgICAgKyBgKCR7ZXJyb3JUb1N0cmluZyhlcnJvcil9KTsgcmV0cnlpbmcgaW4gJHtTdHJpbmcoZGVsYXlJbk1pbGxpc2Vjb25kcyl9bXMuLi5gXG4gICAgICAgICk7XG4gICAgICAgIGF3YWl0IHNsZWVwKGRlbGF5SW5NaWxsaXNlY29uZHMpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogYGVycm9yTWVzc2FnZWAgaXMgdGhlIHJlYWwgdGhyb3cgc2VlbiBieSB0aGUgbW9ua2V5LXBhdGNoO1xuICAgICAqIGByZW5kZXJlckNvbnNvbGVFcnJvcnNgIChMYXllciAxKSBpcyB0aGUgcmVhbCBjYXVzZSBjb25zb2xlLWxvZ2dlZCBpbiB0aGUgcmVuZGVyZXIuXG4gICAgICovXG4gICAgY29uc3QgcmVhbEVycm9yID0gcmVzdWx0LmVycm9yTWVzc2FnZSA/PyByZXN1bHQucmVuZGVyZXJDb25zb2xlRXJyb3JzO1xuXG4gICAgaWYgKHJlc3VsdC5pc0xvYWRlZCAmJiAhcmVhbEVycm9yKSB7XG4gICAgICBjb25zdCBhdHRlbXB0U3VmZml4ID0gYXR0ZW1wdCA+IDEgPyBgIChhdHRlbXB0ICR7U3RyaW5nKGF0dGVtcHQpfS8ke1N0cmluZyhtYXhBdHRlbXB0cyl9KWAgOiAnJztcbiAgICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBQbHVnaW4gXCIke3BsdWdpbklkfVwiIGVuYWJsZWQgc3VjY2Vzc2Z1bGx5JHthdHRlbXB0U3VmZml4fS5gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBBIGNhcHR1cmVkIGxvYWQgZXJyb3IgaXMgZGV0ZXJtaW5pc3RpYyBcdTIwMTQgZmFpbCBmYXN0IHJhdGhlciB0aGFuIHJldHJ5LlxuICAgIGlmICghc2hvdWxkUmV0cnlQbHVnaW5FbmFibGUocmVzdWx0KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBQbHVnaW4gXCIke3BsdWdpbklkfVwiIGZhaWxlZCB0byBsb2FkOiAke3JlYWxFcnJvciA/PyBnZXRHZW5lcmljUGx1Z2luTG9hZEZhaWx1cmVNZXNzYWdlKHBsdWdpbklkKX1gKTtcbiAgICB9XG5cbiAgICAvLyBUcmFuc2llbnQgY29sZC1ib290IHJhY2UgKGVuYWJsZWQgYnV0IG5vdCBsb2FkZWQsIG5vIGNhdXNlIGNhcHR1cmVkKTogcmV0cnkuXG4gICAgaWYgKGF0dGVtcHQgPCBtYXhBdHRlbXB0cykge1xuICAgICAgY29uc3QgZGVsYXlJbk1pbGxpc2Vjb25kcyA9IGNvbXB1dGVCYWNrb2ZmRGVsYXlJbk1pbGxpc2Vjb25kcyhiYXNlRGVsYXlJbk1pbGxpc2Vjb25kcywgYXR0ZW1wdCAtIDEpO1xuICAgICAgbG9nKFxuICAgICAgICBgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBQbHVnaW4gXCIke3BsdWdpbklkfVwiIGVuYWJsZWQgYnV0IG5vdCBsb2FkZWQgYFxuICAgICAgICAgICsgYChhdHRlbXB0ICR7U3RyaW5nKGF0dGVtcHQpfS8ke1N0cmluZyhtYXhBdHRlbXB0cyl9KTsgcmV0cnlpbmcgaW4gJHtTdHJpbmcoZGVsYXlJbk1pbGxpc2Vjb25kcyl9bXMuLi5gXG4gICAgICApO1xuICAgICAgYXdhaXQgc2xlZXAoZGVsYXlJbk1pbGxpc2Vjb25kcyk7XG4gICAgfVxuICB9XG5cbiAgLypcbiAgICogRXhoYXVzdGVkIGV2ZXJ5IGF0dGVtcHQgb24gdGhlIHRyYW5zaWVudCBzaWduYXR1cmU6IGNvbXBvc2UgdGhlIG1vc3RcbiAgICogc3BlY2lmaWMgZGV0YWlsIGF2YWlsYWJsZSAoYGFkYiBsb2djYXRgIHRhaWwgb24gQW5kcm9pZCwgZWxzZSB0aGUgZ2VuZXJpY1xuICAgKiBtZXNzYWdlKSBcdTIwMTQgdW5jaGFuZ2VkIGZyb20gdGhlIHByZS1yZXRyeSBzaW5nbGUtc2hvdCBmYWlsdXJlLlxuICAgKi9cbiAgY29uc3QgbG9nY2F0VGFpbCA9IGF3YWl0IHRyYW5zcG9ydC5yZWFkQ29uc29sZUNhcHR1cmVTaW5jZT8uKGNhcHR1cmVIYW5kbGUpO1xuICBjb25zdCBkZXRhaWwgPSBsb2djYXRUYWlsID8/IGdldEdlbmVyaWNQbHVnaW5Mb2FkRmFpbHVyZU1lc3NhZ2UocGx1Z2luSWQpO1xuICB0aHJvdyBuZXcgRXJyb3IoYFBsdWdpbiBcIiR7cGx1Z2luSWR9XCIgZmFpbGVkIHRvIGxvYWQ6ICR7ZGV0YWlsfWApO1xufVxuXG4vKipcbiAqIEZpbmRzIHRoZSBwcm9qZWN0IHJvb3QgYnkgd2Fsa2luZyB1cCBmcm9tIGBwcm9jZXNzLmN3ZCgpYCBsb29raW5nIGZvciBgcGFja2FnZS5qc29uYC5cbiAqXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgcHJvamVjdCByb290LlxuICovXG5mdW5jdGlvbiBmaW5kUHJvamVjdFJvb3QoKTogc3RyaW5nIHtcbiAgbGV0IGRpcmVjdG9yeSA9IHByb2Nlc3MuY3dkKCk7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bm5lY2Vzc2FyeS1jb25kaXRpb24gLS0gTG9vcCB0ZXJtaW5hdGVzIGF0IGZpbGVzeXN0ZW0gcm9vdC5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAoZXhpc3RzU3luYyhqb2luKGRpcmVjdG9yeSwgJ3BhY2thZ2UuanNvbicpKSkge1xuICAgICAgcmV0dXJuIGRpcmVjdG9yeTtcbiAgICB9XG4gICAgY29uc3QgcGFyZW50ID0gam9pbihkaXJlY3RvcnksICcuLicpO1xuICAgIGlmIChwYXJlbnQgPT09IGRpcmVjdG9yeSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgZmluZCBwcm9qZWN0IHJvb3QgKG5vIHBhY2thZ2UuanNvbiBmb3VuZCkuJyk7XG4gICAgfVxuICAgIGRpcmVjdG9yeSA9IHBhcmVudDtcbiAgfVxufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBjcm9zcy1wcm9jZXNzIGxvY2sgc2NvcGUgZm9yIGEgdHJhbnNwb3J0LCBvciBgdW5kZWZpbmVkYCB3aGVuIG5vXG4gKiBsb2NrIGlzIG5lZWRlZC5cbiAqXG4gKiBEZXNrdG9wIHJ1bnMgdXNlIGhhcm5lc3Mtb3duZWQsIGlzb2xhdGVkIGluc3RhbmNlcyAodGhlaXIgb3duIHVzZXItZGF0YSBkaXJcbiAqIGFuZCBDRFAgcG9ydCksIHNvIHRoZXkgbm8gbG9uZ2VyIGNvbnRlbmQgYW5kIG5lZWQgbm8gbG9jay4gT25seSB0aGUgQW5kcm9pZFxuICogdHJhbnNwb3J0LCB3aGljaCBzaGFyZXMgdGhlIHNpbmdsZSBlbXVsYXRvciBhbmQgQXBwaXVtIHNlcnZlciwgbXVzdCBzZXJpYWxpemUuXG4gKlxuICogQHBhcmFtIHRyYW5zcG9ydE9wdGlvbnMgLSBUaGUgcmVzb2x2ZWQgdHJhbnNwb3J0IG9wdGlvbnMuXG4gKiBAcmV0dXJucyBUaGUgbG9jayBzY29wZSBzdHJpbmcsIG9yIGB1bmRlZmluZWRgIGlmIG5vIGxvY2sgaXMgbmVlZGVkLlxuICovXG5mdW5jdGlvbiBnZXRMb2NrU2NvcGUodHJhbnNwb3J0T3B0aW9uczogT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zIHwgdW5kZWZpbmVkKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHRyYW5zcG9ydE9wdGlvbnM/LnR5cGUgPT09ICdvYnNpZGlhbi1hbmRyb2lkLWFwcGl1bScgPyBBTkRST0lEX1NFVFVQX0xPQ0tfU0NPUEUgOiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmVnaXN0ZXJzIGNsZWFudXAgaGFuZGxlcnMgZm9yIG9ycGhhbmVkIHNldHVwcyB0aGF0IHdlcmUgbmV2ZXIgZXhwbGljaXRseVxuICogdG9ybiBkb3duLlxuICpcbiAqIFR3byBoYW5kbGVycyBjb3ZlciBkaWZmZXJlbnQgZXhpdCBzY2VuYXJpb3M6XG4gKlxuICogLSBgYmVmb3JlRXhpdGAgXHUyMDE0IGZpcmVzIHdoZW4gdGhlIGV2ZW50IGxvb3AgZHJhaW5zIG5hdHVyYWxseS4gQWxsb3dzIGZ1bGxcbiAqICAgYXN5bmMgdGVhcmRvd24gKHVucmVnaXN0ZXIgdmF1bHRzLCBkaXNwb3NlIHRyYW5zcG9ydHMpLiBEb2VzIE5PVCBmaXJlXG4gKiAgIHdoZW4gYHByb2Nlc3MuZXhpdCgpYCBpcyBjYWxsZWQgZGlyZWN0bHkuXG4gKlxuICogLSBgdW5oYW5kbGVkUmVqZWN0aW9uYCBcdTIwMTQgY2F0Y2hlcyBhc3luYyBlcnJvcnMgdGhhdCBieXBhc3MgYGNvcmVTZXR1cGAnc1xuICogICBjYXRjaCBibG9jay4gUGVyZm9ybXMgZnVsbCBhc3luYyB0ZWFyZG93biB3aGlsZSB3ZSBzdGlsbCBjYW4uXG4gKlxuICogLSBgZXhpdGAgXHUyMDE0IGZpcmVzIG9uIGV2ZXJ5IGV4aXQsIGluY2x1ZGluZyBgcHJvY2Vzcy5leGl0KClgLiBPbmx5IHN5bmNocm9ub3VzXG4gKiAgIHdvcmsgaXMgcG9zc2libGUsIHNvIHRoaXMgaGFuZGxlciBkb2VzIGJlc3QtZWZmb3J0IGNsZWFudXA6IGtpbGxzIGNoaWxkXG4gKiAgIHByb2Nlc3NlcyB2aWEgYGRpc3Bvc2VTeW5jKClgIGFuZCByZW1vdmVzIHRlbXAgdmF1bHQgZGlyZWN0b3JpZXMgd2l0aFxuICogICBgcm1TeW5jYC4gVW5yZWdpc3RlcmluZyB2YXVsdHMgKHdoaWNoIHJlcXVpcmVzIElQQyB3aXRoIE9ic2lkaWFuKSBpc1xuICogICBza2lwcGVkIFx1MjAxNCBhIHN0YWxlIHZhdWx0IGVudHJ5IGlzIGFuIGFjY2VwdGFibGUgdHJhZGUtb2ZmIHZzLiBsZWFrZWRcbiAqICAgcHJvY2Vzc2VzIGFuZCB0ZW1wIGRpcmVjdG9yaWVzLlxuICovXG5mdW5jdGlvbiByZWdpc3RlclByb2Nlc3NDbGVhbnVwSGFuZGxlcigpOiB2b2lkIHtcbiAgaWYgKGlzQ2xlYW51cEhhbmRsZXJSZWdpc3RlcmVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlzQ2xlYW51cEhhbmRsZXJSZWdpc3RlcmVkID0gdHJ1ZTtcblxuICBwcm9jZXNzLm9uKCdiZWZvcmVFeGl0JywgKCkgPT4ge1xuICAgIGlmIChhY3RpdmVTZXR1cHMuc2l6ZSA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duXSBQcm9jZXNzIGV4aXRpbmcgd2l0aCAke1N0cmluZyhhY3RpdmVTZXR1cHMuc2l6ZSl9IHNldHVwKHMpIG5vdCB0b3JuIGRvd24uIENsZWFuaW5nIHVwLi4uYCk7XG5cbiAgICBmb3IgKGNvbnN0IHJlc3VsdCBvZiBhY3RpdmVTZXR1cHMpIHtcbiAgICAgIGNvcmVUZWFyZG93bihyZXN1bHQpLmNhdGNoKChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bjoke3Jlc3VsdC50cmFuc3BvcnRMYWJlbH1dIFByb2Nlc3MgY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcHJvY2Vzcy5vbigndW5oYW5kbGVkUmVqZWN0aW9uJywgKCkgPT4ge1xuICAgIGlmIChhY3RpdmVTZXR1cHMuc2l6ZSA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duXSBVbmhhbmRsZWQgcmVqZWN0aW9uIGRldGVjdGVkLiBUZWFyaW5nIGRvd24gJHtTdHJpbmcoYWN0aXZlU2V0dXBzLnNpemUpfSBhY3RpdmUgc2V0dXAocykuLi5gKTtcbiAgICBmb3IgKGNvbnN0IHJlc3VsdCBvZiBhY3RpdmVTZXR1cHMpIHtcbiAgICAgIGNvcmVUZWFyZG93bihyZXN1bHQpLmNhdGNoKChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bjoke3Jlc3VsdC50cmFuc3BvcnRMYWJlbH1dIFJlamVjdGlvbiBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfSk7XG4gICAgfVxuICB9KTtcblxuICBwcm9jZXNzLm9uKCdleGl0JywgKCkgPT4ge1xuICAgIGlmIChhY3RpdmVTZXR1cHMuc2l6ZSA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duXSBTeW5jIGNsZWFudXA6ICR7U3RyaW5nKGFjdGl2ZVNldHVwcy5zaXplKX0gb3JwaGFuZWQgc2V0dXAocykuYCk7XG4gICAgZm9yIChjb25zdCByZXN1bHQgb2YgYWN0aXZlU2V0dXBzKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXN1bHQudHJhbnNwb3J0LmRpc3Bvc2VTeW5jPy4oKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gU3luYyB0cmFuc3BvcnQgY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIHJtU3luYyhyZXN1bHQudGVtcG9yYXJ5VmF1bHQucGF0aCwgeyBmb3JjZTogdHJ1ZSwgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd246JHtyZXN1bHQudHJhbnNwb3J0TGFiZWx9XSBTeW5jIHZhdWx0IGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgICByZWxlYXNlU2V0dXBMb2NrKHJlc3VsdCk7XG4gICAgfVxuICAgIGFjdGl2ZVNldHVwcy5jbGVhcigpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZWxlYXNlcyBhbmQgZm9yZ2V0cyB0aGUgc2V0dXAgbG9jayBhc3NvY2lhdGVkIHdpdGggYSByZXN1bHQsIGlmIGFueS5cbiAqXG4gKiBAcGFyYW0gcmVzdWx0IC0gVGhlIHNldHVwIHJlc3VsdCB3aG9zZSBsb2NrIHNob3VsZCBiZSByZWxlYXNlZC5cbiAqL1xuZnVuY3Rpb24gcmVsZWFzZVNldHVwTG9jayhyZXN1bHQ6IENvcmVTZXR1cFJlc3VsdCk6IHZvaWQge1xuICBjb25zdCBsb2NrID0gc2V0dXBMb2Nrcy5nZXQocmVzdWx0KTtcbiAgaWYgKGxvY2spIHtcbiAgICBsb2NrLnJlbGVhc2UoKTtcbiAgICBzZXR1cExvY2tzLmRlbGV0ZShyZXN1bHQpO1xuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgdGhlIGRpc3QgcGF0aCB0byB1c2UgZm9yIGludGVncmF0aW9uIHRlc3RzLlxuICpcbiAqIFBpY2tzIHdoaWNoZXZlciBvZiBgZGlzdC9kZXZgIGFuZCBgZGlzdC9idWlsZGAgaGFzIGEgbmV3ZXIgYG1haW4uanNgLlxuICogSWYgb25seSBvbmUgZXhpc3RzLCB0aGF0IG9uZSBpcyB1c2VkLiBUaHJvd3MgaWYgbmVpdGhlciBleGlzdHMuXG4gKlxuICogQHBhcmFtIHByb2plY3RSb290IC0gVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHByb2plY3Qgcm9vdC5cbiAqIEByZXR1cm5zIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSBjaG9zZW4gZGlzdCBmb2xkZXIuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVEaXN0UGF0aChwcm9qZWN0Um9vdDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgZGV2UGF0aCA9IGpvaW4ocHJvamVjdFJvb3QsIERJU1RfREVWKTtcbiAgY29uc3QgYnVpbGRQYXRoID0gam9pbihwcm9qZWN0Um9vdCwgRElTVF9CVUlMRCk7XG4gIGNvbnN0IGRldk1haW5KcyA9IGpvaW4oZGV2UGF0aCwgTUFJTl9KUyk7XG4gIGNvbnN0IGJ1aWxkTWFpbkpzID0gam9pbihidWlsZFBhdGgsIE1BSU5fSlMpO1xuICBjb25zdCBkZXZTdGF0ID0gZXhpc3RzU3luYyhkZXZNYWluSnMpID8gYXdhaXQgc3RhdChkZXZNYWluSnMpIDogbnVsbDtcbiAgY29uc3QgYnVpbGRTdGF0ID0gZXhpc3RzU3luYyhidWlsZE1haW5KcykgPyBhd2FpdCBzdGF0KGJ1aWxkTWFpbkpzKSA6IG51bGw7XG5cbiAgaWYgKGRldlN0YXQgJiYgYnVpbGRTdGF0KSB7XG4gICAgcmV0dXJuIGRldlN0YXQubXRpbWUgPiBidWlsZFN0YXQubXRpbWUgPyBkZXZQYXRoIDogYnVpbGRQYXRoO1xuICB9XG5cbiAgaWYgKGRldlN0YXQpIHtcbiAgICByZXR1cm4gZGV2UGF0aDtcbiAgfVxuXG4gIGlmIChidWlsZFN0YXQpIHtcbiAgICByZXR1cm4gYnVpbGRQYXRoO1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKCdObyBidWlsZCBmb3VuZC4gUnVuIGBucG0gcnVuIGJ1aWxkYCBvciBgbnBtIHJ1biBkZXZgIGZpcnN0LicpO1xufVxuXG4vKipcbiAqIFJlZnVzZXMgYSBtb2JpbGUgcnVuIGZvciBhIGRlc2t0b3Atb25seSBwbHVnaW4sIGJlZm9yZSBhbnl0aGluZyBjb3N0bHkgaGFzIGhhcHBlbmVkLlxuICpcbiAqIEEgbm8tb3AgdW5sZXNzIGEgcGx1Z2luIGlzIGJlaW5nIGluc3RhbGxlZCBvbnRvIGEgbW9iaWxlIHRyYW5zcG9ydC4gT3RoZXJ3aXNlIHJlYWRzIGBtYW5pZmVzdC5qc29uYFxuICogb3V0IG9mIHRoZSBuZXdlciBkaXN0IGZvbGRlciBcdTIwMTQgbm8gZGV2aWNlLCBubyBsb2NrLCBubyBzd2VlcC4gV2hlbiB0aGVyZSBpcyBubyByZWFkYWJsZSBidWlsZCB0aGUgY2hlY2tcbiAqIHNpbXBseSBkb2VzIG5vdCBmaXJlOiBhIG1pc3Npbmcgb3IgbWFsZm9ybWVkIGJ1aWxkIGlzIGEgZGlmZmVyZW50IHByb2JsZW0sIGFuZCB7QGxpbmsgcmVzb2x2ZURpc3RQYXRofVxuICogZG93bnN0cmVhbSBhbHJlYWR5IHJlcG9ydHMgaXQgaW4gaXRzIG93biB3b3Jkcy5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHRyYW5zcG9ydCBsYWJlbCwgcHJvamVjdCByb290LCB0cmFuc3BvcnQgb3B0aW9ucyBhbmQgd2hldGhlciBhIHBsdWdpbiBpcyBpbnN0YWxsZWQuXG4gKiBAdGhyb3dzIHtEZXNrdG9wT25seVBsdWdpblNraXBFcnJvcn0gV2hlbiB0aGUgbWFuaWZlc3Qgc2F5cyBgaXNEZXNrdG9wT25seTogdHJ1ZWAuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHNraXBJZkRlc2t0b3BPbmx5KHBhcmFtczogU2tpcElmRGVza3RvcE9ubHlQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBsYWJlbCwgcHJvamVjdFJvb3QsIHNob3VsZEluc3RhbGxQbHVnaW4sIHRyYW5zcG9ydE9wdGlvbnMgfSA9IHBhcmFtcztcblxuICBpZiAoIXNob3VsZEluc3RhbGxQbHVnaW4gfHwgIWNoZWNrSXNNb2JpbGVUcmFuc3BvcnQodHJhbnNwb3J0T3B0aW9ucykpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBsZXQgbWFuaWZlc3RKc29uOiBQbHVnaW5NYW5pZmVzdDtcbiAgdHJ5IHtcbiAgICBjb25zdCBkaXN0UGF0aCA9IGF3YWl0IHJlc29sdmVEaXN0UGF0aChwcm9qZWN0Um9vdCk7XG4gICAgbWFuaWZlc3RKc29uID0gSlNPTi5wYXJzZShhd2FpdCByZWFkRmlsZShqb2luKGRpc3RQYXRoLCAnbWFuaWZlc3QuanNvbicpLCAndXRmLTgnKSkgYXMgUGx1Z2luTWFuaWZlc3Q7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICghbWFuaWZlc3RKc29uLmlzRGVza3RvcE9ubHkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBsb2coXG4gICAgYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gU0tJUFBFRDogXCIke21hbmlmZXN0SnNvbi5pZH1cIiBpcyBkZXNrdG9wLW9ubHkgKGlzRGVza3RvcE9ubHk6IHRydWUpLCBgXG4gICAgICArICdzbyBpdCBoYXMgbm8gbW9iaWxlIGludGVncmF0aW9uIHRlc3RzIHRvIHJ1bi4gTm8gZW11bGF0b3Igd2FzIGJvb3RlZCBhbmQgbm8gQXBwaXVtIHNlcnZlciB3YXMgc3RhcnRlZC4nXG4gICk7XG4gIHRocm93IG5ldyBEZXNrdG9wT25seVBsdWdpblNraXBFcnJvcihtYW5pZmVzdEpzb24uaWQpO1xufVxuXG4vKipcbiAqIFJlbW92ZXMgdGhlIGhvc3Qtc2lkZSB0ZW1wIGRpcmVjdG9yaWVzIGVhcmxpZXIgcnVucyBsZWFrZWQuXG4gKlxuICogUnVucyBhdCBib3RoIGVuZHMgb2YgYSBydW46IGF0IHNldHVwIGl0IGhhcHBlbnMgKipiZWZvcmUqKiB0aGUgdHJhbnNwb3J0IGlzXG4gKiBjcmVhdGVkLCBzbyBpdCBkb2VzIG5vdCBkZXBlbmQgb24gYSBoZWFsdGh5IE9ic2lkaWFuL1dlYlZpZXcgXHUyMDE0IHdoaWNoIGlzXG4gKiBleGFjdGx5IHdoYXQgYSBmYWlsZWQgcnVuIG5vIGxvbmdlciBoYXMsIGFuZCB3aHkgYSBmYWlsZWQgcnVuIGNhbm5vdCBjbGVhbiB1cFxuICogYWZ0ZXIgaXRzZWxmLiBBZ2UtZ2F0ZWQgKHNlZSBgbGVmdG92ZXJNYXhBZ2VJbk1pbGxpc2Vjb25kc2ApIGJlY2F1c2UgZGVza3RvcFxuICogcnVucyBhcmUgbm90IHNlcmlhbGl6ZWQgYW5kIGV2ZXJ5IHByb2plY3Qgb24gdGhlIG1hY2hpbmUgc2hhcmVzIG9uZSB0ZW1wXG4gKiBkaXJlY3RvcnkuIEJlc3QtZWZmb3J0OiBhIHN3ZWVwIG5ldmVyIGZhaWxzIHRoZSBydW4gaXQgaXMgY2xlYW5pbmcgdXAgZm9yLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgc3dlZXAgcGFyYW1ldGVycy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc3dlZXBMZWZ0b3ZlcnMocGFyYW1zOiBTd2VlcExlZnRvdmVyc1BhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7IGxhYmVsLCBwaGFzZSwgdHJhbnNwb3J0T3B0aW9ucyB9ID0gcGFyYW1zO1xuICBpZiAoIXdpbGxTd2VlcExlZnRvdmVycyh0cmFuc3BvcnRPcHRpb25zKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc3dlZXBIb3N0TGVmdG92ZXJzKHtcbiAgICAgIGV4Y2x1ZGVkTmFtZXM6IHBhcmFtcy5leGNsdWRlZE5hbWVzLFxuICAgICAgbWF4QWdlSW5NaWxsaXNlY29uZHM6IHJlc29sdmVMZWZ0b3Zlck1heEFnZUluTWlsbGlzZWNvbmRzKHRyYW5zcG9ydE9wdGlvbnMpXG4gICAgfSk7XG4gICAgaWYgKHJlc3VsdC5yZW1vdmVkQ291bnQgPiAwIHx8IHJlc3VsdC5mYWlsZWRDb3VudCA+IDApIHtcbiAgICAgIGxvZyhcbiAgICAgICAgYFtpbnRlZ3JhdGlvbi0ke3BoYXNlfToke2xhYmVsfV0gU3dlcHQgJHtTdHJpbmcocmVzdWx0LnJlbW92ZWRDb3VudCl9IGxlZnRvdmVyIHRlbXAgZGlyZWN0b3IoaWVzKSBgXG4gICAgICAgICAgKyBgZnJvbSBlYXJsaWVyIHJ1bnMgKCR7U3RyaW5nKHJlc3VsdC5mYWlsZWRDb3VudCl9IHN0aWxsIGluIHVzZSkuYFxuICAgICAgKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tJHtwaGFzZX06JHtsYWJlbH1dIExlZnRvdmVyIHN3ZWVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICB9XG59XG5cbi8qKlxuICogUGVyZm9ybXMgdGhlIGFzeW5jIHRlYXJkb3duIHdvcmsgKHZhdWx0IGRpc3Bvc2FsICsgdHJhbnNwb3J0IGRpc3Bvc2FsKS5cbiAqXG4gKiBAcGFyYW0gcmVzdWx0IC0gVGhlIHNldHVwIHJlc3VsdCB0byB0ZWFyIGRvd24uXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHRlYXJkb3duQXN5bmMocmVzdWx0OiBDb3JlU2V0dXBSZXN1bHQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgdHJ5IHtcbiAgICBhd2FpdCByZXN1bHQudGVtcG9yYXJ5VmF1bHQuZGlzcG9zZShyZXN1bHQudHJhbnNwb3J0KTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bjoke3Jlc3VsdC50cmFuc3BvcnRMYWJlbH1dIFZhdWx0IGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhlcnJvcil9YCk7XG4gIH1cblxuICB0cnkge1xuICAgIGF3YWl0IHJlc3VsdC50cmFuc3BvcnQuZGlzcG9zZT8uKCk7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd246JHtyZXN1bHQudHJhbnNwb3J0TGFiZWx9XSBUcmFuc3BvcnQgY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIkFBWUE7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUDtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1AsT0FBTyxXQUFXLG1CQUFtQjtBQUNyQyxTQUFTLGNBQWMsYUFBYTtBQVFwQyxTQUFTLGdDQUFnQztBQUN6QyxTQUFTLGtDQUFrQztBQUMzQztBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMscUJBQXFCO0FBQzlCLFNBQVMsc0JBQXNCO0FBQy9CLFNBQVMsaUNBQWlDO0FBQzFDO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMsV0FBVztBQUNwQjtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1A7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUCxTQUFTLHNCQUFzQjtBQUMvQixTQUFTLHVCQUF1QjtBQUNoQyxTQUFTLDJC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
466
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2dsb2JhbC1zZXR1cC1jb3JlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogRnJhbWV3b3JrLWFnbm9zdGljIGNvcmUgbG9naWMgZm9yIGludGVncmF0aW9uIHRlc3QgZ2xvYmFsIHNldHVwIGFuZCB0ZWFyZG93bi5cbiAqXG4gKiBWaXRlc3QgYW5kIEplc3QgYWRhcHRlcnMgZGVsZWdhdGUgdG8gdGhlc2UgZnVuY3Rpb25zLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIHNldHVwIGNvdmVyZWQgYnkgaW50ZWdyYXRpb24gdGVzdHMsIG5vdCB1bml0IHRlc3RzLiAqL1xuXG5pbXBvcnQgdHlwZSB7IFBsdWdpbk1hbmlmZXN0IH0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQge1xuICBleGlzdHNTeW5jLFxuICBybVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICByZWFkRmlsZSxcbiAgc3RhdFxufSBmcm9tICdub2RlOmZzL3Byb21pc2VzJztcbmltcG9ydCB7XG4gIGJhc2VuYW1lLFxuICBqb2luLFxuICByZWxhdGl2ZSxcbiAgc2VwXG59IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgcHJvY2VzcywgeyBsb2FkRW52RmlsZSB9IGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5pbXBvcnQgeyBzZXRUaW1lb3V0IGFzIHNsZWVwIH0gZnJvbSAnbm9kZTp0aW1lcnMvcHJvbWlzZXMnO1xuXG5pbXBvcnQgdHlwZSB7IEVuYWJsZVBsdWdpblJlc3VsdCB9IGZyb20gJy4vZW5hYmxlLXBsdWdpbi5tanMnO1xuaW1wb3J0IHR5cGUgeyBTZXR1cExvY2sgfSBmcm9tICcuL3NldHVwLWxvY2subWpzJztcbmltcG9ydCB0eXBlIHsgUG9wdWxhdGVGaWxlc1BhcmFtcyB9IGZyb20gJy4vdGVtcG9yYXJ5LXZhdWx0Lm1qcyc7XG5pbXBvcnQgdHlwZSB7IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB9IGZyb20gJy4vdHJhbnNwb3J0LW9wdGlvbnMubWpzJztcbmltcG9ydCB0eXBlIHsgT2JzaWRpYW5UcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydC5tanMnO1xuXG5pbXBvcnQgeyBERUZBVUxUX0NPTkZJR19ESVJFQ1RPUlkgfSBmcm9tICcuL2NvbmZpZy1kaXJlY3RvcnkubWpzJztcbmltcG9ydCB7IERlc2t0b3BPbmx5UGx1Z2luU2tpcEVycm9yIH0gZnJvbSAnLi9kZXNrdG9wLW9ubHktcGx1Z2luLXNraXAtZXJyb3IubWpzJztcbmltcG9ydCB7XG4gIGVuYWJsZVBsdWdpbldpdGhFcnJvckNhcHR1cmUsXG4gIGdldEdlbmVyaWNQbHVnaW5Mb2FkRmFpbHVyZU1lc3NhZ2Vcbn0gZnJvbSAnLi9lbmFibGUtcGx1Z2luLm1qcyc7XG5pbXBvcnQgeyBlcnJvclRvU3RyaW5nIH0gZnJvbSAnLi9lcnJvci10by1zdHJpbmcubWpzJztcbmltcG9ydCB7IGV2YWxJbk9ic2lkaWFuIH0gZnJvbSAnLi9ldmFsLWluLW9ic2lkaWFuLm1qcyc7XG5pbXBvcnQgeyBlbnN1cmVIZWFkbGVzc1ZhdWx0Q29uZmlnIH0gZnJvbSAnLi9oZWFkbGVzcy12YXVsdC1jb25maWcubWpzJztcbmltcG9ydCB7XG4gIHJlc29sdmVMZWZ0b3Zlck1heEFnZUluTWlsbGlzZWNvbmRzLFxuICBzd2VlcEhvc3RMZWZ0b3ZlcnMsXG4gIHdpbGxTd2VlcExlZnRvdmVyc1xufSBmcm9tICcuL2xlZnRvdmVyLWNsZWFudXAubWpzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLm1qcyc7XG5pbXBvcnQge1xuICBjb21wdXRlQmFja29mZkRlbGF5SW5NaWxsaXNlY29uZHMsXG4gIHJlc29sdmVQbHVnaW5FbmFibGVSZXRyeUNvdW50LFxuICByZXNvbHZlUGx1Z2luRW5hYmxlUmV0cnlEZWxheUluTWlsbGlzZWNvbmRzLFxuICBzaG91bGRSZXRyeVBsdWdpbkVuYWJsZVxufSBmcm9tICcuL3BsdWdpbi1lbmFibGUtcmV0cnkubWpzJztcbmltcG9ydCB7XG4gIGFjcXVpcmVTZXR1cExvY2ssXG4gIEFORFJPSURfU0VUVVBfTE9DS19TQ09QRVxufSBmcm9tICcuL3NldHVwLWxvY2subWpzJztcbmltcG9ydCB7XG4gIGNoZWNrSXNCdWlsZFN0YWxlLFxuICBmaW5kTmV3ZXN0U291cmNlTW9kaWZpY2F0aW9uLFxuICB3aWxsRmFpbE9uU3RhbGVCdWlsZFxufSBmcm9tICcuL3N0YWxlLWJ1aWxkLWRldGVjdGlvbi5tanMnO1xuaW1wb3J0IHsgU3RhbGVCdWlsZEVycm9yIH0gZnJvbSAnLi9zdGFsZS1idWlsZC1lcnJvci5tanMnO1xuaW1wb3J0IHsgVGVtcG9yYXJ5VmF1bHQgfSBmcm9tICcuL3RlbXBvcmFyeS12YXVsdC5tanMnO1xuaW1wb3J0IHsgQXBwaXVtVHJhbnNwb3J0IH0gZnJvbSAnLi90cmFuc3BvcnQtYXBwaXVtLm1qcyc7XG5pbXBvcnQgeyBEZXNrdG9wQ2RwVHJhbnNwb3J0IH0gZnJvbSAnLi90cmFuc3BvcnQtZGVza3RvcC1jZHAubWpzJztcbmltcG9ydCB7IGNyZWF0ZVRyYW5zcG9ydEZyb21PcHRpb25zIH0gZnJvbSAnLi90cmFuc3BvcnQtZmFjdG9yeS5tanMnO1xuaW1wb3J0IHtcbiAgY2hlY2tJc01vYmlsZVRyYW5zcG9ydCxcbiAgcmVzb2x2ZU93bmVkQ29uZmlnRGlyZWN0b3J5XG59IGZyb20gJy4vdHJhbnNwb3J0LW9wdGlvbnMubWpzJztcbmltcG9ydCB7IGluc3RhbGxQbHVnaW5JbnRvVmF1bHQgfSBmcm9tICcuL3ZhdWx0LXBsdWdpbi1pbnN0YWxsLm1qcyc7XG5cbmNvbnN0IERFRkFVTFRfVFJBTlNQT1JUX1RZUEUgPSAnb2JzaWRpYW4tY2RwJztcbmNvbnN0IERJU1RfREVWID0gJ2Rpc3QvZGV2JztcbmNvbnN0IERJU1RfQlVJTEQgPSAnZGlzdC9idWlsZCc7XG5jb25zdCBNQUlOX0pTID0gJ21haW4uanMnO1xuXG4vKipcbiAqIFRyYWNrcyBzZXR1cHMgdGhhdCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5IGJ1dCBoYXZlbid0IGJlZW4gdG9ybiBkb3duIHlldC5cbiAqIFVzZWQgYnkgdGhlIGBiZWZvcmVFeGl0YCBoYW5kbGVyIHRvIGNsZWFuIHVwIHdoZW4gYSB0ZXN0IHJ1bm5lciBleGl0c1xuICogd2l0aG91dCBjYWxsaW5nIHRlYXJkb3duIChlLmcuLCB3aGVuIG9uZSBwcm9qZWN0J3Mgc2V0dXAgZmFpbHMgYW5kIHRoZVxuICogcnVubmVyIGFib3J0cyBiZWZvcmUgdGVhcmluZyBkb3duIGFscmVhZHktaW5pdGlhbGl6ZWQgcHJvamVjdHMpLlxuICovXG5jb25zdCBhY3RpdmVTZXR1cHMgPSBuZXcgU2V0PENvcmVTZXR1cFJlc3VsdD4oKTtcbmNvbnN0IGRpc3Bvc2VkUmVzdWx0cyA9IG5ldyBXZWFrU2V0PENvcmVTZXR1cFJlc3VsdD4oKTtcbmxldCBpc0NsZWFudXBIYW5kbGVyUmVnaXN0ZXJlZCA9IGZhbHNlO1xuXG4vKipcbiAqIFRoZSBjcm9zcy1wcm9jZXNzIHNldHVwIGxvY2sgaGVsZCBieSBlYWNoIGFjdGl2ZSBzZXR1cC4gUmVsZWFzZWQgd2hlbiB0aGVcbiAqIHNldHVwIGlzIHRvcm4gZG93biAob3IgYnkgdGhlIHByb2Nlc3MgY2xlYW51cCBoYW5kbGVycyksIGFsbG93aW5nIGEgY29tcGV0aW5nXG4gKiBydW4gdG8gcHJvY2VlZC4gU2VlIHtAbGluayBhY3F1aXJlU2V0dXBMb2NrfS5cbiAqL1xuY29uc3Qgc2V0dXBMb2NrcyA9IG5ldyBNYXA8Q29yZVNldHVwUmVzdWx0LCBTZXR1cExvY2s+KCk7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGNvcmVTZXR1cH0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29yZVNldHVwT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBDb21tdW5pdHktcGx1Z2luIGlkcyB0byBlbmFibGUgaW4gdGhlIHZhdWx0ICoqaW4gYWRkaXRpb24gdG8qKiB0aGVcbiAgICogcGx1Z2luLXVuZGVyLXRlc3QsIGFmdGVyIGl0IGlzIGVuYWJsZWQuIEVhY2ggaWQncyBidWlsdCBmaWxlcyBtdXN0IGFscmVhZHkgYmVcbiAgICogcHJlc2VudCB1bmRlciBgLm9ic2lkaWFuL3BsdWdpbnMvPGlkPi9gIFx1MjAxNCBzZWVkIHRoZW0gdmlhIHtAbGluayBDb3JlU2V0dXBPcHRpb25zLnBvcHVsYXRlfVxuICAgKiAoZS5nLiB3aXRoIGBidWlsZERlbW9WYXVsdFBvcHVsYXRlYCkuIEVuYWJsaW5nIGdvZXMgdGhyb3VnaCB0aGUgc2FtZVxuICAgKiByZXRyeS9sb2FkLXZlcmlmeSBwYXRoIGFzIHRoZSBwbHVnaW4tdW5kZXItdGVzdC4gQ29tcG9zZXMgd2l0aFxuICAgKiBgaW5zdGFsbFBsdWdpbjogZmFsc2VgIChlbmFibGUgZXh0cmFzIGludG8gYW4gb3RoZXJ3aXNlIHBsdWdpbi1sZXNzIHZhdWx0KS5cbiAgICovXG4gIHJlYWRvbmx5IGVuYWJsZUNvbW11bml0eVBsdWdpbnM/OiByZWFkb25seSBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogV2hldGhlciB0byBpbnN0YWxsIGFuZCBlbmFibGUgdGhlIGJ1aWx0IHBsdWdpbiBpbiB0aGUgdGVtcCB2YXVsdC4gRGVmYXVsdHNcbiAgICogdG8gYHRydWVgLiBTZXQgdG8gYGZhbHNlYCBmb3IgYSAqKm5vbi1wbHVnaW4qKiBjb25zdW1lciAoZS5nLiBhIHR5cGluZ3NcbiAgICogY3Jhd2xlcikgdGhhdCBvbmx5IG5lZWRzIGEgcmVnaXN0ZXJlZCwgZW1wdHkgdmF1bHQgdG8gYGV2YWxJbk9ic2lkaWFuYFxuICAgKiBhZ2FpbnN0OiB0aGUgcGx1Z2luIGBkaXN0YC9gbWFuaWZlc3QuanNvbmAgcmVhZCwgdGhlIGNvcHkgaW50byB0aGUgY29uZmlnXG4gICAqIGZvbGRlcidzIGBwbHVnaW5zL2AsIHRoZSBgY29tbXVuaXR5LXBsdWdpbnMuanNvbmAgd3JpdGUsIGFuZCB0aGUgZW5hYmxlIHN0ZXBcbiAgICogYXJlIGFsbCBza2lwcGVkLCB3aGlsZSB0aGUgdHJhbnNwb3J0LCB0ZW1wIHZhdWx0LCByZWdpc3RyYXRpb24sIGFuZFxuICAgKiB3b3JrZXItZmFjaW5nIGVuZHBvaW50IHByb3Zpc2lvbmluZyBzdGlsbCBydW4gdW5jaGFuZ2VkLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5zdGFsbFBsdWdpbj86IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEZpbGVzIGFuZCBmb2xkZXJzIHRvIHdyaXRlIGludG8gdGhlIHZhdWx0ICoqYmVmb3JlKiogT2JzaWRpYW4gb3BlbnMgaXQsIHNvXG4gICAqIGl0cyBzdGFydHVwIHNjYW4gaW5kZXhlcyB0aGVtIGluIG9uZSBwYXNzIChzZWUge0BsaW5rIFRlbXBvcmFyeVZhdWx0LnBvcHVsYXRlfSkuXG4gICAqIFVzZSB0aGlzIGZvciBsYXJnZSBmaXh0dXJlcyBcdTIwMTQgd3JpdGluZyB0aG91c2FuZHMgb2Ygbm90ZXMgYWZ0ZXIgb3BlbiBhbmRcbiAgICogZm9yY2luZyBhIHJlLXNjYW4gaXMgZmFyIHNsb3dlciBhbmQgbGVzcyByZWxpYWJsZS5cbiAgICpcbiAgICogS2V5cyBuYW1pbmcgdGhlIGNvbmZpZyBmb2xkZXIgYXJlIHdyaXR0ZW4gYXMgYC5vYnNpZGlhbi9cdTIwMjZgOyB1bmRlciBhXG4gICAqIGBjb25maWdEaXJlY3RvcnlgIG92ZXJyaWRlIHtAbGluayByZW1hcENvbmZpZ0RpcmVjdG9yeUtleXN9IHJlZGlyZWN0cyB0aGVtIHRvXG4gICAqIHRoZSBmb2xkZXIgdGhlIHZhdWx0IHdpbGwgYWN0dWFsbHkgcmVhZCwgc28gYSBtYXAgZG9lcyBub3QgaGF2ZSB0byBjYXJyeSBhXG4gICAqIHNlY29uZCBjb3B5IG9mIHRoZSBvdmVycmlkZS5cbiAgICovXG4gIHJlYWRvbmx5IHBvcHVsYXRlPzogUG9wdWxhdGVGaWxlc1BhcmFtcyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVHJhbnNwb3J0IG9wdGlvbnMuIFdoZW4gb21pdHRlZCwgdXNlcyBhbiBvZmYtc2NyZWVuIG93bmVkIGRlc2t0b3AgaW5zdGFuY2UuXG4gICAqL1xuICByZWFkb25seSB0cmFuc3BvcnRPcHRpb25zPzogT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFJlc3VsdCByZXR1cm5lZCBieSB7QGxpbmsgY29yZVNldHVwfSwgdXNlZCBieSBmcmFtZXdvcmsgYWRhcHRlcnNcbiAqIHRvIHBhc3MgY29udGV4dCB0byB0ZXN0IHdvcmtlcnMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29yZVNldHVwUmVzdWx0IHtcbiAgLyoqXG4gIFRoZSB0ZW1wb3JhcnkgdmF1bHQgY3JlYXRlZCBkdXJpbmcgc2V0dXAuXG4gICAqL1xuICByZWFkb25seSB0ZW1wb3JhcnlWYXVsdDogVGVtcG9yYXJ5VmF1bHQ7XG5cbiAgLyoqXG4gIFRoZSB0cmFuc3BvcnQgaW5zdGFuY2UgdXNlZCBkdXJpbmcgc2V0dXAuXG4gICAqL1xuICByZWFkb25seSB0cmFuc3BvcnQ6IE9ic2lkaWFuVHJhbnNwb3J0O1xuXG4gIC8qKlxuICBTaG9ydCBsYWJlbCBmb3IgbG9nIG1lc3NhZ2VzIChlLmcuIGBcIm9ic2lkaWFuLWNkcFwiYCkuXG4gICAqL1xuICByZWFkb25seSB0cmFuc3BvcnRMYWJlbDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgdHJhbnNwb3J0IG9wdGlvbnMgdGhhdCB3ZXJlIHJlc29sdmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0T3B0aW9uczogT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBhc3NlcnRCdWlsZElzRnJlc2h9LlxuICovXG5pbnRlcmZhY2UgQXNzZXJ0QnVpbGRJc0ZyZXNoUGFyYW1zIHtcbiAgLyoqXG4gIFNob3J0IGxhYmVsIGZvciBsb2cgbWVzc2FnZXMuXG4gICAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgcHJvamVjdCByb290IGhvbGRpbmcgYm90aCB0aGUgc291cmNlcyBhbmQgdGhlIGRpc3QgZm9sZGVyLlxuICAgKi9cbiAgcmVhZG9ubHkgcHJvamVjdFJvb3Q6IHN0cmluZztcblxuICAvKipcbiAgV2hldGhlciBhIHBsdWdpbiBpcyBiZWluZyBpbnN0YWxsZWQgYXQgYWxsIFx1MjAxNCBhIHZhdWx0IHRoYXQgc3RheXMgZW1wdHkgaW5zdGFsbHMgbm8gYnVpbGQgdG8gYmUgc3RhbGUuXG4gICAqL1xuICByZWFkb25seSBzaG91bGRJbnN0YWxsUGx1Z2luOiBib29sZWFuO1xuXG4gIC8qKlxuICBUaGUgcmVzb2x2ZWQgdHJhbnNwb3J0IG9wdGlvbnMgKHNvdXJjZSBvZiB7QGxpbmsgT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zLnNob3VsZEZhaWxPblN0YWxlQnVpbGR9KS5cbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydE9wdGlvbnM6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgY29weVBsdWdpbkludG9WYXVsdH0uXG4gKi9cbmludGVyZmFjZSBDb3B5UGx1Z2luSW50b1ZhdWx0UGFyYW1zIHtcbiAgLyoqXG4gIFRoZSBjb25maWcgZm9sZGVyIHRoZSB2YXVsdCB3aWxsIHJlYWQsIHdoZW4gb3ZlcnJpZGRlbiBhd2F5IGZyb20gYC5vYnNpZGlhbmAgXHUyMDE0IHRoZSByZXNvbHZlZFxuICB7QGxpbmsgcmVzb2x2ZU93bmVkQ29uZmlnRGlyZWN0b3J5fSB2YWx1ZSwgd2hpY2ggaXMgYHVuZGVmaW5lZGAgZm9yIE9ic2lkaWFuJ3Mgb3duIGRlZmF1bHQuXG4gICAqL1xuICByZWFkb25seSBjb25maWdEaXJlY3Rvcnk6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgU2hvcnQgbGFiZWwgZm9yIGxvZyBtZXNzYWdlcy5cbiAgICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBwcm9qZWN0IHJvb3QgdG8gcmVzb2x2ZSB0aGUgYnVpbHQgcGx1Z2luIGZyb20uXG4gICAqL1xuICByZWFkb25seSBwcm9qZWN0Um9vdDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgdGVtcCB2YXVsdCB0byBjb3B5IHRoZSBwbHVnaW4gaW50by5cbiAgICovXG4gIHJlYWRvbmx5IHRlbXBvcmFyeVZhdWx0OiBUZW1wb3JhcnlWYXVsdDtcblxuICAvKipcbiAgVGhlIHRyYW5zcG9ydCAodXNlZCBmb3IgdGhlIG1vYmlsZS9kZXNrdG9wLW9ubHkgY29tcGF0aWJpbGl0eSBjaGVjaykuXG4gICAqL1xuICByZWFkb25seSB0cmFuc3BvcnQ6IE9ic2lkaWFuVHJhbnNwb3J0O1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBlbmFibGVFeHRyYUNvbW11bml0eVBsdWdpbnN9LlxuICovXG5pbnRlcmZhY2UgRW5hYmxlRXh0cmFDb21tdW5pdHlQbHVnaW5zUGFyYW1zIHtcbiAgLyoqXG4gIFNob3J0IGxhYmVsIGZvciBsb2cgbWVzc2FnZXMuXG4gICAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgaWRzIG9mIHRoZSBleHRyYSBjb21tdW5pdHkgcGx1Z2lucyB0byBlbmFibGUgKHRoZWlyIGJpbmFyaWVzIG11c3QgYWxyZWFkeSBiZSBpbiB0aGUgdmF1bHQpLlxuICAgKi9cbiAgcmVhZG9ubHkgcGx1Z2luSWRzOiByZWFkb25seSBzdHJpbmdbXTtcblxuICAvKipcbiAgVGhlIHRlbXAgdmF1bHQgdGhlIHBsdWdpbnMgd2VyZSBzZWVkZWQgaW50by5cbiAgICovXG4gIHJlYWRvbmx5IHRlbXBvcmFyeVZhdWx0OiBUZW1wb3JhcnlWYXVsdDtcblxuICAvKipcbiAgVGhlIHRyYW5zcG9ydCB0byBldmFsdWF0ZSBhZ2FpbnN0LlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydDtcblxuICAvKipcbiAgVGhlIHJlc29sdmVkIHRyYW5zcG9ydCBvcHRpb25zIChzb3VyY2Ugb2YgdGhlIHBsdWdpbi1lbmFibGUgcmV0cnkga25vYnMpLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0T3B0aW9uczogbnVsbCB8IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgZW5hYmxlUGx1Z2luSW5WYXVsdH0uXG4gKi9cbmludGVyZmFjZSBFbmFibGVQbHVnaW5JblZhdWx0UGFyYW1zIHtcbiAgLyoqXG4gIFNob3J0IGxhYmVsIGZvciBsb2cgbWVzc2FnZXMuXG4gICAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgaWQgb2YgdGhlIHBsdWdpbiB0byBlbmFibGUuXG4gICAqL1xuICByZWFkb25seSBwbHVnaW5JZDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgdGVtcCB2YXVsdCB0aGUgcGx1Z2luIHdhcyBjb3BpZWQgaW50by5cbiAgICovXG4gIHJlYWRvbmx5IHRlbXBvcmFyeVZhdWx0OiBUZW1wb3JhcnlWYXVsdDtcblxuICAvKipcbiAgVGhlIHRyYW5zcG9ydCB0byBldmFsdWF0ZSBhZ2FpbnN0LlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydDtcblxuICAvKipcbiAgVGhlIHJlc29sdmVkIHRyYW5zcG9ydCBvcHRpb25zIChzb3VyY2Ugb2YgdGhlIHBsdWdpbi1lbmFibGUgcmV0cnkga25vYnMpLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0T3B0aW9uczogbnVsbCB8IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgc2tpcElmRGVza3RvcE9ubHl9LlxuICovXG5pbnRlcmZhY2UgU2tpcElmRGVza3RvcE9ubHlQYXJhbXMge1xuICAvKipcbiAgU2hvcnQgbGFiZWwgZm9yIGxvZyBtZXNzYWdlcy5cbiAgICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBwcm9qZWN0IHJvb3QgdG8gcmVzb2x2ZSB0aGUgYnVpbHQgcGx1Z2luJ3MgbWFuaWZlc3QgZnJvbS5cbiAgICovXG4gIHJlYWRvbmx5IHByb2plY3RSb290OiBzdHJpbmc7XG5cbiAgLyoqXG4gIFdoZXRoZXIgYSBwbHVnaW4gaXMgYmVpbmcgaW5zdGFsbGVkIGF0IGFsbCAtLSB0aGVyZSBpcyBub3RoaW5nIHRvIGNoZWNrIHdoZW4gdGhlIHZhdWx0IHN0YXlzIGVtcHR5LlxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkSW5zdGFsbFBsdWdpbjogYm9vbGVhbjtcblxuICAvKipcbiAgVGhlIHJlc29sdmVkIHRyYW5zcG9ydCBvcHRpb25zLCB3aG9zZSBkaXNjcmltaW5hbnQgc2F5cyB3aGV0aGVyIHRoaXMgcnVuIGlzIG1vYmlsZS5cbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydE9wdGlvbnM6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgc3dlZXBMZWZ0b3ZlcnN9LlxuICovXG5pbnRlcmZhY2UgU3dlZXBMZWZ0b3ZlcnNQYXJhbXMge1xuICAvKipcbiAgRGlyZWN0b3J5IG5hbWVzIHRvIGtlZXAgcmVnYXJkbGVzcyBvZiBhZ2UgKGUuZy4gYSBjb25jdXJyZW50IHNldHVwJ3MgdmF1bHQpLlxuICAgKi9cbiAgcmVhZG9ubHkgZXhjbHVkZWROYW1lcz86IHJlYWRvbmx5IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBTaG9ydCBsYWJlbCBmb3IgbG9nIG1lc3NhZ2VzLlxuICAgKi9cbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblxuICAvKipcbiAgV2hpY2ggZW5kIG9mIHRoZSBydW4gaXMgc3dlZXBpbmcsIGZvciB0aGUgbG9nIHByZWZpeC5cbiAgICovXG4gIHJlYWRvbmx5IHBoYXNlOiAnc2V0dXAnIHwgJ3RlYXJkb3duJztcblxuICAvKipcbiAgVGhlIHJlc29sdmVkIHRyYW5zcG9ydCBvcHRpb25zIChzb3VyY2Ugb2YgdGhlIHN3ZWVwIGtub2JzKS5cbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydE9wdGlvbnM6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBGcmFtZXdvcmstYWdub3N0aWMgZ2xvYmFsIHNldHVwIGxvZ2ljLlxuICpcbiAqIExvYWRzIGAuZW52YCBmcm9tIHRoZSBwcm9qZWN0IHJvb3QsIGNyZWF0ZXMgYSB0cmFuc3BvcnQsIGNyZWF0ZXMgYW5kIHJlZ2lzdGVyc1xuICogYSB0ZW1wb3JhcnkgdmF1bHQgd2l0aCBPYnNpZGlhbiwgYW5kIFx1MjAxNCB1bmxlc3Mge0BsaW5rIENvcmVTZXR1cE9wdGlvbnMuaW5zdGFsbFBsdWdpbn1cbiAqIGlzIGBmYWxzZWAgXHUyMDE0IGNvcGllcyB0aGUgYnVpbHQgcGx1Z2luIGludG8gdGhlIHZhdWx0IGFuZCBlbmFibGVzIGl0LiBUaGVcbiAqIHBsdWdpbi1sZXNzIG1vZGUgc3RpbGwgbGF1bmNoZXMgdGhlIG93bmVkIGluc3RhbmNlIGFuZCBwdWJsaXNoZXMgaXRzXG4gKiB3b3JrZXItZmFjaW5nIGVuZHBvaW50LCBzbyBhIG5vbi1wbHVnaW4gY29uc3VtZXIgcmV1c2VzIHRoZSBzYW1lIGF0dGFjaCB3aXJpbmcuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFNldHVwIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyBUaGUgc2V0dXAgcmVzdWx0IGNvbnRhaW5pbmcgdGhlIHRlbXAgdmF1bHQsIHRyYW5zcG9ydCwgYW5kIHJlc29sdmVkIG9wdGlvbnMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb3JlU2V0dXAocGFyYW1zPzogQ29yZVNldHVwT3B0aW9ucyk6IFByb21pc2U8Q29yZVNldHVwUmVzdWx0PiB7XG4gIGNvbnN0IHByb2plY3RSb290ID0gZmluZFByb2plY3RSb290KCk7XG4gIGNvbnN0IGVudkZpbGVQYXRoID0gam9pbihwcm9qZWN0Um9vdCwgJy5lbnYnKTtcbiAgaWYgKGV4aXN0c1N5bmMoZW52RmlsZVBhdGgpKSB7XG4gICAgbG9hZEVudkZpbGUoZW52RmlsZVBhdGgpO1xuICB9XG5cbiAgY29uc3QgdHJhbnNwb3J0T3B0aW9ucyA9IHJlc29sdmVJbnRlZ3JhdGlvblRyYW5zcG9ydE9wdGlvbnMocGFyYW1zPy50cmFuc3BvcnRPcHRpb25zKTtcbiAgY29uc3QgbGFiZWwgPSB0cmFuc3BvcnRPcHRpb25zLnR5cGU7XG4gIGNvbnN0IHNob3VsZEluc3RhbGxQbHVnaW4gPSBwYXJhbXM/Lmluc3RhbGxQbHVnaW4gIT09IGZhbHNlO1xuXG4gIC8vIEJlZm9yZSB0aGUgbG9jaywgdGhlIHN3ZWVwIGFuZCBhYm92ZSBhbGwgdGhlIHRyYW5zcG9ydDogY3JlYXRpbmcgYSBtb2JpbGUgdHJhbnNwb3J0IGJvb3RzIHRoZSBBVkQgYW5kXG4gIC8vIGF1dG8tc3RhcnRzIEFwcGl1bSAofjcwIHMpIG9ubHkgdG8gcmVhY2ggdGhlIHNhbWUgY29uY2x1c2lvbiBmcm9tIGB0cmFuc3BvcnQuaXNNb2JpbGVgIGZ1cnRoZXIgZG93bi5cbiAgLy8gTmVpdGhlciBpbnB1dCBuZWVkcyBhIGRldmljZSAtLSB0aGUgbWFuaWZlc3QgaXMgb24gZGlzayBhbmQgdGhlIGRpc2NyaW1pbmFudCBhbHJlYWR5IHNheXMgbW9iaWxlLlxuICBhd2FpdCBza2lwSWZEZXNrdG9wT25seSh7IGxhYmVsLCBwcm9qZWN0Um9vdCwgc2hvdWxkSW5zdGFsbFBsdWdpbiwgdHJhbnNwb3J0T3B0aW9ucyB9KTtcblxuICAvLyBTYW1lIHBsYWNlLCBzYW1lIHJlYXNvbmluZzogdGhlIG5ld2VzdCBzb3VyY2UgYW5kIGBtYWluLmpzYCdzIG10aW1lIGFyZSBib3RoIG9uIGRpc2ssIHNvIGEgcnVuIGFib3V0IHRvXG4gIC8vIGluc3RhbGwgeWVzdGVyZGF5J3MgcGx1Z2luIGlzIHJlZnVzZWQgYmVmb3JlIGFuIEFWRCBib290cyByYXRoZXIgdGhhbiBhZnRlciBpdCBmYWlscyBjb25mdXNpbmdseS5cbiAgYXdhaXQgYXNzZXJ0QnVpbGRJc0ZyZXNoKHsgbGFiZWwsIHByb2plY3RSb290LCBzaG91bGRJbnN0YWxsUGx1Z2luLCB0cmFuc3BvcnRPcHRpb25zIH0pO1xuXG4gIGNvbnN0IGxvY2tTY29wZSA9IGdldExvY2tTY29wZSh0cmFuc3BvcnRPcHRpb25zKTtcblxuICBsZXQgbG9jazogU2V0dXBMb2NrIHwgdW5kZWZpbmVkO1xuICBpZiAobG9ja1Njb3BlICE9PSB1bmRlZmluZWQpIHtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gQWNxdWlyaW5nICcke2xvY2tTY29wZX0nIHNldHVwIGxvY2sgKHNlcmlhbGl6ZXMgYWdhaW5zdCBhbnkgY29uY3VycmVudCBpbnRlZ3JhdGlvbi10ZXN0IHJ1bikuLi5gKTtcbiAgICBsb2NrID0gYXdhaXQgYWNxdWlyZVNldHVwTG9jayh7IGxhYmVsLCBzY29wZTogbG9ja1Njb3BlIH0pO1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBTZXR1cCBsb2NrIGFjcXVpcmVkLmApO1xuICB9XG5cbiAgYXdhaXQgc3dlZXBMZWZ0b3ZlcnMoeyBsYWJlbCwgcGhhc2U6ICdzZXR1cCcsIHRyYW5zcG9ydE9wdGlvbnMgfSk7XG5cbiAgbGV0IHRyYW5zcG9ydDogT2JzaWRpYW5UcmFuc3BvcnQgfCB1bmRlZmluZWQ7XG4gIGxldCB0ZW1wb3JhcnlWYXVsdDogVGVtcG9yYXJ5VmF1bHQgfCB1bmRlZmluZWQ7XG5cbiAgdHJ5IHtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gQ3JlYXRpbmcgdHJhbnNwb3J0Li4uYCk7XG4gICAgdHJhbnNwb3J0ID0gYXdhaXQgY3JlYXRlVHJhbnNwb3J0RnJvbU9wdGlvbnModHJhbnNwb3J0T3B0aW9ucyk7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFRyYW5zcG9ydCBjcmVhdGVkOiAke3RyYW5zcG9ydC5jb25zdHJ1Y3Rvci5uYW1lfWApO1xuXG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFByb2plY3Qgcm9vdDogJHtwcm9qZWN0Um9vdH1gKTtcblxuICAgIHRlbXBvcmFyeVZhdWx0ID0gbmV3IFRlbXBvcmFyeVZhdWx0KCk7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIENyZWF0ZWQgdGVtcCB2YXVsdDogJHt0ZW1wb3JhcnlWYXVsdC5wYXRofWApO1xuXG4gICAgLypcbiAgICAgKiBXaGljaCBmb2xkZXIgdGhpcyB2YXVsdCB3aWxsIGFjdHVhbGx5IHJlYWQsIHJlc29sdmVkIG9uY2UgYW5kIGhhbmRlZCB0byBldmVyeSB3cml0ZXIgYmVsb3cuXG4gICAgICogRXZlcnkgcHJlLW9wZW4gd3JpdGUgaGFzIHRvIGFncmVlIG9uIGl0OiBvbmUgdGhhdCBoYXJkY29kZXMgYC5vYnNpZGlhbmAgdW5kZXIgYW4gb3ZlcnJpZGUgd3JpdGVzXG4gICAgICogc29tZXdoZXJlIG5vdGhpbmcgbG9va3MsIGFuZCBub3RoaW5nIHRocm93cyB0byBzYXkgc28uXG4gICAgICovXG4gICAgY29uc3QgY29uZmlnRGlyZWN0b3J5ID0gcmVzb2x2ZU93bmVkQ29uZmlnRGlyZWN0b3J5KHRyYW5zcG9ydE9wdGlvbnMpO1xuXG4gICAgbGV0IHBsdWdpbklkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICBpZiAoc2hvdWxkSW5zdGFsbFBsdWdpbikge1xuICAgICAgcGx1Z2luSWQgPSBhd2FpdCBjb3B5UGx1Z2luSW50b1ZhdWx0KHsgY29uZmlnRGlyZWN0b3J5LCBsYWJlbCwgcHJvamVjdFJvb3QsIHRlbXBvcmFyeVZhdWx0LCB0cmFuc3BvcnQgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBTa2lwcGluZyBwbHVnaW4gaW5zdGFsbCAoaW5zdGFsbFBsdWdpbjogZmFsc2UpIFx1MjAxNCByZWdpc3RlcmluZyBhbiBlbXB0eSB2YXVsdC5gKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zPy5wb3B1bGF0ZSkge1xuICAgICAgY29uc3QgcG9wdWxhdGUgPSByZW1hcENvbmZpZ0RpcmVjdG9yeUtleXMocGFyYW1zLnBvcHVsYXRlLCBjb25maWdEaXJlY3RvcnkpO1xuICAgICAgY29uc3QgZW50cnlDb3VudCA9IE9iamVjdC5rZXlzKHBvcHVsYXRlKS5sZW5ndGg7XG4gICAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gUG9wdWxhdGluZyB2YXVsdCB3aXRoICR7U3RyaW5nKGVudHJ5Q291bnQpfSBlbnRyaWVzIGJlZm9yZSBvcGVuLi4uYCk7XG4gICAgICB0ZW1wb3JhcnlWYXVsdC5wb3B1bGF0ZShwb3B1bGF0ZSk7XG4gICAgfVxuXG4gICAgYXdhaXQgZW5zdXJlSGVhZGxlc3NWYXVsdENvbmZpZyh7XG4gICAgICBjb25maWdEaXJlY3RvcnksXG4gICAgICBsYWJlbCxcbiAgICAgIHZhdWx0UGF0aDogdGVtcG9yYXJ5VmF1bHQucGF0aFxuICAgIH0pO1xuXG4gICAgLy8gYHJlZ2lzdGVyYCBwdXNoZXMgdGhlIGRpcmVjdG9yeSB0byB0aGUgZGV2aWNlIGJlZm9yZSByZWdpc3RlcmluZyBpdCwgc28gZXZlcnkgd3JpdGUgYWJvdmUgXHUyMDE0XG4gICAgLy8gdGhlIHBsdWdpbiBjb3B5LCB0aGUgcG9wdWxhdGUgbWFwLCBhbmQgdGhlIGhlYWRsZXNzIGNvbmZpZyBqdXN0IHdyaXR0ZW4gXHUyMDE0IHJlYWNoZXMgdGhlIGFwcC5cbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gUmVnaXN0ZXJpbmcgdmF1bHQuLi5gKTtcbiAgICBhd2FpdCB0ZW1wb3JhcnlWYXVsdC5yZWdpc3Rlcih0cmFuc3BvcnQpO1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBWYXVsdCByZWdpc3RlcmVkLmApO1xuXG4gICAgaWYgKHBsdWdpbklkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGF3YWl0IGVuYWJsZVBsdWdpbkluVmF1bHQoeyBsYWJlbCwgcGx1Z2luSWQsIHRlbXBvcmFyeVZhdWx0LCB0cmFuc3BvcnQsIHRyYW5zcG9ydE9wdGlvbnMgfSk7XG4gICAgfVxuXG4gICAgYXdhaXQgZW5hYmxlRXh0cmFDb21tdW5pdHlQbHVnaW5zKHtcbiAgICAgIGxhYmVsLFxuICAgICAgcGx1Z2luSWRzOiBwYXJhbXM/LmVuYWJsZUNvbW11bml0eVBsdWdpbnMgPz8gW10sXG4gICAgICB0ZW1wb3JhcnlWYXVsdCxcbiAgICAgIHRyYW5zcG9ydCxcbiAgICAgIHRyYW5zcG9ydE9wdGlvbnNcbiAgICB9KTtcblxuICAgIGNvbnN0IGF1Z21lbnRlZE9wdGlvbnMgPSBhdWdtZW50VHJhbnNwb3J0T3B0aW9ucyh0cmFuc3BvcnRPcHRpb25zLCB0cmFuc3BvcnQpO1xuICAgIGNvbnN0IHJlc3VsdDogQ29yZVNldHVwUmVzdWx0ID0geyB0ZW1wb3JhcnlWYXVsdCwgdHJhbnNwb3J0LCB0cmFuc3BvcnRMYWJlbDogbGFiZWwsIHRyYW5zcG9ydE9wdGlvbnM6IGF1Z21lbnRlZE9wdGlvbnMgfTtcbiAgICBhY3RpdmVTZXR1cHMuYWRkKHJlc3VsdCk7XG4gICAgaWYgKGxvY2spIHtcbiAgICAgIHNldHVwTG9ja3Muc2V0KHJlc3VsdCwgbG9jayk7XG4gICAgfVxuICAgIHJlZ2lzdGVyUHJvY2Vzc0NsZWFudXBIYW5kbGVyKCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gU2V0dXAgZmFpbGVkLCBjbGVhbmluZyB1cC4uLmApO1xuICAgIHRyeSB7XG4gICAgICBpZiAodGVtcG9yYXJ5VmF1bHQgJiYgdHJhbnNwb3J0KSB7XG4gICAgICAgIGF3YWl0IHRlbXBvcmFyeVZhdWx0LmRpc3Bvc2UodHJhbnNwb3J0KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChjbGVhbnVwRXJyb3I6IHVua25vd24pIHtcbiAgICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBWYXVsdCBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoY2xlYW51cEVycm9yKX1gKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRyYW5zcG9ydD8uZGlzcG9zZT8uKCk7XG4gICAgfSBjYXRjaCAoY2xlYW51cEVycm9yOiB1bmtub3duKSB7XG4gICAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gVHJhbnNwb3J0IGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhjbGVhbnVwRXJyb3IpfWApO1xuICAgIH1cblxuICAgIC8vIFJlbGVhc2UgdGhlIGxvY2sgc28gYSB3YWl0aW5nIHJ1biBjYW4gcHJvY2VlZCBldmVuIHRob3VnaCB0aGlzIHJ1biBmYWlsZWQuXG4gICAgbG9jaz8ucmVsZWFzZSgpO1xuXG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIE5PVEU6IElmIHRoZSB0ZXN0IHJ1bm5lciByZXBvcnRzIFwiTm8gdGVzdCBmaWxlcyBmb3VuZFwiLCBpZ25vcmUgaXQgXHUyMDE0IGl0IGlzIGEgc2lkZSBlZmZlY3Qgb2YgdGhlIHNldHVwIGZhaWx1cmUgYWJvdmUuYCk7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cblxuLyoqXG4gKiBGcmFtZXdvcmstYWdub3N0aWMgZ2xvYmFsIHRlYXJkb3duIGxvZ2ljLlxuICpcbiAqIERpc3Bvc2VzIG9mIHRoZSB0ZW1wb3JhcnkgdmF1bHQgYW5kIHRyYW5zcG9ydCBjcmVhdGVkIGR1cmluZyBzZXR1cC5cbiAqXG4gKiBAcGFyYW0gcmVzdWx0IC0gVGhlIHJlc3VsdCBmcm9tIHtAbGluayBjb3JlU2V0dXB9LiBXaGVuIGB1bmRlZmluZWRgLCBkb2VzIG5vdGhpbmcuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb3JlVGVhcmRvd24ocmVzdWx0PzogQ29yZVNldHVwUmVzdWx0KTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmICghcmVzdWx0IHx8IGRpc3Bvc2VkUmVzdWx0cy5oYXMocmVzdWx0KSkge1xuICAgIHJldHVybjtcbiAgfVxuICBkaXNwb3NlZFJlc3VsdHMuYWRkKHJlc3VsdCk7XG5cbiAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd246JHtyZXN1bHQudHJhbnNwb3J0TGFiZWx9XSBUZWFyaW5nIGRvd24uLi5gKTtcblxuICB0cnkge1xuICAgIGF3YWl0IHRlYXJkb3duQXN5bmMocmVzdWx0KTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bjoke3Jlc3VsdC50cmFuc3BvcnRMYWJlbH1dIENsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhlcnJvcil9YCk7XG4gIH0gZmluYWxseSB7XG4gICAgYWN0aXZlU2V0dXBzLmRlbGV0ZShyZXN1bHQpO1xuICAgIHJlbGVhc2VTZXR1cExvY2socmVzdWx0KTtcbiAgfVxuXG4gIGF3YWl0IHN3ZWVwTGVmdG92ZXJzKHtcbiAgICBleGNsdWRlZE5hbWVzOiBbLi4uYWN0aXZlU2V0dXBzXS5tYXAoKGFjdGl2ZVNldHVwKSA9PiBiYXNlbmFtZShhY3RpdmVTZXR1cC50ZW1wb3JhcnlWYXVsdC5wYXRoKSksXG4gICAgbGFiZWw6IHJlc3VsdC50cmFuc3BvcnRMYWJlbCxcbiAgICBwaGFzZTogJ3RlYXJkb3duJyxcbiAgICB0cmFuc3BvcnRPcHRpb25zOiByZXN1bHQudHJhbnNwb3J0T3B0aW9uc1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZWRpcmVjdHMgYSBwb3B1bGF0ZSBtYXAncyBjb25maWctZm9sZGVyIGVudHJpZXMgdG8gdGhlIGZvbGRlciB0aGUgdmF1bHQgd2lsbCBhY3R1YWxseSByZWFkLlxuICpcbiAqIEEgcG9wdWxhdGUgbWFwIG5hbWVzIGl0cyBkZXN0aW5hdGlvbnMgdmF1bHQtcmVsYXRpdmUsIGFuZCBldmVyeXRoaW5nIHRoYXQgYnVpbGRzIG9uZSBcdTIwMTQgaW5jbHVkaW5nXG4gKiBgYnVpbGREZW1vVmF1bHRQb3B1bGF0ZWAsIHdoaWNoIHNlZWRzIGAub2JzaWRpYW4vKmAgY29uZmlnIGZpbGVzIGFuZCBpbmplY3RlZCBjb21tdW5pdHkgcGx1Z2lucydcbiAqIGJpbmFyaWVzIFx1MjAxNCB3cml0ZXMgdGhlbSB1bmRlciBhIGxpdGVyYWwgYC5vYnNpZGlhbi9gLCBiZWNhdXNlIHRoYXQgaXMgdGhlIGZvbGRlciBPYnNpZGlhbiB1c2VzIHdoZW4gbm90aGluZ1xuICogb3ZlcnJpZGVzIGl0LiBVbmRlciBhIGBjb25maWdEaXJlY3RvcnlgIG92ZXJyaWRlIHRob3NlIGVudHJpZXMgbGFuZCBpbiBhIGZvbGRlciB0aGUgdmF1bHQgbmV2ZXIgb3BlbnMsIGFuZFxuICogdGhlIHBsdWdpbnMgc2VlZGVkIHRoYXQgd2F5IGNvbWUgYmFjayBhcyB0aGUgZ2VuZXJpYyBcImVuYWJsZWQgYnV0IG5vdCBsb2FkZWRcIiB3aXRoIG5vdGhpbmcgbmFtaW5nIGEgY29uZmlnXG4gKiBmb2xkZXIuIFJld3JpdGluZyB0aGUga2V5IGhlcmUgZml4ZXMgZXZlcnkgY29uc3VtZXIgYXQgb25jZSBcdTIwMTQgYSBoYW5kLXdyaXR0ZW4gbWFwIGFzIG11Y2ggYXMgYSBkZW1vIHZhdWx0J3NcbiAqIFx1MjAxNCBhbmQgbmVlZHMgbm8gc2Vjb25kIGNvcHkgb2YgdGhlIG92ZXJyaWRlIGZvciBhIGNhbGxlciB0byBrZWVwIGluIHN5bmMgd2l0aCB0aGVpciB0cmFuc3BvcnQgb3B0aW9ucy5cbiAqXG4gKiBTYWZlIHJhdGhlciB0aGFuIG1hZ2ljOiB0aGUgdmF1bHQgaXMgb25lIHRoZSBoYXJuZXNzIG1hZGUgZm9yIHRoaXMgcnVuIGFuZCBoYXMgZXhhY3RseSBvbmUgY29uZmlnIGZvbGRlcixcbiAqIHNvIHVuZGVyIGFuIG92ZXJyaWRlIGEgYC5vYnNpZGlhbi9gIGVudHJ5IGlzIGRlYWQgd2VpZ2h0IG5vdGhpbmcgcmVhZHMuIE9ubHkgYSBsZWFkaW5nIGAub2JzaWRpYW5gIHBhdGhcbiAqIFNFR01FTlQgbW92ZXM7IGEgbm90ZSB3aG9zZSBuYW1lIG1lcmVseSBjb250YWlucyB0aGUgc3RyaW5nIGRvZXMgbm90LlxuICpcbiAqIEBwYXJhbSBwb3B1bGF0ZSAtIFRoZSBjb25zdW1lcidzIHBvcHVsYXRlIG1hcC5cbiAqIEBwYXJhbSBjb25maWdEaXJlY3RvcnkgLSBUaGUgcmVzb2x2ZWQgb3ZlcnJpZGUsIG9yIGB1bmRlZmluZWRgIGZvciBPYnNpZGlhbidzIGRlZmF1bHQgKGEgbm8tb3ApLlxuICogQHJldHVybnMgVGhlIG1hcCB3aXRoIGl0cyBjb25maWctZm9sZGVyIGtleXMgcmVkaXJlY3RlZCwgb3IgdGhlIG9yaWdpbmFsIG1hcCB3aGVuIHRoZXJlIGlzIG5vdGhpbmcgdG8gbW92ZS5cbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG9ic2lkaWFuLWRldi11dGlscy9wYXJhbXMtb3B0aW9ucy1uYW1lLW1hdGNoIC0tIFBlcm1hbmVudDogYFBvcHVsYXRlRmlsZXNQYXJhbXNgIGlzIG9uZSBiYWcgc2hhcmVkIGJ5IGBUZW1wb3JhcnlWYXVsdC5wb3B1bGF0ZWAgYW5kIHRoaXMgcmVtYXAsIHNvIG5vIHBlci1vd25lciBuYW1lIGNhbiBzYXRpc2Z5IGJvdGguXG5leHBvcnQgZnVuY3Rpb24gcmVtYXBDb25maWdEaXJlY3RvcnlLZXlzKHBvcHVsYXRlOiBQb3B1bGF0ZUZpbGVzUGFyYW1zLCBjb25maWdEaXJlY3Rvcnk6IHN0cmluZyB8IHVuZGVmaW5lZCk6IFBvcHVsYXRlRmlsZXNQYXJhbXMge1xuICBpZiAoY29uZmlnRGlyZWN0b3J5ID09PSB1bmRlZmluZWQgfHwgY29uZmlnRGlyZWN0b3J5ID09PSBERUZBVUxUX0NPTkZJR19ESVJFQ1RPUlkpIHtcbiAgICByZXR1cm4gcG9wdWxhdGU7XG4gIH1cblxuICBjb25zdCBwcmVmaXggPSBgJHtERUZBVUxUX0NPTkZJR19ESVJFQ1RPUll9L2A7XG4gIGNvbnN0IHJlbWFwcGVkOiBQb3B1bGF0ZUZpbGVzUGFyYW1zID0ge307XG4gIGZvciAoY29uc3QgW3BhdGgsIGNvbnRlbnRdIG9mIE9iamVjdC5lbnRyaWVzKHBvcHVsYXRlKSkge1xuICAgIHJlbWFwcGVkW3BhdGguc3RhcnRzV2l0aChwcmVmaXgpID8gYCR7Y29uZmlnRGlyZWN0b3J5fS8ke3BhdGguc2xpY2UocHJlZml4Lmxlbmd0aCl9YCA6IHBhdGhdID0gY29udGVudDtcbiAgfVxuXG4gIHJldHVybiByZW1hcHBlZDtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyB0cmFuc3BvcnQgb3B0aW9ucyBmb3IgYW4gaW50ZWdyYXRpb24gcnVuLlxuICpcbiAqIERlc2t0b3AgbGF1bmNoZXMgYXJlIG5vcm1hbGx5IHZpc2libGUsIGJ1dCB0ZXN0IHNldHVwIGV4cGxpY2l0bHkga2VlcHMgaXRzXG4gKiBvd25lZCBpbnN0YW5jZSBvZmYtc2NyZWVuIHNvIGl0IGRvZXMgbm90IGludGVycnVwdCB0aGUgZGV2ZWxvcGVyLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ29uc3VtZXItcHJvdmlkZWQgdHJhbnNwb3J0IG9wdGlvbnMuXG4gKiBAcmV0dXJucyBPcHRpb25zIHdpdGggdGhlIGRlc2t0b3AgaW50ZWdyYXRpb24gdmlzaWJpbGl0eSBkZWZhdWx0IGFwcGxpZWQuXG4gKi9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBvYnNpZGlhbi1kZXYtdXRpbHMvcGFyYW1zLW9wdGlvbnMtbmFtZS1tYXRjaCAtLSBQZXJtYW5lbnQ6IGBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnNgIGlzIG9uZSB0cmFuc3BvcnQgb3B0aW9ucyBiYWcgcmVhZCBieSBmaXZlIGhlbHBlcnMsIHNvIG5vIHBlci1vd25lciBuYW1lIGNhbiBzYXRpc2Z5IHRoZW0gYWxsLlxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVJbnRlZ3JhdGlvblRyYW5zcG9ydE9wdGlvbnMob3B0aW9ucz86IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyk6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB7XG4gIHJldHVybiBvcHRpb25zPy50eXBlID09PSAnb2JzaWRpYW4tYW5kcm9pZC1hcHBpdW0nXG4gICAgPyBvcHRpb25zXG4gICAgOiB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgaXNPYnNpZGlhbkFwcFZpc2libGU6IG9wdGlvbnM/LmlzT2JzaWRpYW5BcHBWaXNpYmxlID8/IGZhbHNlLFxuICAgICAgdHlwZTogJ29ic2lkaWFuLWNkcCdcbiAgICB9O1xufVxuXG4vKipcbiAqIEF1Z21lbnRzIHRyYW5zcG9ydCBvcHRpb25zIHdpdGggcmV1c2UgaW5mbyBzbyB0ZXN0IHdvcmtlcnMgY2FuIHJlYXR0YWNoIHRvIHRoZVxuICogaW5zdGFuY2UgdGhlIGdsb2JhbCBzZXR1cCBhbHJlYWR5IGxhdW5jaGVkIGluc3RlYWQgb2YgY3JlYXRpbmcgdGhlaXIgb3duOlxuICpcbiAqIC0gKipBcHBpdW0qKiBcdTIwMTQgaW5qZWN0cyB0aGUgZXN0YWJsaXNoZWQgYHNlc3Npb25JZGAvYGRldmljZUlkYC5cbiAqIC0gKipPd25lZCBkZXNrdG9wIENEUCoqIFx1MjAxNCBpbmplY3RzIHRoZSBvd25lZCBpbnN0YW5jZSdzIGBob3N0YC9gcG9ydGAgKGNob3NlblxuICogICBhdCBsYXVuY2gpIHBsdXMgdGhlIGludGVybmFsIGBpc0hhcm5lc3NPd25lZEluc3RhbmNlYCBmbGFnLCBzbyBlYWNoIHdvcmtlclxuICogICAqKmF0dGFjaGVzKiogdG8gdGhhdCBpbnN0YW5jZSBvdmVyIENEUCByYXRoZXIgdGhhbiBsYXVuY2hpbmcgKGFuZCBuZXZlclxuICogICByZWdpc3RlcmluZykgaXRzIG93biBcdTIwMTQgdGhlIGJ1ZyB0aGF0IG90aGVyd2lzZSBsZWF2ZXMgYSB3b3JrZXIncyB0cmFuc3BvcnRcbiAqICAgd2l0aCBubyBDRFAgZW5kcG9pbnQuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgb3JpZ2luYWwgdHJhbnNwb3J0IG9wdGlvbnMuXG4gKiBAcGFyYW0gdHJhbnNwb3J0IC0gVGhlIHRyYW5zcG9ydCBpbnN0YW5jZSBjcmVhdGVkIGR1cmluZyBzZXR1cC5cbiAqIEByZXR1cm5zIFRoZSBhdWdtZW50ZWQgb3B0aW9ucywgb3IgdGhlIG9yaWdpbmFsIG9wdGlvbnMgaWYgbm90IGFwcGxpY2FibGUuXG4gKi9cbi8qKlxuICogUmVmdXNlcyBhIHJ1biB3aG9zZSBidWlsdCBwbHVnaW4gcHJlZGF0ZXMgaXRzIHNvdXJjZXMsIGJlZm9yZSBhbnl0aGluZyBjb3N0bHkgaGFzIGhhcHBlbmVkLlxuICpcbiAqIEEgbm8tb3AgdW5sZXNzIGEgcGx1Z2luIGlzIGJlaW5nIGluc3RhbGxlZC4gT3RoZXJ3aXNlIGJvdGggaW5wdXRzIGFyZSBvbiBkaXNrIFx1MjAxNCB0aGUgbmV3ZXN0IHNvdXJjZSBhbmRcbiAqIGBtYWluLmpzYCdzIG10aW1lIFx1MjAxNCBzbyB0aGlzIHJ1bnMgYmVzaWRlIHtAbGluayBza2lwSWZEZXNrdG9wT25seX0sIGJlZm9yZSB0aGUgbG9jaywgdGhlIHN3ZWVwIGFuZCB0aGVcbiAqIHRyYW5zcG9ydDogYSBtb2JpbGUgcnVuIG11c3Qgbm90IGJvb3QgYW4gQVZEICh+NzAtMjAwIHMpIHRvIHJlYWNoIGEgdmVyZGljdCBhIGBzdGF0YCBjb3VsZCBnaXZlLlxuICpcbiAqIEl0IGluaGVyaXRzIHRoYXQgZnVuY3Rpb24ncyBvdGhlciBkaXNjaXBsaW5lIHRvby4gQSBtaXNzaW5nIG9yIHVucmVhZGFibGUgYnVpbGQgaXMgKipzd2FsbG93ZWQqKiwgbGVmdCB0b1xuICoge0BsaW5rIHJlc29sdmVEaXN0UGF0aH0gYW5kIHtAbGluayBjb3B5UGx1Z2luSW50b1ZhdWx0fSB0byByZXBvcnQgZG93bnN0cmVhbSBpbiB0aGVpciBvd24gd29yZHMsIHNvIHRoaXNcbiAqIGd1YXJkIGNhbm5vdCBjaGFuZ2Ugd2hhdCBhIG5vLWJ1aWxkIHJ1biBkb2VzIHRvZGF5LiBBbmQgYSBwcm9qZWN0IHdpdGggbm8gYHNyYy9gIGlzIG5ldmVyIGNhbGxlZCBzdGFsZSBcdTIwMTRcbiAqIHNlZSB7QGxpbmsgY2hlY2tJc0J1aWxkU3RhbGV9LlxuICpcbiAqIEVzY2FwaW5nIHRoZSBmYWlsdXJlIGRvd25ncmFkZXMgaXQgdG8gYSB3YXJuaW5nIHJhdGhlciB0aGFuIHRvIHNpbGVuY2U6IHRoZSBkaXJlY3Rpb24gdGhpcyBleGlzdHMgZm9yIGlzXG4gKiB0aGUgcnVuIHRoYXQgUEFTU0VTIGFnYWluc3QgYSBzdGFsZSBidWlsZCwgd2hpY2ggY29zdHMgbm90aGluZyB2aXNpYmxlIGFuZCBwcm92ZXMgbm90aGluZy5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHRyYW5zcG9ydCBsYWJlbCwgcHJvamVjdCByb290LCB0cmFuc3BvcnQgb3B0aW9ucyBhbmQgd2hldGhlciBhIHBsdWdpbiBpcyBpbnN0YWxsZWQuXG4gKiBAdGhyb3dzIHtTdGFsZUJ1aWxkRXJyb3J9IFdoZW4gdGhlIGJ1aWxkIGlzIG9sZGVyIHRoYW4gaXRzIHNvdXJjZXMgYW5kIHRoZSBmYWlsdXJlIGlzIG5vdCBlc2NhcGVkLlxuICovXG5hc3luYyBmdW5jdGlvbiBhc3NlcnRCdWlsZElzRnJlc2gocGFyYW1zOiBBc3NlcnRCdWlsZElzRnJlc2hQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBsYWJlbCwgcHJvamVjdFJvb3QsIHNob3VsZEluc3RhbGxQbHVnaW4sIHRyYW5zcG9ydE9wdGlvbnMgfSA9IHBhcmFtcztcblxuICBpZiAoIXNob3VsZEluc3RhbGxQbHVnaW4pIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBsZXQgZGlzdFBhdGg6IHN0cmluZztcbiAgbGV0IGJ1aWxkTW9kaWZpZWRBdEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG4gIHRyeSB7XG4gICAgZGlzdFBhdGggPSBhd2FpdCByZXNvbHZlRGlzdFBhdGgocHJvamVjdFJvb3QpO1xuICAgIGNvbnN0IGJ1aWxkU3RhdCA9IGF3YWl0IHN0YXQoam9pbihkaXN0UGF0aCwgTUFJTl9KUykpO1xuICAgIGJ1aWxkTW9kaWZpZWRBdEluTWlsbGlzZWNvbmRzID0gYnVpbGRTdGF0Lm10aW1lTXM7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IG5ld2VzdFNvdXJjZSA9IGF3YWl0IGZpbmROZXdlc3RTb3VyY2VNb2RpZmljYXRpb24ocHJvamVjdFJvb3QpO1xuICBjb25zdCByZWxhdGl2ZURpc3RQYXRoID0gcmVsYXRpdmUocHJvamVjdFJvb3QsIGRpc3RQYXRoKS5zcGxpdChzZXApLmpvaW4oJy8nKTtcblxuICAvLyBUaGUgYG5ld2VzdFNvdXJjZWAgdGVzdCBpcyByZWR1bmRhbnQgd2l0aCB0aGUgdmVyZGljdCBcdTIwMTQgYGNoZWNrSXNCdWlsZFN0YWxlYCBpcyBgZmFsc2VgIHdpdGhvdXQgb25lIFx1MjAxNCBhbmRcbiAgLy8gaXMgd3JpdHRlbiBvdXQgc28gdGhlIG5hcnJvd2luZyBiZWxvdyBuZWVkcyBubyBjYXN0LlxuICBpZiAoIW5ld2VzdFNvdXJjZSB8fCAhY2hlY2tJc0J1aWxkU3RhbGUoeyBidWlsZE1vZGlmaWVkQXRJbk1pbGxpc2Vjb25kcywgbmV3ZXN0U291cmNlIH0pKSB7XG4gICAgbG9nKFxuICAgICAgYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gQnVpbGQgaXMgZnJlc2g6ICR7cmVsYXRpdmVEaXN0UGF0aH0vJHtNQUlOX0pTfSBgXG4gICAgICAgICsgYCgke25ldyBEYXRlKGJ1aWxkTW9kaWZpZWRBdEluTWlsbGlzZWNvbmRzKS50b0lTT1N0cmluZygpfSkgaXMgbm90IG9sZGVyIHRoYW4gJHtcbiAgICAgICAgICBuZXdlc3RTb3VyY2VcbiAgICAgICAgICAgID8gYCR7bmV3ZXN0U291cmNlLnBhdGh9ICgke25ldyBEYXRlKG5ld2VzdFNvdXJjZS5tb2RpZmllZEF0SW5NaWxsaXNlY29uZHMpLnRvSVNPU3RyaW5nKCl9KS5gXG4gICAgICAgICAgICA6ICdhbnkgc291cmNlIFx1MjAxNCB0aGlzIHByb2plY3QgaGFzIG5vbmUgdW5kZXIgc3JjLywgc28gZnJlc2huZXNzIHdhcyBub3QgcHJvdmFibGUuJ1xuICAgICAgICB9YFxuICAgICk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgZXJyb3IgPSBuZXcgU3RhbGVCdWlsZEVycm9yKHtcbiAgICBidWlsZE1vZGlmaWVkQXRJbk1pbGxpc2Vjb25kcyxcbiAgICBkaXN0UGF0aDogcmVsYXRpdmVEaXN0UGF0aCxcbiAgICBzb3VyY2VNb2RpZmllZEF0SW5NaWxsaXNlY29uZHM6IG5ld2VzdFNvdXJjZS5tb2RpZmllZEF0SW5NaWxsaXNlY29uZHMsXG4gICAgc291cmNlUGF0aDogbmV3ZXN0U291cmNlLnBhdGhcbiAgfSk7XG5cbiAgaWYgKHdpbGxGYWlsT25TdGFsZUJ1aWxkKHRyYW5zcG9ydE9wdGlvbnMpKSB7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cblxuICAvLyBMb3VkLCBhbmQgbmV2ZXIgc2lsZW50OiB0aGUgZXNjYXBlIGhhdGNoIGV4aXN0cyBmb3IgYSBydW4gdGhhdCBkZWxpYmVyYXRlbHkgdGVzdHMgYSBzaGlwcGVkIGFydGlmYWN0LFxuICAvLyBhbmQgd2hhdCB0aGF0IHJ1biBtdXN0IG5vdCBkbyBpcyBmb3JnZXQgd2hpY2ggb25lIGl0IHRlc3RlZC4gYGRlc2NyaXB0aW9uYCByYXRoZXIgdGhhbiBgbWVzc2FnZWAsIHNvIHRoZVxuICAvLyByZW1lZHkgaXMgbm90IHJlY2l0ZWQgYXQgYSByZWFkZXIgd2hvIGhhcyBhbHJlYWR5IGFwcGxpZWQgaXQuXG4gIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBXQVJOSU5HOiAke2Vycm9yLmRlc2NyaXB0aW9ufSBDb250aW51aW5nIGFueXdheSBcdTIwMTQgdGhlIHN0YWxlLWJ1aWxkIGZhaWx1cmUgaXMgc3dpdGNoZWQgb2ZmLmApO1xufVxuXG5mdW5jdGlvbiBhdWdtZW50VHJhbnNwb3J0T3B0aW9ucyhcbiAgb3B0aW9uczogT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zIHwgdW5kZWZpbmVkLFxuICB0cmFuc3BvcnQ6IE9ic2lkaWFuVHJhbnNwb3J0XG4pOiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfCB1bmRlZmluZWQge1xuICBpZiAob3B0aW9ucz8udHlwZSA9PT0gJ29ic2lkaWFuLWFuZHJvaWQtYXBwaXVtJyAmJiB0cmFuc3BvcnQgaW5zdGFuY2VvZiBBcHBpdW1UcmFuc3BvcnQpIHtcbiAgICBjb25zdCBzZXNzaW9uSW5mbyA9IHRyYW5zcG9ydC5nZXRTZXNzaW9uSW5mbygpO1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7b3B0aW9ucy50eXBlfV0gU2Vzc2lvbiByZXVzZSBpbmZvOiBzZXNzaW9uSWQ9JHtzZXNzaW9uSW5mby5zZXNzaW9uSWR9LCBkZXZpY2VJZD0ke3Nlc3Npb25JbmZvLmRldmljZUlkfWApO1xuICAgIHJldHVybiB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgZGV2aWNlSWQ6IHNlc3Npb25JbmZvLmRldmljZUlkLFxuICAgICAgc2Vzc2lvbklkOiBzZXNzaW9uSW5mby5zZXNzaW9uSWRcbiAgICB9O1xuICB9XG5cbiAgaWYgKChvcHRpb25zID09PSB1bmRlZmluZWQgfHwgb3B0aW9ucy50eXBlID09PSAnb2JzaWRpYW4tY2RwJykgJiYgdHJhbnNwb3J0IGluc3RhbmNlb2YgRGVza3RvcENkcFRyYW5zcG9ydCkge1xuICAgIGNvbnN0IGVuZHBvaW50ID0gdHJhbnNwb3J0LmdldE93bmVkSW5zdGFuY2VFbmRwb2ludCgpO1xuICAgIGlmIChlbmRwb2ludCkge1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtERUZBVUxUX1RSQU5TUE9SVF9UWVBFfV0gT3duZWQgaW5zdGFuY2UgcmV1c2UgaW5mbzogaG9zdD0ke2VuZHBvaW50Lmhvc3R9LCBwb3J0PSR7U3RyaW5nKGVuZHBvaW50LnBvcnQpfWApO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgaG9zdDogZW5kcG9pbnQuaG9zdCxcbiAgICAgICAgaXNIYXJuZXNzT3duZWRJbnN0YW5jZTogdHJ1ZSxcbiAgICAgICAgcG9ydDogZW5kcG9pbnQucG9ydCxcbiAgICAgICAgdHlwZTogJ29ic2lkaWFuLWNkcCdcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9wdGlvbnM7XG59XG5cbi8qKlxuICogQ29waWVzIHRoZSBidWlsdCBwbHVnaW4gaW50byB0aGUgdGVtcCB2YXVsdCBhbmQgbWFya3MgaXQgYXMgYSBjb21tdW5pdHkgcGx1Z2luLlxuICpcbiAqIFJlYWRzIGBtYW5pZmVzdC5qc29uYCBmcm9tIHRoZSBuZXdlciBvZiBgZGlzdC9kZXZgL2BkaXN0L2J1aWxkYCwgcmVqZWN0cyBhXG4gKiBkZXNrdG9wLW9ubHkgcGx1Z2luIG9uIGEgbW9iaWxlIHRyYW5zcG9ydCwgdGhlbiBoYW5kcyB0aGUgd3JpdGUgaXRzZWxmIHRvXG4gKiB7QGxpbmsgaW5zdGFsbFBsdWdpbkludG9WYXVsdH0gXHUyMDE0IHdoaWNoIHB1dHMgdGhlIGJ1aWxkIGluXG4gKiBgPGNvbmZpZ0RpcmVjdG9yeT4vcGx1Z2lucy88aWQ+YCBhbmQgd3JpdGVzXG4gKiBgPGNvbmZpZ0RpcmVjdG9yeT4vY29tbXVuaXR5LXBsdWdpbnMuanNvbmAsIGhvbm91cmluZyBhIGBjb25maWdEaXJlY3RvcnlgXG4gKiBvdmVycmlkZSBzbyB0aGUgcGx1Z2luIGxhbmRzIHdoZXJlIHRoZSB2YXVsdCB3aWxsIGFjdHVhbGx5IGxvb2sgZm9yIGl0LlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgY29weSBwYXJhbWV0ZXJzLlxuICogQHJldHVybnMgVGhlIHBsdWdpbiBpZCByZWFkIGZyb20gdGhlIG1hbmlmZXN0LlxuICovXG5hc3luYyBmdW5jdGlvbiBjb3B5UGx1Z2luSW50b1ZhdWx0KHBhcmFtczogQ29weVBsdWdpbkludG9WYXVsdFBhcmFtcyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHsgY29uZmlnRGlyZWN0b3J5LCBsYWJlbCwgcHJvamVjdFJvb3QsIHRlbXBvcmFyeVZhdWx0LCB0cmFuc3BvcnQgfSA9IHBhcmFtcztcbiAgY29uc3QgZGlzdFBhdGggPSBhd2FpdCByZXNvbHZlRGlzdFBhdGgocHJvamVjdFJvb3QpO1xuICBjb25zdCBtYW5pZmVzdEpzb24gPSBKU09OLnBhcnNlKGF3YWl0IHJlYWRGaWxlKGpvaW4oZGlzdFBhdGgsICdtYW5pZmVzdC5qc29uJyksICd1dGYtOCcpKSBhcyBQbHVnaW5NYW5pZmVzdDtcbiAgY29uc3QgcGx1Z2luSWQgPSBtYW5pZmVzdEpzb24uaWQ7XG5cbiAgLy8gVGhlIHNhbWUgcmVmdXNhbCB7QGxpbmsgc2tpcElmRGVza3RvcE9ubHl9IGFscmVhZHkgbWFkZSBiZWZvcmUgdGhlIHRyYW5zcG9ydCBleGlzdGVkLiBLZXB0IGFzIHRoZVxuICAvLyBiYWNrc3RvcCBmb3IgYW55IGNhbGxlciB0aGF0IHJlYWNoZXMgaGVyZSBhbm90aGVyIHdheSwgYW5kIHRocm93aW5nIHRoZSBzYW1lIHR5cGUgc28gYm90aCBwYXRocyByZWFkXG4gIC8vIGlkZW50aWNhbGx5IGluIHRoZSBsb2cuXG4gIGlmICh0cmFuc3BvcnQuaXNNb2JpbGUgJiYgbWFuaWZlc3RKc29uLmlzRGVza3RvcE9ubHkpIHtcbiAgICB0aHJvdyBuZXcgRGVza3RvcE9ubHlQbHVnaW5Ta2lwRXJyb3IocGx1Z2luSWQpO1xuICB9XG5cbiAgY29uc3QgbWFpbkpzID0gam9pbihkaXN0UGF0aCwgTUFJTl9KUyk7XG4gIGNvbnN0IGJ1aWxkU3RhdCA9IGF3YWl0IHN0YXQobWFpbkpzKTtcbiAgLy8gXCJJZiBvdXRkYXRlZCwgcmVidWlsZC5cIiB1c2VkIHRvIGVuZCB0aGlzIGxpbmUuIEl0IHdhcyB0aGUgb25seSB0aGluZyBzYWlkIGFib3V0IHN0YWxlbmVzcywgaXQgd2FzIGJ1cmllZFxuICAvLyBhbW9uZyB0d2VudHkgb3RoZXIgc2V0dXAgbGluZXMsIGFuZCBub3RoaW5nIGNvbXBhcmVkIHRoZSB0aW1lc3RhbXAgYWdhaW5zdCBhbnl0aGluZyBcdTIwMTQgc28gYSBydW4gYWdhaW5zdCBhXG4gIC8vIGZpdmUtaG91ci1vbGQgYnVpbGQgcmVhZCBhcyBhIGRlZmVjdCBpbiB0aGUgY29kZSB1bmRlciB0ZXN0LCBhbmQgYSBydW4gdGhhdCBQQVNTRUQgYWdhaW5zdCBvbmUgc2FpZFxuICAvLyBub3RoaW5nIGF0IGFsbC4gYGFzc2VydEJ1aWxkSXNGcmVzaGAgaGFzIGFscmVhZHkgcmVhY2hlZCBhIHZlcmRpY3QgYnkgaGVyZTsgdGhpcyBsaW5lIG9ubHkgc2F5cyB3aGF0IHdhc1xuICAvLyBpbnN0YWxsZWQuXG4gIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBVc2luZyAke2Rpc3RQYXRofSAoJHtidWlsZFN0YXQubXRpbWUudG9JU09TdHJpbmcoKX0pLmApO1xuXG4gIGF3YWl0IGluc3RhbGxQbHVnaW5JbnRvVmF1bHQoeyBjb25maWdEaXJlY3RvcnksIGRpc3RQYXRoLCBwbHVnaW5JZCwgdmF1bHRQYXRoOiB0ZW1wb3JhcnlWYXVsdC5wYXRoIH0pO1xuICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gSW5zdGFsbGVkIFwiJHtwbHVnaW5JZH1cIiBpbnRvICR7Y29uZmlnRGlyZWN0b3J5ID8/IERFRkFVTFRfQ09ORklHX0RJUkVDVE9SWX0vcGx1Z2lucyAoYW5kIGVuYWJsZWQgaXQgdGhlcmUpLmApO1xuXG4gIHJldHVybiBwbHVnaW5JZDtcbn1cblxuLyoqXG4gKiBFbmFibGVzIGV4dHJhIGNvbW11bml0eSBwbHVnaW5zIChiZXlvbmQgdGhlIHBsdWdpbi11bmRlci10ZXN0KSBpbiB0aGUgcmVnaXN0ZXJlZCB2YXVsdCwgZWFjaCB0aHJvdWdoIHRoZVxuICogc2FtZSB7QGxpbmsgZW5hYmxlUGx1Z2luSW5WYXVsdH0gcGF0aC4gRWFjaCBwbHVnaW4ncyBidWlsdCBmaWxlcyBtdXN0IGFscmVhZHkgYmUgcHJlc2VudCBpbiB0aGUgdmF1bHQgKHNlZWRcbiAqIHRoZW0gdmlhIHtAbGluayBDb3JlU2V0dXBPcHRpb25zLnBvcHVsYXRlfSkuIEEgbm8tb3Agd2hlbiB0aGUgbGlzdCBpcyBlbXB0eS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGVuYWJsZSBwYXJhbWV0ZXJzLlxuICovXG5hc3luYyBmdW5jdGlvbiBlbmFibGVFeHRyYUNvbW11bml0eVBsdWdpbnMocGFyYW1zOiBFbmFibGVFeHRyYUNvbW11bml0eVBsdWdpbnNQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBsYWJlbCwgcGx1Z2luSWRzLCB0ZW1wb3JhcnlWYXVsdCwgdHJhbnNwb3J0LCB0cmFuc3BvcnRPcHRpb25zIH0gPSBwYXJhbXM7XG4gIGZvciAoY29uc3QgcGx1Z2luSWQgb2YgcGx1Z2luSWRzKSB7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIEVuYWJsaW5nIGV4dHJhIGNvbW11bml0eSBwbHVnaW4gXCIke3BsdWdpbklkfVwiLi4uYCk7XG4gICAgYXdhaXQgZW5hYmxlUGx1Z2luSW5WYXVsdCh7IGxhYmVsLCBwbHVnaW5JZCwgdGVtcG9yYXJ5VmF1bHQsIHRyYW5zcG9ydCwgdHJhbnNwb3J0T3B0aW9ucyB9KTtcbiAgfVxufVxuXG4vKipcbiAqIEVuYWJsZXMgdGhlIHBsdWdpbiBpbiB0aGUgcmVnaXN0ZXJlZCB2YXVsdCBhbmQgdmVyaWZpZXMgaXQgbG9hZGVkLlxuICpcbiAqIE9ic2lkaWFuJ3MgYGVuYWJsZVBsdWdpbigpYCB3cmFwcyBgbG9hZFBsdWdpbigpYCBpbiBhIHRyeS1jYXRjaCB0aGF0IHN3YWxsb3dzXG4gKiBlcnJvcnMgYW5kIHJldHVybnMgZmFsc2UsIHNvIHtAbGluayBlbmFibGVQbHVnaW5XaXRoRXJyb3JDYXB0dXJlfSBtb25rZXktcGF0Y2hlc1xuICogYGxvYWRQbHVnaW4oKWAgdG8gY2FwdHVyZSB0aGUgZXJyb3IgYmVmb3JlIGl0J3Mgc3dhbGxvd2VkLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZW5hYmxlIHBhcmFtZXRlcnMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGVuYWJsZVBsdWdpbkluVmF1bHQocGFyYW1zOiBFbmFibGVQbHVnaW5JblZhdWx0UGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgbGFiZWwsIHBsdWdpbklkLCB0ZW1wb3JhcnlWYXVsdCwgdHJhbnNwb3J0LCB0cmFuc3BvcnRPcHRpb25zIH0gPSBwYXJhbXM7XG4gIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBFbmFibGluZyBwbHVnaW4gXCIke3BsdWdpbklkfVwiLi4uYCk7XG5cbiAgLypcbiAgICogT3BlbiBhIG5hdGl2ZSBjb25zb2xlLWNhcHR1cmUgd2luZG93IChMYXllciAyLCBBbmRyb2lkIG9ubHkpIGFyb3VuZCB0aGVcbiAgICogZW5hYmxlIHNvIHRoYXQgaWYgT2JzaWRpYW4gc3dhbGxvd3MgdGhlIGxvYWQgZXJyb3IgYmVmb3JlIHRoZSBtb25rZXktcGF0Y2hcbiAgICogYW5kIHRoZSByZW5kZXJlciBjb25zb2xlIChMYXllciAxKSBjYW1lIHVwIGVtcHR5LCB3ZSBjYW4gc3RpbGwgcmVjb3ZlciB0aGVcbiAgICogcmVhbCBjYXVzZSBmcm9tIGBhZGIgbG9nY2F0YC4gTm8tb3AgKHVuZGVmaW5lZCkgb24gdHJhbnNwb3J0cyB0aGF0IGRvbid0XG4gICAqIGltcGxlbWVudCBpdCAoZS5nLiBkZXNrdG9wKS5cbiAgICovXG4gIGNvbnN0IGNhcHR1cmVIYW5kbGUgPSBhd2FpdCB0cmFuc3BvcnQuYmVnaW5Db25zb2xlQ2FwdHVyZT8uKCk7XG5cbiAgLypcbiAgICogT24gYSBmcmVzaGx5IGNvbGQtYm9vdGVkIGVtdWxhdG9yIHRoZSBwbHVnaW4gc3Vic3lzdGVtIGNhbiBzdGlsbCBiZSBzZXR0bGluZ1xuICAgKiB3aGVuIHdlIGVuYWJsZSB0aGUgcGx1Z2luLCBzbyBhIHNpbmdsZS1zaG90IGVuYWJsZSByYWNlcyB0aGUgbG9hZCBhbmQgbG9zZXNcbiAgICogKHRoZSBwbHVnaW4gbGFuZHMgaW4gdGhlIGVuYWJsZWQgc2V0IGJ1dCBuZXZlciBsb2FkcykuIFJldHJ5IHRoZSBlbmFibGUgK1xuICAgKiBsb2FkLXZlcmlmaWNhdGlvbiBhIGZldyB0aW1lcyB3aXRoIGV4cG9uZW50aWFsIGJhY2tvZmYsIHdoaWNoIHJlY292ZXJzIHRoZVxuICAgKiB0cmFuc2llbnQgcmFjZS4gQSBjYXB0dXJlZCBsb2FkIGVycm9yIChgcmVhbEVycm9yYCkgaXMgYSBkZXRlcm1pbmlzdGljIGJ1ZyBcdTIwMTRcbiAgICogcmV0cnlpbmcgY2Fubm90IGZpeCBpdCwgc28gd2UgZmFpbCBmYXN0LiBOb24tQW5kcm9pZCB0cmFuc3BvcnRzIHJlc29sdmUgdG9cbiAgICogdGhlIHNhbWUgZGVmYXVsdHMgYnV0IG5ldmVyIGVudGVyIHRoZSByZXRyeSBwYXRoOiB0aGVpciBsb2FkIGVpdGhlciBzdWNjZWVkc1xuICAgKiBvbiB0aGUgZmlyc3QgYXR0ZW1wdCBvciB0aHJvd3MgYSBjYXB0dXJlZCBlcnJvci5cbiAgICovXG4gIGNvbnN0IG1heEF0dGVtcHRzID0gMSArIHJlc29sdmVQbHVnaW5FbmFibGVSZXRyeUNvdW50KHRyYW5zcG9ydE9wdGlvbnMpO1xuICBjb25zdCBiYXNlRGVsYXlJbk1pbGxpc2Vjb25kcyA9IHJlc29sdmVQbHVnaW5FbmFibGVSZXRyeURlbGF5SW5NaWxsaXNlY29uZHModHJhbnNwb3J0T3B0aW9ucyk7XG5cbiAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IGF0dGVtcHQgPD0gbWF4QXR0ZW1wdHM7IGF0dGVtcHQrKykge1xuICAgIGxldCByZXN1bHQ6IEVuYWJsZVBsdWdpblJlc3VsdDtcbiAgICB0cnkge1xuICAgICAgcmVzdWx0ID0gYXdhaXQgZXZhbEluT2JzaWRpYW4oe1xuICAgICAgICBjYWxsYmFjazogZW5hYmxlUGx1Z2luV2l0aEVycm9yQ2FwdHVyZSxcbiAgICAgICAgaW5wdXQ6IHsgcGx1Z2luSWQgfSxcbiAgICAgICAgc2hvdWxkU2tpcFByZWZsaWdodENoZWNrczogdHJ1ZSxcbiAgICAgICAgdHJhbnNwb3J0LFxuICAgICAgICB2YXVsdFBhdGg6IHRlbXBvcmFyeVZhdWx0LnBhdGhcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvKlxuICAgICAgICogVGhlIGV2YWwgaXRzZWxmIHRocmV3IChlLmcuIHRoZSBXZWJWaWV3IGNvbnRleHQgd2FzIGxvc3QgbWlkLWV4ZWN1dGlvbiBvblxuICAgICAgICogYSBjaHVybmluZyBndWVzdCkgXHUyMDE0IGEgdHJhbnNwb3J0LWxldmVsIHRyYW5zaWVudC4gUmV0cnkgaWYgYXR0ZW1wdHMgcmVtYWluLlxuICAgICAgICovXG4gICAgICBpZiAoYXR0ZW1wdCA8IG1heEF0dGVtcHRzKSB7XG4gICAgICAgIGNvbnN0IGRlbGF5SW5NaWxsaXNlY29uZHMgPSBjb21wdXRlQmFja29mZkRlbGF5SW5NaWxsaXNlY29uZHMoYmFzZURlbGF5SW5NaWxsaXNlY29uZHMsIGF0dGVtcHQgLSAxKTtcbiAgICAgICAgbG9nKFxuICAgICAgICAgIGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIEVuYWJsZSBhdHRlbXB0ICR7U3RyaW5nKGF0dGVtcHQpfS8ke1N0cmluZyhtYXhBdHRlbXB0cyl9IHRocmV3IGBcbiAgICAgICAgICAgICsgYCgke2Vycm9yVG9TdHJpbmcoZXJyb3IpfSk7IHJldHJ5aW5nIGluICR7U3RyaW5nKGRlbGF5SW5NaWxsaXNlY29uZHMpfW1zLi4uYFxuICAgICAgICApO1xuICAgICAgICBhd2FpdCBzbGVlcChkZWxheUluTWlsbGlzZWNvbmRzKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIGBlcnJvck1lc3NhZ2VgIGlzIHRoZSByZWFsIHRocm93IHNlZW4gYnkgdGhlIG1vbmtleS1wYXRjaDtcbiAgICAgKiBgcmVuZGVyZXJDb25zb2xlRXJyb3JzYCAoTGF5ZXIgMSkgaXMgdGhlIHJlYWwgY2F1c2UgY29uc29sZS1sb2dnZWQgaW4gdGhlIHJlbmRlcmVyLlxuICAgICAqL1xuICAgIGNvbnN0IHJlYWxFcnJvciA9IHJlc3VsdC5lcnJvck1lc3NhZ2UgPz8gcmVzdWx0LnJlbmRlcmVyQ29uc29sZUVycm9ycztcblxuICAgIGlmIChyZXN1bHQuaXNMb2FkZWQgJiYgIXJlYWxFcnJvcikge1xuICAgICAgY29uc3QgYXR0ZW1wdFN1ZmZpeCA9IGF0dGVtcHQgPiAxID8gYCAoYXR0ZW1wdCAke1N0cmluZyhhdHRlbXB0KX0vJHtTdHJpbmcobWF4QXR0ZW1wdHMpfSlgIDogJyc7XG4gICAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gUGx1Z2luIFwiJHtwbHVnaW5JZH1cIiBlbmFibGVkIHN1Y2Nlc3NmdWxseSR7YXR0ZW1wdFN1ZmZpeH0uYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQSBjYXB0dXJlZCBsb2FkIGVycm9yIGlzIGRldGVybWluaXN0aWMgXHUyMDE0IGZhaWwgZmFzdCByYXRoZXIgdGhhbiByZXRyeS5cbiAgICBpZiAoIXNob3VsZFJldHJ5UGx1Z2luRW5hYmxlKHJlc3VsdCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUGx1Z2luIFwiJHtwbHVnaW5JZH1cIiBmYWlsZWQgdG8gbG9hZDogJHtyZWFsRXJyb3IgPz8gZ2V0R2VuZXJpY1BsdWdpbkxvYWRGYWlsdXJlTWVzc2FnZShwbHVnaW5JZCl9YCk7XG4gICAgfVxuXG4gICAgLy8gVHJhbnNpZW50IGNvbGQtYm9vdCByYWNlIChlbmFibGVkIGJ1dCBub3QgbG9hZGVkLCBubyBjYXVzZSBjYXB0dXJlZCk6IHJldHJ5LlxuICAgIGlmIChhdHRlbXB0ID49IG1heEF0dGVtcHRzKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBkZWxheUluTWlsbGlzZWNvbmRzID0gY29tcHV0ZUJhY2tvZmZEZWxheUluTWlsbGlzZWNvbmRzKGJhc2VEZWxheUluTWlsbGlzZWNvbmRzLCBhdHRlbXB0IC0gMSk7XG4gICAgbG9nKFxuICAgICAgYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gUGx1Z2luIFwiJHtwbHVnaW5JZH1cIiBlbmFibGVkIGJ1dCBub3QgbG9hZGVkIGBcbiAgICAgICAgKyBgKGF0dGVtcHQgJHtTdHJpbmcoYXR0ZW1wdCl9LyR7U3RyaW5nKG1heEF0dGVtcHRzKX0pOyByZXRyeWluZyBpbiAke1N0cmluZyhkZWxheUluTWlsbGlzZWNvbmRzKX1tcy4uLmBcbiAgICApO1xuICAgIGF3YWl0IHNsZWVwKGRlbGF5SW5NaWxsaXNlY29uZHMpO1xuICB9XG5cbiAgLypcbiAgICogRXhoYXVzdGVkIGV2ZXJ5IGF0dGVtcHQgb24gdGhlIHRyYW5zaWVudCBzaWduYXR1cmU6IGNvbXBvc2UgdGhlIG1vc3RcbiAgICogc3BlY2lmaWMgZGV0YWlsIGF2YWlsYWJsZSAoYGFkYiBsb2djYXRgIHRhaWwgb24gQW5kcm9pZCwgZWxzZSB0aGUgZ2VuZXJpY1xuICAgKiBtZXNzYWdlKSBcdTIwMTQgdW5jaGFuZ2VkIGZyb20gdGhlIHByZS1yZXRyeSBzaW5nbGUtc2hvdCBmYWlsdXJlLlxuICAgKi9cbiAgY29uc3QgbG9nY2F0VGFpbCA9IGF3YWl0IHRyYW5zcG9ydC5yZWFkQ29uc29sZUNhcHR1cmVTaW5jZT8uKGNhcHR1cmVIYW5kbGUpO1xuICBjb25zdCBkZXRhaWwgPSBsb2djYXRUYWlsID8/IGdldEdlbmVyaWNQbHVnaW5Mb2FkRmFpbHVyZU1lc3NhZ2UocGx1Z2luSWQpO1xuICB0aHJvdyBuZXcgRXJyb3IoYFBsdWdpbiBcIiR7cGx1Z2luSWR9XCIgZmFpbGVkIHRvIGxvYWQ6ICR7ZGV0YWlsfWApO1xufVxuXG4vKipcbiAqIEZpbmRzIHRoZSBwcm9qZWN0IHJvb3QgYnkgd2Fsa2luZyB1cCBmcm9tIGBwcm9jZXNzLmN3ZCgpYCBsb29raW5nIGZvciBgcGFja2FnZS5qc29uYC5cbiAqXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgcHJvamVjdCByb290LlxuICovXG5mdW5jdGlvbiBmaW5kUHJvamVjdFJvb3QoKTogc3RyaW5nIHtcbiAgbGV0IGRpcmVjdG9yeSA9IHByb2Nlc3MuY3dkKCk7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bm5lY2Vzc2FyeS1jb25kaXRpb24gLS0gTG9vcCB0ZXJtaW5hdGVzIGF0IGZpbGVzeXN0ZW0gcm9vdC5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAoZXhpc3RzU3luYyhqb2luKGRpcmVjdG9yeSwgJ3BhY2thZ2UuanNvbicpKSkge1xuICAgICAgcmV0dXJuIGRpcmVjdG9yeTtcbiAgICB9XG4gICAgY29uc3QgcGFyZW50ID0gam9pbihkaXJlY3RvcnksICcuLicpO1xuICAgIGlmIChwYXJlbnQgPT09IGRpcmVjdG9yeSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgZmluZCBwcm9qZWN0IHJvb3QgKG5vIHBhY2thZ2UuanNvbiBmb3VuZCkuJyk7XG4gICAgfVxuICAgIGRpcmVjdG9yeSA9IHBhcmVudDtcbiAgfVxufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBjcm9zcy1wcm9jZXNzIGxvY2sgc2NvcGUgZm9yIGEgdHJhbnNwb3J0LCBvciBgdW5kZWZpbmVkYCB3aGVuIG5vXG4gKiBsb2NrIGlzIG5lZWRlZC5cbiAqXG4gKiBEZXNrdG9wIHJ1bnMgdXNlIGhhcm5lc3Mtb3duZWQsIGlzb2xhdGVkIGluc3RhbmNlcyAodGhlaXIgb3duIHVzZXItZGF0YSBkaXJcbiAqIGFuZCBDRFAgcG9ydCksIHNvIHRoZXkgbm8gbG9uZ2VyIGNvbnRlbmQgYW5kIG5lZWQgbm8gbG9jay4gT25seSB0aGUgQW5kcm9pZFxuICogdHJhbnNwb3J0LCB3aGljaCBzaGFyZXMgdGhlIHNpbmdsZSBlbXVsYXRvciBhbmQgQXBwaXVtIHNlcnZlciwgbXVzdCBzZXJpYWxpemUuXG4gKlxuICogT2JzaWRpYW4ncyBDTEkgcGlwZSBpcyBtYWNoaW5lLWdsb2JhbCBwZXIgdXNlciBhbmQgdGhlcmVmb3JlIG91dHNpZGUgdGhhdFxuICogaXNvbGF0aW9uLCB3aGljaCByZWFkcyBsaWtlIGEgcmVhc29uIHRvIGdpdmUgZGVza3RvcCBhIHNjb3BlIHRvby4gTWVhc3VyZWQsIGl0XG4gKiBpcyB0aGUgb3Bwb3NpdGU6IHRoZSBwaXBlIGlzIGFscmVhZHkgaGVsZCBieSB0aGUgZGV2ZWxvcGVyJ3Mgb3duIE9ic2lkaWFuLCBzb1xuICogbm8gcnVuIGNhbiB3aW4gaXQgYW5kIGEgbG9uZSBydW4gbG9zZXMgaXQgZXhhY3RseSBhcyBhIHBhcmFsbGVsIG9uZSBkb2VzIFx1MjAxNCBhbmRcbiAqIG5vdGhpbmcgdGhlIGhhcm5lc3MgdXNlcyBpcyBiZWhpbmQgaXQuIFNlZSBBR0VOVFMubWQgTDU5LlxuICpcbiAqIEBwYXJhbSB0cmFuc3BvcnRPcHRpb25zIC0gVGhlIHJlc29sdmVkIHRyYW5zcG9ydCBvcHRpb25zLlxuICogQHJldHVybnMgVGhlIGxvY2sgc2NvcGUgc3RyaW5nLCBvciBgdW5kZWZpbmVkYCBpZiBubyBsb2NrIGlzIG5lZWRlZC5cbiAqL1xuZnVuY3Rpb24gZ2V0TG9ja1Njb3BlKHRyYW5zcG9ydE9wdGlvbnM6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiB0cmFuc3BvcnRPcHRpb25zPy50eXBlID09PSAnb2JzaWRpYW4tYW5kcm9pZC1hcHBpdW0nID8gQU5EUk9JRF9TRVRVUF9MT0NLX1NDT1BFIDogdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyBjbGVhbnVwIGhhbmRsZXJzIGZvciBvcnBoYW5lZCBzZXR1cHMgdGhhdCB3ZXJlIG5ldmVyIGV4cGxpY2l0bHlcbiAqIHRvcm4gZG93bi5cbiAqXG4gKiBUd28gaGFuZGxlcnMgY292ZXIgZGlmZmVyZW50IGV4aXQgc2NlbmFyaW9zOlxuICpcbiAqIC0gYGJlZm9yZUV4aXRgIFx1MjAxNCBmaXJlcyB3aGVuIHRoZSBldmVudCBsb29wIGRyYWlucyBuYXR1cmFsbHkuIEFsbG93cyBmdWxsXG4gKiAgIGFzeW5jIHRlYXJkb3duICh1bnJlZ2lzdGVyIHZhdWx0cywgZGlzcG9zZSB0cmFuc3BvcnRzKS4gRG9lcyBOT1QgZmlyZVxuICogICB3aGVuIGBwcm9jZXNzLmV4aXQoKWAgaXMgY2FsbGVkIGRpcmVjdGx5LlxuICpcbiAqIC0gYHVuaGFuZGxlZFJlamVjdGlvbmAgXHUyMDE0IGNhdGNoZXMgYXN5bmMgZXJyb3JzIHRoYXQgYnlwYXNzIGBjb3JlU2V0dXBgJ3NcbiAqICAgY2F0Y2ggYmxvY2suIFBlcmZvcm1zIGZ1bGwgYXN5bmMgdGVhcmRvd24gd2hpbGUgd2Ugc3RpbGwgY2FuLlxuICpcbiAqIC0gYGV4aXRgIFx1MjAxNCBmaXJlcyBvbiBldmVyeSBleGl0LCBpbmNsdWRpbmcgYHByb2Nlc3MuZXhpdCgpYC4gT25seSBzeW5jaHJvbm91c1xuICogICB3b3JrIGlzIHBvc3NpYmxlLCBzbyB0aGlzIGhhbmRsZXIgZG9lcyBiZXN0LWVmZm9ydCBjbGVhbnVwOiBraWxscyBjaGlsZFxuICogICBwcm9jZXNzZXMgdmlhIGBkaXNwb3NlU3luYygpYCBhbmQgcmVtb3ZlcyB0ZW1wIHZhdWx0IGRpcmVjdG9yaWVzIHdpdGhcbiAqICAgYHJtU3luY2AuIFVucmVnaXN0ZXJpbmcgdmF1bHRzICh3aGljaCByZXF1aXJlcyBJUEMgd2l0aCBPYnNpZGlhbikgaXNcbiAqICAgc2tpcHBlZCBcdTIwMTQgYSBzdGFsZSB2YXVsdCBlbnRyeSBpcyBhbiBhY2NlcHRhYmxlIHRyYWRlLW9mZiB2cy4gbGVha2VkXG4gKiAgIHByb2Nlc3NlcyBhbmQgdGVtcCBkaXJlY3Rvcmllcy5cbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJQcm9jZXNzQ2xlYW51cEhhbmRsZXIoKTogdm9pZCB7XG4gIGlmIChpc0NsZWFudXBIYW5kbGVyUmVnaXN0ZXJlZCkge1xuICAgIHJldHVybjtcbiAgfVxuICBpc0NsZWFudXBIYW5kbGVyUmVnaXN0ZXJlZCA9IHRydWU7XG5cbiAgcHJvY2Vzcy5vbignYmVmb3JlRXhpdCcsICgpID0+IHtcbiAgICBpZiAoYWN0aXZlU2V0dXBzLnNpemUgPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bl0gUHJvY2VzcyBleGl0aW5nIHdpdGggJHtTdHJpbmcoYWN0aXZlU2V0dXBzLnNpemUpfSBzZXR1cChzKSBub3QgdG9ybiBkb3duLiBDbGVhbmluZyB1cC4uLmApO1xuXG4gICAgZm9yIChjb25zdCByZXN1bHQgb2YgYWN0aXZlU2V0dXBzKSB7XG4gICAgICBjb3JlVGVhcmRvd24ocmVzdWx0KS5jYXRjaCgoZXJyb3I6IHVua25vd24pID0+IHtcbiAgICAgICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd246JHtyZXN1bHQudHJhbnNwb3J0TGFiZWx9XSBQcm9jZXNzIGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIHByb2Nlc3Mub24oJ3VuaGFuZGxlZFJlamVjdGlvbicsICgpID0+IHtcbiAgICBpZiAoYWN0aXZlU2V0dXBzLnNpemUgPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bl0gVW5oYW5kbGVkIHJlamVjdGlvbiBkZXRlY3RlZC4gVGVhcmluZyBkb3duICR7U3RyaW5nKGFjdGl2ZVNldHVwcy5zaXplKX0gYWN0aXZlIHNldHVwKHMpLi4uYCk7XG4gICAgZm9yIChjb25zdCByZXN1bHQgb2YgYWN0aXZlU2V0dXBzKSB7XG4gICAgICBjb3JlVGVhcmRvd24ocmVzdWx0KS5jYXRjaCgoZXJyb3I6IHVua25vd24pID0+IHtcbiAgICAgICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd246JHtyZXN1bHQudHJhbnNwb3J0TGFiZWx9XSBSZWplY3Rpb24gY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcHJvY2Vzcy5vbignZXhpdCcsICgpID0+IHtcbiAgICBpZiAoYWN0aXZlU2V0dXBzLnNpemUgPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bl0gU3luYyBjbGVhbnVwOiAke1N0cmluZyhhY3RpdmVTZXR1cHMuc2l6ZSl9IG9ycGhhbmVkIHNldHVwKHMpLmApO1xuICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIGFjdGl2ZVNldHVwcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmVzdWx0LnRyYW5zcG9ydC5kaXNwb3NlU3luYz8uKCk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bjoke3Jlc3VsdC50cmFuc3BvcnRMYWJlbH1dIFN5bmMgdHJhbnNwb3J0IGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICBybVN5bmMocmVzdWx0LnRlbXBvcmFyeVZhdWx0LnBhdGgsIHsgZm9yY2U6IHRydWUsIHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gU3luYyB2YXVsdCBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICAgcmVsZWFzZVNldHVwTG9jayhyZXN1bHQpO1xuICAgIH1cbiAgICBhY3RpdmVTZXR1cHMuY2xlYXIoKTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmVsZWFzZXMgYW5kIGZvcmdldHMgdGhlIHNldHVwIGxvY2sgYXNzb2NpYXRlZCB3aXRoIGEgcmVzdWx0LCBpZiBhbnkuXG4gKlxuICogQHBhcmFtIHJlc3VsdCAtIFRoZSBzZXR1cCByZXN1bHQgd2hvc2UgbG9jayBzaG91bGQgYmUgcmVsZWFzZWQuXG4gKi9cbmZ1bmN0aW9uIHJlbGVhc2VTZXR1cExvY2socmVzdWx0OiBDb3JlU2V0dXBSZXN1bHQpOiB2b2lkIHtcbiAgY29uc3QgbG9jayA9IHNldHVwTG9ja3MuZ2V0KHJlc3VsdCk7XG4gIGlmICghbG9jaykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGxvY2sucmVsZWFzZSgpO1xuICBzZXR1cExvY2tzLmRlbGV0ZShyZXN1bHQpO1xufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBkaXN0IHBhdGggdG8gdXNlIGZvciBpbnRlZ3JhdGlvbiB0ZXN0cy5cbiAqXG4gKiBQaWNrcyB3aGljaGV2ZXIgb2YgYGRpc3QvZGV2YCBhbmQgYGRpc3QvYnVpbGRgIGhhcyBhIG5ld2VyIGBtYWluLmpzYC5cbiAqIElmIG9ubHkgb25lIGV4aXN0cywgdGhhdCBvbmUgaXMgdXNlZC4gVGhyb3dzIGlmIG5laXRoZXIgZXhpc3RzLlxuICpcbiAqIEBwYXJhbSBwcm9qZWN0Um9vdCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSBwcm9qZWN0IHJvb3QuXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgY2hvc2VuIGRpc3QgZm9sZGVyLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlRGlzdFBhdGgocHJvamVjdFJvb3Q6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGRldlBhdGggPSBqb2luKHByb2plY3RSb290LCBESVNUX0RFVik7XG4gIGNvbnN0IGJ1aWxkUGF0aCA9IGpvaW4ocHJvamVjdFJvb3QsIERJU1RfQlVJTEQpO1xuICBjb25zdCBkZXZNYWluSnMgPSBqb2luKGRldlBhdGgsIE1BSU5fSlMpO1xuICBjb25zdCBidWlsZE1haW5KcyA9IGpvaW4oYnVpbGRQYXRoLCBNQUlOX0pTKTtcbiAgY29uc3QgZGV2U3RhdCA9IGV4aXN0c1N5bmMoZGV2TWFpbkpzKSA/IGF3YWl0IHN0YXQoZGV2TWFpbkpzKSA6IG51bGw7XG4gIGNvbnN0IGJ1aWxkU3RhdCA9IGV4aXN0c1N5bmMoYnVpbGRNYWluSnMpID8gYXdhaXQgc3RhdChidWlsZE1haW5KcykgOiBudWxsO1xuXG4gIGlmIChkZXZTdGF0ICYmIGJ1aWxkU3RhdCkge1xuICAgIHJldHVybiBkZXZTdGF0Lm10aW1lID4gYnVpbGRTdGF0Lm10aW1lID8gZGV2UGF0aCA6IGJ1aWxkUGF0aDtcbiAgfVxuXG4gIGlmIChkZXZTdGF0KSB7XG4gICAgcmV0dXJuIGRldlBhdGg7XG4gIH1cblxuICBpZiAoYnVpbGRTdGF0KSB7XG4gICAgcmV0dXJuIGJ1aWxkUGF0aDtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignTm8gYnVpbGQgZm91bmQuIFJ1biBgbnBtIHJ1biBidWlsZGAgb3IgYG5wbSBydW4gZGV2YCBmaXJzdC4nKTtcbn1cblxuLyoqXG4gKiBSZWZ1c2VzIGEgbW9iaWxlIHJ1biBmb3IgYSBkZXNrdG9wLW9ubHkgcGx1Z2luLCBiZWZvcmUgYW55dGhpbmcgY29zdGx5IGhhcyBoYXBwZW5lZC5cbiAqXG4gKiBBIG5vLW9wIHVubGVzcyBhIHBsdWdpbiBpcyBiZWluZyBpbnN0YWxsZWQgb250byBhIG1vYmlsZSB0cmFuc3BvcnQuIE90aGVyd2lzZSByZWFkcyBgbWFuaWZlc3QuanNvbmBcbiAqIG91dCBvZiB0aGUgbmV3ZXIgZGlzdCBmb2xkZXIgXHUyMDE0IG5vIGRldmljZSwgbm8gbG9jaywgbm8gc3dlZXAuIFdoZW4gdGhlcmUgaXMgbm8gcmVhZGFibGUgYnVpbGQgdGhlIGNoZWNrXG4gKiBzaW1wbHkgZG9lcyBub3QgZmlyZTogYSBtaXNzaW5nIG9yIG1hbGZvcm1lZCBidWlsZCBpcyBhIGRpZmZlcmVudCBwcm9ibGVtLCBhbmQge0BsaW5rIHJlc29sdmVEaXN0UGF0aH1cbiAqIGRvd25zdHJlYW0gYWxyZWFkeSByZXBvcnRzIGl0IGluIGl0cyBvd24gd29yZHMuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSB0cmFuc3BvcnQgbGFiZWwsIHByb2plY3Qgcm9vdCwgdHJhbnNwb3J0IG9wdGlvbnMgYW5kIHdoZXRoZXIgYSBwbHVnaW4gaXMgaW5zdGFsbGVkLlxuICogQHRocm93cyB7RGVza3RvcE9ubHlQbHVnaW5Ta2lwRXJyb3J9IFdoZW4gdGhlIG1hbmlmZXN0IHNheXMgYGlzRGVza3RvcE9ubHk6IHRydWVgLlxuICovXG5hc3luYyBmdW5jdGlvbiBza2lwSWZEZXNrdG9wT25seShwYXJhbXM6IFNraXBJZkRlc2t0b3BPbmx5UGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgbGFiZWwsIHByb2plY3RSb290LCBzaG91bGRJbnN0YWxsUGx1Z2luLCB0cmFuc3BvcnRPcHRpb25zIH0gPSBwYXJhbXM7XG5cbiAgaWYgKCFzaG91bGRJbnN0YWxsUGx1Z2luIHx8ICFjaGVja0lzTW9iaWxlVHJhbnNwb3J0KHRyYW5zcG9ydE9wdGlvbnMpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbGV0IG1hbmlmZXN0SnNvbjogUGx1Z2luTWFuaWZlc3Q7XG4gIHRyeSB7XG4gICAgY29uc3QgZGlzdFBhdGggPSBhd2FpdCByZXNvbHZlRGlzdFBhdGgocHJvamVjdFJvb3QpO1xuICAgIG1hbmlmZXN0SnNvbiA9IEpTT04ucGFyc2UoYXdhaXQgcmVhZEZpbGUoam9pbihkaXN0UGF0aCwgJ21hbmlmZXN0Lmpzb24nKSwgJ3V0Zi04JykpIGFzIFBsdWdpbk1hbmlmZXN0O1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoIW1hbmlmZXN0SnNvbi5pc0Rlc2t0b3BPbmx5KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbG9nKFxuICAgIGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFNLSVBQRUQ6IFwiJHttYW5pZmVzdEpzb24uaWR9XCIgaXMgZGVza3RvcC1vbmx5IChpc0Rlc2t0b3BPbmx5OiB0cnVlKSwgYFxuICAgICAgKyAnc28gaXQgaGFzIG5vIG1vYmlsZSBpbnRlZ3JhdGlvbiB0ZXN0cyB0byBydW4uIE5vIGVtdWxhdG9yIHdhcyBib290ZWQgYW5kIG5vIEFwcGl1bSBzZXJ2ZXIgd2FzIHN0YXJ0ZWQuJ1xuICApO1xuICB0aHJvdyBuZXcgRGVza3RvcE9ubHlQbHVnaW5Ta2lwRXJyb3IobWFuaWZlc3RKc29uLmlkKTtcbn1cblxuLyoqXG4gKiBSZW1vdmVzIHRoZSBob3N0LXNpZGUgdGVtcCBkaXJlY3RvcmllcyBlYXJsaWVyIHJ1bnMgbGVha2VkLlxuICpcbiAqIFJ1bnMgYXQgYm90aCBlbmRzIG9mIGEgcnVuOiBhdCBzZXR1cCBpdCBoYXBwZW5zICoqYmVmb3JlKiogdGhlIHRyYW5zcG9ydCBpc1xuICogY3JlYXRlZCwgc28gaXQgZG9lcyBub3QgZGVwZW5kIG9uIGEgaGVhbHRoeSBPYnNpZGlhbi9XZWJWaWV3IFx1MjAxNCB3aGljaCBpc1xuICogZXhhY3RseSB3aGF0IGEgZmFpbGVkIHJ1biBubyBsb25nZXIgaGFzLCBhbmQgd2h5IGEgZmFpbGVkIHJ1biBjYW5ub3QgY2xlYW4gdXBcbiAqIGFmdGVyIGl0c2VsZi4gQWdlLWdhdGVkIChzZWUgYGxlZnRvdmVyTWF4QWdlSW5NaWxsaXNlY29uZHNgKSBiZWNhdXNlIGRlc2t0b3BcbiAqIHJ1bnMgYXJlIG5vdCBzZXJpYWxpemVkIGFuZCBldmVyeSBwcm9qZWN0IG9uIHRoZSBtYWNoaW5lIHNoYXJlcyBvbmUgdGVtcFxuICogZGlyZWN0b3J5LiBCZXN0LWVmZm9ydDogYSBzd2VlcCBuZXZlciBmYWlscyB0aGUgcnVuIGl0IGlzIGNsZWFuaW5nIHVwIGZvci5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHN3ZWVwIHBhcmFtZXRlcnMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHN3ZWVwTGVmdG92ZXJzKHBhcmFtczogU3dlZXBMZWZ0b3ZlcnNQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBsYWJlbCwgcGhhc2UsIHRyYW5zcG9ydE9wdGlvbnMgfSA9IHBhcmFtcztcbiAgaWYgKCF3aWxsU3dlZXBMZWZ0b3ZlcnModHJhbnNwb3J0T3B0aW9ucykpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0cnkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN3ZWVwSG9zdExlZnRvdmVycyh7XG4gICAgICBleGNsdWRlZE5hbWVzOiBwYXJhbXMuZXhjbHVkZWROYW1lcyxcbiAgICAgIG1heEFnZUluTWlsbGlzZWNvbmRzOiByZXNvbHZlTGVmdG92ZXJNYXhBZ2VJbk1pbGxpc2Vjb25kcyh0cmFuc3BvcnRPcHRpb25zKVxuICAgIH0pO1xuICAgIGlmIChyZXN1bHQucmVtb3ZlZENvdW50ID4gMCB8fCByZXN1bHQuZmFpbGVkQ291bnQgPiAwKSB7XG4gICAgICBsb2coXG4gICAgICAgIGBbaW50ZWdyYXRpb24tJHtwaGFzZX06JHtsYWJlbH1dIFN3ZXB0ICR7U3RyaW5nKHJlc3VsdC5yZW1vdmVkQ291bnQpfSBsZWZ0b3ZlciB0ZW1wIGRpcmVjdG9yKGllcykgYFxuICAgICAgICAgICsgYGZyb20gZWFybGllciBydW5zICgke1N0cmluZyhyZXN1bHQuZmFpbGVkQ291bnQpfSBzdGlsbCBpbiB1c2UpLmBcbiAgICAgICk7XG4gICAgfVxuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLSR7cGhhc2V9OiR7bGFiZWx9XSBMZWZ0b3ZlciBzd2VlcCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgfVxufVxuXG4vKipcbiAqIFBlcmZvcm1zIHRoZSBhc3luYyB0ZWFyZG93biB3b3JrICh2YXVsdCBkaXNwb3NhbCArIHRyYW5zcG9ydCBkaXNwb3NhbCkuXG4gKlxuICogQHBhcmFtIHJlc3VsdCAtIFRoZSBzZXR1cCByZXN1bHQgdG8gdGVhciBkb3duLlxuICovXG5hc3luYyBmdW5jdGlvbiB0ZWFyZG93bkFzeW5jKHJlc3VsdDogQ29yZVNldHVwUmVzdWx0KTogUHJvbWlzZTx2b2lkPiB7XG4gIHRyeSB7XG4gICAgYXdhaXQgcmVzdWx0LnRlbXBvcmFyeVZhdWx0LmRpc3Bvc2UocmVzdWx0LnRyYW5zcG9ydCk7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd246JHtyZXN1bHQudHJhbnNwb3J0TGFiZWx9XSBWYXVsdCBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBhd2FpdCByZXN1bHQudHJhbnNwb3J0LmRpc3Bvc2U/LigpO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gVHJhbnNwb3J0IGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhlcnJvcil9YCk7XG4gIH1cbn1cbiJdLAogICJtYXBwaW5ncyI6ICJBQVlBO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1A7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUDtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1AsT0FBTyxXQUFXLG1CQUFtQjtBQUNyQyxTQUFTLGNBQWMsYUFBYTtBQVFwQyxTQUFTLGdDQUFnQztBQUN6QyxTQUFTLGtDQUFrQztBQUMzQztBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMscUJBQXFCO0FBQzlCLFNBQVMsc0JBQXNCO0FBQy9CLFNBQVMsaUNBQWlDO0FBQzFDO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMsV0FBVztBQUNwQjtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1A7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUDtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUCxTQUFTLHVCQUF1QjtBQUNoQyxTQUFTLHNCQUFzQjtB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
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Hides every element that renders the vault's NAME, so a captured frame does
5
+ * not depend on which temporary vault the run happened to get.
6
+ *
7
+ * The harness names its temporary vaults `temp-vault-<random>`, and Obsidian
8
+ * prints that name in the vault-switcher row at the bottom of the left sidedock.
9
+ * A desktop capture therefore carries the random suffix, which makes the PNG
10
+ * differ on every run — measured as 349 differing pixels in `x:153-197
11
+ * y:774-783` of a 1200x800 frame, amplified 16x to read `temp-vault-` plus
12
+ * that run's six-character suffix.
13
+ * The caption band `labelScreenshot` draws over that strip attenuates it to
14
+ * about 6 % brightness rather than hiding it, so it is invisible to a reader
15
+ * and fatal to reproducibility: a capture suite rewrites its checked-in
16
+ * screenshots on every run and the diff is unreadable.
17
+ *
18
+ * `captureObsidianScreenshot` calls this by default, so a consumer gets a
19
+ * reproducible frame without knowing the helper exists. It is exported anyway,
20
+ * for a consumer capturing through a raw `connectToCdp` connection — the same
21
+ * reason `measureLabelCaption` is exported rather than kept private to the
22
+ * labeller.
23
+ */
24
+ import type { ObsidianTransport } from './transport.mjs';
25
+ /**
26
+ * Options for {@link hideVaultName}.
27
+ */
28
+ export interface HideVaultNameOptions {
29
+ /**
30
+ * Override the transport. When omitted, the transport the current test
31
+ * context is driving is used.
32
+ */
33
+ readonly transport?: ObsidianTransport;
34
+ /**
35
+ * The vault whose Obsidian window to hide the name in. When omitted, the
36
+ * current test context's vault is used.
37
+ */
38
+ readonly vaultPath?: string;
39
+ }
40
+ /**
41
+ * Hides every element whose text is exactly the vault's name.
42
+ *
43
+ * Keyed on `app.vault.getName()` rather than on a class of Obsidian's chrome,
44
+ * deliberately: the varying thing is the DATA, and the row that renders it has
45
+ * moved between Obsidian versions before. Obsidian's own `hide()` rather than an
46
+ * inline `style.visibility` or an injected stylesheet, because those are what
47
+ * `obsidianmd/no-static-styles-assignment` and `obsidianmd/no-forbidden-elements`
48
+ * respectively refuse.
49
+ *
50
+ * Only leaf elements match (`childElementCount === 0`), so an ancestor whose
51
+ * `textContent` happens to concatenate to the same string is left alone — on a
52
+ * vault named after the only note in it, hiding the ancestor would blank half
53
+ * the frame.
54
+ *
55
+ * **Idempotent, and meant to be re-applied.** `hide()` leaves the text in place,
56
+ * so a second call finds what the first one hid; and it has to, because a
57
+ * re-render of the sidedock between two captures puts the row back.
58
+ *
59
+ * **Not asserted here.** Zero is a legitimate answer — the mobile app renders no
60
+ * vault-switcher row at all — so the count is returned rather than checked. A
61
+ * desktop capture suite that wants to fail loudly when Obsidian relocates the
62
+ * row should assert on it itself.
63
+ *
64
+ * @param options - Transport and vault overrides.
65
+ * @returns A {@link Promise} that resolves to the number of elements hidden.
66
+ */
67
+ export declare function hideVaultName(options?: HideVaultNameOptions): Promise<number>;
@@ -0,0 +1,21 @@
1
+ import { evalInObsidian } from "./eval-in-obsidian.mjs";
2
+ import { normalizeOptionalProperties } from "./normalize-optional-properties.mjs";
3
+ async function hideVaultName(options) {
4
+ const { transport, vaultPath } = options ?? {};
5
+ return await evalInObsidian(normalizeOptionalProperties({
6
+ callback({ app }) {
7
+ const vaultName = app.vault.getName();
8
+ const vaultNameEls = [...document.querySelectorAll("*")].filter((el) => el.instanceOf(HTMLElement) && el.childElementCount === 0 && el.textContent === vaultName);
9
+ for (const vaultNameEl of vaultNameEls) {
10
+ vaultNameEl.hide();
11
+ }
12
+ return vaultNameEls.length;
13
+ },
14
+ transport,
15
+ vaultPath
16
+ }));
17
+ }
18
+ export {
19
+ hideVaultName
20
+ };
21
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2hpZGUtdmF1bHQtbmFtZS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIEhpZGVzIGV2ZXJ5IGVsZW1lbnQgdGhhdCByZW5kZXJzIHRoZSB2YXVsdCdzIE5BTUUsIHNvIGEgY2FwdHVyZWQgZnJhbWUgZG9lc1xuICogbm90IGRlcGVuZCBvbiB3aGljaCB0ZW1wb3JhcnkgdmF1bHQgdGhlIHJ1biBoYXBwZW5lZCB0byBnZXQuXG4gKlxuICogVGhlIGhhcm5lc3MgbmFtZXMgaXRzIHRlbXBvcmFyeSB2YXVsdHMgYHRlbXAtdmF1bHQtPHJhbmRvbT5gLCBhbmQgT2JzaWRpYW5cbiAqIHByaW50cyB0aGF0IG5hbWUgaW4gdGhlIHZhdWx0LXN3aXRjaGVyIHJvdyBhdCB0aGUgYm90dG9tIG9mIHRoZSBsZWZ0IHNpZGVkb2NrLlxuICogQSBkZXNrdG9wIGNhcHR1cmUgdGhlcmVmb3JlIGNhcnJpZXMgdGhlIHJhbmRvbSBzdWZmaXgsIHdoaWNoIG1ha2VzIHRoZSBQTkdcbiAqIGRpZmZlciBvbiBldmVyeSBydW4gXHUyMDE0IG1lYXN1cmVkIGFzIDM0OSBkaWZmZXJpbmcgcGl4ZWxzIGluIGB4OjE1My0xOTdcbiAqIHk6Nzc0LTc4M2Agb2YgYSAxMjAweDgwMCBmcmFtZSwgYW1wbGlmaWVkIDE2eCB0byByZWFkIGB0ZW1wLXZhdWx0LWAgcGx1c1xuICogdGhhdCBydW4ncyBzaXgtY2hhcmFjdGVyIHN1ZmZpeC5cbiAqIFRoZSBjYXB0aW9uIGJhbmQgYGxhYmVsU2NyZWVuc2hvdGAgZHJhd3Mgb3ZlciB0aGF0IHN0cmlwIGF0dGVudWF0ZXMgaXQgdG9cbiAqIGFib3V0IDYgJSBicmlnaHRuZXNzIHJhdGhlciB0aGFuIGhpZGluZyBpdCwgc28gaXQgaXMgaW52aXNpYmxlIHRvIGEgcmVhZGVyXG4gKiBhbmQgZmF0YWwgdG8gcmVwcm9kdWNpYmlsaXR5OiBhIGNhcHR1cmUgc3VpdGUgcmV3cml0ZXMgaXRzIGNoZWNrZWQtaW5cbiAqIHNjcmVlbnNob3RzIG9uIGV2ZXJ5IHJ1biBhbmQgdGhlIGRpZmYgaXMgdW5yZWFkYWJsZS5cbiAqXG4gKiBgY2FwdHVyZU9ic2lkaWFuU2NyZWVuc2hvdGAgY2FsbHMgdGhpcyBieSBkZWZhdWx0LCBzbyBhIGNvbnN1bWVyIGdldHMgYVxuICogcmVwcm9kdWNpYmxlIGZyYW1lIHdpdGhvdXQga25vd2luZyB0aGUgaGVscGVyIGV4aXN0cy4gSXQgaXMgZXhwb3J0ZWQgYW55d2F5LFxuICogZm9yIGEgY29uc3VtZXIgY2FwdHVyaW5nIHRocm91Z2ggYSByYXcgYGNvbm5lY3RUb0NkcGAgY29ubmVjdGlvbiBcdTIwMTQgdGhlIHNhbWVcbiAqIHJlYXNvbiBgbWVhc3VyZUxhYmVsQ2FwdGlvbmAgaXMgZXhwb3J0ZWQgcmF0aGVyIHRoYW4ga2VwdCBwcml2YXRlIHRvIHRoZVxuICogbGFiZWxsZXIuXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgY29kZSAoZHJpdmVzIGEgbGl2ZSBPYnNpZGlhbikgY292ZXJlZCBieSBpbnRlZ3JhdGlvbiB0ZXN0cywgbm90IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCB0eXBlIHsgRXZhbEluT2JzaWRpYW5QYXJhbXMgfSBmcm9tICcuL2V2YWwtaW4tb2JzaWRpYW4ubWpzJztcbmltcG9ydCB0eXBlIHsgT2JzaWRpYW5UcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydC5tanMnO1xuXG5pbXBvcnQgeyBldmFsSW5PYnNpZGlhbiB9IGZyb20gJy4vZXZhbC1pbi1vYnNpZGlhbi5tanMnO1xuaW1wb3J0IHsgbm9ybWFsaXplT3B0aW9uYWxQcm9wZXJ0aWVzIH0gZnJvbSAnLi9ub3JtYWxpemUtb3B0aW9uYWwtcHJvcGVydGllcy5tanMnO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBoaWRlVmF1bHROYW1lfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBIaWRlVmF1bHROYW1lT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBPdmVycmlkZSB0aGUgdHJhbnNwb3J0LiBXaGVuIG9taXR0ZWQsIHRoZSB0cmFuc3BvcnQgdGhlIGN1cnJlbnQgdGVzdFxuICAgKiBjb250ZXh0IGlzIGRyaXZpbmcgaXMgdXNlZC5cbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydD86IE9ic2lkaWFuVHJhbnNwb3J0O1xuXG4gIC8qKlxuICAgKiBUaGUgdmF1bHQgd2hvc2UgT2JzaWRpYW4gd2luZG93IHRvIGhpZGUgdGhlIG5hbWUgaW4uIFdoZW4gb21pdHRlZCwgdGhlXG4gICAqIGN1cnJlbnQgdGVzdCBjb250ZXh0J3MgdmF1bHQgaXMgdXNlZC5cbiAgICovXG4gIHJlYWRvbmx5IHZhdWx0UGF0aD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBIaWRlcyBldmVyeSBlbGVtZW50IHdob3NlIHRleHQgaXMgZXhhY3RseSB0aGUgdmF1bHQncyBuYW1lLlxuICpcbiAqIEtleWVkIG9uIGBhcHAudmF1bHQuZ2V0TmFtZSgpYCByYXRoZXIgdGhhbiBvbiBhIGNsYXNzIG9mIE9ic2lkaWFuJ3MgY2hyb21lLFxuICogZGVsaWJlcmF0ZWx5OiB0aGUgdmFyeWluZyB0aGluZyBpcyB0aGUgREFUQSwgYW5kIHRoZSByb3cgdGhhdCByZW5kZXJzIGl0IGhhc1xuICogbW92ZWQgYmV0d2VlbiBPYnNpZGlhbiB2ZXJzaW9ucyBiZWZvcmUuIE9ic2lkaWFuJ3Mgb3duIGBoaWRlKClgIHJhdGhlciB0aGFuIGFuXG4gKiBpbmxpbmUgYHN0eWxlLnZpc2liaWxpdHlgIG9yIGFuIGluamVjdGVkIHN0eWxlc2hlZXQsIGJlY2F1c2UgdGhvc2UgYXJlIHdoYXRcbiAqIGBvYnNpZGlhbm1kL25vLXN0YXRpYy1zdHlsZXMtYXNzaWdubWVudGAgYW5kIGBvYnNpZGlhbm1kL25vLWZvcmJpZGRlbi1lbGVtZW50c2BcbiAqIHJlc3BlY3RpdmVseSByZWZ1c2UuXG4gKlxuICogT25seSBsZWFmIGVsZW1lbnRzIG1hdGNoIChgY2hpbGRFbGVtZW50Q291bnQgPT09IDBgKSwgc28gYW4gYW5jZXN0b3Igd2hvc2VcbiAqIGB0ZXh0Q29udGVudGAgaGFwcGVucyB0byBjb25jYXRlbmF0ZSB0byB0aGUgc2FtZSBzdHJpbmcgaXMgbGVmdCBhbG9uZSBcdTIwMTQgb24gYVxuICogdmF1bHQgbmFtZWQgYWZ0ZXIgdGhlIG9ubHkgbm90ZSBpbiBpdCwgaGlkaW5nIHRoZSBhbmNlc3RvciB3b3VsZCBibGFuayBoYWxmXG4gKiB0aGUgZnJhbWUuXG4gKlxuICogKipJZGVtcG90ZW50LCBhbmQgbWVhbnQgdG8gYmUgcmUtYXBwbGllZC4qKiBgaGlkZSgpYCBsZWF2ZXMgdGhlIHRleHQgaW4gcGxhY2UsXG4gKiBzbyBhIHNlY29uZCBjYWxsIGZpbmRzIHdoYXQgdGhlIGZpcnN0IG9uZSBoaWQ7IGFuZCBpdCBoYXMgdG8sIGJlY2F1c2UgYVxuICogcmUtcmVuZGVyIG9mIHRoZSBzaWRlZG9jayBiZXR3ZWVuIHR3byBjYXB0dXJlcyBwdXRzIHRoZSByb3cgYmFjay5cbiAqXG4gKiAqKk5vdCBhc3NlcnRlZCBoZXJlLioqIFplcm8gaXMgYSBsZWdpdGltYXRlIGFuc3dlciBcdTIwMTQgdGhlIG1vYmlsZSBhcHAgcmVuZGVycyBub1xuICogdmF1bHQtc3dpdGNoZXIgcm93IGF0IGFsbCBcdTIwMTQgc28gdGhlIGNvdW50IGlzIHJldHVybmVkIHJhdGhlciB0aGFuIGNoZWNrZWQuIEFcbiAqIGRlc2t0b3AgY2FwdHVyZSBzdWl0ZSB0aGF0IHdhbnRzIHRvIGZhaWwgbG91ZGx5IHdoZW4gT2JzaWRpYW4gcmVsb2NhdGVzIHRoZVxuICogcm93IHNob3VsZCBhc3NlcnQgb24gaXQgaXRzZWxmLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gVHJhbnNwb3J0IGFuZCB2YXVsdCBvdmVycmlkZXMuXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHRvIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaGlkZGVuLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGlkZVZhdWx0TmFtZShvcHRpb25zPzogSGlkZVZhdWx0TmFtZU9wdGlvbnMpOiBQcm9taXNlPG51bWJlcj4ge1xuICBjb25zdCB7IHRyYW5zcG9ydCwgdmF1bHRQYXRoIH0gPSBvcHRpb25zID8/IHt9O1xuXG4gIHJldHVybiBhd2FpdCBldmFsSW5PYnNpZGlhbihub3JtYWxpemVPcHRpb25hbFByb3BlcnRpZXM8RXZhbEluT2JzaWRpYW5QYXJhbXM8UmVjb3JkPHN0cmluZywgbmV2ZXI+LCBudW1iZXI+Pih7XG4gICAgY2FsbGJhY2soeyBhcHAgfSk6IG51bWJlciB7XG4gICAgICBjb25zdCB2YXVsdE5hbWUgPSBhcHAudmF1bHQuZ2V0TmFtZSgpO1xuICAgICAgY29uc3QgdmF1bHROYW1lRWxzID0gWy4uLmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJyonKV1cbiAgICAgICAgLmZpbHRlcigoZWwpOiBlbCBpcyBIVE1MRWxlbWVudCA9PiBlbC5pbnN0YW5jZU9mKEhUTUxFbGVtZW50KSAmJiBlbC5jaGlsZEVsZW1lbnRDb3VudCA9PT0gMCAmJiBlbC50ZXh0Q29udGVudCA9PT0gdmF1bHROYW1lKTtcblxuICAgICAgZm9yIChjb25zdCB2YXVsdE5hbWVFbCBvZiB2YXVsdE5hbWVFbHMpIHtcbiAgICAgICAgdmF1bHROYW1lRWwuaGlkZSgpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdmF1bHROYW1lRWxzLmxlbmd0aDtcbiAgICB9LFxuICAgIHRyYW5zcG9ydCxcbiAgICB2YXVsdFBhdGhcbiAgfSkpO1xufVxuXG4vKiB2OCBpZ25vcmUgc3RvcCAqL1xuIl0sCiAgIm1hcHBpbmdzIjogIkFBNkJBLFNBQVMsc0JBQXNCO0FBQy9CLFNBQVMsbUNBQW1DO0FBOEM1QyxlQUFzQixjQUFjLFNBQWlEO0FBQ25GLFFBQU0sRUFBRSxXQUFXLFVBQVUsSUFBSSxXQUFXLENBQUM7QUFFN0MsU0FBTyxNQUFNLGVBQWUsNEJBQWlGO0FBQUEsSUFDM0csU0FBUyxFQUFFLElBQUksR0FBVztBQUN4QixZQUFNLFlBQVksSUFBSSxNQUFNLFFBQVE7QUFDcEMsWUFBTSxlQUFlLENBQUMsR0FBRyxTQUFTLGlCQUFpQixHQUFHLENBQUMsRUFDcEQsT0FBTyxDQUFDLE9BQTBCLEdBQUcsV0FBVyxXQUFXLEtBQUssR0FBRyxzQkFBc0IsS0FBSyxHQUFHLGdCQUFnQixTQUFTO0FBRTdILGlCQUFXLGVBQWUsY0FBYztBQUN0QyxvQkFBWSxLQUFLO0FBQUEsTUFDbkI7QUFFQSxhQUFPLGFBQWE7QUFBQSxJQUN0QjtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsRUFDRixDQUFDLENBQUM7QUFDSjsiLAogICJuYW1lcyI6IFtdCn0K
@@ -50,14 +50,16 @@ export type { ClickElementParams, ClickMouseParams, CommonArguments, CreateNoteP
50
50
  export { evalInObsidian } from './eval-in-obsidian.mjs';
51
51
  export type { ComputeFitToCanvasParams, FitScreenshotToCanvasOptions, FitToCanvasGeometry } from './fit-screenshot.mjs';
52
52
  export { computeFitToCanvas, fitScreenshotToCanvas } from './fit-screenshot.mjs';
53
+ export type { HideVaultNameOptions } from './hide-vault-name.mjs';
54
+ export { hideVaultName } from './hide-vault-name.mjs';
53
55
  export type { IncompatibleInstallerVersionErrorConstructorParams } from './incompatible-installer-version-error.mjs';
54
56
  export { IncompatibleInstallerVersionError } from './incompatible-installer-version-error.mjs';
55
57
  export type { InstallerCompatibility, InstallerCompatibilityTier, ResolveInstallerCompatibilityParams } from './installer-compatibility.mjs';
56
58
  export { resolveInstallerCompatibility } from './installer-compatibility.mjs';
57
59
  export type { IntegrationSetupFailedErrorConstructorParams } from './integration-setup-failed-error.mjs';
58
60
  export { IntegrationSetupFailedError } from './integration-setup-failed-error.mjs';
59
- export type { ComputeLabelBandParams, LabelBandGeometry, LabelScreenshotOptions } from './label-screenshot.mjs';
60
- export { buildLabelSvg, computeLabelBand, escapeSvgText, labelScreenshot } from './label-screenshot.mjs';
61
+ export type { ComputeLabelBandParams, LabelBandGeometry, LabelCaptionMeasurement, LabelScreenshotOptions, MeasureLabelCaptionParams } from './label-screenshot.mjs';
62
+ export { buildLabelSvg, computeLabelBand, escapeSvgText, labelScreenshot, measureLabelCaption } from './label-screenshot.mjs';
61
63
  export type { LibResolver } from './lib-registry.mjs';
62
64
  export { registerLibResolver } from './lib-registry.mjs';
63
65
  export type { ObsidianRuntimeVersions, ObsidianVersionChangelogUrls, ObsidianVersionDownloads, ObsidianVersionMetadata } from './obsidian-metadata.mjs';
@@ -80,6 +82,8 @@ export type { BuildSoftKeyboardDiagnosticMessageParams, CheckIsSoftKeyboardUpPar
80
82
  export { buildSoftKeyboardDiagnosticMessage, checkIsSoftKeyboardUp, DEFAULT_MINIMUM_KEYBOARD_HEIGHT_IN_PIXELS, parseInputMethodState, resolveSoftKeyboardTapPoints } from './soft-keyboard-geometry.mjs';
81
83
  export type { RaiseSoftKeyboardParams, TapDeviceParams } from './soft-keyboard.mjs';
82
84
  export { raiseSoftKeyboard, tapDevice } from './soft-keyboard.mjs';
85
+ export type { StaleBuildErrorConstructorParams } from './stale-build-error.mjs';
86
+ export { StaleBuildError } from './stale-build-error.mjs';
83
87
  export type { PopulateFileContent, PopulateFilesParams, TemporaryVaultConstructorOptions } from './temporary-vault.mjs';
84
88
  export { TemporaryVault } from './temporary-vault.mjs';
85
89
  export type { AppiumSessionInfo, AppiumTransportConfig } from './transport-appium.mjs';