@alisio/plugin-thesis 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/agents/thesis-architect.md +38 -0
- package/.agents/agents/thesis-coordinator.md +39 -0
- package/.agents/agents/thesis-editor.md +35 -0
- package/.agents/agents/thesis-evidence-auditor.md +37 -0
- package/.agents/agents/thesis-librarian.md +38 -0
- package/.agents/agents/thesis-methodologist.md +39 -0
- package/.agents/agents/thesis-reviewer.md +36 -0
- package/.agents/agents/thesis-writer.md +38 -0
- package/.agents/skills/thesis-build/SKILL.md +48 -0
- package/.agents/skills/thesis-citations/SKILL.md +49 -0
- package/.agents/skills/thesis-csl-authoring/SKILL.md +48 -0
- package/.agents/skills/thesis-editing/SKILL.md +49 -0
- package/.agents/skills/thesis-evidence/SKILL.md +48 -0
- package/.agents/skills/thesis-figures/SKILL.md +50 -0
- package/.agents/skills/thesis-institution-norms/SKILL.md +50 -0
- package/.agents/skills/thesis-intake/SKILL.md +48 -0
- package/.agents/skills/thesis-math/SKILL.md +48 -0
- package/.agents/skills/thesis-methodology/SKILL.md +49 -0
- package/.agents/skills/thesis-outline/SKILL.md +48 -0
- package/.agents/skills/thesis-policy/SKILL.md +48 -0
- package/.agents/skills/thesis-review/SKILL.md +49 -0
- package/.agents/skills/thesis-search/SKILL.md +47 -0
- package/.agents/skills/thesis-writing/SKILL.md +52 -0
- package/LICENSE +21 -0
- package/README.es.md +242 -0
- package/README.md +235 -0
- package/THIRD_PARTY_NOTICES.md +94 -0
- package/assets/architecture.svg +1 -0
- package/assets/evidence-pipeline.svg +1 -0
- package/assets/lifecycle.svg +1 -0
- package/assets/policy-resolution.svg +1 -0
- package/cover.webp +0 -0
- package/dist/authoring.d.ts +30 -0
- package/dist/authoring.d.ts.map +1 -0
- package/dist/authoring.js +681 -0
- package/dist/authoring.js.map +1 -0
- package/dist/brief.d.ts +40 -0
- package/dist/brief.d.ts.map +1 -0
- package/dist/brief.js +566 -0
- package/dist/brief.js.map +1 -0
- package/dist/cache.d.ts +8 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +20 -0
- package/dist/cache.js.map +1 -0
- package/dist/checks/brief.d.ts +5 -0
- package/dist/checks/brief.d.ts.map +1 -0
- package/dist/checks/brief.js +38 -0
- package/dist/checks/brief.js.map +1 -0
- package/dist/checks/citations.d.ts +14 -0
- package/dist/checks/citations.d.ts.map +1 -0
- package/dist/checks/citations.js +87 -0
- package/dist/checks/citations.js.map +1 -0
- package/dist/checks/claims.d.ts +16 -0
- package/dist/checks/claims.d.ts.map +1 -0
- package/dist/checks/claims.js +147 -0
- package/dist/checks/claims.js.map +1 -0
- package/dist/checks/closing.d.ts +20 -0
- package/dist/checks/closing.d.ts.map +1 -0
- package/dist/checks/closing.js +168 -0
- package/dist/checks/closing.js.map +1 -0
- package/dist/checks/design.d.ts +5 -0
- package/dist/checks/design.d.ts.map +1 -0
- package/dist/checks/design.js +107 -0
- package/dist/checks/design.js.map +1 -0
- package/dist/checks/document.d.ts +17 -0
- package/dist/checks/document.d.ts.map +1 -0
- package/dist/checks/document.js +213 -0
- package/dist/checks/document.js.map +1 -0
- package/dist/checks/evidence.d.ts +7 -0
- package/dist/checks/evidence.d.ts.map +1 -0
- package/dist/checks/evidence.js +133 -0
- package/dist/checks/evidence.js.map +1 -0
- package/dist/checks/hygiene.d.ts +5 -0
- package/dist/checks/hygiene.d.ts.map +1 -0
- package/dist/checks/hygiene.js +37 -0
- package/dist/checks/hygiene.js.map +1 -0
- package/dist/checks/index.d.ts +21 -0
- package/dist/checks/index.d.ts.map +1 -0
- package/dist/checks/index.js +98 -0
- package/dist/checks/index.js.map +1 -0
- package/dist/checks/language.d.ts +14 -0
- package/dist/checks/language.d.ts.map +1 -0
- package/dist/checks/language.js +73 -0
- package/dist/checks/language.js.map +1 -0
- package/dist/checks/outline.d.ts +25 -0
- package/dist/checks/outline.d.ts.map +1 -0
- package/dist/checks/outline.js +214 -0
- package/dist/checks/outline.js.map +1 -0
- package/dist/checks/policy.d.ts +5 -0
- package/dist/checks/policy.d.ts.map +1 -0
- package/dist/checks/policy.js +129 -0
- package/dist/checks/policy.js.map +1 -0
- package/dist/checks/project.d.ts +65 -0
- package/dist/checks/project.d.ts.map +1 -0
- package/dist/checks/project.js +203 -0
- package/dist/checks/project.js.map +1 -0
- package/dist/checks/styles.d.ts +12 -0
- package/dist/checks/styles.d.ts.map +1 -0
- package/dist/checks/styles.js +67 -0
- package/dist/checks/styles.js.map +1 -0
- package/dist/checks/writing.d.ts +6 -0
- package/dist/checks/writing.d.ts.map +1 -0
- package/dist/checks/writing.js +115 -0
- package/dist/checks/writing.js.map +1 -0
- package/dist/chrome/detect.d.ts +19 -0
- package/dist/chrome/detect.d.ts.map +1 -0
- package/dist/chrome/detect.js +116 -0
- package/dist/chrome/detect.js.map +1 -0
- package/dist/claims.d.ts +19 -0
- package/dist/claims.d.ts.map +1 -0
- package/dist/claims.js +99 -0
- package/dist/claims.js.map +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +262 -0
- package/dist/cli.js.map +1 -0
- package/dist/context.d.ts +55 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +62 -0
- package/dist/context.js.map +1 -0
- package/dist/coordinator.d.ts +139 -0
- package/dist/coordinator.d.ts.map +1 -0
- package/dist/coordinator.js +710 -0
- package/dist/coordinator.js.map +1 -0
- package/dist/delegate.d.ts +34 -0
- package/dist/delegate.d.ts.map +1 -0
- package/dist/delegate.js +105 -0
- package/dist/delegate.js.map +1 -0
- package/dist/diffguard.d.ts +24 -0
- package/dist/diffguard.d.ts.map +1 -0
- package/dist/diffguard.js +92 -0
- package/dist/diffguard.js.map +1 -0
- package/dist/doctor.d.ts +34 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +155 -0
- package/dist/doctor.js.map +1 -0
- package/dist/draft.d.ts +64 -0
- package/dist/draft.d.ts.map +1 -0
- package/dist/draft.js +801 -0
- package/dist/draft.js.map +1 -0
- package/dist/figure.d.ts +13 -0
- package/dist/figure.d.ts.map +1 -0
- package/dist/figure.js +143 -0
- package/dist/figure.js.map +1 -0
- package/dist/finalize.d.ts +29 -0
- package/dist/finalize.d.ts.map +1 -0
- package/dist/finalize.js +230 -0
- package/dist/finalize.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +206 -0
- package/dist/index.js.map +1 -0
- package/dist/intake.d.ts +57 -0
- package/dist/intake.d.ts.map +1 -0
- package/dist/intake.js +772 -0
- package/dist/intake.js.map +1 -0
- package/dist/labels.d.ts +50 -0
- package/dist/labels.d.ts.map +1 -0
- package/dist/labels.js +98 -0
- package/dist/labels.js.map +1 -0
- package/dist/outline.d.ts +45 -0
- package/dist/outline.d.ts.map +1 -0
- package/dist/outline.js +148 -0
- package/dist/outline.js.map +1 -0
- package/dist/pack-commands.d.ts +18 -0
- package/dist/pack-commands.d.ts.map +1 -0
- package/dist/pack-commands.js +397 -0
- package/dist/pack-commands.js.map +1 -0
- package/dist/package-paths.d.ts +8 -0
- package/dist/package-paths.d.ts.map +1 -0
- package/dist/package-paths.js +13 -0
- package/dist/package-paths.js.map +1 -0
- package/dist/policy/context.d.ts +19 -0
- package/dist/policy/context.d.ts.map +1 -0
- package/dist/policy/context.js +62 -0
- package/dist/policy/context.js.map +1 -0
- package/dist/policy/ethics.d.ts +59 -0
- package/dist/policy/ethics.d.ts.map +1 -0
- package/dist/policy/ethics.js +106 -0
- package/dist/policy/ethics.js.map +1 -0
- package/dist/policy/kinds.d.ts +9 -0
- package/dist/policy/kinds.d.ts.map +1 -0
- package/dist/policy/kinds.js +68 -0
- package/dist/policy/kinds.js.map +1 -0
- package/dist/policy/packs.d.ts +53 -0
- package/dist/policy/packs.d.ts.map +1 -0
- package/dist/policy/packs.js +336 -0
- package/dist/policy/packs.js.map +1 -0
- package/dist/policy/resolver.d.ts +87 -0
- package/dist/policy/resolver.d.ts.map +1 -0
- package/dist/policy/resolver.js +337 -0
- package/dist/policy/resolver.js.map +1 -0
- package/dist/policy/rules.d.ts +65 -0
- package/dist/policy/rules.d.ts.map +1 -0
- package/dist/policy/rules.js +194 -0
- package/dist/policy/rules.js.map +1 -0
- package/dist/protocol.d.ts +46 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +86 -0
- package/dist/protocol.js.map +1 -0
- package/dist/render/adapters/chrome-pdf/cdp.d.ts +36 -0
- package/dist/render/adapters/chrome-pdf/cdp.d.ts.map +1 -0
- package/dist/render/adapters/chrome-pdf/cdp.js +291 -0
- package/dist/render/adapters/chrome-pdf/cdp.js.map +1 -0
- package/dist/render/adapters/chrome-pdf/index.d.ts +10 -0
- package/dist/render/adapters/chrome-pdf/index.d.ts.map +1 -0
- package/dist/render/adapters/chrome-pdf/index.js +139 -0
- package/dist/render/adapters/chrome-pdf/index.js.map +1 -0
- package/dist/render/adapters/chrome-pdf/network.d.ts +7 -0
- package/dist/render/adapters/chrome-pdf/network.d.ts.map +1 -0
- package/dist/render/adapters/chrome-pdf/network.js +33 -0
- package/dist/render/adapters/chrome-pdf/network.js.map +1 -0
- package/dist/render/adapters/html-preview/index.d.ts +8 -0
- package/dist/render/adapters/html-preview/index.d.ts.map +1 -0
- package/dist/render/adapters/html-preview/index.js +62 -0
- package/dist/render/adapters/html-preview/index.js.map +1 -0
- package/dist/render/adapters/test-json/index.d.ts +8 -0
- package/dist/render/adapters/test-json/index.d.ts.map +1 -0
- package/dist/render/adapters/test-json/index.js +62 -0
- package/dist/render/adapters/test-json/index.js.map +1 -0
- package/dist/render/adapters/typst-pdf/emitter.d.ts +21 -0
- package/dist/render/adapters/typst-pdf/emitter.d.ts.map +1 -0
- package/dist/render/adapters/typst-pdf/emitter.js +259 -0
- package/dist/render/adapters/typst-pdf/emitter.js.map +1 -0
- package/dist/render/adapters/typst-pdf/escape.d.ts +14 -0
- package/dist/render/adapters/typst-pdf/escape.d.ts.map +1 -0
- package/dist/render/adapters/typst-pdf/escape.js +56 -0
- package/dist/render/adapters/typst-pdf/escape.js.map +1 -0
- package/dist/render/adapters/typst-pdf/index.d.ts +9 -0
- package/dist/render/adapters/typst-pdf/index.d.ts.map +1 -0
- package/dist/render/adapters/typst-pdf/index.js +154 -0
- package/dist/render/adapters/typst-pdf/index.js.map +1 -0
- package/dist/render/adapters/typst-pdf/profile.d.ts +3 -0
- package/dist/render/adapters/typst-pdf/profile.d.ts.map +1 -0
- package/dist/render/adapters/typst-pdf/profile.js +55 -0
- package/dist/render/adapters/typst-pdf/profile.js.map +1 -0
- package/dist/render/adapters/typst-pdf/runner.d.ts +52 -0
- package/dist/render/adapters/typst-pdf/runner.d.ts.map +1 -0
- package/dist/render/adapters/typst-pdf/runner.js +209 -0
- package/dist/render/adapters/typst-pdf/runner.js.map +1 -0
- package/dist/render/adapters/typst-pdf/setup.d.ts +30 -0
- package/dist/render/adapters/typst-pdf/setup.d.ts.map +1 -0
- package/dist/render/adapters/typst-pdf/setup.js +183 -0
- package/dist/render/adapters/typst-pdf/setup.js.map +1 -0
- package/dist/render/adapters/typst-pdf/version.d.ts +8 -0
- package/dist/render/adapters/typst-pdf/version.d.ts.map +1 -0
- package/dist/render/adapters/typst-pdf/version.js +14 -0
- package/dist/render/adapters/typst-pdf/version.js.map +1 -0
- package/dist/render/assemble.d.ts +28 -0
- package/dist/render/assemble.d.ts.map +1 -0
- package/dist/render/assemble.js +309 -0
- package/dist/render/assemble.js.map +1 -0
- package/dist/render/assets.d.ts +27 -0
- package/dist/render/assets.d.ts.map +1 -0
- package/dist/render/assets.js +232 -0
- package/dist/render/assets.js.map +1 -0
- package/dist/render/build.d.ts +43 -0
- package/dist/render/build.d.ts.map +1 -0
- package/dist/render/build.js +187 -0
- package/dist/render/build.js.map +1 -0
- package/dist/render/charts.d.ts +83 -0
- package/dist/render/charts.d.ts.map +1 -0
- package/dist/render/charts.js +633 -0
- package/dist/render/charts.js.map +1 -0
- package/dist/render/default-registry.d.ts +7 -0
- package/dist/render/default-registry.d.ts.map +1 -0
- package/dist/render/default-registry.js +15 -0
- package/dist/render/default-registry.js.map +1 -0
- package/dist/render/diagram-theme.d.ts +7 -0
- package/dist/render/diagram-theme.d.ts.map +1 -0
- package/dist/render/diagram-theme.js +50 -0
- package/dist/render/diagram-theme.js.map +1 -0
- package/dist/render/dialect.d.ts +23 -0
- package/dist/render/dialect.d.ts.map +1 -0
- package/dist/render/dialect.js +188 -0
- package/dist/render/dialect.js.map +1 -0
- package/dist/render/html/citations.d.ts +70 -0
- package/dist/render/html/citations.d.ts.map +1 -0
- package/dist/render/html/citations.js +371 -0
- package/dist/render/html/citations.js.map +1 -0
- package/dist/render/html/css.d.ts +14 -0
- package/dist/render/html/css.d.ts.map +1 -0
- package/dist/render/html/css.js +113 -0
- package/dist/render/html/css.js.map +1 -0
- package/dist/render/html/emitter.d.ts +20 -0
- package/dist/render/html/emitter.d.ts.map +1 -0
- package/dist/render/html/emitter.js +652 -0
- package/dist/render/html/emitter.js.map +1 -0
- package/dist/render/html/escape.d.ts +11 -0
- package/dist/render/html/escape.d.ts.map +1 -0
- package/dist/render/html/escape.js +32 -0
- package/dist/render/html/escape.js.map +1 -0
- package/dist/render/html/katex.d.ts +9 -0
- package/dist/render/html/katex.d.ts.map +1 -0
- package/dist/render/html/katex.js +39 -0
- package/dist/render/html/katex.js.map +1 -0
- package/dist/render/html/stage.d.ts +12 -0
- package/dist/render/html/stage.d.ts.map +1 -0
- package/dist/render/html/stage.js +30 -0
- package/dist/render/html/stage.js.map +1 -0
- package/dist/render/index.d.ts +5 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +5 -0
- package/dist/render/index.js.map +1 -0
- package/dist/render/math.d.ts +9 -0
- package/dist/render/math.d.ts.map +1 -0
- package/dist/render/math.js +60 -0
- package/dist/render/math.js.map +1 -0
- package/dist/render/model.d.ts +233 -0
- package/dist/render/model.d.ts.map +1 -0
- package/dist/render/model.js +2 -0
- package/dist/render/model.js.map +1 -0
- package/dist/render/numbering.d.ts +51 -0
- package/dist/render/numbering.d.ts.map +1 -0
- package/dist/render/numbering.js +155 -0
- package/dist/render/numbering.js.map +1 -0
- package/dist/render/output-name.d.ts +4 -0
- package/dist/render/output-name.d.ts.map +1 -0
- package/dist/render/output-name.js +11 -0
- package/dist/render/output-name.js.map +1 -0
- package/dist/render/palettes.d.ts +22 -0
- package/dist/render/palettes.d.ts.map +1 -0
- package/dist/render/palettes.js +46 -0
- package/dist/render/palettes.js.map +1 -0
- package/dist/render/parse.d.ts +15 -0
- package/dist/render/parse.d.ts.map +1 -0
- package/dist/render/parse.js +637 -0
- package/dist/render/parse.js.map +1 -0
- package/dist/render/port.d.ts +79 -0
- package/dist/render/port.d.ts.map +1 -0
- package/dist/render/port.js +2 -0
- package/dist/render/port.js.map +1 -0
- package/dist/render/registry.d.ts +11 -0
- package/dist/render/registry.d.ts.map +1 -0
- package/dist/render/registry.js +21 -0
- package/dist/render/registry.js.map +1 -0
- package/dist/render/text.d.ts +13 -0
- package/dist/render/text.d.ts.map +1 -0
- package/dist/render/text.js +65 -0
- package/dist/render/text.js.map +1 -0
- package/dist/render/walk.d.ts +13 -0
- package/dist/render/walk.d.ts.map +1 -0
- package/dist/render/walk.js +69 -0
- package/dist/render/walk.js.map +1 -0
- package/dist/research/bibtex.d.ts +12 -0
- package/dist/research/bibtex.d.ts.map +1 -0
- package/dist/research/bibtex.js +99 -0
- package/dist/research/bibtex.js.map +1 -0
- package/dist/research/client.d.ts +112 -0
- package/dist/research/client.d.ts.map +1 -0
- package/dist/research/client.js +661 -0
- package/dist/research/client.js.map +1 -0
- package/dist/research/dossier.d.ts +31 -0
- package/dist/research/dossier.d.ts.map +1 -0
- package/dist/research/dossier.js +54 -0
- package/dist/research/dossier.js.map +1 -0
- package/dist/research/flow.d.ts +31 -0
- package/dist/research/flow.d.ts.map +1 -0
- package/dist/research/flow.js +635 -0
- package/dist/research/flow.js.map +1 -0
- package/dist/research/library.d.ts +79 -0
- package/dist/research/library.d.ts.map +1 -0
- package/dist/research/library.js +319 -0
- package/dist/research/library.js.map +1 -0
- package/dist/research/verify.d.ts +80 -0
- package/dist/research/verify.d.ts.map +1 -0
- package/dist/research/verify.js +307 -0
- package/dist/research/verify.js.map +1 -0
- package/dist/resources.d.ts +15 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +148 -0
- package/dist/resources.js.map +1 -0
- package/dist/review.d.ts +22 -0
- package/dist/review.d.ts.map +1 -0
- package/dist/review.js +355 -0
- package/dist/review.js.map +1 -0
- package/dist/schemas.d.ts +252 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +1020 -0
- package/dist/schemas.js.map +1 -0
- package/dist/sections.d.ts +30 -0
- package/dist/sections.d.ts.map +1 -0
- package/dist/sections.js +62 -0
- package/dist/sections.js.map +1 -0
- package/dist/storage.d.ts +21 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +296 -0
- package/dist/storage.js.map +1 -0
- package/dist/style-commands.d.ts +15 -0
- package/dist/style-commands.d.ts.map +1 -0
- package/dist/style-commands.js +54 -0
- package/dist/style-commands.js.map +1 -0
- package/dist/styles/csl.d.ts +58 -0
- package/dist/styles/csl.d.ts.map +1 -0
- package/dist/styles/csl.js +112 -0
- package/dist/styles/csl.js.map +1 -0
- package/dist/styles/discovery.d.ts +45 -0
- package/dist/styles/discovery.d.ts.map +1 -0
- package/dist/styles/discovery.js +99 -0
- package/dist/styles/discovery.js.map +1 -0
- package/dist/styles/golden.d.ts +52 -0
- package/dist/styles/golden.d.ts.map +1 -0
- package/dist/styles/golden.js +216 -0
- package/dist/styles/golden.js.map +1 -0
- package/dist/styles/profile.d.ts +126 -0
- package/dist/styles/profile.d.ts.map +1 -0
- package/dist/styles/profile.js +582 -0
- package/dist/styles/profile.js.map +1 -0
- package/dist/styles/xml.d.ts +22 -0
- package/dist/styles/xml.d.ts.map +1 -0
- package/dist/styles/xml.js +179 -0
- package/dist/styles/xml.js.map +1 -0
- package/dist/types.d.ts +285 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +155 -0
- package/dist/types.js.map +1 -0
- package/dist/typst-pins.d.ts +16 -0
- package/dist/typst-pins.d.ts.map +1 -0
- package/dist/typst-pins.js +39 -0
- package/dist/typst-pins.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/dist/workflow.d.ts +49 -0
- package/dist/workflow.d.ts.map +1 -0
- package/dist/workflow.js +722 -0
- package/dist/workflow.js.map +1 -0
- package/dist/workspace.d.ts +12 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +71 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +70 -0
- package/policy-packs/countries/CO/academic-standards/ntc-1486-2022.yaml +188 -0
- package/policy-packs/countries/CO/copyright/decision-andina-351.yaml +61 -0
- package/policy-packs/countries/CO/copyright/ley-1915-2018.yaml +25 -0
- package/policy-packs/countries/CO/copyright/ley-23-1982.yaml +64 -0
- package/policy-packs/countries/CO/domains/health/resolucion-8430-1993.yaml +219 -0
- package/policy-packs/countries/CO/higher-education/ley-30-1992.yaml +61 -0
- package/policy-packs/countries/CO/manifest.yaml +42 -0
- package/policy-packs/countries/CO/official-domains.yaml +90 -0
- package/policy-packs/countries/CO/privacy/ley-1581-2012.yaml +197 -0
- package/policy-packs/countries/CO/research-integrity/minciencias-res-0314-2018.yaml +64 -0
- package/policy-packs/global/academic-integrity.yaml +45 -0
- package/policy-packs/global/academic-writing.yaml +70 -0
- package/policy-packs/global/evidence-quality.yaml +81 -0
- package/policy-packs/global/manifest.yaml +54 -0
- package/policy-packs/global/objective-verbs.yaml +245 -0
- package/policy-packs/global/reporting-guidelines.yaml +392 -0
- package/policy-packs/global/work-types.yaml +195 -0
- package/styles/LICENSE-CSL +375 -0
- package/styles/apa.csl +2283 -0
- package/styles/catalog.json +43 -0
- package/styles/fixtures/apa-7.expected.json +25 -0
- package/styles/fixtures/icontec-ntc1486-2022.expected.json +25 -0
- package/styles/fixtures/ieee.expected.json +25 -0
- package/styles/fixtures/references.jsonl +8 -0
- package/styles/icontec-ntc1486-2022.csl +388 -0
- package/styles/ieee.csl +519 -0
- package/templates/html/runtime.js +159 -0
- package/templates/html/thesis.css +98 -0
- package/templates/html/vendor/katex/LICENSE +21 -0
- package/templates/html/vendor/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/templates/html/vendor/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/templates/html/vendor/katex/katex.min.css +1 -0
- package/templates/html/vendor/katex/katex.min.js +1 -0
- package/templates/html/vendor/mermaid/LICENSE +21 -0
- package/templates/html/vendor/mermaid/mermaid.min.js +3587 -0
- package/templates/html/vendor/pagedjs/LICENSE +21 -0
- package/templates/html/vendor/pagedjs/paged.polyfill.min.js +4 -0
- package/templates/palettes.json +57 -0
- package/templates/profiles/apa-7.profile.yaml +15 -0
- package/templates/profiles/generic.profile.yaml +20 -0
- package/templates/profiles/icontec-ntc1486-2022.profile.yaml +36 -0
- package/templates/profiles/ieee.profile.yaml +14 -0
- package/templates/typst/i18n/en.yaml +31 -0
- package/templates/typst/i18n/es.yaml +31 -0
- package/templates/typst/i18n/pt.yaml +31 -0
- package/templates/typst/thesis.typ +276 -0
- package/typst-packages/preview/merman/0.3.0/LICENSE +231 -0
- package/typst-packages/preview/merman/0.3.0/README.md +388 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/cose-base-v1/LICENSE +21 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/cose-base-v2/LICENSE +21 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/cytoscape/LICENSE +19 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/cytoscape-cose-bilkent/LICENSE +21 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/cytoscape-fcose/LICENSE +19 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/d3-shape/LICENSE +13 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/dagre/LICENSE +19 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/dompurify/LICENSE +202 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/eclipse-elk/LICENSE.md +264 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/elkjs/LICENSE.md +264 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/fmin/LICENSE +27 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/graphlib/LICENSE +19 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/layout-base-v1/LICENSE +21 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/layout-base-v2/LICENSE +21 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/mermaid/LICENSE +21 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/rough-rs/LICENSE +21 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/roughjs/LICENSE +21 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/sanitize-url/LICENSE +21 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/venn-js/LICENSE +22 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/wasm-minimal-protocol/LICENSE +24 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/zenuml-core/LICENSE +21 -0
- package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_NOTICES.md +265 -0
- package/typst-packages/preview/merman/0.3.0/lib.typ +1 -0
- package/typst-packages/preview/merman/0.3.0/merman_typst_plugin.wasm +0 -0
- package/typst-packages/preview/merman/0.3.0/src/capabilities.typ +5 -0
- package/typst-packages/preview/merman/0.3.0/src/context.typ +1 -0
- package/typst-packages/preview/merman/0.3.0/src/errors.typ +33 -0
- package/typst-packages/preview/merman/0.3.0/src/exports.typ +5 -0
- package/typst-packages/preview/merman/0.3.0/src/figure.typ +143 -0
- package/typst-packages/preview/merman/0.3.0/src/image.typ +50 -0
- package/typst-packages/preview/merman/0.3.0/src/options.typ +566 -0
- package/typst-packages/preview/merman/0.3.0/src/plugin.typ +1 -0
- package/typst-packages/preview/merman/0.3.0/src/raw.typ +22 -0
- package/typst-packages/preview/merman/0.3.0/src/render.typ +137 -0
- package/typst-packages/preview/merman/0.3.0/src/source.typ +7 -0
- package/typst-packages/preview/merman/0.3.0/src/units.typ +51 -0
- package/typst-packages/preview/merman/0.3.0/typst.toml +12 -0
- package/typst-packages/preview/mitex/0.2.7/CHANGELOG.md +69 -0
- package/typst-packages/preview/mitex/0.2.7/LICENSE +176 -0
- package/typst-packages/preview/mitex/0.2.7/README.md +154 -0
- package/typst-packages/preview/mitex/0.2.7/lib.typ +1 -0
- package/typst-packages/preview/mitex/0.2.7/mitex.typ +45 -0
- package/typst-packages/preview/mitex/0.2.7/mitex.wasm +0 -0
- package/typst-packages/preview/mitex/0.2.7/specs/README.md +250 -0
- package/typst-packages/preview/mitex/0.2.7/specs/latex/standard.typ +1187 -0
- package/typst-packages/preview/mitex/0.2.7/specs/mod.typ +12 -0
- package/typst-packages/preview/mitex/0.2.7/specs/prelude.typ +230 -0
- package/typst-packages/preview/mitex/0.2.7/typst.toml +12 -0
package/dist/intake.js
ADDED
|
@@ -0,0 +1,772 @@
|
|
|
1
|
+
import { applyBriefDefaults, isValidLanguageTag, loadBrief, primaryLanguage, stringifyBrief, } from "./brief.js";
|
|
2
|
+
import { approaches, paletteNames, } from "./types.js";
|
|
3
|
+
export const defaultRounds = [1, 2, 3];
|
|
4
|
+
export const presentationRound = 4;
|
|
5
|
+
/** Extra presentation questions asked only when the ICONTEC profile is selected (spec 10.3). */
|
|
6
|
+
export const icontecRound = 5;
|
|
7
|
+
export const roundTitles = {
|
|
8
|
+
1: "language and frame",
|
|
9
|
+
2: "institution and style",
|
|
10
|
+
3: "research intent",
|
|
11
|
+
4: "presentation",
|
|
12
|
+
5: "ICONTEC presentation",
|
|
13
|
+
};
|
|
14
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: control characters are what is rejected
|
|
15
|
+
const controlPattern = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/;
|
|
16
|
+
const maxText = 600;
|
|
17
|
+
const option = (value, label, description, extra = {}) => ({
|
|
18
|
+
value,
|
|
19
|
+
label,
|
|
20
|
+
...(description ? { description } : {}),
|
|
21
|
+
...(extra.recommended ? { recommended: true } : {}),
|
|
22
|
+
...(extra.placeholder ? { textInput: { placeholder: extra.placeholder } } : {}),
|
|
23
|
+
});
|
|
24
|
+
function countryFromContext({ hint, answers }) {
|
|
25
|
+
const answered = answers.country;
|
|
26
|
+
if (answered === "CO")
|
|
27
|
+
return "CO";
|
|
28
|
+
if (answered === "other")
|
|
29
|
+
return answers["country:text"]?.toUpperCase();
|
|
30
|
+
const region = hint.split("-")[1];
|
|
31
|
+
return region && /^[A-Za-z]{2}$/.test(region) ? region.toUpperCase() : undefined;
|
|
32
|
+
}
|
|
33
|
+
/** Language chosen so far, falling back to the conversation hint. */
|
|
34
|
+
function chosenLanguage(context) {
|
|
35
|
+
const value = context.answers.language;
|
|
36
|
+
if (value === "es" || value === "en")
|
|
37
|
+
return value;
|
|
38
|
+
if (value === "other")
|
|
39
|
+
return context.answers["language:text"] ?? context.hint;
|
|
40
|
+
return context.hint;
|
|
41
|
+
}
|
|
42
|
+
function slug(text) {
|
|
43
|
+
return text
|
|
44
|
+
.normalize("NFD")
|
|
45
|
+
.replace(/[̀-ͯ]/g, "")
|
|
46
|
+
.toLowerCase()
|
|
47
|
+
.replace(/[^a-z0-9]+/g, "_")
|
|
48
|
+
.replace(/^_+|_+$/g, "")
|
|
49
|
+
.slice(0, 40);
|
|
50
|
+
}
|
|
51
|
+
const specs = [
|
|
52
|
+
{
|
|
53
|
+
id: "language",
|
|
54
|
+
round: 1,
|
|
55
|
+
textRequired: ["other"],
|
|
56
|
+
validateText: (_, text) => isValidLanguageTag(text)
|
|
57
|
+
? undefined
|
|
58
|
+
: "language text must be a BCP-47 tag such as pt-BR or fr-CA",
|
|
59
|
+
build: ({ hint }) => ({
|
|
60
|
+
id: "language",
|
|
61
|
+
header: "Language",
|
|
62
|
+
question: "In which language will the thesis be written?",
|
|
63
|
+
options: [
|
|
64
|
+
option("conversation", `Conversation language (${hint})`, "Use the language of this conversation.", { recommended: true }),
|
|
65
|
+
option("es", "Spanish", "Written in Spanish; the region follows the country you pick."),
|
|
66
|
+
option("en", "English", "Written in English."),
|
|
67
|
+
option("other", "Other language", "Type a BCP-47 tag such as pt-BR or fr-CA.", {
|
|
68
|
+
placeholder: "BCP-47 tag, for example pt-BR",
|
|
69
|
+
}),
|
|
70
|
+
],
|
|
71
|
+
}),
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "workType",
|
|
75
|
+
round: 1,
|
|
76
|
+
build: () => ({
|
|
77
|
+
id: "workType",
|
|
78
|
+
header: "Work type",
|
|
79
|
+
question: "What kind of work is it?",
|
|
80
|
+
options: [
|
|
81
|
+
option("undergraduate_thesis", "Undergraduate thesis / degree project", "Final project for a bachelor's degree.", { recommended: true }),
|
|
82
|
+
option("master_thesis", "Master's thesis", "Final research work for a master's degree."),
|
|
83
|
+
option("doctoral_dissertation", "Doctoral dissertation", "Original research for a doctorate."),
|
|
84
|
+
option("monograph", "Monograph", "A focused, single-topic study."),
|
|
85
|
+
],
|
|
86
|
+
}),
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "country",
|
|
90
|
+
round: 1,
|
|
91
|
+
textRequired: ["other"],
|
|
92
|
+
validateText: (_, text) => /^[A-Za-z]{2}$/.test(text)
|
|
93
|
+
? undefined
|
|
94
|
+
: "country text must be an ISO 3166-1 alpha-2 code such as MX",
|
|
95
|
+
build: (context) => {
|
|
96
|
+
const language = chosenLanguage(context);
|
|
97
|
+
const colombia = primaryLanguage(language) === "es" && (countryFromContext(context) ?? "CO") === "CO";
|
|
98
|
+
return {
|
|
99
|
+
id: "country",
|
|
100
|
+
header: "Country",
|
|
101
|
+
question: "In which country will it be submitted?",
|
|
102
|
+
options: [
|
|
103
|
+
option("CO", "Colombia", "Loads the Colombian policy pack when it is available.", {
|
|
104
|
+
recommended: colombia,
|
|
105
|
+
}),
|
|
106
|
+
option("other", "Other country", "Type an ISO 3166-1 alpha-2 code such as MX.", {
|
|
107
|
+
placeholder: "ISO country code, for example MX",
|
|
108
|
+
}),
|
|
109
|
+
],
|
|
110
|
+
};
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
id: "secondaryAbstract",
|
|
115
|
+
round: 1,
|
|
116
|
+
textRequired: ["other"],
|
|
117
|
+
validateText: (_, text) => isValidLanguageTag(text)
|
|
118
|
+
? undefined
|
|
119
|
+
: "secondaryAbstract text must be a BCP-47 tag such as pt-BR",
|
|
120
|
+
build: (context) => {
|
|
121
|
+
const english = primaryLanguage(chosenLanguage(context)) === "en";
|
|
122
|
+
return {
|
|
123
|
+
id: "secondaryAbstract",
|
|
124
|
+
header: "Second abstract",
|
|
125
|
+
question: "Does it need an abstract in a second language?",
|
|
126
|
+
options: [
|
|
127
|
+
option("en", "Yes, English", "Add an English abstract.", { recommended: !english }),
|
|
128
|
+
option("none", "No", "A single-language abstract is enough.", { recommended: english }),
|
|
129
|
+
option("other", "Yes, another language", "Type a BCP-47 tag such as pt-BR.", {
|
|
130
|
+
placeholder: "BCP-47 tag, for example pt-BR",
|
|
131
|
+
}),
|
|
132
|
+
],
|
|
133
|
+
};
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
id: "institution",
|
|
138
|
+
round: 2,
|
|
139
|
+
textRequired: ["enter"],
|
|
140
|
+
validateText: (_, text) => parseInstitution(text) ? undefined : "institution text needs at least the university name",
|
|
141
|
+
build: () => ({
|
|
142
|
+
id: "institution",
|
|
143
|
+
header: "Institution",
|
|
144
|
+
question: "University, faculty and program",
|
|
145
|
+
options: [
|
|
146
|
+
option("enter", "Enter them", "Format: University; Faculty; Program; City (only the university is required).", {
|
|
147
|
+
recommended: true,
|
|
148
|
+
placeholder: "University; Faculty; Program; City",
|
|
149
|
+
}),
|
|
150
|
+
option("undecided", "Not decided yet", "Skip for now; you can edit thesis.yaml later."),
|
|
151
|
+
],
|
|
152
|
+
}),
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
id: "citationStyle",
|
|
156
|
+
round: 2,
|
|
157
|
+
build: () => ({
|
|
158
|
+
id: "citationStyle",
|
|
159
|
+
header: "Citation style",
|
|
160
|
+
question: "Which citation style does your program require?",
|
|
161
|
+
options: [
|
|
162
|
+
option("auto", "Let the policy decide", "Institution rules decide; otherwise APA 7 is used and flagged for you to confirm.", { recommended: true }),
|
|
163
|
+
option("apa-7", "APA 7", "Author-date citations."),
|
|
164
|
+
option("ieee", "IEEE", "Numbered citations, common in engineering."),
|
|
165
|
+
option("icontec-ntc1486-2022", "ICONTEC NTC 1486:2022", "Colombian standard; never selected automatically."),
|
|
166
|
+
],
|
|
167
|
+
}),
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
id: "domain",
|
|
171
|
+
round: 2,
|
|
172
|
+
validateText: (value, text) => value === "social_sciences" && !domainFromText(text)
|
|
173
|
+
? "domain text must contain letters or digits to derive a domain id"
|
|
174
|
+
: undefined,
|
|
175
|
+
build: () => ({
|
|
176
|
+
id: "domain",
|
|
177
|
+
header: "Domain",
|
|
178
|
+
question: "Primary research domain",
|
|
179
|
+
options: [
|
|
180
|
+
option("detected", "Detected from the topic", "Decide the domain later from your topic.", {
|
|
181
|
+
recommended: true,
|
|
182
|
+
}),
|
|
183
|
+
option("computer_science", "Engineering / Computer science", "Technical and computing research."),
|
|
184
|
+
option("health_sciences", "Health sciences", "Health and clinical research."),
|
|
185
|
+
option("social_sciences", "Social sciences / Education", "Optionally type a more precise domain.", { placeholder: "Optional: a more precise domain" }),
|
|
186
|
+
],
|
|
187
|
+
}),
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
id: "approach",
|
|
191
|
+
round: 2,
|
|
192
|
+
validateText: (value, text) => value === "mixed" && !approaches.includes(text)
|
|
193
|
+
? `approach text must be one of: ${approaches.join(", ")}`
|
|
194
|
+
: undefined,
|
|
195
|
+
build: ({ answers }) => ({
|
|
196
|
+
id: "approach",
|
|
197
|
+
header: "Approach",
|
|
198
|
+
question: "Research approach",
|
|
199
|
+
options: [
|
|
200
|
+
option("recommended", "Recommended from the domain", `Uses ${recommendedApproach(answers)} for your domain.`, { recommended: true }),
|
|
201
|
+
option("quantitative", "Quantitative", "Numerical data and statistical analysis."),
|
|
202
|
+
option("qualitative", "Qualitative", "Interpretive analysis of non-numerical data."),
|
|
203
|
+
option("mixed", "Mixed", "Both. Optionally type design_science, theoretical or systematic_review instead.", { placeholder: "Optional: design_science, theoretical or systematic_review" }),
|
|
204
|
+
],
|
|
205
|
+
}),
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
id: "title",
|
|
209
|
+
round: 3,
|
|
210
|
+
textRequired: ["enter"],
|
|
211
|
+
build: () => ({
|
|
212
|
+
id: "title",
|
|
213
|
+
header: "Title",
|
|
214
|
+
question: "Working title",
|
|
215
|
+
options: [
|
|
216
|
+
option("enter", "Enter it", "Type your working title.", { placeholder: "Working title" }),
|
|
217
|
+
option("propose", "Propose three titles from my topic", "The methodologist suggests three titles after design starts.", { recommended: true }),
|
|
218
|
+
],
|
|
219
|
+
}),
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
id: "topic",
|
|
223
|
+
round: 3,
|
|
224
|
+
textRequired: ["enter"],
|
|
225
|
+
build: () => ({
|
|
226
|
+
id: "topic",
|
|
227
|
+
header: "Topic",
|
|
228
|
+
question: "Topic and problem in a few sentences",
|
|
229
|
+
options: [
|
|
230
|
+
option("enter", "Enter it", "Describe the topic and the problem.", {
|
|
231
|
+
recommended: true,
|
|
232
|
+
placeholder: "Topic and problem",
|
|
233
|
+
}),
|
|
234
|
+
option("later", "Decide later", "You must provide it before the design phase completes."),
|
|
235
|
+
],
|
|
236
|
+
}),
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
id: "objective",
|
|
240
|
+
round: 3,
|
|
241
|
+
textRequired: ["enter"],
|
|
242
|
+
build: () => ({
|
|
243
|
+
id: "objective",
|
|
244
|
+
header: "General objective",
|
|
245
|
+
question: "General objective",
|
|
246
|
+
options: [
|
|
247
|
+
option("enter", "Enter it", "Type your general objective.", {
|
|
248
|
+
placeholder: "General objective",
|
|
249
|
+
}),
|
|
250
|
+
option("draft", "Draft it with the methodologist", "The methodologist drafts it from your topic.", { recommended: true }),
|
|
251
|
+
],
|
|
252
|
+
}),
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
id: "justification",
|
|
256
|
+
round: 3,
|
|
257
|
+
textRequired: ["enter"],
|
|
258
|
+
build: () => ({
|
|
259
|
+
id: "justification",
|
|
260
|
+
header: "Justification",
|
|
261
|
+
question: "Justification",
|
|
262
|
+
options: [
|
|
263
|
+
option("enter", "Enter it", "Type your justification.", { placeholder: "Justification" }),
|
|
264
|
+
option("draft", "Draft it with the methodologist", "The methodologist drafts it from your topic.", { recommended: true }),
|
|
265
|
+
],
|
|
266
|
+
}),
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
id: "paper",
|
|
270
|
+
round: 4,
|
|
271
|
+
build: ({ answers }) => {
|
|
272
|
+
const letter = defaultPaper(answers) === "letter";
|
|
273
|
+
return {
|
|
274
|
+
id: "paper",
|
|
275
|
+
header: "Paper",
|
|
276
|
+
question: "Paper size",
|
|
277
|
+
options: [
|
|
278
|
+
option("letter", "Letter", "US Letter; usual in Colombia and the United States.", {
|
|
279
|
+
recommended: letter,
|
|
280
|
+
}),
|
|
281
|
+
option("a4", "A4", "ISO A4.", { recommended: !letter }),
|
|
282
|
+
],
|
|
283
|
+
};
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
id: "palette",
|
|
288
|
+
round: 4,
|
|
289
|
+
build: () => ({
|
|
290
|
+
id: "palette",
|
|
291
|
+
header: "Palette",
|
|
292
|
+
question: "Chart palette",
|
|
293
|
+
options: [
|
|
294
|
+
option("okabe-ito", "Okabe-Ito", "Color-blind safe default.", { recommended: true }),
|
|
295
|
+
option("tol-bright", "Paul Tol Bright", "Color-blind safe, vivid."),
|
|
296
|
+
option("tol-muted", "Paul Tol Muted", "Best for many categories."),
|
|
297
|
+
option("tol-high-contrast", "Grayscale-safe high contrast", "Survives black-and-white print; at most three series."),
|
|
298
|
+
],
|
|
299
|
+
}),
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
id: "fontProfile",
|
|
303
|
+
round: 4,
|
|
304
|
+
build: () => ({
|
|
305
|
+
id: "fontProfile",
|
|
306
|
+
header: "Typeface",
|
|
307
|
+
question: "Typeface",
|
|
308
|
+
options: [
|
|
309
|
+
option("serif", "Serif", "Classic body text.", { recommended: true }),
|
|
310
|
+
option("sans", "Sans", "Modern body text."),
|
|
311
|
+
option("institutional", "Institutional", "Fonts provided in thesis/fonts/."),
|
|
312
|
+
],
|
|
313
|
+
}),
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
id: "aiDeclaration",
|
|
317
|
+
round: 4,
|
|
318
|
+
build: () => ({
|
|
319
|
+
id: "aiDeclaration",
|
|
320
|
+
header: "AI declaration",
|
|
321
|
+
question: "AI-use declaration",
|
|
322
|
+
options: [
|
|
323
|
+
option("auto", "Follow the policy", "Include the declaration when the policy requires it.", { recommended: true }),
|
|
324
|
+
option("always", "Always include", "Include the declaration regardless of policy."),
|
|
325
|
+
option("never", "Never include", "Rejected at build time if the policy requires one."),
|
|
326
|
+
],
|
|
327
|
+
}),
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
id: "icontecFont",
|
|
331
|
+
round: 5,
|
|
332
|
+
textRequired: ["other"],
|
|
333
|
+
validateText: (_option, text) => /^[A-Za-z0-9][A-Za-z0-9 .-]{0,59}$/.test(text)
|
|
334
|
+
? undefined
|
|
335
|
+
: "use a font family name (letters, digits, spaces)",
|
|
336
|
+
build: () => ({
|
|
337
|
+
id: "icontecFont",
|
|
338
|
+
header: "ICONTEC font",
|
|
339
|
+
question: "Which body font does your program require? The 2022 guides disagree, so there is no default.",
|
|
340
|
+
options: [
|
|
341
|
+
option("arial", "Arial", "Recommended by one 2022 guide (Pascual Bravo)."),
|
|
342
|
+
option("times", "Times New Roman", "Used by another 2022 guide (EAFIT)."),
|
|
343
|
+
option("other", "Another font", "Enter the family name.", {
|
|
344
|
+
placeholder: "Font family",
|
|
345
|
+
}),
|
|
346
|
+
],
|
|
347
|
+
}),
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
id: "icontecSpacing",
|
|
351
|
+
round: 5,
|
|
352
|
+
build: () => ({
|
|
353
|
+
id: "icontecSpacing",
|
|
354
|
+
header: "ICONTEC spacing",
|
|
355
|
+
question: "Which body line spacing does your program require? The 2022 guides disagree, so there is no default.",
|
|
356
|
+
options: [
|
|
357
|
+
option("1", "Single (1.0)", "Single line spacing."),
|
|
358
|
+
option("1.5", "One and a half (1.5)", "One-and-a-half line spacing."),
|
|
359
|
+
],
|
|
360
|
+
}),
|
|
361
|
+
},
|
|
362
|
+
];
|
|
363
|
+
const specById = new Map(specs.map((spec) => [spec.id, spec]));
|
|
364
|
+
function recommendedApproach(answers) {
|
|
365
|
+
const domain = answers.domain;
|
|
366
|
+
if (domain === "computer_science")
|
|
367
|
+
return "design_science";
|
|
368
|
+
if (domain === "health_sciences")
|
|
369
|
+
return "quantitative";
|
|
370
|
+
return "mixed";
|
|
371
|
+
}
|
|
372
|
+
function defaultPaper(answers) {
|
|
373
|
+
const country = answers.country === "CO" ? "CO" : (answers["country:text"] ?? "").toUpperCase();
|
|
374
|
+
return country === "CO" || country === "US" ? "letter" : "a4";
|
|
375
|
+
}
|
|
376
|
+
function domainFromText(text) {
|
|
377
|
+
const value = slug(text);
|
|
378
|
+
return /^[a-z][a-z0-9_]{1,40}$/.test(value) ? value : undefined;
|
|
379
|
+
}
|
|
380
|
+
export function parseInstitution(text) {
|
|
381
|
+
const parts = (text.includes(";") ? text.split(";") : text.split(","))
|
|
382
|
+
.map((part) => part.trim())
|
|
383
|
+
.filter(Boolean);
|
|
384
|
+
const [name, faculty, program, city] = parts;
|
|
385
|
+
if (!name || parts.length > 4)
|
|
386
|
+
return undefined;
|
|
387
|
+
return { name, faculty: faculty ?? null, program: program ?? null, city: city ?? null };
|
|
388
|
+
}
|
|
389
|
+
/** Whether an answer for this question is already known. */
|
|
390
|
+
function isAnswered(answers, id) {
|
|
391
|
+
return answers[id] !== undefined;
|
|
392
|
+
}
|
|
393
|
+
/** Questions of one round that are still unanswered (skips answered ones). */
|
|
394
|
+
export function buildRound(round, answers, hint) {
|
|
395
|
+
return specs
|
|
396
|
+
.filter((spec) => spec.round === round && !isAnswered(answers, spec.id))
|
|
397
|
+
.map((spec) => spec.build({ hint, answers }));
|
|
398
|
+
}
|
|
399
|
+
export function roundIds(round) {
|
|
400
|
+
return specs.filter((spec) => spec.round === round).map((spec) => spec.id);
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Validate raw answers against the option domain of the given questions. Free text travels under
|
|
404
|
+
* `<id>:text`. For questions that offer an `other` option, an unknown value is read as that
|
|
405
|
+
* option's text, so `language=pt-BR` works.
|
|
406
|
+
*/
|
|
407
|
+
export function acceptAnswers(questions, input, hint) {
|
|
408
|
+
const accepted = {};
|
|
409
|
+
const errors = [];
|
|
410
|
+
const known = new Set(questions.map((question) => question.id));
|
|
411
|
+
for (const key of Object.keys(input)) {
|
|
412
|
+
const id = key.endsWith(":text") ? key.slice(0, -5) : key;
|
|
413
|
+
if (!known.has(id))
|
|
414
|
+
errors.push(`Unknown question id: ${id}`);
|
|
415
|
+
}
|
|
416
|
+
for (const question of questions) {
|
|
417
|
+
let value = input[question.id];
|
|
418
|
+
let text = input[`${question.id}:text`];
|
|
419
|
+
if (value === undefined) {
|
|
420
|
+
if (text !== undefined)
|
|
421
|
+
errors.push(`${question.id}:text was given without ${question.id}`);
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
const spec = specById.get(question.id);
|
|
425
|
+
const values = question.options.map((entry) => entry.value);
|
|
426
|
+
if (!values.includes(value)) {
|
|
427
|
+
const upper = value.toUpperCase();
|
|
428
|
+
if (question.id === "country" && values.includes(upper)) {
|
|
429
|
+
value = upper;
|
|
430
|
+
}
|
|
431
|
+
else if (values.includes("other") && text === undefined) {
|
|
432
|
+
text = value;
|
|
433
|
+
value = "other";
|
|
434
|
+
}
|
|
435
|
+
else {
|
|
436
|
+
errors.push(`${question.id}: "${value}" is not allowed. Allowed values: ${values.join(", ")}`);
|
|
437
|
+
continue;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
const chosen = question.options.find((entry) => entry.value === value);
|
|
441
|
+
if (text !== undefined) {
|
|
442
|
+
if (!chosen?.textInput) {
|
|
443
|
+
errors.push(`${question.id}: option "${value}" does not take free text`);
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
if (text.length > maxText || controlPattern.test(text) || !text.trim()) {
|
|
447
|
+
errors.push(`${question.id}: free text must be 1 to ${maxText} printable characters`);
|
|
448
|
+
continue;
|
|
449
|
+
}
|
|
450
|
+
text = text.trim();
|
|
451
|
+
}
|
|
452
|
+
else if (spec?.textRequired?.includes(value)) {
|
|
453
|
+
errors.push(`${question.id}: option "${value}" needs free text (${question.id}:text=...)`);
|
|
454
|
+
continue;
|
|
455
|
+
}
|
|
456
|
+
if (text !== undefined) {
|
|
457
|
+
const problem = spec?.validateText?.(value, text);
|
|
458
|
+
if (problem) {
|
|
459
|
+
errors.push(`${question.id}: ${problem}`);
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
if (question.id === "language" && value === "conversation") {
|
|
464
|
+
accepted.language = "other";
|
|
465
|
+
accepted["language:text"] = hint;
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
accepted[question.id] = value;
|
|
469
|
+
if (text !== undefined)
|
|
470
|
+
accepted[`${question.id}:text`] = text;
|
|
471
|
+
}
|
|
472
|
+
return { accepted, errors };
|
|
473
|
+
}
|
|
474
|
+
/** Convert an `api.ui.askQuestions` result into the flat string map used for validation. */
|
|
475
|
+
export function flattenAnswers(result) {
|
|
476
|
+
const flat = {};
|
|
477
|
+
for (const [key, value] of Object.entries(result)) {
|
|
478
|
+
const first = Array.isArray(value) ? value[0] : value;
|
|
479
|
+
if (typeof first === "string" && first !== "")
|
|
480
|
+
flat[key] = first;
|
|
481
|
+
}
|
|
482
|
+
return flat;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Parse `/thesis:answer` text: a JSON object, or `id=value` pairs separated by whitespace or
|
|
486
|
+
* newlines (values run until the next `id=` token). `id:text=...` carries free text.
|
|
487
|
+
*/
|
|
488
|
+
export function parseAnswerText(text, ids) {
|
|
489
|
+
const source = text.trim().replace(/^--\s*/, "");
|
|
490
|
+
if (!source)
|
|
491
|
+
throw new Error("No answers were given");
|
|
492
|
+
if (source.startsWith("{")) {
|
|
493
|
+
let parsed;
|
|
494
|
+
try {
|
|
495
|
+
parsed = JSON.parse(source);
|
|
496
|
+
}
|
|
497
|
+
catch {
|
|
498
|
+
throw new Error("Answers look like JSON but could not be parsed");
|
|
499
|
+
}
|
|
500
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
501
|
+
throw new Error("JSON answers must be an object of id to value");
|
|
502
|
+
}
|
|
503
|
+
const flat = {};
|
|
504
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
505
|
+
if (typeof value !== "string")
|
|
506
|
+
throw new Error(`JSON answer for ${key} must be a string`);
|
|
507
|
+
flat[key] = value;
|
|
508
|
+
}
|
|
509
|
+
return flat;
|
|
510
|
+
}
|
|
511
|
+
const names = ids
|
|
512
|
+
.flatMap((id) => [id, `${id}:text`])
|
|
513
|
+
.map((name) => name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
514
|
+
const token = new RegExp(`(?:^|\\s)(${names.join("|")})=`, "g");
|
|
515
|
+
const marks = [...source.matchAll(token)];
|
|
516
|
+
if (marks.length === 0) {
|
|
517
|
+
throw new Error(`Expected id=value pairs for: ${ids.join(", ")}`);
|
|
518
|
+
}
|
|
519
|
+
const first = marks[0];
|
|
520
|
+
if (source.slice(0, first.index).trim()) {
|
|
521
|
+
throw new Error(`Unrecognized text before the first answer: ${source.slice(0, first.index).trim().slice(0, 40)}`);
|
|
522
|
+
}
|
|
523
|
+
const flat = {};
|
|
524
|
+
marks.forEach((mark, index) => {
|
|
525
|
+
const start = (mark.index ?? 0) + mark[0].length;
|
|
526
|
+
const end = marks[index + 1]?.index ?? source.length;
|
|
527
|
+
flat[mark[1]] = source.slice(start, end).trim();
|
|
528
|
+
});
|
|
529
|
+
return flat;
|
|
530
|
+
}
|
|
531
|
+
export function renderPending(pending) {
|
|
532
|
+
const lines = [
|
|
533
|
+
pending.round === presentationRound
|
|
534
|
+
? "Thesis presentation settings (round 4)"
|
|
535
|
+
: `Thesis interview, round ${pending.round} of ${defaultRounds.length}: ${roundTitles[pending.round] ?? ""}`,
|
|
536
|
+
"Answer with /thesis:answer using id=value pairs (separated by spaces or new lines), or one JSON object.",
|
|
537
|
+
"Free text goes in <id>:text=... for options marked (text).",
|
|
538
|
+
"",
|
|
539
|
+
];
|
|
540
|
+
pending.questions.forEach((question, index) => {
|
|
541
|
+
lines.push(`${index + 1}. ${question.id}: ${question.question}`);
|
|
542
|
+
for (const entry of question.options) {
|
|
543
|
+
const flags = [entry.recommended ? "recommended" : "", entry.textInput ? "text" : ""].filter(Boolean);
|
|
544
|
+
lines.push(` - ${entry.value}: ${entry.label}${flags.length ? ` (${flags.join(", ")})` : ""}${entry.description ? ` - ${entry.description}` : ""}`);
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
const example = pending.questions
|
|
548
|
+
.map((question) => {
|
|
549
|
+
const pick = question.options.find((entry) => entry.recommended) ?? question.options[0];
|
|
550
|
+
return `${question.id}=${pick?.value}${pick?.textInput && pick.value === "enter" ? ` ${question.id}:text=...` : ""}`;
|
|
551
|
+
})
|
|
552
|
+
.join(" ");
|
|
553
|
+
lines.push("", `Example: /thesis:answer ${example}`);
|
|
554
|
+
return lines.join("\n");
|
|
555
|
+
}
|
|
556
|
+
/** Seed answers from the raw fields of a thesis.yaml that already exists. */
|
|
557
|
+
export function seedAnswersFromRaw(raw) {
|
|
558
|
+
const answers = {};
|
|
559
|
+
const record = (value) => typeof value === "object" && value !== null && !Array.isArray(value)
|
|
560
|
+
? value
|
|
561
|
+
: {};
|
|
562
|
+
if (typeof raw.language === "string") {
|
|
563
|
+
answers.language = "other";
|
|
564
|
+
answers["language:text"] = raw.language;
|
|
565
|
+
}
|
|
566
|
+
if (typeof raw.workType === "string")
|
|
567
|
+
answers.workType = raw.workType;
|
|
568
|
+
const institution = record(raw.institution);
|
|
569
|
+
if (typeof institution.country === "string") {
|
|
570
|
+
answers.country = institution.country === "CO" ? "CO" : "other";
|
|
571
|
+
if (institution.country !== "CO")
|
|
572
|
+
answers["country:text"] = institution.country;
|
|
573
|
+
}
|
|
574
|
+
if (raw.secondaryAbstractLanguage !== undefined) {
|
|
575
|
+
if (raw.secondaryAbstractLanguage === null)
|
|
576
|
+
answers.secondaryAbstract = "none";
|
|
577
|
+
else if (typeof raw.secondaryAbstractLanguage === "string") {
|
|
578
|
+
answers.secondaryAbstract = "other";
|
|
579
|
+
answers["secondaryAbstract:text"] = raw.secondaryAbstractLanguage;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
if (typeof institution.name === "string" && institution.name) {
|
|
583
|
+
answers.institution = "enter";
|
|
584
|
+
answers["institution:text"] = [
|
|
585
|
+
institution.name,
|
|
586
|
+
institution.faculty,
|
|
587
|
+
institution.program,
|
|
588
|
+
institution.city,
|
|
589
|
+
]
|
|
590
|
+
.filter((part) => typeof part === "string" && part !== "")
|
|
591
|
+
.join("; ");
|
|
592
|
+
}
|
|
593
|
+
if (typeof raw.citationStyle === "string") {
|
|
594
|
+
answers.citationStyle = ["auto", "apa-7", "ieee", "icontec-ntc1486-2022"].includes(raw.citationStyle)
|
|
595
|
+
? raw.citationStyle
|
|
596
|
+
: "auto";
|
|
597
|
+
}
|
|
598
|
+
const domain = record(raw.domain);
|
|
599
|
+
if (typeof domain.primary === "string" && domain.primary !== "undetermined") {
|
|
600
|
+
answers.domain = "social_sciences";
|
|
601
|
+
answers["domain:text"] = domain.primary;
|
|
602
|
+
}
|
|
603
|
+
if (typeof raw.approach === "string") {
|
|
604
|
+
answers.approach =
|
|
605
|
+
raw.approach === "quantitative" || raw.approach === "qualitative" ? raw.approach : "mixed";
|
|
606
|
+
if (answers.approach === "mixed" && raw.approach !== "mixed")
|
|
607
|
+
answers["approach:text"] = raw.approach;
|
|
608
|
+
}
|
|
609
|
+
if (typeof raw.title === "string" && raw.title) {
|
|
610
|
+
answers.title = "enter";
|
|
611
|
+
answers["title:text"] = raw.title;
|
|
612
|
+
}
|
|
613
|
+
const presentation = record(raw.presentation);
|
|
614
|
+
for (const key of ["paper", "fontProfile", "palette"]) {
|
|
615
|
+
if (typeof presentation[key] === "string")
|
|
616
|
+
answers[key] = presentation[key];
|
|
617
|
+
}
|
|
618
|
+
if (answers.palette && !paletteNames.includes(answers.palette))
|
|
619
|
+
delete answers.palette;
|
|
620
|
+
if (answers.palette === "viridis" || answers.palette === "cividis")
|
|
621
|
+
delete answers.palette;
|
|
622
|
+
if (typeof presentation.bodyFont === "string") {
|
|
623
|
+
if (presentation.bodyFont === "Arial")
|
|
624
|
+
answers.icontecFont = "arial";
|
|
625
|
+
else if (presentation.bodyFont === "Times New Roman")
|
|
626
|
+
answers.icontecFont = "times";
|
|
627
|
+
else {
|
|
628
|
+
answers.icontecFont = "other";
|
|
629
|
+
answers["icontecFont:text"] = presentation.bodyFont;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
if (presentation.lineSpacing === 1 || presentation.lineSpacing === 1.5)
|
|
633
|
+
answers.icontecSpacing = String(presentation.lineSpacing);
|
|
634
|
+
const aiUse = record(raw.aiUse);
|
|
635
|
+
if (typeof aiUse.declaration === "string")
|
|
636
|
+
answers.aiDeclaration = aiUse.declaration;
|
|
637
|
+
return answers;
|
|
638
|
+
}
|
|
639
|
+
function resolvedLanguage(answers, country, hint) {
|
|
640
|
+
const value = answers.language;
|
|
641
|
+
if (value === "en")
|
|
642
|
+
return "en";
|
|
643
|
+
if (value === "es")
|
|
644
|
+
return country && /^[A-Z]{2}$/.test(country) ? `es-${country}` : "es";
|
|
645
|
+
if (value === "other")
|
|
646
|
+
return answers["language:text"] ?? hint;
|
|
647
|
+
return undefined;
|
|
648
|
+
}
|
|
649
|
+
export function intakeCountry(answers) {
|
|
650
|
+
if (answers.country === "CO")
|
|
651
|
+
return "CO";
|
|
652
|
+
if (answers.country === "other")
|
|
653
|
+
return answers["country:text"]?.toUpperCase();
|
|
654
|
+
return undefined;
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Overlay answered questions on an existing raw brief (or nothing) and produce the full
|
|
658
|
+
* thesis.yaml. Fields no answer touches keep the user's values.
|
|
659
|
+
*/
|
|
660
|
+
export function buildBriefText(answers, existing, options) {
|
|
661
|
+
const merged = { ...(existing ?? {}) };
|
|
662
|
+
const nested = (key) => {
|
|
663
|
+
const current = merged[key];
|
|
664
|
+
const copy = typeof current === "object" && current !== null && !Array.isArray(current)
|
|
665
|
+
? { ...current }
|
|
666
|
+
: {};
|
|
667
|
+
merged[key] = copy;
|
|
668
|
+
return copy;
|
|
669
|
+
};
|
|
670
|
+
merged.schemaVersion = 1;
|
|
671
|
+
const institution = nested("institution");
|
|
672
|
+
const country = intakeCountry(answers);
|
|
673
|
+
if (country)
|
|
674
|
+
institution.country = country;
|
|
675
|
+
const language = resolvedLanguage(answers, country ?? institution.country, options.hint);
|
|
676
|
+
if (language)
|
|
677
|
+
merged.language = language;
|
|
678
|
+
if (answers.workType)
|
|
679
|
+
merged.workType = answers.workType;
|
|
680
|
+
switch (answers.secondaryAbstract) {
|
|
681
|
+
case "en":
|
|
682
|
+
merged.secondaryAbstractLanguage =
|
|
683
|
+
primaryLanguage(String(merged.language ?? "")) === "en" ? null : "en";
|
|
684
|
+
break;
|
|
685
|
+
case "none":
|
|
686
|
+
merged.secondaryAbstractLanguage = null;
|
|
687
|
+
break;
|
|
688
|
+
case "other":
|
|
689
|
+
merged.secondaryAbstractLanguage = answers["secondaryAbstract:text"];
|
|
690
|
+
break;
|
|
691
|
+
}
|
|
692
|
+
if (answers.institution === "enter" && answers["institution:text"]) {
|
|
693
|
+
const parsed = parseInstitution(answers["institution:text"]);
|
|
694
|
+
if (parsed)
|
|
695
|
+
Object.assign(institution, parsed);
|
|
696
|
+
}
|
|
697
|
+
if (answers.citationStyle)
|
|
698
|
+
merged.citationStyle = answers.citationStyle;
|
|
699
|
+
if (answers.domain) {
|
|
700
|
+
const domain = nested("domain");
|
|
701
|
+
if (answers.domain === "detected")
|
|
702
|
+
domain.primary = "undetermined";
|
|
703
|
+
else if (answers.domain === "social_sciences" && answers["domain:text"]) {
|
|
704
|
+
domain.primary = domainFromText(answers["domain:text"]) ?? "social_sciences";
|
|
705
|
+
}
|
|
706
|
+
else
|
|
707
|
+
domain.primary = answers.domain;
|
|
708
|
+
domain.secondary ??= [];
|
|
709
|
+
}
|
|
710
|
+
if (answers.approach) {
|
|
711
|
+
const text = answers["approach:text"];
|
|
712
|
+
if (answers.approach === "recommended")
|
|
713
|
+
merged.approach = recommendedApproach(answers);
|
|
714
|
+
else if (answers.approach === "mixed" && text)
|
|
715
|
+
merged.approach = text;
|
|
716
|
+
else
|
|
717
|
+
merged.approach = answers.approach;
|
|
718
|
+
}
|
|
719
|
+
if (answers.title === "enter" && answers["title:text"])
|
|
720
|
+
merged.title = answers["title:text"];
|
|
721
|
+
const presentation = nested("presentation");
|
|
722
|
+
if (answers.paper)
|
|
723
|
+
presentation.paper = answers.paper;
|
|
724
|
+
else
|
|
725
|
+
presentation.paper ??= defaultPaper(answers);
|
|
726
|
+
if (answers.palette)
|
|
727
|
+
presentation.palette = answers.palette;
|
|
728
|
+
if (answers.fontProfile)
|
|
729
|
+
presentation.fontProfile = answers.fontProfile;
|
|
730
|
+
if (answers.icontecFont === "arial")
|
|
731
|
+
presentation.bodyFont = "Arial";
|
|
732
|
+
else if (answers.icontecFont === "times")
|
|
733
|
+
presentation.bodyFont = "Times New Roman";
|
|
734
|
+
else if (answers.icontecFont === "other" && answers["icontecFont:text"])
|
|
735
|
+
presentation.bodyFont = answers["icontecFont:text"];
|
|
736
|
+
if (answers.icontecSpacing)
|
|
737
|
+
presentation.lineSpacing = Number(answers.icontecSpacing);
|
|
738
|
+
if (answers.aiDeclaration)
|
|
739
|
+
nested("aiUse").declaration = answers.aiDeclaration;
|
|
740
|
+
merged.year ??= options.year;
|
|
741
|
+
// Re-validate through the same loader the checks use, so a bad pre-existing file is not rewritten.
|
|
742
|
+
const probe = loadBrief(JSON.stringify(merged));
|
|
743
|
+
const errors = probe.issues
|
|
744
|
+
.filter((issue) => issue.severity === "error")
|
|
745
|
+
.map((issue) => `${issue.path || "thesis.yaml"}: ${issue.message}`);
|
|
746
|
+
if (!probe.brief)
|
|
747
|
+
return { errors };
|
|
748
|
+
const brief = applyBriefDefaults(probe.brief);
|
|
749
|
+
return { text: stringifyBrief(brief), brief, errors: [] };
|
|
750
|
+
}
|
|
751
|
+
/** The free-text research intent collected in round 3, for the methodologist. */
|
|
752
|
+
export function intakeIntent(answers) {
|
|
753
|
+
const pick = (id, enter) => answers[id] === enter ? (answers[`${id}:text`] ?? null) : null;
|
|
754
|
+
return {
|
|
755
|
+
title: pick("title", "enter"),
|
|
756
|
+
topic: pick("topic", "enter"),
|
|
757
|
+
objective: pick("objective", "enter"),
|
|
758
|
+
justification: pick("justification", "enter"),
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
export function hintFromEnvironment(env) {
|
|
762
|
+
const raw = env.LC_ALL || env.LC_MESSAGES || env.LANG || "";
|
|
763
|
+
const match = /^([a-z]{2,3})(?:[_-]([A-Za-z]{2}))?/.exec(raw);
|
|
764
|
+
if (!match || match[1] === "C" || raw === "C" || raw === "POSIX")
|
|
765
|
+
return "en";
|
|
766
|
+
const tag = match[2] ? `${match[1]}-${match[2].toUpperCase()}` : match[1];
|
|
767
|
+
return isValidLanguageTag(tag) ? tag : "en";
|
|
768
|
+
}
|
|
769
|
+
export function isRoundComplete(state, round) {
|
|
770
|
+
return state.intake.completedRounds.includes(round);
|
|
771
|
+
}
|
|
772
|
+
//# sourceMappingURL=intake.js.map
|