@mnaoumov/obsidian-dev-toolkit 3.2.0 → 3.3.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 (96) hide show
  1. package/dist/lib/cjs/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.cjs +1 -75
  2. package/dist/lib/cjs/bundlers/esbuild-impl/dependency.cjs +3 -77
  3. package/dist/lib/cjs/bundlers/esbuild-impl/feature-options.cjs +1 -75
  4. package/dist/lib/cjs/bundlers/esbuild-impl/fix-source-maps-plugin.cjs +1 -75
  5. package/dist/lib/cjs/bundlers/esbuild-impl/index.cjs +1 -75
  6. package/dist/lib/cjs/bundlers/esbuild-impl/obsidian-plugin-builder.cjs +1 -75
  7. package/dist/lib/cjs/bundlers/esbuild-impl/preprocess-plugin.cjs +3 -76
  8. package/dist/lib/cjs/bundlers/esbuild-impl/preprocess-plugin.d.cts +1 -1
  9. package/dist/lib/cjs/bundlers/esbuild-impl/rename-css-plugin.cjs +1 -75
  10. package/dist/lib/cjs/bundlers/esbuild.cjs +1 -75
  11. package/dist/lib/cjs/bundlers/index.cjs +1 -75
  12. package/dist/lib/cjs/bundlers/obsidian-cli-reload.cjs +1 -75
  13. package/dist/lib/cjs/bundlers/obsidian-plugin-build.cjs +1 -75
  14. package/dist/lib/cjs/bundlers/obsidian-plugin-features.cjs +1 -75
  15. package/dist/lib/cjs/bundlers/obsidian-plugin-transforms.cjs +1 -75
  16. package/dist/lib/cjs/bundlers/obsidian-plugin-webpack-loader.cjs +1 -75
  17. package/dist/lib/cjs/bundlers/obsidian-plugins-folder-deployment.cjs +32 -85
  18. package/dist/lib/cjs/bundlers/parcel.cjs +112 -81
  19. package/dist/lib/cjs/bundlers/parcel.d.cts +13 -6
  20. package/dist/lib/cjs/bundlers/rollup-compatible-features.cjs +1 -75
  21. package/dist/lib/cjs/bundlers/rollup-compatible.cjs +1 -75
  22. package/dist/lib/cjs/bundlers/rollup.cjs +1 -75
  23. package/dist/lib/cjs/bundlers/vite.cjs +1 -75
  24. package/dist/lib/cjs/bundlers/webpack.cjs +3 -77
  25. package/dist/lib/cjs/demo-vault-app-json.cjs +1 -75
  26. package/dist/lib/cjs/demo-vault-buttons.cjs +1 -75
  27. package/dist/lib/cjs/demo-vault-cli.cjs +1 -75
  28. package/dist/lib/cjs/demo-vault-coverage.cjs +139 -118
  29. package/dist/lib/cjs/demo-vault-coverage.d.cts +100 -5
  30. package/dist/lib/cjs/demo-vault.cjs +3 -77
  31. package/dist/lib/cjs/docs-site/index.cjs +1 -75
  32. package/dist/lib/cjs/docs-site/obsidian-external-type-links.cjs +1 -75
  33. package/dist/lib/cjs/formatters/dprint.cjs +1 -75
  34. package/dist/lib/cjs/formatters/index.cjs +1 -75
  35. package/dist/lib/cjs/index.cjs +1 -81
  36. package/dist/lib/cjs/index.d.cts +0 -2
  37. package/dist/lib/cjs/integration-test-setup.cjs +1 -75
  38. package/dist/lib/cjs/integration-test-vitest-global-setup.cjs +1 -75
  39. package/dist/lib/cjs/jest-setup.cjs +1 -75
  40. package/dist/lib/cjs/linters/eslint-config.cjs +1 -75
  41. package/dist/lib/cjs/linters/eslint-rules/index.cjs +1 -75
  42. package/dist/lib/cjs/linters/eslint-rules/manifest-description.cjs +1 -75
  43. package/dist/lib/cjs/linters/eslint-rules/manifest-helpers.cjs +1 -75
  44. package/dist/lib/cjs/linters/eslint-rules/manifest-id.cjs +1 -75
  45. package/dist/lib/cjs/linters/eslint-rules/manifest-name.cjs +1 -75
  46. package/dist/lib/cjs/linters/eslint-rules/manifest-schema.cjs +1 -75
  47. package/dist/lib/cjs/linters/eslint-rules/no-local-obsidian-internals.cjs +1 -75
  48. package/dist/lib/cjs/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.cjs +2 -77
  49. package/dist/lib/cjs/linters/eslint-rules/no-untrusted-input-events.cjs +1 -75
  50. package/dist/lib/cjs/linters/eslint-rules/obsidian-dev-toolkit-plugin.cjs +1 -75
  51. package/dist/lib/cjs/linters/eslint-rules/plugin-name-as-code-in-ui.cjs +1 -75
  52. package/dist/lib/cjs/linters/eslint-rules/plugin-name-as-code.cjs +1 -75
  53. package/dist/lib/cjs/linters/eslint-rules/require-component-suffix.cjs +1 -75
  54. package/dist/lib/cjs/linters/eslint-rules/require-plugin-api-contract-schemas.cjs +1 -75
  55. package/dist/lib/cjs/linters/eslint.cjs +1 -75
  56. package/dist/lib/cjs/linters/index.cjs +1 -75
  57. package/dist/lib/cjs/linters/markdownlint-cli2-config.cjs +1 -75
  58. package/dist/lib/cjs/linters/markdownlint-rules/index.cjs +1 -75
  59. package/dist/lib/cjs/linters/markdownlint-rules/plugin-name-as-code.cjs +1 -75
  60. package/dist/lib/cjs/linters/markdownlint.cjs +1 -75
  61. package/dist/lib/cjs/linters/obsidianmd-rule-custom-message.cjs +1 -75
  62. package/dist/lib/cjs/linters/plugin-names.cjs +1 -75
  63. package/dist/lib/cjs/obsidian-plugin-repo-paths.cjs +1 -75
  64. package/dist/lib/cjs/setup.cjs +1 -75
  65. package/dist/lib/cjs/templates.cjs +3 -77
  66. package/dist/lib/cjs/test-runners/coverage-badge-cli.cjs +1 -75
  67. package/dist/lib/cjs/test-runners/coverage-badge.cjs +1 -75
  68. package/dist/lib/cjs/test-runners/e2e-runner-support.cjs +1 -75
  69. package/dist/lib/cjs/test-runners/index.cjs +1 -78
  70. package/dist/lib/cjs/test-runners/index.d.cts +0 -1
  71. package/dist/lib/cjs/test-runners/integration-test-plugin.cjs +3 -77
  72. package/dist/lib/cjs/test-runners/jest-config.cjs +1 -75
  73. package/dist/lib/cjs/test-runners/obsidian-test-runner.cjs +1 -75
  74. package/dist/lib/cjs/test-runners/performance-eval-cap.cjs +4 -75
  75. package/dist/lib/cjs/test-runners/performance-eval-cap.d.cts +12 -3
  76. package/dist/lib/cjs/test-runners/stale-build-global-setup.cjs +1 -75
  77. package/dist/lib/cjs/test-runners/vitest-config.cjs +4 -80
  78. package/dist/lib/cjs/test-runners/wdio-obsidian.cjs +1 -75
  79. package/dist/lib/cjs/version.cjs +1 -75
  80. package/dist/lib/cjs/vitest-setup.cjs +1 -75
  81. package/dist/lib/esm/bundlers/esbuild-impl/preprocess-plugin.d.mts +1 -1
  82. package/dist/lib/esm/bundlers/esbuild-impl/preprocess-plugin.mjs +3 -2
  83. package/dist/lib/esm/bundlers/obsidian-plugins-folder-deployment.mjs +32 -15
  84. package/dist/lib/esm/bundlers/parcel.d.mts +13 -6
  85. package/dist/lib/esm/bundlers/parcel.mjs +110 -5
  86. package/dist/lib/esm/demo-vault-coverage.d.mts +100 -5
  87. package/dist/lib/esm/demo-vault-coverage.mjs +139 -44
  88. package/dist/lib/esm/index.d.mts +0 -2
  89. package/dist/lib/esm/index.mjs +1 -5
  90. package/dist/lib/esm/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.mjs +2 -2
  91. package/dist/lib/esm/test-runners/index.d.mts +0 -1
  92. package/dist/lib/esm/test-runners/index.mjs +1 -3
  93. package/dist/lib/esm/test-runners/performance-eval-cap.d.mts +12 -3
  94. package/dist/lib/esm/test-runners/performance-eval-cap.mjs +3 -1
  95. package/dist/lib/esm/test-runners/vitest-config.mjs +4 -5
  96. package/package.json +3 -2
@@ -29,80 +29,6 @@ function ensureBrowserProcess() {
29
29
 
30
30
  ensureBrowserProcess();
31
31
  })();
32
- (function patchObsidianRequire() {
33
- const originalRequire = require;
34
- if (!originalRequire || originalRequire.__isPatched) {
35
- return;
36
- }
37
-
38
- require = Object.assign(
39
- (id) => requirePatched(id),
40
- originalRequire,
41
- {
42
- __isPatched: true
43
- }
44
- );
45
-
46
- function extractDefault(module) {
47
- return module && module.__esModule && 'default' in module ? module.default : module;
48
- }
49
-
50
- const OBSIDIAN_BUILT_IN_MODULE_NAMES = new Set([
51
- '@codemirror/autocomplete',
52
- '@codemirror/collab',
53
- '@codemirror/commands',
54
- '@codemirror/language',
55
- '@codemirror/lint',
56
- '@codemirror/search',
57
- '@codemirror/state',
58
- '@codemirror/text',
59
- '@codemirror/view',
60
- '@lezer/common',
61
- '@lezer/highlight',
62
- '@lezer/lr',
63
- 'obsidian']
64
- );
65
-
66
- const DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES = new Set([
67
- '@codemirror/closebrackets',
68
- '@codemirror/comment',
69
- '@codemirror/fold',
70
- '@codemirror/gutter',
71
- '@codemirror/highlight',
72
- '@codemirror/history',
73
- '@codemirror/matchbrackets',
74
- '@codemirror/panel',
75
- '@codemirror/rangeset',
76
- '@codemirror/rectangular-selection',
77
- '@codemirror/stream-parser',
78
- '@codemirror/tooltip']
79
- );
80
-
81
- function requirePatched(id) {
82
- if (OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id) || DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id)) {
83
- return originalRequire?.(id);
84
- }
85
-
86
- // eslint-disable-next-line @typescript-eslint/no-deprecated, obsidianmd/no-global-this -- Need access to app. Actively use globalThis.
87
- if (globalThis.app.isMobile) {
88
- if (id === 'process' || id === 'node:process') {
89
- // eslint-disable-next-line no-console -- Valid usage.
90
- console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Fake process object is returned instead.`);
91
-
92
- return process;
93
- }
94
- } else {
95
- const module = originalRequire?.(id);
96
- if (module) {
97
- return extractDefault(module);
98
- }
99
- }
100
-
101
- // eslint-disable-next-line no-console -- Valid usage.
102
- console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Empty object is returned instead.`);
103
- return {};
104
- }
105
- })();
106
32
 
107
33
  "use strict";
108
34
  var __create = Object.create;
@@ -142,13 +68,13 @@ var import_debug = require('@mnaoumov/typescript-lib/debug');
142
68
  var import_path = require('@mnaoumov/typescript-lib/path');
143
69
  var import_promises = require('node:fs/promises');
144
70
  var import_node_process = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('node:process')), 1);
145
- var import_obsidian_integration_testing = require('obsidian-integration-testing');
146
71
  var import_obsidian_cli_reload = require('./obsidian-cli-reload.cjs');
147
72
  const moduleState = {
148
73
  devInstanceTransportPromise: void 0,
149
74
  isDevInstanceCleanupRegistered: false,
150
75
  isDevInstanceDisposed: false
151
76
  };
77
+ const OBSIDIAN_INTEGRATION_TESTING_PACKAGE_NAME = "obsidian-integration-testing";
152
78
  const DEV_INSTANCE_PROBE_INTERVAL_IN_MILLISECONDS = 2e3;
153
79
  const DEV_INSTANCE_CLOSED_PROBE_COUNT = 3;
154
80
  async function deployToObsidianPluginsFolder(params) {
@@ -193,8 +119,8 @@ async function deployToObsidianPluginsFolder(params) {
193
119
  }
194
120
  }
195
121
  }
