@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 { createEnvRedisClient, createRedisReadyGate } from './env-redis.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('token-revocation');
7
8
  /**
8
9
  * Redis key namespace for the per-user current `tokenVersion`. The platform
@@ -59,7 +60,7 @@ export function createRedisTokenRevocationStore(redis) {
59
60
  // which is a deliberate opt-out, not a degradation.
60
61
  emitCounter('token_revocation_fail_open_total', { reason: 'read-error' });
61
62
  logger.debug('Token-revocation read failed (fail-open)', {
62
- userId, error: err instanceof Error ? err.message : String(err),
63
+ userId, error: errorMessage(err),
63
64
  });
64
65
  return null;
65
66
  }
@@ -75,7 +76,7 @@ export function createRedisTokenRevocationStore(redis) {
75
76
  // support impersonation everywhere — is visible and alertable.
76
77
  emitCounter('session_revocation_unavailable_total', { reason: 'read-error' });
77
78
  logger.debug('Session-revocation read failed (rejecting impersonation token)', {
78
- error: err instanceof Error ? err.message : String(err),
79
+ error: errorMessage(err),
79
80
  });
80
81
  return 'unavailable';
81
82
  }
@@ -163,7 +164,7 @@ export async function publishTokenRevocation(redis, userId, tokenVersion, ttlSec
163
164
  }
164
165
  catch (err) {
165
166
  logger.warn('Token-revocation publish failed (services fall back to token expiry)', {
166
- userId, error: err instanceof Error ? err.message : String(err),
167
+ userId, error: errorMessage(err),
167
168
  });
168
169
  }
169
170
  }
@@ -188,9 +189,9 @@ export async function publishSessionRevocation(redis, jti, ttlMs) {
188
189
  }
189
190
  catch (err) {
190
191
  logger.warn('Session-revocation publish failed (other services will honour the token until it expires)', {
191
- error: err instanceof Error ? err.message : String(err),
192
+ error: errorMessage(err),
192
193
  });
193
194
  return false;
194
195
  }
195
196
  }
196
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4tcmV2b2NhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy90b2tlbi1yZXZvY2F0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFHdEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLG9CQUFvQixFQUF3QixNQUFNLGdCQUFnQixDQUFDO0FBRWxHLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFekQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFFaEQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sMkJBQTJCLEdBQUcsYUFBYSxDQUFDO0FBRXpELHdDQUF3QztBQUN4QyxNQUFNLFVBQVUsa0JBQWtCLENBQUMsTUFBYztJQUMvQyxPQUFPLEdBQUcsMkJBQTJCLEdBQUcsTUFBTSxFQUFFLENBQUM7QUFDbkQsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSw2QkFBNkIsR0FBRyxjQUFjLENBQUM7QUFFNUQscURBQXFEO0FBQ3JELE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxHQUFXO0lBQzlDLE9BQU8sR0FBRyw2QkFBNkIsR0FBRyxHQUFHLEVBQUUsQ0FBQztBQUNsRCxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsK0JBQStCLENBQUMsS0FBdUI7SUFDckUsT0FBTztRQUNMLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxNQUFjO1lBQ3BDLElBQUksQ0FBQztnQkFDSCxNQUFNLEdBQUcsR0FBRyxNQUFNLEtBQUssQ0FBQyxHQUFHLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFDeEQsSUFBSSxHQUFHLEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxTQUFTLElB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Q0FBQyxDQUFDO0lBQ0wsQ0FBQztBQUNILENBQUM7QUFFRDs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSx3QkFBd0IsQ0FDNUMsS0FBdUIsRUFDdkIsR0FBVyxFQUNYLEtBQWE7SUFFYixJQUFJLENBQUM7UUFDSCxNQUFNLEtBQUssQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4RixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsTUFBTSxDQUFDLElBQUksQ0FBQywyRkFBMkYsRUFBRTtZQUN2RyxLQUFLLEVBQUUsR0FBRyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQztTQUN4RCxDQUFDLENBQUM7UUFDSCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB0eXBlIHsgUmVkaXNDYWNoZUNsaWVudCB9IGZyb20gJy4vY2FjaGUtc2VydmljZS5qcyc7XG5pbXBvcnQgeyBjcmVhdGVFbnZSZWRpc0NsaWVudCwgY3JlYXRlUmVkaXNSZWFkeUdhdGUsIHR5cGUgUmVhZHlBd2FyZVJlZGlzIH0gZnJvbSAnLi9lbnYtcmVkaXMuanMnO1xuaW1wb3J0IHR5cGUgeyBTZXNzaW9uUmV2b2NhdGlvblN0YXRlLCBUb2tlblJldm9jYXRpb25TdG9yZSB9IGZyb20gJy4uL21pZGRsZXdhcmUvYXV0aC5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZW1pdENvdW50ZXIgfSBmcm9tICcuLi91dGlscy9tZXRyaWMtZW1pdHRlci5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcigndG9rZW4tcmV2b2NhdGlvbicpO1xuXG4vKipcbiAqIFJlZGlzIGtleSBuYW1lc3BhY2UgZm9yIHRoZSBwZXItdXNlciBjdXJyZW50IGB0b2tlblZlcnNpb25gLiBUaGUgcGxhdGZvcm1cbiAqIFBVQkxJU0hFUyB0byB0aGlzIGtleSBvbiBldmVyeSBwcml2aWxlZ2UgY2hhbmdlOyB0aGUgc3RhdGVsZXNzIHNlcnZpY2VzIFJFQURcbiAqIGl0IGluIGByZXF1aXJlQXV0aGAgKHZpYSB7QGxpbmsgY3JlYXRlUmVkaXNUb2tlblJldm9jYXRpb25TdG9yZX0pIHRvIHJlamVjdFxuICogdG9rZW5zIG1pbnRlZCBiZWZvcmUgdGhhdCBjaGFuZ2UuIFB1Ymxpc2hlciBhbmQgcmVhZGVycyBNVVNUIHNoYXJlIHRoaXMgZXhhY3RcbiAqIHByZWZpeCDigJQgaGVuY2UgYm90aCBoZWxwZXJzIGxpdmUgaGVyZSwgaW4gb25lIHBsYWNlLlxuICovXG5leHBvcnQgY29uc3QgVE9LRU5fUkVWT0NBVElPTl9LRVlfUFJFRklYID0gJ2F1dGhyZXY6dHY6JztcblxuLyoqIFRoZSByZXZvY2F0aW9uIGtleSBmb3IgYSB1c2VyIGlkLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRva2VuUmV2b2NhdGlvbktleSh1c2VySWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtUT0tFTl9SRVZPQ0FUSU9OX0tFWV9QUkVGSVh9JHt1c2VySWR9YDtcbn1cblxuLyoqXG4gKiBSZWRpcyBrZXkgbmFtZXNwYWNlIGZvciBlbmRlZCBJTVBFUlNPTkFUSU9OIHNlc3Npb25zLCBieSB0b2tlbiBganRpYC4gU2FtZVxuICogcHVibGlzaC9yZWFkIHNwbGl0IGFzIHRoZSB0b2tlblZlcnNpb24ga2V5cyBhYm92ZSwgYW5kIGtlcHQgYmVzaWRlIHRoZW0gZm9yIHRoZVxuICogc2FtZSByZWFzb246IHB1Ymxpc2hlciBhbmQgcmVhZGVycyBtdXN0IGFncmVlIG9uIHRoaXMgZXhhY3QgcHJlZml4LlxuICovXG5leHBvcnQgY29uc3QgU0VTU0lPTl9SRVZPQ0FUSU9OX0tFWV9QUkVGSVggPSAnYXV0aHJldjpqdGk6JztcblxuLyoqIFRoZSByZXZvY2F0aW9uIGtleSBmb3Igb25lIHNlc3Npb24ncyB0b2tlbiBpZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXNzaW9uUmV2b2NhdGlvbktleShqdGk6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtTRVNTSU9OX1JFVk9DQVRJT05fS0VZX1BSRUZJWH0ke2p0aX1gO1xufVxuXG4vKipcbiAqIEJ1aWxkIGEge0BsaW5rIFRva2VuUmV2b2NhdGlvblN0b3JlfSBiYWNrZWQgYnkgYSBSZWRpcyBjbGllbnQsIGZvciBhIHN0YXRlbGVzc1xuICogc2VydmljZSB0byByZWdpc3RlciB2aWEgYHNldFRva2VuUmV2b2NhdGlvblN0b3JlYC4gUmVhZHMgdGhlIGN1cnJlbnRcbiAqIGB0b2tlblZlcnNpb25gIHRoZSBwbGF0Zm9ybSBwdWJsaXNoZWQgZm9yIHRoZSB1c2VyLlxuICpcbiAqIEZhaWwtb3BlbiBieSBjb250cmFjdDogYSBtaXNzLCBhIHBhcnNlIGZhaWx1cmUsIG9yIGEgUmVkaXMgZXJyb3IgYWxsIHlpZWxkXG4gKiBgbnVsbGAgKOKAlCBgcmVxdWlyZUF1dGhgIHRyZWF0cyB0aGF0IGFzIFwibm8ga25vd24gcmV2b2NhdGlvblwiKSwgc28gYSBSZWRpc1xuICogb3V0YWdlIGRlZ3JhZGVzIHRvIHRoZSBwcmUtZXhpc3RpbmcgYmVoYXZpb3VyIHJhdGhlciB0aGFuIGxvY2tpbmcgdXNlcnMgb3V0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUmVkaXNUb2tlblJldm9jYXRpb25TdG9yZShyZWRpczogUmVkaXNDYWNoZUNsaWVudCk6IFRva2VuUmV2b2NhdGlvblN0b3JlIHtcbiAgcmV0dXJuIHtcbiAgICBhc3luYyBnZXRDdXJyZW50VmVyc2lvbih1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmF3ID0gYXdhaXQgcmVkaXMuZ2V0KHRva2VuUmV2b2NhdGlvbktleSh1c2VySWQpKTtcbiAgICAgICAgaWYgKHJhdyA9PT0gbnVsbCB8fCByYXcgPT09IHVuZGVmaW5lZCB8fCByYXcudHJpbSgpID09PSAnJykgcmV0dXJuIG51bGw7XG4gICAgICAgIC8vIFN0cmljdCBpbnRlZ2VyIHBhcnNlOiBgTnVtYmVyYCAodW5saWtlIGBwYXJzZUludGApIHJlamVjdHMgdHJhaWxpbmdcbiAgICAgICAgLy8gZ2FyYmFnZSAoXCI1YWJjXCIg4oaSIE5hTiksIHNvIGEgY29ycnVwdGVkIGVudHJ5IGZhaWxzIG9wZW4gKG51bGwg4oaSIFwibm90XG4gICAgICAgIC8vIHJldm9rZWRcIikgcmF0aGVyIHRoYW4gYmVpbmcgcmVhZCBhcyBhIGJvZ3VzIHZlcnNpb24uIFRoZSBlbXB0eS1zdHJpbmdcbiAgICAgICAgLy8gZ3VhcmQgYWJvdmUgbWF0dGVycyBiZWNhdXNlIGBOdW1iZXIoJycpYCBpcyAwLCBub3QgTmFOLlxuICAgICAgICBjb25zdCBuID0gTnVtYmVyKHJhdyk7XG4gICAgICAgIHJldHVybiBOdW1iZXIuaXNJbnRlZ2VyKG4pID8gbiA6IG51bGw7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgLy8gUmVkaXMgd2FzIHJlYWNoYWJsZSBlbm91Z2ggdG8gdHJ5IGJ1dCB0aGUgcmVhZCBlcnJvcmVkIOKAlCB0aGlzIGlzIGFcbiAgICAgICAgLy8gREVHUkFEQVRJT046IHdoaWxlIGl0IHBlcnNpc3RzLCBmb3JjZWQgbG9nb3V0cyAvIHByaXZpbGVnZSByZXZvY2F0aW9uc1xuICAgICAgICAvLyBzaWxlbnRseSBzdG9wIHRha2luZyBlZmZlY3QgdW50aWwgbmF0dXJhbCB0b2tlbiBleHBpcnkuIEVtaXQgYSBjb3VudGVyXG4gICAgICAgIC8vIHNvIGBUb2tlblJldm9jYXRpb25GYWlsaW5nT3BlbmAgY2FuIGFsZXJ0IG9uIGEgU1VTVEFJTkVEIHJhdGUgKG1pcnJvcnNcbiAgICAgICAgLy8gdGhlIHF1b3RhX2ZhaWxfb3Blbl90b3RhbCBwYXR0ZXJuKS4gTm90IGVtaXR0ZWQgZm9yIHRoZSBcIlJlZGlzIG5vdFxuICAgICAgICAvLyBjb25maWd1cmVkXCIgcGF0aCAoY3JlYXRlRW52UmVkaXNUb2tlblJldm9jYXRpb25TdG9yZSDihpIgbnVsbCBjbGllbnQpLFxuICAgICAgICAvLyB3aGljaCBpcyBhIGRlbGliZXJhdGUgb3B0LW91dCwgbm90IGEgZGVncmFkYXRpb24uXG4gICAgICAgIGVtaXRDb3VudGVyKCd0b2tlbl9yZXZvY2F0aW9uX2ZhaWxfb3Blbl90b3RhbCcsIHsgcmVhc29uOiAncmVhZC1lcnJvcicgfSk7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnVG9rZW4tcmV2b2NhdGlvbiByZWFkIGZhaWxlZCAoZmFpbC1vcGVuKScsIHtcbiAgICAgICAgICB1c2VySWQsIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVyciksXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9LFxuICAgIGFzeW5jIGdldFNlc3Npb25SZXZvY2F0aW9uKGp0aTogc3RyaW5nKTogUHJvbWlzZTxTZXNzaW9uUmV2b2NhdGlvblN0YXRlPiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByYXcgPSBhd2FpdCByZWRpcy5nZXQoc2Vzc2lvblJldm9jYXRpb25LZXkoanRpKSk7XG4gICAgICAgIHJldHVybiByYXcgPT09IG51bGwgfHwgcmF3ID09PSB1bmRlZmluZWQgPyAnbGl2ZScgOiAncmV2b2tlZCc7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgLy8gTk9UIGZhaWwtb3BlbiwgdW5saWtlIGdldEN1cnJlbnRWZXJzaW9uIGFib3ZlOiBgdW5hdmFpbGFibGVgIHJlamVjdHNcbiAgICAgICAgLy8gdGhlIGltcGVyc29uYXRpb24gdG9rZW4uIENvdW50ZWQgc28gYSBzdXN0YWluZWQgb3V0YWdlIOKAlCB3aGljaCBzdG9wc1xuICAgICAgICAvLyBzdXBwb3J0IGltcGVyc29uYXRpb24gZXZlcnl3aGVyZSDigJQgaXMgdmlzaWJsZSBhbmQgYWxlcnRhYmxlLlxuICAgICAgICBlbWl0Q291bnRlcignc2Vzc2lvbl9yZXZvY2F0aW9uX3VuYXZhaWxhYmxlX3RvdGFsJywgeyByZWFzb246ICdyZWFkLWVycm9yJyB9KTtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdTZXNzaW9uLXJldm9jYXRpb24gcmVhZCBmYWlsZWQgKHJlamVjdGluZyBpbXBlcnNvbmF0aW9uIHRva2VuKScsIHtcbiAgICAgICAgICBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuICd1bmF2YWlsYWJsZSc7XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIHtAbGluayBUb2tlblJldm9jYXRpb25TdG9yZX0gYmFja2VkIGJ5IGEgUmVkaXMgY2xpZW50IHRoYXQgaXMgbGF6aWx5XG4gKiBjb25zdHJ1Y3RlZCBmcm9tIHRoZSBzdGFuZGFyZCBgUkVESVNfVVJMYCBvciBgUkVESVNfU0VOVElORUxTYCBlbnYg4oCUXG4gKiBmb3IgYSBzdGF0ZWxlc3Mgc2VydmljZSB0aGF0IGtlZXBzIE5PIFJlZGlzIGNsaWVudCBvZiBpdHMgb3duLiBUaGUgY2xpZW50IGlzXG4gKiBidWlsdCBvbiBmaXJzdCBgZ2V0Q3VycmVudFZlcnNpb25gIGNhbGwgYW5kIG1lbW9pemVkOyBgaW9yZWRpc2AgaXMgbG9hZGVkIHZpYVxuICogYSBndWFyZGVkIGR5bmFtaWMgcmVxdWlyZSBzbyBtZXJlbHkgaW1wb3J0aW5nIHRoaXMgbmV2ZXIgYnJlYWtzIGEgYnVpbGQvdGVzdFxuICogd2hlcmUgUmVkaXMgaXNuJ3QgcHJlc2VudC5cbiAqXG4gKiBGVUxMWSBGQUlMLU9QRU46IG5vIGVudiBjb25maWd1cmVkLCBhbiBpb3JlZGlzIGxvYWQgZmFpbHVyZSwgYSBjb25uZWN0IGVycm9yLFxuICogb3IgYW55IHJlYWQgZmFpbHVyZSBhbGwgcmVzb2x2ZSB0byBgbnVsbGAgKFwibm8ga25vd24gcmV2b2NhdGlvblwiKSwgc28gYVxuICogc2VydmljZSBkZWdyYWRlcyB0byBuYXR1cmFsIHRva2VuIGV4cGlyeSByYXRoZXIgdGhhbiBsb2NraW5nIHVzZXJzIG91dC4gQVxuICogc2VydmljZSBvcHRzIGluIHdpdGggYSBzaW5nbGUgYm9vdCBsaW5lOlxuICogICBgc2V0VG9rZW5SZXZvY2F0aW9uU3RvcmUoY3JlYXRlRW52UmVkaXNUb2tlblJldm9jYXRpb25TdG9yZSgpKTtgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVFbnZSZWRpc1Rva2VuUmV2b2NhdGlvblN0b3JlKCk6IFRva2VuUmV2b2NhdGlvblN0b3JlIHtcbiAgdHlwZSBSZWFkZXJSZWRpcyA9IFJlZGlzQ2FjaGVDbGllbnQgJiBSZWFkeUF3YXJlUmVkaXM7XG4gIC8vIHVuZGVmaW5lZCA9IG5vdCB5ZXQgYXR0ZW1wdGVkOyBudWxsID0gYXR0ZW1wdGVkIGFuZCB1bmF2YWlsYWJsZSAoc3RheSBvZmYpLlxuICBsZXQgY2FjaGVkOiBSZWFkZXJSZWRpcyB8IG51bGwgfCB1bmRlZmluZWQ7XG4gIGxldCByZWFkeTogKCgpID0+IFByb21pc2U8dm9pZD4pIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVhZGVyIGNsaWVudCwgYnVpbHQgb24gZmlyc3QgdXNlLiBUaGUgZW52IGNsaWVudCBoYXMgbm8gb2ZmbGluZSBxdWV1ZSxcbiAgICogc28gYSBHRVQgYmVmb3JlIHRoZSBmaXJzdCBjb25uZWN0aW9uIGNvbXBsZXRlcyBpcyByZWplY3RlZCDigJQgd2hpY2ggbWFkZSB0aGVcbiAgICogRklSU1QgaW1wZXJzb25hdGlvbiBjaGVjayBvbiBldmVyeSBwb2QgcmVhZCAndW5hdmFpbGFibGUnICg0MDEpLiBXYWl0XG4gICAqIChib3VuZGVkLCBuZXZlciByZWplY3RpbmcpIGZvciByZWFkaW5lc3M7IGEgZ2VudWluZWx5IGRvd24gUmVkaXMgdGhlbiBrZWVwc1xuICAgKiB0aGUgZXhpc3RpbmcgZmFpbC1vcGVuIC8gJ3VuYXZhaWxhYmxlJyBzZW1hbnRpY3MuXG4gICAqL1xuICBhc3luYyBmdW5jdGlvbiBjbGllbnQoKTogUHJvbWlzZTxSZWFkZXJSZWRpcyB8IG51bGw+IHtcbiAgICBpZiAoY2FjaGVkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIFNoYXJlZCBlbnYtY29uZmlndXJlZCBpb3JlZGlzIGNvbnN0cnVjdGlvbiAoZXJyb3IgbGlzdGVuZXIgYXR0YWNoZWQsIG51bGxcbiAgICAgIC8vIHdoZW4gUmVkaXMgaXNuJ3QgY29uZmlndXJlZCk7IHRoZSByZWFkZXIgc3RheXMgZmFpbC1vcGVuIOKAlCBhIG51bGwgY2xpZW50XG4gICAgICAvLyBqdXN0IGZhbGxzIGJhY2sgdG8gbmF0dXJhbCB0b2tlbiBleHBpcnkuXG4gICAgICBjYWNoZWQgPSBjcmVhdGVFbnZSZWRpc0NsaWVudDxSZWFkZXJSZWRpcz4oJ3Jldm9jYXRpb24tcmVhZGVyJyk7XG4gICAgICBpZiAoY2FjaGVkKSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdSZWRpcyB0b2tlbi1yZXZvY2F0aW9uIHJlYWRlciBpbml0aWFsaXplZCcpO1xuICAgICAgICByZWFkeSA9IGNyZWF0ZVJlZGlzUmVhZHlHYXRlKGNhY2hlZCk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChyZWFkeSkgYXdhaXQgcmVhZHkoKTtcbiAgICByZXR1cm4gY2FjaGVkO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBhc3luYyBnZXRDdXJyZW50VmVyc2lvbih1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD4ge1xuICAgICAgY29uc3QgcmVkaXMgPSBhd2FpdCBjbGllbnQoKTtcbiAgICAgIGlmICghcmVkaXMpIHJldHVybiBudWxsO1xuICAgICAgcmV0dXJuIGNyZWF0ZVJlZGlzVG9rZW5SZXZvY2F0aW9uU3RvcmUocmVkaXMpLmdldEN1cnJlbnRWZXJzaW9uKHVzZXJJZCk7XG4gICAgfSxcbiAgICBhc3luYyBnZXRTZXNzaW9uUmV2b2NhdGlvbihqdGk6IHN0cmluZyk6IFByb21pc2U8U2Vzc2lvblJldm9jYXRpb25TdGF0ZT4ge1xuICAgICAgY29uc3QgcmVkaXMgPSBhd2FpdCBjbGllbnQoKTtcbiAgICAgIC8vIE5vIFJlZGlzIGNvbmZpZ3VyZWQg4oeSIHRoZXJlIGlzIG5vIHdheSB0byBsZWFybiBhIHNlc3Npb24gd2FzIGVuZGVkLCBzb1xuICAgICAgLy8gYW4gaW1wZXJzb25hdGlvbiB0b2tlbiBjYW4ndCBiZSB0cnVzdGVkLiBFdmVyeSByZWFsIGRlcGxveW1lbnQgcnVucyBSZWRpc1xuICAgICAgLy8gKHRoZSBidWlsZCBxdWV1ZSBuZWVkcyBpdCksIHNvIHRoaXMgb25seSBiaXRlcyBhIG1pc2NvbmZpZ3VyZWQgc2VydmljZS5cbiAgICAgIGlmICghcmVkaXMpIHtcbiAgICAgICAgZW1pdENvdW50ZXIoJ3Nlc3Npb25fcmV2b2NhdGlvbl91bmF2YWlsYWJsZV90b3RhbCcsIHsgcmVhc29uOiAnbm90LWNvbmZpZ3VyZWQnIH0pO1xuICAgICAgICByZXR1cm4gJ3VuYXZhaWxhYmxlJztcbiAgICAgIH1cbiAgICAgIHJldHVybiBjcmVhdGVSZWRpc1Rva2VuUmV2b2NhdGlvblN0b3JlKHJlZGlzKS5nZXRTZXNzaW9uUmV2b2NhdGlvbiEoanRpKTtcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIFB1Ymxpc2ggYSB1c2VyJ3MgY3VycmVudCBgdG9rZW5WZXJzaW9uYCBzbyB0aGUgc3RhdGVsZXNzIHNlcnZpY2VzIHNlZSB0aGVcbiAqIHJldm9jYXRpb24gaW1tZWRpYXRlbHkgKHBsYXRmb3JtIHNpZGUpLiBCZXN0LWVmZm9ydCDigJQgbmV2ZXIgdGhyb3dzOyBhIGZhaWx1cmVcbiAqIGp1c3QgbWVhbnMgdGhlIHNlcnZpY2VzIGZhbGwgYmFjayB0byBuYXR1cmFsIHRva2VuIGV4cGlyeSBmb3IgdGhpcyBjaGFuZ2UuXG4gKlxuICogVGhlIGtleSBpcyB3cml0dGVuIHdpdGggYSBUVEwgZXF1YWwgdG8gdGhlIGFjY2Vzcy10b2tlbiBsaWZldGltZTogYW55IHRva2VuXG4gKiB0aGF0IGNvdWxkIHN0aWxsIGNhcnJ5IGFuIG9sZGVyIHZlcnNpb24gaGFzIGV4cGlyZWQgYnkgdGhlIHRpbWUgdGhlIGVudHJ5XG4gKiBsYXBzZXMsIHNvIGFuIGV4cGlyZWQgZW50cnkgY2FuIG5ldmVyIGNhdXNlIGEgZmFsc2UgXCJyZXZva2VkXCIgbm9yIGEgbWlzc2VkIG9uZS5cbiAqXG4gKiBAcGFyYW0gcmVkaXMgLSB0aGUgcGxhdGZvcm0ncyBSZWRpcyBjbGllbnRcbiAqIEBwYXJhbSB1c2VySWQgLSB0aGUgdXNlciB3aG9zZSBzZXNzaW9ucyBjaGFuZ2VkXG4gKiBAcGFyYW0gdG9rZW5WZXJzaW9uIC0gdGhlIHVzZXIncyBORVcgKHBvc3QtaW5jcmVtZW50KSB0b2tlblZlcnNpb25cbiAqIEBwYXJhbSB0dGxTZWNvbmRzIC0gYWNjZXNzLXRva2VuIGxpZmV0aW1lIGluIHNlY29uZHNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHB1Ymxpc2hUb2tlblJldm9jYXRpb24oXG4gIHJlZGlzOiBSZWRpc0NhY2hlQ2xpZW50LFxuICB1c2VySWQ6IHN0cmluZyxcbiAgdG9rZW5WZXJzaW9uOiBudW1iZXIsXG4gIHR0bFNlY29uZHM6IG51bWJlcixcbik6IFByb21pc2U8dm9pZD4ge1xuICB0cnkge1xuICAgIC8vIGlvcmVkaXMtc3R5bGUgdmFyaWFkaWMgU0VUIHdpdGggZXhwaXJ5OiBTRVQga2V5IHZhbCBFWCB0dGwuXG4gICAgYXdhaXQgcmVkaXMuc2V0KHRva2VuUmV2b2NhdGlvbktleSh1c2VySWQpLCBTdHJpbmcodG9rZW5WZXJzaW9uKSwgJ0VYJywgTWF0aC5tYXgoMSwgTWF0aC5mbG9vcih0dGxTZWNvbmRzKSkpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2dnZXIud2FybignVG9rZW4tcmV2b2NhdGlvbiBwdWJsaXNoIGZhaWxlZCAoc2VydmljZXMgZmFsbCBiYWNrIHRvIHRva2VuIGV4cGlyeSknLCB7XG4gICAgICB1c2VySWQsIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVyciksXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBQdWJsaXNoIHRoYXQgb25lIElNUEVSU09OQVRJT04gc2Vzc2lvbiBoYXMgZW5kZWQsIHNvIGV2ZXJ5IHN0YXRlbGVzcyBzZXJ2aWNlXG4gKiByZWplY3RzIGl0cyB0b2tlbiBvbiB0aGUgbmV4dCByZXF1ZXN0IChwbGF0Zm9ybSBzaWRlKS5cbiAqXG4gKiBSZXR1cm5zIHdoZXRoZXIgdGhlIHB1Ymxpc2ggbGFuZGVkIOKAlCB1bmxpa2UgYHB1Ymxpc2hUb2tlblJldm9jYXRpb25gLCB3aGljaCBpc1xuICogZmlyZS1hbmQtZm9yZ2V0LiBUaGUgY2FsbGVyIG11c3QgYmUgYWJsZSB0byB0ZWxsIHRoZSBwZXJzb24gd2hvIGVuZGVkIHRoZVxuICogc2Vzc2lvbiB0aGF0IGl0IGRpZCBOT1QgZW5kIGV2ZXJ5d2hlcmUsIHJhdGhlciB0aGFuIHJlcG9ydGluZyBzdWNjZXNzIHdoaWxlXG4gKiB0aGUgdG9rZW4gc3RpbGwgd29ya3MgYWdhaW5zdCBvdGhlciBzZXJ2aWNlcy5cbiAqXG4gKiBUaGUgZW50cnkgZXhwaXJlcyB3aXRoIHRoZSBzZXNzaW9uOiBvbmNlIHRoZSB0b2tlbiBpdHNlbGYgY2FuIG5vIGxvbmdlciBiZVxuICogdXNlZCwgdGhlcmUgaXMgbm90aGluZyBsZWZ0IHRvIHJldm9rZSwgc28gdGhlIGtleSBjbGVhbnMgaXRzZWxmIHVwLlxuICpcbiAqIEBwYXJhbSB0dGxNcyAtIHRpbWUgcmVtYWluaW5nIG9uIHRoZSBzZXNzaW9uJ3MgdG9rZW5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHB1Ymxpc2hTZXNzaW9uUmV2b2NhdGlvbihcbiAgcmVkaXM6IFJlZGlzQ2FjaGVDbGllbnQsXG4gIGp0aTogc3RyaW5nLFxuICB0dGxNczogbnVtYmVyLFxuKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIHRyeSB7XG4gICAgYXdhaXQgcmVkaXMuc2V0KHNlc3Npb25SZXZvY2F0aW9uS2V5KGp0aSksICcxJywgJ1BYJywgTWF0aC5tYXgoMTAwMCwgTWF0aC5jZWlsKHR0bE1zKSkpO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2dnZXIud2FybignU2Vzc2lvbi1yZXZvY2F0aW9uIHB1Ymxpc2ggZmFpbGVkIChvdGhlciBzZXJ2aWNlcyB3aWxsIGhvbm91ciB0aGUgdG9rZW4gdW50aWwgaXQgZXhwaXJlcyknLCB7XG4gICAgICBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpLFxuICAgIH0pO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuIl19
197
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4tcmV2b2NhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy90b2tlbi1yZXZvY2F0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFHdEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLG9CQUFvQixFQUF3QixNQUFNLGdCQUFnQixDQUFDO0FBRWxHLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDekQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRXBELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0FBRWhEOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxNQUFNLDJCQUEyQixHQUFHLGFBQWEsQ0FBQztBQUV6RCx3Q0FBd0M7QUFDeEMsTUFBTSxVQUFVLGtCQUFrQixDQUFDLE1BQWM7SUFDL0MsT0FBTyxHQUFHLDJCQUEyQixHQUFHLE1BQU0sRUFBRSxDQUFDO0FBQ25ELENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sNkJBQTZCLEdBQUcsY0FBYyxDQUFDO0FBRTVELHFEQUFxRDtBQUNyRCxNQUFNLFVBQVUsb0JBQW9CLENBQUMsR0FBVztJQUM5QyxPQUFPLEdBQUcsNkJBQTZCLEdBQUcsR0FBRyxFQUFFLENBQUM7QUFDbEQsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLCtCQUErQixDQUFDLEtBQXVCO0lBQ3JFLE9BQU87UUFDTCxLQUFLLENBQUMsaUJBQWlCLENBQUMsTUFBYztZQUNwQyxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxHQUFHLEdBQUcsTUFBTSxLQUFLLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7Z0JBQ3hE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TUFBTSxLQUFLLENBQUMsR0FBRyxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEYsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNiLE1BQU0sQ0FBQyxJQUFJLENBQUMsMkZBQTJGLEVBQUU7WUFDdkcsS0FBSyxFQUFFLFlBQVksQ0FBQyxHQUFHLENBQUM7U0FDekIsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgdHlwZSB7IFJlZGlzQ2FjaGVDbGllbnQgfSBmcm9tICcuL2NhY2hlLXNlcnZpY2UuanMnO1xuaW1wb3J0IHsgY3JlYXRlRW52UmVkaXNDbGllbnQsIGNyZWF0ZVJlZGlzUmVhZHlHYXRlLCB0eXBlIFJlYWR5QXdhcmVSZWRpcyB9IGZyb20gJy4vZW52LXJlZGlzLmpzJztcbmltcG9ydCB0eXBlIHsgU2Vzc2lvblJldm9jYXRpb25TdGF0ZSwgVG9rZW5SZXZvY2F0aW9uU3RvcmUgfSBmcm9tICcuLi9taWRkbGV3YXJlL2F1dGguanMnO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyLmpzJztcbmltcG9ydCB7IGVtaXRDb3VudGVyIH0gZnJvbSAnLi4vdXRpbHMvbWV0cmljLWVtaXR0ZXIuanMnO1xuaW1wb3J0IHsgZXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3Rva2VuLXJldm9jYXRpb24nKTtcblxuLyoqXG4gKiBSZWRpcyBrZXkgbmFtZXNwYWNlIGZvciB0aGUgcGVyLXVzZXIgY3VycmVudCBgdG9rZW5WZXJzaW9uYC4gVGhlIHBsYXRmb3JtXG4gKiBQVUJMSVNIRVMgdG8gdGhpcyBrZXkgb24gZXZlcnkgcHJpdmlsZWdlIGNoYW5nZTsgdGhlIHN0YXRlbGVzcyBzZXJ2aWNlcyBSRUFEXG4gKiBpdCBpbiBgcmVxdWlyZUF1dGhgICh2aWEge0BsaW5rIGNyZWF0ZVJlZGlzVG9rZW5SZXZvY2F0aW9uU3RvcmV9KSB0byByZWplY3RcbiAqIHRva2VucyBtaW50ZWQgYmVmb3JlIHRoYXQgY2hhbmdlLiBQdWJsaXNoZXIgYW5kIHJlYWRlcnMgTVVTVCBzaGFyZSB0aGlzIGV4YWN0XG4gKiBwcmVmaXgg4oCUIGhlbmNlIGJvdGggaGVscGVycyBsaXZlIGhlcmUsIGluIG9uZSBwbGFjZS5cbiAqL1xuZXhwb3J0IGNvbnN0IFRPS0VOX1JFVk9DQVRJT05fS0VZX1BSRUZJWCA9ICdhdXRocmV2OnR2Oic7XG5cbi8qKiBUaGUgcmV2b2NhdGlvbiBrZXkgZm9yIGEgdXNlciBpZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b2tlblJldm9jYXRpb25LZXkodXNlcklkOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7VE9LRU5fUkVWT0NBVElPTl9LRVlfUFJFRklYfSR7dXNlcklkfWA7XG59XG5cbi8qKlxuICogUmVkaXMga2V5IG5hbWVzcGFjZSBmb3IgZW5kZWQgSU1QRVJTT05BVElPTiBzZXNzaW9ucywgYnkgdG9rZW4gYGp0aWAuIFNhbWVcbiAqIHB1Ymxpc2gvcmVhZCBzcGxpdCBhcyB0aGUgdG9rZW5WZXJzaW9uIGtleXMgYWJvdmUsIGFuZCBrZXB0IGJlc2lkZSB0aGVtIGZvciB0aGVcbiAqIHNhbWUgcmVhc29uOiBwdWJsaXNoZXIgYW5kIHJlYWRlcnMgbXVzdCBhZ3JlZSBvbiB0aGlzIGV4YWN0IHByZWZpeC5cbiAqL1xuZXhwb3J0IGNvbnN0IFNFU1NJT05fUkVWT0NBVElPTl9LRVlfUFJFRklYID0gJ2F1dGhyZXY6anRpOic7XG5cbi8qKiBUaGUgcmV2b2NhdGlvbiBrZXkgZm9yIG9uZSBzZXNzaW9uJ3MgdG9rZW4gaWQuICovXG5leHBvcnQgZnVuY3Rpb24gc2Vzc2lvblJldm9jYXRpb25LZXkoanRpOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7U0VTU0lPTl9SRVZPQ0FUSU9OX0tFWV9QUkVGSVh9JHtqdGl9YDtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIHtAbGluayBUb2tlblJldm9jYXRpb25TdG9yZX0gYmFja2VkIGJ5IGEgUmVkaXMgY2xpZW50LCBmb3IgYSBzdGF0ZWxlc3NcbiAqIHNlcnZpY2UgdG8gcmVnaXN0ZXIgdmlhIGBzZXRUb2tlblJldm9jYXRpb25TdG9yZWAuIFJlYWRzIHRoZSBjdXJyZW50XG4gKiBgdG9rZW5WZXJzaW9uYCB0aGUgcGxhdGZvcm0gcHVibGlzaGVkIGZvciB0aGUgdXNlci5cbiAqXG4gKiBGYWlsLW9wZW4gYnkgY29udHJhY3Q6IGEgbWlzcywgYSBwYXJzZSBmYWlsdXJlLCBvciBhIFJlZGlzIGVycm9yIGFsbCB5aWVsZFxuICogYG51bGxgICjigJQgYHJlcXVpcmVBdXRoYCB0cmVhdHMgdGhhdCBhcyBcIm5vIGtub3duIHJldm9jYXRpb25cIiksIHNvIGEgUmVkaXNcbiAqIG91dGFnZSBkZWdyYWRlcyB0byB0aGUgcHJlLWV4aXN0aW5nIGJlaGF2aW91ciByYXRoZXIgdGhhbiBsb2NraW5nIHVzZXJzIG91dC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVJlZGlzVG9rZW5SZXZvY2F0aW9uU3RvcmUocmVkaXM6IFJlZGlzQ2FjaGVDbGllbnQpOiBUb2tlblJldm9jYXRpb25TdG9yZSB7XG4gIHJldHVybiB7XG4gICAgYXN5bmMgZ2V0Q3VycmVudFZlcnNpb24odXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPG51bWJlciB8IG51bGw+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJhdyA9IGF3YWl0IHJlZGlzLmdldCh0b2tlblJldm9jYXRpb25LZXkodXNlcklkKSk7XG4gICAgICAgIGlmIChyYXcgPT09IG51bGwgfHwgcmF3ID09PSB1bmRlZmluZWQgfHwgcmF3LnRyaW0oKSA9PT0gJycpIHJldHVybiBudWxsO1xuICAgICAgICAvLyBTdHJpY3QgaW50ZWdlciBwYXJzZTogYE51bWJlcmAgKHVubGlrZSBgcGFyc2VJbnRgKSByZWplY3RzIHRyYWlsaW5nXG4gICAgICAgIC8vIGdhcmJhZ2UgKFwiNWFiY1wiIOKGkiBOYU4pLCBzbyBhIGNvcnJ1cHRlZCBlbnRyeSBmYWlscyBvcGVuIChudWxsIOKGkiBcIm5vdFxuICAgICAgICAvLyByZXZva2VkXCIpIHJhdGhlciB0aGFuIGJlaW5nIHJlYWQgYXMgYSBib2d1cyB2ZXJzaW9uLiBUaGUgZW1wdHktc3RyaW5nXG4gICAgICAgIC8vIGd1YXJkIGFib3ZlIG1hdHRlcnMgYmVjYXVzZSBgTnVtYmVyKCcnKWAgaXMgMCwgbm90IE5hTi5cbiAgICAgICAgY29uc3QgbiA9IE51bWJlcihyYXcpO1xuICAgICAgICByZXR1cm4gTnVtYmVyLmlzSW50ZWdlcihuKSA/IG4gOiBudWxsO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIC8vIFJlZGlzIHdhcyByZWFjaGFibGUgZW5vdWdoIHRvIHRyeSBidXQgdGhlIHJlYWQgZXJyb3JlZCDigJQgdGhpcyBpcyBhXG4gICAgICAgIC8vIERFR1JBREFUSU9OOiB3aGlsZSBpdCBwZXJzaXN0cywgZm9yY2VkIGxvZ291dHMgLyBwcml2aWxlZ2UgcmV2b2NhdGlvbnNcbiAgICAgICAgLy8gc2lsZW50bHkgc3RvcCB0YWtpbmcgZWZmZWN0IHVudGlsIG5hdHVyYWwgdG9rZW4gZXhwaXJ5LiBFbWl0IGEgY291bnRlclxuICAgICAgICAvLyBzbyBgVG9rZW5SZXZvY2F0aW9uRmFpbGluZ09wZW5gIGNhbiBhbGVydCBvbiBhIFNVU1RBSU5FRCByYXRlIChtaXJyb3JzXG4gICAgICAgIC8vIHRoZSBxdW90YV9mYWlsX29wZW5fdG90YWwgcGF0dGVybikuIE5vdCBlbWl0dGVkIGZvciB0aGUgXCJSZWRpcyBub3RcbiAgICAgICAgLy8gY29uZmlndXJlZFwiIHBhdGggKGNyZWF0ZUVudlJlZGlzVG9rZW5SZXZvY2F0aW9uU3RvcmUg4oaSIG51bGwgY2xpZW50KSxcbiAgICAgICAgLy8gd2hpY2ggaXMgYSBkZWxpYmVyYXRlIG9wdC1vdXQsIG5vdCBhIGRlZ3JhZGF0aW9uLlxuICAgICAgICBlbWl0Q291bnRlcigndG9rZW5fcmV2b2NhdGlvbl9mYWlsX29wZW5fdG90YWwnLCB7IHJlYXNvbjogJ3JlYWQtZXJyb3InIH0pO1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1Rva2VuLXJldm9jYXRpb24gcmVhZCBmYWlsZWQgKGZhaWwtb3BlbiknLCB7XG4gICAgICAgICAgdXNlcklkLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVyciksXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9LFxuICAgIGFzeW5jIGdldFNlc3Npb25SZXZvY2F0aW9uKGp0aTogc3RyaW5nKTogUHJvbWlzZTxTZXNzaW9uUmV2b2NhdGlvblN0YXRlPiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByYXcgPSBhd2FpdCByZWRpcy5nZXQoc2Vzc2lvblJldm9jYXRpb25LZXkoanRpKSk7XG4gICAgICAgIHJldHVybiByYXcgPT09IG51bGwgfHwgcmF3ID09PSB1bmRlZmluZWQgPyAnbGl2ZScgOiAncmV2b2tlZCc7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgLy8gTk9UIGZhaWwtb3BlbiwgdW5saWtlIGdldEN1cnJlbnRWZXJzaW9uIGFib3ZlOiBgdW5hdmFpbGFibGVgIHJlamVjdHNcbiAgICAgICAgLy8gdGhlIGltcGVyc29uYXRpb24gdG9rZW4uIENvdW50ZWQgc28gYSBzdXN0YWluZWQgb3V0YWdlIOKAlCB3aGljaCBzdG9wc1xuICAgICAgICAvLyBzdXBwb3J0IGltcGVyc29uYXRpb24gZXZlcnl3aGVyZSDigJQgaXMgdmlzaWJsZSBhbmQgYWxlcnRhYmxlLlxuICAgICAgICBlbWl0Q291bnRlcignc2Vzc2lvbl9yZXZvY2F0aW9uX3VuYXZhaWxhYmxlX3RvdGFsJywgeyByZWFzb246ICdyZWFkLWVycm9yJyB9KTtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdTZXNzaW9uLXJldm9jYXRpb24gcmVhZCBmYWlsZWQgKHJlamVjdGluZyBpbXBlcnNvbmF0aW9uIHRva2VuKScsIHtcbiAgICAgICAgICBlcnJvcjogZXJyb3JNZXNzYWdlKGVyciksXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gJ3VuYXZhaWxhYmxlJztcbiAgICAgIH1cbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIEJ1aWxkIGEge0BsaW5rIFRva2VuUmV2b2NhdGlvblN0b3JlfSBiYWNrZWQgYnkgYSBSZWRpcyBjbGllbnQgdGhhdCBpcyBsYXppbHlcbiAqIGNvbnN0cnVjdGVkIGZyb20gdGhlIHN0YW5kYXJkIGBSRURJU19VUkxgIG9yIGBSRURJU19TRU5USU5FTFNgIGVudiDigJRcbiAqIGZvciBhIHN0YXRlbGVzcyBzZXJ2aWNlIHRoYXQga2VlcHMgTk8gUmVkaXMgY2xpZW50IG9mIGl0cyBvd24uIFRoZSBjbGllbnQgaXNcbiAqIGJ1aWx0IG9uIGZpcnN0IGBnZXRDdXJyZW50VmVyc2lvbmAgY2FsbCBhbmQgbWVtb2l6ZWQ7IGBpb3JlZGlzYCBpcyBsb2FkZWQgdmlhXG4gKiBhIGd1YXJkZWQgZHluYW1pYyByZXF1aXJlIHNvIG1lcmVseSBpbXBvcnRpbmcgdGhpcyBuZXZlciBicmVha3MgYSBidWlsZC90ZXN0XG4gKiB3aGVyZSBSZWRpcyBpc24ndCBwcmVzZW50LlxuICpcbiAqIEZVTExZIEZBSUwtT1BFTjogbm8gZW52IGNvbmZpZ3VyZWQsIGFuIGlvcmVkaXMgbG9hZCBmYWlsdXJlLCBhIGNvbm5lY3QgZXJyb3IsXG4gKiBvciBhbnkgcmVhZCBmYWlsdXJlIGFsbCByZXNvbHZlIHRvIGBudWxsYCAoXCJubyBrbm93biByZXZvY2F0aW9uXCIpLCBzbyBhXG4gKiBzZXJ2aWNlIGRlZ3JhZGVzIHRvIG5hdHVyYWwgdG9rZW4gZXhwaXJ5IHJhdGhlciB0aGFuIGxvY2tpbmcgdXNlcnMgb3V0LiBBXG4gKiBzZXJ2aWNlIG9wdHMgaW4gd2l0aCBhIHNpbmdsZSBib290IGxpbmU6XG4gKiAgIGBzZXRUb2tlblJldm9jYXRpb25TdG9yZShjcmVhdGVFbnZSZWRpc1Rva2VuUmV2b2NhdGlvblN0b3JlKCkpO2BcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUVudlJlZGlzVG9rZW5SZXZvY2F0aW9uU3RvcmUoKTogVG9rZW5SZXZvY2F0aW9uU3RvcmUge1xuICB0eXBlIFJlYWRlclJlZGlzID0gUmVkaXNDYWNoZUNsaWVudCAmIFJlYWR5QXdhcmVSZWRpcztcbiAgLy8gdW5kZWZpbmVkID0gbm90IHlldCBhdHRlbXB0ZWQ7IG51bGwgPSBhdHRlbXB0ZWQgYW5kIHVuYXZhaWxhYmxlIChzdGF5IG9mZikuXG4gIGxldCBjYWNoZWQ6IFJlYWRlclJlZGlzIHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgbGV0IHJlYWR5OiAoKCkgPT4gUHJvbWlzZTx2b2lkPikgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFRoZSByZWFkZXIgY2xpZW50LCBidWlsdCBvbiBmaXJzdCB1c2UuIFRoZSBlbnYgY2xpZW50IGhhcyBubyBvZmZsaW5lIHF1ZXVlLFxuICAgKiBzbyBhIEdFVCBiZWZvcmUgdGhlIGZpcnN0IGNvbm5lY3Rpb24gY29tcGxldGVzIGlzIHJlamVjdGVkIOKAlCB3aGljaCBtYWRlIHRoZVxuICAgKiBGSVJTVCBpbXBlcnNvbmF0aW9uIGNoZWNrIG9uIGV2ZXJ5IHBvZCByZWFkICd1bmF2YWlsYWJsZScgKDQwMSkuIFdhaXRcbiAgICogKGJvdW5kZWQsIG5ldmVyIHJlamVjdGluZykgZm9yIHJlYWRpbmVzczsgYSBnZW51aW5lbHkgZG93biBSZWRpcyB0aGVuIGtlZXBzXG4gICAqIHRoZSBleGlzdGluZyBmYWlsLW9wZW4gLyAndW5hdmFpbGFibGUnIHNlbWFudGljcy5cbiAgICovXG4gIGFzeW5jIGZ1bmN0aW9uIGNsaWVudCgpOiBQcm9taXNlPFJlYWRlclJlZGlzIHwgbnVsbD4ge1xuICAgIGlmIChjYWNoZWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gU2hhcmVkIGVudi1jb25maWd1cmVkIGlvcmVkaXMgY29uc3RydWN0aW9uIChlcnJvciBsaXN0ZW5lciBhdHRhY2hlZCwgbnVsbFxuICAgICAgLy8gd2hlbiBSZWRpcyBpc24ndCBjb25maWd1cmVkKTsgdGhlIHJlYWRlciBzdGF5cyBmYWlsLW9wZW4g4oCUIGEgbnVsbCBjbGllbnRcbiAgICAgIC8vIGp1c3QgZmFsbHMgYmFjayB0byBuYXR1cmFsIHRva2VuIGV4cGlyeS5cbiAgICAgIGNhY2hlZCA9IGNyZWF0ZUVudlJlZGlzQ2xpZW50PFJlYWRlclJlZGlzPigncmV2b2NhdGlvbi1yZWFkZXInKTtcbiAgICAgIGlmIChjYWNoZWQpIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ1JlZGlzIHRva2VuLXJldm9jYXRpb24gcmVhZGVyIGluaXRpYWxpemVkJyk7XG4gICAgICAgIHJlYWR5ID0gY3JlYXRlUmVkaXNSZWFkeUdhdGUoY2FjaGVkKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHJlYWR5KSBhd2FpdCByZWFkeSgpO1xuICAgIHJldHVybiBjYWNoZWQ7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGFzeW5jIGdldEN1cnJlbnRWZXJzaW9uKHVzZXJJZDogc3RyaW5nKTogUHJvbWlzZTxudW1iZXIgfCBudWxsPiB7XG4gICAgICBjb25zdCByZWRpcyA9IGF3YWl0IGNsaWVudCgpO1xuICAgICAgaWYgKCFyZWRpcykgcmV0dXJuIG51bGw7XG4gICAgICByZXR1cm4gY3JlYXRlUmVkaXNUb2tlblJldm9jYXRpb25TdG9yZShyZWRpcykuZ2V0Q3VycmVudFZlcnNpb24odXNlcklkKTtcbiAgICB9LFxuICAgIGFzeW5jIGdldFNlc3Npb25SZXZvY2F0aW9uKGp0aTogc3RyaW5nKTogUHJvbWlzZTxTZXNzaW9uUmV2b2NhdGlvblN0YXRlPiB7XG4gICAgICBjb25zdCByZWRpcyA9IGF3YWl0IGNsaWVudCgpO1xuICAgICAgLy8gTm8gUmVkaXMgY29uZmlndXJlZCDih5IgdGhlcmUgaXMgbm8gd2F5IHRvIGxlYXJuIGEgc2Vzc2lvbiB3YXMgZW5kZWQsIHNvXG4gICAgICAvLyBhbiBpbXBlcnNvbmF0aW9uIHRva2VuIGNhbid0IGJlIHRydXN0ZWQuIEV2ZXJ5IHJlYWwgZGVwbG95bWVudCBydW5zIFJlZGlzXG4gICAgICAvLyAodGhlIGJ1aWxkIHF1ZXVlIG5lZWRzIGl0KSwgc28gdGhpcyBvbmx5IGJpdGVzIGEgbWlzY29uZmlndXJlZCBzZXJ2aWNlLlxuICAgICAgaWYgKCFyZWRpcykge1xuICAgICAgICBlbWl0Q291bnRlcignc2Vzc2lvbl9yZXZvY2F0aW9uX3VuYXZhaWxhYmxlX3RvdGFsJywgeyByZWFzb246ICdub3QtY29uZmlndXJlZCcgfSk7XG4gICAgICAgIHJldHVybiAndW5hdmFpbGFibGUnO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNyZWF0ZVJlZGlzVG9rZW5SZXZvY2F0aW9uU3RvcmUocmVkaXMpLmdldFNlc3Npb25SZXZvY2F0aW9uIShqdGkpO1xuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogUHVibGlzaCBhIHVzZXIncyBjdXJyZW50IGB0b2tlblZlcnNpb25gIHNvIHRoZSBzdGF0ZWxlc3Mgc2VydmljZXMgc2VlIHRoZVxuICogcmV2b2NhdGlvbiBpbW1lZGlhdGVseSAocGxhdGZvcm0gc2lkZSkuIEJlc3QtZWZmb3J0IOKAlCBuZXZlciB0aHJvd3M7IGEgZmFpbHVyZVxuICoganVzdCBtZWFucyB0aGUgc2VydmljZXMgZmFsbCBiYWNrIHRvIG5hdHVyYWwgdG9rZW4gZXhwaXJ5IGZvciB0aGlzIGNoYW5nZS5cbiAqXG4gKiBUaGUga2V5IGlzIHdyaXR0ZW4gd2l0aCBhIFRUTCBlcXVhbCB0byB0aGUgYWNjZXNzLXRva2VuIGxpZmV0aW1lOiBhbnkgdG9rZW5cbiAqIHRoYXQgY291bGQgc3RpbGwgY2FycnkgYW4gb2xkZXIgdmVyc2lvbiBoYXMgZXhwaXJlZCBieSB0aGUgdGltZSB0aGUgZW50cnlcbiAqIGxhcHNlcywgc28gYW4gZXhwaXJlZCBlbnRyeSBjYW4gbmV2ZXIgY2F1c2UgYSBmYWxzZSBcInJldm9rZWRcIiBub3IgYSBtaXNzZWQgb25lLlxuICpcbiAqIEBwYXJhbSByZWRpcyAtIHRoZSBwbGF0Zm9ybSdzIFJlZGlzIGNsaWVudFxuICogQHBhcmFtIHVzZXJJZCAtIHRoZSB1c2VyIHdob3NlIHNlc3Npb25zIGNoYW5nZWRcbiAqIEBwYXJhbSB0b2tlblZlcnNpb24gLSB0aGUgdXNlcidzIE5FVyAocG9zdC1pbmNyZW1lbnQpIHRva2VuVmVyc2lvblxuICogQHBhcmFtIHR0bFNlY29uZHMgLSBhY2Nlc3MtdG9rZW4gbGlmZXRpbWUgaW4gc2Vjb25kc1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHVibGlzaFRva2VuUmV2b2NhdGlvbihcbiAgcmVkaXM6IFJlZGlzQ2FjaGVDbGllbnQsXG4gIHVzZXJJZDogc3RyaW5nLFxuICB0b2tlblZlcnNpb246IG51bWJlcixcbiAgdHRsU2Vjb25kczogbnVtYmVyLFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIHRyeSB7XG4gICAgLy8gaW9yZWRpcy1zdHlsZSB2YXJpYWRpYyBTRVQgd2l0aCBleHBpcnk6IFNFVCBrZXkgdmFsIEVYIHR0bC5cbiAgICBhd2FpdCByZWRpcy5zZXQodG9rZW5SZXZvY2F0aW9uS2V5KHVzZXJJZCksIFN0cmluZyh0b2tlblZlcnNpb24pLCAnRVgnLCBNYXRoLm1heCgxLCBNYXRoLmZsb29yKHR0bFNlY29uZHMpKSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci53YXJuKCdUb2tlbi1yZXZvY2F0aW9uIHB1Ymxpc2ggZmFpbGVkIChzZXJ2aWNlcyBmYWxsIGJhY2sgdG8gdG9rZW4gZXhwaXJ5KScsIHtcbiAgICAgIHVzZXJJZCwgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpLFxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogUHVibGlzaCB0aGF0IG9uZSBJTVBFUlNPTkFUSU9OIHNlc3Npb24gaGFzIGVuZGVkLCBzbyBldmVyeSBzdGF0ZWxlc3Mgc2VydmljZVxuICogcmVqZWN0cyBpdHMgdG9rZW4gb24gdGhlIG5leHQgcmVxdWVzdCAocGxhdGZvcm0gc2lkZSkuXG4gKlxuICogUmV0dXJucyB3aGV0aGVyIHRoZSBwdWJsaXNoIGxhbmRlZCDigJQgdW5saWtlIGBwdWJsaXNoVG9rZW5SZXZvY2F0aW9uYCwgd2hpY2ggaXNcbiAqIGZpcmUtYW5kLWZvcmdldC4gVGhlIGNhbGxlciBtdXN0IGJlIGFibGUgdG8gdGVsbCB0aGUgcGVyc29uIHdobyBlbmRlZCB0aGVcbiAqIHNlc3Npb24gdGhhdCBpdCBkaWQgTk9UIGVuZCBldmVyeXdoZXJlLCByYXRoZXIgdGhhbiByZXBvcnRpbmcgc3VjY2VzcyB3aGlsZVxuICogdGhlIHRva2VuIHN0aWxsIHdvcmtzIGFnYWluc3Qgb3RoZXIgc2VydmljZXMuXG4gKlxuICogVGhlIGVudHJ5IGV4cGlyZXMgd2l0aCB0aGUgc2Vzc2lvbjogb25jZSB0aGUgdG9rZW4gaXRzZWxmIGNhbiBubyBsb25nZXIgYmVcbiAqIHVzZWQsIHRoZXJlIGlzIG5vdGhpbmcgbGVmdCB0byByZXZva2UsIHNvIHRoZSBrZXkgY2xlYW5zIGl0c2VsZiB1cC5cbiAqXG4gKiBAcGFyYW0gdHRsTXMgLSB0aW1lIHJlbWFpbmluZyBvbiB0aGUgc2Vzc2lvbidzIHRva2VuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwdWJsaXNoU2Vzc2lvblJldm9jYXRpb24oXG4gIHJlZGlzOiBSZWRpc0NhY2hlQ2xpZW50LFxuICBqdGk6IHN0cmluZyxcbiAgdHRsTXM6IG51bWJlcixcbik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICB0cnkge1xuICAgIGF3YWl0IHJlZGlzLnNldChzZXNzaW9uUmV2b2NhdGlvbktleShqdGkpLCAnMScsICdQWCcsIE1hdGgubWF4KDEwMDAsIE1hdGguY2VpbCh0dGxNcykpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nZ2VyLndhcm4oJ1Nlc3Npb24tcmV2b2NhdGlvbiBwdWJsaXNoIGZhaWxlZCAob3RoZXIgc2VydmljZXMgd2lsbCBob25vdXIgdGhlIHRva2VuIHVudGlsIGl0IGV4cGlyZXMpJywge1xuICAgICAgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpLFxuICAgIH0pO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuIl19
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Shared `@pipeline-builder/api-core` mock factory for ESM suites.
3
+ *
4
+ * WHY: every project kept its own `test/helpers/mock-api-core.ts` — twelve forks
5
+ * of the same ~150-line file, ranging from 23 to 61 overridden keys against an
6
+ * api-core barrel exporting ~357 symbols. Each fork re-declared the same logger
7
+ * stub, the same `ErrorCode` proxy, the same error classes and the same
8
+ * service-gate re-implementations, and each drifted independently.
9
+ *
10
+ * THE FIX: the shared parts live here, once. A project's helper keeps ONLY the
11
+ * defaults that are genuinely project-specific (its tier fixtures, its compliance
12
+ * client, its response helpers) and layers them on top:
13
+ *
14
+ * const actualApiCore = jest.requireActual('@pipeline-builder/api-core') as Record<string, unknown>;
15
+ * export function apiCoreMock(overrides: Record<string, unknown> = {}) {
16
+ * return baseApiCoreMock(actualApiCore, { ...projectDefaults, ...overrides });
17
+ * }
18
+ *
19
+ * Both this module and the per-project helpers start from `requireActual`, so an
20
+ * export ADDED to api-core is inherited automatically and can never again break a
21
+ * suite with "does not provide an export named X".
22
+ *
23
+ * WHY IT LIVES IN api-core: the deep path
24
+ * `@pipeline-builder/api-core/lib/testing/mock-api-core.js` is a different
25
+ * specifier from the `@pipeline-builder/api-core` barrel, so a suite's module
26
+ * mock does NOT intercept it — the factory can therefore read the real module
27
+ * without recursing into its own mock. Same trick as `tier-mock.ts`.
28
+ */
29
+ import { jest } from '@jest/globals';
30
+ /** Minimal Express-ish shapes the gate/response stubs below touch. */
31
+ type MockRes = {
32
+ status: (n: number) => {
33
+ json: (b: unknown) => unknown;
34
+ };
35
+ };
36
+ type Next = () => void;
37
+ /** A bare `jest.fn()`, named so the emitted `.d.ts` stays portable (TS2883). */
38
+ type MockFn = ReturnType<typeof jest.fn>;
39
+ /** The winston double every suite asserts on: four spies, nothing else. */
40
+ export interface MockLogger {
41
+ info: MockFn;
42
+ warn: MockFn;
43
+ error: MockFn;
44
+ debug: MockFn;
45
+ }
46
+ /** The 4-method winston stub every suite repeats; a fresh set of spies per call. */
47
+ export declare const loggerMock: () => MockLogger;
48
+ /** Mirrors api-core: `ErrorCode.ANY_CODE` resolves to the string `'ANY_CODE'`. */
49
+ export declare const mockErrorCode: Record<string, string>;
50
+ /** No-op guard: the default mock covers route wiring, not the permission gate. */
51
+ export declare const passThroughMiddleware: (_req: unknown, _res: unknown, next: Next) => void;
52
+ /** Mirrors api-core's `AppError` base (typed HTTP error: statusCode + code). */
53
+ export declare class MockAppError extends Error {
54
+ readonly statusCode: number;
55
+ readonly code: string;
56
+ constructor(statusCode: number, code: string, message?: string);
57
+ }
58
+ /** Mirrors api-core's NotFoundError (404 / NOT_FOUND). */
59
+ export declare class MockNotFoundError extends MockAppError {
60
+ constructor(message?: string);
61
+ }
62
+ /** Mirrors api-core's ConflictError (409 / CONFLICT). */
63
+ export declare class MockConflictError extends MockAppError {
64
+ constructor(message?: string);
65
+ }
66
+ /** Mirrors api-core's ForbiddenError (403 / INSUFFICIENT_PERMISSIONS). */
67
+ export declare class MockForbiddenError extends MockAppError {
68
+ constructor(message?: string);
69
+ }
70
+ /** Mirrors api-core's ValidationError (400 / VALIDATION_ERROR). */
71
+ export declare class MockValidationError extends MockAppError {
72
+ constructor(message?: string);
73
+ }
74
+ /**
75
+ * Capability-aware stand-in for api-core's `requirePermission` /
76
+ * `requireAllPermissions` gate factories. Mirrors the real gate's decision (minus
77
+ * the denial-audit side effect): superadmin passes, otherwise the caller must
78
+ * hold the permission(s); a miss is a 403 with the real message shape.
79
+ *
80
+ * `onAnonymous` picks what happens when there is no `req.user` at all: `'pass'`
81
+ * (suites with no auth layer mounted) or `'401'` (suites that drive the gate).
82
+ * `shape` picks the denial envelope the project's suites assert on.
83
+ */
84
+ export declare function mockPermissionGate(options?: {
85
+ mode?: 'some' | 'every';
86
+ allowService?: boolean;
87
+ onAnonymous?: 'pass' | '401';
88
+ shape?: 'error' | 'message';
89
+ }): (...permissions: string[]) => (req: {
90
+ user?: {
91
+ isSuperAdmin?: boolean;
92
+ permissions?: string[];
93
+ sub?: string;
94
+ };
95
+ }, res: MockRes, next: Next) => unknown;
96
+ /**
97
+ * The defaults shared by every service / package mock: the logger stub, the
98
+ * pagination constants, the inert scheduler / leader-lock / redis-audit wiring a
99
+ * boot module links at load, and the error + cache shapes. A project layers its
100
+ * own defaults on top by passing them in `overrides`.
101
+ */
102
+ export declare function serviceApiCoreDefaults(): Record<string, unknown>;
103
+ /**
104
+ * The audit / security wiring a service's boot module (`src/index.ts`,
105
+ * `src/services/audit.ts`) links at load time. Inert by default: nothing asserts
106
+ * on the registration, and pulling the real graph in would drag Redis + HTTP
107
+ * clients into every route suite.
108
+ */
109
+ export declare function serviceAuditDefaults(): Record<string, unknown>;
110
+ /**
111
+ * Build an api-core mock namespace: REAL api-core, then the shared service
112
+ * defaults, then `overrides` (a project's own defaults merged with the suite's).
113
+ *
114
+ * `actualApiCore` is supplied by the CALLER (`jest.requireActual(...)` at the top
115
+ * of the project's `test/helpers/mock-api-core.ts`) rather than resolved here.
116
+ * That is deliberate: `requireActual` on an ESM barrel only succeeds at a moment
117
+ * when nothing else is mid-`import()` of it, and the project helper — a static
118
+ * import of the test file, evaluated before any `await import(SUT)` — is the one
119
+ * point where that always holds. Resolving it from inside this module (which
120
+ * lives in the api-core package itself) races that import in some suites.
121
+ */
122
+ export declare function baseApiCoreMock(actualApiCore: Record<string, unknown>, overrides?: Record<string, unknown>): Record<string, unknown>;
123
+ /**
124
+ * Build an api-core mock namespace with NO service defaults — REAL api-core plus
125
+ * the logger stub and `ErrorCode` proxy only. Platform uses this: it deliberately
126
+ * keeps api-core's real pagination/report constants and supplies its own
127
+ * (large) identity/tier/permission default set.
128
+ */
129
+ export declare function primitiveApiCoreMock(actualApiCore: Record<string, unknown>, overrides?: Record<string, unknown>): Record<string, unknown>;
130
+ /**
131
+ * Mirror api-core's `requireInternalService({ callers })`: refuse any user token,
132
+ * then refuse a service whose name is not in the route's caller list. Resolved
133
+ * from the MERGED mock (rather than inherited from `requireActual`) so it uses
134
+ * the suite's `isServicePrincipal` / `serviceNameOf` / `sendError`, which the real
135
+ * one closes over and would write past.
136
+ */
137
+ export declare function withInternalServiceGate(mock: Record<string, unknown>, overrides: Record<string, unknown>): Record<string, unknown>;
138
+ /**
139
+ * Mirror api-core's `requireServicePrincipal`: reject a non-service caller with a
140
+ * 403 INSUFFICIENT_PERMISSIONS (an authorization refusal, not a 400), resolving
141
+ * `isServicePrincipal` / `sendError` from the merged mock.
142
+ */
143
+ export declare function withServicePrincipalGate(mock: Record<string, unknown>, overrides: Record<string, unknown>): Record<string, unknown>;
144
+ /**
145
+ * `sendBadRequest` delegating to the (possibly-overridden) `sendError`, mirroring
146
+ * the real implementation — so a suite spying on `sendError` also observes the
147
+ * 400s routed through `sendBadRequest`.
148
+ */
149
+ export declare function withDelegatingSendBadRequest(mock: Record<string, unknown>, overrides: Record<string, unknown>): Record<string, unknown>;
150
+ export {};
@@ -0,0 +1,246 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * Shared `@pipeline-builder/api-core` mock factory for ESM suites.
5
+ *
6
+ * WHY: every project kept its own `test/helpers/mock-api-core.ts` — twelve forks
7
+ * of the same ~150-line file, ranging from 23 to 61 overridden keys against an
8
+ * api-core barrel exporting ~357 symbols. Each fork re-declared the same logger
9
+ * stub, the same `ErrorCode` proxy, the same error classes and the same
10
+ * service-gate re-implementations, and each drifted independently.
11
+ *
12
+ * THE FIX: the shared parts live here, once. A project's helper keeps ONLY the
13
+ * defaults that are genuinely project-specific (its tier fixtures, its compliance
14
+ * client, its response helpers) and layers them on top:
15
+ *
16
+ * const actualApiCore = jest.requireActual('@pipeline-builder/api-core') as Record<string, unknown>;
17
+ * export function apiCoreMock(overrides: Record<string, unknown> = {}) {
18
+ * return baseApiCoreMock(actualApiCore, { ...projectDefaults, ...overrides });
19
+ * }
20
+ *
21
+ * Both this module and the per-project helpers start from `requireActual`, so an
22
+ * export ADDED to api-core is inherited automatically and can never again break a
23
+ * suite with "does not provide an export named X".
24
+ *
25
+ * WHY IT LIVES IN api-core: the deep path
26
+ * `@pipeline-builder/api-core/lib/testing/mock-api-core.js` is a different
27
+ * specifier from the `@pipeline-builder/api-core` barrel, so a suite's module
28
+ * mock does NOT intercept it — the factory can therefore read the real module
29
+ * without recursing into its own mock. Same trick as `tier-mock.ts`.
30
+ */
31
+ import { jest } from '@jest/globals';
32
+ /** The 4-method winston stub every suite repeats; a fresh set of spies per call. */
33
+ export const loggerMock = () => ({
34
+ info: jest.fn(),
35
+ warn: jest.fn(),
36
+ error: jest.fn(),
37
+ debug: jest.fn(),
38
+ });
39
+ /** Mirrors api-core: `ErrorCode.ANY_CODE` resolves to the string `'ANY_CODE'`. */
40
+ export const mockErrorCode = new Proxy({}, { get: (_t, key) => key });
41
+ /** No-op guard: the default mock covers route wiring, not the permission gate. */
42
+ export const passThroughMiddleware = (_req, _res, next) => next();
43
+ /** Mirrors api-core's `AppError` base (typed HTTP error: statusCode + code). */
44
+ export class MockAppError extends Error {
45
+ statusCode;
46
+ code;
47
+ constructor(statusCode, code, message) {
48
+ super(message);
49
+ this.statusCode = statusCode;
50
+ this.code = code;
51
+ this.name = 'AppError';
52
+ }
53
+ }
54
+ /** Mirrors api-core's NotFoundError (404 / NOT_FOUND). */
55
+ export class MockNotFoundError extends MockAppError {
56
+ constructor(message) {
57
+ super(404, 'NOT_FOUND', message);
58
+ this.name = 'NotFoundError';
59
+ }
60
+ }
61
+ /** Mirrors api-core's ConflictError (409 / CONFLICT). */
62
+ export class MockConflictError extends MockAppError {
63
+ constructor(message) {
64
+ super(409, 'CONFLICT', message);
65
+ this.name = 'ConflictError';
66
+ }
67
+ }
68
+ /** Mirrors api-core's ForbiddenError (403 / INSUFFICIENT_PERMISSIONS). */
69
+ export class MockForbiddenError extends MockAppError {
70
+ constructor(message) {
71
+ super(403, 'INSUFFICIENT_PERMISSIONS', message);
72
+ this.name = 'ForbiddenError';
73
+ }
74
+ }
75
+ /** Mirrors api-core's ValidationError (400 / VALIDATION_ERROR). */
76
+ export class MockValidationError extends MockAppError {
77
+ constructor(message) {
78
+ super(400, 'VALIDATION_ERROR', message);
79
+ this.name = 'ValidationError';
80
+ }
81
+ }
82
+ /**
83
+ * Capability-aware stand-in for api-core's `requirePermission` /
84
+ * `requireAllPermissions` gate factories. Mirrors the real gate's decision (minus
85
+ * the denial-audit side effect): superadmin passes, otherwise the caller must
86
+ * hold the permission(s); a miss is a 403 with the real message shape.
87
+ *
88
+ * `onAnonymous` picks what happens when there is no `req.user` at all: `'pass'`
89
+ * (suites with no auth layer mounted) or `'401'` (suites that drive the gate).
90
+ * `shape` picks the denial envelope the project's suites assert on.
91
+ */
92
+ export function mockPermissionGate(options = {}) {
93
+ const { mode = 'some', allowService = false, onAnonymous = 'pass', shape = 'message' } = options;
94
+ const joiner = mode === 'some' ? ' or ' : ' and ';
95
+ const deny = (msg) => (shape === 'error' ? { error: msg } : { success: false, message: msg });
96
+ return (...permissions) => {
97
+ const gate = (req, res, next) => {
98
+ const user = req?.user;
99
+ if (!user)
100
+ return onAnonymous === 'pass' ? next() : res.status(401).json({ error: 'Authentication required' });
101
+ if (allowService && typeof user.sub === 'string' && user.sub.startsWith('service:'))
102
+ return next();
103
+ if (user.isSuperAdmin === true)
104
+ return next();
105
+ const held = Array.isArray(user.permissions) ? user.permissions : [];
106
+ const ok = mode === 'some' ? permissions.some((p) => held.includes(p)) : permissions.every((p) => held.includes(p));
107
+ if (ok)
108
+ return next();
109
+ return res.status(403).json(deny(`Missing required permission: ${permissions.join(joiner)}`));
110
+ };
111
+ // Tags let a wiring suite locate the gate layer in a router stack and assert
112
+ // which flavour was mounted.
113
+ gate.__permission = permissions.join(joiner);
114
+ gate.__allowService = allowService;
115
+ return gate;
116
+ };
117
+ }
118
+ /**
119
+ * The defaults shared by every service / package mock: the logger stub, the
120
+ * pagination constants, the inert scheduler / leader-lock / redis-audit wiring a
121
+ * boot module links at load, and the error + cache shapes. A project layers its
122
+ * own defaults on top by passing them in `overrides`.
123
+ */
124
+ export function serviceApiCoreDefaults() {
125
+ return {
126
+ createLogger: loggerMock,
127
+ MAX_PAGE_LIMIT: 1000,
128
+ DEFAULT_PAGE_LIMIT: 100,
129
+ closeLeaderLock: async () => undefined,
130
+ loadAndRestore: async () => null,
131
+ REPORT_INTERVALS: ['day', 'week', 'month'],
132
+ scrubAwsIdentifiersFromString: (s) => s,
133
+ scrubAwsIdentifiers: (v) => v,
134
+ createScheduler: () => ({ start: () => undefined, stop: () => undefined }),
135
+ createEnvRedisLock: () => null,
136
+ requireStepUp: (_req, _res, next) => next(),
137
+ SYSTEM_ORG_ID: '000000000000000000000001',
138
+ ComputeType: { SMALL: 'SMALL', MEDIUM: 'MEDIUM', LARGE: 'LARGE', X2_LARGE: 'X2_LARGE' },
139
+ PluginType: { CODE_BUILD_STEP: 'CodeBuildStep', SHELL_STEP: 'ShellStep', MANUAL_APPROVAL_STEP: 'ManualApprovalStep' },
140
+ ErrorCode: mockErrorCode,
141
+ errorMessage: (e) => (e instanceof Error ? e.message : String(e)),
142
+ NotFoundError: MockNotFoundError,
143
+ createCacheService: () => ({
144
+ getOrSet: (_key, factory) => factory(),
145
+ invalidatePattern: () => Promise.resolve(0),
146
+ }),
147
+ };
148
+ }
149
+ /**
150
+ * The audit / security wiring a service's boot module (`src/index.ts`,
151
+ * `src/services/audit.ts`) links at load time. Inert by default: nothing asserts
152
+ * on the registration, and pulling the real graph in would drag Redis + HTTP
153
+ * clients into every route suite.
154
+ */
155
+ export function serviceAuditDefaults() {
156
+ return {
157
+ createRemoteAuditClient: () => ({ record: jest.fn() }),
158
+ createEnvRedisAuditSpool: () => null,
159
+ createServiceAuditClient: () => ({ emit: jest.fn(), client: { record: jest.fn() } }),
160
+ createRemoteAuditAccessor: () => ({ getAuditClient: () => ({ record: jest.fn() }), emit: jest.fn() }),
161
+ setAuthzDenialAuditor: () => { },
162
+ wireAuthzDenialAuditor: () => { },
163
+ wireServiceSecurity: () => { },
164
+ setTokenRevocationStore: () => { },
165
+ createRedisTokenRevocationStore: () => ({ getCurrentVersion: async () => null }),
166
+ createEnvRedisTokenRevocationStore: () => ({ getCurrentVersion: async () => null }),
167
+ };
168
+ }
169
+ /**
170
+ * Build an api-core mock namespace: REAL api-core, then the shared service
171
+ * defaults, then `overrides` (a project's own defaults merged with the suite's).
172
+ *
173
+ * `actualApiCore` is supplied by the CALLER (`jest.requireActual(...)` at the top
174
+ * of the project's `test/helpers/mock-api-core.ts`) rather than resolved here.
175
+ * That is deliberate: `requireActual` on an ESM barrel only succeeds at a moment
176
+ * when nothing else is mid-`import()` of it, and the project helper — a static
177
+ * import of the test file, evaluated before any `await import(SUT)` — is the one
178
+ * point where that always holds. Resolving it from inside this module (which
179
+ * lives in the api-core package itself) races that import in some suites.
180
+ */
181
+ export function baseApiCoreMock(actualApiCore, overrides = {}) {
182
+ return { ...actualApiCore, ...serviceApiCoreDefaults(), ...overrides };
183
+ }
184
+ /**
185
+ * Build an api-core mock namespace with NO service defaults — REAL api-core plus
186
+ * the logger stub and `ErrorCode` proxy only. Platform uses this: it deliberately
187
+ * keeps api-core's real pagination/report constants and supplies its own
188
+ * (large) identity/tier/permission default set.
189
+ */
190
+ export function primitiveApiCoreMock(actualApiCore, overrides = {}) {
191
+ return { ...actualApiCore, createLogger: loggerMock, ErrorCode: mockErrorCode, ...overrides };
192
+ }
193
+ /**
194
+ * Mirror api-core's `requireInternalService({ callers })`: refuse any user token,
195
+ * then refuse a service whose name is not in the route's caller list. Resolved
196
+ * from the MERGED mock (rather than inherited from `requireActual`) so it uses
197
+ * the suite's `isServicePrincipal` / `serviceNameOf` / `sendError`, which the real
198
+ * one closes over and would write past.
199
+ */
200
+ export function withInternalServiceGate(mock, overrides) {
201
+ if (overrides.requireInternalService !== undefined)
202
+ return mock;
203
+ mock.requireInternalService = ({ callers }) => (req, res, next) => {
204
+ const isSvc = mock.isServicePrincipal;
205
+ const nameOf = mock.serviceNameOf;
206
+ const caller = nameOf?.(req.user);
207
+ if (isSvc?.(req) && caller && callers.includes(caller)) {
208
+ next();
209
+ return;
210
+ }
211
+ const sendError = mock.sendError;
212
+ sendError(res, 403, 'Internal service calls only', 'INSUFFICIENT_PERMISSIONS');
213
+ };
214
+ return mock;
215
+ }
216
+ /**
217
+ * Mirror api-core's `requireServicePrincipal`: reject a non-service caller with a
218
+ * 403 INSUFFICIENT_PERMISSIONS (an authorization refusal, not a 400), resolving
219
+ * `isServicePrincipal` / `sendError` from the merged mock.
220
+ */
221
+ export function withServicePrincipalGate(mock, overrides) {
222
+ if (overrides.requireServicePrincipal !== undefined)
223
+ return mock;
224
+ mock.requireServicePrincipal = (req, res, next) => {
225
+ const isSvc = mock.isServicePrincipal;
226
+ if (isSvc?.(req)) {
227
+ next();
228
+ return;
229
+ }
230
+ const sendError = mock.sendError;
231
+ sendError(res, 403, 'Internal service calls only', 'INSUFFICIENT_PERMISSIONS');
232
+ };
233
+ return mock;
234
+ }
235
+ /**
236
+ * `sendBadRequest` delegating to the (possibly-overridden) `sendError`, mirroring
237
+ * the real implementation — so a suite spying on `sendError` also observes the
238
+ * 400s routed through `sendBadRequest`.
239
+ */
240
+ export function withDelegatingSendBadRequest(mock, overrides) {
241
+ if ('sendBadRequest' in overrides)
242
+ return mock;
243
+ mock.sendBadRequest = (res, message, code) => mock.sendError(res, 400, message, code ?? mockErrorCode.VALIDATION_ERROR);
244
+ return mock;
245
+ }
246
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9jay1hcGktY29yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0aW5nL21vY2stYXBpLWNvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMkJHO0FBRUgsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQWlCckMsb0ZBQW9GO0FBQ3BGLE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRyxHQUFlLEVBQUUsQ0FBQyxDQUFDO0lBQzNDLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFO0lBQ2YsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUU7SUFDZixLQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRTtJQUNoQixLQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRTtDQUNqQixDQUFDLENBQUM7QUFFSCxrRkFBa0Y7QUFDbEYsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLElBQUksS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUEyQixDQUFDO0FBRWhHLGtGQUFrRjtBQUNsRixNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxDQUFDLElBQWEsRUFBRSxJQUFhLEVBQUUsSUFBVSxFQUFRLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUVoRyxnRkFBZ0Y7QUFDaEYsTUFBTSxPQUFPLFlBQWEsU0FBUSxLQUFLO0lBQ1QsVUFBVTtJQUEwQixJQUFJO0lBQXBFLFlBQTRCLFVBQWtCLEVBQWtCLElBQVksRUFBRSxPQUFnQjtRQUM1RixLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7MEJBRFcsVUFBVTtvQkFBMEIsSUFBSTtRQUVsRSxJQUFJLENBQUMsSUFBSSxHQUFHLFVBQVUsQ0FBQztJQUN6QixD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QUUsR0FBWSxFQUFFLElBQVUsRUFBRSxFQUFFO1FBQ3hFLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxrQkFBMkQsQ0FBQztRQUMvRSxJQUFJLEtBQUssRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDakIsSUFBSSxFQUFFLENBQUM7WUFDUCxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFxRSxDQUFDO1FBQzdGLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLDZCQUE2QixFQUFFLDBCQUEwQixDQUFDLENBQUM7SUFDakYsQ0FBQyxDQUFDO0lBQ0YsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSw0QkFBNEIsQ0FBQyxJQUE2QixFQUFFLFNBQWtDO0lBQzVHLElBQUksZ0JBQWdCLElBQUksU0FBUztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQy9DLElBQUksQ0FBQyxjQUFjLEdBQUcsQ0FBQyxHQUFZLEVBQUUsT0FBZSxFQUFFLElBQWEsRUFBRSxFQUFFLENBQ3BFLElBQUksQ0FBQyxTQUF1RSxDQUMzRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxJQUFJLElBQUksYUFBYSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDL0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogU2hhcmVkIGBAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZWAgbW9jayBmYWN0b3J5IGZvciBFU00gc3VpdGVzLlxuICpcbiAqIFdIWTogZXZlcnkgcHJvamVjdCBrZXB0IGl0cyBvd24gYHRlc3QvaGVscGVycy9tb2NrLWFwaS1jb3JlLnRzYCDigJQgdHdlbHZlIGZvcmtzXG4gKiBvZiB0aGUgc2FtZSB+MTUwLWxpbmUgZmlsZSwgcmFuZ2luZyBmcm9tIDIzIHRvIDYxIG92ZXJyaWRkZW4ga2V5cyBhZ2FpbnN0IGFuXG4gKiBhcGktY29yZSBiYXJyZWwgZXhwb3J0aW5nIH4zNTcgc3ltYm9scy4gRWFjaCBmb3JrIHJlLWRlY2xhcmVkIHRoZSBzYW1lIGxvZ2dlclxuICogc3R1YiwgdGhlIHNhbWUgYEVycm9yQ29kZWAgcHJveHksIHRoZSBzYW1lIGVycm9yIGNsYXNzZXMgYW5kIHRoZSBzYW1lXG4gKiBzZXJ2aWNlLWdhdGUgcmUtaW1wbGVtZW50YXRpb25zLCBhbmQgZWFjaCBkcmlmdGVkIGluZGVwZW5kZW50bHkuXG4gKlxuICogVEhFIEZJWDogdGhlIHNoYXJlZCBwYXJ0cyBsaXZlIGhlcmUsIG9uY2UuIEEgcHJvamVjdCdzIGhlbHBlciBrZWVwcyBPTkxZIHRoZVxuICogZGVmYXVsdHMgdGhhdCBhcmUgZ2VudWluZWx5IHByb2plY3Qtc3BlY2lmaWMgKGl0cyB0aWVyIGZpeHR1cmVzLCBpdHMgY29tcGxpYW5jZVxuICogY2xpZW50LCBpdHMgcmVzcG9uc2UgaGVscGVycykgYW5kIGxheWVycyB0aGVtIG9uIHRvcDpcbiAqXG4gKiAgIGNvbnN0IGFjdHVhbEFwaUNvcmUgPSBqZXN0LnJlcXVpcmVBY3R1YWwoJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJykgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gKiAgIGV4cG9ydCBmdW5jdGlvbiBhcGlDb3JlTW9jayhvdmVycmlkZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge30pIHtcbiAqICAgICByZXR1cm4gYmFzZUFwaUNvcmVNb2NrKGFjdHVhbEFwaUNvcmUsIHsgLi4ucHJvamVjdERlZmF1bHRzLCAuLi5vdmVycmlkZXMgfSk7XG4gKiAgIH1cbiAqXG4gKiBCb3RoIHRoaXMgbW9kdWxlIGFuZCB0aGUgcGVyLXByb2plY3QgaGVscGVycyBzdGFydCBmcm9tIGByZXF1aXJlQWN0dWFsYCwgc28gYW5cbiAqIGV4cG9ydCBBRERFRCB0byBhcGktY29yZSBpcyBpbmhlcml0ZWQgYXV0b21hdGljYWxseSBhbmQgY2FuIG5ldmVyIGFnYWluIGJyZWFrIGFcbiAqIHN1aXRlIHdpdGggXCJkb2VzIG5vdCBwcm92aWRlIGFuIGV4cG9ydCBuYW1lZCBYXCIuXG4gKlxuICogV0hZIElUIExJVkVTIElOIGFwaS1jb3JlOiB0aGUgZGVlcCBwYXRoXG4gKiBgQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUvbGliL3Rlc3RpbmcvbW9jay1hcGktY29yZS5qc2AgaXMgYSBkaWZmZXJlbnRcbiAqIHNwZWNpZmllciBmcm9tIHRoZSBgQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmVgIGJhcnJlbCwgc28gYSBzdWl0ZSdzIG1vZHVsZVxuICogbW9jayBkb2VzIE5PVCBpbnRlcmNlcHQgaXQg4oCUIHRoZSBmYWN0b3J5IGNhbiB0aGVyZWZvcmUgcmVhZCB0aGUgcmVhbCBtb2R1bGVcbiAqIHdpdGhvdXQgcmVjdXJzaW5nIGludG8gaXRzIG93biBtb2NrLiBTYW1lIHRyaWNrIGFzIGB0aWVyLW1vY2sudHNgLlxuICovXG5cbmltcG9ydCB7IGplc3QgfSBmcm9tICdAamVzdC9nbG9iYWxzJztcblxuLyoqIE1pbmltYWwgRXhwcmVzcy1pc2ggc2hhcGVzIHRoZSBnYXRlL3Jlc3BvbnNlIHN0dWJzIGJlbG93IHRvdWNoLiAqL1xudHlwZSBNb2NrUmVzID0geyBzdGF0dXM6IChuOiBudW1iZXIpID0+IHsganNvbjogKGI6IHVua25vd24pID0+IHVua25vd24gfSB9O1xudHlwZSBOZXh0ID0gKCkgPT4gdm9pZDtcblxuLyoqIEEgYmFyZSBgamVzdC5mbigpYCwgbmFtZWQgc28gdGhlIGVtaXR0ZWQgYC5kLnRzYCBzdGF5cyBwb3J0YWJsZSAoVFMyODgzKS4gKi9cbnR5cGUgTW9ja0ZuID0gUmV0dXJuVHlwZTx0eXBlb2YgamVzdC5mbj47XG5cbi8qKiBUaGUgd2luc3RvbiBkb3VibGUgZXZlcnkgc3VpdGUgYXNzZXJ0cyBvbjogZm91ciBzcGllcywgbm90aGluZyBlbHNlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBNb2NrTG9nZ2VyIHtcbiAgaW5mbzogTW9ja0ZuO1xuICB3YXJuOiBNb2NrRm47XG4gIGVycm9yOiBNb2NrRm47XG4gIGRlYnVnOiBNb2NrRm47XG59XG5cbi8qKiBUaGUgNC1tZXRob2Qgd2luc3RvbiBzdHViIGV2ZXJ5IHN1aXRlIHJlcGVhdHM7IGEgZnJlc2ggc2V0IG9mIHNwaWVzIHBlciBjYWxsLiAqL1xuZXhwb3J0IGNvbnN0IGxvZ2dlck1vY2sgPSAoKTogTW9ja0xvZ2dlciA9PiAoe1xuICBpbmZvOiBqZXN0LmZuKCksXG4gIHdhcm46IGplc3QuZm4oKSxcbiAgZXJyb3I6IGplc3QuZm4oKSxcbiAgZGVidWc6IGplc3QuZm4oKSxcbn0pO1xuXG4vKiogTWlycm9ycyBhcGktY29yZTogYEVycm9yQ29kZS5BTllfQ09ERWAgcmVzb2x2ZXMgdG8gdGhlIHN0cmluZyBgJ0FOWV9DT0RFJ2AuICovXG5leHBvcnQgY29uc3QgbW9ja0Vycm9yQ29kZSA9IG5ldyBQcm94eSh7fSwgeyBnZXQ6IChfdCwga2V5KSA9PiBrZXkgfSkgYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcblxuLyoqIE5vLW9wIGd1YXJkOiB0aGUgZGVmYXVsdCBtb2NrIGNvdmVycyByb3V0ZSB3aXJpbmcsIG5vdCB0aGUgcGVybWlzc2lvbiBnYXRlLiAqL1xuZXhwb3J0IGNvbnN0IHBhc3NUaHJvdWdoTWlkZGxld2FyZSA9IChfcmVxOiB1bmtub3duLCBfcmVzOiB1bmtub3duLCBuZXh0OiBOZXh0KTogdm9pZCA9PiBuZXh0KCk7XG5cbi8qKiBNaXJyb3JzIGFwaS1jb3JlJ3MgYEFwcEVycm9yYCBiYXNlICh0eXBlZCBIVFRQIGVycm9yOiBzdGF0dXNDb2RlICsgY29kZSkuICovXG5leHBvcnQgY2xhc3MgTW9ja0FwcEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgc3RhdHVzQ29kZTogbnVtYmVyLCBwdWJsaWMgcmVhZG9ubHkgY29kZTogc3RyaW5nLCBtZXNzYWdlPzogc3RyaW5nKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgdGhpcy5uYW1lID0gJ0FwcEVycm9yJztcbiAgfVxufVxuXG4vKiogTWlycm9ycyBhcGktY29yZSdzIE5vdEZvdW5kRXJyb3IgKDQwNCAvIE5PVF9GT1VORCkuICovXG5leHBvcnQgY2xhc3MgTW9ja05vdEZvdW5kRXJyb3IgZXh0ZW5kcyBNb2NrQXBwRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlPzogc3RyaW5nKSB7XG4gICAgc3VwZXIoNDA0LCAnTk9UX0ZPVU5EJywgbWVzc2FnZSk7XG4gICAgdGhpcy5uYW1lID0gJ05vdEZvdW5kRXJyb3InO1xuICB9XG59XG5cbi8qKiBNaXJyb3JzIGFwaS1jb3JlJ3MgQ29uZmxpY3RFcnJvciAoNDA5IC8gQ09ORkxJQ1QpLiAqL1xuZXhwb3J0IGNsYXNzIE1vY2tDb25mbGljdEVycm9yIGV4dGVuZHMgTW9ja0FwcEVycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZT86IHN0cmluZykge1xuICAgIHN1cGVyKDQwOSwgJ0NPTkZMSUNUJywgbWVzc2FnZSk7XG4gICAgdGhpcy5uYW1lID0gJ0NvbmZsaWN0RXJyb3InO1xuICB9XG59XG5cbi8qKiBNaXJyb3JzIGFwaS1jb3JlJ3MgRm9yYmlkZGVuRXJyb3IgKDQwMyAvIElOU1VGRklDSUVOVF9QRVJNSVNTSU9OUykuICovXG5leHBvcnQgY2xhc3MgTW9ja0ZvcmJpZGRlbkVycm9yIGV4dGVuZHMgTW9ja0FwcEVycm9yIHtcbiAgY29uc3RydWN0b3IobWVzc2FnZT86IHN0cmluZykge1xuICAgIHN1cGVyKDQwMywgJ0lOU1VGRklDSUVOVF9QRVJNSVNTSU9OUycsIG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9ICdGb3JiaWRkZW5FcnJvcic7XG4gIH1cbn1cblxuLyoqIE1pcnJvcnMgYXBpLWNvcmUncyBWYWxpZGF0aW9uRXJyb3IgKDQwMCAvIFZBTElEQVRJT05fRVJST1IpLiAqL1xuZXhwb3J0IGNsYXNzIE1vY2tWYWxpZGF0aW9uRXJyb3IgZXh0ZW5kcyBNb2NrQXBwRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlPzogc3RyaW5nKSB7XG4gICAgc3VwZXIoNDAwLCAnVkFMSURBVElPTl9FUlJPUicsIG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9ICdWYWxpZGF0aW9uRXJyb3InO1xuICB9XG59XG5cbi8qKlxuICogQ2FwYWJpbGl0eS1hd2FyZSBzdGFuZC1pbiBmb3IgYXBpLWNvcmUncyBgcmVxdWlyZVBlcm1pc3Npb25gIC9cbiAqIGByZXF1aXJlQWxsUGVybWlzc2lvbnNgIGdhdGUgZmFjdG9yaWVzLiBNaXJyb3JzIHRoZSByZWFsIGdhdGUncyBkZWNpc2lvbiAobWludXNcbiAqIHRoZSBkZW5pYWwtYXVkaXQgc2lkZSBlZmZlY3QpOiBzdXBlcmFkbWluIHBhc3Nlcywgb3RoZXJ3aXNlIHRoZSBjYWxsZXIgbXVzdFxuICogaG9sZCB0aGUgcGVybWlzc2lvbihzKTsgYSBtaXNzIGlzIGEgNDAzIHdpdGggdGhlIHJlYWwgbWVzc2FnZSBzaGFwZS5cbiAqXG4gKiBgb25Bbm9ueW1vdXNgIHBpY2tzIHdoYXQgaGFwcGVucyB3aGVuIHRoZXJlIGlzIG5vIGByZXEudXNlcmAgYXQgYWxsOiBgJ3Bhc3MnYFxuICogKHN1aXRlcyB3aXRoIG5vIGF1dGggbGF5ZXIgbW91bnRlZCkgb3IgYCc0MDEnYCAoc3VpdGVzIHRoYXQgZHJpdmUgdGhlIGdhdGUpLlxuICogYHNoYXBlYCBwaWNrcyB0aGUgZGVuaWFsIGVudmVsb3BlIHRoZSBwcm9qZWN0J3Mgc3VpdGVzIGFzc2VydCBvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vY2tQZXJtaXNzaW9uR2F0ZShvcHRpb25zOiB7XG4gIG1vZGU/OiAnc29tZScgfCAnZXZlcnknO1xuICBhbGxvd1NlcnZpY2U/OiBib29sZWFuO1xuICBvbkFub255bW91cz86ICdwYXNzJyB8ICc0MDEnO1xuICBzaGFwZT86ICdlcnJvcicgfCAnbWVzc2FnZSc7XG59ID0ge30pIHtcbiAgY29uc3QgeyBtb2RlID0gJ3NvbWUnLCBhbGxvd1NlcnZpY2UgPSBmYWxzZSwgb25Bbm9ueW1vdXMgPSAncGFzcycsIHNoYXBlID0gJ21lc3NhZ2UnIH0gPSBvcHRpb25zO1xuICBjb25zdCBqb2luZXIgPSBtb2RlID09PSAnc29tZScgPyAnIG9yICcgOiAnIGFuZCAnO1xuICBjb25zdCBkZW55ID0gKG1zZzogc3RyaW5nKSA9PiAoc2hhcGUgPT09ICdlcnJvcicgPyB7IGVycm9yOiBtc2cgfSA6IHsgc3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6IG1zZyB9KTtcbiAgcmV0dXJuICguLi5wZXJtaXNzaW9uczogc3RyaW5nW10pID0+IHtcbiAgICBjb25zdCBnYXRlID0gKHJlcTogeyB1c2VyPzogeyBpc1N1cGVyQWRtaW4/OiBib29sZWFuOyBwZXJtaXNzaW9ucz86IHN0cmluZ1tdOyBzdWI/OiBzdHJpbmcgfSB9LCByZXM6IE1vY2tSZXMsIG5leHQ6IE5leHQpOiB1bmtub3duID0+IHtcbiAgICAgIGNvbnN0IHVzZXIgPSByZXE/LnVzZXI7XG4gICAgICBpZiAoIXVzZXIpIHJldHVybiBvbkFub255bW91cyA9PT0gJ3Bhc3MnID8gbmV4dCgpIDogcmVzLnN0YXR1cyg0MDEpLmpzb24oeyBlcnJvcjogJ0F1dGhlbnRpY2F0aW9uIHJlcXVpcmVkJyB9KTtcbiAgICAgIGlmIChhbGxvd1NlcnZpY2UgJiYgdHlwZW9mIHVzZXIuc3ViID09PSAnc3RyaW5nJyAmJiB1c2VyLnN1Yi5zdGFydHNXaXRoKCdzZXJ2aWNlOicpKSByZXR1cm4gbmV4dCgpO1xuICAgICAgaWYgKHVzZXIuaXNTdXBlckFkbWluID09PSB0cnVlKSByZXR1cm4gbmV4dCgpO1xuICAgICAgY29uc3QgaGVsZCA9IEFycmF5LmlzQXJyYXkodXNlci5wZXJtaXNzaW9ucykgPyB1c2VyLnBlcm1pc3Npb25zIDogW107XG4gICAgICBjb25zdCBvayA9IG1vZGUgPT09ICdzb21lJyA/IHBlcm1pc3Npb25zLnNvbWUoKHApID0+IGhlbGQuaW5jbHVkZXMocCkpIDogcGVybWlzc2lvbnMuZXZlcnkoKHApID0+IGhlbGQuaW5jbHVkZXMocCkpO1xuICAgICAgaWYgKG9rKSByZXR1cm4gbmV4dCgpO1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAzKS5qc29uKGRlbnkoYE1pc3NpbmcgcmVxdWlyZWQgcGVybWlzc2lvbjogJHtwZXJtaXNzaW9ucy5qb2luKGpvaW5lcil9YCkpO1xuICAgIH07XG4gICAgLy8gVGFncyBsZXQgYSB3aXJpbmcgc3VpdGUgbG9jYXRlIHRoZSBnYXRlIGxheWVyIGluIGEgcm91dGVyIHN0YWNrIGFuZCBhc3NlcnRcbiAgICAvLyB3aGljaCBmbGF2b3VyIHdhcyBtb3VudGVkLlxuICAgIChnYXRlIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLl9fcGVybWlzc2lvbiA9IHBlcm1pc3Npb25zLmpvaW4oam9pbmVyKTtcbiAgICAoZ2F0ZSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5fX2FsbG93U2VydmljZSA9IGFsbG93U2VydmljZTtcbiAgICByZXR1cm4gZ2F0ZTtcbiAgfTtcbn1cblxuLyoqXG4gKiBUaGUgZGVmYXVsdHMgc2hhcmVkIGJ5IGV2ZXJ5IHNlcnZpY2UgLyBwYWNrYWdlIG1vY2s6IHRoZSBsb2dnZXIgc3R1YiwgdGhlXG4gKiBwYWdpbmF0aW9uIGNvbnN0YW50cywgdGhlIGluZXJ0IHNjaGVkdWxlciAvIGxlYWRlci1sb2NrIC8gcmVkaXMtYXVkaXQgd2lyaW5nIGFcbiAqIGJvb3QgbW9kdWxlIGxpbmtzIGF0IGxvYWQsIGFuZCB0aGUgZXJyb3IgKyBjYWNoZSBzaGFwZXMuIEEgcHJvamVjdCBsYXllcnMgaXRzXG4gKiBvd24gZGVmYXVsdHMgb24gdG9wIGJ5IHBhc3NpbmcgdGhlbSBpbiBgb3ZlcnJpZGVzYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlcnZpY2VBcGlDb3JlRGVmYXVsdHMoKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICByZXR1cm4ge1xuICAgIGNyZWF0ZUxvZ2dlcjogbG9nZ2VyTW9jayxcbiAgICBNQVhfUEFHRV9MSU1JVDogMTAwMCxcbiAgICBERUZBVUxUX1BBR0VfTElNSVQ6IDEwMCxcbiAgICBjbG9zZUxlYWRlckxvY2s6IGFzeW5jICgpID0+IHVuZGVmaW5lZCxcbiAgICBsb2FkQW5kUmVzdG9yZTogYXN5bmMgKCkgPT4gbnVsbCxcbiAgICBSRVBPUlRfSU5URVJWQUxTOiBbJ2RheScsICd3ZWVrJywgJ21vbnRoJ10sXG4gICAgc2NydWJBd3NJZGVudGlmaWVyc0Zyb21TdHJpbmc6IChzOiBzdHJpbmcpID0+IHMsXG4gICAgc2NydWJBd3NJZGVudGlmaWVyczogPFQ+KHY6IFQpOiBUID0+IHYsXG4gICAgY3JlYXRlU2NoZWR1bGVyOiAoKSA9PiAoeyBzdGFydDogKCkgPT4gdW5kZWZpbmVkLCBzdG9wOiAoKSA9PiB1bmRlZmluZWQgfSksXG4gICAgY3JlYXRlRW52UmVkaXNMb2NrOiAoKSA9PiBudWxsLFxuICAgIHJlcXVpcmVTdGVwVXA6IChfcmVxOiB1bmtub3duLCBfcmVzOiB1bmtub3duLCBuZXh0OiBOZXh0KSA9PiBuZXh0KCksXG4gICAgU1lTVEVNX09SR19JRDogJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMScsXG4gICAgQ29tcHV0ZVR5cGU6IHsgU01BTEw6ICdTTUFMTCcsIE1FRElVTTogJ01FRElVTScsIExBUkdFOiAnTEFSR0UnLCBYMl9MQVJHRTogJ1gyX0xBUkdFJyB9LFxuICAgIFBsdWdpblR5cGU6IHsgQ09ERV9CVUlMRF9TVEVQOiAnQ29kZUJ1aWxkU3RlcCcsIFNIRUxMX1NURVA6ICdTaGVsbFN0ZXAnLCBNQU5VQUxfQVBQUk9WQUxfU1RFUDogJ01hbnVhbEFwcHJvdmFsU3RlcCcgfSxcbiAgICBFcnJvckNvZGU6IG1vY2tFcnJvckNvZGUsXG4gICAgZXJyb3JNZXNzYWdlOiAoZTogdW5rbm93bikgPT4gKGUgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFN0cmluZyhlKSksXG4gICAgTm90Rm91bmRFcnJvcjogTW9ja05vdEZvdW5kRXJyb3IsXG4gICAgY3JlYXRlQ2FjaGVTZXJ2aWNlOiAoKSA9PiAoe1xuICAgICAgZ2V0T3JTZXQ6IChfa2V5OiBzdHJpbmcsIGZhY3Rvcnk6ICgpID0+IFByb21pc2U8dW5rbm93bj4pID0+IGZhY3RvcnkoKSxcbiAgICAgIGludmFsaWRhdGVQYXR0ZXJuOiAoKSA9PiBQcm9taXNlLnJlc29sdmUoMCksXG4gICAgfSksXG4gIH07XG59XG5cbi8qKlxuICogVGhlIGF1ZGl0IC8gc2VjdXJpdHkgd2lyaW5nIGEgc2VydmljZSdzIGJvb3QgbW9kdWxlIChgc3JjL2luZGV4LnRzYCxcbiAqIGBzcmMvc2VydmljZXMvYXVkaXQudHNgKSBsaW5rcyBhdCBsb2FkIHRpbWUuIEluZXJ0IGJ5IGRlZmF1bHQ6IG5vdGhpbmcgYXNzZXJ0c1xuICogb24gdGhlIHJlZ2lzdHJhdGlvbiwgYW5kIHB1bGxpbmcgdGhlIHJlYWwgZ3JhcGggaW4gd291bGQgZHJhZyBSZWRpcyArIEhUVFBcbiAqIGNsaWVudHMgaW50byBldmVyeSByb3V0ZSBzdWl0ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlcnZpY2VBdWRpdERlZmF1bHRzKCk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgcmV0dXJuIHtcbiAgICBjcmVhdGVSZW1vdGVBdWRpdENsaWVudDogKCkgPT4gKHsgcmVjb3JkOiBqZXN0LmZuKCkgfSksXG4gICAgY3JlYXRlRW52UmVkaXNBdWRpdFNwb29sOiAoKSA9PiBudWxsLFxuICAgIGNyZWF0ZVNlcnZpY2VBdWRpdENsaWVudDogKCkgPT4gKHsgZW1pdDogamVzdC5mbigpLCBjbGllbnQ6IHsgcmVjb3JkOiBqZXN0LmZuKCkgfSB9KSxcbiAgICBjcmVhdGVSZW1vdGVBdWRpdEFjY2Vzc29yOiAoKSA9PiAoeyBnZXRBdWRpdENsaWVudDogKCkgPT4gKHsgcmVjb3JkOiBqZXN0LmZuKCkgfSksIGVtaXQ6IGplc3QuZm4oKSB9KSxcbiAgICBzZXRBdXRoekRlbmlhbEF1ZGl0b3I6ICgpID0+IHt9LFxuICAgIHdpcmVBdXRoekRlbmlhbEF1ZGl0b3I6ICgpID0+IHt9LFxuICAgIHdpcmVTZXJ2aWNlU2VjdXJpdHk6ICgpID0+IHt9LFxuICAgIHNldFRva2VuUmV2b2NhdGlvblN0b3JlOiAoKSA9PiB7fSxcbiAgICBjcmVhdGVSZWRpc1Rva2VuUmV2b2NhdGlvblN0b3JlOiAoKSA9PiAoeyBnZXRDdXJyZW50VmVyc2lvbjogYXN5bmMgKCkgPT4gbnVsbCB9KSxcbiAgICBjcmVhdGVFbnZSZWRpc1Rva2VuUmV2b2NhdGlvblN0b3JlOiAoKSA9PiAoeyBnZXRDdXJyZW50VmVyc2lvbjogYXN5bmMgKCkgPT4gbnVsbCB9KSxcbiAgfTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhbiBhcGktY29yZSBtb2NrIG5hbWVzcGFjZTogUkVBTCBhcGktY29yZSwgdGhlbiB0aGUgc2hhcmVkIHNlcnZpY2VcbiAqIGRlZmF1bHRzLCB0aGVuIGBvdmVycmlkZXNgIChhIHByb2plY3QncyBvd24gZGVmYXVsdHMgbWVyZ2VkIHdpdGggdGhlIHN1aXRlJ3MpLlxuICpcbiAqIGBhY3R1YWxBcGlDb3JlYCBpcyBzdXBwbGllZCBieSB0aGUgQ0FMTEVSIChgamVzdC5yZXF1aXJlQWN0dWFsKC4uLilgIGF0IHRoZSB0b3BcbiAqIG9mIHRoZSBwcm9qZWN0J3MgYHRlc3QvaGVscGVycy9tb2NrLWFwaS1jb3JlLnRzYCkgcmF0aGVyIHRoYW4gcmVzb2x2ZWQgaGVyZS5cbiAqIFRoYXQgaXMgZGVsaWJlcmF0ZTogYHJlcXVpcmVBY3R1YWxgIG9uIGFuIEVTTSBiYXJyZWwgb25seSBzdWNjZWVkcyBhdCBhIG1vbWVudFxuICogd2hlbiBub3RoaW5nIGVsc2UgaXMgbWlkLWBpbXBvcnQoKWAgb2YgaXQsIGFuZCB0aGUgcHJvamVjdCBoZWxwZXIg4oCUIGEgc3RhdGljXG4gKiBpbXBvcnQgb2YgdGhlIHRlc3QgZmlsZSwgZXZhbHVhdGVkIGJlZm9yZSBhbnkgYGF3YWl0IGltcG9ydChTVVQpYCDigJQgaXMgdGhlIG9uZVxuICogcG9pbnQgd2hlcmUgdGhhdCBhbHdheXMgaG9sZHMuIFJlc29sdmluZyBpdCBmcm9tIGluc2lkZSB0aGlzIG1vZHVsZSAod2hpY2hcbiAqIGxpdmVzIGluIHRoZSBhcGktY29yZSBwYWNrYWdlIGl0c2VsZikgcmFjZXMgdGhhdCBpbXBvcnQgaW4gc29tZSBzdWl0ZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiYXNlQXBpQ29yZU1vY2soXG4gIGFjdHVhbEFwaUNvcmU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICBvdmVycmlkZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge30sXG4pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIHJldHVybiB7IC4uLmFjdHVhbEFwaUNvcmUsIC4uLnNlcnZpY2VBcGlDb3JlRGVmYXVsdHMoKSwgLi4ub3ZlcnJpZGVzIH07XG59XG5cbi8qKlxuICogQnVpbGQgYW4gYXBpLWNvcmUgbW9jayBuYW1lc3BhY2Ugd2l0aCBOTyBzZXJ2aWNlIGRlZmF1bHRzIOKAlCBSRUFMIGFwaS1jb3JlIHBsdXNcbiAqIHRoZSBsb2dnZXIgc3R1YiBhbmQgYEVycm9yQ29kZWAgcHJveHkgb25seS4gUGxhdGZvcm0gdXNlcyB0aGlzOiBpdCBkZWxpYmVyYXRlbHlcbiAqIGtlZXBzIGFwaS1jb3JlJ3MgcmVhbCBwYWdpbmF0aW9uL3JlcG9ydCBjb25zdGFudHMgYW5kIHN1cHBsaWVzIGl0cyBvd25cbiAqIChsYXJnZSkgaWRlbnRpdHkvdGllci9wZXJtaXNzaW9uIGRlZmF1bHQgc2V0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJpbWl0aXZlQXBpQ29yZU1vY2soXG4gIGFjdHVhbEFwaUNvcmU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICBvdmVycmlkZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge30sXG4pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIHJldHVybiB7IC4uLmFjdHVhbEFwaUNvcmUsIGNyZWF0ZUxvZ2dlcjogbG9nZ2VyTW9jaywgRXJyb3JDb2RlOiBtb2NrRXJyb3JDb2RlLCAuLi5vdmVycmlkZXMgfTtcbn1cblxuLyoqXG4gKiBNaXJyb3IgYXBpLWNvcmUncyBgcmVxdWlyZUludGVybmFsU2VydmljZSh7IGNhbGxlcnMgfSlgOiByZWZ1c2UgYW55IHVzZXIgdG9rZW4sXG4gKiB0aGVuIHJlZnVzZSBhIHNlcnZpY2Ugd2hvc2UgbmFtZSBpcyBub3QgaW4gdGhlIHJvdXRlJ3MgY2FsbGVyIGxpc3QuIFJlc29sdmVkXG4gKiBmcm9tIHRoZSBNRVJHRUQgbW9jayAocmF0aGVyIHRoYW4gaW5oZXJpdGVkIGZyb20gYHJlcXVpcmVBY3R1YWxgKSBzbyBpdCB1c2VzXG4gKiB0aGUgc3VpdGUncyBgaXNTZXJ2aWNlUHJpbmNpcGFsYCAvIGBzZXJ2aWNlTmFtZU9mYCAvIGBzZW5kRXJyb3JgLCB3aGljaCB0aGUgcmVhbFxuICogb25lIGNsb3NlcyBvdmVyIGFuZCB3b3VsZCB3cml0ZSBwYXN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2l0aEludGVybmFsU2VydmljZUdhdGUobW9jazogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIG92ZXJyaWRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIGlmIChvdmVycmlkZXMucmVxdWlyZUludGVybmFsU2VydmljZSAhPT0gdW5kZWZpbmVkKSByZXR1cm4gbW9jaztcbiAgbW9jay5yZXF1aXJlSW50ZXJuYWxTZXJ2aWNlID0gKHsgY2FsbGVycyB9OiB7IGNhbGxlcnM6IHJlYWRvbmx5IHN0cmluZ1tdIH0pID0+XG4gICAgKHJlcTogdW5rbm93biwgcmVzOiB1bmtub3duLCBuZXh0OiBOZXh0KSA9PiB7XG4gICAgICBjb25zdCBpc1N2YyA9IG1vY2suaXNTZXJ2aWNlUHJpbmNpcGFsIGFzICgocjogdW5rbm93bikgPT4gYm9vbGVhbikgfCB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBuYW1lT2YgPSBtb2NrLnNlcnZpY2VOYW1lT2YgYXMgKChjOiB1bmtub3duKSA9PiBzdHJpbmcgfCB1bmRlZmluZWQpIHwgdW5kZWZpbmVkO1xuICAgICAgY29uc3QgY2FsbGVyID0gbmFtZU9mPy4oKHJlcSBhcyB7IHVzZXI/OiB1bmtub3duIH0pLnVzZXIpO1xuICAgICAgaWYgKGlzU3ZjPy4ocmVxKSAmJiBjYWxsZXIgJiYgY2FsbGVycy5pbmNsdWRlcyhjYWxsZXIpKSB7XG4gICAgICAgIG5leHQoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3Qgc2VuZEVycm9yID0gbW9jay5zZW5kRXJyb3IgYXMgKHI6IHVua25vd24sIHM6IG51bWJlciwgbTogc3RyaW5nLCBjOiBzdHJpbmcpID0+IHVua25vd247XG4gICAgICBzZW5kRXJyb3IocmVzLCA0MDMsICdJbnRlcm5hbCBzZXJ2aWNlIGNhbGxzIG9ubHknLCAnSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TJyk7XG4gICAgfTtcbiAgcmV0dXJuIG1vY2s7XG59XG5cbi8qKlxuICogTWlycm9yIGFwaS1jb3JlJ3MgYHJlcXVpcmVTZXJ2aWNlUHJpbmNpcGFsYDogcmVqZWN0IGEgbm9uLXNlcnZpY2UgY2FsbGVyIHdpdGggYVxuICogNDAzIElOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyAoYW4gYXV0aG9yaXphdGlvbiByZWZ1c2FsLCBub3QgYSA0MDApLCByZXNvbHZpbmdcbiAqIGBpc1NlcnZpY2VQcmluY2lwYWxgIC8gYHNlbmRFcnJvcmAgZnJvbSB0aGUgbWVyZ2VkIG1vY2suXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoU2VydmljZVByaW5jaXBhbEdhdGUobW9jazogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIG92ZXJyaWRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIGlmIChvdmVycmlkZXMucmVxdWlyZVNlcnZpY2VQcmluY2lwYWwgIT09IHVuZGVmaW5lZCkgcmV0dXJuIG1vY2s7XG4gIG1vY2sucmVxdWlyZVNlcnZpY2VQcmluY2lwYWwgPSAocmVxOiB1bmtub3duLCByZXM6IHVua25vd24sIG5leHQ6IE5leHQpID0+IHtcbiAgICBjb25zdCBpc1N2YyA9IG1vY2suaXNTZXJ2aWNlUHJpbmNpcGFsIGFzICgocjogdW5rbm93bikgPT4gYm9vbGVhbikgfCB1bmRlZmluZWQ7XG4gICAgaWYgKGlzU3ZjPy4ocmVxKSkge1xuICAgICAgbmV4dCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzZW5kRXJyb3IgPSBtb2NrLnNlbmRFcnJvciBhcyAocjogdW5rbm93biwgczogbnVtYmVyLCBtOiBzdHJpbmcsIGM6IHN0cmluZykgPT4gdW5rbm93bjtcbiAgICBzZW5kRXJyb3IocmVzLCA0MDMsICdJbnRlcm5hbCBzZXJ2aWNlIGNhbGxzIG9ubHknLCAnSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TJyk7XG4gIH07XG4gIHJldHVybiBtb2NrO1xufVxuXG4vKipcbiAqIGBzZW5kQmFkUmVxdWVzdGAgZGVsZWdhdGluZyB0byB0aGUgKHBvc3NpYmx5LW92ZXJyaWRkZW4pIGBzZW5kRXJyb3JgLCBtaXJyb3JpbmdcbiAqIHRoZSByZWFsIGltcGxlbWVudGF0aW9uIOKAlCBzbyBhIHN1aXRlIHNweWluZyBvbiBgc2VuZEVycm9yYCBhbHNvIG9ic2VydmVzIHRoZVxuICogNDAwcyByb3V0ZWQgdGhyb3VnaCBgc2VuZEJhZFJlcXVlc3RgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2l0aERlbGVnYXRpbmdTZW5kQmFkUmVxdWVzdChtb2NrOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgb3ZlcnJpZGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgaWYgKCdzZW5kQmFkUmVxdWVzdCcgaW4gb3ZlcnJpZGVzKSByZXR1cm4gbW9jaztcbiAgbW9jay5zZW5kQmFkUmVxdWVzdCA9IChyZXM6IHVua25vd24sIG1lc3NhZ2U6IHN0cmluZywgY29kZT86IHN0cmluZykgPT5cbiAgICAobW9jay5zZW5kRXJyb3IgYXMgKHI6IHVua25vd24sIHM6IG51bWJlciwgbTogc3RyaW5nLCBjPzogc3RyaW5nKSA9PiB1bmtub3duKShcbiAgICAgIHJlcywgNDAwLCBtZXNzYWdlLCBjb2RlID8/IG1vY2tFcnJvckNvZGUuVkFMSURBVElPTl9FUlJPUik7XG4gIHJldHVybiBtb2NrO1xufVxuIl19
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Build a `drizzle-orm` mock namespace: every real export, with `overrides`
3
+ * spread last so a suite can swap an operator for an inspectable stub (or a
4
+ * `jest.fn()` it asserts on) without having to enumerate the rest.
5
+ */
6
+ export declare function drizzleMock(overrides?: Record<string, unknown>): Record<string, unknown>;