@cuekit-ai/react 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -37,7 +37,7 @@ import {
37
37
  setWebRTCCallbacks,
38
38
  setWebRTCConfig,
39
39
  validateDynamicElements
40
- } from "./chunk-VQ6DNY3R.mjs";
40
+ } from "./chunk-24V3WQXJ.mjs";
41
41
 
42
42
  // node_modules/inline-style-parser/index.js
43
43
  var require_inline_style_parser = __commonJS({
@@ -74,17 +74,17 @@ var require_inline_style_parser = __commonJS({
74
74
  function position3() {
75
75
  var start2 = { line: lineno, column };
76
76
  return function(node2) {
77
- node2.position = new Position(start2);
77
+ node2.position = new Position2(start2);
78
78
  whitespace2();
79
79
  return node2;
80
80
  };
81
81
  }
82
- function Position(start2) {
82
+ function Position2(start2) {
83
83
  this.start = start2;
84
84
  this.end = { line: lineno, column };
85
85
  this.source = options.source;
86
86
  }
87
- Position.prototype.content = style;
87
+ Position2.prototype.content = style;
88
88
  var errorsList = [];
89
89
  function error(msg) {
90
90
  var err = new Error(
@@ -389,7 +389,7 @@ var require_core = __commonJS({
389
389
  root4.CryptoJS = factory();
390
390
  }
391
391
  })(exports, function() {
392
- var CryptoJS = CryptoJS || function(Math2, undefined2) {
392
+ var CryptoJS = CryptoJS || (function(Math2, undefined2) {
393
393
  var crypto;
394
394
  if (typeof window !== "undefined" && window.crypto) {
395
395
  crypto = window.crypto;
@@ -429,7 +429,7 @@ var require_core = __commonJS({
429
429
  }
430
430
  throw new Error("Native crypto module could not be used to get secure random number.");
431
431
  };
432
- var create2 = Object.create || /* @__PURE__ */ function() {
432
+ var create2 = Object.create || /* @__PURE__ */ (function() {
433
433
  function F2() {
434
434
  }
435
435
  return function(obj) {
@@ -439,10 +439,10 @@ var require_core = __commonJS({
439
439
  F2.prototype = null;
440
440
  return subtype;
441
441
  };
442
- }();
442
+ })();
443
443
  var C = {};
444
444
  var C_lib = C.lib = {};
445
- var Base = C_lib.Base = /* @__PURE__ */ function() {
445
+ var Base = C_lib.Base = /* @__PURE__ */ (function() {
446
446
  return {
447
447
  /**
448
448
  * Creates a new object that inherits from this object.
@@ -541,7 +541,7 @@ var require_core = __commonJS({
541
541
  return this.init.prototype.extend(this);
542
542
  }
543
543
  };
544
- }();
544
+ })();
545
545
  var WordArray = C_lib.WordArray = Base.extend({
546
546
  /**
547
547
  * Initializes a newly created word array.
@@ -979,7 +979,7 @@ var require_core = __commonJS({
979
979
  });
980
980
  var C_algo = C.algo = {};
981
981
  return C;
982
- }(Math);
982
+ })(Math);
983
983
  return CryptoJS;
984
984
  });
985
985
  }
@@ -1165,7 +1165,7 @@ var require_md5 = __commonJS({
1165
1165
  }
1166
1166
  });
1167
1167
 
1168
- // src/providers/cuekit-provider.tsx
1168
+ // src/providers/ansyr-provider.tsx
1169
1169
  import React, { createContext, useContext, useEffect, useState } from "react";
1170
1170
 
1171
1171
  // src/core/init.ts
@@ -1222,9 +1222,9 @@ var initWebRTC = (apiKey) => {
1222
1222
  return initWebRTCWithDeployedBackend(apiKey);
1223
1223
  };
1224
1224
 
1225
- // src/providers/cuekit-provider.tsx
1226
- if (typeof window !== "undefined" && !globalThis.CuekitStore) {
1227
- globalThis.CuekitStore = {
1225
+ // src/providers/ansyr-provider.tsx
1226
+ if (typeof window !== "undefined" && !globalThis.AnsyrStore) {
1227
+ globalThis.AnsyrStore = {
1228
1228
  intent: null,
1229
1229
  lastText: "",
1230
1230
  lastClickedLabel: "",
@@ -1232,38 +1232,46 @@ if (typeof window !== "undefined" && !globalThis.CuekitStore) {
1232
1232
  appId: void 0,
1233
1233
  deviceId: void 0,
1234
1234
  update(data) {
1235
- Object.assign(globalThis.CuekitStore, data);
1235
+ Object.assign(globalThis.AnsyrStore, data);
1236
1236
  }
1237
1237
  };
1238
1238
  }
1239
- var QubeContext = createContext({
1239
+ var AnsyrContext = createContext({
1240
1240
  apiKey: "",
1241
- appId: ""
1241
+ appId: "",
1242
+ title: "ansyr.ai",
1243
+ showLogo: true,
1244
+ showAIIcon: true,
1245
+ showUserIcon: true
1242
1246
  });
1243
- var useQubeContext = () => useContext(QubeContext);
1247
+ var useAnsyrContext = () => useContext(AnsyrContext);
1244
1248
  var getUniqueId = () => {
1245
1249
  if (typeof window === "undefined") {
1246
1250
  return "server-" + Date.now().toString(36);
1247
1251
  }
1248
1252
  try {
1249
- let id = localStorage.getItem("cuekit_device_id");
1253
+ let id = localStorage.getItem("ansyr_device_id");
1250
1254
  if (!id) {
1251
1255
  id = Date.now().toString(36) + Math.random().toString(36).substring(2);
1252
- localStorage.setItem("cuekit_device_id", id);
1256
+ localStorage.setItem("ansyr_device_id", id);
1253
1257
  }
1254
1258
  return id;
1255
1259
  } catch {
1256
1260
  return "anon-" + Date.now().toString(36);
1257
1261
  }
1258
1262
  };
1259
- var CuekitProvider = ({
1263
+ var AnsyrProvider = ({
1260
1264
  apiKey,
1261
1265
  deviceId = "",
1262
1266
  appId,
1263
1267
  children,
1264
1268
  navigationHandler,
1265
1269
  onConnectionStateChange,
1266
- onParticipantUpdate
1270
+ onParticipantUpdate,
1271
+ title = "ansyr.ai",
1272
+ showLogo = true,
1273
+ showAIIcon = true,
1274
+ showUserIcon = true
1267
1275
  }) => {
1268
1276
  const [internalDeviceId, setInternalDeviceId] = useState(deviceId);
1269
1277
  useEffect(() => {
@@ -1285,7 +1293,7 @@ var CuekitProvider = ({
1285
1293
  };
1286
1294
  }, [navigationHandler]);
1287
1295
  useEffect(() => {
1288
- import("./webrtc-service-3TOBGQF7.mjs").then(({ setWebRTCCallbacks: setWebRTCCallbacks2 }) => {
1296
+ import("./webrtc-service-N76TYFI4.mjs").then(({ setWebRTCCallbacks: setWebRTCCallbacks2 }) => {
1289
1297
  setWebRTCCallbacks2({
1290
1298
  onNavigationCommand: (command) => {
1291
1299
  if (command.data.actionType === "navigate" && command.data.routeName) {
@@ -1311,8 +1319,8 @@ var CuekitProvider = ({
1311
1319
  }, [onConnectionStateChange, onParticipantUpdate, navigationHandler]);
1312
1320
  useEffect(() => {
1313
1321
  const updateGlobalStore = (id) => {
1314
- if (typeof window !== "undefined" && globalThis.CuekitStore) {
1315
- globalThis.CuekitStore.update({
1322
+ if (typeof window !== "undefined" && globalThis.AnsyrStore) {
1323
+ globalThis.AnsyrStore.update({
1316
1324
  apiKey,
1317
1325
  appId,
1318
1326
  deviceId: id
@@ -1362,11 +1370,15 @@ var CuekitProvider = ({
1362
1370
  };
1363
1371
  }, [apiKey, appId, internalDeviceId]);
1364
1372
  return /* @__PURE__ */ React.createElement(
1365
- QubeContext.Provider,
1373
+ AnsyrContext.Provider,
1366
1374
  {
1367
1375
  value: {
1368
1376
  apiKey,
1369
- appId
1377
+ appId,
1378
+ title,
1379
+ showLogo,
1380
+ showAIIcon,
1381
+ showUserIcon
1370
1382
  }
1371
1383
  },
1372
1384
  children
@@ -1374,7 +1386,7 @@ var CuekitProvider = ({
1374
1386
  };
1375
1387
 
1376
1388
  // src/components/mic-button.tsx
1377
- import React11, { useState as useState10, useEffect as useEffect10, useCallback as useCallback5, useRef as useRef7 } from "react";
1389
+ import React15, { useState as useState12, useEffect as useEffect12, useCallback as useCallback6, useRef as useRef10 } from "react";
1378
1390
 
1379
1391
  // src/hooks/use-cuekit.ts
1380
1392
  import { useState as useState3, useCallback as useCallback2, useRef as useRef2 } from "react";
@@ -1420,22 +1432,25 @@ var useWebRTC = (options) => {
1420
1432
  options?.onAISpeechStart,
1421
1433
  options?.onAISpeechEnd
1422
1434
  ]);
1423
- const connect = useCallback(async (identity, apiKey, appId) => {
1424
- try {
1425
- setError(null);
1426
- setIsConnecting(true);
1427
- const authData = await authenticate(identity, apiKey || _apiKey, appId || _appId);
1428
- await connectToRoom(authData.livekit_url, authData.livekit_token);
1429
- setRoom(getRoom());
1430
- setIsConnected(true);
1431
- return authData;
1432
- } catch (err) {
1433
- setError(err.message || "Failed to connect");
1434
- setIsConnected(false);
1435
- } finally {
1436
- setIsConnecting(false);
1437
- }
1438
- }, []);
1435
+ const connect = useCallback(
1436
+ async (identity, apiKey, appId, language) => {
1437
+ try {
1438
+ setError(null);
1439
+ setIsConnecting(true);
1440
+ const authData = await authenticate(identity, apiKey || _apiKey, appId || _appId, language);
1441
+ await connectToRoom(authData.livekit_url, authData.livekit_token);
1442
+ setRoom(getRoom());
1443
+ setIsConnected(true);
1444
+ return authData;
1445
+ } catch (err) {
1446
+ setError(err.message || "Failed to connect");
1447
+ setIsConnected(false);
1448
+ } finally {
1449
+ setIsConnecting(false);
1450
+ }
1451
+ },
1452
+ []
1453
+ );
1439
1454
  const disconnect = useCallback(async () => {
1440
1455
  await disconnectFromRoom();
1441
1456
  setIsConnected(false);
@@ -1513,6 +1528,7 @@ var useCuekit = (options) => {
1513
1528
  }, []);
1514
1529
  const [micState, setMicState] = useState3("idle");
1515
1530
  const [status, setStatus] = useState3("");
1531
+ const [muteState, setMuteState] = useState3({ isMuted: false, canMute: false });
1516
1532
  const handleNavigationCommand = (event) => {
1517
1533
  console.log(`\u2B07\uFE0F Received event from backend: ${event.type}`, event);
1518
1534
  switch (event.type) {
@@ -1577,6 +1593,22 @@ var useCuekit = (options) => {
1577
1593
  }
1578
1594
  break;
1579
1595
  }
1596
+ case "chat": {
1597
+ const chatData = event.data;
1598
+ console.log("\u{1F4AC} Chat message received:", chatData);
1599
+ if (chatData.message && chatData.sender === "ai") {
1600
+ const newMessage = {
1601
+ id: `ai-${Date.now()}`,
1602
+ role: "ai",
1603
+ text: chatData.message,
1604
+ isFinal: true,
1605
+ timestamp: new Date(chatData.timestamp || Date.now()).toISOString()
1606
+ };
1607
+ setMessages((prev) => [...prev, newMessage]);
1608
+ setMicState("listening");
1609
+ }
1610
+ break;
1611
+ }
1580
1612
  case "request_runtime_data": {
1581
1613
  console.log("\u{1F9E0} Requesting runtime data");
1582
1614
  sendRuntimeData();
@@ -1609,17 +1641,21 @@ var useCuekit = (options) => {
1609
1641
  switch (state) {
1610
1642
  case "connecting":
1611
1643
  setStatus("Connecting...");
1644
+ setMuteState((prev) => ({ ...prev, canMute: false }));
1612
1645
  break;
1613
1646
  case "connected":
1614
1647
  setStatus("");
1615
1648
  setMicState("listening");
1649
+ setMuteState((prev) => ({ ...prev, canMute: true }));
1616
1650
  break;
1617
1651
  case "disconnected":
1618
1652
  setStatus("Disconnected");
1619
1653
  setMicState("idle");
1654
+ setMuteState({ isMuted: false, canMute: false });
1620
1655
  break;
1621
1656
  case "reconnecting":
1622
1657
  setStatus("Reconnecting...");
1658
+ setMuteState((prev) => ({ ...prev, canMute: false }));
1623
1659
  break;
1624
1660
  default:
1625
1661
  break;
@@ -1632,8 +1668,8 @@ var useCuekit = (options) => {
1632
1668
  onNavigationCommand: handleNavigationCommand
1633
1669
  });
1634
1670
  const connect = useCallback2(
1635
- async (identity, apiKey, appId) => {
1636
- await webrtc.connect(identity, apiKey, appId);
1671
+ async (identity, apiKey, appId, language) => {
1672
+ await webrtc.connect(identity, apiKey, appId, language);
1637
1673
  },
1638
1674
  [webrtc]
1639
1675
  );
@@ -1641,7 +1677,88 @@ var useCuekit = (options) => {
1641
1677
  await webrtc.disconnect();
1642
1678
  clearMessages();
1643
1679
  setMicState("idle");
1680
+ setMuteState({ isMuted: false, canMute: false });
1644
1681
  }, [webrtc, clearMessages]);
1682
+ const toggleMute = useCallback2(async () => {
1683
+ if (!webrtc.isConnected) return;
1684
+ try {
1685
+ const room = webrtc.room;
1686
+ if (!room) return;
1687
+ const localParticipant = room.localParticipant;
1688
+ const audioTrack = localParticipant.getTrackPublication(Track.Source.Microphone)?.track;
1689
+ if (audioTrack) {
1690
+ if (muteState.isMuted) {
1691
+ await audioTrack.unmute();
1692
+ setMuteState((prev) => ({ ...prev, isMuted: false }));
1693
+ } else {
1694
+ await audioTrack.mute();
1695
+ setMuteState((prev) => ({ ...prev, isMuted: true }));
1696
+ }
1697
+ }
1698
+ } catch (error) {
1699
+ console.error("Failed to toggle mute:", error);
1700
+ }
1701
+ }, [webrtc, muteState.isMuted]);
1702
+ const setMute = useCallback2(
1703
+ async (muted) => {
1704
+ if (!webrtc.isConnected) return;
1705
+ try {
1706
+ const room = webrtc.room;
1707
+ if (!room) return;
1708
+ const localParticipant = room.localParticipant;
1709
+ const audioTrack = localParticipant.getTrackPublication(Track.Source.Microphone)?.track;
1710
+ if (audioTrack) {
1711
+ if (muted && !muteState.isMuted) {
1712
+ await audioTrack.mute();
1713
+ setMuteState((prev) => ({ ...prev, isMuted: true }));
1714
+ } else if (!muted && muteState.isMuted) {
1715
+ await audioTrack.unmute();
1716
+ setMuteState((prev) => ({ ...prev, isMuted: false }));
1717
+ }
1718
+ }
1719
+ } catch (error) {
1720
+ console.error("Failed to set mute:", error);
1721
+ }
1722
+ },
1723
+ [webrtc, muteState.isMuted]
1724
+ );
1725
+ const sendChatMessage = useCallback2(
1726
+ async (message) => {
1727
+ if (!webrtc.isConnected) {
1728
+ console.warn("Cannot send chat message: not connected to LiveKit");
1729
+ return;
1730
+ }
1731
+ try {
1732
+ const room = webrtc.room;
1733
+ if (!room) return;
1734
+ const payload = {
1735
+ type: "chat",
1736
+ message,
1737
+ timestamp: Date.now(),
1738
+ sender: "user"
1739
+ };
1740
+ console.log("\u{1F4E4} Sending chat message via LiveKit:", payload);
1741
+ const encoder = new TextEncoder();
1742
+ const encodedData = encoder.encode(JSON.stringify(payload));
1743
+ await room.localParticipant.publishData(encodedData, {
1744
+ reliable: true
1745
+ });
1746
+ const newMessage = {
1747
+ id: `user-${Date.now()}`,
1748
+ role: "user",
1749
+ text: message,
1750
+ isFinal: true,
1751
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1752
+ };
1753
+ setMessages((prev) => [...prev, newMessage]);
1754
+ setMicState("thinking");
1755
+ } catch (error) {
1756
+ console.error("Failed to send chat message:", error);
1757
+ throw error;
1758
+ }
1759
+ },
1760
+ [webrtc]
1761
+ );
1645
1762
  return {
1646
1763
  ...webrtc,
1647
1764
  messages,
@@ -1650,12 +1767,16 @@ var useCuekit = (options) => {
1650
1767
  status,
1651
1768
  setStatus,
1652
1769
  connect,
1653
- disconnect
1770
+ disconnect,
1771
+ muteState,
1772
+ toggleMute,
1773
+ setMute,
1774
+ sendChatMessage
1654
1775
  };
1655
1776
  };
1656
1777
 
1657
1778
  // src/components/chat-popup.tsx
1658
- import React6, { useState as useState5, useEffect as useEffect5, useRef as useRef3 } from "react";
1779
+ import React10, { useState as useState6, useEffect as useEffect6, useRef as useRef5 } from "react";
1659
1780
 
1660
1781
  // node_modules/devlop/lib/default.js
1661
1782
  function ok() {
@@ -3530,7 +3651,7 @@ var urlAttributes = {
3530
3651
 
3531
3652
  // node_modules/react-markdown/lib/index.js
3532
3653
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3533
- import { useEffect as useEffect4, useState as useState4 } from "react";
3654
+ import { useEffect as useEffect3, useState as useState4 } from "react";
3534
3655
 
3535
3656
  // node_modules/mdast-util-to-string/lib/index.js
3536
3657
  var emptyOptions2 = {};
@@ -9252,7 +9373,7 @@ var convert = (
9252
9373
  * @param {Test} [test]
9253
9374
  * @returns {Check}
9254
9375
  */
9255
- function(test) {
9376
+ (function(test) {
9256
9377
  if (test === null || test === void 0) {
9257
9378
  return ok2;
9258
9379
  }
@@ -9266,7 +9387,7 @@ var convert = (
9266
9387
  return typeFactory(test);
9267
9388
  }
9268
9389
  throw new Error("Expected function, string, or object as test");
9269
- }
9390
+ })
9270
9391
  );
9271
9392
  function anyFactory(tests) {
9272
9393
  const checks2 = [];
@@ -10446,7 +10567,7 @@ var CallableInstance = (
10446
10567
  * @param {string | symbol} property
10447
10568
  * @returns {(...parameters: Array<unknown>) => unknown}
10448
10569
  */
10449
- function(property) {
10570
+ (function(property) {
10450
10571
  const self2 = this;
10451
10572
  const constr = self2.constructor;
10452
10573
  const proto = (
@@ -10461,7 +10582,7 @@ var CallableInstance = (
10461
10582
  };
10462
10583
  Object.setPrototypeOf(apply, proto);
10463
10584
  return apply;
10464
- }
10585
+ })
10465
10586
  );
10466
10587
 
10467
10588
  // node_modules/unified/lib/index.js
@@ -14399,6 +14520,659 @@ var PhoneOffIcon = ({ width = 24, height = 24, className, ...props }) => {
14399
14520
  };
14400
14521
  var phone_off_default = PhoneOffIcon;
14401
14522
 
14523
+ // src/components/svgs/mic-off.tsx
14524
+ import React6 from "react";
14525
+ var MicOffIcon = ({ style, className }) => {
14526
+ return /* @__PURE__ */ React6.createElement(
14527
+ "svg",
14528
+ {
14529
+ xmlns: "http://www.w3.org/2000/svg",
14530
+ width: "24",
14531
+ height: "24",
14532
+ viewBox: "0 0 24 24",
14533
+ fill: "none",
14534
+ stroke: "currentColor",
14535
+ strokeWidth: "2",
14536
+ strokeLinecap: "round",
14537
+ strokeLinejoin: "round",
14538
+ className: `lucide lucide-mic-off-icon lucide-mic-off ${className || ""}`,
14539
+ style
14540
+ },
14541
+ /* @__PURE__ */ React6.createElement("path", { d: "M12 19v3" }),
14542
+ /* @__PURE__ */ React6.createElement("path", { d: "M15 9.34V5a3 3 0 0 0-5.68-1.33" }),
14543
+ /* @__PURE__ */ React6.createElement("path", { d: "M16.95 16.95A7 7 0 0 1 5 12v-2" }),
14544
+ /* @__PURE__ */ React6.createElement("path", { d: "M18.89 13.23A7 7 0 0 0 19 12v-2" }),
14545
+ /* @__PURE__ */ React6.createElement("path", { d: "m2 2 20 20" }),
14546
+ /* @__PURE__ */ React6.createElement("path", { d: "M9 9v3a3 3 0 0 0 5.12 2.12" })
14547
+ );
14548
+ };
14549
+ var mic_off_default = MicOffIcon;
14550
+
14551
+ // src/components/svgs/mic.tsx
14552
+ import React7 from "react";
14553
+ var MicIcon = ({ width = 24, height = 24, className, ...props }) => {
14554
+ return /* @__PURE__ */ React7.createElement(
14555
+ "svg",
14556
+ {
14557
+ xmlns: "http://www.w3.org/2000/svg",
14558
+ width,
14559
+ height,
14560
+ viewBox: "0 0 24 24",
14561
+ fill: "none",
14562
+ stroke: "currentColor",
14563
+ strokeWidth: "2",
14564
+ strokeLinecap: "round",
14565
+ strokeLinejoin: "round",
14566
+ className,
14567
+ ...props
14568
+ },
14569
+ /* @__PURE__ */ React7.createElement("path", { d: "M12 19v3" }),
14570
+ /* @__PURE__ */ React7.createElement("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
14571
+ /* @__PURE__ */ React7.createElement("rect", { x: "9", y: "2", width: "6", height: "13", rx: "3" })
14572
+ );
14573
+ };
14574
+ var mic_default = MicIcon;
14575
+
14576
+ // src/components/draggable-resizable-container.tsx
14577
+ import React9, { useRef as useRef4, useEffect as useEffect5 } from "react";
14578
+
14579
+ // src/utils/draggable-resizable.ts
14580
+ import { useCallback as useCallback3, useRef as useRef3, useState as useState5, useEffect as useEffect4 } from "react";
14581
+ var absoluteToRelative = (position3, size, viewportWidth, viewportHeight) => {
14582
+ return {
14583
+ position: {
14584
+ xPercent: position3.x / viewportWidth * 100,
14585
+ yPercent: position3.y / viewportHeight * 100
14586
+ },
14587
+ size: {
14588
+ widthPercent: size.width / viewportWidth * 100,
14589
+ heightPercent: size.height / viewportHeight * 100
14590
+ }
14591
+ };
14592
+ };
14593
+ var relativeToAbsolute = (relativePosition, relativeSize, viewportWidth, viewportHeight) => {
14594
+ return {
14595
+ position: {
14596
+ x: relativePosition.xPercent / 100 * viewportWidth,
14597
+ y: relativePosition.yPercent / 100 * viewportHeight
14598
+ },
14599
+ size: {
14600
+ width: relativeSize.widthPercent / 100 * viewportWidth,
14601
+ height: relativeSize.heightPercent / 100 * viewportHeight
14602
+ }
14603
+ };
14604
+ };
14605
+ var DEFAULT_BOUNDS = {
14606
+ minWidth: 300,
14607
+ minHeight: 200,
14608
+ maxWidth: typeof window !== "undefined" ? Math.min(window.innerWidth * 0.92, 800) : 800,
14609
+ maxHeight: typeof window !== "undefined" ? Math.min(window.innerHeight * 0.9, 600) : 600
14610
+ };
14611
+ var DEFAULT_POSITION = { x: 0, y: 0 };
14612
+ var DEFAULT_SIZE = {
14613
+ width: 420,
14614
+ height: typeof window !== "undefined" ? Math.min(window.innerHeight * 0.55, 500) : 400
14615
+ };
14616
+ function useDraggableResizable(options = {}) {
14617
+ const {
14618
+ bounds = DEFAULT_BOUNDS,
14619
+ initialPosition = DEFAULT_POSITION,
14620
+ initialSize = DEFAULT_SIZE,
14621
+ onPositionChange,
14622
+ onSizeChange,
14623
+ disabled = false,
14624
+ dragHandle
14625
+ } = options;
14626
+ const [position3, setPositionState] = useState5(initialPosition);
14627
+ const [size, setSizeState] = useState5(initialSize);
14628
+ const [dragState, setDragState] = useState5({
14629
+ isDragging: false,
14630
+ startPosition: { x: 0, y: 0 },
14631
+ startMousePosition: { x: 0, y: 0 }
14632
+ });
14633
+ const [resizeState, setResizeState] = useState5({
14634
+ isResizing: false,
14635
+ direction: "se",
14636
+ startSize: { width: 0, height: 0 },
14637
+ startPosition: { x: 0, y: 0 },
14638
+ startMousePosition: { x: 0, y: 0 }
14639
+ });
14640
+ const containerRef = useRef3(null);
14641
+ const constrainPosition = useCallback3((pos, size2) => {
14642
+ const maxX = window.innerWidth - size2.width;
14643
+ const maxY = window.innerHeight - size2.height;
14644
+ return {
14645
+ x: Math.max(0, Math.min(pos.x, maxX)),
14646
+ y: Math.max(0, Math.min(pos.y, maxY))
14647
+ };
14648
+ }, []);
14649
+ const constrainSize = useCallback3(
14650
+ (newSize) => {
14651
+ return {
14652
+ width: Math.max(bounds.minWidth, Math.min(newSize.width, bounds.maxWidth || Infinity)),
14653
+ height: Math.max(bounds.minHeight, Math.min(newSize.height, bounds.maxHeight || Infinity))
14654
+ };
14655
+ },
14656
+ [bounds]
14657
+ );
14658
+ const setPosition = useCallback3(
14659
+ (newPosition) => {
14660
+ const constrainedPosition = constrainPosition(newPosition, size);
14661
+ setPositionState(constrainedPosition);
14662
+ onPositionChange?.(constrainedPosition);
14663
+ },
14664
+ [size, constrainPosition, onPositionChange]
14665
+ );
14666
+ const setSize = useCallback3(
14667
+ (newSize) => {
14668
+ const constrainedSize = constrainSize(newSize);
14669
+ setSizeState(constrainedSize);
14670
+ onSizeChange?.(constrainedSize);
14671
+ const constrainedPosition = constrainPosition(position3, constrainedSize);
14672
+ if (constrainedPosition.x !== position3.x || constrainedPosition.y !== position3.y) {
14673
+ setPositionState(constrainedPosition);
14674
+ onPositionChange?.(constrainedPosition);
14675
+ }
14676
+ },
14677
+ [position3, constrainSize, constrainPosition, onSizeChange, onPositionChange]
14678
+ );
14679
+ const resetToInitial = useCallback3(() => {
14680
+ setPositionState(initialPosition);
14681
+ setSizeState(initialSize);
14682
+ onPositionChange?.(initialPosition);
14683
+ onSizeChange?.(initialSize);
14684
+ }, [initialPosition, initialSize, onPositionChange, onSizeChange]);
14685
+ const handleDragStart = useCallback3(
14686
+ (e2) => {
14687
+ if (disabled) return;
14688
+ if (dragHandle) {
14689
+ const target = e2.target;
14690
+ if (!target.closest(dragHandle)) return;
14691
+ }
14692
+ e2.preventDefault();
14693
+ e2.stopPropagation();
14694
+ setDragState({
14695
+ isDragging: true,
14696
+ startPosition: { ...position3 },
14697
+ startMousePosition: { x: e2.clientX, y: e2.clientY }
14698
+ });
14699
+ },
14700
+ [disabled, dragHandle, position3]
14701
+ );
14702
+ const handleResizeStart = useCallback3(
14703
+ (direction) => (e2) => {
14704
+ if (disabled) return;
14705
+ e2.preventDefault();
14706
+ e2.stopPropagation();
14707
+ setResizeState({
14708
+ isResizing: true,
14709
+ direction,
14710
+ startSize: { ...size },
14711
+ startPosition: { ...position3 },
14712
+ startMousePosition: { x: e2.clientX, y: e2.clientY }
14713
+ });
14714
+ },
14715
+ [disabled, size, position3]
14716
+ );
14717
+ useEffect4(() => {
14718
+ const handleMouseMove = (e2) => {
14719
+ if (dragState.isDragging) {
14720
+ const deltaX = e2.clientX - dragState.startMousePosition.x;
14721
+ const deltaY = e2.clientY - dragState.startMousePosition.y;
14722
+ const newPosition = {
14723
+ x: dragState.startPosition.x + deltaX,
14724
+ y: dragState.startPosition.y + deltaY
14725
+ };
14726
+ setPosition(newPosition);
14727
+ } else if (resizeState.isResizing) {
14728
+ const deltaX = e2.clientX - resizeState.startMousePosition.x;
14729
+ const deltaY = e2.clientY - resizeState.startMousePosition.y;
14730
+ let newSize = { ...resizeState.startSize };
14731
+ let newPosition = { ...resizeState.startPosition };
14732
+ const { direction } = resizeState;
14733
+ if (direction.includes("e")) {
14734
+ newSize.width = resizeState.startSize.width + deltaX;
14735
+ }
14736
+ if (direction.includes("w")) {
14737
+ newSize.width = resizeState.startSize.width - deltaX;
14738
+ newPosition.x = resizeState.startPosition.x + deltaX;
14739
+ }
14740
+ if (direction.includes("s")) {
14741
+ newSize.height = resizeState.startSize.height + deltaY;
14742
+ }
14743
+ if (direction.includes("n")) {
14744
+ newSize.height = resizeState.startSize.height - deltaY;
14745
+ newPosition.y = resizeState.startPosition.y + deltaY;
14746
+ }
14747
+ setSize(newSize);
14748
+ if (newPosition.x !== resizeState.startPosition.x || newPosition.y !== resizeState.startPosition.y) {
14749
+ setPosition(newPosition);
14750
+ }
14751
+ }
14752
+ };
14753
+ const handleMouseUp = () => {
14754
+ setDragState((prev) => ({ ...prev, isDragging: false }));
14755
+ setResizeState((prev) => ({ ...prev, isResizing: false }));
14756
+ };
14757
+ if (dragState.isDragging || resizeState.isResizing) {
14758
+ document.addEventListener("mousemove", handleMouseMove);
14759
+ document.addEventListener("mouseup", handleMouseUp);
14760
+ }
14761
+ return () => {
14762
+ document.removeEventListener("mousemove", handleMouseMove);
14763
+ document.removeEventListener("mouseup", handleMouseUp);
14764
+ };
14765
+ }, [dragState, resizeState, setPosition, setSize]);
14766
+ const resizeHandlers = {
14767
+ n: { onMouseDown: handleResizeStart("n") },
14768
+ s: { onMouseDown: handleResizeStart("s") },
14769
+ e: { onMouseDown: handleResizeStart("e") },
14770
+ w: { onMouseDown: handleResizeStart("w") },
14771
+ ne: { onMouseDown: handleResizeStart("ne") },
14772
+ nw: { onMouseDown: handleResizeStart("nw") },
14773
+ se: { onMouseDown: handleResizeStart("se") },
14774
+ sw: { onMouseDown: handleResizeStart("sw") }
14775
+ };
14776
+ return {
14777
+ position: position3,
14778
+ size,
14779
+ isDragging: dragState.isDragging,
14780
+ isResizing: resizeState.isResizing,
14781
+ dragHandlers: {
14782
+ onMouseDown: handleDragStart
14783
+ },
14784
+ resizeHandlers,
14785
+ setPosition,
14786
+ setSize,
14787
+ resetToInitial
14788
+ };
14789
+ }
14790
+ function getResizeCursor(direction) {
14791
+ const cursorMap = {
14792
+ n: "n-resize",
14793
+ s: "s-resize",
14794
+ e: "e-resize",
14795
+ w: "w-resize",
14796
+ ne: "ne-resize",
14797
+ nw: "nw-resize",
14798
+ se: "se-resize",
14799
+ sw: "sw-resize"
14800
+ };
14801
+ return cursorMap[direction];
14802
+ }
14803
+
14804
+ // src/components/resize-handle.tsx
14805
+ import React8 from "react";
14806
+ var ResizeHandle = ({
14807
+ direction,
14808
+ onMouseDown,
14809
+ disabled = false,
14810
+ className = "",
14811
+ style = {},
14812
+ size = 8
14813
+ }) => {
14814
+ const getHandleStyle = () => {
14815
+ const baseStyle = {
14816
+ position: "absolute",
14817
+ backgroundColor: "transparent",
14818
+ cursor: disabled ? "default" : getResizeCursor(direction),
14819
+ zIndex: 1e3,
14820
+ userSelect: "none",
14821
+ ...style
14822
+ };
14823
+ switch (direction) {
14824
+ case "n":
14825
+ return {
14826
+ ...baseStyle,
14827
+ top: -size / 2,
14828
+ left: 0,
14829
+ right: 0,
14830
+ height: size
14831
+ };
14832
+ case "s":
14833
+ return {
14834
+ ...baseStyle,
14835
+ bottom: -size / 2,
14836
+ left: 0,
14837
+ right: 0,
14838
+ height: size
14839
+ };
14840
+ case "e":
14841
+ return {
14842
+ ...baseStyle,
14843
+ top: 0,
14844
+ bottom: 0,
14845
+ right: -size / 2,
14846
+ width: size
14847
+ };
14848
+ case "w":
14849
+ return {
14850
+ ...baseStyle,
14851
+ top: 0,
14852
+ bottom: 0,
14853
+ left: -size / 2,
14854
+ width: size
14855
+ };
14856
+ case "ne":
14857
+ return {
14858
+ ...baseStyle,
14859
+ top: -size / 2,
14860
+ right: -size / 2,
14861
+ width: size,
14862
+ height: size
14863
+ };
14864
+ case "nw":
14865
+ return {
14866
+ ...baseStyle,
14867
+ top: -size / 2,
14868
+ left: -size / 2,
14869
+ width: size,
14870
+ height: size
14871
+ };
14872
+ case "se":
14873
+ return {
14874
+ ...baseStyle,
14875
+ bottom: -size / 2,
14876
+ right: -size / 2,
14877
+ width: size,
14878
+ height: size
14879
+ };
14880
+ case "sw":
14881
+ return {
14882
+ ...baseStyle,
14883
+ bottom: -size / 2,
14884
+ left: -size / 2,
14885
+ width: size,
14886
+ height: size
14887
+ };
14888
+ default:
14889
+ return baseStyle;
14890
+ }
14891
+ };
14892
+ const handleMouseDown = (e2) => {
14893
+ if (!disabled) {
14894
+ onMouseDown(e2);
14895
+ }
14896
+ };
14897
+ return /* @__PURE__ */ React8.createElement(
14898
+ "div",
14899
+ {
14900
+ className: `resize-handle resize-handle-${direction} ${className}`,
14901
+ style: getHandleStyle(),
14902
+ onMouseDown: handleMouseDown,
14903
+ "data-direction": direction,
14904
+ "aria-label": `Resize ${direction}`
14905
+ }
14906
+ );
14907
+ };
14908
+ var ResizeHandles = ({
14909
+ onResizeStart,
14910
+ disabled = false,
14911
+ className = "",
14912
+ style = {},
14913
+ size = 8,
14914
+ showHandles = ["n", "s", "e", "w", "ne", "nw", "se", "sw"]
14915
+ }) => {
14916
+ return /* @__PURE__ */ React8.createElement(React8.Fragment, null, showHandles.map((direction) => /* @__PURE__ */ React8.createElement(
14917
+ ResizeHandle,
14918
+ {
14919
+ key: direction,
14920
+ direction,
14921
+ onMouseDown: onResizeStart(direction),
14922
+ disabled,
14923
+ className,
14924
+ style,
14925
+ size
14926
+ }
14927
+ )));
14928
+ };
14929
+
14930
+ // src/components/draggable-resizable-container.tsx
14931
+ var DraggableResizableContainer = ({
14932
+ children,
14933
+ className = "",
14934
+ style = {},
14935
+ dragHandle,
14936
+ showResizeHandles = true,
14937
+ resizeHandleSize = 8,
14938
+ onPositionChange,
14939
+ onSizeChange,
14940
+ onDragStart,
14941
+ onDragEnd,
14942
+ onResizeStart,
14943
+ onResizeEnd,
14944
+ storageKey,
14945
+ persistPosition = false,
14946
+ persistSize = false,
14947
+ ...options
14948
+ }) => {
14949
+ const containerRef = useRef4(null);
14950
+ const loadPersistedData = () => {
14951
+ if (!storageKey || typeof window === "undefined") return {};
14952
+ try {
14953
+ const data = localStorage.getItem(`cuekit-${storageKey}`);
14954
+ if (data) {
14955
+ const parsed = JSON.parse(data);
14956
+ if (parsed.relativePosition && parsed.relativeSize) {
14957
+ const viewportWidth = window.innerWidth;
14958
+ const viewportHeight = window.innerHeight;
14959
+ const { position: position4, size: size2 } = relativeToAbsolute(
14960
+ parsed.relativePosition,
14961
+ parsed.relativeSize,
14962
+ viewportWidth,
14963
+ viewportHeight
14964
+ );
14965
+ return { position: position4, size: size2 };
14966
+ }
14967
+ return {
14968
+ position: parsed.position,
14969
+ size: parsed.size
14970
+ };
14971
+ }
14972
+ } catch (error) {
14973
+ console.warn("Failed to load persisted position/size:", error);
14974
+ }
14975
+ return {};
14976
+ };
14977
+ const savePersistedData = (position4, size2) => {
14978
+ if (!storageKey || typeof window === "undefined") return;
14979
+ try {
14980
+ const viewportWidth = window.innerWidth;
14981
+ const viewportHeight = window.innerHeight;
14982
+ const { position: relativePosition, size: relativeSize } = absoluteToRelative(
14983
+ position4,
14984
+ size2,
14985
+ viewportWidth,
14986
+ viewportHeight
14987
+ );
14988
+ const data = {};
14989
+ if (persistPosition) {
14990
+ data.position = position4;
14991
+ data.relativePosition = relativePosition;
14992
+ }
14993
+ if (persistSize) {
14994
+ data.size = size2;
14995
+ data.relativeSize = relativeSize;
14996
+ }
14997
+ localStorage.setItem(`cuekit-${storageKey}`, JSON.stringify(data));
14998
+ } catch (error) {
14999
+ console.warn("Failed to save persisted position/size:", error);
15000
+ }
15001
+ };
15002
+ const persistedData = loadPersistedData();
15003
+ const initialPosition = persistedData.position || options.initialPosition;
15004
+ const initialSize = persistedData.size || options.initialSize;
15005
+ useEffect5(() => {
15006
+ const handleResize = () => {
15007
+ if (!storageKey || typeof window === "undefined") return;
15008
+ try {
15009
+ const data = localStorage.getItem(`cuekit-${storageKey}`);
15010
+ if (data) {
15011
+ const parsed = JSON.parse(data);
15012
+ if (parsed.relativePosition && parsed.relativeSize) {
15013
+ const viewportWidth = window.innerWidth;
15014
+ const viewportHeight = window.innerHeight;
15015
+ const { position: position4, size: size2 } = relativeToAbsolute(
15016
+ parsed.relativePosition,
15017
+ parsed.relativeSize,
15018
+ viewportWidth,
15019
+ viewportHeight
15020
+ );
15021
+ if (containerRef.current) {
15022
+ containerRef.current.style.left = `${position4.x}px`;
15023
+ containerRef.current.style.top = `${position4.y}px`;
15024
+ containerRef.current.style.width = `${size2.width}px`;
15025
+ containerRef.current.style.height = `${size2.height}px`;
15026
+ }
15027
+ }
15028
+ }
15029
+ } catch (error) {
15030
+ console.warn("Failed to update position on resize:", error);
15031
+ }
15032
+ };
15033
+ window.addEventListener("resize", handleResize);
15034
+ return () => window.removeEventListener("resize", handleResize);
15035
+ }, [storageKey]);
15036
+ const {
15037
+ position: position3,
15038
+ size,
15039
+ isDragging,
15040
+ isResizing,
15041
+ dragHandlers,
15042
+ resizeHandlers,
15043
+ setPosition,
15044
+ setSize
15045
+ } = useDraggableResizable({
15046
+ ...options,
15047
+ initialPosition,
15048
+ initialSize,
15049
+ onPositionChange: (pos) => {
15050
+ onPositionChange?.(pos);
15051
+ if (persistPosition || persistSize) {
15052
+ savePersistedData(pos, size);
15053
+ }
15054
+ },
15055
+ onSizeChange: (newSize) => {
15056
+ onSizeChange?.(newSize);
15057
+ if (persistPosition || persistSize) {
15058
+ savePersistedData(position3, newSize);
15059
+ }
15060
+ }
15061
+ });
15062
+ const handleDragStart = (e2) => {
15063
+ dragHandlers.onMouseDown(e2);
15064
+ onDragStart?.();
15065
+ };
15066
+ const handleResizeStart = (direction) => (e2) => {
15067
+ resizeHandlers[direction].onMouseDown(e2);
15068
+ onResizeStart?.();
15069
+ };
15070
+ useEffect5(() => {
15071
+ if (!isDragging) {
15072
+ onDragEnd?.();
15073
+ }
15074
+ }, [isDragging, onDragEnd]);
15075
+ useEffect5(() => {
15076
+ if (!isResizing) {
15077
+ onResizeEnd?.();
15078
+ }
15079
+ }, [isResizing, onResizeEnd]);
15080
+ const containerStyle = {
15081
+ position: "fixed",
15082
+ left: position3.x,
15083
+ top: position3.y,
15084
+ width: size.width,
15085
+ height: size.height,
15086
+ transform: "none",
15087
+ // We use left/top instead of transform for better performance
15088
+ zIndex: 1e3,
15089
+ ...style
15090
+ };
15091
+ const containerClassName = [
15092
+ "draggable-resizable-container",
15093
+ isDragging ? "is-dragging" : "",
15094
+ isResizing ? "is-resizing" : "",
15095
+ className
15096
+ ].filter(Boolean).join(" ");
15097
+ return /* @__PURE__ */ React9.createElement(
15098
+ "div",
15099
+ {
15100
+ ref: containerRef,
15101
+ className: containerClassName,
15102
+ style: containerStyle,
15103
+ "data-cuekit-ignore": true
15104
+ },
15105
+ /* @__PURE__ */ React9.createElement(
15106
+ "div",
15107
+ {
15108
+ className: "drag-handle",
15109
+ style: {
15110
+ position: "absolute",
15111
+ top: 0,
15112
+ left: 0,
15113
+ right: 0,
15114
+ height: "20px",
15115
+ // Height of the header area
15116
+ cursor: "move",
15117
+ zIndex: 10
15118
+ },
15119
+ onMouseDown: handleDragStart,
15120
+ "data-drag-handle": "true"
15121
+ }
15122
+ ),
15123
+ /* @__PURE__ */ React9.createElement(
15124
+ "div",
15125
+ {
15126
+ className: "draggable-content",
15127
+ style: {
15128
+ width: "100%",
15129
+ height: "100%",
15130
+ overflow: "hidden",
15131
+ display: "flex",
15132
+ flexDirection: "column"
15133
+ }
15134
+ },
15135
+ children
15136
+ ),
15137
+ showResizeHandles && /* @__PURE__ */ React9.createElement(
15138
+ ResizeHandles,
15139
+ {
15140
+ onResizeStart: handleResizeStart,
15141
+ disabled: options.disabled,
15142
+ size: resizeHandleSize
15143
+ }
15144
+ )
15145
+ );
15146
+ };
15147
+ var useDraggableResizableContainer = (storageKey) => {
15148
+ const loadData = () => {
15149
+ if (!storageKey || typeof window === "undefined") return null;
15150
+ try {
15151
+ const data = localStorage.getItem(`cuekit-${storageKey}`);
15152
+ return data ? JSON.parse(data) : null;
15153
+ } catch {
15154
+ return null;
15155
+ }
15156
+ };
15157
+ const saveData = (data) => {
15158
+ if (!storageKey || typeof window === "undefined") return;
15159
+ try {
15160
+ localStorage.setItem(`cuekit-${storageKey}`, JSON.stringify(data));
15161
+ } catch (error) {
15162
+ console.warn("Failed to save data:", error);
15163
+ }
15164
+ };
15165
+ const clearData = () => {
15166
+ if (!storageKey || typeof window === "undefined") return;
15167
+ try {
15168
+ localStorage.removeItem(`cuekit-${storageKey}`);
15169
+ } catch (error) {
15170
+ console.warn("Failed to clear data:", error);
15171
+ }
15172
+ };
15173
+ return { loadData, saveData, clearData };
15174
+ };
15175
+
14402
15176
  // src/components/chat-popup.tsx
14403
15177
  var ChatPopup = ({
14404
15178
  isOpen,
@@ -14415,15 +15189,28 @@ var ChatPopup = ({
14415
15189
  currentTheme = "dark",
14416
15190
  onThemeToggle,
14417
15191
  status,
14418
- anchor
15192
+ anchor,
15193
+ muteState,
15194
+ onToggleMute,
15195
+ // Draggable/Resizable props
15196
+ draggable = true,
15197
+ resizable = true,
15198
+ initialPosition,
15199
+ initialSize,
15200
+ onPositionChange,
15201
+ onSizeChange,
15202
+ persistPosition = true,
15203
+ persistSize = true,
15204
+ storageKey = "chat-popup"
14419
15205
  }) => {
14420
- const [inputText, setInputText] = useState5("");
14421
- const [isSending, setIsSending] = useState5(false);
14422
- const messagesEndRef = useRef3(null);
15206
+ const { title, showLogo, showAIIcon, showUserIcon } = useAnsyrContext();
15207
+ const [inputText, setInputText] = useState6("");
15208
+ const [isSending, setIsSending] = useState6(false);
15209
+ const messagesEndRef = useRef5(null);
14423
15210
  const scrollToBottom = () => {
14424
15211
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
14425
15212
  };
14426
- useEffect5(() => {
15213
+ useEffect6(() => {
14427
15214
  console.log("\u{1F4EC} ChatPopup received messages:", JSON.stringify(messages, null, 2));
14428
15215
  scrollToBottom();
14429
15216
  }, [messages]);
@@ -14445,7 +15232,6 @@ var ChatPopup = ({
14445
15232
  handleSend();
14446
15233
  }
14447
15234
  };
14448
- if (!isOpen || isMinimized) return null;
14449
15235
  const getStatusText = () => {
14450
15236
  if (status) return status;
14451
15237
  if (micState === "listening") return "Listening...";
@@ -14453,48 +15239,57 @@ var ChatPopup = ({
14453
15239
  if (micState === "replying") return "Responding...";
14454
15240
  return "Listening...";
14455
15241
  };
14456
- const getPositionStyle = () => {
15242
+ const getInitialPosition = () => {
15243
+ if (initialPosition) return initialPosition;
14457
15244
  if (!anchor) {
14458
15245
  return {
14459
- bottom: "100px",
14460
- right: "20px"
15246
+ x: window.innerWidth - 420 - 20,
15247
+ y: window.innerHeight - window.innerHeight * 0.55 - 20
14461
15248
  };
14462
15249
  }
14463
15250
  const bottomOffset = anchor.bottom + anchor.size + 16;
14464
- const baseStyle = {
14465
- bottom: `${bottomOffset}px`
14466
- };
15251
+ const popupHeight = window.innerHeight * 0.55;
15252
+ const y = window.innerHeight - bottomOffset - popupHeight;
14467
15253
  switch (anchor.position) {
14468
15254
  case "bottom-center":
14469
- return {
14470
- ...baseStyle,
14471
- left: "50%",
14472
- transform: "translateX(-50%)"
14473
- };
15255
+ return { x: (window.innerWidth - 420) / 2, y };
14474
15256
  case "bottom-left":
14475
- return {
14476
- ...baseStyle,
14477
- left: "20px"
14478
- };
15257
+ return { x: 20, y };
14479
15258
  case "bottom-right":
14480
15259
  default:
14481
- return {
14482
- ...baseStyle,
14483
- right: "20px"
14484
- };
15260
+ return { x: window.innerWidth - 420 - 20, y };
14485
15261
  }
14486
15262
  };
14487
- const positionStyle = getPositionStyle();
14488
- return /* @__PURE__ */ React6.createElement(
14489
- "div",
15263
+ const getInitialSize = () => {
15264
+ if (initialSize) return initialSize;
15265
+ return {
15266
+ width: 420,
15267
+ height: window.innerHeight * 0.55
15268
+ };
15269
+ };
15270
+ if (!isOpen || isMinimized) return null;
15271
+ return /* @__PURE__ */ React10.createElement(
15272
+ DraggableResizableContainer,
14490
15273
  {
14491
- "data-cuekit-ignore": true,
15274
+ initialPosition: getInitialPosition(),
15275
+ initialSize: getInitialSize(),
15276
+ onPositionChange,
15277
+ onSizeChange,
15278
+ persistPosition,
15279
+ persistSize,
15280
+ storageKey,
15281
+ disabled: !draggable && !resizable,
15282
+ showResizeHandles: resizable,
15283
+ bounds: {
15284
+ minWidth: 300,
15285
+ minHeight: 200,
15286
+ maxWidth: Math.min(window.innerWidth * 0.92, 800),
15287
+ // Cap at 800px max width
15288
+ maxHeight: Math.min(window.innerHeight * 0.9, 600)
15289
+ // Cap at 600px max height
15290
+ },
14492
15291
  className: `cuekit-voice-popup ${currentTheme === "dark" ? "cuekit-dark" : ""}`,
14493
15292
  style: {
14494
- position: "fixed",
14495
- width: "420px",
14496
- maxWidth: "92vw",
14497
- height: "55vh",
14498
15293
  borderRadius: "10px",
14499
15294
  background: "hsl(var(--voice-bg))",
14500
15295
  boxShadow: "var(--shadow-card)",
@@ -14502,13 +15297,11 @@ var ChatPopup = ({
14502
15297
  display: "flex",
14503
15298
  animation: "scaleIn 0.3s ease-out",
14504
15299
  flexDirection: "column",
14505
- zIndex: 1e3,
14506
15300
  fontFamily: "Inter, system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif",
14507
- overflow: "hidden",
14508
- ...positionStyle
15301
+ overflow: "hidden"
14509
15302
  }
14510
15303
  },
14511
- /* @__PURE__ */ React6.createElement(
15304
+ /* @__PURE__ */ React10.createElement(
14512
15305
  "div",
14513
15306
  {
14514
15307
  style: {
@@ -14519,14 +15312,14 @@ var ChatPopup = ({
14519
15312
  justifyContent: "space-between"
14520
15313
  }
14521
15314
  },
14522
- /* @__PURE__ */ React6.createElement("div", { style: { display: "flex", alignItems: "center", gap: 0 } }, /* @__PURE__ */ React6.createElement(
15315
+ /* @__PURE__ */ React10.createElement("div", { style: { display: "flex", alignItems: "center", gap: 0 } }, showLogo && /* @__PURE__ */ React10.createElement(
14523
15316
  "img",
14524
15317
  {
14525
15318
  src: "https://dashboard.cuekit.ai/_next/image?url=%2Fimages%2Fcuekit-logo-2.png&w=256&q=100",
14526
15319
  alt: "Cuekit AI",
14527
15320
  style: { width: 58, objectFit: "cover" }
14528
15321
  }
14529
- ), /* @__PURE__ */ React6.createElement(
15322
+ ), /* @__PURE__ */ React10.createElement(
14530
15323
  "div",
14531
15324
  {
14532
15325
  style: {
@@ -14537,10 +15330,11 @@ var ChatPopup = ({
14537
15330
  justifyContent: "center"
14538
15331
  }
14539
15332
  },
14540
- /* @__PURE__ */ React6.createElement(
15333
+ /* @__PURE__ */ React10.createElement(
14541
15334
  "span",
14542
15335
  {
14543
15336
  style: {
15337
+ paddingLeft: showLogo ? 0 : 12,
14544
15338
  fontSize: 18,
14545
15339
  fontWeight: 700,
14546
15340
  lineHeight: "1.2",
@@ -14552,9 +15346,9 @@ var ChatPopup = ({
14552
15346
  WebkitTextFillColor: "transparent"
14553
15347
  }
14554
15348
  },
14555
- "Cuekit.ai"
15349
+ title
14556
15350
  ),
14557
- /* @__PURE__ */ React6.createElement("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 4 } }, /* @__PURE__ */ React6.createElement(
15351
+ /* @__PURE__ */ React10.createElement("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 4 } }, /* @__PURE__ */ React10.createElement(
14558
15352
  "div",
14559
15353
  {
14560
15354
  style: {
@@ -14570,7 +15364,7 @@ var ChatPopup = ({
14570
15364
  fontWeight: "500"
14571
15365
  }
14572
15366
  },
14573
- /* @__PURE__ */ React6.createElement(
15367
+ /* @__PURE__ */ React10.createElement(
14574
15368
  "span",
14575
15369
  {
14576
15370
  style: {
@@ -14581,8 +15375,8 @@ var ChatPopup = ({
14581
15375
  )
14582
15376
  ))
14583
15377
  )),
14584
- /* @__PURE__ */ React6.createElement("div", { style: { minWidth: 100, textAlign: "center" } }),
14585
- /* @__PURE__ */ React6.createElement(
15378
+ /* @__PURE__ */ React10.createElement("div", { style: { minWidth: 100, textAlign: "center" } }),
15379
+ /* @__PURE__ */ React10.createElement(
14586
15380
  "div",
14587
15381
  {
14588
15382
  style: {
@@ -14594,7 +15388,7 @@ var ChatPopup = ({
14594
15388
  top: 16
14595
15389
  }
14596
15390
  },
14597
- onThemeToggle && /* @__PURE__ */ React6.createElement(
15391
+ onThemeToggle && /* @__PURE__ */ React10.createElement(
14598
15392
  "button",
14599
15393
  {
14600
15394
  onClick: () => {
@@ -14624,7 +15418,7 @@ var ChatPopup = ({
14624
15418
  "aria-label": "Toggle theme",
14625
15419
  title: `Switch to ${currentTheme === "dark" ? "light" : "dark"} mode`
14626
15420
  },
14627
- currentTheme === "dark" ? /* @__PURE__ */ React6.createElement(
15421
+ currentTheme === "dark" ? /* @__PURE__ */ React10.createElement(
14628
15422
  sun_default,
14629
15423
  {
14630
15424
  style: {
@@ -14634,7 +15428,7 @@ var ChatPopup = ({
14634
15428
  animation: "themeToggleEnter 0.3s ease-in-out"
14635
15429
  }
14636
15430
  }
14637
- ) : /* @__PURE__ */ React6.createElement(
15431
+ ) : /* @__PURE__ */ React10.createElement(
14638
15432
  moon_default,
14639
15433
  {
14640
15434
  style: {
@@ -14646,7 +15440,7 @@ var ChatPopup = ({
14646
15440
  }
14647
15441
  )
14648
15442
  ),
14649
- /* @__PURE__ */ React6.createElement(
15443
+ /* @__PURE__ */ React10.createElement(
14650
15444
  "button",
14651
15445
  {
14652
15446
  onClick: onMinimize,
@@ -14673,11 +15467,11 @@ var ChatPopup = ({
14673
15467
  "aria-label": "Minimize",
14674
15468
  title: "Minimize chat"
14675
15469
  },
14676
- /* @__PURE__ */ React6.createElement(close_default, { style: { width: 16, height: 16, color: "hsl(var(--voice-text-muted))" } })
15470
+ /* @__PURE__ */ React10.createElement(close_default, { style: { width: 16, height: 16, color: "hsl(var(--voice-text-muted))" } })
14677
15471
  )
14678
15472
  )
14679
15473
  ),
14680
- /* @__PURE__ */ React6.createElement(
15474
+ /* @__PURE__ */ React10.createElement(
14681
15475
  "div",
14682
15476
  {
14683
15477
  style: {
@@ -14690,7 +15484,7 @@ var ChatPopup = ({
14690
15484
  color: "hsl(var(--voice-text))"
14691
15485
  }
14692
15486
  },
14693
- messages.length === 0 ? /* @__PURE__ */ React6.createElement(
15487
+ messages.length === 0 ? /* @__PURE__ */ React10.createElement(
14694
15488
  "div",
14695
15489
  {
14696
15490
  style: {
@@ -14700,7 +15494,7 @@ var ChatPopup = ({
14700
15494
  }
14701
15495
  },
14702
15496
  "Start a conversation with CueKit AI"
14703
- ) : messages.map((message, index2) => /* @__PURE__ */ React6.createElement(
15497
+ ) : messages.map((message, index2) => /* @__PURE__ */ React10.createElement(
14704
15498
  "div",
14705
15499
  {
14706
15500
  key: index2,
@@ -14714,7 +15508,7 @@ var ChatPopup = ({
14714
15508
  justifyContent: message.sender === "user" ? "flex-end" : "flex-start"
14715
15509
  }
14716
15510
  },
14717
- message.sender === "assistant" && /* @__PURE__ */ React6.createElement(
15511
+ message.sender === "assistant" && showAIIcon && /* @__PURE__ */ React10.createElement(
14718
15512
  "div",
14719
15513
  {
14720
15514
  style: {
@@ -14729,7 +15523,7 @@ var ChatPopup = ({
14729
15523
  overflow: "hidden"
14730
15524
  }
14731
15525
  },
14732
- /* @__PURE__ */ React6.createElement(
15526
+ /* @__PURE__ */ React10.createElement(
14733
15527
  "img",
14734
15528
  {
14735
15529
  src: "https://dashboard.cuekit.ai/_next/image?url=%2Fimages%2Fcuekit-logo-2.png&w=256&q=100",
@@ -14743,7 +15537,7 @@ var ChatPopup = ({
14743
15537
  }
14744
15538
  )
14745
15539
  ),
14746
- /* @__PURE__ */ React6.createElement(
15540
+ /* @__PURE__ */ React10.createElement(
14747
15541
  "div",
14748
15542
  {
14749
15543
  style: {
@@ -14754,7 +15548,7 @@ var ChatPopup = ({
14754
15548
  flex: 1
14755
15549
  }
14756
15550
  },
14757
- /* @__PURE__ */ React6.createElement(
15551
+ /* @__PURE__ */ React10.createElement(
14758
15552
  "div",
14759
15553
  {
14760
15554
  style: {
@@ -14772,12 +15566,12 @@ var ChatPopup = ({
14772
15566
  marginLeft: message.sender === "user" ? "auto" : 0
14773
15567
  }
14774
15568
  },
14775
- /* @__PURE__ */ React6.createElement("div", null, /* @__PURE__ */ React6.createElement(
15569
+ /* @__PURE__ */ React10.createElement("div", null, /* @__PURE__ */ React10.createElement(
14776
15570
  Markdown,
14777
15571
  {
14778
15572
  remarkPlugins: [remarkGfm],
14779
15573
  components: {
14780
- p: ({ children }) => /* @__PURE__ */ React6.createElement(
15574
+ p: ({ children }) => /* @__PURE__ */ React10.createElement(
14781
15575
  "p",
14782
15576
  {
14783
15577
  style: {
@@ -14788,7 +15582,7 @@ var ChatPopup = ({
14788
15582
  },
14789
15583
  children
14790
15584
  ),
14791
- h1: ({ children }) => /* @__PURE__ */ React6.createElement(
15585
+ h1: ({ children }) => /* @__PURE__ */ React10.createElement(
14792
15586
  "h1",
14793
15587
  {
14794
15588
  style: {
@@ -14800,7 +15594,7 @@ var ChatPopup = ({
14800
15594
  },
14801
15595
  children
14802
15596
  ),
14803
- h2: ({ children }) => /* @__PURE__ */ React6.createElement(
15597
+ h2: ({ children }) => /* @__PURE__ */ React10.createElement(
14804
15598
  "h2",
14805
15599
  {
14806
15600
  style: {
@@ -14812,7 +15606,7 @@ var ChatPopup = ({
14812
15606
  },
14813
15607
  children
14814
15608
  ),
14815
- h3: ({ children }) => /* @__PURE__ */ React6.createElement(
15609
+ h3: ({ children }) => /* @__PURE__ */ React10.createElement(
14816
15610
  "h3",
14817
15611
  {
14818
15612
  style: {
@@ -14824,7 +15618,7 @@ var ChatPopup = ({
14824
15618
  },
14825
15619
  children
14826
15620
  ),
14827
- ul: ({ children }) => /* @__PURE__ */ React6.createElement(
15621
+ ul: ({ children }) => /* @__PURE__ */ React10.createElement(
14828
15622
  "ul",
14829
15623
  {
14830
15624
  style: {
@@ -14836,7 +15630,7 @@ var ChatPopup = ({
14836
15630
  },
14837
15631
  children
14838
15632
  ),
14839
- ol: ({ children }) => /* @__PURE__ */ React6.createElement(
15633
+ ol: ({ children }) => /* @__PURE__ */ React10.createElement(
14840
15634
  "ol",
14841
15635
  {
14842
15636
  style: {
@@ -14848,7 +15642,7 @@ var ChatPopup = ({
14848
15642
  },
14849
15643
  children
14850
15644
  ),
14851
- li: ({ children }) => /* @__PURE__ */ React6.createElement(
15645
+ li: ({ children }) => /* @__PURE__ */ React10.createElement(
14852
15646
  "li",
14853
15647
  {
14854
15648
  style: {
@@ -14859,7 +15653,7 @@ var ChatPopup = ({
14859
15653
  },
14860
15654
  children
14861
15655
  ),
14862
- strong: ({ children }) => /* @__PURE__ */ React6.createElement(
15656
+ strong: ({ children }) => /* @__PURE__ */ React10.createElement(
14863
15657
  "strong",
14864
15658
  {
14865
15659
  style: {
@@ -14870,7 +15664,7 @@ var ChatPopup = ({
14870
15664
  },
14871
15665
  children
14872
15666
  ),
14873
- em: ({ children }) => /* @__PURE__ */ React6.createElement(
15667
+ em: ({ children }) => /* @__PURE__ */ React10.createElement(
14874
15668
  "em",
14875
15669
  {
14876
15670
  style: {
@@ -14881,7 +15675,7 @@ var ChatPopup = ({
14881
15675
  },
14882
15676
  children
14883
15677
  ),
14884
- code: ({ children }) => /* @__PURE__ */ React6.createElement(
15678
+ code: ({ children }) => /* @__PURE__ */ React10.createElement(
14885
15679
  "code",
14886
15680
  {
14887
15681
  style: {
@@ -14894,7 +15688,7 @@ var ChatPopup = ({
14894
15688
  },
14895
15689
  children
14896
15690
  ),
14897
- pre: ({ children }) => /* @__PURE__ */ React6.createElement(
15691
+ pre: ({ children }) => /* @__PURE__ */ React10.createElement(
14898
15692
  "pre",
14899
15693
  {
14900
15694
  style: {
@@ -14909,7 +15703,7 @@ var ChatPopup = ({
14909
15703
  },
14910
15704
  children
14911
15705
  ),
14912
- blockquote: ({ children }) => /* @__PURE__ */ React6.createElement(
15706
+ blockquote: ({ children }) => /* @__PURE__ */ React10.createElement(
14913
15707
  "blockquote",
14914
15708
  {
14915
15709
  style: {
@@ -14928,7 +15722,7 @@ var ChatPopup = ({
14928
15722
  message.text
14929
15723
  ))
14930
15724
  ),
14931
- message.sender === "user" && /* @__PURE__ */ React6.createElement(
15725
+ message.sender === "user" && showUserIcon && /* @__PURE__ */ React10.createElement(
14932
15726
  "div",
14933
15727
  {
14934
15728
  style: {
@@ -14949,9 +15743,9 @@ var ChatPopup = ({
14949
15743
  )
14950
15744
  )
14951
15745
  )),
14952
- /* @__PURE__ */ React6.createElement("div", { ref: messagesEndRef })
15746
+ /* @__PURE__ */ React10.createElement("div", { ref: messagesEndRef })
14953
15747
  ),
14954
- /* @__PURE__ */ React6.createElement(
15748
+ /* @__PURE__ */ React10.createElement(
14955
15749
  "div",
14956
15750
  {
14957
15751
  style: {
@@ -14960,7 +15754,7 @@ var ChatPopup = ({
14960
15754
  background: "hsl(var(--voice-bg))"
14961
15755
  }
14962
15756
  },
14963
- /* @__PURE__ */ React6.createElement(
15757
+ /* @__PURE__ */ React10.createElement(
14964
15758
  "form",
14965
15759
  {
14966
15760
  onSubmit: (e2) => {
@@ -14969,7 +15763,7 @@ var ChatPopup = ({
14969
15763
  },
14970
15764
  style: { display: "flex", alignItems: "center", gap: 8, margin: 0 }
14971
15765
  },
14972
- /* @__PURE__ */ React6.createElement(
15766
+ /* @__PURE__ */ React10.createElement(
14973
15767
  "input",
14974
15768
  {
14975
15769
  type: "text",
@@ -14996,7 +15790,47 @@ var ChatPopup = ({
14996
15790
  }
14997
15791
  }
14998
15792
  ),
14999
- isConnected && onEndCall && /* @__PURE__ */ React6.createElement(
15793
+ muteState?.canMute && onToggleMute && /* @__PURE__ */ React10.createElement(
15794
+ "button",
15795
+ {
15796
+ onClick: onToggleMute,
15797
+ style: {
15798
+ padding: "10px 12px",
15799
+ borderRadius: 8,
15800
+ border: "1px solid hsl(var(--voice-accent))",
15801
+ background: "hsl(var(--voice-accent))",
15802
+ fontSize: 12,
15803
+ fontWeight: 700,
15804
+ display: "flex",
15805
+ alignItems: "center",
15806
+ justifyContent: "center",
15807
+ cursor: "pointer",
15808
+ transition: "all 0.3s ease"
15809
+ },
15810
+ "aria-label": muteState.isMuted ? "Unmute microphone" : "Mute microphone",
15811
+ title: muteState.isMuted ? "Unmute microphone" : "Mute microphone"
15812
+ },
15813
+ muteState.isMuted ? /* @__PURE__ */ React10.createElement(
15814
+ mic_off_default,
15815
+ {
15816
+ style: {
15817
+ width: 16,
15818
+ height: 16,
15819
+ color: "hsl(var(--voice-user-text))"
15820
+ }
15821
+ }
15822
+ ) : /* @__PURE__ */ React10.createElement(
15823
+ mic_default,
15824
+ {
15825
+ style: {
15826
+ width: 16,
15827
+ height: 16,
15828
+ color: "hsl(var(--voice-user-text))"
15829
+ }
15830
+ }
15831
+ )
15832
+ ),
15833
+ isConnected && onEndCall && /* @__PURE__ */ React10.createElement(
15000
15834
  "button",
15001
15835
  {
15002
15836
  type: "submit",
@@ -15015,7 +15849,7 @@ var ChatPopup = ({
15015
15849
  cursor: "pointer"
15016
15850
  }
15017
15851
  },
15018
- /* @__PURE__ */ React6.createElement(phone_off_default, { style: { width: 16, height: 16 } })
15852
+ /* @__PURE__ */ React10.createElement(phone_off_default, { style: { width: 16, height: 16 } })
15019
15853
  )
15020
15854
  )
15021
15855
  )
@@ -15023,7 +15857,7 @@ var ChatPopup = ({
15023
15857
  };
15024
15858
 
15025
15859
  // src/components/border-glow.tsx
15026
- import React7 from "react";
15860
+ import React11 from "react";
15027
15861
  var BorderGlow = ({ isActive }) => {
15028
15862
  if (!isActive) return null;
15029
15863
  const styles = {
@@ -15150,7 +15984,7 @@ var BorderGlow = ({ isActive }) => {
15150
15984
  opacity: 0.6
15151
15985
  }
15152
15986
  };
15153
- return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement("style", null, `
15987
+ return /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement("style", null, `
15154
15988
  @keyframes borderPulse {
15155
15989
  0%, 100% {
15156
15990
  opacity: 1;
@@ -15159,12 +15993,12 @@ var BorderGlow = ({ isActive }) => {
15159
15993
  opacity: 0.5;
15160
15994
  }
15161
15995
  }
15162
- `), /* @__PURE__ */ React7.createElement("div", { style: styles.container }, /* @__PURE__ */ React7.createElement("div", { style: styles.rightBorder1 }), /* @__PURE__ */ React7.createElement("div", { style: styles.rightBorder2 }), /* @__PURE__ */ React7.createElement("div", { style: styles.rightBorder3 }), /* @__PURE__ */ React7.createElement("div", { style: styles.leftBorder1 }), /* @__PURE__ */ React7.createElement("div", { style: styles.leftBorder2 }), /* @__PURE__ */ React7.createElement("div", { style: styles.leftBorder3 }), /* @__PURE__ */ React7.createElement("div", { style: styles.cornerTopLeft }), /* @__PURE__ */ React7.createElement("div", { style: styles.cornerTopRight }), /* @__PURE__ */ React7.createElement("div", { style: styles.cornerBottomRight }), /* @__PURE__ */ React7.createElement("div", { style: styles.cornerBottomLeft })));
15996
+ `), /* @__PURE__ */ React11.createElement("div", { style: styles.container }, /* @__PURE__ */ React11.createElement("div", { style: styles.rightBorder1 }), /* @__PURE__ */ React11.createElement("div", { style: styles.rightBorder2 }), /* @__PURE__ */ React11.createElement("div", { style: styles.rightBorder3 }), /* @__PURE__ */ React11.createElement("div", { style: styles.leftBorder1 }), /* @__PURE__ */ React11.createElement("div", { style: styles.leftBorder2 }), /* @__PURE__ */ React11.createElement("div", { style: styles.leftBorder3 }), /* @__PURE__ */ React11.createElement("div", { style: styles.cornerTopLeft }), /* @__PURE__ */ React11.createElement("div", { style: styles.cornerTopRight }), /* @__PURE__ */ React11.createElement("div", { style: styles.cornerBottomRight }), /* @__PURE__ */ React11.createElement("div", { style: styles.cornerBottomLeft })));
15163
15997
  };
15164
15998
  var border_glow_default = BorderGlow;
15165
15999
 
15166
16000
  // src/components/voice-intensity-visualizer.tsx
15167
- import React8, { useEffect as useEffect9, useState as useState9 } from "react";
16001
+ import React12, { useEffect as useEffect10, useState as useState10 } from "react";
15168
16002
 
15169
16003
  // node_modules/@livekit/components-react/dist/hooks-C2Bp5v2q.mjs
15170
16004
  import * as r from "react";
@@ -15179,7 +16013,7 @@ var Me = { exports: {} };
15179
16013
  var Or = Me.exports;
15180
16014
  var kt;
15181
16015
  function kr() {
15182
- return kt || (kt = 1, function(e2) {
16016
+ return kt || (kt = 1, (function(e2) {
15183
16017
  (function(t, n) {
15184
16018
  e2.exports ? e2.exports = n() : t.log = n();
15185
16019
  })(Or, function() {
@@ -15323,7 +16157,7 @@ function kr() {
15323
16157
  return o;
15324
16158
  }, s.default = s, s;
15325
16159
  });
15326
- }(Me)), Me.exports;
16160
+ })(Me)), Me.exports;
15327
16161
  }
15328
16162
  var _r = kr();
15329
16163
  var Lr = /* @__PURE__ */ Ar(_r);
@@ -15546,7 +16380,7 @@ function Ue(e2, t) {
15546
16380
  0 <= n && e2.splice(n, 1);
15547
16381
  }
15548
16382
  }
15549
- var Oe = function() {
16383
+ var Oe = (function() {
15550
16384
  function e2(t) {
15551
16385
  this.initialTeardown = t, this.closed = false, this._parentage = null, this._finalizers = null;
15552
16386
  }
@@ -15630,11 +16464,11 @@ var Oe = function() {
15630
16464
  }, e2.prototype.remove = function(t) {
15631
16465
  var n = this._finalizers;
15632
16466
  n && Ue(n, t), t instanceof e2 && t._removeParent(this);
15633
- }, e2.EMPTY = function() {
16467
+ }, e2.EMPTY = (function() {
15634
16468
  var t = new e2();
15635
16469
  return t.closed = true, t;
15636
- }(), e2;
15637
- }();
16470
+ })(), e2;
16471
+ })();
15638
16472
  var an = Oe.EMPTY;
15639
16473
  function cn(e2) {
15640
16474
  return e2 instanceof Oe || e2 && "closed" in e2 && P(e2.remove) && P(e2.add) && P(e2.unsubscribe);
@@ -15666,7 +16500,7 @@ function je() {
15666
16500
  function Re(e2) {
15667
16501
  e2();
15668
16502
  }
15669
- var gt = function(e2) {
16503
+ var gt = (function(e2) {
15670
16504
  te(t, e2);
15671
16505
  function t(n) {
15672
16506
  var r2 = e2.call(this) || this;
@@ -15697,8 +16531,8 @@ var gt = function(e2) {
15697
16531
  this.unsubscribe();
15698
16532
  }
15699
16533
  }, t;
15700
- }(Oe);
15701
- var Nr = function() {
16534
+ })(Oe);
16535
+ var Nr = (function() {
15702
16536
  function e2(t) {
15703
16537
  this.partialObserver = t;
15704
16538
  }
@@ -15729,8 +16563,8 @@ var Nr = function() {
15729
16563
  Le(n);
15730
16564
  }
15731
16565
  }, e2;
15732
- }();
15733
- var Ce = function(e2) {
16566
+ })();
16567
+ var Ce = (function(e2) {
15734
16568
  te(t, e2);
15735
16569
  function t(n, r2, i2) {
15736
16570
  var o = e2.call(this) || this, s;
@@ -15741,7 +16575,7 @@ var Ce = function(e2) {
15741
16575
  } : s = n, o.destination = new Nr(s), o;
15742
16576
  }
15743
16577
  return t;
15744
- }(gt);
16578
+ })(gt);
15745
16579
  function Le(e2) {
15746
16580
  un(e2);
15747
16581
  }
@@ -15754,9 +16588,9 @@ var Ur = {
15754
16588
  error: Fr,
15755
16589
  complete: je
15756
16590
  };
15757
- var bt = function() {
16591
+ var bt = (function() {
15758
16592
  return typeof Symbol == "function" && Symbol.observable || "@@observable";
15759
- }();
16593
+ })();
15760
16594
  function Ge(e2) {
15761
16595
  return e2;
15762
16596
  }
@@ -15767,7 +16601,7 @@ function jr(e2) {
15767
16601
  }, n);
15768
16602
  };
15769
16603
  }
15770
- var k = function() {
16604
+ var k = (function() {
15771
16605
  function e2(t) {
15772
16606
  t && (this._subscribe = t);
15773
16607
  }
@@ -15826,7 +16660,7 @@ var k = function() {
15826
16660
  }, e2.create = function(t) {
15827
16661
  return new e2(t);
15828
16662
  }, e2;
15829
- }();
16663
+ })();
15830
16664
  function Lt(e2) {
15831
16665
  var t;
15832
16666
  return (t = e2 ?? Dr.Promise) !== null && t !== void 0 ? t : Promise;
@@ -15856,7 +16690,7 @@ function j(e2) {
15856
16690
  function F(e2, t, n, r2, i2) {
15857
16691
  return new Hr(e2, t, n, r2, i2);
15858
16692
  }
15859
- var Hr = function(e2) {
16693
+ var Hr = (function(e2) {
15860
16694
  te(t, e2);
15861
16695
  function t(n, r2, i2, o, s, a) {
15862
16696
  var c = e2.call(this, n) || this;
@@ -15891,13 +16725,13 @@ var Hr = function(e2) {
15891
16725
  e2.prototype.unsubscribe.call(this), !r2 && ((n = this.onFinalize) === null || n === void 0 || n.call(this));
15892
16726
  }
15893
16727
  }, t;
15894
- }(gt);
16728
+ })(gt);
15895
16729
  var zr = mt(function(e2) {
15896
16730
  return function() {
15897
16731
  e2(this), this.name = "ObjectUnsubscribedError", this.message = "object unsubscribed";
15898
16732
  };
15899
16733
  });
15900
- var ee = function(e2) {
16734
+ var ee = (function(e2) {
15901
16735
  te(t, e2);
15902
16736
  function t() {
15903
16737
  var n = e2.call(this) || this;
@@ -15976,8 +16810,8 @@ var ee = function(e2) {
15976
16810
  }, t.create = function(n, r2) {
15977
16811
  return new It(n, r2);
15978
16812
  }, t;
15979
- }(k);
15980
- var It = function(e2) {
16813
+ })(k);
16814
+ var It = (function(e2) {
15981
16815
  te(t, e2);
15982
16816
  function t(n, r2) {
15983
16817
  var i2 = e2.call(this) || this;
@@ -15996,8 +16830,8 @@ var It = function(e2) {
15996
16830
  var r2, i2;
15997
16831
  return (i2 = (r2 = this.source) === null || r2 === void 0 ? void 0 : r2.subscribe(n)) !== null && i2 !== void 0 ? i2 : an;
15998
16832
  }, t;
15999
- }(ee);
16000
- var ln = function(e2) {
16833
+ })(ee);
16834
+ var ln = (function(e2) {
16001
16835
  te(t, e2);
16002
16836
  function t(n) {
16003
16837
  var r2 = e2.call(this) || this;
@@ -16020,13 +16854,13 @@ var ln = function(e2) {
16020
16854
  }, t.prototype.next = function(n) {
16021
16855
  e2.prototype.next.call(this, this._value = n);
16022
16856
  }, t;
16023
- }(ee);
16857
+ })(ee);
16024
16858
  var Yr = {
16025
16859
  now: function() {
16026
16860
  return Date.now();
16027
16861
  }
16028
16862
  };
16029
- var qr = function(e2) {
16863
+ var qr = (function(e2) {
16030
16864
  te(t, e2);
16031
16865
  function t(n, r2) {
16032
16866
  return e2.call(this) || this;
@@ -16034,7 +16868,7 @@ var qr = function(e2) {
16034
16868
  return t.prototype.schedule = function(n, r2) {
16035
16869
  return this;
16036
16870
  }, t;
16037
- }(Oe);
16871
+ })(Oe);
16038
16872
  var Mt = {
16039
16873
  setInterval: function(e2, t) {
16040
16874
  for (var n = [], r2 = 2; r2 < arguments.length; r2++)
@@ -16046,7 +16880,7 @@ var Mt = {
16046
16880
  },
16047
16881
  delegate: void 0
16048
16882
  };
16049
- var Kr = function(e2) {
16883
+ var Kr = (function(e2) {
16050
16884
  te(t, e2);
16051
16885
  function t(n, r2) {
16052
16886
  var i2 = e2.call(this, n, r2) || this;
@@ -16088,16 +16922,16 @@ var Kr = function(e2) {
16088
16922
  this.work = this.state = this.scheduler = null, this.pending = false, Ue(o, this), r2 != null && (this.id = this.recycleAsyncId(i2, r2, null)), this.delay = null, e2.prototype.unsubscribe.call(this);
16089
16923
  }
16090
16924
  }, t;
16091
- }(qr);
16092
- var Rt = function() {
16925
+ })(qr);
16926
+ var Rt = (function() {
16093
16927
  function e2(t, n) {
16094
16928
  n === void 0 && (n = e2.now), this.schedulerActionCtor = t, this.now = n;
16095
16929
  }
16096
16930
  return e2.prototype.schedule = function(t, n, r2) {
16097
16931
  return n === void 0 && (n = 0), new this.schedulerActionCtor(this, t).schedule(r2, n);
16098
16932
  }, e2.now = Yr.now, e2;
16099
- }();
16100
- var Gr = function(e2) {
16933
+ })();
16934
+ var Gr = (function(e2) {
16101
16935
  te(t, e2);
16102
16936
  function t(n, r2) {
16103
16937
  r2 === void 0 && (r2 = Rt.now);
@@ -16122,7 +16956,7 @@ var Gr = function(e2) {
16122
16956
  throw i2;
16123
16957
  }
16124
16958
  }, t;
16125
- }(Rt);
16959
+ })(Rt);
16126
16960
  var Qr = new Gr(Kr);
16127
16961
  function Jr(e2) {
16128
16962
  return e2 && P(e2.schedule);
@@ -16980,8 +17814,8 @@ var Xt = /* @__PURE__ */ e.forwardRef(
16980
17814
 
16981
17815
  // src/components/voice-intensity-visualizer.tsx
16982
17816
  var VoiceIntensityWithRoom = (props) => {
16983
- const [room, setRoom] = useState9(null);
16984
- useEffect9(() => {
17817
+ const [room, setRoom] = useState10(null);
17818
+ useEffect10(() => {
16985
17819
  if (props.isActive) {
16986
17820
  const currentRoom = getRoom();
16987
17821
  if (currentRoom) {
@@ -16994,7 +17828,7 @@ var VoiceIntensityWithRoom = (props) => {
16994
17828
  if (!room) {
16995
17829
  return null;
16996
17830
  }
16997
- return /* @__PURE__ */ React8.createElement(Wn.Provider, { value: room }, /* @__PURE__ */ React8.createElement(VoiceIntensityBars, { ...props }));
17831
+ return /* @__PURE__ */ React12.createElement(Wn.Provider, { value: room }, /* @__PURE__ */ React12.createElement(VoiceIntensityBars, { ...props }));
16998
17832
  };
16999
17833
  var VoiceIntensityBars = ({
17000
17834
  isActive,
@@ -17037,7 +17871,7 @@ var VoiceIntensityBars = ({
17037
17871
  if (!trackRef) {
17038
17872
  return null;
17039
17873
  }
17040
- return /* @__PURE__ */ React8.createElement(
17874
+ return /* @__PURE__ */ React12.createElement(
17041
17875
  "div",
17042
17876
  {
17043
17877
  className: `voice-intensity-visualizer ${className}`,
@@ -17054,7 +17888,7 @@ var VoiceIntensityBars = ({
17054
17888
  pointerEvents: "none"
17055
17889
  }
17056
17890
  },
17057
- /* @__PURE__ */ React8.createElement(
17891
+ /* @__PURE__ */ React12.createElement(
17058
17892
  Xt,
17059
17893
  {
17060
17894
  barCount,
@@ -17068,16 +17902,24 @@ var VoiceIntensityBars = ({
17068
17902
  gap: "0.25rem"
17069
17903
  }
17070
17904
  },
17071
- /* @__PURE__ */ React8.createElement("span", { className: "cuekit-voice-intensity-bar" })
17905
+ /* @__PURE__ */ React12.createElement("span", { className: "cuekit-voice-intensity-bar" })
17072
17906
  )
17073
17907
  );
17074
17908
  };
17075
17909
  var VoiceIntensityVisualizer = VoiceIntensityWithRoom;
17076
17910
 
17077
- // src/components/svgs/mic.tsx
17078
- import React9 from "react";
17079
- var MicIcon = ({ width = 24, height = 24, className, ...props }) => {
17080
- return /* @__PURE__ */ React9.createElement(
17911
+ // src/components/language-selector.tsx
17912
+ import React14, { useState as useState11, useRef as useRef9, useEffect as useEffect11 } from "react";
17913
+
17914
+ // src/components/svgs/chevron-down.tsx
17915
+ import React13 from "react";
17916
+ function ChevronDownIcon({
17917
+ width = 24,
17918
+ height = 24,
17919
+ className,
17920
+ ...props
17921
+ }) {
17922
+ return /* @__PURE__ */ React13.createElement(
17081
17923
  "svg",
17082
17924
  {
17083
17925
  xmlns: "http://www.w3.org/2000/svg",
@@ -17086,41 +17928,117 @@ var MicIcon = ({ width = 24, height = 24, className, ...props }) => {
17086
17928
  viewBox: "0 0 24 24",
17087
17929
  fill: "none",
17088
17930
  stroke: "currentColor",
17089
- strokeWidth: "2",
17090
- strokeLinecap: "round",
17091
- strokeLinejoin: "round",
17931
+ "stroke-width": "2",
17932
+ "stroke-linecap": "round",
17933
+ "stroke-linejoin": "round",
17092
17934
  className,
17093
17935
  ...props
17094
17936
  },
17095
- /* @__PURE__ */ React9.createElement("path", { d: "M12 19v3" }),
17096
- /* @__PURE__ */ React9.createElement("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
17097
- /* @__PURE__ */ React9.createElement("rect", { x: "9", y: "2", width: "6", height: "13", rx: "3" })
17937
+ /* @__PURE__ */ React13.createElement("path", { d: "m6 9 6 6 6-6" })
17098
17938
  );
17099
- };
17100
- var mic_default = MicIcon;
17939
+ }
17101
17940
 
17102
- // src/components/svgs/loader.tsx
17103
- import React10 from "react";
17104
- var LoaderIcon = ({ width = 24, height = 24, className, ...props }) => {
17105
- return /* @__PURE__ */ React10.createElement(
17106
- "svg",
17941
+ // src/components/language-selector.tsx
17942
+ var FLAG_EMOJIS = {
17943
+ "en-US": "\u{1F1FA}\u{1F1F8}",
17944
+ "ar-SA": "\u{1F1F8}\u{1F1E6}",
17945
+ "es-ES": "\u{1F1EA}\u{1F1F8}",
17946
+ "fr-FR": "\u{1F1EB}\u{1F1F7}",
17947
+ "de-DE": "\u{1F1E9}\u{1F1EA}",
17948
+ "it-IT": "\u{1F1EE}\u{1F1F9}",
17949
+ "pt-BR": "\u{1F1E7}\u{1F1F7}",
17950
+ "ja-JP": "\u{1F1EF}\u{1F1F5}",
17951
+ "ko-KR": "\u{1F1F0}\u{1F1F7}",
17952
+ "zh-CN": "\u{1F1E8}\u{1F1F3}",
17953
+ "hi-IN": "\u{1F1EE}\u{1F1F3}"
17954
+ };
17955
+ var LanguageSelector = ({
17956
+ selectedLanguage,
17957
+ onLanguageChange,
17958
+ availableLanguages,
17959
+ disabled = false,
17960
+ className = "",
17961
+ tooltip,
17962
+ screenPosition = "bottom-center"
17963
+ }) => {
17964
+ const [isOpen, setIsOpen] = useState11(false);
17965
+ const [showTooltip, setShowTooltip] = useState11(false);
17966
+ const [dropdownUp, setDropdownUp] = useState11(false);
17967
+ const dropdownRef = useRef9(null);
17968
+ useEffect11(() => {
17969
+ const handleClickOutside = (event) => {
17970
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
17971
+ setIsOpen(false);
17972
+ }
17973
+ };
17974
+ document.addEventListener("mousedown", handleClickOutside);
17975
+ return () => {
17976
+ document.removeEventListener("mousedown", handleClickOutside);
17977
+ };
17978
+ }, []);
17979
+ const handleLanguageSelect = (language) => {
17980
+ if (disabled) return;
17981
+ onLanguageChange(language);
17982
+ setIsOpen(false);
17983
+ };
17984
+ const handleButtonClick = () => {
17985
+ if (disabled) return;
17986
+ const isBottomPosition = screenPosition.startsWith("bottom");
17987
+ setDropdownUp(isBottomPosition);
17988
+ setIsOpen(!isOpen);
17989
+ };
17990
+ const getFlagEmoji = (code4) => {
17991
+ return FLAG_EMOJIS[code4] || "\u{1F310}";
17992
+ };
17993
+ return /* @__PURE__ */ React14.createElement(
17994
+ "div",
17107
17995
  {
17108
- xmlns: "http://www.w3.org/2000/svg",
17109
- width: "24",
17110
- height: "24",
17111
- viewBox: "0 0 24 24",
17112
- fill: "none",
17113
- stroke: "currentColor",
17114
- strokeWidth: "2",
17115
- strokeLinecap: "round",
17116
- strokeLinejoin: "round",
17117
- className,
17118
- ...props
17996
+ className: `language-selector-container ${className}`,
17997
+ ref: dropdownRef,
17998
+ onMouseEnter: () => {
17999
+ if (disabled) {
18000
+ setShowTooltip(true);
18001
+ }
18002
+ },
18003
+ onMouseLeave: () => {
18004
+ setShowTooltip(false);
18005
+ }
17119
18006
  },
17120
- /* @__PURE__ */ React10.createElement("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
18007
+ /* @__PURE__ */ React14.createElement(
18008
+ "button",
18009
+ {
18010
+ className: `language-selector-button ${isOpen ? "open" : ""} ${disabled ? "disabled" : ""}`,
18011
+ onClick: handleButtonClick,
18012
+ disabled,
18013
+ "aria-label": disabled ? tooltip || "Language cannot be changed during conversation" : "Select language",
18014
+ "aria-expanded": isOpen,
18015
+ "aria-haspopup": "listbox"
18016
+ },
18017
+ /* @__PURE__ */ React14.createElement("div", { className: "language-selector-content" }, /* @__PURE__ */ React14.createElement("span", { className: "language-flag" }, getFlagEmoji(selectedLanguage.code)), /* @__PURE__ */ React14.createElement("span", { className: "language-code" }, selectedLanguage.code), /* @__PURE__ */ React14.createElement(
18018
+ ChevronDownIcon,
18019
+ {
18020
+ className: `language-chevron ${isOpen ? dropdownUp ? "rotated-up" : "rotated" : ""}`,
18021
+ width: 14,
18022
+ height: 14
18023
+ }
18024
+ ))
18025
+ ),
18026
+ disabled && /* @__PURE__ */ React14.createElement("div", { className: `language-tooltip ${showTooltip ? "show" : ""}` }, /* @__PURE__ */ React14.createElement("div", { className: "language-tooltip-content" }, tooltip || "Close the conversation to change the language"), /* @__PURE__ */ React14.createElement("div", { className: "language-tooltip-arrow" })),
18027
+ isOpen && /* @__PURE__ */ React14.createElement("div", { className: `language-dropdown ${dropdownUp ? "dropdown-up" : ""}` }, /* @__PURE__ */ React14.createElement("div", { className: "language-dropdown-content" }, availableLanguages.map((language) => /* @__PURE__ */ React14.createElement(
18028
+ "button",
18029
+ {
18030
+ key: language.code,
18031
+ className: `language-option ${selectedLanguage.code === language.code ? "selected" : ""}`,
18032
+ onClick: () => handleLanguageSelect(language),
18033
+ role: "option",
18034
+ "aria-selected": selectedLanguage.code === language.code
18035
+ },
18036
+ /* @__PURE__ */ React14.createElement("span", { className: "language-flag" }, getFlagEmoji(language.code)),
18037
+ /* @__PURE__ */ React14.createElement("div", { className: "language-info" }, /* @__PURE__ */ React14.createElement("span", { className: "language-name" }, language.name)),
18038
+ selectedLanguage.code === language.code && /* @__PURE__ */ React14.createElement("div", { className: "language-check" }, "\u2713")
18039
+ ))))
17121
18040
  );
17122
18041
  };
17123
- var loader_default = LoaderIcon;
17124
18042
 
17125
18043
  // src/components/mic-button.tsx
17126
18044
  var chatState = {
@@ -17128,7 +18046,7 @@ var chatState = {
17128
18046
  isMinimized: false
17129
18047
  };
17130
18048
  var VoiceIntensityWrapper = ({ active, buttonSize }) => {
17131
- return /* @__PURE__ */ React11.createElement(
18049
+ return /* @__PURE__ */ React15.createElement(
17132
18050
  VoiceIntensityVisualizer,
17133
18051
  {
17134
18052
  isActive: active,
@@ -17138,6 +18056,10 @@ var VoiceIntensityWrapper = ({ active, buttonSize }) => {
17138
18056
  }
17139
18057
  );
17140
18058
  };
18059
+ var DEFAULT_LANGUAGES = [
18060
+ { code: "en-US", name: "English (US)", flag: "\u{1F1FA}\u{1F1F8}" },
18061
+ { code: "ar-SA", name: "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", flag: "\u{1F1F8}\u{1F1E6}" }
18062
+ ];
17141
18063
  var MicButton = ({
17142
18064
  buttonSize = 52,
17143
18065
  screenPosition = "bottom-center",
@@ -17149,22 +18071,29 @@ var MicButton = ({
17149
18071
  buttonStyle,
17150
18072
  bottomSpace = 20,
17151
18073
  defaultTheme = "system",
17152
- showBorderGlow = false
18074
+ showBorderGlow = false,
18075
+ language,
18076
+ defaultLanguage,
18077
+ onLanguageChange
17153
18078
  }) => {
17154
- const { apiKey, appId } = useQubeContext();
17155
- const [showBodyGlow, setShowBodyGlow] = useState10(false);
17156
- const [currentTheme, setCurrentTheme] = useState10("dark");
17157
- const [isChatOpen, setIsChatOpen] = useState10(chatState.isOpen);
17158
- const [isChatMinimized, setIsChatMinimized] = useState10(chatState.isMinimized);
17159
- useEffect10(() => {
18079
+ const { apiKey, appId } = useAnsyrContext();
18080
+ const [showBodyGlow, setShowBodyGlow] = useState12(false);
18081
+ const [currentTheme, setCurrentTheme] = useState12("dark");
18082
+ const [showLanguageSelector, setShowLanguageSelector] = useState12(false);
18083
+ const [selectedLanguage, setSelectedLanguage] = useState12(
18084
+ language || defaultLanguage || DEFAULT_LANGUAGES[0]
18085
+ );
18086
+ const [isChatOpen, setIsChatOpen] = useState12(chatState.isOpen);
18087
+ const [isChatMinimized, setIsChatMinimized] = useState12(chatState.isMinimized);
18088
+ useEffect12(() => {
17160
18089
  chatState.isOpen = isChatOpen;
17161
18090
  chatState.isMinimized = isChatMinimized;
17162
18091
  }, [isChatOpen, isChatMinimized]);
17163
- const audioContainerRef = useRef7(null);
17164
- const silenceTimerRef = useRef7(null);
17165
- const aiSpeakingRef = useRef7(false);
17166
- const aiSpeechTimeoutRef = useRef7(null);
17167
- const activeAITracksRef = useRef7(/* @__PURE__ */ new Set());
18092
+ const audioContainerRef = useRef10(null);
18093
+ const silenceTimerRef = useRef10(null);
18094
+ const aiSpeakingRef = useRef10(false);
18095
+ const aiSpeechTimeoutRef = useRef10(null);
18096
+ const activeAITracksRef = useRef10(/* @__PURE__ */ new Set());
17168
18097
  const {
17169
18098
  isConnected,
17170
18099
  isConnecting,
@@ -17172,12 +18101,16 @@ var MicButton = ({
17172
18101
  connect: voiceConnect,
17173
18102
  disconnect: voiceDisconnect,
17174
18103
  sendUserCommand: sendUserCommand2,
18104
+ sendChatMessage,
17175
18105
  messages: messageManagerMessages,
17176
18106
  micState,
17177
18107
  setMicState,
17178
18108
  status,
17179
18109
  setStatus,
17180
- participants
18110
+ participants,
18111
+ muteState,
18112
+ toggleMute,
18113
+ setMute
17181
18114
  } = useCuekit({
17182
18115
  // Don't override navigation command - let the provider handle it
17183
18116
  onConnectionStateChange: (state) => {
@@ -17190,7 +18123,7 @@ var MicButton = ({
17190
18123
  onAISpeechEnd: (trackId) => handleAISpeech(false, trackId),
17191
18124
  appId
17192
18125
  });
17193
- useEffect10(() => {
18126
+ useEffect12(() => {
17194
18127
  const checkTheme = () => {
17195
18128
  if (typeof document !== "undefined") {
17196
18129
  let newTheme;
@@ -17213,31 +18146,31 @@ var MicButton = ({
17213
18146
  return () => observer.disconnect();
17214
18147
  }
17215
18148
  }, [defaultTheme]);
17216
- const openChat = useCallback5(() => {
18149
+ const openChat = useCallback6(() => {
17217
18150
  setIsChatOpen(true);
17218
18151
  setIsChatMinimized(false);
17219
18152
  }, []);
17220
- const minimizeChat = useCallback5(() => {
18153
+ const minimizeChat = useCallback6(() => {
17221
18154
  setIsChatMinimized(true);
17222
18155
  if (showBorderGlow) {
17223
18156
  setShowBodyGlow(false);
17224
18157
  }
17225
18158
  }, [showBorderGlow]);
17226
- const restoreChat = useCallback5(() => {
18159
+ const restoreChat = useCallback6(() => {
17227
18160
  setIsChatMinimized(false);
17228
18161
  setIsChatOpen(true);
17229
18162
  if (showBorderGlow && (micState === "listening" || micState === "thinking" || micState === "replying")) {
17230
18163
  setShowBodyGlow(true);
17231
18164
  }
17232
18165
  }, [showBorderGlow, micState]);
17233
- const closeChat = useCallback5(() => {
18166
+ const closeChat = useCallback6(() => {
17234
18167
  setIsChatOpen(false);
17235
18168
  setIsChatMinimized(false);
17236
18169
  if (showBorderGlow) {
17237
18170
  setShowBodyGlow(false);
17238
18171
  }
17239
18172
  }, [showBorderGlow]);
17240
- const handleAISpeech = useCallback5(
18173
+ const handleAISpeech = useCallback6(
17241
18174
  (isSpeaking, trackId) => {
17242
18175
  if (isSpeaking && trackId) {
17243
18176
  activeAITracksRef.current.add(trackId);
@@ -17258,7 +18191,7 @@ var MicButton = ({
17258
18191
  },
17259
18192
  [status, micState, isConnected]
17260
18193
  );
17261
- useEffect10(() => {
18194
+ useEffect12(() => {
17262
18195
  if (audioContainerRef.current) {
17263
18196
  setAudioContainer(audioContainerRef);
17264
18197
  }
@@ -17285,29 +18218,51 @@ var MicButton = ({
17285
18218
  }
17286
18219
  return isConnected2 ? "Ready" : "Connecting...";
17287
18220
  };
17288
- useEffect10(() => {
18221
+ useEffect12(() => {
17289
18222
  if (isConnected) {
17290
18223
  } else {
17291
18224
  }
17292
18225
  }, [isConnected]);
17293
- useEffect10(() => {
18226
+ useEffect12(() => {
17294
18227
  if (isConnected && !isChatOpen) {
17295
18228
  openChat();
17296
18229
  }
17297
18230
  }, [isConnected, isChatOpen, openChat]);
17298
- useEffect10(() => {
18231
+ useEffect12(() => {
17299
18232
  if (messageManagerMessages.length > 0 && !isChatOpen) {
17300
18233
  openChat();
17301
18234
  }
17302
18235
  }, [messageManagerMessages.length, isChatOpen, openChat]);
17303
- const handleMicClick = useCallback5(() => {
18236
+ const handleLanguageChange = useCallback6(
18237
+ (newLanguage) => {
18238
+ setSelectedLanguage(newLanguage);
18239
+ onLanguageChange?.(newLanguage);
18240
+ },
18241
+ [onLanguageChange]
18242
+ );
18243
+ const handleLanguageConfirm = useCallback6(() => {
18244
+ setShowLanguageSelector(false);
18245
+ voiceConnect(`user_${Date.now()}`, apiKey, appId, selectedLanguage).then(() => {
18246
+ if (showBorderGlow) setShowBodyGlow(true);
18247
+ openChat();
18248
+ setTimeout(() => {
18249
+ openChat();
18250
+ }, 500);
18251
+ }).catch((error) => {
18252
+ });
18253
+ }, [voiceConnect, apiKey, appId, selectedLanguage, showBorderGlow, openChat]);
18254
+ const handleMicClick = useCallback6(() => {
17304
18255
  const shouldStop = micState === "listening" && isConnected;
17305
18256
  if (shouldStop) {
17306
18257
  voiceDisconnect().then(() => {
17307
18258
  }).catch((error) => {
17308
18259
  });
17309
18260
  } else {
17310
- voiceConnect(`user_${Date.now()}`, apiKey, appId).then(() => {
18261
+ if (!language && !defaultLanguage && !selectedLanguage) {
18262
+ setShowLanguageSelector(true);
18263
+ return;
18264
+ }
18265
+ voiceConnect(`user_${Date.now()}`, apiKey, appId, selectedLanguage).then(() => {
17311
18266
  if (showBorderGlow) setShowBodyGlow(true);
17312
18267
  openChat();
17313
18268
  setTimeout(() => {
@@ -17323,8 +18278,12 @@ var MicButton = ({
17323
18278
  voiceConnect,
17324
18279
  apiKey,
17325
18280
  appId,
18281
+ language,
18282
+ selectedLanguage,
17326
18283
  openChat,
17327
- showBorderGlow
18284
+ showBorderGlow,
18285
+ sendChatMessage,
18286
+ isChatOpen
17328
18287
  ]);
17329
18288
  const handleSendText = async (textToSend) => {
17330
18289
  setMicState("thinking");
@@ -17334,13 +18293,14 @@ var MicButton = ({
17334
18293
  }
17335
18294
  if (isConnected) {
17336
18295
  try {
17337
- await sendUserCommand2(textToSend);
18296
+ await sendChatMessage(textToSend);
17338
18297
  setMicState("replying");
17339
18298
  setTimeout(() => {
17340
18299
  setMicState("listening");
17341
18300
  if (showBorderGlow) setShowBodyGlow(true);
17342
18301
  }, 1e3);
17343
18302
  } catch (error) {
18303
+ console.error("Failed to send chat message:", error);
17344
18304
  } finally {
17345
18305
  setMicState("listening");
17346
18306
  if (showBorderGlow) setShowBodyGlow(true);
@@ -17367,8 +18327,11 @@ var MicButton = ({
17367
18327
  filter: "drop-shadow(0 10px 8px rgba(0, 0, 0, 0.04)) drop-shadow(0 4px 3px rgba(0, 0, 0, 0.1))",
17368
18328
  ...imageStyle
17369
18329
  };
17370
- const animatedImageStyle = micState === "thinking" ? { ...baseImageStyle, animation: "spin 1s linear infinite" } : micState === "replying" ? { ...baseImageStyle, animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite" } : baseImageStyle;
17371
- return /* @__PURE__ */ React11.createElement("img", { src: imageSource, alt: "Voice Assistant", style: animatedImageStyle });
18330
+ if (micState === "idle") {
18331
+ return /* @__PURE__ */ React15.createElement("img", { src: imageSource, alt: "Voice Assistant", style: baseImageStyle });
18332
+ } else {
18333
+ return /* @__PURE__ */ React15.createElement(VoiceIntensityWrapper, { active: true, buttonSize });
18334
+ }
17372
18335
  }
17373
18336
  const iconStyle = {
17374
18337
  width: `100%`,
@@ -17376,15 +18339,10 @@ var MicButton = ({
17376
18339
  color: "white",
17377
18340
  filter: "drop-shadow(0 10px 8px rgba(0, 0, 0, 0.04)) drop-shadow(0 4px 3px rgba(0, 0, 0, 0.1))"
17378
18341
  };
17379
- switch (micState) {
17380
- case "thinking":
17381
- return /* @__PURE__ */ React11.createElement(loader_default, { style: { ...iconStyle, animation: "spin 1s linear infinite" } });
17382
- case "replying":
17383
- return /* @__PURE__ */ React11.createElement(VoiceIntensityWrapper, { active: true, buttonSize });
17384
- case "listening":
17385
- return /* @__PURE__ */ React11.createElement(VoiceIntensityWrapper, { active: true, buttonSize });
17386
- default:
17387
- return /* @__PURE__ */ React11.createElement(mic_default, { style: iconStyle });
18342
+ if (micState === "idle") {
18343
+ return /* @__PURE__ */ React15.createElement(mic_default, { style: iconStyle });
18344
+ } else {
18345
+ return /* @__PURE__ */ React15.createElement(VoiceIntensityWrapper, { active: true, buttonSize });
17388
18346
  }
17389
18347
  };
17390
18348
  const getPositionStyle = () => {
@@ -17446,16 +18404,15 @@ var MicButton = ({
17446
18404
  const baseStyle = { ...buttonStyles.button };
17447
18405
  switch (micState) {
17448
18406
  case "listening":
17449
- baseStyle.transform = "scale(1.1)";
18407
+ baseStyle.transform = "scale(1.05)";
17450
18408
  baseStyle.boxShadow = "0 25px 50px -12px rgba(59, 130, 246, 0.6)";
17451
18409
  break;
17452
18410
  case "thinking":
17453
- baseStyle.transform = "scale(1.05)";
18411
+ baseStyle.transform = "scale(1.02)";
17454
18412
  baseStyle.boxShadow = "0 20px 25px -5px rgba(196, 132, 252, 0.4)";
17455
- baseStyle.animation = "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite";
17456
18413
  break;
17457
18414
  case "replying":
17458
- baseStyle.transform = "scale(1.05)";
18415
+ baseStyle.transform = "scale(1.02)";
17459
18416
  baseStyle.boxShadow = "0 20px 25px -5px rgba(34, 211, 238, 0.4)";
17460
18417
  break;
17461
18418
  default:
@@ -17464,7 +18421,34 @@ var MicButton = ({
17464
18421
  }
17465
18422
  return baseStyle;
17466
18423
  };
17467
- return /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement("div", { "data-cuekit-ignore": true, style: { ...buttonStyles.container, ...getPositionStyle() } }, /* @__PURE__ */ React11.createElement("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: "8px" } }, /* @__PURE__ */ React11.createElement(
18424
+ return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement("div", { "data-cuekit-ignore": true, style: { ...buttonStyles.container, ...getPositionStyle() } }, showLanguageSelector ? /* @__PURE__ */ React15.createElement("div", { className: "voice-chat-language-selection" }, /* @__PURE__ */ React15.createElement("div", { className: "voice-chat-language-header" }, /* @__PURE__ */ React15.createElement("div", { className: "voice-chat-language-icon" }, /* @__PURE__ */ React15.createElement(mic_default, { width: 20, height: 20 })), /* @__PURE__ */ React15.createElement("span", { className: "voice-chat-language-title" }, "Select Language")), /* @__PURE__ */ React15.createElement(
18425
+ LanguageSelector,
18426
+ {
18427
+ selectedLanguage,
18428
+ onLanguageChange: handleLanguageChange,
18429
+ availableLanguages: DEFAULT_LANGUAGES,
18430
+ className: "voice-chat-language-selector",
18431
+ screenPosition
18432
+ }
18433
+ ), /* @__PURE__ */ React15.createElement("div", { className: "voice-chat-language-actions" }, /* @__PURE__ */ React15.createElement(
18434
+ "button",
18435
+ {
18436
+ className: "voice-chat-cancel-button",
18437
+ onClick: () => setShowLanguageSelector(false)
18438
+ },
18439
+ "Cancel"
18440
+ ), /* @__PURE__ */ React15.createElement("button", { className: "voice-chat-confirm-button", onClick: handleLanguageConfirm }, "Start Voice Chat"))) : /* @__PURE__ */ React15.createElement("div", { className: "voice-chat-main-button" }, /* @__PURE__ */ React15.createElement(
18441
+ LanguageSelector,
18442
+ {
18443
+ selectedLanguage,
18444
+ onLanguageChange: handleLanguageChange,
18445
+ availableLanguages: DEFAULT_LANGUAGES,
18446
+ className: "voice-chat-language-preview",
18447
+ disabled: isConnected || micState !== "idle",
18448
+ tooltip: "Close the conversation to change the language",
18449
+ screenPosition
18450
+ }
18451
+ ), /* @__PURE__ */ React15.createElement(
17468
18452
  "button",
17469
18453
  {
17470
18454
  "data-testid": "ignore",
@@ -17485,8 +18469,8 @@ var MicButton = ({
17485
18469
  },
17486
18470
  "aria-label": micState === "thinking" ? "Processing..." : micState === "replying" ? "AI is responding..." : isListening ? "Stop listening" : "Start listening"
17487
18471
  },
17488
- /* @__PURE__ */ React11.createElement("div", { style: buttonStyles.iconContainer }, getIcon())
17489
- ), hasText && text7 && /* @__PURE__ */ React11.createElement(
18472
+ /* @__PURE__ */ React15.createElement("div", { style: buttonStyles.iconContainer }, getIcon())
18473
+ )), !showLanguageSelector && hasText && text7 && /* @__PURE__ */ React15.createElement(
17490
18474
  "div",
17491
18475
  {
17492
18476
  style: {
@@ -17504,11 +18488,12 @@ var MicButton = ({
17504
18488
  alignItems: "center",
17505
18489
  justifyContent: "center",
17506
18490
  gap: "4px",
18491
+ marginTop: "8px",
17507
18492
  ...textStyle
17508
18493
  }
17509
18494
  },
17510
- /* @__PURE__ */ React11.createElement("span", null, text7)
17511
- ))), /* @__PURE__ */ React11.createElement(
18495
+ /* @__PURE__ */ React15.createElement("span", null, text7)
18496
+ )), /* @__PURE__ */ React15.createElement(
17512
18497
  ChatPopup,
17513
18498
  {
17514
18499
  isOpen: isChatOpen,
@@ -17529,9 +18514,16 @@ var MicButton = ({
17529
18514
  currentTheme,
17530
18515
  onThemeToggle: setCurrentTheme,
17531
18516
  status: getUserFriendlyStatus(micState, isConnected ?? false),
17532
- anchor: { position: screenPosition, bottom: bottomSpace, size: buttonSize }
17533
- }
17534
- ), isChatOpen && isChatMinimized && /* @__PURE__ */ React11.createElement(
18517
+ anchor: { position: screenPosition, bottom: bottomSpace, size: buttonSize },
18518
+ muteState,
18519
+ onToggleMute: toggleMute,
18520
+ draggable: true,
18521
+ resizable: true,
18522
+ persistPosition: true,
18523
+ persistSize: true,
18524
+ storageKey: "cuekit-chat-popup"
18525
+ }
18526
+ ), isChatOpen && isChatMinimized && /* @__PURE__ */ React15.createElement(
17535
18527
  "button",
17536
18528
  {
17537
18529
  onClick: restoreChat,
@@ -17552,8 +18544,8 @@ var MicButton = ({
17552
18544
  className: `cuekit-voice-popup ${currentTheme === "dark" ? "cuekit-dark" : ""}`,
17553
18545
  "aria-label": "Open chat"
17554
18546
  },
17555
- /* @__PURE__ */ React11.createElement("span", { style: { fontSize: 12, fontWeight: 600, color: "hsl(var(--voice-text))" } }, "Open chat")
17556
- ), /* @__PURE__ */ React11.createElement("div", { ref: audioContainerRef, style: { display: "none" } }), showBorderGlow && showBodyGlow && /* @__PURE__ */ React11.createElement(border_glow_default, { isActive: true }));
18547
+ /* @__PURE__ */ React15.createElement("span", { style: { fontSize: 12, fontWeight: 600, color: "hsl(var(--voice-text))" } }, "Open chat")
18548
+ ), /* @__PURE__ */ React15.createElement("div", { ref: audioContainerRef, style: { display: "none" } }), showBorderGlow && showBodyGlow && /* @__PURE__ */ React15.createElement(border_glow_default, { isActive: true }));
17557
18549
  };
17558
18550
 
17559
18551
  // src/utils/instrumentation.ts
@@ -17564,11 +18556,15 @@ function generateDynamicId(routePath, elementIdentifier) {
17564
18556
  return hash.substring(0, 8);
17565
18557
  }
17566
18558
  export {
18559
+ AnsyrProvider,
17567
18560
  border_glow_default as BorderGlow,
17568
18561
  ChatPopup,
17569
- CuekitProvider,
18562
+ DraggableResizableContainer,
17570
18563
  InitCuekit,
18564
+ LanguageSelector,
17571
18565
  MicButton,
18566
+ ResizeHandle,
18567
+ ResizeHandles,
17572
18568
  VoiceIntensityVisualizer,
17573
18569
  captureAllInteractiveElements,
17574
18570
  clearElementCache,
@@ -17580,8 +18576,9 @@ export {
17580
18576
  initWebRTC,
17581
18577
  initWebRTCWithDeployedBackend,
17582
18578
  resolveRoutePath,
18579
+ useAnsyrContext,
17583
18580
  useCuekit,
17584
- useQubeContext,
18581
+ useDraggableResizableContainer,
17585
18582
  useWebRTC,
17586
18583
  validateDynamicElements
17587
18584
  };