@flamingo-stack/openframe-frontend-core 0.0.194 → 0.0.195-snapshot.20260519151313

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/{chunk-PJ5KFD2V.js → chunk-4ML3NA2L.js} +75 -1
  2. package/dist/{chunk-PJ5KFD2V.js.map → chunk-4ML3NA2L.js.map} +1 -1
  3. package/dist/{chunk-C5VTN2SB.js → chunk-BXPH5SOL.js} +748 -359
  4. package/dist/chunk-BXPH5SOL.js.map +1 -0
  5. package/dist/{chunk-56JS47IQ.cjs → chunk-E6AWU7EI.cjs} +794 -405
  6. package/dist/chunk-E6AWU7EI.cjs.map +1 -0
  7. package/dist/{chunk-CVMSC7M4.cjs → chunk-OII2IERE.cjs} +77 -3
  8. package/dist/chunk-OII2IERE.cjs.map +1 -0
  9. package/dist/components/chat/hooks/index.d.ts +1 -0
  10. package/dist/components/chat/hooks/index.d.ts.map +1 -1
  11. package/dist/components/chat/hooks/use-jetstream-dialog-subscription.d.ts +15 -0
  12. package/dist/components/chat/hooks/use-jetstream-dialog-subscription.d.ts.map +1 -0
  13. package/dist/components/chat/types/api.types.d.ts +43 -0
  14. package/dist/components/chat/types/api.types.d.ts.map +1 -1
  15. package/dist/components/chat/types/network.types.d.ts +4 -0
  16. package/dist/components/chat/types/network.types.d.ts.map +1 -1
  17. package/dist/components/chat/utils/message-segment-accumulator.d.ts +16 -0
  18. package/dist/components/chat/utils/message-segment-accumulator.d.ts.map +1 -1
  19. package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
  20. package/dist/components/features/index.cjs +3 -3
  21. package/dist/components/features/index.js +2 -2
  22. package/dist/components/index.cjs +5 -3
  23. package/dist/components/index.cjs.map +1 -1
  24. package/dist/components/index.js +4 -2
  25. package/dist/components/navigation/index.cjs +3 -3
  26. package/dist/components/navigation/index.js +2 -2
  27. package/dist/components/ui/index.cjs +5 -3
  28. package/dist/components/ui/index.cjs.map +1 -1
  29. package/dist/components/ui/index.js +4 -2
  30. package/dist/hooks/index.cjs +2 -2
  31. package/dist/hooks/index.js +1 -1
  32. package/dist/index.cjs +5 -3
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.js +4 -2
  35. package/dist/nats/index.cjs +73 -0
  36. package/dist/nats/index.cjs.map +1 -1
  37. package/dist/nats/index.js +73 -0
  38. package/dist/nats/index.js.map +1 -1
  39. package/dist/nats/nats.d.ts +22 -1
  40. package/dist/nats/nats.d.ts.map +1 -1
  41. package/package.json +1 -1
  42. package/src/components/chat/hooks/index.ts +1 -0
  43. package/src/components/chat/hooks/use-jetstream-dialog-subscription.ts +474 -0
  44. package/src/components/chat/types/api.types.ts +45 -0
  45. package/src/components/chat/types/network.types.ts +4 -0
  46. package/src/components/chat/utils/message-segment-accumulator.ts +28 -0
  47. package/src/components/chat/utils/process-historical-messages.ts +23 -5
  48. package/src/nats/nats.ts +117 -0
  49. package/dist/chunk-56JS47IQ.cjs.map +0 -1
  50. package/dist/chunk-C5VTN2SB.js.map +0 -1
  51. package/dist/chunk-CVMSC7M4.cjs.map +0 -1
