)]}'
{
  "commit": "f20828ffd8ea9d554566636a9c53a3abd57507c5",
  "tree": "6d795f85206b7b427fe92fc1c89df5a2fba07595",
  "parents": [
    "99511a961d741e2dc06113cf5f24180bfea2b26b"
  ],
  "author": {
    "name": "Matthias Andreas Benkard",
    "email": "code@mail.matthias.benkard.de",
    "time": "Sat Jul 18 08:57:22 2026 +0200"
  },
  "committer": {
    "name": "Matthias Andreas Benkard",
    "email": "code@mail.matthias.benkard.de",
    "time": "Sun Jul 19 09:00:01 2026 +0200"
  },
  "message": "Classify line ends by alignment clusters and canonicalize definition lists\n\nThe percentile-based right-margin estimate from the previous commit\nmisclassified two real-world layouts: at the column switch of the\ntwo-column old-BGBl format a window contains both column margins, so the\n90th percentile returned the right column\u0027s margin and marked every\nleft-column soft wrap as deliberate (vetoing hyphen mending, IfSG 2020:\n\"Impf- surveillance\"); and series of equally wide centered \"Artikel N\"\nheadings in draft bills formed the top of their window\u0027s distribution,\nso they counted as full-width and were reflowed into the following line,\nbreaking teileInArtikel\u0027s line anchor (ProdHaftG RegE). Classify against\nalignment clusters instead: a line end is soft when at least five window\nlines end within 4 pt of it (the justified block\u0027s own margin), hard when\nsuch a cluster runs at least 10 pt above it, unclassified otherwise.\nStructure anchors (\"Artikel 2\", \"§ 19\", bare Gliederung labels) are\nalways exempt from reflow since equal-width heading series still form\nsham clusters. Also flush the pending line end-X at page ends — without\nit, the first line of the next page inherited the previous page\u0027s footer\ngeometry and was misclassified (UWG: \"Artikel 2\" swallowed the closing\nprovisions).\n\nMarkerless joins additionally never cross into a following enumeration\nmarker line (\"...vorgesehen und\" + \"d) die Überwachung\" no longer glues\nto \"undd)\"), a text-level veto that also works without geometry.\n\nOn the base-law side, ContentFlattener now separates sibling \u003cLA\u003e\nelements within a \u003cDD\u003e — the short-label/definition pairs of the UWG\nAnhang and § 2 IfSG were previously glued without any separator\n(\"Irreführung über Unternehmereigenschaftdie unwahre Angabe...\") in both\nsynopsis columns. The continuation line is indented two spaces deeper\nthan its enumeration line so StellenAufloeser.zeilenBlock keeps it inside\nthe unit\u0027s block (\"Anhang Nummer 31 Buchstabe b\"). BefehlAnwender writes\nthe same canonical shape when inserting or recasting quoted units\n(rueckeZitatEin), so XML-derived and PDF-derived items agree:\n\"  2a. Stichwort\" + \"    Definitionstext\".\n\nVerified by mvnw verify (179 tests, 7 new) and a before/after sweep of\nall 21 sample law/amendment combinations: applied/manual counts are\nunchanged throughout (UWG 19/0, GEG-BGBl 66/53, GModG-RegE 77/20,\nIfSG-0645 42/24, ...), no marker characters leak into the HTML output.\n\nCo-Authored-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\nChange-Id: Ib7faae1bc5c59bda83f648a579af16a4c77e4285\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "d3195bb867111f6570f52ada0e4784003d41e02b",
      "old_mode": 33188,
      "old_path": "FASSUNGEN.txt",
      "new_id": "9ea3b7e46ed1935fa2084b93ab256b17044307db",
      "new_mode": 33188,
      "new_path": "FASSUNGEN.txt"
    },
    {
      "type": "modify",
      "old_id": "45ce32a170a088b86a10c61e6ee975d97b17d63f",
      "old_mode": 33188,
      "old_path": "src/main/java/eu/mulk/aendggner/aenderung/parse/FontgroessenFilter.java",
      "new_id": "964d856d15897e3d99d3a0760a87ad5a26377308",
      "new_mode": 33188,
      "new_path": "src/main/java/eu/mulk/aendggner/aenderung/parse/FontgroessenFilter.java"
    },
    {
      "type": "modify",
      "old_id": "1355877b645dd76a31017fa78670fd18137ec5c9",
      "old_mode": 33188,
      "old_path": "src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java",
      "new_id": "8a7b6ae701289a848570cbf833f35e881eb7a09a",
      "new_mode": 33188,
      "new_path": "src/main/java/eu/mulk/aendggner/aenderung/parse/TextBereiniger.java"
    },
    {
      "type": "modify",
      "old_id": "c5a4bbb58277738b3e7c2f726127a4b2f105b607",
      "old_mode": 33188,
      "old_path": "src/main/java/eu/mulk/aendggner/anwendung/BefehlAnwender.java",
      "new_id": "ac4dbf238b27ee31523227c374b97b54d29f6127",
      "new_mode": 33188,
      "new_path": "src/main/java/eu/mulk/aendggner/anwendung/BefehlAnwender.java"
    },
    {
      "type": "modify",
      "old_id": "a395fa19a8f7e10bfff31dcf621f800c64c62dd0",
      "old_mode": 33188,
      "old_path": "src/test/java/eu/mulk/aendggner/EndToEndTest.java",
      "new_id": "0b7820da0e836abfec55cb2c568a4ab4bd00e716",
      "new_mode": 33188,
      "new_path": "src/test/java/eu/mulk/aendggner/EndToEndTest.java"
    },
    {
      "type": "modify",
      "old_id": "4ca86cf8eac2f05519a4a0e922741eb98e78038f",
      "old_mode": 33188,
      "old_path": "src/test/java/eu/mulk/aendggner/aenderung/parse/TextBereinigerTest.java",
      "new_id": "8a7cf12b2738d0b4aebfa039795789d0e7fcb8ad",
      "new_mode": 33188,
      "new_path": "src/test/java/eu/mulk/aendggner/aenderung/parse/TextBereinigerTest.java"
    },
    {
      "type": "modify",
      "old_id": "b3e3f32a08c214439379b688877326f91b1d85bd",
      "old_mode": 33188,
      "old_path": "src/test/java/eu/mulk/aendggner/gesetz/gii/GiiXmlLoaderTest.java",
      "new_id": "607f24fef30dcb0c6412d618884cd88abfd82822",
      "new_mode": 33188,
      "new_path": "src/test/java/eu/mulk/aendggner/gesetz/gii/GiiXmlLoaderTest.java"
    },
    {
      "type": "modify",
      "old_id": "866f81bb6cf1ff729dc20ffaf6d64206ae8f691f",
      "old_mode": 33188,
      "old_path": "src/test/resources/eu/mulk/aendggner/mini-gii.xml",
      "new_id": "8ae0418e05d4a07f6cf717b48898864a96004749",
      "new_mode": 33188,
      "new_path": "src/test/resources/eu/mulk/aendggner/mini-gii.xml"
    }
  ]
}
