Commit Graph

78 Commits

Author SHA1 Message Date
m.stangl bf2601a932 fix beim csv Export des Eckrades. Bild der gf für Doku war noch veraltet. Erste Fassung einer Lisp Funktion zur Erzeugung der Stückliste in der Szene 2026-10-09 16:22:57 +02:00
m.stangl 01fb2d29f2 [CHANGE] GEFAELLESTRECKE_LINIENZUG-Streckengruppen per Doppelklick editierbar machen
Bisher brach GEFAELLESTRECKE_EDIT bei jeder Streckengruppe (TYP "Streckengruppe", d.h. mit mindestens einem Bogen) mit "Nur einfache Gefaellestrecken..." ab - Grund war nicht fehlende Technik, sondern dass gf-linienzug-modus schlicht keine Edit-XDATA schrieb (anders als Modus 1/2 ueber SSG_GF_EDIT).

Neue XDATA-App SSG_GF_LZ (gf-lz-xdata-schreiben/-lesen in Lisp/Gefaellestrecke.lsp) sichert die Segmentliste (Typ/hz/Laenge/Winkel/Seite je Segment, bereits laengenfertig) + den Baustartpunkt - Serialisierung per gf-segmente->string/gf-string->segmente, Chunking ueber die bestehenden ssg-sepliste-chunk-string/-split-feld/-explode-chars-Helfer aus ssg_ks_insert.lsp (wiederverwendet statt dupliziert).

Neue Funktion gf-linienzug-rebuild: baut die Kette am selben Startpunkt neu, AS-/EIN-Element und Gefaellewinkel bleiben ueber dieselben zwei Dialoge wie beim Bauen editierbar (gf-dialog-linienzug-aus-ein/-winkel, jetzt mit prefill-Parameter fuer den Edit-Fall statt Defaults) - die Segmentlaengen/-form selbst nicht (dafuer bleibt GEFAELLESTRECKE_LINIENZUG als Neubau). c:GEFAELLESTRECKE_EDIT dispatcht vor der bisherigen TYP-Sperre: Streckengruppe MIT SSG_GF_LZ-XDATA -> neuer Rebuild-Pfad, Streckengruppe OHNE (Altbestand/VF-Kombi) -> bleibt wie bisher abgewiesen. Alter Block wird erst NACH erfolgreichem Neuaufbau geloescht.

doc/variofoerderer.md um den Edit-Ablauf ergaenzt.

Manuell in BricsCAD getestet (Doppelklick auf Linienzug-Streckengruppe, beide Dialoge vorbelegt, Neuaufbau, erneuter Doppelklick auf das Ergebnis) - laeuft.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-09 13:16:55 +02:00
m.stangl a9cdc127d9 [CHANGE] GEFAELLESTRECKE_LINIENZUG: AS/ES-Auswahl und Gefaellewinkel per Dialog statt Konsole (Teil B der GUI-Umstellung)
Zwei neue Dialoge (dcl/gefaellestrecke.dcl, Lisp/Gefaellestrecke.lsp):
- gf-dialog-linienzug-aus-ein: AUS-/EIN-Element Winkel+Seite in EINEM Dialog, ersetzt die vier fruehen Konsolenfragen. Muss vor der Segmentlaengen-/Winkelberechnung laufen (haengt von AS-/ES-Masse ab), darum eigener, fruehzeitiger Dialog.
- gf-dialog-linienzug-winkel: zeigt den automatisch aus der Segmentkette berechneten Gefaellewinkel-Vorschlag ueberschreibbar, mit kurzer Segment-Zusammenfassung und dem bereits gewaehlten AS/ES-Paar nur noch zur Kontrolle (disabled). Ersetzt zugleich die SPAETERE finale Einfuegen-Bestaetigung - nach der rein automatischen AS/ES-Korrekturschleife waere eine zweite Rueckfrage redundant.

Objektauswahl (ssget LINE/ARC) und Start-/Endpunktwahl bleiben bewusst Zeichnung/Konsole. Rueckfall auf die alten Konsolenfragen bleibt erhalten, wenn ein Dialog nicht gezeigt werden kann/darf (GUI aus); ein bewusster Dialog-Abbruch bricht dagegen den ganzen Befehl ab statt auf Konsole zurueckzufallen - neu im Vergleich zum alten Verhalten, aber konsistent mit vfc_eingabemodus/vfs_nachruesten_hz aus Teil A/C.

doc/variofoerderer.md (Abschnitt 4) aktualisiert und um einen bebilderten Beispiel-Walkthrough ergaenzt (gf-linienzug1-3.png: Ausgangslinie, Dialog mit Vorschlagswinkel, fertige Strecke neben der Original-Linie).

Manuell in BricsCAD getestet (vollstaendiger Lauf inkl. Abbruch in beiden Dialogen) - laeuft.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-09 12:22:53 +02:00
m.stangl 57bb1e9057 [CHANGE] VARIOFOERDERER_NACHRUESTEN: Baurichtung per Dialog statt Konsole (Teil C der GUI-Umstellung)
Neuer Dialog vfs_nachruesten_hz (dcl/variofoerderer.dcl) + vfs-dialog-nachruesten-hz (Lisp/vf_standard.lsp) ersetzt den fruehren getreal-Prompt. Zeigt pro unmarkiertem VF_n-Fund Blockname/erkannten Typ und ein hz-Feld, vorbelegt mit dem zuletzt eingegebenen Wert (identisches Default-Fortpflanzungs-Verhalten wie vorher).