@@ -16,7 +16,7 @@ import {
16
16
  useNearViewport,
17
17
  useOnboardingState,
18
18
  useToast
19
- } from "./chunk-PJ5KFD2V.js";
19
+ } from "./chunk-4ML3NA2L.js";
20
20
  import {
21
21
  Button,
22
22
  Checkbox,
@@ -407,7 +407,7 @@ function useDynamicTheme() {
407
407
  }
408
408
 
409
409
  // src/components/features/array-entry-manager.tsx
410
- import { useState as useState56, useEffect as useEffect42 } from "react";
410
+ import { useState as useState57, useEffect as useEffect43 } from "react";
411
411
 
412
412
  // src/components/ui/allowed-domains-input.tsx
413
413
  init_cn();
@@ -7245,13 +7245,17 @@ function useChunkCatchup({
7245
7245
  };
7246
7246
  }
7247
7247
 
7248
- // src/components/chat/hooks/use-nats-dialog-subscription.ts
7248
+ // src/components/chat/hooks/use-jetstream-dialog-subscription.ts
7249
7249
  import { useCallback as useCallback6, useEffect as useEffect9, useRef as useRef10, useState as useState16 } from "react";
7250
7250
  var shared = null;
7251
- function useNatsDialogSubscription({
7251
+ var DEFAULT_INACTIVE_THRESHOLD_MS = 5 * 6e4;
7252
+ var DEFAULT_STREAM_NAME = "CHAT_CHUNKS";
7253
+ function useJetStreamDialogSubscription({
7252
7254
  enabled,
7253
7255
  dialogId,
7254
- topics = ["message"],
7256
+ streamName = DEFAULT_STREAM_NAME,
7257
+ topic,
7258
+ optStartSeq,
7255
7259
  onEvent,
7256
7260
  onConnect,
7257
7261
  onDisconnect,
@@ -7259,13 +7263,16 @@ function useNatsDialogSubscription({
7259
7263
  onBeforeReconnect,
7260
7264
  getNatsWsUrl,
7261
7265
  clientConfig = {},
7262
- reconnectionBackoff
7266
+ reconnectionBackoff,
7267
+ inactiveThresholdMs
7263
7268
  }) {
7264
7269
  const [isConnected, setIsConnected] = useState16(false);
7265
7270
  const [isSubscribed, setIsSubscribed] = useState16(false);
7266
7271
  const [reconnectionCount, setReconnectionCount] = useState16(0);
7272
+ const [currentStreamSeq, setCurrentStreamSeq] = useState16(null);
7267
7273
  const clientRef = useRef10(null);
7268
- const subscriptionRefs = useRef10(/* @__PURE__ */ new Map());
7274
+ const subscriptionRef = useRef10(null);
7275
+ const highestStreamSeqRef = useRef10(null);
7269
7276
  const onEventRef = useRef10(onEvent);
7270
7277
  useEffect9(() => {
7271
7278
  onEventRef.current = onEvent;
@@ -7286,7 +7293,6 @@ function useNatsDialogSubscription({
7286
7293
  useEffect9(() => {
7287
7294
  onBeforeReconnectRef.current = onBeforeReconnect;
7288
7295
  }, [onBeforeReconnect]);
7289
- const hadConnectionBeforeRef = useRef10(false);
7290
7296
  const getNatsWsUrlRef = useRef10(getNatsWsUrl);
7291
7297
  useEffect9(() => {
7292
7298
  getNatsWsUrlRef.current = getNatsWsUrl;
@@ -7295,33 +7301,54 @@ function useNatsDialogSubscription({
7295
7301
  useEffect9(() => {
7296
7302
  reconnectionBackoffRef.current = reconnectionBackoff;
7297
7303
  }, [reconnectionBackoff]);
7298
- const acquireClient = useCallback6((url) => {
7299
- if (shared?.wsUrl !== url) {
7300
- if (shared) {
7301
- shared.closeTimer && clearTimeout(shared.closeTimer);
7302
- const old = shared;
7303
- shared = null;
7304
- void old.client.close().catch(() => {
7304
+ const optStartSeqRef = useRef10(optStartSeq);
7305
+ useEffect9(() => {
7306
+ optStartSeqRef.current = optStartSeq;
7307
+ }, [optStartSeq]);
7308
+ const inactiveThresholdRef = useRef10(inactiveThresholdMs);
7309
+ useEffect9(() => {
7310
+ inactiveThresholdRef.current = inactiveThresholdMs;
7311
+ }, [inactiveThresholdMs]);
7312
+ const hadConnectionBeforeRef = useRef10(false);
7313
+ const acquireClient = useCallback6(
7314
+ (url) => {
7315
+ if (shared?.wsUrl !== url) {
7316
+ if (shared) {
7317
+ if (shared.closeTimer) clearTimeout(shared.closeTimer);
7318
+ const old = shared;
7319
+ shared = null;
7320
+ void old.client.close().catch(() => {
7321
+ });
7322
+ }
7323
+ const { name = "openframe-frontend-jetstream", user = "machine", pass = "" } = clientConfig;
7324
+ const client = createNatsClient({
7325
+ servers: url,
7326
+ name,
7327
+ user,
7328
+ pass,
7329
+ connectTimeoutMs: NETWORK_CONFIG.CONNECT_TIMEOUT_MS,
7330
+ reconnect: false,
7331
+ pingIntervalMs: NETWORK_CONFIG.PING_INTERVAL_MS,
7332
+ maxPingOut: NETWORK_CONFIG.MAX_PING_OUT
7305
7333
  });
7334
+ shared = {
7335
+ wsUrl: url,
7336
+ client,
7337
+ connectPromise: null,
7338
+ refCount: 0,
7339
+ closeTimer: null,
7340
+ retryTimer: null
7341
+ };
7306
7342
  }
7307
- const { name = "openframe-frontend", user = "machine", pass = "" } = clientConfig;
7308
- const client = createNatsClient({
7309
- servers: url,
7310
- name,
7311
- user,
7312
- pass,
7313
- connectTimeoutMs: NETWORK_CONFIG.CONNECT_TIMEOUT_MS,
7314
- reconnect: false,
7315
- pingIntervalMs: NETWORK_CONFIG.PING_INTERVAL_MS,
7316
- maxPingOut: NETWORK_CONFIG.MAX_PING_OUT
7317
- });
7318
- shared = { wsUrl: url, client, connectPromise: null, refCount: 0, closeTimer: null, retryTimer: null };
7319
- }
7320
- shared.refCount += 1;
7321
- shared.closeTimer && clearTimeout(shared.closeTimer);
7322
- shared.closeTimer = null;
7323
- return shared;
7324
- }, [clientConfig]);
7343
+ shared.refCount += 1;
7344
+ if (shared.closeTimer) {
7345
+ clearTimeout(shared.closeTimer);
7346
+ shared.closeTimer = null;
7347
+ }
7348
+ return shared;
7349
+ },
7350
+ [clientConfig]
7351
+ );
7325
7352
  const releaseClient = useCallback6((url) => {
7326
7353
  if (!shared || shared.wsUrl !== url) return;
7327
7354
  shared.refCount = Math.max(0, shared.refCount - 1);
@@ -7410,6 +7437,331 @@ function useNatsDialogSubscription({
7410
7437
  }
7411
7438
  }, jitteredDelay);
7412
7439
  }
7440
+ const unsubscribeStatus = client.onStatus((event) => {
7441
+ const connected = event.status === "connected";
7442
+ const disconnected = event.status === "closed" || event.status === "disconnected";
7443
+ if (connected) {
7444
+ setIsConnected(true);
7445
+ if (hadConnectionBeforeRef.current) {
7446
+ setReconnectionCount((c) => c + 1);
7447
+ }
7448
+ hadConnectionBeforeRef.current = true;
7449
+ retryAttempt = 0;
7450
+ onConnectRef.current?.();
7451
+ }
7452
+ if (event.status === "error") {
7453
+ console.warn("[JetStream] NATS protocol error:", event.data);
7454
+ return;
7455
+ }
7456
+ if (disconnected) {
7457
+ setIsConnected(false);
7458
+ setIsSubscribed(false);
7459
+ if (subscriptionRef.current) {
7460
+ try {
7461
+ subscriptionRef.current.unsubscribe();
7462
+ } catch {
7463
+ }
7464
+ subscriptionRef.current = null;
7465
+ }
7466
+ onDisconnectRef.current?.();
7467
+ scheduleRetry();
7468
+ }
7469
+ });
7470
+ (async () => {
7471
+ try {
7472
+ sharedConn.connectPromise || (sharedConn.connectPromise = client.connect());
7473
+ await sharedConn.connectPromise;
7474
+ if (!closed) {
7475
+ setIsConnected(true);
7476
+ hadConnectionBeforeRef.current = true;
7477
+ }
7478
+ } catch {
7479
+ sharedConn.connectPromise = null;
7480
+ if (!closed) {
7481
+ setIsConnected(false);
7482
+ onDisconnectRef.current?.();
7483
+ scheduleRetry();
7484
+ }
7485
+ }
7486
+ })();
7487
+ return () => {
7488
+ closed = true;
7489
+ setIsConnected(false);
7490
+ setIsSubscribed(false);
7491
+ unsubscribeStatus();
7492
+ if (sharedConn.retryTimer) {
7493
+ clearTimeout(sharedConn.retryTimer);
7494
+ sharedConn.retryTimer = null;
7495
+ }
7496
+ if (subscriptionRef.current) {
7497
+ try {
7498
+ subscriptionRef.current.unsubscribe();
7499
+ } catch {
7500
+ }
7501
+ subscriptionRef.current = null;
7502
+ }
7503
+ if (clientRef.current && currentWsUrlRef.current) {
7504
+ releaseClient(currentWsUrlRef.current);
7505
+ clientRef.current = null;
7506
+ currentWsUrlRef.current = "";
7507
+ }
7508
+ };
7509
+ }, [enabled, getNatsWsUrl, acquireClient, releaseClient]);
7510
+ useEffect9(() => {
7511
+ if (!enabled || !dialogId || !isConnected) {
7512
+ if (subscriptionRef.current) {
7513
+ try {
7514
+ subscriptionRef.current.unsubscribe();
7515
+ } catch {
7516
+ }
7517
+ subscriptionRef.current = null;
7518
+ }
7519
+ setIsSubscribed(false);
7520
+ return;
7521
+ }
7522
+ const client = clientRef.current;
7523
+ if (!client) return;
7524
+ const abortController = new AbortController();
7525
+ const decoder = new TextDecoder();
7526
+ const filterSubject = `chat.${dialogId}.${topic}`;
7527
+ const resumeSeq = highestStreamSeqRef.current;
7528
+ const initialOptStart = optStartSeqRef.current;
7529
+ const startSeq = resumeSeq != null ? resumeSeq + 1 : initialOptStart != null ? initialOptStart + 1 : void 0;
7530
+ let cancelled = false;
7531
+ void (async () => {
7532
+ try {
7533
+ const handle = await client.subscribeJetStreamOrdered(
7534
+ (msg) => {
7535
+ if (cancelled) return;
7536
+ const streamSeq = msg.info.streamSequence;
7537
+ if (typeof streamSeq === "number") {
7538
+ if (highestStreamSeqRef.current == null || streamSeq > highestStreamSeqRef.current) {
7539
+ highestStreamSeqRef.current = streamSeq;
7540
+ setCurrentStreamSeq(streamSeq);
7541
+ }
7542
+ }
7543
+ const cb = onEventRef.current;
7544
+ if (!cb) return;
7545
+ try {
7546
+ const parsed = JSON.parse(decoder.decode(msg.data));
7547
+ if (typeof streamSeq === "number") {
7548
+ ;
7549
+ parsed.streamSeq = streamSeq;
7550
+ }
7551
+ cb(parsed, topic);
7552
+ } catch {
7553
+ }
7554
+ },
7555
+ {
7556
+ streamName,
7557
+ filterSubject,
7558
+ deliverPolicy: startSeq != null ? "byStartSequence" : "new",
7559
+ optStartSeq: startSeq,
7560
+ inactiveThresholdMs: inactiveThresholdRef.current ?? DEFAULT_INACTIVE_THRESHOLD_MS,
7561
+ signal: abortController.signal
7562
+ }
7563
+ );
7564
+ if (cancelled) {
7565
+ try {
7566
+ handle.unsubscribe();
7567
+ } catch {
7568
+ }
7569
+ return;
7570
+ }
7571
+ subscriptionRef.current = handle;
7572
+ setIsSubscribed(true);
7573
+ onSubscribedRef.current?.();
7574
+ } catch {
7575
+ if (!cancelled) {
7576
+ setIsSubscribed(false);
7577
+ }
7578
+ }
7579
+ })();
7580
+ return () => {
7581
+ cancelled = true;
7582
+ abortController.abort();
7583
+ if (subscriptionRef.current) {
7584
+ try {
7585
+ subscriptionRef.current.unsubscribe();
7586
+ } catch {
7587
+ }
7588
+ subscriptionRef.current = null;
7589
+ }
7590
+ setIsSubscribed(false);
7591
+ };
7592
+ }, [enabled, dialogId, isConnected, streamName, topic, reconnectionCount]);
7593
+ useEffect9(() => {
7594
+ highestStreamSeqRef.current = null;
7595
+ setCurrentStreamSeq(null);
7596
+ }, [dialogId]);
7597
+ return { isConnected, isSubscribed, reconnectionCount, currentStreamSeq };
7598
+ }
7599
+
7600
+ // src/components/chat/hooks/use-nats-dialog-subscription.ts
7601
+ import { useCallback as useCallback7, useEffect as useEffect10, useRef as useRef11, useState as useState17 } from "react";
7602
+ var shared2 = null;
7603
+ function useNatsDialogSubscription({
7604
+ enabled,
7605
+ dialogId,
7606
+ topics = ["message"],
7607
+ onEvent,
7608
+ onConnect,
7609
+ onDisconnect,
7610
+ onSubscribed,
7611
+ onBeforeReconnect,
7612
+ getNatsWsUrl,
7613
+ clientConfig = {},
7614
+ reconnectionBackoff
7615
+ }) {
7616
+ const [isConnected, setIsConnected] = useState17(false);
7617
+ const [isSubscribed, setIsSubscribed] = useState17(false);
7618
+ const [reconnectionCount, setReconnectionCount] = useState17(0);
7619
+ const clientRef = useRef11(null);
7620
+ const subscriptionRefs = useRef11(/* @__PURE__ */ new Map());
7621
+ const onEventRef = useRef11(onEvent);
7622
+ useEffect10(() => {
7623
+ onEventRef.current = onEvent;
7624
+ }, [onEvent]);
7625
+ const onConnectRef = useRef11(onConnect);
7626
+ useEffect10(() => {
7627
+ onConnectRef.current = onConnect;
7628
+ }, [onConnect]);
7629
+ const onDisconnectRef = useRef11(onDisconnect);
7630
+ useEffect10(() => {
7631
+ onDisconnectRef.current = onDisconnect;
7632
+ }, [onDisconnect]);
7633
+ const onSubscribedRef = useRef11(onSubscribed);
7634
+ useEffect10(() => {
7635
+ onSubscribedRef.current = onSubscribed;
7636
+ }, [onSubscribed]);
7637
+ const onBeforeReconnectRef = useRef11(onBeforeReconnect);
7638
+ useEffect10(() => {
7639
+ onBeforeReconnectRef.current = onBeforeReconnect;
7640
+ }, [onBeforeReconnect]);
7641
+ const hadConnectionBeforeRef = useRef11(false);
7642
+ const getNatsWsUrlRef = useRef11(getNatsWsUrl);
7643
+ useEffect10(() => {
7644
+ getNatsWsUrlRef.current = getNatsWsUrl;
7645
+ }, [getNatsWsUrl]);
7646
+ const reconnectionBackoffRef = useRef11(reconnectionBackoff);
7647
+ useEffect10(() => {
7648
+ reconnectionBackoffRef.current = reconnectionBackoff;
7649
+ }, [reconnectionBackoff]);
7650
+ const acquireClient = useCallback7((url) => {
7651
+ if (shared2?.wsUrl !== url) {
7652
+ if (shared2) {
7653
+ shared2.closeTimer && clearTimeout(shared2.closeTimer);
7654
+ const old = shared2;
7655
+ shared2 = null;
7656
+ void old.client.close().catch(() => {
7657
+ });
7658
+ }
7659
+ const { name = "openframe-frontend", user = "machine", pass = "" } = clientConfig;
7660
+ const client = createNatsClient({
7661
+ servers: url,
7662
+ name,
7663
+ user,
7664
+ pass,
7665
+ connectTimeoutMs: NETWORK_CONFIG.CONNECT_TIMEOUT_MS,
7666
+ reconnect: false,
7667
+ pingIntervalMs: NETWORK_CONFIG.PING_INTERVAL_MS,
7668
+ maxPingOut: NETWORK_CONFIG.MAX_PING_OUT
7669
+ });
7670
+ shared2 = { wsUrl: url, client, connectPromise: null, refCount: 0, closeTimer: null, retryTimer: null };
7671
+ }
7672
+ shared2.refCount += 1;
7673
+ shared2.closeTimer && clearTimeout(shared2.closeTimer);
7674
+ shared2.closeTimer = null;
7675
+ return shared2;
7676
+ }, [clientConfig]);
7677
+ const releaseClient = useCallback7((url) => {
7678
+ if (!shared2 || shared2.wsUrl !== url) return;
7679
+ shared2.refCount = Math.max(0, shared2.refCount - 1);
7680
+ if (shared2.refCount > 0) return;
7681
+ shared2.closeTimer = setTimeout(() => {
7682
+ const s = shared2;
7683
+ shared2 = null;
7684
+ if (s) {
7685
+ if (s.retryTimer) {
7686
+ clearTimeout(s.retryTimer);
7687
+ s.retryTimer = null;
7688
+ }
7689
+ void s.client.close().catch(() => {
7690
+ });
7691
+ }
7692
+ }, NETWORK_CONFIG.SHARED_CLOSE_DELAY_MS);
7693
+ }, []);
7694
+ const currentWsUrlRef = useRef11("");
7695
+ useEffect10(() => {
7696
+ const wsUrl = getNatsWsUrl();
7697
+ if (!enabled || !wsUrl) {
7698
+ if (currentWsUrlRef.current && clientRef.current) {
7699
+ releaseClient(currentWsUrlRef.current);
7700
+ clientRef.current = null;
7701
+ currentWsUrlRef.current = "";
7702
+ setIsConnected(false);
7703
+ }
7704
+ return;
7705
+ }
7706
+ if (wsUrl === currentWsUrlRef.current && clientRef.current && clientRef.current.isConnected()) {
7707
+ return;
7708
+ }
7709
+ if (currentWsUrlRef.current && currentWsUrlRef.current !== wsUrl && clientRef.current) {
7710
+ releaseClient(currentWsUrlRef.current);
7711
+ clientRef.current = null;
7712
+ setIsConnected(false);
7713
+ }
7714
+ currentWsUrlRef.current = wsUrl;
7715
+ const sharedConn = acquireClient(wsUrl);
7716
+ const client = sharedConn.client;
7717
+ clientRef.current = client;
7718
+ setIsConnected(false);
7719
+ let closed = false;
7720
+ let retryAttempt = 0;
7721
+ function scheduleRetry() {
7722
+ if (closed) return;
7723
+ if (shared2 !== sharedConn) return;
7724
+ if (sharedConn.retryTimer) {
7725
+ clearTimeout(sharedConn.retryTimer);
7726
+ sharedConn.retryTimer = null;
7727
+ }
7728
+ const cfg = reconnectionBackoffRef.current ?? {};
7729
+ const fastRetries = cfg.fastRetries ?? 0;
7730
+ const fastDelay = cfg.fastRetryDelayMs ?? NETWORK_CONFIG.RETRY_INITIAL_DELAY_MS;
7731
+ const baseDelay = cfg.initialDelayMs ?? NETWORK_CONFIG.RETRY_INITIAL_DELAY_MS;
7732
+ const maxDelay = cfg.maxDelayMs ?? NETWORK_CONFIG.RETRY_MAX_DELAY_MS;
7733
+ const multiplier = cfg.multiplier ?? NETWORK_CONFIG.RETRY_BACKOFF_MULTIPLIER;
7734
+ const delay2 = retryAttempt < fastRetries ? fastDelay : Math.min(baseDelay * multiplier ** (retryAttempt - fastRetries), maxDelay);
7735
+ const jitteredDelay = delay2 * (0.5 + Math.random() * 0.5);
7736
+ retryAttempt++;
7737
+ sharedConn.retryTimer = setTimeout(async () => {
7738
+ sharedConn.retryTimer = null;
7739
+ if (closed) return;
7740
+ if (shared2 !== sharedConn) return;
7741
+ try {
7742
+ await onBeforeReconnectRef.current?.();
7743
+ } catch {
7744
+ }
7745
+ if (closed) return;
7746
+ if (shared2 !== sharedConn) return;
7747
+ const freshUrl = getNatsWsUrlRef.current();
7748
+ if (freshUrl !== wsUrl) return;
7749
+ try {
7750
+ sharedConn.connectPromise = null;
7751
+ sharedConn.connectPromise = client.connect();
7752
+ await sharedConn.connectPromise;
7753
+ if (!closed && shared2 === sharedConn) {
7754
+ retryAttempt = 0;
7755
+ setIsConnected(true);
7756
+ }
7757
+ } catch {
7758
+ sharedConn.connectPromise = null;
7759
+ if (!closed && shared2 === sharedConn) {
7760
+ scheduleRetry();
7761
+ }
7762
+ }
7763
+ }, jitteredDelay);
7764
+ }
7413
7765
  const unsubscribeStatus = client.onStatus((event) => {
7414
7766
  const connected = event.status === "connected";
7415
7767
  const disconnected = ["closed", "disconnected", "error"].includes(event.status);
@@ -7481,14 +7833,14 @@ function useNatsDialogSubscription({
7481
7833
  };
7482
7834
  }, [enabled, getNatsWsUrl, acquireClient, releaseClient]);
7483
7835
  const topicsKey = topics.join(",");
7484
- const lastSubscribedDialogIdRef = useRef10(null);
7485
- const isConnectedRef = useRef10(isConnected);
7486
- useEffect9(() => {
7836
+ const lastSubscribedDialogIdRef = useRef11(null);
7837
+ const isConnectedRef = useRef11(isConnected);
7838
+ useEffect10(() => {
7487
7839
  isConnectedRef.current = isConnected;
7488
7840
  }, [isConnected]);
7489
- const currentDialogIdRef = useRef10(null);
7490
- const abortControllerRef = useRef10(null);
7491
- useEffect9(() => {
7841
+ const currentDialogIdRef = useRef11(null);
7842
+ const abortControllerRef = useRef11(null);
7843
+ useEffect10(() => {
7492
7844
  currentDialogIdRef.current = dialogId;
7493
7845
  if (!enabled || !dialogId) {
7494
7846
  if (subscriptionRefs.current.size > 0) {
@@ -7569,7 +7921,7 @@ function useNatsDialogSubscription({
7569
7921
  abortControllerRef.current = null;
7570
7922
  };
7571
7923
  }, [enabled, dialogId, topicsKey, topics]);
7572
- useEffect9(() => {
7924
+ useEffect10(() => {
7573
7925
  if (!enabled || !currentDialogIdRef.current || !isConnected) {
7574
7926
  return;
7575
7927
  }
@@ -7619,7 +7971,7 @@ function buildNatsWsUrl(apiBaseUrl, options) {
7619
7971
  }
7620
7972
 
7621
7973
  // src/components/chat/hooks/use-realtime-chunk-processor.ts
7622
- import { useCallback as useCallback7, useRef as useRef11, useEffect as useEffect10 } from "react";
7974
+ import { useCallback as useCallback8, useRef as useRef12, useEffect as useEffect11 } from "react";
7623
7975
 
7624
7976
  // src/components/chat/utils/chunk-parser.ts
7625
7977
  function normalizeToolCalls(raw) {
@@ -7909,6 +8261,7 @@ var MessageSegmentAccumulator = class {
7909
8261
  return this.getSegments();
7910
8262
  }
7911
8263
  const toolKey = execId || `${toolData.integratedToolType}-${toolData.toolFunction}`;
8264
+ this.resolvePendingApprovalForExecution();
7912
8265
  if (toolData.type === "EXECUTING_TOOL") {
7913
8266
  this.executingTools.set(toolKey, {
7914
8267
  integratedToolType: toolData.integratedToolType,
@@ -7965,6 +8318,30 @@ var MessageSegmentAccumulator = class {
7965
8318
  });
7966
8319
  return matched;
7967
8320
  }
8321
+ /**
8322
+ * A tool only ever runs after its approval gate was granted. The legacy /
8323
+ * single `approval_request` segment carries no `toolExecutionRequestId` to
8324
+ * correlate with the execution, and an observer (e.g. a technician
8325
+ * mirroring the client chat) may never receive an `APPROVAL_RESULT` chunk —
8326
+ * only the tool's `EXECUTING_TOOL` / `EXECUTED_TOOL` events. Treat the
8327
+ * arrival of a tool execution as implicit approval of the most recent
8328
+ * still-pending gate so the card does not stay stuck `pending` in realtime.
8329
+ *
8330
+ * The agent stays paused while an approval is outstanding, so there is at
8331
+ * most one relevant gate; flipping only the latest pending one is safe and
8332
+ * monotonic (never downgrades, can't make a correct state wrong — an
8333
+ * unapproved tool cannot execute). `approval_batch` is handled separately by
8334
+ * `applyExecutionToBatch` and is intentionally left untouched here.
8335
+ */
8336
+ resolvePendingApprovalForExecution() {
8337
+ for (let i = this.segments.length - 1; i >= 0; i--) {
8338
+ const seg = this.segments[i];
8339
+ if (seg.type === "approval_request" && seg.status === "pending") {
8340
+ this.segments[i] = { ...seg, status: "approved" };
8341
+ return;
8342
+ }
8343
+ }
8344
+ }
7968
8345
  /**
7969
8346
  * Track a pending approval request
7970
8347
  */
@@ -8227,14 +8604,14 @@ function useRealtimeChunkProcessor(options) {
8227
8604
  // get the new batch UI; pass `false` explicitly to fall back to legacy.
8228
8605
  batchApprovalsEnabled = true
8229
8606
  } = options;
8230
- const accumulatorRef = useRef11(
8607
+ const accumulatorRef = useRef12(
8231
8608
  createMessageSegmentAccumulator({
8232
8609
  onApprove: callbacks.onApprove,
8233
8610
  onReject: callbacks.onReject
8234
8611
  })
8235
8612
  );
8236
- const hasInitializedWithData = useRef11(false);
8237
- useEffect10(() => {
8613
+ const hasInitializedWithData = useRef12(false);
8614
+ useEffect11(() => {
8238
8615
  if (initialState && !hasInitializedWithData.current) {
8239
8616
  accumulatorRef.current.initializeWithState(initialState);
8240
8617
  if (initialState.escalatedApprovals) {
@@ -8246,9 +8623,9 @@ function useRealtimeChunkProcessor(options) {
8246
8623
  hasInitializedWithData.current = true;
8247
8624
  }
8248
8625
  }, [initialState, callbacks]);
8249
- const isInStreamRef = useRef11(false);
8250
- const pendingEscalatedRef = useRef11(/* @__PURE__ */ new Map());
8251
- const processChunk = useCallback7(
8626
+ const isInStreamRef = useRef12(false);
8627
+ const pendingEscalatedRef = useRef12(/* @__PURE__ */ new Map());
8628
+ const processChunk = useCallback8(
8252
8629
  (chunk) => {
8253
8630
  if (!enableThinking && chunk && typeof chunk === "object" && chunk.type === MESSAGE_TYPE.THINKING) {
8254
8631
  return;
@@ -8447,21 +8824,21 @@ function useRealtimeChunkProcessor(options) {
8447
8824
  },
8448
8825
  [callbacks, displayApprovalTypes, approvalStatuses, initialState, enableThinking]
8449
8826
  );
8450
- const getSegments = useCallback7(() => {
8827
+ const getSegments = useCallback8(() => {
8451
8828
  return accumulatorRef.current.getSegments();
8452
8829
  }, []);
8453
- const reset = useCallback7(() => {
8830
+ const reset = useCallback8(() => {
8454
8831
  accumulatorRef.current.reset();
8455
8832
  pendingEscalatedRef.current.clear();
8456
8833
  hasInitializedWithData.current = false;
8457
8834
  }, []);
8458
- const updateApprovalStatus = useCallback7(
8835
+ const updateApprovalStatus = useCallback8(
8459
8836
  (requestId, status) => {
8460
8837
  return accumulatorRef.current.updateApprovalStatus(requestId, status);
8461
8838
  },
8462
8839
  []
8463
8840
  );
8464
- const getPendingApprovals = useCallback7(() => {
8841
+ const getPendingApprovals = useCallback8(() => {
8465
8842
  return new Map(pendingEscalatedRef.current);
8466
8843
  }, []);
8467
8844
  return {
@@ -8662,11 +9039,22 @@ function processMessageData(data, accumulator, approvalStatuses, options = {}, e
8662
9039
  }
8663
9040
  }
8664
9041
  } else {
8665
- accumulator.trackApprovalRequest(data.approvalRequestId, {
8666
- command: data.command || "",
8667
- explanation: data.explanation,
8668
- approvalType
8669
- });
9042
+ const resolvedStatus = approvalStatuses[data.approvalRequestId];
9043
+ if (resolvedStatus === "approved" || resolvedStatus === "rejected") {
9044
+ accumulator.addApprovalRequest(
9045
+ data.approvalRequestId,
9046
+ data.command || "",
9047
+ data.explanation,
9048
+ approvalType,
9049
+ resolvedStatus
9050
+ );
9051
+ } else {
9052
+ accumulator.trackApprovalRequest(data.approvalRequestId, {
9053
+ command: data.command || "",
9054
+ explanation: data.explanation,
9055
+ approvalType
9056
+ });
9057
+ }
8670
9058
  }
8671
9059
  } else {
8672
9060
  escalatedApprovals?.set(data.approvalRequestId, {
@@ -8926,16 +9314,16 @@ function extractIncompleteMessageState(lastMessage) {
8926
9314
 
8927
9315
  // src/components/navigation/header.tsx
8928
9316
  import Link from "next/link";
8929
- import React24, { useEffect as useEffect11, useRef as useRef12, useState as useState17 } from "react";
9317
+ import React24, { useEffect as useEffect12, useRef as useRef13, useState as useState18 } from "react";
8930
9318
  init_button2();
8931
9319
  import { Fragment as Fragment6, jsx as jsx47, jsxs as jsxs39 } from "react/jsx-runtime";
8932
9320
  function Header({ config, platform }) {
8933
- const [show, setShow] = useState17(true);
8934
- const [lastScrollY, setLastScrollY] = useState17(0);
8935
- const [openDropdowns, setOpenDropdowns] = useState17({});
8936
- const dropdownRefs = useRef12({});
8937
- const triggerRefs = useRef12({});
8938
- useEffect11(() => {
9321
+ const [show, setShow] = useState18(true);
9322
+ const [lastScrollY, setLastScrollY] = useState18(0);
9323
+ const [openDropdowns, setOpenDropdowns] = useState18({});
9324
+ const dropdownRefs = useRef13({});
9325
+ const triggerRefs = useRef13({});
9326
+ useEffect12(() => {
8939
9327
  const handleClickOutside = (event) => {
8940
9328
  const target = event.target;
8941
9329
  if (!target) return;
@@ -8964,14 +9352,14 @@ function Header({ config, platform }) {
8964
9352
  document.removeEventListener("keydown", handleEscapeKey);
8965
9353
  };
8966
9354
  }, [openDropdowns]);
8967
- useEffect11(() => {
9355
+ useEffect12(() => {
8968
9356
  return () => {
8969
9357
  setOpenDropdowns({});
8970
9358
  dropdownRefs.current = {};
8971
9359
  triggerRefs.current = {};
8972
9360
  };
8973
9361
  }, []);
8974
- useEffect11(() => {
9362
+ useEffect12(() => {
8975
9363
  if (!config.autoHide) {
8976
9364
  setShow(true);
8977
9365
  return;
@@ -9194,7 +9582,7 @@ function Header({ config, platform }) {
9194
9582
  }
9195
9583
 
9196
9584
  // src/components/navigation/client-only-header.tsx
9197
- import { useState as useState18, useEffect as useEffect12 } from "react";
9585
+ import { useState as useState19, useEffect as useEffect13 } from "react";
9198
9586
 
9199
9587
  // src/components/navigation/header-skeleton.tsx
9200
9588
  import { jsx as jsx48, jsxs as jsxs40 } from "react/jsx-runtime";
@@ -9242,8 +9630,8 @@ function HeaderSkeleton({ config }) {
9242
9630
  // src/components/navigation/client-only-header.tsx
9243
9631
  import { jsx as jsx49 } from "react/jsx-runtime";
9244
9632
  function ClientOnlyHeader({ config, skeleton }) {
9245
- const [isClient, setIsClient] = useState18(false);
9246
- useEffect12(() => {
9633
+ const [isClient, setIsClient] = useState19(false);
9634
+ useEffect13(() => {
9247
9635
  setIsClient(true);
9248
9636
  }, []);
9249
9637
  if (!isClient) {
@@ -9253,13 +9641,13 @@ function ClientOnlyHeader({ config, skeleton }) {
9253
9641
  }
9254
9642
 
9255
9643
  // src/components/navigation/mobile-nav-panel.tsx
9256
- import { useEffect as useEffect13, useRef as useRef13 } from "react";
9644
+ import { useEffect as useEffect14, useRef as useRef14 } from "react";
9257
9645
  init_button2();
9258
9646
  import { X as X2 } from "lucide-react";
9259
9647
  import { Fragment as Fragment7, jsx as jsx50, jsxs as jsxs41 } from "react/jsx-runtime";
9260
9648
  function MobileNavPanel({ isOpen, config }) {
9261
- const panelRef = useRef13(null);
9262
- useEffect13(() => {
9649
+ const panelRef = useRef14(null);
9650
+ useEffect14(() => {
9263
9651
  if (isOpen) {
9264
9652
  document.body.style.overflow = "hidden";
9265
9653
  } else {
@@ -9269,7 +9657,7 @@ function MobileNavPanel({ isOpen, config }) {
9269
9657
  document.body.style.overflow = "unset";
9270
9658
  };
9271
9659
  }, [isOpen]);
9272
- useEffect13(() => {
9660
+ useEffect14(() => {
9273
9661
  const handleKeyDown = (e) => {
9274
9662
  if (e.key === "Escape" && isOpen) {
9275
9663
  config.onClose?.();
@@ -9377,15 +9765,15 @@ function MobileNavPanel({ isOpen, config }) {
9377
9765
  }
9378
9766
 
9379
9767
  // src/components/navigation/sliding-sidebar.tsx
9380
- import { useState as useState19, useEffect as useEffect14 } from "react";
9768
+ import { useState as useState20, useEffect as useEffect15 } from "react";
9381
9769
  import { motion, AnimatePresence } from "framer-motion";
9382
9770
  init_button2();
9383
9771
  import { Fragment as Fragment8, jsx as jsx51, jsxs as jsxs42 } from "react/jsx-runtime";
9384
9772
  function SlidingSidebar({ config }) {
9385
- const [expandedItems, setExpandedItems] = useState19(/* @__PURE__ */ new Set());
9386
- const [mounted, setMounted] = useState19(false);
9387
- const [headerHeight, setHeaderHeight] = useState19(64);
9388
- useEffect14(() => {
9773
+ const [expandedItems, setExpandedItems] = useState20(/* @__PURE__ */ new Set());
9774
+ const [mounted, setMounted] = useState20(false);
9775
+ const [headerHeight, setHeaderHeight] = useState20(64);
9776
+ useEffect15(() => {
9389
9777
  setMounted(true);
9390
9778
  const calculateHeaderHeight = () => {
9391
9779
  let totalHeight = 0;
@@ -9596,7 +9984,7 @@ function SlidingSidebar({ config }) {
9596
9984
  }
9597
9985
 
9598
9986
  // src/components/navigation/sticky-section-nav.tsx
9599
- import { useEffect as useEffect15, useState as useState20, useCallback as useCallback8, useRef as useRef14 } from "react";
9987
+ import { useEffect as useEffect16, useState as useState21, useCallback as useCallback9, useRef as useRef15 } from "react";
9600
9988
  import { jsx as jsx52, jsxs as jsxs43 } from "react/jsx-runtime";
9601
9989
  function StickySectionNav({
9602
9990
  sections,
@@ -9657,10 +10045,10 @@ function StickySectionNav({
9657
10045
  ] });
9658
10046
  }
9659
10047
  function useSectionNavigation(sections, options) {
9660
- const [activeSection, setActiveSection] = useState20(sections[0]?.id || "");
9661
- const isScrollingFromClick = useRef14(false);
10048
+ const [activeSection, setActiveSection] = useState21(sections[0]?.id || "");
10049
+ const isScrollingFromClick = useRef15(false);
9662
10050
  const { offset: offset2 = 100 } = options || {};
9663
- const handleSectionClick = useCallback8((sectionId) => {
10051
+ const handleSectionClick = useCallback9((sectionId) => {
9664
10052
  const targetElement = document.getElementById(sectionId);
9665
10053
  if (!targetElement) return;
9666
10054
  isScrollingFromClick.current = true;
@@ -9671,14 +10059,14 @@ function useSectionNavigation(sections, options) {
9671
10059
  isScrollingFromClick.current = false;
9672
10060
  }, 500);
9673
10061
  }, [offset2]);
9674
- useEffect15(() => {
10062
+ useEffect16(() => {
9675
10063
  sections.forEach((section) => {
9676
10064
  if (section.ref.current && !section.ref.current.id) {
9677
10065
  section.ref.current.id = section.id;
9678
10066
  }
9679
10067
  });
9680
10068
  }, [sections]);
9681
- useEffect15(() => {
10069
+ useEffect16(() => {
9682
10070
  const handleScroll = () => {
9683
10071
  if (isScrollingFromClick.current) return;
9684
10072
  const scrollPosition = window.scrollY + offset2 + 50;
@@ -9711,7 +10099,7 @@ function useSectionNavigation(sections, options) {
9711
10099
  }
9712
10100
 
9713
10101
  // src/components/navigation/navigation-sidebar.tsx
9714
- import { useCallback as useCallback9, useLayoutEffect as useLayoutEffect4, useMemo as useMemo10, useState as useState21 } from "react";
10102
+ import { useCallback as useCallback10, useLayoutEffect as useLayoutEffect4, useMemo as useMemo10, useState as useState22 } from "react";
9715
10103
 
9716
10104
  // src/components/navigation/navigation-sidebar-header.tsx
9717
10105
  import { jsx as jsx53, jsxs as jsxs44 } from "react/jsx-runtime";
@@ -9861,14 +10249,14 @@ function NavigationSidebar({ config, disabled = false }) {
9861
10249
  STORAGE_KEY,
9862
10250
  !isLgUp || (config.minimized ?? false)
9863
10251
  );
9864
- const [transitionsEnabled, setTransitionsEnabled] = useState21(false);
10252
+ const [transitionsEnabled, setTransitionsEnabled] = useState22(false);
9865
10253
  const isMinimized = !isLgUp || minimized;
9866
10254
  const showLabel = isLgUp && !minimized;
9867
- const handleToggle = useCallback9(() => {
10255
+ const handleToggle = useCallback10(() => {
9868
10256
  setMinimized((prev) => !prev);
9869
10257
  config.onToggleMinimized?.();
9870
10258
  }, [setMinimized, config]);
9871
- const handleItemClick = useCallback9((item, event) => {
10259
+ const handleItemClick = useCallback10((item, event) => {
9872
10260
  event?.stopPropagation();
9873
10261
  if (item.onClick) {
9874
10262
  item.onClick();
@@ -10391,7 +10779,7 @@ function NotificationsHeaderButton({
10391
10779
  }
10392
10780
 
10393
10781
  // src/components/navigation/app-layout.tsx
10394
- import { Suspense, useCallback as useCallback12, useState as useState24 } from "react";
10782
+ import { Suspense, useCallback as useCallback13, useState as useState25 } from "react";
10395
10783
 
10396
10784
  // src/components/features/notifications/notification-drawer.tsx
10397
10785
  import * as DialogPrimitive2 from "@radix-ui/react-dialog";
@@ -10581,7 +10969,7 @@ Switch.displayName = SwitchPrimitives.Root.displayName;
10581
10969
  init_cn();
10582
10970
 
10583
10971
  // src/components/features/notifications/notification-tile.tsx
10584
- import { useMemo as useMemo12, useEffect as useEffect17 } from "react";
10972
+ import { useMemo as useMemo12, useEffect as useEffect18 } from "react";
10585
10973
  init_button();
10586
10974
  init_cn();
10587
10975
  import { jsx as jsx64, jsxs as jsxs52 } from "react/jsx-runtime";
@@ -10595,7 +10983,7 @@ function NotificationTile({
10595
10983
  const { id, variant = "default", title, description, createdAt, read, settled } = notification;
10596
10984
  const initialElapsed = useMemo12(() => Date.now() - createdAt, [createdAt]);
10597
10985
  const isLive = !read && !settled && initialElapsed < liveDurationMs;
10598
- useEffect17(() => {
10986
+ useEffect18(() => {
10599
10987
  if (!isLive) return;
10600
10988
  const remaining = Math.max(0, liveDurationMs - initialElapsed);
10601
10989
  const timer = window.setTimeout(() => {
@@ -10771,7 +11159,7 @@ function NotificationsHistoryButton({ onClick }) {
10771
11159
  }
10772
11160
 
10773
11161
  // src/components/navigation/mobile-burger-menu.tsx
10774
- import React33, { useCallback as useCallback11, useEffect as useEffect18 } from "react";
11162
+ import React33, { useCallback as useCallback12, useEffect as useEffect19 } from "react";
10775
11163
  import { Fragment as Fragment10, jsx as jsx66, jsxs as jsxs54 } from "react/jsx-runtime";
10776
11164
  var HEADER_HEIGHT = 48;
10777
11165
  var MobileBurgerMenu = React33.memo(function MobileBurgerMenu2({
@@ -10784,7 +11172,7 @@ var MobileBurgerMenu = React33.memo(function MobileBurgerMenu2({
10784
11172
  onLogout,
10785
11173
  disabled = false
10786
11174
  }) {
10787
- useEffect18(() => {
11175
+ useEffect19(() => {
10788
11176
  if (isOpen) {
10789
11177
  document.body.style.overflow = "hidden";
10790
11178
  } else {
@@ -10794,7 +11182,7 @@ var MobileBurgerMenu = React33.memo(function MobileBurgerMenu2({
10794
11182
  document.body.style.overflow = "unset";
10795
11183
  };
10796
11184
  }, [isOpen]);
10797
- useEffect18(() => {
11185
+ useEffect19(() => {
10798
11186
  const handleKeyDown = (e) => {
10799
11187
  if (e.key === "Escape" && isOpen) {
10800
11188
  onClose();
@@ -10805,7 +11193,7 @@ var MobileBurgerMenu = React33.memo(function MobileBurgerMenu2({
10805
11193
  return () => document.removeEventListener("keydown", handleKeyDown);
10806
11194
  }
10807
11195
  }, [isOpen, onClose]);
10808
- const handleItemClick = useCallback11((item) => {
11196
+ const handleItemClick = useCallback12((item) => {
10809
11197
  if (item.onClick) {
10810
11198
  item.onClick();
10811
11199
  } else if (item.path) {
@@ -10980,11 +11368,11 @@ function AppLayout({
10980
11368
  mobileBurgerMenuProps,
10981
11369
  disabled = false
10982
11370
  }) {
10983
- const [mobileMenuOpen, setMobileMenuOpen] = useState24(false);
10984
- const handleToggleMobileMenu = useCallback12(() => {
11371
+ const [mobileMenuOpen, setMobileMenuOpen] = useState25(false);
11372
+ const handleToggleMobileMenu = useCallback13(() => {
10985
11373
  setMobileMenuOpen((prev) => !prev);
10986
11374
  }, []);
10987
- const handleCloseMobileMenu = useCallback12(() => {
11375
+ const handleCloseMobileMenu = useCallback13(() => {
10988
11376
  setMobileMenuOpen(false);
10989
11377
  }, []);
10990
11378
  return /* @__PURE__ */ jsxs55("div", { className: cn("flex h-screen bg-ods-bg", className), children: [
@@ -11354,7 +11742,7 @@ ScriptArguments.displayName = "ScriptArguments";
11354
11742
 
11355
11743
  // src/components/announcement-bar.tsx
11356
11744
  init_button2();
11357
- import { useState as useState25, useEffect as useEffect19 } from "react";
11745
+ import { useState as useState26, useEffect as useEffect20 } from "react";
11358
11746
  import Image4 from "next/image";
11359
11747
  import { X as X4 } from "lucide-react";
11360
11748
 
@@ -11560,8 +11948,8 @@ var getSvgIcon = (name, size = "main", extra = {}) => {
11560
11948
  return renderSvgIcon(name, { className: cls, ...extra });
11561
11949
  };
11562
11950
  function AnnouncementBar() {
11563
- const [announcement, setAnnouncement] = useState25(null);
11564
- const [isVisible, setIsVisible] = useState25(false);
11951
+ const [announcement, setAnnouncement] = useState26(null);
11952
+ const [isVisible, setIsVisible] = useState26(false);
11565
11953
  const platform = getAppType();
11566
11954
  const getDismissKey = (id) => `${platform}-announcement-${id}-dismissed`;
11567
11955
  const getCacheKey = () => `${platform}-announcement-cache`;
@@ -11593,7 +11981,7 @@ function AnnouncementBar() {
11593
11981
  clearStoredAnnouncement(getCacheKey());
11594
11982
  }
11595
11983
  };
11596
- useEffect19(() => {
11984
+ useEffect20(() => {
11597
11985
  const cached = getStoredAnnouncement(getCacheKey());
11598
11986
  if (cached) {
11599
11987
  const isDismissed = localStorage.getItem(getDismissKey(cached.id));
@@ -12700,7 +13088,7 @@ function EmptyState2({
12700
13088
  }
12701
13089
 
12702
13090
  // src/components/faq-accordion.tsx
12703
- import { useRef as useRef15, useState as useState26, useEffect as useEffect20, useCallback as useCallback13 } from "react";
13091
+ import { useRef as useRef16, useState as useState27, useEffect as useEffect21, useCallback as useCallback14 } from "react";
12704
13092
 
12705
13093
  // src/components/ui/chevron-button.tsx
12706
13094
  init_cn();
@@ -12740,15 +13128,15 @@ ChevronButton.displayName = "ChevronButton";
12740
13128
  init_cn();
12741
13129
  import { jsx as jsx91, jsxs as jsxs74 } from "react/jsx-runtime";
12742
13130
  var useMeasuredHeight = (isOpen) => {
12743
- const ref = useRef15(null);
12744
- const [maxHeight, setMaxHeight] = useState26("0px");
12745
- const measure = useCallback13(() => {
13131
+ const ref = useRef16(null);
13132
+ const [maxHeight, setMaxHeight] = useState27("0px");
13133
+ const measure = useCallback14(() => {
12746
13134
  if (ref.current) {
12747
13135
  const height = ref.current.scrollHeight;
12748
13136
  setMaxHeight(`${height}px`);
12749
13137
  }
12750
13138
  }, []);
12751
- useEffect20(() => {
13139
+ useEffect21(() => {
12752
13140
  if (isOpen) {
12753
13141
  measure();
12754
13142
  } else {
@@ -12758,7 +13146,7 @@ var useMeasuredHeight = (isOpen) => {
12758
13146
  return { ref, maxHeight };
12759
13147
  };
12760
13148
  function FaqAccordion({ items, defaultOpenIds = [] }) {
12761
- const [openSet, setOpenSet] = useState26(new Set(defaultOpenIds));
13149
+ const [openSet, setOpenSet] = useState27(new Set(defaultOpenIds));
12762
13150
  const toggle = (id) => {
12763
13151
  setOpenSet((prev) => {
12764
13152
  const next = new Set(prev);
@@ -13328,13 +13716,13 @@ init_unified_pagination();
13328
13716
 
13329
13717
  // src/components/footer-waitlist-button.tsx
13330
13718
  import { usePathname as usePathname2, useRouter as useRouter4 } from "next/navigation";
13331
- import { useCallback as useCallback14 } from "react";
13719
+ import { useCallback as useCallback15 } from "react";
13332
13720
  init_button2();
13333
13721
  import { jsx as jsx97 } from "react/jsx-runtime";
13334
13722
  function FooterWaitlistButton({ className }) {
13335
13723
  const router = useRouter4();
13336
13724
  const pathname = usePathname2();
13337
- const handleClick = useCallback14(() => {
13725
+ const handleClick = useCallback15(() => {
13338
13726
  if (pathname?.startsWith("/waitlist")) {
13339
13727
  const anchor = document.getElementById("waitlist-form");
13340
13728
  if (anchor) {
@@ -13361,13 +13749,13 @@ function FooterWaitlistButton({ className }) {
13361
13749
 
13362
13750
  // src/components/hero-image-uploader.tsx
13363
13751
  init_button2();
13364
- import { useRef as useRef16, useState as useState27 } from "react";
13752
+ import { useRef as useRef17, useState as useState28 } from "react";
13365
13753
  import { Loader2 as Loader22, Image as ImageIcon, Upload, X as X6 } from "lucide-react";
13366
13754
  import { Fragment as Fragment14, jsx as jsx98, jsxs as jsxs78 } from "react/jsx-runtime";
13367
13755
  function HeroImageUploader({ imageUrl, onChange, uploadEndpoint, height = 300, objectFit = "cover", showReplaceButton = true, deferUpload = false, onUpload, onDelete }) {
13368
- const inputRef = useRef16(null);
13756
+ const inputRef = useRef17(null);
13369
13757
  const { toast } = useToast();
13370
- const [uploading, setUploading] = useState27(false);
13758
+ const [uploading, setUploading] = useState28(false);
13371
13759
  const ALLOWED_TYPES = ["image/jpeg", "image/jpg", "image/png", "image/webp", "image/gif"];
13372
13760
  const MAX_SIZE = 5 * 1024 * 1024;
13373
13761
  const openDialog = () => inputRef.current?.click();
@@ -13483,7 +13871,7 @@ function HeroImageUploader({ imageUrl, onChange, uploadEndpoint, height = 300, o
13483
13871
  }
13484
13872
 
13485
13873
  // src/components/icons-block.tsx
13486
- import { useState as useState28, useEffect as useEffect21, useRef as useRef17 } from "react";
13874
+ import { useState as useState29, useEffect as useEffect22, useRef as useRef18 } from "react";
13487
13875
 
13488
13876
  // src/components/icons-stub.tsx
13489
13877
  import { DollarSign, Code, Users, Building, GitCompare, MessageSquare } from "lucide-react";
@@ -13519,11 +13907,11 @@ var availableIcons = [
13519
13907
  OpenmspLogo2
13520
13908
  ];
13521
13909
  function ResponsiveIconsBlock({ loading = false }) {
13522
- const [columns, setColumns] = useState28(24);
13523
- const [iconGrid, setIconGrid] = useState28([]);
13524
- const [iconsLoaded, setIconsLoaded] = useState28(false);
13525
- const randomSeedRef = useRef17(0);
13526
- useEffect21(() => {
13910
+ const [columns, setColumns] = useState29(24);
13911
+ const [iconGrid, setIconGrid] = useState29([]);
13912
+ const [iconsLoaded, setIconsLoaded] = useState29(false);
13913
+ const randomSeedRef = useRef18(0);
13914
+ useEffect22(() => {
13527
13915
  function calculateColumns() {
13528
13916
  const cols = Math.ceil(window.innerWidth / 56) + 4;
13529
13917
  setColumns(cols);
@@ -13533,7 +13921,7 @@ function ResponsiveIconsBlock({ loading = false }) {
13533
13921
  setIconsLoaded(true);
13534
13922
  return () => window.removeEventListener("resize", calculateColumns);
13535
13923
  }, []);
13536
- useEffect21(() => {
13924
+ useEffect22(() => {
13537
13925
  if (randomSeedRef.current === 0) {
13538
13926
  randomSeedRef.current = Date.now();
13539
13927
  }
@@ -13638,7 +14026,7 @@ function ResponsiveIconsBlock({ loading = false }) {
13638
14026
 
13639
14027
  // src/components/image-cropper.tsx
13640
14028
  init_button2();
13641
- import { useCallback as useCallback15, useState as useState29 } from "react";
14029
+ import { useCallback as useCallback16, useState as useState30 } from "react";
13642
14030
  import Cropper from "react-easy-crop";
13643
14031
 
13644
14032
  // src/components/ui/slider.tsx
@@ -13696,15 +14084,15 @@ var ImageCropper = ({
13696
14084
  maxSizePx = 512,
13697
14085
  className
13698
14086
  }) => {
13699
- const [crop, setCrop] = useState29({ x: 0, y: 0 });
13700
- const [zoom, setZoom] = useState29(1);
13701
- const [rotation, setRotation] = useState29(0);
13702
- const [croppedAreaPixels, setCroppedAreaPixels] = useState29(null);
13703
- const onCropComplete = useCallback15((_, area) => {
14087
+ const [crop, setCrop] = useState30({ x: 0, y: 0 });
14088
+ const [zoom, setZoom] = useState30(1);
14089
+ const [rotation, setRotation] = useState30(0);
14090
+ const [croppedAreaPixels, setCroppedAreaPixels] = useState30(null);
14091
+ const onCropComplete = useCallback16((_, area) => {
13704
14092
  setCroppedAreaPixels(area);
13705
14093
  }, []);
13706
14094
  const checkerBg = "bg-[length:16px_16px] bg-[linear-gradient(45deg,transparent_25%,#2a2a2a_25%,#2a2a2a_75%,transparent_75%,transparent),linear-gradient(45deg,#2a2a2a_25%,transparent_25%,transparent_75%,#2a2a2a_75%,#2a2a2a)]";
13707
- const exportCrop = useCallback15(async () => {
14095
+ const exportCrop = useCallback16(async () => {
13708
14096
  if (!croppedAreaPixels) return void 0;
13709
14097
  const img = await loadImage(src);
13710
14098
  const canvas = document.createElement("canvas");
@@ -13867,7 +14255,7 @@ var ImageCropper = ({
13867
14255
 
13868
14256
  // src/components/media-carousel.tsx
13869
14257
  init_cn();
13870
- import { useState as useState30, useRef as useRef19, useEffect as useEffect23, memo as memo3, useCallback as useCallback16 } from "react";
14258
+ import { useState as useState31, useRef as useRef20, useEffect as useEffect24, memo as memo3, useCallback as useCallback17 } from "react";
13871
14259
  import { Fragment as Fragment15, jsx as jsx102, jsxs as jsxs81 } from "react/jsx-runtime";
13872
14260
  var ChevronLeftIcon = () => /* @__PURE__ */ jsx102("svg", { width: "24", height: "24", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx102("polyline", { points: "15,18 9,12 15,6" }) });
13873
14261
  var ChevronRightIcon = () => /* @__PURE__ */ jsx102("svg", { width: "24", height: "24", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx102("polyline", { points: "9,18 15,12 9,6" }) });
@@ -13879,12 +14267,12 @@ var MediaCarousel = memo3(function MediaCarousel2({
13879
14267
  autoPlay = false,
13880
14268
  objectFit = "contain"
13881
14269
  }) {
13882
- const [currentIndex, setCurrentIndex] = useState30(0);
13883
- const [touchStart, setTouchStart] = useState30(null);
13884
- const [touchEnd, setTouchEnd] = useState30(null);
13885
- const carouselRef = useRef19(null);
13886
- const thumbnailsRef = useRef19(null);
13887
- useEffect23(() => {
14270
+ const [currentIndex, setCurrentIndex] = useState31(0);
14271
+ const [touchStart, setTouchStart] = useState31(null);
14272
+ const [touchEnd, setTouchEnd] = useState31(null);
14273
+ const carouselRef = useRef20(null);
14274
+ const thumbnailsRef = useRef20(null);
14275
+ useEffect24(() => {
13888
14276
  if (currentIndex >= media.length && media.length > 0) {
13889
14277
  setCurrentIndex(media.length - 1);
13890
14278
  }
@@ -13896,17 +14284,17 @@ var MediaCarousel = memo3(function MediaCarousel2({
13896
14284
  if (!currentItem) {
13897
14285
  return null;
13898
14286
  }
13899
- const nextSlide = useCallback16(() => {
14287
+ const nextSlide = useCallback17(() => {
13900
14288
  setCurrentIndex((prev) => (prev + 1) % media.length);
13901
14289
  }, [media.length]);
13902
- const prevSlide = useCallback16(() => {
14290
+ const prevSlide = useCallback17(() => {
13903
14291
  setCurrentIndex((prev) => (prev - 1 + media.length) % media.length);
13904
14292
  }, [media.length]);
13905
- const selectSlide = useCallback16((index) => {
14293
+ const selectSlide = useCallback17((index) => {
13906
14294
  if (index === currentIndex) return;
13907
14295
  setCurrentIndex(index);
13908
14296
  }, [currentIndex]);
13909
- const handleKeyDown = useCallback16((e) => {
14297
+ const handleKeyDown = useCallback17((e) => {
13910
14298
  if (media.length <= 1) return;
13911
14299
  if (e.key === "ArrowLeft") {
13912
14300
  e.preventDefault();
@@ -16263,16 +16651,16 @@ function evaluateFeatureValue(value, dataType) {
16263
16651
  }
16264
16652
 
16265
16653
  // src/components/made-with-love.tsx
16266
- import { useState as useState31, useEffect as useEffect24 } from "react";
16654
+ import { useState as useState32, useEffect as useEffect25 } from "react";
16267
16655
  import { jsx as jsx132, jsxs as jsxs106 } from "react/jsx-runtime";
16268
16656
  function MadeWithLove({
16269
16657
  className = "",
16270
16658
  size = "md",
16271
16659
  showOnMobile = true
16272
16660
  }) {
16273
- const [isMobile, setIsMobile] = useState31(false);
16274
- const [isHovered, setIsHovered] = useState31(false);
16275
- useEffect24(() => {
16661
+ const [isMobile, setIsMobile] = useState32(false);
16662
+ const [isHovered, setIsHovered] = useState32(false);
16663
+ useEffect25(() => {
16276
16664
  const checkMobile = () => {
16277
16665
  setIsMobile(window.innerWidth < 640);
16278
16666
  };
@@ -16520,7 +16908,7 @@ function DateTimePicker({
16520
16908
 
16521
16909
  // src/components/shared/onboarding/onboarding-walkthrough.tsx
16522
16910
  init_button2();
16523
- import React45, { useRef as useRef20, useCallback as useCallback17 } from "react";
16911
+ import React45, { useRef as useRef21, useCallback as useCallback18 } from "react";
16524
16912
 
16525
16913
  // src/components/shared/onboarding/onboarding-step-card.tsx
16526
16914
  import React44 from "react";
@@ -16786,10 +17174,10 @@ function OnboardingWalkthrough({
16786
17174
  allStepsComplete,
16787
17175
  markMultipleComplete
16788
17176
  } = useOnboardingState(storageKey);
16789
- const hasAutoMarkedRef = useRef20(false);
16790
- const autoMarkingInProgressRef = useRef20(false);
16791
- const lastCompletionStatusRef = useRef20(null);
16792
- const actionInProgressRef = useRef20(/* @__PURE__ */ new Set());
17177
+ const hasAutoMarkedRef = useRef21(false);
17178
+ const autoMarkingInProgressRef = useRef21(false);
17179
+ const lastCompletionStatusRef = useRef21(null);
17180
+ const actionInProgressRef = useRef21(/* @__PURE__ */ new Set());
16793
17181
  React45.useEffect(() => {
16794
17182
  if (isLoadingCompletion) {
16795
17183
  hasAutoMarkedRef.current = false;
@@ -16815,7 +17203,7 @@ function OnboardingWalkthrough({
16815
17203
  lastCompletionStatusRef.current = statusKey;
16816
17204
  }
16817
17205
  }, [completionStatus, isLoadingCompletion, state.completedSteps, markMultipleComplete]);
16818
- const handleStepAction = useCallback17(async (step) => {
17206
+ const handleStepAction = useCallback18(async (step) => {
16819
17207
  if (actionInProgressRef.current.has(step.id)) {
16820
17208
  console.log(`\u23F3 Action already in progress for "${step.id}", skipping`);
16821
17209
  return;
@@ -17092,7 +17480,7 @@ function ProductReleaseCardSkeleton({ className, size = "default" }) {
17092
17480
  }
17093
17481
 
17094
17482
  // src/components/shared/product-release/release-detail-page.tsx
17095
- import { useState as useState35, useEffect as useEffect26 } from "react";
17483
+ import { useState as useState36, useEffect as useEffect27 } from "react";
17096
17484
  import Link4 from "next/link";
17097
17485
 
17098
17486
  // src/components/layout/article-detail-layout.tsx
@@ -17111,7 +17499,7 @@ function ArticleDetailLayout({ children, schemas }) {
17111
17499
  }
17112
17500
 
17113
17501
  // src/components/ui/release-changelog-section.tsx
17114
- import { useState as useState32 } from "react";
17502
+ import { useState as useState33 } from "react";
17115
17503
 
17116
17504
  // src/components/ui/badge.tsx
17117
17505
  init_cn();
@@ -17151,7 +17539,7 @@ function ReleaseChangelogSection({
17151
17539
  defaultCollapsed = true,
17152
17540
  SimpleMarkdownRenderer: SimpleMarkdownRenderer2
17153
17541
  }) {
17154
- const [collapsed, setCollapsed] = useState32(collapsible ? defaultCollapsed : false);
17542
+ const [collapsed, setCollapsed] = useState33(collapsible ? defaultCollapsed : false);
17155
17543
  if (!entries || entries.length === 0) return null;
17156
17544
  const showEntries = !collapsible || !collapsed;
17157
17545
  return /* @__PURE__ */ jsxs113("div", { className: "space-y-4", children: [
@@ -17186,7 +17574,7 @@ function ReleaseChangelogSection({
17186
17574
  }
17187
17575
 
17188
17576
  // src/components/ui/image-gallery-modal.tsx
17189
- import { useState as useState33, useEffect as useEffect25 } from "react";
17577
+ import { useState as useState34, useEffect as useEffect26 } from "react";
17190
17578
  import { ChevronLeft as ChevronLeft3, ChevronRight as ChevronRight7 } from "lucide-react";
17191
17579
  import Image8 from "next/image";
17192
17580
  import { Fragment as Fragment21, jsx as jsx143, jsxs as jsxs114 } from "react/jsx-runtime";
@@ -17196,8 +17584,8 @@ function ImageGalleryModal({
17196
17584
  onClose,
17197
17585
  initialIndex = 0
17198
17586
  }) {
17199
- const [selectedImageIndex, setSelectedImageIndex] = useState33(initialIndex);
17200
- useEffect25(() => {
17587
+ const [selectedImageIndex, setSelectedImageIndex] = useState34(initialIndex);
17588
+ useEffect26(() => {
17201
17589
  if (isOpen) {
17202
17590
  setSelectedImageIndex(initialIndex);
17203
17591
  }
@@ -17212,7 +17600,7 @@ function ImageGalleryModal({
17212
17600
  setSelectedImageIndex(selectedImageIndex + 1);
17213
17601
  }
17214
17602
  };
17215
- useEffect25(() => {
17603
+ useEffect26(() => {
17216
17604
  const handleKeyPress = (event) => {
17217
17605
  if (!isOpen) return;
17218
17606
  switch (event.key) {
@@ -17321,7 +17709,7 @@ import React48 from "react";
17321
17709
  import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
17322
17710
  import { Check as Check2 } from "lucide-react";
17323
17711
  import Link3 from "next/link";
17324
- import React47, { useCallback as useCallback18, useState as useState34 } from "react";
17712
+ import React47, { useCallback as useCallback19, useState as useState35 } from "react";
17325
17713
  init_cn();
17326
17714
  init_button2();
17327
17715
  import { Fragment as Fragment22, jsx as jsx144, jsxs as jsxs115 } from "react/jsx-runtime";
@@ -17329,7 +17717,7 @@ var ROW_CLASSES = "flex flex-1 min-w-0 items-center gap-2 px-3 py-3 cursor-point
17329
17717
  var WRAPPER_CLASSES = "relative flex items-stretch border-b border-ods-border last:border-b-0";
17330
17718
  var SECONDARY_ACTION_CLASSES = "flex w-10 shrink-0 items-center justify-center self-stretch border-l border-ods-border transition-colors hover:bg-ods-bg-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-focus";
17331
17719
  var SecondaryAction = ({ action }) => {
17332
- const handleClick = useCallback18(
17720
+ const handleClick = useCallback19(
17333
17721
  (e) => {
17334
17722
  e.stopPropagation();
17335
17723
  if (action.disabled) {
@@ -17374,7 +17762,7 @@ var SecondaryAction = ({ action }) => {
17374
17762
  );
17375
17763
  };
17376
17764
  var MenuItem = ({ item, onItemClick }) => {
17377
- const activate = useCallback18(() => {
17765
+ const activate = useCallback19(() => {
17378
17766
  if (item.disabled) return;
17379
17767
  if (item.type === "checkbox") {
17380
17768
  item.onClick?.();
@@ -17385,7 +17773,7 @@ var MenuItem = ({ item, onItemClick }) => {
17385
17773
  item.onClick?.();
17386
17774
  onItemClick?.(item);
17387
17775
  }, [item, onItemClick]);
17388
- const handleClick = useCallback18(
17776
+ const handleClick = useCallback19(
17389
17777
  (e) => {
17390
17778
  e.stopPropagation();
17391
17779
  e.preventDefault();
@@ -17393,7 +17781,7 @@ var MenuItem = ({ item, onItemClick }) => {
17393
17781
  },
17394
17782
  [activate]
17395
17783
  );
17396
- const handleKeyDown = useCallback18(
17784
+ const handleKeyDown = useCallback19(
17397
17785
  (e) => {
17398
17786
  if (e.key !== "Enter" && e.key !== " ") return;
17399
17787
  e.preventDefault();
@@ -17402,7 +17790,7 @@ var MenuItem = ({ item, onItemClick }) => {
17402
17790
  },
17403
17791
  [activate]
17404
17792
  );
17405
- const handleLinkClick = useCallback18(
17793
+ const handleLinkClick = useCallback19(
17406
17794
  (e) => {
17407
17795
  if (item.disabled) {
17408
17796
  e.preventDefault();
@@ -17562,8 +17950,8 @@ var ActionsMenuDropdown = ({
17562
17950
  side = "bottom",
17563
17951
  sideOffset = 6
17564
17952
  }) => {
17565
- const [open, setOpen] = useState34(false);
17566
- const handleItemClick = useCallback18(
17953
+ const [open, setOpen] = useState35(false);
17954
+ const handleItemClick = useCallback19(
17567
17955
  (item) => {
17568
17956
  onItemClick?.(item);
17569
17957
  if (item.type !== "checkbox" && item.type !== "submenu") {
@@ -18085,13 +18473,13 @@ function ReleaseDetailPage({
18085
18473
  }) {
18086
18474
  const { data: fetchedRelease, error, isLoading } = useRelease(initialData ? void 0 : slug);
18087
18475
  const release = initialData || fetchedRelease;
18088
- const [galleryOpen, setGalleryOpen] = useState35(false);
18089
- const [galleryIndex, setGalleryIndex] = useState35(0);
18090
- const [roadmapTasks, setRoadmapTasks] = useState35([]);
18091
- const [deliveryData, setDeliveryData] = useState35(null);
18092
- const [roadmapLoading, setRoadmapLoading] = useState35(false);
18093
- const [deliveryLoading, setDeliveryLoading] = useState35(false);
18094
- useEffect26(() => {
18476
+ const [galleryOpen, setGalleryOpen] = useState36(false);
18477
+ const [galleryIndex, setGalleryIndex] = useState36(0);
18478
+ const [roadmapTasks, setRoadmapTasks] = useState36([]);
18479
+ const [deliveryData, setDeliveryData] = useState36(null);
18480
+ const [roadmapLoading, setRoadmapLoading] = useState36(false);
18481
+ const [deliveryLoading, setDeliveryLoading] = useState36(false);
18482
+ useEffect27(() => {
18095
18483
  async function fetchLinkedTasks() {
18096
18484
  if (!release) return;
18097
18485
  try {
@@ -18666,7 +19054,7 @@ function CompactPageLoader({
18666
19054
  }
18667
19055
 
18668
19056
  // src/components/ui/progress-bar.tsx
18669
- import { useEffect as useEffect28, useRef as useRef21, useState as useState37 } from "react";
19057
+ import { useEffect as useEffect29, useRef as useRef22, useState as useState38 } from "react";
18670
19058
  import { jsx as jsx156 } from "react/jsx-runtime";
18671
19059
  var ProgressBar = ({
18672
19060
  progress,
@@ -18682,9 +19070,9 @@ var ProgressBar = ({
18682
19070
  const isMdUp = useMdUp() ?? true;
18683
19071
  const effectiveSegmentWidth = isMdUp ? segmentWidth : mobileSegmentWidth;
18684
19072
  const effectiveHeight = isMdUp ? height : mobileHeight;
18685
- const containerRef = useRef21(null);
18686
- const [segmentCount, setSegmentCount] = useState37(0);
18687
- useEffect28(() => {
19073
+ const containerRef = useRef22(null);
19074
+ const [segmentCount, setSegmentCount] = useState38(0);
19075
+ useEffect29(() => {
18688
19076
  if (!containerRef.current) return;
18689
19077
  const resizeObserver = new ResizeObserver(() => {
18690
19078
  if (containerRef.current) {
@@ -19508,11 +19896,11 @@ DialogDescription.displayName = DialogPrimitive3.Description.displayName;
19508
19896
  // src/components/ui/modal.tsx
19509
19897
  init_cn();
19510
19898
  import * as React58 from "react";
19511
- import { useEffect as useEffect29 } from "react";
19899
+ import { useEffect as useEffect30 } from "react";
19512
19900
  import { jsx as jsx162, jsxs as jsxs131 } from "react/jsx-runtime";
19513
19901
  var Modal = React58.forwardRef(
19514
19902
  ({ isOpen, onClose, children, className }, ref) => {
19515
- useEffect29(() => {
19903
+ useEffect30(() => {
19516
19904
  const handleKeyDown = (event) => {
19517
19905
  if (event.key === "Escape") {
19518
19906
  onClose();
@@ -19594,13 +19982,13 @@ ModalFooter.displayName = "ModalFooter";
19594
19982
 
19595
19983
  // src/components/ui/modal-v2.tsx
19596
19984
  import * as React59 from "react";
19597
- import { useEffect as useEffect30 } from "react";
19985
+ import { useEffect as useEffect31 } from "react";
19598
19986
  init_cn();
19599
19987
  import { jsx as jsx163, jsxs as jsxs132 } from "react/jsx-runtime";
19600
19988
  var ModalContext = React59.createContext({});
19601
19989
  var Modal2 = React59.forwardRef(
19602
19990
  ({ isOpen, onClose, children, className }, ref) => {
19603
- useEffect30(() => {
19991
+ useEffect31(() => {
19604
19992
  const handleKeyDown = (event) => {
19605
19993
  if (event.key === "Escape") {
19606
19994
  onClose();
@@ -20231,7 +20619,7 @@ function TabContent({
20231
20619
 
20232
20620
  // src/components/ui/tab-navigation.tsx
20233
20621
  init_cn();
20234
- import { useState as useState40, useEffect as useEffect31, useMemo as useMemo14, useRef as useRef23, useCallback as useCallback20 } from "react";
20622
+ import { useState as useState41, useEffect as useEffect32, useMemo as useMemo14, useRef as useRef24, useCallback as useCallback21 } from "react";
20235
20623
  import { useSearchParams as useSearchParams3, useRouter as useRouter5, usePathname as usePathname3 } from "next/navigation";
20236
20624
  import { Fragment as Fragment25, jsx as jsx171, jsxs as jsxs139 } from "react/jsx-runtime";
20237
20625
  function TabNavigation({
@@ -20262,9 +20650,9 @@ function TabNavigation({
20262
20650
  }
20263
20651
  return defaultTab || tabs[0]?.id || "";
20264
20652
  };
20265
- const [internalActiveTab, setInternalActiveTab] = useState40(getInitialTab);
20653
+ const [internalActiveTab, setInternalActiveTab] = useState41(getInitialTab);
20266
20654
  const activeTab = isUrlSyncEnabled ? internalActiveTab : controlledActiveTab || "";
20267
- useEffect31(() => {
20655
+ useEffect32(() => {
20268
20656
  if (!isUrlSyncEnabled) return;
20269
20657
  const fromUrl = searchParams?.get(paramName) || "";
20270
20658
  const nextTab = validTabIds.has(fromUrl) ? fromUrl : defaultTab || tabs[0]?.id || "";
@@ -20284,16 +20672,16 @@ function TabNavigation({
20284
20672
  controlledOnTabChange?.(tabId);
20285
20673
  }
20286
20674
  };
20287
- const scrollRef = useRef23(null);
20288
- const [canScrollLeft, setCanScrollLeft] = useState40(false);
20289
- const [canScrollRight, setCanScrollRight] = useState40(false);
20290
- const updateScrollShadows = useCallback20(() => {
20675
+ const scrollRef = useRef24(null);
20676
+ const [canScrollLeft, setCanScrollLeft] = useState41(false);
20677
+ const [canScrollRight, setCanScrollRight] = useState41(false);
20678
+ const updateScrollShadows = useCallback21(() => {
20291
20679
  const el = scrollRef.current;
20292
20680
  if (!el) return;
20293
20681
  setCanScrollLeft(el.scrollLeft > 0);
20294
20682
  setCanScrollRight(el.scrollLeft + el.clientWidth < el.scrollWidth - 1);
20295
20683
  }, []);
20296
- useEffect31(() => {
20684
+ useEffect32(() => {
20297
20685
  const el = scrollRef.current;
20298
20686
  if (!el) return;
20299
20687
  updateScrollShadows();
@@ -20482,11 +20870,11 @@ function StatusIndicator({ status, label, href }) {
20482
20870
 
20483
20871
  // src/components/layout/list-page-layout.tsx
20484
20872
  init_cn();
20485
- import { useEffect as useEffect33, useState as useState42 } from "react";
20873
+ import { useEffect as useEffect34, useState as useState43 } from "react";
20486
20874
 
20487
20875
  // src/components/ui/filter-modal.tsx
20488
20876
  init_cn();
20489
- import { useEffect as useEffect32, useState as useState41 } from "react";
20877
+ import { useEffect as useEffect33, useState as useState42 } from "react";
20490
20878
  init_button2();
20491
20879
 
20492
20880
  // src/components/ui/filter-checkbox-item.tsx
@@ -20682,11 +21070,11 @@ function FilterModal({
20682
21070
  emptyStateTitle = "No filters available",
20683
21071
  emptyStateDescription = "There are no filter options to display at the moment"
20684
21072
  }) {
20685
- const [selectedFilters, setSelectedFilters] = useState41(() => {
21073
+ const [selectedFilters, setSelectedFilters] = useState42(() => {
20686
21074
  return { ...currentFilters };
20687
21075
  });
20688
- const [pendingTags, setPendingTags] = useState41(selectedTags ?? []);
20689
- useEffect32(() => {
21076
+ const [pendingTags, setPendingTags] = useState42(selectedTags ?? []);
21077
+ useEffect33(() => {
20690
21078
  if (isOpen) {
20691
21079
  setSelectedFilters({ ...currentFilters });
20692
21080
  setPendingTags(selectedTags ?? []);
@@ -20829,13 +21217,13 @@ function ListPageLayout({
20829
21217
  mobileFilterTitle,
20830
21218
  stickyHeader = false
20831
21219
  }) {
20832
- const [mobileFilterOpen, setMobileFilterOpen] = useState42(false);
20833
- const [localSearchValue, setLocalSearchValue] = useState42(searchValue);
21220
+ const [mobileFilterOpen, setMobileFilterOpen] = useState43(false);
21221
+ const [localSearchValue, setLocalSearchValue] = useState43(searchValue);
20834
21222
  const debouncedSearchValue = useDebounce(localSearchValue, 500);
20835
- useEffect33(() => {
21223
+ useEffect34(() => {
20836
21224
  setLocalSearchValue(searchValue);
20837
21225
  }, [searchValue]);
20838
- useEffect33(() => {
21226
+ useEffect34(() => {
20839
21227
  if (debouncedSearchValue !== searchValue) {
20840
21228
  onSearch(debouncedSearchValue);
20841
21229
  }
@@ -22373,7 +22761,7 @@ function OrganizationCard({
22373
22761
 
22374
22762
  // src/components/ui/service-card.tsx
22375
22763
  init_cn();
22376
- import { useMemo as useMemo17, useState as useState44 } from "react";
22764
+ import { useMemo as useMemo17, useState as useState45 } from "react";
22377
22765
  import { ExternalLink as ExternalLink3 } from "lucide-react";
22378
22766
 
22379
22767
  // src/components/logs-list.tsx
@@ -22677,7 +23065,7 @@ function ServiceCard({ title, subtitle, icon, tag, rows, className }) {
22677
23065
  ] });
22678
23066
  }
22679
23067
  function ServiceCardRowItem({ row }) {
22680
- const [revealed, setRevealed] = useState44(false);
23068
+ const [revealed, setRevealed] = useState45(false);
22681
23069
  const { copy, copied } = useCopyToClipboard();
22682
23070
  const actions = useMemo17(() => ({ copy: true, open: !!row.href, reveal: !!row.isSecret, ...row.actions }), [row]);
22683
23071
  const displayValue = row.isSecret ? /* @__PURE__ */ jsx204(MaskedValue, { value: row.value, isRevealed: revealed }) : /* @__PURE__ */ jsx204("span", { children: row.value });
@@ -23012,7 +23400,7 @@ var ListLoader = (props) => /* @__PURE__ */ jsx209(ContentLoader, { ...props, va
23012
23400
 
23013
23401
  // src/components/ui/table/table.tsx
23014
23402
  init_cn();
23015
- import { useEffect as useEffect34, useRef as useRef26 } from "react";
23403
+ import { useEffect as useEffect35, useRef as useRef27 } from "react";
23016
23404
  init_pagination();
23017
23405
  init_button2();
23018
23406
 
@@ -23763,10 +24151,10 @@ function Table({
23763
24151
  };
23764
24152
  const allSelected = selectedRows.length > 0 && selectedRows.length === data.length;
23765
24153
  const someSelected = selectedRows.length > 0 && selectedRows.length < data.length;
23766
- const sentinelRef = useRef26(null);
23767
- const onLoadMoreRef = useRef26(infiniteScroll?.onLoadMore);
24154
+ const sentinelRef = useRef27(null);
24155
+ const onLoadMoreRef = useRef27(infiniteScroll?.onLoadMore);
23768
24156
  onLoadMoreRef.current = infiniteScroll?.onLoadMore;
23769
- useEffect34(() => {
24157
+ useEffect35(() => {
23770
24158
  if (!infiniteScroll?.hasNextPage || infiniteScroll.isFetchingNextPage) return;
23771
24159
  const sentinel = sentinelRef.current;
23772
24160
  if (!sentinel) return;
@@ -23978,7 +24366,7 @@ import { useMemo as useMemo18 } from "react";
23978
24366
 
23979
24367
  // src/components/ui/query-report-table/query-report-table-header.tsx
23980
24368
  init_cn();
23981
- import { useRef as useRef27, useState as useState45, useCallback as useCallback21 } from "react";
24369
+ import { useRef as useRef28, useState as useState46, useCallback as useCallback22 } from "react";
23982
24370
  import { jsx as jsx220, jsxs as jsxs178 } from "react/jsx-runtime";
23983
24371
  function QueryReportTableHeader({
23984
24372
  columns,
@@ -24007,9 +24395,9 @@ function QueryReportTableHeader({
24007
24395
  );
24008
24396
  }
24009
24397
  function TruncatedHeaderCell({ value, width }) {
24010
- const textRef = useRef27(null);
24011
- const [isTruncated, setIsTruncated] = useState45(false);
24012
- const checkTruncation = useCallback21(() => {
24398
+ const textRef = useRef28(null);
24399
+ const [isTruncated, setIsTruncated] = useState46(false);
24400
+ const checkTruncation = useCallback22(() => {
24013
24401
  const el = textRef.current;
24014
24402
  if (el) {
24015
24403
  setIsTruncated(el.scrollWidth > el.clientWidth);
@@ -24037,7 +24425,7 @@ function TruncatedHeaderCell({ value, width }) {
24037
24425
 
24038
24426
  // src/components/ui/query-report-table/query-report-table-row.tsx
24039
24427
  init_cn();
24040
- import { useRef as useRef28, useState as useState46, useCallback as useCallback22 } from "react";
24428
+ import { useRef as useRef29, useState as useState47, useCallback as useCallback23 } from "react";
24041
24429
  import { jsx as jsx221, jsxs as jsxs179 } from "react/jsx-runtime";
24042
24430
  function QueryReportTableRow({
24043
24431
  row,
@@ -24083,9 +24471,9 @@ function QueryReportTableRow({
24083
24471
  );
24084
24472
  }
24085
24473
  function TruncatedCell({ value, className }) {
24086
- const textRef = useRef28(null);
24087
- const [isTruncated, setIsTruncated] = useState46(false);
24088
- const checkTruncation = useCallback22(() => {
24474
+ const textRef = useRef29(null);
24475
+ const [isTruncated, setIsTruncated] = useState47(false);
24476
+ const checkTruncation = useCallback23(() => {
24089
24477
  const el = textRef.current;
24090
24478
  if (el) {
24091
24479
  setIsTruncated(el.scrollWidth > el.clientWidth);
@@ -24348,7 +24736,7 @@ init_cn();
24348
24736
 
24349
24737
  // src/components/ui/data-table/data-table-column-filter.tsx
24350
24738
  init_cn();
24351
- import { useCallback as useCallback23, useMemo as useMemo19 } from "react";
24739
+ import { useCallback as useCallback24, useMemo as useMemo19 } from "react";
24352
24740
 
24353
24741
  // src/components/ui/data-table/utils.ts
24354
24742
  function getHideClasses2(hideAt) {
@@ -24408,14 +24796,14 @@ function DataTableColumnFilter({
24408
24796
  () => ({ [column.id]: currentValue ?? EMPTY_ARRAY }),
24409
24797
  [column.id, currentValue]
24410
24798
  );
24411
- const handleApply = useCallback23(
24799
+ const handleApply = useCallback24(
24412
24800
  (applied) => {
24413
24801
  const next = applied[column.id] ?? [];
24414
24802
  column.setFilterValue(next.length > 0 ? next : void 0);
24415
24803
  },
24416
24804
  [column]
24417
24805
  );
24418
- const handleReset = useCallback23(() => {
24806
+ const handleReset = useCallback24(() => {
24419
24807
  column.setFilterValue(void 0);
24420
24808
  }, [column]);
24421
24809
  return /* @__PURE__ */ jsx225(
@@ -24602,7 +24990,7 @@ function DataTableEmpty({
24602
24990
  // src/components/ui/data-table/data-table-row.tsx
24603
24991
  init_cn();
24604
24992
  import Link10 from "next/link";
24605
- import { memo as memo4, useCallback as useCallback24 } from "react";
24993
+ import { memo as memo4, useCallback as useCallback25 } from "react";
24606
24994
  import { flexRender as flexRender2 } from "@tanstack/react-table";
24607
24995
 
24608
24996
  // src/components/ui/data-table/data-table-skeleton.tsx
@@ -24683,7 +25071,7 @@ function DataTableRowImpl({
24683
25071
  className
24684
25072
  }) {
24685
25073
  const isLinkMode = Boolean(href) && !onClick;
24686
- const handleClick = useCallback24(
25074
+ const handleClick = useCallback25(
24687
25075
  (e) => {
24688
25076
  const target = e.target;
24689
25077
  if (target.closest("[data-no-row-click]")) return;
@@ -24820,7 +25208,7 @@ function DataTableBody({
24820
25208
  }
24821
25209
 
24822
25210
  // src/components/ui/data-table/data-table-infinite-footer.tsx
24823
- import { useEffect as useEffect35, useRef as useRef29 } from "react";
25211
+ import { useEffect as useEffect36, useRef as useRef30 } from "react";
24824
25212
  import { Fragment as Fragment37, jsx as jsx231, jsxs as jsxs188 } from "react/jsx-runtime";
24825
25213
  function DataTableInfiniteFooter({
24826
25214
  hasNextPage,
@@ -24829,10 +25217,10 @@ function DataTableInfiniteFooter({
24829
25217
  skeletonRows = 3,
24830
25218
  rootMargin = "200px"
24831
25219
  }) {
24832
- const sentinelRef = useRef29(null);
24833
- const onLoadMoreRef = useRef29(onLoadMore);
25220
+ const sentinelRef = useRef30(null);
25221
+ const onLoadMoreRef = useRef30(onLoadMore);
24834
25222
  onLoadMoreRef.current = onLoadMore;
24835
- useEffect35(() => {
25223
+ useEffect36(() => {
24836
25224
  if (!hasNextPage || isFetchingNextPage) return;
24837
25225
  const sentinel = sentinelRef.current;
24838
25226
  if (!sentinel) return;
@@ -24957,7 +25345,7 @@ var DataTable = Object.assign(DataTableRoot, {
24957
25345
  });
24958
25346
 
24959
25347
  // src/components/ui/phone-input.tsx
24960
- import { useCallback as useCallback25, useEffect as useEffect36, useMemo as useMemo20, useRef as useRef30, useState as useState47 } from "react";
25348
+ import { useCallback as useCallback26, useEffect as useEffect37, useMemo as useMemo20, useRef as useRef31, useState as useState48 } from "react";
24961
25349
  import { jsx as jsx233, jsxs as jsxs190 } from "react/jsx-runtime";
24962
25350
  function PhoneInput({
24963
25351
  value,
@@ -24974,10 +25362,10 @@ function PhoneInput({
24974
25362
  () => [...priority, ...others].find((c) => c.code === countryCode),
24975
25363
  [countryCode, priority, others]
24976
25364
  );
24977
- const [isInvalid, setIsInvalid] = useState47(false);
24978
- const debounceRef = useRef30(null);
24979
- const digitCount = useCallback25((val) => val.replace(/[^0-9]/g, "").length, []);
24980
- const runValidation = useCallback25((phone) => {
25365
+ const [isInvalid, setIsInvalid] = useState48(false);
25366
+ const debounceRef = useRef31(null);
25367
+ const digitCount = useCallback26((val) => val.replace(/[^0-9]/g, "").length, []);
25368
+ const runValidation = useCallback26((phone) => {
24981
25369
  if (!phone || digitCount(phone) === 0) {
24982
25370
  setIsInvalid(false);
24983
25371
  onValidationChange?.(false);
@@ -24987,11 +25375,11 @@ function PhoneInput({
24987
25375
  setIsInvalid(invalid);
24988
25376
  onValidationChange?.(invalid);
24989
25377
  }, [countryCode, digitCount, onValidationChange]);
24990
- const debouncedValidation = useCallback25((phone) => {
25378
+ const debouncedValidation = useCallback26((phone) => {
24991
25379
  if (debounceRef.current) clearTimeout(debounceRef.current);
24992
25380
  debounceRef.current = setTimeout(() => runValidation(phone), 300);
24993
25381
  }, [runValidation]);
24994
- useEffect36(() => {
25382
+ useEffect37(() => {
24995
25383
  return () => {
24996
25384
  if (debounceRef.current) clearTimeout(debounceRef.current);
24997
25385
  };
@@ -25562,9 +25950,9 @@ function FilterList({
25562
25950
 
25563
25951
  // src/components/ui/tag-search-input.tsx
25564
25952
  import {
25565
- useEffect as useEffect38,
25566
- useRef as useRef32,
25567
- useState as useState49
25953
+ useEffect as useEffect39,
25954
+ useRef as useRef33,
25955
+ useState as useState50
25568
25956
  } from "react";
25569
25957
  init_cn();
25570
25958
  import { jsx as jsx236, jsxs as jsxs193 } from "react/jsx-runtime";
@@ -25598,11 +25986,11 @@ function TagSearchInput({
25598
25986
  limitTags,
25599
25987
  placeholder: currentPlaceholder
25600
25988
  });
25601
- const wrapperRef = useRef32(null);
25602
- const hiddenTagsRef = useRef32(null);
25603
- const hiddenTagsPopupRef = useRef32(null);
25604
- const [showHiddenTags, setShowHiddenTags] = useState49(false);
25605
- useEffect38(() => {
25989
+ const wrapperRef = useRef33(null);
25990
+ const hiddenTagsRef = useRef33(null);
25991
+ const hiddenTagsPopupRef = useRef33(null);
25992
+ const [showHiddenTags, setShowHiddenTags] = useState50(false);
25993
+ useEffect39(() => {
25606
25994
  if (!showHiddenTags) return;
25607
25995
  const handleClick = (e) => {
25608
25996
  const target = e.target;
@@ -25758,7 +26146,7 @@ function TagSearchInput({
25758
26146
 
25759
26147
  // src/components/ui/markdown-editor.tsx
25760
26148
  init_cn();
25761
- import { useRef as useRef33, useCallback as useCallback26, useState as useState50, useEffect as useEffect39 } from "react";
26149
+ import { useRef as useRef34, useCallback as useCallback27, useState as useState51, useEffect as useEffect40 } from "react";
25762
26150
  import dynamic from "next/dynamic";
25763
26151
  import { Loader2 as Loader23, Upload as Upload2 } from "lucide-react";
25764
26152
  import { jsx as jsx237, jsxs as jsxs194 } from "react/jsx-runtime";
@@ -25789,7 +26177,7 @@ body .w-md-editor .w-md-editor-bar::after { content: '' !important; display: blo
25789
26177
  body .w-md-editor .w-md-editor-bar:hover::after { border-color: var(--color-text-secondary) !important; }
25790
26178
  `;
25791
26179
  function MarkdownEditorStyles() {
25792
- useEffect39(() => {
26180
+ useEffect40(() => {
25793
26181
  if (document.getElementById(MARKDOWN_EDITOR_STYLE_ID)) return;
25794
26182
  const style = document.createElement("style");
25795
26183
  style.id = MARKDOWN_EDITOR_STYLE_ID;
@@ -25813,11 +26201,11 @@ function MarkdownEditor({
25813
26201
  onFileUploaded,
25814
26202
  renderPreview
25815
26203
  }) {
25816
- const fileInputRef = useRef33(null);
25817
- const [isUploading, setIsUploading] = useState50(false);
25818
- const [uploadProgress, setUploadProgress] = useState50("");
25819
- const [defaultExtraCommands, setDefaultExtraCommands] = useState50([]);
25820
- useEffect39(() => {
26204
+ const fileInputRef = useRef34(null);
26205
+ const [isUploading, setIsUploading] = useState51(false);
26206
+ const [uploadProgress, setUploadProgress] = useState51("");
26207
+ const [defaultExtraCommands, setDefaultExtraCommands] = useState51([]);
26208
+ useEffect40(() => {
25821
26209
  import("@uiw/react-md-editor").then((mod) => {
25822
26210
  if (mod.commands?.getExtraCommands) {
25823
26211
  setDefaultExtraCommands(mod.commands.getExtraCommands());
@@ -25827,7 +26215,7 @@ function MarkdownEditor({
25827
26215
  const handleChange = (val) => {
25828
26216
  onChange(val || "");
25829
26217
  };
25830
- const insertTextAtCursor = useCallback26(
26218
+ const insertTextAtCursor = useCallback27(
25831
26219
  (text) => {
25832
26220
  const textarea = document.querySelector(
25833
26221
  ".w-md-editor-text-textarea"
@@ -25843,7 +26231,7 @@ function MarkdownEditor({
25843
26231
  },
25844
26232
  [value, onChange]
25845
26233
  );
25846
- const handleFileUpload = useCallback26(
26234
+ const handleFileUpload = useCallback27(
25847
26235
  async (file) => {
25848
26236
  if (!onUploadFile) return;
25849
26237
  setIsUploading(true);
@@ -25864,7 +26252,7 @@ function MarkdownEditor({
25864
26252
  },
25865
26253
  [onUploadFile, insertTextAtCursor, onFileUploaded]
25866
26254
  );
25867
- const handleFileInputChange = useCallback26(
26255
+ const handleFileInputChange = useCallback27(
25868
26256
  (e) => {
25869
26257
  const file = e.target.files?.[0];
25870
26258
  if (file) {
@@ -25874,7 +26262,7 @@ function MarkdownEditor({
25874
26262
  },
25875
26263
  [handleFileUpload]
25876
26264
  );
25877
- const handlePaste = useCallback26(
26265
+ const handlePaste = useCallback27(
25878
26266
  (e) => {
25879
26267
  if (!onUploadFile) return;
25880
26268
  const items = e.clipboardData?.items;
@@ -25906,14 +26294,14 @@ function MarkdownEditor({
25906
26294
  }
25907
26295
  } : null;
25908
26296
  const extraCommands = uploadCommand ? [...defaultExtraCommands, uploadCommand] : defaultExtraCommands;
25909
- const wrapperRef = useRef33(null);
25910
- const isDraggingRef = useRef33(false);
25911
- const mouseYRef = useRef33(0);
25912
- const rafRef = useRef33(0);
25913
- const scrollParentRef = useRef33(window);
26297
+ const wrapperRef = useRef34(null);
26298
+ const isDraggingRef = useRef34(false);
26299
+ const mouseYRef = useRef34(0);
26300
+ const rafRef = useRef34(0);
26301
+ const scrollParentRef = useRef34(window);
25914
26302
  const EDGE_ZONE = 60;
25915
26303
  const MAX_SCROLL_SPEED = 15;
25916
- const findScrollParent = useCallback26((el) => {
26304
+ const findScrollParent = useCallback27((el) => {
25917
26305
  let node = el?.parentElement;
25918
26306
  while (node && node !== document.documentElement) {
25919
26307
  const { overflowY } = window.getComputedStyle(node);
@@ -25924,7 +26312,7 @@ function MarkdownEditor({
25924
26312
  }
25925
26313
  return window;
25926
26314
  }, []);
25927
- const scrollLoop = useCallback26(() => {
26315
+ const scrollLoop = useCallback27(() => {
25928
26316
  if (!isDraggingRef.current) return;
25929
26317
  const parent = scrollParentRef.current;
25930
26318
  const isWindow = parent === window;
@@ -25940,7 +26328,7 @@ function MarkdownEditor({
25940
26328
  }
25941
26329
  rafRef.current = requestAnimationFrame(scrollLoop);
25942
26330
  }, []);
25943
- useEffect39(() => {
26331
+ useEffect40(() => {
25944
26332
  const wrapper = wrapperRef.current;
25945
26333
  if (!wrapper) return;
25946
26334
  const onMouseMove = (e) => {
@@ -27190,14 +27578,14 @@ function ArrayEntryManager({
27190
27578
  renderLabel,
27191
27579
  isSaving = false
27192
27580
  }) {
27193
- const [draftItems, setDraftItems] = useState56(items);
27194
- const [isDirty, setIsDirty] = useState56(false);
27195
- useEffect42(() => {
27581
+ const [draftItems, setDraftItems] = useState57(items);
27582
+ const [isDirty, setIsDirty] = useState57(false);
27583
+ useEffect43(() => {
27196
27584
  if (!isDirty && !isSaving) {
27197
27585
  setDraftItems(items);
27198
27586
  }
27199
27587
  }, [items, isDirty, isSaving]);
27200
- useEffect42(() => {
27588
+ useEffect43(() => {
27201
27589
  if (onDirtyChange) {
27202
27590
  onDirtyChange(isDirty);
27203
27591
  }
@@ -27307,7 +27695,7 @@ function ArrayEntryManager({
27307
27695
 
27308
27696
  // src/components/features/provider-button.tsx
27309
27697
  init_button2();
27310
- import { useState as useState57 } from "react";
27698
+ import { useState as useState58 } from "react";
27311
27699
  import { jsx as jsx247 } from "react/jsx-runtime";
27312
27700
  var PROVIDER_CONFIG = {
27313
27701
  microsoft: {
@@ -27328,7 +27716,7 @@ var PROVIDER_CONFIG = {
27328
27716
  }
27329
27717
  };
27330
27718
  function ProviderButton({ provider, onClick, disabled = false, loading = false }) {
27331
- const [internalLoading, setInternalLoading] = useState57(false);
27719
+ const [internalLoading, setInternalLoading] = useState58(false);
27332
27720
  const config = PROVIDER_CONFIG[provider];
27333
27721
  const IconComponent = config.icon;
27334
27722
  const isLoading = loading || internalLoading;
@@ -27412,7 +27800,7 @@ function AuthProvidersList({
27412
27800
 
27413
27801
  // src/components/features/changelog-manager.tsx
27414
27802
  import { Trash2 as Trash23, Plus as Plus3, ChevronDown as ChevronDown7, ChevronUp as ChevronUp3, Eye, EyeOff } from "lucide-react";
27415
- import { useState as useState58, useEffect as useEffect43 } from "react";
27803
+ import { useState as useState59, useEffect as useEffect44 } from "react";
27416
27804
  import { jsx as jsx249, jsxs as jsxs205 } from "react/jsx-runtime";
27417
27805
  function ChangelogManager({
27418
27806
  title,
@@ -27422,8 +27810,8 @@ function ChangelogManager({
27422
27810
  expandAll = false,
27423
27811
  showVisibilityToggle = false
27424
27812
  }) {
27425
- const [expandedIndices, setExpandedIndices] = useState58(/* @__PURE__ */ new Set());
27426
- useEffect43(() => {
27813
+ const [expandedIndices, setExpandedIndices] = useState59(/* @__PURE__ */ new Set());
27814
+ useEffect44(() => {
27427
27815
  if (expandAll && entries.length > 0) {
27428
27816
  setExpandedIndices(new Set(entries.map((_, i) => i)));
27429
27817
  }
@@ -27735,7 +28123,7 @@ var ErrorBoundary = class extends Component {
27735
28123
 
27736
28124
  // src/components/features/figma-prototype-viewer.tsx
27737
28125
  init_cn();
27738
- import { useState as useState59, useRef as useRef36, useEffect as useEffect44, useCallback as useCallback28, useMemo as useMemo24 } from "react";
28126
+ import { useState as useState60, useRef as useRef37, useEffect as useEffect45, useCallback as useCallback29, useMemo as useMemo24 } from "react";
27739
28127
 
27740
28128
  // src/components/features/section-selector.tsx
27741
28129
  init_cn();
@@ -28104,27 +28492,27 @@ var FigmaPrototypeViewer = ({
28104
28492
  }) => {
28105
28493
  const clientId = process.env.NEXT_PUBLIC_FIGMA_CLIENT_ID || "UTQPwZHR9OZp68TTGPFFi5";
28106
28494
  const showDebugPanel = process.env.NEXT_PUBLIC_FIGMA_DEBUG === "true";
28107
- const iframeRef = useRef36(null);
28108
- const containerRef = useRef36(null);
28109
- const navTimerRef = useRef36(null);
28110
- const touchTimerRef = useRef36(null);
28111
- const [screenWidth, setScreenWidth] = useState59(
28495
+ const iframeRef = useRef37(null);
28496
+ const containerRef = useRef37(null);
28497
+ const navTimerRef = useRef37(null);
28498
+ const touchTimerRef = useRef37(null);
28499
+ const [screenWidth, setScreenWidth] = useState60(
28112
28500
  typeof window !== "undefined" ? window.innerWidth : DESKTOP_BREAKPOINT
28113
28501
  );
28114
- const [isTouchDevice, setIsTouchDevice] = useState59(() => {
28502
+ const [isTouchDevice, setIsTouchDevice] = useState60(() => {
28115
28503
  if (typeof window === "undefined") return false;
28116
28504
  return "ontouchstart" in window;
28117
28505
  });
28118
- const [iframeState, setIframeState] = useState59("INITIAL");
28119
- const [iframeKey, setIframeKey] = useState59(0);
28120
- const [isInitialized, setIsInitialized] = useState59(false);
28121
- const [currentNodeId, setCurrentNodeId] = useState59(null);
28122
- const [internalActiveSection, setInternalActiveSection] = useState59(
28506
+ const [iframeState, setIframeState] = useState60("INITIAL");
28507
+ const [iframeKey, setIframeKey] = useState60(0);
28508
+ const [isInitialized, setIsInitialized] = useState60(false);
28509
+ const [currentNodeId, setCurrentNodeId] = useState60(null);
28510
+ const [internalActiveSection, setInternalActiveSection] = useState60(
28123
28511
  config.defaultSectionId || config.sections[0]?.id || ""
28124
28512
  );
28125
28513
  const activeSection = externalActiveSection || internalActiveSection;
28126
- const [isNavigating, setIsNavigating] = useState59(false);
28127
- const [containerDimensions, setContainerDimensions] = useState59({ width: 1200, height: 800 });
28514
+ const [isNavigating, setIsNavigating] = useState60(false);
28515
+ const [containerDimensions, setContainerDimensions] = useState60({ width: 1200, height: 800 });
28128
28516
  const viewMode = useMemo24(
28129
28517
  () => getViewMode(screenWidth, isTouchDevice),
28130
28518
  [screenWidth, isTouchDevice]
@@ -28173,7 +28561,7 @@ var FigmaPrototypeViewer = ({
28173
28561
  embedUrl,
28174
28562
  iframeKey
28175
28563
  ]);
28176
- useEffect44(() => {
28564
+ useEffect45(() => {
28177
28565
  const handleResize = () => {
28178
28566
  const newWidth = window.innerWidth;
28179
28567
  setScreenWidth(newWidth);
@@ -28186,8 +28574,8 @@ var FigmaPrototypeViewer = ({
28186
28574
  window.addEventListener("resize", handleResize);
28187
28575
  return () => window.removeEventListener("resize", handleResize);
28188
28576
  }, []);
28189
- const [lastViewMode, setLastViewMode] = useState59(viewMode);
28190
- useEffect44(() => {
28577
+ const [lastViewMode, setLastViewMode] = useState60(viewMode);
28578
+ useEffect45(() => {
28191
28579
  if (lastViewMode !== viewMode && iframeState === "READY") {
28192
28580
  console.log("[ViewMode Change]", lastViewMode, "\u2192", viewMode);
28193
28581
  setIframeState("RELOADING");
@@ -28195,7 +28583,7 @@ var FigmaPrototypeViewer = ({
28195
28583
  }
28196
28584
  setLastViewMode(viewMode);
28197
28585
  }, [viewMode, lastViewMode, iframeState]);
28198
- useEffect44(() => {
28586
+ useEffect45(() => {
28199
28587
  const handleVisibilityChange = () => {
28200
28588
  if (document.visibilityState === "visible" && iframeState === "READY") {
28201
28589
  console.log("[Sleep Recovery] Reloading iframe after sleep");
@@ -28206,7 +28594,7 @@ var FigmaPrototypeViewer = ({
28206
28594
  document.addEventListener("visibilitychange", handleVisibilityChange);
28207
28595
  return () => document.removeEventListener("visibilitychange", handleVisibilityChange);
28208
28596
  }, [iframeState]);
28209
- useEffect44(() => {
28597
+ useEffect45(() => {
28210
28598
  const handleMessage = (event) => {
28211
28599
  if (event.origin !== "https://www.figma.com") return;
28212
28600
  const validEvents = ["INITIAL_LOAD", "NEW_STATE", "PRESENTED_NODE_CHANGED"];
@@ -28243,7 +28631,7 @@ var FigmaPrototypeViewer = ({
28243
28631
  window.addEventListener("message", handleMessage);
28244
28632
  return () => window.removeEventListener("message", handleMessage);
28245
28633
  }, [config.sections, activeSection, isNavigating, externalActiveSection, config.onSectionChange, viewMode]);
28246
- const navigateToSection = useCallback28((sectionId) => {
28634
+ const navigateToSection = useCallback29((sectionId) => {
28247
28635
  const section = config.sections.find((s) => s.id === sectionId);
28248
28636
  if (!section || !iframeRef.current?.contentWindow || !isInitialized) {
28249
28637
  return;
@@ -28267,7 +28655,7 @@ var FigmaPrototypeViewer = ({
28267
28655
  if (navTimerRef.current) clearTimeout(navTimerRef.current);
28268
28656
  navTimerRef.current = setTimeout(() => setIsNavigating(false), 500);
28269
28657
  }, [config, isInitialized, viewMode, externalActiveSection]);
28270
- const handleSectionClick = useCallback28((sectionId) => {
28658
+ const handleSectionClick = useCallback29((sectionId) => {
28271
28659
  const sectionsDisabled = iframeState !== "READY" || isNavigating;
28272
28660
  if (sectionId === activeSection || sectionsDisabled) {
28273
28661
  return;
@@ -28278,7 +28666,7 @@ var FigmaPrototypeViewer = ({
28278
28666
  navigateToSection(sectionId);
28279
28667
  }
28280
28668
  }, [activeSection, iframeState, isNavigating, externalOnSectionClick, navigateToSection]);
28281
- const handleTouchStart = useCallback28((e) => {
28669
+ const handleTouchStart = useCallback29((e) => {
28282
28670
  const overlayElement = e.currentTarget;
28283
28671
  console.log("[Touch] Touch detected, allowing iframe interaction");
28284
28672
  overlayElement.style.pointerEvents = "none";
@@ -28290,12 +28678,12 @@ var FigmaPrototypeViewer = ({
28290
28678
  }
28291
28679
  }, 500);
28292
28680
  }, []);
28293
- useEffect44(() => {
28681
+ useEffect45(() => {
28294
28682
  if (externalActiveSection && externalActiveSection !== activeSection && isInitialized) {
28295
28683
  navigateToSection(externalActiveSection);
28296
28684
  }
28297
28685
  }, [externalActiveSection, activeSection, isInitialized, navigateToSection]);
28298
- useEffect44(() => {
28686
+ useEffect45(() => {
28299
28687
  return () => {
28300
28688
  if (navTimerRef.current) clearTimeout(navTimerRef.current);
28301
28689
  if (touchTimerRef.current) clearTimeout(touchTimerRef.current);
@@ -28398,7 +28786,7 @@ var FigmaPrototypeViewer = ({
28398
28786
 
28399
28787
  // src/components/features/filters-dropdown.tsx
28400
28788
  init_cn();
28401
- import { useEffect as useEffect45, useRef as useRef37, useState as useState60 } from "react";
28789
+ import { useEffect as useEffect46, useRef as useRef38, useState as useState61 } from "react";
28402
28790
  import { jsx as jsx255, jsxs as jsxs210 } from "react/jsx-runtime";
28403
28791
  var FilterCheckbox = ({ checked, disabled = false, className }) => {
28404
28792
  return /* @__PURE__ */ jsx255(
@@ -28430,15 +28818,15 @@ var FiltersDropdown = ({
28430
28818
  placement = "bottom-start",
28431
28819
  responsive = true
28432
28820
  }) => {
28433
- const [isOpen, setIsOpen] = useState60(false);
28434
- const [shouldRender, setShouldRender] = useState60(false);
28435
- const [isVisible, setIsVisible] = useState60(false);
28436
- const [isMobile, setIsMobile] = useState60(false);
28437
- const [actualPlacement, setActualPlacement] = useState60(placement);
28438
- const dropdownRef = useRef37(null);
28439
- const triggerRef = useRef37(null);
28440
- const containerRef = useRef37(null);
28441
- useEffect45(() => {
28821
+ const [isOpen, setIsOpen] = useState61(false);
28822
+ const [shouldRender, setShouldRender] = useState61(false);
28823
+ const [isVisible, setIsVisible] = useState61(false);
28824
+ const [isMobile, setIsMobile] = useState61(false);
28825
+ const [actualPlacement, setActualPlacement] = useState61(placement);
28826
+ const dropdownRef = useRef38(null);
28827
+ const triggerRef = useRef38(null);
28828
+ const containerRef = useRef38(null);
28829
+ useEffect46(() => {
28442
28830
  if (isOpen) {
28443
28831
  setShouldRender(true);
28444
28832
  let id2 = 0;
@@ -28454,7 +28842,7 @@ var FiltersDropdown = ({
28454
28842
  const t = setTimeout(() => setShouldRender(false), ANIMATION_MS);
28455
28843
  return () => clearTimeout(t);
28456
28844
  }, [isOpen]);
28457
- useEffect45(() => {
28845
+ useEffect46(() => {
28458
28846
  if (!responsive) {
28459
28847
  setIsMobile(false);
28460
28848
  return;
@@ -28466,7 +28854,7 @@ var FiltersDropdown = ({
28466
28854
  window.addEventListener("resize", checkMobile);
28467
28855
  return () => window.removeEventListener("resize", checkMobile);
28468
28856
  }, [responsive]);
28469
- useEffect45(() => {
28857
+ useEffect46(() => {
28470
28858
  if (!isOpen || isMobile || !triggerRef.current) return;
28471
28859
  const calculateOptimalPlacement = () => {
28472
28860
  const trigger = triggerRef.current;
@@ -28492,7 +28880,7 @@ var FiltersDropdown = ({
28492
28880
  window.addEventListener("resize", calculateOptimalPlacement);
28493
28881
  return () => window.removeEventListener("resize", calculateOptimalPlacement);
28494
28882
  }, [isOpen, isMobile, placement]);
28495
- const [selectedFilters, setSelectedFilters] = useState60(() => {
28883
+ const [selectedFilters, setSelectedFilters] = useState61(() => {
28496
28884
  if (currentFilters) {
28497
28885
  return { ...currentFilters };
28498
28886
  }
@@ -28503,12 +28891,12 @@ var FiltersDropdown = ({
28503
28891
  return initial;
28504
28892
  });
28505
28893
  const currentFiltersStr = currentFilters ? JSON.stringify(currentFilters) : "";
28506
- useEffect45(() => {
28894
+ useEffect46(() => {
28507
28895
  if (currentFilters) {
28508
28896
  setSelectedFilters({ ...currentFilters });
28509
28897
  }
28510
28898
  }, [currentFiltersStr]);
28511
- useEffect45(() => {
28899
+ useEffect46(() => {
28512
28900
  const handleClickOutside = (event) => {
28513
28901
  if (containerRef.current && !containerRef.current.contains(event.target)) {
28514
28902
  setIsOpen(false);
@@ -28525,7 +28913,7 @@ var FiltersDropdown = ({
28525
28913
  };
28526
28914
  }
28527
28915
  }, [isOpen, placement]);
28528
- useEffect45(() => {
28916
+ useEffect46(() => {
28529
28917
  const handleEscape = (e) => {
28530
28918
  if (e.key === "Escape" && isOpen) {
28531
28919
  setIsOpen(false);
@@ -28712,7 +29100,7 @@ var FiltersDropdown = ({
28712
29100
  ] });
28713
29101
  };
28714
29102
  var useFiltersDropdown = (initialSections) => {
28715
- const [appliedFilters, setAppliedFilters] = useState60(() => {
29103
+ const [appliedFilters, setAppliedFilters] = useState61(() => {
28716
29104
  const initial = {};
28717
29105
  initialSections.forEach((section) => {
28718
29106
  if (section.defaultSelected) {
@@ -28791,13 +29179,13 @@ function KnowledgeBaseLinksManager({
28791
29179
  }
28792
29180
 
28793
29181
  // src/components/features/loading-provider.tsx
28794
- import { createContext as createContext7, useContext as useContext7, useState as useState61, useEffect as useEffect46 } from "react";
29182
+ import { createContext as createContext7, useContext as useContext7, useState as useState62, useEffect as useEffect47 } from "react";
28795
29183
  import { jsx as jsx258, jsxs as jsxs211 } from "react/jsx-runtime";
28796
29184
  var LoadingContext = createContext7(void 0);
28797
29185
  function LoadingProvider({ children }) {
28798
- const [isLoading, setIsLoading] = useState61(false);
28799
- const [progress, setProgress] = useState61(0);
28800
- useEffect46(() => {
29186
+ const [isLoading, setIsLoading] = useState62(false);
29187
+ const [progress, setProgress] = useState62(0);
29188
+ useEffect47(() => {
28801
29189
  let interval;
28802
29190
  if (isLoading) {
28803
29191
  setProgress(10);
@@ -28842,7 +29230,7 @@ function useLoading() {
28842
29230
  }
28843
29231
 
28844
29232
  // src/components/features/media-gallery-manager.tsx
28845
- import { useState as useState62, useRef as useRef38, useCallback as useCallback29 } from "react";
29233
+ import { useState as useState63, useRef as useRef39, useCallback as useCallback30 } from "react";
28846
29234
  import {
28847
29235
  Upload as Upload3,
28848
29236
  Image as ImageIcon2,
@@ -28863,10 +29251,10 @@ function MediaGalleryManager({
28863
29251
  modalTitle = "Media Gallery",
28864
29252
  className = ""
28865
29253
  }) {
28866
- const fileInputRef = useRef38(null);
28867
- const [deletingIndex, setDeletingIndex] = useState62(null);
28868
- const [draggedIndex, setDraggedIndex] = useState62(null);
28869
- const handleFileSelect = useCallback29(async (event) => {
29254
+ const fileInputRef = useRef39(null);
29255
+ const [deletingIndex, setDeletingIndex] = useState63(null);
29256
+ const [draggedIndex, setDraggedIndex] = useState63(null);
29257
+ const handleFileSelect = useCallback30(async (event) => {
28870
29258
  const file = event.target.files?.[0];
28871
29259
  if (!file) return;
28872
29260
  let mediaType;
@@ -28892,18 +29280,18 @@ function MediaGalleryManager({
28892
29280
  console.error("Upload failed:", error);
28893
29281
  }
28894
29282
  }, [media, onChange, onUpload]);
28895
- const handleDeleteMedia = useCallback29((index) => {
29283
+ const handleDeleteMedia = useCallback30((index) => {
28896
29284
  setDeletingIndex(index);
28897
29285
  onChange(media.filter((_, i) => i !== index));
28898
29286
  setDeletingIndex(null);
28899
29287
  }, [media, onChange]);
28900
- const handleDragStart = useCallback29((index) => {
29288
+ const handleDragStart = useCallback30((index) => {
28901
29289
  setDraggedIndex(index);
28902
29290
  }, []);
28903
- const handleDragOver = useCallback29((e) => {
29291
+ const handleDragOver = useCallback30((e) => {
28904
29292
  e.preventDefault();
28905
29293
  }, []);
28906
- const handleDrop = useCallback29((e, targetIndex) => {
29294
+ const handleDrop = useCallback30((e, targetIndex) => {
28907
29295
  e.preventDefault();
28908
29296
  if (draggedIndex === null || draggedIndex === targetIndex) {
28909
29297
  setDraggedIndex(null);
@@ -28915,7 +29303,7 @@ function MediaGalleryManager({
28915
29303
  onChange(newMedia.map((item, i) => ({ ...item, display_order: i })));
28916
29304
  setDraggedIndex(null);
28917
29305
  }, [media, draggedIndex, onChange]);
28918
- const renderMediaItem = useCallback29((mediaItem, index) => {
29306
+ const renderMediaItem = useCallback30((mediaItem, index) => {
28919
29307
  const isDeleting = deletingIndex === index;
28920
29308
  return /* @__PURE__ */ jsxs212(
28921
29309
  Card,
@@ -29075,7 +29463,7 @@ function OSTypeBadgeGroup({
29075
29463
  }
29076
29464
 
29077
29465
  // src/components/features/parallax-image-showcase.tsx
29078
- import { useEffect as useEffect47, useState as useState63, useRef as useRef39 } from "react";
29466
+ import { useEffect as useEffect48, useState as useState64, useRef as useRef40 } from "react";
29079
29467
  import Image12 from "next/image";
29080
29468
  import { motion as motion2, useScroll, useTransform, useMotionValue, useSpring } from "framer-motion";
29081
29469
  import { jsx as jsx262, jsxs as jsxs214 } from "react/jsx-runtime";
@@ -29094,9 +29482,9 @@ var ParallaxImageShowcase = ({
29094
29482
  const springConfig = { stiffness: 100, damping: 30 };
29095
29483
  const mouseXSpring = useSpring(mouseX, springConfig);
29096
29484
  const mouseYSpring = useSpring(mouseY, springConfig);
29097
- const [componentRect, setComponentRect] = useState63(null);
29098
- const componentRef = useRef39(null);
29099
- useEffect47(() => {
29485
+ const [componentRect, setComponentRect] = useState64(null);
29486
+ const componentRef = useRef40(null);
29487
+ useEffect48(() => {
29100
29488
  const updateRect = () => {
29101
29489
  if (componentRef.current) {
29102
29490
  setComponentRect(componentRef.current.getBoundingClientRect());
@@ -29110,7 +29498,7 @@ var ParallaxImageShowcase = ({
29110
29498
  window.removeEventListener("scroll", updateRect);
29111
29499
  };
29112
29500
  }, []);
29113
- useEffect47(() => {
29501
+ useEffect48(() => {
29114
29502
  const handleGlobalMouseMove = (e) => {
29115
29503
  if (!componentRect) return;
29116
29504
  const centerX = componentRect.left + componentRect.width / 2;
@@ -29754,7 +30142,7 @@ function PushButtonSelector({
29754
30142
  }
29755
30143
 
29756
30144
  // src/components/features/release-media-manager.tsx
29757
- import { useState as useState64, useRef as useRef40 } from "react";
30145
+ import { useState as useState65, useRef as useRef41 } from "react";
29758
30146
  import { Trash2 as Trash25, Plus as Plus5, Image as ImageIcon3, Video as Video5, Upload as Upload4, Loader2 as Loader28, GripVertical as GripVertical2 } from "lucide-react";
29759
30147
  import Image13 from "next/image";
29760
30148
  import { jsx as jsx267, jsxs as jsxs219 } from "react/jsx-runtime";
@@ -29764,8 +30152,8 @@ function ReleaseMediaManager({
29764
30152
  onUpload,
29765
30153
  className = ""
29766
30154
  }) {
29767
- const fileInputRef = useRef40(null);
29768
- const [uploadingIndex, setUploadingIndex] = useState64(null);
30155
+ const fileInputRef = useRef41(null);
30156
+ const [uploadingIndex, setUploadingIndex] = useState65(null);
29769
30157
  const handleFileSelect = async (event) => {
29770
30158
  const file = event.target.files?.[0];
29771
30159
  if (!file) return;
@@ -30026,7 +30414,7 @@ var SelectButton = React94.forwardRef(
30026
30414
  SelectButton.displayName = "SelectButton";
30027
30415
 
30028
30416
  // src/components/features/seo-editor-preview.tsx
30029
- import { useState as useState65 } from "react";
30417
+ import { useState as useState66 } from "react";
30030
30418
  import { Globe as Globe3, ExternalLink as ExternalLink5, Upload as Upload5, X as X11, Loader2 as Loader29, Sparkles as Sparkles2 } from "lucide-react";
30031
30419
  import Image14 from "next/image";
30032
30420
  import { Fragment as Fragment42, jsx as jsx269, jsxs as jsxs221 } from "react/jsx-runtime";
@@ -30050,9 +30438,9 @@ function SEOEditorPreview({
30050
30438
  disabled = false,
30051
30439
  className = ""
30052
30440
  }) {
30053
- const [imageError, setImageError] = useState65(false);
30054
- const [isUploading, setIsUploading] = useState65(false);
30055
- const [fileInputRef, setFileInputRef] = useState65(null);
30441
+ const [imageError, setImageError] = useState66(false);
30442
+ const [isUploading, setIsUploading] = useState66(false);
30443
+ const [fileInputRef, setFileInputRef] = useState66(null);
30056
30444
  const displayTitle = seoTitle.trim() || title || "Untitled";
30057
30445
  const displayDescription = seoDescription.trim() || summary || "No description";
30058
30446
  const hasOgImage = ogImageUrl.trim();
@@ -30496,7 +30884,7 @@ function StatusFilterComponent({
30496
30884
  }
30497
30885
 
30498
30886
  // src/components/features/tags-selector.tsx
30499
- import { useState as useState66 } from "react";
30887
+ import { useState as useState67 } from "react";
30500
30888
  import { Search as Search2, X as X12, Plus as Plus6, Loader2 as Loader210 } from "lucide-react";
30501
30889
  import { jsx as jsx273, jsxs as jsxs224 } from "react/jsx-runtime";
30502
30890
  function TagsSelector({
@@ -30510,9 +30898,9 @@ function TagsSelector({
30510
30898
  disabled = false,
30511
30899
  allowCreate = true
30512
30900
  }) {
30513
- const [searchQuery, setSearchQuery] = useState66("");
30514
- const [showDropdown, setShowDropdown] = useState66(false);
30515
- const [isCreating, setIsCreating] = useState66(false);
30901
+ const [searchQuery, setSearchQuery] = useState67("");
30902
+ const [showDropdown, setShowDropdown] = useState67(false);
30903
+ const [isCreating, setIsCreating] = useState67(false);
30516
30904
  const handleTagAdd = (tagId) => {
30517
30905
  if (!selectedTagIds.includes(tagId) && selectedTagIds.length < maxTags) {
30518
30906
  onTagsChange([...selectedTagIds, tagId]);
@@ -30678,7 +31066,7 @@ function TagsSelector({
30678
31066
 
30679
31067
  // src/components/features/video-source-selector.tsx
30680
31068
  init_button2();
30681
- import { useState as useState67, useCallback as useCallback30 } from "react";
31069
+ import { useState as useState68, useCallback as useCallback31 } from "react";
30682
31070
  import { Upload as Upload6, Sparkles as Sparkles3, X as X13, Video as Video6 } from "lucide-react";
30683
31071
  import { jsx as jsx274, jsxs as jsxs225 } from "react/jsx-runtime";
30684
31072
  function VideoSourceSelector({
@@ -30703,11 +31091,11 @@ function VideoSourceSelector({
30703
31091
  showTitle = true,
30704
31092
  className = ""
30705
31093
  }) {
30706
- const [isUploading, setIsUploading] = useState67(false);
30707
- const [uploadProgress, setUploadProgress] = useState67(0);
30708
- const [uploadMessage, setUploadMessage] = useState67("");
30709
- const [uploadError, setUploadError] = useState67(null);
30710
- const handleUploadClick = useCallback30(() => {
31094
+ const [isUploading, setIsUploading] = useState68(false);
31095
+ const [uploadProgress, setUploadProgress] = useState68(0);
31096
+ const [uploadMessage, setUploadMessage] = useState68("");
31097
+ const [uploadError, setUploadError] = useState68(null);
31098
+ const handleUploadClick = useCallback31(() => {
30711
31099
  const input = document.createElement("input");
30712
31100
  input.type = "file";
30713
31101
  input.accept = "video/*";
@@ -30738,7 +31126,7 @@ function VideoSourceSelector({
30738
31126
  };
30739
31127
  input.click();
30740
31128
  }, [onUploadVideo, onMainVideoUrlChange]);
30741
- const handleDeleteVideo = useCallback30(() => {
31129
+ const handleDeleteVideo = useCallback31(() => {
30742
31130
  onMainVideoUrlChange("");
30743
31131
  }, [onMainVideoUrlChange]);
30744
31132
  return /* @__PURE__ */ jsxs225("div", { className: `space-y-4 p-6 bg-ods-card border border-ods-border rounded-lg ${className}`, children: [
@@ -31057,7 +31445,7 @@ function TranscriptSummaryEditor({
31057
31445
  }
31058
31446
 
31059
31447
  // src/components/features/highlight-video-section.tsx
31060
- import { useState as useState68 } from "react";
31448
+ import { useState as useState69 } from "react";
31061
31449
  import { Sparkles as Sparkles5, Upload as Upload7 } from "lucide-react";
31062
31450
  init_button2();
31063
31451
 
@@ -31356,7 +31744,7 @@ function HighlightVideoSection({
31356
31744
  disabled = false,
31357
31745
  className = ""
31358
31746
  }) {
31359
- const [uploadError, setUploadError] = useState68(null);
31747
+ const [uploadError, setUploadError] = useState69(null);
31360
31748
  const handleUploadClick = () => {
31361
31749
  const input = document.createElement("input");
31362
31750
  input.type = "file";
@@ -32200,7 +32588,7 @@ function ViewToggle({
32200
32588
 
32201
32589
  // src/components/features/policy-configuration-panel.tsx
32202
32590
  init_cn();
32203
- import { useRef as useRef41, useEffect as useEffect48, useState as useState69 } from "react";
32591
+ import { useRef as useRef42, useEffect as useEffect49, useState as useState70 } from "react";
32204
32592
  import { ChevronDown as ChevronDown8 } from "lucide-react";
32205
32593
  init_button2();
32206
32594
 
@@ -32381,9 +32769,9 @@ var PolicyRow = ({ policy, categoryId, editMode, onPermissionChange }) => {
32381
32769
  ] });
32382
32770
  };
32383
32771
  var useAnimatedHeight = (isExpanded) => {
32384
- const [height, setHeight] = useState69(0);
32385
- const contentRef = useRef41(null);
32386
- useEffect48(() => {
32772
+ const [height, setHeight] = useState70(0);
32773
+ const contentRef = useRef42(null);
32774
+ useEffect49(() => {
32387
32775
  if (contentRef.current) {
32388
32776
  const contentHeight = contentRef.current.scrollHeight;
32389
32777
  setHeight(isExpanded ? contentHeight : 0);
@@ -32539,7 +32927,7 @@ PolicyConfigurationPanel.displayName = "PolicyConfigurationPanel";
32539
32927
  init_button2();
32540
32928
  init_cn();
32541
32929
  import { getCountries as getCountries2 } from "libphonenumber-js";
32542
- import { useEffect as useEffect49, useState as useState70 } from "react";
32930
+ import { useEffect as useEffect50, useState as useState71 } from "react";
32543
32931
  import { Fragment as Fragment44, jsx as jsx294, jsxs as jsxs241 } from "react/jsx-runtime";
32544
32932
  function WaitlistForm({
32545
32933
  id = "waitlist-form",
@@ -32559,21 +32947,21 @@ function WaitlistForm({
32559
32947
  privacyPolicyUrl,
32560
32948
  consentText = "I agree to receive recurring automated text messages at the phone number provided. Msg & data rates may apply. Msg frequency varies. Reply HELP for help and STOP to cancel."
32561
32949
  }) {
32562
- const [email, setEmail] = useState70(defaultEmail);
32563
- const [phone, setPhone] = useState70(defaultPhone);
32564
- const [countryCode, setCountryCode] = useState70("US");
32950
+ const [email, setEmail] = useState71(defaultEmail);
32951
+ const [phone, setPhone] = useState71(defaultPhone);
32952
+ const [countryCode, setCountryCode] = useState71("US");
32565
32953
  const { toast } = useToast();
32566
- const [smsConsent, setSmsConsent] = useState70(false);
32567
- const [isClient, setIsClient] = useState70(false);
32568
- const [isPhoneInvalid, setIsPhoneInvalid] = useState70(false);
32569
- const [showConsentError, setShowConsentError] = useState70(false);
32954
+ const [smsConsent, setSmsConsent] = useState71(false);
32955
+ const [isClient, setIsClient] = useState71(false);
32956
+ const [isPhoneInvalid, setIsPhoneInvalid] = useState71(false);
32957
+ const [showConsentError, setShowConsentError] = useState71(false);
32570
32958
  const isMailDomainGeneric = hasGenericEmailDomain(email);
32571
- useEffect49(() => {
32959
+ useEffect50(() => {
32572
32960
  if (defaultEmail) {
32573
32961
  setEmail(defaultEmail);
32574
32962
  }
32575
32963
  }, [defaultEmail]);
32576
- useEffect49(() => {
32964
+ useEffect50(() => {
32577
32965
  setIsClient(true);
32578
32966
  if (!geoApiUrl) return;
32579
32967
  const supportedCountries = new Set(getCountries2());
@@ -33146,22 +33534,22 @@ function EmptyState3() {
33146
33534
  }
33147
33535
 
33148
33536
  // src/components/features/board/use-board-collapse.ts
33149
- import { useCallback as useCallback32, useState as useState71 } from "react";
33537
+ import { useCallback as useCallback33, useState as useState72 } from "react";
33150
33538
  function useBoardCollapse(storageKey) {
33151
33539
  const [persisted, setPersisted] = useLocalStorage(
33152
33540
  storageKey ?? "__board_collapse_unused__",
33153
33541
  {}
33154
33542
  );
33155
- const [memory, setMemory] = useState71({});
33543
+ const [memory, setMemory] = useState72({});
33156
33544
  const collapsed = storageKey ? persisted : memory;
33157
33545
  const setMap = storageKey ? setPersisted : setMemory;
33158
- const toggle = useCallback32(
33546
+ const toggle = useCallback33(
33159
33547
  (columnId) => {
33160
33548
  setMap((prev) => ({ ...prev, [columnId]: !prev[columnId] }));
33161
33549
  },
33162
33550
  [setMap]
33163
33551
  );
33164
- const setCollapsed = useCallback32(
33552
+ const setCollapsed = useCallback33(
33165
33553
  (columnId, value) => {
33166
33554
  setMap((prev) => ({ ...prev, [columnId]: value }));
33167
33555
  },
@@ -33618,6 +34006,7 @@ export {
33618
34006
  CONNECTION_STATUS,
33619
34007
  NETWORK_CONFIG,
33620
34008
  useChunkCatchup,
34009
+ useJetStreamDialogSubscription,
33621
34010
  useNatsDialogSubscription,
33622
34011
  buildNatsWsUrl,
33623
34012
  parseChunkToAction,
@@ -34083,4 +34472,4 @@ export {
34083
34472
  TMCG_SOCIAL_PLATFORMS,
34084
34473
  assets
34085
34474
  };
34086
- //# sourceMappingURL=chunk-C5VTN2SB.js.map
34475
+ //# sourceMappingURL=chunk-BXPH5SOL.js.map