196
- async function getOrLaunchDevInstance(vaultPath) {
197
- moduleState.devInstanceTransportPromise ??= launchDevInstance(vaultPath);
122
+ async function getOrLaunchDevInstance(obsidianIntegrationTesting, vaultPath) {
123
+ moduleState.devInstanceTransportPromise ??= launchDevInstance(obsidianIntegrationTesting, vaultPath);
198
124
  try {
199
125
  return await moduleState.devInstanceTransportPromise;
200
126
  } catch (error) {
@@ -202,14 +128,28 @@ async function getOrLaunchDevInstance(vaultPath) {
202
128
  throw error;
203
129
  }
204
130
  }
131
+ async function importObsidianIntegrationTesting() {
132
+ try {
133
+ return await import("obsidian-integration-testing");
134
+ } catch (error) {
135
+ if (!isMissingPackageError(error)) {
136
+ throw error;
137
+ }
138
+ throw new Error(
139
+ `The development build's \`reload: 'hot-reload-plugin'\` (the default) needs \`${OBSIDIAN_INTEGRATION_TESTING_PACKAGE_NAME}\`, which this project does not have. Install it with: npm install --save-dev ${OBSIDIAN_INTEGRATION_TESTING_PACKAGE_NAME}, or set \`reload\` to \`'obsidian-cli'\` or \`false\`.`,
140
+ { cause: error }
141
+ );
142
+ }
143
+ }
205
144
  async function installAndEnableHotReload(params) {
206
145
  const {
207
146
  obsidianConfigFolder,
208
147
  pluginName
209
148
  } = params;
210
149
  const vaultPath = (0, import_path.dirname)(obsidianConfigFolder);
211
- const transport = await getOrLaunchDevInstance(vaultPath);
212
- await (0, import_obsidian_integration_testing.evalInObsidian)({
150
+ const obsidianIntegrationTesting = await importObsidianIntegrationTesting();
151
+ const transport = await getOrLaunchDevInstance(obsidianIntegrationTesting, vaultPath);
152
+ await obsidianIntegrationTesting.evalInObsidian({
213
153
  // eslint-disable-next-line no-shadow -- No actual shadowing as the function is executed externally.
214
154
  async callback({ app, obsidianModule, pluginName: pluginName2 }) {
215
155
  const HOT_RELOAD_PLUGIN_ID = "hot-reload";
@@ -250,8 +190,15 @@ async function isDevInstanceRunning(cdpUrl) {
250
190
  return false;
251
191
  }
252
192
  }
253
- async function launchDevInstance(vaultPath) {
254
- const transport = await (0, import_obsidian_integration_testing.createTransportFromOptions)();
193
+ function isMissingPackageError(error) {
194
+ if (!(error instanceof Error)) {
195
+ return false;
196
+ }
197
+ const { code } = error;
198
+ return (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") && error.message.includes(`'${OBSIDIAN_INTEGRATION_TESTING_PACKAGE_NAME}'`);
199
+ }
200
+ async function launchDevInstance(obsidianIntegrationTesting, vaultPath) {
201
+ const transport = await obsidianIntegrationTesting.createTransportFromOptions();
255
202
  try {
256
203
  await transport.registerVault(vaultPath);
257
204
  } catch (error) {
@@ -259,7 +206,7 @@ async function launchDevInstance(vaultPath) {
259
206
  throw error;
260
207
  }
261
208
  registerDevInstanceCleanup(transport);
262
- watchDevInstanceAndStopOnClose(transport);
209
+ watchDevInstanceAndStopOnClose(obsidianIntegrationTesting, transport);
263
210
  return transport;
264
211
  }
265
212
  async function readPluginId(pluginFolder, fallbackId) {
@@ -290,8 +237,8 @@ function registerDevInstanceCleanup(transport) {
290
237
  transport.disposeSync?.();
291
238
  }
292
239
  }
293
- function watchDevInstanceAndStopOnClose(transport) {
294
- if (!(transport instanceof import_obsidian_integration_testing.DesktopCdpTransport)) {
240
+ function watchDevInstanceAndStopOnClose(obsidianIntegrationTesting, transport) {
241
+ if (!(transport instanceof obsidianIntegrationTesting.DesktopCdpTransport)) {
295
242
  return;
296
243
  }
297
244
  const endpoint = transport.getOwnedInstanceEndpoint();
@@ -317,4 +264,4 @@ function watchDevInstanceAndStopOnClose(transport) {
317
264
  0 && (module.exports = {
318
265
  deployToObsidianPluginsFolder
319
266
  });
320
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9idW5kbGVycy9vYnNpZGlhbi1wbHVnaW5zLWZvbGRlci1kZXBsb3ltZW50LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBEZXBsb3lzIGEgZGV2ZWxvcG1lbnQgYnVpbGQgaW50byB0aGUgdmF1bHQ6IGNvcGllcyB0aGUgb3V0cHV0IGZvbGRlciBpbnRvIGA8dmF1bHQ+Ly5vYnNpZGlhbi9wbHVnaW5zYCxcbiAqIHRoZW4gcmVsb2FkcyBpdCB0aGUgd2F5IHRoZSBidWlsZCdzIGByZWxvYWRgIG9wdGlvbiBzYXlzLiBCeSBkZWZhdWx0IHRoYXQgaW5zdGFsbHMgYW5kIGVuYWJsZXMgSG90UmVsb2FkXG4gKiBhbmQgdGhlIHBsdWdpbiBpbiBhbiBPYnNpZGlhbiBpbnN0YW5jZSBgbnBtIHJ1biBkZXZgIG93bnM7IGAnb2JzaWRpYW4tY2xpJ2AgcmVsb2FkcyBpdCBpbiB0aGUgT2JzaWRpYW4gdGhlXG4gKiBkZXZlbG9wZXIgaGFzIG9wZW4gaW5zdGVhZCAoYG9ic2lkaWFuLWNsaS1yZWxvYWQudHNgKS4gRXZlcnkgYnVuZGxlciBhZGFwdGVyIGNhbGxzIGl0IG9uY2UgZWFjaCByZWJ1aWxkIGhhc1xuICogd3JpdHRlbiBpdHMgb3V0cHV0LCBzbyB0aGUgbGF0ZXN0IGJ1aWxkIGlzIGFsd2F5cyB0aGUgb25lIHJ1bm5pbmcuXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIENvcGllcyBidWlsZCBvdXRwdXQgaW50byBhIHZhdWx0IGFuZCBkcml2ZXMgYSBsaXZlIE9ic2lkaWFuIG92ZXIgQ0RQLiAqL1xuXG5pbXBvcnQgdHlwZSB7IFBsdWdpbk1hbmlmZXN0IH0gZnJvbSAnb2JzaWRpYW4nO1xuaW1wb3J0IHR5cGUgeyBPYnNpZGlhblRyYW5zcG9ydCB9IGZyb20gJ29ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmcnO1xuXG5pbXBvcnQge1xuICBpbnZva2VBc3luY1NhZmVseSxcbiAgc2xlZXBcbn0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL2FzeW5jJztcbmltcG9ydCB7IGdldExpYkRlYnVnZ2VyIH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL2RlYnVnJztcbmltcG9ydCB7XG4gIGJhc2VuYW1lLFxuICBkaXJuYW1lLFxuICBqb2luLFxuICB0b1Bvc2l4UGF0aFxufSBmcm9tICdAbW5hb3Vtb3YvdHlwZXNjcmlwdC1saWIvcGF0aCc7XG5pbXBvcnQge1xuICBjcCxcbiAgbWtkaXIsXG4gIHJlYWRGaWxlXG59IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnO1xuaW1wb3J0IHByb2Nlc3MgZnJvbSAnbm9kZTpwcm9jZXNzJztcbmltcG9ydCB7XG4gIGNyZWF0ZVRyYW5zcG9ydEZyb21PcHRpb25zLFxuICBEZXNrdG9wQ2RwVHJhbnNwb3J0LFxuICBldmFsSW5PYnNpZGlhblxufSBmcm9tICdvYnNpZGlhbi1pbnRlZ3JhdGlvbi10ZXN0aW5nJztcblxuaW1wb3J0IHR5cGUgeyBPYnNpZGlhblBsdWdpblJlbG9hZCB9IGZyb20gJy4vb2JzaWRpYW4tcGx1Z2luLWJ1aWxkLnRzJztcblxuaW1wb3J0IHsgcmVsb2FkUGx1Z2luV2l0aE9ic2lkaWFuQ2xpIH0gZnJvbSAnLi9vYnNpZGlhbi1jbGktcmVsb2FkLnRzJztcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgZGVwbG95VG9PYnNpZGlhblBsdWdpbnNGb2xkZXJ9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERlcGxveVRvT2JzaWRpYW5QbHVnaW5zRm9sZGVyUGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBmb2xkZXIgd2hlcmUgdGhlIGJ1aWx0IGZpbGVzIGFyZSBsb2NhdGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgZGlzdEZvbGRlcjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBidWlsZCBpcyBhIHByb2R1Y3Rpb24gYnVpbGQuXG4gICAqL1xuICByZWFkb25seSBpc1Byb2R1Y3Rpb25CdWlsZDogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIGZvbGRlciBvZiB0aGUgT2JzaWRpYW4gY29uZmlndXJhdGlvbi4gSWYgbm90IHByb3ZpZGVkLCB0aGUgcGx1Z2luIHdpbGwgbm90IGNvcHkgZmlsZXMuXG4gICAqL1xuICByZWFkb25seSBvYnNpZGlhbkNvbmZpZ0ZvbGRlcjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgT2JzaWRpYW4gcGx1Z2luLlxuICAgKi9cbiAgcmVhZG9ubHkgcGx1Z2luTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBIb3cgdGhlIGRlcGxveWVkIGJ1aWxkIGlzIHJlbG9hZGVkIGluIE9ic2lkaWFuLiBEZWZhdWx0cyB0byBgJ2hvdC1yZWxvYWQtcGx1Z2luJ2AuXG4gICAqL1xuICByZWFkb25seSByZWxvYWQ/OiBPYnNpZGlhblBsdWdpblJlbG9hZDtcbn1cblxuLyoqXG4gKiBUaGUgc3Vic2V0IG9mIGEgQ0RQIHRhcmdldCBkZXNjcmlwdG9yIHJlYWQgZnJvbSB0aGUgb3duZWQgaW5zdGFuY2UncyBgL2pzb25gIGVuZHBvaW50LlxuICovXG5pbnRlcmZhY2UgQ2RwVGFyZ2V0IHtcbiAgLyoqXG4gICAqIFRoZSBraW5kIG9mIHRoZSB0YXJnZXQsIGUuZy4gYHBhZ2VgLlxuICAgKi9cbiAgcmVhZG9ubHkgdHlwZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgc2luZ2xlIGVudHJ5IGluIE9ic2lkaWFuJ3MgY29tbXVuaXR5IHBsdWdpbnMgcmVnaXN0cnkgKGBjb21tdW5pdHktcGx1Z2lucy5qc29uYCkuXG4gKi9cbmludGVyZmFjZSBDb21tdW5pdHlQbHVnaW5SZWdpc3RyeUVudHJ5IHtcbiAgLyoqXG4gICAqIFRoZSBwbHVnaW4gaWQuXG4gICAqL1xuICByZWFkb25seSBpZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgYG93bmVyL25hbWVgIEdpdEh1YiByZXBvc2l0b3J5IHRoZSBwbHVnaW4gaXMgcHVibGlzaGVkIGZyb20uXG4gICAqL1xuICByZWFkb25seSByZXBvOiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIHN1YnNldCBvZiBhIEdpdEh1YiByZWxlYXNlIHdlIHJlYWQuXG4gKi9cbmludGVyZmFjZSBHaXRIdWJSZWxlYXNlIHtcbiAgLyoqXG4gICAqIFRoZSByZWxlYXNlIHRhZywgYSBiYXJlIHZlcnNpb24gc3VjaCBhcyBgMS4yLjNgLlxuICAgKi9cbiAgcmVhZG9ubHkgdGFnX25hbWU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgaW5zdGFsbEFuZEVuYWJsZUhvdFJlbG9hZH0uXG4gKi9cbmludGVyZmFjZSBJbnN0YWxsQW5kRW5hYmxlSG90UmVsb2FkUGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBmb2xkZXIgb2YgdGhlIE9ic2lkaWFuIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICByZWFkb25seSBvYnNpZGlhbkNvbmZpZ0ZvbGRlcjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgYnVpbHQgT2JzaWRpYW4gcGx1Z2luIHRvIGVuYWJsZSBvbmNlIEhvdFJlbG9hZCBpcyBpbiBwbGFjZS5cbiAgICovXG4gIHJlYWRvbmx5IHBsdWdpbk5hbWU6IHN0cmluZztcbn1cblxuLy8gVGhlIGBucG0gcnVuIGRldmAtb3duZWQgT2JzaWRpYW4gaW5zdGFuY2U6IGxhdW5jaGVkIG9uIHRoZSBmaXJzdCByZWJ1aWxkIGFuZCByZXVzZWQgYWNyb3NzIHJlYnVpbGRzLlxuLy8gSXRzIGxpZmV0aW1lIGlzIHRpZWQgdG8gdGhlIGBucG0gcnVuIGRldmAgcHJvY2VzcyBpbiBCT1RIIGRpcmVjdGlvbnMuXG4vLyBUaGUgaW5zdGFuY2UgaXMgY2xvc2VkIHdoZW4gdGhlIHByb2Nlc3MgdGVybWluYXRlcyAoc2VlIGByZWdpc3RlckRldkluc3RhbmNlQ2xlYW51cGApLlxuLy8gVGhlIHByb2Nlc3Mgc3RvcHMgd2hlbiB0aGUgaW5zdGFuY2UgaXMgY2xvc2VkIChzZWUgYHdhdGNoRGV2SW5zdGFuY2VBbmRTdG9wT25DbG9zZWApLlxuLyoqXG5Nb2R1bGUtbGV2ZWwgbXV0YWJsZSBzdGF0ZSwgaGVsZCBpbiBvbmUgb2JqZWN0IHNvIGVhY2ggbXV0YXRpb24gbmFtZXMgaXQgZXhwbGljaXRseS5cbiAqL1xuaW50ZXJmYWNlIE1vZHVsZVN0YXRlIHtcbiAgZGV2SW5zdGFuY2VUcmFuc3BvcnRQcm9taXNlOiBQcm9taXNlPE9ic2lkaWFuVHJhbnNwb3J0PiB8IHVuZGVmaW5lZDtcbiAgaXNEZXZJbnN0YW5jZUNsZWFudXBSZWdpc3RlcmVkOiBib29sZWFuO1xuICBpc0Rldkluc3RhbmNlRGlzcG9zZWQ6IGJvb2xlYW47XG59XG5cbmNvbnN0IG1vZHVsZVN0YXRlOiBNb2R1bGVTdGF0ZSA9IHtcbiAgZGV2SW5zdGFuY2VUcmFuc3BvcnRQcm9taXNlOiB1bmRlZmluZWQsXG4gIGlzRGV2SW5zdGFuY2VDbGVhbnVwUmVnaXN0ZXJlZDogZmFsc2UsXG4gIGlzRGV2SW5zdGFuY2VEaXNwb3NlZDogZmFsc2Vcbn07XG5cbi8qKlxuICogSG93IG9mdGVuIHRoZSBvd25lZCBPYnNpZGlhbiBpbnN0YW5jZSBpcyBwcm9iZWQgdG8gZGV0ZWN0IHRoYXQgaXQgd2FzIGNsb3NlZC5cbiAqL1xuY29uc3QgREVWX0lOU1RBTkNFX1BST0JFX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDIwMDA7XG5cbi8qKlxuICogSG93IG1hbnkgY29uc2VjdXRpdmUgZmFpbGVkIHByb2JlcyBhcmUgdG9sZXJhdGVkIGJlZm9yZSB0aGUgb3duZWQgaW5zdGFuY2UgaXMgY29uc2lkZXJlZCBjbG9zZWQuIEFcbiAqIHNpbmdsZSBmYWlsdXJlIGNhbiBiZSBhIHRyYW5zaWVudCBoaWNjdXAgKGEgYnVzeSByZW5kZXJlciwgYSBtb21lbnRhcmlseSByZWZ1c2VkIGNvbm5lY3Rpb24pLCBzbyB0aGVcbiAqIGRldmVsb3BtZW50IGJ1aWxkIGlzIG9ubHkgc3RvcHBlZCBvbmNlIHRoZSBlbmRwb2ludCBzdGF5cyB1bnJlYWNoYWJsZS5cbiAqL1xuY29uc3QgREVWX0lOU1RBTkNFX0NMT1NFRF9QUk9CRV9DT1VOVCA9IDM7XG4vKipcbiAqIENvcGllcyBhIGRldmVsb3BtZW50IGJ1aWxkIGludG8gdGhlIHZhdWx0J3MgcGx1Z2lucyBmb2xkZXIgYW5kIHJlbG9hZHMgaXQgdGhlcmUsIGFzIHRoZSBgcmVsb2FkYCBvcHRpb25cbiAqIHNheXMuIERvZXMgbm90aGluZyBmb3IgYSBwcm9kdWN0aW9uIGJ1aWxkLCBvciB3aGVuIG5vIE9ic2lkaWFuIGNvbmZpZyBmb2xkZXIgaXMgY29uZmlndXJlZC5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHtAbGluayBEZXBsb3lUb09ic2lkaWFuUGx1Z2luc0ZvbGRlclBhcmFtc30uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIHBsdWdpbiBpcyBkZXBsb3llZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlcGxveVRvT2JzaWRpYW5QbHVnaW5zRm9sZGVyKHBhcmFtczogRGVwbG95VG9PYnNpZGlhblBsdWdpbnNGb2xkZXJQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3Qge1xuICAgIGRpc3RGb2xkZXIsXG4gICAgaXNQcm9kdWN0aW9uQnVpbGQsXG4gICAgcGx1Z2luTmFtZVxuICB9ID0gcGFyYW1zO1xuXG4gIGlmIChpc1Byb2R1Y3Rpb25CdWlsZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICghcGFyYW1zLm9ic2lkaWFuQ29uZmlnRm9sZGVyKSB7XG4gICAgZ2V0TGliRGVidWdnZXIoJ2RlcGxveVRvT2JzaWRpYW5QbHVnaW5zRm9sZGVyJykoXG4gICAgICAnTm8gT2JzaWRpYW4gY29uZmlnIGZvbGRlciBjb25maWd1cmVkLiBgT0JTSURJQU5fQ09ORklHX0ZPTERFUmAgZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgbm90IHNldCBpbiBzeXN0ZW0gb3IgaW4gYC5lbnZgIGZpbGUuIFRoZSBjb21waWxlZCBwbHVnaW4gd2lsbCBub3QgYmUgY29waWVkIGludG8gT2JzaWRpYW4gcGx1Z2lucyBmb2xkZXIuJ1xuICAgICk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3Qgb2JzaWRpYW5Db25maWdGb2xkZXIgPSB0b1Bvc2l4UGF0aChwYXJhbXMub2JzaWRpYW5Db25maWdGb2xkZXIpO1xuXG4gIGNvbnN0IHBsdWdpbkZvbGRlciA9IGpvaW4ob2JzaWRpYW5Db25maWdGb2xkZXIsICdwbHVnaW5zJywgcGx1Z2luTmFtZSk7XG4gIGF3YWl0IG1rZGlyKHBsdWdpbkZvbGRlciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIGF3YWl0IGNwKGRpc3RGb2xkZXIsIHBsdWdpbkZvbGRlciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgc3dpdGNoIChwYXJhbXMucmVsb2FkID8/ICdob3QtcmVsb2FkLXBsdWdpbicpIHtcbiAgICBjYXNlIGZhbHNlOiB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY2FzZSAnaG90LXJlbG9hZC1wbHVnaW4nOiB7XG4gICAgICBhd2FpdCBpbnN0YWxsQW5kRW5hYmxlSG90UmVsb2FkKHtcbiAgICAgICAgb2JzaWRpYW5Db25maWdGb2xkZXIsXG4gICAgICAgIHBsdWdpbk5hbWVcbiAgICAgIH0pO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGNhc2UgJ29ic2lkaWFuLWNsaSc6IHtcbiAgICAgIGF3YWl0IHJlbG9hZFBsdWdpbldpdGhPYnNpZGlhbkNsaSh7XG4gICAgICAgIHBsdWdpbklkOiBhd2FpdCByZWFkUGx1Z2luSWQocGx1Z2luRm9sZGVyLCBwbHVnaW5OYW1lKSxcbiAgICAgICAgdmF1bHROYW1lOiBiYXNlbmFtZShkaXJuYW1lKG9ic2lkaWFuQ29uZmlnRm9sZGVyKSlcbiAgICAgIH0pO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGRlZmF1bHQ6IHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biByZWxvYWQgb3B0aW9uOiAke1N0cmluZyhwYXJhbXMucmVsb2FkKX1gKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBgbnBtIHJ1biBkZXZgLW93bmVkIE9ic2lkaWFuIGluc3RhbmNlIGZvciB0aGUgZ2l2ZW4gdmF1bHQsIGxhdW5jaGluZyBpdCBvbiBmaXJzdCB1c2UgYW5kXG4gKiByZXVzaW5nIGl0IG9uIHN1YnNlcXVlbnQgcmVidWlsZHMuXG4gKlxuICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB2YXVsdCBmb2xkZXIgdG8gb3Blbi5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHJlc29sdmluZyB0byB0aGUgb3duZWQge0BsaW5rIE9ic2lkaWFuVHJhbnNwb3J0fS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZ2V0T3JMYXVuY2hEZXZJbnN0YW5jZSh2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8T2JzaWRpYW5UcmFuc3BvcnQ+IHtcbiAgbW9kdWxlU3RhdGUuZGV2SW5zdGFuY2VUcmFuc3BvcnRQcm9taXNlID8/PSBsYXVuY2hEZXZJbnN0YW5jZSh2YXVsdFBhdGgpO1xuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBtb2R1bGVTdGF0ZS5kZXZJbnN0YW5jZVRyYW5zcG9ydFByb21pc2U7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgLy8gQ2xlYXIgdGhlIGNhY2hlIHNvIGEgbGF0ZXIgcmVidWlsZCByZXRyaWVzIHRoZSBsYXVuY2guXG4gICAgbW9kdWxlU3RhdGUuZGV2SW5zdGFuY2VUcmFuc3BvcnRQcm9taXNlID0gdW5kZWZpbmVkO1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbi8qKlxuICogSW5zdGFsbHMgdGhlIEhvdFJlbG9hZCBwbHVnaW4gZnJvbSB0aGUgb2ZmaWNpYWwgY29tbXVuaXR5IHN0b3JlIChpZiBub3QgYWxyZWFkeSBpbnN0YWxsZWQpLCBsb2FkcyBpdFxuICogKGlmIG5vdCBhbHJlYWR5IHJ1bm5pbmcpLCBhbmQgZW5hYmxlcyB0aGUgZnJlc2hseS1idWlsdCBwbHVnaW4g4oCUIGFsbCB0aHJvdWdoIHRoZSBgbnBtIHJ1biBkZXZgLW93bmVkXG4gKiBPYnNpZGlhbiBpbnN0YW5jZSwgc28gSG90UmVsb2FkIHRoZW4gYXV0by1yZWZyZXNoZXMgdGhlIGRlcGxveWVkIHBsdWdpbiBvbiBldmVyeSByZWJ1aWxkLlxuICpcbiAqIFRoZSBpbnN0YWxsIGdvZXMgdGhyb3VnaCBPYnNpZGlhbidzIG93biBgaW5zdGFsbFBsdWdpbmAgKHRoZSBjb21tdW5pdHktc3RvcmUgbWVjaGFuaXNtKSwgYW5kIGV2ZXJ5IHN0ZXBcbiAqIHJ1bnMgYWdhaW5zdCB0aGUgb3duZWQgaW5zdGFuY2Ugb3ZlciBDRFA7IGFueSBmYWlsdXJlIHN1cmZhY2VzICh0aGUgZGV2IGJ1aWxkIHJlcG9ydHMgaXQpIHJhdGhlciB0aGFuXG4gKiBiZWluZyBzaWxlbnRseSBzd2FsbG93ZWQuXG4gKlxuICogVGhlIGZpcnN0IHN0ZXAgaXMgbGVhdmluZyByZXN0cmljdGVkIG1vZGUgZm9yIHJlYWwsIHdoaWNoIHRoZSBvd25lZCBpbnN0YW5jZSBoYXMgb25seSBmYWtlZCBzbyBmYXIg4oCUXG4gKiB3aXRob3V0IGl0IFwiZW5hYmxlZFwiIGFuZCBcImxvYWRlZFwiIGNvbWUgYXBhcnQgYW5kIG5vbmUgb2YgdGhlIHZhdWx0J3MgcGx1Z2lucywgSG90UmVsb2FkIGluY2x1ZGVkLCBhcmVcbiAqIHJ1bm5pbmcuIFNlZSB0aGUgY29tbWVudCBvbiB0aGUgYHNldEVuYWJsZWAgY2FsbC5cbiAqXG4gKiBUaGUgaW5zdGFsbC1pZi1taXNzaW5nIC8gZW5hYmxlLWlmLWRpc2FibGVkIGxvZ2ljIGJlbG93IGludGVudGlvbmFsbHkgbWlycm9ycyB0aGUgcHVibGljXG4gKiBgaW5zdGFsbENvbW11bml0eVBsdWdpbmAgLyBgZW5hYmxlQ29tbXVuaXR5UGx1Z2luYCBoZWxwZXJzIGluIGBzcmMvb2JzaWRpYW4vY29tbXVuaXR5LXBsdWdpbnMudHNgLiBJdFxuICogY2Fubm90IGltcG9ydCBhbmQgY2FsbCB0aGVtOiB0aGUgYGZuYCBpcyBzZXJpYWxpemVkIChgdG9TdHJpbmcoKWApIGFuZCBleGVjdXRlZCBpbiB0aGUgcmVuZGVyZXIsIGFuZFxuICogdGhpcyBidWlsZC1vd25lZCBPYnNpZGlhbiBpbnN0YW5jZSBpcyBiYXJlIOKAlCBpdCBoYXMgbm8gZGV2LXV0aWxzIGBsaWJgIHByb3ZpZGVyIHdpcmVkICh0aGF0IHJlc29sdmVyIGlzXG4gKiByZWdpc3RlcmVkIG9ubHkgaW4gdGhlIGludGVncmF0aW9uLXRlc3Qgc2V0dXAsIHdob3NlIGZpeHR1cmUgcHVibGlzaGVzIHRoZSBtZXJnZWQgc3VyZmFjZSBvbiBgd2luZG93YCksXG4gKiBzbyB0aGUgY2xvc3VyZSBoYXMgbm8gYWNjZXNzIHRvIHRoZSBsaWJyYXJ5IHN1cmZhY2UgYW5kIG11c3QgaW5saW5lIHRoZSBlcXVpdmFsZW50IHN0ZXBzLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUge0BsaW5rIEluc3RhbGxBbmRFbmFibGVIb3RSZWxvYWRQYXJhbXN9LlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIEhvdFJlbG9hZCBhbmQgdGhlIGJ1aWx0IHBsdWdpbiBhcmUgaW5zdGFsbGVkIGFuZCBlbmFibGVkLlxuICovXG5hc3luYyBmdW5jdGlvbiBpbnN0YWxsQW5kRW5hYmxlSG90UmVsb2FkKHBhcmFtczogSW5zdGFsbEFuZEVuYWJsZUhvdFJlbG9hZFBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7XG4gICAgb2JzaWRpYW5Db25maWdGb2xkZXIsXG4gICAgcGx1Z2luTmFtZVxuICB9ID0gcGFyYW1zO1xuICBjb25zdCB2YXVsdFBhdGggPSBkaXJuYW1lKG9ic2lkaWFuQ29uZmlnRm9sZGVyKTtcbiAgY29uc3QgdHJhbnNwb3J0ID0gYXdhaXQgZ2V0T3JMYXVuY2hEZXZJbnN0YW5jZSh2YXVsdFBhdGgpO1xuICBhd2FpdCBldmFsSW5PYnNpZGlhbih7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNoYWRvdyAtLSBObyBhY3R1YWwgc2hhZG93aW5nIGFzIHRoZSBmdW5jdGlvbiBpcyBleGVjdXRlZCBleHRlcm5hbGx5LlxuICAgIGFzeW5jIGNhbGxiYWNrKHsgYXBwLCBvYnNpZGlhbk1vZHVsZSwgcGx1Z2luTmFtZSB9KSB7XG4gICAgICBjb25zdCBIT1RfUkVMT0FEX1BMVUdJTl9JRCA9ICdob3QtcmVsb2FkJztcbiAgICAgIGNvbnN0IENPTU1VTklUWV9QTFVHSU5TX1JFR0lTVFJZX1VSTCA9ICdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vb2JzaWRpYW5tZC9vYnNpZGlhbi1yZWxlYXNlcy9IRUFEL2NvbW11bml0eS1wbHVnaW5zLmpzb24nO1xuICAgICAgY29uc3QgeyByZXF1ZXN0VXJsIH0gPSBvYnNpZGlhbk1vZHVsZTtcblxuICAgICAgLypcbiAgICAgICAqIEdlbnVpbmVseSBsZWF2ZSByZXN0cmljdGVkIG1vZGUgYmVmb3JlIHRvdWNoaW5nIGFueXRoaW5nIGVsc2UuIFRoZSBvd25lZCBpbnN0YW5jZSBib290cyB3aXRoIGFcbiAgICAgICAqIGZyZXNoIHVzZXItZGF0YSBkaXIsIHNvIE9ic2lkaWFuIHN0YXJ0cyByZXN0cmljdGVkIGFuZCBgUGx1Z2lucy5pbml0aWFsaXplKClgIHJldHVybnMgYmVmb3JlXG4gICAgICAgKiBsb2FkaW5nIGEgc2luZ2xlIHBsdWdpbi4gVGhlIGhhcm5lc3MgdGhlbiBjbG9zZXMgdGhlIHRydXN0IG1vZGFsIGFuZCB3cml0ZXMgdGhlXG4gICAgICAgKiBgZW5hYmxlLXBsdWdpbi08YXBwSWQ+YCBsb2NhbFN0b3JhZ2UgZmxhZyBkaXJlY3RseSDigJQgZGVsaWJlcmF0ZWx5LCB0byBhdm9pZCBhIHN5bmNocm9ub3VzIGxvYWQg4oCUXG4gICAgICAgKiB3aGljaCBsZWF2ZXMgYGlzRW5hYmxlZCgpYCByZXBvcnRpbmcgYHRydWVgIG92ZXIgYSB2YXVsdCB3aGVyZSBub3RoaW5nIGlzIGFjdHVhbGx5IHJ1bm5pbmcuIEV2ZXJ5XG4gICAgICAgKiBgZW5hYmxlZFBsdWdpbnNgIHJlYWRpbmcgYmVsb3cgKGFuZCBpbiB0aGUgbWlycm9yZWQgYGNvbW11bml0eS1wbHVnaW5zLnRzYCBoZWxwZXJzKSB3b3VsZCBiZVxuICAgICAgICogYW5zd2VyaW5nIGFib3V0IHRoZSB2YXVsdCdzIGNvbmZpZyBmaWxlIHJhdGhlciB0aGFuIHRoaXMgaW5zdGFuY2UuXG4gICAgICAgKlxuICAgICAgICogYHNldEVuYWJsZSh0cnVlKWAgaXMgd2hhdCBPYnNpZGlhbidzIG93biBcIkV4aXQgcmVzdHJpY3RlZCBtb2RlXCIgYnV0dG9uIGNhbGxzOiBpdCByZS1hc3NlcnRzIHRoZVxuICAgICAgICogZmxhZyBhbmQgbG9hZHMgZXZlcnl0aGluZyBpbiBgZW5hYmxlZFBsdWdpbnNgLiBVbmNvbmRpdGlvbmFsIG9uIHB1cnBvc2Ug4oCUIHRoZSBmbGFnIGlzIGFscmVhZHlcbiAgICAgICAqIGB0cnVlYCwgc28gYW4gYGlzRW5hYmxlZCgpYCBndWFyZCB3b3VsZCBza2lwIHRoZSBsb2FkIHRoYXQgaXMgdGhlIHdob2xlIHBvaW50LiBJZGVtcG90ZW50IGFuZFxuICAgICAgICogZWZmZWN0aXZlbHkgZnJlZSBvbmNlIHdhcm0gKGBsb2FkUGx1Z2luYCByZXR1cm5zIHRoZSBsaXZlIGluc3RhbmNlKSwgc28gcmUtcnVubmluZyBpdCBvbiBldmVyeVxuICAgICAgICogcmVidWlsZCBjb3N0cyBub3RoaW5nLlxuICAgICAgICovXG4gICAgICBhd2FpdCBhcHAucGx1Z2lucy5zZXRFbmFibGUodHJ1ZSk7XG5cbiAgICAgIGlmICghT2JqZWN0Lmhhc093bihhcHAucGx1Z2lucy5tYW5pZmVzdHMsIEhPVF9SRUxPQURfUExVR0lOX0lEKSkge1xuICAgICAgICBjb25zdCByZWdpc3RyeVJlc3BvbnNlID0gYXdhaXQgcmVxdWVzdFVybChDT01NVU5JVFlfUExVR0lOU19SRUdJU1RSWV9VUkwpO1xuICAgICAgICBjb25zdCByZWdpc3RyeUVudHJpZXMgPSByZWdpc3RyeVJlc3BvbnNlLmpzb24gYXMgQ29tbXVuaXR5UGx1Z2luUmVnaXN0cnlFbnRyeVtdO1xuICAgICAgICBjb25zdCBlbnRyeSA9IHJlZ2lzdHJ5RW50cmllcy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5pZCA9PT0gSE9UX1JFTE9BRF9QTFVHSU5fSUQpO1xuICAgICAgICBpZiAoIWVudHJ5KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBQbHVnaW4gJyR7SE9UX1JFTE9BRF9QTFVHSU5fSUR9JyB3YXMgbm90IGZvdW5kIGluIHRoZSBPYnNpZGlhbiBjb21tdW5pdHkgcGx1Z2lucyByZWdpc3RyeS5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxhdGVzdFJlbGVhc2VSZXNwb25zZSA9IGF3YWl0IHJlcXVlc3RVcmwoYGh0dHBzOi8vYXBpLmdpdGh1Yi5jb20vcmVwb3MvJHtlbnRyeS5yZXBvfS9yZWxlYXNlcy9sYXRlc3RgKTtcbiAgICAgICAgY29uc3QgbGF0ZXN0UmVsZWFzZSA9IGxhdGVzdFJlbGVhc2VSZXNwb25zZS5qc29uIGFzIEdpdEh1YlJlbGVhc2U7XG4gICAgICAgIGNvbnN0IHZlcnNpb24gPSBsYXRlc3RSZWxlYXNlLnRhZ19uYW1lO1xuICAgICAgICBjb25zdCBtYW5pZmVzdFJlc3BvbnNlID0gYXdhaXQgcmVxdWVzdFVybChgaHR0cHM6Ly9naXRodWIuY29tLyR7ZW50cnkucmVwb30vcmVsZWFzZXMvZG93bmxvYWQvJHt2ZXJzaW9ufS9tYW5pZmVzdC5qc29uYCk7XG4gICAgICAgIGNvbnN0IG1hbmlmZXN0ID0gbWFuaWZlc3RSZXNwb25zZS5qc29uIGFzIFBsdWdpbk1hbmlmZXN0O1xuICAgICAgICBhd2FpdCBhcHAucGx1Z2lucy5pbnN0YWxsUGx1Z2luKGVudHJ5LnJlcG8sIHZlcnNpb24sIG1hbmlmZXN0KTtcbiAgICAgIH1cblxuICAgICAgLypcbiAgICAgICAqIEFzayB3aGV0aGVyIEhvdFJlbG9hZCBpcyBSVU5OSU5HLCBub3Qgd2hldGhlciB0aGUgdmF1bHQgY29uZmlnIGxpc3RzIGl0IGFzIGVuYWJsZWQuIEFmdGVyIHRoZVxuICAgICAgICogYHNldEVuYWJsZWAgYWJvdmUgdGhlIHR3byBub3JtYWxseSBhZ3JlZSwgYnV0IGEgSG90UmVsb2FkIHRoYXQgaXMgbGlzdGVkIGFuZCBmYWlsZWQgdG8gbG9hZCB3b3VsZFxuICAgICAgICogcGFzcyBhbiBgZW5hYmxlZFBsdWdpbnNgIGNoZWNrIHdoaWxlIGxlYXZpbmcgdGhlIGRldiBidWlsZCB3aXRob3V0IGF1dG8tcmVmcmVzaC5cbiAgICAgICAqL1xuICAgICAgaWYgKCFPYmplY3QuaGFzT3duKGFwcC5wbHVnaW5zLnBsdWdpbnMsIEhPVF9SRUxPQURfUExVR0lOX0lEKSkge1xuICAgICAgICBhd2FpdCBhcHAucGx1Z2lucy5lbmFibGVQbHVnaW5BbmRTYXZlKEhPVF9SRUxPQURfUExVR0lOX0lEKTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgYXBwLnBsdWdpbnMuZW5hYmxlUGx1Z2luQW5kU2F2ZShwbHVnaW5OYW1lKTtcbiAgICB9LFxuICAgIGlucHV0OiB7IHBsdWdpbk5hbWUgfSxcbiAgICBzaG91bGRTa2lwUHJlZmxpZ2h0Q2hlY2tzOiB0cnVlLFxuICAgIHRyYW5zcG9ydCxcbiAgICB2YXVsdFBhdGhcbiAgfSk7XG59XG5cbi8qKlxuICogUHJvYmVzIHRoZSBvd25lZCBPYnNpZGlhbiBpbnN0YW5jZSdzIENEUCBlbmRwb2ludCB0byBkZXRlcm1pbmUgd2hldGhlciBpdCBpcyBzdGlsbCBydW5uaW5nLlxuICpcbiAqIEEgY2xvc2VkIGluc3RhbmNlIHN0b3BzIHNlcnZpbmcgQ0RQIGFsdG9nZXRoZXIsIHNvIGFuIHVucmVhY2hhYmxlIGVuZHBvaW50IOKAlCBvciBvbmUgbGVmdCB3aXRoIG5vIHBhZ2VcbiAqIHRhcmdldHMgd2hpbGUgdGhlIGFwcCB0ZWFycyBpdHNlbGYgZG93biDigJQgbWVhbnMgdGhlIGluc3RhbmNlIGlzIGdvbmUuXG4gKlxuICogQHBhcmFtIGNkcFVybCAtIFRoZSBiYXNlIENEUCBVUkwgb2YgdGhlIG93bmVkIGluc3RhbmNlLCBlLmcuIGBodHRwOi8vbG9jYWxob3N0OjUxODg4YC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHJlc29sdmluZyB0byBgdHJ1ZWAgd2hpbGUgdGhlIGluc3RhbmNlIGlzIHN0aWxsIHNlcnZpbmcgYSBwYWdlIHRhcmdldC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gaXNEZXZJbnN0YW5jZVJ1bm5pbmcoY2RwVXJsOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgdHJ5IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1nbG9iYWxzIC0tIFdlIHJ1biB0aGlzIG91dHNpZGUgb2YgT2JzaWRpYW4sIHNvIHdlIGRvbid0IGhhdmUgYHJlcXVlc3RVcmwoKWAuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChgJHtjZHBVcmx9L2pzb25gKTtcbiAgICBjb25zdCB0YXJnZXRzID0gYXdhaXQgcmVzcG9uc2UuanNvbigpIGFzIENkcFRhcmdldFtdO1xuICAgIHJldHVybiB0YXJnZXRzLnNvbWUoKHRhcmdldCkgPT4gdGFyZ2V0LnR5cGUgPT09ICdwYWdlJyk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKipcbiAqIExhdW5jaGVzIGEgZnJlc2ggb3duZWQgT2JzaWRpYW4gaW5zdGFuY2UgKGlzb2xhdGVkIHVzZXItZGF0YSBkaXIpIGFuZCBvcGVucyB0aGUgZ2l2ZW4gdmF1bHQuXG4gKlxuICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB2YXVsdCBmb2xkZXIgdG8gb3Blbi5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHJlc29sdmluZyB0byB0aGUgbGF1bmNoZWQge0BsaW5rIE9ic2lkaWFuVHJhbnNwb3J0fS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gbGF1bmNoRGV2SW5zdGFuY2UodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPE9ic2lkaWFuVHJhbnNwb3J0PiB7XG4gIGNvbnN0IHRyYW5zcG9ydCA9IGF3YWl0IGNyZWF0ZVRyYW5zcG9ydEZyb21PcHRpb25zKCk7XG4gIHRyeSB7XG4gICAgYXdhaXQgdHJhbnNwb3J0LnJlZ2lzdGVyVmF1bHQodmF1bHRQYXRoKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0cmFuc3BvcnQuZGlzcG9zZVN5bmM/LigpO1xuICAgIHRocm93IGVycm9yO1xuICB9XG4gIHJlZ2lzdGVyRGV2SW5zdGFuY2VDbGVhbnVwKHRyYW5zcG9ydCk7XG4gIHdhdGNoRGV2SW5zdGFuY2VBbmRTdG9wT25DbG9zZSh0cmFuc3BvcnQpO1xuICByZXR1cm4gdHJhbnNwb3J0O1xufVxuXG4vKipcbiAqIFJlYWRzIHRoZSBwbHVnaW4gaWQgZnJvbSB0aGUgZGVwbG95ZWQgYG1hbmlmZXN0Lmpzb25gLCB3aGljaCBpcyB3aGF0IE9ic2lkaWFuIGFuZCBpdHMgQ0xJIGtub3cgdGhlIHBsdWdpbiBieS5cbiAqXG4gKiBAcGFyYW0gcGx1Z2luRm9sZGVyIC0gVGhlIGRlcGxveWVkIHBsdWdpbiBmb2xkZXIuXG4gKiBAcGFyYW0gZmFsbGJhY2tJZCAtIFRoZSBpZCB0byB1c2Ugd2hlbiB0aGUgZm9sZGVyIGhhcyBubyByZWFkYWJsZSBtYW5pZmVzdC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHJlc29sdmluZyB0byB0aGUgcGx1Z2luIGlkLlxuICovXG5hc3luYyBmdW5jdGlvbiByZWFkUGx1Z2luSWQocGx1Z2luRm9sZGVyOiBzdHJpbmcsIGZhbGxiYWNrSWQ6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgbWFuaWZlc3QgPSBKU09OLnBhcnNlKGF3YWl0IHJlYWRGaWxlKGpvaW4ocGx1Z2luRm9sZGVyLCAnbWFuaWZlc3QuanNvbicpLCAndXRmLTgnKSkgYXMgUGFydGlhbDxQbHVnaW5NYW5pZmVzdD47XG4gICAgcmV0dXJuIG1hbmlmZXN0LmlkID8/IGZhbGxiYWNrSWQ7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxsYmFja0lkO1xuICB9XG59XG5cbi8qKlxuICogUmVnaXN0ZXJzIHByb2Nlc3MtZXhpdCBhbmQgc2lnbmFsIGhhbmRsZXJzIChvbmNlKSB0aGF0IHN5bmNocm9ub3VzbHkgY2xvc2UgdGhlIG93bmVkIE9ic2lkaWFuXG4gKiBpbnN0YW5jZSB3aGVuIHRoZSBgbnBtIHJ1biBkZXZgIHByb2Nlc3MgdGVybWluYXRlcy5cbiAqXG4gKiBUaGVzZSBoYW5kbGVycyBjb3ZlciBhbiBvcmRlcmx5IHNodXRkb3duLiBBIGBTSUdLSUxMYCAob3IgYSBUYXNrIE1hbmFnZXIgLyBJREUgc3RvcCkgcnVucyBubyBoYW5kbGVyXG4gKiBhdCBhbGwsIGFuZCBubyBvcGVyYXRpbmcgc3lzdGVtIGtpbGxzIHRoZSBpbnN0YW5jZSBqdXN0IGZvciBiZWluZyBvdXIgY2hpbGQg4oCUIHNvIHRoYXQgY2FzZSBpcyBjYXVnaHRcbiAqIGZyb20gdGhlIG90aGVyIHNpZGUsIGJ5IHRoZSBoYXJuZXNzJ3MgcGFyZW50LWxpdmVuZXNzIHdhdGNoZG9nOiB0aGUgaW5zdGFuY2UncyByZW5kZXJlciBob2xkcyBhIHNvY2tldFxuICogYmFjayB0byB0aGlzIHByb2Nlc3MgYW5kIGRlc3Ryb3lzIGl0cyB3aW5kb3cgd2hlbiB0aGUga2VybmVsIGNsb3NlcyBpdC4gU2VlIGBwYXJlbnQtbGl2ZW5lc3MudHNgIGluXG4gKiBgb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZ2AuXG4gKlxuICogQHBhcmFtIHRyYW5zcG9ydCAtIFRoZSBvd25lZCB0cmFuc3BvcnQgdG8gZGlzcG9zZSBvbiBzaHV0ZG93bi5cbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJEZXZJbnN0YW5jZUNsZWFudXAodHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydCk6IHZvaWQge1xuICBpZiAobW9kdWxlU3RhdGUuaXNEZXZJbnN0YW5jZUNsZWFudXBSZWdpc3RlcmVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIG1vZHVsZVN0YXRlLmlzRGV2SW5zdGFuY2VDbGVhbnVwUmVnaXN0ZXJlZCA9IHRydWU7XG5cbiAgLy8gYGV4aXRgIGNvdmVycyBhbnkgYHByb2Nlc3MuZXhpdCgpYCwgYnV0IGEgZGVmYXVsdCBDdHJsK0MgdGVybWluYXRlcyBXSVRIT1VUIGZpcmluZyBgZXhpdGAsIHNvIHRoZSBzaWduYWwgaGFuZGxlcnMgZ3VhcmFudGVlIHRoZSBvd25lZCBPYnNpZGlhbiBpcyBraWxsZWQgb24gc2h1dGRvd24uXG4gIHByb2Nlc3Mub24oJ2V4aXQnLCBkaXNwb3NlRGV2SW5zdGFuY2UpO1xuICBmb3IgKGNvbnN0IHNpZ25hbCBvZiBbJ1NJR0hVUCcsICdTSUdJTlQnLCAnU0lHVEVSTSddIGFzIGNvbnN0KSB7XG4gICAgcHJvY2Vzcy5vbmNlKHNpZ25hbCwgKCkgPT4ge1xuICAgICAgZGlzcG9zZURldkluc3RhbmNlKCk7XG4gICAgICBwcm9jZXNzLmV4aXQoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRpc3Bvc2VEZXZJbnN0YW5jZSgpOiB2b2lkIHtcbiAgICBpZiAobW9kdWxlU3RhdGUuaXNEZXZJbnN0YW5jZURpc3Bvc2VkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIG1vZHVsZVN0YXRlLmlzRGV2SW5zdGFuY2VEaXNwb3NlZCA9IHRydWU7XG4gICAgdHJhbnNwb3J0LmRpc3Bvc2VTeW5jPy4oKTtcbiAgfVxufVxuXG4vKipcbiAqIFdhdGNoZXMgdGhlIGBucG0gcnVuIGRldmAtb3duZWQgT2JzaWRpYW4gaW5zdGFuY2UgYW5kIHN0b3BzIHRoZSBkZXZlbG9wbWVudCBidWlsZCBvbmNlIHRoZSBpbnN0YW5jZSBpc1xuICogY2xvc2VkLlxuICpcbiAqIFRoaXMgaXMgdGhlIG1pcnJvciBpbWFnZSBvZiB7QGxpbmsgcmVnaXN0ZXJEZXZJbnN0YW5jZUNsZWFudXB9OiB0aGF0IG9uZSBjbG9zZXMgdGhlIGluc3RhbmNlIHdoZW4gdGhlXG4gKiBgbnBtIHJ1biBkZXZgIHByb2Nlc3MgdGVybWluYXRlcywgdGhpcyBvbmUgdGVybWluYXRlcyB0aGUgcHJvY2VzcyB3aGVuIHRoZSB1c2VyIGNsb3NlcyB0aGUgaW5zdGFuY2UsIHNvXG4gKiB0aGUgdHdvIG5ldmVyIG91dGxpdmUgZWFjaCBvdGhlci4gQSBidWlsZCB3YXRjaGluZyBhbiBPYnNpZGlhbiB0aGF0IGlzIG5vIGxvbmdlciBydW5uaW5nIGhhcyBub3RoaW5nXG4gKiBsZWZ0IHRvIGRlcGxveSB0by5cbiAqXG4gKiBPbmx5IGEgaGFybmVzcy1vd25lZCBpbnN0YW5jZSBpcyB3YXRjaGVkLiBXaGVuIHRoZSB0cmFuc3BvcnQgYXR0YWNoZXMgdG8gYW4gYWxyZWFkeS1ydW5uaW5nIE9ic2lkaWFuXG4gKiAodGhlIHVzZXIncyBvd24pLCB0aGF0IGluc3RhbmNlIGlzIG5vdCBvdXJzIHRvIGJlIHRpZWQgdG8gYW5kIGNsb3NpbmcgaXQgbGVhdmVzIHRoZSBidWlsZCBydW5uaW5nLlxuICpcbiAqIEBwYXJhbSB0cmFuc3BvcnQgLSBUaGUgb3duZWQgdHJhbnNwb3J0IHdob3NlIGluc3RhbmNlIHRvIHdhdGNoLlxuICovXG5mdW5jdGlvbiB3YXRjaERldkluc3RhbmNlQW5kU3RvcE9uQ2xvc2UodHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydCk6IHZvaWQge1xuICBpZiAoISh0cmFuc3BvcnQgaW5zdGFuY2VvZiBEZXNrdG9wQ2RwVHJhbnNwb3J0KSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGVuZHBvaW50ID0gdHJhbnNwb3J0LmdldE93bmVkSW5zdGFuY2VFbmRwb2ludCgpO1xuICBpZiAoIWVuZHBvaW50KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgY2RwVXJsID0gYGh0dHA6Ly8ke2VuZHBvaW50Lmhvc3R9OiR7U3RyaW5nKGVuZHBvaW50LnBvcnQpfWA7XG4gIGludm9rZUFzeW5jU2FmZWx5KHN0b3BXaGVuRGV2SW5zdGFuY2VDbG9zZXMpO1xuXG4gIGFzeW5jIGZ1bmN0aW9uIHN0b3BXaGVuRGV2SW5zdGFuY2VDbG9zZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbGV0IGNvbnNlY3V0aXZlRmFpbGVkUHJvYmVDb3VudCA9IDA7XG4gICAgd2hpbGUgKGNvbnNlY3V0aXZlRmFpbGVkUHJvYmVDb3VudCA8IERFVl9JTlNUQU5DRV9DTE9TRURfUFJPQkVfQ09VTlQpIHtcbiAgICAgIGF3YWl0IHNsZWVwKHsgbWlsbGlzZWNvbmRzOiBERVZfSU5TVEFOQ0VfUFJPQkVfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTIH0pO1xuXG4gICAgICAvLyBUaGUgcHJvY2VzcyBpcyBhbHJlYWR5IHNodXR0aW5nIGRvd24gYW5kIGtpbGxlZCB0aGUgaW5zdGFuY2UgaXRzZWxmOyB0aGUgcHJvYmVzIHdvdWxkIGp1c3QgcmFjZSB0aGUgdGVhcmRvd24uXG4gICAgICBpZiAobW9kdWxlU3RhdGUuaXNEZXZJbnN0YW5jZURpc3Bvc2VkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc2VjdXRpdmVGYWlsZWRQcm9iZUNvdW50ID0gYXdhaXQgaXNEZXZJbnN0YW5jZVJ1bm5pbmcoY2RwVXJsKSA/IDAgOiBjb25zZWN1dGl2ZUZhaWxlZFByb2JlQ291bnQgKyAxO1xuICAgIH1cblxuICAgIGNvbnNvbGUud2FybignVGhlIE9ic2lkaWFuIGluc3RhbmNlIG93bmVkIGJ5IGBucG0gcnVuIGRldmAgd2FzIGNsb3NlZC4gU3RvcHBpbmcgdGhlIGRldmVsb3BtZW50IGJ1aWxkLicpO1xuICAgIHByb2Nlc3MuZXhpdCgpO1xuICB9XG59XG5cbi8qIHY4IGlnbm9yZSBzdG9wICovXG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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
267
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9idW5kbGVycy9vYnNpZGlhbi1wbHVnaW5zLWZvbGRlci1kZXBsb3ltZW50LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBEZXBsb3lzIGEgZGV2ZWxvcG1lbnQgYnVpbGQgaW50byB0aGUgdmF1bHQ6IGNvcGllcyB0aGUgb3V0cHV0IGZvbGRlciBpbnRvIGA8dmF1bHQ+Ly5vYnNpZGlhbi9wbHVnaW5zYCxcbiAqIHRoZW4gcmVsb2FkcyBpdCB0aGUgd2F5IHRoZSBidWlsZCdzIGByZWxvYWRgIG9wdGlvbiBzYXlzLiBCeSBkZWZhdWx0IHRoYXQgaW5zdGFsbHMgYW5kIGVuYWJsZXMgSG90UmVsb2FkXG4gKiBhbmQgdGhlIHBsdWdpbiBpbiBhbiBPYnNpZGlhbiBpbnN0YW5jZSBgbnBtIHJ1biBkZXZgIG93bnM7IGAnb2JzaWRpYW4tY2xpJ2AgcmVsb2FkcyBpdCBpbiB0aGUgT2JzaWRpYW4gdGhlXG4gKiBkZXZlbG9wZXIgaGFzIG9wZW4gaW5zdGVhZCAoYG9ic2lkaWFuLWNsaS1yZWxvYWQudHNgKS4gRXZlcnkgYnVuZGxlciBhZGFwdGVyIGNhbGxzIGl0IG9uY2UgZWFjaCByZWJ1aWxkIGhhc1xuICogd3JpdHRlbiBpdHMgb3V0cHV0LCBzbyB0aGUgbGF0ZXN0IGJ1aWxkIGlzIGFsd2F5cyB0aGUgb25lIHJ1bm5pbmcuXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIENvcGllcyBidWlsZCBvdXRwdXQgaW50byBhIHZhdWx0IGFuZCBkcml2ZXMgYSBsaXZlIE9ic2lkaWFuIG92ZXIgQ0RQLiAqL1xuXG5pbXBvcnQgdHlwZSB7IFBsdWdpbk1hbmlmZXN0IH0gZnJvbSAnb2JzaWRpYW4nO1xuaW1wb3J0IHR5cGUge1xuICBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9ucyxcbiAgRGVza3RvcENkcFRyYW5zcG9ydCxcbiAgZXZhbEluT2JzaWRpYW4sXG4gIE9ic2lkaWFuVHJhbnNwb3J0XG59IGZyb20gJ29ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmcnO1xuXG5pbXBvcnQge1xuICBpbnZva2VBc3luY1NhZmVseSxcbiAgc2xlZXBcbn0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL2FzeW5jJztcbmltcG9ydCB7IGdldExpYkRlYnVnZ2VyIH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL2RlYnVnJztcbmltcG9ydCB7XG4gIGJhc2VuYW1lLFxuICBkaXJuYW1lLFxuICBqb2luLFxuICB0b1Bvc2l4UGF0aFxufSBmcm9tICdAbW5hb3Vtb3YvdHlwZXNjcmlwdC1saWIvcGF0aCc7XG5pbXBvcnQge1xuICBjcCxcbiAgbWtkaXIsXG4gIHJlYWRGaWxlXG59IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnO1xuaW1wb3J0IHByb2Nlc3MgZnJvbSAnbm9kZTpwcm9jZXNzJztcblxuaW1wb3J0IHR5cGUgeyBPYnNpZGlhblBsdWdpblJlbG9hZCB9IGZyb20gJy4vb2JzaWRpYW4tcGx1Z2luLWJ1aWxkLnRzJztcblxuaW1wb3J0IHsgcmVsb2FkUGx1Z2luV2l0aE9ic2lkaWFuQ2xpIH0gZnJvbSAnLi9vYnNpZGlhbi1jbGktcmVsb2FkLnRzJztcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgZGVwbG95VG9PYnNpZGlhblBsdWdpbnNGb2xkZXJ9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERlcGxveVRvT2JzaWRpYW5QbHVnaW5zRm9sZGVyUGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBmb2xkZXIgd2hlcmUgdGhlIGJ1aWx0IGZpbGVzIGFyZSBsb2NhdGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgZGlzdEZvbGRlcjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBidWlsZCBpcyBhIHByb2R1Y3Rpb24gYnVpbGQuXG4gICAqL1xuICByZWFkb25seSBpc1Byb2R1Y3Rpb25CdWlsZDogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIGZvbGRlciBvZiB0aGUgT2JzaWRpYW4gY29uZmlndXJhdGlvbi4gSWYgbm90IHByb3ZpZGVkLCB0aGUgcGx1Z2luIHdpbGwgbm90IGNvcHkgZmlsZXMuXG4gICAqL1xuICByZWFkb25seSBvYnNpZGlhbkNvbmZpZ0ZvbGRlcjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgT2JzaWRpYW4gcGx1Z2luLlxuICAgKi9cbiAgcmVhZG9ubHkgcGx1Z2luTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBIb3cgdGhlIGRlcGxveWVkIGJ1aWxkIGlzIHJlbG9hZGVkIGluIE9ic2lkaWFuLiBEZWZhdWx0cyB0byBgJ2hvdC1yZWxvYWQtcGx1Z2luJ2AuXG4gICAqL1xuICByZWFkb25seSByZWxvYWQ/OiBPYnNpZGlhblBsdWdpblJlbG9hZDtcbn1cblxuLyoqXG4gKiBUaGUgc3Vic2V0IG9mIGEgQ0RQIHRhcmdldCBkZXNjcmlwdG9yIHJlYWQgZnJvbSB0aGUgb3duZWQgaW5zdGFuY2UncyBgL2pzb25gIGVuZHBvaW50LlxuICovXG5pbnRlcmZhY2UgQ2RwVGFyZ2V0IHtcbiAgLyoqXG4gICAqIFRoZSBraW5kIG9mIHRoZSB0YXJnZXQsIGUuZy4gYHBhZ2VgLlxuICAgKi9cbiAgcmVhZG9ubHkgdHlwZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgc2luZ2xlIGVudHJ5IGluIE9ic2lkaWFuJ3MgY29tbXVuaXR5IHBsdWdpbnMgcmVnaXN0cnkgKGBjb21tdW5pdHktcGx1Z2lucy5qc29uYCkuXG4gKi9cbmludGVyZmFjZSBDb21tdW5pdHlQbHVnaW5SZWdpc3RyeUVudHJ5IHtcbiAgLyoqXG4gICAqIFRoZSBwbHVnaW4gaWQuXG4gICAqL1xuICByZWFkb25seSBpZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgYG93bmVyL25hbWVgIEdpdEh1YiByZXBvc2l0b3J5IHRoZSBwbHVnaW4gaXMgcHVibGlzaGVkIGZyb20uXG4gICAqL1xuICByZWFkb25seSByZXBvOiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIHN1YnNldCBvZiBhIEdpdEh1YiByZWxlYXNlIHdlIHJlYWQuXG4gKi9cbmludGVyZmFjZSBHaXRIdWJSZWxlYXNlIHtcbiAgLyoqXG4gICAqIFRoZSByZWxlYXNlIHRhZywgYSBiYXJlIHZlcnNpb24gc3VjaCBhcyBgMS4yLjNgLlxuICAgKi9cbiAgcmVhZG9ubHkgdGFnX25hbWU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgaW5zdGFsbEFuZEVuYWJsZUhvdFJlbG9hZH0uXG4gKi9cbmludGVyZmFjZSBJbnN0YWxsQW5kRW5hYmxlSG90UmVsb2FkUGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBmb2xkZXIgb2YgdGhlIE9ic2lkaWFuIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICByZWFkb25seSBvYnNpZGlhbkNvbmZpZ0ZvbGRlcjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgYnVpbHQgT2JzaWRpYW4gcGx1Z2luIHRvIGVuYWJsZSBvbmNlIEhvdFJlbG9hZCBpcyBpbiBwbGFjZS5cbiAgICovXG4gIHJlYWRvbmx5IHBsdWdpbk5hbWU6IHN0cmluZztcbn1cblxuLy8gVGhlIGBucG0gcnVuIGRldmAtb3duZWQgT2JzaWRpYW4gaW5zdGFuY2U6IGxhdW5jaGVkIG9uIHRoZSBmaXJzdCByZWJ1aWxkIGFuZCByZXVzZWQgYWNyb3NzIHJlYnVpbGRzLlxuLy8gSXRzIGxpZmV0aW1lIGlzIHRpZWQgdG8gdGhlIGBucG0gcnVuIGRldmAgcHJvY2VzcyBpbiBCT1RIIGRpcmVjdGlvbnMuXG4vLyBUaGUgaW5zdGFuY2UgaXMgY2xvc2VkIHdoZW4gdGhlIHByb2Nlc3MgdGVybWluYXRlcyAoc2VlIGByZWdpc3RlckRldkluc3RhbmNlQ2xlYW51cGApLlxuLy8gVGhlIHByb2Nlc3Mgc3RvcHMgd2hlbiB0aGUgaW5zdGFuY2UgaXMgY2xvc2VkIChzZWUgYHdhdGNoRGV2SW5zdGFuY2VBbmRTdG9wT25DbG9zZWApLlxuLyoqXG5Nb2R1bGUtbGV2ZWwgbXV0YWJsZSBzdGF0ZSwgaGVsZCBpbiBvbmUgb2JqZWN0IHNvIGVhY2ggbXV0YXRpb24gbmFtZXMgaXQgZXhwbGljaXRseS5cbiAqL1xuaW50ZXJmYWNlIE1vZHVsZVN0YXRlIHtcbiAgZGV2SW5zdGFuY2VUcmFuc3BvcnRQcm9taXNlOiBQcm9taXNlPE9ic2lkaWFuVHJhbnNwb3J0PiB8IHVuZGVmaW5lZDtcbiAgaXNEZXZJbnN0YW5jZUNsZWFudXBSZWdpc3RlcmVkOiBib29sZWFuO1xuICBpc0Rldkluc3RhbmNlRGlzcG9zZWQ6IGJvb2xlYW47XG59XG5cbi8qKlxuICogVGhlIG1lbWJlcnMgb2YgYG9ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmdgIHRoZSBgJ2hvdC1yZWxvYWQtcGx1Z2luJ2AgcmVsb2FkIHVzZXMsIGxvYWRlZCBvbiBkZW1hbmQuXG4gKi9cbmludGVyZmFjZSBPYnNpZGlhbkludGVncmF0aW9uVGVzdGluZyB7XG4gIC8qKlxuICAgKiBMYXVuY2hlcyBvciBhdHRhY2hlcyB0byBhbiBPYnNpZGlhbiBpbnN0YW5jZS5cbiAgICovXG4gIHJlYWRvbmx5IGNyZWF0ZVRyYW5zcG9ydEZyb21PcHRpb25zOiB0eXBlb2YgY3JlYXRlVHJhbnNwb3J0RnJvbU9wdGlvbnM7XG5cbiAgLyoqXG4gICAqIFRoZSBkZXNrdG9wIHRyYW5zcG9ydCwgd2hpY2gga25vd3MgdGhlIGVuZHBvaW50IG9mIHRoZSBpbnN0YW5jZSBpdCBvd25zLlxuICAgKi9cbiAgcmVhZG9ubHkgRGVza3RvcENkcFRyYW5zcG9ydDogdHlwZW9mIERlc2t0b3BDZHBUcmFuc3BvcnQ7XG5cbiAgLyoqXG4gICAqIFJ1bnMgYSBjYWxsYmFjayBpbnNpZGUgT2JzaWRpYW4uXG4gICAqL1xuICByZWFkb25seSBldmFsSW5PYnNpZGlhbjogdHlwZW9mIGV2YWxJbk9ic2lkaWFuO1xufVxuXG5jb25zdCBtb2R1bGVTdGF0ZTogTW9kdWxlU3RhdGUgPSB7XG4gIGRldkluc3RhbmNlVHJhbnNwb3J0UHJvbWlzZTogdW5kZWZpbmVkLFxuICBpc0Rldkluc3RhbmNlQ2xlYW51cFJlZ2lzdGVyZWQ6IGZhbHNlLFxuICBpc0Rldkluc3RhbmNlRGlzcG9zZWQ6IGZhbHNlXG59O1xuXG4vKipcbiAqIFRoZSBwYWNrYWdlIHRoZSBgJ2hvdC1yZWxvYWQtcGx1Z2luJ2AgcmVsb2FkIGRyaXZlcyB0aGUgb3duZWQgT2JzaWRpYW4gaW5zdGFuY2Ugd2l0aC4gSXQgaXMgYW4gb3B0aW9uYWwgcGVlclxuICogZGVwZW5kZW5jeSwgc28gaXQgaXMgbG9hZGVkIG9ubHkgd2hlbiB0aGF0IHJlbG9hZCBydW5zOiBldmVyeSBidW5kbGVyIGFkYXB0ZXIgaW1wb3J0cyB0aGlzIG1vZHVsZSwgYW5kIGEgcHJvamVjdFxuICogdGhhdCByZWxvYWRzIGFub3RoZXIgd2F5LCBvciBidWlsZHMgZm9yIHByb2R1Y3Rpb24gb25seSwgZG9lcyBub3QgbmVlZCBpdC5cbiAqL1xuY29uc3QgT0JTSURJQU5fSU5URUdSQVRJT05fVEVTVElOR19QQUNLQUdFX05BTUUgPSAnb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZyc7XG5cbi8qKlxuICogSG93IG9mdGVuIHRoZSBvd25lZCBPYnNpZGlhbiBpbnN0YW5jZSBpcyBwcm9iZWQgdG8gZGV0ZWN0IHRoYXQgaXQgd2FzIGNsb3NlZC5cbiAqL1xuY29uc3QgREVWX0lOU1RBTkNFX1BST0JFX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDIwMDA7XG5cbi8qKlxuICogSG93IG1hbnkgY29uc2VjdXRpdmUgZmFpbGVkIHByb2JlcyBhcmUgdG9sZXJhdGVkIGJlZm9yZSB0aGUgb3duZWQgaW5zdGFuY2UgaXMgY29uc2lkZXJlZCBjbG9zZWQuIEFcbiAqIHNpbmdsZSBmYWlsdXJlIGNhbiBiZSBhIHRyYW5zaWVudCBoaWNjdXAgKGEgYnVzeSByZW5kZXJlciwgYSBtb21lbnRhcmlseSByZWZ1c2VkIGNvbm5lY3Rpb24pLCBzbyB0aGVcbiAqIGRldmVsb3BtZW50IGJ1aWxkIGlzIG9ubHkgc3RvcHBlZCBvbmNlIHRoZSBlbmRwb2ludCBzdGF5cyB1bnJlYWNoYWJsZS5cbiAqL1xuY29uc3QgREVWX0lOU1RBTkNFX0NMT1NFRF9QUk9CRV9DT1VOVCA9IDM7XG4vKipcbiAqIENvcGllcyBhIGRldmVsb3BtZW50IGJ1aWxkIGludG8gdGhlIHZhdWx0J3MgcGx1Z2lucyBmb2xkZXIgYW5kIHJlbG9hZHMgaXQgdGhlcmUsIGFzIHRoZSBgcmVsb2FkYCBvcHRpb25cbiAqIHNheXMuIERvZXMgbm90aGluZyBmb3IgYSBwcm9kdWN0aW9uIGJ1aWxkLCBvciB3aGVuIG5vIE9ic2lkaWFuIGNvbmZpZyBmb2xkZXIgaXMgY29uZmlndXJlZC5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHtAbGluayBEZXBsb3lUb09ic2lkaWFuUGx1Z2luc0ZvbGRlclBhcmFtc30uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIHBsdWdpbiBpcyBkZXBsb3llZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlcGxveVRvT2JzaWRpYW5QbHVnaW5zRm9sZGVyKHBhcmFtczogRGVwbG95VG9PYnNpZGlhblBsdWdpbnNGb2xkZXJQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3Qge1xuICAgIGRpc3RGb2xkZXIsXG4gICAgaXNQcm9kdWN0aW9uQnVpbGQsXG4gICAgcGx1Z2luTmFtZVxuICB9ID0gcGFyYW1zO1xuXG4gIGlmIChpc1Byb2R1Y3Rpb25CdWlsZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICghcGFyYW1zLm9ic2lkaWFuQ29uZmlnRm9sZGVyKSB7XG4gICAgZ2V0TGliRGVidWdnZXIoJ2RlcGxveVRvT2JzaWRpYW5QbHVnaW5zRm9sZGVyJykoXG4gICAgICAnTm8gT2JzaWRpYW4gY29uZmlnIGZvbGRlciBjb25maWd1cmVkLiBgT0JTSURJQU5fQ09ORklHX0ZPTERFUmAgZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgbm90IHNldCBpbiBzeXN0ZW0gb3IgaW4gYC5lbnZgIGZpbGUuIFRoZSBjb21waWxlZCBwbHVnaW4gd2lsbCBub3QgYmUgY29waWVkIGludG8gT2JzaWRpYW4gcGx1Z2lucyBmb2xkZXIuJ1xuICAgICk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3Qgb2JzaWRpYW5Db25maWdGb2xkZXIgPSB0b1Bvc2l4UGF0aChwYXJhbXMub2JzaWRpYW5Db25maWdGb2xkZXIpO1xuXG4gIGNvbnN0IHBsdWdpbkZvbGRlciA9IGpvaW4ob2JzaWRpYW5Db25maWdGb2xkZXIsICdwbHVnaW5zJywgcGx1Z2luTmFtZSk7XG4gIGF3YWl0IG1rZGlyKHBsdWdpbkZvbGRlciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIGF3YWl0IGNwKGRpc3RGb2xkZXIsIHBsdWdpbkZvbGRlciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgc3dpdGNoIChwYXJhbXMucmVsb2FkID8/ICdob3QtcmVsb2FkLXBsdWdpbicpIHtcbiAgICBjYXNlIGZhbHNlOiB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY2FzZSAnaG90LXJlbG9hZC1wbHVnaW4nOiB7XG4gICAgICBhd2FpdCBpbnN0YWxsQW5kRW5hYmxlSG90UmVsb2FkKHtcbiAgICAgICAgb2JzaWRpYW5Db25maWdGb2xkZXIsXG4gICAgICAgIHBsdWdpbk5hbWVcbiAgICAgIH0pO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGNhc2UgJ29ic2lkaWFuLWNsaSc6IHtcbiAgICAgIGF3YWl0IHJlbG9hZFBsdWdpbldpdGhPYnNpZGlhbkNsaSh7XG4gICAgICAgIHBsdWdpbklkOiBhd2FpdCByZWFkUGx1Z2luSWQocGx1Z2luRm9sZGVyLCBwbHVnaW5OYW1lKSxcbiAgICAgICAgdmF1bHROYW1lOiBiYXNlbmFtZShkaXJuYW1lKG9ic2lkaWFuQ29uZmlnRm9sZGVyKSlcbiAgICAgIH0pO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGRlZmF1bHQ6IHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biByZWxvYWQgb3B0aW9uOiAke1N0cmluZyhwYXJhbXMucmVsb2FkKX1gKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBgbnBtIHJ1biBkZXZgLW93bmVkIE9ic2lkaWFuIGluc3RhbmNlIGZvciB0aGUgZ2l2ZW4gdmF1bHQsIGxhdW5jaGluZyBpdCBvbiBmaXJzdCB1c2UgYW5kXG4gKiByZXVzaW5nIGl0IG9uIHN1YnNlcXVlbnQgcmVidWlsZHMuXG4gKlxuICogQHBhcmFtIG9ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nIC0gVGhlIGxvYWRlZCBgb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZ2AgbW9kdWxlLlxuICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB2YXVsdCBmb2xkZXIgdG8gb3Blbi5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHJlc29sdmluZyB0byB0aGUgb3duZWQge0BsaW5rIE9ic2lkaWFuVHJhbnNwb3J0fS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZ2V0T3JMYXVuY2hEZXZJbnN0YW5jZShvYnNpZGlhbkludGVncmF0aW9uVGVzdGluZzogT2JzaWRpYW5JbnRlZ3JhdGlvblRlc3RpbmcsIHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTxPYnNpZGlhblRyYW5zcG9ydD4ge1xuICBtb2R1bGVTdGF0ZS5kZXZJbnN0YW5jZVRyYW5zcG9ydFByb21pc2UgPz89IGxhdW5jaERldkluc3RhbmNlKG9ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nLCB2YXVsdFBhdGgpO1xuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBtb2R1bGVTdGF0ZS5kZXZJbnN0YW5jZVRyYW5zcG9ydFByb21pc2U7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgLy8gQ2xlYXIgdGhlIGNhY2hlIHNvIGEgbGF0ZXIgcmVidWlsZCByZXRyaWVzIHRoZSBsYXVuY2guXG4gICAgbW9kdWxlU3RhdGUuZGV2SW5zdGFuY2VUcmFuc3BvcnRQcm9taXNlID0gdW5kZWZpbmVkO1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbi8qKlxuICogTG9hZHMgYG9ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmdgLCB3aGljaCBvbmx5IHRoZSBgJ2hvdC1yZWxvYWQtcGx1Z2luJ2AgcmVsb2FkIG5lZWRzLlxuICpcbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHJlc29sdmluZyB0byB0aGUgbW9kdWxlLlxuICogQHRocm93cyBJZiB0aGUgcHJvamVjdCBkb2VzIG5vdCBoYXZlIHRoZSBwYWNrYWdlLCBuYW1pbmcgdGhlIGNvbW1hbmQgdGhhdCBpbnN0YWxscyBpdCBhbmQgdGhlIGByZWxvYWRgIHZhbHVlc1xuICogdGhhdCBkbyB3aXRob3V0IGl0LlxuICovXG5hc3luYyBmdW5jdGlvbiBpbXBvcnRPYnNpZGlhbkludGVncmF0aW9uVGVzdGluZygpOiBQcm9taXNlPE9ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nPiB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IGltcG9ydCgnb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZycpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmICghaXNNaXNzaW5nUGFja2FnZUVycm9yKGVycm9yKSkge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBUaGUgZGV2ZWxvcG1lbnQgYnVpbGQncyBcXGByZWxvYWQ6ICdob3QtcmVsb2FkLXBsdWdpbidcXGAgKHRoZSBkZWZhdWx0KSBuZWVkcyBcXGAke09CU0lESUFOX0lOVEVHUkFUSU9OX1RFU1RJTkdfUEFDS0FHRV9OQU1FfVxcYCwgd2hpY2ggdGhpcyBwcm9qZWN0IGRvZXMgbm90IGhhdmUuIEluc3RhbGwgaXQgd2l0aDogbnBtIGluc3RhbGwgLS1zYXZlLWRldiAke09CU0lESUFOX0lOVEVHUkFUSU9OX1RFU1RJTkdfUEFDS0FHRV9OQU1FfSwgb3Igc2V0IFxcYHJlbG9hZFxcYCB0byBcXGAnb2JzaWRpYW4tY2xpJ1xcYCBvciBcXGBmYWxzZVxcYC5gLFxuICAgICAgeyBjYXVzZTogZXJyb3IgfVxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBJbnN0YWxscyB0aGUgSG90UmVsb2FkIHBsdWdpbiBmcm9tIHRoZSBvZmZpY2lhbCBjb21tdW5pdHkgc3RvcmUgKGlmIG5vdCBhbHJlYWR5IGluc3RhbGxlZCksIGxvYWRzIGl0XG4gKiAoaWYgbm90IGFscmVhZHkgcnVubmluZyksIGFuZCBlbmFibGVzIHRoZSBmcmVzaGx5LWJ1aWx0IHBsdWdpbiDigJQgYWxsIHRocm91Z2ggdGhlIGBucG0gcnVuIGRldmAtb3duZWRcbiAqIE9ic2lkaWFuIGluc3RhbmNlLCBzbyBIb3RSZWxvYWQgdGhlbiBhdXRvLXJlZnJlc2hlcyB0aGUgZGVwbG95ZWQgcGx1Z2luIG9uIGV2ZXJ5IHJlYnVpbGQuXG4gKlxuICogVGhlIGluc3RhbGwgZ29lcyB0aHJvdWdoIE9ic2lkaWFuJ3Mgb3duIGBpbnN0YWxsUGx1Z2luYCAodGhlIGNvbW11bml0eS1zdG9yZSBtZWNoYW5pc20pLCBhbmQgZXZlcnkgc3RlcFxuICogcnVucyBhZ2FpbnN0IHRoZSBvd25lZCBpbnN0YW5jZSBvdmVyIENEUDsgYW55IGZhaWx1cmUgc3VyZmFjZXMgKHRoZSBkZXYgYnVpbGQgcmVwb3J0cyBpdCkgcmF0aGVyIHRoYW5cbiAqIGJlaW5nIHNpbGVudGx5IHN3YWxsb3dlZC5cbiAqXG4gKiBUaGUgZmlyc3Qgc3RlcCBpcyBsZWF2aW5nIHJlc3RyaWN0ZWQgbW9kZSBmb3IgcmVhbCwgd2hpY2ggdGhlIG93bmVkIGluc3RhbmNlIGhhcyBvbmx5IGZha2VkIHNvIGZhciDigJRcbiAqIHdpdGhvdXQgaXQgXCJlbmFibGVkXCIgYW5kIFwibG9hZGVkXCIgY29tZSBhcGFydCBhbmQgbm9uZSBvZiB0aGUgdmF1bHQncyBwbHVnaW5zLCBIb3RSZWxvYWQgaW5jbHVkZWQsIGFyZVxuICogcnVubmluZy4gU2VlIHRoZSBjb21tZW50IG9uIHRoZSBgc2V0RW5hYmxlYCBjYWxsLlxuICpcbiAqIFRoZSBpbnN0YWxsLWlmLW1pc3NpbmcgLyBlbmFibGUtaWYtZGlzYWJsZWQgbG9naWMgYmVsb3cgaW50ZW50aW9uYWxseSBtaXJyb3JzIHRoZSBwdWJsaWNcbiAqIGBpbnN0YWxsQ29tbXVuaXR5UGx1Z2luYCAvIGBlbmFibGVDb21tdW5pdHlQbHVnaW5gIGhlbHBlcnMgaW4gYHNyYy9vYnNpZGlhbi9jb21tdW5pdHktcGx1Z2lucy50c2AuIEl0XG4gKiBjYW5ub3QgaW1wb3J0IGFuZCBjYWxsIHRoZW06IHRoZSBgZm5gIGlzIHNlcmlhbGl6ZWQgKGB0b1N0cmluZygpYCkgYW5kIGV4ZWN1dGVkIGluIHRoZSByZW5kZXJlciwgYW5kXG4gKiB0aGlzIGJ1aWxkLW93bmVkIE9ic2lkaWFuIGluc3RhbmNlIGlzIGJhcmUg4oCUIGl0IGhhcyBubyBkZXYtdXRpbHMgYGxpYmAgcHJvdmlkZXIgd2lyZWQgKHRoYXQgcmVzb2x2ZXIgaXNcbiAqIHJlZ2lzdGVyZWQgb25seSBpbiB0aGUgaW50ZWdyYXRpb24tdGVzdCBzZXR1cCwgd2hvc2UgZml4dHVyZSBwdWJsaXNoZXMgdGhlIG1lcmdlZCBzdXJmYWNlIG9uIGB3aW5kb3dgKSxcbiAqIHNvIHRoZSBjbG9zdXJlIGhhcyBubyBhY2Nlc3MgdG8gdGhlIGxpYnJhcnkgc3VyZmFjZSBhbmQgbXVzdCBpbmxpbmUgdGhlIGVxdWl2YWxlbnQgc3RlcHMuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSB7QGxpbmsgSW5zdGFsbEFuZEVuYWJsZUhvdFJlbG9hZFBhcmFtc30uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgSG90UmVsb2FkIGFuZCB0aGUgYnVpbHQgcGx1Z2luIGFyZSBpbnN0YWxsZWQgYW5kIGVuYWJsZWQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGluc3RhbGxBbmRFbmFibGVIb3RSZWxvYWQocGFyYW1zOiBJbnN0YWxsQW5kRW5hYmxlSG90UmVsb2FkUGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHtcbiAgICBvYnNpZGlhbkNvbmZpZ0ZvbGRlcixcbiAgICBwbHVnaW5OYW1lXG4gIH0gPSBwYXJhbXM7XG4gIGNvbnN0IHZhdWx0UGF0aCA9IGRpcm5hbWUob2JzaWRpYW5Db25maWdGb2xkZXIpO1xuICBjb25zdCBvYnNpZGlhbkludGVncmF0aW9uVGVzdGluZyA9IGF3YWl0IGltcG9ydE9ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nKCk7XG4gIGNvbnN0IHRyYW5zcG9ydCA9IGF3YWl0IGdldE9yTGF1bmNoRGV2SW5zdGFuY2Uob2JzaWRpYW5JbnRlZ3JhdGlvblRlc3RpbmcsIHZhdWx0UGF0aCk7XG4gIGF3YWl0IG9ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nLmV2YWxJbk9ic2lkaWFuKHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2hhZG93IC0tIE5vIGFjdHVhbCBzaGFkb3dpbmcgYXMgdGhlIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkIGV4dGVybmFsbHkuXG4gICAgYXN5bmMgY2FsbGJhY2soeyBhcHAsIG9ic2lkaWFuTW9kdWxlLCBwbHVnaW5OYW1lIH0pIHtcbiAgICAgIGNvbnN0IEhPVF9SRUxPQURfUExVR0lOX0lEID0gJ2hvdC1yZWxvYWQnO1xuICAgICAgY29uc3QgQ09NTVVOSVRZX1BMVUdJTlNfUkVHSVNUUllfVVJMID0gJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9vYnNpZGlhbm1kL29ic2lkaWFuLXJlbGVhc2VzL0hFQUQvY29tbXVuaXR5LXBsdWdpbnMuanNvbic7XG4gICAgICBjb25zdCB7IHJlcXVlc3RVcmwgfSA9IG9ic2lkaWFuTW9kdWxlO1xuXG4gICAgICAvKlxuICAgICAgICogR2VudWluZWx5IGxlYXZlIHJlc3RyaWN0ZWQgbW9kZSBiZWZvcmUgdG91Y2hpbmcgYW55dGhpbmcgZWxzZS4gVGhlIG93bmVkIGluc3RhbmNlIGJvb3RzIHdpdGggYVxuICAgICAgICogZnJlc2ggdXNlci1kYXRhIGRpciwgc28gT2JzaWRpYW4gc3RhcnRzIHJlc3RyaWN0ZWQgYW5kIGBQbHVnaW5zLmluaXRpYWxpemUoKWAgcmV0dXJucyBiZWZvcmVcbiAgICAgICAqIGxvYWRpbmcgYSBzaW5nbGUgcGx1Z2luLiBUaGUgaGFybmVzcyB0aGVuIGNsb3NlcyB0aGUgdHJ1c3QgbW9kYWwgYW5kIHdyaXRlcyB0aGVcbiAgICAgICAqIGBlbmFibGUtcGx1Z2luLTxhcHBJZD5gIGxvY2FsU3RvcmFnZSBmbGFnIGRpcmVjdGx5IOKAlCBkZWxpYmVyYXRlbHksIHRvIGF2b2lkIGEgc3luY2hyb25vdXMgbG9hZCDigJRcbiAgICAgICAqIHdoaWNoIGxlYXZlcyBgaXNFbmFibGVkKClgIHJlcG9ydGluZyBgdHJ1ZWAgb3ZlciBhIHZhdWx0IHdoZXJlIG5vdGhpbmcgaXMgYWN0dWFsbHkgcnVubmluZy4gRXZlcnlcbiAgICAgICAqIGBlbmFibGVkUGx1Z2luc2AgcmVhZGluZyBiZWxvdyAoYW5kIGluIHRoZSBtaXJyb3JlZCBgY29tbXVuaXR5LXBsdWdpbnMudHNgIGhlbHBlcnMpIHdvdWxkIGJlXG4gICAgICAgKiBhbnN3ZXJpbmcgYWJvdXQgdGhlIHZhdWx0J3MgY29uZmlnIGZpbGUgcmF0aGVyIHRoYW4gdGhpcyBpbnN0YW5jZS5cbiAgICAgICAqXG4gICAgICAgKiBgc2V0RW5hYmxlKHRydWUpYCBpcyB3aGF0IE9ic2lkaWFuJ3Mgb3duIFwiRXhpdCByZXN0cmljdGVkIG1vZGVcIiBidXR0b24gY2FsbHM6IGl0IHJlLWFzc2VydHMgdGhlXG4gICAgICAgKiBmbGFnIGFuZCBsb2FkcyBldmVyeXRoaW5nIGluIGBlbmFibGVkUGx1Z2luc2AuIFVuY29uZGl0aW9uYWwgb24gcHVycG9zZSDigJQgdGhlIGZsYWcgaXMgYWxyZWFkeVxuICAgICAgICogYHRydWVgLCBzbyBhbiBgaXNFbmFibGVkKClgIGd1YXJkIHdvdWxkIHNraXAgdGhlIGxvYWQgdGhhdCBpcyB0aGUgd2hvbGUgcG9pbnQuIElkZW1wb3RlbnQgYW5kXG4gICAgICAgKiBlZmZlY3RpdmVseSBmcmVlIG9uY2Ugd2FybSAoYGxvYWRQbHVnaW5gIHJldHVybnMgdGhlIGxpdmUgaW5zdGFuY2UpLCBzbyByZS1ydW5uaW5nIGl0IG9uIGV2ZXJ5XG4gICAgICAgKiByZWJ1aWxkIGNvc3RzIG5vdGhpbmcuXG4gICAgICAgKi9cbiAgICAgIGF3YWl0IGFwcC5wbHVnaW5zLnNldEVuYWJsZSh0cnVlKTtcblxuICAgICAgaWYgKCFPYmplY3QuaGFzT3duKGFwcC5wbHVnaW5zLm1hbmlmZXN0cywgSE9UX1JFTE9BRF9QTFVHSU5fSUQpKSB7XG4gICAgICAgIGNvbnN0IHJlZ2lzdHJ5UmVzcG9uc2UgPSBhd2FpdCByZXF1ZXN0VXJsKENPTU1VTklUWV9QTFVHSU5TX1JFR0lTVFJZX1VSTCk7XG4gICAgICAgIGNvbnN0IHJlZ2lzdHJ5RW50cmllcyA9IHJlZ2lzdHJ5UmVzcG9uc2UuanNvbiBhcyBDb21tdW5pdHlQbHVnaW5SZWdpc3RyeUVudHJ5W107XG4gICAgICAgIGNvbnN0IGVudHJ5ID0gcmVnaXN0cnlFbnRyaWVzLmZpbmQoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLmlkID09PSBIT1RfUkVMT0FEX1BMVUdJTl9JRCk7XG4gICAgICAgIGlmICghZW50cnkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFBsdWdpbiAnJHtIT1RfUkVMT0FEX1BMVUdJTl9JRH0nIHdhcyBub3QgZm91bmQgaW4gdGhlIE9ic2lkaWFuIGNvbW11bml0eSBwbHVnaW5zIHJlZ2lzdHJ5LmApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGF0ZXN0UmVsZWFzZVJlc3BvbnNlID0gYXdhaXQgcmVxdWVzdFVybChgaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy8ke2VudHJ5LnJlcG99L3JlbGVhc2VzL2xhdGVzdGApO1xuICAgICAgICBjb25zdCBsYXRlc3RSZWxlYXNlID0gbGF0ZXN0UmVsZWFzZVJlc3BvbnNlLmpzb24gYXMgR2l0SHViUmVsZWFzZTtcbiAgICAgICAgY29uc3QgdmVyc2lvbiA9IGxhdGVzdFJlbGVhc2UudGFnX25hbWU7XG4gICAgICAgIGNvbnN0IG1hbmlmZXN0UmVzcG9uc2UgPSBhd2FpdCByZXF1ZXN0VXJsKGBodHRwczovL2dpdGh1Yi5jb20vJHtlbnRyeS5yZXBvfS9yZWxlYXNlcy9kb3dubG9hZC8ke3ZlcnNpb259L21hbmlmZXN0Lmpzb25gKTtcbiAgICAgICAgY29uc3QgbWFuaWZlc3QgPSBtYW5pZmVzdFJlc3BvbnNlLmpzb24gYXMgUGx1Z2luTWFuaWZlc3Q7XG4gICAgICAgIGF3YWl0IGFwcC5wbHVnaW5zLmluc3RhbGxQbHVnaW4oZW50cnkucmVwbywgdmVyc2lvbiwgbWFuaWZlc3QpO1xuICAgICAgfVxuXG4gICAgICAvKlxuICAgICAgICogQXNrIHdoZXRoZXIgSG90UmVsb2FkIGlzIFJVTk5JTkcsIG5vdCB3aGV0aGVyIHRoZSB2YXVsdCBjb25maWcgbGlzdHMgaXQgYXMgZW5hYmxlZC4gQWZ0ZXIgdGhlXG4gICAgICAgKiBgc2V0RW5hYmxlYCBhYm92ZSB0aGUgdHdvIG5vcm1hbGx5IGFncmVlLCBidXQgYSBIb3RSZWxvYWQgdGhhdCBpcyBsaXN0ZWQgYW5kIGZhaWxlZCB0byBsb2FkIHdvdWxkXG4gICAgICAgKiBwYXNzIGFuIGBlbmFibGVkUGx1Z2luc2AgY2hlY2sgd2hpbGUgbGVhdmluZyB0aGUgZGV2IGJ1aWxkIHdpdGhvdXQgYXV0by1yZWZyZXNoLlxuICAgICAgICovXG4gICAgICBpZiAoIU9iamVjdC5oYXNPd24oYXBwLnBsdWdpbnMucGx1Z2lucywgSE9UX1JFTE9BRF9QTFVHSU5fSUQpKSB7XG4gICAgICAgIGF3YWl0IGFwcC5wbHVnaW5zLmVuYWJsZVBsdWdpbkFuZFNhdmUoSE9UX1JFTE9BRF9QTFVHSU5fSUQpO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBhcHAucGx1Z2lucy5lbmFibGVQbHVnaW5BbmRTYXZlKHBsdWdpbk5hbWUpO1xuICAgIH0sXG4gICAgaW5wdXQ6IHsgcGx1Z2luTmFtZSB9LFxuICAgIHNob3VsZFNraXBQcmVmbGlnaHRDaGVja3M6IHRydWUsXG4gICAgdHJhbnNwb3J0LFxuICAgIHZhdWx0UGF0aFxuICB9KTtcbn1cblxuLyoqXG4gKiBQcm9iZXMgdGhlIG93bmVkIE9ic2lkaWFuIGluc3RhbmNlJ3MgQ0RQIGVuZHBvaW50IHRvIGRldGVybWluZSB3aGV0aGVyIGl0IGlzIHN0aWxsIHJ1bm5pbmcuXG4gKlxuICogQSBjbG9zZWQgaW5zdGFuY2Ugc3RvcHMgc2VydmluZyBDRFAgYWx0b2dldGhlciwgc28gYW4gdW5yZWFjaGFibGUgZW5kcG9pbnQg4oCUIG9yIG9uZSBsZWZ0IHdpdGggbm8gcGFnZVxuICogdGFyZ2V0cyB3aGlsZSB0aGUgYXBwIHRlYXJzIGl0c2VsZiBkb3duIOKAlCBtZWFucyB0aGUgaW5zdGFuY2UgaXMgZ29uZS5cbiAqXG4gKiBAcGFyYW0gY2RwVXJsIC0gVGhlIGJhc2UgQ0RQIFVSTCBvZiB0aGUgb3duZWQgaW5zdGFuY2UsIGUuZy4gYGh0dHA6Ly9sb2NhbGhvc3Q6NTE4ODhgLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gcmVzb2x2aW5nIHRvIGB0cnVlYCB3aGlsZSB0aGUgaW5zdGFuY2UgaXMgc3RpbGwgc2VydmluZyBhIHBhZ2UgdGFyZ2V0LlxuICovXG5hc3luYyBmdW5jdGlvbiBpc0Rldkluc3RhbmNlUnVubmluZyhjZHBVcmw6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICB0cnkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1yZXN0cmljdGVkLWdsb2JhbHMgLS0gV2UgcnVuIHRoaXMgb3V0c2lkZSBvZiBPYnNpZGlhbiwgc28gd2UgZG9uJ3QgaGF2ZSBgcmVxdWVzdFVybCgpYC5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke2NkcFVybH0vanNvbmApO1xuICAgIGNvbnN0IHRhcmdldHMgPSBhd2FpdCByZXNwb25zZS5qc29uKCkgYXMgQ2RwVGFyZ2V0W107XG4gICAgcmV0dXJuIHRhcmdldHMuc29tZSgodGFyZ2V0KSA9PiB0YXJnZXQudHlwZSA9PT0gJ3BhZ2UnKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogVGVsbHMgd2hldGhlciBhbiBpbXBvcnQgZmFpbGVkIGJlY2F1c2UgYG9ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmdgIGl0c2VsZiBpcyBub3QgaW5zdGFsbGVkLCBhcyBvcHBvc2VkIHRvXG4gKiBmYWlsaW5nIHdoaWxlIGxvYWRpbmcgaXQuXG4gKlxuICogQHBhcmFtIGVycm9yIC0gVGhlIGVycm9yIHRoZSBpbXBvcnQgdGhyZXcuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgd2hlbiB0aGUgcGFja2FnZSBjb3VsZCBub3QgYmUgZm91bmQuXG4gKi9cbmZ1bmN0aW9uIGlzTWlzc2luZ1BhY2thZ2VFcnJvcihlcnJvcjogdW5rbm93bik6IGJvb2xlYW4ge1xuICBpZiAoIShlcnJvciBpbnN0YW5jZW9mIEVycm9yKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBjb25zdCB7IGNvZGUgfSA9IGVycm9yIGFzIE5vZGVKUy5FcnJub0V4Y2VwdGlvbjtcbiAgcmV0dXJuIChjb2RlID09PSAnRVJSX01PRFVMRV9OT1RfRk9VTkQnIHx8IGNvZGUgPT09ICdNT0RVTEVfTk9UX0ZPVU5EJykgJiYgZXJyb3IubWVzc2FnZS5pbmNsdWRlcyhgJyR7T0JTSURJQU5fSU5URUdSQVRJT05fVEVTVElOR19QQUNLQUdFX05BTUV9J2ApO1xufVxuXG4vKipcbiAqIExhdW5jaGVzIGEgZnJlc2ggb3duZWQgT2JzaWRpYW4gaW5zdGFuY2UgKGlzb2xhdGVkIHVzZXItZGF0YSBkaXIpIGFuZCBvcGVucyB0aGUgZ2l2ZW4gdmF1bHQuXG4gKlxuICogQHBhcmFtIG9ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nIC0gVGhlIGxvYWRlZCBgb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZ2AgbW9kdWxlLlxuICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB2YXVsdCBmb2xkZXIgdG8gb3Blbi5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHJlc29sdmluZyB0byB0aGUgbGF1bmNoZWQge0BsaW5rIE9ic2lkaWFuVHJhbnNwb3J0fS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gbGF1bmNoRGV2SW5zdGFuY2Uob2JzaWRpYW5JbnRlZ3JhdGlvblRlc3Rpbmc6IE9ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nLCB2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8T2JzaWRpYW5UcmFuc3BvcnQ+IHtcbiAgY29uc3QgdHJhbnNwb3J0ID0gYXdhaXQgb2JzaWRpYW5JbnRlZ3JhdGlvblRlc3RpbmcuY3JlYXRlVHJhbnNwb3J0RnJvbU9wdGlvbnMoKTtcbiAgdHJ5IHtcbiAgICBhd2FpdCB0cmFuc3BvcnQucmVnaXN0ZXJWYXVsdCh2YXVsdFBhdGgpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRyYW5zcG9ydC5kaXNwb3NlU3luYz8uKCk7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbiAgcmVnaXN0ZXJEZXZJbnN0YW5jZUNsZWFudXAodHJhbnNwb3J0KTtcbiAgd2F0Y2hEZXZJbnN0YW5jZUFuZFN0b3BPbkNsb3NlKG9ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nLCB0cmFuc3BvcnQpO1xuICByZXR1cm4gdHJhbnNwb3J0O1xufVxuXG4vKipcbiAqIFJlYWRzIHRoZSBwbHVnaW4gaWQgZnJvbSB0aGUgZGVwbG95ZWQgYG1hbmlmZXN0Lmpzb25gLCB3aGljaCBpcyB3aGF0IE9ic2lkaWFuIGFuZCBpdHMgQ0xJIGtub3cgdGhlIHBsdWdpbiBieS5cbiAqXG4gKiBAcGFyYW0gcGx1Z2luRm9sZGVyIC0gVGhlIGRlcGxveWVkIHBsdWdpbiBmb2xkZXIuXG4gKiBAcGFyYW0gZmFsbGJhY2tJZCAtIFRoZSBpZCB0byB1c2Ugd2hlbiB0aGUgZm9sZGVyIGhhcyBubyByZWFkYWJsZSBtYW5pZmVzdC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHJlc29sdmluZyB0byB0aGUgcGx1Z2luIGlkLlxuICovXG5hc3luYyBmdW5jdGlvbiByZWFkUGx1Z2luSWQocGx1Z2luRm9sZGVyOiBzdHJpbmcsIGZhbGxiYWNrSWQ6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgbWFuaWZlc3QgPSBKU09OLnBhcnNlKGF3YWl0IHJlYWRGaWxlKGpvaW4ocGx1Z2luRm9sZGVyLCAnbWFuaWZlc3QuanNvbicpLCAndXRmLTgnKSkgYXMgUGFydGlhbDxQbHVnaW5NYW5pZmVzdD47XG4gICAgcmV0dXJuIG1hbmlmZXN0LmlkID8/IGZhbGxiYWNrSWQ7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxsYmFja0lkO1xuICB9XG59XG5cbi8qKlxuICogUmVnaXN0ZXJzIHByb2Nlc3MtZXhpdCBhbmQgc2lnbmFsIGhhbmRsZXJzIChvbmNlKSB0aGF0IHN5bmNocm9ub3VzbHkgY2xvc2UgdGhlIG93bmVkIE9ic2lkaWFuXG4gKiBpbnN0YW5jZSB3aGVuIHRoZSBgbnBtIHJ1biBkZXZgIHByb2Nlc3MgdGVybWluYXRlcy5cbiAqXG4gKiBUaGVzZSBoYW5kbGVycyBjb3ZlciBhbiBvcmRlcmx5IHNodXRkb3duLiBBIGBTSUdLSUxMYCAob3IgYSBUYXNrIE1hbmFnZXIgLyBJREUgc3RvcCkgcnVucyBubyBoYW5kbGVyXG4gKiBhdCBhbGwsIGFuZCBubyBvcGVyYXRpbmcgc3lzdGVtIGtpbGxzIHRoZSBpbnN0YW5jZSBqdXN0IGZvciBiZWluZyBvdXIgY2hpbGQg4oCUIHNvIHRoYXQgY2FzZSBpcyBjYXVnaHRcbiAqIGZyb20gdGhlIG90aGVyIHNpZGUsIGJ5IHRoZSBoYXJuZXNzJ3MgcGFyZW50LWxpdmVuZXNzIHdhdGNoZG9nOiB0aGUgaW5zdGFuY2UncyByZW5kZXJlciBob2xkcyBhIHNvY2tldFxuICogYmFjayB0byB0aGlzIHByb2Nlc3MgYW5kIGRlc3Ryb3lzIGl0cyB3aW5kb3cgd2hlbiB0aGUga2VybmVsIGNsb3NlcyBpdC4gU2VlIGBwYXJlbnQtbGl2ZW5lc3MudHNgIGluXG4gKiBgb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZ2AuXG4gKlxuICogQHBhcmFtIHRyYW5zcG9ydCAtIFRoZSBvd25lZCB0cmFuc3BvcnQgdG8gZGlzcG9zZSBvbiBzaHV0ZG93bi5cbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJEZXZJbnN0YW5jZUNsZWFudXAodHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydCk6IHZvaWQge1xuICBpZiAobW9kdWxlU3RhdGUuaXNEZXZJbnN0YW5jZUNsZWFudXBSZWdpc3RlcmVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIG1vZHVsZVN0YXRlLmlzRGV2SW5zdGFuY2VDbGVhbnVwUmVnaXN0ZXJlZCA9IHRydWU7XG5cbiAgLy8gYGV4aXRgIGNvdmVycyBhbnkgYHByb2Nlc3MuZXhpdCgpYCwgYnV0IGEgZGVmYXVsdCBDdHJsK0MgdGVybWluYXRlcyBXSVRIT1VUIGZpcmluZyBgZXhpdGAsIHNvIHRoZSBzaWduYWwgaGFuZGxlcnMgZ3VhcmFudGVlIHRoZSBvd25lZCBPYnNpZGlhbiBpcyBraWxsZWQgb24gc2h1dGRvd24uXG4gIHByb2Nlc3Mub24oJ2V4aXQnLCBkaXNwb3NlRGV2SW5zdGFuY2UpO1xuICBmb3IgKGNvbnN0IHNpZ25hbCBvZiBbJ1NJR0hVUCcsICdTSUdJTlQnLCAnU0lHVEVSTSddIGFzIGNvbnN0KSB7XG4gICAgcHJvY2Vzcy5vbmNlKHNpZ25hbCwgKCkgPT4ge1xuICAgICAgZGlzcG9zZURldkluc3RhbmNlKCk7XG4gICAgICBwcm9jZXNzLmV4aXQoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRpc3Bvc2VEZXZJbnN0YW5jZSgpOiB2b2lkIHtcbiAgICBpZiAobW9kdWxlU3RhdGUuaXNEZXZJbnN0YW5jZURpc3Bvc2VkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIG1vZHVsZVN0YXRlLmlzRGV2SW5zdGFuY2VEaXNwb3NlZCA9IHRydWU7XG4gICAgdHJhbnNwb3J0LmRpc3Bvc2VTeW5jPy4oKTtcbiAgfVxufVxuXG4vKipcbiAqIFdhdGNoZXMgdGhlIGBucG0gcnVuIGRldmAtb3duZWQgT2JzaWRpYW4gaW5zdGFuY2UgYW5kIHN0b3BzIHRoZSBkZXZlbG9wbWVudCBidWlsZCBvbmNlIHRoZSBpbnN0YW5jZSBpc1xuICogY2xvc2VkLlxuICpcbiAqIFRoaXMgaXMgdGhlIG1pcnJvciBpbWFnZSBvZiB7QGxpbmsgcmVnaXN0ZXJEZXZJbnN0YW5jZUNsZWFudXB9OiB0aGF0IG9uZSBjbG9zZXMgdGhlIGluc3RhbmNlIHdoZW4gdGhlXG4gKiBgbnBtIHJ1biBkZXZgIHByb2Nlc3MgdGVybWluYXRlcywgdGhpcyBvbmUgdGVybWluYXRlcyB0aGUgcHJvY2VzcyB3aGVuIHRoZSB1c2VyIGNsb3NlcyB0aGUgaW5zdGFuY2UsIHNvXG4gKiB0aGUgdHdvIG5ldmVyIG91dGxpdmUgZWFjaCBvdGhlci4gQSBidWlsZCB3YXRjaGluZyBhbiBPYnNpZGlhbiB0aGF0IGlzIG5vIGxvbmdlciBydW5uaW5nIGhhcyBub3RoaW5nXG4gKiBsZWZ0IHRvIGRlcGxveSB0by5cbiAqXG4gKiBPbmx5IGEgaGFybmVzcy1vd25lZCBpbnN0YW5jZSBpcyB3YXRjaGVkLiBXaGVuIHRoZSB0cmFuc3BvcnQgYXR0YWNoZXMgdG8gYW4gYWxyZWFkeS1ydW5uaW5nIE9ic2lkaWFuXG4gKiAodGhlIHVzZXIncyBvd24pLCB0aGF0IGluc3RhbmNlIGlzIG5vdCBvdXJzIHRvIGJlIHRpZWQgdG8gYW5kIGNsb3NpbmcgaXQgbGVhdmVzIHRoZSBidWlsZCBydW5uaW5nLlxuICpcbiAqIEBwYXJhbSBvYnNpZGlhbkludGVncmF0aW9uVGVzdGluZyAtIFRoZSBsb2FkZWQgYG9ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmdgIG1vZHVsZS5cbiAqIEBwYXJhbSB0cmFuc3BvcnQgLSBUaGUgb3duZWQgdHJhbnNwb3J0IHdob3NlIGluc3RhbmNlIHRvIHdhdGNoLlxuICovXG5mdW5jdGlvbiB3YXRjaERldkluc3RhbmNlQW5kU3RvcE9uQ2xvc2Uob2JzaWRpYW5JbnRlZ3JhdGlvblRlc3Rpbmc6IE9ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nLCB0cmFuc3BvcnQ6IE9ic2lkaWFuVHJhbnNwb3J0KTogdm9pZCB7XG4gIGlmICghKHRyYW5zcG9ydCBpbnN0YW5jZW9mIG9ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nLkRlc2t0b3BDZHBUcmFuc3BvcnQpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgZW5kcG9pbnQgPSB0cmFuc3BvcnQuZ2V0T3duZWRJbnN0YW5jZUVuZHBvaW50KCk7XG4gIGlmICghZW5kcG9pbnQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBjZHBVcmwgPSBgaHR0cDovLyR7ZW5kcG9pbnQuaG9zdH06JHtTdHJpbmcoZW5kcG9pbnQucG9ydCl9YDtcbiAgaW52b2tlQXN5bmNTYWZlbHkoc3RvcFdoZW5EZXZJbnN0YW5jZUNsb3Nlcyk7XG5cbiAgYXN5bmMgZnVuY3Rpb24gc3RvcFdoZW5EZXZJbnN0YW5jZUNsb3NlcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsZXQgY29uc2VjdXRpdmVGYWlsZWRQcm9iZUNvdW50ID0gMDtcbiAgICB3aGlsZSAoY29uc2VjdXRpdmVGYWlsZWRQcm9iZUNvdW50IDwgREVWX0lOU1RBTkNFX0NMT1NFRF9QUk9CRV9DT1VOVCkge1xuICAgICAgYXdhaXQgc2xlZXAoeyBtaWxsaXNlY29uZHM6IERFVl9JTlNUQU5DRV9QUk9CRV9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgfSk7XG5cbiAgICAgIC8vIFRoZSBwcm9jZXNzIGlzIGFscmVhZHkgc2h1dHRpbmcgZG93biBhbmQga2lsbGVkIHRoZSBpbnN0YW5jZSBpdHNlbGY7IHRoZSBwcm9iZXMgd291bGQganVzdCByYWNlIHRoZSB0ZWFyZG93bi5cbiAgICAgIGlmIChtb2R1bGVTdGF0ZS5pc0Rldkluc3RhbmNlRGlzcG9zZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zZWN1dGl2ZUZhaWxlZFByb2JlQ291bnQgPSBhd2FpdCBpc0Rldkluc3RhbmNlUnVubmluZyhjZHBVcmwpID8gMCA6IGNvbnNlY3V0aXZlRmFpbGVkUHJvYmVDb3VudCArIDE7XG4gICAgfVxuXG4gICAgY29uc29sZS53YXJuKCdUaGUgT2JzaWRpYW4gaW5zdGFuY2Ugb3duZWQgYnkgYG5wbSBydW4gZGV2YCB3YXMgY2xvc2VkLiBTdG9wcGluZyB0aGUgZGV2ZWxvcG1lbnQgYnVpbGQuJyk7XG4gICAgcHJvY2Vzcy5leGl0KCk7XG4gIH1cbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQW9CQSxtQkFHTztBQUNQLG1CQUErQjtBQUMvQixrQkFLTztBQUNQLHNCQUlPO0FBQ1AsMEJBQW9CO0FBSXBCLGlDQUE0QztBQW1INUMsTUFBTSxjQUEyQjtBQUFBLEVBQy9CLDZCQUE2QjtBQUFBLEVBQzdCLGdDQUFnQztBQUFBLEVBQ2hDLHVCQUF1QjtBQUN6QjtBQU9BLE1BQU0sNENBQTRDO0FBS2xELE1BQU0sOENBQThDO0FBT3BELE1BQU0sa0NBQWtDO0FBUXhDLGVBQXNCLDhCQUE4QixRQUE0RDtBQUM5RyxRQUFNO0FBQUEsSUFDSjtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsRUFDRixJQUFJO0FBRUosTUFBSSxtQkFBbUI7QUFDckI7QUFBQSxFQUNGO0FBRUEsTUFBSSxDQUFDLE9BQU8sc0JBQXNCO0FBQ2hDLHFDQUFlLCtCQUErQjtBQUFBLE1BQzVDO0FBQUEsSUFDRjtBQUNBO0FBQUEsRUFDRjtBQUVBLFFBQU0sMkJBQXVCLHlCQUFZLE9BQU8sb0JBQW9CO0FBRXBFLFFBQU0sbUJBQWUsa0JBQUssc0JBQXNCLFdBQVcsVUFBVTtBQUNyRSxZQUFN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