@anishhs/retryq 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +142 -19
  2. package/dist/cjs/index.d.ts +9 -0
  3. package/dist/cjs/index.d.ts.map +1 -0
  4. package/dist/cjs/index.js +13 -0
  5. package/dist/cjs/index.js.map +1 -0
  6. package/dist/cjs/manager.d.ts +139 -0
  7. package/dist/cjs/manager.d.ts.map +1 -0
  8. package/dist/cjs/manager.js +431 -0
  9. package/dist/cjs/manager.js.map +1 -0
  10. package/dist/cjs/package.json +3 -0
  11. package/dist/cjs/types.d.ts +237 -0
  12. package/dist/cjs/types.d.ts.map +1 -0
  13. package/dist/cjs/types.js +3 -0
  14. package/dist/cjs/types.js.map +1 -0
  15. package/dist/cjs/utils.d.ts +43 -0
  16. package/dist/cjs/utils.d.ts.map +1 -0
  17. package/dist/cjs/utils.js +71 -0
  18. package/dist/cjs/utils.js.map +1 -0
  19. package/dist/cjs/validation.d.ts +37 -0
  20. package/dist/cjs/validation.d.ts.map +1 -0
  21. package/dist/cjs/validation.js +69 -0
  22. package/dist/cjs/validation.js.map +1 -0
  23. package/dist/esm/index.d.ts +9 -0
  24. package/dist/esm/index.d.ts.map +1 -0
  25. package/dist/esm/index.js +8 -0
  26. package/dist/esm/index.js.map +1 -0
  27. package/dist/esm/manager.d.ts +139 -0
  28. package/dist/esm/manager.d.ts.map +1 -0
  29. package/dist/esm/manager.js +427 -0
  30. package/dist/esm/manager.js.map +1 -0
  31. package/dist/esm/package.json +3 -0
  32. package/dist/esm/types.d.ts +237 -0
  33. package/dist/esm/types.d.ts.map +1 -0
  34. package/dist/esm/types.js +2 -0
  35. package/dist/esm/types.js.map +1 -0
  36. package/dist/esm/utils.d.ts +43 -0
  37. package/dist/esm/utils.d.ts.map +1 -0
  38. package/dist/esm/utils.js +64 -0
  39. package/dist/esm/utils.js.map +1 -0
  40. package/dist/esm/validation.d.ts +37 -0
  41. package/dist/esm/validation.d.ts.map +1 -0
  42. package/dist/esm/validation.js +65 -0
  43. package/dist/esm/validation.js.map +1 -0
  44. package/package.json +29 -12
  45. package/dist/index.d.ts +0 -85
  46. package/dist/index.js +0 -293
  47. package/dist/index.js.map +0 -1
package/README.md CHANGED
@@ -10,15 +10,18 @@ A production-ready, zero-dependency retry queue manager for Node.js with support
10
10
 
11
11
  - ✅ **Concurrency control** - Limit concurrent job execution
12
12
  - ✅ **Priority queue** - Higher priority jobs execute first
13
- - ✅ **Exponential backoff** with configurable delay, multiplier, and jitter
13
+ - ✅ **Exponential backoff** with configurable delay, multiplier, `maxDelay`, and jitter
14
+ - ✅ **Lifecycle events & hooks** - `retry`/`success`/`failure`/`cancel`/`idle` events + per-job callbacks
15
+ - ✅ **Conditional retries** - `shouldRetry(error, attempt)` predicate to skip non-retryable errors
14
16
  - ✅ **Force cancellation** - Abort in-progress jobs with AbortController
15
17
  - ✅ **Cooperative cancellation** - Graceful job termination
18
+ - ✅ **Real time limits** - `maxTime` (and `attemptTimeout`) actively abort in-flight attempts
19
+ - ✅ **Queue draining** - `onIdle()` / `drain()` to await all work
16
20
  - ✅ **Memory safe** - Bounded job history with LRU eviction
17
- - ✅ **Time limits** - Global timeout per job with `maxTime`
18
21
  - ✅ **Job introspection** - List, find, and track jobs by ID or label
