/**
 * Das Handbuch der Anwendung – Inhalt, Tastenlisten und Aufbau an einer Stelle.
 *
 * ## Warum die Hilfe ein Datenmodul ist und keine JSX-Seite
 *
 * Drei Gründe, in dieser Reihenfolge:
 *
 * 1. **Sie darf nicht auslaufen.** Ein Handbuch, das etwas anderes sagt als
 *    die Anwendung, ist schlimmer als keines – es sagt mit der Autorität
 *    eines Handbuchs etwas Falsches. Deshalb stehen Zahlen nicht als Text
 *    darin, sondern kommen aus derselben Konstante wie die Oberfläche:
 *    `SITZUNGSUMFANG`, `ANZEIGEGROESSEN`, `PRUEFUNGSPROFILE`, `KONTAKT`. Wer
 *    den Sitzungsumfang ändert, ändert das Handbuch mit, ohne es zu wissen.
 * 2. **Sie ist prüfbar.** Als Datenstruktur lässt sich zusichern, dass jedes
 *    Kapitel eine Kennung und einen Titel hat, dass keine Kennung doppelt
 *    vorkommt und dass das Inhaltsverzeichnis auf vorhandene Kapitel zeigt.
 * 3. **Sie ist da, wenn es klemmt.** Kein IPC-Kanal, keine Datei auf der
 *    Platte, kein Nachladen aus dem Netz. Dieselbe Überlegung wie bei
 *    `kontakt.ts`: Hilfe, die von einem funktionierenden Kanal abhängt, ist
 *    genau dann weg, wenn man sie braucht.
 *
 * ## Was hier NICHT steht
 *
 * Kein Fachwissen zum Waffenrecht. Das steht in den Erklärungen zu den Fragen
 * und im Glossar. Dieses Handbuch erklärt ausschließlich die **Bedienung**
 * dieser Anwendung – so verlangen es Prüfschritt 3.2.6 und Szenario S10 des
 * Barrierefreiheits-Prüfplans.
 */

import { ANZEIGEGROESSEN } from './ansicht';
import { KONTAKT } from './kontakt';
import { BEWERTUNG_BEZEICHNUNG } from './lernstand';
import { ANHEBUNG_AB_TAGEN, SITZUNGSUMFANG } from './lernplan';
import { HARTNAECKIG_AB_TAGEN } from './hartnaeckig';
import { PRUEFUNGSPROFILE } from './pruefung';
import { STUFE_WORT } from './reife';

// ─── Tastenlisten ────────────────────────────────────────────────────────

/**
 * Wie mehrere Tasten zueinander stehen.
 *
 * Das gehört ins Modell und nicht in die Darstellung: „Strg und Plus“ heißt
 * gleichzeitig, „1 bis 8“ heißt irgendeine davon. Wer den Unterschied nur
 * über ein Leerzeichen zwischen zwei `<kbd>` andeutet, sagt ihn nicht.
 */
export type Tastenverbindung = 'plus' | 'bis' | 'oder';

export interface Tastenzeile {
  /** Die Tasten in der Reihenfolge, in der sie genannt werden. */
  readonly tasten: readonly string[];
  /** Nur nötig, wenn mehr als eine Taste genannt wird. */
  readonly verbindung?: Tastenverbindung;
  /** Was geschieht, wenn man sie drückt. */
  readonly wirkung: string;
}

/**
 * Die Zeichenkürzel der Lernsitzung – abschaltbar (WCAG 2.1.4).
 *
 * Einzelne Zeichen als Kürzel sind heikel: Sie lösen bei Spracheingabe und
 * bei unabsichtlichen Anschlägen aus. WCAG 2.1.4 verlangt deshalb, dass sie
 * sich abschalten lassen; läuft ein Bildschirmleser, sind sie von vornherein
 * aus, weil die Ziffern in dessen Lesemodus für die Überschriftennavigation
 * belegt sind.
 *
 * Diese Liste ist die einzige Quelle: `KuerzelHilfe` in den Einstellungen und
 * das Kapitel „Bedienung ohne Maus“ im Handbuch lesen beide von hier. Vorher
 * standen die Kürzel nur als JSX in `KuerzelHilfe` – ein zweiter Ort hätte
 * ihnen beim nächsten neuen Kürzel widersprochen.
 */
export const TASTENKUERZEL: readonly Tastenzeile[] = Object.freeze([
  Object.freeze({
    tasten: Object.freeze(['1', '8']),
    verbindung: 'bis' as const,
    wirkung: 'Antwortmöglichkeit an dieser Stelle wählen oder abwählen',
  }),
  Object.freeze({
    tasten: Object.freeze(['Eingabe']),
    wirkung: 'Antwort bestätigen, danach zur nächsten Frage',
  }),
  Object.freeze({
    tasten: Object.freeze(['M']),
    wirkung: 'Frage merken oder das Merken aufheben',
  }),
]);

/**
 * Die Tasten, die immer wirken – unabhängig von jeder Einstellung.
 *
 * Sie sind nicht abschaltbar und müssen es auch nicht sein: Es sind entweder
 * Standardtasten der Plattform (Tab, Pfeile, Leertaste) oder Griffe mit
 * Zusatztaste, die WCAG 2.1.4 ausdrücklich ausnimmt.
 */
export const TASTATURBEDIENUNG: readonly Tastenzeile[] = Object.freeze([
  Object.freeze({
    tasten: Object.freeze(['Tab']),
    wirkung: 'Zum nächsten Bedienelement; zusammen mit der Umschalttaste zurück',
  }),
  Object.freeze({
    tasten: Object.freeze(['Pfeiltasten']),
    wirkung: 'Innerhalb einer Gruppe wechseln – etwa zwischen den Antwortmöglichkeiten',
  }),
  Object.freeze({
    tasten: Object.freeze(['Leertaste']),
    wirkung: 'Kontrollkästchen setzen oder lösen, Schaltfläche auslösen',
  }),
  Object.freeze({
    tasten: Object.freeze(['Eingabe']),
    wirkung: 'Schaltfläche auslösen',
  }),
  Object.freeze({
    tasten: Object.freeze(['F1']),
    wirkung: 'Diese Hilfe öffnen – aus jeder Ansicht, auch mitten in einer Simulation',
  }),
  Object.freeze({
    tasten: Object.freeze(['Esc']),
    wirkung: 'Die Hilfe wieder schließen',
  }),
  Object.freeze({
    tasten: Object.freeze(['Strg', 'Plus']),
    verbindung: 'plus' as const,
    wirkung: 'Anzeige eine Stufe größer',
  }),
  Object.freeze({
    tasten: Object.freeze(['Strg', 'Minus']),
    verbindung: 'plus' as const,
    wirkung: 'Anzeige eine Stufe kleiner',
  }),
  Object.freeze({
    tasten: Object.freeze(['Strg', '0']),
    verbindung: 'plus' as const,
    wirkung: 'Zurück auf Normalgröße',
  }),
]);

// ─── Aufbau eines Kapitels ───────────────────────────────────────────────

/**
 * Ein Baustein innerhalb eines Kapitels.
 *
 * Bewusst wenige Arten und ausschließlich reiner Text: In den Zeichenketten
 * steht kein Markup, und nichts davon wird über `dangerouslySetInnerHTML`
 * gerendert. Was hier nicht vorgesehen ist, kann auch nicht durch die
 * Hintertür in die Oberfläche geraten.
 */
export type Hilfeblock =
  | { readonly art: 'absatz'; readonly text: string }
  /** Aufzählung ohne Reihenfolge. */
  | { readonly art: 'liste'; readonly punkte: readonly string[] }
  /** Abfolge, bei der die Reihenfolge zählt – wird als `<ol>` gezeigt. */
  | { readonly art: 'schritte'; readonly punkte: readonly string[] }
  /** Tastenliste; die Zeilen kommen aus den Konstanten oben. */
  | { readonly art: 'tasten'; readonly zeilen: readonly Tastenzeile[] };

