@frontera-sdk/chat-ui 1.50.40
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 +202 -0
- package/README.md +348 -0
- package/dist/af-DK_CjRn6-OPBHDTNZ.js +197 -0
- package/dist/agent-picker.d.ts +38 -0
- package/dist/agent-picker.js +8 -0
- package/dist/as-BPtSu6VN-O4ZZEAJG.js +11 -0
- package/dist/be-CrQ0smca-5HIE5K27.js +11 -0
- package/dist/bg-CrQqGwni-3IRVPZQ7.js +11 -0
- package/dist/bn-NCLZcWHi-XOZJFNIB.js +11 -0
- package/dist/ca-SUf6Y2Om-V6F2EBCA.js +38 -0
- package/dist/capture-NO5ZIGP6.js +1652 -0
- package/dist/chat.css +3555 -0
- package/dist/chat.d.ts +161 -0
- package/dist/chat.js +60498 -0
- package/dist/chunk-2KEBRV3W.js +191 -0
- package/dist/chunk-6BPHEBCF.js +639 -0
- package/dist/chunk-6HYPVNVA.js +25 -0
- package/dist/chunk-7ADM3CKD.js +10 -0
- package/dist/chunk-AFVU5VT6.js +5601 -0
- package/dist/chunk-BEJ3HQG4.js +93 -0
- package/dist/chunk-CCVPZVFK.js +28 -0
- package/dist/chunk-DGDHKMDB.js +10 -0
- package/dist/chunk-FXKXDR5K.js +2166 -0
- package/dist/chunk-GTQH7MPF.js +129 -0
- package/dist/chunk-I7SXWUAN.js +1258 -0
- package/dist/chunk-IQRPGFLI.js +234 -0
- package/dist/chunk-IXDM5R55.js +23 -0
- package/dist/chunk-JD6ETTXC.js +178 -0
- package/dist/chunk-OP4MLJDA.js +215 -0
- package/dist/chunk-PQZ2CS26.js +2315 -0
- package/dist/chunk-PR4QN5HX.js +38 -0
- package/dist/chunk-PUIVKDV5.js +271 -0
- package/dist/chunk-QSSFBZAS.js +6914 -0
- package/dist/chunk-RAKKA3WU.js +5896 -0
- package/dist/chunk-RB2Y4NYC.js +681 -0
- package/dist/chunk-VDZH5Z3K.js +72 -0
- package/dist/chunk-WMN6BPPS.js +49 -0
- package/dist/chunk-WO6DJLFE.js +10857 -0
- package/dist/chunk-X5E2DJVO.js +47634 -0
- package/dist/chunk-XJFTVKLW.js +2687 -0
- package/dist/chunk-ZS6PXIZP.js +187 -0
- package/dist/client.d.ts +89 -0
- package/dist/client.js +20 -0
- package/dist/composer.d.ts +23 -0
- package/dist/composer.js +89 -0
- package/dist/cop-C3sk0IUo-CIZA2H43.js +11 -0
- package/dist/credential.d.ts +75 -0
- package/dist/credential.js +3 -0
- package/dist/cs-CmAteokq-HAKEQPB4.js +17 -0
- package/dist/cu-CBUlrW6Y-QTZ6ZLA4.js +32 -0
- package/dist/cy-BBPa6z2x-MX6DGDNW.js +11 -0
- package/dist/da-CCDXfXtG-5YEOHMG3.js +11 -0
- package/dist/de-1901-CWoAOigE-63QFSF2A.js +11 -0
- package/dist/de-1996-BL6awyxG-R2PHKMAB.js +11 -0
- package/dist/de-ch-1901-hVThVHVb-JSDB53OZ.js +11 -0
- package/dist/el-monoton-D3aKqTz2-2V4OOFBB.js +11 -0
- package/dist/el-polyton-ogVWcTzh-3U7NGQMT.js +11 -0
- package/dist/en-gb-B7Al27b_-UKCBQFSU.js +21 -0
- package/dist/es-DcaaHPU_-NOBXSOZK.js +11 -0
- package/dist/esm-MHF25KDL.js +3 -0
- package/dist/et-B_spaleu-5UAYIW62.js +11 -0
- package/dist/eu-Ctv_kq9Z-V5DREOPN.js +11 -0
- package/dist/fi-RW5VB8Yp-YSXBK7LW.js +11 -0
- package/dist/fr-BC2onEz9-7KH5T76G.js +11 -0
- package/dist/frame.d.ts +59 -0
- package/dist/frame.js +111 -0
- package/dist/fur-AC12wySk-4PD2Y72H.js +11 -0
- package/dist/ga-Cn6LkudM-RRAAJT3N.js +58 -0
- package/dist/gl-DZGc-K_G-KYSXXTCY.js +11 -0
- package/dist/grc-DOlGgO8T-2HXBZVJ5.js +11 -0
- package/dist/gu-Bjl0l-cf-4CFSVZHZ.js +11 -0
- package/dist/header.d.ts +78 -0
- package/dist/header.js +18 -0
- package/dist/hi-DsAaTPCC-KMCFBWK7.js +11 -0
- package/dist/hr-DT1SBBes-X2TIX6EI.js +11 -0
- package/dist/hsb-DC_ITc1e-PXLERA7R.js +46 -0
- package/dist/hu-DVk7Y_ka-PJPVU54B.js +11 -0
- package/dist/hy-e995ysyO-MZBRFX52.js +11 -0
- package/dist/ia-Cr4TJH0c-D3O2FHGP.js +22 -0
- package/dist/id-DifDyWg9-MZ2BGHWI.js +58 -0
- package/dist/is-BT8UVRze-CZZCKEFI.js +11 -0
- package/dist/it-Bt_Meacx-T4Y5JYV6.js +11 -0
- package/dist/ka-jyoLzyDE-ES6EXZLW.js +11 -0
- package/dist/kmr-Cfwhwuff-TSW2R2KS.js +11 -0
- package/dist/kn-C6Lov-DP-B4BL47CE.js +11 -0
- package/dist/la-DuvHjUWw-6K7TFU6X.js +11 -0
- package/dist/la-x-classic-yTyAOQEt-YWTKMM2L.js +11 -0
- package/dist/la-x-liturgic-CXeQb4FY-B772L5E7.js +11 -0
- package/dist/lib-3ZKX25RJ.js +4511 -0
- package/dist/lt-BBe8DlDF-4YINVOZR.js +11 -0
- package/dist/lv-Q2BBHnzp-TMVQ3MX2.js +11 -0
- package/dist/message.d.ts +64 -0
- package/dist/message.js +18 -0
- package/dist/ml-2xLVYkVY-NGZLAPIN.js +11 -0
- package/dist/mn-cyrl-lHM4n0oC-DGBYYUT3.js +11 -0
- package/dist/mn-cyrl-x-lmc-3aetruI8-QHJABMOO.js +11 -0
- package/dist/mr-CjWJPVmH-X5UHV65O.js +11 -0
- package/dist/mul-ethi-D_CMSMEq-H7UMQSOQ.js +11 -0
- package/dist/nb-DI8u59ch-J4CAVI4Y.js +122 -0
- package/dist/new-session-Dw7JOgzu.d.ts +141 -0
- package/dist/new-session.d.ts +4 -0
- package/dist/new-session.js +10 -0
- package/dist/nl-BHQJ6Gvn-7BH55RA7.js +52 -0
- package/dist/nn-ntZvarUK-KKNCHHJ4.js +122 -0
- package/dist/no-B8ItS0F3-3ZXIRJ6U.js +120 -0
- package/dist/oauth-callback.d.ts +35 -0
- package/dist/oauth-callback.js +18 -0
- package/dist/oc-P_i3-xLA-XZM6E5YZ.js +11 -0
- package/dist/or-50rxpoq4-5VELAFMJ.js +11 -0
- package/dist/pa-C54UG8eN-WEJPMZ6Z.js +11 -0
- package/dist/parts.d.ts +49 -0
- package/dist/parts.js +106 -0
- package/dist/pdf-cover-thumbnail-inner-4N2Q5AAG.js +36 -0
- package/dist/pdf-deck-view-inner-FZVLAEQR.js +575 -0
- package/dist/pdf-document-view-inner-6DF54JWK.js +585 -0
- package/dist/pdf-viewer-inner-GPES3KG2.js +256 -0
- package/dist/pending-cards.d.ts +26 -0
- package/dist/pending-cards.js +9 -0
- package/dist/pi-B9cgjyG1-GD5ASDDU.js +11 -0
- package/dist/pl-9fg-ESVt-UMX7MCJM.js +32 -0
- package/dist/platform.css +4013 -0
- package/dist/pms-BRGfm5gS-SSE3AUW5.js +11 -0
- package/dist/pt-Cum2_NUC-W35JYVR4.js +11 -0
- package/dist/rm-C0MIK9N4-IWL4YTNT.js +11 -0
- package/dist/ro-0fmdH0HA-46WUTOYH.js +11 -0
- package/dist/ru-v4l-ayaq-BUGK6XCN.js +196 -0
- package/dist/sa-CKY9c_Vq-4KIJOI5Y.js +11 -0
- package/dist/sh-cyrl-BpCRFOmq-DSLQ4UY2.js +128 -0
- package/dist/sh-latn-sRy4Tuaj-UNQOR63V.js +128 -0
- package/dist/sk-_iOeDNrQ-NCTQKH25.js +17 -0
- package/dist/sl-DpiklF-D-6GG5TDVN.js +11 -0
- package/dist/sr-cyrl-Dpzrbd0W-4Q5226YJ.js +142 -0
- package/dist/sv-CFm5y56M-VTWNPZ7I.js +11 -0
- package/dist/ta-BcghgTbD-NRT35DW6.js +11 -0
- package/dist/te-B5Spl2Jk-5VE6CLN4.js +11 -0
- package/dist/th-DWX5iPSo-N5GMOQOP.js +11 -0
- package/dist/theme.d.ts +49 -0
- package/dist/theme.js +3 -0
- package/dist/tk-BMbKB10q-HGWWY5L3.js +11 -0
- package/dist/tr-CIHIuzqc-6ISBNYLV.js +11 -0
- package/dist/types-BDqLaBfH.d.ts +60 -0
- package/dist/uk-Dir3oxLs-YQ3QZRI4.js +11 -0
- package/dist/univer-workbook-BSSUE5TG.css +3555 -0
- package/dist/univer-workbook-N5IIN7CH.js +290849 -0
- package/dist/vega-chart-block-NQADYNWQ.js +2857 -0
- package/dist/zh-latn-pinyin-BdYb-Ey_-RB542AHF.js +11 -0
- package/package.json +137 -0
- package/src/styles.css +996 -0
|
@@ -0,0 +1,2687 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { Button, Skeleton, ScrollArea } from './chunk-GTQH7MPF.js';
|
|
3
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from './chunk-IQRPGFLI.js';
|
|
4
|
+
import { cn } from './chunk-DGDHKMDB.js';
|
|
5
|
+
import { SquareArrowTopRightIcon, Checkmark1Icon, ClipboardIcon, Book3Icon, ChevronDownMediumIcon, ApiAppIcon, TextToImageIcon, Robot4Icon, DeviceDesktopIcon, PhotoIcon, Code2Icon, Terminal2Icon, Folder1Icon, PencilIcon, FileTextIcon, WritingIcon, WorldSearchIcon, icons_exports } from './chunk-AFVU5VT6.js';
|
|
6
|
+
import '@radix-ui/react-slot';
|
|
7
|
+
import { cva } from 'class-variance-authority';
|
|
8
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
9
|
+
import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
|
|
10
|
+
import * as HoverCardPrimitive from '@radix-ui/react-hover-card';
|
|
11
|
+
import React, { useMemo, memo, forwardRef, useState, useEffect, createElement, useRef, useCallback } from 'react';
|
|
12
|
+
import { Streamdown } from 'streamdown';
|
|
13
|
+
import { motion } from 'motion/react';
|
|
14
|
+
import { cjk } from '@streamdown/cjk';
|
|
15
|
+
import { createMathPlugin } from '@streamdown/math';
|
|
16
|
+
import { visit } from 'unist-util-visit';
|
|
17
|
+
import { visitParents } from 'unist-util-visit-parents';
|
|
18
|
+
|
|
19
|
+
cva(
|
|
20
|
+
"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
|
|
21
|
+
{
|
|
22
|
+
variants: {
|
|
23
|
+
variant: {
|
|
24
|
+
default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
|
25
|
+
secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
|
|
26
|
+
destructive: "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
|
27
|
+
outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
defaultVariants: {
|
|
31
|
+
variant: "default"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
var Collapsible = CollapsiblePrimitive.Root;
|
|
36
|
+
var CollapsibleTrigger2 = CollapsiblePrimitive.CollapsibleTrigger;
|
|
37
|
+
var CollapsibleContent2 = CollapsiblePrimitive.CollapsibleContent;
|
|
38
|
+
var HoverCard = HoverCardPrimitive.Root;
|
|
39
|
+
var HoverCardTrigger = HoverCardPrimitive.Trigger;
|
|
40
|
+
function HoverCardContent({
|
|
41
|
+
className,
|
|
42
|
+
align = "center",
|
|
43
|
+
sideOffset = 4,
|
|
44
|
+
...props
|
|
45
|
+
}) {
|
|
46
|
+
return (
|
|
47
|
+
// Portalled like every other popup primitive here. Rendered inline it is
|
|
48
|
+
// clipped by any scrolling or `overflow-hidden` ancestor — a citation
|
|
49
|
+
// hover card inside a message card was cut off at the card's edge — and
|
|
50
|
+
// its z-100 is trapped in whatever stacking context that ancestor makes.
|
|
51
|
+
/* @__PURE__ */ jsx(HoverCardPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
52
|
+
HoverCardPrimitive.Content,
|
|
53
|
+
{
|
|
54
|
+
align,
|
|
55
|
+
sideOffset,
|
|
56
|
+
className: cn(
|
|
57
|
+
// Fade only, 100ms, ease-out. The old 150ms stacked a fade with a
|
|
58
|
+
// zoom-95 and a 2px slide, on `ease` — which starts slow, so the
|
|
59
|
+
// frames that confirm the click were the slowest, and the movement
|
|
60
|
+
// made a menu read as ARRIVING rather than already being there.
|
|
61
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 duration-100 ease-out z-100 w-64 rounded-md border bg-surface-overlay p-4 text-popover-foreground shadow-md outline-none",
|
|
62
|
+
className
|
|
63
|
+
),
|
|
64
|
+
...props
|
|
65
|
+
}
|
|
66
|
+
) })
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
function componentName(icon) {
|
|
70
|
+
const joined = icon.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
71
|
+
return /^[0-9]/.test(joined) ? `Icon_${joined}Icon` : `${joined}Icon`;
|
|
72
|
+
}
|
|
73
|
+
function normalizeFronteraIconName(value) {
|
|
74
|
+
return (value ?? "").trim().replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
|
|
75
|
+
}
|
|
76
|
+
function resolveFronteraIcon(name) {
|
|
77
|
+
const key = componentName(normalizeFronteraIconName(name));
|
|
78
|
+
const icons = icons_exports;
|
|
79
|
+
return icons[key] ?? null;
|
|
80
|
+
}
|
|
81
|
+
function FronteraIcon({ icon, ...props }) {
|
|
82
|
+
const Icon3 = resolveFronteraIcon(icon);
|
|
83
|
+
if (!Icon3) {
|
|
84
|
+
return /* @__PURE__ */ jsx("span", { "aria-hidden": true, style: { display: "inline-block", width: "1em", height: "1em" } });
|
|
85
|
+
}
|
|
86
|
+
return /* @__PURE__ */ jsx(Icon3, { ...props });
|
|
87
|
+
}
|
|
88
|
+
var frontera_icon_default = FronteraIcon;
|
|
89
|
+
var Shimmer = React.memo(({
|
|
90
|
+
children,
|
|
91
|
+
as: Component = "p",
|
|
92
|
+
className,
|
|
93
|
+
duration = 1.5,
|
|
94
|
+
spread = 2,
|
|
95
|
+
delay = 0,
|
|
96
|
+
repeatDelay = 0.5
|
|
97
|
+
}) => {
|
|
98
|
+
const MotionComponent = useMemo(
|
|
99
|
+
() => motion.create(Component),
|
|
100
|
+
[Component]
|
|
101
|
+
);
|
|
102
|
+
const dynamicSpread = useMemo(() => {
|
|
103
|
+
return children.length * spread;
|
|
104
|
+
}, [children, spread]);
|
|
105
|
+
return /* @__PURE__ */ jsx(
|
|
106
|
+
MotionComponent,
|
|
107
|
+
{
|
|
108
|
+
className: cn(
|
|
109
|
+
"relative inline-block bg-size-[250%_100%,auto] bg-clip-text",
|
|
110
|
+
"text-transparent [--base-color:var(--color-muted-foreground)] [--base-gradient-color:var(--color-foreground)]",
|
|
111
|
+
"[background-repeat:no-repeat,padding-box] [--bg:linear-gradient(90deg,#0000_calc(50%-var(--spread)),var(--base-gradient-color),#0000_calc(50%+var(--spread)))]",
|
|
112
|
+
"dark:[--base-color:var(--color-muted-foreground)] dark:[--base-gradient-color:var(--color-foreground)] dark:[--bg:linear-gradient(90deg,#0000_calc(50%-var(--spread)),var(--base-gradient-color),#0000_calc(50%+var(--spread)))]",
|
|
113
|
+
className
|
|
114
|
+
),
|
|
115
|
+
initial: { backgroundPosition: "105% center" },
|
|
116
|
+
animate: { backgroundPosition: "-5% center" },
|
|
117
|
+
transition: {
|
|
118
|
+
repeat: Number.POSITIVE_INFINITY,
|
|
119
|
+
duration,
|
|
120
|
+
ease: "linear",
|
|
121
|
+
delay,
|
|
122
|
+
repeatDelay
|
|
123
|
+
},
|
|
124
|
+
style: {
|
|
125
|
+
"--spread": `${dynamicSpread}px`,
|
|
126
|
+
backgroundImage: `var(--bg), linear-gradient(var(--base-color), var(--base-color))`
|
|
127
|
+
},
|
|
128
|
+
children
|
|
129
|
+
}
|
|
130
|
+
);
|
|
131
|
+
});
|
|
132
|
+
function Collapse({
|
|
133
|
+
open,
|
|
134
|
+
children,
|
|
135
|
+
className
|
|
136
|
+
}) {
|
|
137
|
+
return /* @__PURE__ */ jsx(
|
|
138
|
+
"div",
|
|
139
|
+
{
|
|
140
|
+
"data-state": open ? "open" : "closed",
|
|
141
|
+
className: cn(
|
|
142
|
+
"grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none",
|
|
143
|
+
open ? "grid-rows-[1fr]" : "grid-rows-[0fr]",
|
|
144
|
+
className
|
|
145
|
+
),
|
|
146
|
+
children: /* @__PURE__ */ jsx("div", { className: "min-h-0 overflow-hidden", children })
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// src/vendor/ui/hooks/layout-motion.ts
|
|
152
|
+
var LAYOUT_MOTION_ATTR = "data-layout-motion";
|
|
153
|
+
var LAYOUT_MOTION_END_EVENT = "sebati:layout-motion-end";
|
|
154
|
+
function isLayoutMoving(node) {
|
|
155
|
+
return !!node?.closest(`[${LAYOUT_MOTION_ATTR}]`);
|
|
156
|
+
}
|
|
157
|
+
function deferDuringLayoutMotion(getNode, measure) {
|
|
158
|
+
let missed = false;
|
|
159
|
+
const onEnd = () => {
|
|
160
|
+
if (!missed) return;
|
|
161
|
+
missed = false;
|
|
162
|
+
measure();
|
|
163
|
+
};
|
|
164
|
+
window.addEventListener(LAYOUT_MOTION_END_EVENT, onEnd);
|
|
165
|
+
return {
|
|
166
|
+
measure: () => {
|
|
167
|
+
if (isLayoutMoving(getNode())) {
|
|
168
|
+
missed = true;
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
measure();
|
|
172
|
+
},
|
|
173
|
+
dispose: () => window.removeEventListener(LAYOUT_MOTION_END_EVENT, onEnd)
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function measureScrollFade(el) {
|
|
177
|
+
const { scrollTop, scrollHeight, clientHeight } = el;
|
|
178
|
+
const maxScroll = scrollHeight - clientHeight;
|
|
179
|
+
if (maxScroll <= 1) return { top: false, bottom: false };
|
|
180
|
+
return {
|
|
181
|
+
top: scrollTop > 1,
|
|
182
|
+
bottom: scrollTop < maxScroll - 1
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function nextFade(prev, el) {
|
|
186
|
+
const next = measureScrollFade(el);
|
|
187
|
+
return next.top === prev.top && next.bottom === prev.bottom ? prev : next;
|
|
188
|
+
}
|
|
189
|
+
function ScrollFadeEdges({
|
|
190
|
+
children,
|
|
191
|
+
className,
|
|
192
|
+
fadeFromClassName = "from-surface-raised"
|
|
193
|
+
}) {
|
|
194
|
+
const observerRef = useRef(null);
|
|
195
|
+
const gateRef = useRef(null);
|
|
196
|
+
const [fade, setFade] = useState({
|
|
197
|
+
top: false,
|
|
198
|
+
bottom: false
|
|
199
|
+
});
|
|
200
|
+
const setViewportRef = useCallback((el) => {
|
|
201
|
+
observerRef.current?.disconnect();
|
|
202
|
+
observerRef.current = null;
|
|
203
|
+
gateRef.current?.dispose();
|
|
204
|
+
gateRef.current = null;
|
|
205
|
+
if (!el) return;
|
|
206
|
+
const measure = () => setFade((prev) => nextFade(prev, el));
|
|
207
|
+
measure();
|
|
208
|
+
const gate = deferDuringLayoutMotion(() => el, measure);
|
|
209
|
+
gateRef.current = gate;
|
|
210
|
+
const ro = new ResizeObserver(gate.measure);
|
|
211
|
+
ro.observe(el);
|
|
212
|
+
for (const child of el.children) {
|
|
213
|
+
ro.observe(child);
|
|
214
|
+
}
|
|
215
|
+
observerRef.current = ro;
|
|
216
|
+
}, []);
|
|
217
|
+
useEffect(
|
|
218
|
+
() => () => {
|
|
219
|
+
observerRef.current?.disconnect();
|
|
220
|
+
gateRef.current?.dispose();
|
|
221
|
+
},
|
|
222
|
+
[]
|
|
223
|
+
);
|
|
224
|
+
const onScroll = useCallback((event) => {
|
|
225
|
+
const el = event.currentTarget;
|
|
226
|
+
setFade((prev) => nextFade(prev, el));
|
|
227
|
+
}, []);
|
|
228
|
+
const fadeBase = cn(
|
|
229
|
+
"pointer-events-none absolute inset-x-0 z-10 h-10",
|
|
230
|
+
fadeFromClassName
|
|
231
|
+
);
|
|
232
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
233
|
+
fade.top ? /* @__PURE__ */ jsx(
|
|
234
|
+
"div",
|
|
235
|
+
{
|
|
236
|
+
"aria-hidden": true,
|
|
237
|
+
className: cn(fadeBase, "top-0 bg-linear-to-b to-transparent")
|
|
238
|
+
}
|
|
239
|
+
) : null,
|
|
240
|
+
/* @__PURE__ */ jsx(
|
|
241
|
+
ScrollArea,
|
|
242
|
+
{
|
|
243
|
+
className: "w-full",
|
|
244
|
+
viewportRef: setViewportRef,
|
|
245
|
+
viewportProps: {
|
|
246
|
+
onScroll,
|
|
247
|
+
// Override primitive `size-full` — h-full expands with content and
|
|
248
|
+
// prevents max-h from creating a scroll region.
|
|
249
|
+
className: cn("!h-auto w-full", className)
|
|
250
|
+
},
|
|
251
|
+
children
|
|
252
|
+
}
|
|
253
|
+
),
|
|
254
|
+
fade.bottom ? /* @__PURE__ */ jsx(
|
|
255
|
+
"div",
|
|
256
|
+
{
|
|
257
|
+
"aria-hidden": true,
|
|
258
|
+
className: cn(fadeBase, "bottom-0 bg-linear-to-t to-transparent")
|
|
259
|
+
}
|
|
260
|
+
) : null
|
|
261
|
+
] });
|
|
262
|
+
}
|
|
263
|
+
var math = createMathPlugin({ singleDollarTextMath: true });
|
|
264
|
+
var BASE_PLUGINS = { math, cjk };
|
|
265
|
+
var codePluginPromise = null;
|
|
266
|
+
function loadCodePlugin() {
|
|
267
|
+
codePluginPromise ??= import('@streamdown/code').then((m) => m.code);
|
|
268
|
+
return codePluginPromise;
|
|
269
|
+
}
|
|
270
|
+
function useStreamdownPlugins() {
|
|
271
|
+
const [code, setCode] = useState(null);
|
|
272
|
+
useEffect(() => {
|
|
273
|
+
void loadCodePlugin().then(setCode);
|
|
274
|
+
}, []);
|
|
275
|
+
return useMemo(
|
|
276
|
+
() => code ? { code, math, cjk } : BASE_PLUGINS,
|
|
277
|
+
[code]
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
function rehypeUnwrapLiSoloP() {
|
|
281
|
+
return (tree) => {
|
|
282
|
+
visit(tree, "element", (li) => {
|
|
283
|
+
if (li.tagName !== "li") return;
|
|
284
|
+
let p = null;
|
|
285
|
+
let pIndex = -1;
|
|
286
|
+
for (let i = 0; i < li.children.length; i++) {
|
|
287
|
+
const c = li.children[i];
|
|
288
|
+
if (!c || c.type !== "element" || c.tagName !== "p") continue;
|
|
289
|
+
if (p) return;
|
|
290
|
+
p = c;
|
|
291
|
+
pIndex = i;
|
|
292
|
+
}
|
|
293
|
+
if (!p || pIndex < 0) return;
|
|
294
|
+
li.children.splice(pIndex, 1, ...p.children);
|
|
295
|
+
});
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
function rehypeWrapParagraphTextNodes() {
|
|
299
|
+
return (tree) => {
|
|
300
|
+
visitParents(tree, "element", (node, ancestors) => {
|
|
301
|
+
if (node.tagName !== "p") return;
|
|
302
|
+
const parent = ancestors.at(-1);
|
|
303
|
+
if (parent?.type === "element" && parent.tagName === "li") return;
|
|
304
|
+
const wrapped = [];
|
|
305
|
+
for (const child of node.children) {
|
|
306
|
+
if (child.type === "text" && child.value.trim().length > 0) {
|
|
307
|
+
wrapped.push({
|
|
308
|
+
type: "element",
|
|
309
|
+
tagName: "span",
|
|
310
|
+
properties: { dataStreamdown: "text" },
|
|
311
|
+
children: [{ type: "text", value: child.value }]
|
|
312
|
+
});
|
|
313
|
+
} else {
|
|
314
|
+
wrapped.push(child);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
node.children = wrapped;
|
|
318
|
+
});
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// src/vendor/ui/ai-elements/normalize-math.ts
|
|
323
|
+
function normalizeMathDelimiters(input) {
|
|
324
|
+
if (!input.includes("\\[") && !input.includes("\\(")) return input;
|
|
325
|
+
const segments = input.split(/(```[\s\S]*?```|`[^`\n]*`)/g);
|
|
326
|
+
return segments.map((seg, i) => {
|
|
327
|
+
if (i % 2 === 1) return seg;
|
|
328
|
+
return seg.replace(/\\\[([\s\S]+?)\\\]/g, (_m, body) => `$$${body}$$`).replace(/\\\(([\s\S]+?)\\\)/g, (_m, body) => `$${body}$`);
|
|
329
|
+
}).join("");
|
|
330
|
+
}
|
|
331
|
+
function escapeCurrencyDollars(input) {
|
|
332
|
+
if (!input.includes("$")) return input;
|
|
333
|
+
const segments = input.split(/(```[\s\S]*?```|`[^`\n]*`)/g);
|
|
334
|
+
return segments.map((seg, i) => {
|
|
335
|
+
if (i % 2 === 1) return seg;
|
|
336
|
+
return seg.replace(/(^|[^\\$])\$(?=\d)/g, (_m, before) => `${before}\\$`);
|
|
337
|
+
}).join("");
|
|
338
|
+
}
|
|
339
|
+
function prepareMarkdown(input) {
|
|
340
|
+
return escapeCurrencyDollars(normalizeMathDelimiters(input));
|
|
341
|
+
}
|
|
342
|
+
var Message = ({
|
|
343
|
+
className,
|
|
344
|
+
from,
|
|
345
|
+
presentation = "document",
|
|
346
|
+
...props
|
|
347
|
+
}) => /* @__PURE__ */ jsx(
|
|
348
|
+
"div",
|
|
349
|
+
{
|
|
350
|
+
className: cn(
|
|
351
|
+
"group flex w-full max-w-[95%] flex-col gap-2",
|
|
352
|
+
from === "user" ? "is-user dark ml-auto justify-end" : "is-assistant",
|
|
353
|
+
// Descendants opt into bubble styling with `group-[.is-bubble]:…`, so
|
|
354
|
+
// the mode travels down without another prop on every component between
|
|
355
|
+
// here and the text.
|
|
356
|
+
presentation === "bubble" && "is-bubble",
|
|
357
|
+
className
|
|
358
|
+
),
|
|
359
|
+
...props
|
|
360
|
+
}
|
|
361
|
+
);
|
|
362
|
+
var MessageContent = ({
|
|
363
|
+
children,
|
|
364
|
+
className,
|
|
365
|
+
...props
|
|
366
|
+
}) => /* @__PURE__ */ jsx(
|
|
367
|
+
"div",
|
|
368
|
+
{
|
|
369
|
+
className: cn(
|
|
370
|
+
// `overflow-clip`, not `hidden` — see MarkdownContainer: `hidden` makes
|
|
371
|
+
// this a scrollport and traps the code block's sticky header here.
|
|
372
|
+
"is-user:dark flex w-fit min-w-0 max-w-full flex-col gap-2 overflow-clip text-sm",
|
|
373
|
+
// Softer corner on phones: the prompt is the only bubble on the screen
|
|
374
|
+
// there, so it reads as a turn rather than as another card.
|
|
375
|
+
"group-[.is-user]:ml-auto group-[.is-user]:rounded-2xl max-md:group-[.is-user]:rounded-2xl group-[.is-user]:bg-surface-raised-active group-[.is-user]:px-3 group-[.is-user]:py-2 group-[.is-user]:text-foreground",
|
|
376
|
+
"group-[.is-assistant]:text-foreground",
|
|
377
|
+
// Bubble mode: both sides get the SAME corner. In document mode the
|
|
378
|
+
// user's prompt is the only bubble on screen and a tighter radius keeps
|
|
379
|
+
// it from reading as a card; here it sits opposite the Agent's bubbles
|
|
380
|
+
// all the way down the thread, and two different radii facing each other
|
|
381
|
+
// is the thing the eye catches.
|
|
382
|
+
"group-[.is-user.is-bubble]:rounded-2xl group-[.is-user.is-bubble]:max-w-2xl",
|
|
383
|
+
className
|
|
384
|
+
),
|
|
385
|
+
...props,
|
|
386
|
+
children
|
|
387
|
+
}
|
|
388
|
+
);
|
|
389
|
+
var STREAMDOWN_CONTROLS = { mermaid: { fullscreen: false } };
|
|
390
|
+
function LinkSafetyModal({ isOpen, onClose, onConfirm, url }) {
|
|
391
|
+
const [copied, setCopied] = useState(false);
|
|
392
|
+
return /* @__PURE__ */ jsx(
|
|
393
|
+
Dialog,
|
|
394
|
+
{
|
|
395
|
+
open: isOpen,
|
|
396
|
+
onOpenChange: (open) => {
|
|
397
|
+
if (!open) {
|
|
398
|
+
setCopied(false);
|
|
399
|
+
onClose();
|
|
400
|
+
}
|
|
401
|
+
},
|
|
402
|
+
children: /* @__PURE__ */ jsxs(DialogContent, { className: "z-[200] max-w-md space-y-4", overlayClassName: "z-[200]", children: [
|
|
403
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
404
|
+
/* @__PURE__ */ jsxs(DialogTitle, { className: "flex items-center gap-2", children: [
|
|
405
|
+
/* @__PURE__ */ jsx(SquareArrowTopRightIcon, { className: "size-5 text-muted-foreground" }),
|
|
406
|
+
"Open external link?"
|
|
407
|
+
] }),
|
|
408
|
+
/* @__PURE__ */ jsx(DialogDescription, { children: "You're about to visit an external website." })
|
|
409
|
+
] }),
|
|
410
|
+
/* @__PURE__ */ jsx("div", { className: "break-all rounded-md border border-border bg-muted px-3 items-center flex font-mono text-sm text-foreground h-8", children: url }),
|
|
411
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
412
|
+
/* @__PURE__ */ jsxs(
|
|
413
|
+
Button,
|
|
414
|
+
{
|
|
415
|
+
variant: "outline",
|
|
416
|
+
className: "flex-1",
|
|
417
|
+
onClick: () => {
|
|
418
|
+
void navigator.clipboard?.writeText(url);
|
|
419
|
+
setCopied(true);
|
|
420
|
+
},
|
|
421
|
+
children: [
|
|
422
|
+
copied ? /* @__PURE__ */ jsx(Checkmark1Icon, {}) : /* @__PURE__ */ jsx(ClipboardIcon, {}),
|
|
423
|
+
copied ? "Copied" : "Copy link"
|
|
424
|
+
]
|
|
425
|
+
}
|
|
426
|
+
),
|
|
427
|
+
/* @__PURE__ */ jsxs(Button, { className: "flex-1", onClick: onConfirm, children: [
|
|
428
|
+
/* @__PURE__ */ jsx(SquareArrowTopRightIcon, {}),
|
|
429
|
+
"Open link"
|
|
430
|
+
] })
|
|
431
|
+
] })
|
|
432
|
+
] })
|
|
433
|
+
}
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
var STREAMDOWN_LINK_SAFETY = {
|
|
437
|
+
enabled: true,
|
|
438
|
+
renderModal: (props) => /* @__PURE__ */ jsx(LinkSafetyModal, { ...props })
|
|
439
|
+
};
|
|
440
|
+
var STREAMDOWN_REHYPE_PLUGINS = [
|
|
441
|
+
rehypeUnwrapLiSoloP,
|
|
442
|
+
rehypeWrapParagraphTextNodes
|
|
443
|
+
];
|
|
444
|
+
var MessageResponse = memo(
|
|
445
|
+
({ className, children, ...props }) => {
|
|
446
|
+
const plugins = useStreamdownPlugins();
|
|
447
|
+
const content = typeof children === "string" ? prepareMarkdown(children) : children;
|
|
448
|
+
return /* @__PURE__ */ jsx(
|
|
449
|
+
Streamdown,
|
|
450
|
+
{
|
|
451
|
+
className: cn(
|
|
452
|
+
"size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0 prose-li:my-0 prose-li:py-0",
|
|
453
|
+
className
|
|
454
|
+
),
|
|
455
|
+
controls: STREAMDOWN_CONTROLS,
|
|
456
|
+
linkSafety: STREAMDOWN_LINK_SAFETY,
|
|
457
|
+
plugins,
|
|
458
|
+
rehypePlugins: STREAMDOWN_REHYPE_PLUGINS,
|
|
459
|
+
...props,
|
|
460
|
+
children: content
|
|
461
|
+
}
|
|
462
|
+
);
|
|
463
|
+
},
|
|
464
|
+
(prevProps, nextProps) => prevProps.children === nextProps.children && prevProps.components === nextProps.components && // className is chrome, independent of the markdown. Skipping it froze
|
|
465
|
+
// restyles of an unchanged answer — including assistant bubble corners
|
|
466
|
+
// when they still lived here, which made every n+1 bubble look last.
|
|
467
|
+
prevProps.className === nextProps.className
|
|
468
|
+
);
|
|
469
|
+
MessageResponse.displayName = "MessageResponse";
|
|
470
|
+
var MessageToolbar = ({
|
|
471
|
+
className,
|
|
472
|
+
children,
|
|
473
|
+
...props
|
|
474
|
+
}) => /* @__PURE__ */ jsx(
|
|
475
|
+
"div",
|
|
476
|
+
{
|
|
477
|
+
className: cn(
|
|
478
|
+
"mt-4 flex w-full items-center justify-between gap-4",
|
|
479
|
+
className
|
|
480
|
+
),
|
|
481
|
+
...props,
|
|
482
|
+
children
|
|
483
|
+
}
|
|
484
|
+
);
|
|
485
|
+
|
|
486
|
+
// src/vendor/lib/tool-activity-label.ts
|
|
487
|
+
var MAX_INTENT = 80;
|
|
488
|
+
var MAX_LABEL_JSON_LENGTH = 32e3;
|
|
489
|
+
function truncate(s, max = MAX_INTENT) {
|
|
490
|
+
if (s.length <= max) return s;
|
|
491
|
+
const cut = s.slice(0, max - 1);
|
|
492
|
+
const lastSpace = cut.lastIndexOf(" ");
|
|
493
|
+
return (lastSpace > 24 ? cut.slice(0, lastSpace) : cut) + "\u2026";
|
|
494
|
+
}
|
|
495
|
+
function titleCaseWords(s) {
|
|
496
|
+
return s.split(/\s+/).filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(" ");
|
|
497
|
+
}
|
|
498
|
+
function capitalizeWord(s) {
|
|
499
|
+
if (!s) return s;
|
|
500
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
501
|
+
}
|
|
502
|
+
function humanizeTokens(tokens) {
|
|
503
|
+
return tokens.join(" ");
|
|
504
|
+
}
|
|
505
|
+
var APP_SKILL_DISPLAY = {
|
|
506
|
+
gmail: "Google Gmail",
|
|
507
|
+
"google-calendar": "Google Calendar",
|
|
508
|
+
"google-drive": "Google Drive",
|
|
509
|
+
"google-sheets": "Google Sheets",
|
|
510
|
+
"google-analytics": "Google Analytics",
|
|
511
|
+
"google-accounts": "Google Accounts",
|
|
512
|
+
slack: "Slack",
|
|
513
|
+
notion: "Notion",
|
|
514
|
+
linear: "Linear",
|
|
515
|
+
figma: "Figma",
|
|
516
|
+
jira: "Jira",
|
|
517
|
+
salesforce: "Salesforce",
|
|
518
|
+
hubspot: "HubSpot",
|
|
519
|
+
discord: "Discord"
|
|
520
|
+
};
|
|
521
|
+
function extractSkillSlug(input) {
|
|
522
|
+
if (!input || typeof input !== "object") return void 0;
|
|
523
|
+
const o = input;
|
|
524
|
+
const v = o.skill_name ?? o.name;
|
|
525
|
+
return typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
526
|
+
}
|
|
527
|
+
function unwrapSkillOutput(output) {
|
|
528
|
+
if (!output || typeof output !== "object") return void 0;
|
|
529
|
+
let o = output;
|
|
530
|
+
if ("value" in o && o.value && typeof o.value === "object") {
|
|
531
|
+
o = o.value;
|
|
532
|
+
}
|
|
533
|
+
return o;
|
|
534
|
+
}
|
|
535
|
+
function resolveSkillLabel(input, output) {
|
|
536
|
+
const out = unwrapSkillOutput(output);
|
|
537
|
+
const fromOutput = out?.displayName;
|
|
538
|
+
if (typeof fromOutput === "string" && fromOutput.trim()) {
|
|
539
|
+
return fromOutput.trim();
|
|
540
|
+
}
|
|
541
|
+
const slug = extractSkillSlug(input);
|
|
542
|
+
return slug ? formatSkillDisplayName(slug) : void 0;
|
|
543
|
+
}
|
|
544
|
+
function formatSkillDisplayName(slug) {
|
|
545
|
+
const normalized = slug.replace(/_/g, "-").replace(/-guide$/i, "");
|
|
546
|
+
if (APP_SKILL_DISPLAY[normalized]) return APP_SKILL_DISPLAY[normalized];
|
|
547
|
+
return titleCaseWords(normalized.replace(/-/g, " "));
|
|
548
|
+
}
|
|
549
|
+
function skillSlugToAppKind(slug) {
|
|
550
|
+
return slug.replace(/_/g, "-").replace(/-guide$/i, "");
|
|
551
|
+
}
|
|
552
|
+
function tokenizeToolName(name) {
|
|
553
|
+
const n = name.trim();
|
|
554
|
+
if (!n) return [];
|
|
555
|
+
if (n.includes("_")) {
|
|
556
|
+
return n.split("_").filter(Boolean).map((t) => t.toLowerCase());
|
|
557
|
+
}
|
|
558
|
+
return n.replace(/([a-z])([A-Z])/g, "$1 $2").split(/\s+/).filter(Boolean).map((t) => t.toLowerCase());
|
|
559
|
+
}
|
|
560
|
+
var VERB_PAST = {
|
|
561
|
+
search: "searched",
|
|
562
|
+
query: "queried",
|
|
563
|
+
get: "retrieved",
|
|
564
|
+
fetch: "fetched",
|
|
565
|
+
list: "listed",
|
|
566
|
+
find: "found",
|
|
567
|
+
read: "read",
|
|
568
|
+
run: "ran",
|
|
569
|
+
execute: "executed",
|
|
570
|
+
create: "created",
|
|
571
|
+
update: "updated",
|
|
572
|
+
delete: "deleted",
|
|
573
|
+
send: "sent",
|
|
574
|
+
submit: "submitted",
|
|
575
|
+
validate: "validated",
|
|
576
|
+
check: "checked",
|
|
577
|
+
discover: "discovered",
|
|
578
|
+
generate: "generated",
|
|
579
|
+
forecast: "forecasted",
|
|
580
|
+
detect: "detected",
|
|
581
|
+
analyze: "analyzed",
|
|
582
|
+
contribute: "analyzed"
|
|
583
|
+
};
|
|
584
|
+
function parseLabelJson(text) {
|
|
585
|
+
if (text.length > MAX_LABEL_JSON_LENGTH) return null;
|
|
586
|
+
try {
|
|
587
|
+
return JSON.parse(text);
|
|
588
|
+
} catch {
|
|
589
|
+
return null;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
function unwrapAiJson(raw) {
|
|
593
|
+
if (typeof raw === "string") return parseLabelJson(raw);
|
|
594
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return raw;
|
|
595
|
+
const r = raw;
|
|
596
|
+
if (r.type === "json" && "value" in r) return r.value;
|
|
597
|
+
const content = Array.isArray(r.content) ? r.content : r.type === "content" && Array.isArray(r.value) ? r.value : null;
|
|
598
|
+
if (content) {
|
|
599
|
+
const textItem = content.find(
|
|
600
|
+
(item) => item.type === "text" && typeof item.text === "string"
|
|
601
|
+
);
|
|
602
|
+
return textItem ? parseLabelJson(textItem.text) : null;
|
|
603
|
+
}
|
|
604
|
+
return raw;
|
|
605
|
+
}
|
|
606
|
+
function inferToolResultCount(raw) {
|
|
607
|
+
const data = unwrapAiJson(raw);
|
|
608
|
+
if (data == null) return null;
|
|
609
|
+
if (Array.isArray(data)) return data.length;
|
|
610
|
+
if (typeof data !== "object") return null;
|
|
611
|
+
const o = data;
|
|
612
|
+
for (const key of [
|
|
613
|
+
"rows",
|
|
614
|
+
"data",
|
|
615
|
+
"results",
|
|
616
|
+
"items",
|
|
617
|
+
"records",
|
|
618
|
+
"citations",
|
|
619
|
+
"documents",
|
|
620
|
+
"matches"
|
|
621
|
+
]) {
|
|
622
|
+
const v = o[key];
|
|
623
|
+
if (Array.isArray(v)) return v.length;
|
|
624
|
+
}
|
|
625
|
+
for (const key of ["total", "count", "rowCount", "length"]) {
|
|
626
|
+
const v = o[key];
|
|
627
|
+
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
628
|
+
}
|
|
629
|
+
return null;
|
|
630
|
+
}
|
|
631
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
632
|
+
function extractIntentSnippet(input) {
|
|
633
|
+
if (!input || typeof input !== "object") return void 0;
|
|
634
|
+
const o = input;
|
|
635
|
+
const preferKeys = [
|
|
636
|
+
"action",
|
|
637
|
+
"query",
|
|
638
|
+
"prompt",
|
|
639
|
+
"sql",
|
|
640
|
+
"command",
|
|
641
|
+
"cmd",
|
|
642
|
+
"code",
|
|
643
|
+
"message",
|
|
644
|
+
"text",
|
|
645
|
+
"question",
|
|
646
|
+
"title",
|
|
647
|
+
"task",
|
|
648
|
+
"input",
|
|
649
|
+
"search",
|
|
650
|
+
"path",
|
|
651
|
+
"filePath",
|
|
652
|
+
"file",
|
|
653
|
+
"url",
|
|
654
|
+
"name"
|
|
655
|
+
];
|
|
656
|
+
for (const k of preferKeys) {
|
|
657
|
+
const v = o[k];
|
|
658
|
+
if (typeof v !== "string") continue;
|
|
659
|
+
const t = v.trim();
|
|
660
|
+
if (t && !UUID_RE.test(t)) return truncate(t);
|
|
661
|
+
}
|
|
662
|
+
return void 0;
|
|
663
|
+
}
|
|
664
|
+
var TOOL_ROW_CONFIG = {
|
|
665
|
+
readFile: { done: "Read", running: "Reading", fail: "Read failed", targetKeys: ["path", "filePath", "file"], mono: true },
|
|
666
|
+
readFileBuffer: { done: "Read", running: "Reading", fail: "Read failed", targetKeys: ["path", "filePath", "file"], mono: true },
|
|
667
|
+
writeFile: { done: "Wrote", running: "Writing", fail: "Write failed", targetKeys: ["path", "filePath", "file"], mono: true },
|
|
668
|
+
exists: { done: "Checked", running: "Checking", fail: "Check failed", targetKeys: ["path", "filePath", "file"], mono: true },
|
|
669
|
+
readdir: { done: "Listed", running: "Listing", fail: "List failed", targetKeys: ["path", "dir", "filePath"], mono: true },
|
|
670
|
+
resolvePath: { done: "Resolved path", running: "Resolving path", fail: "Path resolve failed", targetKeys: ["path"], mono: true },
|
|
671
|
+
symlink: { done: "Linked", running: "Linking", fail: "Link failed", targetKeys: ["path", "target", "from"], mono: true },
|
|
672
|
+
bash: { done: "Ran", running: "Running", fail: "Command failed", targetKeys: ["command", "cmd"], mono: true },
|
|
673
|
+
run_js: { done: "Ran js", running: "Running js", fail: "JS failed", targetKeys: ["code"], mono: true },
|
|
674
|
+
run_python: { done: "Ran python", running: "Running python", fail: "Python failed", targetKeys: ["code"], mono: true },
|
|
675
|
+
read_file: { done: "Read", running: "Reading", fail: "Read failed", targetKeys: ["path", "filePath", "file"], mono: true },
|
|
676
|
+
write_file: { done: "Wrote", running: "Writing", fail: "Write failed", targetKeys: ["path", "filePath", "file"], mono: true },
|
|
677
|
+
edit_file: { done: "Edited", running: "Editing", fail: "Edit failed", targetKeys: ["path", "filePath", "file"], mono: true },
|
|
678
|
+
view_image: { done: "Viewed image", running: "Viewing image", fail: "View failed", targetKeys: ["path"], mono: true },
|
|
679
|
+
web_search: { done: "Searched the web", running: "Searching the web", fail: "Web search failed", targetKeys: ["query", "search"], quote: true },
|
|
680
|
+
searchKnowledge: { done: "Searched knowledge", running: "Searching knowledge", fail: "Knowledge search failed", targetKeys: ["query"], quote: true },
|
|
681
|
+
search_memory: { done: "Searched memory", running: "Searching memory", fail: "Memory search failed", targetKeys: ["queries"], quote: true },
|
|
682
|
+
createDocument: { done: "Created document", running: "Writing document", fail: "Document failed", targetKeys: ["title"] },
|
|
683
|
+
updateDocument: { done: "Updated document", running: "Updating document", fail: "Update failed", targetKeys: ["title"] },
|
|
684
|
+
skill: {
|
|
685
|
+
done: "Used",
|
|
686
|
+
running: "Loading",
|
|
687
|
+
fail: "Skill failed",
|
|
688
|
+
targetKeys: ["skill_name", "name"]
|
|
689
|
+
},
|
|
690
|
+
createImage: { done: "Created image", running: "Generating image", fail: "Image failed", targetKeys: ["prompt"], quote: true },
|
|
691
|
+
// Artifact tools take an artifactId (a uuid — meaningless in the transcript,
|
|
692
|
+
// and filtered by pickTarget/extractIntentSnippet); the human title resolves
|
|
693
|
+
// from the tool OUTPUT via the generic `title` fallback in describeToolRow.
|
|
694
|
+
createSlides: { done: "Created slides", running: "Creating slides", fail: "Slides failed", targetKeys: ["title"], quote: true },
|
|
695
|
+
readSlides: { done: "Read slides", running: "Reading slides", fail: "Read failed", quote: true },
|
|
696
|
+
updateSlides: { done: "Updated slides", running: "Updating slides", fail: "Update failed", quote: true },
|
|
697
|
+
createSpreadsheet: { done: "Created spreadsheet", running: "Creating spreadsheet", fail: "Spreadsheet failed", targetKeys: ["title"], quote: true },
|
|
698
|
+
readSpreadsheet: { done: "Read spreadsheet", running: "Reading spreadsheet", fail: "Read failed", targetKeys: ["url"], quote: true },
|
|
699
|
+
updateSpreadsheet: { done: "Updated spreadsheet", running: "Updating spreadsheet", fail: "Update failed", targetKeys: ["title"], quote: true },
|
|
700
|
+
createPdf: { done: "Created PDF", running: "Creating PDF", fail: "PDF failed", targetKeys: ["title"], quote: true },
|
|
701
|
+
readPdf: { done: "Read PDF", running: "Reading PDF", fail: "Read failed", targetKeys: ["url"], quote: true }
|
|
702
|
+
};
|
|
703
|
+
var GERUND = {
|
|
704
|
+
search: "Searching",
|
|
705
|
+
query: "Querying",
|
|
706
|
+
get: "Fetching",
|
|
707
|
+
fetch: "Fetching",
|
|
708
|
+
list: "Listing",
|
|
709
|
+
read: "Reading",
|
|
710
|
+
run: "Running",
|
|
711
|
+
execute: "Running",
|
|
712
|
+
create: "Creating",
|
|
713
|
+
update: "Updating",
|
|
714
|
+
delete: "Deleting",
|
|
715
|
+
send: "Sending",
|
|
716
|
+
submit: "Submitting",
|
|
717
|
+
validate: "Validating",
|
|
718
|
+
check: "Checking",
|
|
719
|
+
find: "Finding",
|
|
720
|
+
generate: "Generating",
|
|
721
|
+
analyze: "Analyzing",
|
|
722
|
+
detect: "Detecting"
|
|
723
|
+
};
|
|
724
|
+
function truncateTail(s, max) {
|
|
725
|
+
if (s.length <= max) return s;
|
|
726
|
+
return "\u2026" + s.slice(s.length - (max - 1));
|
|
727
|
+
}
|
|
728
|
+
function pickTarget(input, keys) {
|
|
729
|
+
if (!input || typeof input !== "object" || !keys) return void 0;
|
|
730
|
+
const o = input;
|
|
731
|
+
for (const k of keys) {
|
|
732
|
+
const v = o[k];
|
|
733
|
+
if (typeof v !== "string") continue;
|
|
734
|
+
const t = v.trim();
|
|
735
|
+
if (t && !UUID_RE.test(t)) return t;
|
|
736
|
+
}
|
|
737
|
+
return void 0;
|
|
738
|
+
}
|
|
739
|
+
function describeToolRow(toolName, state, input, output, errorText) {
|
|
740
|
+
const authored = pickTarget(input, ["action"]);
|
|
741
|
+
if (authored) {
|
|
742
|
+
return {
|
|
743
|
+
verb: truncate(authored, 80),
|
|
744
|
+
target: void 0,
|
|
745
|
+
targetMono: false
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
const displayName = toolName.includes("__") ? toolName.split("__").pop() ?? toolName : toolName;
|
|
749
|
+
const cfg = TOOL_ROW_CONFIG[toolName] ?? TOOL_ROW_CONFIG[displayName];
|
|
750
|
+
const isError = state === "output-error" || state === "error";
|
|
751
|
+
const isDenied = state === "output-denied";
|
|
752
|
+
const isRunning = ["input-streaming", "partial-call", "input-available", "call"].includes(state);
|
|
753
|
+
let target;
|
|
754
|
+
if (toolName === "skill" || displayName === "skill") {
|
|
755
|
+
target = resolveSkillLabel(input, output);
|
|
756
|
+
} else {
|
|
757
|
+
target = cfg ? pickTarget(input, cfg.targetKeys) : extractIntentSnippet(input);
|
|
758
|
+
if (!target) {
|
|
759
|
+
target = pickTarget(unwrapAiJson(output), ["title"]);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
const targetMono = cfg?.mono ?? false;
|
|
763
|
+
if (target) {
|
|
764
|
+
if (toolName === "skill" || displayName === "skill") ; else if (cfg?.quote) {
|
|
765
|
+
target = `"${truncate(target, 70)}"`;
|
|
766
|
+
} else if (targetMono) {
|
|
767
|
+
target = truncateTail(target, 64);
|
|
768
|
+
} else {
|
|
769
|
+
target = truncate(target, 72);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
const tokens = tokenizeToolName(displayName);
|
|
773
|
+
const head = tokens[0] ?? "";
|
|
774
|
+
const rest = tokens.slice(1);
|
|
775
|
+
const objectPhrase = rest.length ? humanizeTokens(rest) : displayName.replace(/_/g, " ").toLowerCase();
|
|
776
|
+
let verb;
|
|
777
|
+
if (isError) {
|
|
778
|
+
verb = cfg?.done ?? capitalizeWord(objectPhrase);
|
|
779
|
+
} else if (isDenied) {
|
|
780
|
+
verb = `${objectPhrase} denied`;
|
|
781
|
+
} else if (cfg) {
|
|
782
|
+
verb = isRunning ? cfg.running : cfg.done;
|
|
783
|
+
} else if (isRunning) {
|
|
784
|
+
const gerund = GERUND[head] ?? "Running";
|
|
785
|
+
verb = rest.length ? `${gerund} ${objectPhrase}` : gerund;
|
|
786
|
+
} else {
|
|
787
|
+
const past = VERB_PAST[head];
|
|
788
|
+
verb = past ? rest.length ? `${capitalizeWord(past)} ${objectPhrase}` : capitalizeWord(past) : capitalizeWord(objectPhrase);
|
|
789
|
+
}
|
|
790
|
+
let hint;
|
|
791
|
+
let hintTone;
|
|
792
|
+
if (isError) {
|
|
793
|
+
hint = void 0;
|
|
794
|
+
hintTone = "muted";
|
|
795
|
+
} else if (isDenied) {
|
|
796
|
+
hint = "denied";
|
|
797
|
+
hintTone = "danger";
|
|
798
|
+
} else if (!isRunning) {
|
|
799
|
+
const count = inferToolResultCount(output);
|
|
800
|
+
if (count !== null) {
|
|
801
|
+
hint = `${count} ${count === 1 ? "result" : "results"}`;
|
|
802
|
+
hintTone = "muted";
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
return { verb, target, targetMono, hint, hintTone };
|
|
806
|
+
}
|
|
807
|
+
function getIconsTree(data, names) {
|
|
808
|
+
const icons = data.icons;
|
|
809
|
+
const aliases = data.aliases || /* @__PURE__ */ Object.create(null);
|
|
810
|
+
const resolved = /* @__PURE__ */ Object.create(null);
|
|
811
|
+
function resolve(name) {
|
|
812
|
+
if (icons[name]) return resolved[name] = [];
|
|
813
|
+
if (!(name in resolved)) {
|
|
814
|
+
resolved[name] = null;
|
|
815
|
+
const parent = aliases[name] && aliases[name].parent;
|
|
816
|
+
const value = parent && resolve(parent);
|
|
817
|
+
if (value) resolved[name] = [parent].concat(value);
|
|
818
|
+
}
|
|
819
|
+
return resolved[name];
|
|
820
|
+
}
|
|
821
|
+
Object.keys(icons).concat(Object.keys(aliases)).forEach(resolve);
|
|
822
|
+
return resolved;
|
|
823
|
+
}
|
|
824
|
+
var defaultIconDimensions = Object.freeze({
|
|
825
|
+
left: 0,
|
|
826
|
+
top: 0,
|
|
827
|
+
width: 16,
|
|
828
|
+
height: 16
|
|
829
|
+
});
|
|
830
|
+
var defaultIconTransformations = Object.freeze({
|
|
831
|
+
rotate: 0,
|
|
832
|
+
vFlip: false,
|
|
833
|
+
hFlip: false
|
|
834
|
+
});
|
|
835
|
+
var defaultIconProps = Object.freeze({
|
|
836
|
+
...defaultIconDimensions,
|
|
837
|
+
...defaultIconTransformations
|
|
838
|
+
});
|
|
839
|
+
var defaultExtendedIconProps = Object.freeze({
|
|
840
|
+
...defaultIconProps,
|
|
841
|
+
body: "",
|
|
842
|
+
hidden: false
|
|
843
|
+
});
|
|
844
|
+
function mergeIconTransformations(obj1, obj2) {
|
|
845
|
+
const result = {};
|
|
846
|
+
if (!obj1.hFlip !== !obj2.hFlip) result.hFlip = true;
|
|
847
|
+
if (!obj1.vFlip !== !obj2.vFlip) result.vFlip = true;
|
|
848
|
+
const rotate = ((obj1.rotate || 0) + (obj2.rotate || 0)) % 4;
|
|
849
|
+
if (rotate) result.rotate = rotate;
|
|
850
|
+
return result;
|
|
851
|
+
}
|
|
852
|
+
function mergeIconData(parent, child) {
|
|
853
|
+
const result = mergeIconTransformations(parent, child);
|
|
854
|
+
for (const key in defaultExtendedIconProps) if (key in defaultIconTransformations) {
|
|
855
|
+
if (key in parent && !(key in result)) result[key] = defaultIconTransformations[key];
|
|
856
|
+
} else if (key in child) result[key] = child[key];
|
|
857
|
+
else if (key in parent) result[key] = parent[key];
|
|
858
|
+
return result;
|
|
859
|
+
}
|
|
860
|
+
function internalGetIconData(data, name, tree) {
|
|
861
|
+
const icons = data.icons;
|
|
862
|
+
const aliases = data.aliases || /* @__PURE__ */ Object.create(null);
|
|
863
|
+
let currentProps = {};
|
|
864
|
+
function parse(name$1) {
|
|
865
|
+
currentProps = mergeIconData(icons[name$1] || aliases[name$1], currentProps);
|
|
866
|
+
}
|
|
867
|
+
parse(name);
|
|
868
|
+
tree.forEach(parse);
|
|
869
|
+
return mergeIconData(data, currentProps);
|
|
870
|
+
}
|
|
871
|
+
function parseIconSet(data, callback) {
|
|
872
|
+
const names = [];
|
|
873
|
+
if (typeof data !== "object" || typeof data.icons !== "object") return names;
|
|
874
|
+
if (data.not_found instanceof Array) data.not_found.forEach((name) => {
|
|
875
|
+
callback(name, null);
|
|
876
|
+
names.push(name);
|
|
877
|
+
});
|
|
878
|
+
const tree = getIconsTree(data);
|
|
879
|
+
for (const name in tree) {
|
|
880
|
+
const item = tree[name];
|
|
881
|
+
if (item) {
|
|
882
|
+
callback(name, internalGetIconData(data, name, item));
|
|
883
|
+
names.push(name);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
return names;
|
|
887
|
+
}
|
|
888
|
+
var optionalPropertyDefaults = {
|
|
889
|
+
provider: "",
|
|
890
|
+
aliases: {},
|
|
891
|
+
not_found: {},
|
|
892
|
+
...defaultIconDimensions
|
|
893
|
+
};
|
|
894
|
+
function checkOptionalProps(item, defaults) {
|
|
895
|
+
for (const prop in defaults) if (prop in item && typeof item[prop] !== typeof defaults[prop]) return false;
|
|
896
|
+
return true;
|
|
897
|
+
}
|
|
898
|
+
function quicklyValidateIconSet(obj) {
|
|
899
|
+
if (typeof obj !== "object" || obj === null) return null;
|
|
900
|
+
const data = obj;
|
|
901
|
+
if (typeof data.prefix !== "string" || !obj.icons || typeof obj.icons !== "object") return null;
|
|
902
|
+
if (!checkOptionalProps(obj, optionalPropertyDefaults)) return null;
|
|
903
|
+
const icons = data.icons;
|
|
904
|
+
for (const name in icons) {
|
|
905
|
+
const icon = icons[name];
|
|
906
|
+
if (!name || typeof icon.body !== "string" || !checkOptionalProps(icon, defaultExtendedIconProps)) return null;
|
|
907
|
+
}
|
|
908
|
+
const aliases = data.aliases || /* @__PURE__ */ Object.create(null);
|
|
909
|
+
for (const name in aliases) {
|
|
910
|
+
const icon = aliases[name];
|
|
911
|
+
const parent = icon.parent;
|
|
912
|
+
if (!name || typeof parent !== "string" || !icons[parent] && !aliases[parent] || !checkOptionalProps(icon, defaultExtendedIconProps)) return null;
|
|
913
|
+
}
|
|
914
|
+
return data;
|
|
915
|
+
}
|
|
916
|
+
var dataStorage = /* @__PURE__ */ Object.create(null);
|
|
917
|
+
function newStorage(provider, prefix) {
|
|
918
|
+
return {
|
|
919
|
+
provider,
|
|
920
|
+
prefix,
|
|
921
|
+
icons: /* @__PURE__ */ Object.create(null),
|
|
922
|
+
missing: /* @__PURE__ */ new Set()
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
function getStorage(provider, prefix) {
|
|
926
|
+
const providerStorage = dataStorage[provider] || (dataStorage[provider] = /* @__PURE__ */ Object.create(null));
|
|
927
|
+
return providerStorage[prefix] || (providerStorage[prefix] = newStorage(provider, prefix));
|
|
928
|
+
}
|
|
929
|
+
function addIconSet(storage2, data) {
|
|
930
|
+
if (!quicklyValidateIconSet(data)) return [];
|
|
931
|
+
return parseIconSet(data, (name, icon) => {
|
|
932
|
+
if (icon) storage2.icons[name] = icon;
|
|
933
|
+
else storage2.missing.add(name);
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
function addIconToStorage(storage2, name, icon) {
|
|
937
|
+
try {
|
|
938
|
+
if (typeof icon.body === "string") {
|
|
939
|
+
storage2.icons[name] = { ...icon };
|
|
940
|
+
return true;
|
|
941
|
+
}
|
|
942
|
+
} catch (err) {
|
|
943
|
+
}
|
|
944
|
+
return false;
|
|
945
|
+
}
|
|
946
|
+
var matchIconName = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
947
|
+
var stringToIcon = (value, validate, allowSimpleName, provider = "") => {
|
|
948
|
+
const colonSeparated = value.split(":");
|
|
949
|
+
if (value.slice(0, 1) === "@") {
|
|
950
|
+
if (colonSeparated.length < 2 || colonSeparated.length > 3) return null;
|
|
951
|
+
provider = colonSeparated.shift().slice(1);
|
|
952
|
+
}
|
|
953
|
+
if (colonSeparated.length > 3 || !colonSeparated.length) return null;
|
|
954
|
+
if (colonSeparated.length > 1) {
|
|
955
|
+
const name$1 = colonSeparated.pop();
|
|
956
|
+
const prefix = colonSeparated.pop();
|
|
957
|
+
const result = {
|
|
958
|
+
provider: colonSeparated.length > 0 ? colonSeparated[0] : provider,
|
|
959
|
+
prefix,
|
|
960
|
+
name: name$1
|
|
961
|
+
};
|
|
962
|
+
return validate && !validateIconName(result) ? null : result;
|
|
963
|
+
}
|
|
964
|
+
const name = colonSeparated[0];
|
|
965
|
+
const dashSeparated = name.split("-");
|
|
966
|
+
if (dashSeparated.length > 1) {
|
|
967
|
+
const result = {
|
|
968
|
+
provider,
|
|
969
|
+
prefix: dashSeparated.shift(),
|
|
970
|
+
name: dashSeparated.join("-")
|
|
971
|
+
};
|
|
972
|
+
return validate && !validateIconName(result) ? null : result;
|
|
973
|
+
}
|
|
974
|
+
if (allowSimpleName && provider === "") {
|
|
975
|
+
const result = {
|
|
976
|
+
provider,
|
|
977
|
+
prefix: "",
|
|
978
|
+
name
|
|
979
|
+
};
|
|
980
|
+
return validate && !validateIconName(result, allowSimpleName) ? null : result;
|
|
981
|
+
}
|
|
982
|
+
return null;
|
|
983
|
+
};
|
|
984
|
+
var validateIconName = (icon, allowSimpleName) => {
|
|
985
|
+
if (!icon) return false;
|
|
986
|
+
return !!((allowSimpleName && icon.prefix === "" || !!icon.prefix) && !!icon.name);
|
|
987
|
+
};
|
|
988
|
+
var simpleNames = false;
|
|
989
|
+
function allowSimpleNames(allow) {
|
|
990
|
+
if (typeof allow === "boolean") simpleNames = allow;
|
|
991
|
+
return simpleNames;
|
|
992
|
+
}
|
|
993
|
+
function getIconData(name) {
|
|
994
|
+
const icon = typeof name === "string" ? stringToIcon(name, true, simpleNames) : name;
|
|
995
|
+
if (icon) {
|
|
996
|
+
const storage2 = getStorage(icon.provider, icon.prefix);
|
|
997
|
+
const iconName = icon.name;
|
|
998
|
+
return storage2.icons[iconName] || (storage2.missing.has(iconName) ? null : void 0);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
function addIcon(name, data) {
|
|
1002
|
+
const icon = stringToIcon(name, true, simpleNames);
|
|
1003
|
+
if (!icon) return false;
|
|
1004
|
+
const storage2 = getStorage(icon.provider, icon.prefix);
|
|
1005
|
+
if (data) return addIconToStorage(storage2, icon.name, data);
|
|
1006
|
+
else {
|
|
1007
|
+
storage2.missing.add(icon.name);
|
|
1008
|
+
return true;
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
function addCollection(data, provider) {
|
|
1012
|
+
if (typeof data !== "object") return false;
|
|
1013
|
+
if (typeof provider !== "string") provider = data.provider || "";
|
|
1014
|
+
if (simpleNames && !provider && !data.prefix) {
|
|
1015
|
+
let added = false;
|
|
1016
|
+
if (quicklyValidateIconSet(data)) {
|
|
1017
|
+
data.prefix = "";
|
|
1018
|
+
parseIconSet(data, (name, icon) => {
|
|
1019
|
+
if (addIcon(name, icon)) added = true;
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1022
|
+
return added;
|
|
1023
|
+
}
|
|
1024
|
+
const prefix = data.prefix;
|
|
1025
|
+
if (!validateIconName({
|
|
1026
|
+
prefix,
|
|
1027
|
+
name: "a"
|
|
1028
|
+
})) return false;
|
|
1029
|
+
const storage2 = getStorage(provider, prefix);
|
|
1030
|
+
return !!addIconSet(storage2, data);
|
|
1031
|
+
}
|
|
1032
|
+
var defaultIconSizeCustomisations = Object.freeze({
|
|
1033
|
+
width: null,
|
|
1034
|
+
height: null
|
|
1035
|
+
});
|
|
1036
|
+
var defaultIconCustomisations = Object.freeze({
|
|
1037
|
+
...defaultIconSizeCustomisations,
|
|
1038
|
+
...defaultIconTransformations
|
|
1039
|
+
});
|
|
1040
|
+
var unitsSplit = /(-?[0-9.]*[0-9]+[0-9.]*)/g;
|
|
1041
|
+
var unitsTest = /^-?[0-9.]*[0-9]+[0-9.]*$/g;
|
|
1042
|
+
function calculateSize(size, ratio, precision) {
|
|
1043
|
+
if (ratio === 1) return size;
|
|
1044
|
+
precision = precision || 100;
|
|
1045
|
+
if (typeof size === "number") return Math.ceil(size * ratio * precision) / precision;
|
|
1046
|
+
if (typeof size !== "string") return size;
|
|
1047
|
+
const oldParts = size.split(unitsSplit);
|
|
1048
|
+
if (oldParts === null || !oldParts.length) return size;
|
|
1049
|
+
const newParts = [];
|
|
1050
|
+
let code = oldParts.shift();
|
|
1051
|
+
let isNumber = unitsTest.test(code);
|
|
1052
|
+
while (true) {
|
|
1053
|
+
if (isNumber) {
|
|
1054
|
+
const num = parseFloat(code);
|
|
1055
|
+
if (isNaN(num)) newParts.push(code);
|
|
1056
|
+
else newParts.push(Math.ceil(num * ratio * precision) / precision);
|
|
1057
|
+
} else newParts.push(code);
|
|
1058
|
+
code = oldParts.shift();
|
|
1059
|
+
if (code === void 0) return newParts.join("");
|
|
1060
|
+
isNumber = !isNumber;
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
function splitSVGDefs(content, tag = "defs") {
|
|
1064
|
+
let defs = "";
|
|
1065
|
+
const index = content.indexOf("<" + tag);
|
|
1066
|
+
while (index >= 0) {
|
|
1067
|
+
const start = content.indexOf(">", index);
|
|
1068
|
+
const end = content.indexOf("</" + tag);
|
|
1069
|
+
if (start === -1 || end === -1) break;
|
|
1070
|
+
const endEnd = content.indexOf(">", end);
|
|
1071
|
+
if (endEnd === -1) break;
|
|
1072
|
+
defs += content.slice(start + 1, end).trim();
|
|
1073
|
+
content = content.slice(0, index).trim() + content.slice(endEnd + 1);
|
|
1074
|
+
}
|
|
1075
|
+
return {
|
|
1076
|
+
defs,
|
|
1077
|
+
content
|
|
1078
|
+
};
|
|
1079
|
+
}
|
|
1080
|
+
function mergeDefsAndContent(defs, content) {
|
|
1081
|
+
return defs ? "<defs>" + defs + "</defs>" + content : content;
|
|
1082
|
+
}
|
|
1083
|
+
function wrapSVGContent(body, start, end) {
|
|
1084
|
+
const split = splitSVGDefs(body);
|
|
1085
|
+
return mergeDefsAndContent(split.defs, start + split.content + end);
|
|
1086
|
+
}
|
|
1087
|
+
var isUnsetKeyword = (value) => value === "unset" || value === "undefined" || value === "none";
|
|
1088
|
+
function iconToSVG(icon, customisations) {
|
|
1089
|
+
const fullIcon = {
|
|
1090
|
+
...defaultIconProps,
|
|
1091
|
+
...icon
|
|
1092
|
+
};
|
|
1093
|
+
const fullCustomisations = {
|
|
1094
|
+
...defaultIconCustomisations,
|
|
1095
|
+
...customisations
|
|
1096
|
+
};
|
|
1097
|
+
const box = {
|
|
1098
|
+
left: fullIcon.left,
|
|
1099
|
+
top: fullIcon.top,
|
|
1100
|
+
width: fullIcon.width,
|
|
1101
|
+
height: fullIcon.height
|
|
1102
|
+
};
|
|
1103
|
+
let body = fullIcon.body;
|
|
1104
|
+
[fullIcon, fullCustomisations].forEach((props) => {
|
|
1105
|
+
const transformations = [];
|
|
1106
|
+
const hFlip = props.hFlip;
|
|
1107
|
+
const vFlip = props.vFlip;
|
|
1108
|
+
let rotation = props.rotate;
|
|
1109
|
+
if (hFlip) if (vFlip) rotation += 2;
|
|
1110
|
+
else {
|
|
1111
|
+
transformations.push("translate(" + (box.width + box.left).toString() + " " + (0 - box.top).toString() + ")");
|
|
1112
|
+
transformations.push("scale(-1 1)");
|
|
1113
|
+
box.top = box.left = 0;
|
|
1114
|
+
}
|
|
1115
|
+
else if (vFlip) {
|
|
1116
|
+
transformations.push("translate(" + (0 - box.left).toString() + " " + (box.height + box.top).toString() + ")");
|
|
1117
|
+
transformations.push("scale(1 -1)");
|
|
1118
|
+
box.top = box.left = 0;
|
|
1119
|
+
}
|
|
1120
|
+
let tempValue;
|
|
1121
|
+
if (rotation < 0) rotation -= Math.floor(rotation / 4) * 4;
|
|
1122
|
+
rotation = rotation % 4;
|
|
1123
|
+
switch (rotation) {
|
|
1124
|
+
case 1:
|
|
1125
|
+
tempValue = box.height / 2 + box.top;
|
|
1126
|
+
transformations.unshift("rotate(90 " + tempValue.toString() + " " + tempValue.toString() + ")");
|
|
1127
|
+
break;
|
|
1128
|
+
case 2:
|
|
1129
|
+
transformations.unshift("rotate(180 " + (box.width / 2 + box.left).toString() + " " + (box.height / 2 + box.top).toString() + ")");
|
|
1130
|
+
break;
|
|
1131
|
+
case 3:
|
|
1132
|
+
tempValue = box.width / 2 + box.left;
|
|
1133
|
+
transformations.unshift("rotate(-90 " + tempValue.toString() + " " + tempValue.toString() + ")");
|
|
1134
|
+
break;
|
|
1135
|
+
}
|
|
1136
|
+
if (rotation % 2 === 1) {
|
|
1137
|
+
if (box.left !== box.top) {
|
|
1138
|
+
tempValue = box.left;
|
|
1139
|
+
box.left = box.top;
|
|
1140
|
+
box.top = tempValue;
|
|
1141
|
+
}
|
|
1142
|
+
if (box.width !== box.height) {
|
|
1143
|
+
tempValue = box.width;
|
|
1144
|
+
box.width = box.height;
|
|
1145
|
+
box.height = tempValue;
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
if (transformations.length) body = wrapSVGContent(body, '<g transform="' + transformations.join(" ") + '">', "</g>");
|
|
1149
|
+
});
|
|
1150
|
+
const customisationsWidth = fullCustomisations.width;
|
|
1151
|
+
const customisationsHeight = fullCustomisations.height;
|
|
1152
|
+
const boxWidth = box.width;
|
|
1153
|
+
const boxHeight = box.height;
|
|
1154
|
+
let width;
|
|
1155
|
+
let height;
|
|
1156
|
+
if (customisationsWidth === null) {
|
|
1157
|
+
height = customisationsHeight === null ? "1em" : customisationsHeight === "auto" ? boxHeight : customisationsHeight;
|
|
1158
|
+
width = calculateSize(height, boxWidth / boxHeight);
|
|
1159
|
+
} else {
|
|
1160
|
+
width = customisationsWidth === "auto" ? boxWidth : customisationsWidth;
|
|
1161
|
+
height = customisationsHeight === null ? calculateSize(width, boxHeight / boxWidth) : customisationsHeight === "auto" ? boxHeight : customisationsHeight;
|
|
1162
|
+
}
|
|
1163
|
+
const attributes = {};
|
|
1164
|
+
const setAttr = (prop, value) => {
|
|
1165
|
+
if (!isUnsetKeyword(value)) attributes[prop] = value.toString();
|
|
1166
|
+
};
|
|
1167
|
+
setAttr("width", width);
|
|
1168
|
+
setAttr("height", height);
|
|
1169
|
+
const viewBox = [
|
|
1170
|
+
box.left,
|
|
1171
|
+
box.top,
|
|
1172
|
+
boxWidth,
|
|
1173
|
+
boxHeight
|
|
1174
|
+
];
|
|
1175
|
+
attributes.viewBox = viewBox.join(" ");
|
|
1176
|
+
return {
|
|
1177
|
+
attributes,
|
|
1178
|
+
viewBox,
|
|
1179
|
+
body
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
var regex = /\sid="(\S+)"/g;
|
|
1183
|
+
var randomPrefix = "IconifyId" + Date.now().toString(16) + (Math.random() * 16777216 | 0).toString(16);
|
|
1184
|
+
var counter = 0;
|
|
1185
|
+
function replaceIDs(body, prefix = randomPrefix) {
|
|
1186
|
+
const ids = [];
|
|
1187
|
+
let match;
|
|
1188
|
+
while (match = regex.exec(body)) ids.push(match[1]);
|
|
1189
|
+
if (!ids.length) return body;
|
|
1190
|
+
const suffix = "suffix" + (Math.random() * 16777216 | Date.now()).toString(16);
|
|
1191
|
+
ids.forEach((id) => {
|
|
1192
|
+
const newID = typeof prefix === "function" ? prefix(id) : prefix + (counter++).toString();
|
|
1193
|
+
const escapedID = id.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1194
|
+
body = body.replace(new RegExp('([#;"])(' + escapedID + ')([")]|\\.[a-z])', "g"), "$1" + newID + suffix + "$3");
|
|
1195
|
+
});
|
|
1196
|
+
body = body.replace(new RegExp(suffix, "g"), "");
|
|
1197
|
+
return body;
|
|
1198
|
+
}
|
|
1199
|
+
var storage = /* @__PURE__ */ Object.create(null);
|
|
1200
|
+
function setAPIModule(provider, item) {
|
|
1201
|
+
storage[provider] = item;
|
|
1202
|
+
}
|
|
1203
|
+
function getAPIModule(provider) {
|
|
1204
|
+
return storage[provider] || storage[""];
|
|
1205
|
+
}
|
|
1206
|
+
function createAPIConfig(source) {
|
|
1207
|
+
let resources;
|
|
1208
|
+
if (typeof source.resources === "string") resources = [source.resources];
|
|
1209
|
+
else {
|
|
1210
|
+
resources = source.resources;
|
|
1211
|
+
if (!(resources instanceof Array) || !resources.length) return null;
|
|
1212
|
+
}
|
|
1213
|
+
const result = {
|
|
1214
|
+
resources,
|
|
1215
|
+
path: source.path || "/",
|
|
1216
|
+
maxURL: source.maxURL || 500,
|
|
1217
|
+
rotate: source.rotate || 750,
|
|
1218
|
+
timeout: source.timeout || 5e3,
|
|
1219
|
+
random: source.random === true,
|
|
1220
|
+
index: source.index || 0,
|
|
1221
|
+
dataAfterTimeout: source.dataAfterTimeout !== false
|
|
1222
|
+
};
|
|
1223
|
+
return result;
|
|
1224
|
+
}
|
|
1225
|
+
var configStorage = /* @__PURE__ */ Object.create(null);
|
|
1226
|
+
var fallBackAPISources = ["https://api.simplesvg.com", "https://api.unisvg.com"];
|
|
1227
|
+
var fallBackAPI = [];
|
|
1228
|
+
while (fallBackAPISources.length > 0) if (fallBackAPISources.length === 1) fallBackAPI.push(fallBackAPISources.shift());
|
|
1229
|
+
else if (Math.random() > 0.5) fallBackAPI.push(fallBackAPISources.shift());
|
|
1230
|
+
else fallBackAPI.push(fallBackAPISources.pop());
|
|
1231
|
+
configStorage[""] = createAPIConfig({ resources: ["https://api.iconify.design"].concat(fallBackAPI) });
|
|
1232
|
+
function addAPIProvider(provider, customConfig) {
|
|
1233
|
+
const config = createAPIConfig(customConfig);
|
|
1234
|
+
if (config === null) return false;
|
|
1235
|
+
configStorage[provider] = config;
|
|
1236
|
+
return true;
|
|
1237
|
+
}
|
|
1238
|
+
function getAPIConfig(provider) {
|
|
1239
|
+
return configStorage[provider];
|
|
1240
|
+
}
|
|
1241
|
+
var detectFetch = () => {
|
|
1242
|
+
let callback;
|
|
1243
|
+
try {
|
|
1244
|
+
callback = fetch;
|
|
1245
|
+
if (typeof callback === "function") return callback;
|
|
1246
|
+
} catch (err) {
|
|
1247
|
+
}
|
|
1248
|
+
};
|
|
1249
|
+
var fetchModule = detectFetch();
|
|
1250
|
+
function calculateMaxLength(provider, prefix) {
|
|
1251
|
+
const config = getAPIConfig(provider);
|
|
1252
|
+
if (!config) return 0;
|
|
1253
|
+
let result;
|
|
1254
|
+
if (!config.maxURL) result = 0;
|
|
1255
|
+
else {
|
|
1256
|
+
let maxHostLength = 0;
|
|
1257
|
+
config.resources.forEach((item) => {
|
|
1258
|
+
const host = item;
|
|
1259
|
+
maxHostLength = Math.max(maxHostLength, host.length);
|
|
1260
|
+
});
|
|
1261
|
+
const url = prefix + ".json?icons=";
|
|
1262
|
+
result = config.maxURL - maxHostLength - config.path.length - url.length;
|
|
1263
|
+
}
|
|
1264
|
+
return result;
|
|
1265
|
+
}
|
|
1266
|
+
function shouldAbort(status) {
|
|
1267
|
+
return status === 404;
|
|
1268
|
+
}
|
|
1269
|
+
var prepare = (provider, prefix, icons) => {
|
|
1270
|
+
const results = [];
|
|
1271
|
+
const maxLength = calculateMaxLength(provider, prefix);
|
|
1272
|
+
const type = "icons";
|
|
1273
|
+
let item = {
|
|
1274
|
+
type,
|
|
1275
|
+
provider,
|
|
1276
|
+
prefix,
|
|
1277
|
+
icons: []
|
|
1278
|
+
};
|
|
1279
|
+
let length = 0;
|
|
1280
|
+
icons.forEach((name, index) => {
|
|
1281
|
+
length += name.length + 1;
|
|
1282
|
+
if (length >= maxLength && index > 0) {
|
|
1283
|
+
results.push(item);
|
|
1284
|
+
item = {
|
|
1285
|
+
type,
|
|
1286
|
+
provider,
|
|
1287
|
+
prefix,
|
|
1288
|
+
icons: []
|
|
1289
|
+
};
|
|
1290
|
+
length = name.length;
|
|
1291
|
+
}
|
|
1292
|
+
item.icons.push(name);
|
|
1293
|
+
});
|
|
1294
|
+
results.push(item);
|
|
1295
|
+
return results;
|
|
1296
|
+
};
|
|
1297
|
+
function getPath(provider) {
|
|
1298
|
+
if (typeof provider === "string") {
|
|
1299
|
+
const config = getAPIConfig(provider);
|
|
1300
|
+
if (config) return config.path;
|
|
1301
|
+
}
|
|
1302
|
+
return "/";
|
|
1303
|
+
}
|
|
1304
|
+
var send = (host, params, callback) => {
|
|
1305
|
+
if (!fetchModule) {
|
|
1306
|
+
callback("abort", 424);
|
|
1307
|
+
return;
|
|
1308
|
+
}
|
|
1309
|
+
let path = getPath(params.provider);
|
|
1310
|
+
switch (params.type) {
|
|
1311
|
+
case "icons": {
|
|
1312
|
+
const prefix = params.prefix;
|
|
1313
|
+
const icons = params.icons;
|
|
1314
|
+
const iconsList = icons.join(",");
|
|
1315
|
+
const urlParams = new URLSearchParams({ icons: iconsList });
|
|
1316
|
+
path += prefix + ".json?" + urlParams.toString();
|
|
1317
|
+
break;
|
|
1318
|
+
}
|
|
1319
|
+
case "custom": {
|
|
1320
|
+
const uri = params.uri;
|
|
1321
|
+
path += uri.slice(0, 1) === "/" ? uri.slice(1) : uri;
|
|
1322
|
+
break;
|
|
1323
|
+
}
|
|
1324
|
+
default:
|
|
1325
|
+
callback("abort", 400);
|
|
1326
|
+
return;
|
|
1327
|
+
}
|
|
1328
|
+
let defaultError = 503;
|
|
1329
|
+
fetchModule(host + path).then((response) => {
|
|
1330
|
+
const status = response.status;
|
|
1331
|
+
if (status !== 200) {
|
|
1332
|
+
setTimeout(() => {
|
|
1333
|
+
callback(shouldAbort(status) ? "abort" : "next", status);
|
|
1334
|
+
});
|
|
1335
|
+
return;
|
|
1336
|
+
}
|
|
1337
|
+
defaultError = 501;
|
|
1338
|
+
return response.json();
|
|
1339
|
+
}).then((data) => {
|
|
1340
|
+
if (typeof data !== "object" || data === null) {
|
|
1341
|
+
setTimeout(() => {
|
|
1342
|
+
if (data === 404) callback("abort", data);
|
|
1343
|
+
else callback("next", defaultError);
|
|
1344
|
+
});
|
|
1345
|
+
return;
|
|
1346
|
+
}
|
|
1347
|
+
setTimeout(() => {
|
|
1348
|
+
callback("success", data);
|
|
1349
|
+
});
|
|
1350
|
+
}).catch(() => {
|
|
1351
|
+
callback("next", defaultError);
|
|
1352
|
+
});
|
|
1353
|
+
};
|
|
1354
|
+
var fetchAPIModule = {
|
|
1355
|
+
prepare,
|
|
1356
|
+
send
|
|
1357
|
+
};
|
|
1358
|
+
function removeCallback(storages, id) {
|
|
1359
|
+
storages.forEach((storage2) => {
|
|
1360
|
+
const items = storage2.loaderCallbacks;
|
|
1361
|
+
if (items) storage2.loaderCallbacks = items.filter((row) => row.id !== id);
|
|
1362
|
+
});
|
|
1363
|
+
}
|
|
1364
|
+
function updateCallbacks(storage2) {
|
|
1365
|
+
if (!storage2.pendingCallbacksFlag) {
|
|
1366
|
+
storage2.pendingCallbacksFlag = true;
|
|
1367
|
+
setTimeout(() => {
|
|
1368
|
+
storage2.pendingCallbacksFlag = false;
|
|
1369
|
+
const items = storage2.loaderCallbacks ? storage2.loaderCallbacks.slice(0) : [];
|
|
1370
|
+
if (!items.length) return;
|
|
1371
|
+
let hasPending = false;
|
|
1372
|
+
const provider = storage2.provider;
|
|
1373
|
+
const prefix = storage2.prefix;
|
|
1374
|
+
items.forEach((item) => {
|
|
1375
|
+
const icons = item.icons;
|
|
1376
|
+
const oldLength = icons.pending.length;
|
|
1377
|
+
icons.pending = icons.pending.filter((icon) => {
|
|
1378
|
+
if (icon.prefix !== prefix) return true;
|
|
1379
|
+
const name = icon.name;
|
|
1380
|
+
if (storage2.icons[name]) icons.loaded.push({
|
|
1381
|
+
provider,
|
|
1382
|
+
prefix,
|
|
1383
|
+
name
|
|
1384
|
+
});
|
|
1385
|
+
else if (storage2.missing.has(name)) icons.missing.push({
|
|
1386
|
+
provider,
|
|
1387
|
+
prefix,
|
|
1388
|
+
name
|
|
1389
|
+
});
|
|
1390
|
+
else {
|
|
1391
|
+
hasPending = true;
|
|
1392
|
+
return true;
|
|
1393
|
+
}
|
|
1394
|
+
return false;
|
|
1395
|
+
});
|
|
1396
|
+
if (icons.pending.length !== oldLength) {
|
|
1397
|
+
if (!hasPending) removeCallback([storage2], item.id);
|
|
1398
|
+
item.callback(icons.loaded.slice(0), icons.missing.slice(0), icons.pending.slice(0), item.abort);
|
|
1399
|
+
}
|
|
1400
|
+
});
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
var idCounter = 0;
|
|
1405
|
+
function storeCallback(callback, icons, pendingSources) {
|
|
1406
|
+
const id = idCounter++;
|
|
1407
|
+
const abort = removeCallback.bind(null, pendingSources, id);
|
|
1408
|
+
if (!icons.pending.length) return abort;
|
|
1409
|
+
const item = {
|
|
1410
|
+
id,
|
|
1411
|
+
icons,
|
|
1412
|
+
callback,
|
|
1413
|
+
abort
|
|
1414
|
+
};
|
|
1415
|
+
pendingSources.forEach((storage2) => {
|
|
1416
|
+
(storage2.loaderCallbacks || (storage2.loaderCallbacks = [])).push(item);
|
|
1417
|
+
});
|
|
1418
|
+
return abort;
|
|
1419
|
+
}
|
|
1420
|
+
function sortIcons(icons) {
|
|
1421
|
+
const result = {
|
|
1422
|
+
loaded: [],
|
|
1423
|
+
missing: [],
|
|
1424
|
+
pending: []
|
|
1425
|
+
};
|
|
1426
|
+
const storage2 = /* @__PURE__ */ Object.create(null);
|
|
1427
|
+
icons.sort((a, b) => {
|
|
1428
|
+
if (a.provider !== b.provider) return a.provider.localeCompare(b.provider);
|
|
1429
|
+
if (a.prefix !== b.prefix) return a.prefix.localeCompare(b.prefix);
|
|
1430
|
+
return a.name.localeCompare(b.name);
|
|
1431
|
+
});
|
|
1432
|
+
let lastIcon = {
|
|
1433
|
+
provider: "",
|
|
1434
|
+
prefix: "",
|
|
1435
|
+
name: ""
|
|
1436
|
+
};
|
|
1437
|
+
icons.forEach((icon) => {
|
|
1438
|
+
if (lastIcon.name === icon.name && lastIcon.prefix === icon.prefix && lastIcon.provider === icon.provider) return;
|
|
1439
|
+
lastIcon = icon;
|
|
1440
|
+
const provider = icon.provider;
|
|
1441
|
+
const prefix = icon.prefix;
|
|
1442
|
+
const name = icon.name;
|
|
1443
|
+
const providerStorage = storage2[provider] || (storage2[provider] = /* @__PURE__ */ Object.create(null));
|
|
1444
|
+
const localStorage = providerStorage[prefix] || (providerStorage[prefix] = getStorage(provider, prefix));
|
|
1445
|
+
let list;
|
|
1446
|
+
if (name in localStorage.icons) list = result.loaded;
|
|
1447
|
+
else if (prefix === "" || localStorage.missing.has(name)) list = result.missing;
|
|
1448
|
+
else list = result.pending;
|
|
1449
|
+
const item = {
|
|
1450
|
+
provider,
|
|
1451
|
+
prefix,
|
|
1452
|
+
name
|
|
1453
|
+
};
|
|
1454
|
+
list.push(item);
|
|
1455
|
+
});
|
|
1456
|
+
return result;
|
|
1457
|
+
}
|
|
1458
|
+
function listToIcons(list, validate = true, simpleNames2 = false) {
|
|
1459
|
+
const result = [];
|
|
1460
|
+
list.forEach((item) => {
|
|
1461
|
+
const icon = typeof item === "string" ? stringToIcon(item, validate, simpleNames2) : item;
|
|
1462
|
+
if (icon) result.push(icon);
|
|
1463
|
+
});
|
|
1464
|
+
return result;
|
|
1465
|
+
}
|
|
1466
|
+
var defaultConfig = {
|
|
1467
|
+
resources: [],
|
|
1468
|
+
index: 0,
|
|
1469
|
+
timeout: 2e3,
|
|
1470
|
+
rotate: 750,
|
|
1471
|
+
random: false,
|
|
1472
|
+
dataAfterTimeout: false
|
|
1473
|
+
};
|
|
1474
|
+
function sendQuery(config, payload, query, done) {
|
|
1475
|
+
const resourcesCount = config.resources.length;
|
|
1476
|
+
const startIndex = config.random ? Math.floor(Math.random() * resourcesCount) : config.index;
|
|
1477
|
+
let resources;
|
|
1478
|
+
if (config.random) {
|
|
1479
|
+
let list = config.resources.slice(0);
|
|
1480
|
+
resources = [];
|
|
1481
|
+
while (list.length > 1) {
|
|
1482
|
+
const nextIndex = Math.floor(Math.random() * list.length);
|
|
1483
|
+
resources.push(list[nextIndex]);
|
|
1484
|
+
list = list.slice(0, nextIndex).concat(list.slice(nextIndex + 1));
|
|
1485
|
+
}
|
|
1486
|
+
resources = resources.concat(list);
|
|
1487
|
+
} else resources = config.resources.slice(startIndex).concat(config.resources.slice(0, startIndex));
|
|
1488
|
+
const startTime = Date.now();
|
|
1489
|
+
let status = "pending";
|
|
1490
|
+
let queriesSent = 0;
|
|
1491
|
+
let lastError;
|
|
1492
|
+
let timer = null;
|
|
1493
|
+
let queue = [];
|
|
1494
|
+
let doneCallbacks = [];
|
|
1495
|
+
if (typeof done === "function") doneCallbacks.push(done);
|
|
1496
|
+
function resetTimer() {
|
|
1497
|
+
if (timer) {
|
|
1498
|
+
clearTimeout(timer);
|
|
1499
|
+
timer = null;
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
function abort() {
|
|
1503
|
+
if (status === "pending") status = "aborted";
|
|
1504
|
+
resetTimer();
|
|
1505
|
+
queue.forEach((item) => {
|
|
1506
|
+
if (item.status === "pending") item.status = "aborted";
|
|
1507
|
+
});
|
|
1508
|
+
queue = [];
|
|
1509
|
+
}
|
|
1510
|
+
function subscribe(callback, overwrite) {
|
|
1511
|
+
if (overwrite) doneCallbacks = [];
|
|
1512
|
+
if (typeof callback === "function") doneCallbacks.push(callback);
|
|
1513
|
+
}
|
|
1514
|
+
function getQueryStatus() {
|
|
1515
|
+
return {
|
|
1516
|
+
startTime,
|
|
1517
|
+
payload,
|
|
1518
|
+
status,
|
|
1519
|
+
queriesSent,
|
|
1520
|
+
queriesPending: queue.length,
|
|
1521
|
+
subscribe,
|
|
1522
|
+
abort
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
function failQuery() {
|
|
1526
|
+
status = "failed";
|
|
1527
|
+
doneCallbacks.forEach((callback) => {
|
|
1528
|
+
callback(void 0, lastError);
|
|
1529
|
+
});
|
|
1530
|
+
}
|
|
1531
|
+
function clearQueue() {
|
|
1532
|
+
queue.forEach((item) => {
|
|
1533
|
+
if (item.status === "pending") item.status = "aborted";
|
|
1534
|
+
});
|
|
1535
|
+
queue = [];
|
|
1536
|
+
}
|
|
1537
|
+
function moduleResponse(item, response, data) {
|
|
1538
|
+
const isError = response !== "success";
|
|
1539
|
+
queue = queue.filter((queued) => queued !== item);
|
|
1540
|
+
switch (status) {
|
|
1541
|
+
case "pending":
|
|
1542
|
+
break;
|
|
1543
|
+
case "failed":
|
|
1544
|
+
if (isError || !config.dataAfterTimeout) return;
|
|
1545
|
+
break;
|
|
1546
|
+
default:
|
|
1547
|
+
return;
|
|
1548
|
+
}
|
|
1549
|
+
if (response === "abort") {
|
|
1550
|
+
lastError = data;
|
|
1551
|
+
failQuery();
|
|
1552
|
+
return;
|
|
1553
|
+
}
|
|
1554
|
+
if (isError) {
|
|
1555
|
+
lastError = data;
|
|
1556
|
+
if (!queue.length) if (!resources.length) failQuery();
|
|
1557
|
+
else execNext();
|
|
1558
|
+
return;
|
|
1559
|
+
}
|
|
1560
|
+
resetTimer();
|
|
1561
|
+
clearQueue();
|
|
1562
|
+
if (!config.random) {
|
|
1563
|
+
const index = config.resources.indexOf(item.resource);
|
|
1564
|
+
if (index !== -1 && index !== config.index) config.index = index;
|
|
1565
|
+
}
|
|
1566
|
+
status = "completed";
|
|
1567
|
+
doneCallbacks.forEach((callback) => {
|
|
1568
|
+
callback(data);
|
|
1569
|
+
});
|
|
1570
|
+
}
|
|
1571
|
+
function execNext() {
|
|
1572
|
+
if (status !== "pending") return;
|
|
1573
|
+
resetTimer();
|
|
1574
|
+
const resource = resources.shift();
|
|
1575
|
+
if (resource === void 0) {
|
|
1576
|
+
if (queue.length) {
|
|
1577
|
+
timer = setTimeout(() => {
|
|
1578
|
+
resetTimer();
|
|
1579
|
+
if (status === "pending") {
|
|
1580
|
+
clearQueue();
|
|
1581
|
+
failQuery();
|
|
1582
|
+
}
|
|
1583
|
+
}, config.timeout);
|
|
1584
|
+
return;
|
|
1585
|
+
}
|
|
1586
|
+
failQuery();
|
|
1587
|
+
return;
|
|
1588
|
+
}
|
|
1589
|
+
const item = {
|
|
1590
|
+
status: "pending",
|
|
1591
|
+
resource,
|
|
1592
|
+
callback: (status$1, data) => {
|
|
1593
|
+
moduleResponse(item, status$1, data);
|
|
1594
|
+
}
|
|
1595
|
+
};
|
|
1596
|
+
queue.push(item);
|
|
1597
|
+
queriesSent++;
|
|
1598
|
+
timer = setTimeout(execNext, config.rotate);
|
|
1599
|
+
query(resource, payload, item.callback);
|
|
1600
|
+
}
|
|
1601
|
+
setTimeout(execNext);
|
|
1602
|
+
return getQueryStatus;
|
|
1603
|
+
}
|
|
1604
|
+
function initRedundancy(cfg) {
|
|
1605
|
+
const config = {
|
|
1606
|
+
...defaultConfig,
|
|
1607
|
+
...cfg
|
|
1608
|
+
};
|
|
1609
|
+
let queries = [];
|
|
1610
|
+
function cleanup() {
|
|
1611
|
+
queries = queries.filter((item) => item().status === "pending");
|
|
1612
|
+
}
|
|
1613
|
+
function query(payload, queryCallback, doneCallback) {
|
|
1614
|
+
const query$1 = sendQuery(config, payload, queryCallback, (data, error) => {
|
|
1615
|
+
cleanup();
|
|
1616
|
+
if (doneCallback) doneCallback(data, error);
|
|
1617
|
+
});
|
|
1618
|
+
queries.push(query$1);
|
|
1619
|
+
return query$1;
|
|
1620
|
+
}
|
|
1621
|
+
function find(callback) {
|
|
1622
|
+
return queries.find((value) => {
|
|
1623
|
+
return callback(value);
|
|
1624
|
+
}) || null;
|
|
1625
|
+
}
|
|
1626
|
+
const instance = {
|
|
1627
|
+
query,
|
|
1628
|
+
find,
|
|
1629
|
+
setIndex: (index) => {
|
|
1630
|
+
config.index = index;
|
|
1631
|
+
},
|
|
1632
|
+
getIndex: () => config.index,
|
|
1633
|
+
cleanup
|
|
1634
|
+
};
|
|
1635
|
+
return instance;
|
|
1636
|
+
}
|
|
1637
|
+
function emptyCallback$1() {
|
|
1638
|
+
}
|
|
1639
|
+
var redundancyCache = /* @__PURE__ */ Object.create(null);
|
|
1640
|
+
function getRedundancyCache(provider) {
|
|
1641
|
+
if (!redundancyCache[provider]) {
|
|
1642
|
+
const config = getAPIConfig(provider);
|
|
1643
|
+
if (!config) return;
|
|
1644
|
+
const redundancy = initRedundancy(config);
|
|
1645
|
+
const cachedReundancy = {
|
|
1646
|
+
config,
|
|
1647
|
+
redundancy
|
|
1648
|
+
};
|
|
1649
|
+
redundancyCache[provider] = cachedReundancy;
|
|
1650
|
+
}
|
|
1651
|
+
return redundancyCache[provider];
|
|
1652
|
+
}
|
|
1653
|
+
function sendAPIQuery(target, query, callback) {
|
|
1654
|
+
let redundancy;
|
|
1655
|
+
let send2;
|
|
1656
|
+
if (typeof target === "string") {
|
|
1657
|
+
const api = getAPIModule(target);
|
|
1658
|
+
if (!api) {
|
|
1659
|
+
callback(void 0, 424);
|
|
1660
|
+
return emptyCallback$1;
|
|
1661
|
+
}
|
|
1662
|
+
send2 = api.send;
|
|
1663
|
+
const cached = getRedundancyCache(target);
|
|
1664
|
+
if (cached) redundancy = cached.redundancy;
|
|
1665
|
+
} else {
|
|
1666
|
+
const config = createAPIConfig(target);
|
|
1667
|
+
if (config) {
|
|
1668
|
+
redundancy = initRedundancy(config);
|
|
1669
|
+
const moduleKey = target.resources ? target.resources[0] : "";
|
|
1670
|
+
const api = getAPIModule(moduleKey);
|
|
1671
|
+
if (api) send2 = api.send;
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
if (!redundancy || !send2) {
|
|
1675
|
+
callback(void 0, 424);
|
|
1676
|
+
return emptyCallback$1;
|
|
1677
|
+
}
|
|
1678
|
+
return redundancy.query(query, send2, callback)().abort;
|
|
1679
|
+
}
|
|
1680
|
+
function emptyCallback() {
|
|
1681
|
+
}
|
|
1682
|
+
function loadedNewIcons(storage2) {
|
|
1683
|
+
if (!storage2.iconsLoaderFlag) {
|
|
1684
|
+
storage2.iconsLoaderFlag = true;
|
|
1685
|
+
setTimeout(() => {
|
|
1686
|
+
storage2.iconsLoaderFlag = false;
|
|
1687
|
+
updateCallbacks(storage2);
|
|
1688
|
+
});
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
function checkIconNamesForAPI(icons) {
|
|
1692
|
+
const valid = [];
|
|
1693
|
+
const invalid = [];
|
|
1694
|
+
icons.forEach((name) => {
|
|
1695
|
+
(name.match(matchIconName) ? valid : invalid).push(name);
|
|
1696
|
+
});
|
|
1697
|
+
return {
|
|
1698
|
+
valid,
|
|
1699
|
+
invalid
|
|
1700
|
+
};
|
|
1701
|
+
}
|
|
1702
|
+
function parseLoaderResponse(storage2, icons, data) {
|
|
1703
|
+
function checkMissing() {
|
|
1704
|
+
const pending = storage2.pendingIcons;
|
|
1705
|
+
icons.forEach((name) => {
|
|
1706
|
+
if (pending) pending.delete(name);
|
|
1707
|
+
if (!storage2.icons[name]) storage2.missing.add(name);
|
|
1708
|
+
});
|
|
1709
|
+
}
|
|
1710
|
+
if (data && typeof data === "object") try {
|
|
1711
|
+
const parsed = addIconSet(storage2, data);
|
|
1712
|
+
if (!parsed.length) {
|
|
1713
|
+
checkMissing();
|
|
1714
|
+
return;
|
|
1715
|
+
}
|
|
1716
|
+
} catch (err) {
|
|
1717
|
+
console.error(err);
|
|
1718
|
+
}
|
|
1719
|
+
checkMissing();
|
|
1720
|
+
loadedNewIcons(storage2);
|
|
1721
|
+
}
|
|
1722
|
+
function parsePossiblyAsyncResponse(response, callback) {
|
|
1723
|
+
if (response instanceof Promise) response.then((data) => {
|
|
1724
|
+
callback(data);
|
|
1725
|
+
}).catch(() => {
|
|
1726
|
+
callback(null);
|
|
1727
|
+
});
|
|
1728
|
+
else callback(response);
|
|
1729
|
+
}
|
|
1730
|
+
function loadNewIcons(storage2, icons) {
|
|
1731
|
+
if (!storage2.iconsToLoad) storage2.iconsToLoad = icons;
|
|
1732
|
+
else storage2.iconsToLoad = storage2.iconsToLoad.concat(icons).sort();
|
|
1733
|
+
if (!storage2.iconsQueueFlag) {
|
|
1734
|
+
storage2.iconsQueueFlag = true;
|
|
1735
|
+
setTimeout(() => {
|
|
1736
|
+
storage2.iconsQueueFlag = false;
|
|
1737
|
+
const { provider, prefix } = storage2;
|
|
1738
|
+
const icons$1 = storage2.iconsToLoad;
|
|
1739
|
+
delete storage2.iconsToLoad;
|
|
1740
|
+
if (!icons$1 || !icons$1.length) return;
|
|
1741
|
+
const customIconLoader = storage2.loadIcon;
|
|
1742
|
+
if (storage2.loadIcons && (icons$1.length > 1 || !customIconLoader)) {
|
|
1743
|
+
parsePossiblyAsyncResponse(storage2.loadIcons(icons$1, prefix, provider), (data) => {
|
|
1744
|
+
parseLoaderResponse(storage2, icons$1, data);
|
|
1745
|
+
});
|
|
1746
|
+
return;
|
|
1747
|
+
}
|
|
1748
|
+
if (customIconLoader) {
|
|
1749
|
+
icons$1.forEach((name) => {
|
|
1750
|
+
const response = customIconLoader(name, prefix, provider);
|
|
1751
|
+
parsePossiblyAsyncResponse(response, (data) => {
|
|
1752
|
+
const iconSet = data ? {
|
|
1753
|
+
prefix,
|
|
1754
|
+
icons: { [name]: data }
|
|
1755
|
+
} : null;
|
|
1756
|
+
parseLoaderResponse(storage2, [name], iconSet);
|
|
1757
|
+
});
|
|
1758
|
+
});
|
|
1759
|
+
return;
|
|
1760
|
+
}
|
|
1761
|
+
const { valid, invalid } = checkIconNamesForAPI(icons$1);
|
|
1762
|
+
if (invalid.length) parseLoaderResponse(storage2, invalid, null);
|
|
1763
|
+
if (!valid.length) return;
|
|
1764
|
+
const api = prefix.match(matchIconName) ? getAPIModule(provider) : null;
|
|
1765
|
+
if (!api) {
|
|
1766
|
+
parseLoaderResponse(storage2, valid, null);
|
|
1767
|
+
return;
|
|
1768
|
+
}
|
|
1769
|
+
const params = api.prepare(provider, prefix, valid);
|
|
1770
|
+
params.forEach((item) => {
|
|
1771
|
+
sendAPIQuery(provider, item, (data) => {
|
|
1772
|
+
parseLoaderResponse(storage2, item.icons, data);
|
|
1773
|
+
});
|
|
1774
|
+
});
|
|
1775
|
+
});
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
var loadIcons = (icons, callback) => {
|
|
1779
|
+
const cleanedIcons = listToIcons(icons, true, allowSimpleNames());
|
|
1780
|
+
const sortedIcons = sortIcons(cleanedIcons);
|
|
1781
|
+
if (!sortedIcons.pending.length) {
|
|
1782
|
+
let callCallback = true;
|
|
1783
|
+
if (callback) setTimeout(() => {
|
|
1784
|
+
if (callCallback) callback(sortedIcons.loaded, sortedIcons.missing, sortedIcons.pending, emptyCallback);
|
|
1785
|
+
});
|
|
1786
|
+
return () => {
|
|
1787
|
+
callCallback = false;
|
|
1788
|
+
};
|
|
1789
|
+
}
|
|
1790
|
+
const newIcons = /* @__PURE__ */ Object.create(null);
|
|
1791
|
+
const sources = [];
|
|
1792
|
+
let lastProvider, lastPrefix;
|
|
1793
|
+
sortedIcons.pending.forEach((icon) => {
|
|
1794
|
+
const { provider, prefix } = icon;
|
|
1795
|
+
if (prefix === lastPrefix && provider === lastProvider) return;
|
|
1796
|
+
lastProvider = provider;
|
|
1797
|
+
lastPrefix = prefix;
|
|
1798
|
+
sources.push(getStorage(provider, prefix));
|
|
1799
|
+
const providerNewIcons = newIcons[provider] || (newIcons[provider] = /* @__PURE__ */ Object.create(null));
|
|
1800
|
+
if (!providerNewIcons[prefix]) providerNewIcons[prefix] = [];
|
|
1801
|
+
});
|
|
1802
|
+
sortedIcons.pending.forEach((icon) => {
|
|
1803
|
+
const { provider, prefix, name } = icon;
|
|
1804
|
+
const storage2 = getStorage(provider, prefix);
|
|
1805
|
+
const pendingQueue = storage2.pendingIcons || (storage2.pendingIcons = /* @__PURE__ */ new Set());
|
|
1806
|
+
if (!pendingQueue.has(name)) {
|
|
1807
|
+
pendingQueue.add(name);
|
|
1808
|
+
newIcons[provider][prefix].push(name);
|
|
1809
|
+
}
|
|
1810
|
+
});
|
|
1811
|
+
sources.forEach((storage2) => {
|
|
1812
|
+
const list = newIcons[storage2.provider][storage2.prefix];
|
|
1813
|
+
if (list.length) loadNewIcons(storage2, list);
|
|
1814
|
+
});
|
|
1815
|
+
return callback ? storeCallback(callback, sortedIcons, sources) : emptyCallback;
|
|
1816
|
+
};
|
|
1817
|
+
function mergeCustomisations(defaults, item) {
|
|
1818
|
+
const result = { ...defaults };
|
|
1819
|
+
for (const key in item) {
|
|
1820
|
+
const value = item[key];
|
|
1821
|
+
const valueType = typeof value;
|
|
1822
|
+
if (key in defaultIconSizeCustomisations) {
|
|
1823
|
+
if (value === null || value && (valueType === "string" || valueType === "number")) result[key] = value;
|
|
1824
|
+
} else if (valueType === typeof result[key]) result[key] = key === "rotate" ? value % 4 : value;
|
|
1825
|
+
}
|
|
1826
|
+
return result;
|
|
1827
|
+
}
|
|
1828
|
+
var separator = /[\s,]+/;
|
|
1829
|
+
function flipFromString(custom, flip) {
|
|
1830
|
+
flip.split(separator).forEach((str) => {
|
|
1831
|
+
const value = str.trim();
|
|
1832
|
+
switch (value) {
|
|
1833
|
+
case "horizontal":
|
|
1834
|
+
custom.hFlip = true;
|
|
1835
|
+
break;
|
|
1836
|
+
case "vertical":
|
|
1837
|
+
custom.vFlip = true;
|
|
1838
|
+
break;
|
|
1839
|
+
}
|
|
1840
|
+
});
|
|
1841
|
+
}
|
|
1842
|
+
function rotateFromString(value, defaultValue = 0) {
|
|
1843
|
+
const units = value.replace(/^-?[0-9.]*/, "");
|
|
1844
|
+
function cleanup(value$1) {
|
|
1845
|
+
while (value$1 < 0) value$1 += 4;
|
|
1846
|
+
return value$1 % 4;
|
|
1847
|
+
}
|
|
1848
|
+
if (units === "") {
|
|
1849
|
+
const num = parseInt(value);
|
|
1850
|
+
return isNaN(num) ? 0 : cleanup(num);
|
|
1851
|
+
} else if (units !== value) {
|
|
1852
|
+
let split = 0;
|
|
1853
|
+
switch (units) {
|
|
1854
|
+
case "%":
|
|
1855
|
+
split = 25;
|
|
1856
|
+
break;
|
|
1857
|
+
case "deg":
|
|
1858
|
+
split = 90;
|
|
1859
|
+
}
|
|
1860
|
+
if (split) {
|
|
1861
|
+
let num = parseFloat(value.slice(0, value.length - units.length));
|
|
1862
|
+
if (isNaN(num)) return 0;
|
|
1863
|
+
num = num / split;
|
|
1864
|
+
return num % 1 === 0 ? cleanup(num) : 0;
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
return defaultValue;
|
|
1868
|
+
}
|
|
1869
|
+
function iconToHTML(body, attributes) {
|
|
1870
|
+
let renderAttribsHTML = body.indexOf("xlink:") === -1 ? "" : ' xmlns:xlink="http://www.w3.org/1999/xlink"';
|
|
1871
|
+
for (const attr in attributes) renderAttribsHTML += " " + attr + '="' + attributes[attr] + '"';
|
|
1872
|
+
return '<svg xmlns="http://www.w3.org/2000/svg"' + renderAttribsHTML + ">" + body + "</svg>";
|
|
1873
|
+
}
|
|
1874
|
+
function encodeSVGforURL(svg) {
|
|
1875
|
+
return svg.replace(/"/g, "'").replace(/%/g, "%25").replace(/#/g, "%23").replace(/</g, "%3C").replace(/>/g, "%3E").replace(/\s+/g, " ");
|
|
1876
|
+
}
|
|
1877
|
+
function svgToData(svg) {
|
|
1878
|
+
return "data:image/svg+xml," + encodeSVGforURL(svg);
|
|
1879
|
+
}
|
|
1880
|
+
function svgToURL(svg) {
|
|
1881
|
+
return 'url("' + svgToData(svg) + '")';
|
|
1882
|
+
}
|
|
1883
|
+
var policy;
|
|
1884
|
+
function createPolicy() {
|
|
1885
|
+
try {
|
|
1886
|
+
policy = window.trustedTypes.createPolicy("iconify", { createHTML: (s) => s });
|
|
1887
|
+
} catch (err) {
|
|
1888
|
+
policy = null;
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
function cleanUpInnerHTML(html) {
|
|
1892
|
+
if (policy === void 0) createPolicy();
|
|
1893
|
+
return policy ? policy.createHTML(html) : html;
|
|
1894
|
+
}
|
|
1895
|
+
var defaultExtendedIconCustomisations = {
|
|
1896
|
+
...defaultIconCustomisations,
|
|
1897
|
+
inline: false
|
|
1898
|
+
};
|
|
1899
|
+
var svgDefaults = {
|
|
1900
|
+
"xmlns": "http://www.w3.org/2000/svg",
|
|
1901
|
+
"xmlnsXlink": "http://www.w3.org/1999/xlink",
|
|
1902
|
+
"aria-hidden": true,
|
|
1903
|
+
"role": "img"
|
|
1904
|
+
};
|
|
1905
|
+
var commonProps = {
|
|
1906
|
+
display: "inline-block"
|
|
1907
|
+
};
|
|
1908
|
+
var monotoneProps = {
|
|
1909
|
+
backgroundColor: "currentColor"
|
|
1910
|
+
};
|
|
1911
|
+
var coloredProps = {
|
|
1912
|
+
backgroundColor: "transparent"
|
|
1913
|
+
};
|
|
1914
|
+
var propsToAdd = {
|
|
1915
|
+
Image: "var(--svg)",
|
|
1916
|
+
Repeat: "no-repeat",
|
|
1917
|
+
Size: "100% 100%"
|
|
1918
|
+
};
|
|
1919
|
+
var propsToAddTo = {
|
|
1920
|
+
WebkitMask: monotoneProps,
|
|
1921
|
+
mask: monotoneProps,
|
|
1922
|
+
background: coloredProps
|
|
1923
|
+
};
|
|
1924
|
+
for (const prefix in propsToAddTo) {
|
|
1925
|
+
const list = propsToAddTo[prefix];
|
|
1926
|
+
for (const prop in propsToAdd) {
|
|
1927
|
+
list[prefix + prop] = propsToAdd[prop];
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
var inlineDefaults = {
|
|
1931
|
+
...defaultExtendedIconCustomisations,
|
|
1932
|
+
inline: true
|
|
1933
|
+
};
|
|
1934
|
+
function fixSize(value) {
|
|
1935
|
+
return value + (value.match(/^[-0-9.]+$/) ? "px" : "");
|
|
1936
|
+
}
|
|
1937
|
+
var render = (icon, props, name) => {
|
|
1938
|
+
const defaultProps = props.inline ? inlineDefaults : defaultExtendedIconCustomisations;
|
|
1939
|
+
const customisations = mergeCustomisations(defaultProps, props);
|
|
1940
|
+
const mode = props.mode || "svg";
|
|
1941
|
+
const style = {};
|
|
1942
|
+
const customStyle = props.style || {};
|
|
1943
|
+
const componentProps = {
|
|
1944
|
+
...mode === "svg" ? svgDefaults : {}
|
|
1945
|
+
};
|
|
1946
|
+
if (name) {
|
|
1947
|
+
const iconName = stringToIcon(name, false, true);
|
|
1948
|
+
if (iconName) {
|
|
1949
|
+
const classNames = ["iconify"];
|
|
1950
|
+
const props2 = [
|
|
1951
|
+
"provider",
|
|
1952
|
+
"prefix"
|
|
1953
|
+
];
|
|
1954
|
+
for (const prop of props2) {
|
|
1955
|
+
if (iconName[prop]) {
|
|
1956
|
+
classNames.push("iconify--" + iconName[prop]);
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
componentProps.className = classNames.join(" ");
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
for (let key in props) {
|
|
1963
|
+
const value = props[key];
|
|
1964
|
+
if (value === void 0) {
|
|
1965
|
+
continue;
|
|
1966
|
+
}
|
|
1967
|
+
switch (key) {
|
|
1968
|
+
// Properties to ignore
|
|
1969
|
+
case "icon":
|
|
1970
|
+
case "style":
|
|
1971
|
+
case "children":
|
|
1972
|
+
case "onLoad":
|
|
1973
|
+
case "mode":
|
|
1974
|
+
case "ssr":
|
|
1975
|
+
case "fallback":
|
|
1976
|
+
break;
|
|
1977
|
+
// Forward ref
|
|
1978
|
+
case "_ref":
|
|
1979
|
+
componentProps.ref = value;
|
|
1980
|
+
break;
|
|
1981
|
+
// Merge class names
|
|
1982
|
+
case "className":
|
|
1983
|
+
componentProps[key] = (componentProps[key] ? componentProps[key] + " " : "") + value;
|
|
1984
|
+
break;
|
|
1985
|
+
// Boolean attributes
|
|
1986
|
+
case "inline":
|
|
1987
|
+
case "hFlip":
|
|
1988
|
+
case "vFlip":
|
|
1989
|
+
customisations[key] = value === true || value === "true" || value === 1;
|
|
1990
|
+
break;
|
|
1991
|
+
// Flip as string: 'horizontal,vertical'
|
|
1992
|
+
case "flip":
|
|
1993
|
+
if (typeof value === "string") {
|
|
1994
|
+
flipFromString(customisations, value);
|
|
1995
|
+
}
|
|
1996
|
+
break;
|
|
1997
|
+
// Color: copy to style
|
|
1998
|
+
case "color":
|
|
1999
|
+
style.color = value;
|
|
2000
|
+
break;
|
|
2001
|
+
// Rotation as string
|
|
2002
|
+
case "rotate":
|
|
2003
|
+
if (typeof value === "string") {
|
|
2004
|
+
customisations[key] = rotateFromString(value);
|
|
2005
|
+
} else if (typeof value === "number") {
|
|
2006
|
+
customisations[key] = value;
|
|
2007
|
+
}
|
|
2008
|
+
break;
|
|
2009
|
+
// Remove aria-hidden
|
|
2010
|
+
case "ariaHidden":
|
|
2011
|
+
case "aria-hidden":
|
|
2012
|
+
if (value !== true && value !== "true") {
|
|
2013
|
+
delete componentProps["aria-hidden"];
|
|
2014
|
+
}
|
|
2015
|
+
break;
|
|
2016
|
+
// Copy missing property if it does not exist in customisations
|
|
2017
|
+
default:
|
|
2018
|
+
if (defaultProps[key] === void 0) {
|
|
2019
|
+
componentProps[key] = value;
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
const item = iconToSVG(icon, customisations);
|
|
2024
|
+
const renderAttribs = item.attributes;
|
|
2025
|
+
if (customisations.inline) {
|
|
2026
|
+
style.verticalAlign = "-0.125em";
|
|
2027
|
+
}
|
|
2028
|
+
if (mode === "svg") {
|
|
2029
|
+
componentProps.style = {
|
|
2030
|
+
...style,
|
|
2031
|
+
...customStyle
|
|
2032
|
+
};
|
|
2033
|
+
Object.assign(componentProps, renderAttribs);
|
|
2034
|
+
let localCounter = 0;
|
|
2035
|
+
let id = props.id;
|
|
2036
|
+
if (typeof id === "string") {
|
|
2037
|
+
id = id.replace(/-/g, "_");
|
|
2038
|
+
}
|
|
2039
|
+
componentProps.dangerouslySetInnerHTML = {
|
|
2040
|
+
__html: cleanUpInnerHTML(replaceIDs(item.body, id ? () => id + "ID" + localCounter++ : "iconifyReact"))
|
|
2041
|
+
};
|
|
2042
|
+
return createElement("svg", componentProps);
|
|
2043
|
+
}
|
|
2044
|
+
const { body, width, height } = icon;
|
|
2045
|
+
const useMask = mode === "mask" || (mode === "bg" ? false : body.indexOf("currentColor") !== -1);
|
|
2046
|
+
const html = iconToHTML(body, {
|
|
2047
|
+
...renderAttribs,
|
|
2048
|
+
width: width + "",
|
|
2049
|
+
height: height + ""
|
|
2050
|
+
});
|
|
2051
|
+
componentProps.style = {
|
|
2052
|
+
...style,
|
|
2053
|
+
"--svg": svgToURL(html),
|
|
2054
|
+
"width": fixSize(renderAttribs.width),
|
|
2055
|
+
"height": fixSize(renderAttribs.height),
|
|
2056
|
+
...commonProps,
|
|
2057
|
+
...useMask ? monotoneProps : coloredProps,
|
|
2058
|
+
...customStyle
|
|
2059
|
+
};
|
|
2060
|
+
return createElement("span", componentProps);
|
|
2061
|
+
};
|
|
2062
|
+
allowSimpleNames(true);
|
|
2063
|
+
setAPIModule("", fetchAPIModule);
|
|
2064
|
+
if (typeof document !== "undefined" && typeof window !== "undefined") {
|
|
2065
|
+
const _window = window;
|
|
2066
|
+
if (_window.IconifyPreload !== void 0) {
|
|
2067
|
+
const preload = _window.IconifyPreload;
|
|
2068
|
+
const err = "Invalid IconifyPreload syntax.";
|
|
2069
|
+
if (typeof preload === "object" && preload !== null) {
|
|
2070
|
+
(preload instanceof Array ? preload : [preload]).forEach((item) => {
|
|
2071
|
+
try {
|
|
2072
|
+
if (
|
|
2073
|
+
// Check if item is an object and not null/array
|
|
2074
|
+
typeof item !== "object" || item === null || item instanceof Array || // Check for 'icons' and 'prefix'
|
|
2075
|
+
typeof item.icons !== "object" || typeof item.prefix !== "string" || // Add icon set
|
|
2076
|
+
!addCollection(item)
|
|
2077
|
+
) {
|
|
2078
|
+
console.error(err);
|
|
2079
|
+
}
|
|
2080
|
+
} catch (e) {
|
|
2081
|
+
console.error(err);
|
|
2082
|
+
}
|
|
2083
|
+
});
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
if (_window.IconifyProviders !== void 0) {
|
|
2087
|
+
const providers = _window.IconifyProviders;
|
|
2088
|
+
if (typeof providers === "object" && providers !== null) {
|
|
2089
|
+
for (let key in providers) {
|
|
2090
|
+
const err = "IconifyProviders[" + key + "] is invalid.";
|
|
2091
|
+
try {
|
|
2092
|
+
const value = providers[key];
|
|
2093
|
+
if (typeof value !== "object" || !value || value.resources === void 0) {
|
|
2094
|
+
continue;
|
|
2095
|
+
}
|
|
2096
|
+
if (!addAPIProvider(key, value)) {
|
|
2097
|
+
console.error(err);
|
|
2098
|
+
}
|
|
2099
|
+
} catch (e) {
|
|
2100
|
+
console.error(err);
|
|
2101
|
+
}
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
function IconComponent(props) {
|
|
2107
|
+
const [mounted, setMounted] = useState(!!props.ssr);
|
|
2108
|
+
const [abort, setAbort] = useState({});
|
|
2109
|
+
function getInitialState(mounted2) {
|
|
2110
|
+
if (mounted2) {
|
|
2111
|
+
const name2 = props.icon;
|
|
2112
|
+
if (typeof name2 === "object") {
|
|
2113
|
+
return {
|
|
2114
|
+
name: "",
|
|
2115
|
+
data: name2
|
|
2116
|
+
};
|
|
2117
|
+
}
|
|
2118
|
+
const data2 = getIconData(name2);
|
|
2119
|
+
if (data2) {
|
|
2120
|
+
return {
|
|
2121
|
+
name: name2,
|
|
2122
|
+
data: data2
|
|
2123
|
+
};
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
return {
|
|
2127
|
+
name: ""
|
|
2128
|
+
};
|
|
2129
|
+
}
|
|
2130
|
+
const [state, setState] = useState(getInitialState(!!props.ssr));
|
|
2131
|
+
function cleanup() {
|
|
2132
|
+
const callback = abort.callback;
|
|
2133
|
+
if (callback) {
|
|
2134
|
+
callback();
|
|
2135
|
+
setAbort({});
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
function changeState(newState) {
|
|
2139
|
+
if (JSON.stringify(state) !== JSON.stringify(newState)) {
|
|
2140
|
+
cleanup();
|
|
2141
|
+
setState(newState);
|
|
2142
|
+
return true;
|
|
2143
|
+
}
|
|
2144
|
+
}
|
|
2145
|
+
function updateState() {
|
|
2146
|
+
var _a;
|
|
2147
|
+
const name2 = props.icon;
|
|
2148
|
+
if (typeof name2 === "object") {
|
|
2149
|
+
changeState({
|
|
2150
|
+
name: "",
|
|
2151
|
+
data: name2
|
|
2152
|
+
});
|
|
2153
|
+
return;
|
|
2154
|
+
}
|
|
2155
|
+
const data2 = getIconData(name2);
|
|
2156
|
+
if (changeState({
|
|
2157
|
+
name: name2,
|
|
2158
|
+
data: data2
|
|
2159
|
+
})) {
|
|
2160
|
+
if (data2 === void 0) {
|
|
2161
|
+
const callback = loadIcons([name2], updateState);
|
|
2162
|
+
setAbort({
|
|
2163
|
+
callback
|
|
2164
|
+
});
|
|
2165
|
+
} else if (data2) {
|
|
2166
|
+
(_a = props.onLoad) === null || _a === void 0 ? void 0 : _a.call(props, name2);
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2169
|
+
}
|
|
2170
|
+
useEffect(() => {
|
|
2171
|
+
setMounted(true);
|
|
2172
|
+
return cleanup;
|
|
2173
|
+
}, []);
|
|
2174
|
+
useEffect(() => {
|
|
2175
|
+
if (mounted) {
|
|
2176
|
+
updateState();
|
|
2177
|
+
}
|
|
2178
|
+
}, [props.icon, mounted]);
|
|
2179
|
+
const { name, data } = state;
|
|
2180
|
+
if (!data) {
|
|
2181
|
+
return props.children ? props.children : props.fallback ? props.fallback : createElement("span", {});
|
|
2182
|
+
}
|
|
2183
|
+
return render({
|
|
2184
|
+
...defaultIconProps,
|
|
2185
|
+
...data
|
|
2186
|
+
}, props, name);
|
|
2187
|
+
}
|
|
2188
|
+
var Icon = forwardRef((props, ref) => IconComponent({
|
|
2189
|
+
...props,
|
|
2190
|
+
_ref: ref
|
|
2191
|
+
}));
|
|
2192
|
+
forwardRef((props, ref) => IconComponent({
|
|
2193
|
+
inline: true,
|
|
2194
|
+
...props,
|
|
2195
|
+
_ref: ref
|
|
2196
|
+
}));
|
|
2197
|
+
function Icon2(props) {
|
|
2198
|
+
return /* @__PURE__ */ jsx(Icon, { fallback: /* @__PURE__ */ jsx(Skeleton, { className: props.className }), ...props });
|
|
2199
|
+
}
|
|
2200
|
+
var APP_ICON_FRAME = "flex items-center justify-center border border-border rounded-md shrink-0 size-10";
|
|
2201
|
+
function AppIconFrame({
|
|
2202
|
+
className,
|
|
2203
|
+
children
|
|
2204
|
+
}) {
|
|
2205
|
+
return /* @__PURE__ */ jsx("div", { className: cn(APP_ICON_FRAME, className), children });
|
|
2206
|
+
}
|
|
2207
|
+
var BRAND_ICONS = {
|
|
2208
|
+
google: "logos:google-icon",
|
|
2209
|
+
gmail: "logos:google-gmail",
|
|
2210
|
+
"google-calendar": "logos:google-calendar",
|
|
2211
|
+
"google-drive": "logos:google-drive",
|
|
2212
|
+
slack: "logos:slack-icon",
|
|
2213
|
+
notion: "logos:notion-icon",
|
|
2214
|
+
github: "simple-icons:github",
|
|
2215
|
+
gitlab: "logos:gitlab-icon",
|
|
2216
|
+
linear: "simple-icons:linear",
|
|
2217
|
+
asana: "logos:asana-icon",
|
|
2218
|
+
hubspot: "logos:hubspot",
|
|
2219
|
+
airtable: "logos:airtable",
|
|
2220
|
+
todoist: "simple-icons:todoist",
|
|
2221
|
+
clickup: "simple-icons:clickup",
|
|
2222
|
+
dropbox: "logos:dropbox",
|
|
2223
|
+
bitbucket: "logos:bitbucket",
|
|
2224
|
+
sentry: "logos:sentry-icon",
|
|
2225
|
+
spotify: "logos:spotify-icon",
|
|
2226
|
+
reddit: "logos:reddit-icon",
|
|
2227
|
+
netlify: "logos:netlify-icon",
|
|
2228
|
+
calendly: "simple-icons:calendly",
|
|
2229
|
+
salesforce: "logos:salesforce",
|
|
2230
|
+
zoom: "logos:zoom-icon",
|
|
2231
|
+
intercom: "simple-icons:intercom",
|
|
2232
|
+
"microsoft-teams": "logos:microsoft-teams",
|
|
2233
|
+
box: "logos:box",
|
|
2234
|
+
mailchimp: "logos:mailchimp-freddie",
|
|
2235
|
+
// pipedrive logo includes black wordmark text — invisible on dark
|
|
2236
|
+
// bg. Use the masked /public asset instead (see ASSET_ICONS below).
|
|
2237
|
+
xero: "simple-icons:xero",
|
|
2238
|
+
pagerduty: "simple-icons:pagerduty",
|
|
2239
|
+
typeform: "simple-icons:typeform",
|
|
2240
|
+
// harvest — no Iconify slug; monogram letter fallback.
|
|
2241
|
+
eventbrite: "simple-icons:eventbrite",
|
|
2242
|
+
// klaviyo / freshbooks / harvest — no Iconify slug exists across
|
|
2243
|
+
// simple-icons / logos / arcticons. Fall through to monogram letter.
|
|
2244
|
+
square: "simple-icons:square",
|
|
2245
|
+
front: "arcticons:front",
|
|
2246
|
+
basecamp: "simple-icons:basecamp",
|
|
2247
|
+
jira: "logos:jira",
|
|
2248
|
+
confluence: "logos:confluence",
|
|
2249
|
+
figma: "logos:figma",
|
|
2250
|
+
vercel: "simple-icons:vercel",
|
|
2251
|
+
sendgrid: "logos:sendgrid-icon",
|
|
2252
|
+
stripe: "logos:stripe",
|
|
2253
|
+
"outlook-mail": "vscode-icons:file-type-outlook",
|
|
2254
|
+
"outlook-calendar": "vscode-icons:file-type-outlook",
|
|
2255
|
+
// The outlook-mail catalog row seeds `icon: 'outlook'`, and `icon` wins
|
|
2256
|
+
// over `kind` — without this alias it falls through to the monogram.
|
|
2257
|
+
// Seeded rows already carry the value in the DB, so fixing the seed
|
|
2258
|
+
// wouldn't repair existing installs.
|
|
2259
|
+
outlook: "vscode-icons:file-type-outlook",
|
|
2260
|
+
onedrive: "logos:microsoft-onedrive",
|
|
2261
|
+
// `logos` has no sharepoint mark — selfhst carries the full-colour brand
|
|
2262
|
+
// icon, so this stays visually consistent with the logos entries around it.
|
|
2263
|
+
sharepoint: "selfhst:microsoft-sharepoint",
|
|
2264
|
+
mcp: "codicon:mcp",
|
|
2265
|
+
// Channel platforms (not in app catalog but rendered with the same component)
|
|
2266
|
+
discord: "logos:discord-icon",
|
|
2267
|
+
telegram: "logos:telegram",
|
|
2268
|
+
whatsapp: "logos:whatsapp-icon",
|
|
2269
|
+
teams: "logos:microsoft-teams",
|
|
2270
|
+
email: "mingcute:mail-line",
|
|
2271
|
+
webhook: "material-symbols:webhook",
|
|
2272
|
+
cron: "mingcute:time-line",
|
|
2273
|
+
form: "mingcute:list-check-line",
|
|
2274
|
+
// 10 data-source adapters
|
|
2275
|
+
postgres: "logos:postgresql",
|
|
2276
|
+
mysql: "logos:mysql",
|
|
2277
|
+
mongodb: "logos:mongodb-icon",
|
|
2278
|
+
supabase: "logos:supabase-icon",
|
|
2279
|
+
// `logos:` has no Sheets entry. Monochrome mdi mark, matching the one
|
|
2280
|
+
// the artifact library uses for spreadsheets (artifact-format-icon.tsx)
|
|
2281
|
+
// — full-color alternatives sit in a different visual generation from
|
|
2282
|
+
// the rest of the set.
|
|
2283
|
+
"google-sheets": "mdi:google-spreadsheet",
|
|
2284
|
+
"google-analytics": "logos:google-analytics",
|
|
2285
|
+
// bigquery + gcs have no dedicated logos: slug; use google-cloud mark
|
|
2286
|
+
bigquery: "logos:google-cloud",
|
|
2287
|
+
gcs: "logos:google-cloud",
|
|
2288
|
+
posthog: "simple-icons:posthog",
|
|
2289
|
+
shopify: "logos:shopify"
|
|
2290
|
+
};
|
|
2291
|
+
var BRAND_ICON_TINT = {
|
|
2292
|
+
"google-sheets": "text-[#0F9D58]"
|
|
2293
|
+
};
|
|
2294
|
+
var ASSET_ICONS = {
|
|
2295
|
+
rill: { src: "/rill-svg.svg", color: "#4C40F8" },
|
|
2296
|
+
klaviyo: { src: "/klaviyo.svg", color: "#5C4FE7" },
|
|
2297
|
+
freshbooks: { src: "/freshbooks.svg", color: "#0075DD" },
|
|
2298
|
+
harvest: { src: "/harvest.svg", color: "#FA5D00" },
|
|
2299
|
+
pipedrive: { src: "/pipedrive.svg", color: "#1A1A1A" },
|
|
2300
|
+
// Verification plugin family — neutral @frontera/icons glyphs, one per
|
|
2301
|
+
// plugin so the three read as distinct capabilities in the catalog.
|
|
2302
|
+
"document-intelligence": { src: "/document-intelligence.svg", color: "#2563EB" },
|
|
2303
|
+
"bank-statement-analysis": { src: "/bank-statement-analysis.svg", color: "#059669" },
|
|
2304
|
+
"extraction-templates": { src: "/extraction-templates.svg", color: "#7C3AED" }
|
|
2305
|
+
};
|
|
2306
|
+
var SIZE = {
|
|
2307
|
+
sm: { box: "size-6", icon: "size-3.5", text: "text-xs" },
|
|
2308
|
+
md: { box: "size-8", icon: "size-5", text: "text-xs" },
|
|
2309
|
+
lg: { box: "size-10", icon: "size-8", text: "text-sm" }
|
|
2310
|
+
};
|
|
2311
|
+
function getAppBrandIconId(kind, icon) {
|
|
2312
|
+
const iconKey = kind;
|
|
2313
|
+
return BRAND_ICONS[iconKey] ?? null;
|
|
2314
|
+
}
|
|
2315
|
+
function AppIcon({
|
|
2316
|
+
kind,
|
|
2317
|
+
icon,
|
|
2318
|
+
iconUrl,
|
|
2319
|
+
displayName,
|
|
2320
|
+
size = "sm",
|
|
2321
|
+
className = ""
|
|
2322
|
+
}) {
|
|
2323
|
+
const dims = SIZE[size];
|
|
2324
|
+
const iconKey = icon || kind;
|
|
2325
|
+
if (iconUrl) {
|
|
2326
|
+
return (
|
|
2327
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
2328
|
+
/* @__PURE__ */ jsx(
|
|
2329
|
+
"img",
|
|
2330
|
+
{
|
|
2331
|
+
src: iconUrl,
|
|
2332
|
+
alt: displayName ?? kind,
|
|
2333
|
+
draggable: false,
|
|
2334
|
+
className: `inline-block object-contain ${dims.icon} ${className}`
|
|
2335
|
+
}
|
|
2336
|
+
)
|
|
2337
|
+
);
|
|
2338
|
+
}
|
|
2339
|
+
const asset = ASSET_ICONS[iconKey];
|
|
2340
|
+
if (asset) {
|
|
2341
|
+
return /* @__PURE__ */ jsx(
|
|
2342
|
+
"span",
|
|
2343
|
+
{
|
|
2344
|
+
className: `inline-flex items-center justify-center overflow-hidden rounded-md ${dims.box} ${className}`,
|
|
2345
|
+
style: { backgroundColor: asset.color },
|
|
2346
|
+
"aria-label": displayName ?? kind,
|
|
2347
|
+
role: "img",
|
|
2348
|
+
children: /* @__PURE__ */ jsx(
|
|
2349
|
+
"span",
|
|
2350
|
+
{
|
|
2351
|
+
"aria-hidden": true,
|
|
2352
|
+
className: `${dims.icon} block`,
|
|
2353
|
+
style: {
|
|
2354
|
+
WebkitMaskImage: `url(${asset.src})`,
|
|
2355
|
+
maskImage: `url(${asset.src})`,
|
|
2356
|
+
WebkitMaskRepeat: "no-repeat",
|
|
2357
|
+
maskRepeat: "no-repeat",
|
|
2358
|
+
WebkitMaskSize: "contain",
|
|
2359
|
+
maskSize: "contain",
|
|
2360
|
+
WebkitMaskPosition: "center",
|
|
2361
|
+
maskPosition: "center",
|
|
2362
|
+
backgroundColor: "#ffffff"
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2365
|
+
)
|
|
2366
|
+
}
|
|
2367
|
+
);
|
|
2368
|
+
}
|
|
2369
|
+
const brand = BRAND_ICONS[iconKey];
|
|
2370
|
+
if (brand) {
|
|
2371
|
+
return /* @__PURE__ */ jsx(
|
|
2372
|
+
"span",
|
|
2373
|
+
{
|
|
2374
|
+
className: cn(
|
|
2375
|
+
"inline-flex items-center justify-center",
|
|
2376
|
+
BRAND_ICON_TINT[iconKey] ?? "text-foreground"
|
|
2377
|
+
),
|
|
2378
|
+
children: /* @__PURE__ */ jsx(Icon2, { icon: brand, className: dims.icon })
|
|
2379
|
+
}
|
|
2380
|
+
);
|
|
2381
|
+
}
|
|
2382
|
+
const letter = (displayName?.[0] ?? kind[0] ?? "?").toUpperCase();
|
|
2383
|
+
return /* @__PURE__ */ jsx(
|
|
2384
|
+
"span",
|
|
2385
|
+
{
|
|
2386
|
+
className: `inline-flex items-center justify-center rounded-md border bg-muted text-foreground font-mono font-medium ${dims.box} ${dims.text} ${className}`,
|
|
2387
|
+
children: letter
|
|
2388
|
+
}
|
|
2389
|
+
);
|
|
2390
|
+
}
|
|
2391
|
+
var RUNNING_STATES = /* @__PURE__ */ new Set([
|
|
2392
|
+
"input-streaming",
|
|
2393
|
+
"partial-call",
|
|
2394
|
+
"input-available",
|
|
2395
|
+
"call"
|
|
2396
|
+
]);
|
|
2397
|
+
var TIMELINE_ICON_BEAD = "flex w-4 h-7 shrink-0 items-center justify-center rounded-full bg-surface-chat";
|
|
2398
|
+
function getSkillContent(output) {
|
|
2399
|
+
if (!output || typeof output !== "object") return null;
|
|
2400
|
+
let o = output;
|
|
2401
|
+
if ("value" in o && o.value && typeof o.value === "object") {
|
|
2402
|
+
o = o.value;
|
|
2403
|
+
}
|
|
2404
|
+
return typeof o.content === "string" && o.content.trim() ? o.content : null;
|
|
2405
|
+
}
|
|
2406
|
+
function SkillToolItem({
|
|
2407
|
+
state,
|
|
2408
|
+
input,
|
|
2409
|
+
output,
|
|
2410
|
+
className
|
|
2411
|
+
}) {
|
|
2412
|
+
const [open, setOpen] = useState(false);
|
|
2413
|
+
const slug = extractSkillSlug(input);
|
|
2414
|
+
const displayName = resolveSkillLabel(input, output);
|
|
2415
|
+
const appKind = slug ? skillSlugToAppKind(slug) : "";
|
|
2416
|
+
const brandIconId = appKind ? getAppBrandIconId(appKind) : null;
|
|
2417
|
+
const isRunning = RUNNING_STATES.has(state);
|
|
2418
|
+
const isError = state === "output-error" || state === "error";
|
|
2419
|
+
const content = getSkillContent(output);
|
|
2420
|
+
const hasContent = !!content && !isError;
|
|
2421
|
+
const prefix = isError ? "Skill failed" : isRunning ? "Loading" : "Used";
|
|
2422
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("relative z-10", className), children: [
|
|
2423
|
+
/* @__PURE__ */ jsxs(
|
|
2424
|
+
"button",
|
|
2425
|
+
{
|
|
2426
|
+
type: "button",
|
|
2427
|
+
onClick: () => hasContent && setOpen((v) => !v),
|
|
2428
|
+
"aria-expanded": hasContent ? open : void 0,
|
|
2429
|
+
className: cn(
|
|
2430
|
+
"group/row flex w-full min-w-0 items-center gap-2 py-0.5 text-left text-sm text-muted-foreground",
|
|
2431
|
+
hasContent ? "transition-colors hover:text-foreground" : "cursor-default"
|
|
2432
|
+
),
|
|
2433
|
+
children: [
|
|
2434
|
+
/* @__PURE__ */ jsx("span", { className: TIMELINE_ICON_BEAD, children: brandIconId ? /* @__PURE__ */ jsx(frontera_icon_default, { icon: brandIconId, className: "size-3.5 opacity-90" }) : /* @__PURE__ */ jsx(Book3Icon, { className: "size-3.5 opacity-80" }) }),
|
|
2435
|
+
isRunning ? /* @__PURE__ */ jsx(Shimmer, { as: "span", className: "min-w-0 truncate text-sm", children: displayName ? `${prefix} ${displayName} skill` : `${prefix} skill\u2026` }) : /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: isError ? /* @__PURE__ */ jsx("span", { className: " text-destructive", children: prefix }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2436
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
2437
|
+
prefix,
|
|
2438
|
+
" "
|
|
2439
|
+
] }),
|
|
2440
|
+
displayName ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2441
|
+
/* @__PURE__ */ jsx("span", { className: " text-foreground", children: displayName }),
|
|
2442
|
+
/* @__PURE__ */ jsx("span", { children: " skill" })
|
|
2443
|
+
] }) : /* @__PURE__ */ jsx("span", { className: "", children: "skill" })
|
|
2444
|
+
] }) }),
|
|
2445
|
+
hasContent && /* @__PURE__ */ jsx(
|
|
2446
|
+
ChevronDownMediumIcon,
|
|
2447
|
+
{
|
|
2448
|
+
className: cn(
|
|
2449
|
+
"size-3.5 shrink-0 text-muted-foreground/60 transition-transform",
|
|
2450
|
+
!open && "-rotate-90"
|
|
2451
|
+
)
|
|
2452
|
+
}
|
|
2453
|
+
)
|
|
2454
|
+
]
|
|
2455
|
+
}
|
|
2456
|
+
),
|
|
2457
|
+
hasContent && /* @__PURE__ */ jsx(Collapse, { open, children: /* @__PURE__ */ jsx("div", { className: "mt-1.5 ml-6 rounded-lg border border-muted-foreground/10 bg-surface-raised overflow-hidden shadow-xs", children: /* @__PURE__ */ jsx(ScrollFadeEdges, { className: "max-h-52 p-4", children: /* @__PURE__ */ jsx(
|
|
2458
|
+
MessageResponse,
|
|
2459
|
+
{
|
|
2460
|
+
className: "prose prose-sm dark:prose-invert max-w-none leading-relaxed prose-headings:font-medium prose-p:text-muted-foreground prose-li:text-muted-foreground",
|
|
2461
|
+
children: content
|
|
2462
|
+
}
|
|
2463
|
+
) }) }) })
|
|
2464
|
+
] });
|
|
2465
|
+
}
|
|
2466
|
+
function BlueprintIcon({ className, ...rest }) {
|
|
2467
|
+
return /* @__PURE__ */ jsxs(
|
|
2468
|
+
"svg",
|
|
2469
|
+
{
|
|
2470
|
+
viewBox: "0 0 24 24",
|
|
2471
|
+
fill: "none",
|
|
2472
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2473
|
+
"aria-hidden": true,
|
|
2474
|
+
className: cn("shrink-0", className),
|
|
2475
|
+
...rest,
|
|
2476
|
+
children: [
|
|
2477
|
+
/* @__PURE__ */ jsx(
|
|
2478
|
+
"path",
|
|
2479
|
+
{
|
|
2480
|
+
d: "M21.9165 3.57282C21.9665 3.38787 21.9731 3.19389 21.9361 3.00593C21.899 2.81797 21.8191 2.64108 21.7026 2.48898C21.5861 2.33687 21.4361 2.21364 21.2644 2.12885C21.0926 2.04405 20.9036 1.99996 20.712 2H7.82207C4.6072 2 2.00057 3.48949 2.00057 5.32678V5.94952L3.30588 15.3066H17.2431C17.5059 15.3066 17.7619 15.2236 17.9747 15.0695C18.1875 14.9154 18.3462 14.698 18.4282 14.4484L21.8975 3.63719C21.9592 3.44978 21.9755 3.25042 21.9451 3.05548C21.9147 2.86055 21.8386 2.67559 21.7229 2.5158C21.6072 2.35601 21.4552 2.22594 21.2795 2.13628C21.1037 2.04662 20.9093 1.99991 20.712 2",
|
|
2481
|
+
fill: "currentColor",
|
|
2482
|
+
fillOpacity: 0.4
|
|
2483
|
+
}
|
|
2484
|
+
),
|
|
2485
|
+
/* @__PURE__ */ jsx(
|
|
2486
|
+
"path",
|
|
2487
|
+
{
|
|
2488
|
+
d: "M9.34401 21.1216C9.26407 21.3763 9.10494 21.5988 8.88978 21.7568C8.67462 21.9148 8.41465 22 8.14772 22H7.8494C4.6185 22 1.99978 20.5033 1.99978 18.6572V5.28674C1.99978 7.13241 4.619 8.6291 7.8494 8.6291H11.6328C11.8305 8.62903 12.0253 8.6757 12.2015 8.7653C12.3777 8.8549 12.5301 8.98489 12.6465 9.14466C12.7628 9.30444 12.8398 9.48946 12.871 9.68463C12.9022 9.8798 12.8868 10.0796 12.8261 10.2677L9.34401 21.1216Z",
|
|
2489
|
+
fill: "currentColor"
|
|
2490
|
+
}
|
|
2491
|
+
)
|
|
2492
|
+
]
|
|
2493
|
+
}
|
|
2494
|
+
);
|
|
2495
|
+
}
|
|
2496
|
+
var iconClass = "size-3.5 shrink-0";
|
|
2497
|
+
function getToolMeta(toolName, className) {
|
|
2498
|
+
const displayName = toolName.includes("__") ? toolName.split("__").pop() ?? toolName : toolName;
|
|
2499
|
+
const label = displayName.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
2500
|
+
if (toolName.startsWith("blueprint_")) {
|
|
2501
|
+
return {
|
|
2502
|
+
label: toolName.slice("blueprint_".length).replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()),
|
|
2503
|
+
icon: /* @__PURE__ */ jsx(BlueprintIcon, { className: cn(iconClass, className, "text-muted-foreground group-hover/row:text-primary") })
|
|
2504
|
+
};
|
|
2505
|
+
}
|
|
2506
|
+
switch (displayName) {
|
|
2507
|
+
case "web_search":
|
|
2508
|
+
return {
|
|
2509
|
+
label: "Web Search",
|
|
2510
|
+
icon: /* @__PURE__ */ jsx(WorldSearchIcon, { className: cn(iconClass, className) })
|
|
2511
|
+
};
|
|
2512
|
+
case "createDocument":
|
|
2513
|
+
return {
|
|
2514
|
+
label: "Create Document",
|
|
2515
|
+
icon: /* @__PURE__ */ jsx(WritingIcon, { className: cn(iconClass, className) })
|
|
2516
|
+
};
|
|
2517
|
+
case "updateDocument":
|
|
2518
|
+
return {
|
|
2519
|
+
label: "Update Document",
|
|
2520
|
+
icon: /* @__PURE__ */ jsx(PencilIcon, { className: cn(iconClass, className) })
|
|
2521
|
+
};
|
|
2522
|
+
case "skill":
|
|
2523
|
+
return {
|
|
2524
|
+
label: "Skill",
|
|
2525
|
+
icon: /* @__PURE__ */ jsx(Book3Icon, { className: cn(iconClass, className) })
|
|
2526
|
+
};
|
|
2527
|
+
case "resolvePath":
|
|
2528
|
+
return {
|
|
2529
|
+
label: "Resolve Path",
|
|
2530
|
+
icon: /* @__PURE__ */ jsx(Folder1Icon, { className: cn(iconClass, className) })
|
|
2531
|
+
};
|
|
2532
|
+
case "readFile":
|
|
2533
|
+
case "readFileBuffer":
|
|
2534
|
+
case "read_file":
|
|
2535
|
+
return {
|
|
2536
|
+
label: "Read File",
|
|
2537
|
+
icon: /* @__PURE__ */ jsx(FileTextIcon, { className: cn(iconClass, className) })
|
|
2538
|
+
};
|
|
2539
|
+
case "exists":
|
|
2540
|
+
return {
|
|
2541
|
+
label: "Exists",
|
|
2542
|
+
icon: /* @__PURE__ */ jsx(FileTextIcon, { className: cn(iconClass, className) })
|
|
2543
|
+
};
|
|
2544
|
+
case "writeFile":
|
|
2545
|
+
case "write_file":
|
|
2546
|
+
return {
|
|
2547
|
+
label: "Write File",
|
|
2548
|
+
icon: /* @__PURE__ */ jsx(PencilIcon, { className: cn(iconClass, className) })
|
|
2549
|
+
};
|
|
2550
|
+
case "edit_file":
|
|
2551
|
+
return {
|
|
2552
|
+
label: "Edit File",
|
|
2553
|
+
icon: /* @__PURE__ */ jsx(PencilIcon, { className: cn(iconClass, className) })
|
|
2554
|
+
};
|
|
2555
|
+
case "readdir":
|
|
2556
|
+
return {
|
|
2557
|
+
label: "Read Directory",
|
|
2558
|
+
icon: /* @__PURE__ */ jsx(Folder1Icon, { className: cn(iconClass, className) })
|
|
2559
|
+
};
|
|
2560
|
+
case "symlink":
|
|
2561
|
+
return {
|
|
2562
|
+
label: "Create Symlink",
|
|
2563
|
+
icon: /* @__PURE__ */ jsx(Folder1Icon, { className: cn(iconClass, className) })
|
|
2564
|
+
};
|
|
2565
|
+
case "bash":
|
|
2566
|
+
case "shell":
|
|
2567
|
+
return {
|
|
2568
|
+
label: "Bash Command",
|
|
2569
|
+
icon: /* @__PURE__ */ jsx(Terminal2Icon, { className: cn(iconClass, className) })
|
|
2570
|
+
};
|
|
2571
|
+
case "run_js":
|
|
2572
|
+
case "runJs":
|
|
2573
|
+
case "run_python":
|
|
2574
|
+
case "runPython":
|
|
2575
|
+
return {
|
|
2576
|
+
label: displayName === "run_python" || displayName === "runPython" ? "Run Python" : "Run JavaScript",
|
|
2577
|
+
icon: /* @__PURE__ */ jsx(Code2Icon, { className: cn(iconClass, className) })
|
|
2578
|
+
};
|
|
2579
|
+
case "view_image":
|
|
2580
|
+
case "viewImage":
|
|
2581
|
+
return {
|
|
2582
|
+
label: "View Image",
|
|
2583
|
+
icon: /* @__PURE__ */ jsx(PhotoIcon, { className: cn(iconClass, className) })
|
|
2584
|
+
};
|
|
2585
|
+
case "expose_app":
|
|
2586
|
+
return {
|
|
2587
|
+
label: "Expose App",
|
|
2588
|
+
icon: /* @__PURE__ */ jsx(DeviceDesktopIcon, { className: cn(iconClass, className) })
|
|
2589
|
+
};
|
|
2590
|
+
case "setup_web_app":
|
|
2591
|
+
return {
|
|
2592
|
+
label: "Set Up Web App",
|
|
2593
|
+
icon: /* @__PURE__ */ jsx(DeviceDesktopIcon, { className: cn(iconClass, className) })
|
|
2594
|
+
};
|
|
2595
|
+
case "think":
|
|
2596
|
+
return {
|
|
2597
|
+
label: "Internal Check",
|
|
2598
|
+
icon: /* @__PURE__ */ jsx(
|
|
2599
|
+
frontera_icon_default,
|
|
2600
|
+
{
|
|
2601
|
+
icon: "message-circle-dashed",
|
|
2602
|
+
className: cn(iconClass, className)
|
|
2603
|
+
}
|
|
2604
|
+
)
|
|
2605
|
+
};
|
|
2606
|
+
case "delegate":
|
|
2607
|
+
return {
|
|
2608
|
+
label: "Sub-agent",
|
|
2609
|
+
icon: /* @__PURE__ */ jsx(Robot4Icon, { className: cn(iconClass, className) })
|
|
2610
|
+
};
|
|
2611
|
+
case "createImage":
|
|
2612
|
+
return {
|
|
2613
|
+
label: "Create Image",
|
|
2614
|
+
icon: /* @__PURE__ */ jsx(TextToImageIcon, { className: cn(iconClass, className) })
|
|
2615
|
+
};
|
|
2616
|
+
default:
|
|
2617
|
+
return {
|
|
2618
|
+
label,
|
|
2619
|
+
icon: /* @__PURE__ */ jsx(ApiAppIcon, { className: cn(iconClass, className) })
|
|
2620
|
+
};
|
|
2621
|
+
}
|
|
2622
|
+
}
|
|
2623
|
+
function ToolGroupReasoningDetail({ text }) {
|
|
2624
|
+
const plugins = useStreamdownPlugins();
|
|
2625
|
+
const visibleText = useMemo(
|
|
2626
|
+
() => text.replace(/\[REDACTED\]/g, "").trim(),
|
|
2627
|
+
[text]
|
|
2628
|
+
);
|
|
2629
|
+
return /* @__PURE__ */ jsx("div", { className: "pl-6 pt-1", children: /* @__PURE__ */ jsx(
|
|
2630
|
+
ScrollFadeEdges,
|
|
2631
|
+
{
|
|
2632
|
+
className: "max-h-52",
|
|
2633
|
+
fadeFromClassName: "from-surface-chat",
|
|
2634
|
+
children: /* @__PURE__ */ jsx(
|
|
2635
|
+
Streamdown,
|
|
2636
|
+
{
|
|
2637
|
+
className: "space-y-1.5 text-[13px] leading-relaxed text-muted-foreground/80 [&>*:first-child]:mt-0 [&>*:last-child]:mb-0 [&_h1,&_h2,&_h3,&_h4,&_h5,&_h6]:text-[13px]! [&_h1,&_h2,&_h3,&_h4,&_h5,&_h6]:font-semibold [&_h1,&_h2,&_h3,&_h4,&_h5,&_h6]:mt-3!",
|
|
2638
|
+
plugins,
|
|
2639
|
+
linkSafety: STREAMDOWN_LINK_SAFETY,
|
|
2640
|
+
children: visibleText
|
|
2641
|
+
}
|
|
2642
|
+
)
|
|
2643
|
+
}
|
|
2644
|
+
) });
|
|
2645
|
+
}
|
|
2646
|
+
var ToolGroupReasoningItem = ({
|
|
2647
|
+
className,
|
|
2648
|
+
text,
|
|
2649
|
+
isStreaming = false,
|
|
2650
|
+
...props
|
|
2651
|
+
}) => {
|
|
2652
|
+
const [open, setOpen] = useState(false);
|
|
2653
|
+
const expanded = isStreaming || open;
|
|
2654
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("relative z-10 py-0.5", className), ...props, children: [
|
|
2655
|
+
/* @__PURE__ */ jsxs(
|
|
2656
|
+
"button",
|
|
2657
|
+
{
|
|
2658
|
+
type: "button",
|
|
2659
|
+
onClick: () => setOpen((v) => !v),
|
|
2660
|
+
"aria-expanded": expanded,
|
|
2661
|
+
className: "flex w-full items-center gap-2 text-left text-sm text-muted-foreground transition-colors hover:text-foreground",
|
|
2662
|
+
children: [
|
|
2663
|
+
/* @__PURE__ */ jsx("span", { className: "flex w-4 h-7 shrink-0 items-center justify-center rounded-full bg-surface-chat", children: /* @__PURE__ */ jsx(
|
|
2664
|
+
frontera_icon_default,
|
|
2665
|
+
{
|
|
2666
|
+
icon: "message-circle-dashed",
|
|
2667
|
+
className: "size-3.5 opacity-80"
|
|
2668
|
+
}
|
|
2669
|
+
) }),
|
|
2670
|
+
isStreaming ? /* @__PURE__ */ jsx(Shimmer, { as: "span", className: "text-sm", children: "Thinking\u2026" }) : /* @__PURE__ */ jsx("span", { className: "", children: "Thought process" }),
|
|
2671
|
+
/* @__PURE__ */ jsx(
|
|
2672
|
+
ChevronDownMediumIcon,
|
|
2673
|
+
{
|
|
2674
|
+
className: cn(
|
|
2675
|
+
"size-3.5 shrink-0 text-muted-foreground/60 transition-transform",
|
|
2676
|
+
!expanded && "-rotate-90"
|
|
2677
|
+
)
|
|
2678
|
+
}
|
|
2679
|
+
)
|
|
2680
|
+
]
|
|
2681
|
+
}
|
|
2682
|
+
),
|
|
2683
|
+
/* @__PURE__ */ jsx(Collapse, { open: expanded, children: expanded ? /* @__PURE__ */ jsx(ToolGroupReasoningDetail, { text }) : null })
|
|
2684
|
+
] });
|
|
2685
|
+
};
|
|
2686
|
+
|
|
2687
|
+
export { AppIcon, AppIconFrame, Collapse, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, HoverCard, HoverCardContent, HoverCardTrigger, Icon2 as Icon, Message, MessageContent, MessageResponse, MessageToolbar, STREAMDOWN_LINK_SAFETY, Shimmer, SkillToolItem, ToolGroupReasoningItem, deferDuringLayoutMotion, describeToolRow, frontera_icon_default, getToolMeta, useStreamdownPlugins };
|