19
- - ✅ **TypeScript** - Full type safety with bundled declarations
22
+ - ✅ **TypeScript** - Generic, fully-typed API with bundled declarations
23
+ - ✅ **Dual ESM + CJS** - Ships both module formats with an `exports` map
20
24
  - ✅ **Zero dependencies** - Minimal footprint, no external packages
21
- - ✅ **Production tested** - 50+ tests covering all features
22
25
 
23
26
  ## Installation
24
27
 
@@ -268,6 +271,68 @@ retryQ.clearHistory();
268
271
 
269
272
  ---
270
273
 
274
+ #### onIdle() / drain()
275
+
276
+ ```typescript
277
+ onIdle(): Promise<void>
278
+ drain(): Promise<void> // alias
279
+ ```
280
+
281
+ Resolves when the queue is fully idle (no pending **and** no running jobs).
282
+ Resolves immediately if already idle.
283
+
284
+ ```typescript
285
+ for (const item of items) {
286
+ retryQ.createJob(() => process(item), { retries: 3 });
287
+ }
288
+ await retryQ.onIdle(); // wait for the whole batch to settle
289
+ ```
290
+
291
+ ---
292
+
293
+ ### Events
294
+
295
+ `RetryQManager` extends Node's `EventEmitter` and emits typed events:
296
+
297
+ ```typescript
298
+ retryQ.on('retry', ({ job, info }) => console.log(`retry #${info.attempt} in ${info.nextDelay}ms`));
299
+ retryQ.on('success', ({ job, result }) => console.log('done', job.label));
300
+ retryQ.on('failure', ({ job, error }) => console.error('failed', job.label, error));
301
+ retryQ.on('cancel', ({ job }) => console.log('cancelled', job.label));
302
+ retryQ.on('idle', () => console.log('queue drained'));
303
+ ```
304
+
305
+ | Event | Payload | Fired when |
306
+ |-------|---------|-----------|
307
+ | `retry` | `{ job, info: RetryInfo }` | A failed attempt schedules another try |
308
+ | `success` | `{ job, result }` | A job completes successfully |
309
+ | `failure` | `{ job, error }` | A job fails terminally |
310
+ | `cancel` | `{ job }` | A job is cancelled |
311
+ | `idle` | _(none)_ | The queue transitions to fully idle |
312
+
313
+ Prefer per-job feedback? Use the `onRetry` / `onSuccess` / `onFailure` /
314
+ `onCancel` callbacks in `RetryQJobOptions`.
315
+
316
+ ---
317
+
318
+ ### Conditional Retries
319
+
320
+ Skip retries for errors that will never succeed:
321
+
322
+ ```typescript
323
+ retryQ.createJob(async (signal) => {
324
+ const res = await fetch(url, { signal });
325
+ if (!res.ok) throw Object.assign(new Error('HTTP'), { status: res.status });
326
+ return res.json();
327
+ }, {
328
+ retries: 5,
329
+ // Retry 5xx and network errors; give up on 4xx immediately.
330
+ shouldRetry: (err) => !(err?.status >= 400 && err?.status < 500),
331
+ });
332
+ ```
333
+
334
+ ---
335
+
271
336
  ### RetryQJob Interface
272
337
 
273
338
  ```typescript
