fastfetch-api-fetch-enhancer 2.0.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 (72) hide show
  1. package/.idea/FastFetch-Smart-API-Fetcher.iml +12 -0
  2. package/.idea/modules.xml +8 -0
  3. package/.idea/vcs.xml +6 -0
  4. package/LICENSE +21 -0
  5. package/README.md +101 -0
  6. package/__tests__/demo.test.ts +216 -0
  7. package/__tests__/test_database.json +5002 -0
  8. package/coverage/clover.xml +463 -0
  9. package/coverage/coverage-final.json +11 -0
  10. package/coverage/lcov-report/base.css +224 -0
  11. package/coverage/lcov-report/block-navigation.js +87 -0
  12. package/coverage/lcov-report/circuit-breaker.ts.html +547 -0
  13. package/coverage/lcov-report/client.ts.html +1858 -0
  14. package/coverage/lcov-report/errors.ts.html +415 -0
  15. package/coverage/lcov-report/fastFetch.ts.html +1045 -0
  16. package/coverage/lcov-report/favicon.png +0 -0
  17. package/coverage/lcov-report/index.html +251 -0
  18. package/coverage/lcov-report/index.ts.html +241 -0
  19. package/coverage/lcov-report/metrics.ts.html +685 -0
  20. package/coverage/lcov-report/middleware.ts.html +403 -0
  21. package/coverage/lcov-report/offline-queue.ts.html +535 -0
  22. package/coverage/lcov-report/prettify.css +1 -0
  23. package/coverage/lcov-report/prettify.js +2 -0
  24. package/coverage/lcov-report/queue.ts.html +421 -0
  25. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  26. package/coverage/lcov-report/sorter.js +196 -0
  27. package/coverage/lcov-report/streaming.ts.html +466 -0
  28. package/coverage/lcov.info +908 -0
  29. package/dist/circuit-breaker.d.ts +61 -0
  30. package/dist/circuit-breaker.d.ts.map +1 -0
  31. package/dist/circuit-breaker.js +106 -0
  32. package/dist/client.d.ts +215 -0
  33. package/dist/client.d.ts.map +1 -0
  34. package/dist/client.js +391 -0
  35. package/dist/errors.d.ts +56 -0
  36. package/dist/errors.d.ts.map +1 -0
  37. package/dist/errors.js +91 -0
  38. package/dist/fastFetch.d.ts +65 -0
  39. package/dist/fastFetch.d.ts.map +1 -0
  40. package/dist/fastFetch.js +209 -0
  41. package/dist/index.d.ts +18 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +18 -0
  44. package/dist/metrics.d.ts +71 -0
  45. package/dist/metrics.d.ts.map +1 -0
  46. package/dist/metrics.js +131 -0
  47. package/dist/middleware.d.ts +66 -0
  48. package/dist/middleware.d.ts.map +1 -0
  49. package/dist/middleware.js +45 -0
  50. package/dist/offline-queue.d.ts +65 -0
  51. package/dist/offline-queue.d.ts.map +1 -0
  52. package/dist/offline-queue.js +120 -0
  53. package/dist/queue.d.ts +33 -0
  54. package/dist/queue.d.ts.map +1 -0
  55. package/dist/queue.js +76 -0
  56. package/dist/streaming.d.ts +40 -0
  57. package/dist/streaming.d.ts.map +1 -0
  58. package/dist/streaming.js +98 -0
  59. package/index.d.ts +167 -0
  60. package/jest.config.js +16 -0
  61. package/package.json +55 -0
  62. package/src/circuit-breaker.ts +154 -0
  63. package/src/client.ts +591 -0
  64. package/src/errors.ts +110 -0
  65. package/src/fastFetch.ts +320 -0
  66. package/src/index.ts +52 -0
  67. package/src/metrics.ts +200 -0
  68. package/src/middleware.ts +106 -0
  69. package/src/offline-queue.ts +150 -0
  70. package/src/queue.ts +112 -0
  71. package/src/streaming.ts +127 -0
  72. package/tsconfig.json +18 -0
