obsidian-integration-testing 12.0.0 → 12.1.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 (176) hide show
  1. package/dist/lib/cjs/adb-device-list.cjs +54 -0
  2. package/dist/lib/cjs/adb-device-list.d.cts +72 -0
  3. package/dist/lib/cjs/android-sdk.cjs +52 -0
  4. package/dist/lib/cjs/android-sdk.d.cts +29 -0
  5. package/dist/lib/cjs/app-startup-progress.cjs +87 -0
  6. package/dist/lib/cjs/app-startup-progress.d.cts +128 -0
  7. package/dist/lib/cjs/appium-server-marker.cjs +29 -32
  8. package/dist/lib/cjs/appium-server-marker.d.cts +22 -0
  9. package/dist/lib/cjs/avd-probe-verdict.cjs +90 -0
  10. package/dist/lib/cjs/avd-probe-verdict.d.cts +175 -0
  11. package/dist/lib/cjs/community-plugin-registry.cjs +1 -1
  12. package/dist/lib/cjs/community-plugin-registry.d.cts +1 -1
  13. package/dist/lib/cjs/config-directory-fallback-error.cjs +57 -0
  14. package/dist/lib/cjs/config-directory-fallback-error.d.cts +64 -0
  15. package/dist/lib/cjs/config-directory.cjs +46 -0
  16. package/dist/lib/cjs/config-directory.d.cts +45 -0
  17. package/dist/lib/cjs/connect-to-cdp.cjs +13 -7
  18. package/dist/lib/cjs/connect-to-cdp.d.cts +19 -0
  19. package/dist/lib/cjs/demo-vault-bootstrap.cjs +1 -1
  20. package/dist/lib/cjs/demo-vault-bootstrap.d.cts +3 -2
  21. package/dist/lib/cjs/demo-vault-populate.cjs +3 -2
  22. package/dist/lib/cjs/device-readiness.cjs +38 -3
  23. package/dist/lib/cjs/device-readiness.d.cts +83 -9
  24. package/dist/lib/cjs/emulator-arguments.cjs +6 -2
  25. package/dist/lib/cjs/emulator-arguments.d.cts +26 -0
  26. package/dist/lib/cjs/emulator-backend.cjs +71 -0
  27. package/dist/lib/cjs/emulator-backend.d.cts +76 -0
  28. package/dist/lib/cjs/emulator-liveness.cjs +72 -0
  29. package/dist/lib/cjs/emulator-liveness.d.cts +158 -0
  30. package/dist/lib/cjs/emulator-snapshot.cjs +57 -0
  31. package/dist/lib/cjs/emulator-snapshot.d.cts +68 -0
  32. package/dist/lib/cjs/global-setup-core.cjs +30 -30
  33. package/dist/lib/cjs/global-setup-core.d.cts +27 -2
  34. package/dist/lib/cjs/headless-vault-config.cjs +51 -0
  35. package/dist/lib/cjs/headless-vault-config.d.cts +67 -0
  36. package/dist/lib/cjs/index.cjs +12 -1
  37. package/dist/lib/cjs/index.d.cts +6 -1
  38. package/dist/lib/cjs/library.cjs +1 -1
  39. package/dist/lib/cjs/mobile-input.cjs +14 -2
  40. package/dist/lib/cjs/mobile-input.d.cts +5 -9
  41. package/dist/lib/cjs/namespace-bootstrap.cjs +1 -1
  42. package/dist/lib/cjs/obsidian-instance.cjs +52 -3
  43. package/dist/lib/cjs/obsidian-instance.d.cts +12 -0
  44. package/dist/lib/cjs/open-obsidian-settings-tab.cjs +1 -1
  45. package/dist/lib/cjs/open-obsidian-settings-tab.d.cts +3 -2
  46. package/dist/lib/cjs/owned-instance-exit-marker.cjs +99 -0
  47. package/dist/lib/cjs/owned-instance-exit-marker.d.cts +106 -0
  48. package/dist/lib/cjs/owned-instance-exited-error.cjs +106 -0
  49. package/dist/lib/cjs/owned-instance-exited-error.d.cts +98 -0
  50. package/dist/lib/cjs/owned-vault-seed.cjs +9 -5
  51. package/dist/lib/cjs/owned-vault-seed.d.cts +24 -3
  52. package/dist/lib/cjs/parent-liveness.cjs +42 -5
  53. package/dist/lib/cjs/parent-liveness.d.cts +37 -5
  54. package/dist/lib/cjs/port-owner.cjs +61 -0
  55. package/dist/lib/cjs/port-owner.d.cts +47 -0
  56. package/dist/lib/cjs/process-capture.cjs +62 -0
  57. package/dist/lib/cjs/process-capture.d.cts +83 -0
  58. package/dist/lib/cjs/process-exit-message.cjs +14 -8
  59. package/dist/lib/cjs/process-exit-message.d.cts +37 -3
  60. package/dist/lib/cjs/process-liveness.cjs +51 -0
  61. package/dist/lib/cjs/process-liveness.d.cts +18 -0
  62. package/dist/lib/cjs/run-version-matrix.cjs +1 -1
  63. package/dist/lib/cjs/run-version-matrix.d.cts +1 -1
  64. package/dist/lib/cjs/teardown-verdict.cjs +53 -0
  65. package/dist/lib/cjs/teardown-verdict.d.cts +69 -0
  66. package/dist/lib/cjs/temporary-vault.cjs +43 -8
  67. package/dist/lib/cjs/temporary-vault.d.cts +47 -5
  68. package/dist/lib/cjs/transport-appium.cjs +102 -17
  69. package/dist/lib/cjs/transport-appium.d.cts +53 -3
  70. package/dist/lib/cjs/transport-desktop-cdp.cjs +195 -6
  71. package/dist/lib/cjs/transport-desktop-cdp.d.cts +99 -0
  72. package/dist/lib/cjs/transport-factory.cjs +951 -133
  73. package/dist/lib/cjs/transport-options.cjs +11 -3
  74. package/dist/lib/cjs/transport-options.d.cts +131 -12
  75. package/dist/lib/cjs/transport.cjs +1 -1
  76. package/dist/lib/cjs/transport.d.cts +7 -1
  77. package/dist/lib/cjs/vault-plugin-install.cjs +40 -0
  78. package/dist/lib/cjs/vault-plugin-install.d.cts +64 -0
  79. package/dist/lib/cjs/vault-teardown-verdict.cjs +42 -0
  80. package/dist/lib/cjs/vault-teardown-verdict.d.cts +57 -0
  81. package/dist/lib/cjs/version-matrix.cjs +1 -1
  82. package/dist/lib/cjs/version-matrix.d.cts +2 -2
  83. package/dist/lib/cjs/webview-cdp.cjs +6 -7
  84. package/dist/lib/cjs/webview-cdp.d.cts +5 -1
  85. package/dist/lib/esm/adb-device-list.d.mts +72 -0
  86. package/dist/lib/esm/adb-device-list.mjs +28 -0
  87. package/dist/lib/esm/android-sdk.d.mts +29 -0
  88. package/dist/lib/esm/android-sdk.mjs +18 -0
  89. package/dist/lib/esm/app-startup-progress.d.mts +128 -0
  90. package/dist/lib/esm/app-startup-progress.mjs +59 -0
  91. package/dist/lib/esm/appium-server-marker.d.mts +22 -0
  92. package/dist/lib/esm/appium-server-marker.mjs +28 -22
  93. package/dist/lib/esm/avd-probe-verdict.d.mts +175 -0
  94. package/dist/lib/esm/avd-probe-verdict.mjs +62 -0
  95. package/dist/lib/esm/community-plugin-registry.d.mts +1 -1
  96. package/dist/lib/esm/community-plugin-registry.mjs +1 -1
  97. package/dist/lib/esm/config-directory-fallback-error.d.mts +64 -0
  98. package/dist/lib/esm/config-directory-fallback-error.mjs +33 -0
  99. package/dist/lib/esm/config-directory.d.mts +45 -0
  100. package/dist/lib/esm/config-directory.mjs +21 -0
  101. package/dist/lib/esm/connect-to-cdp.d.mts +19 -0
  102. package/dist/lib/esm/connect-to-cdp.mjs +13 -7
  103. package/dist/lib/esm/demo-vault-bootstrap.d.mts +3 -2
  104. package/dist/lib/esm/demo-vault-bootstrap.mjs +1 -1
  105. package/dist/lib/esm/demo-vault-populate.mjs +3 -2
  106. package/dist/lib/esm/device-readiness.d.mts +83 -9
  107. package/dist/lib/esm/device-readiness.mjs +34 -2
  108. package/dist/lib/esm/emulator-arguments.d.mts +26 -0
  109. package/dist/lib/esm/emulator-arguments.mjs +6 -2
  110. package/dist/lib/esm/emulator-backend.d.mts +76 -0
  111. package/dist/lib/esm/emulator-backend.mjs +45 -0
  112. package/dist/lib/esm/emulator-liveness.d.mts +158 -0
  113. package/dist/lib/esm/emulator-liveness.mjs +47 -0
  114. package/dist/lib/esm/emulator-snapshot.d.mts +68 -0
  115. package/dist/lib/esm/emulator-snapshot.mjs +32 -0
  116. package/dist/lib/esm/global-setup-core.d.mts +27 -2
  117. package/dist/lib/esm/global-setup-core.mjs +34 -35
  118. package/dist/lib/esm/headless-vault-config.d.mts +67 -0
  119. package/dist/lib/esm/headless-vault-config.mjs +31 -0
  120. package/dist/lib/esm/index.d.mts +6 -1
  121. package/dist/lib/esm/index.mjs +11 -1
  122. package/dist/lib/esm/library.mjs +1 -1
  123. package/dist/lib/esm/mobile-input.d.mts +5 -9
  124. package/dist/lib/esm/mobile-input.mjs +14 -2
  125. package/dist/lib/esm/namespace-bootstrap.mjs +1 -1
  126. package/dist/lib/esm/obsidian-instance.d.mts +12 -0
  127. package/dist/lib/esm/obsidian-instance.mjs +55 -3
  128. package/dist/lib/esm/open-obsidian-settings-tab.d.mts +3 -2
  129. package/dist/lib/esm/open-obsidian-settings-tab.mjs +1 -1
  130. package/dist/lib/esm/owned-instance-exit-marker.d.mts +106 -0
  131. package/dist/lib/esm/owned-instance-exit-marker.mjs +78 -0
  132. package/dist/lib/esm/owned-instance-exited-error.d.mts +98 -0
  133. package/dist/lib/esm/owned-instance-exited-error.mjs +81 -0
  134. package/dist/lib/esm/owned-vault-seed.d.mts +24 -3
  135. package/dist/lib/esm/owned-vault-seed.mjs +9 -5
  136. package/dist/lib/esm/parent-liveness.d.mts +37 -5
  137. package/dist/lib/esm/parent-liveness.mjs +42 -5
  138. package/dist/lib/esm/port-owner.d.mts +47 -0
  139. package/dist/lib/esm/port-owner.mjs +36 -0
  140. package/dist/lib/esm/process-capture.d.mts +83 -0
  141. package/dist/lib/esm/process-capture.mjs +38 -0
  142. package/dist/lib/esm/process-exit-message.d.mts +37 -3
  143. package/dist/lib/esm/process-exit-message.mjs +13 -8
  144. package/dist/lib/esm/process-liveness.d.mts +18 -0
  145. package/dist/lib/esm/process-liveness.mjs +17 -0
  146. package/dist/lib/esm/run-version-matrix.d.mts +1 -1
  147. package/dist/lib/esm/run-version-matrix.mjs +1 -1
  148. package/dist/lib/esm/teardown-verdict.d.mts +69 -0
  149. package/dist/lib/esm/teardown-verdict.mjs +28 -0
  150. package/dist/lib/esm/temporary-vault.d.mts +47 -5
  151. package/dist/lib/esm/temporary-vault.mjs +43 -8
  152. package/dist/lib/esm/transport-appium.d.mts +53 -3
  153. package/dist/lib/esm/transport-appium.mjs +108 -17
  154. package/dist/lib/esm/transport-desktop-cdp.d.mts +99 -0
  155. package/dist/lib/esm/transport-desktop-cdp.mjs +202 -7
  156. package/dist/lib/esm/transport-factory.mjs +995 -138
  157. package/dist/lib/esm/transport-options.d.mts +131 -12
  158. package/dist/lib/esm/transport-options.mjs +9 -2
  159. package/dist/lib/esm/transport.d.mts +7 -1
  160. package/dist/lib/esm/vault-plugin-install.d.mts +64 -0
  161. package/dist/lib/esm/vault-plugin-install.mjs +20 -0
  162. package/dist/lib/esm/vault-teardown-verdict.d.mts +57 -0
  163. package/dist/lib/esm/vault-teardown-verdict.mjs +18 -0
  164. package/dist/lib/esm/version-matrix.d.mts +2 -2
  165. package/dist/lib/esm/version-matrix.mjs +1 -1
  166. package/dist/lib/esm/webview-cdp.d.mts +5 -1
  167. package/dist/lib/esm/webview-cdp.mjs +6 -7
  168. package/package.json +24 -23
  169. package/dist/lib/cjs/native-dialog-monitor.cjs +0 -192
  170. package/dist/lib/cjs/native-dialog-monitor.d.cts +0 -66
  171. package/dist/lib/cjs/obsidian-namespace.cjs +0 -17
  172. package/dist/lib/cjs/obsidian-namespace.d.cts +0 -128
  173. package/dist/lib/esm/native-dialog-monitor.d.mts +0 -66
  174. package/dist/lib/esm/native-dialog-monitor.mjs +0 -158
  175. package/dist/lib/esm/obsidian-namespace.d.mts +0 -128
  176. package/dist/lib/esm/obsidian-namespace.mjs +0 -1
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var emulator_snapshot_exports = {};
20
+ __export(emulator_snapshot_exports, {
21
+ buildAvdSnapshotDirectoryCandidates: () => buildAvdSnapshotDirectoryCandidates,
22
+ buildSnapshotAgeMessage: () => buildSnapshotAgeMessage
23
+ });
24
+ module.exports = __toCommonJS(emulator_snapshot_exports);
25
+ const DEFAULT_SNAPSHOT_NAME = "default_boot";
26
+ const AVD_HOME_SEGMENTS = [".android", "avd"];
27
+ const TRAILING_SEPARATOR_PATTERN = /[/\\]+$/;
28
+ function buildAvdSnapshotDirectoryCandidates(params) {
29
+ const { avdName, environment, homeDirectory } = params;
30
+ const avdHomes = [
31
+ environment["ANDROID_AVD_HOME"],
32
+ resolveAvdHomeUnder(environment["ANDROID_SDK_HOME"]),
33
+ resolveAvdHomeUnder(homeDirectory)
34
+ ];
35
+ return avdHomes.filter((avdHome) => avdHome !== void 0 && avdHome.length > 0).map((avdHome) => joinPath(avdHome, `${avdName}.avd`, "snapshots", DEFAULT_SNAPSHOT_NAME));
36
+ }
37
+ function buildSnapshotAgeMessage(params) {
38
+ if (params.savedAt === void 0) {
39
+ return `Snapshot reuse is enabled for AVD "${params.avdName}", but no \`${DEFAULT_SNAPSHOT_NAME}\` snapshot was found \u2014 this run cold-boots and saves one for the next.`;
40
+ }
41
+ return `Snapshot reuse is enabled for AVD "${params.avdName}": resuming \`${DEFAULT_SNAPSHOT_NAME}\` saved ${params.savedAt.toISOString()}.`;
42
+ }
43
+ function joinPath(base, ...segments) {
44
+ return [base.replace(TRAILING_SEPARATOR_PATTERN, ""), ...segments].join("/");
45
+ }
46
+ function resolveAvdHomeUnder(base) {
47
+ if (base === void 0 || base.length === 0) {
48
+ return void 0;
49
+ }
50
+ return joinPath(base, ...AVD_HOME_SEGMENTS);
51
+ }
52
+ // Annotate the CommonJS export names for ESM import in node:
53
+ 0 && (module.exports = {
54
+ buildAvdSnapshotDirectoryCandidates,
55
+ buildSnapshotAgeMessage
56
+ });
57
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2VtdWxhdG9yLXNuYXBzaG90LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogUHVyZSBoZWxwZXJzIGZvciBsb2NhdGluZyBhbmQgZGVzY3JpYmluZyBhbiBBVkQncyBzYXZlZCBib290IHNuYXBzaG90LlxuICpcbiAqIE9ubHkgdGhlIG9wdC1pbiBgc2hvdWxkUmV1c2VFbXVsYXRvclNuYXBzaG90YCBwYXRoIHJlc3VtZXMgb25lLCBhbmQgZXZlbiB0aGVuXG4gKiBpdHMgYWdlIGlzIHdvcnRoIGEgbG9nIGxpbmU6IGEgc25hcHNob3QgaXMgdGhlIG9uZSBpbnB1dCB0byBhIHJ1biB0aGF0IG5vIGdhdGVcbiAqIGluc3BlY3RzLCBhbmQgdGhlIGZhaWx1cmUgYSByb3R0ZW4gb25lIHByb2R1Y2VzIFx1MjAxNCBhIGd1ZXN0IHRoYXQgc2VydmVzIGFkYixcbiAqIGFjY2VwdHMgYSB1aWF1dG9tYXRvcjIgc2Vzc2lvbiBhbmQgdGhlbiBkcm9wcyBgb2ZmbGluZWAgYWJvdXQgaGFsZiBhIG1pbnV0ZVxuICogbGF0ZXIgXHUyMDE0IHJlYWRzIGFzIGEgY29kZSByZWdyZXNzaW9uIHJhdGhlciB0aGFuIGFzIHN0YWxlIHN0YXRlLiBgZW11bGF0b3JcbiAqIC1hdmQgXHUyMDI2IC1uby1zbmFwc2hvdC1sb2FkYCAodGhlIGRlZmF1bHQpIG1ha2VzIHRoZSBxdWVzdGlvbiBtb290OyB3aGVuIHRoZVxuICogY2FsbGVyIGhhcyBkZWxpYmVyYXRlbHkgdHJhZGVkIHRoYXQgYXdheSwgKlwicmVzdW1pbmcgc25hcHNob3Qgc2F2ZWQgPGRhdGU+XCIqXG4gKiBpcyB3aGF0IGtlZXBzIHRoZSB0cmFkZSB2aXNpYmxlIGluIHRoZSB0cmFuc2NyaXB0LlxuICpcbiAqIEtlcHQgc2VwYXJhdGUgZnJvbSB0aGUgaW50ZWdyYXRpb24tb25seSBgdHJhbnNwb3J0LWZhY3RvcnlgIHNvIHRoZSBwYXRoXG4gKiBkZXJpdmF0aW9uIGFuZCB0aGUgd29yZGluZyBzdGF5IHVuaXQtdGVzdGFibGUgXHUyMDE0IHRoZSBmYWN0b3J5IGl0c2VsZiBkb2VzIHRoZVxuICogYHN0YXRgLlxuICovXG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGJ1aWxkQXZkU25hcHNob3REaXJlY3RvcnlDYW5kaWRhdGVzfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBCdWlsZEF2ZFNuYXBzaG90RGlyZWN0b3J5Q2FuZGlkYXRlc1BhcmFtcyB7XG4gIC8qKlxuICBUaGUgQW5kcm9pZCBWaXJ0dWFsIERldmljZSBuYW1lLlxuICAgKi9cbiAgcmVhZG9ubHkgYXZkTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgcHJvY2VzcyBlbnZpcm9ubWVudCwgcmVhZCBmb3IgdGhlIEFuZHJvaWQgU0RLJ3MgQVZELWhvbWUgb3ZlcnJpZGVzLlxuICAgKi9cbiAgcmVhZG9ubHkgZW52aXJvbm1lbnQ6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4+O1xuXG4gIC8qKlxuICBUaGUgdXNlcidzIGhvbWUgZGlyZWN0b3J5LCB0aGUgYmFzZSBvZiB0aGUgZGVmYXVsdCBBVkQgaG9tZS5cbiAgICovXG4gIHJlYWRvbmx5IGhvbWVEaXJlY3Rvcnk6IHN0cmluZztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgYnVpbGRTbmFwc2hvdEFnZU1lc3NhZ2V9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWxkU25hcHNob3RBZ2VNZXNzYWdlUGFyYW1zIHtcbiAgLyoqXG4gIFRoZSBBbmRyb2lkIFZpcnR1YWwgRGV2aWNlIG5hbWUuXG4gICAqL1xuICByZWFkb25seSBhdmROYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFdoZW4gdGhlIHNuYXBzaG90IHdhcyBsYXN0IHdyaXR0ZW4sIG9yIGB1bmRlZmluZWRgIHdoZW4gbm9uZSB3YXMgZm91bmQuXG4gICAqL1xuICByZWFkb25seSBzYXZlZEF0PzogRGF0ZSB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBUaGUgc25hcHNob3QgdGhlIGVtdWxhdG9yIGxvYWRzIGFuZCBzYXZlcyBieSBkZWZhdWx0LlxuICovXG5jb25zdCBERUZBVUxUX1NOQVBTSE9UX05BTUUgPSAnZGVmYXVsdF9ib290JztcblxuLyoqXG4gKiBUaGUgZGlyZWN0b3J5IHRoZSBBbmRyb2lkIFNESyBrZWVwcyBBVkRzIGluLCB1bmRlciB3aGljaGV2ZXIgaG9tZSBhcHBsaWVzLlxuICovXG5jb25zdCBBVkRfSE9NRV9TRUdNRU5UUyA9IFsnLmFuZHJvaWQnLCAnYXZkJ107XG5jb25zdCBUUkFJTElOR19TRVBBUkFUT1JfUEFUVEVSTiA9IC9bL1xcXFxdKyQvO1xuXG4vKipcbiAqIEJ1aWxkcyB0aGUgZGlyZWN0b3JpZXMgdGhlIEFWRCdzIGJvb3Qgc25hcHNob3QgY291bGQgbGl2ZSBpbiwgbW9zdCBzcGVjaWZpY1xuICogZmlyc3QuXG4gKlxuICogVGhlIGxvb2t1cCBtaXJyb3JzIHRoZSBlbXVsYXRvcidzIG93bjogYEFORFJPSURfQVZEX0hPTUVgIHdpbnMgb3V0cmlnaHQsIHRoZW5cbiAqIGAuYW5kcm9pZC9hdmRgIHVuZGVyIGBBTkRST0lEX1NES19IT01FYCwgdGhlbiB1bmRlciB0aGUgdXNlcidzIGhvbWUuIFJldHVybmluZ1xuICogY2FuZGlkYXRlcyByYXRoZXIgdGhhbiBvbmUgcGF0aCBrZWVwcyB0aGUgYHN0YXRgIFx1MjAxNCBhbmQgdGhlIGRlY2lzaW9uIHRoYXQgYVxuICogbWlzcyBpcyBub3QgYW4gZXJyb3IgXHUyMDE0IGluIHRoZSBjYWxsZXIuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBBVkQgbmFtZSwgdGhlIGVudmlyb25tZW50LCBhbmQgdGhlIGhvbWUgZGlyZWN0b3J5LlxuICogQHJldHVybnMgVGhlIGNhbmRpZGF0ZSBzbmFwc2hvdCBkaXJlY3RvcmllcywgbW9zdCBzcGVjaWZpYyBmaXJzdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQXZkU25hcHNob3REaXJlY3RvcnlDYW5kaWRhdGVzKHBhcmFtczogQnVpbGRBdmRTbmFwc2hvdERpcmVjdG9yeUNhbmRpZGF0ZXNQYXJhbXMpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHsgYXZkTmFtZSwgZW52aXJvbm1lbnQsIGhvbWVEaXJlY3RvcnkgfSA9IHBhcmFtcztcblxuICBjb25zdCBhdmRIb21lcyA9IFtcbiAgICBlbnZpcm9ubWVudFsnQU5EUk9JRF9BVkRfSE9NRSddLFxuICAgIHJlc29sdmVBdmRIb21lVW5kZXIoZW52aXJvbm1lbnRbJ0FORFJPSURfU0RLX0hPTUUnXSksXG4gICAgcmVzb2x2ZUF2ZEhvbWVVbmRlcihob21lRGlyZWN0b3J5KVxuICBdO1xuXG4gIHJldHVybiBhdmRIb21lc1xuICAgIC5maWx0ZXIoKGF2ZEhvbWUpOiBhdmRIb21lIGlzIHN0cmluZyA9PiBhdmRIb21lICE9PSB1bmRlZmluZWQgJiYgYXZkSG9tZS5sZW5ndGggPiAwKVxuICAgIC5tYXAoKGF2ZEhvbWUpID0+IGpvaW5QYXRoKGF2ZEhvbWUsIGAke2F2ZE5hbWV9LmF2ZGAsICdzbmFwc2hvdHMnLCBERUZBVUxUX1NOQVBTSE9UX05BTUUpKTtcbn1cblxuLyoqXG4gKiBCdWlsZHMgdGhlIGxpbmUgbG9nZ2VkIHdoZW4gYSBydW4gaGFzIG9wdGVkIGludG8gcmVzdW1pbmcgYSBzbmFwc2hvdC5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIEFWRCBuYW1lIGFuZCB0aGUgc25hcHNob3QncyBzYXZlIHRpbWUsIGlmIGl0IHdhcyBmb3VuZC5cbiAqIEByZXR1cm5zIFRoZSBsb2cgbGluZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkU25hcHNob3RBZ2VNZXNzYWdlKHBhcmFtczogQnVpbGRTbmFwc2hvdEFnZU1lc3NhZ2VQYXJhbXMpOiBzdHJpbmcge1xuICBpZiAocGFyYW1zLnNhdmVkQXQgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBgU25hcHNob3QgcmV1c2UgaXMgZW5hYmxlZCBmb3IgQVZEIFwiJHtwYXJhbXMuYXZkTmFtZX1cIiwgYnV0IG5vIFxcYCR7REVGQVVMVF9TTkFQU0hPVF9OQU1FfVxcYCBzbmFwc2hvdCB3YXMgZm91bmQgXHUyMDE0IHRoaXMgcnVuIGNvbGQtYm9vdHMgYW5kIHNhdmVzIG9uZSBmb3IgdGhlIG5leHQuYDtcbiAgfVxuXG4gIHJldHVybiBgU25hcHNob3QgcmV1c2UgaXMgZW5hYmxlZCBmb3IgQVZEIFwiJHtwYXJhbXMuYXZkTmFtZX1cIjogcmVzdW1pbmcgXFxgJHtERUZBVUxUX1NOQVBTSE9UX05BTUV9XFxgIHNhdmVkICR7cGFyYW1zLnNhdmVkQXQudG9JU09TdHJpbmcoKX0uYDtcbn1cblxuLyoqXG4gKiBKb2lucyBwYXRoIHNlZ21lbnRzIHdpdGggYC9gLCB3aGljaCBldmVyeSBwbGF0Zm9ybSdzIHBhdGggQVBJcyBhY2NlcHQuXG4gKlxuICogQHBhcmFtIGJhc2UgLSBUaGUgbGVhZGluZyBzZWdtZW50LCB3aG9zZSB0cmFpbGluZyBzZXBhcmF0b3JzIGFyZSBkcm9wcGVkLlxuICogQHBhcmFtIHNlZ21lbnRzIC0gVGhlIHNlZ21lbnRzIHRvIGFwcGVuZC5cbiAqIEByZXR1cm5zIFRoZSBqb2luZWQgcGF0aC5cbiAqL1xuZnVuY3Rpb24gam9pblBhdGgoYmFzZTogc3RyaW5nLCAuLi5zZWdtZW50czogc3RyaW5nW10pOiBzdHJpbmcge1xuICByZXR1cm4gW2Jhc2UucmVwbGFjZShUUkFJTElOR19TRVBBUkFUT1JfUEFUVEVSTiwgJycpLCAuLi5zZWdtZW50c10uam9pbignLycpO1xufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBBVkQgaG9tZSB1bmRlciBhIGJhc2UgZGlyZWN0b3J5LCB3aGVuIHRoZXJlIGlzIG9uZS5cbiAqXG4gKiBAcGFyYW0gYmFzZSAtIGBBTkRST0lEX1NES19IT01FYCBvciB0aGUgdXNlcidzIGhvbWUgZGlyZWN0b3J5LlxuICogQHJldHVybnMgVGhlIEFWRCBob21lLCBvciBgdW5kZWZpbmVkYCB3aGVuIGBiYXNlYCBpcyB1bnNldC5cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZUF2ZEhvbWVVbmRlcihiYXNlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoYmFzZSA9PT0gdW5kZWZpbmVkIHx8IGJhc2UubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJldHVybiBqb2luUGF0aChiYXNlLCAuLi5BVkRfSE9NRV9TRUdNRU5UUyk7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUF5REEsTUFBTSx3QkFBd0I7QUFLOUIsTUFBTSxvQkFBb0IsQ0FBQyxZQUFZLEtBQUs7QUFDNUMsTUFBTSw2QkFBNkI7QUFjNUIsU0FBUyxvQ0FBb0MsUUFBNkQ7QUFDL0csUUFBTSxFQUFFLFNBQVMsYUFBYSxjQUFjLElBQUk7QUFFaEQsUUFBTSxXQUFXO0FBQUEsSUFDZixZQUFZLGtCQUFrQjtBQUFBLElBQzlCLG9CQUFvQixZQUFZLGtCQUFrQixDQUFDO0FBQUEsSUFDbkQsb0JBQW9CLGFBQWE7QUFBQSxFQUNuQztBQUVBLFNBQU8sU0FDSixPQUFPLENBQUMsWUFBK0IsWUFBWSxVQUFhLFFBQVEsU0FBUyxDQUFDLEVBQ2xGLElBQUksQ0FBQyxZQUFZLFNBQVMsU0FBUyxHQUFHLE9BQU8sUUFBUSxhQUFhLHFCQUFxQixDQUFDO0FBQzdGO0FBUU8sU0FBUyx3QkFBd0IsUUFBK0M7QUFDckYsTUFBSSxPQUFPLFlBQVksUUFBVztBQUNoQyxXQUFPLHNDQUFzQyxPQUFPLE9BQU8sZUFBZSxxQkFBcUI7QUFBQSxFQUNqRztBQUVBLFNBQU8sc0NBQXNDLE9BQU8sT0FBTyxpQkFBaUIscUJBQXFCLFlBQVksT0FBTyxRQUFRLFlBQVksQ0FBQztBQUMzSTtBQVNBLFNBQVMsU0FBUyxTQUFpQixVQUE0QjtBQUM3RCxTQUFPLENBQUMsS0FBSyxRQUFRLDRCQUE0QixFQUFFLEdBQUcsR0FBRyxRQUFRLEVBQUUsS0FBSyxHQUFHO0FBQzdFO0FBUUEsU0FBUyxvQkFBb0IsTUFBOEM7QUFDekUsTUFBSSxTQUFTLFVBQWEsS0FBSyxXQUFXLEdBQUc7QUFDM0MsV0FBTztBQUFBLEVBQ1Q7QUFFQSxTQUFPLFNBQVMsTUFBTSxHQUFHLGlCQUFpQjtBQUM1QzsiLAogICJuYW1lcyI6IFtdCn0K
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Pure helpers for locating and describing an AVD's saved boot snapshot.
5
+ *
6
+ * Only the opt-in `shouldReuseEmulatorSnapshot` path resumes one, and even then
7
+ * its age is worth a log line: a snapshot is the one input to a run that no gate
8
+ * inspects, and the failure a rotten one produces — a guest that serves adb,
9
+ * accepts a uiautomator2 session and then drops `offline` about half a minute
10
+ * later — reads as a code regression rather than as stale state. `emulator
11
+ * -avd … -no-snapshot-load` (the default) makes the question moot; when the
12
+ * caller has deliberately traded that away, *"resuming snapshot saved <date>"*
13
+ * is what keeps the trade visible in the transcript.
14
+ *
15
+ * Kept separate from the integration-only `transport-factory` so the path
16
+ * derivation and the wording stay unit-testable — the factory itself does the
17
+ * `stat`.
18
+ */
19
+ /**
20
+ * Parameters for {@link buildAvdSnapshotDirectoryCandidates}.
21
+ */
22
+ export interface BuildAvdSnapshotDirectoryCandidatesParams {
23
+ /**
24
+ The Android Virtual Device name.
25
+ */
26
+ readonly avdName: string;
27
+ /**
28
+ The process environment, read for the Android SDK's AVD-home overrides.
29
+ */
30
+ readonly environment: Readonly<Record<string, string | undefined>>;
31
+ /**
32
+ The user's home directory, the base of the default AVD home.
33
+ */
34
+ readonly homeDirectory: string;
35
+ }
36
+ /**
37
+ * Parameters for {@link buildSnapshotAgeMessage}.
38
+ */
39
+ export interface BuildSnapshotAgeMessageParams {
40
+ /**
41
+ The Android Virtual Device name.
42
+ */
43
+ readonly avdName: string;
44
+ /**
45
+ When the snapshot was last written, or `undefined` when none was found.
46
+ */
47
+ readonly savedAt?: Date | undefined;
48
+ }
49
+ /**
50
+ * Builds the directories the AVD's boot snapshot could live in, most specific
51
+ * first.
52
+ *
53
+ * The lookup mirrors the emulator's own: `ANDROID_AVD_HOME` wins outright, then
54
+ * `.android/avd` under `ANDROID_SDK_HOME`, then under the user's home. Returning
55
+ * candidates rather than one path keeps the `stat` — and the decision that a
56
+ * miss is not an error — in the caller.
57
+ *
58
+ * @param params - The AVD name, the environment, and the home directory.
59
+ * @returns The candidate snapshot directories, most specific first.
60
+ */
61
+ export declare function buildAvdSnapshotDirectoryCandidates(params: BuildAvdSnapshotDirectoryCandidatesParams): string[];
62
+ /**
63
+ * Builds the line logged when a run has opted into resuming a snapshot.
64
+ *
65
+ * @param params - The AVD name and the snapshot's save time, if it was found.
66
+ * @returns The log line.
67
+ */
68
+ export declare function buildSnapshotAgeMessage(params: BuildSnapshotAgeMessageParams): string;
@@ -30,6 +30,7 @@ var global_setup_core_exports = {};
30
30
  __export(global_setup_core_exports, {
31
31
  coreSetup: () => coreSetup,
32
32
  coreTeardown: () => coreTeardown,
33
+ remapConfigDirectoryKeys: () => remapConfigDirectoryKeys,
33
34
  resolveIntegrationTransportOptions: () => resolveIntegrationTransportOptions
34
35
  });
