velocious 1.0.711 → 1.0.713

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.
@@ -12,6 +12,7 @@ import {
12
12
  AdvisoryLockServiceUnavailableError,
13
13
  advisoryLockBackendUnavailable
14
14
  } from "./advisory-lock-errors.js"
15
+ import {emitAdvisoryLockFallbackReport} from "./advisory-lock-telemetry.js"
15
16
 
16
17
  /**
17
18
  * Provenance of one advisory-lock acquisition (STC-210 design §3): every
@@ -407,17 +408,12 @@ export default class AdvisoryLockRunner {
407
408
  */
408
409
  reportAdvisoryLockFallback({lockName, reason, servedBy}) {
409
410
  const policy = resolveAdvisoryLockBackendPolicy(lockName, this.configuration.getAdvisoryLockPolicy())
410
- const payload = {
411
- context: "advisory-lock-fallback",
411
+ emitAdvisoryLockFallbackReport(this.configuration, {
412
412
  lockName,
413
413
  preferredTier: policy.preferredTier,
414
414
  reason,
415
415
  servedBy
416
- }
417
- const errorEvents = this.configuration.getErrorEvents()
418
-
419
- errorEvents.emit("framework-error", payload)
420
- errorEvents.emit("all-error", {...payload, errorType: "framework-error"})
416
+ })
421
417
  }
422
418
 