export interface Hilfekapitel {
  /** Stabile Kennung, Ziel des Inhaltsverzeichnisses. Nicht mehr ändern. */
  readonly id: string;
  readonly titel: string;
  /** Eine Zeile, die im Inhaltsverzeichnis unter dem Titel steht. */
  readonly kurz: string;
  readonly bloecke: readonly Hilfeblock[];
}

// ─── Der Inhalt ──────────────────────────────────────────────────────────

const KLEINSTE_ANZEIGE = Math.min(...ANZEIGEGROESSEN);
const GROESSTE_ANZEIGE = Math.max(...ANZEIGEGROESSEN);

/**
 * Welches Hilfekapitel zu welcher Ansicht gehört.
 *
 * Für das kontextsensitive F1: Wer mitten in der Prüfungssimulation drückt,
 * landete bis 0.22.0 am Anfang des Handbuchs und musste das passende von elf
 * Kapiteln selbst heraussuchen – unter Zeitdruck, und für
 * Screenreader-Nutzende hieß das, das ganze Inhaltsverzeichnis durchzugehen.
 *
 * Die Tabelle steht hier und nicht in der Oberfläche, weil sie zu den
 * Kapiteln gehört: Wer ein Kapitel umbenennt, sieht die Zuordnung daneben.
 * Ansichten ohne Eintrag bekommen bewusst keines: Dort ist das
 * Inhaltsverzeichnis die richtige Antwort. Der Startbildschirm stand bis
 * Fassung 0.24.2 in dieser Gruppe; seit es „So kommen Sie durch“ gibt,
 * beantwortet ein Kapitel seine Frage, und der Verweis darunter zeigt
 * dorthin.
 *
 * Die Schlüssel sind die `art`-Werte aus `renderer/src/lernen/typen.ts`;
 * `tests/hilfe.test.ts` hält fest, dass jede genannte Kennung wirklich ein
 * Kapitel trifft.
 */
export const HILFE_ZUR_ANSICHT: Readonly<Record<string, string>> = Object.freeze({
  /* Der Startbildschirm hatte bis 0.24.2 bewusst kein Kapitel: Dort sei das
     Inhaltsverzeichnis die richtige Antwort. Das trug, solange es kein
     Kapitel gab, das die Frage des Startbildschirms beantwortet — „was tue
     ich als Nächstes“. Seit es „So kommen Sie durch“ gibt, trägt es nicht
     mehr: Wer dort F1 drückt, sucht genau diesen Text. */
  start: 'weg',
  sitzung: 'lernsitzung',
  /* Bis 0.24.2 führte das Sitzungsende nach „wiedervorlage“. Das Kapitel
     erklärt den Lernplan und kein Wort über die Anschlusswege, die am
     Sitzungsende angeboten werden — die stehen seit 0.25.0 in
     „lernsitzung“. */
  auswertung: 'lernsitzung',
  kapitelwahl: 'lernsitzung',
  pruefungswahl: 'simulation',
  pruefung: 'simulation',
  pruefungsergebnis: 'simulation',
  suche: 'suchen',
  glossar: 'suchen',
});

