@flamingo-stack/openframe-frontend-core 0.0.498 → 0.0.499-snapshot.20260730180712
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/dist/{chunk-MSB3PEPP.cjs → chunk-4NDGD2YH.cjs} +19 -19
- package/dist/{chunk-MSB3PEPP.cjs.map → chunk-4NDGD2YH.cjs.map} +1 -1
- package/dist/{chunk-VOOEX4IZ.js → chunk-5CY6YKWY.js} +6 -6
- package/dist/{chunk-XSNKSMB3.js → chunk-6TJJFQ74.js} +6 -6
- package/dist/{chunk-TTYJAZ7P.cjs → chunk-C5R2OX7A.cjs} +9 -4
- package/dist/chunk-C5R2OX7A.cjs.map +1 -0
- package/dist/{chunk-ZBTIN7RC.cjs → chunk-ETU6VFOL.cjs} +40 -40
- package/dist/{chunk-ZBTIN7RC.cjs.map → chunk-ETU6VFOL.cjs.map} +1 -1
- package/dist/{chunk-ZTE32A7C.cjs → chunk-GDUWGCPP.cjs} +12 -12
- package/dist/{chunk-ZTE32A7C.cjs.map → chunk-GDUWGCPP.cjs.map} +1 -1
- package/dist/{chunk-P47NN7RY.js → chunk-GSONSIWG.js} +28 -3
- package/dist/chunk-GSONSIWG.js.map +1 -0
- package/dist/{chunk-THC3K262.cjs → chunk-I64ZGPA6.cjs} +3 -3
- package/dist/{chunk-THC3K262.cjs.map → chunk-I64ZGPA6.cjs.map} +1 -1
- package/dist/{chunk-4NIBKEED.cjs → chunk-IDRKW6MS.cjs} +12 -12
- package/dist/{chunk-4NIBKEED.cjs.map → chunk-IDRKW6MS.cjs.map} +1 -1
- package/dist/{chunk-W24U7ZUV.cjs → chunk-KQKU4VXB.cjs} +40 -15
- package/dist/chunk-KQKU4VXB.cjs.map +1 -0
- package/dist/{chunk-SGL6URIJ.cjs → chunk-L5CI57RM.cjs} +9 -5
- package/dist/chunk-L5CI57RM.cjs.map +1 -0
- package/dist/{chunk-4EHQEMN4.cjs → chunk-LN2X4XAB.cjs} +18 -18
- package/dist/{chunk-4EHQEMN4.cjs.map → chunk-LN2X4XAB.cjs.map} +1 -1
- package/dist/{chunk-VLWVM6ZS.js → chunk-P3B65FBX.js} +4 -4
- package/dist/{chunk-2OPD6KRB.js → chunk-P5UMIPKR.js} +5 -5
- package/dist/{chunk-WEUNPE3S.js → chunk-P7IOCYGD.js} +53 -48
- package/dist/chunk-P7IOCYGD.js.map +1 -0
- package/dist/{chunk-ZEZTITQZ.cjs → chunk-PAO45LBQ.cjs} +1162 -931
- package/dist/chunk-PAO45LBQ.cjs.map +1 -0
- package/dist/{chunk-G6ARA2HD.js → chunk-QQAKDJPE.js} +3 -3
- package/dist/{chunk-KK4M4URN.js → chunk-R2IGOYHU.js} +3 -3
- package/dist/{chunk-A3Z63ZL5.cjs → chunk-S3COVC7H.cjs} +73 -73
- package/dist/{chunk-A3Z63ZL5.cjs.map → chunk-S3COVC7H.cjs.map} +1 -1
- package/dist/{chunk-OYPUQJJ2.js → chunk-SOX7CGFX.js} +342 -111
- package/dist/{chunk-OYPUQJJ2.js.map → chunk-SOX7CGFX.js.map} +1 -1
- package/dist/{chunk-T67MZAQJ.cjs → chunk-TJCUGL7S.cjs} +33 -33
- package/dist/{chunk-T67MZAQJ.cjs.map → chunk-TJCUGL7S.cjs.map} +1 -1
- package/dist/{chunk-K5HHLTSG.js → chunk-UM2YFCPE.js} +3 -3
- package/dist/{chunk-MVORKLWX.cjs → chunk-V5ALIJZ6.cjs} +32 -32
- package/dist/{chunk-MVORKLWX.cjs.map → chunk-V5ALIJZ6.cjs.map} +1 -1
- package/dist/{chunk-2R25CGSO.cjs → chunk-VLI6ESJN.cjs} +93 -93
- package/dist/{chunk-2R25CGSO.cjs.map → chunk-VLI6ESJN.cjs.map} +1 -1
- package/dist/{chunk-MF3VJKHT.js → chunk-VMDQDD5Y.js} +2 -2
- package/dist/{chunk-6WTCJI5R.js → chunk-VPQBQJ4S.js} +2 -2
- package/dist/{chunk-5ZL7PA63.js → chunk-W6Y66G4K.js} +3 -3
- package/dist/{chunk-QKWOBV55.js → chunk-WHJGRRK2.js} +9 -5
- package/dist/chunk-WHJGRRK2.js.map +1 -0
- package/dist/{chunk-6GAJETAP.js → chunk-XBLRT3MX.js} +4 -4
- package/dist/{chunk-ZHNWWFIM.cjs → chunk-YSN2AZJR.cjs} +5 -5
- package/dist/{chunk-ZHNWWFIM.cjs.map → chunk-YSN2AZJR.cjs.map} +1 -1
- package/dist/{chunk-XI44QDCD.cjs → chunk-ZLJCE75C.cjs} +40 -40
- package/dist/{chunk-XI44QDCD.cjs.map → chunk-ZLJCE75C.cjs.map} +1 -1
- package/dist/{chunk-W4XZ3FBZ.js → chunk-ZU27I5NZ.js} +6 -6
- package/dist/components/case-studies/index.cjs +11 -11
- package/dist/components/case-studies/index.js +5 -5
- package/dist/components/chat/hooks/use-jetstream-dialog-subscription.d.ts +5 -2
- package/dist/components/chat/hooks/use-jetstream-dialog-subscription.d.ts.map +1 -1
- package/dist/components/chat/index.cjs +5 -5
- package/dist/components/chat/index.js +4 -4
- package/dist/components/chat/types/api.types.d.ts +9 -2
- package/dist/components/chat/types/api.types.d.ts.map +1 -1
- package/dist/components/contact/index.cjs +6 -6
- package/dist/components/contact/index.js +5 -5
- package/dist/components/docs/index.cjs +8 -8
- package/dist/components/docs/index.js +7 -7
- package/dist/components/embeds/index.cjs +6 -6
- package/dist/components/embeds/index.js +5 -5
- package/dist/components/faq/index.cjs +7 -7
- package/dist/components/faq/index.js +6 -6
- package/dist/components/features/filters-dropdown.d.ts.map +1 -1
- package/dist/components/features/index.cjs +5 -5
- package/dist/components/features/index.js +4 -4
- package/dist/components/help-center-pages/index.cjs +24 -24
- package/dist/components/help-center-pages/index.js +15 -15
- package/dist/components/index.cjs +166 -162
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +17 -13
- package/dist/components/index.js.map +1 -1
- package/dist/components/navigation/app-header.d.ts +48 -0
- package/dist/components/navigation/app-header.d.ts.map +1 -1
- package/dist/components/navigation/header-mingo-button.d.ts.map +1 -1
- package/dist/components/navigation/index.cjs +7 -5
- package/dist/components/navigation/index.cjs.map +1 -1
- package/dist/components/navigation/index.d.ts +2 -2
- package/dist/components/navigation/index.d.ts.map +1 -1
- package/dist/components/navigation/index.js +6 -4
- package/dist/components/navigation/navigation-sidebar-item.d.ts +14 -0
- package/dist/components/navigation/navigation-sidebar-item.d.ts.map +1 -1
- package/dist/components/navigation/navigation-sidebar-toggle.d.ts.map +1 -1
- package/dist/components/navigation/navigation-sidebar.d.ts +18 -0
- package/dist/components/navigation/navigation-sidebar.d.ts.map +1 -1
- package/dist/components/onboarding-guides/index.cjs +9 -9
- package/dist/components/onboarding-guides/index.js +8 -8
- package/dist/components/related-content/index.cjs +7 -7
- package/dist/components/related-content/index.js +6 -6
- package/dist/components/tickets/index.cjs +8 -8
- package/dist/components/tickets/index.js +7 -7
- package/dist/components/ui/button/button-styles.d.ts +1 -0
- package/dist/components/ui/button/button-styles.d.ts.map +1 -1
- package/dist/components/ui/button/button.d.ts.map +1 -1
- package/dist/components/ui/data-table/data-table-body.d.ts.map +1 -1
- package/dist/components/ui/data-table/data-table-column-filter.d.ts.map +1 -1
- package/dist/components/ui/data-table/data-table-header.d.ts.map +1 -1
- package/dist/components/ui/data-table/data-table-row.d.ts.map +1 -1
- package/dist/components/ui/data-table/data-table-skeleton.d.ts +12 -0
- package/dist/components/ui/data-table/data-table-skeleton.d.ts.map +1 -1
- package/dist/components/ui/data-table/index.d.ts +1 -1
- package/dist/components/ui/data-table/index.d.ts.map +1 -1
- package/dist/components/ui/data-table/utils.d.ts +18 -0
- package/dist/components/ui/data-table/utils.d.ts.map +1 -1
- package/dist/components/ui/file-manager/index.cjs +50 -50
- package/dist/components/ui/file-manager/index.js +1 -1
- package/dist/components/ui/index.cjs +7 -5
- package/dist/components/ui/index.cjs.map +1 -1
- package/dist/components/ui/index.js +6 -4
- package/dist/hooks/index.cjs +5 -3
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.js +4 -2
- package/dist/hooks/ui/index.d.ts +1 -0
- package/dist/hooks/ui/index.d.ts.map +1 -1
- package/dist/hooks/ui/use-isomorphic-layout-effect.d.ts +17 -0
- package/dist/hooks/ui/use-isomorphic-layout-effect.d.ts.map +1 -0
- package/dist/index.cjs +11 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +10 -4
- package/dist/nats/index.cjs +2 -2
- package/dist/nats/index.js +1 -1
- package/dist/nats/nats.d.ts +18 -1
- package/dist/nats/nats.d.ts.map +1 -1
- package/dist/types/navigation.d.ts +24 -0
- package/dist/types/navigation.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/chat/hooks/.use-jetstream-dialog-subscription.md +7 -3
- package/src/components/chat/hooks/use-jetstream-dialog-subscription.ts +77 -5
- package/src/components/chat/types/api.types.ts +9 -2
- package/src/components/features/filters-dropdown.tsx +17 -5
- package/src/components/navigation/app-header.tsx +178 -0
- package/src/components/navigation/header-mingo-button.tsx +5 -0
- package/src/components/navigation/index.ts +2 -2
- package/src/components/navigation/navigation-sidebar-item.tsx +22 -0
- package/src/components/navigation/navigation-sidebar-toggle.tsx +10 -6
- package/src/components/navigation/navigation-sidebar.tsx +187 -44
- package/src/components/ui/button/button-styles.ts +11 -0
- package/src/components/ui/button/button.tsx +6 -3
- package/src/components/ui/button/split-button.tsx +2 -2
- package/src/components/ui/data-table/data-table-body.tsx +5 -2
- package/src/components/ui/data-table/data-table-column-filter.tsx +54 -25
- package/src/components/ui/data-table/data-table-header.tsx +134 -45
- package/src/components/ui/data-table/data-table-row.tsx +3 -2
- package/src/components/ui/data-table/data-table-skeleton.tsx +17 -2
- package/src/components/ui/data-table/index.ts +1 -1
- package/src/components/ui/data-table/utils.ts +49 -3
- package/src/hooks/ui/index.ts +1 -0
- package/src/hooks/ui/use-isomorphic-layout-effect.ts +20 -0
- package/src/nats/.nats.md +2 -2
- package/src/nats/nats.ts +70 -5
- package/src/types/navigation.ts +21 -0
- package/dist/chunk-P47NN7RY.js.map +0 -1
- package/dist/chunk-QKWOBV55.js.map +0 -1
- package/dist/chunk-SGL6URIJ.cjs.map +0 -1
- package/dist/chunk-TTYJAZ7P.cjs.map +0 -1
- package/dist/chunk-W24U7ZUV.cjs.map +0 -1
- package/dist/chunk-WEUNPE3S.js.map +0 -1
- package/dist/chunk-ZEZTITQZ.cjs.map +0 -1
- /package/dist/{chunk-VOOEX4IZ.js.map → chunk-5CY6YKWY.js.map} +0 -0
- /package/dist/{chunk-XSNKSMB3.js.map → chunk-6TJJFQ74.js.map} +0 -0
- /package/dist/{chunk-VLWVM6ZS.js.map → chunk-P3B65FBX.js.map} +0 -0
- /package/dist/{chunk-2OPD6KRB.js.map → chunk-P5UMIPKR.js.map} +0 -0
- /package/dist/{chunk-G6ARA2HD.js.map → chunk-QQAKDJPE.js.map} +0 -0
- /package/dist/{chunk-KK4M4URN.js.map → chunk-R2IGOYHU.js.map} +0 -0
- /package/dist/{chunk-K5HHLTSG.js.map → chunk-UM2YFCPE.js.map} +0 -0
- /package/dist/{chunk-MF3VJKHT.js.map → chunk-VMDQDD5Y.js.map} +0 -0
- /package/dist/{chunk-6WTCJI5R.js.map → chunk-VPQBQJ4S.js.map} +0 -0
- /package/dist/{chunk-5ZL7PA63.js.map → chunk-W6Y66G4K.js.map} +0 -0
- /package/dist/{chunk-6GAJETAP.js.map → chunk-XBLRT3MX.js.map} +0 -0
- /package/dist/{chunk-W4XZ3FBZ.js.map → chunk-ZU27I5NZ.js.map} +0 -0
package/src/nats/nats.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ConnectionOptions,
|
|
3
3
|
Consumer,
|
|
4
|
+
ConsumerEvents,
|
|
4
5
|
ConsumerMessages,
|
|
5
6
|
JsMsg,
|
|
6
7
|
MsgHdrs as NatsHeaders,
|
|
@@ -19,10 +20,27 @@ export interface JetStreamOrderedSubscribeOptions {
|
|
|
19
20
|
deliverPolicy: JetStreamDeliverPolicy
|
|
20
21
|
/** Required when deliverPolicy === 'byStartSequence'. */
|
|
21
22
|
optStartSeq?: number
|
|
22
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Auto-cleanup the ephemeral consumer after this idle time. Defaults to
|
|
25
|
+
* nats.ws's own. Applies to the consumer created first: nats.ws only reads it
|
|
26
|
+
* when the start sequence is the one it was built with, so every consumer it
|
|
27
|
+
* recreates afterwards reverts to the library default.
|
|
28
|
+
*/
|
|
23
29
|
inactiveThresholdMs?: number
|
|
24
30
|
/** AbortSignal to tear down the consumer. */
|
|
25
31
|
signal?: AbortSignal
|
|
32
|
+
/**
|
|
33
|
+
* The ordered consumer had to be rebuilt: the server dropped the ephemeral
|
|
34
|
+
* consumer (its inactivity threshold elapsed while the page was suspended or
|
|
35
|
+
* offline), heartbeats were missed, or a sequence gap was detected. nats.ws
|
|
36
|
+
* recreates it from the last delivered sequence, so this is NOT an error —
|
|
37
|
+
* but everything that aged out of the stream while it was gone is
|
|
38
|
+
* unrecoverable from the tail, and no connection event announces it (the
|
|
39
|
+
* WebSocket never dropped). Callers that keep persisted history alongside
|
|
40
|
+
* the live tail must refetch it here, or they keep showing a snapshot from
|
|
41
|
+
* before the gap.
|
|
42
|
+
*/
|
|
43
|
+
onRecovered?: () => void
|
|
26
44
|
}
|
|
27
45
|
|
|
28
46
|
export interface JetStreamSubscriptionHandle {
|
|
@@ -270,6 +288,47 @@ function mapNatsTypeToStatus(type: unknown): NatsStatus | null {
|
|
|
270
288
|
return null
|
|
271
289
|
}
|
|
272
290
|
|
|
291
|
+
/**
|
|
292
|
+
* Report an ordered consumer rebuilding itself.
|
|
293
|
+
*
|
|
294
|
+
* nats.ws announces this on the message iterator's status channel and nowhere
|
|
295
|
+
* else — the iterator keeps yielding, the WebSocket never drops, and nothing
|
|
296
|
+
* consumes that channel unless someone asks for it. That silence is what lets a
|
|
297
|
+
* tail resume after a suspended page having permanently missed whatever expired
|
|
298
|
+
* from the stream meanwhile: the recreation resumes from the last delivered
|
|
299
|
+
* sequence, so the gap is invisible from the tail alone.
|
|
300
|
+
*
|
|
301
|
+
* `recreatedEvent` is nats.ws's own enum value rather than a literal of ours: a
|
|
302
|
+
* copy that drifted from the library would kill this signal silently, which is
|
|
303
|
+
* the failure mode the signal exists to prevent.
|
|
304
|
+
*
|
|
305
|
+
* The status channel is closed along with the iterator, which ends this loop.
|
|
306
|
+
*/
|
|
307
|
+
function watchForRecovery(
|
|
308
|
+
iter: ConsumerMessages,
|
|
309
|
+
recreatedEvent: ConsumerEvents.OrderedConsumerRecreated,
|
|
310
|
+
onRecovered?: () => void,
|
|
311
|
+
): void {
|
|
312
|
+
if (!onRecovered) return
|
|
313
|
+
void (async () => {
|
|
314
|
+
try {
|
|
315
|
+
const status = await iter.status()
|
|
316
|
+
for await (const event of status) {
|
|
317
|
+
if (event.type !== recreatedEvent) continue
|
|
318
|
+
try {
|
|
319
|
+
onRecovered()
|
|
320
|
+
} catch (e) {
|
|
321
|
+
// A caller that throws must not take the watch down with it — this
|
|
322
|
+
// loop is the only thing reporting recoveries for this subscription.
|
|
323
|
+
console.warn('[nats] onRecovered threw:', e)
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
} catch {
|
|
327
|
+
// Status ends with the subscription — nothing left to report.
|
|
328
|
+
}
|
|
329
|
+
})()
|
|
330
|
+
}
|
|
331
|
+
|
|
273
332
|
export function createNatsClient(options: NatsClientOptions): NatsClient {
|
|
274
333
|
let nc: NatsConnection | null = null
|
|
275
334
|
let statusLoopAbort: AbortController | null = null
|
|
@@ -524,15 +583,20 @@ export function createNatsClient(options: NatsClientOptions): NatsClient {
|
|
|
524
583
|
return { unsubscribe() {} }
|
|
525
584
|
}
|
|
526
585
|
|
|
527
|
-
const inactiveThresholdNs =
|
|
528
|
-
(opts.inactiveThresholdMs ?? 5 * 60_000) * 1_000_000
|
|
529
|
-
|
|
530
586
|
const js = conn.jetstream()
|
|
531
587
|
const consumer: Consumer = await js.consumers.get(opts.streamName, {
|
|
532
588
|
filterSubjects: opts.filterSubject,
|
|
533
589
|
deliver_policy: nats.DeliverPolicy.StartSequence,
|
|
534
590
|
opt_start_seq: opts.optStartSeq ?? 0,
|
|
535
|
-
|
|
591
|
+
// Milliseconds, NOT nanoseconds: nats.ws runs this through its own
|
|
592
|
+
// `nanos()` before it reaches the server. Pre-converting here multiplied
|
|
593
|
+
// it by 1e6 twice, putting the threshold ~9.5 years out — so the ephemeral
|
|
594
|
+
// consumer never expired. Two consequences, both silent: every reconnect
|
|
595
|
+
// and dialog switch orphaned a consumer server-side, and a client that
|
|
596
|
+
// stopped pulling never got the `consumer deleted` that drives the ordered
|
|
597
|
+
// consumer's self-repair. Undefined stays undefined so nats.ws applies its
|
|
598
|
+
// own default rather than a copy of it.
|
|
599
|
+
inactive_threshold: opts.inactiveThresholdMs,
|
|
536
600
|
})
|
|
537
601
|
|
|
538
602
|
const iterRef: { current: ConsumerMessages | null } = { current: null }
|
|
@@ -575,6 +639,7 @@ export function createNatsClient(options: NatsClientOptions): NatsClient {
|
|
|
575
639
|
return
|
|
576
640
|
}
|
|
577
641
|
iterRef.current = iter
|
|
642
|
+
watchForRecovery(iter, nats.ConsumerEvents.OrderedConsumerRecreated, opts.onRecovered)
|
|
578
643
|
for await (const msg of iter) {
|
|
579
644
|
if (closed) break
|
|
580
645
|
try {
|
package/src/types/navigation.ts
CHANGED
|
@@ -92,6 +92,27 @@ export interface SlidingSidebarConfig {
|
|
|
92
92
|
*/
|
|
93
93
|
export interface NavigationSidebarConfig {
|
|
94
94
|
items: NavigationSidebarItem[]
|
|
95
|
+
/**
|
|
96
|
+
* Draw placeholder rows instead of `items`.
|
|
97
|
+
*
|
|
98
|
+
* For hosts whose navigation is not knowable at first paint — entries gated by
|
|
99
|
+
* server-loaded feature flags, permissions, or tenant config. Such a host has no
|
|
100
|
+
* good option without this: rendering the items it has yet means a nav that grows
|
|
101
|
+
* and shifts as answers arrive, and guessing the gated ones wrong shows entries
|
|
102
|
+
* that don't belong to the user (a flag that HIDES a legacy entry when enabled
|
|
103
|
+
* makes "not answered yet" indistinguishable from "off").
|
|
104
|
+
*
|
|
105
|
+
* The rows reuse the real entry's geometry and the sidebar's own minimized state,
|
|
106
|
+
* so the placeholder is correct in both the expanded and the minimized rail with
|
|
107
|
+
* nothing to pass in — and the handoff to the real nav moves nothing.
|
|
108
|
+
*/
|
|
109
|
+
loading?: boolean
|
|
110
|
+
/**
|
|
111
|
+
* How many placeholder rows `loading` draws, per section. Defaults to 7 primary
|
|
112
|
+
* and 2 secondary — the shape of a typical console nav. Pass the counts the host
|
|
113
|
+
* expects so the placeholder and the loaded nav are the same height.
|
|
114
|
+
*/
|
|
115
|
+
loadingRows?: { primary?: number; secondary?: number }
|
|
95
116
|
minimized?: boolean
|
|
96
117
|
onNavigate?: (path: string) => void
|
|
97
118
|
onToggleMinimized?: () => void
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/nats/nats.ts","../src/nats/shared-connection.ts","../src/nats/nats-provider.tsx","../src/nats/use-nats-subscription.ts"],"sourcesContent":["import type {\n ConnectionOptions,\n Consumer,\n ConsumerMessages,\n JsMsg,\n MsgHdrs as NatsHeaders,\n Msg,\n NatsConnection,\n Subscription,\n} from 'nats.ws'\n\nexport type { JsMsg, Msg, Subscription } from 'nats.ws'\n\nexport type JetStreamDeliverPolicy = 'new' | 'byStartSequence'\n\nexport interface JetStreamOrderedSubscribeOptions {\n streamName: string\n filterSubject: string\n deliverPolicy: JetStreamDeliverPolicy\n /** Required when deliverPolicy === 'byStartSequence'. */\n optStartSeq?: number\n /** Auto-cleanup the ephemeral consumer after this idle time. Default: 5 minutes. */\n inactiveThresholdMs?: number\n /** AbortSignal to tear down the consumer. */\n signal?: AbortSignal\n}\n\nexport interface JetStreamSubscriptionHandle {\n unsubscribe(): void\n}\n\nexport interface NatsClientOptions {\n /**\n * NATS server URL(s), for example:\n * - \"wss://nats.example.com:443\"\n * - [\"wss://nats-1.example.com:443\", \"wss://nats-2.example.com:443\"]\n */\n servers: string | string[]\n\n /**\n * Connection name (shows up in NATS monitoring).\n */\n name?: string\n\n /**\n * Auth options (pick one: token or user/pass).\n */\n token?: string\n user?: string\n pass?: string\n\n /**\n * Reconnect behavior.\n */\n reconnect?: boolean\n maxReconnectAttempts?: number\n reconnectTimeWaitMs?: number\n\n /**\n * Exponential backoff for reconnect delays.\n * When set, uses `reconnectDelayHandler` from nats.ws under the hood,\n * overriding `reconnectTimeWaitMs`.\n */\n exponentialBackoff?: {\n /** Initial delay in ms (default: 1000) */\n initialDelayMs?: number\n /** Maximum delay cap in ms (default: 30000) */\n maxDelayMs?: number\n /** Multiplier per attempt (default: 2) */\n multiplier?: number\n /** Add random jitter 0-50% of delay to prevent thundering herd (default: true) */\n jitter?: boolean\n }\n\n /**\n * Ping behavior (keep-alive).\n */\n pingIntervalMs?: number\n maxPingOut?: number\n\n /**\n * Optional inbox prefix (useful if you want to isolate request/reply inboxes).\n */\n inboxPrefix?: string\n\n /**\n * Connection timeout in milliseconds (maps to `nats.ws` connect option `timeout`).\n * If you see `NatsError: TIMEOUT` during connect, increase this.\n */\n connectTimeoutMs?: number\n}\n\nexport interface NatsSubscribeOptions {\n /**\n * Queue group for load-balancing messages across subscribers.\n */\n queue?: string\n\n /**\n * Auto-unsubscribe after receiving this many messages.\n */\n max?: number\n\n /**\n * Abort signal to stop message iteration and unsubscribe.\n */\n signal?: AbortSignal\n}\n\nexport type NatsHeadersInit = Record<string, string> | NatsHeaders | undefined\n\nexport interface NatsPublishOptions {\n headers?: NatsHeadersInit\n}\n\nexport interface NatsRequestOptions {\n timeoutMs?: number\n headers?: NatsHeadersInit\n}\n\nexport interface NatsSubscriptionHandle {\n readonly subscription: Subscription\n unsubscribe(): void\n}\n\nexport type NatsStatus =\n | 'connecting'\n | 'connected'\n | 'disconnected'\n | 'reconnecting'\n | 'closed'\n | 'error'\n\nexport interface NatsStatusEvent {\n status: NatsStatus\n data?: unknown\n}\n\nexport interface NatsClient {\n connect(): Promise<void>\n close(): Promise<void>\n\n isConnected(): boolean\n\n publishBytes(subject: string, payload: Uint8Array, options?: NatsPublishOptions): void\n publishString(subject: string, payload: string, options?: NatsPublishOptions): void\n publishJson<T>(subject: string, payload: T, options?: NatsPublishOptions): void\n\n requestBytes(subject: string, payload: Uint8Array, options?: NatsRequestOptions): Promise<Msg>\n requestString(subject: string, payload: string, options?: NatsRequestOptions): Promise<string>\n requestJson<TResponse, TRequest = unknown>(\n subject: string,\n payload: TRequest,\n options?: NatsRequestOptions,\n ): Promise<TResponse>\n\n subscribeBytes(\n subject: string,\n onMessage: (msg: Msg) => void | Promise<void>,\n options?: NatsSubscribeOptions,\n ): NatsSubscriptionHandle\n subscribeString(\n subject: string,\n onMessage: (payload: string, msg: Msg) => void | Promise<void>,\n options?: NatsSubscribeOptions,\n ): NatsSubscriptionHandle\n subscribeJson<T>(\n subject: string,\n onMessage: (payload: T, msg: Msg) => void | Promise<void>,\n options?: NatsSubscribeOptions,\n ): NatsSubscriptionHandle\n\n /**\n * Subscribe to a JetStream subject via an ephemeral OrderedConsumer (no acks).\n * Use `optStartSeq` with `deliverPolicy: 'byStartSequence'` to resume from a known offset,\n * or `deliverPolicy: 'new'` to live-tail.\n */\n subscribeJetStreamOrdered(\n onMessage: (msg: JsMsg) => void | Promise<void>,\n options: JetStreamOrderedSubscribeOptions,\n ): Promise<JetStreamSubscriptionHandle>\n\n onStatus(listener: (event: NatsStatusEvent) => void): () => void\n}\n\nfunction assertClientSide(): void {\n // This wrapper is meant for browser/Tauri usage via WebSockets.\n // Keep it safe to import from Next.js server bundles by throwing only when used.\n if (typeof window === 'undefined') {\n throw new Error('NATS client can only connect from the browser/runtime with WebSocket support (window is undefined).')\n }\n}\n\nasync function importNats(): Promise<typeof import('nats.ws')> {\n // Browser/Tauri only: always use the websocket client (no Node-only deps).\n return await import('nats.ws')\n}\n\nfunction toNatsHeaders(nats: typeof import('nats.ws'), init: NatsHeadersInit): NatsHeaders | undefined {\n if (!init) return undefined\n if (typeof (init as NatsHeaders).get === 'function') return init as NatsHeaders\n\n const h = nats.headers()\n for (const [k, v] of Object.entries(init as Record<string, string>)) {\n if (v !== undefined && v !== null) h.set(k, String(v))\n }\n return h\n}\n\n/** Returns a cryptographically random float in [0, 1). */\nfunction cryptoRandom(): number {\n const buf = new Uint32Array(1)\n crypto.getRandomValues(buf)\n return buf[0] / (0xffffffff + 1)\n}\n\ninterface ExponentialBackoffHandle {\n handler: () => number\n reset: () => void\n}\n\nfunction createExponentialBackoffHandler(opts: NonNullable<NatsClientOptions['exponentialBackoff']>): ExponentialBackoffHandle {\n const initialDelay = opts.initialDelayMs ?? 1000\n const maxDelay = opts.maxDelayMs ?? 30_000\n const multiplier = opts.multiplier ?? 2\n const jitter = opts.jitter ?? true\n\n let attempt = 0\n\n return {\n handler: (): number => {\n const delay = Math.min(initialDelay * multiplier ** attempt, maxDelay)\n attempt++\n return jitter ? delay * (0.5 + cryptoRandom() * 0.5) : delay\n },\n reset: () => {\n attempt = 0\n },\n }\n}\n\nfunction mapOptionsToConnectionOptions(\n opts: NatsClientOptions,\n backoff?: ExponentialBackoffHandle,\n): ConnectionOptions {\n return {\n servers: opts.servers,\n name: opts.name,\n token: opts.token,\n user: opts.user,\n pass: opts.pass,\n timeout: opts.connectTimeoutMs ?? 15000,\n reconnect: opts.reconnect ?? true,\n maxReconnectAttempts: opts.maxReconnectAttempts,\n reconnectTimeWait: opts.reconnectTimeWaitMs,\n reconnectDelayHandler: backoff?.handler,\n pingInterval: opts.pingIntervalMs,\n maxPingOut: opts.maxPingOut,\n inboxPrefix: opts.inboxPrefix,\n }\n}\n\nfunction mapNatsTypeToStatus(type: unknown): NatsStatus | null {\n const t = String(type).toLowerCase()\n if (t.includes('disconnect')) return 'disconnected'\n if (t === 'reconnecting') return 'reconnecting'\n if (t === 'reconnect' || t.includes('connect')) return 'connected'\n if (t.includes('error')) return 'error'\n if (t.includes('close')) return 'closed'\n return null\n}\n\nexport function createNatsClient(options: NatsClientOptions): NatsClient {\n let nc: NatsConnection | null = null\n let statusLoopAbort: AbortController | null = null\n let connectInFlight: Promise<void> | null = null\n\n const backoff = options.exponentialBackoff\n ? createExponentialBackoffHandler(options.exponentialBackoff)\n : undefined\n\n const statusListeners = new Set<(event: NatsStatusEvent) => void>()\n\n function emitStatus(event: NatsStatusEvent) {\n for (const listener of statusListeners) {\n try {\n listener(event)\n } catch {\n // ignore listener failures\n }\n }\n }\n\n async function connect(): Promise<void> {\n if (nc && !nc.isClosed()) return\n if (connectInFlight) return connectInFlight\n assertClientSide()\n\n connectInFlight = (async () => {\n try {\n emitStatus({ status: 'connecting' })\n\n const nats = await importNats()\n const conn = await nats.connect(mapOptionsToConnectionOptions(options, backoff))\n nc = conn\n\n emitStatus({ status: 'connected' })\n\n statusLoopAbort = new AbortController()\n const signal = statusLoopAbort.signal\n\n ;(async () => {\n try {\n for await (const s of conn.status()) {\n if (signal.aborted) return\n const mapped = mapNatsTypeToStatus((s as any)?.type)\n if (mapped) {\n if (mapped === 'connected' && backoff) {\n backoff.reset()\n }\n emitStatus({ status: mapped, data: (s as any)?.data })\n if (mapped === 'closed') {\n nc = null\n }\n }\n }\n } catch (e) {\n if (!signal.aborted) {\n emitStatus({ status: 'error', data: e })\n \n if (nc === conn && conn.isClosed()) {\n nc = null\n emitStatus({ status: 'closed' })\n }\n }\n }\n })().catch(() => {\n // ignore\n })\n } finally {\n connectInFlight = null\n }\n })()\n\n return connectInFlight\n }\n\n async function close(): Promise<void> {\n const conn = nc\n nc = null\n\n if (statusLoopAbort) {\n try {\n statusLoopAbort.abort()\n } catch {\n // ignore\n }\n statusLoopAbort = null\n }\n\n if (!conn) return\n try {\n await conn.drain()\n } finally {\n try {\n await conn.close()\n } finally {\n emitStatus({ status: 'closed' })\n }\n }\n }\n\n function requireConnection(): NatsConnection {\n if (!nc) throw new Error('NATS is not connected. Call client.connect() first.')\n return nc\n }\n\n function isConnected(): boolean {\n return Boolean(nc) && !nc!.isClosed()\n }\n\n function publishBytes(subject: string, payload: Uint8Array, opts?: NatsPublishOptions): void {\n const conn = requireConnection()\n ;(async () => {\n const nats = await importNats()\n conn.publish(subject, payload, { headers: toNatsHeaders(nats, opts?.headers) })\n })().catch((e) => emitStatus({ status: 'error', data: e }))\n }\n\n function publishString(subject: string, payload: string, opts?: NatsPublishOptions): void {\n ;(async () => {\n const nats = await importNats()\n const sc = nats.StringCodec()\n publishBytes(subject, sc.encode(payload), opts)\n })().catch((e) => emitStatus({ status: 'error', data: e }))\n }\n\n function publishJson<T>(subject: string, payload: T, opts?: NatsPublishOptions): void {\n ;(async () => {\n const nats = await importNats()\n const jc = nats.JSONCodec<T>()\n publishBytes(subject, jc.encode(payload), opts)\n })().catch((e) => emitStatus({ status: 'error', data: e }))\n }\n\n async function requestBytes(subject: string, payload: Uint8Array, opts?: NatsRequestOptions): Promise<Msg> {\n const conn = requireConnection()\n const nats = await importNats()\n const msg = await conn.request(subject, payload, {\n timeout: opts?.timeoutMs ?? 2000,\n headers: toNatsHeaders(nats, opts?.headers),\n })\n return msg\n }\n\n async function requestString(subject: string, payload: string, opts?: NatsRequestOptions): Promise<string> {\n const nats = await importNats()\n const sc = nats.StringCodec()\n const msg = await requestBytes(subject, sc.encode(payload), opts)\n return sc.decode(msg.data)\n }\n\n async function requestJson<TResponse, TRequest = unknown>(\n subject: string,\n payload: TRequest,\n opts?: NatsRequestOptions,\n ): Promise<TResponse> {\n const nats = await importNats()\n const reqCodec = nats.JSONCodec<TRequest>()\n const resCodec = nats.JSONCodec<TResponse>()\n const msg = await requestBytes(subject, reqCodec.encode(payload), opts)\n return resCodec.decode(msg.data)\n }\n\n function subscribeBytes(\n subject: string,\n onMessage: (msg: Msg) => void | Promise<void>,\n opts?: NatsSubscribeOptions,\n ): NatsSubscriptionHandle {\n const conn = requireConnection()\n const sub = conn.subscribe(subject, { queue: opts?.queue })\n if (typeof opts?.max === 'number') sub.unsubscribe(opts.max)\n\n const abortController = new AbortController()\n const signal = opts?.signal ?? abortController.signal\n\n ;(async () => {\n try {\n for await (const msg of sub) {\n if (signal.aborted) break\n await onMessage(msg)\n }\n } catch (e) {\n emitStatus({ status: 'error', data: e })\n } finally {\n try {\n sub.unsubscribe()\n } catch {\n // ignore\n }\n }\n })().catch((e) => emitStatus({ status: 'error', data: e }))\n\n return {\n subscription: sub,\n unsubscribe() {\n try {\n abortController.abort()\n } catch {\n // ignore\n }\n try {\n sub.unsubscribe()\n } catch {\n // ignore\n }\n },\n }\n }\n\n function subscribeString(\n subject: string,\n onMessage: (payload: string, msg: Msg) => void | Promise<void>,\n opts?: NatsSubscribeOptions,\n ): NatsSubscriptionHandle {\n return subscribeBytes(\n subject,\n async (msg) => {\n const nats = await importNats()\n const sc = nats.StringCodec()\n await onMessage(sc.decode(msg.data), msg)\n },\n opts,\n )\n }\n\n function subscribeJson<T>(\n subject: string,\n onMessage: (payload: T, msg: Msg) => void | Promise<void>,\n opts?: NatsSubscribeOptions,\n ): NatsSubscriptionHandle {\n return subscribeBytes(\n subject,\n async (msg) => {\n const nats = await importNats()\n const jc = nats.JSONCodec<T>()\n await onMessage(jc.decode(msg.data), msg)\n },\n opts,\n )\n }\n\n async function subscribeJetStreamOrdered(\n onMessage: (msg: JsMsg) => void | Promise<void>,\n opts: JetStreamOrderedSubscribeOptions,\n ): Promise<JetStreamSubscriptionHandle> {\n const conn = requireConnection()\n if (opts.signal?.aborted) {\n return { unsubscribe() {} }\n }\n\n const nats = await importNats()\n if (opts.signal?.aborted) {\n return { unsubscribe() {} }\n }\n\n const inactiveThresholdNs =\n (opts.inactiveThresholdMs ?? 5 * 60_000) * 1_000_000\n\n const js = conn.jetstream()\n const consumer: Consumer = await js.consumers.get(opts.streamName, {\n filterSubjects: opts.filterSubject,\n deliver_policy: nats.DeliverPolicy.StartSequence,\n opt_start_seq: opts.optStartSeq ?? 0,\n inactive_threshold: inactiveThresholdNs,\n })\n\n const iterRef: { current: ConsumerMessages | null } = { current: null }\n let closed = false\n\n const onAbort = () => {\n void teardown()\n }\n opts.signal?.addEventListener('abort', onAbort, { once: true })\n\n async function teardown(): Promise<void> {\n if (closed) return\n closed = true\n opts.signal?.removeEventListener('abort', onAbort)\n const iter = iterRef.current\n iterRef.current = null\n if (iter) {\n try {\n await iter.close()\n } catch {\n // ignore\n }\n }\n }\n\n if (opts.signal?.aborted) {\n void teardown()\n return { unsubscribe() {} }\n }\n\n ;(async () => {\n try {\n const iter = await consumer.consume()\n if (closed) {\n try {\n await iter.close()\n } catch {\n // ignore\n }\n return\n }\n iterRef.current = iter\n for await (const msg of iter) {\n if (closed) break\n try {\n await onMessage(msg)\n } catch (e) {\n emitStatus({ status: 'error', data: e })\n }\n }\n } catch (e) {\n if (!closed) emitStatus({ status: 'error', data: e })\n }\n })().catch((e) => emitStatus({ status: 'error', data: e }))\n\n return {\n unsubscribe() {\n void teardown()\n },\n }\n }\n\n function onStatus(listener: (event: NatsStatusEvent) => void): () => void {\n statusListeners.add(listener)\n return () => statusListeners.delete(listener)\n }\n\n return {\n connect,\n close,\n isConnected,\n publishBytes,\n publishString,\n publishJson,\n requestBytes,\n requestString,\n requestJson,\n subscribeBytes,\n subscribeString,\n subscribeJson,\n subscribeJetStreamOrdered,\n onStatus,\n }\n}\n","import { createNatsClient, type NatsClient, type NatsStatus, type NatsStatusEvent } from './nats'\n\nexport const NATS_DEFAULTS = {\n SHARED_CLOSE_DELAY_MS: 3000,\n CONNECT_TIMEOUT_MS: 10_000,\n PING_INTERVAL_MS: 30_000,\n MAX_PING_OUT: 3,\n RETRY_INITIAL_DELAY_MS: 1000,\n RETRY_MAX_DELAY_MS: 30_000,\n RETRY_MULTIPLIER: 2,\n} as const\n\nexport interface NatsReconnectionBackoff {\n /** Number of fast retries before exponential phase kicks in. Default: 0. */\n fastRetries?: number\n /** Delay used during the fast-retry phase. Default: RETRY_INITIAL_DELAY_MS. */\n fastRetryDelayMs?: number\n /** Base delay for the exponential phase. Default: RETRY_INITIAL_DELAY_MS. */\n initialDelayMs?: number\n /** Upper cap on any single retry delay. Default: RETRY_MAX_DELAY_MS. */\n maxDelayMs?: number\n /** Per-attempt multiplier during exponential phase. Default: RETRY_MULTIPLIER. */\n multiplier?: number\n}\n\nexport interface SharedConnection {\n wsUrl: string\n client: NatsClient\n connectPromise: Promise<void> | null\n refCount: number\n closeTimer: ReturnType<typeof setTimeout> | null\n retryTimer: ReturnType<typeof setTimeout> | null\n /**\n * Identity of the consumer driving reconnect. When set, other consumers\n * should observe status only and skip their own scheduleRetry — otherwise\n * each disconnect triggers multiple concurrent connect() calls racing over\n * connectPromise.\n */\n retryOwner: object | null\n}\n\nexport interface AcquireClientOptions {\n name?: string\n user?: string\n pass?: string\n connectTimeoutMs?: number\n pingIntervalMs?: number\n maxPingOut?: number\n}\n\nexport interface ReleaseClientOptions {\n delayMs?: number\n}\n\n// One shared connection PER URL. The previous single-slot implementation\n// force-closed whatever was connected the moment any consumer acquired a\n// DIFFERENT URL — even with live refs on it. With two chat surfaces on\n// distinct endpoints (`/ws/nats` client chat vs `/ws/nats-api` dashboard)\n// mounted at once, each acquire killed the other's socket, and the loser's\n// retry loop self-cancelled (connection identity mismatch) leaving a dead\n// subscription that silently received nothing.\nconst connections = new Map<string, SharedConnection>()\n\n/** Legacy accessor from the single-slot era: returns the first live shared\n * connection, or null. With MULTIPLE URLs connected (e.g. `/ws/nats` client\n * chat + `/ws/nats-api` dashboard mounted together) \"first\" is whichever\n * surface acquired first — an arbitrary, mount-order-dependent answer.\n * Prefer `getSharedConnectionFor(url)`; this stays only for external\n * registry-pinned consumers of the old single-connection API. */\nexport function getSharedConnection(): SharedConnection | null {\n const first = connections.values().next()\n return first.done ? null : first.value\n}\n\nexport function acquireClient(url: string, opts?: AcquireClientOptions): SharedConnection {\n let conn = connections.get(url)\n\n if (!conn) {\n const {\n name = 'openframe-frontend',\n user = 'machine',\n pass = '',\n connectTimeoutMs = NATS_DEFAULTS.CONNECT_TIMEOUT_MS,\n pingIntervalMs = NATS_DEFAULTS.PING_INTERVAL_MS,\n maxPingOut = NATS_DEFAULTS.MAX_PING_OUT,\n } = opts ?? {}\n\n const client = createNatsClient({\n servers: url,\n name,\n user,\n pass,\n connectTimeoutMs,\n reconnect: false,\n pingIntervalMs,\n maxPingOut,\n })\n\n conn = {\n wsUrl: url,\n client,\n connectPromise: null,\n refCount: 0,\n closeTimer: null,\n retryTimer: null,\n retryOwner: null,\n }\n connections.set(url, conn)\n }\n\n conn.refCount += 1\n if (conn.closeTimer) {\n clearTimeout(conn.closeTimer)\n conn.closeTimer = null\n }\n return conn\n}\n\nexport function releaseClient(url: string, opts?: ReleaseClientOptions): void {\n const conn = connections.get(url)\n if (!conn) return\n\n conn.refCount = Math.max(0, conn.refCount - 1)\n if (conn.refCount > 0) return\n\n const delay = opts?.delayMs ?? NATS_DEFAULTS.SHARED_CLOSE_DELAY_MS\n conn.closeTimer = setTimeout(() => {\n conn.closeTimer = null\n // A new acquire may have raced in during the grace period.\n if (conn.refCount > 0) return\n if (connections.get(url) === conn) {\n connections.delete(url)\n }\n if (conn.retryTimer) {\n clearTimeout(conn.retryTimer)\n conn.retryTimer = null\n }\n void conn.client.close().catch(() => {})\n }, delay)\n}\n\nexport function getSharedConnectionFor(url: string | null | undefined): SharedConnection | null {\n if (!url) return null\n return connections.get(url) ?? null\n}\n\n// ---------------------------------------------------------------------------\n// Connection lifecycle: retry + status loop, shared by NatsProvider and the\n// chat hooks. Each consumer that wants to drive reconnect creates an\n// ownerToken and calls startConnectionLifecycle(). The first caller to claim\n// retryOwner runs the actual retry loop; subsequent claimants observe status\n// only. When the owner unmounts and releases retryOwner, the next status\n// event lets a surviving consumer pick up ownership opportunistically.\n// ---------------------------------------------------------------------------\n\nexport interface ConnectionLifecycleOptions {\n conn: SharedConnection\n wsUrl: string\n onBeforeReconnect?: () => Promise<void> | void\n backoff?: NatsReconnectionBackoff\n getFreshUrl: () => string | null\n /** Called on every status change (after closed-guard). */\n onStatusChange?: (status: NatsStatus, evt: NatsStatusEvent) => void\n /**\n * Decide which statuses should trigger a retry attempt. Defaults to closed +\n * disconnected. Override to skip 'error' (JetStream protocol errors that\n * don't close the WS) or include it.\n */\n shouldRetryOn?: (status: NatsStatus) => boolean\n}\n\nexport interface ConnectionLifecycleHandle {\n /** Stop observing status, clear any pending retry, release ownership if held. */\n stop(): void\n}\n\nconst defaultShouldRetryOn = (status: NatsStatus) => status === 'closed' || status === 'disconnected'\n\nexport function startConnectionLifecycle(options: ConnectionLifecycleOptions): ConnectionLifecycleHandle {\n const { conn, wsUrl } = options\n // Each lifecycle gets its own identity for retry ownership. The first lifecycle to claim\n // an unowned connection drives reconnect; later attachers observe status only until the\n // owner releases (see opportunistic claim in scheduleRetry).\n const ownerToken = {}\n if (!conn.retryOwner) conn.retryOwner = ownerToken\n\n let closed = false\n let retryAttempt = 0\n\n function emitSynthetic(status: NatsStatus) {\n if (closed) return\n options.onStatusChange?.(status, { status })\n if (status === 'connected') {\n retryAttempt = 0\n }\n }\n\n function scheduleRetry() {\n if (closed) return\n if (getSharedConnectionFor(wsUrl) !== conn) return\n if (!conn.retryOwner) conn.retryOwner = ownerToken\n if (conn.retryOwner !== ownerToken) return\n\n if (conn.retryTimer) {\n clearTimeout(conn.retryTimer)\n conn.retryTimer = null\n }\n\n const cfg = options.backoff ?? {}\n const fastRetries = cfg.fastRetries ?? 0\n const fastDelay = cfg.fastRetryDelayMs ?? NATS_DEFAULTS.RETRY_INITIAL_DELAY_MS\n const baseDelay = cfg.initialDelayMs ?? NATS_DEFAULTS.RETRY_INITIAL_DELAY_MS\n const maxDelay = cfg.maxDelayMs ?? NATS_DEFAULTS.RETRY_MAX_DELAY_MS\n const multiplier = cfg.multiplier ?? NATS_DEFAULTS.RETRY_MULTIPLIER\n\n const delay =\n retryAttempt < fastRetries\n ? fastDelay\n : Math.min(baseDelay * multiplier ** (retryAttempt - fastRetries), maxDelay)\n const jitteredDelay = delay * (0.5 + Math.random() * 0.5)\n retryAttempt++\n\n conn.retryTimer = setTimeout(async () => {\n conn.retryTimer = null\n if (closed) return\n if (getSharedConnectionFor(wsUrl) !== conn) return\n\n try {\n await options.onBeforeReconnect?.()\n } catch {\n // continue regardless of token-refresh outcome\n }\n if (closed) return\n if (getSharedConnectionFor(wsUrl) !== conn) return\n\n const freshUrl = options.getFreshUrl()\n if (freshUrl !== wsUrl) return\n\n try {\n conn.connectPromise = null\n conn.connectPromise = conn.client.connect()\n await conn.connectPromise\n if (!closed && getSharedConnectionFor(wsUrl) === conn) {\n retryAttempt = 0\n }\n } catch {\n conn.connectPromise = null\n if (!closed && getSharedConnectionFor(wsUrl) === conn) {\n scheduleRetry()\n }\n }\n }, jitteredDelay)\n }\n\n const shouldRetryOn = options.shouldRetryOn ?? defaultShouldRetryOn\n\n const unsubStatus = conn.client.onStatus((evt) => {\n if (closed) return\n options.onStatusChange?.(evt.status, evt)\n if (evt.status === 'connected') {\n retryAttempt = 0\n }\n if (shouldRetryOn(evt.status)) {\n scheduleRetry()\n }\n })\n\n if (conn.client.isConnected()) {\n emitSynthetic('connected')\n }\n\n void (async () => {\n try {\n conn.connectPromise ||= conn.client.connect()\n await conn.connectPromise\n } catch {\n conn.connectPromise = null\n if (closed) return\n\n emitSynthetic('disconnected')\n scheduleRetry()\n }\n })()\n\n return {\n stop() {\n closed = true\n unsubStatus()\n if (conn.retryTimer) {\n clearTimeout(conn.retryTimer)\n conn.retryTimer = null\n }\n if (conn.retryOwner === ownerToken) {\n conn.retryOwner = null\n }\n },\n }\n}\n","'use client'\n\nimport * as React from 'react'\nimport type { NatsClient, NatsStatus } from './nats'\nimport {\n acquireClient,\n releaseClient,\n startConnectionLifecycle,\n type AcquireClientOptions,\n type NatsReconnectionBackoff,\n} from './shared-connection'\n\nexport type { NatsReconnectionBackoff } from './shared-connection'\n\nexport interface NatsProviderProps {\n children: React.ReactNode\n /** Return the current NATS WebSocket URL (or null when not yet available, e.g. unauthenticated). */\n getWsUrl: () => string | null\n /** Called before each reconnect attempt. */\n onBeforeReconnect?: () => Promise<void> | void\n clientConfig?: AcquireClientOptions\n reconnectionBackoff?: NatsReconnectionBackoff\n /**\n * Bump this to force re-evaluating `getWsUrl()` (e.g. when auth state flips).\n * Provider does not subscribe to external auth state by itself.\n */\n urlRevision?: unknown\n}\n\nexport interface NatsContextValue {\n client: NatsClient | null\n status: NatsStatus\n isReady: boolean\n reconnectionCount: number\n}\n\nconst NatsContext = React.createContext<NatsContextValue | null>(null)\n\nexport function NatsProvider({\n children,\n getWsUrl,\n onBeforeReconnect,\n clientConfig,\n reconnectionBackoff,\n urlRevision,\n}: NatsProviderProps) {\n const [client, setClient] = React.useState<NatsClient | null>(null)\n const [status, setStatus] = React.useState<NatsStatus>('closed')\n const [reconnectionCount, setReconnectionCount] = React.useState(0)\n\n const getWsUrlRef = React.useRef(getWsUrl)\n React.useEffect(() => {\n getWsUrlRef.current = getWsUrl\n }, [getWsUrl])\n\n const onBeforeReconnectRef = React.useRef(onBeforeReconnect)\n React.useEffect(() => {\n onBeforeReconnectRef.current = onBeforeReconnect\n }, [onBeforeReconnect])\n\n const reconnectionBackoffRef = React.useRef(reconnectionBackoff)\n React.useEffect(() => {\n reconnectionBackoffRef.current = reconnectionBackoff\n }, [reconnectionBackoff])\n\n const clientConfigRef = React.useRef(clientConfig)\n React.useEffect(() => {\n clientConfigRef.current = clientConfig\n }, [clientConfig])\n\n const heldUrlRef = React.useRef<string | null>(null)\n const hadConnectionBeforeRef = React.useRef(false)\n\n React.useEffect(() => {\n const wsUrl = getWsUrlRef.current()\n\n if (!wsUrl) {\n if (heldUrlRef.current) {\n releaseClient(heldUrlRef.current)\n heldUrlRef.current = null\n setClient(null)\n setStatus('closed')\n }\n return\n }\n\n if (heldUrlRef.current && heldUrlRef.current !== wsUrl) {\n releaseClient(heldUrlRef.current)\n heldUrlRef.current = null\n }\n\n const conn = acquireClient(wsUrl, clientConfigRef.current)\n heldUrlRef.current = wsUrl\n setClient(conn.client)\n setStatus(conn.client.isConnected() ? 'connected' : 'connecting')\n\n const lifecycle = startConnectionLifecycle({\n conn,\n wsUrl,\n onBeforeReconnect: () => onBeforeReconnectRef.current?.(),\n backoff: reconnectionBackoffRef.current,\n getFreshUrl: () => getWsUrlRef.current(),\n onStatusChange: (newStatus) => {\n if (newStatus === 'error') return\n setStatus(newStatus)\n if (newStatus === 'connected') {\n if (hadConnectionBeforeRef.current) {\n setReconnectionCount((c) => c + 1)\n }\n hadConnectionBeforeRef.current = true\n }\n },\n })\n\n return () => {\n lifecycle.stop()\n if (heldUrlRef.current) {\n releaseClient(heldUrlRef.current)\n heldUrlRef.current = null\n }\n setClient(null)\n setStatus('closed')\n }\n }, [urlRevision])\n\n const value = React.useMemo<NatsContextValue>(\n () => ({\n client,\n status,\n isReady: status === 'connected' && client !== null,\n reconnectionCount,\n }),\n [client, status, reconnectionCount],\n )\n\n return <NatsContext.Provider value={value}>{children}</NatsContext.Provider>\n}\n\nexport function useNats(): NatsContextValue {\n const ctx = React.useContext(NatsContext)\n if (!ctx) throw new Error('useNats must be used inside <NatsProvider>')\n return ctx\n}\n\nexport function useOptionalNats(): NatsContextValue | null {\n return React.useContext(NatsContext)\n}\n","'use client'\n\nimport * as React from 'react'\nimport type { JsMsg, Msg, NatsSubscribeOptions } from './nats'\nimport { useOptionalNats } from './nats-provider'\n\nexport interface UseNatsSubscriptionOptions extends NatsSubscribeOptions {\n enabled?: boolean\n}\n\nexport interface UseNatsSubscriptionReturn {\n isSubscribed: boolean\n isReady: boolean\n}\n\n/**\n * Subscribe to a NATS subject using the shared connection from <NatsProvider>.\n * Automatically (re)subscribes when the connection becomes ready, when the\n * subject changes, and after reconnections.\n */\nexport function useNatsSubscription(\n subject: string | null,\n onMessage: (msg: Msg) => void | Promise<void>,\n options?: UseNatsSubscriptionOptions,\n): UseNatsSubscriptionReturn {\n const nats = useOptionalNats()\n const handlerRef = React.useRef(onMessage)\n React.useEffect(() => {\n handlerRef.current = onMessage\n }, [onMessage])\n\n const [isSubscribed, setIsSubscribed] = React.useState(false)\n\n const enabled = options?.enabled !== false\n const queue = options?.queue\n const max = options?.max\n const reconnectionCount = nats?.reconnectionCount ?? 0\n const isReady = !!nats?.isReady\n const client = nats?.client ?? null\n\n React.useEffect(() => {\n if (!client || !isReady || !subject || !enabled) {\n setIsSubscribed(false)\n return\n }\n\n const sub = client.subscribeBytes(\n subject,\n (msg) => handlerRef.current(msg),\n { queue, max },\n )\n setIsSubscribed(true)\n\n return () => {\n setIsSubscribed(false)\n try {\n sub.unsubscribe()\n } catch {\n // ignore\n }\n }\n // reconnectionCount intentionally in deps: re-subscribe after reconnect\n }, [client, isReady, subject, enabled, queue, max, reconnectionCount])\n\n return { isSubscribed, isReady }\n}\n\nexport type UseNatsJsonSubscriptionOptions = UseNatsSubscriptionOptions\n\nexport function useNatsJsonSubscription<T = unknown>(\n subject: string | null,\n onPayload: (payload: T, msg: Msg) => void | Promise<void>,\n options?: UseNatsJsonSubscriptionOptions,\n): UseNatsSubscriptionReturn {\n const handlerRef = React.useRef(onPayload)\n React.useEffect(() => {\n handlerRef.current = onPayload\n }, [onPayload])\n\n const decoderRef = React.useRef<TextDecoder | null>(null)\n if (!decoderRef.current && typeof TextDecoder !== 'undefined') {\n decoderRef.current = new TextDecoder()\n }\n\n const wrapped = React.useCallback(async (msg: Msg) => {\n const decoder = decoderRef.current\n if (!decoder) return\n try {\n const parsed = JSON.parse(decoder.decode(msg.data)) as T\n await handlerRef.current(parsed, msg)\n } catch {\n // ignore malformed payloads\n }\n }, [])\n\n return useNatsSubscription(subject, wrapped, options)\n}\n\nexport type NatsJsMsg = JsMsg\n"],"mappings":"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","names":["React"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/ui/button/button-styles.ts","../src/components/ui/button/button.tsx","../src/components/ui/button/split-button.tsx","../src/components/ui/button/index.ts","../src/components/ui/field-wrapper.tsx","../src/components/ui/input.tsx","../src/components/ui/checkbox.tsx","../src/components/ui/dropdown-menu.tsx","../src/components/ui/portal-container.tsx","../src/components/ui/skeleton.tsx"],"sourcesContent":["// Shared style atoms for `Button` and `SplitButton`. Extracted to keep a single\n// source of truth for surface colors, outline borders, and split-divider colors.\n\n// Each variant pairs `disabled:` (real `<button disabled>`) with `aria-disabled:`\n// (used for `<Link aria-disabled>` since anchors don't support `:disabled`).\nexport const buttonSurfaceClasses = {\n accent:\n \"bg-ods-accent text-ods-text-on-accent hover:bg-ods-accent-hover active:bg-ods-accent-active disabled:bg-ods-disabled aria-disabled:bg-ods-disabled\",\n outline:\n \"bg-ods-card text-ods-text-primary hover:bg-ods-bg-hover active:bg-ods-bg-active disabled:bg-ods-card disabled:text-ods-text-disabled aria-disabled:bg-ods-card aria-disabled:text-ods-text-disabled\",\n transparent:\n \"bg-transparent text-ods-text-primary hover:bg-ods-bg-hover active:bg-ods-bg-active disabled:bg-transparent disabled:text-ods-text-disabled aria-disabled:bg-transparent aria-disabled:text-ods-text-disabled\",\n destructive:\n \"bg-ods-error text-ods-text-on-accent hover:bg-ods-error-hover active:bg-ods-error-active disabled:bg-ods-disabled aria-disabled:bg-ods-disabled\",\n warning:\n \"bg-ods-warning text-ods-text-on-accent hover:bg-ods-warning-hover active:bg-ods-warning-active disabled:bg-ods-disabled aria-disabled:bg-ods-disabled\",\n // A self-contained glyph (play badge, unmute glyph) that already carries its\n // own scrim: no button surface at all, in any state. Distinct from\n // `transparent`, whose hover/active fills would paint a rectangle behind the\n // glyph — which is why call sites were undoing them with\n // `hover:bg-transparent active:bg-transparent`.\n glyph:\n \"bg-transparent text-ods-text-primary hover:bg-transparent active:bg-transparent disabled:bg-transparent disabled:text-ods-text-disabled aria-disabled:bg-transparent aria-disabled:text-ods-text-disabled\",\n // Chrome that sits ON media (video cards, image lightboxes): a scrim disc so\n // the glyph stays legible over an arbitrary frame. Promoted to a variant\n // because the walkthrough card, its theater and the bite cards were each\n // stacking the same classes at the call site.\n overlay:\n \"rounded-full bg-ods-overlay text-ods-text-primary backdrop-blur-sm hover:text-ods-accent active:text-ods-accent-active disabled:text-ods-text-disabled aria-disabled:text-ods-text-disabled\",\n} as const\n\nexport const outlineBorderClasses =\n \"border border-ods-border hover:border-ods-border-hover active:border-ods-border-active disabled:border-ods-border aria-disabled:border-ods-border\"\n\n// Color of the vertical seam between the main and icon halves (split layouts).\nexport const splitDividerColorClasses = {\n accent: \"border-ods-accent-active\",\n outline: \"border-ods-border\",\n transparent: \"border-ods-border\",\n destructive: \"border-ods-error-active\",\n warning: \"border-ods-warning-active\",\n} as const\n\nexport type ButtonSurfaceVariant = keyof typeof buttonSurfaceClasses\n","\"use client\"\n\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport Link from \"../../../embed-shims/next-link\"\nimport React from \"react\"\n\nimport { cn } from \"../../../utils/cn\"\nimport { buttonSurfaceClasses, outlineBorderClasses, splitDividerColorClasses } from \"./button-styles\"\n\n// Default layout: centered single content area, padding/gap on the button itself.\nconst buttonVariants = cva(\n [\n \"relative inline-flex items-center justify-center gap-[var(--spacing-system-xsf)]\",\n \"rounded-md whitespace-nowrap\",\n \"transition-colors duration-200\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-focus\",\n \"disabled:pointer-events-none\",\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:h-5 [&_svg]:w-5\",\n ],\n {\n variants: {\n variant: {\n accent: buttonSurfaceClasses.accent,\n outline: cn(buttonSurfaceClasses.outline, outlineBorderClasses),\n transparent: buttonSurfaceClasses.transparent,\n destructive: buttonSurfaceClasses.destructive,\n warning: buttonSurfaceClasses.warning,\n glyph: buttonSurfaceClasses.glyph,\n overlay: buttonSurfaceClasses.overlay,\n },\n size: {\n default: \"py-[var(--spacing-system-sf)] px-[var(--spacing-system-m)] text-h3 md:h-12 h-11\",\n small: \"p-[var(--spacing-system-xs)] text-h5 h-6 md:h-8\",\n \"small-legacy\": \"py-[var(--spacing-system-xs)] px-[var(--spacing-system-m)] h-10 text-[14px] font-bold\", // Temporary alias for \"small\" — deprecated; grep size=\"small-legacy\" (lib + hub) and migrate the remaining consumers before removal\n // 24px pill for slim strips (announcement/promo bars, inline banner\n // actions — Primer banner / Polaris banner / Vercel-bar convention).\n // The label matches the strip's MESSAGE type ramp exactly (DM Sans\n // regular, 13px -> md:14px, snug leading — the announcement bar's\n // subtitle styling): in-strip CTAs must never read louder than the\n // message beside them, so this deliberately uses neither the\n // mono-uppercase control style of \"small\" nor a heavier weight.\n // Pinned h-6 across breakpoints (24px = the WCAG 2.5.8 target-size\n // floor) with horizontal-dominant padding and a 14px glyph.\n compact: \"py-0 px-[var(--spacing-system-sf)] text-h6 font-normal h-6 [&_svg]:h-3.5 [&_svg]:w-3.5\",\n icon: \"p-[var(--spacing-system-sf)] h-11 w-11 md:h-12 md:w-12 [&_svg]:h-4 [&_svg]:w-4 md:[&_svg]:h-6 md:[&_svg]:w-6\",\n // Quiet 32px icon target with a 16px glyph, fixed across breakpoints\n // (Carbon ghost sm / Primer medium / shadcn icon-sm all pin 32px;\n // ≥ the 24px WCAG 2.5.8 target floor). For icon actions that read as\n // metadata rather than CTAs — author-page social rows, share rows.\n // Pair with variant=\"transparent\" for the ghost treatment.\n \"icon-sm\": \"p-[var(--spacing-system-xxs)] h-8 w-8 [&_svg]:h-4 [&_svg]:w-4\",\n // Bare 56px media glyph (play / unmute over video). A size variant so\n // hosts stop re-implementing a <button> to escape the 20px svg cap.\n \"icon-glyph\": \"p-0 h-14 w-14 [&_svg]:h-14 [&_svg]:w-14\",\n },\n fullWidth: {\n true: \"w-full\",\n false: \"\",\n },\n noPaddingX: {\n true: \"px-0\",\n false: \"\",\n },\n },\n compoundVariants: [\n { size: \"small\", class: \"[&_svg]:h-4 [&_svg]:w-4\" },\n ],\n defaultVariants: {\n variant: \"accent\",\n size: \"default\",\n fullWidth: false,\n noPaddingX: false,\n },\n }\n)\n\n// Split layout (used when `splitIcon` is provided): outer button has no padding;\n// inner slots own padding/gap so the divider can span full button height.\nconst splitShellVariants = cva(\n [\n \"group relative inline-flex items-stretch overflow-hidden rounded-md whitespace-nowrap\",\n \"transition-colors duration-200\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-focus\",\n \"disabled:pointer-events-none\",\n ],\n {\n variants: {\n variant: {\n accent: buttonSurfaceClasses.accent,\n outline: cn(buttonSurfaceClasses.outline, outlineBorderClasses),\n transparent: buttonSurfaceClasses.transparent,\n destructive: buttonSurfaceClasses.destructive,\n warning: buttonSurfaceClasses.warning,\n },\n size: {\n default: \"h-12 text-h3\",\n small: \"h-6 md:h-8 text-h5\",\n },\n fullWidth: { true: \"w-full\", false: \"\" },\n },\n defaultVariants: { variant: \"accent\", size: \"default\", fullWidth: false },\n }\n)\n\nconst splitSlotVariants = cva(\n [\"inline-flex items-center justify-center\", \"[&_svg]:shrink-0 [&_svg]:h-5 [&_svg]:w-5\"],\n {\n variants: {\n slot: {\n main: \"gap-[var(--spacing-system-xsf)]\",\n icon: \"border-l\",\n },\n size: { default: \"\", small: \"[&_svg]:h-4 [&_svg]:w-4\" },\n variant: { accent: \"\", outline: \"\", transparent: \"\", destructive: \"\", warning: \"\" },\n },\n compoundVariants: [\n { slot: \"main\", size: \"default\", class: \"px-[var(--spacing-system-m)] py-[var(--spacing-system-sf)]\" },\n { slot: \"main\", size: \"small\", class: \"px-[var(--spacing-system-xs)]\" },\n { slot: \"icon\", size: \"default\", class: \"w-10\" },\n { slot: \"icon\", size: \"small\", class: \"w-6 md:w-8\" },\n { slot: \"icon\", variant: \"accent\", class: cn(\n splitDividerColorClasses.accent,\n \"group-disabled:border-ods-disabled group-aria-disabled:border-ods-disabled\",\n ) },\n { slot: \"icon\", variant: \"outline\", class: splitDividerColorClasses.outline },\n { slot: \"icon\", variant: \"transparent\", class: splitDividerColorClasses.transparent },\n { slot: \"icon\", variant: \"destructive\", class: cn(\n splitDividerColorClasses.destructive,\n \"group-disabled:border-ods-disabled group-aria-disabled:border-ods-disabled\",\n ) },\n { slot: \"icon\", variant: \"warning\", class: cn(\n splitDividerColorClasses.warning,\n \"group-disabled:border-ods-disabled group-aria-disabled:border-ods-disabled\",\n ) },\n ],\n defaultVariants: { slot: \"main\", size: \"default\", variant: \"accent\" },\n }\n)\n\n/** @deprecated Use `size=\"small\"` instead. Temporary alias kept for backward compatibility; will be removed in the future. */\ntype DeprecatedButtonSize = \"small-legacy\"\n\ntype ButtonSize = Exclude<VariantProps<typeof buttonVariants>[\"size\"], \"small-legacy\" | null | undefined> | DeprecatedButtonSize\n\ninterface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n Omit<VariantProps<typeof buttonVariants>, \"size\"> {\n asChild?: boolean\n href?: string\n openInNewTab?: boolean\n prefetch?: boolean\n /**\n * Pre-resolved anchor bundle (from `useNavLink({ href, targetPlatform })`).\n * When set, renders the Button as `<Link>` with `href` / `target` / `rel`\n * / `onClick` spread from this object. Lets callers thread the unified\n * nav decision directly without `<Button asChild><a {...linkProps}/>`\n * gymnastics. Wins over the separate `href` / `openInNewTab` props.\n */\n linkProps?: {\n href: string\n target?: '_blank'\n rel?: 'noopener noreferrer'\n onClick?: React.MouseEventHandler<HTMLAnchorElement>\n } | null\n leftIcon?: React.ReactNode\n rightIcon?: React.ReactNode\n /**\n * Renders a vertical divider and trailing icon area inside the button.\n * The whole button stays a single click target — the icon is decorative\n * (`aria-hidden`). For two independent click targets, use `<SplitButton>`.\n * Only honored when `size` is `\"default\"` or `\"small\"`.\n */\n splitIcon?: React.ReactNode\n loading?: boolean\n size?: ButtonSize\n}\n\nconst Spinner = () => (\n <svg className=\"animate-spin\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n)\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n className,\n variant,\n size,\n fullWidth,\n noPaddingX,\n asChild,\n href,\n openInNewTab,\n prefetch,\n linkProps,\n leftIcon,\n rightIcon,\n splitIcon,\n loading,\n children,\n disabled,\n onClick,\n ...props\n },\n ref,\n) {\n const isDisabled = disabled || loading\n\n // splitIcon is only supported for default/small sizes. With other sizes\n // (icon, small-legacy) we silently fall back to the normal layout.\n const useSplitLayout = !!splitIcon && (size === \"default\" || size === \"small\" || size === undefined)\n\n if (useSplitLayout) {\n const safeSize = (size ?? \"default\") as \"default\" | \"small\"\n const safeVariant = (variant ?? \"accent\") as \"accent\" | \"outline\" | \"transparent\" | \"destructive\" | \"warning\"\n const shellClasses = cn(\n splitShellVariants({ variant: safeVariant, size: safeSize, fullWidth }),\n className,\n )\n const mainSlotClass = splitSlotVariants({ slot: \"main\", size: safeSize, variant: safeVariant })\n const iconSlotClass = splitSlotVariants({ slot: \"icon\", size: safeSize, variant: safeVariant })\n\n const splitContent = (\n <>\n <span className={cn(\"contents\", loading && \"invisible\")}>\n <span className={mainSlotClass}>\n {leftIcon && <span className=\"inline-flex items-center\">{leftIcon}</span>}\n {children}\n {rightIcon && <span className=\"inline-flex items-center\">{rightIcon}</span>}\n </span>\n <span aria-hidden=\"true\" className={iconSlotClass}>\n {splitIcon}\n </span>\n </span>\n {loading && (\n <span className=\"absolute inset-0 inline-flex items-center justify-center text-ods-text-primary\">\n <Spinner />\n </span>\n )}\n </>\n )\n\n // `linkProps` (the pre-resolved bundle from `useNavLink({ href, targetPlatform })`)\n // wins over the legacy `href` + `openInNewTab` props so callers can thread\n // the unified nav decision directly. Either path produces the same `<Link>`.\n const splitAnchor = linkProps ?? (href ? {\n href,\n target: openInNewTab ? '_blank' as const : undefined,\n rel: openInNewTab ? 'noopener noreferrer' as const : undefined,\n onClick: onClick as unknown as React.MouseEventHandler<HTMLAnchorElement> | undefined,\n } : null)\n if (splitAnchor) {\n return (\n <Link\n href={splitAnchor.href}\n prefetch={prefetch}\n target={splitAnchor.target}\n rel={splitAnchor.rel}\n // The Link branches don't spread {...props} (button attrs don't\n // belong on an anchor), but the accessible name MUST survive —\n // icon-only link buttons have no text content.\n aria-label={props['aria-label']}\n aria-disabled={isDisabled || undefined}\n tabIndex={isDisabled ? -1 : undefined}\n className={cn(shellClasses, isDisabled && \"pointer-events-none\")}\n onClick={splitAnchor.onClick}\n >\n {splitContent}\n </Link>\n )\n }\n\n return (\n <button\n ref={ref}\n className={shellClasses}\n disabled={isDisabled}\n onClick={onClick}\n {...props}\n >\n {splitContent}\n </button>\n )\n }\n\n const classes = cn(buttonVariants({ variant, size, fullWidth, noPaddingX }), className)\n\n // asChild: consumer fully controls the rendered element; we just stamp our classes.\n if (asChild) {\n return (\n <Slot ref={ref} className={classes} {...props}>\n {children}\n </Slot>\n )\n }\n\n // Real content stays in layout (preserving width) but goes invisible while loading.\n // The spinner is absolutely positioned so it never shifts the button's size.\n const content = (\n <>\n <span className={cn(\"contents\", loading && \"invisible\")}>\n {leftIcon && <span className=\"inline-flex items-center\">{leftIcon}</span>}\n {children}\n {rightIcon && <span className=\"inline-flex items-center\">{rightIcon}</span>}\n </span>\n {loading && (\n <span className=\"absolute inset-0 inline-flex items-center justify-center text-ods-text-primary\">\n <Spinner />\n </span>\n )}\n </>\n )\n\n // Same `linkProps`-wins-over-href resolution as the splitIcon branch.\n const anchor = linkProps ?? (href ? {\n href,\n target: openInNewTab ? '_blank' as const : undefined,\n rel: openInNewTab ? 'noopener noreferrer' as const : undefined,\n onClick: onClick as unknown as React.MouseEventHandler<HTMLAnchorElement> | undefined,\n } : null)\n if (anchor) {\n return (\n <Link\n href={anchor.href}\n prefetch={prefetch}\n target={anchor.target}\n rel={anchor.rel}\n // See the splitAnchor branch — keep the accessible name on the\n // anchor render (icon-only link buttons have no text content).\n aria-label={props['aria-label']}\n aria-disabled={isDisabled || undefined}\n tabIndex={isDisabled ? -1 : undefined}\n className={cn(classes, isDisabled && \"pointer-events-none\")}\n onClick={anchor.onClick}\n >\n {content}\n </Link>\n )\n }\n\n return (\n <button\n ref={ref}\n className={classes}\n disabled={isDisabled}\n onClick={onClick}\n {...props}\n >\n {content}\n </button>\n )\n})\n\nexport { Button, buttonVariants, type ButtonProps }\n","\"use client\"\n\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport Link from \"../../../embed-shims/next-link\"\nimport React from \"react\"\n\nimport { cn } from \"../../../utils/cn\"\nimport { buttonSurfaceClasses, splitDividerColorClasses } from \"./button-styles\"\n\n// Two independent interactive halves: each a `<button>` or `<a>`. The seam is\n// a 1px border on the left edge of the icon half, colored per variant. For a\n// single-target variant (decorative trailing icon), use `<Button splitIcon>`.\n\nconst splitHalfBase = [\n \"relative inline-flex items-center justify-center gap-[var(--spacing-system-xsf)]\",\n \"whitespace-nowrap transition-colors duration-200\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-focus focus-visible:z-10\",\n \"disabled:pointer-events-none\",\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0\",\n]\n\nconst splitHalfVariants = cva(splitHalfBase, {\n variants: {\n variant: {\n accent: buttonSurfaceClasses.accent,\n outline: buttonSurfaceClasses.outline, // Outline border lives in compoundVariants so we can omit the seam edge.\n transparent: buttonSurfaceClasses.transparent,\n destructive: buttonSurfaceClasses.destructive,\n warning: buttonSurfaceClasses.warning,\n },\n size: {\n default: \"h-10 md:h-12 px-[var(--spacing-system-m)] py-[var(--spacing-system-sf)] text-h3 [&_svg]:h-4 [&_svg]:w-4 md:[&_svg]:h-6 md:[&_svg]:w-6\",\n small: \"h-6 md:h-8 px-[var(--spacing-system-xs)] text-h5 [&_svg]:h-3 [&_svg]:w-3 md:[&_svg]:h-4 md:[&_svg]:w-4\",\n },\n side: { main: \"\", icon: \"\" },\n soloOnMobile: { true: \"\", false: \"\" },\n },\n compoundVariants: [\n // Rounded corners + per-variant seam. The icon-side's left border is the divider.\n { variant: \"accent\", side: \"main\", class: \"rounded-l-md\" },\n { variant: \"accent\", side: \"icon\", class: cn(\n \"rounded-r-md border-l\",\n splitDividerColorClasses.accent,\n \"disabled:border-ods-disabled aria-disabled:border-ods-disabled\",\n ) },\n { variant: \"destructive\", side: \"main\", class: \"rounded-l-md\" },\n { variant: \"destructive\", side: \"icon\", class: cn(\n \"rounded-r-md border-l\",\n splitDividerColorClasses.destructive,\n \"disabled:border-ods-disabled aria-disabled:border-ods-disabled\",\n ) },\n { variant: \"warning\", side: \"main\", class: \"rounded-l-md\" },\n { variant: \"warning\", side: \"icon\", class: cn(\n \"rounded-r-md border-l\",\n splitDividerColorClasses.warning,\n \"disabled:border-ods-disabled aria-disabled:border-ods-disabled\",\n ) },\n { variant: \"outline\", side: \"main\", class: \"rounded-l-md border-y border-l border-ods-border\" },\n { variant: \"outline\", side: \"icon\", class: \"rounded-r-md border border-ods-border\" },\n { variant: \"transparent\", side: \"main\", class: \"rounded-md\" },\n { variant: \"transparent\", side: \"icon\", class: cn(\"rounded-md\", splitDividerColorClasses.transparent) },\n\n // Icon half: per Figma, narrower than main height (default: 40×48; small: 32×32).\n { side: \"icon\", size: \"default\", class: \"w-10 px-0\" },\n { side: \"icon\", size: \"small\", class: \"w-6 md:w-8 px-0\" },\n\n { side: \"icon\", soloOnMobile: true, class: \"max-md:hidden\" },\n { side: \"main\", soloOnMobile: true, class: \"max-md:rounded-r-md\" },\n { variant: \"outline\", side: \"main\", soloOnMobile: true, class: \"max-md:border-r\" },\n ],\n defaultVariants: { variant: \"accent\", size: \"default\", side: \"main\", soloOnMobile: false },\n})\n\ntype SplitButtonVariant = NonNullable<VariantProps<typeof splitHalfVariants>[\"variant\"]>\ntype SplitButtonSize = NonNullable<VariantProps<typeof splitHalfVariants>[\"size\"]>\n\ninterface SplitButtonIconAction {\n icon: React.ReactNode\n /** The icon half is interactive but has no visible text — needs an accessible name. */\n \"aria-label\": string\n onClick?: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>\n href?: string\n /**\n * Opens `href` with `target=\"_blank\"`. Also marks the half as a new-tab\n * affordance, which hides it below `md` (set it for `onClick` handlers that\n * open a new tab/window themselves).\n */\n openInNewTab?: boolean\n prefetch?: boolean\n disabled?: boolean\n}\n\ninterface SplitButtonProps {\n variant?: SplitButtonVariant\n size?: SplitButtonSize\n fullWidth?: boolean\n className?: string\n\n children: React.ReactNode\n onClick?: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>\n href?: string\n openInNewTab?: boolean\n prefetch?: boolean\n leftIcon?: React.ReactNode\n rightIcon?: React.ReactNode\n /** Disables both halves. Equivalent to `mainDisabled && iconAction.disabled`. */\n disabled?: boolean\n /** Disables only the main half. Combine with `iconAction.disabled` for finer control. */\n mainDisabled?: boolean\n type?: \"button\" | \"submit\" | \"reset\"\n \"aria-label\"?: string\n groupAriaLabel?: string\n\n iconAction: SplitButtonIconAction\n}\n\ninterface HalfOptions {\n variant: SplitButtonVariant\n size: SplitButtonSize\n side: \"main\" | \"icon\"\n soloOnMobile?: boolean\n href?: string\n openInNewTab?: boolean\n prefetch?: boolean\n onClick?: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>\n disabled?: boolean\n /** Stretch this half to fill the group's free space (the icon half stays fixed-width). */\n grow?: boolean\n type?: \"button\" | \"submit\" | \"reset\"\n ariaLabel?: string\n children: React.ReactNode\n}\n\nfunction Half({ variant, size, side, soloOnMobile, href, openInNewTab, prefetch, onClick, disabled, grow, type = \"button\", ariaLabel, children }: HalfOptions) {\n const classes = cn(splitHalfVariants({ variant, size, side, soloOnMobile }), grow && \"flex-1\")\n\n if (href) {\n return (\n <Link\n href={href}\n prefetch={prefetch}\n target={openInNewTab ? \"_blank\" : undefined}\n rel={openInNewTab ? \"noopener noreferrer\" : undefined}\n aria-disabled={disabled || undefined}\n tabIndex={disabled ? -1 : undefined}\n aria-label={ariaLabel}\n className={cn(classes, disabled && \"pointer-events-none\")}\n onClick={onClick as unknown as React.MouseEventHandler<HTMLAnchorElement> | undefined}\n >\n {children}\n </Link>\n )\n }\n\n return (\n <button\n type={type}\n className={classes}\n disabled={disabled}\n aria-label={ariaLabel}\n onClick={onClick as React.MouseEventHandler<HTMLButtonElement>}\n >\n {children}\n </button>\n )\n}\n\nconst SplitButton = React.forwardRef<HTMLDivElement, SplitButtonProps>(function SplitButton(\n {\n variant = \"accent\",\n size = \"default\",\n fullWidth = false,\n className,\n children,\n onClick,\n href,\n openInNewTab,\n prefetch,\n leftIcon,\n rightIcon,\n disabled,\n mainDisabled,\n type,\n iconAction,\n \"aria-label\": ariaLabel,\n groupAriaLabel,\n },\n ref,\n) {\n const soloOnMobile = !!iconAction.openInNewTab\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-label={groupAriaLabel}\n className={cn(\"inline-flex items-stretch\", fullWidth && \"w-full\", className)}\n >\n <Half\n variant={variant}\n size={size}\n side=\"main\"\n soloOnMobile={soloOnMobile}\n href={href}\n openInNewTab={openInNewTab}\n prefetch={prefetch}\n onClick={onClick}\n disabled={disabled || mainDisabled}\n grow={fullWidth}\n type={type}\n ariaLabel={ariaLabel}\n >\n {leftIcon && <span className=\"inline-flex items-center\">{leftIcon}</span>}\n <span>{children}</span>\n {rightIcon && <span className=\"inline-flex items-center\">{rightIcon}</span>}\n </Half>\n <Half\n variant={variant}\n size={size}\n side=\"icon\"\n soloOnMobile={soloOnMobile}\n href={iconAction.href}\n openInNewTab={iconAction.openInNewTab}\n prefetch={iconAction.prefetch}\n onClick={iconAction.onClick}\n disabled={disabled || iconAction.disabled}\n ariaLabel={iconAction[\"aria-label\"]}\n >\n <span className=\"inline-flex items-center\">{iconAction.icon}</span>\n </Half>\n </div>\n )\n})\n\nexport { SplitButton, type SplitButtonProps, type SplitButtonIconAction }\n","export * from './button'\nexport * from './split-button'\n","\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"../../utils/cn\"\n\nexport interface FieldWrapperProps {\n /** Label text displayed above the field */\n label?: string\n /**\n * Status message displayed below the field, on ONE line, ellipsized on\n * overflow (full text via the native `title`).\n *\n * It is positioned OUT OF FLOW (absolute, hanging below the wrapper), so it\n * never changes the field's height when it appears — the same treatment\n * `CheckboxBlock` uses. The trade is that it overlaps whatever sits directly\n * below: a form stacking fields needs at least ~20px of vertical gap (e.g.\n * `gap-[var(--spacing-system-lf)]`) for the message to land in clear space.\n */\n error?: string\n /** Color variant for the message: \"error\" (red), \"warning\" (yellow), \"success\" (green) or \"muted\" (grey) */\n errorVariant?: \"error\" | \"warning\" | \"success\" | \"muted\"\n /** Additional className for the outer wrapper */\n className?: string\n children: React.ReactNode\n}\n\nconst errorVariantClasses = {\n error: \"text-ods-error\",\n warning: \"text-ods-warning\",\n success: \"text-ods-success\",\n muted: \"text-ods-text-secondary\",\n} as const\n\nconst FieldWrapper = React.forwardRef<HTMLDivElement, FieldWrapperProps>(\n ({ label, error, errorVariant = \"error\", className, children }, ref) => {\n const hasChrome = label != null || error != null\n\n return (\n <div ref={ref} className={cn(hasChrome ? \"relative flex w-full flex-col\" : \"contents\", className)}>\n {label && (\n <label className=\"text-h4 text-ods-text-primary mb-1\">\n {label}\n </label>\n )}\n {children}\n {error && (\n <p className={cn(\"absolute bottom-0 left-0 right-0 translate-y-full text-h6 truncate\", errorVariantClasses[errorVariant])} title={error}>\n {error}\n </p>\n )}\n </div>\n )\n }\n)\nFieldWrapper.displayName = \"FieldWrapper\"\n\nexport { FieldWrapper }\n","\"use client\"\n\nimport * as React from \"react\";\n\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { FieldWrapper } from \"./field-wrapper\";\n\nexport interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n /** When true, renders error border & ring */\n invalid?: boolean;\n /** Element displayed at the start (left) of the input */\n startAdornment?: React.ReactNode;\n /** Element displayed at the end (right) of the input */\n endAdornment?: React.ReactNode;\n /** Label text displayed above the input */\n label?: string;\n /** Status message displayed below the input */\n error?: string;\n /** Color variant for the message: \"error\" (red), \"warning\" (yellow), \"success\" (green) or \"muted\" (grey).\n Only \"error\" and \"warning\" mark the field invalid (colored border). */\n errorVariant?: \"error\" | \"warning\" | \"success\" | \"muted\";\n /** When true, shows a loading spinner as end adornment */\n loading?: boolean;\n}\n\nconst invalidBorderClasses = {\n error: \"border-ods-error hover:border-ods-error has-[:focus]:border-ods-error\",\n warning: \"!border-ods-warning hover:!border-ods-warning has-[:focus]:!border-ods-warning\",\n} as const;\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, invalid = false, startAdornment, endAdornment, label, error, errorVariant = \"error\", loading = false, ...props }, ref) => {\n // success/muted are informational — they never paint the invalid border\n const variantIsInvalid = errorVariant === \"error\" || errorVariant === \"warning\"\n const isInvalid = invalid || (!!error && variantIsInvalid)\n\n // Range inputs get a clean slider rendering — no label wrapper, borders, or adornments\n if (type === 'range') {\n const rangeInput = (\n <input\n type=\"range\"\n className={cn(\n \"w-full cursor-pointer appearance-none rounded-full bg-white/30 h-1\",\n // Webkit (Chrome/Safari) thumb\n \"[&::-webkit-slider-thumb]:appearance-none\",\n \"[&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3\",\n \"[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white\",\n \"[&::-webkit-slider-thumb]:cursor-pointer [&::-webkit-slider-thumb]:shadow-sm\",\n // Firefox thumb\n \"[&::-moz-range-thumb]:w-3 [&::-moz-range-thumb]:h-3\",\n \"[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white\",\n \"[&::-moz-range-thumb]:border-0 [&::-moz-range-thumb]:cursor-pointer\",\n // Firefox track\n \"[&::-moz-range-track]:bg-transparent\",\n // Disabled\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n ref={ref}\n {...props}\n />\n )\n return label ? (\n <FieldWrapper label={label} error={error} errorVariant={errorVariant}>\n {rangeInput}\n </FieldWrapper>\n ) : rangeInput\n }\n\n const content = (\n <label\n data-invalid={isInvalid || undefined}\n className={cn(\n // Layout & spacing\n \"flex w-full items-center gap-2 rounded-[6px] border px-3 h-11 md:h-12 cursor-text\",\n // Focus-within states\n \"has-[:focus-visible]:outline-none\",\n \"group\",\n // Animations & touch UX\n \"transition-colors duration-200\",\n // Theme palette\n \"bg-ods-card border-ods-border has-[:focus]:border-ods-accent\",\n // Hover & active (not disabled)\n !props.disabled && \"hover:bg-ods-bg-hover hover:border-ods-border-hover active:bg-ods-bg-active active:border-ods-border-active\",\n // Disabled. The adornments (and any icon inside them) carry their own\n // `text-ods-text-secondary`, so grey them from here — a disabled field\n // must read as one flat colour, not grey text next to a live icon.\n // Scoped to the DIRECT span children (the two adornment wrappers): a\n // descendant rule would also repaint whatever the caller renders INSIDE\n // an adornment, which is passed verbatim precisely so it can own its\n // colour (a `Tag` there went invisible against its own fill).\n props.disabled && \"!cursor-not-allowed bg-ods-bg\",\n \"has-[:disabled]:[&>span]:text-ods-text-disabled has-[:disabled]:[&_svg]:text-ods-text-disabled\",\n // Invalid\n isInvalid && invalidBorderClasses[variantIsInvalid ? (errorVariant as \"error\" | \"warning\") : \"error\"],\n className\n )}\n >\n {startAdornment && (\n <span className=\"text-h6 flex-shrink-0 text-ods-text-secondary transition-colors duration-200 group-has-[:focus]:text-ods-accent group-data-[invalid]:text-ods-error [&_svg]:size-4 md:[&_svg]:size-6\">\n {startAdornment}\n </span>\n )}\n <input\n type={type}\n className={cn(\n // Layout\n \"flex-1 min-w-0 bg-transparent border-none outline-none\",\n // Typography\n \"text-h4\",\n // Colors\n \"text-ods-text-primary placeholder:text-ods-text-secondary\",\n // File input adjustments\n \"file:border-0 file:bg-transparent\",\n // Disabled\n \"disabled:cursor-not-allowed disabled:text-ods-text-disabled disabled:placeholder:text-ods-border\",\n // Touch\n \"touch-manipulation\",\n // Autofill override\n \"[&:-webkit-autofill]:[-webkit-box-shadow:0_0_0_9999px_transparent_inset] [&:-webkit-autofill]:[-webkit-text-fill-color:var(--color-text-primary)] [&:-webkit-autofill]:[caret-color:var(--color-text-primary)] [&:-webkit-autofill]:[transition:background-color_9999s_ease-in-out_0s]\"\n )}\n ref={ref}\n {...props}\n />\n {loading && (\n <Loader2 className=\"animate-spin flex-shrink-0 text-ods-text-secondary size-4 md:size-6\" />\n )}\n {!loading && endAdornment && (\n <span className=\"text-h6 flex-shrink-0 text-ods-text-secondary transition-colors duration-200 group-has-[:focus]:text-ods-accent group-data-[invalid]:text-ods-error [&_svg]:size-4 md:[&_svg]:size-6\">\n {endAdornment}\n </span>\n )}\n </label>\n )\n\n return (\n <FieldWrapper label={label} error={error} errorVariant={errorVariant}>\n {content}\n </FieldWrapper>\n )\n }\n)\nInput.displayName = \"Input\"\n\nexport { Input };\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as CheckboxPrimitive from \"@radix-ui/react-checkbox\"\n\nimport { cn } from \"../../utils/cn\"\nimport { CheckboxCheckmarkIcon } from \"../icons-v2-generated/signs-and-symbols/checkbox-checkmark-icon\"\n\nconst Checkbox = React.forwardRef<\n React.ElementRef<typeof CheckboxPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>\n>(({ className, ...props }, ref) => (\n <CheckboxPrimitive.Root\n ref={ref}\n className={cn(\n \"peer h-4 w-4 shrink-0 rounded-sm border border-ods-border bg-ods-card focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-accent focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-ods-accent data-[state=checked]:border-ods-accent\",\n className\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n className={cn(\"flex items-center justify-center text-ods-text-on-accent\")}\n >\n <CheckboxCheckmarkIcon size={10} />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n))\nCheckbox.displayName = CheckboxPrimitive.Root.displayName\n\nexport { Checkbox }\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\"\nimport { Check, ChevronRight, Circle } from \"lucide-react\"\n\nimport { cn } from \"../../utils/cn\"\nimport { usePortalContainer } from \"./portal-container\"\n\nconst DropdownMenu = DropdownMenuPrimitive.Root\n\nconst DropdownMenuTrigger = DropdownMenuPrimitive.Trigger\n\nconst DropdownMenuGroup = DropdownMenuPrimitive.Group\n\nconst DropdownMenuPortal = DropdownMenuPrimitive.Portal\n\nconst DropdownMenuSub = DropdownMenuPrimitive.Sub\n\nconst DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup\n\nconst DropdownMenuSubTrigger = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean\n }\n>(({ className, inset, children, ...props }, ref) => (\n <DropdownMenuPrimitive.SubTrigger\n ref={ref}\n className={cn(\n \"flex cursor-pointer gap-2 select-none items-center rounded-sm px-2 py-1.5 text-h6 outline-none hover:bg-ods-bg-hover focus:bg-ods-bg-hover data-[state=open]:bg-ods-bg-hover [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n inset && \"pl-8\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRight className=\"ml-auto\" />\n </DropdownMenuPrimitive.SubTrigger>\n))\nDropdownMenuSubTrigger.displayName =\n DropdownMenuPrimitive.SubTrigger.displayName\n\nconst DropdownMenuSubContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.SubContent\n ref={ref}\n className={cn(\n \"z-50 min-w-[8rem] overflow-hidden rounded-md border border-ods-border bg-ods-card p-1 text-ods-text-primary shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className\n )}\n {...props}\n />\n))\nDropdownMenuSubContent.displayName =\n DropdownMenuPrimitive.SubContent.displayName\n\nconst DropdownMenuContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => {\n // Portal into the active container (e.g. a drawer) so the menu inherits its\n // stacking context; falls back to `document.body` when none is provided.\n const container = usePortalContainer()\n return (\n <DropdownMenuPrimitive.Portal container={container ?? undefined}>\n <DropdownMenuPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 min-w-[8rem] overflow-hidden rounded-md border border-ods-border bg-ods-card p-1 text-ods-text-primary shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n )\n})\nDropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName\n\nconst DropdownMenuItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Item\n ref={ref}\n className={cn(\n \"relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-h6 outline-none transition-colors text-ods-text-primary hover:bg-ods-bg-hover hover:text-ods-text-primary focus:bg-ods-bg-hover focus:text-ods-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n inset && \"pl-8\",\n className\n )}\n {...props}\n />\n))\nDropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName\n\nconst DropdownMenuCheckboxItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n <DropdownMenuPrimitive.CheckboxItem\n ref={ref}\n className={cn(\n \"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-h6 outline-none transition-colors text-ods-text-primary hover:bg-ods-bg-hover hover:text-ods-text-primary focus:bg-ods-bg-hover focus:text-ods-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Check className=\"h-4 w-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n))\nDropdownMenuCheckboxItem.displayName =\n DropdownMenuPrimitive.CheckboxItem.displayName\n\nconst DropdownMenuRadioItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n <DropdownMenuPrimitive.RadioItem\n ref={ref}\n className={cn(\n \"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-h6 outline-none transition-colors text-ods-text-primary hover:bg-ods-bg-hover hover:text-ods-text-primary focus:bg-ods-bg-hover focus:text-ods-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className\n )}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Circle className=\"h-2 w-2 fill-ods-accent\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n))\nDropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName\n\nconst DropdownMenuLabel = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Label\n ref={ref}\n className={cn(\n \"px-2 py-1.5 text-h6 font-semibold text-ods-text-secondary\",\n inset && \"pl-8\",\n className\n )}\n {...props}\n />\n))\nDropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName\n\nconst DropdownMenuSeparator = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-ods-border\", className)}\n {...props}\n />\n))\nDropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName\n\nconst DropdownMenuShortcut = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement>) => {\n return (\n <span\n className={cn(\"ml-auto text-h6 text-ods-text-secondary opacity-60\", className)}\n {...props}\n />\n )\n}\nDropdownMenuShortcut.displayName = \"DropdownMenuShortcut\"\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuGroup,\n DropdownMenuPortal,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuRadioGroup,\n}\n","'use client'\n\nimport * as React from 'react'\n\n/**\n * The DOM node that Radix overlays (dropdown menus, tooltips) should portal\n * into, instead of the default `document.body`.\n *\n * Portaling to `document.body` lifts content out of every local stacking\n * context, which forces overlays opened *inside* a high-z surface (e.g. the\n * chat drawer) to escalate their own z-index to compete at the document\n * root. Pointing the portal at a node *inside* that surface instead\n * lets the content inherit the surface's stacking context — small, local\n * z-indices then \"just work\" and no escalation is needed. Radix positions\n * content with `strategy: \"fixed\"`, so it still escapes ancestor\n * `overflow: hidden` clipping regardless of where it is portaled.\n *\n * Default `null` → Radix falls back to `document.body` (unchanged behaviour\n * everywhere a provider isn't present).\n */\nexport const PortalContainerContext = React.createContext<HTMLElement | null>(\n null,\n)\n\n/** Read the active portal container (or `null` to use `document.body`). */\nexport function usePortalContainer(): HTMLElement | null {\n return React.useContext(PortalContainerContext)\n}\n","\"use client\"\n\nimport * as React from 'react'\nimport { cn } from \"../../utils/cn\"\n\ninterface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {\n className?: string\n}\n\nconst Skeleton = React.forwardRef<HTMLDivElement, SkeletonProps>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n \"animate-pulse rounded-md bg-ods-border\",\n className\n )}\n {...props}\n />\n )\n }\n)\nSkeleton.displayName = 'Skeleton'\n\ninterface SkeletonTextProps extends React.HTMLAttributes<HTMLDivElement> {\n lines?: number\n className?: string\n}\n\nconst SkeletonText = React.forwardRef<HTMLDivElement, SkeletonTextProps>(\n ({ lines = 1, className, ...props }, ref) => {\n return (\n <div ref={ref} className={cn(\"space-y-2\", className)} {...props}>\n {Array.from({ length: lines }).map((_, i) => (\n <Skeleton \n key={i} \n className={cn(\n \"h-4\",\n i === lines - 1 && lines > 1 && \"w-3/4\" // Last line shorter for multi-line\n )} \n />\n ))}\n </div>\n )\n }\n)\nSkeletonText.displayName = 'SkeletonText'\n\ninterface SkeletonCardProps extends React.HTMLAttributes<HTMLDivElement> {\n showImage?: boolean\n className?: string\n}\n\nconst SkeletonCard = React.forwardRef<HTMLDivElement, SkeletonCardProps>(\n ({ showImage = false, className, ...props }, ref) => {\n return (\n <div \n ref={ref}\n className={cn(\n \"rounded-lg border border-ods-border overflow-hidden\",\n className\n )}\n {...props}\n >\n {showImage && (\n <Skeleton className=\"h-48 w-full\" />\n )}\n <div className=\"p-6\">\n <Skeleton className=\"h-6 w-3/4 mb-4\" />\n <SkeletonText lines={3} />\n </div>\n </div>\n )\n }\n)\nSkeletonCard.displayName = 'SkeletonCard'\n\ninterface SkeletonGridProps extends React.HTMLAttributes<HTMLDivElement> {\n columns?: number\n items?: number\n showImages?: boolean\n className?: string\n}\n\nconst SkeletonGrid = React.forwardRef<HTMLDivElement, SkeletonGridProps>(\n ({ columns = 3, items = 6, showImages = false, className, ...props }, ref) => {\n return (\n <div \n ref={ref}\n className={cn(\n `grid grid-cols-1 gap-6`,\n columns === 2 && \"md:grid-cols-2\",\n columns === 3 && \"md:grid-cols-3\",\n columns === 4 && \"md:grid-cols-4\",\n className\n )}\n {...props}\n >\n {Array.from({ length: items }).map((_, i) => (\n <SkeletonCard key={i} showImage={showImages} />\n ))}\n </div>\n )\n }\n)\nSkeletonGrid.displayName = 'SkeletonGrid'\n\ninterface SkeletonButtonProps extends React.HTMLAttributes<HTMLDivElement> {\n size?: 'sm' | 'default' | 'lg'\n className?: string\n}\n\nconst SkeletonButton = React.forwardRef<HTMLDivElement, SkeletonButtonProps>(\n ({ size = 'default', className, ...props }, ref) => {\n const sizeClasses = {\n sm: 'h-8 w-20',\n default: 'h-10 w-32',\n lg: 'h-12 w-40'\n }\n \n return (\n <Skeleton \n ref={ref}\n className={cn(\n \"rounded-lg\",\n sizeClasses[size],\n className\n )}\n {...props}\n />\n )\n }\n)\nSkeletonButton.displayName = 'SkeletonButton'\n\ninterface SkeletonHeadingProps extends React.HTMLAttributes<HTMLDivElement> {\n level?: 1 | 2 | 3 | 4 | 5 | 6\n className?: string\n}\n\nconst SkeletonHeading = React.forwardRef<HTMLDivElement, SkeletonHeadingProps>(\n ({ level = 1, className, ...props }, ref) => {\n const heightClasses = {\n 1: 'h-12',\n 2: 'h-10',\n 3: 'h-8',\n 4: 'h-7',\n 5: 'h-6',\n 6: 'h-5'\n }\n \n return (\n <Skeleton \n ref={ref}\n className={cn(\n heightClasses[level],\n \"w-3/4\",\n className\n )}\n {...props}\n />\n )\n }\n)\nSkeletonHeading.displayName = 'SkeletonHeading'\n\ninterface SkeletonListProps extends React.HTMLAttributes<HTMLDivElement> {\n items?: number\n className?: string\n}\n\nconst SkeletonList = React.forwardRef<HTMLDivElement, SkeletonListProps>(\n ({ items = 5, className, ...props }, ref) => {\n return (\n <div ref={ref} className={cn(\"space-y-3\", className)} {...props}>\n {Array.from({ length: items }).map((_, i) => (\n <div key={i} className=\"flex items-center gap-3\">\n <Skeleton className=\"h-10 w-10 rounded-full flex-shrink-0\" />\n <div className=\"flex-1\">\n <Skeleton className=\"h-4 w-1/3 mb-1\" />\n <Skeleton className=\"h-3 w-1/2\" />\n </div>\n </div>\n ))}\n </div>\n )\n }\n)\nSkeletonList.displayName = 'SkeletonList'\n\ninterface SkeletonNavigationProps extends React.HTMLAttributes<HTMLDivElement> {\n items?: number\n className?: string\n}\n\nconst SkeletonNavigation = React.forwardRef<HTMLDivElement, SkeletonNavigationProps>(\n ({ items = 6, className, ...props }, ref) => {\n return (\n <div ref={ref} className={cn(\"flex items-center gap-6\", className)} {...props}>\n {Array.from({ length: items }).map((_, i) => (\n <Skeleton key={i} className=\"h-5 w-20\" />\n ))}\n </div>\n )\n }\n)\nSkeletonNavigation.displayName = 'SkeletonNavigation'\n\nexport { \n Skeleton,\n SkeletonText,\n SkeletonCard,\n SkeletonGrid,\n SkeletonButton,\n SkeletonHeading,\n SkeletonList,\n SkeletonNavigation\n}"],"mappings":";;;;;;;;;;;;;;;;;AAAA,IAKa,sBA0BA,sBAIA;AAnCb;AAAA;AAAA;AAKO,IAAM,uBAAuB;AAAA,MAClC,QACE;AAAA,MACF,SACE;AAAA,MACF,aACE;AAAA,MACF,aACE;AAAA,MACF,SACE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMF,OACE;AAAA;AAAA;AAAA;AAAA;AAAA,MAKF,SACE;AAAA,IACJ;AAEO,IAAM,uBACX;AAGK,IAAM,2BAA2B;AAAA,MACtC,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,aAAa;AAAA,MACb,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA;AAAA;;;ACvCA,SAAS,YAAY;AACrB,SAAS,WAA8B;AAEvC,OAAOA,YAAW;AA8KhB,SAkDI,UAjDF,OAAAC,MADF,QAAAC,aAAA;AAnLF,IAWM,gBAoEA,oBA0BA,mBAyEA,SAWA;AA7LN;AAAA;AAAA;AAAA;AAIA;AAGA;AACA;AAGA,IAAM,iBAAiB;AAAA,MACrB;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,QACE,UAAU;AAAA,UACR,SAAS;AAAA,YACP,QAAQ,qBAAqB;AAAA,YAC7B,SAAS,GAAG,qBAAqB,SAAS,oBAAoB;AAAA,YAC9D,aAAa,qBAAqB;AAAA,YAClC,aAAa,qBAAqB;AAAA,YAClC,SAAS,qBAAqB;AAAA,YAC9B,OAAO,qBAAqB;AAAA,YAC5B,SAAS,qBAAqB;AAAA,UAChC;AAAA,UACA,MAAM;AAAA,YACJ,SAAS;AAAA,YACT,OAAO;AAAA,YACP,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAUhB,SAAS;AAAA,YACT,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAMN,WAAW;AAAA;AAAA;AAAA,YAGX,cAAc;AAAA,UAChB;AAAA,UACA,WAAW;AAAA,YACT,MAAM;AAAA,YACN,OAAO;AAAA,UACT;AAAA,UACA,YAAY;AAAA,YACV,MAAM;AAAA,YACN,OAAO;AAAA,UACT;AAAA,QACF;AAAA,QACA,kBAAkB;AAAA,UAChB,EAAE,MAAM,SAAS,OAAO,0BAA0B;AAAA,QACpD;AAAA,QACA,iBAAiB;AAAA,UACf,SAAS;AAAA,UACT,MAAM;AAAA,UACN,WAAW;AAAA,UACX,YAAY;AAAA,QACd;AAAA,MACF;AAAA,IACF;AAIA,IAAM,qBAAqB;AAAA,MACzB;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,QACE,UAAU;AAAA,UACR,SAAS;AAAA,YACP,QAAQ,qBAAqB;AAAA,YAC7B,SAAS,GAAG,qBAAqB,SAAS,oBAAoB;AAAA,YAC9D,aAAa,qBAAqB;AAAA,YAClC,aAAa,qBAAqB;AAAA,YAClC,SAAS,qBAAqB;AAAA,UAChC;AAAA,UACA,MAAM;AAAA,YACJ,SAAS;AAAA,YACT,OAAO;AAAA,UACT;AAAA,UACA,WAAW,EAAE,MAAM,UAAU,OAAO,GAAG;AAAA,QACzC;AAAA,QACA,iBAAiB,EAAE,SAAS,UAAU,MAAM,WAAW,WAAW,MAAM;AAAA,MAC1E;AAAA,IACF;AAEA,IAAM,oBAAoB;AAAA,MACxB,CAAC,2CAA2C,0CAA0C;AAAA,MACtF;AAAA,QACE,UAAU;AAAA,UACR,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,MAAM;AAAA,UACR;AAAA,UACA,MAAM,EAAE,SAAS,IAAI,OAAO,0BAA0B;AAAA,UACtD,SAAS,EAAE,QAAQ,IAAI,SAAS,IAAI,aAAa,IAAI,aAAa,IAAI,SAAS,GAAG;AAAA,QACpF;AAAA,QACA,kBAAkB;AAAA,UAChB,EAAE,MAAM,QAAQ,MAAM,WAAW,OAAO,6DAA6D;AAAA,UACrG,EAAE,MAAM,QAAQ,MAAM,SAAS,OAAO,gCAAgC;AAAA,UACtE,EAAE,MAAM,QAAQ,MAAM,WAAW,OAAO,OAAO;AAAA,UAC/C,EAAE,MAAM,QAAQ,MAAM,SAAS,OAAO,aAAa;AAAA,UACnD,EAAE,MAAM,QAAQ,SAAS,UAAU,OAAO;AAAA,YACxC,yBAAyB;AAAA,YACzB;AAAA,UACF,EAAE;AAAA,UACF,EAAE,MAAM,QAAQ,SAAS,WAAW,OAAO,yBAAyB,QAAQ;AAAA,UAC5E,EAAE,MAAM,QAAQ,SAAS,eAAe,OAAO,yBAAyB,YAAY;AAAA,UACpF,EAAE,MAAM,QAAQ,SAAS,eAAe,OAAO;AAAA,YAC7C,yBAAyB;AAAA,YACzB;AAAA,UACF,EAAE;AAAA,UACF,EAAE,MAAM,QAAQ,SAAS,WAAW,OAAO;AAAA,YACzC,yBAAyB;AAAA,YACzB;AAAA,UACF,EAAE;AAAA,QACJ;AAAA,QACA,iBAAiB,EAAE,MAAM,QAAQ,MAAM,WAAW,SAAS,SAAS;AAAA,MACtE;AAAA,IACF;AAwCA,IAAM,UAAU,MACd,gBAAAA,MAAC,SAAI,WAAU,gBAAe,OAAM,8BAA6B,MAAK,QAAO,SAAQ,aAAY,eAAY,QAC3G;AAAA,sBAAAD,KAAC,YAAO,WAAU,cAAa,IAAG,MAAK,IAAG,MAAK,GAAE,MAAK,QAAO,gBAAe,aAAY,KAAI;AAAA,MAC5F,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,MAAK;AAAA,UACL,GAAE;AAAA;AAAA,MACJ;AAAA,OACF;AAGF,IAAM,SAASD,OAAM,WAA2C,SAASG,QACvE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IACL,GACA,KACA;AACA,YAAM,aAAa,YAAY;AAI/B,YAAM,iBAAiB,CAAC,CAAC,cAAc,SAAS,aAAa,SAAS,WAAW,SAAS;AAE1F,UAAI,gBAAgB;AAClB,cAAM,WAAY,QAAQ;AAC1B,cAAM,cAAe,WAAW;AAChC,cAAM,eAAe;AAAA,UACnB,mBAAmB,EAAE,SAAS,aAAa,MAAM,UAAU,UAAU,CAAC;AAAA,UACtE;AAAA,QACF;AACA,cAAM,gBAAgB,kBAAkB,EAAE,MAAM,QAAQ,MAAM,UAAU,SAAS,YAAY,CAAC;AAC9F,cAAM,gBAAgB,kBAAkB,EAAE,MAAM,QAAQ,MAAM,UAAU,SAAS,YAAY,CAAC;AAE9F,cAAM,eACJ,gBAAAD,MAAA,YACE;AAAA,0BAAAA,MAAC,UAAK,WAAW,GAAG,YAAY,WAAW,WAAW,GACpD;AAAA,4BAAAA,MAAC,UAAK,WAAW,eACd;AAAA,0BAAY,gBAAAD,KAAC,UAAK,WAAU,4BAA4B,oBAAS;AAAA,cACjE;AAAA,cACA,aAAa,gBAAAA,KAAC,UAAK,WAAU,4BAA4B,qBAAU;AAAA,eACtE;AAAA,YACA,gBAAAA,KAAC,UAAK,eAAY,QAAO,WAAW,eACjC,qBACH;AAAA,aACF;AAAA,UACC,WACC,gBAAAA,KAAC,UAAK,WAAU,kFACd,0BAAAA,KAAC,WAAQ,GACX;AAAA,WAEJ;AAMF,cAAM,cAAc,cAAc,OAAO;AAAA,UACvC;AAAA,UACA,QAAQ,eAAe,WAAoB;AAAA,UAC3C,KAAK,eAAe,wBAAiC;AAAA,UACrD;AAAA,QACF,IAAI;AACJ,YAAI,aAAa;AACf,iBACE,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAM,YAAY;AAAA,cAClB;AAAA,cACA,QAAQ,YAAY;AAAA,cACpB,KAAK,YAAY;AAAA,cAIjB,cAAY,MAAM,YAAY;AAAA,cAC9B,iBAAe,cAAc;AAAA,cAC7B,UAAU,aAAa,KAAK;AAAA,cAC5B,WAAW,GAAG,cAAc,cAAc,qBAAqB;AAAA,cAC/D,SAAS,YAAY;AAAA,cAEpB;AAAA;AAAA,UACH;AAAA,QAEJ;AAEA,eACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,WAAW;AAAA,YACX,UAAU;AAAA,YACV;AAAA,YACC,GAAG;AAAA,YAEH;AAAA;AAAA,QACH;AAAA,MAEJ;AAEA,YAAM,UAAU,GAAG,eAAe,EAAE,SAAS,MAAM,WAAW,WAAW,CAAC,GAAG,SAAS;AAGtF,UAAI,SAAS;AACX,eACE,gBAAAA,KAAC,QAAK,KAAU,WAAW,SAAU,GAAG,OACrC,UACH;AAAA,MAEJ;AAIA,YAAM,UACJ,gBAAAC,MAAA,YACE;AAAA,wBAAAA,MAAC,UAAK,WAAW,GAAG,YAAY,WAAW,WAAW,GACnD;AAAA,sBAAY,gBAAAD,KAAC,UAAK,WAAU,4BAA4B,oBAAS;AAAA,UACjE;AAAA,UACA,aAAa,gBAAAA,KAAC,UAAK,WAAU,4BAA4B,qBAAU;AAAA,WACtE;AAAA,QACC,WACC,gBAAAA,KAAC,UAAK,WAAU,kFACd,0BAAAA,KAAC,WAAQ,GACX;AAAA,SAEJ;AAIF,YAAM,SAAS,cAAc,OAAO;AAAA,QAClC;AAAA,QACA,QAAQ,eAAe,WAAoB;AAAA,QAC3C,KAAK,eAAe,wBAAiC;AAAA,QACrD;AAAA,MACF,IAAI;AACJ,UAAI,QAAQ;AACV,eACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,OAAO;AAAA,YACb;AAAA,YACA,QAAQ,OAAO;AAAA,YACf,KAAK,OAAO;AAAA,YAGZ,cAAY,MAAM,YAAY;AAAA,YAC9B,iBAAe,cAAc;AAAA,YAC7B,UAAU,aAAa,KAAK;AAAA,YAC5B,WAAW,GAAG,SAAS,cAAc,qBAAqB;AAAA,YAC1D,SAAS,OAAO;AAAA,YAEf;AAAA;AAAA,QACH;AAAA,MAEJ;AAEA,aACE,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,WAAW;AAAA,UACX,UAAU;AAAA,UACV;AAAA,UACC,GAAG;AAAA,UAEH;AAAA;AAAA,MACH;AAAA,IAEJ,CAAC;AAAA;AAAA;;;ACnWD,SAAS,OAAAG,YAA8B;AAEvC,OAAOC,YAAW;AAsIZ,gBAAAC,MA4DA,QAAAC,aA5DA;AALN,SAAS,KAAK,EAAE,SAAS,MAAM,MAAM,cAAc,MAAM,cAAc,UAAU,SAAS,UAAU,MAAM,OAAO,UAAU,WAAW,SAAS,GAAgB;AAC7J,QAAM,UAAU,GAAG,kBAAkB,EAAE,SAAS,MAAM,MAAM,aAAa,CAAC,GAAG,QAAQ,QAAQ;AAE7F,MAAI,MAAM;AACR,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,QAAQ,eAAe,WAAW;AAAA,QAClC,KAAK,eAAe,wBAAwB;AAAA,QAC5C,iBAAe,YAAY;AAAA,QAC3B,UAAU,WAAW,KAAK;AAAA,QAC1B,cAAY;AAAA,QACZ,WAAW,GAAG,SAAS,YAAY,qBAAqB;AAAA,QACxD;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW;AAAA,MACX;AAAA,MACA,cAAY;AAAA,MACZ;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AArKA,IAaM,eAQA,mBAkJA;AAvKN;AAAA;AAAA;AAAA;AAGA;AAGA;AACA;AAMA,IAAM,gBAAgB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,IAAM,oBAAoBF,KAAI,eAAe;AAAA,MAC3C,UAAU;AAAA,QACR,SAAS;AAAA,UACP,QAAQ,qBAAqB;AAAA,UAC7B,SAAS,qBAAqB;AAAA;AAAA,UAC9B,aAAa,qBAAqB;AAAA,UAClC,aAAa,qBAAqB;AAAA,UAClC,SAAS,qBAAqB;AAAA,QAChC;AAAA,QACA,MAAM;AAAA,UACJ,SAAS;AAAA,UACT,OAAO;AAAA,QACT;AAAA,QACA,MAAM,EAAE,MAAM,IAAI,MAAM,GAAG;AAAA,QAC3B,cAAc,EAAE,MAAM,IAAI,OAAO,GAAG;AAAA,MACtC;AAAA,MACA,kBAAkB;AAAA;AAAA,QAEhB,EAAE,SAAS,UAAU,MAAM,QAAQ,OAAO,eAAe;AAAA,QACzD,EAAE,SAAS,UAAU,MAAM,QAAQ,OAAO;AAAA,UACxC;AAAA,UACA,yBAAyB;AAAA,UACzB;AAAA,QACF,EAAE;AAAA,QACF,EAAE,SAAS,eAAe,MAAM,QAAQ,OAAO,eAAe;AAAA,QAC9D,EAAE,SAAS,eAAe,MAAM,QAAQ,OAAO;AAAA,UAC7C;AAAA,UACA,yBAAyB;AAAA,UACzB;AAAA,QACF,EAAE;AAAA,QACF,EAAE,SAAS,WAAW,MAAM,QAAQ,OAAO,eAAe;AAAA,QAC1D,EAAE,SAAS,WAAW,MAAM,QAAQ,OAAO;AAAA,UACzC;AAAA,UACA,yBAAyB;AAAA,UACzB;AAAA,QACF,EAAE;AAAA,QACF,EAAE,SAAS,WAAW,MAAM,QAAQ,OAAO,mDAAmD;AAAA,QAC9F,EAAE,SAAS,WAAW,MAAM,QAAQ,OAAO,wCAAwC;AAAA,QACnF,EAAE,SAAS,eAAe,MAAM,QAAQ,OAAO,aAAa;AAAA,QAC5D,EAAE,SAAS,eAAe,MAAM,QAAQ,OAAO,GAAG,cAAc,yBAAyB,WAAW,EAAE;AAAA;AAAA,QAGtG,EAAE,MAAM,QAAQ,MAAM,WAAW,OAAO,YAAY;AAAA,QACpD,EAAE,MAAM,QAAQ,MAAM,SAAS,OAAO,kBAAkB;AAAA,QAExD,EAAE,MAAM,QAAQ,cAAc,MAAM,OAAO,gBAAgB;AAAA,QAC3D,EAAE,MAAM,QAAQ,cAAc,MAAM,OAAO,sBAAsB;AAAA,QACjE,EAAE,SAAS,WAAW,MAAM,QAAQ,cAAc,MAAM,OAAO,kBAAkB;AAAA,MACnF;AAAA,MACA,iBAAiB,EAAE,SAAS,UAAU,MAAM,WAAW,MAAM,QAAQ,cAAc,MAAM;AAAA,IAC3F,CAAC;AAgGD,IAAM,cAAcC,OAAM,WAA6C,SAASG,aAC9E;AAAA,MACE,UAAU;AAAA,MACV,OAAO;AAAA,MACP,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc;AAAA,MACd;AAAA,IACF,GACA,KACA;AACA,YAAM,eAAe,CAAC,CAAC,WAAW;AAElC,aACE,gBAAAD;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,MAAK;AAAA,UACL,cAAY;AAAA,UACZ,WAAW,GAAG,6BAA6B,aAAa,UAAU,SAAS;AAAA,UAE3E;AAAA,4BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC;AAAA,gBACA;AAAA,gBACA,MAAK;AAAA,gBACL;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,UAAU,YAAY;AAAA,gBACtB,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBAEC;AAAA,8BAAY,gBAAAD,KAAC,UAAK,WAAU,4BAA4B,oBAAS;AAAA,kBAClE,gBAAAA,KAAC,UAAM,UAAS;AAAA,kBACf,aAAa,gBAAAA,KAAC,UAAK,WAAU,4BAA4B,qBAAU;AAAA;AAAA;AAAA,YACtE;AAAA,YACA,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC;AAAA,gBACA;AAAA,gBACA,MAAK;AAAA,gBACL;AAAA,gBACA,MAAM,WAAW;AAAA,gBACjB,cAAc,WAAW;AAAA,gBACzB,UAAU,WAAW;AAAA,gBACrB,SAAS,WAAW;AAAA,gBACpB,UAAU,YAAY,WAAW;AAAA,gBACjC,WAAW,WAAW,YAAY;AAAA,gBAElC,0BAAAA,KAAC,UAAK,WAAU,4BAA4B,qBAAW,MAAK;AAAA;AAAA,YAC9D;AAAA;AAAA;AAAA,MACF;AAAA,IAEJ,CAAC;AAAA;AAAA;;;ACxOD,IAAAG,eAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;;ACEA;AADA,YAAY,WAAW;AAoCjB,SAEI,KAFJ;AAZN,IAAM,sBAAsB;AAAA,EAC1B,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AACT;AAEA,IAAM,eAAqB;AAAA,EACzB,CAAC,EAAE,OAAO,OAAO,eAAe,SAAS,WAAW,SAAS,GAAG,QAAQ;AACtE,UAAM,YAAY,SAAS,QAAQ,SAAS;AAE5C,WACE,qBAAC,SAAI,KAAU,WAAW,GAAG,YAAY,kCAAkC,YAAY,SAAS,GAC7F;AAAA,eACC,oBAAC,WAAM,WAAU,sCACd,iBACH;AAAA,MAED;AAAA,MACA,SACC,oBAAC,OAAE,WAAW,GAAG,sEAAsE,oBAAoB,YAAY,CAAC,GAAG,OAAO,OAC/H,iBACH;AAAA,OAEJ;AAAA,EAEJ;AACF;AACA,aAAa,cAAc;;;ACjD3B;AAHA,YAAYC,YAAW;AAEvB,SAAS,eAAe;AAoChB,gBAAAC,MA+BF,QAAAC,aA/BE;AAdR,IAAM,uBAAuB;AAAA,EAC3B,OAAO;AAAA,EACP,SAAS;AACX;AAEA,IAAM,QAAc;AAAA,EAClB,CAAC,EAAE,WAAW,MAAM,UAAU,OAAO,gBAAgB,cAAc,OAAO,OAAO,eAAe,SAAS,UAAU,OAAO,GAAG,MAAM,GAAG,QAAQ;AAE5I,UAAM,mBAAmB,iBAAiB,WAAW,iBAAiB;AACtE,UAAM,YAAY,WAAY,CAAC,CAAC,SAAS;AAGzC,QAAI,SAAS,SAAS;AACpB,YAAM,aACJ,gBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAW;AAAA,YACT;AAAA;AAAA,YAEA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA;AAAA,YAEA;AAAA,YACA;AAAA,YACA;AAAA;AAAA,YAEA;AAAA;AAAA,YAEA;AAAA,YACA;AAAA,UACF;AAAA,UACA;AAAA,UACC,GAAG;AAAA;AAAA,MACN;AAEF,aAAO,QACL,gBAAAA,KAAC,gBAAa,OAAc,OAAc,cACvC,sBACH,IACE;AAAA,IACN;AAEA,UAAM,UACJ,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,gBAAc,aAAa;AAAA,QAC3B,WAAW;AAAA;AAAA,UAET;AAAA;AAAA,UAEA;AAAA,UACA;AAAA;AAAA,UAEA;AAAA;AAAA,UAEA;AAAA;AAAA,UAEA,CAAC,MAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAQnB,MAAM,YAAY;AAAA,UAClB;AAAA;AAAA,UAEA,aAAa,qBAAqB,mBAAoB,eAAuC,OAAO;AAAA,UACpG;AAAA,QACF;AAAA,QAEC;AAAA,4BACC,gBAAAD,KAAC,UAAK,WAAU,wLACb,0BACH;AAAA,UAEF,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA,WAAW;AAAA;AAAA,gBAET;AAAA;AAAA,gBAEA;AAAA;AAAA,gBAEA;AAAA;AAAA,gBAEA;AAAA;AAAA,gBAEA;AAAA;AAAA,gBAEA;AAAA;AAAA,gBAEA;AAAA,cACF;AAAA,cACA;AAAA,cACC,GAAG;AAAA;AAAA,UACN;AAAA,UACC,WACC,gBAAAA,KAAC,WAAQ,WAAU,uEAAsE;AAAA,UAE1F,CAAC,WAAW,gBACX,gBAAAA,KAAC,UAAK,WAAU,wLACb,wBACH;AAAA;AAAA;AAAA,IAEJ;AAGF,WACE,gBAAAA,KAAC,gBAAa,OAAc,OAAc,cACvC,mBACH;AAAA,EAEJ;AACF;AACA,MAAM,cAAc;;;AC1IpB;AAHA,YAAYE,YAAW;AACvB,YAAY,uBAAuB;AAoB7B,gBAAAC,YAAA;AAfN,IAAM,WAAiB,kBAGrB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B,gBAAAA;AAAA,EAAmB;AAAA,EAAlB;AAAA,IACC;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,IACC,GAAG;AAAA,IAEJ,0BAAAA;AAAA,MAAmB;AAAA,MAAlB;AAAA,QACC,WAAW,GAAG,0DAA0D;AAAA,QAExE,0BAAAA,KAAC,yBAAsB,MAAM,IAAI;AAAA;AAAA,IACnC;AAAA;AACF,CACD;AACD,SAAS,cAAgC,uBAAK;;;ACrB9C;AAJA,YAAYC,YAAW;AACvB,YAAY,2BAA2B;AACvC,SAAS,OAAO,cAAc,cAAc;;;ACF5C,YAAYC,YAAW;AAkBhB,IAAM,yBAA+B;AAAA,EAC1C;AACF;AAGO,SAAS,qBAAyC;AACvD,SAAa,kBAAW,sBAAsB;AAChD;;;ADAE,SAUE,OAAAC,MAVF,QAAAC,aAAA;AAlBF,IAAM,eAAqC;AAE3C,IAAM,sBAA4C;AAElD,IAAM,oBAA0C;AAEhD,IAAM,qBAA2C;AAEjD,IAAM,kBAAwC;AAE9C,IAAM,yBAA+C;AAErD,IAAM,yBAA+B,kBAKnC,CAAC,EAAE,WAAW,OAAO,UAAU,GAAG,MAAM,GAAG,QAC3C,gBAAAA;AAAA,EAAuB;AAAA,EAAtB;AAAA,IACC;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA,SAAS;AAAA,MACT;AAAA,IACF;AAAA,IACC,GAAG;AAAA,IAEH;AAAA;AAAA,MACD,gBAAAD,KAAC,gBAAa,WAAU,WAAU;AAAA;AAAA;AACpC,CACD;AACD,uBAAuB,cACC,iCAAW;AAEnC,IAAM,yBAA+B,kBAGnC,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B,gBAAAA;AAAA,EAAuB;AAAA,EAAtB;AAAA,IACC;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,uBAAuB,cACC,iCAAW;AAEnC,IAAM,sBAA4B,kBAGhC,CAAC,EAAE,WAAW,aAAa,GAAG,GAAG,MAAM,GAAG,QAAQ;AAGlD,QAAM,YAAY,mBAAmB;AACrC,SACA,gBAAAA,KAAuB,8BAAtB,EAA6B,WAAW,aAAa,QACpD,0BAAAA;AAAA,IAAuB;AAAA,IAAtB;AAAA,MACC;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN,GACF;AAEF,CAAC;AACD,oBAAoB,cAAoC,8BAAQ;AAEhE,IAAM,mBAAyB,kBAK7B,CAAC,EAAE,WAAW,OAAO,GAAG,MAAM,GAAG,QACjC,gBAAAA;AAAA,EAAuB;AAAA,EAAtB;AAAA,IACC;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA,SAAS;AAAA,MACT;AAAA,IACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,iBAAiB,cAAoC,2BAAK;AAE1D,IAAM,2BAAiC,kBAGrC,CAAC,EAAE,WAAW,UAAU,SAAS,GAAG,MAAM,GAAG,QAC7C,gBAAAC;AAAA,EAAuB;AAAA,EAAtB;AAAA,IACC;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,IACC,GAAG;AAAA,IAEJ;AAAA,sBAAAD,KAAC,UAAK,WAAU,gEACd,0BAAAA,KAAuB,qCAAtB,EACC,0BAAAA,KAAC,SAAM,WAAU,WAAU,GAC7B,GACF;AAAA,MACC;AAAA;AAAA;AACH,CACD;AACD,yBAAyB,cACD,mCAAa;AAErC,IAAM,wBAA8B,kBAGlC,CAAC,EAAE,WAAW,UAAU,GAAG,MAAM,GAAG,QACpC,gBAAAC;AAAA,EAAuB;AAAA,EAAtB;AAAA,IACC;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,IACC,GAAG;AAAA,IAEJ;AAAA,sBAAAD,KAAC,UAAK,WAAU,gEACd,0BAAAA,KAAuB,qCAAtB,EACC,0BAAAA,KAAC,UAAO,WAAU,2BAA0B,GAC9C,GACF;AAAA,MACC;AAAA;AAAA;AACH,CACD;AACD,sBAAsB,cAAoC,gCAAU;AAEpE,IAAM,oBAA0B,kBAK9B,CAAC,EAAE,WAAW,OAAO,GAAG,MAAM,GAAG,QACjC,gBAAAA;AAAA,EAAuB;AAAA,EAAtB;AAAA,IACC;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA,SAAS;AAAA,MACT;AAAA,IACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,kBAAkB,cAAoC,4BAAM;AAE5D,IAAM,wBAA8B,kBAGlC,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAC1B,gBAAAA;AAAA,EAAuB;AAAA,EAAtB;AAAA,IACC;AAAA,IACA,WAAW,GAAG,iCAAiC,SAAS;AAAA,IACvD,GAAG;AAAA;AACN,CACD;AACD,sBAAsB,cAAoC,gCAAU;AAEpE,IAAM,uBAAuB,CAAC;AAAA,EAC5B;AAAA,EACA,GAAG;AACL,MAA6C;AAC3C,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,sDAAsD,SAAS;AAAA,MAC5E,GAAG;AAAA;AAAA,EACN;AAEJ;AACA,qBAAqB,cAAc;;;AExLnC;AADA,YAAYE,YAAW;AAUjB,gBAAAC,MAwDE,QAAAC,aAxDF;AAHN,IAAM,WAAiB;AAAA,EACrB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAAQ;AAChC,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AACA,SAAS,cAAc;AAOvB,IAAM,eAAqB;AAAA,EACzB,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,MAAM,GAAG,QAAQ;AAC3C,WACE,gBAAAA,KAAC,SAAI,KAAU,WAAW,GAAG,aAAa,SAAS,GAAI,GAAG,OACvD,gBAAM,KAAK,EAAE,QAAQ,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,MACrC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QAEC,WAAW;AAAA,UACT;AAAA,UACA,MAAM,QAAQ,KAAK,QAAQ,KAAK;AAAA;AAAA,QAClC;AAAA;AAAA,MAJK;AAAA,IAKP,CACD,GACH;AAAA,EAEJ;AACF;AACA,aAAa,cAAc;AAO3B,IAAM,eAAqB;AAAA,EACzB,CAAC,EAAE,YAAY,OAAO,WAAW,GAAG,MAAM,GAAG,QAAQ;AACnD,WACE,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH;AAAA,uBACC,gBAAAD,KAAC,YAAS,WAAU,eAAc;AAAA,UAEpC,gBAAAC,MAAC,SAAI,WAAU,OACb;AAAA,4BAAAD,KAAC,YAAS,WAAU,kBAAiB;AAAA,YACrC,gBAAAA,KAAC,gBAAa,OAAO,GAAG;AAAA,aAC1B;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AACA,aAAa,cAAc;AAS3B,IAAM,eAAqB;AAAA,EACzB,CAAC,EAAE,UAAU,GAAG,QAAQ,GAAG,aAAa,OAAO,WAAW,GAAG,MAAM,GAAG,QAAQ;AAC5E,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA,YAAY,KAAK;AAAA,UACjB,YAAY,KAAK;AAAA,UACjB,YAAY,KAAK;AAAA,UACjB;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH,gBAAM,KAAK,EAAE,QAAQ,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,MACrC,gBAAAA,KAAC,gBAAqB,WAAW,cAAd,CAA0B,CAC9C;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AACA,aAAa,cAAc;AAO3B,IAAM,iBAAuB;AAAA,EAC3B,CAAC,EAAE,OAAO,WAAW,WAAW,GAAG,MAAM,GAAG,QAAQ;AAClD,UAAM,cAAc;AAAA,MAClB,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,IAAI;AAAA,IACN;AAEA,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT;AAAA,UACA,YAAY,IAAI;AAAA,UAChB;AAAA,QACF;AAAA,QACC,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AACA,eAAe,cAAc;AAO7B,IAAM,kBAAwB;AAAA,EAC5B,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,MAAM,GAAG,QAAQ;AAC3C,UAAM,gBAAgB;AAAA,MACpB,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAEA,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW;AAAA,UACT,cAAc,KAAK;AAAA,UACnB;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AACA,gBAAgB,cAAc;AAO9B,IAAM,eAAqB;AAAA,EACzB,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,MAAM,GAAG,QAAQ;AAC3C,WACE,gBAAAA,KAAC,SAAI,KAAU,WAAW,GAAG,aAAa,SAAS,GAAI,GAAG,OACvD,gBAAM,KAAK,EAAE,QAAQ,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,MACrC,gBAAAC,MAAC,SAAY,WAAU,2BACrB;AAAA,sBAAAD,KAAC,YAAS,WAAU,wCAAuC;AAAA,MAC3D,gBAAAC,MAAC,SAAI,WAAU,UACb;AAAA,wBAAAD,KAAC,YAAS,WAAU,kBAAiB;AAAA,QACrC,gBAAAA,KAAC,YAAS,WAAU,aAAY;AAAA,SAClC;AAAA,SALQ,CAMV,CACD,GACH;AAAA,EAEJ;AACF;AACA,aAAa,cAAc;AAO3B,IAAM,qBAA2B;AAAA,EAC/B,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,MAAM,GAAG,QAAQ;AAC3C,WACE,gBAAAA,KAAC,SAAI,KAAU,WAAW,GAAG,2BAA2B,SAAS,GAAI,GAAG,OACrE,gBAAM,KAAK,EAAE,QAAQ,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,MACrC,gBAAAA,KAAC,YAAiB,WAAU,cAAb,CAAwB,CACxC,GACH;AAAA,EAEJ;AACF;AACA,mBAAmB,cAAc;","names":["React","jsx","jsxs","Button","cva","React","jsx","jsxs","SplitButton","init_button","React","jsx","jsxs","React","jsx","React","React","jsx","jsxs","React","jsx","jsxs"]}
|