aizek-chatbot 1.0.26 → 1.0.28
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.cjs +568 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +475 -2
- package/dist/index.css.map +1 -1
- package/dist/index.mjs +567 -102
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
package/dist/index.cjs
CHANGED
|
@@ -4,13 +4,20 @@ var react = require('react');
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var ReactMarkdown = require('react-markdown');
|
|
6
6
|
var remarkGfm = require('remark-gfm');
|
|
7
|
+
var sanitizeHtml = require('sanitize-html');
|
|
7
8
|
|
|
8
9
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
10
|
|
|
10
11
|
var ReactMarkdown__default = /*#__PURE__*/_interopDefault(ReactMarkdown);
|
|
11
12
|
var remarkGfm__default = /*#__PURE__*/_interopDefault(remarkGfm);
|
|
13
|
+
var sanitizeHtml__default = /*#__PURE__*/_interopDefault(sanitizeHtml);
|
|
12
14
|
|
|
13
|
-
// src/utils/
|
|
15
|
+
// src/utils/global.ts
|
|
16
|
+
var SESSION_TTL_MS = 60 * 60 * 1e3;
|
|
17
|
+
var MAX_SESSIONS = 3;
|
|
18
|
+
var DEVICE_KEY = "aizek_device_id_v1";
|
|
19
|
+
var ACTIVE_SESSION_KEY = "aizek_active_session_v1";
|
|
20
|
+
var LOCAL_SESSIONS_KEY = "aizek_sessions_v1";
|
|
14
21
|
function validateHeaders(headers, authConfig, opts = {}) {
|
|
15
22
|
if (headers && (!authConfig || Object.keys(authConfig).length === 0)) {
|
|
16
23
|
return {
|
|
@@ -39,6 +46,65 @@ function validateHeaders(headers, authConfig, opts = {}) {
|
|
|
39
46
|
const isValid = hasAllRequired && !hasExtraKeys && emptyValueKeys.length === 0;
|
|
40
47
|
return { isValid, missingKeys, extraKeys, emptyValueKeys };
|
|
41
48
|
}
|
|
49
|
+
function getOrCreateDeviceId() {
|
|
50
|
+
if (typeof window === "undefined") return "";
|
|
51
|
+
const existing = localStorage.getItem(DEVICE_KEY);
|
|
52
|
+
if (existing) return existing;
|
|
53
|
+
const id = crypto.randomUUID();
|
|
54
|
+
localStorage.setItem(DEVICE_KEY, id);
|
|
55
|
+
return id;
|
|
56
|
+
}
|
|
57
|
+
function now() {
|
|
58
|
+
return Date.now();
|
|
59
|
+
}
|
|
60
|
+
function readStoredSessions() {
|
|
61
|
+
try {
|
|
62
|
+
const raw = localStorage.getItem(LOCAL_SESSIONS_KEY);
|
|
63
|
+
const parsed = JSON.parse(raw ?? "[]");
|
|
64
|
+
if (!Array.isArray(parsed)) return [];
|
|
65
|
+
return parsed.filter((x) => x && typeof x.sessionId === "string" && typeof x.lastActive === "number").slice(0, MAX_SESSIONS);
|
|
66
|
+
} catch {
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function writeStoredSessions(list) {
|
|
71
|
+
localStorage.setItem(LOCAL_SESSIONS_KEY, JSON.stringify(list.slice(0, MAX_SESSIONS)));
|
|
72
|
+
}
|
|
73
|
+
function purgeExpiredLocalSessions(setActiveSessionIdState) {
|
|
74
|
+
const list = readStoredSessions();
|
|
75
|
+
const filtered = list.filter((s) => now() - s.lastActive <= SESSION_TTL_MS);
|
|
76
|
+
if (filtered.length !== list.length) writeStoredSessions(filtered);
|
|
77
|
+
const active = getActiveSessionId();
|
|
78
|
+
if (active && !filtered.some((s) => s.sessionId === active)) {
|
|
79
|
+
setActiveSessionId(null);
|
|
80
|
+
setActiveSessionIdState(null);
|
|
81
|
+
}
|
|
82
|
+
return filtered;
|
|
83
|
+
}
|
|
84
|
+
function getActiveSessionId() {
|
|
85
|
+
return localStorage.getItem(ACTIVE_SESSION_KEY);
|
|
86
|
+
}
|
|
87
|
+
function setActiveSessionId(id) {
|
|
88
|
+
if (!id) localStorage.removeItem(ACTIVE_SESSION_KEY);
|
|
89
|
+
else localStorage.setItem(ACTIVE_SESSION_KEY, id);
|
|
90
|
+
}
|
|
91
|
+
function touchSession(sessionId) {
|
|
92
|
+
const list = readStoredSessions();
|
|
93
|
+
const next = list.map((s) => s.sessionId === sessionId ? { ...s, lastActive: now() } : s);
|
|
94
|
+
if (!next.some((s) => s.sessionId === sessionId)) next.unshift({ sessionId, lastActive: now() });
|
|
95
|
+
writeStoredSessions(next.slice(0, MAX_SESSIONS));
|
|
96
|
+
}
|
|
97
|
+
function upsertSessionsFromServer(serverSessionIds, setSessions) {
|
|
98
|
+
const local = readStoredSessions();
|
|
99
|
+
const map = new Map(local.map((s) => [s.sessionId, s.lastActive]));
|
|
100
|
+
const merged = serverSessionIds.slice(0, MAX_SESSIONS).map((sid) => ({
|
|
101
|
+
sessionId: sid,
|
|
102
|
+
lastActive: map.get(sid) ?? now()
|
|
103
|
+
}));
|
|
104
|
+
writeStoredSessions(merged);
|
|
105
|
+
setSessions(merged.map((x) => x.sessionId));
|
|
106
|
+
return merged;
|
|
107
|
+
}
|
|
42
108
|
var HeaderAlert = ({ headerValidation, showAlert, setShowAlert }) => {
|
|
43
109
|
if (!headerValidation || !showAlert) return null;
|
|
44
110
|
const { isValid, missingKeys, extraKeys, emptyValueKeys, warning } = headerValidation;
|
|
@@ -429,7 +495,17 @@ var extractUIJsonFromText = (text) => {
|
|
|
429
495
|
uiData
|
|
430
496
|
};
|
|
431
497
|
};
|
|
432
|
-
var AizekChatBot = ({
|
|
498
|
+
var AizekChatBot = ({
|
|
499
|
+
clientId,
|
|
500
|
+
headers,
|
|
501
|
+
onMounted,
|
|
502
|
+
onReady,
|
|
503
|
+
onOpen,
|
|
504
|
+
onClose,
|
|
505
|
+
onMessage,
|
|
506
|
+
onToolCall,
|
|
507
|
+
onDisconnect
|
|
508
|
+
}) => {
|
|
433
509
|
const messagesEndRef = react.useRef(null);
|
|
434
510
|
const [config, setConfig] = react.useState();
|
|
435
511
|
const [messages, setMessages] = react.useState([]);
|
|
@@ -438,78 +514,169 @@ var AizekChatBot = ({ clientId, headers, onMounted, onReady, onOpen, onClose, on
|
|
|
438
514
|
const [isOpen, setIsOpen] = react.useState(false);
|
|
439
515
|
const [headerValidation, setHeaderValidation] = react.useState(null);
|
|
440
516
|
const [showAlert, setShowAlert] = react.useState(true);
|
|
517
|
+
const [sessions, setSessions] = react.useState([]);
|
|
518
|
+
const [activeSessionId, setActiveSessionIdState] = react.useState(null);
|
|
519
|
+
const [activeTab, setActiveTab] = react.useState("home");
|
|
520
|
+
const [messageView, setMessageView] = react.useState("list");
|
|
441
521
|
const PROXY_BASE_URL = "https://proxy.aizek.ai/api";
|
|
522
|
+
const createNewSession = async () => {
|
|
523
|
+
const deviceId = getOrCreateDeviceId();
|
|
524
|
+
if (sessions.length >= MAX_SESSIONS) {
|
|
525
|
+
throw new Error(`You can open up to ${MAX_SESSIONS} sessions.`);
|
|
526
|
+
}
|
|
527
|
+
const res = await fetch(`${PROXY_BASE_URL}/aizek-sessions/new?clientId=${clientId}`, {
|
|
528
|
+
method: "POST",
|
|
529
|
+
headers: {
|
|
530
|
+
"Content-Type": "application/json",
|
|
531
|
+
"x-device-id": deviceId,
|
|
532
|
+
"x-alternate": JSON.stringify(headers)
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
const data = await res.json();
|
|
536
|
+
if (!data.success) throw new Error(data.message || "session create failed");
|
|
537
|
+
const sid = data.data.sessionId;
|
|
538
|
+
const updatedSessions = data.data.sessions ?? [sid];
|
|
539
|
+
upsertSessionsFromServer(updatedSessions, setSessions);
|
|
540
|
+
setActiveSessionIdState(sid);
|
|
541
|
+
setActiveSessionId(sid);
|
|
542
|
+
setActiveTab("messages");
|
|
543
|
+
setMessageView("detail");
|
|
544
|
+
touchSession(sid);
|
|
545
|
+
setMessages([]);
|
|
546
|
+
return sid;
|
|
547
|
+
};
|
|
442
548
|
const loadConfig = async () => {
|
|
443
549
|
try {
|
|
444
550
|
setIsConfigLoading(true);
|
|
445
|
-
const
|
|
551
|
+
const deviceId = getOrCreateDeviceId();
|
|
552
|
+
purgeExpiredLocalSessions(setActiveSessionIdState);
|
|
553
|
+
const localActive = getActiveSessionId();
|
|
554
|
+
const response = await fetch(`${PROXY_BASE_URL}/aizek-connect?clientId=${clientId}`, {
|
|
446
555
|
method: "POST",
|
|
447
556
|
headers: {
|
|
448
557
|
"Content-Type": "application/json",
|
|
558
|
+
"x-device-id": deviceId,
|
|
449
559
|
"x-alternate": JSON.stringify(headers)
|
|
450
|
-
}
|
|
451
|
-
credentials: "include",
|
|
452
|
-
body: JSON.stringify({ clientId })
|
|
560
|
+
}
|
|
453
561
|
});
|
|
454
562
|
const data = await response.json();
|
|
455
|
-
if (data.success) {
|
|
456
|
-
setIsOpen(data.data.widget_config.initial_open);
|
|
457
|
-
setConfig(data.data);
|
|
458
|
-
if (headers) {
|
|
459
|
-
const validationResult = validateHeaders(
|
|
460
|
-
headers,
|
|
461
|
-
data.data.auth_config,
|
|
462
|
-
{
|
|
463
|
-
allowExtra: false,
|
|
464
|
-
caseSensitive: true
|
|
465
|
-
}
|
|
466
|
-
);
|
|
467
|
-
setHeaderValidation(validationResult);
|
|
468
|
-
}
|
|
469
|
-
onReady?.({ config: { ...data.data } });
|
|
470
|
-
} else {
|
|
563
|
+
if (!data.success) {
|
|
471
564
|
setIsOpen(false);
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
setIsOpen(!!data.data.widget_config.initial_open);
|
|
568
|
+
setConfig(data.data);
|
|
569
|
+
const serverSessions = data.data.sessions ?? [];
|
|
570
|
+
const merged = upsertSessionsFromServer(serverSessions, setSessions);
|
|
571
|
+
if (merged.length === 0) {
|
|
572
|
+
const newSid = await createNewSession();
|
|
573
|
+
setActiveSessionIdState(newSid);
|
|
574
|
+
setActiveSessionId(newSid);
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
const mergedIds = merged.map((s) => s.sessionId);
|
|
578
|
+
const nextActive = (localActive && mergedIds.includes(localActive) ? localActive : null) ?? mergedIds[0] ?? null;
|
|
579
|
+
setActiveSessionIdState(nextActive);
|
|
580
|
+
setActiveSessionId(nextActive);
|
|
581
|
+
if (headers) {
|
|
582
|
+
const validationResult = validateHeaders(headers, data.data.auth_config, {
|
|
583
|
+
allowExtra: false,
|
|
584
|
+
caseSensitive: true
|
|
585
|
+
});
|
|
586
|
+
setHeaderValidation(validationResult);
|
|
472
587
|
}
|
|
588
|
+
onReady?.({ config: { ...data.data } });
|
|
473
589
|
} catch (error) {
|
|
474
590
|
console.error("Failed to load chat widget config:", error);
|
|
475
591
|
} finally {
|
|
476
592
|
setIsConfigLoading(false);
|
|
477
593
|
}
|
|
478
594
|
};
|
|
479
|
-
const
|
|
595
|
+
const getHistoryMessageBySessionId = async (sid) => {
|
|
480
596
|
try {
|
|
481
|
-
|
|
482
|
-
await fetch(`${PROXY_BASE_URL}/aizek-
|
|
483
|
-
method: "
|
|
597
|
+
const deviceId = getOrCreateDeviceId();
|
|
598
|
+
const response = await fetch(`${PROXY_BASE_URL}/aizek-messages`, {
|
|
599
|
+
method: "GET",
|
|
484
600
|
headers: {
|
|
485
601
|
"Content-Type": "application/json",
|
|
602
|
+
"x-device-id": deviceId,
|
|
603
|
+
"x-session-id": sid,
|
|
486
604
|
"x-alternate": JSON.stringify(headers)
|
|
487
|
-
}
|
|
488
|
-
credentials: "include"
|
|
605
|
+
}
|
|
489
606
|
});
|
|
490
|
-
|
|
607
|
+
const data = await response.json();
|
|
608
|
+
if (!data.success) {
|
|
609
|
+
throw new Error(data.message || "Failed to fetch messages");
|
|
610
|
+
}
|
|
611
|
+
const historyMessages = [];
|
|
612
|
+
if (data.data?.messages && Array.isArray(data.data.messages)) {
|
|
613
|
+
for (const msg of data.data.messages) {
|
|
614
|
+
let textContent = "";
|
|
615
|
+
let uiData = null;
|
|
616
|
+
if (typeof msg.content === "string") {
|
|
617
|
+
textContent = msg.content;
|
|
618
|
+
} else if (Array.isArray(msg.content)) {
|
|
619
|
+
const textParts = [];
|
|
620
|
+
for (const item of msg.content) {
|
|
621
|
+
if (item.type === "text" && item.text) {
|
|
622
|
+
textParts.push(item.text);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
textContent = textParts.join("\n");
|
|
626
|
+
}
|
|
627
|
+
if (textContent) {
|
|
628
|
+
const extracted = extractUIJsonFromText(textContent);
|
|
629
|
+
textContent = extracted.cleanedText;
|
|
630
|
+
uiData = extracted.uiData;
|
|
631
|
+
}
|
|
632
|
+
if (textContent.trim() || uiData) {
|
|
633
|
+
historyMessages.push({
|
|
634
|
+
text: textContent.trim() || void 0,
|
|
635
|
+
ui: uiData,
|
|
636
|
+
role: msg.role === "user" ? "user" : msg.role === "assistant" ? "assistant" : "user",
|
|
637
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
return historyMessages;
|
|
491
643
|
} catch (error) {
|
|
492
|
-
console.error("
|
|
493
|
-
|
|
494
|
-
setIsConfigLoading(false);
|
|
644
|
+
console.error("Error fetching message history:", error);
|
|
645
|
+
return [];
|
|
495
646
|
}
|
|
496
647
|
};
|
|
497
648
|
react.useEffect(() => {
|
|
498
649
|
onMounted?.();
|
|
499
650
|
loadConfig();
|
|
500
|
-
return () => {
|
|
501
|
-
disconnect();
|
|
502
|
-
};
|
|
503
651
|
}, []);
|
|
504
652
|
react.useEffect(() => {
|
|
505
|
-
const
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
653
|
+
const t = setInterval(() => {
|
|
654
|
+
purgeExpiredLocalSessions(setActiveSessionIdState);
|
|
655
|
+
}, 1e3);
|
|
656
|
+
return () => clearInterval(t);
|
|
657
|
+
}, []);
|
|
658
|
+
react.useEffect(() => {
|
|
659
|
+
if (typeof config?.widget_config.initial_open === "boolean") {
|
|
660
|
+
const open = config.widget_config.initial_open;
|
|
661
|
+
setIsOpen(open);
|
|
662
|
+
if (open) onOpen?.();
|
|
663
|
+
else onClose?.();
|
|
664
|
+
}
|
|
509
665
|
}, [config?.widget_config.initial_open]);
|
|
510
666
|
react.useEffect(() => {
|
|
511
667
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
512
668
|
}, [messages]);
|
|
669
|
+
react.useEffect(() => {
|
|
670
|
+
if (activeSessionId && !isConfigLoading) {
|
|
671
|
+
getHistoryMessageBySessionId(activeSessionId).then((historyMessages) => {
|
|
672
|
+
setMessages(historyMessages);
|
|
673
|
+
}).catch((error) => {
|
|
674
|
+
console.error("Failed to load message history:", error);
|
|
675
|
+
});
|
|
676
|
+
} else if (!activeSessionId) {
|
|
677
|
+
setMessages([]);
|
|
678
|
+
}
|
|
679
|
+
}, [activeSessionId, isConfigLoading]);
|
|
513
680
|
const addMessage = (payload) => {
|
|
514
681
|
const newMessage = {
|
|
515
682
|
text: payload.text,
|
|
@@ -524,24 +691,51 @@ var AizekChatBot = ({ clientId, headers, onMounted, onReady, onOpen, onClose, on
|
|
|
524
691
|
};
|
|
525
692
|
const sendMessage = async (message, approval) => {
|
|
526
693
|
if (!message.trim() || isLoading) return;
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
ui: void 0,
|
|
530
|
-
|
|
531
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
532
|
-
};
|
|
533
|
-
setMessages((prev) => [...prev, newMessage]);
|
|
694
|
+
setMessages((prev) => [
|
|
695
|
+
...prev,
|
|
696
|
+
{ text: message, ui: void 0, role: approval ? "approval" : "user", timestamp: /* @__PURE__ */ new Date() }
|
|
697
|
+
]);
|
|
534
698
|
setIsLoading(true);
|
|
535
699
|
try {
|
|
536
|
-
const
|
|
700
|
+
const deviceId = getOrCreateDeviceId();
|
|
701
|
+
purgeExpiredLocalSessions(setActiveSessionIdState);
|
|
702
|
+
let sid = activeSessionId;
|
|
703
|
+
if (!sid) sid = await createNewSession();
|
|
704
|
+
const response = await fetch(`${PROXY_BASE_URL}/aizek-chat?clientId=${clientId}`, {
|
|
537
705
|
method: "POST",
|
|
538
706
|
headers: {
|
|
539
707
|
"Content-Type": "application/json",
|
|
708
|
+
"x-device-id": deviceId,
|
|
709
|
+
"x-session-id": sid,
|
|
540
710
|
"x-alternate": JSON.stringify(headers)
|
|
541
711
|
},
|
|
542
|
-
body: JSON.stringify({ message })
|
|
543
|
-
credentials: "include"
|
|
712
|
+
body: JSON.stringify({ message })
|
|
544
713
|
});
|
|
714
|
+
if (response.status === 401) {
|
|
715
|
+
const local = readStoredSessions().filter((s) => s.sessionId !== sid);
|
|
716
|
+
writeStoredSessions(local);
|
|
717
|
+
setSessions(local.map((x) => x.sessionId));
|
|
718
|
+
setActiveSessionId(null);
|
|
719
|
+
setActiveSessionIdState(null);
|
|
720
|
+
const newSid = await createNewSession();
|
|
721
|
+
const retry = await fetch(`${PROXY_BASE_URL}/aizek-chat?clientId=${clientId}`, {
|
|
722
|
+
method: "POST",
|
|
723
|
+
headers: {
|
|
724
|
+
"Content-Type": "application/json",
|
|
725
|
+
"x-device-id": deviceId,
|
|
726
|
+
"x-session-id": newSid,
|
|
727
|
+
"x-alternate": JSON.stringify(headers)
|
|
728
|
+
},
|
|
729
|
+
body: JSON.stringify({ message })
|
|
730
|
+
});
|
|
731
|
+
if (!retry.ok) throw new Error(`HTTP error ${retry.status}`);
|
|
732
|
+
const retryJson = await retry.json();
|
|
733
|
+
const text = JSON.stringify(retryJson.data);
|
|
734
|
+
const { cleanedText, uiData } = extractUIJsonFromText(text);
|
|
735
|
+
addMessage({ text: cleanedText, ui: uiData, role: "assistant" });
|
|
736
|
+
touchSession(newSid);
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
545
739
|
if (!response.ok) {
|
|
546
740
|
throw new Error(`HTTP error ${response.status}`);
|
|
547
741
|
}
|
|
@@ -585,87 +779,359 @@ var AizekChatBot = ({ clientId, headers, onMounted, onReady, onOpen, onClose, on
|
|
|
585
779
|
}
|
|
586
780
|
}
|
|
587
781
|
}
|
|
782
|
+
touchSession(sid);
|
|
588
783
|
} catch (error) {
|
|
589
784
|
console.error("Error sending message:", error);
|
|
590
|
-
addMessage({ text: "
|
|
785
|
+
addMessage({ text: "Sorry, something went wrong. Please try again.", role: "assistant" });
|
|
591
786
|
} finally {
|
|
592
787
|
setIsLoading(false);
|
|
593
788
|
}
|
|
594
789
|
};
|
|
790
|
+
const disconnectActiveSession = async () => {
|
|
791
|
+
try {
|
|
792
|
+
const deviceId = getOrCreateDeviceId();
|
|
793
|
+
const sid = activeSessionId;
|
|
794
|
+
if (!sid) return;
|
|
795
|
+
await fetch(`${PROXY_BASE_URL}/aizek-disconnect?clientId=${clientId}`, {
|
|
796
|
+
method: "POST",
|
|
797
|
+
headers: {
|
|
798
|
+
"Content-Type": "application/json",
|
|
799
|
+
"x-device-id": deviceId,
|
|
800
|
+
"x-session-id": sid,
|
|
801
|
+
"x-alternate": JSON.stringify(headers)
|
|
802
|
+
},
|
|
803
|
+
body: JSON.stringify({ sessionId: sid })
|
|
804
|
+
});
|
|
805
|
+
const nextStored = readStoredSessions().filter((s) => s.sessionId !== sid);
|
|
806
|
+
writeStoredSessions(nextStored);
|
|
807
|
+
const nextSessions = nextStored.map((x) => x.sessionId);
|
|
808
|
+
setSessions(nextSessions);
|
|
809
|
+
const nextActive = nextSessions[0] ?? null;
|
|
810
|
+
setActiveSessionIdState(nextActive);
|
|
811
|
+
setActiveSessionId(nextActive);
|
|
812
|
+
setMessages([]);
|
|
813
|
+
onDisconnect?.();
|
|
814
|
+
} catch (e) {
|
|
815
|
+
console.error(e);
|
|
816
|
+
}
|
|
817
|
+
};
|
|
818
|
+
const handleSelectSession = (sid) => {
|
|
819
|
+
setActiveSessionIdState(sid);
|
|
820
|
+
setActiveSessionId(sid);
|
|
821
|
+
setActiveTab("messages");
|
|
822
|
+
setMessageView("detail");
|
|
823
|
+
};
|
|
824
|
+
const getSessionLabel = (sid) => {
|
|
825
|
+
const idx = sessions.indexOf(sid);
|
|
826
|
+
return idx >= 0 ? `Chat ${idx + 1}` : "Chat";
|
|
827
|
+
};
|
|
595
828
|
const toggleChat = () => {
|
|
596
829
|
const newIsOpen = !isOpen;
|
|
597
830
|
setIsOpen(newIsOpen);
|
|
598
831
|
if (newIsOpen) onOpen?.();
|
|
599
832
|
else onClose?.();
|
|
600
833
|
};
|
|
834
|
+
const clean = sanitizeHtml__default.default(config?.widget_config.welcome_message ?? "", {
|
|
835
|
+
allowedTags: ["b", "i", "em", "strong", "a", "p", "br"],
|
|
836
|
+
allowedAttributes: {
|
|
837
|
+
a: ["href", "target", "rel"]
|
|
838
|
+
}
|
|
839
|
+
});
|
|
601
840
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: isConfigLoading ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
602
841
|
"button",
|
|
603
842
|
{
|
|
604
843
|
className: "floating-button bottom-right button-sizes medium loading-state",
|
|
605
844
|
style: { background: "#4f46e5" },
|
|
606
|
-
"aria-label": "
|
|
845
|
+
"aria-label": "Loading",
|
|
607
846
|
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "loading-spinner" })
|
|
608
847
|
}
|
|
609
848
|
) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
610
849
|
isOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `overlay floating-chat-overlay ${isOpen ? "is-open" : ""}`, onClick: toggleChat }),
|
|
611
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
className: "logo-image"
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
850
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
851
|
+
"div",
|
|
852
|
+
{
|
|
853
|
+
className: `chat-container ${config?.widget_config.button_position} ${isOpen ? "is-open" : ""}`,
|
|
854
|
+
style: { width: config?.widget_config.chat_width, height: config?.widget_config.chat_height },
|
|
855
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "chatbot-container", children: [
|
|
856
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "header", style: { background: config?.widget_config.header_background }, children: [
|
|
857
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "logo-container", children: config?.widget_config.company_logo ? config?.widget_config.company_logo.startsWith("http") || config?.widget_config.company_logo.startsWith("data:") ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: config?.widget_config.company_logo, alt: "Company Logo", className: "logo-image" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "logo-text", children: config?.widget_config.company_logo }) : "\u{1F916}" }),
|
|
858
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
859
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "company-name", children: config?.widget_config.company_name }),
|
|
860
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "status-text", children: isLoading ? "Typing..." : "Online" })
|
|
861
|
+
] })
|
|
862
|
+
] }),
|
|
863
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "chat-content", children: [
|
|
864
|
+
activeTab === "home" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "home-panel", children: [
|
|
865
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "eyebrow", children: "Welcome" }),
|
|
866
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "panel-title", children: config?.widget_config.company_name }),
|
|
867
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "panel-subtitle", children: "Ask anything. We keep your history and respond instantly." }),
|
|
868
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "home-actions", children: [
|
|
869
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
870
|
+
"button",
|
|
871
|
+
{
|
|
872
|
+
className: "primary-button",
|
|
873
|
+
onClick: async () => {
|
|
874
|
+
try {
|
|
875
|
+
await createNewSession();
|
|
876
|
+
} catch (e) {
|
|
877
|
+
console.error(e);
|
|
878
|
+
}
|
|
879
|
+
},
|
|
880
|
+
disabled: isLoading || sessions.length >= MAX_SESSIONS,
|
|
881
|
+
children: "Start a new conversation"
|
|
882
|
+
}
|
|
883
|
+
),
|
|
884
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
885
|
+
"button",
|
|
886
|
+
{
|
|
887
|
+
className: "ghost-button",
|
|
888
|
+
onClick: () => {
|
|
889
|
+
setActiveTab("messages");
|
|
890
|
+
setMessageView("list");
|
|
891
|
+
},
|
|
892
|
+
children: "View conversations"
|
|
893
|
+
}
|
|
894
|
+
)
|
|
895
|
+
] })
|
|
896
|
+
] }),
|
|
897
|
+
activeTab === "messages" && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: messageView === "list" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "conversation-list", children: [
|
|
898
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "list-header", children: [
|
|
899
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
900
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "eyebrow", children: "Conversations" }),
|
|
901
|
+
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "panel-title", children: "Inbox" })
|
|
902
|
+
] }),
|
|
903
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
904
|
+
"button",
|
|
905
|
+
{
|
|
906
|
+
className: "session-new-button",
|
|
907
|
+
onClick: async () => {
|
|
908
|
+
try {
|
|
909
|
+
await createNewSession();
|
|
910
|
+
} catch (e) {
|
|
911
|
+
console.error(e);
|
|
912
|
+
}
|
|
913
|
+
},
|
|
914
|
+
disabled: sessions.length >= MAX_SESSIONS,
|
|
915
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: "+ New" })
|
|
916
|
+
}
|
|
917
|
+
)
|
|
918
|
+
] }),
|
|
919
|
+
sessions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "empty-list", children: [
|
|
920
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "empty-state-icon", children: "\u{1F4AC}" }),
|
|
921
|
+
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "empty-state-title", children: "No conversations yet" }),
|
|
922
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "empty-state-description", children: "Start a new conversation to see it appear here." })
|
|
923
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "conversation-items", children: sessions.map((sid) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
924
|
+
"button",
|
|
925
|
+
{
|
|
926
|
+
className: `conversation-item ${sid === activeSessionId ? "active" : ""}`,
|
|
927
|
+
onClick: () => handleSelectSession(sid),
|
|
928
|
+
children: [
|
|
929
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "conversation-meta", children: [
|
|
930
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "conversation-title", children: getSessionLabel(sid) }),
|
|
931
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "conversation-sub", children: [
|
|
932
|
+
"Session ID: ",
|
|
933
|
+
sid.slice(0, 8),
|
|
934
|
+
"..."
|
|
935
|
+
] })
|
|
936
|
+
] }),
|
|
937
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "conversation-pill", children: "Open" })
|
|
938
|
+
]
|
|
939
|
+
},
|
|
940
|
+
sid
|
|
941
|
+
)) })
|
|
942
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "conversation-detail", children: [
|
|
943
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "detail-header", children: [
|
|
944
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "detail-header-left", children: /* @__PURE__ */ jsxRuntime.jsx("button", { className: "icon-button", onClick: () => setMessageView("list"), "aria-label": "Back", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
945
|
+
"path",
|
|
946
|
+
{
|
|
947
|
+
d: "M15 18l-6-6 6-6",
|
|
948
|
+
stroke: "currentColor",
|
|
949
|
+
strokeWidth: "2",
|
|
950
|
+
strokeLinecap: "round",
|
|
951
|
+
strokeLinejoin: "round"
|
|
952
|
+
}
|
|
953
|
+
) }) }) }),
|
|
954
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "detail-header-center", children: [
|
|
955
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "detail-avatar", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
956
|
+
"path",
|
|
957
|
+
{
|
|
958
|
+
d: "M12 3c-4.418 0-8 3.134-8 7 0 2.382 1.362 4.486 3.5 5.737V21l4.07-2.13c.14.008.283.013.43.013 4.418 0 8-3.134 8-7s-3.582-7-8-7z",
|
|
959
|
+
stroke: "currentColor",
|
|
960
|
+
strokeWidth: "2",
|
|
961
|
+
strokeLinejoin: "round"
|
|
962
|
+
}
|
|
963
|
+
) }) }),
|
|
964
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "detail-title", children: [
|
|
965
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "detail-title-row", children: [
|
|
966
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { className: "detail-title-text", children: activeSessionId ? getSessionLabel(activeSessionId) : "Chat" }),
|
|
967
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `status-dot ${isLoading ? "typing" : "online"}`, "aria-hidden": "true" })
|
|
968
|
+
] }),
|
|
969
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "detail-subtitle", children: isLoading ? "Yaz\u0131yor\u2026" : "Online" })
|
|
970
|
+
] })
|
|
971
|
+
] }),
|
|
972
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "detail-header-right", children: [
|
|
973
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
974
|
+
"button",
|
|
975
|
+
{
|
|
976
|
+
className: "icon-button",
|
|
977
|
+
onClick: () => {
|
|
978
|
+
setActiveTab("info");
|
|
979
|
+
setMessageView("list");
|
|
980
|
+
},
|
|
981
|
+
"aria-label": "Bilgi",
|
|
982
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", children: [
|
|
983
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
984
|
+
"path",
|
|
985
|
+
{
|
|
986
|
+
d: "M12 17v-6",
|
|
987
|
+
stroke: "currentColor",
|
|
988
|
+
strokeWidth: "2",
|
|
989
|
+
strokeLinecap: "round"
|
|
990
|
+
}
|
|
991
|
+
),
|
|
992
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
993
|
+
"path",
|
|
994
|
+
{
|
|
995
|
+
d: "M12 8h.01",
|
|
996
|
+
stroke: "currentColor",
|
|
997
|
+
strokeWidth: "2.5",
|
|
998
|
+
strokeLinecap: "round"
|
|
999
|
+
}
|
|
1000
|
+
),
|
|
1001
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1002
|
+
"circle",
|
|
1003
|
+
{
|
|
1004
|
+
cx: "12",
|
|
1005
|
+
cy: "12",
|
|
1006
|
+
r: "9",
|
|
1007
|
+
stroke: "currentColor",
|
|
1008
|
+
strokeWidth: "2"
|
|
1009
|
+
}
|
|
1010
|
+
)
|
|
1011
|
+
] })
|
|
1012
|
+
}
|
|
1013
|
+
),
|
|
1014
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1015
|
+
"button",
|
|
1016
|
+
{
|
|
1017
|
+
className: "icon-button danger",
|
|
1018
|
+
onClick: disconnectActiveSession,
|
|
1019
|
+
disabled: !activeSessionId,
|
|
1020
|
+
"aria-label": "End conversation",
|
|
1021
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", children: [
|
|
1022
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1023
|
+
"path",
|
|
1024
|
+
{
|
|
1025
|
+
d: "M3 6h18",
|
|
1026
|
+
stroke: "currentColor",
|
|
1027
|
+
strokeWidth: "2",
|
|
1028
|
+
strokeLinecap: "round"
|
|
1029
|
+
}
|
|
1030
|
+
),
|
|
1031
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1032
|
+
"path",
|
|
1033
|
+
{
|
|
1034
|
+
d: "M8 6V4h8v2",
|
|
1035
|
+
stroke: "currentColor",
|
|
1036
|
+
strokeWidth: "2",
|
|
1037
|
+
strokeLinejoin: "round"
|
|
1038
|
+
}
|
|
1039
|
+
),
|
|
1040
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1041
|
+
"path",
|
|
1042
|
+
{
|
|
1043
|
+
d: "M6 6l1 16h10l1-16",
|
|
1044
|
+
stroke: "currentColor",
|
|
1045
|
+
strokeWidth: "2",
|
|
1046
|
+
strokeLinejoin: "round"
|
|
1047
|
+
}
|
|
1048
|
+
)
|
|
1049
|
+
] })
|
|
1050
|
+
}
|
|
1051
|
+
)
|
|
1052
|
+
] })
|
|
1053
|
+
] }),
|
|
1054
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "messages-container", children: [
|
|
1055
|
+
/* @__PURE__ */ jsxRuntime.jsx(HeaderAlert, { headerValidation, setShowAlert, showAlert }),
|
|
1056
|
+
messages.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "empty-state", children: /* @__PURE__ */ jsxRuntime.jsx("span", { dangerouslySetInnerHTML: { __html: clean } }) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1057
|
+
messages.map((message, index) => /* @__PURE__ */ jsxRuntime.jsx(MessageBubble, { message, onAction: sendMessage }, index)),
|
|
1058
|
+
config?.widget_config.show_typing_indicator && isLoading && /* @__PURE__ */ jsxRuntime.jsx(TypingDots, {})
|
|
1059
|
+
] }),
|
|
1060
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: messagesEndRef })
|
|
1061
|
+
] }),
|
|
1062
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1063
|
+
ChatInput,
|
|
1064
|
+
{
|
|
1065
|
+
handleSendMessage: sendMessage,
|
|
1066
|
+
isLoading,
|
|
1067
|
+
placeholder: config?.widget_config.placeholder ?? ""
|
|
1068
|
+
}
|
|
1069
|
+
)
|
|
1070
|
+
] }) }),
|
|
1071
|
+
activeTab === "info" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "info-panel", children: [
|
|
1072
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "eyebrow", children: "Info" }),
|
|
1073
|
+
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "panel-title", children: "Widget Details" }),
|
|
1074
|
+
/* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "info-list", children: [
|
|
1075
|
+
/* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
1076
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Company" }),
|
|
1077
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: config?.widget_config.company_name })
|
|
1078
|
+
] }),
|
|
1079
|
+
/* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
1080
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Status" }),
|
|
1081
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: isLoading ? "Typing..." : "Online" })
|
|
1082
|
+
] }),
|
|
1083
|
+
/* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
1084
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Conversations" }),
|
|
1085
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: sessions.length })
|
|
1086
|
+
] })
|
|
1087
|
+
] })
|
|
1088
|
+
] })
|
|
1089
|
+
] }),
|
|
1090
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bottom-nav", children: [
|
|
1091
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1092
|
+
"button",
|
|
1093
|
+
{
|
|
1094
|
+
className: `nav-button ${activeTab === "home" ? "active" : ""}`,
|
|
1095
|
+
onClick: () => {
|
|
1096
|
+
setActiveTab("home");
|
|
1097
|
+
setMessageView("list");
|
|
1098
|
+
},
|
|
1099
|
+
children: "Home"
|
|
1100
|
+
}
|
|
1101
|
+
),
|
|
1102
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1103
|
+
"button",
|
|
1104
|
+
{
|
|
1105
|
+
className: `nav-button ${activeTab === "messages" ? "active" : ""}`,
|
|
1106
|
+
onClick: () => {
|
|
1107
|
+
setActiveTab("messages");
|
|
1108
|
+
setMessageView("list");
|
|
1109
|
+
},
|
|
1110
|
+
children: "Messages"
|
|
1111
|
+
}
|
|
1112
|
+
),
|
|
1113
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1114
|
+
"button",
|
|
1115
|
+
{
|
|
1116
|
+
className: `nav-button ${activeTab === "info" ? "active" : ""}`,
|
|
1117
|
+
onClick: () => {
|
|
1118
|
+
setActiveTab("info");
|
|
1119
|
+
setMessageView("list");
|
|
1120
|
+
},
|
|
1121
|
+
children: "Info"
|
|
1122
|
+
}
|
|
1123
|
+
)
|
|
1124
|
+
] })
|
|
624
1125
|
] })
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
628
|
-
HeaderAlert,
|
|
629
|
-
{
|
|
630
|
-
headerValidation,
|
|
631
|
-
setShowAlert,
|
|
632
|
-
showAlert
|
|
633
|
-
}
|
|
634
|
-
),
|
|
635
|
-
messages.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "empty-state", children: [
|
|
636
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "empty-state-icon", children: "\u{1F4AC}" }),
|
|
637
|
-
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "empty-state-title", children: config?.widget_config.welcome_message }),
|
|
638
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "empty-state-description", children: "A\u015Fa\u011F\u0131daki alana mesaj\u0131n\u0131z\u0131 yazarak ba\u015Flayabilirsiniz." })
|
|
639
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
640
|
-
messages.map((message, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
641
|
-
MessageBubble,
|
|
642
|
-
{
|
|
643
|
-
message,
|
|
644
|
-
onAction: sendMessage
|
|
645
|
-
},
|
|
646
|
-
index
|
|
647
|
-
)),
|
|
648
|
-
config?.widget_config.show_typing_indicator && isLoading && /* @__PURE__ */ jsxRuntime.jsx(TypingDots, {})
|
|
649
|
-
] }),
|
|
650
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: messagesEndRef })
|
|
651
|
-
] }),
|
|
652
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
653
|
-
ChatInput,
|
|
654
|
-
{
|
|
655
|
-
handleSendMessage: sendMessage,
|
|
656
|
-
isLoading,
|
|
657
|
-
placeholder: config?.widget_config.placeholder ?? ""
|
|
658
|
-
}
|
|
659
|
-
)
|
|
660
|
-
] }) }),
|
|
1126
|
+
}
|
|
1127
|
+
),
|
|
661
1128
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
662
1129
|
"button",
|
|
663
1130
|
{
|
|
664
1131
|
onClick: toggleChat,
|
|
665
1132
|
className: `floating-button ${config?.widget_config.button_position} button-sizes ${config?.widget_config.button_size} ${isOpen ? "is-open" : ""}`,
|
|
666
1133
|
style: { background: config?.widget_config.button_background },
|
|
667
|
-
|
|
668
|
-
children: isOpen ? /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) : /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h4l4 4 4-4h4c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z" }) })
|
|
1134
|
+
children: isOpen ? /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) : /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h4l4 4 4-4h4c1.1 0-2 .9-2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z" }) })
|
|
669
1135
|
}
|
|
670
1136
|
)
|
|
671
1137
|
] }) });
|