@pipeline-builder/api-core 4.1.6 → 4.1.8

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 (68) hide show
  1. package/README.md +8 -0
  2. package/lib/helpers/org-hierarchy.d.ts +19 -0
  3. package/lib/helpers/org-hierarchy.js +29 -1
  4. package/lib/index.d.ts +26 -0
  5. package/lib/index.js +27 -1
  6. package/lib/middleware/auth.d.ts +57 -0
  7. package/lib/middleware/auth.js +89 -1
  8. package/lib/middleware/route-table.d.ts +26 -0
  9. package/lib/middleware/route-table.js +7 -1
  10. package/lib/services/api-key-exchange.js +3 -2
  11. package/lib/services/audit-spool.js +3 -2
  12. package/lib/services/cache-service.js +5 -4
  13. package/lib/services/compliance-event-subscriber.js +3 -2
  14. package/lib/services/durable-event-bus.js +3 -2
  15. package/lib/services/entity-events.js +3 -2
  16. package/lib/services/env-redis.js +3 -2
  17. package/lib/services/http-client.js +8 -7
  18. package/lib/services/index.d.ts +6 -2
  19. package/lib/services/index.js +11 -3
  20. package/lib/services/jwks-cache.d.ts +0 -12
  21. package/lib/services/jwks-cache.js +7 -6
  22. package/lib/services/leader-lock.js +3 -2
  23. package/lib/services/notification-channels.d.ts +112 -0
  24. package/lib/services/notification-channels.js +123 -0
  25. package/lib/services/quota.js +4 -4
  26. package/lib/services/remote-audit-client.d.ts +1 -1
  27. package/lib/services/remote-audit-client.js +4 -4
  28. package/lib/services/retry-forever.d.ts +37 -0
  29. package/lib/services/retry-forever.js +58 -0
  30. package/lib/services/retry-strategy.d.ts +7 -3
  31. package/lib/services/retry-strategy.js +2 -2
  32. package/lib/services/scheduler.js +2 -2
  33. package/lib/services/service-boot.d.ts +20 -4
  34. package/lib/services/service-boot.js +10 -6
  35. package/lib/services/service-keys.js +6 -5
  36. package/lib/services/sse-ticket-store.js +3 -2
  37. package/lib/services/token-revocation.js +6 -5
  38. package/lib/testing/mock-api-core.d.ts +150 -0
  39. package/lib/testing/mock-api-core.js +246 -0
  40. package/lib/testing/mock-drizzle.d.ts +6 -0
  41. package/lib/testing/mock-drizzle.js +57 -0
  42. package/lib/types/common.d.ts +20 -0
  43. package/lib/types/common.js +1 -1
  44. package/lib/types/http.d.ts +4 -0
  45. package/lib/types/http.js +1 -1
  46. package/lib/types/index.d.ts +1 -0
  47. package/lib/types/index.js +2 -1
  48. package/lib/types/metadata-keys.d.ts +543 -0
  49. package/lib/types/metadata-keys.js +117 -0
  50. package/lib/types/permissions.d.ts +41 -0
  51. package/lib/types/permissions.js +70 -1
  52. package/lib/types/quota-tiers.js +21 -31
  53. package/lib/utils/api-key.d.ts +0 -9
  54. package/lib/utils/api-key.js +2 -13
  55. package/lib/utils/audit.js +3 -2
  56. package/lib/utils/env.d.ts +6 -2
  57. package/lib/utils/env.js +9 -4
  58. package/lib/utils/identity.d.ts +37 -1
  59. package/lib/utils/identity.js +62 -10
  60. package/lib/utils/index.d.ts +2 -1
  61. package/lib/utils/index.js +7 -2
  62. package/lib/utils/params.d.ts +35 -0
  63. package/lib/utils/params.js +24 -1
  64. package/lib/utils/secret-encryption.d.ts +4 -4
  65. package/lib/utils/secret-encryption.js +5 -5
  66. package/lib/utils/ssrf.d.ts +73 -14
  67. package/lib/utils/ssrf.js +138 -21
  68. package/package.json +26 -1
@@ -3,6 +3,7 @@
3
3
  import { JWKS_PATH, isJwksDocument, publicKeyFromJwk, } from '../utils/jwk.js';
4
4
  import { createLogger } from '../utils/logger.js';
5
5
  import { emitCounter } from '../utils/metric-emitter.js';
6
+ import { errorMessage } from '../utils/response.js';
6
7
  const logger = createLogger('jwks-cache');
7
8
  /** How long a fetched key set is served before a refresh is due. */
8
9
  export const JWKS_REFRESH_INTERVAL_MS = 600_000; // 10 minutes
@@ -105,7 +106,7 @@ export class JwksCache {
105
106
  if (this.keys.size > 0) {
106
107
  logger.warn('JWKS refresh failed; continuing on the cached key set', {
107
108
  source: this.source,
108
- error: error instanceof Error ? error.message : String(error),
109
+ error: errorMessage(error),
109
110
  });
110
111
  return;
111
112
  }
@@ -132,7 +133,7 @@ export class JwksCache {
132
133
  emitCounter('jwks_fetch_total', { source: this.source, result: 'error' });
133
134
  logger.warn('JWKS fetch failed', {
134
135
  source: this.source,
135
- error: error instanceof Error ? error.message : String(error),
136
+ error: errorMessage(error),
136
137
  });
137
138
  throw error instanceof Error ? error : new Error(String(error));
138
139
  }
@@ -145,7 +146,7 @@ export class JwksCache {
145
146
  }
146
147
  catch (error) {
147
148
  // One unusable entry must not discard the rest of the set.
148
- logger.warn('Skipping unusable JWKS entry', { kid: jwk.kid, error: error instanceof Error ? error.message : String(error) });
149
+ logger.warn('Skipping unusable JWKS entry', { kid: jwk.kid, error: errorMessage(error) });
149
150
  }
150
151
  }
