@akropolys/kiku 1.7.8 → 1.7.10
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.js +668 -437
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +660 -429
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +215 -0
- package/dist/styles.css.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -794,7 +794,7 @@ I couldn't find any matching products in the store.`;
|
|
|
794
794
|
}
|
|
795
795
|
|
|
796
796
|
// src/components/KikuButton.tsx
|
|
797
|
-
import { useState as
|
|
797
|
+
import { useState as useState6, useEffect as useEffect4, useRef as useRef6, useCallback as useCallback2 } from "react";
|
|
798
798
|
import { createPortal } from "react-dom";
|
|
799
799
|
import { useKiku as useKiku2 } from "@akropolys/sdk";
|
|
800
800
|
import { useAkropolysContext as useAkropolysContext3 } from "@akropolys/sdk";
|
|
@@ -1107,9 +1107,226 @@ function ComparisonMatrix({ sources, defaultCurrency = "KES", displayConfig }) {
|
|
|
1107
1107
|
);
|
|
1108
1108
|
}
|
|
1109
1109
|
|
|
1110
|
+
// src/components/MarkupEditor.tsx
|
|
1111
|
+
import { useEffect as useEffect3, useRef as useRef5, useState as useState5 } from "react";
|
|
1112
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1113
|
+
var COLORS = ["#111111", "#ff5a5a", "#ffb300", "#22c55e", "#06b6d4", "#d946ef", "#9ca3af"];
|
|
1114
|
+
var MAX_EXPORT_DIM = 1280;
|
|
1115
|
+
function MarkupEditor({ src, onCancel, onSend }) {
|
|
1116
|
+
const [img, setImg] = useState5(null);
|
|
1117
|
+
const [loadError, setLoadError] = useState5(false);
|
|
1118
|
+
const [tool, setTool] = useState5("pen");
|
|
1119
|
+
const [color, setColor] = useState5(COLORS[1]);
|
|
1120
|
+
const [actions, setActions] = useState5([]);
|
|
1121
|
+
const [pendingText, setPendingText] = useState5(null);
|
|
1122
|
+
const [textValue, setTextValue] = useState5("");
|
|
1123
|
+
const [instruction, setInstruction] = useState5("");
|
|
1124
|
+
const [exportError, setExportError] = useState5(false);
|
|
1125
|
+
const canvasRef = useRef5(null);
|
|
1126
|
+
const drawingRef = useRef5(null);
|
|
1127
|
+
const textInputRef = useRef5(null);
|
|
1128
|
+
useEffect3(() => {
|
|
1129
|
+
const el = new Image();
|
|
1130
|
+
el.crossOrigin = "anonymous";
|
|
1131
|
+
el.onload = () => setImg(el);
|
|
1132
|
+
el.onerror = () => setLoadError(true);
|
|
1133
|
+
el.src = src;
|
|
1134
|
+
}, [src]);
|
|
1135
|
+
const dims = (() => {
|
|
1136
|
+
if (!img) return { w: 0, h: 0 };
|
|
1137
|
+
const scale = Math.min(1, MAX_EXPORT_DIM / Math.max(img.naturalWidth, img.naturalHeight));
|
|
1138
|
+
return { w: Math.round(img.naturalWidth * scale), h: Math.round(img.naturalHeight * scale) };
|
|
1139
|
+
})();
|
|
1140
|
+
const markLayer = useRef5(null);
|
|
1141
|
+
const paint = (live) => {
|
|
1142
|
+
const canvas = canvasRef.current;
|
|
1143
|
+
if (!canvas || !img) return;
|
|
1144
|
+
const ctx = canvas.getContext("2d");
|
|
1145
|
+
if (!ctx) return;
|
|
1146
|
+
if (!markLayer.current) markLayer.current = document.createElement("canvas");
|
|
1147
|
+
const layer = markLayer.current;
|
|
1148
|
+
layer.width = canvas.width;
|
|
1149
|
+
layer.height = canvas.height;
|
|
1150
|
+
const lctx = layer.getContext("2d");
|
|
1151
|
+
const all = live ? [...actions, live] : actions;
|
|
1152
|
+
for (const a of all) {
|
|
1153
|
+
if (a.kind === "stroke") {
|
|
1154
|
+
lctx.save();
|
|
1155
|
+
lctx.globalCompositeOperation = a.tool === "eraser" ? "destination-out" : "source-over";
|
|
1156
|
+
lctx.strokeStyle = a.color;
|
|
1157
|
+
lctx.lineWidth = a.tool === "eraser" ? a.size * 3 : a.size;
|
|
1158
|
+
lctx.lineCap = "round";
|
|
1159
|
+
lctx.lineJoin = "round";
|
|
1160
|
+
lctx.beginPath();
|
|
1161
|
+
a.points.forEach((p, i) => i === 0 ? lctx.moveTo(p.x, p.y) : lctx.lineTo(p.x, p.y));
|
|
1162
|
+
if (a.points.length === 1) lctx.lineTo(a.points[0].x + 0.01, a.points[0].y);
|
|
1163
|
+
lctx.stroke();
|
|
1164
|
+
lctx.restore();
|
|
1165
|
+
} else {
|
|
1166
|
+
lctx.save();
|
|
1167
|
+
lctx.fillStyle = a.color;
|
|
1168
|
+
lctx.font = `600 ${a.size}px system-ui, sans-serif`;
|
|
1169
|
+
lctx.fillText(a.value, a.x, a.y);
|
|
1170
|
+
lctx.restore();
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
1174
|
+
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
|
|
1175
|
+
ctx.drawImage(layer, 0, 0);
|
|
1176
|
+
};
|
|
1177
|
+
useEffect3(() => {
|
|
1178
|
+
paint();
|
|
1179
|
+
}, [img, actions, dims.w, dims.h]);
|
|
1180
|
+
useEffect3(() => {
|
|
1181
|
+
if (pendingText) textInputRef.current?.focus();
|
|
1182
|
+
}, [pendingText]);
|
|
1183
|
+
const toCanvasPoint = (e) => {
|
|
1184
|
+
const canvas = canvasRef.current;
|
|
1185
|
+
const rect = canvas.getBoundingClientRect();
|
|
1186
|
+
return {
|
|
1187
|
+
x: (e.clientX - rect.left) / rect.width * canvas.width,
|
|
1188
|
+
y: (e.clientY - rect.top) / rect.height * canvas.height
|
|
1189
|
+
};
|
|
1190
|
+
};
|
|
1191
|
+
const strokeSize = () => Math.max(4, Math.round(dims.w / 180));
|
|
1192
|
+
const textSize = () => Math.max(18, Math.round(dims.w / 28));
|
|
1193
|
+
const onPointerDown = (e) => {
|
|
1194
|
+
if (!img) return;
|
|
1195
|
+
const p = toCanvasPoint(e);
|
|
1196
|
+
if (tool === "text") {
|
|
1197
|
+
setPendingText({ x: p.x, y: p.y });
|
|
1198
|
+
setTextValue("");
|
|
1199
|
+
return;
|
|
1200
|
+
}
|
|
1201
|
+
e.target.setPointerCapture(e.pointerId);
|
|
1202
|
+
drawingRef.current = { kind: "stroke", tool, color, size: strokeSize(), points: [p] };
|
|
1203
|
+
paint(drawingRef.current);
|
|
1204
|
+
};
|
|
1205
|
+
const onPointerMove = (e) => {
|
|
1206
|
+
if (!drawingRef.current) return;
|
|
1207
|
+
drawingRef.current.points.push(toCanvasPoint(e));
|
|
1208
|
+
paint(drawingRef.current);
|
|
1209
|
+
};
|
|
1210
|
+
const onPointerUp = () => {
|
|
1211
|
+
if (!drawingRef.current) return;
|
|
1212
|
+
const done = drawingRef.current;
|
|
1213
|
+
drawingRef.current = null;
|
|
1214
|
+
setActions((prev) => [...prev, done]);
|
|
1215
|
+
};
|
|
1216
|
+
const commitText = () => {
|
|
1217
|
+
if (pendingText && textValue.trim()) {
|
|
1218
|
+
setActions((prev) => [...prev, { kind: "text", x: pendingText.x, y: pendingText.y, color, value: textValue.trim(), size: textSize() }]);
|
|
1219
|
+
}
|
|
1220
|
+
setPendingText(null);
|
|
1221
|
+
setTextValue("");
|
|
1222
|
+
};
|
|
1223
|
+
const handleSend = () => {
|
|
1224
|
+
const canvas = canvasRef.current;
|
|
1225
|
+
if (!canvas) return;
|
|
1226
|
+
try {
|
|
1227
|
+
paint();
|
|
1228
|
+
const dataUrl = canvas.toDataURL("image/jpeg", 0.92);
|
|
1229
|
+
onSend(dataUrl, instruction.trim());
|
|
1230
|
+
} catch {
|
|
1231
|
+
setExportError(true);
|
|
1232
|
+
}
|
|
1233
|
+
};
|
|
1234
|
+
const hasMarks = actions.length > 0;
|
|
1235
|
+
return /* @__PURE__ */ jsxs6("div", { className: "hsk-markup", role: "dialog", "aria-label": "Mark up image", children: [
|
|
1236
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-markup-head", children: [
|
|
1237
|
+
/* @__PURE__ */ jsx7("span", { className: "hsk-markup-title", children: "Mark where you want the change" }),
|
|
1238
|
+
/* @__PURE__ */ jsx7("button", { className: "hsk-markup-cancel", onClick: onCancel, children: "Cancel" })
|
|
1239
|
+
] }),
|
|
1240
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-markup-stage", children: loadError ? /* @__PURE__ */ jsx7("div", { className: "hsk-markup-error", children: "This image can't be edited here." }) : !img ? /* @__PURE__ */ jsx7("div", { className: "hsk-markup-loading", children: "Loading image\u2026" }) : /* @__PURE__ */ jsxs6("div", { className: "hsk-markup-canvas-wrap", children: [
|
|
1241
|
+
/* @__PURE__ */ jsx7(
|
|
1242
|
+
"canvas",
|
|
1243
|
+
{
|
|
1244
|
+
ref: canvasRef,
|
|
1245
|
+
width: dims.w,
|
|
1246
|
+
height: dims.h,
|
|
1247
|
+
className: `hsk-markup-canvas hsk-markup-canvas--${tool}`,
|
|
1248
|
+
onPointerDown,
|
|
1249
|
+
onPointerMove,
|
|
1250
|
+
onPointerUp,
|
|
1251
|
+
onPointerLeave: onPointerUp
|
|
1252
|
+
}
|
|
1253
|
+
),
|
|
1254
|
+
pendingText && canvasRef.current && /* @__PURE__ */ jsx7(
|
|
1255
|
+
"input",
|
|
1256
|
+
{
|
|
1257
|
+
ref: textInputRef,
|
|
1258
|
+
className: "hsk-markup-textinput",
|
|
1259
|
+
style: {
|
|
1260
|
+
left: `${pendingText.x / dims.w * 100}%`,
|
|
1261
|
+
top: `${pendingText.y / dims.h * 100}%`,
|
|
1262
|
+
color
|
|
1263
|
+
},
|
|
1264
|
+
value: textValue,
|
|
1265
|
+
placeholder: "Type, then Enter",
|
|
1266
|
+
onChange: (e) => setTextValue(e.target.value),
|
|
1267
|
+
onKeyDown: (e) => {
|
|
1268
|
+
if (e.key === "Enter") commitText();
|
|
1269
|
+
if (e.key === "Escape") {
|
|
1270
|
+
setPendingText(null);
|
|
1271
|
+
setTextValue("");
|
|
1272
|
+
}
|
|
1273
|
+
},
|
|
1274
|
+
onBlur: commitText
|
|
1275
|
+
}
|
|
1276
|
+
)
|
|
1277
|
+
] }) }),
|
|
1278
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-markup-tools", children: [
|
|
1279
|
+
/* @__PURE__ */ jsx7("div", { className: "hsk-markup-colors", children: COLORS.map((c) => /* @__PURE__ */ jsx7(
|
|
1280
|
+
"button",
|
|
1281
|
+
{
|
|
1282
|
+
className: `hsk-markup-color${color === c ? " hsk-markup-color--on" : ""}`,
|
|
1283
|
+
style: { background: c },
|
|
1284
|
+
onClick: () => {
|
|
1285
|
+
setColor(c);
|
|
1286
|
+
if (tool === "eraser") setTool("pen");
|
|
1287
|
+
},
|
|
1288
|
+
"aria-label": `Colour ${c}`
|
|
1289
|
+
},
|
|
1290
|
+
c
|
|
1291
|
+
)) }),
|
|
1292
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-markup-actions", children: [
|
|
1293
|
+
/* @__PURE__ */ jsx7("button", { className: `hsk-markup-tool${tool === "pen" ? " hsk-markup-tool--on" : ""}`, onClick: () => setTool("pen"), children: "Sketch" }),
|
|
1294
|
+
/* @__PURE__ */ jsx7("button", { className: `hsk-markup-tool${tool === "text" ? " hsk-markup-tool--on" : ""}`, onClick: () => setTool("text"), children: "Text" }),
|
|
1295
|
+
/* @__PURE__ */ jsx7("button", { className: `hsk-markup-tool${tool === "eraser" ? " hsk-markup-tool--on" : ""}`, onClick: () => setTool("eraser"), children: "Eraser" }),
|
|
1296
|
+
/* @__PURE__ */ jsx7("button", { className: "hsk-markup-tool", onClick: () => setActions((prev) => prev.slice(0, -1)), disabled: !hasMarks, children: "Undo" }),
|
|
1297
|
+
/* @__PURE__ */ jsx7("button", { className: "hsk-markup-tool", onClick: () => setActions([]), disabled: !hasMarks, children: "Clear" })
|
|
1298
|
+
] })
|
|
1299
|
+
] }),
|
|
1300
|
+
/* @__PURE__ */ jsxs6("div", { className: "hsk-markup-send", children: [
|
|
1301
|
+
/* @__PURE__ */ jsx7(
|
|
1302
|
+
"input",
|
|
1303
|
+
{
|
|
1304
|
+
className: "hsk-markup-instruction",
|
|
1305
|
+
value: instruction,
|
|
1306
|
+
placeholder: "Describe the change \u2014 e.g. add the sofa here",
|
|
1307
|
+
onChange: (e) => setInstruction(e.target.value),
|
|
1308
|
+
onKeyDown: (e) => {
|
|
1309
|
+
if (e.key === "Enter" && (hasMarks || instruction.trim())) handleSend();
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
),
|
|
1313
|
+
/* @__PURE__ */ jsx7(
|
|
1314
|
+
"button",
|
|
1315
|
+
{
|
|
1316
|
+
className: "hsk-markup-go",
|
|
1317
|
+
onClick: handleSend,
|
|
1318
|
+
disabled: !img || !hasMarks && !instruction.trim(),
|
|
1319
|
+
children: "Send"
|
|
1320
|
+
}
|
|
1321
|
+
)
|
|
1322
|
+
] }),
|
|
1323
|
+
exportError && /* @__PURE__ */ jsx7("div", { className: "hsk-markup-error", children: "Couldn't process this image \u2014 try a newer visualization." })
|
|
1324
|
+
] });
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1110
1327
|
// src/components/KikuButton.tsx
|
|
1111
|
-
import { Fragment as Fragment3, jsx as
|
|
1112
|
-
var KikuIcon = ({ className, size = 18 }) => /* @__PURE__ */
|
|
1328
|
+
import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1329
|
+
var KikuIcon = ({ className, size = 18 }) => /* @__PURE__ */ jsx8(
|
|
1113
1330
|
"svg",
|
|
1114
1331
|
{
|
|
1115
1332
|
className: cn("hsk-brand-mark", className),
|
|
@@ -1118,52 +1335,52 @@ var KikuIcon = ({ className, size = 18 }) => /* @__PURE__ */ jsx7(
|
|
|
1118
1335
|
viewBox: "0 0 100 100",
|
|
1119
1336
|
xmlns: "http://www.w3.org/2000/svg",
|
|
1120
1337
|
"aria-label": "kiku",
|
|
1121
|
-
children: /* @__PURE__ */
|
|
1122
|
-
/* @__PURE__ */
|
|
1123
|
-
/* @__PURE__ */
|
|
1338
|
+
children: /* @__PURE__ */ jsxs7("g", { transform: "translate(22.7 19) scale(0.62)", fill: "currentColor", fillRule: "evenodd", children: [
|
|
1339
|
+
/* @__PURE__ */ jsx8("path", { d: "M39.4 10.4 Q44 0 48.6 10.4 L86.1 95.8 Q88 100 83.4 100 L4.6 100 Q0 100 1.9 95.8 Z M24 100 L24 65 Q24 60 27.4 56.3 Q44 38 60.6 56.3 Q64 60 64 65 L64 100 Z" }),
|
|
1340
|
+
/* @__PURE__ */ jsx8("circle", { cx: "55", cy: "82", r: "3.4" })
|
|
1124
1341
|
] })
|
|
1125
1342
|
}
|
|
1126
1343
|
);
|
|
1127
1344
|
var SparkleIcon2 = KikuIcon;
|
|
1128
|
-
var ArrowUpIcon2 = () => /* @__PURE__ */
|
|
1129
|
-
/* @__PURE__ */
|
|
1130
|
-
/* @__PURE__ */
|
|
1345
|
+
var ArrowUpIcon2 = () => /* @__PURE__ */ jsxs7("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1346
|
+
/* @__PURE__ */ jsx8("path", { d: "m5 12 7-7 7 7" }),
|
|
1347
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 19V5" })
|
|
1131
1348
|
] });
|
|
1132
|
-
var StopIcon = () => /* @__PURE__ */
|
|
1133
|
-
var ExternalIcon = () => /* @__PURE__ */
|
|
1134
|
-
/* @__PURE__ */
|
|
1135
|
-
/* @__PURE__ */
|
|
1136
|
-
/* @__PURE__ */
|
|
1349
|
+
var StopIcon = () => /* @__PURE__ */ jsx8("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx8("rect", { x: "5", y: "5", width: "14", height: "14", rx: "2" }) });
|
|
1350
|
+
var ExternalIcon = () => /* @__PURE__ */ jsxs7("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1351
|
+
/* @__PURE__ */ jsx8("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
|
|
1352
|
+
/* @__PURE__ */ jsx8("polyline", { points: "15 3 21 3 21 9" }),
|
|
1353
|
+
/* @__PURE__ */ jsx8("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
|
|
1137
1354
|
] });
|
|
1138
|
-
var ContinueIcon = () => /* @__PURE__ */
|
|
1139
|
-
var CloseIcon = () => /* @__PURE__ */
|
|
1140
|
-
/* @__PURE__ */
|
|
1141
|
-
/* @__PURE__ */
|
|
1355
|
+
var ContinueIcon = () => /* @__PURE__ */ jsx8("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx8("path", { d: "M8 5v14l11-7z" }) });
|
|
1356
|
+
var CloseIcon = () => /* @__PURE__ */ jsxs7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1357
|
+
/* @__PURE__ */ jsx8("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
1358
|
+
/* @__PURE__ */ jsx8("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
1142
1359
|
] });
|
|
1143
|
-
var ChevronRightIcon = () => /* @__PURE__ */
|
|
1144
|
-
var HistoryIcon = () => /* @__PURE__ */
|
|
1145
|
-
/* @__PURE__ */
|
|
1146
|
-
/* @__PURE__ */
|
|
1147
|
-
/* @__PURE__ */
|
|
1360
|
+
var ChevronRightIcon = () => /* @__PURE__ */ jsx8("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx8("path", { d: "m9 18 6-6-6-6" }) });
|
|
1361
|
+
var HistoryIcon = () => /* @__PURE__ */ jsxs7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1362
|
+
/* @__PURE__ */ jsx8("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
|
|
1363
|
+
/* @__PURE__ */ jsx8("path", { d: "M3 3v5h5" }),
|
|
1364
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 7v5l4 2" })
|
|
1148
1365
|
] });
|
|
1149
|
-
var BookmarkIcon = () => /* @__PURE__ */
|
|
1150
|
-
var TrashIcon = () => /* @__PURE__ */
|
|
1151
|
-
/* @__PURE__ */
|
|
1152
|
-
/* @__PURE__ */
|
|
1366
|
+
var BookmarkIcon = () => /* @__PURE__ */ jsx8("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx8("path", { d: "M19 21 12 16l-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z" }) });
|
|
1367
|
+
var TrashIcon = () => /* @__PURE__ */ jsxs7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1368
|
+
/* @__PURE__ */ jsx8("path", { d: "M3 6h18" }),
|
|
1369
|
+
/* @__PURE__ */ jsx8("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
|
|
1153
1370
|
] });
|
|
1154
|
-
var PaperclipIcon = () => /* @__PURE__ */
|
|
1155
|
-
var MicIcon2 = () => /* @__PURE__ */
|
|
1156
|
-
/* @__PURE__ */
|
|
1157
|
-
/* @__PURE__ */
|
|
1158
|
-
/* @__PURE__ */
|
|
1371
|
+
var PaperclipIcon = () => /* @__PURE__ */ jsx8("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx8("path", { d: "m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48" }) });
|
|
1372
|
+
var MicIcon2 = () => /* @__PURE__ */ jsxs7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1373
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z" }),
|
|
1374
|
+
/* @__PURE__ */ jsx8("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
|
|
1375
|
+
/* @__PURE__ */ jsx8("line", { x1: "12", y1: "19", x2: "12", y2: "22" })
|
|
1159
1376
|
] });
|
|
1160
|
-
var MicOffIcon = () => /* @__PURE__ */
|
|
1161
|
-
/* @__PURE__ */
|
|
1162
|
-
/* @__PURE__ */
|
|
1163
|
-
/* @__PURE__ */
|
|
1164
|
-
/* @__PURE__ */
|
|
1165
|
-
/* @__PURE__ */
|
|
1166
|
-
/* @__PURE__ */
|
|
1377
|
+
var MicOffIcon = () => /* @__PURE__ */ jsxs7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1378
|
+
/* @__PURE__ */ jsx8("line", { x1: "2", y1: "2", x2: "22", y2: "22" }),
|
|
1379
|
+
/* @__PURE__ */ jsx8("path", { d: "M18.89 13.23A7.12 7.12 0 0 0 19 12v-2" }),
|
|
1380
|
+
/* @__PURE__ */ jsx8("path", { d: "M5 10v2a7 7 0 0 0 12 5" }),
|
|
1381
|
+
/* @__PURE__ */ jsx8("path", { d: "M15 9.34V5a3 3 0 0 0-5.68-1.33" }),
|
|
1382
|
+
/* @__PURE__ */ jsx8("path", { d: "M9 9v3a3 3 0 0 0 5.12 2.12" }),
|
|
1383
|
+
/* @__PURE__ */ jsx8("line", { x1: "12", y1: "19", x2: "12", y2: "22" })
|
|
1167
1384
|
] });
|
|
1168
1385
|
var DEFAULT_CHIPS = [];
|
|
1169
1386
|
function extractName(raw) {
|
|
@@ -1213,7 +1430,7 @@ function KikuPickerMenu({
|
|
|
1213
1430
|
onDismiss
|
|
1214
1431
|
}) {
|
|
1215
1432
|
const discussed = sources.filter((s) => s.id && referencedIds.includes(s.id));
|
|
1216
|
-
return /* @__PURE__ */
|
|
1433
|
+
return /* @__PURE__ */ jsxs7(
|
|
1217
1434
|
"div",
|
|
1218
1435
|
{
|
|
1219
1436
|
className: "hsk-kiku-picker",
|
|
@@ -1221,7 +1438,7 @@ function KikuPickerMenu({
|
|
|
1221
1438
|
"aria-label": "@kiku commands",
|
|
1222
1439
|
onMouseDown: (e) => e.preventDefault(),
|
|
1223
1440
|
children: [
|
|
1224
|
-
discussed.map((src, i) => /* @__PURE__ */
|
|
1441
|
+
discussed.map((src, i) => /* @__PURE__ */ jsxs7(
|
|
1225
1442
|
"button",
|
|
1226
1443
|
{
|
|
1227
1444
|
className: "hsk-kiku-picker-item",
|
|
@@ -1231,9 +1448,9 @@ function KikuPickerMenu({
|
|
|
1231
1448
|
onDismiss();
|
|
1232
1449
|
},
|
|
1233
1450
|
children: [
|
|
1234
|
-
/* @__PURE__ */
|
|
1235
|
-
/* @__PURE__ */
|
|
1236
|
-
src.price && /* @__PURE__ */
|
|
1451
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-icon", children: src.image ? /* @__PURE__ */ jsx8("img", { src: src.image, alt: "" }) : /* @__PURE__ */ jsx8(BookmarkIcon, {}) }),
|
|
1452
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-item-name", children: src.name }),
|
|
1453
|
+
src.price && /* @__PURE__ */ jsxs7("span", { className: "hsk-kiku-picker-item-price", children: [
|
|
1237
1454
|
src.currency ?? defaultCurrency,
|
|
1238
1455
|
" ",
|
|
1239
1456
|
parseFloat(String(src.price).replace(/[^0-9.]/g, "") || "0").toLocaleString()
|
|
@@ -1242,7 +1459,7 @@ function KikuPickerMenu({
|
|
|
1242
1459
|
},
|
|
1243
1460
|
src.id ?? i
|
|
1244
1461
|
)),
|
|
1245
|
-
discussed.length > 1 && /* @__PURE__ */
|
|
1462
|
+
discussed.length > 1 && /* @__PURE__ */ jsxs7(
|
|
1246
1463
|
"button",
|
|
1247
1464
|
{
|
|
1248
1465
|
className: "hsk-kiku-picker-item",
|
|
@@ -1252,8 +1469,8 @@ function KikuPickerMenu({
|
|
|
1252
1469
|
onDismiss();
|
|
1253
1470
|
},
|
|
1254
1471
|
children: [
|
|
1255
|
-
/* @__PURE__ */
|
|
1256
|
-
/* @__PURE__ */
|
|
1472
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-icon", children: /* @__PURE__ */ jsx8(BookmarkIcon, {}) }),
|
|
1473
|
+
/* @__PURE__ */ jsxs7("span", { className: "hsk-kiku-picker-item-name", children: [
|
|
1257
1474
|
"Capture all (",
|
|
1258
1475
|
discussed.length,
|
|
1259
1476
|
")"
|
|
@@ -1261,7 +1478,7 @@ function KikuPickerMenu({
|
|
|
1261
1478
|
]
|
|
1262
1479
|
}
|
|
1263
1480
|
),
|
|
1264
|
-
discussed.length === 0 && /* @__PURE__ */
|
|
1481
|
+
discussed.length === 0 && /* @__PURE__ */ jsxs7(
|
|
1265
1482
|
"button",
|
|
1266
1483
|
{
|
|
1267
1484
|
className: "hsk-kiku-picker-item",
|
|
@@ -1271,12 +1488,12 @@ function KikuPickerMenu({
|
|
|
1271
1488
|
onDismiss();
|
|
1272
1489
|
},
|
|
1273
1490
|
children: [
|
|
1274
|
-
/* @__PURE__ */
|
|
1275
|
-
/* @__PURE__ */
|
|
1491
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-icon", children: /* @__PURE__ */ jsx8(BookmarkIcon, {}) }),
|
|
1492
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-item-name", children: "Capture current page" })
|
|
1276
1493
|
]
|
|
1277
1494
|
}
|
|
1278
1495
|
),
|
|
1279
|
-
/* @__PURE__ */
|
|
1496
|
+
/* @__PURE__ */ jsxs7(
|
|
1280
1497
|
"button",
|
|
1281
1498
|
{
|
|
1282
1499
|
className: "hsk-kiku-picker-item",
|
|
@@ -1286,12 +1503,12 @@ function KikuPickerMenu({
|
|
|
1286
1503
|
onDismiss();
|
|
1287
1504
|
},
|
|
1288
1505
|
children: [
|
|
1289
|
-
/* @__PURE__ */
|
|
1290
|
-
/* @__PURE__ */
|
|
1506
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-icon", children: /* @__PURE__ */ jsx8(HistoryIcon, {}) }),
|
|
1507
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-item-name", children: "What have you saved?" })
|
|
1291
1508
|
]
|
|
1292
1509
|
}
|
|
1293
1510
|
),
|
|
1294
|
-
/* @__PURE__ */
|
|
1511
|
+
/* @__PURE__ */ jsxs7(
|
|
1295
1512
|
"button",
|
|
1296
1513
|
{
|
|
1297
1514
|
className: "hsk-kiku-picker-item",
|
|
@@ -1301,8 +1518,8 @@ function KikuPickerMenu({
|
|
|
1301
1518
|
onDismiss();
|
|
1302
1519
|
},
|
|
1303
1520
|
children: [
|
|
1304
|
-
/* @__PURE__ */
|
|
1305
|
-
/* @__PURE__ */
|
|
1521
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-icon", children: /* @__PURE__ */ jsx8(TrashIcon, {}) }),
|
|
1522
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-item-name", children: "Delete this" })
|
|
1306
1523
|
]
|
|
1307
1524
|
}
|
|
1308
1525
|
)
|
|
@@ -1311,22 +1528,22 @@ function KikuPickerMenu({
|
|
|
1311
1528
|
);
|
|
1312
1529
|
}
|
|
1313
1530
|
function AtPickerMenu({ onSelect, onDismiss }) {
|
|
1314
|
-
return /* @__PURE__ */
|
|
1531
|
+
return /* @__PURE__ */ jsx8(
|
|
1315
1532
|
"div",
|
|
1316
1533
|
{
|
|
1317
1534
|
className: "hsk-kiku-picker",
|
|
1318
1535
|
role: "menu",
|
|
1319
1536
|
"aria-label": "Extensions",
|
|
1320
1537
|
onMouseDown: (e) => e.preventDefault(),
|
|
1321
|
-
children: /* @__PURE__ */
|
|
1538
|
+
children: /* @__PURE__ */ jsxs7(
|
|
1322
1539
|
"button",
|
|
1323
1540
|
{
|
|
1324
1541
|
className: "hsk-kiku-picker-item",
|
|
1325
1542
|
role: "menuitem",
|
|
1326
1543
|
onClick: () => onSelect("@kiku"),
|
|
1327
1544
|
children: [
|
|
1328
|
-
/* @__PURE__ */
|
|
1329
|
-
/* @__PURE__ */
|
|
1545
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-icon hsk-kiku-picker-icon--accent", children: /* @__PURE__ */ jsx8(SparkleIcon2, {}) }),
|
|
1546
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-picker-item-name", children: "kiku \u2014 capture & remember" })
|
|
1330
1547
|
]
|
|
1331
1548
|
}
|
|
1332
1549
|
)
|
|
@@ -1334,11 +1551,11 @@ function AtPickerMenu({ onSelect, onDismiss }) {
|
|
|
1334
1551
|
);
|
|
1335
1552
|
}
|
|
1336
1553
|
function SourceImg({ src, alt, onImageClick }) {
|
|
1337
|
-
const [failed, setFailed] =
|
|
1554
|
+
const [failed, setFailed] = useState6(false);
|
|
1338
1555
|
if (failed) {
|
|
1339
|
-
return /* @__PURE__ */
|
|
1556
|
+
return /* @__PURE__ */ jsx8("div", { style: { width: "100%", height: "100%", display: "flex", alignItems: "center", justifyContent: "center", background: "var(--hsk-chat-source-bg, rgba(0,0,0,.04))", color: "var(--hsk-chat-muted, #888)" }, children: /* @__PURE__ */ jsx8(SparkleIcon2, {}) });
|
|
1340
1557
|
}
|
|
1341
|
-
return /* @__PURE__ */
|
|
1558
|
+
return /* @__PURE__ */ jsx8(
|
|
1342
1559
|
"img",
|
|
1343
1560
|
{
|
|
1344
1561
|
src,
|
|
@@ -1354,15 +1571,15 @@ function SourceImg({ src, alt, onImageClick }) {
|
|
|
1354
1571
|
function SourcesCarousel({ sources, defaultCurrency, onSelectSource, onImageClick, referencedIds = [], compact = false }) {
|
|
1355
1572
|
const client = useAkropolysContext3();
|
|
1356
1573
|
const isProperty = client?.vertical === "property";
|
|
1357
|
-
const railRef =
|
|
1358
|
-
const [showNext, setShowNext] =
|
|
1574
|
+
const railRef = useRef6(null);
|
|
1575
|
+
const [showNext, setShowNext] = useState6(false);
|
|
1359
1576
|
const measure = useCallback2(() => {
|
|
1360
1577
|
const el = railRef.current;
|
|
1361
1578
|
if (!el) return;
|
|
1362
1579
|
const atEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 8;
|
|
1363
1580
|
setShowNext(el.scrollWidth > el.clientWidth + 4 && !atEnd);
|
|
1364
1581
|
}, []);
|
|
1365
|
-
|
|
1582
|
+
useEffect4(() => {
|
|
1366
1583
|
measure();
|
|
1367
1584
|
const el = railRef.current;
|
|
1368
1585
|
if (!el) return;
|
|
@@ -1379,20 +1596,20 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource, onImageClic
|
|
|
1379
1596
|
};
|
|
1380
1597
|
const display = sources.filter((s) => s.id && referencedIds.includes(s.id));
|
|
1381
1598
|
if (display.length === 0) return null;
|
|
1382
|
-
return /* @__PURE__ */
|
|
1383
|
-
/* @__PURE__ */
|
|
1599
|
+
return /* @__PURE__ */ jsxs7("div", { className: cn("hsk-cb-sources-wrap", compact && "hsk-cb-sources-wrap--compact"), children: [
|
|
1600
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-sources", ref: railRef, children: display.map((src, si) => {
|
|
1384
1601
|
const isReferenced = !!(src.id && referencedIds.includes(src.id));
|
|
1385
|
-
return /* @__PURE__ */
|
|
1602
|
+
return /* @__PURE__ */ jsxs7(
|
|
1386
1603
|
"div",
|
|
1387
1604
|
{
|
|
1388
1605
|
className: cn("hsk-cb-source", isReferenced && "hsk-cb-source--referenced"),
|
|
1389
1606
|
style: { animationDelay: `${si * 50}ms` },
|
|
1390
1607
|
onClick: () => onSelectSource?.(src),
|
|
1391
1608
|
children: [
|
|
1392
|
-
src.image ? /* @__PURE__ */
|
|
1393
|
-
/* @__PURE__ */
|
|
1394
|
-
isReferenced && /* @__PURE__ */
|
|
1395
|
-
isProperty && /* @__PURE__ */
|
|
1609
|
+
src.image ? /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-src-imgwrap", style: { position: "relative" }, children: [
|
|
1610
|
+
/* @__PURE__ */ jsx8(SourceImg, { src: src.image, alt: src.name, onImageClick }),
|
|
1611
|
+
isReferenced && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-source-ref-badge", title: "Featured in response", children: /* @__PURE__ */ jsx8(SparkleIcon2, { size: 10 }) }),
|
|
1612
|
+
isProperty && /* @__PURE__ */ jsx8("div", { style: {
|
|
1396
1613
|
position: "absolute",
|
|
1397
1614
|
top: "6px",
|
|
1398
1615
|
right: "6px",
|
|
@@ -1407,14 +1624,14 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource, onImageClic
|
|
|
1407
1624
|
color: "#fbbf24",
|
|
1408
1625
|
// Gold sparkle badge
|
|
1409
1626
|
boxShadow: "0 2px 4px rgba(0,0,0,0.2)"
|
|
1410
|
-
}, children: /* @__PURE__ */
|
|
1411
|
-
] }) : /* @__PURE__ */
|
|
1412
|
-
/* @__PURE__ */
|
|
1413
|
-
isReferenced && /* @__PURE__ */
|
|
1627
|
+
}, children: /* @__PURE__ */ jsx8(SparkleIcon2, { size: 12 }) })
|
|
1628
|
+
] }) : /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-src-imgwrap-empty", style: { position: "relative" }, children: [
|
|
1629
|
+
/* @__PURE__ */ jsx8(SparkleIcon2, {}),
|
|
1630
|
+
isReferenced && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-source-ref-badge", title: "Featured in response", children: /* @__PURE__ */ jsx8(SparkleIcon2, { size: 10 }) })
|
|
1414
1631
|
] }),
|
|
1415
|
-
/* @__PURE__ */
|
|
1416
|
-
/* @__PURE__ */
|
|
1417
|
-
src.price && /* @__PURE__ */
|
|
1632
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-src-info", children: [
|
|
1633
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-src-name", children: src.name }),
|
|
1634
|
+
src.price && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-src-price", children: [
|
|
1418
1635
|
src.currency ?? defaultCurrency,
|
|
1419
1636
|
" ",
|
|
1420
1637
|
parseFloat(String(src.price).replace(/[^0-9.]/g, "") || "0").toLocaleString()
|
|
@@ -1425,15 +1642,15 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource, onImageClic
|
|
|
1425
1642
|
src.id ?? si
|
|
1426
1643
|
);
|
|
1427
1644
|
}) }),
|
|
1428
|
-
showNext && /* @__PURE__ */
|
|
1429
|
-
/* @__PURE__ */
|
|
1645
|
+
showNext && /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
1646
|
+
/* @__PURE__ */ jsx8(
|
|
1430
1647
|
"div",
|
|
1431
1648
|
{
|
|
1432
1649
|
className: "hsk-cb-sources-fade",
|
|
1433
1650
|
style: { background: "linear-gradient(to right, transparent, var(--hsk-fade-bg, #0e0e0f))" }
|
|
1434
1651
|
}
|
|
1435
1652
|
),
|
|
1436
|
-
/* @__PURE__ */
|
|
1653
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-cb-sources-next", onClick: scrollNext, "aria-label": "See more", children: /* @__PURE__ */ jsx8(ChevronRightIcon, {}) })
|
|
1437
1654
|
] })
|
|
1438
1655
|
] });
|
|
1439
1656
|
}
|
|
@@ -1510,14 +1727,14 @@ function SmartContextPills({
|
|
|
1510
1727
|
pills.push({ emoji: "\u{1F4A1}", label: "Recommend something", query: "What do you recommend for me?" });
|
|
1511
1728
|
}
|
|
1512
1729
|
if (pills.length === 0) return null;
|
|
1513
|
-
return /* @__PURE__ */
|
|
1730
|
+
return /* @__PURE__ */ jsx8("div", { className: "hsk-action-pills", children: pills.map((pill) => /* @__PURE__ */ jsxs7(
|
|
1514
1731
|
"button",
|
|
1515
1732
|
{
|
|
1516
1733
|
className: "hsk-action-pill",
|
|
1517
1734
|
onClick: () => onSend(pill.query),
|
|
1518
1735
|
disabled: loading,
|
|
1519
1736
|
children: [
|
|
1520
|
-
/* @__PURE__ */
|
|
1737
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-pill-emoji", children: pill.emoji }),
|
|
1521
1738
|
pill.label
|
|
1522
1739
|
]
|
|
1523
1740
|
},
|
|
@@ -1578,10 +1795,10 @@ function parseThinking(text) {
|
|
|
1578
1795
|
};
|
|
1579
1796
|
}
|
|
1580
1797
|
function ThinkingBlock({ text, isComplete, seconds: fixedSeconds }) {
|
|
1581
|
-
const startRef =
|
|
1582
|
-
const [seconds, setSeconds] =
|
|
1583
|
-
const [isOpen, setIsOpen] =
|
|
1584
|
-
|
|
1798
|
+
const startRef = useRef6(Date.now());
|
|
1799
|
+
const [seconds, setSeconds] = useState6(() => isComplete ? null : 0);
|
|
1800
|
+
const [isOpen, setIsOpen] = useState6(!isComplete);
|
|
1801
|
+
useEffect4(() => {
|
|
1585
1802
|
if (isComplete) {
|
|
1586
1803
|
if (seconds !== null) {
|
|
1587
1804
|
setSeconds(Math.max(1, Math.round((Date.now() - startRef.current) / 1e3)));
|
|
@@ -1598,8 +1815,8 @@ function ThinkingBlock({ text, isComplete, seconds: fixedSeconds }) {
|
|
|
1598
1815
|
const finalSeconds = fixedSeconds ?? seconds;
|
|
1599
1816
|
const label = isComplete ? finalSeconds !== null && finalSeconds !== void 0 ? `Thought for ${finalSeconds}s` : "Thought process" : `Thinking${seconds ? ` \xB7 ${seconds}s` : "\u2026"}`;
|
|
1600
1817
|
const expandable = !!text;
|
|
1601
|
-
return /* @__PURE__ */
|
|
1602
|
-
/* @__PURE__ */
|
|
1818
|
+
return /* @__PURE__ */ jsxs7("div", { className: cn("hsk-cb-think", !isComplete && "hsk-cb-think--live"), children: [
|
|
1819
|
+
/* @__PURE__ */ jsxs7(
|
|
1603
1820
|
"button",
|
|
1604
1821
|
{
|
|
1605
1822
|
type: "button",
|
|
@@ -1607,20 +1824,20 @@ function ThinkingBlock({ text, isComplete, seconds: fixedSeconds }) {
|
|
|
1607
1824
|
onClick: expandable ? () => setIsOpen((o) => !o) : void 0,
|
|
1608
1825
|
"aria-expanded": expandable ? isOpen : void 0,
|
|
1609
1826
|
children: [
|
|
1610
|
-
isComplete ? /* @__PURE__ */
|
|
1611
|
-
/* @__PURE__ */
|
|
1612
|
-
/* @__PURE__ */
|
|
1613
|
-
] }) : /* @__PURE__ */
|
|
1614
|
-
/* @__PURE__ */
|
|
1615
|
-
/* @__PURE__ */
|
|
1616
|
-
/* @__PURE__ */
|
|
1827
|
+
isComplete ? /* @__PURE__ */ jsxs7("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
1828
|
+
/* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "10" }),
|
|
1829
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 6v6l4 2" })
|
|
1830
|
+
] }) : /* @__PURE__ */ jsxs7("span", { className: "hsk-cb-typing", "aria-hidden": "true", children: [
|
|
1831
|
+
/* @__PURE__ */ jsx8("span", {}),
|
|
1832
|
+
/* @__PURE__ */ jsx8("span", {}),
|
|
1833
|
+
/* @__PURE__ */ jsx8("span", {})
|
|
1617
1834
|
] }),
|
|
1618
|
-
/* @__PURE__ */
|
|
1619
|
-
expandable && /* @__PURE__ */
|
|
1835
|
+
/* @__PURE__ */ jsx8("span", { children: label }),
|
|
1836
|
+
expandable && /* @__PURE__ */ jsx8("span", { className: cn("hsk-cb-think-chevron", isOpen && "hsk-cb-think-chevron--open"), children: "\u25B6" })
|
|
1620
1837
|
]
|
|
1621
1838
|
}
|
|
1622
1839
|
),
|
|
1623
|
-
expandable && isOpen && /* @__PURE__ */
|
|
1840
|
+
expandable && isOpen && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-think-body", children: text })
|
|
1624
1841
|
] });
|
|
1625
1842
|
}
|
|
1626
1843
|
function ChatModal({
|
|
@@ -1641,18 +1858,18 @@ function ChatModal({
|
|
|
1641
1858
|
}) {
|
|
1642
1859
|
const client = useAkropolysContext3();
|
|
1643
1860
|
const { messages, sources, loading, streaming, error, lastAction, lastIntent, send, stop, stopped, interrupted, continueGenerating, reset, referencedIds } = useKiku2();
|
|
1644
|
-
const [input, setInput] =
|
|
1645
|
-
const [shopperName, setShopperNameState] =
|
|
1861
|
+
const [input, setInput] = useState6("");
|
|
1862
|
+
const [shopperName, setShopperNameState] = useState6(() => {
|
|
1646
1863
|
try {
|
|
1647
1864
|
return client.getShopperName?.() ?? "";
|
|
1648
1865
|
} catch {
|
|
1649
1866
|
return "";
|
|
1650
1867
|
}
|
|
1651
1868
|
});
|
|
1652
|
-
const [nameSkipped, setNameSkipped] =
|
|
1869
|
+
const [nameSkipped, setNameSkipped] = useState6(false);
|
|
1653
1870
|
const awaitingName = messages.length === 0 && !shopperName && !nameSkipped;
|
|
1654
|
-
const [attachments, setAttachments] =
|
|
1655
|
-
const imageInputRef =
|
|
1871
|
+
const [attachments, setAttachments] = useState6([]);
|
|
1872
|
+
const imageInputRef = useRef6(null);
|
|
1656
1873
|
const handleImageFiles = (files) => {
|
|
1657
1874
|
if (!files || files.length === 0) return;
|
|
1658
1875
|
Array.from(files).forEach((file) => {
|
|
@@ -1670,9 +1887,9 @@ function ChatModal({
|
|
|
1670
1887
|
const removeAttachment = (idx) => {
|
|
1671
1888
|
setAttachments((prev) => prev.filter((_, i) => i !== idx));
|
|
1672
1889
|
};
|
|
1673
|
-
const [voiceState, setVoiceState] =
|
|
1674
|
-
const recognitionRef =
|
|
1675
|
-
const pendingVoiceRef =
|
|
1890
|
+
const [voiceState, setVoiceState] = useState6("idle");
|
|
1891
|
+
const recognitionRef = useRef6(null);
|
|
1892
|
+
const pendingVoiceRef = useRef6(null);
|
|
1676
1893
|
const hasSpeechAPI = typeof window !== "undefined" && ("SpeechRecognition" in window || "webkitSpeechRecognition" in window);
|
|
1677
1894
|
const startVoice = useCallback2(() => {
|
|
1678
1895
|
if (!hasSpeechAPI || voiceState !== "idle") return;
|
|
@@ -1716,21 +1933,22 @@ function ChatModal({
|
|
|
1716
1933
|
recognitionRef.current?.stop();
|
|
1717
1934
|
setVoiceState("idle");
|
|
1718
1935
|
}, []);
|
|
1719
|
-
|
|
1936
|
+
useEffect4(() => {
|
|
1720
1937
|
return () => recognitionRef.current?.abort();
|
|
1721
1938
|
}, []);
|
|
1722
1939
|
const activeChips = chips;
|
|
1723
1940
|
const activeTitle = title;
|
|
1724
1941
|
const activePlaceholder = awaitingName ? "Type your name\u2026" : placeholder;
|
|
1725
|
-
const [selectedProduct, setSelectedProduct] =
|
|
1726
|
-
const [lightboxSrc, setLightboxSrc] =
|
|
1727
|
-
const
|
|
1728
|
-
const
|
|
1729
|
-
const
|
|
1730
|
-
const [
|
|
1731
|
-
const [
|
|
1732
|
-
const [
|
|
1733
|
-
const [
|
|
1942
|
+
const [selectedProduct, setSelectedProduct] = useState6(null);
|
|
1943
|
+
const [lightboxSrc, setLightboxSrc] = useState6(null);
|
|
1944
|
+
const [markupSrc, setMarkupSrc] = useState6(null);
|
|
1945
|
+
const bottomRef = useRef6(null);
|
|
1946
|
+
const textareaRef = useRef6(null);
|
|
1947
|
+
const [keyInput, setKeyInput] = useState6("");
|
|
1948
|
+
const [keyPhase, setKeyPhase] = useState6("idle");
|
|
1949
|
+
const [mintedKey, setMintedKey] = useState6(null);
|
|
1950
|
+
const [mintedPub, setMintedPub] = useState6(null);
|
|
1951
|
+
const [copied, setCopied] = useState6(null);
|
|
1734
1952
|
const copyValue = (value, which) => {
|
|
1735
1953
|
try {
|
|
1736
1954
|
navigator.clipboard?.writeText(value);
|
|
@@ -1739,17 +1957,17 @@ function ChatModal({
|
|
|
1739
1957
|
setCopied(which);
|
|
1740
1958
|
setTimeout(() => setCopied((c) => c === which ? null : c), 1600);
|
|
1741
1959
|
};
|
|
1742
|
-
const [keyCountdown, setKeyCountdown] =
|
|
1743
|
-
const [minting, setMinting] =
|
|
1744
|
-
const [showKikuPicker, setShowKikuPicker] =
|
|
1745
|
-
const [showAtPicker, setShowAtPicker] =
|
|
1746
|
-
|
|
1960
|
+
const [keyCountdown, setKeyCountdown] = useState6(KIKU_KEY_REVEAL_SECONDS);
|
|
1961
|
+
const [minting, setMinting] = useState6(false);
|
|
1962
|
+
const [showKikuPicker, setShowKikuPicker] = useState6(false);
|
|
1963
|
+
const [showAtPicker, setShowAtPicker] = useState6(false);
|
|
1964
|
+
useEffect4(() => {
|
|
1747
1965
|
if (!lastAction) return;
|
|
1748
1966
|
if (lastAction.type === "request_kiku_key") {
|
|
1749
1967
|
setKeyPhase("prompt_key");
|
|
1750
1968
|
}
|
|
1751
1969
|
}, [lastAction]);
|
|
1752
|
-
|
|
1970
|
+
useEffect4(() => {
|
|
1753
1971
|
if (!mintedKey) return;
|
|
1754
1972
|
setKeyCountdown(KIKU_KEY_REVEAL_SECONDS);
|
|
1755
1973
|
const t = setInterval(() => {
|
|
@@ -1800,9 +2018,9 @@ function ChatModal({
|
|
|
1800
2018
|
setMinting(false);
|
|
1801
2019
|
}
|
|
1802
2020
|
};
|
|
1803
|
-
const msgsContainerRef =
|
|
1804
|
-
const messageRefs =
|
|
1805
|
-
|
|
2021
|
+
const msgsContainerRef = useRef6(null);
|
|
2022
|
+
const messageRefs = useRef6([]);
|
|
2023
|
+
useEffect4(() => {
|
|
1806
2024
|
const container = msgsContainerRef.current;
|
|
1807
2025
|
if (!container) return;
|
|
1808
2026
|
const lastMsg = messages[messages.length - 1];
|
|
@@ -1815,14 +2033,14 @@ function ChatModal({
|
|
|
1815
2033
|
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
1816
2034
|
}
|
|
1817
2035
|
}, [messages, loading, selectedProduct]);
|
|
1818
|
-
|
|
2036
|
+
useEffect4(() => {
|
|
1819
2037
|
const prev = document.body.style.overflow;
|
|
1820
2038
|
document.body.style.overflow = "hidden";
|
|
1821
2039
|
return () => {
|
|
1822
2040
|
document.body.style.overflow = prev;
|
|
1823
2041
|
};
|
|
1824
2042
|
}, []);
|
|
1825
|
-
|
|
2043
|
+
useEffect4(() => {
|
|
1826
2044
|
const h = (e) => {
|
|
1827
2045
|
if (e.key !== "Escape") return;
|
|
1828
2046
|
if (lightboxSrc) {
|
|
@@ -1953,7 +2171,7 @@ function ChatModal({
|
|
|
1953
2171
|
t.style.height = "auto";
|
|
1954
2172
|
t.style.height = `${Math.min(t.scrollHeight, 140)}px`;
|
|
1955
2173
|
};
|
|
1956
|
-
|
|
2174
|
+
useEffect4(() => {
|
|
1957
2175
|
if (voiceState !== "processing") return;
|
|
1958
2176
|
const transcript = pendingVoiceRef.current;
|
|
1959
2177
|
if (!transcript) {
|
|
@@ -1969,7 +2187,7 @@ function ChatModal({
|
|
|
1969
2187
|
}, [voiceState]);
|
|
1970
2188
|
const blurVal = typeof backdropBlur === "number" ? `${backdropBlur}px` : backdropBlur ?? "20px";
|
|
1971
2189
|
const displayMessages = messages;
|
|
1972
|
-
return /* @__PURE__ */
|
|
2190
|
+
return /* @__PURE__ */ jsx8(
|
|
1973
2191
|
"div",
|
|
1974
2192
|
{
|
|
1975
2193
|
className: cn("hsk-cb-overlay", classNames.overlay),
|
|
@@ -1981,7 +2199,7 @@ function ChatModal({
|
|
|
1981
2199
|
...backdropColor ? { background: backdropColor } : {},
|
|
1982
2200
|
...customStyles
|
|
1983
2201
|
},
|
|
1984
|
-
children: /* @__PURE__ */
|
|
2202
|
+
children: /* @__PURE__ */ jsxs7(
|
|
1985
2203
|
"div",
|
|
1986
2204
|
{
|
|
1987
2205
|
className: cn("hsk-cb-panel", classNames.panel),
|
|
@@ -1994,48 +2212,62 @@ function ChatModal({
|
|
|
1994
2212
|
}
|
|
1995
2213
|
},
|
|
1996
2214
|
children: [
|
|
1997
|
-
lightboxSrc && /* @__PURE__ */
|
|
1998
|
-
/* @__PURE__ */
|
|
1999
|
-
/* @__PURE__ */
|
|
2215
|
+
lightboxSrc && /* @__PURE__ */ jsxs7("div", { className: "hsk-lightbox", onClick: () => setLightboxSrc(null), children: [
|
|
2216
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-lightbox-close", onClick: () => setLightboxSrc(null), "aria-label": "Close image", children: /* @__PURE__ */ jsx8(CloseIcon, {}) }),
|
|
2217
|
+
/* @__PURE__ */ jsx8("img", { src: lightboxSrc, alt: "", className: "hsk-lightbox-img", onClick: (e) => e.stopPropagation() })
|
|
2000
2218
|
] }),
|
|
2001
|
-
/* @__PURE__ */
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2219
|
+
markupSrc && /* @__PURE__ */ jsx8("div", { className: "hsk-markup-overlay", children: /* @__PURE__ */ jsx8(
|
|
2220
|
+
MarkupEditor,
|
|
2221
|
+
{
|
|
2222
|
+
src: markupSrc,
|
|
2223
|
+
onCancel: () => setMarkupSrc(null),
|
|
2224
|
+
onSend: (dataUrl, instruction) => {
|
|
2225
|
+
setMarkupSrc(null);
|
|
2226
|
+
handleSend(
|
|
2227
|
+
instruction || "Apply the change indicated by the markings on the image.",
|
|
2228
|
+
[{ type: "image", data: dataUrl, annotated: true }]
|
|
2229
|
+
);
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
) }),
|
|
2233
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-main", children: [
|
|
2234
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-topbar", children: [
|
|
2235
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-topbar-left", children: [
|
|
2236
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-cb-topbar-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon2, {}) }),
|
|
2237
|
+
/* @__PURE__ */ jsx8("div", { children: /* @__PURE__ */ jsx8("div", { className: "hsk-cb-topbar-title", children: activeTitle }) })
|
|
2006
2238
|
] }),
|
|
2007
|
-
/* @__PURE__ */
|
|
2008
|
-
messages.length > 0 && /* @__PURE__ */
|
|
2009
|
-
/* @__PURE__ */
|
|
2239
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-topbar-actions", children: [
|
|
2240
|
+
messages.length > 0 && /* @__PURE__ */ jsx8("button", { className: "hsk-cb-topbar-btn", onClick: handleReset, children: "Clear chat" }),
|
|
2241
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-cb-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx8(CloseIcon, {}) })
|
|
2010
2242
|
] })
|
|
2011
2243
|
] }),
|
|
2012
|
-
/* @__PURE__ */
|
|
2013
|
-
displayMessages.length === 0 ? /* @__PURE__ */
|
|
2014
|
-
awaitingName ? /* @__PURE__ */
|
|
2015
|
-
/* @__PURE__ */
|
|
2244
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-msgs", ref: msgsContainerRef, children: [
|
|
2245
|
+
displayMessages.length === 0 ? /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-empty", children: [
|
|
2246
|
+
awaitingName ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2247
|
+
/* @__PURE__ */ jsxs7("h2", { className: "hsk-cb-hello", children: [
|
|
2016
2248
|
"Hi, I'm ",
|
|
2017
|
-
/* @__PURE__ */
|
|
2249
|
+
/* @__PURE__ */ jsx8("b", { children: "kiku" }),
|
|
2018
2250
|
"."
|
|
2019
2251
|
] }),
|
|
2020
|
-
/* @__PURE__ */
|
|
2021
|
-
/* @__PURE__ */
|
|
2022
|
-
/* @__PURE__ */
|
|
2023
|
-
] }) : shopperName ? /* @__PURE__ */
|
|
2024
|
-
/* @__PURE__ */
|
|
2252
|
+
/* @__PURE__ */ jsx8("p", { className: "hsk-cb-hello-lead", children: "I can search, visualize, or capture anything for you \u2014 on this site or any other." }),
|
|
2253
|
+
/* @__PURE__ */ jsx8("p", { className: "hsk-cb-hello-ask", children: "What should I call you?" }),
|
|
2254
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-cb-hello-skip", onClick: () => setNameSkipped(true), children: "Skip for now" })
|
|
2255
|
+
] }) : shopperName ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2256
|
+
/* @__PURE__ */ jsxs7("h2", { className: "hsk-cb-hello", children: [
|
|
2025
2257
|
"Hi, ",
|
|
2026
2258
|
shopperName,
|
|
2027
2259
|
"."
|
|
2028
2260
|
] }),
|
|
2029
|
-
/* @__PURE__ */
|
|
2030
|
-
] }) : /* @__PURE__ */
|
|
2031
|
-
/* @__PURE__ */
|
|
2261
|
+
/* @__PURE__ */ jsx8("p", { className: "hsk-cb-hello-lead", children: "What can I find for you today?" })
|
|
2262
|
+
] }) : /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2263
|
+
/* @__PURE__ */ jsxs7("h2", { className: "hsk-cb-hello", children: [
|
|
2032
2264
|
"Hi, I'm ",
|
|
2033
|
-
/* @__PURE__ */
|
|
2265
|
+
/* @__PURE__ */ jsx8("b", { children: "kiku" }),
|
|
2034
2266
|
"."
|
|
2035
2267
|
] }),
|
|
2036
|
-
/* @__PURE__ */
|
|
2268
|
+
/* @__PURE__ */ jsx8("p", { className: "hsk-cb-hello-lead", children: "Ask me to search, visualize, or capture anything \u2014 I look across the whole site in real time." })
|
|
2037
2269
|
] }),
|
|
2038
|
-
!awaitingName && activeChips.length > 0 && /* @__PURE__ */
|
|
2270
|
+
!awaitingName && activeChips.length > 0 && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-chips", children: activeChips.map((chip) => /* @__PURE__ */ jsx8(
|
|
2039
2271
|
"button",
|
|
2040
2272
|
{
|
|
2041
2273
|
className: "hsk-cb-chip",
|
|
@@ -2051,50 +2283,59 @@ function ChatModal({
|
|
|
2051
2283
|
const compareSources = sources.filter((s) => s.id && referencedIds.includes(s.id));
|
|
2052
2284
|
const showMatrix = isLast && lastIntent === "compare" && compareSources.length >= 2;
|
|
2053
2285
|
const displayContent = !isUser && showMatrix ? stripMarkdownTables(msg.content) : msg.content;
|
|
2054
|
-
return /* @__PURE__ */
|
|
2286
|
+
return /* @__PURE__ */ jsx8("div", { className: "hsk-cb-msg-group", ref: (el) => {
|
|
2055
2287
|
messageRefs.current[idx] = el;
|
|
2056
|
-
}, children: isUser ? /* @__PURE__ */
|
|
2057
|
-
msg.images && msg.images.length > 0 && /* @__PURE__ */
|
|
2058
|
-
msg.content && /* @__PURE__ */
|
|
2059
|
-
/* @__PURE__ */
|
|
2288
|
+
}, children: isUser ? /* @__PURE__ */ jsxs7("div", { className: `hsk-cb-user-msg${isLastUser ? " hsk-sent" : ""}`, children: [
|
|
2289
|
+
msg.images && msg.images.length > 0 && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-user-imgs", children: msg.images.map((img, i) => /* @__PURE__ */ jsx8("img", { src: img, alt: `attachment ${i + 1}`, className: "hsk-cb-user-img-thumb" }, i)) }),
|
|
2290
|
+
msg.content && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-user-bubble", children: /^@kiku\b/i.test(msg.content) ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2291
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-kiku-badge", children: "@kiku" }),
|
|
2060
2292
|
msg.content.replace(/^@kiku\s*/i, "")
|
|
2061
2293
|
] }) : msg.content })
|
|
2062
|
-
] }) : /* @__PURE__ */
|
|
2063
|
-
/* @__PURE__ */
|
|
2064
|
-
/* @__PURE__ */
|
|
2294
|
+
] }) : /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-ai-msg", children: [
|
|
2295
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon2, {}) }),
|
|
2296
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-ai-body", children: [
|
|
2065
2297
|
(() => {
|
|
2066
2298
|
const parsed = parseThinking(displayContent);
|
|
2067
2299
|
const thinking = msg.thinking || parsed.thinking;
|
|
2068
2300
|
const content = parsed.content;
|
|
2069
2301
|
const isComplete = msg.thinking ? content.length > 0 || !(isLast && streaming) : parsed.isComplete;
|
|
2070
|
-
return /* @__PURE__ */
|
|
2071
|
-
(thinking || msg.thoughtForSeconds != null) && /* @__PURE__ */
|
|
2072
|
-
content && /* @__PURE__ */
|
|
2302
|
+
return /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2303
|
+
(thinking || msg.thoughtForSeconds != null) && /* @__PURE__ */ jsx8(ThinkingBlock, { text: thinking, isComplete, seconds: msg.thoughtForSeconds }),
|
|
2304
|
+
content && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-ai-text", children: [
|
|
2073
2305
|
renderMarkdown(content, isLast && streaming),
|
|
2074
|
-
isLast && streaming && /* @__PURE__ */
|
|
2306
|
+
isLast && streaming && /* @__PURE__ */ jsx8("span", { style: { display: "inline-block", width: "0.5em", height: "1.05em", marginLeft: "2px", verticalAlign: "text-bottom", background: "currentColor", opacity: 0.55, borderRadius: "1px" } })
|
|
2075
2307
|
] })
|
|
2076
2308
|
] });
|
|
2077
2309
|
})(),
|
|
2078
|
-
msg.visualizing && /* @__PURE__ */
|
|
2079
|
-
/* @__PURE__ */
|
|
2080
|
-
/* @__PURE__ */
|
|
2310
|
+
msg.visualizing && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-viz hsk-cb-viz--loading", children: [
|
|
2311
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-cb-viz-spinner" }),
|
|
2312
|
+
/* @__PURE__ */ jsx8("span", { children: "Visualizing\u2026" })
|
|
2081
2313
|
] }),
|
|
2082
|
-
msg.visualization && /* @__PURE__ */
|
|
2083
|
-
/* @__PURE__ */
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
e
|
|
2314
|
+
msg.visualization && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-viz", children: [
|
|
2315
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-viz-imgwrap", children: [
|
|
2316
|
+
/* @__PURE__ */ jsx8(
|
|
2317
|
+
"img",
|
|
2318
|
+
{
|
|
2319
|
+
src: msg.visualization,
|
|
2320
|
+
alt: "Product visualized in your photo",
|
|
2321
|
+
className: "hsk-markdown-img",
|
|
2322
|
+
onError: (e) => {
|
|
2323
|
+
e.target.style.display = "none";
|
|
2324
|
+
}
|
|
2091
2325
|
}
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2326
|
+
),
|
|
2327
|
+
isLast && !streaming && /* @__PURE__ */ jsxs7("button", { className: "hsk-cb-viz-mark", onClick: () => setMarkupSrc(msg.visualization), children: [
|
|
2328
|
+
/* @__PURE__ */ jsxs7("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
2329
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 20h9" }),
|
|
2330
|
+
/* @__PURE__ */ jsx8("path", { d: "M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4Z" })
|
|
2331
|
+
] }),
|
|
2332
|
+
"Mark & edit"
|
|
2333
|
+
] })
|
|
2334
|
+
] }),
|
|
2335
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-viz-disclaimer", children: "AI-generated preview \u2014 colours, size and placement may differ from the real product." })
|
|
2095
2336
|
] }),
|
|
2096
|
-
!isUser && (msg.knowledgeImages?.length ?? 0) > 0 && /* @__PURE__ */
|
|
2097
|
-
/* @__PURE__ */
|
|
2337
|
+
!isUser && (msg.knowledgeImages?.length ?? 0) > 0 && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-kimgs", children: msg.knowledgeImages.map((ref) => /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-kimg-group", children: [
|
|
2338
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-kimg-grid", children: ref.images.map((img, i) => /* @__PURE__ */ jsx8(
|
|
2098
2339
|
"img",
|
|
2099
2340
|
{
|
|
2100
2341
|
src: img.url,
|
|
@@ -2108,16 +2349,16 @@ function ChatModal({
|
|
|
2108
2349
|
},
|
|
2109
2350
|
i
|
|
2110
2351
|
)) }),
|
|
2111
|
-
(ref.title || ref.images[0]?.note) && /* @__PURE__ */
|
|
2352
|
+
(ref.title || ref.images[0]?.note) && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-kimg-caption", children: ref.title || ref.images[0]?.note })
|
|
2112
2353
|
] }, ref.entryId)) }),
|
|
2113
|
-
showMatrix && /* @__PURE__ */
|
|
2354
|
+
showMatrix && /* @__PURE__ */ jsx8(ComparisonMatrix, { sources: compareSources, defaultCurrency }),
|
|
2114
2355
|
(() => {
|
|
2115
2356
|
const msgReferencedIds = isLast ? referencedIds : msg.referencedIds ?? [];
|
|
2116
2357
|
const msgSources = isLast ? sources : msg.sources ?? [];
|
|
2117
2358
|
const msgIntent = isLast ? lastIntent : msg.intent;
|
|
2118
2359
|
const hiddenIntent = msgIntent === "compare" || msgIntent === "capture" || msgIntent === "capture_all" || msgIntent === "delete" || msgIntent === "view_history";
|
|
2119
2360
|
const showCarousel = msgReferencedIds.length > 0 && !hiddenIntent && (!isLast || lastAction?.type !== "request_kiku_key");
|
|
2120
|
-
return showCarousel && /* @__PURE__ */
|
|
2361
|
+
return showCarousel && /* @__PURE__ */ jsx8(
|
|
2121
2362
|
SourcesCarousel,
|
|
2122
2363
|
{
|
|
2123
2364
|
sources: msgSources,
|
|
@@ -2129,11 +2370,11 @@ function ChatModal({
|
|
|
2129
2370
|
}
|
|
2130
2371
|
);
|
|
2131
2372
|
})(),
|
|
2132
|
-
isLast && !loading && lastAction?.url && /* @__PURE__ */
|
|
2373
|
+
isLast && !loading && lastAction?.url && /* @__PURE__ */ jsx8("div", { className: "hsk-action-pills", children: /* @__PURE__ */ jsxs7("a", { className: "hsk-action-pill", href: lastAction.url, children: [
|
|
2133
2374
|
String(lastAction.type || "continue").replace(/_/g, " "),
|
|
2134
2375
|
" \u2192"
|
|
2135
2376
|
] }) }),
|
|
2136
|
-
isLast && !loading && /* @__PURE__ */
|
|
2377
|
+
isLast && !loading && /* @__PURE__ */ jsx8(
|
|
2137
2378
|
SmartContextPills,
|
|
2138
2379
|
{
|
|
2139
2380
|
intent: lastIntent,
|
|
@@ -2145,16 +2386,16 @@ function ChatModal({
|
|
|
2145
2386
|
] })
|
|
2146
2387
|
] }) }, idx);
|
|
2147
2388
|
}),
|
|
2148
|
-
selectedProduct && loading && /* @__PURE__ */
|
|
2389
|
+
selectedProduct && loading && /* @__PURE__ */ jsxs7(
|
|
2149
2390
|
"div",
|
|
2150
2391
|
{
|
|
2151
2392
|
className: "hsk-cb-selected-product",
|
|
2152
2393
|
onClick: () => selectedProduct.url && window.open(selectedProduct.url, "_blank"),
|
|
2153
2394
|
children: [
|
|
2154
|
-
selectedProduct.image && /* @__PURE__ */
|
|
2155
|
-
/* @__PURE__ */
|
|
2156
|
-
/* @__PURE__ */
|
|
2157
|
-
selectedProduct.price && /* @__PURE__ */
|
|
2395
|
+
selectedProduct.image && /* @__PURE__ */ jsx8("img", { className: "hsk-cb-selected-img", src: selectedProduct.image, alt: selectedProduct.name }),
|
|
2396
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-selected-info", children: [
|
|
2397
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-selected-name", children: selectedProduct.name }),
|
|
2398
|
+
selectedProduct.price && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-selected-price", children: [
|
|
2158
2399
|
selectedProduct.currency ?? defaultCurrency,
|
|
2159
2400
|
" ",
|
|
2160
2401
|
parseFloat(String(selectedProduct.price ?? "").replace(/[^0-9.]/g, "") || "0").toLocaleString()
|
|
@@ -2163,22 +2404,12 @@ function ChatModal({
|
|
|
2163
2404
|
]
|
|
2164
2405
|
}
|
|
2165
2406
|
),
|
|
2166
|
-
loading && !streaming && /* @__PURE__ */
|
|
2167
|
-
/* @__PURE__ */
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
/* @__PURE__ */ jsx7("span", { className: "hsk-handle-ball" }),
|
|
2173
|
-
/* @__PURE__ */ jsx7("span", { className: "hsk-handle-ball" }),
|
|
2174
|
-
/* @__PURE__ */ jsx7("span", { className: "hsk-handle-ball" }),
|
|
2175
|
-
/* @__PURE__ */ jsx7("span", { className: "hsk-handle-ball" })
|
|
2176
|
-
] }) }),
|
|
2177
|
-
/* @__PURE__ */ jsx7("span", { className: "hsk-handle-rest" })
|
|
2178
|
-
] }),
|
|
2179
|
-
/* @__PURE__ */ jsx7("span", { className: "hsk-cb-thinking-text", children: "Thinking\u2026" })
|
|
2180
|
-
] }),
|
|
2181
|
-
lastAction?.type === "open_memory" && lastAction.url && !loading && !streaming && /* @__PURE__ */ jsxs6(
|
|
2407
|
+
loading && !streaming && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-typing-bubble", "aria-label": "Assistant is typing", children: /* @__PURE__ */ jsxs7("span", { className: "hsk-cb-typing", children: [
|
|
2408
|
+
/* @__PURE__ */ jsx8("span", {}),
|
|
2409
|
+
/* @__PURE__ */ jsx8("span", {}),
|
|
2410
|
+
/* @__PURE__ */ jsx8("span", {})
|
|
2411
|
+
] }) }),
|
|
2412
|
+
lastAction?.type === "open_memory" && lastAction.url && !loading && !streaming && /* @__PURE__ */ jsxs7(
|
|
2182
2413
|
"a",
|
|
2183
2414
|
{
|
|
2184
2415
|
className: "hsk-cb-memory-pill",
|
|
@@ -2187,23 +2418,23 @@ function ChatModal({
|
|
|
2187
2418
|
rel: "noopener noreferrer",
|
|
2188
2419
|
children: [
|
|
2189
2420
|
"Open my memory on mimi",
|
|
2190
|
-
/* @__PURE__ */
|
|
2421
|
+
/* @__PURE__ */ jsx8(ExternalIcon, {})
|
|
2191
2422
|
]
|
|
2192
2423
|
}
|
|
2193
2424
|
),
|
|
2194
|
-
(stopped || interrupted) && !loading && !streaming && messages.length > 0 && /* @__PURE__ */
|
|
2195
|
-
/* @__PURE__ */
|
|
2196
|
-
/* @__PURE__ */
|
|
2197
|
-
/* @__PURE__ */
|
|
2425
|
+
(stopped || interrupted) && !loading && !streaming && messages.length > 0 && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-stopped", children: [
|
|
2426
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-cb-stopped-label", children: stopped ? "You stopped this response." : "This response was interrupted." }),
|
|
2427
|
+
/* @__PURE__ */ jsxs7("button", { className: "hsk-cb-continue", onClick: continueGenerating, children: [
|
|
2428
|
+
/* @__PURE__ */ jsx8(ContinueIcon, {}),
|
|
2198
2429
|
messages[messages.length - 1]?.role === "assistant" ? "Continue generating" : "Generate response"
|
|
2199
2430
|
] })
|
|
2200
2431
|
] }),
|
|
2201
|
-
error && /* @__PURE__ */
|
|
2202
|
-
keyPhase === "prompt_key" && /* @__PURE__ */
|
|
2203
|
-
/* @__PURE__ */
|
|
2204
|
-
/* @__PURE__ */
|
|
2205
|
-
/* @__PURE__ */
|
|
2206
|
-
/* @__PURE__ */
|
|
2432
|
+
error && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-error", children: getFriendlyError(error) }),
|
|
2433
|
+
keyPhase === "prompt_key" && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-ai-msg", children: [
|
|
2434
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon2, {}) }),
|
|
2435
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-body", children: /* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-text", children: /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-phone-form", children: [
|
|
2436
|
+
/* @__PURE__ */ jsx8("label", { className: "hsk-cb-phone-label", children: "Paste your public id \u2014 or create one" }),
|
|
2437
|
+
/* @__PURE__ */ jsx8(
|
|
2207
2438
|
"input",
|
|
2208
2439
|
{
|
|
2209
2440
|
type: "text",
|
|
@@ -2215,49 +2446,49 @@ function ChatModal({
|
|
|
2215
2446
|
autoFocus: true
|
|
2216
2447
|
}
|
|
2217
2448
|
),
|
|
2218
|
-
/* @__PURE__ */
|
|
2219
|
-
/* @__PURE__ */
|
|
2220
|
-
/* @__PURE__ */
|
|
2449
|
+
/* @__PURE__ */ jsxs7("div", { style: { display: "flex", gap: 8 }, children: [
|
|
2450
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-cb-phone-submit", onClick: handleUseExistingKey, disabled: !keyInput.trim(), children: "Use my id" }),
|
|
2451
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-cb-phone-submit", onClick: handleCreateKey, disabled: minting, children: minting ? "Creating\u2026" : "I'm new \u2014 create one" })
|
|
2221
2452
|
] })
|
|
2222
2453
|
] }) }) })
|
|
2223
2454
|
] }),
|
|
2224
|
-
mintedKey && /* @__PURE__ */
|
|
2225
|
-
/* @__PURE__ */
|
|
2226
|
-
/* @__PURE__ */
|
|
2227
|
-
/* @__PURE__ */
|
|
2228
|
-
/* @__PURE__ */
|
|
2229
|
-
/* @__PURE__ */
|
|
2230
|
-
/* @__PURE__ */
|
|
2231
|
-
/* @__PURE__ */
|
|
2232
|
-
/* @__PURE__ */
|
|
2455
|
+
mintedKey && /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-ai-msg", children: [
|
|
2456
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon2, {}) }),
|
|
2457
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-body", children: /* @__PURE__ */ jsx8("div", { className: "hsk-cb-ai-text", children: /* @__PURE__ */ jsxs7("div", { style: { padding: "12px 14px", border: "1px solid var(--hsk-border, #e5e5e5)", borderRadius: "var(--hsk-border-radius, 0px)", display: "flex", flexDirection: "column", gap: 12 }, children: [
|
|
2458
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
2459
|
+
/* @__PURE__ */ jsx8("div", { style: { fontSize: 12, fontWeight: 600, marginBottom: 4 }, children: "Your secret \u2014 shown only once" }),
|
|
2460
|
+
/* @__PURE__ */ jsx8("code", { style: { display: "block", fontSize: 14, fontWeight: 700, marginBottom: 6, wordBreak: "break-all" }, children: mintedKey }),
|
|
2461
|
+
/* @__PURE__ */ jsxs7("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
|
|
2462
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-cb-phone-submit", style: { padding: "4px 10px" }, onClick: () => copyValue(mintedKey, "secret"), children: copied === "secret" ? "Copied" : "Copy secret" }),
|
|
2463
|
+
/* @__PURE__ */ jsx8("span", { style: { fontSize: 11, opacity: 0.7 }, children: "Keep it private \u2014 use it to unlock your memory at mimi.akropolys.cloud. If lost, the memory is lost with it." })
|
|
2233
2464
|
] })
|
|
2234
2465
|
] }),
|
|
2235
|
-
mintedPub && /* @__PURE__ */
|
|
2236
|
-
/* @__PURE__ */
|
|
2237
|
-
/* @__PURE__ */
|
|
2238
|
-
/* @__PURE__ */
|
|
2239
|
-
/* @__PURE__ */
|
|
2240
|
-
/* @__PURE__ */
|
|
2466
|
+
mintedPub && /* @__PURE__ */ jsxs7("div", { children: [
|
|
2467
|
+
/* @__PURE__ */ jsx8("div", { style: { fontSize: 12, fontWeight: 600, marginBottom: 4 }, children: "Your public id" }),
|
|
2468
|
+
/* @__PURE__ */ jsx8("code", { style: { display: "block", fontSize: 13, fontWeight: 600, marginBottom: 6, wordBreak: "break-all", opacity: 0.85 }, children: mintedPub }),
|
|
2469
|
+
/* @__PURE__ */ jsxs7("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
|
|
2470
|
+
/* @__PURE__ */ jsx8("button", { className: "hsk-cb-phone-submit", style: { padding: "4px 10px" }, onClick: () => copyValue(mintedPub, "pub"), children: copied === "pub" ? "Copied" : "Copy id" }),
|
|
2471
|
+
/* @__PURE__ */ jsx8("span", { style: { fontSize: 11, opacity: 0.7 }, children: "Paste this on any site to keep saving to the same memory." })
|
|
2241
2472
|
] })
|
|
2242
2473
|
] }),
|
|
2243
|
-
/* @__PURE__ */
|
|
2474
|
+
/* @__PURE__ */ jsxs7("div", { style: { fontSize: 11, opacity: 0.6 }, children: [
|
|
2244
2475
|
"Hidden in ",
|
|
2245
2476
|
keyCountdown,
|
|
2246
2477
|
"s."
|
|
2247
2478
|
] })
|
|
2248
2479
|
] }) }) })
|
|
2249
2480
|
] }),
|
|
2250
|
-
/* @__PURE__ */
|
|
2481
|
+
/* @__PURE__ */ jsx8("div", { ref: bottomRef, style: { height: 1 } })
|
|
2251
2482
|
] }),
|
|
2252
|
-
/* @__PURE__ */
|
|
2253
|
-
showAtPicker && /* @__PURE__ */
|
|
2483
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-input-wrap", children: [
|
|
2484
|
+
showAtPicker && /* @__PURE__ */ jsx8(
|
|
2254
2485
|
AtPickerMenu,
|
|
2255
2486
|
{
|
|
2256
2487
|
onSelect: handleSelectExtension,
|
|
2257
2488
|
onDismiss: () => setShowAtPicker(false)
|
|
2258
2489
|
}
|
|
2259
2490
|
),
|
|
2260
|
-
showKikuPicker && /* @__PURE__ */
|
|
2491
|
+
showKikuPicker && /* @__PURE__ */ jsx8(
|
|
2261
2492
|
KikuPickerMenu,
|
|
2262
2493
|
{
|
|
2263
2494
|
sources,
|
|
@@ -2270,9 +2501,9 @@ function ChatModal({
|
|
|
2270
2501
|
onDismiss: () => setShowKikuPicker(false)
|
|
2271
2502
|
}
|
|
2272
2503
|
),
|
|
2273
|
-
attachments.length > 0 && /* @__PURE__ */
|
|
2274
|
-
/* @__PURE__ */
|
|
2275
|
-
/* @__PURE__ */
|
|
2504
|
+
attachments.length > 0 && /* @__PURE__ */ jsx8("div", { className: "hsk-cb-img-strip", children: attachments.map((att, i) => /* @__PURE__ */ jsxs7("div", { className: "hsk-cb-img-thumb-wrap", children: [
|
|
2505
|
+
/* @__PURE__ */ jsx8("img", { src: att.data, alt: `attachment ${i + 1}`, className: "hsk-cb-img-thumb" }),
|
|
2506
|
+
/* @__PURE__ */ jsx8(
|
|
2276
2507
|
"button",
|
|
2277
2508
|
{
|
|
2278
2509
|
className: "hsk-cb-img-thumb-remove",
|
|
@@ -2282,8 +2513,8 @@ function ChatModal({
|
|
|
2282
2513
|
}
|
|
2283
2514
|
)
|
|
2284
2515
|
] }, i)) }),
|
|
2285
|
-
/* @__PURE__ */
|
|
2286
|
-
/* @__PURE__ */
|
|
2516
|
+
/* @__PURE__ */ jsxs7("div", { className: "hsk-cb-input-box", children: [
|
|
2517
|
+
/* @__PURE__ */ jsx8(
|
|
2287
2518
|
"input",
|
|
2288
2519
|
{
|
|
2289
2520
|
ref: imageInputRef,
|
|
@@ -2294,7 +2525,7 @@ function ChatModal({
|
|
|
2294
2525
|
onChange: (e) => handleImageFiles(e.target.files)
|
|
2295
2526
|
}
|
|
2296
2527
|
),
|
|
2297
|
-
enableVision && /* @__PURE__ */
|
|
2528
|
+
enableVision && /* @__PURE__ */ jsx8(
|
|
2298
2529
|
"button",
|
|
2299
2530
|
{
|
|
2300
2531
|
className: "hsk-cb-attach-btn",
|
|
@@ -2302,10 +2533,10 @@ function ChatModal({
|
|
|
2302
2533
|
disabled: loading,
|
|
2303
2534
|
"aria-label": "Attach image",
|
|
2304
2535
|
title: "Attach image",
|
|
2305
|
-
children: /* @__PURE__ */
|
|
2536
|
+
children: /* @__PURE__ */ jsx8(PaperclipIcon, {})
|
|
2306
2537
|
}
|
|
2307
2538
|
),
|
|
2308
|
-
/* @__PURE__ */
|
|
2539
|
+
/* @__PURE__ */ jsx8(
|
|
2309
2540
|
"textarea",
|
|
2310
2541
|
{
|
|
2311
2542
|
ref: textareaRef,
|
|
@@ -2319,7 +2550,7 @@ function ChatModal({
|
|
|
2319
2550
|
autoFocus: true
|
|
2320
2551
|
}
|
|
2321
2552
|
),
|
|
2322
|
-
hasSpeechAPI && enableVoice && /* @__PURE__ */
|
|
2553
|
+
hasSpeechAPI && enableVoice && /* @__PURE__ */ jsxs7(
|
|
2323
2554
|
"button",
|
|
2324
2555
|
{
|
|
2325
2556
|
className: cn(
|
|
@@ -2332,32 +2563,32 @@ function ChatModal({
|
|
|
2332
2563
|
"aria-label": voiceState === "idle" ? "Start voice input" : "Stop recording",
|
|
2333
2564
|
title: voiceState === "idle" ? "Voice input" : "Stop",
|
|
2334
2565
|
children: [
|
|
2335
|
-
voiceState === "listening" ? /* @__PURE__ */
|
|
2336
|
-
voiceState === "listening" && /* @__PURE__ */
|
|
2566
|
+
voiceState === "listening" ? /* @__PURE__ */ jsx8(MicOffIcon, {}) : /* @__PURE__ */ jsx8(MicIcon2, {}),
|
|
2567
|
+
voiceState === "listening" && /* @__PURE__ */ jsx8("span", { className: "hsk-cb-mic-pulse" })
|
|
2337
2568
|
]
|
|
2338
2569
|
}
|
|
2339
2570
|
),
|
|
2340
|
-
loading || streaming ? /* @__PURE__ */
|
|
2571
|
+
loading || streaming ? /* @__PURE__ */ jsx8(
|
|
2341
2572
|
"button",
|
|
2342
2573
|
{
|
|
2343
2574
|
className: cn("hsk-cb-send", "hsk-cb-send--stop", classNames.sendButton),
|
|
2344
2575
|
onClick: stop,
|
|
2345
2576
|
"aria-label": "Stop generating",
|
|
2346
2577
|
title: "Stop generating",
|
|
2347
|
-
children: /* @__PURE__ */
|
|
2578
|
+
children: /* @__PURE__ */ jsx8(StopIcon, {})
|
|
2348
2579
|
}
|
|
2349
|
-
) : /* @__PURE__ */
|
|
2580
|
+
) : /* @__PURE__ */ jsx8(
|
|
2350
2581
|
"button",
|
|
2351
2582
|
{
|
|
2352
2583
|
className: cn("hsk-cb-send", classNames.sendButton),
|
|
2353
2584
|
onClick: () => handleSend(),
|
|
2354
2585
|
disabled: !input.trim() && attachments.length === 0,
|
|
2355
2586
|
"aria-label": "Send message",
|
|
2356
|
-
children: /* @__PURE__ */
|
|
2587
|
+
children: /* @__PURE__ */ jsx8(ArrowUpIcon2, {})
|
|
2357
2588
|
}
|
|
2358
2589
|
)
|
|
2359
2590
|
] }),
|
|
2360
|
-
/* @__PURE__ */
|
|
2591
|
+
/* @__PURE__ */ jsx8("div", { className: "hsk-cb-hint", children: "kiku \xB7 searches the whole catalogue in real time" })
|
|
2361
2592
|
] })
|
|
2362
2593
|
] })
|
|
2363
2594
|
]
|
|
@@ -2383,9 +2614,9 @@ function KikuButton({
|
|
|
2383
2614
|
enableVision = false,
|
|
2384
2615
|
visionCategoryHint
|
|
2385
2616
|
}) {
|
|
2386
|
-
const [open, setOpen] =
|
|
2387
|
-
const [mounted, setMounted] =
|
|
2388
|
-
|
|
2617
|
+
const [open, setOpen] = useState6(false);
|
|
2618
|
+
const [mounted, setMounted] = useState6(false);
|
|
2619
|
+
useEffect4(() => {
|
|
2389
2620
|
setMounted(true);
|
|
2390
2621
|
if (typeof window !== "undefined" && !window.__akropolys_nav_patched) {
|
|
2391
2622
|
window.__akropolys_nav_patched = true;
|
|
@@ -2419,8 +2650,8 @@ function KikuButton({
|
|
|
2419
2650
|
...theme?.fontFamily && { "--hsk-font": theme.fontFamily },
|
|
2420
2651
|
...theme?.borderRadius && { "--hsk-border-radius": theme.borderRadius }
|
|
2421
2652
|
} : void 0;
|
|
2422
|
-
return /* @__PURE__ */
|
|
2423
|
-
/* @__PURE__ */
|
|
2653
|
+
return /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2654
|
+
/* @__PURE__ */ jsxs7(
|
|
2424
2655
|
"button",
|
|
2425
2656
|
{
|
|
2426
2657
|
className: cn("hsk-cb-btn", classNames.button, className),
|
|
@@ -2429,13 +2660,13 @@ function KikuButton({
|
|
|
2429
2660
|
"data-hsk-theme": hskThemeAttr,
|
|
2430
2661
|
"aria-label": "Open AI chat",
|
|
2431
2662
|
children: [
|
|
2432
|
-
/* @__PURE__ */
|
|
2663
|
+
/* @__PURE__ */ jsx8("span", { className: "hsk-cb-btn-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx8(SparkleIcon2, {}) }),
|
|
2433
2664
|
label !== void 0 ? label : null
|
|
2434
2665
|
]
|
|
2435
2666
|
}
|
|
2436
2667
|
),
|
|
2437
2668
|
open && mounted && createPortal(
|
|
2438
|
-
/* @__PURE__ */
|
|
2669
|
+
/* @__PURE__ */ jsx8(
|
|
2439
2670
|
ChatModal,
|
|
2440
2671
|
{
|
|
2441
2672
|
title,
|
|
@@ -2460,11 +2691,11 @@ function KikuButton({
|
|
|
2460
2691
|
}
|
|
2461
2692
|
|
|
2462
2693
|
// src/components/Sparkle.tsx
|
|
2463
|
-
import { useState as
|
|
2694
|
+
import { useState as useState7, useEffect as useEffect5, useRef as useRef7 } from "react";
|
|
2464
2695
|
import { createPortal as createPortal2 } from "react-dom";
|
|
2465
2696
|
import { useSearch as useSearch2, useKiku as useKiku3, useAkropolysContext as useAkropolysContext4 } from "@akropolys/sdk";
|
|
2466
|
-
import { Fragment as Fragment4, jsx as
|
|
2467
|
-
var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */
|
|
2697
|
+
import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2698
|
+
var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ jsx9(
|
|
2468
2699
|
"svg",
|
|
2469
2700
|
{
|
|
2470
2701
|
className: cn("hsk-brand-mark", className),
|
|
@@ -2473,19 +2704,19 @@ var SparkleIcon3 = ({ className, size = 16 }) => /* @__PURE__ */ jsx8(
|
|
|
2473
2704
|
viewBox: "0 0 100 100",
|
|
2474
2705
|
xmlns: "http://www.w3.org/2000/svg",
|
|
2475
2706
|
"aria-label": "kiku",
|
|
2476
|
-
children: /* @__PURE__ */
|
|
2477
|
-
/* @__PURE__ */
|
|
2478
|
-
/* @__PURE__ */
|
|
2707
|
+
children: /* @__PURE__ */ jsxs8("g", { transform: "translate(22.7 19) scale(0.62)", fill: "currentColor", fillRule: "evenodd", children: [
|
|
2708
|
+
/* @__PURE__ */ jsx9("path", { d: "M39.4 10.4 Q44 0 48.6 10.4 L86.1 95.8 Q88 100 83.4 100 L4.6 100 Q0 100 1.9 95.8 Z M24 100 L24 65 Q24 60 27.4 56.3 Q44 38 60.6 56.3 Q64 60 64 65 L64 100 Z" }),
|
|
2709
|
+
/* @__PURE__ */ jsx9("circle", { cx: "55", cy: "82", r: "3.4" })
|
|
2479
2710
|
] })
|
|
2480
2711
|
}
|
|
2481
2712
|
);
|
|
2482
|
-
var CloseIcon2 = () => /* @__PURE__ */
|
|
2483
|
-
/* @__PURE__ */
|
|
2484
|
-
/* @__PURE__ */
|
|
2713
|
+
var CloseIcon2 = () => /* @__PURE__ */ jsxs8("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2714
|
+
/* @__PURE__ */ jsx9("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
2715
|
+
/* @__PURE__ */ jsx9("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
2485
2716
|
] });
|
|
2486
|
-
var ArrowUpIcon3 = () => /* @__PURE__ */
|
|
2487
|
-
/* @__PURE__ */
|
|
2488
|
-
/* @__PURE__ */
|
|
2717
|
+
var ArrowUpIcon3 = () => /* @__PURE__ */ jsxs8("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2718
|
+
/* @__PURE__ */ jsx9("path", { d: "m5 12 7-7 7 7" }),
|
|
2719
|
+
/* @__PURE__ */ jsx9("path", { d: "M12 19V5" })
|
|
2489
2720
|
] });
|
|
2490
2721
|
var getFriendlyError2 = (err) => {
|
|
2491
2722
|
let str = "";
|
|
@@ -2519,17 +2750,17 @@ function SparkleModal({
|
|
|
2519
2750
|
product: initialProduct
|
|
2520
2751
|
}) {
|
|
2521
2752
|
const client = useAkropolysContext4();
|
|
2522
|
-
const [fetchedProduct, setFetchedProduct] =
|
|
2753
|
+
const [fetchedProduct, setFetchedProduct] = useState7(null);
|
|
2523
2754
|
const displayProduct = initialProduct || fetchedProduct;
|
|
2524
2755
|
const { results, loading: searchLoading, search } = useSearch2({ type: "vector" });
|
|
2525
2756
|
const { messages, sources, loading: chatLoading, error: chatError, send } = useKiku3();
|
|
2526
|
-
const [chatInput, setChatInput] =
|
|
2527
|
-
const [isMobile, setIsMobile] =
|
|
2528
|
-
const [showSpecs, setShowSpecs] =
|
|
2529
|
-
const [collapseSimilar, setCollapseSimilar] =
|
|
2530
|
-
const chatBottomRef =
|
|
2531
|
-
const chatTextareaRef =
|
|
2532
|
-
|
|
2757
|
+
const [chatInput, setChatInput] = useState7("");
|
|
2758
|
+
const [isMobile, setIsMobile] = useState7(false);
|
|
2759
|
+
const [showSpecs, setShowSpecs] = useState7(false);
|
|
2760
|
+
const [collapseSimilar, setCollapseSimilar] = useState7(false);
|
|
2761
|
+
const chatBottomRef = useRef7(null);
|
|
2762
|
+
const chatTextareaRef = useRef7(null);
|
|
2763
|
+
useEffect5(() => {
|
|
2533
2764
|
if (!initialProduct && !fetchedProduct) {
|
|
2534
2765
|
client.api.searchVector(productName, 1).then((res) => {
|
|
2535
2766
|
if (res.results && res.results.length > 0) {
|
|
@@ -2539,7 +2770,7 @@ function SparkleModal({
|
|
|
2539
2770
|
}
|
|
2540
2771
|
search(productName, limit);
|
|
2541
2772
|
}, [productName, initialProduct, fetchedProduct, client, limit, search]);
|
|
2542
|
-
|
|
2773
|
+
useEffect5(() => {
|
|
2543
2774
|
const handleResize = () => setIsMobile(window.innerWidth <= 768);
|
|
2544
2775
|
handleResize();
|
|
2545
2776
|
if (typeof window !== "undefined") {
|
|
@@ -2547,17 +2778,17 @@ function SparkleModal({
|
|
|
2547
2778
|
return () => window.removeEventListener("resize", handleResize);
|
|
2548
2779
|
}
|
|
2549
2780
|
}, []);
|
|
2550
|
-
|
|
2781
|
+
useEffect5(() => {
|
|
2551
2782
|
if (results.length > 0) onResult?.(results);
|
|
2552
2783
|
}, [results, onResult]);
|
|
2553
|
-
|
|
2784
|
+
useEffect5(() => {
|
|
2554
2785
|
const h = (e) => {
|
|
2555
2786
|
if (e.key === "Escape") onClose();
|
|
2556
2787
|
};
|
|
2557
2788
|
document.addEventListener("keydown", h);
|
|
2558
2789
|
return () => document.removeEventListener("keydown", h);
|
|
2559
2790
|
}, [onClose]);
|
|
2560
|
-
|
|
2791
|
+
useEffect5(() => {
|
|
2561
2792
|
chatBottomRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
2562
2793
|
}, [messages, chatLoading]);
|
|
2563
2794
|
const blurVal = typeof backdropBlur === "number" ? `${backdropBlur}px` : backdropBlur ?? "16px";
|
|
@@ -2611,7 +2842,7 @@ Question: ${q}`;
|
|
|
2611
2842
|
}
|
|
2612
2843
|
] : messages;
|
|
2613
2844
|
if (isMobile) {
|
|
2614
|
-
return /* @__PURE__ */
|
|
2845
|
+
return /* @__PURE__ */ jsx9(
|
|
2615
2846
|
"div",
|
|
2616
2847
|
{
|
|
2617
2848
|
className: cn("hsk-sp-backdrop hsk-sp-mobile-view", classNames.backdrop),
|
|
@@ -2622,13 +2853,13 @@ Question: ${q}`;
|
|
|
2622
2853
|
background: bg ?? void 0,
|
|
2623
2854
|
...customStyles
|
|
2624
2855
|
},
|
|
2625
|
-
children: /* @__PURE__ */
|
|
2626
|
-
/* @__PURE__ */
|
|
2627
|
-
/* @__PURE__ */
|
|
2628
|
-
/* @__PURE__ */
|
|
2629
|
-
/* @__PURE__ */
|
|
2630
|
-
/* @__PURE__ */
|
|
2631
|
-
displayProduct && /* @__PURE__ */
|
|
2856
|
+
children: /* @__PURE__ */ jsxs8("div", { className: cn("hsk-sp-card hsk-sp-fullscreen hsk-sp-mobile-card", classNames.card), onClick: (e) => e.stopPropagation(), children: [
|
|
2857
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-header", children: [
|
|
2858
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-header-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx9(SparkleIcon3, {}) }),
|
|
2859
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-header-body", children: [
|
|
2860
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-header-title-row", children: [
|
|
2861
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-header-title", children: displayProduct?.name || productName }),
|
|
2862
|
+
displayProduct && /* @__PURE__ */ jsx9(
|
|
2632
2863
|
"button",
|
|
2633
2864
|
{
|
|
2634
2865
|
type: "button",
|
|
@@ -2638,32 +2869,32 @@ Question: ${q}`;
|
|
|
2638
2869
|
}
|
|
2639
2870
|
)
|
|
2640
2871
|
] }),
|
|
2641
|
-
/* @__PURE__ */
|
|
2872
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-header-sub", children: "kiku" })
|
|
2642
2873
|
] }),
|
|
2643
|
-
/* @__PURE__ */
|
|
2874
|
+
/* @__PURE__ */ jsx9("button", { className: "hsk-sp-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx9(CloseIcon2, {}) })
|
|
2644
2875
|
] }),
|
|
2645
|
-
searchLoading && /* @__PURE__ */
|
|
2646
|
-
/* @__PURE__ */
|
|
2647
|
-
/* @__PURE__ */
|
|
2876
|
+
searchLoading && /* @__PURE__ */ jsx9("div", { className: "hsk-sp-bar" }),
|
|
2877
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-chat-container", children: [
|
|
2878
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-msgs", children: [
|
|
2648
2879
|
displayMessages.map((msg, idx) => {
|
|
2649
2880
|
const isUser = msg.role === "user";
|
|
2650
|
-
return /* @__PURE__ */
|
|
2651
|
-
/* @__PURE__ */
|
|
2652
|
-
/* @__PURE__ */
|
|
2653
|
-
/* @__PURE__ */
|
|
2654
|
-
idx === 0 && displayProduct && /* @__PURE__ */
|
|
2655
|
-
/* @__PURE__ */
|
|
2656
|
-
/* @__PURE__ */
|
|
2657
|
-
/* @__PURE__ */
|
|
2658
|
-
/* @__PURE__ */
|
|
2659
|
-
/* @__PURE__ */
|
|
2660
|
-
/* @__PURE__ */
|
|
2881
|
+
return /* @__PURE__ */ jsx9("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ jsx9("div", { className: "hsk-cb-user-msg", children: /* @__PURE__ */ jsx9("div", { className: "hsk-cb-user-bubble", children: msg.content }) }) : /* @__PURE__ */ jsxs8("div", { className: "hsk-cb-ai-msg", children: [
|
|
2882
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx9(SparkleIcon3, {}) }),
|
|
2883
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-ai-body", children: [
|
|
2884
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-ai-text", children: renderMarkdown(msg.content) }),
|
|
2885
|
+
idx === 0 && displayProduct && /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-attachment-deck", children: [
|
|
2886
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-main-card", children: [
|
|
2887
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-mobile-main-card-img", children: displayProduct.images?.[0] ? /* @__PURE__ */ jsx9("img", { src: displayProduct.images[0], alt: displayProduct.name }) : /* @__PURE__ */ jsx9("span", { children: "\xF0\u0178\u203A\x8D" }) }),
|
|
2888
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-main-card-info", children: [
|
|
2889
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-mobile-main-card-brand", children: displayProduct.brand || displayProduct.category || "Product" }),
|
|
2890
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-mobile-main-card-name", children: displayProduct.name }),
|
|
2891
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-main-card-price", children: [
|
|
2661
2892
|
displayProduct.currency ?? "KES",
|
|
2662
2893
|
" ",
|
|
2663
2894
|
parseFloat(displayProduct.price?.replace(/[^0-9.]/g, "") || "0").toLocaleString()
|
|
2664
2895
|
] })
|
|
2665
2896
|
] }),
|
|
2666
|
-
(displayProduct.specs && Object.keys(displayProduct.specs).length > 0 || displayProduct.description) && /* @__PURE__ */
|
|
2897
|
+
(displayProduct.specs && Object.keys(displayProduct.specs).length > 0 || displayProduct.description) && /* @__PURE__ */ jsx9(
|
|
2667
2898
|
"button",
|
|
2668
2899
|
{
|
|
2669
2900
|
type: "button",
|
|
@@ -2682,21 +2913,21 @@ Question: ${q}`;
|
|
|
2682
2913
|
}
|
|
2683
2914
|
);
|
|
2684
2915
|
if (similarProducts.length === 0) return null;
|
|
2685
|
-
return /* @__PURE__ */
|
|
2686
|
-
/* @__PURE__ */
|
|
2687
|
-
/* @__PURE__ */
|
|
2916
|
+
return /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-similar-carousel-inline", children: [
|
|
2917
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-mobile-similar-carousel-title", children: "Similar Products" }),
|
|
2918
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-mobile-similar-carousel-list", children: similarProducts.map((r) => {
|
|
2688
2919
|
const price = parseFloat(r.entity.price?.replace(/[^0-9.]/g, "") || "0");
|
|
2689
2920
|
const currency = r.entity.currency ?? "KES";
|
|
2690
|
-
return /* @__PURE__ */
|
|
2921
|
+
return /* @__PURE__ */ jsxs8(
|
|
2691
2922
|
"div",
|
|
2692
2923
|
{
|
|
2693
2924
|
className: "hsk-sp-mobile-similar-carousel-item",
|
|
2694
2925
|
onClick: () => handleNav(r),
|
|
2695
2926
|
children: [
|
|
2696
|
-
/* @__PURE__ */
|
|
2697
|
-
/* @__PURE__ */
|
|
2698
|
-
/* @__PURE__ */
|
|
2699
|
-
/* @__PURE__ */
|
|
2927
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-mobile-similar-carousel-img", children: r.entity.images?.[0] ? /* @__PURE__ */ jsx9("img", { src: r.entity.images[0], alt: r.entity.name }) : /* @__PURE__ */ jsx9("span", { children: "\xF0\u0178\u203A\x8D" }) }),
|
|
2928
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-similar-carousel-meta", children: [
|
|
2929
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-mobile-similar-carousel-name", title: r.entity.name, children: r.entity.name }),
|
|
2930
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-similar-carousel-price", children: [
|
|
2700
2931
|
currency,
|
|
2701
2932
|
" ",
|
|
2702
2933
|
price.toLocaleString()
|
|
@@ -2713,19 +2944,19 @@ Question: ${q}`;
|
|
|
2713
2944
|
] })
|
|
2714
2945
|
] }) }, idx);
|
|
2715
2946
|
}),
|
|
2716
|
-
chatLoading && /* @__PURE__ */
|
|
2717
|
-
/* @__PURE__ */
|
|
2718
|
-
/* @__PURE__ */
|
|
2719
|
-
/* @__PURE__ */
|
|
2720
|
-
/* @__PURE__ */
|
|
2721
|
-
/* @__PURE__ */
|
|
2947
|
+
chatLoading && /* @__PURE__ */ jsxs8("div", { className: "hsk-cb-typing-row", children: [
|
|
2948
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx9(SparkleIcon3, {}) }),
|
|
2949
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-typing", children: [
|
|
2950
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-dot" }),
|
|
2951
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-dot" }),
|
|
2952
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-dot" })
|
|
2722
2953
|
] })
|
|
2723
2954
|
] }),
|
|
2724
|
-
chatError && /* @__PURE__ */
|
|
2725
|
-
/* @__PURE__ */
|
|
2955
|
+
chatError && /* @__PURE__ */ jsx9("div", { className: "hsk-cb-error", children: getFriendlyError2(chatError) }),
|
|
2956
|
+
/* @__PURE__ */ jsx9("div", { ref: chatBottomRef, style: { height: 1 } })
|
|
2726
2957
|
] }),
|
|
2727
|
-
/* @__PURE__ */
|
|
2728
|
-
/* @__PURE__ */
|
|
2958
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-input-wrap", children: /* @__PURE__ */ jsxs8("div", { className: "hsk-cb-input-box", children: [
|
|
2959
|
+
/* @__PURE__ */ jsx9(
|
|
2729
2960
|
"textarea",
|
|
2730
2961
|
{
|
|
2731
2962
|
ref: chatTextareaRef,
|
|
@@ -2738,34 +2969,34 @@ Question: ${q}`;
|
|
|
2738
2969
|
disabled: chatLoading
|
|
2739
2970
|
}
|
|
2740
2971
|
),
|
|
2741
|
-
/* @__PURE__ */
|
|
2972
|
+
/* @__PURE__ */ jsx9(
|
|
2742
2973
|
"button",
|
|
2743
2974
|
{
|
|
2744
2975
|
className: "hsk-cb-send",
|
|
2745
2976
|
onClick: () => handleSend(),
|
|
2746
2977
|
disabled: !chatInput.trim() || chatLoading,
|
|
2747
2978
|
"aria-label": "Send message",
|
|
2748
|
-
children: /* @__PURE__ */
|
|
2979
|
+
children: /* @__PURE__ */ jsx9(ArrowUpIcon3, {})
|
|
2749
2980
|
}
|
|
2750
2981
|
)
|
|
2751
2982
|
] }) })
|
|
2752
2983
|
] }),
|
|
2753
|
-
showSpecs && displayProduct && /* @__PURE__ */
|
|
2754
|
-
/* @__PURE__ */
|
|
2755
|
-
/* @__PURE__ */
|
|
2756
|
-
/* @__PURE__ */
|
|
2984
|
+
showSpecs && displayProduct && /* @__PURE__ */ jsx9("div", { className: "hsk-sp-mobile-specs-overlay", onClick: () => setShowSpecs(false), children: /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-specs-drawer", onClick: (e) => e.stopPropagation(), children: [
|
|
2985
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-specs-header", children: [
|
|
2986
|
+
/* @__PURE__ */ jsx9("h3", { children: "Specifications" }),
|
|
2987
|
+
/* @__PURE__ */ jsx9("button", { type: "button", onClick: () => setShowSpecs(false), children: "Close" })
|
|
2757
2988
|
] }),
|
|
2758
|
-
/* @__PURE__ */
|
|
2759
|
-
/* @__PURE__ */
|
|
2760
|
-
displayProduct.description && /* @__PURE__ */
|
|
2761
|
-
/* @__PURE__ */
|
|
2762
|
-
/* @__PURE__ */
|
|
2989
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-specs-body", children: [
|
|
2990
|
+
/* @__PURE__ */ jsx9("h4", { className: "hsk-sp-mobile-specs-title", children: displayProduct.name }),
|
|
2991
|
+
displayProduct.description && /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-specs-desc", children: [
|
|
2992
|
+
/* @__PURE__ */ jsx9("h5", { children: "Description" }),
|
|
2993
|
+
/* @__PURE__ */ jsx9("p", { children: displayProduct.description })
|
|
2763
2994
|
] }),
|
|
2764
|
-
displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */
|
|
2765
|
-
/* @__PURE__ */
|
|
2766
|
-
Object.entries(displayProduct.specs).map(([key, val]) => /* @__PURE__ */
|
|
2767
|
-
/* @__PURE__ */
|
|
2768
|
-
/* @__PURE__ */
|
|
2995
|
+
displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-specs-list", children: [
|
|
2996
|
+
/* @__PURE__ */ jsx9("h5", { children: "Details" }),
|
|
2997
|
+
Object.entries(displayProduct.specs).map(([key, val]) => /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-mobile-spec-row", children: [
|
|
2998
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-mobile-spec-label", children: key }),
|
|
2999
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-mobile-spec-value", children: val })
|
|
2769
3000
|
] }, key))
|
|
2770
3001
|
] })
|
|
2771
3002
|
] })
|
|
@@ -2774,7 +3005,7 @@ Question: ${q}`;
|
|
|
2774
3005
|
}
|
|
2775
3006
|
);
|
|
2776
3007
|
}
|
|
2777
|
-
return /* @__PURE__ */
|
|
3008
|
+
return /* @__PURE__ */ jsx9(
|
|
2778
3009
|
"div",
|
|
2779
3010
|
{
|
|
2780
3011
|
className: cn("hsk-sp-backdrop", classNames.backdrop),
|
|
@@ -2785,65 +3016,65 @@ Question: ${q}`;
|
|
|
2785
3016
|
background: bg ?? void 0,
|
|
2786
3017
|
...customStyles
|
|
2787
3018
|
},
|
|
2788
|
-
children: /* @__PURE__ */
|
|
2789
|
-
/* @__PURE__ */
|
|
2790
|
-
/* @__PURE__ */
|
|
2791
|
-
/* @__PURE__ */
|
|
2792
|
-
/* @__PURE__ */
|
|
2793
|
-
/* @__PURE__ */
|
|
3019
|
+
children: /* @__PURE__ */ jsxs8("div", { className: cn("hsk-sp-card hsk-sp-fullscreen", classNames.card), onClick: (e) => e.stopPropagation(), children: [
|
|
3020
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-header", children: [
|
|
3021
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-header-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx9(SparkleIcon3, {}) }),
|
|
3022
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-header-body", children: [
|
|
3023
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-header-title", children: displayProduct?.name || productName }),
|
|
3024
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-header-sub", children: "Ask questions, compare specs, or check similar products" })
|
|
2794
3025
|
] }),
|
|
2795
|
-
/* @__PURE__ */
|
|
3026
|
+
/* @__PURE__ */ jsx9("button", { className: "hsk-sp-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx9(CloseIcon2, {}) })
|
|
2796
3027
|
] }),
|
|
2797
|
-
searchLoading && /* @__PURE__ */
|
|
2798
|
-
/* @__PURE__ */
|
|
2799
|
-
/* @__PURE__ */
|
|
2800
|
-
displayProduct && /* @__PURE__ */
|
|
2801
|
-
/* @__PURE__ */
|
|
2802
|
-
/* @__PURE__ */
|
|
2803
|
-
/* @__PURE__ */
|
|
2804
|
-
displayProduct.brand && /* @__PURE__ */
|
|
2805
|
-
displayProduct.category && /* @__PURE__ */
|
|
2806
|
-
/* @__PURE__ */
|
|
2807
|
-
/* @__PURE__ */
|
|
2808
|
-
/* @__PURE__ */
|
|
2809
|
-
/* @__PURE__ */
|
|
2810
|
-
displayProduct.originalPrice && /* @__PURE__ */
|
|
2811
|
-
displayProduct.discount && /* @__PURE__ */
|
|
3028
|
+
searchLoading && /* @__PURE__ */ jsx9("div", { className: "hsk-sp-bar" }),
|
|
3029
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-body", children: [
|
|
3030
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-details-pane", children: [
|
|
3031
|
+
displayProduct && /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-product-profile-container", children: [
|
|
3032
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-product-profile", children: [
|
|
3033
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-details-imgwrap", children: displayProduct.images?.[0] ? /* @__PURE__ */ jsx9("img", { src: displayProduct.images[0], alt: displayProduct.name }) : /* @__PURE__ */ jsx9("span", { className: "hsk-sp-img-placeholder", children: "\xF0\u0178\u203A\x8D" }) }),
|
|
3034
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-details-meta", children: [
|
|
3035
|
+
displayProduct.brand && /* @__PURE__ */ jsx9("span", { className: "hsk-sp-item-brand", children: displayProduct.brand }),
|
|
3036
|
+
displayProduct.category && /* @__PURE__ */ jsx9("span", { className: "hsk-sp-item-cat", children: displayProduct.category }),
|
|
3037
|
+
/* @__PURE__ */ jsx9("h2", { className: "hsk-sp-details-name", children: displayProduct.name }),
|
|
3038
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-item-price-row", children: [
|
|
3039
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-item-currency", children: displayProduct.currency ?? "KES" }),
|
|
3040
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-item-price", children: parseFloat(displayProduct.price?.replace(/[^0-9.]/g, "") || "0").toLocaleString() }),
|
|
3041
|
+
displayProduct.originalPrice && /* @__PURE__ */ jsx9("span", { className: "hsk-sp-item-original-price", children: parseFloat(displayProduct.originalPrice.replace(/[^0-9.]/g, "") || "0").toLocaleString() }),
|
|
3042
|
+
displayProduct.discount && /* @__PURE__ */ jsxs8("span", { className: "hsk-sp-item-discount", children: [
|
|
2812
3043
|
"(",
|
|
2813
3044
|
displayProduct.discount,
|
|
2814
3045
|
")"
|
|
2815
3046
|
] })
|
|
2816
3047
|
] }),
|
|
2817
|
-
/* @__PURE__ */
|
|
2818
|
-
displayProduct.rating && /* @__PURE__ */
|
|
3048
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-item-meta-badges", children: [
|
|
3049
|
+
displayProduct.rating && /* @__PURE__ */ jsxs8("span", { className: "hsk-sp-meta-badge hsk-sp-meta-badge-rating", children: [
|
|
2819
3050
|
"\xE2\u02DC\u2026 ",
|
|
2820
3051
|
parseFloat(displayProduct.rating.toString()).toFixed(1),
|
|
2821
3052
|
" ",
|
|
2822
3053
|
displayProduct.reviewCount ? `(${displayProduct.reviewCount})` : ""
|
|
2823
3054
|
] }),
|
|
2824
|
-
displayProduct.availability && /* @__PURE__ */
|
|
2825
|
-
displayProduct.stock && !displayProduct.availability && /* @__PURE__ */
|
|
3055
|
+
displayProduct.availability && /* @__PURE__ */ jsx9("span", { className: `hsk-sp-meta-badge hsk-sp-meta-badge-avail ${displayProduct.availability.toLowerCase().includes("in") ? "in-stock" : "out-stock"}`, children: displayProduct.availability }),
|
|
3056
|
+
displayProduct.stock && !displayProduct.availability && /* @__PURE__ */ jsxs8("span", { className: "hsk-sp-meta-badge hsk-sp-meta-badge-stock", children: [
|
|
2826
3057
|
"Stock: ",
|
|
2827
3058
|
displayProduct.stock
|
|
2828
3059
|
] })
|
|
2829
3060
|
] })
|
|
2830
3061
|
] })
|
|
2831
3062
|
] }),
|
|
2832
|
-
displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */
|
|
2833
|
-
/* @__PURE__ */
|
|
3063
|
+
displayProduct.specs && Object.keys(displayProduct.specs).length > 0 && /* @__PURE__ */ jsx9("div", { className: "hsk-sp-specs-horizontal", children: Object.entries(displayProduct.specs).map(([key, val]) => /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-spec-item-horizontal", children: [
|
|
3064
|
+
/* @__PURE__ */ jsxs8("span", { className: "hsk-sp-spec-label-horizontal", children: [
|
|
2834
3065
|
key,
|
|
2835
3066
|
":"
|
|
2836
3067
|
] }),
|
|
2837
|
-
/* @__PURE__ */
|
|
3068
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-spec-value-horizontal", title: val, children: val })
|
|
2838
3069
|
] }, key)) }),
|
|
2839
|
-
displayProduct.description && /* @__PURE__ */
|
|
2840
|
-
/* @__PURE__ */
|
|
2841
|
-
/* @__PURE__ */
|
|
3070
|
+
displayProduct.description && /* @__PURE__ */ jsxs8("div", { className: "hsk-sp-details-desc", children: [
|
|
3071
|
+
/* @__PURE__ */ jsx9("h4", { children: "Description" }),
|
|
3072
|
+
/* @__PURE__ */ jsx9("p", { children: displayProduct.description })
|
|
2842
3073
|
] })
|
|
2843
3074
|
] }),
|
|
2844
|
-
/* @__PURE__ */
|
|
2845
|
-
/* @__PURE__ */
|
|
2846
|
-
/* @__PURE__ */
|
|
3075
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-similar-section", children: [
|
|
3076
|
+
/* @__PURE__ */ jsx9("h3", { children: "Similar Products" }),
|
|
3077
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-results", children: (() => {
|
|
2847
3078
|
const similarProducts = results.filter(
|
|
2848
3079
|
(r) => {
|
|
2849
3080
|
const isSameName = !!(r.entity.name && displayProduct?.name && r.entity.name.toLowerCase() === displayProduct.name.toLowerCase());
|
|
@@ -2852,29 +3083,29 @@ Question: ${q}`;
|
|
|
2852
3083
|
}
|
|
2853
3084
|
);
|
|
2854
3085
|
if (!searchLoading && similarProducts.length === 0) {
|
|
2855
|
-
return /* @__PURE__ */
|
|
3086
|
+
return /* @__PURE__ */ jsx9("div", { className: "hsk-sp-empty", children: "No similar products found." });
|
|
2856
3087
|
}
|
|
2857
3088
|
return similarProducts.map((r, i) => {
|
|
2858
3089
|
const price = parseFloat(r.entity.price?.replace(/[^0-9.]/g, "") || "0");
|
|
2859
3090
|
const currency = r.entity.currency ?? "KES";
|
|
2860
|
-
return /* @__PURE__ */
|
|
3091
|
+
return /* @__PURE__ */ jsxs8(
|
|
2861
3092
|
"div",
|
|
2862
3093
|
{
|
|
2863
3094
|
className: cn("hsk-sp-item", classNames.item),
|
|
2864
3095
|
style: { animationDelay: `${i * 55}ms`, cursor: "pointer" },
|
|
2865
3096
|
onClick: () => handleNav(r),
|
|
2866
3097
|
children: [
|
|
2867
|
-
/* @__PURE__ */
|
|
2868
|
-
/* @__PURE__ */
|
|
2869
|
-
/* @__PURE__ */
|
|
2870
|
-
r.entity.category && /* @__PURE__ */
|
|
2871
|
-
/* @__PURE__ */
|
|
3098
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-img-wrap", children: r.entity.images?.[0] ? /* @__PURE__ */ jsx9("img", { src: r.entity.images[0], alt: r.entity.name }) : /* @__PURE__ */ jsx9("span", { className: "hsk-sp-img-placeholder", children: "\xF0\u0178\u203A\x8D" }) }),
|
|
3099
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-item-body", children: [
|
|
3100
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
3101
|
+
r.entity.category && /* @__PURE__ */ jsx9("div", { className: "hsk-sp-item-cat", children: r.entity.category }),
|
|
3102
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-item-name", title: r.entity.name, children: r.entity.name })
|
|
2872
3103
|
] }),
|
|
2873
|
-
/* @__PURE__ */
|
|
2874
|
-
/* @__PURE__ */
|
|
2875
|
-
/* @__PURE__ */
|
|
3104
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-item-price-row", children: [
|
|
3105
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-item-currency", children: currency }),
|
|
3106
|
+
/* @__PURE__ */ jsx9("span", { className: "hsk-sp-item-price", children: price.toLocaleString() })
|
|
2876
3107
|
] }),
|
|
2877
|
-
/* @__PURE__ */
|
|
3108
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-actions", children: /* @__PURE__ */ jsx9(
|
|
2878
3109
|
"button",
|
|
2879
3110
|
{
|
|
2880
3111
|
className: "hsk-sp-action hsk-sp-action-primary",
|
|
@@ -2894,29 +3125,29 @@ Question: ${q}`;
|
|
|
2894
3125
|
})() })
|
|
2895
3126
|
] })
|
|
2896
3127
|
] }),
|
|
2897
|
-
/* @__PURE__ */
|
|
2898
|
-
/* @__PURE__ */
|
|
3128
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-sp-chat-pane", children: [
|
|
3129
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-msgs", children: [
|
|
2899
3130
|
displayMessages.map((msg, idx) => {
|
|
2900
3131
|
const isUser = msg.role === "user";
|
|
2901
|
-
return /* @__PURE__ */
|
|
2902
|
-
/* @__PURE__ */
|
|
2903
|
-
/* @__PURE__ */
|
|
3132
|
+
return /* @__PURE__ */ jsx9("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ jsx9("div", { className: "hsk-cb-user-msg", children: /* @__PURE__ */ jsx9("div", { className: "hsk-cb-user-bubble", children: msg.content }) }) : /* @__PURE__ */ jsxs8("div", { className: "hsk-cb-ai-msg", children: [
|
|
3133
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx9(SparkleIcon3, {}) }),
|
|
3134
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-ai-body", children: /* @__PURE__ */ jsx9("div", { className: "hsk-cb-ai-text", children: renderMarkdown(msg.content) }) })
|
|
2904
3135
|
] }) }, idx);
|
|
2905
3136
|
}),
|
|
2906
|
-
chatLoading && /* @__PURE__ */
|
|
2907
|
-
/* @__PURE__ */
|
|
2908
|
-
/* @__PURE__ */
|
|
2909
|
-
/* @__PURE__ */
|
|
2910
|
-
/* @__PURE__ */
|
|
2911
|
-
/* @__PURE__ */
|
|
3137
|
+
chatLoading && /* @__PURE__ */ jsxs8("div", { className: "hsk-cb-typing-row", children: [
|
|
3138
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx9(SparkleIcon3, {}) }),
|
|
3139
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-typing", children: [
|
|
3140
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-dot" }),
|
|
3141
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-dot" }),
|
|
3142
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-dot" })
|
|
2912
3143
|
] })
|
|
2913
3144
|
] }),
|
|
2914
|
-
chatError && /* @__PURE__ */
|
|
2915
|
-
/* @__PURE__ */
|
|
3145
|
+
chatError && /* @__PURE__ */ jsx9("div", { className: "hsk-cb-error", children: getFriendlyError2(chatError) }),
|
|
3146
|
+
/* @__PURE__ */ jsx9("div", { ref: chatBottomRef, style: { height: 1 } })
|
|
2916
3147
|
] }),
|
|
2917
|
-
/* @__PURE__ */
|
|
2918
|
-
/* @__PURE__ */
|
|
2919
|
-
/* @__PURE__ */
|
|
3148
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-input-wrap", children: [
|
|
3149
|
+
/* @__PURE__ */ jsxs8("div", { className: "hsk-cb-input-box", children: [
|
|
3150
|
+
/* @__PURE__ */ jsx9(
|
|
2920
3151
|
"textarea",
|
|
2921
3152
|
{
|
|
2922
3153
|
ref: chatTextareaRef,
|
|
@@ -2929,22 +3160,22 @@ Question: ${q}`;
|
|
|
2929
3160
|
disabled: chatLoading
|
|
2930
3161
|
}
|
|
2931
3162
|
),
|
|
2932
|
-
/* @__PURE__ */
|
|
3163
|
+
/* @__PURE__ */ jsx9(
|
|
2933
3164
|
"button",
|
|
2934
3165
|
{
|
|
2935
3166
|
className: "hsk-cb-send",
|
|
2936
3167
|
onClick: () => handleSend(),
|
|
2937
3168
|
disabled: !chatInput.trim() || chatLoading,
|
|
2938
3169
|
"aria-label": "Send message",
|
|
2939
|
-
children: /* @__PURE__ */
|
|
3170
|
+
children: /* @__PURE__ */ jsx9(ArrowUpIcon3, {})
|
|
2940
3171
|
}
|
|
2941
3172
|
)
|
|
2942
3173
|
] }),
|
|
2943
|
-
/* @__PURE__ */
|
|
3174
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-cb-hint", children: "Akropolys \xB7 instant product knowledge" })
|
|
2944
3175
|
] })
|
|
2945
3176
|
] })
|
|
2946
3177
|
] }),
|
|
2947
|
-
/* @__PURE__ */
|
|
3178
|
+
/* @__PURE__ */ jsx9("div", { className: "hsk-sp-footer", children: /* @__PURE__ */ jsx9("span", { className: "hsk-sp-esc", children: "Esc to close" }) })
|
|
2948
3179
|
] })
|
|
2949
3180
|
}
|
|
2950
3181
|
);
|
|
@@ -2962,9 +3193,9 @@ function Sparkle({
|
|
|
2962
3193
|
product,
|
|
2963
3194
|
children
|
|
2964
3195
|
}) {
|
|
2965
|
-
const [open, setOpen] =
|
|
2966
|
-
const [mounted, setMounted] =
|
|
2967
|
-
|
|
3196
|
+
const [open, setOpen] = useState7(false);
|
|
3197
|
+
const [mounted, setMounted] = useState7(false);
|
|
3198
|
+
useEffect5(() => {
|
|
2968
3199
|
setMounted(true);
|
|
2969
3200
|
}, []);
|
|
2970
3201
|
const customStyles = {
|
|
@@ -2974,8 +3205,8 @@ function Sparkle({
|
|
|
2974
3205
|
...theme?.fontFamily && { "--hsk-font": theme.fontFamily },
|
|
2975
3206
|
...theme?.borderRadius && { "--hsk-border-radius": theme.borderRadius }
|
|
2976
3207
|
};
|
|
2977
|
-
return /* @__PURE__ */
|
|
2978
|
-
/* @__PURE__ */
|
|
3208
|
+
return /* @__PURE__ */ jsxs8(Fragment4, { children: [
|
|
3209
|
+
/* @__PURE__ */ jsx9(
|
|
2979
3210
|
"button",
|
|
2980
3211
|
{
|
|
2981
3212
|
className: cn("hsk-sp-btn", classNames.button, className),
|
|
@@ -2983,11 +3214,11 @@ function Sparkle({
|
|
|
2983
3214
|
style: customStyles,
|
|
2984
3215
|
title: "Find similar products",
|
|
2985
3216
|
"aria-label": "Find similar products",
|
|
2986
|
-
children: children || /* @__PURE__ */
|
|
3217
|
+
children: children || /* @__PURE__ */ jsx9(SparkleIcon3, {})
|
|
2987
3218
|
}
|
|
2988
3219
|
),
|
|
2989
3220
|
open && mounted && createPortal2(
|
|
2990
|
-
/* @__PURE__ */
|
|
3221
|
+
/* @__PURE__ */ jsx9(
|
|
2991
3222
|
SparkleModal,
|
|
2992
3223
|
{
|
|
2993
3224
|
productName,
|