35
36
  module.exports = __toCommonJS(global_setup_core_exports);
@@ -38,10 +39,12 @@ var import_promises = require("node:fs/promises");
38
39
  var import_node_path = require("node:path");
39
40
  var import_node_process = __toESM(require("node:process"), 1);
40
41
  var import_promises2 = require("node:timers/promises");
42
+ var import_config_directory = require("./config-directory.cjs");
41
43
  var import_desktop_only_plugin_skip_error = require("./desktop-only-plugin-skip-error.cjs");
42
44
  var import_enable_plugin = require("./enable-plugin.cjs");
43
45
  var import_error_to_string = require("./error-to-string.cjs");
44
46
  var import_eval_in_obsidian = require("./eval-in-obsidian.cjs");
47
+ var import_headless_vault_config = require("./headless-vault-config.cjs");
45
48
  var import_leftover_cleanup = require("./leftover-cleanup.cjs");
46
49
  var import_log = require("./log.cjs");
47
50
  var import_plugin_enable_retry = require("./plugin-enable-retry.cjs");
@@ -51,15 +54,11 @@ var import_transport_appium = require("./transport-appium.cjs");
51
54
  var import_transport_desktop_cdp = require("./transport-desktop-cdp.cjs");
52
55
  var import_transport_factory = require("./transport-factory.cjs");
53
56
  var import_transport_options = require("./transport-options.cjs");
57
+ var import_vault_plugin_install = require("./vault-plugin-install.cjs");
54
58
  const DEFAULT_TRANSPORT_TYPE = "obsidian-cdp";
55
59
  const DIST_DEV = "dist/dev";
56
60
  const DIST_BUILD = "dist/build";
57
61
  const MAIN_JS = "main.js";
58
- const OBSIDIAN_CONFIG_DIR = ".obsidian";
59
- const PLUGINS_DIR = "plugins";
60
- const COMMUNITY_PLUGINS_JSON = "community-plugins.json";
61
- const APP_JSON = "app.json";
62
- const APP_JSON_INDENT = 2;
63
62
  const activeSetups = /* @__PURE__ */ new Set();
64
63
  const disposedResults = /* @__PURE__ */ new WeakSet();
65
64
  let isCleanupHandlerRegistered = false;
@@ -92,20 +91,24 @@ async function coreSetup(params) {
92
91
  (0, import_log.log)(`[integration-setup:${label}] Project root: ${projectRoot}`);
93
92
  temporaryVault = new import_temporary_vault.TemporaryVault();
94
93
  (0, import_log.log)(`[integration-setup:${label}] Created temp vault: ${temporaryVault.path}`);
94
+ const configDirectory = (0, import_transport_options.resolveOwnedConfigDirectory)(transportOptions);
95
95
  let pluginId;
96
96
  if (shouldInstallPlugin) {
97
- pluginId = await copyPluginIntoVault({ label, projectRoot, temporaryVault, transport });
97
+ pluginId = await copyPluginIntoVault({ configDirectory, label, projectRoot, temporaryVault, transport });
98
98
  } else {
99
99
  (0, import_log.log)(`[integration-setup:${label}] Skipping plugin install (installPlugin: false) \u2014 registering an empty vault.`);
100
100
  }
101
101
  if (params?.populate) {
102
- const entryCount = Object.keys(params.populate).length;
102
+ const populate = remapConfigDirectoryKeys(params.populate, configDirectory);
103
+ const entryCount = Object.keys(populate).length;
103
104
  (0, import_log.log)(`[integration-setup:${label}] Populating vault with ${String(entryCount)} entries before open...`);
104
- temporaryVault.populate(params.populate);
105
+ temporaryVault.populate(populate);
105
106
  }
106
- await ensureAlwaysUpdateLinks(temporaryVault, label);
107
- (0, import_log.log)(`[integration-setup:${label}] Syncing vault to device...`);
108
- await temporaryVault.syncToDevice(transport);
107
+ await (0, import_headless_vault_config.ensureHeadlessVaultConfig)({
108
+ configDirectory,
109
+ label,
110
+ vaultPath: temporaryVault.path
111
+ });
109
112
  (0, import_log.log)(`[integration-setup:${label}] Registering vault...`);
110
113
  await temporaryVault.register(transport);
111
114
  (0, import_log.log)(`[integration-setup:${label}] Vault registered.`);
@@ -167,6 +170,17 @@ async function coreTeardown(result) {
167
170
  transportOptions: result.transportOptions
168
171
  });
169
172
  }