"Abbrechen" im Dialog uebernimmt bewusst nur den Vorgabewert fuer DIESEN Fund (Rueckgabe 'ABBRUCH), statt die ganze Nachruesten-Schleife abzubrechen oder auf die Konsole zurueckzufallen - echter Konsolen-Rueckfall bleibt ausschliesslich fuer den Fall, dass der Dialog gar nicht gezeigt werden kann (GUI abgeschaltet). Die Objektauswahl (ssget) selbst bleibt unveraendert Zeichnung/Konsole.

doc/variofoerderer.md um den Befehl ergaenzt (war dort bisher gar nicht erwaehnt).

Manuell in BricsCAD getestet (unmarkierter VF_4-Block, Dialog erscheint, hz=0 markiert) - laeuft.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-09 11:59:18 +02:00
m.stangl 9a7907ab00 [CHANGE] VF Standard/Etage 3D-Linie-Eingabemodus per Dialog statt Konsole (Teil A der GUI-Umstellung)
Neuer Dialog vfc_eingabemodus (dcl/variofoerderer.dcl) + vfc-dialog-eingabemodus-waehlen (Lisp/vf_core.lsp), analog zum bestehenden vfc_typ-Muster: Radio-Buttons "3D-Linie auswaehlen" / "Werte manuell eingeben" ersetzen die fruehere getstring-Konsolenabfrage in vf-dialog-ablauf. Betrifft StandardVarioFoerderer3D und EtageVarioFoerderer3D (beide rufen denselben Ablauf).

Die 3D-Linie-Objektauswahl selbst (vfc-3dlinie-erfassen) bleibt bewusst Zeichnung/Konsole - eine Linie laesst sich nicht durch ein Formularfeld ersetzen. Alle daraus abgeleiteten Werte (deltaL/deltaH/hz/Einfuegehoehe) gehen als Prefill in den bereits bestehenden Basis-Dialog (variofoerderer_basis), der sie ueberschreibbar anzeigt - identisch zum "Werte manuell"-Pfad.

Rueckfall auf die alte Konsolenabfrage bleibt erhalten (GUI abgeschaltet, DXFM_LANG=en_GB), wie bei vfc_typ. doc/variofoerderer.md (Abschnitt 2, 8, Entscheidungsbaum) und CLAUDE.md entsprechend aktualisiert.

Manuell in BricsCAD getestet (StandardVarioFoerderer3D + EtageVarioFoerderer3D, beide Dialogzweige inkl. Abbruch) - laeuft.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-09 11:38:15 +02:00
m.stangl 2ef8f319ab [FIX] vf_linienzug_modus1_anleitung.md: Fragen-Tabelle und Stufe-2-Zahlen an aktuelle Testdatei angepasst
tests/testdata/linienzug_tests_stufe2.json hat sich seit Erstellung des Dokuments geaendert (62 statt 57 Eingabe-Eintraege, zusaetzliche Separator-Vor/Nach-Fragen, Kettenende-Frage vor statt nach der Gefaelle-Berechnung). Fragen-Tabelle in Abschnitt 3 komplett neu durchnummeriert und mit den tatsaechlichen JSON-Kommentaren abgeglichen.

Stufe-2-Ergebnis war veraltet: GF2=86mm/VF=286mm ersetzt durch die tatsaechlichen GF2=319mm/L_VF=48mm aus der Datei; Hoehenrest-Beispielrechnung in Abschnitt 5.a entsprechend angepasst.

Fehlerhafter Fakt in Abschnitt 5.c korrigiert: linienzug_tests.json hat ebenfalls erwartung_dx_mm=638 (nicht dY=637 wie behauptet) - beide Testfaelle zeigen denselben dX-Versatz.

Code-Fakten verifiziert und unveraendert korrekt: Winkeltabelle 3/6/9/12/15/18/21/27/33/39/45/51 Grad (data/json/component_defaults.json), *vfk-feste-horizontal-kettenende*=800mm, *vfl-gf-min-laenge*=400mm, vfl-winkel-stufe-entscheidung/berechne-alle-winkel/berechne-horizontale-mitte/vfl-loesche-seit/vfl-modus-abbruch-sichern existieren alle weiterhin, TEST_LINIENZUG_STUFE2 liest weiterhin linienzug_tests_stufe2.json.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-09 11:02:35 +02:00
m.stangl 5aed90dd56 [CHANGE] doc/plan und doc/todo angelegt, interne Analyse-/TODO-Dokumente dorthin verschoben
doc/todo/: TODO-plan-vf-interactive.md -> plan-vf-interactive.md, TODO-modus2-achsenweise-bilanz.md -> modus2-achsenweise-bilanz.md (offene Fahrplaene/TODOs).
doc/plan/: KS-Frame-Architektur.md, vf-parameter-struct-analyse.md, translate.md, Entwicklungsplan.md (Architektur-Analysen und Planungsdokumente, kein Anwender-Material).

Alle internen Verweise (CLAUDE.md, Lisp/README.md, README.md, doc/variofoerderer.md, Lisp/vf_spec.lsp, lib/dxf_vf_abbild.py, lib/vf_spec_export.py, tests/test_hm_recformat.lsp, tests/test_vf_geometrie.py, tests/test_vf_headless_statisch.py) auf die neuen Pfade angepasst. Reine Pfad-Updates in Kommentaren/Docstrings, keine funktionale Aenderung - Python-Syntax nach dem Umbau geprueft.

Anwender-/Entwickler-Referenzdoku (faq.md, kommandos.md, tools.md, dbg2lsp.md, csv-export.md, json-input-lisp.md, lisp_methods.md, LispTests.md, variofoerderer.md, vf_linienzug_modus1_anleitung.md) bleibt direkt in doc/.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-09 10:56:54 +02:00
m.stangl fe4637d7df [FIX] doc/tools.md: veraltete Item-Zahlen korrigiert, Aufruf vereinheitlicht; set_coords.bat Copy-Paste-Kommentar behoben
Datenbasis (data/json/omniflo_*.json) hat sich seit der letzten Doku-Pflege verschoben: Boegen 27->29, Delta 1->7, Sternweiche 1->2, Dreifachweiche 6->0 (Typ aktuell nicht mehr in den Daten vorhanden), Gesamt 107->110. Schalter/Filterkriterien selbst (SWITCH_FILTERS in lib/omniflo_utils.py) sind unveraendert und weiterhin korrekt dokumentiert.

set_koords-Aufruf im Dokument auf bin\set_coords.bat vereinheitlicht (war inkonsistent zu set_einfuegepunkt.bat, das korrekt den bin\-Wrapper nennt).

bin/set_coords.bat trug noch den Kopfkommentar von set_einfuegepunkt.bat (Copy-Paste-Fehler) - korrigiert auf den tatsaechlichen Zweck (K1-K4 setzen).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-09 10:51:12 +02:00
m.stangl b0322a4f3c [CHANGE] Batch-Wrapper fuer dxf_anlage_export.py, dxf_scan_components.py, dxf_vf_abbild.py
Drei neue bin/*.bat nach dem bestehenden Pass-Through-Muster (setenv.bat + python ... %*, siehe set_einfuegepunkt.bat/dbg2lsp.bat), damit diese lib/-Skripte wie die uebrigen Python-Kommandozeilen bequem ueber bin/ aufrufbar sind. doc/kommandos.md Abschnitt 3 ergaenzt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-09 10:47:23 +02:00
m.stangl aaf47ab3c1 [CHANGE] JSON-Testdaten-Feldnamen aus dxf_anlage_export.py in lib/testdata_schema.py zentralisiert
dxf_anlage_export.py und dxf_scan_components.py fuehrten dieselben Feldnamen (abstand, deltaL_mm, as_seite, ...) aus doc/json-input-lisp.md unabhaengig als lose String-Literale - ein Tippfehler oder eine Schema-Aenderung in nur einer Datei waere nicht aufgefallen. Neues Modul lib/testdata_schema.py buendelt die Feldnamen/festen Werte der dokumentierten Schemas (Kreisel, Einzelblock, VF Standard/Etage, Gefaellestrecke Modus 1) als benannte Konstanten; dxf_anlage_export.py nutzt sie jetzt durchgaengig.

dxf_scan_components.py bewusst NICHT mitumgebaut: deutlich grösser/komplexer, mit zusaetzlichen Sonderfaellen (z.B. "startpunkt"/"gerade"-Form), ein vollstaendiger Umbau haette den Rahmen dieser Aenderung gesprengt und mehr Risiko als Nutzen gehabt.

Verhaltensgleich: alle 9 Tests in tests/test_dxf_anlage_export.py laufen weiterhin gruen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-09 10:43:09 +02:00
m.stangl 1e7e2c6349 [DOC] kommandos.md, faq.md, json-input-lisp.md: fehlende Eintraege ergaenzt
kommandos.md: lib/dxf_anlage_export.py fehlte in der Python-Kommandozeilen-Liste.
faq.md: FAQ-Eintrag fuer QcLinieMitGf/QcLinieMitGfUForm ergaenzt (bisher nur stichwortartig in der Gefaellestrecke-Liste erwaehnt, nirgends erklaert).
json-input-lisp.md: tests/testdata/showroom_ils.json fehlte in der Testdaten-Uebersicht (Abschnitt 9), obwohl TEST_SHOWROOM_ILS dokumentiert ist.

Alle anderen Befehle/Dateien/Testdaten in den drei Dokumenten gegen den aktuellen Code-Stand geprueft und bestaetigt aktuell.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-09 10:34:20 +02:00
m.stangl d0ec791bf8 [DOC] VF-Doku: erledigte TODOs nachgetragen, toten Link entfernt
TODO-plan-vf-interactive.md: TEST_HUNDM05 laeuft inzwischen aktiv in tests/alltests.json (kein disabled mehr), Status-Kopf und S1-Zeile entsprechend aktualisiert.
vf_linienzug_modus1_anleitung.md: Verweis auf nicht existierende doc/VarioFoerderer_Linienzug_Prinzipien.md entfernt.

Geprueft, unveraendert gelassen (noch zutreffend): doc/variofoerderer.md, doc/vf-parameter-struct-analyse.md, doc/TODO-modus2-achsenweise-bilanz.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-09 10:30:02 +02:00
m.stangl a670db839e [CHANGE] VarioFoerderer Standard/Etage: 3D-Linie-Eingabemodus laeuft jetzt ueber den bestehenden Basis-Dialog statt komplett interaktiv auf der Konsole
Die Linie wird weiterhin gepickt (vfc-3dlinie-erfassen, aus vf-eingabe-abfragen herausgezogen), liefert aber deltaL/deltaH/Richtung/Einfuegehoehe/Fahrtrichtung nur noch als Prefill fuer vfs-dialog-eingabe-basis - Seite/Motorseite/Darstellung/Geruest bleiben wie bisher ueber die GUI einstellbar. c:VarioFoerderer dispatcht Standard/Etage dadurch immer in vfs-standard-dialog-ablauf/vfe-etage-dialog-ablauf; der alte rein konsolenbasierte Fallback-Pfad (Schritte 3-11, vf-eingabe-abfragen) ist als toter Code entfernt. Dead-Code-Aufraeumung: 35 nur noch vom entfernten Pfad genutzte Sprachschluessel aus lang/de_DE.json + lang/en_GB.json entfernt (Paritaet geprueft).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-08 16:01:56 +02:00
m.stangl a6f6fcb575 [CHANGE] VF-Standard-Dialog: Geometrie-Reihenfolge angepasst (deltaL+Foerderrichtung, Einfuegehoehe+deltaH), Seite/Motorseite nebeneinander; nur Seite/Motorseite/Geruestoption bleiben Radio-Buttons, Rest wieder Combobox; Winkel/Verteilung-Dialog komplett auf Combobox zurueckgebaut (keine Radio-Variante mehr noetig)
[CHANGE] VF-Linienzug-Wizard: horizontale Kurve (GF-Bogen/Vario-Kurve) direkt nach explizit eingefuegtem AS-Element ausgegraut, da dort zuerst ein gerades Segment folgen muss

[ADD] doc/faq.md: Antworten zu VF/GF-Kombinationsfragen ergaenzt (Puffer-Umschleusung, Zielhoehe, Etagenfoerderer, Streckenueberbrueckung) + Screenshot gf-vf-kombination.png

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-08 14:42:17 +02:00
m.stangl 823dc6728d [CHANGE] Streckengruppe-Menue in Werte-manuell/Zielhoehe/Stueckweise aufgeteilt, QC-Linien unter Gefaellestrecke verschoben, Linienzug-Wizard "Naechstes Element" neu sortiert (GF vor VF) mit eigenem Abschliessen-Knopf statt Kettenende-Radio
Lisp/vf_core.lsp: fuenf eigene Menue-Wrapper (LinienzugVarioFoerdererManuell/-Zielhoehe/-Stueckweise, QcLinieMitGf/-UForm) ersetzen den alten interaktiven Modus-Dialog; vfc-dialog-linienzug-modus-waehlen entfaellt.
dcl/vf_linienzug_wizard.dcl + Lisp/vf_linienzug.lsp: "Neue Linie BIS Kettenende" ist kein Radio mehr, sondern eigener Button "OK und Abschliessen" neben "Ok Weiter"; GF-Optionen stehen vor VF-Optionen.
Menue (SSG_LIB.mnu/.cui), lang/*.json, doc/kommandos.md, doc/lisp_methods.md, doc/faq.md nachgezogen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-08 12:44:36 +02:00
m.stangl 46afb33b0b [ADD] Kreisel-Drehrichtung (DREHRICHTUNG) per JSON steuerbar: kreisel-insert-script bekommt optionalen 6. Parameter drehrichtung (GUZ/UZS), hundm05:bau-kreisel liest ihn aus dem Testdaten-JSON aus. Showroom ILS: Kreisel_Showroom_02/03/05 GUZ, Kreisel_Showroom_01/06 UZS eingetragen. Doku (lisp_methods.md, json-input-lisp.md) nachgezogen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-07 20:55:58 +02:00
s.ayadi d403c23e5b Merge remote-tracking branch 'origin/master' 2026-10-07 15:01:22 +02:00
s.ayadi 4d0d689815 [ADD] Nachbau ILS-3.0-Showroom: tests/testdata/showroom_ils.json aus Showroom_ILS_3_0.dxf (6 Kreisel, 11 Gefaellestrecken, Separatoren/Scanner; Hoehen noch Platzhalter), Treiber tests/test_showroom_ils.lsp (TEST_SHOWROOM_ILS, Menue Tests -> ILS 3.0 Showroom), in alltests.json bis zu den Hoehen deaktiviert; [ADD] dxf_scan_components.py: --flach (waagrechte Staustrecken mit AS an genau einem Ende als GF), --kreisel-achse (Kreisel ohne AN8/SP8, z.B. Schleifen mit Weichenboegen), zerstueckelte Staustrecken-Linien werden vereint, ES am unteren Ende wird erkannt und verbraucht, AS/ES-Seite ohne Seitenangabe im Namen aus der Lage zur Fahrtrichtung, Kurznamen AE-*/EE-*; [FIX] Kreisel-Paarung: zwei Kreisel auf derselben Achse wurden ueber die Luecke gepaart (800 + 12832 statt 9033 + 3000) - Tausch-Nachbesserung auf minimale Abstandssumme; [CHANGE] test_dematic_arvato.lsp: Lauf als dematic_arvato:bau-datei herausgeloest (vom Showroom-Treiber mitgenutzt); [ADD] Tests in test_dxf_scan_gf.py
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 15:00:45 +02:00
m.stangl 0d8d803c36 Merge branch 'master' of https://gitea.schoenenberger.de/Schoenenberger_Systeme_GmbH/dxfmakros 2026-10-07 11:41:45 +02:00
m.stangl fcb4444ee1 [ADD] Block- und Text-Werkzeuge aus Walz (ACADSST) uebernommen
Neue Module ssg_blocktools.lsp (SSG_BLOCK_COUNT, SSG_BLOCK_DELETE,
SSG_ATTR_ERSETZEN) und ssg_texttools.lsp (SSG_TEXT_ERSETZEN,
SSG_TEXT_PARALLEL, SSG_TEXT_HOEHE, SSG_TEXT_STIL) sowie der generische
Eingabe-Wrapper ssg_input.lsp, dazu Menue-/Lade-Integration,
zweisprachige Texte und Unit-Tests fuer die reinen Kerne.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-07 11:40:11 +02:00
s.ayadi f1583d2d41 [ADD] doc/kommandos.md: Kommandouebersicht (BricsCAD-Befehle, Test-Befehle, bin-Skripte, Python-Kommandozeilen, pytest); [CHANGE] menu/SSG_LIB.cui: MenuMacro-UIDs von BricsCAD neu nummeriert
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 17:08:16 +02:00
m.stangl 2f9cb7eaed Merge branch 'master' of https://gitea.schoenenberger.de/Schoenenberger_Systeme_GmbH/dxfmakros 2026-10-06 11:18:35 +02:00
m.stangl 7290a13607 Doku erste Fassung erstellt 2026-10-06 11:17:28 +02:00
s.ayadi 36b6fdb650 [ADD] doc/json-input-lisp.md: JSON-Eingabeformate je Element (Kreisel, Einzelbloecke, VF Standard/Etage, GF Modus 1-3, VF-Linienzug Spec/Journal, Omniflo, gerade) aus tests/testdata mit Feldern, Koordinaten-Bezug und Bau-Routine - ersetzt das geloeschte tests/testdata/object_data.md; [ADD] doc/lisp_methods.md: Uebersicht der LISP-Bau-Routinen je Einheit (Befehl + skriptfaehiger Kern, Signaturen, Rueckgaben, Voraussetzungen, Einfuegeprimitiven)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 17:05:13 +02:00
s.hensch b56fc58cf6 [ADD] FAQ hinzugefügt 2026-10-02 08:56:44 +02:00
s.ayadi 1e6b152d72 export: jeden Wert nur an einer Stelle setzen (ZUORDNUNG, sepliste-IDs, Typen, K1/K2)
- ZUORDNUNG: ssg-id-check-all laeuft jetzt ZUERST, danach sind die
  Wrapper-IDs endgueltig - Separator-Kopien, AS/ES- und Einheiten-Marker
  bekommen ZUORDNUNG direkt beim Erzeugen. Entfallen:
  csv:sep-proxies-zuordnung-setzen, csv:asmark-ids-setzen,
  csv:unitmark-ids-setzen. zuordnung_fix/*cs-sep-fix-by-handle* bleibt
  (count_sep_scan rechnet eigenstaendige Sensoren bewusst neu).
- sepliste-IDs: Zuordnung ueber die KS-Kettenfolge je Typ
  (csv:sepliste-kette-paare) statt ueber die teils gespiegelten
  sepliste-Koordinaten (csv:sepliste-paare, csv:sepliste-ids-setzen
  entfallen). Die Kette wird je Lauf einmal berechnet (csv:kette-von);
  die ID liest csv:block-to-json erst beim Schreiben. Behebt vertauschte
  TrackIds/Nachbarn in HundM05 VF_1 (0031/0029).
- Element-Klassifizierung: eine Tabelle csv:element-familien (cfg-Muster)
  fuer Suche und Klassifizierung; csv:proxy-typ entfaellt.
- Einheiten-Marker: K1/K2 nur noch in *csv-baustein-by-handle*
  (csv:geometrie-merken), K1/K2-Attribute und
  csv:unitmark-k-kos-strings entfallen.

Geprueft: HundM05-Export alt/neu headless verglichen - einzige Abweichung
ist die korrigierte Reihenfolge in VF_1. LISP-Unit-Tests 303/303.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:10:16 +02:00
s.ayadi e67f7cc1aa export: Separator-Typ VF/GF aus der Ketten-Einheit statt Bau-XDATA
Der Typ (Merkmal "Typ") jeder Separator-Zeile kommt jetzt an EINER Stelle
aus der Einheiten-Schneidung csv:kette-einheiten (neu: csv:kette-sep-typen,
eingetragen in csv:ketten-verarbeiten) - dieselbe Quelle wie die
Einheiten-Boundingbox. VF = Separator direkt vor der Umlenkstation bzw.
zwischen Umlenk- und Motorstation, sonst GF.

Die bauzeitige XDATA SSG_SEP_TYP (ssg-sep-typ-xdata-schreiben/-lesen,
15 Einfuegestellen) entfaellt. Sie war teils falsch: der Separator vor dem
ES hinter einer Motorstation bekam "VF", und ein sep_nach-Separator einer
GF, den die folgende VF-Einheit als Einlauf nutzt, blieb "GF"
(HundM05: Sep1/5/7/9/11 und Sep2).

Unit-Tests csv:kette-sep-typen in tests/test_unit.lsp.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:23:27 +02:00
m.stangl 96ca43eff5 export: Hilfskopien nach dem Export loeschen, IDs stabil ueber reservierte IDs
AS/ES-Marker werden wie alle Hilfskopien geloescht (ausser csv_leave_proxies). IDs von AS/ES, Separator-Kopien und Einheiten bleiben ueber reservierte IDs (XDATA SSG_ID_RES) am VF_n/GF_n-Wrapper stabil: AS|n/ES|n, K|i, U|n.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:14:02 +02:00
m.stangl 394d476d56 export: Kettenbausteine ueber KS verketten, Einheiten neu gruppieren
K1/K2 und Boundingbox je Export-Zeile folgen jetzt dem echten
Kettenbaustein statt seinem Stellvertreter:
- Separator (all_elements): KS + bbox des 300-mm-Trennstegs statt des
  Sensor-Symbols; separator_track/group_vf_gf behalten das Symbol
- AS/ES (all_elements, group_vf_gf): KS + bbox des AS-/ES-Elements statt
  des 200x200-Markers ohne K
- gemeinsamer Kern csv:ks-welt-punkte; VF/GF-Wrapper-K1/K2 = K1 des AS
  bzw. K2 des ES

Gruppierter Export neu (sepliste-/XDATA-Algorithmus entfernt):
- Bausteine je Wrapper als Vektorkette K2 -> K1 ordnen (Start am AS)
- Foerdereinheit = Separator vor der Umlenkstation bis Motorstation,
  alles dazwischen Gefaelleeinheit (csv:kette-einheiten, Unit-Tests)
- je Einheit ein temporaerer Proxy mit 3D-Boundingbox, K1/K2, Laenge und
  Anzahl Boegen; wird nach dem Export geloescht (ausser csv_leave_proxies)
- IDs neuer Export-Objekte entlang der Kette AS -> ES aufsteigend

Weiteres:
- ssg-make-layer ohne _LAYER-Befehl fuer bestehende Layer (Konsole)
- einheitliche, zweisprachige Meldungen fuer behaltene Hilfskopien
- bin/show_exportcsv.bat: Export-CSV als Boundingbox-SVG (sps_skel)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 20:25:29 +02:00
s.ayadi ab3958e0e4 export_csv: AS/ES direkt aus ZZ_ASES_MARKER klassifizieren, Kreisel<->Strecke-Kollisionserzeugung entfernen
Stufe 2 (Python-Seite von "sepliste: Bauteil-IDs eintragen"): AS/ES-Kettenenden
sind jetzt ganz normale Items, direkt aus dem dauerhaften ZZ_ASES_MARKER
klassifiziert (TeileId/Position/Boundingbox vom Marker-Block selbst) - keine
Kollisionsberechnung mehr, die sie erfindet.

- lib/export_neighbors.py: compute_strecke_kreisel_schleus entfernt (suchte
  bisher per Kollisionstest den anschliessenden Kreisel und erzeugte dabei bei
  JEDEM Export eine neue TeileId fuer denselben physischen Punkt). AUSSCHLEUS_/
  EINSCHLEUS_TEILEART sind jetzt Teil von KREISEL_UMLAUF_TEILEARTEN - ein AS/ES
  bringt seine eigene Bounding-Box vom Marker mit und wird dadurch, wie jeder
  freie Separator, ueber die normale BBox-Ueberschneidung einem Kreisel
  zugeordnet; die gesonderte "naechster Kreisel per sep_kette"-Suche in
  compute_kreisel_umlauf (dessen sep_kette-Parameter damit entfaellt) ist
  ueberfluessig geworden. compute_sep_kette gibt je Eintrag zusaetzlich das
  Feld "id" weiter (Bauteil-TeileId, siehe vorheriger Commit).
- lib/export_csv.py: process_blocks klassifiziert ZZ_ASES_MARKER direkt (TYP-
  Attribut waehlt Ausschleus-/Einschleuselement); build_strecke_schleus_items
  entfaellt komplett. map_separator_kette_items -> map_sepliste_kette_items:
  ordnet jetzt AS/SEP/ES exakt per ID-Gleichheit zu (sepliste-Feld "id" gegen
  die TeileId der klassifizierten Items) statt per Koordinaten-Naehe - SEP
  faellt bei fehlendem "id"-Feld weiterhin auf den alten Naehe-Abgleich zurueck
  (Altbestand), AS/ES ohne "id" bleiben unaufgeloest.
- Neu: pruefe_ases_in_beiden_containern prueft am Ende von process_blocks, ob
  jede AS-/ES-Zeile sowohl in den TrackIds ihrer eigenen Strecke als auch in
  denen mindestens eines Kreisels auftaucht, und traegt bei Abweichung eine
  Warnung ein (Spalte "Warnungen") - Konsistenzpruefung fuer genau die beiden
  "Container", zu denen ein AS/ES gehoert.
- Aufgeraeumt (tote Routinen): _strecke_ends, _closest_pt_on_segment,
  _distinct_kreisel_ids (nur von den entfernten Funktionen genutzt), sowie der
  temporaere Diagnose-Filter DEBUG_HIGHLIGHT_TEILEIDS/dbg_highlight (an die
  jetzt behobene Koordinaten-Matching-Ambiguitaet gebunden, in seinem eigenen
  Kommentar bereits als Wegwerf-Code markiert). LISP-seitiger Dead-Code-Scan
  (export.lsp, ssg_ks_insert.lsp - die diese Woche bearbeiteten Module):
  keine Funde.

Verifiziert an den echten HundM05-Daten (results/export_raw.json, 45 Bloecke):
TeileId-Bereich luecken- und duplikatfrei 1-45 (vorher 1-55 mit Luecke 24-33 +
Zusatz-IDs 46-55), alle 10 AS/ES-IDs korrekt in ihrer Strecke UND im Kreisel
06 TrackIds, keine Warnungen der neuen Pruefung. Zwei Testdateien auf die neue
Architektur umgestellt (test_export_kreisel_umlauf.py: AS/ES als Item statt
Kollisions-Erzeugung, neue Klasse TestAsEsImKreiselUmlauf fuer die BBox-
Teilnahme; test_export_separatorliste.py: id-basierte Zuordnung, Klasse
TestMarkerIdWiederverwendung durch TestMapSeplisteKetteItemsFallback ersetzt
- die alte testete inzwischen entfernte Mint-Logik). Volle Suite: 224 bestanden
(4 vorbestehende, unabhaengige Fixture-Failures unveraendert).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 14:48:45 +02:00
s.ayadi 618ff3d86c sepliste: Bauteil-IDs eintragen, AS/ES ueber dauerhaften Marker sichtbar machen
Stufe 1 (LISP-Export-Pfad): export_raw.json enthaelt jetzt fuer jeden
sepliste-Eintrag (AS/SEP/ES) einer VF_n/GF_n-Kette die ID des realen
Bauteils, das ihn vertritt.

- csv:sep-proxies-erzeugen (Separatoren) und die neuen AS/ES-Marker teilen
  sich csv:nested-welt-records/csv:block-einfuegen-welt zur Platzierung.
- csv:sepliste-paare ordnet sepliste-Eintraege ihrem Bauteil exklusiv nach
  Abstand zu (kuerzester zuerst, dann verbraucht) statt "jeder Eintrag
  nimmt sich das naechste" - ein einzelner fehlerhafter Koordinatenwert
  (bekannter Bug: gespiegeltes x bei lfdnr=2) verschiebt dadurch keine
  andere Zuordnung mehr.
- Neu: ZZ_ASES_MARKER - ein kleines Rechteck an jedem AS/ES-Kettenende,
  das nach dem Export STEHEN BLEIBT (anders als die temporaeren
  Separator-Kopien). Macht das sonst unsichtbare, in der Wrapper-
  Blockdefinition verpackte Kettenende in BricsCAD sichtbar/anklickbar
  und traegt seine ID unsichtbar am Attribut ID - dadurch behaelt ein
  AS/ES seine TeileId ueber Exportlaeufe hinweg. Wird bei jedem Export
  neu aufgebaut (Lage folgt der Kette), Wiederfund ueber ZUORDNUNG+TYP+
  LFDNR, verwaiste Marker werden entfernt.

In BricsCAD verifiziert (5 HundM05-Ketten, zwei Exportlaeufe: gleiche
Marker-IDs, korrekte sepliste-"id"-Felder). Dabei einen realen Bug
gefunden und behoben: die Blockdefinition des Markers uebernahm ueber
einen ungefilterten entnext-Walk versehentlich auch die Attribute des
zuletzt eingefuegten Blocks (VF_5 verlor dadurch alle Attribute inkl.
ID) - jetzt auf LWPOLYLINE/ATTDEF gefiltert.

9 neue zeichnungsfreie Unit-Tests (csv:sepliste-paare/*, csv:asmark-
finden/*, csv:proxy-typ/*), 4 neue de/en-Textschluessel (Paritaet
geprueft). bin\run_tests.bat --lisp: 257/257 bestanden.

Noch nicht enthalten (Stufe 2, Python): map_separator_kette_items nutzt
das neue "id"-Feld noch nicht, build_strecke_schleus_items synthetisiert
AS/ES-Zeilen weiterhin selbst statt die exportierten zu lesen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 13:09:05 +02:00
m.stangl 350c294717 doc: Umbauplan Modus-2-Solver achsenweise Laengen-Bilanz
Diagnose + Umbauplan fuer die U-Form-Abweichung im Modus-2-Solver als
doc/TODO-modus2-achsenweise-bilanz.md festgehalten (mit dem Entwickler zu
besprechen, noch nicht umgesetzt). Enthaelt: Symptom (test_modus2.dxf),
praezise Ursache (skalare climber-span statt achsenweiser Bilanz, Fundstellen
9990/10070), Beleg als dokumentiertes v1-Limit, 5-Etappen-Umbauplan mit
Regressionsnetz zuerst, Risiko-Einschaetzung und Zwischenloesung (abweisen).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-09-18 17:35:45 +02:00
m.stangl 1d082ccde7 feat: Eingang/Ausgang-Symbole als eigene CSV-Zeile + in TrackIds
Die Materialfluss-Ein-/Ausgangssymbole (Bloecke Eingang_<DIM>/Ausgang_<DIM>,
eingefuegt ueber ils-insert-station) erscheinen jetzt NUR im CSV-Export als
eigene TeileArt-Zeile ("Eingang"/"Ausgang", Merkmale wie BTMT). Wie
Separator/AS/ES nehmen sie als freie Umlauf-Punkte (KREISEL_UMLAUF_TEILEARTEN)
an der TrackIds-Spalte teil und tauchen so auch auf Kreiseln auf, auf deren
Bahn sie liegen. Der Sivas-Export schliesst sie bewusst aus.

- cfg/export.cfg: pattern_eingang/pattern_ausgang
- Lisp/export.lsp: csv:collect-export-blocks sammelt beide Muster
- Lisp/ssg_id.lsp: ssg-id-collect-blocks erfasst sie (ssg-id-check-all fuellt
  das nachgetragene ID-ATTDEF, dokumentiert in data/ils/allocations.json)
- lib/export_csv.py: Klassifikations-Zweige Eingang/Ausgang
- lib/export_neighbors.py: KREISEL_UMLAUF_TEILEARTEN um Eingang/Ausgang erweitert
- lib/export_sivas.py: Eingang/Ausgang uebersprungen (kein Sivas-Eintrag)
- Tests: test_export_eingang_ausgang.py + Kreisel-Umlauf-Test

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-09-16 11:55:57 +02:00
m.stangl c171bc44d6 docs: CSV-Export-Doku in doc/csv-export.md ausgelagert und mit Beispiel ergaenzt
Der lange Docstring in lib/export_csv.py wandert nach doc/csv-export.md
(inkl. durchgerechnetem Beispiel Kreisel+VarioFoerderer), der Docstring
verweist nur noch darauf.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-14 12:59:44 +02:00
y.wang 23d653c4b3 feat: VF-Linienzug Linie-GF - Separator VOR/NACH, Endpunkt/Zielhoehe-Vorwahl, steigende GF (Sonderfall bis 3 Grad)
Auf der neuen Kollegen-Architektur (Stufe 0-2: Spec/Journal/Replay-System
in vf_spec.lsp, Frage-Schale/Bauteil-Trennung) neu aufgebaut, nachdem der
urspruengliche Stand (Commit e76e24e) auf einer aelteren Basis beruhte und
per Rebase-Analyse als eigenstaendige, unabhaengige Erweiterung erkannt
wurde (der Kollege hat nichts entfernt - diese Features existierten vorher
nur lokal uncommitted).

Drei Erweiterungen fuer "Neue Linie: GF" in vf-linienzug-modus:
- Separator VOR/NACH direkt vor bzw. nach der Gefaellestrecke einfuegbar.
- Aeussere Vorwahl "Wie soll die Laenge bestimmt werden?": Endpunkt waehlen
  (bisheriges Verhalten) oder Zielhoehe zuerst festlegen (Winkel wird
  daraus berechnet).
- Dritte Option "Steigende GF" (Sonderfall, 0 bis 3 Grad): erlaubt eine GF,
  die statt zu fallen steigt. Neuer Helfer vfl-bogen-uebergang erkennt
  anhand der tatsaechlichen Frame-Neigung, ob 0/1/2 Uebergangsboegen
  (Vario_Bogen_auf_3/ab_3) noetig sind, und baut sie automatisch - im
  Normalfall (fallend->fallend) ein No-Op.

Lisp/vf_spec.lsp (Kollegen-Spec/Headless-Bau-System) um die drei neuen
Felder (laenge_modus/sep_vor/sep_nach/steigend_modus) erweitert, mit
Defaults, die alte Specs unveraendert lassen - haelt die "Spec-Pfad ==
interaktiver Pfad"-Invariante seines Systems (TEST_HUNDM05/VF_SPEC_BAU)
intakt. tests/test_vf_spec.lsp entsprechend mit neuen Testfaellen ergaenzt.

Neuer Regressionstest TEST_LINIENZUG_STUFE2 (linienzug_tests_stufe2.json)
sowie Anleitung doc/vf_linienzug_modus1_anleitung.md aus dem urspruenglichen
Commit uebernommen; die Gefaelle-Hoehe/Winkel-Optionsreihenfolge im
Testdatensatz an die jetzt geltende (Kollegen-)Konvention angepasst.

Offen (bewusst zurueckgestellt): lib/vf_spec_export.py (Python-Vorwaerts-
Emitter, Pendant zu vf_spec.lsp) noch nicht nachgezogen - siehe Folge-Commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:18:31 +02:00
m.stangl 47724fcfe2 TrackIds von VF/GF-Strecken um AS-/ES-Kettenenden ergaenzt
write_separatorliste_merkmale liess bisher nur "SEP"-Eintraege der
sepliste in die "TrackIds"-Spalte einfliessen; die AS-/ES-Ausschleus-
/Einschleuselemente an Anfang und Ende der Kette fehlten dadurch,
obwohl sie beim Kreisel (compute_kreisel_umlauf) bereits Teil von
dessen TrackIds sind. Jetzt werden alle sepliste-Eintraege (AS, SEP,
ES) in Baureihenfolge aufgeloest.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 15:18:55 +02:00
m.stangl b577b7ad69 doc: CSV-Header und Testliste in csv-export.md ergaenzt
Explizites CSV-Spalten-Layout (inkl. der neuen "TrackIds"-Spalte) und
die neuen/erweiterten Testdateien (Bezeichnung-Attribut, BTMT im
Kreisel-Umlauf, 0-Grad-Start) nachgetragen - inhaltlich war die Doku
bereits aktuell, es fehlte nur die konkrete Kopfzeile und der
Test-Ueberblick.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 15:13:06 +02:00
m.stangl 28dc3b4301 list_trackids aus Merkmalen in eigene CSV-Spalte "TrackIds" verschoben
Statt eines JSON-Merkmals bekommen VF_n/GF_n/Kreisel jetzt eine eigene
CSV-Spalte "TrackIds" (nach "Nachbarn", vor "Fehler") mit der Reihenfolge
der Separator-/BTMT-/AS-ES-/Weichen-TeileIds entlang der Strecke bzw. um
den Kreisel - analog zur bestehenden "Nachbarn"-Spalte statt versteckt im
Merkmale-JSON. Referenz-CSV fuer den Omniflo-Test an den neuen Header
angepasst.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 15:07:31 +02:00
m.stangl 3c0900a02b CSV-Bezeichnung von VF/GF/Kreisel/Eckrad nutzt Anwender-Attribut statt nur Nummerierung
Die Spalte "Bezeichnung" verwendet jetzt das in BricsCAD frei editierbare
Attribut "Bezeichnung" des Blocks, falls gesetzt - sonst wie bisher die
generierte Standardbezeichnung ("VarioFoerderer :3" usw.). Damit laesst
sich ein in der Zeichnung umbenanntes Element im CSV-Export wiedererkennen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 14:52:03 +02:00
m.stangl bfd95ea725 Kreisel-Separatorliste (list_trackids) im CSV-Export ergaenzt
Kreisel bekommen wie VF_n/GF_n ein Merkmal mit der Reihenfolge aller
Separator-/BTMT-Beladung-/BTMT-Entladung-TeileIds entlang der Bahn,
sortiert nach Winkel um die Kreiselachse (Start bei 0 Grad in
Drehrichtung DREHRICHTUNG) - nutzt dieselbe Umlauf-Logik, die bisher
nur die "Nachbarn"-Spalte gespeist hat. Merkmal-Schluessel einheitlich
auf "list_trackids" umbenannt (vorher "Separatorlist" bei VF/GF).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 14:41:25 +02:00
m.stangl 332bd24ab0 doc: CSV-Export-Ablauf dokumentiert (LISP-Sammlung + Python-Nachbarschaftslogik)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 09:43:40 +02:00
s.ayadi b66c4e5dae update mubea with BTMT information 2026-09-07 15:38:39 +02:00
s.ayadi b812e99140 Merge remote-tracking branch 'origin/master' 2026-09-04 09:25:46 +02:00
s.hensch 15ec6c0504 [ADD] Layerdefinitionen und Farben durch layer.cfg für zusammengesetzte Blöcke wie Gefällestrecke oder Varioförderer werden beim Zusammenbau der Baugruppen in den Skripten verwendet; Ebenfalls als Fallback für Blöcke möglich, die kein Attribut LAYER besitzen. 2026-09-04 09:01:12 +02:00
s.ayadi e91f1d00d0 [REFACTOR] Stufe 2: VF-Eingang/-Ausgang getrennt + Regressionsnetz fuer die Geometrie
Der CAD-Lauf belegt die Schritte 0-4 jetzt auch EMPIRISCH:
results/test_hundm05.dxf entstand nach dem Umbau, das Ergebnis-JSON von
11:18 davor - fuer alle 5 Ketten sind ALLE 37 Attribute identisch,
inklusive der reihenfolgeabhaengigen Komma-Listen L_VF_m, L_GF_m, GF_WINKEL
und ANTRIEBFAHRTRICHTUNG. TEST_VF_SPEC: 28 PASS / 0 FAIL.
results/test_linienzug.dxf zeigt eine vollstaendige Kette (AS+ES, Motor,
Umlenkung, 2 Vario-Kurven, 22 Bausteine, HOEHE_VON = HOEHE_BIS = 4500 bei
DELTA_H 0).

Schritt 5a/5b - vfl-vf-eingang-bauen und vfl-vf-ausgang-bauen: beide Bloecke
(GF1 + Einlauf-Separator + Umlenkstation bzw. Motorstation + GF2) enthalten
keine Frage und sind zusammenhaengend, der Umzug ist wortwoertlich
(Zeilenvergleich: 0 Zeilen entfernt, nur zwei Koepfe, zwei Aufrufe und zwei
"frame)" neu). Die Auswahl gf2-eff (ziel-gf2 im Kettenende-Modus, sonst
L_GF2-bau) bleibt BEWUSST an der Aufrufstelle - genau dort entsteht sonst
still die falsche GF2 hinter dem Motor. Der Separator-Zaehler und die
vfl-acc-*-Aufrufe bleiben an derselben Stelle in derselben Reihenfolge.

Regressionsnetz, damit die restlichen Schritte nicht blind gemacht werden
muessen:
- lib/dxf_vf_abbild.py (neu): liest eine Testzeichnung streamend und bildet
  je Kette Attribute, Bausteinzusammensetzung und Einfuegepunkt ab. Ketten
  werden ueber den EINFUEGEPUNKT der Spec zugeordnet, nicht ueber den
  Blocknamen - die VF-Nummer beginnt in jeder neuen Zeichnung wieder bei 1.
  ID und Bezeichnung sind aus dem Vergleich heraus (pro Zeichnung neu).
  --referenz vergleicht (Exit 1 bei Abweichung), --schreibe-referenz frischt
  die Referenz nach einem GEPRUEFTEN Lauf auf.
- tests/reference/hundm05_attribute.json (neu): die Referenz, erzeugt aus dem
  geprueften Lauf - also dem Stand, der attributgleich mit dem Zustand VOR
  dem Umbau ist.
- tests/test_vf_geometrie.py (neu, 8 Tests): vergleicht automatisch, mit
  einem eigenen Test nur fuer die Komma-Listen (das einzige, was eine
  vertauschte vfl-acc-*-Reihenfolge sichtbar macht) und einer Gegenprobe,
  dass eine verfaelschte Referenz auch erkannt wird.

Das faengt, was der Ergebnis-Record NICHT sieht: er sagt "executed, kein
Prompt, Journal aufgegangen", aber nichts darueber, ob dieselbe Geometrie
herauskam. Ablauf ab jetzt pro Schritt: umbauen -> TEST_HUNDM05 (save dxf)
-> pytest tests/test_vf_geometrie.py.

Offen bleiben 5c, 6, 8, 9, 10 (Schleifenrumpf der VF-Einheit, Daten-Executor,
Einheit-Abschluss, Kettenebene je Glied, vfl-spec-ausfuehren). Die vier
haengen zusammen: 6 und 10 brauchen den aufgeteilten Schleifenrumpf. Halb
umgebaut waere der Code schlechter dran als vor oder nach dem Umbau, darum
als ein Schritt mit CAD-Lauf davor und danach.

Verifiziert: 117 pytest-Tests gruen, vf_linienzug.lsp lint-sauber.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 14:10:56 +02:00
s.ayadi 02303ad7fc [REFACTOR] Stufe 2, Schritte 0-4: Frage-Schale und reinen Bauteil trennen
Alle Aenderungen sind verhaltensgleich: die Frage-Schalen behalten ihre
Namen, keine Aufrufstelle in Modus 1/2/3 wurde angefasst.

Schritt 0 - vfl-ziel-report: der Soll-Ist-Vergleich am Kettenende stand
zweimal WORTGLEICH in vfl-vf-einheit-abschluss (einmal fuer "Kettenende ohne
ES", einmal "mit ES"); die Faelle unterscheiden sich nur darin, wann sie
melden, nicht was.

Schritt 1 - Winkelwahl aufgeteilt: vfl-winkel-gueltige (Kandidaten filtern)
und vfl-winkel-nach-index (Kandidat waehlen) sind rein; die Frage-Schale
vfl-waehle-winkel setzt sie zusammen. Neuer Vorgabe-Kanal
*vfl-winkel-idx-vorgabe*: ist er gesetzt, wird nicht gefragt. Kanal statt
Parameter, weil vfl-waehle-winkel aus vier Solvern gerufen wird
(vfl-vf-winkel, vfl-vf-entscheidung, vfl-body-zerlegung,
vfl-segment-entscheidung) - ein Parameter wuerde vier Signaturen und alle
deren Aufrufer aendern. Default nil, also heute ohne Wirkung.

Schritt 2 - vfl-es-masse-setzen: reines Globals-Setzen (ES-Winkel merken +
vf-set-es-masse) aus vfl-frage-es-seite gezogen. *vfl-es-winkel* wird LAZY
von den Blocknamen-Bauern gelesen und muss vor dem ersten ES-Insert stehen.

Schritt 3 - vfl-hor-koerper-bauen: die drei Fragen (Separator vor/nach,
Endpunkt) haengen an keinem berechneten Wert und stehen jetzt alle vor dem
Bau. Journal-Reihenfolge UND Entity-Reihenfolge bleiben identisch; nur
interaktiv erscheint der auf_3-Uebergangsblock erst nach den drei Fragen
statt zwischen Frage 1 und 2. Die dL-Subtraktionskette wurde Zeile fuer Zeile
uebernommen - jeder Schritt ist mit (max *vfk-restlaenge-min-clamp* ...)
geklammert, also nicht kommutativ, und der auf_3-Insert sitzt bewusst
zwischen Subtraktion 1 und 2 (sein Fussabdruck wird GEMESSEN). Nachweis:
Zeilenvergleich alt/neu, dieselben 15 geometrie-relevanten Zeilen in
derselben Reihenfolge.

Schritt 4 - vfl-body-abschluss-bauen: hier laesst sich NICHT alles vorab
fragen (vfl-neue-linie-messen braucht den Frame nach vfl-nach-3grad, die
Hoehenvorschlaege brauchen dL und die Kettenhoehe). Die Schale macht darum
3-Grad-Abschluss -> messen -> Vorschlaege -> Zielhoehe fragen, der reine Teil
beginnt bei der Zerlegung. Nachweis: Multiset-Vergleich der Zeilen, ausser
Kopf, Klammer und Aufruf ist keine Zeile veraendert.

Schritt 7 (Assertion-Teil) - vsp-journal-diff in Lisp/vf_spec.lsp: stellt das
aus der Spec erzeugte Journal Token fuer Token gegen das beim Bau neu
aufgezeichnete. Schaerfster Desync-Detektor - offene Queue-Werte und die
Glied-Folge zeigen nur grobe Abweichungen, ein einzelner Wert, der an der
falschen Stelle verbraucht wird, kann beide passieren lassen und trotzdem
andere Geometrie erzeugen. Neues Record-Feld journal_diff, neuer Test
test_journal_token_gleich.

Zwei bewusste Abweichungen von der Planung (begruendet in
doc/TODO-plan-vf-interactive.md, Abschnitt "Umsetzungsstand Stufe 2"):
vfl-hor-koerper-bauen behaelt ziel-modus als eigenen Parameter neben
ende-code (ende-code darf nil sein, die Separator-Subtraktionen haengen aber
allein am Ziel-Modus); vfl-body-abschluss-bauen braucht letzt-hz und
es-gewuenscht nicht.

Offen: Schritte 5, 6, 8, 9, 10. Das sind die, bei denen die Reihenfolge
selbst Geometrie ist - der Fahrplan verlangt nach jedem einen CAD-Lauf
(TEST_HUNDM05 + TEST_VF_SPEC + TEST_LINIENZUG), nach den Geometrie-Schritten
zusaetzlich DXF-Diff und Sivas-Export-Vergleich. Ohne Lauf zwischen den
Schritten waere ein Fehler nicht mehr einem Schritt zuzuordnen. Sie bringen
keine neue Faehigkeit: der Bau aus Daten laeuft seit Stufe 1 und ist mit
VF_SPEC_BAU belegt (5 OK, 0 Fehler).

Verifiziert: 109 pytest-Tests gruen, beide .lsp lint-sauber, kein neuer
alert/get*/ssget im Bau-Pfad (statischer Waechter).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 12:14:27 +02:00
s.ayadi 5902343352 [CHANGE] Nur noch EIN Test baut die HundM-Geometrie: Spec wird TEST_HUNDM05
Nach dem gruenen VF_SPEC_BAU-Lauf bauten zwei Tests dieselben 5 Ketten. Der
Spec-Pfad ist jetzt der routinemaessige Bau-Test, der Aufzeichnungs-Pfad der
abgeschaltete Regressionstest fuer das Journal-Format.

Umbenennungen:
- tests/testdata/vf_spec_hundm05.json -> tests/testdata/hundm05.json
  Die Spec ist das Eingabeformat und die Datei, in der weitere Ketten der
  Anlage nachgetragen werden. spec_ids jetzt VF_hundm05_LZ_* (wie im
  Aufzeichnungs-Protokoll), damit sich die Ergebnisse beider Laeufe paaren
  lassen.
- tests/testdata/hundm05.json -> tests/testdata/hm_recformat.json
  tests/test_hundm05.lsp -> tests/test_hm_recformat.lsp (TEST_HM_RECFORMAT,
  Praefix hmrec:, Export hm_recformat:export-results)
  tests/test_hundm05.py -> tests/test_hm_recformat.py
  In alltests.json auf "disabled": true.

Neu: tests/test_hundm05.lsp (TEST_HUNDM05) baut die Spec - OHNE eigene
Bau-Logik, es ruft vsp-bau-datei aus Lisp/vf_spec.lsp. Damit gibt es genau
einen Code-Pfad, der aus einer Spec Geometrie erzeugt; c:VF_SPEC_BAU nutzt
denselben. tests/test_hundm05.py prueft das Ergebnis (die 9 Tests, die
vorher in test_vf_spec.py standen); test_vf_spec.py ist jetzt reiner
Uebersetzer-Test ohne CAD.

Warum das Aufzeichnungsformat bleibt (Details in
doc/TODO-plan-vf-interactive.md Abschnitt 4.7):
- hm_recformat.json ist die EINZIGE eingecheckte Kopie der Originaldaten
  (data/polylines.dxf ist mit 124 MB per .gitignore ausgeschlossen). Die Spec
  ist daraus abgeleitet; ohne die Aufzeichnung faellt die rechte Seite des
  Rundlauf-Beweises weg.
- Es prueft eine ANDERE Invariante: das Journal kommt roh aus der XDATA einer
  Kundenzeichnung. TEST_HM_RECFORMAT ist damit der einzige Test dafuer, dass
  ein BESTEHENDER VF_n-Block weiter abspielbar ist - also dass
  Doppelklick-Edit und 2D/3D-Konvertierung an Altbestand funktionieren. Ein
  spec-gebautes Journal kann das nicht zeigen, es kommt aus dem Uebersetzer.
- Es dokumentiert die Frage-Reihenfolge (kommentar je Eintrag); die Spec
  verbirgt den Dialog, das ist ihr Zweck.

Weitere Anpassungen:
- Ergebnisdatei heisst nach der Spec-Datei (<basisname>_results.json), damit
  Befehl und Testrunner in dieselbe Datei schreiben. Verzeichnis: tests/output
  (Override DXFM_VF_SPEC_OUT); NICHT DXFM_RESULTS - das sind die Sivas-/
  CSV-Exporte, dort landete die Datei ausserhalb des Testbaums.
- Neu *vsp-dim-override* fuer TEST_HUNDM05_2D/_3D: wird je Kette angewandt,
  weil der Abbruch-Handler in vf-linienzug-modus *ssg-ils-dim* zurueck setzt.
- Das Anlagenkuerzel der test_id in lib/vf_journal_export.py kam aus dem
  Namen der Ziel-JSON. Nach der Umbenennung haette eine Regenerierung die ids
  stillschweigend auf VF_hm_recformat_LZ_* geaendert und die Paarung der
  beiden Laeufe zerlegt - jetzt feste Konstante TEST_ID_ANLAGE.
- conftest: hundm05_* Fixtures -> hmrec_* (die Spec-Fixtures stehen in
  tests/test_hundm05.py).

Verifiziert: 98 pytest-Tests gruen (die 9 Ergebnis-Tests warten auf einen
neuen TEST_HUNDM05-Lauf), alle .lsp lint-sauber, Spec-Regenerierung
idempotent, TEST_VF_SPEC in BricsCAD 28 PASS / 0 FAIL.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 11:11:12 +02:00
s.ayadi 428f1ced70 [FEAT] VF-Linienzug aus Eingabedaten bauen (Stufe 1: Spec -> Journal -> Replay)
Stufe 1 des Fahrplans in doc/TODO-plan-vf-interactive.md, fertig fuer
Modus 1. Eine SPEC beschreibt eine Kette in Domaenenwerten ("links",
"winkel", "aussen", ja/nein) statt in Menue-Codes; vsp-journal uebersetzt sie
in ein Eingabe-Journal, vsp-bau-aus-spec spielt es per
vfl-journal-replay-start durch den UNVERAENDERTEN vf-linienzug-modus. Der
fertige Block traegt damit dasselbe SSG_VF_EDIT-Journal wie eine handgebaute
Kette und bleibt per Doppelklick editier- und 2D/3D-konvertierbar - kein
Journal-Konsument muss etwas von Specs wissen.

CAD-Lauf VF_SPEC_BAU: 5 OK, 0 Fehler. Je Kette status "executed",
prompts 0 (keine Live-Eingabe erreicht), eingaben_offen 0, keine
Spec-Fehler, keine Bau-Meldungen, glieder_ist == glieder_soll,
Einfuegepunkt gleich dem Kettenstart der Spec.

Neu:
- Lisp/vf_spec.lsp: Code-Tabellen, Emitter vsp-journal, Validierung
  vsp-pruefen, flacher JSON-Loader, Headless-Rahmen vsp-headless-an/-aus,
  Ergebnis-Record, vsp-bau-aus-spec/-liste, c:VF_SPEC_BAU. Von vf_core.lsp
  NACH vf_linienzug.lsp geladen - damit sind beide Ladewege abgedeckt (Menue
  und der .scr-Loader), das MNL bleibt unveraendert.
- lib/vf_spec_export.py: derselbe Emitter in Python PLUS die Umkehrung
  (spec_aus_journal), erzeugt die Spec-Testdaten.
- tests/testdata/vf_spec_hundm05.json: die 5 echten Ketten als Spec,
  erzeugt statt handgeschrieben.
- tests/test_vf_spec.lsp (C:TEST_VF_SPEC, in alltests.json): 7 Faelle je
  Glied-Typ, 7 Validierungsfaelle, Gruppieren, und die 5 echten Ketten gegen
  ihr aufgezeichnetes Journal.
- tests/test_vf_spec.py: 36 Tests (Rundlauf, Spec-Daten, Validierung,
  Erwartungswert-Abgleich, Ergebnisse von VF_SPEC_BAU).

Drei Regeln, die der Uebersetzer besitzen muss - jede wuerde sonst die ganze
Replay-Queue verschieben:
- Der Menue-Code haengt am Frame: erste Sektion 4 Optionen (kein GF-Bogen,
  es gibt noch keine Richtung), jede spaetere 5.
- hz steht genau EINMAL im Journal, beim ersten Segment (vfl-in-abstand
  journalisiert die Richtung nur bei freier Richtungswahl).
- Nur ein HORIZONTALER Erstkoerper einer VF-Einheit stellt die Separator-/
  Endpunktfragen vorab (winkel1=0 laeuft durch vfl-baue-horizontal-koerper);
  ein gewinkelter wird ohne jede Frage gebaut.

Wie die Richtigkeit belegt ist - drei Implementierungen derselben Grammatik,
die einander pruefen:
- Rundlauf gegen echte Daten: journal_aus_spec(spec_aus_journal(tok)) == tok
  fuer alle 5 HundM-Ketten, tokenweise numerisch verglichen. Damit ist
  bewiesen, dass die Spec das Journal verlustfrei abbildet.
- Der Weg, den LISP nimmt (flaches JSON -> Spec -> Journal), ergibt separat
  geprueft dieselben Journale wie das aufgezeichnete Protokoll.
- Der unabhaengige Dekoder aus lib/vf_journal_export.py verdaut alle 7
  synthetischen Emitter-Ausgaben restlos, auch die zwei Zweige, die in den
  echten Daten fehlen (Linie-VF, gewinkelter Erstkoerper).
- Die Erwartungswerte im LISP-Test kommen aus dem geprueften Python-Emitter;
  TestLispErwartungen liest sie zurueck und vergleicht erneut. Ohne das
  koennte ein Uebertragungsfehler einen falschen Erwartungswert
  festschreiben und der CAD-Lauf waere gruen, obwohl der Emitter falsch
  liegt.

Abweichungen von der Planung (Begruendungen in doc/TODO-plan-vf-interactive.md
Abschnitt 4.6): vsp-pruefen ruft den Emitter statt eine zweite Regelmenge zu
pflegen; das vollstaendige Journal steht nicht im Record (statt dessen
glieder_soll/glieder_ist als Desync-Detektor); Zusatzfeld segment_typ am
Glied "Linie", weil dort vfl-segment-entscheidung selbst zwischen GF und VF
waehlt; vf_ende-Werte "automatisch"/"zielpunkt-ohne-es" fuer die Faelle ohne
Frage; Praefix vsp- statt vfs- (das gehoert vf_standard.lsp).

Zusaetzlich:
- tests/test_vf_headless_statisch.py prueft jetzt auch, dass
  Lisp/vf_spec.lsp UEBERHAUPT keine Eingabe-/Dialogfunktion aufruft - beim
  Daten-Pfad ist die Null die Vorgabe.
- tests/testdata/mubea.json: die drei einzeln eingefuegten S-LP-Separatoren
  entfernt (Fortsetzung von 699744e - die Separatoren stecken jetzt in den
  Staustreckenbloecken).

Noch offen: die Uebersetzer fuer Modus 2 und 3. Modus 2 braucht laut
Fahrplan erst 2-3 echte "linienzug2"-Journale als Referenz -
tests/testdata/hundm05.json enthaelt ausschliesslich Modus-1-Ketten.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 10:44:38 +02:00
s.ayadi ba01455d52 [FEAT] VF-Linienzug ohne GUI/Konsole baubar (Stufe 0) + hundm05-Testfall
Ziel: eine VF_n-Kette soll aus einem Stapel Eingabedaten gebaut werden
koennen - ohne Dialog, ohne Konsolenfrage. Fahrplan und Begruendungen in
doc/TODO-plan-vf-interactive.md. Alle Aenderungen sind No-Ops, solange
*ssg-gui-aus* und *vfl-headless* nil sind.

Produktion (Lisp/vf_linienzug.lsp, Lisp/vf_core.lsp):
- vfl-journal-reset im Dispatcher VOR die Modus-cond gezogen. Bisher nur im
  Modus-1-Zweig: ein frischer Modus-2-Lauf erbte das Journal des Vorlaufs und
  schrieb es in die XDATA, ein spaeterer Doppelklick spielte fremde Eingaben
  vor.
- Lokale Variable "member" in vf-linienzug-modus2 umbenannt. Sie verdeckte im
  selben Scope das Builtin member, das weiter unten gebraucht wird - jedes
  Kletterer-Segment waere in "bad function" gelaufen.
- Neu vfl-meldung: sammelt den Text nach *vfl-meldungen* + dbgmsg und zeigt
  ihn nur bei erlaubter GUI modal, sonst per princ. Die 12 Bau-Pfad-alerts
  darauf umgestellt; ein Alert blockierte sonst jeden Batch-Lauf, und sein
  Text ist die einzige Auskunft, WELCHE Sektion abgewiesen wurde. Die reinen
  Interaktiv-Alerts (fehlendes DCL, "nicht editierbar", "kein Journal")
  bleiben alert.
- Neu *vfl-headless* (+ vfl-headless-p/-abbruch/-notausgang/-ort, Diagnose
  *vfl-headless-fehler*, optionaler Antwort-Hook *vfl-headless-antwort-fn*):
  eine erschoepfte Replay-Queue ist damit ein harter Abbruch MIT Fundstelle
  (Art der Eingabe, Glied- und Eingabe-Nummer) statt eines stillen Rueckfalls
  auf Live-Eingabe. Eingebaut in vfl-in-value, vfl-in-value-p,
  vfl-in-selection und vfl-in-abstand.
- vfl-journal-reset loescht Meldungen und Diagnose mit (gehoeren zum Lauf);
  vfl-view-refresh ueberspringt headless _PLAN/_ZOOM.

Testfall HundM05 (5 echte Ketten aus data/polylines.dxf):
- tests/testdata/hundm05.json neu erzeugt aus den XDATA-Journalen der
  VF_n-Bloecke (lib/vf_journal_export.py) - flach, weil ssg-load-json
  zeilenweise liest. Die drei kopierten Ketten bekommen ihren echten
  Einfuegepunkt, nicht das veraltete HOEHE_VON-Attribut.
- tests/test_hundm05.lsp arbeitet jetzt per Journal-Replay statt mit
  Eingabe-Mocks: ein echtes Journal fuehrt die geerbte Fahrtrichtung nicht mit
  (vfl-in-abstand journalisiert hz nur beim ersten Segment), ein Mock kann sie
  also nicht kennen. Schaltet *vfl-headless* ein und schreibt prompts,
  headless_fehler und meldungen ins Ergebnis-JSON.
- Kettenschleife fangt je Kette: ein Fehler NACH dem Bau nimmt nicht mehr die
  restlichen Ketten mit.
- entprev gibt es in AutoLISP nicht (nur entnext/entlast) - die Suche nach dem
  fertigen Block laeuft vorwaerts ab dem Zeichnungsstand vor dem Bau. Dieselbe
  Falle in tests/test_mubea.lsp mitbehoben; sie schlug dort nie zu, weil
  entlast immer sofort traf.

Absicherung ohne CAD:
- tests/test_vf_headless_statisch.py: eingechecktes Inventar aller
  alert/get*/ssget/new_dialog-Fundstellen je Funktion (ein neues getreal in
  einer Bau-Funktion faellt auf, auch wenn sein Zweig im Test nie erreicht
  wird), Praesenz des Riegels in allen vier Wrappern, Diagnose-Reset und die
  Reset-Reihenfolge im Dispatcher. Dazu ein Waechter gegen erfundene
  AutoLISP-Funktionen (entprev u.a.) - diese Fehlerklasse kostet sonst jedes
  Mal einen CAD-Lauf.
- tests/test_hundm05.py prueft zusaetzlich prompts == 0, keine
  Headless-Abbrueche und keine Bau-Meldungen.

tests/alltests.json: hundm05-Zeile laedt VarioFoerderer (nicht KreiselInsert)
und bleibt bis zu einem gruenen CAD-Lauf abgeschaltet.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 10:14:31 +02:00
s.ayadi 04a12e5981 [FIX] VF-Linienzug: Abbruch beim Editieren brach den VF-Block auf
Die interaktiven Editier-Pfade riefen den Neuaufbau ueber
vl-catch-all-apply auf. Der alte Block ist dort per entdel schon
entfernt, und der Catch faengt einen Abbruch (ESC -> (exit)) VOR
*error* ab - der Abbruch-Wickler vfl-modus-abbruch-sichern kam damit
nie zum Zug. Ergebnis: die komplette Kette blieb als lose Einzelteile
ohne VF_n-Block liegen und war nicht mehr per Doppelklick editierbar.

- vfl-edit-ent (Sektions-Zweig) und vfl-edit-ent2 rufen
  vf-linienzug-modus/-modus2 jetzt DIREKT auf. Nur der
  nicht-interaktive Batch-Konverter vfl-konvertiere-ent behaelt den
  Catch (die Batch-Schleife muss weiterlaufen) und meldet den
  betroffenen Block statt still zu scheitern.
- Beide Abbruch-Handler setzen *ssg-ils-dim* zurueck. Das tat bisher
  nur der Aufrufer, der nach einem Abbruch nicht mehr erreicht wird -
  der Dim-Override blieb fuer die restliche Sitzung stehen.

Wiederherstellung aus der Zeichnung (Sektions-XDATA):

- vfl-segment-xdata-sichern schrieb nur die Slice des LETZTEN Glieds
  einer Schleifen-Iteration. Eine VF-Einheit mit eingebetteten
  Vario-Kurven verlor dadurch ihre eigenen Eingaben. Jetzt wird der
  komplette Journal-Abschnitt der Iteration geschrieben, indiziert mit
  dem ersten Glied-Index darin (neu: vfl-journal-ab-glied,
  vfl-steps-zaehlen). Ein Glied ohne Geometrie verbraucht seinen
  Abschnitt nicht mehr - er wandert in den naechsten Record, der
  Entities bekommt.
- Neue XDATA-App SSG_VF_EDIT_PRE haelt die Praeambel (Startpunkt,
  Starthoehe, AS ja/nein + Winkel/Seite) auf den Entities der ersten
  Iteration. Ohne sie fehlte der Kopf des Journals in jeder Sektion.
- Neuer Befehl VF_SEKTION_RESTORE: Auswahl der losen Geometrie ->
  Sektionen lueckenlos ab Glied 1 zusammensetzen -> stummer Replay ->
  interaktiv weiterbauen. Die alte Geometrie wird erst NACH
  erfolgreichem Neuaufbau geloescht, ein Abbruch laesst sie samt XDATA
  stehen (Versuch wiederholbar). Altbestand ohne Praeambel-XDATA wird
  danach gefragt.

Die .dbg-Dateien bleiben reine Ausgabe und werden von keinem Befehl
gelesen - Wiederherstellungs-Daten gehoeren in die XDATA der Zeichnung.

tests/testdata/vfl_journal_hm05_abbruch.json: Journal der Session vom
2026-08-31 (9 Glieder), gegen das die Slice-/Join-Logik geprueft wurde.
Reine Daten, wird von keinem Befehl gelesen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 15:15:16 +02:00