/** * The two editions of one personal report (TASK-report-english-edition-20260929). * Both are rendered by the engine from the same packet; English is a subordinate * edition — when it is missing or fails its checks the report is still ready in * Chinese. */ export type ReportLanguage = "zh" | "en"; export const REPORT_LANGUAGES: readonly ReportLanguage[] = ["zh", "en"]; /** Any CJK ideograph. The English edition must contain none (red line 2). */ const HAN = /[㐀-鿿豈-﫿]/; export function containsHan(text: string): boolean { return HAN.test(text); } export function readReportLanguage(value: unknown): ReportLanguage { return value === "en" ? "en" : "zh"; } /** * Numbers in reading order: degrees, dates, scores, house numbers. Two editions * rendered from one packet must produce the same sequence (red line 3). */ export function numericTokens(text: string): string[] { return text.match(/-?\d+(?:\.\d+)?/g) ?? []; } /** `legacy`: generated before the English edition existed; `unavailable`: attempted and dropped. */ export type EnglishEditionStatus = "ready" | "unavailable" | "legacy";