sonamu 0.9.19 → 0.10.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 (282) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +36 -0
  2. package/dist/ai/agents/agent.js +5 -7
  3. package/dist/ai/agents/index.js +1 -2
  4. package/dist/ai/agents/types.js +1 -1
  5. package/dist/ai/index.js +1 -2
  6. package/dist/ai/providers/rtzr/api.js +2 -3
  7. package/dist/ai/providers/rtzr/error.js +14 -29
  8. package/dist/ai/providers/rtzr/index.js +1 -2
  9. package/dist/ai/providers/rtzr/model.js +13 -20
  10. package/dist/ai/providers/rtzr/options.js +2 -3
  11. package/dist/ai/providers/rtzr/provider.js +2 -3
  12. package/dist/ai/providers/rtzr/utils.js +12 -21
  13. package/dist/api/base-frame.js +4 -4
  14. package/dist/api/caster.js +21 -38
  15. package/dist/api/code-converters.js +41 -98
  16. package/dist/api/config.d.ts +1 -10
  17. package/dist/api/config.d.ts.map +1 -1
  18. package/dist/api/config.js +9 -8
  19. package/dist/api/context.js +2 -3
  20. package/dist/api/decorators.js +80 -116
  21. package/dist/api/index.js +2 -3
  22. package/dist/api/secret.js +6 -10
  23. package/dist/api/sonamu.d.ts.map +1 -1
  24. package/dist/api/sonamu.js +200 -387
  25. package/dist/api/validator.js +5 -8
  26. package/dist/api/websocket-helpers.js +21 -32
  27. package/dist/auth/audit-log/builders.js +2 -3
  28. package/dist/auth/audit-log/events.js +2 -2
  29. package/dist/auth/audit-log/plugin.js +30 -61
  30. package/dist/auth/audit-log-ingestor.js +19 -41
  31. package/dist/auth/auth-generator.js +16 -41
  32. package/dist/auth/better-auth-entities.js +3 -4
  33. package/dist/auth/index.js +2 -3
  34. package/dist/auth/knex-adapter.js +18 -45
  35. package/dist/auth/plugins/entity-definitions/admin.js +2 -2
  36. package/dist/auth/plugins/entity-definitions/anonymous.js +2 -2
  37. package/dist/auth/plugins/entity-definitions/api-key.js +2 -2
  38. package/dist/auth/plugins/entity-definitions/audit-log.js +2 -2
  39. package/dist/auth/plugins/entity-definitions/index.js +2 -3
  40. package/dist/auth/plugins/entity-definitions/jwt.js +2 -2
  41. package/dist/auth/plugins/entity-definitions/organization.js +2 -2
  42. package/dist/auth/plugins/entity-definitions/passkey.js +2 -2
  43. package/dist/auth/plugins/entity-definitions/phone-number.js +2 -2
  44. package/dist/auth/plugins/entity-definitions/sso.js +2 -2
  45. package/dist/auth/plugins/entity-definitions/two-factor.js +2 -2
  46. package/dist/auth/plugins/entity-definitions/types.js +1 -1
  47. package/dist/auth/plugins/entity-definitions/username.js +2 -2
  48. package/dist/auth/plugins/index.js +1 -2
  49. package/dist/auth/plugins/wrappers/admin.js +2 -3
  50. package/dist/auth/plugins/wrappers/anonymous.js +2 -3
  51. package/dist/auth/plugins/wrappers/api-key.js +2 -3
  52. package/dist/auth/plugins/wrappers/index.js +1 -2
  53. package/dist/auth/plugins/wrappers/jwt.js +2 -3
  54. package/dist/auth/plugins/wrappers/organization.js +2 -3
  55. package/dist/auth/plugins/wrappers/passkey.js +2 -3
  56. package/dist/auth/plugins/wrappers/phone-number.js +2 -3
  57. package/dist/auth/plugins/wrappers/sso.js +2 -3
  58. package/dist/auth/plugins/wrappers/two-factor.js +2 -3
  59. package/dist/auth/plugins/wrappers/username.js +2 -3
  60. package/dist/bin/build-config.js +2 -2
  61. package/dist/bin/cli.js +151 -258
  62. package/dist/bin/fixture.d.ts.map +1 -1
  63. package/dist/bin/fixture.js +55 -97
  64. package/dist/bin/hmr-hook-register.js +3 -3
  65. package/dist/bin/migrate-targets.d.ts +3 -0
  66. package/dist/bin/migrate-targets.d.ts.map +1 -0
  67. package/dist/bin/migrate-targets.js +11 -0
  68. package/dist/bin/test-command.js +25 -55
  69. package/dist/bin/ts-loader-register.js +5 -6
  70. package/dist/bin/ts-loader-registration.js +6 -13
  71. package/dist/cache/cache-manager.js +3 -4
  72. package/dist/cache/decorator.js +11 -21
  73. package/dist/cache/drivers.js +2 -3
  74. package/dist/cache/index.js +2 -3
  75. package/dist/cache/types.js +1 -1
  76. package/dist/cache-control/cache-control.js +21 -34
  77. package/dist/cache-control/types.js +1 -1
  78. package/dist/compress/compress.js +10 -10
  79. package/dist/compress/index.js +1 -2
  80. package/dist/compress/types.js +1 -1
  81. package/dist/cone/cone-generator.js +25 -63
  82. package/dist/database/_batch_update.js +26 -46
  83. package/dist/database/base-model.js +44 -97
  84. package/dist/database/base-model.types.js +1 -1
  85. package/dist/database/db.d.ts +8 -14
  86. package/dist/database/db.d.ts.map +1 -1
  87. package/dist/database/db.js +127 -72
  88. package/dist/database/knex.js +5 -8
  89. package/dist/database/puri-subset.types.js +1 -1
  90. package/dist/database/puri-wrapper.js +11 -15
  91. package/dist/database/puri.js +117 -234
  92. package/dist/database/puri.types.js +3 -4
  93. package/dist/database/transaction-context.js +4 -5
  94. package/dist/database/upsert-builder.js +109 -176
  95. package/dist/dict/en.d.ts +1 -0
  96. package/dist/dict/en.d.ts.map +1 -1
  97. package/dist/dict/en.js +4 -4
  98. package/dist/dict/index.js +2 -3
  99. package/dist/dict/ko.d.ts +1 -0
  100. package/dist/dict/ko.d.ts.map +1 -1
  101. package/dist/dict/ko.js +4 -4
  102. package/dist/dict/rc-keys.js +3 -4
  103. package/dist/dict/sd.js +8 -19
  104. package/dist/dict/sonamu-dictionary.js +141 -284
  105. package/dist/dict/types.js +1 -1
  106. package/dist/dict/utils.js +4 -5
  107. package/dist/entity/entity-manager.d.ts +2 -2
  108. package/dist/entity/entity-manager.js +34 -82
  109. package/dist/entity/entity-template-cone.js +33 -66
  110. package/dist/entity/entity.js +156 -310
  111. package/dist/env.d.ts +14 -0
  112. package/dist/env.d.ts.map +1 -0
  113. package/dist/env.js +75 -0
  114. package/dist/exceptions/error-handler.js +2 -3
  115. package/dist/exceptions/so-exceptions.js +7 -5
  116. package/dist/filter/index.js +1 -2
  117. package/dist/filter/types.js +3 -4
  118. package/dist/filter/utils.js +21 -54
  119. package/dist/index.js +8 -7
  120. package/dist/logger/category.js +6 -12
  121. package/dist/logger/configure.js +23 -34
  122. package/dist/migration/code-generation.js +146 -314
  123. package/dist/migration/index-where-predicate.js +52 -144
  124. package/dist/migration/migration-set.js +19 -33
  125. package/dist/migration/migrator.d.ts +2 -0
  126. package/dist/migration/migrator.d.ts.map +1 -1
  127. package/dist/migration/migrator.js +69 -53
  128. package/dist/migration/postgresql-schema-reader.js +126 -225
  129. package/dist/migration/slack-confirm.d.ts +1 -0
  130. package/dist/migration/slack-confirm.d.ts.map +1 -1
  131. package/dist/migration/slack-confirm.js +28 -38
  132. package/dist/migration/types.js +1 -1
  133. package/dist/naite/messaging-types.js +1 -1
  134. package/dist/naite/naite-reporter.js +15 -32
  135. package/dist/naite/naite.js +43 -76
  136. package/dist/ssr/index.js +6 -9
  137. package/dist/ssr/registry.js +10 -18
  138. package/dist/ssr/renderer.js +10 -21
  139. package/dist/ssr/types.js +1 -1
  140. package/dist/storage/base-file.js +5 -10
  141. package/dist/storage/buffered-file.js +3 -4
  142. package/dist/storage/drivers.js +2 -3
  143. package/dist/storage/index.js +2 -3
  144. package/dist/storage/s3-driver.js +5 -9
  145. package/dist/storage/storage-manager.js +5 -5
  146. package/dist/storage/types.js +1 -1
  147. package/dist/storage/uploaded-file.js +4 -6
  148. package/dist/stream/index.js +1 -2
  149. package/dist/stream/sse.js +8 -13
  150. package/dist/stream/ws-audience-resolver.js +5 -5
  151. package/dist/stream/ws-audience.js +3 -4
  152. package/dist/stream/ws-cluster-bus.js +3 -4
  153. package/dist/stream/ws-core.js +1 -1
  154. package/dist/stream/ws-delivery.js +11 -25
  155. package/dist/stream/ws-local-connection-store.js +9 -18
  156. package/dist/stream/ws-presence-store.js +43 -97
  157. package/dist/stream/ws-registry.js +17 -22
  158. package/dist/stream/ws-telemetry-memory.js +38 -45
  159. package/dist/stream/ws-telemetry-trace.js +4 -6
  160. package/dist/stream/ws-telemetry.js +82 -135
  161. package/dist/stream/ws.js +47 -91
  162. package/dist/syncer/api-parser.js +81 -147
  163. package/dist/syncer/checksum.js +9 -20
  164. package/dist/syncer/code-generator.js +29 -47
  165. package/dist/syncer/entity-operations.js +17 -27
  166. package/dist/syncer/event-batcher.js +8 -15
  167. package/dist/syncer/file-patterns.js +3 -4
  168. package/dist/syncer/file-tracking.js +6 -10
  169. package/dist/syncer/index.js +1 -2
  170. package/dist/syncer/module-loader.js +10 -26
  171. package/dist/syncer/syncer-actions.js +19 -37
  172. package/dist/syncer/syncer.js +46 -98
  173. package/dist/syncer/watcher.js +12 -26
  174. package/dist/tasks/decorator.js +7 -11
  175. package/dist/tasks/step-wrapper.js +7 -8
  176. package/dist/tasks/workflow-manager.js +18 -25
  177. package/dist/template/entity-converter.js +40 -64
  178. package/dist/template/helpers.js +32 -63
  179. package/dist/template/implementations/entity.template.js +7 -11
  180. package/dist/template/implementations/entry-server.template.js +2 -3
  181. package/dist/template/implementations/generated.template.js +25 -51
  182. package/dist/template/implementations/generated_http.template.js +31 -58
  183. package/dist/template/implementations/generated_sso.template.js +45 -85
  184. package/dist/template/implementations/init_types.template.js +4 -7
  185. package/dist/template/implementations/model.template.js +5 -10
  186. package/dist/template/implementations/model_test.template.js +2 -3
  187. package/dist/template/implementations/queries.template.js +4 -7
  188. package/dist/template/implementations/sd.template.js +17 -35
  189. package/dist/template/implementations/services.template.js +18 -30
  190. package/dist/template/implementations/view_form.template.js +72 -125
  191. package/dist/template/implementations/view_id_all_select.template.js +2 -3
  192. package/dist/template/implementations/view_list.template.js +86 -143
  193. package/dist/template/implementations/view_search_input.template.js +2 -3
  194. package/dist/template/index.js +5 -8
  195. package/dist/template/template-manager.js +13 -26
  196. package/dist/template/template-types.js +2 -3
  197. package/dist/template/template.js +7 -11
  198. package/dist/template/zod-converter.js +173 -348
  199. package/dist/testing/_relation-graph.js +18 -37
  200. package/dist/testing/bootstrap.js +5 -8
  201. package/dist/testing/data-explorer.js +34 -78
  202. package/dist/testing/dev-test-routes.js +54 -60
  203. package/dist/testing/dev-vitest-manager.js +33 -84
  204. package/dist/testing/faker-mappings.js +3 -4
  205. package/dist/testing/fixture-generator.d.ts +2 -1
  206. package/dist/testing/fixture-generator.d.ts.map +1 -1
  207. package/dist/testing/fixture-generator.js +159 -321
  208. package/dist/testing/fixture-loader.js +2 -2
  209. package/dist/testing/fixture-manager.d.ts.map +1 -1
  210. package/dist/testing/fixture-manager.js +124 -227
  211. package/dist/testing/global-setup.d.ts.map +1 -1
  212. package/dist/testing/global-setup.js +29 -17
  213. package/dist/testing/index.js +1 -2
  214. package/dist/testing/naite-vitest-reporter.js +2 -3
  215. package/dist/testing/parallel-db-manager.js +5 -3
  216. package/dist/testing/vitest-helpers.d.ts.map +1 -1
  217. package/dist/testing/vitest-helpers.js +15 -12
  218. package/dist/types/types.d.ts +14 -14
  219. package/dist/types/types.js +27 -50
  220. package/dist/ui/ai-api.js +6 -11
  221. package/dist/ui/ai-client.js +86 -134
  222. package/dist/ui/api.js +99 -195
  223. package/dist/ui/cdd-service.js +78 -130
  224. package/dist/ui/cdd-types.js +1 -1
  225. package/dist/ui-web/assets/{index-Df8q-fhb.js → index-DFStGyd0.js} +49 -49
  226. package/dist/ui-web/assets/index-Dx4ap5i4.css +1 -0
  227. package/dist/ui-web/index.html +2 -2
  228. package/dist/utils/async-utils.js +13 -25
  229. package/dist/utils/class-name.js +3 -4
  230. package/dist/utils/console-util.js +11 -26
  231. package/dist/utils/controller.d.ts.map +1 -1
  232. package/dist/utils/controller.js +14 -12
  233. package/dist/utils/esm-utils.js +5 -8
  234. package/dist/utils/formatter.js +10 -22
  235. package/dist/utils/fs-utils.js +14 -25
  236. package/dist/utils/lodash-able.js +3 -4
  237. package/dist/utils/model.js +7 -14
  238. package/dist/utils/object-utils.js +41 -73
  239. package/dist/utils/path-utils.js +5 -9
  240. package/dist/utils/process-utils.js +4 -7
  241. package/dist/utils/sql-parser.js +6 -13
  242. package/dist/utils/type-utils.js +16 -26
  243. package/dist/utils/utils.js +18 -40
  244. package/dist/utils/zod-error.js +9 -16
  245. package/dist/vector/chunking.js +24 -37
  246. package/dist/vector/config.js +2 -2
  247. package/dist/vector/embedding.js +8 -19
  248. package/dist/vector/index.js +1 -2
  249. package/dist/vector/types.js +1 -1
  250. package/package.json +7 -7
  251. package/src/__tests__/env.test.ts +127 -0
  252. package/src/api/__tests__/config.test.ts +10 -1
  253. package/src/api/config.ts +4 -12
  254. package/src/api/sonamu.ts +14 -4
  255. package/src/bin/__tests__/migrate-targets.test.ts +28 -0
  256. package/src/bin/__tests__/test-command.test.ts +82 -1
  257. package/src/bin/cli.ts +9 -18
  258. package/src/bin/fixture.ts +5 -4
  259. package/src/bin/migrate-targets.ts +7 -0
  260. package/src/bin/test-command.ts +2 -2
  261. package/src/database/__tests__/db.test.ts +175 -0
  262. package/src/database/db.ts +193 -71
  263. package/src/dict/en.ts +2 -0
  264. package/src/dict/ko.ts +2 -0
  265. package/src/env.ts +123 -0
  266. package/src/migration/__tests__/migrator.test.ts +149 -0
  267. package/src/migration/migrator.ts +74 -17
  268. package/src/migration/slack-confirm.ts +21 -0
  269. package/src/skills/sonamu/database.md +1 -1
  270. package/src/skills/sonamu/entity-basic.md +31 -0
  271. package/src/skills/sonamu/puri.md +22 -0
  272. package/src/skills/sonamu/testing-devrunner.md +1 -1
  273. package/src/skills/sonamu/upsert.md +53 -6
  274. package/src/stream/ws-telemetry-memory.ts +2 -2
  275. package/src/testing/fixture-generator.ts +2 -1
  276. package/src/testing/fixture-manager.ts +3 -4
  277. package/src/testing/global-setup.ts +42 -18
  278. package/src/testing/vitest-helpers.ts +14 -0
  279. package/src/utils/controller.ts +14 -7
  280. package/tsdown.api.config.ts +6 -0
  281. package/dist/_virtual/rolldown_runtime.js +0 -39
  282. package/dist/ui-web/assets/index-D4rYm-Xz.css +0 -1
@@ -1,4 +1,4 @@
1
- import { __esmMin } from "../_virtual/rolldown_runtime.js";
1
+ import { __esmMin } from "../_virtual/_rolldown/runtime.js";
2
2
  import { formatCode, init_formatter } from "../utils/formatter.js";
3
3
  import { exists, init_fs_utils } from "../utils/fs-utils.js";
4
4
  import { assertDefined, init_utils, nonNullable } from "../utils/utils.js";
@@ -11,9 +11,8 @@ import inflection from "inflection";
11
11
  import { z as z$1 } from "zod";
12
12
  import { group, unique } from "radashi";
13
13
  import assert from "assert";
14
- import { writeFile } from "fs/promises";
15
14
  import path from "path";
16
-
15
+ import { writeFile } from "fs/promises";
17
16
  //#region src/entity/entity.ts
18
17
  var Entity;
