@xinghunm/ai-chat 1.2.1 → 1.2.2

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 CHANGED
@@ -93,7 +93,10 @@ var DEFAULT_AI_CHAT_LABELS = {
93
93
  questionnaireSubmitFailed: "Failed to submit. Please try again.",
94
94
  questionnaireMultiSelectHint: "Multiple choice",
95
95
  questionnaireOtherOptionLabel: "Other",
96
- questionnaireOtherPlaceholder: "Other"
96
+ questionnaireOtherPlaceholder: "Other",
97
+ skillLoading: "Loading skills...",
98
+ skillEmpty: "No matching skills",
99
+ removeSkillAriaLabel: "Remove skill"
97
100
  };
98
101
 
99
102
  // src/lib/chat-session.ts
@@ -406,10 +409,10 @@ var createChatStore = (initialState) => (0, import_vanilla.createStore)((set, ge
406
409
  finalizeStoppedStreamingMessage: (sessionId) => {
407
410
  set((state) => finalizeStreamingMessage(state, sessionId, "stopped", true));
408
411
  },
409
- setSessionError: (sessionId, error) => {
412
+ setSessionError: (sessionId, error2) => {
410
413
  const state = get();
411
414
  set({
412
- errorBySession: { ...state.errorBySession, [sessionId]: error }
415
+ errorBySession: { ...state.errorBySession, [sessionId]: error2 }
413
416
  });
414
417
  },
415
418
  clearSessionError: (sessionId) => {
@@ -462,16 +465,28 @@ var import_axios = __toESM(require("axios"));
462
465
 
463
466
  // src/api/index.ts
464
467
  var CHAT_MODELS_PATH = "/models";
468
+ var CHAT_SKILLS_PATH = "/chat/skills";
465
469
  var CHAT_TERMINATE_PATH = "/chat/terminate";
466
- var getChatModels = async (client, path = CHAT_MODELS_PATH) => {
467
- const response = await client.get(path);
470
+ var getChatModels = async (client, path = CHAT_MODELS_PATH, headers) => {
471
+ const hasHeaders = Boolean(headers && Object.keys(headers).length > 0);
472
+ const response = hasHeaders ? await client.get(path, { headers }) : await client.get(path);
468
473
  return response.data;
469
474
  };
470
- var terminateChat = async (client, sessionId, path = CHAT_TERMINATE_PATH) => {
475
+ var getChatSkills = async (client, path = CHAT_SKILLS_PATH, headers) => {
476
+ const hasHeaders = Boolean(headers && Object.keys(headers).length > 0);
477
+ const response = hasHeaders ? await client.get(path, { headers }) : await client.get(path);
478
+ return response.data;
479
+ };
480
+ var terminateChat = async (client, sessionId, path = CHAT_TERMINATE_PATH, headers) => {
481
+ const resolvedHeaders = {
482
+ ...headers ?? {},
483
+ ...sessionId ? { "X-Session-ID": sessionId } : {}
484
+ };
485
+ const hasHeaders = Object.keys(resolvedHeaders).length > 0;
471
486
  const response = await client.post(
472
487
  path,
473
488
  sessionId ? { session_id: sessionId } : {},
474
- { headers: sessionId ? { "X-Session-ID": sessionId } : void 0 }
489
+ hasHeaders ? { headers: resolvedHeaders } : void 0
475
490
  );
476
491
  return response.data;
477
492
  };
@@ -594,11 +609,11 @@ var startChatStream = async ({
594
609
  onPacket(packet);
595
610
  }
596
611
  }
597
- } catch (error) {
598
- if (error instanceof DOMException && error.name === "AbortError") {
612
+ } catch (error2) {
613
+ if (error2 instanceof DOMException && error2.name === "AbortError") {
599
614
  return;
600
615
  }
601
- const normalizedError = error instanceof Error ? error : new Error("stream error");
616
+ const normalizedError = error2 instanceof Error ? error2 : new Error("stream error");
602
617
  onError?.(normalizedError);
603
618
  throw normalizedError;
604
619
  }
@@ -607,6 +622,7 @@ var startChatStream = async ({
607
622
  // src/transport/default-chat-transport.ts
608
623
  var DEFAULT_CHAT_TRANSPORT_ENDPOINTS = {
609
624
  models: "/models",
625
+ skills: "/chat/skills",
610
626
  completions: "/chat/completions",
611
627
  terminate: "/chat/terminate"
612
628
  };
@@ -654,15 +670,18 @@ var createDefaultRequestBody = async ({
654
670
  model,
655
671
  mode,
656
672
  content,
673
+ skills,
657
674
  attachments
658
675
  }) => {
659
676
  const hasAttachments = Boolean(attachments?.length);
677
+ const skillPayload = skills?.length ? { skill: skills.length === 1 ? skills[0] : skills } : {};
660
678
  if (!hasAttachments) {
661
679
  return {
662
680
  model,
663
681
  mode,
664
682
  stream: true,
665
- messages: [{ role: "user", content }]
683
+ messages: [{ role: "user", content }],
684
+ ...skillPayload
666
685
  };
667
686
  }
668
687
  const imageParts = await Promise.all(
@@ -681,36 +700,49 @@ var createDefaultRequestBody = async ({
681
700
  model,
682
701
  mode,
683
702
  stream: true,
684
- messages: [{ role: "user", content: messageContent }]
703
+ messages: [{ role: "user", content: messageContent }],
704
+ ...skillPayload
685
705
  };
686
706
  };
687
707
  var createDefaultChatTransport = ({
688
708
  apiBaseUrl,
689
709
  authToken,
710
+ headers,
690
711
  toolExecutionPolicy,
691
712
  streamHeaders,
692
713
  resolveModels,
714
+ resolveSkills,
693
715
  buildRequestBody,
694
716
  transformStreamPacket,
695
717
  endpoints,
696
718
  axiosInstance
697
719
  }) => {
698
- const client = axiosInstance ?? import_axios.default.create({ baseURL: apiBaseUrl, headers: { Authorization: authToken } });
720
+ const client = axiosInstance ?? import_axios.default.create({
721
+ baseURL: apiBaseUrl,
722
+ headers: {
723
+ Authorization: authToken,
724
+ ...headers ?? {}
725
+ }
726
+ });
699
727
  const resolvedEndpoints = {
700
728
  ...DEFAULT_CHAT_TRANSPORT_ENDPOINTS,
701
729
  ...endpoints
702
730
  };
731
+ const resolvedHeaders = headers ?? {};
703
732
  const resolvedStreamHeaders = {
704
733
  ...createToolExecutionHeaders(toolExecutionPolicy),
734
+ ...resolvedHeaders,
705
735
  ...streamHeaders
706
736
  };
707
737
  return {
708
- getModels: () => resolveModels?.() ?? getChatModels(client, resolvedEndpoints.models),
738
+ getModels: () => resolveModels?.() ?? getChatModels(client, resolvedEndpoints.models, resolvedHeaders),
739
+ getSkills: () => resolveSkills?.() ?? getChatSkills(client, resolvedEndpoints.skills, resolvedHeaders),
709
740
  startStream: async ({
710
741
  sessionId,
711
742
  model,
712
743
  mode,
713
744
  content,
745
+ skills,
714
746
  attachments,
715
747
  signal,
716
748
  onUpdate,
@@ -727,8 +759,9 @@ var createDefaultChatTransport = ({
727
759
  model,
728
760
  mode,
729
761
  content,
762
+ skills,
730
763
  attachments
731
- }) : await createDefaultRequestBody({ model, mode, content, attachments });
764
+ }) : await createDefaultRequestBody({ model, mode, content, skills, attachments });
732
765
  await startChatStream({
733
766
  apiBaseUrl,
734
767
  endpointPath: resolvedEndpoints.completions,
@@ -753,7 +786,7 @@ var createDefaultChatTransport = ({
753
786
  }
754
787
  });
755
788
  },
756
- terminateStream: (sessionId) => terminateChat(client, sessionId, resolvedEndpoints.terminate)
789
+ terminateStream: (sessionId) => terminateChat(client, sessionId, resolvedEndpoints.terminate, resolvedHeaders)
757
790
  };
758
791
  };
759
792
 
@@ -1102,9 +1135,9 @@ var useChatMessageReveal = (message) => {
1102
1135
  }, [batchedTargetUnitCount, displayedUnitCount, isAssistantStreaming, message.role]);
1103
1136
  const settledContent = isFreshBlockActive ? contentBlocks.slice(0, -1).join("\n\n") : displayedContent;
1104
1137
  const freshContent = isFreshBlockActive ? contentBlocks[contentBlocks.length - 1] ?? "" : "";
1105
- const displayedBlocks = isAssistantStreaming && contentBlocks.length > 1 ? contentBlocks.map((content, index) => ({
1138
+ const displayedBlocks = isAssistantStreaming && contentBlocks.length > 1 ? contentBlocks.map((content, index3) => ({
1106
1139
  content,
1107
- tone: isFreshBlockActive && index === contentBlocks.length - 1 ? "fresh" : "settled"
1140
+ tone: isFreshBlockActive && index3 === contentBlocks.length - 1 ? "fresh" : "settled"
1108
1141
  })) : [
1109
1142
  {
1110
1143
  content: displayedContent,
@@ -1137,22 +1170,22 @@ var stringifyTimelineKeyPart = (value) => {
1137
1170
  }
1138
1171
  return String(value);
1139
1172
  };
1140
- var getTimelineBlockKey = (block, index) => {
1173
+ var getTimelineBlockKey = (block, index3) => {
1141
1174
  switch (block.type) {
1142
1175
  case "markdown":
1143
1176
  return null;
1144
1177
  case "notice":
1145
- return `${index}:notice:${block.tone}:${block.text}`;
1178
+ return `${index3}:notice:${block.tone}:${block.text}`;
1146
1179
  case "parameter_summary":
1147
- return `${index}:parameter_summary:${block.items.map((item) => `${item.label}:${item.value}:${item.fieldPath ?? ""}`).join("|")}`;
1180
+ return `${index3}:parameter_summary:${block.items.map((item) => `${item.label}:${item.value}:${item.fieldPath ?? ""}`).join("|")}`;
1148
1181
  case "confirmation_card":
1149
- return `${index}:confirmation_card:${block.proposal.proposalId}`;
1182
+ return `${index3}:confirmation_card:${block.proposal.proposalId}`;
1150
1183
  case "result_summary":
1151
- return `${index}:result_summary:${block.summary.summaryId}:${block.summary.status}`;
1184
+ return `${index3}:result_summary:${block.summary.summaryId}:${block.summary.status}`;
1152
1185
  case "questionnaire":
1153
- return block.questionnaire.blockKey ? `questionnaire:${block.questionnaire.blockKey}` : `${index}:questionnaire:${block.questionnaire.questionnaireId}`;
1186
+ return block.questionnaire.blockKey ? `questionnaire:${block.questionnaire.blockKey}` : `${index3}:questionnaire:${block.questionnaire.questionnaireId}`;
1154
1187
  case "custom":
1155
- return block.blockKey ? `custom:${block.blockKey}` : `${index}:custom:${block.kind}:${stringifyTimelineKeyPart(block.data)}`;
1188
+ return block.blockKey ? `custom:${block.blockKey}` : `${index3}:custom:${block.kind}:${stringifyTimelineKeyPart(block.data)}`;
1156
1189
  default:
1157
1190
  return null;
1158
1191
  }
@@ -1171,9 +1204,9 @@ var buildTimelineTextDisplay = (content, isAssistantStreaming, isFreshBlockActiv
1171
1204
  const contentBlocks = splitMarkdownBlocks(content);
1172
1205
  const settledContent = isAssistantStreaming && isFreshBlockActive && contentBlocks.length > 1 ? contentBlocks.slice(0, -1).join("\n\n") : content;
1173
1206
  const freshContent = isAssistantStreaming && isFreshBlockActive && contentBlocks.length > 1 ? contentBlocks[contentBlocks.length - 1] ?? "" : "";
1174
- const displayedBlocks = contentBlocks.length > 1 ? contentBlocks.map((blockContent, index) => ({
1207
+ const displayedBlocks = contentBlocks.length > 1 ? contentBlocks.map((blockContent, index3) => ({
1175
1208
  content: blockContent,
1176
- tone: isAssistantStreaming && isFreshBlockActive && freshContent && index === contentBlocks.length - 1 ? "fresh" : "settled"
1209
+ tone: isAssistantStreaming && isFreshBlockActive && freshContent && index3 === contentBlocks.length - 1 ? "fresh" : "settled"
1177
1210
  })) : [{ content, tone: "settled" }];
1178
1211
  return {
1179
1212
  settledContent,
@@ -1181,7 +1214,7 @@ var buildTimelineTextDisplay = (content, isAssistantStreaming, isFreshBlockActiv
1181
1214
  displayedBlocks
1182
1215
  };
1183
1216
  };
1184
- var getTimelineDisplayUnitCount = (content) => splitMarkdownBlocks(content).reduce((count, block) => count + Array.from(block).length, 0);
1217
+ var getTimelineDisplayUnitCount = (content) => splitMarkdownBlocks(content).reduce((count2, block) => count2 + Array.from(block).length, 0);
1185
1218
  var buildAnchoredTimelineSegments = ({
1186
1219
  blocks,
1187
1220
  timelineBlockAnchors,
@@ -1190,7 +1223,7 @@ var buildAnchoredTimelineSegments = ({
1190
1223
  }) => {
1191
1224
  const orderedTimelineSegments = [];
1192
1225
  const totalTimelineUnits = timelineDisplayedBlocks.reduce(
1193
- (count, block) => count + Array.from(block.content).length,
1226
+ (count2, block) => count2 + Array.from(block.content).length,
1194
1227
  0
1195
1228
  );
1196
1229
  let textCursor = 0;
@@ -1234,7 +1267,7 @@ var buildAnchoredTimelineSegments = ({
1234
1267
  };
1235
1268
  };
1236
1269
  let trailingCutoff = totalTimelineUnits;
1237
- for (const [index, block] of blocks.entries()) {
1270
+ for (const [index3, block] of blocks.entries()) {
1238
1271
  if (block.type === "markdown") {
1239
1272
  orderedTimelineSegments.push({
1240
1273
  type: "markdown",
@@ -1242,7 +1275,7 @@ var buildAnchoredTimelineSegments = ({
1242
1275
  });
1243
1276
  continue;
1244
1277
  }
1245
- const blockKey = getTimelineBlockKey(block, index);
1278
+ const blockKey = getTimelineBlockKey(block, index3);
1246
1279
  const anchor = blockKey !== null ? timelineBlockAnchors[blockKey] ?? totalTimelineUnits : totalTimelineUnits;
1247
1280
  const isBlockVisible = blockKey !== null && visibleTimelineBlockKeys?.[blockKey] ? true : anchor <= totalTimelineUnits;
1248
1281
  if (anchor > textCursor) {
@@ -1262,7 +1295,7 @@ var buildAnchoredTimelineSegments = ({
1262
1295
  orderedTimelineSegments.push({
1263
1296
  type: "block",
1264
1297
  block,
1265
- index
1298
+ index: index3
1266
1299
  });
1267
1300
  textCursor = Math.max(textCursor, anchor);
1268
1301
  }
@@ -1310,7 +1343,7 @@ var timelineAnchorReducer = (state, action) => {
1310
1343
  ([blockKey, anchor]) => state.timelineBlockAnchors[blockKey] !== anchor
1311
1344
  );
1312
1345
  const hasPreviousKeysChanged = action.currentBlockKeys.length !== state.previousBlockKeys.length || action.currentBlockKeys.some(
1313
- (blockKey, index) => state.previousBlockKeys[index] !== blockKey
1346
+ (blockKey, index3) => state.previousBlockKeys[index3] !== blockKey
1314
1347
  );
1315
1348
  if (!hasAnchorChanged && !hasPreviousKeysChanged) {
1316
1349
  return state;
@@ -1359,7 +1392,7 @@ var useTimelineBlockAnchors = ({
1359
1392
  messageRenderOrder
1360
1393
  }) => {
1361
1394
  const currentTimelineBlockKeys = (0, import_react6.useMemo)(
1362
- () => blocks.map((block, index) => getTimelineBlockKey(block, index)).filter((blockKey) => Boolean(blockKey)),
1395
+ () => blocks.map((block, index3) => getTimelineBlockKey(block, index3)).filter((blockKey) => Boolean(blockKey)),
1363
1396
  [blocks]
1364
1397
  );
1365
1398
  const timelineTextStreamLength = (0, import_react6.useMemo)(
@@ -1781,11 +1814,11 @@ var toggleMultiSelectOtherAnswer = (current, question) => {
1781
1814
  };
1782
1815
  var getTextInputValue = (answer) => typeof answer === "string" ? String(answer) : "";
1783
1816
  var getNumberInputValue = (answer) => typeof answer === "number" || typeof answer === "string" ? String(answer) : "";
1784
- var getOptionChoiceLabel = (index) => {
1785
- if (index < 26) {
1786
- return String.fromCharCode(65 + index);
1817
+ var getOptionChoiceLabel = (index3) => {
1818
+ if (index3 < 26) {
1819
+ return String.fromCharCode(65 + index3);
1787
1820
  }
1788
- return String(index + 1);
1821
+ return String(index3 + 1);
1789
1822
  };
1790
1823
  var normalizeQuestionAnswer = (question, answer, otherDraft = "") => {
1791
1824
  if (answer === void 0) {
@@ -1962,7 +1995,7 @@ var stopInputKeyPropagation = (event) => {
1962
1995
  var OptionChoice = ({
1963
1996
  questionId,
1964
1997
  optionLabel,
1965
- index,
1998
+ index: index3,
1966
1999
  isSelected,
1967
2000
  isInteractionLocked,
1968
2001
  onClick,
@@ -1976,7 +2009,7 @@ var OptionChoice = ({
1976
2009
  "aria-pressed": isSelected,
1977
2010
  "data-selected": isSelected,
1978
2011
  "data-tone": tone,
1979
- "data-testid": `question-option-${questionId}-${index}`,
2012
+ "data-testid": `question-option-${questionId}-${index3}`,
1980
2013
  onClick: (event) => {
1981
2014
  if (isInteractionLocked) {
1982
2015
  return;
@@ -1997,7 +2030,7 @@ var OptionChoice = ({
1997
2030
  onClick();
1998
2031
  },
1999
2032
  children: [
2000
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(OptionChoiceMarker, { "data-selected": isSelected, children: getOptionChoiceLabel(index) }),
2033
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(OptionChoiceMarker, { "data-selected": isSelected, children: getOptionChoiceLabel(index3) }),
2001
2034
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(OptionChoiceContent, { children: [
2002
2035
  inlineInput ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(OptionChoiceLabel, { children: optionLabel }),
2003
2036
  inlineInput
@@ -2074,8 +2107,8 @@ var QuestionnaireCardInner = ({
2074
2107
  content
2075
2108
  });
2076
2109
  setIsSubmitted(true);
2077
- } catch (error) {
2078
- setErrorMessage(error instanceof Error ? error.message : resolvedLabels.submitFailed);
2110
+ } catch (error2) {
2111
+ setErrorMessage(error2 instanceof Error ? error2.message : resolvedLabels.submitFailed);
2079
2112
  } finally {
2080
2113
  setIsSubmitting(false);
2081
2114
  }
@@ -2092,14 +2125,14 @@ var QuestionnaireCardInner = ({
2092
2125
  otherDrafts[questionToRender.id] ?? ""
2093
2126
  );
2094
2127
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(QuestionBody, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(OptionList, { children: [
2095
- questionToRender.options.map((option, index) => {
2128
+ questionToRender.options.map((option, index3) => {
2096
2129
  const isSelected = multiSelectDraft.selectedValues.includes(option.value);
2097
2130
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2098
2131
  OptionChoice,
2099
2132
  {
2100
2133
  questionId: questionToRender.id,
2101
2134
  optionLabel: option.label,
2102
- index,
2135
+ index: index3,
2103
2136
  isSelected,
2104
2137
  isInteractionLocked,
2105
2138
  onClick: () => setAnswers(
@@ -2157,14 +2190,14 @@ var QuestionnaireCardInner = ({
2157
2190
  otherDrafts[questionToRender.id] ?? ""
2158
2191
  );
2159
2192
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(QuestionBody, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(OptionList, { children: [
2160
- questionToRender.options.map((option, index) => {
2193
+ questionToRender.options.map((option, index3) => {
2161
2194
  const isSelected = singleSelectDraft.selectedValue === option.value;
2162
2195
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2163
2196
  OptionChoice,
2164
2197
  {
2165
2198
  questionId: questionToRender.id,
2166
2199
  optionLabel: option.label,
2167
- index,
2200
+ index: index3,
2168
2201
  isSelected,
2169
2202
  isInteractionLocked,
2170
2203
  onClick: () => setAnswers(
@@ -2730,20 +2763,20 @@ var areChatAttachmentsEqual = (previousAttachments, nextAttachments) => {
2730
2763
  if (previousAttachments.length !== nextAttachments.length) {
2731
2764
  return false;
2732
2765
  }
2733
- return previousAttachments.every((attachment, index) => {
2734
- const nextAttachment = nextAttachments[index];
2766
+ return previousAttachments.every((attachment, index3) => {
2767
+ const nextAttachment = nextAttachments[index3];
2735
2768
  return attachment.id === nextAttachment?.id && attachment.name === nextAttachment.name && attachment.mimeType === nextAttachment.mimeType && attachment.size === nextAttachment.size && attachment.previewUrl === nextAttachment.previewUrl;
2736
2769
  });
2737
2770
  };
2738
- var areParameterSummaryItemsEqual = (previousItems, nextItems) => previousItems.length === nextItems.length && previousItems.every((item, index) => {
2739
- const nextItem = nextItems[index];
2771
+ var areParameterSummaryItemsEqual = (previousItems, nextItems) => previousItems.length === nextItems.length && previousItems.every((item, index3) => {
2772
+ const nextItem = nextItems[index3];
2740
2773
  return item.label === nextItem?.label && item.value === nextItem.value && item.fieldPath === nextItem.fieldPath;
2741
2774
  });
2742
2775
  var areExecutionProposalsEqual = (previousProposal, nextProposal) => previousProposal.proposalId === nextProposal.proposalId && previousProposal.resourceKey === nextProposal.resourceKey && previousProposal.resourceName === nextProposal.resourceName && previousProposal.executorName === nextProposal.executorName && previousProposal.requiresConfirmation === nextProposal.requiresConfirmation && areParameterSummaryItemsEqual(previousProposal.parameterSummary, nextProposal.parameterSummary) && (previousProposal.warnings ?? []).length === (nextProposal.warnings ?? []).length && (previousProposal.warnings ?? []).every(
2743
- (warning, index) => warning === nextProposal.warnings?.[index]
2776
+ (warning, index3) => warning === nextProposal.warnings?.[index3]
2744
2777
  );
2745
- var areResultSummariesEqual = (previousSummary, nextSummary) => previousSummary.summaryId === nextSummary.summaryId && previousSummary.status === nextSummary.status && previousSummary.headline === nextSummary.headline && previousSummary.details.length === nextSummary.details.length && previousSummary.details.every((detail, index) => detail === nextSummary.details[index]);
2746
- var areStringArraysEqual = (previousValues, nextValues) => previousValues.length === nextValues.length && previousValues.every((value, index) => value === nextValues[index]);
2778
+ var areResultSummariesEqual = (previousSummary, nextSummary) => previousSummary.summaryId === nextSummary.summaryId && previousSummary.status === nextSummary.status && previousSummary.headline === nextSummary.headline && previousSummary.details.length === nextSummary.details.length && previousSummary.details.every((detail, index3) => detail === nextSummary.details[index3]);
2779
+ var areStringArraysEqual = (previousValues, nextValues) => previousValues.length === nextValues.length && previousValues.every((value, index3) => value === nextValues[index3]);
2747
2780
  var areQuestionAnswersEqual = (previousAnswer, nextAnswer) => {
2748
2781
  if (Array.isArray(previousAnswer) || Array.isArray(nextAnswer)) {
2749
2782
  return Array.isArray(previousAnswer) && Array.isArray(nextAnswer) && areStringArraysEqual(previousAnswer, nextAnswer);
@@ -2762,7 +2795,7 @@ var areQuestionAnswerMapsEqual = (previousAnswers, nextAnswers) => {
2762
2795
  return previousKeys.length === nextKeys.length && previousKeys.every((key) => areQuestionAnswersEqual(previousAnswers[key], nextAnswers[key]));
2763
2796
  };
2764
2797
  var areQuestionOptionsEqual = (previousOptions, nextOptions) => previousOptions.length === nextOptions.length && previousOptions.every(
2765
- (option, index) => option.label === nextOptions[index]?.label && option.value === nextOptions[index]?.value
2798
+ (option, index3) => option.label === nextOptions[index3]?.label && option.value === nextOptions[index3]?.value
2766
2799
  );
2767
2800
  var arePlanQuestionsEqual = (previousQuestion, nextQuestion) => {
2768
2801
  if (previousQuestion.id !== nextQuestion.id || previousQuestion.label !== nextQuestion.label || previousQuestion.required !== nextQuestion.required || previousQuestion.kind !== nextQuestion.kind) {
@@ -2794,8 +2827,8 @@ var areMessageBlocksEqual = (previousBlocks, nextBlocks) => {
2794
2827
  if (previousBlocks.length !== nextBlocks.length) {
2795
2828
  return false;
2796
2829
  }
2797
- return previousBlocks.every((block, index) => {
2798
- const nextBlock = nextBlocks[index];
2830
+ return previousBlocks.every((block, index3) => {
2831
+ const nextBlock = nextBlocks[index3];
2799
2832
  if (!nextBlock || block.type !== nextBlock.type) {
2800
2833
  return false;
2801
2834
  }
@@ -2895,23 +2928,23 @@ var ChatMessageItemView = ({
2895
2928
  settledContent
2896
2929
  });
2897
2930
  const renderMessageContent = (content) => messageRenderMode === "plain-text" ? renderPlainTextContent(content) : renderMarkdownContent(content);
2898
- const renderChatMessageBlock = (block, index) => {
2931
+ const renderChatMessageBlock = (block, index3) => {
2899
2932
  switch (block.type) {
2900
2933
  case "markdown":
2901
2934
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2902
2935
  ContentBlock,
2903
2936
  {
2904
- "data-testid": `chat-message-block-${index}`,
2937
+ "data-testid": `chat-message-block-${index3}`,
2905
2938
  "data-block-tone": "settled",
2906
2939
  "data-render-mode": messageRenderMode,
2907
2940
  children: renderMessageContent(block.text)
2908
2941
  },
2909
- `markdown-${index}`
2942
+ `markdown-${index3}`
2910
2943
  );
2911
2944
  case "notice":
2912
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NoticeCard, { text: block.text, tone: block.tone }) }, `notice-${index}`);
2945
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(NoticeCard, { text: block.text, tone: block.tone }) }, `notice-${index3}`);
2913
2946
  case "parameter_summary":
2914
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ParameterSummaryCard, { items: block.items }) }, `parameter-summary-${index}`);
2947
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ParameterSummaryCard, { items: block.items }) }, `parameter-summary-${index3}`);
2915
2948
  case "confirmation_card":
2916
2949
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2917
2950
  ExecutionConfirmationCard,
@@ -2924,9 +2957,9 @@ var ChatMessageItemView = ({
2924
2957
  sourceMessageId: message.id
2925
2958
  }) : void 0
2926
2959
  }
2927
- ) }, `confirmation-card-${index}`);
2960
+ ) }, `confirmation-card-${index3}`);
2928
2961
  case "result_summary":
2929
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ResultSummaryCard, { summary: block.summary }) }, `result-summary-${index}`);
2962
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ResultSummaryCard, { summary: block.summary }) }, `result-summary-${index3}`);
2930
2963
  case "questionnaire":
2931
2964
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2932
2965
  QuestionnaireCard,
@@ -2947,16 +2980,16 @@ var ChatMessageItemView = ({
2947
2980
  sourceMessageId: message.id
2948
2981
  }) : void 0
2949
2982
  }
2950
- ) }, block.questionnaire.blockKey ?? `questionnaire-${index}`);
2983
+ ) }, block.questionnaire.blockKey ?? `questionnaire-${index3}`);
2951
2984
  case "custom":
2952
2985
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: renderMessageBlock?.({
2953
2986
  block,
2954
- index,
2987
+ index: index3,
2955
2988
  message,
2956
2989
  mode,
2957
2990
  onConfirmationSubmit,
2958
2991
  onQuestionnaireSubmit
2959
- }) ?? null }, `custom-${block.kind}-${index}`);
2992
+ }) ?? null }, `custom-${block.kind}-${index3}`);
2960
2993
  default:
2961
2994
  return null;
2962
2995
  }
@@ -2968,16 +3001,16 @@ var ChatMessageItemView = ({
2968
3001
  const settledText = localTimelineTextDisplay?.settledContent ?? settledContent;
2969
3002
  const freshText = localTimelineTextDisplay?.freshContent ?? freshContent;
2970
3003
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
2971
- textBlocks.filter((block) => block.content).map((block, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3004
+ textBlocks.filter((block) => block.content).map((block, index3) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2972
3005
  ContentBlock,
2973
3006
  {
2974
3007
  "data-testid": block.tone === "fresh" ? "chat-message-fresh-block" : "chat-message-settled-block",
2975
3008
  "data-block-tone": block.tone,
2976
- "data-block-index": index,
3009
+ "data-block-index": index3,
2977
3010
  "data-render-mode": messageRenderMode,
2978
3011
  children: renderMessageContent(block.content)
2979
3012
  },
2980
- `${block.tone}-${index}`
3013
+ `${block.tone}-${index3}`
2981
3014
  )),
2982
3015
  !textBlocks.some((block) => block.content) && !settledText && !freshText && Boolean(textContent) ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2983
3016
  ContentBlock,
@@ -3007,8 +3040,8 @@ var ChatMessageItemView = ({
3007
3040
  return [];
3008
3041
  }
3009
3042
  if (messageRenderOrder === "timeline" && hasTextContent) {
3010
- const hasAnchoredStructuredBlocks = blocks.some((block, index) => {
3011
- const blockKey = getTimelineBlockKey(block, index);
3043
+ const hasAnchoredStructuredBlocks = blocks.some((block, index3) => {
3044
+ const blockKey = getTimelineBlockKey(block, index3);
3012
3045
  return blockKey ? timelineBlockAnchors[blockKey] !== void 0 : false;
3013
3046
  });
3014
3047
  if (hasAnchoredStructuredBlocks) {
@@ -3020,13 +3053,13 @@ var ChatMessageItemView = ({
3020
3053
  });
3021
3054
  }
3022
3055
  const orderedTimelineSegments = blocks.map(
3023
- (block, index) => block.type === "markdown" ? {
3056
+ (block, index3) => block.type === "markdown" ? {
3024
3057
  type: "markdown",
3025
3058
  content: block.text
3026
3059
  } : {
3027
3060
  type: "block",
3028
3061
  block,
3029
- index
3062
+ index: index3
3030
3063
  }
3031
3064
  );
3032
3065
  if (!timelineConsumedText) {
@@ -3034,10 +3067,10 @@ var ChatMessageItemView = ({
3034
3067
  }
3035
3068
  return timelineDisplayedContent ? [...orderedTimelineSegments, { type: "text", content: timelineDisplayedContent }] : orderedTimelineSegments;
3036
3069
  }
3037
- const orderedBlocks = blocks.map((block, index) => ({
3070
+ const orderedBlocks = blocks.map((block, index3) => ({
3038
3071
  type: "block",
3039
3072
  block,
3040
- index
3073
+ index: index3
3041
3074
  }));
3042
3075
  return hasTextContent ? [...orderedBlocks, { type: "text" }] : orderedBlocks;
3043
3076
  })();
@@ -3076,7 +3109,7 @@ var ChatMessageItemView = ({
3076
3109
  ref: bodyStackRef,
3077
3110
  "data-testid": "chat-message-body-stack",
3078
3111
  "data-collapsed": isUserMessageCollapsed,
3079
- children: bodySegments.map((segment, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3112
+ children: bodySegments.map((segment, index3) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3080
3113
  ContentSegment,
3081
3114
  {
3082
3115
  "data-testid": "chat-message-content-segment",
@@ -3086,7 +3119,7 @@ var ChatMessageItemView = ({
3086
3119
  useTimelineSegmentation: true
3087
3120
  }) : renderStaticTextSegment(segment.content) : renderTextContent() : renderStaticTextSegment(segment.content)
3088
3121
  },
3089
- segment.type === "text" ? `text-${index}` : segment.type === "markdown" ? `markdown-${index}` : `${segment.block.type}-${segment.index}`
3122
+ segment.type === "text" ? `text-${index3}` : segment.type === "markdown" ? `markdown-${index3}` : `${segment.block.type}-${segment.index}`
3090
3123
  ))
3091
3124
  }
3092
3125
  ) : null,
@@ -3485,11 +3518,11 @@ var renderChatMessage = ({
3485
3518
  }
3486
3519
  );
3487
3520
  var renderErrorState = ({
3488
- error,
3521
+ error: error2,
3489
3522
  onRetry,
3490
3523
  retryButtonLabel
3491
3524
  }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(ErrorState, { "data-testid": "chat-thread-error-state", children: [
3492
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ErrorText, { children: error }),
3525
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ErrorText, { children: error2 }),
3493
3526
  onRetry ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ErrorActions, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(RetryButton, { type: "button", "data-testid": "chat-thread-retry", onClick: onRetry, children: retryButtonLabel }) }) : null
3494
3527
  ] });
3495
3528
  var groupConversationTurns = (historyMessages, streamingMessage) => {
@@ -3539,7 +3572,7 @@ var ChatThreadView = ({
3539
3572
  activeSessionMode = DEFAULT_CHAT_AGENT_MODE,
3540
3573
  historyMessages,
3541
3574
  streamingMessage,
3542
- error,
3575
+ error: error2,
3543
3576
  retryButtonLabel,
3544
3577
  scrollToLatestLabel,
3545
3578
  onRetry,
@@ -3683,7 +3716,7 @@ var ChatThreadView = ({
3683
3716
  reservedSpaceFrameRef.current = null;
3684
3717
  }
3685
3718
  };
3686
- }, [latestTurn, latestUserMessageId, error, measureLatestTurnMinHeight, scrollToBottom]);
3719
+ }, [latestTurn, latestUserMessageId, error2, measureLatestTurnMinHeight, scrollToBottom]);
3687
3720
  (0, import_react11.useLayoutEffect)(() => {
3688
3721
  if (!latestTurn)
3689
3722
  return;
@@ -3786,11 +3819,11 @@ var ChatThreadView = ({
3786
3819
  onQuestionnaireSubmit,
3787
3820
  renderMessageBlock
3788
3821
  }) }, message.id)),
3789
- error ? renderErrorState({ error, onRetry, retryButtonLabel }) : null
3822
+ error2 ? renderErrorState({ error: error2, onRetry, retryButtonLabel }) : null
3790
3823
  ]
3791
3824
  }
3792
3825
  ) : null,
3793
- !latestTurn && error ? renderErrorState({ error, onRetry, retryButtonLabel }) : null
3826
+ !latestTurn && error2 ? renderErrorState({ error: error2, onRetry, retryButtonLabel }) : null
3794
3827
  ] }),
3795
3828
  isDetached ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ScrollToLatestOverlay, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
3796
3829
  ScrollToLatestButton,
@@ -3817,7 +3850,7 @@ var ChatThread = () => {
3817
3850
  (s) => s.messagesBySession[s.activeSessionId ?? ""] ?? EMPTY_MESSAGES
3818
3851
  );
3819
3852
  const streamingMessage = useChatStore((s) => s.streamingMessageBySession[s.activeSessionId ?? ""]);
3820
- const error = useChatStore((s) => s.errorBySession[s.activeSessionId ?? ""]);
3853
+ const error2 = useChatStore((s) => s.errorBySession[s.activeSessionId ?? ""]);
3821
3854
  const updateQA = useChatStore((s) => s.updateQuestionnaireAnswers);
3822
3855
  const clearSessionError = useChatStore((s) => s.clearSessionError);
3823
3856
  const {
@@ -3897,7 +3930,7 @@ var ChatThread = () => {
3897
3930
  activeSessionMode,
3898
3931
  historyMessages: messages,
3899
3932
  streamingMessage,
3900
- error,
3933
+ error: error2,
3901
3934
  retryButtonLabel: labels.retryButton,
3902
3935
  scrollToLatestLabel: labels.scrollToLatest,
3903
3936
  onRetry: handleRetry,
@@ -4017,276 +4050,2860 @@ var ScrollToLatestBadge = import_styled9.default.span`
4017
4050
  `;
4018
4051
 
4019
4052
  // src/components/chat-composer/index.tsx
4020
- var import_react15 = require("react");
4053
+ var import_react17 = require("react");
4021
4054
  var import_styled14 = __toESM(require("@emotion/styled"));
4022
4055
 
4023
- // src/components/chat-composer/lib/chat-composer.ts
4024
- var createUserMessage = ({
4025
- sessionId,
4026
- content,
4027
- attachments,
4028
- localOnly,
4029
- createdAt,
4030
- createMessageId
4031
- }) => ({
4032
- id: createMessageId(),
4033
- sessionId,
4034
- role: "user",
4035
- content,
4036
- attachments,
4037
- localOnly,
4038
- createdAt
4039
- });
4040
- var createAssistantStreamingMessage = ({
4041
- sessionId,
4042
- createdAt,
4043
- createMessageId
4044
- }) => ({
4045
- id: createMessageId(),
4046
- sessionId,
4047
- role: "assistant",
4048
- content: "",
4049
- status: "streaming",
4050
- createdAt
4051
- });
4052
- var canSendChatMessage = ({
4053
- value,
4054
- attachmentCount = 0,
4055
- isModelsLoading,
4056
- isModelsError,
4057
- hasModels
4058
- }) => {
4059
- const hasText = Boolean(value.trim());
4060
- const hasAttachments = attachmentCount > 0;
4061
- if (!hasText && !hasAttachments)
4056
+ // ../../node_modules/.pnpm/@floating-ui+react@0.27.16_react-dom@18.3.1_react@18.3.1/node_modules/@floating-ui/react/dist/floating-ui.react.mjs
4057
+ var React3 = __toESM(require("react"), 1);
4058
+
4059
+ // ../../node_modules/.pnpm/@floating-ui+utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs
4060
+ function hasWindow() {
4061
+ return typeof window !== "undefined";
4062
+ }
4063
+ function getNodeName(node) {
4064
+ if (isNode(node)) {
4065
+ return (node.nodeName || "").toLowerCase();
4066
+ }
4067
+ return "#document";
4068
+ }
4069
+ function getWindow(node) {
4070
+ var _node$ownerDocument;
4071
+ return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
4072
+ }
4073
+ function getDocumentElement(node) {
4074
+ var _ref;
4075
+ return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
4076
+ }
4077
+ function isNode(value) {
4078
+ if (!hasWindow()) {
4062
4079
  return false;
4063
- if (!hasText && hasAttachments)
4064
- return true;
4065
- return !isModelsLoading && !isModelsError && hasModels;
4066
- };
4067
- var shouldSubmitChatComposer = ({
4068
- key,
4069
- shiftKey,
4070
- canSend
4071
- }) => key === "Enter" && !shiftKey && canSend;
4072
- var shouldStopChatComposer = ({
4073
- key,
4074
- shiftKey,
4075
- isStreaming
4076
- }) => key === "Enter" && !shiftKey && isStreaming;
4077
- var resolveSelectedChatModel = ({
4078
- currentModel,
4079
- availableModels,
4080
- isModelsLoading
4081
- }) => {
4082
- if (!availableModels.length) {
4083
- return isModelsLoading ? currentModel : "";
4084
4080
  }
4085
- if (currentModel && availableModels.some((model) => model.id === currentModel)) {
4086
- return currentModel;
4081
+ return value instanceof Node || value instanceof getWindow(value).Node;
4082
+ }
4083
+ function isElement(value) {
4084
+ if (!hasWindow()) {
4085
+ return false;
4087
4086
  }
4088
- return availableModels[0].id;
4089
- };
4090
- var resolveSendSession = ({
4091
- activeSessionId,
4092
- selectedModel,
4093
- selectedMode,
4094
- nowIso: nowIso2,
4095
- createSessionId
4096
- }) => {
4097
- if (activeSessionId) {
4087
+ return value instanceof Element || value instanceof getWindow(value).Element;
4088
+ }
4089
+ function isHTMLElement(value) {
4090
+ if (!hasWindow()) {
4091
+ return false;
4092
+ }
4093
+ return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
4094
+ }
4095
+ function isShadowRoot(value) {
4096
+ if (!hasWindow() || typeof ShadowRoot === "undefined") {
4097
+ return false;
4098
+ }
4099
+ return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
4100
+ }
4101
+ var invalidOverflowDisplayValues = /* @__PURE__ */ new Set(["inline", "contents"]);
4102
+ function isOverflowElement(element) {
4103
+ const {
4104
+ overflow,
4105
+ overflowX,
4106
+ overflowY,
4107
+ display
4108
+ } = getComputedStyle2(element);
4109
+ return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !invalidOverflowDisplayValues.has(display);
4110
+ }
4111
+ var tableElements = /* @__PURE__ */ new Set(["table", "td", "th"]);
4112
+ function isTableElement(element) {
4113
+ return tableElements.has(getNodeName(element));
4114
+ }
4115
+ var topLayerSelectors = [":popover-open", ":modal"];
4116
+ function isTopLayer(element) {
4117
+ return topLayerSelectors.some((selector) => {
4118
+ try {
4119
+ return element.matches(selector);
4120
+ } catch (_e) {
4121
+ return false;
4122
+ }
4123
+ });
4124
+ }
4125
+ var transformProperties = ["transform", "translate", "scale", "rotate", "perspective"];
4126
+ var willChangeValues = ["transform", "translate", "scale", "rotate", "perspective", "filter"];
4127
+ var containValues = ["paint", "layout", "strict", "content"];
4128
+ function isContainingBlock(elementOrCss) {
4129
+ const webkit = isWebKit();
4130
+ const css = isElement(elementOrCss) ? getComputedStyle2(elementOrCss) : elementOrCss;
4131
+ return transformProperties.some((value) => css[value] ? css[value] !== "none" : false) || (css.containerType ? css.containerType !== "normal" : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== "none" : false) || !webkit && (css.filter ? css.filter !== "none" : false) || willChangeValues.some((value) => (css.willChange || "").includes(value)) || containValues.some((value) => (css.contain || "").includes(value));
4132
+ }
4133
+ function getContainingBlock(element) {
4134
+ let currentNode = getParentNode(element);
4135
+ while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
4136
+ if (isContainingBlock(currentNode)) {
4137
+ return currentNode;
4138
+ } else if (isTopLayer(currentNode)) {
4139
+ return null;
4140
+ }
4141
+ currentNode = getParentNode(currentNode);
4142
+ }
4143
+ return null;
4144
+ }
4145
+ function isWebKit() {
4146
+ if (typeof CSS === "undefined" || !CSS.supports)
4147
+ return false;
4148
+ return CSS.supports("-webkit-backdrop-filter", "none");
4149
+ }
4150
+ var lastTraversableNodeNames = /* @__PURE__ */ new Set(["html", "body", "#document"]);
4151
+ function isLastTraversableNode(node) {
4152
+ return lastTraversableNodeNames.has(getNodeName(node));
4153
+ }
4154
+ function getComputedStyle2(element) {
4155
+ return getWindow(element).getComputedStyle(element);
4156
+ }
4157
+ function getNodeScroll(element) {
4158
+ if (isElement(element)) {
4098
4159
  return {
4099
- localSessionId: activeSessionId,
4100
- sessionId: isDraftChatSessionId(activeSessionId) ? void 0 : activeSessionId
4160
+ scrollLeft: element.scrollLeft,
4161
+ scrollTop: element.scrollTop
4101
4162
  };
4102
4163
  }
4103
- const session = createDraftChatSession({
4104
- model: selectedModel,
4105
- mode: selectedMode ?? DEFAULT_CHAT_AGENT_MODE,
4106
- nowIso: nowIso2,
4107
- createSessionId
4108
- });
4109
- return { session, localSessionId: session.sessionId, sessionId: void 0 };
4110
- };
4111
-
4112
- // src/components/chat-composer/hooks/use-chat-composer.ts
4113
- var import_react13 = require("react");
4164
+ return {
4165
+ scrollLeft: element.scrollX,
4166
+ scrollTop: element.scrollY
4167
+ };
4168
+ }
4169
+ function getParentNode(node) {
4170
+ if (getNodeName(node) === "html") {
4171
+ return node;
4172
+ }
4173
+ const result = (
4174
+ // Step into the shadow DOM of the parent of a slotted node.
4175
+ node.assignedSlot || // DOM Element detected.
4176
+ node.parentNode || // ShadowRoot detected.
4177
+ isShadowRoot(node) && node.host || // Fallback.
4178
+ getDocumentElement(node)
4179
+ );
4180
+ return isShadowRoot(result) ? result.host : result;
4181
+ }
4182
+ function getNearestOverflowAncestor(node) {
4183
+ const parentNode = getParentNode(node);
4184
+ if (isLastTraversableNode(parentNode)) {
4185
+ return node.ownerDocument ? node.ownerDocument.body : node.body;
4186
+ }
4187
+ if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
4188
+ return parentNode;
4189
+ }
4190
+ return getNearestOverflowAncestor(parentNode);
4191
+ }
4192
+ function getOverflowAncestors(node, list, traverseIframes) {
4193
+ var _node$ownerDocument2;
4194
+ if (list === void 0) {
4195
+ list = [];
4196
+ }
4197
+ if (traverseIframes === void 0) {
4198
+ traverseIframes = true;
4199
+ }
4200
+ const scrollableAncestor = getNearestOverflowAncestor(node);
4201
+ const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
4202
+ const win = getWindow(scrollableAncestor);
4203
+ if (isBody) {
4204
+ const frameElement = getFrameElement(win);
4205
+ return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
4206
+ }
4207
+ return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
4208
+ }
4209
+ function getFrameElement(win) {
4210
+ return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
4211
+ }
4114
4212
 
4115
- // src/components/chat-composer/hooks/use-composer-attachments.ts
4213
+ // ../../node_modules/.pnpm/@floating-ui+react@0.27.16_react-dom@18.3.1_react@18.3.1/node_modules/@floating-ui/react/dist/floating-ui.react.utils.mjs
4214
+ var React = __toESM(require("react"), 1);
4116
4215
  var import_react12 = require("react");
4117
- var SUPPORTED_IMAGE_MIME_TYPES = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/webp"]);
4118
- var MAX_COMPOSER_ATTACHMENTS = 10;
4119
- var createObjectUrl = (file) => typeof URL !== "undefined" && typeof URL.createObjectURL === "function" ? URL.createObjectURL(file) : "";
4120
- var revokeObjectUrl = (url) => {
4121
- if (url && typeof URL !== "undefined" && typeof URL.revokeObjectURL === "function") {
4122
- URL.revokeObjectURL(url);
4123
- }
4216
+
4217
+ // ../../node_modules/.pnpm/@floating-ui+utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs
4218
+ var min = Math.min;
4219
+ var max = Math.max;
4220
+ var round = Math.round;
4221
+ var floor = Math.floor;
4222
+ var createCoords = (v) => ({
4223
+ x: v,
4224
+ y: v
4225
+ });
4226
+ var oppositeSideMap = {
4227
+ left: "right",
4228
+ right: "left",
4229
+ bottom: "top",
4230
+ top: "bottom"
4124
4231
  };
4125
- var createAttachmentId = () => `attachment-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
4126
- var releaseComposerAttachments = (attachments) => {
4127
- attachments.forEach((attachment) => revokeObjectUrl(attachment.previewUrl));
4232
+ var oppositeAlignmentMap = {
4233
+ start: "end",
4234
+ end: "start"
4128
4235
  };
4129
- var useComposerAttachments = () => {
4130
- const [attachments, setAttachments] = (0, import_react12.useState)([]);
4131
- const attachmentsRef = (0, import_react12.useRef)([]);
4132
- (0, import_react12.useEffect)(() => {
4133
- attachmentsRef.current = attachments;
4134
- }, [attachments]);
4135
- (0, import_react12.useEffect)(
4136
- () => () => {
4137
- releaseComposerAttachments(attachmentsRef.current);
4138
- },
4139
- []
4140
- );
4141
- const appendFiles = (files) => {
4142
- const validFiles = Array.from(files).filter((file) => SUPPORTED_IMAGE_MIME_TYPES.has(file.type));
4143
- if (!validFiles.length)
4144
- return { addedCount: 0, limitExceeded: false };
4145
- const currentAttachments = attachmentsRef.current;
4146
- const remainingSlots = MAX_COMPOSER_ATTACHMENTS - currentAttachments.length;
4147
- if (remainingSlots <= 0)
4148
- return { addedCount: 0, limitExceeded: true };
4149
- const filesToAppend = validFiles.slice(0, remainingSlots);
4150
- const newAttachments = filesToAppend.map((file) => ({
4151
- id: createAttachmentId(),
4152
- file,
4153
- name: file.name,
4154
- mimeType: file.type,
4155
- size: file.size,
4156
- previewUrl: createObjectUrl(file)
4157
- }));
4158
- setAttachments((current) => [...current, ...newAttachments]);
4159
- return {
4160
- addedCount: filesToAppend.length,
4161
- limitExceeded: validFiles.length > filesToAppend.length
4162
- };
4163
- };
4164
- const removeAttachment = (attachmentId) => {
4165
- setAttachments((current) => {
4166
- const target = current.find((a) => a.id === attachmentId);
4167
- if (target)
4168
- releaseComposerAttachments([target]);
4169
- return current.filter((a) => a.id !== attachmentId);
4170
- });
4171
- };
4172
- const clearAttachments = () => {
4173
- setAttachments((current) => {
4174
- releaseComposerAttachments(current);
4175
- return [];
4176
- });
4177
- };
4178
- const takeMessageAttachments = () => {
4179
- const currentAttachments = attachmentsRef.current;
4180
- if (!currentAttachments.length) {
4236
+ function clamp(start, value, end) {
4237
+ return max(start, min(value, end));
4238
+ }
4239
+ function evaluate(value, param) {
4240
+ return typeof value === "function" ? value(param) : value;
4241
+ }
4242
+ function getSide(placement) {
4243
+ return placement.split("-")[0];
4244
+ }
4245
+ function getAlignment(placement) {
4246
+ return placement.split("-")[1];
4247
+ }
4248
+ function getOppositeAxis(axis) {
4249
+ return axis === "x" ? "y" : "x";
4250
+ }
4251
+ function getAxisLength(axis) {
4252
+ return axis === "y" ? "height" : "width";
4253
+ }
4254
+ var yAxisSides = /* @__PURE__ */ new Set(["top", "bottom"]);
4255
+ function getSideAxis(placement) {
4256
+ return yAxisSides.has(getSide(placement)) ? "y" : "x";
4257
+ }
4258
+ function getAlignmentAxis(placement) {
4259
+ return getOppositeAxis(getSideAxis(placement));
4260
+ }
4261
+ function getAlignmentSides(placement, rects, rtl) {
4262
+ if (rtl === void 0) {
4263
+ rtl = false;
4264
+ }
4265
+ const alignment = getAlignment(placement);
4266
+ const alignmentAxis = getAlignmentAxis(placement);
4267
+ const length = getAxisLength(alignmentAxis);
4268
+ let mainAlignmentSide = alignmentAxis === "x" ? alignment === (rtl ? "end" : "start") ? "right" : "left" : alignment === "start" ? "bottom" : "top";
4269
+ if (rects.reference[length] > rects.floating[length]) {
4270
+ mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
4271
+ }
4272
+ return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
4273
+ }
4274
+ function getExpandedPlacements(placement) {
4275
+ const oppositePlacement = getOppositePlacement(placement);
4276
+ return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
4277
+ }
4278
+ function getOppositeAlignmentPlacement(placement) {
4279
+ return placement.replace(/start|end/g, (alignment) => oppositeAlignmentMap[alignment]);
4280
+ }
4281
+ var lrPlacement = ["left", "right"];
4282
+ var rlPlacement = ["right", "left"];
4283
+ var tbPlacement = ["top", "bottom"];
4284
+ var btPlacement = ["bottom", "top"];
4285
+ function getSideList(side, isStart, rtl) {
4286
+ switch (side) {
4287
+ case "top":
4288
+ case "bottom":
4289
+ if (rtl)
4290
+ return isStart ? rlPlacement : lrPlacement;
4291
+ return isStart ? lrPlacement : rlPlacement;
4292
+ case "left":
4293
+ case "right":
4294
+ return isStart ? tbPlacement : btPlacement;
4295
+ default:
4181
4296
  return [];
4297
+ }
4298
+ }
4299
+ function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
4300
+ const alignment = getAlignment(placement);
4301
+ let list = getSideList(getSide(placement), direction === "start", rtl);
4302
+ if (alignment) {
4303
+ list = list.map((side) => side + "-" + alignment);
4304
+ if (flipAlignment) {
4305
+ list = list.concat(list.map(getOppositeAlignmentPlacement));
4182
4306
  }
4183
- const nextMessageAttachments = currentAttachments.map(({ file: _file, ...attachment }) => ({
4184
- ...attachment,
4185
- file: _file
4186
- }));
4187
- attachmentsRef.current = [];
4188
- setAttachments([]);
4189
- return nextMessageAttachments;
4307
+ }
4308
+ return list;
4309
+ }
4310
+ function getOppositePlacement(placement) {
4311
+ return placement.replace(/left|right|bottom|top/g, (side) => oppositeSideMap[side]);
4312
+ }
4313
+ function expandPaddingObject(padding) {
4314
+ return {
4315
+ top: 0,
4316
+ right: 0,
4317
+ bottom: 0,
4318
+ left: 0,
4319
+ ...padding
4190
4320
  };
4321
+ }
4322
+ function getPaddingObject(padding) {
4323
+ return typeof padding !== "number" ? expandPaddingObject(padding) : {
4324
+ top: padding,
4325
+ right: padding,
4326
+ bottom: padding,
4327
+ left: padding
4328
+ };
4329
+ }
4330
+ function rectToClientRect(rect) {
4331
+ const {
4332
+ x,
4333
+ y,
4334
+ width,
4335
+ height
4336
+ } = rect;
4191
4337
  return {
4192
- attachments,
4193
- appendFiles,
4194
- removeAttachment,
4195
- clearAttachments,
4196
- takeMessageAttachments
4338
+ width,
4339
+ height,
4340
+ top: y,
4341
+ left: x,
4342
+ right: x + width,
4343
+ bottom: y + height,
4344
+ x,
4345
+ y
4197
4346
  };
4198
- };
4347
+ }
4199
4348
 
4200
- // src/components/chat-composer/hooks/use-chat-composer.ts
4201
- var nowIso = () => (/* @__PURE__ */ new Date()).toISOString();
4202
- var ATTACHMENT_NOTICE_DURATION_MS = 3e3;
4203
- var STOP_WAIT_TIMEOUT_MS = 3e3;
4204
- var resolveAccumulatedContent = (currentContent, update) => {
4205
- if (update.content !== void 0) {
4206
- return update.content;
4349
+ // ../../node_modules/.pnpm/tabbable@6.3.0/node_modules/tabbable/dist/index.esm.js
4350
+ var candidateSelectors = ["input:not([inert])", "select:not([inert])", "textarea:not([inert])", "a[href]:not([inert])", "button:not([inert])", "[tabindex]:not(slot):not([inert])", "audio[controls]:not([inert])", "video[controls]:not([inert])", '[contenteditable]:not([contenteditable="false"]):not([inert])', "details>summary:first-of-type:not([inert])", "details:not([inert])"];
4351
+ var candidateSelector = /* @__PURE__ */ candidateSelectors.join(",");
4352
+ var NoElement = typeof Element === "undefined";
4353
+ var matches = NoElement ? function() {
4354
+ } : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
4355
+ var getRootNode = !NoElement && Element.prototype.getRootNode ? function(element) {
4356
+ var _element$getRootNode;
4357
+ return element === null || element === void 0 ? void 0 : (_element$getRootNode = element.getRootNode) === null || _element$getRootNode === void 0 ? void 0 : _element$getRootNode.call(element);
4358
+ } : function(element) {
4359
+ return element === null || element === void 0 ? void 0 : element.ownerDocument;
4360
+ };
4361
+ var _isInert = function isInert(node, lookUp) {
4362
+ var _node$getAttribute;
4363
+ if (lookUp === void 0) {
4364
+ lookUp = true;
4365
+ }
4366
+ var inertAtt = node === null || node === void 0 ? void 0 : (_node$getAttribute = node.getAttribute) === null || _node$getAttribute === void 0 ? void 0 : _node$getAttribute.call(node, "inert");
4367
+ var inert = inertAtt === "" || inertAtt === "true";
4368
+ var result = inert || lookUp && node && _isInert(node.parentNode);
4369
+ return result;
4370
+ };
4371
+ var isContentEditable = function isContentEditable2(node) {
4372
+ var _node$getAttribute2;
4373
+ var attValue = node === null || node === void 0 ? void 0 : (_node$getAttribute2 = node.getAttribute) === null || _node$getAttribute2 === void 0 ? void 0 : _node$getAttribute2.call(node, "contenteditable");
4374
+ return attValue === "" || attValue === "true";
4375
+ };
4376
+ var getCandidates = function getCandidates2(el, includeContainer, filter) {
4377
+ if (_isInert(el)) {
4378
+ return [];
4207
4379
  }
4208
- if (update.contentDelta) {
4209
- return currentContent + update.contentDelta;
4380
+ var candidates = Array.prototype.slice.apply(el.querySelectorAll(candidateSelector));
4381
+ if (includeContainer && matches.call(el, candidateSelector)) {
4382
+ candidates.unshift(el);
4210
4383
  }
4211
- return currentContent;
4384
+ candidates = candidates.filter(filter);
4385
+ return candidates;
4212
4386
  };
4213
- var normalizeChatErrorMessage = (message, labels) => {
4214
- const trimmedMessage = message?.trim();
4215
- if (!trimmedMessage) {
4216
- return labels.genericError;
4387
+ var _getCandidatesIteratively = function getCandidatesIteratively(elements, includeContainer, options) {
4388
+ var candidates = [];
4389
+ var elementsToCheck = Array.from(elements);
4390
+ while (elementsToCheck.length) {
4391
+ var element = elementsToCheck.shift();
4392
+ if (_isInert(element, false)) {
4393
+ continue;
4394
+ }
4395
+ if (element.tagName === "SLOT") {
4396
+ var assigned = element.assignedElements();
4397
+ var content = assigned.length ? assigned : element.children;
4398
+ var nestedCandidates = _getCandidatesIteratively(content, true, options);
4399
+ if (options.flatten) {
4400
+ candidates.push.apply(candidates, nestedCandidates);
4401
+ } else {
4402
+ candidates.push({
4403
+ scopeParent: element,
4404
+ candidates: nestedCandidates
4405
+ });
4406
+ }
4407
+ } else {
4408
+ var validCandidate = matches.call(element, candidateSelector);
4409
+ if (validCandidate && options.filter(element) && (includeContainer || !elements.includes(element))) {
4410
+ candidates.push(element);
4411
+ }
4412
+ var shadowRoot = element.shadowRoot || // check for an undisclosed shadow
4413
+ typeof options.getShadowRoot === "function" && options.getShadowRoot(element);
4414
+ var validShadowRoot = !_isInert(shadowRoot, false) && (!options.shadowRootFilter || options.shadowRootFilter(element));
4415
+ if (shadowRoot && validShadowRoot) {
4416
+ var _nestedCandidates = _getCandidatesIteratively(shadowRoot === true ? element.children : shadowRoot.children, true, options);
4417
+ if (options.flatten) {
4418
+ candidates.push.apply(candidates, _nestedCandidates);
4419
+ } else {
4420
+ candidates.push({
4421
+ scopeParent: element,
4422
+ candidates: _nestedCandidates
4423
+ });
4424
+ }
4425
+ } else {
4426
+ elementsToCheck.unshift.apply(elementsToCheck, element.children);
4427
+ }
4428
+ }
4217
4429
  }
4218
- if (trimmedMessage === "Failed to fetch") {
4219
- return labels.networkError;
4430
+ return candidates;
4431
+ };
4432
+ var hasTabIndex = function hasTabIndex2(node) {
4433
+ return !isNaN(parseInt(node.getAttribute("tabindex"), 10));
4434
+ };
4435
+ var getTabIndex = function getTabIndex2(node) {
4436
+ if (!node) {
4437
+ throw new Error("No node provided");
4220
4438
  }
4221
- return trimmedMessage;
4439
+ if (node.tabIndex < 0) {
4440
+ if ((/^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || isContentEditable(node)) && !hasTabIndex(node)) {
4441
+ return 0;
4442
+ }
4443
+ }
4444
+ return node.tabIndex;
4222
4445
  };
4223
- var useChatComposer = () => {
4224
- const { transport, enableImageAttachments, labels, store } = useChatContext();
4225
- const activeSessionId = useChatStore((s) => s.activeSessionId);
4226
- const activeSession = useChatStore(
4227
- (s) => s.sessions.find((x) => x.sessionId === s.activeSessionId) ?? null
4228
- );
4229
- const preferredMode = useChatStore((s) => s.preferredMode);
4230
- const streamingSessionId = useChatStore(
4231
- (s) => s.activeSessionId && s.isStreamingBySession[s.activeSessionId] ? s.activeSessionId : null
4232
- );
4233
- const isStreaming = Boolean(streamingSessionId);
4234
- const isStopping = useChatStore((s) => {
4235
- const currentStreamingSessionId = s.activeSessionId && s.isStreamingBySession[s.activeSessionId] ? s.activeSessionId : null;
4236
- return currentStreamingSessionId ? s.isStoppingBySession[currentStreamingSessionId] ?? false : false;
4446
+ var getSortOrderTabIndex = function getSortOrderTabIndex2(node, isScope) {
4447
+ var tabIndex = getTabIndex(node);
4448
+ if (tabIndex < 0 && isScope && !hasTabIndex(node)) {
4449
+ return 0;
4450
+ }
4451
+ return tabIndex;
4452
+ };
4453
+ var sortOrderedTabbables = function sortOrderedTabbables2(a, b) {
4454
+ return a.tabIndex === b.tabIndex ? a.documentOrder - b.documentOrder : a.tabIndex - b.tabIndex;
4455
+ };
4456
+ var isInput = function isInput2(node) {
4457
+ return node.tagName === "INPUT";
4458
+ };
4459
+ var isHiddenInput = function isHiddenInput2(node) {
4460
+ return isInput(node) && node.type === "hidden";
4461
+ };
4462
+ var isDetailsWithSummary = function isDetailsWithSummary2(node) {
4463
+ var r = node.tagName === "DETAILS" && Array.prototype.slice.apply(node.children).some(function(child) {
4464
+ return child.tagName === "SUMMARY";
4237
4465
  });
4238
- const createSession = useChatStore((s) => s.createSession);
4239
- const replaceSessionId = useChatStore((s) => s.replaceSessionId);
4240
- const appendMessage = useChatStore((s) => s.appendMessage);
4241
- const startStreamingMessage = useChatStore((s) => s.startStreamingMessage);
4242
- const patchStreamingMessage = useChatStore((s) => s.patchStreamingMessage);
4243
- const completeStreamingMessage = useChatStore((s) => s.completeStreamingMessage);
4244
- const requestStopStreaming = useChatStore((s) => s.requestStopStreaming);
4245
- const finalizeStoppedStreamingMessage = useChatStore((s) => s.finalizeStoppedStreamingMessage);
4246
- const setSessionError = useChatStore((s) => s.setSessionError);
4247
- const clearSessionError = useChatStore((s) => s.clearSessionError);
4248
- const setPreferredMode = useChatStore((s) => s.setPreferredMode);
4249
- const setSessionMode = useChatStore((s) => s.setSessionMode);
4250
- const [availableModels, setAvailableModels] = (0, import_react13.useState)([]);
4251
- const [isModelsLoading, setIsModelsLoading] = (0, import_react13.useState)(true);
4252
- const [isModelsError, setIsModelsError] = (0, import_react13.useState)(false);
4253
- const fetchModels = (0, import_react13.useCallback)(async () => {
4254
- setIsModelsLoading(true);
4255
- setIsModelsError(false);
4466
+ return r;
4467
+ };
4468
+ var getCheckedRadio = function getCheckedRadio2(nodes, form) {
4469
+ for (var i = 0; i < nodes.length; i++) {
4470
+ if (nodes[i].checked && nodes[i].form === form) {
4471
+ return nodes[i];
4472
+ }
4473
+ }
4474
+ };
4475
+ var isTabbableRadio = function isTabbableRadio2(node) {
4476
+ if (!node.name) {
4477
+ return true;
4478
+ }
4479
+ var radioScope = node.form || getRootNode(node);
4480
+ var queryRadios = function queryRadios2(name) {
4481
+ return radioScope.querySelectorAll('input[type="radio"][name="' + name + '"]');
4482
+ };
4483
+ var radioSet;
4484
+ if (typeof window !== "undefined" && typeof window.CSS !== "undefined" && typeof window.CSS.escape === "function") {
4485
+ radioSet = queryRadios(window.CSS.escape(node.name));
4486
+ } else {
4487
+ try {
4488
+ radioSet = queryRadios(node.name);
4489
+ } catch (err) {
4490
+ console.error("Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s", err.message);
4491
+ return false;
4492
+ }
4493
+ }
4494
+ var checked = getCheckedRadio(radioSet, node.form);
4495
+ return !checked || checked === node;
4496
+ };
4497
+ var isRadio = function isRadio2(node) {
4498
+ return isInput(node) && node.type === "radio";
4499
+ };
4500
+ var isNonTabbableRadio = function isNonTabbableRadio2(node) {
4501
+ return isRadio(node) && !isTabbableRadio(node);
4502
+ };
4503
+ var isNodeAttached = function isNodeAttached2(node) {
4504
+ var _nodeRoot;
4505
+ var nodeRoot = node && getRootNode(node);
4506
+ var nodeRootHost = (_nodeRoot = nodeRoot) === null || _nodeRoot === void 0 ? void 0 : _nodeRoot.host;
4507
+ var attached = false;
4508
+ if (nodeRoot && nodeRoot !== node) {
4509
+ var _nodeRootHost, _nodeRootHost$ownerDo, _node$ownerDocument;
4510
+ attached = !!((_nodeRootHost = nodeRootHost) !== null && _nodeRootHost !== void 0 && (_nodeRootHost$ownerDo = _nodeRootHost.ownerDocument) !== null && _nodeRootHost$ownerDo !== void 0 && _nodeRootHost$ownerDo.contains(nodeRootHost) || node !== null && node !== void 0 && (_node$ownerDocument = node.ownerDocument) !== null && _node$ownerDocument !== void 0 && _node$ownerDocument.contains(node));
4511
+ while (!attached && nodeRootHost) {
4512
+ var _nodeRoot2, _nodeRootHost2, _nodeRootHost2$ownerD;
4513
+ nodeRoot = getRootNode(nodeRootHost);
4514
+ nodeRootHost = (_nodeRoot2 = nodeRoot) === null || _nodeRoot2 === void 0 ? void 0 : _nodeRoot2.host;
4515
+ attached = !!((_nodeRootHost2 = nodeRootHost) !== null && _nodeRootHost2 !== void 0 && (_nodeRootHost2$ownerD = _nodeRootHost2.ownerDocument) !== null && _nodeRootHost2$ownerD !== void 0 && _nodeRootHost2$ownerD.contains(nodeRootHost));
4516
+ }
4517
+ }
4518
+ return attached;
4519
+ };
4520
+ var isZeroArea = function isZeroArea2(node) {
4521
+ var _node$getBoundingClie = node.getBoundingClientRect(), width = _node$getBoundingClie.width, height = _node$getBoundingClie.height;
4522
+ return width === 0 && height === 0;
4523
+ };
4524
+ var isHidden = function isHidden2(node, _ref) {
4525
+ var displayCheck = _ref.displayCheck, getShadowRoot = _ref.getShadowRoot;
4526
+ if (displayCheck === "full-native") {
4527
+ if ("checkVisibility" in node) {
4528
+ var visible = node.checkVisibility({
4529
+ // Checking opacity might be desirable for some use cases, but natively,
4530
+ // opacity zero elements _are_ focusable and tabbable.
4531
+ checkOpacity: false,
4532
+ opacityProperty: false,
4533
+ contentVisibilityAuto: true,
4534
+ visibilityProperty: true,
4535
+ // This is an alias for `visibilityProperty`. Contemporary browsers
4536
+ // support both. However, this alias has wider browser support (Chrome
4537
+ // >= 105 and Firefox >= 106, vs. Chrome >= 121 and Firefox >= 122), so
4538
+ // we include it anyway.
4539
+ checkVisibilityCSS: true
4540
+ });
4541
+ return !visible;
4542
+ }
4543
+ }
4544
+ if (getComputedStyle(node).visibility === "hidden") {
4545
+ return true;
4546
+ }
4547
+ var isDirectSummary = matches.call(node, "details>summary:first-of-type");
4548
+ var nodeUnderDetails = isDirectSummary ? node.parentElement : node;
4549
+ if (matches.call(nodeUnderDetails, "details:not([open]) *")) {
4550
+ return true;
4551
+ }
4552
+ if (!displayCheck || displayCheck === "full" || // full-native can run this branch when it falls through in case
4553
+ // Element#checkVisibility is unsupported
4554
+ displayCheck === "full-native" || displayCheck === "legacy-full") {
4555
+ if (typeof getShadowRoot === "function") {
4556
+ var originalNode = node;
4557
+ while (node) {
4558
+ var parentElement = node.parentElement;
4559
+ var rootNode = getRootNode(node);
4560
+ if (parentElement && !parentElement.shadowRoot && getShadowRoot(parentElement) === true) {
4561
+ return isZeroArea(node);
4562
+ } else if (node.assignedSlot) {
4563
+ node = node.assignedSlot;
4564
+ } else if (!parentElement && rootNode !== node.ownerDocument) {
4565
+ node = rootNode.host;
4566
+ } else {
4567
+ node = parentElement;
4568
+ }
4569
+ }
4570
+ node = originalNode;
4571
+ }
4572
+ if (isNodeAttached(node)) {
4573
+ return !node.getClientRects().length;
4574
+ }
4575
+ if (displayCheck !== "legacy-full") {
4576
+ return true;
4577
+ }
4578
+ } else if (displayCheck === "non-zero-area") {
4579
+ return isZeroArea(node);
4580
+ }
4581
+ return false;
4582
+ };
4583
+ var isDisabledFromFieldset = function isDisabledFromFieldset2(node) {
4584
+ if (/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(node.tagName)) {
4585
+ var parentNode = node.parentElement;
4586
+ while (parentNode) {
4587
+ if (parentNode.tagName === "FIELDSET" && parentNode.disabled) {
4588
+ for (var i = 0; i < parentNode.children.length; i++) {
4589
+ var child = parentNode.children.item(i);
4590
+ if (child.tagName === "LEGEND") {
4591
+ return matches.call(parentNode, "fieldset[disabled] *") ? true : !child.contains(node);
4592
+ }
4593
+ }
4594
+ return true;
4595
+ }
4596
+ parentNode = parentNode.parentElement;
4597
+ }
4598
+ }
4599
+ return false;
4600
+ };
4601
+ var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable2(options, node) {
4602
+ if (node.disabled || // we must do an inert look up to filter out any elements inside an inert ancestor
4603
+ // because we're limited in the type of selectors we can use in JSDom (see related
4604
+ // note related to `candidateSelectors`)
4605
+ _isInert(node) || isHiddenInput(node) || isHidden(node, options) || // For a details element with a summary, the summary element gets the focus
4606
+ isDetailsWithSummary(node) || isDisabledFromFieldset(node)) {
4607
+ return false;
4608
+ }
4609
+ return true;
4610
+ };
4611
+ var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable2(options, node) {
4612
+ if (isNonTabbableRadio(node) || getTabIndex(node) < 0 || !isNodeMatchingSelectorFocusable(options, node)) {
4613
+ return false;
4614
+ }
4615
+ return true;
4616
+ };
4617
+ var isShadowRootTabbable = function isShadowRootTabbable2(shadowHostNode) {
4618
+ var tabIndex = parseInt(shadowHostNode.getAttribute("tabindex"), 10);
4619
+ if (isNaN(tabIndex) || tabIndex >= 0) {
4620
+ return true;
4621
+ }
4622
+ return false;
4623
+ };
4624
+ var _sortByOrder = function sortByOrder(candidates) {
4625
+ var regularTabbables = [];
4626
+ var orderedTabbables = [];
4627
+ candidates.forEach(function(item, i) {
4628
+ var isScope = !!item.scopeParent;
4629
+ var element = isScope ? item.scopeParent : item;
4630
+ var candidateTabindex = getSortOrderTabIndex(element, isScope);
4631
+ var elements = isScope ? _sortByOrder(item.candidates) : element;
4632
+ if (candidateTabindex === 0) {
4633
+ isScope ? regularTabbables.push.apply(regularTabbables, elements) : regularTabbables.push(element);
4634
+ } else {
4635
+ orderedTabbables.push({
4636
+ documentOrder: i,
4637
+ tabIndex: candidateTabindex,
4638
+ item,
4639
+ isScope,
4640
+ content: elements
4641
+ });
4642
+ }
4643
+ });
4644
+ return orderedTabbables.sort(sortOrderedTabbables).reduce(function(acc, sortable) {
4645
+ sortable.isScope ? acc.push.apply(acc, sortable.content) : acc.push(sortable.content);
4646
+ return acc;
4647
+ }, []).concat(regularTabbables);
4648
+ };
4649
+ var tabbable = function tabbable2(container, options) {
4650
+ options = options || {};
4651
+ var candidates;
4652
+ if (options.getShadowRoot) {
4653
+ candidates = _getCandidatesIteratively([container], options.includeContainer, {
4654
+ filter: isNodeMatchingSelectorTabbable.bind(null, options),
4655
+ flatten: false,
4656
+ getShadowRoot: options.getShadowRoot,
4657
+ shadowRootFilter: isShadowRootTabbable
4658
+ });
4659
+ } else {
4660
+ candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options));
4661
+ }
4662
+ return _sortByOrder(candidates);
4663
+ };
4664
+
4665
+ // ../../node_modules/.pnpm/@floating-ui+react@0.27.16_react-dom@18.3.1_react@18.3.1/node_modules/@floating-ui/react/dist/floating-ui.react.utils.mjs
4666
+ function isSafari() {
4667
+ return /apple/i.test(navigator.vendor);
4668
+ }
4669
+ function activeElement(doc) {
4670
+ let activeElement2 = doc.activeElement;
4671
+ while (((_activeElement = activeElement2) == null || (_activeElement = _activeElement.shadowRoot) == null ? void 0 : _activeElement.activeElement) != null) {
4672
+ var _activeElement;
4673
+ activeElement2 = activeElement2.shadowRoot.activeElement;
4674
+ }
4675
+ return activeElement2;
4676
+ }
4677
+ function contains(parent, child) {
4678
+ if (!parent || !child) {
4679
+ return false;
4680
+ }
4681
+ const rootNode = child.getRootNode == null ? void 0 : child.getRootNode();
4682
+ if (parent.contains(child)) {
4683
+ return true;
4684
+ }
4685
+ if (rootNode && isShadowRoot(rootNode)) {
4686
+ let next = child;
4687
+ while (next) {
4688
+ if (parent === next) {
4689
+ return true;
4690
+ }
4691
+ next = next.parentNode || next.host;
4692
+ }
4693
+ }
4694
+ return false;
4695
+ }
4696
+ function getDocument(node) {
4697
+ return (node == null ? void 0 : node.ownerDocument) || document;
4698
+ }
4699
+ var isClient = typeof document !== "undefined";
4700
+ var noop = function noop2() {
4701
+ };
4702
+ var index = isClient ? import_react12.useLayoutEffect : noop;
4703
+ var SafeReact = {
4704
+ ...React
4705
+ };
4706
+ var useInsertionEffect = SafeReact.useInsertionEffect;
4707
+ var useSafeInsertionEffect = useInsertionEffect || ((fn) => fn());
4708
+ function useEffectEvent(callback) {
4709
+ const ref = React.useRef(() => {
4710
+ if (process.env.NODE_ENV !== "production") {
4711
+ throw new Error("Cannot call an event handler while rendering.");
4712
+ }
4713
+ });
4714
+ useSafeInsertionEffect(() => {
4715
+ ref.current = callback;
4716
+ });
4717
+ return React.useCallback(function() {
4718
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
4719
+ args[_key] = arguments[_key];
4720
+ }
4721
+ return ref.current == null ? void 0 : ref.current(...args);
4722
+ }, []);
4723
+ }
4724
+ var getTabbableOptions = () => ({
4725
+ getShadowRoot: true,
4726
+ displayCheck: (
4727
+ // JSDOM does not support the `tabbable` library. To solve this we can
4728
+ // check if `ResizeObserver` is a real function (not polyfilled), which
4729
+ // determines if the current environment is JSDOM-like.
4730
+ typeof ResizeObserver === "function" && ResizeObserver.toString().includes("[native code]") ? "full" : "none"
4731
+ )
4732
+ });
4733
+ function getTabbableIn(container, dir) {
4734
+ const list = tabbable(container, getTabbableOptions());
4735
+ const len = list.length;
4736
+ if (len === 0)
4737
+ return;
4738
+ const active = activeElement(getDocument(container));
4739
+ const index3 = list.indexOf(active);
4740
+ const nextIndex = index3 === -1 ? dir === 1 ? 0 : len - 1 : index3 + dir;
4741
+ return list[nextIndex];
4742
+ }
4743
+ function getNextTabbable(referenceElement) {
4744
+ return getTabbableIn(getDocument(referenceElement).body, 1) || referenceElement;
4745
+ }
4746
+ function getPreviousTabbable(referenceElement) {
4747
+ return getTabbableIn(getDocument(referenceElement).body, -1) || referenceElement;
4748
+ }
4749
+ function isOutsideEvent(event, container) {
4750
+ const containerElement = container || event.currentTarget;
4751
+ const relatedTarget = event.relatedTarget;
4752
+ return !relatedTarget || !contains(containerElement, relatedTarget);
4753
+ }
4754
+ function disableFocusInside(container) {
4755
+ const tabbableElements = tabbable(container, getTabbableOptions());
4756
+ tabbableElements.forEach((element) => {
4757
+ element.dataset.tabindex = element.getAttribute("tabindex") || "";
4758
+ element.setAttribute("tabindex", "-1");
4759
+ });
4760
+ }
4761
+ function enableFocusInside(container) {
4762
+ const elements = container.querySelectorAll("[data-tabindex]");
4763
+ elements.forEach((element) => {
4764
+ const tabindex = element.dataset.tabindex;
4765
+ delete element.dataset.tabindex;
4766
+ if (tabindex) {
4767
+ element.setAttribute("tabindex", tabindex);
4768
+ } else {
4769
+ element.removeAttribute("tabindex");
4770
+ }
4771
+ });
4772
+ }
4773
+
4774
+ // ../../node_modules/.pnpm/@floating-ui+react@0.27.16_react-dom@18.3.1_react@18.3.1/node_modules/@floating-ui/react/dist/floating-ui.react.mjs
4775
+ var import_jsx_runtime11 = require("react/jsx-runtime");
4776
+ var ReactDOM2 = __toESM(require("react-dom"), 1);
4777
+
4778
+ // ../../node_modules/.pnpm/@floating-ui+core@1.7.3/node_modules/@floating-ui/core/dist/floating-ui.core.mjs
4779
+ function computeCoordsFromPlacement(_ref, placement, rtl) {
4780
+ let {
4781
+ reference,
4782
+ floating
4783
+ } = _ref;
4784
+ const sideAxis = getSideAxis(placement);
4785
+ const alignmentAxis = getAlignmentAxis(placement);
4786
+ const alignLength = getAxisLength(alignmentAxis);
4787
+ const side = getSide(placement);
4788
+ const isVertical = sideAxis === "y";
4789
+ const commonX = reference.x + reference.width / 2 - floating.width / 2;
4790
+ const commonY = reference.y + reference.height / 2 - floating.height / 2;
4791
+ const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2;
4792
+ let coords;
4793
+ switch (side) {
4794
+ case "top":
4795
+ coords = {
4796
+ x: commonX,
4797
+ y: reference.y - floating.height
4798
+ };
4799
+ break;
4800
+ case "bottom":
4801
+ coords = {
4802
+ x: commonX,
4803
+ y: reference.y + reference.height
4804
+ };
4805
+ break;
4806
+ case "right":
4807
+ coords = {
4808
+ x: reference.x + reference.width,
4809
+ y: commonY
4810
+ };
4811
+ break;
4812
+ case "left":
4813
+ coords = {
4814
+ x: reference.x - floating.width,
4815
+ y: commonY
4816
+ };
4817
+ break;
4818
+ default:
4819
+ coords = {
4820
+ x: reference.x,
4821
+ y: reference.y
4822
+ };
4823
+ }
4824
+ switch (getAlignment(placement)) {
4825
+ case "start":
4826
+ coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);
4827
+ break;
4828
+ case "end":
4829
+ coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1);
4830
+ break;
4831
+ }
4832
+ return coords;
4833
+ }
4834
+ var computePosition = async (reference, floating, config) => {
4835
+ const {
4836
+ placement = "bottom",
4837
+ strategy = "absolute",
4838
+ middleware = [],
4839
+ platform: platform2
4840
+ } = config;
4841
+ const validMiddleware = middleware.filter(Boolean);
4842
+ const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(floating));
4843
+ let rects = await platform2.getElementRects({
4844
+ reference,
4845
+ floating,
4846
+ strategy
4847
+ });
4848
+ let {
4849
+ x,
4850
+ y
4851
+ } = computeCoordsFromPlacement(rects, placement, rtl);
4852
+ let statefulPlacement = placement;
4853
+ let middlewareData = {};
4854
+ let resetCount = 0;
4855
+ for (let i = 0; i < validMiddleware.length; i++) {
4856
+ const {
4857
+ name,
4858
+ fn
4859
+ } = validMiddleware[i];
4860
+ const {
4861
+ x: nextX,
4862
+ y: nextY,
4863
+ data,
4864
+ reset
4865
+ } = await fn({
4866
+ x,
4867
+ y,
4868
+ initialPlacement: placement,
4869
+ placement: statefulPlacement,
4870
+ strategy,
4871
+ middlewareData,
4872
+ rects,
4873
+ platform: platform2,
4874
+ elements: {
4875
+ reference,
4876
+ floating
4877
+ }
4878
+ });
4879
+ x = nextX != null ? nextX : x;
4880
+ y = nextY != null ? nextY : y;
4881
+ middlewareData = {
4882
+ ...middlewareData,
4883
+ [name]: {
4884
+ ...middlewareData[name],
4885
+ ...data
4886
+ }
4887
+ };
4888
+ if (reset && resetCount <= 50) {
4889
+ resetCount++;
4890
+ if (typeof reset === "object") {
4891
+ if (reset.placement) {
4892
+ statefulPlacement = reset.placement;
4893
+ }
4894
+ if (reset.rects) {
4895
+ rects = reset.rects === true ? await platform2.getElementRects({
4896
+ reference,
4897
+ floating,
4898
+ strategy
4899
+ }) : reset.rects;
4900
+ }
4901
+ ({
4902
+ x,
4903
+ y
4904
+ } = computeCoordsFromPlacement(rects, statefulPlacement, rtl));
4905
+ }
4906
+ i = -1;
4907
+ }
4908
+ }
4909
+ return {
4910
+ x,
4911
+ y,
4912
+ placement: statefulPlacement,
4913
+ strategy,
4914
+ middlewareData
4915
+ };
4916
+ };
4917
+ async function detectOverflow(state, options) {
4918
+ var _await$platform$isEle;
4919
+ if (options === void 0) {
4920
+ options = {};
4921
+ }
4922
+ const {
4923
+ x,
4924
+ y,
4925
+ platform: platform2,
4926
+ rects,
4927
+ elements,
4928
+ strategy
4929
+ } = state;
4930
+ const {
4931
+ boundary = "clippingAncestors",
4932
+ rootBoundary = "viewport",
4933
+ elementContext = "floating",
4934
+ altBoundary = false,
4935
+ padding = 0
4936
+ } = evaluate(options, state);
4937
+ const paddingObject = getPaddingObject(padding);
4938
+ const altContext = elementContext === "floating" ? "reference" : "floating";
4939
+ const element = elements[altBoundary ? altContext : elementContext];
4940
+ const clippingClientRect = rectToClientRect(await platform2.getClippingRect({
4941
+ element: ((_await$platform$isEle = await (platform2.isElement == null ? void 0 : platform2.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || await (platform2.getDocumentElement == null ? void 0 : platform2.getDocumentElement(elements.floating)),
4942
+ boundary,
4943
+ rootBoundary,
4944
+ strategy
4945
+ }));
4946
+ const rect = elementContext === "floating" ? {
4947
+ x,
4948
+ y,
4949
+ width: rects.floating.width,
4950
+ height: rects.floating.height
4951
+ } : rects.reference;
4952
+ const offsetParent = await (platform2.getOffsetParent == null ? void 0 : platform2.getOffsetParent(elements.floating));
4953
+ const offsetScale = await (platform2.isElement == null ? void 0 : platform2.isElement(offsetParent)) ? await (platform2.getScale == null ? void 0 : platform2.getScale(offsetParent)) || {
4954
+ x: 1,
4955
+ y: 1
4956
+ } : {
4957
+ x: 1,
4958
+ y: 1
4959
+ };
4960
+ const elementClientRect = rectToClientRect(platform2.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform2.convertOffsetParentRelativeRectToViewportRelativeRect({
4961
+ elements,
4962
+ rect,
4963
+ offsetParent,
4964
+ strategy
4965
+ }) : rect);
4966
+ return {
4967
+ top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
4968
+ bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
4969
+ left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
4970
+ right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
4971
+ };
4972
+ }
4973
+ var flip = function(options) {
4974
+ if (options === void 0) {
4975
+ options = {};
4976
+ }
4977
+ return {
4978
+ name: "flip",
4979
+ options,
4980
+ async fn(state) {
4981
+ var _middlewareData$arrow, _middlewareData$flip;
4982
+ const {
4983
+ placement,
4984
+ middlewareData,
4985
+ rects,
4986
+ initialPlacement,
4987
+ platform: platform2,
4988
+ elements
4989
+ } = state;
4990
+ const {
4991
+ mainAxis: checkMainAxis = true,
4992
+ crossAxis: checkCrossAxis = true,
4993
+ fallbackPlacements: specifiedFallbackPlacements,
4994
+ fallbackStrategy = "bestFit",
4995
+ fallbackAxisSideDirection = "none",
4996
+ flipAlignment = true,
4997
+ ...detectOverflowOptions
4998
+ } = evaluate(options, state);
4999
+ if ((_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
5000
+ return {};
5001
+ }
5002
+ const side = getSide(placement);
5003
+ const initialSideAxis = getSideAxis(initialPlacement);
5004
+ const isBasePlacement = getSide(initialPlacement) === initialPlacement;
5005
+ const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating));
5006
+ const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));
5007
+ const hasFallbackAxisSideDirection = fallbackAxisSideDirection !== "none";
5008
+ if (!specifiedFallbackPlacements && hasFallbackAxisSideDirection) {
5009
+ fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));
5010
+ }
5011
+ const placements2 = [initialPlacement, ...fallbackPlacements];
5012
+ const overflow = await detectOverflow(state, detectOverflowOptions);
5013
+ const overflows = [];
5014
+ let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
5015
+ if (checkMainAxis) {
5016
+ overflows.push(overflow[side]);
5017
+ }
5018
+ if (checkCrossAxis) {
5019
+ const sides2 = getAlignmentSides(placement, rects, rtl);
5020
+ overflows.push(overflow[sides2[0]], overflow[sides2[1]]);
5021
+ }
5022
+ overflowsData = [...overflowsData, {
5023
+ placement,
5024
+ overflows
5025
+ }];
5026
+ if (!overflows.every((side2) => side2 <= 0)) {
5027
+ var _middlewareData$flip2, _overflowsData$filter;
5028
+ const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;
5029
+ const nextPlacement = placements2[nextIndex];
5030
+ if (nextPlacement) {
5031
+ const ignoreCrossAxisOverflow = checkCrossAxis === "alignment" ? initialSideAxis !== getSideAxis(nextPlacement) : false;
5032
+ if (!ignoreCrossAxisOverflow || // We leave the current main axis only if every placement on that axis
5033
+ // overflows the main axis.
5034
+ overflowsData.every((d) => getSideAxis(d.placement) === initialSideAxis ? d.overflows[0] > 0 : true)) {
5035
+ return {
5036
+ data: {
5037
+ index: nextIndex,
5038
+ overflows: overflowsData
5039
+ },
5040
+ reset: {
5041
+ placement: nextPlacement
5042
+ }
5043
+ };
5044
+ }
5045
+ }
5046
+ let resetPlacement = (_overflowsData$filter = overflowsData.filter((d) => d.overflows[0] <= 0).sort((a, b) => a.overflows[1] - b.overflows[1])[0]) == null ? void 0 : _overflowsData$filter.placement;
5047
+ if (!resetPlacement) {
5048
+ switch (fallbackStrategy) {
5049
+ case "bestFit": {
5050
+ var _overflowsData$filter2;
5051
+ const placement2 = (_overflowsData$filter2 = overflowsData.filter((d) => {
5052
+ if (hasFallbackAxisSideDirection) {
5053
+ const currentSideAxis = getSideAxis(d.placement);
5054
+ return currentSideAxis === initialSideAxis || // Create a bias to the `y` side axis due to horizontal
5055
+ // reading directions favoring greater width.
5056
+ currentSideAxis === "y";
5057
+ }
5058
+ return true;
5059
+ }).map((d) => [d.placement, d.overflows.filter((overflow2) => overflow2 > 0).reduce((acc, overflow2) => acc + overflow2, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$filter2[0];
5060
+ if (placement2) {
5061
+ resetPlacement = placement2;
5062
+ }
5063
+ break;
5064
+ }
5065
+ case "initialPlacement":
5066
+ resetPlacement = initialPlacement;
5067
+ break;
5068
+ }
5069
+ }
5070
+ if (placement !== resetPlacement) {
5071
+ return {
5072
+ reset: {
5073
+ placement: resetPlacement
5074
+ }
5075
+ };
5076
+ }
5077
+ }
5078
+ return {};
5079
+ }
5080
+ };
5081
+ };
5082
+ var originSides = /* @__PURE__ */ new Set(["left", "top"]);
5083
+ async function convertValueToCoords(state, options) {
5084
+ const {
5085
+ placement,
5086
+ platform: platform2,
5087
+ elements
5088
+ } = state;
5089
+ const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating));
5090
+ const side = getSide(placement);
5091
+ const alignment = getAlignment(placement);
5092
+ const isVertical = getSideAxis(placement) === "y";
5093
+ const mainAxisMulti = originSides.has(side) ? -1 : 1;
5094
+ const crossAxisMulti = rtl && isVertical ? -1 : 1;
5095
+ const rawValue = evaluate(options, state);
5096
+ let {
5097
+ mainAxis,
5098
+ crossAxis,
5099
+ alignmentAxis
5100
+ } = typeof rawValue === "number" ? {
5101
+ mainAxis: rawValue,
5102
+ crossAxis: 0,
5103
+ alignmentAxis: null
5104
+ } : {
5105
+ mainAxis: rawValue.mainAxis || 0,
5106
+ crossAxis: rawValue.crossAxis || 0,
5107
+ alignmentAxis: rawValue.alignmentAxis
5108
+ };
5109
+ if (alignment && typeof alignmentAxis === "number") {
5110
+ crossAxis = alignment === "end" ? alignmentAxis * -1 : alignmentAxis;
5111
+ }
5112
+ return isVertical ? {
5113
+ x: crossAxis * crossAxisMulti,
5114
+ y: mainAxis * mainAxisMulti
5115
+ } : {
5116
+ x: mainAxis * mainAxisMulti,
5117
+ y: crossAxis * crossAxisMulti
5118
+ };
5119
+ }
5120
+ var offset = function(options) {
5121
+ if (options === void 0) {
5122
+ options = 0;
5123
+ }
5124
+ return {
5125
+ name: "offset",
5126
+ options,
5127
+ async fn(state) {
5128
+ var _middlewareData$offse, _middlewareData$arrow;
5129
+ const {
5130
+ x,
5131
+ y,
5132
+ placement,
5133
+ middlewareData
5134
+ } = state;
5135
+ const diffCoords = await convertValueToCoords(state, options);
5136
+ if (placement === ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse.placement) && (_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
5137
+ return {};
5138
+ }
5139
+ return {
5140
+ x: x + diffCoords.x,
5141
+ y: y + diffCoords.y,
5142
+ data: {
5143
+ ...diffCoords,
5144
+ placement
5145
+ }
5146
+ };
5147
+ }
5148
+ };
5149
+ };
5150
+ var shift = function(options) {
5151
+ if (options === void 0) {
5152
+ options = {};
5153
+ }
5154
+ return {
5155
+ name: "shift",
5156
+ options,
5157
+ async fn(state) {
5158
+ const {
5159
+ x,
5160
+ y,
5161
+ placement
5162
+ } = state;
5163
+ const {
5164
+ mainAxis: checkMainAxis = true,
5165
+ crossAxis: checkCrossAxis = false,
5166
+ limiter = {
5167
+ fn: (_ref) => {
5168
+ let {
5169
+ x: x2,
5170
+ y: y2
5171
+ } = _ref;
5172
+ return {
5173
+ x: x2,
5174
+ y: y2
5175
+ };
5176
+ }
5177
+ },
5178
+ ...detectOverflowOptions
5179
+ } = evaluate(options, state);
5180
+ const coords = {
5181
+ x,
5182
+ y
5183
+ };
5184
+ const overflow = await detectOverflow(state, detectOverflowOptions);
5185
+ const crossAxis = getSideAxis(getSide(placement));
5186
+ const mainAxis = getOppositeAxis(crossAxis);
5187
+ let mainAxisCoord = coords[mainAxis];
5188
+ let crossAxisCoord = coords[crossAxis];
5189
+ if (checkMainAxis) {
5190
+ const minSide = mainAxis === "y" ? "top" : "left";
5191
+ const maxSide = mainAxis === "y" ? "bottom" : "right";
5192
+ const min2 = mainAxisCoord + overflow[minSide];
5193
+ const max2 = mainAxisCoord - overflow[maxSide];
5194
+ mainAxisCoord = clamp(min2, mainAxisCoord, max2);
5195
+ }
5196
+ if (checkCrossAxis) {
5197
+ const minSide = crossAxis === "y" ? "top" : "left";
5198
+ const maxSide = crossAxis === "y" ? "bottom" : "right";
5199
+ const min2 = crossAxisCoord + overflow[minSide];
5200
+ const max2 = crossAxisCoord - overflow[maxSide];
5201
+ crossAxisCoord = clamp(min2, crossAxisCoord, max2);
5202
+ }
5203
+ const limitedCoords = limiter.fn({
5204
+ ...state,
5205
+ [mainAxis]: mainAxisCoord,
5206
+ [crossAxis]: crossAxisCoord
5207
+ });
5208
+ return {
5209
+ ...limitedCoords,
5210
+ data: {
5211
+ x: limitedCoords.x - x,
5212
+ y: limitedCoords.y - y,
5213
+ enabled: {
5214
+ [mainAxis]: checkMainAxis,
5215
+ [crossAxis]: checkCrossAxis
5216
+ }
5217
+ }
5218
+ };
5219
+ }
5220
+ };
5221
+ };
5222
+ var size = function(options) {
5223
+ if (options === void 0) {
5224
+ options = {};
5225
+ }
5226
+ return {
5227
+ name: "size",
5228
+ options,
5229
+ async fn(state) {
5230
+ var _state$middlewareData, _state$middlewareData2;
5231
+ const {
5232
+ placement,
5233
+ rects,
5234
+ platform: platform2,
5235
+ elements
5236
+ } = state;
5237
+ const {
5238
+ apply = () => {
5239
+ },
5240
+ ...detectOverflowOptions
5241
+ } = evaluate(options, state);
5242
+ const overflow = await detectOverflow(state, detectOverflowOptions);
5243
+ const side = getSide(placement);
5244
+ const alignment = getAlignment(placement);
5245
+ const isYAxis = getSideAxis(placement) === "y";
5246
+ const {
5247
+ width,
5248
+ height
5249
+ } = rects.floating;
5250
+ let heightSide;
5251
+ let widthSide;
5252
+ if (side === "top" || side === "bottom") {
5253
+ heightSide = side;
5254
+ widthSide = alignment === (await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating)) ? "start" : "end") ? "left" : "right";
5255
+ } else {
5256
+ widthSide = side;
5257
+ heightSide = alignment === "end" ? "top" : "bottom";
5258
+ }
5259
+ const maximumClippingHeight = height - overflow.top - overflow.bottom;
5260
+ const maximumClippingWidth = width - overflow.left - overflow.right;
5261
+ const overflowAvailableHeight = min(height - overflow[heightSide], maximumClippingHeight);
5262
+ const overflowAvailableWidth = min(width - overflow[widthSide], maximumClippingWidth);
5263
+ const noShift = !state.middlewareData.shift;
5264
+ let availableHeight = overflowAvailableHeight;
5265
+ let availableWidth = overflowAvailableWidth;
5266
+ if ((_state$middlewareData = state.middlewareData.shift) != null && _state$middlewareData.enabled.x) {
5267
+ availableWidth = maximumClippingWidth;
5268
+ }
5269
+ if ((_state$middlewareData2 = state.middlewareData.shift) != null && _state$middlewareData2.enabled.y) {
5270
+ availableHeight = maximumClippingHeight;
5271
+ }
5272
+ if (noShift && !alignment) {
5273
+ const xMin = max(overflow.left, 0);
5274
+ const xMax = max(overflow.right, 0);
5275
+ const yMin = max(overflow.top, 0);
5276
+ const yMax = max(overflow.bottom, 0);
5277
+ if (isYAxis) {
5278
+ availableWidth = width - 2 * (xMin !== 0 || xMax !== 0 ? xMin + xMax : max(overflow.left, overflow.right));
5279
+ } else {
5280
+ availableHeight = height - 2 * (yMin !== 0 || yMax !== 0 ? yMin + yMax : max(overflow.top, overflow.bottom));
5281
+ }
5282
+ }
5283
+ await apply({
5284
+ ...state,
5285
+ availableWidth,
5286
+ availableHeight
5287
+ });
5288
+ const nextDimensions = await platform2.getDimensions(elements.floating);
5289
+ if (width !== nextDimensions.width || height !== nextDimensions.height) {
5290
+ return {
5291
+ reset: {
5292
+ rects: true
5293
+ }
5294
+ };
5295
+ }
5296
+ return {};
5297
+ }
5298
+ };
5299
+ };
5300
+
5301
+ // ../../node_modules/.pnpm/@floating-ui+dom@1.7.4/node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs
5302
+ function getCssDimensions(element) {
5303
+ const css = getComputedStyle2(element);
5304
+ let width = parseFloat(css.width) || 0;
5305
+ let height = parseFloat(css.height) || 0;
5306
+ const hasOffset = isHTMLElement(element);
5307
+ const offsetWidth = hasOffset ? element.offsetWidth : width;
5308
+ const offsetHeight = hasOffset ? element.offsetHeight : height;
5309
+ const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
5310
+ if (shouldFallback) {
5311
+ width = offsetWidth;
5312
+ height = offsetHeight;
5313
+ }
5314
+ return {
5315
+ width,
5316
+ height,
5317
+ $: shouldFallback
5318
+ };
5319
+ }
5320
+ function unwrapElement(element) {
5321
+ return !isElement(element) ? element.contextElement : element;
5322
+ }
5323
+ function getScale(element) {
5324
+ const domElement = unwrapElement(element);
5325
+ if (!isHTMLElement(domElement)) {
5326
+ return createCoords(1);
5327
+ }
5328
+ const rect = domElement.getBoundingClientRect();
5329
+ const {
5330
+ width,
5331
+ height,
5332
+ $
5333
+ } = getCssDimensions(domElement);
5334
+ let x = ($ ? round(rect.width) : rect.width) / width;
5335
+ let y = ($ ? round(rect.height) : rect.height) / height;
5336
+ if (!x || !Number.isFinite(x)) {
5337
+ x = 1;
5338
+ }
5339
+ if (!y || !Number.isFinite(y)) {
5340
+ y = 1;
5341
+ }
5342
+ return {
5343
+ x,
5344
+ y
5345
+ };
5346
+ }
5347
+ var noOffsets = /* @__PURE__ */ createCoords(0);
5348
+ function getVisualOffsets(element) {
5349
+ const win = getWindow(element);
5350
+ if (!isWebKit() || !win.visualViewport) {
5351
+ return noOffsets;
5352
+ }
5353
+ return {
5354
+ x: win.visualViewport.offsetLeft,
5355
+ y: win.visualViewport.offsetTop
5356
+ };
5357
+ }
5358
+ function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
5359
+ if (isFixed === void 0) {
5360
+ isFixed = false;
5361
+ }
5362
+ if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {
5363
+ return false;
5364
+ }
5365
+ return isFixed;
5366
+ }
5367
+ function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
5368
+ if (includeScale === void 0) {
5369
+ includeScale = false;
5370
+ }
5371
+ if (isFixedStrategy === void 0) {
5372
+ isFixedStrategy = false;
5373
+ }
5374
+ const clientRect = element.getBoundingClientRect();
5375
+ const domElement = unwrapElement(element);
5376
+ let scale = createCoords(1);
5377
+ if (includeScale) {
5378
+ if (offsetParent) {
5379
+ if (isElement(offsetParent)) {
5380
+ scale = getScale(offsetParent);
5381
+ }
5382
+ } else {
5383
+ scale = getScale(element);
5384
+ }
5385
+ }
5386
+ const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);
5387
+ let x = (clientRect.left + visualOffsets.x) / scale.x;
5388
+ let y = (clientRect.top + visualOffsets.y) / scale.y;
5389
+ let width = clientRect.width / scale.x;
5390
+ let height = clientRect.height / scale.y;
5391
+ if (domElement) {
5392
+ const win = getWindow(domElement);
5393
+ const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
5394
+ let currentWin = win;
5395
+ let currentIFrame = getFrameElement(currentWin);
5396
+ while (currentIFrame && offsetParent && offsetWin !== currentWin) {
5397
+ const iframeScale = getScale(currentIFrame);
5398
+ const iframeRect = currentIFrame.getBoundingClientRect();
5399
+ const css = getComputedStyle2(currentIFrame);
5400
+ const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
5401
+ const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
5402
+ x *= iframeScale.x;
5403
+ y *= iframeScale.y;
5404
+ width *= iframeScale.x;
5405
+ height *= iframeScale.y;
5406
+ x += left;
5407
+ y += top;
5408
+ currentWin = getWindow(currentIFrame);
5409
+ currentIFrame = getFrameElement(currentWin);
5410
+ }
5411
+ }
5412
+ return rectToClientRect({
5413
+ width,
5414
+ height,
5415
+ x,
5416
+ y
5417
+ });
5418
+ }
5419
+ function getWindowScrollBarX(element, rect) {
5420
+ const leftScroll = getNodeScroll(element).scrollLeft;
5421
+ if (!rect) {
5422
+ return getBoundingClientRect(getDocumentElement(element)).left + leftScroll;
5423
+ }
5424
+ return rect.left + leftScroll;
5425
+ }
5426
+ function getHTMLOffset(documentElement, scroll) {
5427
+ const htmlRect = documentElement.getBoundingClientRect();
5428
+ const x = htmlRect.left + scroll.scrollLeft - getWindowScrollBarX(documentElement, htmlRect);
5429
+ const y = htmlRect.top + scroll.scrollTop;
5430
+ return {
5431
+ x,
5432
+ y
5433
+ };
5434
+ }
5435
+ function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
5436
+ let {
5437
+ elements,
5438
+ rect,
5439
+ offsetParent,
5440
+ strategy
5441
+ } = _ref;
5442
+ const isFixed = strategy === "fixed";
5443
+ const documentElement = getDocumentElement(offsetParent);
5444
+ const topLayer = elements ? isTopLayer(elements.floating) : false;
5445
+ if (offsetParent === documentElement || topLayer && isFixed) {
5446
+ return rect;
5447
+ }
5448
+ let scroll = {
5449
+ scrollLeft: 0,
5450
+ scrollTop: 0
5451
+ };
5452
+ let scale = createCoords(1);
5453
+ const offsets = createCoords(0);
5454
+ const isOffsetParentAnElement = isHTMLElement(offsetParent);
5455
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
5456
+ if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
5457
+ scroll = getNodeScroll(offsetParent);
5458
+ }
5459
+ if (isHTMLElement(offsetParent)) {
5460
+ const offsetRect = getBoundingClientRect(offsetParent);
5461
+ scale = getScale(offsetParent);
5462
+ offsets.x = offsetRect.x + offsetParent.clientLeft;
5463
+ offsets.y = offsetRect.y + offsetParent.clientTop;
5464
+ }
5465
+ }
5466
+ const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
5467
+ return {
5468
+ width: rect.width * scale.x,
5469
+ height: rect.height * scale.y,
5470
+ x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,
5471
+ y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y
5472
+ };
5473
+ }
5474
+ function getClientRects(element) {
5475
+ return Array.from(element.getClientRects());
5476
+ }
5477
+ function getDocumentRect(element) {
5478
+ const html = getDocumentElement(element);
5479
+ const scroll = getNodeScroll(element);
5480
+ const body = element.ownerDocument.body;
5481
+ const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
5482
+ const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
5483
+ let x = -scroll.scrollLeft + getWindowScrollBarX(element);
5484
+ const y = -scroll.scrollTop;
5485
+ if (getComputedStyle2(body).direction === "rtl") {
5486
+ x += max(html.clientWidth, body.clientWidth) - width;
5487
+ }
5488
+ return {
5489
+ width,
5490
+ height,
5491
+ x,
5492
+ y
5493
+ };
5494
+ }
5495
+ var SCROLLBAR_MAX = 25;
5496
+ function getViewportRect(element, strategy) {
5497
+ const win = getWindow(element);
5498
+ const html = getDocumentElement(element);
5499
+ const visualViewport = win.visualViewport;
5500
+ let width = html.clientWidth;
5501
+ let height = html.clientHeight;
5502
+ let x = 0;
5503
+ let y = 0;
5504
+ if (visualViewport) {
5505
+ width = visualViewport.width;
5506
+ height = visualViewport.height;
5507
+ const visualViewportBased = isWebKit();
5508
+ if (!visualViewportBased || visualViewportBased && strategy === "fixed") {
5509
+ x = visualViewport.offsetLeft;
5510
+ y = visualViewport.offsetTop;
5511
+ }
5512
+ }
5513
+ const windowScrollbarX = getWindowScrollBarX(html);
5514
+ if (windowScrollbarX <= 0) {
5515
+ const doc = html.ownerDocument;
5516
+ const body = doc.body;
5517
+ const bodyStyles = getComputedStyle(body);
5518
+ const bodyMarginInline = doc.compatMode === "CSS1Compat" ? parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight) || 0 : 0;
5519
+ const clippingStableScrollbarWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline);
5520
+ if (clippingStableScrollbarWidth <= SCROLLBAR_MAX) {
5521
+ width -= clippingStableScrollbarWidth;
5522
+ }
5523
+ } else if (windowScrollbarX <= SCROLLBAR_MAX) {
5524
+ width += windowScrollbarX;
5525
+ }
5526
+ return {
5527
+ width,
5528
+ height,
5529
+ x,
5530
+ y
5531
+ };
5532
+ }
5533
+ var absoluteOrFixed = /* @__PURE__ */ new Set(["absolute", "fixed"]);
5534
+ function getInnerBoundingClientRect(element, strategy) {
5535
+ const clientRect = getBoundingClientRect(element, true, strategy === "fixed");
5536
+ const top = clientRect.top + element.clientTop;
5537
+ const left = clientRect.left + element.clientLeft;
5538
+ const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);
5539
+ const width = element.clientWidth * scale.x;
5540
+ const height = element.clientHeight * scale.y;
5541
+ const x = left * scale.x;
5542
+ const y = top * scale.y;
5543
+ return {
5544
+ width,
5545
+ height,
5546
+ x,
5547
+ y
5548
+ };
5549
+ }
5550
+ function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
5551
+ let rect;
5552
+ if (clippingAncestor === "viewport") {
5553
+ rect = getViewportRect(element, strategy);
5554
+ } else if (clippingAncestor === "document") {
5555
+ rect = getDocumentRect(getDocumentElement(element));
5556
+ } else if (isElement(clippingAncestor)) {
5557
+ rect = getInnerBoundingClientRect(clippingAncestor, strategy);
5558
+ } else {
5559
+ const visualOffsets = getVisualOffsets(element);
5560
+ rect = {
5561
+ x: clippingAncestor.x - visualOffsets.x,
5562
+ y: clippingAncestor.y - visualOffsets.y,
5563
+ width: clippingAncestor.width,
5564
+ height: clippingAncestor.height
5565
+ };
5566
+ }
5567
+ return rectToClientRect(rect);
5568
+ }
5569
+ function hasFixedPositionAncestor(element, stopNode) {
5570
+ const parentNode = getParentNode(element);
5571
+ if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {
5572
+ return false;
5573
+ }
5574
+ return getComputedStyle2(parentNode).position === "fixed" || hasFixedPositionAncestor(parentNode, stopNode);
5575
+ }
5576
+ function getClippingElementAncestors(element, cache) {
5577
+ const cachedResult = cache.get(element);
5578
+ if (cachedResult) {
5579
+ return cachedResult;
5580
+ }
5581
+ let result = getOverflowAncestors(element, [], false).filter((el) => isElement(el) && getNodeName(el) !== "body");
5582
+ let currentContainingBlockComputedStyle = null;
5583
+ const elementIsFixed = getComputedStyle2(element).position === "fixed";
5584
+ let currentNode = elementIsFixed ? getParentNode(element) : element;
5585
+ while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
5586
+ const computedStyle = getComputedStyle2(currentNode);
5587
+ const currentNodeIsContaining = isContainingBlock(currentNode);
5588
+ if (!currentNodeIsContaining && computedStyle.position === "fixed") {
5589
+ currentContainingBlockComputedStyle = null;
5590
+ }
5591
+ const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === "static" && !!currentContainingBlockComputedStyle && absoluteOrFixed.has(currentContainingBlockComputedStyle.position) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
5592
+ if (shouldDropCurrentNode) {
5593
+ result = result.filter((ancestor) => ancestor !== currentNode);
5594
+ } else {
5595
+ currentContainingBlockComputedStyle = computedStyle;
5596
+ }
5597
+ currentNode = getParentNode(currentNode);
5598
+ }
5599
+ cache.set(element, result);
5600
+ return result;
5601
+ }
5602
+ function getClippingRect(_ref) {
5603
+ let {
5604
+ element,
5605
+ boundary,
5606
+ rootBoundary,
5607
+ strategy
5608
+ } = _ref;
5609
+ const elementClippingAncestors = boundary === "clippingAncestors" ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);
5610
+ const clippingAncestors = [...elementClippingAncestors, rootBoundary];
5611
+ const firstClippingAncestor = clippingAncestors[0];
5612
+ const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => {
5613
+ const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy);
5614
+ accRect.top = max(rect.top, accRect.top);
5615
+ accRect.right = min(rect.right, accRect.right);
5616
+ accRect.bottom = min(rect.bottom, accRect.bottom);
5617
+ accRect.left = max(rect.left, accRect.left);
5618
+ return accRect;
5619
+ }, getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy));
5620
+ return {
5621
+ width: clippingRect.right - clippingRect.left,
5622
+ height: clippingRect.bottom - clippingRect.top,
5623
+ x: clippingRect.left,
5624
+ y: clippingRect.top
5625
+ };
5626
+ }
5627
+ function getDimensions(element) {
5628
+ const {
5629
+ width,
5630
+ height
5631
+ } = getCssDimensions(element);
5632
+ return {
5633
+ width,
5634
+ height
5635
+ };
5636
+ }
5637
+ function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
5638
+ const isOffsetParentAnElement = isHTMLElement(offsetParent);
5639
+ const documentElement = getDocumentElement(offsetParent);
5640
+ const isFixed = strategy === "fixed";
5641
+ const rect = getBoundingClientRect(element, true, isFixed, offsetParent);
5642
+ let scroll = {
5643
+ scrollLeft: 0,
5644
+ scrollTop: 0
5645
+ };
5646
+ const offsets = createCoords(0);
5647
+ function setLeftRTLScrollbarOffset() {
5648
+ offsets.x = getWindowScrollBarX(documentElement);
5649
+ }
5650
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
5651
+ if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
5652
+ scroll = getNodeScroll(offsetParent);
5653
+ }
5654
+ if (isOffsetParentAnElement) {
5655
+ const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
5656
+ offsets.x = offsetRect.x + offsetParent.clientLeft;
5657
+ offsets.y = offsetRect.y + offsetParent.clientTop;
5658
+ } else if (documentElement) {
5659
+ setLeftRTLScrollbarOffset();
5660
+ }
5661
+ }
5662
+ if (isFixed && !isOffsetParentAnElement && documentElement) {
5663
+ setLeftRTLScrollbarOffset();
5664
+ }
5665
+ const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
5666
+ const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
5667
+ const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;
5668
+ return {
5669
+ x,
5670
+ y,
5671
+ width: rect.width,
5672
+ height: rect.height
5673
+ };
5674
+ }
5675
+ function isStaticPositioned(element) {
5676
+ return getComputedStyle2(element).position === "static";
5677
+ }
5678
+ function getTrueOffsetParent(element, polyfill) {
5679
+ if (!isHTMLElement(element) || getComputedStyle2(element).position === "fixed") {
5680
+ return null;
5681
+ }
5682
+ if (polyfill) {
5683
+ return polyfill(element);
5684
+ }
5685
+ let rawOffsetParent = element.offsetParent;
5686
+ if (getDocumentElement(element) === rawOffsetParent) {
5687
+ rawOffsetParent = rawOffsetParent.ownerDocument.body;
5688
+ }
5689
+ return rawOffsetParent;
5690
+ }
5691
+ function getOffsetParent(element, polyfill) {
5692
+ const win = getWindow(element);
5693
+ if (isTopLayer(element)) {
5694
+ return win;
5695
+ }
5696
+ if (!isHTMLElement(element)) {
5697
+ let svgOffsetParent = getParentNode(element);
5698
+ while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) {
5699
+ if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) {
5700
+ return svgOffsetParent;
5701
+ }
5702
+ svgOffsetParent = getParentNode(svgOffsetParent);
5703
+ }
5704
+ return win;
5705
+ }
5706
+ let offsetParent = getTrueOffsetParent(element, polyfill);
5707
+ while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) {
5708
+ offsetParent = getTrueOffsetParent(offsetParent, polyfill);
5709
+ }
5710
+ if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) {
5711
+ return win;
5712
+ }
5713
+ return offsetParent || getContainingBlock(element) || win;
5714
+ }
5715
+ var getElementRects = async function(data) {
5716
+ const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
5717
+ const getDimensionsFn = this.getDimensions;
5718
+ const floatingDimensions = await getDimensionsFn(data.floating);
5719
+ return {
5720
+ reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy),
5721
+ floating: {
5722
+ x: 0,
5723
+ y: 0,
5724
+ width: floatingDimensions.width,
5725
+ height: floatingDimensions.height
5726
+ }
5727
+ };
5728
+ };
5729
+ function isRTL(element) {
5730
+ return getComputedStyle2(element).direction === "rtl";
5731
+ }
5732
+ var platform = {
5733
+ convertOffsetParentRelativeRectToViewportRelativeRect,
5734
+ getDocumentElement,
5735
+ getClippingRect,
5736
+ getOffsetParent,
5737
+ getElementRects,
5738
+ getClientRects,
5739
+ getDimensions,
5740
+ getScale,
5741
+ isElement,
5742
+ isRTL
5743
+ };
5744
+ function rectsAreEqual(a, b) {
5745
+ return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
5746
+ }
5747
+ function observeMove(element, onMove) {
5748
+ let io = null;
5749
+ let timeoutId;
5750
+ const root = getDocumentElement(element);
5751
+ function cleanup() {
5752
+ var _io;
5753
+ clearTimeout(timeoutId);
5754
+ (_io = io) == null || _io.disconnect();
5755
+ io = null;
5756
+ }
5757
+ function refresh(skip, threshold) {
5758
+ if (skip === void 0) {
5759
+ skip = false;
5760
+ }
5761
+ if (threshold === void 0) {
5762
+ threshold = 1;
5763
+ }
5764
+ cleanup();
5765
+ const elementRectForRootMargin = element.getBoundingClientRect();
5766
+ const {
5767
+ left,
5768
+ top,
5769
+ width,
5770
+ height
5771
+ } = elementRectForRootMargin;
5772
+ if (!skip) {
5773
+ onMove();
5774
+ }
5775
+ if (!width || !height) {
5776
+ return;
5777
+ }
5778
+ const insetTop = floor(top);
5779
+ const insetRight = floor(root.clientWidth - (left + width));
5780
+ const insetBottom = floor(root.clientHeight - (top + height));
5781
+ const insetLeft = floor(left);
5782
+ const rootMargin = -insetTop + "px " + -insetRight + "px " + -insetBottom + "px " + -insetLeft + "px";
5783
+ const options = {
5784
+ rootMargin,
5785
+ threshold: max(0, min(1, threshold)) || 1
5786
+ };
5787
+ let isFirstUpdate = true;
5788
+ function handleObserve(entries) {
5789
+ const ratio = entries[0].intersectionRatio;
5790
+ if (ratio !== threshold) {
5791
+ if (!isFirstUpdate) {
5792
+ return refresh();
5793
+ }
5794
+ if (!ratio) {
5795
+ timeoutId = setTimeout(() => {
5796
+ refresh(false, 1e-7);
5797
+ }, 1e3);
5798
+ } else {
5799
+ refresh(false, ratio);
5800
+ }
5801
+ }
5802
+ if (ratio === 1 && !rectsAreEqual(elementRectForRootMargin, element.getBoundingClientRect())) {
5803
+ refresh();
5804
+ }
5805
+ isFirstUpdate = false;
5806
+ }
5807
+ try {
5808
+ io = new IntersectionObserver(handleObserve, {
5809
+ ...options,
5810
+ // Handle <iframe>s
5811
+ root: root.ownerDocument
5812
+ });
5813
+ } catch (_e) {
5814
+ io = new IntersectionObserver(handleObserve, options);
5815
+ }
5816
+ io.observe(element);
5817
+ }
5818
+ refresh(true);
5819
+ return cleanup;
5820
+ }
5821
+ function autoUpdate(reference, floating, update, options) {
5822
+ if (options === void 0) {
5823
+ options = {};
5824
+ }
5825
+ const {
5826
+ ancestorScroll = true,
5827
+ ancestorResize = true,
5828
+ elementResize = typeof ResizeObserver === "function",
5829
+ layoutShift = typeof IntersectionObserver === "function",
5830
+ animationFrame = false
5831
+ } = options;
5832
+ const referenceEl = unwrapElement(reference);
5833
+ const ancestors = ancestorScroll || ancestorResize ? [...referenceEl ? getOverflowAncestors(referenceEl) : [], ...getOverflowAncestors(floating)] : [];
5834
+ ancestors.forEach((ancestor) => {
5835
+ ancestorScroll && ancestor.addEventListener("scroll", update, {
5836
+ passive: true
5837
+ });
5838
+ ancestorResize && ancestor.addEventListener("resize", update);
5839
+ });
5840
+ const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update) : null;
5841
+ let reobserveFrame = -1;
5842
+ let resizeObserver = null;
5843
+ if (elementResize) {
5844
+ resizeObserver = new ResizeObserver((_ref) => {
5845
+ let [firstEntry] = _ref;
5846
+ if (firstEntry && firstEntry.target === referenceEl && resizeObserver) {
5847
+ resizeObserver.unobserve(floating);
5848
+ cancelAnimationFrame(reobserveFrame);
5849
+ reobserveFrame = requestAnimationFrame(() => {
5850
+ var _resizeObserver;
5851
+ (_resizeObserver = resizeObserver) == null || _resizeObserver.observe(floating);
5852
+ });
5853
+ }
5854
+ update();
5855
+ });
5856
+ if (referenceEl && !animationFrame) {
5857
+ resizeObserver.observe(referenceEl);
5858
+ }
5859
+ resizeObserver.observe(floating);
5860
+ }
5861
+ let frameId;
5862
+ let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
5863
+ if (animationFrame) {
5864
+ frameLoop();
5865
+ }
5866
+ function frameLoop() {
5867
+ const nextRefRect = getBoundingClientRect(reference);
5868
+ if (prevRefRect && !rectsAreEqual(prevRefRect, nextRefRect)) {
5869
+ update();
5870
+ }
5871
+ prevRefRect = nextRefRect;
5872
+ frameId = requestAnimationFrame(frameLoop);
5873
+ }
5874
+ update();
5875
+ return () => {
5876
+ var _resizeObserver2;
5877
+ ancestors.forEach((ancestor) => {
5878
+ ancestorScroll && ancestor.removeEventListener("scroll", update);
5879
+ ancestorResize && ancestor.removeEventListener("resize", update);
5880
+ });
5881
+ cleanupIo == null || cleanupIo();
5882
+ (_resizeObserver2 = resizeObserver) == null || _resizeObserver2.disconnect();
5883
+ resizeObserver = null;
5884
+ if (animationFrame) {
5885
+ cancelAnimationFrame(frameId);
5886
+ }
5887
+ };
5888
+ }
5889
+ var offset2 = offset;
5890
+ var shift2 = shift;
5891
+ var flip2 = flip;
5892
+ var size2 = size;
5893
+ var computePosition2 = (reference, floating, options) => {
5894
+ const cache = /* @__PURE__ */ new Map();
5895
+ const mergedOptions = {
5896
+ platform,
5897
+ ...options
5898
+ };
5899
+ const platformWithCache = {
5900
+ ...mergedOptions.platform,
5901
+ _c: cache
5902
+ };
5903
+ return computePosition(reference, floating, {
5904
+ ...mergedOptions,
5905
+ platform: platformWithCache
5906
+ });
5907
+ };
5908
+
5909
+ // ../../node_modules/.pnpm/@floating-ui+react-dom@2.1.6_react-dom@18.3.1_react@18.3.1/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.mjs
5910
+ var React2 = __toESM(require("react"), 1);
5911
+ var import_react13 = require("react");
5912
+ var ReactDOM = __toESM(require("react-dom"), 1);
5913
+ var isClient2 = typeof document !== "undefined";
5914
+ var noop3 = function noop4() {
5915
+ };
5916
+ var index2 = isClient2 ? import_react13.useLayoutEffect : noop3;
5917
+ function deepEqual(a, b) {
5918
+ if (a === b) {
5919
+ return true;
5920
+ }
5921
+ if (typeof a !== typeof b) {
5922
+ return false;
5923
+ }
5924
+ if (typeof a === "function" && a.toString() === b.toString()) {
5925
+ return true;
5926
+ }
5927
+ let length;
5928
+ let i;
5929
+ let keys;
5930
+ if (a && b && typeof a === "object") {
5931
+ if (Array.isArray(a)) {
5932
+ length = a.length;
5933
+ if (length !== b.length)
5934
+ return false;
5935
+ for (i = length; i-- !== 0; ) {
5936
+ if (!deepEqual(a[i], b[i])) {
5937
+ return false;
5938
+ }
5939
+ }
5940
+ return true;
5941
+ }
5942
+ keys = Object.keys(a);
5943
+ length = keys.length;
5944
+ if (length !== Object.keys(b).length) {
5945
+ return false;
5946
+ }
5947
+ for (i = length; i-- !== 0; ) {
5948
+ if (!{}.hasOwnProperty.call(b, keys[i])) {
5949
+ return false;
5950
+ }
5951
+ }
5952
+ for (i = length; i-- !== 0; ) {
5953
+ const key = keys[i];
5954
+ if (key === "_owner" && a.$$typeof) {
5955
+ continue;
5956
+ }
5957
+ if (!deepEqual(a[key], b[key])) {
5958
+ return false;
5959
+ }
5960
+ }
5961
+ return true;
5962
+ }
5963
+ return a !== a && b !== b;
5964
+ }
5965
+ function getDPR(element) {
5966
+ if (typeof window === "undefined") {
5967
+ return 1;
5968
+ }
5969
+ const win = element.ownerDocument.defaultView || window;
5970
+ return win.devicePixelRatio || 1;
5971
+ }
5972
+ function roundByDPR(element, value) {
5973
+ const dpr = getDPR(element);
5974
+ return Math.round(value * dpr) / dpr;
5975
+ }
5976
+ function useLatestRef(value) {
5977
+ const ref = React2.useRef(value);
5978
+ index2(() => {
5979
+ ref.current = value;
5980
+ });
5981
+ return ref;
5982
+ }
5983
+ function useFloating(options) {
5984
+ if (options === void 0) {
5985
+ options = {};
5986
+ }
5987
+ const {
5988
+ placement = "bottom",
5989
+ strategy = "absolute",
5990
+ middleware = [],
5991
+ platform: platform2,
5992
+ elements: {
5993
+ reference: externalReference,
5994
+ floating: externalFloating
5995
+ } = {},
5996
+ transform = true,
5997
+ whileElementsMounted,
5998
+ open
5999
+ } = options;
6000
+ const [data, setData] = React2.useState({
6001
+ x: 0,
6002
+ y: 0,
6003
+ strategy,
6004
+ placement,
6005
+ middlewareData: {},
6006
+ isPositioned: false
6007
+ });
6008
+ const [latestMiddleware, setLatestMiddleware] = React2.useState(middleware);
6009
+ if (!deepEqual(latestMiddleware, middleware)) {
6010
+ setLatestMiddleware(middleware);
6011
+ }
6012
+ const [_reference, _setReference] = React2.useState(null);
6013
+ const [_floating, _setFloating] = React2.useState(null);
6014
+ const setReference = React2.useCallback((node) => {
6015
+ if (node !== referenceRef.current) {
6016
+ referenceRef.current = node;
6017
+ _setReference(node);
6018
+ }
6019
+ }, []);
6020
+ const setFloating = React2.useCallback((node) => {
6021
+ if (node !== floatingRef.current) {
6022
+ floatingRef.current = node;
6023
+ _setFloating(node);
6024
+ }
6025
+ }, []);
6026
+ const referenceEl = externalReference || _reference;
6027
+ const floatingEl = externalFloating || _floating;
6028
+ const referenceRef = React2.useRef(null);
6029
+ const floatingRef = React2.useRef(null);
6030
+ const dataRef = React2.useRef(data);
6031
+ const hasWhileElementsMounted = whileElementsMounted != null;
6032
+ const whileElementsMountedRef = useLatestRef(whileElementsMounted);
6033
+ const platformRef = useLatestRef(platform2);
6034
+ const openRef = useLatestRef(open);
6035
+ const update = React2.useCallback(() => {
6036
+ if (!referenceRef.current || !floatingRef.current) {
6037
+ return;
6038
+ }
6039
+ const config = {
6040
+ placement,
6041
+ strategy,
6042
+ middleware: latestMiddleware
6043
+ };
6044
+ if (platformRef.current) {
6045
+ config.platform = platformRef.current;
6046
+ }
6047
+ computePosition2(referenceRef.current, floatingRef.current, config).then((data2) => {
6048
+ const fullData = {
6049
+ ...data2,
6050
+ // The floating element's position may be recomputed while it's closed
6051
+ // but still mounted (such as when transitioning out). To ensure
6052
+ // `isPositioned` will be `false` initially on the next open, avoid
6053
+ // setting it to `true` when `open === false` (must be specified).
6054
+ isPositioned: openRef.current !== false
6055
+ };
6056
+ if (isMountedRef.current && !deepEqual(dataRef.current, fullData)) {
6057
+ dataRef.current = fullData;
6058
+ ReactDOM.flushSync(() => {
6059
+ setData(fullData);
6060
+ });
6061
+ }
6062
+ });
6063
+ }, [latestMiddleware, placement, strategy, platformRef, openRef]);
6064
+ index2(() => {
6065
+ if (open === false && dataRef.current.isPositioned) {
6066
+ dataRef.current.isPositioned = false;
6067
+ setData((data2) => ({
6068
+ ...data2,
6069
+ isPositioned: false
6070
+ }));
6071
+ }
6072
+ }, [open]);
6073
+ const isMountedRef = React2.useRef(false);
6074
+ index2(() => {
6075
+ isMountedRef.current = true;
6076
+ return () => {
6077
+ isMountedRef.current = false;
6078
+ };
6079
+ }, []);
6080
+ index2(() => {
6081
+ if (referenceEl)
6082
+ referenceRef.current = referenceEl;
6083
+ if (floatingEl)
6084
+ floatingRef.current = floatingEl;
6085
+ if (referenceEl && floatingEl) {
6086
+ if (whileElementsMountedRef.current) {
6087
+ return whileElementsMountedRef.current(referenceEl, floatingEl, update);
6088
+ }
6089
+ update();
6090
+ }
6091
+ }, [referenceEl, floatingEl, update, whileElementsMountedRef, hasWhileElementsMounted]);
6092
+ const refs = React2.useMemo(() => ({
6093
+ reference: referenceRef,
6094
+ floating: floatingRef,
6095
+ setReference,
6096
+ setFloating
6097
+ }), [setReference, setFloating]);
6098
+ const elements = React2.useMemo(() => ({
6099
+ reference: referenceEl,
6100
+ floating: floatingEl
6101
+ }), [referenceEl, floatingEl]);
6102
+ const floatingStyles = React2.useMemo(() => {
6103
+ const initialStyles = {
6104
+ position: strategy,
6105
+ left: 0,
6106
+ top: 0
6107
+ };
6108
+ if (!elements.floating) {
6109
+ return initialStyles;
6110
+ }
6111
+ const x = roundByDPR(elements.floating, data.x);
6112
+ const y = roundByDPR(elements.floating, data.y);
6113
+ if (transform) {
6114
+ return {
6115
+ ...initialStyles,
6116
+ transform: "translate(" + x + "px, " + y + "px)",
6117
+ ...getDPR(elements.floating) >= 1.5 && {
6118
+ willChange: "transform"
6119
+ }
6120
+ };
6121
+ }
6122
+ return {
6123
+ position: strategy,
6124
+ left: x,
6125
+ top: y
6126
+ };
6127
+ }, [strategy, transform, elements.floating, data.x, data.y]);
6128
+ return React2.useMemo(() => ({
6129
+ ...data,
6130
+ update,
6131
+ refs,
6132
+ elements,
6133
+ floatingStyles
6134
+ }), [data, update, refs, elements, floatingStyles]);
6135
+ }
6136
+ var offset3 = (options, deps) => ({
6137
+ ...offset2(options),
6138
+ options: [options, deps]
6139
+ });
6140
+ var shift3 = (options, deps) => ({
6141
+ ...shift2(options),
6142
+ options: [options, deps]
6143
+ });
6144
+ var flip3 = (options, deps) => ({
6145
+ ...flip2(options),
6146
+ options: [options, deps]
6147
+ });
6148
+ var size3 = (options, deps) => ({
6149
+ ...size2(options),
6150
+ options: [options, deps]
6151
+ });
6152
+
6153
+ // ../../node_modules/.pnpm/@floating-ui+react@0.27.16_react-dom@18.3.1_react@18.3.1/node_modules/@floating-ui/react/dist/floating-ui.react.mjs
6154
+ var ARROW_LEFT = "ArrowLeft";
6155
+ var ARROW_RIGHT = "ArrowRight";
6156
+ var ARROW_UP = "ArrowUp";
6157
+ var ARROW_DOWN = "ArrowDown";
6158
+ var horizontalKeys = [ARROW_LEFT, ARROW_RIGHT];
6159
+ var verticalKeys = [ARROW_UP, ARROW_DOWN];
6160
+ var allKeys = [...horizontalKeys, ...verticalKeys];
6161
+ var SafeReact2 = {
6162
+ ...React3
6163
+ };
6164
+ var serverHandoffComplete = false;
6165
+ var count = 0;
6166
+ var genId = () => (
6167
+ // Ensure the id is unique with multiple independent versions of Floating UI
6168
+ // on <React 18
6169
+ "floating-ui-" + Math.random().toString(36).slice(2, 6) + count++
6170
+ );
6171
+ function useFloatingId() {
6172
+ const [id, setId] = React3.useState(() => serverHandoffComplete ? genId() : void 0);
6173
+ index(() => {
6174
+ if (id == null) {
6175
+ setId(genId());
6176
+ }
6177
+ }, []);
6178
+ React3.useEffect(() => {
6179
+ serverHandoffComplete = true;
6180
+ }, []);
6181
+ return id;
6182
+ }
6183
+ var useReactId = SafeReact2.useId;
6184
+ var useId = useReactId || useFloatingId;
6185
+ var devMessageSet;
6186
+ if (process.env.NODE_ENV !== "production") {
6187
+ devMessageSet = /* @__PURE__ */ new Set();
6188
+ }
6189
+ function error() {
6190
+ var _devMessageSet3;
6191
+ for (var _len2 = arguments.length, messages = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
6192
+ messages[_key2] = arguments[_key2];
6193
+ }
6194
+ const message = "Floating UI: " + messages.join(" ");
6195
+ if (!((_devMessageSet3 = devMessageSet) != null && _devMessageSet3.has(message))) {
6196
+ var _devMessageSet4;
6197
+ (_devMessageSet4 = devMessageSet) == null || _devMessageSet4.add(message);
6198
+ console.error(message);
6199
+ }
6200
+ }
6201
+ function createEventEmitter() {
6202
+ const map = /* @__PURE__ */ new Map();
6203
+ return {
6204
+ emit(event, data) {
6205
+ var _map$get;
6206
+ (_map$get = map.get(event)) == null || _map$get.forEach((listener) => listener(data));
6207
+ },
6208
+ on(event, listener) {
6209
+ if (!map.has(event)) {
6210
+ map.set(event, /* @__PURE__ */ new Set());
6211
+ }
6212
+ map.get(event).add(listener);
6213
+ },
6214
+ off(event, listener) {
6215
+ var _map$get2;
6216
+ (_map$get2 = map.get(event)) == null || _map$get2.delete(listener);
6217
+ }
6218
+ };
6219
+ }
6220
+ var FloatingNodeContext = /* @__PURE__ */ React3.createContext(null);
6221
+ var FloatingTreeContext = /* @__PURE__ */ React3.createContext(null);
6222
+ var useFloatingParentNodeId = () => {
6223
+ var _React$useContext;
6224
+ return ((_React$useContext = React3.useContext(FloatingNodeContext)) == null ? void 0 : _React$useContext.id) || null;
6225
+ };
6226
+ var useFloatingTree = () => React3.useContext(FloatingTreeContext);
6227
+ function createAttribute(name) {
6228
+ return "data-floating-ui-" + name;
6229
+ }
6230
+ var HIDDEN_STYLES = {
6231
+ border: 0,
6232
+ clip: "rect(0 0 0 0)",
6233
+ height: "1px",
6234
+ margin: "-1px",
6235
+ overflow: "hidden",
6236
+ padding: 0,
6237
+ position: "fixed",
6238
+ whiteSpace: "nowrap",
6239
+ width: "1px",
6240
+ top: 0,
6241
+ left: 0
6242
+ };
6243
+ var FocusGuard = /* @__PURE__ */ React3.forwardRef(function FocusGuard2(props, ref) {
6244
+ const [role, setRole] = React3.useState();
6245
+ index(() => {
6246
+ if (isSafari()) {
6247
+ setRole("button");
6248
+ }
6249
+ }, []);
6250
+ const restProps = {
6251
+ ref,
6252
+ tabIndex: 0,
6253
+ // Role is only for VoiceOver
6254
+ role,
6255
+ "aria-hidden": role ? void 0 : true,
6256
+ [createAttribute("focus-guard")]: "",
6257
+ style: HIDDEN_STYLES
6258
+ };
6259
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", {
6260
+ ...props,
6261
+ ...restProps
6262
+ });
6263
+ });
6264
+ var PortalContext = /* @__PURE__ */ React3.createContext(null);
6265
+ var attr = /* @__PURE__ */ createAttribute("portal");
6266
+ function useFloatingPortalNode(props) {
6267
+ if (props === void 0) {
6268
+ props = {};
6269
+ }
6270
+ const {
6271
+ id,
6272
+ root
6273
+ } = props;
6274
+ const uniqueId = useId();
6275
+ const portalContext = usePortalContext();
6276
+ const [portalNode, setPortalNode] = React3.useState(null);
6277
+ const portalNodeRef = React3.useRef(null);
6278
+ index(() => {
6279
+ return () => {
6280
+ portalNode == null || portalNode.remove();
6281
+ queueMicrotask(() => {
6282
+ portalNodeRef.current = null;
6283
+ });
6284
+ };
6285
+ }, [portalNode]);
6286
+ index(() => {
6287
+ if (!uniqueId)
6288
+ return;
6289
+ if (portalNodeRef.current)
6290
+ return;
6291
+ const existingIdRoot = id ? document.getElementById(id) : null;
6292
+ if (!existingIdRoot)
6293
+ return;
6294
+ const subRoot = document.createElement("div");
6295
+ subRoot.id = uniqueId;
6296
+ subRoot.setAttribute(attr, "");
6297
+ existingIdRoot.appendChild(subRoot);
6298
+ portalNodeRef.current = subRoot;
6299
+ setPortalNode(subRoot);
6300
+ }, [id, uniqueId]);
6301
+ index(() => {
6302
+ if (root === null)
6303
+ return;
6304
+ if (!uniqueId)
6305
+ return;
6306
+ if (portalNodeRef.current)
6307
+ return;
6308
+ let container = root || (portalContext == null ? void 0 : portalContext.portalNode);
6309
+ if (container && !isNode(container))
6310
+ container = container.current;
6311
+ container = container || document.body;
6312
+ let idWrapper = null;
6313
+ if (id) {
6314
+ idWrapper = document.createElement("div");
6315
+ idWrapper.id = id;
6316
+ container.appendChild(idWrapper);
6317
+ }
6318
+ const subRoot = document.createElement("div");
6319
+ subRoot.id = uniqueId;
6320
+ subRoot.setAttribute(attr, "");
6321
+ container = idWrapper || container;
6322
+ container.appendChild(subRoot);
6323
+ portalNodeRef.current = subRoot;
6324
+ setPortalNode(subRoot);
6325
+ }, [id, root, uniqueId, portalContext]);
6326
+ return portalNode;
6327
+ }
6328
+ function FloatingPortal(props) {
6329
+ const {
6330
+ children,
6331
+ id,
6332
+ root,
6333
+ preserveTabOrder = true
6334
+ } = props;
6335
+ const portalNode = useFloatingPortalNode({
6336
+ id,
6337
+ root
6338
+ });
6339
+ const [focusManagerState, setFocusManagerState] = React3.useState(null);
6340
+ const beforeOutsideRef = React3.useRef(null);
6341
+ const afterOutsideRef = React3.useRef(null);
6342
+ const beforeInsideRef = React3.useRef(null);
6343
+ const afterInsideRef = React3.useRef(null);
6344
+ const modal = focusManagerState == null ? void 0 : focusManagerState.modal;
6345
+ const open = focusManagerState == null ? void 0 : focusManagerState.open;
6346
+ const shouldRenderGuards = (
6347
+ // The FocusManager and therefore floating element are currently open/
6348
+ // rendered.
6349
+ !!focusManagerState && // Guards are only for non-modal focus management.
6350
+ !focusManagerState.modal && // Don't render if unmount is transitioning.
6351
+ focusManagerState.open && preserveTabOrder && !!(root || portalNode)
6352
+ );
6353
+ React3.useEffect(() => {
6354
+ if (!portalNode || !preserveTabOrder || modal) {
6355
+ return;
6356
+ }
6357
+ function onFocus(event) {
6358
+ if (portalNode && isOutsideEvent(event)) {
6359
+ const focusing = event.type === "focusin";
6360
+ const manageFocus = focusing ? enableFocusInside : disableFocusInside;
6361
+ manageFocus(portalNode);
6362
+ }
6363
+ }
6364
+ portalNode.addEventListener("focusin", onFocus, true);
6365
+ portalNode.addEventListener("focusout", onFocus, true);
6366
+ return () => {
6367
+ portalNode.removeEventListener("focusin", onFocus, true);
6368
+ portalNode.removeEventListener("focusout", onFocus, true);
6369
+ };
6370
+ }, [portalNode, preserveTabOrder, modal]);
6371
+ React3.useEffect(() => {
6372
+ if (!portalNode)
6373
+ return;
6374
+ if (open)
6375
+ return;
6376
+ enableFocusInside(portalNode);
6377
+ }, [open, portalNode]);
6378
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(PortalContext.Provider, {
6379
+ value: React3.useMemo(() => ({
6380
+ preserveTabOrder,
6381
+ beforeOutsideRef,
6382
+ afterOutsideRef,
6383
+ beforeInsideRef,
6384
+ afterInsideRef,
6385
+ portalNode,
6386
+ setFocusManagerState
6387
+ }), [preserveTabOrder, portalNode]),
6388
+ children: [shouldRenderGuards && portalNode && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(FocusGuard, {
6389
+ "data-type": "outside",
6390
+ ref: beforeOutsideRef,
6391
+ onFocus: (event) => {
6392
+ if (isOutsideEvent(event, portalNode)) {
6393
+ var _beforeInsideRef$curr;
6394
+ (_beforeInsideRef$curr = beforeInsideRef.current) == null || _beforeInsideRef$curr.focus();
6395
+ } else {
6396
+ const domReference = focusManagerState ? focusManagerState.domReference : null;
6397
+ const prevTabbable = getPreviousTabbable(domReference);
6398
+ prevTabbable == null || prevTabbable.focus();
6399
+ }
6400
+ }
6401
+ }), shouldRenderGuards && portalNode && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", {
6402
+ "aria-owns": portalNode.id,
6403
+ style: HIDDEN_STYLES
6404
+ }), portalNode && /* @__PURE__ */ ReactDOM2.createPortal(children, portalNode), shouldRenderGuards && portalNode && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(FocusGuard, {
6405
+ "data-type": "outside",
6406
+ ref: afterOutsideRef,
6407
+ onFocus: (event) => {
6408
+ if (isOutsideEvent(event, portalNode)) {
6409
+ var _afterInsideRef$curre;
6410
+ (_afterInsideRef$curre = afterInsideRef.current) == null || _afterInsideRef$curre.focus();
6411
+ } else {
6412
+ const domReference = focusManagerState ? focusManagerState.domReference : null;
6413
+ const nextTabbable = getNextTabbable(domReference);
6414
+ nextTabbable == null || nextTabbable.focus();
6415
+ (focusManagerState == null ? void 0 : focusManagerState.closeOnFocusOut) && (focusManagerState == null ? void 0 : focusManagerState.onOpenChange(false, event.nativeEvent, "focus-out"));
6416
+ }
6417
+ }
6418
+ })]
6419
+ });
6420
+ }
6421
+ var usePortalContext = () => React3.useContext(PortalContext);
6422
+ function useFloatingRootContext(options) {
6423
+ const {
6424
+ open = false,
6425
+ onOpenChange: onOpenChangeProp,
6426
+ elements: elementsProp
6427
+ } = options;
6428
+ const floatingId = useId();
6429
+ const dataRef = React3.useRef({});
6430
+ const [events] = React3.useState(() => createEventEmitter());
6431
+ const nested = useFloatingParentNodeId() != null;
6432
+ if (process.env.NODE_ENV !== "production") {
6433
+ const optionDomReference = elementsProp.reference;
6434
+ if (optionDomReference && !isElement(optionDomReference)) {
6435
+ error("Cannot pass a virtual element to the `elements.reference` option,", "as it must be a real DOM element. Use `refs.setPositionReference()`", "instead.");
6436
+ }
6437
+ }
6438
+ const [positionReference, setPositionReference] = React3.useState(elementsProp.reference);
6439
+ const onOpenChange = useEffectEvent((open2, event, reason) => {
6440
+ dataRef.current.openEvent = open2 ? event : void 0;
6441
+ events.emit("openchange", {
6442
+ open: open2,
6443
+ event,
6444
+ reason,
6445
+ nested
6446
+ });
6447
+ onOpenChangeProp == null || onOpenChangeProp(open2, event, reason);
6448
+ });
6449
+ const refs = React3.useMemo(() => ({
6450
+ setPositionReference
6451
+ }), []);
6452
+ const elements = React3.useMemo(() => ({
6453
+ reference: positionReference || elementsProp.reference || null,
6454
+ floating: elementsProp.floating || null,
6455
+ domReference: elementsProp.reference
6456
+ }), [positionReference, elementsProp.reference, elementsProp.floating]);
6457
+ return React3.useMemo(() => ({
6458
+ dataRef,
6459
+ open,
6460
+ onOpenChange,
6461
+ elements,
6462
+ events,
6463
+ floatingId,
6464
+ refs
6465
+ }), [open, onOpenChange, elements, events, floatingId, refs]);
6466
+ }
6467
+ function useFloating2(options) {
6468
+ if (options === void 0) {
6469
+ options = {};
6470
+ }
6471
+ const {
6472
+ nodeId
6473
+ } = options;
6474
+ const internalRootContext = useFloatingRootContext({
6475
+ ...options,
6476
+ elements: {
6477
+ reference: null,
6478
+ floating: null,
6479
+ ...options.elements
6480
+ }
6481
+ });
6482
+ const rootContext = options.rootContext || internalRootContext;
6483
+ const computedElements = rootContext.elements;
6484
+ const [_domReference, setDomReference] = React3.useState(null);
6485
+ const [positionReference, _setPositionReference] = React3.useState(null);
6486
+ const optionDomReference = computedElements == null ? void 0 : computedElements.domReference;
6487
+ const domReference = optionDomReference || _domReference;
6488
+ const domReferenceRef = React3.useRef(null);
6489
+ const tree = useFloatingTree();
6490
+ index(() => {
6491
+ if (domReference) {
6492
+ domReferenceRef.current = domReference;
6493
+ }
6494
+ }, [domReference]);
6495
+ const position = useFloating({
6496
+ ...options,
6497
+ elements: {
6498
+ ...computedElements,
6499
+ ...positionReference && {
6500
+ reference: positionReference
6501
+ }
6502
+ }
6503
+ });
6504
+ const setPositionReference = React3.useCallback((node) => {
6505
+ const computedPositionReference = isElement(node) ? {
6506
+ getBoundingClientRect: () => node.getBoundingClientRect(),
6507
+ getClientRects: () => node.getClientRects(),
6508
+ contextElement: node
6509
+ } : node;
6510
+ _setPositionReference(computedPositionReference);
6511
+ position.refs.setReference(computedPositionReference);
6512
+ }, [position.refs]);
6513
+ const setReference = React3.useCallback((node) => {
6514
+ if (isElement(node) || node === null) {
6515
+ domReferenceRef.current = node;
6516
+ setDomReference(node);
6517
+ }
6518
+ if (isElement(position.refs.reference.current) || position.refs.reference.current === null || // Don't allow setting virtual elements using the old technique back to
6519
+ // `null` to support `positionReference` + an unstable `reference`
6520
+ // callback ref.
6521
+ node !== null && !isElement(node)) {
6522
+ position.refs.setReference(node);
6523
+ }
6524
+ }, [position.refs]);
6525
+ const refs = React3.useMemo(() => ({
6526
+ ...position.refs,
6527
+ setReference,
6528
+ setPositionReference,
6529
+ domReference: domReferenceRef
6530
+ }), [position.refs, setReference, setPositionReference]);
6531
+ const elements = React3.useMemo(() => ({
6532
+ ...position.elements,
6533
+ domReference
6534
+ }), [position.elements, domReference]);
6535
+ const context = React3.useMemo(() => ({
6536
+ ...position,
6537
+ ...rootContext,
6538
+ refs,
6539
+ elements,
6540
+ nodeId
6541
+ }), [position, refs, elements, nodeId, rootContext]);
6542
+ index(() => {
6543
+ rootContext.dataRef.current.floatingContext = context;
6544
+ const node = tree == null ? void 0 : tree.nodesRef.current.find((node2) => node2.id === nodeId);
6545
+ if (node) {
6546
+ node.context = context;
6547
+ }
6548
+ });
6549
+ return React3.useMemo(() => ({
6550
+ ...position,
6551
+ context,
6552
+ refs,
6553
+ elements
6554
+ }), [position, refs, elements, context]);
6555
+ }
6556
+
6557
+ // src/components/chat-composer/lib/chat-composer.ts
6558
+ var createUserMessage = ({
6559
+ sessionId,
6560
+ content,
6561
+ attachments,
6562
+ localOnly,
6563
+ createdAt,
6564
+ createMessageId
6565
+ }) => ({
6566
+ id: createMessageId(),
6567
+ sessionId,
6568
+ role: "user",
6569
+ content,
6570
+ attachments,
6571
+ localOnly,
6572
+ createdAt
6573
+ });
6574
+ var createAssistantStreamingMessage = ({
6575
+ sessionId,
6576
+ createdAt,
6577
+ createMessageId
6578
+ }) => ({
6579
+ id: createMessageId(),
6580
+ sessionId,
6581
+ role: "assistant",
6582
+ content: "",
6583
+ status: "streaming",
6584
+ createdAt
6585
+ });
6586
+ var canSendChatMessage = ({
6587
+ value,
6588
+ attachmentCount = 0,
6589
+ isModelsLoading,
6590
+ isModelsError,
6591
+ hasModels
6592
+ }) => {
6593
+ const hasText = Boolean(value.trim());
6594
+ const hasAttachments = attachmentCount > 0;
6595
+ if (!hasText && !hasAttachments)
6596
+ return false;
6597
+ if (!hasText && hasAttachments)
6598
+ return true;
6599
+ return !isModelsLoading && !isModelsError && hasModels;
6600
+ };
6601
+ var shouldSubmitChatComposer = ({
6602
+ key,
6603
+ shiftKey,
6604
+ canSend
6605
+ }) => key === "Enter" && !shiftKey && canSend;
6606
+ var shouldStopChatComposer = ({
6607
+ key,
6608
+ shiftKey,
6609
+ isStreaming
6610
+ }) => key === "Enter" && !shiftKey && isStreaming;
6611
+ var resolveSelectedChatModel = ({
6612
+ currentModel,
6613
+ availableModels,
6614
+ isModelsLoading
6615
+ }) => {
6616
+ if (!availableModels.length) {
6617
+ return isModelsLoading ? currentModel : "";
6618
+ }
6619
+ if (currentModel && availableModels.some((model) => model.id === currentModel)) {
6620
+ return currentModel;
6621
+ }
6622
+ return availableModels[0].id;
6623
+ };
6624
+ var resolveSendSession = ({
6625
+ activeSessionId,
6626
+ selectedModel,
6627
+ selectedMode,
6628
+ nowIso: nowIso2,
6629
+ createSessionId
6630
+ }) => {
6631
+ if (activeSessionId) {
6632
+ return {
6633
+ localSessionId: activeSessionId,
6634
+ sessionId: isDraftChatSessionId(activeSessionId) ? void 0 : activeSessionId
6635
+ };
6636
+ }
6637
+ const session = createDraftChatSession({
6638
+ model: selectedModel,
6639
+ mode: selectedMode ?? DEFAULT_CHAT_AGENT_MODE,
6640
+ nowIso: nowIso2,
6641
+ createSessionId
6642
+ });
6643
+ return { session, localSessionId: session.sessionId, sessionId: void 0 };
6644
+ };
6645
+
6646
+ // src/components/chat-composer/hooks/use-chat-composer.ts
6647
+ var import_react15 = require("react");
6648
+
6649
+ // src/components/chat-composer/hooks/use-composer-attachments.ts
6650
+ var import_react14 = require("react");
6651
+ var SUPPORTED_IMAGE_MIME_TYPES = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/webp"]);
6652
+ var MAX_COMPOSER_ATTACHMENTS = 10;
6653
+ var createObjectUrl = (file) => typeof URL !== "undefined" && typeof URL.createObjectURL === "function" ? URL.createObjectURL(file) : "";
6654
+ var revokeObjectUrl = (url) => {
6655
+ if (url && typeof URL !== "undefined" && typeof URL.revokeObjectURL === "function") {
6656
+ URL.revokeObjectURL(url);
6657
+ }
6658
+ };
6659
+ var createAttachmentId = () => `attachment-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
6660
+ var releaseComposerAttachments = (attachments) => {
6661
+ attachments.forEach((attachment) => revokeObjectUrl(attachment.previewUrl));
6662
+ };
6663
+ var useComposerAttachments = () => {
6664
+ const [attachments, setAttachments] = (0, import_react14.useState)([]);
6665
+ const attachmentsRef = (0, import_react14.useRef)([]);
6666
+ (0, import_react14.useEffect)(() => {
6667
+ attachmentsRef.current = attachments;
6668
+ }, [attachments]);
6669
+ (0, import_react14.useEffect)(
6670
+ () => () => {
6671
+ releaseComposerAttachments(attachmentsRef.current);
6672
+ },
6673
+ []
6674
+ );
6675
+ const appendFiles = (files) => {
6676
+ const validFiles = Array.from(files).filter((file) => SUPPORTED_IMAGE_MIME_TYPES.has(file.type));
6677
+ if (!validFiles.length)
6678
+ return { addedCount: 0, limitExceeded: false };
6679
+ const currentAttachments = attachmentsRef.current;
6680
+ const remainingSlots = MAX_COMPOSER_ATTACHMENTS - currentAttachments.length;
6681
+ if (remainingSlots <= 0)
6682
+ return { addedCount: 0, limitExceeded: true };
6683
+ const filesToAppend = validFiles.slice(0, remainingSlots);
6684
+ const newAttachments = filesToAppend.map((file) => ({
6685
+ id: createAttachmentId(),
6686
+ file,
6687
+ name: file.name,
6688
+ mimeType: file.type,
6689
+ size: file.size,
6690
+ previewUrl: createObjectUrl(file)
6691
+ }));
6692
+ setAttachments((current) => [...current, ...newAttachments]);
6693
+ return {
6694
+ addedCount: filesToAppend.length,
6695
+ limitExceeded: validFiles.length > filesToAppend.length
6696
+ };
6697
+ };
6698
+ const removeAttachment = (attachmentId) => {
6699
+ setAttachments((current) => {
6700
+ const target = current.find((a) => a.id === attachmentId);
6701
+ if (target)
6702
+ releaseComposerAttachments([target]);
6703
+ return current.filter((a) => a.id !== attachmentId);
6704
+ });
6705
+ };
6706
+ const clearAttachments = () => {
6707
+ setAttachments((current) => {
6708
+ releaseComposerAttachments(current);
6709
+ return [];
6710
+ });
6711
+ };
6712
+ const takeMessageAttachments = () => {
6713
+ const currentAttachments = attachmentsRef.current;
6714
+ if (!currentAttachments.length) {
6715
+ return [];
6716
+ }
6717
+ const nextMessageAttachments = currentAttachments.map(({ file: _file, ...attachment }) => ({
6718
+ ...attachment,
6719
+ file: _file
6720
+ }));
6721
+ attachmentsRef.current = [];
6722
+ setAttachments([]);
6723
+ return nextMessageAttachments;
6724
+ };
6725
+ return {
6726
+ attachments,
6727
+ appendFiles,
6728
+ removeAttachment,
6729
+ clearAttachments,
6730
+ takeMessageAttachments
6731
+ };
6732
+ };
6733
+
6734
+ // src/components/chat-composer/hooks/use-chat-composer.ts
6735
+ var nowIso = () => (/* @__PURE__ */ new Date()).toISOString();
6736
+ var ATTACHMENT_NOTICE_DURATION_MS = 3e3;
6737
+ var STOP_WAIT_TIMEOUT_MS = 3e3;
6738
+ var resolveAccumulatedContent = (currentContent, update) => {
6739
+ if (update.content !== void 0) {
6740
+ return update.content;
6741
+ }
6742
+ if (update.contentDelta) {
6743
+ return currentContent + update.contentDelta;
6744
+ }
6745
+ return currentContent;
6746
+ };
6747
+ var normalizeChatErrorMessage = (message, labels) => {
6748
+ const trimmedMessage = message?.trim();
6749
+ if (!trimmedMessage) {
6750
+ return labels.genericError;
6751
+ }
6752
+ if (trimmedMessage === "Failed to fetch") {
6753
+ return labels.networkError;
6754
+ }
6755
+ return trimmedMessage;
6756
+ };
6757
+ var skillsCacheByLoader = /* @__PURE__ */ new Map();
6758
+ var getCachedSkills = (loader) => {
6759
+ if (!loader) {
6760
+ return { skills: [], resolved: false };
6761
+ }
6762
+ const cachedEntry = skillsCacheByLoader.get(loader);
6763
+ return {
6764
+ skills: cachedEntry?.skills ?? [],
6765
+ resolved: cachedEntry?.resolved ?? false
6766
+ };
6767
+ };
6768
+ var loadSkillsWithCache = async (loader) => {
6769
+ const cachedEntry = skillsCacheByLoader.get(loader);
6770
+ if (cachedEntry?.resolved) {
6771
+ return cachedEntry.skills;
6772
+ }
6773
+ if (cachedEntry?.promise) {
6774
+ return cachedEntry.promise;
6775
+ }
6776
+ const pendingPromise = loader().then((response) => {
6777
+ const nextSkills = response.skills;
6778
+ skillsCacheByLoader.set(loader, { skills: nextSkills, resolved: true });
6779
+ return nextSkills;
6780
+ }).catch((error2) => {
6781
+ skillsCacheByLoader.delete(loader);
6782
+ throw error2;
6783
+ });
6784
+ skillsCacheByLoader.set(loader, {
6785
+ skills: cachedEntry?.skills ?? [],
6786
+ resolved: false,
6787
+ promise: pendingPromise
6788
+ });
6789
+ return pendingPromise;
6790
+ };
6791
+ var useChatComposer = () => {
6792
+ const { transport, enableImageAttachments, labels, store } = useChatContext();
6793
+ const modelsLoader = transport.getModels;
6794
+ const skillsLoader = transport.getSkills;
6795
+ const activeSkillsLoaderRef = (0, import_react15.useRef)(skillsLoader);
6796
+ const activeSessionId = useChatStore((s) => s.activeSessionId);
6797
+ const activeSession = useChatStore(
6798
+ (s) => s.sessions.find((x) => x.sessionId === s.activeSessionId) ?? null
6799
+ );
6800
+ const preferredMode = useChatStore((s) => s.preferredMode);
6801
+ const streamingSessionId = useChatStore(
6802
+ (s) => s.activeSessionId && s.isStreamingBySession[s.activeSessionId] ? s.activeSessionId : null
6803
+ );
6804
+ const isStreaming = Boolean(streamingSessionId);
6805
+ const isStopping = useChatStore((s) => {
6806
+ const currentStreamingSessionId = s.activeSessionId && s.isStreamingBySession[s.activeSessionId] ? s.activeSessionId : null;
6807
+ return currentStreamingSessionId ? s.isStoppingBySession[currentStreamingSessionId] ?? false : false;
6808
+ });
6809
+ const createSession = useChatStore((s) => s.createSession);
6810
+ const replaceSessionId = useChatStore((s) => s.replaceSessionId);
6811
+ const appendMessage = useChatStore((s) => s.appendMessage);
6812
+ const startStreamingMessage = useChatStore((s) => s.startStreamingMessage);
6813
+ const patchStreamingMessage = useChatStore((s) => s.patchStreamingMessage);
6814
+ const completeStreamingMessage = useChatStore((s) => s.completeStreamingMessage);
6815
+ const requestStopStreaming = useChatStore((s) => s.requestStopStreaming);
6816
+ const finalizeStoppedStreamingMessage = useChatStore((s) => s.finalizeStoppedStreamingMessage);
6817
+ const setSessionError = useChatStore((s) => s.setSessionError);
6818
+ const clearSessionError = useChatStore((s) => s.clearSessionError);
6819
+ const setPreferredMode = useChatStore((s) => s.setPreferredMode);
6820
+ const setSessionMode = useChatStore((s) => s.setSessionMode);
6821
+ const [availableModels, setAvailableModels] = (0, import_react15.useState)([]);
6822
+ const [isModelsLoading, setIsModelsLoading] = (0, import_react15.useState)(true);
6823
+ const [isModelsError, setIsModelsError] = (0, import_react15.useState)(false);
6824
+ const [availableSkills, setAvailableSkills] = (0, import_react15.useState)(
6825
+ () => getCachedSkills(skillsLoader).skills
6826
+ );
6827
+ const [isSkillsLoading, setIsSkillsLoading] = (0, import_react15.useState)(
6828
+ () => Boolean(skillsLoader) && !getCachedSkills(skillsLoader).resolved
6829
+ );
6830
+ const fetchModels = (0, import_react15.useCallback)(async () => {
6831
+ setIsModelsLoading(true);
6832
+ setIsModelsError(false);
4256
6833
  try {
4257
- const modelsResponse = await transport.getModels();
6834
+ const modelsResponse = await modelsLoader();
4258
6835
  setAvailableModels(modelsResponse.data);
4259
6836
  } catch {
4260
6837
  setIsModelsError(true);
4261
6838
  } finally {
4262
6839
  setIsModelsLoading(false);
4263
6840
  }
4264
- }, [transport]);
4265
- (0, import_react13.useEffect)(() => {
6841
+ }, [modelsLoader]);
6842
+ (0, import_react15.useEffect)(() => {
4266
6843
  void fetchModels();
4267
6844
  }, [fetchModels]);
6845
+ (0, import_react15.useEffect)(() => {
6846
+ activeSkillsLoaderRef.current = skillsLoader;
6847
+ const cachedSkills = getCachedSkills(skillsLoader);
6848
+ setAvailableSkills(cachedSkills.skills);
6849
+ setIsSkillsLoading(Boolean(skillsLoader) && !cachedSkills.resolved);
6850
+ }, [skillsLoader]);
6851
+ const fetchSkills = (0, import_react15.useCallback)(async () => {
6852
+ if (!skillsLoader) {
6853
+ setAvailableSkills([]);
6854
+ setIsSkillsLoading(false);
6855
+ return;
6856
+ }
6857
+ const cachedSkills = getCachedSkills(skillsLoader);
6858
+ if (cachedSkills.resolved) {
6859
+ setAvailableSkills(cachedSkills.skills);
6860
+ setIsSkillsLoading(false);
6861
+ return;
6862
+ }
6863
+ setIsSkillsLoading(true);
6864
+ try {
6865
+ const nextSkills = await loadSkillsWithCache(skillsLoader);
6866
+ if (activeSkillsLoaderRef.current !== skillsLoader) {
6867
+ return;
6868
+ }
6869
+ setAvailableSkills(nextSkills);
6870
+ } catch {
6871
+ if (activeSkillsLoaderRef.current !== skillsLoader) {
6872
+ return;
6873
+ }
6874
+ setAvailableSkills([]);
6875
+ } finally {
6876
+ if (activeSkillsLoaderRef.current === skillsLoader) {
6877
+ setIsSkillsLoading(false);
6878
+ }
6879
+ }
6880
+ }, [skillsLoader]);
6881
+ (0, import_react15.useEffect)(() => {
6882
+ void fetchSkills();
6883
+ }, [fetchSkills]);
4268
6884
  const hasModels = availableModels.length > 0;
4269
- const [value, setValue] = (0, import_react13.useState)("");
4270
- const [selectedModel, setSelectedModel] = (0, import_react13.useState)("");
4271
- const [selectedMode, setSelectedModeLocal] = (0, import_react13.useState)(DEFAULT_CHAT_AGENT_MODE);
4272
- const [attachmentNotice, setAttachmentNotice] = (0, import_react13.useState)(null);
6885
+ const [value, setValue] = (0, import_react15.useState)("");
6886
+ const [selectedModel, setSelectedModel] = (0, import_react15.useState)("");
6887
+ const [selectedMode, setSelectedModeLocal] = (0, import_react15.useState)(DEFAULT_CHAT_AGENT_MODE);
6888
+ const [selectedSkills, setSelectedSkills] = (0, import_react15.useState)([]);
6889
+ const [attachmentNotice, setAttachmentNotice] = (0, import_react15.useState)(null);
4273
6890
  const { attachments, appendFiles, removeAttachment, takeMessageAttachments } = useComposerAttachments();
4274
- const abortControllerBySessionRef = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
4275
- const stopRequestBySessionRef = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
4276
- const lastRequestBySessionRef = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
4277
- (0, import_react13.useEffect)(() => {
6891
+ const abortControllerBySessionRef = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
6892
+ const stopRequestBySessionRef = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
6893
+ const lastRequestBySessionRef = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
6894
+ (0, import_react15.useEffect)(() => {
4278
6895
  setSelectedModel(
4279
6896
  (current) => resolveSelectedChatModel({ currentModel: current, availableModels, isModelsLoading })
4280
6897
  );
4281
6898
  }, [availableModels, isModelsLoading]);
4282
- (0, import_react13.useEffect)(() => {
6899
+ (0, import_react15.useEffect)(() => {
4283
6900
  if (activeSession) {
4284
6901
  setSelectedModeLocal(activeSession.mode ?? DEFAULT_CHAT_AGENT_MODE);
4285
6902
  return;
4286
6903
  }
4287
6904
  setSelectedModeLocal(preferredMode ?? DEFAULT_CHAT_AGENT_MODE);
4288
6905
  }, [activeSession, preferredMode]);
4289
- (0, import_react13.useEffect)(() => {
6906
+ (0, import_react15.useEffect)(() => {
4290
6907
  if (!attachmentNotice)
4291
6908
  return;
4292
6909
  const timeoutId = window.setTimeout(
@@ -4303,11 +6920,11 @@ var useChatComposer = () => {
4303
6920
  window.clearTimeout(stopRequest.timeoutId);
4304
6921
  stopRequest.timeoutId = null;
4305
6922
  };
4306
- const clearStopRequest = (0, import_react13.useCallback)((sessionId) => {
6923
+ const clearStopRequest = (0, import_react15.useCallback)((sessionId) => {
4307
6924
  clearStopTimeout(sessionId);
4308
6925
  stopRequestBySessionRef.current.delete(sessionId);
4309
6926
  }, []);
4310
- const moveSessionRuntimeState = (0, import_react13.useCallback)(
6927
+ const moveSessionRuntimeState = (0, import_react15.useCallback)(
4311
6928
  (previousSessionId, nextSessionId) => {
4312
6929
  if (previousSessionId === nextSessionId) {
4313
6930
  return;
@@ -4325,7 +6942,7 @@ var useChatComposer = () => {
4325
6942
  },
4326
6943
  []
4327
6944
  );
4328
- const finalizeStop = (0, import_react13.useCallback)(
6945
+ const finalizeStop = (0, import_react15.useCallback)(
4329
6946
  (sessionId) => {
4330
6947
  const stopRequest = stopRequestBySessionRef.current.get(sessionId);
4331
6948
  if (stopRequest) {
@@ -4342,11 +6959,12 @@ var useChatComposer = () => {
4342
6959
  },
4343
6960
  [clearStopRequest, finalizeStoppedStreamingMessage]
4344
6961
  );
4345
- const runStream = (0, import_react13.useCallback)(
6962
+ const runStream = (0, import_react15.useCallback)(
4346
6963
  async ({
4347
6964
  localSessionId,
4348
6965
  sessionId,
4349
6966
  content,
6967
+ skills,
4350
6968
  attachments: attachments2,
4351
6969
  model,
4352
6970
  mode
@@ -4367,6 +6985,7 @@ var useChatComposer = () => {
4367
6985
  localSessionId,
4368
6986
  sessionId,
4369
6987
  content,
6988
+ skills,
4370
6989
  attachments: attachments2,
4371
6990
  model,
4372
6991
  mode
@@ -4379,6 +6998,7 @@ var useChatComposer = () => {
4379
6998
  model,
4380
6999
  mode,
4381
7000
  content,
7001
+ skills,
4382
7002
  attachments: attachments2,
4383
7003
  signal: abortController.signal,
4384
7004
  onSessionId: (nextSessionId) => {
@@ -4392,6 +7012,7 @@ var useChatComposer = () => {
4392
7012
  localSessionId: nextSessionId,
4393
7013
  sessionId: nextSessionId,
4394
7014
  content,
7015
+ skills,
4395
7016
  attachments: attachments2,
4396
7017
  model,
4397
7018
  mode
@@ -4463,11 +7084,13 @@ var useChatComposer = () => {
4463
7084
  store
4464
7085
  ]
4465
7086
  );
4466
- const send = (0, import_react13.useCallback)(
7087
+ const send = (0, import_react15.useCallback)(
4467
7088
  async (contentOverride, options) => {
4468
7089
  const content = (contentOverride ?? value).trim();
4469
7090
  const includeComposerAttachments = options?.includeComposerAttachments ?? true;
7091
+ const includeComposerSkills = options?.includeComposerSkills ?? true;
4470
7092
  const composerAttachmentCount = includeComposerAttachments ? attachments.length : 0;
7093
+ const messageSkills = includeComposerSkills ? selectedSkills : void 0;
4471
7094
  if (!canSendChatMessage({
4472
7095
  value: content,
4473
7096
  attachmentCount: composerAttachmentCount,
@@ -4504,14 +7127,20 @@ var useChatComposer = () => {
4504
7127
  createMessageId: () => `user-${Date.now()}`
4505
7128
  });
4506
7129
  appendMessage(localSessionId, userMessage);
4507
- if (includeComposerAttachments) {
7130
+ if (includeComposerAttachments || includeComposerSkills) {
4508
7131
  setAttachmentNotice(null);
7132
+ }
7133
+ if (includeComposerAttachments) {
4509
7134
  setValue("");
4510
7135
  }
7136
+ if (includeComposerSkills) {
7137
+ setSelectedSkills([]);
7138
+ }
4511
7139
  await runStream({
4512
7140
  localSessionId,
4513
7141
  sessionId,
4514
7142
  content,
7143
+ skills: messageSkills,
4515
7144
  attachments: messageAttachments,
4516
7145
  model: resolvedModel,
4517
7146
  mode: currentMode
@@ -4520,6 +7149,7 @@ var useChatComposer = () => {
4520
7149
  [
4521
7150
  value,
4522
7151
  attachments,
7152
+ selectedSkills,
4523
7153
  isModelsLoading,
4524
7154
  isModelsError,
4525
7155
  hasModels,
@@ -4533,7 +7163,7 @@ var useChatComposer = () => {
4533
7163
  store
4534
7164
  ]
4535
7165
  );
4536
- const stopSession = (0, import_react13.useCallback)(
7166
+ const stopSession = (0, import_react15.useCallback)(
4537
7167
  async (sessionId) => {
4538
7168
  const storeState = store.getState();
4539
7169
  const isSessionStreaming = storeState.isStreamingBySession[sessionId] ?? false;
@@ -4569,13 +7199,16 @@ var useChatComposer = () => {
4569
7199
  state: {
4570
7200
  value,
4571
7201
  attachments,
7202
+ selectedSkills,
4572
7203
  attachmentNotice,
4573
7204
  isStreaming,
4574
7205
  isStopping,
4575
7206
  selectedModel,
4576
7207
  selectedMode,
4577
7208
  availableModels,
7209
+ availableSkills,
4578
7210
  isModelsLoading,
7211
+ isSkillsLoading,
4579
7212
  isModelsError,
4580
7213
  hasModels
4581
7214
  },
@@ -4598,6 +7231,12 @@ var useChatComposer = () => {
4598
7231
  removeAttachment(attachmentId);
4599
7232
  setAttachmentNotice(null);
4600
7233
  },
7234
+ addSkill: (skill) => {
7235
+ setSelectedSkills((current) => current.includes(skill) ? current : [...current, skill]);
7236
+ },
7237
+ removeSkill: (skill) => {
7238
+ setSelectedSkills((current) => current.filter((item) => item !== skill));
7239
+ },
4601
7240
  setSelectedModel,
4602
7241
  setSelectedMode: (mode) => {
4603
7242
  setSelectedModeLocal(mode);
@@ -4612,6 +7251,7 @@ var useChatComposer = () => {
4612
7251
  }
4613
7252
  },
4614
7253
  reloadModels: () => void fetchModels(),
7254
+ reloadSkills: () => void fetchSkills(),
4615
7255
  stopSession,
4616
7256
  stop: async () => {
4617
7257
  if (!streamingSessionId)
@@ -4631,29 +7271,29 @@ var useChatComposer = () => {
4631
7271
  };
4632
7272
 
4633
7273
  // src/components/chat-composer/components/chat-composer-attachment-list.tsx
4634
- var import_react14 = require("react");
7274
+ var import_react16 = require("react");
4635
7275
  var import_styled10 = __toESM(require("@emotion/styled"));
4636
- var import_jsx_runtime11 = require("@emotion/react/jsx-runtime");
7276
+ var import_jsx_runtime12 = require("@emotion/react/jsx-runtime");
4637
7277
  var ChatComposerAttachmentList = ({
4638
7278
  attachments,
4639
7279
  onRemoveAttachment
4640
7280
  }) => {
4641
- const [activeImage, setActiveImage] = (0, import_react14.useState)(null);
7281
+ const [activeImage, setActiveImage] = (0, import_react16.useState)(null);
4642
7282
  if (!attachments.length) {
4643
7283
  return null;
4644
7284
  }
4645
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
4646
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AttachmentList, { "data-testid": "chat-composer-attachment-list", children: attachments.map((attachment) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(AttachmentCard, { children: [
4647
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
7285
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
7286
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(AttachmentList, { "data-testid": "chat-composer-attachment-list", children: attachments.map((attachment) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(AttachmentCard, { children: [
7287
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4648
7288
  AttachmentPreviewButton,
4649
7289
  {
4650
7290
  type: "button",
4651
7291
  "aria-label": `${attachment.name} preview`,
4652
7292
  onClick: () => setActiveImage(attachment),
4653
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AttachmentThumb, { src: attachment.previewUrl, alt: attachment.name })
7293
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(AttachmentThumb, { src: attachment.previewUrl, alt: attachment.name })
4654
7294
  }
4655
7295
  ),
4656
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
7296
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4657
7297
  AttachmentRemoveButton,
4658
7298
  {
4659
7299
  type: "button",
@@ -4662,11 +7302,11 @@ var ChatComposerAttachmentList = ({
4662
7302
  event.stopPropagation();
4663
7303
  onRemoveAttachment(attachment.id);
4664
7304
  },
4665
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CloseGlyph, { "aria-hidden": "true" })
7305
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CloseGlyph, { "aria-hidden": "true" })
4666
7306
  }
4667
7307
  )
4668
7308
  ] }, attachment.id)) }),
4669
- activeImage ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
7309
+ activeImage ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4670
7310
  ImageViewer,
4671
7311
  {
4672
7312
  src: activeImage.previewUrl,
@@ -4790,7 +7430,7 @@ var CloseGlyph = import_styled10.default.span`
4790
7430
  // src/components/chat-composer/components/chat-model-control.tsx
4791
7431
  var import_styled11 = __toESM(require("@emotion/styled"));
4792
7432
  var import_compass_ui = require("@xinghunm/compass-ui");
4793
- var import_jsx_runtime12 = require("@emotion/react/jsx-runtime");
7433
+ var import_jsx_runtime13 = require("@emotion/react/jsx-runtime");
4794
7434
  var ChatModelControl = ({
4795
7435
  selectedModel,
4796
7436
  availableModels,
@@ -4801,7 +7441,7 @@ var ChatModelControl = ({
4801
7441
  onReloadModels
4802
7442
  }) => {
4803
7443
  if (isModelsError) {
4804
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
7444
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
4805
7445
  ModelReloadButton,
4806
7446
  {
4807
7447
  type: "button",
@@ -4809,8 +7449,8 @@ var ChatModelControl = ({
4809
7449
  "aria-label": "Reload",
4810
7450
  onClick: onReloadModels,
4811
7451
  children: [
4812
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "Failed to load models" }),
4813
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
7452
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Failed to load models" }),
7453
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
4814
7454
  ReloadIcon,
4815
7455
  {
4816
7456
  "data-testid": "chat-model-reload-icon",
@@ -4821,8 +7461,8 @@ var ChatModelControl = ({
4821
7461
  fill: "currentColor",
4822
7462
  xmlns: "http://www.w3.org/2000/svg",
4823
7463
  children: [
4824
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M895.469672 511.745197c0-146.498562-82.099856-273.805016-202.788589-338.470805l22.072715-46.630017c-4.50664-12.609179-18.382673-19.176758-30.991852-14.670118l-92.436272 33.040511c-12.609179 4.50664-19.176758 18.382673-14.670118 30.991852l33.040511 92.436272c4.50664 12.609179 18.382673 19.176758 30.991852 14.670118l24.581861-51.92972c99.069343 54.335513 166.240185 159.596881 166.240185 280.561907 0 165.56685-125.817544 301.747415-287.057855 318.14692l0 0.022513c-17.730826 0-32.105209 14.374382-32.105209 32.105209 0 17.730826 14.374382 32.105209 32.105209 32.105209 2.098801 0 4.149507-0.207731 6.135744-0.592494C744.270041 874.039593 895.469672 710.564381 895.469672 511.745197z" }),
4825
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M480.616222 129.23948c-0.041956 0-0.082888 0.00307-0.124843 0.00307l0-0.00307c-0.01535 0.001023-0.031722 0.00307-0.047072 0.004093-1.892093 0.010233-3.744277 0.189312-5.545296 0.5137-194.674794 18.529005-346.957083 182.459588-346.957083 381.987924 0 147.431817 83.146699 275.42798 205.097168 339.700819l-24.814152 52.419883c4.50664 12.609179 18.382673 19.176758 30.991852 14.670118l92.436272-33.040511c12.609179-4.50664 19.176758-18.382673 14.670118-30.991852l-33.040511-92.436272c-4.50664-12.609179-18.382673-19.176758-30.991852-14.670118l-21.853727 46.167482c-100.326986-53.964052-168.535461-159.920246-168.535461-281.81955 0-166.089759 126.616746-302.591643 288.588721-318.284043l0-0.014326c0.041956 0 0.082888 0.00307 0.124843 0.00307 17.730826 0 32.105209-14.374382 32.105209-32.105209C512.721431 143.613862 498.347049 129.23948 480.616222 129.23948z" })
7464
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M895.469672 511.745197c0-146.498562-82.099856-273.805016-202.788589-338.470805l22.072715-46.630017c-4.50664-12.609179-18.382673-19.176758-30.991852-14.670118l-92.436272 33.040511c-12.609179 4.50664-19.176758 18.382673-14.670118 30.991852l33.040511 92.436272c4.50664 12.609179 18.382673 19.176758 30.991852 14.670118l24.581861-51.92972c99.069343 54.335513 166.240185 159.596881 166.240185 280.561907 0 165.56685-125.817544 301.747415-287.057855 318.14692l0 0.022513c-17.730826 0-32.105209 14.374382-32.105209 32.105209 0 17.730826 14.374382 32.105209 32.105209 32.105209 2.098801 0 4.149507-0.207731 6.135744-0.592494C744.270041 874.039593 895.469672 710.564381 895.469672 511.745197z" }),
7465
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M480.616222 129.23948c-0.041956 0-0.082888 0.00307-0.124843 0.00307l0-0.00307c-0.01535 0.001023-0.031722 0.00307-0.047072 0.004093-1.892093 0.010233-3.744277 0.189312-5.545296 0.5137-194.674794 18.529005-346.957083 182.459588-346.957083 381.987924 0 147.431817 83.146699 275.42798 205.097168 339.700819l-24.814152 52.419883c4.50664 12.609179 18.382673 19.176758 30.991852 14.670118l92.436272-33.040511c12.609179-4.50664 19.176758-18.382673 14.670118-30.991852l-33.040511-92.436272c-4.50664-12.609179-18.382673-19.176758-30.991852-14.670118l-21.853727 46.167482c-100.326986-53.964052-168.535461-159.920246-168.535461-281.81955 0-166.089759 126.616746-302.591643 288.588721-318.284043l0-0.014326c0.041956 0 0.082888 0.00307 0.124843 0.00307 17.730826 0 32.105209-14.374382 32.105209-32.105209C512.721431 143.613862 498.347049 129.23948 480.616222 129.23948z" })
4826
7466
  ]
4827
7467
  }
4828
7468
  )
@@ -4831,11 +7471,11 @@ var ChatModelControl = ({
4831
7471
  );
4832
7472
  }
4833
7473
  if (isModelsLoading) {
4834
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ModelBadge, { children: "Loading models..." });
7474
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ModelBadge, { children: "Loading models..." });
4835
7475
  }
4836
7476
  if (hasModels && selectedModel) {
4837
7477
  if (availableModels.length > 1) {
4838
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
7478
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4839
7479
  ModelSelect,
4840
7480
  {
4841
7481
  "data-testid": "chat-model-select",
@@ -4849,9 +7489,9 @@ var ChatModelControl = ({
4849
7489
  }
4850
7490
  );
4851
7491
  }
4852
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ModelBadge, { children: selectedModel });
7492
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ModelBadge, { children: selectedModel });
4853
7493
  }
4854
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ModelBadge, { children: "No model available" });
7494
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ModelBadge, { children: "No model available" });
4855
7495
  };
4856
7496
  var ModelBadge = import_styled11.default.span`
4857
7497
  border-radius: 999px;
@@ -4912,14 +7552,14 @@ var ModelSelect = (0, import_styled11.default)(import_compass_ui.Select)`
4912
7552
  // src/components/chat-composer/components/chat-mode-control.tsx
4913
7553
  var import_styled12 = __toESM(require("@emotion/styled"));
4914
7554
  var import_compass_ui2 = require("@xinghunm/compass-ui");
4915
- var import_jsx_runtime13 = require("@emotion/react/jsx-runtime");
7555
+ var import_jsx_runtime14 = require("@emotion/react/jsx-runtime");
4916
7556
  var ChatModeControl = ({
4917
7557
  value,
4918
7558
  disabled = false,
4919
7559
  labels,
4920
7560
  onChange
4921
7561
  }) => {
4922
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
7562
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4923
7563
  ModeSelect,
4924
7564
  {
4925
7565
  "data-testid": "chat-mode-select",
@@ -4957,8 +7597,8 @@ var ModeSelect = (0, import_styled12.default)(import_compass_ui2.Select)`
4957
7597
  // src/components/chat-composer/components/chat-send-actions.tsx
4958
7598
  var import_styled13 = __toESM(require("@emotion/styled"));
4959
7599
  var import_compass_ui3 = require("@xinghunm/compass-ui");
4960
- var import_jsx_runtime14 = require("@emotion/react/jsx-runtime");
4961
- var ArrowUpIcon = () => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7600
+ var import_jsx_runtime15 = require("@emotion/react/jsx-runtime");
7601
+ var ArrowUpIcon = () => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4962
7602
  "svg",
4963
7603
  {
4964
7604
  "aria-hidden": "true",
@@ -4967,7 +7607,7 @@ var ArrowUpIcon = () => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4967
7607
  viewBox: "0 0 12 12",
4968
7608
  fill: "none",
4969
7609
  xmlns: "http://www.w3.org/2000/svg",
4970
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7610
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4971
7611
  "path",
4972
7612
  {
4973
7613
  d: "M6 10V2M6 2L2 6M6 2L10 6",
@@ -4985,7 +7625,7 @@ var ChatSendActions = ({
4985
7625
  isStopping,
4986
7626
  onStop,
4987
7627
  onSend
4988
- }) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: isStreaming ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7628
+ }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children: isStreaming ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4989
7629
  StopButton,
4990
7630
  {
4991
7631
  type: "button",
@@ -4995,14 +7635,14 @@ var ChatSendActions = ({
4995
7635
  disabled: isStopping,
4996
7636
  shape: "circle",
4997
7637
  onClick: () => void onStop(),
4998
- children: isStopping ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(StopSpinner, { "aria-hidden": "true", "data-testid": "chat-composer-stop-spinner" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(StopGlyph, { "aria-hidden": "true", "data-testid": "chat-composer-stop-glyph" })
7638
+ children: isStopping ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(StopSpinner, { "aria-hidden": "true", "data-testid": "chat-composer-stop-spinner" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(StopGlyph, { "aria-hidden": "true", "data-testid": "chat-composer-stop-glyph" })
4999
7639
  }
5000
- ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7640
+ ) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5001
7641
  PrimaryButton,
5002
7642
  {
5003
7643
  $canSend: canSend,
5004
7644
  type: "button",
5005
- icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ArrowUpIcon, {}),
7645
+ icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ArrowUpIcon, {}),
5006
7646
  "aria-label": "Send",
5007
7647
  "data-testid": "chat-composer-send",
5008
7648
  disabled: !canSend,
@@ -5091,7 +7731,7 @@ var StopSpinner = import_styled13.default.span`
5091
7731
  `;
5092
7732
 
5093
7733
  // src/components/chat-composer/index.tsx
5094
- var import_jsx_runtime15 = require("@emotion/react/jsx-runtime");
7734
+ var import_jsx_runtime16 = require("@emotion/react/jsx-runtime");
5095
7735
  var CHAT_COMPOSER_LINE_HEIGHT_PX = 20;
5096
7736
  var CHAT_COMPOSER_MAX_ROWS = 7;
5097
7737
  var CHAT_COMPOSER_PADDING_TOP_PX = 8;
@@ -5113,7 +7753,7 @@ var getExpandedComposerHeightPx = () => {
5113
7753
  Math.floor(Math.min(CHAT_COMPOSER_EXPANDED_ROWS_HEIGHT_PX, viewportLimitedHeight))
5114
7754
  );
5115
7755
  };
5116
- var PlusIcon = () => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
7756
+ var PlusIcon = () => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5117
7757
  "svg",
5118
7758
  {
5119
7759
  "aria-hidden": "true",
@@ -5122,10 +7762,10 @@ var PlusIcon = () => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5122
7762
  viewBox: "0 0 16 16",
5123
7763
  fill: "none",
5124
7764
  xmlns: "http://www.w3.org/2000/svg",
5125
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M8 3v10M3 8h10", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round" })
7765
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M8 3v10M3 8h10", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round" })
5126
7766
  }
5127
7767
  );
5128
- var ComposerExpandIcon = ({ expanded }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
7768
+ var ComposerExpandIcon = ({ expanded }) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5129
7769
  "svg",
5130
7770
  {
5131
7771
  "aria-hidden": "true",
@@ -5134,7 +7774,7 @@ var ComposerExpandIcon = ({ expanded }) => /* @__PURE__ */ (0, import_jsx_runtim
5134
7774
  viewBox: "0 0 16 16",
5135
7775
  fill: "none",
5136
7776
  xmlns: "http://www.w3.org/2000/svg",
5137
- children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
7777
+ children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5138
7778
  "path",
5139
7779
  {
5140
7780
  d: "M14 6h-4V2M10 6l4-4M2 10h4v4M6 10l-4 4",
@@ -5143,7 +7783,7 @@ var ComposerExpandIcon = ({ expanded }) => /* @__PURE__ */ (0, import_jsx_runtim
5143
7783
  strokeLinecap: "round",
5144
7784
  strokeLinejoin: "round"
5145
7785
  }
5146
- ) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
7786
+ ) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5147
7787
  "path",
5148
7788
  {
5149
7789
  d: "M10 2h4v4M14 2L9 7M6 14H2v-4M2 14l5-5",
@@ -5155,16 +7795,39 @@ var ComposerExpandIcon = ({ expanded }) => /* @__PURE__ */ (0, import_jsx_runtim
5155
7795
  )
5156
7796
  }
5157
7797
  );
7798
+ var resolveSkillQueryMatch = (value) => {
7799
+ const matched = value.match(/(^|\s)\/([^\s/]*)$/);
7800
+ if (!matched || matched.index === void 0) {
7801
+ return null;
7802
+ }
7803
+ const start = matched.index + matched[1].length;
7804
+ return {
7805
+ query: matched[2] ?? "",
7806
+ start,
7807
+ end: value.length
7808
+ };
7809
+ };
7810
+ var replaceSkillQuery = (value, match) => {
7811
+ const before = value.slice(0, match.start).replace(/\s+$/, "");
7812
+ const after = value.slice(match.end).replace(/^\s+/, "");
7813
+ if (before && after) {
7814
+ return `${before} ${after}`;
7815
+ }
7816
+ return before || after;
7817
+ };
5158
7818
  var ChatComposerView = ({
5159
7819
  value,
5160
7820
  placeholder,
5161
7821
  attachments,
5162
7822
  attachmentNotice,
5163
7823
  attachmentLimitNotice,
7824
+ selectedSkills,
5164
7825
  selectedModel,
5165
7826
  selectedMode,
5166
7827
  availableModels,
7828
+ availableSkills,
5167
7829
  isModelsLoading,
7830
+ isSkillsLoading,
5168
7831
  isModelsError,
5169
7832
  hasModels,
5170
7833
  isStreaming,
@@ -5173,20 +7836,29 @@ var ChatComposerView = ({
5173
7836
  modeLabels,
5174
7837
  expandComposerAriaLabel,
5175
7838
  collapseComposerAriaLabel,
7839
+ skillLoadingLabel,
7840
+ skillEmptyLabel,
7841
+ removeSkillAriaLabel,
5176
7842
  onValueChange,
5177
7843
  onPickImages,
5178
7844
  onPasteImages,
5179
7845
  onRemoveAttachment,
7846
+ onAddSkill,
7847
+ onRemoveSkill,
5180
7848
  onSelectedModelChange,
5181
7849
  onSelectedModeChange,
5182
7850
  onReloadModels,
5183
7851
  onStop,
5184
7852
  onSend
5185
7853
  }) => {
5186
- const imageInputRef = (0, import_react15.useRef)(null);
5187
- const inputRef = (0, import_react15.useRef)(null);
5188
- const [isComposerExpandable, setIsComposerExpandable] = (0, import_react15.useState)(false);
5189
- const [isComposerExpanded, setIsComposerExpanded] = (0, import_react15.useState)(false);
7854
+ const imageInputRef = (0, import_react17.useRef)(null);
7855
+ const inputRef = (0, import_react17.useRef)(null);
7856
+ const [isComposerExpandable, setIsComposerExpandable] = (0, import_react17.useState)(false);
7857
+ const [isComposerExpanded, setIsComposerExpanded] = (0, import_react17.useState)(false);
7858
+ const [activeSkillNavigation, setActiveSkillNavigation] = (0, import_react17.useState)({
7859
+ queryKey: "",
7860
+ index: 0
7861
+ });
5190
7862
  const canSend = canSendChatMessage({
5191
7863
  value,
5192
7864
  attachmentCount: attachments.length,
@@ -5194,7 +7866,50 @@ var ChatComposerView = ({
5194
7866
  isModelsError,
5195
7867
  hasModels
5196
7868
  });
5197
- (0, import_react15.useLayoutEffect)(() => {
7869
+ const skillQueryMatch = resolveSkillQueryMatch(value);
7870
+ const filteredSkills = skillQueryMatch ? availableSkills.filter((skill) => {
7871
+ if (selectedSkills.includes(skill)) {
7872
+ return false;
7873
+ }
7874
+ if (skillQueryMatch.query === "") {
7875
+ return true;
7876
+ }
7877
+ return skill.toLowerCase().includes(skillQueryMatch.query.toLowerCase());
7878
+ }) : [];
7879
+ const showSkillMenu = Boolean(skillQueryMatch);
7880
+ const activeSkillQueryKey = skillQueryMatch ? `${skillQueryMatch.start}:${skillQueryMatch.end}:${skillQueryMatch.query}:${selectedSkills.join("\0")}` : "";
7881
+ const { refs, floatingStyles } = useFloating2({
7882
+ open: showSkillMenu,
7883
+ placement: "bottom-start",
7884
+ middleware: [
7885
+ offset3(8),
7886
+ flip3({ padding: 8 }),
7887
+ shift3({ padding: 8 }),
7888
+ size3({
7889
+ apply({ rects, elements, availableHeight }) {
7890
+ Object.assign(elements.floating.style, {
7891
+ width: `${rects.reference.width}px`,
7892
+ maxHeight: `${Math.min(availableHeight, 240)}px`
7893
+ });
7894
+ }
7895
+ })
7896
+ ],
7897
+ whileElementsMounted: autoUpdate
7898
+ });
7899
+ const setSkillMenuReference = (0, import_react17.useCallback)(
7900
+ (element) => {
7901
+ refs.setReference(element);
7902
+ },
7903
+ [refs]
7904
+ );
7905
+ const setSkillMenuFloating = (0, import_react17.useCallback)(
7906
+ (element) => {
7907
+ refs.setFloating(element);
7908
+ },
7909
+ [refs]
7910
+ );
7911
+ const activeSkillIndex = activeSkillNavigation.queryKey === activeSkillQueryKey ? activeSkillNavigation.index : 0;
7912
+ (0, import_react17.useLayoutEffect)(() => {
5198
7913
  const element = inputRef.current;
5199
7914
  if (!element) {
5200
7915
  return;
@@ -5214,7 +7929,43 @@ var ChatComposerView = ({
5214
7929
  setIsComposerExpanded(false);
5215
7930
  await onSend();
5216
7931
  };
7932
+ const handleSelectSkill = (skill) => {
7933
+ if (!skillQueryMatch) {
7934
+ return;
7935
+ }
7936
+ onAddSkill(skill);
7937
+ onValueChange(replaceSkillQuery(value, skillQueryMatch));
7938
+ setActiveSkillNavigation({ queryKey: "", index: 0 });
7939
+ };
5217
7940
  const handleKeyDown = (event) => {
7941
+ if (skillQueryMatch) {
7942
+ if (event.key === "ArrowDown" && filteredSkills.length > 0) {
7943
+ event.preventDefault();
7944
+ setActiveSkillNavigation({
7945
+ queryKey: activeSkillQueryKey,
7946
+ index: (activeSkillIndex + 1) % filteredSkills.length
7947
+ });
7948
+ return;
7949
+ }
7950
+ if (event.key === "ArrowUp" && filteredSkills.length > 0) {
7951
+ event.preventDefault();
7952
+ setActiveSkillNavigation({
7953
+ queryKey: activeSkillQueryKey,
7954
+ index: (activeSkillIndex - 1 + filteredSkills.length) % filteredSkills.length
7955
+ });
7956
+ return;
7957
+ }
7958
+ if (event.key === "Escape") {
7959
+ event.preventDefault();
7960
+ onValueChange(replaceSkillQuery(value, skillQueryMatch));
7961
+ return;
7962
+ }
7963
+ if (event.key === "Enter" && !event.shiftKey && filteredSkills.length > 0) {
7964
+ event.preventDefault();
7965
+ handleSelectSkill(filteredSkills[activeSkillIndex] ?? filteredSkills[0]);
7966
+ return;
7967
+ }
7968
+ }
5218
7969
  if (shouldStopChatComposer({ key: event.key, shiftKey: event.shiftKey, isStreaming })) {
5219
7970
  event.preventDefault();
5220
7971
  void onStop();
@@ -5237,105 +7988,143 @@ var ChatComposerView = ({
5237
7988
  event.preventDefault();
5238
7989
  onPasteImages(imageFiles);
5239
7990
  };
5240
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Container2, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Surface, { "data-testid": "chat-composer-surface", children: [
5241
- enableImageAttachments ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5242
- "input",
5243
- {
5244
- ref: imageInputRef,
5245
- type: "file",
5246
- accept: "image/png,image/jpeg,image/webp",
5247
- multiple: true,
5248
- hidden: true,
5249
- "data-testid": "chat-composer-image-input",
5250
- onChange: handlePickImages
5251
- }
5252
- ) : null,
5253
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5254
- ChatComposerAttachmentList,
5255
- {
5256
- attachments,
5257
- onRemoveAttachment
5258
- }
5259
- ),
5260
- attachmentNotice === "limit_reached" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AttachmentNotice, { "data-testid": "chat-composer-attachment-notice", children: attachmentLimitNotice }) : null,
5261
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(InputArea, { "data-testid": "chat-composer-input-area", children: [
5262
- isComposerExpanded || isComposerExpandable ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5263
- ComposerExpandButton,
7991
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Container2, { children: [
7992
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Surface, { "data-testid": "chat-composer-surface", children: [
7993
+ enableImageAttachments ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
7994
+ "input",
5264
7995
  {
5265
- type: "button",
5266
- "data-testid": "chat-composer-expand-toggle",
5267
- "aria-label": isComposerExpanded ? collapseComposerAriaLabel : expandComposerAriaLabel,
5268
- "aria-expanded": isComposerExpanded,
5269
- onClick: () => setIsComposerExpanded((current) => !current),
5270
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ComposerExpandIcon, { expanded: isComposerExpanded })
7996
+ ref: imageInputRef,
7997
+ type: "file",
7998
+ accept: "image/png,image/jpeg,image/webp",
7999
+ multiple: true,
8000
+ hidden: true,
8001
+ "data-testid": "chat-composer-image-input",
8002
+ onChange: handlePickImages
5271
8003
  }
5272
8004
  ) : null,
5273
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5274
- Input,
5275
- {
5276
- ref: inputRef,
5277
- "data-testid": "chat-composer-input",
5278
- "data-expanded": isComposerExpanded,
5279
- value,
5280
- onChange: (event) => onValueChange(event.target.value),
5281
- onKeyDown: handleKeyDown,
5282
- onPaste: enableImageAttachments ? handlePaste : void 0,
5283
- placeholder
5284
- }
5285
- )
5286
- ] }),
5287
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Footer, { children: [
5288
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(LeadingActions, { "data-testid": "chat-composer-leading-actions", children: enableImageAttachments ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5289
- AttachButton,
8005
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8006
+ ChatComposerAttachmentList,
5290
8007
  {
5291
- type: "button",
5292
- "data-testid": "chat-composer-attach-image",
5293
- "aria-label": "Attach image",
5294
- onClick: () => imageInputRef.current?.click(),
5295
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(PlusIcon, {})
8008
+ attachments,
8009
+ onRemoveAttachment
5296
8010
  }
5297
- ) : null }),
5298
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(TrailingActions, { "data-testid": "chat-composer-trailing-actions", children: [
5299
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5300
- ChatModeControl,
8011
+ ),
8012
+ attachmentNotice === "limit_reached" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AttachmentNotice, { "data-testid": "chat-composer-attachment-notice", children: attachmentLimitNotice }) : null,
8013
+ selectedSkills.length ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SkillTagList, { "data-testid": "chat-composer-skill-tags", children: selectedSkills.map((skill) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(SkillTag, { children: [
8014
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: skill }),
8015
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8016
+ SkillTagRemoveButton,
5301
8017
  {
5302
- value: selectedMode,
5303
- disabled: isStreaming,
5304
- labels: modeLabels,
5305
- onChange: onSelectedModeChange
8018
+ type: "button",
8019
+ "data-testid": `chat-composer-skill-remove-${skill}`,
8020
+ "aria-label": `${removeSkillAriaLabel}: ${skill}`,
8021
+ onClick: () => onRemoveSkill(skill),
8022
+ children: "\xD7"
5306
8023
  }
5307
- ),
5308
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5309
- ChatModelControl,
8024
+ )
8025
+ ] }, skill)) }) : null,
8026
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(InputArea, { ref: setSkillMenuReference, "data-testid": "chat-composer-input-area", children: [
8027
+ isComposerExpanded || isComposerExpandable ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8028
+ ComposerExpandButton,
5310
8029
  {
5311
- selectedModel,
5312
- availableModels,
5313
- isModelsLoading,
5314
- isModelsError,
5315
- hasModels,
5316
- onSelectedModelChange,
5317
- onReloadModels
8030
+ type: "button",
8031
+ "data-testid": "chat-composer-expand-toggle",
8032
+ "aria-label": isComposerExpanded ? collapseComposerAriaLabel : expandComposerAriaLabel,
8033
+ "aria-expanded": isComposerExpanded,
8034
+ onClick: () => setIsComposerExpanded((current) => !current),
8035
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ComposerExpandIcon, { expanded: isComposerExpanded })
5318
8036
  }
5319
- ),
5320
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5321
- ChatSendActions,
8037
+ ) : null,
8038
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8039
+ Input,
5322
8040
  {
5323
- canSend,
5324
- isStreaming,
5325
- isStopping,
5326
- onStop,
5327
- onSend: handleSend
8041
+ ref: inputRef,
8042
+ "data-testid": "chat-composer-input",
8043
+ "data-expanded": isComposerExpanded,
8044
+ value,
8045
+ onChange: (event) => onValueChange(event.target.value),
8046
+ onKeyDown: handleKeyDown,
8047
+ onPaste: enableImageAttachments ? handlePaste : void 0,
8048
+ placeholder
5328
8049
  }
5329
8050
  )
8051
+ ] }),
8052
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Footer, { children: [
8053
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(LeadingActions, { "data-testid": "chat-composer-leading-actions", children: enableImageAttachments ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8054
+ AttachButton,
8055
+ {
8056
+ type: "button",
8057
+ "data-testid": "chat-composer-attach-image",
8058
+ "aria-label": "Attach image",
8059
+ onClick: () => imageInputRef.current?.click(),
8060
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PlusIcon, {})
8061
+ }
8062
+ ) : null }),
8063
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(TrailingActions, { "data-testid": "chat-composer-trailing-actions", children: [
8064
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8065
+ ChatModeControl,
8066
+ {
8067
+ value: selectedMode,
8068
+ disabled: isStreaming,
8069
+ labels: modeLabels,
8070
+ onChange: onSelectedModeChange
8071
+ }
8072
+ ),
8073
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8074
+ ChatModelControl,
8075
+ {
8076
+ selectedModel,
8077
+ availableModels,
8078
+ isModelsLoading,
8079
+ isModelsError,
8080
+ hasModels,
8081
+ onSelectedModelChange,
8082
+ onReloadModels
8083
+ }
8084
+ ),
8085
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8086
+ ChatSendActions,
8087
+ {
8088
+ canSend,
8089
+ isStreaming,
8090
+ isStopping,
8091
+ onStop,
8092
+ onSend: handleSend
8093
+ }
8094
+ )
8095
+ ] })
5330
8096
  ] })
5331
- ] })
5332
- ] }) });
8097
+ ] }),
8098
+ showSkillMenu ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(FloatingPortal, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8099
+ SkillMenu,
8100
+ {
8101
+ ref: setSkillMenuFloating,
8102
+ style: floatingStyles,
8103
+ "data-testid": "chat-composer-skill-menu",
8104
+ role: "listbox",
8105
+ children: isSkillsLoading ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SkillMenuState, { "data-testid": "chat-composer-skill-loading", children: skillLoadingLabel }) : filteredSkills.length ? filteredSkills.map((skill, index3) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8106
+ SkillMenuItem,
8107
+ {
8108
+ type: "button",
8109
+ role: "option",
8110
+ "data-testid": `chat-composer-skill-option-${skill}`,
8111
+ "data-active": index3 === activeSkillIndex,
8112
+ "aria-selected": index3 === activeSkillIndex,
8113
+ onMouseDown: (event) => event.preventDefault(),
8114
+ onClick: () => handleSelectSkill(skill),
8115
+ children: skill
8116
+ },
8117
+ skill
8118
+ )) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SkillMenuState, { "data-testid": "chat-composer-skill-empty", children: skillEmptyLabel })
8119
+ }
8120
+ ) }) : null
8121
+ ] });
5333
8122
  };
5334
8123
  var ChatComposer = () => {
5335
8124
  const { labels, sendRef, retryRef, stopRef, enableImageAttachments } = useChatContext();
5336
8125
  const { state, actions } = useChatComposer();
5337
8126
  const { send, retry } = actions;
5338
- (0, import_react15.useEffect)(() => {
8127
+ (0, import_react17.useEffect)(() => {
5339
8128
  sendRef.current = send;
5340
8129
  retryRef.current = async (sessionId) => {
5341
8130
  retry(sessionId);
@@ -5347,18 +8136,21 @@ var ChatComposer = () => {
5347
8136
  plan: labels.modeLabelPlan,
5348
8137
  agent: labels.modeLabelAgent
5349
8138
  };
5350
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8139
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5351
8140
  ChatComposerView,
5352
8141
  {
5353
8142
  value: state.value,
5354
8143
  attachments: state.attachments,
5355
8144
  attachmentNotice: state.attachmentNotice,
5356
8145
  attachmentLimitNotice: labels.attachmentLimitNotice,
8146
+ selectedSkills: state.selectedSkills,
5357
8147
  placeholder: labels.placeholder,
5358
8148
  selectedModel: state.selectedModel,
5359
8149
  selectedMode: state.selectedMode,
5360
8150
  availableModels: state.availableModels,
8151
+ availableSkills: state.availableSkills,
5361
8152
  isModelsLoading: state.isModelsLoading,
8153
+ isSkillsLoading: state.isSkillsLoading,
5362
8154
  isModelsError: state.isModelsError,
5363
8155
  hasModels: state.hasModels,
5364
8156
  isStreaming: state.isStreaming,
@@ -5367,10 +8159,15 @@ var ChatComposer = () => {
5367
8159
  modeLabels,
5368
8160
  expandComposerAriaLabel: labels.expandComposerAriaLabel,
5369
8161
  collapseComposerAriaLabel: labels.collapseComposerAriaLabel,
8162
+ skillLoadingLabel: labels.skillLoading,
8163
+ skillEmptyLabel: labels.skillEmpty,
8164
+ removeSkillAriaLabel: labels.removeSkillAriaLabel,
5370
8165
  onValueChange: actions.setValue,
5371
8166
  onPickImages: actions.pickImages,
5372
8167
  onPasteImages: actions.pasteImages,
5373
8168
  onRemoveAttachment: actions.removeAttachment,
8169
+ onAddSkill: actions.addSkill,
8170
+ onRemoveSkill: actions.removeSkill,
5374
8171
  onSelectedModelChange: actions.setSelectedModel,
5375
8172
  onSelectedModeChange: actions.setSelectedMode,
5376
8173
  onReloadModels: actions.reloadModels,
@@ -5412,6 +8209,32 @@ var AttachmentNotice = import_styled14.default.div`
5412
8209
  font-size: 12px;
5413
8210
  line-height: 1.4;
5414
8211
  `;
8212
+ var SkillTagList = import_styled14.default.div`
8213
+ display: flex;
8214
+ flex-wrap: wrap;
8215
+ gap: 8px;
8216
+ padding: 12px 12px 0;
8217
+ `;
8218
+ var SkillTag = import_styled14.default.span`
8219
+ display: inline-flex;
8220
+ align-items: center;
8221
+ gap: 6px;
8222
+ max-width: 100%;
8223
+ border-radius: 999px;
8224
+ padding: 8px 12px;
8225
+ background: rgba(255, 255, 255, 0.06);
8226
+ color: var(--text-primary);
8227
+ font-size: 13px;
8228
+ line-height: 1;
8229
+ `;
8230
+ var SkillTagRemoveButton = import_styled14.default.button`
8231
+ border: none;
8232
+ padding: 0;
8233
+ background: transparent;
8234
+ color: inherit;
8235
+ cursor: pointer;
8236
+ line-height: 1;
8237
+ `;
5415
8238
  var InputArea = import_styled14.default.div`
5416
8239
  grid-area: input;
5417
8240
  position: relative;
@@ -5464,6 +8287,40 @@ var Input = import_styled14.default.textarea`
5464
8287
  max-height: var(--textarea-expanded-max-height);
5465
8288
  }
5466
8289
  `;
8290
+ var SkillMenu = import_styled14.default.div`
8291
+ position: relative;
8292
+ display: flex;
8293
+ flex-direction: column;
8294
+ gap: 4px;
8295
+ max-height: 240px;
8296
+ overflow-y: auto;
8297
+ padding: 8px;
8298
+ border: 1px solid rgba(255, 255, 255, 0.12);
8299
+ border-radius: 16px;
8300
+ background: rgba(28, 28, 28, 0.98);
8301
+ box-shadow: 0 16px 40px rgba(0, 0, 0, 0.28);
8302
+ z-index: 1000;
8303
+ `;
8304
+ var SkillMenuItem = import_styled14.default.button`
8305
+ width: 100%;
8306
+ border: none;
8307
+ border-radius: 12px;
8308
+ padding: 12px 14px;
8309
+ background: transparent;
8310
+ color: var(--text-primary);
8311
+ text-align: left;
8312
+ cursor: pointer;
8313
+
8314
+ &[data-active='true'],
8315
+ &:hover {
8316
+ background: rgba(255, 255, 255, 0.12);
8317
+ }
8318
+ `;
8319
+ var SkillMenuState = import_styled14.default.div`
8320
+ padding: 12px 14px;
8321
+ color: var(--text-secondary);
8322
+ font-size: 13px;
8323
+ `;
5467
8324
  var ComposerExpandButton = import_styled14.default.button`
5468
8325
  position: absolute;
5469
8326
  top: 8px;
@@ -5530,20 +8387,20 @@ var AttachButton = import_styled14.default.button`
5530
8387
  var import_styled16 = __toESM(require("@emotion/styled"));
5531
8388
 
5532
8389
  // src/components/chat-conversation-list/components/chat-session-item.tsx
5533
- var import_react16 = require("react");
8390
+ var import_react19 = require("react");
5534
8391
  var import_styled15 = __toESM(require("@emotion/styled"));
5535
- var import_jsx_runtime16 = require("@emotion/react/jsx-runtime");
5536
- var ChatSessionItem = (0, import_react16.memo)(
8392
+ var import_jsx_runtime17 = require("@emotion/react/jsx-runtime");
8393
+ var ChatSessionItem = (0, import_react19.memo)(
5537
8394
  ({ session, isActive, modeLabel, onClick }) => {
5538
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8395
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5539
8396
  SessionButton,
5540
8397
  {
5541
8398
  type: "button",
5542
8399
  "data-active": isActive,
5543
8400
  onClick: () => onClick(session.sessionId),
5544
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(SessionMeta, { children: [
5545
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SessionTitle, { children: session.title }),
5546
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ModeBadge, { children: modeLabel })
8401
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(SessionMeta, { children: [
8402
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SessionTitle, { children: session.title }),
8403
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ModeBadge, { children: modeLabel })
5547
8404
  ] })
5548
8405
  }
5549
8406
  );
@@ -5588,7 +8445,7 @@ var ModeBadge = import_styled15.default.span`
5588
8445
  `;
5589
8446
 
5590
8447
  // src/components/chat-conversation-list/index.tsx
5591
- var import_jsx_runtime17 = require("@emotion/react/jsx-runtime");
8448
+ var import_jsx_runtime18 = require("@emotion/react/jsx-runtime");
5592
8449
  var ChatConversationList = () => {
5593
8450
  const { labels } = useChatContext();
5594
8451
  const sessions = useChatStore((s) => s.sessions);
@@ -5600,12 +8457,12 @@ var ChatConversationList = () => {
5600
8457
  plan: labels.modeLabelPlan,
5601
8458
  agent: labels.modeLabelAgent
5602
8459
  };
5603
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Container3, { children: [
5604
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Toolbar, { children: [
5605
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Title3, { children: "Sessions" }),
5606
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(CreateButton, { type: "button", "data-testid": "chat-create-session", onClick: startNewChat, children: labels.newChat })
8460
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Container3, { children: [
8461
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Toolbar, { children: [
8462
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Title3, { children: "Sessions" }),
8463
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(CreateButton, { type: "button", "data-testid": "chat-create-session", onClick: startNewChat, children: labels.newChat })
5607
8464
  ] }),
5608
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(List2, { "data-testid": "chat-session-list", children: sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
8465
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(List2, { "data-testid": "chat-session-list", children: sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5609
8466
  ChatSessionItem,
5610
8467
  {
5611
8468
  session,
@@ -5654,7 +8511,7 @@ var List2 = import_styled16.default.div`
5654
8511
  `;
5655
8512
 
5656
8513
  // src/components/ai-chat/index.tsx
5657
- var import_jsx_runtime18 = require("@emotion/react/jsx-runtime");
8514
+ var import_jsx_runtime19 = require("@emotion/react/jsx-runtime");
5658
8515
  var QuickActions = ({ renderNewChatTrigger }) => {
5659
8516
  const { labels, stopRef, store } = useChatContext();
5660
8517
  const startNewChat = useChatStore((state) => state.startNewChat);
@@ -5695,9 +8552,15 @@ var QuickActions = ({ renderNewChatTrigger }) => {
5695
8552
  startNewChat: handleStartNewChat
5696
8553
  };
5697
8554
  if (renderNewChatTrigger) {
5698
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(QuickActionsRow, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(NewChatTriggerRenderer, { renderNewChatTrigger, triggerProps }) });
8555
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(QuickActionsRow, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
8556
+ NewChatTriggerRenderer,
8557
+ {
8558
+ renderNewChatTrigger,
8559
+ triggerProps
8560
+ }
8561
+ ) });
5699
8562
  }
5700
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(QuickActionsRow, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
8563
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(QuickActionsRow, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5701
8564
  QuickActionButton,
5702
8565
  {
5703
8566
  type: "button",
@@ -5711,13 +8574,13 @@ var QuickActions = ({ renderNewChatTrigger }) => {
5711
8574
  var NewChatTriggerRenderer = ({
5712
8575
  renderNewChatTrigger,
5713
8576
  triggerProps
5714
- }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, { children: renderNewChatTrigger(triggerProps) });
8577
+ }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, { children: renderNewChatTrigger(triggerProps) });
5715
8578
  var AiChat = ({
5716
8579
  showConversationList = false,
5717
8580
  showNewChatButton = false,
5718
8581
  renderNewChatTrigger,
5719
8582
  ...providerProps
5720
- }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
8583
+ }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5721
8584
  import_compass_ui4.ConfigProvider,
5722
8585
  {
5723
8586
  theme: {
@@ -5752,12 +8615,12 @@ var AiChat = ({
5752
8615
  }
5753
8616
  }
5754
8617
  },
5755
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AiChatProvider, { ...providerProps, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Root, { "data-testid": "ai-chat", children: [
5756
- showConversationList ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ChatConversationList, {}) : null,
5757
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Workspace, { children: [
5758
- showNewChatButton && !showConversationList ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(QuickActions, { renderNewChatTrigger }) : null,
5759
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ChatThread, {}),
5760
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ChatComposer, {})
8618
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(AiChatProvider, { ...providerProps, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Root, { "data-testid": "ai-chat", children: [
8619
+ showConversationList ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ChatConversationList, {}) : null,
8620
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Workspace, { children: [
8621
+ showNewChatButton && !showConversationList ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(QuickActions, { renderNewChatTrigger }) : null,
8622
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ChatThread, {}),
8623
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ChatComposer, {})
5761
8624
  ] })
5762
8625
  ] }) })
5763
8626
  }
@@ -5810,3 +8673,11 @@ var QuickActionButton = import_styled17.default.button`
5810
8673
  useChatContext,
5811
8674
  useChatStore
5812
8675
  });
8676
+ /*! Bundled license information:
8677
+
8678
+ tabbable/dist/index.esm.js:
8679
+ (*!
8680
+ * tabbable 6.3.0
8681
+ * @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
8682
+ *)
8683
+ */