@mnaoumov/obsidian-lib 10.7.0 → 10.9.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 (69) hide show
  1. package/README.md +4 -0
  2. package/data-stores/data-store-locations/package.json +6 -0
  3. package/dist/lib/cjs/__merged.cjs +18 -1
  4. package/dist/lib/cjs/__merged.d.cts +4 -1
  5. package/dist/lib/cjs/code-block-render-handoff.cjs +2 -5
  6. package/dist/lib/cjs/command-handlers/unlock-active-note-command-handler.cjs +2 -2
  7. package/dist/lib/cjs/community-plugins.cjs +2 -2
  8. package/dist/lib/cjs/components/all-windows-event-component.cjs +86 -14
  9. package/dist/lib/cjs/components/all-windows-event-component.d.cts +54 -3
  10. package/dist/lib/cjs/components/monkey-around-component.cjs +1 -1
  11. package/dist/lib/cjs/components/plugin-notice-component.cjs +2 -6
  12. package/dist/lib/cjs/components/style-sheet-component.cjs +1 -4
  13. package/dist/lib/cjs/data-stores/data-store-locations.cjs +248 -0
  14. package/dist/lib/cjs/data-stores/data-store-locations.d.cts +60 -0
  15. package/dist/lib/cjs/data-stores/data-store-seeds.cjs +2 -2
  16. package/dist/lib/cjs/data-stores/data-store-seeds.d.cts +1 -1
  17. package/dist/lib/cjs/data-stores/data-store-transport.cjs +126 -21
  18. package/dist/lib/cjs/data-stores/data-store-transport.d.cts +38 -4
  19. package/dist/lib/cjs/data-stores/index.cjs +4 -1
  20. package/dist/lib/cjs/data-stores/index.d.cts +1 -0
  21. package/dist/lib/cjs/data-stores/shared-data-store.cjs +145 -22
  22. package/dist/lib/cjs/data-stores/shared-data-store.d.cts +53 -1
  23. package/dist/lib/cjs/desktop-bulk-operation-git.cjs +5 -5
  24. package/dist/lib/cjs/folder-note.cjs +5 -5
  25. package/dist/lib/cjs/formula-function.cjs +152 -0
  26. package/dist/lib/cjs/formula-function.d.cts +98 -0
  27. package/dist/lib/cjs/frontmatter-formatting.cjs +2 -2
  28. package/dist/lib/cjs/generated-during-build.cjs +1 -1
  29. package/dist/lib/cjs/index.cjs +7 -1
  30. package/dist/lib/cjs/index.d.cts +2 -0
  31. package/dist/lib/cjs/link.cjs +12 -12
  32. package/dist/lib/cjs/markdown.cjs +7 -7
  33. package/dist/lib/cjs/vault.cjs +2 -2
  34. package/dist/lib/cjs/virtual-file.cjs +340 -0
  35. package/dist/lib/cjs/virtual-file.d.cts +48 -0
  36. package/dist/lib/esm/__merged.d.mts +4 -1
  37. package/dist/lib/esm/__merged.mjs +20 -2
  38. package/dist/lib/esm/code-block-render-handoff.mjs +2 -5
  39. package/dist/lib/esm/command-handlers/unlock-active-note-command-handler.mjs +2 -2
  40. package/dist/lib/esm/community-plugins.mjs +2 -2
  41. package/dist/lib/esm/components/all-windows-event-component.d.mts +54 -3
  42. package/dist/lib/esm/components/all-windows-event-component.mjs +87 -14
  43. package/dist/lib/esm/components/monkey-around-component.mjs +1 -1
  44. package/dist/lib/esm/components/plugin-notice-component.mjs +2 -6
  45. package/dist/lib/esm/components/style-sheet-component.mjs +1 -4
  46. package/dist/lib/esm/data-stores/data-store-locations.d.mts +60 -0
  47. package/dist/lib/esm/data-stores/data-store-locations.mjs +160 -0
  48. package/dist/lib/esm/data-stores/data-store-seeds.d.mts +1 -1
  49. package/dist/lib/esm/data-stores/data-store-seeds.mjs +2 -2
  50. package/dist/lib/esm/data-stores/data-store-transport.d.mts +38 -4
  51. package/dist/lib/esm/data-stores/data-store-transport.mjs +126 -21
  52. package/dist/lib/esm/data-stores/index.d.mts +1 -0
  53. package/dist/lib/esm/data-stores/index.mjs +3 -1
  54. package/dist/lib/esm/data-stores/shared-data-store.d.mts +53 -1
  55. package/dist/lib/esm/data-stores/shared-data-store.mjs +145 -22
  56. package/dist/lib/esm/desktop-bulk-operation-git.mjs +5 -5
  57. package/dist/lib/esm/folder-note.mjs +5 -5
  58. package/dist/lib/esm/formula-function.d.mts +98 -0
  59. package/dist/lib/esm/formula-function.mjs +62 -0
  60. package/dist/lib/esm/frontmatter-formatting.mjs +2 -2
  61. package/dist/lib/esm/generated-during-build.mjs +1 -1
  62. package/dist/lib/esm/index.d.mts +2 -0
  63. package/dist/lib/esm/index.mjs +5 -1
  64. package/dist/lib/esm/link.mjs +12 -12
  65. package/dist/lib/esm/markdown.mjs +7 -7
  66. package/dist/lib/esm/vault.mjs +2 -2
  67. package/dist/lib/esm/virtual-file.d.mts +48 -0
  68. package/dist/lib/esm/virtual-file.mjs +264 -0
  69. package/package.json +5 -5
@@ -31,6 +31,7 @@ ensureBrowserProcess();
31
31
  })();
32
32
 
33
33
  import { ensureNonNullable } from "@mnaoumov/typescript-lib/type-guards";