19
18
  var init_entity = __esmMin((() => {
@@ -52,9 +51,7 @@ var init_entity = __esmMin((() => {
52
51
  if (props) {
53
52
  this.props = props.map((prop) => {
54
53
  if (isEnumProp(prop)) {
55
- if (prop.id.includes("$Model")) {
56
- prop.id = prop.id.replace("$Model", id);
57
- }
54
+ if (prop.id.includes("$Model")) prop.id = prop.id.replace("$Model", id);
58
55
  }
59
56
  return prop;
60
57
  });
@@ -74,14 +71,10 @@ var init_entity = __esmMin((() => {
74
71
  const fields = getSubsetFields(subsetDef);
75
72
  this.subsets[key] = fields.filter((f) => !isInternalSubsetField(f)).map(normalizeSubsetField);
76
73
  this.subsetsInternal[key] = fields.filter(isInternalSubsetField).map(normalizeSubsetField);
77
- if (!Array.isArray(subsetDef) && "cone" in subsetDef && subsetDef.cone) {
78
- this.subsetCones[key] = subsetDef.cone;
79
- }
74
+ if (!Array.isArray(subsetDef) && "cone" in subsetDef && subsetDef.cone) this.subsetCones[key] = subsetDef.cone;
80
75
  }
81
76
  this.enumLabels = Object.fromEntries(Object.entries(enums ?? {}).map(([key, enumDef]) => {
82
- if ("values" in enumDef && "cone" in enumDef && enumDef.cone) {
83
- this.enumCones[key] = enumDef.cone;
84
- }
77
+ if ("values" in enumDef && "cone" in enumDef && enumDef.cone) this.enumCones[key] = enumDef.cone;
85
78
  return [key, getEnumDefValues(enumDef)];
86
79
  }));
87
80
  this.enums = Object.fromEntries(Object.entries(this.enumLabels).map(([key, enumLabel]) => {
@@ -108,13 +101,10 @@ var init_entity = __esmMin((() => {
108
101
  const lines = [];
109
102
  lines.push(`return qbWrapper`);
110
103
  lines.push(`.from("${this.table}")`);
111
- for (const join$1 of subsetQuery.joins) {
112
- const joinMethod = join$1.join === "inner" ? "join" : "leftJoin";
113
- if ("custom" in join$1) {
114
- lines.push(`.${joinMethod}({ ${join$1.as}: "${join$1.table}" }, qbWrapper.knex.raw(\`${join$1.custom}\`))`);
115
- } else {
116
- lines.push(`.${joinMethod}({ ${join$1.as}: "${join$1.table}" }, "${join$1.from}", "${join$1.to}")`);
117
- }
104
+ for (const join of subsetQuery.joins) {
105
+ const joinMethod = join.join === "inner" ? "join" : "leftJoin";
106
+ if ("custom" in join) lines.push(`.${joinMethod}({ ${join.as}: "${join.table}" }, qbWrapper.knex.raw(\`${join.custom}\`))`);
107
+ else lines.push(`.${joinMethod}({ ${join.as}: "${join.table}" }, "${join.from}", "${join.to}")`);
118
108
  }
119
109
  const selectObj = this.buildNestedSelectObject(subsetQuery.select);
120
110
  lines.push(`.select(${this.stringifyNestedSelectObject(selectObj)});`);
@@ -147,12 +137,8 @@ var init_entity = __esmMin((() => {
147
137
  for (let i = 0; i < parts.length - 1; i++) {
148
138
  const part = parts[i];
149
139
  if (part in current) {
150
- if (typeof current[part] === "string") {
151
- throw new Error(`Conflict detected in select items: parent path "${parts.slice(0, i + 1).join("__")}" is already set as a field, cannot nest "${alias}" under it.`);
152
- }
153
- } else {
154
- current[part] = {};
155
- }
140
+ if (typeof current[part] === "string") throw new Error(`Conflict detected in select items: parent path "${parts.slice(0, i + 1).join("__")}" is already set as a field, cannot nest "${alias}" under it.`);
141
+ } else current[part] = {};
156
142
  current = current[part];
157
143
  }
158
144
  const lastPart = parts[parts.length - 1];
@@ -185,60 +171,45 @@ var init_entity = __esmMin((() => {
185
171
  const entries = Object.entries(obj);
186
172
  if (entries.length === 0) return withBraces ? "{}" : "";
187
173
  const lines = entries.map(([key, value]) => {
188
- if (typeof value === "string") {
189
- return `${innerSpaces}${key}: ${value},`;
190
- } else {
191
- return `${innerSpaces}${key}: ${this.stringifyNestedSelectObject(value, indent + 1, true)},`;
192
- }
174
+ if (typeof value === "string") return `${innerSpaces}${key}: ${value},`;
175
+ else return `${innerSpaces}${key}: ${this.stringifyNestedSelectObject(value, indent + 1, true)},`;
193
176
  });
194
- if (withBraces) {
195
- return `{\n${lines.join("\n")}\n${spaces}}`;
196
- } else {
197
- return lines.join("\n");
198
- }
177
+ if (withBraces) return `{\n${lines.join("\n")}\n${spaces}}`;
178
+ else return lines.join("\n");
199
179
  }
200
180
  getPuriLoaderQuery(subsetKey) {
201
181
  const subset = this.getSubsetFieldsForQuery(subsetKey);
202
182
  const { loaders } = this.resolveSubsetQuery("", subset);
203
183
  const lines = [`[`];
204
- const generateLoaderCode = (loaders$1) => {
184
+ const generateLoaderCode = (loaders) => {
205
185
  const loaderLines = [];
206
- for (const loader of loaders$1) {
186
+ for (const loader of loaders) {
207
187
  const { toTable, toCol, through, fromTable } = loader.manyJoin;
208
- const fromEntity = EntityManager.getByTable(fromTable);
209
- const fromIdsType = fromEntity.getPkArrayType();
188
+ const fromIdsType = EntityManager.getByTable(fromTable).getPkArrayType();
210
189
  loaderLines.push("{", `as: "${loader.as}",`, `refId: "${loader.manyJoin.idField}",`, `qb: (qbWrapper: PuriWrapper<DatabaseSchemaExtend>, fromIds: number[] | string[]) => {`);
211
- if (through === undefined) {
190
+ if (through === void 0) {
212
191
  loaderLines.push("return qbWrapper", `.from("${toTable}")`);
213
- loader.oneJoins.forEach((join$1) => {
214
- const joinMethod = join$1.join === "inner" ? "join" : "leftJoin";
215
- if ("custom" in join$1) {
216
- loaderLines.push(`.${joinMethod}({ ${join$1.as}: "${join$1.table}" }, (j) => {`, `j.on(Puri.rawString("${join$1.custom}"));`, "})");
217
- } else {
218
- loaderLines.push(`.${joinMethod}({ ${join$1.as}: "${join$1.table}" }, "${join$1.from}", "${join$1.to}")`);
219
- }
192
+ loader.oneJoins.forEach((join) => {
193
+ const joinMethod = join.join === "inner" ? "join" : "leftJoin";
194
+ if ("custom" in join) loaderLines.push(`.${joinMethod}({ ${join.as}: "${join.table}" }, (j) => {`, `j.on(Puri.rawString("${join.custom}"));`, "})");
195
+ else loaderLines.push(`.${joinMethod}({ ${join.as}: "${join.table}" }, "${join.from}", "${join.to}")`);
220
196
  });
221
197
  const selectObj = this.buildNestedSelectObject(loader.select);
222
198
  selectObj.refId = `"${toTable}.${toCol}"`;
223
199
  loaderLines.push(`.whereIn("${toTable}.${toCol}", fromIds as ${fromIdsType})`, `.select(${this.stringifyNestedSelectObject(selectObj)});`);
224
200
  } else {
225
201
  loaderLines.push("return qbWrapper", `.from("${through.table}")`, `.join("${toTable}", "${through.table}.${through.toCol}", "${toTable}.${toCol}")`);
226
- loader.oneJoins.forEach((join$1) => {
227
- const joinMethod = join$1.join === "inner" ? "join" : "leftJoin";
228
- if ("custom" in join$1) {
229
- loaderLines.push(`.${joinMethod}({ ${join$1.as}: "${join$1.table}" }, (j) => {`, `j.on(Puri.rawString("${join$1.custom}"));`, "})");
230
- } else {
231
- loaderLines.push(`.${joinMethod}({ ${join$1.as}: "${join$1.table}" }, "${join$1.from}", "${join$1.to}")`);
232
- }
202
+ loader.oneJoins.forEach((join) => {
203
+ const joinMethod = join.join === "inner" ? "join" : "leftJoin";
204
+ if ("custom" in join) loaderLines.push(`.${joinMethod}({ ${join.as}: "${join.table}" }, (j) => {`, `j.on(Puri.rawString("${join.custom}"));`, "})");
205
+ else loaderLines.push(`.${joinMethod}({ ${join.as}: "${join.table}" }, "${join.from}", "${join.to}")`);
233
206
  });
234
207
  const selectObj = this.buildNestedSelectObject(loader.select);
235
208
  selectObj.refId = `"${through.table}.${through.fromCol}"`;
236
209
  loaderLines.push(`.whereIn("${through.table}.${through.fromCol}", fromIds as ${fromIdsType})`, `.select(${this.stringifyNestedSelectObject(selectObj)});`);
237
210
  }
238
211
  loaderLines.push(`},`);
239
- if (loader.loaders && loader.loaders.length > 0) {
240
- loaderLines.push("loaders: [", ...generateLoaderCode(loader.loaders), "],");
241
- }
212
+ if (loader.loaders && loader.loaders.length > 0) loaderLines.push("loaders: [", ...generateLoaderCode(loader.loaders), "],");
242
213
  loaderLines.push("},");
243
214
  }
244
215
  return loaderLines;
@@ -249,8 +220,7 @@ var init_entity = __esmMin((() => {
249
220
  }
250
221
  getSubsetQuery(subsetKey) {
251
222
  const subset = this.getSubsetFieldsForQuery(subsetKey);
252
- const result = this.resolveSubsetQuery("", subset);
253
- return result;
223
+ return this.resolveSubsetQuery("", subset);
254
224
  }
255
225
  resolveSubsetQuery(prefix, fields, isAlreadyOuterJoined = false) {
256
226
  prefix = prefix.replace(/\./g, "__");
@@ -258,56 +228,36 @@ var init_entity = __esmMin((() => {
258
228
  if (field.includes(".")) {
259
229
  const [rel] = field.split(".");
260
230
  return rel;
261
- } else {
262
- return "";
263
- }
231
+ } else return "";
264
232
  });
265
- const result = Object.keys(subsetGroup).reduce((r, groupKey) => {
266
- const fields$1 = subsetGroup[groupKey];
267
- assert(fields$1 !== undefined, "fields is undefined");
233
+ return Object.keys(subsetGroup).reduce((r, groupKey) => {
234
+ const fields = subsetGroup[groupKey];
235
+ assert(fields !== void 0, "fields is undefined");
268
236
  if (groupKey === "") {
269
- const realFields = fields$1.filter((field) => !isVirtualProp(this.propsDict[field]));
270
- const virtualCodeFields = fields$1.filter((field) => isVirtualCodeProp(this.propsDict[field]));
237
+ const realFields = fields.filter((field) => !isVirtualProp(this.propsDict[field]));
238
+ const virtualCodeFields = fields.filter((field) => isVirtualCodeProp(this.propsDict[field]));
271
239
  if (prefix === "") {
272
240
  r.select = r.select.concat(realFields.map((field) => this.getFullFieldName(field)));
273
241
  r.virtual = r.virtual.concat(virtualCodeFields);
274
- } else {
275
- r.select = r.select.concat(realFields.map((field) => `${prefix}.${field} as ${prefix}__${field}`));
276
- }
242
+ } else r.select = r.select.concat(realFields.map((field) => `${prefix}.${field} as ${prefix}__${field}`));
277
243
  return r;
278
244
  }
279
245
  const relation = this.relations[groupKey];
280
- if (relation === undefined) {
281
- throw new Error(`존재하지 않는 relation 참조 ${groupKey}`);
282
- }
246
+ if (relation === void 0) throw new Error(`존재하지 않는 relation 참조 ${groupKey}`);
283
247
  const relEntity = EntityManager.get(relation.with);
284
248
  if (isOneToOneRelationProp(relation) || isBelongsToOneRelationProp(relation)) {
285
- const relFields = fields$1.map((field) => field.split(".").slice(1).join("."));
249
+ const relFields = fields.map((field) => field.split(".").slice(1).join("."));
286
250
  if (relFields.length === 1 && relFields[0] === "id") {
287
- if (prefix === "") {
288
- r.select = r.select.concat(`${this.table}.${groupKey}_id`);
289
- } else {
290
- r.select = r.select.concat(`${prefix}.${groupKey}_id as ${prefix}__${groupKey}_id`);
291
- }
251
+ if (prefix === "") r.select = r.select.concat(`${this.table}.${groupKey}_id`);
252
+ else r.select = r.select.concat(`${prefix}.${groupKey}_id as ${prefix}__${groupKey}_id`);
292
253
  return r;
293
254
  }
294
255
  const innerOrOuter = (() => {
295
- if (isAlreadyOuterJoined) {
296
- return "outer";
297
- }
298
- if (isOneToOneRelationProp(relation)) {
299
- if (relation.hasJoinColumn && !(relation.nullable ?? false)) {
300
- return "inner";
301
- } else {
302
- return "outer";
303
- }
304
- } else {
305
- if (relation.nullable) {
306
- return "outer";
307
- } else {
308
- return "inner";
309
- }
310
- }
256
+ if (isAlreadyOuterJoined) return "outer";
257
+ if (isOneToOneRelationProp(relation)) if (relation.hasJoinColumn && !(relation.nullable ?? false)) return "inner";
258
+ else return "outer";
259
+ else if (relation.nullable) return "outer";
260
+ else return "inner";
311
261
  })();
312
262
  const relSubsetQuery = relEntity.resolveSubsetQuery(`${prefix !== "" ? `${prefix}.` : ""}${groupKey}`, relFields, innerOrOuter === "outer");
313
263
  r.select = r.select.concat(relSubsetQuery.select);
@@ -315,19 +265,17 @@ var init_entity = __esmMin((() => {
315
265
  const joinAs = prefix === "" ? groupKey : `${prefix}__${groupKey}`;
316
266
  const fromTable = prefix === "" ? this.table : prefix;
317
267
  let joinClause;
318
- if (relation.customJoinClause) {
319
- joinClause = { custom: relation.customJoinClause };
320
- } else {
268
+ if (relation.customJoinClause) joinClause = { custom: relation.customJoinClause };
269
+ else {
321
270
  let from, to;
322
- if (isOneToOneRelationProp(relation)) {
323
- if (relation.hasJoinColumn) {
324
- from = `${fromTable}.${relation.name}_id`;
325
- to = `${joinAs}.id`;
326
- } else {
327
- from = `${fromTable}.id`;
328
- to = `${joinAs}.${inflection.underscore(this.names.fs.replace(/-/g, "_"))}_id`;
329
- }
271
+ if (isOneToOneRelationProp(relation)) if (relation.hasJoinColumn) {
272
+ from = `${fromTable}.${relation.name}_id`;
273
+ to = `${joinAs}.id`;
330
274
  } else {
275
+ from = `${fromTable}.id`;
276
+ to = `${joinAs}.${inflection.underscore(this.names.fs.replace(/-/g, "_"))}_id`;
277
+ }
278
+ else {
331
279
  from = `${fromTable}.${relation.name}_id`;
332
280
  to = `${joinAs}.id`;
333
281
  }
@@ -344,9 +292,8 @@ var init_entity = __esmMin((() => {
344
292
  });
345
293
  if (relSubsetQuery.loaders.length > 0) {
346
294
  const convertedLoaders = relSubsetQuery.loaders.map((loader) => {
347
- const newAs = [groupKey, loader.as].join("__");
348
295
  return {
349
- as: newAs,
296
+ as: [groupKey, loader.as].join("__"),
350
297
  table: loader.table,
351
298
  manyJoin: loader.manyJoin,
352
299
  oneJoins: loader.oneJoins,
@@ -358,7 +305,7 @@ var init_entity = __esmMin((() => {
358
305
  }
359
306
  r.joins = r.joins.concat(relSubsetQuery.joins);
360
307
  } else if (isHasManyRelationProp(relation) || isManyToManyRelationProp(relation)) {
361
- const relFields = fields$1.map((field) => field.split(".").slice(1).join("."));
308
+ const relFields = fields.map((field) => field.split(".").slice(1).join("."));
362
309
  const relSubsetQuery = relEntity.resolveSubsetQuery("", relFields);
363
310
  let manyJoin;
364
311
  if (isHasManyRelationProp(relation)) {
@@ -370,22 +317,19 @@ var init_entity = __esmMin((() => {
370
317
  toTable: relEntity.table,
371
318
  toCol: relation.joinColumn
372
319
  };
373
- } else if (isManyToManyRelationProp(relation)) {
374
- manyJoin = {
375
- fromTable: this.table,
376
- fromCol: "id",
377
- idField: prefix === "" ? `id` : `${prefix}__id`,
378
- through: {
379
- table: relation.joinTable,
380
- fromCol: `${inflection.singularize(this.table)}_id`,
381
- toCol: `${inflection.singularize(relEntity.table)}_id`
382
- },
383
- toTable: relEntity.table,
384
- toCol: "id"
385
- };
386
- } else {
387
- throw new Error();
388
- }
320
+ } else if (isManyToManyRelationProp(relation)) manyJoin = {
321
+ fromTable: this.table,
322
+ fromCol: "id",
323
+ idField: prefix === "" ? `id` : `${prefix}__id`,
324
+ through: {
325
+ table: relation.joinTable,
326
+ fromCol: `${inflection.singularize(this.table)}_id`,
327
+ toCol: `${inflection.singularize(relEntity.table)}_id`
328
+ },
329
+ toTable: relEntity.table,
330
+ toCol: "id"
331
+ };
332
+ else throw new Error();
389
333
  r.loaders.push({
390
334
  as: groupKey,
391
335
  table: relEntity.table,
@@ -402,7 +346,6 @@ var init_entity = __esmMin((() => {
402
346
  joins: [],
403
347
  loaders: []
404
348
  });
405
- return result;
406
349
  }
407
350
  fieldExprsToPropNodes(fieldExprs, entity = this) {
408
351
  const groups = fieldExprs.reduce((result, fieldExpr) => {
@@ -418,41 +361,31 @@ var init_entity = __esmMin((() => {
418
361
  return result;
419
362
  }, {});
420
363
  return Object.keys(groups).flatMap((key) => {
421
- const group$1 = groups[key];
422
- if (key === "") {
423
- return group$1.map((propName) => {
424
- const prop$1 = entity.props.find((p) => p.name === propName);
425
- if (prop$1 === undefined) {
426
- throw new Error(`${entity.id} -- 잘못된 FieldExpr '${propName}' (사용 가능한 props: ${entity.props.map((p) => p.name).join(", ")})`);
427
- }
428
- return {
429
- nodeType: "plain",
430
- prop: prop$1
431
- };
432
- });
433
- }
364
+ const group = groups[key];
365
+ if (key === "") return group.map((propName) => {
366
+ const prop = entity.props.find((p) => p.name === propName);
367
+ if (prop === void 0) throw new Error(`${entity.id} -- 잘못된 FieldExpr '${propName}' (사용 가능한 props: ${entity.props.map((p) => p.name).join(", ")})`);
368
+ return {
369
+ nodeType: "plain",
370
+ prop
371
+ };
372
+ });
434
373
  const prop = entity.propsDict[key];
435
- if (!isRelationProp(prop)) {
436
- throw new Error(`잘못된 FieldExpr ${key}.${group$1[0]}`);
437
- }
374
+ if (!isRelationProp(prop)) throw new Error(`잘못된 FieldExpr ${key}.${group[0]}`);
438
375
  const relEntity = EntityManager.get(prop.with);
439
376
  if (isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop)) {
440
- if (group$1.length === 1 && (group$1[0] === "id" || group$1[0] === "id?")) {
441
- const idProp = relEntity.propsDict.id;
442
- return {
443
- nodeType: "plain",
444
- prop: {
445
- ...idProp,
446
- name: `${key}_id`,
447
- nullable: prop.nullable
448
- }
449
- };
450
- }
377
+ if (group.length === 1 && (group[0] === "id" || group[0] === "id?")) return {
378
+ nodeType: "plain",
379
+ prop: {
380
+ ...relEntity.propsDict.id,
381
+ name: `${key}_id`,
382
+ nullable: prop.nullable
383
+ }
384
+ };
451
385
  }
452
- const children = this.fieldExprsToPropNodes(group$1, relEntity);
453
- const nodeType = isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop) ? "object" : "array";
386
+ const children = this.fieldExprsToPropNodes(group, relEntity);
454
387
  return {
455
- nodeType,
388
+ nodeType: isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop) ? "object" : "array",
456
389
  prop,
457
390
  children
458
391
  };
@@ -461,18 +394,11 @@ var init_entity = __esmMin((() => {
461
394
  getFieldExprs(prefix = "", maxDepth = 3, froms = []) {
462
395
  return this.props.flatMap((prop) => {
463
396
  const propName = [prefix, prop.name].filter((v) => v !== "").join(".");
464
- if (propName === prefix) {
465
- return null;
466
- }
397
+ if (propName === prefix) return null;
467
398
  if (isRelationProp(prop)) {
468
- if (maxDepth < 0) {
469
- return null;
470
- }
471
- if (froms.includes(prop.with)) {
472
- return null;
473
- }
474
- const relMd = EntityManager.get(prop.with);
475
- return relMd.getFieldExprs(propName, maxDepth - 1, [...froms, this.id]);
399
+ if (maxDepth < 0) return null;
400
+ if (froms.includes(prop.with)) return null;
401
+ return EntityManager.get(prop.with).getFieldExprs(propName, maxDepth - 1, [...froms, this.id]);
476
402
  }
477
403
  return propName;
478
404
  }).filter((f) => f !== null);
@@ -486,16 +412,11 @@ var init_entity = __esmMin((() => {
486
412
  }
487
413
  getTableColumns() {
488
414
  return this.props.map((prop) => {
489
- if (prop.type === "relation") {
490
- if (this.hasForeignKey(prop)) {
491
- return {
492
- name: `${prop.name}_id`,
493
- type: "int_unsigned"
494
- };
495
- } else {
496
- return null;
497
- }
498
- }
415
+ if (prop.type === "relation") if (this.hasForeignKey(prop)) return {
416
+ name: `${prop.name}_id`,
417
+ type: "int_unsigned"
418
+ };
419
+ else return null;
499
420
  return {
500
421
  name: prop.name,
501
422
  type: prop.type
@@ -514,9 +435,7 @@ var init_entity = __esmMin((() => {
514
435
  */
515
436
  getVectorColumn(columnName) {
516
437
  const vectorProps = this.getVectorColumns();
517
- if (columnName) {
518
- return vectorProps.find((p) => p.name === columnName);
519
- }
438
+ if (columnName) return vectorProps.find((p) => p.name === columnName);
520
439
  return vectorProps[0];
521
440
  }
522
441
  /**
@@ -528,17 +447,13 @@ var init_entity = __esmMin((() => {
528
447
  */
529
448
  getFilterableProps() {
530
449
  return this.props.flatMap((prop) => {
531
- if (isVirtualProp(prop)) {
532
- return [];
533
- }
450
+ if (isVirtualProp(prop)) return [];
534
451
  if (isRelationProp(prop)) {
535
- if (this.hasForeignKey(prop)) {
536
- return {
537
- name: `${prop.name}_id`,
538
- type: "integer",
539
- nullable: prop.nullable
540
- };
541
- }
452
+ if (this.hasForeignKey(prop)) return {
453
+ name: `${prop.name}_id`,
454
+ type: "integer",
455
+ nullable: prop.nullable
456
+ };
542
457
  return [];
543
458
  }
544
459
  return prop;
@@ -550,13 +465,9 @@ var init_entity = __esmMin((() => {
550
465
  if (Object.keys(this.subsets).length > 0) {
551
466
  EntityManager.setModulePath(`${this.id}SubsetKey`, `sonamu.generated`);
552
467
  EntityManager.setModulePath(`${this.id}SubsetMapping`, `sonamu.generated`);
553
- for (const subsetKey of Object.keys(this.subsets)) {
554
- EntityManager.setModulePath(`${this.id}Subset${subsetKey.toUpperCase()}`, `sonamu.generated`);
555
- }
556
- }
557
- for (const enumId of Object.keys(this.enumLabels)) {
558
- EntityManager.setModulePath(enumId, `sonamu.generated`);
468
+ for (const subsetKey of Object.keys(this.subsets)) EntityManager.setModulePath(`${this.id}Subset${subsetKey.toUpperCase()}`, `sonamu.generated`);
559
469
  }
470
+ for (const enumId of Object.keys(this.enumLabels)) EntityManager.setModulePath(enumId, `sonamu.generated`);
560
471
  const typesModulePath = `${basePath}/${this.names.parentFs}.types`;
561
472
  const typesFilePath = path.join(Sonamu.apiRootPath, runtimePath(`dist/application/${typesModulePath}.js`));
562
473
  if (await exists(typesFilePath)) {
@@ -584,26 +495,18 @@ var init_entity = __esmMin((() => {
584
495
  internal: true
585
496
  }));
586
497
  const fields = [...normalFields, ...internalFields];
587
- if (this.subsetCones[key]) {
588
- subsets[key] = {
589
- fields,
590
- cone: this.subsetCones[key]
591
- };
592
- } else {
593
- subsets[key] = fields;
594
- }
498
+ if (this.subsetCones[key]) subsets[key] = {
499
+ fields,
500
+ cone: this.subsetCones[key]
501
+ };
502
+ else subsets[key] = fields;
595
503
  }
596
504
  const enums = {};
597
- for (const [key, values] of Object.entries(this.enumLabels)) {
598
- if (this.enumCones[key]) {
599
- enums[key] = {
600
- values,
601
- cone: this.enumCones[key]
602
- };
603
- } else {
604
- enums[key] = values;
605
- }
606
- }
505
+ for (const [key, values] of Object.entries(this.enumLabels)) if (this.enumCones[key]) enums[key] = {
506
+ values,
507
+ cone: this.enumCones[key]
508
+ };
509
+ else enums[key] = values;
607
510
  return {
608
511
  id: this.id,
609
512
  parentId: this.parentId,
@@ -642,14 +545,10 @@ var init_entity = __esmMin((() => {
642
545
  const configLocale = Sonamu.config.i18n?.defaultLocale;
643
546
  const effectiveLocale = locale || (configLocale === "ko" || configLocale === "en" || configLocale === "ja" ? configLocale : "ko");
644
547
  const result = generateTemplateCones(this.toJson(), effectiveLocale);
645
- if (result.entityCone) {
646
- this.cone = result.entityCone;
647
- }
548
+ if (result.entityCone) this.cone = result.entityCone;
648
549
  for (const [propName, cone] of Object.entries(result.propCones)) {
649
550
  const prop = this.props.find((p) => p.name === propName);
650
- if (prop) {
651
- prop.cone = cone;
652
- }
551
+ if (prop) prop.cone = cone;
653
552
  }
654
553
  this.enumCones = {
655
554
  ...this.enumCones,
@@ -670,13 +569,12 @@ var init_entity = __esmMin((() => {
670
569
  */
671
570
  async generateCones(options) {
672
571
  const { generateCones } = await import("../cone/cone-generator.js");
673
- const context = {
572
+ const result = await generateCones({
674
573
  entity: this.toJson(),
675
574
  locale: options?.locale || "ko",
676
- existingCones: options?.preserveExisting !== false ? this.collectExistingCones() : undefined,
575
+ existingCones: options?.preserveExisting !== false ? this.collectExistingCones() : void 0,
677
576
  onlyEmpty: options?.onlyEmpty ?? false
678
- };
679
- const result = await generateCones(context);
577
+ });
680
578
  this.applyCones(result);
681
579
  await this.save();
682
580
  return result;
@@ -688,20 +586,10 @@ var init_entity = __esmMin((() => {
688
586
  */
689
587
  collectExistingCones() {
690
588
  const cones = {};
691
- if (this.cone) {
692
- cones[`entity:${this.id}`] = this.cone;
693
- }
694
- for (const prop of this.props) {
695
- if (prop.cone) {
696
- cones[`prop:${prop.name}`] = prop.cone;
697
- }
698
- }
699
- for (const [enumId, cone] of Object.entries(this.enumCones)) {
700
- cones[`enum:${enumId}`] = cone;
701
- }
702
- for (const [subsetKey, cone] of Object.entries(this.subsetCones)) {
703
- cones[`subset:${subsetKey}`] = cone;
704
- }
589
+ if (this.cone) cones[`entity:${this.id}`] = this.cone;
590
+ for (const prop of this.props) if (prop.cone) cones[`prop:${prop.name}`] = prop.cone;
591
+ for (const [enumId, cone] of Object.entries(this.enumCones)) cones[`enum:${enumId}`] = cone;
592
+ for (const [subsetKey, cone] of Object.entries(this.subsetCones)) cones[`subset:${subsetKey}`] = cone;
705
593
  return cones;
706
594
  }
707
595
  /**
@@ -710,14 +598,10 @@ var init_entity = __esmMin((() => {
710
598
  * @param result - LLM으로 생성된 cone 결과
711
599
  */
712
600
  applyCones(result) {
713
- if (result.entityCone) {
714
- this.cone = result.entityCone;
715
- }
601
+ if (result.entityCone) this.cone = result.entityCone;
716
602
  for (const [propName, cone] of Object.entries(result.propCones)) {
717
603
  const prop = this.props.find((p) => p.name === propName);
718
- if (prop) {
719
- prop.cone = cone;
720
- }
604
+ if (prop) prop.cone = cone;
721
605
  }
722
606
  this.enumCones = {
723
607
  ...this.enumCones,
@@ -729,9 +613,7 @@ var init_entity = __esmMin((() => {
729
613
  };
730
614
  }
731
615
  getSubsetRows(_subsets, _subsetsInternal, prefixes = []) {
732
- if (prefixes.length > 10) {
733
- return [];
734
- }
616
+ if (prefixes.length > 10) return [];
735
617
  const subsets = _subsets ?? this.subsets;
736
618
  const subsetsInternal = _subsetsInternal ?? this.subsetsInternal;
737
619
  const subsetKeys = Object.keys(subsets);
@@ -740,8 +622,7 @@ var init_entity = __esmMin((() => {
740
622
  const combinedFields = unique([...allFields, ...allInternalFields]);
741
623
  return this.props.map((prop) => {
742
624
  if (prop.type === "relation" && combinedFields.find((f) => f.startsWith(`${[...prefixes, prop.name].join(".")}.`))) {
743
- const relEntity = EntityManager.get(prop.with);
744
- const children = relEntity.getSubsetRows(subsets, subsetsInternal, [...prefixes, `${prop.name}`]);
625
+ const children = EntityManager.get(prop.with).getSubsetRows(subsets, subsetsInternal, [...prefixes, `${prop.name}`]);
745
626
  return {
746
627
  field: prop.name,
747
628
  children,
@@ -760,21 +641,17 @@ var init_entity = __esmMin((() => {
760
641
  return {
761
642
  field: prop.name,
762
643
  children: [],
763
- relationEntity: prop.type === "relation" ? prop.with : undefined,
644
+ relationEntity: prop.type === "relation" ? prop.with : void 0,
764
645
  prefixes,
765
646
  has: Object.fromEntries(subsetKeys.map((subsetKey) => {
766
- const subsetFields = subsets[subsetKey];
767
- const has = subsetFields.some((f) => {
647
+ return [subsetKey, subsets[subsetKey].some((f) => {
768
648
  return f === field || f.startsWith(`${field}.`);
769
- });
770
- return [subsetKey, has];
649
+ })];
771
650
  })),
772
651
  isInternal: Object.fromEntries(subsetKeys.map((subsetKey) => {
773
- const internalFields = subsetsInternal[subsetKey] ?? [];
774
- const isInternal = internalFields.some((f) => {
652
+ return [subsetKey, (subsetsInternal[subsetKey] ?? []).some((f) => {
775
653
  return f === field || f.startsWith(`${field}.`);
776
- });
777
- return [subsetKey, isInternal];
654
+ })];
778
655
  }))
779
656
  };
780
657
  });
@@ -782,21 +659,14 @@ var init_entity = __esmMin((() => {
782
659
  subsetRowsToSubsetFields(subsetRows, subsetKey, internal = false) {
783
660
  const hasKey = internal ? "isInternal" : "has";
784
661
  return subsetRows.map((subsetRow) => {
785
- if (subsetRow.children.length > 0) {
786
- return this.subsetRowsToSubsetFields(subsetRow.children, subsetKey, internal);
787
- } else if (subsetRow[hasKey][subsetKey]) {
788
- return subsetRow.prefixes.concat(subsetRow.field).join(".");
789
- } else {
790
- return null;
791
- }
662
+ if (subsetRow.children.length > 0) return this.subsetRowsToSubsetFields(subsetRow.children, subsetKey, internal);
663
+ else if (subsetRow[hasKey][subsetKey]) return subsetRow.prefixes.concat(subsetRow.field).join(".");
664
+ else return null;
792
665
  }).filter(nonNullable).flat();
793
666
  }
794
667
  async createProp(prop, at) {
795
- if (!at) {
796
- this.props.push(prop);
797
- } else {
798
- this.props.splice(at, 0, prop);
799
- }
668
+ if (!at) this.props.push(prop);
669
+ else this.props.splice(at, 0, prop);
800
670
  await this.save();
801
671
  }
802
672
  analyzeSubsetField(subsetField) {
@@ -810,12 +680,8 @@ var init_entity = __esmMin((() => {
810
680
  propName
811
681
  });
812
682
  const prop = EntityManager.get(entityId).props.find((p) => p.name === propName);
813
- if (!prop) {
814
- throw new Error(`${entityId}의 잘못된 서브셋키 ${subsetField}`);
815
- }
816
- if (isRelationProp(prop)) {
817
- entityId = prop.with;
818
- }
683
+ if (!prop) throw new Error(`${entityId}의 잘못된 서브셋키 ${subsetField}`);
684
+ if (isRelationProp(prop)) entityId = prop.with;
819
685
  }
820
686
  return result;
821
687
  }
@@ -830,12 +696,10 @@ var init_entity = __esmMin((() => {
830
696
  for (const subsetKey of relEntitySubsetKeys) {
831
697
  const subset = relEntity.subsets[subsetKey];
832
698
  const modifiedSubsetFields = subset.map((subsetField) => {
833
- const analyzed = relEntity.analyzeSubsetField(subsetField);
834
- const modified = analyzed.map((a) => a.propName === oldName && a.entityId === this.id ? {
699
+ return relEntity.analyzeSubsetField(subsetField).map((a) => a.propName === oldName && a.entityId === this.id ? {
835
700
  ...a,
836
701
  propName: newProp.name
837
- } : a);
838
- return modified.map((a) => a.propName).join(".");
702
+ } : a).map((a) => a.propName).join(".");
839
703
  });
840
704
  if (subset.join(",") !== modifiedSubsetFields.join(",")) {
841
705
  relEntity.subsets[subsetKey] = modifiedSubsetFields;
@@ -857,12 +721,8 @@ var init_entity = __esmMin((() => {
857
721
  for (const subsetKey of relEntitySubsetKeys) {
858
722
  const subset = relEntity.subsets[subsetKey];
859
723
  const modifiedSubsetFields = subset.map((subsetField) => {
860
- const analyzed = relEntity.analyzeSubsetField(subsetField);
861
- if (analyzed.find((a) => a.propName === oldName && a.entityId === this.id)) {
862
- return null;
863
- } else {
864
- return subsetField;
865
- }
724
+ if (relEntity.analyzeSubsetField(subsetField).find((a) => a.propName === oldName && a.entityId === this.id)) return null;
725
+ else return subsetField;
866
726
  }).filter(nonNullable);
867
727
  if (subset.join(",") !== modifiedSubsetFields.join(",")) {
868
728
  relEntity.subsets[subsetKey] = modifiedSubsetFields;
@@ -870,18 +730,14 @@ var init_entity = __esmMin((() => {
870
730
  }
871
731
  }
872
732
  }
873
- for (const index of EntityManager.get(this.id).indexes) {
874
- index.columns = index.columns.filter((col) => col.name !== oldName);
875
- }
733
+ for (const index of EntityManager.get(this.id).indexes) index.columns = index.columns.filter((col) => col.name !== oldName);
876
734
  this.props.splice(at, 1);
877
735
  await Promise.all(entities.map(async (entity) => entity.save()));
878
736
  }
879
737
  getEntityIdFromSubsetField(subsetField) {
880
- if (!subsetField.includes(".")) {
881
- return this.id;
882
- }
738
+ if (!subsetField.includes(".")) return this.id;
883
739
  const arr = subsetField.split(".").slice(0, -1);
884
- const lastEntityId = arr.reduce((entityId, field) => {
740
+ return arr.reduce((entityId, field) => {
885
741
  const relProp = EntityManager.get(entityId).props.find((p) => p.name === field);
886
742
  if (!relProp || relProp.type !== "relation") {
887
743
  console.debug({
@@ -894,7 +750,6 @@ var init_entity = __esmMin((() => {
894
750
  }
895
751
  return relProp.with;
896
752
  }, this.id);
897
- return lastEntityId;
898
753
  }
899
754
  async moveProp(at, to) {
900
755
  const prop = this.props[at];
@@ -908,9 +763,7 @@ var init_entity = __esmMin((() => {
908
763
  * 필드명을 "테이블명.필드명" 형식으로 변환
909
764
  */
910
765
  getFullFieldName(field) {
911
- if (field.includes(".")) {
912
- return field;
913
- }
766
+ if (field.includes(".")) return field;
914
767
  return `${this.table}.${field}`;
915
768
  }
916
769
  /**
@@ -919,12 +772,8 @@ var init_entity = __esmMin((() => {
919
772
  */
920
773
  getPkType() {
921
774
  const idProp = this.propsDict.id;
922
- if (!idProp) {
923
- throw new Error(`Entity ${this.id}에 id 필드가 없습니다`);
924
- }
925
- if (idProp.type === "string" || idProp.type === "uuid") {
926
- return idProp.type;
927
- }
775
+ if (!idProp) throw new Error(`Entity ${this.id}에 id 필드가 없습니다`);
776
+ if (idProp.type === "string" || idProp.type === "uuid") return idProp.type;
928
777
  return "integer";
929
778
  }
930
779
  /**
@@ -933,9 +782,7 @@ var init_entity = __esmMin((() => {
933
782
  */
934
783
  getPkProp() {
935
784
  const idProp = this.propsDict.id;
936
- if (!idProp) {
937
- throw new Error(`Entity ${this.id}에 id 필드가 없습니다`);
938
- }
785
+ if (!idProp) throw new Error(`Entity ${this.id}에 id 필드가 없습니다`);
939
786
  return idProp;
940
787
  }
941
788
  /**
@@ -943,13 +790,12 @@ var init_entity = __esmMin((() => {
943
790
  * LoaderQuery의 fromIds 타입으로 사용됩니다.
944
791
  */
945
792
  getPkArrayType() {
946
- const pkType = this.getPkType();
947
- return pkType === "integer" ? "number[]" : "string[]";
793
+ return this.getPkType() === "integer" ? "number[]" : "string[]";
948
794
  }
949
795
  };
950
796
  }));
951
-
952
797
  //#endregion
953
798
  init_entity();
954
799
  export { Entity, init_entity };
955
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LmpzIiwibmFtZXMiOlsieiIsImxpbmVzOiBzdHJpbmdbXSIsImpvaW4iLCJyZXN1bHQ6IFJldHVyblR5cGU8dHlwZW9mIHRoaXMuYnVpbGROZXN0ZWRTZWxlY3RPYmplY3Q+IiwibG9hZGVyTGluZXM6IHN0cmluZ1tdIiwibG9hZGVycyIsInJlc3VsdDogU3Vic2V0UXVlcnkiLCJmaWVsZHMiLCJqb2luQ2xhdXNlOlxuICAgICAgICAgICAgfCB7XG4gICAgICAgICAgICAgICAgZnJvbTogc3RyaW5nO1xuICAgICAgICAgICAgICAgIHRvOiBzdHJpbmc7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHwge1xuICAgICAgICAgICAgICAgIGN1c3RvbTogc3RyaW5nO1xuICAgICAgICAgICAgICB9IiwiZnJvbTogc3RyaW5nIiwidG86IHN0cmluZyIsIm1hbnlKb2luOiBTdWJzZXRRdWVyeVtcImxvYWRlcnNcIl1bbnVtYmVyXVtcIm1hbnlKb2luXCJdIiwia2V5OiBzdHJpbmciLCJ2YWx1ZTogc3RyaW5nIiwiZWxzZUV4cHI6IHN0cmluZ1tdIiwiZ3JvdXAiLCJwcm9wIiwic3Vic2V0czogeyBba2V5OiBzdHJpbmddOiBpbXBvcnQoXCIuLi90eXBlcy90eXBlc1wiKS5TdWJzZXREZWYgfSIsIm5vcm1hbEZpZWxkczogU3Vic2V0RmllbGRbXSIsImludGVybmFsRmllbGRzOiBTdWJzZXRGaWVsZFtdIiwiZW51bXM6IHsgW2tleTogc3RyaW5nXTogaW1wb3J0KFwiLi4vdHlwZXMvdHlwZXNcIikuRW51bURlZiB9IiwiY29udGV4dDogaW1wb3J0KFwiLi4vY29uZS9jb25lLWdlbmVyYXRvclwiKS5Db25lR2VuZXJhdGlvbkNvbnRleHQiLCJjb25lczogUmVjb3JkPHN0cmluZywgQ29uZT4iLCJyZXN1bHQ6IHtcbiAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICBwcm9wTmFtZTogc3RyaW5nO1xuICAgIH1bXSIsImVudGl0aWVzOiBFbnRpdHlbXSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lbnRpdHkvZW50aXR5LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSBcImFzc2VydFwiO1xuaW1wb3J0IHsgd3JpdGVGaWxlIH0gZnJvbSBcImZzL3Byb21pc2VzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5pbXBvcnQgaW5mbGVjdGlvbiBmcm9tIFwiaW5mbGVjdGlvblwiO1xuaW1wb3J0IHsgZ3JvdXAsIHVuaXF1ZSB9IGZyb20gXCJyYWRhc2hpXCI7XG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiO1xuXG5pbXBvcnQgeyBTb25hbXUgfSBmcm9tIFwiLi4vYXBpL3NvbmFtdVwiO1xuaW1wb3J0IHtcbiAgZ2V0RW51bURlZlZhbHVlcyxcbiAgZ2V0U3Vic2V0RmllbGRzLFxuICBpc0JlbG9uZ3NUb09uZVJlbGF0aW9uUHJvcCxcbiAgaXNFbnVtUHJvcCxcbiAgaXNIYXNNYW55UmVsYXRpb25Qcm9wLFxuICBpc0ludGVybmFsU3Vic2V0RmllbGQsXG4gIGlzTWFueVRvTWFueVJlbGF0aW9uUHJvcCxcbiAgaXNPbmVUb09uZVJlbGF0aW9uUHJvcCxcbiAgaXNSZWxhdGlvblByb3AsXG4gIGlzVmlydHVhbENvZGVQcm9wLFxuICBpc1ZpcnR1YWxQcm9wLFxuICBub3JtYWxpemVTdWJzZXRGaWVsZCxcbn0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQge1xuICB0eXBlIENvbmUsXG4gIHR5cGUgRW50aXR5SW5kZXgsXG4gIHR5cGUgRW50aXR5SnNvbixcbiAgdHlwZSBFbnRpdHlQcm9wLFxuICB0eXBlIEVudGl0eVByb3BOb2RlLFxuICB0eXBlIEVudGl0eVN1YnNldFJvdyxcbiAgdHlwZSBSZWxhdGlvblByb3AsXG4gIHR5cGUgU3Vic2V0RmllbGQsXG4gIHR5cGUgU3Vic2V0UXVlcnksXG59IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgaW1wb3J0TWVtYmVycyB9IGZyb20gXCIuLi91dGlscy9lc20tdXRpbHNcIjtcbmltcG9ydCB7IGZvcm1hdENvZGUgfSBmcm9tIFwiLi4vdXRpbHMvZm9ybWF0dGVyXCI7XG5pbXBvcnQgeyBleGlzdHMgfSBmcm9tIFwiLi4vdXRpbHMvZnMtdXRpbHNcIjtcbmltcG9ydCB7IHJ1bnRpbWVQYXRoIH0gZnJvbSBcIi4uL3V0aWxzL3BhdGgtdXRpbHNcIjtcbmltcG9ydCB7IGFzc2VydERlZmluZWQsIG5vbk51bGxhYmxlIH0gZnJvbSBcIi4uL3V0aWxzL3V0aWxzXCI7XG5pbXBvcnQgeyBFbnRpdHlNYW5hZ2VyIH0gZnJvbSBcIi4vZW50aXR5LW1hbmFnZXJcIjtcblxuZXhwb3J0IGNsYXNzIEVudGl0eSB7XG4gIGlkOiBzdHJpbmc7XG4gIHBhcmVudElkPzogc3RyaW5nO1xuICB0YWJsZTogc3RyaW5nO1xuICB0aXRsZTogc3RyaW5nO1xuICBjb25lPzogQ29uZTtcbiAgbmFtZXM6IHtcbiAgICBwYXJlbnRGczogc3RyaW5nO1xuICAgIGZzOiBzdHJpbmc7XG4gICAgbW9kdWxlOiBzdHJpbmc7XG4gIH07XG4gIHByb3BzOiBFbnRpdHlQcm9wW107XG4gIHByb3BzRGljdDoge1xuICAgIFtrZXk6IHN0cmluZ106IEVudGl0eVByb3A7XG4gIH07XG4gIHJlbGF0aW9uczoge1xuICAgIFtrZXk6IHN0cmluZ106IFJlbGF0aW9uUHJvcDtcbiAgfTtcbiAgaW5kZXhlczogRW50aXR5SW5kZXhbXTtcbiAgc3Vic2V0czoge1xuICAgIFtrZXk6IHN0cmluZ106IHN0cmluZ1tdO1xuICB9O1xuICBzdWJzZXRzSW50ZXJuYWw6IHtcbiAgICBba2V5OiBzdHJpbmddOiBzdHJpbmdbXTtcbiAgfTtcbiAgdHlwZXM6IHtcbiAgICBbbmFtZTogc3RyaW5nXTogei5ab2RUeXBlQW55O1xuICB9ID0ge307XG4gIGVudW1zOiB7XG4gICAgW2VudW1JZDogc3RyaW5nXTogei5ab2RFbnVtPFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHN0cmluZz4+PjtcbiAgfSA9IHt9O1xuICBlbnVtTGFiZWxzOiB7XG4gICAgW2VudW1JZDogc3RyaW5nXToge1xuICAgICAgW2tleTogc3RyaW5nXTogc3RyaW5nO1xuICAgIH07XG4gIH0gPSB7fTtcbiAgZW51bUNvbmVzOiB7XG4gICAgW2VudW1JZDogc3RyaW5nXTogQ29uZTtcbiAgfSA9IHt9O1xuICBzdWJzZXRDb25lczoge1xuICAgIFtzdWJzZXRLZXk6IHN0cmluZ106IENvbmU7XG4gIH0gPSB7fTtcblxuICBjb25zdHJ1Y3Rvcih7IGlkLCBwYXJlbnRJZCwgdGFibGUsIHRpdGxlLCBjb25lLCBwcm9wcywgaW5kZXhlcywgc3Vic2V0cywgZW51bXMgfTogRW50aXR5SnNvbikge1xuICAgIC8vIGlkXG4gICAgdGhpcy5pZCA9IGlkO1xuICAgIHRoaXMucGFyZW50SWQgPSBwYXJlbnRJZDtcbiAgICB0aGlzLnRpdGxlID0gdGl0bGUgPz8gdGhpcy5pZDtcbiAgICB0aGlzLnRhYmxlID0gdGFibGUgPz8gaW5mbGVjdGlvbi51bmRlcnNjb3JlKGluZmxlY3Rpb24ucGx1cmFsaXplKGlkKSk7XG4gICAgdGhpcy5jb25lID0gY29uZTtcblxuICAgIC8vIHByb3BzXG4gICAgaWYgKHByb3BzKSB7XG4gICAgICB0aGlzLnByb3BzID0gcHJvcHMubWFwKChwcm9wKSA9PiB7XG4gICAgICAgIGlmIChpc0VudW1Qcm9wKHByb3ApKSB7XG4gICAgICAgICAgaWYgKHByb3AuaWQuaW5jbHVkZXMoXCIkTW9kZWxcIikpIHtcbiAgICAgICAgICAgIHByb3AuaWQgPSBwcm9wLmlkLnJlcGxhY2UoXCIkTW9kZWxcIiwgaWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvcDtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5wcm9wc0RpY3QgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgIHByb3BzLm1hcCgocHJvcCkgPT4ge1xuICAgICAgICAgIHJldHVybiBbcHJvcC5uYW1lLCBwcm9wXTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICAvLyByZWxhdGlvbnNcbiAgICAgIHRoaXMucmVsYXRpb25zID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICBwcm9wcy5maWx0ZXIoKHByb3ApID0+IGlzUmVsYXRpb25Qcm9wKHByb3ApKS5tYXAoKHByb3ApID0+IFtwcm9wLm5hbWUsIHByb3BdKSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHJvcHMgPSBbXTtcbiAgICAgIHRoaXMucHJvcHNEaWN0ID0ge307XG4gICAgICB0aGlzLnJlbGF0aW9ucyA9IHt9O1xuICAgIH1cblxuICAgIC8vIGluZGV4ZXNcbiAgICB0aGlzLmluZGV4ZXMgPSBpbmRleGVzID8/IFtdO1xuXG4gICAgLy8gc3Vic2V0czogU3Vic2V0RGVm7JeQ7IScIFN1YnNldEZpZWxkW13rpbwg7LaU7Lac7ZWY7JesIHN1YnNldHMo7J2867CYKeyZgCBzdWJzZXRzSW50ZXJuYWwoaW50ZXJuYWwp66GcIOu2hOumrFxuICAgIHRoaXMuc3Vic2V0cyA9IHt9O1xuICAgIHRoaXMuc3Vic2V0c0ludGVybmFsID0ge307XG4gICAgZm9yIChjb25zdCBba2V5LCBzdWJzZXREZWZdIG9mIE9iamVjdC5lbnRyaWVzKHN1YnNldHMgPz8ge30pKSB7XG4gICAgICBjb25zdCBmaWVsZHMgPSBnZXRTdWJzZXRGaWVsZHMoc3Vic2V0RGVmKTtcbiAgICAgIHRoaXMuc3Vic2V0c1trZXldID0gZmllbGRzLmZpbHRlcigoZikgPT4gIWlzSW50ZXJuYWxTdWJzZXRGaWVsZChmKSkubWFwKG5vcm1hbGl6ZVN1YnNldEZpZWxkKTtcbiAgICAgIHRoaXMuc3Vic2V0c0ludGVybmFsW2tleV0gPSBmaWVsZHMuZmlsdGVyKGlzSW50ZXJuYWxTdWJzZXRGaWVsZCkubWFwKG5vcm1hbGl6ZVN1YnNldEZpZWxkKTtcblxuICAgICAgLy8gY29uZSDstpTstpxcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShzdWJzZXREZWYpICYmIFwiY29uZVwiIGluIHN1YnNldERlZiAmJiBzdWJzZXREZWYuY29uZSkge1xuICAgICAgICB0aGlzLnN1YnNldENvbmVzW2tleV0gPSBzdWJzZXREZWYuY29uZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBlbnVtczogRW51bURlZuyXkOyEnCB2YWx1ZXPsmYAgY29uZeulvCDstpTstpztlZjsl6wg7LKY66asXG4gICAgdGhpcy5lbnVtTGFiZWxzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmVudHJpZXMoZW51bXMgPz8ge30pLm1hcCgoW2tleSwgZW51bURlZl0pID0+IHtcbiAgICAgICAgLy8gY29uZSDstpTstpxcbiAgICAgICAgaWYgKFwidmFsdWVzXCIgaW4gZW51bURlZiAmJiBcImNvbmVcIiBpbiBlbnVtRGVmICYmIGVudW1EZWYuY29uZSkge1xuICAgICAgICAgIHRoaXMuZW51bUNvbmVzW2tleV0gPSBlbnVtRGVmLmNvbmUgYXMgQ29uZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW2tleSwgZ2V0RW51bURlZlZhbHVlcyhlbnVtRGVmKV07XG4gICAgICB9KSxcbiAgICApO1xuICAgIHRoaXMuZW51bXMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QuZW50cmllcyh0aGlzLmVudW1MYWJlbHMpLm1hcCgoW2tleSwgZW51bUxhYmVsXSkgPT4ge1xuICAgICAgICByZXR1cm4gW2tleSwgei5lbnVtKE9iamVjdC5rZXlzKGVudW1MYWJlbCkgYXMgdW5rbm93biBhcyByZWFkb25seSBbc3RyaW5nLCAuLi5zdHJpbmdbXV0pXTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICAvLyBuYW1lc1xuICAgIHRoaXMubmFtZXMgPSB7XG4gICAgICBwYXJlbnRGczogaW5mbGVjdGlvbi5kYXNoZXJpemUoaW5mbGVjdGlvbi51bmRlcnNjb3JlKHBhcmVudElkID8/IGlkKSkudG9Mb3dlckNhc2UoKSxcbiAgICAgIGZzOiBpbmZsZWN0aW9uLmRhc2hlcml6ZShpbmZsZWN0aW9uLnVuZGVyc2NvcmUoaWQpKS50b0xvd2VyQ2FzZSgpLFxuICAgICAgbW9kdWxlOiBpZCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOy/vOumrOyaqSDshJzruIzshYsg7ZWE65Oc66W8IOuwmO2ZmO2VqeuLiOuLpCAoc3Vic2V0cyArIHN1YnNldHNJbnRlcm5hbCDtlansuagpXG4gICAqL1xuICBnZXRTdWJzZXRGaWVsZHNGb3JRdWVyeShzdWJzZXRLZXk6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gWy4uLih0aGlzLnN1YnNldHNbc3Vic2V0S2V5XSA/PyBbXSksIC4uLih0aGlzLnN1YnNldHNJbnRlcm5hbFtzdWJzZXRLZXldID8/IFtdKV07XG4gIH1cblxuICAvKipcbiAgICog7KO87Ja07KeEIOydtOumhChzdWJzZXRLZXkp7J2YIHN1YnNldOydhCDsi6TsoJzroZwg6rCA7KC47Jik64qUIFB1cmkg7L2U65OcIOq1rO2YhOyytCBzdHJpbmfsnYQg67CY7ZmY7ZWp64uI64ukLlxuICAgKi9cbiAgZ2V0UHVyaVN1YnNldFF1ZXJ5KHN1YnNldEtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBzdWJzZXQgPSB0aGlzLmdldFN1YnNldEZpZWxkc0ZvclF1ZXJ5KHN1YnNldEtleSk7XG4gICAgY29uc3Qgc3Vic2V0UXVlcnkgPSB0aGlzLnJlc29sdmVTdWJzZXRRdWVyeShcIlwiLCBzdWJzZXQpO1xuXG4gICAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW107XG5cbiAgICAvLyBmcm9tXG4gICAgbGluZXMucHVzaChgcmV0dXJuIHFiV3JhcHBlcmApO1xuICAgIGxpbmVzLnB1c2goYC5mcm9tKFwiJHt0aGlzLnRhYmxlfVwiKWApO1xuXG4gICAgLy8gam9pblxuICAgIGZvciAoY29uc3Qgam9pbiBvZiBzdWJzZXRRdWVyeS5qb2lucykge1xuICAgICAgLy8gam9pbiDrqZTshJzrk5wg6rKw7KCVOiBpbm5lciDihpIgam9pbiwgb3V0ZXIg4oaSIGxlZnRKb2luXG4gICAgICAvLyBGSyBudWxsYWJsZSDsl6zrtoDripQgbGVmdEpvaW4g7YOA7J6FIOyLnOq3uOuLiOyymOyXkOyEnCDsnpDrj5nsnLzroZwg7YyQ64uo65CoXG4gICAgICBjb25zdCBqb2luTWV0aG9kID0gam9pbi5qb2luID09PSBcImlubmVyXCIgPyBcImpvaW5cIiA6IFwibGVmdEpvaW5cIjtcblxuICAgICAgaWYgKFwiY3VzdG9tXCIgaW4gam9pbikge1xuICAgICAgICAvLyBjdXN0b20gam9pbiBjbGF1c2XripQgcmF3IOyCrOyaqVxuICAgICAgICBsaW5lcy5wdXNoKFxuICAgICAgICAgIGAuJHtqb2luTWV0aG9kfSh7ICR7am9pbi5hc306IFwiJHtqb2luLnRhYmxlfVwiIH0sIHFiV3JhcHBlci5rbmV4LnJhdyhcXGAke2pvaW4uY3VzdG9tfVxcYCkpYCxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpbmVzLnB1c2goYC4ke2pvaW5NZXRob2R9KHsgJHtqb2luLmFzfTogXCIke2pvaW4udGFibGV9XCIgfSwgXCIke2pvaW4uZnJvbX1cIiwgXCIke2pvaW4udG99XCIpYCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2VsZWN0IC0g7J6F7LK07KCBIOq1rOyhsOuhnCDsg53shLFcbiAgICBjb25zdCBzZWxlY3RPYmogPSB0aGlzLmJ1aWxkTmVzdGVkU2VsZWN0T2JqZWN0KHN1YnNldFF1ZXJ5LnNlbGVjdCk7XG4gICAgbGluZXMucHVzaChgLnNlbGVjdCgke3RoaXMuc3RyaW5naWZ5TmVzdGVkU2VsZWN0T2JqZWN0KHNlbGVjdE9iail9KTtgKTtcblxuICAgIHJldHVybiBsaW5lcy5qb2luKFwiXFxuXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqICouZW50aXR5Lmpzb27snZggc3Vic2V07JeQIOuTpOyWtOyeiOuKlCDtlYTrk5wg67Cw7Je07J2EIOuwm+yVhOyEnCxcbiAgICogUHVyaeydmCBTZWxlY3RPYmplY3Qg7YOA7J6F7Jy866GcIOuzgO2ZmO2VqeuLiOuLpC5cbiAgICpcbiAgICog7JiIOiBbXCJ1c2Vycy5pZFwiLCBcInBhcmVudC5pZFwiLCBcInBhcmVudC5uYW1lXCJdXG4gICAqICAg4oaSIHsgaWQ6IFwidXNlcnMuaWRcIiwgcGFyZW50OiB7IGlkOiBcInBhcmVudC5pZFwiLCBuYW1lOiBcInBhcmVudC5uYW1lXCIgfSB9XG4gICAqXG4gICAqIOyWuOuNlOuwlOqwgCDslYTri4wg7KSR7LKpIOqwneyytOuhnCDrs4DtmZjtlajsl5Ag7Jyg7J2Y7ZWY7IS47JqULlxuICAgKiDsnbTroIfqsowg7KSR7LKpIOqwneyytOuhnCDrs4DtmZjtlZjsl6wgc2VsZWN07JeQIOuEmOqyqOyjvOuptCBQYXJzZVNlbGVjdE9iamVjdCDtg4DsnoXsnbQgam9pbuuQnCDqsJ3ssrTsnZgg7YOA7J6F7J2EIOyemCDsnqHslYTspIQg7IiYIOyeiOyKteuLiOuLpC5cbiAgICog7KaJLCBlbmhhbmNlcuyXkOyEnCByb3frpbwg67Cb7JWY7J2EIOuVjCBoeWRyYXRl65CcIOqwneyytCDsnpDssrTsnZggbnVsbGl0eeyZgCDqt7gg7JWI7Kq9IO2VhOuTnOydmCBudWxsaXR56rCAIGZrIG51bGxhYmxlIOyXrOu2gOyXkCDrlLDrnbwg7J6YIOy2lOuhoOuQqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgYnVpbGROZXN0ZWRTZWxlY3RPYmplY3QoXG4gICAgc2VsZWN0SXRlbXM6IHN0cmluZ1tdLFxuICAgIC8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55IC0tIOuwmO2ZmCDsmKTruIzsoJ3tirjsnZgg6rCS7J2AIHN0cmluZ+ydvCDsiJjrj4Qg7J6I6rOgIOuYkOuLpOuluCDsmKTruIzsoJ3tirjsnbwg7IiY64+EIOyeiOuKlOuNsCwg7J2066W8IOyerOq3gCDtg4DsnoXsnLzroZwg64KY7YOA64K8IOyImCDsl4bslrQgYW5566GcIOyymOumrO2VqeuLiOuLpC5cbiAgKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gICAgY29uc3QgcmVzdWx0OiBSZXR1cm5UeXBlPHR5cGVvZiB0aGlzLmJ1aWxkTmVzdGVkU2VsZWN0T2JqZWN0PiA9IHt9O1xuXG4gICAgZm9yIChjb25zdCBzZWxlY3RJdGVtIG9mIHNlbGVjdEl0ZW1zKSB7XG4gICAgICAvLyBcInVzZXJzLmlkXCIg65iQ64qUIFwidXNlcnMuaWQgYXMgdXNlcl9faWRcIiDtmJXtg5wg7YyM7IuxXG4gICAgICBjb25zdCBtYXRjaCA9IHNlbGVjdEl0ZW0ubWF0Y2goL14oLis/KSg/OiBhcyAoLispKT8kLyk7XG4gICAgICBpZiAoIW1hdGNoKSBjb250aW51ZTtcblxuICAgICAgY29uc3QgWywgY29sdW1uLCBhbGlhc10gPSBtYXRjaDtcbiAgICAgIGNvbnN0IGNvbHVtblZhbHVlID0gYFwiJHtjb2x1bW4udHJpbSgpfVwiYDtcblxuICAgICAgaWYgKCFhbGlhcyB8fCAhYWxpYXMuaW5jbHVkZXMoXCJfX1wiKSkge1xuICAgICAgICAvLyBhbGlhc+qwgCDsl4bqsbDrgpggX1/rpbwg7Y+s7ZWo7ZWY7KeAIOyViuycvOuptCDstZzsg4HsnIQg7ZWE65OcXG4gICAgICAgIGNvbnN0IGtleSA9IGFsaWFzID8/IGFzc2VydERlZmluZWQoY29sdW1uLnNwbGl0KFwiLlwiKS5wb3AoKSk7XG4gICAgICAgIHJlc3VsdFtrZXldID0gY29sdW1uVmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBhbGlhc+qwgCBfX+ulvCDtj6ztlajtlZjrqbQg7J6F7LK0IOq1rOyhsOuhnCDqt7jro7ntmZRcbiAgICAgICAgY29uc3QgcGFydHMgPSBhbGlhcy5zcGxpdChcIl9fXCIpO1xuICAgICAgICBsZXQgY3VycmVudCA9IHJlc3VsdDtcblxuICAgICAgICAvLyDrp4jsp4Drp4kg7YyM7Yq4IOyghOq5jOyngCDspJHssqkg6rCd7LK0IOyDneyEsVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICAgIGNvbnN0IHBhcnQgPSBwYXJ0c1tpXTtcbiAgICAgICAgICBpZiAocGFydCBpbiBjdXJyZW50KSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGN1cnJlbnRbcGFydF0gPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgLy8g7J6F66Cl7J20IFtcInVzZXJcIiwgXCJ1c2VyX19pZFwiXSDqsJnsnYAg6rK97JqwIVxuICAgICAgICAgICAgICAvLyDslaDstIjsl5Ag66eQ64+EIOyViCDrkJjsp4Drp4wg7JWI7KCE7ZWY6rKMIOyYiOyZuOulvCDrjZjsp5Hri4jri6QuXG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgQ29uZmxpY3QgZGV0ZWN0ZWQgaW4gc2VsZWN0IGl0ZW1zOiBwYXJlbnQgcGF0aCBcIiR7cGFydHMuc2xpY2UoMCwgaSArIDEpLmpvaW4oXCJfX1wiKX1cIiBpcyBhbHJlYWR5IHNldCBhcyBhIGZpZWxkLCBjYW5ub3QgbmVzdCBcIiR7YWxpYXN9XCIgdW5kZXIgaXQuYCxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY3VycmVudFtwYXJ0XSA9IHt9O1xuICAgICAgICAgIH1cbiAgICAgICAgICBjdXJyZW50ID0gY3VycmVudFtwYXJ0XTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOuniOyngOuniSDtjIztirjsl5Ag6rCSIOyEpOyglVxuICAgICAgICBjb25zdCBsYXN0UGFydCA9IHBhcnRzW3BhcnRzLmxlbmd0aCAtIDFdO1xuICAgICAgICBjdXJyZW50W2xhc3RQYXJ0XSA9IGNvbHVtblZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogSlNPTi5zdHJpbmdpZnnsmYAg7Jyg7IKs7ZWcIOydvOydhCDtlanri4jri6QuXG4gICAqIOuLpOunjCDso7zslrTsp4Qg6rCd7LK066W8IEpTT07snbQg7JWE64uMIFR5cGVTY3JpcHQg6rCd7LK0IOumrO2EsOuftCDsiqTtirjrp4HsnLzroZwg66eM65Ok7Ja07KSN64uI64ukLlxuICAgKiBrZXnsl5Ag65Sw7Ji07ZGc6rCAIOyXhuyWtOyalC5cbiAgICog7Lac66ClIOyYiOyLnDpcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiB7XG4gICAqICAgaWQ6IFwidXNlcnMuaWRcIixcbiAgICogICBwYXJlbnQ6IHtcbiAgICogICAgIGlkOiBcInBhcmVudC5pZFwiLFxuICAgKiAgICAgbmFtZTogXCJwYXJlbnQubmFtZVwiLFxuICAgKiAgIH0sXG4gICAqIH1cbiAgICogYGBgXG4gICAqIEBwYXJhbSBvYmog67OA7ZmY7ZWgIOqwneyytFxuICAgKiBAcGFyYW0gaW5kZW50IOuTpOyXrOyTsOq4sCDroIjrsqhcbiAgICogQHBhcmFtIHdpdGhCcmFjZXMgdHJ1ZeuptCDspJHqtITtmLgg7Y+s7ZWoLCBmYWxzZeuptCDrgrTsmqnrp4wg67CY7ZmYXG4gICAqL1xuICBwcml2YXRlIHN0cmluZ2lmeU5lc3RlZFNlbGVjdE9iamVjdChcbiAgICAvLyBveGxpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAtLSDspJHssqkg7Jik67iM7KCd7Yq47J2YIOqwkuydgCBzdHJpbmfsnbwg7IiY64+EIOyeiOqzoCDrmJDri6Trpbgg7Jik67iM7KCd7Yq47J28IOyImOuPhCDsnojripTrjbAsIOydtOulvCDsnqzqt4Ag7YOA7J6F7Jy866GcIOuCmO2DgOuCvCDsiJgg7JeG7Ja0IGFueeuhnCDsspjrpqztlanri4jri6QuXG4gICAgb2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgIGluZGVudDogbnVtYmVyID0gMCxcbiAgICB3aXRoQnJhY2VzOiBib29sZWFuID0gdHJ1ZSxcbiAgKTogc3RyaW5nIHtcbiAgICBjb25zdCBzcGFjZXMgPSBcIiAgXCIucmVwZWF0KGluZGVudCk7XG4gICAgY29uc3QgaW5uZXJTcGFjZXMgPSBcIiAgXCIucmVwZWF0KGluZGVudCArIDEpO1xuXG4gICAgY29uc3QgZW50cmllcyA9IE9iamVjdC5lbnRyaWVzKG9iaik7XG4gICAgaWYgKGVudHJpZXMubGVuZ3RoID09PSAwKSByZXR1cm4gd2l0aEJyYWNlcyA/IFwie31cIiA6IFwiXCI7XG5cbiAgICBjb25zdCBsaW5lcyA9IGVudHJpZXMubWFwKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgLy8g7Lus65+8IOqyveuhnCAo7J2066+4IOuUsOyYtO2RnCDtj6ztlagpXG4gICAgICAgIHJldHVybiBgJHtpbm5lclNwYWNlc30ke2tleX06ICR7dmFsdWV9LGA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyDspJHssqkg6rCd7LK0ICjtla3sg4Eg7KSR6rSE7Zi4IO2PrO2VqClcbiAgICAgICAgcmV0dXJuIGAke2lubmVyU3BhY2VzfSR7a2V5fTogJHt0aGlzLnN0cmluZ2lmeU5lc3RlZFNlbGVjdE9iamVjdCh2YWx1ZSwgaW5kZW50ICsgMSwgdHJ1ZSl9LGA7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAod2l0aEJyYWNlcykge1xuICAgICAgcmV0dXJuIGB7XFxuJHtsaW5lcy5qb2luKFwiXFxuXCIpfVxcbiR7c3BhY2VzfX1gO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyDspJHqtITtmLgg7JeG7J20IOuCtOyaqeunjCDrsJjtmZggKOyVnuuSpCDqsJztlokg7KCc7Jm4KVxuICAgICAgcmV0dXJuIGxpbmVzLmpvaW4oXCJcXG5cIik7XG4gICAgfVxuICB9XG5cbiAgZ2V0UHVyaUxvYWRlclF1ZXJ5KHN1YnNldEtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBzdWJzZXQgPSB0aGlzLmdldFN1YnNldEZpZWxkc0ZvclF1ZXJ5KHN1YnNldEtleSk7XG4gICAgY29uc3QgeyBsb2FkZXJzIH0gPSB0aGlzLnJlc29sdmVTdWJzZXRRdWVyeShcIlwiLCBzdWJzZXQpO1xuXG4gICAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW2BbYF07XG5cbiAgICAvLyDsnqzqt4DsoIHsnLzroZwgbG9hZGVyIOyDneyEse2VmOuKlCDtl6ztjbwg7ZWo7IiYXG4gICAgY29uc3QgZ2VuZXJhdGVMb2FkZXJDb2RlID0gKGxvYWRlcnM6IFN1YnNldFF1ZXJ5W1wibG9hZGVyc1wiXSk6IHN0cmluZ1tdID0+IHtcbiAgICAgIGNvbnN0IGxvYWRlckxpbmVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IGxvYWRlciBvZiBsb2FkZXJzKSB7XG4gICAgICAgIGNvbnN0IHsgdG9UYWJsZSwgdG9Db2wsIHRocm91Z2gsIGZyb21UYWJsZSB9ID0gbG9hZGVyLm1hbnlKb2luO1xuXG4gICAgICAgIC8vIGZyb21UYWJsZeydmCBFbnRpdHnrpbwg6rCA7KC47JmA7IScIFBLIO2DgOyehSDtmZXsnbhcbiAgICAgICAgY29uc3QgZnJvbUVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0QnlUYWJsZShmcm9tVGFibGUpO1xuICAgICAgICBjb25zdCBmcm9tSWRzVHlwZSA9IGZyb21FbnRpdHkuZ2V0UGtBcnJheVR5cGUoKTtcblxuICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKFxuICAgICAgICAgIFwie1wiLFxuICAgICAgICAgIGBhczogXCIke2xvYWRlci5hc31cIixgLFxuICAgICAgICAgIGByZWZJZDogXCIke2xvYWRlci5tYW55Sm9pbi5pZEZpZWxkfVwiLGAsXG4gICAgICAgICAgYHFiOiAocWJXcmFwcGVyOiBQdXJpV3JhcHBlcjxEYXRhYmFzZVNjaGVtYUV4dGVuZD4sIGZyb21JZHM6IG51bWJlcltdIHwgc3RyaW5nW10pID0+IHtgLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmICh0aHJvdWdoID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAvLyBIYXNNYW55XG4gICAgICAgICAgbG9hZGVyTGluZXMucHVzaChcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICBcInJldHVybiBxYldyYXBwZXJcIixcbiAgICAgICAgICAgIGAuZnJvbShcIiR7dG9UYWJsZX1cIilgLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBsb2FkZXIub25lSm9pbnMuZm9yRWFjaCgoam9pbjogU3Vic2V0UXVlcnlbXCJqb2luc1wiXVtudW1iZXJdKSA9PiB7XG4gICAgICAgICAgICAvLyBGSyBudWxsYWJsZSDsl6zrtoDripQgbGVmdEpvaW4g7YOA7J6FIOyLnOq3uOuLiOyymOyXkOyEnCDsnpDrj5nsnLzroZwg7YyQ64uo65CoXG4gICAgICAgICAgICBjb25zdCBqb2luTWV0aG9kID0gam9pbi5qb2luID09PSBcImlubmVyXCIgPyBcImpvaW5cIiA6IFwibGVmdEpvaW5cIjtcbiAgICAgICAgICAgIGlmIChcImN1c3RvbVwiIGluIGpvaW4pIHtcbiAgICAgICAgICAgICAgLy8gY3VzdG9tIGpvaW4gY2xhdXNl64qUIGNhbGxiYWNrIO2Yle2DnOydmCBvbiDrqZTshJzrk5zroZwg7LKY66as7ZWp64uI64ukLlxuICAgICAgICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKFxuICAgICAgICAgICAgICAgIGAuJHtqb2luTWV0aG9kfSh7ICR7am9pbi5hc306IFwiJHtqb2luLnRhYmxlfVwiIH0sIChqKSA9PiB7YCxcbiAgICAgICAgICAgICAgICBgai5vbihQdXJpLnJhd1N0cmluZyhcIiR7am9pbi5jdXN0b219XCIpKTtgLFxuICAgICAgICAgICAgICAgIFwifSlcIixcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGxvYWRlckxpbmVzLnB1c2goXG4gICAgICAgICAgICAgICAgYC4ke2pvaW5NZXRob2R9KHsgJHtqb2luLmFzfTogXCIke2pvaW4udGFibGV9XCIgfSwgXCIke2pvaW4uZnJvbX1cIiwgXCIke2pvaW4udG99XCIpYCxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIOyeheyytOyggSBzZWxlY3Qg6rWs7KGwIOyDneyEsSAocmVmSWQg7Y+s7ZWoKVxuICAgICAgICAgIGNvbnN0IHNlbGVjdE9iaiA9IHRoaXMuYnVpbGROZXN0ZWRTZWxlY3RPYmplY3QobG9hZGVyLnNlbGVjdCk7XG4gICAgICAgICAgc2VsZWN0T2JqLnJlZklkID0gYFwiJHt0b1RhYmxlfS4ke3RvQ29sfVwiYDtcbiAgICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKFxuICAgICAgICAgICAgYC53aGVyZUluKFwiJHt0b1RhYmxlfS4ke3RvQ29sfVwiLCBmcm9tSWRzIGFzICR7ZnJvbUlkc1R5cGV9KWAsXG4gICAgICAgICAgICBgLnNlbGVjdCgke3RoaXMuc3RyaW5naWZ5TmVzdGVkU2VsZWN0T2JqZWN0KHNlbGVjdE9iail9KTtgLFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gTWFueVRvTWFueVxuICAgICAgICAgIGxvYWRlckxpbmVzLnB1c2goXG4gICAgICAgICAgICBcInJldHVybiBxYldyYXBwZXJcIixcbiAgICAgICAgICAgIGAuZnJvbShcIiR7dGhyb3VnaC50YWJsZX1cIilgLFxuICAgICAgICAgICAgYC5qb2luKFwiJHt0b1RhYmxlfVwiLCBcIiR7dGhyb3VnaC50YWJsZX0uJHt0aHJvdWdoLnRvQ29sfVwiLCBcIiR7dG9UYWJsZX0uJHt0b0NvbH1cIilgLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBsb2FkZXIub25lSm9pbnMuZm9yRWFjaCgoam9pbjogU3Vic2V0UXVlcnlbXCJqb2luc1wiXVtudW1iZXJdKSA9PiB7XG4gICAgICAgICAgICAvLyBGSyBudWxsYWJsZSDsl6zrtoDripQgbGVmdEpvaW4g7YOA7J6FIOyLnOq3uOuLiOyymOyXkOyEnCDsnpDrj5nsnLzroZwg7YyQ64uo65CoXG4gICAgICAgICAgICBjb25zdCBqb2luTWV0aG9kID0gam9pbi5qb2luID09PSBcImlubmVyXCIgPyBcImpvaW5cIiA6IFwibGVmdEpvaW5cIjtcbiAgICAgICAgICAgIGlmIChcImN1c3RvbVwiIGluIGpvaW4pIHtcbiAgICAgICAgICAgICAgLy8gY3VzdG9tIGpvaW4gY2xhdXNl64qUIGNhbGxiYWNrIO2Yle2DnOydmCBvbiDrqZTshJzrk5zroZwg7LKY66as7ZWp64uI64ukLlxuICAgICAgICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKFxuICAgICAgICAgICAgICAgIGAuJHtqb2luTWV0aG9kfSh7ICR7am9pbi5hc306IFwiJHtqb2luLnRhYmxlfVwiIH0sIChqKSA9PiB7YCxcbiAgICAgICAgICAgICAgICBgai5vbihQdXJpLnJhd1N0cmluZyhcIiR7am9pbi5jdXN0b219XCIpKTtgLFxuICAgICAgICAgICAgICAgIFwifSlcIixcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGxvYWRlckxpbmVzLnB1c2goXG4gICAgICAgICAgICAgICAgYC4ke2pvaW5NZXRob2R9KHsgJHtqb2luLmFzfTogXCIke2pvaW4udGFibGV9XCIgfSwgXCIke2pvaW4uZnJvbX1cIiwgXCIke2pvaW4udG99XCIpYCxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIOyeheyytOyggSBzZWxlY3Qg6rWs7KGwIOyDneyEsSAocmVmSWQg7Y+s7ZWoKVxuICAgICAgICAgIGNvbnN0IHNlbGVjdE9iaiA9IHRoaXMuYnVpbGROZXN0ZWRTZWxlY3RPYmplY3QobG9hZGVyLnNlbGVjdCk7XG4gICAgICAgICAgc2VsZWN0T2JqLnJlZklkID0gYFwiJHt0aHJvdWdoLnRhYmxlfS4ke3Rocm91Z2guZnJvbUNvbH1cImA7XG4gICAgICAgICAgbG9hZGVyTGluZXMucHVzaChcbiAgICAgICAgICAgIGAud2hlcmVJbihcIiR7dGhyb3VnaC50YWJsZX0uJHt0aHJvdWdoLmZyb21Db2x9XCIsIGZyb21JZHMgYXMgJHtmcm9tSWRzVHlwZX0pYCxcbiAgICAgICAgICAgIGAuc2VsZWN0KCR7dGhpcy5zdHJpbmdpZnlOZXN0ZWRTZWxlY3RPYmplY3Qoc2VsZWN0T2JqKX0pO2AsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxvYWRlckxpbmVzLnB1c2goYH0sYCk7XG5cbiAgICAgICAgLy8g7KSR7LKpIGxvYWRlcnMg7LKY66asXG4gICAgICAgIGlmIChsb2FkZXIubG9hZGVycyAmJiBsb2FkZXIubG9hZGVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgbG9hZGVyTGluZXMucHVzaChcImxvYWRlcnM6IFtcIiwgLi4uZ2VuZXJhdGVMb2FkZXJDb2RlKGxvYWRlci5sb2FkZXJzKSwgXCJdLFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxvYWRlckxpbmVzLnB1c2goXCJ9LFwiKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGxvYWRlckxpbmVzO1xuICAgIH07XG5cbiAgICBsaW5lcy5wdXNoKC4uLmdlbmVyYXRlTG9hZGVyQ29kZShsb2FkZXJzKSk7XG4gICAgbGluZXMucHVzaChgXWApO1xuXG4gICAgcmV0dXJuIGxpbmVzLmpvaW4oXCJcXG5cIik7XG4gIH1cblxuICAvKlxuICAgIHN1YnNldCBTRUxFQ1QvSk9JTi9MT0FERVIg6rKw6rO8IOumrO2EtFxuICAqL1xuICBnZXRTdWJzZXRRdWVyeShzdWJzZXRLZXk6IHN0cmluZyk6IFN1YnNldFF1ZXJ5IHtcbiAgICBjb25zdCBzdWJzZXQgPSB0aGlzLmdldFN1YnNldEZpZWxkc0ZvclF1ZXJ5KHN1YnNldEtleSk7XG5cbiAgICBjb25zdCByZXN1bHQ6IFN1YnNldFF1ZXJ5ID0gdGhpcy5yZXNvbHZlU3Vic2V0UXVlcnkoXCJcIiwgc3Vic2V0KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLypcbiAgICovXG4gIHJlc29sdmVTdWJzZXRRdWVyeShcbiAgICBwcmVmaXg6IHN0cmluZyxcbiAgICBmaWVsZHM6IHN0cmluZ1tdLFxuICAgIGlzQWxyZWFkeU91dGVySm9pbmVkOiBib29sZWFuID0gZmFsc2UsXG4gICk6IFN1YnNldFF1ZXJ5IHtcbiAgICAvLyBwcmVmaXgg7LmY7ZmYIChwcmVmaXjripQgVG9PbmVSZWxhdGlvbuydtCDrs7XsiJjroZwg67aZ7J2AIOqyveyasCDrqqjrkZAgX1/roZwg67OA6rK965CoKVxuICAgIHByZWZpeCA9IHByZWZpeC5yZXBsYWNlKC9cXC4vZywgXCJfX1wiKTtcblxuICAgIC8vIOyEnOu4jOyFi+ydhCAx646B7Iqk66eMIOu2hOumrO2VmOyXrCDqt7jro7ntlZFcbiAgICBjb25zdCBzdWJzZXRHcm91cCA9IGdyb3VwKGZpZWxkcywgKGZpZWxkKSA9PiB7XG4gICAgICBpZiAoZmllbGQuaW5jbHVkZXMoXCIuXCIpKSB7XG4gICAgICAgIGNvbnN0IFtyZWxdID0gZmllbGQuc3BsaXQoXCIuXCIpO1xuICAgICAgICByZXR1cm4gcmVsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBPYmplY3Qua2V5cyhzdWJzZXRHcm91cCkucmVkdWNlKFxuICAgICAgKHIsIGdyb3VwS2V5KSA9PiB7XG4gICAgICAgIGNvbnN0IGZpZWxkcyA9IHN1YnNldEdyb3VwW2dyb3VwS2V5XTtcbiAgICAgICAgYXNzZXJ0KGZpZWxkcyAhPT0gdW5kZWZpbmVkLCBcImZpZWxkcyBpcyB1bmRlZmluZWRcIik7XG5cbiAgICAgICAgLy8g7ZiE7J6sIO2FjOydtOu4lCDtlYTrk5zshYvsnYAgc2VsZWN0LCB2aXJ0dWFs7JeQIOy2lOqwgO2VmOqzoCDrpqzthLRcbiAgICAgICAgaWYgKGdyb3VwS2V5ID09PSBcIlwiKSB7XG4gICAgICAgICAgY29uc3QgcmVhbEZpZWxkcyA9IGZpZWxkcy5maWx0ZXIoKGZpZWxkKSA9PiAhaXNWaXJ0dWFsUHJvcCh0aGlzLnByb3BzRGljdFtmaWVsZF0pKTtcbiAgICAgICAgICAvLyB2aXJ0dWFsVHlwZTogXCJjb2RlXCIgKOuYkOuKlCB1bmRlZmluZWQp7J24IHZpcnR1YWwgcHJvcOunjCByLnZpcnR1YWzsl5Ag7LaU6rCAXG4gICAgICAgICAgLy8gdmlydHVhbFR5cGU6IFwicXVlcnlcIuyduCDqsr3smrAg7IKs7Jqp7J6Q6rCAIGFwcGVuZFNlbGVjdOuhnCDsp4HsoJEg7LaU6rCA7ZWY66+A66GcIOygnOyZuFxuICAgICAgICAgIGNvbnN0IHZpcnR1YWxDb2RlRmllbGRzID0gZmllbGRzLmZpbHRlcigoZmllbGQpID0+XG4gICAgICAgICAgICBpc1ZpcnR1YWxDb2RlUHJvcCh0aGlzLnByb3BzRGljdFtmaWVsZF0pLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAocHJlZml4ID09PSBcIlwiKSB7XG4gICAgICAgICAgICAvLyDtmITsnqwg7YWM7J2067iU7J24IOqyveyasFxuICAgICAgICAgICAgci5zZWxlY3QgPSByLnNlbGVjdC5jb25jYXQocmVhbEZpZWxkcy5tYXAoKGZpZWxkKSA9PiB0aGlzLmdldEZ1bGxGaWVsZE5hbWUoZmllbGQpKSk7XG4gICAgICAgICAgICByLnZpcnR1YWwgPSByLnZpcnR1YWwuY29uY2F0KHZpcnR1YWxDb2RlRmllbGRzKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8g64SY7Ja07JioIO2FjOydtOu4lOyduCDqsr3smrBcbiAgICAgICAgICAgIHIuc2VsZWN0ID0gci5zZWxlY3QuY29uY2F0KFxuICAgICAgICAgICAgICByZWFsRmllbGRzLm1hcCgoZmllbGQpID0+IGAke3ByZWZpeH0uJHtmaWVsZH0gYXMgJHtwcmVmaXh9X18ke2ZpZWxkfWApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlbGF0aW9uID0gdGhpcy5yZWxhdGlvbnNbZ3JvdXBLZXldO1xuICAgICAgICBpZiAocmVsYXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg7KG07J6s7ZWY7KeAIOyViuuKlCByZWxhdGlvbiDssLjsobAgJHtncm91cEtleX1gKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZWxFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChyZWxhdGlvbi53aXRoKTtcblxuICAgICAgICBpZiAoaXNPbmVUb09uZVJlbGF0aW9uUHJvcChyZWxhdGlvbikgfHwgaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocmVsYXRpb24pKSB7XG4gICAgICAgICAgLy8gLU9uZSBSZWxhdGlvbjogSk9JTiDsnLzroZwg7LKY66asXG4gICAgICAgICAgY29uc3QgcmVsRmllbGRzID0gZmllbGRzLm1hcCgoZmllbGQpID0+IGZpZWxkLnNwbGl0KFwiLlwiKS5zbGljZSgxKS5qb2luKFwiLlwiKSk7XG5cbiAgICAgICAgICAvLyAtT25lIFJlbGF0aW9u7JeQ7IScIGlkIO2VhOuTnOunjCDssLjsobDtlZjripQg6rK97JqwIOumtOugiOydtOyFmCDrhJjquLDsp4Ag7JWK6rOgIOumrO2EtFxuICAgICAgICAgIGlmIChyZWxGaWVsZHMubGVuZ3RoID09PSAxICYmIHJlbEZpZWxkc1swXSA9PT0gXCJpZFwiKSB7XG4gICAgICAgICAgICBpZiAocHJlZml4ID09PSBcIlwiKSB7XG4gICAgICAgICAgICAgIHIuc2VsZWN0ID0gci5zZWxlY3QuY29uY2F0KGAke3RoaXMudGFibGV9LiR7Z3JvdXBLZXl9X2lkYCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByLnNlbGVjdCA9IHIuc2VsZWN0LmNvbmNhdChgJHtwcmVmaXh9LiR7Z3JvdXBLZXl9X2lkIGFzICR7cHJlZml4fV9fJHtncm91cEtleX1faWRgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGlubmVyT3JPdXRlclxuICAgICAgICAgIGNvbnN0IGlubmVyT3JPdXRlciA9ICgoKSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNBbHJlYWR5T3V0ZXJKb2luZWQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIFwib3V0ZXJcIjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzT25lVG9PbmVSZWxhdGlvblByb3AocmVsYXRpb24pKSB7XG4gICAgICAgICAgICAgIGlmIChyZWxhdGlvbi5oYXNKb2luQ29sdW1uICYmICEocmVsYXRpb24ubnVsbGFibGUgPz8gZmFsc2UpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiaW5uZXJcIjtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJvdXRlclwiO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpZiAocmVsYXRpb24ubnVsbGFibGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJvdXRlclwiO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBcImlubmVyXCI7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KSgpO1xuICAgICAgICAgIGNvbnN0IHJlbFN1YnNldFF1ZXJ5ID0gcmVsRW50aXR5LnJlc29sdmVTdWJzZXRRdWVyeShcbiAgICAgICAgICAgIGAke3ByZWZpeCAhPT0gXCJcIiA/IGAke3ByZWZpeH0uYCA6IFwiXCJ9JHtncm91cEtleX1gLFxuICAgICAgICAgICAgcmVsRmllbGRzLFxuICAgICAgICAgICAgaW5uZXJPck91dGVyID09PSBcIm91dGVyXCIsXG4gICAgICAgICAgKTtcbiAgICAgICAgICByLnNlbGVjdCA9IHIuc2VsZWN0LmNvbmNhdChyZWxTdWJzZXRRdWVyeS5zZWxlY3QpO1xuICAgICAgICAgIHIudmlydHVhbCA9IHIudmlydHVhbC5jb25jYXQocmVsU3Vic2V0UXVlcnkudmlydHVhbCk7XG5cbiAgICAgICAgICBjb25zdCBqb2luQXMgPSBwcmVmaXggPT09IFwiXCIgPyBncm91cEtleSA6IGAke3ByZWZpeH1fXyR7Z3JvdXBLZXl9YDtcbiAgICAgICAgICBjb25zdCBmcm9tVGFibGUgPSBwcmVmaXggPT09IFwiXCIgPyB0aGlzLnRhYmxlIDogcHJlZml4O1xuXG4gICAgICAgICAgbGV0IGpvaW5DbGF1c2U6XG4gICAgICAgICAgICB8IHtcbiAgICAgICAgICAgICAgICBmcm9tOiBzdHJpbmc7XG4gICAgICAgICAgICAgICAgdG86IHN0cmluZztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfCB7XG4gICAgICAgICAgICAgICAgY3VzdG9tOiBzdHJpbmc7XG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKHJlbGF0aW9uLmN1c3RvbUpvaW5DbGF1c2UpIHtcbiAgICAgICAgICAgIGpvaW5DbGF1c2UgPSB7XG4gICAgICAgICAgICAgIGN1c3RvbTogcmVsYXRpb24uY3VzdG9tSm9pbkNsYXVzZSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmc7XG4gICAgICAgICAgICBpZiAoaXNPbmVUb09uZVJlbGF0aW9uUHJvcChyZWxhdGlvbikpIHtcbiAgICAgICAgICAgICAgaWYgKHJlbGF0aW9uLmhhc0pvaW5Db2x1bW4pIHtcbiAgICAgICAgICAgICAgICBmcm9tID0gYCR7ZnJvbVRhYmxlfS4ke3JlbGF0aW9uLm5hbWV9X2lkYDtcbiAgICAgICAgICAgICAgICB0byA9IGAke2pvaW5Bc30uaWRgO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZyb20gPSBgJHtmcm9tVGFibGV9LmlkYDtcbiAgICAgICAgICAgICAgICB0byA9IGAke2pvaW5Bc30uJHtpbmZsZWN0aW9uLnVuZGVyc2NvcmUodGhpcy5uYW1lcy5mcy5yZXBsYWNlKC8tL2csIFwiX1wiKSl9X2lkYDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZnJvbSA9IGAke2Zyb21UYWJsZX0uJHtyZWxhdGlvbi5uYW1lfV9pZGA7XG4gICAgICAgICAgICAgIHRvID0gYCR7am9pbkFzfS5pZGA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBqb2luQ2xhdXNlID0ge1xuICAgICAgICAgICAgICBmcm9tLFxuICAgICAgICAgICAgICB0byxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgci5qb2lucy5wdXNoKHtcbiAgICAgICAgICAgIGFzOiBqb2luQXMsXG4gICAgICAgICAgICBqb2luOiBpbm5lck9yT3V0ZXIsXG4gICAgICAgICAgICB0YWJsZTogcmVsRW50aXR5LnRhYmxlLFxuICAgICAgICAgICAgLi4uam9pbkNsYXVzZSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIEJlbG9uZ3NUb09uZSDrsJHsl5AgSGFzTWFueeqwgCDrtpnsnYAg6rK97JqwXG4gICAgICAgICAgaWYgKHJlbFN1YnNldFF1ZXJ5LmxvYWRlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgY29udmVydGVkTG9hZGVycyA9IHJlbFN1YnNldFF1ZXJ5LmxvYWRlcnMubWFwKChsb2FkZXIpID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgbmV3QXMgPSBbZ3JvdXBLZXksIGxvYWRlci5hc10uam9pbihcIl9fXCIpO1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGFzOiBuZXdBcyxcbiAgICAgICAgICAgICAgICB0YWJsZTogbG9hZGVyLnRhYmxlLFxuICAgICAgICAgICAgICAgIG1hbnlKb2luOiBsb2FkZXIubWFueUpvaW4sXG4gICAgICAgICAgICAgICAgb25lSm9pbnM6IGxvYWRlci5vbmVKb2lucyxcbiAgICAgICAgICAgICAgICBzZWxlY3Q6IGxvYWRlci5zZWxlY3QsXG4gICAgICAgICAgICAgICAgbG9hZGVyczogbG9hZGVyLmxvYWRlcnMsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgci5sb2FkZXJzID0gWy4uLnIubG9hZGVycywgLi4uY29udmVydGVkTG9hZGVyc107XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgci5qb2lucyA9IHIuam9pbnMuY29uY2F0KHJlbFN1YnNldFF1ZXJ5LmpvaW5zKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc0hhc01hbnlSZWxhdGlvblByb3AocmVsYXRpb24pIHx8IGlzTWFueVRvTWFueVJlbGF0aW9uUHJvcChyZWxhdGlvbikpIHtcbiAgICAgICAgICAvLyAtTWFueSBSZWxhdGlvbjogTG9hZGVyIOuhnCDsspjrpqxcbiAgICAgICAgICBjb25zdCByZWxGaWVsZHMgPSBmaWVsZHMubWFwKChmaWVsZCkgPT4gZmllbGQuc3BsaXQoXCIuXCIpLnNsaWNlKDEpLmpvaW4oXCIuXCIpKTtcbiAgICAgICAgICBjb25zdCByZWxTdWJzZXRRdWVyeSA9IHJlbEVudGl0eS5yZXNvbHZlU3Vic2V0UXVlcnkoXCJcIiwgcmVsRmllbGRzKTtcblxuICAgICAgICAgIGxldCBtYW55Sm9pbjogU3Vic2V0UXVlcnlbXCJsb2FkZXJzXCJdW251bWJlcl1bXCJtYW55Sm9pblwiXTtcbiAgICAgICAgICBpZiAoaXNIYXNNYW55UmVsYXRpb25Qcm9wKHJlbGF0aW9uKSkge1xuICAgICAgICAgICAgY29uc3QgZnJvbUNvbCA9IHJlbGF0aW9uPy5mcm9tQ29sdW1uID8/IFwiaWRcIjtcbiAgICAgICAgICAgIG1hbnlKb2luID0ge1xuICAgICAgICAgICAgICBmcm9tVGFibGU6IHRoaXMudGFibGUsXG4gICAgICAgICAgICAgIGZyb21Db2wsXG4gICAgICAgICAgICAgIGlkRmllbGQ6IHByZWZpeCA9PT0gXCJcIiA/IGAke2Zyb21Db2x9YCA6IGAke3ByZWZpeH1fXyR7ZnJvbUNvbH1gLFxuICAgICAgICAgICAgICB0b1RhYmxlOiByZWxFbnRpdHkudGFibGUsXG4gICAgICAgICAgICAgIHRvQ29sOiByZWxhdGlvbi5qb2luQ29sdW1uLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzTWFueVRvTWFueVJlbGF0aW9uUHJvcChyZWxhdGlvbikpIHtcbiAgICAgICAgICAgIG1hbnlKb2luID0ge1xuICAgICAgICAgICAgICBmcm9tVGFibGU6IHRoaXMudGFibGUsXG4gICAgICAgICAgICAgIGZyb21Db2w6IFwiaWRcIixcbiAgICAgICAgICAgICAgaWRGaWVsZDogcHJlZml4ID09PSBcIlwiID8gYGlkYCA6IGAke3ByZWZpeH1fX2lkYCxcbiAgICAgICAgICAgICAgdGhyb3VnaDoge1xuICAgICAgICAgICAgICAgIHRhYmxlOiByZWxhdGlvbi5qb2luVGFibGUsXG4gICAgICAgICAgICAgICAgZnJvbUNvbDogYCR7aW5mbGVjdGlvbi5zaW5ndWxhcml6ZSh0aGlzLnRhYmxlKX1faWRgLFxuICAgICAgICAgICAgICAgIHRvQ29sOiBgJHtpbmZsZWN0aW9uLnNpbmd1bGFyaXplKHJlbEVudGl0eS50YWJsZSl9X2lkYCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdG9UYWJsZTogcmVsRW50aXR5LnRhYmxlLFxuICAgICAgICAgICAgICB0b0NvbDogXCJpZFwiLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgci5sb2FkZXJzLnB1c2goe1xuICAgICAgICAgICAgYXM6IGdyb3VwS2V5LFxuICAgICAgICAgICAgdGFibGU6IHJlbEVudGl0eS50YWJsZSxcbiAgICAgICAgICAgIG1hbnlKb2luLFxuICAgICAgICAgICAgb25lSm9pbnM6IHJlbFN1YnNldFF1ZXJ5LmpvaW5zLFxuICAgICAgICAgICAgc2VsZWN0OiByZWxTdWJzZXRRdWVyeS5zZWxlY3QsXG4gICAgICAgICAgICBsb2FkZXJzOiByZWxTdWJzZXRRdWVyeS5sb2FkZXJzLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHI7XG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBzZWxlY3Q6IFtdLFxuICAgICAgICB2aXJ0dWFsOiBbXSxcbiAgICAgICAgam9pbnM6IFtdLFxuICAgICAgICBsb2FkZXJzOiBbXSxcbiAgICAgIH0gYXMgU3Vic2V0UXVlcnksXG4gICAgKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLypcbiAgICBGaWVsZEV4cHJbXSDsnYQgRW50aXR5UHJvcE5vZGVbXSDroZwg67OA7ZmYXG4gICovXG4gIGZpZWxkRXhwcnNUb1Byb3BOb2RlcyhmaWVsZEV4cHJzOiBzdHJpbmdbXSwgZW50aXR5OiBFbnRpdHkgPSB0aGlzKTogRW50aXR5UHJvcE5vZGVbXSB7XG4gICAgY29uc3QgZ3JvdXBzID0gZmllbGRFeHBycy5yZWR1Y2UoXG4gICAgICAocmVzdWx0LCBmaWVsZEV4cHIpID0+IHtcbiAgICAgICAgbGV0IGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBlbHNlRXhwcjogc3RyaW5nW107XG4gICAgICAgIGlmIChmaWVsZEV4cHIuaW5jbHVkZXMoXCIuXCIpKSB7XG4gICAgICAgICAgW2tleSwgLi4uZWxzZUV4cHJdID0gZmllbGRFeHByLnNwbGl0KFwiLlwiKTtcbiAgICAgICAgICB2YWx1ZSA9IGVsc2VFeHByLmpvaW4oXCIuXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGtleSA9IFwiXCI7XG4gICAgICAgICAgdmFsdWUgPSBmaWVsZEV4cHI7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0W2tleV0gPSAocmVzdWx0W2tleV0gPz8gW10pLmNvbmNhdCh2YWx1ZSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0sXG4gICAgICB7fSBhcyB7XG4gICAgICAgIFtrOiBzdHJpbmddOiBzdHJpbmdbXTtcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIHJldHVybiBPYmplY3Qua2V5cyhncm91cHMpLmZsYXRNYXA8RW50aXR5UHJvcE5vZGUsIEVudGl0eVByb3BOb2RlW10+KChrZXkpID0+IHtcbiAgICAgIGNvbnN0IGdyb3VwID0gZ3JvdXBzW2tleV07XG5cbiAgICAgIC8vIOydvOuwmCBwcm9wIOyymOumrFxuICAgICAgaWYgKGtleSA9PT0gXCJcIikge1xuICAgICAgICByZXR1cm4gZ3JvdXAubWFwKChwcm9wTmFtZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHByb3AgPSBlbnRpdHkucHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBwcm9wTmFtZSk7XG4gICAgICAgICAgaWYgKHByb3AgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICBgJHtlbnRpdHkuaWR9IC0tIOyemOuqu+uQnCBGaWVsZEV4cHIgJyR7cHJvcE5hbWV9JyAo7IKs7JqpIOqwgOuKpe2VnCBwcm9wczogJHtlbnRpdHkucHJvcHMubWFwKChwKSA9PiBwLm5hbWUpLmpvaW4oXCIsIFwiKX0pYCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBub2RlVHlwZTogXCJwbGFpblwiIGFzIGNvbnN0LFxuICAgICAgICAgICAgcHJvcCxcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gcmVsYXRpb24gcHJvcCDsspjrpqxcbiAgICAgIGNvbnN0IHByb3AgPSBlbnRpdHkucHJvcHNEaWN0W2tleV07XG4gICAgICBpZiAoIWlzUmVsYXRpb25Qcm9wKHByb3ApKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihg7J6Y66q765CcIEZpZWxkRXhwciAke2tleX0uJHtncm91cFswXX1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlbEVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KHByb3Aud2l0aCk7XG5cbiAgICAgIC8vIHJlbGF0aW9uIC1PbmUg7JeQIGlkIO2VhOuTnCDtlZjrgpjsnbgg6rK97JqwXG4gICAgICBpZiAoaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocHJvcCkgfHwgaXNPbmVUb09uZVJlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICBpZiAoZ3JvdXAubGVuZ3RoID09PSAxICYmIChncm91cFswXSA9PT0gXCJpZFwiIHx8IGdyb3VwWzBdID09PSBcImlkP1wiKSkge1xuICAgICAgICAgIC8vIGlkIO2VmOuCmOunjCDsnojripTsp4Ag7LK07YGs7ZW07IScLCDtlZjrgpjrp4wg7J6I7Jy866m0IOyDgeychCBwcm9w7Jy866GcIGlk66W8IOumrO2EtFxuICAgICAgICAgIGNvbnN0IGlkUHJvcCA9IHJlbEVudGl0eS5wcm9wc0RpY3QuaWQ7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG5vZGVUeXBlOiBcInBsYWluXCIgYXMgY29uc3QsXG4gICAgICAgICAgICBwcm9wOiB7XG4gICAgICAgICAgICAgIC4uLmlkUHJvcCxcbiAgICAgICAgICAgICAgbmFtZTogYCR7a2V5fV9pZGAsXG4gICAgICAgICAgICAgIG51bGxhYmxlOiBwcm9wLm51bGxhYmxlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIC1PbmUg6re47Jm47J2YIOqyveyasCBvYmplY3TroZwg66as7YS0XG4gICAgICAvLyAtTWFueeydmCDqsr3smrAgYXJyYXnroZwg66as7YS0XG4gICAgICAvLyBSZWN1cnNpdmUg66GcIOuOgeyKpCDsspjrpqxcbiAgICAgIGNvbnN0IGNoaWxkcmVuID0gdGhpcy5maWVsZEV4cHJzVG9Qcm9wTm9kZXMoZ3JvdXAsIHJlbEVudGl0eSk7XG4gICAgICBjb25zdCBub2RlVHlwZSA9XG4gICAgICAgIGlzQmVsb25nc1RvT25lUmVsYXRpb25Qcm9wKHByb3ApIHx8IGlzT25lVG9PbmVSZWxhdGlvblByb3AocHJvcClcbiAgICAgICAgICA/IChcIm9iamVjdFwiIGFzIGNvbnN0KVxuICAgICAgICAgIDogKFwiYXJyYXlcIiBhcyBjb25zdCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5vZGVUeXBlLFxuICAgICAgICBwcm9wLFxuICAgICAgICBjaGlsZHJlbixcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBnZXRGaWVsZEV4cHJzKHByZWZpeCA9IFwiXCIsIG1heERlcHRoOiBudW1iZXIgPSAzLCBmcm9tczogc3RyaW5nW10gPSBbXSk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5wcm9wc1xuICAgICAgLmZsYXRNYXAoKHByb3ApID0+IHtcbiAgICAgICAgY29uc3QgcHJvcE5hbWUgPSBbcHJlZml4LCBwcm9wLm5hbWVdLmZpbHRlcigodikgPT4gdiAhPT0gXCJcIikuam9pbihcIi5cIik7XG4gICAgICAgIGlmIChwcm9wTmFtZSA9PT0gcHJlZml4KSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzUmVsYXRpb25Qcm9wKHByb3ApKSB7XG4gICAgICAgICAgaWYgKG1heERlcHRoIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChmcm9tcy5pbmNsdWRlcyhwcm9wLndpdGgpKSB7XG4gICAgICAgICAgICAvLyDsl63rsKntlqUgcmVsYXRpb27snbgg6rK97JqwIOygnOyZuFxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIOygleuwqe2WpSByZWxhdGlvbuyduCDqsr3smrAgcmVjdXJzaXZlIOy9nFxuICAgICAgICAgIGNvbnN0IHJlbE1kID0gRW50aXR5TWFuYWdlci5nZXQocHJvcC53aXRoKTtcbiAgICAgICAgICByZXR1cm4gcmVsTWQuZ2V0RmllbGRFeHBycyhwcm9wTmFtZSwgbWF4RGVwdGggLSAxLCBbLi4uZnJvbXMsIHRoaXMuaWRdKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvcE5hbWU7XG4gICAgICB9KVxuICAgICAgLmZpbHRlcigoZikgPT4gZiAhPT0gbnVsbCk7XG4gIH1cblxuICAvKipcbiAgICogUmVsYXRpb24gcHJvcOydtCDtmITsnqwg7YWM7J2067iU7JeQIEZLIOy7rOufvOydhCDsg53shLHtlZjripTsp4Ag7ZmV7J24XG4gICAqKEJlbG9uZ3NUb09uZSDrmJDripQgT25lVG9PbmUoaGFzSm9pbkNvbHVtbj10cnVlKeyduCDqsr3smrAgRksg7IOd7ISxKVxuICAgKi9cbiAgcHJpdmF0ZSBoYXNGb3JlaWduS2V5KHByb3A6IFJlbGF0aW9uUHJvcCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICBwcm9wLnJlbGF0aW9uVHlwZSA9PT0gXCJCZWxvbmdzVG9PbmVcIiB8fFxuICAgICAgKHByb3AucmVsYXRpb25UeXBlID09PSBcIk9uZVRvT25lXCIgJiYgcHJvcC5oYXNKb2luQ29sdW1uKVxuICAgICk7XG4gIH1cblxuICBnZXRUYWJsZUNvbHVtbnMoKTogeyBuYW1lOiBzdHJpbmc7IHR5cGU6IHN0cmluZyB9W10ge1xuICAgIHJldHVybiB0aGlzLnByb3BzXG4gICAgICAubWFwKChwcm9wKSA9PiB7XG4gICAgICAgIGlmIChwcm9wLnR5cGUgPT09IFwicmVsYXRpb25cIikge1xuICAgICAgICAgIGlmICh0aGlzLmhhc0ZvcmVpZ25LZXkocHJvcCkpIHtcbiAgICAgICAgICAgIHJldHVybiB7IG5hbWU6IGAke3Byb3AubmFtZX1faWRgLCB0eXBlOiBcImludF91bnNpZ25lZFwiIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBuYW1lOiBwcm9wLm5hbWUsIHR5cGU6IHByb3AudHlwZSB9O1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIobm9uTnVsbGFibGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVudGl0eeyXkCDsoJXsnZjrkJwg66qo65OgIHZlY3RvciDtg4DsnoUg7Lus65+8IOuwmO2ZmFxuICAgKi9cbiAgZ2V0VmVjdG9yQ29sdW1ucygpOiBFbnRpdHlQcm9wW10ge1xuICAgIHJldHVybiB0aGlzLnByb3BzLmZpbHRlcigocCkgPT4gcC50eXBlID09PSBcInZlY3RvclwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDtirnsoJUgdmVjdG9yIOy7rOufvCDrsJjtmZhcbiAgICogQHBhcmFtIGNvbHVtbk5hbWUgLSDsu6zrn7zrqoUgKOyDneuetSDsi5wg7LKrIOuyiOynuCB2ZWN0b3Ig7Lus65+8KVxuICAgKi9cbiAgZ2V0VmVjdG9yQ29sdW1uKGNvbHVtbk5hbWU/OiBzdHJpbmcpOiBFbnRpdHlQcm9wIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCB2ZWN0b3JQcm9wcyA9IHRoaXMuZ2V0VmVjdG9yQ29sdW1ucygpO1xuICAgIGlmIChjb2x1bW5OYW1lKSB7XG4gICAgICByZXR1cm4gdmVjdG9yUHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBjb2x1bW5OYW1lKTtcbiAgICB9XG4gICAgcmV0dXJuIHZlY3RvclByb3BzWzBdO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VhO2EsOungSDqsIDriqXtlZwgcHJvcHMg67CY7ZmYXG4gICAqXG4gICAqIC0g7J2867CYIHByb3BcbiAgICogLSBGS+ulvCDsg53shLHtlZjripQgcmVsYXRpb24gKEJlbG9uZ3NUb09uZSwgT25lVG9PbmUgd2l0aCBoYXNKb2luQ29sdW1uKVxuICAgKiAgIOKGkiB7bmFtZX1faWQg7ZiV7YOc7J2YIOqwgOyDgSBpbnRlZ2VyIHByb3DsnLzroZwg67OA7ZmYXG4gICAqL1xuICBnZXRGaWx0ZXJhYmxlUHJvcHMoKTogRW50aXR5UHJvcFtdIHtcbiAgICByZXR1cm4gdGhpcy5wcm9wcy5mbGF0TWFwKChwcm9wKTogRW50aXR5UHJvcCB8IEVudGl0eVByb3BbXSA9PiB7XG4gICAgICAvLyBWaXJ0dWFsIHByb3Ag7KCc7Jm4XG4gICAgICBpZiAoaXNWaXJ0dWFsUHJvcChwcm9wKSkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG5cbiAgICAgIC8vIFJlbGF0aW9uIHByb3Ag7LKY66asXG4gICAgICBpZiAoaXNSZWxhdGlvblByb3AocHJvcCkpIHtcbiAgICAgICAgLy8gRkvrpbwg7IOd7ISx7ZWY64qUIHJlbGF0aW9u66eMIO2PrO2VqFxuICAgICAgICBpZiAodGhpcy5oYXNGb3JlaWduS2V5KHByb3ApKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG5hbWU6IGAke3Byb3AubmFtZX1faWRgLFxuICAgICAgICAgICAgdHlwZTogXCJpbnRlZ2VyXCIsXG4gICAgICAgICAgICBudWxsYWJsZTogcHJvcC5udWxsYWJsZSxcbiAgICAgICAgICB9IGFzIEVudGl0eVByb3A7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuXG4gICAgICAvLyDsnbzrsJggcHJvcCDsspjrpqxcbiAgICAgIHJldHVybiBwcm9wO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgcmVnaXN0ZXJNb2R1bGVQYXRocygpIHtcbiAgICBjb25zdCBiYXNlUGF0aCA9IGAke3RoaXMubmFtZXMucGFyZW50RnN9YDtcblxuICAgIC8vIGJhc2Utc2NoZW1lXG4gICAgRW50aXR5TWFuYWdlci5zZXRNb2R1bGVQYXRoKGAke3RoaXMuaWR9QmFzZVNjaGVtYWAsIGBzb25hbXUuZ2VuZXJhdGVkYCk7XG5cbiAgICAvLyBzdWJzZXRcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5zdWJzZXRzKS5sZW5ndGggPiAwKSB7XG4gICAgICBFbnRpdHlNYW5hZ2VyLnNldE1vZHVsZVBhdGgoYCR7dGhpcy5pZH1TdWJzZXRLZXlgLCBgc29uYW11LmdlbmVyYXRlZGApO1xuICAgICAgRW50aXR5TWFuYWdlci5zZXRNb2R1bGVQYXRoKGAke3RoaXMuaWR9U3Vic2V0TWFwcGluZ2AsIGBzb25hbXUuZ2VuZXJhdGVkYCk7XG4gICAgICBmb3IgKGNvbnN0IHN1YnNldEtleSBvZiBPYmplY3Qua2V5cyh0aGlzLnN1YnNldHMpKSB7XG4gICAgICAgIEVudGl0eU1hbmFnZXIuc2V0TW9kdWxlUGF0aChcbiAgICAgICAgICBgJHt0aGlzLmlkfVN1YnNldCR7c3Vic2V0S2V5LnRvVXBwZXJDYXNlKCl9YCxcbiAgICAgICAgICBgc29uYW11LmdlbmVyYXRlZGAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gZW51bXNcbiAgICBmb3IgKGNvbnN0IGVudW1JZCBvZiBPYmplY3Qua2V5cyh0aGlzLmVudW1MYWJlbHMpKSB7XG4gICAgICBFbnRpdHlNYW5hZ2VyLnNldE1vZHVsZVBhdGgoZW51bUlkLCBgc29uYW11LmdlbmVyYXRlZGApO1xuICAgIH1cblxuICAgIC8vIHR5cGVzXG4gICAgY29uc3QgdHlwZXNNb2R1bGVQYXRoID0gYCR7YmFzZVBhdGh9LyR7dGhpcy5uYW1lcy5wYXJlbnRGc30udHlwZXNgO1xuICAgIGNvbnN0IHR5cGVzRmlsZVBhdGggPSBwYXRoLmpvaW4oXG4gICAgICBTb25hbXUuYXBpUm9vdFBhdGgsXG4gICAgICBydW50aW1lUGF0aChgZGlzdC9hcHBsaWNhdGlvbi8ke3R5cGVzTW9kdWxlUGF0aH0uanNgKSxcbiAgICApO1xuXG4gICAgaWYgKGF3YWl0IGV4aXN0cyh0eXBlc0ZpbGVQYXRoKSkge1xuICAgICAgY29uc3QgaW1wb3J0ZWRNZW1iZXJzID0gYXdhaXQgaW1wb3J0TWVtYmVyczx6LlpvZFR5cGVBbnk+KHR5cGVzRmlsZVBhdGgpO1xuICAgICAgdGhpcy50eXBlcyA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgaW1wb3J0ZWRNZW1iZXJzLm1hcCgoeyBuYW1lLCB2YWx1ZSB9KSA9PiB7XG4gICAgICAgICAgRW50aXR5TWFuYWdlci5zZXRNb2R1bGVQYXRoKG5hbWUsIHR5cGVzTW9kdWxlUGF0aCk7XG4gICAgICAgICAgcmV0dXJuIFtuYW1lLCB2YWx1ZV07XG4gICAgICAgIH0pLFxuICAgICAgKSBhcyB7IFtuYW1lOiBzdHJpbmddOiB6LlpvZFR5cGVBbnkgfTtcbiAgICB9XG4gIH1cblxuICByZWdpc3RlclRhYmxlU3BlY3MoKTogdm9pZCB7XG4gICAgLy8g7KGw7J24IO2FjOydtOu4lCDsnbjrjbHsiqQg7KCc7Jm4ICjsu6zrn7wg7J2066aE7JeQICcuJ+ydtCDtj6ztlajrkJwg6rK97JqwKVxuICAgIGNvbnN0IHVuaXF1ZUluZGV4ZXMgPSB0aGlzLmluZGV4ZXNcbiAgICAgIC5maWx0ZXIoKGlkeCkgPT4gaWR4LnR5cGUgPT09IFwidW5pcXVlXCIpXG4gICAgICAuZmlsdGVyKChpZHgpID0+IGlkeC5jb2x1bW5zLmV2ZXJ5KChjb2wpID0+ICFjb2wubmFtZS5pbmNsdWRlcyhcIi5cIikpKTtcblxuICAgIEVudGl0eU1hbmFnZXIuc2V0VGFibGVTcGVjKHtcbiAgICAgIG5hbWU6IHRoaXMudGFibGUsXG4gICAgICB1bmlxdWVJbmRleGVzLFxuICAgICAganNvbkNvbHVtbnM6IHRoaXMucHJvcHMuZmlsdGVyKChwKSA9PiBwLnR5cGUgPT09IFwianNvblwiKS5tYXAoKHApID0+IHAubmFtZSksXG4gICAgfSk7XG4gIH1cblxuICB0b0pzb24oKTogRW50aXR5SnNvbiB7XG4gICAgLy8gc3Vic2V0c+yZgCBzdWJzZXRzSW50ZXJuYWzsnYQgU3Vic2V0RGVmIO2Yle2DnOuhnCDrs7Xsm5AgKGNvbmUg7Y+s7ZWoKVxuICAgIGNvbnN0IHN1YnNldHM6IHsgW2tleTogc3RyaW5nXTogaW1wb3J0KFwiLi4vdHlwZXMvdHlwZXNcIikuU3Vic2V0RGVmIH0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLnN1YnNldHMpKSB7XG4gICAgICBjb25zdCBub3JtYWxGaWVsZHM6IFN1YnNldEZpZWxkW10gPSB0aGlzLnN1YnNldHNba2V5XTtcbiAgICAgIGNvbnN0IGludGVybmFsRmllbGRzOiBTdWJzZXRGaWVsZFtdID0gKHRoaXMuc3Vic2V0c0ludGVybmFsW2tleV0gPz8gW10pLm1hcCgoZmllbGQpID0+ICh7XG4gICAgICAgIGZpZWxkLFxuICAgICAgICBpbnRlcm5hbDogdHJ1ZSxcbiAgICAgIH0pKTtcbiAgICAgIGNvbnN0IGZpZWxkcyA9IFsuLi5ub3JtYWxGaWVsZHMsIC4uLmludGVybmFsRmllbGRzXTtcblxuICAgICAgLy8gY29uZeydtCDsnojsnLzrqbQg7IOI66Gc7Jq0IOqwneyytCDtmJXtg5zroZwsIOyXhuycvOuptCDrsLDsl7Qg7ZiV7YOc66GcXG4gICAgICBpZiAodGhpcy5zdWJzZXRDb25lc1trZXldKSB7XG4gICAgICAgIHN1YnNldHNba2V5XSA9IHtcbiAgICAgICAgICBmaWVsZHMsXG4gICAgICAgICAgY29uZTogdGhpcy5zdWJzZXRDb25lc1trZXldLFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3Vic2V0c1trZXldID0gZmllbGRzO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGVudW1z66W8IEVudW1EZWYg7ZiV7YOc66GcIOuzteybkCAoY29uZSDtj6ztlagpXG4gICAgY29uc3QgZW51bXM6IHsgW2tleTogc3RyaW5nXTogaW1wb3J0KFwiLi4vdHlwZXMvdHlwZXNcIikuRW51bURlZiB9ID0ge307XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZXNdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuZW51bUxhYmVscykpIHtcbiAgICAgIC8vIGNvbmXsnbQg7J6I7Jy866m0IOyDiOuhnOyatCDqsJ3ssrQg7ZiV7YOc66GcLCDsl4bsnLzrqbQgUmVjb3JkIO2Yle2DnOuhnFxuICAgICAgaWYgKHRoaXMuZW51bUNvbmVzW2tleV0pIHtcbiAgICAgICAgZW51bXNba2V5XSA9IHtcbiAgICAgICAgICB2YWx1ZXMsXG4gICAgICAgICAgY29uZTogdGhpcy5lbnVtQ29uZXNba2V5XSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVudW1zW2tleV0gPSB2YWx1ZXM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgcGFyZW50SWQ6IHRoaXMucGFyZW50SWQsXG4gICAgICB0YWJsZTogdGhpcy50YWJsZSxcbiAgICAgIHRpdGxlOiB0aGlzLnRpdGxlLFxuICAgICAgY29uZTogdGhpcy5jb25lLFxuICAgICAgcHJvcHM6IHRoaXMucHJvcHMsXG4gICAgICBpbmRleGVzOiB0aGlzLmluZGV4ZXMsXG4gICAgICBzdWJzZXRzLFxuICAgICAgZW51bXMsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIHNhdmUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gc29ydDogc3Vic2V0c1xuICAgIGNvbnN0IHN1YnNldFJvd3MgPSB0aGlzLmdldFN1YnNldFJvd3MoKTtcbiAgICB0aGlzLnN1YnNldHMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QuZW50cmllcyh0aGlzLnN1YnNldHMpLm1hcCgoW3N1YnNldEtleV0pID0+IHtcbiAgICAgICAgcmV0dXJuIFtzdWJzZXRLZXksIHRoaXMuc3Vic2V0Um93c1RvU3Vic2V0RmllbGRzKHN1YnNldFJvd3MsIHN1YnNldEtleSwgZmFsc2UpXTtcbiAgICAgIH0pLFxuICAgICk7XG4gICAgdGhpcy5zdWJzZXRzSW50ZXJuYWwgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QuZW50cmllcyh0aGlzLnN1YnNldHNJbnRlcm5hbCkubWFwKChbc3Vic2V0S2V5XSkgPT4ge1xuICAgICAgICByZXR1cm4gW3N1YnNldEtleSwgdGhpcy5zdWJzZXRSb3dzVG9TdWJzZXRGaWVsZHMoc3Vic2V0Um93cywgc3Vic2V0S2V5LCB0cnVlKV07XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgLy8gc2F2ZVxuICAgIGNvbnN0IGpzb25QYXRoID0gcGF0aC5qb2luKFxuICAgICAgU29uYW11LmFwaVJvb3RQYXRoLFxuICAgICAgYHNyYy9hcHBsaWNhdGlvbi8ke3RoaXMubmFtZXMucGFyZW50RnN9LyR7dGhpcy5uYW1lcy5mc30uZW50aXR5Lmpzb25gLFxuICAgICk7XG4gICAgY29uc3QganNvbiA9IHRoaXMudG9Kc29uKCk7XG4gICAgYXdhaXQgd3JpdGVGaWxlKGpzb25QYXRoLCBhd2FpdCBmb3JtYXRDb2RlKEpTT04uc3RyaW5naWZ5KGpzb24pLCBqc29uUGF0aCkpO1xuXG4gICAgLy8gcmVsb2FkXG4gICAgYXdhaXQgRW50aXR5TWFuYWdlci5yZWdpc3Rlcihqc29uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDthZztlIzrpr8gY29uZSDrqZTtg4DrjbDsnbTthLDrpbwg7IOd7ISx7ZWp64uI64ukLlxuICAgKlxuICAgKiBMTE3snYQg7IKs7Jqp7ZWY7KeAIOyViuqzoCBmYWtlci1tYXBwaW5ncy50c+ulvCDtmZzsmqntlZjsl6wg6riw67O4IGNvbmXsnYQg7IOd7ISx7ZWp64uI64ukLlxuICAgKiBzdHViIGVudGl0eSDsg53shLEg7IucIOyekOuPmeycvOuhnCDtmLjstpzrkJjslrQg7LWc7IaM7ZWc7J2YIGNvbmUg66mU7YOA642w7J207YSw66W8IOygnOqzte2VqeuLiOuLpC5cbiAgICpcbiAgICogQHBhcmFtIGxvY2FsZSAtIOyDneyEsSDsi5wg7IKs7Jqp7ZWgIGxvY2FsZSAo6riw67O46rCSOiBTb25hbXUuY29uZmlnLmkxOG4uZGVmYXVsdExvY2FsZSDrmJDripQgXCJrb1wiKVxuICAgKi9cbiAgYXN5bmMgZ2VuZXJhdGVUZW1wbGF0ZUNvbmVzKGxvY2FsZT86IFwia29cIiB8IFwiZW5cIiB8IFwiamFcIik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgZ2VuZXJhdGVUZW1wbGF0ZUNvbmVzIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2VudGl0eS10ZW1wbGF0ZS1jb25lXCIpO1xuICAgIGNvbnN0IGNvbmZpZ0xvY2FsZSA9IFNvbmFtdS5jb25maWcuaTE4bj8uZGVmYXVsdExvY2FsZTtcbiAgICBjb25zdCBlZmZlY3RpdmVMb2NhbGUgPVxuICAgICAgbG9jYWxlIHx8XG4gICAgICAoY29uZmlnTG9jYWxlID09PSBcImtvXCIgfHwgY29uZmlnTG9jYWxlID09PSBcImVuXCIgfHwgY29uZmlnTG9jYWxlID09PSBcImphXCJcbiAgICAgICAgPyBjb25maWdMb2NhbGVcbiAgICAgICAgOiBcImtvXCIpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGdlbmVyYXRlVGVtcGxhdGVDb25lcyh0aGlzLnRvSnNvbigpLCBlZmZlY3RpdmVMb2NhbGUpO1xuXG4gICAgLy8g6rKw6rO866W8IEVudGl0eeyXkCDsoIHsmqkgKGFwcGx5Q29uZXPsmYAg64+Z7J287ZWcIOuwqeyLnSlcbiAgICBpZiAocmVzdWx0LmVudGl0eUNvbmUpIHtcbiAgICAgIHRoaXMuY29uZSA9IHJlc3VsdC5lbnRpdHlDb25lO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgW3Byb3BOYW1lLCBjb25lXSBvZiBPYmplY3QuZW50cmllcyhyZXN1bHQucHJvcENvbmVzKSkge1xuICAgICAgY29uc3QgcHJvcCA9IHRoaXMucHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBwcm9wTmFtZSk7XG4gICAgICBpZiAocHJvcCkge1xuICAgICAgICAocHJvcCBhcyB7IGNvbmU/OiBDb25lIH0pLmNvbmUgPSBjb25lO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZW51bUNvbmVzID0geyAuLi50aGlzLmVudW1Db25lcywgLi4ucmVzdWx0LmVudW1Db25lcyB9O1xuICAgIHRoaXMuc3Vic2V0Q29uZXMgPSB7IC4uLnRoaXMuc3Vic2V0Q29uZXMsIC4uLnJlc3VsdC5zdWJzZXRDb25lcyB9O1xuXG4gICAgYXdhaXQgdGhpcy5zYXZlKCk7XG4gIH1cblxuICAvKipcbiAgICogTExN7J2EIOyCrOyaqe2VmOyXrCBjb25lIOuplO2DgOuNsOydtO2EsOulvCDsg53shLHtlanri4jri6QuXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpb25zLnByZXNlcnZlRXhpc3RpbmcgLSDquLDsobQgY29uZSDrs7TsobQg7Jes67aAICjquLDrs7jqsJI6IHRydWUpXG4gICAqIEBwYXJhbSBvcHRpb25zLm9ubHlFbXB0eSAtIGZpeHR1cmVIaW506rCAIOyXhuuKlCBjb25l66eMIOyDneyEsSAo6riw67O46rCSOiBmYWxzZSlcbiAgICogQHBhcmFtIG9wdGlvbnMubG9jYWxlIC0g7IOd7ISxIOyLnCDsgqzsmqntlaAgbG9jYWxlICjquLDrs7jqsJI6IFwia29cIilcbiAgICovXG4gIGFzeW5jIGdlbmVyYXRlQ29uZXMob3B0aW9ucz86IHtcbiAgICBwcmVzZXJ2ZUV4aXN0aW5nPzogYm9vbGVhbjtcbiAgICBvbmx5RW1wdHk/OiBib29sZWFuO1xuICAgIGxvY2FsZT86IFwia29cIiB8IFwiZW5cIiB8IFwiamFcIjtcbiAgfSk6IFByb21pc2U8aW1wb3J0KFwiLi4vY29uZS9jb25lLWdlbmVyYXRvclwiKS5Db25lR2VuZXJhdGlvblJlc3VsdD4ge1xuICAgIGNvbnN0IHsgZ2VuZXJhdGVDb25lcyB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vY29uZS9jb25lLWdlbmVyYXRvclwiKTtcbiAgICBjb25zdCBjb250ZXh0OiBpbXBvcnQoXCIuLi9jb25lL2NvbmUtZ2VuZXJhdG9yXCIpLkNvbmVHZW5lcmF0aW9uQ29udGV4dCA9IHtcbiAgICAgIGVudGl0eTogdGhpcy50b0pzb24oKSxcbiAgICAgIGxvY2FsZTogb3B0aW9ucz8ubG9jYWxlIHx8IFwia29cIixcbiAgICAgIGV4aXN0aW5nQ29uZXM6IG9wdGlvbnM/LnByZXNlcnZlRXhpc3RpbmcgIT09IGZhbHNlID8gdGhpcy5jb2xsZWN0RXhpc3RpbmdDb25lcygpIDogdW5kZWZpbmVkLFxuICAgICAgb25seUVtcHR5OiBvcHRpb25zPy5vbmx5RW1wdHkgPz8gZmFsc2UsXG4gICAgfTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdlbmVyYXRlQ29uZXMoY29udGV4dCk7XG4gICAgdGhpcy5hcHBseUNvbmVzKHJlc3VsdCk7XG4gICAgYXdhaXQgdGhpcy5zYXZlKCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiDquLDsobQgY29uZeuTpOydhCDsiJjsp5Htlanri4jri6QgKGVudGl0eSwgcHJvcHMsIGVudW1zLCBzdWJzZXRzKS5cbiAgICpcbiAgICogQHJldHVybnMg7YKk6rCAIFwiZW50aXR5OmlkXCIsIFwicHJvcDpuYW1lXCIsIFwiZW51bTplbnVtSWRcIiwgXCJzdWJzZXQ6a2V5XCIg7ZiV7Iud7J24IGNvbmUg66e1XG4gICAqL1xuICBwcml2YXRlIGNvbGxlY3RFeGlzdGluZ0NvbmVzKCk6IFJlY29yZDxzdHJpbmcsIENvbmU+IHtcbiAgICBjb25zdCBjb25lczogUmVjb3JkPHN0cmluZywgQ29uZT4gPSB7fTtcblxuICAgIGlmICh0aGlzLmNvbmUpIHtcbiAgICAgIGNvbmVzW2BlbnRpdHk6JHt0aGlzLmlkfWBdID0gdGhpcy5jb25lO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcHJvcCBvZiB0aGlzLnByb3BzKSB7XG4gICAgICBpZiAocHJvcC5jb25lKSB7XG4gICAgICAgIGNvbmVzW2Bwcm9wOiR7cHJvcC5uYW1lfWBdID0gcHJvcC5jb25lO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgW2VudW1JZCwgY29uZV0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5lbnVtQ29uZXMpKSB7XG4gICAgICBjb25lc1tgZW51bToke2VudW1JZH1gXSA9IGNvbmU7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbc3Vic2V0S2V5LCBjb25lXSBvZiBPYmplY3QuZW50cmllcyh0aGlzLnN1YnNldENvbmVzKSkge1xuICAgICAgY29uZXNbYHN1YnNldDoke3N1YnNldEtleX1gXSA9IGNvbmU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbmVzO1xuICB9XG5cbiAgLyoqXG4gICAqIOyDneyEseuQnCBjb25l65Ok7J2EIEVudGl0eeyXkCDsoIHsmqntlanri4jri6QuXG4gICAqXG4gICAqIEBwYXJhbSByZXN1bHQgLSBMTE3snLzroZwg7IOd7ISx65CcIGNvbmUg6rKw6rO8XG4gICAqL1xuICBwcml2YXRlIGFwcGx5Q29uZXMocmVzdWx0OiBpbXBvcnQoXCIuLi9jb25lL2NvbmUtZ2VuZXJhdG9yXCIpLkNvbmVHZW5lcmF0aW9uUmVzdWx0KTogdm9pZCB7XG4gICAgaWYgKHJlc3VsdC5lbnRpdHlDb25lKSB7XG4gICAgICB0aGlzLmNvbmUgPSByZXN1bHQuZW50aXR5Q29uZTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IFtwcm9wTmFtZSwgY29uZV0gb2YgT2JqZWN0LmVudHJpZXMocmVzdWx0LnByb3BDb25lcykpIHtcbiAgICAgIGNvbnN0IHByb3AgPSB0aGlzLnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gcHJvcE5hbWUpO1xuICAgICAgaWYgKHByb3ApIHtcbiAgICAgICAgKHByb3AgYXMgeyBjb25lPzogQ29uZSB9KS5jb25lID0gY29uZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmVudW1Db25lcyA9IHsgLi4udGhpcy5lbnVtQ29uZXMsIC4uLnJlc3VsdC5lbnVtQ29uZXMgfTtcbiAgICB0aGlzLnN1YnNldENvbmVzID0geyAuLi50aGlzLnN1YnNldENvbmVzLCAuLi5yZXN1bHQuc3Vic2V0Q29uZXMgfTtcbiAgfVxuXG4gIGdldFN1YnNldFJvd3MoXG4gICAgX3N1YnNldHM/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZ1tdIH0sXG4gICAgX3N1YnNldHNJbnRlcm5hbD86IHsgW2tleTogc3RyaW5nXTogc3RyaW5nW10gfSxcbiAgICBwcmVmaXhlczogc3RyaW5nW10gPSBbXSxcbiAgKTogRW50aXR5U3Vic2V0Um93W10ge1xuICAgIGlmIChwcmVmaXhlcy5sZW5ndGggPiAxMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGNvbnN0IHN1YnNldHMgPSBfc3Vic2V0cyA/PyB0aGlzLnN1YnNldHM7XG4gICAgY29uc3Qgc3Vic2V0c0ludGVybmFsID0gX3N1YnNldHNJbnRlcm5hbCA/PyB0aGlzLnN1YnNldHNJbnRlcm5hbDtcbiAgICBjb25zdCBzdWJzZXRLZXlzID0gT2JqZWN0LmtleXMoc3Vic2V0cyk7XG4gICAgY29uc3QgYWxsRmllbGRzID0gdW5pcXVlKHN1YnNldEtleXMuZmxhdE1hcCgoa2V5KSA9PiBzdWJzZXRzW2tleV0pKTtcbiAgICAvLyBpbnRlcm5hbCDtlYTrk5zrj4QgYWxsRmllbGRz7JeQIO2PrO2VqCAocmVsYXRpb24g7YOQ7IOJ7JqpKVxuICAgIGNvbnN0IGFsbEludGVybmFsRmllbGRzID0gdW5pcXVlKHN1YnNldEtleXMuZmxhdE1hcCgoa2V5KSA9PiBzdWJzZXRzSW50ZXJuYWxba2V5XSA/PyBbXSkpO1xuICAgIGNvbnN0IGNvbWJpbmVkRmllbGRzID0gdW5pcXVlKFsuLi5hbGxGaWVsZHMsIC4uLmFsbEludGVybmFsRmllbGRzXSk7XG5cbiAgICByZXR1cm4gdGhpcy5wcm9wcy5tYXAoKHByb3ApID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgcHJvcC50eXBlID09PSBcInJlbGF0aW9uXCIgJiZcbiAgICAgICAgY29tYmluZWRGaWVsZHMuZmluZCgoZikgPT4gZi5zdGFydHNXaXRoKGAke1suLi5wcmVmaXhlcywgcHJvcC5uYW1lXS5qb2luKFwiLlwiKX0uYCkpXG4gICAgICApIHtcbiAgICAgICAgY29uc3QgcmVsRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocHJvcC53aXRoKTtcbiAgICAgICAgY29uc3QgY2hpbGRyZW4gPSByZWxFbnRpdHkuZ2V0U3Vic2V0Um93cyhzdWJzZXRzLCBzdWJzZXRzSW50ZXJuYWwsIFtcbiAgICAgICAgICAuLi5wcmVmaXhlcyxcbiAgICAgICAgICBgJHtwcm9wLm5hbWV9YCxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBmaWVsZDogcHJvcC5uYW1lLFxuICAgICAgICAgIGNoaWxkcmVuLFxuICAgICAgICAgIHJlbGF0aW9uRW50aXR5OiBwcm9wLndpdGgsXG4gICAgICAgICAgcHJlZml4ZXMsXG4gICAgICAgICAgaXNPcGVuOiBjaGlsZHJlbi5sZW5ndGggPiAwLFxuICAgICAgICAgIGhhczogT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgICAgc3Vic2V0S2V5cy5tYXAoKHN1YnNldEtleSkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gW3N1YnNldEtleSwgY2hpbGRyZW4uZXZlcnkoKGNoaWxkKSA9PiBjaGlsZC5oYXNbc3Vic2V0S2V5XSldO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKSxcbiAgICAgICAgICBpc0ludGVybmFsOiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgICAgICBzdWJzZXRLZXlzLm1hcCgoc3Vic2V0S2V5KSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBbc3Vic2V0S2V5LCBjaGlsZHJlbi5ldmVyeSgoY2hpbGQpID0+IGNoaWxkLmlzSW50ZXJuYWxbc3Vic2V0S2V5XSldO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKSxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZmllbGQgPSBbLi4ucHJlZml4ZXMsIHByb3AubmFtZV0uam9pbihcIi5cIik7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBmaWVsZDogcHJvcC5uYW1lLFxuICAgICAgICBjaGlsZHJlbjogW10sXG4gICAgICAgIHJlbGF0aW9uRW50aXR5OiBwcm9wLnR5cGUgPT09IFwicmVsYXRpb25cIiA/IHByb3Aud2l0aCA6IHVuZGVmaW5lZCxcbiAgICAgICAgcHJlZml4ZXMsXG4gICAgICAgIGhhczogT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgIHN1YnNldEtleXMubWFwKChzdWJzZXRLZXkpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN1YnNldEZpZWxkcyA9IHN1YnNldHNbc3Vic2V0S2V5XTtcbiAgICAgICAgICAgIGNvbnN0IGhhcyA9IHN1YnNldEZpZWxkcy5zb21lKChmKSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBmID09PSBmaWVsZCB8fCBmLnN0YXJ0c1dpdGgoYCR7ZmllbGR9LmApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gW3N1YnNldEtleSwgaGFzXTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKSxcbiAgICAgICAgaXNJbnRlcm5hbDogT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgIHN1YnNldEtleXMubWFwKChzdWJzZXRLZXkpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGludGVybmFsRmllbGRzID0gc3Vic2V0c0ludGVybmFsW3N1YnNldEtleV0gPz8gW107XG4gICAgICAgICAgICBjb25zdCBpc0ludGVybmFsID0gaW50ZXJuYWxGaWVsZHMuc29tZSgoZikgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gZiA9PT0gZmllbGQgfHwgZi5zdGFydHNXaXRoKGAke2ZpZWxkfS5gKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIFtzdWJzZXRLZXksIGlzSW50ZXJuYWxdO1xuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIHN1YnNldFJvd3NUb1N1YnNldEZpZWxkcyhcbiAgICBzdWJzZXRSb3dzOiBFbnRpdHlTdWJzZXRSb3dbXSxcbiAgICBzdWJzZXRLZXk6IHN0cmluZyxcbiAgICBpbnRlcm5hbDogYm9vbGVhbiA9IGZhbHNlLFxuICApOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgaGFzS2V5ID0gaW50ZXJuYWwgPyBcImlzSW50ZXJuYWxcIiA6IFwiaGFzXCI7XG4gICAgcmV0dXJuIHN1YnNldFJvd3NcbiAgICAgIC5tYXAoKHN1YnNldFJvdykgPT4ge1xuICAgICAgICBpZiAoc3Vic2V0Um93LmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5zdWJzZXRSb3dzVG9TdWJzZXRGaWVsZHMoc3Vic2V0Um93LmNoaWxkcmVuLCBzdWJzZXRLZXksIGludGVybmFsKTtcbiAgICAgICAgfSBlbHNlIGlmIChzdWJzZXRSb3dbaGFzS2V5XVtzdWJzZXRLZXldKSB7XG4gICAgICAgICAgcmV0dXJuIHN1YnNldFJvdy5wcmVmaXhlcy5jb25jYXQoc3Vic2V0Um93LmZpZWxkKS5qb2luKFwiLlwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIC5maWx0ZXIobm9uTnVsbGFibGUpXG4gICAgICAuZmxhdCgpO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlUHJvcChwcm9wOiBFbnRpdHlQcm9wLCBhdD86IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghYXQpIHtcbiAgICAgIHRoaXMucHJvcHMucHVzaChwcm9wKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wcm9wcy5zcGxpY2UoYXQsIDAsIHByb3ApO1xuICAgIH1cbiAgICBhd2FpdCB0aGlzLnNhdmUoKTtcbiAgfVxuXG4gIGFuYWx5emVTdWJzZXRGaWVsZChzdWJzZXRGaWVsZDogc3RyaW5nKToge1xuICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgcHJvcE5hbWU6IHN0cmluZztcbiAgfVtdIHtcbiAgICBjb25zdCBhcnIgPSBzdWJzZXRGaWVsZC5zcGxpdChcIi5cIik7XG5cbiAgICBsZXQgZW50aXR5SWQgPSB0aGlzLmlkO1xuICAgIGNvbnN0IHJlc3VsdDoge1xuICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgIHByb3BOYW1lOiBzdHJpbmc7XG4gICAgfVtdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHByb3BOYW1lID0gYXJyW2ldO1xuICAgICAgcmVzdWx0LnB1c2goe1xuICAgICAgICBlbnRpdHlJZCxcbiAgICAgICAgcHJvcE5hbWUsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcHJvcCA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKS5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IHByb3BOYW1lKTtcbiAgICAgIGlmICghcHJvcCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZW50aXR5SWR97J2YIOyemOuqu+uQnCDshJzruIzshYvtgqQgJHtzdWJzZXRGaWVsZH1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChpc1JlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICBlbnRpdHlJZCA9IHByb3Aud2l0aDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGFzeW5jIG1vZGlmeVByb3AobmV3UHJvcDogRW50aXR5UHJvcCwgYXQ6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIOydtOyghCDtlITroa0g7J2066aEIOyggOyepVxuICAgIGNvbnN0IG9sZE5hbWUgPSB0aGlzLnByb3BzW2F0XS5uYW1lO1xuXG4gICAgLy8g7KCA7J6l7ZWgIOyXlO2LsO2LsFxuICAgIGNvbnN0IGVudGl0aWVzOiBFbnRpdHlbXSA9IFt0aGlzXTtcblxuICAgIC8vIOydtOumhOydtCDrsJTrgJAg6rK97JqwXG4gICAgaWYgKG9sZE5hbWUgIT09IG5ld1Byb3AubmFtZSkge1xuICAgICAgLy8g7KCE7LK0IOyXlO2LsO2LsOyXkOyEnCDtmITsnqwg7IiY7KCV65CcIO2UhOuhreydhCDssLjsobDtlZjqs6Ag7J6I64qUIOuqqOuToCDshJzruIzshYvtlYTrk5wg7LC+7JWE7IScIOyImOyglVxuICAgICAgY29uc3QgYWxsRW50aXR5SWRzID0gRW50aXR5TWFuYWdlci5nZXRBbGxJZHMoKTtcbiAgICAgIGZvciAoY29uc3QgcmVsRW50aXR5SWQgb2YgYWxsRW50aXR5SWRzKSB7XG4gICAgICAgIGNvbnN0IHJlbEVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KHJlbEVudGl0eUlkKTtcbiAgICAgICAgY29uc3QgcmVsRW50aXR5U3Vic2V0S2V5cyA9IE9iamVjdC5rZXlzKHJlbEVudGl0eS5zdWJzZXRzKTtcbiAgICAgICAgZm9yIChjb25zdCBzdWJzZXRLZXkgb2YgcmVsRW50aXR5U3Vic2V0S2V5cykge1xuICAgICAgICAgIGNvbnN0IHN1YnNldCA9IHJlbEVudGl0eS5zdWJzZXRzW3N1YnNldEtleV07XG5cbiAgICAgICAgICAvLyDshJzruIzshYsg7ZWE65Oc66W8IOyInO2ajO2VmOupsCwg7JeU7Yuw7YuwLe2UhOuhrSDri6jsnITroZwg67aE7ISd7ZWcIO2bhCDtmITsnqwg7JeU7Yuw7YuwLe2UhOuhreqzvCDsnbzsuZjtlZjripQg6rK97JqwIOyImOyglSDsspjrpqxcbiAgICAgICAgICBjb25zdCBtb2RpZmllZFN1YnNldEZpZWxkcyA9IHN1YnNldC5tYXAoKHN1YnNldEZpZWxkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbmFseXplZCA9IHJlbEVudGl0eS5hbmFseXplU3Vic2V0RmllbGQoc3Vic2V0RmllbGQpO1xuICAgICAgICAgICAgY29uc3QgbW9kaWZpZWQgPSBhbmFseXplZC5tYXAoKGEpID0+XG4gICAgICAgICAgICAgIGEucHJvcE5hbWUgPT09IG9sZE5hbWUgJiYgYS5lbnRpdHlJZCA9PT0gdGhpcy5pZFxuICAgICAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgICAgICAuLi5hLFxuICAgICAgICAgICAgICAgICAgICBwcm9wTmFtZTogbmV3UHJvcC5uYW1lLFxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDogYSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICAvLyDrtoTshJ3tlZwg7ZWE65Oc66W8IOuLpOyLnCDshJzruIzshYsg7ZWE65Oc66GcIOuzteq1rFxuICAgICAgICAgICAgcmV0dXJuIG1vZGlmaWVkLm1hcCgoYSkgPT4gYS5wcm9wTmFtZSkuam9pbihcIi5cIik7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAoc3Vic2V0LmpvaW4oXCIsXCIpICE9PSBtb2RpZmllZFN1YnNldEZpZWxkcy5qb2luKFwiLFwiKSkge1xuICAgICAgICAgICAgcmVsRW50aXR5LnN1YnNldHNbc3Vic2V0S2V5XSA9IG1vZGlmaWVkU3Vic2V0RmllbGRzO1xuICAgICAgICAgICAgZW50aXRpZXMucHVzaChyZWxFbnRpdHkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIO2UhOuhrSDsiJjsoJVcbiAgICB0aGlzLnByb3BzW2F0XSA9IG5ld1Byb3A7XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbChlbnRpdGllcy5tYXAoYXN5bmMgKGVudGl0eSkgPT4gZW50aXR5LnNhdmUoKSkpO1xuICB9XG5cbiAgYXN5bmMgZGVsUHJvcChhdDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8g7J207KCEIO2UhOuhrSDsnbTrpoQg7KCA7J6lXG4gICAgY29uc3Qgb2xkTmFtZSA9IHRoaXMucHJvcHNbYXRdLm5hbWU7XG5cbiAgICAvLyDsoIDsnqXtlaAg7JeU7Yuw7YuwXG4gICAgY29uc3QgZW50aXRpZXM6IEVudGl0eVtdID0gW3RoaXNdO1xuXG4gICAgLy8g7KCE7LK0IOyXlO2LsO2LsOyXkOyEnCDtmITsnqwg7IKt7KCc65CcIO2UhOuhreydhCDssLjsobDtlZjqs6Ag7J6I64qUIOuqqOuToCDshJzruIzshYvtlYTrk5wg7LC+7JWE7IScIOygnOyZuFxuICAgIGNvbnN0IGFsbEVudGl0eUlkcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCk7XG4gICAgZm9yIChjb25zdCByZWxFbnRpdHlJZCBvZiBhbGxFbnRpdHlJZHMpIHtcbiAgICAgIGNvbnN0IHJlbEVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KHJlbEVudGl0eUlkKTtcbiAgICAgIGNvbnN0IHJlbEVudGl0eVN1YnNldEtleXMgPSBPYmplY3Qua2V5cyhyZWxFbnRpdHkuc3Vic2V0cyk7XG4gICAgICBmb3IgKGNvbnN0IHN1YnNldEtleSBvZiByZWxFbnRpdHlTdWJzZXRLZXlzKSB7XG4gICAgICAgIGNvbnN0IHN1YnNldCA9IHJlbEVudGl0eS5zdWJzZXRzW3N1YnNldEtleV07XG4gICAgICAgIC8vIOyEnOu4jOyFiyDtlYTrk5zrpbwg7Iic7ZqM7ZWY66mwLCDsl5Tti7Dti7At7ZSE66GtIOuLqOychOuhnCDrtoTshJ3tlZwg7ZuEIO2YhOyerCDsl5Tti7Dti7At7ZSE66Gt6rO8IOydvOy5mO2VmOuKlCDqsr3smrAg7J207ZuE7J2YIO2VhOuTnOulvCDsoJzsmbhcbiAgICAgICAgY29uc3QgbW9kaWZpZWRTdWJzZXRGaWVsZHMgPSBzdWJzZXRcbiAgICAgICAgICAubWFwKChzdWJzZXRGaWVsZCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYW5hbHl6ZWQgPSByZWxFbnRpdHkuYW5hbHl6ZVN1YnNldEZpZWxkKHN1YnNldEZpZWxkKTtcbiAgICAgICAgICAgIGlmIChhbmFseXplZC5maW5kKChhKSA9PiBhLnByb3BOYW1lID09PSBvbGROYW1lICYmIGEuZW50aXR5SWQgPT09IHRoaXMuaWQpKSB7XG4gICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHN1YnNldEZpZWxkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG4gICAgICAgICAgLmZpbHRlcihub25OdWxsYWJsZSk7XG5cbiAgICAgICAgaWYgKHN1YnNldC5qb2luKFwiLFwiKSAhPT0gbW9kaWZpZWRTdWJzZXRGaWVsZHMuam9pbihcIixcIikpIHtcbiAgICAgICAgICByZWxFbnRpdHkuc3Vic2V0c1tzdWJzZXRLZXldID0gbW9kaWZpZWRTdWJzZXRGaWVsZHM7XG4gICAgICAgICAgZW50aXRpZXMucHVzaChyZWxFbnRpdHkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8g7ZiE7J6sIOyXlO2LsO2LsOydmCDsnbjrjbHsiqTsl5DshJwg7KCc7Jm4XG4gICAgZm9yIChjb25zdCBpbmRleCBvZiBFbnRpdHlNYW5hZ2VyLmdldCh0aGlzLmlkKS5pbmRleGVzKSB7XG4gICAgICBpbmRleC5jb2x1bW5zID0gaW5kZXguY29sdW1ucy5maWx0ZXIoKGNvbCkgPT4gY29sLm5hbWUgIT09IG9sZE5hbWUpO1xuICAgIH1cblxuICAgIC8vIO2UhOuhrSDsgq3soJxcbiAgICB0aGlzLnByb3BzLnNwbGljZShhdCwgMSk7XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbChlbnRpdGllcy5tYXAoYXN5bmMgKGVudGl0eSkgPT4gZW50aXR5LnNhdmUoKSkpO1xuICB9XG5cbiAgZ2V0RW50aXR5SWRGcm9tU3Vic2V0RmllbGQoc3Vic2V0RmllbGQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCFzdWJzZXRGaWVsZC5pbmNsdWRlcyhcIi5cIikpIHtcbiAgICAgIHJldHVybiB0aGlzLmlkO1xuICAgIH1cblxuICAgIC8vIOyEnOu4jOyFiyDtlYTrk5zsnZgg66eI7KeA66eJ7J2AIO2UhOuhreydtOuvgOuhnCDsoJzsmbhcbiAgICBjb25zdCBhcnIgPSBzdWJzZXRGaWVsZC5zcGxpdChcIi5cIikuc2xpY2UoMCwgLTEpO1xuXG4gICAgLy8g7ISc67iM7IWLIO2VhOuTnOulvCDrgrTroKTqsIDrqbTshJwg66eI7KeA66eJ7Jy866GcIHJlbGF0aW9u65CcIOyXlO2LsO2LsOulvCDssL7snYxcbiAgICBjb25zdCBsYXN0RW50aXR5SWQgPSBhcnIucmVkdWNlKChlbnRpdHlJZCwgZmllbGQpID0+IHtcbiAgICAgIGNvbnN0IHJlbFByb3AgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCkucHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBmaWVsZCk7XG4gICAgICBpZiAoIXJlbFByb3AgfHwgcmVsUHJvcC50eXBlICE9PSBcInJlbGF0aW9uXCIpIHtcbiAgICAgICAgY29uc29sZS5kZWJ1Zyh7IGFyciwgdGhpc0lkOiB0aGlzLmlkLCBlbnRpdHlJZCwgZmllbGQgfSk7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihg7J6Y66q765CcIOyEnOu4jOyFi+2CpCAke3N1YnNldEZpZWxkfWApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlbFByb3Aud2l0aDtcbiAgICB9LCB0aGlzLmlkKTtcbiAgICByZXR1cm4gbGFzdEVudGl0eUlkO1xuICB9XG5cbiAgYXN5bmMgbW92ZVByb3AoYXQ6IG51bWJlciwgdG86IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHByb3AgPSB0aGlzLnByb3BzW2F0XTtcbiAgICBjb25zdCBuZXdQcm9wcyA9IFsuLi50aGlzLnByb3BzXTtcbiAgICBuZXdQcm9wcy5zcGxpY2UodG8sIDAsIHByb3ApO1xuICAgIG5ld1Byb3BzLnNwbGljZShhdCA8IHRvID8gYXQgOiBhdCArIDEsIDEpO1xuICAgIHRoaXMucHJvcHMgPSBuZXdQcm9wcztcblxuICAgIGF3YWl0IHRoaXMuc2F2ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VhOuTnOuqheydhCBcIu2FjOydtOu4lOuqhS7tlYTrk5zrqoVcIiDtmJXsi53snLzroZwg67OA7ZmYXG4gICAqL1xuICBnZXRGdWxsRmllbGROYW1lKGZpZWxkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmIChmaWVsZC5pbmNsdWRlcyhcIi5cIikpIHtcbiAgICAgIHJldHVybiBmaWVsZDtcbiAgICB9XG4gICAgcmV0dXJuIGAke3RoaXMudGFibGV9LiR7ZmllbGR9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiDsl5Tti7Dti7DsnZggUEsg7YOA7J6F7J2EIOuwmO2ZmO2VqeuLiOuLpC5cbiAgICogaWQg7ZWE65Oc7J2YIO2DgOyeheydhCDquLDspIDsnLzroZwgXCJpbnRlZ2VyXCIgfCBcInN0cmluZ1wiIHwgXCJ1dWlkXCLrpbwg67CY7ZmY7ZWp64uI64ukLlxuICAgKi9cbiAgZ2V0UGtUeXBlKCk6IFwiaW50ZWdlclwiIHwgXCJzdHJpbmdcIiB8IFwidXVpZFwiIHtcbiAgICBjb25zdCBpZFByb3AgPSB0aGlzLnByb3BzRGljdC5pZDtcbiAgICBpZiAoIWlkUHJvcCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFbnRpdHkgJHt0aGlzLmlkfeyXkCBpZCDtlYTrk5zqsIAg7JeG7Iq164uI64ukYCk7XG4gICAgfVxuICAgIGlmIChpZFByb3AudHlwZSA9PT0gXCJzdHJpbmdcIiB8fCBpZFByb3AudHlwZSA9PT0gXCJ1dWlkXCIpIHtcbiAgICAgIHJldHVybiBpZFByb3AudHlwZTtcbiAgICB9XG4gICAgcmV0dXJuIFwiaW50ZWdlclwiO1xuICB9XG5cbiAgLyoqXG4gICAqIOyXlO2LsO2LsOydmCBQSyBwcm9w7J2EIOuwmO2ZmO2VqeuLiOuLpC5cbiAgICogbGVuZ3RoIOuTsSDshLjrtoAg7KCV67O07JeQIOygkeq3vO2VoCDrlYwg7IKs7Jqp7ZWp64uI64ukLlxuICAgKi9cbiAgZ2V0UGtQcm9wKCk6IEVudGl0eVByb3Age1xuICAgIGNvbnN0IGlkUHJvcCA9IHRoaXMucHJvcHNEaWN0LmlkO1xuICAgIGlmICghaWRQcm9wKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEVudGl0eSAke3RoaXMuaWR97JeQIGlkIO2VhOuTnOqwgCDsl4bsirXri4jri6RgKTtcbiAgICB9XG4gICAgcmV0dXJuIGlkUHJvcDtcbiAgfVxuXG4gIC8qKlxuICAgKiDsl5Tti7Dti7DsnZggUEsg67Cw7Je0IO2DgOyeheydhCDrsJjtmZjtlanri4jri6QuXG4gICAqIExvYWRlclF1ZXJ57J2YIGZyb21JZHMg7YOA7J6F7Jy866GcIOyCrOyaqeuQqeuLiOuLpC5cbiAgICovXG4gIGdldFBrQXJyYXlUeXBlKCk6IHN0cmluZyB7XG4gICAgY29uc3QgcGtUeXBlID0gdGhpcy5nZXRQa1R5cGUoKTtcbiAgICByZXR1cm4gcGtUeXBlID09PSBcImludGVnZXJcIiA/IFwibnVtYmVyW11cIiA6IFwic3RyaW5nW11cIjtcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O2NBUXVDO2FBY2Y7aUJBWTJCO2lCQUNIO2dCQUNMO2tCQUNPO2FBQ1U7c0JBQ1g7Q0FFcEMsU0FBYixNQUFvQjtFQUNsQjtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFLQTtFQUNBO0VBR0E7RUFHQTtFQUNBO0VBR0E7RUFHQSxRQUVJLEVBQUU7RUFDTixRQUVJLEVBQUU7RUFDTixhQUlJ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
800
+
801
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LmpzIiwibmFtZXMiOlsieiJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lbnRpdHkvZW50aXR5LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSBcImFzc2VydFwiO1xuaW1wb3J0IHsgd3JpdGVGaWxlIH0gZnJvbSBcImZzL3Byb21pc2VzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5pbXBvcnQgaW5mbGVjdGlvbiBmcm9tIFwiaW5mbGVjdGlvblwiO1xuaW1wb3J0IHsgZ3JvdXAsIHVuaXF1ZSB9IGZyb20gXCJyYWRhc2hpXCI7XG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiO1xuXG5pbXBvcnQgeyBTb25hbXUgfSBmcm9tIFwiLi4vYXBpL3NvbmFtdVwiO1xuaW1wb3J0IHtcbiAgZ2V0RW51bURlZlZhbHVlcyxcbiAgZ2V0U3Vic2V0RmllbGRzLFxuICBpc0JlbG9uZ3NUb09uZVJlbGF0aW9uUHJvcCxcbiAgaXNFbnVtUHJvcCxcbiAgaXNIYXNNYW55UmVsYXRpb25Qcm9wLFxuICBpc0ludGVybmFsU3Vic2V0RmllbGQsXG4gIGlzTWFueVRvTWFueVJlbGF0aW9uUHJvcCxcbiAgaXNPbmVUb09uZVJlbGF0aW9uUHJvcCxcbiAgaXNSZWxhdGlvblByb3AsXG4gIGlzVmlydHVhbENvZGVQcm9wLFxuICBpc1ZpcnR1YWxQcm9wLFxuICBub3JtYWxpemVTdWJzZXRGaWVsZCxcbn0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQge1xuICB0eXBlIENvbmUsXG4gIHR5cGUgRW50aXR5SW5kZXgsXG4gIHR5cGUgRW50aXR5SnNvbixcbiAgdHlwZSBFbnRpdHlQcm9wLFxuICB0eXBlIEVudGl0eVByb3BOb2RlLFxuICB0eXBlIEVudGl0eVN1YnNldFJvdyxcbiAgdHlwZSBSZWxhdGlvblByb3AsXG4gIHR5cGUgU3Vic2V0RmllbGQsXG4gIHR5cGUgU3Vic2V0UXVlcnksXG59IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgaW1wb3J0TWVtYmVycyB9IGZyb20gXCIuLi91dGlscy9lc20tdXRpbHNcIjtcbmltcG9ydCB7IGZvcm1hdENvZGUgfSBmcm9tIFwiLi4vdXRpbHMvZm9ybWF0dGVyXCI7XG5pbXBvcnQgeyBleGlzdHMgfSBmcm9tIFwiLi4vdXRpbHMvZnMtdXRpbHNcIjtcbmltcG9ydCB7IHJ1bnRpbWVQYXRoIH0gZnJvbSBcIi4uL3V0aWxzL3BhdGgtdXRpbHNcIjtcbmltcG9ydCB7IGFzc2VydERlZmluZWQsIG5vbk51bGxhYmxlIH0gZnJvbSBcIi4uL3V0aWxzL3V0aWxzXCI7XG5pbXBvcnQgeyBFbnRpdHlNYW5hZ2VyIH0gZnJvbSBcIi4vZW50aXR5LW1hbmFnZXJcIjtcblxuZXhwb3J0IGNsYXNzIEVudGl0eSB7XG4gIGlkOiBzdHJpbmc7XG4gIHBhcmVudElkPzogc3RyaW5nO1xuICB0YWJsZTogc3RyaW5nO1xuICB0aXRsZTogc3RyaW5nO1xuICBjb25lPzogQ29uZTtcbiAgbmFtZXM6IHtcbiAgICBwYXJlbnRGczogc3RyaW5nO1xuICAgIGZzOiBzdHJpbmc7XG4gICAgbW9kdWxlOiBzdHJpbmc7XG4gIH07XG4gIHByb3BzOiBFbnRpdHlQcm9wW107XG4gIHByb3BzRGljdDoge1xuICAgIFtrZXk6IHN0cmluZ106IEVudGl0eVByb3A7XG4gIH07XG4gIHJlbGF0aW9uczoge1xuICAgIFtrZXk6IHN0cmluZ106IFJlbGF0aW9uUHJvcDtcbiAgfTtcbiAgaW5kZXhlczogRW50aXR5SW5kZXhbXTtcbiAgc3Vic2V0czoge1xuICAgIFtrZXk6IHN0cmluZ106IHN0cmluZ1tdO1xuICB9O1xuICBzdWJzZXRzSW50ZXJuYWw6IHtcbiAgICBba2V5OiBzdHJpbmddOiBzdHJpbmdbXTtcbiAgfTtcbiAgdHlwZXM6IHtcbiAgICBbbmFtZTogc3RyaW5nXTogei5ab2RUeXBlQW55O1xuICB9ID0ge307XG4gIGVudW1zOiB7XG4gICAgW2VudW1JZDogc3RyaW5nXTogei5ab2RFbnVtPFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHN0cmluZz4+PjtcbiAgfSA9IHt9O1xuICBlbnVtTGFiZWxzOiB7XG4gICAgW2VudW1JZDogc3RyaW5nXToge1xuICAgICAgW2tleTogc3RyaW5nXTogc3RyaW5nO1xuICAgIH07XG4gIH0gPSB7fTtcbiAgZW51bUNvbmVzOiB7XG4gICAgW2VudW1JZDogc3RyaW5nXTogQ29uZTtcbiAgfSA9IHt9O1xuICBzdWJzZXRDb25lczoge1xuICAgIFtzdWJzZXRLZXk6IHN0cmluZ106IENvbmU7XG4gIH0gPSB7fTtcblxuICBjb25zdHJ1Y3Rvcih7IGlkLCBwYXJlbnRJZCwgdGFibGUsIHRpdGxlLCBjb25lLCBwcm9wcywgaW5kZXhlcywgc3Vic2V0cywgZW51bXMgfTogRW50aXR5SnNvbikge1xuICAgIC8vIGlkXG4gICAgdGhpcy5pZCA9IGlkO1xuICAgIHRoaXMucGFyZW50SWQgPSBwYXJlbnRJZDtcbiAgICB0aGlzLnRpdGxlID0gdGl0bGUgPz8gdGhpcy5pZDtcbiAgICB0aGlzLnRhYmxlID0gdGFibGUgPz8gaW5mbGVjdGlvbi51bmRlcnNjb3JlKGluZmxlY3Rpb24ucGx1cmFsaXplKGlkKSk7XG4gICAgdGhpcy5jb25lID0gY29uZTtcblxuICAgIC8vIHByb3BzXG4gICAgaWYgKHByb3BzKSB7XG4gICAgICB0aGlzLnByb3BzID0gcHJvcHMubWFwKChwcm9wKSA9PiB7XG4gICAgICAgIGlmIChpc0VudW1Qcm9wKHByb3ApKSB7XG4gICAgICAgICAgaWYgKHByb3AuaWQuaW5jbHVkZXMoXCIkTW9kZWxcIikpIHtcbiAgICAgICAgICAgIHByb3AuaWQgPSBwcm9wLmlkLnJlcGxhY2UoXCIkTW9kZWxcIiwgaWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvcDtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5wcm9wc0RpY3QgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgIHByb3BzLm1hcCgocHJvcCkgPT4ge1xuICAgICAgICAgIHJldHVybiBbcHJvcC5uYW1lLCBwcm9wXTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICAvLyByZWxhdGlvbnNcbiAgICAgIHRoaXMucmVsYXRpb25zID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICBwcm9wcy5maWx0ZXIoKHByb3ApID0+IGlzUmVsYXRpb25Qcm9wKHByb3ApKS5tYXAoKHByb3ApID0+IFtwcm9wLm5hbWUsIHByb3BdKSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHJvcHMgPSBbXTtcbiAgICAgIHRoaXMucHJvcHNEaWN0ID0ge307XG4gICAgICB0aGlzLnJlbGF0aW9ucyA9IHt9O1xuICAgIH1cblxuICAgIC8vIGluZGV4ZXNcbiAgICB0aGlzLmluZGV4ZXMgPSBpbmRleGVzID8/IFtdO1xuXG4gICAgLy8gc3Vic2V0czogU3Vic2V0RGVm7JeQ7IScIFN1YnNldEZpZWxkW13rpbwg7LaU7Lac7ZWY7JesIHN1YnNldHMo7J2867CYKeyZgCBzdWJzZXRzSW50ZXJuYWwoaW50ZXJuYWwp66GcIOu2hOumrFxuICAgIHRoaXMuc3Vic2V0cyA9IHt9O1xuICAgIHRoaXMuc3Vic2V0c0ludGVybmFsID0ge307XG4gICAgZm9yIChjb25zdCBba2V5LCBzdWJzZXREZWZdIG9mIE9iamVjdC5lbnRyaWVzKHN1YnNldHMgPz8ge30pKSB7XG4gICAgICBjb25zdCBmaWVsZHMgPSBnZXRTdWJzZXRGaWVsZHMoc3Vic2V0RGVmKTtcbiAgICAgIHRoaXMuc3Vic2V0c1trZXldID0gZmllbGRzLmZpbHRlcigoZikgPT4gIWlzSW50ZXJuYWxTdWJzZXRGaWVsZChmKSkubWFwKG5vcm1hbGl6ZVN1YnNldEZpZWxkKTtcbiAgICAgIHRoaXMuc3Vic2V0c0ludGVybmFsW2tleV0gPSBmaWVsZHMuZmlsdGVyKGlzSW50ZXJuYWxTdWJzZXRGaWVsZCkubWFwKG5vcm1hbGl6ZVN1YnNldEZpZWxkKTtcblxuICAgICAgLy8gY29uZSDstpTstpxcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShzdWJzZXREZWYpICYmIFwiY29uZVwiIGluIHN1YnNldERlZiAmJiBzdWJzZXREZWYuY29uZSkge1xuICAgICAgICB0aGlzLnN1YnNldENvbmVzW2tleV0gPSBzdWJzZXREZWYuY29uZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBlbnVtczogRW51bURlZuyXkOyEnCB2YWx1ZXPsmYAgY29uZeulvCDstpTstpztlZjsl6wg7LKY66asXG4gICAgdGhpcy5lbnVtTGFiZWxzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmVudHJpZXMoZW51bXMgPz8ge30pLm1hcCgoW2tleSwgZW51bURlZl0pID0+IHtcbiAgICAgICAgLy8gY29uZSDstpTstpxcbiAgICAgICAgaWYgKFwidmFsdWVzXCIgaW4gZW51bURlZiAmJiBcImNvbmVcIiBpbiBlbnVtRGVmICYmIGVudW1EZWYuY29uZSkge1xuICAgICAgICAgIHRoaXMuZW51bUNvbmVzW2tleV0gPSBlbnVtRGVmLmNvbmUgYXMgQ29uZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW2tleSwgZ2V0RW51bURlZlZhbHVlcyhlbnVtRGVmKV07XG4gICAgICB9KSxcbiAgICApO1xuICAgIHRoaXMuZW51bXMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QuZW50cmllcyh0aGlzLmVudW1MYWJlbHMpLm1hcCgoW2tleSwgZW51bUxhYmVsXSkgPT4ge1xuICAgICAgICByZXR1cm4gW2tleSwgei5lbnVtKE9iamVjdC5rZXlzKGVudW1MYWJlbCkgYXMgdW5rbm93biBhcyByZWFkb25seSBbc3RyaW5nLCAuLi5zdHJpbmdbXV0pXTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICAvLyBuYW1lc1xuICAgIHRoaXMubmFtZXMgPSB7XG4gICAgICBwYXJlbnRGczogaW5mbGVjdGlvbi5kYXNoZXJpemUoaW5mbGVjdGlvbi51bmRlcnNjb3JlKHBhcmVudElkID8/IGlkKSkudG9Mb3dlckNhc2UoKSxcbiAgICAgIGZzOiBpbmZsZWN0aW9uLmRhc2hlcml6ZShpbmZsZWN0aW9uLnVuZGVyc2NvcmUoaWQpKS50b0xvd2VyQ2FzZSgpLFxuICAgICAgbW9kdWxlOiBpZCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOy/vOumrOyaqSDshJzruIzshYsg7ZWE65Oc66W8IOuwmO2ZmO2VqeuLiOuLpCAoc3Vic2V0cyArIHN1YnNldHNJbnRlcm5hbCDtlansuagpXG4gICAqL1xuICBnZXRTdWJzZXRGaWVsZHNGb3JRdWVyeShzdWJzZXRLZXk6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gWy4uLih0aGlzLnN1YnNldHNbc3Vic2V0S2V5XSA/PyBbXSksIC4uLih0aGlzLnN1YnNldHNJbnRlcm5hbFtzdWJzZXRLZXldID8/IFtdKV07XG4gIH1cblxuICAvKipcbiAgICog7KO87Ja07KeEIOydtOumhChzdWJzZXRLZXkp7J2YIHN1YnNldOydhCDsi6TsoJzroZwg6rCA7KC47Jik64qUIFB1cmkg7L2U65OcIOq1rO2YhOyytCBzdHJpbmfsnYQg67CY7ZmY7ZWp64uI64ukLlxuICAgKi9cbiAgZ2V0UHVyaVN1YnNldFF1ZXJ5KHN1YnNldEtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBzdWJzZXQgPSB0aGlzLmdldFN1YnNldEZpZWxkc0ZvclF1ZXJ5KHN1YnNldEtleSk7XG4gICAgY29uc3Qgc3Vic2V0UXVlcnkgPSB0aGlzLnJlc29sdmVTdWJzZXRRdWVyeShcIlwiLCBzdWJzZXQpO1xuXG4gICAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW107XG5cbiAgICAvLyBmcm9tXG4gICAgbGluZXMucHVzaChgcmV0dXJuIHFiV3JhcHBlcmApO1xuICAgIGxpbmVzLnB1c2goYC5mcm9tKFwiJHt0aGlzLnRhYmxlfVwiKWApO1xuXG4gICAgLy8gam9pblxuICAgIGZvciAoY29uc3Qgam9pbiBvZiBzdWJzZXRRdWVyeS5qb2lucykge1xuICAgICAgLy8gam9pbiDrqZTshJzrk5wg6rKw7KCVOiBpbm5lciDihpIgam9pbiwgb3V0ZXIg4oaSIGxlZnRKb2luXG4gICAgICAvLyBGSyBudWxsYWJsZSDsl6zrtoDripQgbGVmdEpvaW4g7YOA7J6FIOyLnOq3uOuLiOyymOyXkOyEnCDsnpDrj5nsnLzroZwg7YyQ64uo65CoXG4gICAgICBjb25zdCBqb2luTWV0aG9kID0gam9pbi5qb2luID09PSBcImlubmVyXCIgPyBcImpvaW5cIiA6IFwibGVmdEpvaW5cIjtcblxuICAgICAgaWYgKFwiY3VzdG9tXCIgaW4gam9pbikge1xuICAgICAgICAvLyBjdXN0b20gam9pbiBjbGF1c2XripQgcmF3IOyCrOyaqVxuICAgICAgICBsaW5lcy5wdXNoKFxuICAgICAgICAgIGAuJHtqb2luTWV0aG9kfSh7ICR7am9pbi5hc306IFwiJHtqb2luLnRhYmxlfVwiIH0sIHFiV3JhcHBlci5rbmV4LnJhdyhcXGAke2pvaW4uY3VzdG9tfVxcYCkpYCxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpbmVzLnB1c2goYC4ke2pvaW5NZXRob2R9KHsgJHtqb2luLmFzfTogXCIke2pvaW4udGFibGV9XCIgfSwgXCIke2pvaW4uZnJvbX1cIiwgXCIke2pvaW4udG99XCIpYCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2VsZWN0IC0g7J6F7LK07KCBIOq1rOyhsOuhnCDsg53shLFcbiAgICBjb25zdCBzZWxlY3RPYmogPSB0aGlzLmJ1aWxkTmVzdGVkU2VsZWN0T2JqZWN0KHN1YnNldFF1ZXJ5LnNlbGVjdCk7XG4gICAgbGluZXMucHVzaChgLnNlbGVjdCgke3RoaXMuc3RyaW5naWZ5TmVzdGVkU2VsZWN0T2JqZWN0KHNlbGVjdE9iail9KTtgKTtcblxuICAgIHJldHVybiBsaW5lcy5qb2luKFwiXFxuXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqICouZW50aXR5Lmpzb27snZggc3Vic2V07JeQIOuTpOyWtOyeiOuKlCDtlYTrk5wg67Cw7Je07J2EIOuwm+yVhOyEnCxcbiAgICogUHVyaeydmCBTZWxlY3RPYmplY3Qg7YOA7J6F7Jy866GcIOuzgO2ZmO2VqeuLiOuLpC5cbiAgICpcbiAgICog7JiIOiBbXCJ1c2Vycy5pZFwiLCBcInBhcmVudC5pZFwiLCBcInBhcmVudC5uYW1lXCJdXG4gICAqICAg4oaSIHsgaWQ6IFwidXNlcnMuaWRcIiwgcGFyZW50OiB7IGlkOiBcInBhcmVudC5pZFwiLCBuYW1lOiBcInBhcmVudC5uYW1lXCIgfSB9XG4gICAqXG4gICAqIOyWuOuNlOuwlOqwgCDslYTri4wg7KSR7LKpIOqwneyytOuhnCDrs4DtmZjtlajsl5Ag7Jyg7J2Y7ZWY7IS47JqULlxuICAgKiDsnbTroIfqsowg7KSR7LKpIOqwneyytOuhnCDrs4DtmZjtlZjsl6wgc2VsZWN07JeQIOuEmOqyqOyjvOuptCBQYXJzZVNlbGVjdE9iamVjdCDtg4DsnoXsnbQgam9pbuuQnCDqsJ3ssrTsnZgg7YOA7J6F7J2EIOyemCDsnqHslYTspIQg7IiYIOyeiOyKteuLiOuLpC5cbiAgICog7KaJLCBlbmhhbmNlcuyXkOyEnCByb3frpbwg67Cb7JWY7J2EIOuVjCBoeWRyYXRl65CcIOqwneyytCDsnpDssrTsnZggbnVsbGl0eeyZgCDqt7gg7JWI7Kq9IO2VhOuTnOydmCBudWxsaXR56rCAIGZrIG51bGxhYmxlIOyXrOu2gOyXkCDrlLDrnbwg7J6YIOy2lOuhoOuQqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgYnVpbGROZXN0ZWRTZWxlY3RPYmplY3QoXG4gICAgc2VsZWN0SXRlbXM6IHN0cmluZ1tdLFxuICAgIC8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55IC0tIOuwmO2ZmCDsmKTruIzsoJ3tirjsnZgg6rCS7J2AIHN0cmluZ+ydvCDsiJjrj4Qg7J6I6rOgIOuYkOuLpOuluCDsmKTruIzsoJ3tirjsnbwg7IiY64+EIOyeiOuKlOuNsCwg7J2066W8IOyerOq3gCDtg4DsnoXsnLzroZwg64KY7YOA64K8IOyImCDsl4bslrQgYW5566GcIOyymOumrO2VqeuLiOuLpC5cbiAgKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gICAgY29uc3QgcmVzdWx0OiBSZXR1cm5UeXBlPHR5cGVvZiB0aGlzLmJ1aWxkTmVzdGVkU2VsZWN0T2JqZWN0PiA9IHt9O1xuXG4gICAgZm9yIChjb25zdCBzZWxlY3RJdGVtIG9mIHNlbGVjdEl0ZW1zKSB7XG4gICAgICAvLyBcInVzZXJzLmlkXCIg65iQ64qUIFwidXNlcnMuaWQgYXMgdXNlcl9faWRcIiDtmJXtg5wg7YyM7IuxXG4gICAgICBjb25zdCBtYXRjaCA9IHNlbGVjdEl0ZW0ubWF0Y2goL14oLis/KSg/OiBhcyAoLispKT8kLyk7XG4gICAgICBpZiAoIW1hdGNoKSBjb250aW51ZTtcblxuICAgICAgY29uc3QgWywgY29sdW1uLCBhbGlhc10gPSBtYXRjaDtcbiAgICAgIGNvbnN0IGNvbHVtblZhbHVlID0gYFwiJHtjb2x1bW4udHJpbSgpfVwiYDtcblxuICAgICAgaWYgKCFhbGlhcyB8fCAhYWxpYXMuaW5jbHVkZXMoXCJfX1wiKSkge1xuICAgICAgICAvLyBhbGlhc+qwgCDsl4bqsbDrgpggX1/rpbwg7Y+s7ZWo7ZWY7KeAIOyViuycvOuptCDstZzsg4HsnIQg7ZWE65OcXG4gICAgICAgIGNvbnN0IGtleSA9IGFsaWFzID8/IGFzc2VydERlZmluZWQoY29sdW1uLnNwbGl0KFwiLlwiKS5wb3AoKSk7XG4gICAgICAgIHJlc3VsdFtrZXldID0gY29sdW1uVmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBhbGlhc+qwgCBfX+ulvCDtj6ztlajtlZjrqbQg7J6F7LK0IOq1rOyhsOuhnCDqt7jro7ntmZRcbiAgICAgICAgY29uc3QgcGFydHMgPSBhbGlhcy5zcGxpdChcIl9fXCIpO1xuICAgICAgICBsZXQgY3VycmVudCA9IHJlc3VsdDtcblxuICAgICAgICAvLyDrp4jsp4Drp4kg7YyM7Yq4IOyghOq5jOyngCDspJHssqkg6rCd7LK0IOyDneyEsVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICAgIGNvbnN0IHBhcnQgPSBwYXJ0c1tpXTtcbiAgICAgICAgICBpZiAocGFydCBpbiBjdXJyZW50KSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGN1cnJlbnRbcGFydF0gPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgLy8g7J6F66Cl7J20IFtcInVzZXJcIiwgXCJ1c2VyX19pZFwiXSDqsJnsnYAg6rK97JqwIVxuICAgICAgICAgICAgICAvLyDslaDstIjsl5Ag66eQ64+EIOyViCDrkJjsp4Drp4wg7JWI7KCE7ZWY6rKMIOyYiOyZuOulvCDrjZjsp5Hri4jri6QuXG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgQ29uZmxpY3QgZGV0ZWN0ZWQgaW4gc2VsZWN0IGl0ZW1zOiBwYXJlbnQgcGF0aCBcIiR7cGFydHMuc2xpY2UoMCwgaSArIDEpLmpvaW4oXCJfX1wiKX1cIiBpcyBhbHJlYWR5IHNldCBhcyBhIGZpZWxkLCBjYW5ub3QgbmVzdCBcIiR7YWxpYXN9XCIgdW5kZXIgaXQuYCxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY3VycmVudFtwYXJ0XSA9IHt9O1xuICAgICAgICAgIH1cbiAgICAgICAgICBjdXJyZW50ID0gY3VycmVudFtwYXJ0XTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOuniOyngOuniSDtjIztirjsl5Ag6rCSIOyEpOyglVxuICAgICAgICBjb25zdCBsYXN0UGFydCA9IHBhcnRzW3BhcnRzLmxlbmd0aCAtIDFdO1xuICAgICAgICBjdXJyZW50W2xhc3RQYXJ0XSA9IGNvbHVtblZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogSlNPTi5zdHJpbmdpZnnsmYAg7Jyg7IKs7ZWcIOydvOydhCDtlanri4jri6QuXG4gICAqIOuLpOunjCDso7zslrTsp4Qg6rCd7LK066W8IEpTT07snbQg7JWE64uMIFR5cGVTY3JpcHQg6rCd7LK0IOumrO2EsOuftCDsiqTtirjrp4HsnLzroZwg66eM65Ok7Ja07KSN64uI64ukLlxuICAgKiBrZXnsl5Ag65Sw7Ji07ZGc6rCAIOyXhuyWtOyalC5cbiAgICog7Lac66ClIOyYiOyLnDpcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiB7XG4gICAqICAgaWQ6IFwidXNlcnMuaWRcIixcbiAgICogICBwYXJlbnQ6IHtcbiAgICogICAgIGlkOiBcInBhcmVudC5pZFwiLFxuICAgKiAgICAgbmFtZTogXCJwYXJlbnQubmFtZVwiLFxuICAgKiAgIH0sXG4gICAqIH1cbiAgICogYGBgXG4gICAqIEBwYXJhbSBvYmog67OA7ZmY7ZWgIOqwneyytFxuICAgKiBAcGFyYW0gaW5kZW50IOuTpOyXrOyTsOq4sCDroIjrsqhcbiAgICogQHBhcmFtIHdpdGhCcmFjZXMgdHJ1ZeuptCDspJHqtITtmLgg7Y+s7ZWoLCBmYWxzZeuptCDrgrTsmqnrp4wg67CY7ZmYXG4gICAqL1xuICBwcml2YXRlIHN0cmluZ2lmeU5lc3RlZFNlbGVjdE9iamVjdChcbiAgICAvLyBveGxpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAtLSDspJHssqkg7Jik67iM7KCd7Yq47J2YIOqwkuydgCBzdHJpbmfsnbwg7IiY64+EIOyeiOqzoCDrmJDri6Trpbgg7Jik67iM7KCd7Yq47J28IOyImOuPhCDsnojripTrjbAsIOydtOulvCDsnqzqt4Ag7YOA7J6F7Jy866GcIOuCmO2DgOuCvCDsiJgg7JeG7Ja0IGFueeuhnCDsspjrpqztlanri4jri6QuXG4gICAgb2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgIGluZGVudDogbnVtYmVyID0gMCxcbiAgICB3aXRoQnJhY2VzOiBib29sZWFuID0gdHJ1ZSxcbiAgKTogc3RyaW5nIHtcbiAgICBjb25zdCBzcGFjZXMgPSBcIiAgXCIucmVwZWF0KGluZGVudCk7XG4gICAgY29uc3QgaW5uZXJTcGFjZXMgPSBcIiAgXCIucmVwZWF0KGluZGVudCArIDEpO1xuXG4gICAgY29uc3QgZW50cmllcyA9IE9iamVjdC5lbnRyaWVzKG9iaik7XG4gICAgaWYgKGVudHJpZXMubGVuZ3RoID09PSAwKSByZXR1cm4gd2l0aEJyYWNlcyA/IFwie31cIiA6IFwiXCI7XG5cbiAgICBjb25zdCBsaW5lcyA9IGVudHJpZXMubWFwKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgLy8g7Lus65+8IOqyveuhnCAo7J2066+4IOuUsOyYtO2RnCDtj6ztlagpXG4gICAgICAgIHJldHVybiBgJHtpbm5lclNwYWNlc30ke2tleX06ICR7dmFsdWV9LGA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyDspJHssqkg6rCd7LK0ICjtla3sg4Eg7KSR6rSE7Zi4IO2PrO2VqClcbiAgICAgICAgcmV0dXJuIGAke2lubmVyU3BhY2VzfSR7a2V5fTogJHt0aGlzLnN0cmluZ2lmeU5lc3RlZFNlbGVjdE9iamVjdCh2YWx1ZSwgaW5kZW50ICsgMSwgdHJ1ZSl9LGA7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAod2l0aEJyYWNlcykge1xuICAgICAgcmV0dXJuIGB7XFxuJHtsaW5lcy5qb2luKFwiXFxuXCIpfVxcbiR7c3BhY2VzfX1gO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyDspJHqtITtmLgg7JeG7J20IOuCtOyaqeunjCDrsJjtmZggKOyVnuuSpCDqsJztlokg7KCc7Jm4KVxuICAgICAgcmV0dXJuIGxpbmVzLmpvaW4oXCJcXG5cIik7XG4gICAgfVxuICB9XG5cbiAgZ2V0UHVyaUxvYWRlclF1ZXJ5KHN1YnNldEtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBzdWJzZXQgPSB0aGlzLmdldFN1YnNldEZpZWxkc0ZvclF1ZXJ5KHN1YnNldEtleSk7XG4gICAgY29uc3QgeyBsb2FkZXJzIH0gPSB0aGlzLnJlc29sdmVTdWJzZXRRdWVyeShcIlwiLCBzdWJzZXQpO1xuXG4gICAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW2BbYF07XG5cbiAgICAvLyDsnqzqt4DsoIHsnLzroZwgbG9hZGVyIOyDneyEse2VmOuKlCDtl6ztjbwg7ZWo7IiYXG4gICAgY29uc3QgZ2VuZXJhdGVMb2FkZXJDb2RlID0gKGxvYWRlcnM6IFN1YnNldFF1ZXJ5W1wibG9hZGVyc1wiXSk6IHN0cmluZ1tdID0+IHtcbiAgICAgIGNvbnN0IGxvYWRlckxpbmVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IGxvYWRlciBvZiBsb2FkZXJzKSB7XG4gICAgICAgIGNvbnN0IHsgdG9UYWJsZSwgdG9Db2wsIHRocm91Z2gsIGZyb21UYWJsZSB9ID0gbG9hZGVyLm1hbnlKb2luO1xuXG4gICAgICAgIC8vIGZyb21UYWJsZeydmCBFbnRpdHnrpbwg6rCA7KC47JmA7IScIFBLIO2DgOyehSDtmZXsnbhcbiAgICAgICAgY29uc3QgZnJvbUVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0QnlUYWJsZShmcm9tVGFibGUpO1xuICAgICAgICBjb25zdCBmcm9tSWRzVHlwZSA9IGZyb21FbnRpdHkuZ2V0UGtBcnJheVR5cGUoKTtcblxuICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKFxuICAgICAgICAgIFwie1wiLFxuICAgICAgICAgIGBhczogXCIke2xvYWRlci5hc31cIixgLFxuICAgICAgICAgIGByZWZJZDogXCIke2xvYWRlci5tYW55Sm9pbi5pZEZpZWxkfVwiLGAsXG4gICAgICAgICAgYHFiOiAocWJXcmFwcGVyOiBQdXJpV3JhcHBlcjxEYXRhYmFzZVNjaGVtYUV4dGVuZD4sIGZyb21JZHM6IG51bWJlcltdIHwgc3RyaW5nW10pID0+IHtgLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmICh0aHJvdWdoID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAvLyBIYXNNYW55XG4gICAgICAgICAgbG9hZGVyTGluZXMucHVzaChcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICBcInJldHVybiBxYldyYXBwZXJcIixcbiAgICAgICAgICAgIGAuZnJvbShcIiR7dG9UYWJsZX1cIilgLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBsb2FkZXIub25lSm9pbnMuZm9yRWFjaCgoam9pbjogU3Vic2V0UXVlcnlbXCJqb2luc1wiXVtudW1iZXJdKSA9PiB7XG4gICAgICAgICAgICAvLyBGSyBudWxsYWJsZSDsl6zrtoDripQgbGVmdEpvaW4g7YOA7J6FIOyLnOq3uOuLiOyymOyXkOyEnCDsnpDrj5nsnLzroZwg7YyQ64uo65CoXG4gICAgICAgICAgICBjb25zdCBqb2luTWV0aG9kID0gam9pbi5qb2luID09PSBcImlubmVyXCIgPyBcImpvaW5cIiA6IFwibGVmdEpvaW5cIjtcbiAgICAgICAgICAgIGlmIChcImN1c3RvbVwiIGluIGpvaW4pIHtcbiAgICAgICAgICAgICAgLy8gY3VzdG9tIGpvaW4gY2xhdXNl64qUIGNhbGxiYWNrIO2Yle2DnOydmCBvbiDrqZTshJzrk5zroZwg7LKY66as7ZWp64uI64ukLlxuICAgICAgICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKFxuICAgICAgICAgICAgICAgIGAuJHtqb2luTWV0aG9kfSh7ICR7am9pbi5hc306IFwiJHtqb2luLnRhYmxlfVwiIH0sIChqKSA9PiB7YCxcbiAgICAgICAgICAgICAgICBgai5vbihQdXJpLnJhd1N0cmluZyhcIiR7am9pbi5jdXN0b219XCIpKTtgLFxuICAgICAgICAgICAgICAgIFwifSlcIixcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGxvYWRlckxpbmVzLnB1c2goXG4gICAgICAgICAgICAgICAgYC4ke2pvaW5NZXRob2R9KHsgJHtqb2luLmFzfTogXCIke2pvaW4udGFibGV9XCIgfSwgXCIke2pvaW4uZnJvbX1cIiwgXCIke2pvaW4udG99XCIpYCxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIOyeheyytOyggSBzZWxlY3Qg6rWs7KGwIOyDneyEsSAocmVmSWQg7Y+s7ZWoKVxuICAgICAgICAgIGNvbnN0IHNlbGVjdE9iaiA9IHRoaXMuYnVpbGROZXN0ZWRTZWxlY3RPYmplY3QobG9hZGVyLnNlbGVjdCk7XG4gICAgICAgICAgc2VsZWN0T2JqLnJlZklkID0gYFwiJHt0b1RhYmxlfS4ke3RvQ29sfVwiYDtcbiAgICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKFxuICAgICAgICAgICAgYC53aGVyZUluKFwiJHt0b1RhYmxlfS4ke3RvQ29sfVwiLCBmcm9tSWRzIGFzICR7ZnJvbUlkc1R5cGV9KWAsXG4gICAgICAgICAgICBgLnNlbGVjdCgke3RoaXMuc3RyaW5naWZ5TmVzdGVkU2VsZWN0T2JqZWN0KHNlbGVjdE9iail9KTtgLFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gTWFueVRvTWFueVxuICAgICAgICAgIGxvYWRlckxpbmVzLnB1c2goXG4gICAgICAgICAgICBcInJldHVybiBxYldyYXBwZXJcIixcbiAgICAgICAgICAgIGAuZnJvbShcIiR7dGhyb3VnaC50YWJsZX1cIilgLFxuICAgICAgICAgICAgYC5qb2luKFwiJHt0b1RhYmxlfVwiLCBcIiR7dGhyb3VnaC50YWJsZX0uJHt0aHJvdWdoLnRvQ29sfVwiLCBcIiR7dG9UYWJsZX0uJHt0b0NvbH1cIilgLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBsb2FkZXIub25lSm9pbnMuZm9yRWFjaCgoam9pbjogU3Vic2V0UXVlcnlbXCJqb2luc1wiXVtudW1iZXJdKSA9PiB7XG4gICAgICAgICAgICAvLyBGSyBudWxsYWJsZSDsl6zrtoDripQgbGVmdEpvaW4g7YOA7J6FIOyLnOq3uOuLiOyymOyXkOyEnCDsnpDrj5nsnLzroZwg7YyQ64uo65CoXG4gICAgICAgICAgICBjb25zdCBqb2luTWV0aG9kID0gam9pbi5qb2luID09PSBcImlubmVyXCIgPyBcImpvaW5cIiA6IFwibGVmdEpvaW5cIjtcbiAgICAgICAgICAgIGlmIChcImN1c3RvbVwiIGluIGpvaW4pIHtcbiAgICAgICAgICAgICAgLy8gY3VzdG9tIGpvaW4gY2xhdXNl64qUIGNhbGxiYWNrIO2Yle2DnOydmCBvbiDrqZTshJzrk5zroZwg7LKY66as7ZWp64uI64ukLlxuICAgICAgICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKFxuICAgICAgICAgICAgICAgIGAuJHtqb2luTWV0aG9kfSh7ICR7am9pbi5hc306IFwiJHtqb2luLnRhYmxlfVwiIH0sIChqKSA9PiB7YCxcbiAgICAgICAgICAgICAgICBgai5vbihQdXJpLnJhd1N0cmluZyhcIiR7am9pbi5jdXN0b219XCIpKTtgLFxuICAgICAgICAgICAgICAgIFwifSlcIixcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGxvYWRlckxpbmVzLnB1c2goXG4gICAgICAgICAgICAgICAgYC4ke2pvaW5NZXRob2R9KHsgJHtqb2luLmFzfTogXCIke2pvaW4udGFibGV9XCIgfSwgXCIke2pvaW4uZnJvbX1cIiwgXCIke2pvaW4udG99XCIpYCxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIOyeheyytOyggSBzZWxlY3Qg6rWs7KGwIOyDneyEsSAocmVmSWQg7Y+s7ZWoKVxuICAgICAgICAgIGNvbnN0IHNlbGVjdE9iaiA9IHRoaXMuYnVpbGROZXN0ZWRTZWxlY3RPYmplY3QobG9hZGVyLnNlbGVjdCk7XG4gICAgICAgICAgc2VsZWN0T2JqLnJlZklkID0gYFwiJHt0aHJvdWdoLnRhYmxlfS4ke3Rocm91Z2guZnJvbUNvbH1cImA7XG4gICAgICAgICAgbG9hZGVyTGluZXMucHVzaChcbiAgICAgICAgICAgIGAud2hlcmVJbihcIiR7dGhyb3VnaC50YWJsZX0uJHt0aHJvdWdoLmZyb21Db2x9XCIsIGZyb21JZHMgYXMgJHtmcm9tSWRzVHlwZX0pYCxcbiAgICAgICAgICAgIGAuc2VsZWN0KCR7dGhpcy5zdHJpbmdpZnlOZXN0ZWRTZWxlY3RPYmplY3Qoc2VsZWN0T2JqKX0pO2AsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxvYWRlckxpbmVzLnB1c2goYH0sYCk7XG5cbiAgICAgICAgLy8g7KSR7LKpIGxvYWRlcnMg7LKY66asXG4gICAgICAgIGlmIChsb2FkZXIubG9hZGVycyAmJiBsb2FkZXIubG9hZGVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgbG9hZGVyTGluZXMucHVzaChcImxvYWRlcnM6IFtcIiwgLi4uZ2VuZXJhdGVMb2FkZXJDb2RlKGxvYWRlci5sb2FkZXJzKSwgXCJdLFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxvYWRlckxpbmVzLnB1c2goXCJ9LFwiKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGxvYWRlckxpbmVzO1xuICAgIH07XG5cbiAgICBsaW5lcy5wdXNoKC4uLmdlbmVyYXRlTG9hZGVyQ29kZShsb2FkZXJzKSk7XG4gICAgbGluZXMucHVzaChgXWApO1xuXG4gICAgcmV0dXJuIGxpbmVzLmpvaW4oXCJcXG5cIik7XG4gIH1cblxuICAvKlxuICAgIHN1YnNldCBTRUxFQ1QvSk9JTi9MT0FERVIg6rKw6rO8IOumrO2EtFxuICAqL1xuICBnZXRTdWJzZXRRdWVyeShzdWJzZXRLZXk6IHN0cmluZyk6IFN1YnNldFF1ZXJ5IHtcbiAgICBjb25zdCBzdWJzZXQgPSB0aGlzLmdldFN1YnNldEZpZWxkc0ZvclF1ZXJ5KHN1YnNldEtleSk7XG5cbiAgICBjb25zdCByZXN1bHQ6IFN1YnNldFF1ZXJ5ID0gdGhpcy5yZXNvbHZlU3Vic2V0UXVlcnkoXCJcIiwgc3Vic2V0KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLypcbiAgICovXG4gIHJlc29sdmVTdWJzZXRRdWVyeShcbiAgICBwcmVmaXg6IHN0cmluZyxcbiAgICBmaWVsZHM6IHN0cmluZ1tdLFxuICAgIGlzQWxyZWFkeU91dGVySm9pbmVkOiBib29sZWFuID0gZmFsc2UsXG4gICk6IFN1YnNldFF1ZXJ5IHtcbiAgICAvLyBwcmVmaXgg7LmY7ZmYIChwcmVmaXjripQgVG9PbmVSZWxhdGlvbuydtCDrs7XsiJjroZwg67aZ7J2AIOqyveyasCDrqqjrkZAgX1/roZwg67OA6rK965CoKVxuICAgIHByZWZpeCA9IHByZWZpeC5yZXBsYWNlKC9cXC4vZywgXCJfX1wiKTtcblxuICAgIC8vIOyEnOu4jOyFi+ydhCAx646B7Iqk66eMIOu2hOumrO2VmOyXrCDqt7jro7ntlZFcbiAgICBjb25zdCBzdWJzZXRHcm91cCA9IGdyb3VwKGZpZWxkcywgKGZpZWxkKSA9PiB7XG4gICAgICBpZiAoZmllbGQuaW5jbHVkZXMoXCIuXCIpKSB7XG4gICAgICAgIGNvbnN0IFtyZWxdID0gZmllbGQuc3BsaXQoXCIuXCIpO1xuICAgICAgICByZXR1cm4gcmVsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBPYmplY3Qua2V5cyhzdWJzZXRHcm91cCkucmVkdWNlKFxuICAgICAgKHIsIGdyb3VwS2V5KSA9PiB7XG4gICAgICAgIGNvbnN0IGZpZWxkcyA9IHN1YnNldEdyb3VwW2dyb3VwS2V5XTtcbiAgICAgICAgYXNzZXJ0KGZpZWxkcyAhPT0gdW5kZWZpbmVkLCBcImZpZWxkcyBpcyB1bmRlZmluZWRcIik7XG5cbiAgICAgICAgLy8g7ZiE7J6sIO2FjOydtOu4lCDtlYTrk5zshYvsnYAgc2VsZWN0LCB2aXJ0dWFs7JeQIOy2lOqwgO2VmOqzoCDrpqzthLRcbiAgICAgICAgaWYgKGdyb3VwS2V5ID09PSBcIlwiKSB7XG4gICAgICAgICAgY29uc3QgcmVhbEZpZWxkcyA9IGZpZWxkcy5maWx0ZXIoKGZpZWxkKSA9PiAhaXNWaXJ0dWFsUHJvcCh0aGlzLnByb3BzRGljdFtmaWVsZF0pKTtcbiAgICAgICAgICAvLyB2aXJ0dWFsVHlwZTogXCJjb2RlXCIgKOuYkOuKlCB1bmRlZmluZWQp7J24IHZpcnR1YWwgcHJvcOunjCByLnZpcnR1YWzsl5Ag7LaU6rCAXG4gICAgICAgICAgLy8gdmlydHVhbFR5cGU6IFwicXVlcnlcIuyduCDqsr3smrAg7IKs7Jqp7J6Q6rCAIGFwcGVuZFNlbGVjdOuhnCDsp4HsoJEg7LaU6rCA7ZWY66+A66GcIOygnOyZuFxuICAgICAgICAgIGNvbnN0IHZpcnR1YWxDb2RlRmllbGRzID0gZmllbGRzLmZpbHRlcigoZmllbGQpID0+XG4gICAgICAgICAgICBpc1ZpcnR1YWxDb2RlUHJvcCh0aGlzLnByb3BzRGljdFtmaWVsZF0pLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAocHJlZml4ID09PSBcIlwiKSB7XG4gICAgICAgICAgICAvLyDtmITsnqwg7YWM7J2067iU7J24IOqyveyasFxuICAgICAgICAgICAgci5zZWxlY3QgPSByLnNlbGVjdC5jb25jYXQocmVhbEZpZWxkcy5tYXAoKGZpZWxkKSA9PiB0aGlzLmdldEZ1bGxGaWVsZE5hbWUoZmllbGQpKSk7XG4gICAgICAgICAgICByLnZpcnR1YWwgPSByLnZpcnR1YWwuY29uY2F0KHZpcnR1YWxDb2RlRmllbGRzKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8g64SY7Ja07JioIO2FjOydtOu4lOyduCDqsr3smrBcbiAgICAgICAgICAgIHIuc2VsZWN0ID0gci5zZWxlY3QuY29uY2F0KFxuICAgICAgICAgICAgICByZWFsRmllbGRzLm1hcCgoZmllbGQpID0+IGAke3ByZWZpeH0uJHtmaWVsZH0gYXMgJHtwcmVmaXh9X18ke2ZpZWxkfWApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlbGF0aW9uID0gdGhpcy5yZWxhdGlvbnNbZ3JvdXBLZXldO1xuICAgICAgICBpZiAocmVsYXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg7KG07J6s7ZWY7KeAIOyViuuKlCByZWxhdGlvbiDssLjsobAgJHtncm91cEtleX1gKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZWxFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChyZWxhdGlvbi53aXRoKTtcblxuICAgICAgICBpZiAoaXNPbmVUb09uZVJlbGF0aW9uUHJvcChyZWxhdGlvbikgfHwgaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocmVsYXRpb24pKSB7XG4gICAgICAgICAgLy8gLU9uZSBSZWxhdGlvbjogSk9JTiDsnLzroZwg7LKY66asXG4gICAgICAgICAgY29uc3QgcmVsRmllbGRzID0gZmllbGRzLm1hcCgoZmllbGQpID0+IGZpZWxkLnNwbGl0KFwiLlwiKS5zbGljZSgxKS5qb2luKFwiLlwiKSk7XG5cbiAgICAgICAgICAvLyAtT25lIFJlbGF0aW9u7JeQ7IScIGlkIO2VhOuTnOunjCDssLjsobDtlZjripQg6rK97JqwIOumtOugiOydtOyFmCDrhJjquLDsp4Ag7JWK6rOgIOumrO2EtFxuICAgICAgICAgIGlmIChyZWxGaWVsZHMubGVuZ3RoID09PSAxICYmIHJlbEZpZWxkc1swXSA9PT0gXCJpZFwiKSB7XG4gICAgICAgICAgICBpZiAocHJlZml4ID09PSBcIlwiKSB7XG4gICAgICAgICAgICAgIHIuc2VsZWN0ID0gci5zZWxlY3QuY29uY2F0KGAke3RoaXMudGFibGV9LiR7Z3JvdXBLZXl9X2lkYCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByLnNlbGVjdCA9IHIuc2VsZWN0LmNvbmNhdChgJHtwcmVmaXh9LiR7Z3JvdXBLZXl9X2lkIGFzICR7cHJlZml4fV9fJHtncm91cEtleX1faWRgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGlubmVyT3JPdXRlclxuICAgICAgICAgIGNvbnN0IGlubmVyT3JPdXRlciA9ICgoKSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNBbHJlYWR5T3V0ZXJKb2luZWQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIFwib3V0ZXJcIjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzT25lVG9PbmVSZWxhdGlvblByb3AocmVsYXRpb24pKSB7XG4gICAgICAgICAgICAgIGlmIChyZWxhdGlvbi5oYXNKb2luQ29sdW1uICYmICEocmVsYXRpb24ubnVsbGFibGUgPz8gZmFsc2UpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiaW5uZXJcIjtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJvdXRlclwiO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpZiAocmVsYXRpb24ubnVsbGFibGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJvdXRlclwiO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBcImlubmVyXCI7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KSgpO1xuICAgICAgICAgIGNvbnN0IHJlbFN1YnNldFF1ZXJ5ID0gcmVsRW50aXR5LnJlc29sdmVTdWJzZXRRdWVyeShcbiAgICAgICAgICAgIGAke3ByZWZpeCAhPT0gXCJcIiA/IGAke3ByZWZpeH0uYCA6IFwiXCJ9JHtncm91cEtleX1gLFxuICAgICAgICAgICAgcmVsRmllbGRzLFxuICAgICAgICAgICAgaW5uZXJPck91dGVyID09PSBcIm91dGVyXCIsXG4gICAgICAgICAgKTtcbiAgICAgICAgICByLnNlbGVjdCA9IHIuc2VsZWN0LmNvbmNhdChyZWxTdWJzZXRRdWVyeS5zZWxlY3QpO1xuICAgICAgICAgIHIudmlydHVhbCA9IHIudmlydHVhbC5jb25jYXQocmVsU3Vic2V0UXVlcnkudmlydHVhbCk7XG5cbiAgICAgICAgICBjb25zdCBqb2luQXMgPSBwcmVmaXggPT09IFwiXCIgPyBncm91cEtleSA6IGAke3ByZWZpeH1fXyR7Z3JvdXBLZXl9YDtcbiAgICAgICAgICBjb25zdCBmcm9tVGFibGUgPSBwcmVmaXggPT09IFwiXCIgPyB0aGlzLnRhYmxlIDogcHJlZml4O1xuXG4gICAgICAgICAgbGV0IGpvaW5DbGF1c2U6XG4gICAgICAgICAgICB8IHtcbiAgICAgICAgICAgICAgICBmcm9tOiBzdHJpbmc7XG4gICAgICAgICAgICAgICAgdG86IHN0cmluZztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfCB7XG4gICAgICAgICAgICAgICAgY3VzdG9tOiBzdHJpbmc7XG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKHJlbGF0aW9uLmN1c3RvbUpvaW5DbGF1c2UpIHtcbiAgICAgICAgICAgIGpvaW5DbGF1c2UgPSB7XG4gICAgICAgICAgICAgIGN1c3RvbTogcmVsYXRpb24uY3VzdG9tSm9pbkNsYXVzZSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmc7XG4gICAgICAgICAgICBpZiAoaXNPbmVUb09uZVJlbGF0aW9uUHJvcChyZWxhdGlvbikpIHtcbiAgICAgICAgICAgICAgaWYgKHJlbGF0aW9uLmhhc0pvaW5Db2x1bW4pIHtcbiAgICAgICAgICAgICAgICBmcm9tID0gYCR7ZnJvbVRhYmxlfS4ke3JlbGF0aW9uLm5hbWV9X2lkYDtcbiAgICAgICAgICAgICAgICB0byA9IGAke2pvaW5Bc30uaWRgO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZyb20gPSBgJHtmcm9tVGFibGV9LmlkYDtcbiAgICAgICAgICAgICAgICB0byA9IGAke2pvaW5Bc30uJHtpbmZsZWN0aW9uLnVuZGVyc2NvcmUodGhpcy5uYW1lcy5mcy5yZXBsYWNlKC8tL2csIFwiX1wiKSl9X2lkYDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZnJvbSA9IGAke2Zyb21UYWJsZX0uJHtyZWxhdGlvbi5uYW1lfV9pZGA7XG4gICAgICAgICAgICAgIHRvID0gYCR7am9pbkFzfS5pZGA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBqb2luQ2xhdXNlID0ge1xuICAgICAgICAgICAgICBmcm9tLFxuICAgICAgICAgICAgICB0byxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgci5qb2lucy5wdXNoKHtcbiAgICAgICAgICAgIGFzOiBqb2luQXMsXG4gICAgICAgICAgICBqb2luOiBpbm5lck9yT3V0ZXIsXG4gICAgICAgICAgICB0YWJsZTogcmVsRW50aXR5LnRhYmxlLFxuICAgICAgICAgICAgLi4uam9pbkNsYXVzZSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIEJlbG9uZ3NUb09uZSDrsJHsl5AgSGFzTWFueeqwgCDrtpnsnYAg6rK97JqwXG4gICAgICAgICAgaWYgKHJlbFN1YnNldFF1ZXJ5LmxvYWRlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgY29udmVydGVkTG9hZGVycyA9IHJlbFN1YnNldFF1ZXJ5LmxvYWRlcnMubWFwKChsb2FkZXIpID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgbmV3QXMgPSBbZ3JvdXBLZXksIGxvYWRlci5hc10uam9pbihcIl9fXCIpO1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGFzOiBuZXdBcyxcbiAgICAgICAgICAgICAgICB0YWJsZTogbG9hZGVyLnRhYmxlLFxuICAgICAgICAgICAgICAgIG1hbnlKb2luOiBsb2FkZXIubWFueUpvaW4sXG4gICAgICAgICAgICAgICAgb25lSm9pbnM6IGxvYWRlci5vbmVKb2lucyxcbiAgICAgICAgICAgICAgICBzZWxlY3Q6IGxvYWRlci5zZWxlY3QsXG4gICAgICAgICAgICAgICAgbG9hZGVyczogbG9hZGVyLmxvYWRlcnMsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgci5sb2FkZXJzID0gWy4uLnIubG9hZGVycywgLi4uY29udmVydGVkTG9hZGVyc107XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgci5qb2lucyA9IHIuam9pbnMuY29uY2F0KHJlbFN1YnNldFF1ZXJ5LmpvaW5zKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc0hhc01hbnlSZWxhdGlvblByb3AocmVsYXRpb24pIHx8IGlzTWFueVRvTWFueVJlbGF0aW9uUHJvcChyZWxhdGlvbikpIHtcbiAgICAgICAgICAvLyAtTWFueSBSZWxhdGlvbjogTG9hZGVyIOuhnCDsspjrpqxcbiAgICAgICAgICBjb25zdCByZWxGaWVsZHMgPSBmaWVsZHMubWFwKChmaWVsZCkgPT4gZmllbGQuc3BsaXQoXCIuXCIpLnNsaWNlKDEpLmpvaW4oXCIuXCIpKTtcbiAgICAgICAgICBjb25zdCByZWxTdWJzZXRRdWVyeSA9IHJlbEVudGl0eS5yZXNvbHZlU3Vic2V0UXVlcnkoXCJcIiwgcmVsRmllbGRzKTtcblxuICAgICAgICAgIGxldCBtYW55Sm9pbjogU3Vic2V0UXVlcnlbXCJsb2FkZXJzXCJdW251bWJlcl1bXCJtYW55Sm9pblwiXTtcbiAgICAgICAgICBpZiAoaXNIYXNNYW55UmVsYXRpb25Qcm9wKHJlbGF0aW9uKSkge1xuICAgICAgICAgICAgY29uc3QgZnJvbUNvbCA9IHJlbGF0aW9uPy5mcm9tQ29sdW1uID8/IFwiaWRcIjtcbiAgICAgICAgICAgIG1hbnlKb2luID0ge1xuICAgICAgICAgICAgICBmcm9tVGFibGU6IHRoaXMudGFibGUsXG4gICAgICAgICAgICAgIGZyb21Db2wsXG4gICAgICAgICAgICAgIGlkRmllbGQ6IHByZWZpeCA9PT0gXCJcIiA/IGAke2Zyb21Db2x9YCA6IGAke3ByZWZpeH1fXyR7ZnJvbUNvbH1gLFxuICAgICAgICAgICAgICB0b1RhYmxlOiByZWxFbnRpdHkudGFibGUsXG4gICAgICAgICAgICAgIHRvQ29sOiByZWxhdGlvbi5qb2luQ29sdW1uLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzTWFueVRvTWFueVJlbGF0aW9uUHJvcChyZWxhdGlvbikpIHtcbiAgICAgICAgICAgIG1hbnlKb2luID0ge1xuICAgICAgICAgICAgICBmcm9tVGFibGU6IHRoaXMudGFibGUsXG4gICAgICAgICAgICAgIGZyb21Db2w6IFwiaWRcIixcbiAgICAgICAgICAgICAgaWRGaWVsZDogcHJlZml4ID09PSBcIlwiID8gYGlkYCA6IGAke3ByZWZpeH1fX2lkYCxcbiAgICAgICAgICAgICAgdGhyb3VnaDoge1xuICAgICAgICAgICAgICAgIHRhYmxlOiByZWxhdGlvbi5qb2luVGFibGUsXG4gICAgICAgICAgICAgICAgZnJvbUNvbDogYCR7aW5mbGVjdGlvbi5zaW5ndWxhcml6ZSh0aGlzLnRhYmxlKX1faWRgLFxuICAgICAgICAgICAgICAgIHRvQ29sOiBgJHtpbmZsZWN0aW9uLnNpbmd1bGFyaXplKHJlbEVudGl0eS50YWJsZSl9X2lkYCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdG9UYWJsZTogcmVsRW50aXR5LnRhYmxlLFxuICAgICAgICAgICAgICB0b0NvbDogXCJpZFwiLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgci5sb2FkZXJzLnB1c2goe1xuICAgICAgICAgICAgYXM6IGdyb3VwS2V5LFxuICAgICAgICAgICAgdGFibGU6IHJlbEVudGl0eS50YWJsZSxcbiAgICAgICAgICAgIG1hbnlKb2luLFxuICAgICAgICAgICAgb25lSm9pbnM6IHJlbFN1YnNldFF1ZXJ5LmpvaW5zLFxuICAgICAgICAgICAgc2VsZWN0OiByZWxTdWJzZXRRdWVyeS5zZWxlY3QsXG4gICAgICAgICAgICBsb2FkZXJzOiByZWxTdWJzZXRRdWVyeS5sb2FkZXJzLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHI7XG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBzZWxlY3Q6IFtdLFxuICAgICAgICB2aXJ0dWFsOiBbXSxcbiAgICAgICAgam9pbnM6IFtdLFxuICAgICAgICBsb2FkZXJzOiBbXSxcbiAgICAgIH0gYXMgU3Vic2V0UXVlcnksXG4gICAgKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLypcbiAgICBGaWVsZEV4cHJbXSDsnYQgRW50aXR5UHJvcE5vZGVbXSDroZwg67OA7ZmYXG4gICovXG4gIGZpZWxkRXhwcnNUb1Byb3BOb2RlcyhmaWVsZEV4cHJzOiBzdHJpbmdbXSwgZW50aXR5OiBFbnRpdHkgPSB0aGlzKTogRW50aXR5UHJvcE5vZGVbXSB7XG4gICAgY29uc3QgZ3JvdXBzID0gZmllbGRFeHBycy5yZWR1Y2UoXG4gICAgICAocmVzdWx0LCBmaWVsZEV4cHIpID0+IHtcbiAgICAgICAgbGV0IGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBlbHNlRXhwcjogc3RyaW5nW107XG4gICAgICAgIGlmIChmaWVsZEV4cHIuaW5jbHVkZXMoXCIuXCIpKSB7XG4gICAgICAgICAgW2tleSwgLi4uZWxzZUV4cHJdID0gZmllbGRFeHByLnNwbGl0KFwiLlwiKTtcbiAgICAgICAgICB2YWx1ZSA9IGVsc2VFeHByLmpvaW4oXCIuXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGtleSA9IFwiXCI7XG4gICAgICAgICAgdmFsdWUgPSBmaWVsZEV4cHI7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0W2tleV0gPSAocmVzdWx0W2tleV0gPz8gW10pLmNvbmNhdCh2YWx1ZSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0sXG4gICAgICB7fSBhcyB7XG4gICAgICAgIFtrOiBzdHJpbmddOiBzdHJpbmdbXTtcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIHJldHVybiBPYmplY3Qua2V5cyhncm91cHMpLmZsYXRNYXA8RW50aXR5UHJvcE5vZGUsIEVudGl0eVByb3BOb2RlW10+KChrZXkpID0+IHtcbiAgICAgIGNvbnN0IGdyb3VwID0gZ3JvdXBzW2tleV07XG5cbiAgICAgIC8vIOydvOuwmCBwcm9wIOyymOumrFxuICAgICAgaWYgKGtleSA9PT0gXCJcIikge1xuICAgICAgICByZXR1cm4gZ3JvdXAubWFwKChwcm9wTmFtZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHByb3AgPSBlbnRpdHkucHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBwcm9wTmFtZSk7XG4gICAgICAgICAgaWYgKHByb3AgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICBgJHtlbnRpdHkuaWR9IC0tIOyemOuqu+uQnCBGaWVsZEV4cHIgJyR7cHJvcE5hbWV9JyAo7IKs7JqpIOqwgOuKpe2VnCBwcm9wczogJHtlbnRpdHkucHJvcHMubWFwKChwKSA9PiBwLm5hbWUpLmpvaW4oXCIsIFwiKX0pYCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBub2RlVHlwZTogXCJwbGFpblwiIGFzIGNvbnN0LFxuICAgICAgICAgICAgcHJvcCxcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gcmVsYXRpb24gcHJvcCDsspjrpqxcbiAgICAgIGNvbnN0IHByb3AgPSBlbnRpdHkucHJvcHNEaWN0W2tleV07XG4gICAgICBpZiAoIWlzUmVsYXRpb25Qcm9wKHByb3ApKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihg7J6Y66q765CcIEZpZWxkRXhwciAke2tleX0uJHtncm91cFswXX1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlbEVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KHByb3Aud2l0aCk7XG5cbiAgICAgIC8vIHJlbGF0aW9uIC1PbmUg7JeQIGlkIO2VhOuTnCDtlZjrgpjsnbgg6rK97JqwXG4gICAgICBpZiAoaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocHJvcCkgfHwgaXNPbmVUb09uZVJlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICBpZiAoZ3JvdXAubGVuZ3RoID09PSAxICYmIChncm91cFswXSA9PT0gXCJpZFwiIHx8IGdyb3VwWzBdID09PSBcImlkP1wiKSkge1xuICAgICAgICAgIC8vIGlkIO2VmOuCmOunjCDsnojripTsp4Ag7LK07YGs7ZW07IScLCDtlZjrgpjrp4wg7J6I7Jy866m0IOyDgeychCBwcm9w7Jy866GcIGlk66W8IOumrO2EtFxuICAgICAgICAgIGNvbnN0IGlkUHJvcCA9IHJlbEVudGl0eS5wcm9wc0RpY3QuaWQ7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG5vZGVUeXBlOiBcInBsYWluXCIgYXMgY29uc3QsXG4gICAgICAgICAgICBwcm9wOiB7XG4gICAgICAgICAgICAgIC4uLmlkUHJvcCxcbiAgICAgICAgICAgICAgbmFtZTogYCR7a2V5fV9pZGAsXG4gICAgICAgICAgICAgIG51bGxhYmxlOiBwcm9wLm51bGxhYmxlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIC1PbmUg6re47Jm47J2YIOqyveyasCBvYmplY3TroZwg66as7YS0XG4gICAgICAvLyAtTWFueeydmCDqsr3smrAgYXJyYXnroZwg66as7YS0XG4gICAgICAvLyBSZWN1cnNpdmUg66GcIOuOgeyKpCDsspjrpqxcbiAgICAgIGNvbnN0IGNoaWxkcmVuID0gdGhpcy5maWVsZEV4cHJzVG9Qcm9wTm9kZXMoZ3JvdXAsIHJlbEVudGl0eSk7XG4gICAgICBjb25zdCBub2RlVHlwZSA9XG4gICAgICAgIGlzQmVsb25nc1RvT25lUmVsYXRpb25Qcm9wKHByb3ApIHx8IGlzT25lVG9PbmVSZWxhdGlvblByb3AocHJvcClcbiAgICAgICAgICA/IChcIm9iamVjdFwiIGFzIGNvbnN0KVxuICAgICAgICAgIDogKFwiYXJyYXlcIiBhcyBjb25zdCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5vZGVUeXBlLFxuICAgICAgICBwcm9wLFxuICAgICAgICBjaGlsZHJlbixcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBnZXRGaWVsZEV4cHJzKHByZWZpeCA9IFwiXCIsIG1heERlcHRoOiBudW1iZXIgPSAzLCBmcm9tczogc3RyaW5nW10gPSBbXSk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5wcm9wc1xuICAgICAgLmZsYXRNYXAoKHByb3ApID0+IHtcbiAgICAgICAgY29uc3QgcHJvcE5hbWUgPSBbcHJlZml4LCBwcm9wLm5hbWVdLmZpbHRlcigodikgPT4gdiAhPT0gXCJcIikuam9pbihcIi5cIik7XG4gICAgICAgIGlmIChwcm9wTmFtZSA9PT0gcHJlZml4KSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzUmVsYXRpb25Qcm9wKHByb3ApKSB7XG4gICAgICAgICAgaWYgKG1heERlcHRoIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChmcm9tcy5pbmNsdWRlcyhwcm9wLndpdGgpKSB7XG4gICAgICAgICAgICAvLyDsl63rsKntlqUgcmVsYXRpb27snbgg6rK97JqwIOygnOyZuFxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIOygleuwqe2WpSByZWxhdGlvbuyduCDqsr3smrAgcmVjdXJzaXZlIOy9nFxuICAgICAgICAgIGNvbnN0IHJlbE1kID0gRW50aXR5TWFuYWdlci5nZXQocHJvcC53aXRoKTtcbiAgICAgICAgICByZXR1cm4gcmVsTWQuZ2V0RmllbGRFeHBycyhwcm9wTmFtZSwgbWF4RGVwdGggLSAxLCBbLi4uZnJvbXMsIHRoaXMuaWRdKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvcE5hbWU7XG4gICAgICB9KVxuICAgICAgLmZpbHRlcigoZikgPT4gZiAhPT0gbnVsbCk7XG4gIH1cblxuICAvKipcbiAgICogUmVsYXRpb24gcHJvcOydtCDtmITsnqwg7YWM7J2067iU7JeQIEZLIOy7rOufvOydhCDsg53shLHtlZjripTsp4Ag7ZmV7J24XG4gICAqKEJlbG9uZ3NUb09uZSDrmJDripQgT25lVG9PbmUoaGFzSm9pbkNvbHVtbj10cnVlKeyduCDqsr3smrAgRksg7IOd7ISxKVxuICAgKi9cbiAgcHJpdmF0ZSBoYXNGb3JlaWduS2V5KHByb3A6IFJlbGF0aW9uUHJvcCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICBwcm9wLnJlbGF0aW9uVHlwZSA9PT0gXCJCZWxvbmdzVG9PbmVcIiB8fFxuICAgICAgKHByb3AucmVsYXRpb25UeXBlID09PSBcIk9uZVRvT25lXCIgJiYgcHJvcC5oYXNKb2luQ29sdW1uKVxuICAgICk7XG4gIH1cblxuICBnZXRUYWJsZUNvbHVtbnMoKTogeyBuYW1lOiBzdHJpbmc7IHR5cGU6IHN0cmluZyB9W10ge1xuICAgIHJldHVybiB0aGlzLnByb3BzXG4gICAgICAubWFwKChwcm9wKSA9PiB7XG4gICAgICAgIGlmIChwcm9wLnR5cGUgPT09IFwicmVsYXRpb25cIikge1xuICAgICAgICAgIGlmICh0aGlzLmhhc0ZvcmVpZ25LZXkocHJvcCkpIHtcbiAgICAgICAgICAgIHJldHVybiB7IG5hbWU6IGAke3Byb3AubmFtZX1faWRgLCB0eXBlOiBcImludF91bnNpZ25lZFwiIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBuYW1lOiBwcm9wLm5hbWUsIHR5cGU6IHByb3AudHlwZSB9O1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIobm9uTnVsbGFibGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVudGl0eeyXkCDsoJXsnZjrkJwg66qo65OgIHZlY3RvciDtg4DsnoUg7Lus65+8IOuwmO2ZmFxuICAgKi9cbiAgZ2V0VmVjdG9yQ29sdW1ucygpOiBFbnRpdHlQcm9wW10ge1xuICAgIHJldHVybiB0aGlzLnByb3BzLmZpbHRlcigocCkgPT4gcC50eXBlID09PSBcInZlY3RvclwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDtirnsoJUgdmVjdG9yIOy7rOufvCDrsJjtmZhcbiAgICogQHBhcmFtIGNvbHVtbk5hbWUgLSDsu6zrn7zrqoUgKOyDneuetSDsi5wg7LKrIOuyiOynuCB2ZWN0b3Ig7Lus65+8KVxuICAgKi9cbiAgZ2V0VmVjdG9yQ29sdW1uKGNvbHVtbk5hbWU/OiBzdHJpbmcpOiBFbnRpdHlQcm9wIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCB2ZWN0b3JQcm9wcyA9IHRoaXMuZ2V0VmVjdG9yQ29sdW1ucygpO1xuICAgIGlmIChjb2x1bW5OYW1lKSB7XG4gICAgICByZXR1cm4gdmVjdG9yUHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBjb2x1bW5OYW1lKTtcbiAgICB9XG4gICAgcmV0dXJuIHZlY3RvclByb3BzWzBdO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VhO2EsOungSDqsIDriqXtlZwgcHJvcHMg67CY7ZmYXG4gICAqXG4gICAqIC0g7J2867CYIHByb3BcbiAgICogLSBGS+ulvCDsg53shLHtlZjripQgcmVsYXRpb24gKEJlbG9uZ3NUb09uZSwgT25lVG9PbmUgd2l0aCBoYXNKb2luQ29sdW1uKVxuICAgKiAgIOKGkiB7bmFtZX1faWQg7ZiV7YOc7J2YIOqwgOyDgSBpbnRlZ2VyIHByb3DsnLzroZwg67OA7ZmYXG4gICAqL1xuICBnZXRGaWx0ZXJhYmxlUHJvcHMoKTogRW50aXR5UHJvcFtdIHtcbiAgICByZXR1cm4gdGhpcy5wcm9wcy5mbGF0TWFwKChwcm9wKTogRW50aXR5UHJvcCB8IEVudGl0eVByb3BbXSA9PiB7XG4gICAgICAvLyBWaXJ0dWFsIHByb3Ag7KCc7Jm4XG4gICAgICBpZiAoaXNWaXJ0dWFsUHJvcChwcm9wKSkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG5cbiAgICAgIC8vIFJlbGF0aW9uIHByb3Ag7LKY66asXG4gICAgICBpZiAoaXNSZWxhdGlvblByb3AocHJvcCkpIHtcbiAgICAgICAgLy8gRkvrpbwg7IOd7ISx7ZWY64qUIHJlbGF0aW9u66eMIO2PrO2VqFxuICAgICAgICBpZiAodGhpcy5oYXNGb3JlaWduS2V5KHByb3ApKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG5hbWU6IGAke3Byb3AubmFtZX1faWRgLFxuICAgICAgICAgICAgdHlwZTogXCJpbnRlZ2VyXCIsXG4gICAgICAgICAgICBudWxsYWJsZTogcHJvcC5udWxsYWJsZSxcbiAgICAgICAgICB9IGFzIEVudGl0eVByb3A7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuXG4gICAgICAvLyDsnbzrsJggcHJvcCDsspjrpqxcbiAgICAgIHJldHVybiBwcm9wO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgcmVnaXN0ZXJNb2R1bGVQYXRocygpIHtcbiAgICBjb25zdCBiYXNlUGF0aCA9IGAke3RoaXMubmFtZXMucGFyZW50RnN9YDtcblxuICAgIC8vIGJhc2Utc2NoZW1lXG4gICAgRW50aXR5TWFuYWdlci5zZXRNb2R1bGVQYXRoKGAke3RoaXMuaWR9QmFzZVNjaGVtYWAsIGBzb25hbXUuZ2VuZXJhdGVkYCk7XG5cbiAgICAvLyBzdWJzZXRcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5zdWJzZXRzKS5sZW5ndGggPiAwKSB7XG4gICAgICBFbnRpdHlNYW5hZ2VyLnNldE1vZHVsZVBhdGgoYCR7dGhpcy5pZH1TdWJzZXRLZXlgLCBgc29uYW11LmdlbmVyYXRlZGApO1xuICAgICAgRW50aXR5TWFuYWdlci5zZXRNb2R1bGVQYXRoKGAke3RoaXMuaWR9U3Vic2V0TWFwcGluZ2AsIGBzb25hbXUuZ2VuZXJhdGVkYCk7XG4gICAgICBmb3IgKGNvbnN0IHN1YnNldEtleSBvZiBPYmplY3Qua2V5cyh0aGlzLnN1YnNldHMpKSB7XG4gICAgICAgIEVudGl0eU1hbmFnZXIuc2V0TW9kdWxlUGF0aChcbiAgICAgICAgICBgJHt0aGlzLmlkfVN1YnNldCR7c3Vic2V0S2V5LnRvVXBwZXJDYXNlKCl9YCxcbiAgICAgICAgICBgc29uYW11LmdlbmVyYXRlZGAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gZW51bXNcbiAgICBmb3IgKGNvbnN0IGVudW1JZCBvZiBPYmplY3Qua2V5cyh0aGlzLmVudW1MYWJlbHMpKSB7XG4gICAgICBFbnRpdHlNYW5hZ2VyLnNldE1vZHVsZVBhdGgoZW51bUlkLCBgc29uYW11LmdlbmVyYXRlZGApO1xuICAgIH1cblxuICAgIC8vIHR5cGVzXG4gICAgY29uc3QgdHlwZXNNb2R1bGVQYXRoID0gYCR7YmFzZVBhdGh9LyR7dGhpcy5uYW1lcy5wYXJlbnRGc30udHlwZXNgO1xuICAgIGNvbnN0IHR5cGVzRmlsZVBhdGggPSBwYXRoLmpvaW4oXG4gICAgICBTb25hbXUuYXBpUm9vdFBhdGgsXG4gICAgICBydW50aW1lUGF0aChgZGlzdC9hcHBsaWNhdGlvbi8ke3R5cGVzTW9kdWxlUGF0aH0uanNgKSxcbiAgICApO1xuXG4gICAgaWYgKGF3YWl0IGV4aXN0cyh0eXBlc0ZpbGVQYXRoKSkge1xuICAgICAgY29uc3QgaW1wb3J0ZWRNZW1iZXJzID0gYXdhaXQgaW1wb3J0TWVtYmVyczx6LlpvZFR5cGVBbnk+KHR5cGVzRmlsZVBhdGgpO1xuICAgICAgdGhpcy50eXBlcyA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgaW1wb3J0ZWRNZW1iZXJzLm1hcCgoeyBuYW1lLCB2YWx1ZSB9KSA9PiB7XG4gICAgICAgICAgRW50aXR5TWFuYWdlci5zZXRNb2R1bGVQYXRoKG5hbWUsIHR5cGVzTW9kdWxlUGF0aCk7XG4gICAgICAgICAgcmV0dXJuIFtuYW1lLCB2YWx1ZV07XG4gICAgICAgIH0pLFxuICAgICAgKSBhcyB7IFtuYW1lOiBzdHJpbmddOiB6LlpvZFR5cGVBbnkgfTtcbiAgICB9XG4gIH1cblxuICByZWdpc3RlclRhYmxlU3BlY3MoKTogdm9pZCB7XG4gICAgLy8g7KGw7J24IO2FjOydtOu4lCDsnbjrjbHsiqQg7KCc7Jm4ICjsu6zrn7wg7J2066aE7JeQICcuJ+ydtCDtj6ztlajrkJwg6rK97JqwKVxuICAgIGNvbnN0IHVuaXF1ZUluZGV4ZXMgPSB0aGlzLmluZGV4ZXNcbiAgICAgIC5maWx0ZXIoKGlkeCkgPT4gaWR4LnR5cGUgPT09IFwidW5pcXVlXCIpXG4gICAgICAuZmlsdGVyKChpZHgpID0+IGlkeC5jb2x1bW5zLmV2ZXJ5KChjb2wpID0+ICFjb2wubmFtZS5pbmNsdWRlcyhcIi5cIikpKTtcblxuICAgIEVudGl0eU1hbmFnZXIuc2V0VGFibGVTcGVjKHtcbiAgICAgIG5hbWU6IHRoaXMudGFibGUsXG4gICAgICB1bmlxdWVJbmRleGVzLFxuICAgICAganNvbkNvbHVtbnM6IHRoaXMucHJvcHMuZmlsdGVyKChwKSA9PiBwLnR5cGUgPT09IFwianNvblwiKS5tYXAoKHApID0+IHAubmFtZSksXG4gICAgfSk7XG4gIH1cblxuICB0b0pzb24oKTogRW50aXR5SnNvbiB7XG4gICAgLy8gc3Vic2V0c+yZgCBzdWJzZXRzSW50ZXJuYWzsnYQgU3Vic2V0RGVmIO2Yle2DnOuhnCDrs7Xsm5AgKGNvbmUg7Y+s7ZWoKVxuICAgIGNvbnN0IHN1YnNldHM6IHsgW2tleTogc3RyaW5nXTogaW1wb3J0KFwiLi4vdHlwZXMvdHlwZXNcIikuU3Vic2V0RGVmIH0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLnN1YnNldHMpKSB7XG4gICAgICBjb25zdCBub3JtYWxGaWVsZHM6IFN1YnNldEZpZWxkW10gPSB0aGlzLnN1YnNldHNba2V5XTtcbiAgICAgIGNvbnN0IGludGVybmFsRmllbGRzOiBTdWJzZXRGaWVsZFtdID0gKHRoaXMuc3Vic2V0c0ludGVybmFsW2tleV0gPz8gW10pLm1hcCgoZmllbGQpID0+ICh7XG4gICAgICAgIGZpZWxkLFxuICAgICAgICBpbnRlcm5hbDogdHJ1ZSxcbiAgICAgIH0pKTtcbiAgICAgIGNvbnN0IGZpZWxkcyA9IFsuLi5ub3JtYWxGaWVsZHMsIC4uLmludGVybmFsRmllbGRzXTtcblxuICAgICAgLy8gY29uZeydtCDsnojsnLzrqbQg7IOI66Gc7Jq0IOqwneyytCDtmJXtg5zroZwsIOyXhuycvOuptCDrsLDsl7Qg7ZiV7YOc66GcXG4gICAgICBpZiAodGhpcy5zdWJzZXRDb25lc1trZXldKSB7XG4gICAgICAgIHN1YnNldHNba2V5XSA9IHtcbiAgICAgICAgICBmaWVsZHMsXG4gICAgICAgICAgY29uZTogdGhpcy5zdWJzZXRDb25lc1trZXldLFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3Vic2V0c1trZXldID0gZmllbGRzO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGVudW1z66W8IEVudW1EZWYg7ZiV7YOc66GcIOuzteybkCAoY29uZSDtj6ztlagpXG4gICAgY29uc3QgZW51bXM6IHsgW2tleTogc3RyaW5nXTogaW1wb3J0KFwiLi4vdHlwZXMvdHlwZXNcIikuRW51bURlZiB9ID0ge307XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZXNdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuZW51bUxhYmVscykpIHtcbiAgICAgIC8vIGNvbmXsnbQg7J6I7Jy866m0IOyDiOuhnOyatCDqsJ3ssrQg7ZiV7YOc66GcLCDsl4bsnLzrqbQgUmVjb3JkIO2Yle2DnOuhnFxuICAgICAgaWYgKHRoaXMuZW51bUNvbmVzW2tleV0pIHtcbiAgICAgICAgZW51bXNba2V5XSA9IHtcbiAgICAgICAgICB2YWx1ZXMsXG4gICAgICAgICAgY29uZTogdGhpcy5lbnVtQ29uZXNba2V5XSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVudW1zW2tleV0gPSB2YWx1ZXM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgcGFyZW50SWQ6IHRoaXMucGFyZW50SWQsXG4gICAgICB0YWJsZTogdGhpcy50YWJsZSxcbiAgICAgIHRpdGxlOiB0aGlzLnRpdGxlLFxuICAgICAgY29uZTogdGhpcy5jb25lLFxuICAgICAgcHJvcHM6IHRoaXMucHJvcHMsXG4gICAgICBpbmRleGVzOiB0aGlzLmluZGV4ZXMsXG4gICAgICBzdWJzZXRzLFxuICAgICAgZW51bXMsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIHNhdmUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gc29ydDogc3Vic2V0c1xuICAgIGNvbnN0IHN1YnNldFJvd3MgPSB0aGlzLmdldFN1YnNldFJvd3MoKTtcbiAgICB0aGlzLnN1YnNldHMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QuZW50cmllcyh0aGlzLnN1YnNldHMpLm1hcCgoW3N1YnNldEtleV0pID0+IHtcbiAgICAgICAgcmV0dXJuIFtzdWJzZXRLZXksIHRoaXMuc3Vic2V0Um93c1RvU3Vic2V0RmllbGRzKHN1YnNldFJvd3MsIHN1YnNldEtleSwgZmFsc2UpXTtcbiAgICAgIH0pLFxuICAgICk7XG4gICAgdGhpcy5zdWJzZXRzSW50ZXJuYWwgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QuZW50cmllcyh0aGlzLnN1YnNldHNJbnRlcm5hbCkubWFwKChbc3Vic2V0S2V5XSkgPT4ge1xuICAgICAgICByZXR1cm4gW3N1YnNldEtleSwgdGhpcy5zdWJzZXRSb3dzVG9TdWJzZXRGaWVsZHMoc3Vic2V0Um93cywgc3Vic2V0S2V5LCB0cnVlKV07XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgLy8gc2F2ZVxuICAgIGNvbnN0IGpzb25QYXRoID0gcGF0aC5qb2luKFxuICAgICAgU29uYW11LmFwaVJvb3RQYXRoLFxuICAgICAgYHNyYy9hcHBsaWNhdGlvbi8ke3RoaXMubmFtZXMucGFyZW50RnN9LyR7dGhpcy5uYW1lcy5mc30uZW50aXR5Lmpzb25gLFxuICAgICk7XG4gICAgY29uc3QganNvbiA9IHRoaXMudG9Kc29uKCk7XG4gICAgYXdhaXQgd3JpdGVGaWxlKGpzb25QYXRoLCBhd2FpdCBmb3JtYXRDb2RlKEpTT04uc3RyaW5naWZ5KGpzb24pLCBqc29uUGF0aCkpO1xuXG4gICAgLy8gcmVsb2FkXG4gICAgYXdhaXQgRW50aXR5TWFuYWdlci5yZWdpc3Rlcihqc29uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDthZztlIzrpr8gY29uZSDrqZTtg4DrjbDsnbTthLDrpbwg7IOd7ISx7ZWp64uI64ukLlxuICAgKlxuICAgKiBMTE3snYQg7IKs7Jqp7ZWY7KeAIOyViuqzoCBmYWtlci1tYXBwaW5ncy50c+ulvCDtmZzsmqntlZjsl6wg6riw67O4IGNvbmXsnYQg7IOd7ISx7ZWp64uI64ukLlxuICAgKiBzdHViIGVudGl0eSDsg53shLEg7IucIOyekOuPmeycvOuhnCDtmLjstpzrkJjslrQg7LWc7IaM7ZWc7J2YIGNvbmUg66mU7YOA642w7J207YSw66W8IOygnOqzte2VqeuLiOuLpC5cbiAgICpcbiAgICogQHBhcmFtIGxvY2FsZSAtIOyDneyEsSDsi5wg7IKs7Jqp7ZWgIGxvY2FsZSAo6riw67O46rCSOiBTb25hbXUuY29uZmlnLmkxOG4uZGVmYXVsdExvY2FsZSDrmJDripQgXCJrb1wiKVxuICAgKi9cbiAgYXN5bmMgZ2VuZXJhdGVUZW1wbGF0ZUNvbmVzKGxvY2FsZT86IFwia29cIiB8IFwiZW5cIiB8IFwiamFcIik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgZ2VuZXJhdGVUZW1wbGF0ZUNvbmVzIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2VudGl0eS10ZW1wbGF0ZS1jb25lXCIpO1xuICAgIGNvbnN0IGNvbmZpZ0xvY2FsZSA9IFNvbmFtdS5jb25maWcuaTE4bj8uZGVmYXVsdExvY2FsZTtcbiAgICBjb25zdCBlZmZlY3RpdmVMb2NhbGUgPVxuICAgICAgbG9jYWxlIHx8XG4gICAgICAoY29uZmlnTG9jYWxlID09PSBcImtvXCIgfHwgY29uZmlnTG9jYWxlID09PSBcImVuXCIgfHwgY29uZmlnTG9jYWxlID09PSBcImphXCJcbiAgICAgICAgPyBjb25maWdMb2NhbGVcbiAgICAgICAgOiBcImtvXCIpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGdlbmVyYXRlVGVtcGxhdGVDb25lcyh0aGlzLnRvSnNvbigpLCBlZmZlY3RpdmVMb2NhbGUpO1xuXG4gICAgLy8g6rKw6rO866W8IEVudGl0eeyXkCDsoIHsmqkgKGFwcGx5Q29uZXPsmYAg64+Z7J287ZWcIOuwqeyLnSlcbiAgICBpZiAocmVzdWx0LmVudGl0eUNvbmUpIHtcbiAgICAgIHRoaXMuY29uZSA9IHJlc3VsdC5lbnRpdHlDb25lO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgW3Byb3BOYW1lLCBjb25lXSBvZiBPYmplY3QuZW50cmllcyhyZXN1bHQucHJvcENvbmVzKSkge1xuICAgICAgY29uc3QgcHJvcCA9IHRoaXMucHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBwcm9wTmFtZSk7XG4gICAgICBpZiAocHJvcCkge1xuICAgICAgICAocHJvcCBhcyB7IGNvbmU/OiBDb25lIH0pLmNvbmUgPSBjb25lO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZW51bUNvbmVzID0geyAuLi50aGlzLmVudW1Db25lcywgLi4ucmVzdWx0LmVudW1Db25lcyB9O1xuICAgIHRoaXMuc3Vic2V0Q29uZXMgPSB7IC4uLnRoaXMuc3Vic2V0Q29uZXMsIC4uLnJlc3VsdC5zdWJzZXRDb25lcyB9O1xuXG4gICAgYXdhaXQgdGhpcy5zYXZlKCk7XG4gIH1cblxuICAvKipcbiAgICogTExN7J2EIOyCrOyaqe2VmOyXrCBjb25lIOuplO2DgOuNsOydtO2EsOulvCDsg53shLHtlanri4jri6QuXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpb25zLnByZXNlcnZlRXhpc3RpbmcgLSDquLDsobQgY29uZSDrs7TsobQg7Jes67aAICjquLDrs7jqsJI6IHRydWUpXG4gICAqIEBwYXJhbSBvcHRpb25zLm9ubHlFbXB0eSAtIGZpeHR1cmVIaW506rCAIOyXhuuKlCBjb25l66eMIOyDneyEsSAo6riw67O46rCSOiBmYWxzZSlcbiAgICogQHBhcmFtIG9wdGlvbnMubG9jYWxlIC0g7IOd7ISxIOyLnCDsgqzsmqntlaAgbG9jYWxlICjquLDrs7jqsJI6IFwia29cIilcbiAgICovXG4gIGFzeW5jIGdlbmVyYXRlQ29uZXMob3B0aW9ucz86IHtcbiAgICBwcmVzZXJ2ZUV4aXN0aW5nPzogYm9vbGVhbjtcbiAgICBvbmx5RW1wdHk/OiBib29sZWFuO1xuICAgIGxvY2FsZT86IFwia29cIiB8IFwiZW5cIiB8IFwiamFcIjtcbiAgfSk6IFByb21pc2U8aW1wb3J0KFwiLi4vY29uZS9jb25lLWdlbmVyYXRvclwiKS5Db25lR2VuZXJhdGlvblJlc3VsdD4ge1xuICAgIGNvbnN0IHsgZ2VuZXJhdGVDb25lcyB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vY29uZS9jb25lLWdlbmVyYXRvclwiKTtcbiAgICBjb25zdCBjb250ZXh0OiBpbXBvcnQoXCIuLi9jb25lL2NvbmUtZ2VuZXJhdG9yXCIpLkNvbmVHZW5lcmF0aW9uQ29udGV4dCA9IHtcbiAgICAgIGVudGl0eTogdGhpcy50b0pzb24oKSxcbiAgICAgIGxvY2FsZTogb3B0aW9ucz8ubG9jYWxlIHx8IFwia29cIixcbiAgICAgIGV4aXN0aW5nQ29uZXM6IG9wdGlvbnM/LnByZXNlcnZlRXhpc3RpbmcgIT09IGZhbHNlID8gdGhpcy5jb2xsZWN0RXhpc3RpbmdDb25lcygpIDogdW5kZWZpbmVkLFxuICAgICAgb25seUVtcHR5OiBvcHRpb25zPy5vbmx5RW1wdHkgPz8gZmFsc2UsXG4gICAgfTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdlbmVyYXRlQ29uZXMoY29udGV4dCk7XG4gICAgdGhpcy5hcHBseUNvbmVzKHJlc3VsdCk7XG4gICAgYXdhaXQgdGhpcy5zYXZlKCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiDquLDsobQgY29uZeuTpOydhCDsiJjsp5Htlanri4jri6QgKGVudGl0eSwgcHJvcHMsIGVudW1zLCBzdWJzZXRzKS5cbiAgICpcbiAgICogQHJldHVybnMg7YKk6rCAIFwiZW50aXR5OmlkXCIsIFwicHJvcDpuYW1lXCIsIFwiZW51bTplbnVtSWRcIiwgXCJzdWJzZXQ6a2V5XCIg7ZiV7Iud7J24IGNvbmUg66e1XG4gICAqL1xuICBwcml2YXRlIGNvbGxlY3RFeGlzdGluZ0NvbmVzKCk6IFJlY29yZDxzdHJpbmcsIENvbmU+IHtcbiAgICBjb25zdCBjb25lczogUmVjb3JkPHN0cmluZywgQ29uZT4gPSB7fTtcblxuICAgIGlmICh0aGlzLmNvbmUpIHtcbiAgICAgIGNvbmVzW2BlbnRpdHk6JHt0aGlzLmlkfWBdID0gdGhpcy5jb25lO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcHJvcCBvZiB0aGlzLnByb3BzKSB7XG4gICAgICBpZiAocHJvcC5jb25lKSB7XG4gICAgICAgIGNvbmVzW2Bwcm9wOiR7cHJvcC5uYW1lfWBdID0gcHJvcC5jb25lO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgW2VudW1JZCwgY29uZV0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5lbnVtQ29uZXMpKSB7XG4gICAgICBjb25lc1tgZW51bToke2VudW1JZH1gXSA9IGNvbmU7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbc3Vic2V0S2V5LCBjb25lXSBvZiBPYmplY3QuZW50cmllcyh0aGlzLnN1YnNldENvbmVzKSkge1xuICAgICAgY29uZXNbYHN1YnNldDoke3N1YnNldEtleX1gXSA9IGNvbmU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbmVzO1xuICB9XG5cbiAgLyoqXG4gICAqIOyDneyEseuQnCBjb25l65Ok7J2EIEVudGl0eeyXkCDsoIHsmqntlanri4jri6QuXG4gICAqXG4gICAqIEBwYXJhbSByZXN1bHQgLSBMTE3snLzroZwg7IOd7ISx65CcIGNvbmUg6rKw6rO8XG4gICAqL1xuICBwcml2YXRlIGFwcGx5Q29uZXMocmVzdWx0OiBpbXBvcnQoXCIuLi9jb25lL2NvbmUtZ2VuZXJhdG9yXCIpLkNvbmVHZW5lcmF0aW9uUmVzdWx0KTogdm9pZCB7XG4gICAgaWYgKHJlc3VsdC5lbnRpdHlDb25lKSB7XG4gICAgICB0aGlzLmNvbmUgPSByZXN1bHQuZW50aXR5Q29uZTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IFtwcm9wTmFtZSwgY29uZV0gb2YgT2JqZWN0LmVudHJpZXMocmVzdWx0LnByb3BDb25lcykpIHtcbiAgICAgIGNvbnN0IHByb3AgPSB0aGlzLnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gcHJvcE5hbWUpO1xuICAgICAgaWYgKHByb3ApIHtcbiAgICAgICAgKHByb3AgYXMgeyBjb25lPzogQ29uZSB9KS5jb25lID0gY29uZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmVudW1Db25lcyA9IHsgLi4udGhpcy5lbnVtQ29uZXMsIC4uLnJlc3VsdC5lbnVtQ29uZXMgfTtcbiAgICB0aGlzLnN1YnNldENvbmVzID0geyAuLi50aGlzLnN1YnNldENvbmVzLCAuLi5yZXN1bHQuc3Vic2V0Q29uZXMgfTtcbiAgfVxuXG4gIGdldFN1YnNldFJvd3MoXG4gICAgX3N1YnNldHM/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZ1tdIH0sXG4gICAgX3N1YnNldHNJbnRlcm5hbD86IHsgW2tleTogc3RyaW5nXTogc3RyaW5nW10gfSxcbiAgICBwcmVmaXhlczogc3RyaW5nW10gPSBbXSxcbiAgKTogRW50aXR5U3Vic2V0Um93W10ge1xuICAgIGlmIChwcmVmaXhlcy5sZW5ndGggPiAxMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGNvbnN0IHN1YnNldHMgPSBfc3Vic2V0cyA/PyB0aGlzLnN1YnNldHM7XG4gICAgY29uc3Qgc3Vic2V0c0ludGVybmFsID0gX3N1YnNldHNJbnRlcm5hbCA/PyB0aGlzLnN1YnNldHNJbnRlcm5hbDtcbiAgICBjb25zdCBzdWJzZXRLZXlzID0gT2JqZWN0LmtleXMoc3Vic2V0cyk7XG4gICAgY29uc3QgYWxsRmllbGRzID0gdW5pcXVlKHN1YnNldEtleXMuZmxhdE1hcCgoa2V5KSA9PiBzdWJzZXRzW2tleV0pKTtcbiAgICAvLyBpbnRlcm5hbCDtlYTrk5zrj4QgYWxsRmllbGRz7JeQIO2PrO2VqCAocmVsYXRpb24g7YOQ7IOJ7JqpKVxuICAgIGNvbnN0IGFsbEludGVybmFsRmllbGRzID0gdW5pcXVlKHN1YnNldEtleXMuZmxhdE1hcCgoa2V5KSA9PiBzdWJzZXRzSW50ZXJuYWxba2V5XSA/PyBbXSkpO1xuICAgIGNvbnN0IGNvbWJpbmVkRmllbGRzID0gdW5pcXVlKFsuLi5hbGxGaWVsZHMsIC4uLmFsbEludGVybmFsRmllbGRzXSk7XG5cbiAgICByZXR1cm4gdGhpcy5wcm9wcy5tYXAoKHByb3ApID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgcHJvcC50eXBlID09PSBcInJlbGF0aW9uXCIgJiZcbiAgICAgICAgY29tYmluZWRGaWVsZHMuZmluZCgoZikgPT4gZi5zdGFydHNXaXRoKGAke1suLi5wcmVmaXhlcywgcHJvcC5uYW1lXS5qb2luKFwiLlwiKX0uYCkpXG4gICAgICApIHtcbiAgICAgICAgY29uc3QgcmVsRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocHJvcC53aXRoKTtcbiAgICAgICAgY29uc3QgY2hpbGRyZW4gPSByZWxFbnRpdHkuZ2V0U3Vic2V0Um93cyhzdWJzZXRzLCBzdWJzZXRzSW50ZXJuYWwsIFtcbiAgICAgICAgICAuLi5wcmVmaXhlcyxcbiAgICAgICAgICBgJHtwcm9wLm5hbWV9YCxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBmaWVsZDogcHJvcC5uYW1lLFxuICAgICAgICAgIGNoaWxkcmVuLFxuICAgICAgICAgIHJlbGF0aW9uRW50aXR5OiBwcm9wLndpdGgsXG4gICAgICAgICAgcHJlZml4ZXMsXG4gICAgICAgICAgaXNPcGVuOiBjaGlsZHJlbi5sZW5ndGggPiAwLFxuICAgICAgICAgIGhhczogT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgICAgc3Vic2V0S2V5cy5tYXAoKHN1YnNldEtleSkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gW3N1YnNldEtleSwgY2hpbGRyZW4uZXZlcnkoKGNoaWxkKSA9PiBjaGlsZC5oYXNbc3Vic2V0S2V5XSldO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKSxcbiAgICAgICAgICBpc0ludGVybmFsOiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgICAgICBzdWJzZXRLZXlzLm1hcCgoc3Vic2V0S2V5KSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBbc3Vic2V0S2V5LCBjaGlsZHJlbi5ldmVyeSgoY2hpbGQpID0+IGNoaWxkLmlzSW50ZXJuYWxbc3Vic2V0S2V5XSldO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKSxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZmllbGQgPSBbLi4ucHJlZml4ZXMsIHByb3AubmFtZV0uam9pbihcIi5cIik7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBmaWVsZDogcHJvcC5uYW1lLFxuICAgICAgICBjaGlsZHJlbjogW10sXG4gICAgICAgIHJlbGF0aW9uRW50aXR5OiBwcm9wLnR5cGUgPT09IFwicmVsYXRpb25cIiA/IHByb3Aud2l0aCA6IHVuZGVmaW5lZCxcbiAgICAgICAgcHJlZml4ZXMsXG4gICAgICAgIGhhczogT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgIHN1YnNldEtleXMubWFwKChzdWJzZXRLZXkpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN1YnNldEZpZWxkcyA9IHN1YnNldHNbc3Vic2V0S2V5XTtcbiAgICAgICAgICAgIGNvbnN0IGhhcyA9IHN1YnNldEZpZWxkcy5zb21lKChmKSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBmID09PSBmaWVsZCB8fCBmLnN0YXJ0c1dpdGgoYCR7ZmllbGR9LmApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gW3N1YnNldEtleSwgaGFzXTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKSxcbiAgICAgICAgaXNJbnRlcm5hbDogT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgIHN1YnNldEtleXMubWFwKChzdWJzZXRLZXkpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGludGVybmFsRmllbGRzID0gc3Vic2V0c0ludGVybmFsW3N1YnNldEtleV0gPz8gW107XG4gICAgICAgICAgICBjb25zdCBpc0ludGVybmFsID0gaW50ZXJuYWxGaWVsZHMuc29tZSgoZikgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gZiA9PT0gZmllbGQgfHwgZi5zdGFydHNXaXRoKGAke2ZpZWxkfS5gKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIFtzdWJzZXRLZXksIGlzSW50ZXJuYWxdO1xuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIHN1YnNldFJvd3NUb1N1YnNldEZpZWxkcyhcbiAgICBzdWJzZXRSb3dzOiBFbnRpdHlTdWJzZXRSb3dbXSxcbiAgICBzdWJzZXRLZXk6IHN0cmluZyxcbiAgICBpbnRlcm5hbDogYm9vbGVhbiA9IGZhbHNlLFxuICApOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgaGFzS2V5ID0gaW50ZXJuYWwgPyBcImlzSW50ZXJuYWxcIiA6IFwiaGFzXCI7XG4gICAgcmV0dXJuIHN1YnNldFJvd3NcbiAgICAgIC5tYXAoKHN1YnNldFJvdykgPT4ge1xuICAgICAgICBpZiAoc3Vic2V0Um93LmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5zdWJzZXRSb3dzVG9TdWJzZXRGaWVsZHMoc3Vic2V0Um93LmNoaWxkcmVuLCBzdWJzZXRLZXksIGludGVybmFsKTtcbiAgICAgICAgfSBlbHNlIGlmIChzdWJzZXRSb3dbaGFzS2V5XVtzdWJzZXRLZXldKSB7XG4gICAgICAgICAgcmV0dXJuIHN1YnNldFJvdy5wcmVmaXhlcy5jb25jYXQoc3Vic2V0Um93LmZpZWxkKS5qb2luKFwiLlwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIC5maWx0ZXIobm9uTnVsbGFibGUpXG4gICAgICAuZmxhdCgpO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlUHJvcChwcm9wOiBFbnRpdHlQcm9wLCBhdD86IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghYXQpIHtcbiAgICAgIHRoaXMucHJvcHMucHVzaChwcm9wKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wcm9wcy5zcGxpY2UoYXQsIDAsIHByb3ApO1xuICAgIH1cbiAgICBhd2FpdCB0aGlzLnNhdmUoKTtcbiAgfVxuXG4gIGFuYWx5emVTdWJzZXRGaWVsZChzdWJzZXRGaWVsZDogc3RyaW5nKToge1xuICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgcHJvcE5hbWU6IHN0cmluZztcbiAgfVtdIHtcbiAgICBjb25zdCBhcnIgPSBzdWJzZXRGaWVsZC5zcGxpdChcIi5cIik7XG5cbiAgICBsZXQgZW50aXR5SWQgPSB0aGlzLmlkO1xuICAgIGNvbnN0IHJlc3VsdDoge1xuICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgIHByb3BOYW1lOiBzdHJpbmc7XG4gICAgfVtdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHByb3BOYW1lID0gYXJyW2ldO1xuICAgICAgcmVzdWx0LnB1c2goe1xuICAgICAgICBlbnRpdHlJZCxcbiAgICAgICAgcHJvcE5hbWUsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcHJvcCA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKS5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IHByb3BOYW1lKTtcbiAgICAgIGlmICghcHJvcCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZW50aXR5SWR97J2YIOyemOuqu+uQnCDshJzruIzshYvtgqQgJHtzdWJzZXRGaWVsZH1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChpc1JlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICBlbnRpdHlJZCA9IHByb3Aud2l0aDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGFzeW5jIG1vZGlmeVByb3AobmV3UHJvcDogRW50aXR5UHJvcCwgYXQ6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIOydtOyghCDtlITroa0g7J2066aEIOyggOyepVxuICAgIGNvbnN0IG9sZE5hbWUgPSB0aGlzLnByb3BzW2F0XS5uYW1lO1xuXG4gICAgLy8g7KCA7J6l7ZWgIOyXlO2LsO2LsFxuICAgIGNvbnN0IGVudGl0aWVzOiBFbnRpdHlbXSA9IFt0aGlzXTtcblxuICAgIC8vIOydtOumhOydtCDrsJTrgJAg6rK97JqwXG4gICAgaWYgKG9sZE5hbWUgIT09IG5ld1Byb3AubmFtZSkge1xuICAgICAgLy8g7KCE7LK0IOyXlO2LsO2LsOyXkOyEnCDtmITsnqwg7IiY7KCV65CcIO2UhOuhreydhCDssLjsobDtlZjqs6Ag7J6I64qUIOuqqOuToCDshJzruIzshYvtlYTrk5wg7LC+7JWE7IScIOyImOyglVxuICAgICAgY29uc3QgYWxsRW50aXR5SWRzID0gRW50aXR5TWFuYWdlci5nZXRBbGxJZHMoKTtcbiAgICAgIGZvciAoY29uc3QgcmVsRW50aXR5SWQgb2YgYWxsRW50aXR5SWRzKSB7XG4gICAgICAgIGNvbnN0IHJlbEVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KHJlbEVudGl0eUlkKTtcbiAgICAgICAgY29uc3QgcmVsRW50aXR5U3Vic2V0S2V5cyA9IE9iamVjdC5rZXlzKHJlbEVudGl0eS5zdWJzZXRzKTtcbiAgICAgICAgZm9yIChjb25zdCBzdWJzZXRLZXkgb2YgcmVsRW50aXR5U3Vic2V0S2V5cykge1xuICAgICAgICAgIGNvbnN0IHN1YnNldCA9IHJlbEVudGl0eS5zdWJzZXRzW3N1YnNldEtleV07XG5cbiAgICAgICAgICAvLyDshJzruIzshYsg7ZWE65Oc66W8IOyInO2ajO2VmOupsCwg7JeU7Yuw7YuwLe2UhOuhrSDri6jsnITroZwg67aE7ISd7ZWcIO2bhCDtmITsnqwg7JeU7Yuw7YuwLe2UhOuhreqzvCDsnbzsuZjtlZjripQg6rK97JqwIOyImOyglSDsspjrpqxcbiAgICAgICAgICBjb25zdCBtb2RpZmllZFN1YnNldEZpZWxkcyA9IHN1YnNldC5tYXAoKHN1YnNldEZpZWxkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbmFseXplZCA9IHJlbEVudGl0eS5hbmFseXplU3Vic2V0RmllbGQoc3Vic2V0RmllbGQpO1xuICAgICAgICAgICAgY29uc3QgbW9kaWZpZWQgPSBhbmFseXplZC5tYXAoKGEpID0+XG4gICAgICAgICAgICAgIGEucHJvcE5hbWUgPT09IG9sZE5hbWUgJiYgYS5lbnRpdHlJZCA9PT0gdGhpcy5pZFxuICAgICAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgICAgICAuLi5hLFxuICAgICAgICAgICAgICAgICAgICBwcm9wTmFtZTogbmV3UHJvcC5uYW1lLFxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDogYSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICAvLyDrtoTshJ3tlZwg7ZWE65Oc66W8IOuLpOyLnCDshJzruIzshYsg7ZWE65Oc66GcIOuzteq1rFxuICAgICAgICAgICAgcmV0dXJuIG1vZGlmaWVkLm1hcCgoYSkgPT4gYS5wcm9wTmFtZSkuam9pbihcIi5cIik7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAoc3Vic2V0LmpvaW4oXCIsXCIpICE9PSBtb2RpZmllZFN1YnNldEZpZWxkcy5qb2luKFwiLFwiKSkge1xuICAgICAgICAgICAgcmVsRW50aXR5LnN1YnNldHNbc3Vic2V0S2V5XSA9IG1vZGlmaWVkU3Vic2V0RmllbGRzO1xuICAgICAgICAgICAgZW50aXRpZXMucHVzaChyZWxFbnRpdHkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIO2UhOuhrSDsiJjsoJVcbiAgICB0aGlzLnByb3BzW2F0XSA9IG5ld1Byb3A7XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbChlbnRpdGllcy5tYXAoYXN5bmMgKGVudGl0eSkgPT4gZW50aXR5LnNhdmUoKSkpO1xuICB9XG5cbiAgYXN5bmMgZGVsUHJvcChhdDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8g7J207KCEIO2UhOuhrSDsnbTrpoQg7KCA7J6lXG4gICAgY29uc3Qgb2xkTmFtZSA9IHRoaXMucHJvcHNbYXRdLm5hbWU7XG5cbiAgICAvLyDsoIDsnqXtlaAg7JeU7Yuw7YuwXG4gICAgY29uc3QgZW50aXRpZXM6IEVudGl0eVtdID0gW3RoaXNdO1xuXG4gICAgLy8g7KCE7LK0IOyXlO2LsO2LsOyXkOyEnCDtmITsnqwg7IKt7KCc65CcIO2UhOuhreydhCDssLjsobDtlZjqs6Ag7J6I64qUIOuqqOuToCDshJzruIzshYvtlYTrk5wg7LC+7JWE7IScIOygnOyZuFxuICAgIGNvbnN0IGFsbEVudGl0eUlkcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCk7XG4gICAgZm9yIChjb25zdCByZWxFbnRpdHlJZCBvZiBhbGxFbnRpdHlJZHMpIHtcbiAgICAgIGNvbnN0IHJlbEVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KHJlbEVudGl0eUlkKTtcbiAgICAgIGNvbnN0IHJlbEVudGl0eVN1YnNldEtleXMgPSBPYmplY3Qua2V5cyhyZWxFbnRpdHkuc3Vic2V0cyk7XG4gICAgICBmb3IgKGNvbnN0IHN1YnNldEtleSBvZiByZWxFbnRpdHlTdWJzZXRLZXlzKSB7XG4gICAgICAgIGNvbnN0IHN1YnNldCA9IHJlbEVudGl0eS5zdWJzZXRzW3N1YnNldEtleV07XG4gICAgICAgIC8vIOyEnOu4jOyFiyDtlYTrk5zrpbwg7Iic7ZqM7ZWY66mwLCDsl5Tti7Dti7At7ZSE66GtIOuLqOychOuhnCDrtoTshJ3tlZwg7ZuEIO2YhOyerCDsl5Tti7Dti7At7ZSE66Gt6rO8IOydvOy5mO2VmOuKlCDqsr3smrAg7J207ZuE7J2YIO2VhOuTnOulvCDsoJzsmbhcbiAgICAgICAgY29uc3QgbW9kaWZpZWRTdWJzZXRGaWVsZHMgPSBzdWJzZXRcbiAgICAgICAgICAubWFwKChzdWJzZXRGaWVsZCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYW5hbHl6ZWQgPSByZWxFbnRpdHkuYW5hbHl6ZVN1YnNldEZpZWxkKHN1YnNldEZpZWxkKTtcbiAgICAgICAgICAgIGlmIChhbmFseXplZC5maW5kKChhKSA9PiBhLnByb3BOYW1lID09PSBvbGROYW1lICYmIGEuZW50aXR5SWQgPT09IHRoaXMuaWQpKSB7XG4gICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHN1YnNldEZpZWxkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG4gICAgICAgICAgLmZpbHRlcihub25OdWxsYWJsZSk7XG5cbiAgICAgICAgaWYgKHN1YnNldC5qb2luKFwiLFwiKSAhPT0gbW9kaWZpZWRTdWJzZXRGaWVsZHMuam9pbihcIixcIikpIHtcbiAgICAgICAgICByZWxFbnRpdHkuc3Vic2V0c1tzdWJzZXRLZXldID0gbW9kaWZpZWRTdWJzZXRGaWVsZHM7XG4gICAgICAgICAgZW50aXRpZXMucHVzaChyZWxFbnRpdHkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8g7ZiE7J6sIOyXlO2LsO2LsOydmCDsnbjrjbHsiqTsl5DshJwg7KCc7Jm4XG4gICAgZm9yIChjb25zdCBpbmRleCBvZiBFbnRpdHlNYW5hZ2VyLmdldCh0aGlzLmlkKS5pbmRleGVzKSB7XG4gICAgICBpbmRleC5jb2x1bW5zID0gaW5kZXguY29sdW1ucy5maWx0ZXIoKGNvbCkgPT4gY29sLm5hbWUgIT09IG9sZE5hbWUpO1xuICAgIH1cblxuICAgIC8vIO2UhOuhrSDsgq3soJxcbiAgICB0aGlzLnByb3BzLnNwbGljZShhdCwgMSk7XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbChlbnRpdGllcy5tYXAoYXN5bmMgKGVudGl0eSkgPT4gZW50aXR5LnNhdmUoKSkpO1xuICB9XG5cbiAgZ2V0RW50aXR5SWRGcm9tU3Vic2V0RmllbGQoc3Vic2V0RmllbGQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCFzdWJzZXRGaWVsZC5pbmNsdWRlcyhcIi5cIikpIHtcbiAgICAgIHJldHVybiB0aGlzLmlkO1xuICAgIH1cblxuICAgIC8vIOyEnOu4jOyFiyDtlYTrk5zsnZgg66eI7KeA66eJ7J2AIO2UhOuhreydtOuvgOuhnCDsoJzsmbhcbiAgICBjb25zdCBhcnIgPSBzdWJzZXRGaWVsZC5zcGxpdChcIi5cIikuc2xpY2UoMCwgLTEpO1xuXG4gICAgLy8g7ISc67iM7IWLIO2VhOuTnOulvCDrgrTroKTqsIDrqbTshJwg66eI7KeA66eJ7Jy866GcIHJlbGF0aW9u65CcIOyXlO2LsO2LsOulvCDssL7snYxcbiAgICBjb25zdCBsYXN0RW50aXR5SWQgPSBhcnIucmVkdWNlKChlbnRpdHlJZCwgZmllbGQpID0+IHtcbiAgICAgIGNvbnN0IHJlbFByb3AgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCkucHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBmaWVsZCk7XG4gICAgICBpZiAoIXJlbFByb3AgfHwgcmVsUHJvcC50eXBlICE9PSBcInJlbGF0aW9uXCIpIHtcbiAgICAgICAgY29uc29sZS5kZWJ1Zyh7IGFyciwgdGhpc0lkOiB0aGlzLmlkLCBlbnRpdHlJZCwgZmllbGQgfSk7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihg7J6Y66q765CcIOyEnOu4jOyFi+2CpCAke3N1YnNldEZpZWxkfWApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlbFByb3Aud2l0aDtcbiAgICB9LCB0aGlzLmlkKTtcbiAgICByZXR1cm4gbGFzdEVudGl0eUlkO1xuICB9XG5cbiAgYXN5bmMgbW92ZVByb3AoYXQ6IG51bWJlciwgdG86IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHByb3AgPSB0aGlzLnByb3BzW2F0XTtcbiAgICBjb25zdCBuZXdQcm9wcyA9IFsuLi50aGlzLnByb3BzXTtcbiAgICBuZXdQcm9wcy5zcGxpY2UodG8sIDAsIHByb3ApO1xuICAgIG5ld1Byb3BzLnNwbGljZShhdCA8IHRvID8gYXQgOiBhdCArIDEsIDEpO1xuICAgIHRoaXMucHJvcHMgPSBuZXdQcm9wcztcblxuICAgIGF3YWl0IHRoaXMuc2F2ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VhOuTnOuqheydhCBcIu2FjOydtOu4lOuqhS7tlYTrk5zrqoVcIiDtmJXsi53snLzroZwg67OA7ZmYXG4gICAqL1xuICBnZXRGdWxsRmllbGROYW1lKGZpZWxkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmIChmaWVsZC5pbmNsdWRlcyhcIi5cIikpIHtcbiAgICAgIHJldHVybiBmaWVsZDtcbiAgICB9XG4gICAgcmV0dXJuIGAke3RoaXMudGFibGV9LiR7ZmllbGR9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiDsl5Tti7Dti7DsnZggUEsg7YOA7J6F7J2EIOuwmO2ZmO2VqeuLiOuLpC5cbiAgICogaWQg7ZWE65Oc7J2YIO2DgOyeheydhCDquLDspIDsnLzroZwgXCJpbnRlZ2VyXCIgfCBcInN0cmluZ1wiIHwgXCJ1dWlkXCLrpbwg67CY7ZmY7ZWp64uI64ukLlxuICAgKi9cbiAgZ2V0UGtUeXBlKCk6IFwiaW50ZWdlclwiIHwgXCJzdHJpbmdcIiB8IFwidXVpZFwiIHtcbiAgICBjb25zdCBpZFByb3AgPSB0aGlzLnByb3BzRGljdC5pZDtcbiAgICBpZiAoIWlkUHJvcCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFbnRpdHkgJHt0aGlzLmlkfeyXkCBpZCDtlYTrk5zqsIAg7JeG7Iq164uI64ukYCk7XG4gICAgfVxuICAgIGlmIChpZFByb3AudHlwZSA9PT0gXCJzdHJpbmdcIiB8fCBpZFByb3AudHlwZSA9PT0gXCJ1dWlkXCIpIHtcbiAgICAgIHJldHVybiBpZFByb3AudHlwZTtcbiAgICB9XG4gICAgcmV0dXJuIFwiaW50ZWdlclwiO1xuICB9XG5cbiAgLyoqXG4gICAqIOyXlO2LsO2LsOydmCBQSyBwcm9w7J2EIOuwmO2ZmO2VqeuLiOuLpC5cbiAgICogbGVuZ3RoIOuTsSDshLjrtoAg7KCV67O07JeQIOygkeq3vO2VoCDrlYwg7IKs7Jqp7ZWp64uI64ukLlxuICAgKi9cbiAgZ2V0UGtQcm9wKCk6IEVudGl0eVByb3Age1xuICAgIGNvbnN0IGlkUHJvcCA9IHRoaXMucHJvcHNEaWN0LmlkO1xuICAgIGlmICghaWRQcm9wKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEVudGl0eSAke3RoaXMuaWR97JeQIGlkIO2VhOuTnOqwgCDsl4bsirXri4jri6RgKTtcbiAgICB9XG4gICAgcmV0dXJuIGlkUHJvcDtcbiAgfVxuXG4gIC8qKlxuICAgKiDsl5Tti7Dti7DsnZggUEsg67Cw7Je0IO2DgOyeheydhCDrsJjtmZjtlanri4jri6QuXG4gICAqIExvYWRlclF1ZXJ57J2YIGZyb21JZHMg7YOA7J6F7Jy866GcIOyCrOyaqeuQqeuLiOuLpC5cbiAgICovXG4gIGdldFBrQXJyYXlUeXBlKCk6IHN0cmluZyB7XG4gICAgY29uc3QgcGtUeXBlID0gdGhpcy5nZXRQa1R5cGUoKTtcbiAgICByZXR1cm4gcGtUeXBlID09PSBcImludGVnZXJcIiA/IFwibnVtYmVyW11cIiA6IFwic3RyaW5nW11cIjtcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7YUFRc0M7WUFjZjtnQkFZMkI7Z0JBQ0g7ZUFDTDtpQkFDTztZQUNVO3FCQUNYO0NBRW5DLFNBQWIsTUFBb0I7RUFDbEI7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBS0E7RUFDQTtFQUdBO0VBR0E7RUFDQTtFQUdB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