@blokjs/trigger-worker 0.4.0 → 0.6.2

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 (37) hide show
  1. package/__tests__/integration/nats-adapter.real-nats.test.ts +116 -0
  2. package/__tests__/integration/pgboss-adapter.real-pg.test.ts +164 -0
  3. package/__tests__/integration/rabbitmq-adapter.real-rabbitmq.test.ts +179 -0
  4. package/__tests__/integration/sqs-adapter.real-sqs.test.ts +228 -0
  5. package/dist/WorkerTrigger.d.ts +37 -1
  6. package/dist/WorkerTrigger.js +142 -21
  7. package/dist/adapters/InMemoryAdapter.js +10 -5
  8. package/dist/adapters/KafkaAdapter.d.ts +62 -0
  9. package/dist/adapters/KafkaAdapter.js +236 -0
  10. package/dist/adapters/NATSAdapter.js +3 -3
  11. package/dist/adapters/PgBossAdapter.d.ts +56 -0
  12. package/dist/adapters/PgBossAdapter.js +251 -0
  13. package/dist/adapters/RabbitMQAdapter.d.ts +51 -0
  14. package/dist/adapters/RabbitMQAdapter.js +241 -0
  15. package/dist/adapters/RedisStreamsAdapter.d.ts +64 -0
  16. package/dist/adapters/RedisStreamsAdapter.js +240 -0
  17. package/dist/adapters/SQSAdapter.d.ts +61 -0
  18. package/dist/adapters/SQSAdapter.js +269 -0
  19. package/dist/adapters/factory.d.ts +34 -0
  20. package/dist/adapters/factory.js +103 -0
  21. package/dist/index.d.ts +21 -4
  22. package/dist/index.js +24 -4
  23. package/package.json +23 -5
  24. package/src/WorkerTrigger.ts +153 -22
  25. package/src/adapters/InMemoryAdapter.ts +9 -5
  26. package/src/adapters/KafkaAdapter.ts +277 -0
  27. package/src/adapters/NATSAdapter.ts +4 -2
  28. package/src/adapters/PgBossAdapter.ts +293 -0
  29. package/src/adapters/RabbitMQAdapter.ts +285 -0
  30. package/src/adapters/RedisStreamsAdapter.ts +286 -0
  31. package/src/adapters/SQSAdapter.ts +306 -0
  32. package/src/adapters/factory.test.ts +89 -0
  33. package/src/adapters/factory.ts +111 -0
  34. package/src/adapters/new-adapters.test.ts +130 -0
  35. package/src/index.ts +30 -4
  36. package/template/package.json +6 -6
  37. package/template/src/workflows/jobs/process-job.ts +37 -35