34
+ import { DataStoreLocations } from "./data-store-locations.mjs";
34
35
  import {
35
36
  DataStoreReplica,
36
37
  isDataStoreOperation
@@ -40,12 +41,14 @@ const DEFAULT_ACTIVE_DEVICE_MILLISECONDS = 2592e6;
40
41
  const OWNER_PATH_INDEX = -2;
41
42
  const VECTOR_ENTRY_LENGTH = 2;
42
43
  const DEVICE_PATH_PARTS = 2;
44
+ const DEVICE_ID_REG_EXP = /^[\w-]+$/;
43
45
  const RECORD_PREFIX = "shared-record-v1:";
44
46
  class SharedDataStore {
45
47
  constructor(params, device) {
46
48
  this.params = params;
47
49
  this.device = device;
48
- this.transport = new DataStoreTransport(params);
50
+ this.locations = new DataStoreLocations(params);
51
+ this.isSyncEnabled = params.isSyncEnabled ?? true;
49
52
  this.replica = new DataStoreReplica(params.kind);
50
53
  this.activeDeviceMilliseconds = params.activeDeviceMilliseconds ?? DEFAULT_ACTIVE_DEVICE_MILLISECONDS;
51
54
  if (!Number.isFinite(this.activeDeviceMilliseconds) || this.activeDeviceMilliseconds <= 0) {
@@ -54,13 +57,27 @@ class SharedDataStore {
54
57
  }
55
58
  params;
56
59
  device;
60
+ /**
61
+ Configured and remembered reader roots, including retained migration sources while disabled.
62
+ *
63
+ * @returns Unique roots suitable for metadata exclusion without adapter access.
64
+ */
65
+ get transportRoots() {
66
+ return [.../* @__PURE__ */ new Set([...this.knownTransportRoots, ...this.locations.transports.map((transport) => transport.root)])];
67
+ }
57
68
  activeDeviceMilliseconds;
58
69
  counter = 0;
70
+ hasUnpublishedChanges = false;
71
+ isSyncEnabled;
72
+ knownTransportRoots = /* @__PURE__ */ new Set();
59
73
  localRecords = /* @__PURE__ */ new Map();
74
+ locations;
60
75
  replica;
61
76
  time = 0;
62
- transport;
63
77
  vector = /* @__PURE__ */ new Map();
78
+ get transport() {
79
+ return ensureNonNullable(this.locations.transports.at(-1));
80
+ }
64
81
  /**
65
82
  * Opens and synchronizes a store, restoring its device identity exclusively from IndexedDB.
66
83
  *
@@ -69,7 +86,7 @@ class SharedDataStore {
69
86
  */
70
87
  static async open(params) {
71
88
  const device = await params.local.getOrCreate("shared-device-v1", window.crypto.randomUUID());
72
- if (typeof device !== "string" || !/^[\w-]+$/.test(device)) {
89
+ if (typeof device !== "string" || !DEVICE_ID_REG_EXP.test(device)) {
73
90
  throw new Error("Invalid local data-store identity");
74
91
  }
75
92
  const store = new SharedDataStore(params, device);
@@ -87,6 +104,9 @@ class SharedDataStore {
87
104
  await this.loadLocal();
88
105
  await this.mergeFiles();
89
106
  await this.persist();
107
+ if (!this.isSyncEnabled) {
108
+ return;
109
+ }
90
110
  const files = await this.transport.list();
91
111
  const base = `${this.deviceRoot()}/snapshot-${window.crypto.randomUUID()}-manifest`;
92
112
  await this.transport.writeSnapshot({ base, payload: this.checkpoint() });
@@ -111,6 +131,15 @@ class SharedDataStore {
111
131
  }
112
132
  });
113
133
  }
134
+ /**
135
+ * Recognizes transport files, roots, and ancestor folder operations for consumer event filters.
136
+ *
137
+ * @param path - Vault-relative file or folder path.
138
+ * @returns Whether the path intersects an active or retained transport root.
139
+ */
140
+ containsTransportPath(path) {
141
+ return this.transportRoots.some((root) => path === root || path.startsWith(`${root}/`) || root.startsWith(`${path}/`));
142
+ }
114
143
  /**
115
144
  * Deletes a register or removes the currently observed additions of a set member.
116
145
  *
@@ -137,6 +166,24 @@ class SharedDataStore {
137
166
  get(key) {
138
167
  return this.replica.get(key);
139
168
  }
169
+ /**
170
+ * Relocates only this plugin/store subtree; keep opening with the original anchor parameters.
171
+ *
172
+ * @param location - New folder and document format.
173
+ * @returns A promise that resolves after history has been copied and verified.
174
+ */
175
+ async relocate(location) {
176
+ await this.params.local.exclusive(async () => {
177
+ await this.loadLocal();
178
+ if (!this.isSyncEnabled) {
179
+ throw new Error("Enable data-store synchronization before relocation");
180
+ }
181
+ await this.locations.relocate(location);
182
+ await this.mergeFiles();
183
+ this.hasUnpublishedChanges = true;
184
+ await this.persist();
185
+ });
186
+ }
140
187
  /**
141
188
  * Writes one register value, or adds a member to an observed-remove set.
142
189
  *
@@ -157,6 +204,21 @@ class SharedDataStore {
157
204
  async setMany(entries) {
158
205
  await this.change(entries.map(([key, value]) => ({ deleted: false, key, value })));
159
206
  }
207
+ /**
208
+ * Toggles transport without changing identity or causal state. Persist the preference in consumer settings.
209
+ * Enabling publishes a complete checkpoint so offline sequences cannot leave gaps.
210
+ *
211
+ * @param isEnabled - Whether to use vault transport for subsequent calls on this instance.
212
+ * @returns A promise that resolves after synchronization when enabling.
213
+ */
214
+ async setSyncEnabled(isEnabled) {
215
+ await this.params.local.exclusive(async () => {
216
+ await this.loadLocal();
217
+ this.isSyncEnabled = isEnabled;
218
+ await this.mergeFiles();
219
+ await this.persist();
220
+ });
221
+ }
160
222
  /**
161
223
  * Merges complete snapshots and contiguous journal history, then publishes its durable acknowledgement.
162
224
  * Partial deliveries remain pending; a later call retries them. No acknowledgement skips a missing sequence.
@@ -172,13 +234,23 @@ class SharedDataStore {
172
234
  }
173
235
  async acknowledgements(files) {
174
236
  const acknowledgements = [new Map(this.vector)];
175
- const deviceFiles = files.filter((path) => path.startsWith(`${this.transport.root}/devices/`));
176
- const devices = new Set(deviceFiles.map((path) => path.slice(this.transport.root.length + 1).split("/", DEVICE_PATH_PARTS)[1]).filter((device) => device !== void 0));
237
+ const devicesPrefix = `${this.transport.root}/devices/`;
238
+ const devices = /* @__PURE__ */ new Set();
239
+ for (const path of files) {
240
+ if (!path.startsWith(devicesPrefix)) {
241
+ continue;
242
+ }
243
+ const parts = path.slice(devicesPrefix.length).split("/");
244
+ const device = parts[0];
245
+ if (parts.length >= DEVICE_PATH_PARTS && device !== void 0 && DEVICE_ID_REG_EXP.test(device)) {
246
+ devices.add(device);
247
+ }
248
+ }
177
249
  for (const device of devices) {
178
250
  if (device === this.device) {
179
251
  continue;
180
252
  }
181
- const have = await this.transport.read(`${this.transport.root}/devices/${device}/have.md`);
253
+ const have = await this.transport.read(`${this.transport.root}/devices/${device}/have${this.transport.extension}`);
182
254
  if (!isObject(have) || !isVector(have["vector"]) || typeof have["time"] !== "number") {
183
255
  acknowledgements.push(/* @__PURE__ */ new Map());
184
256
  } else if (Date.now() - have["time"] <= this.activeDeviceMilliseconds) {
@@ -217,9 +289,17 @@ class SharedDataStore {
217
289
  candidate.apply(operation);
218
290
  operations.push(operation);
219
291
  }
292
+ if (!this.isSyncEnabled) {
293
+ for (const operation of operations) {
294
+ this.apply(operation);
295
+ }
296
+ this.hasUnpublishedChanges = true;
297
+ await this.persist();
298
+ return;
299
+ }
220
300
  for (const operation of operations) {
221
301
  if (!this.transport.fits([operation])) {
222
- await this.transport.write(`${this.deviceRoot()}/log-${String(operation.sequence)}.md`, [operation]);
302
+ await this.transport.write(`${this.deviceRoot()}/log-${String(operation.sequence)}${this.transport.extension}`, [operation]);
223
303
  }
224
304
  }
225
305
  let batch = [];
@@ -248,13 +328,39 @@ class SharedDataStore {
248
328
  this.time = 0;
249
329
  this.counter = 0;
250
330
  this.localRecords.clear();
331
+ this.knownTransportRoots.clear();
332
+ this.hasUnpublishedChanges = false;
251
333
  const records = await this.params.local.entries();
252
334
  for (const [key, value] of records) {
253
- if (key === "shared-checkpoint-v1") {
254
- this.mergeCheckpoint(value);
255
- } else if (key.startsWith(RECORD_PREFIX)) {
256
- this.replica.apply(value);
257
- this.localRecords.set(key, ensureNonNullable(JSON.stringify(value)));
335
+ switch (key) {
336
+ case "shared-checkpoint-v1": {
337
+ this.mergeCheckpoint(value);
338
+ break;
339
+ }
340
+ case "shared-transport-roots-v1": {
341
+ if (!Array.isArray(value)) {
342
+ throw new TypeError("Invalid local data-store transport roots");
343
+ }
344
+ const suffix = `/${this.params.pluginId}/${this.params.storeId}`;
345
+ for (const root of value) {
346
+ if (typeof root !== "string" || !root.endsWith(suffix)) {
347
+ throw new Error("Invalid local data-store transport roots");
348
+ }
349
+ const transport = new DataStoreTransport({ ...this.params, folder: root.slice(0, -suffix.length) });
350
+ this.knownTransportRoots.add(transport.root);
351
+ }
352
+ break;
353
+ }
354
+ case "shared-unpublished-v1": {
355
+ this.hasUnpublishedChanges = value === true;
356
+ break;
357
+ }
358
+ default: {
359
+ if (key.startsWith(RECORD_PREFIX)) {
360
+ this.replica.apply(value);
361
+ this.localRecords.set(key, ensureNonNullable(JSON.stringify(value)));
362
+ }
363
+ }
258
364
  }
259
365
  }
260
366
  }
@@ -271,19 +377,28 @@ class SharedDataStore {
271
377
  this.observeClock(Number(value["time"]), Number(value["counter"]));
272
378
  }
273
379
  async mergeFiles() {
274
- const allFiles = await this.transport.list();
275
- const files = allFiles.filter((path) => path.startsWith(`${this.transport.root}/devices/`));
276
- const manifests = files.filter((file) => /\/snapshot-[\w-]+-manifest\.md$/.test(file));
380
+ if (!this.isSyncEnabled) {
381
+ return;
382
+ }
383
+ await this.locations.refresh();
384
+ for (const transport of this.locations.transports) {
385
+ await this.mergeTransport(transport);
386
+ }
387
+ }
388
+ async mergeTransport(transport) {
389
+ const allFiles = await transport.list();
390
+ const files = allFiles.filter((path) => path.startsWith(`${transport.root}/devices/`));
391
+ const manifests = files.filter((file) => /\/snapshot-[\w-]+-manifest\.(?:md|json)$/.test(file));
277
392
  for (const path of manifests) {
278
- const snapshot = await this.transport.readSnapshot(path);
393
+ const snapshot = await transport.readSnapshot(path);
279
394
  if (snapshot !== void 0) {
280
395
  this.mergeCheckpoint(snapshot);
281
396
  }
282
397
  }
283
398
  const operations = [];
284
- const segments = files.filter((file) => /\/log-\d+\.md$/.test(file));
399
+ const segments = files.filter((file) => /\/log-\d+\.(?:md|json)$/.test(file));
285
400
  for (const path of segments) {
286
- const segment = await this.transport.read(path);
401
+ const segment = await transport.read(path);
287
402
  if (segment === void 0) {
288
403
  continue;
289
404
  }
@@ -320,13 +435,21 @@ class SharedDataStore {
320
435
  }
321
436
  const entries = [...records].filter(([key, value]) => this.localRecords.get(key) !== JSON.stringify(value));
322
437
  const removedKeys = [...this.localRecords.keys()].filter((key) => !records.has(key));
323
- entries.push(["shared-checkpoint-v1", { ...checkpoint, operations: [] }]);
438
+ entries.push(["shared-checkpoint-v1", { ...checkpoint, operations: [] }], ["shared-unpublished-v1", this.hasUnpublishedChanges], ["shared-transport-roots-v1", this.transportRoots]);
324
439
  await this.params.local.commit({ entries, removedKeys });
325
- await this.transport.write(`${this.deviceRoot()}/have.md`, { format: 1, time: Date.now(), vector: [...this.vector] });
440
+ if (!this.isSyncEnabled) {
441
+ return;
442
+ }
443
+ if (this.hasUnpublishedChanges) {
444
+ await this.transport.writeSnapshot({ base: `${this.deviceRoot()}/snapshot-${window.crypto.randomUUID()}-manifest`, payload: checkpoint });
445
+ await this.params.local.set("shared-unpublished-v1", false);
446
+ this.hasUnpublishedChanges = false;
447
+ }
448
+ await this.transport.write(`${this.deviceRoot()}/have${this.transport.extension}`, { format: 1, time: Date.now(), vector: [...this.vector] });
326
449
  }
327
450
  async publish(operations) {
328
451
  const first = ensureNonNullable(operations[0]);
329
- await this.transport.write(`${this.deviceRoot()}/log-${String(first.sequence)}.md`, operations);
452
+ await this.transport.writeImmutable(`${this.deviceRoot()}/log-${String(first.sequence)}${this.transport.extension}`, operations);
330
453
  for (const operation of operations) {
331
454
  this.apply(operation);
332
455
  }
@@ -343,4 +466,4 @@ function isVector(value) {
343
466
  export {
344
467
  SharedDataStore
345
468
  };
346
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kYXRhLXN0b3Jlcy9zaGFyZWQtZGF0YS1zdG9yZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuL25vLXVuc3VwcG9ydGVkLWZlYXR1cmVzL25vZGUtYnVpbHRpbnMgLS0gVGhlc2UgYXJlIE9ic2lkaWFuIHJlbmRlcmVyIFdlYiBBUElzLCBub3QgTm9kZSBidWlsdGlucy4gKi9cbi8qKlxuICogQGZpbGVcbiAqXG4gKiBNZXJnZWFibGUgcGx1Z2luIGRhdGEsIHRyYW5zcG9ydGVkIGFzIHNpbmdsZS13cml0ZXIgam91cm5hbCBzZWdtZW50cyBhbmQgY2h1bmtlZCBzbmFwc2hvdHMuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBEYXRhQWRhcHRlciB9IGZyb20gJ29ic2lkaWFuJztcbmltcG9ydCB0eXBlIHsgSnNvblZhbHVlIH0gZnJvbSAndHlwZS1mZXN0JztcblxuaW1wb3J0IHsgZW5zdXJlTm9uTnVsbGFibGUgfSBmcm9tICdAbW5hb3Vtb3YvdHlwZXNjcmlwdC1saWIvdHlwZS1ndWFyZHMnO1xuXG5pbXBvcnQgdHlwZSB7XG4gIERhdGFTdG9yZU1lcmdlS2luZCxcbiAgRGF0YVN0b3JlT3BlcmF0aW9uXG59IGZyb20gJy4vZGF0YS1zdG9yZS1yZXBsaWNhLnRzJztcbmltcG9ydCB0eXBlIHsgTG9jYWxEYXRhU3RvcmUgfSBmcm9tICcuL2xvY2FsLWRhdGEtc3RvcmUudHMnO1xuXG5pbXBvcnQge1xuICBEYXRhU3RvcmVSZXBsaWNhLFxuICBpc0RhdGFTdG9yZU9wZXJhdGlvblxufSBmcm9tICcuL2RhdGEtc3RvcmUtcmVwbGljYS50cyc7XG5pbXBvcnQgeyBEYXRhU3RvcmVUcmFuc3BvcnQgfSBmcm9tICcuL2RhdGEtc3RvcmUtdHJhbnNwb3J0LnRzJztcblxuY29uc3QgREVGQVVMVF9BQ1RJVkVfREVWSUNFX01JTExJU0VDT05EUyA9IDJfNTkyXzAwMF8wMDA7XG5cbmNvbnN0IE9XTkVSX1BBVEhfSU5ERVggPSAtMjtcblxuY29uc3QgVkVDVE9SX0VOVFJZX0xFTkdUSCA9IDI7XG5jb25zdCBERVZJQ0VfUEFUSF9QQVJUUyA9IDI7XG5jb25zdCBSRUNPUkRfUFJFRklYID0gJ3NoYXJlZC1yZWNvcmQtdjE6JztcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciBvcGVuaW5nIGEgc2hhcmVkIHN0b3JlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNoYXJlZERhdGFTdG9yZU9wZW5QYXJhbXMge1xuICAvKipcbiAgICogRGV2aWNlIHJldGlyZW1lbnQgaW50ZXJ2YWwsIG1lYXN1cmVkIGZyb20gaXRzIGxhc3QgYWNrbm93bGVkZ2VtZW50LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgMjU5MjAwMDAwMGBcbiAgICovXG4gIHJlYWRvbmx5IGFjdGl2ZURldmljZU1pbGxpc2Vjb25kcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFZhdWx0IGFkYXB0ZXIuXG4gICAqL1xuICByZWFkb25seSBhZGFwdGVyOiBEYXRhQWRhcHRlcjtcbiAgLyoqXG4gICAqIFZhdWx0LXJlbGF0aXZlIGZvbGRlci4gSGlkZGVuIHNlZ21lbnRzIGFyZSBhbGxvd2VkOyBjYWxsZXJzIG11c3QgYXJyYW5nZSB0aGVpciBzeW5jaHJvbml6YXRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IGAnUGx1Z2luIGRhdGEnYFxuICAgKi9cbiAgcmVhZG9ubHkgZm9sZGVyPzogc3RyaW5nO1xuICAvKipcbiAgICogSW1tdXRhYmxlIG1lcmdlIHJ1bGU7IGNoYW5naW5nIGl0IHJlcXVpcmVzIGEgbmV3IHN0b3JlIGlkLlxuICAgKi9cbiAgcmVhZG9ubHkga2luZDogRGF0YVN0b3JlTWVyZ2VLaW5kO1xuICAvKipcbiAgICogRGVkaWNhdGVkIGxvY2FsIHN0b3JlIHNjb3BlZCB0byBUSElTIHZhdWx0LCBwbHVnaW4gYW5kIHNoYXJlZC1zdG9yZSBzY2hlbWEuIFRoZSBjYWxsZXIgb3ducyBpdHMgY29ubmVjdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2FsOiBMb2NhbERhdGFTdG9yZTtcbiAgLyoqXG4gICAqIE1heGltdW0gVVRGLTggYnl0ZXMgcGVyIGZpbGUsIHdyYXBwZXIgaW5jbHVkZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IGAxMDAwMDAwYFxuICAgKi9cbiAgcmVhZG9ubHkgbWF4RmlsZUJ5dGVzPzogbnVtYmVyO1xuICAvKipcbiAgICogUGx1Z2luIG1hbmlmZXN0IGlkLlxuICAgKi9cbiAgcmVhZG9ubHkgcGx1Z2luSWQ6IHN0cmluZztcbiAgLyoqXG4gICAqIFN0b3JlIGlkIGluY2x1ZGluZyB0aGUgY29uc3VtZXIncyBzY2hlbWEgdmVyc2lvbi5cbiAgICovXG4gIHJlYWRvbmx5IHN0b3JlSWQ6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIENoYW5nZSB7XG4gIHJlYWRvbmx5IGRlbGV0ZWQ6IGJvb2xlYW47XG4gIHJlYWRvbmx5IGtleTogc3RyaW5nO1xuICByZWFkb25seSB2YWx1ZTogSnNvblZhbHVlO1xufVxuXG5pbnRlcmZhY2UgQ2hlY2twb2ludCB7XG4gIHJlYWRvbmx5IGNvdW50ZXI6IG51bWJlcjtcbiAgcmVhZG9ubHkgZm9ybWF0OiAxO1xuICByZWFkb25seSBraW5kOiBEYXRhU3RvcmVNZXJnZUtpbmQ7XG4gIHJlYWRvbmx5IG9wZXJhdGlvbnM6IERhdGFTdG9yZU9wZXJhdGlvbltdO1xuICByZWFkb25seSB0aW1lOiBudW1iZXI7XG4gIHJlYWRvbmx5IHZlY3RvcjogVmVyc2lvblZlY3Rvcjtcbn1cblxudHlwZSBWZXJzaW9uVmVjdG9yID0gW3N0cmluZywgbnVtYmVyXVtdO1xuXG4vKipcbiAqIEEgZGV2aWNlLWxvY2FsIHF1ZXJ5IHJlcGxpY2EgYmFja2VkIGJ5IHZhdWx0IGZpbGVzLiBDYWxsIGBzeW5jaHJvbml6ZWAgYWZ0ZXIgdHJhbnNwb3J0IGNoYW5nZXMgb3IgcGVyaW9kaWNhbGx5LlxuICogTm8gdGltZXIgb3IgZXZlbnQgaGFuZGxlciBvdXRsaXZlcyB0aGUgY29uc3VtZXI6IHRoZSBjb25zdW1lciBzY2hlZHVsZXMgc3luY2hyb25pemF0aW9uIGFuZCBvd25zIHVubG9hZGluZy5cbiAqL1xuZXhwb3J0IGNsYXNzIFNoYXJlZERhdGFTdG9yZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgYWN0aXZlRGV2aWNlTWlsbGlzZWNvbmRzOiBudW1iZXI7XG4gIHByaXZhdGUgY291bnRlciA9IDA7XG4gIHByaXZhdGUgcmVhZG9ubHkgbG9jYWxSZWNvcmRzID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgcHJpdmF0ZSByZXBsaWNhOiBEYXRhU3RvcmVSZXBsaWNhO1xuICBwcml2YXRlIHRpbWUgPSAwO1xuICBwcml2YXRlIHJlYWRvbmx5IHRyYW5zcG9ydDogRGF0YVN0b3JlVHJhbnNwb3J0O1xuICBwcml2YXRlIHJlYWRvbmx5IHZlY3RvciA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgcmVhZG9ubHkgcGFyYW1zOiBTaGFyZWREYXRhU3RvcmVPcGVuUGFyYW1zLCBwcm90ZWN0ZWQgcmVhZG9ubHkgZGV2aWNlOiBzdHJpbmcpIHtcbiAgICB0aGlzLnRyYW5zcG9ydCA9IG5ldyBEYXRhU3RvcmVUcmFuc3BvcnQocGFyYW1zKTtcbiAgICB0aGlzLnJlcGxpY2EgPSBuZXcgRGF0YVN0b3JlUmVwbGljYShwYXJhbXMua2luZCk7XG4gICAgdGhpcy5hY3RpdmVEZXZpY2VNaWxsaXNlY29uZHMgPSBwYXJhbXMuYWN0aXZlRGV2aWNlTWlsbGlzZWNvbmRzID8/IERFRkFVTFRfQUNUSVZFX0RFVklDRV9NSUxMSVNFQ09ORFM7XG4gICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUodGhpcy5hY3RpdmVEZXZpY2VNaWxsaXNlY29uZHMpIHx8IHRoaXMuYWN0aXZlRGV2aWNlTWlsbGlzZWNvbmRzIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRGV2aWNlIHJldGlyZW1lbnQgaW50ZXJ2YWwgbXVzdCBiZSBwb3NpdGl2ZScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBPcGVucyBhbmQgc3luY2hyb25pemVzIGEgc3RvcmUsIHJlc3RvcmluZyBpdHMgZGV2aWNlIGlkZW50aXR5IGV4Y2x1c2l2ZWx5IGZyb20gSW5kZXhlZERCLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gUGVyc2lzdGVuY2UsIHRyYW5zcG9ydCBhbmQgbWVyZ2UgcG9saWN5LlxuICAgKiBAcmV0dXJucyBBIHN5bmNocm9uaXplZCBxdWVyeSByZXBsaWNhLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBhc3luYyBvcGVuKHBhcmFtczogU2hhcmVkRGF0YVN0b3JlT3BlblBhcmFtcyk6IFByb21pc2U8U2hhcmVkRGF0YVN0b3JlPiB7XG4gICAgY29uc3QgZGV2aWNlID0gYXdhaXQgcGFyYW1zLmxvY2FsLmdldE9yQ3JlYXRlKCdzaGFyZWQtZGV2aWNlLXYxJywgd2luZG93LmNyeXB0by5yYW5kb21VVUlEKCkpO1xuICAgIGlmICh0eXBlb2YgZGV2aWNlICE9PSAnc3RyaW5nJyB8fCAhL15bXFx3LV0rJC8udGVzdChkZXZpY2UpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgbG9jYWwgZGF0YS1zdG9yZSBpZGVudGl0eScpO1xuICAgIH1cbiAgICBjb25zdCBzdG9yZSA9IG5ldyBTaGFyZWREYXRhU3RvcmUocGFyYW1zLCBkZXZpY2UpO1xuICAgIGF3YWl0IHN0b3JlLnN5bmNocm9uaXplKCk7XG4gICAgcmV0dXJuIHN0b3JlO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1Ymxpc2hlcyBhIGNvbXBsZXRlIGNodW5rZWQgc25hcHNob3QgYW5kIHRyaW1zIG9ubHkgdGhpcyBkZXZpY2UncyBhY2tub3dsZWRnZWQgam91cm5hbCBzZWdtZW50cy5cbiAgICogUmV0aXJlZCBkZXZpY2VzIHJlam9pbiBieSBtZXJnaW5nIHNuYXBzaG90czsgdG9tYnN0b25lcyByZW1haW4gaW4gc25hcHNob3RzIHRvIHByZXZlbnQgcmVzdXJyZWN0aW9uLlxuICAgKlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGNvbXBhY3Rpb24gZmluaXNoZXMuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgY29tcGFjdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnBhcmFtcy5sb2NhbC5leGNsdXNpdmUoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgdGhpcy5sb2FkTG9jYWwoKTtcbiAgICAgIGF3YWl0IHRoaXMubWVyZ2VGaWxlcygpO1xuICAgICAgYXdhaXQgdGhpcy5wZXJzaXN0KCk7XG4gICAgICBjb25zdCBmaWxlcyA9IGF3YWl0IHRoaXMudHJhbnNwb3J0Lmxpc3QoKTtcbiAgICAgIGNvbnN0IGJhc2UgPSBgJHt0aGlzLmRldmljZVJvb3QoKX0vc25hcHNob3QtJHt3aW5kb3cuY3J5cHRvLnJhbmRvbVVVSUQoKX0tbWFuaWZlc3RgO1xuICAgICAgYXdhaXQgdGhpcy50cmFuc3BvcnQud3JpdGVTbmFwc2hvdCh7IGJhc2UsIHBheWxvYWQ6IHRoaXMuY2hlY2twb2ludCgpIH0pO1xuICAgICAgY29uc3QgYWNrbm93bGVkZ2VtZW50cyA9IGF3YWl0IHRoaXMuYWNrbm93bGVkZ2VtZW50cyhmaWxlcyk7XG4gICAgICBmb3IgKGNvbnN0IHBhdGggb2YgZmlsZXMpIHtcbiAgICAgICAgaWYgKCFwYXRoLnN0YXJ0c1dpdGgoYCR7dGhpcy5kZXZpY2VSb290KCl9L2xvZy1gKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9wZXJhdGlvbnMgPSBhd2FpdCB0aGlzLnRyYW5zcG9ydC5yZWFkKHBhdGgpO1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob3BlcmF0aW9ucykgfHwgIW9wZXJhdGlvbnMuZXZlcnkoaXNEYXRhU3RvcmVPcGVyYXRpb24pKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbGFzdCA9IE1hdGgubWF4KC4uLm9wZXJhdGlvbnMubWFwKChvcGVyYXRpb24pID0+IG9wZXJhdGlvbi5zZXF1ZW5jZSkpO1xuICAgICAgICBpZiAoYWNrbm93bGVkZ2VtZW50cy5ldmVyeSgodmVjdG9yKSA9PiAodmVjdG9yLmdldCh0aGlzLmRldmljZSkgPz8gMCkgPj0gbGFzdCkpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLnRyYW5zcG9ydC5yZW1vdmUocGF0aCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIFRoZSBjb21wbGV0ZSBuZXcgc25hcHNob3QgY292ZXJzIGV2ZXJ5IGVhcmxpZXIgc25hcHNob3QgZnJvbSB0aGlzIHdyaXRlci5cbiAgICAgIGZvciAoY29uc3QgcGF0aCBvZiBmaWxlcykge1xuICAgICAgICBpZiAocGF0aC5zdGFydHNXaXRoKGAke3RoaXMuZGV2aWNlUm9vdCgpfS9zbmFwc2hvdC1gKSkge1xuICAgICAgICAgIGF3YWl0IHRoaXMudHJhbnNwb3J0LnJlbW92ZShwYXRoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZXMgYSByZWdpc3RlciBvciByZW1vdmVzIHRoZSBjdXJyZW50bHkgb2JzZXJ2ZWQgYWRkaXRpb25zIG9mIGEgc2V0IG1lbWJlci5cbiAgICpcbiAgICogQHBhcmFtIGtleSAtIFJlY29yZCBrZXkgb3Igc2V0IG1lbWJlci4gTWluL21heCByZWdpc3RlcnMgZGVsaWJlcmF0ZWx5IGNhbm5vdCBiZSBkZWxldGVkLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciBqb3VybmFsIHB1YmxpY2F0aW9uIGFuZCBsb2NhbCBjb21taXQuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZGVsZXRlKGtleTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5jaGFuZ2UoW3sgZGVsZXRlZDogdHJ1ZSwga2V5LCB2YWx1ZTogbnVsbCB9XSk7XG4gIH1cblxuICAvKipcbiAgICogUmVhZHMgdGhlIGN1cnJlbnQgbG9jYWwgcXVlcnkgcmVwbGljYS5cbiAgICpcbiAgICogQHJldHVybnMgRGV0YWNoZWQga2V5L3ZhbHVlIHBhaXJzIGluIGRldGVybWluaXN0aWMgb3JkZXIuXG4gICAqL1xuICBwdWJsaWMgZW50cmllcygpOiBbc3RyaW5nLCB1bmtub3duXVtdIHtcbiAgICByZXR1cm4gdGhpcy5yZXBsaWNhLmVudHJpZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkcyBhIHJlZ2lzdGVyIG9yIHNldCBtZW1iZXJzaGlwIGZyb20gdGhlIGN1cnJlbnQgbG9jYWwgcXVlcnkgcmVwbGljYS5cbiAgICpcbiAgICogQHBhcmFtIGtleSAtIFJlY29yZCBrZXkgb3Igc2V0IG1lbWJlci5cbiAgICogQHJldHVybnMgQSBkZXRhY2hlZCB2YWx1ZSwgb3IgYHVuZGVmaW5lZGAgd2hlbiBhYnNlbnQgb3IgZGVsZXRlZC5cbiAgICovXG4gIHB1YmxpYyBnZXQoa2V5OiBzdHJpbmcpOiB1bmtub3duIHtcbiAgICByZXR1cm4gdGhpcy5yZXBsaWNhLmdldChrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdyaXRlcyBvbmUgcmVnaXN0ZXIgdmFsdWUsIG9yIGFkZHMgYSBtZW1iZXIgdG8gYW4gb2JzZXJ2ZWQtcmVtb3ZlIHNldC5cbiAgICpcbiAgICogQHBhcmFtIGtleSAtIFJlY29yZCBrZXkgb3Igc2V0IG1lbWJlci5cbiAgICogQHBhcmFtIHZhbHVlIC0gSlNPTi1jb21wYXRpYmxlIHZhbHVlICh1c2UgYHRydWVgIGZvciBhIHNldCkuXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIGpvdXJuYWwgcHVibGljYXRpb24gYW5kIGxvY2FsIGNvbW1pdC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBzZXQoa2V5OiBzdHJpbmcsIHZhbHVlOiBKc29uVmFsdWUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnNldE1hbnkoW1trZXksIHZhbHVlXV0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1Ymxpc2hlcyBhIGJhdGNoIG9mIHJlZ2lzdGVyIHdyaXRlcywgc3BsaXQgaW50byBib3VuZGVkIGltbXV0YWJsZSBzZWdtZW50cy5cbiAgICogU2VnbWVudHMgYXJlIGluZGl2aWR1YWxseSBkdXJhYmxlOyBhIGZhaWxlZCBiYXRjaCBjYW4gaGF2ZSBhIHB1Ymxpc2hlZCBwcmVmaXggYW5kIGNhbiBiZSByZXRyaWVkIHNhZmVseS5cbiAgICpcbiAgICogQHBhcmFtIGVudHJpZXMgLSBSZWdpc3RlciB3cml0ZXMgb3Igc2V0IGFkZGl0aW9ucy5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgam91cm5hbCBwdWJsaWNhdGlvbiBhbmQgbG9jYWwgY29tbWl0LlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHNldE1hbnkoZW50cmllczogcmVhZG9ubHkgKHJlYWRvbmx5IFtzdHJpbmcsIEpzb25WYWx1ZV0pW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmNoYW5nZShlbnRyaWVzLm1hcCgoW2tleSwgdmFsdWVdKSA9PiAoeyBkZWxldGVkOiBmYWxzZSwga2V5LCB2YWx1ZSB9KSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1lcmdlcyBjb21wbGV0ZSBzbmFwc2hvdHMgYW5kIGNvbnRpZ3VvdXMgam91cm5hbCBoaXN0b3J5LCB0aGVuIHB1Ymxpc2hlcyBpdHMgZHVyYWJsZSBhY2tub3dsZWRnZW1lbnQuXG4gICAqIFBhcnRpYWwgZGVsaXZlcmllcyByZW1haW4gcGVuZGluZzsgYSBsYXRlciBjYWxsIHJldHJpZXMgdGhlbS4gTm8gYWNrbm93bGVkZ2VtZW50IHNraXBzIGEgbWlzc2luZyBzZXF1ZW5jZS5cbiAgICpcbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgdGhlIGxvY2FsIGNoZWNrcG9pbnQgYW5kIGFja25vd2xlZGdlbWVudCBjb21taXQuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc3luY2hyb25pemUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5wYXJhbXMubG9jYWwuZXhjbHVzaXZlKGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMubG9hZExvY2FsKCk7XG4gICAgICBhd2FpdCB0aGlzLm1lcmdlRmlsZXMoKTtcbiAgICAgIGF3YWl0IHRoaXMucGVyc2lzdCgpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBhY2tub3dsZWRnZW1lbnRzKGZpbGVzOiByZWFkb25seSBzdHJpbmdbXSk6IFByb21pc2U8TWFwPHN0cmluZywgbnVtYmVyPltdPiB7XG4gICAgY29uc3QgYWNrbm93bGVkZ2VtZW50cyA9IFtuZXcgTWFwKHRoaXMudmVjdG9yKV07XG4gICAgY29uc3QgZGV2aWNlRmlsZXMgPSBmaWxlcy5maWx0ZXIoKHBhdGgpID0+IHBhdGguc3RhcnRzV2l0aChgJHt0aGlzLnRyYW5zcG9ydC5yb290fS9kZXZpY2VzL2ApKTtcbiAgICBjb25zdCBkZXZpY2VzID0gbmV3IFNldChkZXZpY2VGaWxlcy5tYXAoKHBhdGgpID0+IHBhdGguc2xpY2UodGhpcy50cmFuc3BvcnQucm9vdC5sZW5ndGggKyAxKS5zcGxpdCgnLycsIERFVklDRV9QQVRIX1BBUlRTKVsxXSkuZmlsdGVyKChkZXZpY2UpID0+IGRldmljZSAhPT0gdW5kZWZpbmVkKSk7XG4gICAgZm9yIChjb25zdCBkZXZpY2Ugb2YgZGV2aWNlcykge1xuICAgICAgaWYgKGRldmljZSA9PT0gdGhpcy5kZXZpY2UpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBoYXZlID0gYXdhaXQgdGhpcy50cmFuc3BvcnQucmVhZChgJHt0aGlzLnRyYW5zcG9ydC5yb290fS9kZXZpY2VzLyR7ZGV2aWNlfS9oYXZlLm1kYCk7XG4gICAgICBpZiAoIWlzT2JqZWN0KGhhdmUpIHx8ICFpc1ZlY3RvcihoYXZlWyd2ZWN0b3InXSkgfHwgdHlwZW9mIGhhdmVbJ3RpbWUnXSAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgYWNrbm93bGVkZ2VtZW50cy5wdXNoKG5ldyBNYXAoKSk7XG4gICAgICB9IGVsc2UgaWYgKERhdGUubm93KCkgLSBoYXZlWyd0aW1lJ10gPD0gdGhpcy5hY3RpdmVEZXZpY2VNaWxsaXNlY29uZHMpIHtcbiAgICAgICAgYWNrbm93bGVkZ2VtZW50cy5wdXNoKG5ldyBNYXAoaGF2ZVsndmVjdG9yJ10pKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFja25vd2xlZGdlbWVudHM7XG4gIH1cblxuICBwcml2YXRlIGFwcGx5KG9wZXJhdGlvbjogRGF0YVN0b3JlT3BlcmF0aW9uKTogdm9pZCB7XG4gICAgdGhpcy5yZXBsaWNhLmFwcGx5KG9wZXJhdGlvbik7XG4gICAgdGhpcy52ZWN0b3Iuc2V0KG9wZXJhdGlvbi5kZXZpY2UsIG9wZXJhdGlvbi5zZXF1ZW5jZSk7XG4gICAgdGhpcy5vYnNlcnZlQ2xvY2sob3BlcmF0aW9uLnRpbWUsIG9wZXJhdGlvbi5jb3VudGVyKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY2hhbmdlKGNoYW5nZXM6IHJlYWRvbmx5IENoYW5nZVtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5wYXJhbXMubG9jYWwuZXhjbHVzaXZlKGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMubG9hZExvY2FsKCk7XG4gICAgICBhd2FpdCB0aGlzLm1lcmdlRmlsZXMoKTtcbiAgICAgIGNvbnN0IG9wZXJhdGlvbnM6IERhdGFTdG9yZU9wZXJhdGlvbltdID0gW107XG4gICAgICBjb25zdCBjYW5kaWRhdGUgPSBuZXcgRGF0YVN0b3JlUmVwbGljYSh0aGlzLnBhcmFtcy5raW5kKTtcbiAgICAgIGZvciAoY29uc3Qgb3BlcmF0aW9uIG9mIHRoaXMucmVwbGljYS5leHBvcnQoKSkge1xuICAgICAgICBjYW5kaWRhdGUuYXBwbHkob3BlcmF0aW9uKTtcbiAgICAgIH1cbiAgICAgIGxldCBzZXF1ZW5jZSA9IHRoaXMudmVjdG9yLmdldCh0aGlzLmRldmljZSkgPz8gMDtcbiAgICAgIGZvciAoY29uc3QgY2hhbmdlIG9mIGNoYW5nZXMpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgdGhpcy5jb3VudGVyID0gbm93ID4gdGhpcy50aW1lID8gMCA6IHRoaXMuY291bnRlciArIDE7XG4gICAgICAgIHRoaXMudGltZSA9IE1hdGgubWF4KG5vdywgdGhpcy50aW1lKTtcbiAgICAgICAgY29uc3Qgb3BlcmF0aW9uOiBEYXRhU3RvcmVPcGVyYXRpb24gPSB7XG4gICAgICAgICAgLi4uY2hhbmdlLFxuICAgICAgICAgIGNvdW50ZXI6IHRoaXMuY291bnRlcixcbiAgICAgICAgICBkZXZpY2U6IHRoaXMuZGV2aWNlLFxuICAgICAgICAgIHNlcXVlbmNlOiArK3NlcXVlbmNlLFxuICAgICAgICAgIHRhZ3M6IGNhbmRpZGF0ZS5vYnNlcnZlZFRhZ3MoY2hhbmdlLmtleSksXG4gICAgICAgICAgdGltZTogdGhpcy50aW1lXG4gICAgICAgIH07XG4gICAgICAgIGNhbmRpZGF0ZS5hcHBseShvcGVyYXRpb24pO1xuICAgICAgICBvcGVyYXRpb25zLnB1c2gob3BlcmF0aW9uKTtcbiAgICAgIH1cbiAgICAgIC8vIFZhbGlkYXRlIGV2ZXJ5IHNpbmdsZSBvcGVyYXRpb24gYmVmb3JlIHB1Ymxpc2hpbmcgYW55IHByZWZpeCBvZiBhIGJhdGNoLlxuICAgICAgZm9yIChjb25zdCBvcGVyYXRpb24gb2Ygb3BlcmF0aW9ucykge1xuICAgICAgICBpZiAoIXRoaXMudHJhbnNwb3J0LmZpdHMoW29wZXJhdGlvbl0pKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy50cmFuc3BvcnQud3JpdGUoYCR7dGhpcy5kZXZpY2VSb290KCl9L2xvZy0ke1N0cmluZyhvcGVyYXRpb24uc2VxdWVuY2UpfS5tZGAsIFtvcGVyYXRpb25dKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGV0IGJhdGNoOiBEYXRhU3RvcmVPcGVyYXRpb25bXSA9IFtdO1xuICAgICAgZm9yIChjb25zdCBvcGVyYXRpb24gb2Ygb3BlcmF0aW9ucykge1xuICAgICAgICBpZiAoIXRoaXMudHJhbnNwb3J0LmZpdHMoWy4uLmJhdGNoLCBvcGVyYXRpb25dKSkge1xuICAgICAgICAgIGF3YWl0IHRoaXMucHVibGlzaChiYXRjaCk7XG4gICAgICAgICAgYmF0Y2ggPSBbXTtcbiAgICAgICAgfVxuICAgICAgICBiYXRjaC5wdXNoKG9wZXJhdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAoYmF0Y2gubGVuZ3RoID4gMCkge1xuICAgICAgICBhd2FpdCB0aGlzLnB1Ymxpc2goYmF0Y2gpO1xuICAgICAgfVxuICAgICAgYXdhaXQgdGhpcy5wZXJzaXN0KCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrcG9pbnQoKTogQ2hlY2twb2ludCB7XG4gICAgcmV0dXJuIHsgY291bnRlcjogdGhpcy5jb3VudGVyLCBmb3JtYXQ6IDEsIGtpbmQ6IHRoaXMucGFyYW1zLmtpbmQsIG9wZXJhdGlvbnM6IHRoaXMucmVwbGljYS5leHBvcnQoKSwgdGltZTogdGhpcy50aW1lLCB2ZWN0b3I6IFsuLi50aGlzLnZlY3Rvcl0gfTtcbiAgfVxuXG4gIHByaXZhdGUgZGV2aWNlUm9vdCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHt0aGlzLnRyYW5zcG9ydC5yb290fS9kZXZpY2VzLyR7dGhpcy5kZXZpY2V9YDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbG9hZExvY2FsKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMucmVwbGljYSA9IG5ldyBEYXRhU3RvcmVSZXBsaWNhKHRoaXMucGFyYW1zLmtpbmQpO1xuICAgIHRoaXMudmVjdG9yLmNsZWFyKCk7XG4gICAgdGhpcy50aW1lID0gMDtcbiAgICB0aGlzLmNvdW50ZXIgPSAwO1xuICAgIHRoaXMubG9jYWxSZWNvcmRzLmNsZWFyKCk7XG4gICAgY29uc3QgcmVjb3JkcyA9IGF3YWl0IHRoaXMucGFyYW1zLmxvY2FsLmVudHJpZXMoKTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiByZWNvcmRzKSB7XG4gICAgICBpZiAoa2V5ID09PSAnc2hhcmVkLWNoZWNrcG9pbnQtdjEnKSB7XG4gICAgICAgIHRoaXMubWVyZ2VDaGVja3BvaW50KHZhbHVlKTtcbiAgICAgIH0gZWxzZSBpZiAoa2V5LnN0YXJ0c1dpdGgoUkVDT1JEX1BSRUZJWCkpIHtcbiAgICAgICAgdGhpcy5yZXBsaWNhLmFwcGx5KHZhbHVlKTtcbiAgICAgICAgdGhpcy5sb2NhbFJlY29yZHMuc2V0KGtleSwgZW5zdXJlTm9uTnVsbGFibGUoSlNPTi5zdHJpbmdpZnkodmFsdWUpKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtZXJnZUNoZWNrcG9pbnQodmFsdWU6IHVua25vd24pOiB2b2lkIHtcbiAgICBpZiAoXG4gICAgICAhaXNPYmplY3QodmFsdWUpIHx8IHZhbHVlWydmb3JtYXQnXSAhPT0gMSB8fCB2YWx1ZVsna2luZCddICE9PSB0aGlzLnBhcmFtcy5raW5kXG4gICAgICB8fCAhQXJyYXkuaXNBcnJheSh2YWx1ZVsnb3BlcmF0aW9ucyddKSB8fCAhdmFsdWVbJ29wZXJhdGlvbnMnXS5ldmVyeShpc0RhdGFTdG9yZU9wZXJhdGlvbilcbiAgICAgIHx8ICFpc1ZlY3Rvcih2YWx1ZVsndmVjdG9yJ10pIHx8ICFOdW1iZXIuaXNTYWZlSW50ZWdlcih2YWx1ZVsndGltZSddKSB8fCAhTnVtYmVyLmlzU2FmZUludGVnZXIodmFsdWVbJ2NvdW50ZXInXSlcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBkYXRhLXN0b3JlIGNoZWNrcG9pbnQgb3IgaW5jb21wYXRpYmxlIG1lcmdlIHJ1bGUnKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBvcGVyYXRpb24gb2YgdmFsdWVbJ29wZXJhdGlvbnMnXSkge1xuICAgICAgdGhpcy5yZXBsaWNhLmFwcGx5KG9wZXJhdGlvbik7XG4gICAgfVxuICAgIGZvciAoY29uc3QgW2RldmljZSwgc2VxdWVuY2VdIG9mIHZhbHVlWyd2ZWN0b3InXSkge1xuICAgICAgdGhpcy52ZWN0b3Iuc2V0KGRldmljZSwgTWF0aC5tYXgoc2VxdWVuY2UsIHRoaXMudmVjdG9yLmdldChkZXZpY2UpID8/IDApKTtcbiAgICB9XG4gICAgdGhpcy5vYnNlcnZlQ2xvY2soTnVtYmVyKHZhbHVlWyd0aW1lJ10pLCBOdW1iZXIodmFsdWVbJ2NvdW50ZXInXSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBtZXJnZUZpbGVzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGFsbEZpbGVzID0gYXdhaXQgdGhpcy50cmFuc3BvcnQubGlzdCgpO1xuICAgIGNvbnN0IGZpbGVzID0gYWxsRmlsZXMuZmlsdGVyKChwYXRoKSA9PiBwYXRoLnN0YXJ0c1dpdGgoYCR7dGhpcy50cmFuc3BvcnQucm9vdH0vZGV2aWNlcy9gKSk7XG4gICAgY29uc3QgbWFuaWZlc3RzID0gZmlsZXMuZmlsdGVyKChmaWxlKSA9PiAvXFwvc25hcHNob3QtW1xcdy1dKy1tYW5pZmVzdFxcLm1kJC8udGVzdChmaWxlKSk7XG4gICAgZm9yIChjb25zdCBwYXRoIG9mIG1hbmlmZXN0cykge1xuICAgICAgY29uc3Qgc25hcHNob3QgPSBhd2FpdCB0aGlzLnRyYW5zcG9ydC5yZWFkU25hcHNob3QocGF0aCk7XG4gICAgICBpZiAoc25hcHNob3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLm1lcmdlQ2hlY2twb2ludChzbmFwc2hvdCk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IG9wZXJhdGlvbnM6IERhdGFTdG9yZU9wZXJhdGlvbltdID0gW107XG4gICAgY29uc3Qgc2VnbWVudHMgPSBmaWxlcy5maWx0ZXIoKGZpbGUpID0+IC9cXC9sb2ctXFxkK1xcLm1kJC8udGVzdChmaWxlKSk7XG4gICAgZm9yIChjb25zdCBwYXRoIG9mIHNlZ21lbnRzKSB7XG4gICAgICBjb25zdCBzZWdtZW50ID0gYXdhaXQgdGhpcy50cmFuc3BvcnQucmVhZChwYXRoKTtcbiAgICAgIGlmIChzZWdtZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoc2VnbWVudCkgfHwgIXNlZ21lbnQuZXZlcnkoaXNEYXRhU3RvcmVPcGVyYXRpb24pKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBkYXRhLXN0b3JlIGpvdXJuYWwgc2VnbWVudCcpO1xuICAgICAgfVxuICAgICAgY29uc3Qgb3duZXIgPSBwYXRoLnNwbGl0KCcvJykuYXQoT1dORVJfUEFUSF9JTkRFWCk7XG4gICAgICBpZiAoc2VnbWVudC5zb21lKChvcGVyYXRpb24pID0+IG9wZXJhdGlvbi5kZXZpY2UgIT09IG93bmVyKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0pvdXJuYWwgc2VnbWVudCBoYXMgYSBkaWZmZXJlbnQgd3JpdGVyJyk7XG4gICAgICB9XG4gICAgICBvcGVyYXRpb25zLnB1c2goLi4uc2VnbWVudCk7XG4gICAgfVxuICAgIG9wZXJhdGlvbnMuc29ydCgoZmlyc3QsIHNlY29uZCkgPT4gZmlyc3QuZGV2aWNlLmxvY2FsZUNvbXBhcmUoc2Vjb25kLmRldmljZSkgfHwgZmlyc3Quc2VxdWVuY2UgLSBzZWNvbmQuc2VxdWVuY2UpO1xuICAgIGZvciAoY29uc3Qgb3BlcmF0aW9uIG9mIG9wZXJhdGlvbnMpIHtcbiAgICAgIGlmIChvcGVyYXRpb24uc2VxdWVuY2UgPT09ICh0aGlzLnZlY3Rvci5nZXQob3BlcmF0aW9uLmRldmljZSkgPz8gMCkgKyAxKSB7XG4gICAgICAgIHRoaXMuYXBwbHkob3BlcmF0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG9ic2VydmVDbG9jayh0aW1lOiBudW1iZXIsIGNvdW50ZXI6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICh0aW1lID4gdGhpcy50aW1lKSB7XG4gICAgICB0aGlzLnRpbWUgPSB0aW1lO1xuICAgICAgdGhpcy5jb3VudGVyID0gY291bnRlcjtcbiAgICB9IGVsc2UgaWYgKHRpbWUgPT09IHRoaXMudGltZSkge1xuICAgICAgdGhpcy5jb3VudGVyID0gTWF0aC5tYXgodGhpcy5jb3VudGVyLCBjb3VudGVyKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHBlcnNpc3QoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY2hlY2twb2ludCA9IHRoaXMuY2hlY2twb2ludCgpO1xuICAgIGNvbnN0IHJlY29yZHMgPSBuZXcgTWFwPHN0cmluZywgRGF0YVN0b3JlT3BlcmF0aW9uPigpO1xuICAgIGZvciAoY29uc3Qgb3BlcmF0aW9uIG9mIGNoZWNrcG9pbnQub3BlcmF0aW9ucykge1xuICAgICAgY29uc3QgaWRlbnRpdHkgPSB0aGlzLnBhcmFtcy5raW5kID09PSAnb2JzZXJ2ZWQtcmVtb3ZlLXNldCcgPyBgJHtvcGVyYXRpb24uZGV2aWNlfToke1N0cmluZyhvcGVyYXRpb24uc2VxdWVuY2UpfWAgOiBvcGVyYXRpb24ua2V5O1xuICAgICAgcmVjb3Jkcy5zZXQoYCR7UkVDT1JEX1BSRUZJWH0ke2lkZW50aXR5fWAsIG9wZXJhdGlvbik7XG4gICAgfVxuICAgIGNvbnN0IGVudHJpZXM6IFtzdHJpbmcsIHVua25vd25dW10gPSBbLi4ucmVjb3Jkc10uZmlsdGVyKChba2V5LCB2YWx1ZV0pID0+IHRoaXMubG9jYWxSZWNvcmRzLmdldChrZXkpICE9PSBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpO1xuICAgIGNvbnN0IHJlbW92ZWRLZXlzID0gWy4uLnRoaXMubG9jYWxSZWNvcmRzLmtleXMoKV0uZmlsdGVyKChrZXkpID0+ICFyZWNvcmRzLmhhcyhrZXkpKTtcbiAgICBlbnRyaWVzLnB1c2goWydzaGFyZWQtY2hlY2twb2ludC12MScsIHsgLi4uY2hlY2twb2ludCwgb3BlcmF0aW9uczogW10gfV0pO1xuICAgIGF3YWl0IHRoaXMucGFyYW1zLmxvY2FsLmNvbW1pdCh7IGVudHJpZXMsIHJlbW92ZWRLZXlzIH0pO1xuICAgIGF3YWl0IHRoaXMudHJhbnNwb3J0LndyaXRlKGAke3RoaXMuZGV2aWNlUm9vdCgpfS9oYXZlLm1kYCwgeyBmb3JtYXQ6IDEsIHRpbWU6IERhdGUubm93KCksIHZlY3RvcjogWy4uLnRoaXMudmVjdG9yXSB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcHVibGlzaChvcGVyYXRpb25zOiBEYXRhU3RvcmVPcGVyYXRpb25bXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGZpcnN0ID0gZW5zdXJlTm9uTnVsbGFibGUob3BlcmF0aW9uc1swXSk7XG4gICAgYXdhaXQgdGhpcy50cmFuc3BvcnQud3JpdGUoYCR7dGhpcy5kZXZpY2VSb290KCl9L2xvZy0ke1N0cmluZyhmaXJzdC5zZXF1ZW5jZSl9Lm1kYCwgb3BlcmF0aW9ucyk7XG4gICAgZm9yIChjb25zdCBvcGVyYXRpb24gb2Ygb3BlcmF0aW9ucykge1xuICAgICAgdGhpcy5hcHBseShvcGVyYXRpb24pO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgIUFycmF5LmlzQXJyYXkodmFsdWUpO1xufVxuXG5mdW5jdGlvbiBpc1ZlY3Rvcih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFZlcnNpb25WZWN0b3Ige1xuICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUuZXZlcnkoKGVudHJ5OiB1bmtub3duKSA9PlxuICAgIEFycmF5LmlzQXJyYXkoZW50cnkpICYmIGVudHJ5Lmxlbmd0aCA9PT0gVkVDVE9SX0VOVFJZX0xFTkdUSFxuICAgICYmIHR5cGVvZiBlbnRyeVswXSA9PT0gJ3N0cmluZycgJiYgL15bXFx3LV0rJC8udGVzdChlbnRyeVswXSkgJiYgTnVtYmVyLmlzU2FmZUludGVnZXIoZW50cnlbMV0pICYmIE51bWJlcihlbnRyeVsxXSkgPj0gMFxuICApO1xufVxuXG4vKiBlc2xpbnQtZW5hYmxlIG4vbm8tdW5zdXBwb3J0ZWQtZmVhdHVyZXMvbm9kZS1idWlsdGlucyAtLSBUaGVzZSBhcmUgT2JzaWRpYW4gcmVuZGVyZXIgV2ViIEFQSXMsIG5vdCBOb2RlIGJ1aWx0aW5zLiAqL1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQVVBLFNBQVMseUJBQXlCO0FBUWxDO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1AsU0FBUywwQkFBMEI7QUFFbkMsTUFBTSxxQ0FBcUM7QUFFM0MsTUFBTSxtQkFBbUI7QUFFekIsTUFBTSxzQkFBc0I7QUFDNUIsTUFBTSxvQkFBb0I7QUFDMUIsTUFBTSxnQkFBZ0I7QUFtRWYsTUFBTSxnQkFBZ0I7QUFBQSxFQVNuQixZQUErQixRQUFzRCxRQUFnQjtBQUF0RTtBQUFzRDtBQUMzRixTQUFLLFlBQVksSUFBSSxtQkFBbUIsTUFBTTtBQUM5QyxTQUFLLFVBQVUsSUFBSSxpQkFBaUIsT0FBTyxJQUFJO0FBQy9DLFNBQUssMkJBQTJCLE9BQU8sNEJBQTRCO0FBQ25FLFFBQUksQ0FBQyxPQUFPLFNBQVMsS0FBSyx3QkFBd0IsS0FBSyxLQUFLLDRCQUE0QixHQUFHO0FBQ3pGLFlBQU0sSUFBSSxNQUFNLDZDQUE2QztBQUFBLElBQy9EO0FBQUEsRUFDRjtBQUFBLEVBUHVDO0FBQUEsRUFBc0Q7QUFBQSxFQVI1RTtBQUFBLEVBQ1QsVUFBVTtBQUFBLEVBQ0QsZUFBZSxvQkFBSSxJQUFvQjtBQUFBLEVBQ2hEO0FBQUEsRUFDQSxPQUFPO0FBQUEsRUFDRTtBQUFBLEVBQ0EsU0FBUyxvQkFBSSxJQUFvQjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBaUJsRCxhQUFvQixLQUFLLFFBQTZEO0FBQ3BGLFVBQU0sU0FBUyxNQUFNLE9BQU8sTUFBTSxZQUFZLG9CQUFvQixPQUFPLE9BQU8sV0FBVyxDQUFDO0FBQzVG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
469
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kYXRhLXN0b3Jlcy9zaGFyZWQtZGF0YS1zdG9yZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuL25vLXVuc3VwcG9ydGVkLWZlYXR1cmVzL25vZGUtYnVpbHRpbnMgLS0gVGhlc2UgYXJlIE9ic2lkaWFuIHJlbmRlcmVyIFdlYiBBUElzLCBub3QgTm9kZSBidWlsdGlucy4gKi9cbi8qKlxuICogQGZpbGVcbiAqXG4gKiBNZXJnZWFibGUgcGx1Z2luIGRhdGEsIHRyYW5zcG9ydGVkIGFzIHNpbmdsZS13cml0ZXIgam91cm5hbCBzZWdtZW50cyBhbmQgY2h1bmtlZCBzbmFwc2hvdHMuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBEYXRhQWRhcHRlciB9IGZyb20gJ29ic2lkaWFuJztcbmltcG9ydCB0eXBlIHsgSnNvblZhbHVlIH0gZnJvbSAndHlwZS1mZXN0JztcblxuaW1wb3J0IHsgZW5zdXJlTm9uTnVsbGFibGUgfSBmcm9tICdAbW5hb3Vtb3YvdHlwZXNjcmlwdC1saWIvdHlwZS1ndWFyZHMnO1xuXG5pbXBvcnQgdHlwZSB7IERhdGFTdG9yZUxvY2F0aW9uIH0gZnJvbSAnLi9kYXRhLXN0b3JlLWxvY2F0aW9ucy50cyc7XG5pbXBvcnQgdHlwZSB7XG4gIERhdGFTdG9yZU1lcmdlS2luZCxcbiAgRGF0YVN0b3JlT3BlcmF0aW9uXG59IGZyb20gJy4vZGF0YS1zdG9yZS1yZXBsaWNhLnRzJztcbmltcG9ydCB0eXBlIHsgTG9jYWxEYXRhU3RvcmUgfSBmcm9tICcuL2xvY2FsLWRhdGEtc3RvcmUudHMnO1xuXG5pbXBvcnQgeyBEYXRhU3RvcmVMb2NhdGlvbnMgfSBmcm9tICcuL2RhdGEtc3RvcmUtbG9jYXRpb25zLnRzJztcbmltcG9ydCB7XG4gIERhdGFTdG9yZVJlcGxpY2EsXG4gIGlzRGF0YVN0b3JlT3BlcmF0aW9uXG59IGZyb20gJy4vZGF0YS1zdG9yZS1yZXBsaWNhLnRzJztcbmltcG9ydCB7IERhdGFTdG9yZVRyYW5zcG9ydCB9IGZyb20gJy4vZGF0YS1zdG9yZS10cmFuc3BvcnQudHMnO1xuXG5jb25zdCBERUZBVUxUX0FDVElWRV9ERVZJQ0VfTUlMTElTRUNPTkRTID0gMl81OTJfMDAwXzAwMDtcblxuY29uc3QgT1dORVJfUEFUSF9JTkRFWCA9IC0yO1xuXG5jb25zdCBWRUNUT1JfRU5UUllfTEVOR1RIID0gMjtcbmNvbnN0IERFVklDRV9QQVRIX1BBUlRTID0gMjtcbmNvbnN0IERFVklDRV9JRF9SRUdfRVhQID0gL15bXFx3LV0rJC87XG5jb25zdCBSRUNPUkRfUFJFRklYID0gJ3NoYXJlZC1yZWNvcmQtdjE6JztcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciBvcGVuaW5nIGEgc2hhcmVkIHN0b3JlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNoYXJlZERhdGFTdG9yZU9wZW5QYXJhbXMge1xuICAvKipcbiAgICogRGV2aWNlIHJldGlyZW1lbnQgaW50ZXJ2YWwsIG1lYXN1cmVkIGZyb20gaXRzIGxhc3QgYWNrbm93bGVkZ2VtZW50LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgMjU5MjAwMDAwMGBcbiAgICovXG4gIHJlYWRvbmx5IGFjdGl2ZURldmljZU1pbGxpc2Vjb25kcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFZhdWx0IGFkYXB0ZXIuXG4gICAqL1xuICByZWFkb25seSBhZGFwdGVyOiBEYXRhQWRhcHRlcjtcbiAgLyoqXG4gICAqIFZhdWx0LXJlbGF0aXZlIGZvbGRlci4gSGlkZGVuIHNlZ21lbnRzIGFyZSBhbGxvd2VkOyBjYWxsZXJzIG11c3QgYXJyYW5nZSB0aGVpciBzeW5jaHJvbml6YXRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IGAnUGx1Z2luIGRhdGEnYFxuICAgKi9cbiAgcmVhZG9ubHkgZm9sZGVyPzogc3RyaW5nO1xuICAvKipcbiAgICogTmV3IGRvY3VtZW50IGVuY29kaW5nIGF0IHRoZSBwZXJtYW5lbnQgZGlzY292ZXJ5IGFuY2hvci5cbiAgICpcbiAgICogQGRlZmF1bHQgYCdtYXJrZG93bidgXG4gICAqL1xuICByZWFkb25seSBmb3JtYXQ/OiAnanNvbicgfCAnbWFya2Rvd24nO1xuICAvKipcbiAgICogRW5hYmxlcyB2YXVsdCB0cmFuc3BvcnQuIERpc2FibGVkIHN0b3JlcyBtYWtlIG5vIGFkYXB0ZXIgY2FsbHMsIGluY2x1ZGluZyBkdXJpbmcgY29tcGFjdGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgYHRydWVgXG4gICAqL1xuICByZWFkb25seSBpc1N5bmNFbmFibGVkPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIEltbXV0YWJsZSBtZXJnZSBydWxlOyBjaGFuZ2luZyBpdCByZXF1aXJlcyBhIG5ldyBzdG9yZSBpZC5cbiAgICovXG4gIHJlYWRvbmx5IGtpbmQ6IERhdGFTdG9yZU1lcmdlS2luZDtcbiAgLyoqXG4gICAqIERlZGljYXRlZCBsb2NhbCBzdG9yZSBzY29wZWQgdG8gVEhJUyB2YXVsdCwgcGx1Z2luIGFuZCBzaGFyZWQtc3RvcmUgc2NoZW1hLiBUaGUgY2FsbGVyIG93bnMgaXRzIGNvbm5lY3Rpb24uXG4gICAqL1xuICByZWFkb25seSBsb2NhbDogTG9jYWxEYXRhU3RvcmU7XG4gIC8qKlxuICAgKiBNYXhpbXVtIFVURi04IGJ5dGVzIHBlciBmaWxlLCB3cmFwcGVyIGluY2x1ZGVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgMTAwMDAwMGBcbiAgICovXG4gIHJlYWRvbmx5IG1heEZpbGVCeXRlcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIE1heGltdW0gVVRGLTggYnl0ZXMgaW4gYSByZWNvbnN0cnVjdGVkIHNuYXBzaG90IGJlZm9yZSBKU09OIHBhcnNpbmcuXG4gICAqXG4gICAqIEBkZWZhdWx0IGA2NDAwMDAwMGBcbiAgICovXG4gIHJlYWRvbmx5IG1heFNuYXBzaG90Qnl0ZXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBQbHVnaW4gbWFuaWZlc3QgaWQuXG4gICAqL1xuICByZWFkb25seSBwbHVnaW5JZDogc3RyaW5nO1xuICAvKipcbiAgICogU3RvcmUgaWQgaW5jbHVkaW5nIHRoZSBjb25zdW1lcidzIHNjaGVtYSB2ZXJzaW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RvcmVJZDogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgQ2hhbmdlIHtcbiAgcmVhZG9ubHkgZGVsZXRlZDogYm9vbGVhbjtcbiAgcmVhZG9ubHkga2V5OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHZhbHVlOiBKc29uVmFsdWU7XG59XG5cbmludGVyZmFjZSBDaGVja3BvaW50IHtcbiAgcmVhZG9ubHkgY291bnRlcjogbnVtYmVyO1xuICByZWFkb25seSBmb3JtYXQ6IDE7XG4gIHJlYWRvbmx5IGtpbmQ6IERhdGFTdG9yZU1lcmdlS2luZDtcbiAgcmVhZG9ubHkgb3BlcmF0aW9uczogRGF0YVN0b3JlT3BlcmF0aW9uW107XG4gIHJlYWRvbmx5IHRpbWU6IG51bWJlcjtcbiAgcmVhZG9ubHkgdmVjdG9yOiBWZXJzaW9uVmVjdG9yO1xufVxuXG50eXBlIFZlcnNpb25WZWN0b3IgPSBbc3RyaW5nLCBudW1iZXJdW107XG5cbi8qKlxuICogQSBkZXZpY2UtbG9jYWwgcXVlcnkgcmVwbGljYSBiYWNrZWQgYnkgdmF1bHQgZmlsZXMuIENhbGwgYHN5bmNocm9uaXplYCBhZnRlciB0cmFuc3BvcnQgY2hhbmdlcyBvciBwZXJpb2RpY2FsbHkuXG4gKiBObyB0aW1lciBvciBldmVudCBoYW5kbGVyIG91dGxpdmVzIHRoZSBjb25zdW1lcjogdGhlIGNvbnN1bWVyIHNjaGVkdWxlcyBzeW5jaHJvbml6YXRpb24gYW5kIG93bnMgdW5sb2FkaW5nLlxuICovXG5leHBvcnQgY2xhc3MgU2hhcmVkRGF0YVN0b3JlIHtcbiAgLyoqXG4gIENvbmZpZ3VyZWQgYW5kIHJlbWVtYmVyZWQgcmVhZGVyIHJvb3RzLCBpbmNsdWRpbmcgcmV0YWluZWQgbWlncmF0aW9uIHNvdXJjZXMgd2hpbGUgZGlzYWJsZWQuXG4gICAqXG4gICAqIEByZXR1cm5zIFVuaXF1ZSByb290cyBzdWl0YWJsZSBmb3IgbWV0YWRhdGEgZXhjbHVzaW9uIHdpdGhvdXQgYWRhcHRlciBhY2Nlc3MuXG4gICAqL1xuICBwdWJsaWMgZ2V0IHRyYW5zcG9ydFJvb3RzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gWy4uLm5ldyBTZXQoWy4uLnRoaXMua25vd25UcmFuc3BvcnRSb290cywgLi4udGhpcy5sb2NhdGlvbnMudHJhbnNwb3J0cy5tYXAoKHRyYW5zcG9ydCkgPT4gdHJhbnNwb3J0LnJvb3QpXSldO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBhY3RpdmVEZXZpY2VNaWxsaXNlY29uZHM6IG51bWJlcjtcbiAgcHJpdmF0ZSBjb3VudGVyID0gMDtcbiAgcHJpdmF0ZSBoYXNVbnB1Ymxpc2hlZENoYW5nZXMgPSBmYWxzZTtcbiAgcHJpdmF0ZSBpc1N5bmNFbmFibGVkOiBib29sZWFuO1xuICBwcml2YXRlIHJlYWRvbmx5IGtub3duVHJhbnNwb3J0Um9vdHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBsb2NhbFJlY29yZHMgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGxvY2F0aW9uczogRGF0YVN0b3JlTG9jYXRpb25zO1xuICBwcml2YXRlIHJlcGxpY2E6IERhdGFTdG9yZVJlcGxpY2E7XG4gIHByaXZhdGUgdGltZSA9IDA7XG5cbiAgcHJpdmF0ZSByZWFkb25seSB2ZWN0b3IgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuXG4gIHByaXZhdGUgZ2V0IHRyYW5zcG9ydCgpOiBEYXRhU3RvcmVUcmFuc3BvcnQge1xuICAgIHJldHVybiBlbnN1cmVOb25OdWxsYWJsZSh0aGlzLmxvY2F0aW9ucy50cmFuc3BvcnRzLmF0KC0xKSk7XG4gIH1cblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKHByb3RlY3RlZCByZWFkb25seSBwYXJhbXM6IFNoYXJlZERhdGFTdG9yZU9wZW5QYXJhbXMsIHByb3RlY3RlZCByZWFkb25seSBkZXZpY2U6IHN0cmluZykge1xuICAgIHRoaXMubG9jYXRpb25zID0gbmV3IERhdGFTdG9yZUxvY2F0aW9ucyhwYXJhbXMpO1xuICAgIHRoaXMuaXNTeW5jRW5hYmxlZCA9IHBhcmFtcy5pc1N5bmNFbmFibGVkID8/IHRydWU7XG4gICAgdGhpcy5yZXBsaWNhID0gbmV3IERhdGFTdG9yZVJlcGxpY2EocGFyYW1zLmtpbmQpO1xuICAgIHRoaXMuYWN0aXZlRGV2aWNlTWlsbGlzZWNvbmRzID0gcGFyYW1zLmFjdGl2ZURldmljZU1pbGxpc2Vjb25kcyA/PyBERUZBVUxUX0FDVElWRV9ERVZJQ0VfTUlMTElTRUNPTkRTO1xuICAgIGlmICghTnVtYmVyLmlzRmluaXRlKHRoaXMuYWN0aXZlRGV2aWNlTWlsbGlzZWNvbmRzKSB8fCB0aGlzLmFjdGl2ZURldmljZU1pbGxpc2Vjb25kcyA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RldmljZSByZXRpcmVtZW50IGludGVydmFsIG11c3QgYmUgcG9zaXRpdmUnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogT3BlbnMgYW5kIHN5bmNocm9uaXplcyBhIHN0b3JlLCByZXN0b3JpbmcgaXRzIGRldmljZSBpZGVudGl0eSBleGNsdXNpdmVseSBmcm9tIEluZGV4ZWREQi5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFBlcnNpc3RlbmNlLCB0cmFuc3BvcnQgYW5kIG1lcmdlIHBvbGljeS5cbiAgICogQHJldHVybnMgQSBzeW5jaHJvbml6ZWQgcXVlcnkgcmVwbGljYS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgb3BlbihwYXJhbXM6IFNoYXJlZERhdGFTdG9yZU9wZW5QYXJhbXMpOiBQcm9taXNlPFNoYXJlZERhdGFTdG9yZT4ge1xuICAgIGNvbnN0IGRldmljZSA9IGF3YWl0IHBhcmFtcy5sb2NhbC5nZXRPckNyZWF0ZSgnc2hhcmVkLWRldmljZS12MScsIHdpbmRvdy5jcnlwdG8ucmFuZG9tVVVJRCgpKTtcbiAgICBpZiAodHlwZW9mIGRldmljZSAhPT0gJ3N0cmluZycgfHwgIURFVklDRV9JRF9SRUdfRVhQLnRlc3QoZGV2aWNlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGxvY2FsIGRhdGEtc3RvcmUgaWRlbnRpdHknKTtcbiAgICB9XG4gICAgY29uc3Qgc3RvcmUgPSBuZXcgU2hhcmVkRGF0YVN0b3JlKHBhcmFtcywgZGV2aWNlKTtcbiAgICBhd2FpdCBzdG9yZS5zeW5jaHJvbml6ZSgpO1xuICAgIHJldHVybiBzdG9yZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaXNoZXMgYSBjb21wbGV0ZSBjaHVua2VkIHNuYXBzaG90IGFuZCB0cmltcyBvbmx5IHRoaXMgZGV2aWNlJ3MgYWNrbm93bGVkZ2VkIGpvdXJuYWwgc2VnbWVudHMuXG4gICAqIFJldGlyZWQgZGV2aWNlcyByZWpvaW4gYnkgbWVyZ2luZyBzbmFwc2hvdHM7IHRvbWJzdG9uZXMgcmVtYWluIGluIHNuYXBzaG90cyB0byBwcmV2ZW50IHJlc3VycmVjdGlvbi5cbiAgICpcbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBjb21wYWN0aW9uIGZpbmlzaGVzLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGNvbXBhY3QoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5wYXJhbXMubG9jYWwuZXhjbHVzaXZlKGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMubG9hZExvY2FsKCk7XG4gICAgICBhd2FpdCB0aGlzLm1lcmdlRmlsZXMoKTtcbiAgICAgIGF3YWl0IHRoaXMucGVyc2lzdCgpO1xuICAgICAgaWYgKCF0aGlzLmlzU3luY0VuYWJsZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgZmlsZXMgPSBhd2FpdCB0aGlzLnRyYW5zcG9ydC5saXN0KCk7XG4gICAgICBjb25zdCBiYXNlID0gYCR7dGhpcy5kZXZpY2VSb290KCl9L3NuYXBzaG90LSR7d2luZG93LmNyeXB0by5yYW5kb21VVUlEKCl9LW1hbmlmZXN0YDtcbiAgICAgIGF3YWl0IHRoaXMudHJhbnNwb3J0LndyaXRlU25hcHNob3QoeyBiYXNlLCBwYXlsb2FkOiB0aGlzLmNoZWNrcG9pbnQoKSB9KTtcbiAgICAgIGNvbnN0IGFja25vd2xlZGdlbWVudHMgPSBhd2FpdCB0aGlzLmFja25vd2xlZGdlbWVudHMoZmlsZXMpO1xuICAgICAgZm9yIChjb25zdCBwYXRoIG9mIGZpbGVzKSB7XG4gICAgICAgIGlmICghcGF0aC5zdGFydHNXaXRoKGAke3RoaXMuZGV2aWNlUm9vdCgpfS9sb2ctYCkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcGVyYXRpb25zID0gYXdhaXQgdGhpcy50cmFuc3BvcnQucmVhZChwYXRoKTtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9wZXJhdGlvbnMpIHx8ICFvcGVyYXRpb25zLmV2ZXJ5KGlzRGF0YVN0b3JlT3BlcmF0aW9uKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGxhc3QgPSBNYXRoLm1heCguLi5vcGVyYXRpb25zLm1hcCgob3BlcmF0aW9uKSA9PiBvcGVyYXRpb24uc2VxdWVuY2UpKTtcbiAgICAgICAgaWYgKGFja25vd2xlZGdlbWVudHMuZXZlcnkoKHZlY3RvcikgPT4gKHZlY3Rvci5nZXQodGhpcy5kZXZpY2UpID8/IDApID49IGxhc3QpKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy50cmFuc3BvcnQucmVtb3ZlKHBhdGgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBUaGUgY29tcGxldGUgbmV3IHNuYXBzaG90IGNvdmVycyBldmVyeSBlYXJsaWVyIHNuYXBzaG90IGZyb20gdGhpcyB3cml0ZXIuXG4gICAgICBmb3IgKGNvbnN0IHBhdGggb2YgZmlsZXMpIHtcbiAgICAgICAgaWYgKHBhdGguc3RhcnRzV2l0aChgJHt0aGlzLmRldmljZVJvb3QoKX0vc25hcHNob3QtYCkpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLnRyYW5zcG9ydC5yZW1vdmUocGF0aCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvZ25pemVzIHRyYW5zcG9ydCBmaWxlcywgcm9vdHMsIGFuZCBhbmNlc3RvciBmb2xkZXIgb3BlcmF0aW9ucyBmb3IgY29uc3VtZXIgZXZlbnQgZmlsdGVycy5cbiAgICpcbiAgICogQHBhcmFtIHBhdGggLSBWYXVsdC1yZWxhdGl2ZSBmaWxlIG9yIGZvbGRlciBwYXRoLlxuICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBwYXRoIGludGVyc2VjdHMgYW4gYWN0aXZlIG9yIHJldGFpbmVkIHRyYW5zcG9ydCByb290LlxuICAgKi9cbiAgcHVibGljIGNvbnRhaW5zVHJhbnNwb3J0UGF0aChwYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy50cmFuc3BvcnRSb290cy5zb21lKChyb290KSA9PiBwYXRoID09PSByb290IHx8IHBhdGguc3RhcnRzV2l0aChgJHtyb290fS9gKSB8fCByb290LnN0YXJ0c1dpdGgoYCR7cGF0aH0vYCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZXMgYSByZWdpc3RlciBvciByZW1vdmVzIHRoZSBjdXJyZW50bHkgb2JzZXJ2ZWQgYWRkaXRpb25zIG9mIGEgc2V0IG1lbWJlci5cbiAgICpcbiAgICogQHBhcmFtIGtleSAtIFJlY29yZCBrZXkgb3Igc2V0IG1lbWJlci4gTWluL21heCByZWdpc3RlcnMgZGVsaWJlcmF0ZWx5IGNhbm5vdCBiZSBkZWxldGVkLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciBqb3VybmFsIHB1YmxpY2F0aW9uIGFuZCBsb2NhbCBjb21taXQuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZGVsZXRlKGtleTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5jaGFuZ2UoW3sgZGVsZXRlZDogdHJ1ZSwga2V5LCB2YWx1ZTogbnVsbCB9XSk7XG4gIH1cblxuICAvKipcbiAgICogUmVhZHMgdGhlIGN1cnJlbnQgbG9jYWwgcXVlcnkgcmVwbGljYS5cbiAgICpcbiAgICogQHJldHVybnMgRGV0YWNoZWQga2V5L3ZhbHVlIHBhaXJzIGluIGRldGVybWluaXN0aWMgb3JkZXIuXG4gICAqL1xuICBwdWJsaWMgZW50cmllcygpOiBbc3RyaW5nLCB1bmtub3duXVtdIHtcbiAgICByZXR1cm4gdGhpcy5yZXBsaWNhLmVudHJpZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkcyBhIHJlZ2lzdGVyIG9yIHNldCBtZW1iZXJzaGlwIGZyb20gdGhlIGN1cnJlbnQgbG9jYWwgcXVlcnkgcmVwbGljYS5cbiAgICpcbiAgICogQHBhcmFtIGtleSAtIFJlY29yZCBrZXkgb3Igc2V0IG1lbWJlci5cbiAgICogQHJldHVybnMgQSBkZXRhY2hlZCB2YWx1ZSwgb3IgYHVuZGVmaW5lZGAgd2hlbiBhYnNlbnQgb3IgZGVsZXRlZC5cbiAgICovXG4gIHB1YmxpYyBnZXQoa2V5OiBzdHJpbmcpOiB1bmtub3duIHtcbiAgICByZXR1cm4gdGhpcy5yZXBsaWNhLmdldChrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbG9jYXRlcyBvbmx5IHRoaXMgcGx1Z2luL3N0b3JlIHN1YnRyZWU7IGtlZXAgb3BlbmluZyB3aXRoIHRoZSBvcmlnaW5hbCBhbmNob3IgcGFyYW1ldGVycy5cbiAgICpcbiAgICogQHBhcmFtIGxvY2F0aW9uIC0gTmV3IGZvbGRlciBhbmQgZG9jdW1lbnQgZm9ybWF0LlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciBoaXN0b3J5IGhhcyBiZWVuIGNvcGllZCBhbmQgdmVyaWZpZWQuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVsb2NhdGUobG9jYXRpb246IERhdGFTdG9yZUxvY2F0aW9uKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5wYXJhbXMubG9jYWwuZXhjbHVzaXZlKGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMubG9hZExvY2FsKCk7XG4gICAgICBpZiAoIXRoaXMuaXNTeW5jRW5hYmxlZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VuYWJsZSBkYXRhLXN0b3JlIHN5bmNocm9uaXphdGlvbiBiZWZvcmUgcmVsb2NhdGlvbicpO1xuICAgICAgfVxuICAgICAgYXdhaXQgdGhpcy5sb2NhdGlvbnMucmVsb2NhdGUobG9jYXRpb24pO1xuICAgICAgYXdhaXQgdGhpcy5tZXJnZUZpbGVzKCk7XG4gICAgICB0aGlzLmhhc1VucHVibGlzaGVkQ2hhbmdlcyA9IHRydWU7XG4gICAgICBhd2FpdCB0aGlzLnBlcnNpc3QoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXcml0ZXMgb25lIHJlZ2lzdGVyIHZhbHVlLCBvciBhZGRzIGEgbWVtYmVyIHRvIGFuIG9ic2VydmVkLXJlbW92ZSBzZXQuXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgLSBSZWNvcmQga2V5IG9yIHNldCBtZW1iZXIuXG4gICAqIEBwYXJhbSB2YWx1ZSAtIEpTT04tY29tcGF0aWJsZSB2YWx1ZSAodXNlIGB0cnVlYCBmb3IgYSBzZXQpLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciBqb3VybmFsIHB1YmxpY2F0aW9uIGFuZCBsb2NhbCBjb21taXQuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc2V0KGtleTogc3RyaW5nLCB2YWx1ZTogSnNvblZhbHVlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5zZXRNYW55KFtba2V5LCB2YWx1ZV1dKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaXNoZXMgYSBiYXRjaCBvZiByZWdpc3RlciB3cml0ZXMsIHNwbGl0IGludG8gYm91bmRlZCBpbW11dGFibGUgc2VnbWVudHMuXG4gICAqIFNlZ21lbnRzIGFyZSBpbmRpdmlkdWFsbHkgZHVyYWJsZTsgYSBmYWlsZWQgYmF0Y2ggY2FuIGhhdmUgYSBwdWJsaXNoZWQgcHJlZml4IGFuZCBjYW4gYmUgcmV0cmllZCBzYWZlbHkuXG4gICAqXG4gICAqIEBwYXJhbSBlbnRyaWVzIC0gUmVnaXN0ZXIgd3JpdGVzIG9yIHNldCBhZGRpdGlvbnMuXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIGpvdXJuYWwgcHVibGljYXRpb24gYW5kIGxvY2FsIGNvbW1pdC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBzZXRNYW55KGVudHJpZXM6IHJlYWRvbmx5IChyZWFkb25seSBbc3RyaW5nLCBKc29uVmFsdWVdKVtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5jaGFuZ2UoZW50cmllcy5tYXAoKFtrZXksIHZhbHVlXSkgPT4gKHsgZGVsZXRlZDogZmFsc2UsIGtleSwgdmFsdWUgfSkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUb2dnbGVzIHRyYW5zcG9ydCB3aXRob3V0IGNoYW5naW5nIGlkZW50aXR5IG9yIGNhdXNhbCBzdGF0ZS4gUGVyc2lzdCB0aGUgcHJlZmVyZW5jZSBpbiBjb25zdW1lciBzZXR0aW5ncy5cbiAgICogRW5hYmxpbmcgcHVibGlzaGVzIGEgY29tcGxldGUgY2hlY2twb2ludCBzbyBvZmZsaW5lIHNlcXVlbmNlcyBjYW5ub3QgbGVhdmUgZ2Fwcy5cbiAgICpcbiAgICogQHBhcmFtIGlzRW5hYmxlZCAtIFdoZXRoZXIgdG8gdXNlIHZhdWx0IHRyYW5zcG9ydCBmb3Igc3Vic2VxdWVudCBjYWxscyBvbiB0aGlzIGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciBzeW5jaHJvbml6YXRpb24gd2hlbiBlbmFibGluZy5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBzZXRTeW5jRW5hYmxlZChpc0VuYWJsZWQ6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnBhcmFtcy5sb2NhbC5leGNsdXNpdmUoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgdGhpcy5sb2FkTG9jYWwoKTtcbiAgICAgIHRoaXMuaXNTeW5jRW5hYmxlZCA9IGlzRW5hYmxlZDtcbiAgICAgIGF3YWl0IHRoaXMubWVyZ2VGaWxlcygpO1xuICAgICAgYXdhaXQgdGhpcy5wZXJzaXN0KCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTWVyZ2VzIGNvbXBsZXRlIHNuYXBzaG90cyBhbmQgY29udGlndW91cyBqb3VybmFsIGhpc3RvcnksIHRoZW4gcHVibGlzaGVzIGl0cyBkdXJhYmxlIGFja25vd2xlZGdlbWVudC5cbiAgICogUGFydGlhbCBkZWxpdmVyaWVzIHJlbWFpbiBwZW5kaW5nOyBhIGxhdGVyIGNhbGwgcmV0cmllcyB0aGVtLiBObyBhY2tub3dsZWRnZW1lbnQgc2tpcHMgYSBtaXNzaW5nIHNlcXVlbmNlLlxuICAgKlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgbG9jYWwgY2hlY2twb2ludCBhbmQgYWNrbm93bGVkZ2VtZW50IGNvbW1pdC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBzeW5jaHJvbml6ZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnBhcmFtcy5sb2NhbC5leGNsdXNpdmUoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgdGhpcy5sb2FkTG9jYWwoKTtcbiAgICAgIGF3YWl0IHRoaXMubWVyZ2VGaWxlcygpO1xuICAgICAgYXdhaXQgdGhpcy5wZXJzaXN0KCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGFja25vd2xlZGdlbWVudHMoZmlsZXM6IHJlYWRvbmx5IHN0cmluZ1tdKTogUHJvbWlzZTxNYXA8c3RyaW5nLCBudW1iZXI+W10+IHtcbiAgICBjb25zdCBhY2tub3dsZWRnZW1lbnRzID0gW25ldyBNYXAodGhpcy52ZWN0b3IpXTtcbiAgICBjb25zdCBkZXZpY2VzUHJlZml4ID0gYCR7dGhpcy50cmFuc3BvcnQucm9vdH0vZGV2aWNlcy9gO1xuICAgIGNvbnN0IGRldmljZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBmb3IgKGNvbnN0IHBhdGggb2YgZmlsZXMpIHtcbiAgICAgIGlmICghcGF0aC5zdGFydHNXaXRoKGRldmljZXNQcmVmaXgpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgLy8gT25seSBhIGZvbGRlciB1bmRlciBgZGV2aWNlcy9gIGlzIGEgZGV2aWNlOyBhIHN0cmF5IGZpbGUgdGhlcmUgKHN1Y2ggYXMgbWFjT1MgYC5EU19TdG9yZWApIG9yIGEgZm9sZGVyIHdob3NlXG4gICAgICAvLyBuYW1lIGlzIG5vdCBhIHZhbGlkIGRldmljZSBpZCBpcyBub3Qgb25lLCBhbmQgY291bnRpbmcgaXQgd291bGQgYmxvY2sgZXZlcnkgdHJpbSBiZWhpbmQgYW4gYWNrbm93bGVkZ2VtZW50XG4gICAgICAvLyB0aGF0IG5ldmVyIGFycml2ZXMuXG4gICAgICBjb25zdCBwYXJ0cyA9IHBhdGguc2xpY2UoZGV2aWNlc1ByZWZpeC5sZW5ndGgpLnNwbGl0KCcvJyk7XG4gICAgICBjb25zdCBkZXZpY2UgPSBwYXJ0c1swXTtcbiAgICAgIGlmIChwYXJ0cy5sZW5ndGggPj0gREVWSUNFX1BBVEhfUEFSVFMgJiYgZGV2aWNlICE9PSB1bmRlZmluZWQgJiYgREVWSUNFX0lEX1JFR19FWFAudGVzdChkZXZpY2UpKSB7XG4gICAgICAgIGRldmljZXMuYWRkKGRldmljZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGZvciAoY29uc3QgZGV2aWNlIG9mIGRldmljZXMpIHtcbiAgICAgIGlmIChkZXZpY2UgPT09IHRoaXMuZGV2aWNlKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgaGF2ZSA9IGF3YWl0IHRoaXMudHJhbnNwb3J0LnJlYWQoYCR7dGhpcy50cmFuc3BvcnQucm9vdH0vZGV2aWNlcy8ke2RldmljZX0vaGF2ZSR7dGhpcy50cmFuc3BvcnQuZXh0ZW5zaW9ufWApO1xuICAgICAgaWYgKCFpc09iamVjdChoYXZlKSB8fCAhaXNWZWN0b3IoaGF2ZVsndmVjdG9yJ10pIHx8IHR5cGVvZiBoYXZlWyd0aW1lJ10gIT09ICdudW1iZXInKSB7XG4gICAgICAgIGFja25vd2xlZGdlbWVudHMucHVzaChuZXcgTWFwKCkpO1xuICAgICAgfSBlbHNlIGlmIChEYXRlLm5vdygpIC0gaGF2ZVsndGltZSddIDw9IHRoaXMuYWN0aXZlRGV2aWNlTWlsbGlzZWNvbmRzKSB7XG4gICAgICAgIGFja25vd2xlZGdlbWVudHMucHVzaChuZXcgTWFwKGhhdmVbJ3ZlY3RvciddKSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhY2tub3dsZWRnZW1lbnRzO1xuICB9XG5cbiAgcHJpdmF0ZSBhcHBseShvcGVyYXRpb246IERhdGFTdG9yZU9wZXJhdGlvbik6IHZvaWQge1xuICAgIHRoaXMucmVwbGljYS5hcHBseShvcGVyYXRpb24pO1xuICAgIHRoaXMudmVjdG9yLnNldChvcGVyYXRpb24uZGV2aWNlLCBvcGVyYXRpb24uc2VxdWVuY2UpO1xuICAgIHRoaXMub2JzZXJ2ZUNsb2NrKG9wZXJhdGlvbi50aW1lLCBvcGVyYXRpb24uY291bnRlcik7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNoYW5nZShjaGFuZ2VzOiByZWFkb25seSBDaGFuZ2VbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMucGFyYW1zLmxvY2FsLmV4Y2x1c2l2ZShhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCB0aGlzLmxvYWRMb2NhbCgpO1xuICAgICAgYXdhaXQgdGhpcy5tZXJnZUZpbGVzKCk7XG4gICAgICBjb25zdCBvcGVyYXRpb25zOiBEYXRhU3RvcmVPcGVyYXRpb25bXSA9IFtdO1xuICAgICAgY29uc3QgY2FuZGlkYXRlID0gbmV3IERhdGFTdG9yZVJlcGxpY2EodGhpcy5wYXJhbXMua2luZCk7XG4gICAgICBmb3IgKGNvbnN0IG9wZXJhdGlvbiBvZiB0aGlzLnJlcGxpY2EuZXhwb3J0KCkpIHtcbiAgICAgICAgY2FuZGlkYXRlLmFwcGx5KG9wZXJhdGlvbik7XG4gICAgICB9XG4gICAgICBsZXQgc2VxdWVuY2UgPSB0aGlzLnZlY3Rvci5nZXQodGhpcy5kZXZpY2UpID8/IDA7XG4gICAgICBmb3IgKGNvbnN0IGNoYW5nZSBvZiBjaGFuZ2VzKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgIHRoaXMuY291bnRlciA9IG5vdyA+IHRoaXMudGltZSA/IDAgOiB0aGlzLmNvdW50ZXIgKyAxO1xuICAgICAgICB0aGlzLnRpbWUgPSBNYXRoLm1heChub3csIHRoaXMudGltZSk7XG4gICAgICAgIGNvbnN0IG9wZXJhdGlvbjogRGF0YVN0b3JlT3BlcmF0aW9uID0ge1xuICAgICAgICAgIC4uLmNoYW5nZSxcbiAgICAgICAgICBjb3VudGVyOiB0aGlzLmNvdW50ZXIsXG4gICAgICAgICAgZGV2aWNlOiB0aGlzLmRldmljZSxcbiAgICAgICAgICBzZXF1ZW5jZTogKytzZXF1ZW5jZSxcbiAgICAgICAgICB0YWdzOiBjYW5kaWRhdGUub2JzZXJ2ZWRUYWdzKGNoYW5nZS5rZXkpLFxuICAgICAgICAgIHRpbWU6IHRoaXMudGltZVxuICAgICAgICB9O1xuICAgICAgICBjYW5kaWRhdGUuYXBwbHkob3BlcmF0aW9uKTtcbiAgICAgICAgb3BlcmF0aW9ucy5wdXNoKG9wZXJhdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuaXNTeW5jRW5hYmxlZCkge1xuICAgICAgICBmb3IgKGNvbnN0IG9wZXJhdGlvbiBvZiBvcGVyYXRpb25zKSB7XG4gICAgICAgICAgdGhpcy5hcHBseShvcGVyYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaGFzVW5wdWJsaXNoZWRDaGFuZ2VzID0gdHJ1ZTtcbiAgICAgICAgYXdhaXQgdGhpcy5wZXJzaXN0KCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIC8vIFZhbGlkYXRlIGV2ZXJ5IHNpbmdsZSBvcGVyYXRpb24gYmVmb3JlIHB1Ymxpc2hpbmcgYW55IHByZWZpeCBvZiBhIGJhdGNoLlxuICAgICAgZm9yIChjb25zdCBvcGVyYXRpb24gb2Ygb3BlcmF0aW9ucykge1xuICAgICAgICBpZiAoIXRoaXMudHJhbnNwb3J0LmZpdHMoW29wZXJhdGlvbl0pKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy50cmFuc3BvcnQud3JpdGUoYCR7dGhpcy5kZXZpY2VSb290KCl9L2xvZy0ke1N0cmluZyhvcGVyYXRpb24uc2VxdWVuY2UpfSR7dGhpcy50cmFuc3BvcnQuZXh0ZW5zaW9ufWAsIFtvcGVyYXRpb25dKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGV0IGJhdGNoOiBEYXRhU3RvcmVPcGVyYXRpb25bXSA9IFtdO1xuICAgICAgZm9yIChjb25zdCBvcGVyYXRpb24gb2Ygb3BlcmF0aW9ucykge1xuICAgICAgICBpZiAoIXRoaXMudHJhbnNwb3J0LmZpdHMoWy4uLmJhdGNoLCBvcGVyYXRpb25dKSkge1xuICAgICAgICAgIGF3YWl0IHRoaXMucHVibGlzaChiYXRjaCk7XG4gICAgICAgICAgYmF0Y2ggPSBbXTtcbiAgICAgICAgfVxuICAgICAgICBiYXRjaC5wdXNoKG9wZXJhdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAoYmF0Y2gubGVuZ3RoID4gMCkge1xuICAgICAgICBhd2FpdCB0aGlzLnB1Ymxpc2goYmF0Y2gpO1xuICAgICAgfVxuICAgICAgYXdhaXQgdGhpcy5wZXJzaXN0KCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrcG9pbnQoKTogQ2hlY2twb2ludCB7XG4gICAgcmV0dXJuIHsgY291bnRlcjogdGhpcy5jb3VudGVyLCBmb3JtYXQ6IDEsIGtpbmQ6IHRoaXMucGFyYW1zLmtpbmQsIG9wZXJhdGlvbnM6IHRoaXMucmVwbGljYS5leHBvcnQoKSwgdGltZTogdGhpcy50aW1lLCB2ZWN0b3I6IFsuLi50aGlzLnZlY3Rvcl0gfTtcbiAgfVxuXG4gIHByaXZhdGUgZGV2aWNlUm9vdCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHt0aGlzLnRyYW5zcG9ydC5yb290fS9kZXZpY2VzLyR7dGhpcy5kZXZpY2V9YDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbG9hZExvY2FsKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMucmVwbGljYSA9IG5ldyBEYXRhU3RvcmVSZXBsaWNhKHRoaXMucGFyYW1zLmtpbmQpO1xuICAgIHRoaXMudmVjdG9yLmNsZWFyKCk7XG4gICAgdGhpcy50aW1lID0gMDtcbiAgICB0aGlzLmNvdW50ZXIgPSAwO1xuICAgIHRoaXMubG9jYWxSZWNvcmRzLmNsZWFyKCk7XG4gICAgdGhpcy5rbm93blRyYW5zcG9ydFJvb3RzLmNsZWFyKCk7XG4gICAgdGhpcy5oYXNVbnB1Ymxpc2hlZENoYW5nZXMgPSBmYWxzZTtcbiAgICBjb25zdCByZWNvcmRzID0gYXdhaXQgdGhpcy5wYXJhbXMubG9jYWwuZW50cmllcygpO1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIHJlY29yZHMpIHtcbiAgICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICAgIGNhc2UgJ3NoYXJlZC1jaGVja3BvaW50LXYxJzoge1xuICAgICAgICAgIHRoaXMubWVyZ2VDaGVja3BvaW50KHZhbHVlKTtcblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ3NoYXJlZC10cmFuc3BvcnQtcm9vdHMtdjEnOiB7XG4gICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBsb2NhbCBkYXRhLXN0b3JlIHRyYW5zcG9ydCByb290cycpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBzdWZmaXggPSBgLyR7dGhpcy5wYXJhbXMucGx1Z2luSWR9LyR7dGhpcy5wYXJhbXMuc3RvcmVJZH1gO1xuICAgICAgICAgIGZvciAoY29uc3Qgcm9vdCBvZiB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiByb290ICE9PSAnc3RyaW5nJyB8fCAhcm9vdC5lbmRzV2l0aChzdWZmaXgpKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBsb2NhbCBkYXRhLXN0b3JlIHRyYW5zcG9ydCByb290cycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gVmFsaWRhdGUgcmVtZW1iZXJlZCBwYXRocyB3aXRob3V0IHJlYWRpbmcgdGhlIGFkYXB0ZXIgb3IgYWN0aXZhdGluZyBhIHdyaXRlci5cbiAgICAgICAgICAgIGNvbnN0IHRyYW5zcG9ydCA9IG5ldyBEYXRhU3RvcmVUcmFuc3BvcnQoeyAuLi50aGlzLnBhcmFtcywgZm9sZGVyOiByb290LnNsaWNlKDAsIC1zdWZmaXgubGVuZ3RoKSB9KTtcbiAgICAgICAgICAgIHRoaXMua25vd25UcmFuc3BvcnRSb290cy5hZGQodHJhbnNwb3J0LnJvb3QpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ3NoYXJlZC11bnB1Ymxpc2hlZC12MSc6IHtcbiAgICAgICAgICB0aGlzLmhhc1VucHVibGlzaGVkQ2hhbmdlcyA9IHZhbHVlID09PSB0cnVlO1xuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgIGlmIChrZXkuc3RhcnRzV2l0aChSRUNPUkRfUFJFRklYKSkge1xuICAgICAgICAgICAgdGhpcy5yZXBsaWNhLmFwcGx5KHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMubG9jYWxSZWNvcmRzLnNldChrZXksIGVuc3VyZU5vbk51bGxhYmxlKEpTT04uc3RyaW5naWZ5KHZhbHVlKSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbWVyZ2VDaGVja3BvaW50KHZhbHVlOiB1bmtub3duKTogdm9pZCB7XG4gICAgaWYgKFxuICAgICAgIWlzT2JqZWN0KHZhbHVlKSB8fCB2YWx1ZVsnZm9ybWF0J10gIT09IDEgfHwgdmFsdWVbJ2tpbmQnXSAhPT0gdGhpcy5wYXJhbXMua2luZFxuICAgICAgfHwgIUFycmF5LmlzQXJyYXkodmFsdWVbJ29wZXJhdGlvbnMnXSkgfHwgIXZhbHVlWydvcGVyYXRpb25zJ10uZXZlcnkoaXNEYXRhU3RvcmVPcGVyYXRpb24pXG4gICAgICB8fCAhaXNWZWN0b3IodmFsdWVbJ3ZlY3RvciddKSB8fCAhTnVtYmVyLmlzU2FmZUludGVnZXIodmFsdWVbJ3RpbWUnXSkgfHwgIU51bWJlci5pc1NhZmVJbnRlZ2VyKHZhbHVlWydjb3VudGVyJ10pXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZGF0YS1zdG9yZSBjaGVja3BvaW50IG9yIGluY29tcGF0aWJsZSBtZXJnZSBydWxlJyk7XG4gICAgfVxuICAgIGZvciAoY29uc3Qgb3BlcmF0aW9uIG9mIHZhbHVlWydvcGVyYXRpb25zJ10pIHtcbiAgICAgIHRoaXMucmVwbGljYS5hcHBseShvcGVyYXRpb24pO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IFtkZXZpY2UsIHNlcXVlbmNlXSBvZiB2YWx1ZVsndmVjdG9yJ10pIHtcbiAgICAgIHRoaXMudmVjdG9yLnNldChkZXZpY2UsIE1hdGgubWF4KHNlcXVlbmNlLCB0aGlzLnZlY3Rvci5nZXQoZGV2aWNlKSA/PyAwKSk7XG4gICAgfVxuICAgIHRoaXMub2JzZXJ2ZUNsb2NrKE51bWJlcih2YWx1ZVsndGltZSddKSwgTnVtYmVyKHZhbHVlWydjb3VudGVyJ10pKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbWVyZ2VGaWxlcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuaXNTeW5jRW5hYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBhd2FpdCB0aGlzLmxvY2F0aW9ucy5yZWZyZXNoKCk7XG4gICAgZm9yIChjb25zdCB0cmFuc3BvcnQgb2YgdGhpcy5sb2NhdGlvbnMudHJhbnNwb3J0cykge1xuICAgICAgYXdhaXQgdGhpcy5tZXJnZVRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbWVyZ2VUcmFuc3BvcnQodHJhbnNwb3J0OiBEYXRhU3RvcmVUcmFuc3BvcnQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBhbGxGaWxlcyA9IGF3YWl0IHRyYW5zcG9ydC5saXN0KCk7XG4gICAgY29uc3QgZmlsZXMgPSBhbGxGaWxlcy5maWx0ZXIoKHBhdGgpID0+IHBhdGguc3RhcnRzV2l0aChgJHt0cmFuc3BvcnQucm9vdH0vZGV2aWNlcy9gKSk7XG4gICAgY29uc3QgbWFuaWZlc3RzID0gZmlsZXMuZmlsdGVyKChmaWxlKSA9PiAvXFwvc25hcHNob3QtW1xcdy1dKy1tYW5pZmVzdFxcLig/Om1kfGpzb24pJC8udGVzdChmaWxlKSk7XG4gICAgZm9yIChjb25zdCBwYXRoIG9mIG1hbmlmZXN0cykge1xuICAgICAgY29uc3Qgc25hcHNob3QgPSBhd2FpdCB0cmFuc3BvcnQucmVhZFNuYXBzaG90KHBhdGgpO1xuICAgICAgaWYgKHNuYXBzaG90ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5tZXJnZUNoZWNrcG9pbnQoc25hcHNob3QpO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBvcGVyYXRpb25zOiBEYXRhU3RvcmVPcGVyYXRpb25bXSA9IFtdO1xuICAgIGNvbnN0IHNlZ21lbnRzID0gZmlsZXMuZmlsdGVyKChmaWxlKSA9PiAvXFwvbG9nLVxcZCtcXC4oPzptZHxqc29uKSQvLnRlc3QoZmlsZSkpO1xuICAgIGZvciAoY29uc3QgcGF0aCBvZiBzZWdtZW50cykge1xuICAgICAgY29uc3Qgc2VnbWVudCA9IGF3YWl0IHRyYW5zcG9ydC5yZWFkKHBhdGgpO1xuICAgICAgaWYgKHNlZ21lbnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShzZWdtZW50KSB8fCAhc2VnbWVudC5ldmVyeShpc0RhdGFTdG9yZU9wZXJhdGlvbikpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRhdGEtc3RvcmUgam91cm5hbCBzZWdtZW50Jyk7XG4gICAgICB9XG4gICAgICBjb25zdCBvd25lciA9IHBhdGguc3BsaXQoJy8nKS5hdChPV05FUl9QQVRIX0lOREVYKTtcbiAgICAgIGlmIChzZWdtZW50LnNvbWUoKG9wZXJhdGlvbikgPT4gb3BlcmF0aW9uLmRldmljZSAhPT0gb3duZXIpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSm91cm5hbCBzZWdtZW50IGhhcyBhIGRpZmZlcmVudCB3cml0ZXInKTtcbiAgICAgIH1cbiAgICAgIG9wZXJhdGlvbnMucHVzaCguLi5zZWdtZW50KTtcbiAgICB9XG4gICAgb3BlcmF0aW9ucy5zb3J0KChmaXJzdCwgc2Vjb25kKSA9PiBmaXJzdC5kZXZpY2UubG9jYWxlQ29tcGFyZShzZWNvbmQuZGV2aWNlKSB8fCBmaXJzdC5zZXF1ZW5jZSAtIHNlY29uZC5zZXF1ZW5jZSk7XG4gICAgZm9yIChjb25zdCBvcGVyYXRpb24gb2Ygb3BlcmF0aW9ucykge1xuICAgICAgaWYgKG9wZXJhdGlvbi5zZXF1ZW5jZSA9PT0gKHRoaXMudmVjdG9yLmdldChvcGVyYXRpb24uZGV2aWNlKSA/PyAwKSArIDEpIHtcbiAgICAgICAgdGhpcy5hcHBseShvcGVyYXRpb24pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb2JzZXJ2ZUNsb2NrKHRpbWU6IG51bWJlciwgY291bnRlcjogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHRpbWUgPiB0aGlzLnRpbWUpIHtcbiAgICAgIHRoaXMudGltZSA9IHRpbWU7XG4gICAgICB0aGlzLmNvdW50ZXIgPSBjb3VudGVyO1xuICAgIH0gZWxzZSBpZiAodGltZSA9PT0gdGhpcy50aW1lKSB7XG4gICAgICB0aGlzLmNvdW50ZXIgPSBNYXRoLm1heCh0aGlzLmNvdW50ZXIsIGNvdW50ZXIpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcGVyc2lzdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBjaGVja3BvaW50ID0gdGhpcy5jaGVja3BvaW50KCk7XG4gICAgY29uc3QgcmVjb3JkcyA9IG5ldyBNYXA8c3RyaW5nLCBEYXRhU3RvcmVPcGVyYXRpb24+KCk7XG4gICAgZm9yIChjb25zdCBvcGVyYXRpb24gb2YgY2hlY2twb2ludC5vcGVyYXRpb25zKSB7XG4gICAgICBjb25zdCBpZGVudGl0eSA9IHRoaXMucGFyYW1zLmtpbmQgPT09ICdvYnNlcnZlZC1yZW1vdmUtc2V0JyA/IGAke29wZXJhdGlvbi5kZXZpY2V9OiR7U3RyaW5nKG9wZXJhdGlvbi5zZXF1ZW5jZSl9YCA6IG9wZXJhdGlvbi5rZXk7XG4gICAgICByZWNvcmRzLnNldChgJHtSRUNPUkRfUFJFRklYfSR7aWRlbnRpdHl9YCwgb3BlcmF0aW9uKTtcbiAgICB9XG4gICAgY29uc3QgZW50cmllczogW3N0cmluZywgdW5rbm93bl1bXSA9IFsuLi5yZWNvcmRzXS5maWx0ZXIoKFtrZXksIHZhbHVlXSkgPT4gdGhpcy5sb2NhbFJlY29yZHMuZ2V0KGtleSkgIT09IEpTT04uc3RyaW5naWZ5KHZhbHVlKSk7XG4gICAgY29uc3QgcmVtb3ZlZEtleXMgPSBbLi4udGhpcy5sb2NhbFJlY29yZHMua2V5cygpXS5maWx0ZXIoKGtleSkgPT4gIXJlY29yZHMuaGFzKGtleSkpO1xuICAgIGVudHJpZXMucHVzaChbJ3NoYXJlZC1jaGVja3BvaW50LXYxJywgeyAuLi5jaGVja3BvaW50LCBvcGVyYXRpb25zOiBbXSB9XSwgWydzaGFyZWQtdW5wdWJsaXNoZWQtdjEnLCB0aGlzLmhhc1VucHVibGlzaGVkQ2hhbmdlc10sIFsnc2hhcmVkLXRyYW5zcG9ydC1yb290cy12MScsIHRoaXMudHJhbnNwb3J0Um9vdHNdKTtcbiAgICBhd2FpdCB0aGlzLnBhcmFtcy5sb2NhbC5jb21taXQoeyBlbnRyaWVzLCByZW1vdmVkS2V5cyB9KTtcbiAgICBpZiAoIXRoaXMuaXNTeW5jRW5hYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5oYXNVbnB1Ymxpc2hlZENoYW5nZXMpIHtcbiAgICAgIGF3YWl0IHRoaXMudHJhbnNwb3J0LndyaXRlU25hcHNob3QoeyBiYXNlOiBgJHt0aGlzLmRldmljZVJvb3QoKX0vc25hcHNob3QtJHt3aW5kb3cuY3J5cHRvLnJhbmRvbVVVSUQoKX0tbWFuaWZlc3RgLCBwYXlsb2FkOiBjaGVja3BvaW50IH0pO1xuICAgICAgYXdhaXQgdGhpcy5wYXJhbXMubG9jYWwuc2V0KCdzaGFyZWQtdW5wdWJsaXNoZWQtdjEnLCBmYWxzZSk7XG4gICAgICB0aGlzLmhhc1VucHVibGlzaGVkQ2hhbmdlcyA9IGZhbHNlO1xuICAgIH1cbiAgICBhd2FpdCB0aGlzLnRyYW5zcG9ydC53cml0ZShgJHt0aGlzLmRldmljZVJvb3QoKX0vaGF2ZSR7dGhpcy50cmFuc3BvcnQuZXh0ZW5zaW9ufWAsIHsgZm9ybWF0OiAxLCB0aW1lOiBEYXRlLm5vdygpLCB2ZWN0b3I6IFsuLi50aGlzLnZlY3Rvcl0gfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHB1Ymxpc2gob3BlcmF0aW9uczogRGF0YVN0b3JlT3BlcmF0aW9uW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBmaXJzdCA9IGVuc3VyZU5vbk51bGxhYmxlKG9wZXJhdGlvbnNbMF0pO1xuICAgIGF3YWl0IHRoaXMudHJhbnNwb3J0LndyaXRlSW1tdXRhYmxlKGAke3RoaXMuZGV2aWNlUm9vdCgpfS9sb2ctJHtTdHJpbmcoZmlyc3Quc2VxdWVuY2UpfSR7dGhpcy50cmFuc3BvcnQuZXh0ZW5zaW9ufWAsIG9wZXJhdGlvbnMpO1xuICAgIGZvciAoY29uc3Qgb3BlcmF0aW9uIG9mIG9wZXJhdGlvbnMpIHtcbiAgICAgIHRoaXMuYXBwbHkob3BlcmF0aW9uKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNPYmplY3QodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmICFBcnJheS5pc0FycmF5KHZhbHVlKTtcbn1cblxuZnVuY3Rpb24gaXNWZWN0b3IodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBWZXJzaW9uVmVjdG9yIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmV2ZXJ5KChlbnRyeTogdW5rbm93bikgPT5cbiAgICBBcnJheS5pc0FycmF5KGVudHJ5KSAmJiBlbnRyeS5sZW5ndGggPT09IFZFQ1RPUl9FTlRSWV9MRU5HVEhcbiAgICAmJiB0eXBlb2YgZW50cnlbMF0gPT09ICdzdHJpbmcnICYmIC9eW1xcdy1dKyQvLnRlc3QoZW50cnlbMF0pICYmIE51bWJlci5pc1NhZmVJbnRlZ2VyKGVudHJ5WzFdKSAmJiBOdW1iZXIoZW50cnlbMV0pID49IDBcbiAgKTtcbn1cblxuLyogZXNsaW50LWVuYWJsZSBuL25vLXVuc3VwcG9ydGVkLWZlYXR1cmVzL25vZGUtYnVpbHRpbnMgLS0gVGhlc2UgYXJlIE9ic2lkaWFuIHJlbmRlcmVyIFdlYiBBUElzLCBub3QgTm9kZSBidWlsdGlucy4gKi9cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFVQSxTQUFTLHlCQUF5QjtBQVNsQyxTQUFTLDBCQUEwQjtBQUNuQztBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMsMEJBQTBCO0FBRW5DLE1BQU0scUNBQXFDO0FBRTNDLE1BQU0sbUJBQW1CO0FBRXpCLE1BQU0sc0JBQXNCO0FBQzVCLE1BQU0sb0JBQW9CO0FBQzFCLE1BQU0sb0JBQW9CO0FBQzFCLE1BQU0sZ0JBQWdCO0FBcUZmLE1BQU0sZ0JBQWdCO0FBQUEsRUEwQm5CLFlBQStCLFFBQXNELFFBQWdCO0FBQXRFO0FBQXNEO0FBQzNGLFNB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