@loggerjs/browser 0.0.2 → 0.1.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.
- package/README.md +69 -57
- package/dist/context-propagation-integration.d.ts +20 -0
- package/dist/context-propagation-integration.d.ts.map +1 -0
- package/dist/framework-router-integrations.d.ts +36 -0
- package/dist/framework-router-integrations.d.ts.map +1 -0
- package/dist/http-transport.d.ts +2 -1
- package/dist/http-transport.d.ts.map +1 -1
- package/dist/index.cjs +363 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +358 -16
- package/dist/index.js.map +1 -1
- package/dist/indexeddb-transport.d.ts +1 -0
- package/dist/indexeddb-transport.d.ts.map +1 -1
- package/dist/offline-first-transport.d.ts +31 -0
- package/dist/offline-first-transport.d.ts.map +1 -0
- package/dist/payload-transforms.d.ts +12 -0
- package/dist/payload-transforms.d.ts.map +1 -0
- package/package.json +22 -2
package/README.md
CHANGED
|
@@ -1,93 +1,105 @@
|
|
|
1
1
|
# @loggerjs/browser
|
|
2
2
|
|
|
3
|
-
Browser transports and integrations
|
|
3
|
+
> Browser transports, offline persistence, and 19 automatic integrations — re-exports all of `@loggerjs/core`.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@loggerjs/browser)
|
|
6
|
+
[](../../LICENSE)
|
|
7
|
+
|
|
8
|
+
The browser platform package for [LoggerJS](../../README.md). It re-exports the entire `@loggerjs/core` API and adds HTTP / IndexedDB / WebSocket / service-worker / broadcast-channel transports, offline queues with replay, ZIP export, and a broad suite of integrations that turn console calls, errors, network failures, Web Vitals, routing, and lifecycle events into structured logs — all opt-in.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @loggerjs/browser @loggerjs/processors
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
4
17
|
|
|
5
18
|
```ts
|
|
6
19
|
import {
|
|
7
20
|
browserHttpTransport,
|
|
8
|
-
browserBroadcastChannelTransport,
|
|
9
|
-
browserServiceWorkerTransport,
|
|
10
|
-
browserWebSocketTransport,
|
|
11
21
|
captureBrowserErrorsIntegration,
|
|
12
22
|
captureConsoleIntegration,
|
|
13
23
|
captureFetchIntegration,
|
|
14
|
-
captureFrameworkErrorsIntegration,
|
|
15
|
-
capturePerformanceIntegration,
|
|
16
|
-
captureReportingIntegration,
|
|
17
|
-
captureRouterIntegration,
|
|
18
|
-
captureRuntimeHostIntegration,
|
|
19
|
-
captureServiceWorkerIntegration,
|
|
20
|
-
captureUserActionsIntegration,
|
|
21
|
-
captureWebSocketIntegration,
|
|
22
24
|
captureWebVitalsIntegration,
|
|
23
25
|
createLogger,
|
|
24
|
-
downloadBlob,
|
|
25
|
-
exportLogsToZip,
|
|
26
|
-
indexedDbBrowserHttpOfflineQueue,
|
|
27
|
-
indexedDbTransport,
|
|
28
26
|
memoryBrowserHttpOfflineQueue,
|
|
29
27
|
pageLifecycleIntegration,
|
|
30
28
|
} from "@loggerjs/browser";
|
|
31
|
-
|
|
32
|
-
const frameworkErrors = captureFrameworkErrorsIntegration({ framework: "react" });
|
|
33
|
-
const localStore = indexedDbTransport({
|
|
34
|
-
durability: "relaxed",
|
|
35
|
-
maxEntries: 50_000,
|
|
36
|
-
storageBucketName: "loggerjs-logs",
|
|
37
|
-
storageBucketDurability: "relaxed",
|
|
38
|
-
ttlMs: 7 * 24 * 60 * 60 * 1000,
|
|
39
|
-
});
|
|
29
|
+
import { redactProcessor } from "@loggerjs/processors";
|
|
40
30
|
|
|
41
31
|
const logger = createLogger({
|
|
42
|
-
|
|
32
|
+
category: ["web"],
|
|
33
|
+
level: "info",
|
|
34
|
+
processors: [redactProcessor()],
|
|
43
35
|
transports: [
|
|
44
36
|
browserHttpTransport({
|
|
45
37
|
url: "/api/logs",
|
|
46
|
-
offlineQueue:
|
|
38
|
+
offlineQueue: memoryBrowserHttpOfflineQueue({ maxEntries: 500 }),
|
|
47
39
|
useBeaconOnPageHide: true,
|
|
48
40
|
}),
|
|
49
|
-
browserBroadcastChannelTransport({ channelName: "loggerjs" }),
|
|
50
|
-
browserServiceWorkerTransport(),
|
|
51
|
-
browserWebSocketTransport({ url: "wss://example.com/logs" }),
|
|
52
|
-
localStore,
|
|
53
41
|
],
|
|
54
42
|
integrations: [
|
|
55
43
|
captureConsoleIntegration({ levels: ["warn", "error"] }),
|
|
56
44
|
captureBrowserErrorsIntegration(),
|
|
57
45
|
captureFetchIntegration(),
|
|
58
|
-
frameworkErrors,
|
|
59
|
-
captureReportingIntegration(),
|
|
60
|
-
captureRouterIntegration(),
|
|
61
|
-
captureRuntimeHostIntegration({ electronChannels: ["main:error"] }),
|
|
62
|
-
captureServiceWorkerIntegration(),
|
|
63
|
-
captureUserActionsIntegration(),
|
|
64
|
-
captureWebSocketIntegration(),
|
|
65
46
|
captureWebVitalsIntegration(),
|
|
66
|
-
capturePerformanceIntegration({ entryTypes: ["navigation", "resource", "longtask"] }),
|
|
67
47
|
pageLifecycleIntegration(),
|
|
68
48
|
],
|
|
69
49
|
});
|
|
70
50
|
|
|
71
51
|
logger.info("page loaded");
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Logs batch over HTTP, queue while offline, replay with backoff when the network returns, and flush via `sendBeacon` when the tab closes.
|
|
55
|
+
|
|
56
|
+
## Transports
|
|
57
|
+
|
|
58
|
+
| Transport | Delivers to |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| `browserHttpTransport` | your collector — batching, offline queue, online replay with backoff, `sendBeacon` on page hide |
|
|
61
|
+
| `indexedDbTransport` | a local, queryable IndexedDB store (TTL, pruning, optional Storage Buckets and durability hints) |
|
|
62
|
+
| `browserWebSocketTransport` | a WebSocket (codec-encoded batches, queues while closed) |
|
|
63
|
+
| `browserServiceWorkerTransport` | a service worker for centralized delivery |
|
|
64
|
+
| `browserBroadcastChannelTransport` | other tabs via `BroadcastChannel` |
|
|
65
|
+
| `offlineFirstTransport` | a local store first, then forwards online |
|
|
72
66
|
|
|
73
|
-
|
|
74
|
-
downloadBlob(zip, "loggerjs-logs.zip");
|
|
67
|
+
### Offline queues & export
|
|
75
68
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
69
|
+
- `memoryBrowserHttpOfflineQueue()` — short-lived in-memory retry buffer.
|
|
70
|
+
- `indexedDbBrowserHttpOfflineQueue()` — survives page reloads.
|
|
71
|
+
- `exportLogsToZip()` + `downloadBlob()` — export a persisted store as a zip containing `logs.ndjson` and `manifest.json`.
|
|
72
|
+
- Call the `indexedDbTransport()` instance's `stats()` to read flush, prune, query, drop, and buffer-depth counters.
|
|
73
|
+
|
|
74
|
+
## Integrations (19)
|
|
75
|
+
|
|
76
|
+
| Group | Integrations |
|
|
77
|
+
| --- | --- |
|
|
78
|
+
| **Console & errors** | `captureConsoleIntegration`, `captureBrowserErrorsIntegration`, `captureFrameworkErrorsIntegration`, `captureReportingIntegration` |
|
|
79
|
+
| **Network** | `captureFetchIntegration`, `captureXHRIntegration`, `captureWebSocketIntegration` |
|
|
80
|
+
| **Performance** | `captureWebVitalsIntegration`, `capturePerformanceIntegration` |
|
|
81
|
+
| **Navigation** | `captureRouterIntegration`, `nextRouterIntegration`, `reactRouterIntegration`, `vueRouterIntegration`, `nuxtRouterIntegration` |
|
|
82
|
+
| **Lifecycle & context** | `pageLifecycleIntegration`, `captureUserActionsIntegration`, `captureServiceWorkerIntegration`, `captureRuntimeHostIntegration`, `browserContextPropagationIntegration` |
|
|
83
|
+
|
|
84
|
+
Integrations patch through an unpatched-original registry and a re-entrancy guard, so the console transport never loops back through console capture. Framework error hooks expose `reactComponentDidCatch()`, `vueErrorHandler()`, etc.:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
const frameworkErrors = captureFrameworkErrorsIntegration({ framework: "react" });
|
|
88
|
+
// In a React ErrorBoundary:
|
|
89
|
+
// componentDidCatch(error, info) { frameworkErrors.reactComponentDidCatch(error, info); }
|
|
79
90
|
```
|
|
80
91
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
## Subpath exports
|
|
93
|
+
|
|
94
|
+
Transports — `transport-http` · `transport-indexeddb` · `transport-websocket` · `transport-service-worker` · `transport-broadcast-channel` · `offline-first-transport` · `offline-indexeddb` · `export-zip` · `payload-transforms`
|
|
95
|
+
|
|
96
|
+
Integrations — `integration-console` · `integration-errors` · `integration-framework-errors` · `integration-reporting` · `integration-fetch` · `integration-xhr` · `integration-websocket` · `integration-web-vitals` · `integration-performance` · `integration-router` · `integration-framework-routers` · `integration-page-lifecycle` · `integration-user-actions` · `integration-service-worker` · `integration-runtime-host` · `integration-context`
|
|
97
|
+
|
|
98
|
+
## Documentation
|
|
99
|
+
|
|
100
|
+
- [Transports](../../docs/TRANSPORTS.md) · [Integrations](../../docs/INTEGRATIONS.md) · [Operations](../../docs/OPERATIONS.md)
|
|
101
|
+
- [Getting Started](../../docs/GETTING-STARTED.md) · [LoggerJS root README](../../README.md)
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
[MIT](../../LICENSE) © JS Kits
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Baggage, type Integration, type TraceContext } from "@loggerjs/core";
|
|
2
|
+
export type BrowserContextActionEventName = "change" | "click" | "input" | "keydown" | "submit";
|
|
3
|
+
export interface BrowserContextEventTargetLike {
|
|
4
|
+
addEventListener: typeof globalThis.addEventListener;
|
|
5
|
+
removeEventListener: typeof globalThis.removeEventListener;
|
|
6
|
+
}
|
|
7
|
+
export interface BrowserContextPropagationOptions {
|
|
8
|
+
sessionId?: string | (() => string | undefined);
|
|
9
|
+
requestId?: () => string | undefined;
|
|
10
|
+
trace?: TraceContext | (() => TraceContext | undefined);
|
|
11
|
+
traceparent?: string | (() => string | undefined);
|
|
12
|
+
baggage?: Baggage | string | (() => Baggage | string | undefined);
|
|
13
|
+
actionEvents?: readonly BrowserContextActionEventName[];
|
|
14
|
+
actionTtlMs?: number;
|
|
15
|
+
root?: BrowserContextEventTargetLike;
|
|
16
|
+
clock?: () => number;
|
|
17
|
+
idFactory?: () => string;
|
|
18
|
+
}
|
|
19
|
+
export declare function browserContextPropagationIntegration(options?: BrowserContextPropagationOptions): Integration;
|
|
20
|
+
//# sourceMappingURL=context-propagation-integration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-propagation-integration.d.ts","sourceRoot":"","sources":["../src/context-propagation-integration.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,6BAA6B,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEhG,MAAM,WAAW,6BAA6B;IAC5C,gBAAgB,EAAE,OAAO,UAAU,CAAC,gBAAgB,CAAC;IACrD,mBAAmB,EAAE,OAAO,UAAU,CAAC,mBAAmB,CAAC;CAC5D;AAED,MAAM,WAAW,gCAAgC;IAC/C,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC;IAChD,SAAS,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACrC,KAAK,CAAC,EAAE,YAAY,GAAG,CAAC,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC;IACxD,WAAW,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC;IAClD,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;IAClE,YAAY,CAAC,EAAE,SAAS,6BAA6B,EAAE,CAAC;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,6BAA6B,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,MAAM,CAAC;CAC1B;AAgCD,wBAAgB,oCAAoC,CAClD,OAAO,GAAE,gCAAqC,GAC7C,WAAW,CAiEb"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type Integration, type LoggerLevel } from "@loggerjs/core";
|
|
2
|
+
export interface FrameworkRouterIntegrationOptions {
|
|
3
|
+
level?: LoggerLevel;
|
|
4
|
+
sanitizeUrl?: (url: string) => string;
|
|
5
|
+
includeState?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface NextRouterLike {
|
|
8
|
+
asPath?: string;
|
|
9
|
+
events?: {
|
|
10
|
+
on?: (event: string, listener: (url: string) => void) => void;
|
|
11
|
+
off?: (event: string, listener: (url: string) => void) => void;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export interface ReactRouterHistoryLike {
|
|
15
|
+
location?: unknown;
|
|
16
|
+
listen?: (listener: (update: unknown) => void) => void | (() => void);
|
|
17
|
+
}
|
|
18
|
+
export interface VueRouterLike {
|
|
19
|
+
currentRoute?: unknown;
|
|
20
|
+
afterEach?: (listener: (to: unknown, from: unknown) => void) => void | (() => void);
|
|
21
|
+
}
|
|
22
|
+
export interface NextRouterIntegrationOptions extends FrameworkRouterIntegrationOptions {
|
|
23
|
+
router: NextRouterLike;
|
|
24
|
+
}
|
|
25
|
+
export interface ReactRouterIntegrationOptions extends FrameworkRouterIntegrationOptions {
|
|
26
|
+
history: ReactRouterHistoryLike;
|
|
27
|
+
}
|
|
28
|
+
export interface VueRouterIntegrationOptions extends FrameworkRouterIntegrationOptions {
|
|
29
|
+
router: VueRouterLike;
|
|
30
|
+
framework?: "vue-router" | "nuxt";
|
|
31
|
+
}
|
|
32
|
+
export declare function nextRouterIntegration(options: NextRouterIntegrationOptions): Integration;
|
|
33
|
+
export declare function reactRouterIntegration(options: ReactRouterIntegrationOptions): Integration;
|
|
34
|
+
export declare function vueRouterIntegration(options: VueRouterIntegrationOptions): Integration;
|
|
35
|
+
export declare function nuxtRouterIntegration(options: Omit<VueRouterIntegrationOptions, "framework">): Integration;
|
|
36
|
+
//# sourceMappingURL=framework-router-integrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-router-integrations.d.ts","sourceRoot":"","sources":["../src/framework-router-integrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAEhB,KAAK,WAAW,EACjB,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,iCAAiC;IAChD,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE;QACP,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;QAC9D,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;KAChE,CAAC;CACH;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;CACrF;AAED,MAAM,WAAW,4BAA6B,SAAQ,iCAAiC;IACrF,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,6BAA8B,SAAQ,iCAAiC;IACtF,OAAO,EAAE,sBAAsB,CAAC;CACjC;AAED,MAAM,WAAW,2BAA4B,SAAQ,iCAAiC;IACpF,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;CACnC;AAgDD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,WAAW,CAkBxF;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,6BAA6B,GAAG,WAAW,CAgB1F;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,WAAW,CActF;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,IAAI,CAAC,2BAA2B,EAAE,WAAW,CAAC,GACtD,WAAW,CAEb"}
|
package/dist/http-transport.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Codec, type LogEvent, type LoggerLevel, type Transport } from "@loggerjs/core";
|
|
1
|
+
import { type Codec, type LogEvent, type LoggerLevel, type PayloadTransform, type Transport } from "@loggerjs/core";
|
|
2
2
|
export type BrowserHttpDropPolicy = "drop-oldest" | "drop-newest";
|
|
3
3
|
export interface BrowserHttpOfflineEntry {
|
|
4
4
|
id: string;
|
|
@@ -40,6 +40,7 @@ export interface BrowserHttpTransportOptions {
|
|
|
40
40
|
offlineReplayMaxDelayMs?: number;
|
|
41
41
|
random?: () => number;
|
|
42
42
|
fetchFn?: typeof fetch;
|
|
43
|
+
transformPayload?: PayloadTransform | readonly PayloadTransform[];
|
|
43
44
|
onDrop?: (event: LogEvent, reason: string) => void;
|
|
44
45
|
}
|
|
45
46
|
export declare function memoryBrowserHttpOfflineQueue(options?: MemoryBrowserHttpOfflineQueueOptions): BrowserHttpOfflineQueue & {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-transport.d.ts","sourceRoot":"","sources":["../src/http-transport.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"http-transport.d.ts","sourceRoot":"","sources":["../src/http-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,KAAK,EAEV,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,SAAS,EAEf,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,aAAa,CAAC;AAOlE,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;IAC1B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3F;AAED,MAAM,WAAW,oCAAoC;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACnE;AAED,MAAM,WAAW,2BAA2B;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,uBAAuB,CAAC;IACvC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,SAAS,gBAAgB,EAAE,CAAC;IAClE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,GAAE,oCAAyC,GACjD,uBAAuB,GAAG;IAAE,IAAI,EAAE,MAAM,MAAM,CAAA;CAAE,CAoClD;AAiCD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,SAAS,CAqSpF"}
|