@schlessera/brain-ui-react 0.7.2 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/chat/brain-markdown.d.ts.map +1 -1
- package/dist/components/chat/brain-markdown.js +93 -55
- package/dist/components/chat/brain-markdown.js.map +1 -1
- package/dist/components/chat/chat-page.d.ts.map +1 -1
- package/dist/components/chat/chat-page.js +10 -1
- package/dist/components/chat/chat-page.js.map +1 -1
- package/dist/components/chat/copy-button.d.ts +6 -0
- package/dist/components/chat/copy-button.d.ts.map +1 -0
- package/dist/components/chat/copy-button.js +16 -0
- package/dist/components/chat/copy-button.js.map +1 -0
- package/dist/components/chat/mermaid-block.d.ts +14 -0
- package/dist/components/chat/mermaid-block.d.ts.map +1 -0
- package/dist/components/chat/mermaid-block.js +55 -0
- package/dist/components/chat/mermaid-block.js.map +1 -0
- package/dist/components/chat/mermaid-share.d.ts +5 -0
- package/dist/components/chat/mermaid-share.d.ts.map +1 -0
- package/dist/components/chat/mermaid-share.js +80 -0
- package/dist/components/chat/mermaid-share.js.map +1 -0
- package/dist/components/chat/mermaid-viewer.d.ts +6 -0
- package/dist/components/chat/mermaid-viewer.d.ts.map +1 -0
- package/dist/components/chat/mermaid-viewer.js +266 -0
- package/dist/components/chat/mermaid-viewer.js.map +1 -0
- package/dist/components/chat/message-share.d.ts.map +1 -1
- package/dist/components/chat/message-share.js +7 -4
- package/dist/components/chat/message-share.js.map +1 -1
- package/dist/components/chat/share-block.d.ts.map +1 -1
- package/dist/components/chat/share-block.js +5 -2
- package/dist/components/chat/share-block.js.map +1 -1
- package/dist/components/files/file-viewer.d.ts.map +1 -1
- package/dist/components/files/file-viewer.js +30 -5
- package/dist/components/files/file-viewer.js.map +1 -1
- package/dist/components/share/share-menu.d.ts +8 -1
- package/dist/components/share/share-menu.d.ts.map +1 -1
- package/dist/components/share/share-menu.js +10 -5
- package/dist/components/share/share-menu.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/client-environment.d.ts +29 -0
- package/dist/lib/client-environment.d.ts.map +1 -0
- package/dist/lib/client-environment.js +153 -0
- package/dist/lib/client-environment.js.map +1 -0
- package/dist/lib/mermaid-theme.d.ts +4 -0
- package/dist/lib/mermaid-theme.d.ts.map +1 -0
- package/dist/lib/mermaid-theme.js +221 -0
- package/dist/lib/mermaid-theme.js.map +1 -0
- package/dist/lib/mermaid.d.ts +62 -0
- package/dist/lib/mermaid.d.ts.map +1 -0
- package/dist/lib/mermaid.js +244 -0
- package/dist/lib/mermaid.js.map +1 -0
- package/dist/stores/file-store.d.ts.map +1 -1
- package/dist/stores/file-store.js +9 -2
- package/dist/stores/file-store.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +3 -2
- package/src/components/chat/brain-markdown.tsx +109 -80
- package/src/components/chat/chat-page.tsx +20 -1
- package/src/components/chat/copy-button.tsx +26 -0
- package/src/components/chat/mermaid-block.tsx +106 -0
- package/src/components/chat/mermaid-share.ts +91 -0
- package/src/components/chat/mermaid-viewer.tsx +336 -0
- package/src/components/chat/message-share.ts +7 -4
- package/src/components/chat/share-block.tsx +5 -2
- package/src/components/files/file-viewer.tsx +37 -5
- package/src/components/share/share-menu.tsx +20 -6
- package/src/index.ts +5 -0
- package/src/lib/client-environment.ts +152 -0
- package/src/lib/mermaid-theme.ts +246 -0
- package/src/lib/mermaid.ts +287 -0
- package/src/stores/file-store.ts +12 -2
- package/src/theme.css +10 -0
|
@@ -12,12 +12,19 @@ interface ShareMenuProps {
|
|
|
12
12
|
title?: string;
|
|
13
13
|
/** When provided, override the default icon button with a custom trigger. */
|
|
14
14
|
className?: string;
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* Optional render-prop for a custom trigger. Receives the click handler plus
|
|
17
|
+
* the status icon, so a custom trigger keeps the busy/done/error feedback
|
|
18
|
+
* instead of silently swallowing it.
|
|
19
|
+
*/
|
|
16
20
|
renderTrigger?: (props: {
|
|
17
21
|
onClick: () => void;
|
|
18
22
|
busy: boolean;
|
|
23
|
+
status: Status;
|
|
24
|
+
icon: React.ReactNode;
|
|
19
25
|
}) => React.ReactNode;
|
|
20
26
|
}
|
|
27
|
+
type Status = "idle" | "busy" | "done" | "error";
|
|
21
28
|
export declare function ShareMenu({ options, title, className, renderTrigger }: ShareMenuProps): import("react").JSX.Element;
|
|
22
29
|
export {};
|
|
23
30
|
//# sourceMappingURL=share-menu.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"share-menu.d.ts","sourceRoot":"","sources":["../../../src/components/share/share-menu.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,GAAG,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7B;AAED,UAAU,cAAc;IACtB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB
|
|
1
|
+
{"version":3,"file":"share-menu.d.ts","sourceRoot":"","sources":["../../../src/components/share/share-menu.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,GAAG,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7B;AAED,UAAU,cAAc;IACtB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE;QACtB,OAAO,EAAE,MAAM,IAAI,CAAC;QACpB,IAAI,EAAE,OAAO,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;KACvB,KAAK,KAAK,CAAC,SAAS,CAAC;CACvB;AAED,KAAK,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEjD,wBAAgB,SAAS,CAAC,EAAE,OAAO,EAAE,KAAe,EAAE,SAAS,EAAE,aAAa,EAAE,EAAE,cAAc,+BAoG/F"}
|
|
@@ -15,14 +15,19 @@ export function ShareMenu({ options, title = "Share", className, renderTrigger }
|
|
|
15
15
|
setOpen(false);
|
|
16
16
|
};
|
|
17
17
|
const onKey = (e) => {
|
|
18
|
-
if (e.key
|
|
19
|
-
|
|
18
|
+
if (e.key !== "Escape")
|
|
19
|
+
return;
|
|
20
|
+
// Captured and stopped: an Escape that dismisses this menu must not also
|
|
21
|
+
// reach whatever the menu is layered over (the diagram viewer closes on
|
|
22
|
+
// Escape too, and dismissing both at once reads as a bug).
|
|
23
|
+
e.stopPropagation();
|
|
24
|
+
setOpen(false);
|
|
20
25
|
};
|
|
21
26
|
document.addEventListener("mousedown", onDocClick);
|
|
22
|
-
document.addEventListener("keydown", onKey);
|
|
27
|
+
document.addEventListener("keydown", onKey, true);
|
|
23
28
|
return () => {
|
|
24
29
|
document.removeEventListener("mousedown", onDocClick);
|
|
25
|
-
document.removeEventListener("keydown", onKey);
|
|
30
|
+
document.removeEventListener("keydown", onKey, true);
|
|
26
31
|
};
|
|
27
32
|
}, [open]);
|
|
28
33
|
// If there's only one option, the trigger should fire it directly.
|
|
@@ -53,6 +58,6 @@ export function ShareMenu({ options, title = "Share", className, renderTrigger }
|
|
|
53
58
|
setOpen((v) => !v);
|
|
54
59
|
};
|
|
55
60
|
const icon = status === "busy" ? (_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" })) : status === "done" ? (_jsx(Check, { className: "h-3.5 w-3.5" })) : status === "error" ? (_jsx(AlertCircle, { className: "h-3.5 w-3.5 text-destructive" })) : (_jsx(Share2, { className: "h-3.5 w-3.5" }));
|
|
56
|
-
return (_jsxs("div", { ref: wrapperRef, className: cn("relative inline-flex", className), children: [renderTrigger ? (renderTrigger({ onClick: handleTrigger, busy: status === "busy" })) : (_jsx("button", { onClick: handleTrigger, disabled: status === "busy", title: error ?? title, className: "rounded p-1.5 text-muted-foreground transition-colors hover:bg-surface-raised hover:text-foreground disabled:opacity-50", children: icon })), open && !single && (_jsx("div", { role: "menu", className: "absolute right-0 top-full z-50 mt-1 min-w-[12rem] overflow-hidden rounded-lg border border-border bg-background py-1 shadow-lg", children: options.map((opt) => (_jsxs("button", { role: "menuitem", onClick: () => void runOption(opt), className: "block w-full px-3 py-2 text-left text-xs text-foreground transition-colors hover:bg-surface-raised", children: [_jsx("div", { className: "font-medium", children: opt.label }), opt.hint && _jsx("div", { className: "text-[10px] text-muted-foreground", children: opt.hint })] }, opt.id))) }))] }));
|
|
61
|
+
return (_jsxs("div", { ref: wrapperRef, className: cn("relative inline-flex", className), children: [renderTrigger ? (renderTrigger({ onClick: handleTrigger, busy: status === "busy", status, icon })) : (_jsx("button", { onClick: handleTrigger, disabled: status === "busy", title: error ?? title, className: "rounded p-1.5 text-muted-foreground transition-colors hover:bg-surface-raised hover:text-foreground disabled:opacity-50", children: icon })), open && !single && (_jsx("div", { role: "menu", className: "absolute right-0 top-full z-50 mt-1 min-w-[12rem] overflow-hidden rounded-lg border border-border bg-background py-1 shadow-lg", children: options.map((opt) => (_jsxs("button", { role: "menuitem", onClick: () => void runOption(opt), className: "block w-full px-3 py-2 text-left text-xs text-foreground transition-colors hover:bg-surface-raised", children: [_jsx("div", { className: "font-medium", children: opt.label }), opt.hint && _jsx("div", { className: "text-[10px] text-muted-foreground", children: opt.hint })] }, opt.id))) }))] }));
|
|
57
62
|
}
|
|
58
63
|
//# sourceMappingURL=share-menu.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"share-menu.js","sourceRoot":"","sources":["../../../src/components/share/share-menu.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"share-menu.js","sourceRoot":"","sources":["../../../src/components/share/share-menu.tsx"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export { AppShell } from "./components/layout/app-shell.js";
|
|
|
13
13
|
export { ChatPage } from "./components/chat/chat-page.js";
|
|
14
14
|
export { GraphPage } from "./components/graph/graph-page.js";
|
|
15
15
|
export { BrainMarkdown } from "./components/chat/brain-markdown.js";
|
|
16
|
+
export { MermaidBlock } from "./components/chat/mermaid-block.js";
|
|
17
|
+
export { inlineMermaidDiagrams, renderMermaidSvg } from "./lib/mermaid.js";
|
|
16
18
|
export { useChatStore, activeChat, anyStreaming, type ChatKey, type ChatMessage, type SessionChat, type ToolCall, type AskUserExchange, type MessageAttachment, } from "./stores/chat-store.js";
|
|
17
19
|
export { useFileStore } from "./stores/file-store.js";
|
|
18
20
|
export { useUIStore, type ActiveView } from "./stores/ui-store.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAG7E,OAAO,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAG7D,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAG7E,OAAO,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAG7D,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAIpE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAG3E,OAAO,EACL,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,iBAAiB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAG/F,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,10 @@ export { ChatPage } from "./components/chat/chat-page.js";
|
|
|
16
16
|
export { GraphPage } from "./components/graph/graph-page.js";
|
|
17
17
|
// Markdown renderer (also useful standalone, e.g. for a dev kitchen sink).
|
|
18
18
|
export { BrainMarkdown } from "./components/chat/brain-markdown.js";
|
|
19
|
+
// Mermaid: standalone diagram block (streaming-safe) + the fence-to-SVG
|
|
20
|
+
// inliner the share pipeline uses before handing markdown to the no-JS renderer.
|
|
21
|
+
export { MermaidBlock } from "./components/chat/mermaid-block.js";
|
|
22
|
+
export { inlineMermaidDiagrams, renderMermaidSvg } from "./lib/mermaid.js";
|
|
19
23
|
// Stores + selectors the shell reads (service-worker busy check, deep links).
|
|
20
24
|
export { useChatStore, activeChat, anyStreaming, } from "./stores/chat-store.js";
|
|
21
25
|
export { useFileStore } from "./stores/file-store.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,sEAAsE;AACtE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAsB,MAAM,aAAa,CAAC;AAE7E,yCAAyC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAE7D,2EAA2E;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAEpE,8EAA8E;AAC9E,OAAO,EACL,YAAY,EACZ,UAAU,EACV,YAAY,GAOb,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAmB,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAkB,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,uBAAuB;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE/F,yDAAyD;AACzD,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,sEAAsE;AACtE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAsB,MAAM,aAAa,CAAC;AAE7E,yCAAyC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAE7D,2EAA2E;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAEpE,wEAAwE;AACxE,iFAAiF;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAE3E,8EAA8E;AAC9E,OAAO,EACL,YAAY,EACZ,UAAU,EACV,YAAY,GAOb,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAmB,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAkB,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,uBAAuB;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE/F,yDAAyD;AACzD,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ClientEnvironment } from "@schlessera/brain-ui-sdk/protocol";
|
|
2
|
+
/**
|
|
3
|
+
* What this browser can actually do, measured rather than guessed.
|
|
4
|
+
*
|
|
5
|
+
* The agent is told this so it stops offering things the device can't do —
|
|
6
|
+
* "share that to WhatsApp" on a desktop with no share sheet, "take a photo of
|
|
7
|
+
* it" on a machine with no camera, "I'll check where you are" with
|
|
8
|
+
* geolocation unavailable. Every check is feature detection; nothing here
|
|
9
|
+
* parses a user-agent string, which is both unreliable and a fingerprinting
|
|
10
|
+
* surface we have no use for.
|
|
11
|
+
*
|
|
12
|
+
* Deliberately NOT included: anything that would prompt. Device presence is
|
|
13
|
+
* read from enumerateDevices(), which reports KINDS without permission (labels
|
|
14
|
+
* stay empty) — asking the reader for camera permission in order to write a
|
|
15
|
+
* system prompt would be a hostile trade.
|
|
16
|
+
*/
|
|
17
|
+
/** Marks the element whose width is the actual reading column. */
|
|
18
|
+
export declare const READING_COLUMN_ATTR = "data-reading-column";
|
|
19
|
+
/**
|
|
20
|
+
* Ask which input devices exist. Cheap, permission-free, and async — so it is
|
|
21
|
+
* primed in the background and read synchronously at send time. The first
|
|
22
|
+
* message of a session may go out without the camera/mic facts rather than
|
|
23
|
+
* blocking on a device enumeration.
|
|
24
|
+
*/
|
|
25
|
+
export declare function primeClientEnvironment(force?: boolean): Promise<void>;
|
|
26
|
+
/** @internal Test seam — drops the cached device inventory. */
|
|
27
|
+
export declare function resetClientEnvironmentCache(): void;
|
|
28
|
+
export declare function detectClientEnvironment(): ClientEnvironment | undefined;
|
|
29
|
+
//# sourceMappingURL=client-environment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-environment.d.ts","sourceRoot":"","sources":["../../src/lib/client-environment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAE3E;;;;;;;;;;;;;;GAcG;AAEH,kEAAkE;AAClE,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AAOzD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,KAAK,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBzE;AAED,+DAA+D;AAC/D,wBAAgB,2BAA2B,IAAI,IAAI,CAIlD;AAED,wBAAgB,uBAAuB,IAAI,iBAAiB,GAAG,SAAS,CAgDvE"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What this browser can actually do, measured rather than guessed.
|
|
3
|
+
*
|
|
4
|
+
* The agent is told this so it stops offering things the device can't do —
|
|
5
|
+
* "share that to WhatsApp" on a desktop with no share sheet, "take a photo of
|
|
6
|
+
* it" on a machine with no camera, "I'll check where you are" with
|
|
7
|
+
* geolocation unavailable. Every check is feature detection; nothing here
|
|
8
|
+
* parses a user-agent string, which is both unreliable and a fingerprinting
|
|
9
|
+
* surface we have no use for.
|
|
10
|
+
*
|
|
11
|
+
* Deliberately NOT included: anything that would prompt. Device presence is
|
|
12
|
+
* read from enumerateDevices(), which reports KINDS without permission (labels
|
|
13
|
+
* stay empty) — asking the reader for camera permission in order to write a
|
|
14
|
+
* system prompt would be a hostile trade.
|
|
15
|
+
*/
|
|
16
|
+
/** Marks the element whose width is the actual reading column. */
|
|
17
|
+
export const READING_COLUMN_ATTR = "data-reading-column";
|
|
18
|
+
/** Cached device inventory; undefined until the async probe has answered once. */
|
|
19
|
+
let mediaKinds;
|
|
20
|
+
let probing = false;
|
|
21
|
+
let deviceListenerBound = false;
|
|
22
|
+
/**
|
|
23
|
+
* Ask which input devices exist. Cheap, permission-free, and async — so it is
|
|
24
|
+
* primed in the background and read synchronously at send time. The first
|
|
25
|
+
* message of a session may go out without the camera/mic facts rather than
|
|
26
|
+
* blocking on a device enumeration.
|
|
27
|
+
*/
|
|
28
|
+
export async function primeClientEnvironment(force = false) {
|
|
29
|
+
if ((mediaKinds && !force) || probing)
|
|
30
|
+
return;
|
|
31
|
+
if (typeof navigator === "undefined")
|
|
32
|
+
return;
|
|
33
|
+
const media = navigator.mediaDevices;
|
|
34
|
+
if (!media || typeof media.enumerateDevices !== "function")
|
|
35
|
+
return;
|
|
36
|
+
probing = true;
|
|
37
|
+
try {
|
|
38
|
+
const devices = await media.enumerateDevices();
|
|
39
|
+
mediaKinds = {
|
|
40
|
+
camera: devices.some((d) => d.kind === "videoinput"),
|
|
41
|
+
microphone: devices.some((d) => d.kind === "audioinput"),
|
|
42
|
+
};
|
|
43
|
+
// A headset plugged in (or a webcam unplugged) mid-conversation changes
|
|
44
|
+
// the honest answer, so the cache follows the hardware.
|
|
45
|
+
if (!deviceListenerBound && typeof media.addEventListener === "function") {
|
|
46
|
+
deviceListenerBound = true;
|
|
47
|
+
media.addEventListener("devicechange", () => void primeClientEnvironment(true));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// Enumeration blocked (permissions policy, older browser) — leave the
|
|
52
|
+
// capability unreported rather than guessing it exists.
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
probing = false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** @internal Test seam — drops the cached device inventory. */
|
|
59
|
+
export function resetClientEnvironmentCache() {
|
|
60
|
+
mediaKinds = undefined;
|
|
61
|
+
probing = false;
|
|
62
|
+
deviceListenerBound = false;
|
|
63
|
+
}
|
|
64
|
+
export function detectClientEnvironment() {
|
|
65
|
+
if (typeof window === "undefined" || typeof navigator === "undefined")
|
|
66
|
+
return undefined;
|
|
67
|
+
// Fire-and-forget: answers by the next message even if this one misses it.
|
|
68
|
+
void primeClientEnvironment();
|
|
69
|
+
const coarse = matches("(pointer: coarse)");
|
|
70
|
+
const env = { formFactor: formFactor(coarse) };
|
|
71
|
+
if (coarse)
|
|
72
|
+
env.touch = true;
|
|
73
|
+
if (matches("(display-mode: standalone)") || matches("(display-mode: fullscreen)")) {
|
|
74
|
+
env.standalone = true;
|
|
75
|
+
}
|
|
76
|
+
if (mediaKinds?.camera)
|
|
77
|
+
env.camera = true;
|
|
78
|
+
if (mediaKinds?.microphone)
|
|
79
|
+
env.microphone = true;
|
|
80
|
+
// getUserMedia and geolocation both require a secure context, which is also
|
|
81
|
+
// what the location tool needs.
|
|
82
|
+
if (navigator.geolocation && window.isSecureContext !== false)
|
|
83
|
+
env.geolocation = true;
|
|
84
|
+
if (typeof navigator.share === "function") {
|
|
85
|
+
env.share = true;
|
|
86
|
+
// canShare({files}) needs a real File to answer honestly; a 1-byte probe
|
|
87
|
+
// is what the share paths themselves check before offering an image.
|
|
88
|
+
try {
|
|
89
|
+
const probe = new File([new Uint8Array(1)], "probe.png", { type: "image/png" });
|
|
90
|
+
if (typeof navigator.canShare === "function" && navigator.canShare({ files: [probe] })) {
|
|
91
|
+
env.shareFiles = true;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// No File constructor / canShare threw — leave shareFiles unset.
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const column = readingColumnWidth();
|
|
99
|
+
if (column)
|
|
100
|
+
env.viewportWidth = column;
|
|
101
|
+
// Both are re-validated server-side against the platform's own locale and
|
|
102
|
+
// timezone databases; anything unrecognized is dropped there.
|
|
103
|
+
const locale = navigator.language;
|
|
104
|
+
if (locale && locale.length <= 35)
|
|
105
|
+
env.locale = locale;
|
|
106
|
+
try {
|
|
107
|
+
const zone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
108
|
+
if (zone && zone.length <= 64)
|
|
109
|
+
env.timeZone = zone;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// Intl unavailable — omit.
|
|
113
|
+
}
|
|
114
|
+
return env;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Phone vs tablet from the SHORT edge of the screen, not from the current
|
|
118
|
+
* window width: a phone in landscape is 900+px wide and would otherwise be
|
|
119
|
+
* reported as a tablet, flipping the device description (and busting the
|
|
120
|
+
* prompt cache) every time the reader rotates.
|
|
121
|
+
*/
|
|
122
|
+
function formFactor(coarse) {
|
|
123
|
+
if (!coarse)
|
|
124
|
+
return "desktop";
|
|
125
|
+
const w = window.screen?.width ?? window.innerWidth ?? 0;
|
|
126
|
+
const h = window.screen?.height ?? window.innerHeight ?? 0;
|
|
127
|
+
const shortEdge = w && h ? Math.min(w, h) : w || h;
|
|
128
|
+
return shortEdge && shortEdge >= 600 ? "tablet" : "phone";
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Width of the column text actually renders into — the chat layout caps it far
|
|
132
|
+
* below the window — rounded to 50px so that dragging a window edge does not
|
|
133
|
+
* rewrite the system prompt (and invalidate its cache) on every message.
|
|
134
|
+
*/
|
|
135
|
+
function readingColumnWidth() {
|
|
136
|
+
const el = document.querySelector(`[${READING_COLUMN_ATTR}]`);
|
|
137
|
+
const measured = el?.getBoundingClientRect().width ||
|
|
138
|
+
window.innerWidth ||
|
|
139
|
+
document.documentElement?.clientWidth ||
|
|
140
|
+
0;
|
|
141
|
+
if (!measured)
|
|
142
|
+
return undefined;
|
|
143
|
+
return Math.max(50, Math.round(measured / 50) * 50);
|
|
144
|
+
}
|
|
145
|
+
function matches(query) {
|
|
146
|
+
try {
|
|
147
|
+
return typeof window.matchMedia === "function" && window.matchMedia(query).matches;
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=client-environment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-environment.js","sourceRoot":"","sources":["../../src/lib/client-environment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type MermaidTheme = "dark" | "light";
|
|
2
|
+
/** Theme variables for a target surface, as mermaid's `themeVariables` object. */
|
|
3
|
+
export declare function mermaidThemeVariables(theme: MermaidTheme): Record<string, string | boolean>;
|
|
4
|
+
//# sourceMappingURL=mermaid-theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaid-theme.d.ts","sourceRoot":"","sources":["../../src/lib/mermaid-theme.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,CAAC;AA+N5C,kFAAkF;AAClF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAE3F"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mermaid theme variables for the two surfaces a diagram can land on.
|
|
3
|
+
*
|
|
4
|
+
* Mermaid's stock "dark" theme is a blue-grey palette that reads as foreign
|
|
5
|
+
* next to the app's warm-neutral chrome, and its "neutral" theme is what the
|
|
6
|
+
* share renderer used to emit. Both are replaced by the "base" theme plus the
|
|
7
|
+
* variables below, so an in-app diagram and a shared PNG are recognisably the
|
|
8
|
+
* same product.
|
|
9
|
+
*
|
|
10
|
+
* Two rules kept the palette honest:
|
|
11
|
+
* - Surfaces follow the tokens in theme.css, not approximations of them. A
|
|
12
|
+
* chat diagram sits on `--color-surface` (#141619), not on the page
|
|
13
|
+
* background, because MermaidBlock draws it on a raised plate.
|
|
14
|
+
* - Multi-series colors reuse CATEGORICAL_SLOTS from the graph view, which
|
|
15
|
+
* is the repo's one CVD-validated categorical palette. Slot order is the
|
|
16
|
+
* CVD-safety mechanism there and is preserved here.
|
|
17
|
+
*/
|
|
18
|
+
import { CATEGORICAL_SLOTS, OTHER_COLOR } from "../components/graph/lib/graph-helpers.js";
|
|
19
|
+
// These variables reach mermaid through initialize(), NOT through a
|
|
20
|
+
// `%%{init: …}%%` directive: mermaid's directive path rewrites `'` to `"`
|
|
21
|
+
// before parsing the JSON and drops any themeVariable containing a hyphen, so
|
|
22
|
+
// a font stack cannot survive it. See the note in mermaid.ts.
|
|
23
|
+
const SANS = '"Plus Jakarta Sans", system-ui, -apple-system, sans-serif';
|
|
24
|
+
/** Ordered series colors, long enough for the 12-slot scales mermaid asks for. */
|
|
25
|
+
const SERIES = [...CATEGORICAL_SLOTS, OTHER_COLOR, "#67b8e3", "#eab354", "#b197d4"];
|
|
26
|
+
/** Expand a scale into the `${prefix}0..count-1` (or 1-based) shape mermaid wants. */
|
|
27
|
+
function scale(prefix, count, oneBased = false) {
|
|
28
|
+
const out = {};
|
|
29
|
+
for (let i = 0; i < count; i++) {
|
|
30
|
+
out[`${prefix}${oneBased ? i + 1 : i}`] = SERIES[i % SERIES.length];
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Dark: the in-app palette. Node fills use `--color-surface-overlay` so nodes
|
|
36
|
+
* sit a step above the block's own `--color-surface` plate, and borders use
|
|
37
|
+
* #3d4150 rather than `--color-border` (#2a2d35) — a 1px border at the token
|
|
38
|
+
* value all but disappears against the plate at diagram scale.
|
|
39
|
+
*/
|
|
40
|
+
const DARK = {
|
|
41
|
+
darkMode: true,
|
|
42
|
+
background: "#141619",
|
|
43
|
+
fontFamily: SANS,
|
|
44
|
+
fontSize: "14px",
|
|
45
|
+
primaryColor: "#1e2128",
|
|
46
|
+
primaryTextColor: "#e8e4df",
|
|
47
|
+
primaryBorderColor: "#3d4150",
|
|
48
|
+
secondaryColor: "#1a1d22",
|
|
49
|
+
secondaryTextColor: "#e8e4df",
|
|
50
|
+
secondaryBorderColor: "#3d4150",
|
|
51
|
+
tertiaryColor: "#0c0e12",
|
|
52
|
+
tertiaryTextColor: "#8a8691",
|
|
53
|
+
tertiaryBorderColor: "#2a2d35",
|
|
54
|
+
mainBkg: "#1e2128",
|
|
55
|
+
nodeBorder: "#3d4150",
|
|
56
|
+
nodeTextColor: "#e8e4df",
|
|
57
|
+
textColor: "#e8e4df",
|
|
58
|
+
lineColor: "#8a8691",
|
|
59
|
+
defaultLinkColor: "#8a8691",
|
|
60
|
+
titleColor: "#e09f3e",
|
|
61
|
+
edgeLabelBackground: "#141619",
|
|
62
|
+
clusterBkg: "#0c0e12",
|
|
63
|
+
clusterBorder: "#2a2d35",
|
|
64
|
+
noteBkgColor: "#1a1d22",
|
|
65
|
+
noteTextColor: "#e8e4df",
|
|
66
|
+
noteBorderColor: "#e09f3e",
|
|
67
|
+
errorBkgColor: "#2a1a1a",
|
|
68
|
+
errorTextColor: "#f87171",
|
|
69
|
+
// Sequence
|
|
70
|
+
actorBkg: "#1e2128",
|
|
71
|
+
actorBorder: "#3d4150",
|
|
72
|
+
actorTextColor: "#e8e4df",
|
|
73
|
+
actorLineColor: "#3d4150",
|
|
74
|
+
signalColor: "#8a8691",
|
|
75
|
+
signalTextColor: "#e8e4df",
|
|
76
|
+
labelBoxBkgColor: "#1a1d22",
|
|
77
|
+
labelBoxBorderColor: "#2a2d35",
|
|
78
|
+
labelTextColor: "#e8e4df",
|
|
79
|
+
loopTextColor: "#e8e4df",
|
|
80
|
+
activationBkgColor: "#1a1d22",
|
|
81
|
+
activationBorderColor: "#5bb5a2",
|
|
82
|
+
sequenceNumberColor: "#0c0e12",
|
|
83
|
+
// State / class / journey
|
|
84
|
+
labelColor: "#e8e4df",
|
|
85
|
+
altBackground: "#0c0e12",
|
|
86
|
+
classText: "#e8e4df",
|
|
87
|
+
// Gantt
|
|
88
|
+
sectionBkgColor: "#1a1d22",
|
|
89
|
+
altSectionBkgColor: "#141619",
|
|
90
|
+
sectionBkgColor2: "#1e2128",
|
|
91
|
+
gridColor: "#2a2d35",
|
|
92
|
+
taskBkgColor: "#2a2d35",
|
|
93
|
+
taskTextColor: "#e8e4df",
|
|
94
|
+
taskTextOutsideColor: "#e8e4df",
|
|
95
|
+
taskTextDarkColor: "#0c0e12",
|
|
96
|
+
taskBorderColor: "#3d4150",
|
|
97
|
+
doneTaskBkgColor: "#565b66",
|
|
98
|
+
doneTaskBorderColor: "#3d4150",
|
|
99
|
+
activeTaskBkgColor: "#e09f3e",
|
|
100
|
+
activeTaskBorderColor: "#e09f3e",
|
|
101
|
+
critBkgColor: "#d03b3b",
|
|
102
|
+
critBorderColor: "#d03b3b",
|
|
103
|
+
todayLineColor: "#5bb5a2",
|
|
104
|
+
// Pie
|
|
105
|
+
pieTitleTextColor: "#e8e4df",
|
|
106
|
+
pieSectionTextColor: "#0c0e12",
|
|
107
|
+
pieLegendTextColor: "#e8e4df",
|
|
108
|
+
pieStrokeColor: "#141619",
|
|
109
|
+
pieOuterStrokeColor: "#2a2d35",
|
|
110
|
+
// Quadrant / requirement / misc surfaces that don't inherit cleanly
|
|
111
|
+
quadrant1Fill: "#1e2128",
|
|
112
|
+
quadrant2Fill: "#1a1d22",
|
|
113
|
+
quadrant3Fill: "#141619",
|
|
114
|
+
quadrant4Fill: "#1e2128",
|
|
115
|
+
quadrantPointFill: "#e09f3e",
|
|
116
|
+
quadrantTitleFill: "#e8e4df",
|
|
117
|
+
quadrantInternalBorderStrokeFill: "#2a2d35",
|
|
118
|
+
quadrantExternalBorderStrokeFill: "#3d4150",
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* Light: what the share renderer emits. Tuned against the PNG/PDF template's
|
|
122
|
+
* own palette (`ui-server/src/render/template.ts`: #ffffff page, #f8fafc
|
|
123
|
+
* surface, #e5e7eb border, #1f2937 text) so a diagram doesn't look pasted in.
|
|
124
|
+
* The amber and teal are darkened from the app tokens — #e09f3e on white is a
|
|
125
|
+
* 1.9:1 line, unusable for edges or titles.
|
|
126
|
+
*/
|
|
127
|
+
const LIGHT = {
|
|
128
|
+
darkMode: false,
|
|
129
|
+
background: "#ffffff",
|
|
130
|
+
fontFamily: SANS,
|
|
131
|
+
fontSize: "14px",
|
|
132
|
+
primaryColor: "#f8fafc",
|
|
133
|
+
primaryTextColor: "#1f2937",
|
|
134
|
+
primaryBorderColor: "#c3c9d2",
|
|
135
|
+
secondaryColor: "#f3f4f6",
|
|
136
|
+
secondaryTextColor: "#1f2937",
|
|
137
|
+
secondaryBorderColor: "#c3c9d2",
|
|
138
|
+
tertiaryColor: "#ffffff",
|
|
139
|
+
tertiaryTextColor: "#6b7280",
|
|
140
|
+
tertiaryBorderColor: "#e5e7eb",
|
|
141
|
+
mainBkg: "#f8fafc",
|
|
142
|
+
nodeBorder: "#c3c9d2",
|
|
143
|
+
nodeTextColor: "#1f2937",
|
|
144
|
+
textColor: "#1f2937",
|
|
145
|
+
lineColor: "#6b7280",
|
|
146
|
+
defaultLinkColor: "#6b7280",
|
|
147
|
+
titleColor: "#9a6516",
|
|
148
|
+
edgeLabelBackground: "#ffffff",
|
|
149
|
+
clusterBkg: "#f3f4f6",
|
|
150
|
+
clusterBorder: "#d7dbe0",
|
|
151
|
+
noteBkgColor: "#fdf6e8",
|
|
152
|
+
noteTextColor: "#1f2937",
|
|
153
|
+
noteBorderColor: "#9a6516",
|
|
154
|
+
errorBkgColor: "#fdecec",
|
|
155
|
+
errorTextColor: "#b42323",
|
|
156
|
+
// Sequence
|
|
157
|
+
actorBkg: "#f8fafc",
|
|
158
|
+
actorBorder: "#c3c9d2",
|
|
159
|
+
actorTextColor: "#1f2937",
|
|
160
|
+
actorLineColor: "#c3c9d2",
|
|
161
|
+
signalColor: "#6b7280",
|
|
162
|
+
signalTextColor: "#1f2937",
|
|
163
|
+
labelBoxBkgColor: "#f3f4f6",
|
|
164
|
+
labelBoxBorderColor: "#d7dbe0",
|
|
165
|
+
labelTextColor: "#1f2937",
|
|
166
|
+
loopTextColor: "#1f2937",
|
|
167
|
+
activationBkgColor: "#f3f4f6",
|
|
168
|
+
activationBorderColor: "#2f7d6b",
|
|
169
|
+
sequenceNumberColor: "#ffffff",
|
|
170
|
+
// State / class / journey
|
|
171
|
+
labelColor: "#1f2937",
|
|
172
|
+
altBackground: "#f3f4f6",
|
|
173
|
+
classText: "#1f2937",
|
|
174
|
+
// Gantt
|
|
175
|
+
sectionBkgColor: "#f8fafc",
|
|
176
|
+
altSectionBkgColor: "#ffffff",
|
|
177
|
+
sectionBkgColor2: "#f3f4f6",
|
|
178
|
+
gridColor: "#e5e7eb",
|
|
179
|
+
taskBkgColor: "#e5e7eb",
|
|
180
|
+
taskTextColor: "#1f2937",
|
|
181
|
+
taskTextOutsideColor: "#1f2937",
|
|
182
|
+
taskTextDarkColor: "#1f2937",
|
|
183
|
+
taskBorderColor: "#c3c9d2",
|
|
184
|
+
doneTaskBkgColor: "#d7dbe0",
|
|
185
|
+
doneTaskBorderColor: "#c3c9d2",
|
|
186
|
+
activeTaskBkgColor: "#e0a75a",
|
|
187
|
+
activeTaskBorderColor: "#9a6516",
|
|
188
|
+
critBkgColor: "#e08a8a",
|
|
189
|
+
critBorderColor: "#b42323",
|
|
190
|
+
todayLineColor: "#2f7d6b",
|
|
191
|
+
// Pie
|
|
192
|
+
pieTitleTextColor: "#1f2937",
|
|
193
|
+
pieSectionTextColor: "#ffffff",
|
|
194
|
+
pieLegendTextColor: "#1f2937",
|
|
195
|
+
pieStrokeColor: "#ffffff",
|
|
196
|
+
pieOuterStrokeColor: "#d7dbe0",
|
|
197
|
+
// Quadrant
|
|
198
|
+
quadrant1Fill: "#f8fafc",
|
|
199
|
+
quadrant2Fill: "#f3f4f6",
|
|
200
|
+
quadrant3Fill: "#ffffff",
|
|
201
|
+
quadrant4Fill: "#f8fafc",
|
|
202
|
+
quadrantPointFill: "#9a6516",
|
|
203
|
+
quadrantTitleFill: "#1f2937",
|
|
204
|
+
quadrantInternalBorderStrokeFill: "#e5e7eb",
|
|
205
|
+
quadrantExternalBorderStrokeFill: "#d7dbe0",
|
|
206
|
+
};
|
|
207
|
+
const SERIES_SCALES = {
|
|
208
|
+
...scale("pie", 12, true), // pie1..pie12
|
|
209
|
+
...scale("cScale", 12), // cScale0..11 (journey, timeline, xychart)
|
|
210
|
+
...scale("fillType", 8), // fillType0..7 (class/state/journey sections)
|
|
211
|
+
...scale("git", 8), // git0..git7 (gitgraph branches)
|
|
212
|
+
};
|
|
213
|
+
const THEME_VARIABLES = {
|
|
214
|
+
dark: { ...DARK, ...SERIES_SCALES },
|
|
215
|
+
light: { ...LIGHT, ...SERIES_SCALES },
|
|
216
|
+
};
|
|
217
|
+
/** Theme variables for a target surface, as mermaid's `themeVariables` object. */
|
|
218
|
+
export function mermaidThemeVariables(theme) {
|
|
219
|
+
return THEME_VARIABLES[theme];
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=mermaid-theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaid-theme.js","sourceRoot":"","sources":["../../src/lib/mermaid-theme.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mermaid runtime + fence helpers.
|
|
3
|
+
*
|
|
4
|
+
* Mermaid is ~2MB, so it loads on first use via dynamic import; nothing here
|
|
5
|
+
* pulls it in at module scope. Rendering is tolerant of partial sources
|
|
6
|
+
* (streaming deltas): parse is gated and every failure resolves to null
|
|
7
|
+
* instead of throwing, so callers keep the previous good SVG. Results are
|
|
8
|
+
* cached per (theme, source), which makes the per-token re-render of a
|
|
9
|
+
* streaming message a cache hit.
|
|
10
|
+
*/
|
|
11
|
+
import { type MermaidTheme } from "./mermaid-theme.js";
|
|
12
|
+
export type { MermaidTheme };
|
|
13
|
+
/** Synchronous cache lookup, so a remounted block can show its SVG without a flash. */
|
|
14
|
+
export declare function peekMermaidSvg(source: string, theme?: MermaidTheme): string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Render a mermaid source to SVG markup. Resolves null when the source does
|
|
17
|
+
* not parse (e.g. an incomplete streaming fence) or rendering fails — never
|
|
18
|
+
* throws and never mutates the document beyond mermaid's temp container.
|
|
19
|
+
*/
|
|
20
|
+
export declare function renderMermaidSvg(source: string, theme?: MermaidTheme): Promise<string | null>;
|
|
21
|
+
export interface MermaidFence {
|
|
22
|
+
/** Offset of the opening fence line start. */
|
|
23
|
+
start: number;
|
|
24
|
+
/** Offset just past the closing fence line (and its newline, if present). */
|
|
25
|
+
end: number;
|
|
26
|
+
/** Diagram source between the fences, without the trailing newline. */
|
|
27
|
+
source: string;
|
|
28
|
+
/** Leading spaces of the opening fence line (a list-indented fence). */
|
|
29
|
+
indent: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Find every *closed* ```mermaid fence in a markdown string. A line scanner
|
|
33
|
+
* (not a regex over the whole text) so mermaid fences nested inside other
|
|
34
|
+
* code blocks are not matched, and an unterminated streaming fence is simply
|
|
35
|
+
* not returned.
|
|
36
|
+
*/
|
|
37
|
+
export declare function findMermaidFences(md: string): MermaidFence[];
|
|
38
|
+
/**
|
|
39
|
+
* Replace each closed mermaid fence via `replacement`; returning null keeps
|
|
40
|
+
* the fence verbatim. Pure — rendering is injected, so this is unit-testable
|
|
41
|
+
* without a DOM.
|
|
42
|
+
*/
|
|
43
|
+
export declare function replaceMermaidFences(md: string, replacement: (fence: MermaidFence, index: number) => string | null): string;
|
|
44
|
+
/** Pure inlining step: substitute pre-rendered SVGs (by fence index) under the budget. */
|
|
45
|
+
export declare function inlineRenderedFences(md: string, rendered: (string | null)[], budget?: number): string;
|
|
46
|
+
export declare function inlineMermaidDiagrams(md: string, theme?: MermaidTheme): Promise<string>;
|
|
47
|
+
/**
|
|
48
|
+
* Give a mermaid SVG an intrinsic pixel size taken from its viewBox.
|
|
49
|
+
*
|
|
50
|
+
* Mermaid ships its diagrams as `style="max-width: Npx"` with no width/height
|
|
51
|
+
* attribute, which is right for a responsive page and wrong for an export: a
|
|
52
|
+
* standalone .svg file then has no intrinsic size, and the PNG/PDF renderer
|
|
53
|
+
* lays it out at the full body width no matter how small the diagram is.
|
|
54
|
+
* Sizing it here is what lets the share page shrink-wrap the figure.
|
|
55
|
+
*
|
|
56
|
+
* Returns the input unchanged when there is no parseable viewBox — an
|
|
57
|
+
* un-sized export beats a corrupted one.
|
|
58
|
+
*/
|
|
59
|
+
export declare function sizeSvgForExport(svg: string, maxWidth?: number): string;
|
|
60
|
+
/** Whether a repo path is a standalone mermaid source file (previewable as a diagram). */
|
|
61
|
+
export declare function isMermaidPath(path: string): boolean;
|
|
62
|
+
//# sourceMappingURL=mermaid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaid.d.ts","sourceRoot":"","sources":["../../src/lib/mermaid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAyB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE9E,YAAY,EAAE,YAAY,EAAE,CAAC;AA8D7B,uFAAuF;AACvF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,YAAqB,GAAG,MAAM,GAAG,IAAI,CAE1F;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,YAAqB,GAC3B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA2BxB;AAED,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,GAAG,EAAE,MAAM,CAAC;IACZ,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;CAChB;AAID;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,EAAE,CA8C5D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GACjE,MAAM,CASR;AAkBD,0FAA0F;AAC1F,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,EAC3B,MAAM,GAAE,MAA4B,GACnC,MAAM,CAeR;AAED,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,MAAM,EACV,KAAK,GAAE,YAAsB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAKjB;AAKD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,SAAO,GAAG,MAAM,CAerE;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD"}
|