173
+ function remapConfigDirectoryKeys(populate, configDirectory) {
174
+ if (configDirectory === void 0 || configDirectory === import_config_directory.DEFAULT_CONFIG_DIRECTORY) {
175
+ return populate;
176
+ }
177
+ const prefix = `${import_config_directory.DEFAULT_CONFIG_DIRECTORY}/`;
178
+ const remapped = {};
179
+ for (const [path, content] of Object.entries(populate)) {
180
+ remapped[path.startsWith(prefix) ? `${configDirectory}/${path.slice(prefix.length)}` : path] = content;
181
+ }
182
+ return remapped;
183
+ }
170
184
  function resolveIntegrationTransportOptions(options) {
171
185
  if (options?.type === "obsidian-android-appium") {
172
186
  return options;
@@ -203,7 +217,7 @@ function augmentTransportOptions(options, transport) {
203
217
  return options;
204
218
  }
205
219
  async function copyPluginIntoVault(params) {
206
- const { label, projectRoot, temporaryVault, transport } = params;
220
+ const { configDirectory, label, projectRoot, temporaryVault, transport } = params;
207
221
  const distPath = await resolveDistPath(projectRoot);
208
222
  const manifestJson = JSON.parse(await (0, import_promises.readFile)((0, import_node_path.join)(distPath, "manifest.json"), "utf-8"));
209
223
  const pluginId = manifestJson.id;
@@ -213,10 +227,8 @@ async function copyPluginIntoVault(params) {
213
227
  const mainJs = (0, import_node_path.join)(distPath, MAIN_JS);
214
228
  const buildStat = await (0, import_promises.stat)(mainJs);
215
229
  (0, import_log.log)(`[integration-setup:${label}] Using ${distPath} (${buildStat.mtime.toISOString()}). If outdated, rebuild.`);
216
- const pluginDirectory = (0, import_node_path.join)(temporaryVault.path, OBSIDIAN_CONFIG_DIR, PLUGINS_DIR, pluginId);
217
- await (0, import_promises.mkdir)(pluginDirectory, { recursive: true });
218
- await (0, import_promises.cp)(distPath, pluginDirectory, { recursive: true });
219
- await (0, import_promises.writeFile)((0, import_node_path.join)(temporaryVault.path, OBSIDIAN_CONFIG_DIR, COMMUNITY_PLUGINS_JSON), JSON.stringify([pluginId]));
230
+ await (0, import_vault_plugin_install.installPluginIntoVault)({ configDirectory, distPath, pluginId, vaultPath: temporaryVault.path });
231
+ (0, import_log.log)(`[integration-setup:${label}] Installed "${pluginId}" into ${configDirectory ?? import_config_directory.DEFAULT_CONFIG_DIRECTORY}/plugins (and enabled it there).`);
220
232
  return pluginId;
221
233
  }
222
234
  async function enableExtraCommunityPlugins(params) {
@@ -274,19 +286,6 @@ async function enablePluginInVault(params) {
274
286
  const detail = logcatTail ?? (0, import_enable_plugin.getGenericPluginLoadFailureMessage)(pluginId);
275
287
  throw new Error(`Plugin "${pluginId}" failed to load: ${detail}`);
276
288
  }
277
- async function ensureAlwaysUpdateLinks(temporaryVault, label) {
278
- const configDirectory = (0, import_node_path.join)(temporaryVault.path, OBSIDIAN_CONFIG_DIR);
279
- const appJsonPath = (0, import_node_path.join)(configDirectory, APP_JSON);
280
- let appConfig = {};
281
- try {
282
- appConfig = JSON.parse(await (0, import_promises.readFile)(appJsonPath, "utf-8"));
283
- } catch {
284
- }
285
- appConfig["alwaysUpdateLinks"] = true;
286
- await (0, import_promises.mkdir)(configDirectory, { recursive: true });
287
- await (0, import_promises.writeFile)(appJsonPath, JSON.stringify(appConfig, null, APP_JSON_INDENT));
288
- (0, import_log.log)(`[integration-setup:${label}] Enabled alwaysUpdateLinks in ${APP_JSON} (headless rename support).`);
289
- }
290
289
  function findProjectRoot() {
291
290
  let directory = import_node_process.default.cwd();
292
291
  while (true) {
@@ -431,6 +430,7 @@ async function teardownAsync(result) {
431
430
  0 && (module.exports = {
432
431
  coreSetup,
433
432
  coreTeardown,
433
+ remapConfigDirectoryKeys,
434
434
  resolveIntegrationTransportOptions
435
435
  });
436
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2dsb2JhbC1zZXR1cC1jb3JlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogRnJhbWV3b3JrLWFnbm9zdGljIGNvcmUgbG9naWMgZm9yIGludGVncmF0aW9uIHRlc3QgZ2xvYmFsIHNldHVwIGFuZCB0ZWFyZG93bi5cbiAqXG4gKiBWaXRlc3QgYW5kIEplc3QgYWRhcHRlcnMgZGVsZWdhdGUgdG8gdGhlc2UgZnVuY3Rpb25zLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIHNldHVwIGNvdmVyZWQgYnkgaW50ZWdyYXRpb24gdGVzdHMsIG5vdCB1bml0IHRlc3RzLiAqL1xuXG5pbXBvcnQgdHlwZSB7IFBsdWdpbk1hbmlmZXN0IH0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQge1xuICBleGlzdHNTeW5jLFxuICBybVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICBjcCxcbiAgbWtkaXIsXG4gIHJlYWRGaWxlLFxuICBzdGF0LFxuICB3cml0ZUZpbGVcbn0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQge1xuICBiYXNlbmFtZSxcbiAgam9pblxufSBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHByb2Nlc3MsIHsgbG9hZEVudkZpbGUgfSBmcm9tICdub2RlOnByb2Nlc3MnO1xuaW1wb3J0IHsgc2V0VGltZW91dCBhcyBzbGVlcCB9IGZyb20gJ25vZGU6dGltZXJzL3Byb21pc2VzJztcblxuaW1wb3J0IHR5cGUgeyBFbmFibGVQbHVnaW5SZXN1bHQgfSBmcm9tICcuL2VuYWJsZS1wbHVnaW4uY2pzJztcbmltcG9ydCB0eXBlIHsgU2V0dXBMb2NrIH0gZnJvbSAnLi9zZXR1cC1sb2NrLmNqcyc7XG5pbXBvcnQgdHlwZSB7IFBvcHVsYXRlRmlsZXNQYXJhbXMgfSBmcm9tICcuL3RlbXBvcmFyeS12YXVsdC5janMnO1xuaW1wb3J0IHR5cGUgeyBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfSBmcm9tICcuL3RyYW5zcG9ydC1vcHRpb25zLmNqcyc7XG5pbXBvcnQgdHlwZSB7IE9ic2lkaWFuVHJhbnNwb3J0IH0gZnJvbSAnLi90cmFuc3BvcnQuY2pzJztcblxuaW1wb3J0IHsgRGVza3RvcE9ubHlQbHVnaW5Ta2lwRXJyb3IgfSBmcm9tICcuL2Rlc2t0b3Atb25seS1wbHVnaW4tc2tpcC1lcnJvci5janMnO1xuaW1wb3J0IHtcbiAgZW5hYmxlUGx1Z2luV2l0aEVycm9yQ2FwdHVyZSxcbiAgZ2V0R2VuZXJpY1BsdWdpbkxvYWRGYWlsdXJlTWVzc2FnZVxufSBmcm9tICcuL2VuYWJsZS1wbHVnaW4uY2pzJztcbmltcG9ydCB7IGVycm9yVG9TdHJpbmcgfSBmcm9tICcuL2Vycm9yLXRvLXN0cmluZy5janMnO1xuaW1wb3J0IHsgZXZhbEluT2JzaWRpYW4gfSBmcm9tICcuL2V2YWwtaW4tb2JzaWRpYW4uY2pzJztcbmltcG9ydCB7XG4gIHJlc29sdmVMZWZ0b3Zlck1heEFnZUluTWlsbGlzZWNvbmRzLFxuICBzd2VlcEhvc3RMZWZ0b3ZlcnMsXG4gIHdpbGxTd2VlcExlZnRvdmVyc1xufSBmcm9tICcuL2xlZnRvdmVyLWNsZWFudXAuY2pzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLmNqcyc7XG5pbXBvcnQge1xuICBjb21wdXRlQmFja29mZkRlbGF5SW5NaWxsaXNlY29uZHMsXG4gIHJlc29sdmVQbHVnaW5FbmFibGVSZXRyeUNvdW50LFxuICByZXNvbHZlUGx1Z2luRW5hYmxlUmV0cnlEZWxheUluTWlsbGlzZWNvbmRzLFxuICBzaG91bGRSZXRyeVBsdWdpbkVuYWJsZVxufSBmcm9tICcuL3BsdWdpbi1lbmFibGUtcmV0cnkuY2pzJztcbmltcG9ydCB7IGFjcXVpcmVTZXR1cExvY2sgfSBmcm9tICcuL3NldHVwLWxvY2suY2pzJztcbmltcG9ydCB7IFRlbXBvcmFyeVZhdWx0IH0gZnJvbSAnLi90ZW1wb3JhcnktdmF1bHQuY2pzJztcbmltcG9ydCB7IEFwcGl1bVRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWFwcGl1bS5janMnO1xuaW1wb3J0IHsgRGVza3RvcENkcFRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWRlc2t0b3AtY2RwLmNqcyc7XG5pbXBvcnQgeyBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9ucyB9IGZyb20gJy4vdHJhbnNwb3J0LWZhY3RvcnkuY2pzJztcbmltcG9ydCB7IGNoZWNrSXNNb2JpbGVUcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydC1vcHRpb25zLmNqcyc7XG5cbmNvbnN0IERFRkFVTFRfVFJBTlNQT1JUX1RZUEUgPSAnb2JzaWRpYW4tY2RwJztcbmNvbnN0IERJU1RfREVWID0gJ2Rpc3QvZGV2JztcbmNvbnN0IERJU1RfQlVJTEQgPSAnZGlzdC9idWlsZCc7XG5jb25zdCBNQUlOX0pTID0gJ21haW4uanMnO1xuY29uc3QgT0JTSURJQU5fQ09ORklHX0RJUiA9ICcub2JzaWRpYW4nO1xuY29uc3QgUExVR0lOU19ESVIgPSAncGx1Z2lucyc7XG5jb25zdCBDT01NVU5JVFlfUExVR0lOU19KU09OID0gJ2NvbW11bml0eS1wbHVnaW5zLmpzb24nO1xuY29uc3QgQVBQX0pTT04gPSAnYXBwLmpzb24nO1xuY29uc3QgQVBQX0pTT05fSU5ERU5UID0gMjtcblxuLyoqXG4gKiBUcmFja3Mgc2V0dXBzIHRoYXQgY29tcGxldGVkIHN1Y2Nlc3NmdWxseSBidXQgaGF2ZW4ndCBiZWVuIHRvcm4gZG93biB5ZXQuXG4gKiBVc2VkIGJ5IHRoZSBgYmVmb3JlRXhpdGAgaGFuZGxlciB0byBjbGVhbiB1cCB3aGVuIGEgdGVzdCBydW5uZXIgZXhpdHNcbiAqIHdpdGhvdXQgY2FsbGluZyB0ZWFyZG93biAoZS5nLiwgd2hlbiBvbmUgcHJvamVjdCdzIHNldHVwIGZhaWxzIGFuZCB0aGVcbiAqIHJ1bm5lciBhYm9ydHMgYmVmb3JlIHRlYXJpbmcgZG93biBhbHJlYWR5LWluaXRpYWxpemVkIHByb2plY3RzKS5cbiAqL1xuY29uc3QgYWN0aXZlU2V0dXBzID0gbmV3IFNldDxDb3JlU2V0dXBSZXN1bHQ+KCk7XG5jb25zdCBkaXNwb3NlZFJlc3VsdHMgPSBuZXcgV2Vha1NldDxDb3JlU2V0dXBSZXN1bHQ+KCk7XG5sZXQgaXNDbGVhbnVwSGFuZGxlclJlZ2lzdGVyZWQgPSBmYWxzZTtcblxuLyoqXG4gKiBUaGUgY3Jvc3MtcHJvY2VzcyBzZXR1cCBsb2NrIGhlbGQgYnkgZWFjaCBhY3RpdmUgc2V0dXAuIFJlbGVhc2VkIHdoZW4gdGhlXG4gKiBzZXR1cCBpcyB0b3JuIGRvd24gKG9yIGJ5IHRoZSBwcm9jZXNzIGNsZWFudXAgaGFuZGxlcnMpLCBhbGxvd2luZyBhIGNvbXBldGluZ1xuICogcnVuIHRvIHByb2NlZWQuIFNlZSB7QGxpbmsgYWNxdWlyZVNldHVwTG9ja30uXG4gKi9cbmNvbnN0IHNldHVwTG9ja3MgPSBuZXcgTWFwPENvcmVTZXR1cFJlc3VsdCwgU2V0dXBMb2NrPigpO1xuXG5jb25zdCBBTkRST0lEX0xPQ0tfU0NPUEUgPSAnYW5kcm9pZCc7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGNvcmVTZXR1cH0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29yZVNldHVwUGFyYW1zIHtcbiAgLyoqXG4gICAqIENvbW11bml0eS1wbHVnaW4gaWRzIHRvIGVuYWJsZSBpbiB0aGUgdmF1bHQgKippbiBhZGRpdGlvbiB0byoqIHRoZVxuICAgKiBwbHVnaW4tdW5kZXItdGVzdCwgYWZ0ZXIgaXQgaXMgZW5hYmxlZC4gRWFjaCBpZCdzIGJ1aWx0IGZpbGVzIG11c3QgYWxyZWFkeSBiZVxuICAgKiBwcmVzZW50IHVuZGVyIGAub2JzaWRpYW4vcGx1Z2lucy88aWQ+L2AgXHUyMDE0IHNlZWQgdGhlbSB2aWEge0BsaW5rIENvcmVTZXR1cFBhcmFtcy5wb3B1bGF0ZX1cbiAgICogKGUuZy4gd2l0aCBgYnVpbGREZW1vVmF1bHRQb3B1bGF0ZWApLiBFbmFibGluZyBnb2VzIHRocm91Z2ggdGhlIHNhbWVcbiAgICogcmV0cnkvbG9hZC12ZXJpZnkgcGF0aCBhcyB0aGUgcGx1Z2luLXVuZGVyLXRlc3QuIENvbXBvc2VzIHdpdGhcbiAgICogYGluc3RhbGxQbHVnaW46IGZhbHNlYCAoZW5hYmxlIGV4dHJhcyBpbnRvIGFuIG90aGVyd2lzZSBwbHVnaW4tbGVzcyB2YXVsdCkuXG4gICAqL1xuICByZWFkb25seSBlbmFibGVDb21tdW5pdHlQbHVnaW5zPzogcmVhZG9ubHkgc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gaW5zdGFsbCBhbmQgZW5hYmxlIHRoZSBidWlsdCBwbHVnaW4gaW4gdGhlIHRlbXAgdmF1bHQuIERlZmF1bHRzXG4gICAqIHRvIGB0cnVlYC4gU2V0IHRvIGBmYWxzZWAgZm9yIGEgKipub24tcGx1Z2luKiogY29uc3VtZXIgKGUuZy4gYSB0eXBpbmdzXG4gICAqIGNyYXdsZXIpIHRoYXQgb25seSBuZWVkcyBhIHJlZ2lzdGVyZWQsIGVtcHR5IHZhdWx0IHRvIGBldmFsSW5PYnNpZGlhbmBcbiAgICogYWdhaW5zdDogdGhlIHBsdWdpbiBgZGlzdGAvYG1hbmlmZXN0Lmpzb25gIHJlYWQsIHRoZSBjb3B5IGludG9cbiAgICogYC5vYnNpZGlhbi9wbHVnaW5zYCwgdGhlIGBjb21tdW5pdHktcGx1Z2lucy5qc29uYCB3cml0ZSwgYW5kIHRoZSBlbmFibGUgc3RlcFxuICAgKiBhcmUgYWxsIHNraXBwZWQsIHdoaWxlIHRoZSB0cmFuc3BvcnQsIHRlbXAgdmF1bHQsIHJlZ2lzdHJhdGlvbiwgYW5kXG4gICAqIHdvcmtlci1mYWNpbmcgZW5kcG9pbnQgcHJvdmlzaW9uaW5nIHN0aWxsIHJ1biB1bmNoYW5nZWQuXG4gICAqL1xuICByZWFkb25seSBpbnN0YWxsUGx1Z2luPzogYm9vbGVhbiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogRmlsZXMgYW5kIGZvbGRlcnMgdG8gd3JpdGUgaW50byB0aGUgdmF1bHQgKipiZWZvcmUqKiBPYnNpZGlhbiBvcGVucyBpdCwgc29cbiAgICogaXRzIHN0YXJ0dXAgc2NhbiBpbmRleGVzIHRoZW0gaW4gb25lIHBhc3MgKHNlZSB7QGxpbmsgVGVtcG9yYXJ5VmF1bHQucG9wdWxhdGV9KS5cbiAgICogVXNlIHRoaXMgZm9yIGxhcmdlIGZpeHR1cmVzIFx1MjAxNCB3cml0aW5nIHRob3VzYW5kcyBvZiBub3RlcyBhZnRlciBvcGVuIGFuZFxuICAgKiBmb3JjaW5nIGEgcmUtc2NhbiBpcyBmYXIgc2xvd2VyIGFuZCBsZXNzIHJlbGlhYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgcG9wdWxhdGU/OiBQb3B1bGF0ZUZpbGVzUGFyYW1zIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBUcmFuc3BvcnQgb3B0aW9ucy4gV2hlbiBvbWl0dGVkLCB1c2VzIGFuIG9mZi1zY3JlZW4gb3duZWQgZGVza3RvcCBpbnN0YW5jZS5cbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydE9wdGlvbnM/OiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmVzdWx0IHJldHVybmVkIGJ5IHtAbGluayBjb3JlU2V0dXB9LCB1c2VkIGJ5IGZyYW1ld29yayBhZGFwdGVyc1xuICogdG8gcGFzcyBjb250ZXh0IHRvIHRlc3Qgd29ya2Vycy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb3JlU2V0dXBSZXN1bHQge1xuICAvKipcbiAgVGhlIHRlbXBvcmFyeSB2YXVsdCBjcmVhdGVkIGR1cmluZyBzZXR1cC5cbiAgICovXG4gIHJlYWRvbmx5IHRlbXBvcmFyeVZhdWx0OiBUZW1wb3JhcnlWYXVsdDtcblxuICAvKipcbiAgVGhlIHRyYW5zcG9ydCBpbnN0YW5jZSB1c2VkIGR1cmluZyBzZXR1cC5cbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydDogT2JzaWRpYW5UcmFuc3BvcnQ7XG5cbiAgLyoqXG4gIFNob3J0IGxhYmVsIGZvciBsb2cgbWVzc2FnZXMgKGUuZy4gYFwib2JzaWRpYW4tY2RwXCJgKS5cbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydExhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSB0cmFuc3BvcnQgb3B0aW9ucyB0aGF0IHdlcmUgcmVzb2x2ZWQuXG4gICAqL1xuICByZWFkb25seSB0cmFuc3BvcnRPcHRpb25zOiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGNvcHlQbHVnaW5JbnRvVmF1bHR9LlxuICovXG5pbnRlcmZhY2UgQ29weVBsdWdpbkludG9WYXVsdFBhcmFtcyB7XG4gIC8qKlxuICBTaG9ydCBsYWJlbCBmb3IgbG9nIG1lc3NhZ2VzLlxuICAgKi9cbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblxuICAvKipcbiAgVGhlIHByb2plY3Qgcm9vdCB0byByZXNvbHZlIHRoZSBidWlsdCBwbHVnaW4gZnJvbS5cbiAgICovXG4gIHJlYWRvbmx5IHByb2plY3RSb290OiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSB0ZW1wIHZhdWx0IHRvIGNvcHkgdGhlIHBsdWdpbiBpbnRvLlxuICAgKi9cbiAgcmVhZG9ubHkgdGVtcG9yYXJ5VmF1bHQ6IFRlbXBvcmFyeVZhdWx0O1xuXG4gIC8qKlxuICBUaGUgdHJhbnNwb3J0ICh1c2VkIGZvciB0aGUgbW9iaWxlL2Rlc2t0b3Atb25seSBjb21wYXRpYmlsaXR5IGNoZWNrKS5cbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydDogT2JzaWRpYW5UcmFuc3BvcnQ7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGVuYWJsZUV4dHJhQ29tbXVuaXR5UGx1Z2luc30uXG4gKi9cbmludGVyZmFjZSBFbmFibGVFeHRyYUNvbW11bml0eVBsdWdpbnNQYXJhbXMge1xuICAvKipcbiAgU2hvcnQgbGFiZWwgZm9yIGxvZyBtZXNzYWdlcy5cbiAgICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBpZHMgb2YgdGhlIGV4dHJhIGNvbW11bml0eSBwbHVnaW5zIHRvIGVuYWJsZSAodGhlaXIgYmluYXJpZXMgbXVzdCBhbHJlYWR5IGJlIGluIHRoZSB2YXVsdCkuXG4gICAqL1xuICByZWFkb25seSBwbHVnaW5JZHM6IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4gIC8qKlxuICBUaGUgdGVtcCB2YXVsdCB0aGUgcGx1Z2lucyB3ZXJlIHNlZWRlZCBpbnRvLlxuICAgKi9cbiAgcmVhZG9ubHkgdGVtcG9yYXJ5VmF1bHQ6IFRlbXBvcmFyeVZhdWx0O1xuXG4gIC8qKlxuICBUaGUgdHJhbnNwb3J0IHRvIGV2YWx1YXRlIGFnYWluc3QuXG4gICAqL1xuICByZWFkb25seSB0cmFuc3BvcnQ6IE9ic2lkaWFuVHJhbnNwb3J0O1xuXG4gIC8qKlxuICBUaGUgcmVzb2x2ZWQgdHJhbnNwb3J0IG9wdGlvbnMgKHNvdXJjZSBvZiB0aGUgcGx1Z2luLWVuYWJsZSByZXRyeSBrbm9icykuXG4gICAqL1xuICByZWFkb25seSB0cmFuc3BvcnRPcHRpb25zOiBudWxsIHwgT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBlbmFibGVQbHVnaW5JblZhdWx0fS5cbiAqL1xuaW50ZXJmYWNlIEVuYWJsZVBsdWdpbkluVmF1bHRQYXJhbXMge1xuICAvKipcbiAgU2hvcnQgbGFiZWwgZm9yIGxvZyBtZXNzYWdlcy5cbiAgICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBpZCBvZiB0aGUgcGx1Z2luIHRvIGVuYWJsZS5cbiAgICovXG4gIHJlYWRvbmx5IHBsdWdpbklkOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSB0ZW1wIHZhdWx0IHRoZSBwbHVnaW4gd2FzIGNvcGllZCBpbnRvLlxuICAgKi9cbiAgcmVhZG9ubHkgdGVtcG9yYXJ5VmF1bHQ6IFRlbXBvcmFyeVZhdWx0O1xuXG4gIC8qKlxuICBUaGUgdHJhbnNwb3J0IHRvIGV2YWx1YXRlIGFnYWluc3QuXG4gICAqL1xuICByZWFkb25seSB0cmFuc3BvcnQ6IE9ic2lkaWFuVHJhbnNwb3J0O1xuXG4gIC8qKlxuICBUaGUgcmVzb2x2ZWQgdHJhbnNwb3J0IG9wdGlvbnMgKHNvdXJjZSBvZiB0aGUgcGx1Z2luLWVuYWJsZSByZXRyeSBrbm9icykuXG4gICAqL1xuICByZWFkb25seSB0cmFuc3BvcnRPcHRpb25zOiBudWxsIHwgT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBza2lwSWZEZXNrdG9wT25seX0uXG4gKi9cbmludGVyZmFjZSBTa2lwSWZEZXNrdG9wT25seVBhcmFtcyB7XG4gIC8qKlxuICBTaG9ydCBsYWJlbCBmb3IgbG9nIG1lc3NhZ2VzLlxuICAgKi9cbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblxuICAvKipcbiAgVGhlIHByb2plY3Qgcm9vdCB0byByZXNvbHZlIHRoZSBidWlsdCBwbHVnaW4ncyBtYW5pZmVzdCBmcm9tLlxuICAgKi9cbiAgcmVhZG9ubHkgcHJvamVjdFJvb3Q6IHN0cmluZztcblxuICAvKipcbiAgV2hldGhlciBhIHBsdWdpbiBpcyBiZWluZyBpbnN0YWxsZWQgYXQgYWxsIC0tIHRoZXJlIGlzIG5vdGhpbmcgdG8gY2hlY2sgd2hlbiB0aGUgdmF1bHQgc3RheXMgZW1wdHkuXG4gICAqL1xuICByZWFkb25seSBzaG91bGRJbnN0YWxsUGx1Z2luOiBib29sZWFuO1xuXG4gIC8qKlxuICBUaGUgcmVzb2x2ZWQgdHJhbnNwb3J0IG9wdGlvbnMsIHdob3NlIGRpc2NyaW1pbmFudCBzYXlzIHdoZXRoZXIgdGhpcyBydW4gaXMgbW9iaWxlLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0T3B0aW9uczogT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBzd2VlcExlZnRvdmVyc30uXG4gKi9cbmludGVyZmFjZSBTd2VlcExlZnRvdmVyc1BhcmFtcyB7XG4gIC8qKlxuICBEaXJlY3RvcnkgbmFtZXMgdG8ga2VlcCByZWdhcmRsZXNzIG9mIGFnZSAoZS5nLiBhIGNvbmN1cnJlbnQgc2V0dXAncyB2YXVsdCkuXG4gICAqL1xuICByZWFkb25seSBleGNsdWRlZE5hbWVzPzogcmVhZG9ubHkgc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFNob3J0IGxhYmVsIGZvciBsb2cgbWVzc2FnZXMuXG4gICAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKlxuICBXaGljaCBlbmQgb2YgdGhlIHJ1biBpcyBzd2VlcGluZywgZm9yIHRoZSBsb2cgcHJlZml4LlxuICAgKi9cbiAgcmVhZG9ubHkgcGhhc2U6ICdzZXR1cCcgfCAndGVhcmRvd24nO1xuXG4gIC8qKlxuICBUaGUgcmVzb2x2ZWQgdHJhbnNwb3J0IG9wdGlvbnMgKHNvdXJjZSBvZiB0aGUgc3dlZXAga25vYnMpLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0T3B0aW9uczogT2JzaWRpYW5UcmFuc3BvcnRPcHRpb25zIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEZyYW1ld29yay1hZ25vc3RpYyBnbG9iYWwgc2V0dXAgbG9naWMuXG4gKlxuICogTG9hZHMgYC5lbnZgIGZyb20gdGhlIHByb2plY3Qgcm9vdCwgY3JlYXRlcyBhIHRyYW5zcG9ydCwgY3JlYXRlcyBhbmQgcmVnaXN0ZXJzXG4gKiBhIHRlbXBvcmFyeSB2YXVsdCB3aXRoIE9ic2lkaWFuLCBhbmQgXHUyMDE0IHVubGVzcyB7QGxpbmsgQ29yZVNldHVwUGFyYW1zLmluc3RhbGxQbHVnaW59XG4gKiBpcyBgZmFsc2VgIFx1MjAxNCBjb3BpZXMgdGhlIGJ1aWx0IHBsdWdpbiBpbnRvIHRoZSB2YXVsdCBhbmQgZW5hYmxlcyBpdC4gVGhlXG4gKiBwbHVnaW4tbGVzcyBtb2RlIHN0aWxsIGxhdW5jaGVzIHRoZSBvd25lZCBpbnN0YW5jZSBhbmQgcHVibGlzaGVzIGl0c1xuICogd29ya2VyLWZhY2luZyBlbmRwb2ludCwgc28gYSBub24tcGx1Z2luIGNvbnN1bWVyIHJldXNlcyB0aGUgc2FtZSBhdHRhY2ggd2lyaW5nLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBTZXR1cCBwYXJhbWV0ZXJzLlxuICogQHJldHVybnMgVGhlIHNldHVwIHJlc3VsdCBjb250YWluaW5nIHRoZSB0ZW1wIHZhdWx0LCB0cmFuc3BvcnQsIGFuZCByZXNvbHZlZCBvcHRpb25zLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29yZVNldHVwKHBhcmFtcz86IENvcmVTZXR1cFBhcmFtcyk6IFByb21pc2U8Q29yZVNldHVwUmVzdWx0PiB7XG4gIGNvbnN0IHByb2plY3RSb290ID0gZmluZFByb2plY3RSb290KCk7XG4gIGNvbnN0IGVudkZpbGVQYXRoID0gam9pbihwcm9qZWN0Um9vdCwgJy5lbnYnKTtcbiAgaWYgKGV4aXN0c1N5bmMoZW52RmlsZVBhdGgpKSB7XG4gICAgbG9hZEVudkZpbGUoZW52RmlsZVBhdGgpO1xuICB9XG5cbiAgY29uc3QgdHJhbnNwb3J0T3B0aW9ucyA9IHJlc29sdmVJbnRlZ3JhdGlvblRyYW5zcG9ydE9wdGlvbnMocGFyYW1zPy50cmFuc3BvcnRPcHRpb25zKTtcbiAgY29uc3QgbGFiZWwgPSB0cmFuc3BvcnRPcHRpb25zLnR5cGU7XG4gIGNvbnN0IHNob3VsZEluc3RhbGxQbHVnaW4gPSBwYXJhbXM/Lmluc3RhbGxQbHVnaW4gIT09IGZhbHNlO1xuXG4gIC8vIEJlZm9yZSB0aGUgbG9jaywgdGhlIHN3ZWVwIGFuZCBhYm92ZSBhbGwgdGhlIHRyYW5zcG9ydDogY3JlYXRpbmcgYSBtb2JpbGUgdHJhbnNwb3J0IGJvb3RzIHRoZSBBVkQgYW5kXG4gIC8vIEF1dG8tc3RhcnRzIEFwcGl1bSAofjcwIHMpIG9ubHkgdG8gcmVhY2ggdGhlIHNhbWUgY29uY2x1c2lvbiBmcm9tIGB0cmFuc3BvcnQuaXNNb2JpbGVgIGZ1cnRoZXIgZG93bi5cbiAgLy8gTmVpdGhlciBpbnB1dCBuZWVkcyBhIGRldmljZSAtLSB0aGUgbWFuaWZlc3QgaXMgb24gZGlzayBhbmQgdGhlIGRpc2NyaW1pbmFudCBhbHJlYWR5IHNheXMgbW9iaWxlLlxuICBhd2FpdCBza2lwSWZEZXNrdG9wT25seSh7IGxhYmVsLCBwcm9qZWN0Um9vdCwgc2hvdWxkSW5zdGFsbFBsdWdpbiwgdHJhbnNwb3J0T3B0aW9ucyB9KTtcblxuICBjb25zdCBsb2NrU2NvcGUgPSBnZXRMb2NrU2NvcGUodHJhbnNwb3J0T3B0aW9ucyk7XG5cbiAgbGV0IGxvY2s6IFNldHVwTG9jayB8IHVuZGVmaW5lZDtcbiAgaWYgKGxvY2tTY29wZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIEFjcXVpcmluZyAnJHtsb2NrU2NvcGV9JyBzZXR1cCBsb2NrIChzZXJpYWxpemVzIGFnYWluc3QgYW55IGNvbmN1cnJlbnQgaW50ZWdyYXRpb24tdGVzdCBydW4pLi4uYCk7XG4gICAgbG9jayA9IGF3YWl0IGFjcXVpcmVTZXR1cExvY2soeyBsYWJlbCwgc2NvcGU6IGxvY2tTY29wZSB9KTtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gU2V0dXAgbG9jayBhY3F1aXJlZC5gKTtcbiAgfVxuXG4gIGF3YWl0IHN3ZWVwTGVmdG92ZXJzKHsgbGFiZWwsIHBoYXNlOiAnc2V0dXAnLCB0cmFuc3BvcnRPcHRpb25zIH0pO1xuXG4gIGxldCB0cmFuc3BvcnQ6IE9ic2lkaWFuVHJhbnNwb3J0IHwgdW5kZWZpbmVkO1xuICBsZXQgdGVtcG9yYXJ5VmF1bHQ6IFRlbXBvcmFyeVZhdWx0IHwgdW5kZWZpbmVkO1xuXG4gIHRyeSB7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIENyZWF0aW5nIHRyYW5zcG9ydC4uLmApO1xuICAgIHRyYW5zcG9ydCA9IGF3YWl0IGNyZWF0ZVRyYW5zcG9ydEZyb21PcHRpb25zKHRyYW5zcG9ydE9wdGlvbnMpO1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBUcmFuc3BvcnQgY3JlYXRlZDogJHt0cmFuc3BvcnQuY29uc3RydWN0b3IubmFtZX1gKTtcblxuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBQcm9qZWN0IHJvb3Q6ICR7cHJvamVjdFJvb3R9YCk7XG5cbiAgICB0ZW1wb3JhcnlWYXVsdCA9IG5ldyBUZW1wb3JhcnlWYXVsdCgpO1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBDcmVhdGVkIHRlbXAgdmF1bHQ6ICR7dGVtcG9yYXJ5VmF1bHQucGF0aH1gKTtcblxuICAgIGxldCBwbHVnaW5JZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgaWYgKHNob3VsZEluc3RhbGxQbHVnaW4pIHtcbiAgICAgIHBsdWdpbklkID0gYXdhaXQgY29weVBsdWdpbkludG9WYXVsdCh7IGxhYmVsLCBwcm9qZWN0Um9vdCwgdGVtcG9yYXJ5VmF1bHQsIHRyYW5zcG9ydCB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFNraXBwaW5nIHBsdWdpbiBpbnN0YWxsIChpbnN0YWxsUGx1Z2luOiBmYWxzZSkgXHUyMDE0IHJlZ2lzdGVyaW5nIGFuIGVtcHR5IHZhdWx0LmApO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXM/LnBvcHVsYXRlKSB7XG4gICAgICBjb25zdCBlbnRyeUNvdW50ID0gT2JqZWN0LmtleXMocGFyYW1zLnBvcHVsYXRlKS5sZW5ndGg7XG4gICAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gUG9wdWxhdGluZyB2YXVsdCB3aXRoICR7U3RyaW5nKGVudHJ5Q291bnQpfSBlbnRyaWVzIGJlZm9yZSBvcGVuLi4uYCk7XG4gICAgICB0ZW1wb3JhcnlWYXVsdC5wb3B1bGF0ZShwYXJhbXMucG9wdWxhdGUpO1xuICAgIH1cblxuICAgIGF3YWl0IGVuc3VyZUFsd2F5c1VwZGF0ZUxpbmtzKHRlbXBvcmFyeVZhdWx0LCBsYWJlbCk7XG5cbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gU3luY2luZyB2YXVsdCB0byBkZXZpY2UuLi5gKTtcbiAgICBhd2FpdCB0ZW1wb3JhcnlWYXVsdC5zeW5jVG9EZXZpY2UodHJhbnNwb3J0KTtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gUmVnaXN0ZXJpbmcgdmF1bHQuLi5gKTtcbiAgICBhd2FpdCB0ZW1wb3JhcnlWYXVsdC5yZWdpc3Rlcih0cmFuc3BvcnQpO1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBWYXVsdCByZWdpc3RlcmVkLmApO1xuXG4gICAgaWYgKHBsdWdpbklkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGF3YWl0IGVuYWJsZVBsdWdpbkluVmF1bHQoeyBsYWJlbCwgcGx1Z2luSWQsIHRlbXBvcmFyeVZhdWx0LCB0cmFuc3BvcnQsIHRyYW5zcG9ydE9wdGlvbnMgfSk7XG4gICAgfVxuXG4gICAgYXdhaXQgZW5hYmxlRXh0cmFDb21tdW5pdHlQbHVnaW5zKHtcbiAgICAgIGxhYmVsLFxuICAgICAgcGx1Z2luSWRzOiBwYXJhbXM/LmVuYWJsZUNvbW11bml0eVBsdWdpbnMgPz8gW10sXG4gICAgICB0ZW1wb3JhcnlWYXVsdCxcbiAgICAgIHRyYW5zcG9ydCxcbiAgICAgIHRyYW5zcG9ydE9wdGlvbnNcbiAgICB9KTtcblxuICAgIGNvbnN0IGF1Z21lbnRlZE9wdGlvbnMgPSBhdWdtZW50VHJhbnNwb3J0T3B0aW9ucyh0cmFuc3BvcnRPcHRpb25zLCB0cmFuc3BvcnQpO1xuICAgIGNvbnN0IHJlc3VsdDogQ29yZVNldHVwUmVzdWx0ID0geyB0ZW1wb3JhcnlWYXVsdCwgdHJhbnNwb3J0LCB0cmFuc3BvcnRMYWJlbDogbGFiZWwsIHRyYW5zcG9ydE9wdGlvbnM6IGF1Z21lbnRlZE9wdGlvbnMgfTtcbiAgICBhY3RpdmVTZXR1cHMuYWRkKHJlc3VsdCk7XG4gICAgaWYgKGxvY2spIHtcbiAgICAgIHNldHVwTG9ja3Muc2V0KHJlc3VsdCwgbG9jayk7XG4gICAgfVxuICAgIHJlZ2lzdGVyUHJvY2Vzc0NsZWFudXBIYW5kbGVyKCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gU2V0dXAgZmFpbGVkLCBjbGVhbmluZyB1cC4uLmApO1xuICAgIHRyeSB7XG4gICAgICBpZiAodGVtcG9yYXJ5VmF1bHQgJiYgdHJhbnNwb3J0KSB7XG4gICAgICAgIGF3YWl0IHRlbXBvcmFyeVZhdWx0LmRpc3Bvc2UodHJhbnNwb3J0KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChjbGVhbnVwRXJyb3I6IHVua25vd24pIHtcbiAgICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBWYXVsdCBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoY2xlYW51cEVycm9yKX1gKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRyYW5zcG9ydD8uZGlzcG9zZT8uKCk7XG4gICAgfSBjYXRjaCAoY2xlYW51cEVycm9yOiB1bmtub3duKSB7XG4gICAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gVHJhbnNwb3J0IGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhjbGVhbnVwRXJyb3IpfWApO1xuICAgIH1cblxuICAgIC8vIFJlbGVhc2UgdGhlIGxvY2sgc28gYSB3YWl0aW5nIHJ1biBjYW4gcHJvY2VlZCBldmVuIHRob3VnaCB0aGlzIHJ1biBmYWlsZWQuXG4gICAgbG9jaz8ucmVsZWFzZSgpO1xuXG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIE5PVEU6IElmIHRoZSB0ZXN0IHJ1bm5lciByZXBvcnRzIFwiTm8gdGVzdCBmaWxlcyBmb3VuZFwiLCBpZ25vcmUgaXQgXHUyMDE0IGl0IGlzIGEgc2lkZSBlZmZlY3Qgb2YgdGhlIHNldHVwIGZhaWx1cmUgYWJvdmUuYCk7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cblxuLyoqXG4gKiBGcmFtZXdvcmstYWdub3N0aWMgZ2xvYmFsIHRlYXJkb3duIGxvZ2ljLlxuICpcbiAqIERpc3Bvc2VzIG9mIHRoZSB0ZW1wb3JhcnkgdmF1bHQgYW5kIHRyYW5zcG9ydCBjcmVhdGVkIGR1cmluZyBzZXR1cC5cbiAqXG4gKiBAcGFyYW0gcmVzdWx0IC0gVGhlIHJlc3VsdCBmcm9tIHtAbGluayBjb3JlU2V0dXB9LiBXaGVuIGB1bmRlZmluZWRgLCBkb2VzIG5vdGhpbmcuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb3JlVGVhcmRvd24ocmVzdWx0PzogQ29yZVNldHVwUmVzdWx0KTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmICghcmVzdWx0IHx8IGRpc3Bvc2VkUmVzdWx0cy5oYXMocmVzdWx0KSkge1xuICAgIHJldHVybjtcbiAgfVxuICBkaXNwb3NlZFJlc3VsdHMuYWRkKHJlc3VsdCk7XG5cbiAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd246JHtyZXN1bHQudHJhbnNwb3J0TGFiZWx9XSBUZWFyaW5nIGRvd24uLi5gKTtcblxuICB0cnkge1xuICAgIGF3YWl0IHRlYXJkb3duQXN5bmMocmVzdWx0KTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bjoke3Jlc3VsdC50cmFuc3BvcnRMYWJlbH1dIENsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhlcnJvcil9YCk7XG4gIH0gZmluYWxseSB7XG4gICAgYWN0aXZlU2V0dXBzLmRlbGV0ZShyZXN1bHQpO1xuICAgIHJlbGVhc2VTZXR1cExvY2socmVzdWx0KTtcbiAgfVxuXG4gIGF3YWl0IHN3ZWVwTGVmdG92ZXJzKHtcbiAgICBleGNsdWRlZE5hbWVzOiBbLi4uYWN0aXZlU2V0dXBzXS5tYXAoKGFjdGl2ZVNldHVwKSA9PiBiYXNlbmFtZShhY3RpdmVTZXR1cC50ZW1wb3JhcnlWYXVsdC5wYXRoKSksXG4gICAgbGFiZWw6IHJlc3VsdC50cmFuc3BvcnRMYWJlbCxcbiAgICBwaGFzZTogJ3RlYXJkb3duJyxcbiAgICB0cmFuc3BvcnRPcHRpb25zOiByZXN1bHQudHJhbnNwb3J0T3B0aW9uc1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyB0cmFuc3BvcnQgb3B0aW9ucyBmb3IgYW4gaW50ZWdyYXRpb24gcnVuLlxuICpcbiAqIERlc2t0b3AgbGF1bmNoZXMgYXJlIG5vcm1hbGx5IHZpc2libGUsIGJ1dCB0ZXN0IHNldHVwIGV4cGxpY2l0bHkga2VlcHMgaXRzXG4gKiBvd25lZCBpbnN0YW5jZSBvZmYtc2NyZWVuIHNvIGl0IGRvZXMgbm90IGludGVycnVwdCB0aGUgZGV2ZWxvcGVyLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ29uc3VtZXItcHJvdmlkZWQgdHJhbnNwb3J0IG9wdGlvbnMuXG4gKiBAcmV0dXJucyBPcHRpb25zIHdpdGggdGhlIGRlc2t0b3AgaW50ZWdyYXRpb24gdmlzaWJpbGl0eSBkZWZhdWx0IGFwcGxpZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlSW50ZWdyYXRpb25UcmFuc3BvcnRPcHRpb25zKG9wdGlvbnM/OiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMpOiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMge1xuICBpZiAob3B0aW9ucz8udHlwZSA9PT0gJ29ic2lkaWFuLWFuZHJvaWQtYXBwaXVtJykge1xuICAgIHJldHVybiBvcHRpb25zO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5vcHRpb25zLFxuICAgIGlzT2JzaWRpYW5BcHBWaXNpYmxlOiBvcHRpb25zPy5pc09ic2lkaWFuQXBwVmlzaWJsZSA/PyBmYWxzZSxcbiAgICB0eXBlOiAnb2JzaWRpYW4tY2RwJ1xuICB9O1xufVxuXG4vKipcbiAqIEF1Z21lbnRzIHRyYW5zcG9ydCBvcHRpb25zIHdpdGggcmV1c2UgaW5mbyBzbyB0ZXN0IHdvcmtlcnMgY2FuIHJlYXR0YWNoIHRvIHRoZVxuICogaW5zdGFuY2UgdGhlIGdsb2JhbCBzZXR1cCBhbHJlYWR5IGxhdW5jaGVkIGluc3RlYWQgb2YgY3JlYXRpbmcgdGhlaXIgb3duOlxuICpcbiAqIC0gKipBcHBpdW0qKiBcdTIwMTQgaW5qZWN0cyB0aGUgZXN0YWJsaXNoZWQgYHNlc3Npb25JZGAvYGRldmljZUlkYC5cbiAqIC0gKipPd25lZCBkZXNrdG9wIENEUCoqIFx1MjAxNCBpbmplY3RzIHRoZSBvd25lZCBpbnN0YW5jZSdzIGBob3N0YC9gcG9ydGAgKGNob3NlblxuICogICBhdCBsYXVuY2gpIHBsdXMgdGhlIGludGVybmFsIGBpc0hhcm5lc3NPd25lZEluc3RhbmNlYCBmbGFnLCBzbyBlYWNoIHdvcmtlclxuICogICAqKmF0dGFjaGVzKiogdG8gdGhhdCBpbnN0YW5jZSBvdmVyIENEUCByYXRoZXIgdGhhbiBsYXVuY2hpbmcgKGFuZCBuZXZlclxuICogICByZWdpc3RlcmluZykgaXRzIG93biBcdTIwMTQgdGhlIGJ1ZyB0aGF0IG90aGVyd2lzZSBsZWF2ZXMgYSB3b3JrZXIncyB0cmFuc3BvcnRcbiAqICAgd2l0aCBubyBDRFAgZW5kcG9pbnQuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgb3JpZ2luYWwgdHJhbnNwb3J0IG9wdGlvbnMuXG4gKiBAcGFyYW0gdHJhbnNwb3J0IC0gVGhlIHRyYW5zcG9ydCBpbnN0YW5jZSBjcmVhdGVkIGR1cmluZyBzZXR1cC5cbiAqIEByZXR1cm5zIFRoZSBhdWdtZW50ZWQgb3B0aW9ucywgb3IgdGhlIG9yaWdpbmFsIG9wdGlvbnMgaWYgbm90IGFwcGxpY2FibGUuXG4gKi9cbmZ1bmN0aW9uIGF1Z21lbnRUcmFuc3BvcnRPcHRpb25zKFxuICBvcHRpb25zOiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfCB1bmRlZmluZWQsXG4gIHRyYW5zcG9ydDogT2JzaWRpYW5UcmFuc3BvcnRcbik6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZCB7XG4gIGlmIChvcHRpb25zPy50eXBlID09PSAnb2JzaWRpYW4tYW5kcm9pZC1hcHBpdW0nICYmIHRyYW5zcG9ydCBpbnN0YW5jZW9mIEFwcGl1bVRyYW5zcG9ydCkge1xuICAgIGNvbnN0IHNlc3Npb25JbmZvID0gdHJhbnNwb3J0LmdldFNlc3Npb25JbmZvKCk7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtvcHRpb25zLnR5cGV9XSBTZXNzaW9uIHJldXNlIGluZm86IHNlc3Npb25JZD0ke3Nlc3Npb25JbmZvLnNlc3Npb25JZH0sIGRldmljZUlkPSR7c2Vzc2lvbkluZm8uZGV2aWNlSWR9YCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBkZXZpY2VJZDogc2Vzc2lvbkluZm8uZGV2aWNlSWQsXG4gICAgICBzZXNzaW9uSWQ6IHNlc3Npb25JbmZvLnNlc3Npb25JZFxuICAgIH07XG4gIH1cblxuICBpZiAoKG9wdGlvbnMgPT09IHVuZGVmaW5lZCB8fCBvcHRpb25zLnR5cGUgPT09ICdvYnNpZGlhbi1jZHAnKSAmJiB0cmFuc3BvcnQgaW5zdGFuY2VvZiBEZXNrdG9wQ2RwVHJhbnNwb3J0KSB7XG4gICAgY29uc3QgZW5kcG9pbnQgPSB0cmFuc3BvcnQuZ2V0T3duZWRJbnN0YW5jZUVuZHBvaW50KCk7XG4gICAgaWYgKGVuZHBvaW50KSB7XG4gICAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke0RFRkFVTFRfVFJBTlNQT1JUX1RZUEV9XSBPd25lZCBpbnN0YW5jZSByZXVzZSBpbmZvOiBob3N0PSR7ZW5kcG9pbnQuaG9zdH0sIHBvcnQ9JHtTdHJpbmcoZW5kcG9pbnQucG9ydCl9YCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICBob3N0OiBlbmRwb2ludC5ob3N0LFxuICAgICAgICBpc0hhcm5lc3NPd25lZEluc3RhbmNlOiB0cnVlLFxuICAgICAgICBwb3J0OiBlbmRwb2ludC5wb3J0LFxuICAgICAgICB0eXBlOiAnb2JzaWRpYW4tY2RwJ1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3B0aW9ucztcbn1cblxuLyoqXG4gKiBDb3BpZXMgdGhlIGJ1aWx0IHBsdWdpbiBpbnRvIHRoZSB0ZW1wIHZhdWx0IGFuZCBtYXJrcyBpdCBhcyBhIGNvbW11bml0eSBwbHVnaW4uXG4gKlxuICogUmVhZHMgYG1hbmlmZXN0Lmpzb25gIGZyb20gdGhlIG5ld2VyIG9mIGBkaXN0L2RldmAvYGRpc3QvYnVpbGRgLCByZWplY3RzIGFcbiAqIGRlc2t0b3Atb25seSBwbHVnaW4gb24gYSBtb2JpbGUgdHJhbnNwb3J0LCBjb3BpZXMgdGhlIGJ1aWxkIGludG9cbiAqIGAub2JzaWRpYW4vcGx1Z2lucy88aWQ+YCwgYW5kIHdyaXRlcyBgLm9ic2lkaWFuL2NvbW11bml0eS1wbHVnaW5zLmpzb25gLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgY29weSBwYXJhbWV0ZXJzLlxuICogQHJldHVybnMgVGhlIHBsdWdpbiBpZCByZWFkIGZyb20gdGhlIG1hbmlmZXN0LlxuICovXG5hc3luYyBmdW5jdGlvbiBjb3B5UGx1Z2luSW50b1ZhdWx0KHBhcmFtczogQ29weVBsdWdpbkludG9WYXVsdFBhcmFtcyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHsgbGFiZWwsIHByb2plY3RSb290LCB0ZW1wb3JhcnlWYXVsdCwgdHJhbnNwb3J0IH0gPSBwYXJhbXM7XG4gIGNvbnN0IGRpc3RQYXRoID0gYXdhaXQgcmVzb2x2ZURpc3RQYXRoKHByb2plY3RSb290KTtcbiAgY29uc3QgbWFuaWZlc3RKc29uID0gSlNPTi5wYXJzZShhd2FpdCByZWFkRmlsZShqb2luKGRpc3RQYXRoLCAnbWFuaWZlc3QuanNvbicpLCAndXRmLTgnKSkgYXMgUGx1Z2luTWFuaWZlc3Q7XG4gIGNvbnN0IHBsdWdpbklkID0gbWFuaWZlc3RKc29uLmlkO1xuXG4gIC8vIFRoZSBzYW1lIHJlZnVzYWwge0BsaW5rIHNraXBJZkRlc2t0b3BPbmx5fSBhbHJlYWR5IG1hZGUgYmVmb3JlIHRoZSB0cmFuc3BvcnQgZXhpc3RlZC4gS2VwdCBhcyB0aGVcbiAgLy8gQmFja3N0b3AgZm9yIGFueSBjYWxsZXIgdGhhdCByZWFjaGVzIGhlcmUgYW5vdGhlciB3YXksIGFuZCB0aHJvd2luZyB0aGUgc2FtZSB0eXBlIHNvIGJvdGggcGF0aHMgcmVhZFxuICAvLyBJZGVudGljYWxseSBpbiB0aGUgbG9nLlxuICBpZiAodHJhbnNwb3J0LmlzTW9iaWxlICYmIG1hbmlmZXN0SnNvbi5pc0Rlc2t0b3BPbmx5KSB7XG4gICAgdGhyb3cgbmV3IERlc2t0b3BPbmx5UGx1Z2luU2tpcEVycm9yKHBsdWdpbklkKTtcbiAgfVxuXG4gIGNvbnN0IG1haW5KcyA9IGpvaW4oZGlzdFBhdGgsIE1BSU5fSlMpO1xuICBjb25zdCBidWlsZFN0YXQgPSBhd2FpdCBzdGF0KG1haW5Kcyk7XG4gIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBVc2luZyAke2Rpc3RQYXRofSAoJHtidWlsZFN0YXQubXRpbWUudG9JU09TdHJpbmcoKX0pLiBJZiBvdXRkYXRlZCwgcmVidWlsZC5gKTtcblxuICBjb25zdCBwbHVnaW5EaXJlY3RvcnkgPSBqb2luKHRlbXBvcmFyeVZhdWx0LnBhdGgsIE9CU0lESUFOX0NPTkZJR19ESVIsIFBMVUdJTlNfRElSLCBwbHVnaW5JZCk7XG4gIGF3YWl0IG1rZGlyKHBsdWdpbkRpcmVjdG9yeSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIGF3YWl0IGNwKGRpc3RQYXRoLCBwbHVnaW5EaXJlY3RvcnksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICBhd2FpdCB3cml0ZUZpbGUoam9pbih0ZW1wb3JhcnlWYXVsdC5wYXRoLCBPQlNJRElBTl9DT05GSUdfRElSLCBDT01NVU5JVFlfUExVR0lOU19KU09OKSwgSlNPTi5zdHJpbmdpZnkoW3BsdWdpbklkXSkpO1xuXG4gIHJldHVybiBwbHVnaW5JZDtcbn1cblxuLyoqXG4gKiBFbmFibGVzIGV4dHJhIGNvbW11bml0eSBwbHVnaW5zIChiZXlvbmQgdGhlIHBsdWdpbi11bmRlci10ZXN0KSBpbiB0aGUgcmVnaXN0ZXJlZCB2YXVsdCwgZWFjaCB0aHJvdWdoIHRoZVxuICogc2FtZSB7QGxpbmsgZW5hYmxlUGx1Z2luSW5WYXVsdH0gcGF0aC4gRWFjaCBwbHVnaW4ncyBidWlsdCBmaWxlcyBtdXN0IGFscmVhZHkgYmUgcHJlc2VudCBpbiB0aGUgdmF1bHQgKHNlZWRcbiAqIHRoZW0gdmlhIHtAbGluayBDb3JlU2V0dXBQYXJhbXMucG9wdWxhdGV9KS4gQSBuby1vcCB3aGVuIHRoZSBsaXN0IGlzIGVtcHR5LlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZW5hYmxlIHBhcmFtZXRlcnMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGVuYWJsZUV4dHJhQ29tbXVuaXR5UGx1Z2lucyhwYXJhbXM6IEVuYWJsZUV4dHJhQ29tbXVuaXR5UGx1Z2luc1BhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7IGxhYmVsLCBwbHVnaW5JZHMsIHRlbXBvcmFyeVZhdWx0LCB0cmFuc3BvcnQsIHRyYW5zcG9ydE9wdGlvbnMgfSA9IHBhcmFtcztcbiAgZm9yIChjb25zdCBwbHVnaW5JZCBvZiBwbHVnaW5JZHMpIHtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gRW5hYmxpbmcgZXh0cmEgY29tbXVuaXR5IHBsdWdpbiBcIiR7cGx1Z2luSWR9XCIuLi5gKTtcbiAgICBhd2FpdCBlbmFibGVQbHVnaW5JblZhdWx0KHsgbGFiZWwsIHBsdWdpbklkLCB0ZW1wb3JhcnlWYXVsdCwgdHJhbnNwb3J0LCB0cmFuc3BvcnRPcHRpb25zIH0pO1xuICB9XG59XG5cbi8qKlxuICogRW5hYmxlcyB0aGUgcGx1Z2luIGluIHRoZSByZWdpc3RlcmVkIHZhdWx0IGFuZCB2ZXJpZmllcyBpdCBsb2FkZWQuXG4gKlxuICogT2JzaWRpYW4ncyBgZW5hYmxlUGx1Z2luKClgIHdyYXBzIGBsb2FkUGx1Z2luKClgIGluIGEgdHJ5LWNhdGNoIHRoYXQgc3dhbGxvd3NcbiAqIGVycm9ycyBhbmQgcmV0dXJucyBmYWxzZSwgc28ge0BsaW5rIGVuYWJsZVBsdWdpbldpdGhFcnJvckNhcHR1cmV9IG1vbmtleS1wYXRjaGVzXG4gKiBgbG9hZFBsdWdpbigpYCB0byBjYXB0dXJlIHRoZSBlcnJvciBiZWZvcmUgaXQncyBzd2FsbG93ZWQuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBlbmFibGUgcGFyYW1ldGVycy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZW5hYmxlUGx1Z2luSW5WYXVsdChwYXJhbXM6IEVuYWJsZVBsdWdpbkluVmF1bHRQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBsYWJlbCwgcGx1Z2luSWQsIHRlbXBvcmFyeVZhdWx0LCB0cmFuc3BvcnQsIHRyYW5zcG9ydE9wdGlvbnMgfSA9IHBhcmFtcztcbiAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIEVuYWJsaW5nIHBsdWdpbiBcIiR7cGx1Z2luSWR9XCIuLi5gKTtcblxuICAvKlxuICAgKiBPcGVuIGEgbmF0aXZlIGNvbnNvbGUtY2FwdHVyZSB3aW5kb3cgKExheWVyIDIsIEFuZHJvaWQgb25seSkgYXJvdW5kIHRoZVxuICAgKiBlbmFibGUgc28gdGhhdCBpZiBPYnNpZGlhbiBzd2FsbG93cyB0aGUgbG9hZCBlcnJvciBiZWZvcmUgdGhlIG1vbmtleS1wYXRjaFxuICAgKiBhbmQgdGhlIHJlbmRlcmVyIGNvbnNvbGUgKExheWVyIDEpIGNhbWUgdXAgZW1wdHksIHdlIGNhbiBzdGlsbCByZWNvdmVyIHRoZVxuICAgKiByZWFsIGNhdXNlIGZyb20gYGFkYiBsb2djYXRgLiBOby1vcCAodW5kZWZpbmVkKSBvbiB0cmFuc3BvcnRzIHRoYXQgZG9uJ3RcbiAgICogaW1wbGVtZW50IGl0IChlLmcuIGRlc2t0b3ApLlxuICAgKi9cbiAgY29uc3QgY2FwdHVyZUhhbmRsZSA9IGF3YWl0IHRyYW5zcG9ydC5iZWdpbkNvbnNvbGVDYXB0dXJlPy4oKTtcblxuICAvKlxuICAgKiBPbiBhIGZyZXNobHkgY29sZC1ib290ZWQgZW11bGF0b3IgdGhlIHBsdWdpbiBzdWJzeXN0ZW0gY2FuIHN0aWxsIGJlIHNldHRsaW5nXG4gICAqIHdoZW4gd2UgZW5hYmxlIHRoZSBwbHVnaW4sIHNvIGEgc2luZ2xlLXNob3QgZW5hYmxlIHJhY2VzIHRoZSBsb2FkIGFuZCBsb3Nlc1xuICAgKiAodGhlIHBsdWdpbiBsYW5kcyBpbiB0aGUgZW5hYmxlZCBzZXQgYnV0IG5ldmVyIGxvYWRzKS4gUmV0cnkgdGhlIGVuYWJsZSArXG4gICAqIGxvYWQtdmVyaWZpY2F0aW9uIGEgZmV3IHRpbWVzIHdpdGggZXhwb25lbnRpYWwgYmFja29mZiwgd2hpY2ggcmVjb3ZlcnMgdGhlXG4gICAqIHRyYW5zaWVudCByYWNlLiBBIGNhcHR1cmVkIGxvYWQgZXJyb3IgKGByZWFsRXJyb3JgKSBpcyBhIGRldGVybWluaXN0aWMgYnVnIFx1MjAxNFxuICAgKiByZXRyeWluZyBjYW5ub3QgZml4IGl0LCBzbyB3ZSBmYWlsIGZhc3QuIE5vbi1BbmRyb2lkIHRyYW5zcG9ydHMgcmVzb2x2ZSB0b1xuICAgKiB0aGUgc2FtZSBkZWZhdWx0cyBidXQgbmV2ZXIgZW50ZXIgdGhlIHJldHJ5IHBhdGg6IHRoZWlyIGxvYWQgZWl0aGVyIHN1Y2NlZWRzXG4gICAqIG9uIHRoZSBmaXJzdCBhdHRlbXB0IG9yIHRocm93cyBhIGNhcHR1cmVkIGVycm9yLlxuICAgKi9cbiAgY29uc3QgbWF4QXR0ZW1wdHMgPSAxICsgcmVzb2x2ZVBsdWdpbkVuYWJsZVJldHJ5Q291bnQodHJhbnNwb3J0T3B0aW9ucyk7XG4gIGNvbnN0IGJhc2VEZWxheUluTWlsbGlzZWNvbmRzID0gcmVzb2x2ZVBsdWdpbkVuYWJsZVJldHJ5RGVsYXlJbk1pbGxpc2Vjb25kcyh0cmFuc3BvcnRPcHRpb25zKTtcblxuICBmb3IgKGxldCBhdHRlbXB0ID0gMTsgYXR0ZW1wdCA8PSBtYXhBdHRlbXB0czsgYXR0ZW1wdCsrKSB7XG4gICAgbGV0IHJlc3VsdDogRW5hYmxlUGx1Z2luUmVzdWx0O1xuICAgIHRyeSB7XG4gICAgICByZXN1bHQgPSBhd2FpdCBldmFsSW5PYnNpZGlhbih7XG4gICAgICAgIGNhbGxiYWNrOiBlbmFibGVQbHVnaW5XaXRoRXJyb3JDYXB0dXJlLFxuICAgICAgICBpbnB1dDogeyBwbHVnaW5JZCB9LFxuICAgICAgICBzaG91bGRTa2lwUHJlZmxpZ2h0Q2hlY2tzOiB0cnVlLFxuICAgICAgICB0cmFuc3BvcnQsXG4gICAgICAgIHZhdWx0UGF0aDogdGVtcG9yYXJ5VmF1bHQucGF0aFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8qXG4gICAgICAgKiBUaGUgZXZhbCBpdHNlbGYgdGhyZXcgKGUuZy4gdGhlIFdlYlZpZXcgY29udGV4dCB3YXMgbG9zdCBtaWQtZXhlY3V0aW9uIG9uXG4gICAgICAgKiBhIGNodXJuaW5nIGd1ZXN0KSBcdTIwMTQgYSB0cmFuc3BvcnQtbGV2ZWwgdHJhbnNpZW50LiBSZXRyeSBpZiBhdHRlbXB0cyByZW1haW4uXG4gICAgICAgKi9cbiAgICAgIGlmIChhdHRlbXB0IDwgbWF4QXR0ZW1wdHMpIHtcbiAgICAgICAgY29uc3QgZGVsYXlJbk1pbGxpc2Vjb25kcyA9IGNvbXB1dGVCYWNrb2ZmRGVsYXlJbk1pbGxpc2Vjb25kcyhiYXNlRGVsYXlJbk1pbGxpc2Vjb25kcywgYXR0ZW1wdCAtIDEpO1xuICAgICAgICBsb2coXG4gICAgICAgICAgYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gRW5hYmxlIGF0dGVtcHQgJHtTdHJpbmcoYXR0ZW1wdCl9LyR7U3RyaW5nKG1heEF0dGVtcHRzKX0gdGhyZXcgYFxuICAgICAgICAgICAgKyBgKCR7ZXJyb3JUb1N0cmluZyhlcnJvcil9KTsgcmV0cnlpbmcgaW4gJHtTdHJpbmcoZGVsYXlJbk1pbGxpc2Vjb25kcyl9bXMuLi5gXG4gICAgICAgICk7XG4gICAgICAgIGF3YWl0IHNsZWVwKGRlbGF5SW5NaWxsaXNlY29uZHMpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogYGVycm9yTWVzc2FnZWAgaXMgdGhlIHJlYWwgdGhyb3cgc2VlbiBieSB0aGUgbW9ua2V5LXBhdGNoO1xuICAgICAqIGByZW5kZXJlckNvbnNvbGVFcnJvcnNgIChMYXllciAxKSBpcyB0aGUgcmVhbCBjYXVzZSBjb25zb2xlLWxvZ2dlZCBpbiB0aGUgcmVuZGVyZXIuXG4gICAgICovXG4gICAgY29uc3QgcmVhbEVycm9yID0gcmVzdWx0LmVycm9yTWVzc2FnZSA/PyByZXN1bHQucmVuZGVyZXJDb25zb2xlRXJyb3JzO1xuXG4gICAgaWYgKHJlc3VsdC5pc0xvYWRlZCAmJiAhcmVhbEVycm9yKSB7XG4gICAgICBjb25zdCBhdHRlbXB0U3VmZml4ID0gYXR0ZW1wdCA+IDEgPyBgIChhdHRlbXB0ICR7U3RyaW5nKGF0dGVtcHQpfS8ke1N0cmluZyhtYXhBdHRlbXB0cyl9KWAgOiAnJztcbiAgICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBQbHVnaW4gXCIke3BsdWdpbklkfVwiIGVuYWJsZWQgc3VjY2Vzc2Z1bGx5JHthdHRlbXB0U3VmZml4fS5gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBBIGNhcHR1cmVkIGxvYWQgZXJyb3IgaXMgZGV0ZXJtaW5pc3RpYyBcdTIwMTQgZmFpbCBmYXN0IHJhdGhlciB0aGFuIHJldHJ5LlxuICAgIGlmICghc2hvdWxkUmV0cnlQbHVnaW5FbmFibGUocmVzdWx0KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBQbHVnaW4gXCIke3BsdWdpbklkfVwiIGZhaWxlZCB0byBsb2FkOiAke3JlYWxFcnJvciA/PyBnZXRHZW5lcmljUGx1Z2luTG9hZEZhaWx1cmVNZXNzYWdlKHBsdWdpbklkKX1gKTtcbiAgICB9XG5cbiAgICAvLyBUcmFuc2llbnQgY29sZC1ib290IHJhY2UgKGVuYWJsZWQgYnV0IG5vdCBsb2FkZWQsIG5vIGNhdXNlIGNhcHR1cmVkKTogcmV0cnkuXG4gICAgaWYgKGF0dGVtcHQgPCBtYXhBdHRlbXB0cykge1xuICAgICAgY29uc3QgZGVsYXlJbk1pbGxpc2Vjb25kcyA9IGNvbXB1dGVCYWNrb2ZmRGVsYXlJbk1pbGxpc2Vjb25kcyhiYXNlRGVsYXlJbk1pbGxpc2Vjb25kcywgYXR0ZW1wdCAtIDEpO1xuICAgICAgbG9nKFxuICAgICAgICBgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBQbHVnaW4gXCIke3BsdWdpbklkfVwiIGVuYWJsZWQgYnV0IG5vdCBsb2FkZWQgYFxuICAgICAgICAgICsgYChhdHRlbXB0ICR7U3RyaW5nKGF0dGVtcHQpfS8ke1N0cmluZyhtYXhBdHRlbXB0cyl9KTsgcmV0cnlpbmcgaW4gJHtTdHJpbmcoZGVsYXlJbk1pbGxpc2Vjb25kcyl9bXMuLi5gXG4gICAgICApO1xuICAgICAgYXdhaXQgc2xlZXAoZGVsYXlJbk1pbGxpc2Vjb25kcyk7XG4gICAgfVxuICB9XG5cbiAgLypcbiAgICogRXhoYXVzdGVkIGV2ZXJ5IGF0dGVtcHQgb24gdGhlIHRyYW5zaWVudCBzaWduYXR1cmU6IGNvbXBvc2UgdGhlIG1vc3RcbiAgICogc3BlY2lmaWMgZGV0YWlsIGF2YWlsYWJsZSAoYGFkYiBsb2djYXRgIHRhaWwgb24gQW5kcm9pZCwgZWxzZSB0aGUgZ2VuZXJpY1xuICAgKiBtZXNzYWdlKSBcdTIwMTQgdW5jaGFuZ2VkIGZyb20gdGhlIHByZS1yZXRyeSBzaW5nbGUtc2hvdCBmYWlsdXJlLlxuICAgKi9cbiAgY29uc3QgbG9nY2F0VGFpbCA9IGF3YWl0IHRyYW5zcG9ydC5yZWFkQ29uc29sZUNhcHR1cmVTaW5jZT8uKGNhcHR1cmVIYW5kbGUpO1xuICBjb25zdCBkZXRhaWwgPSBsb2djYXRUYWlsID8/IGdldEdlbmVyaWNQbHVnaW5Mb2FkRmFpbHVyZU1lc3NhZ2UocGx1Z2luSWQpO1xuICB0aHJvdyBuZXcgRXJyb3IoYFBsdWdpbiBcIiR7cGx1Z2luSWR9XCIgZmFpbGVkIHRvIGxvYWQ6ICR7ZGV0YWlsfWApO1xufVxuXG4vKipcbiAqIEVuYWJsZXMgYGFsd2F5c1VwZGF0ZUxpbmtzYCBpbiB0aGUgb3duZWQgdmF1bHQncyBgLm9ic2lkaWFuL2FwcC5qc29uYC5cbiAqXG4gKiBXaXRob3V0IGl0LCBhbnkgcmVuYW1lIG9yIG1vdmUgdGhhdCBhZmZlY3RzIGxpbmtzIG1ha2VzIE9ic2lkaWFuJ3NcbiAqIGBGaWxlTWFuYWdlci51cGRhdGVBbGxMaW5rc2AgcG9wIGFuIGludGVyYWN0aXZlIFwiVXBkYXRlIGxpbmtzP1wiIGNvbmZpcm1hdGlvbiBtb2RhbFxuICogKGl0IG9ubHkgc2tpcHMgdGhlIG1vZGFsIHdoZW4gYGFsd2F5c1VwZGF0ZUxpbmtzYCBpcyBvbikuIEhlYWRsZXNzIHRoZXJlIGlzIG5vIHVzZXJcbiAqIHRvIGFuc3dlciBpdCwgc28gdGhlIFByb21pc2UgbmV2ZXIgcmVzb2x2ZXMgXHUyMDE0IHRoZSByZW5hbWUncyBpbnRlcm5hbFxuICogYEZpbGVNYW5hZ2VyLnVwZGF0ZVF1ZXVlYCB0YXNrIGhhbmdzIGZvcmV2ZXIsIGFuZCBiZWNhdXNlIHRoYXQgcXVldWUgaXMgYSBzaW5nbGV0b25cbiAqIGV2ZXJ5IHN1YnNlcXVlbnQgYHJlbmFtZUZpbGVgIGluIHRoZSBzaGFyZWQgaW5zdGFuY2UgaGFuZ3MgdG9vICh0aGUgbG9uZy1vYnNlcnZlZFxuICogXCJyZW5hbWUgd2FsbFwiKS4gRW5hYmxpbmcgdGhlIHNldHRpbmcgbWFrZXMgcmVuYW1lcyB1cGRhdGUgbGlua3Mgbm9uLWludGVyYWN0aXZlbHksXG4gKiBzbyByZW5hbWUtZHJpdmVuIGludGVncmF0aW9uIHRlc3RzIHJ1biBpbiBoZWFkbGVzcyBtb2RlLlxuICpcbiAqIE1lcmdlcyBpbnRvIGFueSBleGlzdGluZyBgYXBwLmpzb25gIChlLmcuIG9uZSBjYXJyaWVkIGluIHZpYSBgcG9wdWxhdGVgKSBzbyBvdGhlclxuICogY29uZmlnIGtleXMgYXJlIHByZXNlcnZlZCwgYW5kIHJ1bnMgYmVmb3JlIGBzeW5jVG9EZXZpY2VgIHNvIHRoZSB2YWx1ZSByZWFjaGVzXG4gKiBtb2JpbGUgZGV2aWNlcyB0b28uXG4gKlxuICogQHBhcmFtIHRlbXBvcmFyeVZhdWx0IC0gVGhlIG93bmVkIHRlbXAgdmF1bHQgdG8gY29uZmlndXJlLlxuICogQHBhcmFtIGxhYmVsIC0gVGhlIHRyYW5zcG9ydCBsYWJlbCwgZm9yIGxvZ2dpbmcuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGVuc3VyZUFsd2F5c1VwZGF0ZUxpbmtzKHRlbXBvcmFyeVZhdWx0OiBUZW1wb3JhcnlWYXVsdCwgbGFiZWw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBjb25maWdEaXJlY3RvcnkgPSBqb2luKHRlbXBvcmFyeVZhdWx0LnBhdGgsIE9CU0lESUFOX0NPTkZJR19ESVIpO1xuICBjb25zdCBhcHBKc29uUGF0aCA9IGpvaW4oY29uZmlnRGlyZWN0b3J5LCBBUFBfSlNPTik7XG4gIGxldCBhcHBDb25maWc6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG4gIHRyeSB7XG4gICAgYXBwQ29uZmlnID0gSlNPTi5wYXJzZShhd2FpdCByZWFkRmlsZShhcHBKc29uUGF0aCwgJ3V0Zi04JykpIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICB9IGNhdGNoIHtcbiAgICAvLyBObyBleGlzdGluZyBhcHAuanNvbiAob3IgdW5yZWFkYWJsZSkgXHUyMDE0IHN0YXJ0IGZyb20gYW4gZW1wdHkgY29uZmlnLlxuICB9XG4gIGFwcENvbmZpZ1snYWx3YXlzVXBkYXRlTGlua3MnXSA9IHRydWU7XG4gIGF3YWl0IG1rZGlyKGNvbmZpZ0RpcmVjdG9yeSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIGF3YWl0IHdyaXRlRmlsZShhcHBKc29uUGF0aCwgSlNPTi5zdHJpbmdpZnkoYXBwQ29uZmlnLCBudWxsLCBBUFBfSlNPTl9JTkRFTlQpKTtcbiAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIEVuYWJsZWQgYWx3YXlzVXBkYXRlTGlua3MgaW4gJHtBUFBfSlNPTn0gKGhlYWRsZXNzIHJlbmFtZSBzdXBwb3J0KS5gKTtcbn1cblxuLyoqXG4gKiBGaW5kcyB0aGUgcHJvamVjdCByb290IGJ5IHdhbGtpbmcgdXAgZnJvbSBgcHJvY2Vzcy5jd2QoKWAgbG9va2luZyBmb3IgYHBhY2thZ2UuanNvbmAuXG4gKlxuICogQHJldHVybnMgVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHByb2plY3Qgcm9vdC5cbiAqL1xuZnVuY3Rpb24gZmluZFByb2plY3RSb290KCk6IHN0cmluZyB7XG4gIGxldCBkaXJlY3RvcnkgPSBwcm9jZXNzLmN3ZCgpO1xuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5uZWNlc3NhcnktY29uZGl0aW9uIC0tIExvb3AgdGVybWluYXRlcyBhdCBmaWxlc3lzdGVtIHJvb3QuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgaWYgKGV4aXN0c1N5bmMoam9pbihkaXJlY3RvcnksICdwYWNrYWdlLmpzb24nKSkpIHtcbiAgICAgIHJldHVybiBkaXJlY3Rvcnk7XG4gICAgfVxuICAgIGNvbnN0IHBhcmVudCA9IGpvaW4oZGlyZWN0b3J5LCAnLi4nKTtcbiAgICBpZiAocGFyZW50ID09PSBkaXJlY3RvcnkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGZpbmQgcHJvamVjdCByb290IChubyBwYWNrYWdlLmpzb24gZm91bmQpLicpO1xuICAgIH1cbiAgICBkaXJlY3RvcnkgPSBwYXJlbnQ7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXNvbHZlcyB0aGUgY3Jvc3MtcHJvY2VzcyBsb2NrIHNjb3BlIGZvciBhIHRyYW5zcG9ydCwgb3IgYHVuZGVmaW5lZGAgd2hlbiBub1xuICogbG9jayBpcyBuZWVkZWQuXG4gKlxuICogRGVza3RvcCBydW5zIHVzZSBoYXJuZXNzLW93bmVkLCBpc29sYXRlZCBpbnN0YW5jZXMgKHRoZWlyIG93biB1c2VyLWRhdGEgZGlyXG4gKiBhbmQgQ0RQIHBvcnQpLCBzbyB0aGV5IG5vIGxvbmdlciBjb250ZW5kIGFuZCBuZWVkIG5vIGxvY2suIE9ubHkgdGhlIEFuZHJvaWRcbiAqIHRyYW5zcG9ydCwgd2hpY2ggc2hhcmVzIHRoZSBzaW5nbGUgZW11bGF0b3IgYW5kIEFwcGl1bSBzZXJ2ZXIsIG11c3Qgc2VyaWFsaXplLlxuICpcbiAqIEBwYXJhbSB0cmFuc3BvcnRPcHRpb25zIC0gVGhlIHJlc29sdmVkIHRyYW5zcG9ydCBvcHRpb25zLlxuICogQHJldHVybnMgVGhlIGxvY2sgc2NvcGUgc3RyaW5nLCBvciBgdW5kZWZpbmVkYCBpZiBubyBsb2NrIGlzIG5lZWRlZC5cbiAqL1xuZnVuY3Rpb24gZ2V0TG9ja1Njb3BlKHRyYW5zcG9ydE9wdGlvbnM6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiB0cmFuc3BvcnRPcHRpb25zPy50eXBlID09PSAnb2JzaWRpYW4tYW5kcm9pZC1hcHBpdW0nID8gQU5EUk9JRF9MT0NLX1NDT1BFIDogdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyBjbGVhbnVwIGhhbmRsZXJzIGZvciBvcnBoYW5lZCBzZXR1cHMgdGhhdCB3ZXJlIG5ldmVyIGV4cGxpY2l0bHlcbiAqIHRvcm4gZG93bi5cbiAqXG4gKiBUd28gaGFuZGxlcnMgY292ZXIgZGlmZmVyZW50IGV4aXQgc2NlbmFyaW9zOlxuICpcbiAqIC0gYGJlZm9yZUV4aXRgIFx1MjAxNCBmaXJlcyB3aGVuIHRoZSBldmVudCBsb29wIGRyYWlucyBuYXR1cmFsbHkuIEFsbG93cyBmdWxsXG4gKiAgIGFzeW5jIHRlYXJkb3duICh1bnJlZ2lzdGVyIHZhdWx0cywgZGlzcG9zZSB0cmFuc3BvcnRzKS4gRG9lcyBOT1QgZmlyZVxuICogICB3aGVuIGBwcm9jZXNzLmV4aXQoKWAgaXMgY2FsbGVkIGRpcmVjdGx5LlxuICpcbiAqIC0gYHVuaGFuZGxlZFJlamVjdGlvbmAgXHUyMDE0IGNhdGNoZXMgYXN5bmMgZXJyb3JzIHRoYXQgYnlwYXNzIGBjb3JlU2V0dXBgJ3NcbiAqICAgY2F0Y2ggYmxvY2suIFBlcmZvcm1zIGZ1bGwgYXN5bmMgdGVhcmRvd24gd2hpbGUgd2Ugc3RpbGwgY2FuLlxuICpcbiAqIC0gYGV4aXRgIFx1MjAxNCBmaXJlcyBvbiBldmVyeSBleGl0LCBpbmNsdWRpbmcgYHByb2Nlc3MuZXhpdCgpYC4gT25seSBzeW5jaHJvbm91c1xuICogICB3b3JrIGlzIHBvc3NpYmxlLCBzbyB0aGlzIGhhbmRsZXIgZG9lcyBiZXN0LWVmZm9ydCBjbGVhbnVwOiBraWxscyBjaGlsZFxuICogICBwcm9jZXNzZXMgdmlhIGBkaXNwb3NlU3luYygpYCBhbmQgcmVtb3ZlcyB0ZW1wIHZhdWx0IGRpcmVjdG9yaWVzIHdpdGhcbiAqICAgYHJtU3luY2AuIFVucmVnaXN0ZXJpbmcgdmF1bHRzICh3aGljaCByZXF1aXJlcyBJUEMgd2l0aCBPYnNpZGlhbikgaXNcbiAqICAgc2tpcHBlZCBcdTIwMTQgYSBzdGFsZSB2YXVsdCBlbnRyeSBpcyBhbiBhY2NlcHRhYmxlIHRyYWRlLW9mZiB2cy4gbGVha2VkXG4gKiAgIHByb2Nlc3NlcyBhbmQgdGVtcCBkaXJlY3Rvcmllcy5cbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJQcm9jZXNzQ2xlYW51cEhhbmRsZXIoKTogdm9pZCB7XG4gIGlmIChpc0NsZWFudXBIYW5kbGVyUmVnaXN0ZXJlZCkge1xuICAgIHJldHVybjtcbiAgfVxuICBpc0NsZWFudXBIYW5kbGVyUmVnaXN0ZXJlZCA9IHRydWU7XG5cbiAgcHJvY2Vzcy5vbignYmVmb3JlRXhpdCcsICgpID0+IHtcbiAgICBpZiAoYWN0aXZlU2V0dXBzLnNpemUgPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bl0gUHJvY2VzcyBleGl0aW5nIHdpdGggJHtTdHJpbmcoYWN0aXZlU2V0dXBzLnNpemUpfSBzZXR1cChzKSBub3QgdG9ybiBkb3duLiBDbGVhbmluZyB1cC4uLmApO1xuXG4gICAgZm9yIChjb25zdCByZXN1bHQgb2YgYWN0aXZlU2V0dXBzKSB7XG4gICAgICBjb3JlVGVhcmRvd24ocmVzdWx0KS5jYXRjaCgoZXJyb3I6IHVua25vd24pID0+IHtcbiAgICAgICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd246JHtyZXN1bHQudHJhbnNwb3J0TGFiZWx9XSBQcm9jZXNzIGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIHByb2Nlc3Mub24oJ3VuaGFuZGxlZFJlamVjdGlvbicsICgpID0+IHtcbiAgICBpZiAoYWN0aXZlU2V0dXBzLnNpemUgPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bl0gVW5oYW5kbGVkIHJlamVjdGlvbiBkZXRlY3RlZC4gVGVhcmluZyBkb3duICR7U3RyaW5nKGFjdGl2ZVNldHVwcy5zaXplKX0gYWN0aXZlIHNldHVwKHMpLi4uYCk7XG4gICAgZm9yIChjb25zdCByZXN1bHQgb2YgYWN0aXZlU2V0dXBzKSB7XG4gICAgICBjb3JlVGVhcmRvd24ocmVzdWx0KS5jYXRjaCgoZXJyb3I6IHVua25vd24pID0+IHtcbiAgICAgICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd246JHtyZXN1bHQudHJhbnNwb3J0TGFiZWx9XSBSZWplY3Rpb24gY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcHJvY2Vzcy5vbignZXhpdCcsICgpID0+IHtcbiAgICBpZiAoYWN0aXZlU2V0dXBzLnNpemUgPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bl0gU3luYyBjbGVhbnVwOiAke1N0cmluZyhhY3RpdmVTZXR1cHMuc2l6ZSl9IG9ycGhhbmVkIHNldHVwKHMpLmApO1xuICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIGFjdGl2ZVNldHVwcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmVzdWx0LnRyYW5zcG9ydC5kaXNwb3NlU3luYz8uKCk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bjoke3Jlc3VsdC50cmFuc3BvcnRMYWJlbH1dIFN5bmMgdHJhbnNwb3J0IGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICBybVN5bmMocmVzdWx0LnRlbXBvcmFyeVZhdWx0LnBhdGgsIHsgZm9yY2U6IHRydWUsIHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gU3luYyB2YXVsdCBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICAgcmVsZWFzZVNldHVwTG9jayhyZXN1bHQpO1xuICAgIH1cbiAgICBhY3RpdmVTZXR1cHMuY2xlYXIoKTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmVsZWFzZXMgYW5kIGZvcmdldHMgdGhlIHNldHVwIGxvY2sgYXNzb2NpYXRlZCB3aXRoIGEgcmVzdWx0LCBpZiBhbnkuXG4gKlxuICogQHBhcmFtIHJlc3VsdCAtIFRoZSBzZXR1cCByZXN1bHQgd2hvc2UgbG9jayBzaG91bGQgYmUgcmVsZWFzZWQuXG4gKi9cbmZ1bmN0aW9uIHJlbGVhc2VTZXR1cExvY2socmVzdWx0OiBDb3JlU2V0dXBSZXN1bHQpOiB2b2lkIHtcbiAgY29uc3QgbG9jayA9IHNldHVwTG9ja3MuZ2V0KHJlc3VsdCk7XG4gIGlmIChsb2NrKSB7XG4gICAgbG9jay5yZWxlYXNlKCk7XG4gICAgc2V0dXBMb2Nrcy5kZWxldGUocmVzdWx0KTtcbiAgfVxufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBkaXN0IHBhdGggdG8gdXNlIGZvciBpbnRlZ3JhdGlvbiB0ZXN0cy5cbiAqXG4gKiBQaWNrcyB3aGljaGV2ZXIgb2YgYGRpc3QvZGV2YCBhbmQgYGRpc3QvYnVpbGRgIGhhcyBhIG5ld2VyIGBtYWluLmpzYC5cbiAqIElmIG9ubHkgb25lIGV4aXN0cywgdGhhdCBvbmUgaXMgdXNlZC4gVGhyb3dzIGlmIG5laXRoZXIgZXhpc3RzLlxuICpcbiAqIEBwYXJhbSBwcm9qZWN0Um9vdCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSBwcm9qZWN0IHJvb3QuXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgY2hvc2VuIGRpc3QgZm9sZGVyLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlRGlzdFBhdGgocHJvamVjdFJvb3Q6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGRldlBhdGggPSBqb2luKHByb2plY3RSb290LCBESVNUX0RFVik7XG4gIGNvbnN0IGJ1aWxkUGF0aCA9IGpvaW4ocHJvamVjdFJvb3QsIERJU1RfQlVJTEQpO1xuICBjb25zdCBkZXZNYWluSnMgPSBqb2luKGRldlBhdGgsIE1BSU5fSlMpO1xuICBjb25zdCBidWlsZE1haW5KcyA9IGpvaW4oYnVpbGRQYXRoLCBNQUlOX0pTKTtcbiAgY29uc3QgZGV2U3RhdCA9IGV4aXN0c1N5bmMoZGV2TWFpbkpzKSA/IGF3YWl0IHN0YXQoZGV2TWFpbkpzKSA6IG51bGw7XG4gIGNvbnN0IGJ1aWxkU3RhdCA9IGV4aXN0c1N5bmMoYnVpbGRNYWluSnMpID8gYXdhaXQgc3RhdChidWlsZE1haW5KcykgOiBudWxsO1xuXG4gIGlmIChkZXZTdGF0ICYmIGJ1aWxkU3RhdCkge1xuICAgIHJldHVybiBkZXZTdGF0Lm10aW1lID4gYnVpbGRTdGF0Lm10aW1lID8gZGV2UGF0aCA6IGJ1aWxkUGF0aDtcbiAgfVxuXG4gIGlmIChkZXZTdGF0KSB7XG4gICAgcmV0dXJuIGRldlBhdGg7XG4gIH1cblxuICBpZiAoYnVpbGRTdGF0KSB7XG4gICAgcmV0dXJuIGJ1aWxkUGF0aDtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignTm8gYnVpbGQgZm91bmQuIFJ1biBgbnBtIHJ1biBidWlsZGAgb3IgYG5wbSBydW4gZGV2YCBmaXJzdC4nKTtcbn1cblxuLyoqXG4gKiBSZWZ1c2VzIGEgbW9iaWxlIHJ1biBmb3IgYSBkZXNrdG9wLW9ubHkgcGx1Z2luLCBiZWZvcmUgYW55dGhpbmcgY29zdGx5IGhhcyBoYXBwZW5lZC5cbiAqXG4gKiBBIG5vLW9wIHVubGVzcyBhIHBsdWdpbiBpcyBiZWluZyBpbnN0YWxsZWQgb250byBhIG1vYmlsZSB0cmFuc3BvcnQuIE90aGVyd2lzZSByZWFkcyBgbWFuaWZlc3QuanNvbmBcbiAqIG91dCBvZiB0aGUgbmV3ZXIgZGlzdCBmb2xkZXIgXHUyMDE0IG5vIGRldmljZSwgbm8gbG9jaywgbm8gc3dlZXAuIFdoZW4gdGhlcmUgaXMgbm8gcmVhZGFibGUgYnVpbGQgdGhlIGNoZWNrXG4gKiBzaW1wbHkgZG9lcyBub3QgZmlyZTogYSBtaXNzaW5nIG9yIG1hbGZvcm1lZCBidWlsZCBpcyBhIGRpZmZlcmVudCBwcm9ibGVtLCBhbmQge0BsaW5rIHJlc29sdmVEaXN0UGF0aH1cbiAqIGRvd25zdHJlYW0gYWxyZWFkeSByZXBvcnRzIGl0IGluIGl0cyBvd24gd29yZHMuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSB0cmFuc3BvcnQgbGFiZWwsIHByb2plY3Qgcm9vdCwgdHJhbnNwb3J0IG9wdGlvbnMgYW5kIHdoZXRoZXIgYSBwbHVnaW4gaXMgaW5zdGFsbGVkLlxuICogQHRocm93cyB7RGVza3RvcE9ubHlQbHVnaW5Ta2lwRXJyb3J9IFdoZW4gdGhlIG1hbmlmZXN0IHNheXMgYGlzRGVza3RvcE9ubHk6IHRydWVgLlxuICovXG5hc3luYyBmdW5jdGlvbiBza2lwSWZEZXNrdG9wT25seShwYXJhbXM6IFNraXBJZkRlc2t0b3BPbmx5UGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgbGFiZWwsIHByb2plY3RSb290LCBzaG91bGRJbnN0YWxsUGx1Z2luLCB0cmFuc3BvcnRPcHRpb25zIH0gPSBwYXJhbXM7XG5cbiAgaWYgKCFzaG91bGRJbnN0YWxsUGx1Z2luIHx8ICFjaGVja0lzTW9iaWxlVHJhbnNwb3J0KHRyYW5zcG9ydE9wdGlvbnMpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbGV0IG1hbmlmZXN0SnNvbjogUGx1Z2luTWFuaWZlc3Q7XG4gIHRyeSB7XG4gICAgY29uc3QgZGlzdFBhdGggPSBhd2FpdCByZXNvbHZlRGlzdFBhdGgocHJvamVjdFJvb3QpO1xuICAgIG1hbmlmZXN0SnNvbiA9IEpTT04ucGFyc2UoYXdhaXQgcmVhZEZpbGUoam9pbihkaXN0UGF0aCwgJ21hbmlmZXN0Lmpzb24nKSwgJ3V0Zi04JykpIGFzIFBsdWdpbk1hbmlmZXN0O1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoIW1hbmlmZXN0SnNvbi5pc0Rlc2t0b3BPbmx5KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbG9nKFxuICAgIGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFNLSVBQRUQ6IFwiJHttYW5pZmVzdEpzb24uaWR9XCIgaXMgZGVza3RvcC1vbmx5IChpc0Rlc2t0b3BPbmx5OiB0cnVlKSwgYFxuICAgICAgKyAnc28gaXQgaGFzIG5vIG1vYmlsZSBpbnRlZ3JhdGlvbiB0ZXN0cyB0byBydW4uIE5vIGVtdWxhdG9yIHdhcyBib290ZWQgYW5kIG5vIEFwcGl1bSBzZXJ2ZXIgd2FzIHN0YXJ0ZWQuJ1xuICApO1xuICB0aHJvdyBuZXcgRGVza3RvcE9ubHlQbHVnaW5Ta2lwRXJyb3IobWFuaWZlc3RKc29uLmlkKTtcbn1cblxuLyoqXG4gKiBSZW1vdmVzIHRoZSBob3N0LXNpZGUgdGVtcCBkaXJlY3RvcmllcyBlYXJsaWVyIHJ1bnMgbGVha2VkLlxuICpcbiAqIFJ1bnMgYXQgYm90aCBlbmRzIG9mIGEgcnVuOiBhdCBzZXR1cCBpdCBoYXBwZW5zICoqYmVmb3JlKiogdGhlIHRyYW5zcG9ydCBpc1xuICogY3JlYXRlZCwgc28gaXQgZG9lcyBub3QgZGVwZW5kIG9uIGEgaGVhbHRoeSBPYnNpZGlhbi9XZWJWaWV3IFx1MjAxNCB3aGljaCBpc1xuICogZXhhY3RseSB3aGF0IGEgZmFpbGVkIHJ1biBubyBsb25nZXIgaGFzLCBhbmQgd2h5IGEgZmFpbGVkIHJ1biBjYW5ub3QgY2xlYW4gdXBcbiAqIGFmdGVyIGl0c2VsZi4gQWdlLWdhdGVkIChzZWUgYGxlZnRvdmVyTWF4QWdlSW5NaWxsaXNlY29uZHNgKSBiZWNhdXNlIGRlc2t0b3BcbiAqIHJ1bnMgYXJlIG5vdCBzZXJpYWxpemVkIGFuZCBldmVyeSBwcm9qZWN0IG9uIHRoZSBtYWNoaW5lIHNoYXJlcyBvbmUgdGVtcFxuICogZGlyZWN0b3J5LiBCZXN0LWVmZm9ydDogYSBzd2VlcCBuZXZlciBmYWlscyB0aGUgcnVuIGl0IGlzIGNsZWFuaW5nIHVwIGZvci5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHN3ZWVwIHBhcmFtZXRlcnMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHN3ZWVwTGVmdG92ZXJzKHBhcmFtczogU3dlZXBMZWZ0b3ZlcnNQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBsYWJlbCwgcGhhc2UsIHRyYW5zcG9ydE9wdGlvbnMgfSA9IHBhcmFtcztcbiAgaWYgKCF3aWxsU3dlZXBMZWZ0b3ZlcnModHJhbnNwb3J0T3B0aW9ucykpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0cnkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN3ZWVwSG9zdExlZnRvdmVycyh7XG4gICAgICBleGNsdWRlZE5hbWVzOiBwYXJhbXMuZXhjbHVkZWROYW1lcyxcbiAgICAgIG1heEFnZUluTWlsbGlzZWNvbmRzOiByZXNvbHZlTGVmdG92ZXJNYXhBZ2VJbk1pbGxpc2Vjb25kcyh0cmFuc3BvcnRPcHRpb25zKVxuICAgIH0pO1xuICAgIGlmIChyZXN1bHQucmVtb3ZlZENvdW50ID4gMCB8fCByZXN1bHQuZmFpbGVkQ291bnQgPiAwKSB7XG4gICAgICBsb2coXG4gICAgICAgIGBbaW50ZWdyYXRpb24tJHtwaGFzZX06JHtsYWJlbH1dIFN3ZXB0ICR7U3RyaW5nKHJlc3VsdC5yZW1vdmVkQ291bnQpfSBsZWZ0b3ZlciB0ZW1wIGRpcmVjdG9yKGllcykgYFxuICAgICAgICAgICsgYGZyb20gZWFybGllciBydW5zICgke1N0cmluZyhyZXN1bHQuZmFpbGVkQ291bnQpfSBzdGlsbCBpbiB1c2UpLmBcbiAgICAgICk7XG4gICAgfVxuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLSR7cGhhc2V9OiR7bGFiZWx9XSBMZWZ0b3ZlciBzd2VlcCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgfVxufVxuXG4vKipcbiAqIFBlcmZvcm1zIHRoZSBhc3luYyB0ZWFyZG93biB3b3JrICh2YXVsdCBkaXNwb3NhbCArIHRyYW5zcG9ydCBkaXNwb3NhbCkuXG4gKlxuICogQHBhcmFtIHJlc3VsdCAtIFRoZSBzZXR1cCByZXN1bHQgdG8gdGVhciBkb3duLlxuICovXG5hc3luYyBmdW5jdGlvbiB0ZWFyZG93bkFzeW5jKHJlc3VsdDogQ29yZVNldHVwUmVzdWx0KTogUHJvbWlzZTx2b2lkPiB7XG4gIHRyeSB7XG4gICAgYXdhaXQgcmVzdWx0LnRlbXBvcmFyeVZhdWx0LmRpc3Bvc2UocmVzdWx0LnRyYW5zcG9ydCk7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd246JHtyZXN1bHQudHJhbnNwb3J0TGFiZWx9XSBWYXVsdCBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBhd2FpdCByZXN1bHQudHJhbnNwb3J0LmRpc3Bvc2U/LigpO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gVHJhbnNwb3J0IGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhlcnJvcil9YCk7XG4gIH1cbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQVlBLHFCQUdPO0FBQ1Asc0JBTU87QUFDUCx1QkFHTztBQUNQLDBCQUFxQztBQUNyQyxJQUFBQSxtQkFBb0M7QUFRcEMsNENBQTJDO0FBQzNDLDJCQUdPO0FBQ1AsNkJBQThCO0FBQzlCLDhCQUErQjtBQUMvQiw4QkFJTztBQUNQLGlCQUFvQjtBQUNwQixpQ0FLTztBQUNQLHdCQUFpQztBQUNqQyw2QkFBK0I7QUFDL0IsOEJBQWdDO0FBQ2hDLG1DQUFvQztBQUNwQywrQkFBMkM7QUFDM0MsK0JBQXVDO0FBRXZDLE1BQU0seUJBQXlCO0FBQy9CLE1BQU0sV0FBVztBQUNqQixNQUFNLGFBQWE7QUFDbkIsTUFBTSxVQUFVO0FBQ2hCLE1BQU0sc0JBQXNCO0FBQzVCLE1BQU0sY0FBYztBQUNwQixNQUFNLHlCQUF5QjtBQUMvQixNQUFNLFdBQVc7QUFDakIsTUFBTSxrQkFBa0I7QUFReEIsTUFBTSxlQUFlLG9CQUFJLElBQXFCO0FBQzlDLE1BQU0sa0JBQWtCLG9CQUFJLFFBQXlCO0FBQ3JELElBQUksNkJBQTZCO0FBT2pDLE1BQU0sYUFBYSxvQkFBSSxJQUFnQztBQUV2RCxNQUFNLHFCQUFxQjtBQXNOM0IsZUFBc0IsVUFBVSxRQUFvRDtB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
436
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2dsb2JhbC1zZXR1cC1jb3JlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogRnJhbWV3b3JrLWFnbm9zdGljIGNvcmUgbG9naWMgZm9yIGludGVncmF0aW9uIHRlc3QgZ2xvYmFsIHNldHVwIGFuZCB0ZWFyZG93bi5cbiAqXG4gKiBWaXRlc3QgYW5kIEplc3QgYWRhcHRlcnMgZGVsZWdhdGUgdG8gdGhlc2UgZnVuY3Rpb25zLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIHNldHVwIGNvdmVyZWQgYnkgaW50ZWdyYXRpb24gdGVzdHMsIG5vdCB1bml0IHRlc3RzLiAqL1xuXG5pbXBvcnQgdHlwZSB7IFBsdWdpbk1hbmlmZXN0IH0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQge1xuICBleGlzdHNTeW5jLFxuICBybVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICByZWFkRmlsZSxcbiAgc3RhdFxufSBmcm9tICdub2RlOmZzL3Byb21pc2VzJztcbmltcG9ydCB7XG4gIGJhc2VuYW1lLFxuICBqb2luXG59IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgcHJvY2VzcywgeyBsb2FkRW52RmlsZSB9IGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5pbXBvcnQgeyBzZXRUaW1lb3V0IGFzIHNsZWVwIH0gZnJvbSAnbm9kZTp0aW1lcnMvcHJvbWlzZXMnO1xuXG5pbXBvcnQgdHlwZSB7IEVuYWJsZVBsdWdpblJlc3VsdCB9IGZyb20gJy4vZW5hYmxlLXBsdWdpbi5janMnO1xuaW1wb3J0IHR5cGUgeyBTZXR1cExvY2sgfSBmcm9tICcuL3NldHVwLWxvY2suY2pzJztcbmltcG9ydCB0eXBlIHsgUG9wdWxhdGVGaWxlc1BhcmFtcyB9IGZyb20gJy4vdGVtcG9yYXJ5LXZhdWx0LmNqcyc7XG5pbXBvcnQgdHlwZSB7IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB9IGZyb20gJy4vdHJhbnNwb3J0LW9wdGlvbnMuY2pzJztcbmltcG9ydCB0eXBlIHsgT2JzaWRpYW5UcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydC5janMnO1xuXG5pbXBvcnQgeyBERUZBVUxUX0NPTkZJR19ESVJFQ1RPUlkgfSBmcm9tICcuL2NvbmZpZy1kaXJlY3RvcnkuY2pzJztcbmltcG9ydCB7IERlc2t0b3BPbmx5UGx1Z2luU2tpcEVycm9yIH0gZnJvbSAnLi9kZXNrdG9wLW9ubHktcGx1Z2luLXNraXAtZXJyb3IuY2pzJztcbmltcG9ydCB7XG4gIGVuYWJsZVBsdWdpbldpdGhFcnJvckNhcHR1cmUsXG4gIGdldEdlbmVyaWNQbHVnaW5Mb2FkRmFpbHVyZU1lc3NhZ2Vcbn0gZnJvbSAnLi9lbmFibGUtcGx1Z2luLmNqcyc7XG5pbXBvcnQgeyBlcnJvclRvU3RyaW5nIH0gZnJvbSAnLi9lcnJvci10by1zdHJpbmcuY2pzJztcbmltcG9ydCB7IGV2YWxJbk9ic2lkaWFuIH0gZnJvbSAnLi9ldmFsLWluLW9ic2lkaWFuLmNqcyc7XG5pbXBvcnQgeyBlbnN1cmVIZWFkbGVzc1ZhdWx0Q29uZmlnIH0gZnJvbSAnLi9oZWFkbGVzcy12YXVsdC1jb25maWcuY2pzJztcbmltcG9ydCB7XG4gIHJlc29sdmVMZWZ0b3Zlck1heEFnZUluTWlsbGlzZWNvbmRzLFxuICBzd2VlcEhvc3RMZWZ0b3ZlcnMsXG4gIHdpbGxTd2VlcExlZnRvdmVyc1xufSBmcm9tICcuL2xlZnRvdmVyLWNsZWFudXAuY2pzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLmNqcyc7XG5pbXBvcnQge1xuICBjb21wdXRlQmFja29mZkRlbGF5SW5NaWxsaXNlY29uZHMsXG4gIHJlc29sdmVQbHVnaW5FbmFibGVSZXRyeUNvdW50LFxuICByZXNvbHZlUGx1Z2luRW5hYmxlUmV0cnlEZWxheUluTWlsbGlzZWNvbmRzLFxuICBzaG91bGRSZXRyeVBsdWdpbkVuYWJsZVxufSBmcm9tICcuL3BsdWdpbi1lbmFibGUtcmV0cnkuY2pzJztcbmltcG9ydCB7IGFjcXVpcmVTZXR1cExvY2sgfSBmcm9tICcuL3NldHVwLWxvY2suY2pzJztcbmltcG9ydCB7IFRlbXBvcmFyeVZhdWx0IH0gZnJvbSAnLi90ZW1wb3JhcnktdmF1bHQuY2pzJztcbmltcG9ydCB7IEFwcGl1bVRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWFwcGl1bS5janMnO1xuaW1wb3J0IHsgRGVza3RvcENkcFRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWRlc2t0b3AtY2RwLmNqcyc7XG5pbXBvcnQgeyBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9ucyB9IGZyb20gJy4vdHJhbnNwb3J0LWZhY3RvcnkuY2pzJztcbmltcG9ydCB7XG4gIGNoZWNrSXNNb2JpbGVUcmFuc3BvcnQsXG4gIHJlc29sdmVPd25lZENvbmZpZ0RpcmVjdG9yeVxufSBmcm9tICcuL3RyYW5zcG9ydC1vcHRpb25zLmNqcyc7XG5pbXBvcnQgeyBpbnN0YWxsUGx1Z2luSW50b1ZhdWx0IH0gZnJvbSAnLi92YXVsdC1wbHVnaW4taW5zdGFsbC5janMnO1xuXG5jb25zdCBERUZBVUxUX1RSQU5TUE9SVF9UWVBFID0gJ29ic2lkaWFuLWNkcCc7XG5jb25zdCBESVNUX0RFViA9ICdkaXN0L2Rldic7XG5jb25zdCBESVNUX0JVSUxEID0gJ2Rpc3QvYnVpbGQnO1xuY29uc3QgTUFJTl9KUyA9ICdtYWluLmpzJztcblxuLyoqXG4gKiBUcmFja3Mgc2V0dXBzIHRoYXQgY29tcGxldGVkIHN1Y2Nlc3NmdWxseSBidXQgaGF2ZW4ndCBiZWVuIHRvcm4gZG93biB5ZXQuXG4gKiBVc2VkIGJ5IHRoZSBgYmVmb3JlRXhpdGAgaGFuZGxlciB0byBjbGVhbiB1cCB3aGVuIGEgdGVzdCBydW5uZXIgZXhpdHNcbiAqIHdpdGhvdXQgY2FsbGluZyB0ZWFyZG93biAoZS5nLiwgd2hlbiBvbmUgcHJvamVjdCdzIHNldHVwIGZhaWxzIGFuZCB0aGVcbiAqIHJ1bm5lciBhYm9ydHMgYmVmb3JlIHRlYXJpbmcgZG93biBhbHJlYWR5LWluaXRpYWxpemVkIHByb2plY3RzKS5cbiAqL1xuY29uc3QgYWN0aXZlU2V0dXBzID0gbmV3IFNldDxDb3JlU2V0dXBSZXN1bHQ+KCk7XG5jb25zdCBkaXNwb3NlZFJlc3VsdHMgPSBuZXcgV2Vha1NldDxDb3JlU2V0dXBSZXN1bHQ+KCk7XG5sZXQgaXNDbGVhbnVwSGFuZGxlclJlZ2lzdGVyZWQgPSBmYWxzZTtcblxuLyoqXG4gKiBUaGUgY3Jvc3MtcHJvY2VzcyBzZXR1cCBsb2NrIGhlbGQgYnkgZWFjaCBhY3RpdmUgc2V0dXAuIFJlbGVhc2VkIHdoZW4gdGhlXG4gKiBzZXR1cCBpcyB0b3JuIGRvd24gKG9yIGJ5IHRoZSBwcm9jZXNzIGNsZWFudXAgaGFuZGxlcnMpLCBhbGxvd2luZyBhIGNvbXBldGluZ1xuICogcnVuIHRvIHByb2NlZWQuIFNlZSB7QGxpbmsgYWNxdWlyZVNldHVwTG9ja30uXG4gKi9cbmNvbnN0IHNldHVwTG9ja3MgPSBuZXcgTWFwPENvcmVTZXR1cFJlc3VsdCwgU2V0dXBMb2NrPigpO1xuXG5jb25zdCBBTkRST0lEX0xPQ0tfU0NPUEUgPSAnYW5kcm9pZCc7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGNvcmVTZXR1cH0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29yZVNldHVwUGFyYW1zIHtcbiAgLyoqXG4gICAqIENvbW11bml0eS1wbHVnaW4gaWRzIHRvIGVuYWJsZSBpbiB0aGUgdmF1bHQgKippbiBhZGRpdGlvbiB0byoqIHRoZVxuICAgKiBwbHVnaW4tdW5kZXItdGVzdCwgYWZ0ZXIgaXQgaXMgZW5hYmxlZC4gRWFjaCBpZCdzIGJ1aWx0IGZpbGVzIG11c3QgYWxyZWFkeSBiZVxuICAgKiBwcmVzZW50IHVuZGVyIGAub2JzaWRpYW4vcGx1Z2lucy88aWQ+L2AgXHUyMDE0IHNlZWQgdGhlbSB2aWEge0BsaW5rIENvcmVTZXR1cFBhcmFtcy5wb3B1bGF0ZX1cbiAgICogKGUuZy4gd2l0aCBgYnVpbGREZW1vVmF1bHRQb3B1bGF0ZWApLiBFbmFibGluZyBnb2VzIHRocm91Z2ggdGhlIHNhbWVcbiAgICogcmV0cnkvbG9hZC12ZXJpZnkgcGF0aCBhcyB0aGUgcGx1Z2luLXVuZGVyLXRlc3QuIENvbXBvc2VzIHdpdGhcbiAgICogYGluc3RhbGxQbHVnaW46IGZhbHNlYCAoZW5hYmxlIGV4dHJhcyBpbnRvIGFuIG90aGVyd2lzZSBwbHVnaW4tbGVzcyB2YXVsdCkuXG4gICAqL1xuICByZWFkb25seSBlbmFibGVDb21tdW5pdHlQbHVnaW5zPzogcmVhZG9ubHkgc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gaW5zdGFsbCBhbmQgZW5hYmxlIHRoZSBidWlsdCBwbHVnaW4gaW4gdGhlIHRlbXAgdmF1bHQuIERlZmF1bHRzXG4gICAqIHRvIGB0cnVlYC4gU2V0IHRvIGBmYWxzZWAgZm9yIGEgKipub24tcGx1Z2luKiogY29uc3VtZXIgKGUuZy4gYSB0eXBpbmdzXG4gICAqIGNyYXdsZXIpIHRoYXQgb25seSBuZWVkcyBhIHJlZ2lzdGVyZWQsIGVtcHR5IHZhdWx0IHRvIGBldmFsSW5PYnNpZGlhbmBcbiAgICogYWdhaW5zdDogdGhlIHBsdWdpbiBgZGlzdGAvYG1hbmlmZXN0Lmpzb25gIHJlYWQsIHRoZSBjb3B5IGludG8gdGhlIGNvbmZpZ1xuICAgKiBmb2xkZXIncyBgcGx1Z2lucy9gLCB0aGUgYGNvbW11bml0eS1wbHVnaW5zLmpzb25gIHdyaXRlLCBhbmQgdGhlIGVuYWJsZSBzdGVwXG4gICAqIGFyZSBhbGwgc2tpcHBlZCwgd2hpbGUgdGhlIHRyYW5zcG9ydCwgdGVtcCB2YXVsdCwgcmVnaXN0cmF0aW9uLCBhbmRcbiAgICogd29ya2VyLWZhY2luZyBlbmRwb2ludCBwcm92aXNpb25pbmcgc3RpbGwgcnVuIHVuY2hhbmdlZC5cbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbGxQbHVnaW4/OiBib29sZWFuIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBGaWxlcyBhbmQgZm9sZGVycyB0byB3cml0ZSBpbnRvIHRoZSB2YXVsdCAqKmJlZm9yZSoqIE9ic2lkaWFuIG9wZW5zIGl0LCBzb1xuICAgKiBpdHMgc3RhcnR1cCBzY2FuIGluZGV4ZXMgdGhlbSBpbiBvbmUgcGFzcyAoc2VlIHtAbGluayBUZW1wb3JhcnlWYXVsdC5wb3B1bGF0ZX0pLlxuICAgKiBVc2UgdGhpcyBmb3IgbGFyZ2UgZml4dHVyZXMgXHUyMDE0IHdyaXRpbmcgdGhvdXNhbmRzIG9mIG5vdGVzIGFmdGVyIG9wZW4gYW5kXG4gICAqIGZvcmNpbmcgYSByZS1zY2FuIGlzIGZhciBzbG93ZXIgYW5kIGxlc3MgcmVsaWFibGUuXG4gICAqXG4gICAqIEtleXMgbmFtaW5nIHRoZSBjb25maWcgZm9sZGVyIGFyZSB3cml0dGVuIGFzIGAub2JzaWRpYW4vXHUyMDI2YDsgdW5kZXIgYVxuICAgKiBgY29uZmlnRGlyZWN0b3J5YCBvdmVycmlkZSB7QGxpbmsgcmVtYXBDb25maWdEaXJlY3RvcnlLZXlzfSByZWRpcmVjdHMgdGhlbSB0b1xuICAgKiB0aGUgZm9sZGVyIHRoZSB2YXVsdCB3aWxsIGFjdHVhbGx5IHJlYWQsIHNvIGEgbWFwIGRvZXMgbm90IGhhdmUgdG8gY2FycnkgYVxuICAgKiBzZWNvbmQgY29weSBvZiB0aGUgb3ZlcnJpZGUuXG4gICAqL1xuICByZWFkb25seSBwb3B1bGF0ZT86IFBvcHVsYXRlRmlsZXNQYXJhbXMgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRyYW5zcG9ydCBvcHRpb25zLiBXaGVuIG9taXR0ZWQsIHVzZXMgYW4gb2ZmLXNjcmVlbiBvd25lZCBkZXNrdG9wIGluc3RhbmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0T3B0aW9ucz86IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZXN1bHQgcmV0dXJuZWQgYnkge0BsaW5rIGNvcmVTZXR1cH0sIHVzZWQgYnkgZnJhbWV3b3JrIGFkYXB0ZXJzXG4gKiB0byBwYXNzIGNvbnRleHQgdG8gdGVzdCB3b3JrZXJzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvcmVTZXR1cFJlc3VsdCB7XG4gIC8qKlxuICBUaGUgdGVtcG9yYXJ5IHZhdWx0IGNyZWF0ZWQgZHVyaW5nIHNldHVwLlxuICAgKi9cbiAgcmVhZG9ubHkgdGVtcG9yYXJ5VmF1bHQ6IFRlbXBvcmFyeVZhdWx0O1xuXG4gIC8qKlxuICBUaGUgdHJhbnNwb3J0IGluc3RhbmNlIHVzZWQgZHVyaW5nIHNldHVwLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydDtcblxuICAvKipcbiAgU2hvcnQgbGFiZWwgZm9yIGxvZyBtZXNzYWdlcyAoZS5nLiBgXCJvYnNpZGlhbi1jZHBcImApLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0TGFiZWw6IHN0cmluZztcblxuICAvKipcbiAgVGhlIHRyYW5zcG9ydCBvcHRpb25zIHRoYXQgd2VyZSByZXNvbHZlZC5cbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydE9wdGlvbnM6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgY29weVBsdWdpbkludG9WYXVsdH0uXG4gKi9cbmludGVyZmFjZSBDb3B5UGx1Z2luSW50b1ZhdWx0UGFyYW1zIHtcbiAgLyoqXG4gIFRoZSBjb25maWcgZm9sZGVyIHRoZSB2YXVsdCB3aWxsIHJlYWQsIHdoZW4gb3ZlcnJpZGRlbiBhd2F5IGZyb20gYC5vYnNpZGlhbmAgXHUyMDE0IHRoZSByZXNvbHZlZFxuICB7QGxpbmsgcmVzb2x2ZU93bmVkQ29uZmlnRGlyZWN0b3J5fSB2YWx1ZSwgd2hpY2ggaXMgYHVuZGVmaW5lZGAgZm9yIE9ic2lkaWFuJ3Mgb3duIGRlZmF1bHQuXG4gICAqL1xuICByZWFkb25seSBjb25maWdEaXJlY3Rvcnk6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgU2hvcnQgbGFiZWwgZm9yIGxvZyBtZXNzYWdlcy5cbiAgICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBwcm9qZWN0IHJvb3QgdG8gcmVzb2x2ZSB0aGUgYnVpbHQgcGx1Z2luIGZyb20uXG4gICAqL1xuICByZWFkb25seSBwcm9qZWN0Um9vdDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgdGVtcCB2YXVsdCB0byBjb3B5IHRoZSBwbHVnaW4gaW50by5cbiAgICovXG4gIHJlYWRvbmx5IHRlbXBvcmFyeVZhdWx0OiBUZW1wb3JhcnlWYXVsdDtcblxuICAvKipcbiAgVGhlIHRyYW5zcG9ydCAodXNlZCBmb3IgdGhlIG1vYmlsZS9kZXNrdG9wLW9ubHkgY29tcGF0aWJpbGl0eSBjaGVjaykuXG4gICAqL1xuICByZWFkb25seSB0cmFuc3BvcnQ6IE9ic2lkaWFuVHJhbnNwb3J0O1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBlbmFibGVFeHRyYUNvbW11bml0eVBsdWdpbnN9LlxuICovXG5pbnRlcmZhY2UgRW5hYmxlRXh0cmFDb21tdW5pdHlQbHVnaW5zUGFyYW1zIHtcbiAgLyoqXG4gIFNob3J0IGxhYmVsIGZvciBsb2cgbWVzc2FnZXMuXG4gICAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgaWRzIG9mIHRoZSBleHRyYSBjb21tdW5pdHkgcGx1Z2lucyB0byBlbmFibGUgKHRoZWlyIGJpbmFyaWVzIG11c3QgYWxyZWFkeSBiZSBpbiB0aGUgdmF1bHQpLlxuICAgKi9cbiAgcmVhZG9ubHkgcGx1Z2luSWRzOiByZWFkb25seSBzdHJpbmdbXTtcblxuICAvKipcbiAgVGhlIHRlbXAgdmF1bHQgdGhlIHBsdWdpbnMgd2VyZSBzZWVkZWQgaW50by5cbiAgICovXG4gIHJlYWRvbmx5IHRlbXBvcmFyeVZhdWx0OiBUZW1wb3JhcnlWYXVsdDtcblxuICAvKipcbiAgVGhlIHRyYW5zcG9ydCB0byBldmFsdWF0ZSBhZ2FpbnN0LlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydDtcblxuICAvKipcbiAgVGhlIHJlc29sdmVkIHRyYW5zcG9ydCBvcHRpb25zIChzb3VyY2Ugb2YgdGhlIHBsdWdpbi1lbmFibGUgcmV0cnkga25vYnMpLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0T3B0aW9uczogbnVsbCB8IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgZW5hYmxlUGx1Z2luSW5WYXVsdH0uXG4gKi9cbmludGVyZmFjZSBFbmFibGVQbHVnaW5JblZhdWx0UGFyYW1zIHtcbiAgLyoqXG4gIFNob3J0IGxhYmVsIGZvciBsb2cgbWVzc2FnZXMuXG4gICAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgaWQgb2YgdGhlIHBsdWdpbiB0byBlbmFibGUuXG4gICAqL1xuICByZWFkb25seSBwbHVnaW5JZDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgdGVtcCB2YXVsdCB0aGUgcGx1Z2luIHdhcyBjb3BpZWQgaW50by5cbiAgICovXG4gIHJlYWRvbmx5IHRlbXBvcmFyeVZhdWx0OiBUZW1wb3JhcnlWYXVsdDtcblxuICAvKipcbiAgVGhlIHRyYW5zcG9ydCB0byBldmFsdWF0ZSBhZ2FpbnN0LlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydDtcblxuICAvKipcbiAgVGhlIHJlc29sdmVkIHRyYW5zcG9ydCBvcHRpb25zIChzb3VyY2Ugb2YgdGhlIHBsdWdpbi1lbmFibGUgcmV0cnkga25vYnMpLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0T3B0aW9uczogbnVsbCB8IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgc2tpcElmRGVza3RvcE9ubHl9LlxuICovXG5pbnRlcmZhY2UgU2tpcElmRGVza3RvcE9ubHlQYXJhbXMge1xuICAvKipcbiAgU2hvcnQgbGFiZWwgZm9yIGxvZyBtZXNzYWdlcy5cbiAgICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBwcm9qZWN0IHJvb3QgdG8gcmVzb2x2ZSB0aGUgYnVpbHQgcGx1Z2luJ3MgbWFuaWZlc3QgZnJvbS5cbiAgICovXG4gIHJlYWRvbmx5IHByb2plY3RSb290OiBzdHJpbmc7XG5cbiAgLyoqXG4gIFdoZXRoZXIgYSBwbHVnaW4gaXMgYmVpbmcgaW5zdGFsbGVkIGF0IGFsbCAtLSB0aGVyZSBpcyBub3RoaW5nIHRvIGNoZWNrIHdoZW4gdGhlIHZhdWx0IHN0YXlzIGVtcHR5LlxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkSW5zdGFsbFBsdWdpbjogYm9vbGVhbjtcblxuICAvKipcbiAgVGhlIHJlc29sdmVkIHRyYW5zcG9ydCBvcHRpb25zLCB3aG9zZSBkaXNjcmltaW5hbnQgc2F5cyB3aGV0aGVyIHRoaXMgcnVuIGlzIG1vYmlsZS5cbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydE9wdGlvbnM6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgc3dlZXBMZWZ0b3ZlcnN9LlxuICovXG5pbnRlcmZhY2UgU3dlZXBMZWZ0b3ZlcnNQYXJhbXMge1xuICAvKipcbiAgRGlyZWN0b3J5IG5hbWVzIHRvIGtlZXAgcmVnYXJkbGVzcyBvZiBhZ2UgKGUuZy4gYSBjb25jdXJyZW50IHNldHVwJ3MgdmF1bHQpLlxuICAgKi9cbiAgcmVhZG9ubHkgZXhjbHVkZWROYW1lcz86IHJlYWRvbmx5IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBTaG9ydCBsYWJlbCBmb3IgbG9nIG1lc3NhZ2VzLlxuICAgKi9cbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblxuICAvKipcbiAgV2hpY2ggZW5kIG9mIHRoZSBydW4gaXMgc3dlZXBpbmcsIGZvciB0aGUgbG9nIHByZWZpeC5cbiAgICovXG4gIHJlYWRvbmx5IHBoYXNlOiAnc2V0dXAnIHwgJ3RlYXJkb3duJztcblxuICAvKipcbiAgVGhlIHJlc29sdmVkIHRyYW5zcG9ydCBvcHRpb25zIChzb3VyY2Ugb2YgdGhlIHN3ZWVwIGtub2JzKS5cbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zcG9ydE9wdGlvbnM6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBGcmFtZXdvcmstYWdub3N0aWMgZ2xvYmFsIHNldHVwIGxvZ2ljLlxuICpcbiAqIExvYWRzIGAuZW52YCBmcm9tIHRoZSBwcm9qZWN0IHJvb3QsIGNyZWF0ZXMgYSB0cmFuc3BvcnQsIGNyZWF0ZXMgYW5kIHJlZ2lzdGVyc1xuICogYSB0ZW1wb3JhcnkgdmF1bHQgd2l0aCBPYnNpZGlhbiwgYW5kIFx1MjAxNCB1bmxlc3Mge0BsaW5rIENvcmVTZXR1cFBhcmFtcy5pbnN0YWxsUGx1Z2lufVxuICogaXMgYGZhbHNlYCBcdTIwMTQgY29waWVzIHRoZSBidWlsdCBwbHVnaW4gaW50byB0aGUgdmF1bHQgYW5kIGVuYWJsZXMgaXQuIFRoZVxuICogcGx1Z2luLWxlc3MgbW9kZSBzdGlsbCBsYXVuY2hlcyB0aGUgb3duZWQgaW5zdGFuY2UgYW5kIHB1Ymxpc2hlcyBpdHNcbiAqIHdvcmtlci1mYWNpbmcgZW5kcG9pbnQsIHNvIGEgbm9uLXBsdWdpbiBjb25zdW1lciByZXVzZXMgdGhlIHNhbWUgYXR0YWNoIHdpcmluZy5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gU2V0dXAgcGFyYW1ldGVycy5cbiAqIEByZXR1cm5zIFRoZSBzZXR1cCByZXN1bHQgY29udGFpbmluZyB0aGUgdGVtcCB2YXVsdCwgdHJhbnNwb3J0LCBhbmQgcmVzb2x2ZWQgb3B0aW9ucy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvcmVTZXR1cChwYXJhbXM/OiBDb3JlU2V0dXBQYXJhbXMpOiBQcm9taXNlPENvcmVTZXR1cFJlc3VsdD4ge1xuICBjb25zdCBwcm9qZWN0Um9vdCA9IGZpbmRQcm9qZWN0Um9vdCgpO1xuICBjb25zdCBlbnZGaWxlUGF0aCA9IGpvaW4ocHJvamVjdFJvb3QsICcuZW52Jyk7XG4gIGlmIChleGlzdHNTeW5jKGVudkZpbGVQYXRoKSkge1xuICAgIGxvYWRFbnZGaWxlKGVudkZpbGVQYXRoKTtcbiAgfVxuXG4gIGNvbnN0IHRyYW5zcG9ydE9wdGlvbnMgPSByZXNvbHZlSW50ZWdyYXRpb25UcmFuc3BvcnRPcHRpb25zKHBhcmFtcz8udHJhbnNwb3J0T3B0aW9ucyk7XG4gIGNvbnN0IGxhYmVsID0gdHJhbnNwb3J0T3B0aW9ucy50eXBlO1xuICBjb25zdCBzaG91bGRJbnN0YWxsUGx1Z2luID0gcGFyYW1zPy5pbnN0YWxsUGx1Z2luICE9PSBmYWxzZTtcblxuICAvLyBCZWZvcmUgdGhlIGxvY2ssIHRoZSBzd2VlcCBhbmQgYWJvdmUgYWxsIHRoZSB0cmFuc3BvcnQ6IGNyZWF0aW5nIGEgbW9iaWxlIHRyYW5zcG9ydCBib290cyB0aGUgQVZEIGFuZFxuICAvLyBBdXRvLXN0YXJ0cyBBcHBpdW0gKH43MCBzKSBvbmx5IHRvIHJlYWNoIHRoZSBzYW1lIGNvbmNsdXNpb24gZnJvbSBgdHJhbnNwb3J0LmlzTW9iaWxlYCBmdXJ0aGVyIGRvd24uXG4gIC8vIE5laXRoZXIgaW5wdXQgbmVlZHMgYSBkZXZpY2UgLS0gdGhlIG1hbmlmZXN0IGlzIG9uIGRpc2sgYW5kIHRoZSBkaXNjcmltaW5hbnQgYWxyZWFkeSBzYXlzIG1vYmlsZS5cbiAgYXdhaXQgc2tpcElmRGVza3RvcE9ubHkoeyBsYWJlbCwgcHJvamVjdFJvb3QsIHNob3VsZEluc3RhbGxQbHVnaW4sIHRyYW5zcG9ydE9wdGlvbnMgfSk7XG5cbiAgY29uc3QgbG9ja1Njb3BlID0gZ2V0TG9ja1Njb3BlKHRyYW5zcG9ydE9wdGlvbnMpO1xuXG4gIGxldCBsb2NrOiBTZXR1cExvY2sgfCB1bmRlZmluZWQ7XG4gIGlmIChsb2NrU2NvcGUgIT09IHVuZGVmaW5lZCkge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBBY3F1aXJpbmcgJyR7bG9ja1Njb3BlfScgc2V0dXAgbG9jayAoc2VyaWFsaXplcyBhZ2FpbnN0IGFueSBjb25jdXJyZW50IGludGVncmF0aW9uLXRlc3QgcnVuKS4uLmApO1xuICAgIGxvY2sgPSBhd2FpdCBhY3F1aXJlU2V0dXBMb2NrKHsgbGFiZWwsIHNjb3BlOiBsb2NrU2NvcGUgfSk7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFNldHVwIGxvY2sgYWNxdWlyZWQuYCk7XG4gIH1cblxuICBhd2FpdCBzd2VlcExlZnRvdmVycyh7IGxhYmVsLCBwaGFzZTogJ3NldHVwJywgdHJhbnNwb3J0T3B0aW9ucyB9KTtcblxuICBsZXQgdHJhbnNwb3J0OiBPYnNpZGlhblRyYW5zcG9ydCB8IHVuZGVmaW5lZDtcbiAgbGV0IHRlbXBvcmFyeVZhdWx0OiBUZW1wb3JhcnlWYXVsdCB8IHVuZGVmaW5lZDtcblxuICB0cnkge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBDcmVhdGluZyB0cmFuc3BvcnQuLi5gKTtcbiAgICB0cmFuc3BvcnQgPSBhd2FpdCBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9ucyh0cmFuc3BvcnRPcHRpb25zKTtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gVHJhbnNwb3J0IGNyZWF0ZWQ6ICR7dHJhbnNwb3J0LmNvbnN0cnVjdG9yLm5hbWV9YCk7XG5cbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gUHJvamVjdCByb290OiAke3Byb2plY3RSb290fWApO1xuXG4gICAgdGVtcG9yYXJ5VmF1bHQgPSBuZXcgVGVtcG9yYXJ5VmF1bHQoKTtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gQ3JlYXRlZCB0ZW1wIHZhdWx0OiAke3RlbXBvcmFyeVZhdWx0LnBhdGh9YCk7XG5cbiAgICAvKlxuICAgICAqIFdoaWNoIGZvbGRlciB0aGlzIHZhdWx0IHdpbGwgYWN0dWFsbHkgcmVhZCwgcmVzb2x2ZWQgb25jZSBhbmQgaGFuZGVkIHRvIGV2ZXJ5IHdyaXRlciBiZWxvdy5cbiAgICAgKiBFdmVyeSBwcmUtb3BlbiB3cml0ZSBoYXMgdG8gYWdyZWUgb24gaXQ6IG9uZSB0aGF0IGhhcmRjb2RlcyBgLm9ic2lkaWFuYCB1bmRlciBhbiBvdmVycmlkZSB3cml0ZXNcbiAgICAgKiBzb21ld2hlcmUgbm90aGluZyBsb29rcywgYW5kIG5vdGhpbmcgdGhyb3dzIHRvIHNheSBzby5cbiAgICAgKi9cbiAgICBjb25zdCBjb25maWdEaXJlY3RvcnkgPSByZXNvbHZlT3duZWRDb25maWdEaXJlY3RvcnkodHJhbnNwb3J0T3B0aW9ucyk7XG5cbiAgICBsZXQgcGx1Z2luSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIGlmIChzaG91bGRJbnN0YWxsUGx1Z2luKSB7XG4gICAgICBwbHVnaW5JZCA9IGF3YWl0IGNvcHlQbHVnaW5JbnRvVmF1bHQoeyBjb25maWdEaXJlY3RvcnksIGxhYmVsLCBwcm9qZWN0Um9vdCwgdGVtcG9yYXJ5VmF1bHQsIHRyYW5zcG9ydCB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFNraXBwaW5nIHBsdWdpbiBpbnN0YWxsIChpbnN0YWxsUGx1Z2luOiBmYWxzZSkgXHUyMDE0IHJlZ2lzdGVyaW5nIGFuIGVtcHR5IHZhdWx0LmApO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXM/LnBvcHVsYXRlKSB7XG4gICAgICBjb25zdCBwb3B1bGF0ZSA9IHJlbWFwQ29uZmlnRGlyZWN0b3J5S2V5cyhwYXJhbXMucG9wdWxhdGUsIGNvbmZpZ0RpcmVjdG9yeSk7XG4gICAgICBjb25zdCBlbnRyeUNvdW50ID0gT2JqZWN0LmtleXMocG9wdWxhdGUpLmxlbmd0aDtcbiAgICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBQb3B1bGF0aW5nIHZhdWx0IHdpdGggJHtTdHJpbmcoZW50cnlDb3VudCl9IGVudHJpZXMgYmVmb3JlIG9wZW4uLi5gKTtcbiAgICAgIHRlbXBvcmFyeVZhdWx0LnBvcHVsYXRlKHBvcHVsYXRlKTtcbiAgICB9XG5cbiAgICBhd2FpdCBlbnN1cmVIZWFkbGVzc1ZhdWx0Q29uZmlnKHtcbiAgICAgIGNvbmZpZ0RpcmVjdG9yeSxcbiAgICAgIGxhYmVsLFxuICAgICAgdmF1bHRQYXRoOiB0ZW1wb3JhcnlWYXVsdC5wYXRoXG4gICAgfSk7XG5cbiAgICAvLyBgcmVnaXN0ZXJgIHB1c2hlcyB0aGUgZGlyZWN0b3J5IHRvIHRoZSBkZXZpY2UgYmVmb3JlIHJlZ2lzdGVyaW5nIGl0LCBzbyBldmVyeSB3cml0ZSBhYm92ZSBcdTIwMTRcbiAgICAvLyBUaGUgcGx1Z2luIGNvcHksIHRoZSBwb3B1bGF0ZSBtYXAsIGFuZCB0aGUgaGVhZGxlc3MgY29uZmlnIGp1c3Qgd3JpdHRlbiBcdTIwMTQgcmVhY2hlcyB0aGUgYXBwLlxuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBSZWdpc3RlcmluZyB2YXVsdC4uLmApO1xuICAgIGF3YWl0IHRlbXBvcmFyeVZhdWx0LnJlZ2lzdGVyKHRyYW5zcG9ydCk7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFZhdWx0IHJlZ2lzdGVyZWQuYCk7XG5cbiAgICBpZiAocGx1Z2luSWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgYXdhaXQgZW5hYmxlUGx1Z2luSW5WYXVsdCh7IGxhYmVsLCBwbHVnaW5JZCwgdGVtcG9yYXJ5VmF1bHQsIHRyYW5zcG9ydCwgdHJhbnNwb3J0T3B0aW9ucyB9KTtcbiAgICB9XG5cbiAgICBhd2FpdCBlbmFibGVFeHRyYUNvbW11bml0eVBsdWdpbnMoe1xuICAgICAgbGFiZWwsXG4gICAgICBwbHVnaW5JZHM6IHBhcmFtcz8uZW5hYmxlQ29tbXVuaXR5UGx1Z2lucyA/PyBbXSxcbiAgICAgIHRlbXBvcmFyeVZhdWx0LFxuICAgICAgdHJhbnNwb3J0LFxuICAgICAgdHJhbnNwb3J0T3B0aW9uc1xuICAgIH0pO1xuXG4gICAgY29uc3QgYXVnbWVudGVkT3B0aW9ucyA9IGF1Z21lbnRUcmFuc3BvcnRPcHRpb25zKHRyYW5zcG9ydE9wdGlvbnMsIHRyYW5zcG9ydCk7XG4gICAgY29uc3QgcmVzdWx0OiBDb3JlU2V0dXBSZXN1bHQgPSB7IHRlbXBvcmFyeVZhdWx0LCB0cmFuc3BvcnQsIHRyYW5zcG9ydExhYmVsOiBsYWJlbCwgdHJhbnNwb3J0T3B0aW9uczogYXVnbWVudGVkT3B0aW9ucyB9O1xuICAgIGFjdGl2ZVNldHVwcy5hZGQocmVzdWx0KTtcbiAgICBpZiAobG9jaykge1xuICAgICAgc2V0dXBMb2Nrcy5zZXQocmVzdWx0LCBsb2NrKTtcbiAgICB9XG4gICAgcmVnaXN0ZXJQcm9jZXNzQ2xlYW51cEhhbmRsZXIoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBTZXR1cCBmYWlsZWQsIGNsZWFuaW5nIHVwLi4uYCk7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh0ZW1wb3JhcnlWYXVsdCAmJiB0cmFuc3BvcnQpIHtcbiAgICAgICAgYXdhaXQgdGVtcG9yYXJ5VmF1bHQuZGlzcG9zZSh0cmFuc3BvcnQpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGNsZWFudXBFcnJvcjogdW5rbm93bikge1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFZhdWx0IGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhjbGVhbnVwRXJyb3IpfWApO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdHJhbnNwb3J0Py5kaXNwb3NlPy4oKTtcbiAgICB9IGNhdGNoIChjbGVhbnVwRXJyb3I6IHVua25vd24pIHtcbiAgICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBUcmFuc3BvcnQgY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGNsZWFudXBFcnJvcil9YCk7XG4gICAgfVxuXG4gICAgLy8gUmVsZWFzZSB0aGUgbG9jayBzbyBhIHdhaXRpbmcgcnVuIGNhbiBwcm9jZWVkIGV2ZW4gdGhvdWdoIHRoaXMgcnVuIGZhaWxlZC5cbiAgICBsb2NrPy5yZWxlYXNlKCk7XG5cbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gTk9URTogSWYgdGhlIHRlc3QgcnVubmVyIHJlcG9ydHMgXCJObyB0ZXN0IGZpbGVzIGZvdW5kXCIsIGlnbm9yZSBpdCBcdTIwMTQgaXQgaXMgYSBzaWRlIGVmZmVjdCBvZiB0aGUgc2V0dXAgZmFpbHVyZSBhYm92ZS5gKTtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuXG4vKipcbiAqIEZyYW1ld29yay1hZ25vc3RpYyBnbG9iYWwgdGVhcmRvd24gbG9naWMuXG4gKlxuICogRGlzcG9zZXMgb2YgdGhlIHRlbXBvcmFyeSB2YXVsdCBhbmQgdHJhbnNwb3J0IGNyZWF0ZWQgZHVyaW5nIHNldHVwLlxuICpcbiAqIEBwYXJhbSByZXN1bHQgLSBUaGUgcmVzdWx0IGZyb20ge0BsaW5rIGNvcmVTZXR1cH0uIFdoZW4gYHVuZGVmaW5lZGAsIGRvZXMgbm90aGluZy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvcmVUZWFyZG93bihyZXN1bHQ/OiBDb3JlU2V0dXBSZXN1bHQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKCFyZXN1bHQgfHwgZGlzcG9zZWRSZXN1bHRzLmhhcyhyZXN1bHQpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGRpc3Bvc2VkUmVzdWx0cy5hZGQocmVzdWx0KTtcblxuICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bjoke3Jlc3VsdC50cmFuc3BvcnRMYWJlbH1dIFRlYXJpbmcgZG93bi4uLmApO1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgdGVhcmRvd25Bc3luYyhyZXN1bHQpO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gQ2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBhY3RpdmVTZXR1cHMuZGVsZXRlKHJlc3VsdCk7XG4gICAgcmVsZWFzZVNldHVwTG9jayhyZXN1bHQpO1xuICB9XG5cbiAgYXdhaXQgc3dlZXBMZWZ0b3ZlcnMoe1xuICAgIGV4Y2x1ZGVkTmFtZXM6IFsuLi5hY3RpdmVTZXR1cHNdLm1hcCgoYWN0aXZlU2V0dXApID0+IGJhc2VuYW1lKGFjdGl2ZVNldHVwLnRlbXBvcmFyeVZhdWx0LnBhdGgpKSxcbiAgICBsYWJlbDogcmVzdWx0LnRyYW5zcG9ydExhYmVsLFxuICAgIHBoYXNlOiAndGVhcmRvd24nLFxuICAgIHRyYW5zcG9ydE9wdGlvbnM6IHJlc3VsdC50cmFuc3BvcnRPcHRpb25zXG4gIH0pO1xufVxuXG4vKipcbiAqIFJlZGlyZWN0cyBhIHBvcHVsYXRlIG1hcCdzIGNvbmZpZy1mb2xkZXIgZW50cmllcyB0byB0aGUgZm9sZGVyIHRoZSB2YXVsdCB3aWxsIGFjdHVhbGx5IHJlYWQuXG4gKlxuICogQSBwb3B1bGF0ZSBtYXAgbmFtZXMgaXRzIGRlc3RpbmF0aW9ucyB2YXVsdC1yZWxhdGl2ZSwgYW5kIGV2ZXJ5dGhpbmcgdGhhdCBidWlsZHMgb25lIFx1MjAxNCBpbmNsdWRpbmdcbiAqIGBidWlsZERlbW9WYXVsdFBvcHVsYXRlYCwgd2hpY2ggc2VlZHMgYC5vYnNpZGlhbi8qYCBjb25maWcgZmlsZXMgYW5kIGluamVjdGVkIGNvbW11bml0eSBwbHVnaW5zJ1xuICogYmluYXJpZXMgXHUyMDE0IHdyaXRlcyB0aGVtIHVuZGVyIGEgbGl0ZXJhbCBgLm9ic2lkaWFuL2AsIGJlY2F1c2UgdGhhdCBpcyB0aGUgZm9sZGVyIE9ic2lkaWFuIHVzZXMgd2hlbiBub3RoaW5nXG4gKiBvdmVycmlkZXMgaXQuIFVuZGVyIGEgYGNvbmZpZ0RpcmVjdG9yeWAgb3ZlcnJpZGUgdGhvc2UgZW50cmllcyBsYW5kIGluIGEgZm9sZGVyIHRoZSB2YXVsdCBuZXZlciBvcGVucywgYW5kXG4gKiB0aGUgcGx1Z2lucyBzZWVkZWQgdGhhdCB3YXkgY29tZSBiYWNrIGFzIHRoZSBnZW5lcmljIFwiZW5hYmxlZCBidXQgbm90IGxvYWRlZFwiIHdpdGggbm90aGluZyBuYW1pbmcgYSBjb25maWdcbiAqIGZvbGRlci4gUmV3cml0aW5nIHRoZSBrZXkgaGVyZSBmaXhlcyBldmVyeSBjb25zdW1lciBhdCBvbmNlIFx1MjAxNCBhIGhhbmQtd3JpdHRlbiBtYXAgYXMgbXVjaCBhcyBhIGRlbW8gdmF1bHQnc1xuICogXHUyMDE0IGFuZCBuZWVkcyBubyBzZWNvbmQgY29weSBvZiB0aGUgb3ZlcnJpZGUgZm9yIGEgY2FsbGVyIHRvIGtlZXAgaW4gc3luYyB3aXRoIHRoZWlyIHRyYW5zcG9ydCBvcHRpb25zLlxuICpcbiAqIFNhZmUgcmF0aGVyIHRoYW4gbWFnaWM6IHRoZSB2YXVsdCBpcyBvbmUgdGhlIGhhcm5lc3MgbWFkZSBmb3IgdGhpcyBydW4gYW5kIGhhcyBleGFjdGx5IG9uZSBjb25maWcgZm9sZGVyLFxuICogc28gdW5kZXIgYW4gb3ZlcnJpZGUgYSBgLm9ic2lkaWFuL2AgZW50cnkgaXMgZGVhZCB3ZWlnaHQgbm90aGluZyByZWFkcy4gT25seSBhIGxlYWRpbmcgYC5vYnNpZGlhbmAgcGF0aFxuICogU0VHTUVOVCBtb3ZlczsgYSBub3RlIHdob3NlIG5hbWUgbWVyZWx5IGNvbnRhaW5zIHRoZSBzdHJpbmcgZG9lcyBub3QuXG4gKlxuICogQHBhcmFtIHBvcHVsYXRlIC0gVGhlIGNvbnN1bWVyJ3MgcG9wdWxhdGUgbWFwLlxuICogQHBhcmFtIGNvbmZpZ0RpcmVjdG9yeSAtIFRoZSByZXNvbHZlZCBvdmVycmlkZSwgb3IgYHVuZGVmaW5lZGAgZm9yIE9ic2lkaWFuJ3MgZGVmYXVsdCAoYSBuby1vcCkuXG4gKiBAcmV0dXJucyBUaGUgbWFwIHdpdGggaXRzIGNvbmZpZy1mb2xkZXIga2V5cyByZWRpcmVjdGVkLCBvciB0aGUgb3JpZ2luYWwgbWFwIHdoZW4gdGhlcmUgaXMgbm90aGluZyB0byBtb3ZlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVtYXBDb25maWdEaXJlY3RvcnlLZXlzKHBvcHVsYXRlOiBQb3B1bGF0ZUZpbGVzUGFyYW1zLCBjb25maWdEaXJlY3Rvcnk6IHN0cmluZyB8IHVuZGVmaW5lZCk6IFBvcHVsYXRlRmlsZXNQYXJhbXMge1xuICBpZiAoY29uZmlnRGlyZWN0b3J5ID09PSB1bmRlZmluZWQgfHwgY29uZmlnRGlyZWN0b3J5ID09PSBERUZBVUxUX0NPTkZJR19ESVJFQ1RPUlkpIHtcbiAgICByZXR1cm4gcG9wdWxhdGU7XG4gIH1cblxuICBjb25zdCBwcmVmaXggPSBgJHtERUZBVUxUX0NPTkZJR19ESVJFQ1RPUll9L2A7XG4gIGNvbnN0IHJlbWFwcGVkOiBQb3B1bGF0ZUZpbGVzUGFyYW1zID0ge307XG4gIGZvciAoY29uc3QgW3BhdGgsIGNvbnRlbnRdIG9mIE9iamVjdC5lbnRyaWVzKHBvcHVsYXRlKSkge1xuICAgIHJlbWFwcGVkW3BhdGguc3RhcnRzV2l0aChwcmVmaXgpID8gYCR7Y29uZmlnRGlyZWN0b3J5fS8ke3BhdGguc2xpY2UocHJlZml4Lmxlbmd0aCl9YCA6IHBhdGhdID0gY29udGVudDtcbiAgfVxuXG4gIHJldHVybiByZW1hcHBlZDtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyB0cmFuc3BvcnQgb3B0aW9ucyBmb3IgYW4gaW50ZWdyYXRpb24gcnVuLlxuICpcbiAqIERlc2t0b3AgbGF1bmNoZXMgYXJlIG5vcm1hbGx5IHZpc2libGUsIGJ1dCB0ZXN0IHNldHVwIGV4cGxpY2l0bHkga2VlcHMgaXRzXG4gKiBvd25lZCBpbnN0YW5jZSBvZmYtc2NyZWVuIHNvIGl0IGRvZXMgbm90IGludGVycnVwdCB0aGUgZGV2ZWxvcGVyLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ29uc3VtZXItcHJvdmlkZWQgdHJhbnNwb3J0IG9wdGlvbnMuXG4gKiBAcmV0dXJucyBPcHRpb25zIHdpdGggdGhlIGRlc2t0b3AgaW50ZWdyYXRpb24gdmlzaWJpbGl0eSBkZWZhdWx0IGFwcGxpZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlSW50ZWdyYXRpb25UcmFuc3BvcnRPcHRpb25zKG9wdGlvbnM/OiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMpOiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMge1xuICBpZiAob3B0aW9ucz8udHlwZSA9PT0gJ29ic2lkaWFuLWFuZHJvaWQtYXBwaXVtJykge1xuICAgIHJldHVybiBvcHRpb25zO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5vcHRpb25zLFxuICAgIGlzT2JzaWRpYW5BcHBWaXNpYmxlOiBvcHRpb25zPy5pc09ic2lkaWFuQXBwVmlzaWJsZSA/PyBmYWxzZSxcbiAgICB0eXBlOiAnb2JzaWRpYW4tY2RwJ1xuICB9O1xufVxuXG4vKipcbiAqIEF1Z21lbnRzIHRyYW5zcG9ydCBvcHRpb25zIHdpdGggcmV1c2UgaW5mbyBzbyB0ZXN0IHdvcmtlcnMgY2FuIHJlYXR0YWNoIHRvIHRoZVxuICogaW5zdGFuY2UgdGhlIGdsb2JhbCBzZXR1cCBhbHJlYWR5IGxhdW5jaGVkIGluc3RlYWQgb2YgY3JlYXRpbmcgdGhlaXIgb3duOlxuICpcbiAqIC0gKipBcHBpdW0qKiBcdTIwMTQgaW5qZWN0cyB0aGUgZXN0YWJsaXNoZWQgYHNlc3Npb25JZGAvYGRldmljZUlkYC5cbiAqIC0gKipPd25lZCBkZXNrdG9wIENEUCoqIFx1MjAxNCBpbmplY3RzIHRoZSBvd25lZCBpbnN0YW5jZSdzIGBob3N0YC9gcG9ydGAgKGNob3NlblxuICogICBhdCBsYXVuY2gpIHBsdXMgdGhlIGludGVybmFsIGBpc0hhcm5lc3NPd25lZEluc3RhbmNlYCBmbGFnLCBzbyBlYWNoIHdvcmtlclxuICogICAqKmF0dGFjaGVzKiogdG8gdGhhdCBpbnN0YW5jZSBvdmVyIENEUCByYXRoZXIgdGhhbiBsYXVuY2hpbmcgKGFuZCBuZXZlclxuICogICByZWdpc3RlcmluZykgaXRzIG93biBcdTIwMTQgdGhlIGJ1ZyB0aGF0IG90aGVyd2lzZSBsZWF2ZXMgYSB3b3JrZXIncyB0cmFuc3BvcnRcbiAqICAgd2l0aCBubyBDRFAgZW5kcG9pbnQuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgb3JpZ2luYWwgdHJhbnNwb3J0IG9wdGlvbnMuXG4gKiBAcGFyYW0gdHJhbnNwb3J0IC0gVGhlIHRyYW5zcG9ydCBpbnN0YW5jZSBjcmVhdGVkIGR1cmluZyBzZXR1cC5cbiAqIEByZXR1cm5zIFRoZSBhdWdtZW50ZWQgb3B0aW9ucywgb3IgdGhlIG9yaWdpbmFsIG9wdGlvbnMgaWYgbm90IGFwcGxpY2FibGUuXG4gKi9cbmZ1bmN0aW9uIGF1Z21lbnRUcmFuc3BvcnRPcHRpb25zKFxuICBvcHRpb25zOiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfCB1bmRlZmluZWQsXG4gIHRyYW5zcG9ydDogT2JzaWRpYW5UcmFuc3BvcnRcbik6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZCB7XG4gIGlmIChvcHRpb25zPy50eXBlID09PSAnb2JzaWRpYW4tYW5kcm9pZC1hcHBpdW0nICYmIHRyYW5zcG9ydCBpbnN0YW5jZW9mIEFwcGl1bVRyYW5zcG9ydCkge1xuICAgIGNvbnN0IHNlc3Npb25JbmZvID0gdHJhbnNwb3J0LmdldFNlc3Npb25JbmZvKCk7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtvcHRpb25zLnR5cGV9XSBTZXNzaW9uIHJldXNlIGluZm86IHNlc3Npb25JZD0ke3Nlc3Npb25JbmZvLnNlc3Npb25JZH0sIGRldmljZUlkPSR7c2Vzc2lvbkluZm8uZGV2aWNlSWR9YCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBkZXZpY2VJZDogc2Vzc2lvbkluZm8uZGV2aWNlSWQsXG4gICAgICBzZXNzaW9uSWQ6IHNlc3Npb25JbmZvLnNlc3Npb25JZFxuICAgIH07XG4gIH1cblxuICBpZiAoKG9wdGlvbnMgPT09IHVuZGVmaW5lZCB8fCBvcHRpb25zLnR5cGUgPT09ICdvYnNpZGlhbi1jZHAnKSAmJiB0cmFuc3BvcnQgaW5zdGFuY2VvZiBEZXNrdG9wQ2RwVHJhbnNwb3J0KSB7XG4gICAgY29uc3QgZW5kcG9pbnQgPSB0cmFuc3BvcnQuZ2V0T3duZWRJbnN0YW5jZUVuZHBvaW50KCk7XG4gICAgaWYgKGVuZHBvaW50KSB7XG4gICAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke0RFRkFVTFRfVFJBTlNQT1JUX1RZUEV9XSBPd25lZCBpbnN0YW5jZSByZXVzZSBpbmZvOiBob3N0PSR7ZW5kcG9pbnQuaG9zdH0sIHBvcnQ9JHtTdHJpbmcoZW5kcG9pbnQucG9ydCl9YCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICBob3N0OiBlbmRwb2ludC5ob3N0LFxuICAgICAgICBpc0hhcm5lc3NPd25lZEluc3RhbmNlOiB0cnVlLFxuICAgICAgICBwb3J0OiBlbmRwb2ludC5wb3J0LFxuICAgICAgICB0eXBlOiAnb2JzaWRpYW4tY2RwJ1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3B0aW9ucztcbn1cblxuLyoqXG4gKiBDb3BpZXMgdGhlIGJ1aWx0IHBsdWdpbiBpbnRvIHRoZSB0ZW1wIHZhdWx0IGFuZCBtYXJrcyBpdCBhcyBhIGNvbW11bml0eSBwbHVnaW4uXG4gKlxuICogUmVhZHMgYG1hbmlmZXN0Lmpzb25gIGZyb20gdGhlIG5ld2VyIG9mIGBkaXN0L2RldmAvYGRpc3QvYnVpbGRgLCByZWplY3RzIGFcbiAqIGRlc2t0b3Atb25seSBwbHVnaW4gb24gYSBtb2JpbGUgdHJhbnNwb3J0LCB0aGVuIGhhbmRzIHRoZSB3cml0ZSBpdHNlbGYgdG9cbiAqIHtAbGluayBpbnN0YWxsUGx1Z2luSW50b1ZhdWx0fSBcdTIwMTQgd2hpY2ggcHV0cyB0aGUgYnVpbGQgaW5cbiAqIGA8Y29uZmlnRGlyZWN0b3J5Pi9wbHVnaW5zLzxpZD5gIGFuZCB3cml0ZXNcbiAqIGA8Y29uZmlnRGlyZWN0b3J5Pi9jb21tdW5pdHktcGx1Z2lucy5qc29uYCwgaG9ub3VyaW5nIGEgYGNvbmZpZ0RpcmVjdG9yeWBcbiAqIG92ZXJyaWRlIHNvIHRoZSBwbHVnaW4gbGFuZHMgd2hlcmUgdGhlIHZhdWx0IHdpbGwgYWN0dWFsbHkgbG9vayBmb3IgaXQuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBjb3B5IHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyBUaGUgcGx1Z2luIGlkIHJlYWQgZnJvbSB0aGUgbWFuaWZlc3QuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNvcHlQbHVnaW5JbnRvVmF1bHQocGFyYW1zOiBDb3B5UGx1Z2luSW50b1ZhdWx0UGFyYW1zKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgeyBjb25maWdEaXJlY3RvcnksIGxhYmVsLCBwcm9qZWN0Um9vdCwgdGVtcG9yYXJ5VmF1bHQsIHRyYW5zcG9ydCB9ID0gcGFyYW1zO1xuICBjb25zdCBkaXN0UGF0aCA9IGF3YWl0IHJlc29sdmVEaXN0UGF0aChwcm9qZWN0Um9vdCk7XG4gIGNvbnN0IG1hbmlmZXN0SnNvbiA9IEpTT04ucGFyc2UoYXdhaXQgcmVhZEZpbGUoam9pbihkaXN0UGF0aCwgJ21hbmlmZXN0Lmpzb24nKSwgJ3V0Zi04JykpIGFzIFBsdWdpbk1hbmlmZXN0O1xuICBjb25zdCBwbHVnaW5JZCA9IG1hbmlmZXN0SnNvbi5pZDtcblxuICAvLyBUaGUgc2FtZSByZWZ1c2FsIHtAbGluayBza2lwSWZEZXNrdG9wT25seX0gYWxyZWFkeSBtYWRlIGJlZm9yZSB0aGUgdHJhbnNwb3J0IGV4aXN0ZWQuIEtlcHQgYXMgdGhlXG4gIC8vIEJhY2tzdG9wIGZvciBhbnkgY2FsbGVyIHRoYXQgcmVhY2hlcyBoZXJlIGFub3RoZXIgd2F5LCBhbmQgdGhyb3dpbmcgdGhlIHNhbWUgdHlwZSBzbyBib3RoIHBhdGhzIHJlYWRcbiAgLy8gSWRlbnRpY2FsbHkgaW4gdGhlIGxvZy5cbiAgaWYgKHRyYW5zcG9ydC5pc01vYmlsZSAmJiBtYW5pZmVzdEpzb24uaXNEZXNrdG9wT25seSkge1xuICAgIHRocm93IG5ldyBEZXNrdG9wT25seVBsdWdpblNraXBFcnJvcihwbHVnaW5JZCk7XG4gIH1cblxuICBjb25zdCBtYWluSnMgPSBqb2luKGRpc3RQYXRoLCBNQUlOX0pTKTtcbiAgY29uc3QgYnVpbGRTdGF0ID0gYXdhaXQgc3RhdChtYWluSnMpO1xuICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gVXNpbmcgJHtkaXN0UGF0aH0gKCR7YnVpbGRTdGF0Lm10aW1lLnRvSVNPU3RyaW5nKCl9KS4gSWYgb3V0ZGF0ZWQsIHJlYnVpbGQuYCk7XG5cbiAgYXdhaXQgaW5zdGFsbFBsdWdpbkludG9WYXVsdCh7IGNvbmZpZ0RpcmVjdG9yeSwgZGlzdFBhdGgsIHBsdWdpbklkLCB2YXVsdFBhdGg6IHRlbXBvcmFyeVZhdWx0LnBhdGggfSk7XG4gIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBJbnN0YWxsZWQgXCIke3BsdWdpbklkfVwiIGludG8gJHtjb25maWdEaXJlY3RvcnkgPz8gREVGQVVMVF9DT05GSUdfRElSRUNUT1JZfS9wbHVnaW5zIChhbmQgZW5hYmxlZCBpdCB0aGVyZSkuYCk7XG5cbiAgcmV0dXJuIHBsdWdpbklkO1xufVxuXG4vKipcbiAqIEVuYWJsZXMgZXh0cmEgY29tbXVuaXR5IHBsdWdpbnMgKGJleW9uZCB0aGUgcGx1Z2luLXVuZGVyLXRlc3QpIGluIHRoZSByZWdpc3RlcmVkIHZhdWx0LCBlYWNoIHRocm91Z2ggdGhlXG4gKiBzYW1lIHtAbGluayBlbmFibGVQbHVnaW5JblZhdWx0fSBwYXRoLiBFYWNoIHBsdWdpbidzIGJ1aWx0IGZpbGVzIG11c3QgYWxyZWFkeSBiZSBwcmVzZW50IGluIHRoZSB2YXVsdCAoc2VlZFxuICogdGhlbSB2aWEge0BsaW5rIENvcmVTZXR1cFBhcmFtcy5wb3B1bGF0ZX0pLiBBIG5vLW9wIHdoZW4gdGhlIGxpc3QgaXMgZW1wdHkuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBlbmFibGUgcGFyYW1ldGVycy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZW5hYmxlRXh0cmFDb21tdW5pdHlQbHVnaW5zKHBhcmFtczogRW5hYmxlRXh0cmFDb21tdW5pdHlQbHVnaW5zUGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgbGFiZWwsIHBsdWdpbklkcywgdGVtcG9yYXJ5VmF1bHQsIHRyYW5zcG9ydCwgdHJhbnNwb3J0T3B0aW9ucyB9ID0gcGFyYW1zO1xuICBmb3IgKGNvbnN0IHBsdWdpbklkIG9mIHBsdWdpbklkcykge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBFbmFibGluZyBleHRyYSBjb21tdW5pdHkgcGx1Z2luIFwiJHtwbHVnaW5JZH1cIi4uLmApO1xuICAgIGF3YWl0IGVuYWJsZVBsdWdpbkluVmF1bHQoeyBsYWJlbCwgcGx1Z2luSWQsIHRlbXBvcmFyeVZhdWx0LCB0cmFuc3BvcnQsIHRyYW5zcG9ydE9wdGlvbnMgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBFbmFibGVzIHRoZSBwbHVnaW4gaW4gdGhlIHJlZ2lzdGVyZWQgdmF1bHQgYW5kIHZlcmlmaWVzIGl0IGxvYWRlZC5cbiAqXG4gKiBPYnNpZGlhbidzIGBlbmFibGVQbHVnaW4oKWAgd3JhcHMgYGxvYWRQbHVnaW4oKWAgaW4gYSB0cnktY2F0Y2ggdGhhdCBzd2FsbG93c1xuICogZXJyb3JzIGFuZCByZXR1cm5zIGZhbHNlLCBzbyB7QGxpbmsgZW5hYmxlUGx1Z2luV2l0aEVycm9yQ2FwdHVyZX0gbW9ua2V5LXBhdGNoZXNcbiAqIGBsb2FkUGx1Z2luKClgIHRvIGNhcHR1cmUgdGhlIGVycm9yIGJlZm9yZSBpdCdzIHN3YWxsb3dlZC5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGVuYWJsZSBwYXJhbWV0ZXJzLlxuICovXG5hc3luYyBmdW5jdGlvbiBlbmFibGVQbHVnaW5JblZhdWx0KHBhcmFtczogRW5hYmxlUGx1Z2luSW5WYXVsdFBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7IGxhYmVsLCBwbHVnaW5JZCwgdGVtcG9yYXJ5VmF1bHQsIHRyYW5zcG9ydCwgdHJhbnNwb3J0T3B0aW9ucyB9ID0gcGFyYW1zO1xuICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gRW5hYmxpbmcgcGx1Z2luIFwiJHtwbHVnaW5JZH1cIi4uLmApO1xuXG4gIC8qXG4gICAqIE9wZW4gYSBuYXRpdmUgY29uc29sZS1jYXB0dXJlIHdpbmRvdyAoTGF5ZXIgMiwgQW5kcm9pZCBvbmx5KSBhcm91bmQgdGhlXG4gICAqIGVuYWJsZSBzbyB0aGF0IGlmIE9ic2lkaWFuIHN3YWxsb3dzIHRoZSBsb2FkIGVycm9yIGJlZm9yZSB0aGUgbW9ua2V5LXBhdGNoXG4gICAqIGFuZCB0aGUgcmVuZGVyZXIgY29uc29sZSAoTGF5ZXIgMSkgY2FtZSB1cCBlbXB0eSwgd2UgY2FuIHN0aWxsIHJlY292ZXIgdGhlXG4gICAqIHJlYWwgY2F1c2UgZnJvbSBgYWRiIGxvZ2NhdGAuIE5vLW9wICh1bmRlZmluZWQpIG9uIHRyYW5zcG9ydHMgdGhhdCBkb24ndFxuICAgKiBpbXBsZW1lbnQgaXQgKGUuZy4gZGVza3RvcCkuXG4gICAqL1xuICBjb25zdCBjYXB0dXJlSGFuZGxlID0gYXdhaXQgdHJhbnNwb3J0LmJlZ2luQ29uc29sZUNhcHR1cmU/LigpO1xuXG4gIC8qXG4gICAqIE9uIGEgZnJlc2hseSBjb2xkLWJvb3RlZCBlbXVsYXRvciB0aGUgcGx1Z2luIHN1YnN5c3RlbSBjYW4gc3RpbGwgYmUgc2V0dGxpbmdcbiAgICogd2hlbiB3ZSBlbmFibGUgdGhlIHBsdWdpbiwgc28gYSBzaW5nbGUtc2hvdCBlbmFibGUgcmFjZXMgdGhlIGxvYWQgYW5kIGxvc2VzXG4gICAqICh0aGUgcGx1Z2luIGxhbmRzIGluIHRoZSBlbmFibGVkIHNldCBidXQgbmV2ZXIgbG9hZHMpLiBSZXRyeSB0aGUgZW5hYmxlICtcbiAgICogbG9hZC12ZXJpZmljYXRpb24gYSBmZXcgdGltZXMgd2l0aCBleHBvbmVudGlhbCBiYWNrb2ZmLCB3aGljaCByZWNvdmVycyB0aGVcbiAgICogdHJhbnNpZW50IHJhY2UuIEEgY2FwdHVyZWQgbG9hZCBlcnJvciAoYHJlYWxFcnJvcmApIGlzIGEgZGV0ZXJtaW5pc3RpYyBidWcgXHUyMDE0XG4gICAqIHJldHJ5aW5nIGNhbm5vdCBmaXggaXQsIHNvIHdlIGZhaWwgZmFzdC4gTm9uLUFuZHJvaWQgdHJhbnNwb3J0cyByZXNvbHZlIHRvXG4gICAqIHRoZSBzYW1lIGRlZmF1bHRzIGJ1dCBuZXZlciBlbnRlciB0aGUgcmV0cnkgcGF0aDogdGhlaXIgbG9hZCBlaXRoZXIgc3VjY2VlZHNcbiAgICogb24gdGhlIGZpcnN0IGF0dGVtcHQgb3IgdGhyb3dzIGEgY2FwdHVyZWQgZXJyb3IuXG4gICAqL1xuICBjb25zdCBtYXhBdHRlbXB0cyA9IDEgKyByZXNvbHZlUGx1Z2luRW5hYmxlUmV0cnlDb3VudCh0cmFuc3BvcnRPcHRpb25zKTtcbiAgY29uc3QgYmFzZURlbGF5SW5NaWxsaXNlY29uZHMgPSByZXNvbHZlUGx1Z2luRW5hYmxlUmV0cnlEZWxheUluTWlsbGlzZWNvbmRzKHRyYW5zcG9ydE9wdGlvbnMpO1xuXG4gIGZvciAobGV0IGF0dGVtcHQgPSAxOyBhdHRlbXB0IDw9IG1heEF0dGVtcHRzOyBhdHRlbXB0KyspIHtcbiAgICBsZXQgcmVzdWx0OiBFbmFibGVQbHVnaW5SZXN1bHQ7XG4gICAgdHJ5IHtcbiAgICAgIHJlc3VsdCA9IGF3YWl0IGV2YWxJbk9ic2lkaWFuKHtcbiAgICAgICAgY2FsbGJhY2s6IGVuYWJsZVBsdWdpbldpdGhFcnJvckNhcHR1cmUsXG4gICAgICAgIGlucHV0OiB7IHBsdWdpbklkIH0sXG4gICAgICAgIHNob3VsZFNraXBQcmVmbGlnaHRDaGVja3M6IHRydWUsXG4gICAgICAgIHRyYW5zcG9ydCxcbiAgICAgICAgdmF1bHRQYXRoOiB0ZW1wb3JhcnlWYXVsdC5wYXRoXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLypcbiAgICAgICAqIFRoZSBldmFsIGl0c2VsZiB0aHJldyAoZS5nLiB0aGUgV2ViVmlldyBjb250ZXh0IHdhcyBsb3N0IG1pZC1leGVjdXRpb24gb25cbiAgICAgICAqIGEgY2h1cm5pbmcgZ3Vlc3QpIFx1MjAxNCBhIHRyYW5zcG9ydC1sZXZlbCB0cmFuc2llbnQuIFJldHJ5IGlmIGF0dGVtcHRzIHJlbWFpbi5cbiAgICAgICAqL1xuICAgICAgaWYgKGF0dGVtcHQgPCBtYXhBdHRlbXB0cykge1xuICAgICAgICBjb25zdCBkZWxheUluTWlsbGlzZWNvbmRzID0gY29tcHV0ZUJhY2tvZmZEZWxheUluTWlsbGlzZWNvbmRzKGJhc2VEZWxheUluTWlsbGlzZWNvbmRzLCBhdHRlbXB0IC0gMSk7XG4gICAgICAgIGxvZyhcbiAgICAgICAgICBgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBFbmFibGUgYXR0ZW1wdCAke1N0cmluZyhhdHRlbXB0KX0vJHtTdHJpbmcobWF4QXR0ZW1wdHMpfSB0aHJldyBgXG4gICAgICAgICAgICArIGAoJHtlcnJvclRvU3RyaW5nKGVycm9yKX0pOyByZXRyeWluZyBpbiAke1N0cmluZyhkZWxheUluTWlsbGlzZWNvbmRzKX1tcy4uLmBcbiAgICAgICAgKTtcbiAgICAgICAgYXdhaXQgc2xlZXAoZGVsYXlJbk1pbGxpc2Vjb25kcyk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBgZXJyb3JNZXNzYWdlYCBpcyB0aGUgcmVhbCB0aHJvdyBzZWVuIGJ5IHRoZSBtb25rZXktcGF0Y2g7XG4gICAgICogYHJlbmRlcmVyQ29uc29sZUVycm9yc2AgKExheWVyIDEpIGlzIHRoZSByZWFsIGNhdXNlIGNvbnNvbGUtbG9nZ2VkIGluIHRoZSByZW5kZXJlci5cbiAgICAgKi9cbiAgICBjb25zdCByZWFsRXJyb3IgPSByZXN1bHQuZXJyb3JNZXNzYWdlID8/IHJlc3VsdC5yZW5kZXJlckNvbnNvbGVFcnJvcnM7XG5cbiAgICBpZiAocmVzdWx0LmlzTG9hZGVkICYmICFyZWFsRXJyb3IpIHtcbiAgICAgIGNvbnN0IGF0dGVtcHRTdWZmaXggPSBhdHRlbXB0ID4gMSA/IGAgKGF0dGVtcHQgJHtTdHJpbmcoYXR0ZW1wdCl9LyR7U3RyaW5nKG1heEF0dGVtcHRzKX0pYCA6ICcnO1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFBsdWdpbiBcIiR7cGx1Z2luSWR9XCIgZW5hYmxlZCBzdWNjZXNzZnVsbHkke2F0dGVtcHRTdWZmaXh9LmApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEEgY2FwdHVyZWQgbG9hZCBlcnJvciBpcyBkZXRlcm1pbmlzdGljIFx1MjAxNCBmYWlsIGZhc3QgcmF0aGVyIHRoYW4gcmV0cnkuXG4gICAgaWYgKCFzaG91bGRSZXRyeVBsdWdpbkVuYWJsZShyZXN1bHQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFBsdWdpbiBcIiR7cGx1Z2luSWR9XCIgZmFpbGVkIHRvIGxvYWQ6ICR7cmVhbEVycm9yID8/IGdldEdlbmVyaWNQbHVnaW5Mb2FkRmFpbHVyZU1lc3NhZ2UocGx1Z2luSWQpfWApO1xuICAgIH1cblxuICAgIC8vIFRyYW5zaWVudCBjb2xkLWJvb3QgcmFjZSAoZW5hYmxlZCBidXQgbm90IGxvYWRlZCwgbm8gY2F1c2UgY2FwdHVyZWQpOiByZXRyeS5cbiAgICBpZiAoYXR0ZW1wdCA8IG1heEF0dGVtcHRzKSB7XG4gICAgICBjb25zdCBkZWxheUluTWlsbGlzZWNvbmRzID0gY29tcHV0ZUJhY2tvZmZEZWxheUluTWlsbGlzZWNvbmRzKGJhc2VEZWxheUluTWlsbGlzZWNvbmRzLCBhdHRlbXB0IC0gMSk7XG4gICAgICBsb2coXG4gICAgICAgIGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFBsdWdpbiBcIiR7cGx1Z2luSWR9XCIgZW5hYmxlZCBidXQgbm90IGxvYWRlZCBgXG4gICAgICAgICAgKyBgKGF0dGVtcHQgJHtTdHJpbmcoYXR0ZW1wdCl9LyR7U3RyaW5nKG1heEF0dGVtcHRzKX0pOyByZXRyeWluZyBpbiAke1N0cmluZyhkZWxheUluTWlsbGlzZWNvbmRzKX1tcy4uLmBcbiAgICAgICk7XG4gICAgICBhd2FpdCBzbGVlcChkZWxheUluTWlsbGlzZWNvbmRzKTtcbiAgICB9XG4gIH1cblxuICAvKlxuICAgKiBFeGhhdXN0ZWQgZXZlcnkgYXR0ZW1wdCBvbiB0aGUgdHJhbnNpZW50IHNpZ25hdHVyZTogY29tcG9zZSB0aGUgbW9zdFxuICAgKiBzcGVjaWZpYyBkZXRhaWwgYXZhaWxhYmxlIChgYWRiIGxvZ2NhdGAgdGFpbCBvbiBBbmRyb2lkLCBlbHNlIHRoZSBnZW5lcmljXG4gICAqIG1lc3NhZ2UpIFx1MjAxNCB1bmNoYW5nZWQgZnJvbSB0aGUgcHJlLXJldHJ5IHNpbmdsZS1zaG90IGZhaWx1cmUuXG4gICAqL1xuICBjb25zdCBsb2djYXRUYWlsID0gYXdhaXQgdHJhbnNwb3J0LnJlYWRDb25zb2xlQ2FwdHVyZVNpbmNlPy4oY2FwdHVyZUhhbmRsZSk7XG4gIGNvbnN0IGRldGFpbCA9IGxvZ2NhdFRhaWwgPz8gZ2V0R2VuZXJpY1BsdWdpbkxvYWRGYWlsdXJlTWVzc2FnZShwbHVnaW5JZCk7XG4gIHRocm93IG5ldyBFcnJvcihgUGx1Z2luIFwiJHtwbHVnaW5JZH1cIiBmYWlsZWQgdG8gbG9hZDogJHtkZXRhaWx9YCk7XG59XG5cbi8qKlxuICogRmluZHMgdGhlIHByb2plY3Qgcm9vdCBieSB3YWxraW5nIHVwIGZyb20gYHByb2Nlc3MuY3dkKClgIGxvb2tpbmcgZm9yIGBwYWNrYWdlLmpzb25gLlxuICpcbiAqIEByZXR1cm5zIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSBwcm9qZWN0IHJvb3QuXG4gKi9cbmZ1bmN0aW9uIGZpbmRQcm9qZWN0Um9vdCgpOiBzdHJpbmcge1xuICBsZXQgZGlyZWN0b3J5ID0gcHJvY2Vzcy5jd2QoKTtcblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVubmVjZXNzYXJ5LWNvbmRpdGlvbiAtLSBMb29wIHRlcm1pbmF0ZXMgYXQgZmlsZXN5c3RlbSByb290LlxuICB3aGlsZSAodHJ1ZSkge1xuICAgIGlmIChleGlzdHNTeW5jKGpvaW4oZGlyZWN0b3J5LCAncGFja2FnZS5qc29uJykpKSB7XG4gICAgICByZXR1cm4gZGlyZWN0b3J5O1xuICAgIH1cbiAgICBjb25zdCBwYXJlbnQgPSBqb2luKGRpcmVjdG9yeSwgJy4uJyk7XG4gICAgaWYgKHBhcmVudCA9PT0gZGlyZWN0b3J5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBmaW5kIHByb2plY3Qgcm9vdCAobm8gcGFja2FnZS5qc29uIGZvdW5kKS4nKTtcbiAgICB9XG4gICAgZGlyZWN0b3J5ID0gcGFyZW50O1xuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgdGhlIGNyb3NzLXByb2Nlc3MgbG9jayBzY29wZSBmb3IgYSB0cmFuc3BvcnQsIG9yIGB1bmRlZmluZWRgIHdoZW4gbm9cbiAqIGxvY2sgaXMgbmVlZGVkLlxuICpcbiAqIERlc2t0b3AgcnVucyB1c2UgaGFybmVzcy1vd25lZCwgaXNvbGF0ZWQgaW5zdGFuY2VzICh0aGVpciBvd24gdXNlci1kYXRhIGRpclxuICogYW5kIENEUCBwb3J0KSwgc28gdGhleSBubyBsb25nZXIgY29udGVuZCBhbmQgbmVlZCBubyBsb2NrLiBPbmx5IHRoZSBBbmRyb2lkXG4gKiB0cmFuc3BvcnQsIHdoaWNoIHNoYXJlcyB0aGUgc2luZ2xlIGVtdWxhdG9yIGFuZCBBcHBpdW0gc2VydmVyLCBtdXN0IHNlcmlhbGl6ZS5cbiAqXG4gKiBAcGFyYW0gdHJhbnNwb3J0T3B0aW9ucyAtIFRoZSByZXNvbHZlZCB0cmFuc3BvcnQgb3B0aW9ucy5cbiAqIEByZXR1cm5zIFRoZSBsb2NrIHNjb3BlIHN0cmluZywgb3IgYHVuZGVmaW5lZGAgaWYgbm8gbG9jayBpcyBuZWVkZWQuXG4gKi9cbmZ1bmN0aW9uIGdldExvY2tTY29wZSh0cmFuc3BvcnRPcHRpb25zOiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfCB1bmRlZmluZWQpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdHJhbnNwb3J0T3B0aW9ucz8udHlwZSA9PT0gJ29ic2lkaWFuLWFuZHJvaWQtYXBwaXVtJyA/IEFORFJPSURfTE9DS19TQ09QRSA6IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZWdpc3RlcnMgY2xlYW51cCBoYW5kbGVycyBmb3Igb3JwaGFuZWQgc2V0dXBzIHRoYXQgd2VyZSBuZXZlciBleHBsaWNpdGx5XG4gKiB0b3JuIGRvd24uXG4gKlxuICogVHdvIGhhbmRsZXJzIGNvdmVyIGRpZmZlcmVudCBleGl0IHNjZW5hcmlvczpcbiAqXG4gKiAtIGBiZWZvcmVFeGl0YCBcdTIwMTQgZmlyZXMgd2hlbiB0aGUgZXZlbnQgbG9vcCBkcmFpbnMgbmF0dXJhbGx5LiBBbGxvd3MgZnVsbFxuICogICBhc3luYyB0ZWFyZG93biAodW5yZWdpc3RlciB2YXVsdHMsIGRpc3Bvc2UgdHJhbnNwb3J0cykuIERvZXMgTk9UIGZpcmVcbiAqICAgd2hlbiBgcHJvY2Vzcy5leGl0KClgIGlzIGNhbGxlZCBkaXJlY3RseS5cbiAqXG4gKiAtIGB1bmhhbmRsZWRSZWplY3Rpb25gIFx1MjAxNCBjYXRjaGVzIGFzeW5jIGVycm9ycyB0aGF0IGJ5cGFzcyBgY29yZVNldHVwYCdzXG4gKiAgIGNhdGNoIGJsb2NrLiBQZXJmb3JtcyBmdWxsIGFzeW5jIHRlYXJkb3duIHdoaWxlIHdlIHN0aWxsIGNhbi5cbiAqXG4gKiAtIGBleGl0YCBcdTIwMTQgZmlyZXMgb24gZXZlcnkgZXhpdCwgaW5jbHVkaW5nIGBwcm9jZXNzLmV4aXQoKWAuIE9ubHkgc3luY2hyb25vdXNcbiAqICAgd29yayBpcyBwb3NzaWJsZSwgc28gdGhpcyBoYW5kbGVyIGRvZXMgYmVzdC1lZmZvcnQgY2xlYW51cDoga2lsbHMgY2hpbGRcbiAqICAgcHJvY2Vzc2VzIHZpYSBgZGlzcG9zZVN5bmMoKWAgYW5kIHJlbW92ZXMgdGVtcCB2YXVsdCBkaXJlY3RvcmllcyB3aXRoXG4gKiAgIGBybVN5bmNgLiBVbnJlZ2lzdGVyaW5nIHZhdWx0cyAod2hpY2ggcmVxdWlyZXMgSVBDIHdpdGggT2JzaWRpYW4pIGlzXG4gKiAgIHNraXBwZWQgXHUyMDE0IGEgc3RhbGUgdmF1bHQgZW50cnkgaXMgYW4gYWNjZXB0YWJsZSB0cmFkZS1vZmYgdnMuIGxlYWtlZFxuICogICBwcm9jZXNzZXMgYW5kIHRlbXAgZGlyZWN0b3JpZXMuXG4gKi9cbmZ1bmN0aW9uIHJlZ2lzdGVyUHJvY2Vzc0NsZWFudXBIYW5kbGVyKCk6IHZvaWQge1xuICBpZiAoaXNDbGVhbnVwSGFuZGxlclJlZ2lzdGVyZWQpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaXNDbGVhbnVwSGFuZGxlclJlZ2lzdGVyZWQgPSB0cnVlO1xuXG4gIHByb2Nlc3Mub24oJ2JlZm9yZUV4aXQnLCAoKSA9PiB7XG4gICAgaWYgKGFjdGl2ZVNldHVwcy5zaXplID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd25dIFByb2Nlc3MgZXhpdGluZyB3aXRoICR7U3RyaW5nKGFjdGl2ZVNldHVwcy5zaXplKX0gc2V0dXAocykgbm90IHRvcm4gZG93bi4gQ2xlYW5pbmcgdXAuLi5gKTtcblxuICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIGFjdGl2ZVNldHVwcykge1xuICAgICAgY29yZVRlYXJkb3duKHJlc3VsdCkuY2F0Y2goKGVycm9yOiB1bmtub3duKSA9PiB7XG4gICAgICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gUHJvY2VzcyBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfSk7XG4gICAgfVxuICB9KTtcblxuICBwcm9jZXNzLm9uKCd1bmhhbmRsZWRSZWplY3Rpb24nLCAoKSA9PiB7XG4gICAgaWYgKGFjdGl2ZVNldHVwcy5zaXplID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd25dIFVuaGFuZGxlZCByZWplY3Rpb24gZGV0ZWN0ZWQuIFRlYXJpbmcgZG93biAke1N0cmluZyhhY3RpdmVTZXR1cHMuc2l6ZSl9IGFjdGl2ZSBzZXR1cChzKS4uLmApO1xuICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIGFjdGl2ZVNldHVwcykge1xuICAgICAgY29yZVRlYXJkb3duKHJlc3VsdCkuY2F0Y2goKGVycm9yOiB1bmtub3duKSA9PiB7XG4gICAgICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gUmVqZWN0aW9uIGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIHByb2Nlc3Mub24oJ2V4aXQnLCAoKSA9PiB7XG4gICAgaWYgKGFjdGl2ZVNldHVwcy5zaXplID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd25dIFN5bmMgY2xlYW51cDogJHtTdHJpbmcoYWN0aXZlU2V0dXBzLnNpemUpfSBvcnBoYW5lZCBzZXR1cChzKS5gKTtcbiAgICBmb3IgKGNvbnN0IHJlc3VsdCBvZiBhY3RpdmVTZXR1cHMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlc3VsdC50cmFuc3BvcnQuZGlzcG9zZVN5bmM/LigpO1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgbG9nKGBbaW50ZWdyYXRpb24tdGVhcmRvd246JHtyZXN1bHQudHJhbnNwb3J0TGFiZWx9XSBTeW5jIHRyYW5zcG9ydCBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgcm1TeW5jKHJlc3VsdC50ZW1wb3JhcnlWYXVsdC5wYXRoLCB7IGZvcmNlOiB0cnVlLCByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bjoke3Jlc3VsdC50cmFuc3BvcnRMYWJlbH1dIFN5bmMgdmF1bHQgY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH1cbiAgICAgIHJlbGVhc2VTZXR1cExvY2socmVzdWx0KTtcbiAgICB9XG4gICAgYWN0aXZlU2V0dXBzLmNsZWFyKCk7XG4gIH0pO1xufVxuXG4vKipcbiAqIFJlbGVhc2VzIGFuZCBmb3JnZXRzIHRoZSBzZXR1cCBsb2NrIGFzc29jaWF0ZWQgd2l0aCBhIHJlc3VsdCwgaWYgYW55LlxuICpcbiAqIEBwYXJhbSByZXN1bHQgLSBUaGUgc2V0dXAgcmVzdWx0IHdob3NlIGxvY2sgc2hvdWxkIGJlIHJlbGVhc2VkLlxuICovXG5mdW5jdGlvbiByZWxlYXNlU2V0dXBMb2NrKHJlc3VsdDogQ29yZVNldHVwUmVzdWx0KTogdm9pZCB7XG4gIGNvbnN0IGxvY2sgPSBzZXR1cExvY2tzLmdldChyZXN1bHQpO1xuICBpZiAobG9jaykge1xuICAgIGxvY2sucmVsZWFzZSgpO1xuICAgIHNldHVwTG9ja3MuZGVsZXRlKHJlc3VsdCk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXNvbHZlcyB0aGUgZGlzdCBwYXRoIHRvIHVzZSBmb3IgaW50ZWdyYXRpb24gdGVzdHMuXG4gKlxuICogUGlja3Mgd2hpY2hldmVyIG9mIGBkaXN0L2RldmAgYW5kIGBkaXN0L2J1aWxkYCBoYXMgYSBuZXdlciBgbWFpbi5qc2AuXG4gKiBJZiBvbmx5IG9uZSBleGlzdHMsIHRoYXQgb25lIGlzIHVzZWQuIFRocm93cyBpZiBuZWl0aGVyIGV4aXN0cy5cbiAqXG4gKiBAcGFyYW0gcHJvamVjdFJvb3QgLSBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgcHJvamVjdCByb290LlxuICogQHJldHVybnMgVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIGNob3NlbiBkaXN0IGZvbGRlci5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZURpc3RQYXRoKHByb2plY3RSb290OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBkZXZQYXRoID0gam9pbihwcm9qZWN0Um9vdCwgRElTVF9ERVYpO1xuICBjb25zdCBidWlsZFBhdGggPSBqb2luKHByb2plY3RSb290LCBESVNUX0JVSUxEKTtcbiAgY29uc3QgZGV2TWFpbkpzID0gam9pbihkZXZQYXRoLCBNQUlOX0pTKTtcbiAgY29uc3QgYnVpbGRNYWluSnMgPSBqb2luKGJ1aWxkUGF0aCwgTUFJTl9KUyk7XG4gIGNvbnN0IGRldlN0YXQgPSBleGlzdHNTeW5jKGRldk1haW5KcykgPyBhd2FpdCBzdGF0KGRldk1haW5KcykgOiBudWxsO1xuICBjb25zdCBidWlsZFN0YXQgPSBleGlzdHNTeW5jKGJ1aWxkTWFpbkpzKSA/IGF3YWl0IHN0YXQoYnVpbGRNYWluSnMpIDogbnVsbDtcblxuICBpZiAoZGV2U3RhdCAmJiBidWlsZFN0YXQpIHtcbiAgICByZXR1cm4gZGV2U3RhdC5tdGltZSA+IGJ1aWxkU3RhdC5tdGltZSA/IGRldlBhdGggOiBidWlsZFBhdGg7XG4gIH1cblxuICBpZiAoZGV2U3RhdCkge1xuICAgIHJldHVybiBkZXZQYXRoO1xuICB9XG5cbiAgaWYgKGJ1aWxkU3RhdCkge1xuICAgIHJldHVybiBidWlsZFBhdGg7XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ05vIGJ1aWxkIGZvdW5kLiBSdW4gYG5wbSBydW4gYnVpbGRgIG9yIGBucG0gcnVuIGRldmAgZmlyc3QuJyk7XG59XG5cbi8qKlxuICogUmVmdXNlcyBhIG1vYmlsZSBydW4gZm9yIGEgZGVza3RvcC1vbmx5IHBsdWdpbiwgYmVmb3JlIGFueXRoaW5nIGNvc3RseSBoYXMgaGFwcGVuZWQuXG4gKlxuICogQSBuby1vcCB1bmxlc3MgYSBwbHVnaW4gaXMgYmVpbmcgaW5zdGFsbGVkIG9udG8gYSBtb2JpbGUgdHJhbnNwb3J0LiBPdGhlcndpc2UgcmVhZHMgYG1hbmlmZXN0Lmpzb25gXG4gKiBvdXQgb2YgdGhlIG5ld2VyIGRpc3QgZm9sZGVyIFx1MjAxNCBubyBkZXZpY2UsIG5vIGxvY2ssIG5vIHN3ZWVwLiBXaGVuIHRoZXJlIGlzIG5vIHJlYWRhYmxlIGJ1aWxkIHRoZSBjaGVja1xuICogc2ltcGx5IGRvZXMgbm90IGZpcmU6IGEgbWlzc2luZyBvciBtYWxmb3JtZWQgYnVpbGQgaXMgYSBkaWZmZXJlbnQgcHJvYmxlbSwgYW5kIHtAbGluayByZXNvbHZlRGlzdFBhdGh9XG4gKiBkb3duc3RyZWFtIGFscmVhZHkgcmVwb3J0cyBpdCBpbiBpdHMgb3duIHdvcmRzLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgdHJhbnNwb3J0IGxhYmVsLCBwcm9qZWN0IHJvb3QsIHRyYW5zcG9ydCBvcHRpb25zIGFuZCB3aGV0aGVyIGEgcGx1Z2luIGlzIGluc3RhbGxlZC5cbiAqIEB0aHJvd3Mge0Rlc2t0b3BPbmx5UGx1Z2luU2tpcEVycm9yfSBXaGVuIHRoZSBtYW5pZmVzdCBzYXlzIGBpc0Rlc2t0b3BPbmx5OiB0cnVlYC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc2tpcElmRGVza3RvcE9ubHkocGFyYW1zOiBTa2lwSWZEZXNrdG9wT25seVBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7IGxhYmVsLCBwcm9qZWN0Um9vdCwgc2hvdWxkSW5zdGFsbFBsdWdpbiwgdHJhbnNwb3J0T3B0aW9ucyB9ID0gcGFyYW1zO1xuXG4gIGlmICghc2hvdWxkSW5zdGFsbFBsdWdpbiB8fCAhY2hlY2tJc01vYmlsZVRyYW5zcG9ydCh0cmFuc3BvcnRPcHRpb25zKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGxldCBtYW5pZmVzdEpzb246IFBsdWdpbk1hbmlmZXN0O1xuICB0cnkge1xuICAgIGNvbnN0IGRpc3RQYXRoID0gYXdhaXQgcmVzb2x2ZURpc3RQYXRoKHByb2plY3RSb290KTtcbiAgICBtYW5pZmVzdEpzb24gPSBKU09OLnBhcnNlKGF3YWl0IHJlYWRGaWxlKGpvaW4oZGlzdFBhdGgsICdtYW5pZmVzdC5qc29uJyksICd1dGYtOCcpKSBhcyBQbHVnaW5NYW5pZmVzdDtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKCFtYW5pZmVzdEpzb24uaXNEZXNrdG9wT25seSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGxvZyhcbiAgICBgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBTS0lQUEVEOiBcIiR7bWFuaWZlc3RKc29uLmlkfVwiIGlzIGRlc2t0b3Atb25seSAoaXNEZXNrdG9wT25seTogdHJ1ZSksIGBcbiAgICAgICsgJ3NvIGl0IGhhcyBubyBtb2JpbGUgaW50ZWdyYXRpb24gdGVzdHMgdG8gcnVuLiBObyBlbXVsYXRvciB3YXMgYm9vdGVkIGFuZCBubyBBcHBpdW0gc2VydmVyIHdhcyBzdGFydGVkLidcbiAgKTtcbiAgdGhyb3cgbmV3IERlc2t0b3BPbmx5UGx1Z2luU2tpcEVycm9yKG1hbmlmZXN0SnNvbi5pZCk7XG59XG5cbi8qKlxuICogUmVtb3ZlcyB0aGUgaG9zdC1zaWRlIHRlbXAgZGlyZWN0b3JpZXMgZWFybGllciBydW5zIGxlYWtlZC5cbiAqXG4gKiBSdW5zIGF0IGJvdGggZW5kcyBvZiBhIHJ1bjogYXQgc2V0dXAgaXQgaGFwcGVucyAqKmJlZm9yZSoqIHRoZSB0cmFuc3BvcnQgaXNcbiAqIGNyZWF0ZWQsIHNvIGl0IGRvZXMgbm90IGRlcGVuZCBvbiBhIGhlYWx0aHkgT2JzaWRpYW4vV2ViVmlldyBcdTIwMTQgd2hpY2ggaXNcbiAqIGV4YWN0bHkgd2hhdCBhIGZhaWxlZCBydW4gbm8gbG9uZ2VyIGhhcywgYW5kIHdoeSBhIGZhaWxlZCBydW4gY2Fubm90IGNsZWFuIHVwXG4gKiBhZnRlciBpdHNlbGYuIEFnZS1nYXRlZCAoc2VlIGBsZWZ0b3Zlck1heEFnZUluTWlsbGlzZWNvbmRzYCkgYmVjYXVzZSBkZXNrdG9wXG4gKiBydW5zIGFyZSBub3Qgc2VyaWFsaXplZCBhbmQgZXZlcnkgcHJvamVjdCBvbiB0aGUgbWFjaGluZSBzaGFyZXMgb25lIHRlbXBcbiAqIGRpcmVjdG9yeS4gQmVzdC1lZmZvcnQ6IGEgc3dlZXAgbmV2ZXIgZmFpbHMgdGhlIHJ1biBpdCBpcyBjbGVhbmluZyB1cCBmb3IuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBzd2VlcCBwYXJhbWV0ZXJzLlxuICovXG5hc3luYyBmdW5jdGlvbiBzd2VlcExlZnRvdmVycyhwYXJhbXM6IFN3ZWVwTGVmdG92ZXJzUGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgbGFiZWwsIHBoYXNlLCB0cmFuc3BvcnRPcHRpb25zIH0gPSBwYXJhbXM7XG4gIGlmICghd2lsbFN3ZWVwTGVmdG92ZXJzKHRyYW5zcG9ydE9wdGlvbnMpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzd2VlcEhvc3RMZWZ0b3ZlcnMoe1xuICAgICAgZXhjbHVkZWROYW1lczogcGFyYW1zLmV4Y2x1ZGVkTmFtZXMsXG4gICAgICBtYXhBZ2VJbk1pbGxpc2Vjb25kczogcmVzb2x2ZUxlZnRvdmVyTWF4QWdlSW5NaWxsaXNlY29uZHModHJhbnNwb3J0T3B0aW9ucylcbiAgICB9KTtcbiAgICBpZiAocmVzdWx0LnJlbW92ZWRDb3VudCA+IDAgfHwgcmVzdWx0LmZhaWxlZENvdW50ID4gMCkge1xuICAgICAgbG9nKFxuICAgICAgICBgW2ludGVncmF0aW9uLSR7cGhhc2V9OiR7bGFiZWx9XSBTd2VwdCAke1N0cmluZyhyZXN1bHQucmVtb3ZlZENvdW50KX0gbGVmdG92ZXIgdGVtcCBkaXJlY3RvcihpZXMpIGBcbiAgICAgICAgICArIGBmcm9tIGVhcmxpZXIgcnVucyAoJHtTdHJpbmcocmVzdWx0LmZhaWxlZENvdW50KX0gc3RpbGwgaW4gdXNlKS5gXG4gICAgICApO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi0ke3BoYXNlfToke2xhYmVsfV0gTGVmdG92ZXIgc3dlZXAgZXJyb3IgKG5vbi1mYXRhbCk6ICR7ZXJyb3JUb1N0cmluZyhlcnJvcil9YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBQZXJmb3JtcyB0aGUgYXN5bmMgdGVhcmRvd24gd29yayAodmF1bHQgZGlzcG9zYWwgKyB0cmFuc3BvcnQgZGlzcG9zYWwpLlxuICpcbiAqIEBwYXJhbSByZXN1bHQgLSBUaGUgc2V0dXAgcmVzdWx0IHRvIHRlYXIgZG93bi5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gdGVhcmRvd25Bc3luYyhyZXN1bHQ6IENvcmVTZXR1cFJlc3VsdCk6IFByb21pc2U8dm9pZD4ge1xuICB0cnkge1xuICAgIGF3YWl0IHJlc3VsdC50ZW1wb3JhcnlWYXVsdC5kaXNwb3NlKHJlc3VsdC50cmFuc3BvcnQpO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXRlYXJkb3duOiR7cmVzdWx0LnRyYW5zcG9ydExhYmVsfV0gVmF1bHQgY2xlYW51cCBlcnJvciAobm9uLWZhdGFsKTogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgYXdhaXQgcmVzdWx0LnRyYW5zcG9ydC5kaXNwb3NlPy4oKTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBsb2coYFtpbnRlZ3JhdGlvbi10ZWFyZG93bjoke3Jlc3VsdC50cmFuc3BvcnRMYWJlbH1dIFRyYW5zcG9ydCBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICB9XG59XG4iXSwKICAibWFwcGluZ3Mi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QU87QUFBQSxFQUNUO0FBRUEsUUFBTSxJQUFJLE1BQU0sNkRBQTZEO0FBQy9FO0FBYUEsZUFBZSxrQkFBa0IsUUFBZ0Q7QUFDL0UsUUFBTSxFQUFFLE9BQU8sYUFBYSxxQkFBcUIsaUJBQWlCLElBQUk7QUFFdEUsTUFBSSxDQUFDLHVCQUF1QixLQUFDLGlEQUF1QixnQkFBZ0IsR0FBRztBQUNyRTtBQUFBLEVBQ0Y7QUFFQSxNQUFJO0FBQ0osTUFBSTtBQUNGLFVBQU0sV0FBVyxNQUFNLGdCQUFnQixXQUFXO0FBQ2xELG1CQUFlLEtBQUssTUFBTSxVQUFNLDhCQUFTLHVCQUFLLFVBQVUsZUFBZSxHQUFHLE9BQU8sQ0FBQztBQUFBLEVBQ3BGLFFBQVE7QUFDTjtBQUFBLEVBQ0Y7QUFFQSxNQUFJLENBQUMsYUFBYSxlQUFlO0FBQy9CO0FBQUEsRUFDRjtBQUVBO0FBQUEsSUFDRSxzQkFBc0IsS0FBSyxlQUFlLGFBQWEsRUFBRTtBQUFBLEVBRTNEO0FBQ0EsUUFBTSxJQUFJLGlFQUEyQixhQUFhLEVBQUU7QUFDdEQ7QUFjQSxlQUFlLGVBQWUsUUFBNkM7QUFDekUsUUFBTSxFQUFFLE9BQU8sT0FBTyxpQkFBaUIsSUFBSTtBQUMzQyxNQUFJLEtBQUMsNENBQW1CLGdCQUFnQixHQUFHO0FBQ3pDO0FBQUEsRUFDRjtBQUVBLE1BQUk7QUFDRixVQUFNLFNBQVMsVUFBTSw0Q0FBbUI7QUFBQSxNQUN0QyxlQUFlLE9BQU87QUFBQSxNQUN0QiwwQkFBc0IsNkRBQW9DLGdCQUFnQjtBQUFBLElBQzVFLENBQUM7QUFDRCxRQUFJLE9BQU8sZUFBZSxLQUFLLE9BQU8sY0FBYyxHQUFHO0FBQ3JEO0FBQUEsUUFDRSxnQkFBZ0IsS0FBSyxJQUFJLEtBQUssV0FBVyxPQUFPLE9BQU8sWUFBWSxDQUFDLG1EQUMxQyxPQUFPLE9BQU8sV0FBVyxDQUFDO0FBQUEsTUFDdEQ7QUFBQSxJQUNGO0FBQUEsRUFDRixTQUFTLE9BQWdCO0FBQ3ZCLHdCQUFJLGdCQUFnQixLQUFLLElBQUksS0FBSywyQ0FBdUMsc0NBQWMsS0FBSyxDQUFDLEVBQUU7QUFBQSxFQUNqRztBQUNGO0FBT0EsZUFBZSxjQUFjLFFBQXdDO0FBQ25FLE1BQUk7QUFDRixVQUFNLE9BQU8sZUFBZSxRQUFRLE9BQU8sU0FBUztBQUFBLEVBQ3RELFNBQVMsT0FBZ0I7QUFDdkIsd0JBQUkseUJBQXlCLE9BQU8sY0FBYywwQ0FBc0Msc0NBQWMsS0FBSyxDQUFDLEVBQUU7QUFBQSxFQUNoSDtBQUVBLE1BQUk7QUFDRixVQUFNLE9BQU8sVUFBVSxVQUFVO0FBQUEsRUFDbkMsU0FBUyxPQUFnQjtBQUN2Qix3QkFBSSx5QkFBeUIsT0FBTyxjQUFjLDhDQUEwQyxzQ0FBYyxLQUFLLENBQUMsRUFBRTtBQUFBLEVBQ3BIO0FBQ0Y7IiwKICAibmFtZXMiOiBbImltcG9ydF9wcm9taXNlcyIsICJzbGVlcCIsICJwcm9jZXNzIl0KfQo=
@@ -26,8 +26,8 @@ export interface CoreSetupParams {
26
26
  * Whether to install and enable the built plugin in the temp vault. Defaults
27
27
  * to `true`. Set to `false` for a **non-plugin** consumer (e.g. a typings
28
28
  * crawler) that only needs a registered, empty vault to `evalInObsidian`
29
- * against: the plugin `dist`/`manifest.json` read, the copy into
30
- * `.obsidian/plugins`, the `community-plugins.json` write, and the enable step
29
+ * against: the plugin `dist`/`manifest.json` read, the copy into the config
30
+ * folder's `plugins/`, the `community-plugins.json` write, and the enable step
31
31
  * are all skipped, while the transport, temp vault, registration, and
32
32
  * worker-facing endpoint provisioning still run unchanged.
33
33
  */
@@ -37,6 +37,11 @@ export interface CoreSetupParams {
37
37
  * its startup scan indexes them in one pass (see {@link TemporaryVault.populate}).
38
38
  * Use this for large fixtures — writing thousands of notes after open and
39
39
  * forcing a re-scan is far slower and less reliable.
40
+ *
41
+ * Keys naming the config folder are written as `.obsidian/…`; under a
42
+ * `configDirectory` override {@link remapConfigDirectoryKeys} redirects them to
43
+ * the folder the vault will actually read, so a map does not have to carry a
44
+ * second copy of the override.
40
45
  */
41
46
  readonly populate?: PopulateFilesParams | undefined;
42
47
  /**
@@ -87,6 +92,26 @@ export declare function coreSetup(params?: CoreSetupParams): Promise<CoreSetupRe
87
92
  * @param result - The result from {@link coreSetup}. When `undefined`, does nothing.
88
93
  */
89
94
  export declare function coreTeardown(result?: CoreSetupResult): Promise<void>;
95
+ /**
96
+ * Redirects a populate map's config-folder entries to the folder the vault will actually read.
97
+ *
98
+ * A populate map names its destinations vault-relative, and everything that builds one — including
99
+ * `buildDemoVaultPopulate`, which seeds `.obsidian/*` config files and injected community plugins'
100
+ * binaries — writes them under a literal `.obsidian/`, because that is the folder Obsidian uses when nothing
101
+ * overrides it. Under a `configDirectory` override those entries land in a folder the vault never opens, and
102
+ * the plugins seeded that way come back as the generic "enabled but not loaded" with nothing naming a config
103
+ * folder. Rewriting the key here fixes every consumer at once — a hand-written map as much as a demo vault's
104
+ * — and needs no second copy of the override for a caller to keep in sync with their transport options.
105
+ *
106
+ * Safe rather than magic: the vault is one the harness made for this run and has exactly one config folder,
107
+ * so under an override a `.obsidian/` entry is dead weight nothing reads. Only a leading `.obsidian` path
108
+ * SEGMENT moves; a note whose name merely contains the string does not.
109
+ *
110
+ * @param populate - The consumer's populate map.
111
+ * @param configDirectory - The resolved override, or `undefined` for Obsidian's default (a no-op).
112
+ * @returns The map with its config-folder keys redirected, or the original map when there is nothing to move.
113
+ */
114
+ export declare function remapConfigDirectoryKeys(populate: PopulateFilesParams, configDirectory: string | undefined): PopulateFilesParams;
90
115
  /**
91
116
  * Resolves transport options for an integration run.
92
117
  *