@workflow/core 4.8.0 → 4.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,11 @@
1
1
  import type { Event } from '@workflow/world';
2
+ /**
3
+ * Delay before firing the deferred unconsumed-event check after the promise
4
+ * queue has drained. Must be long enough for cross-VM microtask chains to
5
+ * propagate (resolve in host → workflow code in VM → subscribe call back
6
+ * in host). Any subscribe() arriving during this window cancels the check.
7
+ */
8
+ export declare const DEFERRED_CHECK_DELAY_MS = 100;
2
9
  export declare enum EventConsumerResult {
3
10
  /**
4
11
  * Callback consumed the event, but should not be removed from the callbacks list
@@ -36,6 +43,16 @@ export interface EventsConsumerOptions {
36
43
  * deserialization delays the resolve() that triggers the next subscribe().
37
44
  */
38
45
  getPromiseQueue: () => Promise<void>;
46
+ /**
47
+ * Whether no data delivery is in flight (`isDeliveryIdle` in private.ts).
48
+ * The unconsumed-event check waits for this before it fires: a delivery in
49
+ * flight means the workflow VM is mid-reaction, and an event it has not
50
+ * claimed yet is an event it has not reached yet.
51
+ *
52
+ * Defaults to always-idle so the tests that drive a consumer with no
53
+ * orchestrator context keep the pre-existing timing.
54
+ */
55
+ isDeliveryIdle?: () => boolean;
39
56
  }
