@xaendar/signals 0.4.5 → 0.4.6

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,280 +1,1007 @@
1
- import { Stack as e } from "@xaendar/common";
1
+ import { Stack } from "@xaendar/common";
2
2
  //#region ../packages/signals/src/lib/utils/globals/globals.ts
3
- var t = {
3
+ /**
4
+ * Global state for the signals runtime.
5
+ * Tracks the currently computing `Computed` instance, whether the state is frozen,
6
+ * and the current generation counter.
7
+ *
8
+ * @internal
9
+ */
10
+ var GLOBAL_STATE = {
4
11
  computing: null,
5
- frozen: !1
6
- }, n = new e();
7
- function r(e) {
8
- n.push(e), t.computing = e;
12
+ frozen: false
13
+ };
14
+ var computingStack = new Stack();
15
+ /**
16
+ * Pushes a `Computed` instance onto the computing stack and sets it as the
17
+ * currently active computation in `GLOBAL_STATE`.
18
+ *
19
+ * Should be called before executing a computed function to register
20
+ * dependency tracking.
21
+ *
22
+ * @param computed - The `Computed` instance entering the computation phase.
23
+ * @internal
24
+ */
25
+ function pushComputed(computed) {
26
+ computingStack.push(computed);
27
+ GLOBAL_STATE.computing = computed;
9
28
  }
10
- function i() {
11
- n.pop(), t.computing = n[n.length - 1] ?? null;
29
+ /**
30
+ * Pops the most recent `Computed` instance from the computing stack and
31
+ * restores the previous one as the active computation in `GLOBAL_STATE`.
32
+ *
33
+ * Should be called after a computed function finishes executing.
34
+ *
35
+ * @internal
36
+ */
37
+ function popComputed() {
38
+ computingStack.pop();
39
+ GLOBAL_STATE.computing = computingStack[computingStack.length - 1] ?? null;
12
40
  }
13
41
  //#endregion
14
42
  //#region ../packages/signals/src/lib/utils/private-symbol/private-symbol.ts
15
- var a = Symbol("signals-private");
16
- function o(e) {
17
- if (e !== a) throw Error("Invalid symbol");
43
+ /**
44
+ * Symbol not available in public API,
45
+ * used to call internal methods of `State` and `Computed` from `Watcher` without exposing them in the public API.
46
+ *
47
+ * @internal
48
+ */
49
+ var PRIVATE = Symbol("signals-private");
50
+ /**
51
+ * Asserts that the provided symbol matches the internal {@link PRIVATE} symbol,
52
+ * ensuring the caller has access to internal APIs.
53
+ *
54
+ * Throws if the symbol does not match, preventing external code from
55
+ * invoking methods intended for internal use only.
56
+ *
57
+ * @param symbol - The symbol to validate against {@link PRIVATE}.
58
+ * @throws {Error} If `symbol` does not match {@link PRIVATE}.
59
+ * @internal
60
+ */
61
+ function assertPrivateContext(symbol) {
62
+ if (symbol !== PRIVATE) throw new Error("Invalid symbol");
18
63
  }
19
64
  //#endregion
20
65
  //#region ../packages/signals/src/lib/utils/dev-mode/dev-mode.ts
21
- var s = !1;
22
- function c(e) {
23
- s = e;
66
+ /**
67
+ * Whether the library is runnign in development mode
68
+ * Used to log extra information for example
69
+ * - Invalid transition states for {@link Computed} or {@link Watcher}
70
+ */
71
+ var devMode = false;
72
+ /**
73
+ * Sets the development mode flag.
74
+ * @param mode - `true` to enable dev mode, `false` to disable it.
75
+ */
76
+ function setDevMode(mode) {
77
+ devMode = mode;
24
78
  }
25
- function l() {
26
- return s;
79
+ /**
80
+ * Returns the current development mode state.
81
+ * @returns `true` if dev mode is enabled, `false` otherwise.
82
+ */
83
+ function isDevMode() {
84
+ return devMode;
27
85
  }
28
86
  //#endregion
29
87
  //#region ../packages/signals/src/lib/models/computed/computed.ts
30
- var u = class e {
31
- #e;
32
- #t;
33
- #n;
34
- getSources(e) {
35
- return o(e), [...this.#n];
88
+ /**
89
+ * A read-only Signal whose value is derived lazily from other Signals.
90
+ *
91
+ * The value is recomputed only when explicitly read and only if one or more
92
+ * of its (recursive) dependencies have changed since the last evaluation.
93
+ * The result is cached and reused until the Signal becomes stale again.
94
+ *
95
+ * @template T The type of the computed value.
96
+ *
97
+ * @see Signal algorithms — "The Signal.Computed class"
98
+ */
99
+ var Computed = class Computed {
100
+ /**
101
+ * The current value of the signal.
102
+ *
103
+ * Uninitialised (`!`) until the first evaluation. After that, holds either
104
+ * the return value of `#callback` or a boxed error
105
+ * `{ isError: true; value: Error }` if the last evaluation threw.
106
+ *
107
+ * @internalSlot
108
+ * @see Signal algorithms — "Signal.Computed internal slots"
109
+ */
110
+ #value;
111
+ /**
112
+ * The current evaluation state of this Signal.
113
+ *
114
+ * - `~dirty~` — value is known to be stale or has never been evaluated.
115
+ * - `~checked~` — an indirect source changed; may or may not be stale.
116
+ * - `~computing~` — `#callback` is currently executing; guards against cycles.
117
+ * - `~clean~` — cached value is up-to-date.
118
+ *
119
+ * @internalSlot
120
+ * @see Signal algorithms — "Signal.Computed State machine"
121
+ */
122
+ #state;
123
+ /**
124
+ * The ordered set of Signals read during the last evaluation of
125
+ * `#callback`. Cleared and rebuilt on every re-evaluation so that
126
+ * conditional branches that are no longer taken stop being tracked.
127
+ *
128
+ * May contain both `State` and `Computed` instances.
129
+ *
130
+ * @internalSlot
131
+ * @see Signal algorithms — "Signal.Computed internal slots"
132
+ */
133
+ #sources;
134
+ /**
135
+ * Returns a snapshot of the current sources set for introspection.
136
+ *
137
+ * @param symbol - Private access symbol; rejects calls from outside the library.
138
+ * @returns An array of `State` and `Computed` instances that this Signal depends on.
139
+ * @internal
140
+ */
141
+ getSources(symbol) {
142
+ assertPrivateContext(symbol);
143
+ return [...this.#sources];
36
144
  }
37
- #r;
38
- getSinks(e) {
39
- return o(e), [...this.#r];
145
+ /**
146
+ * The set of Signals and Watchers that directly depend on this Signal.
147
+ *
148
+ * Populated only when this Signal is reachable from at least one active
149
+ * `Watcher`. An un-watched `Computed` has an empty sinks set, which allows
150
+ * it to be garbage-collected independently from the rest of the graph.
151
+ *
152
+ * @internalSlot
153
+ * @see Signal algorithms — "Signal.Computed internal slots"
154
+ * @see Method — `Signal.Computed.prototype.get` (NOTE on sinks)
155
+ */
156
+ #sinks;
157
+ /**
158
+ * Returns a snapshot of the current sinks set for introspection.
159
+ *
160
+ * @param symbol - Private access symbol; rejects calls from outside the library.
161
+ * @returns An array of `Computed` and `Watcher` instances that depend on this Signal.
162
+ * @internal
163
+ */
164
+ getSinks(symbol) {
165
+ assertPrivateContext(symbol);
166
+ return [...this.#sinks];
40
167
  }
41
- #i;
42
- #a;
43
- constructor(e, t) {
44
- this.#a = e, this.#i = t?.equals ?? Object.is, this.#n = /* @__PURE__ */ new Set(), this.#r = /* @__PURE__ */ new Set(), this.#t = "dirty";
168
+ /**
169
+ * The equality function used to determine whether a newly computed value
170
+ * is meaningfully different from the previously cached one.
171
+ *
172
+ * Called as `equals.call(computed, oldValue, newValue)`. Returns `true` if
173
+ * the values are considered equal, in which case no downstream propagation
174
+ * occurs. Defaults to `Object.is` when not provided via options.
175
+ *
176
+ * If this function throws, the exception is cached as the Signal's value
177
+ * and the outcome is treated as `~dirty~`.
178
+ *
179
+ * @internalSlot
180
+ * @see Signal algorithms — "Signal.Computed internal slots"
181
+ * @see Algorithm — "Set Signal value"
182
+ */
183
+ #equals;
184
+ /**
185
+ * The pure function that produces this Signal's value. Evaluated lazily
186
+ * whenever the Signal is read while in a `~dirty~` or `~checked~` state.
187
+ *
188
+ * Called with `this` bound to the `Computed` instance itself so that
189
+ * internal methods (e.g. `addSource`) are accessible if needed.
190
+ * Any exception thrown by this function is caught and cached.
191
+ *
192
+ * @internalSlot
193
+ * @see Signal algorithms — "Signal.Computed internal slots"
194
+ */
195
+ #callback;
196
+ /**
197
+ * Creates a new `Computed` signal.
198
+ *
199
+ * The Signal starts in the `~dirty~` state with an uninitialised value, so
200
+ * `#callback` will be invoked on the first `get()`.
201
+ *
202
+ * @param cb - Pure function evaluated lazily to produce the value.
203
+ * Receives the `Computed` instance as `this`.
204
+ * @param options - Optional configuration:
205
+ * - `equals` — custom equality function; defaults to `Object.is`.
206
+ *
207
+ * @see Signal algorithms — "Signal.Computed Constructor"
208
+ */
209
+ constructor(cb, options) {
210
+ this.#callback = cb;
211
+ this.#equals = options?.equals ?? Object.is;
212
+ this.#sources = /* @__PURE__ */ new Set();
213
+ this.#sinks = /* @__PURE__ */ new Set();
214
+ this.#state = "dirty";
45
215
  }
216
+ /**
217
+ * Returns the current value of this Signal, re-evaluating `#callback` if
218
+ * the cached value may be stale.
219
+ *
220
+ * Registers this Signal as a source of any outer `Computed` currently
221
+ * being evaluated (automatic dependency tracking).
222
+ *
223
+ * If the state is `~dirty~` or `~checked~`, walks the source graph
224
+ * depth-first to find and recalculate the deepest stale `Computed` first,
225
+ * then re-checks upward until this Signal is `~clean~`.
226
+ *
227
+ * @returns The current computed value, or a boxed error object if the last
228
+ * evaluation threw.
229
+ * @throws If `frozen` is `true`.
230
+ * @throws If the Signal is in the `~computing~` state (cyclic dependency).
231
+ *
232
+ * @see Signal algorithms — "Method: Signal.Computed.prototype.get"
233
+ */
46
234
  get() {
47
- if (t.frozen) throw Error("Cannot get value of a Computed signal while the global state is frozen");
48
- if (this.#t === "computing") throw Error("Circular dependency detected while computing a Computed signal");
49
- if (t.computing?.addSource(this, a), this.#r.size === 0) this.#s();
50
- else if (this.#t === "dirty" || this.#t === "checked") for (; this.#t === "dirty" || this.#t === "checked";) this.#o().#s();
51
- return this.#e;
235
+ if (GLOBAL_STATE.frozen) throw new Error("Cannot get value of a Computed signal while the global state is frozen");
236
+ if (this.#state === "computing") throw new Error("Circular dependency detected while computing a Computed signal");
237
+ GLOBAL_STATE.computing?.addSource(this, PRIVATE);
238
+ if (this.#sinks.size === 0) this.#computeValue();
239
+ else if (this.#state === "dirty" || this.#state === "checked") while (this.#state === "dirty" || this.#state === "checked") this.#findDeepestStale().#computeValue();
240
+ return this.#value;
52
241
  }
53
- addSource(e, t) {
54
- o(t), this.#n.add(e), e.addSink(this, a);
242
+ /**
243
+ * Registers a Signal as a source of this `Computed`, discovered during the
244
+ * execution of `#callback`.
245
+ *
246
+ * If this `Computed` is currently being watched (has at least one sink),
247
+ * the source is also informed of this Signal as a new sink, building the
248
+ * live push-notification chain upward.
249
+ *
250
+ * @param source - The Signal read during evaluation.
251
+ * @param symbol - Private access symbol; rejects calls from outside the library.
252
+ * @internal
253
+ */
254
+ addSource(source, symbol) {
255
+ assertPrivateContext(symbol);
256
+ this.#sources.add(source);
257
+ source.addSink(this, PRIVATE);
55
258
  }
56
- getState(e) {
57
- return o(e), this.#t;
259
+ /**
260
+ * Returns the current evaluation state of this Signal.
261
+ *
262
+ * @param symbol - Private access symbol; rejects calls from outside the library.
263
+ * @internal
264
+ * @see Signal algorithms — "Signal.Computed State machine"
265
+ */
266
+ getState(symbol) {
267
+ assertPrivateContext(symbol);
268
+ return this.#state;
58
269
  }
59
- setState(t, n) {
60
- if (o(n), this.#t !== t) {
61
- if (!this.#d(this.#t, t)) {
62
- l() && (console.warn(`Invalid state transition from ${this.#t} to ${t} in Computed Signal`), console.warn((/* @__PURE__ */ Error()).stack));
63
- return;
270
+ /**
271
+ * Transitions this Signal to a new evaluation state.
272
+ *
273
+ * Only valid transitions (as defined by the state machine) are allowed.
274
+ * Invalid transitions throw an error.
275
+ *
276
+ * @param newState - The target state.
277
+ * @param symbol - Private access symbol; rejects calls from outside the library.
278
+ * @throws If the transition from the current state to `newState` is not allowed.
279
+ * @internal
280
+ * @see Signal algorithms — "Signal.Computed State machine"
281
+ */
282
+ setState(newState, symbol) {
283
+ assertPrivateContext(symbol);
284
+ if (this.#state === newState) return;
285
+ if (!this.#isValidTransition(this.#state, newState)) {
286
+ if (isDevMode()) {
287
+ console.warn(`Invalid state transition from ${this.#state} to ${newState} in Computed Signal`);
288
+ console.warn((/* @__PURE__ */ new Error()).stack);
64
289
  }
65
- this.#t = t, (this.#t === "dirty" || this.#t === "checked") && this.#r.forEach((t) => t instanceof e ? t.setState("checked", a) : t.notify(a));
290
+ return;
66
291
  }
292
+ this.#state = newState;
293
+ if (this.#state === "dirty" || this.#state === "checked") this.#sinks.forEach((sink) => sink instanceof Computed ? sink.setState("checked", PRIVATE) : sink.notify(PRIVATE));
67
294
  }
68
- addSink(e, t) {
69
- o(t), this.#r.size === 0 && this.#n.forEach((e) => e.addSink(this, a)), this.#r.add(e);
295
+ /**
296
+ * Registers a new sink (a `Computed` or `Watcher` that directly depends on
297
+ * this Signal) in the internal sinks set.
298
+ *
299
+ * If this is the first sink, propagates the sink registration recursively
300
+ * up through `#sources`, building the live dependency chain that enables
301
+ * push-based invalidation.
302
+ *
303
+ * @param sink - The dependent node to register.
304
+ * @param symbol - Private access symbol; rejects calls from outside the library.
305
+ * @internal
306
+ */
307
+ addSink(sink, symbol) {
308
+ assertPrivateContext(symbol);
309
+ if (this.#sinks.size === 0) this.#sources.forEach((source) => source.addSink(this, PRIVATE));
310
+ this.#sinks.add(sink);
70
311
  }
71
- removeSink(e, t) {
72
- o(t), this.#r.delete(e), this.#r.size === 0 && this.#n.forEach((e) => e.removeSink(this, a));
312
+ /**
313
+ * Removes a sink from the internal sinks set.
314
+ *
315
+ * If the sinks set becomes empty after removal, propagates the removal
316
+ * recursively up through `#sources`, tearing down the live dependency
317
+ * chain and allowing garbage collection of un-watched nodes.
318
+ *
319
+ * @param sink - The dependent node to remove.
320
+ * @param symbol - Private access symbol; rejects calls from outside the library.
321
+ * @internal
322
+ */
323
+ removeSink(sink, symbol) {
324
+ assertPrivateContext(symbol);
325
+ this.#sinks.delete(sink);
326
+ if (this.#sinks.size === 0) this.#sources.forEach((source) => source.removeSink(this, PRIVATE));
73
327
  }
74
- #o() {
75
- let t = [...this.#n].find((t) => t instanceof e && (t.#t === "dirty" || t.#t === "checked"));
76
- return t ? t.#o() : this;
328
+ /**
329
+ * Recursively walks the source graph depth-first to find the deepest,
330
+ * left-most `Computed` node that is in a `~dirty~` or `~checked~` state.
331
+ *
332
+ * This ensures that recalculation always starts from the bottom of the
333
+ * dependency graph, so every node sees already-updated dependencies —
334
+ * the core of glitch-free evaluation.
335
+ *
336
+ * Cuts off the search when hitting a `~clean~` `Computed` source, since
337
+ * its subtree is guaranteed to be up-to-date.
338
+ *
339
+ * @returns The deepest stale `Computed` found, or `node` itself if none of
340
+ * its sources are stale.
341
+ */
342
+ #findDeepestStale() {
343
+ const unclearNode = [...this.#sources].find((source) => source instanceof Computed && (source.#state === "dirty" || source.#state === "checked"));
344
+ return unclearNode ? unclearNode.#findDeepestStale() : this;
77
345
  }
78
- #s() {
79
- this.#n.forEach((e) => e.removeSink(this, a)), this.#n.clear(), r(this), this.setState("computing", a);
80
- let t;
346
+ /**
347
+ * Executes `#callback` to recompute this Signal's value.
348
+ *
349
+ * Implements the "recalculate dirty computed Signal" algorithm:
350
+ * 1. Clears stale sources and removes this Signal from their sinks.
351
+ * 2. Sets `computing` to this Signal for automatic dependency tracking.
352
+ * 3. Runs the callback, caching the return value or any thrown exception.
353
+ * 4. Restores the previous `computing` value.
354
+ * 5. Runs the "set Signal value" algorithm to detect value changes.
355
+ * 6. Transitions state to `~clean~`.
356
+ * 7. Propagates `~dirty~` to sinks (or attempts `~clean~` if value unchanged).
357
+ *
358
+ * @see Signal algorithms — "Algorithm: recalculate dirty computed Signal"
359
+ */
360
+ #computeValue() {
361
+ this.#sources.forEach((source) => source.removeSink(this, PRIVATE));
362
+ this.#sources.clear();
363
+ pushComputed(this);
364
+ this.setState("computing", PRIVATE);
365
+ let newValue;
81
366
  try {
82
- t = this.#a.call(this);
83
- } catch (e) {
84
- t = {
85
- isError: !0,
86
- value: e
367
+ newValue = this.#callback.call(this);
368
+ } catch (error) {
369
+ newValue = {
370
+ isError: true,
371
+ value: error
87
372
  };
88
373
  } finally {
89
- i();
374
+ popComputed();
90
375
  }
91
- let n = this.#c(t);
92
- this.setState("clean", a), n === "dirty" ? this.#r.forEach((t) => t instanceof e ? t.setState("dirty", a) : t.notify(a)) : this.#l();
376
+ const outcome = this.#setValue(newValue);
377
+ this.setState("clean", PRIVATE);
378
+ outcome === "dirty" ? this.#sinks.forEach((sink) => sink instanceof Computed ? sink.setState("dirty", PRIVATE) : sink.notify(PRIVATE)) : this.#propagateClean();
93
379
  }
94
- #c(e) {
95
- let t = this.#e;
96
- if (this.#u(e)) return this.#e = e, "dirty";
380
+ /**
381
+ * Implements the "set Signal value" algorithm.
382
+ *
383
+ * Compares the new value against the cached one using `#equals`. If equal,
384
+ * returns `~clean~` and leaves `#value` untouched. Otherwise updates
385
+ * `#value` and returns `~dirty~`.
386
+ *
387
+ * Special cases:
388
+ * - If `newValue` is a boxed error, `#equals` is skipped and the error is
389
+ * cached directly.
390
+ * - If `#equals` itself throws, the exception is cached as a boxed error
391
+ * and the outcome is `~dirty~`.
392
+ *
393
+ * @param newValue - The value (or boxed error) produced by `#callback`.
394
+ * @returns `~clean~` if the value is unchanged, `~dirty~` otherwise.
395
+ *
396
+ * @see Signal algorithms — "Set Signal value algorithm"
397
+ */
398
+ #setValue(newValue) {
399
+ const oldValue = this.#value;
400
+ if (this.#isErrorValue(newValue)) {
401
+ this.#value = newValue;
402
+ return "dirty";
403
+ }
97
404
  try {
98
- if (!this.#u(t) && this.#i.call(this, t, e)) return "clean";
99
- } catch (e) {
100
- return this.#e = {
101
- isError: !0,
102
- value: e
103
- }, "dirty";
405
+ if (!this.#isErrorValue(oldValue) && this.#equals.call(this, oldValue, newValue)) return "clean";
406
+ } catch (equalsError) {
407
+ this.#value = {
408
+ isError: true,
409
+ value: equalsError
410
+ };
411
+ return "dirty";
104
412
  }
105
- return this.#e = e, "dirty";
413
+ this.#value = newValue;
414
+ return "dirty";
106
415
  }
107
- #l() {
108
- [...this.#r].filter((t) => t instanceof e && t.#t === "checked").forEach((t) => {
109
- [...t.#n].every((t) => !(t instanceof e) || t.#t === "clean") && (t.#t = "clean", t.#l());
416
+ /**
417
+ * Recursively marks `~checked~` sinks as `~clean~` when all of their
418
+ * immediate sources are already `~clean~`.
419
+ *
420
+ * Called after a recalculation that produced an unchanged value (`~clean~`
421
+ * outcome from `#setValue`). Propagates the clean signal upward through
422
+ * the graph so that Computed nodes that were only transitively dirty — and
423
+ * whose dependencies have not actually changed — are not needlessly
424
+ * re-evaluated on the next read.
425
+ *
426
+ * @see Signal algorithms — "Algorithm: recalculate dirty computed Signal"
427
+ */
428
+ #propagateClean() {
429
+ [...this.#sinks].filter((sink) => sink instanceof Computed && sink.#state === "checked").forEach((sink) => {
430
+ if ([...sink.#sources].every((source) => !(source instanceof Computed) || source.#state === "clean")) {
431
+ sink.#state = "clean";
432
+ sink.#propagateClean();
433
+ }
110
434
  });
111
435
  }
112
- #u(e) {
113
- return typeof e == "object" && !!e && "isError" in e;
436
+ /**
437
+ * Type guard that checks whether a value is a boxed error object.
438
+ *
439
+ * Used to distinguish a legitimately computed value from a cached
440
+ * exception produced by `#callback` or `#equals`.
441
+ *
442
+ * @param value - The value to inspect.
443
+ * @returns `true` if `value` is `{ isError: true; value: Error }`.
444
+ */
445
+ #isErrorValue(value) {
446
+ return typeof value === "object" && !!value && "isError" in value;
114
447
  }
115
- #d(e, t) {
116
- switch (e) {
117
- case "checked": return t === "clean" || t === "dirty";
118
- case "clean": return t === "checked" || t === "dirty";
119
- case "dirty": return t === "computing";
120
- case "computing": return t === "clean";
448
+ #isValidTransition(from, to) {
449
+ switch (from) {
450
+ case "checked": return to === "clean" || to === "dirty";
451
+ case "clean": return to === "checked" || to === "dirty";
452
+ case "dirty": return to === "computing";
453
+ case "computing": return to === "clean";
121
454
  }
122
455
  }
123
- }, d = class {
124
- #e;
125
- #t;
126
- #n;
127
- #r;
128
- #i;
129
- getSinks(e) {
130
- return o(e), [...this.#i];
456
+ };
457
+ //#endregion
458
+ //#region ../packages/signals/src/lib/models/state/state.ts
459
+ var State = class {
460
+ /**
461
+ * The current value of the signal.
462
+ *
463
+ * Initialised to `initialValue` in the constructor and updated by `set`
464
+ * whenever the new value is not equal to the current one according to
465
+ * `#equals`.
466
+ *
467
+ * @internalSlot
468
+ * @see Signal algorithms — 'Signal.State internal slots'
469
+ */
470
+ #value;
471
+ /**
472
+ * The equality function used to determine whether a new value is
473
+ * meaningfully different from the current one.
474
+ *
475
+ * Called as `equals.call(signal, oldValue, newValue)`. If it returns
476
+ * `true` the signal is considered unchanged and no propagation occurs.
477
+ * Defaults to `Object.is` when not provided via options.
478
+ *
479
+ * @internalSlot
480
+ * @see Signal algorithms — 'Signal.State internal slots'
481
+ * @see Algorithm — 'Set Signal value'
482
+ */
483
+ #equals;
484
+ /**
485
+ * Optional callback invoked (with `frozen = true`) the first time this
486
+ * Signal gains a sink — i.e. when it transitions from un-observed to
487
+ * observed by at least one `Watcher` (directly or transitively).
488
+ *
489
+ * @internalSlot
490
+ * @see Signal algorithms — 'Signal.State internal slots'
491
+ * @see Method — `Signal.subtle.Watcher.prototype.watch`
492
+ */
493
+ #watched;
494
+ /**
495
+ * Optional callback invoked (with `frozen = true`) when this Signal loses
496
+ * its last sink — i.e. when it transitions from observed back to
497
+ * un-observed.
498
+ *
499
+ * @internalSlot
500
+ * @see Signal algorithms — 'Signal.State internal slots'
501
+ * @see Method — `Signal.subtle.Watcher.prototype.unwatch`
502
+ */
503
+ #unwatched;
504
+ /**
505
+ * The set of watched signals that directly depend on this one.
506
+ *
507
+ * Populated only when this Signal is reachable from at least one active
508
+ * `Watcher` — un-watched Signals have an empty sinks set, which allows
509
+ * them to be garbage-collected independently from the rest of the graph.
510
+ *
511
+ * Should contain both `Computed` and `Watcher` instances, as both can be
512
+ * direct dependents of a `State`.
513
+ *
514
+ * @internalSlot
515
+ * @see Signal algorithms — 'Signal.State internal slots'
516
+ * @see Method — `Signal.State.prototype.get` (NOTE on sinks)
517
+ */
518
+ #sinks;
519
+ /**
520
+ * Returns a snapshot of the current sinks set for introspection.
521
+ *
522
+ * @param symbol - Private access symbol; rejects calls from outside the library.
523
+ * @returns An array of `Computed` and `Watcher` instances that depend on this Signal.
524
+ * @internal
525
+ */
526
+ getSinks(symbol) {
527
+ assertPrivateContext(symbol);
528
+ return [...this.#sinks];
131
529
  }
132
- constructor(e, t) {
133
- this.#e = e, this.#t = t?.equals ?? Object.is, this.#n = t?.watched, this.#r = t?.unwatched, this.#i = /* @__PURE__ */ new Set();
530
+ /**
531
+ * Creates a new `State` signal.
532
+ *
533
+ * @param initialValue - The initial value of the signal.
534
+ * @param options - Optional configuration:
535
+ * - `equals` — custom equality function; defaults to `Object.is`.
536
+ * - `watched` — called when the signal gains its first sink.
537
+ * - `unwatched` — called when the signal loses its last sink.
538
+ *
539
+ * @see Signal algorithms — 'Constructor: Signal.State(initialValue, options)'
540
+ */
541
+ constructor(initialValue, options) {
542
+ this.#value = initialValue;
543
+ this.#equals = options?.equals ?? Object.is;
544
+ this.#watched = options?.watched;
545
+ this.#unwatched = options?.unwatched;
546
+ this.#sinks = /* @__PURE__ */ new Set();
134
547
  }
548
+ /**
549
+ * Returns the current value of the signal, registering this Signal as a
550
+ * source of the innermost `Computed` currently being evaluated (if any).
551
+ *
552
+ * @throws If `frozen` is `true` — reads are forbidden while a protected
553
+ * callback (`notify`, `watched`, `unwatched`) is executing.
554
+ *
555
+ * @see Signal algorithms — 'Method: Signal.State.prototype.get()'
556
+ */
135
557
  get() {
136
- if (t.frozen) throw Error("Cannot get value while signals are frozen");
137
- return t.computing?.addSource(this, a), this.#e;
558
+ if (GLOBAL_STATE.frozen) throw new Error("Cannot get value while signals are frozen");
559
+ GLOBAL_STATE.computing?.addSource(this, PRIVATE);
560
+ return this.#value;
138
561
  }
139
- set(e) {
140
- if (t.frozen) throw Error("Cannot set value while signals are frozen");
141
- this.#t.call(this, this.#e, e) || (this.#e = e, this.#i.forEach((e) => e instanceof u ? e.setState("dirty", a) : e.notify(a)));
562
+ /**
563
+ * Updates the signal's value and propagates changes to all dependent
564
+ * sinks.
565
+ *
566
+ * If `equals(currentValue, newValue)` returns `true` the call is a no-op
567
+ * and no propagation occurs. Otherwise `#value` is updated, all direct
568
+ * `Computed` sinks are marked `~dirty~`, indirect ones `~checked~`, and
569
+ * each reachable `Watcher` has its `notify` callback invoked synchronously
570
+ * (with `frozen = true`).
571
+ *
572
+ * @param newValue - The new value to set.
573
+ * @throws If `frozen` is `true` — writes are forbidden while a protected
574
+ * callback is executing.
575
+ *
576
+ * @see Signal algorithms — 'Method: Signal.State.prototype.set(newValue)'
577
+ * @see Algorithm — 'Set Signal value'
578
+ */
579
+ set(newValue) {
580
+ if (GLOBAL_STATE.frozen) throw new Error("Cannot set value while signals are frozen");
581
+ if (!this.#equals.call(this, this.#value, newValue)) {
582
+ this.#value = newValue;
583
+ this.#sinks.forEach((sink) => sink instanceof Computed ? sink.setState("dirty", PRIVATE) : sink.notify(PRIVATE));
584
+ }
142
585
  }
143
- addSink(e, n) {
144
- o(n);
145
- let r = this.#i.size === 0;
146
- if (this.#i.add(e), r && this.#n) {
147
- t.frozen = !0;
586
+ /**
587
+ * Registers a new sink (a `Computed` or `Watcher` that depends on this
588
+ * Signal) in the internal sinks set.
589
+ *
590
+ * Called by `Watcher.prototype.watch` when building the live dependency
591
+ * chain, and by `Computed` when propagating sink registration up through
592
+ * its sources.
593
+ *
594
+ * @param sink - The dependent node to register.
595
+ * @param symbol - The private symbol for validation.
596
+ * @internal
597
+ */
598
+ addSink(sink, symbol) {
599
+ assertPrivateContext(symbol);
600
+ const empty = this.#sinks.size === 0;
601
+ this.#sinks.add(sink);
602
+ if (empty && this.#watched) {
603
+ GLOBAL_STATE.frozen = true;
148
604
  try {
149
- this.#n();
605
+ this.#watched();
150
606
  } finally {
151
- t.frozen = !1;
607
+ GLOBAL_STATE.frozen = false;
152
608
  }
153
609
  }
154
610
  }
155
- removeSink(e, n) {
156
- if (o(n), this.#i.delete(e), this.#i.size === 0 && this.#r) {
157
- t.frozen = !0;
611
+ /**
612
+ * Removes a sink from the internal sinks set.
613
+ *
614
+ * Called by `Watcher.prototype.unwatch` when tearing down the live
615
+ * dependency chain. If the sinks set becomes empty after removal, the
616
+ * caller is responsible for propagating the removal up through this
617
+ * Signal's sources.
618
+ *
619
+ * @param sink - The dependent node to remove.
620
+ * @param symbol - The private symbol for validation.
621
+ * @internal
622
+ */
623
+ removeSink(sink, symbol) {
624
+ assertPrivateContext(symbol);
625
+ this.#sinks.delete(sink);
626
+ if (this.#sinks.size === 0 && this.#unwatched) {
627
+ GLOBAL_STATE.frozen = true;
158
628
  try {
159
- this.#r();
629
+ this.#unwatched();
160
630
  } finally {
161
- t.frozen = !1;
631
+ GLOBAL_STATE.frozen = false;
162
632
  }
163
633
  }
164
634
  }
165
- }, f = class {
166
- #e;
167
- #t;
168
- getSources(e) {
169
- return o(e), [...this.#t];
635
+ };
636
+ //#endregion
637
+ //#region ../packages/signals/src/lib/models/watcher/watcher.ts
638
+ /**
639
+ * A `Watcher` observes a set of Signals and fires a `notify` callback
640
+ * synchronously when any of their (recursive) dependencies change.
641
+ *
642
+ * It is the low-level primitive on top of which frameworks implement
643
+ * effects and scheduling. It does not hold a value and has no generic
644
+ * type parameter.
645
+ *
646
+ * @see Signal algorithms — 'The `Signal.subtle.Watcher` class'
647
+ */
648
+ var Watcher = class {
649
+ /**
650
+ * The current state of the Watcher.
651
+ *
652
+ * - `~waiting~` — newly created, or `notify` has already been called since
653
+ * the last `watch` call. Not actively observing changes.
654
+ * - `~watching~` — actively watching; no dependency has changed yet.
655
+ * - `~pending~` — a dependency has changed but `notify` has not yet run.
656
+ *
657
+ * @internalSlot
658
+ * @see Signal algorithms — 'Signal.subtle.Watcher State machine'
659
+ */
660
+ #state;
661
+ /**
662
+ * The ordered set of Signals this Watcher is currently watching.
663
+ * May contain both `State` and `Computed` instances.
664
+ *
665
+ * @internalSlot
666
+ * @see Signal algorithms — 'Signal.subtle.Watcher internal slots'
667
+ */
668
+ #signals;
669
+ /**
670
+ * Returns a snapshot of the current watched signals set for introspection.
671
+ *
672
+ * @param symbol - Private access symbol; rejects calls from outside the library.
673
+ * @returns An array of `State` and `Computed` instances that this Watcher is watching.
674
+ * @internal
675
+ */
676
+ getSources(symbol) {
677
+ assertPrivateContext(symbol);
678
+ return [...this.#signals];
170
679
  }
171
- #n;
172
- constructor(e) {
173
- this.#e = "waiting", this.#t = /* @__PURE__ */ new Set(), this.#n = e;
680
+ /**
681
+ * The callback invoked synchronously when a watched Signal (or one of its
682
+ * recursive dependencies) changes for the first time since the last
683
+ * `watch` call.
684
+ *
685
+ * Receives the Watcher itself as `this`. No Signals may be read or written
686
+ * during its execution (`frozen` is `true` for its entire duration).
687
+ *
688
+ * @internalSlot
689
+ * @see Signal algorithms — 'Signal.subtle.Watcher internal slots'
690
+ */
691
+ #notifyCallback;
692
+ /**
693
+ * Creates a new Watcher.
694
+ *
695
+ * The Watcher starts in the `~waiting~` state with an empty signals set.
696
+ *
697
+ * @param notifyCallback - Called synchronously (with `frozen = true`) the
698
+ * first time a watched dependency changes after each `watch` call. No
699
+ * Signals may be read or written inside this callback.
700
+ *
701
+ * @see Signal algorithms — 'Constructor: new Signal.subtle.Watcher(callback)'
702
+ */
703
+ constructor(notifyCallback) {
704
+ this.#state = "waiting";
705
+ this.#signals = /* @__PURE__ */ new Set();
706
+ this.#notifyCallback = notifyCallback;
174
707
  }
708
+ /**
709
+ * Returns the subset of watched Signals that are `Computed` instances
710
+ * currently in a `~dirty~` or `~checked~` state, meaning they may have a
711
+ * stale value that has not yet been re-evaluated.
712
+ *
713
+ * Typically called inside the microtask scheduled by the `notify` callback
714
+ * to know which Signals need to be pulled.
715
+ *
716
+ * @returns An array of `Computed` signals that are dirty or checked.
717
+ *
718
+ * @see Signal algorithms — 'Method: Signal.subtle.Watcher.prototype.getPending()'
719
+ */
175
720
  getPending() {
176
- return [...this.#t].filter((e) => {
177
- if (!(e instanceof u)) return !1;
178
- let t = e.getState(a);
179
- return t === "dirty" || t === "checked";
721
+ return [...this.#signals].filter((signal) => {
722
+ if (!(signal instanceof Computed)) return false;
723
+ const state = signal.getState(PRIVATE);
724
+ return state === "dirty" || state === "checked";
180
725
  });
181
726
  }
182
- watch(...e) {
183
- if (t.frozen) throw Error("Cannot watch signals while frozen");
184
- e.forEach((e) => {
185
- if (this.#t.has(e)) throw Error("Cannot watch a signal that is already being watched");
186
- this.#t.add(e), e.addSink(this, a);
187
- }), this.setState("watching", a);
727
+ /**
728
+ * Adds the given Signals to the watched set and transitions the Watcher to
729
+ * the `~watching~` state.
730
+ *
731
+ * For each newly-watched Signal, the Watcher is registered as a sink and —
732
+ * if it is the first sink — the sink registration is propagated recursively
733
+ * up through the Signal's sources, building the live dependency chain.
734
+ *
735
+ * The `watched` callback of each Signal (if any) is called with
736
+ * `frozen = true`.
737
+ *
738
+ * @param signals - One or more `State` signals to start watching.
739
+ * @throws If `frozen` is `true` at the time of the call.
740
+ *
741
+ * @see Signal algorithms — 'Method: Signal.subtle.Watcher.prototype.watch(...signals)'
742
+ */
743
+ watch(...signals) {
744
+ if (GLOBAL_STATE.frozen) throw new Error("Cannot watch signals while frozen");
745
+ signals.forEach((signal) => {
746
+ if (this.#signals.has(signal)) throw new Error("Cannot watch a signal that is already being watched");
747
+ this.#signals.add(signal);
748
+ signal.addSink(this, PRIVATE);
749
+ });
750
+ this.setState("watching", PRIVATE);
188
751
  }
189
- unwatch(...e) {
190
- if (t.frozen) throw Error("Cannot unwatch signals while frozen");
191
- e.forEach((e) => {
192
- if (!this.#t.has(e)) throw Error("Cannot unwatch a signal that is not being watched");
193
- this.#t.delete(e), e.removeSink(this, a);
194
- }), this.#t.size || this.setState("waiting", a);
752
+ /**
753
+ * Removes the given Signals from the watched set.
754
+ *
755
+ * For each removed Signal, the Watcher is unregistered as a sink. If the
756
+ * Signal's sink set becomes empty as a result, the removal is propagated
757
+ * recursively up through its sources, tearing down the live dependency
758
+ * chain and allowing garbage collection of unwatched nodes.
759
+ *
760
+ * The `unwatched` callback of each Signal (if any) is called with
761
+ * `frozen = true`.
762
+ *
763
+ * If no Signals remain in the watched set, the Watcher transitions back to
764
+ * the `~waiting~` state.
765
+ *
766
+ * @param signals - One or more `State` signals to stop watching.
767
+ * @throws If `frozen` is `true` at the time of the call.
768
+ * @throws If any of the given Signals is not currently being watched.
769
+ *
770
+ * @see Signal algorithms — 'Method: Signal.subtle.Watcher.prototype.unwatch(...signals)'
771
+ */
772
+ unwatch(...signals) {
773
+ if (GLOBAL_STATE.frozen) throw new Error("Cannot unwatch signals while frozen");
774
+ signals.forEach((signal) => {
775
+ if (!this.#signals.has(signal)) throw new Error("Cannot unwatch a signal that is not being watched");
776
+ this.#signals.delete(signal);
777
+ signal.removeSink(this, PRIVATE);
778
+ });
779
+ if (!this.#signals.size) this.setState("waiting", PRIVATE);
195
780
  }
196
- getState(e) {
197
- return o(e), this.#e;
781
+ /**
782
+ * Get the current state of the Watcher.
783
+ * @param symbol - The private symbol for prevent external calls.
784
+ */
785
+ getState(symbol) {
786
+ assertPrivateContext(symbol);
787
+ return this.#state;
198
788
  }
199
- setState(e, t) {
200
- if (o(t), this.#e !== e) {
201
- if (!this.#r(this.#e, e)) {
202
- l() && (console.warn(`Invalid state transition from ${this.#e} to ${e} in Watcher`), console.warn((/* @__PURE__ */ Error()).stack));
203
- return;
789
+ /**
790
+ * Set the current state of the Watcher.
791
+ * @param newState - The new state to set.
792
+ * @param symbol - The private symbol for prevent external calls.
793
+ * @throws If the transition from `pending` to `watching` is attempted.
794
+ */
795
+ setState(newState, symbol) {
796
+ assertPrivateContext(symbol);
797
+ if (this.#state === newState) return;
798
+ if (!this.#isValidTransition(this.#state, newState)) {
799
+ if (isDevMode()) {
800
+ console.warn(`Invalid state transition from ${this.#state} to ${newState} in Watcher`);
801
+ console.warn((/* @__PURE__ */ new Error()).stack);
204
802
  }
205
- this.#e = e;
803
+ return;
206
804
  }
805
+ this.#state = newState;
207
806
  }
208
- notify(e) {
209
- o(e), t.frozen = !0;
807
+ /**
808
+ * Invoce the notify callback when a watched dependency changes
809
+ * @param symbol - The private symbol for prevent external calls.
810
+ */
811
+ notify(symbol) {
812
+ assertPrivateContext(symbol);
813
+ GLOBAL_STATE.frozen = true;
210
814
  try {
211
- this.setState("pending", a), this.#n.call(this);
815
+ this.setState("pending", PRIVATE);
816
+ this.#notifyCallback.call(this);
212
817
  } finally {
213
- this.setState("waiting", a), t.frozen = !1;
818
+ this.setState("waiting", PRIVATE);
819
+ GLOBAL_STATE.frozen = false;
214
820
  }
215
821
  }
216
- #r(e, t) {
217
- switch (e) {
218
- case "waiting": return t === "watching";
219
- case "watching": return t === "pending" || t === "waiting";
220
- case "pending": return t === "waiting";
822
+ #isValidTransition(from, to) {
823
+ switch (from) {
824
+ case "waiting": return to === "watching";
825
+ case "watching": return to === "pending" || to === "waiting";
826
+ case "pending": return to === "waiting";
221
827
  }
222
828
  }
223
829
  };
224
830
  //#endregion
225
831
  //#region ../packages/signals/src/lib/subtle.ts
226
- function p(e) {
227
- let n = t.computing;
228
- t.computing = null;
832
+ /**
833
+ * Executes a function without tracking any dependencies.
834
+ * @param fn - The function to execute without tracking.
835
+ * @returns The result of the function execution.
836
+ */
837
+ function untrack(fn) {
838
+ const prevComputing = GLOBAL_STATE.computing;
839
+ GLOBAL_STATE.computing = null;
229
840
  try {
230
- return e();
841
+ return fn();
231
842
  } finally {
232
- t.computing = n;
843
+ GLOBAL_STATE.computing = prevComputing;
233
844
  }
234
845
  }
235
- function m() {
236
- return t.computing;
846
+ /**
847
+ * Returns the currently active `Computed` instance being evaluated, or `null`
848
+ * @returns The currently active `Computed` instance, or `null` if none is being evaluated.
849
+ */
850
+ function currentComputed() {
851
+ return GLOBAL_STATE.computing;
237
852
  }
238
- function h(e) {
239
- return e.getSources(a);
853
+ /**
854
+ * Returns the ordered list of all Signals which the given `Computed` or
855
+ * `Watcher` referenced during its last evaluation.
856
+ *
857
+ * - For a `Computed`, these are the Signals read inside its callback.
858
+ * - For a `Watcher`, these are the Signals it is currently watching.
859
+ *
860
+ * @param signal - The `Computed` or `Watcher` to introspect.
861
+ * @returns An array of `State` and `Computed` instances.
862
+ */
863
+ function introspectSources(signal) {
864
+ return signal.getSources(PRIVATE);
240
865
  }
241
- function g(e) {
242
- return e.getSinks(a);
866
+ /**
867
+ * Returns the direct dependents of the given Signal — Watchers that contain
868
+ * it, plus any `Computed` Signals which read it during their last evaluation
869
+ * (if that `Computed` is recursively watched).
870
+ *
871
+ * @param signal - The `State` or `Computed` Signal to introspect.
872
+ * @returns An array of `Computed` and `Watcher` instances.
873
+ */
874
+ function introspectSinks(signal) {
875
+ return signal.getSinks(PRIVATE);
243
876
  }
244
- function _(e) {
245
- return e.getSinks(a).length > 0;
877
+ /**
878
+ * Returns `true` if the given Signal is 'live' — i.e. it is watched by a
879
+ * `Watcher`, or it is read by a `Computed` Signal which is (recursively)
880
+ * live.
881
+ *
882
+ * @param signal - The `State` or `Computed` Signal to check.
883
+ * @returns `true` if the Signal has at least one sink.
884
+ */
885
+ function hasSinks(signal) {
886
+ return signal.getSinks(PRIVATE).length > 0;
246
887
  }
247
- function v(e) {
248
- return e.getSources(a).length > 0;
888
+ /**
889
+ * Returns `true` if the given node is 'reactive' — i.e. it depends on some
890
+ * other Signal. A `Computed` where `hasSources` is `false` will always
891
+ * return the same constant.
892
+ *
893
+ * @param signal - The `Computed` or `Watcher` to check.
894
+ * @returns `true` if the node has at least one source.
895
+ */
896
+ function hasSources(signal) {
897
+ return signal.getSources(PRIVATE).length > 0;
249
898
  }
250
899
  //#endregion
251
900
  //#region ../packages/signals/src/lib/load-signals.ts
252
- function y(e) {
253
- c(e?.devMode ?? !1), globalThis.Signal ??= {
254
- State: d,
255
- Computed: u,
901
+ /**
902
+ * Loads the Signals library by defining the `Signal` global object with the following properties:
903
+ * - `State`: The `State` class for creating reactive state variables.
904
+ * - `Computed`: The `Computed` class for creating derived reactive values.
905
+ * - `Watcher`: The `Watcher` class for observing changes in signals.
906
+ * - `subtle`: An object containing internal utility functions for working with signals, including:
907
+ * - `untrack`: Executes a function without tracking dependencies.
908
+ * - `currentComputed`: Returns the currently active `Computed` instance being evaluated, or `null` if none.
909
+ * - `introspectSources`: Returns the list of sources for a given `Computed` or `Watcher`.
910
+ * - `introspectSinks`: Returns the list of sinks for a given `State` or `Computed`.
911
+ * - `hasSinks`: Returns `true` if a given `State` or `Computed` has at least one sink.
912
+ * - `hasSources`: Returns `true` if a given `Computed` or `Watcher` has at least one source.
913
+ * - `Watcher`: The `Watcher` class for observing changes in signals.
914
+ *
915
+ * This function should be called once to initialize the Signals library and make its API available globally.
916
+ */
917
+ function loadSignals(options) {
918
+ setDevMode(options?.devMode ?? false);
919
+ globalThis.Signal ??= {
920
+ State,
921
+ Computed,
256
922
  subtle: {
257
- untrack: p,
258
- currentComputed: m,
259
- introspectSources: h,
260
- introspectSinks: g,
261
- hasSinks: _,
262
- hasSources: v,
263
- Watcher: f
923
+ untrack,
924
+ currentComputed,
925
+ introspectSources,
926
+ introspectSinks,
927
+ hasSinks,
928
+ hasSources,
929
+ Watcher
264
930
  }
265
931
  };
266
932
  }
267
933
  //#endregion
268
934
  //#region ../packages/signals/src/lib/models/effect/effect.ts
269
- function b(e) {
270
- let t = new Signal.Computed(() => e()), n = !0, r = new Signal.subtle.Watcher(() => {
271
- n && (n = !1, queueMicrotask(() => {
272
- n = !0, r.getPending().forEach((e) => e.get()), r.watch();
273
- }));
935
+ /**
936
+ * Runs a side-effectful function and automatically re-runs it whenever any
937
+ * Signal read during its execution changes.
938
+ *
939
+ * Internally, `effect` wraps the user callback inside a `Computed` node
940
+ * (for dependency tracking) and observes it with a `Watcher` (for push
941
+ * notifications). When any tracked dependency changes, the `Watcher`
942
+ * schedules a microtask that re-evaluates the `Computed`, which in turn
943
+ * re-runs the user callback and re-registers the new set of dependencies.
944
+ *
945
+ * The returned disposer function stops the effect: it unwatches the internal
946
+ * `Computed` from the `Watcher`, severing all dependency subscriptions so
947
+ * the callback is never called again and the graph nodes can be
948
+ * garbage-collected.
949
+ *
950
+ * @example
951
+ * ```ts
952
+ * const count = new State(0);
953
+ *
954
+ * const stop = effect(() => {
955
+ * console.log('count is', count.get());
956
+ * });
957
+ * // logs: "count is 0"
958
+ *
959
+ * count.set(1); // logs: "count is 1"
960
+ * count.set(2); // logs: "count is 2"
961
+ *
962
+ * stop(); // no more logs
963
+ * count.set(3); // silent
964
+ * ```
965
+ *
966
+ * @param fn - The side-effectful function to run. Any Signal read inside it
967
+ * is tracked as a dependency.
968
+ * @returns A disposer function that, when called, permanently stops the effect.
969
+ */
970
+ function effect(fn) {
971
+ /**
972
+ * Wrap the user callback in a Computed so that automatic dependency
973
+ * tracking (via pushComputed / popComputed) works for free.
974
+ * The Computed always returns `undefined` — we only care about the
975
+ * side-effects and the tracked sources, not the value.
976
+ */
977
+ const computed = new Signal.Computed(() => fn());
978
+ let needsEnqueue = true;
979
+ /**
980
+ * The Watcher is notified synchronously as soon as any tracked dependency
981
+ * changes. Its job is purely to schedule the re-execution; the actual
982
+ * re-evaluation happens asynchronously in a microtask so that multiple
983
+ * synchronous signal updates are batched into a single re-run.
984
+ */
985
+ const watcher = new Signal.subtle.Watcher(() => {
986
+ if (needsEnqueue) {
987
+ needsEnqueue = false;
988
+ queueMicrotask(() => {
989
+ needsEnqueue = true;
990
+ watcher.getPending().forEach((computed) => computed.get());
991
+ watcher.watch();
992
+ });
993
+ }
274
994
  });
275
- return r.watch(t), t.get(), () => r.unwatch(t);
995
+ watcher.watch(computed);
996
+ computed.get();
997
+ /**
998
+ * Disposer — call this to permanently stop the effect.
999
+ *
1000
+ * Unwatching the Computed tears down the entire live dependency chain
1001
+ * (Watcher → Computed → all sources), preventing any further
1002
+ * notifications and allowing GC.
1003
+ */
1004
+ return () => watcher.unwatch(computed);
276
1005
  }
277
1006
  //#endregion
278
- export { b as effect, y as loadSignals };
279
-
280
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieGFlbmRhci1zaWduYWxzLmVzLmpzIiwibmFtZXMiOlsiI3NvdXJjZXMiLCIjc2lua3MiLCIjY2FsbGJhY2siLCIjZXF1YWxzIiwiI3N0YXRlIiwiI2NvbXB1dGVWYWx1ZSIsIiNmaW5kRGVlcGVzdFN0YWxlIiwiI3ZhbHVlIiwiI2lzVmFsaWRUcmFuc2l0aW9uIiwiI3NldFZhbHVlIiwiI3Byb3BhZ2F0ZUNsZWFuIiwiI2lzRXJyb3JWYWx1ZSIsIiNzaW5rcyIsIiN2YWx1ZSIsIiNlcXVhbHMiLCIjd2F0Y2hlZCIsIiN1bndhdGNoZWQiLCIjc2lnbmFscyIsIiNzdGF0ZSIsIiNub3RpZnlDYWxsYmFjayIsIiNpc1ZhbGlkVHJhbnNpdGlvbiJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL3NpZ25hbHMvc3JjL2xpYi91dGlscy9nbG9iYWxzL2dsb2JhbHMudHMiLCIuLi8uLi8uLi8uLi9wYWNrYWdlcy9zaWduYWxzL3NyYy9saWIvdXRpbHMvcHJpdmF0ZS1zeW1ib2wvcHJpdmF0ZS1zeW1ib2wudHMiLCIuLi8uLi8uLi8uLi9wYWNrYWdlcy9zaWduYWxzL3NyYy9saWIvdXRpbHMvZGV2LW1vZGUvZGV2LW1vZGUudHMiLCIuLi8uLi8uLi8uLi9wYWNrYWdlcy9zaWduYWxzL3NyYy9saWIvbW9kZWxzL2NvbXB1dGVkL2NvbXB1dGVkLnRzIiwiLi4vLi4vLi4vLi4vcGFja2FnZXMvc2lnbmFscy9zcmMvbGliL21vZGVscy9zdGF0ZS9zdGF0ZS50cyIsIi4uLy4uLy4uLy4uL3BhY2thZ2VzL3NpZ25hbHMvc3JjL2xpYi9tb2RlbHMvd2F0Y2hlci93YXRjaGVyLnRzIiwiLi4vLi4vLi4vLi4vcGFja2FnZXMvc2lnbmFscy9zcmMvbGliL3N1YnRsZS50cyIsIi4uLy4uLy4uLy4uL3BhY2thZ2VzL3NpZ25hbHMvc3JjL2xpYi9sb2FkLXNpZ25hbHMudHMiLCIuLi8uLi8uLi8uLi9wYWNrYWdlcy9zaWduYWxzL3NyYy9saWIvbW9kZWxzL2VmZmVjdC9lZmZlY3QudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU3RhY2sgfSBmcm9tICdAeGFlbmRhci9jb21tb24nO1xyXG5pbXBvcnQgeyBDb21wdXRlZCB9IGZyb20gJy4uLy4uL21vZGVscy9jb21wdXRlZC9jb21wdXRlZCc7XHJcbmltcG9ydCB7IEdsb2JhbFN0YXRlIH0gZnJvbSAnLi4vLi4vdHlwZXMvZ2xvYmFsLXN0YXRlLnR5cGUnO1xyXG5cclxuLyoqXHJcbiAqIEdsb2JhbCBzdGF0ZSBmb3IgdGhlIHNpZ25hbHMgcnVudGltZS5cclxuICogVHJhY2tzIHRoZSBjdXJyZW50bHkgY29tcHV0aW5nIGBDb21wdXRlZGAgaW5zdGFuY2UsIHdoZXRoZXIgdGhlIHN0YXRlIGlzIGZyb3plbixcclxuICogYW5kIHRoZSBjdXJyZW50IGdlbmVyYXRpb24gY291bnRlci5cclxuICpcclxuICogQGludGVybmFsXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgR0xPQkFMX1NUQVRFOiBHbG9iYWxTdGF0ZSA9IHtcclxuICBjb21wdXRpbmc6IG51bGwsXHJcbiAgZnJvemVuOiBmYWxzZVxyXG59O1xyXG5cclxuY29uc3QgY29tcHV0aW5nU3RhY2sgPSBuZXcgU3RhY2s8Q29tcHV0ZWQ+O1xyXG5cclxuLyoqXHJcbiAqIFB1c2hlcyBhIGBDb21wdXRlZGAgaW5zdGFuY2Ugb250byB0aGUgY29tcHV0aW5nIHN0YWNrIGFuZCBzZXRzIGl0IGFzIHRoZVxyXG4gKiBjdXJyZW50bHkgYWN0aXZlIGNvbXB1dGF0aW9uIGluIGBHTE9CQUxfU1RBVEVgLlxyXG4gKlxyXG4gKiBTaG91bGQgYmUgY2FsbGVkIGJlZm9yZSBleGVjdXRpbmcgYSBjb21wdXRlZCBmdW5jdGlvbiB0byByZWdpc3RlclxyXG4gKiBkZXBlbmRlbmN5IHRyYWNraW5nLlxyXG4gKlxyXG4gKiBAcGFyYW0gY29tcHV0ZWQgLSBUaGUgYENvbXB1dGVkYCBpbnN0YW5jZSBlbnRlcmluZyB0aGUgY29tcHV0YXRpb24gcGhhc2UuXHJcbiAqIEBpbnRlcm5hbFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHB1c2hDb21wdXRlZChjb21wdXRlZDogQ29tcHV0ZWQpOiB2b2lkIHtcclxuICBjb21wdXRpbmdTdGFjay5wdXNoKGNvbXB1dGVkKTtcclxuICBHTE9CQUxfU1RBVEUuY29tcHV0aW5nID0gY29tcHV0ZWQ7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBQb3BzIHRoZSBtb3N0IHJlY2VudCBgQ29tcHV0ZWRgIGluc3RhbmNlIGZyb20gdGhlIGNvbXB1dGluZyBzdGFjayBhbmRcclxuICogcmVzdG9yZXMgdGhlIHByZXZpb3VzIG9uZSBhcyB0aGUgYWN0aXZlIGNvbXB1dGF0aW9uIGluIGBHTE9CQUxfU1RBVEVgLlxyXG4gKlxyXG4gKiBTaG91bGQgYmUgY2FsbGVkIGFmdGVyIGEgY29tcHV0ZWQgZnVuY3Rpb24gZmluaXNoZXMgZXhlY3V0aW5nLlxyXG4gKlxyXG4gKiBAaW50ZXJuYWxcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBwb3BDb21wdXRlZCgpOiB2b2lkIHtcclxuICBjb21wdXRpbmdTdGFjay5wb3AoKTtcclxuICBHTE9CQUxfU1RBVEUuY29tcHV0aW5nID0gY29tcHV0aW5nU3RhY2tbY29tcHV0aW5nU3RhY2subGVuZ3RoIC0gMV0gPz8gbnVsbDtcclxufSIsIi8qKlxyXG4gKiBTeW1ib2wgbm90IGF2YWlsYWJsZSBpbiBwdWJsaWMgQVBJLFxyXG4gKiB1c2VkIHRvIGNhbGwgaW50ZXJuYWwgbWV0aG9kcyBvZiBgU3RhdGVgIGFuZCBgQ29tcHV0ZWRgIGZyb20gYFdhdGNoZXJgIHdpdGhvdXQgZXhwb3NpbmcgdGhlbSBpbiB0aGUgcHVibGljIEFQSS5cclxuICpcclxuICogQGludGVybmFsXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgUFJJVkFURSA9IFN5bWJvbCgnc2lnbmFscy1wcml2YXRlJyk7XHJcblxyXG4vKipcclxuICogQXNzZXJ0cyB0aGF0IHRoZSBwcm92aWRlZCBzeW1ib2wgbWF0Y2hlcyB0aGUgaW50ZXJuYWwge0BsaW5rIFBSSVZBVEV9IHN5bWJvbCxcclxuICogZW5zdXJpbmcgdGhlIGNhbGxlciBoYXMgYWNjZXNzIHRvIGludGVybmFsIEFQSXMuXHJcbiAqXHJcbiAqIFRocm93cyBpZiB0aGUgc3ltYm9sIGRvZXMgbm90IG1hdGNoLCBwcmV2ZW50aW5nIGV4dGVybmFsIGNvZGUgZnJvbVxyXG4gKiBpbnZva2luZyBtZXRob2RzIGludGVuZGVkIGZvciBpbnRlcm5hbCB1c2Ugb25seS5cclxuICpcclxuICogQHBhcmFtIHN5bWJvbCAtIFRoZSBzeW1ib2wgdG8gdmFsaWRhdGUgYWdhaW5zdCB7QGxpbmsgUFJJVkFURX0uXHJcbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiBgc3ltYm9sYCBkb2VzIG5vdCBtYXRjaCB7QGxpbmsgUFJJVkFURX0uXHJcbiAqIEBpbnRlcm5hbFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydFByaXZhdGVDb250ZXh0KHN5bWJvbDogc3ltYm9sKTogdm9pZCB7XHJcbiAgaWYgKHN5bWJvbCAhPT0gUFJJVkFURSkge1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN5bWJvbCcpO1xyXG4gIH1cclxufSIsIi8qKiBcclxuICogV2hldGhlciB0aGUgbGlicmFyeSBpcyBydW5uaWduIGluIGRldmVsb3BtZW50IG1vZGVcclxuICogVXNlZCB0byBsb2cgZXh0cmEgaW5mb3JtYXRpb24gZm9yIGV4YW1wbGVcclxuICogLSBJbnZhbGlkIHRyYW5zaXRpb24gc3RhdGVzIGZvciB7QGxpbmsgQ29tcHV0ZWR9IG9yIHtAbGluayBXYXRjaGVyfSAgXHJcbiAqL1xyXG5sZXQgZGV2TW9kZSA9IGZhbHNlO1xyXG5cclxuLyoqXHJcbiAqIFNldHMgdGhlIGRldmVsb3BtZW50IG1vZGUgZmxhZy5cclxuICogQHBhcmFtIG1vZGUgLSBgdHJ1ZWAgdG8gZW5hYmxlIGRldiBtb2RlLCBgZmFsc2VgIHRvIGRpc2FibGUgaXQuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gc2V0RGV2TW9kZShtb2RlOiBib29sZWFuKTogdm9pZCB7XHJcbiAgZGV2TW9kZSA9IG1vZGU7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBjdXJyZW50IGRldmVsb3BtZW50IG1vZGUgc3RhdGUuXHJcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiBkZXYgbW9kZSBpcyBlbmFibGVkLCBgZmFsc2VgIG90aGVyd2lzZS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBpc0Rldk1vZGUoKTogYm9vbGVhbiB7XHJcbiAgcmV0dXJuIGRldk1vZGU7XHJcbn0iLCJcclxuaW1wb3J0IHsgR0xPQkFMX1NUQVRFLCBwb3BDb21wdXRlZCwgcHVzaENvbXB1dGVkIH0gZnJvbSAnLi4vLi4vdXRpbHMvZ2xvYmFscy9nbG9iYWxzJztcclxuaW1wb3J0IHsgUFJJVkFURSwgYXNzZXJ0UHJpdmF0ZUNvbnRleHQgfSBmcm9tICcuLi8uLi91dGlscy9wcml2YXRlLXN5bWJvbC9wcml2YXRlLXN5bWJvbCc7XHJcbmltcG9ydCB7IENvbXB1dGVkU3RhdGUgfSBmcm9tICcuLi8uLi90eXBlcy9jb21wdXRlZC1zdGF0ZS50eXBlJztcclxuaW1wb3J0IHsgU2lnbmFsRXF1YWwgfSBmcm9tICcuLi8uLi90eXBlcy9zaWduYWwtZXF1YWwudHlwZSc7XHJcbmltcG9ydCB7IFNpZ25hbE9wdGlvbnMgfSBmcm9tICcuLi8uLi90eXBlcy9zaWduYWwtb3B0aW9ucy50eXBlJztcclxuaW1wb3J0IHsgU3RhdGUgfSBmcm9tICcuLi9zdGF0ZS9zdGF0ZSc7XHJcbmltcG9ydCB7IFdhdGNoZXIgfSBmcm9tICcuLi93YXRjaGVyL3dhdGNoZXInO1xyXG5pbXBvcnQgeyBpc0Rldk1vZGUgfSBmcm9tICcuLi8uLi91dGlscy9kZXYtbW9kZS9kZXYtbW9kZSc7XHJcblxyXG4vKipcclxuICogQSByZWFkLW9ubHkgU2lnbmFsIHdob3NlIHZhbHVlIGlzIGRlcml2ZWQgbGF6aWx5IGZyb20gb3RoZXIgU2lnbmFscy5cclxuICpcclxuICogVGhlIHZhbHVlIGlzIHJlY29tcHV0ZWQgb25seSB3aGVuIGV4cGxpY2l0bHkgcmVhZCBhbmQgb25seSBpZiBvbmUgb3IgbW9yZVxyXG4gKiBvZiBpdHMgKHJlY3Vyc2l2ZSkgZGVwZW5kZW5jaWVzIGhhdmUgY2hhbmdlZCBzaW5jZSB0aGUgbGFzdCBldmFsdWF0aW9uLlxyXG4gKiBUaGUgcmVzdWx0IGlzIGNhY2hlZCBhbmQgcmV1c2VkIHVudGlsIHRoZSBTaWduYWwgYmVjb21lcyBzdGFsZSBhZ2Fpbi5cclxuICpcclxuICogQHRlbXBsYXRlIFQgVGhlIHR5cGUgb2YgdGhlIGNvbXB1dGVkIHZhbHVlLlxyXG4gKlxyXG4gKiBAc2VlIFNpZ25hbCBhbGdvcml0aG1zIOKAlCBcIlRoZSBTaWduYWwuQ29tcHV0ZWQgY2xhc3NcIlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIENvbXB1dGVkPFQgPSBhbnk+IHtcclxuICAvKipcclxuICAgKiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgc2lnbmFsLlxyXG4gICAqXHJcbiAgICogVW5pbml0aWFsaXNlZCAoYCFgKSB1bnRpbCB0aGUgZmlyc3QgZXZhbHVhdGlvbi4gQWZ0ZXIgdGhhdCwgaG9sZHMgZWl0aGVyXHJcbiAgICogdGhlIHJldHVybiB2YWx1ZSBvZiBgI2NhbGxiYWNrYCBvciBhIGJveGVkIGVycm9yXHJcbiAgICogYHsgaXNFcnJvcjogdHJ1ZTsgdmFsdWU6IEVycm9yIH1gIGlmIHRoZSBsYXN0IGV2YWx1YXRpb24gdGhyZXcuXHJcbiAgICpcclxuICAgKiBAaW50ZXJuYWxTbG90XHJcbiAgICogQHNlZSBTaWduYWwgYWxnb3JpdGhtcyDigJQgXCJTaWduYWwuQ29tcHV0ZWQgaW50ZXJuYWwgc2xvdHNcIlxyXG4gICAqL1xyXG4gICN2YWx1ZSE6IFQgfCB7IGlzRXJyb3I6IHRydWU7IHZhbHVlOiBFcnJvciB9O1xyXG4gIC8qKlxyXG4gICAqIFRoZSBjdXJyZW50IGV2YWx1YXRpb24gc3RhdGUgb2YgdGhpcyBTaWduYWwuXHJcbiAgICpcclxuICAgKiAtIGB+ZGlydHl+YCAgICAg4oCUIHZhbHVlIGlzIGtub3duIHRvIGJlIHN0YWxlIG9yIGhhcyBuZXZlciBiZWVuIGV2YWx1YXRlZC5cclxuICAgKiAtIGB+Y2hlY2tlZH5gICAg4oCUIGFuIGluZGlyZWN0IHNvdXJjZSBjaGFuZ2VkOyBtYXkgb3IgbWF5IG5vdCBiZSBzdGFsZS5cclxuICAgKiAtIGB+Y29tcHV0aW5nfmAg4oCUIGAjY2FsbGJhY2tgIGlzIGN1cnJlbnRseSBleGVjdXRpbmc7IGd1YXJkcyBhZ2FpbnN0IGN5Y2xlcy5cclxuICAgKiAtIGB+Y2xlYW5+YCAgICAg4oCUIGNhY2hlZCB2YWx1ZSBpcyB1cC10by1kYXRlLlxyXG4gICAqXHJcbiAgICogQGludGVybmFsU2xvdFxyXG4gICAqIEBzZWUgU2lnbmFsIGFsZ29yaXRobXMg4oCUIFwiU2lnbmFsLkNvbXB1dGVkIFN0YXRlIG1hY2hpbmVcIlxyXG4gICAqL1xyXG4gICNzdGF0ZTogQ29tcHV0ZWRTdGF0ZTtcclxuICAvKipcclxuICAgKiBUaGUgb3JkZXJlZCBzZXQgb2YgU2lnbmFscyByZWFkIGR1cmluZyB0aGUgbGFzdCBldmFsdWF0aW9uIG9mXHJcbiAgICogYCNjYWxsYmFja2AuIENsZWFyZWQgYW5kIHJlYnVpbHQgb24gZXZlcnkgcmUtZXZhbHVhdGlvbiBzbyB0aGF0XHJcbiAgICogY29uZGl0aW9uYWwgYnJhbmNoZXMgdGhhdCBhcmUgbm8gbG9uZ2VyIHRha2VuIHN0b3AgYmVpbmcgdHJhY2tlZC5cclxuICAgKlxyXG4gICAqIE1heSBjb250YWluIGJvdGggYFN0YXRlYCBhbmQgYENvbXB1dGVkYCBpbnN0YW5jZXMuXHJcbiAgICpcclxuICAgKiBAaW50ZXJuYWxTbG90XHJcbiAgICogQHNlZSBTaWduYWwgYWxnb3JpdGhtcyDigJQgXCJTaWduYWwuQ29tcHV0ZWQgaW50ZXJuYWwgc2xvdHNcIlxyXG4gICAqL1xyXG4gICNzb3VyY2VzOiBTZXQ8U3RhdGU8dW5rbm93bj4gfCBDb21wdXRlZDx1bmtub3duPj47XHJcbiAgLyoqXHJcbiAqIFJldHVybnMgYSBzbmFwc2hvdCBvZiB0aGUgY3VycmVudCBzb3VyY2VzIHNldCBmb3IgaW50cm9zcGVjdGlvbi5cclxuICpcclxuICogQHBhcmFtIHN5bWJvbCAtIFByaXZhdGUgYWNjZXNzIHN5bWJvbDsgcmVqZWN0cyBjYWxscyBmcm9tIG91dHNpZGUgdGhlIGxpYnJhcnkuXHJcbiAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGBTdGF0ZWAgYW5kIGBDb21wdXRlZGAgaW5zdGFuY2VzIHRoYXQgdGhpcyBTaWduYWwgZGVwZW5kcyBvbi5cclxuICogQGludGVybmFsXHJcbiAqL1xyXG4gIHB1YmxpYyBnZXRTb3VyY2VzKHN5bWJvbDogc3ltYm9sKTogKFN0YXRlPHVua25vd24+IHwgQ29tcHV0ZWQ8dW5rbm93bj4pW10ge1xyXG4gICAgYXNzZXJ0UHJpdmF0ZUNvbnRleHQoc3ltYm9sKTtcclxuICAgIHJldHVybiBbLi4udGhpcy4jc291cmNlc107XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIFRoZSBzZXQgb2YgU2lnbmFscyBhbmQgV2F0Y2hlcnMgdGhhdCBkaXJlY3RseSBkZXBlbmQgb24gdGhpcyBTaWduYWwuXHJcbiAgICpcclxuICAgKiBQb3B1bGF0ZWQgb25seSB3aGVuIHRoaXMgU2lnbmFsIGlzIHJlYWNoYWJsZSBmcm9tIGF0IGxlYXN0IG9uZSBhY3RpdmVcclxuICAgKiBgV2F0Y2hlcmAuIEFuIHVuLXdhdGNoZWQgYENvbXB1dGVkYCBoYXMgYW4gZW1wdHkgc2lua3Mgc2V0LCB3aGljaCBhbGxvd3NcclxuICAgKiBpdCB0byBiZSBnYXJiYWdlLWNvbGxlY3RlZCBpbmRlcGVuZGVudGx5IGZyb20gdGhlIHJlc3Qgb2YgdGhlIGdyYXBoLlxyXG4gICAqXHJcbiAgICogQGludGVybmFsU2xvdFxyXG4gICAqIEBzZWUgU2lnbmFsIGFsZ29yaXRobXMg4oCUIFwiU2lnbmFsLkNvbXB1dGVkIGludGVybmFsIHNsb3RzXCJcclxuICAgKiBAc2VlIE1ldGhvZCDigJQgYFNpZ25hbC5Db21wdXRlZC5wcm90b3R5cGUuZ2V0YCAoTk9URSBvbiBzaW5rcylcclxuICAgKi9cclxuICAjc2lua3M6IFNldDxDb21wdXRlZDx1bmtub3duPiB8IFdhdGNoZXI+O1xyXG4gIC8qKlxyXG4gICAqIFJldHVybnMgYSBzbmFwc2hvdCBvZiB0aGUgY3VycmVudCBzaW5rcyBzZXQgZm9yIGludHJvc3BlY3Rpb24uXHJcbiAgICpcclxuICAgKiBAcGFyYW0gc3ltYm9sIC0gUHJpdmF0ZSBhY2Nlc3Mgc3ltYm9sOyByZWplY3RzIGNhbGxzIGZyb20gb3V0c2lkZSB0aGUgbGlicmFyeS5cclxuICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiBgQ29tcHV0ZWRgIGFuZCBgV2F0Y2hlcmAgaW5zdGFuY2VzIHRoYXQgZGVwZW5kIG9uIHRoaXMgU2lnbmFsLlxyXG4gICAqIEBpbnRlcm5hbFxyXG4gICAqL1xyXG4gIHB1YmxpYyBnZXRTaW5rcyhzeW1ib2w6IHN5bWJvbCk6IChDb21wdXRlZDx1bmtub3duPiB8IFdhdGNoZXIpW10ge1xyXG4gICAgYXNzZXJ0UHJpdmF0ZUNvbnRleHQoc3ltYm9sKTtcclxuICAgIHJldHVybiBbLi4udGhpcy4jc2lua3NdO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBUaGUgZXF1YWxpdHkgZnVuY3Rpb24gdXNlZCB0byBkZXRlcm1pbmUgd2hldGhlciBhIG5ld2x5IGNvbXB1dGVkIHZhbHVlXHJcbiAgICogaXMgbWVhbmluZ2Z1bGx5IGRpZmZlcmVudCBmcm9tIHRoZSBwcmV2aW91c2x5IGNhY2hlZCBvbmUuXHJcbiAgICpcclxuICAgKiBDYWxsZWQgYXMgYGVxdWFscy5jYWxsKGNvbXB1dGVkLCBvbGRWYWx1ZSwgbmV3VmFsdWUpYC4gUmV0dXJucyBgdHJ1ZWAgaWZcclxuICAgKiB0aGUgdmFsdWVzIGFyZSBjb25zaWRlcmVkIGVxdWFsLCBpbiB3aGljaCBjYXNlIG5vIGRvd25zdHJlYW0gcHJvcGFnYXRpb25cclxuICAgKiBvY2N1cnMuIERlZmF1bHRzIHRvIGBPYmplY3QuaXNgIHdoZW4gbm90IHByb3ZpZGVkIHZpYSBvcHRpb25zLlxyXG4gICAqXHJcbiAgICogSWYgdGhpcyBmdW5jdGlvbiB0aHJvd3MsIHRoZSBleGNlcHRpb24gaXMgY2FjaGVkIGFzIHRoZSBTaWduYWwncyB2YWx1ZVxyXG4gICAqIGFuZCB0aGUgb3V0Y29tZSBpcyB0cmVhdGVkIGFzIGB+ZGlydHl+YC5cclxuICAgKlxyXG4gICAqIEBpbnRlcm5hbFNsb3RcclxuICAgKiBAc2VlIFNpZ25hbCBhbGdvcml0aG1zIOKAlCBcIlNpZ25hbC5Db21wdXRlZCBpbnRlcm5hbCBzbG90c1wiXHJcbiAgICogQHNlZSBBbGdvcml0aG0g4oCUIFwiU2V0IFNpZ25hbCB2YWx1ZVwiXHJcbiAgICovXHJcbiAgI2VxdWFsczogU2lnbmFsRXF1YWw8VD47XHJcbiAgLyoqXHJcbiAgICogVGhlIHB1cmUgZnVuY3Rpb24gdGhhdCBwcm9kdWNlcyB0aGlzIFNpZ25hbCdzIHZhbHVlLiBFdmFsdWF0ZWQgbGF6aWx5XHJcbiAgICogd2hlbmV2ZXIgdGhlIFNpZ25hbCBpcyByZWFkIHdoaWxlIGluIGEgYH5kaXJ0eX5gIG9yIGB+Y2hlY2tlZH5gIHN0YXRlLlxyXG4gICAqXHJcbiAgICogQ2FsbGVkIHdpdGggYHRoaXNgIGJvdW5kIHRvIHRoZSBgQ29tcHV0ZWRgIGluc3RhbmNlIGl0c2VsZiBzbyB0aGF0XHJcbiAgICogaW50ZXJuYWwgbWV0aG9kcyAoZS5nLiBgYWRkU291cmNlYCkgYXJlIGFjY2Vzc2libGUgaWYgbmVlZGVkLlxyXG4gICAqIEFueSBleGNlcHRpb24gdGhyb3duIGJ5IHRoaXMgZnVuY3Rpb24gaXMgY2F1Z2h0IGFuZCBjYWNoZWQuXHJcbiAgICpcclxuICAgKiBAaW50ZXJuYWxTbG90XHJcbiAgICogQHNlZSBTaWduYWwgYWxnb3JpdGhtcyDigJQgXCJTaWduYWwuQ29tcHV0ZWQgaW50ZXJuYWwgc2xvdHNcIlxyXG4gICAqL1xyXG4gICNjYWxsYmFjazogKHRoaXM6IENvbXB1dGVkPFQ+KSA9PiBUO1xyXG5cclxuICAvKipcclxuICAgKiBDcmVhdGVzIGEgbmV3IGBDb21wdXRlZGAgc2lnbmFsLlxyXG4gICAqXHJcbiAgICogVGhlIFNpZ25hbCBzdGFydHMgaW4gdGhlIGB+ZGlydHl+YCBzdGF0ZSB3aXRoIGFuIHVuaW5pdGlhbGlzZWQgdmFsdWUsIHNvXHJcbiAgICogYCNjYWxsYmFja2Agd2lsbCBiZSBpbnZva2VkIG9uIHRoZSBmaXJzdCBgZ2V0KClgLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIGNiIC0gUHVyZSBmdW5jdGlvbiBldmFsdWF0ZWQgbGF6aWx5IHRvIHByb2R1Y2UgdGhlIHZhbHVlLlxyXG4gICAqICAgUmVjZWl2ZXMgdGhlIGBDb21wdXRlZGAgaW5zdGFuY2UgYXMgYHRoaXNgLlxyXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvbjpcclxuICAgKiAgIC0gYGVxdWFsc2Ag4oCUIGN1c3RvbSBlcXVhbGl0eSBmdW5jdGlvbjsgZGVmYXVsdHMgdG8gYE9iamVjdC5pc2AuXHJcbiAgICpcclxuICAgKiBAc2VlIFNpZ25hbCBhbGdvcml0aG1zIOKAlCBcIlNpZ25hbC5Db21wdXRlZCBDb25zdHJ1Y3RvclwiXHJcbiAgICovXHJcbiAgY29uc3RydWN0b3IoY2I6ICh0aGlzOiBDb21wdXRlZDxUPikgPT4gVCwgb3B0aW9ucz86IFNpZ25hbE9wdGlvbnM8VD4pIHtcclxuICAgIHRoaXMuI2NhbGxiYWNrID0gY2I7XHJcbiAgICB0aGlzLiNlcXVhbHMgPSBvcHRpb25zPy5lcXVhbHMgPz8gT2JqZWN0LmlzO1xyXG4gICAgdGhpcy4jc291cmNlcyA9IG5ldyBTZXQ7XHJcbiAgICB0aGlzLiNzaW5rcyA9IG5ldyBTZXQ7XHJcbiAgICB0aGlzLiNzdGF0ZSA9ICdkaXJ0eSc7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoaXMgU2lnbmFsLCByZS1ldmFsdWF0aW5nIGAjY2FsbGJhY2tgIGlmXHJcbiAgICogdGhlIGNhY2hlZCB2YWx1ZSBtYXkgYmUgc3RhbGUuXHJcbiAgICpcclxuICAgKiBSZWdpc3RlcnMgdGhpcyBTaWduYWwgYXMgYSBzb3VyY2Ugb2YgYW55IG91dGVyIGBDb21wdXRlZGAgY3VycmVudGx5XHJcbiAgICogYmVpbmcgZXZhbHVhdGVkIChhdXRvbWF0aWMgZGVwZW5kZW5jeSB0cmFja2luZykuXHJcbiAgICpcclxuICAgKiBJZiB0aGUgc3RhdGUgaXMgYH5kaXJ0eX5gIG9yIGB+Y2hlY2tlZH5gLCB3YWxrcyB0aGUgc291cmNlIGdyYXBoXHJcbiAgICogZGVwdGgtZmlyc3QgdG8gZmluZCBhbmQgcmVjYWxjdWxhdGUgdGhlIGRlZXBlc3Qgc3RhbGUgYENvbXB1dGVkYCBmaXJzdCxcclxuICAgKiB0aGVuIHJlLWNoZWNrcyB1cHdhcmQgdW50aWwgdGhpcyBTaWduYWwgaXMgYH5jbGVhbn5gLlxyXG4gICAqXHJcbiAgICogQHJldHVybnMgVGhlIGN1cnJlbnQgY29tcHV0ZWQgdmFsdWUsIG9yIGEgYm94ZWQgZXJyb3Igb2JqZWN0IGlmIHRoZSBsYXN0XHJcbiAgICogICBldmFsdWF0aW9uIHRocmV3LlxyXG4gICAqIEB0aHJvd3MgSWYgYGZyb3plbmAgaXMgYHRydWVgLlxyXG4gICAqIEB0aHJvd3MgSWYgdGhlIFNpZ25hbCBpcyBpbiB0aGUgYH5jb21wdXRpbmd+YCBzdGF0ZSAoY3ljbGljIGRlcGVuZGVuY3kpLlxyXG4gICAqXHJcbiAgICogQHNlZSBTaWduYWwgYWxnb3JpdGhtcyDigJQgXCJNZXRob2Q6IFNpZ25hbC5Db21wdXRlZC5wcm90b3R5cGUuZ2V0XCJcclxuICAgKi9cclxuICBwdWJsaWMgZ2V0KCk6IFQgfCB7IGlzRXJyb3I6IHRydWU7IHZhbHVlOiBFcnJvciB9IHtcclxuICAgIGlmIChHTE9CQUxfU1RBVEUuZnJvemVuKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGdldCB2YWx1ZSBvZiBhIENvbXB1dGVkIHNpZ25hbCB3aGlsZSB0aGUgZ2xvYmFsIHN0YXRlIGlzIGZyb3plbicpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLiNzdGF0ZSA9PT0gJ2NvbXB1dGluZycpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaXJjdWxhciBkZXBlbmRlbmN5IGRldGVjdGVkIHdoaWxlIGNvbXB1dGluZyBhIENvbXB1dGVkIHNpZ25hbCcpO1xyXG4gICAgfVxyXG5cclxuICAgIEdMT0JBTF9TVEFURS5jb21wdXRpbmc/LmFkZFNvdXJjZSh0aGlzLCBQUklWQVRFKTtcclxuXHJcbiAgICBpZiAodGhpcy4jc2lua3Muc2l6ZSA9PT0gMCkge1xyXG4gICAgICB0aGlzLiNjb21wdXRlVmFsdWUoKTtcclxuICAgIH0gZWxzZSBpZiAodGhpcy4jc3RhdGUgPT09ICdkaXJ0eScgfHwgdGhpcy4jc3RhdGUgPT09ICdjaGVja2VkJykge1xyXG4gICAgICB3aGlsZSAodGhpcy4jc3RhdGUgPT09ICdkaXJ0eScgfHwgdGhpcy4jc3RhdGUgPT09ICdjaGVja2VkJykge1xyXG4gICAgICAgIGNvbnN0IGRlZXBlc3QgPSB0aGlzLiNmaW5kRGVlcGVzdFN0YWxlKCk7XHJcbiAgICAgICAgZGVlcGVzdC4jY29tcHV0ZVZhbHVlKCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy4jdmFsdWU7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RlcnMgYSBTaWduYWwgYXMgYSBzb3VyY2Ugb2YgdGhpcyBgQ29tcHV0ZWRgLCBkaXNjb3ZlcmVkIGR1cmluZyB0aGVcclxuICAgKiBleGVjdXRpb24gb2YgYCNjYWxsYmFja2AuXHJcbiAgICpcclxuICAgKiBJZiB0aGlzIGBDb21wdXRlZGAgaXMgY3VycmVudGx5IGJlaW5nIHdhdGNoZWQgKGhhcyBhdCBsZWFzdCBvbmUgc2luayksXHJcbiAgICogdGhlIHNvdXJjZSBpcyBhbHNvIGluZm9ybWVkIG9mIHRoaXMgU2lnbmFsIGFzIGEgbmV3IHNpbmssIGJ1aWxkaW5nIHRoZVxyXG4gICAqIGxpdmUgcHVzaC1ub3RpZmljYXRpb24gY2hhaW4gdXB3YXJkLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIHNvdXJjZSAtIFRoZSBTaWduYWwgcmVhZCBkdXJpbmcgZXZhbHVhdGlvbi5cclxuICAgKiBAcGFyYW0gc3ltYm9sIC0gUHJpdmF0ZSBhY2Nlc3Mgc3ltYm9sOyByZWplY3RzIGNhbGxzIGZyb20gb3V0c2lkZSB0aGUgbGlicmFyeS5cclxuICAgKiBAaW50ZXJuYWxcclxuICAgKi9cclxuICBwdWJsaWMgYWRkU291cmNlKHNvdXJjZTogU3RhdGUgfCBDb21wdXRlZCwgc3ltYm9sOiBzeW1ib2wpIHtcclxuICAgIGFzc2VydFByaXZhdGVDb250ZXh0KHN5bWJvbCk7XHJcbiAgICB0aGlzLiNzb3VyY2VzLmFkZChzb3VyY2UpO1xyXG4gICAgc291cmNlLmFkZFNpbmsodGhpcywgUFJJVkFURSlcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJldHVybnMgdGhlIGN1cnJlbnQgZXZhbHVhdGlvbiBzdGF0ZSBvZiB0aGlzIFNpZ25hbC5cclxuICAgKlxyXG4gICAqIEBwYXJhbSBzeW1ib2wgLSBQcml2YXRlIGFjY2VzcyBzeW1ib2w7IHJlamVjdHMgY2FsbHMgZnJvbSBvdXRzaWRlIHRoZSBsaWJyYXJ5LlxyXG4gICAqIEBpbnRlcm5hbFxyXG4gICAqIEBzZWUgU2lnbmFsIGFsZ29yaXRobXMg4oCUIFwiU2lnbmFsLkNvbXB1dGVkIFN0YXRlIG1hY2hpbmVcIlxyXG4gICAqL1xyXG4gIHB1YmxpYyBnZXRTdGF0ZShzeW1ib2w6IHN5bWJvbCk6IENvbXB1dGVkU3RhdGUge1xyXG4gICAgYXNzZXJ0UHJpdmF0ZUNvbnRleHQoc3ltYm9sKTtcclxuICAgIHJldHVybiB0aGlzLiNzdGF0ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRyYW5zaXRpb25zIHRoaXMgU2lnbmFsIHRvIGEgbmV3IGV2YWx1YXRpb24gc3RhdGUuXHJcbiAgICpcclxuICAgKiBPbmx5IHZhbGlkIHRyYW5zaXRpb25zIChhcyBkZWZpbmVkIGJ5IHRoZSBzdGF0ZSBtYWNoaW5lKSBhcmUgYWxsb3dlZC5cclxuICAgKiBJbnZhbGlkIHRyYW5zaXRpb25zIHRocm93IGFuIGVycm9yLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIG5ld1N0YXRlIC0gVGhlIHRhcmdldCBzdGF0ZS5cclxuICAgKiBAcGFyYW0gc3ltYm9sIC0gUHJpdmF0ZSBhY2Nlc3Mgc3ltYm9sOyByZWplY3RzIGNhbGxzIGZyb20gb3V0c2lkZSB0aGUgbGlicmFyeS5cclxuICAgKiBAdGhyb3dzIElmIHRoZSB0cmFuc2l0aW9uIGZyb20gdGhlIGN1cnJlbnQgc3RhdGUgdG8gYG5ld1N0YXRlYCBpcyBub3QgYWxsb3dlZC5cclxuICAgKiBAaW50ZXJuYWxcclxuICAgKiBAc2VlIFNpZ25hbCBhbGdvcml0aG1zIOKAlCBcIlNpZ25hbC5Db21wdXRlZCBTdGF0ZSBtYWNoaW5lXCJcclxuICAgKi9cclxuICBwdWJsaWMgc2V0U3RhdGUobmV3U3RhdGU6IENvbXB1dGVkU3RhdGUsIHN5bWJvbDogc3ltYm9sKTogdm9pZCB7XHJcbiAgICBhc3NlcnRQcml2YXRlQ29udGV4dChzeW1ib2wpO1xyXG5cclxuICAgIGlmICh0aGlzLiNzdGF0ZSA9PT0gbmV3U3RhdGUpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghdGhpcy4jaXNWYWxpZFRyYW5zaXRpb24odGhpcy4jc3RhdGUsIG5ld1N0YXRlKSkge1xyXG4gICAgICBpZiAoaXNEZXZNb2RlKCkpIHtcclxuICAgICAgICBjb25zb2xlLndhcm4oYEludmFsaWQgc3RhdGUgdHJhbnNpdGlvbiBmcm9tICR7dGhpcy4jc3RhdGV9IHRvICR7bmV3U3RhdGV9IGluIENvbXB1dGVkIFNpZ25hbGApO1xyXG4gICAgICAgIGNvbnNvbGUud2FybihuZXcgRXJyb3IoKS5zdGFjaylcclxuICAgICAgfVxyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy4jc3RhdGUgPSBuZXdTdGF0ZTtcclxuXHJcbiAgICBpZiAodGhpcy4jc3RhdGUgPT09ICdkaXJ0eScgfHwgdGhpcy4jc3RhdGUgPT09ICdjaGVja2VkJykge1xyXG4gICAgICB0aGlzLiNzaW5rcy5mb3JFYWNoKHNpbmsgPT4gc2luayBpbnN0YW5jZW9mIENvbXB1dGVkID8gc2luay5zZXRTdGF0ZSgnY2hlY2tlZCcsIFBSSVZBVEUpIDogc2luay5ub3RpZnkoUFJJVkFURSkpXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RlcnMgYSBuZXcgc2luayAoYSBgQ29tcHV0ZWRgIG9yIGBXYXRjaGVyYCB0aGF0IGRpcmVjdGx5IGRlcGVuZHMgb25cclxuICAgKiB0aGlzIFNpZ25hbCkgaW4gdGhlIGludGVybmFsIHNpbmtzIHNldC5cclxuICAgKlxyXG4gICAqIElmIHRoaXMgaXMgdGhlIGZpcnN0IHNpbmssIHByb3BhZ2F0ZXMgdGhlIHNpbmsgcmVnaXN0cmF0aW9uIHJlY3Vyc2l2ZWx5XHJcbiAgICogdXAgdGhyb3VnaCBgI3NvdXJjZXNgLCBidWlsZGluZyB0aGUgbGl2ZSBkZXBlbmRlbmN5IGNoYWluIHRoYXQgZW5hYmxlc1xyXG4gICAqIHB1c2gtYmFzZWQgaW52YWxpZGF0aW9uLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIHNpbmsgLSBUaGUgZGVwZW5kZW50IG5vZGUgdG8gcmVnaXN0ZXIuXHJcbiAgICogQHBhcmFtIHN5bWJvbCAtIFByaXZhdGUgYWNjZXNzIHN5bWJvbDsgcmVqZWN0cyBjYWxscyBmcm9tIG91dHNpZGUgdGhlIGxpYnJhcnkuXHJcbiAgICogQGludGVybmFsXHJcbiAgICovXHJcbiAgcHVibGljIGFkZFNpbmsoc2luazogQ29tcHV0ZWQ8dW5rbm93bj4gfCBXYXRjaGVyLCBzeW1ib2w6IHN5bWJvbCkge1xyXG4gICAgYXNzZXJ0UHJpdmF0ZUNvbnRleHQoc3ltYm9sKTtcclxuICAgIGlmICh0aGlzLiNzaW5rcy5zaXplID09PSAwKSB7XHJcbiAgICAgIHRoaXMuI3NvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4gc291cmNlLmFkZFNpbmsodGhpcywgUFJJVkFURSkpO1xyXG4gICAgfVxyXG4gICAgdGhpcy4jc2lua3MuYWRkKHNpbmspO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVtb3ZlcyBhIHNpbmsgZnJvbSB0aGUgaW50ZXJuYWwgc2lua3Mgc2V0LlxyXG4gICAqXHJcbiAgICogSWYgdGhlIHNpbmtzIHNldCBiZWNvbWVzIGVtcHR5IGFmdGVyIHJlbW92YWwsIHByb3BhZ2F0ZXMgdGhlIHJlbW92YWxcclxuICAgKiByZWN1cnNpdmVseSB1cCB0aHJvdWdoIGAjc291cmNlc2AsIHRlYXJpbmcgZG93biB0aGUgbGl2ZSBkZXBlbmRlbmN5XHJcbiAgICogY2hhaW4gYW5kIGFsbG93aW5nIGdhcmJhZ2UgY29sbGVjdGlvbiBvZiB1bi13YXRjaGVkIG5vZGVzLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIHNpbmsgLSBUaGUgZGVwZW5kZW50IG5vZGUgdG8gcmVtb3ZlLlxyXG4gICAqIEBwYXJhbSBzeW1ib2wgLSBQcml2YXRlIGFjY2VzcyBzeW1ib2w7IHJlamVjdHMgY2FsbHMgZnJvbSBvdXRzaWRlIHRoZSBsaWJyYXJ5LlxyXG4gICAqIEBpbnRlcm5hbFxyXG4gICAqL1xyXG4gIHB1YmxpYyByZW1vdmVTaW5rKHNpbms6IENvbXB1dGVkIHwgV2F0Y2hlciwgc3ltYm9sOiBzeW1ib2wpIHtcclxuICAgIGFzc2VydFByaXZhdGVDb250ZXh0KHN5bWJvbCk7XHJcbiAgICB0aGlzLiNzaW5rcy5kZWxldGUoc2luayk7XHJcblxyXG4gICAgaWYgKHRoaXMuI3NpbmtzLnNpemUgPT09IDApIHtcclxuICAgICAgdGhpcy4jc291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiBzb3VyY2UucmVtb3ZlU2luayh0aGlzLCBQUklWQVRFKSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWN1cnNpdmVseSB3YWxrcyB0aGUgc291cmNlIGdyYXBoIGRlcHRoLWZpcnN0IHRvIGZpbmQgdGhlIGRlZXBlc3QsXHJcbiAgICogbGVmdC1tb3N0IGBDb21wdXRlZGAgbm9kZSB0aGF0IGlzIGluIGEgYH5kaXJ0eX5gIG9yIGB+Y2hlY2tlZH5gIHN0YXRlLlxyXG4gICAqXHJcbiAgICogVGhpcyBlbnN1cmVzIHRoYXQgcmVjYWxjdWxhdGlvbiBhbHdheXMgc3RhcnRzIGZyb20gdGhlIGJvdHRvbSBvZiB0aGVcclxuICAgKiBkZXBlbmRlbmN5IGdyYXBoLCBzbyBldmVyeSBub2RlIHNlZXMgYWxyZWFkeS11cGRhdGVkIGRlcGVuZGVuY2llcyDigJRcclxuICAgKiB0aGUgY29yZSBvZiBnbGl0Y2gtZnJlZSBldmFsdWF0aW9uLlxyXG4gICAqXHJcbiAgICogQ3V0cyBvZmYgdGhlIHNlYXJjaCB3aGVuIGhpdHRpbmcgYSBgfmNsZWFufmAgYENvbXB1dGVkYCBzb3VyY2UsIHNpbmNlXHJcbiAgICogaXRzIHN1YnRyZWUgaXMgZ3VhcmFudGVlZCB0byBiZSB1cC10by1kYXRlLlxyXG4gICAqXHJcbiAgICogQHJldHVybnMgVGhlIGRlZXBlc3Qgc3RhbGUgYENvbXB1dGVkYCBmb3VuZCwgb3IgYG5vZGVgIGl0c2VsZiBpZiBub25lIG9mXHJcbiAgICogICBpdHMgc291cmNlcyBhcmUgc3RhbGUuXHJcbiAgICovXHJcbiAgI2ZpbmREZWVwZXN0U3RhbGUoKTogQ29tcHV0ZWQge1xyXG4gICAgY29uc3QgdW5jbGVhck5vZGUgPSBbLi4udGhpcy4jc291cmNlc10uZmluZCgoc291cmNlKTogc291cmNlIGlzIENvbXB1dGVkID0+IHNvdXJjZSBpbnN0YW5jZW9mIENvbXB1dGVkICYmIChzb3VyY2UuI3N0YXRlID09PSAnZGlydHknIHx8IHNvdXJjZS4jc3RhdGUgPT09ICdjaGVja2VkJykpO1xyXG4gICAgcmV0dXJuIHVuY2xlYXJOb2RlID8gdW5jbGVhck5vZGUuI2ZpbmREZWVwZXN0U3RhbGUoKSA6IHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFeGVjdXRlcyBgI2NhbGxiYWNrYCB0byByZWNvbXB1dGUgdGhpcyBTaWduYWwncyB2YWx1ZS5cclxuICAgKlxyXG4gICAqIEltcGxlbWVudHMgdGhlIFwicmVjYWxjdWxhdGUgZGlydHkgY29tcHV0ZWQgU2lnbmFsXCIgYWxnb3JpdGhtOlxyXG4gICAqIDEuIENsZWFycyBzdGFsZSBzb3VyY2VzIGFuZCByZW1vdmVzIHRoaXMgU2lnbmFsIGZyb20gdGhlaXIgc2lua3MuXHJcbiAgICogMi4gU2V0cyBgY29tcHV0aW5nYCB0byB0aGlzIFNpZ25hbCBmb3IgYXV0b21hdGljIGRlcGVuZGVuY3kgdHJhY2tpbmcuXHJcbiAgICogMy4gUnVucyB0aGUgY2FsbGJhY2ssIGNhY2hpbmcgdGhlIHJldHVybiB2YWx1ZSBvciBhbnkgdGhyb3duIGV4Y2VwdGlvbi5cclxuICAgKiA0LiBSZXN0b3JlcyB0aGUgcHJldmlvdXMgYGNvbXB1dGluZ2AgdmFsdWUuXHJcbiAgICogNS4gUnVucyB0aGUgXCJzZXQgU2lnbmFsIHZhbHVlXCIgYWxnb3JpdGhtIHRvIGRldGVjdCB2YWx1ZSBjaGFuZ2VzLlxyXG4gICAqIDYuIFRyYW5zaXRpb25zIHN0YXRlIHRvIGB+Y2xlYW5+YC5cclxuICAgKiA3LiBQcm9wYWdhdGVzIGB+ZGlydHl+YCB0byBzaW5rcyAob3IgYXR0ZW1wdHMgYH5jbGVhbn5gIGlmIHZhbHVlIHVuY2hhbmdlZCkuXHJcbiAgICpcclxuICAgKiBAc2VlIFNpZ25hbCBhbGdvcml0aG1zIOKAlCBcIkFsZ29yaXRobTogcmVjYWxjdWxhdGUgZGlydHkgY29tcHV0ZWQgU2lnbmFsXCJcclxuICAgKi9cclxuICAjY29tcHV0ZVZhbHVlKCk6IHZvaWQge1xyXG4gICAgdGhpcy4jc291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiBzb3VyY2UucmVtb3ZlU2luayh0aGlzLCBQUklWQVRFKSk7XHJcbiAgICB0aGlzLiNzb3VyY2VzLmNsZWFyKCk7XHJcblxyXG4gICAgcHVzaENvbXB1dGVkKHRoaXMpO1xyXG4gICAgdGhpcy5zZXRTdGF0ZSgnY29tcHV0aW5nJywgUFJJVkFURSk7XHJcblxyXG4gICAgbGV0IG5ld1ZhbHVlOiBUIHwgeyBpc0Vycm9yOiB0cnVlOyB2YWx1ZTogRXJyb3IgfTtcclxuXHJcbiAgICB0cnkge1xyXG4gICAgICBuZXdWYWx1ZSA9IHRoaXMuI2NhbGxiYWNrLmNhbGwodGhpcyk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBuZXdWYWx1ZSA9IHsgaXNFcnJvcjogdHJ1ZSwgdmFsdWU6IGVycm9yIGFzIEVycm9yIH07XHJcbiAgICB9IGZpbmFsbHkge1xyXG4gICAgICBwb3BDb21wdXRlZCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IG91dGNvbWUgPSB0aGlzLiNzZXRWYWx1ZShuZXdWYWx1ZSk7XHJcblxyXG4gICAgdGhpcy5zZXRTdGF0ZSgnY2xlYW4nLCBQUklWQVRFKTtcclxuXHJcbiAgICBvdXRjb21lID09PSAnZGlydHknXHJcbiAgICAgID8gdGhpcy4jc2lua3MuZm9yRWFjaChzaW5rID0+IHNpbmsgaW5zdGFuY2VvZiBDb21wdXRlZCA/IHNpbmsuc2V0U3RhdGUoJ2RpcnR5JywgUFJJVkFURSkgOiBzaW5rLm5vdGlmeShQUklWQVRFKSlcclxuICAgICAgOiB0aGlzLiNwcm9wYWdhdGVDbGVhbigpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSW1wbGVtZW50cyB0aGUgXCJzZXQgU2lnbmFsIHZhbHVlXCIgYWxnb3JpdGhtLlxyXG4gICAqXHJcbiAgICogQ29tcGFyZXMgdGhlIG5ldyB2YWx1ZSBhZ2FpbnN0IHRoZSBjYWNoZWQgb25lIHVzaW5nIGAjZXF1YWxzYC4gSWYgZXF1YWwsXHJcbiAgICogcmV0dXJucyBgfmNsZWFufmAgYW5kIGxlYXZlcyBgI3ZhbHVlYCB1bnRvdWNoZWQuIE90aGVyd2lzZSB1cGRhdGVzXHJcbiAgICogYCN2YWx1ZWAgYW5kIHJldHVybnMgYH5kaXJ0eX5gLlxyXG4gICAqXHJcbiAgICogU3BlY2lhbCBjYXNlczpcclxuICAgKiAtIElmIGBuZXdWYWx1ZWAgaXMgYSBib3hlZCBlcnJvciwgYCNlcXVhbHNgIGlzIHNraXBwZWQgYW5kIHRoZSBlcnJvciBpc1xyXG4gICAqICAgY2FjaGVkIGRpcmVjdGx5LlxyXG4gICAqIC0gSWYgYCNlcXVhbHNgIGl0c2VsZiB0aHJvd3MsIHRoZSBleGNlcHRpb24gaXMgY2FjaGVkIGFzIGEgYm94ZWQgZXJyb3JcclxuICAgKiAgIGFuZCB0aGUgb3V0Y29tZSBpcyBgfmRpcnR5fmAuXHJcbiAgICpcclxuICAgKiBAcGFyYW0gbmV3VmFsdWUgLSBUaGUgdmFsdWUgKG9yIGJveGVkIGVycm9yKSBwcm9kdWNlZCBieSBgI2NhbGxiYWNrYC5cclxuICAgKiBAcmV0dXJucyBgfmNsZWFufmAgaWYgdGhlIHZhbHVlIGlzIHVuY2hhbmdlZCwgYH5kaXJ0eX5gIG90aGVyd2lzZS5cclxuICAgKlxyXG4gICAqIEBzZWUgU2lnbmFsIGFsZ29yaXRobXMg4oCUIFwiU2V0IFNpZ25hbCB2YWx1ZSBhbGdvcml0aG1cIlxyXG4gICAqL1xyXG4gICNzZXRWYWx1ZShuZXdWYWx1ZTogVCB8IHsgaXNFcnJvcjogdHJ1ZTsgdmFsdWU6IEVycm9yIH0pOiAnY2xlYW4nIHwgJ2RpcnR5JyB7XHJcbiAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuI3ZhbHVlO1xyXG5cclxuICAgIC8qXHJcbiAgICAgIElmIG5ldyB2YWx1ZSBpcyBhbiBlcnJvciB3ZSBhbHdheXMgdXBkYXRlIHdpdGhvdXQgY2FsbGluZyBlcXVhbHNcclxuICAgICovXHJcbiAgICBpZiAodGhpcy4jaXNFcnJvclZhbHVlKG5ld1ZhbHVlKSkge1xyXG4gICAgICB0aGlzLiN2YWx1ZSA9IG5ld1ZhbHVlO1xyXG4gICAgICByZXR1cm4gJ2RpcnR5JztcclxuICAgIH1cclxuXHJcbiAgICB0cnkge1xyXG4gICAgICBpZiAoIXRoaXMuI2lzRXJyb3JWYWx1ZShvbGRWYWx1ZSkgJiYgdGhpcy4jZXF1YWxzLmNhbGwodGhpcywgb2xkVmFsdWUsIG5ld1ZhbHVlKSkge1xyXG4gICAgICAgIHJldHVybiAnY2xlYW4nO1xyXG4gICAgICB9XHJcbiAgICB9IGNhdGNoIChlcXVhbHNFcnJvcikge1xyXG4gICAgICB0aGlzLiN2YWx1ZSA9IHsgaXNFcnJvcjogdHJ1ZSwgdmFsdWU6IGVxdWFsc0Vycm9yIGFzIEVycm9yIH07XHJcbiAgICAgIHJldHVybiAnZGlydHknO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuI3ZhbHVlID0gbmV3VmFsdWU7XHJcbiAgICByZXR1cm4gJ2RpcnR5JztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlY3Vyc2l2ZWx5IG1hcmtzIGB+Y2hlY2tlZH5gIHNpbmtzIGFzIGB+Y2xlYW5+YCB3aGVuIGFsbCBvZiB0aGVpclxyXG4gICAqIGltbWVkaWF0ZSBzb3VyY2VzIGFyZSBhbHJlYWR5IGB+Y2xlYW5+YC5cclxuICAgKlxyXG4gICAqIENhbGxlZCBhZnRlciBhIHJlY2FsY3VsYXRpb24gdGhhdCBwcm9kdWNlZCBhbiB1bmNoYW5nZWQgdmFsdWUgKGB+Y2xlYW5+YFxyXG4gICAqIG91dGNvbWUgZnJvbSBgI3NldFZhbHVlYCkuIFByb3BhZ2F0ZXMgdGhlIGNsZWFuIHNpZ25hbCB1cHdhcmQgdGhyb3VnaFxyXG4gICAqIHRoZSBncmFwaCBzbyB0aGF0IENvbXB1dGVkIG5vZGVzIHRoYXQgd2VyZSBvbmx5IHRyYW5zaXRpdmVseSBkaXJ0eSDigJQgYW5kXHJcbiAgICogd2hvc2UgZGVwZW5kZW5jaWVzIGhhdmUgbm90IGFjdHVhbGx5IGNoYW5nZWQg4oCUIGFyZSBub3QgbmVlZGxlc3NseVxyXG4gICAqIHJlLWV2YWx1YXRlZCBvbiB0aGUgbmV4dCByZWFkLlxyXG4gICAqXHJcbiAgICogQHNlZSBTaWduYWwgYWxnb3JpdGhtcyDigJQgXCJBbGdvcml0aG06IHJlY2FsY3VsYXRlIGRpcnR5IGNvbXB1dGVkIFNpZ25hbFwiXHJcbiAgICovXHJcbiAgI3Byb3BhZ2F0ZUNsZWFuKCk6IHZvaWQge1xyXG4gICAgWy4uLnRoaXMuI3NpbmtzXVxyXG4gICAgICAuZmlsdGVyKChzaW5rKTogc2luayBpcyBDb21wdXRlZDx1bmtub3duPiA9PiBzaW5rIGluc3RhbmNlb2YgQ29tcHV0ZWQgJiYgc2luay4jc3RhdGUgPT09ICdjaGVja2VkJylcclxuICAgICAgLmZvckVhY2goc2luayA9PiB7XHJcbiAgICAgICAgY29uc3QgYWxsU291cmNlc0NsZWFuID0gWy4uLnNpbmsuI3NvdXJjZXNdLmV2ZXJ5KHNvdXJjZSA9PiAhKHNvdXJjZSBpbnN0YW5jZW9mIENvbXB1dGVkKSB8fCBzb3VyY2UuI3N0YXRlID09PSAnY2xlYW4nKTtcclxuICAgICAgICBpZiAoYWxsU291cmNlc0NsZWFuKSB7XHJcbiAgICAgICAgICBzaW5rLiNzdGF0ZSA9ICdjbGVhbic7XHJcbiAgICAgICAgICBzaW5rLiNwcm9wYWdhdGVDbGVhbigpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUeXBlIGd1YXJkIHRoYXQgY2hlY2tzIHdoZXRoZXIgYSB2YWx1ZSBpcyBhIGJveGVkIGVycm9yIG9iamVjdC5cclxuICAgKlxyXG4gICAqIFVzZWQgdG8gZGlzdGluZ3Vpc2ggYSBsZWdpdGltYXRlbHkgY29tcHV0ZWQgdmFsdWUgZnJvbSBhIGNhY2hlZFxyXG4gICAqIGV4Y2VwdGlvbiBwcm9kdWNlZCBieSBgI2NhbGxiYWNrYCBvciBgI2VxdWFsc2AuXHJcbiAgICpcclxuICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gaW5zcGVjdC5cclxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBgeyBpc0Vycm9yOiB0cnVlOyB2YWx1ZTogRXJyb3IgfWAuXHJcbiAgICovXHJcbiAgI2lzRXJyb3JWYWx1ZSh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIHsgaXNFcnJvcjogdHJ1ZTsgdmFsdWU6IEVycm9yIH0ge1xyXG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgISF2YWx1ZSAmJiAnaXNFcnJvcicgaW4gdmFsdWU7XHJcbiAgfVxyXG5cclxuICAjaXNWYWxpZFRyYW5zaXRpb24oZnJvbTogQ29tcHV0ZWRTdGF0ZSwgdG86IENvbXB1dGVkU3RhdGUpOiBib29sZWFuIHtcclxuICAgIHN3aXRjaCAoZnJvbSkge1xyXG4gICAgICBjYXNlICdjaGVja2VkJzpcclxuICAgICAgICByZXR1cm4gdG8gPT09ICdjbGVhbicgfHwgdG8gPT09ICdkaXJ0eSc7XHJcbiAgICAgIGNhc2UgJ2NsZWFuJzpcclxuICAgICAgICByZXR1cm4gdG8gPT09ICdjaGVja2VkJyB8fCB0byA9PT0gJ2RpcnR5JztcclxuICAgICAgY2FzZSAnZGlydHknOlxyXG4gICAgICAgIHJldHVybiB0byA9PT0gJ2NvbXB1dGluZyc7XHJcbiAgICAgIGNhc2UgJ2NvbXB1dGluZyc6XHJcbiAgICAgICAgcmV0dXJuIHRvID09PSAnY2xlYW4nO1xyXG4gICAgfVxyXG4gIH1cclxufSIsImltcG9ydCB7IE5vQXJnc1ZvaWRGdW5jdGlvbiB9IGZyb20gJ0B4YWVuZGFyL3R5cGVzJztcclxuaW1wb3J0IHsgR0xPQkFMX1NUQVRFIH0gZnJvbSAnLi4vLi4vdXRpbHMvZ2xvYmFscy9nbG9iYWxzJztcclxuaW1wb3J0IHsgUFJJVkFURSwgYXNzZXJ0UHJpdmF0ZUNvbnRleHQgfSBmcm9tICcuLi8uLi91dGlscy9wcml2YXRlLXN5bWJvbC9wcml2YXRlLXN5bWJvbCc7XHJcbmltcG9ydCB7IFNpZ25hbEVxdWFsIH0gZnJvbSAnLi4vLi4vdHlwZXMvc2lnbmFsLWVxdWFsLnR5cGUnO1xyXG5pbXBvcnQgeyBTaWduYWxPcHRpb25zIH0gZnJvbSAnLi4vLi4vdHlwZXMvc2lnbmFsLW9wdGlvbnMudHlwZSc7XHJcbmltcG9ydCB7IENvbXB1dGVkIH0gZnJvbSAnLi4vY29tcHV0ZWQvY29tcHV0ZWQnO1xyXG5pbXBvcnQgeyBXYXRjaGVyIH0gZnJvbSAnLi4vd2F0Y2hlci93YXRjaGVyJztcclxuXHJcbmV4cG9ydCBjbGFzcyBTdGF0ZTxUID0gYW55PiB7XHJcbiAgLyoqXHJcbiAgICogVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHNpZ25hbC5cclxuICAgKlxyXG4gICAqIEluaXRpYWxpc2VkIHRvIGBpbml0aWFsVmFsdWVgIGluIHRoZSBjb25zdHJ1Y3RvciBhbmQgdXBkYXRlZCBieSBgc2V0YFxyXG4gICAqIHdoZW5ldmVyIHRoZSBuZXcgdmFsdWUgaXMgbm90IGVxdWFsIHRvIHRoZSBjdXJyZW50IG9uZSBhY2NvcmRpbmcgdG9cclxuICAgKiBgI2VxdWFsc2AuXHJcbiAgICpcclxuICAgKiBAaW50ZXJuYWxTbG90XHJcbiAgICogQHNlZSBTaWduYWwgYWxnb3JpdGhtcyDigJQgJ1NpZ25hbC5TdGF0ZSBpbnRlcm5hbCBzbG90cydcclxuICAgKi9cclxuICAjdmFsdWU6IFQ7XHJcbiAgLyoqXHJcbiAgICogVGhlIGVxdWFsaXR5IGZ1bmN0aW9uIHVzZWQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgYSBuZXcgdmFsdWUgaXNcclxuICAgKiBtZWFuaW5nZnVsbHkgZGlmZmVyZW50IGZyb20gdGhlIGN1cnJlbnQgb25lLlxyXG4gICAqXHJcbiAgICogQ2FsbGVkIGFzIGBlcXVhbHMuY2FsbChzaWduYWwsIG9sZFZhbHVlLCBuZXdWYWx1ZSlgLiBJZiBpdCByZXR1cm5zXHJcbiAgICogYHRydWVgIHRoZSBzaWduYWwgaXMgY29uc2lkZXJlZCB1bmNoYW5nZWQgYW5kIG5vIHByb3BhZ2F0aW9uIG9jY3Vycy5cclxuICAgKiBEZWZhdWx0cyB0byBgT2JqZWN0LmlzYCB3aGVuIG5vdCBwcm92aWRlZCB2aWEgb3B0aW9ucy5cclxuICAgKlxyXG4gICAqIEBpbnRlcm5hbFNsb3RcclxuICAgKiBAc2VlIFNpZ25hbCBhbGdvcml0aG1zIOKAlCAnU2lnbmFsLlN0YXRlIGludGVybmFsIHNsb3RzJ1xyXG4gICAqIEBzZWUgQWxnb3JpdGhtIOKAlCAnU2V0IFNpZ25hbCB2YWx1ZSdcclxuICAgKi9cclxuICAjZXF1YWxzOiBTaWduYWxFcXVhbDxUPlxyXG4gIC8qKlxyXG4gICAqIE9wdGlvbmFsIGNhbGxiYWNrIGludm9rZWQgKHdpdGggYGZyb3plbiA9IHRydWVgKSB0aGUgZmlyc3QgdGltZSB0aGlzXHJcbiAgICogU2lnbmFsIGdhaW5zIGEgc2luayDigJQgaS5lLiB3aGVuIGl0IHRyYW5zaXRpb25zIGZyb20gdW4tb2JzZXJ2ZWQgdG9cclxuICAgKiBvYnNlcnZlZCBieSBhdCBsZWFzdCBvbmUgYFdhdGNoZXJgIChkaXJlY3RseSBvciB0cmFuc2l0aXZlbHkpLlxyXG4gICAqXHJcbiAgICogQGludGVybmFsU2xvdFxyXG4gICAqIEBzZWUgU2lnbmFsIGFsZ29yaXRobXMg4oCUICdTaWduYWwuU3RhdGUgaW50ZXJuYWwgc2xvdHMnXHJcbiAgICogQHNlZSBNZXRob2Qg4oCUIGBTaWduYWwuc3VidGxlLldhdGNoZXIucHJvdG90eXBlLndhdGNoYFxyXG4gICAqL1xyXG4gICN3YXRjaGVkPzogTm9BcmdzVm9pZEZ1bmN0aW9uO1xyXG4gIC8qKlxyXG4gICAqIE9wdGlvbmFsIGNhbGxiYWNrIGludm9rZWQgKHdpdGggYGZyb3plbiA9IHRydWVgKSB3aGVuIHRoaXMgU2lnbmFsIGxvc2VzXHJcbiAgICogaXRzIGxhc3Qgc2luayDigJQgaS5lLiB3aGVuIGl0IHRyYW5zaXRpb25zIGZyb20gb2JzZXJ2ZWQgYmFjayB0b1xyXG4gICAqIHVuLW9ic2VydmVkLlxyXG4gICAqXHJcbiAgICogQGludGVybmFsU2xvdFxyXG4gICAqIEBzZWUgU2lnbmFsIGFsZ29yaXRobXMg4oCUICdTaWduYWwuU3RhdGUgaW50ZXJuYWwgc2xvdHMnXHJcbiAgICogQHNlZSBNZXRob2Qg4oCUIGBTaWduYWwuc3VidGxlLldhdGNoZXIucHJvdG90eXBlLnVud2F0Y2hgXHJcbiAgICovXHJcbiAgI3Vud2F0Y2hlZD86IE5vQXJnc1ZvaWRGdW5jdGlvbjtcclxuICAvKipcclxuICAgKiBUaGUgc2V0IG9mIHdhdGNoZWQgc2lnbmFscyB0aGF0IGRpcmVjdGx5IGRlcGVuZCBvbiB0aGlzIG9uZS5cclxuICAgKlxyXG4gICAqIFBvcHVsYXRlZCBvbmx5IHdoZW4gdGhpcyBTaWduYWwgaXMgcmVhY2hhYmxlIGZyb20gYXQgbGVhc3Qgb25lIGFjdGl2ZVxyXG4gICAqIGBXYXRjaGVyYCDigJQgdW4td2F0Y2hlZCBTaWduYWxzIGhhdmUgYW4gZW1wdHkgc2lua3Mgc2V0LCB3aGljaCBhbGxvd3NcclxuICAgKiB0aGVtIHRvIGJlIGdhcmJhZ2UtY29sbGVjdGVkIGluZGVwZW5kZW50bHkgZnJvbSB0aGUgcmVzdCBvZiB0aGUgZ3JhcGguXHJcbiAgICpcclxuICAgKiBTaG91bGQgY29udGFpbiBib3RoIGBDb21wdXRlZGAgYW5kIGBXYXRjaGVyYCBpbnN0YW5jZXMsIGFzIGJvdGggY2FuIGJlXHJcbiAgICogZGlyZWN0IGRlcGVuZGVudHMgb2YgYSBgU3RhdGVgLlxyXG4gICAqXHJcbiAgICogQGludGVybmFsU2xvdFxyXG4gICAqIEBzZWUgU2lnbmFsIGFsZ29yaXRobXMg4oCUICdTaWduYWwuU3RhdGUgaW50ZXJuYWwgc2xvdHMnXHJcbiAgICogQHNlZSBNZXRob2Qg4oCUIGBTaWduYWwuU3RhdGUucHJvdG90eXBlLmdldGAgKE5PVEUgb24gc2lua3MpXHJcbiAgICovXHJcbiAgI3NpbmtzOiBTZXQ8Q29tcHV0ZWQ8dW5rbm93bj4gfCBXYXRjaGVyPjtcclxuICAvKipcclxuICAgKiBSZXR1cm5zIGEgc25hcHNob3Qgb2YgdGhlIGN1cnJlbnQgc2lua3Mgc2V0IGZvciBpbnRyb3NwZWN0aW9uLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIHN5bWJvbCAtIFByaXZhdGUgYWNjZXNzIHN5bWJvbDsgcmVqZWN0cyBjYWxscyBmcm9tIG91dHNpZGUgdGhlIGxpYnJhcnkuXHJcbiAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgYENvbXB1dGVkYCBhbmQgYFdhdGNoZXJgIGluc3RhbmNlcyB0aGF0IGRlcGVuZCBvbiB0aGlzIFNpZ25hbC5cclxuICAgKiBAaW50ZXJuYWxcclxuICAgKi9cclxuICBwdWJsaWMgZ2V0U2lua3Moc3ltYm9sOiBzeW1ib2wpOiAoQ29tcHV0ZWQ8dW5rbm93bj4gfCBXYXRjaGVyKVtdIHtcclxuICAgIGFzc2VydFByaXZhdGVDb250ZXh0KHN5bWJvbCk7XHJcbiAgICByZXR1cm4gWy4uLnRoaXMuI3NpbmtzXTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENyZWF0ZXMgYSBuZXcgYFN0YXRlYCBzaWduYWwuXHJcbiAgICpcclxuICAgKiBAcGFyYW0gaW5pdGlhbFZhbHVlIC0gVGhlIGluaXRpYWwgdmFsdWUgb2YgdGhlIHNpZ25hbC5cclxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb246XHJcbiAgICogICAtIGBlcXVhbHNgIOKAlCBjdXN0b20gZXF1YWxpdHkgZnVuY3Rpb247IGRlZmF1bHRzIHRvIGBPYmplY3QuaXNgLlxyXG4gICAqICAgLSBgd2F0Y2hlZGAg4oCUIGNhbGxlZCB3aGVuIHRoZSBzaWduYWwgZ2FpbnMgaXRzIGZpcnN0IHNpbmsuXHJcbiAgICogICAtIGB1bndhdGNoZWRgIOKAlCBjYWxsZWQgd2hlbiB0aGUgc2lnbmFsIGxvc2VzIGl0cyBsYXN0IHNpbmsuXHJcbiAgICpcclxuICAgKiBAc2VlIFNpZ25hbCBhbGdvcml0aG1zIOKAlCAnQ29uc3RydWN0b3I6IFNpZ25hbC5TdGF0ZShpbml0aWFsVmFsdWUsIG9wdGlvbnMpJ1xyXG4gICAqL1xyXG4gIGNvbnN0cnVjdG9yKGluaXRpYWxWYWx1ZTogVCwgb3B0aW9ucz86IFNpZ25hbE9wdGlvbnM8VD4pIHtcclxuICAgIHRoaXMuI3ZhbHVlID0gaW5pdGlhbFZhbHVlO1xyXG4gICAgdGhpcy4jZXF1YWxzID0gb3B0aW9ucz8uZXF1YWxzID8/IE9iamVjdC5pcztcclxuICAgIHRoaXMuI3dhdGNoZWQgPSBvcHRpb25zPy53YXRjaGVkO1xyXG4gICAgdGhpcy4jdW53YXRjaGVkID0gb3B0aW9ucz8udW53YXRjaGVkO1xyXG4gICAgdGhpcy4jc2lua3MgPSBuZXcgU2V0O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJucyB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgc2lnbmFsLCByZWdpc3RlcmluZyB0aGlzIFNpZ25hbCBhcyBhXHJcbiAgICogc291cmNlIG9mIHRoZSBpbm5lcm1vc3QgYENvbXB1dGVkYCBjdXJyZW50bHkgYmVpbmcgZXZhbHVhdGVkIChpZiBhbnkpLlxyXG4gICAqXHJcbiAgICogQHRocm93cyBJZiBgZnJvemVuYCBpcyBgdHJ1ZWAg4oCUIHJlYWRzIGFyZSBmb3JiaWRkZW4gd2hpbGUgYSBwcm90ZWN0ZWRcclxuICAgKiBjYWxsYmFjayAoYG5vdGlmeWAsIGB3YXRjaGVkYCwgYHVud2F0Y2hlZGApIGlzIGV4ZWN1dGluZy5cclxuICAgKlxyXG4gICAqIEBzZWUgU2lnbmFsIGFsZ29yaXRobXMg4oCUICdNZXRob2Q6IFNpZ25hbC5TdGF0ZS5wcm90b3R5cGUuZ2V0KCknXHJcbiAgICovXHJcbiAgcHVibGljIGdldCgpOiBUIHtcclxuICAgIGlmIChHTE9CQUxfU1RBVEUuZnJvemVuKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGdldCB2YWx1ZSB3aGlsZSBzaWduYWxzIGFyZSBmcm96ZW4nKTtcclxuICAgIH1cclxuXHJcbiAgICAvKlxyXG4gICAgICBJZiB0aGVyZSBpcyBhIGN1cnJlbnRseSBjb21wdXRpbmcgYENvbXB1dGVkYCwgcmVnaXN0ZXIgdGhpcyBgU3RhdGVgIGFzIGFcclxuICAgICAgc291cmNlIG9mIHRoYXQgYENvbXB1dGVkYC4gXHJcbiAgICAgIFRoaXMgaXMgaG93IHRoZSBkZXBlbmRlbmN5IGdyYXBoIGlzIGJ1aWx0LlxyXG5cclxuICAgICAgVEhpcyBpcyBkb25lIGV2ZXJ5IHRpbWUgYSBgU3RhdGVgIGlzIHJlYWQgdG8gZ3VhcmFudGVlIGFsd2F5cyB1cC10by1kYXRlIFxyXG4gICAgICB0cmFja2luZyBvZiBkZXBlbmRlbmNpZXMsIGV2ZW4gaWYgdGhleSBjaGFuZ2UgYmV0d2VlbiBjb21wdXRhdGlvbnNcclxuICAgICovXHJcbiAgICBHTE9CQUxfU1RBVEUuY29tcHV0aW5nPy5hZGRTb3VyY2UodGhpcywgUFJJVkFURSlcclxuXHJcbiAgICByZXR1cm4gdGhpcy4jdmFsdWU7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBVcGRhdGVzIHRoZSBzaWduYWwncyB2YWx1ZSBhbmQgcHJvcGFnYXRlcyBjaGFuZ2VzIHRvIGFsbCBkZXBlbmRlbnRcclxuICAgKiBzaW5rcy5cclxuICAgKlxyXG4gICAqIElmIGBlcXVhbHMoY3VycmVudFZhbHVlLCBuZXdWYWx1ZSlgIHJldHVybnMgYHRydWVgIHRoZSBjYWxsIGlzIGEgbm8tb3BcclxuICAgKiBhbmQgbm8gcHJvcGFnYXRpb24gb2NjdXJzLiBPdGhlcndpc2UgYCN2YWx1ZWAgaXMgdXBkYXRlZCwgYWxsIGRpcmVjdFxyXG4gICAqIGBDb21wdXRlZGAgc2lua3MgYXJlIG1hcmtlZCBgfmRpcnR5fmAsIGluZGlyZWN0IG9uZXMgYH5jaGVja2VkfmAsIGFuZFxyXG4gICAqIGVhY2ggcmVhY2hhYmxlIGBXYXRjaGVyYCBoYXMgaXRzIGBub3RpZnlgIGNhbGxiYWNrIGludm9rZWQgc3luY2hyb25vdXNseVxyXG4gICAqICh3aXRoIGBmcm96ZW4gPSB0cnVlYCkuXHJcbiAgICpcclxuICAgKiBAcGFyYW0gbmV3VmFsdWUgLSBUaGUgbmV3IHZhbHVlIHRvIHNldC5cclxuICAgKiBAdGhyb3dzIElmIGBmcm96ZW5gIGlzIGB0cnVlYCDigJQgd3JpdGVzIGFyZSBmb3JiaWRkZW4gd2hpbGUgYSBwcm90ZWN0ZWRcclxuICAgKiBjYWxsYmFjayBpcyBleGVjdXRpbmcuXHJcbiAgICpcclxuICAgKiBAc2VlIFNpZ25hbCBhbGdvcml0aG1zIOKAlCAnTWV0aG9kOiBTaWduYWwuU3RhdGUucHJvdG90eXBlLnNldChuZXdWYWx1ZSknXHJcbiAgICogQHNlZSBBbGdvcml0aG0g4oCUICdTZXQgU2lnbmFsIHZhbHVlJ1xyXG4gICAqL1xyXG4gIHB1YmxpYyBzZXQobmV3VmFsdWU6IFQpOiB2b2lkIHtcclxuICAgIGlmIChHTE9CQUxfU1RBVEUuZnJvemVuKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHNldCB2YWx1ZSB3aGlsZSBzaWduYWxzIGFyZSBmcm96ZW4nKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXRoaXMuI2VxdWFscy5jYWxsKHRoaXMsIHRoaXMuI3ZhbHVlLCBuZXdWYWx1ZSkpIHtcclxuICAgICAgdGhpcy4jdmFsdWUgPSBuZXdWYWx1ZTtcclxuICAgICAgdGhpcy4jc2lua3MuZm9yRWFjaChzaW5rID0+IHNpbmsgaW5zdGFuY2VvZiBDb21wdXRlZCA/IHNpbmsuc2V0U3RhdGUoJ2RpcnR5JywgUFJJVkFURSkgOiBzaW5rLm5vdGlmeShQUklWQVRFKSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWdpc3RlcnMgYSBuZXcgc2luayAoYSBgQ29tcHV0ZWRgIG9yIGBXYXRjaGVyYCB0aGF0IGRlcGVuZHMgb24gdGhpc1xyXG4gICAqIFNpZ25hbCkgaW4gdGhlIGludGVybmFsIHNpbmtzIHNldC5cclxuICAgKlxyXG4gICAqIENhbGxlZCBieSBgV2F0Y2hlci5wcm90b3R5cGUud2F0Y2hgIHdoZW4gYnVpbGRpbmcgdGhlIGxpdmUgZGVwZW5kZW5jeVxyXG4gICAqIGNoYWluLCBhbmQgYnkgYENvbXB1dGVkYCB3aGVuIHByb3BhZ2F0aW5nIHNpbmsgcmVnaXN0cmF0aW9uIHVwIHRocm91Z2hcclxuICAgKiBpdHMgc291cmNlcy5cclxuICAgKlxyXG4gICAqIEBwYXJhbSBzaW5rIC0gVGhlIGRlcGVuZGVudCBub2RlIHRvIHJlZ2lzdGVyLlxyXG4gICAqIEBwYXJhbSBzeW1ib2wgLSBUaGUgcHJpdmF0ZSBzeW1ib2wgZm9yIHZhbGlkYXRpb24uXHJcbiAgICogQGludGVybmFsXHJcbiAgICovXHJcbiAgcHVibGljIGFkZFNpbmsoc2luazogQ29tcHV0ZWQgfCBXYXRjaGVyLCBzeW1ib2w6IHN5bWJvbCk6IHZvaWQge1xyXG4gICAgYXNzZXJ0UHJpdmF0ZUNvbnRleHQoc3ltYm9sKTtcclxuICAgIGNvbnN0IGVtcHR5ID0gdGhpcy4jc2lua3Muc2l6ZSA9PT0gMDtcclxuICAgIHRoaXMuI3NpbmtzLmFkZChzaW5rKTtcclxuXHJcbiAgICBpZiAoZW1wdHkgJiYgdGhpcy4jd2F0Y2hlZCkge1xyXG4gICAgICBHTE9CQUxfU1RBVEUuZnJvemVuID0gdHJ1ZTtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICB0aGlzLiN3YXRjaGVkKCk7XHJcbiAgICAgIH0gZmluYWxseSB7XHJcbiAgICAgICAgR0xPQkFMX1NUQVRFLmZyb3plbiA9IGZhbHNlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZW1vdmVzIGEgc2luayBmcm9tIHRoZSBpbnRlcm5hbCBzaW5rcyBzZXQuXHJcbiAgICpcclxuICAgKiBDYWxsZWQgYnkgYFdhdGNoZXIucHJvdG90eXBlLnVud2F0Y2hgIHdoZW4gdGVhcmluZyBkb3duIHRoZSBsaXZlXHJcbiAgICogZGVwZW5kZW5jeSBjaGFpbi4gSWYgdGhlIHNpbmtzIHNldCBiZWNvbWVzIGVtcHR5IGFmdGVyIHJlbW92YWwsIHRoZVxyXG4gICAqIGNhbGxlciBpcyByZXNwb25zaWJsZSBmb3IgcHJvcGFnYXRpbmcgdGhlIHJlbW92YWwgdXAgdGhyb3VnaCB0aGlzXHJcbiAgICogU2lnbmFsJ3Mgc291cmNlcy5cclxuICAgKlxyXG4gICAqIEBwYXJhbSBzaW5rIC0gVGhlIGRlcGVuZGVudCBub2RlIHRvIHJlbW92ZS5cclxuICAgKiBAcGFyYW0gc3ltYm9sIC0gVGhlIHByaXZhdGUgc3ltYm9sIGZvciB2YWxpZGF0aW9uLlxyXG4gICAqIEBpbnRlcm5hbFxyXG4gICAqL1xyXG4gIHB1YmxpYyByZW1vdmVTaW5rKHNpbms6IENvbXB1dGVkIHwgV2F0Y2hlciwgc3ltYm9sOiBzeW1ib2wpOiB2b2lkIHtcclxuICAgIGFzc2VydFByaXZhdGVDb250ZXh0KHN5bWJvbCk7XHJcbiAgICB0aGlzLiNzaW5rcy5kZWxldGUoc2luayk7XHJcbiAgICBjb25zdCBlbXB0eSA9IHRoaXMuI3NpbmtzLnNpemUgPT09IDA7XHJcblxyXG4gICAgaWYgKGVtcHR5ICYmIHRoaXMuI3Vud2F0Y2hlZCkge1xyXG4gICAgICBHTE9CQUxfU1RBVEUuZnJvemVuID0gdHJ1ZTtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICB0aGlzLiN1bndhdGNoZWQoKTtcclxuICAgICAgfSBmaW5hbGx5IHtcclxuICAgICAgICBHTE9CQUxfU1RBVEUuZnJvemVuID0gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwiaW1wb3J0IHsgTm9BcmdzVm9pZEZ1bmN0aW9uIH0gZnJvbSAnQHhhZW5kYXIvdHlwZXMnO1xyXG5pbXBvcnQgeyBHTE9CQUxfU1RBVEUgfSBmcm9tICcuLi8uLi91dGlscy9nbG9iYWxzL2dsb2JhbHMnO1xyXG5pbXBvcnQgeyBQUklWQVRFLCBhc3NlcnRQcml2YXRlQ29udGV4dCB9IGZyb20gJy4uLy4uL3V0aWxzL3ByaXZhdGUtc3ltYm9sL3ByaXZhdGUtc3ltYm9sJztcclxuaW1wb3J0IHsgU3RhdGUgfSBmcm9tICcuLi9zdGF0ZS9zdGF0ZSc7XHJcbmltcG9ydCB7IFdhdGNoZXJTdGF0ZSB9IGZyb20gJy4uLy4uL3R5cGVzL3dhdGNoZXItc3RhdGUudHlwZSc7XHJcbmltcG9ydCB7IENvbXB1dGVkIH0gZnJvbSAnLi4vY29tcHV0ZWQvY29tcHV0ZWQnO1xyXG5pbXBvcnQgeyBpc0Rldk1vZGUgfSBmcm9tICcuLi8uLi91dGlscy9kZXYtbW9kZS9kZXYtbW9kZSc7XHJcblxyXG4vKipcclxuICogQSBgV2F0Y2hlcmAgb2JzZXJ2ZXMgYSBzZXQgb2YgU2lnbmFscyBhbmQgZmlyZXMgYSBgbm90aWZ5YCBjYWxsYmFja1xyXG4gKiBzeW5jaHJvbm91c2x5IHdoZW4gYW55IG9mIHRoZWlyIChyZWN1cnNpdmUpIGRlcGVuZGVuY2llcyBjaGFuZ2UuXHJcbiAqXHJcbiAqIEl0IGlzIHRoZSBsb3ctbGV2ZWwgcHJpbWl0aXZlIG9uIHRvcCBvZiB3aGljaCBmcmFtZXdvcmtzIGltcGxlbWVudFxyXG4gKiBlZmZlY3RzIGFuZCBzY2hlZHVsaW5nLiBJdCBkb2VzIG5vdCBob2xkIGEgdmFsdWUgYW5kIGhhcyBubyBnZW5lcmljXHJcbiAqIHR5cGUgcGFyYW1ldGVyLlxyXG4gKlxyXG4gKiBAc2VlIFNpZ25hbCBhbGdvcml0aG1zIOKAlCAnVGhlIGBTaWduYWwuc3VidGxlLldhdGNoZXJgIGNsYXNzJ1xyXG4gKi9cclxuZXhwb3J0IGNsYXNzIFdhdGNoZXIge1xyXG4gIC8qKlxyXG4gICAqIFRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBXYXRjaGVyLlxyXG4gICAqXHJcbiAgICogLSBgfndhaXRpbmd+YCAg4oCUIG5ld2x5IGNyZWF0ZWQsIG9yIGBub3RpZnlgIGhhcyBhbHJlYWR5IGJlZW4gY2FsbGVkIHNpbmNlXHJcbiAgICogICAgICAgICAgICAgICAgICB0aGUgbGFzdCBgd2F0Y2hgIGNhbGwuIE5vdCBhY3RpdmVseSBvYnNlcnZpbmcgY2hhbmdlcy5cclxuICAgKiAtIGB+d2F0Y2hpbmd+YCDigJQgYWN0aXZlbHkgd2F0Y2hpbmc7IG5vIGRlcGVuZGVuY3kgaGFzIGNoYW5nZWQgeWV0LlxyXG4gICAqIC0gYH5wZW5kaW5nfmAgIOKAlCBhIGRlcGVuZGVuY3kgaGFzIGNoYW5nZWQgYnV0IGBub3RpZnlgIGhhcyBub3QgeWV0IHJ1bi5cclxuICAgKlxyXG4gICAqIEBpbnRlcm5hbFNsb3RcclxuICAgKiBAc2VlIFNpZ25hbCBhbGdvcml0aG1zIOKAlCAnU2lnbmFsLnN1YnRsZS5XYXRjaGVyIFN0YXRlIG1hY2hpbmUnXHJcbiAgICovXHJcbiAgI3N0YXRlOiBXYXRjaGVyU3RhdGU7XHJcbiAgLyoqXHJcbiAgICogVGhlIG9yZGVyZWQgc2V0IG9mIFNpZ25hbHMgdGhpcyBXYXRjaGVyIGlzIGN1cnJlbnRseSB3YXRjaGluZy5cclxuICAgKiBNYXkgY29udGFpbiBib3RoIGBTdGF0ZWAgYW5kIGBDb21wdXRlZGAgaW5zdGFuY2VzLlxyXG4gICAqXHJcbiAgICogQGludGVybmFsU2xvdFxyXG4gICAqIEBzZWUgU2lnbmFsIGFsZ29yaXRobXMg4oCUICdTaWduYWwuc3VidGxlLldhdGNoZXIgaW50ZXJuYWwgc2xvdHMnXHJcbiAgICovXHJcbiAgI3NpZ25hbHM6IFNldDxTdGF0ZTx1bmtub3duPiB8IENvbXB1dGVkPHVua25vd24+PjtcclxuICAvKipcclxuICAgKiBSZXR1cm5zIGEgc25hcHNob3Qgb2YgdGhlIGN1cnJlbnQgd2F0Y2hlZCBzaWduYWxzIHNldCBmb3IgaW50cm9zcGVjdGlvbi5cclxuICAgKlxyXG4gICAqIEBwYXJhbSBzeW1ib2wgLSBQcml2YXRlIGFjY2VzcyBzeW1ib2w7IHJlamVjdHMgY2FsbHMgZnJvbSBvdXRzaWRlIHRoZSBsaWJyYXJ5LlxyXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGBTdGF0ZWAgYW5kIGBDb21wdXRlZGAgaW5zdGFuY2VzIHRoYXQgdGhpcyBXYXRjaGVyIGlzIHdhdGNoaW5nLlxyXG4gICAqIEBpbnRlcm5hbFxyXG4gICAqL1xyXG4gIHB1YmxpYyBnZXRTb3VyY2VzKHN5bWJvbDogc3ltYm9sKTogKFN0YXRlPHVua25vd24+IHwgQ29tcHV0ZWQ8dW5rbm93bj4pW10ge1xyXG4gICAgYXNzZXJ0UHJpdmF0ZUNvbnRleHQoc3ltYm9sKTtcclxuICAgIHJldHVybiBbLi4udGhpcy4jc2lnbmFsc107XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIFRoZSBjYWxsYmFjayBpbnZva2VkIHN5bmNocm9ub3VzbHkgd2hlbiBhIHdhdGNoZWQgU2lnbmFsIChvciBvbmUgb2YgaXRzXHJcbiAgICogcmVjdXJzaXZlIGRlcGVuZGVuY2llcykgY2hhbmdlcyBmb3IgdGhlIGZpcnN0IHRpbWUgc2luY2UgdGhlIGxhc3RcclxuICAgKiBgd2F0Y2hgIGNhbGwuXHJcbiAgICpcclxuICAgKiBSZWNlaXZlcyB0aGUgV2F0Y2hlciBpdHNlbGYgYXMgYHRoaXNgLiBObyBTaWduYWxzIG1heSBiZSByZWFkIG9yIHdyaXR0ZW5cclxuICAgKiBkdXJpbmcgaXRzIGV4ZWN1dGlvbiAoYGZyb3plbmAgaXMgYHRydWVgIGZvciBpdHMgZW50aXJlIGR1cmF0aW9uKS5cclxuICAgKlxyXG4gICAqIEBpbnRlcm5hbFNsb3RcclxuICAgKiBAc2VlIFNpZ25hbCBhbGdvcml0aG1zIOKAlCAnU2lnbmFsLnN1YnRsZS5XYXRjaGVyIGludGVybmFsIHNsb3RzJ1xyXG4gICAqL1xyXG4gICNub3RpZnlDYWxsYmFjazogTm9BcmdzVm9pZEZ1bmN0aW9uO1xyXG5cclxuICAvKipcclxuICAgKiBDcmVhdGVzIGEgbmV3IFdhdGNoZXIuXHJcbiAgICpcclxuICAgKiBUaGUgV2F0Y2hlciBzdGFydHMgaW4gdGhlIGB+d2FpdGluZ35gIHN0YXRlIHdpdGggYW4gZW1wdHkgc2lnbmFscyBzZXQuXHJcbiAgICpcclxuICAgKiBAcGFyYW0gbm90aWZ5Q2FsbGJhY2sgLSBDYWxsZWQgc3luY2hyb25vdXNseSAod2l0aCBgZnJvemVuID0gdHJ1ZWApIHRoZVxyXG4gICAqIGZpcnN0IHRpbWUgYSB3YXRjaGVkIGRlcGVuZGVuY3kgY2hhbmdlcyBhZnRlciBlYWNoIGB3YXRjaGAgY2FsbC4gTm9cclxuICAgKiBTaWduYWxzIG1heSBiZSByZWFkIG9yIHdyaXR0ZW4gaW5zaWRlIHRoaXMgY2FsbGJhY2suXHJcbiAgICpcclxuICAgKiBAc2VlIFNpZ25hbCBhbGdvcml0aG1zIOKAlCAnQ29uc3RydWN0b3I6IG5ldyBTaWduYWwuc3VidGxlLldhdGNoZXIoY2FsbGJhY2spJ1xyXG4gICAqL1xyXG4gIGNvbnN0cnVjdG9yKG5vdGlmeUNhbGxiYWNrOiBOb0FyZ3NWb2lkRnVuY3Rpb24pIHtcclxuICAgIHRoaXMuI3N0YXRlID0gJ3dhaXRpbmcnO1xyXG4gICAgdGhpcy4jc2lnbmFscyA9IG5ldyBTZXQ7XHJcbiAgICB0aGlzLiNub3RpZnlDYWxsYmFjayA9IG5vdGlmeUNhbGxiYWNrO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJucyB0aGUgc3Vic2V0IG9mIHdhdGNoZWQgU2lnbmFscyB0aGF0IGFyZSBgQ29tcHV0ZWRgIGluc3RhbmNlc1xyXG4gICAqIGN1cnJlbnRseSBpbiBhIGB+ZGlydHl+YCBvciBgfmNoZWNrZWR+YCBzdGF0ZSwgbWVhbmluZyB0aGV5IG1heSBoYXZlIGFcclxuICAgKiBzdGFsZSB2YWx1ZSB0aGF0IGhhcyBub3QgeWV0IGJlZW4gcmUtZXZhbHVhdGVkLlxyXG4gICAqXHJcbiAgICogVHlwaWNhbGx5IGNhbGxlZCBpbnNpZGUgdGhlIG1pY3JvdGFzayBzY2hlZHVsZWQgYnkgdGhlIGBub3RpZnlgIGNhbGxiYWNrXHJcbiAgICogdG8ga25vdyB3aGljaCBTaWduYWxzIG5lZWQgdG8gYmUgcHVsbGVkLlxyXG4gICAqXHJcbiAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgYENvbXB1dGVkYCBzaWduYWxzIHRoYXQgYXJlIGRpcnR5IG9yIGNoZWNrZWQuXHJcbiAgICpcclxuICAgKiBAc2VlIFNpZ25hbCBhbGdvcml0aG1zIOKAlCAnTWV0aG9kOiBTaWduYWwuc3VidGxlLldhdGNoZXIucHJvdG90eXBlLmdldFBlbmRpbmcoKSdcclxuICAgKi9cclxuICBwdWJsaWMgZ2V0UGVuZGluZygpOiBDb21wdXRlZDx1bmtub3duPltdIHtcclxuICAgIHJldHVybiBbLi4udGhpcy4jc2lnbmFsc10uZmlsdGVyKChzaWduYWwpOiBzaWduYWwgaXMgQ29tcHV0ZWQ8dW5rbm93bj4gPT4ge1xyXG4gICAgICBpZiAoIShzaWduYWwgaW5zdGFuY2VvZiBDb21wdXRlZCkpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IHN0YXRlID0gc2lnbmFsLmdldFN0YXRlKFBSSVZBVEUpO1xyXG4gICAgICByZXR1cm4gc3RhdGUgPT09ICdkaXJ0eScgfHwgc3RhdGUgPT09ICdjaGVja2VkJztcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQWRkcyB0aGUgZ2l2ZW4gU2lnbmFscyB0byB0aGUgd2F0Y2hlZCBzZXQgYW5kIHRyYW5zaXRpb25zIHRoZSBXYXRjaGVyIHRvXHJcbiAgICogdGhlIGB+d2F0Y2hpbmd+YCBzdGF0ZS5cclxuICAgKlxyXG4gICAqIEZvciBlYWNoIG5ld2x5LXdhdGNoZWQgU2lnbmFsLCB0aGUgV2F0Y2hlciBpcyByZWdpc3RlcmVkIGFzIGEgc2luayBhbmQg4oCUXHJcbiAgICogaWYgaXQgaXMgdGhlIGZpcnN0IHNpbmsg4oCUIHRoZSBzaW5rIHJlZ2lzdHJhdGlvbiBpcyBwcm9wYWdhdGVkIHJlY3Vyc2l2ZWx5XHJcbiAgICogdXAgdGhyb3VnaCB0aGUgU2lnbmFsJ3Mgc291cmNlcywgYnVpbGRpbmcgdGhlIGxpdmUgZGVwZW5kZW5jeSBjaGFpbi5cclxuICAgKlxyXG4gICAqIFRoZSBgd2F0Y2hlZGAgY2FsbGJhY2sgb2YgZWFjaCBTaWduYWwgKGlmIGFueSkgaXMgY2FsbGVkIHdpdGhcclxuICAgKiBgZnJvemVuID0gdHJ1ZWAuXHJcbiAgICpcclxuICAgKiBAcGFyYW0gc2lnbmFscyAtIE9uZSBvciBtb3JlIGBTdGF0ZWAgc2lnbmFscyB0byBzdGFydCB3YXRjaGluZy5cclxuICAgKiBAdGhyb3dzIElmIGBmcm96ZW5gIGlzIGB0cnVlYCBhdCB0aGUgdGltZSBvZiB0aGUgY2FsbC5cclxuICAgKlxyXG4gICAqIEBzZWUgU2lnbmFsIGFsZ29yaXRobXMg4oCUICdNZXRob2Q6IFNpZ25hbC5zdWJ0bGUuV2F0Y2hlci5wcm90b3R5cGUud2F0Y2goLi4uc2lnbmFscyknXHJcbiAgICovXHJcbiAgcHVibGljIHdhdGNoKC4uLnNpZ25hbHM6IChTdGF0ZSB8IENvbXB1dGVkKVtdKSB7XHJcbiAgICBpZiAoR0xPQkFMX1NUQVRFLmZyb3plbikge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCB3YXRjaCBzaWduYWxzIHdoaWxlIGZyb3plbicpO1xyXG4gICAgfVxyXG5cclxuICAgIHNpZ25hbHMuZm9yRWFjaChzaWduYWwgPT4ge1xyXG4gICAgICBpZiAodGhpcy4jc2lnbmFscy5oYXMoc2lnbmFsKSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHdhdGNoIGEgc2lnbmFsIHRoYXQgaXMgYWxyZWFkeSBiZWluZyB3YXRjaGVkJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMuI3NpZ25hbHMuYWRkKHNpZ25hbClcclxuICAgICAgc2lnbmFsLmFkZFNpbmsodGhpcywgUFJJVkFURSk7XHJcbiAgICB9KTtcclxuXHJcblxyXG4gICAgdGhpcy5zZXRTdGF0ZSgnd2F0Y2hpbmcnLCBQUklWQVRFKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlbW92ZXMgdGhlIGdpdmVuIFNpZ25hbHMgZnJvbSB0aGUgd2F0Y2hlZCBzZXQuXHJcbiAgICpcclxuICAgKiBGb3IgZWFjaCByZW1vdmVkIFNpZ25hbCwgdGhlIFdhdGNoZXIgaXMgdW5yZWdpc3RlcmVkIGFzIGEgc2luay4gSWYgdGhlXHJcbiAgICogU2lnbmFsJ3Mgc2luayBzZXQgYmVjb21lcyBlbXB0eSBhcyBhIHJlc3VsdCwgdGhlIHJlbW92YWwgaXMgcHJvcGFnYXRlZFxyXG4gICAqIHJlY3Vyc2l2ZWx5IHVwIHRocm91Z2ggaXRzIHNvdXJjZXMsIHRlYXJpbmcgZG93biB0aGUgbGl2ZSBkZXBlbmRlbmN5XHJcbiAgICogY2hhaW4gYW5kIGFsbG93aW5nIGdhcmJhZ2UgY29sbGVjdGlvbiBvZiB1bndhdGNoZWQgbm9kZXMuXHJcbiAgICpcclxuICAgKiBUaGUgYHVud2F0Y2hlZGAgY2FsbGJhY2sgb2YgZWFjaCBTaWduYWwgKGlmIGFueSkgaXMgY2FsbGVkIHdpdGhcclxuICAgKiBgZnJvemVuID0gdHJ1ZWAuXHJcbiAgICpcclxuICAgKiBJZiBubyBTaWduYWxzIHJlbWFpbiBpbiB0aGUgd2F0Y2hlZCBzZXQsIHRoZSBXYXRjaGVyIHRyYW5zaXRpb25zIGJhY2sgdG9cclxuICAgKiB0aGUgYH53YWl0aW5nfmAgc3RhdGUuXHJcbiAgICpcclxuICAgKiBAcGFyYW0gc2lnbmFscyAtIE9uZSBvciBtb3JlIGBTdGF0ZWAgc2lnbmFscyB0byBzdG9wIHdhdGNoaW5nLlxyXG4gICAqIEB0aHJvd3MgSWYgYGZyb3plbmAgaXMgYHRydWVgIGF0IHRoZSB0aW1lIG9mIHRoZSBjYWxsLlxyXG4gICAqIEB0aHJvd3MgSWYgYW55IG9mIHRoZSBnaXZlbiBTaWduYWxzIGlzIG5vdCBjdXJyZW50bHkgYmVpbmcgd2F0Y2hlZC5cclxuICAgKlxyXG4gICAqIEBzZWUgU2lnbmFsIGFsZ29yaXRobXMg4oCUICdNZXRob2Q6IFNpZ25hbC5zdWJ0bGUuV2F0Y2hlci5wcm90b3R5cGUudW53YXRjaCguLi5zaWduYWxzKSdcclxuICAgKi9cclxuICBwdWJsaWMgdW53YXRjaCguLi5zaWduYWxzOiAoU3RhdGUgfCBDb21wdXRlZClbXSkge1xyXG4gICAgaWYgKEdMT0JBTF9TVEFURS5mcm96ZW4pIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgdW53YXRjaCBzaWduYWxzIHdoaWxlIGZyb3plbicpO1xyXG4gICAgfVxyXG5cclxuICAgIHNpZ25hbHMuZm9yRWFjaChzaWduYWwgPT4ge1xyXG4gICAgICBpZiAoIXRoaXMuI3NpZ25hbHMuaGFzKHNpZ25hbCkpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCB1bndhdGNoIGEgc2lnbmFsIHRoYXQgaXMgbm90IGJlaW5nIHdhdGNoZWQnKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy4jc2lnbmFscy5kZWxldGUoc2lnbmFsKVxyXG4gICAgICBzaWduYWwucmVtb3ZlU2luayh0aGlzLCBQUklWQVRFKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGlmICghdGhpcy4jc2lnbmFscy5zaXplKSB7XHJcbiAgICAgIHRoaXMuc2V0U3RhdGUoJ3dhaXRpbmcnLCBQUklWQVRFKVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBXYXRjaGVyLlxyXG4gICAqIEBwYXJhbSBzeW1ib2wgLSBUaGUgcHJpdmF0ZSBzeW1ib2wgZm9yIHByZXZlbnQgZXh0ZXJuYWwgY2FsbHMuXHJcbiAgICovXHJcbiAgcHVibGljIGdldFN0YXRlKHN5bWJvbDogc3ltYm9sKTogV2F0Y2hlclN0YXRlIHtcclxuICAgIGFzc2VydFByaXZhdGVDb250ZXh0KHN5bWJvbCk7XHJcbiAgICByZXR1cm4gdGhpcy4jc3RhdGU7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZXQgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIFdhdGNoZXIuXHJcbiAgICogQHBhcmFtIG5ld1N0YXRlIC0gVGhlIG5ldyBzdGF0ZSB0byBzZXQuXHJcbiAgICogQHBhcmFtIHN5bWJvbCAtIFRoZSBwcml2YXRlIHN5bWJvbCBmb3IgcHJldmVudCBleHRlcm5hbCBjYWxscy5cclxuICAgKiBAdGhyb3dzIElmIHRoZSB0cmFuc2l0aW9uIGZyb20gYHBlbmRpbmdgIHRvIGB3YXRjaGluZ2AgaXMgYXR0ZW1wdGVkLlxyXG4gICAqL1xyXG4gIHB1YmxpYyBzZXRTdGF0ZShuZXdTdGF0ZTogV2F0Y2hlclN0YXRlLCBzeW1ib2w6IHN5bWJvbCk6IHZvaWQge1xyXG4gICAgYXNzZXJ0UHJpdmF0ZUNvbnRleHQoc3ltYm9sKTtcclxuXHJcbiAgICBpZiAodGhpcy4jc3RhdGUgPT09IG5ld1N0YXRlKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXRoaXMuI2lzVmFsaWRUcmFuc2l0aW9uKHRoaXMuI3N0YXRlLCBuZXdTdGF0ZSkpIHtcclxuICAgICAgaWYgKGlzRGV2TW9kZSgpKSB7XHJcbiAgICAgICAgY29uc29sZS53YXJuKGBJbnZhbGlkIHN0YXRlIHRyYW5zaXRpb24gZnJvbSAke3RoaXMuI3N0YXRlfSB0byAke25ld1N0YXRlfSBpbiBXYXRjaGVyYCk7XHJcbiAgICAgICAgY29uc29sZS53YXJuKG5ldyBFcnJvcigpLnN0YWNrKVxyXG4gICAgICB9XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLiNzdGF0ZSA9IG5ld1N0YXRlXHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbnZvY2UgdGhlIG5vdGlmeSBjYWxsYmFjayB3aGVuIGEgd2F0Y2hlZCBkZXBlbmRlbmN5IGNoYW5nZXNcclxuICAgKiBAcGFyYW0gc3ltYm9sIC0gVGhlIHByaXZhdGUgc3ltYm9sIGZvciBwcmV2ZW50IGV4dGVybmFsIGNhbGxzLlxyXG4gICAqL1xyXG4gIHB1YmxpYyBub3RpZnkoc3ltYm9sOiBzeW1ib2wpOiB2b2lkIHtcclxuICAgIGFzc2VydFByaXZhdGVDb250ZXh0KHN5bWJvbCk7XHJcbiAgICBcclxuICAgIEdMT0JBTF9TVEFURS5mcm96ZW4gPSB0cnVlO1xyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIHRoaXMuc2V0U3RhdGUoJ3BlbmRpbmcnLCBQUklWQVRFKVxyXG4gICAgICB0aGlzLiNub3RpZnlDYWxsYmFjay5jYWxsKHRoaXMpO1xyXG4gICAgfSBmaW5hbGx5IHtcclxuICAgICAgdGhpcy5zZXRTdGF0ZSgnd2FpdGluZycsIFBSSVZBVEUpO1xyXG4gICAgICBHTE9CQUxfU1RBVEUuZnJvemVuID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAjaXNWYWxpZFRyYW5zaXRpb24oZnJvbTogV2F0Y2hlclN0YXRlLCB0bzogV2F0Y2hlclN0YXRlKTogYm9vbGVhbiB7XHJcbiAgICBzd2l0Y2ggKGZyb20pIHtcclxuICAgICAgY2FzZSAnd2FpdGluZyc6XHJcbiAgICAgICAgcmV0dXJuIHRvID09PSAnd2F0Y2hpbmcnO1xyXG4gICAgICBjYXNlICd3YXRjaGluZyc6XHJcbiAgICAgICAgcmV0dXJuIHRvID09PSAncGVuZGluZycgfHwgdG8gPT09ICd3YWl0aW5nJztcclxuICAgICAgY2FzZSAncGVuZGluZyc6XHJcbiAgICAgICAgcmV0dXJuIHRvID09PSAnd2FpdGluZyc7XHJcbiAgICB9XHJcbiAgfVxyXG59IiwiaW1wb3J0IHsgR0xPQkFMX1NUQVRFIH0gZnJvbSAnLi91dGlscy9nbG9iYWxzL2dsb2JhbHMnO1xyXG5pbXBvcnQgeyBDb21wdXRlZCB9IGZyb20gJy4vbW9kZWxzL2NvbXB1dGVkL2NvbXB1dGVkJztcclxuaW1wb3J0IHsgU3RhdGUgfSBmcm9tICcuL21vZGVscy9zdGF0ZS9zdGF0ZSc7XHJcbmltcG9ydCB7IFdhdGNoZXIgfSBmcm9tICcuL21vZGVscy93YXRjaGVyL3dhdGNoZXInO1xyXG5pbXBvcnQgeyBQUklWQVRFIH0gZnJvbSAnLi91dGlscy9wcml2YXRlLXN5bWJvbC9wcml2YXRlLXN5bWJvbCc7XHJcblxyXG4vKipcclxuICogRXhlY3V0ZXMgYSBmdW5jdGlvbiB3aXRob3V0IHRyYWNraW5nIGFueSBkZXBlbmRlbmNpZXMuXHJcbiAqIEBwYXJhbSBmbiAtIFRoZSBmdW5jdGlvbiB0byBleGVjdXRlIHdpdGhvdXQgdHJhY2tpbmcuXHJcbiAqIEByZXR1cm5zIFRoZSByZXN1bHQgb2YgdGhlIGZ1bmN0aW9uIGV4ZWN1dGlvbi5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiB1bnRyYWNrPFQ+KGZuOiAoKSA9PiBUKTogVCB7XHJcbiAgY29uc3QgcHJldkNvbXB1dGluZyA9IEdMT0JBTF9TVEFURS5jb21wdXRpbmc7XHJcbiAgR0xPQkFMX1NUQVRFLmNvbXB1dGluZyA9IG51bGw7XHJcblxyXG4gIHRyeSB7XHJcbiAgICByZXR1cm4gZm4oKTtcclxuICB9IGZpbmFsbHkge1xyXG4gICAgR0xPQkFMX1NUQVRFLmNvbXB1dGluZyA9IHByZXZDb21wdXRpbmc7XHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGUgY3VycmVudGx5IGFjdGl2ZSBgQ29tcHV0ZWRgIGluc3RhbmNlIGJlaW5nIGV2YWx1YXRlZCwgb3IgYG51bGxgXHJcbiAqIEByZXR1cm5zIFRoZSBjdXJyZW50bHkgYWN0aXZlIGBDb21wdXRlZGAgaW5zdGFuY2UsIG9yIGBudWxsYCBpZiBub25lIGlzIGJlaW5nIGV2YWx1YXRlZC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBjdXJyZW50Q29tcHV0ZWQoKTogQ29tcHV0ZWQgfCBudWxsIHtcclxuICByZXR1cm4gR0xPQkFMX1NUQVRFLmNvbXB1dGluZztcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIG9yZGVyZWQgbGlzdCBvZiBhbGwgU2lnbmFscyB3aGljaCB0aGUgZ2l2ZW4gYENvbXB1dGVkYCBvclxyXG4gKiBgV2F0Y2hlcmAgcmVmZXJlbmNlZCBkdXJpbmcgaXRzIGxhc3QgZXZhbHVhdGlvbi5cclxuICpcclxuICogLSBGb3IgYSBgQ29tcHV0ZWRgLCB0aGVzZSBhcmUgdGhlIFNpZ25hbHMgcmVhZCBpbnNpZGUgaXRzIGNhbGxiYWNrLlxyXG4gKiAtIEZvciBhIGBXYXRjaGVyYCwgdGhlc2UgYXJlIHRoZSBTaWduYWxzIGl0IGlzIGN1cnJlbnRseSB3YXRjaGluZy5cclxuICpcclxuICogQHBhcmFtIHNpZ25hbCAtIFRoZSBgQ29tcHV0ZWRgIG9yIGBXYXRjaGVyYCB0byBpbnRyb3NwZWN0LlxyXG4gKiBAcmV0dXJucyBBbiBhcnJheSBvZiBgU3RhdGVgIGFuZCBgQ29tcHV0ZWRgIGluc3RhbmNlcy5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBpbnRyb3NwZWN0U291cmNlcyhzaWduYWw6IENvbXB1dGVkIHwgV2F0Y2hlcik6IChTdGF0ZSB8IENvbXB1dGVkKVtdIHtcclxuICByZXR1cm4gc2lnbmFsLmdldFNvdXJjZXMoUFJJVkFURSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBkaXJlY3QgZGVwZW5kZW50cyBvZiB0aGUgZ2l2ZW4gU2lnbmFsIOKAlCBXYXRjaGVycyB0aGF0IGNvbnRhaW5cclxuICogaXQsIHBsdXMgYW55IGBDb21wdXRlZGAgU2lnbmFscyB3aGljaCByZWFkIGl0IGR1cmluZyB0aGVpciBsYXN0IGV2YWx1YXRpb25cclxuICogKGlmIHRoYXQgYENvbXB1dGVkYCBpcyByZWN1cnNpdmVseSB3YXRjaGVkKS5cclxuICpcclxuICogQHBhcmFtIHNpZ25hbCAtIFRoZSBgU3RhdGVgIG9yIGBDb21wdXRlZGAgU2lnbmFsIHRvIGludHJvc3BlY3QuXHJcbiAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGBDb21wdXRlZGAgYW5kIGBXYXRjaGVyYCBpbnN0YW5jZXMuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gaW50cm9zcGVjdFNpbmtzKHNpZ25hbDogU3RhdGUgfCBDb21wdXRlZCk6IChDb21wdXRlZCB8IFdhdGNoZXIpW10ge1xyXG4gIHJldHVybiBzaWduYWwuZ2V0U2lua3MoUFJJVkFURSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZ2l2ZW4gU2lnbmFsIGlzICdsaXZlJyDigJQgaS5lLiBpdCBpcyB3YXRjaGVkIGJ5IGFcclxuICogYFdhdGNoZXJgLCBvciBpdCBpcyByZWFkIGJ5IGEgYENvbXB1dGVkYCBTaWduYWwgd2hpY2ggaXMgKHJlY3Vyc2l2ZWx5KVxyXG4gKiBsaXZlLlxyXG4gKlxyXG4gKiBAcGFyYW0gc2lnbmFsIC0gVGhlIGBTdGF0ZWAgb3IgYENvbXB1dGVkYCBTaWduYWwgdG8gY2hlY2suXHJcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgU2lnbmFsIGhhcyBhdCBsZWFzdCBvbmUgc2luay5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBoYXNTaW5rcyhzaWduYWw6IFN0YXRlIHwgQ29tcHV0ZWQpOiBib29sZWFuIHtcclxuICByZXR1cm4gc2lnbmFsLmdldFNpbmtzKFBSSVZBVEUpLmxlbmd0aCA+IDA7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZ2l2ZW4gbm9kZSBpcyAncmVhY3RpdmUnIOKAlCBpLmUuIGl0IGRlcGVuZHMgb24gc29tZVxyXG4gKiBvdGhlciBTaWduYWwuIEEgYENvbXB1dGVkYCB3aGVyZSBgaGFzU291cmNlc2AgaXMgYGZhbHNlYCB3aWxsIGFsd2F5c1xyXG4gKiByZXR1cm4gdGhlIHNhbWUgY29uc3RhbnQuXHJcbiAqXHJcbiAqIEBwYXJhbSBzaWduYWwgLSBUaGUgYENvbXB1dGVkYCBvciBgV2F0Y2hlcmAgdG8gY2hlY2suXHJcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbm9kZSBoYXMgYXQgbGVhc3Qgb25lIHNvdXJjZS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBoYXNTb3VyY2VzKHNpZ25hbDogQ29tcHV0ZWQgfCBXYXRjaGVyKTogYm9vbGVhbiB7XHJcbiAgcmV0dXJuIHNpZ25hbC5nZXRTb3VyY2VzKFBSSVZBVEUpLmxlbmd0aCA+IDA7XHJcbn0iLCJpbXBvcnQgeyBDb21wdXRlZCB9IGZyb20gJy4vbW9kZWxzL2NvbXB1dGVkL2NvbXB1dGVkJztcclxuaW1wb3J0IHsgU3RhdGUgfSBmcm9tICcuL21vZGVscy9zdGF0ZS9zdGF0ZSc7XHJcbmltcG9ydCB7IFdhdGNoZXIgfSBmcm9tICcuL21vZGVscy93YXRjaGVyL3dhdGNoZXInO1xyXG5pbXBvcnQgeyBjdXJyZW50Q29tcHV0ZWQsIGhhc1NpbmtzLCBoYXNTb3VyY2VzLCBpbnRyb3NwZWN0U2lua3MsIGludHJvc3BlY3RTb3VyY2VzLCB1bnRyYWNrIH0gZnJvbSAnLi9zdWJ0bGUnO1xyXG5pbXBvcnQgeyBzZXREZXZNb2RlIH0gZnJvbSAnLi91dGlscy9kZXYtbW9kZS9kZXYtbW9kZSc7XHJcblxyXG4vKipcclxuICogTG9hZHMgdGhlIFNpZ25hbHMgbGlicmFyeSBieSBkZWZpbmluZyB0aGUgYFNpZ25hbGAgZ2xvYmFsIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczpcclxuICogLSBgU3RhdGVgOiBUaGUgYFN0YXRlYCBjbGFzcyBmb3IgY3JlYXRpbmcgcmVhY3RpdmUgc3RhdGUgdmFyaWFibGVzLlxyXG4gKiAtIGBDb21wdXRlZGA6IFRoZSBgQ29tcHV0ZWRgIGNsYXNzIGZvciBjcmVhdGluZyBkZXJpdmVkIHJlYWN0aXZlIHZhbHVlcy5cclxuICogLSBgV2F0Y2hlcmA6IFRoZSBgV2F0Y2hlcmAgY2xhc3MgZm9yIG9ic2VydmluZyBjaGFuZ2VzIGluIHNpZ25hbHMuXHJcbiAqIC0gYHN1YnRsZWA6IEFuIG9iamVjdCBjb250YWluaW5nIGludGVybmFsIHV0aWxpdHkgZnVuY3Rpb25zIGZvciB3b3JraW5nIHdpdGggc2lnbmFscywgaW5jbHVkaW5nOlxyXG4gKiAgLSBgdW50cmFja2A6IEV4ZWN1dGVzIGEgZnVuY3Rpb24gd2l0aG91dCB0cmFja2luZyBkZXBlbmRlbmNpZXMuXHJcbiAqICAtIGBjdXJyZW50Q29tcHV0ZWRgOiBSZXR1cm5zIHRoZSBjdXJyZW50bHkgYWN0aXZlIGBDb21wdXRlZGAgaW5zdGFuY2UgYmVpbmcgZXZhbHVhdGVkLCBvciBgbnVsbGAgaWYgbm9uZS5cclxuICogIC0gYGludHJvc3BlY3RTb3VyY2VzYDogUmV0dXJucyB0aGUgbGlzdCBvZiBzb3VyY2VzIGZvciBhIGdpdmVuIGBDb21wdXRlZGAgb3IgYFdhdGNoZXJgLlxyXG4gKiAgLSBgaW50cm9zcGVjdFNpbmtzYDogUmV0dXJucyB0aGUgbGlzdCBvZiBzaW5rcyBmb3IgYSBnaXZlbiBgU3RhdGVgIG9yIGBDb21wdXRlZGAuXHJcbiAqICAtIGBoYXNTaW5rc2A6IFJldHVybnMgYHRydWVgIGlmIGEgZ2l2ZW4gYFN0YXRlYCBvciBgQ29tcHV0ZWRgIGhhcyBhdCBsZWFzdCBvbmUgc2luay5cclxuICogIC0gYGhhc1NvdXJjZXNgOiBSZXR1cm5zIGB0cnVlYCBpZiBhIGdpdmVuIGBDb21wdXRlZGAgb3IgYFdhdGNoZXJgIGhhcyBhdCBsZWFzdCBvbmUgc291cmNlLlxyXG4gKiAgLSBgV2F0Y2hlcmA6IFRoZSBgV2F0Y2hlcmAgY2xhc3MgZm9yIG9ic2VydmluZyBjaGFuZ2VzIGluIHNpZ25hbHMuXHJcbiAqIFxyXG4gKiBUaGlzIGZ1bmN0aW9uIHNob3VsZCBiZSBjYWxsZWQgb25jZSB0byBpbml0aWFsaXplIHRoZSBTaWduYWxzIGxpYnJhcnkgYW5kIG1ha2UgaXRzIEFQSSBhdmFpbGFibGUgZ2xvYmFsbHkuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gbG9hZFNpZ25hbHMob3B0aW9ucz86IHsgZGV2TW9kZT86IGJvb2xlYW4gfSk6IHZvaWQge1xyXG4gIHNldERldk1vZGUob3B0aW9ucz8uZGV2TW9kZSA/PyBmYWxzZSlcclxuXHJcbiAgZ2xvYmFsVGhpcy5TaWduYWwgPz89IHtcclxuICAgIFN0YXRlLFxyXG4gICAgQ29tcHV0ZWQsXHJcbiAgICBzdWJ0bGU6IHtcclxuICAgICAgdW50cmFjayxcclxuICAgICAgY3VycmVudENvbXB1dGVkLFxyXG4gICAgICBpbnRyb3NwZWN0U291cmNlczogaW50cm9zcGVjdFNvdXJjZXMgYXMgdW5rbm93biBhcyB0eXBlb2YgU2lnbmFsLnN1YnRsZS5pbnRyb3NwZWN0U291cmNlcyxcclxuICAgICAgaW50cm9zcGVjdFNpbmtzOiBpbnRyb3NwZWN0U2lua3MgYXMgdW5rbm93biBhcyB0eXBlb2YgU2lnbmFsLnN1YnRsZS5pbnRyb3NwZWN0U2lua3MsXHJcbiAgICAgIGhhc1NpbmtzOiBoYXNTaW5rcyBhcyB1bmtub3duIGFzIHR5cGVvZiBTaWduYWwuc3VidGxlLmhhc1NpbmtzLFxyXG4gICAgICBoYXNTb3VyY2VzOiBoYXNTb3VyY2VzIGFzIHVua25vd24gYXMgdHlwZW9mIFNpZ25hbC5zdWJ0bGUuaGFzU291cmNlcyxcclxuICAgICAgV2F0Y2hlclxyXG4gICAgfVxyXG4gIH1cclxufSIsImltcG9ydCB7IE5vQXJnc1ZvaWRGdW5jdGlvbiB9IGZyb20gXCJAeGFlbmRhci90eXBlc1wiO1xyXG5cclxuLyoqXHJcbiAqIFJ1bnMgYSBzaWRlLWVmZmVjdGZ1bCBmdW5jdGlvbiBhbmQgYXV0b21hdGljYWxseSByZS1ydW5zIGl0IHdoZW5ldmVyIGFueVxyXG4gKiBTaWduYWwgcmVhZCBkdXJpbmcgaXRzIGV4ZWN1dGlvbiBjaGFuZ2VzLlxyXG4gKlxyXG4gKiBJbnRlcm5hbGx5LCBgZWZmZWN0YCB3cmFwcyB0aGUgdXNlciBjYWxsYmFjayBpbnNpZGUgYSBgQ29tcHV0ZWRgIG5vZGVcclxuICogKGZvciBkZXBlbmRlbmN5IHRyYWNraW5nKSBhbmQgb2JzZXJ2ZXMgaXQgd2l0aCBhIGBXYXRjaGVyYCAoZm9yIHB1c2hcclxuICogbm90aWZpY2F0aW9ucykuIFdoZW4gYW55IHRyYWNrZWQgZGVwZW5kZW5jeSBjaGFuZ2VzLCB0aGUgYFdhdGNoZXJgXHJcbiAqIHNjaGVkdWxlcyBhIG1pY3JvdGFzayB0aGF0IHJlLWV2YWx1YXRlcyB0aGUgYENvbXB1dGVkYCwgd2hpY2ggaW4gdHVyblxyXG4gKiByZS1ydW5zIHRoZSB1c2VyIGNhbGxiYWNrIGFuZCByZS1yZWdpc3RlcnMgdGhlIG5ldyBzZXQgb2YgZGVwZW5kZW5jaWVzLlxyXG4gKlxyXG4gKiBUaGUgcmV0dXJuZWQgZGlzcG9zZXIgZnVuY3Rpb24gc3RvcHMgdGhlIGVmZmVjdDogaXQgdW53YXRjaGVzIHRoZSBpbnRlcm5hbFxyXG4gKiBgQ29tcHV0ZWRgIGZyb20gdGhlIGBXYXRjaGVyYCwgc2V2ZXJpbmcgYWxsIGRlcGVuZGVuY3kgc3Vic2NyaXB0aW9ucyBzb1xyXG4gKiB0aGUgY2FsbGJhY2sgaXMgbmV2ZXIgY2FsbGVkIGFnYWluIGFuZCB0aGUgZ3JhcGggbm9kZXMgY2FuIGJlXHJcbiAqIGdhcmJhZ2UtY29sbGVjdGVkLlxyXG4gKlxyXG4gKiBAZXhhbXBsZVxyXG4gKiBgYGB0c1xyXG4gKiBjb25zdCBjb3VudCA9IG5ldyBTdGF0ZSgwKTtcclxuICpcclxuICogY29uc3Qgc3RvcCA9IGVmZmVjdCgoKSA9PiB7XHJcbiAqICAgY29uc29sZS5sb2coJ2NvdW50IGlzJywgY291bnQuZ2V0KCkpO1xyXG4gKiB9KTtcclxuICogLy8gbG9nczogXCJjb3VudCBpcyAwXCJcclxuICpcclxuICogY291bnQuc2V0KDEpOyAvLyBsb2dzOiBcImNvdW50IGlzIDFcIlxyXG4gKiBjb3VudC5zZXQoMik7IC8vIGxvZ3M6IFwiY291bnQgaXMgMlwiXHJcbiAqXHJcbiAqIHN0b3AoKTsgICAgICAgLy8gbm8gbW9yZSBsb2dzXHJcbiAqIGNvdW50LnNldCgzKTsgLy8gc2lsZW50XHJcbiAqIGBgYFxyXG4gKlxyXG4gKiBAcGFyYW0gZm4gLSBUaGUgc2lkZS1lZmZlY3RmdWwgZnVuY3Rpb24gdG8gcnVuLiBBbnkgU2lnbmFsIHJlYWQgaW5zaWRlIGl0XHJcbiAqICAgaXMgdHJhY2tlZCBhcyBhIGRlcGVuZGVuY3kuXHJcbiAqIEByZXR1cm5zIEEgZGlzcG9zZXIgZnVuY3Rpb24gdGhhdCwgd2hlbiBjYWxsZWQsIHBlcm1hbmVudGx5IHN0b3BzIHRoZSBlZmZlY3QuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZWZmZWN0KGZuOiBOb0FyZ3NWb2lkRnVuY3Rpb24pOiBOb0FyZ3NWb2lkRnVuY3Rpb24ge1xyXG4gIC8qKlxyXG4gICAqIFdyYXAgdGhlIHVzZXIgY2FsbGJhY2sgaW4gYSBDb21wdXRlZCBzbyB0aGF0IGF1dG9tYXRpYyBkZXBlbmRlbmN5XHJcbiAgICogdHJhY2tpbmcgKHZpYSBwdXNoQ29tcHV0ZWQgLyBwb3BDb21wdXRlZCkgd29ya3MgZm9yIGZyZWUuXHJcbiAgICogVGhlIENvbXB1dGVkIGFsd2F5cyByZXR1cm5zIGB1bmRlZmluZWRgIOKAlCB3ZSBvbmx5IGNhcmUgYWJvdXQgdGhlXHJcbiAgICogc2lkZS1lZmZlY3RzIGFuZCB0aGUgdHJhY2tlZCBzb3VyY2VzLCBub3QgdGhlIHZhbHVlLlxyXG4gICAqL1xyXG4gIGNvbnN0IGNvbXB1dGVkID0gbmV3IFNpZ25hbC5Db21wdXRlZDx2b2lkPigoKSA9PiBmbigpKTtcclxuXHJcbiAgbGV0IG5lZWRzRW5xdWV1ZSA9IHRydWU7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoZSBXYXRjaGVyIGlzIG5vdGlmaWVkIHN5bmNocm9ub3VzbHkgYXMgc29vbiBhcyBhbnkgdHJhY2tlZCBkZXBlbmRlbmN5XHJcbiAgICogY2hhbmdlcy4gSXRzIGpvYiBpcyBwdXJlbHkgdG8gc2NoZWR1bGUgdGhlIHJlLWV4ZWN1dGlvbjsgdGhlIGFjdHVhbFxyXG4gICAqIHJlLWV2YWx1YXRpb24gaGFwcGVucyBhc3luY2hyb25vdXNseSBpbiBhIG1pY3JvdGFzayBzbyB0aGF0IG11bHRpcGxlXHJcbiAgICogc3luY2hyb25vdXMgc2lnbmFsIHVwZGF0ZXMgYXJlIGJhdGNoZWQgaW50byBhIHNpbmdsZSByZS1ydW4uXHJcbiAgICovXHJcbiAgY29uc3Qgd2F0Y2hlciA9IG5ldyBTaWduYWwuc3VidGxlLldhdGNoZXIoKCkgPT4ge1xyXG4gICAgaWYgKG5lZWRzRW5xdWV1ZSkge1xyXG4gICAgICBuZWVkc0VucXVldWUgPSBmYWxzZTtcclxuICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xyXG4gICAgICAgIG5lZWRzRW5xdWV1ZSA9IHRydWU7XHJcbiAgICAgICAgd2F0Y2hlci5nZXRQZW5kaW5nKCkuZm9yRWFjaChjb21wdXRlZCA9PiBjb21wdXRlZC5nZXQoKSk7XHJcbiAgICAgICAgd2F0Y2hlci53YXRjaCgpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgLy8gSW5pdGlhbCBzeW5jaHJvbm91cyBleGVjdXRpb24gKyBmaXJzdCBzdWJzY3JpcHRpb24uXHJcbiAgd2F0Y2hlci53YXRjaChjb21wdXRlZCk7XHJcbiAgY29tcHV0ZWQuZ2V0KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIERpc3Bvc2VyIOKAlCBjYWxsIHRoaXMgdG8gcGVybWFuZW50bHkgc3RvcCB0aGUgZWZmZWN0LlxyXG4gICAqXHJcbiAgICogVW53YXRjaGluZyB0aGUgQ29tcHV0ZWQgdGVhcnMgZG93biB0aGUgZW50aXJlIGxpdmUgZGVwZW5kZW5jeSBjaGFpblxyXG4gICAqIChXYXRjaGVyIOKGkiBDb21wdXRlZCDihpIgYWxsIHNvdXJjZXMpLCBwcmV2ZW50aW5nIGFueSBmdXJ0aGVyXHJcbiAgICogbm90aWZpY2F0aW9ucyBhbmQgYWxsb3dpbmcgR0MuXHJcbiAgICovXHJcbiAgcmV0dXJuICgpID0+IHdhdGNoZXIudW53YXRjaChjb21wdXRlZCk7XHJcbn0iXSwibWFwcGluZ3MiOiI7O0FBV0EsSUFBYSxJ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
1007
+ export { effect, loadSignals };