@orca-pt/orca-components 1.0.1
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/LICENSE +21 -0
- package/README.md +473 -0
- package/dist/components/ContentElement.vue.d.ts +21 -0
- package/dist/components/OrcaMarkdown.vue.d.ts +15 -0
- package/dist/components/loading/CardLoading.vue.d.ts +9 -0
- package/dist/components/loading/GeneralLoading.vue.d.ts +11 -0
- package/dist/components/loading/ImageLoading.vue.d.ts +9 -0
- package/dist/components/loading/MapLoading.vue.d.ts +9 -0
- package/dist/components/loading/VideoLoading.vue.d.ts +9 -0
- package/dist/components/renderers/OrcaAudio.vue.d.ts +11 -0
- package/dist/components/renderers/OrcaButtons.vue.d.ts +16 -0
- package/dist/components/renderers/OrcaCardList.vue.d.ts +11 -0
- package/dist/components/renderers/OrcaImage.vue.d.ts +14 -0
- package/dist/components/renderers/OrcaLocation.vue.d.ts +13 -0
- package/dist/components/renderers/OrcaTracing.vue.d.ts +13 -0
- package/dist/components/renderers/OrcaVideo.vue.d.ts +11 -0
- package/dist/components/renderers/OrcaYouTube.vue.d.ts +10 -0
- package/dist/composables/__tests__/useContentParser.test.d.ts +1 -0
- package/dist/composables/core/index.d.ts +3 -0
- package/dist/composables/core/matchFinder.d.ts +13 -0
- package/dist/composables/core/matchProcessor.d.ts +9 -0
- package/dist/composables/core/recursiveParser.d.ts +6 -0
- package/dist/composables/parsers/__tests__/parsers.test.d.ts +1 -0
- package/dist/composables/parsers/baseParser.d.ts +34 -0
- package/dist/composables/parsers/index.d.ts +5 -0
- package/dist/composables/parsers/parseAudio.d.ts +2 -0
- package/dist/composables/parsers/parseButton.d.ts +2 -0
- package/dist/composables/parsers/parseCard.d.ts +2 -0
- package/dist/composables/parsers/parseLocation.d.ts +11 -0
- package/dist/composables/parsers/parseTracing.d.ts +9 -0
- package/dist/composables/parsing/index.d.ts +8 -0
- package/dist/composables/parsing/markerCleaner.d.ts +15 -0
- package/dist/composables/parsing/markerDefinitions.d.ts +20 -0
- package/dist/composables/parsing/markerOperations.d.ts +27 -0
- package/dist/composables/parsing/markerUtils.d.ts +58 -0
- package/dist/composables/useCodeButtons.d.ts +8 -0
- package/dist/composables/useContentParser.d.ts +12 -0
- package/dist/composables/useImageModal.d.ts +10 -0
- package/dist/composables/useLoadingStates.d.ts +13 -0
- package/dist/composables/useMarkdown.d.ts +8 -0
- package/dist/constants/loadingTypes.d.ts +9 -0
- package/dist/index.d.ts +16 -0
- package/dist/orca-components.css +13 -0
- package/dist/orca-components.es.js +1851 -0
- package/dist/orca-components.es.js.map +1 -0
- package/dist/orca-components.umd.js +2 -0
- package/dist/orca-components.umd.js.map +1 -0
- package/dist/types/index.d.ts +128 -0
- package/dist/utils/helpers.d.ts +48 -0
- package/package.json +83 -0
|
@@ -0,0 +1,1851 @@
|
|
|
1
|
+
import { computed, unref, ref, watch, onMounted, nextTick, defineComponent, createElementBlock, openBlock, createElementVNode, createStaticVNode, createVNode, Fragment, renderList, toDisplayString, createTextVNode, onUnmounted, createBlock, withCtx, createCommentVNode, normalizeStyle, normalizeClass, createSlots, Transition, isRef, withModifiers } from "vue";
|
|
2
|
+
import { VCard, VImg, VCardItem, VCardTitle, VBtn, VIcon, VExpandTransition, VProgressCircular, VDialog } from "vuetify/components";
|
|
3
|
+
import MarkdownIt from "markdown-it";
|
|
4
|
+
import hljs from "highlight.js";
|
|
5
|
+
import markdownItLinkAttributes from "markdown-it-link-attributes";
|
|
6
|
+
import markdownItKatex from "markdown-it-katex";
|
|
7
|
+
import { VideoPlayer } from "@videojs-player/vue";
|
|
8
|
+
import mapboxgl from "mapbox-gl";
|
|
9
|
+
import { components } from "vuetify/dist/vuetify-labs.esm.js";
|
|
10
|
+
function isImageFile(url) {
|
|
11
|
+
const imageExtensions = [
|
|
12
|
+
".jpg",
|
|
13
|
+
".jpeg",
|
|
14
|
+
".png",
|
|
15
|
+
".gif",
|
|
16
|
+
".webp",
|
|
17
|
+
".bmp",
|
|
18
|
+
".svg"
|
|
19
|
+
];
|
|
20
|
+
try {
|
|
21
|
+
const urlObj = new URL(url);
|
|
22
|
+
const pathname = urlObj.pathname.toLowerCase();
|
|
23
|
+
return imageExtensions.some((ext) => pathname.endsWith(ext));
|
|
24
|
+
} catch (e) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function getFileNameFromUrl(url) {
|
|
29
|
+
try {
|
|
30
|
+
const urlObj = new URL(url);
|
|
31
|
+
const pathname = urlObj.pathname;
|
|
32
|
+
const segments = pathname.split("/");
|
|
33
|
+
const encodedFileName = segments.pop() || "";
|
|
34
|
+
return decodeURIComponent(encodedFileName);
|
|
35
|
+
} catch (e) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function getYouTubeId(url) {
|
|
40
|
+
const regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/;
|
|
41
|
+
const match = url.match(regExp);
|
|
42
|
+
return match && match[7].length === 11 ? match[7] : "";
|
|
43
|
+
}
|
|
44
|
+
function getVuetifyColor(colorName) {
|
|
45
|
+
if (!colorName) return "#1976D2";
|
|
46
|
+
const colorMap = {
|
|
47
|
+
primary: "#1976D2",
|
|
48
|
+
secondary: "#424242",
|
|
49
|
+
success: "#4CAF50",
|
|
50
|
+
info: "#2196F3",
|
|
51
|
+
warning: "#FB8C00",
|
|
52
|
+
error: "#FF5252",
|
|
53
|
+
accent: "#82B1FF"
|
|
54
|
+
};
|
|
55
|
+
if (colorMap[colorName.toLowerCase()]) {
|
|
56
|
+
return colorMap[colorName.toLowerCase()];
|
|
57
|
+
}
|
|
58
|
+
return colorName;
|
|
59
|
+
}
|
|
60
|
+
function getGroupedButtons(buttons) {
|
|
61
|
+
const rows = {};
|
|
62
|
+
buttons.forEach((button) => {
|
|
63
|
+
const row = button.row || 1;
|
|
64
|
+
if (!rows[row]) {
|
|
65
|
+
rows[row] = [];
|
|
66
|
+
}
|
|
67
|
+
rows[row].push(button);
|
|
68
|
+
});
|
|
69
|
+
return Object.keys(rows).sort((a, b) => parseInt(a) - parseInt(b)).map((row) => rows[parseInt(row)]);
|
|
70
|
+
}
|
|
71
|
+
function generateMapId(index) {
|
|
72
|
+
return `map-container-${index}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
73
|
+
}
|
|
74
|
+
function cleanOrcaMarkers(text) {
|
|
75
|
+
return text.replace(/\[orca\..*?\]/g, "").trim();
|
|
76
|
+
}
|
|
77
|
+
function hasLoadingMarkers(content) {
|
|
78
|
+
return /\[orca\.(?:loading|image\.loading|loading\.image)\.start\]/.test(
|
|
79
|
+
content
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
function getOutlinedButtonStyle(color) {
|
|
83
|
+
if (!color) return {};
|
|
84
|
+
const hexColor = getVuetifyColor(color);
|
|
85
|
+
return {
|
|
86
|
+
border: `1px solid ${hexColor}`,
|
|
87
|
+
color: hexColor,
|
|
88
|
+
"background-color": "transparent"
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function getOutlinedButtonTextStyle(color) {
|
|
92
|
+
if (!color) return {};
|
|
93
|
+
const hexColor = getVuetifyColor(color);
|
|
94
|
+
return {
|
|
95
|
+
color: hexColor,
|
|
96
|
+
"background-color": "transparent"
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function getAppendIconStyle(color) {
|
|
100
|
+
if (!color) return {};
|
|
101
|
+
const hexColor = getVuetifyColor(color);
|
|
102
|
+
return {
|
|
103
|
+
color: hexColor,
|
|
104
|
+
fill: hexColor
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const MARKERS = [
|
|
108
|
+
// Loading markers (general)
|
|
109
|
+
{
|
|
110
|
+
type: "general-loading",
|
|
111
|
+
start: "[orca.loading.start]",
|
|
112
|
+
end: "[orca.loading.end]"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
type: "thinking-loading",
|
|
116
|
+
start: "[orca.loading.thinking.start]",
|
|
117
|
+
end: "[orca.loading.thinking.end]"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
type: "searching-loading",
|
|
121
|
+
start: "[orca.loading.searching.start]",
|
|
122
|
+
end: "[orca.loading.searching.end]"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
type: "coding-loading",
|
|
126
|
+
start: "[orca.loading.coding.start]",
|
|
127
|
+
end: "[orca.loading.coding.end]"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
type: "analyzing-loading",
|
|
131
|
+
start: "[orca.loading.analyzing.start]",
|
|
132
|
+
end: "[orca.loading.analyzing.end]"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
type: "generating-loading",
|
|
136
|
+
start: "[orca.loading.generating.start]",
|
|
137
|
+
end: "[orca.loading.generating.end]"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
type: "custom-loading",
|
|
141
|
+
start: "[orca.loading.custom.start]",
|
|
142
|
+
end: "[orca.loading.custom.end]"
|
|
143
|
+
},
|
|
144
|
+
// Loading markers (content-specific)
|
|
145
|
+
{
|
|
146
|
+
type: "image-loading",
|
|
147
|
+
start: "[orca.loading.image.start]",
|
|
148
|
+
end: "[orca.loading.image.end]"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
type: "video-loading",
|
|
152
|
+
start: "[orca.loading.video.start]",
|
|
153
|
+
end: "[orca.loading.video.end]"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
type: "youtube-loading",
|
|
157
|
+
start: "[orca.loading.youtube.start]",
|
|
158
|
+
end: "[orca.loading.youtube.end]"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
type: "card-loading",
|
|
162
|
+
start: "[orca.loading.card.list.start]",
|
|
163
|
+
end: "[orca.loading.card.list.end]"
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
type: "map-loading",
|
|
167
|
+
start: "[orca.loading.map.start]",
|
|
168
|
+
end: "[orca.loading.map.end]"
|
|
169
|
+
},
|
|
170
|
+
// Content markers
|
|
171
|
+
{ type: "image", start: "[orca.image.start]", end: "[orca.image.end]" },
|
|
172
|
+
{ type: "video", start: "[orca.video.start]", end: "[orca.video.end]" },
|
|
173
|
+
{
|
|
174
|
+
type: "youtube",
|
|
175
|
+
start: "[orca.youtube.start]",
|
|
176
|
+
end: "[orca.youtube.end]"
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
type: "card",
|
|
180
|
+
start: "[orca.list.card.start]",
|
|
181
|
+
end: "[orca.list.card.end]"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
type: "location",
|
|
185
|
+
start: "[orca.location.start]",
|
|
186
|
+
end: "[orca.location.end]"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
type: "buttons",
|
|
190
|
+
start: "[orca.buttons.start]",
|
|
191
|
+
end: "[orca.buttons.end]"
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
type: "tracing",
|
|
195
|
+
start: "[orca.tracing.start]",
|
|
196
|
+
end: "[orca.tracing.end]"
|
|
197
|
+
},
|
|
198
|
+
{ type: "audio", start: "[orca.audio.start]", end: "[orca.audio.end]" }
|
|
199
|
+
];
|
|
200
|
+
const GENERAL_LOADING_TYPES = [
|
|
201
|
+
"general-loading",
|
|
202
|
+
"thinking-loading",
|
|
203
|
+
"searching-loading",
|
|
204
|
+
"coding-loading",
|
|
205
|
+
"analyzing-loading",
|
|
206
|
+
"generating-loading",
|
|
207
|
+
"custom-loading"
|
|
208
|
+
];
|
|
209
|
+
function escapeRegex(str) {
|
|
210
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
211
|
+
}
|
|
212
|
+
function createMarkerPattern(config) {
|
|
213
|
+
const start = escapeRegex(config.start);
|
|
214
|
+
const end = escapeRegex(config.end);
|
|
215
|
+
return new RegExp(`${start}(.*?)${end}`, "s");
|
|
216
|
+
}
|
|
217
|
+
function generatePatterns(markers) {
|
|
218
|
+
return markers.map((marker) => ({
|
|
219
|
+
type: marker.type,
|
|
220
|
+
regex: createMarkerPattern(marker)
|
|
221
|
+
}));
|
|
222
|
+
}
|
|
223
|
+
const CONTENT_PATTERNS = generatePatterns(MARKERS);
|
|
224
|
+
function filterMarkers(markers, predicate) {
|
|
225
|
+
return markers.filter(predicate);
|
|
226
|
+
}
|
|
227
|
+
function isLoadingType$2(type) {
|
|
228
|
+
return type.includes("-loading");
|
|
229
|
+
}
|
|
230
|
+
function isGeneralLoadingType$1(type) {
|
|
231
|
+
return GENERAL_LOADING_TYPES.includes(type);
|
|
232
|
+
}
|
|
233
|
+
function getGeneralLoadingMarkers(markers) {
|
|
234
|
+
return filterMarkers(markers, (m) => isGeneralLoadingType$1(m.type));
|
|
235
|
+
}
|
|
236
|
+
function getContentMarkers(markers) {
|
|
237
|
+
return filterMarkers(markers, (m) => !isLoadingType$2(m.type));
|
|
238
|
+
}
|
|
239
|
+
function removeByPattern(content, pattern, preserveContent) {
|
|
240
|
+
return content.replace(pattern, preserveContent ? "$1" : "");
|
|
241
|
+
}
|
|
242
|
+
function removeMarkers(content, markers, preserveContent = false) {
|
|
243
|
+
let cleaned = content;
|
|
244
|
+
for (const marker of markers) {
|
|
245
|
+
const pattern = createMarkerPattern(marker);
|
|
246
|
+
cleaned = removeByPattern(cleaned, pattern, preserveContent);
|
|
247
|
+
}
|
|
248
|
+
return cleaned;
|
|
249
|
+
}
|
|
250
|
+
function removeLoadingMarkers(content, loadingMarkers) {
|
|
251
|
+
return removeMarkers(content, loadingMarkers, true);
|
|
252
|
+
}
|
|
253
|
+
function removeContentMarkers(content, contentMarkers) {
|
|
254
|
+
return removeMarkers(content, contentMarkers, false);
|
|
255
|
+
}
|
|
256
|
+
function removeAllMarkers(content, loadingMarkers, contentMarkers) {
|
|
257
|
+
let cleaned = removeLoadingMarkers(content, loadingMarkers);
|
|
258
|
+
cleaned = removeContentMarkers(cleaned, contentMarkers);
|
|
259
|
+
return cleaned;
|
|
260
|
+
}
|
|
261
|
+
const GENERAL_LOADING_MARKERS = getGeneralLoadingMarkers(MARKERS);
|
|
262
|
+
const CONTENT_MARKERS = getContentMarkers(MARKERS);
|
|
263
|
+
function removeOnlyLoadingMarkers(content) {
|
|
264
|
+
return removeLoadingMarkers(content, GENERAL_LOADING_MARKERS);
|
|
265
|
+
}
|
|
266
|
+
function removeCompleteMarkers(content) {
|
|
267
|
+
return removeAllMarkers(content, GENERAL_LOADING_MARKERS, CONTENT_MARKERS);
|
|
268
|
+
}
|
|
269
|
+
function findMatches(content) {
|
|
270
|
+
const matches = CONTENT_PATTERNS.map(({ type, regex }) => {
|
|
271
|
+
const match = content.match(regex);
|
|
272
|
+
return {
|
|
273
|
+
type,
|
|
274
|
+
match,
|
|
275
|
+
index: match ? content.indexOf(match[0]) : Infinity
|
|
276
|
+
};
|
|
277
|
+
});
|
|
278
|
+
return matches.filter(
|
|
279
|
+
(m) => m.match !== null && m.index !== Infinity
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
function createFieldPattern(fieldName, allFieldNames) {
|
|
283
|
+
const otherFields = allFieldNames.filter((f) => f !== fieldName).map((f) => `${f}:`).join("|");
|
|
284
|
+
const pattern = `${fieldName}:\\s*([\\s\\S]*?)(?=\\s*(?:${otherFields})|$)`;
|
|
285
|
+
return new RegExp(pattern, "m");
|
|
286
|
+
}
|
|
287
|
+
function extractField(block, fieldName, allFieldNames) {
|
|
288
|
+
const pattern = createFieldPattern(fieldName, allFieldNames);
|
|
289
|
+
const match = block.match(pattern);
|
|
290
|
+
if (!match || !match[1]) {
|
|
291
|
+
return "";
|
|
292
|
+
}
|
|
293
|
+
let value = match[1];
|
|
294
|
+
value = value.replace(/\u200b/g, "");
|
|
295
|
+
const firstLine = value.split("\n")[0];
|
|
296
|
+
return firstLine.trim();
|
|
297
|
+
}
|
|
298
|
+
function parseYamlList(payload, fields, mapper) {
|
|
299
|
+
const fieldNames = fields.map((f) => f.name);
|
|
300
|
+
const blocks = payload.split("- ").map((block) => block.trim()).filter((block) => block);
|
|
301
|
+
const results = blocks.map((block) => {
|
|
302
|
+
const extracted = {};
|
|
303
|
+
for (const field of fields) {
|
|
304
|
+
const value = extractField(block, field.name, fieldNames);
|
|
305
|
+
if (field.type === "number") {
|
|
306
|
+
const num = parseInt(value, 10);
|
|
307
|
+
extracted[field.name] = Number.isFinite(num) ? num : field.defaultValue !== void 0 ? field.defaultValue : void 0;
|
|
308
|
+
} else {
|
|
309
|
+
extracted[field.name] = value || (field.defaultValue !== void 0 ? field.defaultValue : field.required ? "" : void 0);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return mapper(extracted);
|
|
313
|
+
});
|
|
314
|
+
return results;
|
|
315
|
+
}
|
|
316
|
+
const CARD_FIELDS = [
|
|
317
|
+
{
|
|
318
|
+
name: "photo",
|
|
319
|
+
required: true,
|
|
320
|
+
defaultValue: "https://via.placeholder.com/300x200"
|
|
321
|
+
},
|
|
322
|
+
{ name: "header", required: true, defaultValue: "Card Title" },
|
|
323
|
+
{ name: "subheader", defaultValue: "" }
|
|
324
|
+
];
|
|
325
|
+
function parseCard(payload) {
|
|
326
|
+
return parseYamlList(payload, CARD_FIELDS, (data) => ({
|
|
327
|
+
photo: data.photo || "",
|
|
328
|
+
header: data.header || "",
|
|
329
|
+
subheader: data.subheader || ""
|
|
330
|
+
}));
|
|
331
|
+
}
|
|
332
|
+
const BUTTON_FIELDS = [
|
|
333
|
+
{ name: "type", required: true, defaultValue: "action" },
|
|
334
|
+
{ name: "label", required: true, defaultValue: "Button" },
|
|
335
|
+
{ name: "url", defaultValue: void 0 },
|
|
336
|
+
{ name: "id", type: "number", defaultValue: void 0 },
|
|
337
|
+
{ name: "color", defaultValue: "primary" },
|
|
338
|
+
{ name: "row", type: "number", defaultValue: 1 }
|
|
339
|
+
];
|
|
340
|
+
function parseButton(payload) {
|
|
341
|
+
const result = parseYamlList(payload, BUTTON_FIELDS, (data) => {
|
|
342
|
+
const type = data.type === "link" ? "link" : "action";
|
|
343
|
+
return {
|
|
344
|
+
type,
|
|
345
|
+
label: data.label || "",
|
|
346
|
+
url: data.url,
|
|
347
|
+
id: data.id,
|
|
348
|
+
color: data.color,
|
|
349
|
+
row: data.row
|
|
350
|
+
};
|
|
351
|
+
});
|
|
352
|
+
return result;
|
|
353
|
+
}
|
|
354
|
+
const AUDIO_FIELDS = [
|
|
355
|
+
{ name: "label", required: true, defaultValue: "Audio Track" },
|
|
356
|
+
{ name: "url", required: true, defaultValue: "" },
|
|
357
|
+
{ name: "type", required: true, defaultValue: "audio/mpeg" }
|
|
358
|
+
];
|
|
359
|
+
function parseAudio(payload) {
|
|
360
|
+
return parseYamlList(payload, AUDIO_FIELDS, (data) => ({
|
|
361
|
+
label: data.label || "",
|
|
362
|
+
url: data.url || "",
|
|
363
|
+
type: data.type || ""
|
|
364
|
+
}));
|
|
365
|
+
}
|
|
366
|
+
function parseLocation(payload) {
|
|
367
|
+
const [latitude, longitude] = payload.split(",").map((coord) => coord.trim());
|
|
368
|
+
const parsedLatitude = parseFloat(latitude);
|
|
369
|
+
const parsedLongitude = parseFloat(longitude);
|
|
370
|
+
return {
|
|
371
|
+
latitude: Number.isFinite(parsedLatitude) ? parsedLatitude : 0,
|
|
372
|
+
longitude: Number.isFinite(parsedLongitude) ? parsedLongitude : 0
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
function parseTracing(payload) {
|
|
376
|
+
var _a;
|
|
377
|
+
const visibilityMatch = payload.match(/visibility:\s*(\w+)/);
|
|
378
|
+
const visibility = (visibilityMatch == null ? void 0 : visibilityMatch[1]) || "all";
|
|
379
|
+
const contentMatch = payload.match(/content:\s*([\s\S]*)/);
|
|
380
|
+
const content = ((_a = contentMatch == null ? void 0 : contentMatch[1]) == null ? void 0 : _a.trim()) || payload;
|
|
381
|
+
return {
|
|
382
|
+
visibility,
|
|
383
|
+
content,
|
|
384
|
+
rawContent: payload
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
function isLoadingType$1(type) {
|
|
388
|
+
return type.includes("-loading");
|
|
389
|
+
}
|
|
390
|
+
const SIMPLE_CONTENT_TYPES = ["image", "video", "youtube"];
|
|
391
|
+
const PARSER_MAP = {
|
|
392
|
+
card: parseCard,
|
|
393
|
+
location: parseLocation,
|
|
394
|
+
buttons: parseButton,
|
|
395
|
+
tracing: parseTracing,
|
|
396
|
+
audio: parseAudio
|
|
397
|
+
};
|
|
398
|
+
function processMatch(type, payload) {
|
|
399
|
+
if (isLoadingType$1(type)) {
|
|
400
|
+
return null;
|
|
401
|
+
}
|
|
402
|
+
if (SIMPLE_CONTENT_TYPES.includes(type)) {
|
|
403
|
+
return { type, content: payload };
|
|
404
|
+
}
|
|
405
|
+
const parser = PARSER_MAP[type];
|
|
406
|
+
if (parser) {
|
|
407
|
+
const content = parser(payload);
|
|
408
|
+
return { type, content };
|
|
409
|
+
}
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
412
|
+
function isGeneralLoadingType(type) {
|
|
413
|
+
return GENERAL_LOADING_TYPES.includes(type);
|
|
414
|
+
}
|
|
415
|
+
function parseContentRecursively(content) {
|
|
416
|
+
const parts = [];
|
|
417
|
+
let remainingContent = content;
|
|
418
|
+
let iteration = 0;
|
|
419
|
+
const maxIterations = 100;
|
|
420
|
+
while (remainingContent.length > 0 && iteration < maxIterations) {
|
|
421
|
+
iteration++;
|
|
422
|
+
const matches = findMatches(remainingContent);
|
|
423
|
+
if (matches.length === 0) {
|
|
424
|
+
const cleanText = removeCompleteMarkers(remainingContent).trim();
|
|
425
|
+
if (cleanText) {
|
|
426
|
+
parts.push({ type: "text", content: cleanText });
|
|
427
|
+
}
|
|
428
|
+
break;
|
|
429
|
+
}
|
|
430
|
+
const firstMatch = matches.reduce(
|
|
431
|
+
(prev, current) => prev.index < current.index ? prev : current
|
|
432
|
+
);
|
|
433
|
+
const shouldSkip = isGeneralLoadingType(firstMatch.type);
|
|
434
|
+
const textBefore = remainingContent.substring(0, firstMatch.index);
|
|
435
|
+
const cleanTextBefore = removeCompleteMarkers(textBefore).trim();
|
|
436
|
+
if (cleanTextBefore) {
|
|
437
|
+
parts.push({ type: "text", content: cleanTextBefore });
|
|
438
|
+
}
|
|
439
|
+
if (!shouldSkip) {
|
|
440
|
+
const matchPayload = (firstMatch.match[1] ?? "").trim();
|
|
441
|
+
const part = processMatch(firstMatch.type, matchPayload);
|
|
442
|
+
if (part) {
|
|
443
|
+
parts.push(part);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
const matchEnd = firstMatch.index + firstMatch.match[0].length;
|
|
447
|
+
remainingContent = remainingContent.substring(matchEnd);
|
|
448
|
+
}
|
|
449
|
+
return parts;
|
|
450
|
+
}
|
|
451
|
+
function useContentParser(description) {
|
|
452
|
+
return computed(() => {
|
|
453
|
+
const content = unref(description);
|
|
454
|
+
return parseContent(content || "");
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
function parseContent(content) {
|
|
458
|
+
const parts = [];
|
|
459
|
+
let remainingContent = content;
|
|
460
|
+
let iteration = 0;
|
|
461
|
+
const MAX_ITERATIONS = 100;
|
|
462
|
+
while (remainingContent.length > 0 && iteration < MAX_ITERATIONS) {
|
|
463
|
+
iteration++;
|
|
464
|
+
const matches = findMatches(remainingContent);
|
|
465
|
+
if (matches.length === 0) {
|
|
466
|
+
addCleanTextIfExists(parts, remainingContent);
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
469
|
+
const firstMatch = matches.reduce(
|
|
470
|
+
(prev, current) => prev.index < current.index ? prev : current
|
|
471
|
+
);
|
|
472
|
+
const textBefore = remainingContent.substring(0, firstMatch.index);
|
|
473
|
+
addCleanTextIfExists(parts, textBefore);
|
|
474
|
+
processMatchAndAddParts(parts, firstMatch);
|
|
475
|
+
const matchEnd = firstMatch.index + firstMatch.match[0].length;
|
|
476
|
+
remainingContent = remainingContent.substring(matchEnd);
|
|
477
|
+
}
|
|
478
|
+
return parts;
|
|
479
|
+
}
|
|
480
|
+
function addCleanTextIfExists(parts, text) {
|
|
481
|
+
const cleanText = removeCompleteMarkers(text).trim();
|
|
482
|
+
if (cleanText) {
|
|
483
|
+
parts.push({ type: "text", content: cleanText });
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
function processMatchAndAddParts(parts, match) {
|
|
487
|
+
const matchPayload = (match.match[1] ?? "").trim();
|
|
488
|
+
const isLoadingType2 = match.type.includes("-loading");
|
|
489
|
+
if (isLoadingType2 && !matchPayload) {
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
if (isLoadingType2 && matchPayload) {
|
|
493
|
+
const cleanPayload = removeOnlyLoadingMarkers(matchPayload);
|
|
494
|
+
if (cleanPayload.trim()) {
|
|
495
|
+
const nestedParts = parseContentRecursively(cleanPayload);
|
|
496
|
+
parts.push(...nestedParts);
|
|
497
|
+
}
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
const part = processMatch(match.type, matchPayload);
|
|
501
|
+
if (part) {
|
|
502
|
+
parts.push(part);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
const LOADING_PATTERNS = {
|
|
506
|
+
general: {
|
|
507
|
+
start: "[orca.loading.start]",
|
|
508
|
+
end: "[orca.loading.end]"
|
|
509
|
+
},
|
|
510
|
+
thinking: {
|
|
511
|
+
start: "[orca.loading.thinking.start]",
|
|
512
|
+
end: "[orca.loading.thinking.end]"
|
|
513
|
+
},
|
|
514
|
+
searching: {
|
|
515
|
+
start: "[orca.loading.searching.start]",
|
|
516
|
+
end: "[orca.loading.searching.end]"
|
|
517
|
+
},
|
|
518
|
+
coding: {
|
|
519
|
+
start: "[orca.loading.coding.start]",
|
|
520
|
+
end: "[orca.loading.coding.end]"
|
|
521
|
+
},
|
|
522
|
+
analyzing: {
|
|
523
|
+
start: "[orca.loading.analyzing.start]",
|
|
524
|
+
end: "[orca.loading.analyzing.end]"
|
|
525
|
+
},
|
|
526
|
+
generating: {
|
|
527
|
+
start: "[orca.loading.generating.start]",
|
|
528
|
+
end: "[orca.loading.generating.end]"
|
|
529
|
+
},
|
|
530
|
+
custom: {
|
|
531
|
+
start: "[orca.loading.custom.start]",
|
|
532
|
+
end: "[orca.loading.custom.end]"
|
|
533
|
+
},
|
|
534
|
+
image: {
|
|
535
|
+
start: "[orca.loading.image.start]",
|
|
536
|
+
end: "[orca.loading.image.end]",
|
|
537
|
+
actual: /\[orca\.image\.start\](.*?)\[orca\.image\.end\]/s
|
|
538
|
+
},
|
|
539
|
+
video: {
|
|
540
|
+
start: "[orca.loading.video.start]",
|
|
541
|
+
end: "[orca.loading.video.end]",
|
|
542
|
+
actual: /\[orca\.video\.start\](.*?)\[orca\.video\.end\]/s
|
|
543
|
+
},
|
|
544
|
+
youtube: {
|
|
545
|
+
start: "[orca.loading.youtube.start]",
|
|
546
|
+
end: "[orca.loading.youtube.end]",
|
|
547
|
+
actual: /\[orca\.youtube\.start\](.*?)\[orca\.youtube\.end\]/s
|
|
548
|
+
},
|
|
549
|
+
card: {
|
|
550
|
+
start: "[orca.loading.card.start]",
|
|
551
|
+
end: "[orca.loading.card.end]",
|
|
552
|
+
actual: /\[orca\.list\.card\.start\](.*?)\[orca\.list\.card\.end\]/s
|
|
553
|
+
},
|
|
554
|
+
map: {
|
|
555
|
+
start: "[orca.loading.map.start]",
|
|
556
|
+
end: "[orca.loading.map.end]",
|
|
557
|
+
actual: /\[orca\.location\.start\](.*?)\[orca\.location\.end\]/s
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
const LOADING_MESSAGES = {
|
|
561
|
+
"general-loading": "⏳ Loading...",
|
|
562
|
+
"thinking-loading": "🤔 Thinking...",
|
|
563
|
+
"searching-loading": "🔍 Searching...",
|
|
564
|
+
"coding-loading": "💻 Coding...",
|
|
565
|
+
"analyzing-loading": "📊 Analyzing...",
|
|
566
|
+
"generating-loading": "✨ Generating...",
|
|
567
|
+
"custom-loading": "⏳ Processing...",
|
|
568
|
+
"image-loading": "🖼️ Loading image...",
|
|
569
|
+
"video-loading": "🎥 Loading video...",
|
|
570
|
+
"youtube-loading": "📺 Loading YouTube video...",
|
|
571
|
+
"card-loading": "🃏 Loading cards...",
|
|
572
|
+
"map-loading": "🗺️ Loading map..."
|
|
573
|
+
};
|
|
574
|
+
function isActiveLoading(content, startPattern, endPattern) {
|
|
575
|
+
const hasStart = content.includes(startPattern);
|
|
576
|
+
const hasEnd = content.includes(endPattern);
|
|
577
|
+
return hasStart && !hasEnd;
|
|
578
|
+
}
|
|
579
|
+
function isActiveContentLoading(content, startPattern, endPattern, actualPattern) {
|
|
580
|
+
const hasStart = content.includes(startPattern);
|
|
581
|
+
const hasEnd = content.includes(endPattern);
|
|
582
|
+
const hasActual = actualPattern ? actualPattern.test(content) : false;
|
|
583
|
+
return hasStart && !hasEnd && !hasActual;
|
|
584
|
+
}
|
|
585
|
+
function useLoadingStates(description) {
|
|
586
|
+
const isLoading = ref(false);
|
|
587
|
+
const isImageLoading = ref(false);
|
|
588
|
+
const isVideoLoading = ref(false);
|
|
589
|
+
const isCardLoading = ref(false);
|
|
590
|
+
const isLocationLoading = ref(false);
|
|
591
|
+
const descriptionValue = computed(() => {
|
|
592
|
+
return unref(description);
|
|
593
|
+
});
|
|
594
|
+
watch(
|
|
595
|
+
descriptionValue,
|
|
596
|
+
(val) => {
|
|
597
|
+
if (!val) {
|
|
598
|
+
isLoading.value = false;
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
const hasActiveLoading = isActiveLoading(
|
|
602
|
+
val,
|
|
603
|
+
LOADING_PATTERNS.general.start,
|
|
604
|
+
LOADING_PATTERNS.general.end
|
|
605
|
+
) || isActiveLoading(
|
|
606
|
+
val,
|
|
607
|
+
LOADING_PATTERNS.thinking.start,
|
|
608
|
+
LOADING_PATTERNS.thinking.end
|
|
609
|
+
) || isActiveLoading(
|
|
610
|
+
val,
|
|
611
|
+
LOADING_PATTERNS.searching.start,
|
|
612
|
+
LOADING_PATTERNS.searching.end
|
|
613
|
+
) || isActiveLoading(
|
|
614
|
+
val,
|
|
615
|
+
LOADING_PATTERNS.coding.start,
|
|
616
|
+
LOADING_PATTERNS.coding.end
|
|
617
|
+
) || isActiveLoading(
|
|
618
|
+
val,
|
|
619
|
+
LOADING_PATTERNS.analyzing.start,
|
|
620
|
+
LOADING_PATTERNS.analyzing.end
|
|
621
|
+
) || isActiveLoading(
|
|
622
|
+
val,
|
|
623
|
+
LOADING_PATTERNS.generating.start,
|
|
624
|
+
LOADING_PATTERNS.generating.end
|
|
625
|
+
) || isActiveLoading(
|
|
626
|
+
val,
|
|
627
|
+
LOADING_PATTERNS.custom.start,
|
|
628
|
+
LOADING_PATTERNS.custom.end
|
|
629
|
+
);
|
|
630
|
+
isLoading.value = hasActiveLoading;
|
|
631
|
+
},
|
|
632
|
+
{ immediate: true }
|
|
633
|
+
);
|
|
634
|
+
watch(
|
|
635
|
+
descriptionValue,
|
|
636
|
+
(val) => {
|
|
637
|
+
isImageLoading.value = isActiveContentLoading(
|
|
638
|
+
val,
|
|
639
|
+
LOADING_PATTERNS.image.start,
|
|
640
|
+
LOADING_PATTERNS.image.end,
|
|
641
|
+
LOADING_PATTERNS.image.actual
|
|
642
|
+
);
|
|
643
|
+
},
|
|
644
|
+
{ immediate: true }
|
|
645
|
+
);
|
|
646
|
+
watch(
|
|
647
|
+
descriptionValue,
|
|
648
|
+
(val) => {
|
|
649
|
+
const videoLoading = isActiveContentLoading(
|
|
650
|
+
val,
|
|
651
|
+
LOADING_PATTERNS.video.start,
|
|
652
|
+
LOADING_PATTERNS.video.end,
|
|
653
|
+
LOADING_PATTERNS.video.actual
|
|
654
|
+
);
|
|
655
|
+
const youtubeLoading = isActiveContentLoading(
|
|
656
|
+
val,
|
|
657
|
+
LOADING_PATTERNS.youtube.start,
|
|
658
|
+
LOADING_PATTERNS.youtube.end,
|
|
659
|
+
LOADING_PATTERNS.youtube.actual
|
|
660
|
+
);
|
|
661
|
+
isVideoLoading.value = videoLoading || youtubeLoading;
|
|
662
|
+
},
|
|
663
|
+
{ immediate: true }
|
|
664
|
+
);
|
|
665
|
+
watch(
|
|
666
|
+
descriptionValue,
|
|
667
|
+
(val) => {
|
|
668
|
+
isCardLoading.value = isActiveContentLoading(
|
|
669
|
+
val,
|
|
670
|
+
LOADING_PATTERNS.card.start,
|
|
671
|
+
LOADING_PATTERNS.card.end,
|
|
672
|
+
LOADING_PATTERNS.card.actual
|
|
673
|
+
);
|
|
674
|
+
},
|
|
675
|
+
{ immediate: true }
|
|
676
|
+
);
|
|
677
|
+
watch(
|
|
678
|
+
descriptionValue,
|
|
679
|
+
(val) => {
|
|
680
|
+
isLocationLoading.value = isActiveContentLoading(
|
|
681
|
+
val,
|
|
682
|
+
LOADING_PATTERNS.map.start,
|
|
683
|
+
LOADING_PATTERNS.map.end,
|
|
684
|
+
LOADING_PATTERNS.map.actual
|
|
685
|
+
);
|
|
686
|
+
},
|
|
687
|
+
{ immediate: true }
|
|
688
|
+
);
|
|
689
|
+
const getLoadingMessage = (loadingType) => {
|
|
690
|
+
return LOADING_MESSAGES[loadingType] || LOADING_MESSAGES["general-loading"];
|
|
691
|
+
};
|
|
692
|
+
return {
|
|
693
|
+
isLoading,
|
|
694
|
+
isImageLoading,
|
|
695
|
+
isVideoLoading,
|
|
696
|
+
isCardLoading,
|
|
697
|
+
isLocationLoading,
|
|
698
|
+
getLoadingMessage
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
const COPY_ICON = `
|
|
702
|
+
<div class="d-flex align-center">
|
|
703
|
+
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
704
|
+
<rect x="6.66675" y="6.66675" width="10" height="10" rx="2" stroke="rgb(var(--v-theme-on-surface))" stroke-opacity="0.9" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
705
|
+
<path d="M13.3333 6.66659V4.99992C13.3333 4.07944 12.5871 3.33325 11.6666 3.33325H4.99992C4.07944 3.33325 3.33325 4.07944 3.33325 4.99992V11.6666C3.33325 12.5871 4.07944 13.3333 4.99992 13.3333H6.66659" stroke="rgb(var(--v-theme-on-surface))" stroke-opacity="0.9" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
706
|
+
</svg>
|
|
707
|
+
<span style="color:rgb(var(--v-theme-on-surface)); font-feature-settings: 'liga' off, 'clig' off; font-family: Inter; font-size: 12px; font-style: normal; font-weight: 400; line-height: 24px;">Copy</span>
|
|
708
|
+
</div>
|
|
709
|
+
`;
|
|
710
|
+
const COPIED_ICON = `
|
|
711
|
+
<div class="d-flex align-center">
|
|
712
|
+
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
713
|
+
<path d="M4.16663 9.99992L8.33329 14.1666L16.6666 5.83325" stroke="rgb(var(--v-theme-on-surface))" stroke-opacity="0.5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
714
|
+
</svg>
|
|
715
|
+
<span style="color: rgb(var(--v-theme-on-surface)); font-feature-settings: 'liga' off, 'clig' off; font-family: Inter; font-size: 12px; font-style: normal; font-weight: 400; line-height: 24px;"> Copied</span>
|
|
716
|
+
</div>
|
|
717
|
+
`;
|
|
718
|
+
const COLLAPSE_ICON = `
|
|
719
|
+
<div class="d-flex align-center">
|
|
720
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
721
|
+
<path d="M7.5 14.1667L10 11.6667L12.5 14.1667" stroke="rgb(var(--v-theme-on-surface))" stroke-opacity="0.9" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
722
|
+
<path d="M7.5 5.83325L10 8.33325L12.5 5.83325" stroke="rgb(var(--v-theme-on-surface))" stroke-opacity="0.9" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
723
|
+
</svg>
|
|
724
|
+
<span style="color: rgb(var(--v-theme-on-surface)); font-feature-settings: 'liga' off, 'clig' off; font-family: Inter; font-size: 12px; font-style: normal; font-weight: 400; line-height: 24px;"> Collapse</span>
|
|
725
|
+
</div>
|
|
726
|
+
`;
|
|
727
|
+
const EXPAND_ICON = `
|
|
728
|
+
<div class="d-flex align-center">
|
|
729
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
730
|
+
<path d="M7.5 14.1667L10 11.6667L12.5 14.1667" stroke="rgb(var(--v-theme-on-surface))" stroke-opacity="0.9" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
731
|
+
<path d="M7.5 5.83325L10 8.33325L12.5 5.83325" stroke="rgb(var(--v-theme-on-surface))" stroke-opacity="0.9" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
732
|
+
</svg>
|
|
733
|
+
<span style="color: rgb(var(--v-theme-on-surface)); font-feature-settings: 'liga' off, 'clig' off; font-family: Inter; font-size: 12px; font-style: normal; font-weight: 400; line-height: 24px;"> Expand</span>
|
|
734
|
+
</div>
|
|
735
|
+
`;
|
|
736
|
+
async function copyToClipboard(text, button) {
|
|
737
|
+
try {
|
|
738
|
+
await navigator.clipboard.writeText(text);
|
|
739
|
+
button.innerHTML = COPIED_ICON;
|
|
740
|
+
setTimeout(() => {
|
|
741
|
+
button.innerHTML = COPY_ICON;
|
|
742
|
+
}, 2e3);
|
|
743
|
+
} catch (error) {
|
|
744
|
+
console.error("Failed to copy code:", error);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
function toggleCodeBlock(wrapper, button) {
|
|
748
|
+
const isCollapsed = wrapper.classList.contains("collapsed");
|
|
749
|
+
if (isCollapsed) {
|
|
750
|
+
wrapper.classList.remove("collapsed");
|
|
751
|
+
wrapper.style.maxHeight = "";
|
|
752
|
+
wrapper.style.overflow = "";
|
|
753
|
+
button.innerHTML = COLLAPSE_ICON;
|
|
754
|
+
} else {
|
|
755
|
+
wrapper.classList.add("collapsed");
|
|
756
|
+
const height = wrapper.scrollHeight;
|
|
757
|
+
wrapper.style.maxHeight = `${height}px`;
|
|
758
|
+
wrapper.offsetHeight;
|
|
759
|
+
wrapper.style.maxHeight = "0px";
|
|
760
|
+
wrapper.style.overflow = "hidden";
|
|
761
|
+
button.innerHTML = EXPAND_ICON;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
function attachCodeButtons(block) {
|
|
765
|
+
if (block.closest(".code-container")) return;
|
|
766
|
+
const codeContainer = document.createElement("div");
|
|
767
|
+
codeContainer.className = "code-container";
|
|
768
|
+
const codeWrapper = document.createElement("div");
|
|
769
|
+
codeWrapper.className = "code-wrapper";
|
|
770
|
+
codeWrapper.style.transition = "max-height 0.3s ease, opacity 0.3s ease";
|
|
771
|
+
codeWrapper.style.overflow = "hidden";
|
|
772
|
+
codeWrapper.appendChild(block.cloneNode(true));
|
|
773
|
+
const buttonsContainer = document.createElement("div");
|
|
774
|
+
buttonsContainer.className = "buttons-container";
|
|
775
|
+
const copyButton = document.createElement("button");
|
|
776
|
+
copyButton.innerHTML = COPY_ICON;
|
|
777
|
+
copyButton.className = "copy-btn";
|
|
778
|
+
copyButton.onclick = () => {
|
|
779
|
+
var _a;
|
|
780
|
+
const code = ((_a = block.querySelector("code")) == null ? void 0 : _a.innerText) || "";
|
|
781
|
+
copyToClipboard(code, copyButton);
|
|
782
|
+
};
|
|
783
|
+
const collapseButton = document.createElement("button");
|
|
784
|
+
collapseButton.innerHTML = COLLAPSE_ICON;
|
|
785
|
+
collapseButton.className = "collapse-btn";
|
|
786
|
+
collapseButton.onclick = () => {
|
|
787
|
+
toggleCodeBlock(codeWrapper, collapseButton);
|
|
788
|
+
};
|
|
789
|
+
buttonsContainer.appendChild(collapseButton);
|
|
790
|
+
buttonsContainer.appendChild(copyButton);
|
|
791
|
+
codeContainer.appendChild(buttonsContainer);
|
|
792
|
+
codeContainer.appendChild(codeWrapper);
|
|
793
|
+
block.replaceWith(codeContainer);
|
|
794
|
+
}
|
|
795
|
+
function useCodeButtons(containerRef, shouldAddButtons) {
|
|
796
|
+
const addCodeButtons = () => {
|
|
797
|
+
nextTick(() => {
|
|
798
|
+
if (!containerRef.value || !shouldAddButtons()) return;
|
|
799
|
+
const codeBlocks = containerRef.value.querySelectorAll("pre");
|
|
800
|
+
codeBlocks.forEach((block) => {
|
|
801
|
+
attachCodeButtons(block);
|
|
802
|
+
});
|
|
803
|
+
});
|
|
804
|
+
};
|
|
805
|
+
onMounted(() => {
|
|
806
|
+
addCodeButtons();
|
|
807
|
+
});
|
|
808
|
+
return {
|
|
809
|
+
addCodeButtons
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
function useImageModal() {
|
|
813
|
+
const modalVisible = ref(false);
|
|
814
|
+
const currentImage = ref("");
|
|
815
|
+
const openModal = (imageUrl) => {
|
|
816
|
+
currentImage.value = imageUrl;
|
|
817
|
+
modalVisible.value = true;
|
|
818
|
+
};
|
|
819
|
+
const closeModal = () => {
|
|
820
|
+
modalVisible.value = false;
|
|
821
|
+
setTimeout(() => {
|
|
822
|
+
currentImage.value = "";
|
|
823
|
+
}, 300);
|
|
824
|
+
};
|
|
825
|
+
return {
|
|
826
|
+
modalVisible,
|
|
827
|
+
currentImage,
|
|
828
|
+
openModal,
|
|
829
|
+
closeModal
|
|
830
|
+
};
|
|
831
|
+
}
|
|
832
|
+
const LOADING_CONTENT_TYPES = [
|
|
833
|
+
"general-loading",
|
|
834
|
+
"thinking-loading",
|
|
835
|
+
"searching-loading",
|
|
836
|
+
"coding-loading",
|
|
837
|
+
"analyzing-loading",
|
|
838
|
+
"generating-loading",
|
|
839
|
+
"custom-loading",
|
|
840
|
+
"image-loading",
|
|
841
|
+
"video-loading",
|
|
842
|
+
"youtube-loading",
|
|
843
|
+
"card-loading",
|
|
844
|
+
"map-loading"
|
|
845
|
+
];
|
|
846
|
+
function isLoadingType(type) {
|
|
847
|
+
return LOADING_CONTENT_TYPES.includes(type);
|
|
848
|
+
}
|
|
849
|
+
const escapeCodeHtml = (value) => {
|
|
850
|
+
const map = {
|
|
851
|
+
"&": "&",
|
|
852
|
+
"<": "<",
|
|
853
|
+
">": ">",
|
|
854
|
+
'"': """,
|
|
855
|
+
"'": "'"
|
|
856
|
+
};
|
|
857
|
+
return value.replace(/[&<>"']/g, (m) => map[m]);
|
|
858
|
+
};
|
|
859
|
+
const md = new MarkdownIt({
|
|
860
|
+
html: false,
|
|
861
|
+
linkify: true,
|
|
862
|
+
typographer: true,
|
|
863
|
+
highlight: (str, lang) => {
|
|
864
|
+
if (lang && hljs.getLanguage(lang)) {
|
|
865
|
+
try {
|
|
866
|
+
return `<pre><code class="hljs">${hljs.highlight(str, { language: lang }).value}</code></pre>`;
|
|
867
|
+
} catch {
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
return `<pre><code class="hljs">${escapeCodeHtml(str)}</code></pre>`;
|
|
871
|
+
}
|
|
872
|
+
}).use(markdownItKatex).use(markdownItLinkAttributes, {
|
|
873
|
+
pattern: /^https?:\/\//,
|
|
874
|
+
attrs: {
|
|
875
|
+
target: "_blank",
|
|
876
|
+
rel: "noopener noreferrer"
|
|
877
|
+
}
|
|
878
|
+
});
|
|
879
|
+
function useMarkdown() {
|
|
880
|
+
const render = (text) => {
|
|
881
|
+
const cleanText = text.replace(/\[orca\..*?\]/g, "").trim();
|
|
882
|
+
return cleanText ? md.render(cleanText) : "";
|
|
883
|
+
};
|
|
884
|
+
return { render };
|
|
885
|
+
}
|
|
886
|
+
const _hoisted_1$e = { class: "image-container tw-my-4" };
|
|
887
|
+
const _hoisted_2$a = { class: "image-wrapper" };
|
|
888
|
+
const _hoisted_3$7 = ["src"];
|
|
889
|
+
const _sfc_main$e = /* @__PURE__ */ defineComponent({
|
|
890
|
+
__name: "OrcaImage",
|
|
891
|
+
props: {
|
|
892
|
+
url: {}
|
|
893
|
+
},
|
|
894
|
+
emits: ["open-modal"],
|
|
895
|
+
setup(__props, { emit: __emit }) {
|
|
896
|
+
const props = __props;
|
|
897
|
+
const emit = __emit;
|
|
898
|
+
const openModal = () => {
|
|
899
|
+
emit("open-modal", props.url);
|
|
900
|
+
};
|
|
901
|
+
return (_ctx, _cache) => {
|
|
902
|
+
return openBlock(), createElementBlock("div", _hoisted_1$e, [
|
|
903
|
+
createElementVNode("div", _hoisted_2$a, [
|
|
904
|
+
createElementVNode("img", {
|
|
905
|
+
src: __props.url,
|
|
906
|
+
alt: "Generated image",
|
|
907
|
+
class: "orca-image",
|
|
908
|
+
loading: "lazy",
|
|
909
|
+
onClick: openModal
|
|
910
|
+
}, null, 8, _hoisted_3$7),
|
|
911
|
+
_cache[0] || (_cache[0] = createStaticVNode('<div class="image-overlay" data-v-e4f9d4c4><div class="zoom-icon" data-v-e4f9d4c4><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-v-e4f9d4c4><circle cx="11" cy="11" r="8" data-v-e4f9d4c4></circle><path d="m21 21-4.35-4.35" data-v-e4f9d4c4></path><line x1="11" y1="8" x2="11" y2="14" data-v-e4f9d4c4></line><line x1="8" y1="11" x2="14" y2="11" data-v-e4f9d4c4></line></svg></div></div>', 1))
|
|
912
|
+
])
|
|
913
|
+
]);
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
});
|
|
917
|
+
const _export_sfc = (sfc, props) => {
|
|
918
|
+
const target = sfc.__vccOpts || sfc;
|
|
919
|
+
for (const [key, val] of props) {
|
|
920
|
+
target[key] = val;
|
|
921
|
+
}
|
|
922
|
+
return target;
|
|
923
|
+
};
|
|
924
|
+
const OrcaImage = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["__scopeId", "data-v-e4f9d4c4"]]);
|
|
925
|
+
const _hoisted_1$d = { class: "orca-video-container" };
|
|
926
|
+
const _hoisted_2$9 = { class: "video-wrapper" };
|
|
927
|
+
const _sfc_main$d = /* @__PURE__ */ defineComponent({
|
|
928
|
+
__name: "OrcaVideo",
|
|
929
|
+
props: {
|
|
930
|
+
url: {}
|
|
931
|
+
},
|
|
932
|
+
setup(__props) {
|
|
933
|
+
const videoOptions = ref({
|
|
934
|
+
autoplay: false,
|
|
935
|
+
controls: true,
|
|
936
|
+
responsive: true,
|
|
937
|
+
fluid: true,
|
|
938
|
+
sources: [
|
|
939
|
+
{
|
|
940
|
+
type: "video/mp4",
|
|
941
|
+
src: ""
|
|
942
|
+
}
|
|
943
|
+
]
|
|
944
|
+
});
|
|
945
|
+
return (_ctx, _cache) => {
|
|
946
|
+
return openBlock(), createElementBlock("div", _hoisted_1$d, [
|
|
947
|
+
createElementVNode("div", _hoisted_2$9, [
|
|
948
|
+
createVNode(unref(VideoPlayer), {
|
|
949
|
+
options: {
|
|
950
|
+
...videoOptions.value,
|
|
951
|
+
sources: [
|
|
952
|
+
{
|
|
953
|
+
type: "video/mp4",
|
|
954
|
+
src: __props.url
|
|
955
|
+
}
|
|
956
|
+
]
|
|
957
|
+
},
|
|
958
|
+
class: "video-player-custom"
|
|
959
|
+
}, null, 8, ["options"])
|
|
960
|
+
])
|
|
961
|
+
]);
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
});
|
|
965
|
+
const OrcaVideo = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["__scopeId", "data-v-7a20a30c"]]);
|
|
966
|
+
const _hoisted_1$c = { class: "orca-youtube-container" };
|
|
967
|
+
const _hoisted_2$8 = { class: "youtube-wrapper" };
|
|
968
|
+
const _hoisted_3$6 = ["src"];
|
|
969
|
+
const _sfc_main$c = /* @__PURE__ */ defineComponent({
|
|
970
|
+
__name: "OrcaYouTube",
|
|
971
|
+
props: {
|
|
972
|
+
url: {}
|
|
973
|
+
},
|
|
974
|
+
setup(__props) {
|
|
975
|
+
const props = __props;
|
|
976
|
+
const embedUrl = computed(() => {
|
|
977
|
+
const videoId = getYouTubeId(props.url);
|
|
978
|
+
return `https://www.youtube.com/embed/${videoId}`;
|
|
979
|
+
});
|
|
980
|
+
return (_ctx, _cache) => {
|
|
981
|
+
return openBlock(), createElementBlock("div", _hoisted_1$c, [
|
|
982
|
+
createElementVNode("div", _hoisted_2$8, [
|
|
983
|
+
createElementVNode("iframe", {
|
|
984
|
+
width: "100%",
|
|
985
|
+
height: "100%",
|
|
986
|
+
src: embedUrl.value,
|
|
987
|
+
frameborder: "0",
|
|
988
|
+
allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
|
|
989
|
+
allowfullscreen: "",
|
|
990
|
+
class: "youtube-iframe"
|
|
991
|
+
}, null, 8, _hoisted_3$6)
|
|
992
|
+
])
|
|
993
|
+
]);
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
});
|
|
997
|
+
const OrcaYouTube = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["__scopeId", "data-v-9cd52c38"]]);
|
|
998
|
+
const _hoisted_1$b = { class: "orca-audio-container" };
|
|
999
|
+
const _hoisted_2$7 = { class: "audio-list" };
|
|
1000
|
+
const _hoisted_3$5 = { class: "audio-content" };
|
|
1001
|
+
const _hoisted_4$4 = { class: "audio-label" };
|
|
1002
|
+
const _hoisted_5 = ["type"];
|
|
1003
|
+
const _hoisted_6 = ["src", "type"];
|
|
1004
|
+
const _sfc_main$b = /* @__PURE__ */ defineComponent({
|
|
1005
|
+
__name: "OrcaAudio",
|
|
1006
|
+
props: {
|
|
1007
|
+
audioItems: {}
|
|
1008
|
+
},
|
|
1009
|
+
setup(__props) {
|
|
1010
|
+
return (_ctx, _cache) => {
|
|
1011
|
+
return openBlock(), createElementBlock("div", _hoisted_1$b, [
|
|
1012
|
+
createElementVNode("div", _hoisted_2$7, [
|
|
1013
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.audioItems, (audio, audioIndex) => {
|
|
1014
|
+
return openBlock(), createElementBlock("div", {
|
|
1015
|
+
key: audioIndex,
|
|
1016
|
+
class: "audio-item"
|
|
1017
|
+
}, [
|
|
1018
|
+
_cache[1] || (_cache[1] = createElementVNode("div", { class: "audio-icon-wrapper" }, [
|
|
1019
|
+
createElementVNode("svg", {
|
|
1020
|
+
class: "audio-icon",
|
|
1021
|
+
fill: "none",
|
|
1022
|
+
stroke: "currentColor",
|
|
1023
|
+
viewBox: "0 0 24 24"
|
|
1024
|
+
}, [
|
|
1025
|
+
createElementVNode("path", {
|
|
1026
|
+
"stroke-linecap": "round",
|
|
1027
|
+
"stroke-linejoin": "round",
|
|
1028
|
+
"stroke-width": "2",
|
|
1029
|
+
d: "M9 19V6l12-3v13M9 19c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zm12-3c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zM9 10l12-3"
|
|
1030
|
+
})
|
|
1031
|
+
])
|
|
1032
|
+
], -1)),
|
|
1033
|
+
createElementVNode("div", _hoisted_3$5, [
|
|
1034
|
+
createElementVNode("p", _hoisted_4$4, toDisplayString(audio.label), 1),
|
|
1035
|
+
createElementVNode("audio", {
|
|
1036
|
+
controls: "",
|
|
1037
|
+
class: "audio-player",
|
|
1038
|
+
type: audio.type
|
|
1039
|
+
}, [
|
|
1040
|
+
createElementVNode("source", {
|
|
1041
|
+
src: audio.url,
|
|
1042
|
+
type: audio.type
|
|
1043
|
+
}, null, 8, _hoisted_6),
|
|
1044
|
+
_cache[0] || (_cache[0] = createTextVNode(" Your browser does not support the audio element. ", -1))
|
|
1045
|
+
], 8, _hoisted_5)
|
|
1046
|
+
])
|
|
1047
|
+
]);
|
|
1048
|
+
}), 128))
|
|
1049
|
+
])
|
|
1050
|
+
]);
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
});
|
|
1054
|
+
const OrcaAudio = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-ade9342b"]]);
|
|
1055
|
+
const _hoisted_1$a = { class: "orca-location-container" };
|
|
1056
|
+
const _hoisted_2$6 = { class: "map-wrapper" };
|
|
1057
|
+
const _hoisted_3$4 = { class: "location-info" };
|
|
1058
|
+
const _hoisted_4$3 = { class: "location-text" };
|
|
1059
|
+
const _sfc_main$a = /* @__PURE__ */ defineComponent({
|
|
1060
|
+
__name: "OrcaLocation",
|
|
1061
|
+
props: {
|
|
1062
|
+
latitude: {},
|
|
1063
|
+
longitude: {},
|
|
1064
|
+
mapboxToken: {}
|
|
1065
|
+
},
|
|
1066
|
+
setup(__props) {
|
|
1067
|
+
const props = __props;
|
|
1068
|
+
const mapInstance = ref(null);
|
|
1069
|
+
const mapLoading = ref(false);
|
|
1070
|
+
const onMapContainerReady = (el) => {
|
|
1071
|
+
const htmlEl = el && "tagName" in el ? el : null;
|
|
1072
|
+
if (!htmlEl) return;
|
|
1073
|
+
if (!el) return;
|
|
1074
|
+
mapLoading.value = true;
|
|
1075
|
+
nextTick(() => {
|
|
1076
|
+
try {
|
|
1077
|
+
mapboxgl.accessToken = props.mapboxToken || "pk.eyJ1IjoicG91cnlhYnpwIiwiYSI6ImNsZ3Vuanl4YzF2NXkzZW1tcnR0MTlxNXEifQ.I3RdtfiL0ObnXbWVKxW1gQ";
|
|
1078
|
+
if (mapInstance.value) {
|
|
1079
|
+
mapInstance.value.remove();
|
|
1080
|
+
mapInstance.value = null;
|
|
1081
|
+
}
|
|
1082
|
+
const containerId = `map-${props.latitude}-${props.longitude}`;
|
|
1083
|
+
htmlEl.id = containerId;
|
|
1084
|
+
const newMap = new mapboxgl.Map({
|
|
1085
|
+
container: htmlEl,
|
|
1086
|
+
style: "mapbox://styles/mapbox/streets-v11",
|
|
1087
|
+
center: [props.longitude, props.latitude],
|
|
1088
|
+
zoom: 12,
|
|
1089
|
+
attributionControl: false
|
|
1090
|
+
});
|
|
1091
|
+
mapInstance.value = newMap;
|
|
1092
|
+
newMap.on("load", () => {
|
|
1093
|
+
new mapboxgl.Marker({
|
|
1094
|
+
color: "#0D5FD6"
|
|
1095
|
+
}).setLngLat([props.longitude, props.latitude]).addTo(newMap);
|
|
1096
|
+
newMap.addControl(new mapboxgl.NavigationControl());
|
|
1097
|
+
setTimeout(() => {
|
|
1098
|
+
newMap.resize();
|
|
1099
|
+
}, 100);
|
|
1100
|
+
mapLoading.value = false;
|
|
1101
|
+
});
|
|
1102
|
+
newMap.on("error", (e) => {
|
|
1103
|
+
console.error("Mapbox error:", e);
|
|
1104
|
+
mapLoading.value = false;
|
|
1105
|
+
});
|
|
1106
|
+
newMap.on("render", () => {
|
|
1107
|
+
newMap.resize();
|
|
1108
|
+
});
|
|
1109
|
+
} catch (error) {
|
|
1110
|
+
console.error("Error initializing map:", error);
|
|
1111
|
+
mapLoading.value = false;
|
|
1112
|
+
}
|
|
1113
|
+
});
|
|
1114
|
+
};
|
|
1115
|
+
onUnmounted(() => {
|
|
1116
|
+
if (mapInstance.value) {
|
|
1117
|
+
mapInstance.value.remove();
|
|
1118
|
+
mapInstance.value = null;
|
|
1119
|
+
}
|
|
1120
|
+
});
|
|
1121
|
+
return (_ctx, _cache) => {
|
|
1122
|
+
return openBlock(), createElementBlock("div", _hoisted_1$a, [
|
|
1123
|
+
createElementVNode("div", _hoisted_2$6, [
|
|
1124
|
+
(openBlock(), createElementBlock("div", {
|
|
1125
|
+
ref: (el) => onMapContainerReady(el),
|
|
1126
|
+
class: "map-container",
|
|
1127
|
+
key: `map-${__props.latitude}-${__props.longitude}`
|
|
1128
|
+
}))
|
|
1129
|
+
]),
|
|
1130
|
+
createElementVNode("div", _hoisted_3$4, [
|
|
1131
|
+
_cache[0] || (_cache[0] = createElementVNode("div", { class: "location-icon" }, [
|
|
1132
|
+
createElementVNode("svg", {
|
|
1133
|
+
width: "16",
|
|
1134
|
+
height: "16",
|
|
1135
|
+
viewBox: "0 0 24 24",
|
|
1136
|
+
fill: "none",
|
|
1137
|
+
stroke: "currentColor",
|
|
1138
|
+
"stroke-width": "2"
|
|
1139
|
+
}, [
|
|
1140
|
+
createElementVNode("path", { d: "M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z" }),
|
|
1141
|
+
createElementVNode("circle", {
|
|
1142
|
+
cx: "12",
|
|
1143
|
+
cy: "10",
|
|
1144
|
+
r: "3"
|
|
1145
|
+
})
|
|
1146
|
+
])
|
|
1147
|
+
], -1)),
|
|
1148
|
+
createElementVNode("span", _hoisted_4$3, toDisplayString(__props.latitude.toFixed(6)) + ", " + toDisplayString(__props.longitude.toFixed(6)), 1)
|
|
1149
|
+
])
|
|
1150
|
+
]);
|
|
1151
|
+
};
|
|
1152
|
+
}
|
|
1153
|
+
});
|
|
1154
|
+
const OrcaLocation = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["__scopeId", "data-v-99a42606"]]);
|
|
1155
|
+
const _hoisted_1$9 = { class: "orca-card-container" };
|
|
1156
|
+
const _hoisted_2$5 = {
|
|
1157
|
+
key: 0,
|
|
1158
|
+
class: "card-image-wrapper"
|
|
1159
|
+
};
|
|
1160
|
+
const _hoisted_3$3 = {
|
|
1161
|
+
key: 1,
|
|
1162
|
+
class: "card-subheader"
|
|
1163
|
+
};
|
|
1164
|
+
const _hoisted_4$2 = {
|
|
1165
|
+
key: 2,
|
|
1166
|
+
class: "card-text"
|
|
1167
|
+
};
|
|
1168
|
+
const _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
1169
|
+
__name: "OrcaCardList",
|
|
1170
|
+
props: {
|
|
1171
|
+
cards: {}
|
|
1172
|
+
},
|
|
1173
|
+
setup(__props) {
|
|
1174
|
+
return (_ctx, _cache) => {
|
|
1175
|
+
return openBlock(), createElementBlock("div", _hoisted_1$9, [
|
|
1176
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.cards, (card, i) => {
|
|
1177
|
+
return openBlock(), createBlock(unref(VCard), {
|
|
1178
|
+
key: i,
|
|
1179
|
+
class: "orca-card",
|
|
1180
|
+
elevation: "2"
|
|
1181
|
+
}, {
|
|
1182
|
+
default: withCtx(() => [
|
|
1183
|
+
card.photo ? (openBlock(), createElementBlock("div", _hoisted_2$5, [
|
|
1184
|
+
createVNode(unref(VImg), {
|
|
1185
|
+
src: card.photo,
|
|
1186
|
+
height: "223",
|
|
1187
|
+
cover: "",
|
|
1188
|
+
class: "card-image"
|
|
1189
|
+
}, null, 8, ["src"])
|
|
1190
|
+
])) : createCommentVNode("", true),
|
|
1191
|
+
createVNode(unref(VCardItem), { class: "card-content" }, {
|
|
1192
|
+
default: withCtx(() => [
|
|
1193
|
+
card.header ? (openBlock(), createBlock(unref(VCardTitle), {
|
|
1194
|
+
key: 0,
|
|
1195
|
+
class: "card-header"
|
|
1196
|
+
}, {
|
|
1197
|
+
default: withCtx(() => [
|
|
1198
|
+
createTextVNode(toDisplayString(card.header), 1)
|
|
1199
|
+
]),
|
|
1200
|
+
_: 2
|
|
1201
|
+
}, 1024)) : createCommentVNode("", true),
|
|
1202
|
+
card.subheader ? (openBlock(), createElementBlock("span", _hoisted_3$3, toDisplayString(card.subheader), 1)) : createCommentVNode("", true),
|
|
1203
|
+
card.text ? (openBlock(), createElementBlock("p", _hoisted_4$2, toDisplayString(card.text), 1)) : createCommentVNode("", true)
|
|
1204
|
+
]),
|
|
1205
|
+
_: 2
|
|
1206
|
+
}, 1024)
|
|
1207
|
+
]),
|
|
1208
|
+
_: 2
|
|
1209
|
+
}, 1024);
|
|
1210
|
+
}), 128))
|
|
1211
|
+
]);
|
|
1212
|
+
};
|
|
1213
|
+
}
|
|
1214
|
+
});
|
|
1215
|
+
const OrcaCardList = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["__scopeId", "data-v-d9e3b93c"]]);
|
|
1216
|
+
const _hoisted_1$8 = { class: "orca-buttons-container tw-my-4" };
|
|
1217
|
+
const _sfc_main$8 = /* @__PURE__ */ defineComponent({
|
|
1218
|
+
__name: "OrcaButtons",
|
|
1219
|
+
props: {
|
|
1220
|
+
buttons: {},
|
|
1221
|
+
disabled: { type: Boolean }
|
|
1222
|
+
},
|
|
1223
|
+
emits: ["button-click"],
|
|
1224
|
+
setup(__props, { emit: __emit }) {
|
|
1225
|
+
const props = __props;
|
|
1226
|
+
const emit = __emit;
|
|
1227
|
+
const groupedButtons = computed(() => getGroupedButtons(props.buttons));
|
|
1228
|
+
const handleButtonClick = (button) => {
|
|
1229
|
+
if (button.type === "action" && !props.disabled) {
|
|
1230
|
+
emit("button-click", button);
|
|
1231
|
+
}
|
|
1232
|
+
};
|
|
1233
|
+
return (_ctx, _cache) => {
|
|
1234
|
+
return openBlock(), createElementBlock("div", _hoisted_1$8, [
|
|
1235
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(groupedButtons.value, (row, rowIndex) => {
|
|
1236
|
+
return openBlock(), createElementBlock("div", {
|
|
1237
|
+
key: rowIndex,
|
|
1238
|
+
class: "button-row"
|
|
1239
|
+
}, [
|
|
1240
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(row, (button, index) => {
|
|
1241
|
+
return openBlock(), createBlock(unref(VBtn), {
|
|
1242
|
+
disabled: __props.disabled,
|
|
1243
|
+
key: index,
|
|
1244
|
+
class: normalizeClass(["orca-button", "custom-outlined-button"]),
|
|
1245
|
+
style: normalizeStyle(unref(getOutlinedButtonStyle)(button.color)),
|
|
1246
|
+
variant: "text",
|
|
1247
|
+
rounded: "xl",
|
|
1248
|
+
target: button.type === "link" ? "_blank" : void 0,
|
|
1249
|
+
href: button.type === "link" ? button.url : void 0,
|
|
1250
|
+
onClick: ($event) => handleButtonClick(button)
|
|
1251
|
+
}, createSlots({
|
|
1252
|
+
default: withCtx(() => [
|
|
1253
|
+
createElementVNode("span", {
|
|
1254
|
+
style: normalizeStyle(unref(getOutlinedButtonTextStyle)(button.color))
|
|
1255
|
+
}, toDisplayString(button.label), 5)
|
|
1256
|
+
]),
|
|
1257
|
+
_: 2
|
|
1258
|
+
}, [
|
|
1259
|
+
button.type === "link" ? {
|
|
1260
|
+
name: "append",
|
|
1261
|
+
fn: withCtx(() => [
|
|
1262
|
+
createVNode(unref(VIcon), {
|
|
1263
|
+
icon: "tabler-external-link",
|
|
1264
|
+
style: normalizeStyle(unref(getAppendIconStyle)(button.color)),
|
|
1265
|
+
size: "small"
|
|
1266
|
+
}, null, 8, ["style"])
|
|
1267
|
+
]),
|
|
1268
|
+
key: "0"
|
|
1269
|
+
} : void 0
|
|
1270
|
+
]), 1032, ["disabled", "style", "target", "href", "onClick"]);
|
|
1271
|
+
}), 128))
|
|
1272
|
+
]);
|
|
1273
|
+
}), 128))
|
|
1274
|
+
]);
|
|
1275
|
+
};
|
|
1276
|
+
}
|
|
1277
|
+
});
|
|
1278
|
+
const OrcaButtons = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-480c6090"]]);
|
|
1279
|
+
const _hoisted_1$7 = {
|
|
1280
|
+
key: 0,
|
|
1281
|
+
class: "orca-trace-container"
|
|
1282
|
+
};
|
|
1283
|
+
const _hoisted_2$4 = { class: "trace-header" };
|
|
1284
|
+
const _hoisted_3$2 = {
|
|
1285
|
+
key: 0,
|
|
1286
|
+
class: "trace-content"
|
|
1287
|
+
};
|
|
1288
|
+
const _hoisted_4$1 = { class: "trace-pre" };
|
|
1289
|
+
const _sfc_main$7 = /* @__PURE__ */ defineComponent({
|
|
1290
|
+
__name: "OrcaTracing",
|
|
1291
|
+
props: {
|
|
1292
|
+
tracingData: {},
|
|
1293
|
+
visibility: {},
|
|
1294
|
+
isAdmin: { type: Boolean }
|
|
1295
|
+
},
|
|
1296
|
+
setup(__props) {
|
|
1297
|
+
const props = __props;
|
|
1298
|
+
const traceVisible = ref(false);
|
|
1299
|
+
const isVisible = computed(() => traceVisible.value);
|
|
1300
|
+
const shouldShow = computed(() => {
|
|
1301
|
+
if (Array.isArray(props.tracingData)) {
|
|
1302
|
+
return props.tracingData.some(
|
|
1303
|
+
(item) => item.visibility === "all" || item.visibility === "admin" && props.isAdmin
|
|
1304
|
+
);
|
|
1305
|
+
}
|
|
1306
|
+
return props.tracingData.visibility === "all" || props.tracingData.visibility === "admin" && props.isAdmin;
|
|
1307
|
+
});
|
|
1308
|
+
const tracingContent = computed(() => {
|
|
1309
|
+
if (Array.isArray(props.tracingData)) {
|
|
1310
|
+
return props.tracingData.map((item) => item.content || item.rawContent).join("\n\n");
|
|
1311
|
+
}
|
|
1312
|
+
return props.tracingData.content || props.tracingData.rawContent || "";
|
|
1313
|
+
});
|
|
1314
|
+
const toggleTrace = () => {
|
|
1315
|
+
traceVisible.value = !traceVisible.value;
|
|
1316
|
+
};
|
|
1317
|
+
return (_ctx, _cache) => {
|
|
1318
|
+
return shouldShow.value ? (openBlock(), createElementBlock("div", _hoisted_1$7, [
|
|
1319
|
+
createVNode(unref(VCard), {
|
|
1320
|
+
class: "trace-card",
|
|
1321
|
+
elevation: "2"
|
|
1322
|
+
}, {
|
|
1323
|
+
default: withCtx(() => [
|
|
1324
|
+
createElementVNode("div", _hoisted_2$4, [
|
|
1325
|
+
_cache[0] || (_cache[0] = createElementVNode("div", { class: "trace-header-content" }, [
|
|
1326
|
+
createElementVNode("div", { class: "trace-icon" }, [
|
|
1327
|
+
createElementVNode("svg", {
|
|
1328
|
+
width: "20",
|
|
1329
|
+
height: "20",
|
|
1330
|
+
viewBox: "0 0 24 24",
|
|
1331
|
+
fill: "none",
|
|
1332
|
+
stroke: "currentColor",
|
|
1333
|
+
"stroke-width": "2"
|
|
1334
|
+
}, [
|
|
1335
|
+
createElementVNode("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })
|
|
1336
|
+
])
|
|
1337
|
+
]),
|
|
1338
|
+
createElementVNode("strong", { class: "trace-title" }, "Trace Log")
|
|
1339
|
+
], -1)),
|
|
1340
|
+
createVNode(unref(VBtn), {
|
|
1341
|
+
size: "small",
|
|
1342
|
+
variant: "tonal",
|
|
1343
|
+
color: "primary",
|
|
1344
|
+
class: "trace-toggle-btn",
|
|
1345
|
+
onClick: toggleTrace
|
|
1346
|
+
}, {
|
|
1347
|
+
default: withCtx(() => [
|
|
1348
|
+
createTextVNode(toDisplayString(isVisible.value ? "Hide" : "Show"), 1)
|
|
1349
|
+
]),
|
|
1350
|
+
_: 1
|
|
1351
|
+
})
|
|
1352
|
+
]),
|
|
1353
|
+
createVNode(unref(VExpandTransition), null, {
|
|
1354
|
+
default: withCtx(() => [
|
|
1355
|
+
isVisible.value ? (openBlock(), createElementBlock("div", _hoisted_3$2, [
|
|
1356
|
+
createElementVNode("pre", _hoisted_4$1, toDisplayString(tracingContent.value), 1)
|
|
1357
|
+
])) : createCommentVNode("", true)
|
|
1358
|
+
]),
|
|
1359
|
+
_: 1
|
|
1360
|
+
})
|
|
1361
|
+
]),
|
|
1362
|
+
_: 1
|
|
1363
|
+
})
|
|
1364
|
+
])) : createCommentVNode("", true);
|
|
1365
|
+
};
|
|
1366
|
+
}
|
|
1367
|
+
});
|
|
1368
|
+
const OrcaTracing = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-69e262d5"]]);
|
|
1369
|
+
const _hoisted_1$6 = ["innerHTML"];
|
|
1370
|
+
const _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
1371
|
+
__name: "ContentElement",
|
|
1372
|
+
props: {
|
|
1373
|
+
element: {},
|
|
1374
|
+
disabledButton: { type: Boolean },
|
|
1375
|
+
visibility: {},
|
|
1376
|
+
isAdmin: { type: Boolean },
|
|
1377
|
+
mapboxToken: {}
|
|
1378
|
+
},
|
|
1379
|
+
emits: ["image-modal", "button-click"],
|
|
1380
|
+
setup(__props, { emit: __emit }) {
|
|
1381
|
+
const emit = __emit;
|
|
1382
|
+
const { render: renderText } = useMarkdown();
|
|
1383
|
+
const handleImageModal = (url) => {
|
|
1384
|
+
emit("image-modal", url);
|
|
1385
|
+
};
|
|
1386
|
+
const handleButtonClick = (button) => {
|
|
1387
|
+
emit("button-click", button);
|
|
1388
|
+
};
|
|
1389
|
+
return (_ctx, _cache) => {
|
|
1390
|
+
return openBlock(), createElementBlock("div", null, [
|
|
1391
|
+
__props.element.type === "text" ? (openBlock(), createElementBlock("div", {
|
|
1392
|
+
key: 0,
|
|
1393
|
+
class: "text-content",
|
|
1394
|
+
innerHTML: unref(renderText)(__props.element.content)
|
|
1395
|
+
}, null, 8, _hoisted_1$6)) : __props.element.type === "image" ? (openBlock(), createBlock(OrcaImage, {
|
|
1396
|
+
key: 1,
|
|
1397
|
+
url: __props.element.content,
|
|
1398
|
+
onOpenModal: handleImageModal
|
|
1399
|
+
}, null, 8, ["url"])) : __props.element.type === "video" ? (openBlock(), createBlock(OrcaVideo, {
|
|
1400
|
+
key: 2,
|
|
1401
|
+
url: __props.element.content
|
|
1402
|
+
}, null, 8, ["url"])) : __props.element.type === "youtube" ? (openBlock(), createBlock(OrcaYouTube, {
|
|
1403
|
+
key: 3,
|
|
1404
|
+
url: __props.element.content
|
|
1405
|
+
}, null, 8, ["url"])) : __props.element.type === "audio" ? (openBlock(), createBlock(OrcaAudio, {
|
|
1406
|
+
key: 4,
|
|
1407
|
+
"audio-items": __props.element.content
|
|
1408
|
+
}, null, 8, ["audio-items"])) : __props.element.type === "location" ? (openBlock(), createBlock(OrcaLocation, {
|
|
1409
|
+
key: 5,
|
|
1410
|
+
latitude: __props.element.content.latitude,
|
|
1411
|
+
longitude: __props.element.content.longitude,
|
|
1412
|
+
"mapbox-token": __props.mapboxToken
|
|
1413
|
+
}, null, 8, ["latitude", "longitude", "mapbox-token"])) : __props.element.type === "card" ? (openBlock(), createBlock(OrcaCardList, {
|
|
1414
|
+
key: 6,
|
|
1415
|
+
cards: __props.element.content
|
|
1416
|
+
}, null, 8, ["cards"])) : __props.element.type === "buttons" ? (openBlock(), createBlock(OrcaButtons, {
|
|
1417
|
+
key: 7,
|
|
1418
|
+
buttons: __props.element.content,
|
|
1419
|
+
disabled: __props.disabledButton,
|
|
1420
|
+
onButtonClick: handleButtonClick
|
|
1421
|
+
}, null, 8, ["buttons", "disabled"])) : __props.element.type === "tracing" ? (openBlock(), createBlock(OrcaTracing, {
|
|
1422
|
+
key: 8,
|
|
1423
|
+
"tracing-data": __props.element.content,
|
|
1424
|
+
visibility: __props.visibility,
|
|
1425
|
+
"is-admin": __props.isAdmin
|
|
1426
|
+
}, null, 8, ["tracing-data", "visibility", "is-admin"])) : createCommentVNode("", true)
|
|
1427
|
+
]);
|
|
1428
|
+
};
|
|
1429
|
+
}
|
|
1430
|
+
});
|
|
1431
|
+
const _hoisted_1$5 = {
|
|
1432
|
+
key: 0,
|
|
1433
|
+
class: "general-loading-container"
|
|
1434
|
+
};
|
|
1435
|
+
const _hoisted_2$3 = { class: "loading-content" };
|
|
1436
|
+
const _hoisted_3$1 = { class: "loading-text" };
|
|
1437
|
+
const _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
1438
|
+
__name: "GeneralLoading",
|
|
1439
|
+
props: {
|
|
1440
|
+
isLoading: { type: Boolean },
|
|
1441
|
+
message: {}
|
|
1442
|
+
},
|
|
1443
|
+
setup(__props) {
|
|
1444
|
+
return (_ctx, _cache) => {
|
|
1445
|
+
return openBlock(), createBlock(Transition, {
|
|
1446
|
+
name: "fade",
|
|
1447
|
+
mode: "out-in"
|
|
1448
|
+
}, {
|
|
1449
|
+
default: withCtx(() => [
|
|
1450
|
+
__props.isLoading ? (openBlock(), createElementBlock("div", _hoisted_1$5, [
|
|
1451
|
+
createElementVNode("div", _hoisted_2$3, [
|
|
1452
|
+
createVNode(unref(VProgressCircular), {
|
|
1453
|
+
indeterminate: "",
|
|
1454
|
+
size: 24,
|
|
1455
|
+
width: 3,
|
|
1456
|
+
color: "primary",
|
|
1457
|
+
class: "loading-spinner"
|
|
1458
|
+
}),
|
|
1459
|
+
createElementVNode("span", _hoisted_3$1, toDisplayString(__props.message), 1)
|
|
1460
|
+
])
|
|
1461
|
+
])) : createCommentVNode("", true)
|
|
1462
|
+
]),
|
|
1463
|
+
_: 1
|
|
1464
|
+
});
|
|
1465
|
+
};
|
|
1466
|
+
}
|
|
1467
|
+
});
|
|
1468
|
+
const GeneralLoading = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-ba70521a"]]);
|
|
1469
|
+
const _hoisted_1$4 = {
|
|
1470
|
+
key: 0,
|
|
1471
|
+
class: "image-loading-placeholder"
|
|
1472
|
+
};
|
|
1473
|
+
const _hoisted_2$2 = { class: "loading-skeleton-image" };
|
|
1474
|
+
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
1475
|
+
__name: "ImageLoading",
|
|
1476
|
+
props: {
|
|
1477
|
+
isLoading: { type: Boolean }
|
|
1478
|
+
},
|
|
1479
|
+
setup(__props) {
|
|
1480
|
+
return (_ctx, _cache) => {
|
|
1481
|
+
return openBlock(), createBlock(Transition, {
|
|
1482
|
+
name: "fade",
|
|
1483
|
+
mode: "out-in"
|
|
1484
|
+
}, {
|
|
1485
|
+
default: withCtx(() => [
|
|
1486
|
+
__props.isLoading ? (openBlock(), createElementBlock("div", _hoisted_1$4, [
|
|
1487
|
+
createElementVNode("div", _hoisted_2$2, [
|
|
1488
|
+
createVNode(unref(VProgressCircular), {
|
|
1489
|
+
indeterminate: "",
|
|
1490
|
+
size: 48,
|
|
1491
|
+
width: 4,
|
|
1492
|
+
color: "primary",
|
|
1493
|
+
class: "loading-spinner-large"
|
|
1494
|
+
}),
|
|
1495
|
+
_cache[0] || (_cache[0] = createElementVNode("span", { class: "loading-skeleton-text" }, "🖼️ Loading image...", -1))
|
|
1496
|
+
])
|
|
1497
|
+
])) : createCommentVNode("", true)
|
|
1498
|
+
]),
|
|
1499
|
+
_: 1
|
|
1500
|
+
});
|
|
1501
|
+
};
|
|
1502
|
+
}
|
|
1503
|
+
});
|
|
1504
|
+
const ImageLoading = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-39a596d3"]]);
|
|
1505
|
+
const _hoisted_1$3 = {
|
|
1506
|
+
key: 0,
|
|
1507
|
+
class: "video-loading-placeholder"
|
|
1508
|
+
};
|
|
1509
|
+
const _hoisted_2$1 = { class: "loading-skeleton-video" };
|
|
1510
|
+
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
1511
|
+
__name: "VideoLoading",
|
|
1512
|
+
props: {
|
|
1513
|
+
isLoading: { type: Boolean }
|
|
1514
|
+
},
|
|
1515
|
+
setup(__props) {
|
|
1516
|
+
return (_ctx, _cache) => {
|
|
1517
|
+
return openBlock(), createBlock(Transition, {
|
|
1518
|
+
name: "fade",
|
|
1519
|
+
mode: "out-in"
|
|
1520
|
+
}, {
|
|
1521
|
+
default: withCtx(() => [
|
|
1522
|
+
__props.isLoading ? (openBlock(), createElementBlock("div", _hoisted_1$3, [
|
|
1523
|
+
createElementVNode("div", _hoisted_2$1, [
|
|
1524
|
+
createVNode(unref(VProgressCircular), {
|
|
1525
|
+
indeterminate: "",
|
|
1526
|
+
size: 48,
|
|
1527
|
+
width: 4,
|
|
1528
|
+
color: "primary",
|
|
1529
|
+
class: "loading-spinner-large"
|
|
1530
|
+
}),
|
|
1531
|
+
_cache[0] || (_cache[0] = createElementVNode("div", { class: "loading-skeleton-text" }, "🎥 Loading video...", -1))
|
|
1532
|
+
])
|
|
1533
|
+
])) : createCommentVNode("", true)
|
|
1534
|
+
]),
|
|
1535
|
+
_: 1
|
|
1536
|
+
});
|
|
1537
|
+
};
|
|
1538
|
+
}
|
|
1539
|
+
});
|
|
1540
|
+
const VideoLoading = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-0889a265"]]);
|
|
1541
|
+
const _hoisted_1$2 = {
|
|
1542
|
+
key: 0,
|
|
1543
|
+
class: "card-loading-placeholder"
|
|
1544
|
+
};
|
|
1545
|
+
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
1546
|
+
__name: "CardLoading",
|
|
1547
|
+
props: {
|
|
1548
|
+
isLoading: { type: Boolean }
|
|
1549
|
+
},
|
|
1550
|
+
setup(__props) {
|
|
1551
|
+
const VSkeletonLoader = components.VSkeletonLoader;
|
|
1552
|
+
return (_ctx, _cache) => {
|
|
1553
|
+
return openBlock(), createBlock(Transition, {
|
|
1554
|
+
name: "fade",
|
|
1555
|
+
mode: "out-in"
|
|
1556
|
+
}, {
|
|
1557
|
+
default: withCtx(() => [
|
|
1558
|
+
__props.isLoading ? (openBlock(), createElementBlock("div", _hoisted_1$2, [
|
|
1559
|
+
createVNode(unref(VSkeletonLoader), {
|
|
1560
|
+
class: "card-skeleton",
|
|
1561
|
+
width: "311",
|
|
1562
|
+
type: "image, article"
|
|
1563
|
+
}),
|
|
1564
|
+
_cache[0] || (_cache[0] = createElementVNode("span", { class: "loading-skeleton-text" }, "🃏 Loading cards...", -1))
|
|
1565
|
+
])) : createCommentVNode("", true)
|
|
1566
|
+
]),
|
|
1567
|
+
_: 1
|
|
1568
|
+
});
|
|
1569
|
+
};
|
|
1570
|
+
}
|
|
1571
|
+
});
|
|
1572
|
+
const CardLoading = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-2d326b15"]]);
|
|
1573
|
+
const _hoisted_1$1 = {
|
|
1574
|
+
key: 0,
|
|
1575
|
+
class: "map-loading-placeholder"
|
|
1576
|
+
};
|
|
1577
|
+
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
1578
|
+
__name: "MapLoading",
|
|
1579
|
+
props: {
|
|
1580
|
+
isLoading: { type: Boolean }
|
|
1581
|
+
},
|
|
1582
|
+
setup(__props) {
|
|
1583
|
+
const VSkeletonLoader = components.VSkeletonLoader;
|
|
1584
|
+
return (_ctx, _cache) => {
|
|
1585
|
+
return openBlock(), createBlock(Transition, {
|
|
1586
|
+
name: "fade",
|
|
1587
|
+
mode: "out-in"
|
|
1588
|
+
}, {
|
|
1589
|
+
default: withCtx(() => [
|
|
1590
|
+
__props.isLoading ? (openBlock(), createElementBlock("div", _hoisted_1$1, [
|
|
1591
|
+
createVNode(unref(VSkeletonLoader), {
|
|
1592
|
+
class: "map-skeleton",
|
|
1593
|
+
width: "500",
|
|
1594
|
+
height: "300",
|
|
1595
|
+
type: "image"
|
|
1596
|
+
}),
|
|
1597
|
+
_cache[0] || (_cache[0] = createElementVNode("span", { class: "loading-skeleton-text" }, "🗺️ Loading map...", -1))
|
|
1598
|
+
])) : createCommentVNode("", true)
|
|
1599
|
+
]),
|
|
1600
|
+
_: 1
|
|
1601
|
+
});
|
|
1602
|
+
};
|
|
1603
|
+
}
|
|
1604
|
+
});
|
|
1605
|
+
const MapLoading = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-4bb3095a"]]);
|
|
1606
|
+
const _hoisted_1 = { class: "message-content" };
|
|
1607
|
+
const _hoisted_2 = {
|
|
1608
|
+
key: 0,
|
|
1609
|
+
class: "tw-flex tw-flex-wrap tw-gap-4 tw-mt-4 tw-mb-4"
|
|
1610
|
+
};
|
|
1611
|
+
const _hoisted_3 = ["src", "onClick"];
|
|
1612
|
+
const _hoisted_4 = { class: "modal-content" };
|
|
1613
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
1614
|
+
__name: "OrcaMarkdown",
|
|
1615
|
+
props: {
|
|
1616
|
+
description: {},
|
|
1617
|
+
role: {},
|
|
1618
|
+
images: {},
|
|
1619
|
+
fileAttachments: { default: () => [] },
|
|
1620
|
+
isLastMessage: { type: Boolean, default: false },
|
|
1621
|
+
storeIdentifier: {},
|
|
1622
|
+
visibility: { default: "all" }
|
|
1623
|
+
},
|
|
1624
|
+
emits: ["send-message"],
|
|
1625
|
+
setup(__props, { emit: __emit }) {
|
|
1626
|
+
const props = __props;
|
|
1627
|
+
const emit = __emit;
|
|
1628
|
+
const messageContentRef = ref(null);
|
|
1629
|
+
const { modalVisible, currentImage, openModal, closeModal } = useImageModal();
|
|
1630
|
+
const contentParts = useContentParser(computed(() => props.description));
|
|
1631
|
+
const {
|
|
1632
|
+
isLoading,
|
|
1633
|
+
isImageLoading,
|
|
1634
|
+
isVideoLoading,
|
|
1635
|
+
isCardLoading,
|
|
1636
|
+
isLocationLoading,
|
|
1637
|
+
getLoadingMessage
|
|
1638
|
+
} = useLoadingStates(computed(() => props.description));
|
|
1639
|
+
const imageFiles = computed(() => {
|
|
1640
|
+
return props.fileAttachments.filter((file) => file && isImageFile(file));
|
|
1641
|
+
});
|
|
1642
|
+
const nonImageFiles = computed(() => {
|
|
1643
|
+
return props.fileAttachments.filter((file) => file && !isImageFile(file));
|
|
1644
|
+
});
|
|
1645
|
+
const disabledButton = computed(() => {
|
|
1646
|
+
return props.role !== "assistant" || !props.isLastMessage || isAdminPage();
|
|
1647
|
+
});
|
|
1648
|
+
const isAdminPage = () => {
|
|
1649
|
+
return props.visibility === "admin";
|
|
1650
|
+
};
|
|
1651
|
+
const getActiveLoadingType = computed(() => {
|
|
1652
|
+
const desc = props.description || "";
|
|
1653
|
+
if (desc.includes("[orca.loading.thinking.start]") && !desc.includes("[orca.loading.thinking.end]")) {
|
|
1654
|
+
return "thinking-loading";
|
|
1655
|
+
}
|
|
1656
|
+
if (desc.includes("[orca.loading.searching.start]") && !desc.includes("[orca.loading.searching.end]")) {
|
|
1657
|
+
return "searching-loading";
|
|
1658
|
+
}
|
|
1659
|
+
if (desc.includes("[orca.loading.coding.start]") && !desc.includes("[orca.loading.coding.end]")) {
|
|
1660
|
+
return "coding-loading";
|
|
1661
|
+
}
|
|
1662
|
+
if (desc.includes("[orca.loading.analyzing.start]") && !desc.includes("[orca.loading.analyzing.end]")) {
|
|
1663
|
+
return "analyzing-loading";
|
|
1664
|
+
}
|
|
1665
|
+
if (desc.includes("[orca.loading.generating.start]") && !desc.includes("[orca.loading.generating.end]")) {
|
|
1666
|
+
return "generating-loading";
|
|
1667
|
+
}
|
|
1668
|
+
if (desc.includes("[orca.loading.custom.start]") && !desc.includes("[orca.loading.custom.end]")) {
|
|
1669
|
+
return "custom-loading";
|
|
1670
|
+
}
|
|
1671
|
+
if (desc.includes("[orca.loading.start]") && !desc.includes("[orca.loading.end]")) {
|
|
1672
|
+
return "general-loading";
|
|
1673
|
+
}
|
|
1674
|
+
return null;
|
|
1675
|
+
});
|
|
1676
|
+
const getCurrentLoadingMessage = computed(() => {
|
|
1677
|
+
if (isLoading.value) {
|
|
1678
|
+
const activeType = getActiveLoadingType.value;
|
|
1679
|
+
if (activeType) {
|
|
1680
|
+
return getLoadingMessage(activeType);
|
|
1681
|
+
}
|
|
1682
|
+
return "⏳ Loading...";
|
|
1683
|
+
}
|
|
1684
|
+
return "⏳ Loading...";
|
|
1685
|
+
});
|
|
1686
|
+
const { addCodeButtons } = useCodeButtons(
|
|
1687
|
+
messageContentRef,
|
|
1688
|
+
() => props.role !== "user"
|
|
1689
|
+
);
|
|
1690
|
+
watch(contentParts, () => {
|
|
1691
|
+
addCodeButtons();
|
|
1692
|
+
});
|
|
1693
|
+
const handleButtonClick = async (button) => {
|
|
1694
|
+
if (button.type === "action" && !disabledButton.value) {
|
|
1695
|
+
try {
|
|
1696
|
+
emit("send-message", {
|
|
1697
|
+
message: button.label,
|
|
1698
|
+
buttonData: button,
|
|
1699
|
+
type: "button-action"
|
|
1700
|
+
});
|
|
1701
|
+
} catch (error) {
|
|
1702
|
+
console.error("Error emitting button click:", error);
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
};
|
|
1706
|
+
const handleImageModal = (url) => {
|
|
1707
|
+
openModal(url);
|
|
1708
|
+
};
|
|
1709
|
+
return (_ctx, _cache) => {
|
|
1710
|
+
return openBlock(), createElementBlock(Fragment, null, [
|
|
1711
|
+
createElementVNode("div", _hoisted_1, [
|
|
1712
|
+
createElementVNode("div", {
|
|
1713
|
+
ref_key: "messageContentRef",
|
|
1714
|
+
ref: messageContentRef,
|
|
1715
|
+
class: "content-wrapper"
|
|
1716
|
+
}, [
|
|
1717
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(unref(contentParts), (part, index) => {
|
|
1718
|
+
return openBlock(), createElementBlock(Fragment, { key: index }, [
|
|
1719
|
+
!unref(isLoadingType)(part.type) ? (openBlock(), createBlock(_sfc_main$6, {
|
|
1720
|
+
key: 0,
|
|
1721
|
+
element: part,
|
|
1722
|
+
"disabled-button": disabledButton.value,
|
|
1723
|
+
visibility: props.visibility,
|
|
1724
|
+
"is-admin": isAdminPage(),
|
|
1725
|
+
onImageModal: handleImageModal,
|
|
1726
|
+
onButtonClick: handleButtonClick
|
|
1727
|
+
}, null, 8, ["element", "disabled-button", "visibility", "is-admin"])) : createCommentVNode("", true)
|
|
1728
|
+
], 64);
|
|
1729
|
+
}), 128)),
|
|
1730
|
+
createVNode(GeneralLoading, {
|
|
1731
|
+
isLoading: unref(isLoading),
|
|
1732
|
+
message: getCurrentLoadingMessage.value
|
|
1733
|
+
}, null, 8, ["isLoading", "message"]),
|
|
1734
|
+
createVNode(ImageLoading, { isLoading: unref(isImageLoading) }, null, 8, ["isLoading"]),
|
|
1735
|
+
createVNode(VideoLoading, { isLoading: unref(isVideoLoading) }, null, 8, ["isLoading"]),
|
|
1736
|
+
createVNode(CardLoading, { isLoading: unref(isCardLoading) }, null, 8, ["isLoading"]),
|
|
1737
|
+
createVNode(MapLoading, { isLoading: unref(isLocationLoading) }, null, 8, ["isLoading"]),
|
|
1738
|
+
props.fileAttachments && props.fileAttachments.length > 0 && props.role === "user" ? (openBlock(), createElementBlock("div", _hoisted_2, [
|
|
1739
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(imageFiles.value, (file) => {
|
|
1740
|
+
return openBlock(), createElementBlock("img", {
|
|
1741
|
+
key: file,
|
|
1742
|
+
src: file,
|
|
1743
|
+
class: "tw-w-[300px] lg:tw-w-[303px] tw-h-[300px] lg:tw-h-[303px] tw-object-cover tw-rounded-lg tw-cursor-pointer",
|
|
1744
|
+
onClick: ($event) => unref(openModal)(file)
|
|
1745
|
+
}, null, 8, _hoisted_3);
|
|
1746
|
+
}), 128)),
|
|
1747
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(nonImageFiles.value, (file) => {
|
|
1748
|
+
return openBlock(), createBlock(unref(VBtn), {
|
|
1749
|
+
key: file,
|
|
1750
|
+
class: "text-center text-sm",
|
|
1751
|
+
variant: "tonal",
|
|
1752
|
+
color: "grey-500",
|
|
1753
|
+
href: file,
|
|
1754
|
+
target: "_blank",
|
|
1755
|
+
rel: "noopener noreferrer"
|
|
1756
|
+
}, {
|
|
1757
|
+
default: withCtx(() => [
|
|
1758
|
+
createTextVNode(toDisplayString(unref(getFileNameFromUrl)(file)), 1)
|
|
1759
|
+
]),
|
|
1760
|
+
_: 2
|
|
1761
|
+
}, 1032, ["href"]);
|
|
1762
|
+
}), 128))
|
|
1763
|
+
])) : createCommentVNode("", true)
|
|
1764
|
+
], 512)
|
|
1765
|
+
]),
|
|
1766
|
+
createVNode(unref(VDialog), {
|
|
1767
|
+
modelValue: unref(modalVisible),
|
|
1768
|
+
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => isRef(modalVisible) ? modalVisible.value = $event : null),
|
|
1769
|
+
fullscreen: "",
|
|
1770
|
+
class: "image-modal",
|
|
1771
|
+
scrim: "rgba(0, 0, 0, 0.85)",
|
|
1772
|
+
onClick: unref(closeModal),
|
|
1773
|
+
transition: "fade-transition"
|
|
1774
|
+
}, {
|
|
1775
|
+
default: withCtx(() => [
|
|
1776
|
+
createElementVNode("div", {
|
|
1777
|
+
class: "modal-close-btn",
|
|
1778
|
+
onClick: _cache[0] || (_cache[0] = withModifiers(
|
|
1779
|
+
//@ts-ignore
|
|
1780
|
+
(...args) => unref(closeModal) && unref(closeModal)(...args),
|
|
1781
|
+
["stop"]
|
|
1782
|
+
))
|
|
1783
|
+
}, [..._cache[2] || (_cache[2] = [
|
|
1784
|
+
createElementVNode("button", {
|
|
1785
|
+
class: "close-button",
|
|
1786
|
+
"aria-label": "Close image"
|
|
1787
|
+
}, [
|
|
1788
|
+
createElementVNode("svg", {
|
|
1789
|
+
width: "24",
|
|
1790
|
+
height: "24",
|
|
1791
|
+
viewBox: "0 0 24 24",
|
|
1792
|
+
fill: "none",
|
|
1793
|
+
stroke: "currentColor",
|
|
1794
|
+
"stroke-width": "2.5",
|
|
1795
|
+
"stroke-linecap": "round",
|
|
1796
|
+
"stroke-linejoin": "round"
|
|
1797
|
+
}, [
|
|
1798
|
+
createElementVNode("line", {
|
|
1799
|
+
x1: "18",
|
|
1800
|
+
y1: "6",
|
|
1801
|
+
x2: "6",
|
|
1802
|
+
y2: "18"
|
|
1803
|
+
}),
|
|
1804
|
+
createElementVNode("line", {
|
|
1805
|
+
x1: "6",
|
|
1806
|
+
y1: "6",
|
|
1807
|
+
x2: "18",
|
|
1808
|
+
y2: "18"
|
|
1809
|
+
})
|
|
1810
|
+
])
|
|
1811
|
+
], -1)
|
|
1812
|
+
])]),
|
|
1813
|
+
createElementVNode("div", _hoisted_4, [
|
|
1814
|
+
createVNode(unref(VImg), {
|
|
1815
|
+
src: unref(currentImage),
|
|
1816
|
+
class: "modal-image",
|
|
1817
|
+
contain: ""
|
|
1818
|
+
}, null, 8, ["src"])
|
|
1819
|
+
])
|
|
1820
|
+
]),
|
|
1821
|
+
_: 1
|
|
1822
|
+
}, 8, ["modelValue", "onClick"])
|
|
1823
|
+
], 64);
|
|
1824
|
+
};
|
|
1825
|
+
}
|
|
1826
|
+
});
|
|
1827
|
+
const OrcaMarkdown = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-619a1855"]]);
|
|
1828
|
+
const version = "1.0.1";
|
|
1829
|
+
const packageInfo = {
|
|
1830
|
+
name: "@orca-pt/orca-components",
|
|
1831
|
+
version: "1.0.1",
|
|
1832
|
+
description: "Orca native components for rendering special content markers",
|
|
1833
|
+
author: "Orca Team"
|
|
1834
|
+
};
|
|
1835
|
+
export {
|
|
1836
|
+
OrcaMarkdown,
|
|
1837
|
+
cleanOrcaMarkers,
|
|
1838
|
+
generateMapId,
|
|
1839
|
+
getAppendIconStyle,
|
|
1840
|
+
getFileNameFromUrl,
|
|
1841
|
+
getGroupedButtons,
|
|
1842
|
+
getOutlinedButtonStyle,
|
|
1843
|
+
getOutlinedButtonTextStyle,
|
|
1844
|
+
getVuetifyColor,
|
|
1845
|
+
getYouTubeId,
|
|
1846
|
+
hasLoadingMarkers,
|
|
1847
|
+
isImageFile,
|
|
1848
|
+
packageInfo,
|
|
1849
|
+
version
|
|
1850
|
+
};
|
|
1851
|
+
//# sourceMappingURL=orca-components.es.js.map
|