ai-spector 0.8.81 → 0.8.82
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/README.md +1 -1
- package/README.vi.md +1 -1
- package/dist/core/course/catalog.d.ts.map +1 -1
- package/dist/core/course/catalog.js +17 -12
- package/dist/core/course/catalog.js.map +1 -1
- package/dist/core/course/fallback.d.ts +9 -0
- package/dist/core/course/fallback.d.ts.map +1 -0
- package/dist/core/course/fallback.js +15 -0
- package/dist/core/course/fallback.js.map +1 -0
- package/dist/core/course/html-shell.d.ts +1 -0
- package/dist/core/course/html-shell.d.ts.map +1 -1
- package/dist/core/course/html-shell.js +45 -6
- package/dist/core/course/html-shell.js.map +1 -1
- package/dist/core/course/locale.d.ts +9 -7
- package/dist/core/course/locale.d.ts.map +1 -1
- package/dist/core/course/locale.js +77 -30
- package/dist/core/course/locale.js.map +1 -1
- package/dist/core/course/redirects.d.ts +3 -0
- package/dist/core/course/redirects.d.ts.map +1 -0
- package/dist/core/course/redirects.js +33 -0
- package/dist/core/course/redirects.js.map +1 -0
- package/dist/core/course/render.d.ts +7 -0
- package/dist/core/course/render.d.ts.map +1 -1
- package/dist/core/course/render.js +35 -2
- package/dist/core/course/render.js.map +1 -1
- package/dist/core/course/sections.js +7 -7
- package/dist/core/course/sections.js.map +1 -1
- package/dist/core/course/serve.d.ts.map +1 -1
- package/dist/core/course/serve.js +30 -6
- package/dist/core/course/serve.js.map +1 -1
- package/dist/core/operations/init.js +1 -1
- package/dist/core/operations/init.js.map +1 -1
- package/dist/core/operations/setup.js +1 -1
- package/dist/core/operations/setup.js.map +1 -1
- package/package.json +1 -1
- package/scaffold/claude/.claude/skills/ai-spector-course/references/course-guide.md +48 -41
- package/scaffold/claude/.claude/skills/ai-spector-course/skill.md +12 -9
- package/scaffold/cursor/skills/ai-spector-course/SKILL.md +12 -9
- package/scaffold/cursor/skills/ai-spector-course/references/course-guide.md +48 -41
- package/website/README.md +13 -4
- package/website/docs/en/01-welcome/01-what-is-ai-spector.md +60 -0
- package/website/docs/en/01-welcome/README.md +7 -0
- package/website/docs/en/02-get-started/01-setup-via-chat.md +66 -0
- package/website/docs/en/02-get-started/README.md +7 -0
- package/website/docs/en/03-chat-basics/01-how-chat-works.md +72 -0
- package/website/docs/en/03-chat-basics/02-four-kinds-of-approve.md +64 -0
- package/website/docs/en/03-chat-basics/README.md +8 -0
- package/website/docs/en/04-changes/01-add-or-change-requirement.md +58 -0
- package/website/docs/en/04-changes/README.md +7 -0
- package/website/docs/en/05-generate/01-generate-srs.md +67 -0
- package/website/docs/en/05-generate/README.md +7 -0
- package/website/docs/en/06-review/01-document-review.md +61 -0
- package/website/docs/en/06-review/02-resolve-comments.md +56 -0
- package/website/docs/en/06-review/README.md +8 -0
- package/website/docs/en/07-everyday/01-tasks-and-workspace.md +71 -0
- package/website/docs/en/07-everyday/README.md +5 -0
- package/website/docs/en/README.md +32 -0
- package/website/docs/vi/01-welcome/01-what-is-ai-spector.md +60 -0
- package/website/docs/vi/01-welcome/README.md +7 -0
- package/website/docs/vi/02-get-started/01-setup-via-chat.md +66 -0
- package/website/docs/vi/02-get-started/README.md +7 -0
- package/website/docs/vi/03-chat-basics/01-how-chat-works.md +72 -0
- package/website/docs/vi/03-chat-basics/02-four-kinds-of-approve.md +64 -0
- package/website/docs/vi/03-chat-basics/README.md +8 -0
- package/website/docs/vi/04-changes/01-add-or-change-requirement.md +58 -0
- package/website/docs/vi/04-changes/README.md +7 -0
- package/website/docs/vi/05-generate/01-generate-srs.md +67 -0
- package/website/docs/vi/05-generate/README.md +7 -0
- package/website/docs/vi/06-review/01-document-review.md +61 -0
- package/website/docs/vi/06-review/02-resolve-comments.md +56 -0
- package/website/docs/vi/06-review/README.md +8 -0
- package/website/docs/vi/07-everyday/01-tasks-and-workspace.md +71 -0
- package/website/docs/vi/07-everyday/README.md +5 -0
- package/website/docs/vi/README.md +32 -0
- package/website/docs/01-get-started/01-prerequisites-and-init.md +0 -88
- package/website/docs/01-get-started/02-setup-and-skills.md +0 -70
- package/website/docs/01-get-started/README.md +0 -17
- package/website/docs/01-get-started/_category_.json +0 -4
- package/website/docs/02-chat-basics/01-how-chat-works.md +0 -95
- package/website/docs/02-chat-basics/02-workspace-and-tasks.md +0 -82
- package/website/docs/02-chat-basics/03-incremental-changes.md +0 -59
- package/website/docs/02-chat-basics/README.md +0 -19
- package/website/docs/02-chat-basics/_category_.json +0 -4
- package/website/docs/03-graph/01-sources-and-analyze.md +0 -70
- package/website/docs/03-graph/02-validate-index-explore.md +0 -83
- package/website/docs/03-graph/README.md +0 -18
- package/website/docs/03-graph/_category_.json +0 -4
- package/website/docs/04-generate/01-generate-srs.md +0 -101
- package/website/docs/04-generate/02-basic-design.md +0 -61
- package/website/docs/04-generate/README.md +0 -21
- package/website/docs/04-generate/_category_.json +0 -4
- package/website/docs/05-prototype/01-translations.md +0 -43
- package/website/docs/05-prototype/02-build-prototype.md +0 -142
- package/website/docs/05-prototype/03-external-prototype-map.md +0 -127
- package/website/docs/05-prototype/README.md +0 -11
- package/website/docs/05-prototype/_category_.json +0 -4
- package/website/docs/06-review/01-document-review.md +0 -108
- package/website/docs/06-review/02-comment-threads.md +0 -68
- package/website/docs/06-review/README.md +0 -12
- package/website/docs/06-review/_category_.json +0 -4
- package/website/docs/07-advanced/01-custom-templates.md +0 -46
- package/website/docs/07-advanced/02-search-and-editors.md +0 -52
- package/website/docs/07-advanced/README.md +0 -10
- package/website/docs/07-advanced/_category_.json +0 -4
- package/website/docs/README.md +0 -56
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Documentation workflow in **Cursor** or **Claude Code**: traceability graph, SRS
|
|
|
4
4
|
|
|
5
5
|
**Needs:** Node 20+, Git, [Cursor](https://cursor.com) and/or [Claude Code](https://docs.anthropic.com/en/docs/claude-code), Python 3.11+ *(optional — CocoIndex semantic search)*.
|
|
6
6
|
|
|
7
|
-
**Learn:** `npm run docs:dev` · [Course](website/docs/README.md) · Tiếng Việt: `/vi/docs/` · Offline: `npx ai-spector course serve --open`
|
|
7
|
+
**Learn:** `npm run docs:dev` · [Course](website/docs/en/README.md) · Tiếng Việt: `/vi/docs/` · Offline: `npx ai-spector course serve --open`
|
|
8
8
|
|
|
9
9
|
**Tiếng Việt:** [README.vi.md](README.vi.md)
|
|
10
10
|
|
package/README.vi.md
CHANGED
|
@@ -4,7 +4,7 @@ Công cụ làm tài liệu phần mềm trên **Cursor** hoặc **Claude Code**
|
|
|
4
4
|
|
|
5
5
|
**Cần có:** Node 20+, Git, [Cursor](https://cursor.com) và/hoặc [Claude Code](https://docs.anthropic.com/en/docs/claude-code), Python 3.11+ *(không bắt buộc — dùng cho tìm kiếm thông minh với CocoIndex)*.
|
|
6
6
|
|
|
7
|
-
Hướng dẫn từng bước: `npm run docs:dev` hoặc `npx ai-spector course serve --open` · [Course](website/docs/README.md)
|
|
7
|
+
Hướng dẫn từng bước: `npm run docs:dev` hoặc `npx ai-spector course serve --open` · [Course](website/docs/vi/README.md)
|
|
8
8
|
|
|
9
9
|
**English:** [README.md](README.md)
|
|
10
10
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../../src/core/course/catalog.ts"],"names":[],"mappings":"AAIA,OAAO,EAAyB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAGvE,MAAM,WAAW,UAAU;IACzB,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAqED,qBAAa,mBAAoB,SAAQ,KAAK;IAE1C,QAAQ,CAAC,MAAM,EAAE,YAAY;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE;gBADtB,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,MAAM,EAAE;CAKlC;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,YAAY,EACrB,YAAY,EAAE,MAAM,EAAE,GACrB,MAAM,CAeR;
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../../src/core/course/catalog.ts"],"names":[],"mappings":"AAIA,OAAO,EAAyB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAGvE,MAAM,WAAW,UAAU;IACzB,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAqED,qBAAa,mBAAoB,SAAQ,KAAK;IAE1C,QAAQ,CAAC,MAAM,EAAE,YAAY;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE;gBADtB,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,MAAM,EAAE;CAKlC;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,YAAY,EACrB,YAAY,EAAE,MAAM,EAAE,GACrB,MAAM,CAeR;AAMD,6EAA6E;AAC7E,wBAAsB,iBAAiB,CACrC,WAAW,CAAC,EAAE,MAAM,EACpB,MAAM,GAAE,YAAoC,GAC3C,OAAO,CAAC,MAAM,CAAC,CAmBjB;AAED,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,YAAoC,GAC3C,OAAO,CAAC,UAAU,EAAE,CAAC,CAqBvB;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAGpF;AAED,wBAAgB,SAAS,CACvB,KAAK,EAAE,UAAU,EAAE,EACnB,IAAI,EAAE,MAAM,GACX;IAAE,IAAI,CAAC,EAAE,UAAU,CAAC;IAAC,IAAI,CAAC,EAAE,UAAU,CAAC;IAAC,OAAO,CAAC,EAAE,UAAU,CAAA;CAAE,CAYhE"}
|
|
@@ -80,28 +80,33 @@ export function formatCourseNotFoundMessage(_locale, checkedPaths) {
|
|
|
80
80
|
...checkedPaths.map((p) => ` - ${p}`),
|
|
81
81
|
"",
|
|
82
82
|
"Fix:",
|
|
83
|
-
" 1. Reinstall ai-spector (course ships in node_modules/ai-spector/website/docs/):",
|
|
83
|
+
" 1. Reinstall ai-spector (course ships in node_modules/ai-spector/website/docs/{locale}/):",
|
|
84
84
|
" npm install ai-spector",
|
|
85
85
|
" 2. Or add a local copy in your project:",
|
|
86
|
-
" docs/course/ (optional override)",
|
|
87
|
-
" 3. From the ai-spector repo: edit website/docs/
|
|
86
|
+
" docs/course/en/ or docs/course/vi/ (optional override)",
|
|
87
|
+
" 3. From the ai-spector repo: edit website/docs/en/ or website/docs/vi/.",
|
|
88
88
|
];
|
|
89
89
|
return lines.join("\n");
|
|
90
90
|
}
|
|
91
|
+
function localeCourseDir(base, locale) {
|
|
92
|
+
return join(base, locale);
|
|
93
|
+
}
|
|
91
94
|
/** Prefer project-local course copy when present; otherwise bundled docs. */
|
|
92
95
|
export async function resolveCourseRoot(projectRoot, locale = DEFAULT_COURSE_LOCALE) {
|
|
93
|
-
const
|
|
94
|
-
const
|
|
96
|
+
const bundledBase = courseBundleRoot();
|
|
97
|
+
const localBase = projectRoot ? join(projectRoot, "docs", "course") : undefined;
|
|
95
98
|
const checkedPaths = [];
|
|
96
|
-
if (
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
if (localBase) {
|
|
100
|
+
const localLocale = localeCourseDir(localBase, locale);
|
|
101
|
+
checkedPaths.push(localLocale);
|
|
102
|
+
if (await pathExists(localLocale)) {
|
|
103
|
+
return localLocale;
|
|
100
104
|
}
|
|
101
105
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
106
|
+
const bundledLocale = localeCourseDir(bundledBase, locale);
|
|
107
|
+
checkedPaths.push(bundledLocale);
|
|
108
|
+
if (await pathExists(bundledLocale)) {
|
|
109
|
+
return bundledLocale;
|
|
105
110
|
}
|
|
106
111
|
throw new CourseNotFoundError(locale, checkedPaths);
|
|
107
112
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../../src/core/course/catalog.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../../src/core/course/catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CoursePage } from "./catalog.js";
|
|
2
|
+
import type { CourseLocale } from "./locale.js";
|
|
3
|
+
export interface PageResolveResult {
|
|
4
|
+
page?: CoursePage;
|
|
5
|
+
fallback: boolean;
|
|
6
|
+
bodyLocale: CourseLocale;
|
|
7
|
+
}
|
|
8
|
+
export declare function resolvePageWithFallback(locale: CourseLocale, slug: string, localePages: CoursePage[], enPages: CoursePage[]): PageResolveResult;
|
|
9
|
+
//# sourceMappingURL=fallback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fallback.d.ts","sourceRoot":"","sources":["../../../src/core/course/fallback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,YAAY,CAAC;CAC1B;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,UAAU,EAAE,EACzB,OAAO,EAAE,UAAU,EAAE,GACpB,iBAAiB,CAYnB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { pageBySlug } from "./catalog.js";
|
|
2
|
+
export function resolvePageWithFallback(locale, slug, localePages, enPages) {
|
|
3
|
+
const page = pageBySlug(localePages, slug);
|
|
4
|
+
if (page) {
|
|
5
|
+
return { page, fallback: false, bodyLocale: locale };
|
|
6
|
+
}
|
|
7
|
+
if (locale === "vi") {
|
|
8
|
+
const enPage = pageBySlug(enPages, slug);
|
|
9
|
+
if (enPage) {
|
|
10
|
+
return { page: enPage, fallback: true, bodyLocale: "en" };
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return { fallback: false, bodyLocale: locale };
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=fallback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fallback.js","sourceRoot":"","sources":["../../../src/core/course/fallback.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAS1C,MAAM,UAAU,uBAAuB,CACrC,MAAoB,EACpB,IAAY,EACZ,WAAyB,EACzB,OAAqB;IAErB,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAC3C,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IACvD,CAAC;IACD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACzC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;QAC5D,CAAC;IACH,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;AACjD,CAAC"}
|
|
@@ -9,6 +9,7 @@ export interface CourseShellOptions {
|
|
|
9
9
|
prev?: CoursePage;
|
|
10
10
|
next?: CoursePage;
|
|
11
11
|
locale?: CourseLocale;
|
|
12
|
+
localeFallback?: boolean;
|
|
12
13
|
}
|
|
13
14
|
export declare function buildCoursePageHtml(opts: CourseShellOptions): string;
|
|
14
15
|
//# sourceMappingURL=html-shell.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html-shell.d.ts","sourceRoot":"","sources":["../../../src/core/course/html-shell.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAKL,KAAK,YAAY,EAClB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"html-shell.d.ts","sourceRoot":"","sources":["../../../src/core/course/html-shell.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAKL,KAAK,YAAY,EAClB,MAAM,aAAa,CAAC;AA8YrB,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAoID,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAoGpE"}
|
|
@@ -302,6 +302,23 @@ button { font: inherit; cursor: pointer; }
|
|
|
302
302
|
}
|
|
303
303
|
.chat-hint strong { color: var(--accent); }
|
|
304
304
|
.chat-hint code { font-size: .85em; }
|
|
305
|
+
|
|
306
|
+
.callout { margin: 1.25rem 0; padding: 1rem 1.1rem; border-radius: var(--radius); border: 1px solid var(--border); }
|
|
307
|
+
.callout.exercise { border-color: var(--accent-border); background: var(--accent-soft); }
|
|
308
|
+
.callout.exercise::before { content: "Try it now"; display: block; font-weight: 700; color: var(--accent); margin-bottom: .5rem; }
|
|
309
|
+
.callout.roletip { font-size: .88rem; background: var(--bg); }
|
|
310
|
+
.callout.roletip::before { content: "Role tip"; display: block; font-weight: 600; color: var(--muted); margin-bottom: .35rem; }
|
|
311
|
+
.callout.behind { font-size: .85rem; color: var(--muted); }
|
|
312
|
+
.locale-switch { font-size: .78rem; display: flex; align-items: center; gap: .25rem; }
|
|
313
|
+
.locale-switch a { color: var(--muted); text-decoration: none; }
|
|
314
|
+
.locale-switch a.locale-active { color: var(--accent); font-weight: 700; }
|
|
315
|
+
.locale-sep { color: var(--muted); }
|
|
316
|
+
.locale-fallback-banner { background: #fef3c7; color: #92400e; padding: .75rem 1rem; border-radius: var(--radius); margin-bottom: 1rem; font-size: .88rem; }
|
|
317
|
+
@media (prefers-color-scheme: dark) {
|
|
318
|
+
.locale-fallback-banner { background: #422006; color: #fde68a; }
|
|
319
|
+
}
|
|
320
|
+
.nav-group-disabled h3 { color: var(--muted); opacity: .7; }
|
|
321
|
+
.nav-disabled { display: block; padding: .32rem .45rem; font-size: .82rem; color: var(--muted); }
|
|
305
322
|
`;
|
|
306
323
|
const SCRIPTS = (copyLabel, copiedLabel) => `
|
|
307
324
|
(function () {
|
|
@@ -405,14 +422,33 @@ function lessonProgress(pages, activeSlug) {
|
|
|
405
422
|
return { index, total, pct };
|
|
406
423
|
}
|
|
407
424
|
const SECTION_IDS = [
|
|
408
|
-
"01-
|
|
409
|
-
"02-
|
|
410
|
-
"03-
|
|
411
|
-
"04-
|
|
412
|
-
"05-
|
|
425
|
+
"01-welcome",
|
|
426
|
+
"02-get-started",
|
|
427
|
+
"03-chat-basics",
|
|
428
|
+
"04-changes",
|
|
429
|
+
"05-generate",
|
|
413
430
|
"06-review",
|
|
414
|
-
"07-
|
|
431
|
+
"07-everyday",
|
|
415
432
|
];
|
|
433
|
+
function localeSwitcherHtml(activeLocale, activeSlug) {
|
|
434
|
+
const locales = ["en", "vi"];
|
|
435
|
+
return locales
|
|
436
|
+
.map((loc) => {
|
|
437
|
+
const active = loc === activeLocale ? ' class="locale-active"' : "";
|
|
438
|
+
return `<a href="${coursePageUrl(loc, activeSlug)}"${active}>${loc.toUpperCase()}</a>`;
|
|
439
|
+
})
|
|
440
|
+
.join('<span class="locale-sep">|</span>');
|
|
441
|
+
}
|
|
442
|
+
function advancedStubHtml(locale) {
|
|
443
|
+
const title = locale === "vi" ? "Nâng cao (sắp ra mắt)" : "Advanced (coming soon)";
|
|
444
|
+
const hint = locale === "vi"
|
|
445
|
+
? "Đồ thị, prototype, mẫu tùy chỉnh…"
|
|
446
|
+
: "Graph, prototype, custom templates…";
|
|
447
|
+
return `<div class="nav-group nav-group-disabled"><h3>${escapeHtml(title)}</h3><ul><li><span class="nav-disabled">${escapeHtml(hint)}</span></li></ul></div>`;
|
|
448
|
+
}
|
|
449
|
+
function fallbackBannerHtml(ui) {
|
|
450
|
+
return `<div class="locale-fallback-banner" role="status">${escapeHtml(ui.localeFallback)}</div>`;
|
|
451
|
+
}
|
|
416
452
|
function navGroups(pages, locale) {
|
|
417
453
|
return SECTION_IDS
|
|
418
454
|
.map((sectionId) => {
|
|
@@ -521,6 +557,7 @@ export function buildCoursePageHtml(opts) {
|
|
|
521
557
|
<span>${escapeHtml(progressLabel)}</span>
|
|
522
558
|
<div class="progress-bar" aria-hidden="true"><div class="progress-fill" style="width:${progress.pct}%"></div></div>
|
|
523
559
|
</div>
|
|
560
|
+
<div class="locale-switch">${localeSwitcherHtml(locale, opts.activeSlug)}</div>
|
|
524
561
|
<a class="open-chat" href="#chat-hint">${escapeHtml(ui.tryInChat)}</a>
|
|
525
562
|
</header>
|
|
526
563
|
<div class="sidebar-backdrop"></div>
|
|
@@ -531,9 +568,11 @@ export function buildCoursePageHtml(opts) {
|
|
|
531
568
|
<input type="search" class="search" placeholder="${escapeHtml(ui.searchPlaceholder)}" aria-label="${escapeHtml(ui.searchAria)}" />
|
|
532
569
|
<div class="nav-group"><ul>${topNav}</ul></div>
|
|
533
570
|
${sectionNav}
|
|
571
|
+
${advancedStubHtml(locale)}
|
|
534
572
|
</aside>
|
|
535
573
|
<div class="main-wrap">
|
|
536
574
|
<div class="content-panel">
|
|
575
|
+
${opts.localeFallback ? fallbackBannerHtml(ui) : ""}
|
|
537
576
|
${breadcrumbHtml(opts.activePage, locale, ui)}
|
|
538
577
|
${metaBadges(opts.activePage, progress, ui)}
|
|
539
578
|
<div class="${withTocClass}">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html-shell.js","sourceRoot":"","sources":["../../../src/core/course/html-shell.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,QAAQ,EACR,qBAAqB,GAEtB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,GAAG
|
|
1
|
+
{"version":3,"file":"html-shell.js","sourceRoot":"","sources":["../../../src/core/course/html-shell.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,QAAQ,EACR,qBAAqB,GAEtB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgUd,CAAC;AAEF,MAAM,OAAO,GAAG,CAAC,SAAiB,EAAE,WAAmB,EAAE,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAmCpC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;;;;;4BAKrB,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;qDACF,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+B7E,CAAC;AAcF,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI;SACR,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK;SACT,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;SAC3B,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC;SAC7B,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;SACzB,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,YAAY,CAAC,IAAgB;IACpC,OAAO,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,WAAW,CAAC,KAAmB;IACtC,OAAO,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,cAAc,CACrB,KAAmB,EACnB,UAAkB;IAElB,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC;IAC7B,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,WAAW,GAAG;IAClB,YAAY;IACZ,gBAAgB;IAChB,gBAAgB;IAChB,YAAY;IACZ,aAAa;IACb,WAAW;IACX,aAAa;CACL,CAAC;AAEX,SAAS,kBAAkB,CAAC,YAA0B,EAAE,UAAkB;IACxE,MAAM,OAAO,GAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7C,OAAO,OAAO;SACX,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACX,MAAM,MAAM,GAAG,GAAG,KAAK,YAAY,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,OAAO,YAAY,aAAa,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,MAAM,IAAI,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC;IACzF,CAAC,CAAC;SACD,IAAI,CAAC,mCAAmC,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAoB;IAC5C,MAAM,KAAK,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,wBAAwB,CAAC;IACnF,MAAM,IAAI,GACR,MAAM,KAAK,IAAI;QACb,CAAC,CAAC,mCAAmC;QACrC,CAAC,CAAC,qCAAqC,CAAC;IAC5C,OAAO,iDAAiD,UAAU,CAAC,KAAK,CAAC,2CAA2C,UAAU,CAAC,IAAI,CAAC,yBAAyB,CAAC;AAChK,CAAC;AAED,SAAS,kBAAkB,CAAC,EAA+B;IACzD,OAAO,qDAAqD,UAAU,CAAC,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC;AACpG,CAAC;AAED,SAAS,SAAS,CAChB,KAAmB,EACnB,MAAoB;IAEpB,OAAO,WAAW;SACf,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;QACjB,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;QAC9D,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAC1B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CACtE,CAAC;QACF,OAAO;YACL,KAAK,EAAE,qBAAqB,CAAC,SAAS,EAAE,MAAM,CAAC;YAC/C,SAAS;YACT,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO;SAC7D,CAAC;IACJ,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,cAAc,CAAC,IAA4B,EAAE,MAAoB,EAAE,EAA+B;IACzG,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACnC,OAAO,kCAAkC,IAAI,KAAK,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC;IACpF,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,YAAY,IAAI,KAAK,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjE,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CACR,YAAY,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,UAAU,CAAC,qBAAqB,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,MAAM,CACtH,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC;IACjE,OAAO,yBAAyB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;AAC1D,CAAC;AAED,SAAS,UAAU,CACjB,IAA4B,EAC5B,QAAsD,EACtD,EAA+B;IAE/B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,IAAI,EAAE,YAAY,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,uBAAuB,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,QAAQ,IAAI,QAAQ,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,uBAAuB,UAAU,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC;IAC1G,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,4BAA4B,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC;AAC7D,CAAC;AAED,SAAS,YAAY,CAAC,IAA4B,EAAE,MAAoB,EAAE,EAA+B;IACvG,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IACzD,OAAO,kCAAkC,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,aAAa,IAAI,QAAQ,CAAC;AAC5F,CAAC;AAED,SAAS,cAAc,CAAC,QAAgB;IACtC,OAAO,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAwB;IAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC;IACnC,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5B,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC7D,MAAM,QAAQ,GAAG;QACf,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC;KAC3C,CAAC,MAAM,CAAC,OAAO,CAAiB,CAAC;IAElC,MAAM,MAAM,GAAG,QAAQ;SACpB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,OAAO,iBAAiB,MAAM,CAAC,IAAI,EAAE,WAAW,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC;IAC/H,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;IAEZ,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC;SAC7C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK;aACtB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACT,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,MAAM,SAAS,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YACnD,MAAM,GAAG,GAAG;gBACV,MAAM,CAAC,IAAI,EAAE;gBACb,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa;aAC3C,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC5B,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAClC,OAAO,iBAAiB,GAAG,WAAW,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC;QACvG,CAAC,CAAC;aACD,IAAI,CAAC,EAAE,CAAC,CAAC;QACZ,OAAO,8BAA8B,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,KAAK,aAAa,CAAC;IAC7F,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;IAEZ,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI;QACxB,CAAC,CAAC,yBAAyB,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,yBAAyB,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,gCAAgC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,aAAa;QACpM,CAAC,CAAC,mCAAmC,CAAC;IACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI;QACxB,CAAC,CAAC,yBAAyB,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,yBAAyB,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC,8BAA8B,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,eAAe;QAChM,CAAC,CAAC,mCAAmC,CAAC;IAExC,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,GAAG,CAAC;QACtC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC;QAC7C,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC;IAEd,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,OAAO;QACtB,CAAC,CAAC,gCAAgC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC;kBAC7C,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC;;iBAE1B;QACb,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,UAAU,CAAC;IAE/D,OAAO;cACK,MAAM;;;;WAIT,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,UAAU,CAAC,EAAE,CAAC,WAAW,CAAC;WACtD,MAAM;;;;yDAIwC,UAAU,CAAC,EAAE,CAAC,OAAO,CAAC;8BACjD,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;wCACxB,UAAU,CAAC,EAAE,CAAC,aAAa,CAAC;cACtD,UAAU,CAAC,aAAa,CAAC;6FACsD,QAAQ,CAAC,GAAG;;iCAExE,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC;6CAC/B,UAAU,CAAC,EAAE,CAAC,SAAS,CAAC;;;;;;6BAMxC,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC;yDACK,UAAU,CAAC,EAAE,CAAC,iBAAiB,CAAC,iBAAiB,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC;mCAChG,MAAM;QACjC,UAAU;QACV,gBAAgB,CAAC,MAAM,CAAC;;;;UAItB,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;UACjD,cAAc,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC;UAC3C,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,CAAC;sBAC7B,YAAY;qCACG,IAAI,CAAC,QAAQ;YACtC,QAAQ;;6BAES,QAAQ,GAAG,QAAQ;8BAClB,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC;;;;;YAK3D,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC;;QAE/B,CAAC;AACT,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type CourseLocale = "en";
|
|
1
|
+
export type CourseLocale = "en" | "vi";
|
|
2
2
|
export declare const DEFAULT_COURSE_LOCALE: CourseLocale;
|
|
3
3
|
export declare const SUPPORTED_COURSE_LOCALES: readonly CourseLocale[];
|
|
4
4
|
export interface CourseUiStrings {
|
|
@@ -19,16 +19,18 @@ export interface CourseUiStrings {
|
|
|
19
19
|
copy: string;
|
|
20
20
|
copied: string;
|
|
21
21
|
inEditor: string;
|
|
22
|
+
localeFallback: string;
|
|
22
23
|
}
|
|
23
24
|
export declare const SECTION_LABELS: Record<string, string>;
|
|
24
|
-
export declare
|
|
25
|
-
export declare function
|
|
26
|
-
export declare function
|
|
27
|
-
export declare function
|
|
28
|
-
export declare function
|
|
25
|
+
export declare const SECTION_LABELS_VI: Record<string, string>;
|
|
26
|
+
export declare function courseUi(locale?: CourseLocale): CourseUiStrings;
|
|
27
|
+
export declare function sectionLabelForLocale(sectionId: string, locale?: CourseLocale): string;
|
|
28
|
+
export declare function chatHintForSection(sectionId: string | undefined, locale?: CourseLocale): string;
|
|
29
|
+
export declare function coursePathPrefix(locale?: CourseLocale): string;
|
|
30
|
+
export declare function coursePageUrl(locale: CourseLocale, slug: string): string;
|
|
29
31
|
export declare function parseCourseRequest(pathname: string): {
|
|
30
32
|
locale: CourseLocale;
|
|
31
33
|
slug: string;
|
|
32
34
|
};
|
|
33
|
-
export declare function normalizeCourseLocale(
|
|
35
|
+
export declare function normalizeCourseLocale(value?: string): CourseLocale;
|
|
34
36
|
//# sourceMappingURL=locale.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../../src/core/course/locale.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../../src/core/course/locale.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,CAAC;AAEvC,eAAO,MAAM,qBAAqB,EAAE,YAAmB,CAAC;AAExD,eAAO,MAAM,wBAAwB,EAAE,SAAS,YAAY,EAA0B,CAAC;AAEvF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACnD,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AA4CD,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQjD,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQpD,CAAC;AA2BF,wBAAgB,QAAQ,CAAC,MAAM,GAAE,YAAoC,GAAG,eAAe,CAEtF;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,YAAoC,GAC3C,MAAM,CAGR;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,MAAM,GAAE,YAAoC,GAC3C,MAAM,CAMR;AAED,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,YAAoC,GAAG,MAAM,CAErF;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAGxE;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAW3F;AAED,wBAAgB,qBAAqB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,YAAY,CAElE"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export const DEFAULT_COURSE_LOCALE = "en";
|
|
2
|
-
export const SUPPORTED_COURSE_LOCALES = ["en"];
|
|
3
|
-
const
|
|
2
|
+
export const SUPPORTED_COURSE_LOCALES = ["en", "vi"];
|
|
3
|
+
const UI_EN = {
|
|
4
4
|
course: "Course",
|
|
5
5
|
courseTitle: "AI Spector Course",
|
|
6
|
-
brandSub: "
|
|
6
|
+
brandSub: "9 lessons · ~10 min each",
|
|
7
7
|
searchPlaceholder: "Search lessons…",
|
|
8
8
|
searchAria: "Search lessons",
|
|
9
9
|
onThisPage: "On this page",
|
|
@@ -18,43 +18,85 @@ const UI = {
|
|
|
18
18
|
copy: "Copy",
|
|
19
19
|
copied: "Copied",
|
|
20
20
|
inEditor: "In Cursor / Claude Code:",
|
|
21
|
+
localeFallback: "Vietnamese translation not available yet — showing English.",
|
|
22
|
+
};
|
|
23
|
+
const UI_VI = {
|
|
24
|
+
course: "Khóa học",
|
|
25
|
+
courseTitle: "Khóa học AI Spector",
|
|
26
|
+
brandSub: "9 bài · ~10 phút mỗi bài",
|
|
27
|
+
searchPlaceholder: "Tìm bài học…",
|
|
28
|
+
searchAria: "Tìm bài học",
|
|
29
|
+
onThisPage: "Trong trang này",
|
|
30
|
+
previous: "Trước",
|
|
31
|
+
next: "Tiếp",
|
|
32
|
+
lessonOf: (i, t) => `Bài ${i}/${t}`,
|
|
33
|
+
lessonBadge: (i, t) => `Bài ${i} / ${t}`,
|
|
34
|
+
browse: "Duyệt",
|
|
35
|
+
progressTitle: "Tiến độ khóa học",
|
|
36
|
+
tryInChat: "Thử trong chat ↓",
|
|
37
|
+
openNav: "Mở menu",
|
|
38
|
+
copy: "Sao chép",
|
|
39
|
+
copied: "Đã sao chép",
|
|
40
|
+
inEditor: "Trong Cursor / Claude Code:",
|
|
41
|
+
localeFallback: "Bản dịch tiếng Việt chưa có — hiển thị tiếng Anh.",
|
|
21
42
|
};
|
|
22
43
|
export const SECTION_LABELS = {
|
|
23
|
-
"01-
|
|
24
|
-
"02-
|
|
25
|
-
"03-
|
|
26
|
-
"04-
|
|
27
|
-
"05-
|
|
28
|
-
"06-review": "Review
|
|
29
|
-
"07-
|
|
44
|
+
"01-welcome": "Welcome",
|
|
45
|
+
"02-get-started": "Get started",
|
|
46
|
+
"03-chat-basics": "Chat basics",
|
|
47
|
+
"04-changes": "Changes",
|
|
48
|
+
"05-generate": "Generate",
|
|
49
|
+
"06-review": "Review",
|
|
50
|
+
"07-everyday": "Everyday",
|
|
51
|
+
};
|
|
52
|
+
export const SECTION_LABELS_VI = {
|
|
53
|
+
"01-welcome": "Giới thiệu",
|
|
54
|
+
"02-get-started": "Bắt đầu",
|
|
55
|
+
"03-chat-basics": "Chat cơ bản",
|
|
56
|
+
"04-changes": "Thay đổi",
|
|
57
|
+
"05-generate": "Tạo tài liệu",
|
|
58
|
+
"06-review": "Rà soát",
|
|
59
|
+
"07-everyday": "Hàng ngày",
|
|
30
60
|
};
|
|
31
61
|
const CHAT_HINTS = {
|
|
32
|
-
"01-
|
|
33
|
-
"02-
|
|
34
|
-
"03-
|
|
35
|
-
"04-
|
|
36
|
-
"05-
|
|
62
|
+
"01-welcome": "Try in chat: <code>open the course</code>",
|
|
63
|
+
"02-get-started": "Try in chat: <code>setup ai-spector project</code>",
|
|
64
|
+
"03-chat-basics": "Try in chat: <code>help me approve</code>",
|
|
65
|
+
"04-changes": "Try in chat: <code>I want to add login with Google</code>",
|
|
66
|
+
"05-generate": "Try in chat: <code>generate the SRS</code>",
|
|
37
67
|
"06-review": "Try in chat: <code>review documents</code> or <code>resolve comments</code>",
|
|
38
|
-
"07-
|
|
68
|
+
"07-everyday": "Try in chat: <code>active tasks</code> or <code>check my workspace</code>",
|
|
39
69
|
default: "Ask in chat: <code>open the ai-spector course</code> or <code>help me learn ai-spector</code>",
|
|
40
70
|
};
|
|
41
|
-
|
|
42
|
-
|
|
71
|
+
const CHAT_HINTS_VI = {
|
|
72
|
+
"01-welcome": "Thử trong chat: <code>open the course</code>",
|
|
73
|
+
"02-get-started": "Thử trong chat: <code>setup ai-spector project</code>",
|
|
74
|
+
"03-chat-basics": "Thử trong chat: <code>help me approve</code>",
|
|
75
|
+
"04-changes": "Thử trong chat: <code>I want to add login with Google</code>",
|
|
76
|
+
"05-generate": "Thử trong chat: <code>generate the SRS</code>",
|
|
77
|
+
"06-review": "Thử trong chat: <code>review documents</code> hoặc <code>resolve comments</code>",
|
|
78
|
+
"07-everyday": "Thử trong chat: <code>active tasks</code> hoặc <code>check my workspace</code>",
|
|
79
|
+
default: "Hỏi trong chat: <code>open the ai-spector course</code> hoặc <code>help me learn ai-spector</code>",
|
|
80
|
+
};
|
|
81
|
+
export function courseUi(locale = DEFAULT_COURSE_LOCALE) {
|
|
82
|
+
return locale === "vi" ? UI_VI : UI_EN;
|
|
43
83
|
}
|
|
44
|
-
export function sectionLabelForLocale(sectionId,
|
|
45
|
-
|
|
84
|
+
export function sectionLabelForLocale(sectionId, locale = DEFAULT_COURSE_LOCALE) {
|
|
85
|
+
const labels = locale === "vi" ? SECTION_LABELS_VI : SECTION_LABELS;
|
|
86
|
+
return labels[sectionId] ?? sectionId;
|
|
46
87
|
}
|
|
47
|
-
export function chatHintForSection(sectionId,
|
|
48
|
-
|
|
49
|
-
|
|
88
|
+
export function chatHintForSection(sectionId, locale = DEFAULT_COURSE_LOCALE) {
|
|
89
|
+
const hints = locale === "vi" ? CHAT_HINTS_VI : CHAT_HINTS;
|
|
90
|
+
if (sectionId && hints[sectionId]) {
|
|
91
|
+
return hints[sectionId];
|
|
50
92
|
}
|
|
51
|
-
return
|
|
93
|
+
return hints.default;
|
|
52
94
|
}
|
|
53
|
-
export function coursePathPrefix(
|
|
54
|
-
return
|
|
95
|
+
export function coursePathPrefix(locale = DEFAULT_COURSE_LOCALE) {
|
|
96
|
+
return `/course/${locale}`;
|
|
55
97
|
}
|
|
56
|
-
export function coursePageUrl(
|
|
57
|
-
const base = coursePathPrefix();
|
|
98
|
+
export function coursePageUrl(locale, slug) {
|
|
99
|
+
const base = coursePathPrefix(locale);
|
|
58
100
|
return `${base}/${slug === "index" ? "index" : slug}`;
|
|
59
101
|
}
|
|
60
102
|
export function parseCourseRequest(pathname) {
|
|
@@ -62,9 +104,14 @@ export function parseCourseRequest(pathname) {
|
|
|
62
104
|
if (!trimmed || trimmed === "index") {
|
|
63
105
|
return { locale: "en", slug: "index" };
|
|
64
106
|
}
|
|
107
|
+
const [first, ...rest] = trimmed.split("/");
|
|
108
|
+
if (first === "en" || first === "vi") {
|
|
109
|
+
const slugRest = rest.join("/");
|
|
110
|
+
return { locale: first, slug: slugRest || "index" };
|
|
111
|
+
}
|
|
65
112
|
return { locale: "en", slug: trimmed };
|
|
66
113
|
}
|
|
67
|
-
export function normalizeCourseLocale(
|
|
68
|
-
return "en";
|
|
114
|
+
export function normalizeCourseLocale(value) {
|
|
115
|
+
return value === "vi" ? "vi" : "en";
|
|
69
116
|
}
|
|
70
117
|
//# sourceMappingURL=locale.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locale.js","sourceRoot":"","sources":["../../../src/core/course/locale.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,qBAAqB,GAAiB,IAAI,CAAC;AAExD,MAAM,CAAC,MAAM,wBAAwB,GAA4B,CAAC,IAAI,CAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"locale.js","sourceRoot":"","sources":["../../../src/core/course/locale.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redirects.d.ts","sourceRoot":"","sources":["../../../src/core/course/redirects.ts"],"names":[],"mappings":"AAeA,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAWrE;AAED,wBAAgB,kBAAkB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAKnE"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const LEGACY_REDIRECTS = {
|
|
2
|
+
index: "/course/en/index",
|
|
3
|
+
"01-get-started": "/course/en/02-get-started",
|
|
4
|
+
"01-get-started/01-prerequisites-and-init": "/course/en/02-get-started/01-setup-via-chat",
|
|
5
|
+
"01-get-started/02-setup-and-skills": "/course/en/02-get-started/01-setup-via-chat",
|
|
6
|
+
"02-chat-basics": "/course/en/03-chat-basics",
|
|
7
|
+
"02-chat-basics/01-how-chat-works": "/course/en/03-chat-basics/01-how-chat-works",
|
|
8
|
+
"02-chat-basics/02-workspace-and-tasks": "/course/en/07-everyday/01-tasks-and-workspace",
|
|
9
|
+
"02-chat-basics/03-incremental-changes": "/course/en/04-changes/01-add-or-change-requirement",
|
|
10
|
+
"04-generate/01-generate-srs": "/course/en/05-generate/01-generate-srs",
|
|
11
|
+
"04-generate/02-basic-design": "/course/en/index?migrated=1",
|
|
12
|
+
"06-review/01-document-review": "/course/en/06-review/01-document-review",
|
|
13
|
+
"06-review/02-comment-threads": "/course/en/06-review/02-resolve-comments",
|
|
14
|
+
};
|
|
15
|
+
export function legacyCourseRedirect(slug) {
|
|
16
|
+
if (slug.startsWith("en/") || slug.startsWith("vi/")) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
if (slug in LEGACY_REDIRECTS) {
|
|
20
|
+
return LEGACY_REDIRECTS[slug];
|
|
21
|
+
}
|
|
22
|
+
if (slug && slug !== "index") {
|
|
23
|
+
return "/course/en/index?migrated=1";
|
|
24
|
+
}
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
export function isLegacyCoursePath(pathAfterCourse) {
|
|
28
|
+
if (!pathAfterCourse || pathAfterCourse === "index") {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
return !pathAfterCourse.startsWith("en/") && !pathAfterCourse.startsWith("vi/");
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=redirects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redirects.js","sourceRoot":"","sources":["../../../src/core/course/redirects.ts"],"names":[],"mappings":"AAAA,MAAM,gBAAgB,GAA2B;IAC/C,KAAK,EAAE,kBAAkB;IACzB,gBAAgB,EAAE,2BAA2B;IAC7C,0CAA0C,EAAE,6CAA6C;IACzF,oCAAoC,EAAE,6CAA6C;IACnF,gBAAgB,EAAE,2BAA2B;IAC7C,kCAAkC,EAAE,6CAA6C;IACjF,uCAAuC,EAAE,+CAA+C;IACxF,uCAAuC,EAAE,oDAAoD;IAC7F,6BAA6B,EAAE,wCAAwC;IACvE,6BAA6B,EAAE,6BAA6B;IAC5D,8BAA8B,EAAE,yCAAyC;IACzE,8BAA8B,EAAE,0CAA0C;CAC3E,CAAC;AAEF,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACrD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,IAAI,IAAI,gBAAgB,EAAE,CAAC;QAC7B,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IACD,IAAI,IAAI,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QAC7B,OAAO,6BAA6B,CAAC;IACvC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,eAAuB;IACxD,IAAI,CAAC,eAAe,IAAI,eAAe,KAAK,OAAO,EAAE,CAAC;QACpD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AAClF,CAAC"}
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import type { CoursePage } from "./catalog.js";
|
|
2
2
|
import { type CourseLocale } from "./locale.js";
|
|
3
|
+
/** Turn :::exercise / :::roletip / :::behind fences into placeholders for HTML injection after render. */
|
|
4
|
+
export declare function preprocessCallouts(markdown: string, locale?: CourseLocale): {
|
|
5
|
+
markdown: string;
|
|
6
|
+
callouts: string[];
|
|
7
|
+
};
|
|
3
8
|
/** Turn GFM ```mermaid fences into elements mermaid.js can render. */
|
|
4
9
|
export declare function transformMermaidBlocks(html: string): string;
|
|
10
|
+
/** Turn :::exercise / :::roletip / :::behind fences into styled callouts. */
|
|
11
|
+
export declare function preprocessCalloutsOnly(markdown: string, locale?: CourseLocale): string;
|
|
5
12
|
export declare function renderCourseMarkdown(markdown: string, currentRelPath?: string, locale?: CourseLocale): Promise<string>;
|
|
6
13
|
export declare function loadPageHtml(courseRoot: string, page: CoursePage, locale?: CourseLocale): Promise<string>;
|
|
7
14
|
//# sourceMappingURL=render.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/core/course/render.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAwC,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/core/course/render.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAwC,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAkBtF,0GAA0G;AAC1G,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,YAAoC,GAC3C;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAW1C;AA8DD,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQ3D;AAED,6EAA6E;AAC7E,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,YAAoC,GAC3C,MAAM,CAER;AAED,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,cAAc,SAAc,EAC5B,MAAM,GAAE,YAAoC,GAC3C,OAAO,CAAC,MAAM,CAAC,CAMjB;AAED,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,UAAU,EAChB,MAAM,GAAE,YAAoC,GAC3C,OAAO,CAAC,MAAM,CAAC,CAGjB"}
|
|
@@ -11,6 +11,33 @@ const mdProcessor = unified()
|
|
|
11
11
|
.use(remarkGfm)
|
|
12
12
|
.use(remarkRehype)
|
|
13
13
|
.use(rehypeStringify);
|
|
14
|
+
const CALLOUT_PLACEHOLDER = "AISPECTOR_CALLOUT_";
|
|
15
|
+
function calloutHtml(kind, body, locale) {
|
|
16
|
+
const behindLabel = locale === "vi" ? "Chi tiết kỹ thuật" : "Behind the scenes";
|
|
17
|
+
if (kind === "behind") {
|
|
18
|
+
return `<details class="callout behind"><summary>${behindLabel}</summary>${body.trim()}</details>`;
|
|
19
|
+
}
|
|
20
|
+
return `<div class="callout ${kind}">${body.trim()}</div>`;
|
|
21
|
+
}
|
|
22
|
+
/** Turn :::exercise / :::roletip / :::behind fences into placeholders for HTML injection after render. */
|
|
23
|
+
export function preprocessCallouts(markdown, locale = DEFAULT_COURSE_LOCALE) {
|
|
24
|
+
const callouts = [];
|
|
25
|
+
const processed = markdown.replace(/:::(exercise|roletip|behind)\n([\s\S]*?):::/g, (_, kind, body) => {
|
|
26
|
+
const idx = callouts.length;
|
|
27
|
+
callouts.push(calloutHtml(kind, body, locale));
|
|
28
|
+
return `\n\n${CALLOUT_PLACEHOLDER}${idx}\n\n`;
|
|
29
|
+
});
|
|
30
|
+
return { markdown: processed, callouts };
|
|
31
|
+
}
|
|
32
|
+
function injectCallouts(html, callouts) {
|
|
33
|
+
let result = html;
|
|
34
|
+
for (let i = 0; i < callouts.length; i++) {
|
|
35
|
+
const para = new RegExp(`<p>${CALLOUT_PLACEHOLDER}${i}</p>`, "g");
|
|
36
|
+
result = result.replace(para, callouts[i]);
|
|
37
|
+
result = result.replaceAll(`${CALLOUT_PLACEHOLDER}${i}`, callouts[i]);
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
14
41
|
function slugFromHref(href, currentRelPath, locale) {
|
|
15
42
|
const clean = href.split("#")[0];
|
|
16
43
|
const hash = href.includes("#") ? `#${href.split("#").slice(1).join("#")}` : "";
|
|
@@ -61,10 +88,16 @@ export function transformMermaidBlocks(html) {
|
|
|
61
88
|
return `<div class="mermaid-diagram"><pre class="mermaid">${diagram}</pre></div>`;
|
|
62
89
|
});
|
|
63
90
|
}
|
|
91
|
+
/** Turn :::exercise / :::roletip / :::behind fences into styled callouts. */
|
|
92
|
+
export function preprocessCalloutsOnly(markdown, locale = DEFAULT_COURSE_LOCALE) {
|
|
93
|
+
return preprocessCallouts(markdown, locale).markdown;
|
|
94
|
+
}
|
|
64
95
|
export async function renderCourseMarkdown(markdown, currentRelPath = "README.md", locale = DEFAULT_COURSE_LOCALE) {
|
|
65
|
-
const
|
|
96
|
+
const { markdown: withPlaceholders, callouts } = preprocessCallouts(markdown, locale);
|
|
97
|
+
const prepared = rewriteMarkdownLinks(withPlaceholders, currentRelPath, locale);
|
|
66
98
|
const file = await mdProcessor.process(prepared);
|
|
67
|
-
|
|
99
|
+
const html = transformMermaidBlocks(String(file));
|
|
100
|
+
return injectCallouts(html, callouts);
|
|
68
101
|
}
|
|
69
102
|
export async function loadPageHtml(courseRoot, page, locale = DEFAULT_COURSE_LOCALE) {
|
|
70
103
|
const markdown = await readFile(join(courseRoot, page.relPath), "utf8");
|