# Fremdbestandteile Der LSA-Planer hat **keine Laufzeitabhängigkeiten** im Sinne von `package.json`: Der Abschnitt `dependencies` ist leer, und das Installationspaket enthält kein `node_modules`. Fremder Code steckt trotzdem in dem, was ausgeliefert wird – an zwei Stellen: als Laufzeit (Electron mit Chromium und Node.js) und als Bibliotheken, die Vite in den Renderer hineinübersetzt. Dieses Verzeichnis hält fest, **was das ist**, unter welcher Lizenz es steht, woher es kommt und wozu das Programm es benutzt. **Das ist keine Rechtsauskunft.** Es wird hier auch nicht behauptet, mit dieser Aufstellung seien die Pflichten aus den genannten Lizenzen erfüllt. Was dem Auslieferungsstand beiliegt, steht unten unter „Was dem Paket beiliegt"; wo die Urheber- und Genehmigungsvermerke stehen und was davon offenbleibt, unter „Was aussteht" – und beides steht dort, weil es gemessen ist, nicht weil es vermutet wird. Stand: Fassung 5.43.2, am gebauten Stand gemessen am 18.09.2026 und am Neubau vom 19.09.2026 nachgemessen. Was an installierten Paketen und an früheren Auslieferungsständen gemessen ist, stammt vom 07.09.2026 und steht unverändert – ein ausgeliefertes Paket ändert sich nicht mehr. Wie, steht unter „Wie das ermittelt wurde". --- ## Was ausgeliefert wird und was nicht `package.json` führt jspdf, jspdf-autotable und electron unter `devDependencies`. Das ist keine Auskunft über die Auslieferung, sondern über die Installation: Beim Anwender wird kein `npm install` gefahren, deshalb steht dort alles beisammen. Was tatsächlich ins Paket geht, entscheidet nicht diese Einordnung, sondern - der Abschnitt `build.files` in `package.json` – er bestimmt, was in `app.asar` wandert: `build/**` ohne die Quellkarten, die Symbole und `package.json`, - der Abschnitt `build.extraFiles` – er legt sechs Dateien unverpackt neben die Programmdatei: zwei zu den Fremdbestandteilen (siehe „Was dem Paket beiliegt"), dazu `LICENSE` und `LICENSE.de.txt`, die Lizenz des Programms selbst, `QUELLCODE.txt`, der Vermerk nach Artikel 3 der EUPL, und `LIESMICH.txt`, das Blatt für den Empfänger – die vier letzten nicht Gegenstand dieses Verzeichnisses, - was Vite in `build/renderer/assets/*.js` hineinübersetzt hat – dort liegt der fremde Code, nicht mehr als Paket, sondern als Teil der Ausgabedateien, - und electron-builder, der die Laufzeit aus `node_modules/electron/dist` daneben legt. Die Trennung unten folgt deshalb dem Bauergebnis, nicht der Einordnung in `package.json`. --- ## Die Laufzeit Electron liefert Chromium und Node.js mit. Beide werden nicht gebündelt, sondern als Programmdatei und Bibliotheken neben die Anwendung gelegt. | Bestandteil | Fassung | Lizenz | Herkunft | Wofür | | --- | --- | --- | --- | --- | | Electron | 44.3.0 | MIT | https://github.com/electron/electron | Fenster, Menü, Dateidialoge, Hauptprozess; Trennung von Renderer und System | | Chromium | 152.0.7977.78 | BSD-3-Clause und weitere | https://www.chromium.org | Darstellung der Oberfläche; Druckausgabe | | Node.js | 24.20.0 | MIT und weitere | https://nodejs.org | Hauptprozess: Dateizugriff, der eine Netzaufruf in `electron/karte.ts` | Chromium ist selbst ein Zusammenbau. Die Übersicht seiner Bestandteile liefert Electron mit: `LICENSES.chromium.html`, rund 19,5 MB, **780 Einträge** – von Abseil über die Schriftarten bis zu den Videocodecs. Sie liegt im Auslieferungspaket neben der Programmdatei und ist dort auch die einzige Stelle, an der diese Lizenztexte stehen. Dasselbe gilt für Electrons eigenen Text: `LICENSE.electron.txt`. **Die Einträge beschreiben den Quellbaum, nicht die Windows-Programmdatei.** Chromiums `licenses.py` erzeugt die Datei über alle Zielplattformen hinweg; was davon in einem Windows-Bau wirklich steckt, sagt sie nicht. Gemessen an der Übersicht aus Electron 33.4.11, mit der bis 5.25.0 ausgeliefert wurde (385 Einträge): **20** davon tragen eine reziproke Lizenz (GPL, LGPL, AGPL, MPL, EPL), ohne dass ihr Text daneben eine permissive Wahl anbietet – darunter `glibc`, `gtk`, `libsecret`, `libusbx`, `Speech Dispatcher`, `libbrlapi`, `v4l-utils`, `plasma-wayland-protocols` und `Android System SDK`, also Bestandteile anderer Betriebssysteme. **An der heutigen Übersicht mit 780 Einträgen ist diese Zählung nicht wiederholt.** Bis 5.42.1 stand sie hier als Messung am ausgelieferten Stand, obwohl die Laufzeit seit 5.26.0 eine andere ist. Nachgesehen ist am 17.09.2026 nur, welche der neun Namen die heutige Datei noch als Eintrag führt: acht; `Android System SDK` steht nicht mehr darin. Welche reziprok lizenzierten Einträge in `LSA-Planer Professional.exe` und den DLLs daneben tatsächlich gebunden sind, ist an dieser Datei **nicht** zu entscheiden; sie ist eine Aufstellung des Quellbaums. Was die Datei ihrerseits leistet: Sie nennt in ihrem Kopf den Ort, an dem der Chromium-Quellcode zu beziehen ist (`source.chromium.org`) – das ist die Angabe, die reziproke Lizenzen für die Weitergabe von Binärdateien verlangen. Node.js hat keine eigene Datei im Paket. Es steht als Eintrag „Node.js" in `LICENSES.chromium.html`, ebenso wie „V8 JavaScript Engine". --- ## In den Renderer gebündelt Alles hier steckt in `build/renderer/assets/*.js` und damit in `app.asar`. Als Paket ist keines davon im Auslieferungsstand vorhanden – nur sein übersetzter, verkürzter Code, und seit einer Berichtigung nach 5.13.0 sein Lizenztext als Kommentar am Anfang derjenigen Ausgabedatei, die diesen Code enthält – seit 5.14.0 auch im ausgelieferten Paket. Zwei davon binden wir selbst ein; die übrigen elf bringen die beiden mit. | Bestandteil | Fassung | Lizenz | Herkunft | Wofür | | --- | --- | --- | --- | --- | | `jspdf` | 2.5.2 | MIT | https://github.com/MrRio/jsPDF | Erzeugt die Planunterlagen als PDF (`src/services/export/pdf.ts`, `src/render/pdfSurface.ts`) | | `jspdf-autotable` | 3.8.4 | MIT | https://github.com/simonbengtsson/jsPDF-AutoTable | Tabellensatz im PDF: Zwischenzeitenmatrix, Signalgruppen- und Fundstellenverzeichnis | | `@babel/runtime` | 7.28.4 | MIT | https://github.com/babel/babel | Hilfsfunktionen, die jsPDF und canvg aus ihrer Übersetzung mitbringen | | `fflate` | 0.8.2 | MIT | https://github.com/101arrowz/fflate | Verdichtet die Inhaltsströme im PDF (jsPDF wird mit `compress: true` gerufen) | | `canvg` | 3.0.11 | MIT | https://github.com/canvg/canvg | Wahlweise Abhängigkeit von jsPDF für den `html()`-Weg – vom Programm nicht gerufen | | `core-js` | 3.46.0 | MIT | https://github.com/zloirock/core-js | Nachrüstungen, die canvg mitbringt | | `dompurify` | 2.5.8 | (MPL-2.0 OR Apache-2.0) | https://github.com/cure53/DOMPurify | Wahlweise Abhängigkeit von jsPDF für den `html()`-Weg – vom Programm nicht gerufen | | `html2canvas` | 1.4.1 | MIT | https://github.com/niklasvh/html2canvas | Wahlweise Abhängigkeit von jsPDF für den `html()`-Weg – vom Programm nicht gerufen | | `performance-now` | 2.1.0 | MIT | https://github.com/braveg1rl/performance-now | Zeitmessung, die raf mitbringt | | `raf` | 3.4.1 | MIT | https://github.com/chrisdickinson/raf | Bildfolgesteuerung, die canvg mitbringt | | `rgbcolor` | 1.0.1 | MIT OR SEE LICENSE IN FEEL-FREE.md | https://github.com/yetzt/node-rgbcolor | Farbwertzerlegung, die canvg mitbringt | | `stackblur-canvas` | 2.7.0 | MIT | https://github.com/flozz/StackBlur | Weichzeichner, den canvg mitbringt | | `svg-pathdata` | 6.0.3 | MIT | https://github.com/nfroidure/svg-pathdata | Pfadauswertung, die canvg mitbringt | Die Lizenzangabe ist wörtlich die aus dem `package.json` des installierten Pakets. Bei `rgbcolor` ist das keine gebräuchliche SPDX-Angabe: „MIT OR SEE LICENSE IN FEEL-FREE.md". **Hier stand, `FEEL-FREE.md` liege dem Paket nicht bei. Das ist falsch** – sie liegt in `node_modules/rgbcolor/`, fünf Zeilen lang, und ihr Inhalt entscheidet die Sache: Sie ist keine Lizenz mit Bedingungen, sondern ein formloser Freibrief („Feel free to use the code for your own color picker tool or whatever you feel like."). Von den beiden angebotenen Wegen ist MIT damit der einzige mit einem prüfbaren Wortlaut. **Für dieses Programm ist MIT gewählt**; die `LICENSE.md` des Pakets führt ihn, und ihr Wortlaut steht im Banner von `index.es-*.js` und in `DRITTANBIETER-LIZENZEN.txt`. **Zwei Einträge lassen eine Wahl, und sie ist getroffen.** Wo eine Lizenzangabe zwei Wege anbietet, entscheidet der Weitergebende, welchen er geht – und solange er es nicht sagt, muss ein Dritter vom strengeren ausgehen. Für dieses Programm ist gewählt: bei `dompurify` **Apache-2.0** (nicht MPL-2.0), bei `rgbcolor` **MIT** (nicht der formlose Freibrief der `FEEL-FREE.md`). Beide Male liegt der gewählte Wortlaut bei – bei DOMPurify sogar beide: Der Apache-Text und der MPL-Text stehen zusammen in seiner `LICENSE`, gehen als Ganzes in den Banner von `purify.es-*.js` und stehen ebenso in `DRITTANBIETER-LIZENZEN.txt`. Die Beilage trägt damit für beide Wege, unabhängig von der Wahl. DOMPurify führt keine `NOTICE`-Datei; Abschnitt 4 Buchstabe d der Apache-Lizenz läuft deshalb leer. **Neun der dreizehn werden im Betrieb nie geladen.** Beim Start holt `index.html` nur die eigene Ausgabedatei und `pdf-*.js`; darin stecken jspdf, jspdf-autotable, fflate und `@babel/runtime`. Alles übrige – canvg, core-js, dompurify, html2canvas, performance-now, raf, rgbcolor, stackblur-canvas, svg-pathdata – hat Vite in nachladbare Teildateien gelegt (`index.es-*.js`, `purify.es-*.js`, `html2canvas.esm-*.js`). Erreichbar sind sie allein über `jsPDF.html()`, und diese Methode ruft das Programm nirgends auf. Ausgeliefert werden sie trotzdem – sie liegen in `app.asar`. --- ## Nur zur Entwicklung Diese Pakete gehen **nicht** ins Auslieferungspaket. Sie stehen hier, damit die Aufstellung oben als vollständig gelesen werden kann, und nicht, weil sie Pflichten auslösen. `@eslint/js`, `@playwright/test`, `@types/node`, `@vitest/coverage-v8`, `electron-builder`, `esbuild`, `eslint`, `globals`, `jsdom`, `prettier`, `typescript`, `typescript-eslint`, `vite`, `vitest` – dazu ihr eigener Anhang. Sämtlich MIT, mit zwei Ausnahmen: `@playwright/test` und `typescript` stehen unter Apache-2.0. `electron` steht in beiden Listen: als Werkzeug beim Entwickeln und als Laufzeit im Paket. `jspdf` und `jspdf-autotable` stehen in `devDependencies`, gehören der Sache nach aber in die Aufstellung oben. --- ## Wie das ermittelt wurde Nicht aus dem Gedächtnis, sondern am Baum: - **Fassung und Lizenz** je Paket aus `node_modules//package.json`. Der Lizenztext liegt in aller Regel daneben (`LICENSE`, bei jspdf-autotable `LICENSE.txt`, bei performance-now `license.txt`, bei stackblur-canvas `LICENSE-MIT.txt`, bei rgbcolor `LICENSE.md`). - **Welche Pakete im Renderer landen**: aus den Quellkarten des gebauten Standes. `build/renderer/assets/*.js.map` führt in `sources` jede Ursprungsdatei; die Einträge unterhalb von `node_modules/` ergeben genau die dreizehn oben. Die Quellkarten selbst werden nicht ausgeliefert (`!build/**/*.map` in `build.files`). - **Ob der Urhebervermerk in der Ausgabedatei steht**: durch Suche nach dem Namen des Rechteinhabers in **derjenigen** Ausgabedatei, der die Quellkarte das Paket zuweist. Der Name stammt aus der Lizenzdatei des installierten Pakets, nicht aus einer Liste hier. - **Chromium und Node.js**: die Fassungen stehen als Zeichenkette in der Programmdatei `node_modules/electron/dist/electron.exe` (`Chrome/…`, `node.js/v…`); die Bestandteilübersicht ist `node_modules/electron/dist/LICENSES.chromium.html`. - **Was im Paket ankommt**: durch Nachsehen in `release/win-unpacked` und im Verzeichnisbaum von `resources/app.asar` eines am 19.09.2026 gebauten Standes 5.43.2. Neben der Programmdatei liegen dort acht Dateien: `LICENSE.electron.txt`, `LICENSES.chromium.html`, `DRITTANBIETER-LIZENZEN.txt` und `FREMDBESTANDTEILE.md` – dazu `LICENSE`, `LICENSE.de.txt` und `QUELLCODE.txt`, die Lizenz des Programms selbst und der Vermerk auf ihren Quellcode, sowie `LIESMICH.txt`, das Blatt für den Empfänger; die vier letzten sind nicht Gegenstand dieses Verzeichnisses. `DRITTANBIETER-LIZENZEN.txt` liegt außerdem unter `build/` im Verzeichnisbaum von `app.asar`. Im **ausgelieferten** Paket 5.14.0 lagen die beiden EUPL-Dateien noch nicht: Es ist vor dieser Änderung geschnürt worden. --- ## Was dem Paket beiliegt Neben der Programmdatei liegen vier Dateien zu den Fremdbestandteilen – drei mit Lizenztexten, dazu dieses Verzeichnis selbst – an derselben Stelle, dort, wohin electron-builder von sich aus seine beiden legt, und nicht an zwei: | Datei | Kommt von | Inhalt | | --- | --- | --- | | `LICENSE.electron.txt` | electron-builder, von sich aus | Electrons eigener Text | | `LICENSES.chromium.html` | electron-builder, von sich aus | Chromiums Bestandteilübersicht | | `DRITTANBIETER-LIZENZEN.txt` | `scripts/lizenztexte.mjs`, über `build.extraFiles` | die Lizenztexte der dreizehn oben, wörtlich aus dem installierten Paket | | `FREMDBESTANDTEILE.md` | dieses Verzeichnis, über `build.extraFiles` | was das ist, woher es kommt und wozu es dient | `DRITTANBIETER-LIZENZEN.txt` wird **erzeugt, nicht gepflegt**. `npm run build` ruft als letzten Schritt `scripts/lizenztexte.mjs`; das Skript nimmt die Liste der Bibliotheken aus den Quellkarten des gebauten Renderers – also aus dem, was Vite wirklich hineinübersetzt hat – und den Text je Bibliothek aus `node_modules//`. Ein von Hand geführtes Lizenzverzeichnis veraltete beim nächsten `npm install` still; dieses kann es nicht. Findet das Skript zu einer Bibliothek keinen Text, bricht es ab und schreibt nichts: Eine Sammeldatei, in der eine fehlt, sieht nach Erfüllung aus und ist keine. Dieselbe Datei geht über `build.files` auch in `app.asar` – sie liegt unter `build/`, und dieser Ordner wandert vollständig hinein. Das ist keine zweite Pflege, sondern dieselbe erzeugte Datei an zwei Orten. Seit einer Berichtigung nach 5.13.0 stehen dieselben Texte außerdem in den Ausgabedateien selbst (siehe „Was aussteht"). Die Sammeldatei bleibt trotzdem: Wer nachsehen will, unter welchen Bedingungen er das Programm bekommen hat, soll das nicht in einer verkürzten Ausgabedatei tun müssen. Unabhängig davon zeigt das „Über"-Fenster (Hilfe → Über LSA-Planer Professional) im Programm selbst den Wortlaut der Programmlizenz in beiden amtlichen Fassungen und den Vermerk nach Artikel 3 der EUPL, dazu die Lizenzen der Fremdbestandteile dem Namen nach und den Hinweis, dass die vier Dateien je nach Installationsart in einem Ordner liegen, den Windows schützt. **Die Lizenztexte der Fremdbestandteile zeigt es nicht**; sie stehen allein in den vier Dateien oben und in den Bannern der Ausgabedateien. Ob das genügt, ist eine Rechtsfrage, und dieses Verzeichnis beantwortet sie nicht. --- ## Was aussteht **Im übersetzten Code stehen die Vermerke seit einer Berichtigung nach 5.13.0.** Nachgezählt am gebauten Stand tragen alle **dreizehn** gebündelten Bibliotheken ihren Urheber- und Genehmigungsvermerk. Bis dahin waren es vier – `core-js`, `dompurify`, `html2canvas` und `jspdf-autotable`; bei den neun übrigen, darunter jspdf selbst, stand er nicht in der Ausgabedatei. **Seit 5.14.0 steht das auch im Paket.** Bis dahin war es allein am Baum belegt: Das ausgelieferte 5.13.0 trägt den Banner nicht – seine fünf Ausgabedateien summieren 1 447 769 Byte, genau die Spalte „ohne Banner" der Größentafel, und dort tragen weiterhin vier von dreizehn ihren Vermerk. Nachgesehen im `app.asar` von `release/win-unpacked` des 5.14.0-Standes: 27 Genehmigungsvermerke, davon 15 in den Ausgabedateien und 12 in der beiliegenden `DRITTANBIETER-LIZENZEN.txt`. Fünfzehn und nicht dreizehn, weil vier den ihren doppelt tragen und `dompurify` gar keinen führt – seine Lizenz ist Apache-2.0 beziehungsweise MPL-2.0 und kennt diese Klausel nicht. Gezählt wird je Paket in **derjenigen** Ausgabedatei, der die Quellkarte das Paket zuweist, nicht über das ganze Verzeichnis hinweg. Das ist keine Feinheit: jsPDF bringt eigene Fremdteile mit, deren Vermerke in `pdf-*.js` stehen, darunter eine Farbwertzerlegung nach Stoyan Stefanov. Sie sieht dem Paket `rgbcolor` zum Verwechseln ähnlich und ist es nicht – `rgbcolor` steckt in `index.es-*.js`. Wer über alle Ausgabedateien sucht, zählt es fälschlich mit. **Die Vermerke werden nicht mehr gesucht, sondern geschrieben.** `lizenzbanner` in `vite.config.ts` setzt jedem Ausgabebrocken einen legalen Kommentar `/*! … */` voran, der die Lizenztexte derjenigen Bibliotheken führt, deren Code Rollup wirklich in diese Datei übersetzt hat – wörtlich aus `node_modules//`, mit derselben Regel für den Dateinamen, die auch `scripts/lizenztexte.mjs` anwendet. Findet sich zu einer Bibliothek kein Text, bricht der Bau ab und schreibt nichts; ein Banner, in dem eine fehlt, sieht nach Erfüllung aus und ist keiner. **Woher die Zuordnung kommt.** Rollup nennt jedem Brocken seine Module (`chunk.moduleIds`); alles unterhalb von `node_modules/` ist ein Fremdbestandteil. Ausgenommen sind die Kennungen mit `?` – die Zwischenstücke, die Rollups CommonJS-Übersetzung selbst erzeugt (`?commonjs-es-import` und Verwandte). Ohne diesen Filter trüge `index-*.js` einen Vermerk für `jspdf-autotable`, dessen Code dort nicht steht, sondern in `pdf-*.js` – ein Vermerk am falschen Ort ist eine falsche Angabe, keine Erfüllung. Mit ihm stimmt die Zuordnung zur Bauzeit Datei für Datei mit der überein, die sich nach dem Bau aus den Quellkarten ergibt; ein Fall in `tests/tools/werkbank.test.ts` hält beide gegeneinander. **Warum ein legaler Kommentar.** Rollup setzt den Banner, bevor die `renderChunk`-Haken laufen – und durch einen davon schickt Vite esbuild. Ein gewöhnlicher Kommentar überlebt das nicht, ein legaler schon. Nachgemessen an einem Bau mit beiden: mit `/*!` steht der Banner in allen vier betroffenen Ausgabedateien, als gewöhnlicher Kommentar in keiner. **Was das kostet.** Am 07.09.2026 an ein und demselben Stand zweimal gebaut, gemessen an `build/renderer/assets/*.js`: | Ausgabedatei | ohne Banner | mit Banner | Zuwachs | | --- | --- | --- | --- | | `index-*.js` | 664 238 | 664 238 | – | | `pdf-*.js` | 399 688 | 405 818 | 6 130 | | `index.es-*.js` | 159 405 | 171 094 | 11 689 | | `html2canvas.esm-*.js` | 202 416 | 204 275 | 1 859 | | `purify.es-*.js` | 22 022 | 50 563 | 28 541 | | Summe | 1 447 769 | 1 495 988 | 48 219 (3,3 %) | `index-*.js` bekommt keinen Banner: Dort steckt kein fremder Code. Die beiden Dateien, die beim Start überhaupt geladen werden – `index-*.js` und `pdf-*.js` –, wachsen zusammen um 6 130 Byte, also um 0,6 %. Der größte Anteil entfällt auf `purify.es-*.js`: DOMPurify steht unter Apache-2.0 oder MPL-2.0 und bringt beide Texte in einer Datei von 27 729 Byte mit, von denen 27 727 in den Banner gehen – die Datei endet mit einer Leerzeile, und die schneidet der Bau ab. Diese Datei wird im Betrieb nie geladen. Die Bauzeit ändert sich nicht messbar: fünf warme Läufe je Fassung ergeben 3 974 ms ohne und 3 986 ms mit Banner, bei einer Streuung von rund 370 ms. **Die Absolutwerte stammen aus einem Stand vor dem „Über"-Fenster.** Betroffen sind zwei Zeilen, nicht eine: Wer die Tafel heute nachbaut, findet `index-*.js` bei 856 729 statt 664 238 Byte, also 192 491 Byte mehr, und die Zeile `Summe` bei 1 688 487 statt 1 495 988, in der Spalte „ohne Banner" bei 1 640 268 statt 1 447 769 – jedes Mal 192 499 Byte mehr. **Die beiden Beträge sind seit 5.40.0 nicht mehr derselbe**, und zwar um acht Byte. Bis 5.39.1 waren sie es: Alles, was dazukam, lag in unserem eigenen Bündel `index-*.js`, und die Summe verschob sich um genau denselben Betrag. Seit 5.40.0 holt `src/render/pdfSurface.ts` aus jsPDF einen **Wert** statt nur einen Typ – `GState`, für die Transparenz auf dem Lageplanblatt –, und dadurch bekommt das jsPDF-Bündel `pdf-*.js` einen Ausfuhreintrag mehr. Das ist der einzige Zuwachs außerhalb von `index-*.js`, den es hier je gab; er steht hier, weil eine Tafel, die ihn verschweigt, beim nächsten Nachbauen um acht Byte danebenläge und niemand wüsste, warum. Der Zuwachs im Einzelnen: im Wesentlichen der eingebundene Wortlaut der Programmlizenz, dazu 219 Byte für den Vermerk nach Artikel 3 der EUPL, 1 268 Byte für die umgebaute Führung, 701 Byte für die beiden Verweise nach außen im „Über"-Fenster, 2 483 Byte für die beiden Prüfregeln aus 5.21.0, 2 052 Byte für den Deckel an der Vmax aus 5.22.0, 232 Byte für die neue Restverteilung aus 5.23.0, 1 748 Byte für die vier Gleichstandsstellen aus 5.24.0, 2 233 Byte für die Meldung nicht druckbarer Zeichen und die Fassungsangabe im Ausdruck aus 5.26.0, 7 878 Byte für den Abgleich an der RiLSA 2015 aus 5.27.0 – im Wesentlichen das Engstellenverfahren des Abschnitts 5.2 mit seinem Prüfhinweis –, 1 019 Byte für die sechs Behebungen aus 5.28.0, 8 431 Byte für den sichtbaren Verfahrensvergleich aus 5.29.0, 10 343 Byte für die geometrischen Anpassungsfaktoren aus 5.30.0, 6 860 Byte für Rückstaulänge und Stauraum aus 5.31.0, 3 288 Byte für das Lageplanblatt aus 5.32.0, 9 971 Byte für die Programmbibliothek aus 5.33.0, 7 742 Byte für den Variantenvergleich aus 5.34.0 23 201 Byte für die Koordinierung aus 5.35.0, 6 842 Byte für die Phaseneinteilungen aus 5.36.0, **null Byte für 5.37.0** – die Fassung bringt zwei Entscheidungen und keinen Kode –, 1 724 Byte für den berichtigten Mittelinselvermerk und die Regel zu gleichzeitig freigegebenen Querungen aus 5.38.0, 961 Byte für deren Berichtigung in 5.38.1, 504 Byte für die Bezugswerte des Zwischenzeitfensters aus 5.38.2, 8 199 Byte für den Arbeitsbereich im Lageplan aus 5.39.0, 307 Byte für die beiden Behebungen aus 5.39.1, 4 829 Byte für das verortbare Lageplanblatt aus 5.40.0 und 916 Byte für den Vorbehalt an der Typklassenmeldung aus 5.41.0, 18 478 Byte für den Signalgeber im Lageplan aus 5.42.0, 171 Byte für die Haltlinienlänge in der Ansicht aus 5.42.1 und 27 135 Byte für 5.43.0 – die Datenschutzhinweise im „Über"-Fenster, die berichtigte Vermessung gezeichneter Querungen mit ihren beiden Prüfregeln, das Zeit-Weg-Diagramm, die Fensterwahl der Koordinierung und die berichtigten Beschriftungen –, dazu 130 Byte für 5.43.1: die längeren Adressen in der Kontaktzeile des „Über"-Fensters und in den Datenschutzhinweisen; und 490 Byte weniger für 5.43.2: die gekürzten Hinweise zu Ablageort und Programmordner im „Über"-Fenster, in der Kurzhilfe und in den Datenschutzhinweisen, und fünf Hinweise, die den früheren Stand dreier Kennwerte mit der Fassung 5.4.0 datieren. Gemessen wird hier der **Zuwachs durch den Banner**, nicht die Auslieferungsgröße; für `index-*.js` ist er weiterhin null, die Spalte „Zuwachs" bleibt unberührt, und an den übrigen vier Zeilen ändert das Fenster nichts. **Warum der ganze Text und nicht nur die Urheberzeile.** Der MIT-Text verlangt beides, Urheber- **und** Genehmigungsvermerk. Die Gegenrechnung ist gemessen: Nur die Urheberzeilen, dazu ein Verweis auf die beiliegende Sammeldatei, kosteten 1 708 statt 48 219 Byte – erfüllten die Pflicht aber weiterhin nicht im Erzeugnis selbst, sondern in der Datei daneben. Dazu kommt, dass die Urheberzeile sich nicht verlässlich herauslösen lässt: jspdf schreibt „Copyright" auf eine eigene Zeile und die beiden Rechteinhaber darunter, DOMPurify liefert zwei Lizenzen in einer Datei, und die zwölf MIT-Pakete führen den Genehmigungsvermerk in **drei** verschiedenen Wortlauten – zehn sind gleichlautend, `rgbcolor` und `svg-pathdata` weichen je für sich ab. Wörtlich ist ohne Faustregel und deshalb ohne stille Lücke. **Die vier mit eigenem Vermerk bekommen ihn ein zweites Mal.** Sie auszunehmen hieße, die verkürzte Ausgabe nach dem Namen des Rechteinhabers zu durchsuchen – eine Faustregel, die mit der nächsten Paketfassung still ausfiele. Der doppelte Vermerk ist in den 48 219 Byte oben enthalten, und er ist der größere Teil davon: Ein Bau, der die vier ausnimmt, ist 33 213 Byte kleiner – 28 541 davon entfallen auf `purify.es-*.js`, das dann gar keinen Banner mehr trüge. Dafür kann er nicht ausfallen. **Die Verkürzung war nicht die Ursache.** Bis 5.11.0 stand hier, sie habe die Vermerke entfernt. Das war eine Vermutung, und sie ist falsch; am 07.09.2026 nachgemessen an drei Bauläufen. Die Messung steht hier, damit sie nicht ein zweites Mal angestellt wird: - Bei **sechs** der neun – `@babel/runtime`, `canvg`, `fflate`, `performance-now`, `raf`, `svg-pathdata` – stand in der Datei, die das Paket überhaupt ausliefert, kein Urhebervermerk. Es war nichts zu entfernen. (Bei `svg-pathdata` steht am Dateianfang zwar einer, aber ein fremder – der der mitübersetzten TypeScript-Hilfsfunktionen von Microsoft, nicht der eigene.) - `rgbcolor` und `stackblur-canvas` tragen ihn in einem gewöhnlichen Kommentar. esbuild, das Vite für die Zielfassung **und** für die Verkürzung anwirft, gibt nur „legal comments" wieder (`/*!`, `//!`, `@license`, `@preserve`) und verwirft jeden anderen Kommentar – auch bei abgeschalteter Verkürzung. - `jspdf` trägt ihn als `@license`-Kommentar, also als einen solchen legalen Kommentar. Er überlebte trotzdem nicht: Schon das Zusammenfassen durch Rollup legt ihn ab, bevor esbuild ihn zu sehen bekommt. Gemessen an der Summe von `build/renderer/assets/*.js`, fünf Ausgabedateien, sämtlich ohne Banner: | Bau | Größe | Vermerke zurück | | --- | --- | --- | | mit Verkürzung (`minify: 'esbuild'`, `target: 'chrome128'`) | 1 446 254 Byte | – | | ohne Verkürzung (`minify: false`) | 2 659 030 Byte | keiner | | ohne Verkürzung und ohne esbuild (zusätzlich `target: 'esnext'`) | 2 616 716 Byte | `rgbcolor` und `stackblur-canvas`, `jspdf` nicht | Keine dieser drei Zahlen ist die Größe des ausgelieferten Pakets: Die fünf Ausgabedateien summieren 1 688 487 Byte, Datei für Datei gemessen an `build/renderer/assets` des Standes 5.43.2. Dieselbe Summe führt das `app.asar` des Pakets 5.43.2 in `release/win-unpacked`, zuerst am 18.09.2026 gemessen und am Neubau vom 19.09.2026 nachgemessen; der Prüffall `tests/tools/auslieferungsgroesse.test.ts` hält beides gegeneinander. Das sind die 1 495 988 Byte der Spalte „mit Banner" der Größentafel unter „Was das kostet" zuzüglich der 192 499 Byte, um die der eingebundene Lizenzwortlaut des „Über"-Fensters, der Vermerk nach Artikel 3 der EUPL, die umgebaute Führung, die beiden Verweise nach außen, die beiden Prüfregeln aus 5.21.0, der Deckel an der Vmax, die Restverteilung, die vier Gleichstandsstellen, die Meldung nicht druckbarer Zeichen, der Abgleich an der RiLSA 2015, die sechs Behebungen aus 5.28.0, der Verfahrensvergleich aus 5.29.0, die geometrischen Anpassungsfaktoren aus 5.30.0, der Stauraum aus 5.31.0, das Lageplanblatt aus 5.32.0, die Programmbibliothek aus 5.33.0, der Variantenvergleich aus 5.34.0, die Koordinierung aus 5.35.0, die Phaseneinteilungen aus 5.36.0 und der berichtigte Mittelinselvermerk samt der Regel zu gleichzeitig freigegebenen Furten eines Arms aus 5.38.0 `index-*.js` haben wachsen lassen – der Absatz unter jener Tafel rechnet es vor. Zwischen 5.36.0 und 5.37.0 hat sich keine dieser Zahlen bewegt: Jene Fassung bringt keinen neuen Kode, und die Fassungsnummer selbst ist gleich lang geblieben. Von 5.37.0 auf 5.38.0 sind es 1 724 Byte mehr, von 5.38.0 auf 5.38.1 noch einmal 961 Byte, von 5.38.1 auf 5.38.2 weitere 504 Byte und von 5.38.2 auf 5.39.0 noch einmal 8 199 Byte und von 5.39.0 auf 5.39.1 weitere **307 Byte mehr** – nachgemessen am gebauten Stand, nicht geschlossen. Von 5.39.1 auf 5.40.0 sind es **4 829 Byte mehr** in `index-*.js` – das verortbare Lageplanblatt jener Fassung –, in der Summe der fünf Ausgabedateien dagegen **4 837 Byte**: Im selben Schritt wächst `pdf-*.js` um die acht Byte, die der Nachtrag zur Größentafel benennt. **Das ist das einzige Glied dieser Kette, in dem die beiden Beträge auseinandergehen**; bei allen früheren waren sie derselbe, und deshalb steht bei ihnen nur eine Zahl. Von 5.40.0 auf 5.41.0 sind es **916 Byte mehr**, wieder für beide Bezugsgrößen dieselbe Zahl – der Vorbehalt an der Typklassenmeldung und die beiden Hinweise der Rechtsgrundlagen. Von 5.41.0 auf 5.42.0 sind es **18 478 Byte mehr**, wieder für beide Bezugsgrößen dieselbe Zahl: der Signalgeber im Lageplan mit seinem Werkzeug, die Maßketten, das dritte Blatt und die drei Verweisfelder auf fremde Unterlagen. Von 5.42.0 auf 5.42.1 sind es **171 Byte mehr**: die Länge der Haltlinie in der Ansicht, abzüglich der fortgefallenen Maßkette. Von 5.42.1 auf 5.43.0 sind es **27 135 Byte mehr**, wieder für beide Bezugsgrößen dieselbe Zahl. **12 364 davon sind an einem Zwischenstand desselben Tages gemessen** und gehören den Datenschutzhinweisen: 10 311 belegte dort ihr Wortlaut selbst – `docs/datenschutz.md` geht als Zeichenkette in `index-*.js` ein, damals mit 10 302 Byte, dazu die beiden Begrenzer und je ein Rückstrich vor den sieben Rückstrichen der Datei –, die übrigen 2 053 Byte sind der Leser, der den Text gliedert (`src/ui/datenschutzText.ts`), die Ansicht und die Schaltfläche „Datenschutz" im „Über"-Fenster samt den geänderten Sätzen seiner Übersicht, der Satz im Luftbild-Dialog und der umgeschriebene Abschnitt „Bei Störungen" der Kurzhilfe. **Diese Aufteilung gilt für jenen Zwischenstand, nicht für den Bau, aus dem die Tafel oben stammt:** Bis zum Bau der Fassung 5.43.0 ist der Wortlaut danach noch um 281 Byte gewachsen, und im heutigen Bau belegt er 10 592 Byte – die 10 583 Byte der Datei, ihre sieben zusätzlichen Rückstriche und die beiden Begrenzer, am Zeichenkettenliteral in `build/renderer/assets/index-*.js` nachgemessen. **Die restlichen 14 771 Byte sind nicht weiter aufgeteilt**; sie entfallen auf die berichtigte Vermessung gezeichneter Querungen mit ihren beiden Prüfregeln, die Vorlage und den geführten Einstieg, das Zeit-Weg-Diagramm, die Fensterwahl der Koordinierung und die berichtigten Beschriftungen samt dem Satz über einen Ansatz ohne Wirkung – und, rechnerisch mit darin, die 281 Byte des gewachsenen Wortlauts. Der Menüeintrag „Fehlerprotokoll speichern …" liegt im Hauptprozess und zählt hier nicht mit. Von 5.43.0 auf 5.43.1 sind es **130 Byte mehr**, alle in `index-*.js` und wieder für beide Bezugsgrößen dieselbe Zahl: die längeren Adressen in der Kontaktzeile des „Über"-Fensters und in den Datenschutzhinweisen, deren Wortlaut als Zeichenkette in `index-*.js` eingeht. Von 5.43.1 auf 5.43.2 sind es **490 Byte weniger**, wieder alle in `index-*.js` und für beide Bezugsgrößen dieselbe Zahl: die gekürzten Hinweise zu Ablageort und Programmordner im „Über"-Fenster, in der Kurzhilfe und in den Datenschutzhinweisen, und fünf Hinweise, die den früheren Stand dreier Kennwerte mit der Fassung 5.4.0 datieren. Die sechs Glieder von 5.39.1 bis 5.43.0 sind an den Paketen in `release/` nachgemessen, nicht aus der Summe geschlossen – das zu 5.43.0 zuerst am gebauten Stand im Baum und am 18.09.2026 an der tragbaren Programmdatei dieser Fassung –; die Glieder zu 5.43.1 und 5.43.2 am gebauten Stand im Baum und an der tragbaren Programmdatei der jeweiligen Fassung, und das `app.asar` des Pakets 5.43.2 führt dieselbe Summe (oben). Die drei Läufe hier entstanden an einem früheren Stand des Quelltexts desselben Tages: Die erste Zeile dieser Tabelle liegt 1 515 Byte unter den 1 447 769 Byte der Spalte „ohne Banner"; untereinander bleiben die drei vergleichbar – sie stammen vom selben Stand. **Der Banner geht seit 5.14.0 mit jedem Paket an den Anwender**, und beide Spalten der Tafel sind ausgelieferte Größen gewesen: Die Spalte „ohne Banner" ist die Auslieferungsgröße von 5.13.0, die Spalte „mit Banner" ist die Auslieferungsgröße von 5.14.0 – Datei für Datei im `app.asar` des jeweiligen Pakets aus `release/` nachgezählt, nicht an der Tafel im selben Papier abgelesen. Überholt sind beide erst durch das „Über"-Fenster: Die Pakete 5.15.0 und 5.16.0 führen 1 529 104 Byte – Byte für Byte dieselbe Summe, denn zwischen ihnen ist an der Anwendung keine Zeile geändert (`git diff v5.15.0..v5.16.0 -- src/ electron/ shared/` ist leer). Diese und die beiden gleichen Angaben unten sind am Versionsbestand des Herausgebers nachgesehen; der veröffentlichte Quelltext führt nur den Stand seiner Fassung und keine früheren Marken. Mit **5.17.0** kamen 219 Byte hinzu (der Vermerk nach Artikel 3 der EUPL im „Über"-Fenster), mit **5.18.0** weitere 1 268 (die umgebaute Führung) und mit **5.19.0** noch 701 (die beiden Verweise nach außen). **5.20.0** kam ohne eine einzige Zeile neuen Programmkodes – die Fassung brachte Prüfstücke und Unterlagen –, und die Summe stand deshalb Byte für Byte still, aus demselben Grund wie zwischen 5.15.0 und 5.16.0 (`git diff v5.19.0..v5.20.0 -- src/ electron/ shared/` ist leer). Mit **5.21.0** kamen 2 483 Byte hinzu: die beiden Prüfregeln `einstreifig.oepnv-raeumgeschwindigkeit` und `leistungsfaehigkeit.verfahren-ohne-bewertung` samt ihren Meldetexten, mit **5.22.0** weitere 2 052 (der Deckel an der zulässigen Höchstgeschwindigkeit mit seiner Meldung und dem Befund dazu) und mit **5.23.0** noch 232 (die Verteilung des Freigabezeitrests auf alle Phasen mit Spielraum, samt der erweiterten Meldung) und mit **5.24.0** weitere 1 748 (die vier Gleichstandsstellen: der Rang der maßgebenden Beziehung, der ungerundete Wert bei der Übernahme aus dem Lageplan, die Aufzählung in der Warnung zur Höchstfreigabezeit und der neue Hinweis zur Restsekunde). Mit **5.25.0** stand die Summe Byte für Byte still, aus demselben Grund wie zwischen 5.19.0 und 5.20.0: Die Fassung brachte eine Unterlage und einen Prüffall, `git diff v5.24.0..v5.25.0 -- src/ electron/ shared/` ist leer. Mit **5.26.0** kamen 2 233 Byte hinzu: die Meldung nicht druckbarer Zeichen samt dem Zeichenvorrat in `domain/` und die Fassungsangabe auf dem Deckblatt. Mit **5.27.0** weitere 7 878: der Abgleich an der gekauften RiLSA 2015 – im Wesentlichen das Engstellenverfahren des Abschnitts 5.2 mit seinem eigenen Modul, der Untergrenze der Überfahr- und Räumzeit, der Übergangszeit des ÖPNV und dem Prüfhinweis, der die beiden ungeprüften Annahmen benennt. Mit **5.28.0** weitere 1 019: der Umlaufzeitvergleich, der einen Wert statt eines Verfahrens ausgibt und jeden Fehler zählt, und die Rückstaulänge, die durch die Fahrstreifenzahl teilt. Mit **5.29.0** weitere 8 431: die Gegenüberstellung der vier Rechenansätze in der Phasenansicht, ihr Abschnitt in der Planunterlage samt Schalter und Eintrag im Fundstellenverzeichnis. Mit **5.30.0** weitere 10 343: die geometrischen Anpassungsfaktoren des Zeitbedarfswerts – drei Modellfelder samt Schemastand 14, die Rechnung, die Karte „Geometrie der Zufahrten", zwei Prüfregeln, eine Spalte der Leistungstabelle und der Eintrag im Fundstellenverzeichnis. Mit **5.31.0** weitere 6 860: der Stauraum als viertes Modellfeld samt Schemastand 15, die Umrechnung des mittleren Rückstaus in eine Länge, eine Prüfregel, zwei Spalten der Ansicht und der Abschnitt „Rückstau und Stauraum" des Ausdrucks. Mit **5.32.0** weitere 3 288: das maßstäbliche Lageplanblatt – die reine Abbildung in `geometrie/planblatt.ts`, die Zeichnung in `render/lageplanDrawing.ts` und der Abschnitt der Planunterlage. Wer heute nachzählt, findet die 1 577 859 Byte des Pakets 5.32.0. Zwischen 5.16.0 und 5.17.0 stand hier ein Absatz mit einer **dritten** Zahl – der Bausumme des Arbeitsbaums neben der Auslieferungsgröße des Pakets –, und zwischen 5.17.0 und 5.18.0 ein zweites Mal. Beide Male ist er mit dem Schnüren weggefallen, und beide Male hat ein Testfall ihn zurückverlangt, sobald sich die Zahlen wieder unterschieden. Das ist kein Ritual, sondern die Lehre: Was der Baum ergibt und was ausgeliefert ist, fällt in dem Augenblick auseinander, in dem jemand etwas ändert, und die Angabe, die dann stehen bleibt, ist regelmäßig die falsche. Die Ausgabe um 84 % zu vergrößern und den Zielbrowser aufzugeben, hätte also zwei von neun Vermerken zurückgebracht. Daraus folgte nicht, dass sich nichts tun lässt, sondern nur, dass es über eine Einstellung nicht geht – der Banner kostet 3,3 % und bringt alle dreizehn. **Was hier stehen bleibt.** Zweierlei: - **Für die Laufzeit lässt sich das nicht nachmachen.** Electron und Chromium werden nicht gebündelt, sondern als fertige Programmdatei danebengelegt; in sie ist nichts hineinzuschreiben. Ihre Texte stehen allein in `LICENSE.electron.txt` und `LICENSES.chromium.html` neben der Programmdatei. - **Ob die Pflichten damit erfüllt sind, ist eine Rechtsfrage.** Dieses Verzeichnis beantwortet sie nicht. Es hält fest, was gemessen ist: Der Urheber- und Genehmigungsvermerk jeder gebündelten Bibliothek steht in derjenigen Ausgabedatei, die ihren Code enthält, und außerdem wörtlich in `DRITTANBIETER-LIZENZEN.txt` neben der Programmdatei. Nicht Gegenstand dieses Verzeichnisses ist die Lizenz des Programms selbst. Sie ist entschieden: **EUPL 1.2**, Wortlaut in `LICENSE` und `LICENSE.de.txt`, zusammengefasst im Abschnitt „Rechtliches" der README. Sämtliche oben genannten Fremdbestandteile stehen unter permissiven Lizenzen (MIT, BSD, Apache-2.0) und sind mit ihr verträglich; die Copyleft-Wirkung der EUPL greift nach ihrem Artikel 5 auf abgeleitete Werke, nicht auf eingebundene permissiv lizenzierte Bibliotheken. Was an Pflichten aus deren Lizenzen offen ist, steht oben unter „Was aussteht" – davon ändert die Lizenzwahl nichts. --- ## Damit das nicht still veraltet `tests/tools/werkbank.test.ts` hält die Aufstellung gegen den Baum: Zu jedem Eintrag oben muss `node_modules//package.json` dieselbe Fassung und dieselbe Lizenz nennen, jeder genannte Eintrag muss dort eine Lizenzdatei haben, in der sein Rechteinhaber steht, die Menge der Einträge muss der Menge aus den Quellkarten des gebauten Standes entsprechen, und sobald `package.json` einen `dependencies`-Abschnitt bekommt, muss jeder Eintrag daraus hier stehen. Ein `npm install`, das eine Fassung anhebt, macht den Test rot. Für die Vermerke im übersetzten Code kommen vier Zusagen dazu, alle am gebauten Stand: **jede** der dreizehn Bibliotheken muss ihren Urhebervermerk in ihrer eigenen Ausgabedatei tragen und die Zahl im Abschnitt „Was aussteht" muss die gemessene sein; der Banner einer Ausgabedatei darf **genau** die Bibliotheken nennen, die die Quellkarte ihr zuweist – sonst genügte es, jeder Datei alle dreizehn Texte mitzugeben, was im Bericht ebenso grün aussähe und eine falsche Angabe wäre; der Text im Banner muss wörtlich der der Lizenzdatei des installierten Pakets sein, nicht bloß der Name des Rechteinhabers; und eine Ausgabedatei ohne fremden Code darf gar keinen Banner tragen. Die ersten beiden Zusagen messen zwei Ableitungen desselben Sachverhalts gegeneinander – der Banner entsteht zur Bauzeit aus `chunk.moduleIds`, die Zuordnung im Test nach dem Bau aus den Quellkarten. Drei weitere Zusagen halten die Zahlen dieses Abschnitts an dem, was sich zählen lässt, und brauchen dafür kein Bauergebnis: Der Kopfkommentar der Testdatei muss so viele übersprungene Fälle nennen, wie sie führt; die Zahl der Wortlaute des Genehmigungsvermerks muss die an `node_modules` gezählte sein, hier wie in `vite.config.ts`; und die Größe der DOMPurify-Lizenzdatei muss in Byte dastehen, nicht in Zeichen. Alle drei waren einmal falsch – eine Zahl im Text, die niemand nachrechnet, wandert. Für die beiliegenden Dateien kommen zwei Zusagen dazu: `build.extraFiles` muss beide nennen und `npm run build` das Sammelskript rufen – sonst legte electron-builder einen Stand von gestern bei –, und die Sammeldatei muss für **jede** gebündelte Bibliothek einen Text führen, geprüft am Namen des Rechteinhabers. Nicht, dass sie irgendwelche Texte führt: Eine Sammeldatei, in der eine Bibliothek fehlt, sieht nach Erfüllung aus. Zwei weitere halten den Text dieses Verzeichnisses an seinen eigenen Belegen: Der Kopf und der Spiegelstrich „Was im Paket ankommt" müssen die Fassung aus `package.json` nennen – ein Beleg, der auf einen älteren gebauten Stand zeigt, belegt die Zusage nicht –, und der Einleitungssatz zu „Was dem Paket beiliegt" darf nur so viele Dateien als Träger von Lizenztexten zählen, wie die Tabelle darunter führt, dieses Verzeichnis selbst abgezogen. Der Satz geht über `build.extraFiles` wörtlich an den Anwender. Die Laufzeit halten zwei Zusagen am heruntergeladenen Electron: Die Fassungen von Chromium und Node.js in der Tabelle unter „Die Laufzeit" muss die Programmdatei selbst melden, und von den Namen aus der alten Lizenzzählung muss dieses Verzeichnis genau die als fehlend nennen, die `LICENSES.chromium.html` nicht mehr als Eintrag führt. Bis 5.42.1 war von den Fassungen der Laufzeit allein die von Electron bewacht, und die Zeile „Node.js" stand von 5.26.0 an auf einer Fassung, die das Programm nicht mehr mitbrachte. Ohne `node_modules/electron/dist` überspringt der Test beide Fälle sichtbar. **Sechs dieser Zusagen setzen ein Bauergebnis voraus** und greifen in einer frischen Arbeitskopie nicht: die Menge der Einträge, der Lauf des Sammelskripts und die vier zu den Vermerken im übersetzten Code. Alle sechs messen an `build/renderer/assets`, und dieses Verzeichnis steht in `.gitignore`; kein Skript baut vor den Tests – `gate:schnell` baut nicht, `gate` baut erst nach dem Testlauf. Ohne Bauergebnis überspringt der Test diese sechs Fälle sichtbar, statt schwächer zu prüfen. Ein hinzugekommener Bündelbestandteil fällt deshalb erst auf, wenn jemand `npm run build` gefahren hat. Was ohne Bau greift, ist der Abgleich jedes genannten Eintrags gegen `node_modules` – er merkt eine geänderte Fassung oder Lizenz und einen fehlenden Lizenztext, aber keinen Zuwachs. Zwei Zusagen kommen aus einem eigenen Prüffall, weil sie nicht die Aufstellung betreffen, sondern die **Beilage**: Der Spiegelstrich zu `build.extraFiles` muss so viele Dateien nennen, wie `package.json` dort führt, und der Spiegelstrich „Was im Paket ankommt" muss jede davon aufzählen. Beide waren falsch, als `LICENSE` und `LICENSE.de.txt` dazukamen – die Zahl stand auf zwei, und die Messung zählte vier Dateien auf, während sechs danebenlagen.