@@ -0,0 +1,61 @@
1
+ /**
2
+ * FastFetch Circuit Breaker — Finite State Machine implementation.
3
+ *
4
+ * Prevents cascading failures by "opening" the circuit after a configurable
5
+ * number of consecutive failures, then probing with a single request after
6
+ * the reset timeout before fully re-closing.
7
+ *
8
+ * States:
9
+ * CLOSED — normal operation; every request goes through
10
+ * OPEN — requests are immediately rejected (CircuitOpenError)
11
+ * HALF_OPEN — one probe request is allowed; success → CLOSED, failure → OPEN
12
+ */
13
+ export type CircuitState = "CLOSED" | "OPEN" | "HALF_OPEN";
14
+ export interface CircuitBreakerOptions {
15
+ /**
16
+ * Number of consecutive failures before the circuit opens (default: 5).
17
+ */
18
+ threshold?: number;
19
+ /**
20
+ * Milliseconds to wait in the OPEN state before transitioning to HALF_OPEN
21
+ * and allowing a single probe request (default: 30 000 ms = 30 s).
22
+ */
23
+ timeout?: number;
24
+ /** Called when the circuit transitions CLOSED → OPEN. */
25
+ onOpen?: () => void;
26
+ /** Called when the circuit transitions HALF_OPEN → CLOSED (recovered). */
27
+ onClose?: () => void;
28
+ /** Called when the circuit transitions OPEN → HALF_OPEN (probing). */
29
+ onHalfOpen?: () => void;
30
+ }
31
+ export declare class CircuitBreaker {
32
+ private _state;
33
+ private consecutiveFailures;
34
+ private openedAt;
35
+ private probeInFlight;
36
+ private readonly threshold;
37
+ private readonly timeoutMs;
38
+ private readonly onOpen?;
39
+ private readonly onClose?;
40
+ private readonly onHalfOpen?;
41
+ constructor(options?: CircuitBreakerOptions);
42
+ /**
43
+ * Current circuit state. Reading this property can trigger an automatic
44
+ * OPEN → HALF_OPEN transition when the reset timeout has elapsed.
45
+ */
46
+ get state(): CircuitState;
47
+ /**
48
+ * Execute `fn` through the circuit breaker.
49
+ * - CLOSED → run `fn`, track success/failure
50
+ * - OPEN → throw `CircuitOpenError` immediately (no network call)
51
+ * - HALF_OPEN → allow one probe; success closes, failure re-opens
52
+ */
53
+ execute<T>(fn: () => Promise<T>): Promise<T>;
54
+ private recordSuccess;
55
+ private recordFailure;
56
+ /** Manually reset the circuit to CLOSED. Useful for testing. */
57
+ reset(): void;
58
+ /** Number of consecutive failures recorded since last success. */
59
+ get failures(): number;
60
+ }
61
+ //# sourceMappingURL=circuit-breaker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../src/circuit-breaker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAE3D,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,aAAa,CAAS;IAE9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAa;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAa;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAa;gBAE7B,OAAO,GAAE,qBAA0B;IAU/C;;;OAGG;IACH,IAAI,KAAK,IAAI,YAAY,CAUxB;IAID;;;;;OAKG;IACG,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IA2BlD,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,aAAa;IAuBrB,gEAAgE;IAChE,KAAK,IAAI,IAAI;IAOb,kEAAkE;IAClE,IAAI,QAAQ,IAAI,MAAM,CAErB;CACF"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * FastFetch Circuit Breaker — Finite State Machine implementation.
3
+ *
4
+ * Prevents cascading failures by "opening" the circuit after a configurable
5
+ * number of consecutive failures, then probing with a single request after
6
+ * the reset timeout before fully re-closing.
7
+ *
8
+ * States:
9
+ * CLOSED — normal operation; every request goes through
10
+ * OPEN — requests are immediately rejected (CircuitOpenError)
11
+ * HALF_OPEN — one probe request is allowed; success → CLOSED, failure → OPEN
12
+ */
13
+ import { CircuitOpenError } from "./errors.js";
14
+ export class CircuitBreaker {
15
+ constructor(options = {}) {
16
+ this._state = "CLOSED";
17
+ this.consecutiveFailures = 0;
18
+ this.openedAt = 0;
19
+ this.probeInFlight = false;
20
+ this.threshold = options.threshold ?? 5;
21
+ this.timeoutMs = options.timeout ?? 30000;
22
+ this.onOpen = options.onOpen;
23
+ this.onClose = options.onClose;
24
+ this.onHalfOpen = options.onHalfOpen;
25
+ }
26
+ // ── State accessor ───────────────────────────────────────────────────────
27
+ /**
28
+ * Current circuit state. Reading this property can trigger an automatic
29
+ * OPEN → HALF_OPEN transition when the reset timeout has elapsed.
30
+ */
31
+ get state() {
32
+ if (this._state === "OPEN" &&
33
+ Date.now() - this.openedAt >= this.timeoutMs) {
34
+ this._state = "HALF_OPEN";
35
+ this.probeInFlight = false;
36
+ this.onHalfOpen?.();
37
+ }
38
+ return this._state;
39
+ }
40
+ // ── Core execute ─────────────────────────────────────────────────────────
41
+ /**
42
+ * Execute `fn` through the circuit breaker.
43
+ * - CLOSED → run `fn`, track success/failure
44
+ * - OPEN → throw `CircuitOpenError` immediately (no network call)
45
+ * - HALF_OPEN → allow one probe; success closes, failure re-opens
46
+ */
47
+ async execute(fn) {
48
+ const currentState = this.state; // may trigger OPEN→HALF_OPEN
49
+ if (currentState === "OPEN") {
50
+ throw new CircuitOpenError();
51
+ }
52
+ if (currentState === "HALF_OPEN") {
53
+ // Reject parallel probes — only one probe allowed at a time
54
+ if (this.probeInFlight) {
55
+ throw new CircuitOpenError();
56
+ }
57
+ this.probeInFlight = true;
58
+ }
59
+ try {
60
+ const result = await fn();
61
+ this.recordSuccess();
62
+ return result;
63
+ }
64
+ catch (err) {
65
+ this.recordFailure();
66
+ throw err;
67
+ }
68
+ }
69
+ // ── Private FSM transitions ──────────────────────────────────────────────
70
+ recordSuccess() {
71
+ this.consecutiveFailures = 0;
72
+ this.probeInFlight = false;
73
+ if (this._state === "HALF_OPEN") {
74
+ this._state = "CLOSED";
75
+ this.onClose?.();
76
+ }
77
+ }
78
+ recordFailure() {
79
+ this.consecutiveFailures++;
80
+ this.probeInFlight = false;
81
+ if (this._state === "HALF_OPEN") {
82
+ // Probe failed — re-open the circuit
83
+ this._state = "OPEN";
84
+ this.openedAt = Date.now();
85
+ return;
86
+ }
87
+ if (this._state === "CLOSED" &&
88
+ this.consecutiveFailures >= this.threshold) {
89
+ this._state = "OPEN";
90
+ this.openedAt = Date.now();
91
+ this.onOpen?.();
92
+ }
93
+ }
94
+ // ── Manual controls ──────────────────────────────────────────────────────
95
+ /** Manually reset the circuit to CLOSED. Useful for testing. */
96
+ reset() {
97
+ this._state = "CLOSED";
98
+ this.consecutiveFailures = 0;
99
+ this.openedAt = 0;
100
+ this.probeInFlight = false;
101
+ }
102
+ /** Number of consecutive failures recorded since last success. */
103
+ get failures() {
104
+ return this.consecutiveFailures;
105
+ }
106
+ }
@@ -0,0 +1,215 @@
1
+ /**
2
+ * FastFetch client factory — `createClient()`.
3
+ *
4
+ * Creates a pre-configured `FastFetchClient` instance with:
5
+ * - Base URL + default headers
6
+ * - Request / Response / Error interceptors (v1.x, preserved)
7
+ * - Koa-style middleware pipeline (`api.use()`)
8
+ * - Circuit breaker
9
+ * - Concurrency-limited request queue
10
+ * - Built-in metrics
11
+ * - SSE streaming (`api.stream()`)
12
+ * - Offline request queue
13
+ * - Typed HTTP method helpers (get / post / put / patch / delete / json)
14
+ * - Auto-serialisation of request body (plain objects → JSON)
15
+ */
16
+ import { FastFetchOptions } from "./fastFetch.js";
17
+ import { MetricsCollector } from "./metrics.js";
18
+ import { CircuitBreaker, CircuitBreakerOptions } from "./circuit-breaker.js";
19
+ import { RequestQueue } from "./queue.js";
20
+ import { MiddlewareFn } from "./middleware.js";
21
+ import { SSEHandler } from "./streaming.js";
22
+ export type RequestInterceptor = (url: string, init: RequestInit & FastFetchOptions) => (RequestInit & FastFetchOptions) | Promise<RequestInit & FastFetchOptions>;
23
+ export type ResponseInterceptor = (response: Response) => Response | Promise<Response>;
24
+ export type ErrorInterceptor = (error: unknown) => unknown | Promise<unknown>;
25
+ export interface ClientOptions extends FastFetchOptions {
26
+ /**
27
+ * Base URL prepended to all relative paths.
28
+ * @example `'https://api.example.com/v1'`
29
+ */
30
+ baseURL?: string;
31
+ /**
32
+ * Default headers merged into every request.
33
+ * Per-request headers take precedence.
34
+ */
35
+ headers?: Record<string, string>;
36
+ /**
37
+ * Throw an `HttpError` for non-2xx responses (default: `true`).
38
+ * Set to `false` to receive the raw Response regardless of status.
39
+ */
40
+ throwOnError?: boolean;
41
+ /**
42
+ * Circuit breaker configuration.
43
+ * When provided, the circuit breaker wraps every request.
44
+ */
45
+ circuitBreaker?: CircuitBreakerOptions;
46
+ /**
47
+ * Maximum number of concurrent in-flight requests for this client.
48
+ * Additional requests are queued until a slot becomes free.
49
+ */
50
+ maxConcurrent?: number;
51
+ /**
52
+ * Rolling window size for the built-in metrics collector (default: 1 000).
53
+ */
54
+ metricsWindowSize?: number;
55
+ /**
56
+ * When `true`, mutating requests (POST/PUT/PATCH/DELETE) made while
57
+ * `navigator.onLine === false` are queued and replayed on reconnect.
58
+ * No-op in non-browser environments.
59
+ */
60
+ offlineQueue?: boolean;
61
+ /** v1.x interceptors — still supported. Prefer `use()` for new code. */
62
+ interceptors?: {
63
+ request?: RequestInterceptor[];
64
+ response?: ResponseInterceptor[];
65
+ error?: ErrorInterceptor[];
66
+ };
67
+ }
68
+ export declare class FastFetchClient {
69
+ private readonly baseURL;
70
+ private readonly defaultHeaders;
71
+ private readonly defaultOptions;
72
+ private readonly clientThrowOnError;
73
+ private readonly requestInterceptors;
74
+ private readonly responseInterceptors;
75
+ private readonly errorInterceptors;
76
+ private readonly middlewares;
77
+ private readonly _circuitBreaker?;
78
+ private readonly _queue?;
79
+ private readonly _offlineQueue?;
80
+ private readonly _metrics;
81
+ constructor(options?: ClientOptions);
82
+ /**
83
+ * Register a middleware function.
84
+ *
85
+ * Middleware runs in registration order (Koa onion model):
86
+ * - Code *before* `await next()` executes on the way *down* (pre-request).
87
+ * - Code *after* `await next()` executes on the way *up* (post-response).
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * api.use(async (ctx, next) => {
92
+ * ctx.init.headers['X-Request-Id'] = crypto.randomUUID();
93
+ * const start = Date.now();
94
+ * await next();
95
+ * console.log(`${ctx.method} ${ctx.url} — ${Date.now() - start}ms ${ctx.response?.status}`);
96
+ * });
97
+ * ```
98
+ */
99
+ use(middleware: MiddlewareFn): this;
100
+ /**
101
+ * Built-in metrics collector.
102
+ * Call `.metrics.snapshot()` to get request counts, error rates, and latency percentiles.
103
+ *
104
+ * @example
105
+ * ```ts
106
+ * console.table(api.metrics.snapshot().byEndpoint);
107
+ * ```
108
+ */
109
+ get metrics(): MetricsCollector;
110
+ /**
111
+ * Direct access to the circuit breaker (if configured).
112
+ * Useful for inspecting state or manually resetting in tests.
113
+ */
114
+ get circuitBreaker(): CircuitBreaker | undefined;
115
+ /**
116
+ * Direct access to the concurrency queue (if configured).
117
+ * Useful for observing `pending` / `active` counts.
118
+ */
119
+ get queue(): RequestQueue | undefined;
120
+ private resolveURL;
121
+ private mergeInit;
122
+ /**
123
+ * Auto-serialise the request body.
124
+ * - Plain objects / arrays → JSON string + `Content-Type: application/json`
125
+ * - FormData / URLSearchParams / Blob / ArrayBuffer / string → passed through
126
+ */
127
+ private autoSerializeBody;
128
+ /**
129
+ * Make an HTTP request. Runs the full pipeline:
130
+ * request interceptors → middleware → circuit breaker → queue → fastFetch → response interceptors.
131
+ *
132
+ * Throws `HttpError` on non-2xx by default (disable with `throwOnError: false`).
133
+ */
134
+ fetch(path: string, init?: RequestInit & FastFetchOptions & {
135
+ throwOnError?: boolean;
136
+ }): Promise<Response>;
137
+ /**
138
+ * Fetch and automatically parse the response body as JSON.
139
+ * Returns a typed `Promise<T>`.
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * const user = await api.json<User>('/users/1');
144
+ * const posts = await api.json<Post[]>('/posts?limit=10');
145
+ * ```
146
+ */
147
+ json<T = unknown>(path: string, init?: RequestInit & FastFetchOptions): Promise<T>;
148
+ /**
149
+ * Open a Server-Sent Events stream and call `handler` for each event.
150
+ *
151
+ * The method resolves when the stream ends or the provided `AbortSignal` fires.
152
+ * Automatically sets `Accept: text/event-stream` and `Cache-Control: no-cache`.
153
+ *
154
+ * @example
155
+ * ```ts
156
+ * const ctrl = new AbortController();
157
+ * await api.stream('/api/ai/generate', (event) => {
158
+ * process.stdout.write(event.data);
159
+ * }, { signal: ctrl.signal });
160
+ * ```
161
+ */
162
+ stream(path: string, handler: SSEHandler, init?: RequestInit & FastFetchOptions): Promise<void>;
163
+ /** GET request — returns raw `Response`. Use `.json<T>()` for parsed data. */
164
+ get(path: string, init?: RequestInit & FastFetchOptions): Promise<Response>;
165
+ /**
166
+ * POST request. Body is automatically serialised:
167
+ * - Plain objects / arrays → JSON (+ `Content-Type: application/json`)
168
+ * - FormData / URLSearchParams / string → passed through as-is
169
+ */
170
+ post<B = unknown>(path: string, body?: B, init?: RequestInit & FastFetchOptions): Promise<Response>;
171
+ /**
172
+ * PUT request with auto body serialisation.
173
+ */
174
+ put<B = unknown>(path: string, body?: B, init?: RequestInit & FastFetchOptions): Promise<Response>;
175
+ /**
176
+ * PATCH request with auto body serialisation.
177
+ */
178
+ patch<B = unknown>(path: string, body?: B, init?: RequestInit & FastFetchOptions): Promise<Response>;
179
+ /** DELETE request. */
180
+ delete(path: string, init?: RequestInit & FastFetchOptions): Promise<Response>;
181
+ }
182
+ /**
183
+ * Create a pre-configured `FastFetchClient` instance.
184
+ *
185
+ * @example
186
+ * ```ts
187
+ * import { createClient } from 'fastfetch-api-fetch-enhancer';
188
+ *
189
+ * const api = createClient({
190
+ * baseURL: 'https://api.example.com/v1',
191
+ * headers: { Authorization: `Bearer ${token}` },
192
+ * retries: 3,
193
+ * timeout: 8_000,
194
+ * circuitBreaker: { threshold: 5, timeout: 30_000 },
195
+ * maxConcurrent: 10,
196
+ * offlineQueue: true,
197
+ * });
198
+ *
199
+ * // Register middleware
200
+ * api.use(async (ctx, next) => {
201
+ * ctx.init.headers['X-Request-Id'] = crypto.randomUUID();
202
+ * await next();
203
+ * console.log(`${ctx.method} ${ctx.url} → ${ctx.response?.status} in ${ctx.duration}ms`);
204
+ * });
205
+ *
206
+ * const user = await api.json<User>('/users/1');
207
+ * const posts = await api.json<Post[]>('/posts');
208
+ * await api.post('/users', { name: 'Alice', role: 'admin' }); // auto-JSON
209
+ * await api.stream('/events', (e) => console.log(e.data));
210
+ *
211
+ * console.table(api.metrics.snapshot().byEndpoint);
212
+ * ```
213
+ */
214
+ export declare function createClient(options?: ClientOptions): FastFetchClient;
215
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAa,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EACL,cAAc,EACd,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAiB,MAAM,YAAY,CAAC;AACzD,OAAO,EAGL,YAAY,EACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAc,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAOxD,MAAM,MAAM,kBAAkB,GAAG,CAC/B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,GAAG,gBAAgB,KACjC,CAAC,WAAW,GAAG,gBAAgB,CAAC,GAAG,OAAO,CAAC,WAAW,GAAG,gBAAgB,CAAC,CAAC;AAEhF,MAAM,MAAM,mBAAmB,GAAG,CAChC,QAAQ,EAAE,QAAQ,KACf,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAElC,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAM9E,MAAM,WAAW,aAAc,SAAQ,gBAAgB;IACrD;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,cAAc,CAAC,EAAE,qBAAqB,CAAC;IAEvC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,wEAAwE;IACxE,YAAY,CAAC,EAAE;QACb,OAAO,CAAC,EAAE,kBAAkB,EAAE,CAAC;QAC/B,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;QACjC,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;KAC5B,CAAC;CACH;AAMD,qBAAa,eAAe;IAE1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyB;IACxD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgD;IAC/E,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAU;IAG7C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAuB;IAC3D,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAwB;IAC7D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqB;IAGvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsB;IAClD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAiB;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAe;IAC9C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmB;gBAEhC,OAAO,GAAE,aAAkB;IA2DvC;;;;;;;;;;;;;;;;OAgBG;IACH,GAAG,CAAC,UAAU,EAAE,YAAY,GAAG,IAAI;IAOnC;;;;;;;;OAQG;IACH,IAAI,OAAO,IAAI,gBAAgB,CAE9B;IAID;;;OAGG;IACH,IAAI,cAAc,IAAI,cAAc,GAAG,SAAS,CAE/C;IAID;;;OAGG;IACH,IAAI,KAAK,IAAI,YAAY,GAAG,SAAS,CAEpC;IAID,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,SAAS;IAajB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAyBzB;;;;;OAKG;IACG,KAAK,CACT,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,WAAW,GAAG,gBAAgB,GAAG;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,GACjE,OAAO,CAAC,QAAQ,CAAC;IAyGpB;;;;;;;;;OASG;IACG,IAAI,CAAC,CAAC,GAAG,OAAO,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,WAAW,GAAG,gBAAgB,GACpC,OAAO,CAAC,CAAC,CAAC;IAab;;;;;;;;;;;;;OAaG;IACG,MAAM,CACV,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,UAAU,EACnB,IAAI,CAAC,EAAE,WAAW,GAAG,gBAAgB,GACpC,OAAO,CAAC,IAAI,CAAC;IA0BhB,8EAA8E;IAC9E,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAI3E;;;;OAIG;IACH,IAAI,CAAC,CAAC,GAAG,OAAO,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,CAAC,EACR,IAAI,CAAC,EAAE,WAAW,GAAG,gBAAgB,GACpC,OAAO,CAAC,QAAQ,CAAC;IAWpB;;OAEG;IACH,GAAG,CAAC,CAAC,GAAG,OAAO,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,CAAC,EACR,IAAI,CAAC,EAAE,WAAW,GAAG,gBAAgB,GACpC,OAAO,CAAC,QAAQ,CAAC;IAWpB;;OAEG;IACH,KAAK,CAAC,CAAC,GAAG,OAAO,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,CAAC,EACR,IAAI,CAAC,EAAE,WAAW,GAAG,gBAAgB,GACpC,OAAO,CAAC,QAAQ,CAAC;IAWpB,sBAAsB;IACtB,MAAM,CACJ,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,WAAW,GAAG,gBAAgB,GACpC,OAAO,CAAC,QAAQ,CAAC;CAGrB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,eAAe,CAErE"}