423
419
  /**
@@ -6,9 +6,9 @@
6
6
  * A lock convoy is only fixable when it is *attributable*: which lock name was
7
7
  * contended, on which backend tier, for how long, and who held it. These reports
8
8
  * fire on the acquisition/release events themselves — never from a periodic
9
- * scanner — so a contended lock in production surfaces on the framework-error
10
- * channel with the holder identity available on that tier at that moment,
11
- * without SSH forensics.
9
+ * scanner — so a contended lock in production surfaces on the telemetry channel
10
+ * with the holder identity available on that tier at that moment, without SSH
11
+ * forensics.
12
12
  *
13
13
  * Three events, each with its own threshold (all configurable per database via
14
14
  * `advisoryLockTelemetry`, see `docs/advisory-locks.md`):
@@ -128,3 +128,39 @@ export function emitAdvisoryLockTelemetryReport(configuration, report) {
128
128
  console.error(`[velocious advisory-lock-telemetry ${report.event}] lock=${JSON.stringify(report.lockName)} tier=${report.backendTier} durationMs=${report.durationMs}${report.outcome ? ` outcome=${report.outcome}` : ""}${report.holderConnectionId ? ` holderConnectionId=${report.holderConnectionId}` : ""}${report.holderId ? ` holderId=${report.holderId}` : ""} — subscribe via configuration.getTelemetryEvents().on("telemetry", …) to route these measurements to your metrics`)
129
129
  }
130
130
  }
131
+
132
+ /**
133
+ * Reports one acquisition served below the lock name's preferred tier
134
+ * (design §3): the caller wanted the lock server and got the database, so the
135
+ * downgrade must be visible without being mistaken for a failure. Fallbacks are
136
+ * measurements, not errors, so they stay off `framework-error` and its bug
137
+ * reporters (same contract as the duration telemetry).
138
+ * @param {import("../configuration.js").default} configuration - Owning configuration.
139
+ * @param {{lockName: string, preferredTier: string, reason: string, servedBy: string}} report - Fallback details.
140
+ * @returns {void}
141
+ */
142
+ export function emitAdvisoryLockFallbackReport(configuration, report) {
143
+ /** @type {import("eventemitter3").EventEmitter | undefined} */
144
+ let telemetryEvents
145
+
146
+ try {
147
+ telemetryEvents = configuration?.getTelemetryEvents()
148
+ } catch {
149
+ return // No configuration to report through — never break lock handling.
150
+ }
151
+
152
+ if (!telemetryEvents) return
153
+
154
+ const payload = {context: "advisory-lock-fallback", ...report}
155
+ const hasListener = telemetryEvents.listenerCount("telemetry") > 0
156
+
157
+ try {
158
+ telemetryEvents.emit("telemetry", payload)
159
+ } catch {
160
+ // A broken listener must never surface as a lock failure.
161
+ }
162
+
163
+ if (!hasListener) {
164
+ console.error(`[velocious advisory-lock-fallback] lock=${JSON.stringify(report.lockName)} preferredTier=${report.preferredTier} servedBy=${report.servedBy} reason=${report.reason}`)
165
+ }
166
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"advisory-lock-runner.d.ts","sourceRoot":"","sources":["../../../src/database/advisory-lock-runner.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"advisory-lock-runner.d.ts","sourceRoot":"","sources":["../../../src/database/advisory-lock-runner.js"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ import timeout, { TimeoutError } from "awaitery/build/timeout.js";
3
3
  import { DEFAULT_ADVISORY_LOCK_ACQUIRE_TIMEOUT_MS } from "./advisory-lock-bound.js";
4
4
  import { AdvisoryLockBackendUnavailableError, resolveAdvisoryLockBackendPolicy, refuseAdvisoryLockTierBelowMinimum } from "./advisory-lock-backend-policy.js";
5
5
  import { AdvisoryLockLostError, AdvisoryLockServiceUnavailableError, advisoryLockBackendUnavailable } from "./advisory-lock-errors.js";
6
+ import { emitAdvisoryLockFallbackReport } from "./advisory-lock-telemetry.js";
6
7
  /**
7
8
  * Provenance of one advisory-lock acquisition (STC-210 design §3): every
8
9
  * held lock reports the tier that actually served it, so a fallback is
@@ -336,16 +337,12 @@ export default class AdvisoryLockRunner {
336
337
  */
337
338
  reportAdvisoryLockFallback({ lockName, reason, servedBy }) {
338
339
  const policy = resolveAdvisoryLockBackendPolicy(lockName, this.configuration.getAdvisoryLockPolicy());
339
- const payload = {
340
- context: "advisory-lock-fallback",
340
+ emitAdvisoryLockFallbackReport(this.configuration, {
341
341
  lockName,
342
342
  preferredTier: policy.preferredTier,
343
343
  reason,
344
344
  servedBy
345
- };
346
- const errorEvents = this.configuration.getErrorEvents();
347
- errorEvents.emit("framework-error", payload);
348
- errorEvents.emit("all-error", { ...payload, errorType: "framework-error" });
345
+ });
349
346
  }
350
347
  /**
351
348
  * Resolves the backend policy for one lock name and returns the file
@@ -550,4 +547,4 @@ function advisoryLockPolicyAllowsFileTier(policy) {
550
547
  export { AdvisoryLockBusyError, AdvisoryLockHoldTimeoutError, AdvisoryLockTimeoutError };
551
548
  export { AdvisoryLockBackendUnavailableError, AdvisoryLockMinTierRefusedError } from "./advisory-lock-backend-policy.js";
552
549
  export { AdvisoryLockLostError, AdvisoryLockServiceUnavailableError } from "./advisory-lock-errors.js";
553
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWR2aXNvcnktbG9jay1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGF0YWJhc2UvYWR2aXNvcnktbG9jay1ydW5uZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sT0FBTyxFQUFFLEVBQUMsWUFBWSxFQUFDLE1BQU0sMkJBQTJCLENBQUE7QUFDL0QsT0FBTyxFQUFDLHdDQUF3QyxFQUFDLE1BQU0sMEJBQTBCLENBQUE7QUFDakYsT0FBTyxFQUNMLG1DQUFtQyxFQUNuQyxnQ0FBZ0MsRUFDaEMsa0NBQWtDLEVBQ25DLE1BQU0sbUNBQW1DLENBQUE7QUFDMUMsT0FBTyxFQUNMLHFCQUFxQixFQUNyQixtQ0FBbUMsRUFDbkMsOEJBQThCLEVBQy9CLE1BQU0sMkJBQTJCLENBQUE7QUFFbEM7Ozs7Ozs7Ozs7O0dBV0c7QUFFSDs7R0FFRztBQUNILE1BQU0sd0JBQXlCLFNBQVEsS0FBSztJQUMxQzs7OztPQUlHO0lBQ0gsWUFBWSxPQUFPLEVBQUUsRUFBQyxJQUFJLEVBQUM7UUFDekIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQ2QsSUFBSSxDQUFDLElBQUksR0FBRywwQkFBMEIsQ0FBQTtRQUN0QyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQTtJQUN0QixDQUFDO0NBQ0Y7QUFFRDs7R0FFRztBQUNILE1BQU0scUJBQXNCLFNBQVEsS0FBSztJQUN2Qzs7OztPQUlHO0lBQ0gsWUFBWSxPQUFPLEVBQUUsRUFBQyxJQUFJLEVBQUM7UUFDekIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQ2QsSUFBSSxDQUFDLElBQUksR0FBRyx1QkFBdUIsQ0FBQTtRQUNuQyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQTtJQUN0QixDQUFDO0NBQ0Y7QUFFRDs7R0FFRztBQUNILE1BQU0sNEJBQTZCLFNBQVEsS0FBSztJQUM5Qzs7OztPQUlHO0lBQ0gsWUFBWSxPQUFPLEVB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O0dBSUc7QUFDSCxTQUFTLGdDQUFnQyxDQUFDLE1BQU07SUFDOUMsT0FBTyxNQUFNLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQTtBQUM3QyxDQUFDO0FBRUQsT0FBTyxFQUFDLHFCQUFxQixFQUFFLDRCQUE0QixFQUFFLHdCQUF3QixFQUFDLENBQUE7QUFDdEYsT0FBTyxFQUFDLG1DQUFtQyxFQUFFLCtCQUErQixFQUFDLE1BQU0sbUNBQW1DLENBQUE7QUFDdEgsT0FBTyxFQUFDLHFCQUFxQixFQUFFLG1DQUFtQyxFQUFDLE1BQU0sMkJBQTJCLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHRpbWVvdXQsIHtUaW1lb3V0RXJyb3J9IGZyb20gXCJhd2FpdGVyeS9idWlsZC90aW1lb3V0LmpzXCJcbmltcG9ydCB7REVGQVVMVF9BRFZJU09SWV9MT0NLX0FDUVVJUkVfVElNRU9VVF9NU30gZnJvbSBcIi4vYWR2aXNvcnktbG9jay1ib3VuZC5qc1wiXG5pbXBvcnQge1xuICBBZHZpc29yeUxvY2tCYWNrZW5kVW5hdmFpbGFibGVFcnJvcixcbiAgcmVzb2x2ZUFkdmlzb3J5TG9ja0JhY2tlbmRQb2xpY3ksXG4gIHJlZnVzZUFkdmlzb3J5TG9ja1RpZXJCZWxvd01pbmltdW1cbn0gZnJvbSBcIi4vYWR2aXNvcnktbG9jay1iYWNrZW5kLXBvbGljeS5qc1wiXG5pbXBvcnQge1xuICBBZHZpc29yeUxvY2tMb3N0RXJyb3IsXG4gIEFkdmlzb3J5TG9ja1NlcnZpY2VVbmF2YWlsYWJsZUVycm9yLFxuICBhZHZpc29yeUxvY2tCYWNrZW5kVW5hdmFpbGFibGVcbn0gZnJvbSBcIi4vYWR2aXNvcnktbG9jay1lcnJvcnMuanNcIlxuXG4vKipcbiAqIFByb3ZlbmFuY2Ugb2Ygb25lIGFkdmlzb3J5LWxvY2sgYWNxdWlzaXRpb24gKFNUQy0yMTAgZGVzaWduIMKnMyk6IGV2ZXJ5XG4gKiBoZWxkIGxvY2sgcmVwb3J0cyB0aGUgdGllciB0aGF0IGFjdHVhbGx5IHNlcnZlZCBpdCwgc28gYSBmYWxsYmFjayBpc1xuICogdmlzaWJsZSB0byB0aGUgY2FsbGJhY2ssIGluIGxvZ3MsIGFuZCBpbiBgZ2V0QWR2aXNvcnlMb2NrQmFja2VuZFN0YXR1cygpYC5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IEFkdmlzb3J5TG9ja0JhY2tlbmRQcm92ZW5hbmNlXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vYWR2aXNvcnktbG9jay1iYWNrZW5kLXBvbGljeS5qc1wiKS5BZHZpc29yeUxvY2tUaWVyfSBiYWNrZW5kIC0gVGllciB0aGF0IHNlcnZlZCB0aGUgYWNxdWlzaXRpb24uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2RyaXZlclR5cGVdIC0gRGF0YWJhc2UgZHJpdmVyIHR5cGUgd2hlbiB0aGUgZHJpdmVyIHRpZXIgc2VydmVkIGl0LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtlcG9jaF0gLSBGZW5jaW5nIGVwb2NoIHdoZW4gdGhlIHNlcnZpbmcgdGllciBpc3N1ZXMgb25lLlxuICogQHByb3BlcnR5IHtib29sZWFufSBmZW5jaW5nU3VwcG9ydGVkIC0gV2hldGhlciB0aGlzIHRpZXIgY2FycmllcyBmZW5jaW5nIHRva2VucyAoZGVzaWduIMKnOCk7IHRoZSBmaWxlIHRpZXIgcmVwb3J0cyBmYWxzZSByYXRoZXIgdGhhbiBwcmV0ZW5kaW5nLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtob2xkZXJJZF0gLSBCYWNrZW5kIGhvbGRlciBpZCBmb3IgdGhlIGZpbGUgdGllci5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbbG9ja05hbWVdIC0gTG9jayBuYW1lIHRoaXMgcHJvdmVuYW5jZSBiZWxvbmdzIHRvLlxuICovXG5cbi8qKlxuICogVGhyb3duIHdoZW4gYW4gYWR2aXNvcnkgbG9jayBjb3VsZCBub3QgYmUgYWNxdWlyZWQgYmVmb3JlIGB0aW1lb3V0TXNgIGVsYXBzZWQuXG4gKi9cbmNsYXNzIEFkdmlzb3J5TG9ja1RpbWVvdXRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgLyoqXG4gICAqIFJ1bnMgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gRXJyb3IgbWVzc2FnZS5cbiAgICogQHBhcmFtIHt7bmFtZTogc3RyaW5nfX0gYXJncyAtIFRoZSBhZHZpc29yeSBsb2NrIG5hbWUgdGhhdCB0aW1lZCBvdXQuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlLCB7bmFtZX0pIHtcbiAgICBzdXBlcihtZXNzYWdlKVxuICAgIHRoaXMubmFtZSA9IFwiQWR2aXNvcnlMb2NrVGltZW91dEVycm9yXCJcbiAgICB0aGlzLmxvY2tOYW1lID0gbmFtZVxuICB9XG59XG5cbi8qKlxuICogVGhyb3duIHdoZW4gYHdpdGhBZHZpc29yeUxvY2tPckZhaWxgIGZpbmRzIHRoZSBsb2NrIGFscmVhZHkgaGVsZC5cbiAqL1xuY2xhc3MgQWR2aXNvcnlMb2NrQnVzeUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAvKipcbiAgICogUnVucyBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBFcnJvciBtZXNzYWdlLlxuICAgKiBAcGFyYW0ge3tuYW1lOiBzdHJpbmd9fSBhcmdzIC0gVGhlIGFkdmlzb3J5IGxvY2sgbmFtZSB0aGF0IHdhcyBhbHJlYWR5IGhlbGQuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlLCB7bmFtZX0pIHtcbiAgICBzdXBlcihtZXNzYWdlKVxuICAgIHRoaXMubmFtZSA9IFwiQWR2aXNvcnlMb2NrQnVzeUVycm9yXCJcbiAgICB0aGlzLmxvY2tOYW1lID0gbmFtZVxuICB9XG59XG5cbi8qKlxuICogVGhyb3duIHdoZW4gYSBjYWxsYmFjayBob2xkcyBhbiBhZHZpc29yeSBsb2NrIGxvbmdlciB0aGFuIGBob2xkVGltZW91dE1zYC5cbiAqL1xuY2xhc3MgQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgLyoqXG4gICAqIFJ1bnMgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gRXJyb3IgbWVzc2FnZS5cbiAgICogQHBhcmFtIHt7bmFtZTogc3RyaW5nfX0gYXJncyAtIFRoZSBhZHZpc29yeSBsb2NrIG5hbWUgd2hvc2UgaG9sZCB0aW1lZCBvdXQuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlLCB7bmFtZX0pIHtcbiAgICBzdXBlcihtZXNzYWdlKVxuICAgIHRoaXMubmFtZSA9IFwiQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXRFcnJvclwiXG4gICAgdGhpcy5sb2NrTmFtZSA9IG5hbWVcbiAgfVxufVxuXG4vKipcbiAqIFJ1bnMgYWR2aXNvcnkgbG9ja3Mgb24gdGhlIGNhbGxlciBjb25uZWN0aW9uIGJ5IGRlZmF1bHQsIHVzaW5nIGEgZGVkaWNhdGVkXG4gKiBsb2NrIGNvbm5lY3Rpb24gd2hlbiBgZGVkaWNhdGVkQ29ubmVjdGlvbmAgaXMgcmVxdWVzdGVkIG9yIHdoZW4gYSBwb3NpdGl2ZVxuICogaG9sZCB0aW1lb3V0IG5lZWRzIHNlcGFyYXRlIG93bmVyc2hpcC5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQWR2aXNvcnlMb2NrUnVubmVyIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gYWR2aXNvcnktbG9jayBydW5uZXIgZm9yIG9uZSBtb2RlbCBkYXRhYmFzZSBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge3tjb25maWd1cmF0aW9uOiBpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHQsIGNvbm5lY3Rpb25Qcm92aWRlcjogKCkgPT4gaW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCwgZGF0YWJhc2VJZGVudGlmaWVyOiBzdHJpbmd9fSBhcmdzIC0gUnVubmVyIGRlcGVuZGVuY2llcy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtjb25maWd1cmF0aW9uLCBjb25uZWN0aW9uUHJvdmlkZXIsIGRhdGFiYXNlSWRlbnRpZmllcn0pIHtcbiAgICB0aGlzLmNvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uXG4gICAgdGhpcy5jb25uZWN0aW9uUHJvdmlkZXIgPSBjb25uZWN0aW9uUHJvdmlkZXJcbiAgICB0aGlzLmRhdGFiYXNlSWRlbnRpZmllciA9IGRhdGFiYXNlSWRlbnRpZmllclxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYSBjYWxsYmFjayBhZnRlciBhY3F1aXJpbmcgdGhlIGFkdmlzb3J5IGxvY2ssIHdhaXRpbmcgdXAgdG8gYHRpbWVvdXRNc2AuXG4gICAqIFdoZW4gYGRlZGljYXRlZENvbm5lY3Rpb25gIGlzIHRydWUgdGhlIGxvY2sgaXMgYWNxdWlyZWQgb24gYSBzcGF3bmVkXG4gICAqIGNvbm5lY3Rpb24gdGhhdCBpcyByZWxlYXNlZCBhZnRlciB0aGUgY2FsbGJhY2sgZmluaXNoZXMsIHdoaWxlIHRoZSBjYWxsYmFja1xuICAgKiBpdHNlbGYgc3RpbGwgcnVucyBhZ2FpbnN0IHRoZSBjYWxsZXIvbW9kZWwgY29ubmVjdGlvbi4gV2hlbiBhIGBob2xkVGltZW91dE1zYFxuICAgKiBpcyBzZXQgdGhlIGNhbGxiYWNrIHJlY2VpdmVzIGEgYFRpbWVvdXRDb250cm9sYCBmcm9tIGF3YWl0ZXJ5IGZvciBjb29wZXJhdGl2ZVxuICAgKiBjYW5jZWxsYXRpb24gKGBjb250cm9sLmNoZWNrKClgLCBgY29udHJvbC5zaWduYWxgLCBgY29udHJvbC50aW1lZE91dGAsXG4gICAqIGBjb250cm9sLnJlbWFpbmluZygpYCk7IGEgZGVkaWNhdGVkIGNvbm5lY3Rpb24gaXMgYWxzbyB1c2VkIHNvIHRpbWVvdXRcbiAgICogY2xlYW51cCBjYW4gcmVsZWFzZSB0aGUgbG9jayBldmVuIGlmIGNhbGxiYWNrIGRhdGFiYXNlIHdvcmsgaXMgc3R1Y2suXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTG9jayBuYW1lLlxuICAgKiBAcGFyYW0geyhhcmdzPzoge2NvbnRyb2w/OiBpbXBvcnQoXCJhd2FpdGVyeS9idWlsZC90aW1lb3V0LmpzXCIpLlRpbWVvdXRDb250cm9sLCBsb2NrQmFja2VuZDogQWR2aXNvcnlMb2NrQmFja2VuZFByb3ZlbmFuY2V9KSA9PiBQcm9taXNlPFQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHRvIGludm9rZSB3aGlsZSB0aGUgbG9jayBpcyBoZWxkLlxuICAgKiBAcGFyYW0ge3t0aW1lb3V0TXM/OiBudW1iZXIgfCBudWxsLCBob2xkVGltZW91dE1zPzogbnVtYmVyIHwgbnVsbCwgZGVkaWNhdGVkQ29ubmVjdGlvbj86IGJvb2xlYW59fSBbYXJnc10gLSBMb2NrIGFuZCBob2xkIHRpbWVvdXQgb3B0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgd2l0aEFkdmlzb3J5TG9jayhuYW1lLCBjYWxsYmFjaywgYXJncyA9IHt9KSB7XG4gICAgY29uc3QgbG9ja1NlcnZlclJlc3VsdCA9IGF3YWl0IHRoaXMuYXR0ZW1wdExvY2tTZXJ2ZXIoe2FyZ3MsIGNhbGxiYWNrLCBtb2RlOiBcIndhaXRcIiwgbmFtZX0pXG5cbiAgICAvLyBUaGUgd2FpdCBtb2RlIG5ldmVyIHJldHVybnMgYSBkZWZlcnJlZCBvdXRjb21lLCBzbyB0aGUgdmFsdWUgbWVtYmVyIGlzIHByZXNlbnQuXG4gICAgaWYgKGxvY2tTZXJ2ZXJSZXN1bHQpIHJldHVybiAvKiogQHR5cGUge3t2YWx1ZTogVH19ICovIChsb2NrU2VydmVyUmVzdWx0KS52YWx1ZVxuXG4gICAgY29uc3QgZmlsZUJhY2tlbmQgPSBhd2FpdCB0aGlzLmZpbGVCYWNrZW5kRm9yTmFtZShuYW1lKVxuXG4gICAgaWYgKGZpbGVCYWNrZW5kKSB7XG4gICAgICBjb25zdCBhY3F1aXJlZCA9IGF3YWl0IGZpbGVCYWNrZW5kLmFjcXVpcmUobmFtZSwge3RpbWVvdXRNczogdGhpcy5hY3F1aXJlVGltZW91dE1zKGFyZ3MpfSlcblxuICAgICAgaWYgKCFhY3F1aXJlZCkge1xuICAgICAgICB0aHJvdyBuZXcgQWR2aXNvcnlMb2NrVGltZW91dEVycm9yKGBUaW1lZCBvdXQgd2FpdGluZyBmb3IgYWR2aXNvcnkgbG9jayAke0pTT04uc3RyaW5naWZ5KG5hbWUpfSBvbiB0aGUgZmlsZSB0aWVyYCwge25hbWV9KVxuICAgICAgfVxuXG4gICAgICBjb25zdCBsb2NrQmFja2VuZCA9IHRoaXMuZmlsZVByb3ZlbmFuY2UoZmlsZUJhY2tlbmQsIG5hbWUpXG5cbiAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5yZWNvcmRBZHZpc29yeUxvY2tBY3F1aXNpdGlvbih7YmFja2VuZDogbG9ja0JhY2tlbmQuYmFja2VuZCwgZmVuY2luZ1N1cHBvcnRlZDogbG9ja0JhY2tlbmQuZmVuY2luZ1N1cHBvcnRlZCwgbG9ja05hbWU6IG5hbWV9KVxuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5ydW5Mb2NrZWRDYWxsYmFjayh7Y2FsbGJhY2ssIGhvbGRUaW1lb3V0TXM6IGFyZ3MuaG9sZFRpbWVvdXRNcywgbG9ja0JhY2tlbmQsIG5hbWUsIHJlbGVhc2U6IGFzeW5jICgpID0+IGF3YWl0IGZpbGVCYWNrZW5kLnJlbGVhc2UobmFtZSl9KVxuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLndpdGhMb2NrQ29ubmVjdGlvbihhcmdzLCBhc3luYyAoY29ubmVjdGlvbikgPT4ge1xuICAgICAgY29uc3QgbG9ja0JhY2tlbmQgPSB0aGlzLmRyaXZlclByb3ZlbmFuY2UoY29ubmVjdGlvbilcblxuICAgICAgdGhpcy5hc3NlcnREcml2ZXJUaWVyRWxpZ2libGUobmFtZSwgbG9ja0JhY2tlbmQpXG5cbiAgICAgIGNvbnN0IGFjcXVpcmVkID0gYXdhaXQgY29ubmVjdGlvbi5hY3F1aXJlQWR2aXNvcnlMb2NrKG5hbWUsIGFyZ3MpXG5cbiAgICAgIGlmICghYWNxdWlyZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEFkdmlzb3J5TG9ja1RpbWVvdXRFcnJvcihgVGltZWQgb3V0IHdhaXRpbmcgZm9yIGFkdmlzb3J5IGxvY2sgJHtKU09OLnN0cmluZ2lmeShuYW1lKX1gLCB7bmFtZX0pXG4gICAgICB9XG5cbiAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5yZWNvcmRBZHZpc29yeUxvY2tBY3F1aXNpdGlvbih7YmFja2VuZDogbG9ja0JhY2tlbmQuYmFja2VuZCwgZmVuY2luZ1N1cHBvcnRlZDogbG9ja0JhY2tlbmQuZmVuY2luZ1N1cHBvcnRlZCwgbG9ja05hbWU6IG5hbWV9KVxuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5ydW5Mb2NrZWRDYWxsYmFjayh7Y2FsbGJhY2ssIGhvbGRUaW1lb3V0TXM6IGFyZ3MuaG9sZFRpbWVvdXRNcywgbG9ja0JhY2tlbmQsIG5hbWUsIHJlbGVhc2U6IGFzeW5jICgpID0+IGF3YWl0IGNvbm5lY3Rpb24ucmVsZWFzZUFkdmlzb3J5TG9jayhuYW1lKX0pXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGEgY2FsbGJhY2sgb25seSBpZiB0aGUgYWR2aXNvcnkgbG9jayBjYW4gYmUgYWNxdWlyZWQgaW1tZWRpYXRlbHkuXG4gICAqIFdoZW4gYGRlZGljYXRlZENvbm5lY3Rpb25gIGlzIHRydWUgdGhlIGxvY2sgaXMgYWNxdWlyZWQgb24gYSBzcGF3bmVkXG4gICAqIGNvbm5lY3Rpb24gdGhhdCBpcyByZWxlYXNlZCBhZnRlciB0aGUgY2FsbGJhY2sgZmluaXNoZXMsIHdoaWxlIHRoZSBjYWxsYmFja1xuICAgKiBpdHNlbGYgc3RpbGwgcnVucyBhZ2FpbnN0IHRoZSBjYWxsZXIvbW9kZWwgY29ubmVjdGlvbi4gV2hlbiBhIGBob2xkVGltZW91dE1zYFxuICAgKiBpcyBzZXQgdGhlIGNhbGxiYWNrIHJlY2VpdmVzIGEgYFRpbWVvdXRDb250cm9sYCBmcm9tIGF3YWl0ZXJ5IGZvciBjb29wZXJhdGl2ZVxuICAgKiBjYW5jZWxsYXRpb24uXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTG9jayBuYW1lLlxuICAgKiBAcGFyYW0geyhhcmdzPzoge2NvbnRyb2w/OiBpbXBvcnQoXCJhd2FpdGVyeS9idWlsZC90aW1lb3V0LmpzXCIpLlRpbWVvdXRDb250cm9sLCBsb2NrQmFja2VuZDogQWR2aXNvcnlMb2NrQmFja2VuZFByb3ZlbmFuY2V9KSA9PiBQcm9taXNlPFQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHRvIGludm9rZSB3aGlsZSB0aGUgbG9jayBpcyBoZWxkLlxuICAgKiBAcGFyYW0ge3tob2xkVGltZW91dE1zPzogbnVtYmVyIHwgbnVsbCwgZGVkaWNhdGVkQ29ubmVjdGlvbj86IGJvb2xlYW59fSBbYXJnc10gLSBIb2xkIHRpbWVvdXQgb3B0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgd2l0aEFkdmlzb3J5TG9ja09yRmFpbChuYW1lLCBjYWxsYmFjaywgYXJncyA9IHt9KSB7XG4gICAgY29uc3QgbG9ja1NlcnZlclJlc3VsdCA9IGF3YWl0IHRoaXMuYXR0ZW1wdExvY2tTZXJ2ZXIoe2FyZ3MsIGNhbGxiYWNrLCBtb2RlOiBcIm9yLWZhaWxcIiwgbmFtZX0pXG5cbiAgICAvLyBUaGUgb3ItZmFpbCBtb2RlIHRocm93cyBvbiBjb250ZW50aW9uLCBzbyB0aGUgdmFsdWUgbWVtYmVyIGlzIHByZXNlbnQuXG4gICAgaWYgKGxvY2tTZXJ2ZXJSZXN1bHQpIHJldHVybiAvKiogQHR5cGUge3t2YWx1ZTogVH19ICovIChsb2NrU2VydmVyUmVzdWx0KS52YWx1ZVxuXG4gICAgY29uc3QgZmlsZUJhY2tlbmQgPSBhd2FpdCB0aGlzLmZpbGVCYWNrZW5kRm9yTmFtZShuYW1lKVxuXG4gICAgaWYgKGZpbGVCYWNrZW5kKSB7XG4gICAgICBjb25zdCBhY3F1aXJlZCA9IGF3YWl0IGZpbGVCYWNrZW5kLnRyeUFjcXVpcmUobmFtZSlcblxuICAgICAgaWYgKCFhY3F1aXJlZCkge1xuICAgICAgICB0aHJvdyBuZXcgQWR2aXNvcnlMb2NrQnVzeUVycm9yKGBBZHZpc29yeSBsb2NrICR7SlNPTi5zdHJpbmdpZnkobmFtZSl9IGlzIGFscmVhZHkgaGVsZCBvbiB0aGUgZmlsZSB0aWVyYCwge25hbWV9KVxuICAgICAgfVxuXG4gICAgICBjb25zdCBsb2NrQmFja2VuZCA9IHRoaXMuZmlsZVByb3ZlbmFuY2UoZmlsZUJhY2tlbmQsIG5hbWUpXG5cbiAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5yZWNvcmRBZHZpc29yeUxvY2tBY3F1aXNpdGlvbih7YmFja2VuZDogbG9ja0JhY2tlbmQuYmFja2VuZCwgZmVuY2luZ1N1cHBvcnRlZDogbG9ja0JhY2tlbmQuZmVuY2luZ1N1cHBvcnRlZCwgbG9ja05hbWU6IG5hbWV9KVxuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5ydW5Mb2NrZWRDYWxsYmFjayh7Y2FsbGJhY2ssIGhvbGRUaW1lb3V0TXM6IGFyZ3MuaG9sZFRpbWVvdXRNcywgbG9ja0JhY2tlbmQsIG5hbWUsIHJlbGVhc2U6IGFzeW5jICgpID0+IGF3YWl0IGZpbGVCYWNrZW5kLnJlbGVhc2UobmFtZSl9KVxuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLndpdGhMb2NrQ29ubmVjdGlvbihhcmdzLCBhc3luYyAoY29ubmVjdGlvbikgPT4ge1xuICAgICAgY29uc3QgbG9ja0JhY2tlbmQgPSB0aGlzLmRyaXZlclByb3ZlbmFuY2UoY29ubmVjdGlvbilcblxuICAgICAgdGhpcy5hc3NlcnREcml2ZXJUaWVyRWxpZ2libGUobmFtZSwgbG9ja0JhY2tlbmQpXG5cbiAgICAgIGNvbnN0IGFjcXVpcmVkID0gYXdhaXQgY29ubmVjdGlvbi50cnlBY3F1aXJlQWR2aXNvcnlMb2NrKG5hbWUpXG5cbiAgICAgIGlmICghYWNxdWlyZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEFkdmlzb3J5TG9ja0J1c3lFcnJvcihgQWR2aXNvcnkgbG9jayAke0pTT04uc3RyaW5naWZ5KG5hbWUpfSBpcyBhbHJlYWR5IGhlbGRgLCB7bmFtZX0pXG4gICAgICB9XG5cbiAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5yZWNvcmRBZHZpc29yeUxvY2tBY3F1aXNpdGlvbih7YmFja2VuZDogbG9ja0JhY2tlbmQuYmFja2VuZCwgZmVuY2luZ1N1cHBvcnRlZDogbG9ja0JhY2tlbmQuZmVuY2luZ1N1cHBvcnRlZCwgbG9ja05hbWU6IG5hbWV9KVxuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5ydW5Mb2NrZWRDYWxsYmFjayh7Y2FsbGJhY2ssIGhvbGRUaW1lb3V0TXM6IGFyZ3MuaG9sZFRpbWVvdXRNcywgbG9ja0JhY2tlbmQsIG5hbWUsIHJlbGVhc2U6IGFzeW5jICgpID0+IGF3YWl0IGNvbm5lY3Rpb24ucmVsZWFzZUFkdmlzb3J5TG9jayhuYW1lKX0pXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAvKipcbiAgICogUnVucyBhIGNhbGxiYWNrIGlmIHRoZSBhZHZpc29yeSBsb2NrIGNhbiBiZSBhY3F1aXJlZCB3aXRob3V0IHdhaXRpbmc7XG4gICAqIG90aGVyd2lzZSByZXR1cm5zIGEgYHthY3F1aXJlZDogZmFsc2V9YCBkZWZlciByZXN1bHQgaW5zdGVhZCBvZiB0aHJvd2luZy5cbiAgICpcbiAgICogVGhpcyBpcyB0aGUgbm9uLXRocm93aW5nIGNvdW50ZXJwYXJ0IG9mIGB3aXRoQWR2aXNvcnlMb2NrT3JGYWlsYCBmb3IgaG90XG4gICAqIHBhdGhzOiBcImhvbGRlciBidXN5LCBkZWZlciBtZVwiIGlzIGEgZmlyc3QtY2xhc3Mgb3V0Y29tZSwgc28gYSBjb250ZW5kZWRcbiAgICogbG9jayBwcm9kdWNlcyB6ZXJvIGV4Y2VwdGlvbiB0cmFmZmljIGFuZCDigJQgYmVjYXVzZSB0aGUgcHJvYmUgaXMgYSBzaW5nbGVcbiAgICogaW1tZWRpYXRlIHRyeS1hY3F1aXJlIOKAlCB6ZXJvIHBpbm5lZCBjb25uZWN0aW9ucy4gQ2FsbGVycyByZXNjaGVkdWxlIHZpYVxuICAgKiB0aGVpciBvd24gZXZlbnQtZHJpdmVuIHJldHJ5IG1hY2hpbmVyeS4gVGhlIHJlc3VsdCBmb3JtIGlzIGlkZW50aWNhbFxuICAgKiBhY3Jvc3MgdGllcnM6IHRoZSBkcml2ZXIncyBgdHJ5QWNxdWlyZUFkdmlzb3J5TG9ja2AgbWFwcyBwZXItdGllciAoTXlTUUxcbiAgICogYEdFVF9MT0NLKG5hbWUsIDApYCwgUG9zdGdyZVNRTCBgcGdfdHJ5X2Fkdmlzb3J5X2xvY2tgLCBTUUwgU2VydmVyXG4gICAqIGBzcF9nZXRhcHBsb2NrIEBMb2NrVGltZW91dCA9IDBgLCBTUUxpdGUgcHJvY2Vzcy1sb2NhbCBxdWV1ZSwgU1FMaXRlIE5vZGVcbiAgICogZmlsZSBsb2NrKSwgc28gYSBjYWxsZXIgbmV2ZXIgYnJhbmNoZXMgb24gdGhlIGJhY2tlbmQuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTG9jayBuYW1lLlxuICAgKiBAcGFyYW0geyhhcmdzPzoge2NvbnRyb2w/OiBpbXBvcnQoXCJhd2FpdGVyeS9idWlsZC90aW1lb3V0LmpzXCIpLlRpbWVvdXRDb250cm9sLCBsb2NrQmFja2VuZDogQWR2aXNvcnlMb2NrQmFja2VuZFByb3ZlbmFuY2V9KSA9PiBQcm9taXNlPFQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHRvIGludm9rZSB3aGlsZSB0aGUgbG9jayBpcyBoZWxkLlxuICAgKiBAcGFyYW0ge3tob2xkVGltZW91dE1zPzogbnVtYmVyIHwgbnVsbCwgZGVkaWNhdGVkQ29ubmVjdGlvbj86IGJvb2xlYW59fSBbYXJnc10gLSBIb2xkIHRpbWVvdXQgb3B0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8e2FjcXVpcmVkOiB0cnVlLCByZXN1bHQ6IFR9IHwge2FjcXVpcmVkOiBmYWxzZSwgcmVhc29uOiBcImNvbnRlbmRlZFwiLCBsb2NrTmFtZTogc3RyaW5nfT59IC0gRWl0aGVyIHRoZSBoZWxkLWNhbGxiYWNrIHJlc3VsdCBvciB0aGUgZGVmZXIgb3V0Y29tZS5cbiAgICovXG4gIGFzeW5jIHdpdGhBZHZpc29yeUxvY2tPckRlZmVyKG5hbWUsIGNhbGxiYWNrLCBhcmdzID0ge30pIHtcbiAgICBjb25zdCBsb2NrU2VydmVyUmVzdWx0ID0gYXdhaXQgdGhpcy5hdHRlbXB0TG9ja1NlcnZlcih7YXJncywgY2FsbGJhY2ssIG1vZGU6IFwiZGVmZXJcIiwgbmFtZX0pXG5cbiAgICBpZiAobG9ja1NlcnZlclJlc3VsdCkge1xuICAgICAgaWYgKFwiZGVmZXJyZWRcIiBpbiBsb2NrU2VydmVyUmVzdWx0KSByZXR1cm4gbG9ja1NlcnZlclJlc3VsdC5kZWZlcnJlZFxuXG4gICAgICByZXR1cm4ge2FjcXVpcmVkOiB0cnVlLCByZXN1bHQ6IC8qKiBAdHlwZSB7e3ZhbHVlOiBUfX0gKi8gKGxvY2tTZXJ2ZXJSZXN1bHQpLnZhbHVlfVxuICAgIH1cblxuICAgIGNvbnN0IGZpbGVCYWNrZW5kID0gYXdhaXQgdGhpcy5maWxlQmFja2VuZEZvck5hbWUobmFtZSlcblxuICAgIGlmIChmaWxlQmFja2VuZCkge1xuICAgICAgY29uc3QgYWNxdWlyZWQgPSBhd2FpdCBmaWxlQmFja2VuZC5hY3F1aXJlKG5hbWUsIHt0aW1lb3V0TXM6IDB9KVxuXG4gICAgICBpZiAoIWFjcXVpcmVkKSByZXR1cm4ge2FjcXVpcmVkOiBmYWxzZSwgcmVhc29uOiBcImNvbnRlbmRlZFwiLCBsb2NrTmFtZTogbmFtZX1cblxuICAgICAgY29uc3QgbG9ja0JhY2tlbmQgPSB0aGlzLmZpbGVQcm92ZW5hbmNlKGZpbGVCYWNrZW5kLCBuYW1lKVxuXG4gICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ucmVjb3JkQWR2aXNvcnlMb2NrQWNxdWlzaXRpb24oe2JhY2tlbmQ6IGxvY2tCYWNrZW5kLmJhY2tlbmQsIGZlbmNpbmdTdXBwb3J0ZWQ6IGxvY2tCYWNrZW5kLmZlbmNpbmdTdXBwb3J0ZWQsIGxvY2tOYW1lOiBuYW1lfSlcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5ydW5Mb2NrZWRDYWxsYmFjayh7Y2FsbGJhY2ssIGhvbGRUaW1lb3V0TXM6IGFyZ3MuaG9sZFRpbWVvdXRNcywgbG9ja0JhY2tlbmQsIG5hbWUsIHJlbGVhc2U6IGFzeW5jICgpID0+IGF3YWl0IGZpbGVCYWNrZW5kLnJlbGVhc2UobmFtZSl9KVxuXG4gICAgICByZXR1cm4ge2FjcXVpcmVkOiB0cnVlLCByZXN1bHR9XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMud2l0aExvY2tDb25uZWN0aW9uKGFyZ3MsIGFzeW5jIChjb25uZWN0aW9uKSA9PiB7XG4gICAgICBjb25zdCBhY3F1aXJlZCA9IGF3YWl0IGNvbm5lY3Rpb24udHJ5QWNxdWlyZUFkdmlzb3J5TG9jayhuYW1lKVxuXG4gICAgICBpZiAoIWFjcXVpcmVkKSByZXR1cm4ge2FjcXVpcmVkOiBmYWxzZSwgcmVhc29uOiBcImNvbnRlbmRlZFwiLCBsb2NrTmFtZTogbmFtZX1cblxuICAgICAgY29uc3QgbG9ja0JhY2tlbmQgPSB0aGlzLmRyaXZlclByb3ZlbmFuY2UoY29ubmVjdGlvbilcblxuICAgICAgdGhpcy5hc3NlcnREcml2ZXJUaWVyRWxpZ2libGUobmFtZSwgbG9ja0JhY2tlbmQpXG5cbiAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5yZWNvcmRBZHZpc29yeUxvY2tBY3F1aXNpdGlvbih7YmFja2VuZDogbG9ja0JhY2tlbmQuYmFja2VuZCwgZmVuY2luZ1N1cHBvcnRlZDogbG9ja0JhY2tlbmQuZmVuY2luZ1N1cHBvcnRlZCwgbG9ja05hbWU6IG5hbWV9KVxuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnJ1bkxvY2tlZENhbGxiYWNrKHtjYWxsYmFjaywgaG9sZFRpbWVvdXRNczogYXJncy5ob2xkVGltZW91dE1zLCBsb2NrQmFja2VuZCwgbmFtZSwgcmVsZWFzZTogYXN5bmMgKCkgPT4gYXdhaXQgY29ubmVjdGlvbi5yZWxlYXNlQWR2aXNvcnlMb2NrKG5hbWUpfSlcblxuICAgICAgcmV0dXJuIHthY3F1aXJlZDogdHJ1ZSwgcmVzdWx0fVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyB0aGUgbG9jayBob2xkZXIgY2FsbGJhY2sgYW5kIHJlbGVhc2VzIHRoZSBsb2NrIGZyb20gaXRzIG93bmluZyBiYWNrZW5kLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0ge3tjYWxsYmFjazogKGFyZ3M/OiB7Y29udHJvbD86IGltcG9ydChcImF3YWl0ZXJ5L2J1aWxkL3RpbWVvdXQuanNcIikuVGltZW91dENvbnRyb2wsIGxvY2tCYWNrZW5kOiBBZHZpc29yeUxvY2tCYWNrZW5kUHJvdmVuYW5jZX0pID0+IFByb21pc2U8VD4sIGhvbGRUaW1lb3V0TXM/OiBudW1iZXIgfCBudWxsLCBsb2NrQmFja2VuZDogQWR2aXNvcnlMb2NrQmFja2VuZFByb3ZlbmFuY2UsIG5hbWU6IHN0cmluZywgcmVsZWFzZTogKCkgPT4gUHJvbWlzZTx1bmtub3duPn19IGFyZ3MgLSBMb2NrZWQgY2FsbGJhY2sgYXJncy5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgcnVuTG9ja2VkQ2FsbGJhY2soe2NhbGxiYWNrLCBob2xkVGltZW91dE1zLCBsb2NrQmFja2VuZCwgbmFtZSwgcmVsZWFzZX0pIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IEFkdmlzb3J5TG9ja1J1bm5lci5ydW5XaXRoQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXQobmFtZSwgY2FsbGJhY2ssIGhvbGRUaW1lb3V0TXMsIGxvY2tCYWNrZW5kKVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCByZWxlYXNlKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2VydmVzIG9uZSBhY3F1aXNpdGlvbiBvbiB0aGUgbG9jay1zZXJ2ZXIgdGllciB3aGVuIHRoZSBsb2NrIG5hbWUgcHJlZmVyc1xuICAgKiBpdCAoZGVzaWduIMKnMS/CpzkpLCBmYWxsaW5nICp1cHdhcmQqIHRvIHRoZSBkcml2ZXIgcGF0aCB3aGVuIHRoZSBzZXJ2ZXIgaXNcbiAgICogdW5yZWFjaGFibGUgYW5kIHRoZSBuYW1lJ3MgbWluaW11bSB0aWVyIHBlcm1pdHMgYSBEQi1uYXRpdmUgaG9sZC5cbiAgICpcbiAgICogYG51bGxgIG1lYW5zIFwidGhpcyB0aWVyIGRpZCBub3Qgc2VydmUgdGhlIGFjcXVpc2l0aW9uIOKAlCBjb250aW51ZSB3aXRoIHRoZVxuICAgKiBuZXh0IGVsaWdpYmxlIHRpZXJcIi4gQSByZXR1cm5lZCB2YWx1ZSBtZWFucyB0aGUgbG9jay1zZXJ2ZXIgdGllciBhbnN3ZXJlZCxcbiAgICogaW5jbHVkaW5nIGEgZGVmaW5pdGl2ZSBidXN5L3RpbWVvdXQgb3V0Y29tZS5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHt7YXJnczoge2hvbGRUaW1lb3V0TXM/OiBudW1iZXIgfCBudWxsLCB0aW1lb3V0TXM/OiBudW1iZXIgfCBudWxsfSwgY2FsbGJhY2s6IChhcmdzPzoge2NvbnRyb2w/OiBpbXBvcnQoXCJhd2FpdGVyeS9idWlsZC90aW1lb3V0LmpzXCIpLlRpbWVvdXRDb250cm9sLCBsb2NrQmFja2VuZDogQWR2aXNvcnlMb2NrQmFja2VuZFByb3ZlbmFuY2V9KSA9PiBQcm9taXNlPFQ+LCBtb2RlOiBcIndhaXRcIiB8IFwib3ItZmFpbFwiIHwgXCJkZWZlclwiLCBuYW1lOiBzdHJpbmd9fSByZXF1ZXN0IC0gQWNxdWlzaXRpb24gcmVxdWVzdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8e2RlZmVycmVkOiB7YWNxdWlyZWQ6IGZhbHNlLCByZWFzb246IFwiY29udGVuZGVkXCIsIGxvY2tOYW1lOiBzdHJpbmd9fSB8IHt2YWx1ZTogVH0gfCBudWxsPn0gLSBSZXN1bHQgd2hlbiB0aGlzIHRpZXIgc2VydmVkIGl0LCBvdGhlcndpc2UgbnVsbC5cbiAgICovXG4gIGFzeW5jIGF0dGVtcHRMb2NrU2VydmVyKHthcmdzLCBjYWxsYmFjaywgbW9kZSwgbmFtZX0pIHtcbiAgICBjb25zdCBwb2xpY3kgPSByZXNvbHZlQWR2aXNvcnlMb2NrQmFja2VuZFBvbGljeShuYW1lLCB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0QWR2aXNvcnlMb2NrUG9saWN5KCkpXG5cbiAgICBpZiAocG9saWN5LnByZWZlcnJlZFRpZXIgIT09IFwibG9jay1zZXJ2ZXJcIikgcmV0dXJuIG51bGxcbiAgICBpZiAoIXBvbGljeS5hbGxvd2VkVGllcnMuaW5jbHVkZXMoXCJsb2NrLXNlcnZlclwiKSkgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IGJhY2tlbmQgPSBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0QWR2aXNvcnlMb2NrTG9ja1NlcnZlckJhY2tlbmQoKVxuXG4gICAgaWYgKCFiYWNrZW5kKSB7XG4gICAgICB0aGlzLnJlcG9ydEFkdmlzb3J5TG9ja0ZhbGxiYWNrKHtyZWFzb246IFwibG9jay1zZXJ2ZXIgdGllciBpcyBub3QgZW5hYmxlZCBpbiBjb25maWd1cmF0aW9uXCIsIHNlcnZlZEJ5OiBcImRyaXZlci1uYXRpdmVcIiwgbG9ja05hbWU6IG5hbWV9KVxuXG4gICAgICByZXR1cm4gbnVsbFxuICAgIH1cblxuICAgIC8qKiBAdHlwZSB7Ym9vbGVhbn0gKi9cbiAgICBsZXQgYWNxdWlyZWRcblxuICAgIHRyeSB7XG4gICAgICBpZiAobW9kZSA9PT0gXCJ3YWl0XCIpIHtcbiAgICAgICAgYWNxdWlyZWQgPSBhd2FpdCBiYWNrZW5kLmFjcXVpcmUobmFtZSwge3RpbWVvdXRNczogdGhpcy5hY3F1aXJlVGltZW91dE1zKGFyZ3MpfSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFjcXVpcmVkID0gYXdhaXQgYmFja2VuZC50cnlBY3F1aXJlKG5hbWUpXG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmICghKGVycm9yIGluc3RhbmNlb2YgQWR2aXNvcnlMb2NrU2VydmljZVVuYXZhaWxhYmxlRXJyb3IpKSB0aHJvdyBlcnJvclxuXG4gICAgICBpZiAocG9saWN5Lm1pblRpZXIgPT09IFwibG9jay1zZXJ2ZXJcIikge1xuICAgICAgICB0aHJvdyBhZHZpc29yeUxvY2tCYWNrZW5kVW5hdmFpbGFibGUoe1xuICAgICAgICAgIGxvY2tOYW1lOiBuYW1lLFxuICAgICAgICAgIG1pblRpZXI6IHBvbGljeS5taW5UaWVyLFxuICAgICAgICAgIHJlYXNvbnM6IFtgbG9jay1zZXJ2ZXIgdW5hdmFpbGFibGU6ICR7ZXJyb3IubWVzc2FnZX1gXVxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICB0aGlzLnJlcG9ydEFkdmlzb3J5TG9ja0ZhbGxiYWNrKHtyZWFzb246IGVycm9yLm1lc3NhZ2UsIHNlcnZlZEJ5OiBcImRyaXZlci1uYXRpdmVcIiwgbG9ja05hbWU6IG5hbWV9KVxuXG4gICAgICByZXR1cm4gbnVsbFxuICAgIH1cblxuICAgIGlmICghYWNxdWlyZWQpIHtcbiAgICAgIGlmIChtb2RlID09PSBcImRlZmVyXCIpIHJldHVybiB7ZGVmZXJyZWQ6IHthY3F1aXJlZDogZmFsc2UsIHJlYXNvbjogXCJjb250ZW5kZWRcIiwgbG9ja05hbWU6IG5hbWV9fVxuICAgICAgaWYgKG1vZGUgPT09IFwib3ItZmFpbFwiKSB0aHJvdyBuZXcgQWR2aXNvcnlMb2NrQnVzeUVycm9yKGBBZHZpc29yeSBsb2NrICR7SlNPTi5zdHJpbmdpZnkobmFtZSl9IGlzIGFscmVhZHkgaGVsZGAsIHtuYW1lfSlcblxuICAgICAgdGhyb3cgbmV3IEFkdmlzb3J5TG9ja1RpbWVvdXRFcnJvcihgVGltZWQgb3V0IHdhaXRpbmcgZm9yIGFkdmlzb3J5IGxvY2sgJHtKU09OLnN0cmluZ2lmeShuYW1lKX1gLCB7bmFtZX0pXG4gICAgfVxuXG4gICAgY29uc3QgZXBvY2ggPSBiYWNrZW5kLmdldEhvbGRFcG9jaChuYW1lKVxuICAgIGNvbnN0IGxvY2tCYWNrZW5kID0gLyoqIEB0eXBlIHtBZHZpc29yeUxvY2tCYWNrZW5kUHJvdmVuYW5jZX0gKi8gKHtcbiAgICAgIGJhY2tlbmQ6IFwibG9jay1zZXJ2ZXJcIixcbiAgICAgIGVwb2NoOiBlcG9jaCA/PyB1bmRlZmluZWQsXG4gICAgICBmZW5jaW5nU3VwcG9ydGVkOiB0cnVlLFxuICAgICAgbG9ja05hbWU6IG5hbWVcbiAgICB9KVxuXG4gICAgdGhpcy5jb25maWd1cmF0aW9uLnJlY29yZEFkdmlzb3J5TG9ja0FjcXVpc2l0aW9uKHtiYWNrZW5kOiBcImxvY2stc2VydmVyXCIsIGZlbmNpbmdTdXBwb3J0ZWQ6IHRydWUsIGxvY2tOYW1lOiBuYW1lfSlcblxuICAgICAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IHRoaXMucnVuTG9ja1NlcnZlckhvbGQoe1xuICAgICAgYmFja2VuZCxcbiAgICAgIGNhbGxiYWNrLFxuICAgICAgaG9sZFRpbWVvdXRNczogYXJncy5ob2xkVGltZW91dE1zLFxuICAgICAgbG9ja0JhY2tlbmQsXG4gICAgICBuYW1lXG4gICAgfSlcblxuICAgIHJldHVybiB7dmFsdWV9XG4gIH1cblxuICAvKipcbiAgICogUnVucyB0aGUgY3JpdGljYWwgc2VjdGlvbiB1bmRlciBhIGxvY2stc2VydmVyIGxlYXNlIGFuZCBzdXJmYWNlcyBhIGZlbmNlZFxuICAgKiBsZWFzZSBhcyBgQWR2aXNvcnlMb2NrTG9zdEVycm9yYCAoZGVzaWduIMKnOCk6IHRoZSBzZWN0aW9uIG1heSBoYXZlXG4gICAqIG92ZXJsYXBwZWQgYW5vdGhlciBob2xkZXIsIHNvIGl0cyBvdXRjb21lIG11c3Qgbm90IGJlIHRydXN0ZWQgYXMgZXhjbHVzaXZlLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0ge3tiYWNrZW5kOiBpbXBvcnQoXCIuL2Fkdmlzb3J5LWxvY2stbG9jay1zZXJ2ZXItYmFja2VuZC5qc1wiKS5kZWZhdWx0LCBjYWxsYmFjazogKGFyZ3M/OiB7Y29udHJvbD86IGltcG9ydChcImF3YWl0ZXJ5L2J1aWxkL3RpbWVvdXQuanNcIikuVGltZW91dENvbnRyb2wsIGxvY2tCYWNrZW5kOiBBZHZpc29yeUxvY2tCYWNrZW5kUHJvdmVuYW5jZX0pID0+IFByb21pc2U8VD4sIGhvbGRUaW1lb3V0TXM/OiBudW1iZXIgfCBudWxsLCBsb2NrQmFja2VuZDogQWR2aXNvcnlMb2NrQmFja2VuZFByb3ZlbmFuY2UsIG5hbWU6IHN0cmluZ319IGFyZ3MgLSBIb2xkIHJlcXVlc3QuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIENhbGxiYWNrIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIHJ1bkxvY2tTZXJ2ZXJIb2xkKHtiYWNrZW5kLCBjYWxsYmFjaywgaG9sZFRpbWVvdXRNcywgbG9ja0JhY2tlbmQsIG5hbWV9KSB7XG4gICAgLyoqIEB0eXBlIHtUIHwgdW5kZWZpbmVkfSAqL1xuICAgIGxldCB2YWx1ZVxuICAgIC8qKiBAdHlwZSB7dW5rbm93bn0gKi9cbiAgICBsZXQgY2FsbGJhY2tFcnJvclxuICAgIGxldCBmYWlsZWQgPSBmYWxzZVxuXG4gICAgdHJ5IHtcbiAgICAgIHZhbHVlID0gYXdhaXQgdGhpcy5ydW5Mb2NrZWRDYWxsYmFjayh7XG4gICAgICAgIGNhbGxiYWNrLFxuICAgICAgICBob2xkVGltZW91dE1zLFxuICAgICAgICBsb2NrQmFja2VuZCxcbiAgICAgICAgbmFtZSxcbiAgICAgICAgcmVsZWFzZTogYXN5bmMgKCkgPT4gYXdhaXQgYmFja2VuZC5yZWxlYXNlKG5hbWUpXG4gICAgICB9KVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBmYWlsZWQgPSB0cnVlXG4gICAgICBjYWxsYmFja0Vycm9yID0gZXJyb3JcbiAgICB9XG5cbiAgICBjb25zdCBsb3NzID0gYmFja2VuZC50YWtlTG9zcyhuYW1lLCBsb2NrQmFja2VuZC5lcG9jaCA/PyBudWxsKVxuXG4gICAgaWYgKGxvc3MpIHtcbiAgICAgIHRocm93IG5ldyBBZHZpc29yeUxvY2tMb3N0RXJyb3IoXG4gICAgICAgIGBMb3N0IHRoZSBsZWFzZSBmb3IgYWR2aXNvcnkgbG9jayAke0pTT04uc3RyaW5naWZ5KG5hbWUpfSB3aGlsZSB0aGUgY3JpdGljYWwgc2VjdGlvbiB3YXMgcnVubmluZ2AsXG4gICAgICAgIHtcbiAgICAgICAgICBjYXVzZTogY2FsbGJhY2tFcnJvciBpbnN0YW5jZW9mIEVycm9yID8gY2FsbGJhY2tFcnJvciA6IHVuZGVmaW5lZCxcbiAgICAgICAgICBjdXJyZW50RXBvY2g6IGxvc3MuY3VycmVudEVwb2NoLFxuICAgICAgICAgIGVwb2NoOiBsb2NrQmFja2VuZC5lcG9jaCA/PyBudWxsLFxuICAgICAgICAgIGxvY2tOYW1lOiBuYW1lXG4gICAgICAgIH1cbiAgICAgIClcbiAgICB9XG5cbiAgICBpZiAoZmFpbGVkKSB0aHJvdyBjYWxsYmFja0Vycm9yXG5cbiAgICByZXR1cm4gLyoqIEB0eXBlIHtUfSAqLyAodmFsdWUpXG4gIH1cblxuICAvKipcbiAgICogUmVwb3J0cyBhbiBhY3F1aXNpdGlvbiBzZXJ2ZWQgYmVsb3cgdGhlIGxvY2sgbmFtZSdzIHByZWZlcnJlZCB0aWVyXG4gICAqIChkZXNpZ24gwqczKTogZXZlcnkgZmFsbGJhY2sgaXMgdmlzaWJsZSBvbiB0aGUgZnJhbWV3b3JrLWVycm9yIGNoYW5uZWwsIHNvIGFcbiAgICogc2lsZW50IGRvd25ncmFkZSBpcyBpbXBvc3NpYmxlLlxuICAgKiBAcGFyYW0ge3tsb2NrTmFtZTogc3RyaW5nLCByZWFzb246IHN0cmluZywgc2VydmVkQnk6IGltcG9ydChcIi4vYWR2aXNvcnktbG9jay1iYWNrZW5kLXBvbGljeS5qc1wiKS5BZHZpc29yeUxvY2tUaWVyfX0gYXJncyAtIEZhbGxiYWNrIGRldGFpbHMuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgcmVwb3J0QWR2aXNvcnlMb2NrRmFsbGJhY2soe2xvY2tOYW1lLCByZWFzb24sIHNlcnZlZEJ5fSkge1xuICAgIGNvbnN0IHBvbGljeSA9IHJlc29sdmVBZHZpc29yeUxvY2tCYWNrZW5kUG9saWN5KGxvY2tOYW1lLCB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0QWR2aXNvcnlMb2NrUG9saWN5KCkpXG4gICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgIGNvbnRleHQ6IFwiYWR2aXNvcnktbG9jay1mYWxsYmFja1wiLFxuICAgICAgbG9ja05hbWUsXG4gICAgICBwcmVmZXJyZWRUaWVyOiBwb2xpY3kucHJlZmVycmVkVGllcixcbiAgICAgIHJlYXNvbixcbiAgICAgIHNlcnZlZEJ5XG4gICAgfVxuICAgIGNvbnN0IGVycm9yRXZlbnRzID0gdGhpcy5jb25maWd1cmF0aW9uLmdldEVycm9yRXZlbnRzKClcblxuICAgIGVycm9yRXZlbnRzLmVtaXQoXCJmcmFtZXdvcmstZXJyb3JcIiwgcGF5bG9hZClcbiAgICBlcnJvckV2ZW50cy5lbWl0KFwiYWxsLWVycm9yXCIsIHsuLi5wYXlsb2FkLCBlcnJvclR5cGU6IFwiZnJhbWV3b3JrLWVycm9yXCJ9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIHRoZSBiYWNrZW5kIHBvbGljeSBmb3Igb25lIGxvY2sgbmFtZSBhbmQgcmV0dXJucyB0aGUgZmlsZVxuICAgKiBiYWNrZW5kIHdoZW4gdGhlIG5hbWUgZXhwbGljaXRseSBvcHRzIGludG8gdGhlIGZpbGUgdGllclxuICAgKiAoYHByZWZlcnJlZFRpZXI6IFwiZmlsZVwiYCBwbHVzIGBhZHZpc29yeUxvY2tzLmJhY2tlbmRzLmZpbGUuZW5hYmxlZDogdHJ1ZWApLlxuICAgKiBBIG5hbWUgd2hvc2UgZGVjbGFyZWQgbWluaW11bSB0aWVyIGlzIGNyb3NzLWhvc3QgaXMgcmVmdXNlZCBsb3VkbHlcbiAgICogKGBBZHZpc29yeUxvY2tNaW5UaWVyUmVmdXNlZEVycm9yYCkgYmVmb3JlIGFueSBjb250YWN0IHdpdGggdGhlIGZpbGVcbiAgICogdGllci4gQSBuYW1lIHRoYXQgcHJlZmVycyB0aGUgZmlsZSB0aWVyIHdoaWxlIHRoZSBiYWNrZW5kIGlzIGRpc2FibGVkXG4gICAqIG1vdmVzIHRvIHRoZSBkcml2ZXIgcGF0aCAoYSBzdHJvbmdlci1vci1lcXVhbCB0aWVyKSwgbmV2ZXIgdGhlIG90aGVyIHdheVxuICAgKiBhcm91bmQuIE5vdGhpbmcgaGVyZSBldmVyIGF1dG8tZW5hYmxlcyB0aGUgZmlsZSB0aWVyLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIExvY2sgbmFtZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi9hZHZpc29yeS1sb2NrLWZpbGUtYmFja2VuZC5qc1wiKS5kZWZhdWx0IHwgbnVsbD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgZmlsZSBiYWNrZW5kIHNlcnZpbmcgdGhpcyBuYW1lLCBvciBudWxsIGZvciB0aGUgZHJpdmVyIHBhdGguXG4gICAqL1xuICBhc3luYyBmaWxlQmFja2VuZEZvck5hbWUobmFtZSkge1xuICAgIGNvbnN0IHBvbGljeSA9IHJlc29sdmVBZHZpc29yeUxvY2tCYWNrZW5kUG9saWN5KG5hbWUsIHRoaXMuY29uZmlndXJhdGlvbi5nZXRBZHZpc29yeUxvY2tQb2xpY3koKSlcblxuICAgIGlmIChwb2xpY3kucHJlZmVycmVkVGllciAhPT0gXCJmaWxlXCIpIHJldHVybiBudWxsXG5cbiAgICBpZiAoIWFkdmlzb3J5TG9ja1BvbGljeUFsbG93c0ZpbGVUaWVyKHBvbGljeSkpIHtcbiAgICAgIHJlZnVzZUFkdmlzb3J5TG9ja1RpZXJCZWxvd01pbmltdW0oe1xuICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24sXG4gICAgICAgIGxvY2tOYW1lOiBuYW1lLFxuICAgICAgICBtaW5UaWVyOiBwb2xpY3kubWluVGllcixcbiAgICAgICAgcmVxdWVzdGVkQmFja2VuZDogXCJmaWxlXCJcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgY29uc3QgYmFja2VuZCA9IGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5nZXRBZHZpc29yeUxvY2tGaWxlQmFja2VuZCgpXG5cbiAgICBpZiAoIWJhY2tlbmQpIHtcbiAgICAgIC8vIFByZWZlcnJlZCB0aWVyIHVuYXZhaWxhYmxlOiBmYWlsICp1cHdhcmQqIHRvIHRoZSBkcml2ZXIgcGF0aCAoYVxuICAgICAgLy8gc3Ryb25nZXItb3ItZXF1YWwgdGllciksIG5ldmVyIGRvd253YXJkLiBJZiB0aGUgZHJpdmVyIGNhbm5vdCBzYXRpc2Z5XG4gICAgICAvLyB0aGUgbWluaW11bSBlaXRoZXIsIGBhc3NlcnREcml2ZXJUaWVyRWxpZ2libGVgIHRocm93c1xuICAgICAgLy8gYEFkdmlzb3J5TG9ja0JhY2tlbmRVbmF2YWlsYWJsZUVycm9yYCBvbiB0aGUgZHJpdmVyIHBhdGguXG4gICAgICByZXR1cm4gbnVsbFxuICAgIH1cblxuICAgIHJldHVybiBiYWNrZW5kXG4gIH1cblxuICAvKipcbiAgICogRmFpbC1jbG9zZWQgY2hlY2sgb24gdGhlIGRyaXZlciBwYXRoIChkZXNpZ24gwqc5KTogYW4gdW5kZWNsYXJlZCBsb2NrIG5hbWVcbiAgICoga2VlcHMgdG9kYXkncyBiZWhhdmlvciAoYW55IGRyaXZlciBzZXJ2ZXMgaXQg4oCUIGZ1bGwgYmFja3dhcmRcbiAgICogY29tcGF0aWJpbGl0eSksIGJ1dCBhIG5hbWUgd2l0aCBhbiBleHBsaWNpdCBwb2xpY3kgZW50cnkgaXMgcmVmdXNlZCB3aXRoXG4gICAqIGBBZHZpc29yeUxvY2tCYWNrZW5kVW5hdmFpbGFibGVFcnJvcmAgd2hlbiB0aGUgY29uZmlndXJlZCBkcml2ZXIgY2Fubm90XG4gICAqIHNhdGlzZnkgaXRzIG1pbmltdW0gdGllciAoZS5nLiBgbWluVGllcjogXCJkcml2ZXItbmF0aXZlXCJgIG9uIGEgU1FMaXRlXG4gICAqIGRyaXZlciwgd2hpY2ggaGFzIG5vIG5hdGl2ZSBhZHZpc29yeS1sb2NrIHByaW1pdGl2ZSkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTG9jayBuYW1lLlxuICAgKiBAcGFyYW0ge0Fkdmlzb3J5TG9ja0JhY2tlbmRQcm92ZW5hbmNlfSBsb2NrQmFja2VuZCAtIFRpZXIgdGhlIGRyaXZlciBwYXRoIHdvdWxkIHNlcnZlIHdpdGguXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgYXNzZXJ0RHJpdmVyVGllckVsaWdpYmxlKG5hbWUsIGxvY2tCYWNrZW5kKSB7XG4gICAgY29uc3QgcG9saWN5ID0gcmVzb2x2ZUFkdmlzb3J5TG9ja0JhY2tlbmRQb2xpY3kobmFtZSwgdGhpcy5jb25maWd1cmF0aW9uLmdldEFkdmlzb3J5TG9ja1BvbGljeSgpKVxuXG4gICAgaWYgKCFwb2xpY3kuZW50cnkpIHJldHVyblxuXG4gICAgY29uc3QgdGllciA9IGxvY2tCYWNrZW5kLmJhY2tlbmRcblxuICAgIGlmICh0aWVyID09PSBcInByb2Nlc3MtbG9jYWxcIiAmJiAhcG9saWN5LmFsbG93ZWRUaWVycy5pbmNsdWRlcyhcInByb2Nlc3MtbG9jYWxcIikpIHtcbiAgICAgIHRocm93IG5ldyBBZHZpc29yeUxvY2tCYWNrZW5kVW5hdmFpbGFibGVFcnJvcihcbiAgICAgICAgYEFkdmlzb3J5IGxvY2sgJHtKU09OLnN0cmluZ2lmeShuYW1lKX0gcmVxdWlyZXMgbWluaW11bSB0aWVyICR7SlNPTi5zdHJpbmdpZnkocG9saWN5Lm1pblRpZXIpfSBidXQgdGhlIGNvbmZpZ3VyZWQgZHJpdmVyICgke1N0cmluZyhsb2NrQmFja2VuZC5kcml2ZXJUeXBlKX0pIG9ubHkgb2ZmZXJzIHRoZSBwcm9jZXNzLWxvY2FsIHRpZXJgLFxuICAgICAgICB7bG9ja05hbWU6IG5hbWUsIG1pblRpZXI6IHBvbGljeS5taW5UaWVyLCByZWFzb25zOiBbYGRyaXZlciB0aWVyICR7dGllcn0gYmVsb3cgbWluVGllciAke3BvbGljeS5taW5UaWVyfWBdfVxuICAgICAgKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgd2FpdCBib3VuZCBmb3IgYSBmaWxlLXRpZXIgYWNxdWlzaXRpb246IGFuIGV4cGxpY2l0IGNhbGxlclxuICAgKiBgdGltZW91dE1zYCAoaW5jbHVkaW5nIGFuIGV4cGxpY2l0IGBudWxsYCBvcHQtb3V0KSB3aW5zLCBvdGhlcndpc2UgdGhlXG4gICAqIHNhbWUgZnJhbWV3b3JrIGRlZmF1bHQgdGhhdCBib3VuZHMgZHJpdmVyIGFjcXVpc2l0aW9ucyBhcHBsaWVzLlxuICAgKiBAcGFyYW0ge3t0aW1lb3V0TXM/OiBudW1iZXIgfCBudWxsfX0gYXJncyAtIExvY2sgb3B0aW9ucy5cbiAgICogQHJldHVybnMge251bWJlciB8IG51bGx9IC0gV2FpdCBib3VuZCBpbiBtaWxsaXNlY29uZHMsIG9yIGBudWxsYCBmb3IgYW4gaW5kZWZpbml0ZSB3YWl0LlxuICAgKi9cbiAgYWNxdWlyZVRpbWVvdXRNcyhhcmdzKSB7XG4gICAgaWYgKGFyZ3MudGltZW91dE1zICE9PSB1bmRlZmluZWQpIHJldHVybiBhcmdzLnRpbWVvdXRNc1xuXG4gICAgcmV0dXJuIERFRkFVTFRfQURWSVNPUllfTE9DS19BQ1FVSVJFX1RJTUVPVVRfTVNcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIGFjcXVpc2l0aW9uIHByb3ZlbmFuY2UgZm9yIGEgZmlsZS10aWVyIGhvbGQuIFRoZSBmaWxlIHRpZXJcbiAgICogY2Fubm90IGNhcnJ5IGZlbmNpbmcgdG9rZW5zLCBzbyB0aGUgbGltaXRhdGlvbiBpcyByZXBvcnRlZCBvbiBldmVyeVxuICAgKiBhY3F1aXNpdGlvbiByYXRoZXIgdGhhbiBzaWxlbnRseSBwcmV0ZW5kZWQgYXdheSAoZGVzaWduIMKnOCkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9hZHZpc29yeS1sb2NrLWZpbGUtYmFja2VuZC5qc1wiKS5kZWZhdWx0fSBiYWNrZW5kIC0gQmFja2VuZCB0aGF0IHNlcnZlZCB0aGUgYWNxdWlzaXRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTG9jayBuYW1lLlxuICAgKiBAcmV0dXJucyB7QWR2aXNvcnlMb2NrQmFja2VuZFByb3ZlbmFuY2V9IC0gQWNxdWlzaXRpb24gcHJvdmVuYW5jZS5cbiAgICovXG4gIGZpbGVQcm92ZW5hbmNlKGJhY2tlbmQsIG5hbWUpIHtcbiAgICByZXR1cm4ge2JhY2tlbmQ6IFwiZmlsZVwiLCBmZW5jaW5nU3VwcG9ydGVkOiBmYWxzZSwgaG9sZGVySWQ6IGJhY2tlbmQuaG9sZGVySWQsIGxvY2tOYW1lOiBuYW1lfVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyB0aGUgYWNxdWlzaXRpb24gcHJvdmVuYW5jZSBmb3IgYSBkcml2ZXItc2VydmVkIGhvbGQuIFNRTGl0ZSBoYXMgbm9cbiAgICogbmF0aXZlIGFkdmlzb3J5LWxvY2sgcHJpbWl0aXZlLCBzbyBpdHMgZW11bGF0aW9uIHRpZXIgaXMgcmVwb3J0ZWQgYXNcbiAgICogYHByb2Nlc3MtbG9jYWxgIHJhdGhlciB0aGFuIHByZXRlbmRpbmcgdG8gYmUgZGF0YWJhc2UtbmF0aXZlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uIHRoYXQgc2VydmVkIHRoZSBhY3F1aXNpdGlvbi5cbiAgICogQHJldHVybnMge0Fkdmlzb3J5TG9ja0JhY2tlbmRQcm92ZW5hbmNlfSAtIEFjcXVpc2l0aW9uIHByb3ZlbmFuY2UuXG4gICAqL1xuICBkcml2ZXJQcm92ZW5hbmNlKGNvbm5lY3Rpb24pIHtcbiAgICBsZXQgZHJpdmVyVHlwZSA9IG51bGxcblxuICAgIHRyeSB7XG4gICAgICBkcml2ZXJUeXBlID0gY29ubmVjdGlvbi5nZXRUeXBlKClcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIFRlc3Qgc3R1YiBkcml2ZXJzIG1heSBub3QgaW1wbGVtZW50IGdldFR5cGUoKTsgdGhlIHRpZXIgYWxvbmUgaWRlbnRpZmllcyB0aGUgYmFja2VuZC5cbiAgICB9XG5cbiAgICBjb25zdCB0aWVyID0gdHlwZW9mIGNvbm5lY3Rpb24uYWR2aXNvcnlMb2NrQmFja2VuZFRpZXIgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgPyBjb25uZWN0aW9uLmFkdmlzb3J5TG9ja0JhY2tlbmRUaWVyKClcbiAgICAgIDogKGRyaXZlclR5cGUgPT09IFwic3FsaXRlXCIgPyBcInByb2Nlc3MtbG9jYWxcIiA6IFwiZHJpdmVyLW5hdGl2ZVwiKVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGJhY2tlbmQ6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9hZHZpc29yeS1sb2NrLWJhY2tlbmQtcG9saWN5LmpzXCIpLkFkdmlzb3J5TG9ja1RpZXJ9ICovICh0aWVyKSxcbiAgICAgIGRyaXZlclR5cGU6IGRyaXZlclR5cGUgPz8gdW5kZWZpbmVkLFxuICAgICAgZmVuY2luZ1N1cHBvcnRlZDogdGllciA9PT0gXCJkcml2ZXItbmF0aXZlXCJcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBsb2NrIHdvcmsgb24gdGhlIGNhbGxlciBjb25uZWN0aW9uIHVubGVzcyBgZGVkaWNhdGVkQ29ubmVjdGlvbmAgaXNcbiAgICogcmVxdWVzdGVkIG9yIGEgcG9zaXRpdmUgaG9sZCB0aW1lb3V0IG5lZWRzIGl0cyBvd24gbG9jayBjb25uZWN0aW9uLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0ge3tkZWRpY2F0ZWRDb25uZWN0aW9uPzogYm9vbGVhbiwgaG9sZFRpbWVvdXRNcz86IG51bWJlciB8IG51bGx9fSBhcmdzIC0gTG9jayBjb25uZWN0aW9uIG9wdGlvbnMuXG4gICAqIEBwYXJhbSB7KGNvbm5lY3Rpb246IGltcG9ydChcIi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQpID0+IFByb21pc2U8VD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgcmVjZWl2aW5nIHRoZSBjb25uZWN0aW9uIHRoYXQgb3ducyB0aGUgYWR2aXNvcnkgbG9jay5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgd2l0aExvY2tDb25uZWN0aW9uKGFyZ3MsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgaG9sZFRpbWVvdXRNcyA9IGFyZ3MuaG9sZFRpbWVvdXRNc1xuXG4gICAgaWYgKGFyZ3MuZGVkaWNhdGVkQ29ubmVjdGlvbiB8fCAoaG9sZFRpbWVvdXRNcyAmJiBob2xkVGltZW91dE1zID4gMCkpIHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLndpdGhEZWRpY2F0ZWRDb25uZWN0aW9uKGNhbGxiYWNrKVxuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCBjYWxsYmFjayh0aGlzLmNvbm5lY3Rpb25Qcm92aWRlcigpKVxuICB9XG5cbiAgLyoqXG4gICAqIFNwYXducyBhIGRlZGljYXRlZCBsb2NrIGNvbm5lY3Rpb24gYW5kIGNsb3NlcyBpdCBhZnRlciBsb2NrIHdvcmsgY29tcGxldGVzXG4gICAqIHdoZW4gdGhlIHNwYXduZWQgZHJpdmVyIG93bnMgdGhlIHVuZGVybHlpbmcgcGh5c2ljYWwgY29ubmVjdGlvbi5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHsoY29ubmVjdGlvbjogaW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCkgPT4gUHJvbWlzZTxUPn0gY2FsbGJhY2sgLSBDYWxsYmFjayB0aGF0IHJlY2VpdmVzIHRoZSBkZWRpY2F0ZWQgbG9jayBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBhc3luYyB3aXRoRGVkaWNhdGVkQ29ubmVjdGlvbihjYWxsYmFjaykge1xuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0RGF0YWJhc2VQb29sKHRoaXMuZGF0YWJhc2VJZGVudGlmaWVyKS5zcGF3bkNvbm5lY3Rpb24oKVxuXG4gICAgLy8gVGhlIHNwYXduZWQgZHJpdmVyIG93bnMgaXRzIHBoeXNpY2FsIGNvbm5lY3Rpb24gdW5sZXNzIGl0IGJvcnJvd3MgYSBzaGFyZWQgb25lXG4gICAgLy8gdmlhIGBnZXRDb25uZWN0aW9uYC4gQW4gb3duZWQgY29ubmVjdGlvbiBsaXZlcyBvdXRzaWRlIHRoZSBwb29scycgdHJhY2tlZCBzZXRzLFxuICAgIC8vIHNvIHJlZ2lzdGVyIGl0IHdoaWxlIHRoZSBsb2NrIGlzIGhlbGQ6IGEgc2h1dGRvd24gdGhlbiBjbG9zZXMgaXQgKHJlbGVhc2luZyB0aGVcbiAgICAvLyBsb2NrKSBpbnN0ZWFkIG9mIG9ycGhhbmluZyBhIGhhbGYtb3BlbiBzZXNzaW9uIHVudGlsIHRoZSBEQiBgd2FpdF90aW1lb3V0YC5cbiAgICBjb25zdCBvd25zQ29ubmVjdGlvbiA9ICFjb25uZWN0aW9uLmdldEFyZ3MoKS5nZXRDb25uZWN0aW9uXG5cbiAgICBpZiAob3duc0Nvbm5lY3Rpb24pIHRoaXMuY29uZmlndXJhdGlvbi5yZWdpc3RlckFkdmlzb3J5TG9ja0Nvbm5lY3Rpb24oY29ubmVjdGlvbilcblxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgY2FsbGJhY2soY29ubmVjdGlvbilcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKG93bnNDb25uZWN0aW9uKSB7XG4gICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi51bnJlZ2lzdGVyQWR2aXNvcnlMb2NrQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuICAgICAgICBhd2FpdCBjb25uZWN0aW9uLmNsb3NlKClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGF3YWl0IGNvbm5lY3Rpb24ucmVsZWFzZUhlbGRBZHZpc29yeUxvY2tzKClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBgY2FsbGJhY2tgLCByZWplY3Rpbmcgd2l0aCBgQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXRFcnJvcmAgaWYgaXQgaGFzXG4gICAqIG5vdCBzZXR0bGVkIHdpdGhpbiBgaG9sZFRpbWVvdXRNc2AuIFRoZSBjYWxsYmFjayBpcyBub3QgY2FuY2VsbGVkOyBjYWxsZXJzXG4gICAqIHVzZSBhIGRlZGljYXRlZCBhZHZpc29yeS1sb2NrIGNvbm5lY3Rpb24gc28gdGhlIGxvY2sgY2FuIHN0aWxsIGJlIHJlbGVhc2VkLlxuICAgKlxuICAgKiBUaGUgY2FsbGJhY2sgcmVjZWl2ZXMgYSBgVGltZW91dENvbnRyb2xgIGZyb20gYXdhaXRlcnksIGVuYWJsaW5nIGNvb3BlcmF0aXZlXG4gICAqIGNhbmNlbGxhdGlvbiB2aWEgYGNvbnRyb2wuY2hlY2soKWAsIGBjb250cm9sLnNpZ25hbGAsIGBjb250cm9sLnRpbWVkT3V0YCxcbiAgICogYW5kIGBjb250cm9sLnJlbWFpbmluZygpYCwgcGx1cyBgbG9ja0JhY2tlbmRgIHByb3ZlbmFuY2UgZm9yIHRoZSB0aWVyIHRoYXRcbiAgICogc2VydmVkIHRoZSBhY3F1aXNpdGlvbi5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBMb2NrIG5hbWUgKGZvciB0aGUgZXJyb3IgbWVzc2FnZSkuXG4gICAqIEBwYXJhbSB7KGFyZ3M/OiB7Y29udHJvbD86IGltcG9ydChcImF3YWl0ZXJ5L2J1aWxkL3RpbWVvdXQuanNcIikuVGltZW91dENvbnRyb2wsIGxvY2tCYWNrZW5kOiBBZHZpc29yeUxvY2tCYWNrZW5kUHJvdmVuYW5jZX0pID0+IFByb21pc2U8VD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgaG9sZGluZyB0aGUgbG9jay5cbiAgICogQHBhcmFtIHtudW1iZXIgfCBudWxsfSBbaG9sZFRpbWVvdXRNc10gLSBNYXggaG9sZCB0aW1lOyBmYWxzeSBkaXNhYmxlcyB0aGUgdGltZW91dC5cbiAgICogQHBhcmFtIHtBZHZpc29yeUxvY2tCYWNrZW5kUHJvdmVuYW5jZX0gW2xvY2tCYWNrZW5kXSAtIFByb3ZlbmFuY2Ugb2YgdGhlIGFjcXVpc2l0aW9uIHNlcnZpbmcgdGhpcyBob2xkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgcnVuV2l0aEFkdmlzb3J5TG9ja0hvbGRUaW1lb3V0KG5hbWUsIGNhbGxiYWNrLCBob2xkVGltZW91dE1zLCBsb2NrQmFja2VuZCkge1xuICAgIGlmICghaG9sZFRpbWVvdXRNcyB8fCBob2xkVGltZW91dE1zIDw9IDApIHtcbiAgICAgIHJldHVybiBhd2FpdCBjYWxsYmFjayh7bG9ja0JhY2tlbmQ6IGxvY2tCYWNrZW5kID8/IEFkdmlzb3J5TG9ja1J1bm5lci51bmtub3duQmFja2VuZFByb3ZlbmFuY2UoKX0pXG4gICAgfVxuXG4gICAgbGV0IGNhbGxiYWNrU2V0dGxlZCA9IGZhbHNlXG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRpbWVvdXQoe3RpbWVvdXQ6IGhvbGRUaW1lb3V0TXN9LCBhc3luYyAoe2NvbnRyb2x9KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IGNhbGxiYWNrKHtjb250cm9sLCBsb2NrQmFja2VuZDogbG9ja0JhY2tlbmQgPz8gQWR2aXNvcnlMb2NrUnVubmVyLnVua25vd25CYWNrZW5kUHJvdmVuYW5jZSgpfSlcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBjYWxsYmFja1NldHRsZWQgPSB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmICghY2FsbGJhY2tTZXR0bGVkIHx8IGVycm9yIGluc3RhbmNlb2YgVGltZW91dEVycm9yKSB7XG4gICAgICAgIHRocm93IG5ldyBBZHZpc29yeUxvY2tIb2xkVGltZW91dEVycm9yKGBBZHZpc29yeSBsb2NrICR7SlNPTi5zdHJpbmdpZnkobmFtZSl9IGhlbGQgbG9uZ2VyIHRoYW4gJHtob2xkVGltZW91dE1zfW1zYCwge25hbWV9KVxuICAgICAgfVxuXG4gICAgICB0aHJvdyBlcnJvclxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBOZXV0cmFsIHByb3ZlbmFuY2UgZm9yIGRpcmVjdCBgcnVuV2l0aEFkdmlzb3J5TG9ja0hvbGRUaW1lb3V0YCBjYWxsZXJzIHRoYXRcbiAgICogaG9sZCBhIGxvY2sgYWNxdWlyZWQgb3V0c2lkZSB0aGlzIHJ1bm5lci5cbiAgICogQHJldHVybnMge0Fkdmlzb3J5TG9ja0JhY2tlbmRQcm92ZW5hbmNlfSAtIFByb3ZlbmFuY2Ugd2l0aCBhbiB1bmtub3duIHRpZXIuXG4gICAqL1xuICBzdGF0aWMgdW5rbm93bkJhY2tlbmRQcm92ZW5hbmNlKCkge1xuICAgIHJldHVybiB7YmFja2VuZDogXCJwcm9jZXNzLWxvY2FsXCIsIGZlbmNpbmdTdXBwb3J0ZWQ6IGZhbHNlfVxuICB9XG59XG5cbi8qKlxuICogUnVucyBhZHZpc29yeSBsb2NrIHBvbGljeSBhbGxvd3MgZmlsZSB0aWVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Fkdmlzb3J5LWxvY2stYmFja2VuZC1wb2xpY3kuanNcIikuUmVzb2x2ZWRBZHZpc29yeUxvY2tCYWNrZW5kUG9saWN5fSBwb2xpY3kgLSBSZXNvbHZlZCBwb2xpY3kuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSBmaWxlIHRpZXIgbWF5IHNlcnZlIHRoaXMgbmFtZS5cbiAqL1xuZnVuY3Rpb24gYWR2aXNvcnlMb2NrUG9saWN5QWxsb3dzRmlsZVRpZXIocG9saWN5KSB7XG4gIHJldHVybiBwb2xpY3kuYWxsb3dlZFRpZXJzLmluY2x1ZGVzKFwiZmlsZVwiKVxufVxuXG5leHBvcnQge0Fkdmlzb3J5TG9ja0J1c3lFcnJvciwgQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXRFcnJvciwgQWR2aXNvcnlMb2NrVGltZW91dEVycm9yfVxuZXhwb3J0IHtBZHZpc29yeUxvY2tCYWNrZW5kVW5hdmFpbGFibGVFcnJvciwgQWR2aXNvcnlMb2NrTWluVGllclJlZnVzZWRFcnJvcn0gZnJvbSBcIi4vYWR2aXNvcnktbG9jay1iYWNrZW5kLXBvbGljeS5qc1wiXG5leHBvcnQge0Fkdmlzb3J5TG9ja0xvc3RFcnJvciwgQWR2aXNvcnlMb2NrU2VydmljZVVuYXZhaWxhYmxlRXJyb3J9IGZyb20gXCIuL2Fkdmlzb3J5LWxvY2stZXJyb3JzLmpzXCJcbiJdfQ==
550
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWR2aXNvcnktbG9jay1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGF0YWJhc2UvYWR2aXNvcnktbG9jay1ydW5uZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sT0FBTyxFQUFFLEVBQUMsWUFBWSxFQUFDLE1BQU0sMkJBQTJCLENBQUE7QUFDL0QsT0FBTyxFQUFDLHdDQUF3QyxFQUFDLE1BQU0sMEJBQTBCLENBQUE7QUFDakYsT0FBTyxFQUNMLG1DQUFtQyxFQUNuQyxnQ0FBZ0MsRUFDaEMsa0NBQWtDLEVBQ25DLE1BQU0sbUNBQW1DLENBQUE7QUFDMUMsT0FBTyxFQUNMLHFCQUFxQixFQUNyQixtQ0FBbUMsRUFDbkMsOEJBQThCLEVBQy9CLE1BQU0sMkJBQTJCLENBQUE7QUFDbEMsT0FBTyxFQUFDLDhCQUE4QixFQUFDLE1BQU0sOEJBQThCLENBQUE7QUFFM0U7Ozs7Ozs7Ozs7O0dBV0c7QUFFSDs7R0FFRztBQUNILE1BQU0sd0JBQXlCLFNBQVEsS0FBSztJQUMxQzs7OztPQUlHO0lBQ0gsWUFBWSxPQUFPLEVBQUUsRUFBQyxJQUFJLEVBQUM7UUFDekIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQ2QsSUFBSSxDQUFDLElBQUksR0FBRywwQkFBMEIsQ0FBQTtRQUN0QyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQTtJQUN0QixDQUFDO0NBQ0Y7QUFFRDs7R0FFRztBQUNILE1BQU0scUJBQXNCLFNBQVEsS0FBSztJQUN2Qzs7OztPQUlHO0lBQ0gsWUFBWSxPQUFPLEVBQUUsRUFBQyxJQUFJLEVBQUM7UUFDekIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQ2QsSUFBSSxDQUFDLElBQUksR0FBRyx1QkFBdUIsQ0FBQTtRQUNuQyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQTtJQUN0QixDQUFDO0NBQ0Y7QUFFRDs7R0FFRztBQUNILE1BQU0sNEJB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QUFBO0FBQ3RGLE9BQU8sRUFBQyxtQ0FBbUMsRUFBRSwrQkFBK0IsRUFBQyxNQUFNLG1DQUFtQyxDQUFBO0FBQ3RILE9BQU8sRUFBQyxxQkFBcUIsRUFBRSxtQ0FBbUMsRUFBQyxNQUFNLDJCQUEyQixDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB0aW1lb3V0LCB7VGltZW91dEVycm9yfSBmcm9tIFwiYXdhaXRlcnkvYnVpbGQvdGltZW91dC5qc1wiXG5pbXBvcnQge0RFRkFVTFRfQURWSVNPUllfTE9DS19BQ1FVSVJFX1RJTUVPVVRfTVN9IGZyb20gXCIuL2Fkdmlzb3J5LWxvY2stYm91bmQuanNcIlxuaW1wb3J0IHtcbiAgQWR2aXNvcnlMb2NrQmFja2VuZFVuYXZhaWxhYmxlRXJyb3IsXG4gIHJlc29sdmVBZHZpc29yeUxvY2tCYWNrZW5kUG9saWN5LFxuICByZWZ1c2VBZHZpc29yeUxvY2tUaWVyQmVsb3dNaW5pbXVtXG59IGZyb20gXCIuL2Fkdmlzb3J5LWxvY2stYmFja2VuZC1wb2xpY3kuanNcIlxuaW1wb3J0IHtcbiAgQWR2aXNvcnlMb2NrTG9zdEVycm9yLFxuICBBZHZpc29yeUxvY2tTZXJ2aWNlVW5hdmFpbGFibGVFcnJvcixcbiAgYWR2aXNvcnlMb2NrQmFja2VuZFVuYXZhaWxhYmxlXG59IGZyb20gXCIuL2Fkdmlzb3J5LWxvY2stZXJyb3JzLmpzXCJcbmltcG9ydCB7ZW1pdEFkdmlzb3J5TG9ja0ZhbGxiYWNrUmVwb3J0fSBmcm9tIFwiLi9hZHZpc29yeS1sb2NrLXRlbGVtZXRyeS5qc1wiXG5cbi8qKlxuICogUHJvdmVuYW5jZSBvZiBvbmUgYWR2aXNvcnktbG9jayBhY3F1aXNpdGlvbiAoU1RDLTIxMCBkZXNpZ24gwqczKTogZXZlcnlcbiAqIGhlbGQgbG9jayByZXBvcnRzIHRoZSB0aWVyIHRoYXQgYWN0dWFsbHkgc2VydmVkIGl0LCBzbyBhIGZhbGxiYWNrIGlzXG4gKiB2aXNpYmxlIHRvIHRoZSBjYWxsYmFjaywgaW4gbG9ncywgYW5kIGluIGBnZXRBZHZpc29yeUxvY2tCYWNrZW5kU3RhdHVzKClgLlxuICogQHR5cGVkZWYge29iamVjdH0gQWR2aXNvcnlMb2NrQmFja2VuZFByb3ZlbmFuY2VcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9hZHZpc29yeS1sb2NrLWJhY2tlbmQtcG9saWN5LmpzXCIpLkFkdmlzb3J5TG9ja1RpZXJ9IGJhY2tlbmQgLSBUaWVyIHRoYXQgc2VydmVkIHRoZSBhY3F1aXNpdGlvbi5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbZHJpdmVyVHlwZV0gLSBEYXRhYmFzZSBkcml2ZXIgdHlwZSB3aGVuIHRoZSBkcml2ZXIgdGllciBzZXJ2ZWQgaXQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2Vwb2NoXSAtIEZlbmNpbmcgZXBvY2ggd2hlbiB0aGUgc2VydmluZyB0aWVyIGlzc3VlcyBvbmUuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGZlbmNpbmdTdXBwb3J0ZWQgLSBXaGV0aGVyIHRoaXMgdGllciBjYXJyaWVzIGZlbmNpbmcgdG9rZW5zIChkZXNpZ24gwqc4KTsgdGhlIGZpbGUgdGllciByZXBvcnRzIGZhbHNlIHJhdGhlciB0aGFuIHByZXRlbmRpbmcuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2hvbGRlcklkXSAtIEJhY2tlbmQgaG9sZGVyIGlkIGZvciB0aGUgZmlsZSB0aWVyLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtsb2NrTmFtZV0gLSBMb2NrIG5hbWUgdGhpcyBwcm92ZW5hbmNlIGJlbG9uZ3MgdG8uXG4gKi9cblxuLyoqXG4gKiBUaHJvd24gd2hlbiBhbiBhZHZpc29yeSBsb2NrIGNvdWxkIG5vdCBiZSBhY3F1aXJlZCBiZWZvcmUgYHRpbWVvdXRNc2AgZWxhcHNlZC5cbiAqL1xuY2xhc3MgQWR2aXNvcnlMb2NrVGltZW91dEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAvKipcbiAgICogUnVucyBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBFcnJvciBtZXNzYWdlLlxuICAgKiBAcGFyYW0ge3tuYW1lOiBzdHJpbmd9fSBhcmdzIC0gVGhlIGFkdmlzb3J5IGxvY2sgbmFtZSB0aGF0IHRpbWVkIG91dC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIHtuYW1lfSkge1xuICAgIHN1cGVyKG1lc3NhZ2UpXG4gICAgdGhpcy5uYW1lID0gXCJBZHZpc29yeUxvY2tUaW1lb3V0RXJyb3JcIlxuICAgIHRoaXMubG9ja05hbWUgPSBuYW1lXG4gIH1cbn1cblxuLyoqXG4gKiBUaHJvd24gd2hlbiBgd2l0aEFkdmlzb3J5TG9ja09yRmFpbGAgZmluZHMgdGhlIGxvY2sgYWxyZWFkeSBoZWxkLlxuICovXG5jbGFzcyBBZHZpc29yeUxvY2tCdXN5RXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIC8qKlxuICAgKiBSdW5zIGNvbnN0cnVjdG9yLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIEVycm9yIG1lc3NhZ2UuXG4gICAqIEBwYXJhbSB7e25hbWU6IHN0cmluZ319IGFyZ3MgLSBUaGUgYWR2aXNvcnkgbG9jayBuYW1lIHRoYXQgd2FzIGFscmVhZHkgaGVsZC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIHtuYW1lfSkge1xuICAgIHN1cGVyKG1lc3NhZ2UpXG4gICAgdGhpcy5uYW1lID0gXCJBZHZpc29yeUxvY2tCdXN5RXJyb3JcIlxuICAgIHRoaXMubG9ja05hbWUgPSBuYW1lXG4gIH1cbn1cblxuLyoqXG4gKiBUaHJvd24gd2hlbiBhIGNhbGxiYWNrIGhvbGRzIGFuIGFkdmlzb3J5IGxvY2sgbG9uZ2VyIHRoYW4gYGhvbGRUaW1lb3V0TXNgLlxuICovXG5jbGFzcyBBZHZpc29yeUxvY2tIb2xkVGltZW91dEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAvKipcbiAgICogUnVucyBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBFcnJvciBtZXNzYWdlLlxuICAgKiBAcGFyYW0ge3tuYW1lOiBzdHJpbmd9fSBhcmdzIC0gVGhlIGFkdmlzb3J5IGxvY2sgbmFtZSB3aG9zZSBob2xkIHRpbWVkIG91dC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIHtuYW1lfSkge1xuICAgIHN1cGVyKG1lc3NhZ2UpXG4gICAgdGhpcy5uYW1lID0gXCJBZHZpc29yeUxvY2tIb2xkVGltZW91dEVycm9yXCJcbiAgICB0aGlzLmxvY2tOYW1lID0gbmFtZVxuICB9XG59XG5cbi8qKlxuICogUnVucyBhZHZpc29yeSBsb2NrcyBvbiB0aGUgY2FsbGVyIGNvbm5lY3Rpb24gYnkgZGVmYXVsdCwgdXNpbmcgYSBkZWRpY2F0ZWRcbiAqIGxvY2sgY29ubmVjdGlvbiB3aGVuIGBkZWRpY2F0ZWRDb25uZWN0aW9uYCBpcyByZXF1ZXN0ZWQgb3Igd2hlbiBhIHBvc2l0aXZlXG4gKiBob2xkIHRpbWVvdXQgbmVlZHMgc2VwYXJhdGUgb3duZXJzaGlwLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBZHZpc29yeUxvY2tSdW5uZXIge1xuICAvKipcbiAgICogQ3JlYXRlcyBhbiBhZHZpc29yeS1sb2NrIHJ1bm5lciBmb3Igb25lIG1vZGVsIGRhdGFiYXNlIGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSB7e2NvbmZpZ3VyYXRpb246IGltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdCwgY29ubmVjdGlvblByb3ZpZGVyOiAoKSA9PiBpbXBvcnQoXCIuL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0LCBkYXRhYmFzZUlkZW50aWZpZXI6IHN0cmluZ319IGFyZ3MgLSBSdW5uZXIgZGVwZW5kZW5jaWVzLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe2NvbmZpZ3VyYXRpb24sIGNvbm5lY3Rpb25Qcm92aWRlciwgZGF0YWJhc2VJZGVudGlmaWVyfSkge1xuICAgIHRoaXMuY29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb25cbiAgICB0aGlzLmNvbm5lY3Rpb25Qcm92aWRlciA9IGNvbm5lY3Rpb25Qcm92aWRlclxuICAgIHRoaXMuZGF0YWJhc2VJZGVudGlmaWVyID0gZGF0YWJhc2VJZGVudGlmaWVyXG4gIH1cblxuICAvKipcbiAgICogUnVucyBhIGNhbGxiYWNrIGFmdGVyIGFjcXVpcmluZyB0aGUgYWR2aXNvcnkgbG9jaywgd2FpdGluZyB1cCB0byBgdGltZW91dE1zYC5cbiAgICogV2hlbiBgZGVkaWNhdGVkQ29ubmVjdGlvbmAgaXMgdHJ1ZSB0aGUgbG9jayBpcyBhY3F1aXJlZCBvbiBhIHNwYXduZWRcbiAgICogY29ubmVjdGlvbiB0aGF0IGlzIHJlbGVhc2VkIGFmdGVyIHRoZSBjYWxsYmFjayBmaW5pc2hlcywgd2hpbGUgdGhlIGNhbGxiYWNrXG4gICAqIGl0c2VsZiBzdGlsbCBydW5zIGFnYWluc3QgdGhlIGNhbGxlci9tb2RlbCBjb25uZWN0aW9uLiBXaGVuIGEgYGhvbGRUaW1lb3V0TXNgXG4gICAqIGlzIHNldCB0aGUgY2FsbGJhY2sgcmVjZWl2ZXMgYSBgVGltZW91dENvbnRyb2xgIGZyb20gYXdhaXRlcnkgZm9yIGNvb3BlcmF0aXZlXG4gICAqIGNhbmNlbGxhdGlvbiAoYGNvbnRyb2wuY2hlY2soKWAsIGBjb250cm9sLnNpZ25hbGAsIGBjb250cm9sLnRpbWVkT3V0YCxcbiAgICogYGNvbnRyb2wucmVtYWluaW5nKClgKTsgYSBkZWRpY2F0ZWQgY29ubmVjdGlvbiBpcyBhbHNvIHVzZWQgc28gdGltZW91dFxuICAgKiBjbGVhbnVwIGNhbiByZWxlYXNlIHRoZSBsb2NrIGV2ZW4gaWYgY2FsbGJhY2sgZGF0YWJhc2Ugd29yayBpcyBzdHVjay5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBMb2NrIG5hbWUuXG4gICAqIEBwYXJhbSB7KGFyZ3M/OiB7Y29udHJvbD86IGltcG9ydChcImF3YWl0ZXJ5L2J1aWxkL3RpbWVvdXQuanNcIikuVGltZW91dENvbnRyb2wsIGxvY2tCYWNrZW5kOiBBZHZpc29yeUxvY2tCYWNrZW5kUHJvdmVuYW5jZX0pID0+IFByb21pc2U8VD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgdG8gaW52b2tlIHdoaWxlIHRoZSBsb2NrIGlzIGhlbGQuXG4gICAqIEBwYXJhbSB7e3RpbWVvdXRNcz86IG51bWJlciB8IG51bGwsIGhvbGRUaW1lb3V0TXM/OiBudW1iZXIgfCBudWxsLCBkZWRpY2F0ZWRDb25uZWN0aW9uPzogYm9vbGVhbn19IFthcmdzXSAtIExvY2sgYW5kIGhvbGQgdGltZW91dCBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBhc3luYyB3aXRoQWR2aXNvcnlMb2NrKG5hbWUsIGNhbGxiYWNrLCBhcmdzID0ge30pIHtcbiAgICBjb25zdCBsb2NrU2VydmVyUmVzdWx0ID0gYXdhaXQgdGhpcy5hdHRlbXB0TG9ja1NlcnZlcih7YXJncywgY2FsbGJhY2ssIG1vZGU6IFwid2FpdFwiLCBuYW1lfSlcblxuICAgIC8vIFRoZSB3YWl0IG1vZGUgbmV2ZXIgcmV0dXJucyBhIGRlZmVycmVkIG91dGNvbWUsIHNvIHRoZSB2YWx1ZSBtZW1iZXIgaXMgcHJlc2VudC5cbiAgICBpZiAobG9ja1NlcnZlclJlc3VsdCkgcmV0dXJuIC8qKiBAdHlwZSB7e3ZhbHVlOiBUfX0gKi8gKGxvY2tTZXJ2ZXJSZXN1bHQpLnZhbHVlXG5cbiAgICBjb25zdCBmaWxlQmFja2VuZCA9IGF3YWl0IHRoaXMuZmlsZUJhY2tlbmRGb3JOYW1lKG5hbWUpXG5cbiAgICBpZiAoZmlsZUJhY2tlbmQpIHtcbiAgICAgIGNvbnN0IGFjcXVpcmVkID0gYXdhaXQgZmlsZUJhY2tlbmQuYWNxdWlyZShuYW1lLCB7dGltZW91dE1zOiB0aGlzLmFjcXVpcmVUaW1lb3V0TXMoYXJncyl9KVxuXG4gICAgICBpZiAoIWFjcXVpcmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBBZHZpc29yeUxvY2tUaW1lb3V0RXJyb3IoYFRpbWVkIG91dCB3YWl0aW5nIGZvciBhZHZpc29yeSBsb2NrICR7SlNPTi5zdHJpbmdpZnkobmFtZSl9IG9uIHRoZSBmaWxlIHRpZXJgLCB7bmFtZX0pXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGxvY2tCYWNrZW5kID0gdGhpcy5maWxlUHJvdmVuYW5jZShmaWxlQmFja2VuZCwgbmFtZSlcblxuICAgICAgdGhpcy5jb25maWd1cmF0aW9uLnJlY29yZEFkdmlzb3J5TG9ja0FjcXVpc2l0aW9uKHtiYWNrZW5kOiBsb2NrQmFja2VuZC5iYWNrZW5kLCBmZW5jaW5nU3VwcG9ydGVkOiBsb2NrQmFja2VuZC5mZW5jaW5nU3VwcG9ydGVkLCBsb2NrTmFtZTogbmFtZX0pXG5cbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJ1bkxvY2tlZENhbGxiYWNrKHtjYWxsYmFjaywgaG9sZFRpbWVvdXRNczogYXJncy5ob2xkVGltZW91dE1zLCBsb2NrQmFja2VuZCwgbmFtZSwgcmVsZWFzZTogYXN5bmMgKCkgPT4gYXdhaXQgZmlsZUJhY2tlbmQucmVsZWFzZShuYW1lKX0pXG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMud2l0aExvY2tDb25uZWN0aW9uKGFyZ3MsIGFzeW5jIChjb25uZWN0aW9uKSA9PiB7XG4gICAgICBjb25zdCBsb2NrQmFja2VuZCA9IHRoaXMuZHJpdmVyUHJvdmVuYW5jZShjb25uZWN0aW9uKVxuXG4gICAgICB0aGlzLmFzc2VydERyaXZlclRpZXJFbGlnaWJsZShuYW1lLCBsb2NrQmFja2VuZClcblxuICAgICAgY29uc3QgYWNxdWlyZWQgPSBhd2FpdCBjb25uZWN0aW9uLmFjcXVpcmVBZHZpc29yeUxvY2sobmFtZSwgYXJncylcblxuICAgICAgaWYgKCFhY3F1aXJlZCkge1xuICAgICAgICB0aHJvdyBuZXcgQWR2aXNvcnlMb2NrVGltZW91dEVycm9yKGBUaW1lZCBvdXQgd2FpdGluZyBmb3IgYWR2aXNvcnkgbG9jayAke0pTT04uc3RyaW5naWZ5KG5hbWUpfWAsIHtuYW1lfSlcbiAgICAgIH1cblxuICAgICAgdGhpcy5jb25maWd1cmF0aW9uLnJlY29yZEFkdmlzb3J5TG9ja0FjcXVpc2l0aW9uKHtiYWNrZW5kOiBsb2NrQmFja2VuZC5iYWNrZW5kLCBmZW5jaW5nU3VwcG9ydGVkOiBsb2NrQmFja2VuZC5mZW5jaW5nU3VwcG9ydGVkLCBsb2NrTmFtZTogbmFtZX0pXG5cbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJ1bkxvY2tlZENhbGxiYWNrKHtjYWxsYmFjaywgaG9sZFRpbWVvdXRNczogYXJncy5ob2xkVGltZW91dE1zLCBsb2NrQmFja2VuZCwgbmFtZSwgcmVsZWFzZTogYXN5bmMgKCkgPT4gYXdhaXQgY29ubmVjdGlvbi5yZWxlYXNlQWR2aXNvcnlMb2NrKG5hbWUpfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYSBjYWxsYmFjayBvbmx5IGlmIHRoZSBhZHZpc29yeSBsb2NrIGNhbiBiZSBhY3F1aXJlZCBpbW1lZGlhdGVseS5cbiAgICogV2hlbiBgZGVkaWNhdGVkQ29ubmVjdGlvbmAgaXMgdHJ1ZSB0aGUgbG9jayBpcyBhY3F1aXJlZCBvbiBhIHNwYXduZWRcbiAgICogY29ubmVjdGlvbiB0aGF0IGlzIHJlbGVhc2VkIGFmdGVyIHRoZSBjYWxsYmFjayBmaW5pc2hlcywgd2hpbGUgdGhlIGNhbGxiYWNrXG4gICAqIGl0c2VsZiBzdGlsbCBydW5zIGFnYWluc3QgdGhlIGNhbGxlci9tb2RlbCBjb25uZWN0aW9uLiBXaGVuIGEgYGhvbGRUaW1lb3V0TXNgXG4gICAqIGlzIHNldCB0aGUgY2FsbGJhY2sgcmVjZWl2ZXMgYSBgVGltZW91dENvbnRyb2xgIGZyb20gYXdhaXRlcnkgZm9yIGNvb3BlcmF0aXZlXG4gICAqIGNhbmNlbGxhdGlvbi5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBMb2NrIG5hbWUuXG4gICAqIEBwYXJhbSB7KGFyZ3M/OiB7Y29udHJvbD86IGltcG9ydChcImF3YWl0ZXJ5L2J1aWxkL3RpbWVvdXQuanNcIikuVGltZW91dENvbnRyb2wsIGxvY2tCYWNrZW5kOiBBZHZpc29yeUxvY2tCYWNrZW5kUHJvdmVuYW5jZX0pID0+IFByb21pc2U8VD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgdG8gaW52b2tlIHdoaWxlIHRoZSBsb2NrIGlzIGhlbGQuXG4gICAqIEBwYXJhbSB7e2hvbGRUaW1lb3V0TXM/OiBudW1iZXIgfCBudWxsLCBkZWRpY2F0ZWRDb25uZWN0aW9uPzogYm9vbGVhbn19IFthcmdzXSAtIEhvbGQgdGltZW91dCBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBhc3luYyB3aXRoQWR2aXNvcnlMb2NrT3JGYWlsKG5hbWUsIGNhbGxiYWNrLCBhcmdzID0ge30pIHtcbiAgICBjb25zdCBsb2NrU2VydmVyUmVzdWx0ID0gYXdhaXQgdGhpcy5hdHRlbXB0TG9ja1NlcnZlcih7YXJncywgY2FsbGJhY2ssIG1vZGU6IFwib3ItZmFpbFwiLCBuYW1lfSlcblxuICAgIC8vIFRoZSBvci1mYWlsIG1vZGUgdGhyb3dzIG9uIGNvbnRlbnRpb24sIHNvIHRoZSB2YWx1ZSBtZW1iZXIgaXMgcHJlc2VudC5cbiAgICBpZiAobG9ja1NlcnZlclJlc3VsdCkgcmV0dXJuIC8qKiBAdHlwZSB7e3ZhbHVlOiBUfX0gKi8gKGxvY2tTZXJ2ZXJSZXN1bHQpLnZhbHVlXG5cbiAgICBjb25zdCBmaWxlQmFja2VuZCA9IGF3YWl0IHRoaXMuZmlsZUJhY2tlbmRGb3JOYW1lKG5hbWUpXG5cbiAgICBpZiAoZmlsZUJhY2tlbmQpIHtcbiAgICAgIGNvbnN0IGFjcXVpcmVkID0gYXdhaXQgZmlsZUJhY2tlbmQudHJ5QWNxdWlyZShuYW1lKVxuXG4gICAgICBpZiAoIWFjcXVpcmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBBZHZpc29yeUxvY2tCdXN5RXJyb3IoYEFkdmlzb3J5IGxvY2sgJHtKU09OLnN0cmluZ2lmeShuYW1lKX0gaXMgYWxyZWFkeSBoZWxkIG9uIHRoZSBmaWxlIHRpZXJgLCB7bmFtZX0pXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGxvY2tCYWNrZW5kID0gdGhpcy5maWxlUHJvdmVuYW5jZShmaWxlQmFja2VuZCwgbmFtZSlcblxuICAgICAgdGhpcy5jb25maWd1cmF0aW9uLnJlY29yZEFkdmlzb3J5TG9ja0FjcXVpc2l0aW9uKHtiYWNrZW5kOiBsb2NrQmFja2VuZC5iYWNrZW5kLCBmZW5jaW5nU3VwcG9ydGVkOiBsb2NrQmFja2VuZC5mZW5jaW5nU3VwcG9ydGVkLCBsb2NrTmFtZTogbmFtZX0pXG5cbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJ1bkxvY2tlZENhbGxiYWNrKHtjYWxsYmFjaywgaG9sZFRpbWVvdXRNczogYXJncy5ob2xkVGltZW91dE1zLCBsb2NrQmFja2VuZCwgbmFtZSwgcmVsZWFzZTogYXN5bmMgKCkgPT4gYXdhaXQgZmlsZUJhY2tlbmQucmVsZWFzZShuYW1lKX0pXG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMud2l0aExvY2tDb25uZWN0aW9uKGFyZ3MsIGFzeW5jIChjb25uZWN0aW9uKSA9PiB7XG4gICAgICBjb25zdCBsb2NrQmFja2VuZCA9IHRoaXMuZHJpdmVyUHJvdmVuYW5jZShjb25uZWN0aW9uKVxuXG4gICAgICB0aGlzLmFzc2VydERyaXZlclRpZXJFbGlnaWJsZShuYW1lLCBsb2NrQmFja2VuZClcblxuICAgICAgY29uc3QgYWNxdWlyZWQgPSBhd2FpdCBjb25uZWN0aW9uLnRyeUFjcXVpcmVBZHZpc29yeUxvY2sobmFtZSlcblxuICAgICAgaWYgKCFhY3F1aXJlZCkge1xuICAgICAgICB0aHJvdyBuZXcgQWR2aXNvcnlMb2NrQnVzeUVycm9yKGBBZHZpc29yeSBsb2NrICR7SlNPTi5zdHJpbmdpZnkobmFtZSl9IGlzIGFscmVhZHkgaGVsZGAsIHtuYW1lfSlcbiAgICAgIH1cblxuICAgICAgdGhpcy5jb25maWd1cmF0aW9uLnJlY29yZEFkdmlzb3J5TG9ja0FjcXVpc2l0aW9uKHtiYWNrZW5kOiBsb2NrQmFja2VuZC5iYWNrZW5kLCBmZW5jaW5nU3VwcG9ydGVkOiBsb2NrQmFja2VuZC5mZW5jaW5nU3VwcG9ydGVkLCBsb2NrTmFtZTogbmFtZX0pXG5cbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJ1bkxvY2tlZENhbGxiYWNrKHtjYWxsYmFjaywgaG9sZFRpbWVvdXRNczogYXJncy5ob2xkVGltZW91dE1zLCBsb2NrQmFja2VuZCwgbmFtZSwgcmVsZWFzZTogYXN5bmMgKCkgPT4gYXdhaXQgY29ubmVjdGlvbi5yZWxlYXNlQWR2aXNvcnlMb2NrKG5hbWUpfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gIC8qKlxuICAgKiBSdW5zIGEgY2FsbGJhY2sgaWYgdGhlIGFkdmlzb3J5IGxvY2sgY2FuIGJlIGFjcXVpcmVkIHdpdGhvdXQgd2FpdGluZztcbiAgICogb3RoZXJ3aXNlIHJldHVybnMgYSBge2FjcXVpcmVkOiBmYWxzZX1gIGRlZmVyIHJlc3VsdCBpbnN0ZWFkIG9mIHRocm93aW5nLlxuICAgKlxuICAgKiBUaGlzIGlzIHRoZSBub24tdGhyb3dpbmcgY291bnRlcnBhcnQgb2YgYHdpdGhBZHZpc29yeUxvY2tPckZhaWxgIGZvciBob3RcbiAgICogcGF0aHM6IFwiaG9sZGVyIGJ1c3ksIGRlZmVyIG1lXCIgaXMgYSBmaXJzdC1jbGFzcyBvdXRjb21lLCBzbyBhIGNvbnRlbmRlZFxuICAgKiBsb2NrIHByb2R1Y2VzIHplcm8gZXhjZXB0aW9uIHRyYWZmaWMgYW5kIOKAlCBiZWNhdXNlIHRoZSBwcm9iZSBpcyBhIHNpbmdsZVxuICAgKiBpbW1lZGlhdGUgdHJ5LWFjcXVpcmUg4oCUIHplcm8gcGlubmVkIGNvbm5lY3Rpb25zLiBDYWxsZXJzIHJlc2NoZWR1bGUgdmlhXG4gICAqIHRoZWlyIG93biBldmVudC1kcml2ZW4gcmV0cnkgbWFjaGluZXJ5LiBUaGUgcmVzdWx0IGZvcm0gaXMgaWRlbnRpY2FsXG4gICAqIGFjcm9zcyB0aWVyczogdGhlIGRyaXZlcidzIGB0cnlBY3F1aXJlQWR2aXNvcnlMb2NrYCBtYXBzIHBlci10aWVyIChNeVNRTFxuICAgKiBgR0VUX0xPQ0sobmFtZSwgMClgLCBQb3N0Z3JlU1FMIGBwZ190cnlfYWR2aXNvcnlfbG9ja2AsIFNRTCBTZXJ2ZXJcbiAgICogYHNwX2dldGFwcGxvY2sgQExvY2tUaW1lb3V0ID0gMGAsIFNRTGl0ZSBwcm9jZXNzLWxvY2FsIHF1ZXVlLCBTUUxpdGUgTm9kZVxuICAgKiBmaWxlIGxvY2spLCBzbyBhIGNhbGxlciBuZXZlciBicmFuY2hlcyBvbiB0aGUgYmFja2VuZC5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBMb2NrIG5hbWUuXG4gICAqIEBwYXJhbSB7KGFyZ3M/OiB7Y29udHJvbD86IGltcG9ydChcImF3YWl0ZXJ5L2J1aWxkL3RpbWVvdXQuanNcIikuVGltZW91dENvbnRyb2wsIGxvY2tCYWNrZW5kOiBBZHZpc29yeUxvY2tCYWNrZW5kUHJvdmVuYW5jZX0pID0+IFByb21pc2U8VD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgdG8gaW52b2tlIHdoaWxlIHRoZSBsb2NrIGlzIGhlbGQuXG4gICAqIEBwYXJhbSB7e2hvbGRUaW1lb3V0TXM/OiBudW1iZXIgfCBudWxsLCBkZWRpY2F0ZWRDb25uZWN0aW9uPzogYm9vbGVhbn19IFthcmdzXSAtIEhvbGQgdGltZW91dCBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7YWNxdWlyZWQ6IHRydWUsIHJlc3VsdDogVH0gfCB7YWNxdWlyZWQ6IGZhbHNlLCByZWFzb246IFwiY29udGVuZGVkXCIsIGxvY2tOYW1lOiBzdHJpbmd9Pn0gLSBFaXRoZXIgdGhlIGhlbGQtY2FsbGJhY2sgcmVzdWx0IG9yIHRoZSBkZWZlciBvdXRjb21lLlxuICAgKi9cbiAgYXN5bmMgd2l0aEFkdmlzb3J5TG9ja09yRGVmZXIobmFtZSwgY2FsbGJhY2ssIGFyZ3MgPSB7fSkge1xuICAgIGNvbnN0IGxvY2tTZXJ2ZXJSZXN1bHQgPSBhd2FpdCB0aGlzLmF0dGVtcHRMb2NrU2VydmVyKHthcmdzLCBjYWxsYmFjaywgbW9kZTogXCJkZWZlclwiLCBuYW1lfSlcblxuICAgIGlmIChsb2NrU2VydmVyUmVzdWx0KSB7XG4gICAgICBpZiAoXCJkZWZlcnJlZFwiIGluIGxvY2tTZXJ2ZXJSZXN1bHQpIHJldHVybiBsb2NrU2VydmVyUmVzdWx0LmRlZmVycmVkXG5cbiAgICAgIHJldHVybiB7YWNxdWlyZWQ6IHRydWUsIHJlc3VsdDogLyoqIEB0eXBlIHt7dmFsdWU6IFR9fSAqLyAobG9ja1NlcnZlclJlc3VsdCkudmFsdWV9XG4gICAgfVxuXG4gICAgY29uc3QgZmlsZUJhY2tlbmQgPSBhd2FpdCB0aGlzLmZpbGVCYWNrZW5kRm9yTmFtZShuYW1lKVxuXG4gICAgaWYgKGZpbGVCYWNrZW5kKSB7XG4gICAgICBjb25zdCBhY3F1aXJlZCA9IGF3YWl0IGZpbGVCYWNrZW5kLmFjcXVpcmUobmFtZSwge3RpbWVvdXRNczogMH0pXG5cbiAgICAgIGlmICghYWNxdWlyZWQpIHJldHVybiB7YWNxdWlyZWQ6IGZhbHNlLCByZWFzb246IFwiY29udGVuZGVkXCIsIGxvY2tOYW1lOiBuYW1lfVxuXG4gICAgICBjb25zdCBsb2NrQmFja2VuZCA9IHRoaXMuZmlsZVByb3ZlbmFuY2UoZmlsZUJhY2tlbmQsIG5hbWUpXG5cbiAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5yZWNvcmRBZHZpc29yeUxvY2tBY3F1aXNpdGlvbih7YmFja2VuZDogbG9ja0JhY2tlbmQuYmFja2VuZCwgZmVuY2luZ1N1cHBvcnRlZDogbG9ja0JhY2tlbmQuZmVuY2luZ1N1cHBvcnRlZCwgbG9ja05hbWU6IG5hbWV9KVxuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnJ1bkxvY2tlZENhbGxiYWNrKHtjYWxsYmFjaywgaG9sZFRpbWVvdXRNczogYXJncy5ob2xkVGltZW91dE1zLCBsb2NrQmFja2VuZCwgbmFtZSwgcmVsZWFzZTogYXN5bmMgKCkgPT4gYXdhaXQgZmlsZUJhY2tlbmQucmVsZWFzZShuYW1lKX0pXG5cbiAgICAgIHJldHVybiB7YWNxdWlyZWQ6IHRydWUsIHJlc3VsdH1cbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy53aXRoTG9ja0Nvbm5lY3Rpb24oYXJncywgYXN5bmMgKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgIGNvbnN0IGFjcXVpcmVkID0gYXdhaXQgY29ubmVjdGlvbi50cnlBY3F1aXJlQWR2aXNvcnlMb2NrKG5hbWUpXG5cbiAgICAgIGlmICghYWNxdWlyZWQpIHJldHVybiB7YWNxdWlyZWQ6IGZhbHNlLCByZWFzb246IFwiY29udGVuZGVkXCIsIGxvY2tOYW1lOiBuYW1lfVxuXG4gICAgICBjb25zdCBsb2NrQmFja2VuZCA9IHRoaXMuZHJpdmVyUHJvdmVuYW5jZShjb25uZWN0aW9uKVxuXG4gICAgICB0aGlzLmFzc2VydERyaXZlclRpZXJFbGlnaWJsZShuYW1lLCBsb2NrQmFja2VuZClcblxuICAgICAgdGhpcy5jb25maWd1cmF0aW9uLnJlY29yZEFkdmlzb3J5TG9ja0FjcXVpc2l0aW9uKHtiYWNrZW5kOiBsb2NrQmFja2VuZC5iYWNrZW5kLCBmZW5jaW5nU3VwcG9ydGVkOiBsb2NrQmFja2VuZC5mZW5jaW5nU3VwcG9ydGVkLCBsb2NrTmFtZTogbmFtZX0pXG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMucnVuTG9ja2VkQ2FsbGJhY2soe2NhbGxiYWNrLCBob2xkVGltZW91dE1zOiBhcmdzLmhvbGRUaW1lb3V0TXMsIGxvY2tCYWNrZW5kLCBuYW1lLCByZWxlYXNlOiBhc3luYyAoKSA9PiBhd2FpdCBjb25uZWN0aW9uLnJlbGVhc2VBZHZpc29yeUxvY2sobmFtZSl9KVxuXG4gICAgICByZXR1cm4ge2FjcXVpcmVkOiB0cnVlLCByZXN1bHR9XG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHRoZSBsb2NrIGhvbGRlciBjYWxsYmFjayBhbmQgcmVsZWFzZXMgdGhlIGxvY2sgZnJvbSBpdHMgb3duaW5nIGJhY2tlbmQuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7e2NhbGxiYWNrOiAoYXJncz86IHtjb250cm9sPzogaW1wb3J0KFwiYXdhaXRlcnkvYnVpbGQvdGltZW91dC5qc1wiKS5UaW1lb3V0Q29udHJvbCwgbG9ja0JhY2tlbmQ6IEFkdmlzb3J5TG9ja0JhY2tlbmRQcm92ZW5hbmNlfSkgPT4gUHJvbWlzZTxUPiwgaG9sZFRpbWVvdXRNcz86IG51bWJlciB8IG51bGwsIGxvY2tCYWNrZW5kOiBBZHZpc29yeUxvY2tCYWNrZW5kUHJvdmVuYW5jZSwgbmFtZTogc3RyaW5nLCByZWxlYXNlOiAoKSA9PiBQcm9taXNlPHVua25vd24+fX0gYXJncyAtIExvY2tlZCBjYWxsYmFjayBhcmdzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBhc3luYyBydW5Mb2NrZWRDYWxsYmFjayh7Y2FsbGJhY2ssIGhvbGRUaW1lb3V0TXMsIGxvY2tCYWNrZW5kLCBuYW1lLCByZWxlYXNlfSkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgQWR2aXNvcnlMb2NrUnVubmVyLnJ1bldpdGhBZHZpc29yeUxvY2tIb2xkVGltZW91dChuYW1lLCBjYWxsYmFjaywgaG9sZFRpbWVvdXRNcywgbG9ja0JhY2tlbmQpXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHJlbGVhc2UoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXJ2ZXMgb25lIGFjcXVpc2l0aW9uIG9uIHRoZSBsb2NrLXNlcnZlciB0aWVyIHdoZW4gdGhlIGxvY2sgbmFtZSBwcmVmZXJzXG4gICAqIGl0IChkZXNpZ24gwqcxL8KnOSksIGZhbGxpbmcgKnVwd2FyZCogdG8gdGhlIGRyaXZlciBwYXRoIHdoZW4gdGhlIHNlcnZlciBpc1xuICAgKiB1bnJlYWNoYWJsZSBhbmQgdGhlIG5hbWUncyBtaW5pbXVtIHRpZXIgcGVybWl0cyBhIERCLW5hdGl2ZSBob2xkLlxuICAgKlxuICAgKiBgbnVsbGAgbWVhbnMgXCJ0aGlzIHRpZXIgZGlkIG5vdCBzZXJ2ZSB0aGUgYWNxdWlzaXRpb24g4oCUIGNvbnRpbnVlIHdpdGggdGhlXG4gICAqIG5leHQgZWxpZ2libGUgdGllclwiLiBBIHJldHVybmVkIHZhbHVlIG1lYW5zIHRoZSBsb2NrLXNlcnZlciB0aWVyIGFuc3dlcmVkLFxuICAgKiBpbmNsdWRpbmcgYSBkZWZpbml0aXZlIGJ1c3kvdGltZW91dCBvdXRjb21lLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0ge3thcmdzOiB7aG9sZFRpbWVvdXRNcz86IG51bWJlciB8IG51bGwsIHRpbWVvdXRNcz86IG51bWJlciB8IG51bGx9LCBjYWxsYmFjazogKGFyZ3M/OiB7Y29udHJvbD86IGltcG9ydChcImF3YWl0ZXJ5L2J1aWxkL3RpbWVvdXQuanNcIikuVGltZW91dENvbnRyb2wsIGxvY2tCYWNrZW5kOiBBZHZpc29yeUxvY2tCYWNrZW5kUHJvdmVuYW5jZX0pID0+IFByb21pc2U8VD4sIG1vZGU6IFwid2FpdFwiIHwgXCJvci1mYWlsXCIgfCBcImRlZmVyXCIsIG5hbWU6IHN0cmluZ319IHJlcXVlc3QgLSBBY3F1aXNpdGlvbiByZXF1ZXN0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7ZGVmZXJyZWQ6IHthY3F1aXJlZDogZmFsc2UsIHJlYXNvbjogXCJjb250ZW5kZWRcIiwgbG9ja05hbWU6IHN0cmluZ319IHwge3ZhbHVlOiBUfSB8IG51bGw+fSAtIFJlc3VsdCB3aGVuIHRoaXMgdGllciBzZXJ2ZWQgaXQsIG90aGVyd2lzZSBudWxsLlxuICAgKi9cbiAgYXN5bmMgYXR0ZW1wdExvY2tTZXJ2ZXIoe2FyZ3MsIGNhbGxiYWNrLCBtb2RlLCBuYW1lfSkge1xuICAgIGNvbnN0IHBvbGljeSA9IHJlc29sdmVBZHZpc29yeUxvY2tCYWNrZW5kUG9saWN5KG5hbWUsIHRoaXMuY29uZmlndXJhdGlvbi5nZXRBZHZpc29yeUxvY2tQb2xpY3koKSlcblxuICAgIGlmIChwb2xpY3kucHJlZmVycmVkVGllciAhPT0gXCJsb2NrLXNlcnZlclwiKSByZXR1cm4gbnVsbFxuICAgIGlmICghcG9saWN5LmFsbG93ZWRUaWVycy5pbmNsdWRlcyhcImxvY2stc2VydmVyXCIpKSByZXR1cm4gbnVsbFxuXG4gICAgY29uc3QgYmFja2VuZCA9IGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5nZXRBZHZpc29yeUxvY2tMb2NrU2VydmVyQmFja2VuZCgpXG5cbiAgICBpZiAoIWJhY2tlbmQpIHtcbiAgICAgIHRoaXMucmVwb3J0QWR2aXNvcnlMb2NrRmFsbGJhY2soe3JlYXNvbjogXCJsb2NrLXNlcnZlciB0aWVyIGlzIG5vdCBlbmFibGVkIGluIGNvbmZpZ3VyYXRpb25cIiwgc2VydmVkQnk6IFwiZHJpdmVyLW5hdGl2ZVwiLCBsb2NrTmFtZTogbmFtZX0pXG5cbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgLyoqIEB0eXBlIHtib29sZWFufSAqL1xuICAgIGxldCBhY3F1aXJlZFxuXG4gICAgdHJ5IHtcbiAgICAgIGlmIChtb2RlID09PSBcIndhaXRcIikge1xuICAgICAgICBhY3F1aXJlZCA9IGF3YWl0IGJhY2tlbmQuYWNxdWlyZShuYW1lLCB7dGltZW91dE1zOiB0aGlzLmFjcXVpcmVUaW1lb3V0TXMoYXJncyl9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWNxdWlyZWQgPSBhd2FpdCBiYWNrZW5kLnRyeUFjcXVpcmUobmFtZSlcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKCEoZXJyb3IgaW5zdGFuY2VvZiBBZHZpc29yeUxvY2tTZXJ2aWNlVW5hdmFpbGFibGVFcnJvcikpIHRocm93IGVycm9yXG5cbiAgICAgIGlmIChwb2xpY3kubWluVGllciA9PT0gXCJsb2NrLXNlcnZlclwiKSB7XG4gICAgICAgIHRocm93IGFkdmlzb3J5TG9ja0JhY2tlbmRVbmF2YWlsYWJsZSh7XG4gICAgICAgICAgbG9ja05hbWU6IG5hbWUsXG4gICAgICAgICAgbWluVGllcjogcG9saWN5Lm1pblRpZXIsXG4gICAgICAgICAgcmVhc29uczogW2Bsb2NrLXNlcnZlciB1bmF2YWlsYWJsZTogJHtlcnJvci5tZXNzYWdlfWBdXG4gICAgICAgIH0pXG4gICAgICB9XG5cbiAgICAgIHRoaXMucmVwb3J0QWR2aXNvcnlMb2NrRmFsbGJhY2soe3JlYXNvbjogZXJyb3IubWVzc2FnZSwgc2VydmVkQnk6IFwiZHJpdmVyLW5hdGl2ZVwiLCBsb2NrTmFtZTogbmFtZX0pXG5cbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgaWYgKCFhY3F1aXJlZCkge1xuICAgICAgaWYgKG1vZGUgPT09IFwiZGVmZXJcIikgcmV0dXJuIHtkZWZlcnJlZDoge2FjcXVpcmVkOiBmYWxzZSwgcmVhc29uOiBcImNvbnRlbmRlZFwiLCBsb2NrTmFtZTogbmFtZX19XG4gICAgICBpZiAobW9kZSA9PT0gXCJvci1mYWlsXCIpIHRocm93IG5ldyBBZHZpc29yeUxvY2tCdXN5RXJyb3IoYEFkdmlzb3J5IGxvY2sgJHtKU09OLnN0cmluZ2lmeShuYW1lKX0gaXMgYWxyZWFkeSBoZWxkYCwge25hbWV9KVxuXG4gICAgICB0aHJvdyBuZXcgQWR2aXNvcnlMb2NrVGltZW91dEVycm9yKGBUaW1lZCBvdXQgd2FpdGluZyBmb3IgYWR2aXNvcnkgbG9jayAke0pTT04uc3RyaW5naWZ5KG5hbWUpfWAsIHtuYW1lfSlcbiAgICB9XG5cbiAgICBjb25zdCBlcG9jaCA9IGJhY2tlbmQuZ2V0SG9sZEVwb2NoKG5hbWUpXG4gICAgY29uc3QgbG9ja0JhY2tlbmQgPSAvKiogQHR5cGUge0Fkdmlzb3J5TG9ja0JhY2tlbmRQcm92ZW5hbmNlfSAqLyAoe1xuICAgICAgYmFja2VuZDogXCJsb2NrLXNlcnZlclwiLFxuICAgICAgZXBvY2g6IGVwb2NoID8/IHVuZGVmaW5lZCxcbiAgICAgIGZlbmNpbmdTdXBwb3J0ZWQ6IHRydWUsXG4gICAgICBsb2NrTmFtZTogbmFtZVxuICAgIH0pXG5cbiAgICB0aGlzLmNvbmZpZ3VyYXRpb24ucmVjb3JkQWR2aXNvcnlMb2NrQWNxdWlzaXRpb24oe2JhY2tlbmQ6IFwibG9jay1zZXJ2ZXJcIiwgZmVuY2luZ1N1cHBvcnRlZDogdHJ1ZSwgbG9ja05hbWU6IG5hbWV9KVxuXG4gICAgICAgIGNvbnN0IHZhbHVlID0gYXdhaXQgdGhpcy5ydW5Mb2NrU2VydmVySG9sZCh7XG4gICAgICBiYWNrZW5kLFxuICAgICAgY2FsbGJhY2ssXG4gICAgICBob2xkVGltZW91dE1zOiBhcmdzLmhvbGRUaW1lb3V0TXMsXG4gICAgICBsb2NrQmFja2VuZCxcbiAgICAgIG5hbWVcbiAgICB9KVxuXG4gICAgcmV0dXJuIHt2YWx1ZX1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHRoZSBjcml0aWNhbCBzZWN0aW9uIHVuZGVyIGEgbG9jay1zZXJ2ZXIgbGVhc2UgYW5kIHN1cmZhY2VzIGEgZmVuY2VkXG4gICAqIGxlYXNlIGFzIGBBZHZpc29yeUxvY2tMb3N0RXJyb3JgIChkZXNpZ24gwqc4KTogdGhlIHNlY3Rpb24gbWF5IGhhdmVcbiAgICogb3ZlcmxhcHBlZCBhbm90aGVyIGhvbGRlciwgc28gaXRzIG91dGNvbWUgbXVzdCBub3QgYmUgdHJ1c3RlZCBhcyBleGNsdXNpdmUuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7e2JhY2tlbmQ6IGltcG9ydChcIi4vYWR2aXNvcnktbG9jay1sb2NrLXNlcnZlci1iYWNrZW5kLmpzXCIpLmRlZmF1bHQsIGNhbGxiYWNrOiAoYXJncz86IHtjb250cm9sPzogaW1wb3J0KFwiYXdhaXRlcnkvYnVpbGQvdGltZW91dC5qc1wiKS5UaW1lb3V0Q29udHJvbCwgbG9ja0JhY2tlbmQ6IEFkdmlzb3J5TG9ja0JhY2tlbmRQcm92ZW5hbmNlfSkgPT4gUHJvbWlzZTxUPiwgaG9sZFRpbWVvdXRNcz86IG51bWJlciB8IG51bGwsIGxvY2tCYWNrZW5kOiBBZHZpc29yeUxvY2tCYWNrZW5kUHJvdmVuYW5jZSwgbmFtZTogc3RyaW5nfX0gYXJncyAtIEhvbGQgcmVxdWVzdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gQ2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgcnVuTG9ja1NlcnZlckhvbGQoe2JhY2tlbmQsIGNhbGxiYWNrLCBob2xkVGltZW91dE1zLCBsb2NrQmFja2VuZCwgbmFtZX0pIHtcbiAgICAvKiogQHR5cGUge1QgfCB1bmRlZmluZWR9ICovXG4gICAgbGV0IHZhbHVlXG4gICAgLyoqIEB0eXBlIHt1bmtub3dufSAqL1xuICAgIGxldCBjYWxsYmFja0Vycm9yXG4gICAgbGV0IGZhaWxlZCA9IGZhbHNlXG5cbiAgICB0cnkge1xuICAgICAgdmFsdWUgPSBhd2FpdCB0aGlzLnJ1bkxvY2tlZENhbGxiYWNrKHtcbiAgICAgICAgY2FsbGJhY2ssXG4gICAgICAgIGhvbGRUaW1lb3V0TXMsXG4gICAgICAgIGxvY2tCYWNrZW5kLFxuICAgICAgICBuYW1lLFxuICAgICAgICByZWxlYXNlOiBhc3luYyAoKSA9PiBhd2FpdCBiYWNrZW5kLnJlbGVhc2UobmFtZSlcbiAgICAgIH0pXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGZhaWxlZCA9IHRydWVcbiAgICAgIGNhbGxiYWNrRXJyb3IgPSBlcnJvclxuICAgIH1cblxuICAgIGNvbnN0IGxvc3MgPSBiYWNrZW5kLnRha2VMb3NzKG5hbWUsIGxvY2tCYWNrZW5kLmVwb2NoID8/IG51bGwpXG5cbiAgICBpZiAobG9zcykge1xuICAgICAgdGhyb3cgbmV3IEFkdmlzb3J5TG9ja0xvc3RFcnJvcihcbiAgICAgICAgYExvc3QgdGhlIGxlYXNlIGZvciBhZHZpc29yeSBsb2NrICR7SlNPTi5zdHJpbmdpZnkobmFtZSl9IHdoaWxlIHRoZSBjcml0aWNhbCBzZWN0aW9uIHdhcyBydW5uaW5nYCxcbiAgICAgICAge1xuICAgICAgICAgIGNhdXNlOiBjYWxsYmFja0Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBjYWxsYmFja0Vycm9yIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGN1cnJlbnRFcG9jaDogbG9zcy5jdXJyZW50RXBvY2gsXG4gICAgICAgICAgZXBvY2g6IGxvY2tCYWNrZW5kLmVwb2NoID8/IG51bGwsXG4gICAgICAgICAgbG9ja05hbWU6IG5hbWVcbiAgICAgICAgfVxuICAgICAgKVxuICAgIH1cblxuICAgIGlmIChmYWlsZWQpIHRocm93IGNhbGxiYWNrRXJyb3JcblxuICAgIHJldHVybiAvKiogQHR5cGUge1R9ICovICh2YWx1ZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBvcnRzIGFuIGFjcXVpc2l0aW9uIHNlcnZlZCBiZWxvdyB0aGUgbG9jayBuYW1lJ3MgcHJlZmVycmVkIHRpZXJcbiAgICogKGRlc2lnbiDCpzMpOiBldmVyeSBmYWxsYmFjayBpcyB2aXNpYmxlIG9uIHRoZSBmcmFtZXdvcmstZXJyb3IgY2hhbm5lbCwgc28gYVxuICAgKiBzaWxlbnQgZG93bmdyYWRlIGlzIGltcG9zc2libGUuXG4gICAqIEBwYXJhbSB7e2xvY2tOYW1lOiBzdHJpbmcsIHJlYXNvbjogc3RyaW5nLCBzZXJ2ZWRCeTogaW1wb3J0KFwiLi9hZHZpc29yeS1sb2NrLWJhY2tlbmQtcG9saWN5LmpzXCIpLkFkdmlzb3J5TG9ja1RpZXJ9fSBhcmdzIC0gRmFsbGJhY2sgZGV0YWlscy5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICByZXBvcnRBZHZpc29yeUxvY2tGYWxsYmFjayh7bG9ja05hbWUsIHJlYXNvbiwgc2VydmVkQnl9KSB7XG4gICAgY29uc3QgcG9saWN5ID0gcmVzb2x2ZUFkdmlzb3J5TG9ja0JhY2tlbmRQb2xpY3kobG9ja05hbWUsIHRoaXMuY29uZmlndXJhdGlvbi5nZXRBZHZpc29yeUxvY2tQb2xpY3koKSlcbiAgICBlbWl0QWR2aXNvcnlMb2NrRmFsbGJhY2tSZXBvcnQodGhpcy5jb25maWd1cmF0aW9uLCB7XG4gICAgICBsb2NrTmFtZSxcbiAgICAgIHByZWZlcnJlZFRpZXI6IHBvbGljeS5wcmVmZXJyZWRUaWVyLFxuICAgICAgcmVhc29uLFxuICAgICAgc2VydmVkQnlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIHRoZSBiYWNrZW5kIHBvbGljeSBmb3Igb25lIGxvY2sgbmFtZSBhbmQgcmV0dXJucyB0aGUgZmlsZVxuICAgKiBiYWNrZW5kIHdoZW4gdGhlIG5hbWUgZXhwbGljaXRseSBvcHRzIGludG8gdGhlIGZpbGUgdGllclxuICAgKiAoYHByZWZlcnJlZFRpZXI6IFwiZmlsZVwiYCBwbHVzIGBhZHZpc29yeUxvY2tzLmJhY2tlbmRzLmZpbGUuZW5hYmxlZDogdHJ1ZWApLlxuICAgKiBBIG5hbWUgd2hvc2UgZGVjbGFyZWQgbWluaW11bSB0aWVyIGlzIGNyb3NzLWhvc3QgaXMgcmVmdXNlZCBsb3VkbHlcbiAgICogKGBBZHZpc29yeUxvY2tNaW5UaWVyUmVmdXNlZEVycm9yYCkgYmVmb3JlIGFueSBjb250YWN0IHdpdGggdGhlIGZpbGVcbiAgICogdGllci4gQSBuYW1lIHRoYXQgcHJlZmVycyB0aGUgZmlsZSB0aWVyIHdoaWxlIHRoZSBiYWNrZW5kIGlzIGRpc2FibGVkXG4gICAqIG1vdmVzIHRvIHRoZSBkcml2ZXIgcGF0aCAoYSBzdHJvbmdlci1vci1lcXVhbCB0aWVyKSwgbmV2ZXIgdGhlIG90aGVyIHdheVxuICAgKiBhcm91bmQuIE5vdGhpbmcgaGVyZSBldmVyIGF1dG8tZW5hYmxlcyB0aGUgZmlsZSB0aWVyLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIExvY2sgbmFtZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi9hZHZpc29yeS1sb2NrLWZpbGUtYmFja2VuZC5qc1wiKS5kZWZhdWx0IHwgbnVsbD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgZmlsZSBiYWNrZW5kIHNlcnZpbmcgdGhpcyBuYW1lLCBvciBudWxsIGZvciB0aGUgZHJpdmVyIHBhdGguXG4gICAqL1xuICBhc3luYyBmaWxlQmFja2VuZEZvck5hbWUobmFtZSkge1xuICAgIGNvbnN0IHBvbGljeSA9IHJlc29sdmVBZHZpc29yeUxvY2tCYWNrZW5kUG9saWN5KG5hbWUsIHRoaXMuY29uZmlndXJhdGlvbi5nZXRBZHZpc29yeUxvY2tQb2xpY3koKSlcblxuICAgIGlmIChwb2xpY3kucHJlZmVycmVkVGllciAhPT0gXCJmaWxlXCIpIHJldHVybiBudWxsXG5cbiAgICBpZiAoIWFkdmlzb3J5TG9ja1BvbGljeUFsbG93c0ZpbGVUaWVyKHBvbGljeSkpIHtcbiAgICAgIHJlZnVzZUFkdmlzb3J5TG9ja1RpZXJCZWxvd01pbmltdW0oe1xuICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24sXG4gICAgICAgIGxvY2tOYW1lOiBuYW1lLFxuICAgICAgICBtaW5UaWVyOiBwb2xpY3kubWluVGllcixcbiAgICAgICAgcmVxdWVzdGVkQmFja2VuZDogXCJmaWxlXCJcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgY29uc3QgYmFja2VuZCA9IGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5nZXRBZHZpc29yeUxvY2tGaWxlQmFja2VuZCgpXG5cbiAgICBpZiAoIWJhY2tlbmQpIHtcbiAgICAgIC8vIFByZWZlcnJlZCB0aWVyIHVuYXZhaWxhYmxlOiBmYWlsICp1cHdhcmQqIHRvIHRoZSBkcml2ZXIgcGF0aCAoYVxuICAgICAgLy8gc3Ryb25nZXItb3ItZXF1YWwgdGllciksIG5ldmVyIGRvd253YXJkLiBJZiB0aGUgZHJpdmVyIGNhbm5vdCBzYXRpc2Z5XG4gICAgICAvLyB0aGUgbWluaW11bSBlaXRoZXIsIGBhc3NlcnREcml2ZXJUaWVyRWxpZ2libGVgIHRocm93c1xuICAgICAgLy8gYEFkdmlzb3J5TG9ja0JhY2tlbmRVbmF2YWlsYWJsZUVycm9yYCBvbiB0aGUgZHJpdmVyIHBhdGguXG4gICAgICByZXR1cm4gbnVsbFxuICAgIH1cblxuICAgIHJldHVybiBiYWNrZW5kXG4gIH1cblxuICAvKipcbiAgICogRmFpbC1jbG9zZWQgY2hlY2sgb24gdGhlIGRyaXZlciBwYXRoIChkZXNpZ24gwqc5KTogYW4gdW5kZWNsYXJlZCBsb2NrIG5hbWVcbiAgICoga2VlcHMgdG9kYXkncyBiZWhhdmlvciAoYW55IGRyaXZlciBzZXJ2ZXMgaXQg4oCUIGZ1bGwgYmFja3dhcmRcbiAgICogY29tcGF0aWJpbGl0eSksIGJ1dCBhIG5hbWUgd2l0aCBhbiBleHBsaWNpdCBwb2xpY3kgZW50cnkgaXMgcmVmdXNlZCB3aXRoXG4gICAqIGBBZHZpc29yeUxvY2tCYWNrZW5kVW5hdmFpbGFibGVFcnJvcmAgd2hlbiB0aGUgY29uZmlndXJlZCBkcml2ZXIgY2Fubm90XG4gICAqIHNhdGlzZnkgaXRzIG1pbmltdW0gdGllciAoZS5nLiBgbWluVGllcjogXCJkcml2ZXItbmF0aXZlXCJgIG9uIGEgU1FMaXRlXG4gICAqIGRyaXZlciwgd2hpY2ggaGFzIG5vIG5hdGl2ZSBhZHZpc29yeS1sb2NrIHByaW1pdGl2ZSkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTG9jayBuYW1lLlxuICAgKiBAcGFyYW0ge0Fkdmlzb3J5TG9ja0JhY2tlbmRQcm92ZW5hbmNlfSBsb2NrQmFja2VuZCAtIFRpZXIgdGhlIGRyaXZlciBwYXRoIHdvdWxkIHNlcnZlIHdpdGguXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgYXNzZXJ0RHJpdmVyVGllckVsaWdpYmxlKG5hbWUsIGxvY2tCYWNrZW5kKSB7XG4gICAgY29uc3QgcG9saWN5ID0gcmVzb2x2ZUFkdmlzb3J5TG9ja0JhY2tlbmRQb2xpY3kobmFtZSwgdGhpcy5jb25maWd1cmF0aW9uLmdldEFkdmlzb3J5TG9ja1BvbGljeSgpKVxuXG4gICAgaWYgKCFwb2xpY3kuZW50cnkpIHJldHVyblxuXG4gICAgY29uc3QgdGllciA9IGxvY2tCYWNrZW5kLmJhY2tlbmRcblxuICAgIGlmICh0aWVyID09PSBcInByb2Nlc3MtbG9jYWxcIiAmJiAhcG9saWN5LmFsbG93ZWRUaWVycy5pbmNsdWRlcyhcInByb2Nlc3MtbG9jYWxcIikpIHtcbiAgICAgIHRocm93IG5ldyBBZHZpc29yeUxvY2tCYWNrZW5kVW5hdmFpbGFibGVFcnJvcihcbiAgICAgICAgYEFkdmlzb3J5IGxvY2sgJHtKU09OLnN0cmluZ2lmeShuYW1lKX0gcmVxdWlyZXMgbWluaW11bSB0aWVyICR7SlNPTi5zdHJpbmdpZnkocG9saWN5Lm1pblRpZXIpfSBidXQgdGhlIGNvbmZpZ3VyZWQgZHJpdmVyICgke1N0cmluZyhsb2NrQmFja2VuZC5kcml2ZXJUeXBlKX0pIG9ubHkgb2ZmZXJzIHRoZSBwcm9jZXNzLWxvY2FsIHRpZXJgLFxuICAgICAgICB7bG9ja05hbWU6IG5hbWUsIG1pblRpZXI6IHBvbGljeS5taW5UaWVyLCByZWFzb25zOiBbYGRyaXZlciB0aWVyICR7dGllcn0gYmVsb3cgbWluVGllciAke3BvbGljeS5taW5UaWVyfWBdfVxuICAgICAgKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgd2FpdCBib3VuZCBmb3IgYSBmaWxlLXRpZXIgYWNxdWlzaXRpb246IGFuIGV4cGxpY2l0IGNhbGxlclxuICAgKiBgdGltZW91dE1zYCAoaW5jbHVkaW5nIGFuIGV4cGxpY2l0IGBudWxsYCBvcHQtb3V0KSB3aW5zLCBvdGhlcndpc2UgdGhlXG4gICAqIHNhbWUgZnJhbWV3b3JrIGRlZmF1bHQgdGhhdCBib3VuZHMgZHJpdmVyIGFjcXVpc2l0aW9ucyBhcHBsaWVzLlxuICAgKiBAcGFyYW0ge3t0aW1lb3V0TXM/OiBudW1iZXIgfCBudWxsfX0gYXJncyAtIExvY2sgb3B0aW9ucy5cbiAgICogQHJldHVybnMge251bWJlciB8IG51bGx9IC0gV2FpdCBib3VuZCBpbiBtaWxsaXNlY29uZHMsIG9yIGBudWxsYCBmb3IgYW4gaW5kZWZpbml0ZSB3YWl0LlxuICAgKi9cbiAgYWNxdWlyZVRpbWVvdXRNcyhhcmdzKSB7XG4gICAgaWYgKGFyZ3MudGltZW91dE1zICE9PSB1bmRlZmluZWQpIHJldHVybiBhcmdzLnRpbWVvdXRNc1xuXG4gICAgcmV0dXJuIERFRkFVTFRfQURWSVNPUllfTE9DS19BQ1FVSVJFX1RJTUVPVVRfTVNcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIGFjcXVpc2l0aW9uIHByb3ZlbmFuY2UgZm9yIGEgZmlsZS10aWVyIGhvbGQuIFRoZSBmaWxlIHRpZXJcbiAgICogY2Fubm90IGNhcnJ5IGZlbmNpbmcgdG9rZW5zLCBzbyB0aGUgbGltaXRhdGlvbiBpcyByZXBvcnRlZCBvbiBldmVyeVxuICAgKiBhY3F1aXNpdGlvbiByYXRoZXIgdGhhbiBzaWxlbnRseSBwcmV0ZW5kZWQgYXdheSAoZGVzaWduIMKnOCkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9hZHZpc29yeS1sb2NrLWZpbGUtYmFja2VuZC5qc1wiKS5kZWZhdWx0fSBiYWNrZW5kIC0gQmFja2VuZCB0aGF0IHNlcnZlZCB0aGUgYWNxdWlzaXRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTG9jayBuYW1lLlxuICAgKiBAcmV0dXJucyB7QWR2aXNvcnlMb2NrQmFja2VuZFByb3ZlbmFuY2V9IC0gQWNxdWlzaXRpb24gcHJvdmVuYW5jZS5cbiAgICovXG4gIGZpbGVQcm92ZW5hbmNlKGJhY2tlbmQsIG5hbWUpIHtcbiAgICByZXR1cm4ge2JhY2tlbmQ6IFwiZmlsZVwiLCBmZW5jaW5nU3VwcG9ydGVkOiBmYWxzZSwgaG9sZGVySWQ6IGJhY2tlbmQuaG9sZGVySWQsIGxvY2tOYW1lOiBuYW1lfVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyB0aGUgYWNxdWlzaXRpb24gcHJvdmVuYW5jZSBmb3IgYSBkcml2ZXItc2VydmVkIGhvbGQuIFNRTGl0ZSBoYXMgbm9cbiAgICogbmF0aXZlIGFkdmlzb3J5LWxvY2sgcHJpbWl0aXZlLCBzbyBpdHMgZW11bGF0aW9uIHRpZXIgaXMgcmVwb3J0ZWQgYXNcbiAgICogYHByb2Nlc3MtbG9jYWxgIHJhdGhlciB0aGFuIHByZXRlbmRpbmcgdG8gYmUgZGF0YWJhc2UtbmF0aXZlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uIHRoYXQgc2VydmVkIHRoZSBhY3F1aXNpdGlvbi5cbiAgICogQHJldHVybnMge0Fkdmlzb3J5TG9ja0JhY2tlbmRQcm92ZW5hbmNlfSAtIEFjcXVpc2l0aW9uIHByb3ZlbmFuY2UuXG4gICAqL1xuICBkcml2ZXJQcm92ZW5hbmNlKGNvbm5lY3Rpb24pIHtcbiAgICBsZXQgZHJpdmVyVHlwZSA9IG51bGxcblxuICAgIHRyeSB7XG4gICAgICBkcml2ZXJUeXBlID0gY29ubmVjdGlvbi5nZXRUeXBlKClcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIFRlc3Qgc3R1YiBkcml2ZXJzIG1heSBub3QgaW1wbGVtZW50IGdldFR5cGUoKTsgdGhlIHRpZXIgYWxvbmUgaWRlbnRpZmllcyB0aGUgYmFja2VuZC5cbiAgICB9XG5cbiAgICBjb25zdCB0aWVyID0gdHlwZW9mIGNvbm5lY3Rpb24uYWR2aXNvcnlMb2NrQmFja2VuZFRpZXIgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgPyBjb25uZWN0aW9uLmFkdmlzb3J5TG9ja0JhY2tlbmRUaWVyKClcbiAgICAgIDogKGRyaXZlclR5cGUgPT09IFwic3FsaXRlXCIgPyBcInByb2Nlc3MtbG9jYWxcIiA6IFwiZHJpdmVyLW5hdGl2ZVwiKVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGJhY2tlbmQ6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9hZHZpc29yeS1sb2NrLWJhY2tlbmQtcG9saWN5LmpzXCIpLkFkdmlzb3J5TG9ja1RpZXJ9ICovICh0aWVyKSxcbiAgICAgIGRyaXZlclR5cGU6IGRyaXZlclR5cGUgPz8gdW5kZWZpbmVkLFxuICAgICAgZmVuY2luZ1N1cHBvcnRlZDogdGllciA9PT0gXCJkcml2ZXItbmF0aXZlXCJcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBsb2NrIHdvcmsgb24gdGhlIGNhbGxlciBjb25uZWN0aW9uIHVubGVzcyBgZGVkaWNhdGVkQ29ubmVjdGlvbmAgaXNcbiAgICogcmVxdWVzdGVkIG9yIGEgcG9zaXRpdmUgaG9sZCB0aW1lb3V0IG5lZWRzIGl0cyBvd24gbG9jayBjb25uZWN0aW9uLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0ge3tkZWRpY2F0ZWRDb25uZWN0aW9uPzogYm9vbGVhbiwgaG9sZFRpbWVvdXRNcz86IG51bWJlciB8IG51bGx9fSBhcmdzIC0gTG9jayBjb25uZWN0aW9uIG9wdGlvbnMuXG4gICAqIEBwYXJhbSB7KGNvbm5lY3Rpb246IGltcG9ydChcIi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQpID0+IFByb21pc2U8VD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgcmVjZWl2aW5nIHRoZSBjb25uZWN0aW9uIHRoYXQgb3ducyB0aGUgYWR2aXNvcnkgbG9jay5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgd2l0aExvY2tDb25uZWN0aW9uKGFyZ3MsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgaG9sZFRpbWVvdXRNcyA9IGFyZ3MuaG9sZFRpbWVvdXRNc1xuXG4gICAgaWYgKGFyZ3MuZGVkaWNhdGVkQ29ubmVjdGlvbiB8fCAoaG9sZFRpbWVvdXRNcyAmJiBob2xkVGltZW91dE1zID4gMCkpIHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLndpdGhEZWRpY2F0ZWRDb25uZWN0aW9uKGNhbGxiYWNrKVxuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCBjYWxsYmFjayh0aGlzLmNvbm5lY3Rpb25Qcm92aWRlcigpKVxuICB9XG5cbiAgLyoqXG4gICAqIFNwYXducyBhIGRlZGljYXRlZCBsb2NrIGNvbm5lY3Rpb24gYW5kIGNsb3NlcyBpdCBhZnRlciBsb2NrIHdvcmsgY29tcGxldGVzXG4gICAqIHdoZW4gdGhlIHNwYXduZWQgZHJpdmVyIG93bnMgdGhlIHVuZGVybHlpbmcgcGh5c2ljYWwgY29ubmVjdGlvbi5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHsoY29ubmVjdGlvbjogaW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCkgPT4gUHJvbWlzZTxUPn0gY2FsbGJhY2sgLSBDYWxsYmFjayB0aGF0IHJlY2VpdmVzIHRoZSBkZWRpY2F0ZWQgbG9jayBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBhc3luYyB3aXRoRGVkaWNhdGVkQ29ubmVjdGlvbihjYWxsYmFjaykge1xuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0RGF0YWJhc2VQb29sKHRoaXMuZGF0YWJhc2VJZGVudGlmaWVyKS5zcGF3bkNvbm5lY3Rpb24oKVxuXG4gICAgLy8gVGhlIHNwYXduZWQgZHJpdmVyIG93bnMgaXRzIHBoeXNpY2FsIGNvbm5lY3Rpb24gdW5sZXNzIGl0IGJvcnJvd3MgYSBzaGFyZWQgb25lXG4gICAgLy8gdmlhIGBnZXRDb25uZWN0aW9uYC4gQW4gb3duZWQgY29ubmVjdGlvbiBsaXZlcyBvdXRzaWRlIHRoZSBwb29scycgdHJhY2tlZCBzZXRzLFxuICAgIC8vIHNvIHJlZ2lzdGVyIGl0IHdoaWxlIHRoZSBsb2NrIGlzIGhlbGQ6IGEgc2h1dGRvd24gdGhlbiBjbG9zZXMgaXQgKHJlbGVhc2luZyB0aGVcbiAgICAvLyBsb2NrKSBpbnN0ZWFkIG9mIG9ycGhhbmluZyBhIGhhbGYtb3BlbiBzZXNzaW9uIHVudGlsIHRoZSBEQiBgd2FpdF90aW1lb3V0YC5cbiAgICBjb25zdCBvd25zQ29ubmVjdGlvbiA9ICFjb25uZWN0aW9uLmdldEFyZ3MoKS5nZXRDb25uZWN0aW9uXG5cbiAgICBpZiAob3duc0Nvbm5lY3Rpb24pIHRoaXMuY29uZmlndXJhdGlvbi5yZWdpc3RlckFkdmlzb3J5TG9ja0Nvbm5lY3Rpb24oY29ubmVjdGlvbilcblxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgY2FsbGJhY2soY29ubmVjdGlvbilcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKG93bnNDb25uZWN0aW9uKSB7XG4gICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi51bnJlZ2lzdGVyQWR2aXNvcnlMb2NrQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuICAgICAgICBhd2FpdCBjb25uZWN0aW9uLmNsb3NlKClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGF3YWl0IGNvbm5lY3Rpb24ucmVsZWFzZUhlbGRBZHZpc29yeUxvY2tzKClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBgY2FsbGJhY2tgLCByZWplY3Rpbmcgd2l0aCBgQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXRFcnJvcmAgaWYgaXQgaGFzXG4gICAqIG5vdCBzZXR0bGVkIHdpdGhpbiBgaG9sZFRpbWVvdXRNc2AuIFRoZSBjYWxsYmFjayBpcyBub3QgY2FuY2VsbGVkOyBjYWxsZXJzXG4gICAqIHVzZSBhIGRlZGljYXRlZCBhZHZpc29yeS1sb2NrIGNvbm5lY3Rpb24gc28gdGhlIGxvY2sgY2FuIHN0aWxsIGJlIHJlbGVhc2VkLlxuICAgKlxuICAgKiBUaGUgY2FsbGJhY2sgcmVjZWl2ZXMgYSBgVGltZW91dENvbnRyb2xgIGZyb20gYXdhaXRlcnksIGVuYWJsaW5nIGNvb3BlcmF0aXZlXG4gICAqIGNhbmNlbGxhdGlvbiB2aWEgYGNvbnRyb2wuY2hlY2soKWAsIGBjb250cm9sLnNpZ25hbGAsIGBjb250cm9sLnRpbWVkT3V0YCxcbiAgICogYW5kIGBjb250cm9sLnJlbWFpbmluZygpYCwgcGx1cyBgbG9ja0JhY2tlbmRgIHByb3ZlbmFuY2UgZm9yIHRoZSB0aWVyIHRoYXRcbiAgICogc2VydmVkIHRoZSBhY3F1aXNpdGlvbi5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBMb2NrIG5hbWUgKGZvciB0aGUgZXJyb3IgbWVzc2FnZSkuXG4gICAqIEBwYXJhbSB7KGFyZ3M/OiB7Y29udHJvbD86IGltcG9ydChcImF3YWl0ZXJ5L2J1aWxkL3RpbWVvdXQuanNcIikuVGltZW91dENvbnRyb2wsIGxvY2tCYWNrZW5kOiBBZHZpc29yeUxvY2tCYWNrZW5kUHJvdmVuYW5jZX0pID0+IFByb21pc2U8VD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgaG9sZGluZyB0aGUgbG9jay5cbiAgICogQHBhcmFtIHtudW1iZXIgfCBudWxsfSBbaG9sZFRpbWVvdXRNc10gLSBNYXggaG9sZCB0aW1lOyBmYWxzeSBkaXNhYmxlcyB0aGUgdGltZW91dC5cbiAgICogQHBhcmFtIHtBZHZpc29yeUxvY2tCYWNrZW5kUHJvdmVuYW5jZX0gW2xvY2tCYWNrZW5kXSAtIFByb3ZlbmFuY2Ugb2YgdGhlIGFjcXVpc2l0aW9uIHNlcnZpbmcgdGhpcyBob2xkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgcnVuV2l0aEFkdmlzb3J5TG9ja0hvbGRUaW1lb3V0KG5hbWUsIGNhbGxiYWNrLCBob2xkVGltZW91dE1zLCBsb2NrQmFja2VuZCkge1xuICAgIGlmICghaG9sZFRpbWVvdXRNcyB8fCBob2xkVGltZW91dE1zIDw9IDApIHtcbiAgICAgIHJldHVybiBhd2FpdCBjYWxsYmFjayh7bG9ja0JhY2tlbmQ6IGxvY2tCYWNrZW5kID8/IEFkdmlzb3J5TG9ja1J1bm5lci51bmtub3duQmFja2VuZFByb3ZlbmFuY2UoKX0pXG4gICAgfVxuXG4gICAgbGV0IGNhbGxiYWNrU2V0dGxlZCA9IGZhbHNlXG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRpbWVvdXQoe3RpbWVvdXQ6IGhvbGRUaW1lb3V0TXN9LCBhc3luYyAoe2NvbnRyb2x9KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IGNhbGxiYWNrKHtjb250cm9sLCBsb2NrQmFja2VuZDogbG9ja0JhY2tlbmQgPz8gQWR2aXNvcnlMb2NrUnVubmVyLnVua25vd25CYWNrZW5kUHJvdmVuYW5jZSgpfSlcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBjYWxsYmFja1NldHRsZWQgPSB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmICghY2FsbGJhY2tTZXR0bGVkIHx8IGVycm9yIGluc3RhbmNlb2YgVGltZW91dEVycm9yKSB7XG4gICAgICAgIHRocm93IG5ldyBBZHZpc29yeUxvY2tIb2xkVGltZW91dEVycm9yKGBBZHZpc29yeSBsb2NrICR7SlNPTi5zdHJpbmdpZnkobmFtZSl9IGhlbGQgbG9uZ2VyIHRoYW4gJHtob2xkVGltZW91dE1zfW1zYCwge25hbWV9KVxuICAgICAgfVxuXG4gICAgICB0aHJvdyBlcnJvclxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBOZXV0cmFsIHByb3ZlbmFuY2UgZm9yIGRpcmVjdCBgcnVuV2l0aEFkdmlzb3J5TG9ja0hvbGRUaW1lb3V0YCBjYWxsZXJzIHRoYXRcbiAgICogaG9sZCBhIGxvY2sgYWNxdWlyZWQgb3V0c2lkZSB0aGlzIHJ1bm5lci5cbiAgICogQHJldHVybnMge0Fkdmlzb3J5TG9ja0JhY2tlbmRQcm92ZW5hbmNlfSAtIFByb3ZlbmFuY2Ugd2l0aCBhbiB1bmtub3duIHRpZXIuXG4gICAqL1xuICBzdGF0aWMgdW5rbm93bkJhY2tlbmRQcm92ZW5hbmNlKCkge1xuICAgIHJldHVybiB7YmFja2VuZDogXCJwcm9jZXNzLWxvY2FsXCIsIGZlbmNpbmdTdXBwb3J0ZWQ6IGZhbHNlfVxuICB9XG59XG5cbi8qKlxuICogUnVucyBhZHZpc29yeSBsb2NrIHBvbGljeSBhbGxvd3MgZmlsZSB0aWVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Fkdmlzb3J5LWxvY2stYmFja2VuZC1wb2xpY3kuanNcIikuUmVzb2x2ZWRBZHZpc29yeUxvY2tCYWNrZW5kUG9saWN5fSBwb2xpY3kgLSBSZXNvbHZlZCBwb2xpY3kuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSBmaWxlIHRpZXIgbWF5IHNlcnZlIHRoaXMgbmFtZS5cbiAqL1xuZnVuY3Rpb24gYWR2aXNvcnlMb2NrUG9saWN5QWxsb3dzRmlsZVRpZXIocG9saWN5KSB7XG4gIHJldHVybiBwb2xpY3kuYWxsb3dlZFRpZXJzLmluY2x1ZGVzKFwiZmlsZVwiKVxufVxuXG5leHBvcnQge0Fkdmlzb3J5TG9ja0J1c3lFcnJvciwgQWR2aXNvcnlMb2NrSG9sZFRpbWVvdXRFcnJvciwgQWR2aXNvcnlMb2NrVGltZW91dEVycm9yfVxuZXhwb3J0IHtBZHZpc29yeUxvY2tCYWNrZW5kVW5hdmFpbGFibGVFcnJvciwgQWR2aXNvcnlMb2NrTWluVGllclJlZnVzZWRFcnJvcn0gZnJvbSBcIi4vYWR2aXNvcnktbG9jay1iYWNrZW5kLXBvbGljeS5qc1wiXG5leHBvcnQge0Fkdmlzb3J5TG9ja0xvc3RFcnJvciwgQWR2aXNvcnlMb2NrU2VydmljZVVuYXZhaWxhYmxlRXJyb3J9IGZyb20gXCIuL2Fkdmlzb3J5LWxvY2stZXJyb3JzLmpzXCJcbiJdfQ==
@@ -52,9 +52,9 @@ export type AdvisoryLockTelemetryThresholds = {
52
52
  * A lock convoy is only fixable when it is *attributable*: which lock name was
53
53
  * contended, on which backend tier, for how long, and who held it. These reports
54
54
  * fire on the acquisition/release events themselves — never from a periodic
55
- * scanner — so a contended lock in production surfaces on the framework-error
56
- * channel with the holder identity available on that tier at that moment,
57
- * without SSH forensics.
55
+ * scanner — so a contended lock in production surfaces on the telemetry channel
56
+ * with the holder identity available on that tier at that moment, without SSH
57
+ * forensics.
58
58
  *
59
59
  * Three events, each with its own threshold (all configurable per database via
60
60
  * `advisoryLockTelemetry`, see `docs/advisory-locks.md`):
@@ -129,4 +129,20 @@ export declare function advisoryLockTelemetryThresholds(args: import("../configu
129
129
  * @returns {void} - No return value.
130
130
  */
131
131
  export declare function emitAdvisoryLockTelemetryReport(configuration: import("../configuration.js").default, report: AdvisoryLockTelemetryReport): void;
132
+ /**
133
+ * Reports one acquisition served below the lock name's preferred tier
134
+ * (design §3): the caller wanted the lock server and got the database, so the
135
+ * downgrade must be visible without being mistaken for a failure. Fallbacks are
136
+ * measurements, not errors, so they stay off `framework-error` and its bug
137
+ * reporters (same contract as the duration telemetry).
138
+ * @param {import("../configuration.js").default} configuration - Owning configuration.
139
+ * @param {{lockName: string, preferredTier: string, reason: string, servedBy: string}} report - Fallback details.
140
+ * @returns {void}
141
+ */
142
+ export declare function emitAdvisoryLockFallbackReport(configuration: import("../configuration.js").default, report: {
143
+ lockName: string;
144
+ preferredTier: string;
145
+ reason: string;
146
+ servedBy: string;
147
+ }): void;
132
148
  //# sourceMappingURL=advisory-lock-telemetry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"advisory-lock-telemetry.d.ts","sourceRoot":"","sources":["../../../src/database/advisory-lock-telemetry.js"],"names":[],"mappings":"AA6CG,YAAkB,2BAA2B,GAC7C;;;;IAAuG,KAAK,EAAjG,4BAA4B,GAAG,+BAA+B,GAAG,yBAAyB,CACrG;;;;IAAmB,QAAQ,EAAhB,MAAM,CACjB;;;;IAAmB,WAAW,EAAnB,MAAM,CACjB;;;;IAAmB,UAAU,EAAlB,MAAM,CACjB;;;;IAA0C,OAAO,EAAtC,UAAU,GAAG,SAAS,GAAG,IAAI,CACxC;;;;IAA0B,SAAS,EAAxB,MAAM,GAAG,IAAI,CACxB;;;;IAA0B,QAAQ,EAAvB,MAAM,GAAG,IAAI,CACxB;;;;IAA0B,kBAAkB,EAAjC,MAAM,GAAG,IAAI,CACxB;;;;IAA0B,iBAAiB,EAAhC,MAAM,GAAG,IAAI,CAC1B;CAAA,CAAA;AAIE,YAAkB,+BAA+B,GACjD;;;;IAA0B,aAAa,EAA5B,MAAM,GAAG,IAAI,CACxB;;;;IAA0B,UAAU,EAAzB,MAAM,GAAG,IAAI,CAC1B;CAAA,CAAA;AA5DD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH;;;;;;;;;;;;GAYG;AAEH;;;;;GAKG;AAEH,iFAAiF;AACjF,eAAO,MAAM,qCAAqC,OAAO,CAAA;AAEzD,sEAAsE;AACtE,eAAO,MAAM,kCAAkC,QAAY,CAAA;AAE3D;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,IAAI,EAHzC,OAAO,2BAA2B,EAAE,yBAGK,GAFvC,+BAA+B,CAiB3C;AAED;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAAC,aAAa,EAJlD,OAAO,qBAAqB,EAAE,OAIoB,EAAE,MAAM,EAH1D,2BAG0D,GAFxD,IAAI,CA0BhB"}
1
+ {"version":3,"file":"advisory-lock-telemetry.d.ts","sourceRoot":"","sources":["../../../src/database/advisory-lock-telemetry.js"],"names":[],"mappings":"AA6CG,YAAkB,2BAA2B,GAC7C;;;;IAAuG,KAAK,EAAjG,4BAA4B,GAAG,+BAA+B,GAAG,yBAAyB,CACrG;;;;IAAmB,QAAQ,EAAhB,MAAM,CACjB;;;;IAAmB,WAAW,EAAnB,MAAM,CACjB;;;;IAAmB,UAAU,EAAlB,MAAM,CACjB;;;;IAA0C,OAAO,EAAtC,UAAU,GAAG,SAAS,GAAG,IAAI,CACxC;;;;IAA0B,SAAS,EAAxB,MAAM,GAAG,IAAI,CACxB;;;;IAA0B,QAAQ,EAAvB,MAAM,GAAG,IAAI,CACxB;;;;IAA0B,kBAAkB,EAAjC,MAAM,GAAG,IAAI,CACxB;;;;IAA0B,iBAAiB,EAAhC,MAAM,GAAG,IAAI,CAC1B;CAAA,CAAA;AAIE,YAAkB,+BAA+B,GACjD;;;;IAA0B,aAAa,EAA5B,MAAM,GAAG,IAAI,CACxB;;;;IAA0B,UAAU,EAAzB,MAAM,GAAG,IAAI,CAC1B;CAAA,CAAA;AA5DD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH;;;;;;;;;;;;GAYG;AAEH;;;;;GAKG;AAEH,iFAAiF;AACjF,eAAO,MAAM,qCAAqC,OAAO,CAAA;AAEzD,sEAAsE;AACtE,eAAO,MAAM,kCAAkC,QAAY,CAAA;AAE3D;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,IAAI,EAHzC,OAAO,2BAA2B,EAAE,yBAGK,GAFvC,+BAA+B,CAiB3C;AAED;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAAC,aAAa,EAJlD,OAAO,qBAAqB,EAAE,OAIoB,EAAE,MAAM,EAH1D,2BAG0D,GAFxD,IAAI,CA0BhB;AAED;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAAC,aAAa,EAJjD,OAAO,qBAAqB,EAAE,OAImB,EAAE,MAAM,EAHzD;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAGjB,GAFvD,IAAI,CA0BhB"}
@@ -5,9 +5,9 @@
5
5
  * A lock convoy is only fixable when it is *attributable*: which lock name was
6
6
  * contended, on which backend tier, for how long, and who held it. These reports
7
7
  * fire on the acquisition/release events themselves — never from a periodic
8
- * scanner — so a contended lock in production surfaces on the framework-error
9
- * channel with the holder identity available on that tier at that moment,
10
- * without SSH forensics.
8
+ * scanner — so a contended lock in production surfaces on the telemetry channel
9
+ * with the holder identity available on that tier at that moment, without SSH
10
+ * forensics.
11
11
  *
12
12
  * Three events, each with its own threshold (all configurable per database via
13
13
  * `advisoryLockTelemetry`, see `docs/advisory-locks.md`):
@@ -120,4 +120,37 @@ export function emitAdvisoryLockTelemetryReport(configuration, report) {
120
120
  console.error(`[velocious advisory-lock-telemetry ${report.event}] lock=${JSON.stringify(report.lockName)} tier=${report.backendTier} durationMs=${report.durationMs}${report.outcome ? ` outcome=${report.outcome}` : ""}${report.holderConnectionId ? ` holderConnectionId=${report.holderConnectionId}` : ""}${report.holderId ? ` holderId=${report.holderId}` : ""} — subscribe via configuration.getTelemetryEvents().on("telemetry", …) to route these measurements to your metrics`);
121
121
  }
122
122
  }
123
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWR2aXNvcnktbG9jay10ZWxlbWV0cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGF0YWJhc2UvYWR2aXNvcnktbG9jay10ZWxlbWV0cnkuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Q0c7QUFFSDs7Ozs7Ozs7Ozs7O0dBWUc7QUFFSDs7Ozs7R0FLRztBQUVILGlGQUFpRjtBQUNqRixNQUFNLENBQUMsTUFBTSxxQ0FBcUMsR0FBRyxJQUFJLENBQUE7QUFFekQsc0VBQXNFO0FBQ3RFLE1BQU0sQ0FBQyxNQUFNLGtDQUFrQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUE7QUFFM0Q7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSwrQkFBK0IsQ0FBQyxJQUFJO0lBQ2xELE1BQU0sVUFBVSxHQUFHLElBQUksRUFBRSxxQkFBcUIsQ0FBQTtJQUM5Qyw4Q0FBOEM7SUFDOUMsTUFBTSxVQUFVLEdBQUc7UUFDakIsYUFBYSxFQUFFLHFDQUFxQztRQUNwRCxVQUFVLEVBQUUsa0NBQWtDO0tBQy9DLENBQUE7SUFFRCxJQUFJLFVBQVUsRUFBRSxhQUFhLEtBQUssSUFBSTtRQUFFLFVBQVUsQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFBO1NBQ2xFLElBQUksT0FBTyxVQUFVLEVBQUUsYUFBYSxLQUFLLFFBQVEsSUFBSSxVQUFVLENBQUMsYUFBYSxJQUFJLENBQUM7UUFBRSxVQUFVLENBQUMsYUFBYSxHQUFHLFVBQVUsQ0FBQyxhQUFhLENBQUE7SUFFNUksSUFBSSxVQUFVLEVBQUUsVUFBVSxLQUFLLElBQUk7UUFBRSxVQUFVLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQTtTQUM1RCxJQUFJLE9BQU8sVUFBVSxFQUFFLFVBQVUsS0FBSyxRQUFRLElBQUksVUFBVSxDQUFDLFVBQVUsSUFBSSxDQUFDO1FBQUUsVUFBVSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUMsVUFBVSxDQUFBO0lBRWhJLE9BQU8sVUFBVSxDQUFBO0FBQ25CLENBQUM7QUFFRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUsK0JBQStCLENBQUMsYUFBYSxFQUFFLE1BQU07SUFDbkUsK0RBQStEO0lBQy9ELElBQUksZUFBZSxDQUFBO0lBRW5CLElBQUksQ0FBQztRQUNILGVBQWUsR0FBRyxhQUFhLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQTtJQUN2RCxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTSxDQUFDLGtFQUFrRTtJQUMzRSxDQUFDO0lBRUQsSUFBSSxDQUFDLGVBQWU7UUFBRSxPQUFNO0lBRTVCLE1BQU0sV0FBVyxHQUFHLGVBQWUsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQ2xFLE1BQU0sT0FBTyxHQUFHLEVBQUMsT0FBTyxFQUFFLHlCQUF5QixFQUFFLEdBQUcsTUFBTSxFQUFDLENBQUE7SUFFL0QsSUFBSSxDQUFDO1FBQ0gsZUFBZSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFDNUMsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLDBEQUEwRDtJQUM1RCxDQUFDO0lBRUQsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2pCLE9BQU8sQ0FBQyxLQUFLLENBQUMsc0NBQXNDLE1BQU0sQ0FBQyxLQUFLLFVBQVUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFNBQVMsTUFBTSxDQUFDLFdBQVcsZUFBZSxNQUFNLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFlBQVksTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyx1QkFBdUIsTUFBTSxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxhQUFhLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxvSEFBb0gsQ0FBQyxDQUFBO0lBQzlkLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbi8qKlxuICogRXZlbnQtZHJpdmVuIGFkdmlzb3J5LWxvY2sgZHVyYXRpb24gdGVsZW1ldHJ5IChTVEMtMjYxLCBwYXJlbnQgZXBpYyBTVEMtMjA5KS5cbiAqXG4gKiBBIGxvY2sgY29udm95IGlzIG9ubHkgZml4YWJsZSB3aGVuIGl0IGlzICphdHRyaWJ1dGFibGUqOiB3aGljaCBsb2NrIG5hbWUgd2FzXG4gKiBjb250ZW5kZWQsIG9uIHdoaWNoIGJhY2tlbmQgdGllciwgZm9yIGhvdyBsb25nLCBhbmQgd2hvIGhlbGQgaXQuIFRoZXNlIHJlcG9ydHNcbiAqIGZpcmUgb24gdGhlIGFjcXVpc2l0aW9uL3JlbGVhc2UgZXZlbnRzIHRoZW1zZWx2ZXMg4oCUIG5ldmVyIGZyb20gYSBwZXJpb2RpY1xuICogc2Nhbm5lciDigJQgc28gYSBjb250ZW5kZWQgbG9jayBpbiBwcm9kdWN0aW9uIHN1cmZhY2VzIG9uIHRoZSBmcmFtZXdvcmstZXJyb3JcbiAqIGNoYW5uZWwgd2l0aCB0aGUgaG9sZGVyIGlkZW50aXR5IGF2YWlsYWJsZSBvbiB0aGF0IHRpZXIgYXQgdGhhdCBtb21lbnQsXG4gKiB3aXRob3V0IFNTSCBmb3JlbnNpY3MuXG4gKlxuICogVGhyZWUgZXZlbnRzLCBlYWNoIHdpdGggaXRzIG93biB0aHJlc2hvbGQgKGFsbCBjb25maWd1cmFibGUgcGVyIGRhdGFiYXNlIHZpYVxuICogYGFkdmlzb3J5TG9ja1RlbGVtZXRyeWAsIHNlZSBgZG9jcy9hZHZpc29yeS1sb2Nrcy5tZGApOlxuICpcbiAqIC0gYGFkdmlzb3J5LWxvY2stc2xvdy1hY3F1aXJlYCDigJQgYW4gYWNxdWlyZSB3YWl0IGNvbXBsZXRlZCBzbG93ZXIgdGhhblxuICogICBgc2xvd0FjcXVpcmVNc2AgKGRlZmF1bHQgNTAwMCksIGluY2x1ZGluZyB0aGUgZXZlbnR1YWwgb3V0Y29tZSAoYGFjcXVpcmVkYFxuICogICBvciBgdGltZW91dGApLlxuICogLSBgYWR2aXNvcnktbG9jay1hY3F1aXJlLXRpbWVvdXRgIOKAlCBhIHdhaXQgZXhjZWVkZWQgaXRzIHRpbWVvdXQuIFRoZSByZXBvcnRcbiAqICAgY2FycmllcyB0aGUgaG9sZGVyIGlkZW50aXR5IGF2YWlsYWJsZSBvbiB0aGUgdGllciBhdCB0aGF0IG1vbWVudDogdGhlXG4gKiAgIGRyaXZlci1uYXRpdmUgdGllcnMgYXR0cmlidXRlIHRoZSBob2xkZXIgY29ubmVjdGlvbiAoTWFyaWFEQlxuICogICBgSVNfVVNFRF9MT0NLYCwgUG9zdGdyZVNRTCBgcGdfbG9ja3NgIGpvaW5lZCB0byBgcGdfc3RhdF9hY3Rpdml0eWAsIFNRTFxuICogICBTZXJ2ZXIgYHN5cy5kbV90cmFuX2xvY2tzYCByZXF1ZXN0IHNlc3Npb24sIFNRTGl0ZSBOb2RlIGZpbGUgdGllclxuICogICBgb3duZXIuanNvbmAgcGlkL2hvc3RuYW1lKTsgdGhlIHByb2Nlc3MtbG9jYWwgdGllciByZXBvcnRzIHRoZSBvd25pbmdcbiAqICAgZHJpdmVyJ3MgYGhvbGRlcklkYC5cbiAqIC0gYGFkdmlzb3J5LWxvY2stc2xvdy1ob2xkYCDigJQgYSBob2xkIGxhc3RlZCBsb25nZXIgdGhhbiBgc2xvd0hvbGRNc2BcbiAqICAgKGRlZmF1bHQgNjAwMDApLCBlbWl0dGVkIGF0IHJlbGVhc2UuXG4gKlxuICogUmVwb3J0cyBhcmUgZW1pdHRlZCBvbiBgY29uZmlndXJhdGlvbi5nZXRUZWxlbWV0cnlFdmVudHMoKWAgYXMgYHRlbGVtZXRyeWBcbiAqIHdpdGggYHtjb250ZXh0OiBcImFkdmlzb3J5LWxvY2stdGVsZW1ldHJ5XCIsIGV2ZW50LCBsb2NrTmFtZSwgYmFja2VuZFRpZXIsIC4uLn1gXG4gKiBwYXlsb2Fkcy5cbiAqXG4gKiBUaGVzZSBhcmUgbWVhc3VyZW1lbnRzLCBub3QgZmFpbHVyZXMsIHNvIHRoZXkgYXJlIGRlbGliZXJhdGVseSBrZXB0IG9mZiB0aGVcbiAqIGZyYW1ld29yay1lcnJvciBjaGFubmVsOiBhIGJ1ZyByZXBvcnRlciBzdWJzY3JpYmVkIHRvIGBmcmFtZXdvcmstZXJyb3JgIC9cbiAqIGBhbGwtZXJyb3JgIG11c3QgYmUgYWJsZSB0byBhc3N1bWUgZXZlcnkgcGF5bG9hZCBjYXJyaWVzIGEgdGhyb3duIHZhbHVlLCBhbmQgYVxuICogY29udGVudGlvbiByZXBvcnQgZGVsaXZlcmVkIHRoZXJlIGJlY2FtZSBvbmUgYnVnIHJlcG9ydCAocGx1cyBpdHMgc3ltYm9saWNhdGlvblxuICogYW5kIG5vdGlmaWNhdGlvbiB3b3JrKSBwZXIgZXZlbnQuXG4gKlxuICogSG9sZGVyIGxvb2t1cHMgYXJlIHN0cmljdGx5IGJlc3QtZWZmb3J0ICphZnRlciogdGhlIGFjcXVpc2l0aW9uIGFscmVhZHlcbiAqIHNldHRsZWQ6IGEgZmFpbGVkIGxvb2t1cCBuZXZlciBjaGFuZ2VzIHRoZSBhY3F1aXNpdGlvbiBvdXRjb21lIGFuZCBuZXZlclxuICogdGhyb3dzIHRvIHRoZSBjYWxsZXIuXG4gKi9cblxuLyoqXG4gKiBPbmUgYWR2aXNvcnktbG9jayB0ZWxlbWV0cnkgcmVwb3J0LlxuICogQHR5cGVkZWYge29iamVjdH0gQWR2aXNvcnlMb2NrVGVsZW1ldHJ5UmVwb3J0XG4gKiBAcHJvcGVydHkge1wiYWR2aXNvcnktbG9jay1zbG93LWFjcXVpcmVcIiB8IFwiYWR2aXNvcnktbG9jay1hY3F1aXJlLXRpbWVvdXRcIiB8IFwiYWR2aXNvcnktbG9jay1zbG93LWhvbGRcIn0gZXZlbnQgLSBXaGljaCBldmVudCBmaXJlZC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBsb2NrTmFtZSAtIFRoZSBjb250ZW5kZWQgYWR2aXNvcnktbG9jayBuYW1lLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IGJhY2tlbmRUaWVyIC0gVGllciB0aGF0IHNlcnZlZCAob3IgcmVmdXNlZCkgdGhlIGFjcXVpc2l0aW9uOiBgZHJpdmVyLW5hdGl2ZWAsIGBwcm9jZXNzLWxvY2FsYCwgb3IgYGZpbGVgLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGR1cmF0aW9uTXMgLSBNZWFzdXJlZCBkdXJhdGlvbiBvZiB0aGUgYWNxdWlyZSB3YWl0IChvciB0aGUgaG9sZCkuXG4gKiBAcHJvcGVydHkge1wiYWNxdWlyZWRcIiB8IFwidGltZW91dFwiIHwgbnVsbH0gb3V0Y29tZSAtIEZvciBhY3F1aXJlIGV2ZW50czogd2hldGhlciB0aGUgd2FpdCBldmVudHVhbGx5IGFjcXVpcmVkIHRoZSBsb2NrLiBOdWxsIGZvciBob2xkIHJlcG9ydHMuXG4gKiBAcHJvcGVydHkge251bWJlciB8IG51bGx9IHRpbWVvdXRNcyAtIFRoZSBlZmZlY3RpdmUgYWNxdWlyZSBib3VuZCBmb3IgYWNxdWlyZSBldmVudHMuIE51bGwgZm9yIGhvbGQgcmVwb3J0cyBvciBhbiB1bmJvdW5kZWQgd2FpdC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nIHwgbnVsbH0gaG9sZGVySWQgLSBQcm9jZXNzLWxvY2FsIGhvbGRlciBhdHRyaWJ1dGlvbiB3aGVuIHRoZSB0aWVyIGNhbiBuYW1lIGl0cyBsb2NhbCBob2xkZXIuXG4gKiBAcHJvcGVydHkge3N0cmluZyB8IG51bGx9IGhvbGRlckNvbm5lY3Rpb25JZCAtIERyaXZlci1uYXRpdmUgaG9sZGVyIGF0dHJpYnV0aW9uIGNhcHR1cmVkIGF0IHRoZSBldmVudCBtb21lbnQgKE1hcmlhREIgYElTX1VTRURfTE9DS2AgY29ubmVjdGlvbiBpZCwgUG9zdGdyZVNRTCBwaWQsIFNRTCBTZXJ2ZXIgc2Vzc2lvbiBpZCwgU1FMaXRlIGZpbGUgYHBpZEBob3N0bmFtZWApLlxuICogQHByb3BlcnR5IHtzdHJpbmcgfCBudWxsfSBob2xkZXJMb29rdXBFcnJvciAtIFNldCB3aGVuIHRoZSBiZXN0LWVmZm9ydCBob2xkZXIgbG9va3VwIGl0c2VsZiBmYWlsZWQ7IHRoZSBsb29rdXAgbmV2ZXIgYWZmZWN0cyB0aGUgYWNxdWlzaXRpb24uXG4gKi9cblxuLyoqXG4gKiBSZXNvbHZlZCBwZXItZGF0YWJhc2UgdGVsZW1ldHJ5IHRocmVzaG9sZHMuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBBZHZpc29yeUxvY2tUZWxlbWV0cnlUaHJlc2hvbGRzXG4gKiBAcHJvcGVydHkge251bWJlciB8IG51bGx9IHNsb3dBY3F1aXJlTXMgLSBSZXBvcnQgYW4gYWNxdWlyZSB3YWl0IHNsb3dlciB0aGFuIHRoaXM7IGBudWxsYCBkaXNhYmxlcyBzbG93LWFjcXVpcmUgcmVwb3J0cy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyIHwgbnVsbH0gc2xvd0hvbGRNcyAtIFJlcG9ydCBhIGhvbGQgbG9uZ2VyIHRoYW4gdGhpcyBhdCByZWxlYXNlOyBgbnVsbGAgZGlzYWJsZXMgaG9sZCByZXBvcnRzLlxuICovXG5cbi8qKiBGcmFtZXdvcmsgZGVmYXVsdDogcmVwb3J0IGFuIGFjcXVpcmUgd2FpdCB0aGF0IGNvbXBsZXRlZCBzbG93ZXIgdGhhbiB0aGlzLiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfQURWSVNPUllfTE9DS19TTE9XX0FDUVVJUkVfTVMgPSA1MDAwXG5cbi8qKiBGcmFtZXdvcmsgZGVmYXVsdDogcmVwb3J0IGEgaG9sZCB0aGF0IG91dGxpdmVzIHRoaXMgYXQgcmVsZWFzZS4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0FEVklTT1JZX0xPQ0tfU0xPV19IT0xEX01TID0gNjAgKiAxMDAwXG5cbi8qKlxuICogUmVzb2x2ZSB0aGUgdGVsZW1ldHJ5IHRocmVzaG9sZHMgZm9yIG9uZSBkYXRhYmFzZSBjb25maWd1cmF0aW9uLlxuICogQW4gZXhwbGljaXQgcGVyLWRhdGFiYXNlIGBhZHZpc29yeUxvY2tUZWxlbWV0cnlgIHZhbHVlIHdpbnM7IGBudWxsYCBvcHRzIG91dFxuICogb2YgdGhhdCByZXBvcnQ7IG9ubHkgd2hlbiBuZWl0aGVyIGlzIGNvbmZpZ3VyZWQgZG9lcyB0aGUgZnJhbWV3b3JrIGRlZmF1bHRcbiAqIGFwcGx5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkRhdGFiYXNlQ29uZmlndXJhdGlvblR5cGV9IGFyZ3MgLSBEYXRhYmFzZSBjb25maWd1cmF0aW9uIGFyZ3MuXG4gKiBAcmV0dXJucyB7QWR2aXNvcnlMb2NrVGVsZW1ldHJ5VGhyZXNob2xkc30gLSBSZXNvbHZlZCB0aHJlc2hvbGRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWR2aXNvcnlMb2NrVGVsZW1ldHJ5VGhyZXNob2xkcyhhcmdzKSB7XG4gIGNvbnN0IGNvbmZpZ3VyZWQgPSBhcmdzPy5hZHZpc29yeUxvY2tUZWxlbWV0cnlcbiAgLyoqIEB0eXBlIHtBZHZpc29yeUxvY2tUZWxlbWV0cnlUaHJlc2hvbGRzfSAqL1xuICBjb25zdCB0aHJlc2hvbGRzID0ge1xuICAgIHNsb3dBY3F1aXJlTXM6IERFRkFVTFRfQURWSVNPUllfTE9DS19TTE9XX0FDUVVJUkVfTVMsXG4gICAgc2xvd0hvbGRNczogREVGQVVMVF9BRFZJU09SWV9MT0NLX1NMT1dfSE9MRF9NU1xuICB9XG5cbiAgaWYgKGNvbmZpZ3VyZWQ/LnNsb3dBY3F1aXJlTXMgPT09IG51bGwpIHRocmVzaG9sZHMuc2xvd0FjcXVpcmVNcyA9IG51bGxcbiAgZWxzZSBpZiAodHlwZW9mIGNvbmZpZ3VyZWQ/LnNsb3dBY3F1aXJlTXMgPT09IFwibnVtYmVyXCIgJiYgY29uZmlndXJlZC5zbG93QWNxdWlyZU1zID49IDApIHRocmVzaG9sZHMuc2xvd0FjcXVpcmVNcyA9IGNvbmZpZ3VyZWQuc2xvd0FjcXVpcmVNc1xuXG4gIGlmIChjb25maWd1cmVkPy5zbG93SG9sZE1zID09PSBudWxsKSB0aHJlc2hvbGRzLnNsb3dIb2xkTXMgPSBudWxsXG4gIGVsc2UgaWYgKHR5cGVvZiBjb25maWd1cmVkPy5zbG93SG9sZE1zID09PSBcIm51bWJlclwiICYmIGNvbmZpZ3VyZWQuc2xvd0hvbGRNcyA+PSAwKSB0aHJlc2hvbGRzLnNsb3dIb2xkTXMgPSBjb25maWd1cmVkLnNsb3dIb2xkTXNcblxuICByZXR1cm4gdGhyZXNob2xkc1xufVxuXG4vKipcbiAqIEVtaXQgb25lIHRlbGVtZXRyeSByZXBvcnQgb24gdGhlIGZyYW1ld29yay10ZWxlbWV0cnkgY2hhbm5lbC5cbiAqXG4gKiBXaGVuIG5vIGB0ZWxlbWV0cnlgIGxpc3RlbmVyIGlzIGF0dGFjaGVkLCBhIG9uZS1saW5lIHN1bW1hcnkgZ29lcyB0byBgc3RkZXJyYFxuICogc28gYSBjb252b3kgaXMgbmV2ZXIgY29tcGxldGVseSBzaWxlbnQuIEEgbGlzdGVuZXIgZmFpbHVyZSBjYW4gbmV2ZXIgYnJlYWtcbiAqIGxvY2sgaGFuZGxpbmcsIHNvIGVtaXNzaW9ucyBhcmUgZ3VhcmRlZC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBjb25maWd1cmF0aW9uIC0gQ29uZmlndXJhdGlvbiBpbnN0YW5jZSBvd25pbmcgdGhlIHRlbGVtZXRyeSBjaGFubmVsLlxuICogQHBhcmFtIHtBZHZpc29yeUxvY2tUZWxlbWV0cnlSZXBvcnR9IHJlcG9ydCAtIFRoZSByZXBvcnQgcGF5bG9hZC5cbiAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVtaXRBZHZpc29yeUxvY2tUZWxlbWV0cnlSZXBvcnQoY29uZmlndXJhdGlvbiwgcmVwb3J0KSB7XG4gIC8qKiBAdHlwZSB7aW1wb3J0KFwiZXZlbnRlbWl0dGVyM1wiKS5FdmVudEVtaXR0ZXIgfCB1bmRlZmluZWR9ICovXG4gIGxldCB0ZWxlbWV0cnlFdmVudHNcblxuICB0cnkge1xuICAgIHRlbGVtZXRyeUV2ZW50cyA9IGNvbmZpZ3VyYXRpb24/LmdldFRlbGVtZXRyeUV2ZW50cygpXG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiAvLyBObyBjb25maWd1cmF0aW9uIHRvIHJlcG9ydCB0aHJvdWdoIOKAlCBuZXZlciBicmVhayBsb2NrIGhhbmRsaW5nLlxuICB9XG5cbiAgaWYgKCF0ZWxlbWV0cnlFdmVudHMpIHJldHVyblxuXG4gIGNvbnN0IGhhc0xpc3RlbmVyID0gdGVsZW1ldHJ5RXZlbnRzLmxpc3RlbmVyQ291bnQoXCJ0ZWxlbWV0cnlcIikgPiAwXG4gIGNvbnN0IHBheWxvYWQgPSB7Y29udGV4dDogXCJhZHZpc29yeS1sb2NrLXRlbGVtZXRyeVwiLCAuLi5yZXBvcnR9XG5cbiAgdHJ5IHtcbiAgICB0ZWxlbWV0cnlFdmVudHMuZW1pdChcInRlbGVtZXRyeVwiLCBwYXlsb2FkKVxuICB9IGNhdGNoIHtcbiAgICAvLyBBIGJyb2tlbiBsaXN0ZW5lciBtdXN0IG5ldmVyIHN1cmZhY2UgYXMgYSBsb2NrIGZhaWx1cmUuXG4gIH1cblxuICBpZiAoIWhhc0xpc3RlbmVyKSB7XG4gICAgY29uc29sZS5lcnJvcihgW3ZlbG9jaW91cyBhZHZpc29yeS1sb2NrLXRlbGVtZXRyeSAke3JlcG9ydC5ldmVudH1dIGxvY2s9JHtKU09OLnN0cmluZ2lmeShyZXBvcnQubG9ja05hbWUpfSB0aWVyPSR7cmVwb3J0LmJhY2tlbmRUaWVyfSBkdXJhdGlvbk1zPSR7cmVwb3J0LmR1cmF0aW9uTXN9JHtyZXBvcnQub3V0Y29tZSA/IGAgb3V0Y29tZT0ke3JlcG9ydC5vdXRjb21lfWAgOiBcIlwifSR7cmVwb3J0LmhvbGRlckNvbm5lY3Rpb25JZCA/IGAgaG9sZGVyQ29ubmVjdGlvbklkPSR7cmVwb3J0LmhvbGRlckNvbm5lY3Rpb25JZH1gIDogXCJcIn0ke3JlcG9ydC5ob2xkZXJJZCA/IGAgaG9sZGVySWQ9JHtyZXBvcnQuaG9sZGVySWR9YCA6IFwiXCJ9IOKAlCBzdWJzY3JpYmUgdmlhIGNvbmZpZ3VyYXRpb24uZ2V0VGVsZW1ldHJ5RXZlbnRzKCkub24oXCJ0ZWxlbWV0cnlcIiwg4oCmKSB0byByb3V0ZSB0aGVzZSBtZWFzdXJlbWVudHMgdG8geW91ciBtZXRyaWNzYClcbiAgfVxufVxuIl19
123
+ /**
124
+ * Reports one acquisition served below the lock name's preferred tier
125
+ * (design §3): the caller wanted the lock server and got the database, so the
126
+ * downgrade must be visible without being mistaken for a failure. Fallbacks are
127
+ * measurements, not errors, so they stay off `framework-error` and its bug
128
+ * reporters (same contract as the duration telemetry).
129
+ * @param {import("../configuration.js").default} configuration - Owning configuration.
130
+ * @param {{lockName: string, preferredTier: string, reason: string, servedBy: string}} report - Fallback details.
131
+ * @returns {void}
132
+ */
133
+ export function emitAdvisoryLockFallbackReport(configuration, report) {
134
+ /** @type {import("eventemitter3").EventEmitter | undefined} */
135
+ let telemetryEvents;
136
+ try {
137
+ telemetryEvents = configuration?.getTelemetryEvents();
138
+ }
139
+ catch {
140
+ return; // No configuration to report through — never break lock handling.
141
+ }
142
+ if (!telemetryEvents)
143
+ return;
144
+ const payload = { context: "advisory-lock-fallback", ...report };
145
+ const hasListener = telemetryEvents.listenerCount("telemetry") > 0;
146
+ try {
147
+ telemetryEvents.emit("telemetry", payload);
148
+ }
149
+ catch {
150
+ // A broken listener must never surface as a lock failure.
151
+ }
152
+ if (!hasListener) {
153
+ console.error(`[velocious advisory-lock-fallback] lock=${JSON.stringify(report.lockName)} preferredTier=${report.preferredTier} servedBy=${report.servedBy} reason=${report.reason}`);
154
+ }
155
+ }
156
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWR2aXNvcnktbG9jay10ZWxlbWV0cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGF0YWJhc2UvYWR2aXNvcnktbG9jay10ZWxlbWV0cnkuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Q0c7QUFFSDs7Ozs7Ozs7Ozs7O0dBWUc7QUFFSDs7Ozs7R0FLRztBQUVILGlGQUFpRjtBQUNqRixNQUFNLENBQUMsTUFBTSxxQ0FBcUMsR0FBRyxJQUFJLENBQUE7QUFFekQsc0VBQXNFO0FBQ3RFLE1BQU0sQ0FBQyxNQUFNLGtDQUFrQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUE7QUFFM0Q7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSwrQkFBK0IsQ0FBQyxJQUFJO0lBQ2xELE1BQU0sVUFBVSxHQUFHLElBQUksRUFBRSxxQkFBcUIsQ0FBQTtJQUM5Qyw4Q0FBOEM7SUFDOUMsTUFBTSxVQUFVLEdBQUc7UUFDakIsYUFBYSxFQUFFLHFDQUFxQztRQUNwRCxVQUFVLEVBQUUsa0NBQWtDO0tBQy9DLENBQUE7SUFFRCxJQUFJLFVBQVUsRUFBRSxhQUFhLEtBQUssSUFBSTtRQUFFLFVBQVUsQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFBO1NBQ2xFLElBQUksT0FBTyxVQUFVLEVBQUUsYUFBYSxLQUFLLFFBQVEsSUFBSSxVQUFVLENBQUMsYUFBYSxJQUFJLENBQUM7UUFBRSxVQUFVLENBQUMsYUFBYSxHQUFHLFVBQVUsQ0FBQyxhQUFhLENBQUE7SUFFNUksSUFBSSxVQUFVLEVBQUUsVUFBVSxLQUFLLElBQUk7UUFBRSxVQUFVLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQTtTQUM1RCxJQUFJLE9BQU8sVUFBVSxFQUFFLFVBQVUsS0FBSyxRQUFRLElBQUksVUFBVSxDQUFDLFVBQVUsSUFBSSxDQUFDO1FBQUUsVUFBVSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUMsVUFBVSxDQUFBO0lBRWhJLE9BQU8sVUFBVSxDQUFBO0FBQ25CLENBQUM7QUFFRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUsK0JBQStCLENBQUMsYUFBYSxFQUFFLE1BQU07SUFDbkUsK0RBQStEO0lBQy9ELElBQUksZUFBZSxDQUFBO0lBRW5CLElBQUksQ0FBQztRQUNILGVBQWUsR0FBRyxhQUFhLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQTtJQUN2RCxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTSxDQUFDLGtFQUFrRTtJQUMzRSxDQUFDO0lBRUQsSUFBSSxDQUFDLGVBQWU7UUFBRSxPQUFNO0lBRTVCLE1BQU0sV0FBVyxHQUFHLGVBQWUsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQ2xFLE1BQU0sT0FBTyxHQUFHLEVBQUMsT0FBTyxFQUFFLHlCQUF5QixFQUFFLEdBQUcsTUFBTSxFQUFDLENBQUE7SUFFL0QsSUFBSSxDQUFDO1FBQ0gsZUFBZSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFDNUMsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLDBEQUEwRDtJQUM1RCxDQUFDO0lBRUQsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2pCLE9BQU8sQ0FBQyxLQUFLLENBQUMsc0NBQXNDLE1BQU0sQ0FBQyxLQUFLLFVBQVUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFNBQVMsTUFBTSxDQUFDLFdBQVcsZUFBZSxNQUFNLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFlBQVksTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyx1QkFBdUIsTUFBTSxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxhQUFhLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxvSEFBb0gsQ0FBQyxDQUFBO0lBQzlkLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxVQUFVLDhCQUE4QixDQUFDLGFBQWEsRUFBRSxNQUFNO0lBQ2xFLCtEQUErRDtJQUMvRCxJQUFJLGVBQWUsQ0FBQTtJQUVuQixJQUFJLENBQUM7UUFDSCxlQUFlLEdBQUcsYUFBYSxFQUFFLGtCQUFrQixFQUFFLENBQUE7SUFDdkQsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU0sQ0FBQyxrRUFBa0U7SUFDM0UsQ0FBQztJQUVELElBQUksQ0FBQyxlQUFlO1FBQUUsT0FBTTtJQUU1QixNQUFNLE9BQU8sR0FBRyxFQUFDLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxHQUFHLE1BQU0sRUFBQyxDQUFBO0lBQzlELE1BQU0sV0FBVyxHQUFHLGVBQWUsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBRWxFLElBQUksQ0FBQztRQUNILGVBQWUsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBQzVDLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCwwREFBMEQ7SUFDNUQsQ0FBQztJQUVELElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNqQixPQUFPLENBQUMsS0FBSyxDQUFDLDJDQUEyQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsa0JBQWtCLE1BQU0sQ0FBQyxhQUFhLGFBQWEsTUFBTSxDQUFDLFFBQVEsV0FBVyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQTtJQUN2TCxDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG4vKipcbiAqIEV2ZW50LWRyaXZlbiBhZHZpc29yeS1sb2NrIGR1cmF0aW9uIHRlbGVtZXRyeSAoU1RDLTI2MSwgcGFyZW50IGVwaWMgU1RDLTIwOSkuXG4gKlxuICogQSBsb2NrIGNvbnZveSBpcyBvbmx5IGZpeGFibGUgd2hlbiBpdCBpcyAqYXR0cmlidXRhYmxlKjogd2hpY2ggbG9jayBuYW1lIHdhc1xuICogY29udGVuZGVkLCBvbiB3aGljaCBiYWNrZW5kIHRpZXIsIGZvciBob3cgbG9uZywgYW5kIHdobyBoZWxkIGl0LiBUaGVzZSByZXBvcnRzXG4gKiBmaXJlIG9uIHRoZSBhY3F1aXNpdGlvbi9yZWxlYXNlIGV2ZW50cyB0aGVtc2VsdmVzIOKAlCBuZXZlciBmcm9tIGEgcGVyaW9kaWNcbiAqIHNjYW5uZXIg4oCUIHNvIGEgY29udGVuZGVkIGxvY2sgaW4gcHJvZHVjdGlvbiBzdXJmYWNlcyBvbiB0aGUgdGVsZW1ldHJ5IGNoYW5uZWxcbiAqIHdpdGggdGhlIGhvbGRlciBpZGVudGl0eSBhdmFpbGFibGUgb24gdGhhdCB0aWVyIGF0IHRoYXQgbW9tZW50LCB3aXRob3V0IFNTSFxuICogZm9yZW5zaWNzLlxuICpcbiAqIFRocmVlIGV2ZW50cywgZWFjaCB3aXRoIGl0cyBvd24gdGhyZXNob2xkIChhbGwgY29uZmlndXJhYmxlIHBlciBkYXRhYmFzZSB2aWFcbiAqIGBhZHZpc29yeUxvY2tUZWxlbWV0cnlgLCBzZWUgYGRvY3MvYWR2aXNvcnktbG9ja3MubWRgKTpcbiAqXG4gKiAtIGBhZHZpc29yeS1sb2NrLXNsb3ctYWNxdWlyZWAg4oCUIGFuIGFjcXVpcmUgd2FpdCBjb21wbGV0ZWQgc2xvd2VyIHRoYW5cbiAqICAgYHNsb3dBY3F1aXJlTXNgIChkZWZhdWx0IDUwMDApLCBpbmNsdWRpbmcgdGhlIGV2ZW50dWFsIG91dGNvbWUgKGBhY3F1aXJlZGBcbiAqICAgb3IgYHRpbWVvdXRgKS5cbiAqIC0gYGFkdmlzb3J5LWxvY2stYWNxdWlyZS10aW1lb3V0YCDigJQgYSB3YWl0IGV4Y2VlZGVkIGl0cyB0aW1lb3V0LiBUaGUgcmVwb3J0XG4gKiAgIGNhcnJpZXMgdGhlIGhvbGRlciBpZGVudGl0eSBhdmFpbGFibGUgb24gdGhlIHRpZXIgYXQgdGhhdCBtb21lbnQ6IHRoZVxuICogICBkcml2ZXItbmF0aXZlIHRpZXJzIGF0dHJpYnV0ZSB0aGUgaG9sZGVyIGNvbm5lY3Rpb24gKE1hcmlhREJcbiAqICAgYElTX1VTRURfTE9DS2AsIFBvc3RncmVTUUwgYHBnX2xvY2tzYCBqb2luZWQgdG8gYHBnX3N0YXRfYWN0aXZpdHlgLCBTUUxcbiAqICAgU2VydmVyIGBzeXMuZG1fdHJhbl9sb2Nrc2AgcmVxdWVzdCBzZXNzaW9uLCBTUUxpdGUgTm9kZSBmaWxlIHRpZXJcbiAqICAgYG93bmVyLmpzb25gIHBpZC9ob3N0bmFtZSk7IHRoZSBwcm9jZXNzLWxvY2FsIHRpZXIgcmVwb3J0cyB0aGUgb3duaW5nXG4gKiAgIGRyaXZlcidzIGBob2xkZXJJZGAuXG4gKiAtIGBhZHZpc29yeS1sb2NrLXNsb3ctaG9sZGAg4oCUIGEgaG9sZCBsYXN0ZWQgbG9uZ2VyIHRoYW4gYHNsb3dIb2xkTXNgXG4gKiAgIChkZWZhdWx0IDYwMDAwKSwgZW1pdHRlZCBhdCByZWxlYXNlLlxuICpcbiAqIFJlcG9ydHMgYXJlIGVtaXR0ZWQgb24gYGNvbmZpZ3VyYXRpb24uZ2V0VGVsZW1ldHJ5RXZlbnRzKClgIGFzIGB0ZWxlbWV0cnlgXG4gKiB3aXRoIGB7Y29udGV4dDogXCJhZHZpc29yeS1sb2NrLXRlbGVtZXRyeVwiLCBldmVudCwgbG9ja05hbWUsIGJhY2tlbmRUaWVyLCAuLi59YFxuICogcGF5bG9hZHMuXG4gKlxuICogVGhlc2UgYXJlIG1lYXN1cmVtZW50cywgbm90IGZhaWx1cmVzLCBzbyB0aGV5IGFyZSBkZWxpYmVyYXRlbHkga2VwdCBvZmYgdGhlXG4gKiBmcmFtZXdvcmstZXJyb3IgY2hhbm5lbDogYSBidWcgcmVwb3J0ZXIgc3Vic2NyaWJlZCB0byBgZnJhbWV3b3JrLWVycm9yYCAvXG4gKiBgYWxsLWVycm9yYCBtdXN0IGJlIGFibGUgdG8gYXNzdW1lIGV2ZXJ5IHBheWxvYWQgY2FycmllcyBhIHRocm93biB2YWx1ZSwgYW5kIGFcbiAqIGNvbnRlbnRpb24gcmVwb3J0IGRlbGl2ZXJlZCB0aGVyZSBiZWNhbWUgb25lIGJ1ZyByZXBvcnQgKHBsdXMgaXRzIHN5bWJvbGljYXRpb25cbiAqIGFuZCBub3RpZmljYXRpb24gd29yaykgcGVyIGV2ZW50LlxuICpcbiAqIEhvbGRlciBsb29rdXBzIGFyZSBzdHJpY3RseSBiZXN0LWVmZm9ydCAqYWZ0ZXIqIHRoZSBhY3F1aXNpdGlvbiBhbHJlYWR5XG4gKiBzZXR0bGVkOiBhIGZhaWxlZCBsb29rdXAgbmV2ZXIgY2hhbmdlcyB0aGUgYWNxdWlzaXRpb24gb3V0Y29tZSBhbmQgbmV2ZXJcbiAqIHRocm93cyB0byB0aGUgY2FsbGVyLlxuICovXG5cbi8qKlxuICogT25lIGFkdmlzb3J5LWxvY2sgdGVsZW1ldHJ5IHJlcG9ydC5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IEFkdmlzb3J5TG9ja1RlbGVtZXRyeVJlcG9ydFxuICogQHByb3BlcnR5IHtcImFkdmlzb3J5LWxvY2stc2xvdy1hY3F1aXJlXCIgfCBcImFkdmlzb3J5LWxvY2stYWNxdWlyZS10aW1lb3V0XCIgfCBcImFkdmlzb3J5LWxvY2stc2xvdy1ob2xkXCJ9IGV2ZW50IC0gV2hpY2ggZXZlbnQgZmlyZWQuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gbG9ja05hbWUgLSBUaGUgY29udGVuZGVkIGFkdmlzb3J5LWxvY2sgbmFtZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBiYWNrZW5kVGllciAtIFRpZXIgdGhhdCBzZXJ2ZWQgKG9yIHJlZnVzZWQpIHRoZSBhY3F1aXNpdGlvbjogYGRyaXZlci1uYXRpdmVgLCBgcHJvY2Vzcy1sb2NhbGAsIG9yIGBmaWxlYC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBkdXJhdGlvbk1zIC0gTWVhc3VyZWQgZHVyYXRpb24gb2YgdGhlIGFjcXVpcmUgd2FpdCAob3IgdGhlIGhvbGQpLlxuICogQHByb3BlcnR5IHtcImFjcXVpcmVkXCIgfCBcInRpbWVvdXRcIiB8IG51bGx9IG91dGNvbWUgLSBGb3IgYWNxdWlyZSBldmVudHM6IHdoZXRoZXIgdGhlIHdhaXQgZXZlbnR1YWxseSBhY3F1aXJlZCB0aGUgbG9jay4gTnVsbCBmb3IgaG9sZCByZXBvcnRzLlxuICogQHByb3BlcnR5IHtudW1iZXIgfCBudWxsfSB0aW1lb3V0TXMgLSBUaGUgZWZmZWN0aXZlIGFjcXVpcmUgYm91bmQgZm9yIGFjcXVpcmUgZXZlbnRzLiBOdWxsIGZvciBob2xkIHJlcG9ydHMgb3IgYW4gdW5ib3VuZGVkIHdhaXQuXG4gKiBAcHJvcGVydHkge3N0cmluZyB8IG51bGx9IGhvbGRlcklkIC0gUHJvY2Vzcy1sb2NhbCBob2xkZXIgYXR0cmlidXRpb24gd2hlbiB0aGUgdGllciBjYW4gbmFtZSBpdHMgbG9jYWwgaG9sZGVyLlxuICogQHByb3BlcnR5IHtzdHJpbmcgfCBudWxsfSBob2xkZXJDb25uZWN0aW9uSWQgLSBEcml2ZXItbmF0aXZlIGhvbGRlciBhdHRyaWJ1dGlvbiBjYXB0dXJlZCBhdCB0aGUgZXZlbnQgbW9tZW50IChNYXJpYURCIGBJU19VU0VEX0xPQ0tgIGNvbm5lY3Rpb24gaWQsIFBvc3RncmVTUUwgcGlkLCBTUUwgU2VydmVyIHNlc3Npb24gaWQsIFNRTGl0ZSBmaWxlIGBwaWRAaG9zdG5hbWVgKS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nIHwgbnVsbH0gaG9sZGVyTG9va3VwRXJyb3IgLSBTZXQgd2hlbiB0aGUgYmVzdC1lZmZvcnQgaG9sZGVyIGxvb2t1cCBpdHNlbGYgZmFpbGVkOyB0aGUgbG9va3VwIG5ldmVyIGFmZmVjdHMgdGhlIGFjcXVpc2l0aW9uLlxuICovXG5cbi8qKlxuICogUmVzb2x2ZWQgcGVyLWRhdGFiYXNlIHRlbGVtZXRyeSB0aHJlc2hvbGRzLlxuICogQHR5cGVkZWYge29iamVjdH0gQWR2aXNvcnlMb2NrVGVsZW1ldHJ5VGhyZXNob2xkc1xuICogQHByb3BlcnR5IHtudW1iZXIgfCBudWxsfSBzbG93QWNxdWlyZU1zIC0gUmVwb3J0IGFuIGFjcXVpcmUgd2FpdCBzbG93ZXIgdGhhbiB0aGlzOyBgbnVsbGAgZGlzYWJsZXMgc2xvdy1hY3F1aXJlIHJlcG9ydHMuXG4gKiBAcHJvcGVydHkge251bWJlciB8IG51bGx9IHNsb3dIb2xkTXMgLSBSZXBvcnQgYSBob2xkIGxvbmdlciB0aGFuIHRoaXMgYXQgcmVsZWFzZTsgYG51bGxgIGRpc2FibGVzIGhvbGQgcmVwb3J0cy5cbiAqL1xuXG4vKiogRnJhbWV3b3JrIGRlZmF1bHQ6IHJlcG9ydCBhbiBhY3F1aXJlIHdhaXQgdGhhdCBjb21wbGV0ZWQgc2xvd2VyIHRoYW4gdGhpcy4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0FEVklTT1JZX0xPQ0tfU0xPV19BQ1FVSVJFX01TID0gNTAwMFxuXG4vKiogRnJhbWV3b3JrIGRlZmF1bHQ6IHJlcG9ydCBhIGhvbGQgdGhhdCBvdXRsaXZlcyB0aGlzIGF0IHJlbGVhc2UuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9BRFZJU09SWV9MT0NLX1NMT1dfSE9MRF9NUyA9IDYwICogMTAwMFxuXG4vKipcbiAqIFJlc29sdmUgdGhlIHRlbGVtZXRyeSB0aHJlc2hvbGRzIGZvciBvbmUgZGF0YWJhc2UgY29uZmlndXJhdGlvbi5cbiAqIEFuIGV4cGxpY2l0IHBlci1kYXRhYmFzZSBgYWR2aXNvcnlMb2NrVGVsZW1ldHJ5YCB2YWx1ZSB3aW5zOyBgbnVsbGAgb3B0cyBvdXRcbiAqIG9mIHRoYXQgcmVwb3J0OyBvbmx5IHdoZW4gbmVpdGhlciBpcyBjb25maWd1cmVkIGRvZXMgdGhlIGZyYW1ld29yayBkZWZhdWx0XG4gKiBhcHBseS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5EYXRhYmFzZUNvbmZpZ3VyYXRpb25UeXBlfSBhcmdzIC0gRGF0YWJhc2UgY29uZmlndXJhdGlvbiBhcmdzLlxuICogQHJldHVybnMge0Fkdmlzb3J5TG9ja1RlbGVtZXRyeVRocmVzaG9sZHN9IC0gUmVzb2x2ZWQgdGhyZXNob2xkcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkdmlzb3J5TG9ja1RlbGVtZXRyeVRocmVzaG9sZHMoYXJncykge1xuICBjb25zdCBjb25maWd1cmVkID0gYXJncz8uYWR2aXNvcnlMb2NrVGVsZW1ldHJ5XG4gIC8qKiBAdHlwZSB7QWR2aXNvcnlMb2NrVGVsZW1ldHJ5VGhyZXNob2xkc30gKi9cbiAgY29uc3QgdGhyZXNob2xkcyA9IHtcbiAgICBzbG93QWNxdWlyZU1zOiBERUZBVUxUX0FEVklTT1JZX0xPQ0tfU0xPV19BQ1FVSVJFX01TLFxuICAgIHNsb3dIb2xkTXM6IERFRkFVTFRfQURWSVNPUllfTE9DS19TTE9XX0hPTERfTVNcbiAgfVxuXG4gIGlmIChjb25maWd1cmVkPy5zbG93QWNxdWlyZU1zID09PSBudWxsKSB0aHJlc2hvbGRzLnNsb3dBY3F1aXJlTXMgPSBudWxsXG4gIGVsc2UgaWYgKHR5cGVvZiBjb25maWd1cmVkPy5zbG93QWNxdWlyZU1zID09PSBcIm51bWJlclwiICYmIGNvbmZpZ3VyZWQuc2xvd0FjcXVpcmVNcyA+PSAwKSB0aHJlc2hvbGRzLnNsb3dBY3F1aXJlTXMgPSBjb25maWd1cmVkLnNsb3dBY3F1aXJlTXNcblxuICBpZiAoY29uZmlndXJlZD8uc2xvd0hvbGRNcyA9PT0gbnVsbCkgdGhyZXNob2xkcy5zbG93SG9sZE1zID0gbnVsbFxuICBlbHNlIGlmICh0eXBlb2YgY29uZmlndXJlZD8uc2xvd0hvbGRNcyA9PT0gXCJudW1iZXJcIiAmJiBjb25maWd1cmVkLnNsb3dIb2xkTXMgPj0gMCkgdGhyZXNob2xkcy5zbG93SG9sZE1zID0gY29uZmlndXJlZC5zbG93SG9sZE1zXG5cbiAgcmV0dXJuIHRocmVzaG9sZHNcbn1cblxuLyoqXG4gKiBFbWl0IG9uZSB0ZWxlbWV0cnkgcmVwb3J0IG9uIHRoZSBmcmFtZXdvcmstdGVsZW1ldHJ5IGNoYW5uZWwuXG4gKlxuICogV2hlbiBubyBgdGVsZW1ldHJ5YCBsaXN0ZW5lciBpcyBhdHRhY2hlZCwgYSBvbmUtbGluZSBzdW1tYXJ5IGdvZXMgdG8gYHN0ZGVycmBcbiAqIHNvIGEgY29udm95IGlzIG5ldmVyIGNvbXBsZXRlbHkgc2lsZW50LiBBIGxpc3RlbmVyIGZhaWx1cmUgY2FuIG5ldmVyIGJyZWFrXG4gKiBsb2NrIGhhbmRsaW5nLCBzbyBlbWlzc2lvbnMgYXJlIGd1YXJkZWQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gY29uZmlndXJhdGlvbiAtIENvbmZpZ3VyYXRpb24gaW5zdGFuY2Ugb3duaW5nIHRoZSB0ZWxlbWV0cnkgY2hhbm5lbC5cbiAqIEBwYXJhbSB7QWR2aXNvcnlMb2NrVGVsZW1ldHJ5UmVwb3J0fSByZXBvcnQgLSBUaGUgcmVwb3J0IHBheWxvYWQuXG4gKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbWl0QWR2aXNvcnlMb2NrVGVsZW1ldHJ5UmVwb3J0KGNvbmZpZ3VyYXRpb24sIHJlcG9ydCkge1xuICAvKiogQHR5cGUge2ltcG9ydChcImV2ZW50ZW1pdHRlcjNcIikuRXZlbnRFbWl0dGVyIHwgdW5kZWZpbmVkfSAqL1xuICBsZXQgdGVsZW1ldHJ5RXZlbnRzXG5cbiAgdHJ5IHtcbiAgICB0ZWxlbWV0cnlFdmVudHMgPSBjb25maWd1cmF0aW9uPy5nZXRUZWxlbWV0cnlFdmVudHMoKVxuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gLy8gTm8gY29uZmlndXJhdGlvbiB0byByZXBvcnQgdGhyb3VnaCDigJQgbmV2ZXIgYnJlYWsgbG9jayBoYW5kbGluZy5cbiAgfVxuXG4gIGlmICghdGVsZW1ldHJ5RXZlbnRzKSByZXR1cm5cblxuICBjb25zdCBoYXNMaXN0ZW5lciA9IHRlbGVtZXRyeUV2ZW50cy5saXN0ZW5lckNvdW50KFwidGVsZW1ldHJ5XCIpID4gMFxuICBjb25zdCBwYXlsb2FkID0ge2NvbnRleHQ6IFwiYWR2aXNvcnktbG9jay10ZWxlbWV0cnlcIiwgLi4ucmVwb3J0fVxuXG4gIHRyeSB7XG4gICAgdGVsZW1ldHJ5RXZlbnRzLmVtaXQoXCJ0ZWxlbWV0cnlcIiwgcGF5bG9hZClcbiAgfSBjYXRjaCB7XG4gICAgLy8gQSBicm9rZW4gbGlzdGVuZXIgbXVzdCBuZXZlciBzdXJmYWNlIGFzIGEgbG9jayBmYWlsdXJlLlxuICB9XG5cbiAgaWYgKCFoYXNMaXN0ZW5lcikge1xuICAgIGNvbnNvbGUuZXJyb3IoYFt2ZWxvY2lvdXMgYWR2aXNvcnktbG9jay10ZWxlbWV0cnkgJHtyZXBvcnQuZXZlbnR9XSBsb2NrPSR7SlNPTi5zdHJpbmdpZnkocmVwb3J0LmxvY2tOYW1lKX0gdGllcj0ke3JlcG9ydC5iYWNrZW5kVGllcn0gZHVyYXRpb25Ncz0ke3JlcG9ydC5kdXJhdGlvbk1zfSR7cmVwb3J0Lm91dGNvbWUgPyBgIG91dGNvbWU9JHtyZXBvcnQub3V0Y29tZX1gIDogXCJcIn0ke3JlcG9ydC5ob2xkZXJDb25uZWN0aW9uSWQgPyBgIGhvbGRlckNvbm5lY3Rpb25JZD0ke3JlcG9ydC5ob2xkZXJDb25uZWN0aW9uSWR9YCA6IFwiXCJ9JHtyZXBvcnQuaG9sZGVySWQgPyBgIGhvbGRlcklkPSR7cmVwb3J0LmhvbGRlcklkfWAgOiBcIlwifSDigJQgc3Vic2NyaWJlIHZpYSBjb25maWd1cmF0aW9uLmdldFRlbGVtZXRyeUV2ZW50cygpLm9uKFwidGVsZW1ldHJ5XCIsIOKApikgdG8gcm91dGUgdGhlc2UgbWVhc3VyZW1lbnRzIHRvIHlvdXIgbWV0cmljc2ApXG4gIH1cbn1cblxuLyoqXG4gKiBSZXBvcnRzIG9uZSBhY3F1aXNpdGlvbiBzZXJ2ZWQgYmVsb3cgdGhlIGxvY2sgbmFtZSdzIHByZWZlcnJlZCB0aWVyXG4gKiAoZGVzaWduIMKnMyk6IHRoZSBjYWxsZXIgd2FudGVkIHRoZSBsb2NrIHNlcnZlciBhbmQgZ290IHRoZSBkYXRhYmFzZSwgc28gdGhlXG4gKiBkb3duZ3JhZGUgbXVzdCBiZSB2aXNpYmxlIHdpdGhvdXQgYmVpbmcgbWlzdGFrZW4gZm9yIGEgZmFpbHVyZS4gRmFsbGJhY2tzIGFyZVxuICogbWVhc3VyZW1lbnRzLCBub3QgZXJyb3JzLCBzbyB0aGV5IHN0YXkgb2ZmIGBmcmFtZXdvcmstZXJyb3JgIGFuZCBpdHMgYnVnXG4gKiByZXBvcnRlcnMgKHNhbWUgY29udHJhY3QgYXMgdGhlIGR1cmF0aW9uIHRlbGVtZXRyeSkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gY29uZmlndXJhdGlvbiAtIE93bmluZyBjb25maWd1cmF0aW9uLlxuICogQHBhcmFtIHt7bG9ja05hbWU6IHN0cmluZywgcHJlZmVycmVkVGllcjogc3RyaW5nLCByZWFzb246IHN0cmluZywgc2VydmVkQnk6IHN0cmluZ319IHJlcG9ydCAtIEZhbGxiYWNrIGRldGFpbHMuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVtaXRBZHZpc29yeUxvY2tGYWxsYmFja1JlcG9ydChjb25maWd1cmF0aW9uLCByZXBvcnQpIHtcbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCJldmVudGVtaXR0ZXIzXCIpLkV2ZW50RW1pdHRlciB8IHVuZGVmaW5lZH0gKi9cbiAgbGV0IHRlbGVtZXRyeUV2ZW50c1xuXG4gIHRyeSB7XG4gICAgdGVsZW1ldHJ5RXZlbnRzID0gY29uZmlndXJhdGlvbj8uZ2V0VGVsZW1ldHJ5RXZlbnRzKClcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIC8vIE5vIGNvbmZpZ3VyYXRpb24gdG8gcmVwb3J0IHRocm91Z2gg4oCUIG5ldmVyIGJyZWFrIGxvY2sgaGFuZGxpbmcuXG4gIH1cblxuICBpZiAoIXRlbGVtZXRyeUV2ZW50cykgcmV0dXJuXG5cbiAgY29uc3QgcGF5bG9hZCA9IHtjb250ZXh0OiBcImFkdmlzb3J5LWxvY2stZmFsbGJhY2tcIiwgLi4ucmVwb3J0fVxuICBjb25zdCBoYXNMaXN0ZW5lciA9IHRlbGVtZXRyeUV2ZW50cy5saXN0ZW5lckNvdW50KFwidGVsZW1ldHJ5XCIpID4gMFxuXG4gIHRyeSB7XG4gICAgdGVsZW1ldHJ5RXZlbnRzLmVtaXQoXCJ0ZWxlbWV0cnlcIiwgcGF5bG9hZClcbiAgfSBjYXRjaCB7XG4gICAgLy8gQSBicm9rZW4gbGlzdGVuZXIgbXVzdCBuZXZlciBzdXJmYWNlIGFzIGEgbG9jayBmYWlsdXJlLlxuICB9XG5cbiAgaWYgKCFoYXNMaXN0ZW5lcikge1xuICAgIGNvbnNvbGUuZXJyb3IoYFt2ZWxvY2lvdXMgYWR2aXNvcnktbG9jay1mYWxsYmFja10gbG9jaz0ke0pTT04uc3RyaW5naWZ5KHJlcG9ydC5sb2NrTmFtZSl9IHByZWZlcnJlZFRpZXI9JHtyZXBvcnQucHJlZmVycmVkVGllcn0gc2VydmVkQnk9JHtyZXBvcnQuc2VydmVkQnl9IHJlYXNvbj0ke3JlcG9ydC5yZWFzb259YClcbiAgfVxufVxuIl19
@@ -36,9 +36,10 @@ export default class SyncModelChangeFeedService {
36
36
  });