@@ -525,15 +590,26 @@ process.on('SIGTERM', async () => {
525
590
  ### RetryQJobOptions
526
591
 
527
592
  ```typescript
528
- type RetryQJobOptions = {
529
- retries?: number; // Number of retry attempts (default: 3)
530
- delay?: number; // Initial delay in ms (default: 1000)
531
- backoff?: number; // Delay multiplier (default: 2)
532
- maxTime?: number; // Total time limit in ms (default: 30000)
533
- jitter?: number; // Jitter fraction 0-1 (default: 0.1)
534
- label?: string; // Human-readable identifier (default: job ID)
535
- priority?: number; // Execution priority (default: 1)
536
- signal?: AbortSignal; // External abort signal (optional)
593
+ type RetryQJobOptions<T = unknown> = {
594
+ retries?: number; // Number of retry attempts (default: 3)
595
+ delay?: number; // Initial delay in ms (default: 1000)
596
+ backoff?: number; // Delay multiplier (default: 2)
597
+ maxTime?: number; // Total time limit in ms (default: 30000)
598
+ maxDelay?: number; // Cap for a single backoff delay (default: Infinity)
599
+ attemptTimeout?: number; // Per-attempt timeout in ms (default: Infinity)
600
+ jitter?: number; // Jitter fraction 0-1 (default: 0.1)
601
+ label?: string; // Human-readable identifier (default: job ID)
602
+ priority?: number; // Execution priority (default: 1)
603
+ signal?: AbortSignal; // External abort signal (optional)
604
+
605
+ // Conditional retry: return false to stop retrying immediately
606
+ shouldRetry?: (error: unknown, attempt: number) => boolean;
607
+
608
+ // Per-job lifecycle callbacks
609
+ onRetry?: (info: RetryInfo) => void;
610
+ onSuccess?: (result: T) => void;
611
+ onFailure?: (error: unknown) => void;
612
+ onCancel?: () => void;
537
613
  };
538
614
  ```
539
615
 
@@ -544,7 +620,9 @@ type RetryQJobOptions = {
544
620
  | `retries` | `3` | Number of retry attempts after initial try |
545
621
  | `delay` | `1000` | Initial delay between retries (ms) |
546
622
  | `backoff` | `2` | Multiplier for exponential backoff |
547
- | `maxTime` | `30000` | Total execution time limit (30s) |
623
+ | `maxTime` | `30000` | Total execution time limit (30s), enforced during attempts |
624
+ | `maxDelay` | `Infinity` | Cap for a single backoff delay (ms) |
625
+ | `attemptTimeout` | `Infinity` | Per-attempt timeout (ms) |
548
626
  | `jitter` | `0.1` | Random delay variation (±10%) |
549
627
  | `priority` | `1` | Queue priority (higher = sooner) |
550
628
  | `maxConcurrent` | `Infinity` | Concurrent job limit |
@@ -644,6 +722,19 @@ throw new Error('API request failed');
644
722
 
645
723
  ## Migration Guide
646
724
 
725
+ ### From v1.1.x to v1.2.x
726
+
727
+ **No breaking API changes.** All existing code keeps working; new options,
728
+ callbacks, events, and methods are additive. Two behavior fixes to be aware of:
729
+
730
+ - `listJobs().cancelled` now holds cancelled jobs — they no longer appear under
731
+ `failed`.
732
+ - `maxTime` now actively aborts an in-flight attempt once the budget is
733
+ exhausted (previously it only blocked starting a new attempt).
734
+
735
+ The package now ships **both ESM and CJS** with an `exports` map; `import` and
736
+ `require` both resolve automatically.
737
+
647
738
  ### From v1.0.x to v1.1.x
648
739
 
649
740
  **No breaking changes!** All existing code works.
@@ -763,7 +854,7 @@ async (signal) => {
763
854
  ## FAQ
764
855
 
765
856
  **Q: Is this production-ready?**
766
- A: Yes! Tested with 50+ comprehensive tests. Score: 9.5/10
857
+ A: Yes covered by a `node:test` suite spanning concurrency, cancellation, events, timeouts, and retry semantics.
767
858
 
768
859
  **Q: Does it work with TypeScript?**
769
860
  A: Yes, full TypeScript support with bundled type definitions.
@@ -788,13 +879,43 @@ More examples available at: [github.com/anishhs-gh/retryq-examples](https://gith
788
879
 
789
880
  ---
790
881
 
882
+ ## Development
883
+
884
+ ```bash
885
+ npm install # install dev dependencies
886
+ npm run typecheck # tsc --noEmit
887
+ npm run build # emit dual ESM + CJS into dist/ (with .d.ts)
888
+ npm test # build (pretest) then run node:test suite
889
+ ```
890
+
891
+ The package builds to both module formats:
892
+
893
+ - CommonJS → `dist/cjs` (`require`)
894
+ - ES modules → `dist/esm` (`import`)
895
+
896
+ resolved automatically via the `exports` map in `package.json`.
897
+
898
+ ## CI / Release
899
+
900
+ | Workflow | Trigger | Purpose |
901
+ |----------|---------|---------|
902
+ | **Test** | push/PR to `develop`/`master` | Typecheck, build, and test on Node 16/18/20 |
903
+ | **Audit** | push/PR + weekly | `npm audit` of production dependencies |
904
+ | **Dry-run publish** | push to `develop`, PRs | Gated on Test + Audit; verifies the npm token authenticates and has publish permission, and that `npm publish` would succeed — without publishing |
905
+ | **Publish (manual)** | `workflow_dispatch` | Gated on Test + Audit; publishes to npm and creates a GitHub Release + version tag |
906
+
907
+ Releases are **manual**: bump the version in `package.json`, merge to `master`,
908
+ then run the **Publish** workflow from the Actions tab. Requires an `NPM_TOKEN`
909
+ repository secret with publish access to the `@anishhs` scope.
910
+
791
911
  ## Contributing
792
912
 
793
913
  Contributions welcome! Please:
794
914
  1. Fork the repository
795
- 2. Create a feature branch
796
- 3. Add tests for new features
797
- 4. Submit a pull request
915
+ 2. Create a feature branch (off `develop`)
916
+ 3. Add tests for new features (`tests/*.test.js`, `node:test`)
917
+ 4. Ensure `npm test` passes
918
+ 5. Submit a pull request into `develop`
798
919
 
799
920
  ---
800
921
 
@@ -813,7 +934,9 @@ See [CHANGELOG.md](./CHANGELOG.md) for version history.
813
934
  ## Support
814
935
 
815
936
  - **Issues**: [GitHub Issues](https://github.com/anishhs-gh/retryq/issues)
816
- - **Email**: anishsh701@gmail.com
937
+ - **GitHub**: [anishhs-gh](https://github.com/anishhs-gh)
938
+ - **Website**: [anishhs.com](https://anishhs.com)
939
+ - **LinkedIn**: [linkedin.com/in/anishsh](https://linkedin.com/in/anishsh)
817
940
 
818
941
  ---
819
942
 
@@ -0,0 +1,9 @@
1
+ /**
2
+ * `@anishhs/retryq` — a production-ready, zero-dependency retry queue manager.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ export { RetryQManager } from "./manager.js";
7
+ export { RetryQTimeoutError } from "./utils.js";
8
+ export type { CancelableFunction, CancelEvent, FailureEvent, JobListSnapshot, JobState, JobSummary, RetryEvent, RetryInfo, RetryQEvents, RetryQJob, RetryQJobOptions, RetryQManagerConfig, SuccessEvent, } from "./types.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,YAAY,EACV,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,UAAU,EACV,UAAU,EACV,SAAS,EACT,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACb,MAAM,YAAY,CAAC"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RetryQTimeoutError = exports.RetryQManager = void 0;
4
+ /**
5
+ * `@anishhs/retryq` — a production-ready, zero-dependency retry queue manager.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ var manager_js_1 = require("./manager.js");
10
+ Object.defineProperty(exports, "RetryQManager", { enumerable: true, get: function () { return manager_js_1.RetryQManager; } });
11
+ var utils_js_1 = require("./utils.js");
12
+ Object.defineProperty(exports, "RetryQTimeoutError", { enumerable: true, get: function () { return utils_js_1.RetryQTimeoutError; } });
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,2CAA6C;AAApC,2GAAA,aAAa,OAAA;AACtB,uCAAgD;AAAvC,8GAAA,kBAAkB,OAAA"}
@@ -0,0 +1,139 @@
1
+ import { EventEmitter } from "node:events";
2
+ import type { JobListSnapshot, JobState, RetryQEvents, RetryQJob, RetryQJobOptions, RetryQManagerConfig } from "./types.js";
3
+ /**
4
+ * In-memory retry queue manager with concurrency control, priority scheduling,
5
+ * exponential backoff with jitter, lifecycle events, cooperative/force
6
+ * cancellation, and bounded job history.
7
+ *
8
+ * The manager extends {@link EventEmitter}; subscribe to `retry`, `success`,
9
+ * `failure`, `cancel`, and `idle` events (see {@link RetryQEvents}).
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * const q = new RetryQManager({ maxConcurrent: 3 });
14
+ * q.on("failure", ({ job, error }) => console.error(job.label, error));
15
+ *
16
+ * const job = q.createJob(async (signal) => {
17
+ * const res = await fetch("https://api.example.com", { signal });
18
+ * if (!res.ok) throw new Error(`HTTP ${res.status}`);
19
+ * return res.json();
20
+ * }, { retries: 5, shouldRetry: (e) => !`${e}`.includes("404") });
21
+ *
22
+ * await job.promise;
23
+ * await q.onIdle();
24
+ * ```
25
+ */
26
+ export declare class RetryQManager extends EventEmitter {
27
+ private pendingQueue;
28
+ private runningJobs;
29
+ private failedJobs;
30
+ private completedJobs;
31
+ private cancelledJobs;
32
+ private maxConcurrent;
33
+ private maxHistorySize;
34
+ private registry;
35
+ /** Cleanup callbacks (e.g. external-signal listener removal) keyed by job id. */
36
+ private cleanups;
37
+ /** Resolvers waiting for the queue to become idle. */
38
+ private idleWaiters;
39
+ /** Tracks idle state so the `idle` event only fires on transition. */
40
+ private wasIdle;
41
+ /**
42
+ * @param config - Manager configuration, or a number for `maxConcurrent`
43
+ * (legacy form, kept for backwards compatibility).
44
+ */
45
+ constructor(config?: RetryQManagerConfig | number);
46
+ /** Subscribe to a manager event. See {@link RetryQEvents}. */
47
+ on<E extends keyof RetryQEvents>(event: E, listener: RetryQEvents[E]): this;
48
+ on(event: string | symbol, listener: (...args: any[]) => void): this;
49
+ /** Subscribe to a manager event once. See {@link RetryQEvents}. */
50
+ once<E extends keyof RetryQEvents>(event: E, listener: RetryQEvents[E]): this;
51
+ once(event: string | symbol, listener: (...args: any[]) => void): this;
52
+ /** Remove a previously registered listener. See {@link RetryQEvents}. */
53
+ off<E extends keyof RetryQEvents>(event: E, listener: RetryQEvents[E]): this;
54
+ off(event: string | symbol, listener: (...args: any[]) => void): this;
55
+ /** Emit a manager event. See {@link RetryQEvents}. */
56
+ emit<E extends keyof RetryQEvents>(event: E, ...args: Parameters<RetryQEvents[E]>): boolean;
57
+ emit(event: string | symbol, ...args: any[]): boolean;
58
+ /**
59
+ * Create and immediately enqueue a job.
60
+ *
61
+ * @typeParam T - Resolved value produced by `fn`.
62
+ * @param fn - Async function to run. Receives an {@link AbortSignal} that
63
+ * aborts on force-cancellation or attempt/`maxTime` timeout.
64
+ * @param options - Per-job configuration (see {@link RetryQJobOptions}).
65
+ * @returns The created {@link RetryQJob}. Await `job.promise` for the result.
66
+ * @throws {Error} If any option fails validation.
67
+ */
68
+ createJob<T>(fn: (signal?: AbortSignal) => Promise<T>, options?: RetryQJobOptions<T>): RetryQJob<T>;
69
+ /**
70
+ * Cancel a pending or running job.
71
+ *
72
+ * Cooperative (default) cancellation stops future retries and interrupts the
73
+ * delay between them. Force cancellation additionally aborts the in-flight
74
+ * attempt via its {@link AbortSignal}.
75
+ *
76
+ * @param id - Id of the job to cancel.
77
+ * @param force - When `true`, abort in-progress execution. Defaults to `false`.
78
+ */
79
+ cancelJob(id: string, force?: boolean): void;
80
+ /**
81
+ * Returns a promise that resolves when the queue is fully idle — no pending
82
+ * and no running jobs. Resolves immediately if already idle.
83
+ *
84
+ * @returns A promise that resolves on idle.
85
+ */
86
+ onIdle(): Promise<void>;
87
+ /**
88
+ * Alias for {@link RetryQManager.onIdle}.
89
+ * @returns A promise that resolves when the queue is idle.
90
+ */
91
+ drain(): Promise<void>;
92
+ /**
93
+ * Clear retained job history.
94
+ *
95
+ * @param state - Optional terminal state to clear (`completed`, `failed`, or
96
+ * `cancelled`). When omitted, all history is cleared.
97
+ */
98
+ clearHistory(state?: JobState): void;
99
+ /**
100
+ * Snapshot of all jobs grouped by state.
101
+ * @returns A {@link JobListSnapshot}.
102
+ */
103
+ listJobs(): JobListSnapshot;
104
+ /**
105
+ * Find a job by id across every state.
106
+ * @param id - Job id.
107
+ * @returns The job, or `null` if not found.
108
+ */
109
+ findJobById(id: string): RetryQJob | null;
110
+ /**
111
+ * Find all jobs (across every state) with a matching label.
112
+ * @param label - Label to match.
113
+ * @returns Matching jobs.
114
+ */
115
+ findJobsByLabel(label: string): RetryQJob[];
116
+ /** Evict the oldest entry from a history map when it reaches the size cap. */
117
+ private _evictOldest;
118
+ /** Sort the pending queue by descending priority (stable: FIFO within a tier). */
119
+ private _sortQueue;
120
+ /** Promote pending jobs into running while capacity allows (synchronous). */
121
+ private _processQueue;
122
+ private _isIdle;
123
+ /** Resolve idle waiters and emit `idle` once when the queue drains. */
124
+ private _checkIdle;
125
+ /** Run and remove a job's cleanup callback, if any. */
126
+ private _runCleanup;
127
+ /**
128
+ * Execute a single attempt, bounded by `timeoutMs`. A per-attempt
129
+ * AbortController is linked to the job's controller so force-cancellation
130
+ * still propagates, while a timeout aborts only this attempt (leaving the job
131
+ * free to retry). Uses `Promise.race` so the loop advances even if `fn`
132
+ * ignores the signal.
133
+ */
134
+ private _runAttempt;
135
+ /** Core retry loop for a single job. */
136
+ private _runJob;
137
+ private _jobSummary;
138
+ }
139
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAEV,eAAe,EACf,QAAQ,EAGR,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAIpB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,WAAW,CAA0C;IAC7D,OAAO,CAAC,UAAU,CAA0C;IAC5D,OAAO,CAAC,aAAa,CAA0C;IAC/D,OAAO,CAAC,aAAa,CAA0C;IAC/D,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAA8C;IAC9D,iFAAiF;IACjF,OAAO,CAAC,QAAQ,CAAsC;IACtD,sDAAsD;IACtD,OAAO,CAAC,WAAW,CAAyB;IAC5C,sEAAsE;IACtE,OAAO,CAAC,OAAO,CAAQ;IAEvB;;;OAGG;gBACS,MAAM,GAAE,mBAAmB,GAAG,MAAW;IAgBrD,8DAA8D;IAC9D,EAAE,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI;IAC3E,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI;IAKpE,mEAAmE;IACnE,IAAI,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI;IAC7E,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI;IAKtE,yEAAyE;IACzE,GAAG,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI;IAC5E,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI;IAKrE,sDAAsD;IACtD,IAAI,CAAC,CAAC,SAAS,MAAM,YAAY,EAC/B,KAAK,EAAE,CAAC,EACR,GAAG,IAAI,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GACnC,OAAO;IACV,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO;IASrD;;;;;;;;;OASG;IACH,SAAS,CAAC,CAAC,EACT,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,EACxC,OAAO,GAAE,gBAAgB,CAAC,CAAC,CAAM,GAChC,SAAS,CAAC,CAAC,CAAC;IAsDf;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,GAAE,OAAe,GAAG,IAAI;IA+BnD;;;;;OAKG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAKvB;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB;;;;;OAKG;IACH,YAAY,CAAC,KAAK,CAAC,EAAE,QAAQ,GAAG,IAAI;IAMpC;;;OAGG;IACH,QAAQ,IAAI,eAAe;IAkB3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAWzC;;;;OAIG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE;IAe3C,8EAA8E;IAC9E,OAAO,CAAC,YAAY;IAOpB,kFAAkF;IAClF,OAAO,CAAC,UAAU;IAIlB,6EAA6E;IAC7E,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,OAAO;IAIf,uEAAuE;IACvE,OAAO,CAAC,UAAU;IAalB,uDAAuD;IACvD,OAAO,CAAC,WAAW;IAQnB;;;;;;OAMG;IACH,OAAO,CAAC,WAAW;IAkCnB,wCAAwC;YAC1B,OAAO;IAmHrB,OAAO,CAAC,WAAW;CASpB"}