@thanh01.pmt/curriculum-kit 1.4.17 → 1.4.18

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/index.cjs CHANGED
@@ -10690,6 +10690,8 @@ ${lines.join("\n")}
10690
10690
 
10691
10691
  // src/services/contextBuilder.ts
10692
10692
  var DEFAULT_LESSON_PRIORITIES = [
10693
+ "Symbol & Identifier Ledger",
10694
+ "Artifact Contract",
10693
10695
  "A. Lesson Design Plan",
10694
10696
  "B. Lesson Flow",
10695
10697
  "Learning Objectives & Evidence",
@@ -10908,6 +10910,12 @@ function normalizeHeading(str) {
10908
10910
  return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
10909
10911
  }
10910
10912
  function findCanonicalFuzzy(norm) {
10913
+ if (norm.includes("symbol") || norm.includes("identifier ledger") || norm.includes("dinh danh")) {
10914
+ return "Symbol & Identifier Ledger";
10915
+ }
10916
+ if (norm.includes("artifact contract") || norm.includes("hop dong hoc lieu")) {
10917
+ return "Artifact Contract";
10918
+ }
10911
10919
  if (norm.includes("lesson design plan") || norm.includes("ke hoach thiet ke")) {
10912
10920
  return "A. Lesson Design Plan";
10913
10921
  }
@@ -10958,6 +10966,39 @@ function deriveArtifactTypeFromFileName(fileName) {
10958
10966
  const token = base.match(/^([A-Z][A-Z0-9_]*?)(?=_|$)/);
10959
10967
  return token ? token[1] : void 0;
10960
10968
  }
10969
+ function extractSymbolLedger(lessonMarkdown) {
10970
+ const result = {
10971
+ keySymbols: [],
10972
+ rawBlock: ""
10973
+ };
10974
+ if (!lessonMarkdown) return result;
10975
+ const ledgerMatch = lessonMarkdown.match(/###?\s*(?:Symbol & Identifier Ledger|Bảng Định Danh|Artifact Contract)[\s\S]*?(?=\n##|\n---|$)/i);
10976
+ if (ledgerMatch) {
10977
+ result.rawBlock = ledgerMatch[0].trim();
10978
+ }
10979
+ const structMatch = lessonMarkdown.match(/(?:Primary Struct|Primary Class|Primary Function|Main Component|Primary Module|Struct chính|Class chính|Hàm chính)[:\s*`]+([A-Za-z0-9_]+)/i);
10980
+ if (structMatch) {
10981
+ result.primarySymbol = structMatch[1];
10982
+ result.keySymbols.push(structMatch[1]);
10983
+ } else {
10984
+ const codeStructMatch = lessonMarkdown.match(/(?:struct|class|interface|type|def|function)\s+([A-Za-z0-9_]+)/);
10985
+ if (codeStructMatch) {
10986
+ const sym = codeStructMatch[1];
10987
+ result.primarySymbol = sym;
10988
+ result.keySymbols.push(sym);
10989
+ }
10990
+ }
10991
+ const fileMatch = lessonMarkdown.match(/(?:Entry File|Source File|Target File|Tên file mã nguồn)[:\s*`]+([A-Za-z0-9_\-\.]+\.[a-z0-9_]+)/i);
10992
+ if (fileMatch) {
10993
+ result.entryFileName = fileMatch[1];
10994
+ } else {
10995
+ const codeFileComment = lessonMarkdown.match(/(?:\/\/\s*|#\s*|\/\*\s*)([A-Za-z0-9_\-]+\.[a-zA-Z0-9]+)/);
10996
+ if (codeFileComment) {
10997
+ result.entryFileName = codeFileComment[1];
10998
+ }
10999
+ }
11000
+ return result;
11001
+ }
10961
11002
 
10962
11003
  // src/services/knowledgeExpositionService.ts
10963
11004
  var EXPOSITION_REL = (lessonCode) => "_sot/expositions/" + lessonCode + ".md";
@@ -10977,8 +11018,22 @@ var DEPTH_RULES = {
10977
11018
  cio: "Write WHAT + WHY + HOW: include the mechanism, step by step, still technology-independent.",
10978
11019
  sio: "Write WHAT + WHY + HOW + SPECIFIC: include concrete implementations and how the real project keywords are used."
10979
11020
  };
10980
- function buildSystemPrompt(targetLanguage = "vi") {
11021
+ function buildDomainLexiconGuardrail(techStack, hardwarePlatform) {
11022
+ const targetTech = (techStack || "").trim();
11023
+ const targetHw = (hardwarePlatform || "").trim();
11024
+ const platformAnchor = [targetTech, targetHw].filter(Boolean).join(" | ");
11025
+ if (!platformAnchor) {
11026
+ return `- \u{1F512} TECHNICAL DOMAIN ANCHOR: Strictly adhere to the declared curriculum domain. Use ONLY native, standard, idiomatic syntax and mechanisms. Strictly FORBIDDEN from using foreign paradigms, cross-domain jargon, or hallucinated APIs.`;
11027
+ }
11028
+ return `- \u{1F512} STRICT DOMAIN & TECHNICAL PLATFORM ANCHOR:
11029
+ \u2022 Declared Platform: "${platformAnchor}"
11030
+ \u2022 NATIVE PARADIGM ONLY: You MUST strictly use standard, idiomatic syntax, conventions, naming patterns, and mental models of "${platformAnchor}".
11031
+ \u2022 ANTI-CONTAMINATION INVARIANT: Strictly FORBIDDEN from importing or using syntax, units, keywords, tags, or concepts from unrelated/foreign ecosystems (e.g., do NOT leak Web/HTML/CSS tags or units into native mobile/embedded stacks, do NOT leak dynamic scripting into statically typed systems, do NOT use hardware/circuit terminology in pure-software courses).
11032
+ \u2022 REAL APIS ONLY: Every method, modifier, property, and API referenced must exist in the standard SDK of "${platformAnchor}".`;
11033
+ }
11034
+ function buildSystemPrompt(targetLanguage = "vi", techStack, hardwarePlatform) {
10981
11035
  const langDirective = buildLanguageDirective(targetLanguage);
11036
+ const domainGuardrails = buildDomainLexiconGuardrail(techStack, hardwarePlatform);
10982
11037
  return [
10983
11038
  "You write KNOWLEDGE_EXPOSITION: self-study reading material for a student in a teacherless program.",
10984
11039
  "Rules:",
@@ -10987,6 +11042,7 @@ function buildSystemPrompt(targetLanguage = "vi") {
10987
11042
  "3. Respect each concept depth target (ULO/CIO/SIO) \u2014 do not overshoot.",
10988
11043
  "4. Student-facing only: no teacher instructions, no classroom management text.",
10989
11044
  "5. Output the full markdown document following the provided section skeleton exactly (headers and placeholders preserved).",
11045
+ domainGuardrails,
10990
11046
  langDirective
10991
11047
  ].join("\n");
10992
11048
  }
@@ -11023,7 +11079,7 @@ function buildUserPrompt(session, plan, glossary, targetLanguage = "vi", slcMark
11023
11079
  ].filter(Boolean).join("\n");
11024
11080
  }
11025
11081
  async function ensureKnowledgeExposition(options) {
11026
- const { projectId, lessonCode, plan, glossary, llmFn, storage } = options;
11082
+ const { projectId, lessonCode, plan, glossary, llmFn, storage, techStack, hardwarePlatform } = options;
11027
11083
  const session = plan.sessions.find((s) => s.id === lessonCode);
11028
11084
  if (!session) throw new Error("Session " + lessonCode + " not found in plan " + plan.plan_id);
11029
11085
  const existing = await storage.readArtifact(projectId, EXPOSITION_REL(lessonCode));
@@ -11038,7 +11094,7 @@ async function ensureKnowledgeExposition(options) {
11038
11094
  }
11039
11095
  const targetLanguage = options.targetLanguage || plan.translation?.target_language || "vi";
11040
11096
  const content = (await llmFn(
11041
- buildSystemPrompt(targetLanguage),
11097
+ buildSystemPrompt(targetLanguage, techStack, hardwarePlatform),
11042
11098
  buildUserPrompt(session, plan, glossary, targetLanguage, options.slcMarkdown)
11043
11099
  )).trim();
11044
11100
  if (content.length < 200) {
@@ -11108,6 +11164,18 @@ async function ensureExpositionForLesson(storage, projectId, lessonCode, options
11108
11164
  }
11109
11165
  const scopedTerms = new Set(plan.glossary_scope.find((g) => g.session_id === lessonCode)?.terms ?? []);
11110
11166
  glossary = glossary.filter((g) => scopedTerms.has(g.term));
11167
+ let hw = options.hardwarePlatform;
11168
+ let tech = options.techStack;
11169
+ if (!hw || !tech) {
11170
+ try {
11171
+ const lpRaw = await storage.readSotDocument(projectId, "LEARNER_PROFILE.md");
11172
+ if (lpRaw) {
11173
+ const hwMatch = lpRaw.match(/(?:Student Equipment|Hardware|Platform|Thiết bị)[:\s*`]+([^\n\r]+)/i);
11174
+ if (hwMatch && !hw) hw = hwMatch[1].trim();
11175
+ }
11176
+ } catch {
11177
+ }
11178
+ }
11111
11179
  const { runCurriculumAIInference: runCurriculumAIInference2 } = await Promise.resolve().then(() => (init_streamRunner(), streamRunner_exports));
11112
11180
  const targetLang = options.targetLanguage || plan.translation?.target_language || "vi";
11113
11181
  const result = await ensureKnowledgeExposition({
@@ -11117,6 +11185,8 @@ async function ensureExpositionForLesson(storage, projectId, lessonCode, options
11117
11185
  glossary,
11118
11186
  targetLanguage: targetLang,
11119
11187
  slcMarkdown: options.slcMarkdown,
11188
+ techStack: tech,
11189
+ hardwarePlatform: hw,
11120
11190
  llmFn: async (systemPrompt, userPrompt) => {
11121
11191
  const runnerOpts = options.customInference ? { customInference: options.customInference } : {};
11122
11192
  const out = await runCurriculumAIInference2(
@@ -25143,7 +25213,11 @@ type: "LESSON_EDP"
25143
25213
 
25144
25214
  ### 3. Resource Map (Slide, Handout, Starter Code, Lab Tools)
25145
25215
  ### 4. Assessment Map (Rubric criteria, formative checkpoints, remediation paths)
25146
- ### 5. Artifact Contract (Detailed specifications for ACT, SLIDE, QUIZ)
25216
+ ### 5. Artifact Contract & Code Symbol Ledger
25217
+ - **Primary Struct / Class / Component:** [Explicit canonical identifier e.g. ProfileCardView]
25218
+ - **Entry Source File:** [Explicit file name e.g. ProfileCardView.swift]
25219
+ - **Key Functions & State Variables:** [Canonical identifiers used across all student activities]
25220
+ - **Artifact Specifications:** [Deliverable requirements for ACT, SLIDE, QUIZ, GUIDE, WKS, CODE, EXT]
25147
25221
 
25148
25222
  ---
25149
25223
 
@@ -25193,7 +25267,11 @@ type: "LESSON_GENERAL"
25193
25267
 
25194
25268
  ### 3. Resource Map
25195
25269
  ### 4. Assessment Map
25196
- ### 5. Artifact Contract
25270
+ ### 5. Artifact Contract & Code Symbol Ledger
25271
+ - **Primary Struct / Class / Component:** [Explicit canonical identifier e.g. MainComponent]
25272
+ - **Entry Source File:** [Explicit file name e.g. MainComponent.ext]
25273
+ - **Key Functions & State Variables:** [Canonical identifiers used across all student activities]
25274
+ - **Artifact Specifications:** [Deliverable requirements for ACT, SLIDE, QUIZ, GUIDE, WKS, CODE, EXT]
25197
25275
 
25198
25276
  ---
25199
25277
 
@@ -25241,7 +25319,11 @@ type: "LESSON_5E"
25241
25319
 
25242
25320
  ### 3. Resource Map
25243
25321
  ### 4. Assessment Map
25244
- ### 5. Artifact Contract (Detailed specifications for ACT, SLIDE, QUIZ, GUIDE)
25322
+ ### 5. Artifact Contract & Code Symbol Ledger
25323
+ - **Primary Struct / Class / Component:** [Explicit canonical identifier e.g. MainComponent]
25324
+ - **Entry Source File:** [Explicit file name e.g. MainComponent.ext]
25325
+ - **Key Functions & State Variables:** [Canonical identifiers used across all student activities]
25326
+ - **Artifact Specifications:** [Deliverable requirements for ACT, SLIDE, QUIZ, GUIDE, WKS, CODE, EXT]
25245
25327
 
25246
25328
  ---
25247
25329
 
@@ -25816,17 +25898,23 @@ ${currentContent}` }],
25816
25898
  artifactType: "LESSON"
25817
25899
  });
25818
25900
  const lessonExcerpt = lessonExcerptResult.excerpt;
25819
- const lessonInjectionMeta = {
25820
- source: "LESSON",
25901
+ ({
25821
25902
  verified: lessonExcerptResult.verified,
25822
25903
  sectionAware: lessonExcerptResult.sectionAware,
25823
25904
  issues: lessonExcerptResult.issues
25824
- };
25825
- lessonInjection = lessonInjectionMeta;
25905
+ });
25906
+ const symbolLedger = extractSymbolLedger(lessonContent);
25907
+ const symbolLedgerBlock = symbolLedger.primarySymbol ? `
25908
+
25909
+ [MANDATORY CODE SYMBOL REGISTRY (Inherited from LESSON Plan)]:
25910
+ - Primary Struct / Class / Component: \`${symbolLedger.primarySymbol}\`
25911
+ - Entry Source File: \`${symbolLedger.entryFileName || symbolLedger.primarySymbol}\`
25912
+ - Key Identifiers to inherit verbatim: ${symbolLedger.keySymbols.map((s) => `\`${s}\``).join(", ")}
25913
+ - INVARIANT: You MUST use these exact identifier names in all code examples, exercises, and test assertions. Do NOT invent new struct/class names!` : "";
25826
25914
  const satelliteContext = `${commonContext}
25827
25915
 
25828
25916
  [CANONICAL LESSON PLAN (${pedagogyLabel})]:
25829
- ${lessonExcerpt}`;
25917
+ ${lessonExcerpt}${symbolLedgerBlock}`;
25830
25918
  const judgeSat = (sat, content) => {
25831
25919
  if (gateModeFor(gates, sat) !== "LLM_JUDGE") return Promise.resolve();
25832
25920
  return judgeSatelliteArtifact({
@@ -26329,6 +26417,14 @@ ${buildHeadingDirective("CODE", slcMarkdown, targetLang)}`;
26329
26417
  c3: "### Challenge 3: [Name] (Difficulty: \u2B50\u2B50\u2B50\u2B50\u2B50) \u2014 Extension Milestones (Level 1: Ninja \u2192 Level 2: Guru \u2192 Level 3: Master)",
26330
26418
  meta: "## [REQUIRED] Metacognitive Deep Dive & Engineering Trade-offs"
26331
26419
  };
26420
+ const lessonIdxMatch = lessonCode.match(/L0*(\d+)/i);
26421
+ const lessonIdx = lessonIdxMatch ? parseInt(lessonIdxMatch[1], 10) : 1;
26422
+ const isEarlyLesson = lessonIdx <= 4;
26423
+ const zpdCeilingPrompt = isEarlyLesson ? `
26424
+ 4. CRITICAL ZPD SCOPE LOCK (LESSON #${lessonIdx} - FOUNDATIONAL):
26425
+ - This is an early foundational lesson. The extension challenge MUST focus on creative design variations, parameterization, or edge cases of the current lesson concepts ONLY.
26426
+ - STRICTLY FORBIDDEN: NEVER introduce advanced mechanisms from future lessons (No complex event buses, No remote network/API calls, No persistent databases, No async concurrency, No out-of-scope hardware/sensors).` : `
26427
+ 4. ZPD SCOPE: Focus on architectural edge cases, algorithmic optimization, and synthesis of learned concepts up to Lesson #${lessonIdx}.`;
26332
26428
  const extPrompt = `You are @activity (Lead STEM Specialist & Differentiated Extension Designer).
26333
26429
  Based on Master Lesson Plan \`LESSON_${lessonCode}.md\`, author the advanced extension challenge: \`EXT_${lessonCode}.md\`.
26334
26430
 
@@ -26360,6 +26456,7 @@ ${extHeadings.sub}
26360
26456
  - ${extHeadings.c3}
26361
26457
  - ${extHeadings.meta}
26362
26458
  3. Output 100% clean Markdown directly \u2014 NO code fences around the document.
26459
+ ${zpdCeilingPrompt}
26363
26460
 
26364
26461
  ${languageDirective}
26365
26462
 
@@ -26890,6 +26987,15 @@ async function generateSingleArtifact(req) {
26890
26987
  const artifactSpecializedPrompt = getArtifactSpecializedInvariants(artifactType, {
26891
26988
  ...req,
26892
26989
  studentCount});
26990
+ const techStack = req.config?.techStack || req.hardwarePlatform?.[0] || "Declared Technical Domain";
26991
+ const domainGuardrail = buildDomainLexiconGuardrail(techStack, hwStr);
26992
+ const symbolLedger = contextSot.lessonPlan ? extractSymbolLedger(contextSot.lessonPlan) : null;
26993
+ const symbolLedgerPrompt = symbolLedger?.primarySymbol ? `
26994
+ 7. MANDATORY CODE SYMBOL REGISTRY (Inherited from Canonical LESSON):
26995
+ - Primary Struct / Class: \`${symbolLedger.primarySymbol}\`
26996
+ - Entry Source File: \`${symbolLedger.entryFileName || symbolLedger.primarySymbol + ".swift"}\`
26997
+ - Key Identifiers to inherit: ${symbolLedger.keySymbols.map((s) => `\`${s}\``).join(", ")}
26998
+ - INVARIANT: You MUST use these exact identifier names in all code examples, exercises, and starter templates. Do NOT invent conflicting struct or class names.` : "";
26893
26999
  const systemPrompt = `You are ${meta.persona}, an expert Curriculum & Pedagogical Specialist in the Curriculum OS Multi-Agent Team.
26894
27000
  Your task is to author a canonical, publication-grade learning artifact of type "${artifactType.toUpperCase()}".
26895
27001
 
@@ -26900,7 +27006,10 @@ ${headingDirective}
26900
27006
  3. PEDAGOGICAL GROUNDING: Strictly align with the ${pedagogy.toUpperCase()} model, Bloom's Revised Taxonomy, and IEEE/ACM CS2023 guidelines.
26901
27007
  4. SCAFFOLDING LEVEL: "${scaffoldingLevel.toUpperCase()}".${scaffoldingRule}
26902
27008
  5. TARGET AUDIENCE: ${gradeLevel ? `Grade ${gradeLevel}, ` : ""}${targetAge} on ${hwStr}.${deviceRule}${classDynamicsRule}${extraContextRule}
26903
- 6. OUTPUT INTEGRITY: Output clean Markdown starting directly with YAML frontmatter. Do not wrap entire response in triple backticks.${artifactSpecializedPrompt}${mediaPolicy ? `
27009
+ 6. DOMAIN & TECH STACK GUARDRAILS:
27010
+ ${domainGuardrail}
27011
+ ${symbolLedgerPrompt}
27012
+ 8. OUTPUT INTEGRITY: Output clean Markdown starting directly with YAML frontmatter. Do not wrap entire response in triple backticks.${artifactSpecializedPrompt}${mediaPolicy ? `
26904
27013
 
26905
27014
  IMAGE PLANNING (media ledger) \u2014 QUOTA GEN: t\u1ED1i \u0111a ${mediaPolicy.maxGenImagesPerArtifact} \u1EA3nh AI cho artifact n\xE0y (\u1EA3nh search kho kh\xF4ng gi\u1EDBi h\u1EA1n).
26906
27015
  Khi n\u1ED9i dung c\u1EA7n minh h\u1ECDa (diagram quy tr\xECnh, s\u01A1 \u0111\u1ED3 kh\xE1i ni\u1EC7m, step-by-step visual), ch\xE8n placeholder \u0111\xFAng format [IMAGE: slug] (slug ch\u1EEF th\u01B0\u1EDDng-g\u1EA1ch ngang, unique trong b\xE0i, vd img-for-loop-diagram) T\u1EA0I \u0110\xDANG CH\u1ED6 c\u1EA7n \u1EA3nh, tr\xEAn d\xF2ng ri\xEAng. KH\xD4NG t\u1EF1 sinh \u1EA3nh, KH\xD4NG d\xF9ng markdown image \u2014 placeholder s\u1EBD \u0111\u01B0\u1EE3c thay b\u1EB1ng \u1EA3nh th\u1EADt sau khi Media Curator duy\u1EC7t. Ch\u1EC9 \u0111\u1EB7t cho \u1EA3nh TH\u1EF0C S\u1EF0 c\u1EA7n thi\u1EBFt.` : ""}`;
@@ -27380,6 +27489,24 @@ ${includeUnitTests ? "- Unit Testing: Provide automated assertions or test runne
27380
27489
  1. **CLASS-SCALED INVENTORY FOR ${studentCount} STUDENTS**:
27381
27490
  - Exact quantities calculated for ${studentCount} students.
27382
27491
  - Component specifications, estimated unit cost, and affordable alternatives.`;
27492
+ case "ext": {
27493
+ const lessonIdxMatch = (req.lessonId || "").match(/L0*(\d+)/i);
27494
+ const lessonIdx = lessonIdxMatch ? parseInt(lessonIdxMatch[1], 10) : 1;
27495
+ const isEarlyLesson = lessonIdx <= 4;
27496
+ const zpdCeilingRule = isEarlyLesson ? `- \u{1F6D1} ZPD COMPLEXITY CEILING (FOUNDATIONAL LESSON #${lessonIdx}):
27497
+ \u2022 SCOPE LOCK: This is an early foundational lesson. The extension challenge MUST focus on creative design variations, parameterization, or edge cases of the current lesson concepts ONLY.
27498
+ \u2022 STRICTLY FORBIDDEN: NEVER introduce advanced mechanisms from future lessons (No complex event buses, No remote network/API calls, No persistent databases, No async concurrency, No out-of-scope hardware/sensors).` : `- \u{1F680} ZPD ADVANCED CHALLENGE (LESSON #${lessonIdx}):
27499
+ \u2022 Focus on architectural edge cases, algorithmic optimization, and synthesis of learned concepts up to Lesson #${lessonIdx}.`;
27500
+ return `
27501
+ ### \u{1F680} EXTENSION CHALLENGE ARCHITECTURE INVARIANTS:
27502
+ ${zpdCeilingRule}
27503
+ 1. **STRUCTURED 3-TIER CHALLENGES**:
27504
+ - Challenge 1 (Mission Briefing): High-stakes real-world scenario applying today's concepts.
27505
+ - Challenge 2 (Architectural Constraints & Edge Cases): Deeper technical rules without violating prerequisite boundaries.
27506
+ - Challenge 3 (Extension Milestones): Progressive milestones (Level 1: Novice \u2192 Level 2: Advanced \u2192 Level 3: Master).
27507
+ 2. **METACOGNITIVE & ENGINEERING TRADE-OFFS**:
27508
+ - Explicit reflection prompts evaluating architectural choices, code maintainability, and design patterns.`;
27509
+ }
27383
27510
  case "lesson": {
27384
27511
  const lessonDuration = cfg.lessonDuration || 90;
27385
27512
  const pedagogicalModel = cfg.pedagogicalModel || req.pedagogy || "5e";
@@ -31203,6 +31330,7 @@ exports.buildCurriculumContext = buildCurriculumContext;
31203
31330
  exports.buildCurriculumPlan = buildCurriculumPlan;
31204
31331
  exports.buildDeliveryPackages = buildDeliveryPackages;
31205
31332
  exports.buildDiagnosticQuizPrompt = buildDiagnosticQuizPrompt;
31333
+ exports.buildDomainLexiconGuardrail = buildDomainLexiconGuardrail;
31206
31334
  exports.buildExpositionContext = buildExpositionContext;
31207
31335
  exports.buildExpositionExcerpt = buildExpositionExcerpt;
31208
31336
  exports.buildExtensionPrompt = buildExtensionPrompt;
@@ -31253,6 +31381,7 @@ exports.extractSectionHeadingsFromSLC = extractSectionHeadingsFromSLC;
31253
31381
  exports.extractSessionSlice = extractSessionSlice;
31254
31382
  exports.extractStandardRefs = extractStandardRefs;
31255
31383
  exports.extractStreamChunk = extractStreamChunk;
31384
+ exports.extractSymbolLedger = extractSymbolLedger;
31256
31385
  exports.extractThoughtAndContent = extractThoughtAndContent;
31257
31386
  exports.findStandardStatement = findStandardStatement;
31258
31387
  exports.formatQuizzesToCsv = formatQuizzesToCsv;