import { type GraderSpec } from "../../eval/gradersJson/schema.js"; /** Every answer typed, keyed by question name. Never pruned: an answer to * a question that is hidden stays, so changing a choice back shows it. */ export type Answers = Record; export type GraderDraft = { answers: Answers; }; export type ChoiceOption = { value: string; label: string; }; export type QuestionInput = { kind: "text"; /** Ctrl+E opens `$EDITOR` on it. */ long: boolean; /** Shown in place of the value while it is empty. */ help: string; /** Asked once per non-empty answer, plus one more. */ repeat: boolean; } | { kind: "choice"; options: ChoiceOption[]; /** Help shown while unanswered; null when the first option is the default. */ unset: string | null; }; /** How an answer becomes a field of the `graders.json` object. */ export type Output = "text" | "number" | "yesNo" | "list" | "none"; export type QuestionSpec = { name: string; label: string; input: QuestionInput; output: Output; /** Asked only when this holds of the answers so far. */ when?: (answers: Answers) => boolean; /** For a `none` output: the answer to show when a saved spec is opened, * read from the fields the question decided. */ derive?: (spec: Record) => string; }; export declare const YES_NO: ChoiceOption[]; export declare const PICK_HELP = "pick with \u2190 \u2192"; /** The footer for a grader whose kind is not picked yet. */ export declare const KIND_NEEDED = "pick what to check with \u2190 \u2192"; export declare const KIND_QUESTION: QuestionSpec; export declare const KIND_QUESTIONS: Record; export declare const TAIL_QUESTIONS: QuestionSpec[]; export declare function kindOf(draft: GraderDraft): GraderSpec["kind"] | null; /** The answer, or for a choice that defaults, its first option. */ export declare function choiceValue(answers: Answers, question: QuestionSpec): string; /** The option label for a choice value; the value itself for text. */ export declare function labelOf(question: QuestionSpec, value: string): string; /** One row per question the draft shows. A repeating question becomes one * row per non-empty answer plus one empty row, named `name.0`, `name.1`, * and labelled `label 1`, `label 2`. */ export declare function questionsFor(draft: GraderDraft): QuestionSpec[]; /** The row a parser problem about `field` is shown on: the question of * that name, or for a repeating question's list key (`points`) its first * row (`point.0`); null when no shown row holds the field. */ export declare function questionForField(draft: GraderDraft, field: string): QuestionSpec | null; /** The object `graders.json` holds for a draft: the answer of every shown * question, converted by its output. Nothing a hidden question answered * is written. The kind is always written, empty when unpicked, so the * parser's refusal names it. */ export declare function specObjectFor(draft: GraderDraft): Record; /** The draft that shows a saved spec: every field read back through the * same table, so `specObjectFor(draftFromSpec(spec))` is the spec with * any `false` left out. */ export declare function draftFromSpec(spec: GraderSpec): GraderDraft; export declare function autoFill(answers: Answers): Answers;