40
57
  export declare class EventsConsumer {
41
58
  eventIndex: number;
@@ -44,6 +61,7 @@ export declare class EventsConsumer {
44
61
  private onConsumedEvent?;
45
62
  private onUnconsumedEvent;
46
63
  private getPromiseQueue;
64
+ private isDeliveryIdle;
47
65
  private pendingUnconsumedCheck;
48
66
  private pendingUnconsumedTimeout;
49
67
  private unconsumedCheckVersion;
@@ -69,6 +87,28 @@ export declare class EventsConsumer {
69
87
  */
70
88
  private consumeOne;
71
89
  private handleUnconsumed;
90
+ /**
91
+ * Run `fn` once no data delivery is in flight, polling the way
92
+ * `scheduleWhenIdle` does: let the promise queue drain, re-check a timer
93
+ * tick later, repeat.
94
+ *
95
+ * Without this the check is a bet that every delivery the walk is running
96
+ * ahead of lands inside a fixed window. Consumption is synchronous while the
97
+ * resolution it triggers is not: a step result hydrates in the host, resolves
98
+ * from a detached continuation behind `awaitEarlierDeliveries`, and only then
99
+ * does VM code run far enough to subscribe the next consumer. Replaying a
100
+ * batch of N parallel step results leaves N-1 of them on that detached path
101
+ * with the queue already drained, so the walk sits on the ordered event the
102
+ * VM is about to draw and the window is the only thing standing between a
103
+ * healthy run and `ReplayDivergenceError`. On a backend whose deliveries take
104
+ * longer than the window, that bet loses.
105
+ *
106
+ * Termination is `hasParkedCommittedDelivery`'s: it counts only deliveries
107
+ * that resolve on their own, so nothing here can gate its own retirement. A
108
+ * genuinely orphaned event has no delivery to wait on and reaches `fn` on the
109
+ * first poll.
110
+ */
111
+ private whenDeliveryIdle;
72
112
  }
73
113
  export {};
74
114
  //# sourceMappingURL=events-consumer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"events-consumer.d.ts","sourceRoot":"","sources":["../src/events-consumer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAG7C,oBAAY,mBAAmB;IAC7B;;OAEG;IACH,QAAQ,IAAA;IACR;;OAEG;IACH,WAAW,IAAA;IACX;;OAEG;IACH,QAAQ,IAAA;CACT;AAED,KAAK,qBAAqB,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,KAAK,mBAAmB,CAAC;AAE1E,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACzC;;;;;;OAMG;IACH,iBAAiB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAC1C;;;;;OAKG;IACH,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAED,qBAAa,cAAc;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,CAAM;IAC9B,QAAQ,CAAC,SAAS,EAAE,qBAAqB,EAAE,CAAM;IACjD,OAAO,CAAC,eAAe,CAAC,CAAyB;IACjD,OAAO,CAAC,iBAAiB,CAAyB;IAClD,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,sBAAsB,CAA8B;IAC5D,OAAO,CAAC,wBAAwB,CAA8C;IAC9E,OAAO,CAAC,sBAAsB,CAAK;gBAEvB,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,qBAAqB;IAQ3D;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,EAAE,qBAAqB;IAgBnC,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,OAAO,CA0Bb;IAEF;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAgClB,OAAO,CAAC,gBAAgB;CAqCzB"}
1
+ {"version":3,"file":"events-consumer.d.ts","sourceRoot":"","sources":["../src/events-consumer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAG7C;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C,oBAAY,mBAAmB;IAC7B;;OAEG;IACH,QAAQ,IAAA;IACR;;OAEG;IACH,WAAW,IAAA;IACX;;OAEG;IACH,QAAQ,IAAA;CACT;AAED,KAAK,qBAAqB,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,KAAK,mBAAmB,CAAC;AAE1E,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACzC;;;;;;OAMG;IACH,iBAAiB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAC1C;;;;;OAKG;IACH,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC;CAChC;AAED,qBAAa,cAAc;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,CAAM;IAC9B,QAAQ,CAAC,SAAS,EAAE,qBAAqB,EAAE,CAAM;IACjD,OAAO,CAAC,eAAe,CAAC,CAAyB;IACjD,OAAO,CAAC,iBAAiB,CAAyB;IAClD,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,sBAAsB,CAA8B;IAC5D,OAAO,CAAC,wBAAwB,CAA8C;IAC9E,OAAO,CAAC,sBAAsB,CAAK;gBAEvB,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,qBAAqB;IAS3D;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,EAAE,qBAAqB;IAgBnC,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,OAAO,CA0Bb;IAEF;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAgClB,OAAO,CAAC,gBAAgB;IA2CxB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,gBAAgB;CAqBzB"}
@@ -1,4 +1,11 @@
1
1
  import { eventsLogger } from './logger.js';
2
+ /**
3
+ * Delay before firing the deferred unconsumed-event check after the promise
4
+ * queue has drained. Must be long enough for cross-VM microtask chains to
5
+ * propagate (resolve in host → workflow code in VM → subscribe call back
6
+ * in host). Any subscribe() arriving during this window cancels the check.
7
+ */
8
+ export const DEFERRED_CHECK_DELAY_MS = 100;
2
9
  export var EventConsumerResult;
3
10
  (function (EventConsumerResult) {
4
11
  /**
@@ -21,6 +28,7 @@ export class EventsConsumer {
21
28
  onConsumedEvent;
22
29
  onUnconsumedEvent;
23
30
  getPromiseQueue;
31
+ isDeliveryIdle;
24
32
  pendingUnconsumedCheck = null;
25
33
  pendingUnconsumedTimeout = null;
26
34
  unconsumedCheckVersion = 0;
@@ -30,6 +38,7 @@ export class EventsConsumer {
30
38
  this.onConsumedEvent = options.onConsumedEvent;
31
39
  this.onUnconsumedEvent = options.onUnconsumedEvent;
32
40
  this.getPromiseQueue = options.getPromiseQueue;
41
+ this.isDeliveryIdle = options.isDeliveryIdle ?? (() => true);
33
42
  }
34
43
  /**
35
44
  * Registers a callback function to be called after an event has been consumed
@@ -150,23 +159,70 @@ export class EventsConsumer {
150
159
  () => new Promise((resolve) => setTimeout(resolve, 0)))
151
160
  .then(() => this.getPromiseQueue())
152
161
  .then(() => {
153
- // Use a delayed setTimeout after the queue drains. The delay must be
154
- // long enough for promise chains to propagate across the VM boundary
155
- // (from resolve() in the host context through to the workflow code
156
- // calling subscribe() in the VM context). Node.js does not guarantee
157
- // that setTimeout(0) fires after all cross-context microtasks settle,
158
- // so we use a small but non-zero delay. Any subscribe() call that
159
- // arrives during this window will cancel the check via version
160
- // invalidation + clearTimeout.
161
- this.pendingUnconsumedTimeout = setTimeout(() => {
162
- this.pendingUnconsumedTimeout = null;
163
- if (this.unconsumedCheckVersion === checkVersion) {
164
- this.pendingUnconsumedCheck = null;
165
- this.onUnconsumedEvent(currentEvent);
166
- }
167
- }, 100);
162
+ // Wait out any delivery still in flight before starting the timer.
163
+ // The queue draining says the host has no hydration work left; it
164
+ // does not say the VM has finished reacting to what was hydrated.
165
+ this.whenDeliveryIdle(checkVersion, () => {
166
+ // Use a delayed setTimeout once deliveries are idle. The delay must
167
+ // be long enough for promise chains to propagate across the VM
168
+ // boundary (from resolve() in the host context through to the
169
+ // workflow code calling subscribe() in the VM context). Node.js
170
+ // does not guarantee that setTimeout(0) fires after all
171
+ // cross-context microtasks settle, so we use a small but non-zero
172
+ // delay. Any subscribe() call that arrives during this window will
173
+ // cancel the check via version invalidation + clearTimeout.
174
+ this.pendingUnconsumedTimeout = setTimeout(() => {
175
+ this.pendingUnconsumedTimeout = null;
176
+ if (this.unconsumedCheckVersion === checkVersion) {
177
+ this.pendingUnconsumedCheck = null;
178
+ this.onUnconsumedEvent(currentEvent);
179
+ }
180
+ }, DEFERRED_CHECK_DELAY_MS);
181
+ });
168
182
  });
169
183
  }
170
184
  }
185
+ /**
186
+ * Run `fn` once no data delivery is in flight, polling the way
187
+ * `scheduleWhenIdle` does: let the promise queue drain, re-check a timer
188
+ * tick later, repeat.
189
+ *
190
+ * Without this the check is a bet that every delivery the walk is running
191
+ * ahead of lands inside a fixed window. Consumption is synchronous while the
192
+ * resolution it triggers is not: a step result hydrates in the host, resolves
193
+ * from a detached continuation behind `awaitEarlierDeliveries`, and only then
194
+ * does VM code run far enough to subscribe the next consumer. Replaying a
195
+ * batch of N parallel step results leaves N-1 of them on that detached path
196
+ * with the queue already drained, so the walk sits on the ordered event the
197
+ * VM is about to draw and the window is the only thing standing between a
198
+ * healthy run and `ReplayDivergenceError`. On a backend whose deliveries take
199
+ * longer than the window, that bet loses.
200
+ *
201
+ * Termination is `hasParkedCommittedDelivery`'s: it counts only deliveries
202
+ * that resolve on their own, so nothing here can gate its own retirement. A
203
+ * genuinely orphaned event has no delivery to wait on and reaches `fn` on the
204
+ * first poll.
205
+ */
206
+ whenDeliveryIdle(checkVersion, fn) {
207
+ const poll = () => {
208
+ this.pendingUnconsumedTimeout = null;
209
+ if (this.unconsumedCheckVersion !== checkVersion) {
210
+ return;
211
+ }
212
+ if (this.isDeliveryIdle()) {
213
+ fn();
214
+ return;
215
+ }
216
+ this.getPromiseQueue().then(() => {
217
+ if (this.unconsumedCheckVersion !== checkVersion) {
218
+ return;
219
+ }
220
+ // Held in the same field the fired check uses so subscribe() cancels a
221
+ // poll in progress exactly as it cancels the check itself.
222
+ this.pendingUnconsumedTimeout = setTimeout(poll, 0);
223
+ });
224
+ };
225
+ poll();
226
+ }
171
227
  }
172
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnRzLWNvbnN1bWVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2V2ZW50cy1jb25zdW1lci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTNDLE1BQU0sQ0FBTixJQUFZLG1CQWFYO0FBYkQsV0FBWSxtQkFBbUI7SUFDN0I7O09BRUc7SUFDSCxxRUFBUSxDQUFBO0lBQ1I7O09BRUc7SUFDSCwyRUFBVyxDQUFBO0lBQ1g7O09BRUc7SUFDSCxxRUFBUSxDQUFBO0FBQ1YsQ0FBQyxFQWJXLG1CQUFtQixLQUFuQixtQkFBbUIsUUFhOUI7QUE0QkQsTUFBTSxPQUFPLGNBQWM7SUFDekIsVUFBVSxDQUFTO0lBQ1YsTUFBTSxHQUFZLEVBQUUsQ0FBQztJQUNyQixTQUFTLEdBQTRCLEVBQUUsQ0FBQztJQUN6QyxlQUFlLENBQTBCO0lBQ3pDLGlCQUFpQixDQUF5QjtJQUMxQyxlQUFlLENBQXNCO0lBQ3JDLHNCQUFzQixHQUF5QixJQUFJLENBQUM7SUFDcEQsd0JBQXdCLEdBQXlDLElBQUksQ0FBQztJQUN0RSxzQkFBc0IsR0FBRyxDQUFDLENBQUM7SUFFbkMsWUFBWSxNQUFlLEVBQUUsT0FBOEI7UUFDekQsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUM7UUFDcEIsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO1FBQy9DLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7UUFDbkQsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO0lBQ2pELENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILFNBQVMsQ0FBQyxFQUF5QjtRQUNqQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN4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LElBQUksQ0FBQyxzQkFBc0IsS0FBSyxZQUFZLEVBQUUsQ0FBQzt3QkFDakQsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksQ0FBQzt3QkFDbkMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxDQUFDO29CQUN2QyxDQUFDO2dCQUNILENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNWLENBQUMsQ0FBQyxDQUFDO1FBQ1AsQ0FBQztJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRXZlbnQgfSBmcm9tICdAd29ya2Zsb3cvd29ybGQnO1xuaW1wb3J0IHsgZXZlbnRzTG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXIuanMnO1xuXG5leHBvcnQgZW51bSBFdmVudENvbnN1bWVyUmVzdWx0IHtcbiAgLyoqXG4gICAqIENhbGxiYWNrIGNvbnN1bWVkIHRoZSBldmVudCwgYnV0IHNob3VsZCBub3QgYmUgcmVtb3ZlZCBmcm9tIHRoZSBjYWxsYmFja3MgbGlzdFxuICAgKi9cbiAgQ29uc3VtZWQsXG4gIC8qKlxuICAgKiBDYWxsYmFjayBkaWQgbm90IGNvbnN1bWUgdGhlIGV2ZW50LCBzbyBpdCBzaG91bGQgYmUgcGFzc2VkIHRvIHRoZSBuZXh0IGNhbGxiYWNrXG4gICAqL1xuICBOb3RDb25zdW1lZCxcbiAgLyoqXG4gICAqIENhbGxiYWNrIGNvbnN1bWVkIHRoZSBldmVudCwgYW5kIHNob3VsZCBiZSByZW1vdmVkIGZyb20gdGhlIGNhbGxiYWNrcyBsaXN0XG4gICAqL1xuICBGaW5pc2hlZCxcbn1cblxudHlwZSBFdmVudENvbnN1bWVyQ2FsbGJhY2sgPSAoZXZlbnQ6IEV2ZW50IHwgbnVsbCkgPT4gRXZlbnRDb25zdW1lclJlc3VsdDtcblxuZXhwb3J0IGludGVyZmFjZSBFdmVudHNDb25zdW1lck9wdGlvbnMge1xuICAvKipcbiAgICogQ2FsbGJhY2sgaW52b2tlZCBhZnRlciBhbiBldmVudCBoYXMgYmVlbiBjb25zdW1lZC4gQ29uc3VtZXJzIHN1Y2ggYXMgdGhlXG4gICAqIGRldGVybWluaXN0aWMgd29ya2Zsb3cgY2xvY2sgbXVzdCBub3Qgb2JzZXJ2ZSBldmVudHMgdGhhdCBhcmUgbWVyZWx5XG4gICAqIGluc3BlY3RlZCB3aGlsZSB3YWl0aW5nIGZvciB1c2VyIGNvZGUgdG8gc3Vic2NyaWJlIHRvIHRoZSBuZXh0IG9wZXJhdGlvbi5cbiAgICovXG4gIG9uQ29uc3VtZWRFdmVudD86IChldmVudDogRXZlbnQpID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBDYWxsYmFjayBpbnZva2VkIHdoZW4gYSBub24tbnVsbCBldmVudCBjYW5ub3QgYmUgY29uc3VtZWQgYnkgYW55IHJlZ2lzdGVyZWRcbiAgICogY2FsbGJhY2ssIGluZGljYXRpbmcgYW4gb3JwaGFuZWQgb3IgaW52YWxpZCBldmVudCBpbiB0aGUgZXZlbnQgbG9nLiBUaGVcbiAgICogY2hlY2sgaXMgZGVmZXJyZWQgdW50aWwgYWZ0ZXIgdGhlIHByb21pc2UgcXVldWUgaGFzIGRyYWluZWQsIGVuc3VyaW5nIHRoYXRcbiAgICogYW55IHBlbmRpbmcgYXN5bmMgd29yayAoZS5nLiwgZGVzZXJpYWxpemF0aW9uL2RlY3J5cHRpb24pIGNvbXBsZXRlcyBhbmRcbiAgICogZG93bnN0cmVhbSBzdWJzY3JpYmUoKSBjYWxscyBoYXZlIGEgY2hhbmNlIHRvIGNhbmNlbCB0aGUgY2hlY2sgZmlyc3QuXG4gICAqL1xuICBvblVuY29uc3VtZWRFdmVudDogKGV2ZW50OiBFdmVudCkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGN1cnJlbnQgcHJvbWlzZSBxdWV1ZS4gVGhlIHVuY29uc3VtZWQgZXZlbnQgY2hlY2sgaXMgY2hhaW5lZFxuICAgKiBvbnRvIHRoaXMgcXVldWUgc28gaXQgb25seSBmaXJlcyBhZnRlciBhbGwgcGVuZGluZyBhc3luYyB3b3JrIChlLmcuLFxuICAgKiBkZXNlcmlhbGl6YXRpb24pIGhhcyBjb21wbGV0ZWQuIFRoaXMgcHJldmVudHMgZmFsc2UgcG9zaXRpdmVzIHdoZW4gYXN5bmNcbiAgICogZGVzZXJpYWxpemF0aW9uIGRlbGF5cyB0aGUgcmVzb2x2ZSgpIHRoYXQgdHJpZ2dlcnMgdGhlIG5leHQgc3Vic2NyaWJlKCkuXG4gICAqL1xuICBnZXRQcm9taXNlUXVldWU6ICgpID0+IFByb21pc2U8dm9pZD47XG59XG5cbmV4cG9ydCBjbGFzcyBFdmVudHNDb25zdW1lciB7XG4gIGV2ZW50SW5kZXg6IG51bWJlcjtcbiAgcmVhZG9ubHkgZXZlbnRzOiBFdmVudFtdID0gW107XG4gIHJlYWRvbmx5IGNhbGxiYWNrczogRXZlbnRDb25zdW1lckNhbGxiYWNrW10gPSBbXTtcbiAgcHJpdmF0ZSBvbkNvbnN1bWVkRXZlbnQ/OiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkO1xuICBwcml2YXRlIG9uVW5jb25zdW1lZEV2ZW50OiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkO1xuICBwcml2YXRlIGdldFByb21pc2VRdWV1ZTogKCkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgcHJpdmF0ZSBwZW5kaW5nVW5jb25zdW1lZENoZWNrOiBQcm9taXNlPHZvaWQ+IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcGVuZGluZ1VuY29uc3VtZWRUaW1lb3V0OiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHVuY29uc3VtZWRDaGVja1ZlcnNpb24gPSAwO1xuXG4gIGNvbnN0cnVjdG9yKGV2ZW50czogRXZlbnRbXSwgb3B0aW9uczogRXZlbnRzQ29uc3VtZXJPcHRpb25zKSB7XG4gICAgdGhpcy5ldmVudHMgPSBldmVudHM7XG4gICAgdGhpcy5ldmVudEluZGV4ID0gMDtcbiAgICB0aGlzLm9uQ29uc3VtZWRFdmVudCA9IG9wdGlvbnMub25Db25zdW1lZEV2ZW50O1xuICAgIHRoaXMub25VbmNvbnN1bWVkRXZlbnQgPSBvcHRpb25zLm9uVW5jb25zdW1lZEV2ZW50O1xuICAgIHRoaXMuZ2V0UHJvbWlzZVF1ZXVlID0gb3B0aW9ucy5nZXRQcm9taXNlUXVldWU7XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGEgY2FsbGJhY2sgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIGFmdGVyIGFuIGV2ZW50IGhhcyBiZWVuIGNvbnN1bWVkXG4gICAqIGJ5IGEgZGlmZmVyZW50IGNhbGxiYWNrLiBUaGUgY2FsbGJhY2sgY2FuIHJldHVybjpcbiAgICogIC0gYEV2ZW50Q29uc3VtZXJSZXN1bHQuQ29uc3VtZWRgIHRoZSBldmVudCBpcyBjb25zaWRlcmVkIGNvbnN1bWVkIGFuZCB3aWxsIG5vdCBiZSBwYXNzZWQgdG8gYW55IG90aGVyIGNhbGxiYWNrLCBidXQgdGhlIGNhbGxiYWNrIHdpbGwgcmVtYWluIGluIHRoZSBjYWxsYmFja3MgbGlzdFxuICAgKiAgLSBgRXZlbnRDb25zdW1lclJlc3VsdC5Ob3RDb25zdW1lZGAgdGhlIGV2ZW50IGlzIHBhc3NlZCB0byB0aGUgbmV4dCBjYWxsYmFja1xuICAgKiAgLSBgRXZlbnRDb25zdW1lclJlc3VsdC5GaW5pc2hlZGAgdGhlIGV2ZW50IGlzIGNvbnNpZGVyZWQgY29uc3VtZWQgYW5kIHRoZSBjYWxsYmFjayBpcyByZW1vdmVkIGZyb20gdGhlIGNhbGxiYWNrcyBsaXN0XG4gICAqXG4gICAqIEBwYXJhbSBmbiAtIFRoZSBjYWxsYmFjayBmdW5jdGlvbiB0byByZWdpc3Rlci5cbiAgICovXG4gIHN1YnNjcmliZShmbjogRXZlbnRDb25zdW1lckNhbGxiYWNrKSB7XG4gICAgdGhpcy5jYWxsYmFja3MucHVzaChmbik7XG4gICAgLy8gQ2FuY2VsIGFueSBwZW5kaW5nIHVuY29uc3VtZWQgY2hlY2sgc2luY2UgYSBuZXcgY2FsbGJhY2sgbWF5IGNvbnN1bWUgdGhlIGV2ZW50LlxuICAgIC8vIEluY3JlbWVudGluZyB0aGUgdmVyc2lvbiBjYXVzZXMgYW55IGluLWZsaWdodCBwcm9taXNlIGNoYWluIGNoZWNrIHRvIG5vLW9wLlxuICAgIC8vIEFsc28gY2xlYXIgdGhlIHBlbmRpbmcgc2V0VGltZW91dCBpZiBpdCBoYXNuJ3QgZmlyZWQgeWV0LlxuICAgIGlmICh0aGlzLnBlbmRpbmdVbmNvbnN1bWVkQ2hlY2sgIT09IG51bGwpIHtcbiAgICAgIHRoaXMudW5jb25zdW1lZENoZWNrVmVyc2lvbisrO1xuICAgICAgdGhpcy5wZW5kaW5nVW5jb25zdW1lZENoZWNrID0gbnVsbDtcbiAgICAgIGlmICh0aGlzLnBlbmRpbmdVbmNvbnN1bWVkVGltZW91dCAhPT0gbnVsbCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZW5kaW5nVW5jb25zdW1lZFRpbWVvdXQpO1xuICAgICAgICB0aGlzLnBlbmRpbmdVbmNvbnN1bWVkVGltZW91dCA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIHByb2Nlc3MubmV4dFRpY2sodGhpcy5jb25zdW1lKTtcbiAgfVxuXG4gIHByaXZhdGUgbm90aWZ5Q29uc3VtZWRFdmVudChldmVudDogRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMub25Db25zdW1lZEV2ZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICB0aGlzLm9uQ29uc3VtZWRFdmVudChldmVudCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGV2ZW50c0xvZ2dlci5lcnJvcignb25Db25zdW1lZEV2ZW50IGNhbGxiYWNrIHRocmV3IGFuIGVycm9yJywge1xuICAgICAgICBlcnJvcixcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY29uc3VtZSA9ICgpID0+IHtcbiAgICAvLyBEcmFpbiBjb25zZWN1dGl2ZWx5IGNvbnN1bWFibGUgZXZlbnRzIHN5bmNocm9ub3VzbHkgd2l0aGluIGEgc2luZ2xlXG4gICAgLy8gcGFzcyBpbnN0ZWFkIG9mIHBheWluZyBvbmUgYHByb2Nlc3MubmV4dFRpY2tgIHBlciBjb25zdW1lZCBldmVudC5cbiAgICAvL1xuICAgIC8vIFdoeSB0aGlzIGlzIHNhZmU6IGEgY2FsbGJhY2sgb25seSBjb25zdW1lcyBhbiBldmVudCB1c2luZyBhIGNvbnN1bWVyXG4gICAgLy8gdGhhdCBpcyBBTFJFQURZIHJlZ2lzdGVyZWQgKGUuZy4gYSBsb25nLWxpdmVkIHN0ZXAgY29uc3VtZXIgd2Fsa2luZ1xuICAgIC8vIGBzdGVwX2NyZWF0ZWRgIOKGkiBgc3RlcF9zdGFydGVkYCDihpIgYHN0ZXBfY29tcGxldGVkYCwgb3IgdGhlIHN0cnVjdHVyYWxcbiAgICAvLyBsaWZlY3ljbGUgY29uc3VtZXIpLiBOZXcgY29uc3VtZXJzIGFyZSBvbmx5IGV2ZXIgcmVnaXN0ZXJlZCBieSB3b3JrZmxvd1xuICAgIC8vIFZNIGJvZHkgY29kZSB0aGF0IHJ1bnMgYXN5bmNocm9ub3VzbHkgb2ZmIGBjdHgucHJvbWlzZVF1ZXVlYCBhZnRlciBhXG4gICAgLy8gZGVsaXZlcnkgYHJlc29sdmUoKWA7IG5vbmUgb2YgdGhlIGNhbGxiYWNrcyBoZXJlIGNhbGwgYHN1YnNjcmliZSgpYFxuICAgIC8vIHN5bmNocm9ub3VzbHkuIFNvIHdpdGhpbiBvbmUgcGFzcyBgdGhpcy5jYWxsYmFja3NgIGlzIG11dGF0ZWQgb25seSBieVxuICAgIC8vIHRoaXMgbG9vcCAodGhlIGBGaW5pc2hlZGAgc3BsaWNlKSwgYW5kIHRoZSBuZXh0IGV2ZW50J3MgY29uc3VtZXIgaXNcbiAgICAvLyBlaXRoZXIgYWxyZWFkeSBwcmVzZW50IChhZHZhbmNlIG5vdykgb3Igbm90IHlldCByZWdpc3RlcmVkIOKAlCBpbiB3aGljaFxuICAgIC8vIGNhc2Ugbm8gY2FsbGJhY2sgY29uc3VtZXMgdGhlIGV2ZW50IGFuZCB3ZSBmYWxsIHRocm91Z2ggdG8gdGhlXG4gICAgLy8gY3Jvc3MtVk0tc2FmZSBkZWZlcnJlZCB1bmNvbnN1bWVkLWV2ZW50IGNoZWNrIGJlbG93LCBleGFjdGx5IGFzIGJlZm9yZS5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgY29uc3QgY3VycmVudEV2ZW50ID0gdGhpcy5ldmVudHNbdGhpcy5ldmVudEluZGV4XSA/PyBudWxsO1xuICAgICAgaWYgKCF0aGlzLmNvbnN1bWVPbmUoY3VycmVudEV2ZW50KSkge1xuICAgICAgICAvLyBObyBjYWxsYmFjayBjb25zdW1lZCB0aGUgY3VycmVudCBldmVudDsgaGFuZGxlIHRoZSB0ZXJtaW5hbCBjYXNlLlxuICAgICAgICB0aGlzLmhhbmRsZVVuY29uc3VtZWQoY3VycmVudEV2ZW50KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLy8gQSByZWFsIGV2ZW50IHdhcyBjb25zdW1lZCDigJQgYWR2YW5jZSB0byB0aGUgbmV4dCBpbiB0aGUgc2FtZSBwYXNzLiBBXG4gICAgICAvLyBjb25zdW1lZCBgbnVsbGAgc2VudGluZWwgbmV2ZXIgcmV0dXJucyB0cnVlIChzZWUgY29uc3VtZU9uZSksIHNvIHRoZVxuICAgICAgLy8gc3luY2hyb25vdXMgZHJhaW4gY2FuJ3Qgc3BpbiBwYXN0IHRoZSBlbmQgb2YgdGhlIGxvZy5cbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIE9mZmVyIGBjdXJyZW50RXZlbnRgIHRvIGVhY2ggcmVnaXN0ZXJlZCBjYWxsYmFjayBpbiB0dXJuLiBSZXR1cm5zIHRydWVcbiAgICogd2hlbiBhIGNhbGxiYWNrIGNvbnN1bWVkIGEgcmVhbCAobm9uLW51bGwpIGV2ZW50IGFuZCB0aGUgZHJhaW4gc2hvdWxkXG4gICAqIGFkdmFuY2UgdG8gdGhlIG5leHQgZXZlbnQgaW4gdGhlIHNhbWUgc3luY2hyb25vdXMgcGFzczsgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqIChub3RoaW5nIGNvbnN1bWVkIGl0LCBvciB0aGUgY29uc3VtZWQgZXZlbnQgd2FzIHRoZSBlbmQtb2YtZXZlbnRzXG4gICAqIHNlbnRpbmVsKS5cbiAgICovXG4gIHByaXZhdGUgY29uc3VtZU9uZShjdXJyZW50RXZlbnQ6IEV2ZW50IHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGNhbGxiYWNrID0gdGhpcy5jYWxsYmFja3NbaV07XG4gICAgICBsZXQgaGFuZGxlZCA9IEV2ZW50Q29uc3VtZXJSZXN1bHQuTm90Q29uc3VtZWQ7XG4gICAgICB0cnkge1xuICAgICAgICBoYW5kbGVkID0gY2FsbGJhY2soY3VycmVudEV2ZW50KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGV2ZW50c0xvZ2dlci5lcnJvcignRXZlbnRDb25zdW1lciBjYWxsYmFjayB0aHJldyBhbiBlcnJvcicsIHsgZXJyb3IgfSk7XG4gICAgICB9XG4gICAgICBpZiAoXG4gICAgICAgIGhhbmRsZWQgIT09IEV2ZW50Q29uc3VtZXJSZXN1bHQuQ29uc3VtZWQgJiZcbiAgICAgICAgaGFuZGxlZCAhPT0gRXZlbnRDb25zdW1lclJlc3VsdC5GaW5pc2hlZFxuICAgICAgKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKGN1cnJlbnRFdmVudCAhPT0gbnVsbCkge1xuICAgICAgICB0aGlzLm5vdGlmeUNvbnN1bWVkRXZlbnQoY3VycmVudEV2ZW50KTtcbiAgICAgIH1cbiAgICAgIC8vIGNvbnN1bWVyIGhhbmRsZWQgdGhpcyBldmVudCwgc28gaW5jcmVhc2UgdGhlIGV2ZW50IGluZGV4XG4gICAgICB0aGlzLmV2ZW50SW5kZXgrKztcbiAgICAgIC8vIHJlbW92ZSB0aGUgY2FsbGJhY2sgaWYgaXQgaGFzIGZpbmlzaGVkXG4gICAgICBpZiAoaGFuZGxlZCA9PT0gRXZlbnRDb25zdW1lclJlc3VsdC5GaW5pc2hlZCkge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XG4gICAgICB9XG4gICAgICAvLyBDb250aW51ZSBkcmFpbmluZyBvbmx5IGZvciByZWFsIGV2ZW50cy4gUmVhbCBjb25zdW1lcnMgcmV0dXJuXG4gICAgICAvLyBOb3RDb25zdW1lZCBmb3IgdGhlIGBudWxsYCBzZW50aW5lbCwgYnV0IGd1YXJkIGFnYWluc3QgYSBwYXRob2xvZ2ljYWxcbiAgICAgIC8vIGNhbGxiYWNrIGNvbnN1bWluZyBpdCBzbyB0aGUgZHJhaW4gbmV2ZXIgc3BpbnMgcGFzdCBlbmQtb2YtbG9nLlxuICAgICAgcmV0dXJuIGN1cnJlbnRFdmVudCAhPT0gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVVbmNvbnN1bWVkKGN1cnJlbnRFdmVudDogRXZlbnQgfCBudWxsKSB7XG4gICAgLy8gQWxsIGNhbGxiYWNrcyByZXR1cm5lZCBOb3RDb25zdW1lZCBmb3IgdGhlIGN1cnJlbnQgZXZlbnQuXG4gICAgLy8gSWYgdGhlIGN1cnJlbnQgZXZlbnQgaXMgbm9uLW51bGwgKGEgcmVhbCBldmVudCwgbm90IGVuZC1vZi1ldmVudHMpLFxuICAgIC8vIHNjaGVkdWxlIGEgZGVmZXJyZWQgY2hlY2suIFdlIGNoYWluIG9udG8gdGhlIHByb21pc2VRdWV1ZSBzbyB0aGF0IGFueVxuICAgIC8vIHBlbmRpbmcgYXN5bmMgd29yayAoZS5nLiwgZGVzZXJpYWxpemF0aW9uL2RlY3J5cHRpb24gdGhhdCB0cmlnZ2Vyc1xuICAgIC8vIHJlc29sdmUoKSDihpIgdXNlciBjb2RlIOKGkiBzdWJzY3JpYmUoKSkgY29tcGxldGVzIGZpcnN0LiBJZiB0aGUgZXZlbnRcbiAgICAvLyBpcyBzdGlsbCB1bmNvbnN1bWVkIGFmdGVyIHRoZSBxdWV1ZSBkcmFpbnMsIGl0J3MgdHJ1bHkgb3JwaGFuZWQuXG4gICAgaWYgKGN1cnJlbnRFdmVudCAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgY2hlY2tWZXJzaW9uID0gKyt0aGlzLnVuY29uc3VtZWRDaGVja1ZlcnNpb247XG4gICAgICB0aGlzLnBlbmRpbmdVbmNvbnN1bWVkQ2hlY2sgPSB0aGlzLmdldFByb21pc2VRdWV1ZSgpXG4gICAgICAgIC50aGVuKFxuICAgICAgICAgIC8vIFlpZWxkIG9uY2UgYWZ0ZXIgdGhlIGZpcnN0IHF1ZXVlIGRyYWluIHNvIHByb21pc2UgY2hhaW5zIHJlc3VtZWQgYnlcbiAgICAgICAgICAvLyB0aGF0IGRyYWluIGNhbiBydW4gYWNyb3NzIHRoZSBWTSBib3VuZGFyeSBhbmQgYXBwZW5kIGFueSBmb2xsb3ctdXBcbiAgICAgICAgICAvLyBhc3luYyB3b3JrIChmb3IgZXhhbXBsZTogc3RlcF9jb21wbGV0ZWQgcmVzb2x2ZXMgLT4gZm9yLWF3YWl0IGxvb3BcbiAgICAgICAgICAvLyByZXN1bWVzIC0+IHRoZSBuZXh0IGhvb2sgcGF5bG9hZCBzdGFydHMgaHlkcmF0aW5nKS5cbiAgICAgICAgICAoKSA9PiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCAwKSlcbiAgICAgICAgKVxuICAgICAgICAudGhlbigoKSA9PiB0aGlzLmdldFByb21pc2VRdWV1ZSgpKVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgLy8gVXNlIGEgZGVsYXllZCBzZXRUaW1lb3V0IGFmdGVyIHRoZSBxdWV1ZSBkcmFpbnMuIFRoZSBkZWxheSBtdXN0IGJlXG4gICAgICAgICAgLy8gbG9uZyBlbm91Z2ggZm9yIHByb21pc2UgY2hhaW5zIHRvIHByb3BhZ2F0ZSBhY3Jvc3MgdGhlIFZNIGJvdW5kYXJ5XG4gICAgICAgICAgLy8gKGZyb20gcmVzb2x2ZSgpIGluIHRoZSBob3N0IGNvbnRleHQgdGhyb3VnaCB0byB0aGUgd29ya2Zsb3cgY29kZVxuICAgICAgICAgIC8vIGNhbGxpbmcgc3Vic2NyaWJlKCkgaW4gdGhlIFZNIGNvbnRleHQpLiBOb2RlLmpzIGRvZXMgbm90IGd1YXJhbnRlZVxuICAgICAgICAgIC8vIHRoYXQgc2V0VGltZW91dCgwKSBmaXJlcyBhZnRlciBhbGwgY3Jvc3MtY29udGV4dCBtaWNyb3Rhc2tzIHNldHRsZSxcbiAgICAgICAgICAvLyBzbyB3ZSB1c2UgYSBzbWFsbCBidXQgbm9uLXplcm8gZGVsYXkuIEFueSBzdWJzY3JpYmUoKSBjYWxsIHRoYXRcbiAgICAgICAgICAvLyBhcnJpdmVzIGR1cmluZyB0aGlzIHdpbmRvdyB3aWxsIGNhbmNlbCB0aGUgY2hlY2sgdmlhIHZlcnNpb25cbiAgICAgICAgICAvLyBpbnZhbGlkYXRpb24gKyBjbGVhclRpbWVvdXQuXG4gICAgICAgICAgdGhpcy5wZW5kaW5nVW5jb25zdW1lZFRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucGVuZGluZ1VuY29uc3VtZWRUaW1lb3V0ID0gbnVsbDtcbiAgICAgICAgICAgIGlmICh0aGlzLnVuY29uc3VtZWRDaGVja1ZlcnNpb24gPT09IGNoZWNrVmVyc2lvbikge1xuICAgICAgICAgICAgICB0aGlzLnBlbmRpbmdVbmNvbnN1bWVkQ2hlY2sgPSBudWxsO1xuICAgICAgICAgICAgICB0aGlzLm9uVW5jb25zdW1lZEV2ZW50KGN1cnJlbnRFdmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG59XG4iXX0=
228
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnRzLWNvbnN1bWVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2V2ZW50cy1jb25zdW1lci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTNDOzs7OztHQUtHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsR0FBRyxDQUFDO0FBRTNDLE1BQU0sQ0FBTixJQUFZLG1CQWFYO0FBYkQsV0FBWSxtQkFBbUI7SUFDN0I7O09BRUc7SUFDSCxxRUFBUSxDQUFBO0lBQ1I7O09BRUc7SUFDSCwyRUFBVyxDQUFBO0lBQ1g7O09BRUc7SUFDSCxxRUFBUSxDQUFBO0FBQ1YsQ0FBQyxFQWJXLG1CQUFtQixLQUFuQixtQkFBbUIsUUFhOUI7QUFzQ0QsTUFBTSxPQUFPLGNBQWM7SUFDekIsVUFBVSxDQUFTO0lBQ1YsTUFBTSxHQUFZLEVBQUUsQ0FBQztJQUNyQixTQUFTLEdBQTRCLEVBQUUsQ0FBQztJQUN6QyxlQUFlLENBQTBCO0lBQ3pDLGlCQUFpQixDQUF5QjtJQUMxQyxlQUFlLENBQXNCO0lBQ3JDLGNBQWMsQ0FBZ0I7SUFDOUIsc0JBQXNCLEdBQXlCLElBQUksQ0FBQztJQUNwRCx3QkFBd0IsR0FBeUMsSUFBSSxDQUFDO0lBQ3RFLHNCQUFzQixHQUFHLENBQUMsQ0FBQztJQUVuQyxZQUFZLE1BQWUsRUFBRSxPQUE4QjtRQUN6RCxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztRQUNwQixJQUFJLENBQUMsZUFBZSxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUM7UUFDL0MsSUFBSSxDQUFDLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQztRQUNuRCxJQUFJLENBQUMsZUFBZSxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUM7UUFDL0MsSUFBSSxDQUFDLGNBQWMsR0FBRyxPQUFP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LDJEQUEyRDtnQkFDM0QsSUFBSSxDQUFDLHdCQUF3QixHQUFHLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDdEQsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUM7UUFDRixJQUFJLEVBQUUsQ0FBQztJQUNULENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRXZlbnQgfSBmcm9tICdAd29ya2Zsb3cvd29ybGQnO1xuaW1wb3J0IHsgZXZlbnRzTG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXIuanMnO1xuXG4vKipcbiAqIERlbGF5IGJlZm9yZSBmaXJpbmcgdGhlIGRlZmVycmVkIHVuY29uc3VtZWQtZXZlbnQgY2hlY2sgYWZ0ZXIgdGhlIHByb21pc2VcbiAqIHF1ZXVlIGhhcyBkcmFpbmVkLiBNdXN0IGJlIGxvbmcgZW5vdWdoIGZvciBjcm9zcy1WTSBtaWNyb3Rhc2sgY2hhaW5zIHRvXG4gKiBwcm9wYWdhdGUgKHJlc29sdmUgaW4gaG9zdCDihpIgd29ya2Zsb3cgY29kZSBpbiBWTSDihpIgc3Vic2NyaWJlIGNhbGwgYmFja1xuICogaW4gaG9zdCkuIEFueSBzdWJzY3JpYmUoKSBhcnJpdmluZyBkdXJpbmcgdGhpcyB3aW5kb3cgY2FuY2VscyB0aGUgY2hlY2suXG4gKi9cbmV4cG9ydCBjb25zdCBERUZFUlJFRF9DSEVDS19ERUxBWV9NUyA9IDEwMDtcblxuZXhwb3J0IGVudW0gRXZlbnRDb25zdW1lclJlc3VsdCB7XG4gIC8qKlxuICAgKiBDYWxsYmFjayBjb25zdW1lZCB0aGUgZXZlbnQsIGJ1dCBzaG91bGQgbm90IGJlIHJlbW92ZWQgZnJvbSB0aGUgY2FsbGJhY2tzIGxpc3RcbiAgICovXG4gIENvbnN1bWVkLFxuICAvKipcbiAgICogQ2FsbGJhY2sgZGlkIG5vdCBjb25zdW1lIHRoZSBldmVudCwgc28gaXQgc2hvdWxkIGJlIHBhc3NlZCB0byB0aGUgbmV4dCBjYWxsYmFja1xuICAgKi9cbiAgTm90Q29uc3VtZWQsXG4gIC8qKlxuICAgKiBDYWxsYmFjayBjb25zdW1lZCB0aGUgZXZlbnQsIGFuZCBzaG91bGQgYmUgcmVtb3ZlZCBmcm9tIHRoZSBjYWxsYmFja3MgbGlzdFxuICAgKi9cbiAgRmluaXNoZWQsXG59XG5cbnR5cGUgRXZlbnRDb25zdW1lckNhbGxiYWNrID0gKGV2ZW50OiBFdmVudCB8IG51bGwpID0+IEV2ZW50Q29uc3VtZXJSZXN1bHQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXZlbnRzQ29uc3VtZXJPcHRpb25zIHtcbiAgLyoqXG4gICAqIENhbGxiYWNrIGludm9rZWQgYWZ0ZXIgYW4gZXZlbnQgaGFzIGJlZW4gY29uc3VtZWQuIENvbnN1bWVycyBzdWNoIGFzIHRoZVxuICAgKiBkZXRlcm1pbmlzdGljIHdvcmtmbG93IGNsb2NrIG11c3Qgbm90IG9ic2VydmUgZXZlbnRzIHRoYXQgYXJlIG1lcmVseVxuICAgKiBpbnNwZWN0ZWQgd2hpbGUgd2FpdGluZyBmb3IgdXNlciBjb2RlIHRvIHN1YnNjcmliZSB0byB0aGUgbmV4dCBvcGVyYXRpb24uXG4gICAqL1xuICBvbkNvbnN1bWVkRXZlbnQ/OiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkO1xuICAvKipcbiAgICogQ2FsbGJhY2sgaW52b2tlZCB3aGVuIGEgbm9uLW51bGwgZXZlbnQgY2Fubm90IGJlIGNvbnN1bWVkIGJ5IGFueSByZWdpc3RlcmVkXG4gICAqIGNhbGxiYWNrLCBpbmRpY2F0aW5nIGFuIG9ycGhhbmVkIG9yIGludmFsaWQgZXZlbnQgaW4gdGhlIGV2ZW50IGxvZy4gVGhlXG4gICAqIGNoZWNrIGlzIGRlZmVycmVkIHVudGlsIGFmdGVyIHRoZSBwcm9taXNlIHF1ZXVlIGhhcyBkcmFpbmVkLCBlbnN1cmluZyB0aGF0XG4gICAqIGFueSBwZW5kaW5nIGFzeW5jIHdvcmsgKGUuZy4sIGRlc2VyaWFsaXphdGlvbi9kZWNyeXB0aW9uKSBjb21wbGV0ZXMgYW5kXG4gICAqIGRvd25zdHJlYW0gc3Vic2NyaWJlKCkgY2FsbHMgaGF2ZSBhIGNoYW5jZSB0byBjYW5jZWwgdGhlIGNoZWNrIGZpcnN0LlxuICAgKi9cbiAgb25VbmNvbnN1bWVkRXZlbnQ6IChldmVudDogRXZlbnQpID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHByb21pc2UgcXVldWUuIFRoZSB1bmNvbnN1bWVkIGV2ZW50IGNoZWNrIGlzIGNoYWluZWRcbiAgICogb250byB0aGlzIHF1ZXVlIHNvIGl0IG9ubHkgZmlyZXMgYWZ0ZXIgYWxsIHBlbmRpbmcgYXN5bmMgd29yayAoZS5nLixcbiAgICogZGVzZXJpYWxpemF0aW9uKSBoYXMgY29tcGxldGVkLiBUaGlzIHByZXZlbnRzIGZhbHNlIHBvc2l0aXZlcyB3aGVuIGFzeW5jXG4gICAqIGRlc2VyaWFsaXphdGlvbiBkZWxheXMgdGhlIHJlc29sdmUoKSB0aGF0IHRyaWdnZXJzIHRoZSBuZXh0IHN1YnNjcmliZSgpLlxuICAgKi9cbiAgZ2V0UHJvbWlzZVF1ZXVlOiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuICAvKipcbiAgICogV2hldGhlciBubyBkYXRhIGRlbGl2ZXJ5IGlzIGluIGZsaWdodCAoYGlzRGVsaXZlcnlJZGxlYCBpbiBwcml2YXRlLnRzKS5cbiAgICogVGhlIHVuY29uc3VtZWQtZXZlbnQgY2hlY2sgd2FpdHMgZm9yIHRoaXMgYmVmb3JlIGl0IGZpcmVzOiBhIGRlbGl2ZXJ5IGluXG4gICAqIGZsaWdodCBtZWFucyB0aGUgd29ya2Zsb3cgVk0gaXMgbWlkLXJlYWN0aW9uLCBhbmQgYW4gZXZlbnQgaXQgaGFzIG5vdFxuICAgKiBjbGFpbWVkIHlldCBpcyBhbiBldmVudCBpdCBoYXMgbm90IHJlYWNoZWQgeWV0LlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBhbHdheXMtaWRsZSBzbyB0aGUgdGVzdHMgdGhhdCBkcml2ZSBhIGNvbnN1bWVyIHdpdGggbm9cbiAgICogb3JjaGVzdHJhdG9yIGNvbnRleHQga2VlcCB0aGUgcHJlLWV4aXN0aW5nIHRpbWluZy5cbiAgICovXG4gIGlzRGVsaXZlcnlJZGxlPzogKCkgPT4gYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNsYXNzIEV2ZW50c0NvbnN1bWVyIHtcbiAgZXZlbnRJbmRleDogbnVtYmVyO1xuICByZWFkb25seSBldmVudHM6IEV2ZW50W10gPSBbXTtcbiAgcmVhZG9ubHkgY2FsbGJhY2tzOiBFdmVudENvbnN1bWVyQ2FsbGJhY2tbXSA9IFtdO1xuICBwcml2YXRlIG9uQ29uc3VtZWRFdmVudD86IChldmVudDogRXZlbnQpID0+IHZvaWQ7XG4gIHByaXZhdGUgb25VbmNvbnN1bWVkRXZlbnQ6IChldmVudDogRXZlbnQpID0+IHZvaWQ7XG4gIHByaXZhdGUgZ2V0UHJvbWlzZVF1ZXVlOiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuICBwcml2YXRlIGlzRGVsaXZlcnlJZGxlOiAoKSA9PiBib29sZWFuO1xuICBwcml2YXRlIHBlbmRpbmdVbmNvbnN1bWVkQ2hlY2s6IFByb21pc2U8dm9pZD4gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBwZW5kaW5nVW5jb25zdW1lZFRpbWVvdXQ6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgdW5jb25zdW1lZENoZWNrVmVyc2lvbiA9IDA7XG5cbiAgY29uc3RydWN0b3IoZXZlbnRzOiBFdmVudFtdLCBvcHRpb25zOiBFdmVudHNDb25zdW1lck9wdGlvbnMpIHtcbiAgICB0aGlzLmV2ZW50cyA9IGV2ZW50cztcbiAgICB0aGlzLmV2ZW50SW5kZXggPSAwO1xuICAgIHRoaXMub25Db25zdW1lZEV2ZW50ID0gb3B0aW9ucy5vbkNvbnN1bWVkRXZlbnQ7XG4gICAgdGhpcy5vblVuY29uc3VtZWRFdmVudCA9IG9wdGlvbnMub25VbmNvbnN1bWVkRXZlbnQ7XG4gICAgdGhpcy5nZXRQcm9taXNlUXVldWUgPSBvcHRpb25zLmdldFByb21pc2VRdWV1ZTtcbiAgICB0aGlzLmlzRGVsaXZlcnlJZGxlID0gb3B0aW9ucy5pc0RlbGl2ZXJ5SWRsZSA/PyAoKCkgPT4gdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGEgY2FsbGJhY2sgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIGFmdGVyIGFuIGV2ZW50IGhhcyBiZWVuIGNvbnN1bWVkXG4gICAqIGJ5IGEgZGlmZmVyZW50IGNhbGxiYWNrLiBUaGUgY2FsbGJhY2sgY2FuIHJldHVybjpcbiAgICogIC0gYEV2ZW50Q29uc3VtZXJSZXN1bHQuQ29uc3VtZWRgIHRoZSBldmVudCBpcyBjb25zaWRlcmVkIGNvbnN1bWVkIGFuZCB3aWxsIG5vdCBiZSBwYXNzZWQgdG8gYW55IG90aGVyIGNhbGxiYWNrLCBidXQgdGhlIGNhbGxiYWNrIHdpbGwgcmVtYWluIGluIHRoZSBjYWxsYmFja3MgbGlzdFxuICAgKiAgLSBgRXZlbnRDb25zdW1lclJlc3VsdC5Ob3RDb25zdW1lZGAgdGhlIGV2ZW50IGlzIHBhc3NlZCB0byB0aGUgbmV4dCBjYWxsYmFja1xuICAgKiAgLSBgRXZlbnRDb25zdW1lclJlc3VsdC5GaW5pc2hlZGAgdGhlIGV2ZW50IGlzIGNvbnNpZGVyZWQgY29uc3VtZWQgYW5kIHRoZSBjYWxsYmFjayBpcyByZW1vdmVkIGZyb20gdGhlIGNhbGxiYWNrcyBsaXN0XG4gICAqXG4gICAqIEBwYXJhbSBmbiAtIFRoZSBjYWxsYmFjayBmdW5jdGlvbiB0byByZWdpc3Rlci5cbiAgICovXG4gIHN1YnNjcmliZShmbjogRXZlbnRDb25zdW1lckNhbGxiYWNrKSB7XG4gICAgdGhpcy5jYWxsYmFja3MucHVzaChmbik7XG4gICAgLy8gQ2FuY2VsIGFueSBwZW5kaW5nIHVuY29uc3VtZWQgY2hlY2sgc2luY2UgYSBuZXcgY2FsbGJhY2sgbWF5IGNvbnN1bWUgdGhlIGV2ZW50LlxuICAgIC8vIEluY3JlbWVudGluZyB0aGUgdmVyc2lvbiBjYXVzZXMgYW55IGluLWZsaWdodCBwcm9taXNlIGNoYWluIGNoZWNrIHRvIG5vLW9wLlxuICAgIC8vIEFsc28gY2xlYXIgdGhlIHBlbmRpbmcgc2V0VGltZW91dCBpZiBpdCBoYXNuJ3QgZmlyZWQgeWV0LlxuICAgIGlmICh0aGlzLnBlbmRpbmdVbmNvbnN1bWVkQ2hlY2sgIT09IG51bGwpIHtcbiAgICAgIHRoaXMudW5jb25zdW1lZENoZWNrVmVyc2lvbisrO1xuICAgICAgdGhpcy5wZW5kaW5nVW5jb25zdW1lZENoZWNrID0gbnVsbDtcbiAgICAgIGlmICh0aGlzLnBlbmRpbmdVbmNvbnN1bWVkVGltZW91dCAhPT0gbnVsbCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZW5kaW5nVW5jb25zdW1lZFRpbWVvdXQpO1xuICAgICAgICB0aGlzLnBlbmRpbmdVbmNvbnN1bWVkVGltZW91dCA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIHByb2Nlc3MubmV4dFRpY2sodGhpcy5jb25zdW1lKTtcbiAgfVxuXG4gIHByaXZhdGUgbm90aWZ5Q29uc3VtZWRFdmVudChldmVudDogRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMub25Db25zdW1lZEV2ZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICB0aGlzLm9uQ29uc3VtZWRFdmVudChldmVudCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGV2ZW50c0xvZ2dlci5lcnJvcignb25Db25zdW1lZEV2ZW50IGNhbGxiYWNrIHRocmV3IGFuIGVycm9yJywge1xuICAgICAgICBlcnJvcixcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY29uc3VtZSA9ICgpID0+IHtcbiAgICAvLyBEcmFpbiBjb25zZWN1dGl2ZWx5IGNvbnN1bWFibGUgZXZlbnRzIHN5bmNocm9ub3VzbHkgd2l0aGluIGEgc2luZ2xlXG4gICAgLy8gcGFzcyBpbnN0ZWFkIG9mIHBheWluZyBvbmUgYHByb2Nlc3MubmV4dFRpY2tgIHBlciBjb25zdW1lZCBldmVudC5cbiAgICAvL1xuICAgIC8vIFdoeSB0aGlzIGlzIHNhZmU6IGEgY2FsbGJhY2sgb25seSBjb25zdW1lcyBhbiBldmVudCB1c2luZyBhIGNvbnN1bWVyXG4gICAgLy8gdGhhdCBpcyBBTFJFQURZIHJlZ2lzdGVyZWQgKGUuZy4gYSBsb25nLWxpdmVkIHN0ZXAgY29uc3VtZXIgd2Fsa2luZ1xuICAgIC8vIGBzdGVwX2NyZWF0ZWRgIOKGkiBgc3RlcF9zdGFydGVkYCDihpIgYHN0ZXBfY29tcGxldGVkYCwgb3IgdGhlIHN0cnVjdHVyYWxcbiAgICAvLyBsaWZlY3ljbGUgY29uc3VtZXIpLiBOZXcgY29uc3VtZXJzIGFyZSBvbmx5IGV2ZXIgcmVnaXN0ZXJlZCBieSB3b3JrZmxvd1xuICAgIC8vIFZNIGJvZHkgY29kZSB0aGF0IHJ1bnMgYXN5bmNocm9ub3VzbHkgb2ZmIGBjdHgucHJvbWlzZVF1ZXVlYCBhZnRlciBhXG4gICAgLy8gZGVsaXZlcnkgYHJlc29sdmUoKWA7IG5vbmUgb2YgdGhlIGNhbGxiYWNrcyBoZXJlIGNhbGwgYHN1YnNjcmliZSgpYFxuICAgIC8vIHN5bmNocm9ub3VzbHkuIFNvIHdpdGhpbiBvbmUgcGFzcyBgdGhpcy5jYWxsYmFja3NgIGlzIG11dGF0ZWQgb25seSBieVxuICAgIC8vIHRoaXMgbG9vcCAodGhlIGBGaW5pc2hlZGAgc3BsaWNlKSwgYW5kIHRoZSBuZXh0IGV2ZW50J3MgY29uc3VtZXIgaXNcbiAgICAvLyBlaXRoZXIgYWxyZWFkeSBwcmVzZW50IChhZHZhbmNlIG5vdykgb3Igbm90IHlldCByZWdpc3RlcmVkIOKAlCBpbiB3aGljaFxuICAgIC8vIGNhc2Ugbm8gY2FsbGJhY2sgY29uc3VtZXMgdGhlIGV2ZW50IGFuZCB3ZSBmYWxsIHRocm91Z2ggdG8gdGhlXG4gICAgLy8gY3Jvc3MtVk0tc2FmZSBkZWZlcnJlZCB1bmNvbnN1bWVkLWV2ZW50IGNoZWNrIGJlbG93LCBleGFjdGx5IGFzIGJlZm9yZS5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgY29uc3QgY3VycmVudEV2ZW50ID0gdGhpcy5ldmVudHNbdGhpcy5ldmVudEluZGV4XSA/PyBudWxsO1xuICAgICAgaWYgKCF0aGlzLmNvbnN1bWVPbmUoY3VycmVudEV2ZW50KSkge1xuICAgICAgICAvLyBObyBjYWxsYmFjayBjb25zdW1lZCB0aGUgY3VycmVudCBldmVudDsgaGFuZGxlIHRoZSB0ZXJtaW5hbCBjYXNlLlxuICAgICAgICB0aGlzLmhhbmRsZVVuY29uc3VtZWQoY3VycmVudEV2ZW50KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLy8gQSByZWFsIGV2ZW50IHdhcyBjb25zdW1lZCDigJQgYWR2YW5jZSB0byB0aGUgbmV4dCBpbiB0aGUgc2FtZSBwYXNzLiBBXG4gICAgICAvLyBjb25zdW1lZCBgbnVsbGAgc2VudGluZWwgbmV2ZXIgcmV0dXJucyB0cnVlIChzZWUgY29uc3VtZU9uZSksIHNvIHRoZVxuICAgICAgLy8gc3luY2hyb25vdXMgZHJhaW4gY2FuJ3Qgc3BpbiBwYXN0IHRoZSBlbmQgb2YgdGhlIGxvZy5cbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIE9mZmVyIGBjdXJyZW50RXZlbnRgIHRvIGVhY2ggcmVnaXN0ZXJlZCBjYWxsYmFjayBpbiB0dXJuLiBSZXR1cm5zIHRydWVcbiAgICogd2hlbiBhIGNhbGxiYWNrIGNvbnN1bWVkIGEgcmVhbCAobm9uLW51bGwpIGV2ZW50IGFuZCB0aGUgZHJhaW4gc2hvdWxkXG4gICAqIGFkdmFuY2UgdG8gdGhlIG5leHQgZXZlbnQgaW4gdGhlIHNhbWUgc3luY2hyb25vdXMgcGFzczsgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqIChub3RoaW5nIGNvbnN1bWVkIGl0LCBvciB0aGUgY29uc3VtZWQgZXZlbnQgd2FzIHRoZSBlbmQtb2YtZXZlbnRzXG4gICAqIHNlbnRpbmVsKS5cbiAgICovXG4gIHByaXZhdGUgY29uc3VtZU9uZShjdXJyZW50RXZlbnQ6IEV2ZW50IHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGNhbGxiYWNrID0gdGhpcy5jYWxsYmFja3NbaV07XG4gICAgICBsZXQgaGFuZGxlZCA9IEV2ZW50Q29uc3VtZXJSZXN1bHQuTm90Q29uc3VtZWQ7XG4gICAgICB0cnkge1xuICAgICAgICBoYW5kbGVkID0gY2FsbGJhY2soY3VycmVudEV2ZW50KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGV2ZW50c0xvZ2dlci5lcnJvcignRXZlbnRDb25zdW1lciBjYWxsYmFjayB0aHJldyBhbiBlcnJvcicsIHsgZXJyb3IgfSk7XG4gICAgICB9XG4gICAgICBpZiAoXG4gICAgICAgIGhhbmRsZWQgIT09IEV2ZW50Q29uc3VtZXJSZXN1bHQuQ29uc3VtZWQgJiZcbiAgICAgICAgaGFuZGxlZCAhPT0gRXZlbnRDb25zdW1lclJlc3VsdC5GaW5pc2hlZFxuICAgICAgKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKGN1cnJlbnRFdmVudCAhPT0gbnVsbCkge1xuICAgICAgICB0aGlzLm5vdGlmeUNvbnN1bWVkRXZlbnQoY3VycmVudEV2ZW50KTtcbiAgICAgIH1cbiAgICAgIC8vIGNvbnN1bWVyIGhhbmRsZWQgdGhpcyBldmVudCwgc28gaW5jcmVhc2UgdGhlIGV2ZW50IGluZGV4XG4gICAgICB0aGlzLmV2ZW50SW5kZXgrKztcbiAgICAgIC8vIHJlbW92ZSB0aGUgY2FsbGJhY2sgaWYgaXQgaGFzIGZpbmlzaGVkXG4gICAgICBpZiAoaGFuZGxlZCA9PT0gRXZlbnRDb25zdW1lclJlc3VsdC5GaW5pc2hlZCkge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XG4gICAgICB9XG4gICAgICAvLyBDb250aW51ZSBkcmFpbmluZyBvbmx5IGZvciByZWFsIGV2ZW50cy4gUmVhbCBjb25zdW1lcnMgcmV0dXJuXG4gICAgICAvLyBOb3RDb25zdW1lZCBmb3IgdGhlIGBudWxsYCBzZW50aW5lbCwgYnV0IGd1YXJkIGFnYWluc3QgYSBwYXRob2xvZ2ljYWxcbiAgICAgIC8vIGNhbGxiYWNrIGNvbnN1bWluZyBpdCBzbyB0aGUgZHJhaW4gbmV2ZXIgc3BpbnMgcGFzdCBlbmQtb2YtbG9nLlxuICAgICAgcmV0dXJuIGN1cnJlbnRFdmVudCAhPT0gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVVbmNvbnN1bWVkKGN1cnJlbnRFdmVudDogRXZlbnQgfCBudWxsKSB7XG4gICAgLy8gQWxsIGNhbGxiYWNrcyByZXR1cm5lZCBOb3RDb25zdW1lZCBmb3IgdGhlIGN1cnJlbnQgZXZlbnQuXG4gICAgLy8gSWYgdGhlIGN1cnJlbnQgZXZlbnQgaXMgbm9uLW51bGwgKGEgcmVhbCBldmVudCwgbm90IGVuZC1vZi1ldmVudHMpLFxuICAgIC8vIHNjaGVkdWxlIGEgZGVmZXJyZWQgY2hlY2suIFdlIGNoYWluIG9udG8gdGhlIHByb21pc2VRdWV1ZSBzbyB0aGF0IGFueVxuICAgIC8vIHBlbmRpbmcgYXN5bmMgd29yayAoZS5nLiwgZGVzZXJpYWxpemF0aW9uL2RlY3J5cHRpb24gdGhhdCB0cmlnZ2Vyc1xuICAgIC8vIHJlc29sdmUoKSDihpIgdXNlciBjb2RlIOKGkiBzdWJzY3JpYmUoKSkgY29tcGxldGVzIGZpcnN0LiBJZiB0aGUgZXZlbnRcbiAgICAvLyBpcyBzdGlsbCB1bmNvbnN1bWVkIGFmdGVyIHRoZSBxdWV1ZSBkcmFpbnMsIGl0J3MgdHJ1bHkgb3JwaGFuZWQuXG4gICAgaWYgKGN1cnJlbnRFdmVudCAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgY2hlY2tWZXJzaW9uID0gKyt0aGlzLnVuY29uc3VtZWRDaGVja1ZlcnNpb247XG4gICAgICB0aGlzLnBlbmRpbmdVbmNvbnN1bWVkQ2hlY2sgPSB0aGlzLmdldFByb21pc2VRdWV1ZSgpXG4gICAgICAgIC50aGVuKFxuICAgICAgICAgIC8vIFlpZWxkIG9uY2UgYWZ0ZXIgdGhlIGZpcnN0IHF1ZXVlIGRyYWluIHNvIHByb21pc2UgY2hhaW5zIHJlc3VtZWQgYnlcbiAgICAgICAgICAvLyB0aGF0IGRyYWluIGNhbiBydW4gYWNyb3NzIHRoZSBWTSBib3VuZGFyeSBhbmQgYXBwZW5kIGFueSBmb2xsb3ctdXBcbiAgICAgICAgICAvLyBhc3luYyB3b3JrIChmb3IgZXhhbXBsZTogc3RlcF9jb21wbGV0ZWQgcmVzb2x2ZXMgLT4gZm9yLWF3YWl0IGxvb3BcbiAgICAgICAgICAvLyByZXN1bWVzIC0+IHRoZSBuZXh0IGhvb2sgcGF5bG9hZCBzdGFydHMgaHlkcmF0aW5nKS5cbiAgICAgICAgICAoKSA9PiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCAwKSlcbiAgICAgICAgKVxuICAgICAgICAudGhlbigoKSA9PiB0aGlzLmdldFByb21pc2VRdWV1ZSgpKVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgLy8gV2FpdCBvdXQgYW55IGRlbGl2ZXJ5IHN0aWxsIGluIGZsaWdodCBiZWZvcmUgc3RhcnRpbmcgdGhlIHRpbWVyLlxuICAgICAgICAgIC8vIFRoZSBxdWV1ZSBkcmFpbmluZyBzYXlzIHRoZSBob3N0IGhhcyBubyBoeWRyYXRpb24gd29yayBsZWZ0OyBpdFxuICAgICAgICAgIC8vIGRvZXMgbm90IHNheSB0aGUgVk0gaGFzIGZpbmlzaGVkIHJlYWN0aW5nIHRvIHdoYXQgd2FzIGh5ZHJhdGVkLlxuICAgICAgICAgIHRoaXMud2hlbkRlbGl2ZXJ5SWRsZShjaGVja1ZlcnNpb24sICgpID0+IHtcbiAgICAgICAgICAgIC8vIFVzZSBhIGRlbGF5ZWQgc2V0VGltZW91dCBvbmNlIGRlbGl2ZXJpZXMgYXJlIGlkbGUuIFRoZSBkZWxheSBtdXN0XG4gICAgICAgICAgICAvLyBiZSBsb25nIGVub3VnaCBmb3IgcHJvbWlzZSBjaGFpbnMgdG8gcHJvcGFnYXRlIGFjcm9zcyB0aGUgVk1cbiAgICAgICAgICAgIC8vIGJvdW5kYXJ5IChmcm9tIHJlc29sdmUoKSBpbiB0aGUgaG9zdCBjb250ZXh0IHRocm91Z2ggdG8gdGhlXG4gICAgICAgICAgICAvLyB3b3JrZmxvdyBjb2RlIGNhbGxpbmcgc3Vic2NyaWJlKCkgaW4gdGhlIFZNIGNvbnRleHQpLiBOb2RlLmpzXG4gICAgICAgICAgICAvLyBkb2VzIG5vdCBndWFyYW50ZWUgdGhhdCBzZXRUaW1lb3V0KDApIGZpcmVzIGFmdGVyIGFsbFxuICAgICAgICAgICAgLy8gY3Jvc3MtY29udGV4dCBtaWNyb3Rhc2tzIHNldHRsZSwgc28gd2UgdXNlIGEgc21hbGwgYnV0IG5vbi16ZXJvXG4gICAgICAgICAgICAvLyBkZWxheS4gQW55IHN1YnNjcmliZSgpIGNhbGwgdGhhdCBhcnJpdmVzIGR1cmluZyB0aGlzIHdpbmRvdyB3aWxsXG4gICAgICAgICAgICAvLyBjYW5jZWwgdGhlIGNoZWNrIHZpYSB2ZXJzaW9uIGludmFsaWRhdGlvbiArIGNsZWFyVGltZW91dC5cbiAgICAgICAgICAgIHRoaXMucGVuZGluZ1VuY29uc3VtZWRUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMucGVuZGluZ1VuY29uc3VtZWRUaW1lb3V0ID0gbnVsbDtcbiAgICAgICAgICAgICAgaWYgKHRoaXMudW5jb25zdW1lZENoZWNrVmVyc2lvbiA9PT0gY2hlY2tWZXJzaW9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wZW5kaW5nVW5jb25zdW1lZENoZWNrID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aGlzLm9uVW5jb25zdW1lZEV2ZW50KGN1cnJlbnRFdmVudCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sIERFRkVSUkVEX0NIRUNLX0RFTEFZX01TKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1biBgZm5gIG9uY2Ugbm8gZGF0YSBkZWxpdmVyeSBpcyBpbiBmbGlnaHQsIHBvbGxpbmcgdGhlIHdheVxuICAgKiBgc2NoZWR1bGVXaGVuSWRsZWAgZG9lczogbGV0IHRoZSBwcm9taXNlIHF1ZXVlIGRyYWluLCByZS1jaGVjayBhIHRpbWVyXG4gICAqIHRpY2sgbGF0ZXIsIHJlcGVhdC5cbiAgICpcbiAgICogV2l0aG91dCB0aGlzIHRoZSBjaGVjayBpcyBhIGJldCB0aGF0IGV2ZXJ5IGRlbGl2ZXJ5IHRoZSB3YWxrIGlzIHJ1bm5pbmdcbiAgICogYWhlYWQgb2YgbGFuZHMgaW5zaWRlIGEgZml4ZWQgd2luZG93LiBDb25zdW1wdGlvbiBpcyBzeW5jaHJvbm91cyB3aGlsZSB0aGVcbiAgICogcmVzb2x1dGlvbiBpdCB0cmlnZ2VycyBpcyBub3Q6IGEgc3RlcCByZXN1bHQgaHlkcmF0ZXMgaW4gdGhlIGhvc3QsIHJlc29sdmVzXG4gICAqIGZyb20gYSBkZXRhY2hlZCBjb250aW51YXRpb24gYmVoaW5kIGBhd2FpdEVhcmxpZXJEZWxpdmVyaWVzYCwgYW5kIG9ubHkgdGhlblxuICAgKiBkb2VzIFZNIGNvZGUgcnVuIGZhciBlbm91Z2ggdG8gc3Vic2NyaWJlIHRoZSBuZXh0IGNvbnN1bWVyLiBSZXBsYXlpbmcgYVxuICAgKiBiYXRjaCBvZiBOIHBhcmFsbGVsIHN0ZXAgcmVzdWx0cyBsZWF2ZXMgTi0xIG9mIHRoZW0gb24gdGhhdCBkZXRhY2hlZCBwYXRoXG4gICAqIHdpdGggdGhlIHF1ZXVlIGFscmVhZHkgZHJhaW5lZCwgc28gdGhlIHdhbGsgc2l0cyBvbiB0aGUgb3JkZXJlZCBldmVudCB0aGVcbiAgICogVk0gaXMgYWJvdXQgdG8gZHJhdyBhbmQgdGhlIHdpbmRvdyBpcyB0aGUgb25seSB0aGluZyBzdGFuZGluZyBiZXR3ZWVuIGFcbiAgICogaGVhbHRoeSBydW4gYW5kIGBSZXBsYXlEaXZlcmdlbmNlRXJyb3JgLiBPbiBhIGJhY2tlbmQgd2hvc2UgZGVsaXZlcmllcyB0YWtlXG4gICAqIGxvbmdlciB0aGFuIHRoZSB3aW5kb3csIHRoYXQgYmV0IGxvc2VzLlxuICAgKlxuICAgKiBUZXJtaW5hdGlvbiBpcyBgaGFzUGFya2VkQ29tbWl0dGVkRGVsaXZlcnlgJ3M6IGl0IGNvdW50cyBvbmx5IGRlbGl2ZXJpZXNcbiAgICogdGhhdCByZXNvbHZlIG9uIHRoZWlyIG93biwgc28gbm90aGluZyBoZXJlIGNhbiBnYXRlIGl0cyBvd24gcmV0aXJlbWVudC4gQVxuICAgKiBnZW51aW5lbHkgb3JwaGFuZWQgZXZlbnQgaGFzIG5vIGRlbGl2ZXJ5IHRvIHdhaXQgb24gYW5kIHJlYWNoZXMgYGZuYCBvbiB0aGVcbiAgICogZmlyc3QgcG9sbC5cbiAgICovXG4gIHByaXZhdGUgd2hlbkRlbGl2ZXJ5SWRsZShjaGVja1ZlcnNpb246IG51bWJlciwgZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICBjb25zdCBwb2xsID0gKCkgPT4ge1xuICAgICAgdGhpcy5wZW5kaW5nVW5jb25zdW1lZFRpbWVvdXQgPSBudWxsO1xuICAgICAgaWYgKHRoaXMudW5jb25zdW1lZENoZWNrVmVyc2lvbiAhPT0gY2hlY2tWZXJzaW9uKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmlzRGVsaXZlcnlJZGxlKCkpIHtcbiAgICAgICAgZm4oKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5nZXRQcm9taXNlUXVldWUoKS50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMudW5jb25zdW1lZENoZWNrVmVyc2lvbiAhPT0gY2hlY2tWZXJzaW9uKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIEhlbGQgaW4gdGhlIHNhbWUgZmllbGQgdGhlIGZpcmVkIGNoZWNrIHVzZXMgc28gc3Vic2NyaWJlKCkgY2FuY2VscyBhXG4gICAgICAgIC8vIHBvbGwgaW4gcHJvZ3Jlc3MgZXhhY3RseSBhcyBpdCBjYW5jZWxzIHRoZSBjaGVjayBpdHNlbGYuXG4gICAgICAgIHRoaXMucGVuZGluZ1VuY29uc3VtZWRUaW1lb3V0ID0gc2V0VGltZW91dChwb2xsLCAwKTtcbiAgICAgIH0pO1xuICAgIH07XG4gICAgcG9sbCgpO1xuICB9XG59XG4iXX0=
package/dist/private.d.ts CHANGED
@@ -53,26 +53,33 @@ export interface WorkflowOrchestratorContext {
53
53
  pendingDeliveries: number;
54
54
  /**
55
55
  * Ordered registry of in-flight "branch-deciding" deliveries — the
56
- * resolutions a workflow typically `Promise.race`s on: buffered hook
57
- * payloads (`hook_received`) and wait completions (`wait_completed`).
58
- * Keyed by the delivery's position (index) in the consumed event log.
56
+ * resolutions a workflow typically `Promise.race`s on, or awaits from
57
+ * independent concurrent branches: hook payloads (`hook_received`), wait
58
+ * completions (`wait_completed`), and step results (`step_completed` /
59
+ * `step_failed`). Keyed by the delivery's position (index) in the consumed
60
+ * event log.
59
61
  *
60
- * The problem: a buffered hook payload is observed via the async hook
61
- * iterator (`yield await this`), costing extra microtask hops, while a
62
- * `wait_completed` resolves with fewer hops and a reused sleep can
63
- * resolve in an entirely earlier loop iteration. Either way, the
64
- * resolution that the committed event log ordered first can lose a
65
- * `Promise.race` to a faster- or already-resolved competitor, diverging
66
- * from the log and surfacing as `ReplayDivergenceError`.
62
+ * The problem: each of these resolutions reaches workflow code after a
63
+ * different, workload-dependent number of microtask hops. A buffered hook
64
+ * payload is observed via the async hook iterator (`yield await this`),
65
+ * costing extra hops; a `wait_completed` resolves with fewer, and a reused
66
+ * sleep can resolve in an entirely earlier loop iteration; a step result is
67
+ * gated on hydration whose cost varies between replays of the SAME
68
+ * invocation the first replay pays the full decrypt/decompress/revive,
69
+ * while later replays sharing the invocation's `stepHydrationCache`
70
+ * memo-hit small primitive results and resolve in one or two hops. Either
71
+ * way, the resolution that the committed event log ordered first can lose a
72
+ * `Promise.race` (or a `useStep` ULID allocation) to a faster- or
73
+ * already-resolved competitor, diverging from the log and surfacing as
74
+ * `ReplayDivergenceError`.
67
75
  *
68
76
  * The fix is a strict, deterministic delivery order anchored on
69
77
  * event-log position: a delivery does not resolve to the workflow until
70
- * every earlier-in-log delivery of the OPPOSITE kind has been delivered.
71
- * (Opposite kind only: sequential same-kind hook payloads must not block
72
- * one another, and a wait need not wait behind a later wait.) Because the
78
+ * every relevant earlier-in-log delivery has been delivered. Because the
73
79
  * gate is "the earlier delivery resolved", not "won a timing race", the
74
80
  * outcome is independent of microtask hops, hydration/decryption time,
75
- * and `Promise.race` argument order.
81
+ * and `Promise.race` argument order. Which earlier kinds a delivery defers
82
+ * behind is spelled out on {@link awaitEarlierDeliveries}.
76
83
  *
77
84
  * Index is used rather than the `eventId` string because `eventId` is an
78
85
  * opaque, world-assigned value not guaranteed to sort in creation order
@@ -102,52 +109,115 @@ export interface WorkflowOrchestratorContext {
102
109
  stepHydrationCache?: StepHydrationCache;
103
110
  }
104
111
  /** The kind of branch-deciding delivery a barrier represents. */
105
- export type DeliveryKind = 'hook' | 'wait';
112
+ export type DeliveryKind = 'hook' | 'wait' | 'step';
106
113
  interface DeliveryBarrierEntry {
107
114
  kind: DeliveryKind;
108
115
  /** Resolves once this delivery has resolved to the workflow. */
109
116
  delivered: Promise<void>;
117
+ /**
118
+ * Whether this delivery is committed to reaching the workflow without any
119
+ * further action by workflow code. True for wait completions and step
120
+ * results, which always resolve from their own chain, and for a hook payload
121
+ * that already had a waiting consumer when it was consumed.
122
+ *
123
+ * False for a BUFFERED hook payload no consumer has claimed yet: it is
124
+ * delivered by `claim()`, i.e. whenever the workflow next reads the hook —
125
+ * which may be causally *after* a later-in-log delivery. `arm()` flips it
126
+ * once a consumer takes the payload.
127
+ */
128
+ armed: boolean;
110
129
  }
111
130
  /**
112
- * Awaits, in strict event-log order, every still-registered delivery whose
113
- * index is earlier than `eventIndex` AND whose kind is in `deferBehindKinds`,
114
- * so that this resolution is handed to the workflow only after all relevant
115
- * earlier-in-log deliveries have been. This is what keeps a `Promise.race`
116
- * deterministic and aligned with the committed event log, independent of
117
- * microtask-hop counts, hydration time, or race-argument order.
131
+ * Awaits, in strict event-log order, every still-registered delivery that is
132
+ * earlier in the log than `eventIndex` and that a delivery of `kind` defers
133
+ * behind (see {@link DEFER_BEHIND}), so that this resolution is handed to the
134
+ * workflow only after all relevant earlier-in-log deliveries have been. This
135
+ * is what keeps a `Promise.race` — or the ULID a follow-up `useStep` draws on
136
+ * a concurrent branch deterministic and aligned with the committed event
137
+ * log, independent of microtask-hop counts, hydration time, or race-argument
138
+ * order. When this delivery does have to wait, it also yields a macrotask
139
+ * afterwards so the earlier delivery's consumer can run to its own next
140
+ * suspension point first; see the comment at that `await` for why ordering the
141
+ * `resolve()` calls alone is not enough.
118
142
  *
119
- * `deferBehindKinds` is the opposite kind(s): a hook defers behind earlier
120
- * WAITS (not earlier hooks those are sequential same-entity payloads), a
121
- * wait defers behind earlier HOOKS.
143
+ * One asymmetry: a STEP result additionally skips any earlier delivery that
144
+ * will not resolve on its own, i.e. one blocked (directly or transitively) on
145
+ * a buffered hook payload no consumer has claimed. Such a payload is delivered
146
+ * only when the workflow next reads the hook, and reaching that read very
147
+ * commonly requires the step result itself (`await stepX()` before the read).
148
+ * Gating the step on it would stall the workflow until the barrier's idle
149
+ * safety net fires, which then releases every delivery queued behind that
150
+ * payload at once — losing exactly the race this ordering exists to protect.
151
+ * Waits and hooks keep gating on unclaimed payloads: for them, waiting for the
152
+ * claim IS the ordering guarantee (a `wait_completed` must not preempt a
153
+ * payload the log ordered first).
122
154
  */
123
- export declare function awaitEarlierDeliveries(ctx: WorkflowOrchestratorContext, eventIndex: number | undefined, deferBehindKinds: readonly DeliveryKind[]): Promise<void>;
155
+ export declare function awaitEarlierDeliveries(ctx: WorkflowOrchestratorContext, eventIndex: number | undefined, kind: DeliveryKind): Promise<void>;
124
156
  /** Handle for a registered branch-deciding delivery barrier. */
125
157
  export interface DeliveryBarrier {
126
158
  /**
127
159
  * Mark this delivery as delivered to the workflow. Resolves its
128
- * `delivered` promise so any later-in-log opposite-kind delivery gated on
129
- * it (via {@link awaitEarlierDeliveries}) may proceed, and removes it from
130
- * the registry. Idempotent.
160
+ * `delivered` promise so any later-in-log delivery gated on it (via
161
+ * {@link awaitEarlierDeliveries}) may proceed, and removes it from the
162
+ * registry. Idempotent.
131
163
  */
132
164
  markDelivered: () => void;
165
+ /**
166
+ * Mark this delivery as committed to happening, for a barrier registered
167
+ * unarmed (a buffered hook payload) once a consumer has claimed it. From
168
+ * then on a later step result may be ordered behind it. Idempotent.
169
+ */
170
+ arm: () => void;
133
171
  }
134
172
  /**
135
173
  * Register a branch-deciding delivery at its event-log index so that later
136
- * opposite-kind deliveries can be ordered strictly after it. Returns an inert
137
- * handle when `pendingDeliveryBarriers` is not initialized.
174
+ * deliveries can be ordered strictly after it. Returns an inert handle when
175
+ * `pendingDeliveryBarriers` is not initialized.
176
+ *
177
+ * Pass `armed: false` for a delivery whose resolution waits on workflow code
178
+ * asking for it (a buffered hook payload); call `arm()` when it does.
138
179
  *
139
180
  * To guarantee a later delivery gated on this one can never hang when this
140
181
  * delivery is abandoned (the workflow took a different branch or is
141
182
  * suspending and never observes it), the barrier auto-resolves at idle.
183
+ *
184
+ * INVARIANT required of every call site: a barrier that is ever `armed` must
185
+ * be paired with a delivery chain that runs unconditionally — attached when
186
+ * the event is consumed (waits, step results, waiting-consumer hook
187
+ * payloads), or by the `claim()` whose invocation is what arms it (buffered
188
+ * hook payloads). The idle check ({@link scheduleWhenIdle}) refuses to
189
+ * observe idle while an armed, self-resolving barrier is undelivered, and the
190
+ * safety net below is itself idle-gated — so an armed barrier with no
191
+ * unconditional chain would livelock every idle check in the run, including
192
+ * its own retirement.
193
+ */
194
+ export declare function registerDeliveryBarrier(ctx: WorkflowOrchestratorContext, eventIndex: number | undefined, kind: DeliveryKind, options?: {
195
+ armed?: boolean;
196
+ }): DeliveryBarrier;
197
+ /**
198
+ * Whether no data delivery (step result, hook payload) is in flight right now.
199
+ *
200
+ * "In flight" is two distinct windows, each with its own guard:
201
+ * `pendingDeliveries > 0` covers hydration inside the serial queue slots, and
202
+ * {@link hasParkedCommittedDelivery} covers the detached gap between a slot
203
+ * releasing that counter and the delivery's `resolve()` actually running —
204
+ * deliberately outside `pendingDeliveries` (see step.ts), and invisible to it.
205
+ *
206
+ * Anything that decides a replay is over, or that a replay went wrong, has to
207
+ * consult this first: while it is false the workflow VM is mid-reaction, so
208
+ * what it has and has not done yet says nothing about the run. Two callers
209
+ * read it, for the two such decisions: {@link scheduleWhenIdle} for the
210
+ * suspension, and the events consumer's unconsumed-event check for divergence.
142
211
  */
143
- export declare function registerDeliveryBarrier(ctx: WorkflowOrchestratorContext, eventIndex: number | undefined, kind: DeliveryKind): DeliveryBarrier;
212
+ export declare function isDeliveryIdle(ctx: WorkflowOrchestratorContext): boolean;
144
213
  /**
145
214
  * Schedule a callback to fire only after all pending data deliveries
146
215
  * (step results, hook payloads) and async deserialization have completed.
147
- * Uses a polling loop: setTimeout(0) → check pendingDeliveries
148
- * if > 0, wait for promiseQueue → repeat. This handles the multi-round
149
- * delivery pattern where each hook payload delivery cycle appends new
150
- * async work to the promiseQueue.
216
+ * Uses a polling loop: setTimeout(0) → check pendingDeliveries and the
217
+ * barrier registry → if anything is still in flight, wait for promiseQueue →
218
+ * repeat. This handles the multi-round delivery pattern where each hook
219
+ * payload delivery cycle appends new async work to the promiseQueue. What
220
+ * counts as in flight is {@link isDeliveryIdle}.
151
221
  *
152
222
  * The initial `setTimeout(0)` macrotask is load-bearing and must NOT be
153
223
  * downgraded to a microtask (`queueMicrotask`/`Promise.resolve().then`).
@@ -1 +1 @@
1
- {"version":3,"file":"private.d.ts","sourceRoot":"","sources":["../src/private.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,MAAM,MAAM,YAAY,CACtB,IAAI,SAAS,YAAY,EAAE,GAAG,GAAG,EAAE,EACnC,MAAM,SAAS,YAAY,GAAG,OAAO,GAAG,OAAO,IAC7C,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAsEF;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,QAGxE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAoBxE;AAED;;;GAGG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,SAAS,GAAG,SAAS,CAAC;IACrC,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,cAAc,EAAE,cAAc,CAAC;IAC/B;;;OAGG;IACH,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACzC,eAAe,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B;;;;OAIG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,uBAAuB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAC5D;;;;;;;;;;;;;;;;OAgBG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAED,iEAAiE;AACjE,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3C,UAAU,oBAAoB;IAC5B,IAAI,EAAE,YAAY,CAAC;IACnB,gEAAgE;IAChE,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,2BAA2B,EAChC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,gBAAgB,EAAE,SAAS,YAAY,EAAE,GACxC,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED,gEAAgE;AAChE,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,aAAa,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,2BAA2B,EAChC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,IAAI,EAAE,YAAY,GACjB,eAAe,CA6BjB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,2BAA2B,EAChC,EAAE,EAAE,MAAM,IAAI,GACb,IAAI,CAYN"}
1
+ {"version":3,"file":"private.d.ts","sourceRoot":"","sources":["../src/private.ts"],"names":[],"mappings":"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"}