151
152
  if (keys.size === 0) {
@@ -168,7 +169,7 @@ export class JwksCache {
168
169
  * Unauthenticated by design: the key set is public, and requiring a credential
169
170
  * to fetch the keys that verify credentials is a bootstrap cycle.
170
171
  */
171
- export async function fetchPlatformJwks() {
172
+ async function fetchPlatformJwks() {
172
173
  const absolute = process.env.PLATFORM_JWKS_URL;
173
174
  const timeout = parseInt(process.env.JWKS_FETCH_TIMEOUT_MS || '3000', 10);
174
175
  if (absolute)
@@ -190,7 +191,7 @@ export async function fetchPlatformJwks() {
190
191
  return res.body;
191
192
  }
192
193
  /** Fetch a JWKS document from an absolute URL (outside-the-cluster verifiers). */
193
- export async function fetchJwksFromUrl(url, timeoutMs = 3000) {
194
+ async function fetchJwksFromUrl(url, timeoutMs = 3000) {
194
195
  const controller = new AbortController();
195
196
  const timer = setTimeout(() => controller.abort(), timeoutMs);
196
197
  try {
@@ -219,4 +220,4 @@ export function platformJwksCache() {
219
220
  export function setPlatformJwksCache(cache) {
220
221
  platformJwks = cache;
221
222
  }
222
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiandrcy1jYWNoZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9qd2tzLWNhY2hlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUE0QnRDLE9BQU8sRUFDTCxTQUFTLEVBQ1QsY0FBYyxFQUNkLGdCQUFnQixHQUdqQixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFekQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDO0FBRTFDLG9FQUFvRTtBQUNwRSxNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBRyxPQUFPLENBQUMsQ0FBQyxhQUFhO0FBRTlELDREQUE0RDtBQUM1RCxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUM7QUFFM0MsMkZBQTJGO0FBQzNGLE1BQU0sQ0FBQyxNQUFNLCtCQUErQixHQUFHLE1BQU0sQ0FBQztBQUV0RCx3RkFBd0Y7QUFDeEYsTUFBTSxPQUFPLG9CQUFxQixTQUFRLEtBQUs7SUFDN0MsWUFBWSxPQUFPLEdBQUcsZ0RBQWdEO1FBQ3BFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNmLElBQUksQ0FBQyxJQUFJLEdBQUcsc0JBQXNCLENBQUM7SUFDckMsQ0FBQztDQUNGO0FBRUQsb0ZBQW9GO0FBQ3BGLE1BQU0sT0FBTyxlQUFnQixTQUFRLEtBQUs7SUFDeEMsWUFBWSxHQUFXO1FBQ3JCLEtBQUssQ0FBQyxvQ0FBb0MsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsSUFBSSxHQUFHLGlCQUFpQixDQUFDO0lBQ2hDLENBQUM7Q0FDRjtBQWNEOzs7R0FHRztBQUNILE1BQU0sT0FBTyxTQUFTO0lBWVMsT0FBTztJQVg1QixJQUFJLEdBQUcsSUFB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RyxFQUFFLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQzlELElBQUksQ0FBQztRQUNILE1BQU0sR0FBRyxHQUFHLE1BQU0sS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxFQUFFLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNyRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHVCQUF1QixHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUNsRSxNQUFNLElBQUksR0FBWSxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN2QyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsaUNBQWlDLENBQUMsQ0FBQztRQUM5RSxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7WUFBUyxDQUFDO1FBQ1QsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3RCLENBQUM7QUFDSCxDQUFDO0FBRUQsSUFBSSxZQUFtQyxDQUFDO0FBRXhDLG1FQUFtRTtBQUNuRSxNQUFNLFVBQVUsaUJBQWlCO0lBQy9CLFlBQVksS0FBSyxJQUFJLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQztJQUNqRixPQUFPLFlBQVksQ0FBQztBQUN0QixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUFDLEtBQTRCO0lBQy9ELFlBQVksR0FBRyxLQUFLLENBQUM7QUFDdkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqIFRoZSBKV0tTIGNhY2hlIGV2ZXJ5IHZlcmlmaWVyIGluIHRoZSBmbGVldCBzaGFyZXMuXG4gKlxuICogUGxhdGZvcm0gc2lnbnMgdXNlciB0b2tlbnMgd2l0aCBFUzI1NiBhbmQgcHVibGlzaGVzIHRoZSBwdWJsaWMgaGFsdmVzIGF0XG4gKiBgLy53ZWxsLWtub3duL2p3a3MuanNvbmAuIFZlcmlmaWVycyBtdXN0IG5vdCBmZXRjaCB0aGF0IHBlciByZXF1ZXN0IChwbGF0Zm9ybVxuICogd291bGQgbGFuZCBvbiB0aGUgaG90IHBhdGggb2YgdGhlIHdob2xlIGZsZWV0KSBub3IgY2FjaGUgaXQgZm9yZXZlciAoYSByb3RhdGVkXG4gKiBrZXkgd291bGQgbmV2ZXIgYmUgcGlja2VkIHVwKSwgc28gdGhlIGNvbnRyYWN0IGlzIGZpeGVkIGhlcmUgYW5kIHJldXNlZCBieVxuICogYXBpLWNvcmUncyBgcmVxdWlyZUF1dGhgLCBpbWFnZS1yZWdpc3RyeSdzIGF1dGggcmVzb2x2ZXIgYW5kIHRoZSBDTEk6XG4gKlxuICogLSAqKlJlZnJlc2ggZXZlcnkgMTAgbWludXRlcy4qKiBBIGtleSByb3RhdGVkIGluIGF0IHBsYXRmb3JtIGlzIHRydXN0ZWQgZmxlZXQtXG4gKiAgIHdpZGUgd2l0aGluIHRoYXQgd2luZG93IHdpdGhvdXQgYW55b25lIHJlc3RhcnRpbmcuXG4gKiAtICoqUmVmZXRjaCBvbmNlIG9uIGFuIHVua25vd24gYGtpZGAuKiogQSBicmFuZC1uZXcgc2lnbmluZyBrZXkgaXMgcGlja2VkIHVwXG4gKiAgIGltbWVkaWF0ZWx5IGluc3RlYWQgb2YgNDAxLWluZyBldmVyeSByZXF1ZXN0IHVudGlsIHRoZSBuZXh0IHJlZnJlc2guIFJhdGUtXG4gKiAgIGxpbWl0ZWQgKHtAbGluayBVTktOT1dOX0tJRF9SRUZFVENIX0NPT0xET1dOX01TfSkgc28gYSBmbG9vZCBvZiBmb3JnZWQgYGtpZGBzXG4gKiAgIGNhbid0IHR1cm4gaW50byBhIGZldGNoIHN0b3JtIGFnYWluc3QgcGxhdGZvcm0uXG4gKiAtICoqTmVnYXRpdmUtY2FjaGUgZmFpbHVyZXMgYnJpZWZseS4qKiBBIHBsYXRmb3JtIG91dGFnZSBkb2Vzbid0IGJlY29tZSBhXG4gKiAgIGZldGNoLXBlci1yZXF1ZXN0IGFtcGxpZmllci5cbiAqIC0gKipGYWlsIGNsb3NlZC4qKiBBbiB1bnZlcmlmaWFibGUgdG9rZW4gaXMgbm90IGFuIGlkZW50aXR5OiB3aGVuIHRoZSBrZXkgc2V0XG4gKiAgIGNhbm5vdCBiZSBvYnRhaW5lZCB0aGUgdmVyaWZpZXIgdGhyb3dzIHtAbGluayBKd2tzVW5hdmFpbGFibGVFcnJvcn0gYW5kIHRoZVxuICogICBjYWxsZXIgYW5zd2VycyA0MDEvNTAzIOKAlCBpdCBORVZFUiBmYWxscyB0aHJvdWdoIHRvIFwiYWxsb3dcIi5cbiAqICAgQSBrZXkgc2V0IGFscmVhZHkgaW4gaGFuZCBpcyBzdGlsbCB1c2VkIHdoaWxlIGEgcmVmcmVzaCBpcyBmYWlsaW5nICh0aGUga2V5c1xuICogICBhcmUgcHVibGljIGFuZCBkb24ndCBleHBpcmU7IHJlZnVzaW5nIGV2ZXJ5IHJlcXVlc3QgYmVjYXVzZSBwbGF0Zm9ybSBibGlwcGVkXG4gKiAgIHdvdWxkIGJlIGEgc2VsZi1pbmZsaWN0ZWQgb3V0YWdlKSwgd2hpY2ggaXMgd2h5IHRoZSBuZWdhdGl2ZSBjYWNoZSBleGlzdHMuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBLZXlPYmplY3QgfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHtcbiAgSldLU19QQVRILFxuICBpc0p3a3NEb2N1bWVudCxcbiAgcHVibGljS2V5RnJvbUp3ayxcbiAgdHlwZSBKd2tzRG9jdW1lbnQsXG4gIHR5cGUgUHVibGljSndrLFxufSBmcm9tICcuLi91dGlscy9qd2suanMnO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyLmpzJztcbmltcG9ydCB7IGVtaXRDb3VudGVyIH0gZnJvbSAnLi4vdXRpbHMvbWV0cmljLWVtaXR0ZXIuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ2p3a3MtY2FjaGUnKTtcblxuLyoqIEhvdyBsb25nIGEgZmV0Y2hlZCBrZXkgc2V0IGlzIHNlcnZlZCBiZWZvcmUgYSByZWZyZXNoIGlzIGR1ZS4gKi9cbmV4cG9ydCBjb25zdCBKV0tTX1JFRlJFU0hfSU5URVJWQUxfTVMgPSA2MDBfMDAwOyAvLyAxMCBtaW51dGVzXG5cbi8qKiBIb3cgbG9uZyBhIGZldGNoIEZBSUxVUkUgc3VwcHJlc3NlcyBmdXJ0aGVyIGF0dGVtcHRzLiAqL1xuZXhwb3J0IGNvbnN0IEpXS1NfTkVHQVRJVkVfVFRMX01TID0gMTBfMDAwO1xuXG4vKiogTWluaW11bSBnYXAgYmV0d2VlbiB1bmtub3duLWBraWRgIHJlZmV0Y2hlcywgc28gZm9yZ2VkIGtpZHMgY2FuJ3Qgc3RhbXBlZGUgcGxhdGZvcm0uICovXG5leHBvcnQgY29uc3QgVU5LTk9XTl9LSURfUkVGRVRDSF9DT09MRE9XTl9NUyA9IDMwXzAwMDtcblxuLyoqIFRoZSBrZXkgc2V0IGNvdWxkIG5vdCBiZSBvYnRhaW5lZCDigJQgdGhlIHRva2VuJ3MgdmFsaWRpdHkgaXMgVU5LTk9XTiAoNTAzLXNoYXBlZCkuICovXG5leHBvcnQgY2xhc3MgSndrc1VuYXZhaWxhYmxlRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSAnVG9rZW4gc2lnbmluZyBrZXlzIGFyZSB0ZW1wb3JhcmlseSB1bmF2YWlsYWJsZScpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLm5hbWUgPSAnSndrc1VuYXZhaWxhYmxlRXJyb3InO1xuICB9XG59XG5cbi8qKiBUaGUga2V5IHNldCB3YXMgb2J0YWluZWQgYW5kIGRvZXMgTk9UIGNvbnRhaW4gdGhlIHRva2VuJ3MgYGtpZGAgKDQwMS1zaGFwZWQpLiAqL1xuZXhwb3J0IGNsYXNzIFVua25vd25LaWRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3Ioa2lkOiBzdHJpbmcpIHtcbiAgICBzdXBlcihgTm8gcHVibGlzaGVkIHNpZ25pbmcga2V5IGZvciBraWQgJHtraWR9YCk7XG4gICAgdGhpcy5uYW1lID0gJ1Vua25vd25LaWRFcnJvcic7XG4gIH1cbn1cblxuLyoqIEZldGNoZXMgdGhlIHJhdyBKV0tTIGRvY3VtZW50LiBSZWplY3RzIG9uIGFueSB0cmFuc3BvcnQvc2hhcGUgZmFpbHVyZS4gKi9cbmV4cG9ydCB0eXBlIEp3a3NGZXRjaGVyID0gKCkgPT4gUHJvbWlzZTxKd2tzRG9jdW1lbnQ+O1xuXG5leHBvcnQgaW50ZXJmYWNlIEp3a3NDYWNoZU9wdGlvbnMge1xuICBmZXRjaDogSndrc0ZldGNoZXI7XG4gIC8qKiBGb3IgbWV0cmljcy9sb2dnaW5nIChlLmcuIGAncGxhdGZvcm0nYCkuICovXG4gIHNvdXJjZT86IHN0cmluZztcbiAgcmVmcmVzaEludGVydmFsTXM/OiBudW1iZXI7XG4gIG5lZ2F0aXZlVHRsTXM/OiBudW1iZXI7XG4gIHVua25vd25LaWRDb29sZG93bk1zPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIEEga2V5IHNldCB3aXRoIHRoZSBmcmVzaG5lc3MgYm9va2tlZXBpbmcgdGhlIGNvbnRyYWN0IGFib3ZlIG5lZWRzLiBEZWxpYmVyYXRlbHlcbiAqIHRyYW5zcG9ydC1hZ25vc3RpYzogdGhlIENMSSBhbmQgdGhlIExhbWJkYSBoYW5kIGl0IHRoZWlyIG93biBmZXRjaGVyLlxuICovXG5leHBvcnQgY2xhc3MgSndrc0NhY2hlIHtcbiAgcHJpdmF0ZSBrZXlzID0gbmV3IE1hcDxzdHJpbmcsIEtleU9iamVjdD4oKTtcbiAgcHJpdmF0ZSBmZXRjaGVkQXQgPSAwO1xuICBwcml2YXRlIGZhaWxlZFVudGlsID0gMDtcbiAgcHJpdmF0ZSBsYXN0VW5rbm93bktpZEZldGNoQXQgPSAwO1xuICBwcml2YXRlIGluRmxpZ2h0OiBQcm9taXNlPHZvaWQ+IHwgdW5kZWZpbmVkO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgcmVmcmVzaEludGVydmFsTXM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBuZWdhdGl2ZVR0bE1zOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgdW5rbm93bktpZENvb2xkb3duTXM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBzb3VyY2U6IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM6IEp3a3NDYWNoZU9wdGlvbnMpIHtcbiAgICB0aGlzLnJlZnJlc2hJbnRlcnZhbE1zID0gb3B0aW9ucy5yZWZyZXNoSW50ZXJ2YWxNcyA/PyBKV0tTX1JFRlJFU0hfSU5URVJWQUxfTVM7XG4gICAgdGhpcy5uZWdhdGl2ZVR0bE1zID0gb3B0aW9ucy5uZWdhdGl2ZVR0bE1zID8/IEpXS1NfTkVHQVRJVkVfVFRMX01TO1xuICAgIHRoaXMudW5rbm93bktpZENvb2xkb3duTXMgPSBvcHRpb25zLnVua25vd25LaWRDb29sZG93bk1zID8/IFVOS05PV05fS0lEX1JFRkVUQ0hfQ09PTERPV05fTVM7XG4gICAgdGhpcy5zb3VyY2UgPSBvcHRpb25zLnNvdXJjZSA/PyAncGxhdGZvcm0nO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB2ZXJpZmljYXRpb24ga2V5IGZvciBga2lkYC5cbiAgICpcbiAgICogQHRocm93cyB7Sndrc1VuYXZhaWxhYmxlRXJyb3J9IHRoZSBrZXkgc2V0IGNvdWxkIG5vdCBiZSBvYnRhaW5lZCBhdCBhbGwuXG4gICAqIEB0aHJvd3Mge1Vua25vd25LaWRFcnJvcn0gdGhlIGtleSBzZXQgaXMgaW4gaGFuZCBidXQgaGFzIG5vIHN1Y2gga2V5LlxuICAgKi9cbiAgYXN5bmMgZ2V0S2V5KGtpZDogc3RyaW5nKTogUHJvbWlzZTxLZXlPYmplY3Q+IHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZUZyZXNoKCk7XG4gICAgY29uc3Qga2V5ID0gdGhpcy5rZXlzLmdldChraWQpO1xuICAgIGlmIChrZXkpIHJldHVybiBrZXk7XG5cbiAgICAvLyBVbmtub3duIGtpZDogcGxhdGZvcm0gbWF5IGhhdmUgSlVTVCByb3RhdGVkLiBSZWZldGNoIG9uY2UgKHJhdGUtbGltaXRlZCksXG4gICAgLy8gdGhlbiBkZWNpZGUuIEEgY2FjaGVkLWJ1dC1zdGFsZSBzZXQgdGhhdCBzdGlsbCBsYWNrcyB0aGUga2lkIGFmdGVyIHRoZVxuICAgIC8vIHJlZmV0Y2ggaXMgYSByZWFsIHJlamVjdGlvbiwgbm90IGEgZnJlc2huZXNzIHByb2JsZW0uXG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBpZiAobm93IC0gdGhpcy5sYXN0VW5rbm93bktpZEZldGNoQXQgPj0gdGhpcy51bmtub3duS2lkQ29vbGRvd25Ncykge1xuICAgICAgdGhpcy5sYXN0VW5rbm93bktpZEZldGNoQXQgPSBub3c7XG4gICAgICBlbWl0Q291bnRlcignandrc191bmtub3duX2tpZF9yZWZldGNoX3RvdGFsJywgeyBzb3VyY2U6IHRoaXMuc291cmNlIH0pO1xuICAgICAgYXdhaXQgdGhpcy5yZWZyZXNoKHsgZm9yY2U6IHRydWUgfSkuY2F0Y2goKCkgPT4geyAvKiBoYW5kbGVkIGJlbG93IGJ5IHRoZSBtaXNzICovIH0pO1xuICAgICAgY29uc3QgcmVmcmVzaGVkID0gdGhpcy5rZXlzLmdldChraWQpO1xuICAgICAgaWYgKHJlZnJlc2hlZCkgcmV0dXJuIHJlZnJlc2hlZDtcbiAgICB9XG4gICAgaWYgKHRoaXMua2V5cy5zaXplID09PSAwKSB0aHJvdyBuZXcgSndrc1VuYXZhaWxhYmxlRXJyb3IoKTtcbiAgICB0aHJvdyBuZXcgVW5rbm93bktpZEVycm9yKGtpZCk7XG4gIH1cblxuICAvKiogRXZlcnkgY3VycmVudGx5LXRydXN0ZWQgYGtpZGAuIEV4cG9zZWQgZm9yIGRpYWdub3N0aWNzIGFuZCB0ZXN0cy4gKi9cbiAga25vd25LaWRzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gWy4uLnRoaXMua2V5cy5rZXlzKCldO1xuICB9XG5cbiAgLyoqIERyb3AgZXZlcnl0aGluZywgc28gdGhlIG5leHQgbG9va3VwIHJlZmV0Y2hlcy4gKi9cbiAgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5rZXlzLmNsZWFyKCk7XG4gICAgdGhpcy5mZXRjaGVkQXQgPSAwO1xuICAgIHRoaXMuZmFpbGVkVW50aWwgPSAwO1xuICAgIHRoaXMubGFzdFVua25vd25LaWRGZXRjaEF0ID0gMDtcbiAgICB0aGlzLmluRmxpZ2h0ID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqIFJlZmV0Y2ggd2hlbiB0aGUgc2V0IGlzIG1pc3Npbmcgb3IgcGFzdCBpdHMgcmVmcmVzaCBpbnRlcnZhbC4gKi9cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVGcmVzaCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IHN0YWxlID0gbm93IC0gdGhpcy5mZXRjaGVkQXQgPj0gdGhpcy5yZWZyZXNoSW50ZXJ2YWxNcztcbiAgICBpZiAodGhpcy5rZXlzLnNpemUgPiAwICYmICFzdGFsZSkgcmV0dXJuO1xuXG4gICAgaWYgKG5vdyA8IHRoaXMuZmFpbGVkVW50aWwpIHtcbiAgICAgIC8vIEluc2lkZSB0aGUgbmVnYXRpdmUtY2FjaGUgd2luZG93LiBTZXJ2ZSBhIGtleSBzZXQgd2UgYWxyZWFkeSBob2xkXG4gICAgICAvLyAocHVibGljIGtleXMgZG9uJ3QgZXhwaXJlKTsgd2l0aCBub3RoaW5nIGluIGhhbmQsIGZhaWwgY2xvc2VkLlxuICAgICAgaWYgKHRoaXMua2V5cy5zaXplID4gMCkgcmV0dXJuO1xuICAgICAgdGhyb3cgbmV3IEp3a3NVbmF2YWlsYWJsZUVycm9yKCk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMucmVmcmVzaCh7IGZvcmNlOiBmYWxzZSB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKHRoaXMua2V5cy5zaXplID4gMCkge1xuICAgICAgICBsb2dnZXIud2FybignSldLUyByZWZyZXNoIGZhaWxlZDsgY29udGludWluZyBvbiB0aGUgY2FjaGVkIGtleSBzZXQnLCB7XG4gICAgICAgICAgc291cmNlOiB0aGlzLnNvdXJjZSxcbiAgICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEp3a3NVbmF2YWlsYWJsZUVycm9yKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIE9uZSByZWFsIGZldGNoLCBzaGFyZWQgYnkgZXZlcnkgY29uY3VycmVudCBjYWxsZXIuICovXG4gIHByaXZhdGUgcmVmcmVzaChvcHRzOiB7IGZvcmNlOiBib29sZWFuIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5pbkZsaWdodCkgcmV0dXJuIHRoaXMuaW5GbGlnaHQ7XG4gICAgaWYgKCFvcHRzLmZvcmNlICYmIERhdGUubm93KCkgPCB0aGlzLmZhaWxlZFVudGlsKSByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEp3a3NVbmF2YWlsYWJsZUVycm9yKCkpO1xuICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLnBlcmZvcm1GZXRjaCgpLmZpbmFsbHkoKCkgPT4geyB0aGlzLmluRmxpZ2h0ID0gdW5kZWZpbmVkOyB9KTtcbiAgICB0aGlzLmluRmxpZ2h0ID0gcHJvbWlzZTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcGVyZm9ybUZldGNoKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxldCBkb2N1bWVudDogSndrc0RvY3VtZW50O1xuICAgIHRyeSB7XG4gICAgICBkb2N1bWVudCA9IGF3YWl0IHRoaXMub3B0aW9ucy5mZXRjaCgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmZhaWxlZFVudGlsID0gRGF0ZS5ub3coKSArIHRoaXMubmVnYXRpdmVUdGxNcztcbiAgICAgIGVtaXRDb3VudGVyKCdqd2tzX2ZldGNoX3RvdGFsJywgeyBzb3VyY2U6IHRoaXMuc291cmNlLCByZXN1bHQ6ICdlcnJvcicgfSk7XG4gICAgICBsb2dnZXIud2FybignSldLUyBmZXRjaCBmYWlsZWQnLCB7XG4gICAgICAgIHNvdXJjZTogdGhpcy5zb3VyY2UsXG4gICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvciksXG4gICAgICB9KTtcbiAgICAgIHRocm93IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKTtcbiAgICB9XG5cbiAgICBjb25zdCBrZXlzID0gbmV3IE1hcDxzdHJpbmcsIEtleU9iamVjdD4oKTtcbiAgICBmb3IgKGNvbnN0IGp3ayBvZiBkb2N1bWVudC5rZXlzIGFzIFB1YmxpY0p3a1tdKSB7XG4gICAgICBpZiAoIWp3az8ua2lkKSBjb250aW51ZTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGtleXMuc2V0KGp3ay5raWQsIHB1YmxpY0tleUZyb21Kd2soandrKSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBPbmUgdW51c2FibGUgZW50cnkgbXVzdCBub3QgZGlzY2FyZCB0aGUgcmVzdCBvZiB0aGUgc2V0LlxuICAgICAgICBsb2dnZXIud2FybignU2tpcHBpbmcgdW51c2FibGUgSldLUyBlbnRyeScsIHsga2lkOiBqd2sua2lkLCBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoa2V5cy5zaXplID09PSAwKSB7XG4gICAgICB0aGlzLmZhaWxlZFVudGlsID0gRGF0ZS5ub3coKSArIHRoaXMubmVnYXRpdmVUdGxNcztcbiAgICAgIGVtaXRDb3VudGVyKCdqd2tzX2ZldGNoX3RvdGFsJywgeyBzb3VyY2U6IHRoaXMuc291cmNlLCByZXN1bHQ6ICdlbXB0eScgfSk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0pXS1MgZG9jdW1lbnQgY29udGFpbmVkIG5vIHVzYWJsZSBrZXlzJyk7XG4gICAgfVxuXG4gICAgdGhpcy5rZXlzID0ga2V5cztcbiAgICB0aGlzLmZldGNoZWRBdCA9IERhdGUubm93KCk7XG4gICAgdGhpcy5mYWlsZWRVbnRpbCA9IDA7XG4gICAgZW1pdENvdW50ZXIoJ2p3a3NfZmV0Y2hfdG90YWwnLCB7IHNvdXJjZTogdGhpcy5zb3VyY2UsIHJlc3VsdDogJ3N1Y2Nlc3MnIH0pO1xuICB9XG59XG5cbi8qKlxuICogRmV0Y2ggcGxhdGZvcm0ncyBKV0tTIG92ZXIgdGhlIGluLWNsdXN0ZXIgYWRkcmVzcyBldmVyeSBvdGhlciBjYWxsZXIgdXNlc1xuICogKGBQTEFURk9STV9TRVJWSUNFX0hPU1RgIC8gYFBMQVRGT1JNX1NFUlZJQ0VfUE9SVGApLCBvciB0aGUgYWJzb2x1dGVcbiAqIGBQTEFURk9STV9KV0tTX1VSTGAgd2hlbiBvbmUgaXMgY29uZmlndXJlZCAodGhlIENMSSBhbmQgdGhlIGV2ZW50cyBMYW1iZGEgcnVuXG4gKiBvdXRzaWRlIHRoZSBjbHVzdGVyKS5cbiAqXG4gKiBVbmF1dGhlbnRpY2F0ZWQgYnkgZGVzaWduOiB0aGUga2V5IHNldCBpcyBwdWJsaWMsIGFuZCByZXF1aXJpbmcgYSBjcmVkZW50aWFsXG4gKiB0byBmZXRjaCB0aGUga2V5cyB0aGF0IHZlcmlmeSBjcmVkZW50aWFscyBpcyBhIGJvb3RzdHJhcCBjeWNsZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZldGNoUGxhdGZvcm1Kd2tzKCk6IFByb21pc2U8Sndrc0RvY3VtZW50PiB7XG4gIGNvbnN0IGFic29sdXRlID0gcHJvY2Vzcy5lbnYuUExBVEZPUk1fSldLU19VUkw7XG4gIGNvbnN0IHRpbWVvdXQgPSBwYXJzZUludChwcm9jZXNzLmVudi5KV0tTX0ZFVENIX1RJTUVPVVRfTVMgfHwgJzMwMDAnLCAxMCk7XG4gIGlmIChhYnNvbHV0ZSkgcmV0dXJuIGZldGNoSndrc0Zyb21VcmwoYWJzb2x1dGUsIHRpbWVvdXQpO1xuXG4gIC8vIExvYWRlZCBMQVpJTFksIG9uIHRoZSBmaXJzdCBmZXRjaC4gQSBzdGF0aWMgaW1wb3J0IHdvdWxkIHB1dCB0aGUgSFRUUCBjbGllbnRcbiAgLy8gKGFuZCBwbGF0Zm9ybSdzIGFkZHJlc3MpIGludG8gdGhlIGltcG9ydCBncmFwaCBvZiBldmVyeSBtb2R1bGUgdGhhdCBtZXJlbHlcbiAgLy8gdXNlcyBgcmVxdWlyZUF1dGhgIOKAlCB0aGUgc2FtZSByZWFzb24gYGFwaS1rZXktZXhjaGFuZ2VgIGlzIGxhenksIGFuZCB3aGF0XG4gIC8vIGtlZXBzIHBhcnRpYWwgYGh0dHAtY2xpZW50LmpzYCBtb2NrcyBpbiB0aGUgc2VydmljZSBzdWl0ZXMgd29ya2luZy5cbiAgY29uc3QgeyBJbnRlcm5hbEh0dHBDbGllbnQgfSA9IGF3YWl0IGltcG9ydCgnLi9odHRwLWNsaWVudC5qcycpO1xuICBjb25zdCBjbGllbnQgPSBuZXcgSW50ZXJuYWxIdHRwQ2xpZW50KHtcbiAgICBob3N0OiBwcm9jZXNzLmVudi5QTEFURk9STV9TRVJWSUNFX0hPU1QgfHwgJ3BsYXRmb3JtJyxcbiAgICBwb3J0OiBwYXJzZUludChwcm9jZXNzLmVudi5QTEFURk9STV9TRVJWSUNFX1BPUlQgfHwgJzMwMDAnLCAxMCksXG4gICAgdGltZW91dCxcbiAgfSk7XG4gIGNvbnN0IHJlcyA9IGF3YWl0IGNsaWVudC5nZXQ8dW5rbm93bj4oSldLU19QQVRILCB7IGlkZW1wb3RlbnQ6IHRydWUgfSk7XG4gIGlmIChyZXMuc3RhdHVzQ29kZSAhPT0gMjAwIHx8ICFpc0p3a3NEb2N1bWVudChyZXMuYm9keSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgSldLUyByZXNwb25zZSAoc3RhdHVzICR7cmVzLnN0YXR1c0NvZGV9KWApO1xuICB9XG4gIHJldHVybiByZXMuYm9keTtcbn1cblxuLyoqIEZldGNoIGEgSldLUyBkb2N1bWVudCBmcm9tIGFuIGFic29sdXRlIFVSTCAob3V0c2lkZS10aGUtY2x1c3RlciB2ZXJpZmllcnMpLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZldGNoSndrc0Zyb21VcmwodXJsOiBzdHJpbmcsIHRpbWVvdXRNcyA9IDMwMDApOiBQcm9taXNlPEp3a3NEb2N1bWVudD4ge1xuICBjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4gY29udHJvbGxlci5hYm9ydCgpLCB0aW1lb3V0TXMpO1xuICB0cnkge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKHVybCwgeyBzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsLCBoZWFkZXJzOiB7IGFjY2VwdDogJ2FwcGxpY2F0aW9uL2pzb24nIH0gfSk7XG4gICAgaWYgKCFyZXMub2spIHRocm93IG5ldyBFcnJvcihgSldLUyBmZXRjaCByZXR1cm5lZCAke3Jlcy5zdGF0dXN9YCk7XG4gICAgY29uc3QgYm9keTogdW5rbm93biA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgaWYgKCFpc0p3a3NEb2N1bWVudChib2R5KSkgdGhyb3cgbmV3IEVycm9yKCdKV0tTIHJlc3BvbnNlIHdhcyBub3QgYSBrZXkgc2V0Jyk7XG4gICAgcmV0dXJuIGJvZHk7XG4gIH0gZmluYWxseSB7XG4gICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgfVxufVxuXG5sZXQgcGxhdGZvcm1Kd2tzOiBKd2tzQ2FjaGUgfCB1bmRlZmluZWQ7XG5cbi8qKiBUaGUgcHJvY2Vzcy13aWRlIGNhY2hlIG9mIHBsYXRmb3JtJ3MgcHVibGlzaGVkIHNpZ25pbmcga2V5cy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwbGF0Zm9ybUp3a3NDYWNoZSgpOiBKd2tzQ2FjaGUge1xuICBwbGF0Zm9ybUp3a3MgPz89IG5ldyBKd2tzQ2FjaGUoeyBmZXRjaDogZmV0Y2hQbGF0Zm9ybUp3a3MsIHNvdXJjZTogJ3BsYXRmb3JtJyB9KTtcbiAgcmV0dXJuIHBsYXRmb3JtSndrcztcbn1cblxuLyoqXG4gKiBSZXBsYWNlIHRoZSBwcm9jZXNzLXdpZGUgY2FjaGUg4oCUIHVzZWQgYnkgdGVzdHMsIGFuZCBieSBhbnkgaG9zdCB0aGF0IG11c3RcbiAqIHN1cHBseSBpdHMgb3duIGZldGNoZXIuIFBhc3MgYHVuZGVmaW5lZGAgdG8gZHJvcCBiYWNrIHRvIHRoZSBkZWZhdWx0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0UGxhdGZvcm1Kd2tzQ2FjaGUoY2FjaGU6IEp3a3NDYWNoZSB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICBwbGF0Zm9ybUp3a3MgPSBjYWNoZTtcbn1cbiJdfQ==
223
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiandrcy1jYWNoZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9qd2tzLWNhY2hlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUE0QnRDLE9BQU8sRUFDTCxTQUFTLEVBQ1QsY0FBYyxFQUNkLGdCQUFnQixHQUdqQixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDekQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRXBELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUUxQyxvRUFBb0U7QUFDcEUsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUcsT0FBTyxDQUFDLENBQUMsYUFBYTtBQUU5RCw0REFBNEQ7QUFDNUQsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsTUFBTSxDQUFDO0FBRTNDLDJGQUEyRjtBQUMzRixNQUFNLENBQUMsTUFBTSwrQkFBK0IsR0FBRyxNQUFNLENBQUM7QUFFdEQsd0ZBQXdGO0FBQ3hGLE1BQU0sT0FBTyxvQkFBcUIsU0FBUSxLQUFLO0lBQzdDLFlBQVksT0FBTyxHQUFHLGdEQUFnRDtRQUNwRSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDZixJQUFJLENBQUMsSUFBSSxHQUFHLHNCQUFzQixDQUFDO0lBQ3JDLENBQUM7Q0FDRjtBQUVELG9GQUFvRjtBQUNwRixNQUFNLE9BQU8sZUFBZ0IsU0FBUSxLQUFLO0lBQ3hDLFlBQVksR0FBVztRQUNyQixLQUFLLENBQUMsb0NBQW9DLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLElBQUksR0FBRyxpQkFBaUIsQ0FBQztJQUNoQyxDQUFDO0NBQ0Y7QUFjRDs7O0dBR0c7QUFDSCxN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LEVBQUUsTUFBTSxFQUFFLGtCQUFrQixFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3JHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsdUJBQXVCLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ2xFLE1BQU0sSUFBSSxHQUFZLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1FBQzlFLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztZQUFTLENBQUM7UUFDVCxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdEIsQ0FBQztBQUNILENBQUM7QUFFRCxJQUFJLFlBQW1DLENBQUM7QUFFeEMsbUVBQW1FO0FBQ25FLE1BQU0sVUFBVSxpQkFBaUI7SUFDL0IsWUFBWSxLQUFLLElBQUksU0FBUyxDQUFDLEVBQUUsS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDO0lBQ2pGLE9BQU8sWUFBWSxDQUFDO0FBQ3RCLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsb0JBQW9CLENBQUMsS0FBNEI7SUFDL0QsWUFBWSxHQUFHLEtBQUssQ0FBQztBQUN2QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogVGhlIEpXS1MgY2FjaGUgZXZlcnkgdmVyaWZpZXIgaW4gdGhlIGZsZWV0IHNoYXJlcy5cbiAqXG4gKiBQbGF0Zm9ybSBzaWducyB1c2VyIHRva2VucyB3aXRoIEVTMjU2IGFuZCBwdWJsaXNoZXMgdGhlIHB1YmxpYyBoYWx2ZXMgYXRcbiAqIGAvLndlbGwta25vd24vandrcy5qc29uYC4gVmVyaWZpZXJzIG11c3Qgbm90IGZldGNoIHRoYXQgcGVyIHJlcXVlc3QgKHBsYXRmb3JtXG4gKiB3b3VsZCBsYW5kIG9uIHRoZSBob3QgcGF0aCBvZiB0aGUgd2hvbGUgZmxlZXQpIG5vciBjYWNoZSBpdCBmb3JldmVyIChhIHJvdGF0ZWRcbiAqIGtleSB3b3VsZCBuZXZlciBiZSBwaWNrZWQgdXApLCBzbyB0aGUgY29udHJhY3QgaXMgZml4ZWQgaGVyZSBhbmQgcmV1c2VkIGJ5XG4gKiBhcGktY29yZSdzIGByZXF1aXJlQXV0aGAsIGltYWdlLXJlZ2lzdHJ5J3MgYXV0aCByZXNvbHZlciBhbmQgdGhlIENMSTpcbiAqXG4gKiAtICoqUmVmcmVzaCBldmVyeSAxMCBtaW51dGVzLioqIEEga2V5IHJvdGF0ZWQgaW4gYXQgcGxhdGZvcm0gaXMgdHJ1c3RlZCBmbGVldC1cbiAqICAgd2lkZSB3aXRoaW4gdGhhdCB3aW5kb3cgd2l0aG91dCBhbnlvbmUgcmVzdGFydGluZy5cbiAqIC0gKipSZWZldGNoIG9uY2Ugb24gYW4gdW5rbm93biBga2lkYC4qKiBBIGJyYW5kLW5ldyBzaWduaW5nIGtleSBpcyBwaWNrZWQgdXBcbiAqICAgaW1tZWRpYXRlbHkgaW5zdGVhZCBvZiA0MDEtaW5nIGV2ZXJ5IHJlcXVlc3QgdW50aWwgdGhlIG5leHQgcmVmcmVzaC4gUmF0ZS1cbiAqICAgbGltaXRlZCAoe0BsaW5rIFVOS05PV05fS0lEX1JFRkVUQ0hfQ09PTERPV05fTVN9KSBzbyBhIGZsb29kIG9mIGZvcmdlZCBga2lkYHNcbiAqICAgY2FuJ3QgdHVybiBpbnRvIGEgZmV0Y2ggc3Rvcm0gYWdhaW5zdCBwbGF0Zm9ybS5cbiAqIC0gKipOZWdhdGl2ZS1jYWNoZSBmYWlsdXJlcyBicmllZmx5LioqIEEgcGxhdGZvcm0gb3V0YWdlIGRvZXNuJ3QgYmVjb21lIGFcbiAqICAgZmV0Y2gtcGVyLXJlcXVlc3QgYW1wbGlmaWVyLlxuICogLSAqKkZhaWwgY2xvc2VkLioqIEFuIHVudmVyaWZpYWJsZSB0b2tlbiBpcyBub3QgYW4gaWRlbnRpdHk6IHdoZW4gdGhlIGtleSBzZXRcbiAqICAgY2Fubm90IGJlIG9idGFpbmVkIHRoZSB2ZXJpZmllciB0aHJvd3Mge0BsaW5rIEp3a3NVbmF2YWlsYWJsZUVycm9yfSBhbmQgdGhlXG4gKiAgIGNhbGxlciBhbnN3ZXJzIDQwMS81MDMg4oCUIGl0IE5FVkVSIGZhbGxzIHRocm91Z2ggdG8gXCJhbGxvd1wiLlxuICogICBBIGtleSBzZXQgYWxyZWFkeSBpbiBoYW5kIGlzIHN0aWxsIHVzZWQgd2hpbGUgYSByZWZyZXNoIGlzIGZhaWxpbmcgKHRoZSBrZXlzXG4gKiAgIGFyZSBwdWJsaWMgYW5kIGRvbid0IGV4cGlyZTsgcmVmdXNpbmcgZXZlcnkgcmVxdWVzdCBiZWNhdXNlIHBsYXRmb3JtIGJsaXBwZWRcbiAqICAgd291bGQgYmUgYSBzZWxmLWluZmxpY3RlZCBvdXRhZ2UpLCB3aGljaCBpcyB3aHkgdGhlIG5lZ2F0aXZlIGNhY2hlIGV4aXN0cy5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEtleU9iamVjdCB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQge1xuICBKV0tTX1BBVEgsXG4gIGlzSndrc0RvY3VtZW50LFxuICBwdWJsaWNLZXlGcm9tSndrLFxuICB0eXBlIEp3a3NEb2N1bWVudCxcbiAgdHlwZSBQdWJsaWNKd2ssXG59IGZyb20gJy4uL3V0aWxzL2p3ay5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZW1pdENvdW50ZXIgfSBmcm9tICcuLi91dGlscy9tZXRyaWMtZW1pdHRlci5qcyc7XG5pbXBvcnQgeyBlcnJvck1lc3NhZ2UgfSBmcm9tICcuLi91dGlscy9yZXNwb25zZS5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcignandrcy1jYWNoZScpO1xuXG4vKiogSG93IGxvbmcgYSBmZXRjaGVkIGtleSBzZXQgaXMgc2VydmVkIGJlZm9yZSBhIHJlZnJlc2ggaXMgZHVlLiAqL1xuZXhwb3J0IGNvbnN0IEpXS1NfUkVGUkVTSF9JTlRFUlZBTF9NUyA9IDYwMF8wMDA7IC8vIDEwIG1pbnV0ZXNcblxuLyoqIEhvdyBsb25nIGEgZmV0Y2ggRkFJTFVSRSBzdXBwcmVzc2VzIGZ1cnRoZXIgYXR0ZW1wdHMuICovXG5leHBvcnQgY29uc3QgSldLU19ORUdBVElWRV9UVExfTVMgPSAxMF8wMDA7XG5cbi8qKiBNaW5pbXVtIGdhcCBiZXR3ZWVuIHVua25vd24tYGtpZGAgcmVmZXRjaGVzLCBzbyBmb3JnZWQga2lkcyBjYW4ndCBzdGFtcGVkZSBwbGF0Zm9ybS4gKi9cbmV4cG9ydCBjb25zdCBVTktOT1dOX0tJRF9SRUZFVENIX0NPT0xET1dOX01TID0gMzBfMDAwO1xuXG4vKiogVGhlIGtleSBzZXQgY291bGQgbm90IGJlIG9idGFpbmVkIOKAlCB0aGUgdG9rZW4ncyB2YWxpZGl0eSBpcyBVTktOT1dOICg1MDMtc2hhcGVkKS4gKi9cbmV4cG9ydCBjbGFzcyBKd2tzVW5hdmFpbGFibGVFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZSA9ICdUb2tlbiBzaWduaW5nIGtleXMgYXJlIHRlbXBvcmFyaWx5IHVuYXZhaWxhYmxlJykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9ICdKd2tzVW5hdmFpbGFibGVFcnJvcic7XG4gIH1cbn1cblxuLyoqIFRoZSBrZXkgc2V0IHdhcyBvYnRhaW5lZCBhbmQgZG9lcyBOT1QgY29udGFpbiB0aGUgdG9rZW4ncyBga2lkYCAoNDAxLXNoYXBlZCkuICovXG5leHBvcnQgY2xhc3MgVW5rbm93bktpZEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihraWQ6IHN0cmluZykge1xuICAgIHN1cGVyKGBObyBwdWJsaXNoZWQgc2lnbmluZyBrZXkgZm9yIGtpZCAke2tpZH1gKTtcbiAgICB0aGlzLm5hbWUgPSAnVW5rbm93bktpZEVycm9yJztcbiAgfVxufVxuXG4vKiogRmV0Y2hlcyB0aGUgcmF3IEpXS1MgZG9jdW1lbnQuIFJlamVjdHMgb24gYW55IHRyYW5zcG9ydC9zaGFwZSBmYWlsdXJlLiAqL1xuZXhwb3J0IHR5cGUgSndrc0ZldGNoZXIgPSAoKSA9PiBQcm9taXNlPEp3a3NEb2N1bWVudD47XG5cbmV4cG9ydCBpbnRlcmZhY2UgSndrc0NhY2hlT3B0aW9ucyB7XG4gIGZldGNoOiBKd2tzRmV0Y2hlcjtcbiAgLyoqIEZvciBtZXRyaWNzL2xvZ2dpbmcgKGUuZy4gYCdwbGF0Zm9ybSdgKS4gKi9cbiAgc291cmNlPzogc3RyaW5nO1xuICByZWZyZXNoSW50ZXJ2YWxNcz86IG51bWJlcjtcbiAgbmVnYXRpdmVUdGxNcz86IG51bWJlcjtcbiAgdW5rbm93bktpZENvb2xkb3duTXM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogQSBrZXkgc2V0IHdpdGggdGhlIGZyZXNobmVzcyBib29ra2VlcGluZyB0aGUgY29udHJhY3QgYWJvdmUgbmVlZHMuIERlbGliZXJhdGVseVxuICogdHJhbnNwb3J0LWFnbm9zdGljOiB0aGUgQ0xJIGFuZCB0aGUgTGFtYmRhIGhhbmQgaXQgdGhlaXIgb3duIGZldGNoZXIuXG4gKi9cbmV4cG9ydCBjbGFzcyBKd2tzQ2FjaGUge1xuICBwcml2YXRlIGtleXMgPSBuZXcgTWFwPHN0cmluZywgS2V5T2JqZWN0PigpO1xuICBwcml2YXRlIGZldGNoZWRBdCA9IDA7XG4gIHByaXZhdGUgZmFpbGVkVW50aWwgPSAwO1xuICBwcml2YXRlIGxhc3RVbmtub3duS2lkRmV0Y2hBdCA9IDA7XG4gIHByaXZhdGUgaW5GbGlnaHQ6IFByb21pc2U8dm9pZD4gfCB1bmRlZmluZWQ7XG5cbiAgcHJpdmF0ZSByZWFkb25seSByZWZyZXNoSW50ZXJ2YWxNczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IG5lZ2F0aXZlVHRsTXM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSB1bmtub3duS2lkQ29vbGRvd25NczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHNvdXJjZTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogSndrc0NhY2hlT3B0aW9ucykge1xuICAgIHRoaXMucmVmcmVzaEludGVydmFsTXMgPSBvcHRpb25zLnJlZnJlc2hJbnRlcnZhbE1zID8/IEpXS1NfUkVGUkVTSF9JTlRFUlZBTF9NUztcbiAgICB0aGlzLm5lZ2F0aXZlVHRsTXMgPSBvcHRpb25zLm5lZ2F0aXZlVHRsTXMgPz8gSldLU19ORUdBVElWRV9UVExfTVM7XG4gICAgdGhpcy51bmtub3duS2lkQ29vbGRvd25NcyA9IG9wdGlvbnMudW5rbm93bktpZENvb2xkb3duTXMgPz8gVU5LTk9XTl9LSURfUkVGRVRDSF9DT09MRE9XTl9NUztcbiAgICB0aGlzLnNvdXJjZSA9IG9wdGlvbnMuc291cmNlID8/ICdwbGF0Zm9ybSc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHZlcmlmaWNhdGlvbiBrZXkgZm9yIGBraWRgLlxuICAgKlxuICAgKiBAdGhyb3dzIHtKd2tzVW5hdmFpbGFibGVFcnJvcn0gdGhlIGtleSBzZXQgY291bGQgbm90IGJlIG9idGFpbmVkIGF0IGFsbC5cbiAgICogQHRocm93cyB7VW5rbm93bktpZEVycm9yfSB0aGUga2V5IHNldCBpcyBpbiBoYW5kIGJ1dCBoYXMgbm8gc3VjaCBrZXkuXG4gICAqL1xuICBhc3luYyBnZXRLZXkoa2lkOiBzdHJpbmcpOiBQcm9taXNlPEtleU9iamVjdD4ge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlRnJlc2goKTtcbiAgICBjb25zdCBrZXkgPSB0aGlzLmtleXMuZ2V0KGtpZCk7XG4gICAgaWYgKGtleSkgcmV0dXJuIGtleTtcblxuICAgIC8vIFVua25vd24ga2lkOiBwbGF0Zm9ybSBtYXkgaGF2ZSBKVVNUIHJvdGF0ZWQuIFJlZmV0Y2ggb25jZSAocmF0ZS1saW1pdGVkKSxcbiAgICAvLyB0aGVuIGRlY2lkZS4gQSBjYWNoZWQtYnV0LXN0YWxlIHNldCB0aGF0IHN0aWxsIGxhY2tzIHRoZSBraWQgYWZ0ZXIgdGhlXG4gICAgLy8gcmVmZXRjaCBpcyBhIHJlYWwgcmVqZWN0aW9uLCBub3QgYSBmcmVzaG5lc3MgcHJvYmxlbS5cbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGlmIChub3cgLSB0aGlzLmxhc3RVbmtub3duS2lkRmV0Y2hBdCA+PSB0aGlzLnVua25vd25LaWRDb29sZG93bk1zKSB7XG4gICAgICB0aGlzLmxhc3RVbmtub3duS2lkRmV0Y2hBdCA9IG5vdztcbiAgICAgIGVtaXRDb3VudGVyKCdqd2tzX3Vua25vd25fa2lkX3JlZmV0Y2hfdG90YWwnLCB7IHNvdXJjZTogdGhpcy5zb3VyY2UgfSk7XG4gICAgICBhd2FpdCB0aGlzLnJlZnJlc2goeyBmb3JjZTogdHJ1ZSB9KS5jYXRjaCgoKSA9PiB7IC8qIGhhbmRsZWQgYmVsb3cgYnkgdGhlIG1pc3MgKi8gfSk7XG4gICAgICBjb25zdCByZWZyZXNoZWQgPSB0aGlzLmtleXMuZ2V0KGtpZCk7XG4gICAgICBpZiAocmVmcmVzaGVkKSByZXR1cm4gcmVmcmVzaGVkO1xuICAgIH1cbiAgICBpZiAodGhpcy5rZXlzLnNpemUgPT09IDApIHRocm93IG5ldyBKd2tzVW5hdmFpbGFibGVFcnJvcigpO1xuICAgIHRocm93IG5ldyBVbmtub3duS2lkRXJyb3Ioa2lkKTtcbiAgfVxuXG4gIC8qKiBFdmVyeSBjdXJyZW50bHktdHJ1c3RlZCBga2lkYC4gRXhwb3NlZCBmb3IgZGlhZ25vc3RpY3MgYW5kIHRlc3RzLiAqL1xuICBrbm93bktpZHMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBbLi4udGhpcy5rZXlzLmtleXMoKV07XG4gIH1cblxuICAvKiogRHJvcCBldmVyeXRoaW5nLCBzbyB0aGUgbmV4dCBsb29rdXAgcmVmZXRjaGVzLiAqL1xuICByZXNldCgpOiB2b2lkIHtcbiAgICB0aGlzLmtleXMuY2xlYXIoKTtcbiAgICB0aGlzLmZldGNoZWRBdCA9IDA7XG4gICAgdGhpcy5mYWlsZWRVbnRpbCA9IDA7XG4gICAgdGhpcy5sYXN0VW5rbm93bktpZEZldGNoQXQgPSAwO1xuICAgIHRoaXMuaW5GbGlnaHQgPSB1bmRlZmluZWQ7XG4gIH1cblxuICAvKiogUmVmZXRjaCB3aGVuIHRoZSBzZXQgaXMgbWlzc2luZyBvciBwYXN0IGl0cyByZWZyZXNoIGludGVydmFsLiAqL1xuICBwcml2YXRlIGFzeW5jIGVuc3VyZUZyZXNoKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgY29uc3Qgc3RhbGUgPSBub3cgLSB0aGlzLmZldGNoZWRBdCA+PSB0aGlzLnJlZnJlc2hJbnRlcnZhbE1zO1xuICAgIGlmICh0aGlzLmtleXMuc2l6ZSA+IDAgJiYgIXN0YWxlKSByZXR1cm47XG5cbiAgICBpZiAobm93IDwgdGhpcy5mYWlsZWRVbnRpbCkge1xuICAgICAgLy8gSW5zaWRlIHRoZSBuZWdhdGl2ZS1jYWNoZSB3aW5kb3cuIFNlcnZlIGEga2V5IHNldCB3ZSBhbHJlYWR5IGhvbGRcbiAgICAgIC8vIChwdWJsaWMga2V5cyBkb24ndCBleHBpcmUpOyB3aXRoIG5vdGhpbmcgaW4gaGFuZCwgZmFpbCBjbG9zZWQuXG4gICAgICBpZiAodGhpcy5rZXlzLnNpemUgPiAwKSByZXR1cm47XG4gICAgICB0aHJvdyBuZXcgSndrc1VuYXZhaWxhYmxlRXJyb3IoKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5yZWZyZXNoKHsgZm9yY2U6IGZhbHNlIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAodGhpcy5rZXlzLnNpemUgPiAwKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdKV0tTIHJlZnJlc2ggZmFpbGVkOyBjb250aW51aW5nIG9uIHRoZSBjYWNoZWQga2V5IHNldCcsIHtcbiAgICAgICAgICBzb3VyY2U6IHRoaXMuc291cmNlLFxuICAgICAgICAgIGVycm9yOiBlcnJvck1lc3NhZ2UoZXJyb3IpLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEp3a3NVbmF2YWlsYWJsZUVycm9yKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIE9uZSByZWFsIGZldGNoLCBzaGFyZWQgYnkgZXZlcnkgY29uY3VycmVudCBjYWxsZXIuICovXG4gIHByaXZhdGUgcmVmcmVzaChvcHRzOiB7IGZvcmNlOiBib29sZWFuIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5pbkZsaWdodCkgcmV0dXJuIHRoaXMuaW5GbGlnaHQ7XG4gICAgaWYgKCFvcHRzLmZvcmNlICYmIERhdGUubm93KCkgPCB0aGlzLmZhaWxlZFVudGlsKSByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEp3a3NVbmF2YWlsYWJsZUVycm9yKCkpO1xuICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLnBlcmZvcm1GZXRjaCgpLmZpbmFsbHkoKCkgPT4geyB0aGlzLmluRmxpZ2h0ID0gdW5kZWZpbmVkOyB9KTtcbiAgICB0aGlzLmluRmxpZ2h0ID0gcHJvbWlzZTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcGVyZm9ybUZldGNoKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxldCBkb2N1bWVudDogSndrc0RvY3VtZW50O1xuICAgIHRyeSB7XG4gICAgICBkb2N1bWVudCA9IGF3YWl0IHRoaXMub3B0aW9ucy5mZXRjaCgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmZhaWxlZFVudGlsID0gRGF0ZS5ub3coKSArIHRoaXMubmVnYXRpdmVUdGxNcztcbiAgICAgIGVtaXRDb3VudGVyKCdqd2tzX2ZldGNoX3RvdGFsJywgeyBzb3VyY2U6IHRoaXMuc291cmNlLCByZXN1bHQ6ICdlcnJvcicgfSk7XG4gICAgICBsb2dnZXIud2FybignSldLUyBmZXRjaCBmYWlsZWQnLCB7XG4gICAgICAgIHNvdXJjZTogdGhpcy5zb3VyY2UsXG4gICAgICAgIGVycm9yOiBlcnJvck1lc3NhZ2UoZXJyb3IpLFxuICAgICAgfSk7XG4gICAgICB0aHJvdyBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSk7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5cyA9IG5ldyBNYXA8c3RyaW5nLCBLZXlPYmplY3Q+KCk7XG4gICAgZm9yIChjb25zdCBqd2sgb2YgZG9jdW1lbnQua2V5cyBhcyBQdWJsaWNKd2tbXSkge1xuICAgICAgaWYgKCFqd2s/LmtpZCkgY29udGludWU7XG4gICAgICB0cnkge1xuICAgICAgICBrZXlzLnNldChqd2sua2lkLCBwdWJsaWNLZXlGcm9tSndrKGp3aykpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gT25lIHVudXNhYmxlIGVudHJ5IG11c3Qgbm90IGRpc2NhcmQgdGhlIHJlc3Qgb2YgdGhlIHNldC5cbiAgICAgICAgbG9nZ2VyLndhcm4oJ1NraXBwaW5nIHVudXNhYmxlIEpXS1MgZW50cnknLCB7IGtpZDogandrLmtpZCwgZXJyb3I6IGVycm9yTWVzc2FnZShlcnJvcikgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChrZXlzLnNpemUgPT09IDApIHtcbiAgICAgIHRoaXMuZmFpbGVkVW50aWwgPSBEYXRlLm5vdygpICsgdGhpcy5uZWdhdGl2ZVR0bE1zO1xuICAgICAgZW1pdENvdW50ZXIoJ2p3a3NfZmV0Y2hfdG90YWwnLCB7IHNvdXJjZTogdGhpcy5zb3VyY2UsIHJlc3VsdDogJ2VtcHR5JyB9KTtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSldLUyBkb2N1bWVudCBjb250YWluZWQgbm8gdXNhYmxlIGtleXMnKTtcbiAgICB9XG5cbiAgICB0aGlzLmtleXMgPSBrZXlzO1xuICAgIHRoaXMuZmV0Y2hlZEF0ID0gRGF0ZS5ub3coKTtcbiAgICB0aGlzLmZhaWxlZFVudGlsID0gMDtcbiAgICBlbWl0Q291bnRlcignandrc19mZXRjaF90b3RhbCcsIHsgc291cmNlOiB0aGlzLnNvdXJjZSwgcmVzdWx0OiAnc3VjY2VzcycgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBGZXRjaCBwbGF0Zm9ybSdzIEpXS1Mgb3ZlciB0aGUgaW4tY2x1c3RlciBhZGRyZXNzIGV2ZXJ5IG90aGVyIGNhbGxlciB1c2VzXG4gKiAoYFBMQVRGT1JNX1NFUlZJQ0VfSE9TVGAgLyBgUExBVEZPUk1fU0VSVklDRV9QT1JUYCksIG9yIHRoZSBhYnNvbHV0ZVxuICogYFBMQVRGT1JNX0pXS1NfVVJMYCB3aGVuIG9uZSBpcyBjb25maWd1cmVkICh0aGUgQ0xJIGFuZCB0aGUgZXZlbnRzIExhbWJkYSBydW5cbiAqIG91dHNpZGUgdGhlIGNsdXN0ZXIpLlxuICpcbiAqIFVuYXV0aGVudGljYXRlZCBieSBkZXNpZ246IHRoZSBrZXkgc2V0IGlzIHB1YmxpYywgYW5kIHJlcXVpcmluZyBhIGNyZWRlbnRpYWxcbiAqIHRvIGZldGNoIHRoZSBrZXlzIHRoYXQgdmVyaWZ5IGNyZWRlbnRpYWxzIGlzIGEgYm9vdHN0cmFwIGN5Y2xlLlxuICovXG5hc3luYyBmdW5jdGlvbiBmZXRjaFBsYXRmb3JtSndrcygpOiBQcm9taXNlPEp3a3NEb2N1bWVudD4ge1xuICBjb25zdCBhYnNvbHV0ZSA9IHByb2Nlc3MuZW52LlBMQVRGT1JNX0pXS1NfVVJMO1xuICBjb25zdCB0aW1lb3V0ID0gcGFyc2VJbnQocHJvY2Vzcy5lbnYuSldLU19GRVRDSF9USU1FT1VUX01TIHx8ICczMDAwJywgMTApO1xuICBpZiAoYWJzb2x1dGUpIHJldHVybiBmZXRjaEp3a3NGcm9tVXJsKGFic29sdXRlLCB0aW1lb3V0KTtcblxuICAvLyBMb2FkZWQgTEFaSUxZLCBvbiB0aGUgZmlyc3QgZmV0Y2guIEEgc3RhdGljIGltcG9ydCB3b3VsZCBwdXQgdGhlIEhUVFAgY2xpZW50XG4gIC8vIChhbmQgcGxhdGZvcm0ncyBhZGRyZXNzKSBpbnRvIHRoZSBpbXBvcnQgZ3JhcGggb2YgZXZlcnkgbW9kdWxlIHRoYXQgbWVyZWx5XG4gIC8vIHVzZXMgYHJlcXVpcmVBdXRoYCDigJQgdGhlIHNhbWUgcmVhc29uIGBhcGkta2V5LWV4Y2hhbmdlYCBpcyBsYXp5LCBhbmQgd2hhdFxuICAvLyBrZWVwcyBwYXJ0aWFsIGBodHRwLWNsaWVudC5qc2AgbW9ja3MgaW4gdGhlIHNlcnZpY2Ugc3VpdGVzIHdvcmtpbmcuXG4gIGNvbnN0IHsgSW50ZXJuYWxIdHRwQ2xpZW50IH0gPSBhd2FpdCBpbXBvcnQoJy4vaHR0cC1jbGllbnQuanMnKTtcbiAgY29uc3QgY2xpZW50ID0gbmV3IEludGVybmFsSHR0cENsaWVudCh7XG4gICAgaG9zdDogcHJvY2Vzcy5lbnYuUExBVEZPUk1fU0VSVklDRV9IT1NUIHx8ICdwbGF0Zm9ybScsXG4gICAgcG9ydDogcGFyc2VJbnQocHJvY2Vzcy5lbnYuUExBVEZPUk1fU0VSVklDRV9QT1JUIHx8ICczMDAwJywgMTApLFxuICAgIHRpbWVvdXQsXG4gIH0pO1xuICBjb25zdCByZXMgPSBhd2FpdCBjbGllbnQuZ2V0PHVua25vd24+KEpXS1NfUEFUSCwgeyBpZGVtcG90ZW50OiB0cnVlIH0pO1xuICBpZiAocmVzLnN0YXR1c0NvZGUgIT09IDIwMCB8fCAhaXNKd2tzRG9jdW1lbnQocmVzLmJvZHkpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbmV4cGVjdGVkIEpXS1MgcmVzcG9uc2UgKHN0YXR1cyAke3Jlcy5zdGF0dXNDb2RlfSlgKTtcbiAgfVxuICByZXR1cm4gcmVzLmJvZHk7XG59XG5cbi8qKiBGZXRjaCBhIEpXS1MgZG9jdW1lbnQgZnJvbSBhbiBhYnNvbHV0ZSBVUkwgKG91dHNpZGUtdGhlLWNsdXN0ZXIgdmVyaWZpZXJzKS4gKi9cbmFzeW5jIGZ1bmN0aW9uIGZldGNoSndrc0Zyb21VcmwodXJsOiBzdHJpbmcsIHRpbWVvdXRNcyA9IDMwMDApOiBQcm9taXNlPEp3a3NEb2N1bWVudD4ge1xuICBjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4gY29udHJvbGxlci5hYm9ydCgpLCB0aW1lb3V0TXMpO1xuICB0cnkge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKHVybCwgeyBzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsLCBoZWFkZXJzOiB7IGFjY2VwdDogJ2FwcGxpY2F0aW9uL2pzb24nIH0gfSk7XG4gICAgaWYgKCFyZXMub2spIHRocm93IG5ldyBFcnJvcihgSldLUyBmZXRjaCByZXR1cm5lZCAke3Jlcy5zdGF0dXN9YCk7XG4gICAgY29uc3QgYm9keTogdW5rbm93biA9IGF3YWl0IHJlcy5qc29uKCk7XG4gICAgaWYgKCFpc0p3a3NEb2N1bWVudChib2R5KSkgdGhyb3cgbmV3IEVycm9yKCdKV0tTIHJlc3BvbnNlIHdhcyBub3QgYSBrZXkgc2V0Jyk7XG4gICAgcmV0dXJuIGJvZHk7XG4gIH0gZmluYWxseSB7XG4gICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgfVxufVxuXG5sZXQgcGxhdGZvcm1Kd2tzOiBKd2tzQ2FjaGUgfCB1bmRlZmluZWQ7XG5cbi8qKiBUaGUgcHJvY2Vzcy13aWRlIGNhY2hlIG9mIHBsYXRmb3JtJ3MgcHVibGlzaGVkIHNpZ25pbmcga2V5cy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwbGF0Zm9ybUp3a3NDYWNoZSgpOiBKd2tzQ2FjaGUge1xuICBwbGF0Zm9ybUp3a3MgPz89IG5ldyBKd2tzQ2FjaGUoeyBmZXRjaDogZmV0Y2hQbGF0Zm9ybUp3a3MsIHNvdXJjZTogJ3BsYXRmb3JtJyB9KTtcbiAgcmV0dXJuIHBsYXRmb3JtSndrcztcbn1cblxuLyoqXG4gKiBSZXBsYWNlIHRoZSBwcm9jZXNzLXdpZGUgY2FjaGUg4oCUIHVzZWQgYnkgdGVzdHMsIGFuZCBieSBhbnkgaG9zdCB0aGF0IG11c3RcbiAqIHN1cHBseSBpdHMgb3duIGZldGNoZXIuIFBhc3MgYHVuZGVmaW5lZGAgdG8gZHJvcCBiYWNrIHRvIHRoZSBkZWZhdWx0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0UGxhdGZvcm1Kd2tzQ2FjaGUoY2FjaGU6IEp3a3NDYWNoZSB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICBwbGF0Zm9ybUp3a3MgPSBjYWNoZTtcbn1cbiJdfQ==
@@ -3,6 +3,7 @@
3
3
  import { randomUUID } from 'crypto';
4
4
  import { createEnvRedisClient } from './env-redis.js';
5
5
  import { createLogger } from '../utils/logger.js';
6
+ import { errorMessage } from '../utils/response.js';
6
7
  const lockLogger = createLogger('leader-lock');
7
8
  /**
8
9
  * Best-effort close of a leader-lock Redis client on shutdown. Prefers graceful
@@ -55,7 +56,7 @@ export async function withLeaderLock(redis, key, ttlMs, fn) {
55
56
  // pod can prove it's the leader, so nobody runs this window. Skipping is
56
57
  // the safe side — running here could duplicate destructive work across pods.
57
58
  lockLogger.warn('Leader lock unavailable; skipping this run', {
58
- key, error: err instanceof Error ? err.message : String(err),
59
+ key, error: errorMessage(err),
59
60
  });
60
61
  return false;
61
62
  }
@@ -97,4 +98,4 @@ export function createEnvRedisLock() {
97
98
  lockLogger.info('Redis leader-lock client initialized');
98
99
  return inst;
99
100
  }
100
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGVhZGVyLWxvY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvbGVhZGVyLWxvY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVsRCxNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7QUFvQi9DOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLGVBQWUsQ0FBQyxLQUFtQztJQUN2RSxJQUFJLENBQUMsS0FBSztRQUFFLE9BQU87SUFDbkIsSUFBSSxDQUFDO1FBQ0gsSUFBSSxPQUFPLEtBQUssQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFLENBQUM7WUFBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUFDLE9BQU87UUFBQyxDQUFDO0lBQ3ZFLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCw2QkFBNkI7SUFDL0IsQ0FBQztJQUNELElBQUksQ0FBQztRQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDO0lBQUMsQ0FBQztJQUFDLE1BQU0sQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFDM0QsQ0FBQztBQUVEO2lFQUNpRTtBQUNqRSxNQUFNLGdCQUFnQixHQUNwQixtR0FBbUcsQ0FBQztBQUV0Rzs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsY0FBYyxDQUNsQyxLQUFnQixFQUNoQixHQUFXLEVBQ1gsS0FBYSxFQUNiLEVBQXVCO0lBRXZCLE1BQU0sS0FBSyxHQUFHLFVBQVUsRUFBRSxDQUFDO0lBQzNCLElBQUksUUFBaUIsQ0FBQztJQUN0QixJQUFJLENBQUM7UUFDSCxRQUFRLEdBQUcsTUFBTSxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNiLDBFQUEwRTtRQUMxRSx5RUFBeUU7UUFDekUsNkVBQTZFO1FBQzdFLFVBQVUsQ0FBQyxJQUFJLENBQUMsNENBQTRDLEVBQUU7WUFDNUQsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO1NBQzdELENBQUMsQ0FBQztRQUNILE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELElBQUksUUFBUSxLQUFLLElBQUk7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUVwQyxJQUFJLENBQUM7UUFDSCxNQUFNLEVBQUUsRUFBRSxDQUFDO0lBQ2IsQ0FBQztZQUFTLENBQUM7UUFDVCwwRUFBMEU7UUFDMUUsd0VBQXdFO1FBQ3hFLDRFQUE0RTtRQUM1RSxxREFBcUQ7UUFDckQsSUFBSSxDQUFDO1lBQ0gsSUFBSSxPQUFPLEtBQUssQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFLENBQUM7Z0JBQ3JDLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3BELENBQUM7aUJBQU0sSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEtBQUssRUFBRSxDQUFDO2dCQUM1QyxNQUFNLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdkIsQ0FBQztRQUNILENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxvREFBb0Q7UUFDdEQsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQjtJQUNoQyxNQUFNLElBQUksR0FBRyxvQkFBb0IsQ0FBWSxhQUFhLENBQUMsQ0FBQztJQUM1RCxJQUFJLElBQUk7UUFBRSxVQUFVLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7SUFDbEUsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IHJhbmRvbVVVSUQgfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHsgY3JlYXRlRW52UmVkaXNDbGllbnQgfSBmcm9tICcuL2Vudi1yZWRpcy5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuXG5jb25zdCBsb2NrTG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdsZWFkZXItbG9jaycpO1xuXG4vKipcbiAqIE1pbmltYWwgUmVkaXMgY2xpZW50IHN1cmZhY2UgbmVlZGVkIGZvciBhIGxlYWRlciBsb2NrIChhIHN1YnNldCBvZiBpb3JlZGlzKS5cbiAqIGBzZXRgIGlzIHZhcmlhZGljIHNvIGNhbGxlcnMgY2FuIHBhc3MgYCdQWCcsIHR0bCwgJ05YJ2AuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTG9ja1JlZGlzIHtcbiAgc2V0KGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiBQcm9taXNlPHVua25vd24+O1xuICBnZXQoa2V5OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+O1xuICBkZWwoLi4ua2V5czogc3RyaW5nW10pOiBQcm9taXNlPG51bWJlcj47XG4gIC8qKiBPcHRpb25hbCBMdWEgZXZhbCAoaW9yZWRpcyBoYXMgaXQpLiBXaGVuIHByZXNlbnQsIHJlbGVhc2UgdXNlcyBhbiBhdG9taWNcbiAgICogIGNvbXBhcmUtYW5kLWRlbGV0ZSBzbyBhIGxhcHNlZCBob2xkZXIgY2FuJ3QgZnJlZSBhIHN1Y2Nlc3NvcidzIGxvY2suICovXG4gIGV2YWw/KHNjcmlwdDogc3RyaW5nLCBudW1LZXlzOiBudW1iZXIsIC4uLmFyZ3M6IHVua25vd25bXSk6IFByb21pc2U8dW5rbm93bj47XG4gIC8qKiBHcmFjZWZ1bCBjbG9zZSAoaW9yZWRpcyBgcXVpdGApIOKAlCBjYWxsZWQgb24gc2h1dGRvd24gc28gdGhlIGNvbm5lY3Rpb25cbiAgICogIGRvZXNuJ3Qga2VlcCB0aGUgZXZlbnQgbG9vcCBhbGl2ZS4gKi9cbiAgcXVpdD8oKTogUHJvbWlzZTx1bmtub3duPjtcbiAgLyoqIEltbWVkaWF0ZSBjbG9zZSAoaW9yZWRpcyBgZGlzY29ubmVjdGApIOKAlCB0aGUgZmFsbGJhY2sgaWYgYHF1aXRgIGZhaWxzLiAqL1xuICBkaXNjb25uZWN0PygpOiB2b2lkO1xufVxuXG4vKipcbiAqIEJlc3QtZWZmb3J0IGNsb3NlIG9mIGEgbGVhZGVyLWxvY2sgUmVkaXMgY2xpZW50IG9uIHNodXRkb3duLiBQcmVmZXJzIGdyYWNlZnVsXG4gKiBgcXVpdGA7IGZhbGxzIGJhY2sgdG8gYGRpc2Nvbm5lY3RgLiBOby1vcCBmb3IgYSBudWxsIGNsaWVudCAvIG9uZSB3aXRob3V0XG4gKiBlaXRoZXIgbWV0aG9kLiBOZXZlciB0aHJvd3MuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbG9zZUxlYWRlckxvY2socmVkaXM6IExvY2tSZWRpcyB8IG51bGwgfCB1bmRlZmluZWQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKCFyZWRpcykgcmV0dXJuO1xuICB0cnkge1xuICAgIGlmICh0eXBlb2YgcmVkaXMucXVpdCA9PT0gJ2Z1bmN0aW9uJykgeyBhd2FpdCByZWRpcy5xdWl0KCk7IHJldHVybjsgfVxuICB9IGNhdGNoIHtcbiAgICAvLyBmYWxsIHRocm91Z2ggdG8gZGlzY29ubmVjdFxuICB9XG4gIHRyeSB7IHJlZGlzLmRpc2Nvbm5lY3Q/LigpOyB9IGNhdGNoIHsgLyogYmVzdC1lZmZvcnQgKi8gfVxufVxuXG4vKiogQXRvbWljIFwiZGVsZXRlIG9ubHkgaWYgSSBzdGlsbCBvd24gaXRcIiDigJQgY2xvc2VzIHRoZSBnZXQtdGhlbi1kZWwgcmFjZSB3aGVyZVxuICogIHRoZSBsb2NrIGV4cGlyZXMgYW5kIGlzIHJlLWFjcXVpcmVkIGJldHdlZW4gdGhlIHR3byBjYWxscy4gKi9cbmNvbnN0IFJFTEVBU0VfSUZfT1dORVIgPVxuICAnaWYgcmVkaXMuY2FsbChcImdldFwiLCBLRVlTWzFdKSA9PSBBUkdWWzFdIHRoZW4gcmV0dXJuIHJlZGlzLmNhbGwoXCJkZWxcIiwgS0VZU1sxXSkgZWxzZSByZXR1cm4gMCBlbmQnO1xuXG4vKipcbiAqIFJ1biBgZm5gIG9ubHkgaWYgdGhpcyBwcm9jZXNzIHdpbnMgYSBzaG9ydC1saXZlZCBkaXN0cmlidXRlZCBsb2NrIOKAlCB0aGVcbiAqIGFjcm9zcy1wb2RzIFwic2luZ2xlIHJ1bm5lclwiIGd1YXJkIGZvciBwZXJpb2RpYyBqb2JzIChkaWdlc3QgZmx1c2hlcywgZXRjLikuXG4gKlxuICogVXNlcyBgU0VUIGtleSB0b2tlbiBOWCBQWCB0dGxgLCBzbyBleGFjdGx5IG9uZSBob2xkZXIgcnVucyBwZXIgd2luZG93IGFuZCB0aGVcbiAqIGxvY2sgYXV0by1leHBpcmVzIGlmIHRoYXQgaG9sZGVyIGRpZXMgbWlkLXJ1biAobm8gc3R1Y2sgbG9jaykuIFRoZSBsb2NrIGlzXG4gKiByZWxlYXNlZCBvbiBjb21wbGV0aW9uLCBidXQgb25seSBpZiB3ZSBzdGlsbCBvd24gaXQg4oCUIGEgc2xvd2VyIHByZWRlY2Vzc29yXG4gKiBuZXZlciBkZWxldGVzIGEgc3VjY2Vzc29yJ3MgbG9jay4gYHR0bE1zYCBzaG91bGQgY29tZm9ydGFibHkgZXhjZWVkIG9uZSBydW4uXG4gKlxuICogSWYgUmVkaXMgY2FuJ3QgYmUgcmVhY2hlZCB0aGUgcnVuIGlzIHNraXBwZWQgKHJldHVybnMgZmFsc2UpIHJhdGhlciB0aGFuXG4gKiByZWplY3Rpbmcg4oCUIGNhbGxlcnMgYXJlIHRpbWVycywgYW5kIGEgUmVkaXMgYmxpcCBtdXN0IG5vdCBjcmFzaCB0aGUgcHJvY2Vzcy5cbiAqXG4gKiBAcmV0dXJucyB0cnVlIGlmIHdlIGhlbGQgdGhlIGxvY2sgYW5kIHJhbiBgZm5gOyBmYWxzZSBpZiBhbm90aGVyIGhvbGRlciBkaWQgb3JcbiAqICAgdGhlIGxvY2sgY291bGRuJ3QgYmUgdGFrZW4uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3aXRoTGVhZGVyTG9jayhcbiAgcmVkaXM6IExvY2tSZWRpcyxcbiAga2V5OiBzdHJpbmcsXG4gIHR0bE1zOiBudW1iZXIsXG4gIGZuOiAoKSA9PiBQcm9taXNlPHZvaWQ+LFxuKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IHRva2VuID0gcmFuZG9tVVVJRCgpO1xuICBsZXQgYWNxdWlyZWQ6IHVua25vd247XG4gIHRyeSB7XG4gICAgYWNxdWlyZWQgPSBhd2FpdCByZWRpcy5zZXQoa2V5LCB0b2tlbiwgJ1BYJywgdHRsTXMsICdOWCcpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICAvLyBSZWRpcyB1bnJlYWNoYWJsZSAoaW5jbHVkaW5nIGJlZm9yZSB0aGUgZmlyc3QgY29ubmVjdGlvbiBjb21wbGV0ZXMpOiBub1xuICAgIC8vIHBvZCBjYW4gcHJvdmUgaXQncyB0aGUgbGVhZGVyLCBzbyBub2JvZHkgcnVucyB0aGlzIHdpbmRvdy4gU2tpcHBpbmcgaXNcbiAgICAvLyB0aGUgc2FmZSBzaWRlIOKAlCBydW5uaW5nIGhlcmUgY291bGQgZHVwbGljYXRlIGRlc3RydWN0aXZlIHdvcmsgYWNyb3NzIHBvZHMuXG4gICAgbG9ja0xvZ2dlci53YXJuKCdMZWFkZXIgbG9jayB1bmF2YWlsYWJsZTsgc2tpcHBpbmcgdGhpcyBydW4nLCB7XG4gICAgICBrZXksIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVyciksXG4gICAgfSk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChhY3F1aXJlZCAhPT0gJ09LJykgcmV0dXJuIGZhbHNlO1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgZm4oKTtcbiAgfSBmaW5hbGx5IHtcbiAgICAvLyBSZWxlYXNlIG9ubHkgaWYgdGhlIGxvY2sgaXMgc3RpbGwgb3VycyDigJQgaWYgb3VyIHJ1biBvdmVycmFuIHRoZSBUVEwgYW5kXG4gICAgLy8gYW5vdGhlciBob2xkZXIgdG9vayBvdmVyLCByZWxlYXNpbmcgaGVyZSB3b3VsZCBmcmVlIHRoZWlyIGxvY2sgZWFybHkuXG4gICAgLy8gUHJlZmVyIGFuIGF0b21pYyBDQVMgKEx1YSk7IGZhbGwgYmFjayB0byBnZXQtdGhlbi1kZWwgZm9yIGNsaWVudHMgd2l0aG91dFxuICAgIC8vIGV2YWwgKHRoZSBzbWFsbCBub24tYXRvbWljIHdpbmRvdyBpcyBUVEwtYm91bmRlZCkuXG4gICAgdHJ5IHtcbiAgICAgIGlmICh0eXBlb2YgcmVkaXMuZXZhbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBhd2FpdCByZWRpcy5ldmFsKFJFTEVBU0VfSUZfT1dORVIsIDEsIGtleSwgdG9rZW4pO1xuICAgICAgfSBlbHNlIGlmICgoYXdhaXQgcmVkaXMuZ2V0KGtleSkpID09PSB0b2tlbikge1xuICAgICAgICBhd2FpdCByZWRpcy5kZWwoa2V5KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIEJlc3QtZWZmb3J0OiB0aGUgVFRMIGV4cGlyZXMgdGhlIGxvY2sgcmVnYXJkbGVzcy5cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogQSBgTG9ja1JlZGlzYCBiYWNrZWQgYnkgdGhlIHNoYXJlZCBlbnYgUmVkaXMgY2xpZW50IChzZWUgZW52LXJlZGlzLnRzKSDigJQgdGhlIGxlYWRlci1sb2NrIGNvdW50ZXJwYXJ0IHRvIGBjcmVhdGVFbnZSZWRpc0F1ZGl0U3Bvb2xgIC9cbiAqIGBjcmVhdGVFbnZSZWRpc1Rva2VuUmV2b2NhdGlvblN0b3JlYCwgZm9yIGEgc2VydmljZSB0aGF0IGhhcyBubyBCdWxsTVEgY2xpZW50IHRvXG4gKiBib3Jyb3cuIFJldHVybnMgYG51bGxgIHdoZW4gUmVkaXMgaXNuJ3QgY29uZmlndXJlZCwgc28gYSBjYWxsZXIgY2FuIGRlZ3JhZGUgdG9cbiAqIHJ1bm5pbmcgb24gZXZlcnkgcG9kICh0aGUgYXRvbWljIGd1YXJkcyBpdCB3cmFwcyBtdXN0IHN0aWxsIG1ha2UgdGhhdCBzYWZlKS5cbiAqIFRoZSBjbGllbnQgaXMgYSByZWFsIGlvcmVkaXMgaW5zdGFuY2U7IGlvcmVkaXMgZXhwb3NlcyBgc2V0YC9gZ2V0YC9gZGVsYC9gZXZhbGAsXG4gKiBzYXRpc2Z5aW5nIGBMb2NrUmVkaXNgIGluY2x1ZGluZyB0aGUgYXRvbWljIENBUyByZWxlYXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRW52UmVkaXNMb2NrKCk6IExvY2tSZWRpcyB8IG51bGwge1xuICBjb25zdCBpbnN0ID0gY3JlYXRlRW52UmVkaXNDbGllbnQ8TG9ja1JlZGlzPignbGVhZGVyLWxvY2snKTtcbiAgaWYgKGluc3QpIGxvY2tMb2dnZXIuaW5mbygnUmVkaXMgbGVhZGVyLWxvY2sgY2xpZW50IGluaXRpYWxpemVkJyk7XG4gIHJldHVybiBpbnN0O1xufVxuIl19
101
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGVhZGVyLWxvY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvbGVhZGVyLWxvY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFcEQsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBb0IvQzs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxlQUFlLENBQUMsS0FBbUM7SUFDdkUsSUFBSSxDQUFDLEtBQUs7UUFBRSxPQUFPO0lBQ25CLElBQUksQ0FBQztRQUNILElBQUksT0FBTyxLQUFLLENBQUMsSUFBSSxLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7WUFBQyxPQUFPO1FBQUMsQ0FBQztJQUN2RSxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsNkJBQTZCO0lBQy9CLENBQUM7SUFDRCxJQUFJLENBQUM7UUFBQyxLQUFLLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQztJQUFDLENBQUM7SUFBQyxNQUFNLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0FBQzNELENBQUM7QUFFRDtpRUFDaUU7QUFDakUsTUFBTSxnQkFBZ0IsR0FDcEIsbUdBQW1HLENBQUM7QUFFdEc7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLGNBQWMsQ0FDbEMsS0FBZ0IsRUFDaEIsR0FBVyxFQUNYLEtBQWEsRUFDYixFQUF1QjtJQUV2QixNQUFNLEtBQUssR0FBRyxVQUFVLEVBQUUsQ0FBQztJQUMzQixJQUFJLFFBQWlCLENBQUM7SUFDdEIsSUFBSSxDQUFDO1FBQ0gsUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDYiwwRUFBMEU7UUFDMUUseUVBQXlFO1FBQ3pFLDZFQUE2RTtRQUM3RSxVQUFVLENBQUMsSUFBSSxDQUFDLDRDQUE0QyxFQUFFO1lBQzVELEdBQUcsRUFBRSxLQUFLLEVBQUUsWUFBWSxDQUFDLEdBQUcsQ0FBQztTQUM5QixDQUFDLENBQUM7UUFDSCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFDRCxJQUFJLFFBQVEsS0FBSyxJQUFJO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFFcEMsSUFBSSxDQUFDO1FBQ0gsTUFBTSxFQUFFLEVBQUUsQ0FBQztJQUNiLENBQUM7WUFBUyxDQUFDO1FBQ1QsMEVBQTBFO1FBQzFFLHdFQUF3RTtRQUN4RSw0RUFBNEU7UUFDNUUscURBQXFEO1FBQ3JELElBQUksQ0FBQztZQUNILElBQUksT0FBTyxLQUFLLENBQUMsSUFBSSxLQUFLLFVBQVUsRUFBRSxDQUFDO2dCQUNyQyxNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNwRCxDQUFDO2lCQUFNLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxLQUFLLEVBQUUsQ0FBQztnQkFDNUMsTUFBTSxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3ZCLENBQUM7UUFDSCxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1Asb0RBQW9EO1FBQ3RELENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxrQkFBa0I7SUFDaEMsTUFBTSxJQUFJLEdBQUcsb0JBQW9CLENBQVksYUFBYSxDQUFDLENBQUM7SUFDNUQsSUFBSSxJQUFJO1FBQUUsVUFBVSxDQUFDLElBQUksQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO0lBQ2xFLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyByYW5kb21VVUlEIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCB7IGNyZWF0ZUVudlJlZGlzQ2xpZW50IH0gZnJvbSAnLi9lbnYtcmVkaXMuanMnO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyLmpzJztcbmltcG9ydCB7IGVycm9yTWVzc2FnZSB9IGZyb20gJy4uL3V0aWxzL3Jlc3BvbnNlLmpzJztcblxuY29uc3QgbG9ja0xvZ2dlciA9IGNyZWF0ZUxvZ2dlcignbGVhZGVyLWxvY2snKTtcblxuLyoqXG4gKiBNaW5pbWFsIFJlZGlzIGNsaWVudCBzdXJmYWNlIG5lZWRlZCBmb3IgYSBsZWFkZXIgbG9jayAoYSBzdWJzZXQgb2YgaW9yZWRpcykuXG4gKiBgc2V0YCBpcyB2YXJpYWRpYyBzbyBjYWxsZXJzIGNhbiBwYXNzIGAnUFgnLCB0dGwsICdOWCdgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIExvY2tSZWRpcyB7XG4gIHNldChrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKTogUHJvbWlzZTx1bmtub3duPjtcbiAgZ2V0KGtleTogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPjtcbiAgZGVsKC4uLmtleXM6IHN0cmluZ1tdKTogUHJvbWlzZTxudW1iZXI+O1xuICAvKiogT3B0aW9uYWwgTHVhIGV2YWwgKGlvcmVkaXMgaGFzIGl0KS4gV2hlbiBwcmVzZW50LCByZWxlYXNlIHVzZXMgYW4gYXRvbWljXG4gICAqICBjb21wYXJlLWFuZC1kZWxldGUgc28gYSBsYXBzZWQgaG9sZGVyIGNhbid0IGZyZWUgYSBzdWNjZXNzb3IncyBsb2NrLiAqL1xuICBldmFsPyhzY3JpcHQ6IHN0cmluZywgbnVtS2V5czogbnVtYmVyLCAuLi5hcmdzOiB1bmtub3duW10pOiBQcm9taXNlPHVua25vd24+O1xuICAvKiogR3JhY2VmdWwgY2xvc2UgKGlvcmVkaXMgYHF1aXRgKSDigJQgY2FsbGVkIG9uIHNodXRkb3duIHNvIHRoZSBjb25uZWN0aW9uXG4gICAqICBkb2Vzbid0IGtlZXAgdGhlIGV2ZW50IGxvb3AgYWxpdmUuICovXG4gIHF1aXQ/KCk6IFByb21pc2U8dW5rbm93bj47XG4gIC8qKiBJbW1lZGlhdGUgY2xvc2UgKGlvcmVkaXMgYGRpc2Nvbm5lY3RgKSDigJQgdGhlIGZhbGxiYWNrIGlmIGBxdWl0YCBmYWlscy4gKi9cbiAgZGlzY29ubmVjdD8oKTogdm9pZDtcbn1cblxuLyoqXG4gKiBCZXN0LWVmZm9ydCBjbG9zZSBvZiBhIGxlYWRlci1sb2NrIFJlZGlzIGNsaWVudCBvbiBzaHV0ZG93bi4gUHJlZmVycyBncmFjZWZ1bFxuICogYHF1aXRgOyBmYWxscyBiYWNrIHRvIGBkaXNjb25uZWN0YC4gTm8tb3AgZm9yIGEgbnVsbCBjbGllbnQgLyBvbmUgd2l0aG91dFxuICogZWl0aGVyIG1ldGhvZC4gTmV2ZXIgdGhyb3dzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY2xvc2VMZWFkZXJMb2NrKHJlZGlzOiBMb2NrUmVkaXMgfCBudWxsIHwgdW5kZWZpbmVkKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmICghcmVkaXMpIHJldHVybjtcbiAgdHJ5IHtcbiAgICBpZiAodHlwZW9mIHJlZGlzLnF1aXQgPT09ICdmdW5jdGlvbicpIHsgYXdhaXQgcmVkaXMucXVpdCgpOyByZXR1cm47IH1cbiAgfSBjYXRjaCB7XG4gICAgLy8gZmFsbCB0aHJvdWdoIHRvIGRpc2Nvbm5lY3RcbiAgfVxuICB0cnkgeyByZWRpcy5kaXNjb25uZWN0Py4oKTsgfSBjYXRjaCB7IC8qIGJlc3QtZWZmb3J0ICovIH1cbn1cblxuLyoqIEF0b21pYyBcImRlbGV0ZSBvbmx5IGlmIEkgc3RpbGwgb3duIGl0XCIg4oCUIGNsb3NlcyB0aGUgZ2V0LXRoZW4tZGVsIHJhY2Ugd2hlcmVcbiAqICB0aGUgbG9jayBleHBpcmVzIGFuZCBpcyByZS1hY3F1aXJlZCBiZXR3ZWVuIHRoZSB0d28gY2FsbHMuICovXG5jb25zdCBSRUxFQVNFX0lGX09XTkVSID1cbiAgJ2lmIHJlZGlzLmNhbGwoXCJnZXRcIiwgS0VZU1sxXSkgPT0gQVJHVlsxXSB0aGVuIHJldHVybiByZWRpcy5jYWxsKFwiZGVsXCIsIEtFWVNbMV0pIGVsc2UgcmV0dXJuIDAgZW5kJztcblxuLyoqXG4gKiBSdW4gYGZuYCBvbmx5IGlmIHRoaXMgcHJvY2VzcyB3aW5zIGEgc2hvcnQtbGl2ZWQgZGlzdHJpYnV0ZWQgbG9jayDigJQgdGhlXG4gKiBhY3Jvc3MtcG9kcyBcInNpbmdsZSBydW5uZXJcIiBndWFyZCBmb3IgcGVyaW9kaWMgam9icyAoZGlnZXN0IGZsdXNoZXMsIGV0Yy4pLlxuICpcbiAqIFVzZXMgYFNFVCBrZXkgdG9rZW4gTlggUFggdHRsYCwgc28gZXhhY3RseSBvbmUgaG9sZGVyIHJ1bnMgcGVyIHdpbmRvdyBhbmQgdGhlXG4gKiBsb2NrIGF1dG8tZXhwaXJlcyBpZiB0aGF0IGhvbGRlciBkaWVzIG1pZC1ydW4gKG5vIHN0dWNrIGxvY2spLiBUaGUgbG9jayBpc1xuICogcmVsZWFzZWQgb24gY29tcGxldGlvbiwgYnV0IG9ubHkgaWYgd2Ugc3RpbGwgb3duIGl0IOKAlCBhIHNsb3dlciBwcmVkZWNlc3NvclxuICogbmV2ZXIgZGVsZXRlcyBhIHN1Y2Nlc3NvcidzIGxvY2suIGB0dGxNc2Agc2hvdWxkIGNvbWZvcnRhYmx5IGV4Y2VlZCBvbmUgcnVuLlxuICpcbiAqIElmIFJlZGlzIGNhbid0IGJlIHJlYWNoZWQgdGhlIHJ1biBpcyBza2lwcGVkIChyZXR1cm5zIGZhbHNlKSByYXRoZXIgdGhhblxuICogcmVqZWN0aW5nIOKAlCBjYWxsZXJzIGFyZSB0aW1lcnMsIGFuZCBhIFJlZGlzIGJsaXAgbXVzdCBub3QgY3Jhc2ggdGhlIHByb2Nlc3MuXG4gKlxuICogQHJldHVybnMgdHJ1ZSBpZiB3ZSBoZWxkIHRoZSBsb2NrIGFuZCByYW4gYGZuYDsgZmFsc2UgaWYgYW5vdGhlciBob2xkZXIgZGlkIG9yXG4gKiAgIHRoZSBsb2NrIGNvdWxkbid0IGJlIHRha2VuLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd2l0aExlYWRlckxvY2soXG4gIHJlZGlzOiBMb2NrUmVkaXMsXG4gIGtleTogc3RyaW5nLFxuICB0dGxNczogbnVtYmVyLFxuICBmbjogKCkgPT4gUHJvbWlzZTx2b2lkPixcbik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBjb25zdCB0b2tlbiA9IHJhbmRvbVVVSUQoKTtcbiAgbGV0IGFjcXVpcmVkOiB1bmtub3duO1xuICB0cnkge1xuICAgIGFjcXVpcmVkID0gYXdhaXQgcmVkaXMuc2V0KGtleSwgdG9rZW4sICdQWCcsIHR0bE1zLCAnTlgnKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgLy8gUmVkaXMgdW5yZWFjaGFibGUgKGluY2x1ZGluZyBiZWZvcmUgdGhlIGZpcnN0IGNvbm5lY3Rpb24gY29tcGxldGVzKTogbm9cbiAgICAvLyBwb2QgY2FuIHByb3ZlIGl0J3MgdGhlIGxlYWRlciwgc28gbm9ib2R5IHJ1bnMgdGhpcyB3aW5kb3cuIFNraXBwaW5nIGlzXG4gICAgLy8gdGhlIHNhZmUgc2lkZSDigJQgcnVubmluZyBoZXJlIGNvdWxkIGR1cGxpY2F0ZSBkZXN0cnVjdGl2ZSB3b3JrIGFjcm9zcyBwb2RzLlxuICAgIGxvY2tMb2dnZXIud2FybignTGVhZGVyIGxvY2sgdW5hdmFpbGFibGU7IHNraXBwaW5nIHRoaXMgcnVuJywge1xuICAgICAga2V5LCBlcnJvcjogZXJyb3JNZXNzYWdlKGVyciksXG4gICAgfSk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChhY3F1aXJlZCAhPT0gJ09LJykgcmV0dXJuIGZhbHNlO1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgZm4oKTtcbiAgfSBmaW5hbGx5IHtcbiAgICAvLyBSZWxlYXNlIG9ubHkgaWYgdGhlIGxvY2sgaXMgc3RpbGwgb3VycyDigJQgaWYgb3VyIHJ1biBvdmVycmFuIHRoZSBUVEwgYW5kXG4gICAgLy8gYW5vdGhlciBob2xkZXIgdG9vayBvdmVyLCByZWxlYXNpbmcgaGVyZSB3b3VsZCBmcmVlIHRoZWlyIGxvY2sgZWFybHkuXG4gICAgLy8gUHJlZmVyIGFuIGF0b21pYyBDQVMgKEx1YSk7IGZhbGwgYmFjayB0byBnZXQtdGhlbi1kZWwgZm9yIGNsaWVudHMgd2l0aG91dFxuICAgIC8vIGV2YWwgKHRoZSBzbWFsbCBub24tYXRvbWljIHdpbmRvdyBpcyBUVEwtYm91bmRlZCkuXG4gICAgdHJ5IHtcbiAgICAgIGlmICh0eXBlb2YgcmVkaXMuZXZhbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBhd2FpdCByZWRpcy5ldmFsKFJFTEVBU0VfSUZfT1dORVIsIDEsIGtleSwgdG9rZW4pO1xuICAgICAgfSBlbHNlIGlmICgoYXdhaXQgcmVkaXMuZ2V0KGtleSkpID09PSB0b2tlbikge1xuICAgICAgICBhd2FpdCByZWRpcy5kZWwoa2V5KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIEJlc3QtZWZmb3J0OiB0aGUgVFRMIGV4cGlyZXMgdGhlIGxvY2sgcmVnYXJkbGVzcy5cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogQSBgTG9ja1JlZGlzYCBiYWNrZWQgYnkgdGhlIHNoYXJlZCBlbnYgUmVkaXMgY2xpZW50IChzZWUgZW52LXJlZGlzLnRzKSDigJQgdGhlIGxlYWRlci1sb2NrIGNvdW50ZXJwYXJ0IHRvIGBjcmVhdGVFbnZSZWRpc0F1ZGl0U3Bvb2xgIC9cbiAqIGBjcmVhdGVFbnZSZWRpc1Rva2VuUmV2b2NhdGlvblN0b3JlYCwgZm9yIGEgc2VydmljZSB0aGF0IGhhcyBubyBCdWxsTVEgY2xpZW50IHRvXG4gKiBib3Jyb3cuIFJldHVybnMgYG51bGxgIHdoZW4gUmVkaXMgaXNuJ3QgY29uZmlndXJlZCwgc28gYSBjYWxsZXIgY2FuIGRlZ3JhZGUgdG9cbiAqIHJ1bm5pbmcgb24gZXZlcnkgcG9kICh0aGUgYXRvbWljIGd1YXJkcyBpdCB3cmFwcyBtdXN0IHN0aWxsIG1ha2UgdGhhdCBzYWZlKS5cbiAqIFRoZSBjbGllbnQgaXMgYSByZWFsIGlvcmVkaXMgaW5zdGFuY2U7IGlvcmVkaXMgZXhwb3NlcyBgc2V0YC9gZ2V0YC9gZGVsYC9gZXZhbGAsXG4gKiBzYXRpc2Z5aW5nIGBMb2NrUmVkaXNgIGluY2x1ZGluZyB0aGUgYXRvbWljIENBUyByZWxlYXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRW52UmVkaXNMb2NrKCk6IExvY2tSZWRpcyB8IG51bGwge1xuICBjb25zdCBpbnN0ID0gY3JlYXRlRW52UmVkaXNDbGllbnQ8TG9ja1JlZGlzPignbGVhZGVyLWxvY2snKTtcbiAgaWYgKGluc3QpIGxvY2tMb2dnZXIuaW5mbygnUmVkaXMgbGVhZGVyLWxvY2sgY2xpZW50IGluaXRpYWxpemVkJyk7XG4gIHJldHVybiBpbnN0O1xufVxuIl19
@@ -0,0 +1,112 @@
1
+ /** Inbox priority every channel renders from. */
2
+ export type NotificationPriority = 'urgent' | 'high' | 'normal';
3
+ /**
4
+ * Transport-agnostic notification payload. Channels render from these fields;
5
+ * `payload` is the exact JSON the generic `webhook` channel forwards unchanged
6
+ * (so an existing webhook consumer keeps receiving the shape it expects).
7
+ */
8
+ export interface NotificationMessage {
9
+ /** Org whose inbox / destination receives this. */
10
+ recipientOrgId: string;
11
+ /** Short subject line, already prefixed/decorated by the caller. */
12
+ subject: string;
13
+ /** Plain-text body. */
14
+ body: string;
15
+ priority: NotificationPriority;
16
+ messageType: 'announcement' | 'conversation';
17
+ /** Structured body forwarded verbatim by the webhook channel. */
18
+ payload: unknown;
19
+ /** Stable key for at-least-once channels (email) to dedupe retries. */
20
+ dedupeKey?: string;
21
+ }
22
+ /**
23
+ * Channel-specific delivery target. `value` is the URL (webhook/slack) or the
24
+ * email address; `secret` is the webhook HMAC key; `targetUsers` narrows an
25
+ * email fan-out (null/absent = every org admin).
26
+ */
27
+ export interface ChannelTarget {
28
+ value?: string;
29
+ secret?: string;
30
+ targetUsers?: string[] | null;
31
+ orgId?: string;
32
+ }
33
+ /**
34
+ * Outcome of one delivery. `skipped` distinguishes "intentionally not sent"
35
+ * (email disabled, dedupe hit) from a real failure so the caller can count them
36
+ * apart; `code`/`error` feed structured logging and the audit trail.
37
+ */
38
+ export interface DeliveryResult {
39
+ ok: boolean;
40
+ skipped?: boolean;
41
+ code?: number;
42
+ error?: string;
43
+ }
44
+ /**
45
+ * One delivery transport. Generic in the message type so a service can carry
46
+ * extra rendering fields (platform's alert severity/labels) without loosening
47
+ * the shared contract or casting.
48
+ */
49
+ export interface NotificationChannel<M extends NotificationMessage = NotificationMessage> {
50
+ readonly channel: string;
51
+ deliver(msg: M, target: ChannelTarget, signal?: AbortSignal): Promise<DeliveryResult>;
52
+ }
53
+ /** Options for {@link createWebhookChannel}. */
54
+ export interface WebhookChannelOptions<M extends NotificationMessage = NotificationMessage> {
55
+ /** Channel name (default `'webhook'`). */
56
+ name?: string;
57
+ /** Allowed URL protocols (default https-only). */
58
+ protocols?: string[];
59
+ /** Per-delivery wall-clock cap in ms. */
60
+ timeoutMs?: number;
61
+ /** Render the JSON body; defaults to `msg.payload` forwarded verbatim. */
62
+ render?: (msg: M) => unknown;
63
+ }
64
+ /**
65
+ * Generic outbound webhook transport.
66
+ *
67
+ * The URL is org-controlled, so delivery goes through {@link safeFetch}: the
68
+ * host is resolved and vetted, the vetted IP is PINNED into the socket (no
69
+ * DNS-rebinding window between the check and the connect), and redirects are
70
+ * refused — a 3xx is a FAILED delivery, never a pivot to an unvetted host and
71
+ * never recorded green. Signed with `X-PB-Signature` when the target carries a
72
+ * secret; targets without one (alert destinations) stay unsigned.
73
+ */
74
+ export declare function createWebhookChannel<M extends NotificationMessage = NotificationMessage>(opts?: WebhookChannelOptions<M>): NotificationChannel<M>;
75
+ /** Arguments handed to an {@link EmailChannelOptions.send} implementation. */
76
+ export interface EmailSendRequest {
77
+ /** The target address, when the transport addresses one recipient directly. */
78
+ to?: string;
79
+ /** Org whose admins/users receive it, when the transport resolves recipients. */
80
+ orgId: string;
81
+ /** Narrowed recipient list, or null for "every org admin". */
82
+ targetUsers?: string[] | null;
83
+ subject: string;
84
+ text: string;
85
+ }
86
+ /** Options for {@link createEmailChannel}. */
87
+ export interface EmailChannelOptions {
88
+ /** Perform the send; resolve false for a transport-level failure. */
89
+ send: (req: EmailSendRequest) => Promise<boolean>;
90
+ /** Report whether email is configured at all on this deploy (default: yes). */
91
+ enabled?: () => boolean;
92
+ /**
93
+ * At-least-once dedupe window. A repeat of the same `(dedupeKey, target)`
94
+ * inside the window is reported `{ ok: true, skipped: true }` rather than
95
+ * re-sent. Omit/0 to disable.
96
+ */
97
+ dedupeTtlMs?: number;
98
+ }
99
+ /**
100
+ * Email transport. The actual delivery mechanism is injected (`send`) because
101
+ * it legitimately differs — platform has SMTP/SES, compliance asks platform to
102
+ * send on its behalf — but the parts that were duplicated-and-drifting are
103
+ * here: the enabled/skipped semantics and the at-least-once dedupe window (a
104
+ * webhook-retrying alert source would otherwise re-mail the same event).
105
+ */
106
+ export declare function createEmailChannel<M extends NotificationMessage = NotificationMessage>(opts: EmailChannelOptions): NotificationChannel<M>;
107
+ /**
108
+ * Build the per-service channel registry. Returns a resolver that yields `null`
109
+ * for an unknown name — the channel is DB data, so an unknown value is possible
110
+ * and the caller logs/counts it rather than throwing.
111
+ */
112
+ export declare function createChannelRegistry<M extends NotificationMessage = NotificationMessage>(channels: NotificationChannel<M>[]): (channel: string) => NotificationChannel<M> | null;
@@ -0,0 +1,123 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * Shared notification-channel contract + the transports that are genuinely the
5
+ * same everywhere.
6
+ *
7
+ * Two services had grown their own copy of this (platform's alert relay and
8
+ * compliance's notifier) with INCOMPATIBLE contracts — `target.value` vs
9
+ * `target.url`, a severity enum vs a priority enum, `skipped` present in one
10
+ * result shape and absent in the other, and two separate SSRF postures in the
11
+ * two webhook senders. This module is the single contract; the webhook and
12
+ * email transports live here.
13
+ *
14
+ * What stays per-service: the `in-app` transport only. Compliance posts to the
15
+ * message service over HTTP; platform (which is the alert ingress and must not
16
+ * add a network hop to an alert fan-out) writes the shared `messages` table
17
+ * directly under a superadmin tenant context. Those are genuinely different
18
+ * transports, not duplication.
19
+ */
20
+ import { createHmac } from 'crypto';
21
+ import { errorMessage } from '../utils/response.js';
22
+ import { safeFetch } from '../utils/ssrf.js';
23
+ /**
24
+ * Generic outbound webhook transport.
25
+ *
26
+ * The URL is org-controlled, so delivery goes through {@link safeFetch}: the
27
+ * host is resolved and vetted, the vetted IP is PINNED into the socket (no
28
+ * DNS-rebinding window between the check and the connect), and redirects are
29
+ * refused — a 3xx is a FAILED delivery, never a pivot to an unvetted host and
30
+ * never recorded green. Signed with `X-PB-Signature` when the target carries a
31
+ * secret; targets without one (alert destinations) stay unsigned.
32
+ */
33
+ export function createWebhookChannel(opts = {}) {
34
+ const render = opts.render ?? ((msg) => msg.payload);
35
+ return {
36
+ channel: opts.name ?? 'webhook',
37
+ async deliver(msg, target, signal) {
38
+ if (!target.value)
39
+ return { ok: false, error: 'no webhook url' };
40
+ const body = JSON.stringify(render(msg));
41
+ const headers = { 'Content-Type': 'application/json' };
42
+ if (target.secret) {
43
+ headers['X-PB-Signature'] = `sha256=${createHmac('sha256', target.secret).update(body).digest('hex')}`;
44
+ }
45
+ try {
46
+ const resp = await safeFetch(target.value, {
47
+ method: 'POST',
48
+ headers,
49
+ body,
50
+ signal,
51
+ protocols: opts.protocols,
52
+ timeoutMs: opts.timeoutMs,
53
+ });
54
+ if (resp.redirected) {
55
+ return { ok: false, code: resp.status, error: 'webhook url redirected (refused)' };
56
+ }
57
+ return resp.ok ? { ok: true, code: resp.status } : { ok: false, code: resp.status };
58
+ }
59
+ catch (err) {
60
+ return { ok: false, error: errorMessage(err) };
61
+ }
62
+ },
63
+ };
64
+ }
65
+ /**
66
+ * Email transport. The actual delivery mechanism is injected (`send`) because
67
+ * it legitimately differs — platform has SMTP/SES, compliance asks platform to
68
+ * send on its behalf — but the parts that were duplicated-and-drifting are
69
+ * here: the enabled/skipped semantics and the at-least-once dedupe window (a
70
+ * webhook-retrying alert source would otherwise re-mail the same event).
71
+ */
72
+ export function createEmailChannel(opts) {
73
+ const ttl = opts.dedupeTtlMs ?? 0;
74
+ const recent = new Map(); // dedupe key -> expiry (epoch ms)
75
+ const seenRecently = (key) => {
76
+ const now = Date.now();
77
+ for (const [k, exp] of recent) {
78
+ if (exp <= now)
79
+ recent.delete(k);
80
+ }
81
+ return recent.has(key);
82
+ };
83
+ return {
84
+ channel: 'email',
85
+ async deliver(msg, target) {
86
+ // Email unconfigured on this deploy → report SKIPPED (not delivered) so a
87
+ // caller never claims it sent something it didn't.
88
+ if (opts.enabled && !opts.enabled()) {
89
+ return { ok: false, skipped: true, error: 'email-disabled' };
90
+ }
91
+ const dedupeKey = ttl > 0 && msg.dedupeKey ? `${msg.dedupeKey}:${target.value ?? msg.recipientOrgId}` : null;
92
+ if (dedupeKey && seenRecently(dedupeKey)) {
93
+ return { ok: true, skipped: true };
94
+ }
95
+ try {
96
+ const sent = await opts.send({
97
+ to: target.value,
98
+ orgId: msg.recipientOrgId,
99
+ targetUsers: target.targetUsers ?? null,
100
+ subject: msg.subject,
101
+ text: msg.body,
102
+ });
103
+ // Record only on success, so a failed send is retried by the next event.
104
+ if (sent && dedupeKey)
105
+ recent.set(dedupeKey, Date.now() + ttl);
106
+ return sent ? { ok: true } : { ok: false, error: 'email-send-failed' };
107
+ }
108
+ catch (err) {
109
+ return { ok: false, error: errorMessage(err) };
110
+ }
111
+ },
112
+ };
113
+ }
114
+ /**
115
+ * Build the per-service channel registry. Returns a resolver that yields `null`
116
+ * for an unknown name — the channel is DB data, so an unknown value is possible
117
+ * and the caller logs/counts it rather than throwing.
118
+ */
119
+ export function createChannelRegistry(channels) {
120
+ const byName = new Map(channels.map((c) => [c.channel, c]));
121
+ return (channel) => byName.get(channel) ?? null;
122
+ }
123
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm90aWZpY2F0aW9uLWNoYW5uZWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpY2VzL25vdGlmaWNhdGlvbi1jaGFubmVscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JHO0FBRUgsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUVwQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDcEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBdUU3Qzs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUsb0JBQW9CLENBQ2xDLElBQUksR0FBNkIsRUFBRTtJQUVuQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxHQUFNLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN4RCxPQUFPO1FBQ0wsT0FBTyxFQUFFLElBQUksQ0FBQyxJQUFJLElBQUksU0FBUztRQUMvQixLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTTtZQUMvQixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUs7Z0JBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLGdCQUFnQixFQUFFLENBQUM7WUFDakUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUN6QyxNQUFNLE9BQU8sR0FBMkIsRUFBRSxjQUFjLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQztZQUMvRSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDbEIsT0FBTyxDQUFDLGdCQUFnQixDQUFDLEdBQUcsVUFBVSxVQUFVLENBQUMsUUFBUSxFQUFFLE1B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ZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBTaGFyZWQgbm90aWZpY2F0aW9uLWNoYW5uZWwgY29udHJhY3QgKyB0aGUgdHJhbnNwb3J0cyB0aGF0IGFyZSBnZW51aW5lbHkgdGhlXG4gKiBzYW1lIGV2ZXJ5d2hlcmUuXG4gKlxuICogVHdvIHNlcnZpY2VzIGhhZCBncm93biB0aGVpciBvd24gY29weSBvZiB0aGlzIChwbGF0Zm9ybSdzIGFsZXJ0IHJlbGF5IGFuZFxuICogY29tcGxpYW5jZSdzIG5vdGlmaWVyKSB3aXRoIElOQ09NUEFUSUJMRSBjb250cmFjdHMg4oCUIGB0YXJnZXQudmFsdWVgIHZzXG4gKiBgdGFyZ2V0LnVybGAsIGEgc2V2ZXJpdHkgZW51bSB2cyBhIHByaW9yaXR5IGVudW0sIGBza2lwcGVkYCBwcmVzZW50IGluIG9uZVxuICogcmVzdWx0IHNoYXBlIGFuZCBhYnNlbnQgaW4gdGhlIG90aGVyLCBhbmQgdHdvIHNlcGFyYXRlIFNTUkYgcG9zdHVyZXMgaW4gdGhlXG4gKiB0d28gd2ViaG9vayBzZW5kZXJzLiBUaGlzIG1vZHVsZSBpcyB0aGUgc2luZ2xlIGNvbnRyYWN0OyB0aGUgd2ViaG9vayBhbmRcbiAqIGVtYWlsIHRyYW5zcG9ydHMgbGl2ZSBoZXJlLlxuICpcbiAqIFdoYXQgc3RheXMgcGVyLXNlcnZpY2U6IHRoZSBgaW4tYXBwYCB0cmFuc3BvcnQgb25seS4gQ29tcGxpYW5jZSBwb3N0cyB0byB0aGVcbiAqIG1lc3NhZ2Ugc2VydmljZSBvdmVyIEhUVFA7IHBsYXRmb3JtICh3aGljaCBpcyB0aGUgYWxlcnQgaW5ncmVzcyBhbmQgbXVzdCBub3RcbiAqIGFkZCBhIG5ldHdvcmsgaG9wIHRvIGFuIGFsZXJ0IGZhbi1vdXQpIHdyaXRlcyB0aGUgc2hhcmVkIGBtZXNzYWdlc2AgdGFibGVcbiAqIGRpcmVjdGx5IHVuZGVyIGEgc3VwZXJhZG1pbiB0ZW5hbnQgY29udGV4dC4gVGhvc2UgYXJlIGdlbnVpbmVseSBkaWZmZXJlbnRcbiAqIHRyYW5zcG9ydHMsIG5vdCBkdXBsaWNhdGlvbi5cbiAqL1xuXG5pbXBvcnQgeyBjcmVhdGVIbWFjIH0gZnJvbSAnY3J5cHRvJztcblxuaW1wb3J0IHsgZXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgc2FmZUZldGNoIH0gZnJvbSAnLi4vdXRpbHMvc3NyZi5qcyc7XG5cbi8qKiBJbmJveCBwcmlvcml0eSBldmVyeSBjaGFubmVsIHJlbmRlcnMgZnJvbS4gKi9cbmV4cG9ydCB0eXBlIE5vdGlmaWNhdGlvblByaW9yaXR5ID0gJ3VyZ2VudCcgfCAnaGlnaCcgfCAnbm9ybWFsJztcblxuLyoqXG4gKiBUcmFuc3BvcnQtYWdub3N0aWMgbm90aWZpY2F0aW9uIHBheWxvYWQuIENoYW5uZWxzIHJlbmRlciBmcm9tIHRoZXNlIGZpZWxkcztcbiAqIGBwYXlsb2FkYCBpcyB0aGUgZXhhY3QgSlNPTiB0aGUgZ2VuZXJpYyBgd2ViaG9va2AgY2hhbm5lbCBmb3J3YXJkcyB1bmNoYW5nZWRcbiAqIChzbyBhbiBleGlzdGluZyB3ZWJob29rIGNvbnN1bWVyIGtlZXBzIHJlY2VpdmluZyB0aGUgc2hhcGUgaXQgZXhwZWN0cykuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTm90aWZpY2F0aW9uTWVzc2FnZSB7XG4gIC8qKiBPcmcgd2hvc2UgaW5ib3ggLyBkZXN0aW5hdGlvbiByZWNlaXZlcyB0aGlzLiAqL1xuICByZWNpcGllbnRPcmdJZDogc3RyaW5nO1xuICAvKiogU2hvcnQgc3ViamVjdCBsaW5lLCBhbHJlYWR5IHByZWZpeGVkL2RlY29yYXRlZCBieSB0aGUgY2FsbGVyLiAqL1xuICBzdWJqZWN0OiBzdHJpbmc7XG4gIC8qKiBQbGFpbi10ZXh0IGJvZHkuICovXG4gIGJvZHk6IHN0cmluZztcbiAgcHJpb3JpdHk6IE5vdGlmaWNhdGlvblByaW9yaXR5O1xuICBtZXNzYWdlVHlwZTogJ2Fubm91bmNlbWVudCcgfCAnY29udmVyc2F0aW9uJztcbiAgLyoqIFN0cnVjdHVyZWQgYm9keSBmb3J3YXJkZWQgdmVyYmF0aW0gYnkgdGhlIHdlYmhvb2sgY2hhbm5lbC4gKi9cbiAgcGF5bG9hZDogdW5rbm93bjtcbiAgLyoqIFN0YWJsZSBrZXkgZm9yIGF0LWxlYXN0LW9uY2UgY2hhbm5lbHMgKGVtYWlsKSB0byBkZWR1cGUgcmV0cmllcy4gKi9cbiAgZGVkdXBlS2V5Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIENoYW5uZWwtc3BlY2lmaWMgZGVsaXZlcnkgdGFyZ2V0LiBgdmFsdWVgIGlzIHRoZSBVUkwgKHdlYmhvb2svc2xhY2spIG9yIHRoZVxuICogZW1haWwgYWRkcmVzczsgYHNlY3JldGAgaXMgdGhlIHdlYmhvb2sgSE1BQyBrZXk7IGB0YXJnZXRVc2Vyc2AgbmFycm93cyBhblxuICogZW1haWwgZmFuLW91dCAobnVsbC9hYnNlbnQgPSBldmVyeSBvcmcgYWRtaW4pLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENoYW5uZWxUYXJnZXQge1xuICB2YWx1ZT86IHN0cmluZztcbiAgc2VjcmV0Pzogc3RyaW5nO1xuICB0YXJnZXRVc2Vycz86IHN0cmluZ1tdIHwgbnVsbDtcbiAgb3JnSWQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogT3V0Y29tZSBvZiBvbmUgZGVsaXZlcnkuIGBza2lwcGVkYCBkaXN0aW5ndWlzaGVzIFwiaW50ZW50aW9uYWxseSBub3Qgc2VudFwiXG4gKiAoZW1haWwgZGlzYWJsZWQsIGRlZHVwZSBoaXQpIGZyb20gYSByZWFsIGZhaWx1cmUgc28gdGhlIGNhbGxlciBjYW4gY291bnQgdGhlbVxuICogYXBhcnQ7IGBjb2RlYC9gZXJyb3JgIGZlZWQgc3RydWN0dXJlZCBsb2dnaW5nIGFuZCB0aGUgYXVkaXQgdHJhaWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGVsaXZlcnlSZXN1bHQge1xuICBvazogYm9vbGVhbjtcbiAgc2tpcHBlZD86IGJvb2xlYW47XG4gIGNvZGU/OiBudW1iZXI7XG4gIGVycm9yPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIE9uZSBkZWxpdmVyeSB0cmFuc3BvcnQuIEdlbmVyaWMgaW4gdGhlIG1lc3NhZ2UgdHlwZSBzbyBhIHNlcnZpY2UgY2FuIGNhcnJ5XG4gKiBleHRyYSByZW5kZXJpbmcgZmllbGRzIChwbGF0Zm9ybSdzIGFsZXJ0IHNldmVyaXR5L2xhYmVscykgd2l0aG91dCBsb29zZW5pbmdcbiAqIHRoZSBzaGFyZWQgY29udHJhY3Qgb3IgY2FzdGluZy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBOb3RpZmljYXRpb25DaGFubmVsPE0gZXh0ZW5kcyBOb3RpZmljYXRpb25NZXNzYWdlID0gTm90aWZpY2F0aW9uTWVzc2FnZT4ge1xuICByZWFkb25seSBjaGFubmVsOiBzdHJpbmc7XG4gIGRlbGl2ZXIobXNnOiBNLCB0YXJnZXQ6IENoYW5uZWxUYXJnZXQsIHNpZ25hbD86IEFib3J0U2lnbmFsKTogUHJvbWlzZTxEZWxpdmVyeVJlc3VsdD47XG59XG5cbi8qKiBPcHRpb25zIGZvciB7QGxpbmsgY3JlYXRlV2ViaG9va0NoYW5uZWx9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBXZWJob29rQ2hhbm5lbE9wdGlvbnM8TSBleHRlbmRzIE5vdGlmaWNhdGlvbk1lc3NhZ2UgPSBOb3RpZmljYXRpb25NZXNzYWdlPiB7XG4gIC8qKiBDaGFubmVsIG5hbWUgKGRlZmF1bHQgYCd3ZWJob29rJ2ApLiAqL1xuICBuYW1lPzogc3RyaW5nO1xuICAvKiogQWxsb3dlZCBVUkwgcHJvdG9jb2xzIChkZWZhdWx0IGh0dHBzLW9ubHkpLiAqL1xuICBwcm90b2NvbHM/OiBzdHJpbmdbXTtcbiAgLyoqIFBlci1kZWxpdmVyeSB3YWxsLWNsb2NrIGNhcCBpbiBtcy4gKi9cbiAgdGltZW91dE1zPzogbnVtYmVyO1xuICAvKiogUmVuZGVyIHRoZSBKU09OIGJvZHk7IGRlZmF1bHRzIHRvIGBtc2cucGF5bG9hZGAgZm9yd2FyZGVkIHZlcmJhdGltLiAqL1xuICByZW5kZXI/OiAobXNnOiBNKSA9PiB1bmtub3duO1xufVxuXG4vKipcbiAqIEdlbmVyaWMgb3V0Ym91bmQgd2ViaG9vayB0cmFuc3BvcnQuXG4gKlxuICogVGhlIFVSTCBpcyBvcmctY29udHJvbGxlZCwgc28gZGVsaXZlcnkgZ29lcyB0aHJvdWdoIHtAbGluayBzYWZlRmV0Y2h9OiB0aGVcbiAqIGhvc3QgaXMgcmVzb2x2ZWQgYW5kIHZldHRlZCwgdGhlIHZldHRlZCBJUCBpcyBQSU5ORUQgaW50byB0aGUgc29ja2V0IChub1xuICogRE5TLXJlYmluZGluZyB3aW5kb3cgYmV0d2VlbiB0aGUgY2hlY2sgYW5kIHRoZSBjb25uZWN0KSwgYW5kIHJlZGlyZWN0cyBhcmVcbiAqIHJlZnVzZWQg4oCUIGEgM3h4IGlzIGEgRkFJTEVEIGRlbGl2ZXJ5LCBuZXZlciBhIHBpdm90IHRvIGFuIHVudmV0dGVkIGhvc3QgYW5kXG4gKiBuZXZlciByZWNvcmRlZCBncmVlbi4gU2lnbmVkIHdpdGggYFgtUEItU2lnbmF0dXJlYCB3aGVuIHRoZSB0YXJnZXQgY2FycmllcyBhXG4gKiBzZWNyZXQ7IHRhcmdldHMgd2l0aG91dCBvbmUgKGFsZXJ0IGRlc3RpbmF0aW9ucykgc3RheSB1bnNpZ25lZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVdlYmhvb2tDaGFubmVsPE0gZXh0ZW5kcyBOb3RpZmljYXRpb25NZXNzYWdlID0gTm90aWZpY2F0aW9uTWVzc2FnZT4oXG4gIG9wdHM6IFdlYmhvb2tDaGFubmVsT3B0aW9uczxNPiA9IHt9LFxuKTogTm90aWZpY2F0aW9uQ2hhbm5lbDxNPiB7XG4gIGNvbnN0IHJlbmRlciA9IG9wdHMucmVuZGVyID8/ICgobXNnOiBNKSA9PiBtc2cucGF5bG9hZCk7XG4gIHJldHVybiB7XG4gICAgY2hhbm5lbDogb3B0cy5uYW1lID8/ICd3ZWJob29rJyxcbiAgICBhc3luYyBkZWxpdmVyKG1zZywgdGFyZ2V0LCBzaWduYWwpIHtcbiAgICAgIGlmICghdGFyZ2V0LnZhbHVlKSByZXR1cm4geyBvazogZmFsc2UsIGVycm9yOiAnbm8gd2ViaG9vayB1cmwnIH07XG4gICAgICBjb25zdCBib2R5ID0gSlNPTi5zdHJpbmdpZnkocmVuZGVyKG1zZykpO1xuICAgICAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9O1xuICAgICAgaWYgKHRhcmdldC5zZWNyZXQpIHtcbiAgICAgICAgaGVhZGVyc1snWC1QQi1TaWduYXR1cmUnXSA9IGBzaGEyNTY9JHtjcmVhdGVIbWFjKCdzaGEyNTYnLCB0YXJnZXQuc2VjcmV0KS51cGRhdGUoYm9keSkuZGlnZXN0KCdoZXgnKX1gO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IHNhZmVGZXRjaCh0YXJnZXQudmFsdWUsIHtcbiAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgIGJvZHksXG4gICAgICAgICAgc2lnbmFsLFxuICAgICAgICAgIHByb3RvY29sczogb3B0cy5wcm90b2NvbHMsXG4gICAgICAgICAgdGltZW91dE1zOiBvcHRzLnRpbWVvdXRNcyxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZXNwLnJlZGlyZWN0ZWQpIHtcbiAgICAgICAgICByZXR1cm4geyBvazogZmFsc2UsIGNvZGU6IHJlc3Auc3RhdHVzLCBlcnJvcjogJ3dlYmhvb2sgdXJsIHJlZGlyZWN0ZWQgKHJlZnVzZWQpJyB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXNwLm9rID8geyBvazogdHJ1ZSwgY29kZTogcmVzcC5zdGF0dXMgfSA6IHsgb2s6IGZhbHNlLCBjb2RlOiByZXNwLnN0YXR1cyB9O1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHJldHVybiB7IG9rOiBmYWxzZSwgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpIH07XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqIEFyZ3VtZW50cyBoYW5kZWQgdG8gYW4ge0BsaW5rIEVtYWlsQ2hhbm5lbE9wdGlvbnMuc2VuZH0gaW1wbGVtZW50YXRpb24uICovXG5leHBvcnQgaW50ZXJmYWNlIEVtYWlsU2VuZFJlcXVlc3Qge1xuICAvKiogVGhlIHRhcmdldCBhZGRyZXNzLCB3aGVuIHRoZSB0cmFuc3BvcnQgYWRkcmVzc2VzIG9uZSByZWNpcGllbnQgZGlyZWN0bHkuICovXG4gIHRvPzogc3RyaW5nO1xuICAvKiogT3JnIHdob3NlIGFkbWlucy91c2VycyByZWNlaXZlIGl0LCB3aGVuIHRoZSB0cmFuc3BvcnQgcmVzb2x2ZXMgcmVjaXBpZW50cy4gKi9cbiAgb3JnSWQ6IHN0cmluZztcbiAgLyoqIE5hcnJvd2VkIHJlY2lwaWVudCBsaXN0LCBvciBudWxsIGZvciBcImV2ZXJ5IG9yZyBhZG1pblwiLiAqL1xuICB0YXJnZXRVc2Vycz86IHN0cmluZ1tdIHwgbnVsbDtcbiAgc3ViamVjdDogc3RyaW5nO1xuICB0ZXh0OiBzdHJpbmc7XG59XG5cbi8qKiBPcHRpb25zIGZvciB7QGxpbmsgY3JlYXRlRW1haWxDaGFubmVsfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRW1haWxDaGFubmVsT3B0aW9ucyB7XG4gIC8qKiBQZXJmb3JtIHRoZSBzZW5kOyByZXNvbHZlIGZhbHNlIGZvciBhIHRyYW5zcG9ydC1sZXZlbCBmYWlsdXJlLiAqL1xuICBzZW5kOiAocmVxOiBFbWFpbFNlbmRSZXF1ZXN0KSA9PiBQcm9taXNlPGJvb2xlYW4+O1xuICAvKiogUmVwb3J0IHdoZXRoZXIgZW1haWwgaXMgY29uZmlndXJlZCBhdCBhbGwgb24gdGhpcyBkZXBsb3kgKGRlZmF1bHQ6IHllcykuICovXG4gIGVuYWJsZWQ/OiAoKSA9PiBib29sZWFuO1xuICAvKipcbiAgICogQXQtbGVhc3Qtb25jZSBkZWR1cGUgd2luZG93LiBBIHJlcGVhdCBvZiB0aGUgc2FtZSBgKGRlZHVwZUtleSwgdGFyZ2V0KWBcbiAgICogaW5zaWRlIHRoZSB3aW5kb3cgaXMgcmVwb3J0ZWQgYHsgb2s6IHRydWUsIHNraXBwZWQ6IHRydWUgfWAgcmF0aGVyIHRoYW5cbiAgICogcmUtc2VudC4gT21pdC8wIHRvIGRpc2FibGUuXG4gICAqL1xuICBkZWR1cGVUdGxNcz86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBFbWFpbCB0cmFuc3BvcnQuIFRoZSBhY3R1YWwgZGVsaXZlcnkgbWVjaGFuaXNtIGlzIGluamVjdGVkIChgc2VuZGApIGJlY2F1c2VcbiAqIGl0IGxlZ2l0aW1hdGVseSBkaWZmZXJzIOKAlCBwbGF0Zm9ybSBoYXMgU01UUC9TRVMsIGNvbXBsaWFuY2UgYXNrcyBwbGF0Zm9ybSB0b1xuICogc2VuZCBvbiBpdHMgYmVoYWxmIOKAlCBidXQgdGhlIHBhcnRzIHRoYXQgd2VyZSBkdXBsaWNhdGVkLWFuZC1kcmlmdGluZyBhcmVcbiAqIGhlcmU6IHRoZSBlbmFibGVkL3NraXBwZWQgc2VtYW50aWNzIGFuZCB0aGUgYXQtbGVhc3Qtb25jZSBkZWR1cGUgd2luZG93IChhXG4gKiB3ZWJob29rLXJldHJ5aW5nIGFsZXJ0IHNvdXJjZSB3b3VsZCBvdGhlcndpc2UgcmUtbWFpbCB0aGUgc2FtZSBldmVudCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVFbWFpbENoYW5uZWw8TSBleHRlbmRzIE5vdGlmaWNhdGlvbk1lc3NhZ2UgPSBOb3RpZmljYXRpb25NZXNzYWdlPihcbiAgb3B0czogRW1haWxDaGFubmVsT3B0aW9ucyxcbik6IE5vdGlmaWNhdGlvbkNoYW5uZWw8TT4ge1xuICBjb25zdCB0dGwgPSBvcHRzLmRlZHVwZVR0bE1zID8/IDA7XG4gIGNvbnN0IHJlY2VudCA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7IC8vIGRlZHVwZSBrZXkgLT4gZXhwaXJ5IChlcG9jaCBtcylcblxuICBjb25zdCBzZWVuUmVjZW50bHkgPSAoa2V5OiBzdHJpbmcpOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGZvciAoY29uc3QgW2ssIGV4cF0gb2YgcmVjZW50KSB7XG4gICAgICBpZiAoZXhwIDw9IG5vdykgcmVjZW50LmRlbGV0ZShrKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlY2VudC5oYXMoa2V5KTtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIGNoYW5uZWw6ICdlbWFpbCcsXG4gICAgYXN5bmMgZGVsaXZlcihtc2csIHRhcmdldCkge1xuICAgICAgLy8gRW1haWwgdW5jb25maWd1cmVkIG9uIHRoaXMgZGVwbG95IOKGkiByZXBvcnQgU0tJUFBFRCAobm90IGRlbGl2ZXJlZCkgc28gYVxuICAgICAgLy8gY2FsbGVyIG5ldmVyIGNsYWltcyBpdCBzZW50IHNvbWV0aGluZyBpdCBkaWRuJ3QuXG4gICAgICBpZiAob3B0cy5lbmFibGVkICYmICFvcHRzLmVuYWJsZWQoKSkge1xuICAgICAgICByZXR1cm4geyBvazogZmFsc2UsIHNraXBwZWQ6IHRydWUsIGVycm9yOiAnZW1haWwtZGlzYWJsZWQnIH07XG4gICAgICB9XG4gICAgICBjb25zdCBkZWR1cGVLZXkgPSB0dGwgPiAwICYmIG1zZy5kZWR1cGVLZXkgPyBgJHttc2cuZGVkdXBlS2V5fToke3RhcmdldC52YWx1ZSA/PyBtc2cucmVjaXBpZW50T3JnSWR9YCA6IG51bGw7XG4gICAgICBpZiAoZGVkdXBlS2V5ICYmIHNlZW5SZWNlbnRseShkZWR1cGVLZXkpKSB7XG4gICAgICAgIHJldHVybiB7IG9rOiB0cnVlLCBza2lwcGVkOiB0cnVlIH07XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBzZW50ID0gYXdhaXQgb3B0cy5zZW5kKHtcbiAgICAgICAgICB0bzogdGFyZ2V0LnZhbHVlLFxuICAgICAgICAgIG9yZ0lkOiBtc2cucmVjaXBpZW50T3JnSWQsXG4gICAgICAgICAgdGFyZ2V0VXNlcnM6IHRhcmdldC50YXJnZXRVc2VycyA/PyBudWxsLFxuICAgICAgICAgIHN1YmplY3Q6IG1zZy5zdWJqZWN0LFxuICAgICAgICAgIHRleHQ6IG1zZy5ib2R5LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gUmVjb3JkIG9ubHkgb24gc3VjY2Vzcywgc28gYSBmYWlsZWQgc2VuZCBpcyByZXRyaWVkIGJ5IHRoZSBuZXh0IGV2ZW50LlxuICAgICAgICBpZiAoc2VudCAmJiBkZWR1cGVLZXkpIHJlY2VudC5zZXQoZGVkdXBlS2V5LCBEYXRlLm5vdygpICsgdHRsKTtcbiAgICAgICAgcmV0dXJuIHNlbnQgPyB7IG9rOiB0cnVlIH0gOiB7IG9rOiBmYWxzZSwgZXJyb3I6ICdlbWFpbC1zZW5kLWZhaWxlZCcgfTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICByZXR1cm4geyBvazogZmFsc2UsIGVycm9yOiBlcnJvck1lc3NhZ2UoZXJyKSB9O1xuICAgICAgfVxuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogQnVpbGQgdGhlIHBlci1zZXJ2aWNlIGNoYW5uZWwgcmVnaXN0cnkuIFJldHVybnMgYSByZXNvbHZlciB0aGF0IHlpZWxkcyBgbnVsbGBcbiAqIGZvciBhbiB1bmtub3duIG5hbWUg4oCUIHRoZSBjaGFubmVsIGlzIERCIGRhdGEsIHNvIGFuIHVua25vd24gdmFsdWUgaXMgcG9zc2libGVcbiAqIGFuZCB0aGUgY2FsbGVyIGxvZ3MvY291bnRzIGl0IHJhdGhlciB0aGFuIHRocm93aW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ2hhbm5lbFJlZ2lzdHJ5PE0gZXh0ZW5kcyBOb3RpZmljYXRpb25NZXNzYWdlID0gTm90aWZpY2F0aW9uTWVzc2FnZT4oXG4gIGNoYW5uZWxzOiBOb3RpZmljYXRpb25DaGFubmVsPE0+W10sXG4pOiAoY2hhbm5lbDogc3RyaW5nKSA9PiBOb3RpZmljYXRpb25DaGFubmVsPE0+IHwgbnVsbCB7XG4gIGNvbnN0IGJ5TmFtZSA9IG5ldyBNYXAoY2hhbm5lbHMubWFwKChjKSA9PiBbYy5jaGFubmVsLCBjXSkpO1xuICByZXR1cm4gKGNoYW5uZWw6IHN0cmluZykgPT4gYnlOYW1lLmdldChjaGFubmVsKSA/PyBudWxsO1xufVxuIl19