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 { createKnexInstance, init_knex } from "../database/knex.js";
3
3
  import { init_controller, isTest } from "../utils/controller.js";
4
4
  import { Sonamu, init_sonamu } from "../api/sonamu.js";
@@ -10,11 +10,10 @@ import { RelationGraph, init__relation_graph } from "./_relation-graph.js";
10
10
  import inflection from "inflection";
11
11
  import { unique } from "radashi";
12
12
  import assert from "assert";
13
+ import { readFileSync, writeFileSync } from "fs";
13
14
  import chalk from "chalk";
14
15
  import { execSync } from "child_process";
15
- import { readFileSync, writeFileSync } from "fs";
16
16
  import { inspect } from "util";
17
-
18
17
  //#region src/testing/fixture-manager.ts
19
18
  var FixtureManagerClass, FixtureManager;
20
19
  var init_fixture_manager = __esmMin((() => {
@@ -32,9 +31,7 @@ var init_fixture_manager = __esmMin((() => {
32
31
  this._tdb = tdb;
33
32
  }
34
33
  get tdb() {
35
- if (this._tdb === null) {
36
- throw new Error("FixtureManager has not been initialized");
37
- }
34
+ if (this._tdb === null) throw new Error("FixtureManager has not been initialized");
38
35
  return this._tdb;
39
36
  }
40
37
  _fdb = null;
@@ -42,26 +39,20 @@ var init_fixture_manager = __esmMin((() => {
42
39
  this._fdb = fdb;
43
40
  }
44
41
  get fdb() {
45
- if (this._fdb === null) {
46
- throw new Error("FixtureManager has not been initialized");
47
- }
42
+ if (this._fdb === null) throw new Error("FixtureManager has not been initialized");
48
43
  return this._fdb;
49
44
  }
50
45
  cachedTableNames = null;
51
46
  relationGraph = new RelationGraph();
52
47
  builder = new UpsertBuilder();
53
- fixtureRefMap = new Map();
54
- skippedFixtures = new Map();
48
+ fixtureRefMap = /* @__PURE__ */ new Map();
49
+ skippedFixtures = /* @__PURE__ */ new Map();
55
50
  init() {
56
- if (this._tdb !== null) {
57
- return;
58
- }
59
- if (Sonamu.dbConfig.test && Sonamu.dbConfig.production_master) {
51
+ if (this._tdb !== null) return;
52
+ if (Sonamu.dbConfig.test && Sonamu.dbConfig.production) {
60
53
  const tConn = Sonamu.dbConfig.test.connection;
61
- const pConn = Sonamu.dbConfig.production_master.connection;
62
- if (`${tConn.host ?? "localhost"}:${tConn.port ?? 5432}/${tConn.database}` === `${pConn.host ?? "localhost"}:${pConn.port ?? 5432}/${pConn.database}`) {
63
- throw new Error(`테스트DB와 프로덕션DB에 동일한 데이터베이스가 사용되었습니다.`);
64
- }
54
+ const pConn = Sonamu.dbConfig.production.connection;
55
+ if (`${tConn.host ?? "localhost"}:${tConn.port ?? 5432}/${tConn.database}` === `${pConn.host ?? "localhost"}:${pConn.port ?? 5432}/${pConn.database}`) throw new Error(`테스트DB와 프로덕션DB에 동일한 데이터베이스가 사용되었습니다.`);
65
56
  }
66
57
  this.tdb = createKnexInstance(Sonamu.dbConfig.test);
67
58
  this.fdb = createKnexInstance(Sonamu.dbConfig.fixture);
@@ -125,8 +116,7 @@ var init_fixture_manager = __esmMin((() => {
125
116
  const tableName = entity.table || entity.id.toLowerCase();
126
117
  const idProp = entity.props.find((p) => p.name === "id");
127
118
  const idType = idProp?.type;
128
- const usesSequence = idType === "integer" || idType === "bigInteger" || idProp?.cone?.fixtureStrategy === "sequence";
129
- if (!usesSequence) {
119
+ if (!(idType === "integer" || idType === "bigInteger" || idProp?.cone?.fixtureStrategy === "sequence")) {
130
120
  !isTest() && console.log(`Skipping sequence reset for ${tableName} (id type: ${idType || "unknown"})`);
131
121
  continue;
132
122
  }
@@ -142,57 +132,47 @@ var init_fixture_manager = __esmMin((() => {
142
132
  await testDb.destroy();
143
133
  }
144
134
  }
145
- visitedRecords = new Set();
135
+ visitedRecords = /* @__PURE__ */ new Set();
146
136
  async importFixture(entityId, ids) {
147
137
  this.visitedRecords.clear();
148
138
  const queries = unique((await Promise.all(ids.map(async (id) => {
149
139
  return await this.getImportQueries(entityId, "id", id);
150
140
  }))).flat());
151
141
  const wdb = BaseModel.getDB("w");
152
- for (const query of queries) {
153
- await wdb.raw(query);
154
- }
142
+ for (const query of queries) await wdb.raw(query);
155
143
  }
156
144
  async getImportQueries(entityId, field, id) {
157
145
  const recordKey = `${entityId}#${field}#${id}`;
158
- if (this.visitedRecords.has(recordKey)) {
159
- return [];
160
- }
146
+ if (this.visitedRecords.has(recordKey)) return [];
161
147
  this.visitedRecords.add(recordKey);
162
148
  const entity = EntityManager.get(entityId);
163
- const wdb = BaseModel.getDB("w");
164
- const [row] = await wdb(entity.table).where(field, id).limit(1);
165
- if (row === undefined) {
166
- throw new Error(`${entityId}#${id} row를 찾을 수 없습니다.`);
167
- }
149
+ const [row] = await BaseModel.getDB("w")(entity.table).where(field, id).limit(1);
150
+ if (row === void 0) throw new Error(`${entityId}#${id} row를 찾을 수 없습니다.`);
168
151
  const fixtureDatabase = Sonamu.dbConfig.fixture.connection.database;
169
- const realDatabase = Sonamu.dbConfig.production_master.connection.database;
152
+ const realDatabase = Sonamu.dbConfig.production.connection.database;
170
153
  const selfQuery = `INSERT IGNORE INTO \`${fixtureDatabase}\`.\`${entity.table}\` (SELECT * FROM \`${realDatabase}\`.\`${entity.table}\` WHERE \`id\` = ${id})`;
171
- const args = Object.entries(entity.relations).filter(([, relation]) => isBelongsToOneRelationProp(relation) || isOneToOneRelationProp(relation) && relation.customJoinClause === undefined).map(([, relation]) => {
172
- let field$1;
173
- let id$1;
154
+ const args = Object.entries(entity.relations).filter(([, relation]) => isBelongsToOneRelationProp(relation) || isOneToOneRelationProp(relation) && relation.customJoinClause === void 0).map(([, relation]) => {
155
+ let field;
156
+ let id;
174
157
  if (isOneToOneRelationProp(relation) && !relation.hasJoinColumn) {
175
158
  const relatedEntity = EntityManager.get(relation.with);
176
159
  const relatedIdColumnName = relatedEntity.props.find((p) => isRelationProp(p) && p.with === entity.id)?.name;
177
- if (!relatedIdColumnName) {
178
- throw new Error(`${relatedEntity.id}의 ${entity.id} 관계 프롭을 찾을 수 없습니다.`);
179
- }
180
- field$1 = `${relatedIdColumnName}_id`;
181
- id$1 = row.id;
160
+ if (!relatedIdColumnName) throw new Error(`${relatedEntity.id}의 ${entity.id} 관계 프롭을 찾을 수 없습니다.`);
161
+ field = `${relatedIdColumnName}_id`;
162
+ id = row.id;
182
163
  } else {
183
- field$1 = "id";
184
- id$1 = row[`${relation.name}_id`];
164
+ field = "id";
165
+ id = row[`${relation.name}_id`];
185
166
  }
186
167
  return {
187
168
  entityId: relation.with,
188
- field: field$1,
189
- id: id$1
169
+ field,
170
+ id
190
171
  };
191
172
  }).filter((arg) => arg.id !== null);
192
- const relQueries = await Promise.all(args.map(async (args$1) => {
193
- return this.getImportQueries(args$1.entityId, args$1.field, args$1.id);
194
- }));
195
- return [...unique(relQueries.toReversed().flat()), selfQuery];
173
+ return [...unique((await Promise.all(args.map(async (args) => {
174
+ return this.getImportQueries(args.entityId, args.field, args.id);
175
+ }))).toReversed().flat()), selfQuery];
196
176
  }
197
177
  async destroy() {
198
178
  if (this._tdb) {
@@ -213,41 +193,34 @@ var init_fixture_manager = __esmMin((() => {
213
193
  const entity = EntityManager.get(entityId);
214
194
  const column = entity.props.find((prop) => prop.name === field)?.type === "relation" ? `${field}_id` : field;
215
195
  let query = sourceDB(entity.table);
216
- if (searchType === "equals") {
217
- query = query.where(column, value);
218
- } else if (searchType === "like") {
219
- query = query.where(column, "like", `%${value}%`);
220
- }
196
+ if (searchType === "equals") query = query.where(column, value);
197
+ else if (searchType === "like") query = query.where(column, "like", `%${value}%`);
221
198
  const rows = await query;
222
- if (rows.length === 0) {
223
- throw new Error("No records found");
224
- }
199
+ if (rows.length === 0) throw new Error("No records found");
225
200
  const fixtures = [];
226
201
  for (const row of rows) {
227
202
  const initialRecordsLength = fixtures.length;
228
203
  const newRecords = await this.createFixtureRecord(entity, row, { _db: sourceDB });
229
204
  fixtures.push(...newRecords);
230
205
  const currentFixtureRecord = fixtures.find((r) => r.fixtureId === `${entityId}#${row.id}`);
231
- if (currentFixtureRecord) {
232
- currentFixtureRecord.fetchedRecords = fixtures.filter((r) => r.fixtureId !== currentFixtureRecord.fixtureId).slice(initialRecordsLength).map((r) => r.fixtureId);
233
- }
206
+ if (currentFixtureRecord) currentFixtureRecord.fetchedRecords = fixtures.filter((r) => r.fixtureId !== currentFixtureRecord.fixtureId).slice(initialRecordsLength).map((r) => r.fixtureId);
234
207
  }
235
208
  for (const fixture of fixtures) {
236
- const entity$1 = EntityManager.get(fixture.entityId);
209
+ const entity = EntityManager.get(fixture.entityId);
237
210
  const customColumns = duplicateCheck?.columns?.[fixture.entityId];
238
211
  if (customColumns && customColumns.length > 0) {
239
- const customDuplicateRow = await this.checkDuplicateByColumns(targetDB, entity$1, fixture, customColumns);
212
+ const customDuplicateRow = await this.checkDuplicateByColumns(targetDB, entity, fixture, customColumns);
240
213
  if (customDuplicateRow) {
241
- const [record] = await this.createFixtureRecord(entity$1, customDuplicateRow, {
214
+ const [record] = await this.createFixtureRecord(entity, customDuplicateRow, {
242
215
  singleRecord: true,
243
216
  _db: targetDB
244
217
  });
245
218
  fixture.target = record;
246
219
  }
247
220
  }
248
- const uniqueRow = await this.checkUniqueViolation(targetDB, entity$1, fixture);
221
+ const uniqueRow = await this.checkUniqueViolation(targetDB, entity, fixture);
249
222
  if (uniqueRow) {
250
- const [record] = await this.createFixtureRecord(entity$1, uniqueRow, {
223
+ const [record] = await this.createFixtureRecord(entity, uniqueRow, {
251
224
  singleRecord: true,
252
225
  _db: targetDB
253
226
  });
@@ -261,61 +234,52 @@ var init_fixture_manager = __esmMin((() => {
261
234
  }
262
235
  async createFixtureRecord(entity, row, options) {
263
236
  const records = [];
264
- const visitedEntities = new Set();
265
- const create = async (entity$1, row$1) => {
266
- const fixtureId = `${entity$1.id}#${row$1.id}`;
267
- if (visitedEntities.has(fixtureId)) {
268
- return;
269
- }
237
+ const visitedEntities = /* @__PURE__ */ new Set();
238
+ const create = async (entity, row) => {
239
+ const fixtureId = `${entity.id}#${row.id}`;
240
+ if (visitedEntities.has(fixtureId)) return;
270
241
  visitedEntities.add(fixtureId);
271
242
  const record = {
272
243
  fixtureId,
273
- entityId: entity$1.id,
274
- id: row$1.id,
244
+ entityId: entity.id,
245
+ id: row.id,
275
246
  columns: {},
276
247
  fetchedRecords: [],
277
248
  belongsRecords: []
278
249
  };
279
- for (const prop of entity$1.props) {
280
- if (isVirtualProp(prop)) {
281
- continue;
282
- }
250
+ for (const prop of entity.props) {
251
+ if (isVirtualProp(prop)) continue;
283
252
  record.columns[prop.name] = {
284
253
  prop,
285
- value: row$1[prop.name]
254
+ value: row[prop.name]
286
255
  };
287
256
  const db = options?._db ?? BaseModel.getDB("w");
288
257
  if (isManyToManyRelationProp(prop)) {
289
258
  const relatedEntity = EntityManager.get(prop.with);
290
259
  const throughTable = prop.joinTable;
291
- const fromColumn = `${inflection.singularize(entity$1.table)}_id`;
260
+ const fromColumn = `${inflection.singularize(entity.table)}_id`;
292
261
  const toColumn = `${inflection.singularize(relatedEntity.table)}_id`;
293
- const relatedIds = await db(throughTable).where(fromColumn, row$1.id).pluck(toColumn);
262
+ const relatedIds = await db(throughTable).where(fromColumn, row.id).pluck(toColumn);
294
263
  record.columns[prop.name].value = relatedIds;
295
264
  } else if (isHasManyRelationProp(prop)) {
296
- const relatedEntity = EntityManager.get(prop.with);
297
- const relatedIds = await db(relatedEntity.table).where(prop.joinColumn, row$1.id).pluck("id");
265
+ const relatedIds = await db(EntityManager.get(prop.with).table).where(prop.joinColumn, row.id).pluck("id");
298
266
  record.columns[prop.name].value = relatedIds;
299
267
  } else if (isOneToOneRelationProp(prop) && !prop.hasJoinColumn) {
300
268
  const relatedEntity = EntityManager.get(prop.with);
301
- const relatedProp = relatedEntity.props.find((p) => isRelationProp(p) && p.with === entity$1.id);
269
+ const relatedProp = relatedEntity.props.find((p) => isRelationProp(p) && p.with === entity.id);
302
270
  if (relatedProp && isRelationProp(relatedProp)) {
303
271
  const fkColumn = `${relatedProp.name}_id`;
304
- const relatedRow = await db(relatedEntity.table).where(fkColumn, row$1.id).first();
272
+ const relatedRow = await db(relatedEntity.table).where(fkColumn, row.id).first();
305
273
  record.columns[prop.name].value = relatedRow?.id;
306
274
  }
307
275
  } else if (isRelationProp(prop)) {
308
- const relatedId = row$1[`${prop.name}_id`];
276
+ const relatedId = row[`${prop.name}_id`];
309
277
  record.columns[prop.name].value = relatedId;
310
- if (relatedId) {
311
- record.belongsRecords.push(`${prop.with}#${relatedId}`);
312
- }
278
+ if (relatedId) record.belongsRecords.push(`${prop.with}#${relatedId}`);
313
279
  if (!options?.singleRecord && relatedId) {
314
280
  const relatedEntity = EntityManager.get(prop.with);
315
281
  const relatedRow = await db(relatedEntity.table).where("id", relatedId).first();
316
- if (relatedRow) {
317
- await create(relatedEntity, relatedRow);
318
- }
282
+ if (relatedRow) await create(relatedEntity, relatedRow);
319
283
  }
320
284
  }
321
285
  }
@@ -337,9 +301,9 @@ var init_fixture_manager = __esmMin((() => {
337
301
  async insertFixtures(dbName, _fixtures) {
338
302
  const fixtures = unique(_fixtures, (f) => f.fixtureId);
339
303
  this.builder = new UpsertBuilder();
340
- this.fixtureRefMap = new Map();
341
- this.skippedFixtures = new Map();
342
- const dbConfig = process.env.SONAMU_WORKER_DB === "true" && process.env.VITEST_POOL_ID ? (() => {
304
+ this.fixtureRefMap = /* @__PURE__ */ new Map();
305
+ this.skippedFixtures = /* @__PURE__ */ new Map();
306
+ const db = createKnexInstance(process.env.SONAMU_WORKER_DB === "true" && process.env.VITEST_POOL_ID ? (() => {
343
307
  const workerId = parseInt(process.env.VITEST_POOL_ID ?? "1", 10);
344
308
  const baseConfig = Sonamu.dbConfig[dbName];
345
309
  const connection = baseConfig.connection;
@@ -354,8 +318,7 @@ var init_fixture_manager = __esmMin((() => {
354
318
  max: 1
355
319
  }
356
320
  };
357
- })() : Sonamu.dbConfig[dbName];
358
- const db = createKnexInstance(dbConfig);
321
+ })() : Sonamu.dbConfig[dbName]);
359
322
  const results = [];
360
323
  try {
361
324
  this.relationGraph.buildGraph(fixtures);
@@ -365,8 +328,7 @@ var init_fixture_manager = __esmMin((() => {
365
328
  if (!fixture) continue;
366
329
  const hasTarget = !!fixture.target;
367
330
  const hasUnique = !!fixture.unique;
368
- const hasDuplicate = hasTarget || hasUnique;
369
- if (hasDuplicate && !fixture.override) {
331
+ if ((hasTarget || hasUnique) && !fixture.override) {
370
332
  const existingId = fixture.unique?.id ?? fixture.target?.id;
371
333
  assert(existingId);
372
334
  this.skippedFixtures.set(fixtureId, {
@@ -376,14 +338,13 @@ var init_fixture_manager = __esmMin((() => {
376
338
  !isTest() && console.log(chalk.yellow(`Skipped ${fixture.entityId}#${fixture.id} (existing: #${existingId}, override: false)`));
377
339
  }
378
340
  }
379
- const fixturesByTable = new Map();
341
+ const fixturesByTable = /* @__PURE__ */ new Map();
380
342
  const tableOrder = [];
381
343
  for (const fixtureId of insertionOrder) {
382
344
  if (this.skippedFixtures.has(fixtureId)) continue;
383
345
  const fixture = fixtures.find((f) => f.fixtureId === fixtureId);
384
346
  if (!fixture) continue;
385
- const entity = EntityManager.get(fixture.entityId);
386
- const tableName = entity.table;
347
+ const tableName = EntityManager.get(fixture.entityId).table;
387
348
  if (!fixturesByTable.has(tableName)) {
388
349
  fixturesByTable.set(tableName, []);
389
350
  tableOrder.push(tableName);
@@ -391,7 +352,7 @@ var init_fixture_manager = __esmMin((() => {
391
352
  fixturesByTable.get(tableName)?.push(fixture);
392
353
  }
393
354
  await db.transaction(async (trx) => {
394
- const insertedIdsByTable = new Map();
355
+ const insertedIdsByTable = /* @__PURE__ */ new Map();
395
356
  for (const tableName of tableOrder) {
396
357
  const tableFixtures = fixturesByTable.get(tableName) ?? [];
397
358
  const levels = this.groupFixturesByLevel(tableFixtures);
@@ -400,46 +361,35 @@ var init_fixture_manager = __esmMin((() => {
400
361
  this.registerFixture(fixture, insertedIdsByTable);
401
362
  !isTest() && console.log(chalk.blue(`Registered ${fixture.entityId}#${fixture.id}${fixture.override ? ` (override)` : ""}`));
402
363
  }
403
- const table = this.builder.getTable(tableName);
404
- const uuids = table.rows.map((row) => row.uuid);
364
+ const uuids = this.builder.getTable(tableName).rows.map((row) => row.uuid);
405
365
  !isTest() && console.log(chalk.blue(`Upserting ${tableName} with ${uuids.length} rows (level ${levels.indexOf(levelFixtures) + 1}/${levels.length})`));
406
366
  const ids = await this.builder.upsert(trx, tableName);
407
367
  if (uuids.length > 0 && uuids.length === ids.length) {
408
- const existingMap = insertedIdsByTable.get(tableName) ?? new Map();
409
- for (let i = 0; i < uuids.length; i++) {
410
- existingMap.set(uuids[i], ids[i]);
411
- }
368
+ const existingMap = insertedIdsByTable.get(tableName) ?? /* @__PURE__ */ new Map();
369
+ for (let i = 0; i < uuids.length; i++) existingMap.set(uuids[i], ids[i]);
412
370
  insertedIdsByTable.set(tableName, existingMap);
413
- } else if (uuids.length !== ids.length) {
414
- console.warn(chalk.yellow(`Warning: uuid count (${uuids.length}) != id count (${ids.length}) for ${tableName}`));
415
- }
371
+ } else if (uuids.length !== ids.length) console.warn(chalk.yellow(`Warning: uuid count (${uuids.length}) != id count (${ids.length}) for ${tableName}`));
416
372
  }
417
373
  }
418
374
  await this.processManyToManyRelations(trx, fixtures, insertedIdsByTable);
419
375
  !isTest() && console.log(chalk.blue("Resetting sequences..."));
420
- for (const tableName of tableOrder) {
421
- try {
422
- const entity = EntityManager.getAllEntities().find((e) => e.table === tableName || e.id.toLowerCase() === tableName);
423
- if (entity) {
424
- const idProp = entity.props.find((p) => p.name === "id");
425
- const idType = idProp?.type;
426
- const usesSequence = idType === "integer" || idType === "bigInteger" || idProp?.cone?.fixtureStrategy === "sequence";
427
- if (!usesSequence) {
428
- !isTest() && console.log(chalk.gray(`Skipped sequence reset for ${tableName} (id type: ${idType || "unknown"})`));
429
- continue;
430
- }
376
+ for (const tableName of tableOrder) try {
377
+ const entity = EntityManager.getAllEntities().find((e) => e.table === tableName || e.id.toLowerCase() === tableName);
378
+ if (entity) {
379
+ const idProp = entity.props.find((p) => p.name === "id");
380
+ const idType = idProp?.type;
381
+ if (!(idType === "integer" || idType === "bigInteger" || idProp?.cone?.fixtureStrategy === "sequence")) {
382
+ !isTest() && console.log(chalk.gray(`Skipped sequence reset for ${tableName} (id type: ${idType || "unknown"})`));
383
+ continue;
431
384
  }
432
- const entity2 = EntityManager.getAllEntities().find((e) => e.table === tableName || e.id.toLowerCase() === tableName);
433
- const idType2 = entity2?.props.find((p) => p.name === "id")?.type;
434
- const maxIdResult = idType2 === "string" ? await trx.raw(`SELECT MAX(id::bigint) as max_id FROM "${tableName}"`).then((r) => r.rows[0]) : await trx(tableName).max("id as max_id").first();
435
- const maxId = maxIdResult?.max_id;
436
- if (maxId !== null && maxId !== undefined) {
437
- await trx.raw(`SELECT setval(pg_get_serial_sequence(?, 'id'), ?)`, [tableName, maxId]);
438
- !isTest() && console.log(chalk.green(`Reset sequence for ${tableName}: ${maxId}`));
439
- }
440
- } catch {
441
- !isTest() && console.log(chalk.gray(`Skipped sequence reset for ${tableName}`));
442
385
  }
386
+ const maxId = (EntityManager.getAllEntities().find((e) => e.table === tableName || e.id.toLowerCase() === tableName)?.props.find((p) => p.name === "id")?.type === "string" ? await trx.raw(`SELECT MAX(id::bigint) as max_id FROM "${tableName}"`).then((r) => r.rows[0]) : await trx(tableName).max("id as max_id").first())?.max_id;
387
+ if (maxId !== null && maxId !== void 0) {
388
+ await trx.raw(`SELECT setval(pg_get_serial_sequence(?, 'id'), ?)`, [tableName, maxId]);
389
+ !isTest() && console.log(chalk.green(`Reset sequence for ${tableName}: ${maxId}`));
390
+ }
391
+ } catch {
392
+ !isTest() && console.log(chalk.gray(`Skipped sequence reset for ${tableName}`));
443
393
  }
444
394
  for (const fixture of fixtures) {
445
395
  const entity = EntityManager.get(fixture.entityId);
@@ -453,9 +403,8 @@ var init_fixture_manager = __esmMin((() => {
453
403
  }
454
404
  const ref = this.fixtureRefMap.get(fixture.fixtureId);
455
405
  if (ref) {
456
- const uuidToId = insertedIdsByTable.get(entity.table);
457
- const insertedId = uuidToId?.get(ref.uuid);
458
- if (insertedId !== undefined) {
406
+ const insertedId = insertedIdsByTable.get(entity.table)?.get(ref.uuid);
407
+ if (insertedId !== void 0) {
459
408
  results.push({
460
409
  entityId: fixture.entityId,
461
410
  data: await trx(entity.table).where("id", insertedId).first()
@@ -481,52 +430,34 @@ var init_fixture_manager = __esmMin((() => {
481
430
  const isOverrideMode = fixture.override && existingRecord;
482
431
  for (const [propName, column] of Object.entries(fixture.columns)) {
483
432
  const prop = column.prop;
484
- if (isVirtualProp(prop)) {
485
- continue;
486
- }
487
- if ("generated" in prop && prop.generated) {
488
- continue;
489
- }
433
+ if (isVirtualProp(prop)) continue;
434
+ if ("generated" in prop && prop.generated) continue;
490
435
  if (propName === "id") {
491
436
  const idProp = entity.props.find((p) => p.name === "id");
492
437
  const usesSequence = !entity.parentId && (idProp?.type === "integer" || idProp?.type === "bigInteger" || idProp?.cone?.fixtureStrategy === "sequence");
493
- if (isOverrideMode && existingRecord) {
494
- row[propName] = existingRecord.columns[propName]?.value;
495
- } else if (!usesSequence) {
496
- row[propName] = column.value;
497
- }
438
+ if (isOverrideMode && existingRecord) row[propName] = existingRecord.columns[propName]?.value;
439
+ else if (!usesSequence) row[propName] = column.value;
498
440
  continue;
499
441
  }
500
442
  if (isRelationProp(prop)) {
501
443
  if (isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop) && prop.hasJoinColumn) {
502
444
  const relatedId = column.value;
503
- if (relatedId !== null && relatedId !== undefined) {
445
+ if (relatedId !== null && relatedId !== void 0) {
504
446
  const relatedFixtureId = `${prop.with}#${relatedId}`;
505
447
  const skippedExistingId = this.skippedFixtures.get(relatedFixtureId)?.existingId;
506
- if (skippedExistingId !== undefined) {
507
- row[`${propName}_id`] = skippedExistingId;
508
- } else {
448
+ if (skippedExistingId !== void 0) row[`${propName}_id`] = skippedExistingId;
449
+ else {
509
450
  const relatedRef = this.fixtureRefMap.get(relatedFixtureId);
510
451
  if (relatedRef) {
511
452
  const relatedEntity = EntityManager.get(prop.with);
512
- const relatedInsertedIds = insertedIdsByTable?.get(relatedEntity.table);
513
- const actualId = relatedInsertedIds?.get(relatedRef.uuid);
514
- if (actualId !== undefined) {
515
- row[`${propName}_id`] = actualId;
516
- } else {
517
- row[`${propName}_id`] = relatedRef;
518
- }
519
- } else {
520
- row[`${propName}_id`] = relatedId;
521
- }
453
+ const actualId = (insertedIdsByTable?.get(relatedEntity.table))?.get(relatedRef.uuid);
454
+ if (actualId !== void 0) row[`${propName}_id`] = actualId;
455
+ else row[`${propName}_id`] = relatedRef;
456
+ } else row[`${propName}_id`] = relatedId;
522
457
  }
523
- } else {
524
- row[`${propName}_id`] = null;
525
- }
458
+ } else row[`${propName}_id`] = null;
526
459
  }
527
- } else {
528
- row[propName] = this.convertColumnValue(prop, column.value);
529
- }
460
+ } else row[propName] = this.convertColumnValue(prop, column.value);
530
461
  }
531
462
  !isTest() && console.log(chalk.blue(`Registering ${entity.table} - ${inspect(row, false, null, true)}`));
532
463
  const ref = this.builder.register(entity.table, row);
@@ -537,15 +468,11 @@ var init_fixture_manager = __esmMin((() => {
537
468
  * 컬럼 값 변환
538
469
  */
539
470
  convertColumnValue(prop, value) {
540
- if (value === null || value === undefined) {
541
- return null;
542
- }
471
+ if (value === null || value === void 0) return null;
543
472
  switch (prop.type) {
544
473
  case "json": return value;
545
474
  case "date":
546
- if (typeof value === "string" || typeof value === "number") {
547
- return new Date(value);
548
- }
475
+ if (typeof value === "string" || typeof value === "number") return new Date(value);
549
476
  return value;
550
477
  default: return value;
551
478
  }
@@ -555,9 +482,8 @@ var init_fixture_manager = __esmMin((() => {
555
482
  const entity = EntityManager.get(fixture.entityId);
556
483
  const sourceRef = this.fixtureRefMap.get(fixture.fixtureId);
557
484
  if (!sourceRef) continue;
558
- const sourceUuidToId = insertedIdsByTable.get(entity.table);
559
- const sourceId = sourceUuidToId?.get(sourceRef.uuid);
560
- if (sourceId === undefined) continue;
485
+ const sourceId = insertedIdsByTable.get(entity.table)?.get(sourceRef.uuid);
486
+ if (sourceId === void 0) continue;
561
487
  for (const [, column] of Object.entries(fixture.columns)) {
562
488
  const prop = column.prop;
563
489
  if (isManyToManyRelationProp(prop) && Array.isArray(column.value)) {
@@ -574,16 +500,13 @@ var init_fixture_manager = __esmMin((() => {
574
500
  const relatedRef = this.fixtureRefMap.get(relatedFixtureId);
575
501
  let targetId;
576
502
  if (relatedRef) {
577
- const relatedUuidToId = insertedIdsByTable.get(relatedEntity.table);
578
- const resolvedId = relatedUuidToId?.get(relatedRef.uuid);
579
- if (resolvedId === undefined) {
503
+ const resolvedId = insertedIdsByTable.get(relatedEntity.table)?.get(relatedRef.uuid);
504
+ if (resolvedId === void 0) {
580
505
  console.warn(`Related fixture ${relatedFixtureId} not found in insertedIds, skipping`);
581
506
  continue;
582
507
  }
583
508
  targetId = resolvedId;
584
- } else {
585
- targetId = relatedId;
586
- }
509
+ } else targetId = relatedId;
587
510
  const [found] = await trx(joinTable).where({
588
511
  [sourceColumn]: sourceId,
589
512
  [targetColumn]: targetId
@@ -611,30 +534,23 @@ var init_fixture_manager = __esmMin((() => {
611
534
  * 이를 방지하기 위해 FixtureManager가 레벨별로 나눠서 처리합니다.
612
535
  */
613
536
  groupFixturesByLevel(fixtures) {
614
- if (fixtures.length === 0) {
615
- return [];
616
- }
537
+ if (fixtures.length === 0) return [];
617
538
  const entity = EntityManager.get(fixtures[0].entityId);
618
539
  const selfRefProps = entity.props.filter((p) => isRelationProp(p) && (isBelongsToOneRelationProp(p) || isOneToOneRelationProp(p) && p.hasJoinColumn) && p.with === entity.id);
619
- if (selfRefProps.length === 0) {
620
- return [fixtures];
621
- }
540
+ if (selfRefProps.length === 0) return [fixtures];
622
541
  const levels = [];
623
542
  const remaining = new Set(fixtures.map((f) => f.fixtureId));
624
- const processed = new Set();
543
+ const processed = /* @__PURE__ */ new Set();
625
544
  while (remaining.size > 0) {
626
545
  const currentLevel = [];
627
546
  for (const fixture of fixtures) {
628
547
  if (!remaining.has(fixture.fixtureId)) continue;
629
- const canProcess = selfRefProps.every((prop) => {
548
+ if (selfRefProps.every((prop) => {
630
549
  const refId = fixture.columns[prop.name]?.value;
631
- if (refId === null || refId === undefined) return true;
550
+ if (refId === null || refId === void 0) return true;
632
551
  const refFixtureId = `${prop.with}#${refId}`;
633
552
  return processed.has(refFixtureId) || !remaining.has(refFixtureId);
634
- });
635
- if (canProcess) {
636
- currentLevel.push(fixture);
637
- }
553
+ })) currentLevel.push(fixture);
638
554
  }
639
555
  if (currentLevel.length === 0) {
640
556
  const remainingIds = Array.from(remaining).join(", ");
@@ -649,51 +565,36 @@ var init_fixture_manager = __esmMin((() => {
649
565
  return levels;
650
566
  }
651
567
  async checkUniqueViolation(db, entity, fixture) {
652
- const _uniqueIndexes = entity.indexes?.filter((i) => i.type === "unique") ?? [];
653
- const uniqueIndexes = _uniqueIndexes.filter((index) => index.columns.every((column) => !column.name.startsWith(`${entity.table}__`)));
654
- if (uniqueIndexes.length === 0) {
655
- return null;
656
- }
568
+ const uniqueIndexes = (entity.indexes?.filter((i) => i.type === "unique") ?? []).filter((index) => index.columns.every((column) => !column.name.startsWith(`${entity.table}__`)));
569
+ if (uniqueIndexes.length === 0) return null;
657
570
  let uniqueQuery = db(entity.table);
658
571
  let hasCondition = false;
659
572
  for (const index of uniqueIndexes) {
660
- const containsNull = index.columns.some((column) => {
573
+ if (index.columns.some((column) => {
661
574
  const field = column.name.replace(/_id$/, "");
662
575
  return fixture.columns[field]?.value === null;
663
- });
664
- if (containsNull) {
665
- continue;
666
- }
576
+ })) continue;
667
577
  uniqueQuery = uniqueQuery.orWhere((qb) => {
668
578
  for (const column of index.columns) {
669
579
  const field = column.name.replace(/_id$/, "");
670
- if (Array.isArray(fixture.columns[field]?.value)) {
671
- qb.whereIn(column.name, fixture.columns[field].value);
672
- } else {
673
- qb.andWhere(column.name, fixture.columns[field]?.value);
674
- }
580
+ if (Array.isArray(fixture.columns[field]?.value)) qb.whereIn(column.name, fixture.columns[field].value);
581
+ else qb.andWhere(column.name, fixture.columns[field]?.value);
675
582
  }
676
583
  });
677
584
  hasCondition = true;
678
585
  }
679
- if (!hasCondition) {
680
- return null;
681
- }
586
+ if (!hasCondition) return null;
682
587
  const [uniqueFound] = await uniqueQuery;
683
588
  return uniqueFound;
684
589
  }
685
590
  async checkDuplicateByColumns(db, entity, fixture, columns) {
686
- if (columns.length === 0) {
687
- return null;
688
- }
591
+ if (columns.length === 0) return null;
689
592
  const whereClause = {};
690
593
  for (const column of columns) {
691
594
  const prop = entity.props.find((p) => p.name === column);
692
595
  const dbColumn = prop && isRelationProp(prop) ? `${column}_id` : column;
693
596
  const value = fixture.columns[column]?.value;
694
- if (value === null || value === undefined) {
695
- return null;
696
- }
597
+ if (value === null || value === void 0) return null;
697
598
  whereClause[dbColumn] = value;
698
599
  }
699
600
  const [found] = await db(entity.table).where(whereClause).limit(1);
@@ -704,18 +605,14 @@ var init_fixture_manager = __esmMin((() => {
704
605
  const content = readFileSync(path).toString();
705
606
  const fixtureLoaderStart = content.indexOf("const fixtureLoader = {");
706
607
  const fixtureLoaderEnd = content.indexOf("};", fixtureLoaderStart);
707
- if (fixtureLoaderStart !== -1 && fixtureLoaderEnd !== -1) {
708
- const newContent = `${content.slice(0, fixtureLoaderEnd)} ${code}\n${content.slice(fixtureLoaderEnd)}`;
709
- writeFileSync(path, newContent);
710
- } else {
711
- throw new Error("Failed to find fixtureLoader in fixture.ts");
712
- }
608
+ if (fixtureLoaderStart !== -1 && fixtureLoaderEnd !== -1) writeFileSync(path, `${content.slice(0, fixtureLoaderEnd)} ${code}\n${content.slice(fixtureLoaderEnd)}`);
609
+ else throw new Error("Failed to find fixtureLoader in fixture.ts");
713
610
  }
714
611
  };
715
612
  FixtureManager = new FixtureManagerClass();
716
613
  }));
717
-
718
614
  //#endregion
719
615
  init_fixture_manager();
720
616
  export { FixtureManager, FixtureManagerClass, init_fixture_manager };
721
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4dHVyZS1tYW5hZ2VyLmpzIiwibmFtZXMiOlsiZmllbGQ6IHN0cmluZyIsImlkOiBudW1iZXIiLCJhcmdzIiwiZml4dHVyZXM6IEZpeHR1cmVSZWNvcmRbXSIsImVudGl0eSIsInJlY29yZHM6IEZpeHR1cmVSZWNvcmRbXSIsInJvdyIsInJlY29yZDogRml4dHVyZVJlY29yZCIsInJlc3VsdHM6IEZpeHR1cmVJbXBvcnRSZXN1bHRbXSIsInRhYmxlT3JkZXI6IHN0cmluZ1tdIiwicm93OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiIsInRhcmdldElkOiBudW1iZXIgfCBzdHJpbmciLCJsZXZlbHM6IEZpeHR1cmVSZWNvcmRbXVtdIiwiY3VycmVudExldmVsOiBGaXh0dXJlUmVjb3JkW10iLCJ3aGVyZUNsYXVzZTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4iXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdGluZy9maXh0dXJlLW1hbmFnZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCI7XG5pbXBvcnQgeyBleGVjU3luYyB9IGZyb20gXCJjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyByZWFkRmlsZVN5bmMsIHdyaXRlRmlsZVN5bmMgfSBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IGluc3BlY3QgfSBmcm9tIFwidXRpbFwiO1xuXG5pbXBvcnQgY2hhbGsgZnJvbSBcImNoYWxrXCI7XG5pbXBvcnQgaW5mbGVjdGlvbiBmcm9tIFwiaW5mbGVjdGlvblwiO1xuaW1wb3J0IHsgdHlwZSBLbmV4IH0gZnJvbSBcImtuZXhcIjtcbmltcG9ydCB7IHVuaXF1ZSB9IGZyb20gXCJyYWRhc2hpXCI7XG5cbmltcG9ydCB7IFNvbmFtdSB9IGZyb20gXCIuLi9hcGkvc29uYW11XCI7XG5pbXBvcnQgeyBCYXNlTW9kZWwgfSBmcm9tIFwiLi4vZGF0YWJhc2UvYmFzZS1tb2RlbFwiO1xuaW1wb3J0IHsgdHlwZSBTb25hbXVEQkNvbmZpZyB9IGZyb20gXCIuLi9kYXRhYmFzZS9kYlwiO1xuaW1wb3J0IHsgY3JlYXRlS25leEluc3RhbmNlIH0gZnJvbSBcIi4uL2RhdGFiYXNlL2tuZXhcIjtcbmltcG9ydCB7IFVwc2VydEJ1aWxkZXIgfSBmcm9tIFwiLi4vZGF0YWJhc2UvdXBzZXJ0LWJ1aWxkZXJcIjtcbmltcG9ydCB7IHR5cGUgVUJSZWYgfSBmcm9tIFwiLi4vZGF0YWJhc2UvdXBzZXJ0LWJ1aWxkZXJcIjtcbmltcG9ydCB7IHR5cGUgRW50aXR5IH0gZnJvbSBcIi4uL2VudGl0eS9lbnRpdHlcIjtcbmltcG9ydCB7IEVudGl0eU1hbmFnZXIgfSBmcm9tIFwiLi4vZW50aXR5L2VudGl0eS1tYW5hZ2VyXCI7XG5pbXBvcnQge1xuICBpc0JlbG9uZ3NUb09uZVJlbGF0aW9uUHJvcCxcbiAgaXNIYXNNYW55UmVsYXRpb25Qcm9wLFxuICBpc01hbnlUb01hbnlSZWxhdGlvblByb3AsXG4gIGlzT25lVG9PbmVSZWxhdGlvblByb3AsXG4gIGlzUmVsYXRpb25Qcm9wLFxuICBpc1ZpcnR1YWxQcm9wLFxufSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7XG4gIHR5cGUgQmVsb25nc1RvT25lUmVsYXRpb25Qcm9wLFxuICB0eXBlIERhdGFiYXNlU2NoZW1hRXh0ZW5kLFxuICB0eXBlIEVudGl0eVByb3AsXG4gIHR5cGUgRml4dHVyZUltcG9ydFJlc3VsdCxcbiAgdHlwZSBGaXh0dXJlUmVjb3JkLFxuICB0eXBlIEZpeHR1cmVTZWFyY2hPcHRpb25zLFxuICB0eXBlIE9uZVRvT25lUmVsYXRpb25Qcm9wLFxufSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IGlzVGVzdCB9IGZyb20gXCIuLi91dGlscy9jb250cm9sbGVyXCI7XG5pbXBvcnQgeyBSZWxhdGlvbkdyYXBoIH0gZnJvbSBcIi4vX3JlbGF0aW9uLWdyYXBoXCI7XG5cbi8qKiDsgqzsmqnsnpAg7KeA7KCVIOykkeuztSDtmZXsnbgg7Lus65+8IChlbnRpdHlJZOuzhOuhnCDsp4DsoJUpICovXG5leHBvcnQgaW50ZXJmYWNlIER1cGxpY2F0ZUNoZWNrT3B0aW9ucyB7XG4gIGNvbHVtbnM/OiB7XG4gICAgW2VudGl0eUlkOiBzdHJpbmddOiBzdHJpbmdbXTtcbiAgfTtcbn1cblxuZXhwb3J0IGNsYXNzIEZpeHR1cmVNYW5hZ2VyQ2xhc3Mge1xuICBwcml2YXRlIF90ZGI6IEtuZXggfCBudWxsID0gbnVsbDtcbiAgc2V0IHRkYih0ZGI6IEtuZXgpIHtcbiAgICB0aGlzLl90ZGIgPSB0ZGI7XG4gIH1cbiAgZ2V0IHRkYigpOiBLbmV4IHtcbiAgICBpZiAodGhpcy5fdGRiID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJGaXh0dXJlTWFuYWdlciBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRcIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl90ZGI7XG4gIH1cblxuICBwcml2YXRlIF9mZGI6IEtuZXggfCBudWxsID0gbnVsbDtcbiAgc2V0IGZkYihmZGI6IEtuZXgpIHtcbiAgICB0aGlzLl9mZGIgPSBmZGI7XG4gIH1cbiAgZ2V0IGZkYigpOiBLbmV4IHtcbiAgICBpZiAodGhpcy5fZmRiID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJGaXh0dXJlTWFuYWdlciBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRcIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9mZGI7XG4gIH1cbiAgY2FjaGVkVGFibGVOYW1lczogc3RyaW5nW10gfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIHJlbGF0aW9uR3JhcGggPSBuZXcgUmVsYXRpb25HcmFwaCgpO1xuXG4gIC8vIFVwc2VydEJ1aWxkZXIg6riw67CYIGltcG9ydOulvCDsnITtlZwg7IOB7YOcXG4gIHByaXZhdGUgYnVpbGRlcjogVXBzZXJ0QnVpbGRlciA9IG5ldyBVcHNlcnRCdWlsZGVyKCk7XG4gIHByaXZhdGUgZml4dHVyZVJlZk1hcDogTWFwPHN0cmluZywgVUJSZWY+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIHNraXBwZWRGaXh0dXJlczogTWFwPHN0cmluZywgeyBlbnRpdHlJZDogc3RyaW5nOyBleGlzdGluZ0lkOiBudW1iZXIgfCBzdHJpbmcgfT4gPVxuICAgIG5ldyBNYXAoKTtcblxuICBpbml0KCkge1xuICAgIGlmICh0aGlzLl90ZGIgIT09IG51bGwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKFNvbmFtdS5kYkNvbmZpZy50ZXN0ICYmIFNvbmFtdS5kYkNvbmZpZy5wcm9kdWN0aW9uX21hc3Rlcikge1xuICAgICAgY29uc3QgdENvbm4gPSBTb25hbXUuZGJDb25maWcudGVzdC5jb25uZWN0aW9uIGFzIEtuZXguQ29ubmVjdGlvbkNvbmZpZyAmIHtcbiAgICAgICAgcG9ydD86IG51bWJlcjtcbiAgICAgIH07XG4gICAgICBjb25zdCBwQ29ubiA9IFNvbmFtdS5kYkNvbmZpZy5wcm9kdWN0aW9uX21hc3Rlci5jb25uZWN0aW9uIGFzIEtuZXguQ29ubmVjdGlvbkNvbmZpZyAmIHtcbiAgICAgICAgcG9ydD86IG51bWJlcjtcbiAgICAgIH07XG4gICAgICBpZiAoXG4gICAgICAgIGAke3RDb25uLmhvc3QgPz8gXCJsb2NhbGhvc3RcIn06JHt0Q29ubi5wb3J0ID8/IDU0MzJ9LyR7dENvbm4uZGF0YWJhc2V9YCA9PT1cbiAgICAgICAgYCR7cENvbm4uaG9zdCA/PyBcImxvY2FsaG9zdFwifToke3BDb25uLnBvcnQgPz8gNTQzMn0vJHtwQ29ubi5kYXRhYmFzZX1gXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGDthYzsiqTtirhEQuyZgCDtlITroZzrjZXshZhEQuyXkCDrj5nsnbztlZwg642w7J207YSw67Kg7J207Iqk6rCAIOyCrOyaqeuQmOyXiOyKteuLiOuLpC5gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnRkYiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShTb25hbXUuZGJDb25maWcudGVzdCk7XG4gICAgdGhpcy5mZGIgPSBjcmVhdGVLbmV4SW5zdGFuY2UoU29uYW11LmRiQ29uZmlnLmZpeHR1cmUpO1xuICB9XG5cbiAgLyoqXG4gICAg7JuQ6rKpIGZpeHR1cmUgRELrpbwg66Gc7LusIHRlc3QgRELroZwg67O17IKs7ZWp64uI64ukLlxuICAgIHBnX2R1bXDroZwg7JuQ6rKpIERC66W8IOuNpO2UhO2VmOqzoCwgcGdfcmVzdG9yZeuhnCDroZzsu6zsl5Ag67O17JuQ7ZWp64uI64ukLlxuICAqL1xuICBhc3luYyBzeW5jKCkge1xuICAgIGNvbnN0IGZpeHR1cmVDb25uID0gU29uYW11LmRiQ29uZmlnLmZpeHR1cmUuY29ubmVjdGlvbiBhcyBLbmV4LlBnQ29ubmVjdGlvbkNvbmZpZztcbiAgICBjb25zdCB0ZXN0Q29ubiA9IFNvbmFtdS5kYkNvbmZpZy50ZXN0LmNvbm5lY3Rpb24gYXMgS25leC5QZ0Nvbm5lY3Rpb25Db25maWc7XG5cbiAgICAvLyAxLiDroZzsu6wgdGVzdCBEQiDsl7DqsrAg7KKF66OMIOuwjyDsnqzsg53shLFcbiAgICBjb25zdCB0ZXN0UGdFbnYgPSB7IFBHUEFTU1dPUkQ6IHRlc3RDb25uLnBhc3N3b3JkIHx8IFwiXCIgfTtcbiAgICBleGVjU3luYyhcbiAgICAgIGBwc3FsIC1oICR7dGVzdENvbm4uaG9zdH0gLXAgJHt0ZXN0Q29ubi5wb3J0ID8/IDU0MzJ9IC1VICR7dGVzdENvbm4udXNlcn0gLWQgcG9zdGdyZXMgLWMgXCJcbiAgICAgICAgU0VMRUNUIHBnX3Rlcm1pbmF0ZV9iYWNrZW5kKHBnX3N0YXRfYWN0aXZpdHkucGlkKVxuICAgICAgICBGUk9NIHBnX3N0YXRfYWN0aXZpdHlcbiAgICAgICAgV0hFUkUgZGF0bmFtZSA9ICcke3Rlc3RDb25uLmRhdGFiYXNlfSdcbiAgICAgICAgICBBTkQgcGlkIDw+IHBnX2JhY2tlbmRfcGlkKCk7XG4gICAgICBcImAsXG4gICAgICB7IHN0ZGlvOiBcImluaGVyaXRcIiwgZW52OiB7IC4uLnByb2Nlc3MuZW52LCAuLi50ZXN0UGdFbnYgfSBhcyBOb2RlSlMuUHJvY2Vzc0VudiB9LFxuICAgICk7XG5cbiAgICBleGVjU3luYyhcbiAgICAgIGBwc3FsIC1oICR7dGVzdENvbm4uaG9zdH0gLXAgJHt0ZXN0Q29ubi5wb3J0ID8/IDU0MzJ9IC1VICR7dGVzdENvbm4udXNlcn0gLWQgcG9zdGdyZXMgLWMgXCJEUk9QIERBVEFCQVNFIElGIEVYSVNUUyBcXFxcXCIke3Rlc3RDb25uLmRhdGFiYXNlfVxcXFxcIlwiYCxcbiAgICAgIHsgc3RkaW86IFwiaW5oZXJpdFwiLCBlbnY6IHsgLi4ucHJvY2Vzcy5lbnYsIC4uLnRlc3RQZ0VudiB9IGFzIE5vZGVKUy5Qcm9jZXNzRW52IH0sXG4gICAgKTtcblxuICAgIGV4ZWNTeW5jKFxuICAgICAgYHBzcWwgLWggJHt0ZXN0Q29ubi5ob3N0fSAtcCAke3Rlc3RDb25uLnBvcnQgPz8gNTQzMn0gLVUgJHt0ZXN0Q29ubi51c2VyfSAtZCBwb3N0Z3JlcyAtYyBcIkNSRUFURSBEQVRBQkFTRSBcXFxcXCIke3Rlc3RDb25uLmRhdGFiYXNlfVxcXFxcIlwiYCxcbiAgICAgIHsgc3RkaW86IFwiaW5oZXJpdFwiLCBlbnY6IHsgLi4ucHJvY2Vzcy5lbnYsIC4uLnRlc3RQZ0VudiB9IGFzIE5vZGVKUy5Qcm9jZXNzRW52IH0sXG4gICAgKTtcblxuICAgIC8vIDIuIOybkOqyqSBmaXh0dXJlIERCIOKGkiDroZzsu6wgdGVzdCBEQuuhnCDrs7XsgqwgKHBnX2R1bXAgfCBwZ19yZXN0b3JlKVxuICAgIGNvbnN0IGZpeHR1cmVQZ0VudiA9IHsgUEdQQVNTV09SRDogZml4dHVyZUNvbm4ucGFzc3dvcmQgfHwgXCJcIiB9O1xuICAgIGNvbnN0IGR1bXBDbWQgPSBgcGdfZHVtcCAtaCAke2ZpeHR1cmVDb25uLmhvc3R9IC1wICR7Zml4dHVyZUNvbm4ucG9ydCA/PyA1NDMyfSAtVSAke2ZpeHR1cmVDb25uLnVzZXJ9IC1kICR7Zml4dHVyZUNvbm4uZGF0YWJhc2V9IC1GY2A7XG4gICAgY29uc3QgcmVzdG9yZUNtZCA9IGBwZ19yZXN0b3JlIC1oICR7dGVzdENvbm4uaG9zdH0gLXAgJHt0ZXN0Q29ubi5wb3J0ID8/IDU0MzJ9IC1VICR7dGVzdENvbm4udXNlcn0gLWQgJHt0ZXN0Q29ubi5kYXRhYmFzZX0gLS1uby1vd25lciAtLW5vLWFjbGA7XG5cbiAgICBleGVjU3luYyhgJHtkdW1wQ21kfSB8IFBHUEFTU1dPUkQ9XCIke3Rlc3RDb25uLnBhc3N3b3JkIHx8IFwiXCJ9XCIgJHtyZXN0b3JlQ21kfWAsIHtcbiAgICAgIHN0ZGlvOiBcImluaGVyaXRcIixcbiAgICAgIGVudjogeyAuLi5wcm9jZXNzLmVudiwgLi4uZml4dHVyZVBnRW52IH0gYXMgTm9kZUpTLlByb2Nlc3NFbnYsXG4gICAgICBzaGVsbDogXCIvYmluL2Jhc2hcIixcbiAgICB9KTtcblxuICAgIC8vIDMuIOyLnO2AgOyKpCDrpqzshYsgKOuNsOydtO2EsCDrs7Xsgqwg7ZuEIOyLnO2AgOyKpOulvCBNQVgoaWQp66GcIOygleugrClcbiAgICBhd2FpdCB0aGlzLnJlc2V0U2VxdWVuY2VzKFNvbmFtdS5kYkNvbmZpZy50ZXN0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDrqqjrk6Ag7YWM7J2067iU7J2YIOyLnO2AgOyKpOulvCDtmITsnqwgTUFYKGlkKeuhnCDrpqzshYvtlanri4jri6QuXG4gICAqIGZpeHR1cmUgc3luYyDtm4Qg7Iuc7YCA7Iqk6rCAIOyLpOygnCDrjbDsnbTthLDsmYAg66ee7KeAIOyViuuKlCDrrLjsoJzrpbwg7ZW06rKw7ZWp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZXNldFNlcXVlbmNlcyhkYkNvbmZpZzogU29uYW11REJDb25maWdbXCJ0ZXN0XCJdKSB7XG4gICAgY29uc3QgdGVzdERiID0gY3JlYXRlS25leEluc3RhbmNlKGRiQ29uZmlnKTtcbiAgICBjb25zdCBlbnRpdGllcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsRW50aXRpZXMoKTtcblxuICAgIHRyeSB7XG4gICAgICBmb3IgKGNvbnN0IGVudGl0eSBvZiBlbnRpdGllcykge1xuICAgICAgICBjb25zdCB0YWJsZU5hbWUgPSBlbnRpdHkudGFibGUgfHwgZW50aXR5LmlkLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgICAgLy8gaWQg7ZWE65Oc7J2YIO2DgOyeheydhCDtmZXsnbjtlanri4jri6RcbiAgICAgICAgY29uc3QgaWRQcm9wID0gZW50aXR5LnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gXCJpZFwiKTtcbiAgICAgICAgY29uc3QgaWRUeXBlID0gaWRQcm9wPy50eXBlO1xuXG4gICAgICAgIC8vIGludGVnZXIvYmlnSW50ZWdlcuydtOqxsOuCmCwgc3RyaW5n7J207KeA66eMIGZpeHR1cmVTdHJhdGVneT1zZXF1ZW5jZeyduCDqsr3smrDsl5Drp4wg66as7IWL7ZWp64uI64ukXG4gICAgICAgIGNvbnN0IHVzZXNTZXF1ZW5jZSA9XG4gICAgICAgICAgaWRUeXBlID09PSBcImludGVnZXJcIiB8fFxuICAgICAgICAgIGlkVHlwZSA9PT0gXCJiaWdJbnRlZ2VyXCIgfHxcbiAgICAgICAgICBpZFByb3A/LmNvbmU/LmZpeHR1cmVTdHJhdGVneSA9PT0gXCJzZXF1ZW5jZVwiO1xuXG4gICAgICAgIGlmICghdXNlc1NlcXVlbmNlKSB7XG4gICAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgYFNraXBwaW5nIHNlcXVlbmNlIHJlc2V0IGZvciAke3RhYmxlTmFtZX0gKGlkIHR5cGU6ICR7aWRUeXBlIHx8IFwidW5rbm93blwifSlgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFBvc3RncmVTUUwg7Iuc7YCA7Iqk66W8IO2YhOyerCDthYzsnbTruJTsnZggTUFYKGlkKeuhnCDrpqzshYvtlanri4jri6QuXG4gICAgICAgIC8vIHN0cmluZyDtg4DsnoXsnZgg6rK97JqwIOyIq+yekCDsupDsiqTtjIXsnbQg7ZWE7JqU7ZWp64uI64ukLlxuICAgICAgICBjb25zdCBtYXhFeHByID0gaWRUeXBlID09PSBcInN0cmluZ1wiID8gXCJNQVgoaWQ6OmJpZ2ludClcIiA6IFwiTUFYKGlkKVwiO1xuICAgICAgICBhd2FpdCB0ZXN0RGIucmF3KGBcbiAgICAgICAgICBTRUxFQ1Qgc2V0dmFsKFxuICAgICAgICAgICAgcGdfZ2V0X3NlcmlhbF9zZXF1ZW5jZSgncHVibGljLiR7dGFibGVOYW1lfScsICdpZCcpLFxuICAgICAgICAgICAgQ09BTEVTQ0UoKFNFTEVDVCAke21heEV4cHJ9IEZST00gJHt0YWJsZU5hbWV9KSwgMSlcbiAgICAgICAgICApXG4gICAgICAgIGApO1xuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCB0ZXN0RGIuZGVzdHJveSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdmlzaXRlZFJlY29yZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgYXN5bmMgaW1wb3J0Rml4dHVyZShlbnRpdHlJZDogc3RyaW5nLCBpZHM6IG51bWJlcltdKSB7XG4gICAgLy8g67Cp66y4IOq4sOuhnSDstIjquLDtmZQgKOyDiOuhnOyatCBpbXBvcnQg7J6R7JeFIOyLnOyekSlcbiAgICB0aGlzLnZpc2l0ZWRSZWNvcmRzLmNsZWFyKCk7XG5cbiAgICBjb25zdCBxdWVyaWVzID0gdW5pcXVlKFxuICAgICAgKFxuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICBpZHMubWFwKGFzeW5jIChpZCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZ2V0SW1wb3J0UXVlcmllcyhlbnRpdHlJZCwgXCJpZFwiLCBpZCk7XG4gICAgICAgICAgfSksXG4gICAgICAgIClcbiAgICAgICkuZmxhdCgpLFxuICAgICk7XG5cbiAgICBjb25zdCB3ZGIgPSBCYXNlTW9kZWwuZ2V0REIoXCJ3XCIpO1xuICAgIGZvciAoY29uc3QgcXVlcnkgb2YgcXVlcmllcykge1xuICAgICAgYXdhaXQgd2RiLnJhdyhxdWVyeSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZ2V0SW1wb3J0UXVlcmllcyhlbnRpdHlJZDogc3RyaW5nLCBmaWVsZDogc3RyaW5nLCBpZDogbnVtYmVyKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IHJlY29yZEtleSA9IGAke2VudGl0eUlkfSMke2ZpZWxkfSMke2lkfWA7XG5cbiAgICAvLyDsiJztmZgg7LC47KGwIOuwqeyngDog7J2066+4IOuwqeusuO2VnCDroIjsvZTrk5zripQg7Iqk7YK1XG4gICAgaWYgKHRoaXMudmlzaXRlZFJlY29yZHMuaGFzKHJlY29yZEtleSkpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgdGhpcy52aXNpdGVkUmVjb3Jkcy5hZGQocmVjb3JkS2V5KTtcblxuICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICBjb25zdCB3ZGIgPSBCYXNlTW9kZWwuZ2V0REIoXCJ3XCIpO1xuXG4gICAgLy8g7Jes6riw7IScIOyLpERC7J2YIHJvdyDqsIDsoLjsmLRcbiAgICBjb25zdCBbcm93XSA9IGF3YWl0IHdkYihlbnRpdHkudGFibGUpLndoZXJlKGZpZWxkLCBpZCkubGltaXQoMSk7XG4gICAgaWYgKHJvdyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZW50aXR5SWR9IyR7aWR9IHJvd+ulvCDssL7snYQg7IiYIOyXhuyKteuLiOuLpC5gKTtcbiAgICB9XG5cbiAgICAvLyDtlL3siqTss5BEQiwg7IukREJcbiAgICBjb25zdCBmaXh0dXJlRGF0YWJhc2UgPSAoU29uYW11LmRiQ29uZmlnLmZpeHR1cmUuY29ubmVjdGlvbiBhcyBLbmV4LkNvbm5lY3Rpb25Db25maWcpLmRhdGFiYXNlO1xuICAgIGNvbnN0IHJlYWxEYXRhYmFzZSA9IChTb25hbXUuZGJDb25maWcucHJvZHVjdGlvbl9tYXN0ZXIuY29ubmVjdGlvbiBhcyBLbmV4LkNvbm5lY3Rpb25Db25maWcpXG4gICAgICAuZGF0YWJhc2U7XG5cbiAgICBjb25zdCBzZWxmUXVlcnkgPSBgSU5TRVJUIElHTk9SRSBJTlRPIFxcYCR7Zml4dHVyZURhdGFiYXNlfVxcYC5cXGAke2VudGl0eS50YWJsZX1cXGAgKFNFTEVDVCAqIEZST00gXFxgJHtyZWFsRGF0YWJhc2V9XFxgLlxcYCR7ZW50aXR5LnRhYmxlfVxcYCBXSEVSRSBcXGBpZFxcYCA9ICR7aWR9KWA7XG5cbiAgICBjb25zdCBhcmdzID0gT2JqZWN0LmVudHJpZXMoZW50aXR5LnJlbGF0aW9ucylcbiAgICAgIC5maWx0ZXIoXG4gICAgICAgIChbLCByZWxhdGlvbl0pID0+XG4gICAgICAgICAgaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocmVsYXRpb24pIHx8XG4gICAgICAgICAgKGlzT25lVG9PbmVSZWxhdGlvblByb3AocmVsYXRpb24pICYmIHJlbGF0aW9uLmN1c3RvbUpvaW5DbGF1c2UgPT09IHVuZGVmaW5lZCksXG4gICAgICApXG4gICAgICAubWFwKChbLCByZWxhdGlvbl0pID0+IHtcbiAgICAgICAgLypcbiAgICAgICAgQmVsb25nc1RvT25l7J24IOqyveyasFxuICAgICAgICAgIENhdGVnb3J5IC8gJ2lkJyAvIHJvd1tjYXRlZ29yeV9pZF0g7Zi47LacXG4gICAgICAgIE9uZVRvT25l7JeQIGpvaW5Db2x1bW4gPT09IHRydWUg7J24IOqyveyasFxuICAgICAgICAgIFByb2ZpbGUgLyAnaWQnIC8gcm93W3Byb2ZpbGVfaWRdIO2YuOy2nFxuICAgICAgICBPbmVUb09uZeyXkCBqb2luQ29sdW1uID09PSBmYWxzZSDsnbgg6rK97JqwXG4gICAgICAgICAgUHJvZmlsZSAvICdwcm9maWxlX2lkJyAvIHJvd1snaWQnXSDtmLjstpxcbiAgICAgICAgKi9cbiAgICAgICAgbGV0IGZpZWxkOiBzdHJpbmc7XG4gICAgICAgIGxldCBpZDogbnVtYmVyO1xuICAgICAgICBpZiAoaXNPbmVUb09uZVJlbGF0aW9uUHJvcChyZWxhdGlvbikgJiYgIXJlbGF0aW9uLmhhc0pvaW5Db2x1bW4pIHtcbiAgICAgICAgICBjb25zdCByZWxhdGVkRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocmVsYXRpb24ud2l0aCk7XG4gICAgICAgICAgY29uc3QgcmVsYXRlZElkQ29sdW1uTmFtZSA9IHJlbGF0ZWRFbnRpdHkucHJvcHMuZmluZChcbiAgICAgICAgICAgIChwKSA9PiBpc1JlbGF0aW9uUHJvcChwKSAmJiBwLndpdGggPT09IGVudGl0eS5pZCxcbiAgICAgICAgICApPy5uYW1lO1xuICAgICAgICAgIGlmICghcmVsYXRlZElkQ29sdW1uTmFtZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3JlbGF0ZWRFbnRpdHkuaWR97J2YICR7ZW50aXR5LmlkfSDqtIDqs4Qg7ZSE66Gt7J2EIOywvuydhCDsiJgg7JeG7Iq164uI64ukLmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmaWVsZCA9IGAke3JlbGF0ZWRJZENvbHVtbk5hbWV9X2lkYDtcbiAgICAgICAgICBpZCA9IHJvdy5pZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmaWVsZCA9IFwiaWRcIjtcbiAgICAgICAgICBpZCA9IHJvd1tgJHtyZWxhdGlvbi5uYW1lfV9pZGBdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHJlbGF0aW9uLndpdGgsXG4gICAgICAgICAgZmllbGQsXG4gICAgICAgICAgaWQsXG4gICAgICAgIH07XG4gICAgICB9KVxuICAgICAgLmZpbHRlcigoYXJnKSA9PiBhcmcuaWQgIT09IG51bGwpO1xuXG4gICAgY29uc3QgcmVsUXVlcmllcyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgYXJncy5tYXAoYXN5bmMgKGFyZ3MpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0SW1wb3J0UXVlcmllcyhhcmdzLmVudGl0eUlkLCBhcmdzLmZpZWxkLCBhcmdzLmlkKTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICByZXR1cm4gWy4uLnVuaXF1ZShyZWxRdWVyaWVzLnRvUmV2ZXJzZWQoKS5mbGF0KCkpLCBzZWxmUXVlcnldO1xuICB9XG5cbiAgYXN5bmMgZGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5fdGRiKSB7XG4gICAgICBhd2FpdCB0aGlzLl90ZGIuZGVzdHJveSgpO1xuICAgICAgdGhpcy5fdGRiID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2ZkYikge1xuICAgICAgYXdhaXQgdGhpcy5fZmRiLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMuX2ZkYiA9IG51bGw7XG4gICAgfVxuICAgIGF3YWl0IEJhc2VNb2RlbC5kZXN0cm95KCk7XG4gIH1cblxuICBhc3luYyBnZXRGaXh0dXJlcyhcbiAgICBzb3VyY2VEQk5hbWU6IGtleW9mIFNvbmFtdURCQ29uZmlnLFxuICAgIHRhcmdldERCTmFtZToga2V5b2YgU29uYW11REJDb25maWcsXG4gICAgc2VhcmNoT3B0aW9uczogRml4dHVyZVNlYXJjaE9wdGlvbnMsXG4gICAgZHVwbGljYXRlQ2hlY2s/OiBEdXBsaWNhdGVDaGVja09wdGlvbnMsXG4gICkge1xuICAgIGNvbnN0IHNvdXJjZURCID0gY3JlYXRlS25leEluc3RhbmNlKFNvbmFtdS5kYkNvbmZpZ1tzb3VyY2VEQk5hbWVdKTtcbiAgICBjb25zdCB0YXJnZXREQiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShTb25hbXUuZGJDb25maWdbdGFyZ2V0REJOYW1lXSk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBlbnRpdHlJZCwgZmllbGQsIHZhbHVlLCBzZWFyY2hUeXBlIH0gPSBzZWFyY2hPcHRpb25zO1xuXG4gICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICBjb25zdCBjb2x1bW4gPVxuICAgICAgICBlbnRpdHkucHJvcHMuZmluZCgocHJvcCkgPT4gcHJvcC5uYW1lID09PSBmaWVsZCk/LnR5cGUgPT09IFwicmVsYXRpb25cIlxuICAgICAgICAgID8gYCR7ZmllbGR9X2lkYFxuICAgICAgICAgIDogZmllbGQ7XG5cbiAgICAgIGxldCBxdWVyeSA9IHNvdXJjZURCKGVudGl0eS50YWJsZSk7XG4gICAgICBpZiAoc2VhcmNoVHlwZSA9PT0gXCJlcXVhbHNcIikge1xuICAgICAgICBxdWVyeSA9IHF1ZXJ5LndoZXJlKGNvbHVtbiwgdmFsdWUpO1xuICAgICAgfSBlbHNlIGlmIChzZWFyY2hUeXBlID09PSBcImxpa2VcIikge1xuICAgICAgICBxdWVyeSA9IHF1ZXJ5LndoZXJlKGNvbHVtbiwgXCJsaWtlXCIsIGAlJHt2YWx1ZX0lYCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJvd3MgPSBhd2FpdCBxdWVyeTtcbiAgICAgIGlmIChyb3dzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyByZWNvcmRzIGZvdW5kXCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBmaXh0dXJlczogRml4dHVyZVJlY29yZFtdID0gW107XG4gICAgICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKSB7XG4gICAgICAgIGNvbnN0IGluaXRpYWxSZWNvcmRzTGVuZ3RoID0gZml4dHVyZXMubGVuZ3RoO1xuICAgICAgICBjb25zdCBuZXdSZWNvcmRzID0gYXdhaXQgdGhpcy5jcmVhdGVGaXh0dXJlUmVjb3JkKGVudGl0eSwgcm93LCB7XG4gICAgICAgICAgX2RiOiBzb3VyY2VEQixcbiAgICAgICAgfSk7XG4gICAgICAgIGZpeHR1cmVzLnB1c2goLi4ubmV3UmVjb3Jkcyk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRGaXh0dXJlUmVjb3JkID0gZml4dHVyZXMuZmluZCgocikgPT4gci5maXh0dXJlSWQgPT09IGAke2VudGl0eUlkfSMke3Jvdy5pZH1gKTtcblxuICAgICAgICBpZiAoY3VycmVudEZpeHR1cmVSZWNvcmQpIHtcbiAgICAgICAgICAvLyDtmITsnqwgZml4dHVyZeuhnOu2gO2EsCDsg53shLHrkJwgZmV0Y2hlZFJlY29yZHMg7ISk7KCVXG4gICAgICAgICAgY3VycmVudEZpeHR1cmVSZWNvcmQuZmV0Y2hlZFJlY29yZHMgPSBmaXh0dXJlc1xuICAgICAgICAgICAgLmZpbHRlcigocikgPT4gci5maXh0dXJlSWQgIT09IGN1cnJlbnRGaXh0dXJlUmVjb3JkLmZpeHR1cmVJZClcbiAgICAgICAgICAgIC5zbGljZShpbml0aWFsUmVjb3Jkc0xlbmd0aClcbiAgICAgICAgICAgIC5tYXAoKHIpID0+IHIuZml4dHVyZUlkKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGZpeHR1cmUgb2YgZml4dHVyZXMpIHtcbiAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZml4dHVyZS5lbnRpdHlJZCk7XG5cbiAgICAgICAgLy8g7IKs7Jqp7J6QIOyngOyglSDsu6zrn7wg6riw7KSAIOykkeuztSDtmZXsnbgg4oaSIHRhcmdldFxuICAgICAgICBjb25zdCBjdXN0b21Db2x1bW5zID0gZHVwbGljYXRlQ2hlY2s/LmNvbHVtbnM/LltmaXh0dXJlLmVudGl0eUlkXTtcbiAgICAgICAgaWYgKGN1c3RvbUNvbHVtbnMgJiYgY3VzdG9tQ29sdW1ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3QgY3VzdG9tRHVwbGljYXRlUm93ID0gYXdhaXQgdGhpcy5jaGVja0R1cGxpY2F0ZUJ5Q29sdW1ucyhcbiAgICAgICAgICAgIHRhcmdldERCLFxuICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgZml4dHVyZSxcbiAgICAgICAgICAgIGN1c3RvbUNvbHVtbnMsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoY3VzdG9tRHVwbGljYXRlUm93KSB7XG4gICAgICAgICAgICBjb25zdCBbcmVjb3JkXSA9IGF3YWl0IHRoaXMuY3JlYXRlRml4dHVyZVJlY29yZChlbnRpdHksIGN1c3RvbUR1cGxpY2F0ZVJvdywge1xuICAgICAgICAgICAgICBzaW5nbGVSZWNvcmQ6IHRydWUsXG4gICAgICAgICAgICAgIF9kYjogdGFyZ2V0REIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGZpeHR1cmUudGFyZ2V0ID0gcmVjb3JkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVuaXF1ZSBpbmRleCDquLDspIAg7KSR67O1IO2ZleyduCDihpIgZml4dHVyZS51bmlxdWVcbiAgICAgICAgY29uc3QgdW5pcXVlUm93ID0gYXdhaXQgdGhpcy5jaGVja1VuaXF1ZVZpb2xhdGlvbih0YXJnZXREQiwgZW50aXR5LCBmaXh0dXJlKTtcbiAgICAgICAgaWYgKHVuaXF1ZVJvdykge1xuICAgICAgICAgIGNvbnN0IFtyZWNvcmRdID0gYXdhaXQgdGhpcy5jcmVhdGVGaXh0dXJlUmVjb3JkKGVudGl0eSwgdW5pcXVlUm93LCB7XG4gICAgICAgICAgICBzaW5nbGVSZWNvcmQ6IHRydWUsXG4gICAgICAgICAgICBfZGI6IHRhcmdldERCLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGZpeHR1cmUudW5pcXVlID0gcmVjb3JkO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB1bmlxdWUoZml4dHVyZXMsIChmKSA9PiBmLmZpeHR1cmVJZCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChbdGFyZ2V0REIuZGVzdHJveSgpLCBzb3VyY2VEQi5kZXN0cm95KCldKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjcmVhdGVGaXh0dXJlUmVjb3JkKFxuICAgIGVudGl0eTogRW50aXR5LFxuICAgIHJvdzoge1xuICAgICAgaWQ6IG51bWJlciB8IHN0cmluZztcbiAgICAgIFtrZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfCBudWxsO1xuICAgIH0sXG4gICAgb3B0aW9ucz86IHtcbiAgICAgIHNpbmdsZVJlY29yZD86IGJvb2xlYW47XG4gICAgICBfZGI/OiBLbmV4O1xuICAgIH0sXG4gICk6IFByb21pc2U8Rml4dHVyZVJlY29yZFtdPiB7XG4gICAgY29uc3QgcmVjb3JkczogRml4dHVyZVJlY29yZFtdID0gW107XG4gICAgY29uc3QgdmlzaXRlZEVudGl0aWVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICBjb25zdCBjcmVhdGUgPSBhc3luYyAoXG4gICAgICBlbnRpdHk6IEVudGl0eSxcbiAgICAgIHJvdzoge1xuICAgICAgICBpZDogbnVtYmVyIHwgc3RyaW5nO1xuICAgICAgICBba2V5OiBzdHJpbmddOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHwgbnVsbDtcbiAgICAgIH0sXG4gICAgKSA9PiB7XG4gICAgICBjb25zdCBmaXh0dXJlSWQgPSBgJHtlbnRpdHkuaWR9IyR7cm93LmlkfWA7XG4gICAgICBpZiAodmlzaXRlZEVudGl0aWVzLmhhcyhmaXh0dXJlSWQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZpc2l0ZWRFbnRpdGllcy5hZGQoZml4dHVyZUlkKTtcblxuICAgICAgY29uc3QgcmVjb3JkOiBGaXh0dXJlUmVjb3JkID0ge1xuICAgICAgICBmaXh0dXJlSWQsXG4gICAgICAgIGVudGl0eUlkOiBlbnRpdHkuaWQsXG4gICAgICAgIGlkOiByb3cuaWQsXG4gICAgICAgIGNvbHVtbnM6IHt9LFxuICAgICAgICBmZXRjaGVkUmVjb3JkczogW10sXG4gICAgICAgIGJlbG9uZ3NSZWNvcmRzOiBbXSxcbiAgICAgIH07XG5cbiAgICAgIGZvciAoY29uc3QgcHJvcCBvZiBlbnRpdHkucHJvcHMpIHtcbiAgICAgICAgaWYgKGlzVmlydHVhbFByb3AocHJvcCkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlY29yZC5jb2x1bW5zW3Byb3AubmFtZV0gPSB7XG4gICAgICAgICAgcHJvcDogcHJvcCxcbiAgICAgICAgICB2YWx1ZTogcm93W3Byb3AubmFtZV0sXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZGIgPSBvcHRpb25zPy5fZGIgPz8gQmFzZU1vZGVsLmdldERCKFwid1wiKTtcbiAgICAgICAgaWYgKGlzTWFueVRvTWFueVJlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChwcm9wLndpdGgpO1xuICAgICAgICAgIGNvbnN0IHRocm91Z2hUYWJsZSA9IHByb3Auam9pblRhYmxlO1xuICAgICAgICAgIGNvbnN0IGZyb21Db2x1bW4gPSBgJHtpbmZsZWN0aW9uLnNpbmd1bGFyaXplKGVudGl0eS50YWJsZSl9X2lkYDtcbiAgICAgICAgICBjb25zdCB0b0NvbHVtbiA9IGAke2luZmxlY3Rpb24uc2luZ3VsYXJpemUocmVsYXRlZEVudGl0eS50YWJsZSl9X2lkYDtcblxuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRJZHMgPSBhd2FpdCBkYih0aHJvdWdoVGFibGUpLndoZXJlKGZyb21Db2x1bW4sIHJvdy5pZCkucGx1Y2sodG9Db2x1bW4pO1xuICAgICAgICAgIHJlY29yZC5jb2x1bW5zW3Byb3AubmFtZV0udmFsdWUgPSByZWxhdGVkSWRzO1xuICAgICAgICB9IGVsc2UgaWYgKGlzSGFzTWFueVJlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChwcm9wLndpdGgpO1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRJZHMgPSBhd2FpdCBkYihyZWxhdGVkRW50aXR5LnRhYmxlKVxuICAgICAgICAgICAgLndoZXJlKHByb3Auam9pbkNvbHVtbiwgcm93LmlkKVxuICAgICAgICAgICAgLnBsdWNrKFwiaWRcIik7XG4gICAgICAgICAgcmVjb3JkLmNvbHVtbnNbcHJvcC5uYW1lXS52YWx1ZSA9IHJlbGF0ZWRJZHM7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNPbmVUb09uZVJlbGF0aW9uUHJvcChwcm9wKSAmJiAhcHJvcC5oYXNKb2luQ29sdW1uKSB7XG4gICAgICAgICAgLy8g7Jet67Cp7ZalIE9uZVRvT25lOiBGS+ulvCDqsIDsp4Qg6rSA66CoIOyXlO2LsO2LsOulvCDssL7sirXri4jri6RcbiAgICAgICAgICAvLyDsmIjsi5w6IFVzZXIgT25lVG9PbmUgRW1wbG95ZWUgKEVtcGxveWVl6rCAIHVzZXJfaWQgRkvrpbwg6rCA7KeQKVxuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChwcm9wLndpdGgpO1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRQcm9wID0gcmVsYXRlZEVudGl0eS5wcm9wcy5maW5kKFxuICAgICAgICAgICAgKHApID0+IGlzUmVsYXRpb25Qcm9wKHApICYmIHAud2l0aCA9PT0gZW50aXR5LmlkLFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKHJlbGF0ZWRQcm9wICYmIGlzUmVsYXRpb25Qcm9wKHJlbGF0ZWRQcm9wKSkge1xuICAgICAgICAgICAgLy8g6rSA66CoIOyXlO2LsO2LsOyXkOyEnCBGSyDsu6zrn7zsnLzroZwg7L+866as7ZWp64uI64ukIChpZOqwgCDslYTri5gpXG4gICAgICAgICAgICBjb25zdCBma0NvbHVtbiA9IGAke3JlbGF0ZWRQcm9wLm5hbWV9X2lkYDtcbiAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRSb3cgPSBhd2FpdCBkYihyZWxhdGVkRW50aXR5LnRhYmxlKS53aGVyZShma0NvbHVtbiwgcm93LmlkKS5maXJzdCgpO1xuICAgICAgICAgICAgcmVjb3JkLmNvbHVtbnNbcHJvcC5uYW1lXS52YWx1ZSA9IHJlbGF0ZWRSb3c/LmlkO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChpc1JlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRJZCA9IHJvd1tgJHtwcm9wLm5hbWV9X2lkYF07XG4gICAgICAgICAgcmVjb3JkLmNvbHVtbnNbcHJvcC5uYW1lXS52YWx1ZSA9IHJlbGF0ZWRJZDtcbiAgICAgICAgICBpZiAocmVsYXRlZElkKSB7XG4gICAgICAgICAgICByZWNvcmQuYmVsb25nc1JlY29yZHMucHVzaChgJHtwcm9wLndpdGh9IyR7cmVsYXRlZElkfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW9wdGlvbnM/LnNpbmdsZVJlY29yZCAmJiByZWxhdGVkSWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChwcm9wLndpdGgpO1xuICAgICAgICAgICAgY29uc3QgcmVsYXRlZFJvdyA9IGF3YWl0IGRiKHJlbGF0ZWRFbnRpdHkudGFibGUpLndoZXJlKFwiaWRcIiwgcmVsYXRlZElkKS5maXJzdCgpO1xuICAgICAgICAgICAgaWYgKHJlbGF0ZWRSb3cpIHtcbiAgICAgICAgICAgICAgYXdhaXQgY3JlYXRlKHJlbGF0ZWRFbnRpdHksIHJlbGF0ZWRSb3cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZWNvcmRzLnB1c2gocmVjb3JkKTtcbiAgICB9O1xuXG4gICAgYXdhaXQgY3JlYXRlKGVudGl0eSwgcm93KTtcblxuICAgIHJldHVybiByZWNvcmRzO1xuICB9XG5cbiAgLyoqXG4gICAqIDEuIFJlbGF0aW9uR3JhcGjroZwgZml4dHVyZSDri6jsnIQg7IK97J6FIOyInOyEnCDqs4TsgrAgKHNlbGYtcmVmZXJlbmNlIO2PrO2VqClcbiAgICogMi4g7YWM7J2067iU67OEIOugiOuyqOuzhOuhnCBVcHNlcnRCdWlsZGVy7JeQIOuTseuhnSDrsI8gdXBzZXJ0IOyLpO2WiVxuICAgKiAzLiDsiJzshJwg6riw67CYIHV1aWTihpJpZCDrp6TtlZEgKFVwc2VydEJ1aWxkZXLqsIAgdXVpZOulvCBEQuyXkCDsoIDsnqXtlZjsp4Ag7JWK7Jy866+A66GcKVxuICAgKlxuICAgKiBVcHNlcnRCdWlsZGVy64qUIHNlbGYtcmVmZXJlbmNl6rCAIOyeiOycvOuptCBidWlsZEluc2VydExldmVscygp66GcIOyerOygleugrO2VmOyXrFxuICAgKiDrk7HroZ0g7Iic7ISc7JmAIOuwmO2ZmCDsiJzshJzqsIAg64us65287KeIIOyImCDsnojsirXri4jri6QuIOydtOulvCDrsKnsp4DtlZjquLAg7JyE7ZW0XG4gICAqIEZpeHR1cmVNYW5hZ2Vy6rCAIOugiOuyqOuzhOuhnCDrgpjriKDshJwg7LKY66as7ZWY7JesIOqwgSB1cHNlcnQg7Zi47Lac7JeQ7ISc64qUXG4gICAqIHNlbGYtcmVmZXJlbmNl6rCAIOyXhuuPhOuhnSDtlanri4jri6QuXG4gICAqL1xuICBhc3luYyBpbnNlcnRGaXh0dXJlcyhcbiAgICBkYk5hbWU6IGtleW9mIFNvbmFtdURCQ29uZmlnLFxuICAgIF9maXh0dXJlczogRml4dHVyZVJlY29yZFtdLFxuICApOiBQcm9taXNlPEZpeHR1cmVJbXBvcnRSZXN1bHRbXT4ge1xuICAgIGNvbnN0IGZpeHR1cmVzID0gdW5pcXVlKF9maXh0dXJlcywgKGYpID0+IGYuZml4dHVyZUlkKTtcblxuICAgIC8vIOy0iOq4sO2ZlFxuICAgIHRoaXMuYnVpbGRlciA9IG5ldyBVcHNlcnRCdWlsZGVyKCk7XG4gICAgdGhpcy5maXh0dXJlUmVmTWFwID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuc2tpcHBlZEZpeHR1cmVzID0gbmV3IE1hcCgpO1xuXG4gICAgLy8g67OR66CsIO2FjOyKpO2KuCDrqqjrk5zsl5DshJzripQgd29ya2Vy67OEIERC7JeQIOyggOyepVxuICAgIGNvbnN0IGRiQ29uZmlnID1cbiAgICAgIHByb2Nlc3MuZW52LlNPTkFNVV9XT1JLRVJfREIgPT09IFwidHJ1ZVwiICYmIHByb2Nlc3MuZW52LlZJVEVTVF9QT09MX0lEXG4gICAgICAgID8gKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHdvcmtlcklkID0gcGFyc2VJbnQocHJvY2Vzcy5lbnYuVklURVNUX1BPT0xfSUQgPz8gXCIxXCIsIDEwKTtcbiAgICAgICAgICAgIGNvbnN0IGJhc2VDb25maWcgPSBTb25hbXUuZGJDb25maWdbZGJOYW1lXTtcbiAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBiYXNlQ29uZmlnLmNvbm5lY3Rpb24gYXMgeyBkYXRhYmFzZTogc3RyaW5nIH07XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAuLi5iYXNlQ29uZmlnLFxuICAgICAgICAgICAgICBjb25uZWN0aW9uOiB7IC4uLmNvbm5lY3Rpb24sIGRhdGFiYXNlOiBgJHtjb25uZWN0aW9uLmRhdGFiYXNlfV8ke3dvcmtlcklkfWAgfSxcbiAgICAgICAgICAgICAgcG9vbDogeyBtaW46IDEsIG1heDogMSB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSgpXG4gICAgICAgIDogU29uYW11LmRiQ29uZmlnW2RiTmFtZV07XG4gICAgY29uc3QgZGIgPSBjcmVhdGVLbmV4SW5zdGFuY2UoZGJDb25maWcpO1xuICAgIGNvbnN0IHJlc3VsdHM6IEZpeHR1cmVJbXBvcnRSZXN1bHRbXSA9IFtdO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIDEuIFJlbGF0aW9uR3JhcGjroZwgZml4dHVyZSDri6jsnIQg7IK97J6FIOyInOyEnCDqs4TsgrBcbiAgICAgIHRoaXMucmVsYXRpb25HcmFwaC5idWlsZEdyYXBoKGZpeHR1cmVzKTtcbiAgICAgIGNvbnN0IGluc2VydGlvbk9yZGVyID0gdGhpcy5yZWxhdGlvbkdyYXBoLmdldEluc2VydGlvbk9yZGVyKCk7XG5cbiAgICAgIC8vIDIuIOyKpO2Cte2VoCBmaXh0dXJlIOuovOyggCDsspjrpqwgKG92ZXJyaWRlIOyytO2BrClcbiAgICAgIGZvciAoY29uc3QgZml4dHVyZUlkIG9mIGluc2VydGlvbk9yZGVyKSB7XG4gICAgICAgIGNvbnN0IGZpeHR1cmUgPSBmaXh0dXJlcy5maW5kKChmKSA9PiBmLmZpeHR1cmVJZCA9PT0gZml4dHVyZUlkKTtcbiAgICAgICAgaWYgKCFmaXh0dXJlKSBjb250aW51ZTtcblxuICAgICAgICBjb25zdCBoYXNUYXJnZXQgPSAhIWZpeHR1cmUudGFyZ2V0O1xuICAgICAgICBjb25zdCBoYXNVbmlxdWUgPSAhIWZpeHR1cmUudW5pcXVlO1xuICAgICAgICBjb25zdCBoYXNEdXBsaWNhdGUgPSBoYXNUYXJnZXQgfHwgaGFzVW5pcXVlO1xuXG4gICAgICAgIC8vIOykkeuzteydtCDsnojqs6Agb3ZlcnJpZGU9ZmFsc2Xsnbgg6rK97JqwOiDsiqTtgrVcbiAgICAgICAgaWYgKGhhc0R1cGxpY2F0ZSAmJiAhZml4dHVyZS5vdmVycmlkZSkge1xuICAgICAgICAgIC8vIOq4sOyhtCDroIjsvZTrk5wgSUQg7KCA7J6lICh1bmlxdWUg7Jqw7ISgLCDsl4bsnLzrqbQgdGFyZ2V0KVxuICAgICAgICAgIGNvbnN0IGV4aXN0aW5nSWQgPSBmaXh0dXJlLnVuaXF1ZT8uaWQgPz8gZml4dHVyZS50YXJnZXQ/LmlkO1xuICAgICAgICAgIGFzc2VydChleGlzdGluZ0lkKTtcbiAgICAgICAgICB0aGlzLnNraXBwZWRGaXh0dXJlcy5zZXQoZml4dHVyZUlkLCB7XG4gICAgICAgICAgICBlbnRpdHlJZDogZml4dHVyZS5lbnRpdHlJZCxcbiAgICAgICAgICAgIGV4aXN0aW5nSWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICBjaGFsay55ZWxsb3coXG4gICAgICAgICAgICAgICAgYFNraXBwZWQgJHtmaXh0dXJlLmVudGl0eUlkfSMke2ZpeHR1cmUuaWR9IChleGlzdGluZzogIyR7ZXhpc3RpbmdJZH0sIG92ZXJyaWRlOiBmYWxzZSlgLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyAzLiDthYzsnbTruJTrs4QgZml4dHVyZSDqt7jro7ntmZQgKGluc2VydGlvbk9yZGVyIOyInOyEnCDquLDrsJgpXG4gICAgICBjb25zdCBmaXh0dXJlc0J5VGFibGUgPSBuZXcgTWFwPHN0cmluZywgRml4dHVyZVJlY29yZFtdPigpO1xuICAgICAgY29uc3QgdGFibGVPcmRlcjogc3RyaW5nW10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBmaXh0dXJlSWQgb2YgaW5zZXJ0aW9uT3JkZXIpIHtcbiAgICAgICAgLy8g7Iqk7YK165CcIGZpeHR1cmUg7KCc7Jm4XG4gICAgICAgIGlmICh0aGlzLnNraXBwZWRGaXh0dXJlcy5oYXMoZml4dHVyZUlkKSkgY29udGludWU7XG5cbiAgICAgICAgY29uc3QgZml4dHVyZSA9IGZpeHR1cmVzLmZpbmQoKGYpID0+IGYuZml4dHVyZUlkID09PSBmaXh0dXJlSWQpO1xuICAgICAgICBpZiAoIWZpeHR1cmUpIGNvbnRpbnVlO1xuXG4gICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmUuZW50aXR5SWQpO1xuICAgICAgICBjb25zdCB0YWJsZU5hbWUgPSBlbnRpdHkudGFibGU7XG5cbiAgICAgICAgaWYgKCFmaXh0dXJlc0J5VGFibGUuaGFzKHRhYmxlTmFtZSkpIHtcbiAgICAgICAgICBmaXh0dXJlc0J5VGFibGUuc2V0KHRhYmxlTmFtZSwgW10pO1xuICAgICAgICAgIHRhYmxlT3JkZXIucHVzaCh0YWJsZU5hbWUpO1xuICAgICAgICB9XG4gICAgICAgIGZpeHR1cmVzQnlUYWJsZS5nZXQodGFibGVOYW1lKT8ucHVzaChmaXh0dXJlKTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgZGIudHJhbnNhY3Rpb24oYXN5bmMgKHRyeCkgPT4ge1xuICAgICAgICBjb25zdCBpbnNlcnRlZElkc0J5VGFibGUgPSBuZXcgTWFwPHN0cmluZywgTWFwPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPj4oKTtcblxuICAgICAgICAvLyA0LiDthYzsnbTruJTrs4Qg66CI67Ko67OEIOyymOumrFxuICAgICAgICBmb3IgKGNvbnN0IHRhYmxlTmFtZSBvZiB0YWJsZU9yZGVyKSB7XG4gICAgICAgICAgY29uc3QgdGFibGVGaXh0dXJlcyA9IGZpeHR1cmVzQnlUYWJsZS5nZXQodGFibGVOYW1lKSA/PyBbXTtcbiAgICAgICAgICBjb25zdCBsZXZlbHMgPSB0aGlzLmdyb3VwRml4dHVyZXNCeUxldmVsKHRhYmxlRml4dHVyZXMpO1xuXG4gICAgICAgICAgZm9yIChjb25zdCBsZXZlbEZpeHR1cmVzIG9mIGxldmVscykge1xuICAgICAgICAgICAgLy8g7ZW064u5IOugiOuyqOydmCBmaXh0dXJl65OkIHJlZ2lzdGVyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGZpeHR1cmUgb2YgbGV2ZWxGaXh0dXJlcykge1xuICAgICAgICAgICAgICB0aGlzLnJlZ2lzdGVyRml4dHVyZShmaXh0dXJlLCBpbnNlcnRlZElkc0J5VGFibGUpO1xuICAgICAgICAgICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgICAgIGNoYWxrLmJsdWUoXG4gICAgICAgICAgICAgICAgICAgIGBSZWdpc3RlcmVkICR7Zml4dHVyZS5lbnRpdHlJZH0jJHtmaXh0dXJlLmlkfSR7Zml4dHVyZS5vdmVycmlkZSA/IGAgKG92ZXJyaWRlKWAgOiBcIlwifWAsXG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHVwc2VydCDsi6Ttlokg7KCEIHV1aWQg66qp66GdIOyggOyepVxuICAgICAgICAgICAgY29uc3QgdGFibGUgPSB0aGlzLmJ1aWxkZXIuZ2V0VGFibGUodGFibGVOYW1lKTtcbiAgICAgICAgICAgIGNvbnN0IHV1aWRzID0gdGFibGUucm93cy5tYXAoKHJvdykgPT4gcm93LnV1aWQgYXMgc3RyaW5nKTtcblxuICAgICAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgIGNoYWxrLmJsdWUoXG4gICAgICAgICAgICAgICAgICBgVXBzZXJ0aW5nICR7dGFibGVOYW1lfSB3aXRoICR7dXVpZHMubGVuZ3RofSByb3dzIChsZXZlbCAke2xldmVscy5pbmRleE9mKGxldmVsRml4dHVyZXMpICsgMX0vJHtsZXZlbHMubGVuZ3RofSlgLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBpZHMgPSAoYXdhaXQgdGhpcy5idWlsZGVyLnVwc2VydChcbiAgICAgICAgICAgICAgdHJ4LFxuICAgICAgICAgICAgICB0YWJsZU5hbWUgYXMga2V5b2YgRGF0YWJhc2VTY2hlbWFFeHRlbmQsXG4gICAgICAgICAgICApKSBhcyAobnVtYmVyIHwgc3RyaW5nKVtdO1xuXG4gICAgICAgICAgICAvLyDsiJzshJwg6riw67CYIHV1aWQgLT4gaWQg66ek7ZWRXG4gICAgICAgICAgICAvLyBzZWxmLXJlZmVyZW5jZeqwgCDsl4bsnLzrr4DroZwg65Ox66GdIOyInOyEnCA9IOuwmO2ZmCDsiJzshJwg67O07J6lXG4gICAgICAgICAgICBpZiAodXVpZHMubGVuZ3RoID4gMCAmJiB1dWlkcy5sZW5ndGggPT09IGlkcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgY29uc3QgZXhpc3RpbmdNYXAgPVxuICAgICAgICAgICAgICAgIGluc2VydGVkSWRzQnlUYWJsZS5nZXQodGFibGVOYW1lKSA/PyBuZXcgTWFwPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPigpO1xuICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHV1aWRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgZXhpc3RpbmdNYXAuc2V0KHV1aWRzW2ldLCBpZHNbaV0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGluc2VydGVkSWRzQnlUYWJsZS5zZXQodGFibGVOYW1lLCBleGlzdGluZ01hcCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHV1aWRzLmxlbmd0aCAhPT0gaWRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgICAgY2hhbGsueWVsbG93KFxuICAgICAgICAgICAgICAgICAgYFdhcm5pbmc6IHV1aWQgY291bnQgKCR7dXVpZHMubGVuZ3RofSkgIT0gaWQgY291bnQgKCR7aWRzLmxlbmd0aH0pIGZvciAke3RhYmxlTmFtZX1gLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gNS4gTWFueVRvTWFueSDqtIDqs4Qg7LKY66asXG4gICAgICAgIGF3YWl0IHRoaXMucHJvY2Vzc01hbnlUb01hbnlSZWxhdGlvbnModHJ4LCBmaXh0dXJlcywgaW5zZXJ0ZWRJZHNCeVRhYmxlKTtcblxuICAgICAgICAvLyA2LiBQb3N0Z3JlU1FMIOyLnO2AgOyKpCDrpqzshYtcbiAgICAgICAgLy8gRml4dHVyZSDsgr3snoUg7ZuEIOqwgSDthYzsnbTruJTsnZggSUQg7Iuc7YCA7Iqk66W8IOy1nOuMgCBJRCDqsJLsnLzroZwg7JeF642w7J207Yq47ZWp64uI64ukLlxuICAgICAgICAvLyDsnbTroIfqsowg7ZWY7KeAIOyViuycvOuptCDri6TsnYwgSU5TRVJUIOyLnCBJROqwgCAyMDAw67KI64yA66GcIOyDneyEseuQoCDsiJgg7J6I7Iq164uI64ukLlxuICAgICAgICAhaXNUZXN0KCkgJiYgY29uc29sZS5sb2coY2hhbGsuYmx1ZShcIlJlc2V0dGluZyBzZXF1ZW5jZXMuLi5cIikpO1xuICAgICAgICBmb3IgKGNvbnN0IHRhYmxlTmFtZSBvZiB0YWJsZU9yZGVyKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIEVudGl0eeulvCDssL7slYTshJwgaWQg7YOA7J6FIO2ZleyduFxuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXRBbGxFbnRpdGllcygpLmZpbmQoXG4gICAgICAgICAgICAgIChlKSA9PiBlLnRhYmxlID09PSB0YWJsZU5hbWUgfHwgZS5pZC50b0xvd2VyQ2FzZSgpID09PSB0YWJsZU5hbWUsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBpZiAoZW50aXR5KSB7XG4gICAgICAgICAgICAgIGNvbnN0IGlkUHJvcCA9IGVudGl0eS5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IFwiaWRcIik7XG4gICAgICAgICAgICAgIGNvbnN0IGlkVHlwZSA9IGlkUHJvcD8udHlwZTtcblxuICAgICAgICAgICAgICAvLyBpbnRlZ2VyL2JpZ0ludGVnZXLsnbTqsbDrgpgsIHN0cmluZ+ydtOyngOunjCBmaXh0dXJlU3RyYXRlZ3k9c2VxdWVuY2Xsnbgg6rK97Jqw7JeQ66eMIOumrOyFi+2VqeuLiOuLpFxuICAgICAgICAgICAgICBjb25zdCB1c2VzU2VxdWVuY2UgPVxuICAgICAgICAgICAgICAgIGlkVHlwZSA9PT0gXCJpbnRlZ2VyXCIgfHxcbiAgICAgICAgICAgICAgICBpZFR5cGUgPT09IFwiYmlnSW50ZWdlclwiIHx8XG4gICAgICAgICAgICAgICAgaWRQcm9wPy5jb25lPy5maXh0dXJlU3RyYXRlZ3kgPT09IFwic2VxdWVuY2VcIjtcblxuICAgICAgICAgICAgICBpZiAoIXVzZXNTZXF1ZW5jZSkge1xuICAgICAgICAgICAgICAgICFpc1Rlc3QoKSAmJlxuICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgICAgIGNoYWxrLmdyYXkoXG4gICAgICAgICAgICAgICAgICAgICAgYFNraXBwZWQgc2VxdWVuY2UgcmVzZXQgZm9yICR7dGFibGVOYW1lfSAoaWQgdHlwZTogJHtpZFR5cGUgfHwgXCJ1bmtub3duXCJ9KWAsXG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIO2FjOydtOu4lOydmCDstZzrjIAgSUQg7KGw7ZqMIChzdHJpbmcg7YOA7J6F7J2AIOyIq+yekCDsupDsiqTtjIUg7ZWE7JqUKVxuICAgICAgICAgICAgY29uc3QgZW50aXR5MiA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsRW50aXRpZXMoKS5maW5kKFxuICAgICAgICAgICAgICAoZSkgPT4gZS50YWJsZSA9PT0gdGFibGVOYW1lIHx8IGUuaWQudG9Mb3dlckNhc2UoKSA9PT0gdGFibGVOYW1lLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IGlkVHlwZTIgPSBlbnRpdHkyPy5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IFwiaWRcIik/LnR5cGU7XG4gICAgICAgICAgICBjb25zdCBtYXhJZFJlc3VsdCA9XG4gICAgICAgICAgICAgIGlkVHlwZTIgPT09IFwic3RyaW5nXCJcbiAgICAgICAgICAgICAgICA/IGF3YWl0IHRyeFxuICAgICAgICAgICAgICAgICAgICAucmF3KGBTRUxFQ1QgTUFYKGlkOjpiaWdpbnQpIGFzIG1heF9pZCBGUk9NIFwiJHt0YWJsZU5hbWV9XCJgKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigocikgPT4gci5yb3dzWzBdKVxuICAgICAgICAgICAgICAgIDogYXdhaXQgdHJ4KHRhYmxlTmFtZSkubWF4KFwiaWQgYXMgbWF4X2lkXCIpLmZpcnN0KCk7XG4gICAgICAgICAgICBjb25zdCBtYXhJZCA9IG1heElkUmVzdWx0Py5tYXhfaWQ7XG5cbiAgICAgICAgICAgIGlmIChtYXhJZCAhPT0gbnVsbCAmJiBtYXhJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIC8vIOyLnO2AgOyKpOuqheydhCBwZ19nZXRfc2VyaWFsX3NlcXVlbmNl66GcIOyViOyghO2VmOqyjCDsobDtmoxcbiAgICAgICAgICAgICAgYXdhaXQgdHJ4LnJhdyhgU0VMRUNUIHNldHZhbChwZ19nZXRfc2VyaWFsX3NlcXVlbmNlKD8sICdpZCcpLCA/KWAsIFtcbiAgICAgICAgICAgICAgICB0YWJsZU5hbWUsXG4gICAgICAgICAgICAgICAgbWF4SWQsXG4gICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAhaXNUZXN0KCkgJiYgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYFJlc2V0IHNlcXVlbmNlIGZvciAke3RhYmxlTmFtZX06ICR7bWF4SWR9YCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLy8g7Iuc7YCA7Iqk6rCAIOyXhuuKlCDthYzsnbTruJQoam9pbiB0YWJsZSDrk7Ep7J2AIOustOyLnFxuICAgICAgICAgICAgIWlzVGVzdCgpICYmIGNvbnNvbGUubG9nKGNoYWxrLmdyYXkoYFNraXBwZWQgc2VxdWVuY2UgcmVzZXQgZm9yICR7dGFibGVOYW1lfWApKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyA3LiDqsrDqs7wg7IiY7KeRXG4gICAgICAgIGZvciAoY29uc3QgZml4dHVyZSBvZiBmaXh0dXJlcykge1xuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmUuZW50aXR5SWQpO1xuXG4gICAgICAgICAgLy8g7Iqk7YK165CcIGZpeHR1cmXripQg6riw7KG0IOugiOy9lOuTnCDsoJXrs7TroZwg6rKw6rO8IOy2lOqwgFxuICAgICAgICAgIGNvbnN0IHNraXBwZWQgPSB0aGlzLnNraXBwZWRGaXh0dXJlcy5nZXQoZml4dHVyZS5maXh0dXJlSWQpO1xuICAgICAgICAgIGlmIChza2lwcGVkKSB7XG4gICAgICAgICAgICByZXN1bHRzLnB1c2goe1xuICAgICAgICAgICAgICBlbnRpdHlJZDogZml4dHVyZS5lbnRpdHlJZCxcbiAgICAgICAgICAgICAgZGF0YTogYXdhaXQgdHJ4KGVudGl0eS50YWJsZSkud2hlcmUoXCJpZFwiLCBza2lwcGVkLmV4aXN0aW5nSWQpLmZpcnN0KCksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHJlZiA9IHRoaXMuZml4dHVyZVJlZk1hcC5nZXQoZml4dHVyZS5maXh0dXJlSWQpO1xuICAgICAgICAgIGlmIChyZWYpIHtcbiAgICAgICAgICAgIGNvbnN0IHV1aWRUb0lkID0gaW5zZXJ0ZWRJZHNCeVRhYmxlLmdldChlbnRpdHkudGFibGUpO1xuICAgICAgICAgICAgY29uc3QgaW5zZXJ0ZWRJZCA9IHV1aWRUb0lkPy5nZXQocmVmLnV1aWQpO1xuXG4gICAgICAgICAgICBpZiAoaW5zZXJ0ZWRJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIHJlc3VsdHMucHVzaCh7XG4gICAgICAgICAgICAgICAgZW50aXR5SWQ6IGZpeHR1cmUuZW50aXR5SWQsXG4gICAgICAgICAgICAgICAgZGF0YTogYXdhaXQgdHJ4KGVudGl0eS50YWJsZSkud2hlcmUoXCJpZFwiLCBpbnNlcnRlZElkKS5maXJzdCgpLFxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgICAgIGNoYWxrLmdyZWVuKGBJbnNlcnRlZCBpbnRvICR7ZW50aXR5LnRhYmxlfTogIyR7Zml4dHVyZS5pZH0gLT4gIyR7aW5zZXJ0ZWRJZH1gKSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IGRiLmRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5pcXVlKHJlc3VsdHMsIChyKSA9PiBgJHtyLmVudGl0eUlkfSMke3IuZGF0YS5pZH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXh0dXJlUmVjb3Jk66W8IFVwc2VydEJ1aWxkZXLsl5Ag65Ox66GdXG4gICAqIEBwYXJhbSBpbnNlcnRlZElkc0J5VGFibGUg7J2066+4IHVwc2VydOuQnCDthYzsnbTruJTsnZggdXVpZOKGkmlkIOunpO2VkSAo66CI67Ko67OEIOyymOumrCDsi5wg7IKs7JqpKVxuICAgKi9cbiAgcHJpdmF0ZSByZWdpc3RlckZpeHR1cmUoXG4gICAgZml4dHVyZTogRml4dHVyZVJlY29yZCxcbiAgICBpbnNlcnRlZElkc0J5VGFibGU/OiBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBudW1iZXIgfCBzdHJpbmc+PixcbiAgKTogVUJSZWYge1xuICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmUuZW50aXR5SWQpO1xuICAgIGNvbnN0IHJvdzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcblxuICAgIC8vIE92ZXJyaWRlIOuqqOuTnCDtjJDri6g6IHRhcmdldCDrmJDripQgdW5pcXVl6rCAIOyeiOqzoCBvdmVycmlkZT10cnVl7J24IOqyveyasFxuICAgIGNvbnN0IGV4aXN0aW5nUmVjb3JkID0gZml4dHVyZS50YXJnZXQgPz8gZml4dHVyZS51bmlxdWU7XG4gICAgY29uc3QgaXNPdmVycmlkZU1vZGUgPSBmaXh0dXJlLm92ZXJyaWRlICYmIGV4aXN0aW5nUmVjb3JkO1xuXG4gICAgZm9yIChjb25zdCBbcHJvcE5hbWUsIGNvbHVtbl0gb2YgT2JqZWN0LmVudHJpZXMoZml4dHVyZS5jb2x1bW5zKSkge1xuICAgICAgY29uc3QgcHJvcCA9IGNvbHVtbi5wcm9wO1xuXG4gICAgICBpZiAoaXNWaXJ0dWFsUHJvcChwcm9wKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gR2VuZXJhdGVkIGNvbHVtbuydgCBJTlNFUlTsl5DshJwg7KCc7Jm4IChEQuqwgCDsnpDrj5kg7IOd7ISxKVxuICAgICAgaWYgKFwiZ2VuZXJhdGVkXCIgaW4gcHJvcCAmJiBwcm9wLmdlbmVyYXRlZCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gaWQg7LKY66asXG4gICAgICBpZiAocHJvcE5hbWUgPT09IFwiaWRcIikge1xuICAgICAgICBjb25zdCBpZFByb3AgPSBlbnRpdHkucHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBcImlkXCIpO1xuICAgICAgICAvLyBwYXJlbnRJZCDsl5Tti7Dti7DsnZggaWTripQg67aA66qoIOyXlO2LsO2LsOydmCBGS+ydtOuvgOuhnCDsi5ztgIDsiqQg66+47IKs7JqpICjrqoXsi5zsoIHsnLzroZwg7Y+s7ZWoKVxuICAgICAgICBjb25zdCB1c2VzU2VxdWVuY2UgPVxuICAgICAgICAgICFlbnRpdHkucGFyZW50SWQgJiZcbiAgICAgICAgICAoaWRQcm9wPy50eXBlID09PSBcImludGVnZXJcIiB8fFxuICAgICAgICAgICAgaWRQcm9wPy50eXBlID09PSBcImJpZ0ludGVnZXJcIiB8fFxuICAgICAgICAgICAgaWRQcm9wPy5jb25lPy5maXh0dXJlU3RyYXRlZ3kgPT09IFwic2VxdWVuY2VcIik7XG5cbiAgICAgICAgaWYgKGlzT3ZlcnJpZGVNb2RlICYmIGV4aXN0aW5nUmVjb3JkKSB7XG4gICAgICAgICAgLy8gT3ZlcnJpZGU6IOq4sOyhtCDroIjsvZTrk5zsnZgg6rCSIOyCrOyaqSDihpIgVVBEQVRFXG4gICAgICAgICAgcm93W3Byb3BOYW1lXSA9IGV4aXN0aW5nUmVjb3JkLmNvbHVtbnNbcHJvcE5hbWVdPy52YWx1ZTtcbiAgICAgICAgfSBlbHNlIGlmICghdXNlc1NlcXVlbmNlKSB7XG4gICAgICAgICAgLy8gc3RyaW5nIFBLIOuYkOuKlCBwYXJlbnRJZCDsl5Tti7Dti7AgRks6IOyDneyEseuQnCBpZCDqsJLsnYQgSU5TRVJU7JeQIO2PrO2VqFxuICAgICAgICAgIHJvd1twcm9wTmFtZV0gPSBjb2x1bW4udmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaW50ZWdlci9iaWdJbnRlZ2VyIFBLOiBEQiDsi5ztgIDsiqTsl5Ag66eh6rmAICjqsJIg7KCc7Jm4KVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzUmVsYXRpb25Qcm9wKHByb3ApKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBpc0JlbG9uZ3NUb09uZVJlbGF0aW9uUHJvcChwcm9wKSB8fFxuICAgICAgICAgIChpc09uZVRvT25lUmVsYXRpb25Qcm9wKHByb3ApICYmIHByb3AuaGFzSm9pbkNvbHVtbilcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgcmVsYXRlZElkID0gY29sdW1uLnZhbHVlIGFzIG51bWJlciB8IG51bGw7XG4gICAgICAgICAgaWYgKHJlbGF0ZWRJZCAhPT0gbnVsbCAmJiByZWxhdGVkSWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY29uc3QgcmVsYXRlZEZpeHR1cmVJZCA9IGAke3Byb3Aud2l0aH0jJHtyZWxhdGVkSWR9YDtcblxuICAgICAgICAgICAgLy8g66i87KCAIHNraXDrkJwgZml4dHVyZeyduOyngCDtmZXsnbhcbiAgICAgICAgICAgIGNvbnN0IHNraXBwZWRFeGlzdGluZ0lkID0gdGhpcy5za2lwcGVkRml4dHVyZXMuZ2V0KHJlbGF0ZWRGaXh0dXJlSWQpPy5leGlzdGluZ0lkO1xuICAgICAgICAgICAgaWYgKHNraXBwZWRFeGlzdGluZ0lkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgLy8gc2tpcOuQnCBmaXh0dXJlIOKGkiB0YXJnZXQgRELsnZgg6riw7KG0IOugiOy9lOuTnCBpZCDsgqzsmqlcbiAgICAgICAgICAgICAgcm93W2Ake3Byb3BOYW1lfV9pZGBdID0gc2tpcHBlZEV4aXN0aW5nSWQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb25zdCByZWxhdGVkUmVmID0gdGhpcy5maXh0dXJlUmVmTWFwLmdldChyZWxhdGVkRml4dHVyZUlkKTtcbiAgICAgICAgICAgICAgaWYgKHJlbGF0ZWRSZWYpIHtcbiAgICAgICAgICAgICAgICAvLyDsnbTrr7ggdXBzZXJ065CcIOqwmeydgCDthYzsnbTruJQgZml4dHVyZSDtmZXsnbhcbiAgICAgICAgICAgICAgICBjb25zdCByZWxhdGVkRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocHJvcC53aXRoKTtcbiAgICAgICAgICAgICAgICBjb25zdCByZWxhdGVkSW5zZXJ0ZWRJZHMgPSBpbnNlcnRlZElkc0J5VGFibGU/LmdldChyZWxhdGVkRW50aXR5LnRhYmxlKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhY3R1YWxJZCA9IHJlbGF0ZWRJbnNlcnRlZElkcz8uZ2V0KHJlbGF0ZWRSZWYudXVpZCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoYWN0dWFsSWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgLy8g7J2066+4IHVwc2VydOuQqCDihpIg7Iuk7KCcIElEIOyCrOyaqVxuICAgICAgICAgICAgICAgICAgcm93W2Ake3Byb3BOYW1lfV9pZGBdID0gYWN0dWFsSWQ7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIC8vIOyVhOyngSB1cHNlcnQg7JWI65CoIOKGkiBVQlJlZiDsgqzsmqlcbiAgICAgICAgICAgICAgICAgIHJvd1tgJHtwcm9wTmFtZX1faWRgXSA9IHJlbGF0ZWRSZWY7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGZpeHR1cmVz7JeQIO2PrO2VqOuQmOyngCDslYrsnYAg66CI7L2U65OcIOKGkiBJRCDqt7jrjIDroZwg7IKs7JqpXG4gICAgICAgICAgICAgICAgcm93W2Ake3Byb3BOYW1lfV9pZGBdID0gcmVsYXRlZElkO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJvd1tgJHtwcm9wTmFtZX1faWRgXSA9IG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIEhhc01hbnksIE1hbnlUb01hbnnripQg67OE64+EIOyymOumrFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8g7J2867CYIOy7rOufvFxuICAgICAgICByb3dbcHJvcE5hbWVdID0gdGhpcy5jb252ZXJ0Q29sdW1uVmFsdWUocHJvcCBhcyBFbnRpdHlQcm9wLCBjb2x1bW4udmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgICFpc1Rlc3QoKSAmJlxuICAgICAgY29uc29sZS5sb2coY2hhbGsuYmx1ZShgUmVnaXN0ZXJpbmcgJHtlbnRpdHkudGFibGV9IC0gJHtpbnNwZWN0KHJvdywgZmFsc2UsIG51bGwsIHRydWUpfWApKTtcbiAgICBjb25zdCByZWYgPSB0aGlzLmJ1aWxkZXIucmVnaXN0ZXIoZW50aXR5LnRhYmxlLCByb3cpO1xuICAgIHRoaXMuZml4dHVyZVJlZk1hcC5zZXQoZml4dHVyZS5maXh0dXJlSWQsIHJlZik7XG5cbiAgICByZXR1cm4gcmVmO1xuICB9XG5cbiAgLyoqXG4gICAqIOy7rOufvCDqsJIg67OA7ZmYXG4gICAqL1xuICBwcml2YXRlIGNvbnZlcnRDb2x1bW5WYWx1ZShwcm9wOiBFbnRpdHlQcm9wLCB2YWx1ZTogdW5rbm93bik6IHVua25vd24ge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHByb3AudHlwZSkge1xuICAgICAgY2FzZSBcImpzb25cIjpcbiAgICAgICAgLy8gVXBzZXJ0QnVpbGRlci5yZWdpc3RlcuyXkOyEnCBKU09OLnN0cmluZ2lmeSDsspjrpqztlZjrr4DroZwgb2JqZWN0IOq3uOuMgOuhnCDsoITri6xcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuXG4gICAgICBjYXNlIFwiZGF0ZVwiOlxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiIHx8IHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgIHJldHVybiBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBwcm9jZXNzTWFueVRvTWFueVJlbGF0aW9ucyhcbiAgICB0cng6IEtuZXguVHJhbnNhY3Rpb24sXG4gICAgZml4dHVyZXM6IEZpeHR1cmVSZWNvcmRbXSxcbiAgICBpbnNlcnRlZElkc0J5VGFibGU6IE1hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz4+LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBmb3IgKGNvbnN0IGZpeHR1cmUgb2YgZml4dHVyZXMpIHtcbiAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmUuZW50aXR5SWQpO1xuICAgICAgY29uc3Qgc291cmNlUmVmID0gdGhpcy5maXh0dXJlUmVmTWFwLmdldChmaXh0dXJlLmZpeHR1cmVJZCk7XG5cbiAgICAgIGlmICghc291cmNlUmVmKSBjb250aW51ZTtcblxuICAgICAgY29uc3Qgc291cmNlVXVpZFRvSWQgPSBpbnNlcnRlZElkc0J5VGFibGUuZ2V0KGVudGl0eS50YWJsZSk7XG4gICAgICBjb25zdCBzb3VyY2VJZCA9IHNvdXJjZVV1aWRUb0lkPy5nZXQoc291cmNlUmVmLnV1aWQpO1xuXG4gICAgICBpZiAoc291cmNlSWQgPT09IHVuZGVmaW5lZCkgY29udGludWU7XG5cbiAgICAgIGZvciAoY29uc3QgWywgY29sdW1uXSBvZiBPYmplY3QuZW50cmllcyhmaXh0dXJlLmNvbHVtbnMpKSB7XG4gICAgICAgIGNvbnN0IHByb3AgPSBjb2x1bW4ucHJvcDtcblxuICAgICAgICBpZiAoaXNNYW55VG9NYW55UmVsYXRpb25Qcm9wKHByb3ApICYmIEFycmF5LmlzQXJyYXkoY29sdW1uLnZhbHVlKSkge1xuICAgICAgICAgIC8vIOyEoO2DneuQmOyngCDslYrsnYAgTWFueVRvTWFueSDqtIDqs4TripQg7KCA7J6l7ZWY7KeAIOyViuydjFxuICAgICAgICAgIGNvbnN0IHRhcmdldFRhYmxlID0gRW50aXR5TWFuYWdlci5nZXQocHJvcC53aXRoKTtcbiAgICAgICAgICBpZiAoIXRoaXMuYnVpbGRlci5oYXNUYWJsZSh0YXJnZXRUYWJsZS50YWJsZSkpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgY29uc3QgcmVsYXRlZElkcyA9IGNvbHVtbi52YWx1ZSBhcyBudW1iZXJbXTtcbiAgICAgICAgICBpZiAocmVsYXRlZElkcy5sZW5ndGggPT09IDApIGNvbnRpbnVlO1xuXG4gICAgICAgICAgY29uc3Qgam9pblRhYmxlID0gcHJvcC5qb2luVGFibGU7XG4gICAgICAgICAgY29uc3QgcmVsYXRlZEVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KHByb3Aud2l0aCk7XG5cbiAgICAgICAgICBjb25zdCBzb3VyY2VDb2x1bW4gPSBgJHtpbmZsZWN0aW9uLnNpbmd1bGFyaXplKGVudGl0eS50YWJsZSl9X2lkYDtcbiAgICAgICAgICBjb25zdCB0YXJnZXRDb2x1bW4gPSBgJHtpbmZsZWN0aW9uLnNpbmd1bGFyaXplKHJlbGF0ZWRFbnRpdHkudGFibGUpfV9pZGA7XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IHJlbGF0ZWRJZCBvZiByZWxhdGVkSWRzKSB7XG4gICAgICAgICAgICBjb25zdCByZWxhdGVkRml4dHVyZUlkID0gYCR7cHJvcC53aXRofSMke3JlbGF0ZWRJZH1gO1xuICAgICAgICAgICAgY29uc3QgcmVsYXRlZFJlZiA9IHRoaXMuZml4dHVyZVJlZk1hcC5nZXQocmVsYXRlZEZpeHR1cmVJZCk7XG5cbiAgICAgICAgICAgIGxldCB0YXJnZXRJZDogbnVtYmVyIHwgc3RyaW5nO1xuXG4gICAgICAgICAgICBpZiAocmVsYXRlZFJlZikge1xuICAgICAgICAgICAgICBjb25zdCByZWxhdGVkVXVpZFRvSWQgPSBpbnNlcnRlZElkc0J5VGFibGUuZ2V0KHJlbGF0ZWRFbnRpdHkudGFibGUpO1xuICAgICAgICAgICAgICBjb25zdCByZXNvbHZlZElkID0gcmVsYXRlZFV1aWRUb0lkPy5nZXQocmVsYXRlZFJlZi51dWlkKTtcblxuICAgICAgICAgICAgICBpZiAocmVzb2x2ZWRJZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICAgYFJlbGF0ZWQgZml4dHVyZSAke3JlbGF0ZWRGaXh0dXJlSWR9IG5vdCBmb3VuZCBpbiBpbnNlcnRlZElkcywgc2tpcHBpbmdgLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGFyZ2V0SWQgPSByZXNvbHZlZElkO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGFyZ2V0SWQgPSByZWxhdGVkSWQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEpvaW5UYWJsZeyXkCDsgr3snoVcbiAgICAgICAgICAgIGNvbnN0IFtmb3VuZF0gPSBhd2FpdCB0cngoam9pblRhYmxlKVxuICAgICAgICAgICAgICAud2hlcmUoe1xuICAgICAgICAgICAgICAgIFtzb3VyY2VDb2x1bW5dOiBzb3VyY2VJZCxcbiAgICAgICAgICAgICAgICBbdGFyZ2V0Q29sdW1uXTogdGFyZ2V0SWQsXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC5saW1pdCgxKTtcblxuICAgICAgICAgICAgaWYgKCFmb3VuZCkge1xuICAgICAgICAgICAgICBhd2FpdCB0cngoam9pblRhYmxlKS5pbnNlcnQoe1xuICAgICAgICAgICAgICAgIFtzb3VyY2VDb2x1bW5dOiBzb3VyY2VJZCxcbiAgICAgICAgICAgICAgICBbdGFyZ2V0Q29sdW1uXTogdGFyZ2V0SWQsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICFpc1Rlc3QoKSAmJlxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgY2hhbGsuZ3JlZW4oXG4gICAgICAgICAgICAgICAgICAgIGBJbnNlcnRlZCBpbnRvICR7am9pblRhYmxlfTogJHtlbnRpdHkudGFibGV9KCR7c291cmNlSWR9KSAtICR7cmVsYXRlZEVudGl0eS50YWJsZX0oJHt0YXJnZXRJZH0pYCxcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog6rCZ7J2AIO2FjOydtOu4lCDrgrQgZml4dHVyZeuTpOydhCBzZWxmLXJlZmVyZW5jZSDroIjrsqjrs4TroZwg67aE7ZWgXG4gICAqIC0gc2VsZi1yZWZlcmVuY2XqsIAg7JeG64qUIGZpeHR1cmXrk6Q6IExldmVsIDBcbiAgICogLSBMZXZlbCAw7J2EIOywuOyhsO2VmOuKlCBmaXh0dXJl65OkOiBMZXZlbCAxXG4gICAqIC0g67CY67O1XG4gICAqXG4gICAqIFVwc2VydEJ1aWxkZXLqsIAgc2VsZi1yZWZlcmVuY2XqsIAg7J6I7Jy866m0IGJ1aWxkSW5zZXJ0TGV2ZWxzKCnroZwg7J6s7KCV66Cs7ZWY7JesXG4gICAqIOuTseuhnSDsiJzshJzsmYAg67CY7ZmYIOyInOyEnOqwgCDri6zrnbzsp4gg7IiYIOyeiOyKteuLiOuLpC5cbiAgICog7J2066W8IOuwqeyngO2VmOq4sCDsnITtlbQgRml4dHVyZU1hbmFnZXLqsIAg66CI67Ko67OE66GcIOuCmOuIoOyEnCDsspjrpqztlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGdyb3VwRml4dHVyZXNCeUxldmVsKGZpeHR1cmVzOiBGaXh0dXJlUmVjb3JkW10pOiBGaXh0dXJlUmVjb3JkW11bXSB7XG4gICAgaWYgKGZpeHR1cmVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmVzWzBdLmVudGl0eUlkKTtcblxuICAgIC8vIHNlbGYtcmVmZXJlbmNlIHJlbGF0aW9uIHByb3Ag7LC+6riwXG4gICAgY29uc3Qgc2VsZlJlZlByb3BzID0gZW50aXR5LnByb3BzLmZpbHRlcihcbiAgICAgIChwKTogcCBpcyBCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AgfCBPbmVUb09uZVJlbGF0aW9uUHJvcCA9PlxuICAgICAgICBpc1JlbGF0aW9uUHJvcChwKSAmJlxuICAgICAgICAoaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocCkgfHwgKGlzT25lVG9PbmVSZWxhdGlvblByb3AocCkgJiYgcC5oYXNKb2luQ29sdW1uKSkgJiZcbiAgICAgICAgcC53aXRoID09PSBlbnRpdHkuaWQsXG4gICAgKTtcblxuICAgIGlmIChzZWxmUmVmUHJvcHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBzZWxmLXJlZmVyZW5jZSDsl4bsnYwg4oaSIOuLqOydvCDroIjrsqhcbiAgICAgIHJldHVybiBbZml4dHVyZXNdO1xuICAgIH1cblxuICAgIC8vIOugiOuyqOuzhCDrtoTtlaAgKHRvcG9sb2dpY2FsIHNvcnQpXG4gICAgY29uc3QgbGV2ZWxzOiBGaXh0dXJlUmVjb3JkW11bXSA9IFtdO1xuICAgIGNvbnN0IHJlbWFpbmluZyA9IG5ldyBTZXQoZml4dHVyZXMubWFwKChmKSA9PiBmLmZpeHR1cmVJZCkpO1xuICAgIGNvbnN0IHByb2Nlc3NlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgd2hpbGUgKHJlbWFpbmluZy5zaXplID4gMCkge1xuICAgICAgY29uc3QgY3VycmVudExldmVsOiBGaXh0dXJlUmVjb3JkW10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBmaXh0dXJlIG9mIGZpeHR1cmVzKSB7XG4gICAgICAgIGlmICghcmVtYWluaW5nLmhhcyhmaXh0dXJlLmZpeHR1cmVJZCkpIGNvbnRpbnVlO1xuXG4gICAgICAgIC8vIHNlbGYtcmVmZXJlbmNl6rCAIOuqqOuRkCDsnbTrr7gg7LKY66as65CQ6rGw64KYIG51bGzsnbgg6rK97JqwXG4gICAgICAgIGNvbnN0IGNhblByb2Nlc3MgPSBzZWxmUmVmUHJvcHMuZXZlcnkoKHByb3ApID0+IHtcbiAgICAgICAgICBjb25zdCByZWZJZCA9IGZpeHR1cmUuY29sdW1uc1twcm9wLm5hbWVdPy52YWx1ZSBhcyBudW1iZXIgfCBudWxsO1xuICAgICAgICAgIGlmIChyZWZJZCA9PT0gbnVsbCB8fCByZWZJZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICBjb25zdCByZWZGaXh0dXJlSWQgPSBgJHtwcm9wLndpdGh9IyR7cmVmSWR9YDtcbiAgICAgICAgICAvLyDsnbTrr7gg7LKY66as65CQ6rGw64KYLCDtmITsnqwgZml4dHVyZXPsl5Ag7Y+s7ZWo65CY7KeAIOyViuydgCDqsr3smrAgKOyZuOu2gCDssLjsobApXG4gICAgICAgICAgcmV0dXJuIHByb2Nlc3NlZC5oYXMocmVmRml4dHVyZUlkKSB8fCAhcmVtYWluaW5nLmhhcyhyZWZGaXh0dXJlSWQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoY2FuUHJvY2Vzcykge1xuICAgICAgICAgIGN1cnJlbnRMZXZlbC5wdXNoKGZpeHR1cmUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChjdXJyZW50TGV2ZWwubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnN0IHJlbWFpbmluZ0lkcyA9IEFycmF5LmZyb20ocmVtYWluaW5nKS5qb2luKFwiLCBcIik7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgQ2lyY3VsYXIgc2VsZi1yZWZlcmVuY2UgZGV0ZWN0ZWQgaW4gJHtlbnRpdHkudGFibGV9LiBSZW1haW5pbmcgZml4dHVyZXM6ICR7cmVtYWluaW5nSWRzfWAsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgZml4dHVyZSBvZiBjdXJyZW50TGV2ZWwpIHtcbiAgICAgICAgcmVtYWluaW5nLmRlbGV0ZShmaXh0dXJlLmZpeHR1cmVJZCk7XG4gICAgICAgIHByb2Nlc3NlZC5hZGQoZml4dHVyZS5maXh0dXJlSWQpO1xuICAgICAgfVxuXG4gICAgICBsZXZlbHMucHVzaChjdXJyZW50TGV2ZWwpO1xuICAgIH1cblxuICAgIHJldHVybiBsZXZlbHM7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNoZWNrVW5pcXVlVmlvbGF0aW9uKGRiOiBLbmV4LCBlbnRpdHk6IEVudGl0eSwgZml4dHVyZTogRml4dHVyZVJlY29yZCkge1xuICAgIGNvbnN0IF91bmlxdWVJbmRleGVzID0gZW50aXR5LmluZGV4ZXM/LmZpbHRlcigoaSkgPT4gaS50eXBlID09PSBcInVuaXF1ZVwiKSA/PyBbXTtcblxuICAgIGNvbnN0IHVuaXF1ZUluZGV4ZXMgPSBfdW5pcXVlSW5kZXhlcy5maWx0ZXIoKGluZGV4KSA9PlxuICAgICAgaW5kZXguY29sdW1ucy5ldmVyeSgoY29sdW1uKSA9PiAhY29sdW1uLm5hbWUuc3RhcnRzV2l0aChgJHtlbnRpdHkudGFibGV9X19gKSksXG4gICAgKTtcbiAgICBpZiAodW5pcXVlSW5kZXhlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGxldCB1bmlxdWVRdWVyeSA9IGRiKGVudGl0eS50YWJsZSk7XG4gICAgbGV0IGhhc0NvbmRpdGlvbiA9IGZhbHNlO1xuXG4gICAgZm9yIChjb25zdCBpbmRleCBvZiB1bmlxdWVJbmRleGVzKSB7XG4gICAgICAvLyDsu6zrn7wg7KSRIO2VmOuCmOudvOuPhCBudWxs7J2066m0IOycoOuLiO2BrCDsoJzslb3snYQg7JyE67CY7ZWY7KeAIOyViuq4sCDrlYzrrLjsl5Ag7ZW064u5IOyduOuNseyKpOuKlCDrrLTsi5xcbiAgICAgIGNvbnN0IGNvbnRhaW5zTnVsbCA9IGluZGV4LmNvbHVtbnMuc29tZSgoY29sdW1uKSA9PiB7XG4gICAgICAgIGNvbnN0IGZpZWxkID0gY29sdW1uLm5hbWUucmVwbGFjZSgvX2lkJC8sIFwiXCIpO1xuICAgICAgICByZXR1cm4gZml4dHVyZS5jb2x1bW5zW2ZpZWxkXT8udmFsdWUgPT09IG51bGw7XG4gICAgICB9KTtcbiAgICAgIGlmIChjb250YWluc051bGwpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHVuaXF1ZVF1ZXJ5ID0gdW5pcXVlUXVlcnkub3JXaGVyZSgocWIpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBjb2x1bW4gb2YgaW5kZXguY29sdW1ucykge1xuICAgICAgICAgIGNvbnN0IGZpZWxkID0gY29sdW1uLm5hbWUucmVwbGFjZSgvX2lkJC8sIFwiXCIpO1xuXG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZml4dHVyZS5jb2x1bW5zW2ZpZWxkXT8udmFsdWUpKSB7XG4gICAgICAgICAgICBxYi53aGVyZUluKGNvbHVtbi5uYW1lLCBmaXh0dXJlLmNvbHVtbnNbZmllbGRdLnZhbHVlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcWIuYW5kV2hlcmUoY29sdW1uLm5hbWUsIGZpeHR1cmUuY29sdW1uc1tmaWVsZF0/LnZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaGFzQ29uZGl0aW9uID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoIWhhc0NvbmRpdGlvbikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgW3VuaXF1ZUZvdW5kXSA9IGF3YWl0IHVuaXF1ZVF1ZXJ5O1xuICAgIHJldHVybiB1bmlxdWVGb3VuZDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY2hlY2tEdXBsaWNhdGVCeUNvbHVtbnMoXG4gICAgZGI6IEtuZXgsXG4gICAgZW50aXR5OiBFbnRpdHksXG4gICAgZml4dHVyZTogRml4dHVyZVJlY29yZCxcbiAgICBjb2x1bW5zOiBzdHJpbmdbXSxcbiAgKSB7XG4gICAgaWYgKGNvbHVtbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCB3aGVyZUNsYXVzZTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcblxuICAgIGZvciAoY29uc3QgY29sdW1uIG9mIGNvbHVtbnMpIHtcbiAgICAgIC8vIHJlbGF0aW9uIO2VhOuTnOyduCDqsr3smrAgX2lkIOu2meydtOq4sFxuICAgICAgY29uc3QgcHJvcCA9IGVudGl0eS5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IGNvbHVtbik7XG4gICAgICBjb25zdCBkYkNvbHVtbiA9IHByb3AgJiYgaXNSZWxhdGlvblByb3AocHJvcCkgPyBgJHtjb2x1bW59X2lkYCA6IGNvbHVtbjtcbiAgICAgIGNvbnN0IHZhbHVlID0gZml4dHVyZS5jb2x1bW5zW2NvbHVtbl0/LnZhbHVlO1xuXG4gICAgICAvLyBudWxsIOqwkuydtCDtj6ztlajrkJwg6rK97JqwIOykkeuztSDtmZXsnbgg7Iqk7YK1XG4gICAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgd2hlcmVDbGF1c2VbZGJDb2x1bW5dID0gdmFsdWU7XG4gICAgfVxuXG4gICAgY29uc3QgW2ZvdW5kXSA9IGF3YWl0IGRiKGVudGl0eS50YWJsZSkud2hlcmUod2hlcmVDbGF1c2UpLmxpbWl0KDEpO1xuICAgIHJldHVybiBmb3VuZDtcbiAgfVxuXG4gIGFzeW5jIGFkZEZpeHR1cmVMb2FkZXIoY29kZTogc3RyaW5nKSB7XG4gICAgY29uc3QgcGF0aCA9IGAke1NvbmFtdS5hcGlSb290UGF0aH0vc3JjL3Rlc3RpbmcvZml4dHVyZS50c2A7XG4gICAgY29uc3QgY29udGVudCA9IHJlYWRGaWxlU3luYyhwYXRoKS50b1N0cmluZygpO1xuXG4gICAgY29uc3QgZml4dHVyZUxvYWRlclN0YXJ0ID0gY29udGVudC5pbmRleE9mKFwiY29uc3QgZml4dHVyZUxvYWRlciA9IHtcIik7XG4gICAgY29uc3QgZml4dHVyZUxvYWRlckVuZCA9IGNvbnRlbnQuaW5kZXhPZihcIn07XCIsIGZpeHR1cmVMb2FkZXJTdGFydCk7XG5cbiAgICBpZiAoZml4dHVyZUxvYWRlclN0YXJ0ICE9PSAtMSAmJiBmaXh0dXJlTG9hZGVyRW5kICE9PSAtMSkge1xuICAgICAgY29uc3QgbmV3Q29udGVudCA9IGAke2NvbnRlbnQuc2xpY2UoMCwgZml4dHVyZUxvYWRlckVuZCl9ICAke2NvZGV9XFxuJHtjb250ZW50LnNsaWNlKGZpeHR1cmVMb2FkZXJFbmQpfWA7XG5cbiAgICAgIHdyaXRlRmlsZVN5bmMocGF0aCwgbmV3Q29udGVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkZhaWxlZCB0byBmaW5kIGZpeHR1cmVMb2FkZXIgaW4gZml4dHVyZS50c1wiKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IEZpeHR1cmVNYW5hZ2VyID0gbmV3IEZpeHR1cmVNYW5hZ2VyQ2xhc3MoKTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Y0FVdUM7a0JBQ1k7WUFFRztzQkFDSztzQkFHRjthQVFqQztrQkFVcUI7dUJBQ0s7Q0FTckMsc0JBQWIsTUFBaUM7RUFDL0IsQUFBUSxPQUFvQjtFQUM1QixJQUFJLElBQUksS0FBVztBQUNqQixRQUFLLE9BQU87O0VBRWQsSUFBSSxNQUFZO0FBQ2QsT0FBSSxLQUFLLFNBQVMsTUFBTTtBQUN0QixVQUFNLElBQUksTUFBTSwwQ0FBMEM7O0FBRTVELFVBQU8sS0FBSzs7RUFHZCxBQUFRLE9BQW9CO0VBQzVCLElBQUksSUFBSSxLQUFXO0FBQ2pCLFFBQUssT0FBTzs7RUFFZCxJQUFJLE1BQVk7QUFDZCxPQUFJLEtBQUssU0FBUyxNQUFNO0FBQ3RCLFVBQU0sSUFBSSxNQUFNLDBDQUEwQzs7QUFFNUQsVUFBTyxLQUFLOztFQUVkLG1CQUFvQztFQUVwQyxBQUFRLGdCQUFnQixJQUFJLGVBQWU7RUFHM0MsQUFBUSxVQUF5QixJQUFJLGVBQWU7RUFDcEQsQUFBUSxnQkFBb0MsSUFBSSxLQUFLO0VBQ3JELEFBQVEsa0JBQ04sSUFBSSxLQUFLO0VBRVgsT0FBTztBQUNMLE9BQUksS0FBSyxTQUFTLE1BQU07QUFDdEI7O0FBRUYsT0FBSSxPQUFPLFNBQVMsUUFBUSxPQUFPLFNBQVMsbUJBQW1CO0lBQzdELE1BQU0s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
617
+
618
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4dHVyZS1tYW5hZ2VyLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0aW5nL2ZpeHR1cmUtbWFuYWdlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gXCJhc3NlcnRcIjtcbmltcG9ydCB7IGV4ZWNTeW5jIH0gZnJvbSBcImNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IHJlYWRGaWxlU3luYywgd3JpdGVGaWxlU3luYyB9IGZyb20gXCJmc1wiO1xuaW1wb3J0IHsgaW5zcGVjdCB9IGZyb20gXCJ1dGlsXCI7XG5cbmltcG9ydCBjaGFsayBmcm9tIFwiY2hhbGtcIjtcbmltcG9ydCBpbmZsZWN0aW9uIGZyb20gXCJpbmZsZWN0aW9uXCI7XG5pbXBvcnQgeyB0eXBlIEtuZXggfSBmcm9tIFwia25leFwiO1xuaW1wb3J0IHsgdW5pcXVlIH0gZnJvbSBcInJhZGFzaGlcIjtcblxuaW1wb3J0IHsgU29uYW11IH0gZnJvbSBcIi4uL2FwaS9zb25hbXVcIjtcbmltcG9ydCB7IEJhc2VNb2RlbCB9IGZyb20gXCIuLi9kYXRhYmFzZS9iYXNlLW1vZGVsXCI7XG5pbXBvcnQgeyB0eXBlIFNvbmFtdURCQ29uZmlnIH0gZnJvbSBcIi4uL2RhdGFiYXNlL2RiXCI7XG5pbXBvcnQgeyBjcmVhdGVLbmV4SW5zdGFuY2UgfSBmcm9tIFwiLi4vZGF0YWJhc2Uva25leFwiO1xuaW1wb3J0IHsgVXBzZXJ0QnVpbGRlciB9IGZyb20gXCIuLi9kYXRhYmFzZS91cHNlcnQtYnVpbGRlclwiO1xuaW1wb3J0IHsgdHlwZSBVQlJlZiB9IGZyb20gXCIuLi9kYXRhYmFzZS91cHNlcnQtYnVpbGRlclwiO1xuaW1wb3J0IHsgdHlwZSBFbnRpdHkgfSBmcm9tIFwiLi4vZW50aXR5L2VudGl0eVwiO1xuaW1wb3J0IHsgRW50aXR5TWFuYWdlciB9IGZyb20gXCIuLi9lbnRpdHkvZW50aXR5LW1hbmFnZXJcIjtcbmltcG9ydCB7XG4gIGlzQmVsb25nc1RvT25lUmVsYXRpb25Qcm9wLFxuICBpc0hhc01hbnlSZWxhdGlvblByb3AsXG4gIGlzTWFueVRvTWFueVJlbGF0aW9uUHJvcCxcbiAgaXNPbmVUb09uZVJlbGF0aW9uUHJvcCxcbiAgaXNSZWxhdGlvblByb3AsXG4gIGlzVmlydHVhbFByb3AsXG59IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHtcbiAgdHlwZSBCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AsXG4gIHR5cGUgRGF0YWJhc2VTY2hlbWFFeHRlbmQsXG4gIHR5cGUgRW50aXR5UHJvcCxcbiAgdHlwZSBGaXh0dXJlSW1wb3J0UmVzdWx0LFxuICB0eXBlIEZpeHR1cmVSZWNvcmQsXG4gIHR5cGUgRml4dHVyZVNlYXJjaE9wdGlvbnMsXG4gIHR5cGUgT25lVG9PbmVSZWxhdGlvblByb3AsXG59IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgaXNUZXN0IH0gZnJvbSBcIi4uL3V0aWxzL2NvbnRyb2xsZXJcIjtcbmltcG9ydCB7IFJlbGF0aW9uR3JhcGggfSBmcm9tIFwiLi9fcmVsYXRpb24tZ3JhcGhcIjtcblxuLyoqIOyCrOyaqeyekCDsp4DsoJUg7KSR67O1IO2ZleyduCDsu6zrn7wgKGVudGl0eUlk67OE66GcIOyngOyglSkgKi9cbmV4cG9ydCBpbnRlcmZhY2UgRHVwbGljYXRlQ2hlY2tPcHRpb25zIHtcbiAgY29sdW1ucz86IHtcbiAgICBbZW50aXR5SWQ6IHN0cmluZ106IHN0cmluZ1tdO1xuICB9O1xufVxuXG5leHBvcnQgY2xhc3MgRml4dHVyZU1hbmFnZXJDbGFzcyB7XG4gIHByaXZhdGUgX3RkYjogS25leCB8IG51bGwgPSBudWxsO1xuICBzZXQgdGRiKHRkYjogS25leCkge1xuICAgIHRoaXMuX3RkYiA9IHRkYjtcbiAgfVxuICBnZXQgdGRiKCk6IEtuZXgge1xuICAgIGlmICh0aGlzLl90ZGIgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkZpeHR1cmVNYW5hZ2VyIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3RkYjtcbiAgfVxuXG4gIHByaXZhdGUgX2ZkYjogS25leCB8IG51bGwgPSBudWxsO1xuICBzZXQgZmRiKGZkYjogS25leCkge1xuICAgIHRoaXMuX2ZkYiA9IGZkYjtcbiAgfVxuICBnZXQgZmRiKCk6IEtuZXgge1xuICAgIGlmICh0aGlzLl9mZGIgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkZpeHR1cmVNYW5hZ2VyIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2ZkYjtcbiAgfVxuICBjYWNoZWRUYWJsZU5hbWVzOiBzdHJpbmdbXSB8IG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgcmVsYXRpb25HcmFwaCA9IG5ldyBSZWxhdGlvbkdyYXBoKCk7XG5cbiAgLy8gVXBzZXJ0QnVpbGRlciDquLDrsJggaW1wb3J066W8IOychO2VnCDsg4Htg5xcbiAgcHJpdmF0ZSBidWlsZGVyOiBVcHNlcnRCdWlsZGVyID0gbmV3IFVwc2VydEJ1aWxkZXIoKTtcbiAgcHJpdmF0ZSBmaXh0dXJlUmVmTWFwOiBNYXA8c3RyaW5nLCBVQlJlZj4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgc2tpcHBlZEZpeHR1cmVzOiBNYXA8c3RyaW5nLCB7IGVudGl0eUlkOiBzdHJpbmc7IGV4aXN0aW5nSWQ6IG51bWJlciB8IHN0cmluZyB9PiA9XG4gICAgbmV3IE1hcCgpO1xuXG4gIGluaXQoKSB7XG4gICAgaWYgKHRoaXMuX3RkYiAhPT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoU29uYW11LmRiQ29uZmlnLnRlc3QgJiYgU29uYW11LmRiQ29uZmlnLnByb2R1Y3Rpb24pIHtcbiAgICAgIGNvbnN0IHRDb25uID0gU29uYW11LmRiQ29uZmlnLnRlc3QuY29ubmVjdGlvbiBhcyBLbmV4LkNvbm5lY3Rpb25Db25maWcgJiB7XG4gICAgICAgIHBvcnQ/OiBudW1iZXI7XG4gICAgICB9O1xuICAgICAgY29uc3QgcENvbm4gPSBTb25hbXUuZGJDb25maWcucHJvZHVjdGlvbi5jb25uZWN0aW9uIGFzIEtuZXguQ29ubmVjdGlvbkNvbmZpZyAmIHtcbiAgICAgICAgcG9ydD86IG51bWJlcjtcbiAgICAgIH07XG4gICAgICBpZiAoXG4gICAgICAgIGAke3RDb25uLmhvc3QgPz8gXCJsb2NhbGhvc3RcIn06JHt0Q29ubi5wb3J0ID8/IDU0MzJ9LyR7dENvbm4uZGF0YWJhc2V9YCA9PT1cbiAgICAgICAgYCR7cENvbm4uaG9zdCA/PyBcImxvY2FsaG9zdFwifToke3BDb25uLnBvcnQgPz8gNTQzMn0vJHtwQ29ubi5kYXRhYmFzZX1gXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGDthYzsiqTtirhEQuyZgCDtlITroZzrjZXshZhEQuyXkCDrj5nsnbztlZwg642w7J207YSw67Kg7J207Iqk6rCAIOyCrOyaqeuQmOyXiOyKteuLiOuLpC5gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnRkYiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShTb25hbXUuZGJDb25maWcudGVzdCk7XG4gICAgdGhpcy5mZGIgPSBjcmVhdGVLbmV4SW5zdGFuY2UoU29uYW11LmRiQ29uZmlnLmZpeHR1cmUpO1xuICB9XG5cbiAgLyoqXG4gICAg7JuQ6rKpIGZpeHR1cmUgRELrpbwg66Gc7LusIHRlc3QgRELroZwg67O17IKs7ZWp64uI64ukLlxuICAgIHBnX2R1bXDroZwg7JuQ6rKpIERC66W8IOuNpO2UhO2VmOqzoCwgcGdfcmVzdG9yZeuhnCDroZzsu6zsl5Ag67O17JuQ7ZWp64uI64ukLlxuICAqL1xuICBhc3luYyBzeW5jKCkge1xuICAgIGNvbnN0IGZpeHR1cmVDb25uID0gU29uYW11LmRiQ29uZmlnLmZpeHR1cmUuY29ubmVjdGlvbiBhcyBLbmV4LlBnQ29ubmVjdGlvbkNvbmZpZztcbiAgICBjb25zdCB0ZXN0Q29ubiA9IFNvbmFtdS5kYkNvbmZpZy50ZXN0LmNvbm5lY3Rpb24gYXMgS25leC5QZ0Nvbm5lY3Rpb25Db25maWc7XG5cbiAgICAvLyAxLiDroZzsu6wgdGVzdCBEQiDsl7DqsrAg7KKF66OMIOuwjyDsnqzsg53shLFcbiAgICBjb25zdCB0ZXN0UGdFbnYgPSB7IFBHUEFTU1dPUkQ6IHRlc3RDb25uLnBhc3N3b3JkIHx8IFwiXCIgfTtcbiAgICBleGVjU3luYyhcbiAgICAgIGBwc3FsIC1oICR7dGVzdENvbm4uaG9zdH0gLXAgJHt0ZXN0Q29ubi5wb3J0ID8/IDU0MzJ9IC1VICR7dGVzdENvbm4udXNlcn0gLWQgcG9zdGdyZXMgLWMgXCJcbiAgICAgICAgU0VMRUNUIHBnX3Rlcm1pbmF0ZV9iYWNrZW5kKHBnX3N0YXRfYWN0aXZpdHkucGlkKVxuICAgICAgICBGUk9NIHBnX3N0YXRfYWN0aXZpdHlcbiAgICAgICAgV0hFUkUgZGF0bmFtZSA9ICcke3Rlc3RDb25uLmRhdGFiYXNlfSdcbiAgICAgICAgICBBTkQgcGlkIDw+IHBnX2JhY2tlbmRfcGlkKCk7XG4gICAgICBcImAsXG4gICAgICB7IHN0ZGlvOiBcImluaGVyaXRcIiwgZW52OiB7IC4uLnByb2Nlc3MuZW52LCAuLi50ZXN0UGdFbnYgfSBhcyBOb2RlSlMuUHJvY2Vzc0VudiB9LFxuICAgICk7XG5cbiAgICBleGVjU3luYyhcbiAgICAgIGBwc3FsIC1oICR7dGVzdENvbm4uaG9zdH0gLXAgJHt0ZXN0Q29ubi5wb3J0ID8/IDU0MzJ9IC1VICR7dGVzdENvbm4udXNlcn0gLWQgcG9zdGdyZXMgLWMgXCJEUk9QIERBVEFCQVNFIElGIEVYSVNUUyBcXFxcXCIke3Rlc3RDb25uLmRhdGFiYXNlfVxcXFxcIlwiYCxcbiAgICAgIHsgc3RkaW86IFwiaW5oZXJpdFwiLCBlbnY6IHsgLi4ucHJvY2Vzcy5lbnYsIC4uLnRlc3RQZ0VudiB9IGFzIE5vZGVKUy5Qcm9jZXNzRW52IH0sXG4gICAgKTtcblxuICAgIGV4ZWNTeW5jKFxuICAgICAgYHBzcWwgLWggJHt0ZXN0Q29ubi5ob3N0fSAtcCAke3Rlc3RDb25uLnBvcnQgPz8gNTQzMn0gLVUgJHt0ZXN0Q29ubi51c2VyfSAtZCBwb3N0Z3JlcyAtYyBcIkNSRUFURSBEQVRBQkFTRSBcXFxcXCIke3Rlc3RDb25uLmRhdGFiYXNlfVxcXFxcIlwiYCxcbiAgICAgIHsgc3RkaW86IFwiaW5oZXJpdFwiLCBlbnY6IHsgLi4ucHJvY2Vzcy5lbnYsIC4uLnRlc3RQZ0VudiB9IGFzIE5vZGVKUy5Qcm9jZXNzRW52IH0sXG4gICAgKTtcblxuICAgIC8vIDIuIOybkOqyqSBmaXh0dXJlIERCIOKGkiDroZzsu6wgdGVzdCBEQuuhnCDrs7XsgqwgKHBnX2R1bXAgfCBwZ19yZXN0b3JlKVxuICAgIGNvbnN0IGZpeHR1cmVQZ0VudiA9IHsgUEdQQVNTV09SRDogZml4dHVyZUNvbm4ucGFzc3dvcmQgfHwgXCJcIiB9O1xuICAgIGNvbnN0IGR1bXBDbWQgPSBgcGdfZHVtcCAtaCAke2ZpeHR1cmVDb25uLmhvc3R9IC1wICR7Zml4dHVyZUNvbm4ucG9ydCA/PyA1NDMyfSAtVSAke2ZpeHR1cmVDb25uLnVzZXJ9IC1kICR7Zml4dHVyZUNvbm4uZGF0YWJhc2V9IC1GY2A7XG4gICAgY29uc3QgcmVzdG9yZUNtZCA9IGBwZ19yZXN0b3JlIC1oICR7dGVzdENvbm4uaG9zdH0gLXAgJHt0ZXN0Q29ubi5wb3J0ID8/IDU0MzJ9IC1VICR7dGVzdENvbm4udXNlcn0gLWQgJHt0ZXN0Q29ubi5kYXRhYmFzZX0gLS1uby1vd25lciAtLW5vLWFjbGA7XG5cbiAgICBleGVjU3luYyhgJHtkdW1wQ21kfSB8IFBHUEFTU1dPUkQ9XCIke3Rlc3RDb25uLnBhc3N3b3JkIHx8IFwiXCJ9XCIgJHtyZXN0b3JlQ21kfWAsIHtcbiAgICAgIHN0ZGlvOiBcImluaGVyaXRcIixcbiAgICAgIGVudjogeyAuLi5wcm9jZXNzLmVudiwgLi4uZml4dHVyZVBnRW52IH0gYXMgTm9kZUpTLlByb2Nlc3NFbnYsXG4gICAgICBzaGVsbDogXCIvYmluL2Jhc2hcIixcbiAgICB9KTtcblxuICAgIC8vIDMuIOyLnO2AgOyKpCDrpqzshYsgKOuNsOydtO2EsCDrs7Xsgqwg7ZuEIOyLnO2AgOyKpOulvCBNQVgoaWQp66GcIOygleugrClcbiAgICBhd2FpdCB0aGlzLnJlc2V0U2VxdWVuY2VzKFNvbmFtdS5kYkNvbmZpZy50ZXN0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDrqqjrk6Ag7YWM7J2067iU7J2YIOyLnO2AgOyKpOulvCDtmITsnqwgTUFYKGlkKeuhnCDrpqzshYvtlanri4jri6QuXG4gICAqIGZpeHR1cmUgc3luYyDtm4Qg7Iuc7YCA7Iqk6rCAIOyLpOygnCDrjbDsnbTthLDsmYAg66ee7KeAIOyViuuKlCDrrLjsoJzrpbwg7ZW06rKw7ZWp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZXNldFNlcXVlbmNlcyhkYkNvbmZpZzogU29uYW11REJDb25maWdbXCJ0ZXN0XCJdKSB7XG4gICAgY29uc3QgdGVzdERiID0gY3JlYXRlS25leEluc3RhbmNlKGRiQ29uZmlnKTtcbiAgICBjb25zdCBlbnRpdGllcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsRW50aXRpZXMoKTtcblxuICAgIHRyeSB7XG4gICAgICBmb3IgKGNvbnN0IGVudGl0eSBvZiBlbnRpdGllcykge1xuICAgICAgICBjb25zdCB0YWJsZU5hbWUgPSBlbnRpdHkudGFibGUgfHwgZW50aXR5LmlkLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgICAgLy8gaWQg7ZWE65Oc7J2YIO2DgOyeheydhCDtmZXsnbjtlanri4jri6RcbiAgICAgICAgY29uc3QgaWRQcm9wID0gZW50aXR5LnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gXCJpZFwiKTtcbiAgICAgICAgY29uc3QgaWRUeXBlID0gaWRQcm9wPy50eXBlO1xuXG4gICAgICAgIC8vIGludGVnZXIvYmlnSW50ZWdlcuydtOqxsOuCmCwgc3RyaW5n7J207KeA66eMIGZpeHR1cmVTdHJhdGVneT1zZXF1ZW5jZeyduCDqsr3smrDsl5Drp4wg66as7IWL7ZWp64uI64ukXG4gICAgICAgIGNvbnN0IHVzZXNTZXF1ZW5jZSA9XG4gICAgICAgICAgaWRUeXBlID09PSBcImludGVnZXJcIiB8fFxuICAgICAgICAgIGlkVHlwZSA9PT0gXCJiaWdJbnRlZ2VyXCIgfHxcbiAgICAgICAgICBpZFByb3A/LmNvbmU/LmZpeHR1cmVTdHJhdGVneSA9PT0gXCJzZXF1ZW5jZVwiO1xuXG4gICAgICAgIGlmICghdXNlc1NlcXVlbmNlKSB7XG4gICAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgYFNraXBwaW5nIHNlcXVlbmNlIHJlc2V0IGZvciAke3RhYmxlTmFtZX0gKGlkIHR5cGU6ICR7aWRUeXBlIHx8IFwidW5rbm93blwifSlgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFBvc3RncmVTUUwg7Iuc7YCA7Iqk66W8IO2YhOyerCDthYzsnbTruJTsnZggTUFYKGlkKeuhnCDrpqzshYvtlanri4jri6QuXG4gICAgICAgIC8vIHN0cmluZyDtg4DsnoXsnZgg6rK97JqwIOyIq+yekCDsupDsiqTtjIXsnbQg7ZWE7JqU7ZWp64uI64ukLlxuICAgICAgICBjb25zdCBtYXhFeHByID0gaWRUeXBlID09PSBcInN0cmluZ1wiID8gXCJNQVgoaWQ6OmJpZ2ludClcIiA6IFwiTUFYKGlkKVwiO1xuICAgICAgICBhd2FpdCB0ZXN0RGIucmF3KGBcbiAgICAgICAgICBTRUxFQ1Qgc2V0dmFsKFxuICAgICAgICAgICAgcGdfZ2V0X3NlcmlhbF9zZXF1ZW5jZSgncHVibGljLiR7dGFibGVOYW1lfScsICdpZCcpLFxuICAgICAgICAgICAgQ09BTEVTQ0UoKFNFTEVDVCAke21heEV4cHJ9IEZST00gJHt0YWJsZU5hbWV9KSwgMSlcbiAgICAgICAgICApXG4gICAgICAgIGApO1xuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCB0ZXN0RGIuZGVzdHJveSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdmlzaXRlZFJlY29yZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgYXN5bmMgaW1wb3J0Rml4dHVyZShlbnRpdHlJZDogc3RyaW5nLCBpZHM6IG51bWJlcltdKSB7XG4gICAgLy8g67Cp66y4IOq4sOuhnSDstIjquLDtmZQgKOyDiOuhnOyatCBpbXBvcnQg7J6R7JeFIOyLnOyekSlcbiAgICB0aGlzLnZpc2l0ZWRSZWNvcmRzLmNsZWFyKCk7XG5cbiAgICBjb25zdCBxdWVyaWVzID0gdW5pcXVlKFxuICAgICAgKFxuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICBpZHMubWFwKGFzeW5jIChpZCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZ2V0SW1wb3J0UXVlcmllcyhlbnRpdHlJZCwgXCJpZFwiLCBpZCk7XG4gICAgICAgICAgfSksXG4gICAgICAgIClcbiAgICAgICkuZmxhdCgpLFxuICAgICk7XG5cbiAgICBjb25zdCB3ZGIgPSBCYXNlTW9kZWwuZ2V0REIoXCJ3XCIpO1xuICAgIGZvciAoY29uc3QgcXVlcnkgb2YgcXVlcmllcykge1xuICAgICAgYXdhaXQgd2RiLnJhdyhxdWVyeSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZ2V0SW1wb3J0UXVlcmllcyhlbnRpdHlJZDogc3RyaW5nLCBmaWVsZDogc3RyaW5nLCBpZDogbnVtYmVyKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IHJlY29yZEtleSA9IGAke2VudGl0eUlkfSMke2ZpZWxkfSMke2lkfWA7XG5cbiAgICAvLyDsiJztmZgg7LC47KGwIOuwqeyngDog7J2066+4IOuwqeusuO2VnCDroIjsvZTrk5zripQg7Iqk7YK1XG4gICAgaWYgKHRoaXMudmlzaXRlZFJlY29yZHMuaGFzKHJlY29yZEtleSkpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgdGhpcy52aXNpdGVkUmVjb3Jkcy5hZGQocmVjb3JkS2V5KTtcblxuICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICBjb25zdCB3ZGIgPSBCYXNlTW9kZWwuZ2V0REIoXCJ3XCIpO1xuXG4gICAgLy8g7Jes6riw7IScIOyLpERC7J2YIHJvdyDqsIDsoLjsmLRcbiAgICBjb25zdCBbcm93XSA9IGF3YWl0IHdkYihlbnRpdHkudGFibGUpLndoZXJlKGZpZWxkLCBpZCkubGltaXQoMSk7XG4gICAgaWYgKHJvdyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZW50aXR5SWR9IyR7aWR9IHJvd+ulvCDssL7snYQg7IiYIOyXhuyKteuLiOuLpC5gKTtcbiAgICB9XG5cbiAgICAvLyDtlL3siqTss5BEQiwg7IukREJcbiAgICBjb25zdCBmaXh0dXJlRGF0YWJhc2UgPSAoU29uYW11LmRiQ29uZmlnLmZpeHR1cmUuY29ubmVjdGlvbiBhcyBLbmV4LkNvbm5lY3Rpb25Db25maWcpLmRhdGFiYXNlO1xuICAgIGNvbnN0IHJlYWxEYXRhYmFzZSA9IChTb25hbXUuZGJDb25maWcucHJvZHVjdGlvbi5jb25uZWN0aW9uIGFzIEtuZXguQ29ubmVjdGlvbkNvbmZpZykuZGF0YWJhc2U7XG5cbiAgICBjb25zdCBzZWxmUXVlcnkgPSBgSU5TRVJUIElHTk9SRSBJTlRPIFxcYCR7Zml4dHVyZURhdGFiYXNlfVxcYC5cXGAke2VudGl0eS50YWJsZX1cXGAgKFNFTEVDVCAqIEZST00gXFxgJHtyZWFsRGF0YWJhc2V9XFxgLlxcYCR7ZW50aXR5LnRhYmxlfVxcYCBXSEVSRSBcXGBpZFxcYCA9ICR7aWR9KWA7XG5cbiAgICBjb25zdCBhcmdzID0gT2JqZWN0LmVudHJpZXMoZW50aXR5LnJlbGF0aW9ucylcbiAgICAgIC5maWx0ZXIoXG4gICAgICAgIChbLCByZWxhdGlvbl0pID0+XG4gICAgICAgICAgaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocmVsYXRpb24pIHx8XG4gICAgICAgICAgKGlzT25lVG9PbmVSZWxhdGlvblByb3AocmVsYXRpb24pICYmIHJlbGF0aW9uLmN1c3RvbUpvaW5DbGF1c2UgPT09IHVuZGVmaW5lZCksXG4gICAgICApXG4gICAgICAubWFwKChbLCByZWxhdGlvbl0pID0+IHtcbiAgICAgICAgLypcbiAgICAgICAgQmVsb25nc1RvT25l7J24IOqyveyasFxuICAgICAgICAgIENhdGVnb3J5IC8gJ2lkJyAvIHJvd1tjYXRlZ29yeV9pZF0g7Zi47LacXG4gICAgICAgIE9uZVRvT25l7JeQIGpvaW5Db2x1bW4gPT09IHRydWUg7J24IOqyveyasFxuICAgICAgICAgIFByb2ZpbGUgLyAnaWQnIC8gcm93W3Byb2ZpbGVfaWRdIO2YuOy2nFxuICAgICAgICBPbmVUb09uZeyXkCBqb2luQ29sdW1uID09PSBmYWxzZSDsnbgg6rK97JqwXG4gICAgICAgICAgUHJvZmlsZSAvICdwcm9maWxlX2lkJyAvIHJvd1snaWQnXSDtmLjstpxcbiAgICAgICAgKi9cbiAgICAgICAgbGV0IGZpZWxkOiBzdHJpbmc7XG4gICAgICAgIGxldCBpZDogbnVtYmVyO1xuICAgICAgICBpZiAoaXNPbmVUb09uZVJlbGF0aW9uUHJvcChyZWxhdGlvbikgJiYgIXJlbGF0aW9uLmhhc0pvaW5Db2x1bW4pIHtcbiAgICAgICAgICBjb25zdCByZWxhdGVkRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocmVsYXRpb24ud2l0aCk7XG4gICAgICAgICAgY29uc3QgcmVsYXRlZElkQ29sdW1uTmFtZSA9IHJlbGF0ZWRFbnRpdHkucHJvcHMuZmluZChcbiAgICAgICAgICAgIChwKSA9PiBpc1JlbGF0aW9uUHJvcChwKSAmJiBwLndpdGggPT09IGVudGl0eS5pZCxcbiAgICAgICAgICApPy5uYW1lO1xuICAgICAgICAgIGlmICghcmVsYXRlZElkQ29sdW1uTmFtZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3JlbGF0ZWRFbnRpdHkuaWR97J2YICR7ZW50aXR5LmlkfSDqtIDqs4Qg7ZSE66Gt7J2EIOywvuydhCDsiJgg7JeG7Iq164uI64ukLmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmaWVsZCA9IGAke3JlbGF0ZWRJZENvbHVtbk5hbWV9X2lkYDtcbiAgICAgICAgICBpZCA9IHJvdy5pZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmaWVsZCA9IFwiaWRcIjtcbiAgICAgICAgICBpZCA9IHJvd1tgJHtyZWxhdGlvbi5uYW1lfV9pZGBdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHJlbGF0aW9uLndpdGgsXG4gICAgICAgICAgZmllbGQsXG4gICAgICAgICAgaWQsXG4gICAgICAgIH07XG4gICAgICB9KVxuICAgICAgLmZpbHRlcigoYXJnKSA9PiBhcmcuaWQgIT09IG51bGwpO1xuXG4gICAgY29uc3QgcmVsUXVlcmllcyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgYXJncy5tYXAoYXN5bmMgKGFyZ3MpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0SW1wb3J0UXVlcmllcyhhcmdzLmVudGl0eUlkLCBhcmdzLmZpZWxkLCBhcmdzLmlkKTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICByZXR1cm4gWy4uLnVuaXF1ZShyZWxRdWVyaWVzLnRvUmV2ZXJzZWQoKS5mbGF0KCkpLCBzZWxmUXVlcnldO1xuICB9XG5cbiAgYXN5bmMgZGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5fdGRiKSB7XG4gICAgICBhd2FpdCB0aGlzLl90ZGIuZGVzdHJveSgpO1xuICAgICAgdGhpcy5fdGRiID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2ZkYikge1xuICAgICAgYXdhaXQgdGhpcy5fZmRiLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMuX2ZkYiA9IG51bGw7XG4gICAgfVxuICAgIGF3YWl0IEJhc2VNb2RlbC5kZXN0cm95KCk7XG4gIH1cblxuICBhc3luYyBnZXRGaXh0dXJlcyhcbiAgICBzb3VyY2VEQk5hbWU6IGtleW9mIFNvbmFtdURCQ29uZmlnLFxuICAgIHRhcmdldERCTmFtZToga2V5b2YgU29uYW11REJDb25maWcsXG4gICAgc2VhcmNoT3B0aW9uczogRml4dHVyZVNlYXJjaE9wdGlvbnMsXG4gICAgZHVwbGljYXRlQ2hlY2s/OiBEdXBsaWNhdGVDaGVja09wdGlvbnMsXG4gICkge1xuICAgIGNvbnN0IHNvdXJjZURCID0gY3JlYXRlS25leEluc3RhbmNlKFNvbmFtdS5kYkNvbmZpZ1tzb3VyY2VEQk5hbWVdKTtcbiAgICBjb25zdCB0YXJnZXREQiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShTb25hbXUuZGJDb25maWdbdGFyZ2V0REJOYW1lXSk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBlbnRpdHlJZCwgZmllbGQsIHZhbHVlLCBzZWFyY2hUeXBlIH0gPSBzZWFyY2hPcHRpb25zO1xuXG4gICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICBjb25zdCBjb2x1bW4gPVxuICAgICAgICBlbnRpdHkucHJvcHMuZmluZCgocHJvcCkgPT4gcHJvcC5uYW1lID09PSBmaWVsZCk/LnR5cGUgPT09IFwicmVsYXRpb25cIlxuICAgICAgICAgID8gYCR7ZmllbGR9X2lkYFxuICAgICAgICAgIDogZmllbGQ7XG5cbiAgICAgIGxldCBxdWVyeSA9IHNvdXJjZURCKGVudGl0eS50YWJsZSk7XG4gICAgICBpZiAoc2VhcmNoVHlwZSA9PT0gXCJlcXVhbHNcIikge1xuICAgICAgICBxdWVyeSA9IHF1ZXJ5LndoZXJlKGNvbHVtbiwgdmFsdWUpO1xuICAgICAgfSBlbHNlIGlmIChzZWFyY2hUeXBlID09PSBcImxpa2VcIikge1xuICAgICAgICBxdWVyeSA9IHF1ZXJ5LndoZXJlKGNvbHVtbiwgXCJsaWtlXCIsIGAlJHt2YWx1ZX0lYCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJvd3MgPSBhd2FpdCBxdWVyeTtcbiAgICAgIGlmIChyb3dzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyByZWNvcmRzIGZvdW5kXCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBmaXh0dXJlczogRml4dHVyZVJlY29yZFtdID0gW107XG4gICAgICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKSB7XG4gICAgICAgIGNvbnN0IGluaXRpYWxSZWNvcmRzTGVuZ3RoID0gZml4dHVyZXMubGVuZ3RoO1xuICAgICAgICBjb25zdCBuZXdSZWNvcmRzID0gYXdhaXQgdGhpcy5jcmVhdGVGaXh0dXJlUmVjb3JkKGVudGl0eSwgcm93LCB7XG4gICAgICAgICAgX2RiOiBzb3VyY2VEQixcbiAgICAgICAgfSk7XG4gICAgICAgIGZpeHR1cmVzLnB1c2goLi4ubmV3UmVjb3Jkcyk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRGaXh0dXJlUmVjb3JkID0gZml4dHVyZXMuZmluZCgocikgPT4gci5maXh0dXJlSWQgPT09IGAke2VudGl0eUlkfSMke3Jvdy5pZH1gKTtcblxuICAgICAgICBpZiAoY3VycmVudEZpeHR1cmVSZWNvcmQpIHtcbiAgICAgICAgICAvLyDtmITsnqwgZml4dHVyZeuhnOu2gO2EsCDsg53shLHrkJwgZmV0Y2hlZFJlY29yZHMg7ISk7KCVXG4gICAgICAgICAgY3VycmVudEZpeHR1cmVSZWNvcmQuZmV0Y2hlZFJlY29yZHMgPSBmaXh0dXJlc1xuICAgICAgICAgICAgLmZpbHRlcigocikgPT4gci5maXh0dXJlSWQgIT09IGN1cnJlbnRGaXh0dXJlUmVjb3JkLmZpeHR1cmVJZClcbiAgICAgICAgICAgIC5zbGljZShpbml0aWFsUmVjb3Jkc0xlbmd0aClcbiAgICAgICAgICAgIC5tYXAoKHIpID0+IHIuZml4dHVyZUlkKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGZpeHR1cmUgb2YgZml4dHVyZXMpIHtcbiAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZml4dHVyZS5lbnRpdHlJZCk7XG5cbiAgICAgICAgLy8g7IKs7Jqp7J6QIOyngOyglSDsu6zrn7wg6riw7KSAIOykkeuztSDtmZXsnbgg4oaSIHRhcmdldFxuICAgICAgICBjb25zdCBjdXN0b21Db2x1bW5zID0gZHVwbGljYXRlQ2hlY2s/LmNvbHVtbnM/LltmaXh0dXJlLmVudGl0eUlkXTtcbiAgICAgICAgaWYgKGN1c3RvbUNvbHVtbnMgJiYgY3VzdG9tQ29sdW1ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3QgY3VzdG9tRHVwbGljYXRlUm93ID0gYXdhaXQgdGhpcy5jaGVja0R1cGxpY2F0ZUJ5Q29sdW1ucyhcbiAgICAgICAgICAgIHRhcmdldERCLFxuICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgZml4dHVyZSxcbiAgICAgICAgICAgIGN1c3RvbUNvbHVtbnMsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoY3VzdG9tRHVwbGljYXRlUm93KSB7XG4gICAgICAgICAgICBjb25zdCBbcmVjb3JkXSA9IGF3YWl0IHRoaXMuY3JlYXRlRml4dHVyZVJlY29yZChlbnRpdHksIGN1c3RvbUR1cGxpY2F0ZVJvdywge1xuICAgICAgICAgICAgICBzaW5nbGVSZWNvcmQ6IHRydWUsXG4gICAgICAgICAgICAgIF9kYjogdGFyZ2V0REIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGZpeHR1cmUudGFyZ2V0ID0gcmVjb3JkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVuaXF1ZSBpbmRleCDquLDspIAg7KSR67O1IO2ZleyduCDihpIgZml4dHVyZS51bmlxdWVcbiAgICAgICAgY29uc3QgdW5pcXVlUm93ID0gYXdhaXQgdGhpcy5jaGVja1VuaXF1ZVZpb2xhdGlvbih0YXJnZXREQiwgZW50aXR5LCBmaXh0dXJlKTtcbiAgICAgICAgaWYgKHVuaXF1ZVJvdykge1xuICAgICAgICAgIGNvbnN0IFtyZWNvcmRdID0gYXdhaXQgdGhpcy5jcmVhdGVGaXh0dXJlUmVjb3JkKGVudGl0eSwgdW5pcXVlUm93LCB7XG4gICAgICAgICAgICBzaW5nbGVSZWNvcmQ6IHRydWUsXG4gICAgICAgICAgICBfZGI6IHRhcmdldERCLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGZpeHR1cmUudW5pcXVlID0gcmVjb3JkO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB1bmlxdWUoZml4dHVyZXMsIChmKSA9PiBmLmZpeHR1cmVJZCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChbdGFyZ2V0REIuZGVzdHJveSgpLCBzb3VyY2VEQi5kZXN0cm95KCldKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjcmVhdGVGaXh0dXJlUmVjb3JkKFxuICAgIGVudGl0eTogRW50aXR5LFxuICAgIHJvdzoge1xuICAgICAgaWQ6IG51bWJlciB8IHN0cmluZztcbiAgICAgIFtrZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfCBudWxsO1xuICAgIH0sXG4gICAgb3B0aW9ucz86IHtcbiAgICAgIHNpbmdsZVJlY29yZD86IGJvb2xlYW47XG4gICAgICBfZGI/OiBLbmV4O1xuICAgIH0sXG4gICk6IFByb21pc2U8Rml4dHVyZVJlY29yZFtdPiB7XG4gICAgY29uc3QgcmVjb3JkczogRml4dHVyZVJlY29yZFtdID0gW107XG4gICAgY29uc3QgdmlzaXRlZEVudGl0aWVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICBjb25zdCBjcmVhdGUgPSBhc3luYyAoXG4gICAgICBlbnRpdHk6IEVudGl0eSxcbiAgICAgIHJvdzoge1xuICAgICAgICBpZDogbnVtYmVyIHwgc3RyaW5nO1xuICAgICAgICBba2V5OiBzdHJpbmddOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHwgbnVsbDtcbiAgICAgIH0sXG4gICAgKSA9PiB7XG4gICAgICBjb25zdCBmaXh0dXJlSWQgPSBgJHtlbnRpdHkuaWR9IyR7cm93LmlkfWA7XG4gICAgICBpZiAodmlzaXRlZEVudGl0aWVzLmhhcyhmaXh0dXJlSWQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZpc2l0ZWRFbnRpdGllcy5hZGQoZml4dHVyZUlkKTtcblxuICAgICAgY29uc3QgcmVjb3JkOiBGaXh0dXJlUmVjb3JkID0ge1xuICAgICAgICBmaXh0dXJlSWQsXG4gICAgICAgIGVudGl0eUlkOiBlbnRpdHkuaWQsXG4gICAgICAgIGlkOiByb3cuaWQsXG4gICAgICAgIGNvbHVtbnM6IHt9LFxuICAgICAgICBmZXRjaGVkUmVjb3JkczogW10sXG4gICAgICAgIGJlbG9uZ3NSZWNvcmRzOiBbXSxcbiAgICAgIH07XG5cbiAgICAgIGZvciAoY29uc3QgcHJvcCBvZiBlbnRpdHkucHJvcHMpIHtcbiAgICAgICAgaWYgKGlzVmlydHVhbFByb3AocHJvcCkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlY29yZC5jb2x1bW5zW3Byb3AubmFtZV0gPSB7XG4gICAgICAgICAgcHJvcDogcHJvcCxcbiAgICAgICAgICB2YWx1ZTogcm93W3Byb3AubmFtZV0sXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZGIgPSBvcHRpb25zPy5fZGIgPz8gQmFzZU1vZGVsLmdldERCKFwid1wiKTtcbiAgICAgICAgaWYgKGlzTWFueVRvTWFueVJlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChwcm9wLndpdGgpO1xuICAgICAgICAgIGNvbnN0IHRocm91Z2hUYWJsZSA9IHByb3Auam9pblRhYmxlO1xuICAgICAgICAgIGNvbnN0IGZyb21Db2x1bW4gPSBgJHtpbmZsZWN0aW9uLnNpbmd1bGFyaXplKGVudGl0eS50YWJsZSl9X2lkYDtcbiAgICAgICAgICBjb25zdCB0b0NvbHVtbiA9IGAke2luZmxlY3Rpb24uc2luZ3VsYXJpemUocmVsYXRlZEVudGl0eS50YWJsZSl9X2lkYDtcblxuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRJZHMgPSBhd2FpdCBkYih0aHJvdWdoVGFibGUpLndoZXJlKGZyb21Db2x1bW4sIHJvdy5pZCkucGx1Y2sodG9Db2x1bW4pO1xuICAgICAgICAgIHJlY29yZC5jb2x1bW5zW3Byb3AubmFtZV0udmFsdWUgPSByZWxhdGVkSWRzO1xuICAgICAgICB9IGVsc2UgaWYgKGlzSGFzTWFueVJlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChwcm9wLndpdGgpO1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRJZHMgPSBhd2FpdCBkYihyZWxhdGVkRW50aXR5LnRhYmxlKVxuICAgICAgICAgICAgLndoZXJlKHByb3Auam9pbkNvbHVtbiwgcm93LmlkKVxuICAgICAgICAgICAgLnBsdWNrKFwiaWRcIik7XG4gICAgICAgICAgcmVjb3JkLmNvbHVtbnNbcHJvcC5uYW1lXS52YWx1ZSA9IHJlbGF0ZWRJZHM7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNPbmVUb09uZVJlbGF0aW9uUHJvcChwcm9wKSAmJiAhcHJvcC5oYXNKb2luQ29sdW1uKSB7XG4gICAgICAgICAgLy8g7Jet67Cp7ZalIE9uZVRvT25lOiBGS+ulvCDqsIDsp4Qg6rSA66CoIOyXlO2LsO2LsOulvCDssL7sirXri4jri6RcbiAgICAgICAgICAvLyDsmIjsi5w6IFVzZXIgT25lVG9PbmUgRW1wbG95ZWUgKEVtcGxveWVl6rCAIHVzZXJfaWQgRkvrpbwg6rCA7KeQKVxuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChwcm9wLndpdGgpO1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRQcm9wID0gcmVsYXRlZEVudGl0eS5wcm9wcy5maW5kKFxuICAgICAgICAgICAgKHApID0+IGlzUmVsYXRpb25Qcm9wKHApICYmIHAud2l0aCA9PT0gZW50aXR5LmlkLFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKHJlbGF0ZWRQcm9wICYmIGlzUmVsYXRpb25Qcm9wKHJlbGF0ZWRQcm9wKSkge1xuICAgICAgICAgICAgLy8g6rSA66CoIOyXlO2LsO2LsOyXkOyEnCBGSyDsu6zrn7zsnLzroZwg7L+866as7ZWp64uI64ukIChpZOqwgCDslYTri5gpXG4gICAgICAgICAgICBjb25zdCBma0NvbHVtbiA9IGAke3JlbGF0ZWRQcm9wLm5hbWV9X2lkYDtcbiAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRSb3cgPSBhd2FpdCBkYihyZWxhdGVkRW50aXR5LnRhYmxlKS53aGVyZShma0NvbHVtbiwgcm93LmlkKS5maXJzdCgpO1xuICAgICAgICAgICAgcmVjb3JkLmNvbHVtbnNbcHJvcC5uYW1lXS52YWx1ZSA9IHJlbGF0ZWRSb3c/LmlkO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChpc1JlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICAgIGNvbnN0IHJlbGF0ZWRJZCA9IHJvd1tgJHtwcm9wLm5hbWV9X2lkYF07XG4gICAgICAgICAgcmVjb3JkLmNvbHVtbnNbcHJvcC5uYW1lXS52YWx1ZSA9IHJlbGF0ZWRJZDtcbiAgICAgICAgICBpZiAocmVsYXRlZElkKSB7XG4gICAgICAgICAgICByZWNvcmQuYmVsb25nc1JlY29yZHMucHVzaChgJHtwcm9wLndpdGh9IyR7cmVsYXRlZElkfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW9wdGlvbnM/LnNpbmdsZVJlY29yZCAmJiByZWxhdGVkSWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChwcm9wLndpdGgpO1xuICAgICAgICAgICAgY29uc3QgcmVsYXRlZFJvdyA9IGF3YWl0IGRiKHJlbGF0ZWRFbnRpdHkudGFibGUpLndoZXJlKFwiaWRcIiwgcmVsYXRlZElkKS5maXJzdCgpO1xuICAgICAgICAgICAgaWYgKHJlbGF0ZWRSb3cpIHtcbiAgICAgICAgICAgICAgYXdhaXQgY3JlYXRlKHJlbGF0ZWRFbnRpdHksIHJlbGF0ZWRSb3cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZWNvcmRzLnB1c2gocmVjb3JkKTtcbiAgICB9O1xuXG4gICAgYXdhaXQgY3JlYXRlKGVudGl0eSwgcm93KTtcblxuICAgIHJldHVybiByZWNvcmRzO1xuICB9XG5cbiAgLyoqXG4gICAqIDEuIFJlbGF0aW9uR3JhcGjroZwgZml4dHVyZSDri6jsnIQg7IK97J6FIOyInOyEnCDqs4TsgrAgKHNlbGYtcmVmZXJlbmNlIO2PrO2VqClcbiAgICogMi4g7YWM7J2067iU67OEIOugiOuyqOuzhOuhnCBVcHNlcnRCdWlsZGVy7JeQIOuTseuhnSDrsI8gdXBzZXJ0IOyLpO2WiVxuICAgKiAzLiDsiJzshJwg6riw67CYIHV1aWTihpJpZCDrp6TtlZEgKFVwc2VydEJ1aWxkZXLqsIAgdXVpZOulvCBEQuyXkCDsoIDsnqXtlZjsp4Ag7JWK7Jy866+A66GcKVxuICAgKlxuICAgKiBVcHNlcnRCdWlsZGVy64qUIHNlbGYtcmVmZXJlbmNl6rCAIOyeiOycvOuptCBidWlsZEluc2VydExldmVscygp66GcIOyerOygleugrO2VmOyXrFxuICAgKiDrk7HroZ0g7Iic7ISc7JmAIOuwmO2ZmCDsiJzshJzqsIAg64us65287KeIIOyImCDsnojsirXri4jri6QuIOydtOulvCDrsKnsp4DtlZjquLAg7JyE7ZW0XG4gICAqIEZpeHR1cmVNYW5hZ2Vy6rCAIOugiOuyqOuzhOuhnCDrgpjriKDshJwg7LKY66as7ZWY7JesIOqwgSB1cHNlcnQg7Zi47Lac7JeQ7ISc64qUXG4gICAqIHNlbGYtcmVmZXJlbmNl6rCAIOyXhuuPhOuhnSDtlanri4jri6QuXG4gICAqL1xuICBhc3luYyBpbnNlcnRGaXh0dXJlcyhcbiAgICBkYk5hbWU6IGtleW9mIFNvbmFtdURCQ29uZmlnLFxuICAgIF9maXh0dXJlczogRml4dHVyZVJlY29yZFtdLFxuICApOiBQcm9taXNlPEZpeHR1cmVJbXBvcnRSZXN1bHRbXT4ge1xuICAgIGNvbnN0IGZpeHR1cmVzID0gdW5pcXVlKF9maXh0dXJlcywgKGYpID0+IGYuZml4dHVyZUlkKTtcblxuICAgIC8vIOy0iOq4sO2ZlFxuICAgIHRoaXMuYnVpbGRlciA9IG5ldyBVcHNlcnRCdWlsZGVyKCk7XG4gICAgdGhpcy5maXh0dXJlUmVmTWFwID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuc2tpcHBlZEZpeHR1cmVzID0gbmV3IE1hcCgpO1xuXG4gICAgLy8g67OR66CsIO2FjOyKpO2KuCDrqqjrk5zsl5DshJzripQgd29ya2Vy67OEIERC7JeQIOyggOyepVxuICAgIGNvbnN0IGRiQ29uZmlnID1cbiAgICAgIHByb2Nlc3MuZW52LlNPTkFNVV9XT1JLRVJfREIgPT09IFwidHJ1ZVwiICYmIHByb2Nlc3MuZW52LlZJVEVTVF9QT09MX0lEXG4gICAgICAgID8gKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHdvcmtlcklkID0gcGFyc2VJbnQocHJvY2Vzcy5lbnYuVklURVNUX1BPT0xfSUQgPz8gXCIxXCIsIDEwKTtcbiAgICAgICAgICAgIGNvbnN0IGJhc2VDb25maWcgPSBTb25hbXUuZGJDb25maWdbZGJOYW1lXTtcbiAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBiYXNlQ29uZmlnLmNvbm5lY3Rpb24gYXMgeyBkYXRhYmFzZTogc3RyaW5nIH07XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAuLi5iYXNlQ29uZmlnLFxuICAgICAgICAgICAgICBjb25uZWN0aW9uOiB7IC4uLmNvbm5lY3Rpb24sIGRhdGFiYXNlOiBgJHtjb25uZWN0aW9uLmRhdGFiYXNlfV8ke3dvcmtlcklkfWAgfSxcbiAgICAgICAgICAgICAgcG9vbDogeyBtaW46IDEsIG1heDogMSB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSgpXG4gICAgICAgIDogU29uYW11LmRiQ29uZmlnW2RiTmFtZV07XG4gICAgY29uc3QgZGIgPSBjcmVhdGVLbmV4SW5zdGFuY2UoZGJDb25maWcpO1xuICAgIGNvbnN0IHJlc3VsdHM6IEZpeHR1cmVJbXBvcnRSZXN1bHRbXSA9IFtdO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIDEuIFJlbGF0aW9uR3JhcGjroZwgZml4dHVyZSDri6jsnIQg7IK97J6FIOyInOyEnCDqs4TsgrBcbiAgICAgIHRoaXMucmVsYXRpb25HcmFwaC5idWlsZEdyYXBoKGZpeHR1cmVzKTtcbiAgICAgIGNvbnN0IGluc2VydGlvbk9yZGVyID0gdGhpcy5yZWxhdGlvbkdyYXBoLmdldEluc2VydGlvbk9yZGVyKCk7XG5cbiAgICAgIC8vIDIuIOyKpO2Cte2VoCBmaXh0dXJlIOuovOyggCDsspjrpqwgKG92ZXJyaWRlIOyytO2BrClcbiAgICAgIGZvciAoY29uc3QgZml4dHVyZUlkIG9mIGluc2VydGlvbk9yZGVyKSB7XG4gICAgICAgIGNvbnN0IGZpeHR1cmUgPSBmaXh0dXJlcy5maW5kKChmKSA9PiBmLmZpeHR1cmVJZCA9PT0gZml4dHVyZUlkKTtcbiAgICAgICAgaWYgKCFmaXh0dXJlKSBjb250aW51ZTtcblxuICAgICAgICBjb25zdCBoYXNUYXJnZXQgPSAhIWZpeHR1cmUudGFyZ2V0O1xuICAgICAgICBjb25zdCBoYXNVbmlxdWUgPSAhIWZpeHR1cmUudW5pcXVlO1xuICAgICAgICBjb25zdCBoYXNEdXBsaWNhdGUgPSBoYXNUYXJnZXQgfHwgaGFzVW5pcXVlO1xuXG4gICAgICAgIC8vIOykkeuzteydtCDsnojqs6Agb3ZlcnJpZGU9ZmFsc2Xsnbgg6rK97JqwOiDsiqTtgrVcbiAgICAgICAgaWYgKGhhc0R1cGxpY2F0ZSAmJiAhZml4dHVyZS5vdmVycmlkZSkge1xuICAgICAgICAgIC8vIOq4sOyhtCDroIjsvZTrk5wgSUQg7KCA7J6lICh1bmlxdWUg7Jqw7ISgLCDsl4bsnLzrqbQgdGFyZ2V0KVxuICAgICAgICAgIGNvbnN0IGV4aXN0aW5nSWQgPSBmaXh0dXJlLnVuaXF1ZT8uaWQgPz8gZml4dHVyZS50YXJnZXQ/LmlkO1xuICAgICAgICAgIGFzc2VydChleGlzdGluZ0lkKTtcbiAgICAgICAgICB0aGlzLnNraXBwZWRGaXh0dXJlcy5zZXQoZml4dHVyZUlkLCB7XG4gICAgICAgICAgICBlbnRpdHlJZDogZml4dHVyZS5lbnRpdHlJZCxcbiAgICAgICAgICAgIGV4aXN0aW5nSWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICBjaGFsay55ZWxsb3coXG4gICAgICAgICAgICAgICAgYFNraXBwZWQgJHtmaXh0dXJlLmVudGl0eUlkfSMke2ZpeHR1cmUuaWR9IChleGlzdGluZzogIyR7ZXhpc3RpbmdJZH0sIG92ZXJyaWRlOiBmYWxzZSlgLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyAzLiDthYzsnbTruJTrs4QgZml4dHVyZSDqt7jro7ntmZQgKGluc2VydGlvbk9yZGVyIOyInOyEnCDquLDrsJgpXG4gICAgICBjb25zdCBmaXh0dXJlc0J5VGFibGUgPSBuZXcgTWFwPHN0cmluZywgRml4dHVyZVJlY29yZFtdPigpO1xuICAgICAgY29uc3QgdGFibGVPcmRlcjogc3RyaW5nW10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBmaXh0dXJlSWQgb2YgaW5zZXJ0aW9uT3JkZXIpIHtcbiAgICAgICAgLy8g7Iqk7YK165CcIGZpeHR1cmUg7KCc7Jm4XG4gICAgICAgIGlmICh0aGlzLnNraXBwZWRGaXh0dXJlcy5oYXMoZml4dHVyZUlkKSkgY29udGludWU7XG5cbiAgICAgICAgY29uc3QgZml4dHVyZSA9IGZpeHR1cmVzLmZpbmQoKGYpID0+IGYuZml4dHVyZUlkID09PSBmaXh0dXJlSWQpO1xuICAgICAgICBpZiAoIWZpeHR1cmUpIGNvbnRpbnVlO1xuXG4gICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmUuZW50aXR5SWQpO1xuICAgICAgICBjb25zdCB0YWJsZU5hbWUgPSBlbnRpdHkudGFibGU7XG5cbiAgICAgICAgaWYgKCFmaXh0dXJlc0J5VGFibGUuaGFzKHRhYmxlTmFtZSkpIHtcbiAgICAgICAgICBmaXh0dXJlc0J5VGFibGUuc2V0KHRhYmxlTmFtZSwgW10pO1xuICAgICAgICAgIHRhYmxlT3JkZXIucHVzaCh0YWJsZU5hbWUpO1xuICAgICAgICB9XG4gICAgICAgIGZpeHR1cmVzQnlUYWJsZS5nZXQodGFibGVOYW1lKT8ucHVzaChmaXh0dXJlKTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgZGIudHJhbnNhY3Rpb24oYXN5bmMgKHRyeCkgPT4ge1xuICAgICAgICBjb25zdCBpbnNlcnRlZElkc0J5VGFibGUgPSBuZXcgTWFwPHN0cmluZywgTWFwPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPj4oKTtcblxuICAgICAgICAvLyA0LiDthYzsnbTruJTrs4Qg66CI67Ko67OEIOyymOumrFxuICAgICAgICBmb3IgKGNvbnN0IHRhYmxlTmFtZSBvZiB0YWJsZU9yZGVyKSB7XG4gICAgICAgICAgY29uc3QgdGFibGVGaXh0dXJlcyA9IGZpeHR1cmVzQnlUYWJsZS5nZXQodGFibGVOYW1lKSA/PyBbXTtcbiAgICAgICAgICBjb25zdCBsZXZlbHMgPSB0aGlzLmdyb3VwRml4dHVyZXNCeUxldmVsKHRhYmxlRml4dHVyZXMpO1xuXG4gICAgICAgICAgZm9yIChjb25zdCBsZXZlbEZpeHR1cmVzIG9mIGxldmVscykge1xuICAgICAgICAgICAgLy8g7ZW064u5IOugiOuyqOydmCBmaXh0dXJl65OkIHJlZ2lzdGVyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGZpeHR1cmUgb2YgbGV2ZWxGaXh0dXJlcykge1xuICAgICAgICAgICAgICB0aGlzLnJlZ2lzdGVyRml4dHVyZShmaXh0dXJlLCBpbnNlcnRlZElkc0J5VGFibGUpO1xuICAgICAgICAgICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgICAgIGNoYWxrLmJsdWUoXG4gICAgICAgICAgICAgICAgICAgIGBSZWdpc3RlcmVkICR7Zml4dHVyZS5lbnRpdHlJZH0jJHtmaXh0dXJlLmlkfSR7Zml4dHVyZS5vdmVycmlkZSA/IGAgKG92ZXJyaWRlKWAgOiBcIlwifWAsXG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHVwc2VydCDsi6Ttlokg7KCEIHV1aWQg66qp66GdIOyggOyepVxuICAgICAgICAgICAgY29uc3QgdGFibGUgPSB0aGlzLmJ1aWxkZXIuZ2V0VGFibGUodGFibGVOYW1lKTtcbiAgICAgICAgICAgIGNvbnN0IHV1aWRzID0gdGFibGUucm93cy5tYXAoKHJvdykgPT4gcm93LnV1aWQgYXMgc3RyaW5nKTtcblxuICAgICAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgIGNoYWxrLmJsdWUoXG4gICAgICAgICAgICAgICAgICBgVXBzZXJ0aW5nICR7dGFibGVOYW1lfSB3aXRoICR7dXVpZHMubGVuZ3RofSByb3dzIChsZXZlbCAke2xldmVscy5pbmRleE9mKGxldmVsRml4dHVyZXMpICsgMX0vJHtsZXZlbHMubGVuZ3RofSlgLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBpZHMgPSAoYXdhaXQgdGhpcy5idWlsZGVyLnVwc2VydChcbiAgICAgICAgICAgICAgdHJ4LFxuICAgICAgICAgICAgICB0YWJsZU5hbWUgYXMga2V5b2YgRGF0YWJhc2VTY2hlbWFFeHRlbmQsXG4gICAgICAgICAgICApKSBhcyAobnVtYmVyIHwgc3RyaW5nKVtdO1xuXG4gICAgICAgICAgICAvLyDsiJzshJwg6riw67CYIHV1aWQgLT4gaWQg66ek7ZWRXG4gICAgICAgICAgICAvLyBzZWxmLXJlZmVyZW5jZeqwgCDsl4bsnLzrr4DroZwg65Ox66GdIOyInOyEnCA9IOuwmO2ZmCDsiJzshJwg67O07J6lXG4gICAgICAgICAgICBpZiAodXVpZHMubGVuZ3RoID4gMCAmJiB1dWlkcy5sZW5ndGggPT09IGlkcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgY29uc3QgZXhpc3RpbmdNYXAgPVxuICAgICAgICAgICAgICAgIGluc2VydGVkSWRzQnlUYWJsZS5nZXQodGFibGVOYW1lKSA/PyBuZXcgTWFwPHN0cmluZywgbnVtYmVyIHwgc3RyaW5nPigpO1xuICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHV1aWRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgZXhpc3RpbmdNYXAuc2V0KHV1aWRzW2ldLCBpZHNbaV0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGluc2VydGVkSWRzQnlUYWJsZS5zZXQodGFibGVOYW1lLCBleGlzdGluZ01hcCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHV1aWRzLmxlbmd0aCAhPT0gaWRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgICAgY2hhbGsueWVsbG93KFxuICAgICAgICAgICAgICAgICAgYFdhcm5pbmc6IHV1aWQgY291bnQgKCR7dXVpZHMubGVuZ3RofSkgIT0gaWQgY291bnQgKCR7aWRzLmxlbmd0aH0pIGZvciAke3RhYmxlTmFtZX1gLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gNS4gTWFueVRvTWFueSDqtIDqs4Qg7LKY66asXG4gICAgICAgIGF3YWl0IHRoaXMucHJvY2Vzc01hbnlUb01hbnlSZWxhdGlvbnModHJ4LCBmaXh0dXJlcywgaW5zZXJ0ZWRJZHNCeVRhYmxlKTtcblxuICAgICAgICAvLyA2LiBQb3N0Z3JlU1FMIOyLnO2AgOyKpCDrpqzshYtcbiAgICAgICAgLy8gRml4dHVyZSDsgr3snoUg7ZuEIOqwgSDthYzsnbTruJTsnZggSUQg7Iuc7YCA7Iqk66W8IOy1nOuMgCBJRCDqsJLsnLzroZwg7JeF642w7J207Yq47ZWp64uI64ukLlxuICAgICAgICAvLyDsnbTroIfqsowg7ZWY7KeAIOyViuycvOuptCDri6TsnYwgSU5TRVJUIOyLnCBJROqwgCAyMDAw67KI64yA66GcIOyDneyEseuQoCDsiJgg7J6I7Iq164uI64ukLlxuICAgICAgICAhaXNUZXN0KCkgJiYgY29uc29sZS5sb2coY2hhbGsuYmx1ZShcIlJlc2V0dGluZyBzZXF1ZW5jZXMuLi5cIikpO1xuICAgICAgICBmb3IgKGNvbnN0IHRhYmxlTmFtZSBvZiB0YWJsZU9yZGVyKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIEVudGl0eeulvCDssL7slYTshJwgaWQg7YOA7J6FIO2ZleyduFxuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXRBbGxFbnRpdGllcygpLmZpbmQoXG4gICAgICAgICAgICAgIChlKSA9PiBlLnRhYmxlID09PSB0YWJsZU5hbWUgfHwgZS5pZC50b0xvd2VyQ2FzZSgpID09PSB0YWJsZU5hbWUsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBpZiAoZW50aXR5KSB7XG4gICAgICAgICAgICAgIGNvbnN0IGlkUHJvcCA9IGVudGl0eS5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IFwiaWRcIik7XG4gICAgICAgICAgICAgIGNvbnN0IGlkVHlwZSA9IGlkUHJvcD8udHlwZTtcblxuICAgICAgICAgICAgICAvLyBpbnRlZ2VyL2JpZ0ludGVnZXLsnbTqsbDrgpgsIHN0cmluZ+ydtOyngOunjCBmaXh0dXJlU3RyYXRlZ3k9c2VxdWVuY2Xsnbgg6rK97Jqw7JeQ66eMIOumrOyFi+2VqeuLiOuLpFxuICAgICAgICAgICAgICBjb25zdCB1c2VzU2VxdWVuY2UgPVxuICAgICAgICAgICAgICAgIGlkVHlwZSA9PT0gXCJpbnRlZ2VyXCIgfHxcbiAgICAgICAgICAgICAgICBpZFR5cGUgPT09IFwiYmlnSW50ZWdlclwiIHx8XG4gICAgICAgICAgICAgICAgaWRQcm9wPy5jb25lPy5maXh0dXJlU3RyYXRlZ3kgPT09IFwic2VxdWVuY2VcIjtcblxuICAgICAgICAgICAgICBpZiAoIXVzZXNTZXF1ZW5jZSkge1xuICAgICAgICAgICAgICAgICFpc1Rlc3QoKSAmJlxuICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgICAgIGNoYWxrLmdyYXkoXG4gICAgICAgICAgICAgICAgICAgICAgYFNraXBwZWQgc2VxdWVuY2UgcmVzZXQgZm9yICR7dGFibGVOYW1lfSAoaWQgdHlwZTogJHtpZFR5cGUgfHwgXCJ1bmtub3duXCJ9KWAsXG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIO2FjOydtOu4lOydmCDstZzrjIAgSUQg7KGw7ZqMIChzdHJpbmcg7YOA7J6F7J2AIOyIq+yekCDsupDsiqTtjIUg7ZWE7JqUKVxuICAgICAgICAgICAgY29uc3QgZW50aXR5MiA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsRW50aXRpZXMoKS5maW5kKFxuICAgICAgICAgICAgICAoZSkgPT4gZS50YWJsZSA9PT0gdGFibGVOYW1lIHx8IGUuaWQudG9Mb3dlckNhc2UoKSA9PT0gdGFibGVOYW1lLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IGlkVHlwZTIgPSBlbnRpdHkyPy5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IFwiaWRcIik/LnR5cGU7XG4gICAgICAgICAgICBjb25zdCBtYXhJZFJlc3VsdCA9XG4gICAgICAgICAgICAgIGlkVHlwZTIgPT09IFwic3RyaW5nXCJcbiAgICAgICAgICAgICAgICA/IGF3YWl0IHRyeFxuICAgICAgICAgICAgICAgICAgICAucmF3KGBTRUxFQ1QgTUFYKGlkOjpiaWdpbnQpIGFzIG1heF9pZCBGUk9NIFwiJHt0YWJsZU5hbWV9XCJgKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigocikgPT4gci5yb3dzWzBdKVxuICAgICAgICAgICAgICAgIDogYXdhaXQgdHJ4KHRhYmxlTmFtZSkubWF4KFwiaWQgYXMgbWF4X2lkXCIpLmZpcnN0KCk7XG4gICAgICAgICAgICBjb25zdCBtYXhJZCA9IG1heElkUmVzdWx0Py5tYXhfaWQ7XG5cbiAgICAgICAgICAgIGlmIChtYXhJZCAhPT0gbnVsbCAmJiBtYXhJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIC8vIOyLnO2AgOyKpOuqheydhCBwZ19nZXRfc2VyaWFsX3NlcXVlbmNl66GcIOyViOyghO2VmOqyjCDsobDtmoxcbiAgICAgICAgICAgICAgYXdhaXQgdHJ4LnJhdyhgU0VMRUNUIHNldHZhbChwZ19nZXRfc2VyaWFsX3NlcXVlbmNlKD8sICdpZCcpLCA/KWAsIFtcbiAgICAgICAgICAgICAgICB0YWJsZU5hbWUsXG4gICAgICAgICAgICAgICAgbWF4SWQsXG4gICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAhaXNUZXN0KCkgJiYgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYFJlc2V0IHNlcXVlbmNlIGZvciAke3RhYmxlTmFtZX06ICR7bWF4SWR9YCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLy8g7Iuc7YCA7Iqk6rCAIOyXhuuKlCDthYzsnbTruJQoam9pbiB0YWJsZSDrk7Ep7J2AIOustOyLnFxuICAgICAgICAgICAgIWlzVGVzdCgpICYmIGNvbnNvbGUubG9nKGNoYWxrLmdyYXkoYFNraXBwZWQgc2VxdWVuY2UgcmVzZXQgZm9yICR7dGFibGVOYW1lfWApKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyA3LiDqsrDqs7wg7IiY7KeRXG4gICAgICAgIGZvciAoY29uc3QgZml4dHVyZSBvZiBmaXh0dXJlcykge1xuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmUuZW50aXR5SWQpO1xuXG4gICAgICAgICAgLy8g7Iqk7YK165CcIGZpeHR1cmXripQg6riw7KG0IOugiOy9lOuTnCDsoJXrs7TroZwg6rKw6rO8IOy2lOqwgFxuICAgICAgICAgIGNvbnN0IHNraXBwZWQgPSB0aGlzLnNraXBwZWRGaXh0dXJlcy5nZXQoZml4dHVyZS5maXh0dXJlSWQpO1xuICAgICAgICAgIGlmIChza2lwcGVkKSB7XG4gICAgICAgICAgICByZXN1bHRzLnB1c2goe1xuICAgICAgICAgICAgICBlbnRpdHlJZDogZml4dHVyZS5lbnRpdHlJZCxcbiAgICAgICAgICAgICAgZGF0YTogYXdhaXQgdHJ4KGVudGl0eS50YWJsZSkud2hlcmUoXCJpZFwiLCBza2lwcGVkLmV4aXN0aW5nSWQpLmZpcnN0KCksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHJlZiA9IHRoaXMuZml4dHVyZVJlZk1hcC5nZXQoZml4dHVyZS5maXh0dXJlSWQpO1xuICAgICAgICAgIGlmIChyZWYpIHtcbiAgICAgICAgICAgIGNvbnN0IHV1aWRUb0lkID0gaW5zZXJ0ZWRJZHNCeVRhYmxlLmdldChlbnRpdHkudGFibGUpO1xuICAgICAgICAgICAgY29uc3QgaW5zZXJ0ZWRJZCA9IHV1aWRUb0lkPy5nZXQocmVmLnV1aWQpO1xuXG4gICAgICAgICAgICBpZiAoaW5zZXJ0ZWRJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIHJlc3VsdHMucHVzaCh7XG4gICAgICAgICAgICAgICAgZW50aXR5SWQ6IGZpeHR1cmUuZW50aXR5SWQsXG4gICAgICAgICAgICAgICAgZGF0YTogYXdhaXQgdHJ4KGVudGl0eS50YWJsZSkud2hlcmUoXCJpZFwiLCBpbnNlcnRlZElkKS5maXJzdCgpLFxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgICAgIGNoYWxrLmdyZWVuKGBJbnNlcnRlZCBpbnRvICR7ZW50aXR5LnRhYmxlfTogIyR7Zml4dHVyZS5pZH0gLT4gIyR7aW5zZXJ0ZWRJZH1gKSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IGRiLmRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5pcXVlKHJlc3VsdHMsIChyKSA9PiBgJHtyLmVudGl0eUlkfSMke3IuZGF0YS5pZH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXh0dXJlUmVjb3Jk66W8IFVwc2VydEJ1aWxkZXLsl5Ag65Ox66GdXG4gICAqIEBwYXJhbSBpbnNlcnRlZElkc0J5VGFibGUg7J2066+4IHVwc2VydOuQnCDthYzsnbTruJTsnZggdXVpZOKGkmlkIOunpO2VkSAo66CI67Ko67OEIOyymOumrCDsi5wg7IKs7JqpKVxuICAgKi9cbiAgcHJpdmF0ZSByZWdpc3RlckZpeHR1cmUoXG4gICAgZml4dHVyZTogRml4dHVyZVJlY29yZCxcbiAgICBpbnNlcnRlZElkc0J5VGFibGU/OiBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBudW1iZXIgfCBzdHJpbmc+PixcbiAgKTogVUJSZWYge1xuICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmUuZW50aXR5SWQpO1xuICAgIGNvbnN0IHJvdzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcblxuICAgIC8vIE92ZXJyaWRlIOuqqOuTnCDtjJDri6g6IHRhcmdldCDrmJDripQgdW5pcXVl6rCAIOyeiOqzoCBvdmVycmlkZT10cnVl7J24IOqyveyasFxuICAgIGNvbnN0IGV4aXN0aW5nUmVjb3JkID0gZml4dHVyZS50YXJnZXQgPz8gZml4dHVyZS51bmlxdWU7XG4gICAgY29uc3QgaXNPdmVycmlkZU1vZGUgPSBmaXh0dXJlLm92ZXJyaWRlICYmIGV4aXN0aW5nUmVjb3JkO1xuXG4gICAgZm9yIChjb25zdCBbcHJvcE5hbWUsIGNvbHVtbl0gb2YgT2JqZWN0LmVudHJpZXMoZml4dHVyZS5jb2x1bW5zKSkge1xuICAgICAgY29uc3QgcHJvcCA9IGNvbHVtbi5wcm9wO1xuXG4gICAgICBpZiAoaXNWaXJ0dWFsUHJvcChwcm9wKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gR2VuZXJhdGVkIGNvbHVtbuydgCBJTlNFUlTsl5DshJwg7KCc7Jm4IChEQuqwgCDsnpDrj5kg7IOd7ISxKVxuICAgICAgaWYgKFwiZ2VuZXJhdGVkXCIgaW4gcHJvcCAmJiBwcm9wLmdlbmVyYXRlZCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gaWQg7LKY66asXG4gICAgICBpZiAocHJvcE5hbWUgPT09IFwiaWRcIikge1xuICAgICAgICBjb25zdCBpZFByb3AgPSBlbnRpdHkucHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBcImlkXCIpO1xuICAgICAgICAvLyBwYXJlbnRJZCDsl5Tti7Dti7DsnZggaWTripQg67aA66qoIOyXlO2LsO2LsOydmCBGS+ydtOuvgOuhnCDsi5ztgIDsiqQg66+47IKs7JqpICjrqoXsi5zsoIHsnLzroZwg7Y+s7ZWoKVxuICAgICAgICBjb25zdCB1c2VzU2VxdWVuY2UgPVxuICAgICAgICAgICFlbnRpdHkucGFyZW50SWQgJiZcbiAgICAgICAgICAoaWRQcm9wPy50eXBlID09PSBcImludGVnZXJcIiB8fFxuICAgICAgICAgICAgaWRQcm9wPy50eXBlID09PSBcImJpZ0ludGVnZXJcIiB8fFxuICAgICAgICAgICAgaWRQcm9wPy5jb25lPy5maXh0dXJlU3RyYXRlZ3kgPT09IFwic2VxdWVuY2VcIik7XG5cbiAgICAgICAgaWYgKGlzT3ZlcnJpZGVNb2RlICYmIGV4aXN0aW5nUmVjb3JkKSB7XG4gICAgICAgICAgLy8gT3ZlcnJpZGU6IOq4sOyhtCDroIjsvZTrk5zsnZgg6rCSIOyCrOyaqSDihpIgVVBEQVRFXG4gICAgICAgICAgcm93W3Byb3BOYW1lXSA9IGV4aXN0aW5nUmVjb3JkLmNvbHVtbnNbcHJvcE5hbWVdPy52YWx1ZTtcbiAgICAgICAgfSBlbHNlIGlmICghdXNlc1NlcXVlbmNlKSB7XG4gICAgICAgICAgLy8gc3RyaW5nIFBLIOuYkOuKlCBwYXJlbnRJZCDsl5Tti7Dti7AgRks6IOyDneyEseuQnCBpZCDqsJLsnYQgSU5TRVJU7JeQIO2PrO2VqFxuICAgICAgICAgIHJvd1twcm9wTmFtZV0gPSBjb2x1bW4udmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaW50ZWdlci9iaWdJbnRlZ2VyIFBLOiBEQiDsi5ztgIDsiqTsl5Ag66eh6rmAICjqsJIg7KCc7Jm4KVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzUmVsYXRpb25Qcm9wKHByb3ApKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBpc0JlbG9uZ3NUb09uZVJlbGF0aW9uUHJvcChwcm9wKSB8fFxuICAgICAgICAgIChpc09uZVRvT25lUmVsYXRpb25Qcm9wKHByb3ApICYmIHByb3AuaGFzSm9pbkNvbHVtbilcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgcmVsYXRlZElkID0gY29sdW1uLnZhbHVlIGFzIG51bWJlciB8IG51bGw7XG4gICAgICAgICAgaWYgKHJlbGF0ZWRJZCAhPT0gbnVsbCAmJiByZWxhdGVkSWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY29uc3QgcmVsYXRlZEZpeHR1cmVJZCA9IGAke3Byb3Aud2l0aH0jJHtyZWxhdGVkSWR9YDtcblxuICAgICAgICAgICAgLy8g66i87KCAIHNraXDrkJwgZml4dHVyZeyduOyngCDtmZXsnbhcbiAgICAgICAgICAgIGNvbnN0IHNraXBwZWRFeGlzdGluZ0lkID0gdGhpcy5za2lwcGVkRml4dHVyZXMuZ2V0KHJlbGF0ZWRGaXh0dXJlSWQpPy5leGlzdGluZ0lkO1xuICAgICAgICAgICAgaWYgKHNraXBwZWRFeGlzdGluZ0lkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgLy8gc2tpcOuQnCBmaXh0dXJlIOKGkiB0YXJnZXQgRELsnZgg6riw7KG0IOugiOy9lOuTnCBpZCDsgqzsmqlcbiAgICAgICAgICAgICAgcm93W2Ake3Byb3BOYW1lfV9pZGBdID0gc2tpcHBlZEV4aXN0aW5nSWQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb25zdCByZWxhdGVkUmVmID0gdGhpcy5maXh0dXJlUmVmTWFwLmdldChyZWxhdGVkRml4dHVyZUlkKTtcbiAgICAgICAgICAgICAgaWYgKHJlbGF0ZWRSZWYpIHtcbiAgICAgICAgICAgICAgICAvLyDsnbTrr7ggdXBzZXJ065CcIOqwmeydgCDthYzsnbTruJQgZml4dHVyZSDtmZXsnbhcbiAgICAgICAgICAgICAgICBjb25zdCByZWxhdGVkRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocHJvcC53aXRoKTtcbiAgICAgICAgICAgICAgICBjb25zdCByZWxhdGVkSW5zZXJ0ZWRJZHMgPSBpbnNlcnRlZElkc0J5VGFibGU/LmdldChyZWxhdGVkRW50aXR5LnRhYmxlKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhY3R1YWxJZCA9IHJlbGF0ZWRJbnNlcnRlZElkcz8uZ2V0KHJlbGF0ZWRSZWYudXVpZCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoYWN0dWFsSWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgLy8g7J2066+4IHVwc2VydOuQqCDihpIg7Iuk7KCcIElEIOyCrOyaqVxuICAgICAgICAgICAgICAgICAgcm93W2Ake3Byb3BOYW1lfV9pZGBdID0gYWN0dWFsSWQ7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIC8vIOyVhOyngSB1cHNlcnQg7JWI65CoIOKGkiBVQlJlZiDsgqzsmqlcbiAgICAgICAgICAgICAgICAgIHJvd1tgJHtwcm9wTmFtZX1faWRgXSA9IHJlbGF0ZWRSZWY7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGZpeHR1cmVz7JeQIO2PrO2VqOuQmOyngCDslYrsnYAg66CI7L2U65OcIOKGkiBJRCDqt7jrjIDroZwg7IKs7JqpXG4gICAgICAgICAgICAgICAgcm93W2Ake3Byb3BOYW1lfV9pZGBdID0gcmVsYXRlZElkO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJvd1tgJHtwcm9wTmFtZX1faWRgXSA9IG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIEhhc01hbnksIE1hbnlUb01hbnnripQg67OE64+EIOyymOumrFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8g7J2867CYIOy7rOufvFxuICAgICAgICByb3dbcHJvcE5hbWVdID0gdGhpcy5jb252ZXJ0Q29sdW1uVmFsdWUocHJvcCBhcyBFbnRpdHlQcm9wLCBjb2x1bW4udmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgICFpc1Rlc3QoKSAmJlxuICAgICAgY29uc29sZS5sb2coY2hhbGsuYmx1ZShgUmVnaXN0ZXJpbmcgJHtlbnRpdHkudGFibGV9IC0gJHtpbnNwZWN0KHJvdywgZmFsc2UsIG51bGwsIHRydWUpfWApKTtcbiAgICBjb25zdCByZWYgPSB0aGlzLmJ1aWxkZXIucmVnaXN0ZXIoZW50aXR5LnRhYmxlLCByb3cpO1xuICAgIHRoaXMuZml4dHVyZVJlZk1hcC5zZXQoZml4dHVyZS5maXh0dXJlSWQsIHJlZik7XG5cbiAgICByZXR1cm4gcmVmO1xuICB9XG5cbiAgLyoqXG4gICAqIOy7rOufvCDqsJIg67OA7ZmYXG4gICAqL1xuICBwcml2YXRlIGNvbnZlcnRDb2x1bW5WYWx1ZShwcm9wOiBFbnRpdHlQcm9wLCB2YWx1ZTogdW5rbm93bik6IHVua25vd24ge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHByb3AudHlwZSkge1xuICAgICAgY2FzZSBcImpzb25cIjpcbiAgICAgICAgLy8gVXBzZXJ0QnVpbGRlci5yZWdpc3RlcuyXkOyEnCBKU09OLnN0cmluZ2lmeSDsspjrpqztlZjrr4DroZwgb2JqZWN0IOq3uOuMgOuhnCDsoITri6xcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuXG4gICAgICBjYXNlIFwiZGF0ZVwiOlxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiIHx8IHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgIHJldHVybiBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBwcm9jZXNzTWFueVRvTWFueVJlbGF0aW9ucyhcbiAgICB0cng6IEtuZXguVHJhbnNhY3Rpb24sXG4gICAgZml4dHVyZXM6IEZpeHR1cmVSZWNvcmRbXSxcbiAgICBpbnNlcnRlZElkc0J5VGFibGU6IE1hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIG51bWJlciB8IHN0cmluZz4+LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBmb3IgKGNvbnN0IGZpeHR1cmUgb2YgZml4dHVyZXMpIHtcbiAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmUuZW50aXR5SWQpO1xuICAgICAgY29uc3Qgc291cmNlUmVmID0gdGhpcy5maXh0dXJlUmVmTWFwLmdldChmaXh0dXJlLmZpeHR1cmVJZCk7XG5cbiAgICAgIGlmICghc291cmNlUmVmKSBjb250aW51ZTtcblxuICAgICAgY29uc3Qgc291cmNlVXVpZFRvSWQgPSBpbnNlcnRlZElkc0J5VGFibGUuZ2V0KGVudGl0eS50YWJsZSk7XG4gICAgICBjb25zdCBzb3VyY2VJZCA9IHNvdXJjZVV1aWRUb0lkPy5nZXQoc291cmNlUmVmLnV1aWQpO1xuXG4gICAgICBpZiAoc291cmNlSWQgPT09IHVuZGVmaW5lZCkgY29udGludWU7XG5cbiAgICAgIGZvciAoY29uc3QgWywgY29sdW1uXSBvZiBPYmplY3QuZW50cmllcyhmaXh0dXJlLmNvbHVtbnMpKSB7XG4gICAgICAgIGNvbnN0IHByb3AgPSBjb2x1bW4ucHJvcDtcblxuICAgICAgICBpZiAoaXNNYW55VG9NYW55UmVsYXRpb25Qcm9wKHByb3ApICYmIEFycmF5LmlzQXJyYXkoY29sdW1uLnZhbHVlKSkge1xuICAgICAgICAgIC8vIOyEoO2DneuQmOyngCDslYrsnYAgTWFueVRvTWFueSDqtIDqs4TripQg7KCA7J6l7ZWY7KeAIOyViuydjFxuICAgICAgICAgIGNvbnN0IHRhcmdldFRhYmxlID0gRW50aXR5TWFuYWdlci5nZXQocHJvcC53aXRoKTtcbiAgICAgICAgICBpZiAoIXRoaXMuYnVpbGRlci5oYXNUYWJsZSh0YXJnZXRUYWJsZS50YWJsZSkpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgY29uc3QgcmVsYXRlZElkcyA9IGNvbHVtbi52YWx1ZSBhcyBudW1iZXJbXTtcbiAgICAgICAgICBpZiAocmVsYXRlZElkcy5sZW5ndGggPT09IDApIGNvbnRpbnVlO1xuXG4gICAgICAgICAgY29uc3Qgam9pblRhYmxlID0gcHJvcC5qb2luVGFibGU7XG4gICAgICAgICAgY29uc3QgcmVsYXRlZEVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KHByb3Aud2l0aCk7XG5cbiAgICAgICAgICBjb25zdCBzb3VyY2VDb2x1bW4gPSBgJHtpbmZsZWN0aW9uLnNpbmd1bGFyaXplKGVudGl0eS50YWJsZSl9X2lkYDtcbiAgICAgICAgICBjb25zdCB0YXJnZXRDb2x1bW4gPSBgJHtpbmZsZWN0aW9uLnNpbmd1bGFyaXplKHJlbGF0ZWRFbnRpdHkudGFibGUpfV9pZGA7XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IHJlbGF0ZWRJZCBvZiByZWxhdGVkSWRzKSB7XG4gICAgICAgICAgICBjb25zdCByZWxhdGVkRml4dHVyZUlkID0gYCR7cHJvcC53aXRofSMke3JlbGF0ZWRJZH1gO1xuICAgICAgICAgICAgY29uc3QgcmVsYXRlZFJlZiA9IHRoaXMuZml4dHVyZVJlZk1hcC5nZXQocmVsYXRlZEZpeHR1cmVJZCk7XG5cbiAgICAgICAgICAgIGxldCB0YXJnZXRJZDogbnVtYmVyIHwgc3RyaW5nO1xuXG4gICAgICAgICAgICBpZiAocmVsYXRlZFJlZikge1xuICAgICAgICAgICAgICBjb25zdCByZWxhdGVkVXVpZFRvSWQgPSBpbnNlcnRlZElkc0J5VGFibGUuZ2V0KHJlbGF0ZWRFbnRpdHkudGFibGUpO1xuICAgICAgICAgICAgICBjb25zdCByZXNvbHZlZElkID0gcmVsYXRlZFV1aWRUb0lkPy5nZXQocmVsYXRlZFJlZi51dWlkKTtcblxuICAgICAgICAgICAgICBpZiAocmVzb2x2ZWRJZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICAgYFJlbGF0ZWQgZml4dHVyZSAke3JlbGF0ZWRGaXh0dXJlSWR9IG5vdCBmb3VuZCBpbiBpbnNlcnRlZElkcywgc2tpcHBpbmdgLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGFyZ2V0SWQgPSByZXNvbHZlZElkO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGFyZ2V0SWQgPSByZWxhdGVkSWQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEpvaW5UYWJsZeyXkCDsgr3snoVcbiAgICAgICAgICAgIGNvbnN0IFtmb3VuZF0gPSBhd2FpdCB0cngoam9pblRhYmxlKVxuICAgICAgICAgICAgICAud2hlcmUoe1xuICAgICAgICAgICAgICAgIFtzb3VyY2VDb2x1bW5dOiBzb3VyY2VJZCxcbiAgICAgICAgICAgICAgICBbdGFyZ2V0Q29sdW1uXTogdGFyZ2V0SWQsXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC5saW1pdCgxKTtcblxuICAgICAgICAgICAgaWYgKCFmb3VuZCkge1xuICAgICAgICAgICAgICBhd2FpdCB0cngoam9pblRhYmxlKS5pbnNlcnQoe1xuICAgICAgICAgICAgICAgIFtzb3VyY2VDb2x1bW5dOiBzb3VyY2VJZCxcbiAgICAgICAgICAgICAgICBbdGFyZ2V0Q29sdW1uXTogdGFyZ2V0SWQsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICFpc1Rlc3QoKSAmJlxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgY2hhbGsuZ3JlZW4oXG4gICAgICAgICAgICAgICAgICAgIGBJbnNlcnRlZCBpbnRvICR7am9pblRhYmxlfTogJHtlbnRpdHkudGFibGV9KCR7c291cmNlSWR9KSAtICR7cmVsYXRlZEVudGl0eS50YWJsZX0oJHt0YXJnZXRJZH0pYCxcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog6rCZ7J2AIO2FjOydtOu4lCDrgrQgZml4dHVyZeuTpOydhCBzZWxmLXJlZmVyZW5jZSDroIjrsqjrs4TroZwg67aE7ZWgXG4gICAqIC0gc2VsZi1yZWZlcmVuY2XqsIAg7JeG64qUIGZpeHR1cmXrk6Q6IExldmVsIDBcbiAgICogLSBMZXZlbCAw7J2EIOywuOyhsO2VmOuKlCBmaXh0dXJl65OkOiBMZXZlbCAxXG4gICAqIC0g67CY67O1XG4gICAqXG4gICAqIFVwc2VydEJ1aWxkZXLqsIAgc2VsZi1yZWZlcmVuY2XqsIAg7J6I7Jy866m0IGJ1aWxkSW5zZXJ0TGV2ZWxzKCnroZwg7J6s7KCV66Cs7ZWY7JesXG4gICAqIOuTseuhnSDsiJzshJzsmYAg67CY7ZmYIOyInOyEnOqwgCDri6zrnbzsp4gg7IiYIOyeiOyKteuLiOuLpC5cbiAgICog7J2066W8IOuwqeyngO2VmOq4sCDsnITtlbQgRml4dHVyZU1hbmFnZXLqsIAg66CI67Ko67OE66GcIOuCmOuIoOyEnCDsspjrpqztlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGdyb3VwRml4dHVyZXNCeUxldmVsKGZpeHR1cmVzOiBGaXh0dXJlUmVjb3JkW10pOiBGaXh0dXJlUmVjb3JkW11bXSB7XG4gICAgaWYgKGZpeHR1cmVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGZpeHR1cmVzWzBdLmVudGl0eUlkKTtcblxuICAgIC8vIHNlbGYtcmVmZXJlbmNlIHJlbGF0aW9uIHByb3Ag7LC+6riwXG4gICAgY29uc3Qgc2VsZlJlZlByb3BzID0gZW50aXR5LnByb3BzLmZpbHRlcihcbiAgICAgIChwKTogcCBpcyBCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AgfCBPbmVUb09uZVJlbGF0aW9uUHJvcCA9PlxuICAgICAgICBpc1JlbGF0aW9uUHJvcChwKSAmJlxuICAgICAgICAoaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocCkgfHwgKGlzT25lVG9PbmVSZWxhdGlvblByb3AocCkgJiYgcC5oYXNKb2luQ29sdW1uKSkgJiZcbiAgICAgICAgcC53aXRoID09PSBlbnRpdHkuaWQsXG4gICAgKTtcblxuICAgIGlmIChzZWxmUmVmUHJvcHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBzZWxmLXJlZmVyZW5jZSDsl4bsnYwg4oaSIOuLqOydvCDroIjrsqhcbiAgICAgIHJldHVybiBbZml4dHVyZXNdO1xuICAgIH1cblxuICAgIC8vIOugiOuyqOuzhCDrtoTtlaAgKHRvcG9sb2dpY2FsIHNvcnQpXG4gICAgY29uc3QgbGV2ZWxzOiBGaXh0dXJlUmVjb3JkW11bXSA9IFtdO1xuICAgIGNvbnN0IHJlbWFpbmluZyA9IG5ldyBTZXQoZml4dHVyZXMubWFwKChmKSA9PiBmLmZpeHR1cmVJZCkpO1xuICAgIGNvbnN0IHByb2Nlc3NlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgd2hpbGUgKHJlbWFpbmluZy5zaXplID4gMCkge1xuICAgICAgY29uc3QgY3VycmVudExldmVsOiBGaXh0dXJlUmVjb3JkW10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBmaXh0dXJlIG9mIGZpeHR1cmVzKSB7XG4gICAgICAgIGlmICghcmVtYWluaW5nLmhhcyhmaXh0dXJlLmZpeHR1cmVJZCkpIGNvbnRpbnVlO1xuXG4gICAgICAgIC8vIHNlbGYtcmVmZXJlbmNl6rCAIOuqqOuRkCDsnbTrr7gg7LKY66as65CQ6rGw64KYIG51bGzsnbgg6rK97JqwXG4gICAgICAgIGNvbnN0IGNhblByb2Nlc3MgPSBzZWxmUmVmUHJvcHMuZXZlcnkoKHByb3ApID0+IHtcbiAgICAgICAgICBjb25zdCByZWZJZCA9IGZpeHR1cmUuY29sdW1uc1twcm9wLm5hbWVdPy52YWx1ZSBhcyBudW1iZXIgfCBudWxsO1xuICAgICAgICAgIGlmIChyZWZJZCA9PT0gbnVsbCB8fCByZWZJZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICBjb25zdCByZWZGaXh0dXJlSWQgPSBgJHtwcm9wLndpdGh9IyR7cmVmSWR9YDtcbiAgICAgICAgICAvLyDsnbTrr7gg7LKY66as65CQ6rGw64KYLCDtmITsnqwgZml4dHVyZXPsl5Ag7Y+s7ZWo65CY7KeAIOyViuydgCDqsr3smrAgKOyZuOu2gCDssLjsobApXG4gICAgICAgICAgcmV0dXJuIHByb2Nlc3NlZC5oYXMocmVmRml4dHVyZUlkKSB8fCAhcmVtYWluaW5nLmhhcyhyZWZGaXh0dXJlSWQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoY2FuUHJvY2Vzcykge1xuICAgICAgICAgIGN1cnJlbnRMZXZlbC5wdXNoKGZpeHR1cmUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChjdXJyZW50TGV2ZWwubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnN0IHJlbWFpbmluZ0lkcyA9IEFycmF5LmZyb20ocmVtYWluaW5nKS5qb2luKFwiLCBcIik7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgQ2lyY3VsYXIgc2VsZi1yZWZlcmVuY2UgZGV0ZWN0ZWQgaW4gJHtlbnRpdHkudGFibGV9LiBSZW1haW5pbmcgZml4dHVyZXM6ICR7cmVtYWluaW5nSWRzfWAsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgZml4dHVyZSBvZiBjdXJyZW50TGV2ZWwpIHtcbiAgICAgICAgcmVtYWluaW5nLmRlbGV0ZShmaXh0dXJlLmZpeHR1cmVJZCk7XG4gICAgICAgIHByb2Nlc3NlZC5hZGQoZml4dHVyZS5maXh0dXJlSWQpO1xuICAgICAgfVxuXG4gICAgICBsZXZlbHMucHVzaChjdXJyZW50TGV2ZWwpO1xuICAgIH1cblxuICAgIHJldHVybiBsZXZlbHM7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNoZWNrVW5pcXVlVmlvbGF0aW9uKGRiOiBLbmV4LCBlbnRpdHk6IEVudGl0eSwgZml4dHVyZTogRml4dHVyZVJlY29yZCkge1xuICAgIGNvbnN0IF91bmlxdWVJbmRleGVzID0gZW50aXR5LmluZGV4ZXM/LmZpbHRlcigoaSkgPT4gaS50eXBlID09PSBcInVuaXF1ZVwiKSA/PyBbXTtcblxuICAgIGNvbnN0IHVuaXF1ZUluZGV4ZXMgPSBfdW5pcXVlSW5kZXhlcy5maWx0ZXIoKGluZGV4KSA9PlxuICAgICAgaW5kZXguY29sdW1ucy5ldmVyeSgoY29sdW1uKSA9PiAhY29sdW1uLm5hbWUuc3RhcnRzV2l0aChgJHtlbnRpdHkudGFibGV9X19gKSksXG4gICAgKTtcbiAgICBpZiAodW5pcXVlSW5kZXhlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGxldCB1bmlxdWVRdWVyeSA9IGRiKGVudGl0eS50YWJsZSk7XG4gICAgbGV0IGhhc0NvbmRpdGlvbiA9IGZhbHNlO1xuXG4gICAgZm9yIChjb25zdCBpbmRleCBvZiB1bmlxdWVJbmRleGVzKSB7XG4gICAgICAvLyDsu6zrn7wg7KSRIO2VmOuCmOudvOuPhCBudWxs7J2066m0IOycoOuLiO2BrCDsoJzslb3snYQg7JyE67CY7ZWY7KeAIOyViuq4sCDrlYzrrLjsl5Ag7ZW064u5IOyduOuNseyKpOuKlCDrrLTsi5xcbiAgICAgIGNvbnN0IGNvbnRhaW5zTnVsbCA9IGluZGV4LmNvbHVtbnMuc29tZSgoY29sdW1uKSA9PiB7XG4gICAgICAgIGNvbnN0IGZpZWxkID0gY29sdW1uLm5hbWUucmVwbGFjZSgvX2lkJC8sIFwiXCIpO1xuICAgICAgICByZXR1cm4gZml4dHVyZS5jb2x1bW5zW2ZpZWxkXT8udmFsdWUgPT09IG51bGw7XG4gICAgICB9KTtcbiAgICAgIGlmIChjb250YWluc051bGwpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHVuaXF1ZVF1ZXJ5ID0gdW5pcXVlUXVlcnkub3JXaGVyZSgocWIpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBjb2x1bW4gb2YgaW5kZXguY29sdW1ucykge1xuICAgICAgICAgIGNvbnN0IGZpZWxkID0gY29sdW1uLm5hbWUucmVwbGFjZSgvX2lkJC8sIFwiXCIpO1xuXG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZml4dHVyZS5jb2x1bW5zW2ZpZWxkXT8udmFsdWUpKSB7XG4gICAgICAgICAgICBxYi53aGVyZUluKGNvbHVtbi5uYW1lLCBmaXh0dXJlLmNvbHVtbnNbZmllbGRdLnZhbHVlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcWIuYW5kV2hlcmUoY29sdW1uLm5hbWUsIGZpeHR1cmUuY29sdW1uc1tmaWVsZF0/LnZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaGFzQ29uZGl0aW9uID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoIWhhc0NvbmRpdGlvbikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgW3VuaXF1ZUZvdW5kXSA9IGF3YWl0IHVuaXF1ZVF1ZXJ5O1xuICAgIHJldHVybiB1bmlxdWVGb3VuZDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY2hlY2tEdXBsaWNhdGVCeUNvbHVtbnMoXG4gICAgZGI6IEtuZXgsXG4gICAgZW50aXR5OiBFbnRpdHksXG4gICAgZml4dHVyZTogRml4dHVyZVJlY29yZCxcbiAgICBjb2x1bW5zOiBzdHJpbmdbXSxcbiAgKSB7XG4gICAgaWYgKGNvbHVtbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCB3aGVyZUNsYXVzZTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcblxuICAgIGZvciAoY29uc3QgY29sdW1uIG9mIGNvbHVtbnMpIHtcbiAgICAgIC8vIHJlbGF0aW9uIO2VhOuTnOyduCDqsr3smrAgX2lkIOu2meydtOq4sFxuICAgICAgY29uc3QgcHJvcCA9IGVudGl0eS5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IGNvbHVtbik7XG4gICAgICBjb25zdCBkYkNvbHVtbiA9IHByb3AgJiYgaXNSZWxhdGlvblByb3AocHJvcCkgPyBgJHtjb2x1bW59X2lkYCA6IGNvbHVtbjtcbiAgICAgIGNvbnN0IHZhbHVlID0gZml4dHVyZS5jb2x1bW5zW2NvbHVtbl0/LnZhbHVlO1xuXG4gICAgICAvLyBudWxsIOqwkuydtCDtj6ztlajrkJwg6rK97JqwIOykkeuztSDtmZXsnbgg7Iqk7YK1XG4gICAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgd2hlcmVDbGF1c2VbZGJDb2x1bW5dID0gdmFsdWU7XG4gICAgfVxuXG4gICAgY29uc3QgW2ZvdW5kXSA9IGF3YWl0IGRiKGVudGl0eS50YWJsZSkud2hlcmUod2hlcmVDbGF1c2UpLmxpbWl0KDEpO1xuICAgIHJldHVybiBmb3VuZDtcbiAgfVxuXG4gIGFzeW5jIGFkZEZpeHR1cmVMb2FkZXIoY29kZTogc3RyaW5nKSB7XG4gICAgY29uc3QgcGF0aCA9IGAke1NvbmFtdS5hcGlSb290UGF0aH0vc3JjL3Rlc3RpbmcvZml4dHVyZS50c2A7XG4gICAgY29uc3QgY29udGVudCA9IHJlYWRGaWxlU3luYyhwYXRoKS50b1N0cmluZygpO1xuXG4gICAgY29uc3QgZml4dHVyZUxvYWRlclN0YXJ0ID0gY29udGVudC5pbmRleE9mKFwiY29uc3QgZml4dHVyZUxvYWRlciA9IHtcIik7XG4gICAgY29uc3QgZml4dHVyZUxvYWRlckVuZCA9IGNvbnRlbnQuaW5kZXhPZihcIn07XCIsIGZpeHR1cmVMb2FkZXJTdGFydCk7XG5cbiAgICBpZiAoZml4dHVyZUxvYWRlclN0YXJ0ICE9PSAtMSAmJiBmaXh0dXJlTG9hZGVyRW5kICE9PSAtMSkge1xuICAgICAgY29uc3QgbmV3Q29udGVudCA9IGAke2NvbnRlbnQuc2xpY2UoMCwgZml4dHVyZUxvYWRlckVuZCl9ICAke2NvZGV9XFxuJHtjb250ZW50LnNsaWNlKGZpeHR1cmVMb2FkZXJFbmQpfWA7XG5cbiAgICAgIHdyaXRlRmlsZVN5bmMocGF0aCwgbmV3Q29udGVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkZhaWxlZCB0byBmaW5kIGZpeHR1cmVMb2FkZXIgaW4gZml4dHVyZS50c1wiKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IEZpeHR1cmVNYW5hZ2VyID0gbmV3IEZpeHR1cmVNYW5hZ2VyQ2xhc3MoKTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7OzthQVVzQztpQkFDWTtXQUVHO3FCQUNLO3FCQUdGO1lBUWpDO2lC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