37
37
  /**
38
38
  * Builds a stable change-feed page. The additive `total` is the scope's pending
39
- * change count from the request cursor to the snapshot bound (a COUNT, not a
40
- * materialized read), so a client can render a "synced of total" progress bar;
41
- * older clients ignore it.
39
+ * change count from the request cursor to the snapshot bound, so a client can
40
+ * render a "synced of total" progress bar; older clients ignore it. The count
41
+ * query only runs when the page read cannot answer it: a sequence cursor whose
42
+ * page is short of the limit has already materialized the whole remaining set.
42
43
  * @returns {Promise<{status: string, nextCursor: {id: string, serverSequence: number, updatedAt: string} | null, syncs: Array<Record<string, unknown>>, total: number, upToCursor: {id: string, serverSequence: number, updatedAt: string} | null}>} Change-feed page result.
43
44
  */
44
45
  changes(): Promise<{
@@ -1 +1 @@
1
- {"version":3,"file":"sync-model-change-feed-service.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-model-change-feed-service.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sync-model-change-feed-service.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-model-change-feed-service.js"],"names":[],"mappings":"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"}
@@ -30,9 +30,10 @@ export default class SyncModelChangeFeedService {
30
30
  }
31
31
  /**
32
32
  * Builds a stable change-feed page. The additive `total` is the scope's pending
33
- * change count from the request cursor to the snapshot bound (a COUNT, not a
34
- * materialized read), so a client can render a "synced of total" progress bar;
35
- * older clients ignore it.
33
+ * change count from the request cursor to the snapshot bound, so a client can
34
+ * render a "synced of total" progress bar; older clients ignore it. The count
35
+ * query only runs when the page read cannot answer it: a sequence cursor whose
36
+ * page is short of the limit has already materialized the whole remaining set.
36
37
  * @returns {Promise<{status: string, nextCursor: {id: string, serverSequence: number, updatedAt: string} | null, syncs: Array<Record<string, unknown>>, total: number, upToCursor: {id: string, serverSequence: number, updatedAt: string} | null}>} Change-feed page result.
37
38
  */
