radiant-docs 0.1.60 → 0.1.62
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/package.json +1 -1
- package/template/package-lock.json +10 -4
- package/template/package.json +11 -2
- package/template/scripts/generate-proxy-allowed-origins.mjs +14 -6
- package/template/scripts/publish-shiki-platform-assets.mjs +1151 -0
- package/template/src/components/Header.astro +6 -1
- package/template/src/components/NavigationTabList.astro +65 -0
- package/template/src/components/NavigationTabs.astro +109 -0
- package/template/src/components/OpenApiPage.astro +178 -14
- package/template/src/components/Sidebar.astro +2 -2
- package/template/src/components/SidebarDropdown.astro +105 -44
- package/template/src/components/SidebarMenu.astro +3 -0
- package/template/src/components/SidebarSegmented.astro +87 -52
- package/template/src/components/SidebarTabs.astro +86 -0
- package/template/src/components/chat/AssistantDocsWidget.tsx +127 -2
- package/template/src/components/chat/AssistantEmbedPanel.tsx +287 -290
- package/template/src/components/endpoint/PlaygroundBar.astro +54 -9
- package/template/src/components/endpoint/PlaygroundForm.astro +1 -1
- package/template/src/components/endpoint/RequestSnippets.astro +6 -1
- package/template/src/components/endpoint/ResponseFieldTree.astro +17 -13
- package/template/src/components/endpoint/ResponseFields.astro +4 -6
- package/template/src/components/endpoint/ResponseSnippets.astro +6 -1
- package/template/src/components/sidebar/SidebarEndpointLink.astro +9 -12
- package/template/src/components/sidebar/SidebarOpenApi.astro +3 -9
- package/template/src/components/ui/Field.astro +18 -15
- package/template/src/components/ui/Tag.astro +16 -2
- package/template/src/components/user/Accordion.astro +1 -1
- package/template/src/components/user/Callout.astro +2 -2
- package/template/src/components/user/CodeBlock.astro +58 -7
- package/template/src/components/user/CodeGroup.astro +52 -1
- package/template/src/components/user/Column.astro +1 -1
- package/template/src/components/user/Step.astro +1 -1
- package/template/src/components/user/Tabs.astro +1 -1
- package/template/src/generated/shiki-platform-assets.json +24 -0
- package/template/src/layouts/Layout.astro +111 -8
- package/template/src/lib/assistant-panel-config.ts +59 -0
- package/template/src/lib/assistant-shiki-client.ts +506 -0
- package/template/src/lib/mdx/remark-resolve-internal-links.ts +334 -17
- package/template/src/lib/routes.ts +66 -24
- package/template/src/lib/utils.ts +11 -0
- package/template/src/styles/global.css +12 -0
|
@@ -1,34 +1,17 @@
|
|
|
1
1
|
import type { JSX } from "preact";
|
|
2
2
|
import { useEffect, useRef, useState } from "preact/hooks";
|
|
3
3
|
import { Icon } from "@iconify/react";
|
|
4
|
-
import Prism from "prismjs";
|
|
5
|
-
import "prismjs/components/prism-markup.js";
|
|
6
|
-
import "prismjs/components/prism-clike.js";
|
|
7
|
-
import "prismjs/components/prism-javascript.js";
|
|
8
|
-
import "prismjs/components/prism-typescript.js";
|
|
9
|
-
import "prismjs/components/prism-jsx.js";
|
|
10
|
-
import "prismjs/components/prism-tsx.js";
|
|
11
|
-
import "prismjs/components/prism-json.js";
|
|
12
|
-
import "prismjs/components/prism-markdown.js";
|
|
13
|
-
import "prismjs/components/prism-bash.js";
|
|
14
|
-
import "prismjs/components/prism-python.js";
|
|
15
|
-
import "prismjs/components/prism-yaml.js";
|
|
16
|
-
import "prismjs/components/prism-sql.js";
|
|
17
|
-
import "prismjs/components/prism-rust.js";
|
|
18
|
-
import "prismjs/components/prism-go.js";
|
|
19
|
-
import "prismjs/components/prism-java.js";
|
|
20
|
-
import "prismjs/components/prism-markup-templating.js";
|
|
21
|
-
import "prismjs/components/prism-php.js";
|
|
22
|
-
import "prismjs/components/prism-ruby.js";
|
|
23
|
-
import "prismjs/components/prism-css.js";
|
|
24
|
-
import "prismjs/components/prism-diff.js";
|
|
25
|
-
import "prism-themes/themes/prism-one-light.css";
|
|
26
4
|
import { type Plugin, unified } from "unified";
|
|
27
5
|
import remarkParse from "remark-parse";
|
|
28
6
|
import remarkGfm from "remark-gfm";
|
|
29
7
|
import remarkRehype from "remark-rehype";
|
|
30
8
|
import rehypeStringify from "rehype-stringify";
|
|
31
9
|
import { getDocsBasePath, withBasePath } from "../../lib/base-path";
|
|
10
|
+
import {
|
|
11
|
+
highlightAssistantCodeToHtml,
|
|
12
|
+
normalizeAssistantCodeLanguage,
|
|
13
|
+
type AssistantShikiRuntimeConfig,
|
|
14
|
+
} from "../../lib/assistant-shiki-client";
|
|
32
15
|
|
|
33
16
|
type AssistantLinkTarget = "current" | "blank";
|
|
34
17
|
export type AssistantPanelSize = "default" | "expanded";
|
|
@@ -59,10 +42,13 @@ type AssistantEmbedPanelProps = {
|
|
|
59
42
|
allowApiPathQueryOverride?: boolean;
|
|
60
43
|
openSignal?: number;
|
|
61
44
|
panelSize?: AssistantPanelSize;
|
|
45
|
+
mobileBreakpoint?: string;
|
|
46
|
+
panelFullscreenHeightBreakpoint?: string;
|
|
62
47
|
onRequestOpen?: () => void;
|
|
63
48
|
onRequestClose?: () => void;
|
|
64
49
|
onRequestPanelSizeToggle?: (size: AssistantPanelSize) => void;
|
|
65
50
|
onCurrentLinkNavigate?: (href: string, sourceElement?: Element) => void;
|
|
51
|
+
shiki?: AssistantShikiRuntimeConfig;
|
|
66
52
|
};
|
|
67
53
|
|
|
68
54
|
type AssistantColorByMode = {
|
|
@@ -120,41 +106,50 @@ const HANDOFF_ACK_TYPE = "assistant-handoff:ack";
|
|
|
120
106
|
const IN_FLIGHT_STALE_MS = 10000;
|
|
121
107
|
const IN_FLIGHT_HEARTBEAT_MS = 3000;
|
|
122
108
|
const MARKDOWN_HTML_CACHE_LIMIT = 300;
|
|
109
|
+
const DEFAULT_ASSISTANT_MOBILE_BREAKPOINT = "640px";
|
|
110
|
+
const DEFAULT_ASSISTANT_PANEL_FULLSCREEN_HEIGHT_BREAKPOINT = "560px";
|
|
123
111
|
const markdownHtmlCache = new Map<string, string>();
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
mdx: "markdown",
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
const PRISM_LANGUAGE_LABEL: Record<string, string> = {
|
|
112
|
+
const markdownHtmlPromiseCache = new Map<string, Promise<string>>();
|
|
113
|
+
const ASSISTANT_LANGUAGE_LABEL: Record<string, string> = {
|
|
114
|
+
bash: "Bash",
|
|
115
|
+
css: "CSS",
|
|
116
|
+
diff: "Diff",
|
|
117
|
+
go: "Go",
|
|
118
|
+
html: "HTML",
|
|
119
|
+
java: "Java",
|
|
136
120
|
javascript: "JavaScript",
|
|
137
|
-
typescript: "TypeScript",
|
|
138
121
|
jsx: "JSX",
|
|
139
|
-
tsx: "TSX",
|
|
140
122
|
json: "JSON",
|
|
141
123
|
markdown: "Markdown",
|
|
142
|
-
|
|
143
|
-
|
|
124
|
+
mdx: "MDX",
|
|
125
|
+
php: "PHP",
|
|
126
|
+
plaintext: "Text",
|
|
144
127
|
python: "Python",
|
|
145
|
-
|
|
146
|
-
sql: "SQL",
|
|
128
|
+
ruby: "Ruby",
|
|
147
129
|
rust: "Rust",
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
mdx: "MDX",
|
|
130
|
+
shell: "Shell",
|
|
131
|
+
sql: "SQL",
|
|
132
|
+
tsx: "TSX",
|
|
133
|
+
typescript: "TypeScript",
|
|
134
|
+
yaml: "YAML",
|
|
154
135
|
};
|
|
155
136
|
|
|
156
137
|
const EXTERNAL_PROTOCOL_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*:/;
|
|
157
138
|
|
|
139
|
+
function buildMarkdownCacheKey(
|
|
140
|
+
normalizedMarkdown: string,
|
|
141
|
+
linkTarget: AssistantLinkTarget,
|
|
142
|
+
shiki: AssistantShikiRuntimeConfig | undefined,
|
|
143
|
+
): string {
|
|
144
|
+
return [
|
|
145
|
+
linkTarget,
|
|
146
|
+
shiki?.assetBaseUrl ?? "",
|
|
147
|
+
shiki?.syntaxThemes.light ?? "",
|
|
148
|
+
shiki?.syntaxThemes.dark ?? "",
|
|
149
|
+
normalizedMarkdown,
|
|
150
|
+
].join("\0");
|
|
151
|
+
}
|
|
152
|
+
|
|
158
153
|
function normalizeRelTokens(value: unknown): string[] {
|
|
159
154
|
if (Array.isArray(value)) {
|
|
160
155
|
return value
|
|
@@ -395,6 +390,13 @@ function normalizePanelSize(value: unknown): AssistantPanelSize {
|
|
|
395
390
|
return value === "expanded" ? "expanded" : "default";
|
|
396
391
|
}
|
|
397
392
|
|
|
393
|
+
function getPanelFullscreenMediaQuery(
|
|
394
|
+
mobileBreakpoint: string,
|
|
395
|
+
panelFullscreenHeightBreakpoint: string,
|
|
396
|
+
): string {
|
|
397
|
+
return `(max-width: ${mobileBreakpoint}), (max-height: ${panelFullscreenHeightBreakpoint})`;
|
|
398
|
+
}
|
|
399
|
+
|
|
398
400
|
function normalizePersistedPanelState(rawState: unknown): PersistedPanelState {
|
|
399
401
|
if (!rawState || typeof rawState !== "object") {
|
|
400
402
|
return createEmptyPersistedPanelState();
|
|
@@ -574,32 +576,20 @@ function escapeHtml(value: string): string {
|
|
|
574
576
|
.replaceAll("'", "'");
|
|
575
577
|
}
|
|
576
578
|
|
|
577
|
-
function
|
|
578
|
-
const normalized = rawLanguage.trim().toLowerCase();
|
|
579
|
-
return PRISM_LANGUAGE_ALIAS[normalized] ?? normalized;
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
function resolvePrismLanguageLabel(language: string): string {
|
|
579
|
+
function resolveAssistantLanguageLabel(language: string): string {
|
|
583
580
|
const normalized = language.trim().toLowerCase();
|
|
584
581
|
if (!normalized) {
|
|
585
582
|
return "";
|
|
586
583
|
}
|
|
587
584
|
|
|
588
585
|
return (
|
|
589
|
-
|
|
586
|
+
ASSISTANT_LANGUAGE_LABEL[normalized] ??
|
|
590
587
|
normalized
|
|
591
588
|
.replace(/[-_]+/g, " ")
|
|
592
589
|
.replace(/\b\w/g, (char) => char.toUpperCase())
|
|
593
590
|
);
|
|
594
591
|
}
|
|
595
592
|
|
|
596
|
-
function resolvePrismGrammar(language: string) {
|
|
597
|
-
return (
|
|
598
|
-
Prism.languages[language] ??
|
|
599
|
-
Prism.languages[PRISM_LANGUAGE_ALIAS[language] ?? ""]
|
|
600
|
-
);
|
|
601
|
-
}
|
|
602
|
-
|
|
603
593
|
function ensureCodeBlockCopyButton(preElement: HTMLPreElement): void {
|
|
604
594
|
const existingButton = Array.from(preElement.children).find(
|
|
605
595
|
(child) =>
|
|
@@ -697,12 +687,23 @@ function unwrapEscapedFenceCodeBlock(rawCode: string): {
|
|
|
697
687
|
}
|
|
698
688
|
|
|
699
689
|
return {
|
|
700
|
-
language:
|
|
690
|
+
language: normalizeAssistantCodeLanguage(languageToken),
|
|
701
691
|
code: lines.slice(1, -1).join("\n"),
|
|
702
692
|
};
|
|
703
693
|
}
|
|
704
694
|
|
|
705
|
-
function
|
|
695
|
+
function stripSerializedCodeBlockTrailingNewline(rawCode: string): string {
|
|
696
|
+
if (rawCode.endsWith("\n")) {
|
|
697
|
+
return rawCode.slice(0, -1);
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
return rawCode;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
async function highlightCodeBlocksInHtml(
|
|
704
|
+
html: string,
|
|
705
|
+
shiki: AssistantShikiRuntimeConfig | undefined,
|
|
706
|
+
): Promise<string> {
|
|
706
707
|
if (typeof document === "undefined" || !html.trim()) {
|
|
707
708
|
return html;
|
|
708
709
|
}
|
|
@@ -711,8 +712,8 @@ function highlightCodeBlocksInHtml(html: string): string {
|
|
|
711
712
|
const container = document.createElement("div");
|
|
712
713
|
container.innerHTML = html;
|
|
713
714
|
|
|
714
|
-
const codeNodes = container.querySelectorAll("pre > code");
|
|
715
|
-
|
|
715
|
+
const codeNodes = Array.from(container.querySelectorAll("pre > code"));
|
|
716
|
+
for (const codeNode of codeNodes) {
|
|
716
717
|
const getLanguageClassName = (element: Element | null) =>
|
|
717
718
|
Array.from(element?.classList ?? []).find(
|
|
718
719
|
(className) =>
|
|
@@ -741,13 +742,14 @@ function highlightCodeBlocksInHtml(html: string): string {
|
|
|
741
742
|
}
|
|
742
743
|
});
|
|
743
744
|
preParent.classList.add(`language-${language}`);
|
|
744
|
-
const languageLabel =
|
|
745
|
+
const languageLabel = resolveAssistantLanguageLabel(language);
|
|
745
746
|
if (languageLabel) {
|
|
746
747
|
preParent.setAttribute("data-language", languageLabel);
|
|
747
748
|
} else {
|
|
748
749
|
preParent.removeAttribute("data-language");
|
|
749
750
|
}
|
|
750
751
|
|
|
752
|
+
codeNode.setAttribute("data-rd-code-theme", "");
|
|
751
753
|
ensureCodeBlockCopyButton(preParent);
|
|
752
754
|
}
|
|
753
755
|
};
|
|
@@ -759,7 +761,9 @@ function highlightCodeBlocksInHtml(html: string): string {
|
|
|
759
761
|
preLanguageClassName?.replace(/^(language-|lang-)/, "") ??
|
|
760
762
|
"";
|
|
761
763
|
|
|
762
|
-
let rawCode =
|
|
764
|
+
let rawCode = stripSerializedCodeBlockTrailingNewline(
|
|
765
|
+
codeNode.textContent ?? "",
|
|
766
|
+
);
|
|
763
767
|
if (!rawLanguage) {
|
|
764
768
|
const unwrappedFence = unwrapEscapedFenceCodeBlock(rawCode);
|
|
765
769
|
if (unwrappedFence) {
|
|
@@ -769,28 +773,37 @@ function highlightCodeBlocksInHtml(html: string): string {
|
|
|
769
773
|
}
|
|
770
774
|
|
|
771
775
|
if (!rawLanguage) {
|
|
772
|
-
|
|
776
|
+
const preParent = codeNode.parentElement;
|
|
777
|
+
if (preParent instanceof HTMLPreElement) {
|
|
778
|
+
ensureCodeBlockCopyButton(preParent);
|
|
779
|
+
}
|
|
780
|
+
continue;
|
|
773
781
|
}
|
|
774
782
|
|
|
775
|
-
const resolvedLanguage =
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
783
|
+
const resolvedLanguage = normalizeAssistantCodeLanguage(rawLanguage);
|
|
784
|
+
setLanguageClass(resolvedLanguage);
|
|
785
|
+
|
|
786
|
+
if (!shiki) {
|
|
787
|
+
codeNode.textContent = rawCode;
|
|
788
|
+
continue;
|
|
781
789
|
}
|
|
782
790
|
|
|
783
|
-
setLanguageClass(resolvedLanguage);
|
|
784
791
|
try {
|
|
785
|
-
const highlighted =
|
|
786
|
-
|
|
792
|
+
const highlighted = await highlightAssistantCodeToHtml({
|
|
793
|
+
code: rawCode,
|
|
794
|
+
config: shiki,
|
|
795
|
+
language: resolvedLanguage,
|
|
796
|
+
});
|
|
797
|
+
setLanguageClass(highlighted.language);
|
|
798
|
+
codeNode.innerHTML = highlighted.html;
|
|
787
799
|
} catch (error) {
|
|
788
800
|
console.error("Assistant embed code highlighting failed", {
|
|
789
801
|
language: resolvedLanguage,
|
|
790
802
|
error,
|
|
791
803
|
});
|
|
804
|
+
codeNode.textContent = rawCode;
|
|
792
805
|
}
|
|
793
|
-
}
|
|
806
|
+
}
|
|
794
807
|
|
|
795
808
|
return container.innerHTML;
|
|
796
809
|
} catch (error) {
|
|
@@ -805,45 +818,139 @@ function highlightCodeBlocksInHtml(html: string): string {
|
|
|
805
818
|
function renderMarkdownToHtml(
|
|
806
819
|
markdown: string,
|
|
807
820
|
linkTarget: AssistantLinkTarget,
|
|
808
|
-
|
|
821
|
+
shiki: AssistantShikiRuntimeConfig | undefined,
|
|
822
|
+
): Promise<string> {
|
|
809
823
|
const normalizedMarkdown = markdown.replaceAll("\r\n", "\n");
|
|
810
|
-
const cacheKey =
|
|
824
|
+
const cacheKey = buildMarkdownCacheKey(normalizedMarkdown, linkTarget, shiki);
|
|
811
825
|
const cached = markdownHtmlCache.get(cacheKey);
|
|
812
826
|
if (cached !== undefined) {
|
|
813
|
-
return cached;
|
|
827
|
+
return Promise.resolve(cached);
|
|
814
828
|
}
|
|
815
829
|
|
|
816
|
-
|
|
830
|
+
const cachedPromise = markdownHtmlPromiseCache.get(cacheKey);
|
|
831
|
+
if (cachedPromise) {
|
|
832
|
+
return cachedPromise;
|
|
833
|
+
}
|
|
817
834
|
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
835
|
+
const renderPromise = (async () => {
|
|
836
|
+
let html = "";
|
|
837
|
+
|
|
838
|
+
try {
|
|
839
|
+
const processor = unified()
|
|
840
|
+
.use(remarkParse)
|
|
841
|
+
.use(remarkGfm)
|
|
842
|
+
.use(remarkRehype, { allowDangerousHtml: false })
|
|
843
|
+
.use(rehypeRebaseInternalLinks);
|
|
844
|
+
|
|
845
|
+
if (linkTarget === "blank") {
|
|
846
|
+
processor.use(rehypeOpenLinksInNewTab);
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
html = String(
|
|
850
|
+
processor.use(rehypeStringify).processSync(normalizedMarkdown),
|
|
851
|
+
);
|
|
852
|
+
} catch {
|
|
853
|
+
html = escapeHtml(normalizedMarkdown).replaceAll("\n", "<br/>");
|
|
827
854
|
}
|
|
828
855
|
|
|
829
|
-
html =
|
|
830
|
-
processor.use(rehypeStringify).processSync(normalizedMarkdown),
|
|
831
|
-
);
|
|
832
|
-
} catch {
|
|
833
|
-
html = escapeHtml(normalizedMarkdown).replaceAll("\n", "<br/>");
|
|
834
|
-
}
|
|
856
|
+
html = await highlightCodeBlocksInHtml(html, shiki);
|
|
835
857
|
|
|
836
|
-
|
|
858
|
+
markdownHtmlCache.set(cacheKey, html);
|
|
859
|
+
if (markdownHtmlCache.size > MARKDOWN_HTML_CACHE_LIMIT) {
|
|
860
|
+
const oldestKey = markdownHtmlCache.keys().next().value;
|
|
861
|
+
if (oldestKey) {
|
|
862
|
+
markdownHtmlCache.delete(oldestKey);
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
markdownHtmlPromiseCache.delete(cacheKey);
|
|
867
|
+
return html;
|
|
868
|
+
})();
|
|
869
|
+
|
|
870
|
+
markdownHtmlPromiseCache.set(cacheKey, renderPromise);
|
|
871
|
+
return renderPromise;
|
|
872
|
+
}
|
|
837
873
|
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
874
|
+
function getCachedMarkdownHtml(
|
|
875
|
+
markdown: string,
|
|
876
|
+
linkTarget: AssistantLinkTarget,
|
|
877
|
+
shiki: AssistantShikiRuntimeConfig | undefined,
|
|
878
|
+
): string | undefined {
|
|
879
|
+
return markdownHtmlCache.get(
|
|
880
|
+
buildMarkdownCacheKey(markdown.replaceAll("\r\n", "\n"), linkTarget, shiki),
|
|
881
|
+
);
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
function AssistantMarkdownBlock({
|
|
885
|
+
className,
|
|
886
|
+
linkTarget,
|
|
887
|
+
markdown,
|
|
888
|
+
onClick,
|
|
889
|
+
onRendered,
|
|
890
|
+
shiki,
|
|
891
|
+
}: {
|
|
892
|
+
className: string;
|
|
893
|
+
linkTarget: AssistantLinkTarget;
|
|
894
|
+
markdown: string;
|
|
895
|
+
onClick: (event: JSX.TargetedMouseEvent<HTMLDivElement>) => void;
|
|
896
|
+
onRendered?: () => void;
|
|
897
|
+
shiki?: AssistantShikiRuntimeConfig;
|
|
898
|
+
}) {
|
|
899
|
+
const onRenderedRef = useRef(onRendered);
|
|
900
|
+
const [html, setHtml] = useState(
|
|
901
|
+
() => getCachedMarkdownHtml(markdown, linkTarget, shiki) ?? "",
|
|
902
|
+
);
|
|
903
|
+
|
|
904
|
+
useEffect(() => {
|
|
905
|
+
onRenderedRef.current = onRendered;
|
|
906
|
+
}, [onRendered]);
|
|
907
|
+
|
|
908
|
+
useEffect(() => {
|
|
909
|
+
let isCancelled = false;
|
|
910
|
+
const cached = getCachedMarkdownHtml(markdown, linkTarget, shiki);
|
|
911
|
+
if (cached !== undefined) {
|
|
912
|
+
setHtml(cached);
|
|
913
|
+
onRenderedRef.current?.();
|
|
914
|
+
return () => {
|
|
915
|
+
isCancelled = true;
|
|
916
|
+
};
|
|
843
917
|
}
|
|
844
|
-
}
|
|
845
918
|
|
|
846
|
-
|
|
919
|
+
void renderMarkdownToHtml(markdown, linkTarget, shiki)
|
|
920
|
+
.then((nextHtml) => {
|
|
921
|
+
if (isCancelled) return;
|
|
922
|
+
setHtml((previousHtml) =>
|
|
923
|
+
previousHtml === nextHtml ? previousHtml : nextHtml,
|
|
924
|
+
);
|
|
925
|
+
onRenderedRef.current?.();
|
|
926
|
+
})
|
|
927
|
+
.catch((error) => {
|
|
928
|
+
if (isCancelled) return;
|
|
929
|
+
console.error("Assistant embed markdown rendering failed", error);
|
|
930
|
+
setHtml(escapeHtml(markdown).replaceAll("\n", "<br/>"));
|
|
931
|
+
onRenderedRef.current?.();
|
|
932
|
+
});
|
|
933
|
+
|
|
934
|
+
return () => {
|
|
935
|
+
isCancelled = true;
|
|
936
|
+
};
|
|
937
|
+
}, [
|
|
938
|
+
linkTarget,
|
|
939
|
+
markdown,
|
|
940
|
+
shiki?.assetBaseUrl,
|
|
941
|
+
shiki?.syntaxThemes.dark,
|
|
942
|
+
shiki?.syntaxThemes.light,
|
|
943
|
+
]);
|
|
944
|
+
|
|
945
|
+
return (
|
|
946
|
+
<div
|
|
947
|
+
className={className}
|
|
948
|
+
onClick={onClick}
|
|
949
|
+
dangerouslySetInnerHTML={{
|
|
950
|
+
__html: html,
|
|
951
|
+
}}
|
|
952
|
+
/>
|
|
953
|
+
);
|
|
847
954
|
}
|
|
848
955
|
|
|
849
956
|
function extractErrorMessage(rawBody: string): string {
|
|
@@ -944,11 +1051,18 @@ export default function AssistantEmbedPanel({
|
|
|
944
1051
|
allowApiPathQueryOverride = true,
|
|
945
1052
|
openSignal = 0,
|
|
946
1053
|
panelSize,
|
|
1054
|
+
mobileBreakpoint = DEFAULT_ASSISTANT_MOBILE_BREAKPOINT,
|
|
1055
|
+
panelFullscreenHeightBreakpoint = DEFAULT_ASSISTANT_PANEL_FULLSCREEN_HEIGHT_BREAKPOINT,
|
|
947
1056
|
onRequestOpen,
|
|
948
1057
|
onRequestClose,
|
|
949
1058
|
onRequestPanelSizeToggle,
|
|
950
1059
|
onCurrentLinkNavigate,
|
|
1060
|
+
shiki,
|
|
951
1061
|
}: AssistantEmbedPanelProps) {
|
|
1062
|
+
const panelFullscreenMediaQuery = getPanelFullscreenMediaQuery(
|
|
1063
|
+
mobileBreakpoint,
|
|
1064
|
+
panelFullscreenHeightBreakpoint,
|
|
1065
|
+
);
|
|
952
1066
|
const [initialPanelState] = useState<PersistedPanelState>(() =>
|
|
953
1067
|
canSendChatRequest
|
|
954
1068
|
? readPersistedPanelState()
|
|
@@ -969,7 +1083,17 @@ export default function AssistantEmbedPanel({
|
|
|
969
1083
|
const [localPanelSize, setLocalPanelSize] = useState<AssistantPanelSize>(
|
|
970
1084
|
panelSize ?? initialPanelState.panelSize,
|
|
971
1085
|
);
|
|
972
|
-
const [isShellFullscreen, setIsShellFullscreen] = useState(
|
|
1086
|
+
const [isShellFullscreen, setIsShellFullscreen] = useState(() => {
|
|
1087
|
+
if (
|
|
1088
|
+
panelSurface !== "inline" ||
|
|
1089
|
+
typeof window === "undefined" ||
|
|
1090
|
+
typeof window.matchMedia !== "function"
|
|
1091
|
+
) {
|
|
1092
|
+
return false;
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
return window.matchMedia(panelFullscreenMediaQuery).matches;
|
|
1096
|
+
});
|
|
973
1097
|
const activeRequestAbortRef = useRef<AbortController | null>(null);
|
|
974
1098
|
const scrollViewportRef = useRef<HTMLDivElement | null>(null);
|
|
975
1099
|
const savedScrollTopRef = useRef(initialPanelState.scrollTop);
|
|
@@ -1541,6 +1665,27 @@ export default function AssistantEmbedPanel({
|
|
|
1541
1665
|
notifyPanelSizeChange(resolvedPanelSize);
|
|
1542
1666
|
}, [resolvedPanelSize]);
|
|
1543
1667
|
|
|
1668
|
+
useEffect(() => {
|
|
1669
|
+
if (
|
|
1670
|
+
panelSurface !== "inline" ||
|
|
1671
|
+
typeof window === "undefined" ||
|
|
1672
|
+
typeof window.matchMedia !== "function"
|
|
1673
|
+
) {
|
|
1674
|
+
return;
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
const mediaQuery = window.matchMedia(panelFullscreenMediaQuery);
|
|
1678
|
+
const updateShellLayout = () => {
|
|
1679
|
+
setIsShellFullscreen(mediaQuery.matches);
|
|
1680
|
+
};
|
|
1681
|
+
|
|
1682
|
+
updateShellLayout();
|
|
1683
|
+
mediaQuery.addEventListener("change", updateShellLayout);
|
|
1684
|
+
return () => {
|
|
1685
|
+
mediaQuery.removeEventListener("change", updateShellLayout);
|
|
1686
|
+
};
|
|
1687
|
+
}, [panelFullscreenMediaQuery, panelSurface]);
|
|
1688
|
+
|
|
1544
1689
|
useEffect(() => {
|
|
1545
1690
|
if (typeof window === "undefined") {
|
|
1546
1691
|
return;
|
|
@@ -1949,6 +2094,12 @@ export default function AssistantEmbedPanel({
|
|
|
1949
2094
|
});
|
|
1950
2095
|
};
|
|
1951
2096
|
|
|
2097
|
+
const handleMarkdownRendered = () => {
|
|
2098
|
+
if (isBusyRef.current) {
|
|
2099
|
+
queueThreadScrollToBottom(messagesRef.current);
|
|
2100
|
+
}
|
|
2101
|
+
};
|
|
2102
|
+
|
|
1952
2103
|
const panelClassName = [
|
|
1953
2104
|
"relative flex min-h-0 flex-col overflow-hidden text-neutral-900 shadow-2xl dark:text-neutral-50",
|
|
1954
2105
|
panelSurface === "inline"
|
|
@@ -1963,7 +2114,7 @@ export default function AssistantEmbedPanel({
|
|
|
1963
2114
|
<AssistantPanelIcon
|
|
1964
2115
|
color={launcherIconColor}
|
|
1965
2116
|
imageSrc={launcherIconImageSrc}
|
|
1966
|
-
className="assistant-embed-header-icon inline-flex size-9 shrink-0 items-center justify-center rounded-md dark:border-[0.5px] border-neutral-900/7 bg-
|
|
2117
|
+
className="assistant-embed-header-icon inline-flex size-9 shrink-0 items-center justify-center rounded-md dark:border-[0.5px] border-neutral-900/7 bg-neutral-700/7 dark:bg-white/6 text-neutral-900 dark:border-white/7 dark:text-neutral-50 [&_img]:block [&_img]:size-5.5 [&_img]:object-contain [&_svg]:static [&_svg]:block [&_svg]:size-5 [&_svg]:transform-none [&_svg]:opacity-100"
|
|
1967
2118
|
/>
|
|
1968
2119
|
<div className="min-w-0 space-y-px">
|
|
1969
2120
|
<p className="truncate text-sm font-medium leading-3.5 text-neutral-900 dark:text-neutral-50">
|
|
@@ -2041,7 +2192,7 @@ export default function AssistantEmbedPanel({
|
|
|
2041
2192
|
{messages.length === 0 ? (
|
|
2042
2193
|
<div
|
|
2043
2194
|
key={emptyStateAnimationKey}
|
|
2044
|
-
className="flex min-h-full flex-col items-center justify-center
|
|
2195
|
+
className="flex min-h-full flex-col items-center justify-center py-8 text-center"
|
|
2045
2196
|
>
|
|
2046
2197
|
<AssistantPanelIcon
|
|
2047
2198
|
color={launcherIconColor}
|
|
@@ -2069,7 +2220,7 @@ export default function AssistantEmbedPanel({
|
|
|
2069
2220
|
<button
|
|
2070
2221
|
key={question}
|
|
2071
2222
|
type="button"
|
|
2072
|
-
className="assistant-empty-state-item w-fit rounded-full border-neutral-900/8 bg-white/90 px-3.5 py-2 text-
|
|
2223
|
+
className="assistant-empty-state-item w-fit rounded-full border-neutral-900/8 bg-white/90 px-3.5 py-2 text-center text-[13px] leading-5 text-neutral-700 shadow-[0px_1px_3px_0px_rgba(0,0,0,0.04),0px_0px_0px_1px_rgba(0,0,0,0.06)_inset,0px_-1px_0px_0px_rgba(0,0,0,0.06)_inset] transition hover:bg-white dark:bg-white/4 dark:text-neutral-200 dark:hover:bg-white/8 cursor-pointer dark:shadow-[0_1px_3px_0_rgba(0,0,0,0.04),inset_0_1px_0_0_rgba(255,255,255,0.04),inset_0_0_0_1px_rgba(0,0,0,0.06),inset_0_-1px_0_0_rgba(0,0,0,0.06),inset_0_0_0_1px_rgba(196,196,196,0.07)]"
|
|
2073
2224
|
style={
|
|
2074
2225
|
{
|
|
2075
2226
|
"--assistant-empty-state-delay": `${400 + index * 100}ms`,
|
|
@@ -2101,17 +2252,18 @@ export default function AssistantEmbedPanel({
|
|
|
2101
2252
|
key={message.id}
|
|
2102
2253
|
className={isUser ? "text-right" : "text-left"}
|
|
2103
2254
|
>
|
|
2104
|
-
<
|
|
2255
|
+
<AssistantMarkdownBlock
|
|
2105
2256
|
className={[
|
|
2106
2257
|
"ask-ai-markdown prose-rules text-[15px]! max-w-full min-w-0 wrap-break-word prose-code:text-neutral-700 dark:prose-code:text-neutral-200 prose-pre:shadow-xs prose-pre:text-neutral-700! dark:prose-pre:text-neutral-100! prose-pre:border prose-pre:border-neutral-200 dark:prose-pre:border-neutral-800 prose-pre:rounded-xl!",
|
|
2107
2258
|
isUser
|
|
2108
2259
|
? "inline-block ml-2 px-3 py-1.5 rounded-2xl rounded-br-sm bg-neutral-900/5 text-neutral-700/85 dark:bg-neutral-800 dark:text-neutral-100 *:text-left"
|
|
2109
2260
|
: "block w-full bg-transparent text-neutral-900 dark:text-neutral-100",
|
|
2110
2261
|
].join(" ")}
|
|
2262
|
+
linkTarget={linkTarget}
|
|
2263
|
+
markdown={message.content}
|
|
2111
2264
|
onClick={handleRenderedMarkdownClick}
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
}}
|
|
2265
|
+
onRendered={handleMarkdownRendered}
|
|
2266
|
+
shiki={shiki}
|
|
2115
2267
|
/>
|
|
2116
2268
|
</div>
|
|
2117
2269
|
);
|
|
@@ -2152,7 +2304,10 @@ export default function AssistantEmbedPanel({
|
|
|
2152
2304
|
}}
|
|
2153
2305
|
onKeyDown={handleChatInputKeyDown}
|
|
2154
2306
|
placeholder="Ask a question..."
|
|
2155
|
-
className=
|
|
2307
|
+
className={[
|
|
2308
|
+
"assistant-embed-input my-auto min-w-0 flex-1 bg-transparent pl-4 py-2.5 text-neutral-900 placeholder:text-neutral-400 focus:outline-none dark:text-white dark:placeholder:text-neutral-400 leading-5 resize-none [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
|
|
2309
|
+
isShellFullscreen ? "text-base" : "text-sm",
|
|
2310
|
+
].join(" ")}
|
|
2156
2311
|
disabled={isBusy}
|
|
2157
2312
|
rows={1}
|
|
2158
2313
|
/>
|
|
@@ -2198,14 +2353,25 @@ export default function AssistantEmbedPanel({
|
|
|
2198
2353
|
</p>
|
|
2199
2354
|
<button
|
|
2200
2355
|
type="button"
|
|
2201
|
-
className="mt-1 inline-flex items-center gap-1.5 rounded-md border border-neutral-900/8 bg-white px-2.5 py-1.5 text-[13px] font-medium text-neutral-700 shadow-xs transition hover:bg-neutral-50 dark:border-white/10 dark:bg-white/5 dark:text-neutral-200 dark:hover:bg-white/10 cursor-pointer"
|
|
2356
|
+
className="mt-1 inline-flex items-center gap-1.5 rounded-md border border-neutral-900/8 bg-white px-2.5 py-1.5 text-[13px] font-medium text-neutral-700 shadow-xs transition hover:bg-neutral-50/80 dark:border-white/10 dark:bg-white/5 dark:text-neutral-200 dark:hover:bg-white/10 cursor-pointer"
|
|
2202
2357
|
onClick={handleUnavailableBack}
|
|
2203
2358
|
>
|
|
2204
|
-
<
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2359
|
+
<svg
|
|
2360
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
2361
|
+
width="14px"
|
|
2362
|
+
height="14px"
|
|
2363
|
+
viewBox="0 0 24 24"
|
|
2364
|
+
>
|
|
2365
|
+
<path d="M0 0h24v24H0z" fill="none" />
|
|
2366
|
+
<path
|
|
2367
|
+
fill="none"
|
|
2368
|
+
stroke="currentColor"
|
|
2369
|
+
stroke-linecap="round"
|
|
2370
|
+
stroke-linejoin="round"
|
|
2371
|
+
stroke-width="2"
|
|
2372
|
+
d="m12 19l-7-7l7-7m7 7H5"
|
|
2373
|
+
/>
|
|
2374
|
+
</svg>
|
|
2209
2375
|
Back
|
|
2210
2376
|
</button>
|
|
2211
2377
|
</div>
|
|
@@ -2250,7 +2416,7 @@ export default function AssistantEmbedPanel({
|
|
|
2250
2416
|
max-width: 100%;
|
|
2251
2417
|
min-width: 0;
|
|
2252
2418
|
box-sizing: border-box;
|
|
2253
|
-
padding
|
|
2419
|
+
padding: 2.25rem 0 0 !important;
|
|
2254
2420
|
background: var(--color-neutral-50) !important;
|
|
2255
2421
|
overflow-x: hidden;
|
|
2256
2422
|
overflow-y: hidden;
|
|
@@ -2315,10 +2481,6 @@ export default function AssistantEmbedPanel({
|
|
|
2315
2481
|
justify-content: center;
|
|
2316
2482
|
width: 1.75rem;
|
|
2317
2483
|
height: 1.75rem;
|
|
2318
|
-
border: 1px solid
|
|
2319
|
-
color-mix(in oklab, var(--color-neutral-200) 80%, transparent);
|
|
2320
|
-
background: color-mix(in oklab, #fff 80%, transparent);
|
|
2321
|
-
backdrop-filter: blur(4px);
|
|
2322
2484
|
color: color-mix(
|
|
2323
2485
|
in oklab,
|
|
2324
2486
|
var(--color-neutral-500) 80%,
|
|
@@ -2333,22 +2495,14 @@ export default function AssistantEmbedPanel({
|
|
|
2333
2495
|
}
|
|
2334
2496
|
|
|
2335
2497
|
.dark .ask-ai-markdown .ask-ai-copy-code-button {
|
|
2336
|
-
border-color: color-mix(
|
|
2337
|
-
in oklab,
|
|
2338
|
-
var(--color-neutral-700) 50%,
|
|
2339
|
-
transparent
|
|
2340
|
-
);
|
|
2341
|
-
background: var(--rd-code-surface);
|
|
2342
2498
|
color: var(--color-neutral-400);
|
|
2343
2499
|
}
|
|
2344
2500
|
|
|
2345
2501
|
.ask-ai-markdown .ask-ai-copy-code-button:hover {
|
|
2346
|
-
background: var(--color-neutral-50);
|
|
2347
2502
|
color: var(--color-neutral-600);
|
|
2348
2503
|
}
|
|
2349
2504
|
|
|
2350
2505
|
.dark .ask-ai-markdown .ask-ai-copy-code-button:hover {
|
|
2351
|
-
background: var(--color-neutral-800);
|
|
2352
2506
|
color: var(--color-neutral-200);
|
|
2353
2507
|
}
|
|
2354
2508
|
|
|
@@ -2426,6 +2580,7 @@ export default function AssistantEmbedPanel({
|
|
|
2426
2580
|
display: block;
|
|
2427
2581
|
width: 100%;
|
|
2428
2582
|
min-width: 100%;
|
|
2583
|
+
padding-block: 0.625rem;
|
|
2429
2584
|
background: transparent !important;
|
|
2430
2585
|
white-space: inherit;
|
|
2431
2586
|
word-break: normal;
|
|
@@ -2471,164 +2626,6 @@ export default function AssistantEmbedPanel({
|
|
|
2471
2626
|
background: var(--color-neutral-800);
|
|
2472
2627
|
}
|
|
2473
2628
|
|
|
2474
|
-
.dark .ask-ai-markdown .token.comment,
|
|
2475
|
-
.dark .ask-ai-markdown .token.prolog,
|
|
2476
|
-
.dark .ask-ai-markdown .token.doctype,
|
|
2477
|
-
.dark .ask-ai-markdown .token.cdata {
|
|
2478
|
-
color: #7f848e;
|
|
2479
|
-
}
|
|
2480
|
-
|
|
2481
|
-
.dark .ask-ai-markdown .token.punctuation {
|
|
2482
|
-
color: #abb2bf;
|
|
2483
|
-
}
|
|
2484
|
-
|
|
2485
|
-
.dark .ask-ai-markdown .token.property,
|
|
2486
|
-
.dark .ask-ai-markdown .token.tag,
|
|
2487
|
-
.dark .ask-ai-markdown .token.boolean,
|
|
2488
|
-
.dark .ask-ai-markdown .token.number,
|
|
2489
|
-
.dark .ask-ai-markdown .token.constant,
|
|
2490
|
-
.dark .ask-ai-markdown .token.symbol,
|
|
2491
|
-
.dark .ask-ai-markdown .token.deleted {
|
|
2492
|
-
color: #d19a66;
|
|
2493
|
-
}
|
|
2494
|
-
|
|
2495
|
-
.dark .ask-ai-markdown .token.selector,
|
|
2496
|
-
.dark .ask-ai-markdown .token.attr-name,
|
|
2497
|
-
.dark .ask-ai-markdown .token.string,
|
|
2498
|
-
.dark .ask-ai-markdown .token.char,
|
|
2499
|
-
.dark .ask-ai-markdown .token.builtin,
|
|
2500
|
-
.dark .ask-ai-markdown .token.inserted {
|
|
2501
|
-
color: #98c379;
|
|
2502
|
-
}
|
|
2503
|
-
|
|
2504
|
-
.dark .ask-ai-markdown .token.operator,
|
|
2505
|
-
.dark .ask-ai-markdown .token.entity,
|
|
2506
|
-
.dark .ask-ai-markdown .token.url,
|
|
2507
|
-
.dark .ask-ai-markdown .language-css .token.string,
|
|
2508
|
-
.dark .ask-ai-markdown .style .token.string {
|
|
2509
|
-
color: #56b6c2;
|
|
2510
|
-
}
|
|
2511
|
-
|
|
2512
|
-
.dark .ask-ai-markdown .token.atrule,
|
|
2513
|
-
.dark .ask-ai-markdown .token.attr-value,
|
|
2514
|
-
.dark .ask-ai-markdown .token.keyword {
|
|
2515
|
-
color: #c678dd;
|
|
2516
|
-
}
|
|
2517
|
-
|
|
2518
|
-
.dark .ask-ai-markdown .token.function,
|
|
2519
|
-
.dark .ask-ai-markdown .token.class-name {
|
|
2520
|
-
color: #e5c07b;
|
|
2521
|
-
}
|
|
2522
|
-
|
|
2523
|
-
.dark .ask-ai-markdown .token.regex,
|
|
2524
|
-
.dark .ask-ai-markdown .token.important,
|
|
2525
|
-
.dark .ask-ai-markdown .token.variable {
|
|
2526
|
-
color: #e06c75;
|
|
2527
|
-
}
|
|
2528
|
-
|
|
2529
|
-
.dark .ask-ai-markdown .token.attr-value > .token.punctuation.attr-equals,
|
|
2530
|
-
.dark
|
|
2531
|
-
.ask-ai-markdown
|
|
2532
|
-
.token.special-attr
|
|
2533
|
-
> .token.attr-value
|
|
2534
|
-
> .token.value.css {
|
|
2535
|
-
color: #abb2bf;
|
|
2536
|
-
}
|
|
2537
|
-
|
|
2538
|
-
.dark .ask-ai-markdown .language-css .token.selector {
|
|
2539
|
-
color: #d19a66;
|
|
2540
|
-
}
|
|
2541
|
-
|
|
2542
|
-
.dark .ask-ai-markdown .language-css .token.property {
|
|
2543
|
-
color: #abb2bf;
|
|
2544
|
-
}
|
|
2545
|
-
|
|
2546
|
-
.dark .ask-ai-markdown .language-css .token.function,
|
|
2547
|
-
.dark .ask-ai-markdown .language-css .token.url > .token.function {
|
|
2548
|
-
color: #56b6c2;
|
|
2549
|
-
}
|
|
2550
|
-
|
|
2551
|
-
.dark .ask-ai-markdown .language-css .token.url > .token.string.url {
|
|
2552
|
-
color: #98c379;
|
|
2553
|
-
}
|
|
2554
|
-
|
|
2555
|
-
.dark .ask-ai-markdown .language-css .token.important,
|
|
2556
|
-
.dark .ask-ai-markdown .language-css .token.atrule .token.rule {
|
|
2557
|
-
color: #c678dd;
|
|
2558
|
-
}
|
|
2559
|
-
|
|
2560
|
-
.dark .ask-ai-markdown .language-javascript .token.operator {
|
|
2561
|
-
color: #c678dd;
|
|
2562
|
-
}
|
|
2563
|
-
|
|
2564
|
-
.dark
|
|
2565
|
-
.ask-ai-markdown
|
|
2566
|
-
.language-javascript
|
|
2567
|
-
.token.template-string
|
|
2568
|
-
> .token.interpolation
|
|
2569
|
-
> .token.interpolation-punctuation.punctuation {
|
|
2570
|
-
color: #e06c75;
|
|
2571
|
-
}
|
|
2572
|
-
|
|
2573
|
-
.dark .ask-ai-markdown .language-json .token.operator {
|
|
2574
|
-
color: #abb2bf;
|
|
2575
|
-
}
|
|
2576
|
-
|
|
2577
|
-
.dark .ask-ai-markdown .language-json .token.null.keyword {
|
|
2578
|
-
color: #d19a66;
|
|
2579
|
-
}
|
|
2580
|
-
|
|
2581
|
-
.dark .ask-ai-markdown .language-markdown .token.url,
|
|
2582
|
-
.dark .ask-ai-markdown .language-markdown .token.url > .token.operator,
|
|
2583
|
-
.dark
|
|
2584
|
-
.ask-ai-markdown
|
|
2585
|
-
.language-markdown
|
|
2586
|
-
.token.url-reference.url
|
|
2587
|
-
> .token.string {
|
|
2588
|
-
color: #abb2bf;
|
|
2589
|
-
}
|
|
2590
|
-
|
|
2591
|
-
.dark .ask-ai-markdown .language-markdown .token.url > .token.content {
|
|
2592
|
-
color: #56b6c2;
|
|
2593
|
-
}
|
|
2594
|
-
|
|
2595
|
-
.dark .ask-ai-markdown .language-markdown .token.url > .token.url,
|
|
2596
|
-
.dark .ask-ai-markdown .language-markdown .token.url-reference.url {
|
|
2597
|
-
color: #98c379;
|
|
2598
|
-
}
|
|
2599
|
-
|
|
2600
|
-
.dark .ask-ai-markdown .language-markdown .token.blockquote.punctuation,
|
|
2601
|
-
.dark .ask-ai-markdown .language-markdown .token.hr.punctuation {
|
|
2602
|
-
color: #7f848e;
|
|
2603
|
-
}
|
|
2604
|
-
|
|
2605
|
-
.dark .ask-ai-markdown .language-markdown .token.code-snippet {
|
|
2606
|
-
color: #98c379;
|
|
2607
|
-
}
|
|
2608
|
-
|
|
2609
|
-
.dark .ask-ai-markdown .language-markdown .token.bold .token.content {
|
|
2610
|
-
color: #e5c07b;
|
|
2611
|
-
}
|
|
2612
|
-
|
|
2613
|
-
.dark .ask-ai-markdown .language-markdown .token.italic .token.content {
|
|
2614
|
-
color: #c678dd;
|
|
2615
|
-
}
|
|
2616
|
-
|
|
2617
|
-
.dark .ask-ai-markdown .language-markdown .token.strike .token.content,
|
|
2618
|
-
.dark
|
|
2619
|
-
.ask-ai-markdown
|
|
2620
|
-
.language-markdown
|
|
2621
|
-
.token.strike
|
|
2622
|
-
.token.punctuation,
|
|
2623
|
-
.dark .ask-ai-markdown .language-markdown .token.list.punctuation,
|
|
2624
|
-
.dark
|
|
2625
|
-
.ask-ai-markdown
|
|
2626
|
-
.language-markdown
|
|
2627
|
-
.token.title.important
|
|
2628
|
-
> .token.punctuation {
|
|
2629
|
-
color: #e06c75;
|
|
2630
|
-
}
|
|
2631
|
-
|
|
2632
2629
|
.ask-ai-markdown pre > code::-webkit-scrollbar {
|
|
2633
2630
|
width: 0;
|
|
2634
2631
|
height: 0;
|