@@ -70,8 +70,14 @@ export class InMemoryAdapter {
70
70
  if (!this.connected) {
71
71
  throw new Error("Not connected. Call connect() first.");
72
72
  }
73
- if (!this.jobs.has(queue)) {
74
- this.jobs.set(queue, []);
73
+ // Get-or-init the per-queue job list. Same pattern as `stats`
74
+ // below — the previous code used `set-if-absent` then `.get()!`,
75
+ // but that non-null assertion is what biome flags. Pulling the
76
+ // reference once and seeding when missing keeps the type exact.
77
+ let jobs = this.jobs.get(queue);
78
+ if (!jobs) {
79
+ jobs = [];
80
+ this.jobs.set(queue, jobs);
75
81
  }
76
82
  if (!this.stats.has(queue)) {
77
83
  this.stats.set(queue, { completed: 0, failed: 0 });
@@ -91,7 +97,6 @@ export class InMemoryAdapter {
91
97
  if (job.status === "delayed") {
92
98
  job.scheduledAt = new Date(Date.now() + job.delay);
93
99
  }
94
- const jobs = this.jobs.get(queue);
95
100
  // Insert sorted by priority (higher first)
96
101
  const insertIdx = jobs.findIndex((j) => j.status === "waiting" && j.priority < job.priority);
97
102
  if (insertIdx >= 0) {
@@ -182,7 +187,7 @@ export class InMemoryAdapter {
182
187
  internalJob.error = error;
183
188
  if (requeue && internalJob.attempts < internalJob.maxRetries) {
184
189
  // Requeue with backoff
185
- const backoff = Math.min(1000 * Math.pow(2, internalJob.attempts), 30000);
190
+ const backoff = Math.min(1000 * 2 ** internalJob.attempts, 30000);
186
191
  internalJob.status = "delayed";
187
192
  internalJob.scheduledAt = new Date(Date.now() + backoff);
188
193
  }
@@ -217,4 +222,4 @@ export class InMemoryAdapter {
217
222
  }
218
223
  }
219
224
  }
220
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5NZW1vcnlBZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXJzL0luTWVtb3J5QWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFHSCxPQUFPLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQWdDbEM7O0dBRUc7QUFDSCxNQUFNLE9BQU8sZUFBZTtJQUNsQixRQUFRLEdBQUcsV0FBb0IsQ0FBQztJQUNqQyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ2xCLElBQUksR0FBK0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUM3QyxVQUFVLEdBQWdDLElBQUksR0FBRyxFQUFFLENBQUM7SUFDcEQsS0FBSyxHQUF1RCxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRTlFLEtBQUssQ0FBQyxPQUFPO1FBQ1osSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7SUFDdkIsQ0FBQztJQUVELEtBQUssQ0FBQyxVQUFVO1FBQ2Ysc0JBQXNCO1FBQ3RCLEtBQUssTUFBTSxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDbEQsU0FBUyxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7WUFDMUIsSUFBSSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3JCLGFBQWEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEMsQ0FBQztRQUNGLENBQUM7UUFDRCxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDO0lBRUQsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUF5QixFQUFFLE9BQTBDO1FBQ2xGLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDckIsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3pELENBQUM7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDbEMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNqQyxDQUFDO1FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ25DLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzNELENBQUM7UUFFRCxNQUFNLFNBQVMsR0FBbUI7WUFDakMsTUFBTTtZQUNOLE9BQU87WUFDUCxNQUFNLEVBQUUsQ0FBQztZQUNULE9BQU8sRUFBRSxJQUFJO1NBQ2IsQ0FBQztRQUVGLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFN0MseUJBQXlCO1FBQ3pCLFNBQVMsQ0FBQyxLQUFLLEdBQUcsV0FBVyxDQUFDLEdBQUcsRUFBRTtZQUNsQyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtnQkFDNUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxzQ0FBc0MsTUFBTSxDQUFDLEtBQUssS0FBTSxHQUFhLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUNoRyxDQUFDLENBQUMsQ0FBQztRQUNKLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLGtCQUFrQjtJQUMzQixDQUFDO0lBRUQsS0FBSyxDQUFDLE1BQU0sQ0FDWCxLQUFhLEVBQ2IsSUFBYSxFQUNiLElBTUM7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3JCLE1BQU0sSUFBSSxLQUFLLENBQUMsc0NBQXNDLENBQUMsQ0FBQztRQUN6RCxDQUFDO1FBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzFCLENBQUM7UUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM1QixJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3BELENBQUM7UUFFRCxNQUFNLEdBQUcsR0FBZ0I7WUFDeEIsRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLElBQUksSUFBSSxFQUFFO1lBQ3pCLElBQUk7WUFDSixLQUFLO1lBQ0wsUUFBUSxFQUFFLElBQUksRUFBRSxRQUFRLElBQUksQ0FBQztZQUM3QixRQUFRLEVBQUUsQ0FBQztZQUNYLFVBQVUsRUFBRSxJQUFJLEVBQUUsT0FBTyxJQUFJLENBQUM7WUFDOUIsU0FBUyxFQUFFLElBQUksSUFBSSxFQUFFO1lBQ3JCLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxJQUFJLENBQUM7WUFDdkIsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLElBQUksQ0FBQztZQUMzQixNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTO1NBQzdELENBQUM7UUFFRixJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDOUIsR0FBRyxDQUFDLFdBQVcsR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BELENBQUM7UUFFRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUUsQ0FBQztRQUVuQywyQ0FBMkM7UUFDM0MsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxTQUFTLElBQUksQ0FBQyxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDN0YsSUFBSSxTQUFTLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDcEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2hDLENBQUM7YUFBTSxDQUFDO1lBQ1AsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNoQixDQUFDO1FBRUQsT0FBTyxHQUFHLENBQUMsRUFBRSxDQUFDO0lBQ2YsQ0FBQztJQUVELEtBQUssQ0FBQyxjQUFjLENBQUMsS0FBYTtRQUNqQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM3QyxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQ2YsU0FBUyxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7WUFDMUIsSUFBSSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3JCLGFBQWEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEMsQ0FBQztZQUNELElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQy9CLENBQUM7SUFDRixDQUFDO0lBRUQsV0FBVztRQUNWLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUN2QixDQUFDO0lBRUQsS0FBSyxDQUFDLFdBQVc7UUFDaEIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxLQUFLLENBQUMsYUFBYSxDQUFDLEtBQWE7UUFDaEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3hDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFFeEUsT0FBTztZQUNOLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxLQUFLLFNBQVMsQ0FBQyxDQUFDLE1BQU07WUFDMUQsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEtBQUssUUFBUSxDQUFDLENBQUMsTUFBTTtZQUN4RCxTQUFTLEVBQUUsVUFBVSxDQUFDLFNBQVM7WUFDL0IsTUFBTSxFQUFFLFVBQVUsQ0FBQyxNQUFNO1lBQ3pCLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxLQUFLLFNBQVMsQ0FBQyxDQUFDLE1BQU07U0FDMUQsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNLLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBYTtRQUN0QyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM3QyxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU87WUFBRSxPQUFPO1FBRTdDLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsV0FBVyxJQUFJLENBQUMsQ0FBQztRQUN0RCxJQUFJLFNBQVMsQ0FBQyxNQUFNLElBQUksV0FBVztZQUFFLE9BQU87UUFFNUMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFPO1FBRXZDLHdDQUF3QztRQUN4QyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDdkIsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUN4QixJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssU0FBUyxJQUFJLEdBQUcsQ0FBQyxXQUFXLElBQUksR0FBRyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxHQUFHLEVBQUUsQ0FBQztnQkFDckYsR0FBRyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUM7WUFDeEIsQ0FBQztRQUNGLENBQUM7UUFFRCx3QkFBd0I7UUFDeEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxTQUFTLENBQUMsQ0FBQztRQUM3RCxJQUFJLE1BQU0sR0FBRyxDQUFDO1lBQUUsT0FBTztRQUV2QixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDakMsV0FBVyxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUM7UUFDOUIsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBRW5CLE1BQU0sU0FBUyxHQUFjO1lBQzVCLEVBQUUsRUFBRSxXQUFXLENBQUMsRUFBRTtZQUNsQixJQUFJLEVBQUUsV0FBVyxDQUFDLElBQUk7WUFDdEIsT0FBTyxFQUFFLEVBQUU7WUFDWCxLQUFLLEVBQUUsV0FBVyxDQUFDLEtBQUs7WUFDeEIsUUFBUSxFQUFFLFdBQVcsQ0FBQyxRQUFRO1lBQzlCLFFBQVEsRUFBRSxXQUFXLENBQUMsUUFBUTtZQUM5QixVQUFVLEVBQUUsV0FBVyxDQUFDLFVBQVU7WUFDbEMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxTQUFTO1lBQ2hDLEtBQUssRUFBRSxXQUFXLENBQUMsS0FBSztZQUN4QixPQUFPLEVBQUUsV0FBVyxDQUFDLE9BQU87WUFDNUIsR0FBRyxFQUFFLFdBQVc7WUFDaEIsUUFBUSxFQUFFLEtBQUssSUFBSSxFQUFFO2dCQUNwQixXQUFXLENBQUMsTUFBTSxHQUFHLFdBQVcsQ0FBQztnQkFDakMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDdEMsSUFBSSxHQUFHLElBQUksQ0FBQztvQkFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDbEMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2hDLElBQUksQ0FBQztvQkFBRSxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDdEIsQ0FBQztZQUNELElBQUksRUFBRSxLQUFLLEVBQUUsS0FBWSxFQUFFLE9BQWlCLEVBQUUsRUFBRTtnQkFDL0MsV0FBVyxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUN2QixXQUFXLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztnQkFFMUIsSUFBSSxPQUFPLElBQUksV0FBVyxDQUFDLFFBQVEsR0FBRyxXQUFXLENBQUMsVUFBVSxFQUFFLENBQUM7b0JBQzlELHVCQUF1QjtvQkFDdkIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO29CQUMxRSxXQUFXLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQztvQkFDL0IsV0FBVyxDQUFDLFdBQVcsR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsT0FBTyxDQUFDLENBQUM7Z0JBQzFELENBQUM7cUJBQU0sQ0FBQztvQkFDUCxXQUFXLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQztvQkFDOUIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztvQkFDdEMsSUFBSSxHQUFHLElBQUksQ0FBQzt3QkFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztvQkFDbEMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ2hDLElBQUksQ0FBQzt3QkFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ25CLENBQUM7WUFDRixDQUFDO1NBQ0QsQ0FBQztRQUVGLElBQUksQ0FBQztZQUNKLE1BQU0sU0FBUyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNwQyxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1IsbUNBQW1DO1lBQ25DLElBQUksV0FBVyxDQUFDLE1BQU0sS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFDckMsV0FBVyxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUM7Z0JBQzlCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQ3RDLElBQUksR0FBRyxJQUFJLENBQUM7b0JBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ2xDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNoQyxJQUFJLENBQUM7b0JBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ25CLENBQUM7UUFDRixDQUFDO2dCQUFTLENBQUM7WUFDVixTQUFTLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDcEIsQ0FBQztJQUNGLENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogSW5NZW1vcnlBZGFwdGVyIC0gV29ya2VyIGFkYXB0ZXIgdXNpbmcgaW4tcHJvY2VzcyBxdWV1ZXNcbiAqXG4gKiBJZGVhbCBmb3I6XG4gKiAtIERldmVsb3BtZW50IGFuZCB0ZXN0aW5nXG4gKiAtIFNpbXBsZSBiYWNrZ3JvdW5kIGpvYiBwcm9jZXNzaW5nXG4gKiAtIFNpbmdsZS1pbnN0YW5jZSBkZXBsb3ltZW50c1xuICpcbiAqIExpbWl0YXRpb25zOlxuICogLSBKb2JzIGFyZSBsb3N0IG9uIHByb2Nlc3MgcmVzdGFydFxuICogLSBObyBkaXN0cmlidXRlZCBwcm9jZXNzaW5nXG4gKiAtIE5vIHBlcnNpc3RlbmNlXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGFkYXB0ZXIgPSBuZXcgSW5NZW1vcnlBZGFwdGVyKCk7XG4gKiBgYGBcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFdvcmtlclRyaWdnZXJPcHRzIH0gZnJvbSBcIkBibG9ranMvaGVscGVyXCI7XG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSBcInV1aWRcIjtcbmltcG9ydCB0eXBlIHsgV29ya2VyQWRhcHRlciwgV29ya2VySm9iLCBXb3JrZXJRdWV1ZVN0YXRzIH0gZnJvbSBcIi4uL1dvcmtlclRyaWdnZXJcIjtcblxuLyoqXG4gKiBJbnRlcm5hbCBqb2IgcmVwcmVzZW50YXRpb25cbiAqL1xuaW50ZXJmYWNlIEludGVybmFsSm9iIHtcblx0aWQ6IHN0cmluZztcblx0ZGF0YTogdW5rbm93bjtcblx0cXVldWU6IHN0cmluZztcblx0cHJpb3JpdHk6IG51bWJlcjtcblx0YXR0ZW1wdHM6IG51bWJlcjtcblx0bWF4UmV0cmllczogbnVtYmVyO1xuXHRjcmVhdGVkQXQ6IERhdGU7XG5cdGRlbGF5OiBudW1iZXI7XG5cdHRpbWVvdXQ6IG51bWJlcjtcblx0c3RhdHVzOiBcIndhaXRpbmdcIiB8IFwiYWN0aXZlXCIgfCBcImNvbXBsZXRlZFwiIHwgXCJmYWlsZWRcIiB8IFwiZGVsYXllZFwiO1xuXHRzY2hlZHVsZWRBdD86IERhdGU7XG5cdGVycm9yPzogRXJyb3I7XG59XG5cbi8qKlxuICogUXVldWUgcHJvY2Vzc29yIGVudHJ5XG4gKi9cbmludGVyZmFjZSBRdWV1ZVByb2Nlc3NvciB7XG5cdGNvbmZpZzogV29ya2VyVHJpZ2dlck9wdHM7XG5cdGhhbmRsZXI6IChqb2I6IFdvcmtlckpvYikgPT4gUHJvbWlzZTx2b2lkPjtcblx0YWN0aXZlOiBudW1iZXI7XG5cdHJ1bm5pbmc6IGJvb2xlYW47XG5cdHRpbWVyPzogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0SW50ZXJ2YWw+O1xufVxuXG4vKipcbiAqIEluTWVtb3J5QWRhcHRlciAtIFNpbXBsZSBpbi1wcm9jZXNzIHdvcmtlciBxdWV1ZVxuICovXG5leHBvcnQgY2xhc3MgSW5NZW1vcnlBZGFwdGVyIGltcGxlbWVudHMgV29ya2VyQWRhcHRlciB7XG5cdHJlYWRvbmx5IHByb3ZpZGVyID0gXCJpbi1tZW1vcnlcIiBhcyBjb25zdDtcblx0cHJpdmF0ZSBjb25uZWN0ZWQgPSBmYWxzZTtcblx0cHJpdmF0ZSBqb2JzOiBNYXA8c3RyaW5nLCBJbnRlcm5hbEpvYltdPiA9IG5ldyBNYXAoKTtcblx0cHJpdmF0ZSBwcm9jZXNzb3JzOiBNYXA8c3RyaW5nLCBRdWV1ZVByb2Nlc3Nvcj4gPSBuZXcgTWFwKCk7XG5cdHByaXZhdGUgc3RhdHM6IE1hcDxzdHJpbmcsIHsgY29tcGxldGVkOiBudW1iZXI7IGZhaWxlZDogbnVtYmVyIH0+ID0gbmV3IE1hcCgpO1xuXG5cdGFzeW5jIGNvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0dGhpcy5jb25uZWN0ZWQgPSB0cnVlO1xuXHR9XG5cblx0YXN5bmMgZGlzY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHQvLyBTdG9wIGFsbCBwcm9jZXNzb3JzXG5cdFx0Zm9yIChjb25zdCBbcXVldWUsIHByb2Nlc3Nvcl0gb2YgdGhpcy5wcm9jZXNzb3JzKSB7XG5cdFx0XHRwcm9jZXNzb3IucnVubmluZyA9IGZhbHNlO1xuXHRcdFx0aWYgKHByb2Nlc3Nvci50aW1lcikge1xuXHRcdFx0XHRjbGVhckludGVydmFsKHByb2Nlc3Nvci50aW1lcik7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRoaXMucHJvY2Vzc29ycy5jbGVhcigpO1xuXHRcdHRoaXMuam9icy5jbGVhcigpO1xuXHRcdHRoaXMuc3RhdHMuY2xlYXIoKTtcblx0XHR0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuXHR9XG5cblx0YXN5bmMgcHJvY2Vzcyhjb25maWc6IFdvcmtlclRyaWdnZXJPcHRzLCBoYW5kbGVyOiAoam9iOiBXb3JrZXJKb2IpID0+IFByb21pc2U8dm9pZD4pOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRpZiAoIXRoaXMuY29ubmVjdGVkKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJOb3QgY29ubmVjdGVkLiBDYWxsIGNvbm5lY3QoKSBmaXJzdC5cIik7XG5cdFx0fVxuXG5cdFx0aWYgKCF0aGlzLmpvYnMuaGFzKGNvbmZpZy5xdWV1ZSkpIHtcblx0XHRcdHRoaXMuam9icy5zZXQoY29uZmlnLnF1ZXVlLCBbXSk7XG5cdFx0fVxuXHRcdGlmICghdGhpcy5zdGF0cy5oYXMoY29uZmlnLnF1ZXVlKSkge1xuXHRcdFx0dGhpcy5zdGF0cy5zZXQoY29uZmlnLnF1ZXVlLCB7IGNvbXBsZXRlZDogMCwgZmFpbGVkOiAwIH0pO1xuXHRcdH1cblxuXHRcdGNvbnN0IHByb2Nlc3NvcjogUXVldWVQcm9jZXNzb3IgPSB7XG5cdFx0XHRjb25maWcsXG5cdFx0XHRoYW5kbGVyLFxuXHRcdFx0YWN0aXZlOiAwLFxuXHRcdFx0cnVubmluZzogdHJ1ZSxcblx0XHR9O1xuXG5cdFx0dGhpcy5wcm9jZXNzb3JzLnNldChjb25maWcucXVldWUsIHByb2Nlc3Nvcik7XG5cblx0XHQvLyBTdGFydCBwb2xsaW5nIGZvciBqb2JzXG5cdFx0cHJvY2Vzc29yLnRpbWVyID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuXHRcdFx0dGhpcy5wcm9jZXNzTmV4dChjb25maWcucXVldWUpLmNhdGNoKChlcnIpID0+IHtcblx0XHRcdFx0Y29uc29sZS5lcnJvcihgW0luTWVtb3J5QWRhcHRlcl0gRXJyb3IgcHJvY2Vzc2luZyAke2NvbmZpZy5xdWV1ZX06ICR7KGVyciBhcyBFcnJvcikubWVzc2FnZX1gKTtcblx0XHRcdH0pO1xuXHRcdH0sIDUwKTsgLy8gUG9sbCBldmVyeSA1MG1zXG5cdH1cblxuXHRhc3luYyBhZGRKb2IoXG5cdFx0cXVldWU6IHN0cmluZyxcblx0XHRkYXRhOiB1bmtub3duLFxuXHRcdG9wdHM/OiB7XG5cdFx0XHRwcmlvcml0eT86IG51bWJlcjtcblx0XHRcdGRlbGF5PzogbnVtYmVyO1xuXHRcdFx0cmV0cmllcz86IG51bWJlcjtcblx0XHRcdHRpbWVvdXQ/OiBudW1iZXI7XG5cdFx0XHRqb2JJZD86IHN0cmluZztcblx0XHR9LFxuXHQpOiBQcm9taXNlPHN0cmluZz4ge1xuXHRcdGlmICghdGhpcy5jb25uZWN0ZWQpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIk5vdCBjb25uZWN0ZWQuIENhbGwgY29ubmVjdCgpIGZpcnN0LlwiKTtcblx0XHR9XG5cblx0XHRpZiAoIXRoaXMuam9icy5oYXMocXVldWUpKSB7XG5cdFx0XHR0aGlzLmpvYnMuc2V0KHF1ZXVlLCBbXSk7XG5cdFx0fVxuXHRcdGlmICghdGhpcy5zdGF0cy5oYXMocXVldWUpKSB7XG5cdFx0XHR0aGlzLnN0YXRzLnNldChxdWV1ZSwgeyBjb21wbGV0ZWQ6IDAsIGZhaWxlZDogMCB9KTtcblx0XHR9XG5cblx0XHRjb25zdCBqb2I6IEludGVybmFsSm9iID0ge1xuXHRcdFx0aWQ6IG9wdHM/LmpvYklkIHx8IHV1aWQoKSxcblx0XHRcdGRhdGEsXG5cdFx0XHRxdWV1ZSxcblx0XHRcdHByaW9yaXR5OiBvcHRzPy5wcmlvcml0eSA/PyAwLFxuXHRcdFx0YXR0ZW1wdHM6IDAsXG5cdFx0XHRtYXhSZXRyaWVzOiBvcHRzPy5yZXRyaWVzID8/IDMsXG5cdFx0XHRjcmVhdGVkQXQ6IG5ldyBEYXRlKCksXG5cdFx0XHRkZWxheTogb3B0cz8uZGVsYXkgPz8gMCxcblx0XHRcdHRpbWVvdXQ6IG9wdHM/LnRpbWVvdXQgPz8gMCxcblx0XHRcdHN0YXR1czogb3B0cz8uZGVsYXkgJiYgb3B0cy5kZWxheSA+IDAgPyBcImRlbGF5ZWRcIiA6IFwid2FpdGluZ1wiLFxuXHRcdH07XG5cblx0XHRpZiAoam9iLnN0YXR1cyA9PT0gXCJkZWxheWVkXCIpIHtcblx0XHRcdGpvYi5zY2hlZHVsZWRBdCA9IG5ldyBEYXRlKERhdGUubm93KCkgKyBqb2IuZGVsYXkpO1xuXHRcdH1cblxuXHRcdGNvbnN0IGpvYnMgPSB0aGlzLmpvYnMuZ2V0KHF1ZXVlKSE7XG5cblx0XHQvLyBJbnNlcnQgc29ydGVkIGJ5IHByaW9yaXR5IChoaWdoZXIgZmlyc3QpXG5cdFx0Y29uc3QgaW5zZXJ0SWR4ID0gam9icy5maW5kSW5kZXgoKGopID0+IGouc3RhdHVzID09PSBcIndhaXRpbmdcIiAmJiBqLnByaW9yaXR5IDwgam9iLnByaW9yaXR5KTtcblx0XHRpZiAoaW5zZXJ0SWR4ID49IDApIHtcblx0XHRcdGpvYnMuc3BsaWNlKGluc2VydElkeCwgMCwgam9iKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0am9icy5wdXNoKGpvYik7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGpvYi5pZDtcblx0fVxuXG5cdGFzeW5jIHN0b3BQcm9jZXNzaW5nKHF1ZXVlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRjb25zdCBwcm9jZXNzb3IgPSB0aGlzLnByb2Nlc3NvcnMuZ2V0KHF1ZXVlKTtcblx0XHRpZiAocHJvY2Vzc29yKSB7XG5cdFx0XHRwcm9jZXNzb3IucnVubmluZyA9IGZhbHNlO1xuXHRcdFx0aWYgKHByb2Nlc3Nvci50aW1lcikge1xuXHRcdFx0XHRjbGVhckludGVydmFsKHByb2Nlc3Nvci50aW1lcik7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnByb2Nlc3NvcnMuZGVsZXRlKHF1ZXVlKTtcblx0XHR9XG5cdH1cblxuXHRpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5jb25uZWN0ZWQ7XG5cdH1cblxuXHRhc3luYyBoZWFsdGhDaGVjaygpOiBQcm9taXNlPGJvb2xlYW4+IHtcblx0XHRyZXR1cm4gdGhpcy5jb25uZWN0ZWQ7XG5cdH1cblxuXHRhc3luYyBnZXRRdWV1ZVN0YXRzKHF1ZXVlOiBzdHJpbmcpOiBQcm9taXNlPFdvcmtlclF1ZXVlU3RhdHM+IHtcblx0XHRjb25zdCBqb2JzID0gdGhpcy5qb2JzLmdldChxdWV1ZSkgfHwgW107XG5cdFx0Y29uc3QgcXVldWVTdGF0cyA9IHRoaXMuc3RhdHMuZ2V0KHF1ZXVlKSB8fCB7IGNvbXBsZXRlZDogMCwgZmFpbGVkOiAwIH07XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0d2FpdGluZzogam9icy5maWx0ZXIoKGopID0+IGouc3RhdHVzID09PSBcIndhaXRpbmdcIikubGVuZ3RoLFxuXHRcdFx0YWN0aXZlOiBqb2JzLmZpbHRlcigoaikgPT4gai5zdGF0dXMgPT09IFwiYWN0aXZlXCIpLmxlbmd0aCxcblx0XHRcdGNvbXBsZXRlZDogcXVldWVTdGF0cy5jb21wbGV0ZWQsXG5cdFx0XHRmYWlsZWQ6IHF1ZXVlU3RhdHMuZmFpbGVkLFxuXHRcdFx0ZGVsYXllZDogam9icy5maWx0ZXIoKGopID0+IGouc3RhdHVzID09PSBcImRlbGF5ZWRcIikubGVuZ3RoLFxuXHRcdH07XG5cdH1cblxuXHQvKipcblx0ICogUHJvY2VzcyB0aGUgbmV4dCBhdmFpbGFibGUgam9iIGZyb20gYSBxdWV1ZVxuXHQgKi9cblx0cHJpdmF0ZSBhc3luYyBwcm9jZXNzTmV4dChxdWV1ZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Y29uc3QgcHJvY2Vzc29yID0gdGhpcy5wcm9jZXNzb3JzLmdldChxdWV1ZSk7XG5cdFx0aWYgKCFwcm9jZXNzb3IgfHwgIXByb2Nlc3Nvci5ydW5uaW5nKSByZXR1cm47XG5cblx0XHRjb25zdCBjb25jdXJyZW5jeSA9IHByb2Nlc3Nvci5jb25maWcuY29uY3VycmVuY3kgPz8gMTtcblx0XHRpZiAocHJvY2Vzc29yLmFjdGl2ZSA+PSBjb25jdXJyZW5jeSkgcmV0dXJuO1xuXG5cdFx0Y29uc3Qgam9icyA9IHRoaXMuam9icy5nZXQocXVldWUpO1xuXHRcdGlmICgham9icyB8fCBqb2JzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG5cdFx0Ly8gQ2hlY2sgZm9yIGRlbGF5ZWQgam9icyB0aGF0IGFyZSByZWFkeVxuXHRcdGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG5cdFx0Zm9yIChjb25zdCBqb2Igb2Ygam9icykge1xuXHRcdFx0aWYgKGpvYi5zdGF0dXMgPT09IFwiZGVsYXllZFwiICYmIGpvYi5zY2hlZHVsZWRBdCAmJiBqb2Iuc2NoZWR1bGVkQXQuZ2V0VGltZSgpIDw9IG5vdykge1xuXHRcdFx0XHRqb2Iuc3RhdHVzID0gXCJ3YWl0aW5nXCI7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gRmluZCBuZXh0IHdhaXRpbmcgam9iXG5cdFx0Y29uc3Qgam9iSWR4ID0gam9icy5maW5kSW5kZXgoKGopID0+IGouc3RhdHVzID09PSBcIndhaXRpbmdcIik7XG5cdFx0aWYgKGpvYklkeCA8IDApIHJldHVybjtcblxuXHRcdGNvbnN0IGludGVybmFsSm9iID0gam9ic1tqb2JJZHhdO1xuXHRcdGludGVybmFsSm9iLnN0YXR1cyA9IFwiYWN0aXZlXCI7XG5cdFx0cHJvY2Vzc29yLmFjdGl2ZSsrO1xuXG5cdFx0Y29uc3Qgd29ya2VySm9iOiBXb3JrZXJKb2IgPSB7XG5cdFx0XHRpZDogaW50ZXJuYWxKb2IuaWQsXG5cdFx0XHRkYXRhOiBpbnRlcm5hbEpvYi5kYXRhLFxuXHRcdFx0aGVhZGVyczoge30sXG5cdFx0XHRxdWV1ZTogaW50ZXJuYWxKb2IucXVldWUsXG5cdFx0XHRwcmlvcml0eTogaW50ZXJuYWxKb2IucHJpb3JpdHksXG5cdFx0XHRhdHRlbXB0czogaW50ZXJuYWxKb2IuYXR0ZW1wdHMsXG5cdFx0XHRtYXhSZXRyaWVzOiBpbnRlcm5hbEpvYi5tYXhSZXRyaWVzLFxuXHRcdFx0Y3JlYXRlZEF0OiBpbnRlcm5hbEpvYi5jcmVhdGVkQXQsXG5cdFx0XHRkZWxheTogaW50ZXJuYWxKb2IuZGVsYXksXG5cdFx0XHR0aW1lb3V0OiBpbnRlcm5hbEpvYi50aW1lb3V0LFxuXHRcdFx0cmF3OiBpbnRlcm5hbEpvYixcblx0XHRcdGNvbXBsZXRlOiBhc3luYyAoKSA9PiB7XG5cdFx0XHRcdGludGVybmFsSm9iLnN0YXR1cyA9IFwiY29tcGxldGVkXCI7XG5cdFx0XHRcdGNvbnN0IGlkeCA9IGpvYnMuaW5kZXhPZihpbnRlcm5hbEpvYik7XG5cdFx0XHRcdGlmIChpZHggPj0gMCkgam9icy5zcGxpY2UoaWR4LCAxKTtcblx0XHRcdFx0Y29uc3QgcyA9IHRoaXMuc3RhdHMuZ2V0KHF1ZXVlKTtcblx0XHRcdFx0aWYgKHMpIHMuY29tcGxldGVkKys7XG5cdFx0XHR9LFxuXHRcdFx0ZmFpbDogYXN5bmMgKGVycm9yOiBFcnJvciwgcmVxdWV1ZT86IGJvb2xlYW4pID0+IHtcblx0XHRcdFx0aW50ZXJuYWxKb2IuYXR0ZW1wdHMrKztcblx0XHRcdFx0aW50ZXJuYWxKb2IuZXJyb3IgPSBlcnJvcjtcblxuXHRcdFx0XHRpZiAocmVxdWV1ZSAmJiBpbnRlcm5hbEpvYi5hdHRlbXB0cyA8IGludGVybmFsSm9iLm1heFJldHJpZXMpIHtcblx0XHRcdFx0XHQvLyBSZXF1ZXVlIHdpdGggYmFja29mZlxuXHRcdFx0XHRcdGNvbnN0IGJhY2tvZmYgPSBNYXRoLm1pbigxMDAwICogTWF0aC5wb3coMiwgaW50ZXJuYWxKb2IuYXR0ZW1wdHMpLCAzMDAwMCk7XG5cdFx0XHRcdFx0aW50ZXJuYWxKb2Iuc3RhdHVzID0gXCJkZWxheWVkXCI7XG5cdFx0XHRcdFx0aW50ZXJuYWxKb2Iuc2NoZWR1bGVkQXQgPSBuZXcgRGF0ZShEYXRlLm5vdygpICsgYmFja29mZik7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0aW50ZXJuYWxKb2Iuc3RhdHVzID0gXCJmYWlsZWRcIjtcblx0XHRcdFx0XHRjb25zdCBpZHggPSBqb2JzLmluZGV4T2YoaW50ZXJuYWxKb2IpO1xuXHRcdFx0XHRcdGlmIChpZHggPj0gMCkgam9icy5zcGxpY2UoaWR4LCAxKTtcblx0XHRcdFx0XHRjb25zdCBzID0gdGhpcy5zdGF0cy5nZXQocXVldWUpO1xuXHRcdFx0XHRcdGlmIChzKSBzLmZhaWxlZCsrO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdH07XG5cblx0XHR0cnkge1xuXHRcdFx0YXdhaXQgcHJvY2Vzc29yLmhhbmRsZXIod29ya2VySm9iKTtcblx0XHR9IGNhdGNoIHtcblx0XHRcdC8vIEhhbmRsZXIgdGhyZXcgLSB0cmVhdCBhcyBmYWlsdXJlXG5cdFx0XHRpZiAoaW50ZXJuYWxKb2Iuc3RhdHVzID09PSBcImFjdGl2ZVwiKSB7XG5cdFx0XHRcdGludGVybmFsSm9iLnN0YXR1cyA9IFwiZmFpbGVkXCI7XG5cdFx0XHRcdGNvbnN0IGlkeCA9IGpvYnMuaW5kZXhPZihpbnRlcm5hbEpvYik7XG5cdFx0XHRcdGlmIChpZHggPj0gMCkgam9icy5zcGxpY2UoaWR4LCAxKTtcblx0XHRcdFx0Y29uc3QgcyA9IHRoaXMuc3RhdHMuZ2V0KHF1ZXVlKTtcblx0XHRcdFx0aWYgKHMpIHMuZmFpbGVkKys7XG5cdFx0XHR9XG5cdFx0fSBmaW5hbGx5IHtcblx0XHRcdHByb2Nlc3Nvci5hY3RpdmUtLTtcblx0XHR9XG5cdH1cbn1cbiJdfQ==
225
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5NZW1vcnlBZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXJzL0luTWVtb3J5QWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFHSCxPQUFPLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQWdDbEM7O0dBRUc7QUFDSCxNQUFNLE9BQU8sZUFBZTtJQUNsQixRQUFRLEdBQUcsV0FBb0IsQ0FBQztJQUNqQyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ2xCLElBQUksR0FBK0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUM3QyxVQUFVLEdBQWdDLElBQUksR0FBRyxFQUFFLENBQUM7SUFDcEQsS0FBSyxHQUF1RCxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRTlFLEtBQUssQ0FBQyxPQUFPO1FBQ1osSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7SUFDdkIsQ0FBQztJQUVELEtBQUssQ0FBQyxVQUFVO1FBQ2Ysc0JBQXNCO1FBQ3RCLEtBQUssTUFBTSxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDbEQsU0FBUyxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7WUFDMUIsSUFBSSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3JCLGFBQWEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEMsQ0FBQztRQUNGLENBQUM7UUFDRCxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDO0lBRUQsS0FBSyxDQUFDLE9BQU8s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LE1BQU0sRUFBRSxDQUFDO1FBQ3BCLENBQUM7SUFDRixDQUFDO0NBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEluTWVtb3J5QWRhcHRlciAtIFdvcmtlciBhZGFwdGVyIHVzaW5nIGluLXByb2Nlc3MgcXVldWVzXG4gKlxuICogSWRlYWwgZm9yOlxuICogLSBEZXZlbG9wbWVudCBhbmQgdGVzdGluZ1xuICogLSBTaW1wbGUgYmFja2dyb3VuZCBqb2IgcHJvY2Vzc2luZ1xuICogLSBTaW5nbGUtaW5zdGFuY2UgZGVwbG95bWVudHNcbiAqXG4gKiBMaW1pdGF0aW9uczpcbiAqIC0gSm9icyBhcmUgbG9zdCBvbiBwcm9jZXNzIHJlc3RhcnRcbiAqIC0gTm8gZGlzdHJpYnV0ZWQgcHJvY2Vzc2luZ1xuICogLSBObyBwZXJzaXN0ZW5jZVxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBhZGFwdGVyID0gbmV3IEluTWVtb3J5QWRhcHRlcigpO1xuICogYGBgXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBXb3JrZXJUcmlnZ2VyT3B0cyB9IGZyb20gXCJAYmxva2pzL2hlbHBlclwiO1xuaW1wb3J0IHsgdjQgYXMgdXVpZCB9IGZyb20gXCJ1dWlkXCI7XG5pbXBvcnQgdHlwZSB7IFdvcmtlckFkYXB0ZXIsIFdvcmtlckpvYiwgV29ya2VyUXVldWVTdGF0cyB9IGZyb20gXCIuLi9Xb3JrZXJUcmlnZ2VyXCI7XG5cbi8qKlxuICogSW50ZXJuYWwgam9iIHJlcHJlc2VudGF0aW9uXG4gKi9cbmludGVyZmFjZSBJbnRlcm5hbEpvYiB7XG5cdGlkOiBzdHJpbmc7XG5cdGRhdGE6IHVua25vd247XG5cdHF1ZXVlOiBzdHJpbmc7XG5cdHByaW9yaXR5OiBudW1iZXI7XG5cdGF0dGVtcHRzOiBudW1iZXI7XG5cdG1heFJldHJpZXM6IG51bWJlcjtcblx0Y3JlYXRlZEF0OiBEYXRlO1xuXHRkZWxheTogbnVtYmVyO1xuXHR0aW1lb3V0OiBudW1iZXI7XG5cdHN0YXR1czogXCJ3YWl0aW5nXCIgfCBcImFjdGl2ZVwiIHwgXCJjb21wbGV0ZWRcIiB8IFwiZmFpbGVkXCIgfCBcImRlbGF5ZWRcIjtcblx0c2NoZWR1bGVkQXQ/OiBEYXRlO1xuXHRlcnJvcj86IEVycm9yO1xufVxuXG4vKipcbiAqIFF1ZXVlIHByb2Nlc3NvciBlbnRyeVxuICovXG5pbnRlcmZhY2UgUXVldWVQcm9jZXNzb3Ige1xuXHRjb25maWc6IFdvcmtlclRyaWdnZXJPcHRzO1xuXHRoYW5kbGVyOiAoam9iOiBXb3JrZXJKb2IpID0+IFByb21pc2U8dm9pZD47XG5cdGFjdGl2ZTogbnVtYmVyO1xuXHRydW5uaW5nOiBib29sZWFuO1xuXHR0aW1lcj86IFJldHVyblR5cGU8dHlwZW9mIHNldEludGVydmFsPjtcbn1cblxuLyoqXG4gKiBJbk1lbW9yeUFkYXB0ZXIgLSBTaW1wbGUgaW4tcHJvY2VzcyB3b3JrZXIgcXVldWVcbiAqL1xuZXhwb3J0IGNsYXNzIEluTWVtb3J5QWRhcHRlciBpbXBsZW1lbnRzIFdvcmtlckFkYXB0ZXIge1xuXHRyZWFkb25seSBwcm92aWRlciA9IFwiaW4tbWVtb3J5XCIgYXMgY29uc3Q7XG5cdHByaXZhdGUgY29ubmVjdGVkID0gZmFsc2U7XG5cdHByaXZhdGUgam9iczogTWFwPHN0cmluZywgSW50ZXJuYWxKb2JbXT4gPSBuZXcgTWFwKCk7XG5cdHByaXZhdGUgcHJvY2Vzc29yczogTWFwPHN0cmluZywgUXVldWVQcm9jZXNzb3I+ID0gbmV3IE1hcCgpO1xuXHRwcml2YXRlIHN0YXRzOiBNYXA8c3RyaW5nLCB7IGNvbXBsZXRlZDogbnVtYmVyOyBmYWlsZWQ6IG51bWJlciB9PiA9IG5ldyBNYXAoKTtcblxuXHRhc3luYyBjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdHRoaXMuY29ubmVjdGVkID0gdHJ1ZTtcblx0fVxuXG5cdGFzeW5jIGRpc2Nvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Ly8gU3RvcCBhbGwgcHJvY2Vzc29yc1xuXHRcdGZvciAoY29uc3QgW3F1ZXVlLCBwcm9jZXNzb3JdIG9mIHRoaXMucHJvY2Vzc29ycykge1xuXHRcdFx0cHJvY2Vzc29yLnJ1bm5pbmcgPSBmYWxzZTtcblx0XHRcdGlmIChwcm9jZXNzb3IudGltZXIpIHtcblx0XHRcdFx0Y2xlYXJJbnRlcnZhbChwcm9jZXNzb3IudGltZXIpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHR0aGlzLnByb2Nlc3NvcnMuY2xlYXIoKTtcblx0XHR0aGlzLmpvYnMuY2xlYXIoKTtcblx0XHR0aGlzLnN0YXRzLmNsZWFyKCk7XG5cdFx0dGhpcy5jb25uZWN0ZWQgPSBmYWxzZTtcblx0fVxuXG5cdGFzeW5jIHByb2Nlc3MoY29uZmlnOiBXb3JrZXJUcmlnZ2VyT3B0cywgaGFuZGxlcjogKGpvYjogV29ya2VySm9iKSA9PiBQcm9taXNlPHZvaWQ+KTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKCF0aGlzLmNvbm5lY3RlZCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiTm90IGNvbm5lY3RlZC4gQ2FsbCBjb25uZWN0KCkgZmlyc3QuXCIpO1xuXHRcdH1cblxuXHRcdGlmICghdGhpcy5qb2JzLmhhcyhjb25maWcucXVldWUpKSB7XG5cdFx0XHR0aGlzLmpvYnMuc2V0KGNvbmZpZy5xdWV1ZSwgW10pO1xuXHRcdH1cblx0XHRpZiAoIXRoaXMuc3RhdHMuaGFzKGNvbmZpZy5xdWV1ZSkpIHtcblx0XHRcdHRoaXMuc3RhdHMuc2V0KGNvbmZpZy5xdWV1ZSwgeyBjb21wbGV0ZWQ6IDAsIGZhaWxlZDogMCB9KTtcblx0XHR9XG5cblx0XHRjb25zdCBwcm9jZXNzb3I6IFF1ZXVlUHJvY2Vzc29yID0ge1xuXHRcdFx0Y29uZmlnLFxuXHRcdFx0aGFuZGxlcixcblx0XHRcdGFjdGl2ZTogMCxcblx0XHRcdHJ1bm5pbmc6IHRydWUsXG5cdFx0fTtcblxuXHRcdHRoaXMucHJvY2Vzc29ycy5zZXQoY29uZmlnLnF1ZXVlLCBwcm9jZXNzb3IpO1xuXG5cdFx0Ly8gU3RhcnQgcG9sbGluZyBmb3Igam9ic1xuXHRcdHByb2Nlc3Nvci50aW1lciA9IHNldEludGVydmFsKCgpID0+IHtcblx0XHRcdHRoaXMucHJvY2Vzc05leHQoY29uZmlnLnF1ZXVlKS5jYXRjaCgoZXJyKSA9PiB7XG5cdFx0XHRcdGNvbnNvbGUuZXJyb3IoYFtJbk1lbW9yeUFkYXB0ZXJdIEVycm9yIHByb2Nlc3NpbmcgJHtjb25maWcucXVldWV9OiAkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG5cdFx0XHR9KTtcblx0XHR9LCA1MCk7IC8vIFBvbGwgZXZlcnkgNTBtc1xuXHR9XG5cblx0YXN5bmMgYWRkSm9iKFxuXHRcdHF1ZXVlOiBzdHJpbmcsXG5cdFx0ZGF0YTogdW5rbm93bixcblx0XHRvcHRzPzoge1xuXHRcdFx0cHJpb3JpdHk/OiBudW1iZXI7XG5cdFx0XHRkZWxheT86IG51bWJlcjtcblx0XHRcdHJldHJpZXM/OiBudW1iZXI7XG5cdFx0XHR0aW1lb3V0PzogbnVtYmVyO1xuXHRcdFx0am9iSWQ/OiBzdHJpbmc7XG5cdFx0fSxcblx0KTogUHJvbWlzZTxzdHJpbmc+IHtcblx0XHRpZiAoIXRoaXMuY29ubmVjdGVkKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJOb3QgY29ubmVjdGVkLiBDYWxsIGNvbm5lY3QoKSBmaXJzdC5cIik7XG5cdFx0fVxuXG5cdFx0Ly8gR2V0LW9yLWluaXQgdGhlIHBlci1xdWV1ZSBqb2IgbGlzdC4gU2FtZSBwYXR0ZXJuIGFzIGBzdGF0c2Bcblx0XHQvLyBiZWxvdyDigJQgdGhlIHByZXZpb3VzIGNvZGUgdXNlZCBgc2V0LWlmLWFic2VudGAgdGhlbiBgLmdldCgpIWAsXG5cdFx0Ly8gYnV0IHRoYXQgbm9uLW51bGwgYXNzZXJ0aW9uIGlzIHdoYXQgYmlvbWUgZmxhZ3MuIFB1bGxpbmcgdGhlXG5cdFx0Ly8gcmVmZXJlbmNlIG9uY2UgYW5kIHNlZWRpbmcgd2hlbiBtaXNzaW5nIGtlZXBzIHRoZSB0eXBlIGV4YWN0LlxuXHRcdGxldCBqb2JzID0gdGhpcy5qb2JzLmdldChxdWV1ZSk7XG5cdFx0aWYgKCFqb2JzKSB7XG5cdFx0XHRqb2JzID0gW107XG5cdFx0XHR0aGlzLmpvYnMuc2V0KHF1ZXVlLCBqb2JzKTtcblx0XHR9XG5cdFx0aWYgKCF0aGlzLnN0YXRzLmhhcyhxdWV1ZSkpIHtcblx0XHRcdHRoaXMuc3RhdHMuc2V0KHF1ZXVlLCB7IGNvbXBsZXRlZDogMCwgZmFpbGVkOiAwIH0pO1xuXHRcdH1cblxuXHRcdGNvbnN0IGpvYjogSW50ZXJuYWxKb2IgPSB7XG5cdFx0XHRpZDogb3B0cz8uam9iSWQgfHwgdXVpZCgpLFxuXHRcdFx0ZGF0YSxcblx0XHRcdHF1ZXVlLFxuXHRcdFx0cHJpb3JpdHk6IG9wdHM/LnByaW9yaXR5ID8/IDAsXG5cdFx0XHRhdHRlbXB0czogMCxcblx0XHRcdG1heFJldHJpZXM6IG9wdHM/LnJldHJpZXMgPz8gMyxcblx0XHRcdGNyZWF0ZWRBdDogbmV3IERhdGUoKSxcblx0XHRcdGRlbGF5OiBvcHRzPy5kZWxheSA/PyAwLFxuXHRcdFx0dGltZW91dDogb3B0cz8udGltZW91dCA/PyAwLFxuXHRcdFx0c3RhdHVzOiBvcHRzPy5kZWxheSAmJiBvcHRzLmRlbGF5ID4gMCA/IFwiZGVsYXllZFwiIDogXCJ3YWl0aW5nXCIsXG5cdFx0fTtcblxuXHRcdGlmIChqb2Iuc3RhdHVzID09PSBcImRlbGF5ZWRcIikge1xuXHRcdFx0am9iLnNjaGVkdWxlZEF0ID0gbmV3IERhdGUoRGF0ZS5ub3coKSArIGpvYi5kZWxheSk7XG5cdFx0fVxuXG5cdFx0Ly8gSW5zZXJ0IHNvcnRlZCBieSBwcmlvcml0eSAoaGlnaGVyIGZpcnN0KVxuXHRcdGNvbnN0IGluc2VydElkeCA9IGpvYnMuZmluZEluZGV4KChqKSA9PiBqLnN0YXR1cyA9PT0gXCJ3YWl0aW5nXCIgJiYgai5wcmlvcml0eSA8IGpvYi5wcmlvcml0eSk7XG5cdFx0aWYgKGluc2VydElkeCA+PSAwKSB7XG5cdFx0XHRqb2JzLnNwbGljZShpbnNlcnRJZHgsIDAsIGpvYik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGpvYnMucHVzaChqb2IpO1xuXHRcdH1cblxuXHRcdHJldHVybiBqb2IuaWQ7XG5cdH1cblxuXHRhc3luYyBzdG9wUHJvY2Vzc2luZyhxdWV1ZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Y29uc3QgcHJvY2Vzc29yID0gdGhpcy5wcm9jZXNzb3JzLmdldChxdWV1ZSk7XG5cdFx0aWYgKHByb2Nlc3Nvcikge1xuXHRcdFx0cHJvY2Vzc29yLnJ1bm5pbmcgPSBmYWxzZTtcblx0XHRcdGlmIChwcm9jZXNzb3IudGltZXIpIHtcblx0XHRcdFx0Y2xlYXJJbnRlcnZhbChwcm9jZXNzb3IudGltZXIpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5wcm9jZXNzb3JzLmRlbGV0ZShxdWV1ZSk7XG5cdFx0fVxuXHR9XG5cblx0aXNDb25uZWN0ZWQoKTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMuY29ubmVjdGVkO1xuXHR9XG5cblx0YXN5bmMgaGVhbHRoQ2hlY2soKTogUHJvbWlzZTxib29sZWFuPiB7XG5cdFx0cmV0dXJuIHRoaXMuY29ubmVjdGVkO1xuXHR9XG5cblx0YXN5bmMgZ2V0UXVldWVTdGF0cyhxdWV1ZTogc3RyaW5nKTogUHJvbWlzZTxXb3JrZXJRdWV1ZVN0YXRzPiB7XG5cdFx0Y29uc3Qgam9icyA9IHRoaXMuam9icy5nZXQocXVldWUpIHx8IFtdO1xuXHRcdGNvbnN0IHF1ZXVlU3RhdHMgPSB0aGlzLnN0YXRzLmdldChxdWV1ZSkgfHwgeyBjb21wbGV0ZWQ6IDAsIGZhaWxlZDogMCB9O1xuXG5cdFx0cmV0dXJuIHtcblx0XHRcdHdhaXRpbmc6IGpvYnMuZmlsdGVyKChqKSA9PiBqLnN0YXR1cyA9PT0gXCJ3YWl0aW5nXCIpLmxlbmd0aCxcblx0XHRcdGFjdGl2ZTogam9icy5maWx0ZXIoKGopID0+IGouc3RhdHVzID09PSBcImFjdGl2ZVwiKS5sZW5ndGgsXG5cdFx0XHRjb21wbGV0ZWQ6IHF1ZXVlU3RhdHMuY29tcGxldGVkLFxuXHRcdFx0ZmFpbGVkOiBxdWV1ZVN0YXRzLmZhaWxlZCxcblx0XHRcdGRlbGF5ZWQ6IGpvYnMuZmlsdGVyKChqKSA9PiBqLnN0YXR1cyA9PT0gXCJkZWxheWVkXCIpLmxlbmd0aCxcblx0XHR9O1xuXHR9XG5cblx0LyoqXG5cdCAqIFByb2Nlc3MgdGhlIG5leHQgYXZhaWxhYmxlIGpvYiBmcm9tIGEgcXVldWVcblx0ICovXG5cdHByaXZhdGUgYXN5bmMgcHJvY2Vzc05leHQocXVldWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IHByb2Nlc3NvciA9IHRoaXMucHJvY2Vzc29ycy5nZXQocXVldWUpO1xuXHRcdGlmICghcHJvY2Vzc29yIHx8ICFwcm9jZXNzb3IucnVubmluZykgcmV0dXJuO1xuXG5cdFx0Y29uc3QgY29uY3VycmVuY3kgPSBwcm9jZXNzb3IuY29uZmlnLmNvbmN1cnJlbmN5ID8/IDE7XG5cdFx0aWYgKHByb2Nlc3Nvci5hY3RpdmUgPj0gY29uY3VycmVuY3kpIHJldHVybjtcblxuXHRcdGNvbnN0IGpvYnMgPSB0aGlzLmpvYnMuZ2V0KHF1ZXVlKTtcblx0XHRpZiAoIWpvYnMgfHwgam9icy5sZW5ndGggPT09IDApIHJldHVybjtcblxuXHRcdC8vIENoZWNrIGZvciBkZWxheWVkIGpvYnMgdGhhdCBhcmUgcmVhZHlcblx0XHRjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuXHRcdGZvciAoY29uc3Qgam9iIG9mIGpvYnMpIHtcblx0XHRcdGlmIChqb2Iuc3RhdHVzID09PSBcImRlbGF5ZWRcIiAmJiBqb2Iuc2NoZWR1bGVkQXQgJiYgam9iLnNjaGVkdWxlZEF0LmdldFRpbWUoKSA8PSBub3cpIHtcblx0XHRcdFx0am9iLnN0YXR1cyA9IFwid2FpdGluZ1wiO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEZpbmQgbmV4dCB3YWl0aW5nIGpvYlxuXHRcdGNvbnN0IGpvYklkeCA9IGpvYnMuZmluZEluZGV4KChqKSA9PiBqLnN0YXR1cyA9PT0gXCJ3YWl0aW5nXCIpO1xuXHRcdGlmIChqb2JJZHggPCAwKSByZXR1cm47XG5cblx0XHRjb25zdCBpbnRlcm5hbEpvYiA9IGpvYnNbam9iSWR4XTtcblx0XHRpbnRlcm5hbEpvYi5zdGF0dXMgPSBcImFjdGl2ZVwiO1xuXHRcdHByb2Nlc3Nvci5hY3RpdmUrKztcblxuXHRcdGNvbnN0IHdvcmtlckpvYjogV29ya2VySm9iID0ge1xuXHRcdFx0aWQ6IGludGVybmFsSm9iLmlkLFxuXHRcdFx0ZGF0YTogaW50ZXJuYWxKb2IuZGF0YSxcblx0XHRcdGhlYWRlcnM6IHt9LFxuXHRcdFx0cXVldWU6IGludGVybmFsSm9iLnF1ZXVlLFxuXHRcdFx0cHJpb3JpdHk6IGludGVybmFsSm9iLnByaW9yaXR5LFxuXHRcdFx0YXR0ZW1wdHM6IGludGVybmFsSm9iLmF0dGVtcHRzLFxuXHRcdFx0bWF4UmV0cmllczogaW50ZXJuYWxKb2IubWF4UmV0cmllcyxcblx0XHRcdGNyZWF0ZWRBdDogaW50ZXJuYWxKb2IuY3JlYXRlZEF0LFxuXHRcdFx0ZGVsYXk6IGludGVybmFsSm9iLmRlbGF5LFxuXHRcdFx0dGltZW91dDogaW50ZXJuYWxKb2IudGltZW91dCxcblx0XHRcdHJhdzogaW50ZXJuYWxKb2IsXG5cdFx0XHRjb21wbGV0ZTogYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRpbnRlcm5hbEpvYi5zdGF0dXMgPSBcImNvbXBsZXRlZFwiO1xuXHRcdFx0XHRjb25zdCBpZHggPSBqb2JzLmluZGV4T2YoaW50ZXJuYWxKb2IpO1xuXHRcdFx0XHRpZiAoaWR4ID49IDApIGpvYnMuc3BsaWNlKGlkeCwgMSk7XG5cdFx0XHRcdGNvbnN0IHMgPSB0aGlzLnN0YXRzLmdldChxdWV1ZSk7XG5cdFx0XHRcdGlmIChzKSBzLmNvbXBsZXRlZCsrO1xuXHRcdFx0fSxcblx0XHRcdGZhaWw6IGFzeW5jIChlcnJvcjogRXJyb3IsIHJlcXVldWU/OiBib29sZWFuKSA9PiB7XG5cdFx0XHRcdGludGVybmFsSm9iLmF0dGVtcHRzKys7XG5cdFx0XHRcdGludGVybmFsSm9iLmVycm9yID0gZXJyb3I7XG5cblx0XHRcdFx0aWYgKHJlcXVldWUgJiYgaW50ZXJuYWxKb2IuYXR0ZW1wdHMgPCBpbnRlcm5hbEpvYi5tYXhSZXRyaWVzKSB7XG5cdFx0XHRcdFx0Ly8gUmVxdWV1ZSB3aXRoIGJhY2tvZmZcblx0XHRcdFx0XHRjb25zdCBiYWNrb2ZmID0gTWF0aC5taW4oMTAwMCAqIDIgKiogaW50ZXJuYWxKb2IuYXR0ZW1wdHMsIDMwMDAwKTtcblx0XHRcdFx0XHRpbnRlcm5hbEpvYi5zdGF0dXMgPSBcImRlbGF5ZWRcIjtcblx0XHRcdFx0XHRpbnRlcm5hbEpvYi5zY2hlZHVsZWRBdCA9IG5ldyBEYXRlKERhdGUubm93KCkgKyBiYWNrb2ZmKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRpbnRlcm5hbEpvYi5zdGF0dXMgPSBcImZhaWxlZFwiO1xuXHRcdFx0XHRcdGNvbnN0IGlkeCA9IGpvYnMuaW5kZXhPZihpbnRlcm5hbEpvYik7XG5cdFx0XHRcdFx0aWYgKGlkeCA+PSAwKSBqb2JzLnNwbGljZShpZHgsIDEpO1xuXHRcdFx0XHRcdGNvbnN0IHMgPSB0aGlzLnN0YXRzLmdldChxdWV1ZSk7XG5cdFx0XHRcdFx0aWYgKHMpIHMuZmFpbGVkKys7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0fTtcblxuXHRcdHRyeSB7XG5cdFx0XHRhd2FpdCBwcm9jZXNzb3IuaGFuZGxlcih3b3JrZXJKb2IpO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0Ly8gSGFuZGxlciB0aHJldyAtIHRyZWF0IGFzIGZhaWx1cmVcblx0XHRcdGlmIChpbnRlcm5hbEpvYi5zdGF0dXMgPT09IFwiYWN0aXZlXCIpIHtcblx0XHRcdFx0aW50ZXJuYWxKb2Iuc3RhdHVzID0gXCJmYWlsZWRcIjtcblx0XHRcdFx0Y29uc3QgaWR4ID0gam9icy5pbmRleE9mKGludGVybmFsSm9iKTtcblx0XHRcdFx0aWYgKGlkeCA+PSAwKSBqb2JzLnNwbGljZShpZHgsIDEpO1xuXHRcdFx0XHRjb25zdCBzID0gdGhpcy5zdGF0cy5nZXQocXVldWUpO1xuXHRcdFx0XHRpZiAocykgcy5mYWlsZWQrKztcblx0XHRcdH1cblx0XHR9IGZpbmFsbHkge1xuXHRcdFx0cHJvY2Vzc29yLmFjdGl2ZS0tO1xuXHRcdH1cblx0fVxufVxuIl19
@@ -0,0 +1,62 @@
1
+ /**
2
+ * KafkaAdapter — v0.7 PR 5 — Worker adapter backed by Apache Kafka via
3
+ * `kafkajs`. Consumes from a topic (the `queue` field) with a
4
+ * consumer-group identifier; produces via the same client.
5
+ *
6
+ * Kafka is fundamentally a streaming platform — not a queue — so a
7
+ * few semantics differ from BullMQ/SQS/RabbitMQ:
8
+ *
9
+ * - **Ordering**: per-partition, not per-topic. Set the partition
10
+ * key via the `dedupId` field on `addJob` to keep related
11
+ * messages on the same partition.
12
+ * - **Retries**: Kafka doesn't have a broker-side retry concept.
13
+ * The adapter re-throws on handler failure; offset commit is
14
+ * suppressed so the consumer re-polls the message on the next
15
+ * cycle. For real retry semantics, layer a dead-letter topic.
16
+ * - **Stats**: KafkaJS exposes consumer-group lag via its admin
17
+ * client; the lag count is reported as `waiting`. Other stats
18
+ * are tracked locally per consumer.
19
+ *
20
+ * Requires `kafkajs` as a peer dependency:
21
+ *
22
+ * bun add kafkajs
23
+ *
24
+ * Environment variables (read at adapter construction):
25
+ * - `KAFKA_BROKERS` — comma-separated list (default `localhost:9092`).
26
+ * - `KAFKA_CLIENT_ID` — client.id (default `"blok-worker"`).
27
+ * - `KAFKA_SASL_USERNAME` — SASL/PLAIN username (optional).
28
+ * - `KAFKA_SASL_PASSWORD` — SASL/PLAIN password (optional).
29
+ * - `KAFKA_SSL` — when `"true"`, enable TLS.
30
+ */
31
+ import type { WorkerTriggerOpts } from "@blokjs/helper";
32
+ import type { WorkerAdapter, WorkerJob, WorkerQueueStats } from "../WorkerTrigger";
33
+ export interface KafkaConfig {
34
+ brokers: string[];
35
+ clientId: string;
36
+ saslUsername?: string;
37
+ saslPassword?: string;
38
+ ssl: boolean;
39
+ }
40
+ export declare class KafkaAdapter implements WorkerAdapter {
41
+ readonly provider: "kafka";
42
+ private readonly config;
43
+ private kafka;
44
+ private handle;
45
+ private connected;
46
+ private stats;
47
+ constructor(config?: Partial<KafkaConfig>);
48
+ connect(): Promise<void>;
49
+ disconnect(): Promise<void>;
50
+ process(config: WorkerTriggerOpts, handler: (job: WorkerJob) => Promise<void>): Promise<void>;
51
+ addJob(queue: string, data: unknown, opts?: {
52
+ priority?: number;
53
+ delay?: number;
54
+ retries?: number;
55
+ timeout?: number;
56
+ jobId?: string;
57
+ }): Promise<string>;
58
+ stopProcessing(queue: string): Promise<void>;
59
+ isConnected(): boolean;
60
+ healthCheck(): Promise<boolean>;
61
+ getQueueStats(queue: string): Promise<WorkerQueueStats>;
62
+ }
@@ -0,0 +1,236 @@
1
+ /**
2
+ * KafkaAdapter — v0.7 PR 5 — Worker adapter backed by Apache Kafka via
3
+ * `kafkajs`. Consumes from a topic (the `queue` field) with a
4
+ * consumer-group identifier; produces via the same client.
5
+ *
6
+ * Kafka is fundamentally a streaming platform — not a queue — so a
7
+ * few semantics differ from BullMQ/SQS/RabbitMQ:
8
+ *
9
+ * - **Ordering**: per-partition, not per-topic. Set the partition
10
+ * key via the `dedupId` field on `addJob` to keep related
11
+ * messages on the same partition.
12
+ * - **Retries**: Kafka doesn't have a broker-side retry concept.
13
+ * The adapter re-throws on handler failure; offset commit is
14
+ * suppressed so the consumer re-polls the message on the next
15
+ * cycle. For real retry semantics, layer a dead-letter topic.
16
+ * - **Stats**: KafkaJS exposes consumer-group lag via its admin
17
+ * client; the lag count is reported as `waiting`. Other stats
18
+ * are tracked locally per consumer.
19
+ *
20
+ * Requires `kafkajs` as a peer dependency:
21
+ *
22
+ * bun add kafkajs
23
+ *
24
+ * Environment variables (read at adapter construction):
25
+ * - `KAFKA_BROKERS` — comma-separated list (default `localhost:9092`).
26
+ * - `KAFKA_CLIENT_ID` — client.id (default `"blok-worker"`).
27
+ * - `KAFKA_SASL_USERNAME` — SASL/PLAIN username (optional).
28
+ * - `KAFKA_SASL_PASSWORD` — SASL/PLAIN password (optional).
29
+ * - `KAFKA_SSL` — when `"true"`, enable TLS.
30
+ */
31
+ import { v4 as uuid } from "uuid";
32
+ export class KafkaAdapter {
33
+ provider = "kafka";
34
+ config;
35
+ // biome-ignore lint/suspicious/noExplicitAny: kafkajs's exported `Kafka` constructor is loosely typed.
36
+ kafka = null;
37
+ handle = { consumers: new Map() };
38
+ connected = false;
39
+ stats = new Map();
40
+ constructor(config) {
41
+ this.config = {
42
+ brokers: config?.brokers ?? (process.env.KAFKA_BROKERS ?? "localhost:9092").split(",").map((s) => s.trim()),
43
+ clientId: config?.clientId ?? process.env.KAFKA_CLIENT_ID ?? "blok-worker",
44
+ saslUsername: config?.saslUsername ?? process.env.KAFKA_SASL_USERNAME,
45
+ saslPassword: config?.saslPassword ?? process.env.KAFKA_SASL_PASSWORD,
46
+ ssl: config?.ssl ?? process.env.KAFKA_SSL === "true",
47
+ };
48
+ }
49
+ async connect() {
50
+ if (this.connected)
51
+ return;
52
+ try {
53
+ // biome-ignore lint/suspicious/noExplicitAny: kafkajs is a runtime-loaded peer dep.
54
+ const kafkajs = await import("kafkajs");
55
+ const sasl = this.config.saslUsername && this.config.saslPassword
56
+ ? { mechanism: "plain", username: this.config.saslUsername, password: this.config.saslPassword }
57
+ : undefined;
58
+ this.kafka = new kafkajs.Kafka({
59
+ clientId: this.config.clientId,
60
+ brokers: this.config.brokers,
61
+ ssl: this.config.ssl,
62
+ sasl,
63
+ });
64
+ this.handle.producer = this.kafka.producer();
65
+ await this.handle.producer?.connect();
66
+ this.handle.admin = this.kafka.admin();
67
+ await this.handle.admin?.connect();
68
+ this.connected = true;
69
+ }
70
+ catch (err) {
71
+ throw new Error(`[blok][kafka] connect failed: ${err.message}. Install kafkajs as a peer dependency: bun add kafkajs`);
72
+ }
73
+ }
74
+ async disconnect() {
75
+ if (!this.connected)
76
+ return;
77
+ for (const [, consumer] of this.handle.consumers) {
78
+ try {
79
+ await consumer.disconnect();
80
+ }
81
+ catch {
82
+ /* ignore */
83
+ }
84
+ }
85
+ this.handle.consumers.clear();
86
+ try {
87
+ await this.handle.producer?.disconnect();
88
+ }
89
+ catch {
90
+ /* ignore */
91
+ }
92
+ try {
93
+ await this.handle.admin?.disconnect();
94
+ }
95
+ catch {
96
+ /* ignore */
97
+ }
98
+ this.connected = false;
99
+ }
100
+ async process(config, handler) {
101
+ if (!this.connected)
102
+ throw new Error("[blok][kafka] not connected. Call connect() first.");
103
+ const groupId = config.consumerGroup ?? `${config.queue}-group`;
104
+ const consumer = this.kafka.consumer({ groupId });
105
+ await consumer.connect();
106
+ await consumer.subscribe({ topic: config.queue, fromBeginning: config.fromBeginning === true });
107
+ this.handle.consumers.set(config.queue, consumer);
108
+ this.stats.set(config.queue, { completed: 0, failed: 0, active: 0 });
109
+ const stats = this.stats.get(config.queue);
110
+ await consumer.run({
111
+ autoCommit: config.ack !== false,
112
+ eachMessage: async ({ message, }) => {
113
+ const payloadString = message.value?.toString("utf8") ?? "";
114
+ let data;
115
+ try {
116
+ data = payloadString.length > 0 ? JSON.parse(payloadString) : null;
117
+ }
118
+ catch {
119
+ data = payloadString;
120
+ }
121
+ const headers = {};
122
+ if (message.headers) {
123
+ for (const [k, v] of Object.entries(message.headers))
124
+ headers[k] = v?.toString("utf8") ?? "";
125
+ }
126
+ const job = {
127
+ id: message.key?.toString("utf8") ?? `${config.queue}:${message.offset}`,
128
+ data,
129
+ headers,
130
+ queue: config.queue,
131
+ priority: config.priority ?? 0,
132
+ attempts: 0,
133
+ maxRetries: config.retries ?? 0,
134
+ createdAt: new Date(Number.parseInt(message.timestamp, 10)),
135
+ timeout: config.timeout,
136
+ raw: message,
137
+ complete: async () => {
138
+ stats.completed += 1;
139
+ },
140
+ fail: async (_err) => {
141
+ stats.failed += 1;
142
+ throw _err;
143
+ },
144
+ };
145
+ stats.active += 1;
146
+ try {
147
+ await handler(job);
148
+ stats.completed += 1;
149
+ }
150
+ catch (err) {
151
+ stats.failed += 1;
152
+ throw err;
153
+ }
154
+ finally {
155
+ stats.active = Math.max(0, stats.active - 1);
156
+ }
157
+ },
158
+ });
159
+ }
160
+ async addJob(queue, data, opts) {
161
+ if (!this.connected)
162
+ throw new Error("[blok][kafka] not connected. Call connect() first.");
163
+ if (!this.handle.producer)
164
+ throw new Error("[blok][kafka] producer not initialized");
165
+ const key = opts?.jobId ?? uuid();
166
+ const payload = typeof data === "string" ? data : JSON.stringify(data);
167
+ await this.handle.producer.send({
168
+ topic: queue,
169
+ messages: [
170
+ {
171
+ key,
172
+ value: payload,
173
+ headers: opts?.delay ? { "x-blok-delay-ms": String(opts.delay) } : undefined,
174
+ },
175
+ ],
176
+ });
177
+ return key;
178
+ }
179
+ async stopProcessing(queue) {
180
+ const consumer = this.handle.consumers.get(queue);
181
+ if (consumer) {
182
+ try {
183
+ await consumer.stop();
184
+ }
185
+ catch {
186
+ /* ignore */
187
+ }
188
+ try {
189
+ await consumer.disconnect();
190
+ }
191
+ catch {
192
+ /* ignore */
193
+ }
194
+ this.handle.consumers.delete(queue);
195
+ }
196
+ }
197
+ isConnected() {
198
+ return this.connected;
199
+ }
200
+ async healthCheck() {
201
+ if (!this.connected || !this.handle.admin)
202
+ return false;
203
+ try {
204
+ await this.handle.admin.fetchTopicOffsets("__consumer_offsets");
205
+ return true;
206
+ }
207
+ catch {
208
+ return false;
209
+ }
210
+ }
211
+ async getQueueStats(queue) {
212
+ const counters = this.stats.get(queue) ?? { completed: 0, failed: 0, active: 0 };
213
+ let waiting = 0;
214
+ if (this.handle.admin) {
215
+ try {
216
+ const offsets = await this.handle.admin.fetchTopicOffsets(queue);
217
+ // Approximate: total committed offsets across partitions. Real lag
218
+ // requires admin.fetchOffsets({ groupId }) — skipped here to keep
219
+ // the call cheap; production deployments should use Kafka's
220
+ // dedicated lag metrics anyway.
221
+ waiting = offsets.reduce((sum, p) => sum + Number.parseInt(p.offset, 10), 0);
222
+ }
223
+ catch {
224
+ waiting = 0;
225
+ }
226
+ }
227
+ return {
228
+ waiting,
229
+ active: counters.active,
230
+ completed: counters.completed,
231
+ failed: counters.failed,
232
+ delayed: 0,
233
+ };
234
+ }
235
+ }
236
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiS2Fma2FBZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXJzL0thZmthQWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2Qkc7QUFHSCxPQUFPLEVBQUUsRUFBRSxJQUFJLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQXNDbEMsTUFBTSxPQUFPLFlBQVk7SUFDZixRQUFRLEdBQUcsT0FBZ0IsQ0FBQztJQUNwQixNQUFNLENBQWM7SUFDckMsdUdBQXVHO0lBQy9GLEtBQUssR0FBUSxJQUFJLENBQUM7SUFDbEIsTUFBTSxHQUFrQixFQUFFLFNBQVMsRUFBRSxJQUFJLEdBQUcsRUFBRSxFQUFFLENBQUM7SUFDakQsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUNsQixLQUFLLEdBQW9DLElBQUksR0FBRyxFQUFFLENBQUM7SUFFM0QsWUFBWSxNQUE2QjtRQUN4QyxJQUFJLENBQUMsTUFBTSxHQUFHO1lBQ2IsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsSUFBSSxnQkFBZ0IsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUMzRyxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsSUFBSSxhQUFhO1lBQzFFLFlBQVksRUFBRSxNQUFNLEVBQUUsWUFBWSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CO1lBQ3JFLFlBQVksRUFBRSxNQUFNLEVBQUUsWUFBWSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CO1lBQ3JFLEdBQUcsRUFBRSxNQUFNLEVBQUUsR0FBRyxJQUFJLE9BQU8sQ0FBQyxHQUFH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QUFhO1FBQ2hDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUNqRixJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUM7UUFDaEIsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQztnQkFDSixNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNqRSxtRUFBbUU7Z0JBQ25FLGtFQUFrRTtnQkFDbEUsNERBQTREO2dCQUM1RCxnQ0FBZ0M7Z0JBQ2hDLE9BQU8sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM5RSxDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNSLE9BQU8sR0FBRyxDQUFDLENBQUM7WUFDYixDQUFDO1FBQ0YsQ0FBQztRQUNELE9BQU87WUFDTixPQUFPO1lBQ1AsTUFBTSxFQUFFLFFBQVEsQ0FBQyxNQUFNO1lBQ3ZCLFNBQVMsRUFBRSxRQUFRLENBQUMsU0FBUztZQUM3QixNQUFNLEVBQUUsUUFBUSxDQUFDLE1BQU07WUFDdkIsT0FBTyxFQUFFLENBQUM7U0FDVixDQUFDO0lBQ0gsQ0FBQztDQUNEIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBLYWZrYUFkYXB0ZXIg4oCUIHYwLjcgUFIgNSDigJQgV29ya2VyIGFkYXB0ZXIgYmFja2VkIGJ5IEFwYWNoZSBLYWZrYSB2aWFcbiAqIGBrYWZrYWpzYC4gQ29uc3VtZXMgZnJvbSBhIHRvcGljICh0aGUgYHF1ZXVlYCBmaWVsZCkgd2l0aCBhXG4gKiBjb25zdW1lci1ncm91cCBpZGVudGlmaWVyOyBwcm9kdWNlcyB2aWEgdGhlIHNhbWUgY2xpZW50LlxuICpcbiAqIEthZmthIGlzIGZ1bmRhbWVudGFsbHkgYSBzdHJlYW1pbmcgcGxhdGZvcm0g4oCUIG5vdCBhIHF1ZXVlIOKAlCBzbyBhXG4gKiBmZXcgc2VtYW50aWNzIGRpZmZlciBmcm9tIEJ1bGxNUS9TUVMvUmFiYml0TVE6XG4gKlxuICogICAtICoqT3JkZXJpbmcqKjogcGVyLXBhcnRpdGlvbiwgbm90IHBlci10b3BpYy4gU2V0IHRoZSBwYXJ0aXRpb25cbiAqICAgICBrZXkgdmlhIHRoZSBgZGVkdXBJZGAgZmllbGQgb24gYGFkZEpvYmAgdG8ga2VlcCByZWxhdGVkXG4gKiAgICAgbWVzc2FnZXMgb24gdGhlIHNhbWUgcGFydGl0aW9uLlxuICogICAtICoqUmV0cmllcyoqOiBLYWZrYSBkb2Vzbid0IGhhdmUgYSBicm9rZXItc2lkZSByZXRyeSBjb25jZXB0LlxuICogICAgIFRoZSBhZGFwdGVyIHJlLXRocm93cyBvbiBoYW5kbGVyIGZhaWx1cmU7IG9mZnNldCBjb21taXQgaXNcbiAqICAgICBzdXBwcmVzc2VkIHNvIHRoZSBjb25zdW1lciByZS1wb2xscyB0aGUgbWVzc2FnZSBvbiB0aGUgbmV4dFxuICogICAgIGN5Y2xlLiBGb3IgcmVhbCByZXRyeSBzZW1hbnRpY3MsIGxheWVyIGEgZGVhZC1sZXR0ZXIgdG9waWMuXG4gKiAgIC0gKipTdGF0cyoqOiBLYWZrYUpTIGV4cG9zZXMgY29uc3VtZXItZ3JvdXAgbGFnIHZpYSBpdHMgYWRtaW5cbiAqICAgICBjbGllbnQ7IHRoZSBsYWcgY291bnQgaXMgcmVwb3J0ZWQgYXMgYHdhaXRpbmdgLiBPdGhlciBzdGF0c1xuICogICAgIGFyZSB0cmFja2VkIGxvY2FsbHkgcGVyIGNvbnN1bWVyLlxuICpcbiAqIFJlcXVpcmVzIGBrYWZrYWpzYCBhcyBhIHBlZXIgZGVwZW5kZW5jeTpcbiAqXG4gKiAgICAgYnVuIGFkZCBrYWZrYWpzXG4gKlxuICogRW52aXJvbm1lbnQgdmFyaWFibGVzIChyZWFkIGF0IGFkYXB0ZXIgY29uc3RydWN0aW9uKTpcbiAqICAgLSBgS0FGS0FfQlJPS0VSU2AgICAgICAgICAgIOKAlCBjb21tYS1zZXBhcmF0ZWQgbGlzdCAoZGVmYXVsdCBgbG9jYWxob3N0OjkwOTJgKS5cbiAqICAgLSBgS0FGS0FfQ0xJRU5UX0lEYCAgICAgICAgIOKAlCBjbGllbnQuaWQgKGRlZmF1bHQgYFwiYmxvay13b3JrZXJcImApLlxuICogICAtIGBLQUZLQV9TQVNMX1VTRVJOQU1FYCAgICAg4oCUIFNBU0wvUExBSU4gdXNlcm5hbWUgKG9wdGlvbmFsKS5cbiAqICAgLSBgS0FGS0FfU0FTTF9QQVNTV09SRGAgICAgIOKAlCBTQVNML1BMQUlOIHBhc3N3b3JkIChvcHRpb25hbCkuXG4gKiAgIC0gYEtBRktBX1NTTGAgICAgICAgICAgICAgICDigJQgd2hlbiBgXCJ0cnVlXCJgLCBlbmFibGUgVExTLlxuICovXG5cbmltcG9ydCB0eXBlIHsgV29ya2VyVHJpZ2dlck9wdHMgfSBmcm9tIFwiQGJsb2tqcy9oZWxwZXJcIjtcbmltcG9ydCB7IHY0IGFzIHV1aWQgfSBmcm9tIFwidXVpZFwiO1xuaW1wb3J0IHR5cGUgeyBXb3JrZXJBZGFwdGVyLCBXb3JrZXJKb2IsIFdvcmtlclF1ZXVlU3RhdHMgfSBmcm9tIFwiLi4vV29ya2VyVHJpZ2dlclwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIEthZmthQ29uZmlnIHtcblx0YnJva2Vyczogc3RyaW5nW107XG5cdGNsaWVudElkOiBzdHJpbmc7XG5cdHNhc2xVc2VybmFtZT86IHN0cmluZztcblx0c2FzbFBhc3N3b3JkPzogc3RyaW5nO1xuXHRzc2w6IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBLYWZrYUpzSGFuZGxlIHtcblx0cHJvZHVjZXI/OiB7XG5cdFx0Y29ubmVjdDogKCkgPT4gUHJvbWlzZTx2b2lkPjtcblx0XHRkaXNjb25uZWN0OiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuXHRcdHNlbmQ6IChhcmdzOiB1bmtub3duKSA9PiBQcm9taXNlPHVua25vd24+O1xuXHR9O1xuXHRjb25zdW1lcnM6IE1hcDxcblx0XHRzdHJpbmcsXG5cdFx0e1xuXHRcdFx0ZGlzY29ubmVjdDogKCkgPT4gUHJvbWlzZTx2b2lkPjtcblx0XHRcdHN0b3A6ICgpID0+IFByb21pc2U8dm9pZD47XG5cdFx0XHRydW46IChvcHRzOiB1bmtub3duKSA9PiBQcm9taXNlPHZvaWQ+O1xuXHRcdH1cblx0Pjtcblx0YWRtaW4/OiB7XG5cdFx0Y29ubmVjdDogKCkgPT4gUHJvbWlzZTx2b2lkPjtcblx0XHRkaXNjb25uZWN0OiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuXHRcdGZldGNoVG9waWNPZmZzZXRzOiAodG9waWM6IHN0cmluZykgPT4gUHJvbWlzZTxBcnJheTx7IHBhcnRpdGlvbjogbnVtYmVyOyBvZmZzZXQ6IHN0cmluZyB9Pj47XG5cdH07XG59XG5cbmludGVyZmFjZSBRdWV1ZVN0YXRzQ291bnRlcnMge1xuXHRjb21wbGV0ZWQ6IG51bWJlcjtcblx0ZmFpbGVkOiBudW1iZXI7XG5cdGFjdGl2ZTogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgS2Fma2FBZGFwdGVyIGltcGxlbWVudHMgV29ya2VyQWRhcHRlciB7XG5cdHJlYWRvbmx5IHByb3ZpZGVyID0gXCJrYWZrYVwiIGFzIGNvbnN0O1xuXHRwcml2YXRlIHJlYWRvbmx5IGNvbmZpZzogS2Fma2FDb25maWc7XG5cdC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueToga2Fma2FqcydzIGV4cG9ydGVkIGBLYWZrYWAgY29uc3RydWN0b3IgaXMgbG9vc2VseSB0eXBlZC5cblx0cHJpdmF0ZSBrYWZrYTogYW55ID0gbnVsbDtcblx0cHJpdmF0ZSBoYW5kbGU6IEthZmthSnNIYW5kbGUgPSB7IGNvbnN1bWVyczogbmV3IE1hcCgpIH07XG5cdHByaXZhdGUgY29ubmVjdGVkID0gZmFsc2U7XG5cdHByaXZhdGUgc3RhdHM6IE1hcDxzdHJpbmcsIFF1ZXVlU3RhdHNDb3VudGVycz4gPSBuZXcgTWFwKCk7XG5cblx0Y29uc3RydWN0b3IoY29uZmlnPzogUGFydGlhbDxLYWZrYUNvbmZpZz4pIHtcblx0XHR0aGlzLmNvbmZpZyA9IHtcblx0XHRcdGJyb2tlcnM6IGNvbmZpZz8uYnJva2VycyA/PyAocHJvY2Vzcy5lbnYuS0FGS0FfQlJPS0VSUyA/PyBcImxvY2FsaG9zdDo5MDkyXCIpLnNwbGl0KFwiLFwiKS5tYXAoKHMpID0+IHMudHJpbSgpKSxcblx0XHRcdGNsaWVudElkOiBjb25maWc/LmNsaWVudElkID8/IHByb2Nlc3MuZW52LktBRktBX0NMSUVOVF9JRCA/PyBcImJsb2std29ya2VyXCIsXG5cdFx0XHRzYXNsVXNlcm5hbWU6IGNvbmZpZz8uc2FzbFVzZXJuYW1lID8/IHByb2Nlc3MuZW52LktBRktBX1NBU0xfVVNFUk5BTUUsXG5cdFx0XHRzYXNsUGFzc3dvcmQ6IGNvbmZpZz8uc2FzbFBhc3N3b3JkID8/IHByb2Nlc3MuZW52LktBRktBX1NBU0xfUEFTU1dPUkQsXG5cdFx0XHRzc2w6IGNvbmZpZz8uc3NsID8/IHByb2Nlc3MuZW52LktBRktBX1NTTCA9PT0gXCJ0cnVlXCIsXG5cdFx0fTtcblx0fVxuXG5cdGFzeW5jIGNvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKHRoaXMuY29ubmVjdGVkKSByZXR1cm47XG5cdFx0dHJ5IHtcblx0XHRcdC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueToga2Fma2FqcyBpcyBhIHJ1bnRpbWUtbG9hZGVkIHBlZXIgZGVwLlxuXHRcdFx0Y29uc3Qga2Fma2FqczogYW55ID0gYXdhaXQgaW1wb3J0KFwia2Fma2Fqc1wiKTtcblx0XHRcdGNvbnN0IHNhc2wgPVxuXHRcdFx0XHR0aGlzLmNvbmZpZy5zYXNsVXNlcm5hbWUgJiYgdGhpcy5jb25maWcuc2FzbFBhc3N3b3JkXG5cdFx0XHRcdFx0PyB7IG1lY2hhbmlzbTogXCJwbGFpblwiLCB1c2VybmFtZTogdGhpcy5jb25maWcuc2FzbFVzZXJuYW1lLCBwYXNzd29yZDogdGhpcy5jb25maWcuc2FzbFBhc3N3b3JkIH1cblx0XHRcdFx0XHQ6IHVuZGVmaW5lZDtcblx0XHRcdHRoaXMua2Fma2EgPSBuZXcga2Fma2Fqcy5LYWZrYSh7XG5cdFx0XHRcdGNsaWVudElkOiB0aGlzLmNvbmZpZy5jbGllbnRJZCxcblx0XHRcdFx0YnJva2VyczogdGhpcy5jb25maWcuYnJva2Vycyxcblx0XHRcdFx0c3NsOiB0aGlzLmNvbmZpZy5zc2wsXG5cdFx0XHRcdHNhc2wsXG5cdFx0XHR9KTtcblx0XHRcdHRoaXMuaGFuZGxlLnByb2R1Y2VyID0gdGhpcy5rYWZrYS5wcm9kdWNlcigpO1xuXHRcdFx0YXdhaXQgdGhpcy5oYW5kbGUucHJvZHVjZXI/LmNvbm5lY3QoKTtcblx0XHRcdHRoaXMuaGFuZGxlLmFkbWluID0gdGhpcy5rYWZrYS5hZG1pbigpO1xuXHRcdFx0YXdhaXQgdGhpcy5oYW5kbGUuYWRtaW4/LmNvbm5lY3QoKTtcblx0XHRcdHRoaXMuY29ubmVjdGVkID0gdHJ1ZTtcblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihcblx0XHRcdFx0YFtibG9rXVtrYWZrYV0gY29ubmVjdCBmYWlsZWQ6ICR7KGVyciBhcyBFcnJvcikubWVzc2FnZX0uIEluc3RhbGwga2Fma2FqcyBhcyBhIHBlZXIgZGVwZW5kZW5jeTogYnVuIGFkZCBrYWZrYWpzYCxcblx0XHRcdCk7XG5cdFx0fVxuXHR9XG5cblx0YXN5bmMgZGlzY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRpZiAoIXRoaXMuY29ubmVjdGVkKSByZXR1cm47XG5cdFx0Zm9yIChjb25zdCBbLCBjb25zdW1lcl0gb2YgdGhpcy5oYW5kbGUuY29uc3VtZXJzKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRhd2FpdCBjb25zdW1lci5kaXNjb25uZWN0KCk7XG5cdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0LyogaWdub3JlICovXG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRoaXMuaGFuZGxlLmNvbnN1bWVycy5jbGVhcigpO1xuXHRcdHRyeSB7XG5cdFx0XHRhd2FpdCB0aGlzLmhhbmRsZS5wcm9kdWNlcj8uZGlzY29ubmVjdCgpO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0LyogaWdub3JlICovXG5cdFx0fVxuXHRcdHRyeSB7XG5cdFx0XHRhd2FpdCB0aGlzLmhhbmRsZS5hZG1pbj8uZGlzY29ubmVjdCgpO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0LyogaWdub3JlICovXG5cdFx0fVxuXHRcdHRoaXMuY29ubmVjdGVkID0gZmFsc2U7XG5cdH1cblxuXHRhc3luYyBwcm9jZXNzKGNvbmZpZzogV29ya2VyVHJpZ2dlck9wdHMsIGhhbmRsZXI6IChqb2I6IFdvcmtlckpvYikgPT4gUHJvbWlzZTx2b2lkPik6IFByb21pc2U8dm9pZD4ge1xuXHRcdGlmICghdGhpcy5jb25uZWN0ZWQpIHRocm93IG5ldyBFcnJvcihcIltibG9rXVtrYWZrYV0gbm90IGNvbm5lY3RlZC4gQ2FsbCBjb25uZWN0KCkgZmlyc3QuXCIpO1xuXHRcdGNvbnN0IGdyb3VwSWQgPSBjb25maWcuY29uc3VtZXJHcm91cCA/PyBgJHtjb25maWcucXVldWV9LWdyb3VwYDtcblx0XHRjb25zdCBjb25zdW1lciA9IHRoaXMua2Fma2EuY29uc3VtZXIoeyBncm91cElkIH0pO1xuXHRcdGF3YWl0IGNvbnN1bWVyLmNvbm5lY3QoKTtcblx0XHRhd2FpdCBjb25zdW1lci5zdWJzY3JpYmUoeyB0b3BpYzogY29uZmlnLnF1ZXVlLCBmcm9tQmVnaW5uaW5nOiBjb25maWcuZnJvbUJlZ2lubmluZyA9PT0gdHJ1ZSB9KTtcblx0XHR0aGlzLmhhbmRsZS5jb25zdW1lcnMuc2V0KGNvbmZpZy5xdWV1ZSwgY29uc3VtZXIpO1xuXHRcdHRoaXMuc3RhdHMuc2V0KGNvbmZpZy5xdWV1ZSwgeyBjb21wbGV0ZWQ6IDAsIGZhaWxlZDogMCwgYWN0aXZlOiAwIH0pO1xuXHRcdGNvbnN0IHN0YXRzID0gdGhpcy5zdGF0cy5nZXQoY29uZmlnLnF1ZXVlKSBhcyBRdWV1ZVN0YXRzQ291bnRlcnM7XG5cblx0XHRhd2FpdCBjb25zdW1lci5ydW4oe1xuXHRcdFx0YXV0b0NvbW1pdDogY29uZmlnLmFjayAhPT0gZmFsc2UsXG5cdFx0XHRlYWNoTWVzc2FnZTogYXN5bmMgKHtcblx0XHRcdFx0bWVzc2FnZSxcblx0XHRcdH06IHtcblx0XHRcdFx0bWVzc2FnZTogeyBrZXk/OiBCdWZmZXI7IHZhbHVlPzogQnVmZmVyOyBvZmZzZXQ6IHN0cmluZzsgdGltZXN0YW1wOiBzdHJpbmc7IGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBCdWZmZXI+IH07XG5cdFx0XHR9KSA9PiB7XG5cdFx0XHRcdGNvbnN0IHBheWxvYWRTdHJpbmcgPSBtZXNzYWdlLnZhbHVlPy50b1N0cmluZyhcInV0ZjhcIikgPz8gXCJcIjtcblx0XHRcdFx0bGV0IGRhdGE6IHVua25vd247XG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0ZGF0YSA9IHBheWxvYWRTdHJpbmcubGVuZ3RoID4gMCA/IEpTT04ucGFyc2UocGF5bG9hZFN0cmluZykgOiBudWxsO1xuXHRcdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0XHRkYXRhID0gcGF5bG9hZFN0cmluZztcblx0XHRcdFx0fVxuXHRcdFx0XHRjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cdFx0XHRcdGlmIChtZXNzYWdlLmhlYWRlcnMpIHtcblx0XHRcdFx0XHRmb3IgKGNvbnN0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyhtZXNzYWdlLmhlYWRlcnMpKSBoZWFkZXJzW2tdID0gdj8udG9TdHJpbmcoXCJ1dGY4XCIpID8/IFwiXCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y29uc3Qgam9iOiBXb3JrZXJKb2IgPSB7XG5cdFx0XHRcdFx0aWQ6IG1lc3NhZ2Uua2V5Py50b1N0cmluZyhcInV0ZjhcIikgPz8gYCR7Y29uZmlnLnF1ZXVlfToke21lc3NhZ2Uub2Zmc2V0fWAsXG5cdFx0XHRcdFx0ZGF0YSxcblx0XHRcdFx0XHRoZWFkZXJzLFxuXHRcdFx0XHRcdHF1ZXVlOiBjb25maWcucXVldWUsXG5cdFx0XHRcdFx0cHJpb3JpdHk6IGNvbmZpZy5wcmlvcml0eSA/PyAwLFxuXHRcdFx0XHRcdGF0dGVtcHRzOiAwLFxuXHRcdFx0XHRcdG1heFJldHJpZXM6IGNvbmZpZy5yZXRyaWVzID8/IDAsXG5cdFx0XHRcdFx0Y3JlYXRlZEF0OiBuZXcgRGF0ZShOdW1iZXIucGFyc2VJbnQobWVzc2FnZS50aW1lc3RhbXAsIDEwKSksXG5cdFx0XHRcdFx0dGltZW91dDogY29uZmlnLnRpbWVvdXQsXG5cdFx0XHRcdFx0cmF3OiBtZXNzYWdlLFxuXHRcdFx0XHRcdGNvbXBsZXRlOiBhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0XHRzdGF0cy5jb21wbGV0ZWQgKz0gMTtcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdGZhaWw6IGFzeW5jIChfZXJyOiBFcnJvcikgPT4ge1xuXHRcdFx0XHRcdFx0c3RhdHMuZmFpbGVkICs9IDE7XG5cdFx0XHRcdFx0XHR0aHJvdyBfZXJyO1xuXHRcdFx0XHRcdH0sXG5cdFx0XHRcdH07XG5cdFx0XHRcdHN0YXRzLmFjdGl2ZSArPSAxO1xuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdGF3YWl0IGhhbmRsZXIoam9iKTtcblx0XHRcdFx0XHRzdGF0cy5jb21wbGV0ZWQgKz0gMTtcblx0XHRcdFx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0XHRcdFx0c3RhdHMuZmFpbGVkICs9IDE7XG5cdFx0XHRcdFx0dGhyb3cgZXJyO1xuXHRcdFx0XHR9IGZpbmFsbHkge1xuXHRcdFx0XHRcdHN0YXRzLmFjdGl2ZSA9IE1hdGgubWF4KDAsIHN0YXRzLmFjdGl2ZSAtIDEpO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdH0pO1xuXHR9XG5cblx0YXN5bmMgYWRkSm9iKFxuXHRcdHF1ZXVlOiBzdHJpbmcsXG5cdFx0ZGF0YTogdW5rbm93bixcblx0XHRvcHRzPzogeyBwcmlvcml0eT86IG51bWJlcjsgZGVsYXk/OiBudW1iZXI7IHJldHJpZXM/OiBudW1iZXI7IHRpbWVvdXQ/OiBudW1iZXI7IGpvYklkPzogc3RyaW5nIH0sXG5cdCk6IFByb21pc2U8c3RyaW5nPiB7XG5cdFx0aWYgKCF0aGlzLmNvbm5lY3RlZCkgdGhyb3cgbmV3IEVycm9yKFwiW2Jsb2tdW2thZmthXSBub3QgY29ubmVjdGVkLiBDYWxsIGNvbm5lY3QoKSBmaXJzdC5cIik7XG5cdFx0aWYgKCF0aGlzLmhhbmRsZS5wcm9kdWNlcikgdGhyb3cgbmV3IEVycm9yKFwiW2Jsb2tdW2thZmthXSBwcm9kdWNlciBub3QgaW5pdGlhbGl6ZWRcIik7XG5cdFx0Y29uc3Qga2V5ID0gb3B0cz8uam9iSWQgPz8gdXVpZCgpO1xuXHRcdGNvbnN0IHBheWxvYWQgPSB0eXBlb2YgZGF0YSA9PT0gXCJzdHJpbmdcIiA/IGRhdGEgOiBKU09OLnN0cmluZ2lmeShkYXRhKTtcblx0XHRhd2FpdCB0aGlzLmhhbmRsZS5wcm9kdWNlci5zZW5kKHtcblx0XHRcdHRvcGljOiBxdWV1ZSxcblx0XHRcdG1lc3NhZ2VzOiBbXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRrZXksXG5cdFx0XHRcdFx0dmFsdWU6IHBheWxvYWQsXG5cdFx0XHRcdFx0aGVhZGVyczogb3B0cz8uZGVsYXkgPyB7IFwieC1ibG9rLWRlbGF5LW1zXCI6IFN0cmluZyhvcHRzLmRlbGF5KSB9IDogdW5kZWZpbmVkLFxuXHRcdFx0XHR9LFxuXHRcdFx0XSxcblx0XHR9KTtcblx0XHRyZXR1cm4ga2V5O1xuXHR9XG5cblx0YXN5bmMgc3RvcFByb2Nlc3NpbmcocXVldWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IGNvbnN1bWVyID0gdGhpcy5oYW5kbGUuY29uc3VtZXJzLmdldChxdWV1ZSk7XG5cdFx0aWYgKGNvbnN1bWVyKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRhd2FpdCBjb25zdW1lci5zdG9wKCk7XG5cdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0LyogaWdub3JlICovXG5cdFx0XHR9XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRhd2FpdCBjb25zdW1lci5kaXNjb25uZWN0KCk7XG5cdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0LyogaWdub3JlICovXG5cdFx0XHR9XG5cdFx0XHR0aGlzLmhhbmRsZS5jb25zdW1lcnMuZGVsZXRlKHF1ZXVlKTtcblx0XHR9XG5cdH1cblxuXHRpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5jb25uZWN0ZWQ7XG5cdH1cblxuXHRhc3luYyBoZWFsdGhDaGVjaygpOiBQcm9taXNlPGJvb2xlYW4+IHtcblx0XHRpZiAoIXRoaXMuY29ubmVjdGVkIHx8ICF0aGlzLmhhbmRsZS5hZG1pbikgcmV0dXJuIGZhbHNlO1xuXHRcdHRyeSB7XG5cdFx0XHRhd2FpdCB0aGlzLmhhbmRsZS5hZG1pbi5mZXRjaFRvcGljT2Zmc2V0cyhcIl9fY29uc3VtZXJfb2Zmc2V0c1wiKTtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fVxuXG5cdGFzeW5jIGdldFF1ZXVlU3RhdHMocXVldWU6IHN0cmluZyk6IFByb21pc2U8V29ya2VyUXVldWVTdGF0cz4ge1xuXHRcdGNvbnN0IGNvdW50ZXJzID0gdGhpcy5zdGF0cy5nZXQocXVldWUpID8/IHsgY29tcGxldGVkOiAwLCBmYWlsZWQ6IDAsIGFjdGl2ZTogMCB9O1xuXHRcdGxldCB3YWl0aW5nID0gMDtcblx0XHRpZiAodGhpcy5oYW5kbGUuYWRtaW4pIHtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdGNvbnN0IG9mZnNldHMgPSBhd2FpdCB0aGlzLmhhbmRsZS5hZG1pbi5mZXRjaFRvcGljT2Zmc2V0cyhxdWV1ZSk7XG5cdFx0XHRcdC8vIEFwcHJveGltYXRlOiB0b3RhbCBjb21taXR0ZWQgb2Zmc2V0cyBhY3Jvc3MgcGFydGl0aW9ucy4gUmVhbCBsYWdcblx0XHRcdFx0Ly8gcmVxdWlyZXMgYWRtaW4uZmV0Y2hPZmZzZXRzKHsgZ3JvdXBJZCB9KSDigJQgc2tpcHBlZCBoZXJlIHRvIGtlZXBcblx0XHRcdFx0Ly8gdGhlIGNhbGwgY2hlYXA7IHByb2R1Y3Rpb24gZGVwbG95bWVudHMgc2hvdWxkIHVzZSBLYWZrYSdzXG5cdFx0XHRcdC8vIGRlZGljYXRlZCBsYWcgbWV0cmljcyBhbnl3YXkuXG5cdFx0XHRcdHdhaXRpbmcgPSBvZmZzZXRzLnJlZHVjZSgoc3VtLCBwKSA9PiBzdW0gKyBOdW1iZXIucGFyc2VJbnQocC5vZmZzZXQsIDEwKSwgMCk7XG5cdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0d2FpdGluZyA9IDA7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB7XG5cdFx0XHR3YWl0aW5nLFxuXHRcdFx0YWN0aXZlOiBjb3VudGVycy5hY3RpdmUsXG5cdFx0XHRjb21wbGV0ZWQ6IGNvdW50ZXJzLmNvbXBsZXRlZCxcblx0XHRcdGZhaWxlZDogY291bnRlcnMuZmFpbGVkLFxuXHRcdFx0ZGVsYXllZDogMCxcblx0XHR9O1xuXHR9XG59XG4iXX0=