38
39
  async changes() {
@@ -40,10 +41,20 @@ export default class SyncModelChangeFeedService {
40
41
  const upToCursor = await this.resolveUpToCursor();
41
42
  if (!upToCursor)
42
43
  return { status: "success", nextCursor: null, syncs: [], total: 0, upToCursor: null };
43
- const total = await this.totalPendingChanges({ upToCursor });
44
- const query = this.pageQuery({ limit, upToCursor });
45
- const records = await query.toArray();
44
+ const afterServerSequence = this.optionalPositiveIntegerParam(this.params.afterServerSequence, "afterServerSequence");
45
+ // A cursor at or past the scope's snapshot bound cannot have pending rows.
46
+ // Answering here skips both the page read and the count, which would otherwise
47
+ // run against an empty sequence range on every caught-up poll. A multi-scope
48
+ // client sends its global cursor to each scope, so a scope whose own sequences
49
+ // are behind that cursor lands here on nearly every request.
50
+ if (afterServerSequence !== null && afterServerSequence >= upToCursor.serverSequence) {
51
+ return { status: "success", nextCursor: upToCursor, syncs: [], total: 0, upToCursor };
52
+ }
53
+ const records = await this.pageQuery({ limit, upToCursor }).toArray();
46
54
  const nextCursor = records.length > 0 ? this.cursorForRecord(records[records.length - 1]) : upToCursor;
55
+ const total = afterServerSequence !== null && records.length < limit
56
+ ? records.length
57
+ : await this.totalPendingChanges({ upToCursor });
47
58
  return {
48
59
  status: "success",
49
60
  nextCursor,
@@ -246,4 +257,4 @@ export default class SyncModelChangeFeedService {
246
257
  return date.toISOString();
247
258
  }
248
259
  }
249
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1tb2RlbC1jaGFuZ2UtZmVlZC1zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3N5bmMvc3luYy1tb2RlbC1jaGFuZ2UtZmVlZC1zZXJ2aWNlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLGNBQWMsTUFBTSx1QkFBdUIsQ0FBQTtBQUVsRCxPQUFPLEVBQUMsMkJBQTJCLEVBQUMsTUFBTSw0QkFBNEIsQ0FBQTtBQUN0RSxPQUFPLEVBQUMseUJBQXlCLEVBQUMsTUFBTSxpQ0FBaUMsQ0FBQTtBQUV6RTs7Ozs7O0dBTUc7QUFDSCxNQUFNLENBQUMsT0FBTyxPQUFPLDBCQUEwQjtJQUM3Qzs7Ozs7Ozs7O09BU0c7SUFDSCxZQUFZLEVBQUMsWUFBWSxHQUFHLElBQUksRUFBRSxRQUFRLEdBQUcsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLGVBQWUsRUFBQztRQUNqRyxJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQTtRQUNoQyxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQTtRQUN4QixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQTtRQUM1QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQTtRQUNwQixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsSUFBSSxJQUFJLENBQUE7UUFDcEMsSUFBSSxDQUFDLGVBQWUsR0FBRyxlQUFlLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUE7SUFDN0YsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILEtBQUssQ0FBQyxPQUFPO1FBQ1gsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3JELE1BQU0sVUFBVSxHQUFHLE1BQU0s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SUFBSSxFQUFFLDBCQUEwQixFQUFDLENBQUMsQ0FBQTtRQUNwSCxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUE7SUFDM0IsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBWZWxvY2lvdXNFcnJvciBmcm9tIFwiLi4vdmVsb2Npb3VzLWVycm9yLmpzXCJcblxuaW1wb3J0IHtkZWNsYXJlZFN5bmNTY29wZUF0dHJpYnV0ZXN9IGZyb20gXCIuL3N5bmMtc2NvcGUtYXR0cmlidXRlcy5qc1wiXG5pbXBvcnQge2RlY29kZVJlcGxheVBlcnNpc3RlZERhdGF9IGZyb20gXCIuL3N5bmMtcmVwbGF5LXBlcnNpc3RlZC1kYXRhLmpzXCJcblxuLyoqXG4gKiBHZW5lcmljIGN1cnNvci1wYWdpbmF0ZWQgY2hhbmdlIGZlZWQgb3ZlciBhbiBhcHAtb3duZWQgc3luYy9jaGFuZ2UgbW9kZWwuXG4gKlxuICogQXBwcyBwcm92aWRlIHRoZSBtb2RlbCBhbmQgb3B0aW9uYWwgc2NvcGluZy9zZXJpYWxpemF0aW9uIGhvb2tzLiBWZWxvY2lvdXMgb3duc1xuICogY3Vyc29yIHBhcnNpbmcsIHNuYXBzaG90IGhpZ2gtd2F0ZXIgcmVzb2x1dGlvbiwgc3RhYmxlIG9yZGVyaW5nLCBwYWdlIGxpbWl0cyxcbiAqIGFuZCByZXNwb25zZSBzaGFwZSBmb3IgYC92ZWxvY2lvdXMvc3luYy9jaGFuZ2VzYCBzdHlsZSBlbmRwb2ludHMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFN5bmNNb2RlbENoYW5nZUZlZWRTZXJ2aWNlIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBnZW5lcmljIHN5bmMtbW9kZWwgY2hhbmdlLWZlZWQgc2VydmljZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBTZXJ2aWNlIGFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHt0eXBlb2YgaW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IGFyZ3MubW9kZWxDbGFzcyAtIFN5bmMvY2hhbmdlIG1vZGVsIGNsYXNzLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSBhcmdzLnBhcmFtcyAtIFJlcXVlc3QgcGFyYW1zLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2FyZ3MuZGVmYXVsdExpbWl0XSAtIERlZmF1bHQgcGFnZSBzaXplLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2FyZ3MubWF4TGltaXRdIC0gTWF4aW11bSBwYWdlIHNpemUuXG4gICAqIEBwYXJhbSB7KHJlY29yZDogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4pID0+IFJlY29yZDxzdHJpbmcsIHVua25vd24+fSBbYXJncy5zZXJpYWxpemVSZWNvcmRdIC0gUmVjb3JkIHNlcmlhbGl6ZXIuXG4gICAqIEBwYXJhbSB7KGFyZ3M6IHtxdWVyeTogaW1wb3J0KFwiLi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0pID0+IHZvaWR9IFthcmdzLnNjb3BlUXVlcnldIC0gQXBwbGllcyBhcHAtb3duZWQgdmlzaWJpbGl0eSBzY29wZS5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtkZWZhdWx0TGltaXQgPSAxMDAwLCBtYXhMaW1pdCA9IDEwMDAsIG1vZGVsQ2xhc3MsIHBhcmFtcywgc2NvcGVRdWVyeSwgc2VyaWFsaXplUmVjb3JkfSkge1xuICAgIHRoaXMuZGVmYXVsdExpbWl0ID0gZGVmYXVsdExpbWl0XG4gICAgdGhpcy5tYXhMaW1pdCA9IG1heExpbWl0XG4gICAgdGhpcy5tb2RlbENsYXNzID0gbW9kZWxDbGFzc1xuICAgIHRoaXMucGFyYW1zID0gcGFyYW1zXG4gICAgdGhpcy5zY29wZVF1ZXJ5ID0gc2NvcGVRdWVyeSB8fCBudWxsXG4gICAgdGhpcy5zZXJpYWxpemVSZWNvcmQgPSBzZXJpYWxpemVSZWNvcmQgfHwgKChyZWNvcmQpID0+IHRoaXMuZGVmYXVsdFNlcmlhbGl6ZVJlY29yZChyZWNvcmQpKVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhIHN0YWJsZSBjaGFuZ2UtZmVlZCBwYWdlLiBUaGUgYWRkaXRpdmUgYHRvdGFsYCBpcyB0aGUgc2NvcGUncyBwZW5kaW5nXG4gICAqIGNoYW5nZSBjb3VudCBmcm9tIHRoZSByZXF1ZXN0IGN1cnNvciB0byB0aGUgc25hcHNob3QgYm91bmQgKGEgQ09VTlQsIG5vdCBhXG4gICAqIG1hdGVyaWFsaXplZCByZWFkKSwgc28gYSBjbGllbnQgY2FuIHJlbmRlciBhIFwic3luY2VkIG9mIHRvdGFsXCIgcHJvZ3Jlc3MgYmFyO1xuICAgKiBvbGRlciBjbGllbnRzIGlnbm9yZSBpdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8e3N0YXR1czogc3RyaW5nLCBuZXh0Q3Vyc29yOiB7aWQ6IHN0cmluZywgc2VydmVyU2VxdWVuY2U6IG51bWJlciwgdXBkYXRlZEF0OiBzdHJpbmd9IHwgbnVsbCwgc3luY3M6IEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PiwgdG90YWw6IG51bWJlciwgdXBUb0N1cnNvcjoge2lkOiBzdHJpbmcsIHNlcnZlclNlcXVlbmNlOiBudW1iZXIsIHVwZGF0ZWRBdDogc3RyaW5nfSB8IG51bGx9Pn0gQ2hhbmdlLWZlZWQgcGFnZSByZXN1bHQuXG4gICAqL1xuICBhc3luYyBjaGFuZ2VzKCkge1xuICAgIGNvbnN0IGxpbWl0ID0gdGhpcy5ub3JtYWxpemVkTGltaXQodGhpcy5wYXJhbXMubGltaXQpXG4gICAgY29uc3QgdXBUb0N1cnNvciA9IGF3YWl0IHRoaXMucmVzb2x2ZVVwVG9DdXJzb3IoKVxuXG4gICAgaWYgKCF1cFRvQ3Vyc29yKSByZXR1cm4ge3N0YXR1czogXCJzdWNjZXNzXCIsIG5leHRDdXJzb3I6IG51bGwsIHN5bmNzOiBbXSwgdG90YWw6IDAsIHVwVG9DdXJzb3I6IG51bGx9XG5cbiAgICBjb25zdCB0b3RhbCA9IGF3YWl0IHRoaXMudG90YWxQZW5kaW5nQ2hhbmdlcyh7dXBUb0N1cnNvcn0pXG4gICAgY29uc3QgcXVlcnkgPSB0aGlzLnBhZ2VRdWVyeSh7bGltaXQsIHVwVG9DdXJzb3J9KVxuICAgIGNvbnN0IHJlY29yZHMgPSBhd2FpdCBxdWVyeS50b0FycmF5KClcbiAgICBjb25zdCBuZXh0Q3Vyc29yID0gcmVjb3Jkcy5sZW5ndGggPiAwID8gdGhpcy5jdXJzb3JGb3JSZWNvcmQocmVjb3Jkc1tyZWNvcmRzLmxlbmd0aCAtIDFdKSA6IHVwVG9DdXJzb3JcblxuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXM6IFwic3VjY2Vzc1wiLFxuICAgICAgbmV4dEN1cnNvcixcbiAgICAgIHN5bmNzOiByZWNvcmRzLm1hcCgocmVjb3JkKSA9PiB0aGlzLnNlcmlhbGl6ZVJlY29yZChyZWNvcmQpKSxcbiAgICAgIHRvdGFsLFxuICAgICAgdXBUb0N1cnNvclxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBOb3JtYWxpemVzIHRoZSByZXF1ZXN0ZWQgcGFnZSBsaW1pdC5cbiAgICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIFJhdyBsaW1pdCBwYXJhbS5cbiAgICogQHJldHVybnMge251bWJlcn0gTm9ybWFsaXplZCBwYWdlIGxpbWl0LlxuICAgKi9cbiAgbm9ybWFsaXplZExpbWl0KHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IFwiXCIpIHJldHVybiB0aGlzLmRlZmF1bHRMaW1pdFxuXG4gICAgY29uc3QgbGltaXQgPSBOdW1iZXIodmFsdWUpXG5cbiAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKGxpbWl0KSB8fCBsaW1pdCA8PSAwKSB7XG4gICAgICB0aHJvdyBWZWxvY2lvdXNFcnJvci5zYWZlKFwiU3luYyBjaGFuZ2VzIGxpbWl0IG11c3QgYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyLlwiLCB7Y29kZTogXCJzeW5jLWludmFsaWQtY2hhbmdlcy1saW1pdFwifSlcbiAgICB9XG5cbiAgICByZXR1cm4gTWF0aC5taW4obGltaXQsIHRoaXMubWF4TGltaXQpXG4gIH1cblxuICAvKipcbiAgICogUGFyc2VzIGFuIG9wdGlvbmFsIHBvc2l0aXZlIGludGVnZXIgY3Vyc29yIGZpZWxkLlxuICAgKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gUmF3IGludGVnZXIgcGFyYW0uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gUGFyYW0gbmFtZSBmb3IgZXJyb3IgbWVzc2FnZXMuXG4gICAqIEByZXR1cm5zIHtudW1iZXIgfCBudWxsfSBQb3NpdGl2ZSBpbnRlZ2VyIHZhbHVlLCBvciBudWxsIHdoZW4gb21pdHRlZC5cbiAgICovXG4gIG9wdGlvbmFsUG9zaXRpdmVJbnRlZ2VyUGFyYW0odmFsdWUsIG5hbWUpIHtcbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gXCJcIikgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IGludGVnZXIgPSBOdW1iZXIodmFsdWUpXG5cbiAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKGludGVnZXIpIHx8IGludGVnZXIgPD0gMCkge1xuICAgICAgdGhyb3cgVmVsb2Npb3VzRXJyb3Iuc2FmZShgJHtuYW1lfSBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlci5gLCB7Y29kZTogXCJzeW5jLWludmFsaWQtY2hhbmdlcy1jdXJzb3JcIn0pXG4gICAgfVxuXG4gICAgcmV0dXJuIGludGVnZXJcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgaGlnaC13YXRlciBjdXJzb3IgdGhhdCBib3VuZHMgdGhlIGN1cnJlbnQgZmVlZCBwYWdlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7aWQ6IHN0cmluZywgc2VydmVyU2VxdWVuY2U6IG51bWJlciwgdXBkYXRlZEF0OiBzdHJpbmd9IHwgbnVsbD59IFNuYXBzaG90IHVwcGVyLWJvdW5kIGN1cnNvci5cbiAgICovXG4gIGFzeW5jIHJlc29sdmVVcFRvQ3Vyc29yKCkge1xuICAgIGNvbnN0IHVwVG9TZXJ2ZXJTZXF1ZW5jZSA9IHRoaXMub3B0aW9uYWxQb3NpdGl2ZUludGVnZXJQYXJhbSh0aGlzLnBhcmFtcy51cFRvU2VydmVyU2VxdWVuY2UsIFwidXBUb1NlcnZlclNlcXVlbmNlXCIpXG5cbiAgICBpZiAodXBUb1NlcnZlclNlcXVlbmNlICE9PSBudWxsICYmIHR5cGVvZiB0aGlzLnBhcmFtcy51cFRvVXBkYXRlZEF0ID09PSBcInN0cmluZ1wiICYmIHR5cGVvZiB0aGlzLnBhcmFtcy51cFRvSWQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHJldHVybiB7aWQ6IHRoaXMucGFyYW1zLnVwVG9JZCwgc2VydmVyU2VxdWVuY2U6IHVwVG9TZXJ2ZXJTZXF1ZW5jZSwgdXBkYXRlZEF0OiB0aGlzLnBhcmFtcy51cFRvVXBkYXRlZEF0fVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGhpcy5wYXJhbXMudXBUb1VwZGF0ZWRBdCA9PT0gXCJzdHJpbmdcIiAmJiB0eXBlb2YgdGhpcy5wYXJhbXMudXBUb0lkID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBjb25zdCB1cFRvUmVjb3JkID0gYXdhaXQgdGhpcy5tb2RlbENsYXNzLmZpbmRCeSh7aWQ6IHRoaXMucGFyYW1zLnVwVG9JZH0pXG5cbiAgICAgIGlmICh1cFRvUmVjb3JkKSByZXR1cm4gdGhpcy5jdXJzb3JGb3JSZWNvcmQodXBUb1JlY29yZClcbiAgICB9XG5cbiAgICBjb25zdCBxdWVyeSA9IHRoaXMuc2NvcGVkUXVlcnkoKVxuICAgIGNvbnN0IHRhYmxlID0gcXVlcnkuZHJpdmVyLnF1b3RlVGFibGUodGhpcy5tb2RlbENsYXNzLnRhYmxlTmFtZSgpKVxuICAgIGNvbnN0IHNlcnZlclNlcXVlbmNlQ29sdW1uID0gcXVlcnkuZHJpdmVyLnF1b3RlQ29sdW1uKFwic2VydmVyX3NlcXVlbmNlXCIpXG4gICAgY29uc3QgbGF0ZXN0UmVjb3JkcyA9IGF3YWl0IHF1ZXJ5XG4gICAgICAub3JkZXIoYCR7dGFibGV9LiR7c2VydmVyU2VxdWVuY2VDb2x1bW59IERFU0NgKVxuICAgICAgLmxpbWl0KDEpXG4gICAgICAudG9BcnJheSgpXG5cbiAgICBpZiAobGF0ZXN0UmVjb3Jkcy5sZW5ndGggPT09IDApIHJldHVybiBudWxsXG5cbiAgICByZXR1cm4gdGhpcy5jdXJzb3JGb3JSZWNvcmQobGF0ZXN0UmVjb3Jkc1swXSlcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIG9yZGVyZWQgYW5kIGN1cnNvci1maWx0ZXJlZCBwYWdlIHF1ZXJ5LlxuICAgKiBAcGFyYW0ge3tsaW1pdDogbnVtYmVyLCB1cFRvQ3Vyc29yOiB7aWQ6IHN0cmluZywgc2VydmVyU2VxdWVuY2U6IG51bWJlciwgdXBkYXRlZEF0OiBzdHJpbmd9fX0gYXJncyAtIFBhZ2UgcXVlcnkgYXJncy5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHR9IFBhZ2UgcXVlcnkuXG4gICAqL1xuICBwYWdlUXVlcnkoe2xpbWl0LCB1cFRvQ3Vyc29yfSkge1xuICAgIGNvbnN0IHF1ZXJ5ID0gdGhpcy5jdXJzb3JGaWx0ZXJlZFF1ZXJ5KHt1cFRvQ3Vyc29yfSlcbiAgICBjb25zdCBkcml2ZXIgPSBxdWVyeS5kcml2ZXJcbiAgICBjb25zdCBzZXJ2ZXJTZXF1ZW5jZUNvbHVtbiA9IGAke2RyaXZlci5xdW90ZVRhYmxlKHRoaXMubW9kZWxDbGFzcy50YWJsZU5hbWUoKSl9LiR7ZHJpdmVyLnF1b3RlQ29sdW1uKFwic2VydmVyX3NlcXVlbmNlXCIpfWBcblxuICAgIHJldHVybiBxdWVyeVxuICAgICAgLm9yZGVyKGAke3NlcnZlclNlcXVlbmNlQ29sdW1ufSBBU0NgKVxuICAgICAgLmxpbWl0KGxpbWl0KVxuICB9XG5cbiAgLyoqXG4gICAqIENvdW50cyB0aGUgc2NvcGUncyBwZW5kaW5nIGNoYW5nZSByb3dzIGZyb20gdGhlIHJlcXVlc3QgY3Vyc29yIHRvIHRoZSBzbmFwc2hvdFxuICAgKiBib3VuZCB3aXRob3V0IG1hdGVyaWFsaXppbmcgdGhlbSwgc28gdGhlIGNsaWVudCBjYW4gcmVuZGVyIGEgc3RhYmxlIFwib2YgWVwiXG4gICAqIHByb2dyZXNzIGRlbm9taW5hdG9yLlxuICAgKiBAcGFyYW0ge3t1cFRvQ3Vyc29yOiB7aWQ6IHN0cmluZywgc2VydmVyU2VxdWVuY2U6IG51bWJlciwgdXBkYXRlZEF0OiBzdHJpbmd9fX0gYXJncyAtIENvdW50IGFyZ3MuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPG51bWJlcj59IFBlbmRpbmcgY2hhbmdlIGNvdW50IGZyb20gdGhlIHJlcXVlc3QgY3Vyc29yLlxuICAgKi9cbiAgYXN5bmMgdG90YWxQZW5kaW5nQ2hhbmdlcyh7dXBUb0N1cnNvcn0pIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5jdXJzb3JGaWx0ZXJlZFF1ZXJ5KHt1cFRvQ3Vyc29yfSkuY291bnQoKVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhIHNjb3BlZCBxdWVyeSB3aXRoIHRoZSBzbmFwc2hvdCB1cHBlciBib3VuZCBhbmQgYWZ0ZXItY3Vyc29yIGZpbHRlcnNcbiAgICogYXBwbGllZCwgYnV0IHdpdGhvdXQgb3JkZXJpbmcgb3IgYSBwYWdlIGxpbWl0LiBTaGFyZWQgYnkgdGhlIHBhZ2UgcmVhZCBhbmQgdGhlXG4gICAqIHRvdGFsLWNvdW50IHNvIGJvdGggY291bnQgdGhlIHNhbWUgc2V0IG9mIHJvd3MuXG4gICAqIEBwYXJhbSB7e3VwVG9DdXJzb3I6IHtpZDogc3RyaW5nLCBzZXJ2ZXJTZXF1ZW5jZTogbnVtYmVyLCB1cGRhdGVkQXQ6IHN0cmluZ319fSBhcmdzIC0gRmlsdGVyIGFyZ3MuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9xdWVyeS9tb2RlbC1jbGFzcy1xdWVyeS5qc1wiKS5kZWZhdWx0fSBDdXJzb3ItZmlsdGVyZWQgcXVlcnkuXG4gICAqL1xuICBjdXJzb3JGaWx0ZXJlZFF1ZXJ5KHt1cFRvQ3Vyc29yfSkge1xuICAgIGNvbnN0IHF1ZXJ5ID0gdGhpcy5zY29wZWRRdWVyeSgpXG4gICAgY29uc3QgZHJpdmVyID0gcXVlcnkuZHJpdmVyXG4gICAgY29uc3QgdGFibGUgPSBkcml2ZXIucXVvdGVUYWJsZSh0aGlzLm1vZGVsQ2xhc3MudGFibGVOYW1lKCkpXG4gICAgY29uc3Qgc2VydmVyU2VxdWVuY2VDb2x1bW4gPSBgJHt0YWJsZX0uJHtkcml2ZXIucXVvdGVDb2x1bW4oXCJzZXJ2ZXJfc2VxdWVuY2VcIil9YFxuICAgIGNvbnN0IHVwZGF0ZWRBdENvbHVtbiA9IGAke3RhYmxlfS4ke2RyaXZlci5xdW90ZUNvbHVtbihcInVwZGF0ZWRfYXRcIil9YFxuICAgIGNvbnN0IGlkQ29sdW1uID0gYCR7dGFibGV9LiR7ZHJpdmVyLnF1b3RlQ29sdW1uKFwiaWRcIil9YFxuXG4gICAgcXVlcnkud2hlcmUoYCR7c2VydmVyU2VxdWVuY2VDb2x1bW59IDw9ICR7ZHJpdmVyLnF1b3RlKHVwVG9DdXJzb3Iuc2VydmVyU2VxdWVuY2UpfWApXG5cbiAgICBjb25zdCBhZnRlclNlcnZlclNlcXVlbmNlID0gdGhpcy5vcHRpb25hbFBvc2l0aXZlSW50ZWdlclBhcmFtKHRoaXMucGFyYW1zLmFmdGVyU2VydmVyU2VxdWVuY2UsIFwiYWZ0ZXJTZXJ2ZXJTZXF1ZW5jZVwiKVxuXG4gICAgaWYgKGFmdGVyU2VydmVyU2VxdWVuY2UgIT09IG51bGwpIHtcbiAgICAgIHF1ZXJ5LndoZXJlKGAke3NlcnZlclNlcXVlbmNlQ29sdW1ufSA+ICR7ZHJpdmVyLnF1b3RlKGFmdGVyU2VydmVyU2VxdWVuY2UpfWApXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5wYXJhbXMuYWZ0ZXJVcGRhdGVkQXQgPT09IFwic3RyaW5nXCIgJiYgdGhpcy5wYXJhbXMuYWZ0ZXJVcGRhdGVkQXQgIT09IFwiXCIpIHtcbiAgICAgIGNvbnN0IGlzUGFnaW5nRXhpc3RpbmdTbmFwc2hvdCA9IHR5cGVvZiB0aGlzLnBhcmFtcy51cFRvVXBkYXRlZEF0ID09PSBcInN0cmluZ1wiICYmIHRoaXMucGFyYW1zLnVwVG9VcGRhdGVkQXQgIT09IFwiXCIgJiYgdHlwZW9mIHRoaXMucGFyYW1zLnVwVG9JZCA9PT0gXCJzdHJpbmdcIiAmJiB0aGlzLnBhcmFtcy51cFRvSWQgIT09IFwiXCJcblxuICAgICAgaWYgKGlzUGFnaW5nRXhpc3RpbmdTbmFwc2hvdCAmJiB0eXBlb2YgdGhpcy5wYXJhbXMuYWZ0ZXJJZCA9PT0gXCJzdHJpbmdcIiAmJiB0aGlzLnBhcmFtcy5hZnRlcklkICE9PSBcIlwiKSB7XG4gICAgICAgIHF1ZXJ5LndoZXJlKGAoJHt1cGRhdGVkQXRDb2x1bW59ID4gJHtkcml2ZXIucXVvdGUodGhpcy5wYXJhbXMuYWZ0ZXJVcGRhdGVkQXQpfSBPUiAoJHt1cGRhdGVkQXRDb2x1bW59ID0gJHtkcml2ZXIucXVvdGUodGhpcy5wYXJhbXMuYWZ0ZXJVcGRhdGVkQXQpfSBBTkQgJHtpZENvbHVtbn0gPiAke2RyaXZlci5xdW90ZSh0aGlzLnBhcmFtcy5hZnRlcklkKX0pKWApXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBxdWVyeS53aGVyZShgJHt1cGRhdGVkQXRDb2x1bW59ID49ICR7ZHJpdmVyLnF1b3RlKHRoaXMucGFyYW1zLmFmdGVyVXBkYXRlZEF0KX1gKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBxdWVyeVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhIGJhc2UgcXVlcnkgd2l0aCBhcHAtb3duZWQgc2NvcGUgYXBwbGllZC5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHR9IFNjb3BlZCBiYXNlIHF1ZXJ5LlxuICAgKi9cbiAgc2NvcGVkUXVlcnkoKSB7XG4gICAgY29uc3QgcXVlcnkgPSB0aGlzLm1vZGVsQ2xhc3Mud2hlcmUoe30pXG5cbiAgICBpZiAodGhpcy5zY29wZVF1ZXJ5KSB0aGlzLnNjb3BlUXVlcnkoe3F1ZXJ5fSlcblxuICAgIHJldHVybiBxdWVyeVxuICB9XG5cbiAgLyoqXG4gICAqIFNlcmlhbGl6ZXMgYSByZWNvcmQgaW50byBhIHRyYW5zcG9ydCBjdXJzb3IuXG4gICAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IHJlY29yZCAtIFN5bmMvY2hhbmdlIHJlY29yZC5cbiAgICogQHJldHVybnMge3tpZDogc3RyaW5nLCBzZXJ2ZXJTZXF1ZW5jZTogbnVtYmVyLCB1cGRhdGVkQXQ6IHN0cmluZ319IEN1cnNvciBmb3Igcm93LlxuICAgKi9cbiAgY3Vyc29yRm9yUmVjb3JkKHJlY29yZCkge1xuICAgIHJldHVybiB7aWQ6IFN0cmluZyh0aGlzLnJlY29yZFZhbHVlKHJlY29yZCwgXCJpZFwiKSksIHNlcnZlclNlcXVlbmNlOiBOdW1iZXIodGhpcy5yZWNvcmRWYWx1ZShyZWNvcmQsIFwic2VydmVyU2VxdWVuY2VcIikpLCB1cGRhdGVkQXQ6IHRoaXMuaXNvRGF0ZSh0aGlzLnJlY29yZFZhbHVlKHJlY29yZCwgXCJ1cGRhdGVkQXRcIikpfVxuICB9XG5cbiAgLyoqXG4gICAqIFNlcmlhbGl6ZXMgYSByZWNvcmQgdXNpbmcgdGhlIHN0YW5kYXJkIHN5bmMgZW52ZWxvcGUgc2hhcGUgcGx1cyB0aGUgc3luY1xuICAgKiBtb2RlbCdzIGRlY2xhcmVkIHNjb3BlLXBhcnRpdGlvbiBhdHRyaWJ1dGVzIChgc3RhdGljIHN5bmNTY29wZUF0dHJpYnV0ZXNgKSxcbiAgICogZWFjaCBlbWl0dGVkIHVuZGVyIGl0cyBvd24gYXR0cmlidXRlIG5hbWUuIE1vZGVscyBkZWNsYXJpbmcgbm8gc2NvcGVcbiAgICogYXR0cmlidXRlcyBrZWVwIHRoZSBkZXByZWNhdGVkIDEuMC41MDMgd2lyZSBhbmQgZW1pdCBgZXZlbnRJZGAuIEtleXMgYXJlXG4gICAqIHNvcnRlZCBzbyBhIGRlY2xhcmVkIGBbXCJldmVudElkXCJdYCBwYXJ0aXRpb24gc3RheXMgYnl0ZS1pZGVudGljYWwgd2l0aCB0aGVcbiAgICogMS4wLjUwMyB3aXJlLlxuICAgKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSByZWNvcmQgLSBTeW5jL2NoYW5nZSByZWNvcmQuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gRGVmYXVsdCBzZXJpYWxpemVkIHJvdy5cbiAgICovXG4gIGRlZmF1bHRTZXJpYWxpemVSZWNvcmQocmVjb3JkKSB7XG4gICAgY29uc3Qgc2NvcGVBdHRyaWJ1dGVzID0gZGVjbGFyZWRTeW5jU2NvcGVBdHRyaWJ1dGVzKHRoaXMubW9kZWxDbGFzcylcbiAgICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSAqL1xuICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSB7XG4gICAgICBkYXRhOiB0aGlzLnJlY29yZERhdGEocmVjb3JkKSxcbiAgICAgIGlkOiB0aGlzLnJlY29yZFZhbHVlKHJlY29yZCwgXCJpZFwiKSxcbiAgICAgIHJlc291cmNlSWQ6IHRoaXMucmVjb3JkVmFsdWUocmVjb3JkLCBcInJlc291cmNlSWRcIiksXG4gICAgICByZXNvdXJjZVR5cGU6IHRoaXMucmVjb3JkVmFsdWUocmVjb3JkLCBcInJlc291cmNlVHlwZVwiKSxcbiAgICAgIHNlcnZlclNlcXVlbmNlOiB0aGlzLnJlY29yZFZhbHVlKHJlY29yZCwgXCJzZXJ2ZXJTZXF1ZW5jZVwiKSxcbiAgICAgIHN5bmNUeXBlOiB0aGlzLnJlY29yZFZhbHVlKHJlY29yZCwgXCJzeW5jVHlwZVwiKSxcbiAgICAgIHVwZGF0ZWRBdDogdGhpcy5pc29EYXRlKHRoaXMucmVjb3JkVmFsdWUocmVjb3JkLCBcInVwZGF0ZWRBdFwiKSlcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHNjb3BlQXR0cmlidXRlIG9mIHNjb3BlQXR0cmlidXRlcyB8fCBbXCJldmVudElkXCJdKSB7XG4gICAgICBzZXJpYWxpemVkW3Njb3BlQXR0cmlidXRlXSA9IHRoaXMucmVjb3JkVmFsdWUocmVjb3JkLCBzY29wZUF0dHJpYnV0ZSlcbiAgICB9XG5cbiAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKE9iamVjdC5lbnRyaWVzKHNlcmlhbGl6ZWQpLnNvcnQoKFtsZWZ0S2V5XSwgW3JpZ2h0S2V5XSkgPT4gbGVmdEtleS5sb2NhbGVDb21wYXJlKHJpZ2h0S2V5KSkpXG4gIH1cblxuICAvKipcbiAgICogUmVhZHMgYW5kIHBhcnNlcyB0aGUgcmVjb3JkIGRhdGEgcGF5bG9hZC5cbiAgICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gcmVjb3JkIC0gU3luYy9jaGFuZ2UgcmVjb3JkLlxuICAgKiBAcmV0dXJucyB7dW5rbm93bn0gUGFyc2VkIGRhdGEgdmFsdWUuXG4gICAqL1xuICByZWNvcmREYXRhKHJlY29yZCkge1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLnJlY29yZFZhbHVlKHJlY29yZCwgXCJkYXRhXCIpXG5cbiAgICBpZiAoZGF0YSA9PT0gXCJcIiB8fCBkYXRhID09PSBudWxsIHx8IGRhdGEgPT09IHVuZGVmaW5lZCkgcmV0dXJuIG51bGxcbiAgICByZXR1cm4gZGVjb2RlUmVwbGF5UGVyc2lzdGVkRGF0YShkYXRhKS5wYXlsb2FkXG4gIH1cblxuICAvKipcbiAgICogUmVhZHMgYSB2YWx1ZSBmcm9tIGVpdGhlciBhIHJlY29yZCBhY2Nlc3NvciBtZXRob2Qgb3IgcGxhaW4gcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IHJlY29yZCAtIFN5bmMvY2hhbmdlIHJlY29yZC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBDYW1lbC1jYXNlZCB2YWx1ZS9tZXRob2QgbmFtZS5cbiAgICogQHJldHVybnMge3Vua25vd259IFJlY29yZCB2YWx1ZS5cbiAgICovXG4gIHJlY29yZFZhbHVlKHJlY29yZCwgbmFtZSkge1xuICAgIGlmICghcmVjb3JkIHx8IHR5cGVvZiByZWNvcmQgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlN5bmMgY2hhbmdlcyByb3cgbXVzdCBiZSBhbiBvYmplY3QuXCIpXG4gICAgfVxuXG4gICAgY29uc3QgcmVjb3JkT2JqZWN0ID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59ICovIChyZWNvcmQpXG4gICAgY29uc3QgbWV0aG9kID0gcmVjb3JkT2JqZWN0W25hbWVdXG4gICAgY29uc3QgdmFsdWUgPSB0eXBlb2YgbWV0aG9kID09PSBcImZ1bmN0aW9uXCIgPyBtZXRob2QuY2FsbChyZWNvcmQpIDogbWV0aG9kXG5cbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBTeW5jIGNoYW5nZXMgcm93IGlzIG1pc3NpbmcgJHtuYW1lfS5gKVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGEgZGF0ZS1saWtlIHZhbHVlIHRvIGFuIElTTyBzdHJpbmcuXG4gICAqIEBwYXJhbSB7RGF0ZSB8IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQgfCB1bmtub3dufSB2YWx1ZSAtIERhdGUgdmFsdWUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IElTTyBkYXRlLlxuICAgKi9cbiAgaXNvRGF0ZSh2YWx1ZSkge1xuICAgIGNvbnN0IGRhdGUgPSB2YWx1ZSBpbnN0YW5jZW9mIERhdGUgPyB2YWx1ZSA6IG5ldyBEYXRlKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiB8fCB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgPyB2YWx1ZSA6IDApXG5cbiAgICBpZiAoTnVtYmVyLmlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgdGhyb3cgVmVsb2Npb3VzRXJyb3Iuc2FmZShcIlN5bmMgY2hhbmdlcyByb3cgaGFzIGFuIGludmFsaWQgdXBkYXRlZF9hdCB2YWx1ZS5cIiwge2NvZGU6IFwic3luYy1pbnZhbGlkLWNoYW5nZXMtcm93XCJ9KVxuICAgIH1cblxuICAgIHJldHVybiBkYXRlLnRvSVNPU3RyaW5nKClcbiAgfVxufVxuIl19
260
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1tb2RlbC1jaGFuZ2UtZmVlZC1zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3N5bmMvc3luYy1tb2RlbC1jaGFuZ2UtZmVlZC1zZXJ2aWNlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLGNBQWMsTUFBTSx1QkFBdUIsQ0FBQTtBQUVsRCxPQUFPLEVBQUMsMkJBQTJCLEVBQUMsTUFBTSw0QkFBNEIsQ0FBQTtBQUN0RSxPQUFPLEVBQUMseUJBQXlCLEVBQUMsTUFBTSxpQ0FBaUMsQ0FBQTtBQUV6RTs7Ozs7O0dBTUc7QUFDSCxNQUFNLENBQUMsT0FBTyxPQUFPLDBCQUEwQjtJQUM3Qzs7Ozs7Ozs7O09BU0c7SUFDSCxZQUFZLEVBQUMsWUFBWSxHQUFHLElBQUksRUFBRSxRQUFRLEdBQUcsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLGVBQWUsRUFBQztRQUNqRyxJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQTtRQUNoQyxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQTtRQUN4QixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQTtRQUM1QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQTtRQUNwQixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsSUFBSSxJQUFJLENBQUE7UUFDcEMsSUFBSSxDQUFDLGVBQWUsR0FBRyxlQUFlLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUE7SUFDN0YsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxLQUFLLENBQUMsT0FBTztRQUNYLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNyRCxNQUFNLFVBQVUsR0FBRyxNQUFN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QUFNLElBQUksS0FBSyxDQUFDLCtCQUErQixJQUFJLEdBQUcsQ0FBQyxDQUFBO1FBQ3pELENBQUM7UUFFRCxPQUFPLEtBQUssQ0FBQTtJQUNkLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsT0FBTyxDQUFDLEtBQUs7UUFDWCxNQUFNLElBQUksR0FBRyxLQUFLLFlBQVksSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFFekgsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDakMsTUFBTSxjQUFjLENBQUMsSUFBSSxDQUFDLG1EQUFtRCxFQUFFLEVBQUMsSUFBSSxFQUFFLDBCQUEwQixFQUFDLENBQUMsQ0FBQTtRQUNwSCxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUE7SUFDM0IsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBWZWxvY2lvdXNFcnJvciBmcm9tIFwiLi4vdmVsb2Npb3VzLWVycm9yLmpzXCJcblxuaW1wb3J0IHtkZWNsYXJlZFN5bmNTY29wZUF0dHJpYnV0ZXN9IGZyb20gXCIuL3N5bmMtc2NvcGUtYXR0cmlidXRlcy5qc1wiXG5pbXBvcnQge2RlY29kZVJlcGxheVBlcnNpc3RlZERhdGF9IGZyb20gXCIuL3N5bmMtcmVwbGF5LXBlcnNpc3RlZC1kYXRhLmpzXCJcblxuLyoqXG4gKiBHZW5lcmljIGN1cnNvci1wYWdpbmF0ZWQgY2hhbmdlIGZlZWQgb3ZlciBhbiBhcHAtb3duZWQgc3luYy9jaGFuZ2UgbW9kZWwuXG4gKlxuICogQXBwcyBwcm92aWRlIHRoZSBtb2RlbCBhbmQgb3B0aW9uYWwgc2NvcGluZy9zZXJpYWxpemF0aW9uIGhvb2tzLiBWZWxvY2lvdXMgb3duc1xuICogY3Vyc29yIHBhcnNpbmcsIHNuYXBzaG90IGhpZ2gtd2F0ZXIgcmVzb2x1dGlvbiwgc3RhYmxlIG9yZGVyaW5nLCBwYWdlIGxpbWl0cyxcbiAqIGFuZCByZXNwb25zZSBzaGFwZSBmb3IgYC92ZWxvY2lvdXMvc3luYy9jaGFuZ2VzYCBzdHlsZSBlbmRwb2ludHMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFN5bmNNb2RlbENoYW5nZUZlZWRTZXJ2aWNlIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBnZW5lcmljIHN5bmMtbW9kZWwgY2hhbmdlLWZlZWQgc2VydmljZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBTZXJ2aWNlIGFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHt0eXBlb2YgaW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IGFyZ3MubW9kZWxDbGFzcyAtIFN5bmMvY2hhbmdlIG1vZGVsIGNsYXNzLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSBhcmdzLnBhcmFtcyAtIFJlcXVlc3QgcGFyYW1zLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2FyZ3MuZGVmYXVsdExpbWl0XSAtIERlZmF1bHQgcGFnZSBzaXplLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2FyZ3MubWF4TGltaXRdIC0gTWF4aW11bSBwYWdlIHNpemUuXG4gICAqIEBwYXJhbSB7KHJlY29yZDogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4pID0+IFJlY29yZDxzdHJpbmcsIHVua25vd24+fSBbYXJncy5zZXJpYWxpemVSZWNvcmRdIC0gUmVjb3JkIHNlcmlhbGl6ZXIuXG4gICAqIEBwYXJhbSB7KGFyZ3M6IHtxdWVyeTogaW1wb3J0KFwiLi4vZGF0YWJhc2UvcXVlcnkvbW9kZWwtY2xhc3MtcXVlcnkuanNcIikuZGVmYXVsdH0pID0+IHZvaWR9IFthcmdzLnNjb3BlUXVlcnldIC0gQXBwbGllcyBhcHAtb3duZWQgdmlzaWJpbGl0eSBzY29wZS5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtkZWZhdWx0TGltaXQgPSAxMDAwLCBtYXhMaW1pdCA9IDEwMDAsIG1vZGVsQ2xhc3MsIHBhcmFtcywgc2NvcGVRdWVyeSwgc2VyaWFsaXplUmVjb3JkfSkge1xuICAgIHRoaXMuZGVmYXVsdExpbWl0ID0gZGVmYXVsdExpbWl0XG4gICAgdGhpcy5tYXhMaW1pdCA9IG1heExpbWl0XG4gICAgdGhpcy5tb2RlbENsYXNzID0gbW9kZWxDbGFzc1xuICAgIHRoaXMucGFyYW1zID0gcGFyYW1zXG4gICAgdGhpcy5zY29wZVF1ZXJ5ID0gc2NvcGVRdWVyeSB8fCBudWxsXG4gICAgdGhpcy5zZXJpYWxpemVSZWNvcmQgPSBzZXJpYWxpemVSZWNvcmQgfHwgKChyZWNvcmQpID0+IHRoaXMuZGVmYXVsdFNlcmlhbGl6ZVJlY29yZChyZWNvcmQpKVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhIHN0YWJsZSBjaGFuZ2UtZmVlZCBwYWdlLiBUaGUgYWRkaXRpdmUgYHRvdGFsYCBpcyB0aGUgc2NvcGUncyBwZW5kaW5nXG4gICAqIGNoYW5nZSBjb3VudCBmcm9tIHRoZSByZXF1ZXN0IGN1cnNvciB0byB0aGUgc25hcHNob3QgYm91bmQsIHNvIGEgY2xpZW50IGNhblxuICAgKiByZW5kZXIgYSBcInN5bmNlZCBvZiB0b3RhbFwiIHByb2dyZXNzIGJhcjsgb2xkZXIgY2xpZW50cyBpZ25vcmUgaXQuIFRoZSBjb3VudFxuICAgKiBxdWVyeSBvbmx5IHJ1bnMgd2hlbiB0aGUgcGFnZSByZWFkIGNhbm5vdCBhbnN3ZXIgaXQ6IGEgc2VxdWVuY2UgY3Vyc29yIHdob3NlXG4gICAqIHBhZ2UgaXMgc2hvcnQgb2YgdGhlIGxpbWl0IGhhcyBhbHJlYWR5IG1hdGVyaWFsaXplZCB0aGUgd2hvbGUgcmVtYWluaW5nIHNldC5cbiAgICogQHJldHVybnMge1Byb21pc2U8e3N0YXR1czogc3RyaW5nLCBuZXh0Q3Vyc29yOiB7aWQ6IHN0cmluZywgc2VydmVyU2VxdWVuY2U6IG51bWJlciwgdXBkYXRlZEF0OiBzdHJpbmd9IHwgbnVsbCwgc3luY3M6IEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PiwgdG90YWw6IG51bWJlciwgdXBUb0N1cnNvcjoge2lkOiBzdHJpbmcsIHNlcnZlclNlcXVlbmNlOiBudW1iZXIsIHVwZGF0ZWRBdDogc3RyaW5nfSB8IG51bGx9Pn0gQ2hhbmdlLWZlZWQgcGFnZSByZXN1bHQuXG4gICAqL1xuICBhc3luYyBjaGFuZ2VzKCkge1xuICAgIGNvbnN0IGxpbWl0ID0gdGhpcy5ub3JtYWxpemVkTGltaXQodGhpcy5wYXJhbXMubGltaXQpXG4gICAgY29uc3QgdXBUb0N1cnNvciA9IGF3YWl0IHRoaXMucmVzb2x2ZVVwVG9DdXJzb3IoKVxuXG4gICAgaWYgKCF1cFRvQ3Vyc29yKSByZXR1cm4ge3N0YXR1czogXCJzdWNjZXNzXCIsIG5leHRDdXJzb3I6IG51bGwsIHN5bmNzOiBbXSwgdG90YWw6IDAsIHVwVG9DdXJzb3I6IG51bGx9XG5cbiAgICBjb25zdCBhZnRlclNlcnZlclNlcXVlbmNlID0gdGhpcy5vcHRpb25hbFBvc2l0aXZlSW50ZWdlclBhcmFtKHRoaXMucGFyYW1zLmFmdGVyU2VydmVyU2VxdWVuY2UsIFwiYWZ0ZXJTZXJ2ZXJTZXF1ZW5jZVwiKVxuXG4gICAgLy8gQSBjdXJzb3IgYXQgb3IgcGFzdCB0aGUgc2NvcGUncyBzbmFwc2hvdCBib3VuZCBjYW5ub3QgaGF2ZSBwZW5kaW5nIHJvd3MuXG4gICAgLy8gQW5zd2VyaW5nIGhlcmUgc2tpcHMgYm90aCB0aGUgcGFnZSByZWFkIGFuZCB0aGUgY291bnQsIHdoaWNoIHdvdWxkIG90aGVyd2lzZVxuICAgIC8vIHJ1biBhZ2FpbnN0IGFuIGVtcHR5IHNlcXVlbmNlIHJhbmdlIG9uIGV2ZXJ5IGNhdWdodC11cCBwb2xsLiBBIG11bHRpLXNjb3BlXG4gICAgLy8gY2xpZW50IHNlbmRzIGl0cyBnbG9iYWwgY3Vyc29yIHRvIGVhY2ggc2NvcGUsIHNvIGEgc2NvcGUgd2hvc2Ugb3duIHNlcXVlbmNlc1xuICAgIC8vIGFyZSBiZWhpbmQgdGhhdCBjdXJzb3IgbGFuZHMgaGVyZSBvbiBuZWFybHkgZXZlcnkgcmVxdWVzdC5cbiAgICBpZiAoYWZ0ZXJTZXJ2ZXJTZXF1ZW5jZSAhPT0gbnVsbCAmJiBhZnRlclNlcnZlclNlcXVlbmNlID49IHVwVG9DdXJzb3Iuc2VydmVyU2VxdWVuY2UpIHtcbiAgICAgIHJldHVybiB7c3RhdHVzOiBcInN1Y2Nlc3NcIiwgbmV4dEN1cnNvcjogdXBUb0N1cnNvciwgc3luY3M6IFtdLCB0b3RhbDogMCwgdXBUb0N1cnNvcn1cbiAgICB9XG5cbiAgICBjb25zdCByZWNvcmRzID0gYXdhaXQgdGhpcy5wYWdlUXVlcnkoe2xpbWl0LCB1cFRvQ3Vyc29yfSkudG9BcnJheSgpXG4gICAgY29uc3QgbmV4dEN1cnNvciA9IHJlY29yZHMubGVuZ3RoID4gMCA/IHRoaXMuY3Vyc29yRm9yUmVjb3JkKHJlY29yZHNbcmVjb3Jkcy5sZW5ndGggLSAxXSkgOiB1cFRvQ3Vyc29yXG4gICAgY29uc3QgdG90YWwgPSBhZnRlclNlcnZlclNlcXVlbmNlICE9PSBudWxsICYmIHJlY29yZHMubGVuZ3RoIDwgbGltaXRcbiAgICAgID8gcmVjb3Jkcy5sZW5ndGhcbiAgICAgIDogYXdhaXQgdGhpcy50b3RhbFBlbmRpbmdDaGFuZ2VzKHt1cFRvQ3Vyc29yfSlcblxuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXM6IFwic3VjY2Vzc1wiLFxuICAgICAgbmV4dEN1cnNvcixcbiAgICAgIHN5bmNzOiByZWNvcmRzLm1hcCgocmVjb3JkKSA9PiB0aGlzLnNlcmlhbGl6ZVJlY29yZChyZWNvcmQpKSxcbiAgICAgIHRvdGFsLFxuICAgICAgdXBUb0N1cnNvclxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBOb3JtYWxpemVzIHRoZSByZXF1ZXN0ZWQgcGFnZSBsaW1pdC5cbiAgICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIFJhdyBsaW1pdCBwYXJhbS5cbiAgICogQHJldHVybnMge251bWJlcn0gTm9ybWFsaXplZCBwYWdlIGxpbWl0LlxuICAgKi9cbiAgbm9ybWFsaXplZExpbWl0KHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IFwiXCIpIHJldHVybiB0aGlzLmRlZmF1bHRMaW1pdFxuXG4gICAgY29uc3QgbGltaXQgPSBOdW1iZXIodmFsdWUpXG5cbiAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKGxpbWl0KSB8fCBsaW1pdCA8PSAwKSB7XG4gICAgICB0aHJvdyBWZWxvY2lvdXNFcnJvci5zYWZlKFwiU3luYyBjaGFuZ2VzIGxpbWl0IG11c3QgYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyLlwiLCB7Y29kZTogXCJzeW5jLWludmFsaWQtY2hhbmdlcy1saW1pdFwifSlcbiAgICB9XG5cbiAgICByZXR1cm4gTWF0aC5taW4obGltaXQsIHRoaXMubWF4TGltaXQpXG4gIH1cblxuICAvKipcbiAgICogUGFyc2VzIGFuIG9wdGlvbmFsIHBvc2l0aXZlIGludGVnZXIgY3Vyc29yIGZpZWxkLlxuICAgKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gUmF3IGludGVnZXIgcGFyYW0uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gUGFyYW0gbmFtZSBmb3IgZXJyb3IgbWVzc2FnZXMuXG4gICAqIEByZXR1cm5zIHtudW1iZXIgfCBudWxsfSBQb3NpdGl2ZSBpbnRlZ2VyIHZhbHVlLCBvciBudWxsIHdoZW4gb21pdHRlZC5cbiAgICovXG4gIG9wdGlvbmFsUG9zaXRpdmVJbnRlZ2VyUGFyYW0odmFsdWUsIG5hbWUpIHtcbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gXCJcIikgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IGludGVnZXIgPSBOdW1iZXIodmFsdWUpXG5cbiAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKGludGVnZXIpIHx8IGludGVnZXIgPD0gMCkge1xuICAgICAgdGhyb3cgVmVsb2Npb3VzRXJyb3Iuc2FmZShgJHtuYW1lfSBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlci5gLCB7Y29kZTogXCJzeW5jLWludmFsaWQtY2hhbmdlcy1jdXJzb3JcIn0pXG4gICAgfVxuXG4gICAgcmV0dXJuIGludGVnZXJcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgaGlnaC13YXRlciBjdXJzb3IgdGhhdCBib3VuZHMgdGhlIGN1cnJlbnQgZmVlZCBwYWdlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7aWQ6IHN0cmluZywgc2VydmVyU2VxdWVuY2U6IG51bWJlciwgdXBkYXRlZEF0OiBzdHJpbmd9IHwgbnVsbD59IFNuYXBzaG90IHVwcGVyLWJvdW5kIGN1cnNvci5cbiAgICovXG4gIGFzeW5jIHJlc29sdmVVcFRvQ3Vyc29yKCkge1xuICAgIGNvbnN0IHVwVG9TZXJ2ZXJTZXF1ZW5jZSA9IHRoaXMub3B0aW9uYWxQb3NpdGl2ZUludGVnZXJQYXJhbSh0aGlzLnBhcmFtcy51cFRvU2VydmVyU2VxdWVuY2UsIFwidXBUb1NlcnZlclNlcXVlbmNlXCIpXG5cbiAgICBpZiAodXBUb1NlcnZlclNlcXVlbmNlICE9PSBudWxsICYmIHR5cGVvZiB0aGlzLnBhcmFtcy51cFRvVXBkYXRlZEF0ID09PSBcInN0cmluZ1wiICYmIHR5cGVvZiB0aGlzLnBhcmFtcy51cFRvSWQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHJldHVybiB7aWQ6IHRoaXMucGFyYW1zLnVwVG9JZCwgc2VydmVyU2VxdWVuY2U6IHVwVG9TZXJ2ZXJTZXF1ZW5jZSwgdXBkYXRlZEF0OiB0aGlzLnBhcmFtcy51cFRvVXBkYXRlZEF0fVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGhpcy5wYXJhbXMudXBUb1VwZGF0ZWRBdCA9PT0gXCJzdHJpbmdcIiAmJiB0eXBlb2YgdGhpcy5wYXJhbXMudXBUb0lkID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBjb25zdCB1cFRvUmVjb3JkID0gYXdhaXQgdGhpcy5tb2RlbENsYXNzLmZpbmRCeSh7aWQ6IHRoaXMucGFyYW1zLnVwVG9JZH0pXG5cbiAgICAgIGlmICh1cFRvUmVjb3JkKSByZXR1cm4gdGhpcy5jdXJzb3JGb3JSZWNvcmQodXBUb1JlY29yZClcbiAgICB9XG5cbiAgICBjb25zdCBxdWVyeSA9IHRoaXMuc2NvcGVkUXVlcnkoKVxuICAgIGNvbnN0IHRhYmxlID0gcXVlcnkuZHJpdmVyLnF1b3RlVGFibGUodGhpcy5tb2RlbENsYXNzLnRhYmxlTmFtZSgpKVxuICAgIGNvbnN0IHNlcnZlclNlcXVlbmNlQ29sdW1uID0gcXVlcnkuZHJpdmVyLnF1b3RlQ29sdW1uKFwic2VydmVyX3NlcXVlbmNlXCIpXG4gICAgY29uc3QgbGF0ZXN0UmVjb3JkcyA9IGF3YWl0IHF1ZXJ5XG4gICAgICAub3JkZXIoYCR7dGFibGV9LiR7c2VydmVyU2VxdWVuY2VDb2x1bW59IERFU0NgKVxuICAgICAgLmxpbWl0KDEpXG4gICAgICAudG9BcnJheSgpXG5cbiAgICBpZiAobGF0ZXN0UmVjb3Jkcy5sZW5ndGggPT09IDApIHJldHVybiBudWxsXG5cbiAgICByZXR1cm4gdGhpcy5jdXJzb3JGb3JSZWNvcmQobGF0ZXN0UmVjb3Jkc1swXSlcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIG9yZGVyZWQgYW5kIGN1cnNvci1maWx0ZXJlZCBwYWdlIHF1ZXJ5LlxuICAgKiBAcGFyYW0ge3tsaW1pdDogbnVtYmVyLCB1cFRvQ3Vyc29yOiB7aWQ6IHN0cmluZywgc2VydmVyU2VxdWVuY2U6IG51bWJlciwgdXBkYXRlZEF0OiBzdHJpbmd9fX0gYXJncyAtIFBhZ2UgcXVlcnkgYXJncy5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHR9IFBhZ2UgcXVlcnkuXG4gICAqL1xuICBwYWdlUXVlcnkoe2xpbWl0LCB1cFRvQ3Vyc29yfSkge1xuICAgIGNvbnN0IHF1ZXJ5ID0gdGhpcy5jdXJzb3JGaWx0ZXJlZFF1ZXJ5KHt1cFRvQ3Vyc29yfSlcbiAgICBjb25zdCBkcml2ZXIgPSBxdWVyeS5kcml2ZXJcbiAgICBjb25zdCBzZXJ2ZXJTZXF1ZW5jZUNvbHVtbiA9IGAke2RyaXZlci5xdW90ZVRhYmxlKHRoaXMubW9kZWxDbGFzcy50YWJsZU5hbWUoKSl9LiR7ZHJpdmVyLnF1b3RlQ29sdW1uKFwic2VydmVyX3NlcXVlbmNlXCIpfWBcblxuICAgIHJldHVybiBxdWVyeVxuICAgICAgLm9yZGVyKGAke3NlcnZlclNlcXVlbmNlQ29sdW1ufSBBU0NgKVxuICAgICAgLmxpbWl0KGxpbWl0KVxuICB9XG5cbiAgLyoqXG4gICAqIENvdW50cyB0aGUgc2NvcGUncyBwZW5kaW5nIGNoYW5nZSByb3dzIGZyb20gdGhlIHJlcXVlc3QgY3Vyc29yIHRvIHRoZSBzbmFwc2hvdFxuICAgKiBib3VuZCB3aXRob3V0IG1hdGVyaWFsaXppbmcgdGhlbSwgc28gdGhlIGNsaWVudCBjYW4gcmVuZGVyIGEgc3RhYmxlIFwib2YgWVwiXG4gICAqIHByb2dyZXNzIGRlbm9taW5hdG9yLlxuICAgKiBAcGFyYW0ge3t1cFRvQ3Vyc29yOiB7aWQ6IHN0cmluZywgc2VydmVyU2VxdWVuY2U6IG51bWJlciwgdXBkYXRlZEF0OiBzdHJpbmd9fX0gYXJncyAtIENvdW50IGFyZ3MuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPG51bWJlcj59IFBlbmRpbmcgY2hhbmdlIGNvdW50IGZyb20gdGhlIHJlcXVlc3QgY3Vyc29yLlxuICAgKi9cbiAgYXN5bmMgdG90YWxQZW5kaW5nQ2hhbmdlcyh7dXBUb0N1cnNvcn0pIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5jdXJzb3JGaWx0ZXJlZFF1ZXJ5KHt1cFRvQ3Vyc29yfSkuY291bnQoKVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhIHNjb3BlZCBxdWVyeSB3aXRoIHRoZSBzbmFwc2hvdCB1cHBlciBib3VuZCBhbmQgYWZ0ZXItY3Vyc29yIGZpbHRlcnNcbiAgICogYXBwbGllZCwgYnV0IHdpdGhvdXQgb3JkZXJpbmcgb3IgYSBwYWdlIGxpbWl0LiBTaGFyZWQgYnkgdGhlIHBhZ2UgcmVhZCBhbmQgdGhlXG4gICAqIHRvdGFsLWNvdW50IHNvIGJvdGggY291bnQgdGhlIHNhbWUgc2V0IG9mIHJvd3MuXG4gICAqIEBwYXJhbSB7e3VwVG9DdXJzb3I6IHtpZDogc3RyaW5nLCBzZXJ2ZXJTZXF1ZW5jZTogbnVtYmVyLCB1cGRhdGVkQXQ6IHN0cmluZ319fSBhcmdzIC0gRmlsdGVyIGFyZ3MuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9xdWVyeS9tb2RlbC1jbGFzcy1xdWVyeS5qc1wiKS5kZWZhdWx0fSBDdXJzb3ItZmlsdGVyZWQgcXVlcnkuXG4gICAqL1xuICBjdXJzb3JGaWx0ZXJlZFF1ZXJ5KHt1cFRvQ3Vyc29yfSkge1xuICAgIGNvbnN0IHF1ZXJ5ID0gdGhpcy5zY29wZWRRdWVyeSgpXG4gICAgY29uc3QgZHJpdmVyID0gcXVlcnkuZHJpdmVyXG4gICAgY29uc3QgdGFibGUgPSBkcml2ZXIucXVvdGVUYWJsZSh0aGlzLm1vZGVsQ2xhc3MudGFibGVOYW1lKCkpXG4gICAgY29uc3Qgc2VydmVyU2VxdWVuY2VDb2x1bW4gPSBgJHt0YWJsZX0uJHtkcml2ZXIucXVvdGVDb2x1bW4oXCJzZXJ2ZXJfc2VxdWVuY2VcIil9YFxuICAgIGNvbnN0IHVwZGF0ZWRBdENvbHVtbiA9IGAke3RhYmxlfS4ke2RyaXZlci5xdW90ZUNvbHVtbihcInVwZGF0ZWRfYXRcIil9YFxuICAgIGNvbnN0IGlkQ29sdW1uID0gYCR7dGFibGV9LiR7ZHJpdmVyLnF1b3RlQ29sdW1uKFwiaWRcIil9YFxuXG4gICAgcXVlcnkud2hlcmUoYCR7c2VydmVyU2VxdWVuY2VDb2x1bW59IDw9ICR7ZHJpdmVyLnF1b3RlKHVwVG9DdXJzb3Iuc2VydmVyU2VxdWVuY2UpfWApXG5cbiAgICBjb25zdCBhZnRlclNlcnZlclNlcXVlbmNlID0gdGhpcy5vcHRpb25hbFBvc2l0aXZlSW50ZWdlclBhcmFtKHRoaXMucGFyYW1zLmFmdGVyU2VydmVyU2VxdWVuY2UsIFwiYWZ0ZXJTZXJ2ZXJTZXF1ZW5jZVwiKVxuXG4gICAgaWYgKGFmdGVyU2VydmVyU2VxdWVuY2UgIT09IG51bGwpIHtcbiAgICAgIHF1ZXJ5LndoZXJlKGAke3NlcnZlclNlcXVlbmNlQ29sdW1ufSA+ICR7ZHJpdmVyLnF1b3RlKGFmdGVyU2VydmVyU2VxdWVuY2UpfWApXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5wYXJhbXMuYWZ0ZXJVcGRhdGVkQXQgPT09IFwic3RyaW5nXCIgJiYgdGhpcy5wYXJhbXMuYWZ0ZXJVcGRhdGVkQXQgIT09IFwiXCIpIHtcbiAgICAgIGNvbnN0IGlzUGFnaW5nRXhpc3RpbmdTbmFwc2hvdCA9IHR5cGVvZiB0aGlzLnBhcmFtcy51cFRvVXBkYXRlZEF0ID09PSBcInN0cmluZ1wiICYmIHRoaXMucGFyYW1zLnVwVG9VcGRhdGVkQXQgIT09IFwiXCIgJiYgdHlwZW9mIHRoaXMucGFyYW1zLnVwVG9JZCA9PT0gXCJzdHJpbmdcIiAmJiB0aGlzLnBhcmFtcy51cFRvSWQgIT09IFwiXCJcblxuICAgICAgaWYgKGlzUGFnaW5nRXhpc3RpbmdTbmFwc2hvdCAmJiB0eXBlb2YgdGhpcy5wYXJhbXMuYWZ0ZXJJZCA9PT0gXCJzdHJpbmdcIiAmJiB0aGlzLnBhcmFtcy5hZnRlcklkICE9PSBcIlwiKSB7XG4gICAgICAgIHF1ZXJ5LndoZXJlKGAoJHt1cGRhdGVkQXRDb2x1bW59ID4gJHtkcml2ZXIucXVvdGUodGhpcy5wYXJhbXMuYWZ0ZXJVcGRhdGVkQXQpfSBPUiAoJHt1cGRhdGVkQXRDb2x1bW59ID0gJHtkcml2ZXIucXVvdGUodGhpcy5wYXJhbXMuYWZ0ZXJVcGRhdGVkQXQpfSBBTkQgJHtpZENvbHVtbn0gPiAke2RyaXZlci5xdW90ZSh0aGlzLnBhcmFtcy5hZnRlcklkKX0pKWApXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBxdWVyeS53aGVyZShgJHt1cGRhdGVkQXRDb2x1bW59ID49ICR7ZHJpdmVyLnF1b3RlKHRoaXMucGFyYW1zLmFmdGVyVXBkYXRlZEF0KX1gKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBxdWVyeVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhIGJhc2UgcXVlcnkgd2l0aCBhcHAtb3duZWQgc2NvcGUgYXBwbGllZC5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHR9IFNjb3BlZCBiYXNlIHF1ZXJ5LlxuICAgKi9cbiAgc2NvcGVkUXVlcnkoKSB7XG4gICAgY29uc3QgcXVlcnkgPSB0aGlzLm1vZGVsQ2xhc3Mud2hlcmUoe30pXG5cbiAgICBpZiAodGhpcy5zY29wZVF1ZXJ5KSB0aGlzLnNjb3BlUXVlcnkoe3F1ZXJ5fSlcblxuICAgIHJldHVybiBxdWVyeVxuICB9XG5cbiAgLyoqXG4gICAqIFNlcmlhbGl6ZXMgYSByZWNvcmQgaW50byBhIHRyYW5zcG9ydCBjdXJzb3IuXG4gICAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IHJlY29yZCAtIFN5bmMvY2hhbmdlIHJlY29yZC5cbiAgICogQHJldHVybnMge3tpZDogc3RyaW5nLCBzZXJ2ZXJTZXF1ZW5jZTogbnVtYmVyLCB1cGRhdGVkQXQ6IHN0cmluZ319IEN1cnNvciBmb3Igcm93LlxuICAgKi9cbiAgY3Vyc29yRm9yUmVjb3JkKHJlY29yZCkge1xuICAgIHJldHVybiB7aWQ6IFN0cmluZyh0aGlzLnJlY29yZFZhbHVlKHJlY29yZCwgXCJpZFwiKSksIHNlcnZlclNlcXVlbmNlOiBOdW1iZXIodGhpcy5yZWNvcmRWYWx1ZShyZWNvcmQsIFwic2VydmVyU2VxdWVuY2VcIikpLCB1cGRhdGVkQXQ6IHRoaXMuaXNvRGF0ZSh0aGlzLnJlY29yZFZhbHVlKHJlY29yZCwgXCJ1cGRhdGVkQXRcIikpfVxuICB9XG5cbiAgLyoqXG4gICAqIFNlcmlhbGl6ZXMgYSByZWNvcmQgdXNpbmcgdGhlIHN0YW5kYXJkIHN5bmMgZW52ZWxvcGUgc2hhcGUgcGx1cyB0aGUgc3luY1xuICAgKiBtb2RlbCdzIGRlY2xhcmVkIHNjb3BlLXBhcnRpdGlvbiBhdHRyaWJ1dGVzIChgc3RhdGljIHN5bmNTY29wZUF0dHJpYnV0ZXNgKSxcbiAgICogZWFjaCBlbWl0dGVkIHVuZGVyIGl0cyBvd24gYXR0cmlidXRlIG5hbWUuIE1vZGVscyBkZWNsYXJpbmcgbm8gc2NvcGVcbiAgICogYXR0cmlidXRlcyBrZWVwIHRoZSBkZXByZWNhdGVkIDEuMC41MDMgd2lyZSBhbmQgZW1pdCBgZXZlbnRJZGAuIEtleXMgYXJlXG4gICAqIHNvcnRlZCBzbyBhIGRlY2xhcmVkIGBbXCJldmVudElkXCJdYCBwYXJ0aXRpb24gc3RheXMgYnl0ZS1pZGVudGljYWwgd2l0aCB0aGVcbiAgICogMS4wLjUwMyB3aXJlLlxuICAgKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSByZWNvcmQgLSBTeW5jL2NoYW5nZSByZWNvcmQuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gRGVmYXVsdCBzZXJpYWxpemVkIHJvdy5cbiAgICovXG4gIGRlZmF1bHRTZXJpYWxpemVSZWNvcmQocmVjb3JkKSB7XG4gICAgY29uc3Qgc2NvcGVBdHRyaWJ1dGVzID0gZGVjbGFyZWRTeW5jU2NvcGVBdHRyaWJ1dGVzKHRoaXMubW9kZWxDbGFzcylcbiAgICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSAqL1xuICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSB7XG4gICAgICBkYXRhOiB0aGlzLnJlY29yZERhdGEocmVjb3JkKSxcbiAgICAgIGlkOiB0aGlzLnJlY29yZFZhbHVlKHJlY29yZCwgXCJpZFwiKSxcbiAgICAgIHJlc291cmNlSWQ6IHRoaXMucmVjb3JkVmFsdWUocmVjb3JkLCBcInJlc291cmNlSWRcIiksXG4gICAgICByZXNvdXJjZVR5cGU6IHRoaXMucmVjb3JkVmFsdWUocmVjb3JkLCBcInJlc291cmNlVHlwZVwiKSxcbiAgICAgIHNlcnZlclNlcXVlbmNlOiB0aGlzLnJlY29yZFZhbHVlKHJlY29yZCwgXCJzZXJ2ZXJTZXF1ZW5jZVwiKSxcbiAgICAgIHN5bmNUeXBlOiB0aGlzLnJlY29yZFZhbHVlKHJlY29yZCwgXCJzeW5jVHlwZVwiKSxcbiAgICAgIHVwZGF0ZWRBdDogdGhpcy5pc29EYXRlKHRoaXMucmVjb3JkVmFsdWUocmVjb3JkLCBcInVwZGF0ZWRBdFwiKSlcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHNjb3BlQXR0cmlidXRlIG9mIHNjb3BlQXR0cmlidXRlcyB8fCBbXCJldmVudElkXCJdKSB7XG4gICAgICBzZXJpYWxpemVkW3Njb3BlQXR0cmlidXRlXSA9IHRoaXMucmVjb3JkVmFsdWUocmVjb3JkLCBzY29wZUF0dHJpYnV0ZSlcbiAgICB9XG5cbiAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKE9iamVjdC5lbnRyaWVzKHNlcmlhbGl6ZWQpLnNvcnQoKFtsZWZ0S2V5XSwgW3JpZ2h0S2V5XSkgPT4gbGVmdEtleS5sb2NhbGVDb21wYXJlKHJpZ2h0S2V5KSkpXG4gIH1cblxuICAvKipcbiAgICogUmVhZHMgYW5kIHBhcnNlcyB0aGUgcmVjb3JkIGRhdGEgcGF5bG9hZC5cbiAgICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gcmVjb3JkIC0gU3luYy9jaGFuZ2UgcmVjb3JkLlxuICAgKiBAcmV0dXJucyB7dW5rbm93bn0gUGFyc2VkIGRhdGEgdmFsdWUuXG4gICAqL1xuICByZWNvcmREYXRhKHJlY29yZCkge1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLnJlY29yZFZhbHVlKHJlY29yZCwgXCJkYXRhXCIpXG5cbiAgICBpZiAoZGF0YSA9PT0gXCJcIiB8fCBkYXRhID09PSBudWxsIHx8IGRhdGEgPT09IHVuZGVmaW5lZCkgcmV0dXJuIG51bGxcbiAgICByZXR1cm4gZGVjb2RlUmVwbGF5UGVyc2lzdGVkRGF0YShkYXRhKS5wYXlsb2FkXG4gIH1cblxuICAvKipcbiAgICogUmVhZHMgYSB2YWx1ZSBmcm9tIGVpdGhlciBhIHJlY29yZCBhY2Nlc3NvciBtZXRob2Qgb3IgcGxhaW4gcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IHJlY29yZCAtIFN5bmMvY2hhbmdlIHJlY29yZC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBDYW1lbC1jYXNlZCB2YWx1ZS9tZXRob2QgbmFtZS5cbiAgICogQHJldHVybnMge3Vua25vd259IFJlY29yZCB2YWx1ZS5cbiAgICovXG4gIHJlY29yZFZhbHVlKHJlY29yZCwgbmFtZSkge1xuICAgIGlmICghcmVjb3JkIHx8IHR5cGVvZiByZWNvcmQgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlN5bmMgY2hhbmdlcyByb3cgbXVzdCBiZSBhbiBvYmplY3QuXCIpXG4gICAgfVxuXG4gICAgY29uc3QgcmVjb3JkT2JqZWN0ID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59ICovIChyZWNvcmQpXG4gICAgY29uc3QgbWV0aG9kID0gcmVjb3JkT2JqZWN0W25hbWVdXG4gICAgY29uc3QgdmFsdWUgPSB0eXBlb2YgbWV0aG9kID09PSBcImZ1bmN0aW9uXCIgPyBtZXRob2QuY2FsbChyZWNvcmQpIDogbWV0aG9kXG5cbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBTeW5jIGNoYW5nZXMgcm93IGlzIG1pc3NpbmcgJHtuYW1lfS5gKVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGEgZGF0ZS1saWtlIHZhbHVlIHRvIGFuIElTTyBzdHJpbmcuXG4gICAqIEBwYXJhbSB7RGF0ZSB8IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQgfCB1bmtub3dufSB2YWx1ZSAtIERhdGUgdmFsdWUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IElTTyBkYXRlLlxuICAgKi9cbiAgaXNvRGF0ZSh2YWx1ZSkge1xuICAgIGNvbnN0IGRhdGUgPSB2YWx1ZSBpbnN0YW5jZW9mIERhdGUgPyB2YWx1ZSA6IG5ldyBEYXRlKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiB8fCB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgPyB2YWx1ZSA6IDApXG5cbiAgICBpZiAoTnVtYmVyLmlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgdGhyb3cgVmVsb2Npb3VzRXJyb3Iuc2FmZShcIlN5bmMgY2hhbmdlcyByb3cgaGFzIGFuIGludmFsaWQgdXBkYXRlZF9hdCB2YWx1ZS5cIiwge2NvZGU6IFwic3luYy1pbnZhbGlkLWNoYW5nZXMtcm93XCJ9KVxuICAgIH1cblxuICAgIHJldHVybiBkYXRlLnRvSVNPU3RyaW5nKClcbiAgfVxufVxuIl19
@@ -34,9 +34,10 @@ export default class SyncModelChangeFeedService {
34
34
 
35
35
  /**
36
36
  * Builds a stable change-feed page. The additive `total` is the scope's pending
37
- * change count from the request cursor to the snapshot bound (a COUNT, not a
38
- * materialized read), so a client can render a "synced of total" progress bar;
39
- * older clients ignore it.
37
+ * change count from the request cursor to the snapshot bound, so a client can
38
+ * render a "synced of total" progress bar; older clients ignore it. The count
39
+ * query only runs when the page read cannot answer it: a sequence cursor whose
40
+ * page is short of the limit has already materialized the whole remaining set.
40
41
  * @returns {Promise<{status: string, nextCursor: {id: string, serverSequence: number, updatedAt: string} | null, syncs: Array<Record<string, unknown>>, total: number, upToCursor: {id: string, serverSequence: number, updatedAt: string} | null}>} Change-feed page result.
41
42
  */
42
43
  async changes() {
@@ -45,10 +46,22 @@ export default class SyncModelChangeFeedService {
45
46
 
46
47
  if (!upToCursor) return {status: "success", nextCursor: null, syncs: [], total: 0, upToCursor: null}
47
48
 
48
- const total = await this.totalPendingChanges({upToCursor})
49
- const query = this.pageQuery({limit, upToCursor})
50
- const records = await query.toArray()
49
+ const afterServerSequence = this.optionalPositiveIntegerParam(this.params.afterServerSequence, "afterServerSequence")
50
+
51
+ // A cursor at or past the scope's snapshot bound cannot have pending rows.
52
+ // Answering here skips both the page read and the count, which would otherwise
53
+ // run against an empty sequence range on every caught-up poll. A multi-scope
54
+ // client sends its global cursor to each scope, so a scope whose own sequences
55
+ // are behind that cursor lands here on nearly every request.
56
+ if (afterServerSequence !== null && afterServerSequence >= upToCursor.serverSequence) {
57
+ return {status: "success", nextCursor: upToCursor, syncs: [], total: 0, upToCursor}
58
+ }
59
+
60
+ const records = await this.pageQuery({limit, upToCursor}).toArray()
51
61
  const nextCursor = records.length > 0 ? this.cursorForRecord(records[records.length - 1]) : upToCursor
62
+ const total = afterServerSequence !== null && records.length < limit
63
+ ? records.length
64
+ : await this.totalPendingChanges({upToCursor})
52
65
 
53
66
  return {
54
67
  status: "success",
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "velocious": "build/bin/velocious.js"
4
4
  },
5
5
  "name": "velocious",
6
- "version": "1.0.711",
6
+ "version": "1.0.713",
7
7
  "main": "build/index.js",
8
8
  "types": "build/index.d.ts",
9
9
  "files": [
@@ -12,6 +12,7 @@ import {
12
12
  AdvisoryLockServiceUnavailableError,
13
13
  advisoryLockBackendUnavailable
14
14
  } from "./advisory-lock-errors.js"
15
+ import {emitAdvisoryLockFallbackReport} from "./advisory-lock-telemetry.js"
15
16
 
16
17
  /**
17
18
  * Provenance of one advisory-lock acquisition (STC-210 design §3): every
@@ -407,17 +408,12 @@ export default class AdvisoryLockRunner {
407
408
  */
408
409
  reportAdvisoryLockFallback({lockName, reason, servedBy}) {
409
410
  const policy = resolveAdvisoryLockBackendPolicy(lockName, this.configuration.getAdvisoryLockPolicy())
410
- const payload = {
411
- context: "advisory-lock-fallback",
411
+ emitAdvisoryLockFallbackReport(this.configuration, {
412
412
  lockName,
413
413
  preferredTier: policy.preferredTier,
414
414
  reason,
415
415
  servedBy
416
- }
417
- const errorEvents = this.configuration.getErrorEvents()
418
-
419
- errorEvents.emit("framework-error", payload)
420
- errorEvents.emit("all-error", {...payload, errorType: "framework-error"})
416
+ })
421
417
  }
422
418
 
423
419
  /**
@@ -6,9 +6,9 @@
6
6
  * A lock convoy is only fixable when it is *attributable*: which lock name was
7
7
  * contended, on which backend tier, for how long, and who held it. These reports
8
8
  * fire on the acquisition/release events themselves — never from a periodic
9
- * scanner — so a contended lock in production surfaces on the framework-error
10
- * channel with the holder identity available on that tier at that moment,
11
- * without SSH forensics.
9
+ * scanner — so a contended lock in production surfaces on the telemetry channel
10
+ * with the holder identity available on that tier at that moment, without SSH
11
+ * forensics.
12
12
  *
13
13
  * Three events, each with its own threshold (all configurable per database via
14
14
  * `advisoryLockTelemetry`, see `docs/advisory-locks.md`):
@@ -128,3 +128,39 @@ export function emitAdvisoryLockTelemetryReport(configuration, report) {
128
128
  console.error(`[velocious advisory-lock-telemetry ${report.event}] lock=${JSON.stringify(report.lockName)} tier=${report.backendTier} durationMs=${report.durationMs}${report.outcome ? ` outcome=${report.outcome}` : ""}${report.holderConnectionId ? ` holderConnectionId=${report.holderConnectionId}` : ""}${report.holderId ? ` holderId=${report.holderId}` : ""} — subscribe via configuration.getTelemetryEvents().on("telemetry", …) to route these measurements to your metrics`)
129
129
  }
130
130
  }
131
+
132
+ /**
133
+ * Reports one acquisition served below the lock name's preferred tier
134
+ * (design §3): the caller wanted the lock server and got the database, so the
135
+ * downgrade must be visible without being mistaken for a failure. Fallbacks are
136
+ * measurements, not errors, so they stay off `framework-error` and its bug
137
+ * reporters (same contract as the duration telemetry).
138
+ * @param {import("../configuration.js").default} configuration - Owning configuration.
139
+ * @param {{lockName: string, preferredTier: string, reason: string, servedBy: string}} report - Fallback details.
140
+ * @returns {void}
141
+ */
142
+ export function emitAdvisoryLockFallbackReport(configuration, report) {
143
+ /** @type {import("eventemitter3").EventEmitter | undefined} */
144
+ let telemetryEvents
145
+
146
+ try {
147
+ telemetryEvents = configuration?.getTelemetryEvents()
148
+ } catch {
149
+ return // No configuration to report through — never break lock handling.
150
+ }
151
+
152
+ if (!telemetryEvents) return
153
+
154
+ const payload = {context: "advisory-lock-fallback", ...report}
155
+ const hasListener = telemetryEvents.listenerCount("telemetry") > 0
156
+
157
+ try {
158
+ telemetryEvents.emit("telemetry", payload)
159
+ } catch {
160
+ // A broken listener must never surface as a lock failure.
161
+ }
162
+
163
+ if (!hasListener) {
164
+ console.error(`[velocious advisory-lock-fallback] lock=${JSON.stringify(report.lockName)} preferredTier=${report.preferredTier} servedBy=${report.servedBy} reason=${report.reason}`)
165
+ }
166
+ }
@@ -34,9 +34,10 @@ export default class SyncModelChangeFeedService {
34
34
 
35
35
  /**
36
36
  * Builds a stable change-feed page. The additive `total` is the scope's pending
37
- * change count from the request cursor to the snapshot bound (a COUNT, not a
38
- * materialized read), so a client can render a "synced of total" progress bar;
39
- * older clients ignore it.
37
+ * change count from the request cursor to the snapshot bound, so a client can
38
+ * render a "synced of total" progress bar; older clients ignore it. The count
39
+ * query only runs when the page read cannot answer it: a sequence cursor whose
40
+ * page is short of the limit has already materialized the whole remaining set.
40
41
  * @returns {Promise<{status: string, nextCursor: {id: string, serverSequence: number, updatedAt: string} | null, syncs: Array<Record<string, unknown>>, total: number, upToCursor: {id: string, serverSequence: number, updatedAt: string} | null}>} Change-feed page result.
41
42
  */
42
43
  async changes() {
@@ -45,10 +46,22 @@ export default class SyncModelChangeFeedService {
45
46
 
46
47
  if (!upToCursor) return {status: "success", nextCursor: null, syncs: [], total: 0, upToCursor: null}
47
48
 
48
- const total = await this.totalPendingChanges({upToCursor})
49
- const query = this.pageQuery({limit, upToCursor})
50
- const records = await query.toArray()
49
+ const afterServerSequence = this.optionalPositiveIntegerParam(this.params.afterServerSequence, "afterServerSequence")
50
+
51
+ // A cursor at or past the scope's snapshot bound cannot have pending rows.
52
+ // Answering here skips both the page read and the count, which would otherwise
53
+ // run against an empty sequence range on every caught-up poll. A multi-scope
54
+ // client sends its global cursor to each scope, so a scope whose own sequences
55
+ // are behind that cursor lands here on nearly every request.
56
+ if (afterServerSequence !== null && afterServerSequence >= upToCursor.serverSequence) {
57
+ return {status: "success", nextCursor: upToCursor, syncs: [], total: 0, upToCursor}
58
+ }
59
+
60
+ const records = await this.pageQuery({limit, upToCursor}).toArray()
51
61
  const nextCursor = records.length > 0 ? this.cursorForRecord(records[records.length - 1]) : upToCursor
62
+ const total = afterServerSequence !== null && records.length < limit
63
+ ? records.length
64
+ : await this.totalPendingChanges({upToCursor})
52
65
 
53
66
  return {
54
67
  status: "success",