export const HILFE_KAPITEL: readonly Hilfekapitel[] = Object.freeze([
  Object.freeze({
    id: 'ueberblick',
    titel: 'Was diese Anwendung ist',
    kurz: 'Wozu sie da ist – und wozu nicht',
    bloecke: Object.freeze([
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Diese Anwendung bereitet auf die Sachkundeprüfung nach § 7 des Waffengesetzes vor. ' +
          'Grundlage ist der amtliche Fragenkatalog des Bundesverwaltungsamts. Welche Fassung ' +
          'eingebaut ist, steht im Fußbereich jeder Ansicht und unter „Über diese Software“.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Sie läuft vollständig auf Ihrem Rechner. Es gibt kein Konto, keine Anmeldung und ' +
          'keine Datenübertragung – auch diese Hilfe wird nicht aus dem Netz nachgeladen.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Was sie nicht ist: ein Ersatz für eine Ausbildung, und keine Rechtsberatung. Über das ' +
          'Bestehen entscheidet allein der zuständige Prüfungsausschuss. Er bestimmt auch, wie ' +
          'viele Fragen gestellt werden und wie viele davon richtig sein müssen.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Vor allem deckt sie nur einen Teil der Prüfung ab. Die Sachkundeprüfung besteht nach ' +
          '§ 2 Absatz 3 der Allgemeinen Waffengesetz-Verordnung aus einem theoretischen und ' +
          'einem praktischen Teil. Diese Anwendung übt den theoretischen: den Fragenkatalog, den ' +
          'viele Prüfungsstellen schriftlich abfragen und um mündliche Fragen ergänzen. Der ' +
          'praktische Teil verlangt die sichere Handhabung von Waffen und Munition ' +
          'einschließlich ausreichender Fertigkeiten im Schießen (§ 1 Absatz 1 Nummer 3 der ' +
          'Verordnung). Den kann keine Software vermitteln und diese auch nicht prüfen; er ' +
          'gehört in einen Lehrgang mit einer Waffe in der Hand.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Wer also alle Fragen dieser Anwendung sicher beantwortet, hat den Stoff des ' +
          'theoretischen Teils beisammen – die Prüfung bestanden hat er damit noch nicht. Wie ' +
          'der praktische Teil bei Ihrer Prüfungsstelle abläuft und was dort verlangt wird, ' +
          'erfahren Sie bei ihr selbst oder in Ihrem Lehrgang.',
      }),
    ]),
  }),

  Object.freeze({
    id: 'erste-schritte',
    titel: 'Erste Schritte',
    kurz: 'Der kürzeste Weg von hier zur ersten Frage',
    bloecke: Object.freeze([
      Object.freeze({
        art: 'schritte' as const,
        punkte: Object.freeze([
          `Auf dem Startbildschirm „Weiterlernen“ wählen. Das Programm stellt ${String(SITZUNGSUMFANG)} Fragen zusammen: zuerst, was zur Wiederholung ansteht, dann Neues.`,
          'Eine Antwort wählen und „Antwort bestätigen“ drücken. Erst danach zeigt sich, ob es richtig war – mit einer Erklärung und den Fundstellen im Gesetz. Bei einer offenen Frage schreiben Sie die Antwort selbst und drücken „Musterantwort anzeigen“.',
          'Mit „Nächste Frage“ weiter. Was Sie später noch einmal ansehen wollen, legen Sie über „Frage merken“ auf die Merkliste.',
          'Am Ende steht die Bilanz der Sitzung. Falsch beantwortete Fragen lassen sich von dort sofort wiederholen.',
          'Wenn Ihr Prüfungstermin feststeht: Tragen Sie ihn auf dem Startbildschirm unter „Ihr Lernplan“ ein. Erst dann kann das Programm sagen, wie viel Sie täglich schaffen müssen.',
        ]),
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Mehr ist für den Anfang nicht nötig. Alles Weitere – ein Kapitel gezielt wählen, nur ' +
          'die Fehler üben, nach einem Stichwort suchen, eine ganze Simulation durchlaufen – steht ' +
          'ebenfalls auf dem Startbildschirm und läuft Ihnen nicht davon.',
      }),
    ]),
  }),

  /*
    Das einzige Kapitel, das nicht eine Funktion erklärt, sondern eine
    Reihenfolge. Es fehlte bis Fassung 0.24.2, und das war die größte Lücke
    des Handbuchs: Nachgezählt sagte im ganzen Text genau **ein** Satz, was
    zu tun ist, um den Lernstand zu heben („Wer dem Tagespensum folgt, hält
    sie oben.“) – als dritter Halbsatz eines Listenpunkts im fünften von elf
    Kapiteln. „Woche“, „Rhythmus“ und „Strategie“ kamen kein einziges Mal
    vor. Der Lernende stand nach „Erste Schritte“ vor einem Startbildschirm
    mit fünf Einstiegen, vier Diagnosekarten, fünf Prüfungszuschnitten und
    drei Druckstücken, ohne einen Satz zur Reihenfolge.

    Zwei Grenzen sind dabei einzuhalten, beide aus Entscheidungsnotizen:
    **keine Phasennamen** (`entscheidung-lernphasen.md` hat die vier Phasen
    begründet abgelehnt; ein Handbuchtext, der sie einführt, holt sie durch
    die Hintertür zurück) und **kein „Rückstand“** – die Größe ist nicht
    wohldefiniert. Jede Wegmarke unten ist deshalb ein Zustand, den die
    Anwendung ohnehin anzeigt, und keine neu erfundene Größe.
  */
  Object.freeze({
    id: 'weg',
    titel: 'So kommen Sie durch',
    kurz: 'Von heute bis zum Prüfungstag',
    bloecke: Object.freeze([
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Diese Anwendung nimmt Ihnen die Auswahl ab. „Weiterlernen“ legt zuerst vor, was heute ' +
          'fällig ist, füllt mit Fragen auf, die Sie noch nie hatten, und greift erst danach auf ' +
          'Wiederholungen zurück, die noch nicht an der Reihe wären. Wer nichts weiter tut als ' +
          'das, kommt an. Die übrigen Einstiege sind für die Fälle gedacht, in denen Sie mehr ' +
          'wissen als das Programm.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Am Anfang sehen Sie überwiegend Fragen, die Sie noch nie hatten. Ihr Lernstand oben auf ' +
          `dem Startbildschirm steht dann bei „${STUFE_WORT.ohne_beleg}“ oder ` +
          `„${STUFE_WORT.zurueck}“, und das bleibt eine Weile so – eine Frage zählt erst als ` +
          'belegt, wenn Sie sie nach mindestens einem Tag Abstand ein zweites Mal richtig ' +
          'beantwortet haben. In dieser Zeit lohnt das Glossar: Die Fachwörter des Waffenrechts ' +
          'entscheiden mit darüber, ob Sie eine Frage überhaupt verstehen.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Sobald Sie den Katalog einmal durchhaben, verschiebt sich die Arbeit vom Neuen zum ' +
          'Wiederholen. Das Tagespensum wird dann von den fälligen Fragen bestimmt und schwankt ' +
          'von Tag zu Tag. Jetzt lohnt der Blick auf „Ihr Lernstand im Einzelnen“: Die ' +
          'Aufschlüsselung nach Kapiteln und Abschnitten zeigt, welcher Bereich zurückliegt, und ' +
          'über „Kapitel wählen“ nehmen Sie ihn gezielt vor.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          `Steht oben „${STUFE_WORT.kippe}“ oder „${STUFE_WORT.reif}“, ist die erste ` +
          'Prüfungssimulation an der Reihe. Sie beantwortet, was der Lernstand offenlässt: ob es ' +
          'auch unter Zeitvorgabe und am Stück trägt. Ein einzelner Bogen sagt dabei wenig – er ' +
          'zieht nur einen Teil des Katalogs. Wer wissen will, ob es vorangeht, fährt mehrere ' +
          'Läufe mit demselben Zuschnitt und derselben Zeitvorgabe; nur Gleiches lässt sich ' +
          'vergleichen.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Haben Sie einen Prüfungstermin eingetragen, ändert sich zum Termin hin etwas, das man ' +
          `sonst nicht bemerkt: Ab ${String(ANHEBUNG_AB_TAGEN)} Tagen vor dem Termin hebt die ` +
          'Anwendung ihren Anspruch an, wie sicher eine Frage sitzen soll. Die Wiederholungen ' +
          'rücken dadurch enger zusammen, und das Tagespensum wächst. Das ist beabsichtigt und ' +
          'kein Fehler.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'In den letzten Wochen kommt es weniger auf neue Fragen an als darauf, dass das ' +
          'Gelernte hält: die hartnäckigen Fragen abarbeiten, das Fehlerprotokoll ausdrucken und ' +
          'auf Papier durchgehen, und den Bereich vornehmen, den die Simulation als schwach ' +
          'gemeldet hat.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Einen festen Wochenplan gibt es hier nicht, und es soll auch keinen geben: Die ' +
          'Anwendung rechnet Ihr Pensum täglich neu und weiß dabei mehr über Ihren Stand als ein ' +
          'Plan, den Sie im Voraus aufstellen. Was sie nicht weiß, ist, wie viel Zeit Sie haben – ' +
          'deshalb der Prüfungstermin unter „Ihr Lernplan“.',
      }),
    ]),
  }),

  Object.freeze({
    id: 'lernsitzung',
    titel: 'Die Lernsitzung',
    kurz: 'Fragearten, Erklärungen, Merkliste, Selbstbewertung',
    bloecke: Object.freeze([
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Der amtliche Katalog kennt zwei Arten von Fragen, und die Sitzung behandelt sie ' +
          'unterschiedlich.',
      }),
      Object.freeze({
        art: 'liste' as const,
        punkte: Object.freeze([
          'Fragen zum Ankreuzen: Stehen runde Felder vor den Antworten, ist genau eine richtig. Stehen Kästchen davor, können es mehrere sein – dann zählt die Frage erst als richtig, wenn alle zutreffenden gewählt sind und keine weitere.',
          `Offene Fragen: Sie schreiben die Antwort selbst. Danach erscheint die Musterantwort, und Sie bewerten sich in vier Stufen – „${BEWERTUNG_BEZEICHNUNG.nochmal}“, „${BEWERTUNG_BEZEICHNUNG.schwer}“, „${BEWERTUNG_BEZEICHNUNG.gut}“, „${BEWERTUNG_BEZEICHNUNG.leicht}“. Diese Selbstbewertung steuert, wann die Frage wiederkommt – zu milde zu bewerten schadet nur Ihnen. Ihre eigene Antwort bleibt dabei stehen, damit Sie sie Wort für Wort danebenhalten können.`,
          'Haben Sie dieselbe offene Frage schon einmal beantwortet, erscheint nach dem Bestätigen zusätzlich Ihre letzte Antwort mit dem Datum – zwischen dem, was Sie heute geschrieben haben, und der Musterantwort. Vorher erscheint sie nicht: Sie soll kein Spickzettel sein, sondern zeigen, ob Sie heute genauer sind als beim letzten Mal.',
        ]),
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Nach jeder Antwort steht eine Erklärung mit der Fundstelle im Gesetz da. Sie ist ein ' +
          'redaktioneller Zusatz dieser Software und nicht Teil des amtlichen Katalogs; der ' +
          'Wortlaut der Fragen und Antworten bleibt unangetastet.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Unter mancher Musterantwort steht eine Liste: „Im amtlichen Fragenkatalog ist hier ' +
          'unterstrichen“. Das ist die Hervorhebung des Katalogs und keine Vorgabe für Ihre ' +
          'Antwort – das Amt sagt nirgends, was es damit meint, und bei den meisten offenen ' +
          'Fragen ist gar nichts unterstrichen. Eine richtige Antwort kann anders formuliert ' +
          'sein und trotzdem stimmen.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Wer gezielt nur die offenen Fragen üben will, findet auf dem Startbildschirm den ' +
          'Einstieg „Offene Fragen“. Sie sind der Teil der Prüfung, den ein Mensch bewertet – ' +
          'und der einzige, den sich niemand durch Ankreuzen erschließen kann.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Wie eine solche Antwort gebaut ist, verrät ihr erstes Wort. An den 104 offenen ' +
          'Fragen des Katalogs nachgezählt: 26 beginnen mit „Was“, 25 mit „Welche“, 7 mit ' +
          '„Wie“, je 5 mit „Wann“ und „Nennen Sie“.',
      }),
      Object.freeze({
        art: 'liste' as const,
        punkte: Object.freeze([
          '„Welche …“ und „Nennen Sie …“ verlangen eine Aufzählung. Eine einzige Nennung ist dort selten die ganze Antwort.',
          '„Was …“ verlangt eine Bestimmung – was etwas ist oder was eine Vorschrift regelt.',
          '„Wie …“ verlangt einen Ablauf oder eine Einordnung der Art nach: erst der eine Schritt, dann der nächste.',
          '„Wann …“ verlangt die Voraussetzungen und nicht das Ergebnis. „Ja, wenn …“ ist eine Antwort, „Ja“ ist keine.',
        ]),
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Nur 5 der 104 Fragen nennen selbst eine Anzahl. Wo eine dasteht, ist sie verbindlich: ' +
          'Zwei richtige Nennungen bei drei verlangten sind eine unvollständige Antwort.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Drei Gewohnheiten, die am Prüfungstag zählen. Benutzen Sie das Wort, das das Gesetz ' +
          'benutzt – das Glossar führt 118 davon. Schreiben Sie das Ergebnis zuerst und die ' +
          'Begründung dahinter; wer mit der Begründung anfängt, lässt das Ergebnis oft weg. Und ' +
          'hören Sie auf, wenn die Frage beantwortet ist: Was darüber hinaus steht, kann falsch ' +
          'sein und zieht die Antwort mit hinunter.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Schreiben Sie die Antwort auf, bevor Sie die Musterantwort aufdecken – auch dann, ' +
          'wenn Sie meinen, sie im Kopf zu haben. Was man beim Lesen wiedererkennt, hat man in ' +
          'der Prüfung noch nicht geschrieben. Das ist der ganze Unterschied zwischen Üben und ' +
          'Blättern.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Fachwörter in der Frage lassen sich an Ort und Stelle aufklappen – allerdings nur ' +
          'in der Lernsitzung, nicht in der Simulation und nicht in der Suche. Das vollständige ' +
          'Glossar erreichen Sie vom Startbildschirm aus über „Fachbegriffe nachschlagen“.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Bei den meisten offenen Fragen steht unter der Musterantwort eine Prüfliste: „Nach ' +
          'Einschätzung dieser Software gehört zu einer vollständigen Antwort“. Gehen Sie diese ' +
          'Punkte durch, bevor Sie eine der vier Stufen wählen – sonst hat Ihre Selbstbewertung ' +
          'keinen Maßstab. Die Punkte sind eine Erkennungshilfe und kein Urteil über Ihre ' +
          'Antwort; wo die Musterantwort aus einer einzigen Tatsache besteht, entfällt die Liste. ' +
          'Dieselbe Prüfliste steht in der Prüfungssimulation, wenn Sie dort Ihre offenen Fragen ' +
          'nachbewerten.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Haben Sie bei einer Auswahlfrage richtig geraten, sagen Sie es der Anwendung: Unter der ' +
          'Auflösung steht dann „Ich hatte geraten“. Die Frage wird daraufhin behandelt, als hätten ' +
          'Sie sie nicht gewusst – sie kommt in dieser Sitzung noch einmal, und als neuer Beleg für ' +
          'Ihren Reifegrad zählt sie nicht. Das ist keine Bestrafung, sondern der einzige Weg, wie ' +
          'die Anwendung von einem Glückstreffer erfahren kann: Ob eine angekreuzte Antwort gewusst ' +
          'oder geraten war, sieht sie Ihnen nicht an.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Führt eine Erklärung Fundstellen auf, steht unter ihr „Im Gesetz nachlesen“. Die dort ' +
          'genannten Stellen lassen sich aufklappen und zeigen den Wortlaut der Norm – die ' +
          'Gesetzestexte sind mitgeliefert, es wird nichts nachgeladen. Bei einer Frage, die Sie ' +
          'zum dritten Mal falsch haben, ist das der Ort, an dem sich das Wiederholen lohnt: Der ' +
          'amtliche Wortlaut sagt oft in einem Halbsatz, woran die Frage hängt.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Am Ende einer Sitzung bietet die Anwendung an, was sich unmittelbar anschließen lässt: ' +
          'weiterlernen mit dem, was heute noch fällig ist, die in dieser Sitzung falsch ' +
          'beantworteten Fragen sofort wiederholen, oder unter „Verwandte Fragen“ die Fragen ' +
          'üben, die denselben Gegenstand behandeln. Diese Zuordnung ist eine redaktionelle ' +
          'Ergänzung dieser Software; der amtliche Katalog kennt keine Beziehung zwischen zwei ' +
          'Fragen.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Zwei der Einstiege auf dem Startbildschirm sind leicht zu verwechseln. „Nur Fehler“ ' +
          'sieht allein auf Ihre jeweils letzte Antwort: Eine Frage, die dreimal danebenging und ' +
          'zuletzt saß, steht dort nicht mehr. „Gemerkte Fragen“ enthält, was Sie selbst mit dem ' +
          'Merkzeichen versehen haben, und sonst nichts – die Anwendung trägt dort nie von sich ' +
          'aus etwas ein.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Eine Sitzung lässt sich jederzeit über „Sitzung beenden“ verlassen. Was Sie bis dahin ' +
          'beantwortet haben, ist bereits gespeichert – es geht nichts verloren.',
      }),
    ]),
  }),

  Object.freeze({
    id: 'suchen',
    /* Dieselbe Benennung wie auf dem Startbildschirm, auf der Schaltfläche
       und über der Zielansicht. Bis Fassung 0.20.0 hieß dieselbe Sache hier
       „Fragen finden und nachschlagen“ und dort „Fragen finden“. */
    titel: 'Fragen durchsuchen',
    kurz: 'Ein Stichwort, eine Nummer – oder ein ganzes Kapitel der Reihe nach',
    bloecke: Object.freeze([
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Über „Fragen durchsuchen“ auf dem Startbildschirm lässt sich der Wortlaut aller ' +
          'Fragen samt ihrer Antwortmöglichkeiten durchsuchen. Groß- und Kleinschreibung, ' +
          'Umlaute und ß spielen dabei keine Rolle: „schiessen“ findet dasselbe wie ' +
          '„schießen“, „Buechse“ dasselbe wie „Büchse“.',
      }),
      Object.freeze({
        art: 'liste' as const,
        punkte: Object.freeze([
          'Gesucht wird auch im Wortinneren. Wer „Besitzkarte“ eingibt, findet die „Waffenbesitzkarte“ – deutsche Zusammensetzungen verstecken das gesuchte Wort sonst.',
          'Mehrere Wörter grenzen ein: Jedes muss in derselben Frage vorkommen, gleich ob in der Frage selbst oder in einer Antwortmöglichkeit.',
          'Eine Fragennummer wie „2.150“ oder „45“ führt direkt zur Frage. Gibt es die Nummer in mehreren Kapiteln, stehen alle nebeneinander.',
          'Bei leerem Suchfeld steht der gewählte Bereich vollständig da, in der Reihenfolge des amtlichen Katalogs – so lässt sich ein Kapitel der Reihe nach durchsehen.',
          'Die Zeile über der Liste nennt den gewählten Bereich, sobald einer gesetzt ist – auch dann, wenn es Treffer gibt.',
        ]),
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Jeder Treffer sagt, wo er sitzt: im Fragetext, im Wortinneren, in einer bestimmten ' +
          'Antwortmöglichkeit – oder nur in der Musterantwort. Die wird in der Trefferliste ' +
          'nicht gezeigt, denn bei den offenen Fragen ist sie die Lösung. Welche ' +
          'Antwortmöglichkeit richtig ist, verrät die Suche ebenfalls nicht.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Von jedem Treffer führt ein Knopf direkt ins Üben, und aus der Auswertung geht es ' +
          'zurück in die Suche: Der Suchbegriff steht dann noch da, und eine Einschränkung ' +
          'auf einen Bereich kommt mit – Sie finden dieselbe Trefferliste vor, wieder von ' +
          'ihrem Anfang an. Wer stattdessen zum Startbildschirm zurückgeht, beginnt beim ' +
          'nächsten Öffnen der Suche von vorn: leeres Feld, ganzer Katalog.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Findet die Suche nichts, bleibt sie nicht dabei stehen: Sie benennt das Wort, das ' +
          'im Katalog nicht vorkommt, rechnet vor, was ohne die Bereichseinschränkung zu ' +
          'finden wäre, und schlägt bei zusammengesetzten Wörtern eine Zerlegung vor.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Wo der Katalog ein anderes Wort benutzt als der Alltag – „abhanden gekommen“ statt ' +
          '„gestohlen“, „Sicherheitsbehältnis“ statt „Tresor“ –, bietet die Suche das an. Dieser ' +
          'Vorschlag erscheint unabhängig davon, ob Sie schon Treffer haben: Auch wer etwas ' +
          'findet, übersieht damit unter Umständen die Fragen, die den amtlichen Ausdruck ' +
          'benutzen.',
      }),
    ]),
  }),

  Object.freeze({
    id: 'wiedervorlage',
    titel: 'Wiedervorlage und Lernplan',
    kurz: 'Warum eine Frage wiederkommt – und wann',
    bloecke: Object.freeze([
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Das Programm schätzt für jede Frage, wie sicher Sie sie gerade noch abrufen können, ' +
          'und legt danach fest, wann sie wieder vorgelegt wird. Was sitzt, kommt selten; was ' +
          'wackelt, kommt bald. Einstellen müssen Sie dafür nichts.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Tragen Sie einen Prüfungstermin ein, rücken die Wiederholungen zum Termin hin enger ' +
          'zusammen, und das Programm nennt ein Tagespensum. Steht kein Termin fest, lassen Sie ' +
          'das Feld leer – dann wird ohne Stichtag geplant.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Das Pensum rechnet sich täglich neu. Sobald Sie heute etwas bearbeitet haben, nennt ' +
          'es Ihre Arbeit und was wirklich noch offen ist. Wer Tage auslässt, bekommt danach ' +
          'mehr – ein Rückstand wird nicht gesondert angemahnt, er steht bereits im Pensum. Am ' +
          'Prüfungstag selbst kommen keine neuen Fragen mehr dazu: Eine Frage, die an diesem ' +
          'Tag zum ersten Mal auftaucht, lässt sich nicht mehr belegen. Wiederholungen bleiben ' +
          'unberührt.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Unter „Drucken“ lassen sich drei Dokumente als PDF speichern; Sie wählen dort zuerst, ' +
          'welches es sein soll. Der „Lernbericht“ zeigt Ihren Stand ' +
          'ohne Fragen und Antworten. Das „Fehlerprotokoll“ enthält die Fragen, die Sie zuletzt ' +
          'falsch beantwortet haben – mit allen Antwortmöglichkeiten, der richtigen Antwort und ' +
          'einer Begründung, wahlweise kurz oder ausführlich. Die „Fragenliste“ ist ein Bogen ' +
          'zum Bearbeiten auf Papier: Kästchen zum Ankreuzen, Linien für die offenen Fragen, und ' +
          'die Lösungen erst im Anhang. Sie lässt sich kapitel- oder abschnittsweise erzeugen.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Beim Fehlerprotokoll und bei der Fragenliste steht vor dem Speichern, wie viele ' +
          'Seiten zu erwarten sind – die Zahl kann groß werden. Ein Fehlerprotokoll mit ' +
          'ausführlicher Begründung über den ganzen Katalog ergibt im Großdruck fast tausend ' +
          'Seiten. Der Lernbericht bekommt keine Schätzung; er ist immer kurz. Jedes Dokument nennt auf ' +
          'jeder Seite die Herkunft der Fragen und weist aus, was davon aus dem amtlichen ' +
          'Katalog stammt und was Ergänzung dieser Software ist.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Ihr Stand steht auf dem Startbildschirm unter „Ihr Lernstand im Einzelnen“, ' +
          'aufgeschlüsselt nach Bereichen. Dort steht auch, wann Sie zuletzt gelernt haben – ' +
          '„heute“, „gestern“, „vor 14 Tagen“ oder „noch nie“. Wer nach einer Pause ' +
          'zurückkommt, sieht einen gefallenen Stand und ein gewachsenes Pensum; diese Zeile ' +
          'ist die Erklärung dazu. Wer den Stand schwarz auf weiß braucht, gibt ihn unter ' +
          '„Drucken“ als Lernbericht aus.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Ganz oben steht, wie weit Sie sind: ein Wort und die Zahl, auf der es beruht – ' +
          `wie viele Ihrer Fragen belegt sitzen und wie viele es insgesamt sind. Die vier Worte sind ` +
          `„${STUFE_WORT.ohne_beleg}“, „${STUFE_WORT.zurueck}“, „${STUFE_WORT.kippe}“ und ` +
          `„${STUFE_WORT.reif}“. Dasselbe steht je Kapitel und Abschnitt darunter.`,
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Belegt heißt: Sie haben die Frage nach mindestens einem Tag Abstand noch einmal ' +
          'richtig beantwortet. Beim ersten Mal zählt sie nicht mit, auch wenn Sie richtig ' +
          'geantwortet haben. Der Grund ist nicht Strenge, sondern Ehrlichkeit: Dass Sie die ' +
          'richtige Antwort unter mehreren wiedererkennen, heißt noch nicht, dass Sie sie ' +
          'morgen erinnern. Erst das Wiedersehen zeigt es.',
      }),
      Object.freeze({
        art: 'liste' as const,
        punkte: Object.freeze([
          'Die Zahl kann fallen, ohne dass Sie etwas falsch gemacht haben – ein Beleg altert. ' +
            'Wer dem Tagespensum folgt, hält sie oben.',
          'Eine falsche Antwort nimmt den Beleg wieder weg. Die Frage kommt dann bald erneut.',
          'Nach dem ersten Durchgang durch den Katalog steht die Zahl noch bei null. Das ist ' +
            'richtig so – belegt ist dann noch nichts. Wie viel Sie bearbeitet haben, steht ' +
            'gleich daneben.',
        ]),
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Die Zahl sagt, was belegt sitzt – nicht, was in der Prüfung herauskäme. Raten ist ' +
          'nicht eingerechnet, nie Gesehenes gilt als nicht gekonnt. Sie ist also eher zu ' +
          'niedrig als zu hoch. Über das Bestehen entscheidet allein der Prüfungsausschuss.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Ein Sonderfall: Liegt ein einzelner Bereich weit zurück, kann das ganze Urteil ' +
          'darauf zurückfallen, auch wenn es sonst gut aussieht. Bei Notwehr und Notstand ' +
          'lassen manche Prüfungsstellen nur zwei Fehler zu, gleich wie gut der Rest ist. ' +
          'Steht der Bereich zurück, sagt das Programm es an dieser Stelle ausdrücklich.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Nicht jede Prüfungsstelle prüft Kapitel IV, „Not- und Seenotsignalmittel“. Unter ' +
          '„Ihr Lernplan“ steht dafür ein Schalter: „Kapitel IV – Not- und Seenotsignalmittel ' +
          'mitlernen“. Schalten Sie ihn aus, kommen aus diesem Kapitel keine Fragen mehr in ' +
          'Ihre Lernsitzungen, und Fortschritt, Tagespensum und Prognose rechnen ohne sie. Das ' +
          'ist ein knappes Sechstel des Katalogs – wer es mitschleppt, ohne es zu brauchen, ' +
          'sieht dauerhaft zu wenig Fortschritt.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Beim allerersten Start werden Sie danach gefragt, noch vor dem Startbildschirm – ' +
          'damit der Schalter dort ankommt, wo er wirkt. Die Frage erscheint einmal; danach ' +
          'ändern Sie es unter „Ihr Lernplan“.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Fragen Sie im Zweifel bei Ihrer Prüfungsstelle nach, bevor Sie abwählen. Die ' +
          'Entscheidung gehört zum Lernprofil: Zwei Personen an einem Rechner können sie ' +
          'verschieden treffen. Verloren geht dabei nichts – was Sie in Kapitel IV bereits ' +
          'gelernt haben, bleibt gespeichert und ist beim Wiedereinschalten vollständig ' +
          'wieder da. Nachschlagen können Sie die Fragen jederzeit über „Fragen durchsuchen“, ' +
          'und in der Kapitelwahl bleibt Kapitel IV zum Üben stehen; es trägt dort den ' +
          'Vermerk, dass es für dieses Profil abgewählt ist.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'In der Prüfungssimulation steht dasselbe Kästchen noch einmal. Es übernimmt Ihre ' +
          'Einstellung von hier als Vorgabe: Wer Kapitel IV abgewählt hat, bekommt daraus auch ' +
          'in der Simulation keine Frage. Für eine einzelne Simulation lässt es sich umstellen – ' +
          'am Schalter für das tägliche Lernen ändert das nichts.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Unter „Ihr Lernstand im Einzelnen“ erscheint der Abschnitt „Hartnäckige Fragen“, ' +
          `sobald Ihnen eine Frage an ${String(HARTNAECKIG_AB_TAGEN)} verschiedenen Tagen ` +
          'danebengegangen ist. Das ist etwas anderes als der Einstieg „Nur Fehler“, der allein ' +
          'Ihre letzte Antwort ansieht. Mit „Diese Fragen üben“ starten Sie eine Sitzung aus genau ' +
          'diesen Fragen. Nehmen Sie sich dort Zeit für die Erklärung und klappen Sie die ' +
          'Fundstelle auf: Bloßes Wiederholen hat bei diesen Fragen schon dreimal nicht gereicht. ' +
          'Solange keine Frage die Schwelle erreicht, erscheint der Abschnitt nicht.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Steht bei einer hartnäckigen Frage „Sie wählen dort meist …“, haben Sie immer wieder ' +
          'dieselbe falsche Antwort angekreuzt. Dann verwechseln Sie zwei Dinge, und es hilft ein ' +
          'Merksatz, der sie auseinanderhält. Fehlt dieser Zusatz, streuen Ihre Fehlgriffe über ' +
          'mehrere Antworten – dann fehlt der Stoff und nicht die Unterscheidung.',
      }),
    ]),
  }),

  Object.freeze({
    id: 'simulation',
    titel: 'Die Prüfungssimulation',
    kurz: 'Ein ganzer Bogen am Stück – und unterbrechbar',
    bloecke: Object.freeze([
      Object.freeze({
        art: 'absatz' as const,
        text:
          'In der Simulation bearbeiten Sie einen Bogen – den Fragensatz eines Durchgangs – am ' +
          'Stück, ohne Rückmeldung zwischendurch, so ' +
          `wie es in der Prüfung zugeht. ${String(PRUEFUNGSPROFILE.length)} Zuschnitte stehen ` +
          'bereit; sie unterscheiden sich in Fragenzahl, Zeit, Bestehensgrenze, im Anteil ' +
          'offener Fragen, in der Verteilung über die Themenbereiche und darin, ob nach Quote ' +
          'oder nach Fehlerpunkten gewertet wird. Keiner davon ist „die“ amtliche Prüfung – ' +
          'welche Regeln gelten, bestimmt Ihr Prüfungsausschuss.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Auch ein bestandener Durchgang bildet immer nur den theoretischen Teil ab. Zur ' +
          'Sachkundeprüfung gehört nach § 2 Absatz 3 der Allgemeinen Waffengesetz-Verordnung ' +
          'ein praktischer Teil, den diese Anwendung weder übt noch prüft, und viele ' +
          'Prüfungsstellen stellen zusätzlich mündliche Fragen. Siehe „Was diese Anwendung ' +
          'ist“.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Im Profil „Selbst einstellen“ wählen Sie Fragenzahl, Zeit, Bestehensgrenze und den ' +
          'Anteil offener Fragen selbst. Der Anteil ist eine Bitte, keine Zusage: Der amtliche ' +
          'Katalog enthält nur einen Teil an offenen Fragen, und wer Kapitel IV abwählt, ' +
          'verliert davon weitere. Unter dem Feld steht deshalb, wie viele offene Fragen Ihr ' +
          'Wunsch ergäbe und wie viele wirklich zur Verfügung stehen. Reicht der Vorrat nicht, ' +
          'füllt die Anwendung mit Auswahlfragen auf und sagt es Ihnen vorher. Weicht der fertige ' +
          'Bogen aus einem anderen Grund von den Vorgaben ab – etwa weil ein Themenbereich zu ' +
          'wenige Fragen hat –, steht das zu Beginn der Simulation als Hinweis über den Fragen.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Nach der Abgabe folgt bei offenen Fragen ein zweiter Schritt: Sie sehen Ihre eigene ' +
          'Antwort neben der Musterantwort und entscheiden selbst, ob Sie das Wesentliche ' +
          'getroffen haben – so, wie es in der Prüfung der Prüfungsausschuss täte. Ohne Wertung ' +
          'zählt eine Antwort als falsch. Erst danach steht das Ergebnis fest.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Die Zeitvorgabe lässt sich verlängern oder ganz abschalten. Wer einen ' +
          'Nachteilsausgleich bekommt, stellt hier dieselbe Verlängerung ein, die ihm in der ' +
          'Prüfung zusteht, und übt unter den Bedingungen, unter denen er geprüft wird.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Ob Ihnen in der Prüfung ein Nachteilsausgleich zusteht, entscheidet diese Anwendung ' +
          'nicht – und das Waffenrecht regelt ihn nicht. Nachgeschlagen: Das Wort kommt weder ' +
          'im Waffengesetz noch in der Allgemeinen Waffengesetz-Verordnung vor. Entschieden ' +
          'wird es dort, wo Ihre Prüfung abgenommen wird.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Wer das ist, hängt an Ihrem Weg. Die zuständige Behörde bildet die Prüfungsausschüsse ' +
          '(§ 2 Absatz 1 AWaffV). Gehören Sie einem schießsportlichen Verein an, der einem ' +
          'anerkannten Schießsportverband angehört, kann der Verein die Prüfung für seine ' +
          'Mitglieder selbst abnehmen und bildet dafür einen eigenen Ausschuss ' +
          '(§ 3 Absatz 5 AWaffV).',
      }),
      Object.freeze({
        art: 'liste' as const,
        punkte: Object.freeze([
          'Ob ein Ausgleich möglich ist – und in welcher Form. Mehr Zeit ist nur eine von mehreren.',
          'Welchen Nachweis die Stelle sehen will.',
          'Bis wann der Antrag vorliegen muss.',
          'Ob auch der praktische Teil berührt ist. Die Prüfung besteht aus einem theoretischen und einem praktischen Teil (§ 2 Absatz 3 AWaffV); diese Anwendung bereitet nur auf den theoretischen vor.',
        ]),
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Fragen Sie früh, am besten vor der Anmeldung. Und üben Sie in beiden Zuständen: ' +
          'Solange nichts zugesagt ist, ist die Zeitvorgabe ohne Verlängerung der Maßstab. Ein ' +
          'zugesagter Ausgleich ist dann ein Vorteil und keine Voraussetzung.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Falls es beim ersten Mal nicht reicht: Die Prüfung lässt sich wiederholen, auch ' +
          'mehrmals; der Prüfungsausschuss kann dafür eine Frist bestimmen ' +
          '(§ 2 Absatz 5 AWaffV).',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Eine unterbrochene Simulation geht nicht verloren: Wird das Fenster geschlossen oder ' +
          'fällt der Strom aus, bietet der Startbildschirm sie beim nächsten Start zum ' +
          'Fortsetzen an. Die Uhr steht still, solange das Programm zu ist, und läuft erst nach ' +
          'einer ausdrücklichen Bestätigung weiter.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Zum Unterbrechen genügt es also, das Fenster zu schließen. „Simulation abbrechen“ im ' +
          'laufenden Bogen tut etwas anderes: Es verwirft ihn. Die Anwendung fragt vorher nach, ' +
          'und ein verworfener Bogen erscheint auch nicht im Verlauf – dort steht nur, was ' +
          'abgegeben und ausgewertet wurde. Offen sein kann außerdem immer nur eine Simulation ' +
          'je Lernprofil: Wer eine neue startet, verwirft damit die alte. Und wer seinen ' +
          'Lernstand unter „Neu anfangen“ zurücksetzt, verliert einen offenen Bogen mit.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Diese Hilfe können Sie auch mitten in einer laufenden Simulation öffnen; sie bleibt ' +
          'stehen, wo sie ist. Die Uhr läuft dabei weiter – sie anzuhalten würde die Simulation ' +
          'verfälschen.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Ein Simulationslauf ist kein Nebenschauplatz. Jede Frage, die Sie im Bogen beantwortet ' +
          'haben, geht denselben Weg wie eine Antwort aus der Lernsitzung: Sie zählt in der ' +
          'Tagesbilanz mit, sie zählt für den Reifegrad, und die Anwendung setzt daraufhin den ' +
          'nächsten Vorlagetermin. Eine falsch beantwortete Frage verliert dabei ihren Beleg. Ihr ' +
          'Lernstand kann nach einem schwachen Bogen also sinken – das ist dieselbe Regel wie beim ' +
          'täglichen Lernen und kein Fehler. Fragen, die im Bogen standen, zu denen Sie aber nicht ' +
          'mehr gekommen sind, bleiben unberührt: Sie erscheinen in der Auswertung als nicht ' +
          'beantwortet, verschieben aber keinen Termin und nehmen keinen Beleg weg.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Die Auswertung sagt mehr als bestanden oder nicht bestanden. Unter „Ergebnis nach ' +
          'Themenbereichen“ steht, wie Sie in jedem Bereich abgeschnitten haben – dort sehen Sie, ' +
          'welches Kapitel Sie als Nächstes vornehmen sollten. „Wiederkehrende Lücken“ erscheint, ' +
          'sobald mehrere Simulationen vorliegen, und nennt die Bereiche, die nicht nur einmal, ' +
          'sondern wiederholt unter der Grenze lagen; das ist der Unterschied zwischen einem ' +
          'schlechten Tag und einer echten Lücke. Mit „Fehler wiederholen“ starten Sie unmittelbar ' +
          'eine Lernsitzung aus den Fragen, die in diesem Bogen danebengingen.',
      }),
    ]),
  }),

  Object.freeze({
    id: 'tastatur',
    titel: 'Bedienung ohne Maus',
    kurz: 'Alles ist mit der Tastatur erreichbar',
    bloecke: Object.freeze([
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Es gibt keine Funktion, die nur mit der Maus erreichbar wäre. Der erste Tabstopp im ' +
          'Fenster ist immer der Sprunglink „Direkt zum Hauptinhalt springen“.',
      }),
      Object.freeze({ art: 'tasten' as const, zeilen: TASTATURBEDIENUNG }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Unter macOS steht die Befehlstaste an der Stelle von Strg. Die Anzeigegröße lässt ' +
          'sich außerdem über das Menü „Ansicht“ und auf dem Startbildschirm unter ' +
          '„Anzeigegröße“ ändern.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Dazu kommen drei Kürzel aus einzelnen Zeichen. Sie wirken nur in der Lernsitzung und ' +
          'nur außerhalb von Textfeldern, und sie lassen sich abschalten. Läuft ein ' +
          'Bildschirmleser, sind sie von vornherein aus: Dessen Lesemodus belegt die Ziffern ' +
          'bereits für die Navigation nach Überschriften.',
      }),
      Object.freeze({ art: 'tasten' as const, zeilen: TASTENKUERZEL }),
    ]),
  }),

  Object.freeze({
    id: 'anpassen',
    titel: 'Anzeige, Farben und Vorlesen',
    kurz: 'Was sich einstellen lässt, wenn das Lesen schwerfällt',
    bloecke: Object.freeze([
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Alle Einstellungen stehen auf dem Startbildschirm unter „Einstellungen“, gelten ' +
          'sofort und überstehen das Schließen des Programms.',
      }),
      Object.freeze({
        art: 'liste' as const,
        punkte: Object.freeze([
          `Anzeigegröße: ${String(KLEINSTE_ANZEIGE)} bis ${String(GROESSTE_ANZEIGE)} Prozent. Vergrößert wird alles gemeinsam, auch die Prüfzeichen auf den Bildern – eine reine Schriftvergrößerung ließe ausgerechnet die unberührt.`,
          'Farbschema: hell, dunkel oder hoher Kontrast, wahlweise nach Vorgabe des Betriebssystems. Schaltet das System auf hohen Kontrast, folgt die Anwendung von selbst.',
          'Textdarstellung: drei Stufen für Zeilen-, Wort- und Zeichenabstand. Sie sind etwas anderes als die Anzeigegröße: Die vergrößert alles gemeinsam und hilft bei zu kleiner Schrift; hier bekommt der Text mehr Luft zwischen den Buchstaben, ohne größer zu werden. Wer mit Legasthenie liest, braucht oft genau das.',
          'Vorlesen: blendet eine Schaltfläche ein, die vorliest, was gerade dasteht – die Frage mit ihren Antwortmöglichkeiten, nach dem Bestätigen die Rückmeldung. Gesprochen wird nur auf Knopfdruck. Wer das nicht bei jeder Frage tun möchte, schaltet darunter „Frage und Rückmeldung von selbst vorlesen“ ein; mit „Bei falscher Antwort die ausführliche Begründung vorlesen“ kommt der lange Text unter „Warum das so ist“ dazu, aber nur wenn es danebenging. Beide stehen ab Werk aus und lassen sich einzeln setzen. Das selbsttätige Vorlesen gilt nur in der Lernsitzung, nicht in der Simulation – dort spricht die Anwendung ausschließlich auf Knopfdruck. Benutzt werden die Stimmen Ihres Betriebssystems. Gedacht ist das für Menschen ohne Bildschirmleser – beide zugleich sprechen durcheinander.',
          'Schwierigkeit: zwei Schalter, beide ab Werk aus. Ausgeschaltet steht die Anwendung so nah am amtlichen Katalog wie möglich; eingeschaltet wird es schwerer, ohne dass ein Lernvorteil belegt wäre.',
        ]),
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Die Rechtschreibprüfung ist im ganzen Fenster abgeschaltet, auch im Textfeld der ' +
          'offenen Fragen. Der Grund: Ihre Wörterbücher würden aus dem Netz nachgeladen, und ' +
          'die Zusage, dass nichts übertragen wird, gilt ohne Ausnahme.',
      }),
    ]),
  }),

  Object.freeze({
    id: 'daten',
    titel: 'Profile und Ihre Daten',
    kurz: 'Wo der Lernstand liegt und wie er wieder verschwindet',
    bloecke: Object.freeze([
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Mehrere Personen können dieselbe Installation benutzen: Jedes Profil hat seinen ' +
          'eigenen Lernstand, seine eigene Merkliste und seinen eigenen Prüfungstermin. ' +
          'Angelegt, umbenannt, gewechselt und gelöscht werden Profile auf dem Startbildschirm ' +
          'unter „Einstellungen“ – nur dort, weil dort weder eine Sitzung noch eine Simulation ' +
          'läuft, die ein Wechsel durcheinanderbringen könnte.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Der Lernstand liegt in einer Datenbankdatei in Ihrem Benutzerprofil – unter Windows ' +
          'im Ordner „AppData“, unter macOS unter „Library/Application Support“, jeweils in ' +
          'einem Ordner mit dem Namen der Anwendung. Er verlässt den Rechner nicht.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Unter „Neu anfangen“ lässt sich der Lernstand des gewählten Profils vollständig ' +
          'zurücksetzen. Das ist endgültig und wird vorher noch einmal abgefragt.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Sichern und übertragen: Auf dem Startbildschirm gibt es den Abschnitt „Lernstand ' +
          'sichern und übertragen“. „Sicherung speichern“ schreibt Ihren ganzen Lernstand in eine ' +
          'einzige Datei – alle Profile, alle Antworten, die Merklisten, die Prüfungstermine und ' +
          'den Verlauf Ihrer Simulationen. Diese Datei können Sie aufheben oder auf einen anderen ' +
          'Rechner mitnehmen. Es wird nichts übertragen: Die Datei geht nur dorthin, wohin Sie sie ' +
          'legen.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          '„Sicherung auswählen und ansehen“ geht den anderen Weg. Sie sehen zuerst, was in der ' +
          'Datei steht – wie viele Profile, wie viele Antworten, wann zuletzt gelernt wurde – und ' +
          'daneben dasselbe für den Stand auf diesem Rechner. Erst danach entscheiden Sie. Was Sie ' +
          'einlesen, tritt an die Stelle Ihres jetzigen Standes; zusammengeführt wird nichts. ' +
          'Unmittelbar vorher legt die Anwendung von selbst eine Sicherung Ihres jetzigen Standes ' +
          'an und nennt Ihnen deren Namen – das ist der Weg zurück.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Beim Einlesen haben Sie zwei Möglichkeiten. „Ersetzen“ setzt Ihren ganzen ' +
          'Lernstand durch den aus der Datei – alles, was nur hier steht, ist danach fort. Vorher ' +
          'zählt die Anwendung aus, was das wäre, und nennt es Profil für Profil. „Ein Profil ' +
          'dazunehmen“ lässt alles Vorhandene unberührt und stellt das gewählte Profil daneben; ' +
          'das ist der Weg, wenn Sie auf zwei Rechnern lernen. Zusammengerechnet wird dabei ' +
          'nichts: Haben Sie hier und in der Datei dasselbe Profil, stehen danach beide ' +
          'nebeneinander.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Nicht in der Sicherung stehen Ihre Einstellungen – Farbschema, Anzeigegröße, Vorlesen. ' +
          'Die sind auf einem neuen Rechner in einer Minute wieder eingestellt. Der Fragenkatalog ' +
          'auch nicht: Er gehört zum Programm. Enthalten ist dagegen alles, was Sie je bei einer ' +
          'offenen Frage getippt haben – die Sicherung kopiert Ihren vollständigen Lernstand. Und ' +
          'die Datei ist nicht verschlüsselt: Wer sie hat, kann sie lesen. Geben Sie sie also nur ' +
          'weiter, wenn Sie das wollen.',
      }),
    ]),
  }),

  Object.freeze({
    id: 'probleme',
    titel: 'Wenn etwas nicht funktioniert',
    kurz: 'Die häufigsten Fälle und was dann zu tun ist',
    bloecke: Object.freeze([
      Object.freeze({
        art: 'liste' as const,
        punkte: Object.freeze([
          'Der Fragenkatalog lädt nicht: Es erscheint eine Meldung mit der Schaltfläche „Fragenkatalog erneut laden“. Hilft die nicht, ist die Installation unvollständig – dann ist ein erneutes Installieren der sicherste Weg.',
          'Das Fenster bleibt leer oder zeigt eine Fehlerseite: Ihr Lernstand ist davon nicht betroffen. „Anwendung neu laden“ auf der Fehlerseite oder „Ansicht → Neu laden“ im Menü setzt die Oberfläche neu auf.',
          `Die Schrift ist zu klein: Strg und Plus, oder auf dem Startbildschirm unter „Anzeigegröße“. Die Anwendung geht bis auf ${String(GROESSTE_ANZEIGE)} Prozent.`,
          'Die Vorlesefunktion schweigt: Dann bietet das Betriebssystem keine Stimme an. Unter Windows werden Stimmen in den Systemeinstellungen unter „Zeit und Sprache“ nachinstalliert.',
          'Eine Simulation scheint verschwunden: Sie ist es fast nie – der Startbildschirm bietet eine unterbrochene Simulation zum Fortsetzen an, solange sie nicht ausdrücklich verworfen wurde.',
        ]),
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Bleibt es dabei, melden Sie es bitte. Für Rückfragen hilft der Abschnitt ' +
          '„Systemzustand“ auf dem Startbildschirm: Er nennt Programmfassung, Baustand und den ' +
          'Zustand der Datenbank.',
      }),
    ]),
  }),

  Object.freeze({
    id: 'melden',
    titel: 'Eine Barriere oder einen Fehler melden',
    kurz: 'Wer antwortet, worauf – und bis wann',
    bloecke: Object.freeze([
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Wenn Sie in dieser Anwendung auf eine Barriere stoßen oder einen Fehler finden, ' +
          `melden Sie es bitte. Sie bekommen eine Antwort ${KONTAKT.frist}.`,
      }),
      Object.freeze({
        art: 'liste' as const,
        punkte: Object.freeze([`Verantwortlich: ${KONTAKT.name}`, `E-Mail: ${KONTAKT.epost}`]),
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Die Angaben stehen als Text da und sind nicht verknüpft: Die Anwendung öffnet von ' +
          'sich aus keine Verbindung ins Netz und startet auch kein E-Mail-Programm. Kopieren ' +
          'Sie die Adresse in das Programm Ihrer Wahl. Wofür dieser Weg im Einzelnen da ist, ' +
          'steht ausführlich unter „Über diese Software“.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Aus einer Lernsitzung heraus geht es kürzer: Unter den Schaltflächen steht „Fehler zu ' +
          'dieser Frage melden“. Aufgeklappt zeigt der Block einen fertigen Text mit ' +
          'Fragennummer, Katalogstand und Programmfassung – alles, was zur Bearbeitung nötig ' +
          'ist. Schreiben Sie darunter, was Ihnen aufgefallen ist, kopieren Sie ihn mit der ' +
          'Schaltfläche und schicken Sie ihn an die oben genannte Adresse.',
      }),
      Object.freeze({
        art: 'absatz' as const,
        text:
          'Der Text steht sichtbar da, bevor Sie ihn kopieren: Sie sollen lesen können, was Sie ' +
          'weitergeben. Er enthält nichts über Sie und nichts über Ihren Lernstand. Steht die ' +
          'Schaltfläche einmal nicht zur Verfügung, markieren Sie den Text im Feld und kopieren ' +
          'ihn mit Strg und C.',
      }),
    ]),
  }),
]);

/** Die Überschrift des Hilfefensters – auch für Menü und Tests. */
export const HILFE_TITEL = 'Hilfe';

/** Was unter der Überschrift steht, noch vor dem Inhaltsverzeichnis. */
export const HILFE_EINLEITUNG =
  'Dieses Handbuch erklärt die Bedienung der Anwendung. Es legt sich über das, was gerade zu ' +
  'sehen ist – Ihre Lernsitzung oder Ihr Prüfungsbogen bleibt stehen, wo er ist.';
